summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/sound
diff options
context:
space:
mode:
Diffstat (limited to 'ANDROID_3.4.5/sound')
-rw-r--r--ANDROID_3.4.5/sound/Kconfig137
-rw-r--r--ANDROID_3.4.5/sound/Makefile19
-rw-r--r--ANDROID_3.4.5/sound/ac97_bus.c77
-rw-r--r--ANDROID_3.4.5/sound/aoa/Kconfig17
-rw-r--r--ANDROID_3.4.5/sound/aoa/Makefile4
-rw-r--r--ANDROID_3.4.5/sound/aoa/aoa-gpio.h83
-rw-r--r--ANDROID_3.4.5/sound/aoa/aoa.h129
-rw-r--r--ANDROID_3.4.5/sound/aoa/codecs/Kconfig24
-rw-r--r--ANDROID_3.4.5/sound/aoa/codecs/Makefile7
-rw-r--r--ANDROID_3.4.5/sound/aoa/codecs/onyx.c1135
-rw-r--r--ANDROID_3.4.5/sound/aoa/codecs/onyx.h75
-rw-r--r--ANDROID_3.4.5/sound/aoa/codecs/tas-basstreble.h134
-rw-r--r--ANDROID_3.4.5/sound/aoa/codecs/tas-gain-table.h209
-rw-r--r--ANDROID_3.4.5/sound/aoa/codecs/tas.c1029
-rw-r--r--ANDROID_3.4.5/sound/aoa/codecs/tas.h55
-rw-r--r--ANDROID_3.4.5/sound/aoa/codecs/toonie.c151
-rw-r--r--ANDROID_3.4.5/sound/aoa/core/Makefile5
-rw-r--r--ANDROID_3.4.5/sound/aoa/core/alsa.c100
-rw-r--r--ANDROID_3.4.5/sound/aoa/core/alsa.h16
-rw-r--r--ANDROID_3.4.5/sound/aoa/core/core.c162
-rw-r--r--ANDROID_3.4.5/sound/aoa/core/gpio-feature.c422
-rw-r--r--ANDROID_3.4.5/sound/aoa/core/gpio-pmf.c253
-rw-r--r--ANDROID_3.4.5/sound/aoa/fabrics/Kconfig11
-rw-r--r--ANDROID_3.4.5/sound/aoa/fabrics/Makefile3
-rw-r--r--ANDROID_3.4.5/sound/aoa/fabrics/layout.c1168
-rw-r--r--ANDROID_3.4.5/sound/aoa/soundbus/Kconfig14
-rw-r--r--ANDROID_3.4.5/sound/aoa/soundbus/Makefile3
-rw-r--r--ANDROID_3.4.5/sound/aoa/soundbus/core.c219
-rw-r--r--ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/Makefile2
-rw-r--r--ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/control.c194
-rw-r--r--ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/core.c464
-rw-r--r--ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/i2sbus.h126
-rw-r--r--ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/interface.h187
-rw-r--r--ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/pcm.c1064
-rw-r--r--ANDROID_3.4.5/sound/aoa/soundbus/soundbus.h204
-rw-r--r--ANDROID_3.4.5/sound/aoa/soundbus/sysfs.c42
-rw-r--r--ANDROID_3.4.5/sound/arm/Kconfig43
-rw-r--r--ANDROID_3.4.5/sound/arm/Makefile16
-rw-r--r--ANDROID_3.4.5/sound/arm/aaci.c1116
-rw-r--r--ANDROID_3.4.5/sound/arm/aaci.h250
-rw-r--r--ANDROID_3.4.5/sound/arm/pxa2xx-ac97-lib.c402
-rw-r--r--ANDROID_3.4.5/sound/arm/pxa2xx-ac97.c260
-rw-r--r--ANDROID_3.4.5/sound/arm/pxa2xx-pcm-lib.c285
-rw-r--r--ANDROID_3.4.5/sound/arm/pxa2xx-pcm.c132
-rw-r--r--ANDROID_3.4.5/sound/arm/pxa2xx-pcm.h30
-rw-r--r--ANDROID_3.4.5/sound/atmel/Kconfig19
-rw-r--r--ANDROID_3.4.5/sound/atmel/Makefile5
-rw-r--r--ANDROID_3.4.5/sound/atmel/abdac.c612
-rw-r--r--ANDROID_3.4.5/sound/atmel/ac97c.c1231
-rw-r--r--ANDROID_3.4.5/sound/atmel/ac97c.h73
-rw-r--r--ANDROID_3.4.5/sound/core/Kconfig220
-rw-r--r--ANDROID_3.4.5/sound/core/Makefile38
-rw-r--r--ANDROID_3.4.5/sound/core/compress_offload.c773
-rw-r--r--ANDROID_3.4.5/sound/core/control.c1726
-rw-r--r--ANDROID_3.4.5/sound/core/control_compat.c448
-rw-r--r--ANDROID_3.4.5/sound/core/ctljack.c56
-rw-r--r--ANDROID_3.4.5/sound/core/device.c245
-rw-r--r--ANDROID_3.4.5/sound/core/hrtimer.c167
-rw-r--r--ANDROID_3.4.5/sound/core/hwdep.c547
-rw-r--r--ANDROID_3.4.5/sound/core/hwdep_compat.c78
-rw-r--r--ANDROID_3.4.5/sound/core/info.c1016
-rw-r--r--ANDROID_3.4.5/sound/core/info_oss.c139
-rw-r--r--ANDROID_3.4.5/sound/core/init.c991
-rw-r--r--ANDROID_3.4.5/sound/core/isadma.c117
-rw-r--r--ANDROID_3.4.5/sound/core/jack.c242
-rw-r--r--ANDROID_3.4.5/sound/core/memalloc.c547
-rw-r--r--ANDROID_3.4.5/sound/core/memory.c92
-rw-r--r--ANDROID_3.4.5/sound/core/misc.c148
-rw-r--r--ANDROID_3.4.5/sound/core/oss/Makefile13
-rw-r--r--ANDROID_3.4.5/sound/core/oss/copy.c92
-rw-r--r--ANDROID_3.4.5/sound/core/oss/io.c141
-rw-r--r--ANDROID_3.4.5/sound/core/oss/linear.c178
-rw-r--r--ANDROID_3.4.5/sound/core/oss/mixer_oss.c1422
-rw-r--r--ANDROID_3.4.5/sound/core/oss/mulaw.c344
-rw-r--r--ANDROID_3.4.5/sound/core/oss/pcm_oss.c3117
-rw-r--r--ANDROID_3.4.5/sound/core/oss/pcm_plugin.c756
-rw-r--r--ANDROID_3.4.5/sound/core/oss/pcm_plugin.h185
-rw-r--r--ANDROID_3.4.5/sound/core/oss/rate.c348
-rw-r--r--ANDROID_3.4.5/sound/core/oss/route.c109
-rw-r--r--ANDROID_3.4.5/sound/core/pcm.c1220
-rw-r--r--ANDROID_3.4.5/sound/core/pcm_compat.c532
-rw-r--r--ANDROID_3.4.5/sound/core/pcm_lib.c2289
-rw-r--r--ANDROID_3.4.5/sound/core/pcm_memory.c493
-rw-r--r--ANDROID_3.4.5/sound/core/pcm_misc.c490
-rw-r--r--ANDROID_3.4.5/sound/core/pcm_native.c3492
-rw-r--r--ANDROID_3.4.5/sound/core/pcm_timer.c141
-rw-r--r--ANDROID_3.4.5/sound/core/rawmidi.c1726
-rw-r--r--ANDROID_3.4.5/sound/core/rawmidi_compat.c120
-rw-r--r--ANDROID_3.4.5/sound/core/rtctimer.c188
-rw-r--r--ANDROID_3.4.5/sound/core/seq/Kconfig16
-rw-r--r--ANDROID_3.4.5/sound/core/seq/Makefile29
-rw-r--r--ANDROID_3.4.5/sound/core/seq/oss/Makefile10
-rw-r--r--ANDROID_3.4.5/sound/core/seq/oss/seq_oss.c312
-rw-r--r--ANDROID_3.4.5/sound/core/seq/oss/seq_oss_device.h189
-rw-r--r--ANDROID_3.4.5/sound/core/seq/oss/seq_oss_event.c447
-rw-r--r--ANDROID_3.4.5/sound/core/seq/oss/seq_oss_event.h112
-rw-r--r--ANDROID_3.4.5/sound/core/seq/oss/seq_oss_init.c546
-rw-r--r--ANDROID_3.4.5/sound/core/seq/oss/seq_oss_ioctl.c209
-rw-r--r--ANDROID_3.4.5/sound/core/seq/oss/seq_oss_midi.c714
-rw-r--r--ANDROID_3.4.5/sound/core/seq/oss/seq_oss_midi.h48
-rw-r--r--ANDROID_3.4.5/sound/core/seq/oss/seq_oss_readq.c237
-rw-r--r--ANDROID_3.4.5/sound/core/seq/oss/seq_oss_readq.h56
-rw-r--r--ANDROID_3.4.5/sound/core/seq/oss/seq_oss_rw.c216
-rw-r--r--ANDROID_3.4.5/sound/core/seq/oss/seq_oss_synth.c664
-rw-r--r--ANDROID_3.4.5/sound/core/seq/oss/seq_oss_synth.h51
-rw-r--r--ANDROID_3.4.5/sound/core/seq/oss/seq_oss_timer.c284
-rw-r--r--ANDROID_3.4.5/sound/core/seq/oss/seq_oss_timer.h70
-rw-r--r--ANDROID_3.4.5/sound/core/seq/oss/seq_oss_writeq.c173
-rw-r--r--ANDROID_3.4.5/sound/core/seq/oss/seq_oss_writeq.h50
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq.c137
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_clientmgr.c2591
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_clientmgr.h103
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_compat.c138
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_device.c573
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_dummy.c261
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_fifo.c272
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_fifo.h72
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_info.c72
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_info.h40
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_lock.c49
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_lock.h33
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_memory.c521
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_memory.h107
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_midi.c481
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_midi_emul.c740
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_midi_event.c550
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_ports.c685
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_ports.h142
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_prioq.c453
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_prioq.h62
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_queue.c793
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_queue.h139
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_system.c175
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_system.h46
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_timer.c455
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_timer.h148
-rw-r--r--ANDROID_3.4.5/sound/core/seq/seq_virmidi.c543
-rw-r--r--ANDROID_3.4.5/sound/core/sgbuf.c138
-rw-r--r--ANDROID_3.4.5/sound/core/sound.c491
-rw-r--r--ANDROID_3.4.5/sound/core/sound_oss.c285
-rw-r--r--ANDROID_3.4.5/sound/core/timer.c1999
-rw-r--r--ANDROID_3.4.5/sound/core/timer_compat.c127
-rw-r--r--ANDROID_3.4.5/sound/core/vmaster.c455
-rw-r--r--ANDROID_3.4.5/sound/drivers/Kconfig223
-rw-r--r--ANDROID_3.4.5/sound/drivers/Makefile25
-rw-r--r--ANDROID_3.4.5/sound/drivers/aloop.c1258
-rw-r--r--ANDROID_3.4.5/sound/drivers/dummy.c1157
-rw-r--r--ANDROID_3.4.5/sound/drivers/ml403-ac97cr.c1344
-rw-r--r--ANDROID_3.4.5/sound/drivers/mpu401/Makefile12
-rw-r--r--ANDROID_3.4.5/sound/drivers/mpu401/mpu401.c288
-rw-r--r--ANDROID_3.4.5/sound/drivers/mpu401/mpu401_uart.c632
-rw-r--r--ANDROID_3.4.5/sound/drivers/mtpav.c792
-rw-r--r--ANDROID_3.4.5/sound/drivers/mts64.c1090
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl3/Makefile12
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl3/opl3_drums.c226
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl3/opl3_lib.c561
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl3/opl3_midi.c881
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl3/opl3_oss.c285
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl3/opl3_seq.c298
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl3/opl3_synth.c616
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl3/opl3_voice.h52
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl4/Makefile10
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl4/opl4_lib.c281
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl4/opl4_local.h232
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl4/opl4_mixer.c95
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl4/opl4_proc.c133
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl4/opl4_seq.c215
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl4/opl4_synth.c634
-rw-r--r--ANDROID_3.4.5/sound/drivers/opl4/yrw801.c961
-rw-r--r--ANDROID_3.4.5/sound/drivers/pcm-indirect2.c573
-rw-r--r--ANDROID_3.4.5/sound/drivers/pcm-indirect2.h140
-rw-r--r--ANDROID_3.4.5/sound/drivers/pcsp/Makefile2
-rw-r--r--ANDROID_3.4.5/sound/drivers/pcsp/pcsp.c244
-rw-r--r--ANDROID_3.4.5/sound/drivers/pcsp/pcsp.h82
-rw-r--r--ANDROID_3.4.5/sound/drivers/pcsp/pcsp_input.c116
-rw-r--r--ANDROID_3.4.5/sound/drivers/pcsp/pcsp_input.h14
-rw-r--r--ANDROID_3.4.5/sound/drivers/pcsp/pcsp_lib.c359
-rw-r--r--ANDROID_3.4.5/sound/drivers/pcsp/pcsp_mixer.c163
-rw-r--r--ANDROID_3.4.5/sound/drivers/portman2x4.c879
-rw-r--r--ANDROID_3.4.5/sound/drivers/serial-u16550.c1050
-rw-r--r--ANDROID_3.4.5/sound/drivers/virmidi.c197
-rw-r--r--ANDROID_3.4.5/sound/drivers/vx/Makefile8
-rw-r--r--ANDROID_3.4.5/sound/drivers/vx/vx_cmd.c109
-rw-r--r--ANDROID_3.4.5/sound/drivers/vx/vx_cmd.h246
-rw-r--r--ANDROID_3.4.5/sound/drivers/vx/vx_core.c828
-rw-r--r--ANDROID_3.4.5/sound/drivers/vx/vx_hwdep.c260
-rw-r--r--ANDROID_3.4.5/sound/drivers/vx/vx_mixer.c1028
-rw-r--r--ANDROID_3.4.5/sound/drivers/vx/vx_pcm.c1283
-rw-r--r--ANDROID_3.4.5/sound/drivers/vx/vx_uer.c312
-rw-r--r--ANDROID_3.4.5/sound/firewire/Kconfig36
-rw-r--r--ANDROID_3.4.5/sound/firewire/Makefile8
-rw-r--r--ANDROID_3.4.5/sound/firewire/amdtp.c563
-rw-r--r--ANDROID_3.4.5/sound/firewire/amdtp.h169
-rw-r--r--ANDROID_3.4.5/sound/firewire/cmp.c307
-rw-r--r--ANDROID_3.4.5/sound/firewire/cmp.h41
-rw-r--r--ANDROID_3.4.5/sound/firewire/fcp.c224
-rw-r--r--ANDROID_3.4.5/sound/firewire/fcp.h12
-rw-r--r--ANDROID_3.4.5/sound/firewire/isight.c753
-rw-r--r--ANDROID_3.4.5/sound/firewire/iso-resources.c232
-rw-r--r--ANDROID_3.4.5/sound/firewire/iso-resources.h38
-rw-r--r--ANDROID_3.4.5/sound/firewire/lib.c85
-rw-r--r--ANDROID_3.4.5/sound/firewire/lib.h19
-rw-r--r--ANDROID_3.4.5/sound/firewire/packets-buffer.c77
-rw-r--r--ANDROID_3.4.5/sound/firewire/packets-buffer.h26
-rw-r--r--ANDROID_3.4.5/sound/firewire/speakers.c854
-rw-r--r--ANDROID_3.4.5/sound/i2c/Makefile15
-rw-r--r--ANDROID_3.4.5/sound/i2c/cs8427.c616
-rw-r--r--ANDROID_3.4.5/sound/i2c/i2c.c353
-rw-r--r--ANDROID_3.4.5/sound/i2c/other/Makefile17
-rw-r--r--ANDROID_3.4.5/sound/i2c/other/ak4113.c639
-rw-r--r--ANDROID_3.4.5/sound/i2c/other/ak4114.c626
-rw-r--r--ANDROID_3.4.5/sound/i2c/other/ak4117.c552
-rw-r--r--ANDROID_3.4.5/sound/i2c/other/ak4xxx-adda.c945
-rw-r--r--ANDROID_3.4.5/sound/i2c/other/pt2258.c227
-rw-r--r--ANDROID_3.4.5/sound/i2c/other/tea575x-tuner.c427
-rw-r--r--ANDROID_3.4.5/sound/i2c/tea6330t.c386
-rw-r--r--ANDROID_3.4.5/sound/isa/Kconfig446
-rw-r--r--ANDROID_3.4.5/sound/isa/Makefile26
-rw-r--r--ANDROID_3.4.5/sound/isa/ad1816a/Makefile9
-rw-r--r--ANDROID_3.4.5/sound/isa/ad1816a/ad1816a.c294
-rw-r--r--ANDROID_3.4.5/sound/isa/ad1816a/ad1816a_lib.c972
-rw-r--r--ANDROID_3.4.5/sound/isa/ad1848/Makefile10
-rw-r--r--ANDROID_3.4.5/sound/isa/ad1848/ad1848.c188
-rw-r--r--ANDROID_3.4.5/sound/isa/adlib.c129
-rw-r--r--ANDROID_3.4.5/sound/isa/als100.c378
-rw-r--r--ANDROID_3.4.5/sound/isa/azt2320.c354
-rw-r--r--ANDROID_3.4.5/sound/isa/cmi8330.c782
-rw-r--r--ANDROID_3.4.5/sound/isa/cs423x/Makefile13
-rw-r--r--ANDROID_3.4.5/sound/isa/cs423x/cs4231.c204
-rw-r--r--ANDROID_3.4.5/sound/isa/cs423x/cs4236.c728
-rw-r--r--ANDROID_3.4.5/sound/isa/cs423x/cs4236_lib.c1089
-rw-r--r--ANDROID_3.4.5/sound/isa/es1688/Makefile11
-rw-r--r--ANDROID_3.4.5/sound/isa/es1688/es1688.c372
-rw-r--r--ANDROID_3.4.5/sound/isa/es1688/es1688_lib.c1046
-rw-r--r--ANDROID_3.4.5/sound/isa/es18xx.c2434
-rw-r--r--ANDROID_3.4.5/sound/isa/galaxy/Makefile10
-rw-r--r--ANDROID_3.4.5/sound/isa/galaxy/azt1605.c91
-rw-r--r--ANDROID_3.4.5/sound/isa/galaxy/azt2316.c111
-rw-r--r--ANDROID_3.4.5/sound/isa/galaxy/galaxy.c651
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/Makefile24
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/gus_dma.c250
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/gus_dram.c102
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/gus_instr.c172
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/gus_io.c540
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/gus_irq.c149
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/gus_main.c483
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/gus_mem.c351
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/gus_mem_proc.c102
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/gus_mixer.c193
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/gus_pcm.c910
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/gus_reset.c413
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/gus_tables.h90
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/gus_timer.c203
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/gus_uart.c262
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/gus_volume.c218
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/gusclassic.c245
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/gusextreme.c373
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/gusmax.c387
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/interwave-stb.c2
-rw-r--r--ANDROID_3.4.5/sound/isa/gus/interwave.c947
-rw-r--r--ANDROID_3.4.5/sound/isa/msnd/Makefile9
-rw-r--r--ANDROID_3.4.5/sound/isa/msnd/msnd.c708
-rw-r--r--ANDROID_3.4.5/sound/isa/msnd/msnd.h308
-rw-r--r--ANDROID_3.4.5/sound/isa/msnd/msnd_classic.c3
-rw-r--r--ANDROID_3.4.5/sound/isa/msnd/msnd_classic.h129
-rw-r--r--ANDROID_3.4.5/sound/isa/msnd/msnd_midi.c182
-rw-r--r--ANDROID_3.4.5/sound/isa/msnd/msnd_pinnacle.c1245
-rw-r--r--ANDROID_3.4.5/sound/isa/msnd/msnd_pinnacle.h181
-rw-r--r--ANDROID_3.4.5/sound/isa/msnd/msnd_pinnacle_mixer.c344
-rw-r--r--ANDROID_3.4.5/sound/isa/opl3sa2.c971
-rw-r--r--ANDROID_3.4.5/sound/isa/opti9xx/Makefile15
-rw-r--r--ANDROID_3.4.5/sound/isa/opti9xx/miro.c1680
-rw-r--r--ANDROID_3.4.5/sound/isa/opti9xx/opti92x-ad1848.c1165
-rw-r--r--ANDROID_3.4.5/sound/isa/opti9xx/opti92x-cs4231.c2
-rw-r--r--ANDROID_3.4.5/sound/isa/opti9xx/opti93x.c3
-rw-r--r--ANDROID_3.4.5/sound/isa/sb/Makefile28
-rw-r--r--ANDROID_3.4.5/sound/isa/sb/emu8000.c1163
-rw-r--r--ANDROID_3.4.5/sound/isa/sb/emu8000_callback.c547
-rw-r--r--ANDROID_3.4.5/sound/isa/sb/emu8000_local.h45
-rw-r--r--ANDROID_3.4.5/sound/isa/sb/emu8000_patch.c305
-rw-r--r--ANDROID_3.4.5/sound/isa/sb/emu8000_pcm.c705
-rw-r--r--ANDROID_3.4.5/sound/isa/sb/emu8000_synth.c136
-rw-r--r--ANDROID_3.4.5/sound/isa/sb/jazz16.c404
-rw-r--r--ANDROID_3.4.5/sound/isa/sb/sb16.c699
-rw-r--r--ANDROID_3.4.5/sound/isa/sb/sb16_csp.c1202
-rw-r--r--ANDROID_3.4.5/sound/isa/sb/sb16_main.c925
-rw-r--r--ANDROID_3.4.5/sound/isa/sb/sb8.c268
-rw-r--r--ANDROID_3.4.5/sound/isa/sb/sb8_main.c646
-rw-r--r--ANDROID_3.4.5/sound/isa/sb/sb8_midi.c286
-rw-r--r--ANDROID_3.4.5/sound/isa/sb/sb_common.c324
-rw-r--r--ANDROID_3.4.5/sound/isa/sb/sb_mixer.c978
-rw-r--r--ANDROID_3.4.5/sound/isa/sb/sbawe.c2
-rw-r--r--ANDROID_3.4.5/sound/isa/sc6000.c728
-rw-r--r--ANDROID_3.4.5/sound/isa/sscape.c1359
-rw-r--r--ANDROID_3.4.5/sound/isa/wavefront/Makefile9
-rw-r--r--ANDROID_3.4.5/sound/isa/wavefront/wavefront.c687
-rw-r--r--ANDROID_3.4.5/sound/isa/wavefront/wavefront_fx.c285
-rw-r--r--ANDROID_3.4.5/sound/isa/wavefront/wavefront_midi.c577
-rw-r--r--ANDROID_3.4.5/sound/isa/wavefront/wavefront_synth.c2199
-rw-r--r--ANDROID_3.4.5/sound/isa/wss/Makefile10
-rw-r--r--ANDROID_3.4.5/sound/isa/wss/wss_lib.c2304
-rw-r--r--ANDROID_3.4.5/sound/last.c41
-rw-r--r--ANDROID_3.4.5/sound/mips/Kconfig37
-rw-r--r--ANDROID_3.4.5/sound/mips/Makefile12
-rw-r--r--ANDROID_3.4.5/sound/mips/ad1843.c561
-rw-r--r--ANDROID_3.4.5/sound/mips/au1x00.c696
-rw-r--r--ANDROID_3.4.5/sound/mips/hal2.c938
-rw-r--r--ANDROID_3.4.5/sound/mips/hal2.h245
-rw-r--r--ANDROID_3.4.5/sound/mips/sgio2audio.c979
-rw-r--r--ANDROID_3.4.5/sound/oss/CHANGELOG369
-rw-r--r--ANDROID_3.4.5/sound/oss/Kconfig541
-rw-r--r--ANDROID_3.4.5/sound/oss/Makefile108
-rw-r--r--ANDROID_3.4.5/sound/oss/README.FIRST6
-rw-r--r--ANDROID_3.4.5/sound/oss/ad1848.c3069
-rw-r--r--ANDROID_3.4.5/sound/oss/ad1848.h24
-rw-r--r--ANDROID_3.4.5/sound/oss/ad1848_mixer.h253
-rw-r--r--ANDROID_3.4.5/sound/oss/aedsp16.c1373
-rw-r--r--ANDROID_3.4.5/sound/oss/audio.c985
-rw-r--r--ANDROID_3.4.5/sound/oss/bin2hex.c39
-rw-r--r--ANDROID_3.4.5/sound/oss/coproc.h12
-rw-r--r--ANDROID_3.4.5/sound/oss/dev_table.c256
-rw-r--r--ANDROID_3.4.5/sound/oss/dev_table.h390
-rw-r--r--ANDROID_3.4.5/sound/oss/dmabuf.c1268
-rw-r--r--ANDROID_3.4.5/sound/oss/dmasound/Kconfig45
-rw-r--r--ANDROID_3.4.5/sound/oss/dmasound/Makefile7
-rw-r--r--ANDROID_3.4.5/sound/oss/dmasound/dmasound.h262
-rw-r--r--ANDROID_3.4.5/sound/oss/dmasound/dmasound_atari.c1620
-rw-r--r--ANDROID_3.4.5/sound/oss/dmasound/dmasound_core.c1589
-rw-r--r--ANDROID_3.4.5/sound/oss/dmasound/dmasound_paula.c751
-rw-r--r--ANDROID_3.4.5/sound/oss/dmasound/dmasound_q40.c638
-rw-r--r--ANDROID_3.4.5/sound/oss/hex2hex.c101
-rw-r--r--ANDROID_3.4.5/sound/oss/kahlua.c231
-rw-r--r--ANDROID_3.4.5/sound/oss/midi_ctrl.h22
-rw-r--r--ANDROID_3.4.5/sound/oss/midi_synth.c712
-rw-r--r--ANDROID_3.4.5/sound/oss/midi_synth.h47
-rw-r--r--ANDROID_3.4.5/sound/oss/midibuf.c425
-rw-r--r--ANDROID_3.4.5/sound/oss/mpu401.c1806
-rw-r--r--ANDROID_3.4.5/sound/oss/mpu401.h11
-rw-r--r--ANDROID_3.4.5/sound/oss/msnd.c413
-rw-r--r--ANDROID_3.4.5/sound/oss/msnd.h278
-rw-r--r--ANDROID_3.4.5/sound/oss/msnd_classic.c3
-rw-r--r--ANDROID_3.4.5/sound/oss/msnd_classic.h185
-rw-r--r--ANDROID_3.4.5/sound/oss/msnd_pinnacle.c1935
-rw-r--r--ANDROID_3.4.5/sound/oss/msnd_pinnacle.h246
-rw-r--r--ANDROID_3.4.5/sound/oss/opl3.c1258
-rw-r--r--ANDROID_3.4.5/sound/oss/opl3_hw.h246
-rw-r--r--ANDROID_3.4.5/sound/oss/os.h45
-rw-r--r--ANDROID_3.4.5/sound/oss/pas2.h17
-rw-r--r--ANDROID_3.4.5/sound/oss/pas2_card.c455
-rw-r--r--ANDROID_3.4.5/sound/oss/pas2_midi.c262
-rw-r--r--ANDROID_3.4.5/sound/oss/pas2_mixer.c336
-rw-r--r--ANDROID_3.4.5/sound/oss/pas2_pcm.c437
-rw-r--r--ANDROID_3.4.5/sound/oss/pss.c1268
-rw-r--r--ANDROID_3.4.5/sound/oss/sb.h185
-rw-r--r--ANDROID_3.4.5/sound/oss/sb_audio.c1098
-rw-r--r--ANDROID_3.4.5/sound/oss/sb_card.c354
-rw-r--r--ANDROID_3.4.5/sound/oss/sb_card.h149
-rw-r--r--ANDROID_3.4.5/sound/oss/sb_common.c1292
-rw-r--r--ANDROID_3.4.5/sound/oss/sb_ess.c1831
-rw-r--r--ANDROID_3.4.5/sound/oss/sb_ess.h34
-rw-r--r--ANDROID_3.4.5/sound/oss/sb_midi.c206
-rw-r--r--ANDROID_3.4.5/sound/oss/sb_mixer.c770
-rw-r--r--ANDROID_3.4.5/sound/oss/sb_mixer.h105
-rw-r--r--ANDROID_3.4.5/sound/oss/sequencer.c1671
-rw-r--r--ANDROID_3.4.5/sound/oss/sound_calls.h87
-rw-r--r--ANDROID_3.4.5/sound/oss/sound_config.h147
-rw-r--r--ANDROID_3.4.5/sound/oss/sound_firmware.h2
-rw-r--r--ANDROID_3.4.5/sound/oss/sound_timer.c327
-rw-r--r--ANDROID_3.4.5/sound/oss/soundcard.c739
-rw-r--r--ANDROID_3.4.5/sound/oss/soundvers.h2
-rw-r--r--ANDROID_3.4.5/sound/oss/swarm_cs4297a.c2768
-rw-r--r--ANDROID_3.4.5/sound/oss/sys_timer.c285
-rw-r--r--ANDROID_3.4.5/sound/oss/trix.c525
-rw-r--r--ANDROID_3.4.5/sound/oss/tuning.h23
-rw-r--r--ANDROID_3.4.5/sound/oss/uart401.c482
-rw-r--r--ANDROID_3.4.5/sound/oss/uart6850.c361
-rw-r--r--ANDROID_3.4.5/sound/oss/ulaw.h69
-rw-r--r--ANDROID_3.4.5/sound/oss/v_midi.c290
-rw-r--r--ANDROID_3.4.5/sound/oss/v_midi.h14
-rw-r--r--ANDROID_3.4.5/sound/oss/vidc.c557
-rw-r--r--ANDROID_3.4.5/sound/oss/vidc.h63
-rw-r--r--ANDROID_3.4.5/sound/oss/vidc_fill.S218
-rw-r--r--ANDROID_3.4.5/sound/oss/vwsnd.c3498
-rw-r--r--ANDROID_3.4.5/sound/oss/waveartist.c2024
-rw-r--r--ANDROID_3.4.5/sound/oss/waveartist.h92
-rw-r--r--ANDROID_3.4.5/sound/parisc/Kconfig20
-rw-r--r--ANDROID_3.4.5/sound/parisc/Makefile8
-rw-r--r--ANDROID_3.4.5/sound/parisc/harmony.c1047
-rw-r--r--ANDROID_3.4.5/sound/parisc/harmony.h154
-rw-r--r--ANDROID_3.4.5/sound/pci/Kconfig872
-rw-r--r--ANDROID_3.4.5/sound/pci/Makefile82
-rw-r--r--ANDROID_3.4.5/sound/pci/ac97/Makefile10
-rw-r--r--ANDROID_3.4.5/sound/pci/ac97/ac97_codec.c2937
-rw-r--r--ANDROID_3.4.5/sound/pci/ac97/ac97_id.h66
-rw-r--r--ANDROID_3.4.5/sound/pci/ac97/ac97_local.h41
-rw-r--r--ANDROID_3.4.5/sound/pci/ac97/ac97_patch.c3965
-rw-r--r--ANDROID_3.4.5/sound/pci/ac97/ac97_patch.h95
-rw-r--r--ANDROID_3.4.5/sound/pci/ac97/ac97_pcm.c737
-rw-r--r--ANDROID_3.4.5/sound/pci/ac97/ac97_proc.c490
-rw-r--r--ANDROID_3.4.5/sound/pci/ad1889.c1078
-rw-r--r--ANDROID_3.4.5/sound/pci/ad1889.h189
-rw-r--r--ANDROID_3.4.5/sound/pci/ak4531_codec.c494
-rw-r--r--ANDROID_3.4.5/sound/pci/ali5451/Makefile9
-rw-r--r--ANDROID_3.4.5/sound/pci/ali5451/ali5451.c2319
-rw-r--r--ANDROID_3.4.5/sound/pci/als300.c877
-rw-r--r--ANDROID_3.4.5/sound/pci/als4000.c1061
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/Makefile5
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/asihpi.c2992
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpi.h1727
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpi6000.c1809
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpi6000.h70
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpi6205.c2208
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpi6205.h103
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpi_internal.h1431
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpi_version.h32
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpicmn.c703
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpicmn.h67
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpidebug.c78
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpidebug.h102
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpidspcd.c148
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpidspcd.h106
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpifunc.c2871
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpimsginit.c116
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpimsginit.h46
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpimsgx.c800
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpimsgx.h36
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpioctl.c482
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpioctl.h38
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpios.c83
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpios.h165
-rw-r--r--ANDROID_3.4.5/sound/pci/asihpi/hpipcida.h37
-rw-r--r--ANDROID_3.4.5/sound/pci/atiixp.c1726
-rw-r--r--ANDROID_3.4.5/sound/pci/atiixp_modem.c1357
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/Makefile7
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au8810.c16
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au8810.h224
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au8820.c14
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au8820.h204
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au8830.c17
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au8830.h251
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au88x0.c398
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au88x0.h295
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au88x0_a3d.c914
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au88x0_a3d.h123
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au88x0_a3ddata.c91
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au88x0_core.c2856
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au88x0_eq.c929
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au88x0_eq.h43
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au88x0_eqdata.c116
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au88x0_game.c133
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au88x0_mixer.c32
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au88x0_mpu401.c112
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au88x0_pcm.c678
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au88x0_synth.c418
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au88x0_wt.h65
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au88x0_xtalk.c795
-rw-r--r--ANDROID_3.4.5/sound/pci/au88x0/au88x0_xtalk.h61
-rw-r--r--ANDROID_3.4.5/sound/pci/aw2/Makefile3
-rw-r--r--ANDROID_3.4.5/sound/pci/aw2/aw2-alsa.c792
-rw-r--r--ANDROID_3.4.5/sound/pci/aw2/aw2-saa7146.c463
-rw-r--r--ANDROID_3.4.5/sound/pci/aw2/aw2-saa7146.h105
-rw-r--r--ANDROID_3.4.5/sound/pci/aw2/aw2-tsl.c110
-rw-r--r--ANDROID_3.4.5/sound/pci/aw2/saa7146.h168
-rw-r--r--ANDROID_3.4.5/sound/pci/azt3328.c2895
-rw-r--r--ANDROID_3.4.5/sound/pci/azt3328.h342
-rw-r--r--ANDROID_3.4.5/sound/pci/bt87x.c987
-rw-r--r--ANDROID_3.4.5/sound/pci/ca0106/Makefile3
-rw-r--r--ANDROID_3.4.5/sound/pci/ca0106/ca0106.h742
-rw-r--r--ANDROID_3.4.5/sound/pci/ca0106/ca0106_main.c1959
-rw-r--r--ANDROID_3.4.5/sound/pci/ca0106/ca0106_mixer.c956
-rw-r--r--ANDROID_3.4.5/sound/pci/ca0106/ca0106_proc.c457
-rw-r--r--ANDROID_3.4.5/sound/pci/ca0106/ca_midi.c316
-rw-r--r--ANDROID_3.4.5/sound/pci/ca0106/ca_midi.h66
-rw-r--r--ANDROID_3.4.5/sound/pci/cmipci.c3423
-rw-r--r--ANDROID_3.4.5/sound/pci/cs4281.c2109
-rw-r--r--ANDROID_3.4.5/sound/pci/cs46xx/Makefile10
-rw-r--r--ANDROID_3.4.5/sound/pci/cs46xx/cs46xx.c186
-rw-r--r--ANDROID_3.4.5/sound/pci/cs46xx/cs46xx_image.h3468
-rw-r--r--ANDROID_3.4.5/sound/pci/cs46xx/cs46xx_lib.c3882
-rw-r--r--ANDROID_3.4.5/sound/pci/cs46xx/cs46xx_lib.h210
-rw-r--r--ANDROID_3.4.5/sound/pci/cs46xx/dsp_spos.c2017
-rw-r--r--ANDROID_3.4.5/sound/pci/cs46xx/dsp_spos.h231
-rw-r--r--ANDROID_3.4.5/sound/pci/cs46xx/dsp_spos_scb_lib.c1784
-rw-r--r--ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwc4630.h320
-rw-r--r--ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwcasync.h176
-rw-r--r--ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwcbinhack.h48
-rw-r--r--ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwcdma.asp170
-rw-r--r--ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwcdma.h68
-rw-r--r--ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwcsnoop.h46
-rw-r--r--ANDROID_3.4.5/sound/pci/cs5530.c313
-rw-r--r--ANDROID_3.4.5/sound/pci/cs5535audio/Makefile10
-rw-r--r--ANDROID_3.4.5/sound/pci/cs5535audio/cs5535audio.c424
-rw-r--r--ANDROID_3.4.5/sound/pci/cs5535audio/cs5535audio.h142
-rw-r--r--ANDROID_3.4.5/sound/pci/cs5535audio/cs5535audio_olpc.c191
-rw-r--r--ANDROID_3.4.5/sound/pci/cs5535audio/cs5535audio_pcm.c454
-rw-r--r--ANDROID_3.4.5/sound/pci/cs5535audio/cs5535audio_pm.c131
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/Makefile5
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/ct20k1reg.h636
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/ct20k2reg.h89
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/ctamixer.c486
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/ctamixer.h96
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/ctatc.c1744
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/ctatc.h160
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/ctdaio.c762
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/ctdaio.h123
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/cthardware.c91
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/cthardware.h215
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/cthw20k1.c2304
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/cthw20k1.h26
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/cthw20k2.c2370
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/cthw20k2.h26
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/ctimap.c112
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/ctimap.h40
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/ctmixer.c1227
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/ctmixer.h70
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/ctpcm.c435
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/ctpcm.h27
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/ctresource.c301
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/ctresource.h72
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/ctsrc.c885
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/ctsrc.h149
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/cttimer.c443
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/cttimer.h29
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/ctvmem.c247
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/ctvmem.h63
-rw-r--r--ANDROID_3.4.5/sound/pci/ctxfi/xfi.c168
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/Makefile34
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/darla20.c101
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/darla20_dsp.c130
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/darla24.c108
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/darla24_dsp.c162
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/echo3g.c122
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/echo3g_dsp.c132
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/echoaudio.c2360
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/echoaudio.h598
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_3g.c432
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_dsp.c1151
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_dsp.h698
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_gml.c200
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/gina20.c105
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/gina20_dsp.c220
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/gina24.c129
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/gina24_dsp.c349
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/indigo.c107
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/indigo_dsp.c164
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/indigo_express_dsp.c120
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/indigodj.c107
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/indigodj_dsp.c164
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/indigodjx.c108
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/indigodjx_dsp.c71
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/indigoio.c108
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/indigoio_dsp.c135
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/indigoiox.c110
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/indigoiox_dsp.c71
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/layla20.c115
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/layla20_dsp.c295
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/layla24.c127
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/layla24_dsp.c398
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/mia.c121
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/mia_dsp.c224
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/midi.c331
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/mona.c138
-rw-r--r--ANDROID_3.4.5/sound/pci/echoaudio/mona_dsp.c427
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/Makefile15
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/emu10k1.c288
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/emu10k1_callback.c552
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/emu10k1_main.c2101
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/emu10k1_patch.c229
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/emu10k1_synth.c124
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/emu10k1_synth_local.h42
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/emu10k1x.c1635
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/emufx.c2758
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/emumixer.c2143
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/emumpu401.c396
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/emupcm.c1870
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/emuproc.c671
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/io.c583
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/irq.c208
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/memory.c573
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/p16v.c934
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/p16v.h299
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/p17v.h158
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/timer.c96
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/tina2.h32
-rw-r--r--ANDROID_3.4.5/sound/pci/emu10k1/voice.c168
-rw-r--r--ANDROID_3.4.5/sound/pci/ens1370.c2513
-rw-r--r--ANDROID_3.4.5/sound/pci/ens1371.c2
-rw-r--r--ANDROID_3.4.5/sound/pci/es1938.c1907
-rw-r--r--ANDROID_3.4.5/sound/pci/es1968.c2923
-rw-r--r--ANDROID_3.4.5/sound/pci/fm801.c1441
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/Kconfig261
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/Makefile65
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/hda_beep.c268
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/hda_beep.h61
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/hda_codec.c5548
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/hda_codec.h1084
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/hda_eld.c671
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/hda_generic.c1085
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/hda_hwdep.c817
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/hda_intel.c3173
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/hda_jack.c375
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/hda_jack.h75
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/hda_local.h708
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/hda_proc.c742
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/hda_trace.h117
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/patch_analog.c5067
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/patch_ca0110.c576
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/patch_ca0132.c1103
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/patch_cirrus.c2053
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/patch_cmedia.c776
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/patch_conexant.c4599
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/patch_hdmi.c1986
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/patch_realtek.c7034
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/patch_si3054.c337
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/patch_sigmatel.c6515
-rw-r--r--ANDROID_3.4.5/sound/pci/hda/patch_via.c3935
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/Makefile12
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/ak4xxx.c196
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/amp.c98
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/amp.h48
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/aureon.c2308
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/aureon.h65
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/delta.c881
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/delta.h166
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/envy24ht.h220
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/ews.c1087
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/ews.h86
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/hoontech.c360
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/hoontech.h77
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/ice1712.c2824
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/ice1712.h531
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/ice1724.c2898
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/juli.c700
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/juli.h10
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/maya44.c779
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/maya44.h10
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/phase.c975
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/phase.h53
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/pontis.c836
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/pontis.h33
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/prodigy192.c822
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/prodigy192.h19
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/prodigy_hifi.c1236
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/prodigy_hifi.h38
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/quartet.c1130
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/quartet.h10
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/revo.c633
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/revo.h55
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/se.c774
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/se.h15
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/stac946x.h25
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/vt1720_mobo.c139
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/vt1720_mobo.h41
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/wtm.c517
-rw-r--r--ANDROID_3.4.5/sound/pci/ice1712/wtm.h20
-rw-r--r--ANDROID_3.4.5/sound/pci/intel8x0.c3364
-rw-r--r--ANDROID_3.4.5/sound/pci/intel8x0m.c1350
-rw-r--r--ANDROID_3.4.5/sound/pci/korg1212/Makefile9
-rw-r--r--ANDROID_3.4.5/sound/pci/korg1212/korg1212.c2497
-rw-r--r--ANDROID_3.4.5/sound/pci/lola/Makefile4
-rw-r--r--ANDROID_3.4.5/sound/pci/lola/lola.c791
-rw-r--r--ANDROID_3.4.5/sound/pci/lola/lola.h527
-rw-r--r--ANDROID_3.4.5/sound/pci/lola/lola_clock.c323
-rw-r--r--ANDROID_3.4.5/sound/pci/lola/lola_mixer.c895
-rw-r--r--ANDROID_3.4.5/sound/pci/lola/lola_pcm.c706
-rw-r--r--ANDROID_3.4.5/sound/pci/lola/lola_proc.c222
-rw-r--r--ANDROID_3.4.5/sound/pci/lx6464es/Makefile2
-rw-r--r--ANDROID_3.4.5/sound/pci/lx6464es/lx6464es.c1164
-rw-r--r--ANDROID_3.4.5/sound/pci/lx6464es/lx6464es.h114
-rw-r--r--ANDROID_3.4.5/sound/pci/lx6464es/lx_core.c1357
-rw-r--r--ANDROID_3.4.5/sound/pci/lx6464es/lx_core.h239
-rw-r--r--ANDROID_3.4.5/sound/pci/lx6464es/lx_defs.h376
-rw-r--r--ANDROID_3.4.5/sound/pci/maestro3.c2862
-rw-r--r--ANDROID_3.4.5/sound/pci/mixart/Makefile8
-rw-r--r--ANDROID_3.4.5/sound/pci/mixart/mixart.c1401
-rw-r--r--ANDROID_3.4.5/sound/pci/mixart/mixart.h228
-rw-r--r--ANDROID_3.4.5/sound/pci/mixart/mixart_core.c598
-rw-r--r--ANDROID_3.4.5/sound/pci/mixart/mixart_core.h571
-rw-r--r--ANDROID_3.4.5/sound/pci/mixart/mixart_hwdep.c653
-rw-r--r--ANDROID_3.4.5/sound/pci/mixart/mixart_hwdep.h155
-rw-r--r--ANDROID_3.4.5/sound/pci/mixart/mixart_mixer.c1186
-rw-r--r--ANDROID_3.4.5/sound/pci/mixart/mixart_mixer.h31
-rw-r--r--ANDROID_3.4.5/sound/pci/nm256/Makefile9
-rw-r--r--ANDROID_3.4.5/sound/pci/nm256/nm256.c1768
-rw-r--r--ANDROID_3.4.5/sound/pci/nm256/nm256_coef.c4607
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/Makefile8
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/ak4396.h44
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/cm9780.h63
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/cs2000.h83
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/cs4245.h107
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/cs4362a.h69
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/cs4398.h69
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/oxygen.c884
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/oxygen.h260
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/oxygen_io.c279
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/oxygen_lib.c834
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/oxygen_mixer.c1102
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/oxygen_pcm.c766
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/oxygen_regs.h457
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/pcm1796.h58
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/virtuoso.c114
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/wm8766.h73
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/wm8776.h177
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/wm8785.h45
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/xonar.h54
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/xonar_cs43xx.c452
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/xonar_dg.c609
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/xonar_dg.h8
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/xonar_hdmi.c128
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/xonar_lib.c134
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/xonar_pcm179x.c1145
-rw-r--r--ANDROID_3.4.5/sound/pci/oxygen/xonar_wm87x6.c1338
-rw-r--r--ANDROID_3.4.5/sound/pci/pcxhr/Makefile2
-rw-r--r--ANDROID_3.4.5/sound/pci/pcxhr/pcxhr.c1628
-rw-r--r--ANDROID_3.4.5/sound/pci/pcxhr/pcxhr.h216
-rw-r--r--ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_core.c1305
-rw-r--r--ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_core.h203
-rw-r--r--ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_hwdep.c503
-rw-r--r--ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_hwdep.h40
-rw-r--r--ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_mix22.c852
-rw-r--r--ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_mix22.h59
-rw-r--r--ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_mixer.c1270
-rw-r--r--ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_mixer.h29
-rw-r--r--ANDROID_3.4.5/sound/pci/riptide/Makefile3
-rw-r--r--ANDROID_3.4.5/sound/pci/riptide/riptide.c2223
-rw-r--r--ANDROID_3.4.5/sound/pci/rme32.c2005
-rw-r--r--ANDROID_3.4.5/sound/pci/rme96.c2416
-rw-r--r--ANDROID_3.4.5/sound/pci/rme9652/Makefile13
-rw-r--r--ANDROID_3.4.5/sound/pci/rme9652/hdsp.c5657
-rw-r--r--ANDROID_3.4.5/sound/pci/rme9652/hdspm.c6940
-rw-r--r--ANDROID_3.4.5/sound/pci/rme9652/rme9652.c2652
-rw-r--r--ANDROID_3.4.5/sound/pci/sis7019.c1502
-rw-r--r--ANDROID_3.4.5/sound/pci/sis7019.h342
-rw-r--r--ANDROID_3.4.5/sound/pci/sonicvibes.c1551
-rw-r--r--ANDROID_3.4.5/sound/pci/trident/Makefile9
-rw-r--r--ANDROID_3.4.5/sound/pci/trident/trident.c197
-rw-r--r--ANDROID_3.4.5/sound/pci/trident/trident_main.c3982
-rw-r--r--ANDROID_3.4.5/sound/pci/trident/trident_memory.c315
-rw-r--r--ANDROID_3.4.5/sound/pci/via82xx.c2644
-rw-r--r--ANDROID_3.4.5/sound/pci/via82xx_modem.c1248
-rw-r--r--ANDROID_3.4.5/sound/pci/vx222/Makefile8
-rw-r--r--ANDROID_3.4.5/sound/pci/vx222/vx222.c314
-rw-r--r--ANDROID_3.4.5/sound/pci/vx222/vx222.h114
-rw-r--r--ANDROID_3.4.5/sound/pci/vx222/vx222_ops.c1031
-rw-r--r--ANDROID_3.4.5/sound/pci/ymfpci/Makefile9
-rw-r--r--ANDROID_3.4.5/sound/pci/ymfpci/ymfpci.c375
-rw-r--r--ANDROID_3.4.5/sound/pci/ymfpci/ymfpci_main.c2470
-rw-r--r--ANDROID_3.4.5/sound/pcmcia/Kconfig33
-rw-r--r--ANDROID_3.4.5/sound/pcmcia/Makefile6
-rw-r--r--ANDROID_3.4.5/sound/pcmcia/pdaudiocf/Makefile8
-rw-r--r--ANDROID_3.4.5/sound/pcmcia/pdaudiocf/pdaudiocf.c312
-rw-r--r--ANDROID_3.4.5/sound/pcmcia/pdaudiocf/pdaudiocf.h142
-rw-r--r--ANDROID_3.4.5/sound/pcmcia/pdaudiocf/pdaudiocf_core.c298
-rw-r--r--ANDROID_3.4.5/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c325
-rw-r--r--ANDROID_3.4.5/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c307
-rw-r--r--ANDROID_3.4.5/sound/pcmcia/vx/Makefile8
-rw-r--r--ANDROID_3.4.5/sound/pcmcia/vx/vxp_mixer.c151
-rw-r--r--ANDROID_3.4.5/sound/pcmcia/vx/vxp_ops.c614
-rw-r--r--ANDROID_3.4.5/sound/pcmcia/vx/vxpocket.c382
-rw-r--r--ANDROID_3.4.5/sound/pcmcia/vx/vxpocket.h90
-rw-r--r--ANDROID_3.4.5/sound/ppc/Kconfig52
-rw-r--r--ANDROID_3.4.5/sound/ppc/Makefile10
-rw-r--r--ANDROID_3.4.5/sound/ppc/awacs.c1146
-rw-r--r--ANDROID_3.4.5/sound/ppc/awacs.h205
-rw-r--r--ANDROID_3.4.5/sound/ppc/beep.c285
-rw-r--r--ANDROID_3.4.5/sound/ppc/burgundy.c732
-rw-r--r--ANDROID_3.4.5/sound/ppc/burgundy.h114
-rw-r--r--ANDROID_3.4.5/sound/ppc/daca.c282
-rw-r--r--ANDROID_3.4.5/sound/ppc/keywest.c147
-rw-r--r--ANDROID_3.4.5/sound/ppc/pmac.c1410
-rw-r--r--ANDROID_3.4.5/sound/ppc/pmac.h210
-rw-r--r--ANDROID_3.4.5/sound/ppc/powermac.c195
-rw-r--r--ANDROID_3.4.5/sound/ppc/snd_ps3.c1160
-rw-r--r--ANDROID_3.4.5/sound/ppc/snd_ps3.h136
-rw-r--r--ANDROID_3.4.5/sound/ppc/snd_ps3_reg.h891
-rw-r--r--ANDROID_3.4.5/sound/ppc/tumbler.c1495
-rw-r--r--ANDROID_3.4.5/sound/ppc/tumbler_volume.h250
-rw-r--r--ANDROID_3.4.5/sound/sh/Kconfig31
-rw-r--r--ANDROID_3.4.5/sound/sh/Makefile10
-rw-r--r--ANDROID_3.4.5/sound/sh/aica.c689
-rw-r--r--ANDROID_3.4.5/sound/sh/aica.h81
-rw-r--r--ANDROID_3.4.5/sound/sh/sh_dac_audio.c444
-rw-r--r--ANDROID_3.4.5/sound/soc/Kconfig57
-rw-r--r--ANDROID_3.4.5/sound/soc/Makefile28
-rw-r--r--ANDROID_3.4.5/sound/soc/atmel/Kconfig33
-rw-r--r--ANDROID_3.4.5/sound/soc/atmel/Makefile12
-rw-r--r--ANDROID_3.4.5/sound/soc/atmel/atmel-pcm.c501
-rw-r--r--ANDROID_3.4.5/sound/soc/atmel/atmel-pcm.h83
-rw-r--r--ANDROID_3.4.5/sound/soc/atmel/atmel_ssc_dai.c867
-rw-r--r--ANDROID_3.4.5/sound/soc/atmel/atmel_ssc_dai.h122
-rw-r--r--ANDROID_3.4.5/sound/soc/atmel/sam9g20_wm8731.c280
-rw-r--r--ANDROID_3.4.5/sound/soc/atmel/snd-soc-afeb9260.c163
-rw-r--r--ANDROID_3.4.5/sound/soc/au1x/Kconfig64
-rw-r--r--ANDROID_3.4.5/sound/soc/au1x/Makefile23
-rw-r--r--ANDROID_3.4.5/sound/soc/au1x/ac97c.c352
-rw-r--r--ANDROID_3.4.5/sound/soc/au1x/db1000.c65
-rw-r--r--ANDROID_3.4.5/sound/soc/au1x/db1200.c211
-rw-r--r--ANDROID_3.4.5/sound/soc/au1x/dbdma2.c385
-rw-r--r--ANDROID_3.4.5/sound/soc/au1x/dma.c358
-rw-r--r--ANDROID_3.4.5/sound/soc/au1x/i2sc.c319
-rw-r--r--ANDROID_3.4.5/sound/soc/au1x/psc-ac97.c518
-rw-r--r--ANDROID_3.4.5/sound/soc/au1x/psc-i2s.c428
-rw-r--r--ANDROID_3.4.5/sound/soc/au1x/psc.h42
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/Kconfig181
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/Makefile35
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ac97-pcm.c481
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ac97-pcm.h26
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ac97.c382
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ac97.h59
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ad1836.c123
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ad193x.c151
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ad1980.c112
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ad73311.c213
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bf5xx-i2s-pcm.c320
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bf5xx-i2s-pcm.h26
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bf5xx-i2s.c297
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bf5xx-sport.c1094
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bf5xx-sport.h174
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ssm2602.c156
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bf5xx-tdm-pcm.c345
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bf5xx-tdm-pcm.h18
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bf5xx-tdm.c323
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bf5xx-tdm.h23
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bfin-eval-adau1373.c184
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bfin-eval-adau1701.c124
-rw-r--r--ANDROID_3.4.5/sound/soc/blackfin/bfin-eval-adav80x.c156
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/88pm860x-codec.c1488
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/88pm860x-codec.h97
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/Kconfig455
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/Makefile219
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/ac97.c156
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/ad1836.c398
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/ad1836.h51
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/ad193x.c538
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/ad193x.h85
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/ad1980.c284
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/ad1980.h26
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/ad73311.c70
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/ad73311.h88
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/adau1373.c1409
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/adau1373.h29
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/adau1701.c546
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/adau1701.h17
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/adav80x.c952
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/adav80x.h35
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/ads117x.c65
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/ak4104.c258
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/ak4535.c497
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/ak4535.h37
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/ak4641.c664
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/ak4641.h47
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/ak4642.c590
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/ak4671.c713
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/ak4671.h153
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/alc5623.c1109
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/alc5623.h161
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/alc5632.c1234
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/alc5632.h252
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/cq93vc.c211
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/cs4270.c740
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/cs4271.c664
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/cs42l51.c639
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/cs42l51.h161
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/cs42l73.c1455
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/cs42l73.h227
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/cx20442.c443
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/cx20442.h18
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/da7210.c1151
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/dfbmcs320.c62
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/dmic.c96
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/jz4740.c431
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/l3.c91
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/lm4857.c267
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/max9768.c247
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/max98088.c2130
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/max98088.h206
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/max98095.c2399
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/max98095.h299
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/max9850.c386
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/max9850.h38
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/max9877.c308
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/max9877.h37
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/pcm3008.c179
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/pcm3008.h22
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/rt5631.c1769
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/rt5631.h701
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/sgtl5000.c1468
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/sgtl5000.h400
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/sigmadsp.c246
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/sigmadsp.h21
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/sn95031.c928
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/sn95031.h132
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/spdif_transciever.c69
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/ssm2602.c773
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/ssm2602.h125
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/sta32x.c1024
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/sta32x.h211
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/stac9766.c414
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/stac9766.h17
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/tlv320aic23.c696
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/tlv320aic23.h119
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/tlv320aic26.c458
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/tlv320aic26.h93
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/tlv320aic32x4.c770
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/tlv320aic32x4.h143
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/tlv320aic3x.c1505
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/tlv320aic3x.h253
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/tlv320dac33.c1650
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/tlv320dac33.h264
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/tpa6130a2.c505
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/tpa6130a2.h62
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/twl4030.c2303
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/twl6040.c1662
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/twl6040.h44
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/uda134x.c631
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/uda134x.h34
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/uda1380.c864
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/uda1380.h79
-rwxr-xr-xANDROID_3.4.5/sound/soc/codecs/vt1603.c1249
-rwxr-xr-xANDROID_3.4.5/sound/soc/codecs/vt1603.h119
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wl1273.c517
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wl1273.h30
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm1250-ev1.c238
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm2000.c862
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm2000.h69
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm2200.c2287
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm2200.h3674
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm5100-tables.c1364
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm5100.c2766
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm5100.h5156
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8350.c1697
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8350.h29
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8400.c1469
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8400.h59
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8510.c706
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8510.h102
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8523.c584
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8523.h157
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8580.c966
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8580.h35
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8711.c529
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8711.h39
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8727.c74
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8728.c396
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8728.h21
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8731.c787
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8731.h39
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8737.c763
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8737.h322
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8741.c606
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8741.h211
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8750.c857
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8750.h60
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8753.c1709
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8753.h118
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8770.c748
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8770.h51
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8776.c572
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8776.h48
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8782.c70
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8804.c841
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8804.h61
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8900.c1340
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8900.h55
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8903.c2257
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8903.h1225
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8904.c2339
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8904.h1592
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8940.c809
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8940.h102
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8955.c1094
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8955.h486
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8958-dsp2.c1054
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8960.c1032
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8960.h113
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8961.c1135
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8961.h863
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8962.c3778
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8962.h3780
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8971.c745
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8971.h56
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8974.c682
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8974.h86
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8978.c1129
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8978.h85
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8983.c1199
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8983.h1029
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8985.c1260
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8985.h1045
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8988.c1010
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8988.h57
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8990.c1453
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8990.h835
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8991.c1423
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8991.h833
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8993.c1866
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8993.h2138
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8994.c4391
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8994.h155
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8995.c2415
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8995.h4269
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8996.c3265
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm8996.h3721
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm9081.c1425
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm9081.h784
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm9090.c712
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm9090.h713
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm9705.c413
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm9705.h11
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm9712.c700
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm9712.h11
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm9713.c1283
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm9713.h50
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm_hubs.c1086
-rw-r--r--ANDROID_3.4.5/sound/soc/codecs/wm_hubs.h62
-rwxr-xr-xANDROID_3.4.5/sound/soc/codecs/wmt_fm34.c830
-rwxr-xr-xANDROID_3.4.5/sound/soc/codecs/wmt_hwdac.c195
-rwxr-xr-xANDROID_3.4.5/sound/soc/codecs/wmt_vt1602.c981
-rwxr-xr-xANDROID_3.4.5/sound/soc/codecs/wmt_vt1602.h67
-rw-r--r--ANDROID_3.4.5/sound/soc/davinci/Kconfig85
-rw-r--r--ANDROID_3.4.5/sound/soc/davinci/Makefile20
-rw-r--r--ANDROID_3.4.5/sound/soc/davinci/davinci-evm.c339
-rw-r--r--ANDROID_3.4.5/sound/soc/davinci/davinci-i2s.c768
-rw-r--r--ANDROID_3.4.5/sound/soc/davinci/davinci-i2s.h20
-rw-r--r--ANDROID_3.4.5/sound/soc/davinci/davinci-mcasp.c983
-rw-r--r--ANDROID_3.4.5/sound/soc/davinci/davinci-mcasp.h59
-rw-r--r--ANDROID_3.4.5/sound/soc/davinci/davinci-pcm.c892
-rw-r--r--ANDROID_3.4.5/sound/soc/davinci/davinci-pcm.h31
-rw-r--r--ANDROID_3.4.5/sound/soc/davinci/davinci-sffsdr.c181
-rw-r--r--ANDROID_3.4.5/sound/soc/davinci/davinci-vcif.c266
-rw-r--r--ANDROID_3.4.5/sound/soc/ep93xx/Kconfig42
-rw-r--r--ANDROID_3.4.5/sound/soc/ep93xx/Makefile17
-rw-r--r--ANDROID_3.4.5/sound/soc/ep93xx/edb93xx.c128
-rw-r--r--ANDROID_3.4.5/sound/soc/ep93xx/ep93xx-ac97.c457
-rw-r--r--ANDROID_3.4.5/sound/soc/ep93xx/ep93xx-i2s.c472
-rw-r--r--ANDROID_3.4.5/sound/soc/ep93xx/ep93xx-pcm.c242
-rw-r--r--ANDROID_3.4.5/sound/soc/ep93xx/ep93xx-pcm.h20
-rw-r--r--ANDROID_3.4.5/sound/soc/ep93xx/simone.c90
-rw-r--r--ANDROID_3.4.5/sound/soc/ep93xx/snappercl15.c146
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/Kconfig67
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/Makefile22
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/efika-audio-fabric.c91
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/fsl_dma.c999
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/fsl_dma.h129
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/fsl_ssi.c800
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/fsl_ssi.h200
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/mpc5200_dma.c534
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/mpc5200_dma.h84
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_ac97.c333
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_ac97.h13
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_i2s.c230
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/mpc8610_hpcd.c595
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/p1022_ds.c601
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/pcm030-audio-fabric.c91
-rw-r--r--ANDROID_3.4.5/sound/soc/imx/Kconfig79
-rw-r--r--ANDROID_3.4.5/sound/soc/imx/Makefile22
-rw-r--r--ANDROID_3.4.5/sound/soc/imx/eukrea-tlv320.c164
-rw-r--r--ANDROID_3.4.5/sound/soc/imx/imx-audmux.c311
-rw-r--r--ANDROID_3.4.5/sound/soc/imx/imx-audmux.h60
-rw-r--r--ANDROID_3.4.5/sound/soc/imx/imx-pcm-dma-mx2.c175
-rw-r--r--ANDROID_3.4.5/sound/soc/imx/imx-pcm-fiq.c336
-rw-r--r--ANDROID_3.4.5/sound/soc/imx/imx-pcm.c105
-rw-r--r--ANDROID_3.4.5/sound/soc/imx/imx-pcm.h32
-rw-r--r--ANDROID_3.4.5/sound/soc/imx/imx-ssi.c690
-rw-r--r--ANDROID_3.4.5/sound/soc/imx/imx-ssi.h216
-rw-r--r--ANDROID_3.4.5/sound/soc/imx/mx27vis-aic32x4.c245
-rw-r--r--ANDROID_3.4.5/sound/soc/imx/phycore-ac97.c125
-rw-r--r--ANDROID_3.4.5/sound/soc/imx/wm1133-ev1.c304
-rw-r--r--ANDROID_3.4.5/sound/soc/jz4740/Kconfig23
-rw-r--r--ANDROID_3.4.5/sound/soc/jz4740/Makefile13
-rw-r--r--ANDROID_3.4.5/sound/soc/jz4740/jz4740-i2s.c527
-rw-r--r--ANDROID_3.4.5/sound/soc/jz4740/jz4740-i2s.h16
-rw-r--r--ANDROID_3.4.5/sound/soc/jz4740/jz4740-pcm.c362
-rw-r--r--ANDROID_3.4.5/sound/soc/jz4740/jz4740-pcm.h20
-rw-r--r--ANDROID_3.4.5/sound/soc/jz4740/qi_lb60.c142
-rw-r--r--ANDROID_3.4.5/sound/soc/kirkwood/Kconfig30
-rw-r--r--ANDROID_3.4.5/sound/soc/kirkwood/Makefile11
-rw-r--r--ANDROID_3.4.5/sound/soc/kirkwood/kirkwood-dma.c398
-rw-r--r--ANDROID_3.4.5/sound/soc/kirkwood/kirkwood-i2s.c491
-rw-r--r--ANDROID_3.4.5/sound/soc/kirkwood/kirkwood-openrd.c111
-rw-r--r--ANDROID_3.4.5/sound/soc/kirkwood/kirkwood-t5325.c131
-rw-r--r--ANDROID_3.4.5/sound/soc/kirkwood/kirkwood.h128
-rw-r--r--ANDROID_3.4.5/sound/soc/mid-x86/Kconfig13
-rw-r--r--ANDROID_3.4.5/sound/soc/mid-x86/Makefile5
-rw-r--r--ANDROID_3.4.5/sound/soc/mid-x86/mfld_machine.c438
-rw-r--r--ANDROID_3.4.5/sound/soc/mid-x86/sst_platform.c517
-rw-r--r--ANDROID_3.4.5/sound/soc/mid-x86/sst_platform.h131
-rw-r--r--ANDROID_3.4.5/sound/soc/mxs/Kconfig20
-rw-r--r--ANDROID_3.4.5/sound/soc/mxs/Makefile10
-rw-r--r--ANDROID_3.4.5/sound/soc/mxs/mxs-pcm.c247
-rw-r--r--ANDROID_3.4.5/sound/soc/mxs/mxs-pcm.h27
-rw-r--r--ANDROID_3.4.5/sound/soc/mxs/mxs-saif.c762
-rw-r--r--ANDROID_3.4.5/sound/soc/mxs/mxs-saif.h134
-rw-r--r--ANDROID_3.4.5/sound/soc/mxs/mxs-sgtl5000.c165
-rw-r--r--ANDROID_3.4.5/sound/soc/nuc900/Kconfig27
-rw-r--r--ANDROID_3.4.5/sound/soc/nuc900/Makefile11
-rw-r--r--ANDROID_3.4.5/sound/soc/nuc900/nuc900-ac97.c414
-rw-r--r--ANDROID_3.4.5/sound/soc/nuc900/nuc900-audio.c75
-rw-r--r--ANDROID_3.4.5/sound/soc/nuc900/nuc900-audio.h115
-rw-r--r--ANDROID_3.4.5/sound/soc/nuc900/nuc900-pcm.c365
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/Kconfig152
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/Makefile44
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/am3517evm.c161
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/ams-delta.c630
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/igep0020.c120
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/mcbsp.c1040
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/mcbsp.h346
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/n810.c384
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/omap-abe-twl6040.c349
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/omap-dmic.c545
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/omap-dmic.h69
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/omap-hdmi.c148
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/omap-hdmi.h36
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/omap-mcbsp.c817
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/omap-mcbsp.h64
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/omap-mcpdm.c524
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/omap-mcpdm.h107
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/omap-pcm.c443
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/omap-pcm.h40
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/omap3beagle.c150
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/omap3evm.c118
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/omap3pandora.c325
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/omap4-hdmi-card.c121
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/osk5912.c189
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/overo.c122
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/rx51.c451
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/sdp3430.c279
-rw-r--r--ANDROID_3.4.5/sound/soc/omap/zoom2.c219
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/Kconfig196
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/Makefile49
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/corgi.c343
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/e740_wm9705.c192
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/e750_wm9705.c174
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/e800_wm9712.c164
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/em-x270.c96
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/hx4700.c234
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/imote2.c104
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/magician.c563
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/mioa701_wm9713.c236
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/palm27x.c210
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/poodle.c317
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/pxa-ssp.c845
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/pxa-ssp.h45
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/pxa2xx-ac97.c271
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/pxa2xx-ac97.h20
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/pxa2xx-i2s.c402
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/pxa2xx-i2s.h18
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/pxa2xx-pcm.c148
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/raumfeld.c339
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/saarb.c190
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/spitz.c363
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/tavorevb3.c189
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/tosa.c289
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/z2.c231
-rw-r--r--ANDROID_3.4.5/sound/soc/pxa/zylonite.c291
-rw-r--r--ANDROID_3.4.5/sound/soc/s6000/Kconfig19
-rw-r--r--ANDROID_3.4.5/sound/soc/s6000/Makefile11
-rw-r--r--ANDROID_3.4.5/sound/soc/s6000/s6000-i2s.c611
-rw-r--r--ANDROID_3.4.5/sound/soc/s6000/s6000-i2s.h23
-rw-r--r--ANDROID_3.4.5/sound/soc/s6000/s6000-pcm.c528
-rw-r--r--ANDROID_3.4.5/sound/soc/s6000/s6000-pcm.h33
-rw-r--r--ANDROID_3.4.5/sound/soc/s6000/s6105-ipcam.c244
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/Kconfig214
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/Makefile67
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/ac97.c517
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/dma.c465
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/dma.h24
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/goni_wm8994.c302
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/h1940_uda1380.c281
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/i2s-regs.h143
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/i2s.c1158
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/i2s.h29
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/idma.c444
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/idma.h26
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/jive_wm8750.c174
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/littlemill.c256
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/ln2440sbc_alc650.c72
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/lowland.c237
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/neo1973_wm8753.c472
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/pcm.c645
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/pcm.h17
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/regs-i2s-v2.h115
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/rx1950_uda1380.c301
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/s3c-i2s-v2.c757
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/s3c-i2s-v2.h106
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/s3c2412-i2s.c193
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/s3c2412-i2s.h27
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/s3c24xx-i2s.c498
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/s3c24xx-i2s.h35
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/s3c24xx_simtec.c388
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/s3c24xx_simtec.h22
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/s3c24xx_simtec_hermes.c123
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c111
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/s3c24xx_uda134x.c351
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/smartq_wm8987.c275
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/smdk2443_wm9710.c68
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/smdk_spdif.c223
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/smdk_wm8580.c258
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/smdk_wm8580pcm.c196
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/smdk_wm8994.c179
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/smdk_wm8994pcm.c166
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/smdk_wm9713.c108
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/spdif.c491
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/spdif.h19
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/speyside.c357
-rw-r--r--ANDROID_3.4.5/sound/soc/samsung/tobermory.c258
-rw-r--r--ANDROID_3.4.5/sound/soc/sh/Kconfig80
-rw-r--r--ANDROID_3.4.5/sound/soc/sh/Makefile26
-rw-r--r--ANDROID_3.4.5/sound/soc/sh/dma-sh7760.c376
-rw-r--r--ANDROID_3.4.5/sound/soc/sh/fsi-ak4642.c108
-rw-r--r--ANDROID_3.4.5/sound/soc/sh/fsi-da7210.c81
-rw-r--r--ANDROID_3.4.5/sound/soc/sh/fsi-hdmi.c118
-rw-r--r--ANDROID_3.4.5/sound/soc/sh/fsi.c1771
-rw-r--r--ANDROID_3.4.5/sound/soc/sh/hac.c339
-rw-r--r--ANDROID_3.4.5/sound/soc/sh/migor.c225
-rw-r--r--ANDROID_3.4.5/sound/soc/sh/sh7760-ac97.c73
-rw-r--r--ANDROID_3.4.5/sound/soc/sh/siu.h194
-rw-r--r--ANDROID_3.4.5/sound/soc/sh/siu_dai.c853
-rw-r--r--ANDROID_3.4.5/sound/soc/sh/siu_pcm.c617
-rw-r--r--ANDROID_3.4.5/sound/soc/sh/ssi.c408
-rw-r--r--ANDROID_3.4.5/sound/soc/soc-cache.c340
-rw-r--r--ANDROID_3.4.5/sound/soc/soc-core.c3955
-rw-r--r--ANDROID_3.4.5/sound/soc/soc-dapm.c3288
-rw-r--r--ANDROID_3.4.5/sound/soc/soc-dmaengine-pcm.c288
-rw-r--r--ANDROID_3.4.5/sound/soc/soc-io.c170
-rw-r--r--ANDROID_3.4.5/sound/soc/soc-jack.c385
-rw-r--r--ANDROID_3.4.5/sound/soc/soc-pcm.c707
-rw-r--r--ANDROID_3.4.5/sound/soc/soc-utils.c158
-rw-r--r--ANDROID_3.4.5/sound/soc/tegra/Kconfig58
-rw-r--r--ANDROID_3.4.5/sound/soc/tegra/Makefile21
-rw-r--r--ANDROID_3.4.5/sound/soc/tegra/tegra_alc5632.c289
-rw-r--r--ANDROID_3.4.5/sound/soc/tegra/tegra_asoc_utils.c157
-rw-r--r--ANDROID_3.4.5/sound/soc/tegra/tegra_asoc_utils.h45
-rw-r--r--ANDROID_3.4.5/sound/soc/tegra/tegra_das.c261
-rw-r--r--ANDROID_3.4.5/sound/soc/tegra/tegra_das.h135
-rw-r--r--ANDROID_3.4.5/sound/soc/tegra/tegra_i2s.c459
-rw-r--r--ANDROID_3.4.5/sound/soc/tegra/tegra_i2s.h166
-rw-r--r--ANDROID_3.4.5/sound/soc/tegra/tegra_pcm.c399
-rw-r--r--ANDROID_3.4.5/sound/soc/tegra/tegra_pcm.h55
-rw-r--r--ANDROID_3.4.5/sound/soc/tegra/tegra_spdif.c364
-rw-r--r--ANDROID_3.4.5/sound/soc/tegra/tegra_spdif.h473
-rw-r--r--ANDROID_3.4.5/sound/soc/tegra/tegra_wm8903.c527
-rw-r--r--ANDROID_3.4.5/sound/soc/tegra/trimslice.c203
-rw-r--r--ANDROID_3.4.5/sound/soc/txx9/Kconfig29
-rw-r--r--ANDROID_3.4.5/sound/soc/txx9/Makefile11
-rw-r--r--ANDROID_3.4.5/sound/soc/txx9/txx9aclc-ac97.c231
-rw-r--r--ANDROID_3.4.5/sound/soc/txx9/txx9aclc-generic.c90
-rw-r--r--ANDROID_3.4.5/sound/soc/txx9/txx9aclc.c445
-rw-r--r--ANDROID_3.4.5/sound/soc/txx9/txx9aclc.h74
-rwxr-xr-xANDROID_3.4.5/sound/soc/wmt/Kconfig65
-rwxr-xr-xANDROID_3.4.5/sound/soc/wmt/Makefile12
-rwxr-xr-xANDROID_3.4.5/sound/soc/wmt/wmt-i2s.c1105
-rwxr-xr-xANDROID_3.4.5/sound/soc/wmt/wmt-pcm-controller.c419
-rwxr-xr-xANDROID_3.4.5/sound/soc/wmt/wmt-pcm-controller.h122
-rwxr-xr-xANDROID_3.4.5/sound/soc/wmt/wmt-pcm-dma.c597
-rwxr-xr-xANDROID_3.4.5/sound/soc/wmt/wmt-pcm-dma.h35
-rwxr-xr-xANDROID_3.4.5/sound/soc/wmt/wmt-pcm.c767
-rwxr-xr-xANDROID_3.4.5/sound/soc/wmt/wmt-pcm.h46
-rwxr-xr-xANDROID_3.4.5/sound/soc/wmt/wmt-soc.c321
-rwxr-xr-xANDROID_3.4.5/sound/soc/wmt/wmt-soc.h53
-rwxr-xr-xANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.c259
-rwxr-xr-xANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.h55
-rwxr-xr-xANDROID_3.4.5/sound/soc/wmt/wmt_swmixer.c101
-rwxr-xr-xANDROID_3.4.5/sound/soc/wmt/wmt_swmixer.h33
-rwxr-xr-xANDROID_3.4.5/sound/soc/wmt/wmt_wm8994.c304
-rw-r--r--ANDROID_3.4.5/sound/sound_core.c670
-rw-r--r--ANDROID_3.4.5/sound/sound_firmware.c78
-rw-r--r--ANDROID_3.4.5/sound/sparc/Kconfig41
-rw-r--r--ANDROID_3.4.5/sound/sparc/Makefile12
-rw-r--r--ANDROID_3.4.5/sound/sparc/amd7930.c1099
-rw-r--r--ANDROID_3.4.5/sound/sparc/cs4231.c2121
-rw-r--r--ANDROID_3.4.5/sound/sparc/dbri.c2700
-rw-r--r--ANDROID_3.4.5/sound/spi/Kconfig38
-rw-r--r--ANDROID_3.4.5/sound/spi/Makefile5
-rw-r--r--ANDROID_3.4.5/sound/spi/at73c213.c1119
-rw-r--r--ANDROID_3.4.5/sound/spi/at73c213.h119
-rw-r--r--ANDROID_3.4.5/sound/synth/Makefile12
-rw-r--r--ANDROID_3.4.5/sound/synth/emux/Makefile12
-rw-r--r--ANDROID_3.4.5/sound/synth/emux/emux.c192
-rw-r--r--ANDROID_3.4.5/sound/synth/emux/emux_effect.c310
-rw-r--r--ANDROID_3.4.5/sound/synth/emux/emux_hwdep.c153
-rw-r--r--ANDROID_3.4.5/sound/synth/emux/emux_nrpn.c396
-rw-r--r--ANDROID_3.4.5/sound/synth/emux/emux_oss.c517
-rw-r--r--ANDROID_3.4.5/sound/synth/emux/emux_proc.c132
-rw-r--r--ANDROID_3.4.5/sound/synth/emux/emux_seq.c403
-rw-r--r--ANDROID_3.4.5/sound/synth/emux/emux_synth.c984
-rw-r--r--ANDROID_3.4.5/sound/synth/emux/emux_voice.h96
-rw-r--r--ANDROID_3.4.5/sound/synth/emux/soundfont.c1496
-rw-r--r--ANDROID_3.4.5/sound/synth/util_mem.c211
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/Makefile3
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/chip.c220
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/chip.h31
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/comm.c175
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/comm.h43
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/common.h29
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/control.c631
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/control.h57
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/firmware.c418
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/firmware.h27
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/midi.c202
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/midi.h45
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/pcm.c666
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/pcm.h75
-rw-r--r--ANDROID_3.4.5/sound/usb/Kconfig119
-rw-r--r--ANDROID_3.4.5/sound/usb/Makefile26
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/Makefile4
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/audio.c889
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/audio.h7
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/control.c559
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/control.h6
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/device.c542
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/device.h140
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/input.c842
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/input.h8
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/midi.c174
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/midi.h8
-rw-r--r--ANDROID_3.4.5/sound/usb/card.c729
-rw-r--r--ANDROID_3.4.5/sound/usb/card.h111
-rw-r--r--ANDROID_3.4.5/sound/usb/clock.c318
-rw-r--r--ANDROID_3.4.5/sound/usb/clock.h10
-rw-r--r--ANDROID_3.4.5/sound/usb/debug.h15
-rw-r--r--ANDROID_3.4.5/sound/usb/endpoint.c966
-rw-r--r--ANDROID_3.4.5/sound/usb/endpoint.h21
-rw-r--r--ANDROID_3.4.5/sound/usb/format.c515
-rw-r--r--ANDROID_3.4.5/sound/usb/format.h9
-rw-r--r--ANDROID_3.4.5/sound/usb/helper.c118
-rw-r--r--ANDROID_3.4.5/sound/usb/helper.h36
-rw-r--r--ANDROID_3.4.5/sound/usb/midi.c2237
-rw-r--r--ANDROID_3.4.5/sound/usb/midi.h50
-rw-r--r--ANDROID_3.4.5/sound/usb/misc/Makefile2
-rw-r--r--ANDROID_3.4.5/sound/usb/misc/ua101.c1390
-rw-r--r--ANDROID_3.4.5/sound/usb/mixer.c2283
-rw-r--r--ANDROID_3.4.5/sound/usb/mixer.h71
-rw-r--r--ANDROID_3.4.5/sound/usb/mixer_maps.c376
-rw-r--r--ANDROID_3.4.5/sound/usb/mixer_quirks.c654
-rw-r--r--ANDROID_3.4.5/sound/usb/mixer_quirks.h13
-rw-r--r--ANDROID_3.4.5/sound/usb/pcm.c911
-rw-r--r--ANDROID_3.4.5/sound/usb/pcm.h14
-rw-r--r--ANDROID_3.4.5/sound/usb/power.h17
-rw-r--r--ANDROID_3.4.5/sound/usb/proc.c173
-rw-r--r--ANDROID_3.4.5/sound/usb/proc.h8
-rw-r--r--ANDROID_3.4.5/sound/usb/quirks-table.h2769
-rw-r--r--ANDROID_3.4.5/sound/usb/quirks.c763
-rw-r--r--ANDROID_3.4.5/sound/usb/quirks.h23
-rw-r--r--ANDROID_3.4.5/sound/usb/stream.c452
-rw-r--r--ANDROID_3.4.5/sound/usb/stream.h12
-rw-r--r--ANDROID_3.4.5/sound/usb/usbaudio.h105
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/Makefile5
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/us122l.c775
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/us122l.h31
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usX2Yhwdep.c265
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usX2Yhwdep.h6
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usb_stream.c754
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usb_stream.h112
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usbus428ctldefs.h104
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usbusx2y.c462
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usbusx2y.h88
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usbusx2yaudio.c1028
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usx2y.h51
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usx2yhwdeppcm.c794
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usx2yhwdeppcm.h22
1361 files changed, 0 insertions, 724495 deletions
diff --git a/ANDROID_3.4.5/sound/Kconfig b/ANDROID_3.4.5/sound/Kconfig
deleted file mode 100644
index 261a03c8..00000000
--- a/ANDROID_3.4.5/sound/Kconfig
+++ /dev/null
@@ -1,137 +0,0 @@
-menuconfig SOUND
- tristate "Sound card support"
- depends on HAS_IOMEM
- help
- If you have a sound card in your computer, i.e. if it can say more
- than an occasional beep, say Y. Be sure to have all the information
- about your sound card and its configuration down (I/O port,
- interrupt and DMA channel), because you will be asked for it.
-
- You want to read the Sound-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>. General information about
- the modular sound system is contained in the files
- <file:Documentation/sound/oss/Introduction>. The file
- <file:Documentation/sound/oss/README.OSS> contains some slightly
- outdated but still useful information as well. Newer sound
- driver documentation is found in <file:Documentation/sound/alsa/*>.
-
- If you have a PnP sound card and you want to configure it at boot
- time using the ISA PnP tools (read
- <http://www.roestock.demon.co.uk/isapnptools/>), then you need to
- compile the sound card support as a module and load that module
- after the PnP configuration is finished. To do this, choose M here
- and read <file:Documentation/sound/oss/README.modules>; the module
- will be called soundcore.
-
-if SOUND
-
-config SOUND_OSS_CORE
- bool
- default n
-
-config SOUND_OSS_CORE_PRECLAIM
- bool "Preclaim OSS device numbers"
- depends on SOUND_OSS_CORE
- default y
- help
- With this option enabled, the kernel will claim all OSS device
- numbers if any OSS support (native or emulation) is enabled
- whether the respective module is loaded or not and try to load the
- appropriate module using sound-slot/service-* and char-major-*
- module aliases when one of the device numbers is opened. With
- this option disabled, kernel will only claim actually in-use
- device numbers and opening a missing device will generate only the
- standard char-major-* aliases.
-
- The only visible difference is use of additional module aliases
- and whether OSS sound devices appear multiple times in
- /proc/devices. sound-slot/service-* module aliases are scheduled
- to be removed (ie. PRECLAIM won't be available) and this option is
- to make the transition easier. This option can be overridden
- during boot using the kernel parameter soundcore.preclaim_oss.
-
- Disabling this allows alternative OSS implementations.
-
- Please read Documentation/feature-removal-schedule.txt for
- details.
-
- If unsure, say Y.
-
-source "sound/oss/dmasound/Kconfig"
-
-if !M68K && !UML
-
-menuconfig SND
- tristate "Advanced Linux Sound Architecture"
- help
- Say 'Y' or 'M' to enable ALSA (Advanced Linux Sound Architecture),
- the new base sound system.
-
- For more information, see <http://www.alsa-project.org/>
-
-if SND
-
-source "sound/core/Kconfig"
-
-source "sound/drivers/Kconfig"
-
-source "sound/isa/Kconfig"
-
-source "sound/pci/Kconfig"
-
-source "sound/ppc/Kconfig"
-
-source "sound/aoa/Kconfig"
-
-source "sound/arm/Kconfig"
-
-source "sound/atmel/Kconfig"
-
-source "sound/spi/Kconfig"
-
-source "sound/mips/Kconfig"
-
-source "sound/sh/Kconfig"
-
-# the following will depend on the order of config.
-# here assuming USB is defined before ALSA
-source "sound/usb/Kconfig"
-
-source "sound/firewire/Kconfig"
-
-# the following will depend on the order of config.
-# here assuming PCMCIA is defined before ALSA
-source "sound/pcmcia/Kconfig"
-
-source "sound/sparc/Kconfig"
-
-source "sound/parisc/Kconfig"
-
-source "sound/soc/Kconfig"
-
-endif # SND
-
-menuconfig SOUND_PRIME
- tristate "Open Sound System (DEPRECATED)"
- select SOUND_OSS_CORE
- help
- Say 'Y' or 'M' to enable Open Sound System drivers.
-
-if SOUND_PRIME
-
-source "sound/oss/Kconfig"
-
-endif # SOUND_PRIME
-
-endif # !M68K
-
-endif # SOUND
-
-# AC97_BUS is used from both sound and ucb1400
-config AC97_BUS
- tristate
- help
- This is used to avoid config and link hard dependencies between the
- sound subsystem and other function drivers completely unrelated to
- sound although they're sharing the AC97 bus. Concerned drivers
- should "select" this.
diff --git a/ANDROID_3.4.5/sound/Makefile b/ANDROID_3.4.5/sound/Makefile
deleted file mode 100644
index 987b7d2b..00000000
--- a/ANDROID_3.4.5/sound/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-# Makefile for the Linux sound card driver
-#
-
-obj-$(CONFIG_SOUND) += soundcore.o
-obj-$(CONFIG_SOUND_PRIME) += sound_firmware.o
-obj-$(CONFIG_SOUND_PRIME) += oss/
-obj-$(CONFIG_DMASOUND) += oss/
-obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ \
- firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ usb/
-obj-$(CONFIG_SND_AOA) += aoa/
-
-# This one must be compilable even if sound is configured out
-obj-$(CONFIG_AC97_BUS) += ac97_bus.o
-
-ifeq ($(CONFIG_SND),y)
- obj-y += last.o
-endif
-
-soundcore-objs := sound_core.o
diff --git a/ANDROID_3.4.5/sound/ac97_bus.c b/ANDROID_3.4.5/sound/ac97_bus.c
deleted file mode 100644
index 2b50cbe6..00000000
--- a/ANDROID_3.4.5/sound/ac97_bus.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Linux driver model AC97 bus interface
- *
- * Author: Nicolas Pitre
- * Created: Jan 14, 2005
- * Copyright: (C) MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/string.h>
-#include <sound/ac97_codec.h>
-
-/*
- * Let drivers decide whether they want to support given codec from their
- * probe method. Drivers have direct access to the struct snd_ac97
- * structure and may decide based on the id field amongst other things.
- */
-static int ac97_bus_match(struct device *dev, struct device_driver *drv)
-{
- return 1;
-}
-
-#ifdef CONFIG_PM
-static int ac97_bus_suspend(struct device *dev, pm_message_t state)
-{
- int ret = 0;
-
- if (dev->driver && dev->driver->suspend)
- ret = dev->driver->suspend(dev, state);
-
- return ret;
-}
-
-static int ac97_bus_resume(struct device *dev)
-{
- int ret = 0;
-
- if (dev->driver && dev->driver->resume)
- ret = dev->driver->resume(dev);
-
- return ret;
-}
-#endif /* CONFIG_PM */
-
-struct bus_type ac97_bus_type = {
- .name = "ac97",
- .match = ac97_bus_match,
-#ifdef CONFIG_PM
- .suspend = ac97_bus_suspend,
- .resume = ac97_bus_resume,
-#endif /* CONFIG_PM */
-};
-
-static int __init ac97_bus_init(void)
-{
- return bus_register(&ac97_bus_type);
-}
-
-subsys_initcall(ac97_bus_init);
-
-static void __exit ac97_bus_exit(void)
-{
- bus_unregister(&ac97_bus_type);
-}
-
-module_exit(ac97_bus_exit);
-
-EXPORT_SYMBOL(ac97_bus_type);
-
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/aoa/Kconfig b/ANDROID_3.4.5/sound/aoa/Kconfig
deleted file mode 100644
index c081e18b..00000000
--- a/ANDROID_3.4.5/sound/aoa/Kconfig
+++ /dev/null
@@ -1,17 +0,0 @@
-menuconfig SND_AOA
- tristate "Apple Onboard Audio driver"
- depends on PPC_PMAC
- select SND_PCM
- ---help---
- This option enables the new driver for the various
- Apple Onboard Audio components.
-
-if SND_AOA
-
-source "sound/aoa/fabrics/Kconfig"
-
-source "sound/aoa/codecs/Kconfig"
-
-source "sound/aoa/soundbus/Kconfig"
-
-endif # SND_AOA
diff --git a/ANDROID_3.4.5/sound/aoa/Makefile b/ANDROID_3.4.5/sound/aoa/Makefile
deleted file mode 100644
index a8c037f9..00000000
--- a/ANDROID_3.4.5/sound/aoa/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-obj-$(CONFIG_SND_AOA) += core/
-obj-$(CONFIG_SND_AOA_SOUNDBUS) += soundbus/
-obj-$(CONFIG_SND_AOA) += fabrics/
-obj-$(CONFIG_SND_AOA) += codecs/
diff --git a/ANDROID_3.4.5/sound/aoa/aoa-gpio.h b/ANDROID_3.4.5/sound/aoa/aoa-gpio.h
deleted file mode 100644
index 6065b034..00000000
--- a/ANDROID_3.4.5/sound/aoa/aoa-gpio.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Apple Onboard Audio GPIO definitions
- *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- */
-
-#ifndef __AOA_GPIO_H
-#define __AOA_GPIO_H
-#include <linux/workqueue.h>
-#include <linux/mutex.h>
-#include <asm/prom.h>
-
-typedef void (*notify_func_t)(void *data);
-
-enum notify_type {
- AOA_NOTIFY_HEADPHONE,
- AOA_NOTIFY_LINE_IN,
- AOA_NOTIFY_LINE_OUT,
-};
-
-struct gpio_runtime;
-struct gpio_methods {
- /* for initialisation/de-initialisation of the GPIO layer */
- void (*init)(struct gpio_runtime *rt);
- void (*exit)(struct gpio_runtime *rt);
-
- /* turn off headphone, speakers, lineout */
- void (*all_amps_off)(struct gpio_runtime *rt);
- /* turn headphone, speakers, lineout back to previous setting */
- void (*all_amps_restore)(struct gpio_runtime *rt);
-
- void (*set_headphone)(struct gpio_runtime *rt, int on);
- void (*set_speakers)(struct gpio_runtime *rt, int on);
- void (*set_lineout)(struct gpio_runtime *rt, int on);
- void (*set_master)(struct gpio_runtime *rt, int on);
-
- int (*get_headphone)(struct gpio_runtime *rt);
- int (*get_speakers)(struct gpio_runtime *rt);
- int (*get_lineout)(struct gpio_runtime *rt);
- int (*get_master)(struct gpio_runtime *rt);
-
- void (*set_hw_reset)(struct gpio_runtime *rt, int on);
-
- /* use this to be notified of any events. The notification
- * function is passed the data, and is called in process
- * context by the use of schedule_work.
- * The interface for it is that setting a function to NULL
- * removes it, and they return 0 if the operation succeeded,
- * and -EBUSY if the notification is already assigned by
- * someone else. */
- int (*set_notify)(struct gpio_runtime *rt,
- enum notify_type type,
- notify_func_t notify,
- void *data);
- /* returns 0 if not plugged in, 1 if plugged in
- * or a negative error code */
- int (*get_detect)(struct gpio_runtime *rt,
- enum notify_type type);
-};
-
-struct gpio_notification {
- struct delayed_work work;
- notify_func_t notify;
- void *data;
- void *gpio_private;
- struct mutex mutex;
-};
-
-struct gpio_runtime {
- /* to be assigned by fabric */
- struct device_node *node;
- /* since everyone needs this pointer anyway... */
- struct gpio_methods *methods;
- /* to be used by the gpio implementation */
- int implementation_private;
- struct gpio_notification headphone_notify;
- struct gpio_notification line_in_notify;
- struct gpio_notification line_out_notify;
-};
-
-#endif /* __AOA_GPIO_H */
diff --git a/ANDROID_3.4.5/sound/aoa/aoa.h b/ANDROID_3.4.5/sound/aoa/aoa.h
deleted file mode 100644
index e0878948..00000000
--- a/ANDROID_3.4.5/sound/aoa/aoa.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Apple Onboard Audio definitions
- *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- */
-
-#ifndef __AOA_H
-#define __AOA_H
-#include <asm/prom.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/asound.h>
-#include <sound/control.h>
-#include "aoa-gpio.h"
-#include "soundbus/soundbus.h"
-
-#define MAX_CODEC_NAME_LEN 32
-
-struct aoa_codec {
- char name[MAX_CODEC_NAME_LEN];
-
- struct module *owner;
-
- /* called when the fabric wants to init this codec.
- * Do alsa card manipulations from here. */
- int (*init)(struct aoa_codec *codec);
-
- /* called when the fabric is done with the codec.
- * The alsa card will be cleaned up so don't bother. */
- void (*exit)(struct aoa_codec *codec);
-
- /* May be NULL, but can be used by the fabric.
- * Refcounting is the codec driver's responsibility */
- struct device_node *node;
-
- /* assigned by fabric before init() is called, points
- * to the soundbus device. Cannot be NULL. */
- struct soundbus_dev *soundbus_dev;
-
- /* assigned by the fabric before init() is called, points
- * to the fabric's gpio runtime record for the relevant
- * device. */
- struct gpio_runtime *gpio;
-
- /* assigned by the fabric before init() is called, contains
- * a codec specific bitmask of what outputs and inputs are
- * actually connected */
- u32 connected;
-
- /* data the fabric can associate with this structure */
- void *fabric_data;
-
- /* private! */
- struct list_head list;
- struct aoa_fabric *fabric;
-};
-
-/* return 0 on success */
-extern int
-aoa_codec_register(struct aoa_codec *codec);
-extern void
-aoa_codec_unregister(struct aoa_codec *codec);
-
-#define MAX_LAYOUT_NAME_LEN 32
-
-struct aoa_fabric {
- char name[MAX_LAYOUT_NAME_LEN];
-
- struct module *owner;
-
- /* once codecs register, they are passed here after.
- * They are of course not initialised, since the
- * fabric is responsible for initialising some fields
- * in the codec structure! */
- int (*found_codec)(struct aoa_codec *codec);
- /* called for each codec when it is removed,
- * also in the case that aoa_fabric_unregister
- * is called and all codecs are removed
- * from this fabric.
- * Also called if found_codec returned 0 but
- * the codec couldn't initialise. */
- void (*remove_codec)(struct aoa_codec *codec);
- /* If found_codec returned 0, and the codec
- * could be initialised, this is called. */
- void (*attached_codec)(struct aoa_codec *codec);
-};
-
-/* return 0 on success, -EEXIST if another fabric is
- * registered, -EALREADY if the same fabric is registered.
- * Passing NULL can be used to test for the presence
- * of another fabric, if -EALREADY is returned there is
- * no other fabric present.
- * In the case that the function returns -EALREADY
- * and the fabric passed is not NULL, all codecs
- * that are not assigned yet are passed to the fabric
- * again for reconsideration. */
-extern int
-aoa_fabric_register(struct aoa_fabric *fabric, struct device *dev);
-
-/* it is vital to call this when the fabric exits!
- * When calling, the remove_codec will be called
- * for all codecs, unless it is NULL. */
-extern void
-aoa_fabric_unregister(struct aoa_fabric *fabric);
-
-/* if for some reason you want to get rid of a codec
- * before the fabric is removed, use this.
- * Note that remove_codec is called for it! */
-extern void
-aoa_fabric_unlink_codec(struct aoa_codec *codec);
-
-/* alsa help methods */
-struct aoa_card {
- struct snd_card *alsa_card;
-};
-
-extern int aoa_snd_device_new(snd_device_type_t type,
- void * device_data, struct snd_device_ops * ops);
-extern struct snd_card *aoa_get_card(void);
-extern int aoa_snd_ctl_add(struct snd_kcontrol* control);
-
-/* GPIO stuff */
-extern struct gpio_methods *pmf_gpio_methods;
-extern struct gpio_methods *ftr_gpio_methods;
-/* extern struct gpio_methods *map_gpio_methods; */
-
-#endif /* __AOA_H */
diff --git a/ANDROID_3.4.5/sound/aoa/codecs/Kconfig b/ANDROID_3.4.5/sound/aoa/codecs/Kconfig
deleted file mode 100644
index 0c68e328..00000000
--- a/ANDROID_3.4.5/sound/aoa/codecs/Kconfig
+++ /dev/null
@@ -1,24 +0,0 @@
-config SND_AOA_ONYX
- tristate "support Onyx chip"
- select I2C
- select I2C_POWERMAC
- ---help---
- This option enables support for the Onyx (pcm3052)
- codec chip found in the latest Apple machines
- (most of those with digital audio output).
-
-config SND_AOA_TAS
- tristate "support TAS chips"
- select I2C
- select I2C_POWERMAC
- ---help---
- This option enables support for the tas chips
- found in a lot of Apple Machines, especially
- iBooks and PowerBooks without digital.
-
-config SND_AOA_TOONIE
- tristate "support Toonie chip"
- ---help---
- This option enables support for the toonie codec
- found in the Mac Mini. If you have a Mac Mini and
- want to hear sound, select this option.
diff --git a/ANDROID_3.4.5/sound/aoa/codecs/Makefile b/ANDROID_3.4.5/sound/aoa/codecs/Makefile
deleted file mode 100644
index c3ee77fc..00000000
--- a/ANDROID_3.4.5/sound/aoa/codecs/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-snd-aoa-codec-onyx-objs := onyx.o
-snd-aoa-codec-tas-objs := tas.o
-snd-aoa-codec-toonie-objs := toonie.o
-
-obj-$(CONFIG_SND_AOA_ONYX) += snd-aoa-codec-onyx.o
-obj-$(CONFIG_SND_AOA_TAS) += snd-aoa-codec-tas.o
-obj-$(CONFIG_SND_AOA_TOONIE) += snd-aoa-codec-toonie.o
diff --git a/ANDROID_3.4.5/sound/aoa/codecs/onyx.c b/ANDROID_3.4.5/sound/aoa/codecs/onyx.c
deleted file mode 100644
index 270790d3..00000000
--- a/ANDROID_3.4.5/sound/aoa/codecs/onyx.c
+++ /dev/null
@@ -1,1135 +0,0 @@
-/*
- * Apple Onboard Audio driver for Onyx codec
- *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- *
- *
- * This is a driver for the pcm3052 codec chip (codenamed Onyx)
- * that is present in newer Apple hardware (with digital output).
- *
- * The Onyx codec has the following connections (listed by the bit
- * to be used in aoa_codec.connected):
- * 0: analog output
- * 1: digital output
- * 2: line input
- * 3: microphone input
- * Note that even though I know of no machine that has for example
- * the digital output connected but not the analog, I have handled
- * all the different cases in the code so that this driver may serve
- * as a good example of what to do.
- *
- * NOTE: This driver assumes that there's at most one chip to be
- * used with one alsa card, in form of creating all kinds
- * of mixer elements without regard for their existence.
- * But snd-aoa assumes that there's at most one card, so
- * this means you can only have one onyx on a system. This
- * should probably be fixed by changing the assumption of
- * having just a single card on a system, and making the
- * 'card' pointer accessible to anyone who needs it instead
- * of hiding it in the aoa_snd_* functions...
- *
- */
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa");
-
-#include "onyx.h"
-#include "../aoa.h"
-#include "../soundbus/soundbus.h"
-
-
-#define PFX "snd-aoa-codec-onyx: "
-
-struct onyx {
- /* cache registers 65 to 80, they are write-only! */
- u8 cache[16];
- struct i2c_client *i2c;
- struct aoa_codec codec;
- u32 initialised:1,
- spdif_locked:1,
- analog_locked:1,
- original_mute:2;
- int open_count;
- struct codec_info *codec_info;
-
- /* mutex serializes concurrent access to the device
- * and this structure.
- */
- struct mutex mutex;
-};
-#define codec_to_onyx(c) container_of(c, struct onyx, codec)
-
-/* both return 0 if all ok, else on error */
-static int onyx_read_register(struct onyx *onyx, u8 reg, u8 *value)
-{
- s32 v;
-
- if (reg != ONYX_REG_CONTROL) {
- *value = onyx->cache[reg-FIRSTREGISTER];
- return 0;
- }
- v = i2c_smbus_read_byte_data(onyx->i2c, reg);
- if (v < 0)
- return -1;
- *value = (u8)v;
- onyx->cache[ONYX_REG_CONTROL-FIRSTREGISTER] = *value;
- return 0;
-}
-
-static int onyx_write_register(struct onyx *onyx, u8 reg, u8 value)
-{
- int result;
-
- result = i2c_smbus_write_byte_data(onyx->i2c, reg, value);
- if (!result)
- onyx->cache[reg-FIRSTREGISTER] = value;
- return result;
-}
-
-/* alsa stuff */
-
-static int onyx_dev_register(struct snd_device *dev)
-{
- return 0;
-}
-
-static struct snd_device_ops ops = {
- .dev_register = onyx_dev_register,
-};
-
-/* this is necessary because most alsa mixer programs
- * can't properly handle the negative range */
-#define VOLUME_RANGE_SHIFT 128
-
-static int onyx_snd_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = -128 + VOLUME_RANGE_SHIFT;
- uinfo->value.integer.max = -1 + VOLUME_RANGE_SHIFT;
- return 0;
-}
-
-static int onyx_snd_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct onyx *onyx = snd_kcontrol_chip(kcontrol);
- s8 l, r;
-
- mutex_lock(&onyx->mutex);
- onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_LEFT, &l);
- onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT, &r);
- mutex_unlock(&onyx->mutex);
-
- ucontrol->value.integer.value[0] = l + VOLUME_RANGE_SHIFT;
- ucontrol->value.integer.value[1] = r + VOLUME_RANGE_SHIFT;
-
- return 0;
-}
-
-static int onyx_snd_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct onyx *onyx = snd_kcontrol_chip(kcontrol);
- s8 l, r;
-
- if (ucontrol->value.integer.value[0] < -128 + VOLUME_RANGE_SHIFT ||
- ucontrol->value.integer.value[0] > -1 + VOLUME_RANGE_SHIFT)
- return -EINVAL;
- if (ucontrol->value.integer.value[1] < -128 + VOLUME_RANGE_SHIFT ||
- ucontrol->value.integer.value[1] > -1 + VOLUME_RANGE_SHIFT)
- return -EINVAL;
-
- mutex_lock(&onyx->mutex);
- onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_LEFT, &l);
- onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT, &r);
-
- if (l + VOLUME_RANGE_SHIFT == ucontrol->value.integer.value[0] &&
- r + VOLUME_RANGE_SHIFT == ucontrol->value.integer.value[1]) {
- mutex_unlock(&onyx->mutex);
- return 0;
- }
-
- onyx_write_register(onyx, ONYX_REG_DAC_ATTEN_LEFT,
- ucontrol->value.integer.value[0]
- - VOLUME_RANGE_SHIFT);
- onyx_write_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT,
- ucontrol->value.integer.value[1]
- - VOLUME_RANGE_SHIFT);
- mutex_unlock(&onyx->mutex);
-
- return 1;
-}
-
-static struct snd_kcontrol_new volume_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = onyx_snd_vol_info,
- .get = onyx_snd_vol_get,
- .put = onyx_snd_vol_put,
-};
-
-/* like above, this is necessary because a lot
- * of alsa mixer programs don't handle ranges
- * that don't start at 0 properly.
- * even alsamixer is one of them... */
-#define INPUTGAIN_RANGE_SHIFT (-3)
-
-static int onyx_snd_inputgain_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 3 + INPUTGAIN_RANGE_SHIFT;
- uinfo->value.integer.max = 28 + INPUTGAIN_RANGE_SHIFT;
- return 0;
-}
-
-static int onyx_snd_inputgain_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct onyx *onyx = snd_kcontrol_chip(kcontrol);
- u8 ig;
-
- mutex_lock(&onyx->mutex);
- onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &ig);
- mutex_unlock(&onyx->mutex);
-
- ucontrol->value.integer.value[0] =
- (ig & ONYX_ADC_PGA_GAIN_MASK) + INPUTGAIN_RANGE_SHIFT;
-
- return 0;
-}
-
-static int onyx_snd_inputgain_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct onyx *onyx = snd_kcontrol_chip(kcontrol);
- u8 v, n;
-
- if (ucontrol->value.integer.value[0] < 3 + INPUTGAIN_RANGE_SHIFT ||
- ucontrol->value.integer.value[0] > 28 + INPUTGAIN_RANGE_SHIFT)
- return -EINVAL;
- mutex_lock(&onyx->mutex);
- onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
- n = v;
- n &= ~ONYX_ADC_PGA_GAIN_MASK;
- n |= (ucontrol->value.integer.value[0] - INPUTGAIN_RANGE_SHIFT)
- & ONYX_ADC_PGA_GAIN_MASK;
- onyx_write_register(onyx, ONYX_REG_ADC_CONTROL, n);
- mutex_unlock(&onyx->mutex);
-
- return n != v;
-}
-
-static struct snd_kcontrol_new inputgain_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Capture Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = onyx_snd_inputgain_info,
- .get = onyx_snd_inputgain_get,
- .put = onyx_snd_inputgain_put,
-};
-
-static int onyx_snd_capture_source_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = { "Line-In", "Microphone" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item > 1)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int onyx_snd_capture_source_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct onyx *onyx = snd_kcontrol_chip(kcontrol);
- s8 v;
-
- mutex_lock(&onyx->mutex);
- onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
- mutex_unlock(&onyx->mutex);
-
- ucontrol->value.enumerated.item[0] = !!(v&ONYX_ADC_INPUT_MIC);
-
- return 0;
-}
-
-static void onyx_set_capture_source(struct onyx *onyx, int mic)
-{
- s8 v;
-
- mutex_lock(&onyx->mutex);
- onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
- v &= ~ONYX_ADC_INPUT_MIC;
- if (mic)
- v |= ONYX_ADC_INPUT_MIC;
- onyx_write_register(onyx, ONYX_REG_ADC_CONTROL, v);
- mutex_unlock(&onyx->mutex);
-}
-
-static int onyx_snd_capture_source_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- if (ucontrol->value.enumerated.item[0] > 1)
- return -EINVAL;
- onyx_set_capture_source(snd_kcontrol_chip(kcontrol),
- ucontrol->value.enumerated.item[0]);
- return 1;
-}
-
-static struct snd_kcontrol_new capture_source_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- /* If we name this 'Input Source', it properly shows up in
- * alsamixer as a selection, * but it's shown under the
- * 'Playback' category.
- * If I name it 'Capture Source', it shows up in strange
- * ways (two bools of which one can be selected at a
- * time) but at least it's shown in the 'Capture'
- * category.
- * I was told that this was due to backward compatibility,
- * but I don't understand then why the mangling is *not*
- * done when I name it "Input Source".....
- */
- .name = "Capture Source",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = onyx_snd_capture_source_info,
- .get = onyx_snd_capture_source_get,
- .put = onyx_snd_capture_source_put,
-};
-
-#define onyx_snd_mute_info snd_ctl_boolean_stereo_info
-
-static int onyx_snd_mute_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct onyx *onyx = snd_kcontrol_chip(kcontrol);
- u8 c;
-
- mutex_lock(&onyx->mutex);
- onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &c);
- mutex_unlock(&onyx->mutex);
-
- ucontrol->value.integer.value[0] = !(c & ONYX_MUTE_LEFT);
- ucontrol->value.integer.value[1] = !(c & ONYX_MUTE_RIGHT);
-
- return 0;
-}
-
-static int onyx_snd_mute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct onyx *onyx = snd_kcontrol_chip(kcontrol);
- u8 v = 0, c = 0;
- int err = -EBUSY;
-
- mutex_lock(&onyx->mutex);
- if (onyx->analog_locked)
- goto out_unlock;
-
- onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
- c = v;
- c &= ~(ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT);
- if (!ucontrol->value.integer.value[0])
- c |= ONYX_MUTE_LEFT;
- if (!ucontrol->value.integer.value[1])
- c |= ONYX_MUTE_RIGHT;
- err = onyx_write_register(onyx, ONYX_REG_DAC_CONTROL, c);
-
- out_unlock:
- mutex_unlock(&onyx->mutex);
-
- return !err ? (v != c) : err;
-}
-
-static struct snd_kcontrol_new mute_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = onyx_snd_mute_info,
- .get = onyx_snd_mute_get,
- .put = onyx_snd_mute_put,
-};
-
-
-#define onyx_snd_single_bit_info snd_ctl_boolean_mono_info
-
-#define FLAG_POLARITY_INVERT 1
-#define FLAG_SPDIFLOCK 2
-
-static int onyx_snd_single_bit_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct onyx *onyx = snd_kcontrol_chip(kcontrol);
- u8 c;
- long int pv = kcontrol->private_value;
- u8 polarity = (pv >> 16) & FLAG_POLARITY_INVERT;
- u8 address = (pv >> 8) & 0xff;
- u8 mask = pv & 0xff;
-
- mutex_lock(&onyx->mutex);
- onyx_read_register(onyx, address, &c);
- mutex_unlock(&onyx->mutex);
-
- ucontrol->value.integer.value[0] = !!(c & mask) ^ polarity;
-
- return 0;
-}
-
-static int onyx_snd_single_bit_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct onyx *onyx = snd_kcontrol_chip(kcontrol);
- u8 v = 0, c = 0;
- int err;
- long int pv = kcontrol->private_value;
- u8 polarity = (pv >> 16) & FLAG_POLARITY_INVERT;
- u8 spdiflock = (pv >> 16) & FLAG_SPDIFLOCK;
- u8 address = (pv >> 8) & 0xff;
- u8 mask = pv & 0xff;
-
- mutex_lock(&onyx->mutex);
- if (spdiflock && onyx->spdif_locked) {
- /* even if alsamixer doesn't care.. */
- err = -EBUSY;
- goto out_unlock;
- }
- onyx_read_register(onyx, address, &v);
- c = v;
- c &= ~(mask);
- if (!!ucontrol->value.integer.value[0] ^ polarity)
- c |= mask;
- err = onyx_write_register(onyx, address, c);
-
- out_unlock:
- mutex_unlock(&onyx->mutex);
-
- return !err ? (v != c) : err;
-}
-
-#define SINGLE_BIT(n, type, description, address, mask, flags) \
-static struct snd_kcontrol_new n##_control = { \
- .iface = SNDRV_CTL_ELEM_IFACE_##type, \
- .name = description, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
- .info = onyx_snd_single_bit_info, \
- .get = onyx_snd_single_bit_get, \
- .put = onyx_snd_single_bit_put, \
- .private_value = (flags << 16) | (address << 8) | mask \
-}
-
-SINGLE_BIT(spdif,
- MIXER,
- SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
- ONYX_REG_DIG_INFO4,
- ONYX_SPDIF_ENABLE,
- FLAG_SPDIFLOCK);
-SINGLE_BIT(ovr1,
- MIXER,
- "Oversampling Rate",
- ONYX_REG_DAC_CONTROL,
- ONYX_OVR1,
- 0);
-SINGLE_BIT(flt0,
- MIXER,
- "Fast Digital Filter Rolloff",
- ONYX_REG_DAC_FILTER,
- ONYX_ROLLOFF_FAST,
- FLAG_POLARITY_INVERT);
-SINGLE_BIT(hpf,
- MIXER,
- "Highpass Filter",
- ONYX_REG_ADC_HPF_BYPASS,
- ONYX_HPF_DISABLE,
- FLAG_POLARITY_INVERT);
-SINGLE_BIT(dm12,
- MIXER,
- "Digital De-Emphasis",
- ONYX_REG_DAC_DEEMPH,
- ONYX_DIGDEEMPH_CTRL,
- 0);
-
-static int onyx_spdif_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int onyx_spdif_mask_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- /* datasheet page 30, all others are 0 */
- ucontrol->value.iec958.status[0] = 0x3e;
- ucontrol->value.iec958.status[1] = 0xff;
-
- ucontrol->value.iec958.status[3] = 0x3f;
- ucontrol->value.iec958.status[4] = 0x0f;
-
- return 0;
-}
-
-static struct snd_kcontrol_new onyx_spdif_mask = {
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
- .info = onyx_spdif_info,
- .get = onyx_spdif_mask_get,
-};
-
-static int onyx_spdif_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct onyx *onyx = snd_kcontrol_chip(kcontrol);
- u8 v;
-
- mutex_lock(&onyx->mutex);
- onyx_read_register(onyx, ONYX_REG_DIG_INFO1, &v);
- ucontrol->value.iec958.status[0] = v & 0x3e;
-
- onyx_read_register(onyx, ONYX_REG_DIG_INFO2, &v);
- ucontrol->value.iec958.status[1] = v;
-
- onyx_read_register(onyx, ONYX_REG_DIG_INFO3, &v);
- ucontrol->value.iec958.status[3] = v & 0x3f;
-
- onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
- ucontrol->value.iec958.status[4] = v & 0x0f;
- mutex_unlock(&onyx->mutex);
-
- return 0;
-}
-
-static int onyx_spdif_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct onyx *onyx = snd_kcontrol_chip(kcontrol);
- u8 v;
-
- mutex_lock(&onyx->mutex);
- onyx_read_register(onyx, ONYX_REG_DIG_INFO1, &v);
- v = (v & ~0x3e) | (ucontrol->value.iec958.status[0] & 0x3e);
- onyx_write_register(onyx, ONYX_REG_DIG_INFO1, v);
-
- v = ucontrol->value.iec958.status[1];
- onyx_write_register(onyx, ONYX_REG_DIG_INFO2, v);
-
- onyx_read_register(onyx, ONYX_REG_DIG_INFO3, &v);
- v = (v & ~0x3f) | (ucontrol->value.iec958.status[3] & 0x3f);
- onyx_write_register(onyx, ONYX_REG_DIG_INFO3, v);
-
- onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
- v = (v & ~0x0f) | (ucontrol->value.iec958.status[4] & 0x0f);
- onyx_write_register(onyx, ONYX_REG_DIG_INFO4, v);
- mutex_unlock(&onyx->mutex);
-
- return 1;
-}
-
-static struct snd_kcontrol_new onyx_spdif_ctrl = {
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
- .info = onyx_spdif_info,
- .get = onyx_spdif_get,
- .put = onyx_spdif_put,
-};
-
-/* our registers */
-
-static u8 register_map[] = {
- ONYX_REG_DAC_ATTEN_LEFT,
- ONYX_REG_DAC_ATTEN_RIGHT,
- ONYX_REG_CONTROL,
- ONYX_REG_DAC_CONTROL,
- ONYX_REG_DAC_DEEMPH,
- ONYX_REG_DAC_FILTER,
- ONYX_REG_DAC_OUTPHASE,
- ONYX_REG_ADC_CONTROL,
- ONYX_REG_ADC_HPF_BYPASS,
- ONYX_REG_DIG_INFO1,
- ONYX_REG_DIG_INFO2,
- ONYX_REG_DIG_INFO3,
- ONYX_REG_DIG_INFO4
-};
-
-static u8 initial_values[ARRAY_SIZE(register_map)] = {
- 0x80, 0x80, /* muted */
- ONYX_MRST | ONYX_SRST, /* but handled specially! */
- ONYX_MUTE_LEFT | ONYX_MUTE_RIGHT,
- 0, /* no deemphasis */
- ONYX_DAC_FILTER_ALWAYS,
- ONYX_OUTPHASE_INVERTED,
- (-1 /*dB*/ + 8) & 0xF, /* line in selected, -1 dB gain*/
- ONYX_ADC_HPF_ALWAYS,
- (1<<2), /* pcm audio */
- 2, /* category: pcm coder */
- 0, /* sampling frequency 44.1 kHz, clock accuracy level II */
- 1 /* 24 bit depth */
-};
-
-/* reset registers of chip, either to initial or to previous values */
-static int onyx_register_init(struct onyx *onyx)
-{
- int i;
- u8 val;
- u8 regs[sizeof(initial_values)];
-
- if (!onyx->initialised) {
- memcpy(regs, initial_values, sizeof(initial_values));
- if (onyx_read_register(onyx, ONYX_REG_CONTROL, &val))
- return -1;
- val &= ~ONYX_SILICONVERSION;
- val |= initial_values[3];
- regs[3] = val;
- } else {
- for (i=0; i<sizeof(register_map); i++)
- regs[i] = onyx->cache[register_map[i]-FIRSTREGISTER];
- }
-
- for (i=0; i<sizeof(register_map); i++) {
- if (onyx_write_register(onyx, register_map[i], regs[i]))
- return -1;
- }
- onyx->initialised = 1;
- return 0;
-}
-
-static struct transfer_info onyx_transfers[] = {
- /* this is first so we can skip it if no input is present...
- * No hardware exists with that, but it's here as an example
- * of what to do :) */
- {
- /* analog input */
- .formats = SNDRV_PCM_FMTBIT_S8 |
- SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_S24_BE,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .transfer_in = 1,
- .must_be_clock_source = 0,
- .tag = 0,
- },
- {
- /* if analog and digital are currently off, anything should go,
- * so this entry describes everything we can do... */
- .formats = SNDRV_PCM_FMTBIT_S8 |
- SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_S24_BE
-#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
- | SNDRV_PCM_FMTBIT_COMPRESSED_16BE
-#endif
- ,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .tag = 0,
- },
- {
- /* analog output */
- .formats = SNDRV_PCM_FMTBIT_S8 |
- SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_S24_BE,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .transfer_in = 0,
- .must_be_clock_source = 0,
- .tag = 1,
- },
- {
- /* digital pcm output, also possible for analog out */
- .formats = SNDRV_PCM_FMTBIT_S8 |
- SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_S24_BE,
- .rates = SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000,
- .transfer_in = 0,
- .must_be_clock_source = 0,
- .tag = 2,
- },
-#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
- /* Once alsa gets supports for this kind of thing we can add it... */
- {
- /* digital compressed output */
- .formats = SNDRV_PCM_FMTBIT_COMPRESSED_16BE,
- .rates = SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000,
- .tag = 2,
- },
-#endif
- {}
-};
-
-static int onyx_usable(struct codec_info_item *cii,
- struct transfer_info *ti,
- struct transfer_info *out)
-{
- u8 v;
- struct onyx *onyx = cii->codec_data;
- int spdif_enabled, analog_enabled;
-
- mutex_lock(&onyx->mutex);
- onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
- spdif_enabled = !!(v & ONYX_SPDIF_ENABLE);
- onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
- analog_enabled =
- (v & (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT))
- != (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT);
- mutex_unlock(&onyx->mutex);
-
- switch (ti->tag) {
- case 0: return 1;
- case 1: return analog_enabled;
- case 2: return spdif_enabled;
- }
- return 1;
-}
-
-static int onyx_prepare(struct codec_info_item *cii,
- struct bus_info *bi,
- struct snd_pcm_substream *substream)
-{
- u8 v;
- struct onyx *onyx = cii->codec_data;
- int err = -EBUSY;
-
- mutex_lock(&onyx->mutex);
-
-#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
- if (substream->runtime->format == SNDRV_PCM_FMTBIT_COMPRESSED_16BE) {
- /* mute and lock analog output */
- onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
- if (onyx_write_register(onyx,
- ONYX_REG_DAC_CONTROL,
- v | ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT))
- goto out_unlock;
- onyx->analog_locked = 1;
- err = 0;
- goto out_unlock;
- }
-#endif
- switch (substream->runtime->rate) {
- case 32000:
- case 44100:
- case 48000:
- /* these rates are ok for all outputs */
- /* FIXME: program spdif channel control bits here so that
- * userspace doesn't have to if it only plays pcm! */
- err = 0;
- goto out_unlock;
- default:
- /* got some rate that the digital output can't do,
- * so disable and lock it */
- onyx_read_register(cii->codec_data, ONYX_REG_DIG_INFO4, &v);
- if (onyx_write_register(onyx,
- ONYX_REG_DIG_INFO4,
- v & ~ONYX_SPDIF_ENABLE))
- goto out_unlock;
- onyx->spdif_locked = 1;
- err = 0;
- goto out_unlock;
- }
-
- out_unlock:
- mutex_unlock(&onyx->mutex);
-
- return err;
-}
-
-static int onyx_open(struct codec_info_item *cii,
- struct snd_pcm_substream *substream)
-{
- struct onyx *onyx = cii->codec_data;
-
- mutex_lock(&onyx->mutex);
- onyx->open_count++;
- mutex_unlock(&onyx->mutex);
-
- return 0;
-}
-
-static int onyx_close(struct codec_info_item *cii,
- struct snd_pcm_substream *substream)
-{
- struct onyx *onyx = cii->codec_data;
-
- mutex_lock(&onyx->mutex);
- onyx->open_count--;
- if (!onyx->open_count)
- onyx->spdif_locked = onyx->analog_locked = 0;
- mutex_unlock(&onyx->mutex);
-
- return 0;
-}
-
-static int onyx_switch_clock(struct codec_info_item *cii,
- enum clock_switch what)
-{
- struct onyx *onyx = cii->codec_data;
-
- mutex_lock(&onyx->mutex);
- /* this *MUST* be more elaborate later... */
- switch (what) {
- case CLOCK_SWITCH_PREPARE_SLAVE:
- onyx->codec.gpio->methods->all_amps_off(onyx->codec.gpio);
- break;
- case CLOCK_SWITCH_SLAVE:
- onyx->codec.gpio->methods->all_amps_restore(onyx->codec.gpio);
- break;
- default: /* silence warning */
- break;
- }
- mutex_unlock(&onyx->mutex);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-
-static int onyx_suspend(struct codec_info_item *cii, pm_message_t state)
-{
- struct onyx *onyx = cii->codec_data;
- u8 v;
- int err = -ENXIO;
-
- mutex_lock(&onyx->mutex);
- if (onyx_read_register(onyx, ONYX_REG_CONTROL, &v))
- goto out_unlock;
- onyx_write_register(onyx, ONYX_REG_CONTROL, v | ONYX_ADPSV | ONYX_DAPSV);
- /* Apple does a sleep here but the datasheet says to do it on resume */
- err = 0;
- out_unlock:
- mutex_unlock(&onyx->mutex);
-
- return err;
-}
-
-static int onyx_resume(struct codec_info_item *cii)
-{
- struct onyx *onyx = cii->codec_data;
- u8 v;
- int err = -ENXIO;
-
- mutex_lock(&onyx->mutex);
-
- /* reset codec */
- onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
- msleep(1);
- onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 1);
- msleep(1);
- onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
- msleep(1);
-
- /* take codec out of suspend (if it still is after reset) */
- if (onyx_read_register(onyx, ONYX_REG_CONTROL, &v))
- goto out_unlock;
- onyx_write_register(onyx, ONYX_REG_CONTROL, v & ~(ONYX_ADPSV | ONYX_DAPSV));
- /* FIXME: should divide by sample rate, but 8k is the lowest we go */
- msleep(2205000/8000);
- /* reset all values */
- onyx_register_init(onyx);
- err = 0;
- out_unlock:
- mutex_unlock(&onyx->mutex);
-
- return err;
-}
-
-#endif /* CONFIG_PM */
-
-static struct codec_info onyx_codec_info = {
- .transfers = onyx_transfers,
- .sysclock_factor = 256,
- .bus_factor = 64,
- .owner = THIS_MODULE,
- .usable = onyx_usable,
- .prepare = onyx_prepare,
- .open = onyx_open,
- .close = onyx_close,
- .switch_clock = onyx_switch_clock,
-#ifdef CONFIG_PM
- .suspend = onyx_suspend,
- .resume = onyx_resume,
-#endif
-};
-
-static int onyx_init_codec(struct aoa_codec *codec)
-{
- struct onyx *onyx = codec_to_onyx(codec);
- struct snd_kcontrol *ctl;
- struct codec_info *ci = &onyx_codec_info;
- u8 v;
- int err;
-
- if (!onyx->codec.gpio || !onyx->codec.gpio->methods) {
- printk(KERN_ERR PFX "gpios not assigned!!\n");
- return -EINVAL;
- }
-
- onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
- msleep(1);
- onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 1);
- msleep(1);
- onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
- msleep(1);
-
- if (onyx_register_init(onyx)) {
- printk(KERN_ERR PFX "failed to initialise onyx registers\n");
- return -ENODEV;
- }
-
- if (aoa_snd_device_new(SNDRV_DEV_LOWLEVEL, onyx, &ops)) {
- printk(KERN_ERR PFX "failed to create onyx snd device!\n");
- return -ENODEV;
- }
-
- /* nothing connected? what a joke! */
- if ((onyx->codec.connected & 0xF) == 0)
- return -ENOTCONN;
-
- /* if no inputs are present... */
- if ((onyx->codec.connected & 0xC) == 0) {
- if (!onyx->codec_info)
- onyx->codec_info = kmalloc(sizeof(struct codec_info), GFP_KERNEL);
- if (!onyx->codec_info)
- return -ENOMEM;
- ci = onyx->codec_info;
- *ci = onyx_codec_info;
- ci->transfers++;
- }
-
- /* if no outputs are present... */
- if ((onyx->codec.connected & 3) == 0) {
- if (!onyx->codec_info)
- onyx->codec_info = kmalloc(sizeof(struct codec_info), GFP_KERNEL);
- if (!onyx->codec_info)
- return -ENOMEM;
- ci = onyx->codec_info;
- /* this is fine as there have to be inputs
- * if we end up in this part of the code */
- *ci = onyx_codec_info;
- ci->transfers[1].formats = 0;
- }
-
- if (onyx->codec.soundbus_dev->attach_codec(onyx->codec.soundbus_dev,
- aoa_get_card(),
- ci, onyx)) {
- printk(KERN_ERR PFX "error creating onyx pcm\n");
- return -ENODEV;
- }
-#define ADDCTL(n) \
- do { \
- ctl = snd_ctl_new1(&n, onyx); \
- if (ctl) { \
- ctl->id.device = \
- onyx->codec.soundbus_dev->pcm->device; \
- err = aoa_snd_ctl_add(ctl); \
- if (err) \
- goto error; \
- } \
- } while (0)
-
- if (onyx->codec.soundbus_dev->pcm) {
- /* give the user appropriate controls
- * depending on what inputs are connected */
- if ((onyx->codec.connected & 0xC) == 0xC)
- ADDCTL(capture_source_control);
- else if (onyx->codec.connected & 4)
- onyx_set_capture_source(onyx, 0);
- else
- onyx_set_capture_source(onyx, 1);
- if (onyx->codec.connected & 0xC)
- ADDCTL(inputgain_control);
-
- /* depending on what output is connected,
- * give the user appropriate controls */
- if (onyx->codec.connected & 1) {
- ADDCTL(volume_control);
- ADDCTL(mute_control);
- ADDCTL(ovr1_control);
- ADDCTL(flt0_control);
- ADDCTL(hpf_control);
- ADDCTL(dm12_control);
- /* spdif control defaults to off */
- }
- if (onyx->codec.connected & 2) {
- ADDCTL(onyx_spdif_mask);
- ADDCTL(onyx_spdif_ctrl);
- }
- if ((onyx->codec.connected & 3) == 3)
- ADDCTL(spdif_control);
- /* if only S/PDIF is connected, enable it unconditionally */
- if ((onyx->codec.connected & 3) == 2) {
- onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
- v |= ONYX_SPDIF_ENABLE;
- onyx_write_register(onyx, ONYX_REG_DIG_INFO4, v);
- }
- }
-#undef ADDCTL
- printk(KERN_INFO PFX "attached to onyx codec via i2c\n");
-
- return 0;
- error:
- onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx);
- snd_device_free(aoa_get_card(), onyx);
- return err;
-}
-
-static void onyx_exit_codec(struct aoa_codec *codec)
-{
- struct onyx *onyx = codec_to_onyx(codec);
-
- if (!onyx->codec.soundbus_dev) {
- printk(KERN_ERR PFX "onyx_exit_codec called without soundbus_dev!\n");
- return;
- }
- onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx);
-}
-
-static int onyx_create(struct i2c_adapter *adapter,
- struct device_node *node,
- int addr)
-{
- struct i2c_board_info info;
- struct i2c_client *client;
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- strlcpy(info.type, "aoa_codec_onyx", I2C_NAME_SIZE);
- info.addr = addr;
- info.platform_data = node;
- client = i2c_new_device(adapter, &info);
- if (!client)
- return -ENODEV;
-
- /*
- * We know the driver is already loaded, so the device should be
- * already bound. If not it means binding failed, which suggests
- * the device doesn't really exist and should be deleted.
- * Ideally this would be replaced by better checks _before_
- * instantiating the device.
- */
- if (!client->driver) {
- i2c_unregister_device(client);
- return -ENODEV;
- }
-
- /*
- * Let i2c-core delete that device on driver removal.
- * This is safe because i2c-core holds the core_lock mutex for us.
- */
- list_add_tail(&client->detected, &client->driver->clients);
- return 0;
-}
-
-static int onyx_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct device_node *node = client->dev.platform_data;
- struct onyx *onyx;
- u8 dummy;
-
- onyx = kzalloc(sizeof(struct onyx), GFP_KERNEL);
-
- if (!onyx)
- return -ENOMEM;
-
- mutex_init(&onyx->mutex);
- onyx->i2c = client;
- i2c_set_clientdata(client, onyx);
-
- /* we try to read from register ONYX_REG_CONTROL
- * to check if the codec is present */
- if (onyx_read_register(onyx, ONYX_REG_CONTROL, &dummy) != 0) {
- printk(KERN_ERR PFX "failed to read control register\n");
- goto fail;
- }
-
- strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN);
- onyx->codec.owner = THIS_MODULE;
- onyx->codec.init = onyx_init_codec;
- onyx->codec.exit = onyx_exit_codec;
- onyx->codec.node = of_node_get(node);
-
- if (aoa_codec_register(&onyx->codec)) {
- goto fail;
- }
- printk(KERN_DEBUG PFX "created and attached onyx instance\n");
- return 0;
- fail:
- kfree(onyx);
- return -ENODEV;
-}
-
-static int onyx_i2c_attach(struct i2c_adapter *adapter)
-{
- struct device_node *busnode, *dev = NULL;
- struct pmac_i2c_bus *bus;
-
- bus = pmac_i2c_adapter_to_bus(adapter);
- if (bus == NULL)
- return -ENODEV;
- busnode = pmac_i2c_get_bus_node(bus);
-
- while ((dev = of_get_next_child(busnode, dev)) != NULL) {
- if (of_device_is_compatible(dev, "pcm3052")) {
- const u32 *addr;
- printk(KERN_DEBUG PFX "found pcm3052\n");
- addr = of_get_property(dev, "reg", NULL);
- if (!addr)
- return -ENODEV;
- return onyx_create(adapter, dev, (*addr)>>1);
- }
- }
-
- /* if that didn't work, try desperate mode for older
- * machines that have stuff missing from the device tree */
-
- if (!of_device_is_compatible(busnode, "k2-i2c"))
- return -ENODEV;
-
- printk(KERN_DEBUG PFX "found k2-i2c, checking if onyx chip is on it\n");
- /* probe both possible addresses for the onyx chip */
- if (onyx_create(adapter, NULL, 0x46) == 0)
- return 0;
- return onyx_create(adapter, NULL, 0x47);
-}
-
-static int onyx_i2c_remove(struct i2c_client *client)
-{
- struct onyx *onyx = i2c_get_clientdata(client);
-
- aoa_codec_unregister(&onyx->codec);
- of_node_put(onyx->codec.node);
- kfree(onyx->codec_info);
- kfree(onyx);
- return 0;
-}
-
-static const struct i2c_device_id onyx_i2c_id[] = {
- { "aoa_codec_onyx", 0 },
- { }
-};
-
-static struct i2c_driver onyx_driver = {
- .driver = {
- .name = "aoa_codec_onyx",
- .owner = THIS_MODULE,
- },
- .attach_adapter = onyx_i2c_attach,
- .probe = onyx_i2c_probe,
- .remove = onyx_i2c_remove,
- .id_table = onyx_i2c_id,
-};
-
-module_i2c_driver(onyx_driver);
diff --git a/ANDROID_3.4.5/sound/aoa/codecs/onyx.h b/ANDROID_3.4.5/sound/aoa/codecs/onyx.h
deleted file mode 100644
index ffd20254..00000000
--- a/ANDROID_3.4.5/sound/aoa/codecs/onyx.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Apple Onboard Audio driver for Onyx codec (header)
- *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- */
-#ifndef __SND_AOA_CODEC_ONYX_H
-#define __SND_AOA_CODEC_ONYX_H
-#include <stddef.h>
-#include <linux/i2c.h>
-#include <asm/pmac_low_i2c.h>
-#include <asm/prom.h>
-
-/* PCM3052 register definitions */
-
-/* the attenuation registers take values from
- * -1 (0dB) to -127 (-63.0 dB) or others (muted) */
-#define ONYX_REG_DAC_ATTEN_LEFT 65
-#define FIRSTREGISTER ONYX_REG_DAC_ATTEN_LEFT
-#define ONYX_REG_DAC_ATTEN_RIGHT 66
-
-#define ONYX_REG_CONTROL 67
-# define ONYX_MRST (1<<7)
-# define ONYX_SRST (1<<6)
-# define ONYX_ADPSV (1<<5)
-# define ONYX_DAPSV (1<<4)
-# define ONYX_SILICONVERSION (1<<0)
-/* all others reserved */
-
-#define ONYX_REG_DAC_CONTROL 68
-# define ONYX_OVR1 (1<<6)
-# define ONYX_MUTE_RIGHT (1<<1)
-# define ONYX_MUTE_LEFT (1<<0)
-
-#define ONYX_REG_DAC_DEEMPH 69
-# define ONYX_DIGDEEMPH_SHIFT 5
-# define ONYX_DIGDEEMPH_MASK (3<<ONYX_DIGDEEMPH_SHIFT)
-# define ONYX_DIGDEEMPH_CTRL (1<<4)
-
-#define ONYX_REG_DAC_FILTER 70
-# define ONYX_ROLLOFF_FAST (1<<5)
-# define ONYX_DAC_FILTER_ALWAYS (1<<2)
-
-#define ONYX_REG_DAC_OUTPHASE 71
-# define ONYX_OUTPHASE_INVERTED (1<<0)
-
-#define ONYX_REG_ADC_CONTROL 72
-# define ONYX_ADC_INPUT_MIC (1<<5)
-/* 8 + input gain in dB, valid range for input gain is -4 .. 20 dB */
-# define ONYX_ADC_PGA_GAIN_MASK 0x1f
-
-#define ONYX_REG_ADC_HPF_BYPASS 75
-# define ONYX_HPF_DISABLE (1<<3)
-# define ONYX_ADC_HPF_ALWAYS (1<<2)
-
-#define ONYX_REG_DIG_INFO1 77
-# define ONYX_MASK_DIN_TO_BPZ (1<<7)
-/* bits 1-5 control channel bits 1-5 */
-# define ONYX_DIGOUT_DISABLE (1<<0)
-
-#define ONYX_REG_DIG_INFO2 78
-/* controls channel bits 8-15 */
-
-#define ONYX_REG_DIG_INFO3 79
-/* control channel bits 24-29, high 2 bits reserved */
-
-#define ONYX_REG_DIG_INFO4 80
-# define ONYX_VALIDL (1<<7)
-# define ONYX_VALIDR (1<<6)
-# define ONYX_SPDIF_ENABLE (1<<5)
-/* lower 4 bits control bits 32-35 of channel control and word length */
-# define ONYX_WORDLEN_MASK (0xF)
-
-#endif /* __SND_AOA_CODEC_ONYX_H */
diff --git a/ANDROID_3.4.5/sound/aoa/codecs/tas-basstreble.h b/ANDROID_3.4.5/sound/aoa/codecs/tas-basstreble.h
deleted file mode 100644
index 69b61136..00000000
--- a/ANDROID_3.4.5/sound/aoa/codecs/tas-basstreble.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * This file is only included exactly once!
- *
- * The tables here are derived from the tas3004 datasheet,
- * modulo typo corrections and some smoothing...
- */
-
-#define TAS3004_TREBLE_MIN 0
-#define TAS3004_TREBLE_MAX 72
-#define TAS3004_BASS_MIN 0
-#define TAS3004_BASS_MAX 72
-#define TAS3004_TREBLE_ZERO 36
-#define TAS3004_BASS_ZERO 36
-
-static u8 tas3004_treble_table[] = {
- 150, /* -18 dB */
- 149,
- 148,
- 147,
- 146,
- 145,
- 144,
- 143,
- 142,
- 141,
- 140,
- 139,
- 138,
- 137,
- 136,
- 135,
- 134,
- 133,
- 132,
- 131,
- 130,
- 129,
- 128,
- 127,
- 126,
- 125,
- 124,
- 123,
- 122,
- 121,
- 120,
- 119,
- 118,
- 117,
- 116,
- 115,
- 114, /* 0 dB */
- 113,
- 112,
- 111,
- 109,
- 108,
- 107,
- 105,
- 104,
- 103,
- 101,
- 99,
- 98,
- 96,
- 93,
- 91,
- 89,
- 86,
- 83,
- 81,
- 77,
- 74,
- 71,
- 67,
- 63,
- 59,
- 54,
- 49,
- 44,
- 38,
- 32,
- 26,
- 19,
- 10,
- 4,
- 2,
- 1, /* +18 dB */
-};
-
-static inline u8 tas3004_treble(int idx)
-{
- return tas3004_treble_table[idx];
-}
-
-/* I only save the difference here to the treble table
- * so that the binary is smaller...
- * I have also ignored completely differences of
- * +/- 1
- */
-static s8 tas3004_bass_diff_to_treble[] = {
- 2, /* 7 dB, offset 50 */
- 2,
- 2,
- 2,
- 2,
- 1,
- 2,
- 2,
- 2,
- 3,
- 4,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9,
- 10,
- 11,
- 14,
- 13,
- 8,
- 1, /* 18 dB */
-};
-
-static inline u8 tas3004_bass(int idx)
-{
- u8 result = tas3004_treble_table[idx];
-
- if (idx >= 50)
- result += tas3004_bass_diff_to_treble[idx-50];
- return result;
-}
diff --git a/ANDROID_3.4.5/sound/aoa/codecs/tas-gain-table.h b/ANDROID_3.4.5/sound/aoa/codecs/tas-gain-table.h
deleted file mode 100644
index 4cfa6757..00000000
--- a/ANDROID_3.4.5/sound/aoa/codecs/tas-gain-table.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- This is the program used to generate below table.
-
-#include <stdio.h>
-#include <math.h>
-int main() {
- int dB2;
- printf("/" "* This file is only included exactly once!\n");
- printf(" *\n");
- printf(" * If they'd only tell us that generating this table was\n");
- printf(" * as easy as calculating\n");
- printf(" * hwvalue = 1048576.0*exp(0.057564628*dB*2)\n");
- printf(" * :) *" "/\n");
- printf("static int tas_gaintable[] = {\n");
- printf(" 0x000000, /" "* -infinity dB *" "/\n");
- for (dB2=-140;dB2<=36;dB2++)
- printf(" 0x%.6x, /" "* %-02.1f dB *" "/\n", (int)(1048576.0*exp(0.057564628*dB2)), dB2/2.0);
- printf("};\n\n");
-}
-
-*/
-
-/* This file is only included exactly once!
- *
- * If they'd only tell us that generating this table was
- * as easy as calculating
- * hwvalue = 1048576.0*exp(0.057564628*dB*2)
- * :) */
-static int tas_gaintable[] = {
- 0x000000, /* -infinity dB */
- 0x00014b, /* -70.0 dB */
- 0x00015f, /* -69.5 dB */
- 0x000174, /* -69.0 dB */
- 0x00018a, /* -68.5 dB */
- 0x0001a1, /* -68.0 dB */
- 0x0001ba, /* -67.5 dB */
- 0x0001d4, /* -67.0 dB */
- 0x0001f0, /* -66.5 dB */
- 0x00020d, /* -66.0 dB */
- 0x00022c, /* -65.5 dB */
- 0x00024d, /* -65.0 dB */
- 0x000270, /* -64.5 dB */
- 0x000295, /* -64.0 dB */
- 0x0002bc, /* -63.5 dB */
- 0x0002e6, /* -63.0 dB */
- 0x000312, /* -62.5 dB */
- 0x000340, /* -62.0 dB */
- 0x000372, /* -61.5 dB */
- 0x0003a6, /* -61.0 dB */
- 0x0003dd, /* -60.5 dB */
- 0x000418, /* -60.0 dB */
- 0x000456, /* -59.5 dB */
- 0x000498, /* -59.0 dB */
- 0x0004de, /* -58.5 dB */
- 0x000528, /* -58.0 dB */
- 0x000576, /* -57.5 dB */
- 0x0005c9, /* -57.0 dB */
- 0x000620, /* -56.5 dB */
- 0x00067d, /* -56.0 dB */
- 0x0006e0, /* -55.5 dB */
- 0x000748, /* -55.0 dB */
- 0x0007b7, /* -54.5 dB */
- 0x00082c, /* -54.0 dB */
- 0x0008a8, /* -53.5 dB */
- 0x00092b, /* -53.0 dB */
- 0x0009b6, /* -52.5 dB */
- 0x000a49, /* -52.0 dB */
- 0x000ae5, /* -51.5 dB */
- 0x000b8b, /* -51.0 dB */
- 0x000c3a, /* -50.5 dB */
- 0x000cf3, /* -50.0 dB */
- 0x000db8, /* -49.5 dB */
- 0x000e88, /* -49.0 dB */
- 0x000f64, /* -48.5 dB */
- 0x00104e, /* -48.0 dB */
- 0x001145, /* -47.5 dB */
- 0x00124b, /* -47.0 dB */
- 0x001361, /* -46.5 dB */
- 0x001487, /* -46.0 dB */
- 0x0015be, /* -45.5 dB */
- 0x001708, /* -45.0 dB */
- 0x001865, /* -44.5 dB */
- 0x0019d8, /* -44.0 dB */
- 0x001b60, /* -43.5 dB */
- 0x001cff, /* -43.0 dB */
- 0x001eb7, /* -42.5 dB */
- 0x002089, /* -42.0 dB */
- 0x002276, /* -41.5 dB */
- 0x002481, /* -41.0 dB */
- 0x0026ab, /* -40.5 dB */
- 0x0028f5, /* -40.0 dB */
- 0x002b63, /* -39.5 dB */
- 0x002df5, /* -39.0 dB */
- 0x0030ae, /* -38.5 dB */
- 0x003390, /* -38.0 dB */
- 0x00369e, /* -37.5 dB */
- 0x0039db, /* -37.0 dB */
- 0x003d49, /* -36.5 dB */
- 0x0040ea, /* -36.0 dB */
- 0x0044c3, /* -35.5 dB */
- 0x0048d6, /* -35.0 dB */
- 0x004d27, /* -34.5 dB */
- 0x0051b9, /* -34.0 dB */
- 0x005691, /* -33.5 dB */
- 0x005bb2, /* -33.0 dB */
- 0x006121, /* -32.5 dB */
- 0x0066e3, /* -32.0 dB */
- 0x006cfb, /* -31.5 dB */
- 0x007370, /* -31.0 dB */
- 0x007a48, /* -30.5 dB */
- 0x008186, /* -30.0 dB */
- 0x008933, /* -29.5 dB */
- 0x009154, /* -29.0 dB */
- 0x0099f1, /* -28.5 dB */
- 0x00a310, /* -28.0 dB */
- 0x00acba, /* -27.5 dB */
- 0x00b6f6, /* -27.0 dB */
- 0x00c1cd, /* -26.5 dB */
- 0x00cd49, /* -26.0 dB */
- 0x00d973, /* -25.5 dB */
- 0x00e655, /* -25.0 dB */
- 0x00f3fb, /* -24.5 dB */
- 0x010270, /* -24.0 dB */
- 0x0111c0, /* -23.5 dB */
- 0x0121f9, /* -23.0 dB */
- 0x013328, /* -22.5 dB */
- 0x01455b, /* -22.0 dB */
- 0x0158a2, /* -21.5 dB */
- 0x016d0e, /* -21.0 dB */
- 0x0182af, /* -20.5 dB */
- 0x019999, /* -20.0 dB */
- 0x01b1de, /* -19.5 dB */
- 0x01cb94, /* -19.0 dB */
- 0x01e6cf, /* -18.5 dB */
- 0x0203a7, /* -18.0 dB */
- 0x022235, /* -17.5 dB */
- 0x024293, /* -17.0 dB */
- 0x0264db, /* -16.5 dB */
- 0x02892c, /* -16.0 dB */
- 0x02afa3, /* -15.5 dB */
- 0x02d862, /* -15.0 dB */
- 0x03038a, /* -14.5 dB */
- 0x033142, /* -14.0 dB */
- 0x0361af, /* -13.5 dB */
- 0x0394fa, /* -13.0 dB */
- 0x03cb50, /* -12.5 dB */
- 0x0404de, /* -12.0 dB */
- 0x0441d5, /* -11.5 dB */
- 0x048268, /* -11.0 dB */
- 0x04c6d0, /* -10.5 dB */
- 0x050f44, /* -10.0 dB */
- 0x055c04, /* -9.5 dB */
- 0x05ad50, /* -9.0 dB */
- 0x06036e, /* -8.5 dB */
- 0x065ea5, /* -8.0 dB */
- 0x06bf44, /* -7.5 dB */
- 0x07259d, /* -7.0 dB */
- 0x079207, /* -6.5 dB */
- 0x0804dc, /* -6.0 dB */
- 0x087e80, /* -5.5 dB */
- 0x08ff59, /* -5.0 dB */
- 0x0987d5, /* -4.5 dB */
- 0x0a1866, /* -4.0 dB */
- 0x0ab189, /* -3.5 dB */
- 0x0b53be, /* -3.0 dB */
- 0x0bff91, /* -2.5 dB */
- 0x0cb591, /* -2.0 dB */
- 0x0d765a, /* -1.5 dB */
- 0x0e4290, /* -1.0 dB */
- 0x0f1adf, /* -0.5 dB */
- 0x100000, /* 0.0 dB */
- 0x10f2b4, /* 0.5 dB */
- 0x11f3c9, /* 1.0 dB */
- 0x13041a, /* 1.5 dB */
- 0x14248e, /* 2.0 dB */
- 0x15561a, /* 2.5 dB */
- 0x1699c0, /* 3.0 dB */
- 0x17f094, /* 3.5 dB */
- 0x195bb8, /* 4.0 dB */
- 0x1adc61, /* 4.5 dB */
- 0x1c73d5, /* 5.0 dB */
- 0x1e236d, /* 5.5 dB */
- 0x1fec98, /* 6.0 dB */
- 0x21d0d9, /* 6.5 dB */
- 0x23d1cd, /* 7.0 dB */
- 0x25f125, /* 7.5 dB */
- 0x2830af, /* 8.0 dB */
- 0x2a9254, /* 8.5 dB */
- 0x2d1818, /* 9.0 dB */
- 0x2fc420, /* 9.5 dB */
- 0x3298b0, /* 10.0 dB */
- 0x35982f, /* 10.5 dB */
- 0x38c528, /* 11.0 dB */
- 0x3c224c, /* 11.5 dB */
- 0x3fb278, /* 12.0 dB */
- 0x4378b0, /* 12.5 dB */
- 0x477829, /* 13.0 dB */
- 0x4bb446, /* 13.5 dB */
- 0x5030a1, /* 14.0 dB */
- 0x54f106, /* 14.5 dB */
- 0x59f980, /* 15.0 dB */
- 0x5f4e52, /* 15.5 dB */
- 0x64f403, /* 16.0 dB */
- 0x6aef5e, /* 16.5 dB */
- 0x714575, /* 17.0 dB */
- 0x77fbaa, /* 17.5 dB */
- 0x7f17af, /* 18.0 dB */
-};
-
diff --git a/ANDROID_3.4.5/sound/aoa/codecs/tas.c b/ANDROID_3.4.5/sound/aoa/codecs/tas.c
deleted file mode 100644
index 8e63d1f3..00000000
--- a/ANDROID_3.4.5/sound/aoa/codecs/tas.c
+++ /dev/null
@@ -1,1029 +0,0 @@
-/*
- * Apple Onboard Audio driver for tas codec
- *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- *
- * Open questions:
- * - How to distinguish between 3004 and versions?
- *
- * FIXMEs:
- * - This codec driver doesn't honour the 'connected'
- * property of the aoa_codec struct, hence if
- * it is used in machines where not everything is
- * connected it will display wrong mixer elements.
- * - Driver assumes that the microphone is always
- * monaureal and connected to the right channel of
- * the input. This should also be a codec-dependent
- * flag, maybe the codec should have 3 different
- * bits for the three different possibilities how
- * it can be hooked up...
- * But as long as I don't see any hardware hooked
- * up that way...
- * - As Apple notes in their code, the tas3004 seems
- * to delay the right channel by one sample. You can
- * see this when for example recording stereo in
- * audacity, or recording the tas output via cable
- * on another machine (use a sinus generator or so).
- * I tried programming the BiQuads but couldn't
- * make the delay work, maybe someone can read the
- * datasheet and fix it. The relevant Apple comment
- * is in AppleTAS3004Audio.cpp lines 1637 ff. Note
- * that their comment describing how they program
- * the filters sucks...
- *
- * Other things:
- * - this should actually register *two* aoa_codec
- * structs since it has two inputs. Then it must
- * use the prepare callback to forbid running the
- * secondary output on a different clock.
- * Also, whatever bus knows how to do this must
- * provide two soundbus_dev devices and the fabric
- * must be able to link them correctly.
- *
- * I don't even know if Apple ever uses the second
- * port on the tas3004 though, I don't think their
- * i2s controllers can even do it. OTOH, they all
- * derive the clocks from common clocks, so it
- * might just be possible. The framework allows the
- * codec to refine the transfer_info items in the
- * usable callback, so we can simply remove the
- * rates the second instance is not using when it
- * actually is in use.
- * Maybe we'll need to make the sound busses have
- * a 'clock group id' value so the codec can
- * determine if the two outputs can be driven at
- * the same time. But that is likely overkill, up
- * to the fabric to not link them up incorrectly,
- * and up to the hardware designer to not wire
- * them up in some weird unusable way.
- */
-#include <stddef.h>
-#include <linux/i2c.h>
-#include <asm/pmac_low_i2c.h>
-#include <asm/prom.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-
-MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("tas codec driver for snd-aoa");
-
-#include "tas.h"
-#include "tas-gain-table.h"
-#include "tas-basstreble.h"
-#include "../aoa.h"
-#include "../soundbus/soundbus.h"
-
-#define PFX "snd-aoa-codec-tas: "
-
-
-struct tas {
- struct aoa_codec codec;
- struct i2c_client *i2c;
- u32 mute_l:1, mute_r:1 ,
- controls_created:1 ,
- drc_enabled:1,
- hw_enabled:1;
- u8 cached_volume_l, cached_volume_r;
- u8 mixer_l[3], mixer_r[3];
- u8 bass, treble;
- u8 acr;
- int drc_range;
- /* protects hardware access against concurrency from
- * userspace when hitting controls and during
- * codec init/suspend/resume */
- struct mutex mtx;
-};
-
-static int tas_reset_init(struct tas *tas);
-
-static struct tas *codec_to_tas(struct aoa_codec *codec)
-{
- return container_of(codec, struct tas, codec);
-}
-
-static inline int tas_write_reg(struct tas *tas, u8 reg, u8 len, u8 *data)
-{
- if (len == 1)
- return i2c_smbus_write_byte_data(tas->i2c, reg, *data);
- else
- return i2c_smbus_write_i2c_block_data(tas->i2c, reg, len, data);
-}
-
-static void tas3004_set_drc(struct tas *tas)
-{
- unsigned char val[6];
-
- if (tas->drc_enabled)
- val[0] = 0x50; /* 3:1 above threshold */
- else
- val[0] = 0x51; /* disabled */
- val[1] = 0x02; /* 1:1 below threshold */
- if (tas->drc_range > 0xef)
- val[2] = 0xef;
- else if (tas->drc_range < 0)
- val[2] = 0x00;
- else
- val[2] = tas->drc_range;
- val[3] = 0xb0;
- val[4] = 0x60;
- val[5] = 0xa0;
-
- tas_write_reg(tas, TAS_REG_DRC, 6, val);
-}
-
-static void tas_set_treble(struct tas *tas)
-{
- u8 tmp;
-
- tmp = tas3004_treble(tas->treble);
- tas_write_reg(tas, TAS_REG_TREBLE, 1, &tmp);
-}
-
-static void tas_set_bass(struct tas *tas)
-{
- u8 tmp;
-
- tmp = tas3004_bass(tas->bass);
- tas_write_reg(tas, TAS_REG_BASS, 1, &tmp);
-}
-
-static void tas_set_volume(struct tas *tas)
-{
- u8 block[6];
- int tmp;
- u8 left, right;
-
- left = tas->cached_volume_l;
- right = tas->cached_volume_r;
-
- if (left > 177) left = 177;
- if (right > 177) right = 177;
-
- if (tas->mute_l) left = 0;
- if (tas->mute_r) right = 0;
-
- /* analysing the volume and mixer tables shows
- * that they are similar enough when we shift
- * the mixer table down by 4 bits. The error
- * is miniscule, in just one item the error
- * is 1, at a value of 0x07f17b (mixer table
- * value is 0x07f17a) */
- tmp = tas_gaintable[left];
- block[0] = tmp>>20;
- block[1] = tmp>>12;
- block[2] = tmp>>4;
- tmp = tas_gaintable[right];
- block[3] = tmp>>20;
- block[4] = tmp>>12;
- block[5] = tmp>>4;
- tas_write_reg(tas, TAS_REG_VOL, 6, block);
-}
-
-static void tas_set_mixer(struct tas *tas)
-{
- u8 block[9];
- int tmp, i;
- u8 val;
-
- for (i=0;i<3;i++) {
- val = tas->mixer_l[i];
- if (val > 177) val = 177;
- tmp = tas_gaintable[val];
- block[3*i+0] = tmp>>16;
- block[3*i+1] = tmp>>8;
- block[3*i+2] = tmp;
- }
- tas_write_reg(tas, TAS_REG_LMIX, 9, block);
-
- for (i=0;i<3;i++) {
- val = tas->mixer_r[i];
- if (val > 177) val = 177;
- tmp = tas_gaintable[val];
- block[3*i+0] = tmp>>16;
- block[3*i+1] = tmp>>8;
- block[3*i+2] = tmp;
- }
- tas_write_reg(tas, TAS_REG_RMIX, 9, block);
-}
-
-/* alsa stuff */
-
-static int tas_dev_register(struct snd_device *dev)
-{
- return 0;
-}
-
-static struct snd_device_ops ops = {
- .dev_register = tas_dev_register,
-};
-
-static int tas_snd_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 177;
- return 0;
-}
-
-static int tas_snd_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tas *tas = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&tas->mtx);
- ucontrol->value.integer.value[0] = tas->cached_volume_l;
- ucontrol->value.integer.value[1] = tas->cached_volume_r;
- mutex_unlock(&tas->mtx);
- return 0;
-}
-
-static int tas_snd_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tas *tas = snd_kcontrol_chip(kcontrol);
-
- if (ucontrol->value.integer.value[0] < 0 ||
- ucontrol->value.integer.value[0] > 177)
- return -EINVAL;
- if (ucontrol->value.integer.value[1] < 0 ||
- ucontrol->value.integer.value[1] > 177)
- return -EINVAL;
-
- mutex_lock(&tas->mtx);
- if (tas->cached_volume_l == ucontrol->value.integer.value[0]
- && tas->cached_volume_r == ucontrol->value.integer.value[1]) {
- mutex_unlock(&tas->mtx);
- return 0;
- }
-
- tas->cached_volume_l = ucontrol->value.integer.value[0];
- tas->cached_volume_r = ucontrol->value.integer.value[1];
- if (tas->hw_enabled)
- tas_set_volume(tas);
- mutex_unlock(&tas->mtx);
- return 1;
-}
-
-static struct snd_kcontrol_new volume_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = tas_snd_vol_info,
- .get = tas_snd_vol_get,
- .put = tas_snd_vol_put,
-};
-
-#define tas_snd_mute_info snd_ctl_boolean_stereo_info
-
-static int tas_snd_mute_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tas *tas = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&tas->mtx);
- ucontrol->value.integer.value[0] = !tas->mute_l;
- ucontrol->value.integer.value[1] = !tas->mute_r;
- mutex_unlock(&tas->mtx);
- return 0;
-}
-
-static int tas_snd_mute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tas *tas = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&tas->mtx);
- if (tas->mute_l == !ucontrol->value.integer.value[0]
- && tas->mute_r == !ucontrol->value.integer.value[1]) {
- mutex_unlock(&tas->mtx);
- return 0;
- }
-
- tas->mute_l = !ucontrol->value.integer.value[0];
- tas->mute_r = !ucontrol->value.integer.value[1];
- if (tas->hw_enabled)
- tas_set_volume(tas);
- mutex_unlock(&tas->mtx);
- return 1;
-}
-
-static struct snd_kcontrol_new mute_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = tas_snd_mute_info,
- .get = tas_snd_mute_get,
- .put = tas_snd_mute_put,
-};
-
-static int tas_snd_mixer_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 177;
- return 0;
-}
-
-static int tas_snd_mixer_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tas *tas = snd_kcontrol_chip(kcontrol);
- int idx = kcontrol->private_value;
-
- mutex_lock(&tas->mtx);
- ucontrol->value.integer.value[0] = tas->mixer_l[idx];
- ucontrol->value.integer.value[1] = tas->mixer_r[idx];
- mutex_unlock(&tas->mtx);
-
- return 0;
-}
-
-static int tas_snd_mixer_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tas *tas = snd_kcontrol_chip(kcontrol);
- int idx = kcontrol->private_value;
-
- mutex_lock(&tas->mtx);
- if (tas->mixer_l[idx] == ucontrol->value.integer.value[0]
- && tas->mixer_r[idx] == ucontrol->value.integer.value[1]) {
- mutex_unlock(&tas->mtx);
- return 0;
- }
-
- tas->mixer_l[idx] = ucontrol->value.integer.value[0];
- tas->mixer_r[idx] = ucontrol->value.integer.value[1];
-
- if (tas->hw_enabled)
- tas_set_mixer(tas);
- mutex_unlock(&tas->mtx);
- return 1;
-}
-
-#define MIXER_CONTROL(n,descr,idx) \
-static struct snd_kcontrol_new n##_control = { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = descr " Playback Volume", \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
- .info = tas_snd_mixer_info, \
- .get = tas_snd_mixer_get, \
- .put = tas_snd_mixer_put, \
- .private_value = idx, \
-}
-
-MIXER_CONTROL(pcm1, "PCM", 0);
-MIXER_CONTROL(monitor, "Monitor", 2);
-
-static int tas_snd_drc_range_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = TAS3004_DRC_MAX;
- return 0;
-}
-
-static int tas_snd_drc_range_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tas *tas = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&tas->mtx);
- ucontrol->value.integer.value[0] = tas->drc_range;
- mutex_unlock(&tas->mtx);
- return 0;
-}
-
-static int tas_snd_drc_range_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tas *tas = snd_kcontrol_chip(kcontrol);
-
- if (ucontrol->value.integer.value[0] < 0 ||
- ucontrol->value.integer.value[0] > TAS3004_DRC_MAX)
- return -EINVAL;
-
- mutex_lock(&tas->mtx);
- if (tas->drc_range == ucontrol->value.integer.value[0]) {
- mutex_unlock(&tas->mtx);
- return 0;
- }
-
- tas->drc_range = ucontrol->value.integer.value[0];
- if (tas->hw_enabled)
- tas3004_set_drc(tas);
- mutex_unlock(&tas->mtx);
- return 1;
-}
-
-static struct snd_kcontrol_new drc_range_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "DRC Range",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = tas_snd_drc_range_info,
- .get = tas_snd_drc_range_get,
- .put = tas_snd_drc_range_put,
-};
-
-#define tas_snd_drc_switch_info snd_ctl_boolean_mono_info
-
-static int tas_snd_drc_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tas *tas = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&tas->mtx);
- ucontrol->value.integer.value[0] = tas->drc_enabled;
- mutex_unlock(&tas->mtx);
- return 0;
-}
-
-static int tas_snd_drc_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tas *tas = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&tas->mtx);
- if (tas->drc_enabled == ucontrol->value.integer.value[0]) {
- mutex_unlock(&tas->mtx);
- return 0;
- }
-
- tas->drc_enabled = !!ucontrol->value.integer.value[0];
- if (tas->hw_enabled)
- tas3004_set_drc(tas);
- mutex_unlock(&tas->mtx);
- return 1;
-}
-
-static struct snd_kcontrol_new drc_switch_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "DRC Range Switch",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = tas_snd_drc_switch_info,
- .get = tas_snd_drc_switch_get,
- .put = tas_snd_drc_switch_put,
-};
-
-static int tas_snd_capture_source_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = { "Line-In", "Microphone" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item > 1)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int tas_snd_capture_source_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tas *tas = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&tas->mtx);
- ucontrol->value.enumerated.item[0] = !!(tas->acr & TAS_ACR_INPUT_B);
- mutex_unlock(&tas->mtx);
- return 0;
-}
-
-static int tas_snd_capture_source_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tas *tas = snd_kcontrol_chip(kcontrol);
- int oldacr;
-
- if (ucontrol->value.enumerated.item[0] > 1)
- return -EINVAL;
- mutex_lock(&tas->mtx);
- oldacr = tas->acr;
-
- /*
- * Despite what the data sheet says in one place, the
- * TAS_ACR_B_MONAUREAL bit forces mono output even when
- * input A (line in) is selected.
- */
- tas->acr &= ~(TAS_ACR_INPUT_B | TAS_ACR_B_MONAUREAL);
- if (ucontrol->value.enumerated.item[0])
- tas->acr |= TAS_ACR_INPUT_B | TAS_ACR_B_MONAUREAL |
- TAS_ACR_B_MON_SEL_RIGHT;
- if (oldacr == tas->acr) {
- mutex_unlock(&tas->mtx);
- return 0;
- }
- if (tas->hw_enabled)
- tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr);
- mutex_unlock(&tas->mtx);
- return 1;
-}
-
-static struct snd_kcontrol_new capture_source_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- /* If we name this 'Input Source', it properly shows up in
- * alsamixer as a selection, * but it's shown under the
- * 'Playback' category.
- * If I name it 'Capture Source', it shows up in strange
- * ways (two bools of which one can be selected at a
- * time) but at least it's shown in the 'Capture'
- * category.
- * I was told that this was due to backward compatibility,
- * but I don't understand then why the mangling is *not*
- * done when I name it "Input Source".....
- */
- .name = "Capture Source",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = tas_snd_capture_source_info,
- .get = tas_snd_capture_source_get,
- .put = tas_snd_capture_source_put,
-};
-
-static int tas_snd_treble_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = TAS3004_TREBLE_MIN;
- uinfo->value.integer.max = TAS3004_TREBLE_MAX;
- return 0;
-}
-
-static int tas_snd_treble_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tas *tas = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&tas->mtx);
- ucontrol->value.integer.value[0] = tas->treble;
- mutex_unlock(&tas->mtx);
- return 0;
-}
-
-static int tas_snd_treble_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tas *tas = snd_kcontrol_chip(kcontrol);
-
- if (ucontrol->value.integer.value[0] < TAS3004_TREBLE_MIN ||
- ucontrol->value.integer.value[0] > TAS3004_TREBLE_MAX)
- return -EINVAL;
- mutex_lock(&tas->mtx);
- if (tas->treble == ucontrol->value.integer.value[0]) {
- mutex_unlock(&tas->mtx);
- return 0;
- }
-
- tas->treble = ucontrol->value.integer.value[0];
- if (tas->hw_enabled)
- tas_set_treble(tas);
- mutex_unlock(&tas->mtx);
- return 1;
-}
-
-static struct snd_kcontrol_new treble_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Treble",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = tas_snd_treble_info,
- .get = tas_snd_treble_get,
- .put = tas_snd_treble_put,
-};
-
-static int tas_snd_bass_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = TAS3004_BASS_MIN;
- uinfo->value.integer.max = TAS3004_BASS_MAX;
- return 0;
-}
-
-static int tas_snd_bass_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tas *tas = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&tas->mtx);
- ucontrol->value.integer.value[0] = tas->bass;
- mutex_unlock(&tas->mtx);
- return 0;
-}
-
-static int tas_snd_bass_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tas *tas = snd_kcontrol_chip(kcontrol);
-
- if (ucontrol->value.integer.value[0] < TAS3004_BASS_MIN ||
- ucontrol->value.integer.value[0] > TAS3004_BASS_MAX)
- return -EINVAL;
- mutex_lock(&tas->mtx);
- if (tas->bass == ucontrol->value.integer.value[0]) {
- mutex_unlock(&tas->mtx);
- return 0;
- }
-
- tas->bass = ucontrol->value.integer.value[0];
- if (tas->hw_enabled)
- tas_set_bass(tas);
- mutex_unlock(&tas->mtx);
- return 1;
-}
-
-static struct snd_kcontrol_new bass_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Bass",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = tas_snd_bass_info,
- .get = tas_snd_bass_get,
- .put = tas_snd_bass_put,
-};
-
-static struct transfer_info tas_transfers[] = {
- {
- /* input */
- .formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S24_BE,
- .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
- .transfer_in = 1,
- },
- {
- /* output */
- .formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S24_BE,
- .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
- .transfer_in = 0,
- },
- {}
-};
-
-static int tas_usable(struct codec_info_item *cii,
- struct transfer_info *ti,
- struct transfer_info *out)
-{
- return 1;
-}
-
-static int tas_reset_init(struct tas *tas)
-{
- u8 tmp;
-
- tas->codec.gpio->methods->all_amps_off(tas->codec.gpio);
- msleep(5);
- tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 0);
- msleep(5);
- tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 1);
- msleep(20);
- tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 0);
- msleep(10);
- tas->codec.gpio->methods->all_amps_restore(tas->codec.gpio);
-
- tmp = TAS_MCS_SCLK64 | TAS_MCS_SPORT_MODE_I2S | TAS_MCS_SPORT_WL_24BIT;
- if (tas_write_reg(tas, TAS_REG_MCS, 1, &tmp))
- goto outerr;
-
- tas->acr |= TAS_ACR_ANALOG_PDOWN;
- if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr))
- goto outerr;
-
- tmp = 0;
- if (tas_write_reg(tas, TAS_REG_MCS2, 1, &tmp))
- goto outerr;
-
- tas3004_set_drc(tas);
-
- /* Set treble & bass to 0dB */
- tas->treble = TAS3004_TREBLE_ZERO;
- tas->bass = TAS3004_BASS_ZERO;
- tas_set_treble(tas);
- tas_set_bass(tas);
-
- tas->acr &= ~TAS_ACR_ANALOG_PDOWN;
- if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr))
- goto outerr;
-
- return 0;
- outerr:
- return -ENODEV;
-}
-
-static int tas_switch_clock(struct codec_info_item *cii, enum clock_switch clock)
-{
- struct tas *tas = cii->codec_data;
-
- switch(clock) {
- case CLOCK_SWITCH_PREPARE_SLAVE:
- /* Clocks are going away, mute mute mute */
- tas->codec.gpio->methods->all_amps_off(tas->codec.gpio);
- tas->hw_enabled = 0;
- break;
- case CLOCK_SWITCH_SLAVE:
- /* Clocks are back, re-init the codec */
- mutex_lock(&tas->mtx);
- tas_reset_init(tas);
- tas_set_volume(tas);
- tas_set_mixer(tas);
- tas->hw_enabled = 1;
- tas->codec.gpio->methods->all_amps_restore(tas->codec.gpio);
- mutex_unlock(&tas->mtx);
- break;
- default:
- /* doesn't happen as of now */
- return -EINVAL;
- }
- return 0;
-}
-
-#ifdef CONFIG_PM
-/* we are controlled via i2c and assume that is always up
- * If that wasn't the case, we'd have to suspend once
- * our i2c device is suspended, and then take note of that! */
-static int tas_suspend(struct tas *tas)
-{
- mutex_lock(&tas->mtx);
- tas->hw_enabled = 0;
- tas->acr |= TAS_ACR_ANALOG_PDOWN;
- tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr);
- mutex_unlock(&tas->mtx);
- return 0;
-}
-
-static int tas_resume(struct tas *tas)
-{
- /* reset codec */
- mutex_lock(&tas->mtx);
- tas_reset_init(tas);
- tas_set_volume(tas);
- tas_set_mixer(tas);
- tas->hw_enabled = 1;
- mutex_unlock(&tas->mtx);
- return 0;
-}
-
-static int _tas_suspend(struct codec_info_item *cii, pm_message_t state)
-{
- return tas_suspend(cii->codec_data);
-}
-
-static int _tas_resume(struct codec_info_item *cii)
-{
- return tas_resume(cii->codec_data);
-}
-#else /* CONFIG_PM */
-#define _tas_suspend NULL
-#define _tas_resume NULL
-#endif /* CONFIG_PM */
-
-static struct codec_info tas_codec_info = {
- .transfers = tas_transfers,
- /* in theory, we can drive it at 512 too...
- * but so far the framework doesn't allow
- * for that and I don't see much point in it. */
- .sysclock_factor = 256,
- /* same here, could be 32 for just one 16 bit format */
- .bus_factor = 64,
- .owner = THIS_MODULE,
- .usable = tas_usable,
- .switch_clock = tas_switch_clock,
- .suspend = _tas_suspend,
- .resume = _tas_resume,
-};
-
-static int tas_init_codec(struct aoa_codec *codec)
-{
- struct tas *tas = codec_to_tas(codec);
- int err;
-
- if (!tas->codec.gpio || !tas->codec.gpio->methods) {
- printk(KERN_ERR PFX "gpios not assigned!!\n");
- return -EINVAL;
- }
-
- mutex_lock(&tas->mtx);
- if (tas_reset_init(tas)) {
- printk(KERN_ERR PFX "tas failed to initialise\n");
- mutex_unlock(&tas->mtx);
- return -ENXIO;
- }
- tas->hw_enabled = 1;
- mutex_unlock(&tas->mtx);
-
- if (tas->codec.soundbus_dev->attach_codec(tas->codec.soundbus_dev,
- aoa_get_card(),
- &tas_codec_info, tas)) {
- printk(KERN_ERR PFX "error attaching tas to soundbus\n");
- return -ENODEV;
- }
-
- if (aoa_snd_device_new(SNDRV_DEV_LOWLEVEL, tas, &ops)) {
- printk(KERN_ERR PFX "failed to create tas snd device!\n");
- return -ENODEV;
- }
- err = aoa_snd_ctl_add(snd_ctl_new1(&volume_control, tas));
- if (err)
- goto error;
-
- err = aoa_snd_ctl_add(snd_ctl_new1(&mute_control, tas));
- if (err)
- goto error;
-
- err = aoa_snd_ctl_add(snd_ctl_new1(&pcm1_control, tas));
- if (err)
- goto error;
-
- err = aoa_snd_ctl_add(snd_ctl_new1(&monitor_control, tas));
- if (err)
- goto error;
-
- err = aoa_snd_ctl_add(snd_ctl_new1(&capture_source_control, tas));
- if (err)
- goto error;
-
- err = aoa_snd_ctl_add(snd_ctl_new1(&drc_range_control, tas));
- if (err)
- goto error;
-
- err = aoa_snd_ctl_add(snd_ctl_new1(&drc_switch_control, tas));
- if (err)
- goto error;
-
- err = aoa_snd_ctl_add(snd_ctl_new1(&treble_control, tas));
- if (err)
- goto error;
-
- err = aoa_snd_ctl_add(snd_ctl_new1(&bass_control, tas));
- if (err)
- goto error;
-
- return 0;
- error:
- tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas);
- snd_device_free(aoa_get_card(), tas);
- return err;
-}
-
-static void tas_exit_codec(struct aoa_codec *codec)
-{
- struct tas *tas = codec_to_tas(codec);
-
- if (!tas->codec.soundbus_dev)
- return;
- tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas);
-}
-
-
-static int tas_create(struct i2c_adapter *adapter,
- struct device_node *node,
- int addr)
-{
- struct i2c_board_info info;
- struct i2c_client *client;
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- strlcpy(info.type, "aoa_codec_tas", I2C_NAME_SIZE);
- info.addr = addr;
- info.platform_data = node;
-
- client = i2c_new_device(adapter, &info);
- if (!client)
- return -ENODEV;
- /*
- * We know the driver is already loaded, so the device should be
- * already bound. If not it means binding failed, and then there
- * is no point in keeping the device instantiated.
- */
- if (!client->driver) {
- i2c_unregister_device(client);
- return -ENODEV;
- }
-
- /*
- * Let i2c-core delete that device on driver removal.
- * This is safe because i2c-core holds the core_lock mutex for us.
- */
- list_add_tail(&client->detected, &client->driver->clients);
- return 0;
-}
-
-static int tas_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct device_node *node = client->dev.platform_data;
- struct tas *tas;
-
- tas = kzalloc(sizeof(struct tas), GFP_KERNEL);
-
- if (!tas)
- return -ENOMEM;
-
- mutex_init(&tas->mtx);
- tas->i2c = client;
- i2c_set_clientdata(client, tas);
-
- /* seems that half is a saner default */
- tas->drc_range = TAS3004_DRC_MAX / 2;
-
- strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN);
- tas->codec.owner = THIS_MODULE;
- tas->codec.init = tas_init_codec;
- tas->codec.exit = tas_exit_codec;
- tas->codec.node = of_node_get(node);
-
- if (aoa_codec_register(&tas->codec)) {
- goto fail;
- }
- printk(KERN_DEBUG
- "snd-aoa-codec-tas: tas found, addr 0x%02x on %s\n",
- (unsigned int)client->addr, node->full_name);
- return 0;
- fail:
- mutex_destroy(&tas->mtx);
- kfree(tas);
- return -EINVAL;
-}
-
-static int tas_i2c_attach(struct i2c_adapter *adapter)
-{
- struct device_node *busnode, *dev = NULL;
- struct pmac_i2c_bus *bus;
-
- bus = pmac_i2c_adapter_to_bus(adapter);
- if (bus == NULL)
- return -ENODEV;
- busnode = pmac_i2c_get_bus_node(bus);
-
- while ((dev = of_get_next_child(busnode, dev)) != NULL) {
- if (of_device_is_compatible(dev, "tas3004")) {
- const u32 *addr;
- printk(KERN_DEBUG PFX "found tas3004\n");
- addr = of_get_property(dev, "reg", NULL);
- if (!addr)
- continue;
- return tas_create(adapter, dev, ((*addr) >> 1) & 0x7f);
- }
- /* older machines have no 'codec' node with a 'compatible'
- * property that says 'tas3004', they just have a 'deq'
- * node without any such property... */
- if (strcmp(dev->name, "deq") == 0) {
- const u32 *_addr;
- u32 addr;
- printk(KERN_DEBUG PFX "found 'deq' node\n");
- _addr = of_get_property(dev, "i2c-address", NULL);
- if (!_addr)
- continue;
- addr = ((*_addr) >> 1) & 0x7f;
- /* now, if the address doesn't match any of the two
- * that a tas3004 can have, we cannot handle this.
- * I doubt it ever happens but hey. */
- if (addr != 0x34 && addr != 0x35)
- continue;
- return tas_create(adapter, dev, addr);
- }
- }
- return -ENODEV;
-}
-
-static int tas_i2c_remove(struct i2c_client *client)
-{
- struct tas *tas = i2c_get_clientdata(client);
- u8 tmp = TAS_ACR_ANALOG_PDOWN;
-
- aoa_codec_unregister(&tas->codec);
- of_node_put(tas->codec.node);
-
- /* power down codec chip */
- tas_write_reg(tas, TAS_REG_ACR, 1, &tmp);
-
- mutex_destroy(&tas->mtx);
- kfree(tas);
- return 0;
-}
-
-static const struct i2c_device_id tas_i2c_id[] = {
- { "aoa_codec_tas", 0 },
- { }
-};
-
-static struct i2c_driver tas_driver = {
- .driver = {
- .name = "aoa_codec_tas",
- .owner = THIS_MODULE,
- },
- .attach_adapter = tas_i2c_attach,
- .probe = tas_i2c_probe,
- .remove = tas_i2c_remove,
- .id_table = tas_i2c_id,
-};
-
-module_i2c_driver(tas_driver);
diff --git a/ANDROID_3.4.5/sound/aoa/codecs/tas.h b/ANDROID_3.4.5/sound/aoa/codecs/tas.h
deleted file mode 100644
index ae177e34..00000000
--- a/ANDROID_3.4.5/sound/aoa/codecs/tas.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Apple Onboard Audio driver for tas codec (header)
- *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- */
-#ifndef __SND_AOA_CODECTASH
-#define __SND_AOA_CODECTASH
-
-#define TAS_REG_MCS 0x01 /* main control */
-# define TAS_MCS_FASTLOAD (1<<7)
-# define TAS_MCS_SCLK64 (1<<6)
-# define TAS_MCS_SPORT_MODE_MASK (3<<4)
-# define TAS_MCS_SPORT_MODE_I2S (2<<4)
-# define TAS_MCS_SPORT_MODE_RJ (1<<4)
-# define TAS_MCS_SPORT_MODE_LJ (0<<4)
-# define TAS_MCS_SPORT_WL_MASK (3<<0)
-# define TAS_MCS_SPORT_WL_16BIT (0<<0)
-# define TAS_MCS_SPORT_WL_18BIT (1<<0)
-# define TAS_MCS_SPORT_WL_20BIT (2<<0)
-# define TAS_MCS_SPORT_WL_24BIT (3<<0)
-
-#define TAS_REG_DRC 0x02
-#define TAS_REG_VOL 0x04
-#define TAS_REG_TREBLE 0x05
-#define TAS_REG_BASS 0x06
-#define TAS_REG_LMIX 0x07
-#define TAS_REG_RMIX 0x08
-
-#define TAS_REG_ACR 0x40 /* analog control */
-# define TAS_ACR_B_MONAUREAL (1<<7)
-# define TAS_ACR_B_MON_SEL_RIGHT (1<<6)
-# define TAS_ACR_DEEMPH_MASK (3<<2)
-# define TAS_ACR_DEEMPH_OFF (0<<2)
-# define TAS_ACR_DEEMPH_48KHz (1<<2)
-# define TAS_ACR_DEEMPH_44KHz (2<<2)
-# define TAS_ACR_INPUT_B (1<<1)
-# define TAS_ACR_ANALOG_PDOWN (1<<0)
-
-#define TAS_REG_MCS2 0x43 /* main control 2 */
-# define TAS_MCS2_ALLPASS (1<<1)
-
-#define TAS_REG_LEFT_BIQUAD6 0x10
-#define TAS_REG_RIGHT_BIQUAD6 0x19
-
-#define TAS_REG_LEFT_LOUDNESS 0x21
-#define TAS_REG_RIGHT_LOUDNESS 0x22
-#define TAS_REG_LEFT_LOUDNESS_GAIN 0x23
-#define TAS_REG_RIGHT_LOUDNESS_GAIN 0x24
-
-#define TAS3001_DRC_MAX 0x5f
-#define TAS3004_DRC_MAX 0xef
-
-#endif /* __SND_AOA_CODECTASH */
diff --git a/ANDROID_3.4.5/sound/aoa/codecs/toonie.c b/ANDROID_3.4.5/sound/aoa/codecs/toonie.c
deleted file mode 100644
index 69d2cb60..00000000
--- a/ANDROID_3.4.5/sound/aoa/codecs/toonie.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Apple Onboard Audio driver for Toonie codec
- *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- *
- *
- * This is a driver for the toonie codec chip. This chip is present
- * on the Mac Mini and is nothing but a DAC.
- */
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("toonie codec driver for snd-aoa");
-
-#include "../aoa.h"
-#include "../soundbus/soundbus.h"
-
-
-#define PFX "snd-aoa-codec-toonie: "
-
-struct toonie {
- struct aoa_codec codec;
-};
-#define codec_to_toonie(c) container_of(c, struct toonie, codec)
-
-static int toonie_dev_register(struct snd_device *dev)
-{
- return 0;
-}
-
-static struct snd_device_ops ops = {
- .dev_register = toonie_dev_register,
-};
-
-static struct transfer_info toonie_transfers[] = {
- /* This thing *only* has analog output,
- * the rates are taken from Info.plist
- * from Darwin. */
- {
- .formats = SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_S24_BE,
- .rates = SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000,
- },
- {}
-};
-
-static int toonie_usable(struct codec_info_item *cii,
- struct transfer_info *ti,
- struct transfer_info *out)
-{
- return 1;
-}
-
-#ifdef CONFIG_PM
-static int toonie_suspend(struct codec_info_item *cii, pm_message_t state)
-{
- /* can we turn it off somehow? */
- return 0;
-}
-
-static int toonie_resume(struct codec_info_item *cii)
-{
- return 0;
-}
-#endif /* CONFIG_PM */
-
-static struct codec_info toonie_codec_info = {
- .transfers = toonie_transfers,
- .sysclock_factor = 256,
- .bus_factor = 64,
- .owner = THIS_MODULE,
- .usable = toonie_usable,
-#ifdef CONFIG_PM
- .suspend = toonie_suspend,
- .resume = toonie_resume,
-#endif
-};
-
-static int toonie_init_codec(struct aoa_codec *codec)
-{
- struct toonie *toonie = codec_to_toonie(codec);
-
- /* nothing connected? what a joke! */
- if (toonie->codec.connected != 1)
- return -ENOTCONN;
-
- if (aoa_snd_device_new(SNDRV_DEV_LOWLEVEL, toonie, &ops)) {
- printk(KERN_ERR PFX "failed to create toonie snd device!\n");
- return -ENODEV;
- }
-
- if (toonie->codec.soundbus_dev->attach_codec(toonie->codec.soundbus_dev,
- aoa_get_card(),
- &toonie_codec_info, toonie)) {
- printk(KERN_ERR PFX "error creating toonie pcm\n");
- snd_device_free(aoa_get_card(), toonie);
- return -ENODEV;
- }
-
- return 0;
-}
-
-static void toonie_exit_codec(struct aoa_codec *codec)
-{
- struct toonie *toonie = codec_to_toonie(codec);
-
- if (!toonie->codec.soundbus_dev) {
- printk(KERN_ERR PFX "toonie_exit_codec called without soundbus_dev!\n");
- return;
- }
- toonie->codec.soundbus_dev->detach_codec(toonie->codec.soundbus_dev, toonie);
-}
-
-static struct toonie *toonie;
-
-static int __init toonie_init(void)
-{
- toonie = kzalloc(sizeof(struct toonie), GFP_KERNEL);
-
- if (!toonie)
- return -ENOMEM;
-
- strlcpy(toonie->codec.name, "toonie", sizeof(toonie->codec.name));
- toonie->codec.owner = THIS_MODULE;
- toonie->codec.init = toonie_init_codec;
- toonie->codec.exit = toonie_exit_codec;
-
- if (aoa_codec_register(&toonie->codec)) {
- kfree(toonie);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void __exit toonie_exit(void)
-{
- aoa_codec_unregister(&toonie->codec);
- kfree(toonie);
-}
-
-module_init(toonie_init);
-module_exit(toonie_exit);
diff --git a/ANDROID_3.4.5/sound/aoa/core/Makefile b/ANDROID_3.4.5/sound/aoa/core/Makefile
deleted file mode 100644
index a1596e88..00000000
--- a/ANDROID_3.4.5/sound/aoa/core/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-obj-$(CONFIG_SND_AOA) += snd-aoa.o
-snd-aoa-objs := core.o \
- alsa.o \
- gpio-pmf.o \
- gpio-feature.o
diff --git a/ANDROID_3.4.5/sound/aoa/core/alsa.c b/ANDROID_3.4.5/sound/aoa/core/alsa.c
deleted file mode 100644
index 0fa3855b..00000000
--- a/ANDROID_3.4.5/sound/aoa/core/alsa.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Apple Onboard Audio Alsa helpers
- *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- */
-#include <linux/module.h>
-#include "alsa.h"
-
-static int index = -1;
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "index for AOA sound card.");
-
-static struct aoa_card *aoa_card;
-
-int aoa_alsa_init(char *name, struct module *mod, struct device *dev)
-{
- struct snd_card *alsa_card;
- int err;
-
- if (aoa_card)
- /* cannot be EEXIST due to usage in aoa_fabric_register */
- return -EBUSY;
-
- err = snd_card_create(index, name, mod, sizeof(struct aoa_card),
- &alsa_card);
- if (err < 0)
- return err;
- aoa_card = alsa_card->private_data;
- aoa_card->alsa_card = alsa_card;
- alsa_card->dev = dev;
- strlcpy(alsa_card->driver, "AppleOnbdAudio", sizeof(alsa_card->driver));
- strlcpy(alsa_card->shortname, name, sizeof(alsa_card->shortname));
- strlcpy(alsa_card->longname, name, sizeof(alsa_card->longname));
- strlcpy(alsa_card->mixername, name, sizeof(alsa_card->mixername));
- err = snd_card_register(aoa_card->alsa_card);
- if (err < 0) {
- printk(KERN_ERR "snd-aoa: couldn't register alsa card\n");
- snd_card_free(aoa_card->alsa_card);
- aoa_card = NULL;
- return err;
- }
- return 0;
-}
-
-struct snd_card *aoa_get_card(void)
-{
- if (aoa_card)
- return aoa_card->alsa_card;
- return NULL;
-}
-EXPORT_SYMBOL_GPL(aoa_get_card);
-
-void aoa_alsa_cleanup(void)
-{
- if (aoa_card) {
- snd_card_free(aoa_card->alsa_card);
- aoa_card = NULL;
- }
-}
-
-int aoa_snd_device_new(snd_device_type_t type,
- void * device_data, struct snd_device_ops * ops)
-{
- struct snd_card *card = aoa_get_card();
- int err;
-
- if (!card) return -ENOMEM;
-
- err = snd_device_new(card, type, device_data, ops);
- if (err) {
- printk(KERN_ERR "snd-aoa: failed to create snd device (%d)\n", err);
- return err;
- }
- err = snd_device_register(card, device_data);
- if (err) {
- printk(KERN_ERR "snd-aoa: failed to register "
- "snd device (%d)\n", err);
- printk(KERN_ERR "snd-aoa: have you forgotten the "
- "dev_register callback?\n");
- snd_device_free(card, device_data);
- }
- return err;
-}
-EXPORT_SYMBOL_GPL(aoa_snd_device_new);
-
-int aoa_snd_ctl_add(struct snd_kcontrol* control)
-{
- int err;
-
- if (!aoa_card) return -ENODEV;
-
- err = snd_ctl_add(aoa_card->alsa_card, control);
- if (err)
- printk(KERN_ERR "snd-aoa: failed to add alsa control (%d)\n",
- err);
- return err;
-}
-EXPORT_SYMBOL_GPL(aoa_snd_ctl_add);
diff --git a/ANDROID_3.4.5/sound/aoa/core/alsa.h b/ANDROID_3.4.5/sound/aoa/core/alsa.h
deleted file mode 100644
index 9669e448..00000000
--- a/ANDROID_3.4.5/sound/aoa/core/alsa.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Apple Onboard Audio Alsa private helpers
- *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- */
-
-#ifndef __SND_AOA_ALSA_H
-#define __SND_AOA_ALSA_H
-#include "../aoa.h"
-
-extern int aoa_alsa_init(char *name, struct module *mod, struct device *dev);
-extern void aoa_alsa_cleanup(void);
-
-#endif /* __SND_AOA_ALSA_H */
diff --git a/ANDROID_3.4.5/sound/aoa/core/core.c b/ANDROID_3.4.5/sound/aoa/core/core.c
deleted file mode 100644
index 10bec6c6..00000000
--- a/ANDROID_3.4.5/sound/aoa/core/core.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Apple Onboard Audio driver core
- *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/list.h>
-#include "../aoa.h"
-#include "alsa.h"
-
-MODULE_DESCRIPTION("Apple Onboard Audio Sound Driver");
-MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
-MODULE_LICENSE("GPL");
-
-/* We allow only one fabric. This simplifies things,
- * and more don't really make that much sense */
-static struct aoa_fabric *fabric;
-static LIST_HEAD(codec_list);
-
-static int attach_codec_to_fabric(struct aoa_codec *c)
-{
- int err;
-
- if (!try_module_get(c->owner))
- return -EBUSY;
- /* found_codec has to be assigned */
- err = -ENOENT;
- if (fabric->found_codec)
- err = fabric->found_codec(c);
- if (err) {
- module_put(c->owner);
- printk(KERN_ERR "snd-aoa: fabric didn't like codec %s\n",
- c->name);
- return err;
- }
- c->fabric = fabric;
-
- err = 0;
- if (c->init)
- err = c->init(c);
- if (err) {
- printk(KERN_ERR "snd-aoa: codec %s didn't init\n", c->name);
- c->fabric = NULL;
- if (fabric->remove_codec)
- fabric->remove_codec(c);
- module_put(c->owner);
- return err;
- }
- if (fabric->attached_codec)
- fabric->attached_codec(c);
- return 0;
-}
-
-int aoa_codec_register(struct aoa_codec *codec)
-{
- int err = 0;
-
- /* if there's a fabric already, we can tell if we
- * will want to have this codec, so propagate error
- * through. Otherwise, this will happen later... */
- if (fabric)
- err = attach_codec_to_fabric(codec);
- if (!err)
- list_add(&codec->list, &codec_list);
- return err;
-}
-EXPORT_SYMBOL_GPL(aoa_codec_register);
-
-void aoa_codec_unregister(struct aoa_codec *codec)
-{
- list_del(&codec->list);
- if (codec->fabric && codec->exit)
- codec->exit(codec);
- if (fabric && fabric->remove_codec)
- fabric->remove_codec(codec);
- codec->fabric = NULL;
- module_put(codec->owner);
-}
-EXPORT_SYMBOL_GPL(aoa_codec_unregister);
-
-int aoa_fabric_register(struct aoa_fabric *new_fabric, struct device *dev)
-{
- struct aoa_codec *c;
- int err;
-
- /* allow querying for presence of fabric
- * (i.e. do this test first!) */
- if (new_fabric == fabric) {
- err = -EALREADY;
- goto attach;
- }
- if (fabric)
- return -EEXIST;
- if (!new_fabric)
- return -EINVAL;
-
- err = aoa_alsa_init(new_fabric->name, new_fabric->owner, dev);
- if (err)
- return err;
-
- fabric = new_fabric;
-
- attach:
- list_for_each_entry(c, &codec_list, list) {
- if (c->fabric != fabric)
- attach_codec_to_fabric(c);
- }
- return err;
-}
-EXPORT_SYMBOL_GPL(aoa_fabric_register);
-
-void aoa_fabric_unregister(struct aoa_fabric *old_fabric)
-{
- struct aoa_codec *c;
-
- if (fabric != old_fabric)
- return;
-
- list_for_each_entry(c, &codec_list, list) {
- if (c->fabric)
- aoa_fabric_unlink_codec(c);
- }
-
- aoa_alsa_cleanup();
-
- fabric = NULL;
-}
-EXPORT_SYMBOL_GPL(aoa_fabric_unregister);
-
-void aoa_fabric_unlink_codec(struct aoa_codec *codec)
-{
- if (!codec->fabric) {
- printk(KERN_ERR "snd-aoa: fabric unassigned "
- "in aoa_fabric_unlink_codec\n");
- dump_stack();
- return;
- }
- if (codec->exit)
- codec->exit(codec);
- if (codec->fabric->remove_codec)
- codec->fabric->remove_codec(codec);
- codec->fabric = NULL;
- module_put(codec->owner);
-}
-EXPORT_SYMBOL_GPL(aoa_fabric_unlink_codec);
-
-static int __init aoa_init(void)
-{
- return 0;
-}
-
-static void __exit aoa_exit(void)
-{
- aoa_alsa_cleanup();
-}
-
-module_init(aoa_init);
-module_exit(aoa_exit);
diff --git a/ANDROID_3.4.5/sound/aoa/core/gpio-feature.c b/ANDROID_3.4.5/sound/aoa/core/gpio-feature.c
deleted file mode 100644
index faa31749..00000000
--- a/ANDROID_3.4.5/sound/aoa/core/gpio-feature.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Apple Onboard Audio feature call GPIO control
- *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- *
- * This file contains the GPIO control routines for
- * direct (through feature calls) access to the GPIO
- * registers.
- */
-
-#include <asm/pmac_feature.h>
-#include <linux/interrupt.h>
-#include "../aoa.h"
-
-/* TODO: these are lots of global variables
- * that aren't used on most machines...
- * Move them into a dynamically allocated
- * structure and use that.
- */
-
-/* these are the GPIO numbers (register addresses as offsets into
- * the GPIO space) */
-static int headphone_mute_gpio;
-static int master_mute_gpio;
-static int amp_mute_gpio;
-static int lineout_mute_gpio;
-static int hw_reset_gpio;
-static int lineout_detect_gpio;
-static int headphone_detect_gpio;
-static int linein_detect_gpio;
-
-/* see the SWITCH_GPIO macro */
-static int headphone_mute_gpio_activestate;
-static int master_mute_gpio_activestate;
-static int amp_mute_gpio_activestate;
-static int lineout_mute_gpio_activestate;
-static int hw_reset_gpio_activestate;
-static int lineout_detect_gpio_activestate;
-static int headphone_detect_gpio_activestate;
-static int linein_detect_gpio_activestate;
-
-/* node pointers that we save when getting the GPIO number
- * to get the interrupt later */
-static struct device_node *lineout_detect_node;
-static struct device_node *linein_detect_node;
-static struct device_node *headphone_detect_node;
-
-static int lineout_detect_irq;
-static int linein_detect_irq;
-static int headphone_detect_irq;
-
-static struct device_node *get_gpio(char *name,
- char *altname,
- int *gpioptr,
- int *gpioactiveptr)
-{
- struct device_node *np, *gpio;
- const u32 *reg;
- const char *audio_gpio;
-
- *gpioptr = -1;
-
- /* check if we can get it the easy way ... */
- np = of_find_node_by_name(NULL, name);
- if (!np) {
- /* some machines have only gpioX/extint-gpioX nodes,
- * and an audio-gpio property saying what it is ...
- * So what we have to do is enumerate all children
- * of the gpio node and check them all. */
- gpio = of_find_node_by_name(NULL, "gpio");
- if (!gpio)
- return NULL;
- while ((np = of_get_next_child(gpio, np))) {
- audio_gpio = of_get_property(np, "audio-gpio", NULL);
- if (!audio_gpio)
- continue;
- if (strcmp(audio_gpio, name) == 0)
- break;
- if (altname && (strcmp(audio_gpio, altname) == 0))
- break;
- }
- /* still not found, assume not there */
- if (!np)
- return NULL;
- }
-
- reg = of_get_property(np, "reg", NULL);
- if (!reg)
- return NULL;
-
- *gpioptr = *reg;
-
- /* this is a hack, usually the GPIOs 'reg' property
- * should have the offset based from the GPIO space
- * which is at 0x50, but apparently not always... */
- if (*gpioptr < 0x50)
- *gpioptr += 0x50;
-
- reg = of_get_property(np, "audio-gpio-active-state", NULL);
- if (!reg)
- /* Apple seems to default to 1, but
- * that doesn't seem right at least on most
- * machines. So until proven that the opposite
- * is necessary, we default to 0
- * (which, incidentally, snd-powermac also does...) */
- *gpioactiveptr = 0;
- else
- *gpioactiveptr = *reg;
-
- return np;
-}
-
-static void get_irq(struct device_node * np, int *irqptr)
-{
- if (np)
- *irqptr = irq_of_parse_and_map(np, 0);
- else
- *irqptr = NO_IRQ;
-}
-
-/* 0x4 is outenable, 0x1 is out, thus 4 or 5 */
-#define SWITCH_GPIO(name, v, on) \
- (((v)&~1) | ((on)? \
- (name##_gpio_activestate==0?4:5): \
- (name##_gpio_activestate==0?5:4)))
-
-#define FTR_GPIO(name, bit) \
-static void ftr_gpio_set_##name(struct gpio_runtime *rt, int on)\
-{ \
- int v; \
- \
- if (unlikely(!rt)) return; \
- \
- if (name##_mute_gpio < 0) \
- return; \
- \
- v = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, \
- name##_mute_gpio, \
- 0); \
- \
- /* muted = !on... */ \
- v = SWITCH_GPIO(name##_mute, v, !on); \
- \
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, \
- name##_mute_gpio, v); \
- \
- rt->implementation_private &= ~(1<<bit); \
- rt->implementation_private |= (!!on << bit); \
-} \
-static int ftr_gpio_get_##name(struct gpio_runtime *rt) \
-{ \
- if (unlikely(!rt)) return 0; \
- return (rt->implementation_private>>bit)&1; \
-}
-
-FTR_GPIO(headphone, 0);
-FTR_GPIO(amp, 1);
-FTR_GPIO(lineout, 2);
-FTR_GPIO(master, 3);
-
-static void ftr_gpio_set_hw_reset(struct gpio_runtime *rt, int on)
-{
- int v;
-
- if (unlikely(!rt)) return;
- if (hw_reset_gpio < 0)
- return;
-
- v = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL,
- hw_reset_gpio, 0);
- v = SWITCH_GPIO(hw_reset, v, on);
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL,
- hw_reset_gpio, v);
-}
-
-static struct gpio_methods methods;
-
-static void ftr_gpio_all_amps_off(struct gpio_runtime *rt)
-{
- int saved;
-
- if (unlikely(!rt)) return;
- saved = rt->implementation_private;
- ftr_gpio_set_headphone(rt, 0);
- ftr_gpio_set_amp(rt, 0);
- ftr_gpio_set_lineout(rt, 0);
- if (methods.set_master)
- ftr_gpio_set_master(rt, 0);
- rt->implementation_private = saved;
-}
-
-static void ftr_gpio_all_amps_restore(struct gpio_runtime *rt)
-{
- int s;
-
- if (unlikely(!rt)) return;
- s = rt->implementation_private;
- ftr_gpio_set_headphone(rt, (s>>0)&1);
- ftr_gpio_set_amp(rt, (s>>1)&1);
- ftr_gpio_set_lineout(rt, (s>>2)&1);
- if (methods.set_master)
- ftr_gpio_set_master(rt, (s>>3)&1);
-}
-
-static void ftr_handle_notify(struct work_struct *work)
-{
- struct gpio_notification *notif =
- container_of(work, struct gpio_notification, work.work);
-
- mutex_lock(&notif->mutex);
- if (notif->notify)
- notif->notify(notif->data);
- mutex_unlock(&notif->mutex);
-}
-
-static void gpio_enable_dual_edge(int gpio)
-{
- int v;
-
- if (gpio == -1)
- return;
- v = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio, 0);
- v |= 0x80; /* enable dual edge */
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gpio, v);
-}
-
-static void ftr_gpio_init(struct gpio_runtime *rt)
-{
- get_gpio("headphone-mute", NULL,
- &headphone_mute_gpio,
- &headphone_mute_gpio_activestate);
- get_gpio("amp-mute", NULL,
- &amp_mute_gpio,
- &amp_mute_gpio_activestate);
- get_gpio("lineout-mute", NULL,
- &lineout_mute_gpio,
- &lineout_mute_gpio_activestate);
- get_gpio("hw-reset", "audio-hw-reset",
- &hw_reset_gpio,
- &hw_reset_gpio_activestate);
- if (get_gpio("master-mute", NULL,
- &master_mute_gpio,
- &master_mute_gpio_activestate)) {
- methods.set_master = ftr_gpio_set_master;
- methods.get_master = ftr_gpio_get_master;
- }
-
- headphone_detect_node = get_gpio("headphone-detect", NULL,
- &headphone_detect_gpio,
- &headphone_detect_gpio_activestate);
- /* go Apple, and thanks for giving these different names
- * across the board... */
- lineout_detect_node = get_gpio("lineout-detect", "line-output-detect",
- &lineout_detect_gpio,
- &lineout_detect_gpio_activestate);
- linein_detect_node = get_gpio("linein-detect", "line-input-detect",
- &linein_detect_gpio,
- &linein_detect_gpio_activestate);
-
- gpio_enable_dual_edge(headphone_detect_gpio);
- gpio_enable_dual_edge(lineout_detect_gpio);
- gpio_enable_dual_edge(linein_detect_gpio);
-
- get_irq(headphone_detect_node, &headphone_detect_irq);
- get_irq(lineout_detect_node, &lineout_detect_irq);
- get_irq(linein_detect_node, &linein_detect_irq);
-
- ftr_gpio_all_amps_off(rt);
- rt->implementation_private = 0;
- INIT_DELAYED_WORK(&rt->headphone_notify.work, ftr_handle_notify);
- INIT_DELAYED_WORK(&rt->line_in_notify.work, ftr_handle_notify);
- INIT_DELAYED_WORK(&rt->line_out_notify.work, ftr_handle_notify);
- mutex_init(&rt->headphone_notify.mutex);
- mutex_init(&rt->line_in_notify.mutex);
- mutex_init(&rt->line_out_notify.mutex);
-}
-
-static void ftr_gpio_exit(struct gpio_runtime *rt)
-{
- ftr_gpio_all_amps_off(rt);
- rt->implementation_private = 0;
- if (rt->headphone_notify.notify)
- free_irq(headphone_detect_irq, &rt->headphone_notify);
- if (rt->line_in_notify.gpio_private)
- free_irq(linein_detect_irq, &rt->line_in_notify);
- if (rt->line_out_notify.gpio_private)
- free_irq(lineout_detect_irq, &rt->line_out_notify);
- cancel_delayed_work_sync(&rt->headphone_notify.work);
- cancel_delayed_work_sync(&rt->line_in_notify.work);
- cancel_delayed_work_sync(&rt->line_out_notify.work);
- mutex_destroy(&rt->headphone_notify.mutex);
- mutex_destroy(&rt->line_in_notify.mutex);
- mutex_destroy(&rt->line_out_notify.mutex);
-}
-
-static irqreturn_t ftr_handle_notify_irq(int xx, void *data)
-{
- struct gpio_notification *notif = data;
-
- schedule_delayed_work(&notif->work, 0);
-
- return IRQ_HANDLED;
-}
-
-static int ftr_set_notify(struct gpio_runtime *rt,
- enum notify_type type,
- notify_func_t notify,
- void *data)
-{
- struct gpio_notification *notif;
- notify_func_t old;
- int irq;
- char *name;
- int err = -EBUSY;
-
- switch (type) {
- case AOA_NOTIFY_HEADPHONE:
- notif = &rt->headphone_notify;
- name = "headphone-detect";
- irq = headphone_detect_irq;
- break;
- case AOA_NOTIFY_LINE_IN:
- notif = &rt->line_in_notify;
- name = "linein-detect";
- irq = linein_detect_irq;
- break;
- case AOA_NOTIFY_LINE_OUT:
- notif = &rt->line_out_notify;
- name = "lineout-detect";
- irq = lineout_detect_irq;
- break;
- default:
- return -EINVAL;
- }
-
- if (irq == NO_IRQ)
- return -ENODEV;
-
- mutex_lock(&notif->mutex);
-
- old = notif->notify;
-
- if (!old && !notify) {
- err = 0;
- goto out_unlock;
- }
-
- if (old && notify) {
- if (old == notify && notif->data == data)
- err = 0;
- goto out_unlock;
- }
-
- if (old && !notify)
- free_irq(irq, notif);
-
- if (!old && notify) {
- err = request_irq(irq, ftr_handle_notify_irq, 0, name, notif);
- if (err)
- goto out_unlock;
- }
-
- notif->notify = notify;
- notif->data = data;
-
- err = 0;
- out_unlock:
- mutex_unlock(&notif->mutex);
- return err;
-}
-
-static int ftr_get_detect(struct gpio_runtime *rt,
- enum notify_type type)
-{
- int gpio, ret, active;
-
- switch (type) {
- case AOA_NOTIFY_HEADPHONE:
- gpio = headphone_detect_gpio;
- active = headphone_detect_gpio_activestate;
- break;
- case AOA_NOTIFY_LINE_IN:
- gpio = linein_detect_gpio;
- active = linein_detect_gpio_activestate;
- break;
- case AOA_NOTIFY_LINE_OUT:
- gpio = lineout_detect_gpio;
- active = lineout_detect_gpio_activestate;
- break;
- default:
- return -EINVAL;
- }
-
- if (gpio == -1)
- return -ENODEV;
-
- ret = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio, 0);
- if (ret < 0)
- return ret;
- return ((ret >> 1) & 1) == active;
-}
-
-static struct gpio_methods methods = {
- .init = ftr_gpio_init,
- .exit = ftr_gpio_exit,
- .all_amps_off = ftr_gpio_all_amps_off,
- .all_amps_restore = ftr_gpio_all_amps_restore,
- .set_headphone = ftr_gpio_set_headphone,
- .set_speakers = ftr_gpio_set_amp,
- .set_lineout = ftr_gpio_set_lineout,
- .set_hw_reset = ftr_gpio_set_hw_reset,
- .get_headphone = ftr_gpio_get_headphone,
- .get_speakers = ftr_gpio_get_amp,
- .get_lineout = ftr_gpio_get_lineout,
- .set_notify = ftr_set_notify,
- .get_detect = ftr_get_detect,
-};
-
-struct gpio_methods *ftr_gpio_methods = &methods;
-EXPORT_SYMBOL_GPL(ftr_gpio_methods);
diff --git a/ANDROID_3.4.5/sound/aoa/core/gpio-pmf.c b/ANDROID_3.4.5/sound/aoa/core/gpio-pmf.c
deleted file mode 100644
index c8d8a1a6..00000000
--- a/ANDROID_3.4.5/sound/aoa/core/gpio-pmf.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Apple Onboard Audio pmf GPIOs
- *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- */
-
-#include <linux/slab.h>
-#include <asm/pmac_feature.h>
-#include <asm/pmac_pfunc.h>
-#include "../aoa.h"
-
-#define PMF_GPIO(name, bit) \
-static void pmf_gpio_set_##name(struct gpio_runtime *rt, int on)\
-{ \
- struct pmf_args args = { .count = 1, .u[0].v = !on }; \
- int rc; \
- \
- if (unlikely(!rt)) return; \
- rc = pmf_call_function(rt->node, #name "-mute", &args); \
- if (rc && rc != -ENODEV) \
- printk(KERN_WARNING "pmf_gpio_set_" #name \
- " failed, rc: %d\n", rc); \
- rt->implementation_private &= ~(1<<bit); \
- rt->implementation_private |= (!!on << bit); \
-} \
-static int pmf_gpio_get_##name(struct gpio_runtime *rt) \
-{ \
- if (unlikely(!rt)) return 0; \
- return (rt->implementation_private>>bit)&1; \
-}
-
-PMF_GPIO(headphone, 0);
-PMF_GPIO(amp, 1);
-PMF_GPIO(lineout, 2);
-
-static void pmf_gpio_set_hw_reset(struct gpio_runtime *rt, int on)
-{
- struct pmf_args args = { .count = 1, .u[0].v = !!on };
- int rc;
-
- if (unlikely(!rt)) return;
- rc = pmf_call_function(rt->node, "hw-reset", &args);
- if (rc)
- printk(KERN_WARNING "pmf_gpio_set_hw_reset"
- " failed, rc: %d\n", rc);
-}
-
-static void pmf_gpio_all_amps_off(struct gpio_runtime *rt)
-{
- int saved;
-
- if (unlikely(!rt)) return;
- saved = rt->implementation_private;
- pmf_gpio_set_headphone(rt, 0);
- pmf_gpio_set_amp(rt, 0);
- pmf_gpio_set_lineout(rt, 0);
- rt->implementation_private = saved;
-}
-
-static void pmf_gpio_all_amps_restore(struct gpio_runtime *rt)
-{
- int s;
-
- if (unlikely(!rt)) return;
- s = rt->implementation_private;
- pmf_gpio_set_headphone(rt, (s>>0)&1);
- pmf_gpio_set_amp(rt, (s>>1)&1);
- pmf_gpio_set_lineout(rt, (s>>2)&1);
-}
-
-static void pmf_handle_notify(struct work_struct *work)
-{
- struct gpio_notification *notif =
- container_of(work, struct gpio_notification, work.work);
-
- mutex_lock(&notif->mutex);
- if (notif->notify)
- notif->notify(notif->data);
- mutex_unlock(&notif->mutex);
-}
-
-static void pmf_gpio_init(struct gpio_runtime *rt)
-{
- pmf_gpio_all_amps_off(rt);
- rt->implementation_private = 0;
- INIT_DELAYED_WORK(&rt->headphone_notify.work, pmf_handle_notify);
- INIT_DELAYED_WORK(&rt->line_in_notify.work, pmf_handle_notify);
- INIT_DELAYED_WORK(&rt->line_out_notify.work, pmf_handle_notify);
- mutex_init(&rt->headphone_notify.mutex);
- mutex_init(&rt->line_in_notify.mutex);
- mutex_init(&rt->line_out_notify.mutex);
-}
-
-static void pmf_gpio_exit(struct gpio_runtime *rt)
-{
- pmf_gpio_all_amps_off(rt);
- rt->implementation_private = 0;
-
- if (rt->headphone_notify.gpio_private)
- pmf_unregister_irq_client(rt->headphone_notify.gpio_private);
- if (rt->line_in_notify.gpio_private)
- pmf_unregister_irq_client(rt->line_in_notify.gpio_private);
- if (rt->line_out_notify.gpio_private)
- pmf_unregister_irq_client(rt->line_out_notify.gpio_private);
-
- /* make sure no work is pending before freeing
- * all things */
- cancel_delayed_work_sync(&rt->headphone_notify.work);
- cancel_delayed_work_sync(&rt->line_in_notify.work);
- cancel_delayed_work_sync(&rt->line_out_notify.work);
-
- mutex_destroy(&rt->headphone_notify.mutex);
- mutex_destroy(&rt->line_in_notify.mutex);
- mutex_destroy(&rt->line_out_notify.mutex);
-
- kfree(rt->headphone_notify.gpio_private);
- kfree(rt->line_in_notify.gpio_private);
- kfree(rt->line_out_notify.gpio_private);
-}
-
-static void pmf_handle_notify_irq(void *data)
-{
- struct gpio_notification *notif = data;
-
- schedule_delayed_work(&notif->work, 0);
-}
-
-static int pmf_set_notify(struct gpio_runtime *rt,
- enum notify_type type,
- notify_func_t notify,
- void *data)
-{
- struct gpio_notification *notif;
- notify_func_t old;
- struct pmf_irq_client *irq_client;
- char *name;
- int err = -EBUSY;
-
- switch (type) {
- case AOA_NOTIFY_HEADPHONE:
- notif = &rt->headphone_notify;
- name = "headphone-detect";
- break;
- case AOA_NOTIFY_LINE_IN:
- notif = &rt->line_in_notify;
- name = "linein-detect";
- break;
- case AOA_NOTIFY_LINE_OUT:
- notif = &rt->line_out_notify;
- name = "lineout-detect";
- break;
- default:
- return -EINVAL;
- }
-
- mutex_lock(&notif->mutex);
-
- old = notif->notify;
-
- if (!old && !notify) {
- err = 0;
- goto out_unlock;
- }
-
- if (old && notify) {
- if (old == notify && notif->data == data)
- err = 0;
- goto out_unlock;
- }
-
- if (old && !notify) {
- irq_client = notif->gpio_private;
- pmf_unregister_irq_client(irq_client);
- kfree(irq_client);
- notif->gpio_private = NULL;
- }
- if (!old && notify) {
- irq_client = kzalloc(sizeof(struct pmf_irq_client),
- GFP_KERNEL);
- if (!irq_client) {
- err = -ENOMEM;
- goto out_unlock;
- }
- irq_client->data = notif;
- irq_client->handler = pmf_handle_notify_irq;
- irq_client->owner = THIS_MODULE;
- err = pmf_register_irq_client(rt->node,
- name,
- irq_client);
- if (err) {
- printk(KERN_ERR "snd-aoa: gpio layer failed to"
- " register %s irq (%d)\n", name, err);
- kfree(irq_client);
- goto out_unlock;
- }
- notif->gpio_private = irq_client;
- }
- notif->notify = notify;
- notif->data = data;
-
- err = 0;
- out_unlock:
- mutex_unlock(&notif->mutex);
- return err;
-}
-
-static int pmf_get_detect(struct gpio_runtime *rt,
- enum notify_type type)
-{
- char *name;
- int err = -EBUSY, ret;
- struct pmf_args args = { .count = 1, .u[0].p = &ret };
-
- switch (type) {
- case AOA_NOTIFY_HEADPHONE:
- name = "headphone-detect";
- break;
- case AOA_NOTIFY_LINE_IN:
- name = "linein-detect";
- break;
- case AOA_NOTIFY_LINE_OUT:
- name = "lineout-detect";
- break;
- default:
- return -EINVAL;
- }
-
- err = pmf_call_function(rt->node, name, &args);
- if (err)
- return err;
- return ret;
-}
-
-static struct gpio_methods methods = {
- .init = pmf_gpio_init,
- .exit = pmf_gpio_exit,
- .all_amps_off = pmf_gpio_all_amps_off,
- .all_amps_restore = pmf_gpio_all_amps_restore,
- .set_headphone = pmf_gpio_set_headphone,
- .set_speakers = pmf_gpio_set_amp,
- .set_lineout = pmf_gpio_set_lineout,
- .set_hw_reset = pmf_gpio_set_hw_reset,
- .get_headphone = pmf_gpio_get_headphone,
- .get_speakers = pmf_gpio_get_amp,
- .get_lineout = pmf_gpio_get_lineout,
- .set_notify = pmf_set_notify,
- .get_detect = pmf_get_detect,
-};
-
-struct gpio_methods *pmf_gpio_methods = &methods;
-EXPORT_SYMBOL_GPL(pmf_gpio_methods);
diff --git a/ANDROID_3.4.5/sound/aoa/fabrics/Kconfig b/ANDROID_3.4.5/sound/aoa/fabrics/Kconfig
deleted file mode 100644
index 3ca475a8..00000000
--- a/ANDROID_3.4.5/sound/aoa/fabrics/Kconfig
+++ /dev/null
@@ -1,11 +0,0 @@
-config SND_AOA_FABRIC_LAYOUT
- tristate "layout-id fabric"
- select SND_AOA_SOUNDBUS
- select SND_AOA_SOUNDBUS_I2S
- ---help---
- This enables the layout-id fabric for the Apple Onboard
- Audio driver, the module holding it all together
- based on the device-tree's layout-id property.
-
- If you are unsure and have a later Apple machine,
- compile it as a module.
diff --git a/ANDROID_3.4.5/sound/aoa/fabrics/Makefile b/ANDROID_3.4.5/sound/aoa/fabrics/Makefile
deleted file mode 100644
index da37c10e..00000000
--- a/ANDROID_3.4.5/sound/aoa/fabrics/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-snd-aoa-fabric-layout-objs += layout.o
-
-obj-$(CONFIG_SND_AOA_FABRIC_LAYOUT) += snd-aoa-fabric-layout.o
diff --git a/ANDROID_3.4.5/sound/aoa/fabrics/layout.c b/ANDROID_3.4.5/sound/aoa/fabrics/layout.c
deleted file mode 100644
index 552b97af..00000000
--- a/ANDROID_3.4.5/sound/aoa/fabrics/layout.c
+++ /dev/null
@@ -1,1168 +0,0 @@
-/*
- * Apple Onboard Audio driver -- layout/machine id fabric
- *
- * Copyright 2006-2008 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- *
- *
- * This fabric module looks for sound codecs based on the
- * layout-id or device-id property in the device tree.
- */
-#include <asm/prom.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include "../aoa.h"
-#include "../soundbus/soundbus.h"
-
-MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Layout-ID fabric for snd-aoa");
-
-#define MAX_CODECS_PER_BUS 2
-
-/* These are the connections the layout fabric
- * knows about. It doesn't really care about the
- * input ones, but I thought I'd separate them
- * to give them proper names. The thing is that
- * Apple usually will distinguish the active output
- * by GPIOs, while the active input is set directly
- * on the codec. Hence we here tell the codec what
- * we think is connected. This information is hard-
- * coded below ... */
-#define CC_SPEAKERS (1<<0)
-#define CC_HEADPHONE (1<<1)
-#define CC_LINEOUT (1<<2)
-#define CC_DIGITALOUT (1<<3)
-#define CC_LINEIN (1<<4)
-#define CC_MICROPHONE (1<<5)
-#define CC_DIGITALIN (1<<6)
-/* pretty bogus but users complain...
- * This is a flag saying that the LINEOUT
- * should be renamed to HEADPHONE.
- * be careful with input detection! */
-#define CC_LINEOUT_LABELLED_HEADPHONE (1<<7)
-
-struct codec_connection {
- /* CC_ flags from above */
- int connected;
- /* codec dependent bit to be set in the aoa_codec.connected field.
- * This intentionally doesn't have any generic flags because the
- * fabric has to know the codec anyway and all codecs might have
- * different connectors */
- int codec_bit;
-};
-
-struct codec_connect_info {
- char *name;
- struct codec_connection *connections;
-};
-
-#define LAYOUT_FLAG_COMBO_LINEOUT_SPDIF (1<<0)
-
-struct layout {
- unsigned int layout_id, device_id;
- struct codec_connect_info codecs[MAX_CODECS_PER_BUS];
- int flags;
-
- /* if busname is not assigned, we use 'Master' below,
- * so that our layout table doesn't need to be filled
- * too much.
- * We only assign these two if we expect to find more
- * than one soundbus, i.e. on those machines with
- * multiple layout-ids */
- char *busname;
- int pcmid;
-};
-
-MODULE_ALIAS("sound-layout-36");
-MODULE_ALIAS("sound-layout-41");
-MODULE_ALIAS("sound-layout-45");
-MODULE_ALIAS("sound-layout-47");
-MODULE_ALIAS("sound-layout-48");
-MODULE_ALIAS("sound-layout-49");
-MODULE_ALIAS("sound-layout-50");
-MODULE_ALIAS("sound-layout-51");
-MODULE_ALIAS("sound-layout-56");
-MODULE_ALIAS("sound-layout-57");
-MODULE_ALIAS("sound-layout-58");
-MODULE_ALIAS("sound-layout-60");
-MODULE_ALIAS("sound-layout-61");
-MODULE_ALIAS("sound-layout-62");
-MODULE_ALIAS("sound-layout-64");
-MODULE_ALIAS("sound-layout-65");
-MODULE_ALIAS("sound-layout-66");
-MODULE_ALIAS("sound-layout-67");
-MODULE_ALIAS("sound-layout-68");
-MODULE_ALIAS("sound-layout-69");
-MODULE_ALIAS("sound-layout-70");
-MODULE_ALIAS("sound-layout-72");
-MODULE_ALIAS("sound-layout-76");
-MODULE_ALIAS("sound-layout-80");
-MODULE_ALIAS("sound-layout-82");
-MODULE_ALIAS("sound-layout-84");
-MODULE_ALIAS("sound-layout-86");
-MODULE_ALIAS("sound-layout-90");
-MODULE_ALIAS("sound-layout-92");
-MODULE_ALIAS("sound-layout-94");
-MODULE_ALIAS("sound-layout-96");
-MODULE_ALIAS("sound-layout-98");
-MODULE_ALIAS("sound-layout-100");
-
-MODULE_ALIAS("aoa-device-id-14");
-MODULE_ALIAS("aoa-device-id-22");
-MODULE_ALIAS("aoa-device-id-35");
-
-/* onyx with all but microphone connected */
-static struct codec_connection onyx_connections_nomic[] = {
- {
- .connected = CC_SPEAKERS | CC_HEADPHONE | CC_LINEOUT,
- .codec_bit = 0,
- },
- {
- .connected = CC_DIGITALOUT,
- .codec_bit = 1,
- },
- {
- .connected = CC_LINEIN,
- .codec_bit = 2,
- },
- {} /* terminate array by .connected == 0 */
-};
-
-/* onyx on machines without headphone */
-static struct codec_connection onyx_connections_noheadphones[] = {
- {
- .connected = CC_SPEAKERS | CC_LINEOUT |
- CC_LINEOUT_LABELLED_HEADPHONE,
- .codec_bit = 0,
- },
- {
- .connected = CC_DIGITALOUT,
- .codec_bit = 1,
- },
- /* FIXME: are these correct? probably not for all the machines
- * below ... If not this will need separating. */
- {
- .connected = CC_LINEIN,
- .codec_bit = 2,
- },
- {
- .connected = CC_MICROPHONE,
- .codec_bit = 3,
- },
- {} /* terminate array by .connected == 0 */
-};
-
-/* onyx on machines with real line-out */
-static struct codec_connection onyx_connections_reallineout[] = {
- {
- .connected = CC_SPEAKERS | CC_LINEOUT | CC_HEADPHONE,
- .codec_bit = 0,
- },
- {
- .connected = CC_DIGITALOUT,
- .codec_bit = 1,
- },
- {
- .connected = CC_LINEIN,
- .codec_bit = 2,
- },
- {} /* terminate array by .connected == 0 */
-};
-
-/* tas on machines without line out */
-static struct codec_connection tas_connections_nolineout[] = {
- {
- .connected = CC_SPEAKERS | CC_HEADPHONE,
- .codec_bit = 0,
- },
- {
- .connected = CC_LINEIN,
- .codec_bit = 2,
- },
- {
- .connected = CC_MICROPHONE,
- .codec_bit = 3,
- },
- {} /* terminate array by .connected == 0 */
-};
-
-/* tas on machines with neither line out nor line in */
-static struct codec_connection tas_connections_noline[] = {
- {
- .connected = CC_SPEAKERS | CC_HEADPHONE,
- .codec_bit = 0,
- },
- {
- .connected = CC_MICROPHONE,
- .codec_bit = 3,
- },
- {} /* terminate array by .connected == 0 */
-};
-
-/* tas on machines without microphone */
-static struct codec_connection tas_connections_nomic[] = {
- {
- .connected = CC_SPEAKERS | CC_HEADPHONE | CC_LINEOUT,
- .codec_bit = 0,
- },
- {
- .connected = CC_LINEIN,
- .codec_bit = 2,
- },
- {} /* terminate array by .connected == 0 */
-};
-
-/* tas on machines with everything connected */
-static struct codec_connection tas_connections_all[] = {
- {
- .connected = CC_SPEAKERS | CC_HEADPHONE | CC_LINEOUT,
- .codec_bit = 0,
- },
- {
- .connected = CC_LINEIN,
- .codec_bit = 2,
- },
- {
- .connected = CC_MICROPHONE,
- .codec_bit = 3,
- },
- {} /* terminate array by .connected == 0 */
-};
-
-static struct codec_connection toonie_connections[] = {
- {
- .connected = CC_SPEAKERS | CC_HEADPHONE,
- .codec_bit = 0,
- },
- {} /* terminate array by .connected == 0 */
-};
-
-static struct codec_connection topaz_input[] = {
- {
- .connected = CC_DIGITALIN,
- .codec_bit = 0,
- },
- {} /* terminate array by .connected == 0 */
-};
-
-static struct codec_connection topaz_output[] = {
- {
- .connected = CC_DIGITALOUT,
- .codec_bit = 1,
- },
- {} /* terminate array by .connected == 0 */
-};
-
-static struct codec_connection topaz_inout[] = {
- {
- .connected = CC_DIGITALIN,
- .codec_bit = 0,
- },
- {
- .connected = CC_DIGITALOUT,
- .codec_bit = 1,
- },
- {} /* terminate array by .connected == 0 */
-};
-
-static struct layout layouts[] = {
- /* last PowerBooks (15" Oct 2005) */
- { .layout_id = 82,
- .flags = LAYOUT_FLAG_COMBO_LINEOUT_SPDIF,
- .codecs[0] = {
- .name = "onyx",
- .connections = onyx_connections_noheadphones,
- },
- .codecs[1] = {
- .name = "topaz",
- .connections = topaz_input,
- },
- },
- /* PowerMac9,1 */
- { .layout_id = 60,
- .codecs[0] = {
- .name = "onyx",
- .connections = onyx_connections_reallineout,
- },
- },
- /* PowerMac9,1 */
- { .layout_id = 61,
- .codecs[0] = {
- .name = "topaz",
- .connections = topaz_input,
- },
- },
- /* PowerBook5,7 */
- { .layout_id = 64,
- .flags = LAYOUT_FLAG_COMBO_LINEOUT_SPDIF,
- .codecs[0] = {
- .name = "onyx",
- .connections = onyx_connections_noheadphones,
- },
- },
- /* PowerBook5,7 */
- { .layout_id = 65,
- .codecs[0] = {
- .name = "topaz",
- .connections = topaz_input,
- },
- },
- /* PowerBook5,9 [17" Oct 2005] */
- { .layout_id = 84,
- .flags = LAYOUT_FLAG_COMBO_LINEOUT_SPDIF,
- .codecs[0] = {
- .name = "onyx",
- .connections = onyx_connections_noheadphones,
- },
- .codecs[1] = {
- .name = "topaz",
- .connections = topaz_input,
- },
- },
- /* PowerMac8,1 */
- { .layout_id = 45,
- .codecs[0] = {
- .name = "onyx",
- .connections = onyx_connections_noheadphones,
- },
- .codecs[1] = {
- .name = "topaz",
- .connections = topaz_input,
- },
- },
- /* Quad PowerMac (analog in, analog/digital out) */
- { .layout_id = 68,
- .codecs[0] = {
- .name = "onyx",
- .connections = onyx_connections_nomic,
- },
- },
- /* Quad PowerMac (digital in) */
- { .layout_id = 69,
- .codecs[0] = {
- .name = "topaz",
- .connections = topaz_input,
- },
- .busname = "digital in", .pcmid = 1 },
- /* Early 2005 PowerBook (PowerBook 5,6) */
- { .layout_id = 70,
- .codecs[0] = {
- .name = "tas",
- .connections = tas_connections_nolineout,
- },
- },
- /* PowerBook 5,4 */
- { .layout_id = 51,
- .codecs[0] = {
- .name = "tas",
- .connections = tas_connections_nolineout,
- },
- },
- /* PowerBook6,7 */
- { .layout_id = 80,
- .codecs[0] = {
- .name = "tas",
- .connections = tas_connections_noline,
- },
- },
- /* PowerBook6,8 */
- { .layout_id = 72,
- .codecs[0] = {
- .name = "tas",
- .connections = tas_connections_nolineout,
- },
- },
- /* PowerMac8,2 */
- { .layout_id = 86,
- .codecs[0] = {
- .name = "onyx",
- .connections = onyx_connections_nomic,
- },
- .codecs[1] = {
- .name = "topaz",
- .connections = topaz_input,
- },
- },
- /* PowerBook6,7 */
- { .layout_id = 92,
- .codecs[0] = {
- .name = "tas",
- .connections = tas_connections_nolineout,
- },
- },
- /* PowerMac10,1 (Mac Mini) */
- { .layout_id = 58,
- .codecs[0] = {
- .name = "toonie",
- .connections = toonie_connections,
- },
- },
- {
- .layout_id = 96,
- .codecs[0] = {
- .name = "onyx",
- .connections = onyx_connections_noheadphones,
- },
- },
- /* unknown, untested, but this comes from Apple */
- { .layout_id = 41,
- .codecs[0] = {
- .name = "tas",
- .connections = tas_connections_all,
- },
- },
- { .layout_id = 36,
- .codecs[0] = {
- .name = "tas",
- .connections = tas_connections_nomic,
- },
- .codecs[1] = {
- .name = "topaz",
- .connections = topaz_inout,
- },
- },
- { .layout_id = 47,
- .codecs[0] = {
- .name = "onyx",
- .connections = onyx_connections_noheadphones,
- },
- },
- { .layout_id = 48,
- .codecs[0] = {
- .name = "topaz",
- .connections = topaz_input,
- },
- },
- { .layout_id = 49,
- .codecs[0] = {
- .name = "onyx",
- .connections = onyx_connections_nomic,
- },
- },
- { .layout_id = 50,
- .codecs[0] = {
- .name = "topaz",
- .connections = topaz_input,
- },
- },
- { .layout_id = 56,
- .codecs[0] = {
- .name = "onyx",
- .connections = onyx_connections_noheadphones,
- },
- },
- { .layout_id = 57,
- .codecs[0] = {
- .name = "topaz",
- .connections = topaz_input,
- },
- },
- { .layout_id = 62,
- .codecs[0] = {
- .name = "onyx",
- .connections = onyx_connections_noheadphones,
- },
- .codecs[1] = {
- .name = "topaz",
- .connections = topaz_output,
- },
- },
- { .layout_id = 66,
- .codecs[0] = {
- .name = "onyx",
- .connections = onyx_connections_noheadphones,
- },
- },
- { .layout_id = 67,
- .codecs[0] = {
- .name = "topaz",
- .connections = topaz_input,
- },
- },
- { .layout_id = 76,
- .codecs[0] = {
- .name = "tas",
- .connections = tas_connections_nomic,
- },
- .codecs[1] = {
- .name = "topaz",
- .connections = topaz_inout,
- },
- },
- { .layout_id = 90,
- .codecs[0] = {
- .name = "tas",
- .connections = tas_connections_noline,
- },
- },
- { .layout_id = 94,
- .codecs[0] = {
- .name = "onyx",
- /* but it has an external mic?? how to select? */
- .connections = onyx_connections_noheadphones,
- },
- },
- { .layout_id = 98,
- .codecs[0] = {
- .name = "toonie",
- .connections = toonie_connections,
- },
- },
- { .layout_id = 100,
- .codecs[0] = {
- .name = "topaz",
- .connections = topaz_input,
- },
- .codecs[1] = {
- .name = "onyx",
- .connections = onyx_connections_noheadphones,
- },
- },
- /* PowerMac3,4 */
- { .device_id = 14,
- .codecs[0] = {
- .name = "tas",
- .connections = tas_connections_noline,
- },
- },
- /* PowerMac3,6 */
- { .device_id = 22,
- .codecs[0] = {
- .name = "tas",
- .connections = tas_connections_all,
- },
- },
- /* PowerBook5,2 */
- { .device_id = 35,
- .codecs[0] = {
- .name = "tas",
- .connections = tas_connections_all,
- },
- },
- {}
-};
-
-static struct layout *find_layout_by_id(unsigned int id)
-{
- struct layout *l;
-
- l = layouts;
- while (l->codecs[0].name) {
- if (l->layout_id == id)
- return l;
- l++;
- }
- return NULL;
-}
-
-static struct layout *find_layout_by_device(unsigned int id)
-{
- struct layout *l;
-
- l = layouts;
- while (l->codecs[0].name) {
- if (l->device_id == id)
- return l;
- l++;
- }
- return NULL;
-}
-
-static void use_layout(struct layout *l)
-{
- int i;
-
- for (i=0; i<MAX_CODECS_PER_BUS; i++) {
- if (l->codecs[i].name) {
- request_module("snd-aoa-codec-%s", l->codecs[i].name);
- }
- }
- /* now we wait for the codecs to call us back */
-}
-
-struct layout_dev;
-
-struct layout_dev_ptr {
- struct layout_dev *ptr;
-};
-
-struct layout_dev {
- struct list_head list;
- struct soundbus_dev *sdev;
- struct device_node *sound;
- struct aoa_codec *codecs[MAX_CODECS_PER_BUS];
- struct layout *layout;
- struct gpio_runtime gpio;
-
- /* we need these for headphone/lineout detection */
- struct snd_kcontrol *headphone_ctrl;
- struct snd_kcontrol *lineout_ctrl;
- struct snd_kcontrol *speaker_ctrl;
- struct snd_kcontrol *master_ctrl;
- struct snd_kcontrol *headphone_detected_ctrl;
- struct snd_kcontrol *lineout_detected_ctrl;
-
- struct layout_dev_ptr selfptr_headphone;
- struct layout_dev_ptr selfptr_lineout;
-
- u32 have_lineout_detect:1,
- have_headphone_detect:1,
- switch_on_headphone:1,
- switch_on_lineout:1;
-};
-
-static LIST_HEAD(layouts_list);
-static int layouts_list_items;
-/* this can go away but only if we allow multiple cards,
- * make the fabric handle all the card stuff, etc... */
-static struct layout_dev *layout_device;
-
-#define control_info snd_ctl_boolean_mono_info
-
-#define AMP_CONTROL(n, description) \
-static int n##_control_get(struct snd_kcontrol *kcontrol, \
- struct snd_ctl_elem_value *ucontrol) \
-{ \
- struct gpio_runtime *gpio = snd_kcontrol_chip(kcontrol); \
- if (gpio->methods && gpio->methods->get_##n) \
- ucontrol->value.integer.value[0] = \
- gpio->methods->get_##n(gpio); \
- return 0; \
-} \
-static int n##_control_put(struct snd_kcontrol *kcontrol, \
- struct snd_ctl_elem_value *ucontrol) \
-{ \
- struct gpio_runtime *gpio = snd_kcontrol_chip(kcontrol); \
- if (gpio->methods && gpio->methods->get_##n) \
- gpio->methods->set_##n(gpio, \
- !!ucontrol->value.integer.value[0]); \
- return 1; \
-} \
-static struct snd_kcontrol_new n##_ctl = { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = description, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
- .info = control_info, \
- .get = n##_control_get, \
- .put = n##_control_put, \
-}
-
-AMP_CONTROL(headphone, "Headphone Switch");
-AMP_CONTROL(speakers, "Speakers Switch");
-AMP_CONTROL(lineout, "Line-Out Switch");
-AMP_CONTROL(master, "Master Switch");
-
-static int detect_choice_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct layout_dev *ldev = snd_kcontrol_chip(kcontrol);
-
- switch (kcontrol->private_value) {
- case 0:
- ucontrol->value.integer.value[0] = ldev->switch_on_headphone;
- break;
- case 1:
- ucontrol->value.integer.value[0] = ldev->switch_on_lineout;
- break;
- default:
- return -ENODEV;
- }
- return 0;
-}
-
-static int detect_choice_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct layout_dev *ldev = snd_kcontrol_chip(kcontrol);
-
- switch (kcontrol->private_value) {
- case 0:
- ldev->switch_on_headphone = !!ucontrol->value.integer.value[0];
- break;
- case 1:
- ldev->switch_on_lineout = !!ucontrol->value.integer.value[0];
- break;
- default:
- return -ENODEV;
- }
- return 1;
-}
-
-static struct snd_kcontrol_new headphone_detect_choice = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Headphone Detect Autoswitch",
- .info = control_info,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .get = detect_choice_get,
- .put = detect_choice_put,
- .private_value = 0,
-};
-
-static struct snd_kcontrol_new lineout_detect_choice = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Line-Out Detect Autoswitch",
- .info = control_info,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .get = detect_choice_get,
- .put = detect_choice_put,
- .private_value = 1,
-};
-
-static int detected_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct layout_dev *ldev = snd_kcontrol_chip(kcontrol);
- int v;
-
- switch (kcontrol->private_value) {
- case 0:
- v = ldev->gpio.methods->get_detect(&ldev->gpio,
- AOA_NOTIFY_HEADPHONE);
- break;
- case 1:
- v = ldev->gpio.methods->get_detect(&ldev->gpio,
- AOA_NOTIFY_LINE_OUT);
- break;
- default:
- return -ENODEV;
- }
- ucontrol->value.integer.value[0] = v;
- return 0;
-}
-
-static struct snd_kcontrol_new headphone_detected = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Headphone Detected",
- .info = control_info,
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .get = detected_get,
- .private_value = 0,
-};
-
-static struct snd_kcontrol_new lineout_detected = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Line-Out Detected",
- .info = control_info,
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .get = detected_get,
- .private_value = 1,
-};
-
-static int check_codec(struct aoa_codec *codec,
- struct layout_dev *ldev,
- struct codec_connect_info *cci)
-{
- const u32 *ref;
- char propname[32];
- struct codec_connection *cc;
-
- /* if the codec has a 'codec' node, we require a reference */
- if (codec->node && (strcmp(codec->node->name, "codec") == 0)) {
- snprintf(propname, sizeof(propname),
- "platform-%s-codec-ref", codec->name);
- ref = of_get_property(ldev->sound, propname, NULL);
- if (!ref) {
- printk(KERN_INFO "snd-aoa-fabric-layout: "
- "required property %s not present\n", propname);
- return -ENODEV;
- }
- if (*ref != codec->node->phandle) {
- printk(KERN_INFO "snd-aoa-fabric-layout: "
- "%s doesn't match!\n", propname);
- return -ENODEV;
- }
- } else {
- if (layouts_list_items != 1) {
- printk(KERN_INFO "snd-aoa-fabric-layout: "
- "more than one soundbus, but no references.\n");
- return -ENODEV;
- }
- }
- codec->soundbus_dev = ldev->sdev;
- codec->gpio = &ldev->gpio;
-
- cc = cci->connections;
- if (!cc)
- return -EINVAL;
-
- printk(KERN_INFO "snd-aoa-fabric-layout: can use this codec\n");
-
- codec->connected = 0;
- codec->fabric_data = cc;
-
- while (cc->connected) {
- codec->connected |= 1<<cc->codec_bit;
- cc++;
- }
-
- return 0;
-}
-
-static int layout_found_codec(struct aoa_codec *codec)
-{
- struct layout_dev *ldev;
- int i;
-
- list_for_each_entry(ldev, &layouts_list, list) {
- for (i=0; i<MAX_CODECS_PER_BUS; i++) {
- if (!ldev->layout->codecs[i].name)
- continue;
- if (strcmp(ldev->layout->codecs[i].name, codec->name) == 0) {
- if (check_codec(codec,
- ldev,
- &ldev->layout->codecs[i]) == 0)
- return 0;
- }
- }
- }
- return -ENODEV;
-}
-
-static void layout_remove_codec(struct aoa_codec *codec)
-{
- int i;
- /* here remove the codec from the layout dev's
- * codec reference */
-
- codec->soundbus_dev = NULL;
- codec->gpio = NULL;
- for (i=0; i<MAX_CODECS_PER_BUS; i++) {
- }
-}
-
-static void layout_notify(void *data)
-{
- struct layout_dev_ptr *dptr = data;
- struct layout_dev *ldev;
- int v, update;
- struct snd_kcontrol *detected, *c;
- struct snd_card *card = aoa_get_card();
-
- ldev = dptr->ptr;
- if (data == &ldev->selfptr_headphone) {
- v = ldev->gpio.methods->get_detect(&ldev->gpio, AOA_NOTIFY_HEADPHONE);
- detected = ldev->headphone_detected_ctrl;
- update = ldev->switch_on_headphone;
- if (update) {
- ldev->gpio.methods->set_speakers(&ldev->gpio, !v);
- ldev->gpio.methods->set_headphone(&ldev->gpio, v);
- ldev->gpio.methods->set_lineout(&ldev->gpio, 0);
- }
- } else if (data == &ldev->selfptr_lineout) {
- v = ldev->gpio.methods->get_detect(&ldev->gpio, AOA_NOTIFY_LINE_OUT);
- detected = ldev->lineout_detected_ctrl;
- update = ldev->switch_on_lineout;
- if (update) {
- ldev->gpio.methods->set_speakers(&ldev->gpio, !v);
- ldev->gpio.methods->set_headphone(&ldev->gpio, 0);
- ldev->gpio.methods->set_lineout(&ldev->gpio, v);
- }
- } else
- return;
-
- if (detected)
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &detected->id);
- if (update) {
- c = ldev->headphone_ctrl;
- if (c)
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &c->id);
- c = ldev->speaker_ctrl;
- if (c)
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &c->id);
- c = ldev->lineout_ctrl;
- if (c)
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &c->id);
- }
-}
-
-static void layout_attached_codec(struct aoa_codec *codec)
-{
- struct codec_connection *cc;
- struct snd_kcontrol *ctl;
- int headphones, lineout;
- struct layout_dev *ldev = layout_device;
-
- /* need to add this codec to our codec array! */
-
- cc = codec->fabric_data;
-
- headphones = codec->gpio->methods->get_detect(codec->gpio,
- AOA_NOTIFY_HEADPHONE);
- lineout = codec->gpio->methods->get_detect(codec->gpio,
- AOA_NOTIFY_LINE_OUT);
-
- if (codec->gpio->methods->set_master) {
- ctl = snd_ctl_new1(&master_ctl, codec->gpio);
- ldev->master_ctrl = ctl;
- aoa_snd_ctl_add(ctl);
- }
- while (cc->connected) {
- if (cc->connected & CC_SPEAKERS) {
- if (headphones <= 0 && lineout <= 0)
- ldev->gpio.methods->set_speakers(codec->gpio, 1);
- ctl = snd_ctl_new1(&speakers_ctl, codec->gpio);
- ldev->speaker_ctrl = ctl;
- aoa_snd_ctl_add(ctl);
- }
- if (cc->connected & CC_HEADPHONE) {
- if (headphones == 1)
- ldev->gpio.methods->set_headphone(codec->gpio, 1);
- ctl = snd_ctl_new1(&headphone_ctl, codec->gpio);
- ldev->headphone_ctrl = ctl;
- aoa_snd_ctl_add(ctl);
- ldev->have_headphone_detect =
- !ldev->gpio.methods
- ->set_notify(&ldev->gpio,
- AOA_NOTIFY_HEADPHONE,
- layout_notify,
- &ldev->selfptr_headphone);
- if (ldev->have_headphone_detect) {
- ctl = snd_ctl_new1(&headphone_detect_choice,
- ldev);
- aoa_snd_ctl_add(ctl);
- ctl = snd_ctl_new1(&headphone_detected,
- ldev);
- ldev->headphone_detected_ctrl = ctl;
- aoa_snd_ctl_add(ctl);
- }
- }
- if (cc->connected & CC_LINEOUT) {
- if (lineout == 1)
- ldev->gpio.methods->set_lineout(codec->gpio, 1);
- ctl = snd_ctl_new1(&lineout_ctl, codec->gpio);
- if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
- strlcpy(ctl->id.name,
- "Headphone Switch", sizeof(ctl->id.name));
- ldev->lineout_ctrl = ctl;
- aoa_snd_ctl_add(ctl);
- ldev->have_lineout_detect =
- !ldev->gpio.methods
- ->set_notify(&ldev->gpio,
- AOA_NOTIFY_LINE_OUT,
- layout_notify,
- &ldev->selfptr_lineout);
- if (ldev->have_lineout_detect) {
- ctl = snd_ctl_new1(&lineout_detect_choice,
- ldev);
- if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
- strlcpy(ctl->id.name,
- "Headphone Detect Autoswitch",
- sizeof(ctl->id.name));
- aoa_snd_ctl_add(ctl);
- ctl = snd_ctl_new1(&lineout_detected,
- ldev);
- if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
- strlcpy(ctl->id.name,
- "Headphone Detected",
- sizeof(ctl->id.name));
- ldev->lineout_detected_ctrl = ctl;
- aoa_snd_ctl_add(ctl);
- }
- }
- cc++;
- }
- /* now update initial state */
- if (ldev->have_headphone_detect)
- layout_notify(&ldev->selfptr_headphone);
- if (ldev->have_lineout_detect)
- layout_notify(&ldev->selfptr_lineout);
-}
-
-static struct aoa_fabric layout_fabric = {
- .name = "SoundByLayout",
- .owner = THIS_MODULE,
- .found_codec = layout_found_codec,
- .remove_codec = layout_remove_codec,
- .attached_codec = layout_attached_codec,
-};
-
-static int aoa_fabric_layout_probe(struct soundbus_dev *sdev)
-{
- struct device_node *sound = NULL;
- const unsigned int *id;
- struct layout *layout = NULL;
- struct layout_dev *ldev = NULL;
- int err;
-
- /* hm, currently we can only have one ... */
- if (layout_device)
- return -ENODEV;
-
- /* by breaking out we keep a reference */
- while ((sound = of_get_next_child(sdev->ofdev.dev.of_node, sound))) {
- if (sound->type && strcasecmp(sound->type, "soundchip") == 0)
- break;
- }
- if (!sound)
- return -ENODEV;
-
- id = of_get_property(sound, "layout-id", NULL);
- if (id) {
- layout = find_layout_by_id(*id);
- } else {
- id = of_get_property(sound, "device-id", NULL);
- if (id)
- layout = find_layout_by_device(*id);
- }
-
- if (!layout) {
- printk(KERN_ERR "snd-aoa-fabric-layout: unknown layout\n");
- goto outnodev;
- }
-
- ldev = kzalloc(sizeof(struct layout_dev), GFP_KERNEL);
- if (!ldev)
- goto outnodev;
-
- layout_device = ldev;
- ldev->sdev = sdev;
- ldev->sound = sound;
- ldev->layout = layout;
- ldev->gpio.node = sound->parent;
- switch (layout->layout_id) {
- case 0: /* anything with device_id, not layout_id */
- case 41: /* that unknown machine no one seems to have */
- case 51: /* PowerBook5,4 */
- case 58: /* Mac Mini */
- ldev->gpio.methods = ftr_gpio_methods;
- printk(KERN_DEBUG
- "snd-aoa-fabric-layout: Using direct GPIOs\n");
- break;
- default:
- ldev->gpio.methods = pmf_gpio_methods;
- printk(KERN_DEBUG
- "snd-aoa-fabric-layout: Using PMF GPIOs\n");
- }
- ldev->selfptr_headphone.ptr = ldev;
- ldev->selfptr_lineout.ptr = ldev;
- dev_set_drvdata(&sdev->ofdev.dev, ldev);
- list_add(&ldev->list, &layouts_list);
- layouts_list_items++;
-
- /* assign these before registering ourselves, so
- * callbacks that are done during registration
- * already have the values */
- sdev->pcmid = ldev->layout->pcmid;
- if (ldev->layout->busname) {
- sdev->pcmname = ldev->layout->busname;
- } else {
- sdev->pcmname = "Master";
- }
-
- ldev->gpio.methods->init(&ldev->gpio);
-
- err = aoa_fabric_register(&layout_fabric, &sdev->ofdev.dev);
- if (err && err != -EALREADY) {
- printk(KERN_INFO "snd-aoa-fabric-layout: can't use,"
- " another fabric is active!\n");
- goto outlistdel;
- }
-
- use_layout(layout);
- ldev->switch_on_headphone = 1;
- ldev->switch_on_lineout = 1;
- return 0;
- outlistdel:
- /* we won't be using these then... */
- ldev->gpio.methods->exit(&ldev->gpio);
- /* reset if we didn't use it */
- sdev->pcmname = NULL;
- sdev->pcmid = -1;
- list_del(&ldev->list);
- layouts_list_items--;
- kfree(ldev);
- outnodev:
- of_node_put(sound);
- layout_device = NULL;
- return -ENODEV;
-}
-
-static int aoa_fabric_layout_remove(struct soundbus_dev *sdev)
-{
- struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev);
- int i;
-
- for (i=0; i<MAX_CODECS_PER_BUS; i++) {
- if (ldev->codecs[i]) {
- aoa_fabric_unlink_codec(ldev->codecs[i]);
- }
- ldev->codecs[i] = NULL;
- }
- list_del(&ldev->list);
- layouts_list_items--;
- of_node_put(ldev->sound);
-
- ldev->gpio.methods->set_notify(&ldev->gpio,
- AOA_NOTIFY_HEADPHONE,
- NULL,
- NULL);
- ldev->gpio.methods->set_notify(&ldev->gpio,
- AOA_NOTIFY_LINE_OUT,
- NULL,
- NULL);
-
- ldev->gpio.methods->exit(&ldev->gpio);
- layout_device = NULL;
- kfree(ldev);
- sdev->pcmid = -1;
- sdev->pcmname = NULL;
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int aoa_fabric_layout_suspend(struct soundbus_dev *sdev, pm_message_t state)
-{
- struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev);
-
- if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off)
- ldev->gpio.methods->all_amps_off(&ldev->gpio);
-
- return 0;
-}
-
-static int aoa_fabric_layout_resume(struct soundbus_dev *sdev)
-{
- struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev);
-
- if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off)
- ldev->gpio.methods->all_amps_restore(&ldev->gpio);
-
- return 0;
-}
-#endif
-
-static struct soundbus_driver aoa_soundbus_driver = {
- .name = "snd_aoa_soundbus_drv",
- .owner = THIS_MODULE,
- .probe = aoa_fabric_layout_probe,
- .remove = aoa_fabric_layout_remove,
-#ifdef CONFIG_PM
- .suspend = aoa_fabric_layout_suspend,
- .resume = aoa_fabric_layout_resume,
-#endif
- .driver = {
- .owner = THIS_MODULE,
- }
-};
-
-static int __init aoa_fabric_layout_init(void)
-{
- int err;
-
- err = soundbus_register_driver(&aoa_soundbus_driver);
- if (err)
- return err;
- return 0;
-}
-
-static void __exit aoa_fabric_layout_exit(void)
-{
- soundbus_unregister_driver(&aoa_soundbus_driver);
- aoa_fabric_unregister(&layout_fabric);
-}
-
-module_init(aoa_fabric_layout_init);
-module_exit(aoa_fabric_layout_exit);
diff --git a/ANDROID_3.4.5/sound/aoa/soundbus/Kconfig b/ANDROID_3.4.5/sound/aoa/soundbus/Kconfig
deleted file mode 100644
index 839d1137..00000000
--- a/ANDROID_3.4.5/sound/aoa/soundbus/Kconfig
+++ /dev/null
@@ -1,14 +0,0 @@
-config SND_AOA_SOUNDBUS
- tristate "Apple Soundbus support"
- select SND_PCM
- ---help---
- This option enables the generic driver for the soundbus
- support on Apple machines.
-
- It is required for the sound bus implementations.
-
-config SND_AOA_SOUNDBUS_I2S
- tristate "I2S bus support"
- depends on SND_AOA_SOUNDBUS && PCI
- ---help---
- This option enables support for Apple I2S busses.
diff --git a/ANDROID_3.4.5/sound/aoa/soundbus/Makefile b/ANDROID_3.4.5/sound/aoa/soundbus/Makefile
deleted file mode 100644
index 0e61f5aa..00000000
--- a/ANDROID_3.4.5/sound/aoa/soundbus/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_SND_AOA_SOUNDBUS) += snd-aoa-soundbus.o
-snd-aoa-soundbus-objs := core.o sysfs.o
-obj-$(CONFIG_SND_AOA_SOUNDBUS_I2S) += i2sbus/
diff --git a/ANDROID_3.4.5/sound/aoa/soundbus/core.c b/ANDROID_3.4.5/sound/aoa/soundbus/core.c
deleted file mode 100644
index 7487eb76..00000000
--- a/ANDROID_3.4.5/sound/aoa/soundbus/core.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * soundbus
- *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- */
-
-#include <linux/module.h>
-#include "soundbus.h"
-
-MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Apple Soundbus");
-
-struct soundbus_dev *soundbus_dev_get(struct soundbus_dev *dev)
-{
- struct device *tmp;
-
- if (!dev)
- return NULL;
- tmp = get_device(&dev->ofdev.dev);
- if (tmp)
- return to_soundbus_device(tmp);
- else
- return NULL;
-}
-EXPORT_SYMBOL_GPL(soundbus_dev_get);
-
-void soundbus_dev_put(struct soundbus_dev *dev)
-{
- if (dev)
- put_device(&dev->ofdev.dev);
-}
-EXPORT_SYMBOL_GPL(soundbus_dev_put);
-
-static int soundbus_probe(struct device *dev)
-{
- int error = -ENODEV;
- struct soundbus_driver *drv;
- struct soundbus_dev *soundbus_dev;
-
- drv = to_soundbus_driver(dev->driver);
- soundbus_dev = to_soundbus_device(dev);
-
- if (!drv->probe)
- return error;
-
- soundbus_dev_get(soundbus_dev);
-
- error = drv->probe(soundbus_dev);
- if (error)
- soundbus_dev_put(soundbus_dev);
-
- return error;
-}
-
-
-static int soundbus_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
- struct soundbus_dev * soundbus_dev;
- struct platform_device * of;
- const char *compat;
- int retval = 0;
- int cplen, seen = 0;
-
- if (!dev)
- return -ENODEV;
-
- soundbus_dev = to_soundbus_device(dev);
- if (!soundbus_dev)
- return -ENODEV;
-
- of = &soundbus_dev->ofdev;
-
- /* stuff we want to pass to /sbin/hotplug */
- retval = add_uevent_var(env, "OF_NAME=%s", of->dev.of_node->name);
- if (retval)
- return retval;
-
- retval = add_uevent_var(env, "OF_TYPE=%s", of->dev.of_node->type);
- if (retval)
- return retval;
-
- /* Since the compatible field can contain pretty much anything
- * it's not really legal to split it out with commas. We split it
- * up using a number of environment variables instead. */
-
- compat = of_get_property(of->dev.of_node, "compatible", &cplen);
- while (compat && cplen > 0) {
- int tmp = env->buflen;
- retval = add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat);
- if (retval)
- return retval;
- compat += env->buflen - tmp;
- cplen -= env->buflen - tmp;
- seen += 1;
- }
-
- retval = add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen);
- if (retval)
- return retval;
- retval = add_uevent_var(env, "MODALIAS=%s", soundbus_dev->modalias);
-
- return retval;
-}
-
-static int soundbus_device_remove(struct device *dev)
-{
- struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
- struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
-
- if (dev->driver && drv->remove)
- drv->remove(soundbus_dev);
- soundbus_dev_put(soundbus_dev);
-
- return 0;
-}
-
-static void soundbus_device_shutdown(struct device *dev)
-{
- struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
- struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
-
- if (dev->driver && drv->shutdown)
- drv->shutdown(soundbus_dev);
-}
-
-#ifdef CONFIG_PM
-
-static int soundbus_device_suspend(struct device *dev, pm_message_t state)
-{
- struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
- struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
-
- if (dev->driver && drv->suspend)
- return drv->suspend(soundbus_dev, state);
- return 0;
-}
-
-static int soundbus_device_resume(struct device * dev)
-{
- struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
- struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
-
- if (dev->driver && drv->resume)
- return drv->resume(soundbus_dev);
- return 0;
-}
-
-#endif /* CONFIG_PM */
-
-static struct bus_type soundbus_bus_type = {
- .name = "aoa-soundbus",
- .probe = soundbus_probe,
- .uevent = soundbus_uevent,
- .remove = soundbus_device_remove,
- .shutdown = soundbus_device_shutdown,
-#ifdef CONFIG_PM
- .suspend = soundbus_device_suspend,
- .resume = soundbus_device_resume,
-#endif
- .dev_attrs = soundbus_dev_attrs,
-};
-
-int soundbus_add_one(struct soundbus_dev *dev)
-{
- static int devcount;
-
- /* sanity checks */
- if (!dev->attach_codec ||
- !dev->ofdev.dev.of_node ||
- dev->pcmname ||
- dev->pcmid != -1) {
- printk(KERN_ERR "soundbus: adding device failed sanity check!\n");
- return -EINVAL;
- }
-
- dev_set_name(&dev->ofdev.dev, "soundbus:%x", ++devcount);
- dev->ofdev.dev.bus = &soundbus_bus_type;
- return of_device_register(&dev->ofdev);
-}
-EXPORT_SYMBOL_GPL(soundbus_add_one);
-
-void soundbus_remove_one(struct soundbus_dev *dev)
-{
- of_device_unregister(&dev->ofdev);
-}
-EXPORT_SYMBOL_GPL(soundbus_remove_one);
-
-int soundbus_register_driver(struct soundbus_driver *drv)
-{
- /* initialize common driver fields */
- drv->driver.name = drv->name;
- drv->driver.bus = &soundbus_bus_type;
-
- /* register with core */
- return driver_register(&drv->driver);
-}
-EXPORT_SYMBOL_GPL(soundbus_register_driver);
-
-void soundbus_unregister_driver(struct soundbus_driver *drv)
-{
- driver_unregister(&drv->driver);
-}
-EXPORT_SYMBOL_GPL(soundbus_unregister_driver);
-
-static int __init soundbus_init(void)
-{
- return bus_register(&soundbus_bus_type);
-}
-
-static void __exit soundbus_exit(void)
-{
- bus_unregister(&soundbus_bus_type);
-}
-
-subsys_initcall(soundbus_init);
-module_exit(soundbus_exit);
diff --git a/ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/Makefile b/ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/Makefile
deleted file mode 100644
index 1b949b2a..00000000
--- a/ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_SND_AOA_SOUNDBUS_I2S) += snd-aoa-i2sbus.o
-snd-aoa-i2sbus-objs := core.o pcm.o control.o
diff --git a/ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/control.c b/ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/control.c
deleted file mode 100644
index 4dc9b49c..00000000
--- a/ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/control.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * i2sbus driver -- bus control routines
- *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- */
-
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/macio.h>
-#include <asm/pmac_feature.h>
-#include <asm/pmac_pfunc.h>
-#include <asm/keylargo.h>
-
-#include "i2sbus.h"
-
-int i2sbus_control_init(struct macio_dev* dev, struct i2sbus_control **c)
-{
- *c = kzalloc(sizeof(struct i2sbus_control), GFP_KERNEL);
- if (!*c)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&(*c)->list);
-
- (*c)->macio = dev->bus->chip;
- return 0;
-}
-
-void i2sbus_control_destroy(struct i2sbus_control *c)
-{
- kfree(c);
-}
-
-/* this is serialised externally */
-int i2sbus_control_add_dev(struct i2sbus_control *c,
- struct i2sbus_dev *i2sdev)
-{
- struct device_node *np;
-
- np = i2sdev->sound.ofdev.dev.of_node;
- i2sdev->enable = pmf_find_function(np, "enable");
- i2sdev->cell_enable = pmf_find_function(np, "cell-enable");
- i2sdev->clock_enable = pmf_find_function(np, "clock-enable");
- i2sdev->cell_disable = pmf_find_function(np, "cell-disable");
- i2sdev->clock_disable = pmf_find_function(np, "clock-disable");
-
- /* if the bus number is not 0 or 1 we absolutely need to use
- * the platform functions -- there's nothing in Darwin that
- * would allow seeing a system behind what the FCRs are then,
- * and I don't want to go parsing a bunch of platform functions
- * by hand to try finding a system... */
- if (i2sdev->bus_number != 0 && i2sdev->bus_number != 1 &&
- (!i2sdev->enable ||
- !i2sdev->cell_enable || !i2sdev->clock_enable ||
- !i2sdev->cell_disable || !i2sdev->clock_disable)) {
- pmf_put_function(i2sdev->enable);
- pmf_put_function(i2sdev->cell_enable);
- pmf_put_function(i2sdev->clock_enable);
- pmf_put_function(i2sdev->cell_disable);
- pmf_put_function(i2sdev->clock_disable);
- return -ENODEV;
- }
-
- list_add(&i2sdev->item, &c->list);
-
- return 0;
-}
-
-void i2sbus_control_remove_dev(struct i2sbus_control *c,
- struct i2sbus_dev *i2sdev)
-{
- /* this is serialised externally */
- list_del(&i2sdev->item);
- if (list_empty(&c->list))
- i2sbus_control_destroy(c);
-}
-
-int i2sbus_control_enable(struct i2sbus_control *c,
- struct i2sbus_dev *i2sdev)
-{
- struct pmf_args args = { .count = 0 };
- struct macio_chip *macio = c->macio;
-
- if (i2sdev->enable)
- return pmf_call_one(i2sdev->enable, &args);
-
- if (macio == NULL || macio->base == NULL)
- return -ENODEV;
-
- switch (i2sdev->bus_number) {
- case 0:
- /* these need to be locked or done through
- * newly created feature calls! */
- MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_ENABLE);
- break;
- case 1:
- MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_ENABLE);
- break;
- default:
- return -ENODEV;
- }
- return 0;
-}
-
-int i2sbus_control_cell(struct i2sbus_control *c,
- struct i2sbus_dev *i2sdev,
- int enable)
-{
- struct pmf_args args = { .count = 0 };
- struct macio_chip *macio = c->macio;
-
- switch (enable) {
- case 0:
- if (i2sdev->cell_disable)
- return pmf_call_one(i2sdev->cell_disable, &args);
- break;
- case 1:
- if (i2sdev->cell_enable)
- return pmf_call_one(i2sdev->cell_enable, &args);
- break;
- default:
- printk(KERN_ERR "i2sbus: INVALID CELL ENABLE VALUE\n");
- return -ENODEV;
- }
-
- if (macio == NULL || macio->base == NULL)
- return -ENODEV;
-
- switch (i2sdev->bus_number) {
- case 0:
- if (enable)
- MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE);
- else
- MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE);
- break;
- case 1:
- if (enable)
- MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_CELL_ENABLE);
- else
- MACIO_BIC(KEYLARGO_FCR1, KL1_I2S1_CELL_ENABLE);
- break;
- default:
- return -ENODEV;
- }
- return 0;
-}
-
-int i2sbus_control_clock(struct i2sbus_control *c,
- struct i2sbus_dev *i2sdev,
- int enable)
-{
- struct pmf_args args = { .count = 0 };
- struct macio_chip *macio = c->macio;
-
- switch (enable) {
- case 0:
- if (i2sdev->clock_disable)
- return pmf_call_one(i2sdev->clock_disable, &args);
- break;
- case 1:
- if (i2sdev->clock_enable)
- return pmf_call_one(i2sdev->clock_enable, &args);
- break;
- default:
- printk(KERN_ERR "i2sbus: INVALID CLOCK ENABLE VALUE\n");
- return -ENODEV;
- }
-
- if (macio == NULL || macio->base == NULL)
- return -ENODEV;
-
- switch (i2sdev->bus_number) {
- case 0:
- if (enable)
- MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT);
- else
- MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT);
- break;
- case 1:
- if (enable)
- MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_CLK_ENABLE_BIT);
- else
- MACIO_BIC(KEYLARGO_FCR1, KL1_I2S1_CLK_ENABLE_BIT);
- break;
- default:
- return -ENODEV;
- }
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/core.c b/ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/core.c
deleted file mode 100644
index 01065833..00000000
--- a/ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/core.c
+++ /dev/null
@@ -1,464 +0,0 @@
-/*
- * i2sbus driver
- *
- * Copyright 2006-2008 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/dma-mapping.h>
-
-#include <sound/core.h>
-
-#include <asm/macio.h>
-#include <asm/dbdma.h>
-
-#include "../soundbus.h"
-#include "i2sbus.h"
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
-MODULE_DESCRIPTION("Apple Soundbus: I2S support");
-
-static int force;
-module_param(force, int, 0444);
-MODULE_PARM_DESC(force, "Force loading i2sbus even when"
- " no layout-id property is present");
-
-static struct of_device_id i2sbus_match[] = {
- { .name = "i2s" },
- { }
-};
-
-MODULE_DEVICE_TABLE(of, i2sbus_match);
-
-static int alloc_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
- struct dbdma_command_mem *r,
- int numcmds)
-{
- /* one more for rounding, one for branch back, one for stop command */
- r->size = (numcmds + 3) * sizeof(struct dbdma_cmd);
- /* We use the PCI APIs for now until the generic one gets fixed
- * enough or until we get some macio-specific versions
- */
- r->space = dma_alloc_coherent(
- &macio_get_pci_dev(i2sdev->macio)->dev,
- r->size,
- &r->bus_addr,
- GFP_KERNEL);
-
- if (!r->space) return -ENOMEM;
-
- memset(r->space, 0, r->size);
- r->cmds = (void*)DBDMA_ALIGN(r->space);
- r->bus_cmd_start = r->bus_addr +
- (dma_addr_t)((char*)r->cmds - (char*)r->space);
-
- return 0;
-}
-
-static void free_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
- struct dbdma_command_mem *r)
-{
- if (!r->space) return;
-
- dma_free_coherent(&macio_get_pci_dev(i2sdev->macio)->dev,
- r->size, r->space, r->bus_addr);
-}
-
-static void i2sbus_release_dev(struct device *dev)
-{
- struct i2sbus_dev *i2sdev;
- int i;
-
- i2sdev = container_of(dev, struct i2sbus_dev, sound.ofdev.dev);
-
- if (i2sdev->intfregs) iounmap(i2sdev->intfregs);
- if (i2sdev->out.dbdma) iounmap(i2sdev->out.dbdma);
- if (i2sdev->in.dbdma) iounmap(i2sdev->in.dbdma);
- for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++)
- if (i2sdev->allocated_resource[i])
- release_and_free_resource(i2sdev->allocated_resource[i]);
- free_dbdma_descriptor_ring(i2sdev, &i2sdev->out.dbdma_ring);
- free_dbdma_descriptor_ring(i2sdev, &i2sdev->in.dbdma_ring);
- for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++)
- free_irq(i2sdev->interrupts[i], i2sdev);
- i2sbus_control_remove_dev(i2sdev->control, i2sdev);
- mutex_destroy(&i2sdev->lock);
- kfree(i2sdev);
-}
-
-static irqreturn_t i2sbus_bus_intr(int irq, void *devid)
-{
- struct i2sbus_dev *dev = devid;
- u32 intreg;
-
- spin_lock(&dev->low_lock);
- intreg = in_le32(&dev->intfregs->intr_ctl);
-
- /* acknowledge interrupt reasons */
- out_le32(&dev->intfregs->intr_ctl, intreg);
-
- spin_unlock(&dev->low_lock);
-
- return IRQ_HANDLED;
-}
-
-
-/*
- * XXX FIXME: We test the layout_id's here to get the proper way of
- * mapping in various registers, thanks to bugs in Apple device-trees.
- * We could instead key off the machine model and the name of the i2s
- * node (i2s-a). This we'll do when we move it all to macio_asic.c
- * and have that export items for each sub-node too.
- */
-static int i2sbus_get_and_fixup_rsrc(struct device_node *np, int index,
- int layout, struct resource *res)
-{
- struct device_node *parent;
- int pindex, rc = -ENXIO;
- const u32 *reg;
-
- /* Machines with layout 76 and 36 (K2 based) have a weird device
- * tree what we need to special case.
- * Normal machines just fetch the resource from the i2s-X node.
- * Darwin further divides normal machines into old and new layouts
- * with a subtely different code path but that doesn't seem necessary
- * in practice, they just bloated it. In addition, even on our K2
- * case the i2s-modem node, if we ever want to handle it, uses the
- * normal layout
- */
- if (layout != 76 && layout != 36)
- return of_address_to_resource(np, index, res);
-
- parent = of_get_parent(np);
- pindex = (index == aoa_resource_i2smmio) ? 0 : 1;
- rc = of_address_to_resource(parent, pindex, res);
- if (rc)
- goto bail;
- reg = of_get_property(np, "reg", NULL);
- if (reg == NULL) {
- rc = -ENXIO;
- goto bail;
- }
- res->start += reg[index * 2];
- res->end = res->start + reg[index * 2 + 1] - 1;
- bail:
- of_node_put(parent);
- return rc;
-}
-
-/* FIXME: look at device node refcounting */
-static int i2sbus_add_dev(struct macio_dev *macio,
- struct i2sbus_control *control,
- struct device_node *np)
-{
- struct i2sbus_dev *dev;
- struct device_node *child = NULL, *sound = NULL;
- struct resource *r;
- int i, layout = 0, rlen, ok = force;
- static const char *rnames[] = { "i2sbus: %s (control)",
- "i2sbus: %s (tx)",
- "i2sbus: %s (rx)" };
- static irq_handler_t ints[] = {
- i2sbus_bus_intr,
- i2sbus_tx_intr,
- i2sbus_rx_intr
- };
-
- if (strlen(np->name) != 5)
- return 0;
- if (strncmp(np->name, "i2s-", 4))
- return 0;
-
- dev = kzalloc(sizeof(struct i2sbus_dev), GFP_KERNEL);
- if (!dev)
- return 0;
-
- i = 0;
- while ((child = of_get_next_child(np, child))) {
- if (strcmp(child->name, "sound") == 0) {
- i++;
- sound = child;
- }
- }
- if (i == 1) {
- const u32 *id = of_get_property(sound, "layout-id", NULL);
-
- if (id) {
- layout = *id;
- snprintf(dev->sound.modalias, 32,
- "sound-layout-%d", layout);
- ok = 1;
- } else {
- id = of_get_property(sound, "device-id", NULL);
- /*
- * We probably cannot handle all device-id machines,
- * so restrict to those we do handle for now.
- */
- if (id && (*id == 22 || *id == 14 || *id == 35)) {
- snprintf(dev->sound.modalias, 32,
- "aoa-device-id-%d", *id);
- ok = 1;
- layout = -1;
- }
- }
- }
- /* for the time being, until we can handle non-layout-id
- * things in some fabric, refuse to attach if there is no
- * layout-id property or we haven't been forced to attach.
- * When there are two i2s busses and only one has a layout-id,
- * then this depends on the order, but that isn't important
- * either as the second one in that case is just a modem. */
- if (!ok) {
- kfree(dev);
- return -ENODEV;
- }
-
- mutex_init(&dev->lock);
- spin_lock_init(&dev->low_lock);
- dev->sound.ofdev.archdata.dma_mask = macio->ofdev.archdata.dma_mask;
- dev->sound.ofdev.dev.of_node = np;
- dev->sound.ofdev.dev.dma_mask = &dev->sound.ofdev.archdata.dma_mask;
- dev->sound.ofdev.dev.parent = &macio->ofdev.dev;
- dev->sound.ofdev.dev.release = i2sbus_release_dev;
- dev->sound.attach_codec = i2sbus_attach_codec;
- dev->sound.detach_codec = i2sbus_detach_codec;
- dev->sound.pcmid = -1;
- dev->macio = macio;
- dev->control = control;
- dev->bus_number = np->name[4] - 'a';
- INIT_LIST_HEAD(&dev->sound.codec_list);
-
- for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) {
- dev->interrupts[i] = -1;
- snprintf(dev->rnames[i], sizeof(dev->rnames[i]),
- rnames[i], np->name);
- }
- for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) {
- int irq = irq_of_parse_and_map(np, i);
- if (request_irq(irq, ints[i], 0, dev->rnames[i], dev))
- goto err;
- dev->interrupts[i] = irq;
- }
-
-
- /* Resource handling is problematic as some device-trees contain
- * useless crap (ugh ugh ugh). We work around that here by calling
- * specific functions for calculating the appropriate resources.
- *
- * This will all be moved to macio_asic.c at one point
- */
- for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) {
- if (i2sbus_get_and_fixup_rsrc(np,i,layout,&dev->resources[i]))
- goto err;
- /* If only we could use our resource dev->resources[i]...
- * but request_resource doesn't know about parents and
- * contained resources...
- */
- dev->allocated_resource[i] =
- request_mem_region(dev->resources[i].start,
- resource_size(&dev->resources[i]),
- dev->rnames[i]);
- if (!dev->allocated_resource[i]) {
- printk(KERN_ERR "i2sbus: failed to claim resource %d!\n", i);
- goto err;
- }
- }
-
- r = &dev->resources[aoa_resource_i2smmio];
- rlen = resource_size(r);
- if (rlen < sizeof(struct i2s_interface_regs))
- goto err;
- dev->intfregs = ioremap(r->start, rlen);
-
- r = &dev->resources[aoa_resource_txdbdma];
- rlen = resource_size(r);
- if (rlen < sizeof(struct dbdma_regs))
- goto err;
- dev->out.dbdma = ioremap(r->start, rlen);
-
- r = &dev->resources[aoa_resource_rxdbdma];
- rlen = resource_size(r);
- if (rlen < sizeof(struct dbdma_regs))
- goto err;
- dev->in.dbdma = ioremap(r->start, rlen);
-
- if (!dev->intfregs || !dev->out.dbdma || !dev->in.dbdma)
- goto err;
-
- if (alloc_dbdma_descriptor_ring(dev, &dev->out.dbdma_ring,
- MAX_DBDMA_COMMANDS))
- goto err;
- if (alloc_dbdma_descriptor_ring(dev, &dev->in.dbdma_ring,
- MAX_DBDMA_COMMANDS))
- goto err;
-
- if (i2sbus_control_add_dev(dev->control, dev)) {
- printk(KERN_ERR "i2sbus: control layer didn't like bus\n");
- goto err;
- }
-
- if (soundbus_add_one(&dev->sound)) {
- printk(KERN_DEBUG "i2sbus: device registration error!\n");
- goto err;
- }
-
- /* enable this cell */
- i2sbus_control_cell(dev->control, dev, 1);
- i2sbus_control_enable(dev->control, dev);
- i2sbus_control_clock(dev->control, dev, 1);
-
- return 1;
- err:
- for (i=0;i<3;i++)
- if (dev->interrupts[i] != -1)
- free_irq(dev->interrupts[i], dev);
- free_dbdma_descriptor_ring(dev, &dev->out.dbdma_ring);
- free_dbdma_descriptor_ring(dev, &dev->in.dbdma_ring);
- if (dev->intfregs) iounmap(dev->intfregs);
- if (dev->out.dbdma) iounmap(dev->out.dbdma);
- if (dev->in.dbdma) iounmap(dev->in.dbdma);
- for (i=0;i<3;i++)
- if (dev->allocated_resource[i])
- release_and_free_resource(dev->allocated_resource[i]);
- mutex_destroy(&dev->lock);
- kfree(dev);
- return 0;
-}
-
-static int i2sbus_probe(struct macio_dev* dev, const struct of_device_id *match)
-{
- struct device_node *np = NULL;
- int got = 0, err;
- struct i2sbus_control *control = NULL;
-
- err = i2sbus_control_init(dev, &control);
- if (err)
- return err;
- if (!control) {
- printk(KERN_ERR "i2sbus_control_init API breakage\n");
- return -ENODEV;
- }
-
- while ((np = of_get_next_child(dev->ofdev.dev.of_node, np))) {
- if (of_device_is_compatible(np, "i2sbus") ||
- of_device_is_compatible(np, "i2s-modem")) {
- got += i2sbus_add_dev(dev, control, np);
- }
- }
-
- if (!got) {
- /* found none, clean up */
- i2sbus_control_destroy(control);
- return -ENODEV;
- }
-
- dev_set_drvdata(&dev->ofdev.dev, control);
-
- return 0;
-}
-
-static int i2sbus_remove(struct macio_dev* dev)
-{
- struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev);
- struct i2sbus_dev *i2sdev, *tmp;
-
- list_for_each_entry_safe(i2sdev, tmp, &control->list, item)
- soundbus_remove_one(&i2sdev->sound);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state)
-{
- struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev);
- struct codec_info_item *cii;
- struct i2sbus_dev* i2sdev;
- int err, ret = 0;
-
- list_for_each_entry(i2sdev, &control->list, item) {
- /* Notify Alsa */
- if (i2sdev->sound.pcm) {
- /* Suspend PCM streams */
- snd_pcm_suspend_all(i2sdev->sound.pcm);
- }
-
- /* Notify codecs */
- list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
- err = 0;
- if (cii->codec->suspend)
- err = cii->codec->suspend(cii, state);
- if (err)
- ret = err;
- }
-
- /* wait until streams are stopped */
- i2sbus_wait_for_stop_both(i2sdev);
- }
-
- return ret;
-}
-
-static int i2sbus_resume(struct macio_dev* dev)
-{
- struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev);
- struct codec_info_item *cii;
- struct i2sbus_dev* i2sdev;
- int err, ret = 0;
-
- list_for_each_entry(i2sdev, &control->list, item) {
- /* reset i2s bus format etc. */
- i2sbus_pcm_prepare_both(i2sdev);
-
- /* Notify codecs so they can re-initialize */
- list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
- err = 0;
- if (cii->codec->resume)
- err = cii->codec->resume(cii);
- if (err)
- ret = err;
- }
- }
-
- return ret;
-}
-#endif /* CONFIG_PM */
-
-static int i2sbus_shutdown(struct macio_dev* dev)
-{
- return 0;
-}
-
-static struct macio_driver i2sbus_drv = {
- .driver = {
- .name = "soundbus-i2s",
- .owner = THIS_MODULE,
- .of_match_table = i2sbus_match,
- },
- .probe = i2sbus_probe,
- .remove = i2sbus_remove,
-#ifdef CONFIG_PM
- .suspend = i2sbus_suspend,
- .resume = i2sbus_resume,
-#endif
- .shutdown = i2sbus_shutdown,
-};
-
-static int __init soundbus_i2sbus_init(void)
-{
- return macio_register_driver(&i2sbus_drv);
-}
-
-static void __exit soundbus_i2sbus_exit(void)
-{
- macio_unregister_driver(&i2sbus_drv);
-}
-
-module_init(soundbus_i2sbus_init);
-module_exit(soundbus_i2sbus_exit);
diff --git a/ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/i2sbus.h b/ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/i2sbus.h
deleted file mode 100644
index befefd99..00000000
--- a/ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/i2sbus.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * i2sbus driver -- private definitions
- *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- */
-#ifndef __I2SBUS_H
-#define __I2SBUS_H
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/mutex.h>
-#include <linux/completion.h>
-
-#include <sound/pcm.h>
-
-#include <asm/prom.h>
-#include <asm/pmac_feature.h>
-#include <asm/dbdma.h>
-
-#include "interface.h"
-#include "../soundbus.h"
-
-struct i2sbus_control {
- struct list_head list;
- struct macio_chip *macio;
-};
-
-#define MAX_DBDMA_COMMANDS 32
-
-struct dbdma_command_mem {
- dma_addr_t bus_addr;
- dma_addr_t bus_cmd_start;
- struct dbdma_cmd *cmds;
- void *space;
- int size;
- u32 running:1;
- u32 stopping:1;
-};
-
-struct pcm_info {
- u32 created:1, /* has this direction been created with alsa? */
- active:1; /* is this stream active? */
- /* runtime information */
- struct snd_pcm_substream *substream;
- int current_period;
- u32 frame_count;
- struct dbdma_command_mem dbdma_ring;
- volatile struct dbdma_regs __iomem *dbdma;
- struct completion *stop_completion;
-};
-
-enum {
- aoa_resource_i2smmio = 0,
- aoa_resource_txdbdma,
- aoa_resource_rxdbdma,
-};
-
-struct i2sbus_dev {
- struct soundbus_dev sound;
- struct macio_dev *macio;
- struct i2sbus_control *control;
- volatile struct i2s_interface_regs __iomem *intfregs;
-
- struct resource resources[3];
- struct resource *allocated_resource[3];
- int interrupts[3];
- char rnames[3][32];
-
- /* info about currently active substreams */
- struct pcm_info out, in;
- snd_pcm_format_t format;
- unsigned int rate;
-
- /* list for a single controller */
- struct list_head item;
- /* number of bus on controller */
- int bus_number;
- /* for use by control layer */
- struct pmf_function *enable,
- *cell_enable,
- *cell_disable,
- *clock_enable,
- *clock_disable;
-
- /* locks */
- /* spinlock for low-level interrupt locking */
- spinlock_t low_lock;
- /* mutex for high-level consistency */
- struct mutex lock;
-};
-
-#define soundbus_dev_to_i2sbus_dev(sdev) \
- container_of(sdev, struct i2sbus_dev, sound)
-
-/* pcm specific functions */
-extern int
-i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
- struct codec_info *ci, void *data);
-extern void
-i2sbus_detach_codec(struct soundbus_dev *dev, void *data);
-extern irqreturn_t
-i2sbus_tx_intr(int irq, void *devid);
-extern irqreturn_t
-i2sbus_rx_intr(int irq, void *devid);
-
-extern void i2sbus_wait_for_stop_both(struct i2sbus_dev *i2sdev);
-extern void i2sbus_pcm_prepare_both(struct i2sbus_dev *i2sdev);
-
-/* control specific functions */
-extern int i2sbus_control_init(struct macio_dev* dev,
- struct i2sbus_control **c);
-extern void i2sbus_control_destroy(struct i2sbus_control *c);
-extern int i2sbus_control_add_dev(struct i2sbus_control *c,
- struct i2sbus_dev *i2sdev);
-extern void i2sbus_control_remove_dev(struct i2sbus_control *c,
- struct i2sbus_dev *i2sdev);
-extern int i2sbus_control_enable(struct i2sbus_control *c,
- struct i2sbus_dev *i2sdev);
-extern int i2sbus_control_cell(struct i2sbus_control *c,
- struct i2sbus_dev *i2sdev,
- int enable);
-extern int i2sbus_control_clock(struct i2sbus_control *c,
- struct i2sbus_dev *i2sdev,
- int enable);
-#endif /* __I2SBUS_H */
diff --git a/ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/interface.h b/ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/interface.h
deleted file mode 100644
index c6b5f545..00000000
--- a/ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/interface.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * i2sbus driver -- interface register definitions
- *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- */
-#ifndef __I2SBUS_INTERFACE_H
-#define __I2SBUS_INTERFACE_H
-
-/* i2s bus control registers, at least what we know about them */
-
-#define __PAD(m,n) u8 __pad##m[n]
-#define _PAD(line, n) __PAD(line, n)
-#define PAD(n) _PAD(__LINE__, (n))
-struct i2s_interface_regs {
- __le32 intr_ctl; /* 0x00 */
- PAD(12);
- __le32 serial_format; /* 0x10 */
- PAD(12);
- __le32 codec_msg_out; /* 0x20 */
- PAD(12);
- __le32 codec_msg_in; /* 0x30 */
- PAD(12);
- __le32 frame_count; /* 0x40 */
- PAD(12);
- __le32 frame_match; /* 0x50 */
- PAD(12);
- __le32 data_word_sizes; /* 0x60 */
- PAD(12);
- __le32 peak_level_sel; /* 0x70 */
- PAD(12);
- __le32 peak_level_in0; /* 0x80 */
- PAD(12);
- __le32 peak_level_in1; /* 0x90 */
- PAD(12);
- /* total size: 0x100 bytes */
-} __attribute__((__packed__));
-
-/* interrupt register is just a bitfield with
- * interrupt enable and pending bits */
-#define I2S_REG_INTR_CTL 0x00
-# define I2S_INT_FRAME_COUNT (1<<31)
-# define I2S_PENDING_FRAME_COUNT (1<<30)
-# define I2S_INT_MESSAGE_FLAG (1<<29)
-# define I2S_PENDING_MESSAGE_FLAG (1<<28)
-# define I2S_INT_NEW_PEAK (1<<27)
-# define I2S_PENDING_NEW_PEAK (1<<26)
-# define I2S_INT_CLOCKS_STOPPED (1<<25)
-# define I2S_PENDING_CLOCKS_STOPPED (1<<24)
-# define I2S_INT_EXTERNAL_SYNC_ERROR (1<<23)
-# define I2S_PENDING_EXTERNAL_SYNC_ERROR (1<<22)
-# define I2S_INT_EXTERNAL_SYNC_OK (1<<21)
-# define I2S_PENDING_EXTERNAL_SYNC_OK (1<<20)
-# define I2S_INT_NEW_SAMPLE_RATE (1<<19)
-# define I2S_PENDING_NEW_SAMPLE_RATE (1<<18)
-# define I2S_INT_STATUS_FLAG (1<<17)
-# define I2S_PENDING_STATUS_FLAG (1<<16)
-
-/* serial format register is more interesting :)
- * It contains:
- * - clock source
- * - MClk divisor
- * - SClk divisor
- * - SClk master flag
- * - serial format (sony, i2s 64x, i2s 32x, dav, silabs)
- * - external sample frequency interrupt (don't understand)
- * - external sample frequency
- */
-#define I2S_REG_SERIAL_FORMAT 0x10
-/* clock source. You get either 18.432, 45.1584 or 49.1520 MHz */
-# define I2S_SF_CLOCK_SOURCE_SHIFT 30
-# define I2S_SF_CLOCK_SOURCE_MASK (3<<I2S_SF_CLOCK_SOURCE_SHIFT)
-# define I2S_SF_CLOCK_SOURCE_18MHz (0<<I2S_SF_CLOCK_SOURCE_SHIFT)
-# define I2S_SF_CLOCK_SOURCE_45MHz (1<<I2S_SF_CLOCK_SOURCE_SHIFT)
-# define I2S_SF_CLOCK_SOURCE_49MHz (2<<I2S_SF_CLOCK_SOURCE_SHIFT)
-/* also, let's define the exact clock speeds here, in Hz */
-#define I2S_CLOCK_SPEED_18MHz 18432000
-#define I2S_CLOCK_SPEED_45MHz 45158400
-#define I2S_CLOCK_SPEED_49MHz 49152000
-/* MClk is the clock that drives the codec, usually called its 'system clock'.
- * It is derived by taking only every 'divisor' tick of the clock.
- */
-# define I2S_SF_MCLKDIV_SHIFT 24
-# define I2S_SF_MCLKDIV_MASK (0x1F<<I2S_SF_MCLKDIV_SHIFT)
-# define I2S_SF_MCLKDIV_1 (0x14<<I2S_SF_MCLKDIV_SHIFT)
-# define I2S_SF_MCLKDIV_3 (0x13<<I2S_SF_MCLKDIV_SHIFT)
-# define I2S_SF_MCLKDIV_5 (0x12<<I2S_SF_MCLKDIV_SHIFT)
-# define I2S_SF_MCLKDIV_14 (0x0E<<I2S_SF_MCLKDIV_SHIFT)
-# define I2S_SF_MCLKDIV_OTHER(div) (((div/2-1)<<I2S_SF_MCLKDIV_SHIFT)&I2S_SF_MCLKDIV_MASK)
-static inline int i2s_sf_mclkdiv(int div, int *out)
-{
- int d;
-
- switch(div) {
- case 1: *out |= I2S_SF_MCLKDIV_1; return 0;
- case 3: *out |= I2S_SF_MCLKDIV_3; return 0;
- case 5: *out |= I2S_SF_MCLKDIV_5; return 0;
- case 14: *out |= I2S_SF_MCLKDIV_14; return 0;
- default:
- if (div%2) return -1;
- d = div/2-1;
- if (d == 0x14 || d == 0x13 || d == 0x12 || d == 0x0E)
- return -1;
- *out |= I2S_SF_MCLKDIV_OTHER(div);
- return 0;
- }
-}
-/* SClk is the clock that drives the i2s wire bus. Note that it is
- * derived from the MClk above by taking only every 'divisor' tick
- * of MClk.
- */
-# define I2S_SF_SCLKDIV_SHIFT 20
-# define I2S_SF_SCLKDIV_MASK (0xF<<I2S_SF_SCLKDIV_SHIFT)
-# define I2S_SF_SCLKDIV_1 (8<<I2S_SF_SCLKDIV_SHIFT)
-# define I2S_SF_SCLKDIV_3 (9<<I2S_SF_SCLKDIV_SHIFT)
-# define I2S_SF_SCLKDIV_OTHER(div) (((div/2-1)<<I2S_SF_SCLKDIV_SHIFT)&I2S_SF_SCLKDIV_MASK)
-static inline int i2s_sf_sclkdiv(int div, int *out)
-{
- int d;
-
- switch(div) {
- case 1: *out |= I2S_SF_SCLKDIV_1; return 0;
- case 3: *out |= I2S_SF_SCLKDIV_3; return 0;
- default:
- if (div%2) return -1;
- d = div/2-1;
- if (d == 8 || d == 9) return -1;
- *out |= I2S_SF_SCLKDIV_OTHER(div);
- return 0;
- }
-}
-# define I2S_SF_SCLK_MASTER (1<<19)
-/* serial format is the way the data is put to the i2s wire bus */
-# define I2S_SF_SERIAL_FORMAT_SHIFT 16
-# define I2S_SF_SERIAL_FORMAT_MASK (7<<I2S_SF_SERIAL_FORMAT_SHIFT)
-# define I2S_SF_SERIAL_FORMAT_SONY (0<<I2S_SF_SERIAL_FORMAT_SHIFT)
-# define I2S_SF_SERIAL_FORMAT_I2S_64X (1<<I2S_SF_SERIAL_FORMAT_SHIFT)
-# define I2S_SF_SERIAL_FORMAT_I2S_32X (2<<I2S_SF_SERIAL_FORMAT_SHIFT)
-# define I2S_SF_SERIAL_FORMAT_I2S_DAV (4<<I2S_SF_SERIAL_FORMAT_SHIFT)
-# define I2S_SF_SERIAL_FORMAT_I2S_SILABS (5<<I2S_SF_SERIAL_FORMAT_SHIFT)
-/* unknown */
-# define I2S_SF_EXT_SAMPLE_FREQ_INT_SHIFT 12
-# define I2S_SF_EXT_SAMPLE_FREQ_INT_MASK (0xF<<I2S_SF_SAMPLE_FREQ_INT_SHIFT)
-/* probably gives external frequency? */
-# define I2S_SF_EXT_SAMPLE_FREQ_MASK 0xFFF
-
-/* used to send codec messages, but how isn't clear */
-#define I2S_REG_CODEC_MSG_OUT 0x20
-
-/* used to receive codec messages, but how isn't clear */
-#define I2S_REG_CODEC_MSG_IN 0x30
-
-/* frame count reg isn't clear to me yet, but probably useful */
-#define I2S_REG_FRAME_COUNT 0x40
-
-/* program to some value, and get interrupt if frame count reaches it */
-#define I2S_REG_FRAME_MATCH 0x50
-
-/* this register describes how the bus transfers data */
-#define I2S_REG_DATA_WORD_SIZES 0x60
-/* number of interleaved input channels */
-# define I2S_DWS_NUM_CHANNELS_IN_SHIFT 24
-# define I2S_DWS_NUM_CHANNELS_IN_MASK (0x1F<<I2S_DWS_NUM_CHANNELS_IN_SHIFT)
-/* word size of input data */
-# define I2S_DWS_DATA_IN_SIZE_SHIFT 16
-# define I2S_DWS_DATA_IN_16BIT (0<<I2S_DWS_DATA_IN_SIZE_SHIFT)
-# define I2S_DWS_DATA_IN_24BIT (3<<I2S_DWS_DATA_IN_SIZE_SHIFT)
-/* number of interleaved output channels */
-# define I2S_DWS_NUM_CHANNELS_OUT_SHIFT 8
-# define I2S_DWS_NUM_CHANNELS_OUT_MASK (0x1F<<I2S_DWS_NUM_CHANNELS_OUT_SHIFT)
-/* word size of output data */
-# define I2S_DWS_DATA_OUT_SIZE_SHIFT 0
-# define I2S_DWS_DATA_OUT_16BIT (0<<I2S_DWS_DATA_OUT_SIZE_SHIFT)
-# define I2S_DWS_DATA_OUT_24BIT (3<<I2S_DWS_DATA_OUT_SIZE_SHIFT)
-
-
-/* unknown */
-#define I2S_REG_PEAK_LEVEL_SEL 0x70
-
-/* unknown */
-#define I2S_REG_PEAK_LEVEL_IN0 0x80
-
-/* unknown */
-#define I2S_REG_PEAK_LEVEL_IN1 0x90
-
-#endif /* __I2SBUS_INTERFACE_H */
diff --git a/ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/pcm.c b/ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/pcm.c
deleted file mode 100644
index 19491ed9..00000000
--- a/ANDROID_3.4.5/sound/aoa/soundbus/i2sbus/pcm.c
+++ /dev/null
@@ -1,1064 +0,0 @@
-/*
- * i2sbus driver -- pcm routines
- *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <asm/macio.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include "../soundbus.h"
-#include "i2sbus.h"
-
-static inline void get_pcm_info(struct i2sbus_dev *i2sdev, int in,
- struct pcm_info **pi, struct pcm_info **other)
-{
- if (in) {
- if (pi)
- *pi = &i2sdev->in;
- if (other)
- *other = &i2sdev->out;
- } else {
- if (pi)
- *pi = &i2sdev->out;
- if (other)
- *other = &i2sdev->in;
- }
-}
-
-static int clock_and_divisors(int mclk, int sclk, int rate, int *out)
-{
- /* sclk must be derived from mclk! */
- if (mclk % sclk)
- return -1;
- /* derive sclk register value */
- if (i2s_sf_sclkdiv(mclk / sclk, out))
- return -1;
-
- if (I2S_CLOCK_SPEED_18MHz % (rate * mclk) == 0) {
- if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_18MHz / (rate * mclk), out)) {
- *out |= I2S_SF_CLOCK_SOURCE_18MHz;
- return 0;
- }
- }
- if (I2S_CLOCK_SPEED_45MHz % (rate * mclk) == 0) {
- if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_45MHz / (rate * mclk), out)) {
- *out |= I2S_SF_CLOCK_SOURCE_45MHz;
- return 0;
- }
- }
- if (I2S_CLOCK_SPEED_49MHz % (rate * mclk) == 0) {
- if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_49MHz / (rate * mclk), out)) {
- *out |= I2S_SF_CLOCK_SOURCE_49MHz;
- return 0;
- }
- }
- return -1;
-}
-
-#define CHECK_RATE(rate) \
- do { if (rates & SNDRV_PCM_RATE_ ##rate) { \
- int dummy; \
- if (clock_and_divisors(sysclock_factor, \
- bus_factor, rate, &dummy)) \
- rates &= ~SNDRV_PCM_RATE_ ##rate; \
- } } while (0)
-
-static int i2sbus_pcm_open(struct i2sbus_dev *i2sdev, int in)
-{
- struct pcm_info *pi, *other;
- struct soundbus_dev *sdev;
- int masks_inited = 0, err;
- struct codec_info_item *cii, *rev;
- struct snd_pcm_hardware *hw;
- u64 formats = 0;
- unsigned int rates = 0;
- struct transfer_info v;
- int result = 0;
- int bus_factor = 0, sysclock_factor = 0;
- int found_this;
-
- mutex_lock(&i2sdev->lock);
-
- get_pcm_info(i2sdev, in, &pi, &other);
-
- hw = &pi->substream->runtime->hw;
- sdev = &i2sdev->sound;
-
- if (pi->active) {
- /* alsa messed up */
- result = -EBUSY;
- goto out_unlock;
- }
-
- /* we now need to assign the hw */
- list_for_each_entry(cii, &sdev->codec_list, list) {
- struct transfer_info *ti = cii->codec->transfers;
- bus_factor = cii->codec->bus_factor;
- sysclock_factor = cii->codec->sysclock_factor;
- while (ti->formats && ti->rates) {
- v = *ti;
- if (ti->transfer_in == in
- && cii->codec->usable(cii, ti, &v)) {
- if (masks_inited) {
- formats &= v.formats;
- rates &= v.rates;
- } else {
- formats = v.formats;
- rates = v.rates;
- masks_inited = 1;
- }
- }
- ti++;
- }
- }
- if (!masks_inited || !bus_factor || !sysclock_factor) {
- result = -ENODEV;
- goto out_unlock;
- }
- /* bus dependent stuff */
- hw->info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_JOINT_DUPLEX;
-
- CHECK_RATE(5512);
- CHECK_RATE(8000);
- CHECK_RATE(11025);
- CHECK_RATE(16000);
- CHECK_RATE(22050);
- CHECK_RATE(32000);
- CHECK_RATE(44100);
- CHECK_RATE(48000);
- CHECK_RATE(64000);
- CHECK_RATE(88200);
- CHECK_RATE(96000);
- CHECK_RATE(176400);
- CHECK_RATE(192000);
- hw->rates = rates;
-
- /* well. the codec might want 24 bits only, and we'll
- * ever only transfer 24 bits, but they are top-aligned!
- * So for alsa, we claim that we're doing full 32 bit
- * while in reality we'll ignore the lower 8 bits of
- * that when doing playback (they're transferred as 0
- * as far as I know, no codecs we have are 32-bit capable
- * so I can't really test) and when doing recording we'll
- * always have those lower 8 bits recorded as 0 */
- if (formats & SNDRV_PCM_FMTBIT_S24_BE)
- formats |= SNDRV_PCM_FMTBIT_S32_BE;
- if (formats & SNDRV_PCM_FMTBIT_U24_BE)
- formats |= SNDRV_PCM_FMTBIT_U32_BE;
- /* now mask off what we can support. I suppose we could
- * also support S24_3LE and some similar formats, but I
- * doubt there's a codec that would be able to use that,
- * so we don't support it here. */
- hw->formats = formats & (SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_U16_BE |
- SNDRV_PCM_FMTBIT_S32_BE |
- SNDRV_PCM_FMTBIT_U32_BE);
-
- /* we need to set the highest and lowest rate possible.
- * These are the highest and lowest rates alsa can
- * support properly in its bitfield.
- * Below, we'll use that to restrict to the rate
- * currently in use (if any). */
- hw->rate_min = 5512;
- hw->rate_max = 192000;
- /* if the other stream is active, then we can only
- * support what it is currently using.
- * FIXME: I lied. This comment is wrong. We can support
- * anything that works with the same serial format, ie.
- * when recording 24 bit sound we can well play 16 bit
- * sound at the same time iff using the same transfer mode.
- */
- if (other->active) {
- /* FIXME: is this guaranteed by the alsa api? */
- hw->formats &= (1ULL << i2sdev->format);
- /* see above, restrict rates to the one we already have */
- hw->rate_min = i2sdev->rate;
- hw->rate_max = i2sdev->rate;
- }
-
- hw->channels_min = 2;
- hw->channels_max = 2;
- /* these are somewhat arbitrary */
- hw->buffer_bytes_max = 131072;
- hw->period_bytes_min = 256;
- hw->period_bytes_max = 16384;
- hw->periods_min = 3;
- hw->periods_max = MAX_DBDMA_COMMANDS;
- err = snd_pcm_hw_constraint_integer(pi->substream->runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0) {
- result = err;
- goto out_unlock;
- }
- list_for_each_entry(cii, &sdev->codec_list, list) {
- if (cii->codec->open) {
- err = cii->codec->open(cii, pi->substream);
- if (err) {
- result = err;
- /* unwind */
- found_this = 0;
- list_for_each_entry_reverse(rev,
- &sdev->codec_list, list) {
- if (found_this && rev->codec->close) {
- rev->codec->close(rev,
- pi->substream);
- }
- if (rev == cii)
- found_this = 1;
- }
- goto out_unlock;
- }
- }
- }
-
- out_unlock:
- mutex_unlock(&i2sdev->lock);
- return result;
-}
-
-#undef CHECK_RATE
-
-static int i2sbus_pcm_close(struct i2sbus_dev *i2sdev, int in)
-{
- struct codec_info_item *cii;
- struct pcm_info *pi;
- int err = 0, tmp;
-
- mutex_lock(&i2sdev->lock);
-
- get_pcm_info(i2sdev, in, &pi, NULL);
-
- list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
- if (cii->codec->close) {
- tmp = cii->codec->close(cii, pi->substream);
- if (tmp)
- err = tmp;
- }
- }
-
- pi->substream = NULL;
- pi->active = 0;
- mutex_unlock(&i2sdev->lock);
- return err;
-}
-
-static void i2sbus_wait_for_stop(struct i2sbus_dev *i2sdev,
- struct pcm_info *pi)
-{
- unsigned long flags;
- struct completion done;
- long timeout;
-
- spin_lock_irqsave(&i2sdev->low_lock, flags);
- if (pi->dbdma_ring.stopping) {
- init_completion(&done);
- pi->stop_completion = &done;
- spin_unlock_irqrestore(&i2sdev->low_lock, flags);
- timeout = wait_for_completion_timeout(&done, HZ);
- spin_lock_irqsave(&i2sdev->low_lock, flags);
- pi->stop_completion = NULL;
- if (timeout == 0) {
- /* timeout expired, stop dbdma forcefully */
- printk(KERN_ERR "i2sbus_wait_for_stop: timed out\n");
- /* make sure RUN, PAUSE and S0 bits are cleared */
- out_le32(&pi->dbdma->control, (RUN | PAUSE | 1) << 16);
- pi->dbdma_ring.stopping = 0;
- timeout = 10;
- while (in_le32(&pi->dbdma->status) & ACTIVE) {
- if (--timeout <= 0)
- break;
- udelay(1);
- }
- }
- }
- spin_unlock_irqrestore(&i2sdev->low_lock, flags);
-}
-
-#ifdef CONFIG_PM
-void i2sbus_wait_for_stop_both(struct i2sbus_dev *i2sdev)
-{
- struct pcm_info *pi;
-
- get_pcm_info(i2sdev, 0, &pi, NULL);
- i2sbus_wait_for_stop(i2sdev, pi);
- get_pcm_info(i2sdev, 1, &pi, NULL);
- i2sbus_wait_for_stop(i2sdev, pi);
-}
-#endif
-
-static int i2sbus_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
-}
-
-static inline int i2sbus_hw_free(struct snd_pcm_substream *substream, int in)
-{
- struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
- struct pcm_info *pi;
-
- get_pcm_info(i2sdev, in, &pi, NULL);
- if (pi->dbdma_ring.stopping)
- i2sbus_wait_for_stop(i2sdev, pi);
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-static int i2sbus_playback_hw_free(struct snd_pcm_substream *substream)
-{
- return i2sbus_hw_free(substream, 0);
-}
-
-static int i2sbus_record_hw_free(struct snd_pcm_substream *substream)
-{
- return i2sbus_hw_free(substream, 1);
-}
-
-static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in)
-{
- /* whee. Hard work now. The user has selected a bitrate
- * and bit format, so now we have to program our
- * I2S controller appropriately. */
- struct snd_pcm_runtime *runtime;
- struct dbdma_cmd *command;
- int i, periodsize, nperiods;
- dma_addr_t offset;
- struct bus_info bi;
- struct codec_info_item *cii;
- int sfr = 0; /* serial format register */
- int dws = 0; /* data word sizes reg */
- int input_16bit;
- struct pcm_info *pi, *other;
- int cnt;
- int result = 0;
- unsigned int cmd, stopaddr;
-
- mutex_lock(&i2sdev->lock);
-
- get_pcm_info(i2sdev, in, &pi, &other);
-
- if (pi->dbdma_ring.running) {
- result = -EBUSY;
- goto out_unlock;
- }
- if (pi->dbdma_ring.stopping)
- i2sbus_wait_for_stop(i2sdev, pi);
-
- if (!pi->substream || !pi->substream->runtime) {
- result = -EINVAL;
- goto out_unlock;
- }
-
- runtime = pi->substream->runtime;
- pi->active = 1;
- if (other->active &&
- ((i2sdev->format != runtime->format)
- || (i2sdev->rate != runtime->rate))) {
- result = -EINVAL;
- goto out_unlock;
- }
-
- i2sdev->format = runtime->format;
- i2sdev->rate = runtime->rate;
-
- periodsize = snd_pcm_lib_period_bytes(pi->substream);
- nperiods = pi->substream->runtime->periods;
- pi->current_period = 0;
-
- /* generate dbdma command ring first */
- command = pi->dbdma_ring.cmds;
- memset(command, 0, (nperiods + 2) * sizeof(struct dbdma_cmd));
-
- /* commands to DMA to/from the ring */
- /*
- * For input, we need to do a graceful stop; if we abort
- * the DMA, we end up with leftover bytes that corrupt
- * the next recording. To do this we set the S0 status
- * bit and wait for the DMA controller to stop. Each
- * command has a branch condition to
- * make it branch to a stop command if S0 is set.
- * On input we also need to wait for the S7 bit to be
- * set before turning off the DMA controller.
- * In fact we do the graceful stop for output as well.
- */
- offset = runtime->dma_addr;
- cmd = (in? INPUT_MORE: OUTPUT_MORE) | BR_IFSET | INTR_ALWAYS;
- stopaddr = pi->dbdma_ring.bus_cmd_start +
- (nperiods + 1) * sizeof(struct dbdma_cmd);
- for (i = 0; i < nperiods; i++, command++, offset += periodsize) {
- command->command = cpu_to_le16(cmd);
- command->cmd_dep = cpu_to_le32(stopaddr);
- command->phy_addr = cpu_to_le32(offset);
- command->req_count = cpu_to_le16(periodsize);
- }
-
- /* branch back to beginning of ring */
- command->command = cpu_to_le16(DBDMA_NOP | BR_ALWAYS);
- command->cmd_dep = cpu_to_le32(pi->dbdma_ring.bus_cmd_start);
- command++;
-
- /* set stop command */
- command->command = cpu_to_le16(DBDMA_STOP);
-
- /* ok, let's set the serial format and stuff */
- switch (runtime->format) {
- /* 16 bit formats */
- case SNDRV_PCM_FORMAT_S16_BE:
- case SNDRV_PCM_FORMAT_U16_BE:
- /* FIXME: if we add different bus factors we need to
- * do more here!! */
- bi.bus_factor = 0;
- list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
- bi.bus_factor = cii->codec->bus_factor;
- break;
- }
- if (!bi.bus_factor) {
- result = -ENODEV;
- goto out_unlock;
- }
- input_16bit = 1;
- break;
- case SNDRV_PCM_FORMAT_S32_BE:
- case SNDRV_PCM_FORMAT_U32_BE:
- /* force 64x bus speed, otherwise the data cannot be
- * transferred quickly enough! */
- bi.bus_factor = 64;
- input_16bit = 0;
- break;
- default:
- result = -EINVAL;
- goto out_unlock;
- }
- /* we assume all sysclocks are the same! */
- list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
- bi.sysclock_factor = cii->codec->sysclock_factor;
- break;
- }
-
- if (clock_and_divisors(bi.sysclock_factor,
- bi.bus_factor,
- runtime->rate,
- &sfr) < 0) {
- result = -EINVAL;
- goto out_unlock;
- }
- switch (bi.bus_factor) {
- case 32:
- sfr |= I2S_SF_SERIAL_FORMAT_I2S_32X;
- break;
- case 64:
- sfr |= I2S_SF_SERIAL_FORMAT_I2S_64X;
- break;
- }
- /* FIXME: THIS ASSUMES MASTER ALL THE TIME */
- sfr |= I2S_SF_SCLK_MASTER;
-
- list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
- int err = 0;
- if (cii->codec->prepare)
- err = cii->codec->prepare(cii, &bi, pi->substream);
- if (err) {
- result = err;
- goto out_unlock;
- }
- }
- /* codecs are fine with it, so set our clocks */
- if (input_16bit)
- dws = (2 << I2S_DWS_NUM_CHANNELS_IN_SHIFT) |
- (2 << I2S_DWS_NUM_CHANNELS_OUT_SHIFT) |
- I2S_DWS_DATA_IN_16BIT | I2S_DWS_DATA_OUT_16BIT;
- else
- dws = (2 << I2S_DWS_NUM_CHANNELS_IN_SHIFT) |
- (2 << I2S_DWS_NUM_CHANNELS_OUT_SHIFT) |
- I2S_DWS_DATA_IN_24BIT | I2S_DWS_DATA_OUT_24BIT;
-
- /* early exit if already programmed correctly */
- /* not locking these is fine since we touch them only in this function */
- if (in_le32(&i2sdev->intfregs->serial_format) == sfr
- && in_le32(&i2sdev->intfregs->data_word_sizes) == dws)
- goto out_unlock;
-
- /* let's notify the codecs about clocks going away.
- * For now we only do mastering on the i2s cell... */
- list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
- if (cii->codec->switch_clock)
- cii->codec->switch_clock(cii, CLOCK_SWITCH_PREPARE_SLAVE);
-
- i2sbus_control_enable(i2sdev->control, i2sdev);
- i2sbus_control_cell(i2sdev->control, i2sdev, 1);
-
- out_le32(&i2sdev->intfregs->intr_ctl, I2S_PENDING_CLOCKS_STOPPED);
-
- i2sbus_control_clock(i2sdev->control, i2sdev, 0);
-
- msleep(1);
-
- /* wait for clock stopped. This can apparently take a while... */
- cnt = 100;
- while (cnt-- &&
- !(in_le32(&i2sdev->intfregs->intr_ctl) & I2S_PENDING_CLOCKS_STOPPED)) {
- msleep(5);
- }
- out_le32(&i2sdev->intfregs->intr_ctl, I2S_PENDING_CLOCKS_STOPPED);
-
- /* not locking these is fine since we touch them only in this function */
- out_le32(&i2sdev->intfregs->serial_format, sfr);
- out_le32(&i2sdev->intfregs->data_word_sizes, dws);
-
- i2sbus_control_enable(i2sdev->control, i2sdev);
- i2sbus_control_cell(i2sdev->control, i2sdev, 1);
- i2sbus_control_clock(i2sdev->control, i2sdev, 1);
- msleep(1);
-
- list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
- if (cii->codec->switch_clock)
- cii->codec->switch_clock(cii, CLOCK_SWITCH_SLAVE);
-
- out_unlock:
- mutex_unlock(&i2sdev->lock);
- return result;
-}
-
-#ifdef CONFIG_PM
-void i2sbus_pcm_prepare_both(struct i2sbus_dev *i2sdev)
-{
- i2sbus_pcm_prepare(i2sdev, 0);
- i2sbus_pcm_prepare(i2sdev, 1);
-}
-#endif
-
-static int i2sbus_pcm_trigger(struct i2sbus_dev *i2sdev, int in, int cmd)
-{
- struct codec_info_item *cii;
- struct pcm_info *pi;
- int result = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&i2sdev->low_lock, flags);
-
- get_pcm_info(i2sdev, in, &pi, NULL);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- if (pi->dbdma_ring.running) {
- result = -EALREADY;
- goto out_unlock;
- }
- list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
- if (cii->codec->start)
- cii->codec->start(cii, pi->substream);
- pi->dbdma_ring.running = 1;
-
- if (pi->dbdma_ring.stopping) {
- /* Clear the S0 bit, then see if we stopped yet */
- out_le32(&pi->dbdma->control, 1 << 16);
- if (in_le32(&pi->dbdma->status) & ACTIVE) {
- /* possible race here? */
- udelay(10);
- if (in_le32(&pi->dbdma->status) & ACTIVE) {
- pi->dbdma_ring.stopping = 0;
- goto out_unlock; /* keep running */
- }
- }
- }
-
- /* make sure RUN, PAUSE and S0 bits are cleared */
- out_le32(&pi->dbdma->control, (RUN | PAUSE | 1) << 16);
-
- /* set branch condition select register */
- out_le32(&pi->dbdma->br_sel, (1 << 16) | 1);
-
- /* write dma command buffer address to the dbdma chip */
- out_le32(&pi->dbdma->cmdptr, pi->dbdma_ring.bus_cmd_start);
-
- /* initialize the frame count and current period */
- pi->current_period = 0;
- pi->frame_count = in_le32(&i2sdev->intfregs->frame_count);
-
- /* set the DMA controller running */
- out_le32(&pi->dbdma->control, (RUN << 16) | RUN);
-
- /* off you go! */
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- if (!pi->dbdma_ring.running) {
- result = -EALREADY;
- goto out_unlock;
- }
- pi->dbdma_ring.running = 0;
-
- /* Set the S0 bit to make the DMA branch to the stop cmd */
- out_le32(&pi->dbdma->control, (1 << 16) | 1);
- pi->dbdma_ring.stopping = 1;
-
- list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
- if (cii->codec->stop)
- cii->codec->stop(cii, pi->substream);
- break;
- default:
- result = -EINVAL;
- goto out_unlock;
- }
-
- out_unlock:
- spin_unlock_irqrestore(&i2sdev->low_lock, flags);
- return result;
-}
-
-static snd_pcm_uframes_t i2sbus_pcm_pointer(struct i2sbus_dev *i2sdev, int in)
-{
- struct pcm_info *pi;
- u32 fc;
-
- get_pcm_info(i2sdev, in, &pi, NULL);
-
- fc = in_le32(&i2sdev->intfregs->frame_count);
- fc = fc - pi->frame_count;
-
- if (fc >= pi->substream->runtime->buffer_size)
- fc %= pi->substream->runtime->buffer_size;
- return fc;
-}
-
-static inline void handle_interrupt(struct i2sbus_dev *i2sdev, int in)
-{
- struct pcm_info *pi;
- u32 fc, nframes;
- u32 status;
- int timeout, i;
- int dma_stopped = 0;
- struct snd_pcm_runtime *runtime;
-
- spin_lock(&i2sdev->low_lock);
- get_pcm_info(i2sdev, in, &pi, NULL);
- if (!pi->dbdma_ring.running && !pi->dbdma_ring.stopping)
- goto out_unlock;
-
- i = pi->current_period;
- runtime = pi->substream->runtime;
- while (pi->dbdma_ring.cmds[i].xfer_status) {
- if (le16_to_cpu(pi->dbdma_ring.cmds[i].xfer_status) & BT)
- /*
- * BT is the branch taken bit. If it took a branch
- * it is because we set the S0 bit to make it
- * branch to the stop command.
- */
- dma_stopped = 1;
- pi->dbdma_ring.cmds[i].xfer_status = 0;
-
- if (++i >= runtime->periods) {
- i = 0;
- pi->frame_count += runtime->buffer_size;
- }
- pi->current_period = i;
-
- /*
- * Check the frame count. The DMA tends to get a bit
- * ahead of the frame counter, which confuses the core.
- */
- fc = in_le32(&i2sdev->intfregs->frame_count);
- nframes = i * runtime->period_size;
- if (fc < pi->frame_count + nframes)
- pi->frame_count = fc - nframes;
- }
-
- if (dma_stopped) {
- timeout = 1000;
- for (;;) {
- status = in_le32(&pi->dbdma->status);
- if (!(status & ACTIVE) && (!in || (status & 0x80)))
- break;
- if (--timeout <= 0) {
- printk(KERN_ERR "i2sbus: timed out "
- "waiting for DMA to stop!\n");
- break;
- }
- udelay(1);
- }
-
- /* Turn off DMA controller, clear S0 bit */
- out_le32(&pi->dbdma->control, (RUN | PAUSE | 1) << 16);
-
- pi->dbdma_ring.stopping = 0;
- if (pi->stop_completion)
- complete(pi->stop_completion);
- }
-
- if (!pi->dbdma_ring.running)
- goto out_unlock;
- spin_unlock(&i2sdev->low_lock);
- /* may call _trigger again, hence needs to be unlocked */
- snd_pcm_period_elapsed(pi->substream);
- return;
-
- out_unlock:
- spin_unlock(&i2sdev->low_lock);
-}
-
-irqreturn_t i2sbus_tx_intr(int irq, void *devid)
-{
- handle_interrupt((struct i2sbus_dev *)devid, 0);
- return IRQ_HANDLED;
-}
-
-irqreturn_t i2sbus_rx_intr(int irq, void *devid)
-{
- handle_interrupt((struct i2sbus_dev *)devid, 1);
- return IRQ_HANDLED;
-}
-
-static int i2sbus_playback_open(struct snd_pcm_substream *substream)
-{
- struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
-
- if (!i2sdev)
- return -EINVAL;
- i2sdev->out.substream = substream;
- return i2sbus_pcm_open(i2sdev, 0);
-}
-
-static int i2sbus_playback_close(struct snd_pcm_substream *substream)
-{
- struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
- int err;
-
- if (!i2sdev)
- return -EINVAL;
- if (i2sdev->out.substream != substream)
- return -EINVAL;
- err = i2sbus_pcm_close(i2sdev, 0);
- if (!err)
- i2sdev->out.substream = NULL;
- return err;
-}
-
-static int i2sbus_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
-
- if (!i2sdev)
- return -EINVAL;
- if (i2sdev->out.substream != substream)
- return -EINVAL;
- return i2sbus_pcm_prepare(i2sdev, 0);
-}
-
-static int i2sbus_playback_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
-
- if (!i2sdev)
- return -EINVAL;
- if (i2sdev->out.substream != substream)
- return -EINVAL;
- return i2sbus_pcm_trigger(i2sdev, 0, cmd);
-}
-
-static snd_pcm_uframes_t i2sbus_playback_pointer(struct snd_pcm_substream
- *substream)
-{
- struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
-
- if (!i2sdev)
- return -EINVAL;
- if (i2sdev->out.substream != substream)
- return 0;
- return i2sbus_pcm_pointer(i2sdev, 0);
-}
-
-static struct snd_pcm_ops i2sbus_playback_ops = {
- .open = i2sbus_playback_open,
- .close = i2sbus_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = i2sbus_hw_params,
- .hw_free = i2sbus_playback_hw_free,
- .prepare = i2sbus_playback_prepare,
- .trigger = i2sbus_playback_trigger,
- .pointer = i2sbus_playback_pointer,
-};
-
-static int i2sbus_record_open(struct snd_pcm_substream *substream)
-{
- struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
-
- if (!i2sdev)
- return -EINVAL;
- i2sdev->in.substream = substream;
- return i2sbus_pcm_open(i2sdev, 1);
-}
-
-static int i2sbus_record_close(struct snd_pcm_substream *substream)
-{
- struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
- int err;
-
- if (!i2sdev)
- return -EINVAL;
- if (i2sdev->in.substream != substream)
- return -EINVAL;
- err = i2sbus_pcm_close(i2sdev, 1);
- if (!err)
- i2sdev->in.substream = NULL;
- return err;
-}
-
-static int i2sbus_record_prepare(struct snd_pcm_substream *substream)
-{
- struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
-
- if (!i2sdev)
- return -EINVAL;
- if (i2sdev->in.substream != substream)
- return -EINVAL;
- return i2sbus_pcm_prepare(i2sdev, 1);
-}
-
-static int i2sbus_record_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
-
- if (!i2sdev)
- return -EINVAL;
- if (i2sdev->in.substream != substream)
- return -EINVAL;
- return i2sbus_pcm_trigger(i2sdev, 1, cmd);
-}
-
-static snd_pcm_uframes_t i2sbus_record_pointer(struct snd_pcm_substream
- *substream)
-{
- struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
-
- if (!i2sdev)
- return -EINVAL;
- if (i2sdev->in.substream != substream)
- return 0;
- return i2sbus_pcm_pointer(i2sdev, 1);
-}
-
-static struct snd_pcm_ops i2sbus_record_ops = {
- .open = i2sbus_record_open,
- .close = i2sbus_record_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = i2sbus_hw_params,
- .hw_free = i2sbus_record_hw_free,
- .prepare = i2sbus_record_prepare,
- .trigger = i2sbus_record_trigger,
- .pointer = i2sbus_record_pointer,
-};
-
-static void i2sbus_private_free(struct snd_pcm *pcm)
-{
- struct i2sbus_dev *i2sdev = snd_pcm_chip(pcm);
- struct codec_info_item *p, *tmp;
-
- i2sdev->sound.pcm = NULL;
- i2sdev->out.created = 0;
- i2sdev->in.created = 0;
- list_for_each_entry_safe(p, tmp, &i2sdev->sound.codec_list, list) {
- printk(KERN_ERR "i2sbus: a codec didn't unregister!\n");
- list_del(&p->list);
- module_put(p->codec->owner);
- kfree(p);
- }
- soundbus_dev_put(&i2sdev->sound);
- module_put(THIS_MODULE);
-}
-
-int
-i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
- struct codec_info *ci, void *data)
-{
- int err, in = 0, out = 0;
- struct transfer_info *tmp;
- struct i2sbus_dev *i2sdev = soundbus_dev_to_i2sbus_dev(dev);
- struct codec_info_item *cii;
-
- if (!dev->pcmname || dev->pcmid == -1) {
- printk(KERN_ERR "i2sbus: pcm name and id must be set!\n");
- return -EINVAL;
- }
-
- list_for_each_entry(cii, &dev->codec_list, list) {
- if (cii->codec_data == data)
- return -EALREADY;
- }
-
- if (!ci->transfers || !ci->transfers->formats
- || !ci->transfers->rates || !ci->usable)
- return -EINVAL;
-
- /* we currently code the i2s transfer on the clock, and support only
- * 32 and 64 */
- if (ci->bus_factor != 32 && ci->bus_factor != 64)
- return -EINVAL;
-
- /* If you want to fix this, you need to keep track of what transport infos
- * are to be used, which codecs they belong to, and then fix all the
- * sysclock/busclock stuff above to depend on which is usable */
- list_for_each_entry(cii, &dev->codec_list, list) {
- if (cii->codec->sysclock_factor != ci->sysclock_factor) {
- printk(KERN_DEBUG
- "cannot yet handle multiple different sysclocks!\n");
- return -EINVAL;
- }
- if (cii->codec->bus_factor != ci->bus_factor) {
- printk(KERN_DEBUG
- "cannot yet handle multiple different bus clocks!\n");
- return -EINVAL;
- }
- }
-
- tmp = ci->transfers;
- while (tmp->formats && tmp->rates) {
- if (tmp->transfer_in)
- in = 1;
- else
- out = 1;
- tmp++;
- }
-
- cii = kzalloc(sizeof(struct codec_info_item), GFP_KERNEL);
- if (!cii) {
- printk(KERN_DEBUG "i2sbus: failed to allocate cii\n");
- return -ENOMEM;
- }
-
- /* use the private data to point to the codec info */
- cii->sdev = soundbus_dev_get(dev);
- cii->codec = ci;
- cii->codec_data = data;
-
- if (!cii->sdev) {
- printk(KERN_DEBUG
- "i2sbus: failed to get soundbus dev reference\n");
- err = -ENODEV;
- goto out_free_cii;
- }
-
- if (!try_module_get(THIS_MODULE)) {
- printk(KERN_DEBUG "i2sbus: failed to get module reference!\n");
- err = -EBUSY;
- goto out_put_sdev;
- }
-
- if (!try_module_get(ci->owner)) {
- printk(KERN_DEBUG
- "i2sbus: failed to get module reference to codec owner!\n");
- err = -EBUSY;
- goto out_put_this_module;
- }
-
- if (!dev->pcm) {
- err = snd_pcm_new(card, dev->pcmname, dev->pcmid, 0, 0,
- &dev->pcm);
- if (err) {
- printk(KERN_DEBUG "i2sbus: failed to create pcm\n");
- goto out_put_ci_module;
- }
- dev->pcm->dev = &dev->ofdev.dev;
- }
-
- /* ALSA yet again sucks.
- * If it is ever fixed, remove this line. See below. */
- out = in = 1;
-
- if (!i2sdev->out.created && out) {
- if (dev->pcm->card != card) {
- /* eh? */
- printk(KERN_ERR
- "Can't attach same bus to different cards!\n");
- err = -EINVAL;
- goto out_put_ci_module;
- }
- err = snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, 1);
- if (err)
- goto out_put_ci_module;
- snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &i2sbus_playback_ops);
- i2sdev->out.created = 1;
- }
-
- if (!i2sdev->in.created && in) {
- if (dev->pcm->card != card) {
- printk(KERN_ERR
- "Can't attach same bus to different cards!\n");
- err = -EINVAL;
- goto out_put_ci_module;
- }
- err = snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, 1);
- if (err)
- goto out_put_ci_module;
- snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE,
- &i2sbus_record_ops);
- i2sdev->in.created = 1;
- }
-
- /* so we have to register the pcm after adding any substream
- * to it because alsa doesn't create the devices for the
- * substreams when we add them later.
- * Therefore, force in and out on both busses (above) and
- * register the pcm now instead of just after creating it.
- */
- err = snd_device_register(card, dev->pcm);
- if (err) {
- printk(KERN_ERR "i2sbus: error registering new pcm\n");
- goto out_put_ci_module;
- }
- /* no errors any more, so let's add this to our list */
- list_add(&cii->list, &dev->codec_list);
-
- dev->pcm->private_data = i2sdev;
- dev->pcm->private_free = i2sbus_private_free;
-
- /* well, we really should support scatter/gather DMA */
- snd_pcm_lib_preallocate_pages_for_all(
- dev->pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(macio_get_pci_dev(i2sdev->macio)),
- 64 * 1024, 64 * 1024);
-
- return 0;
- out_put_ci_module:
- module_put(ci->owner);
- out_put_this_module:
- module_put(THIS_MODULE);
- out_put_sdev:
- soundbus_dev_put(dev);
- out_free_cii:
- kfree(cii);
- return err;
-}
-
-void i2sbus_detach_codec(struct soundbus_dev *dev, void *data)
-{
- struct codec_info_item *cii = NULL, *i;
-
- list_for_each_entry(i, &dev->codec_list, list) {
- if (i->codec_data == data) {
- cii = i;
- break;
- }
- }
- if (cii) {
- list_del(&cii->list);
- module_put(cii->codec->owner);
- kfree(cii);
- }
- /* no more codecs, but still a pcm? */
- if (list_empty(&dev->codec_list) && dev->pcm) {
- /* the actual cleanup is done by the callback above! */
- snd_device_free(dev->pcm->card, dev->pcm);
- }
-}
diff --git a/ANDROID_3.4.5/sound/aoa/soundbus/soundbus.h b/ANDROID_3.4.5/sound/aoa/soundbus/soundbus.h
deleted file mode 100644
index adecbf36..00000000
--- a/ANDROID_3.4.5/sound/aoa/soundbus/soundbus.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * soundbus generic definitions
- *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPL v2, can be found in COPYING.
- */
-#ifndef __SOUNDBUS_H
-#define __SOUNDBUS_H
-
-#include <linux/of_device.h>
-#include <sound/pcm.h>
-#include <linux/list.h>
-
-
-/* When switching from master to slave or the other way around,
- * you don't want to have the codec chip acting as clock source
- * while the bus still is.
- * More importantly, while switch from slave to master, you need
- * to turn off the chip's master function first, but then there's
- * no clock for a while and other chips might reset, so we notify
- * their drivers after having switched.
- * The constants here are codec-point of view, so when we switch
- * the soundbus to master we tell the codec we're going to switch
- * and give it CLOCK_SWITCH_PREPARE_SLAVE!
- */
-enum clock_switch {
- CLOCK_SWITCH_PREPARE_SLAVE,
- CLOCK_SWITCH_PREPARE_MASTER,
- CLOCK_SWITCH_SLAVE,
- CLOCK_SWITCH_MASTER,
- CLOCK_SWITCH_NOTIFY,
-};
-
-/* information on a transfer the codec can take */
-struct transfer_info {
- u64 formats; /* SNDRV_PCM_FMTBIT_* */
- unsigned int rates; /* SNDRV_PCM_RATE_* */
- /* flags */
- u32 transfer_in:1, /* input = 1, output = 0 */
- must_be_clock_source:1;
- /* for codecs to distinguish among their TIs */
- int tag;
-};
-
-struct codec_info_item {
- struct codec_info *codec;
- void *codec_data;
- struct soundbus_dev *sdev;
- /* internal, to be used by the soundbus provider */
- struct list_head list;
-};
-
-/* for prepare, where the codecs need to know
- * what we're going to drive the bus with */
-struct bus_info {
- /* see below */
- int sysclock_factor;
- int bus_factor;
-};
-
-/* information on the codec itself, plus function pointers */
-struct codec_info {
- /* the module this lives in */
- struct module *owner;
-
- /* supported transfer possibilities, array terminated by
- * formats or rates being 0. */
- struct transfer_info *transfers;
-
- /* Master clock speed factor
- * to be used (master clock speed = sysclock_factor * sampling freq)
- * Unused if the soundbus provider has no such notion.
- */
- int sysclock_factor;
-
- /* Bus factor, bus clock speed = bus_factor * sampling freq)
- * Unused if the soundbus provider has no such notion.
- */
- int bus_factor;
-
- /* operations */
- /* clock switching, see above */
- int (*switch_clock)(struct codec_info_item *cii,
- enum clock_switch clock);
-
- /* called for each transfer_info when the user
- * opens the pcm device to determine what the
- * hardware can support at this point in time.
- * That can depend on other user-switchable controls.
- * Return 1 if usable, 0 if not.
- * out points to another instance of a transfer_info
- * which is initialised to the values in *ti, and
- * it's format and rate values can be modified by
- * the callback if it is necessary to further restrict
- * the formats that can be used at the moment, for
- * example when one codec has multiple logical codec
- * info structs for multiple inputs.
- */
- int (*usable)(struct codec_info_item *cii,
- struct transfer_info *ti,
- struct transfer_info *out);
-
- /* called when pcm stream is opened, probably not implemented
- * most of the time since it isn't too useful */
- int (*open)(struct codec_info_item *cii,
- struct snd_pcm_substream *substream);
-
- /* called when the pcm stream is closed, at this point
- * the user choices can all be unlocked (see below) */
- int (*close)(struct codec_info_item *cii,
- struct snd_pcm_substream *substream);
-
- /* if the codec must forbid some user choices because
- * they are not valid with the substream/transfer info,
- * it must do so here. Example: no digital output for
- * incompatible framerate, say 8KHz, on Onyx.
- * If the selected stuff in the substream is NOT
- * compatible, you have to reject this call! */
- int (*prepare)(struct codec_info_item *cii,
- struct bus_info *bi,
- struct snd_pcm_substream *substream);
-
- /* start() is called before data is pushed to the codec.
- * Note that start() must be atomic! */
- int (*start)(struct codec_info_item *cii,
- struct snd_pcm_substream *substream);
-
- /* stop() is called after data is no longer pushed to the codec.
- * Note that stop() must be atomic! */
- int (*stop)(struct codec_info_item *cii,
- struct snd_pcm_substream *substream);
-
- int (*suspend)(struct codec_info_item *cii, pm_message_t state);
- int (*resume)(struct codec_info_item *cii);
-};
-
-/* information on a soundbus device */
-struct soundbus_dev {
- /* the bus it belongs to */
- struct list_head onbuslist;
-
- /* the of device it represents */
- struct platform_device ofdev;
-
- /* what modules go by */
- char modalias[32];
-
- /* These fields must be before attach_codec can be called.
- * They should be set by the owner of the alsa card object
- * that is needed, and whoever sets them must make sure
- * that they are unique within that alsa card object. */
- char *pcmname;
- int pcmid;
-
- /* this is assigned by the soundbus provider in attach_codec */
- struct snd_pcm *pcm;
-
- /* operations */
- /* attach a codec to this soundbus, give the alsa
- * card object the PCMs for this soundbus should be in.
- * The 'data' pointer must be unique, it is used as the
- * key for detach_codec(). */
- int (*attach_codec)(struct soundbus_dev *dev, struct snd_card *card,
- struct codec_info *ci, void *data);
- void (*detach_codec)(struct soundbus_dev *dev, void *data);
- /* TODO: suspend/resume */
-
- /* private for the soundbus provider */
- struct list_head codec_list;
- u32 have_out:1, have_in:1;
-};
-#define to_soundbus_device(d) container_of(d, struct soundbus_dev, ofdev.dev)
-#define of_to_soundbus_device(d) container_of(d, struct soundbus_dev, ofdev)
-
-extern int soundbus_add_one(struct soundbus_dev *dev);
-extern void soundbus_remove_one(struct soundbus_dev *dev);
-
-extern struct soundbus_dev *soundbus_dev_get(struct soundbus_dev *dev);
-extern void soundbus_dev_put(struct soundbus_dev *dev);
-
-struct soundbus_driver {
- char *name;
- struct module *owner;
-
- /* we don't implement any matching at all */
-
- int (*probe)(struct soundbus_dev* dev);
- int (*remove)(struct soundbus_dev* dev);
-
- int (*suspend)(struct soundbus_dev* dev, pm_message_t state);
- int (*resume)(struct soundbus_dev* dev);
- int (*shutdown)(struct soundbus_dev* dev);
-
- struct device_driver driver;
-};
-#define to_soundbus_driver(drv) container_of(drv,struct soundbus_driver, driver)
-
-extern int soundbus_register_driver(struct soundbus_driver *drv);
-extern void soundbus_unregister_driver(struct soundbus_driver *drv);
-
-extern struct device_attribute soundbus_dev_attrs[];
-
-#endif /* __SOUNDBUS_H */
diff --git a/ANDROID_3.4.5/sound/aoa/soundbus/sysfs.c b/ANDROID_3.4.5/sound/aoa/soundbus/sysfs.c
deleted file mode 100644
index e0980b5c..00000000
--- a/ANDROID_3.4.5/sound/aoa/soundbus/sysfs.c
+++ /dev/null
@@ -1,42 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/stat.h>
-/* FIX UP */
-#include "soundbus.h"
-
-#define soundbus_config_of_attr(field, format_string) \
-static ssize_t \
-field##_show (struct device *dev, struct device_attribute *attr, \
- char *buf) \
-{ \
- struct soundbus_dev *mdev = to_soundbus_device (dev); \
- return sprintf (buf, format_string, mdev->ofdev.dev.of_node->field); \
-}
-
-static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct soundbus_dev *sdev = to_soundbus_device(dev);
- struct platform_device *of = &sdev->ofdev;
- int length;
-
- if (*sdev->modalias) {
- strlcpy(buf, sdev->modalias, sizeof(sdev->modalias) + 1);
- strcat(buf, "\n");
- length = strlen(buf);
- } else {
- length = sprintf(buf, "of:N%sT%s\n",
- of->dev.of_node->name, of->dev.of_node->type);
- }
-
- return length;
-}
-
-soundbus_config_of_attr (name, "%s\n");
-soundbus_config_of_attr (type, "%s\n");
-
-struct device_attribute soundbus_dev_attrs[] = {
- __ATTR_RO(name),
- __ATTR_RO(type),
- __ATTR_RO(modalias),
- __ATTR_NULL
-};
diff --git a/ANDROID_3.4.5/sound/arm/Kconfig b/ANDROID_3.4.5/sound/arm/Kconfig
deleted file mode 100644
index 885683a3..00000000
--- a/ANDROID_3.4.5/sound/arm/Kconfig
+++ /dev/null
@@ -1,43 +0,0 @@
-# ALSA ARM drivers
-
-menuconfig SND_ARM
- bool "ARM sound devices"
- depends on ARM
- default y
- help
- Support for sound devices specific to ARM architectures.
- Drivers that are implemented on ASoC can be found in
- "ALSA for SoC audio support" section.
-
-if SND_ARM
-
-config SND_ARMAACI
- tristate "ARM PrimeCell PL041 AC Link support"
- depends on ARM_AMBA
- select SND_PCM
- select SND_AC97_CODEC
-
-config SND_PXA2XX_PCM
- tristate
- select SND_PCM
-
-config SND_PXA2XX_LIB
- tristate
- select SND_AC97_CODEC if SND_PXA2XX_LIB_AC97
-
-config SND_PXA2XX_LIB_AC97
- bool
-
-config SND_PXA2XX_AC97
- tristate "AC97 driver for the Intel PXA2xx chip"
- depends on ARCH_PXA
- select SND_PXA2XX_PCM
- select SND_AC97_CODEC
- select SND_PXA2XX_LIB
- select SND_PXA2XX_LIB_AC97
- help
- Say Y or M if you want to support any AC97 codec attached to
- the PXA2xx AC97 interface.
-
-endif # SND_ARM
-
diff --git a/ANDROID_3.4.5/sound/arm/Makefile b/ANDROID_3.4.5/sound/arm/Makefile
deleted file mode 100644
index 8c0c851d..00000000
--- a/ANDROID_3.4.5/sound/arm/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# Makefile for ALSA
-#
-
-obj-$(CONFIG_SND_ARMAACI) += snd-aaci.o
-snd-aaci-objs := aaci.o
-
-obj-$(CONFIG_SND_PXA2XX_PCM) += snd-pxa2xx-pcm.o
-snd-pxa2xx-pcm-objs := pxa2xx-pcm.o
-
-obj-$(CONFIG_SND_PXA2XX_LIB) += snd-pxa2xx-lib.o
-snd-pxa2xx-lib-y := pxa2xx-pcm-lib.o
-snd-pxa2xx-lib-$(CONFIG_SND_PXA2XX_LIB_AC97) += pxa2xx-ac97-lib.o
-
-obj-$(CONFIG_SND_PXA2XX_AC97) += snd-pxa2xx-ac97.o
-snd-pxa2xx-ac97-objs := pxa2xx-ac97.o
diff --git a/ANDROID_3.4.5/sound/arm/aaci.c b/ANDROID_3.4.5/sound/arm/aaci.c
deleted file mode 100644
index 5119fdab..00000000
--- a/ANDROID_3.4.5/sound/arm/aaci.c
+++ /dev/null
@@ -1,1116 +0,0 @@
-/*
- * linux/sound/arm/aaci.c - ARM PrimeCell AACI PL041 driver
- *
- * Copyright (C) 2003 Deep Blue Solutions Ltd, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Documentation: ARM DDI 0173B
- */
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/err.h>
-#include <linux/amba/bus.h>
-#include <linux/io.h>
-
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/ac97_codec.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-
-#include "aaci.h"
-
-#define DRIVER_NAME "aaci-pl041"
-
-#define FRAME_PERIOD_US 21
-
-/*
- * PM support is not complete. Turn it off.
- */
-#undef CONFIG_PM
-
-static void aaci_ac97_select_codec(struct aaci *aaci, struct snd_ac97 *ac97)
-{
- u32 v, maincr = aaci->maincr | MAINCR_SCRA(ac97->num);
-
- /*
- * Ensure that the slot 1/2 RX registers are empty.
- */
- v = readl(aaci->base + AACI_SLFR);
- if (v & SLFR_2RXV)
- readl(aaci->base + AACI_SL2RX);
- if (v & SLFR_1RXV)
- readl(aaci->base + AACI_SL1RX);
-
- if (maincr != readl(aaci->base + AACI_MAINCR)) {
- writel(maincr, aaci->base + AACI_MAINCR);
- readl(aaci->base + AACI_MAINCR);
- udelay(1);
- }
-}
-
-/*
- * P29:
- * The recommended use of programming the external codec through slot 1
- * and slot 2 data is to use the channels during setup routines and the
- * slot register at any other time. The data written into slot 1, slot 2
- * and slot 12 registers is transmitted only when their corresponding
- * SI1TxEn, SI2TxEn and SI12TxEn bits are set in the AACI_MAINCR
- * register.
- */
-static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short val)
-{
- struct aaci *aaci = ac97->private_data;
- int timeout;
- u32 v;
-
- if (ac97->num >= 4)
- return;
-
- mutex_lock(&aaci->ac97_sem);
-
- aaci_ac97_select_codec(aaci, ac97);
-
- /*
- * P54: You must ensure that AACI_SL2TX is always written
- * to, if required, before data is written to AACI_SL1TX.
- */
- writel(val << 4, aaci->base + AACI_SL2TX);
- writel(reg << 12, aaci->base + AACI_SL1TX);
-
- /* Initially, wait one frame period */
- udelay(FRAME_PERIOD_US);
-
- /* And then wait an additional eight frame periods for it to be sent */
- timeout = FRAME_PERIOD_US * 8;
- do {
- udelay(1);
- v = readl(aaci->base + AACI_SLFR);
- } while ((v & (SLFR_1TXB|SLFR_2TXB)) && --timeout);
-
- if (v & (SLFR_1TXB|SLFR_2TXB))
- dev_err(&aaci->dev->dev,
- "timeout waiting for write to complete\n");
-
- mutex_unlock(&aaci->ac97_sem);
-}
-
-/*
- * Read an AC'97 register.
- */
-static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
-{
- struct aaci *aaci = ac97->private_data;
- int timeout, retries = 10;
- u32 v;
-
- if (ac97->num >= 4)
- return ~0;
-
- mutex_lock(&aaci->ac97_sem);
-
- aaci_ac97_select_codec(aaci, ac97);
-
- /*
- * Write the register address to slot 1.
- */
- writel((reg << 12) | (1 << 19), aaci->base + AACI_SL1TX);
-
- /* Initially, wait one frame period */
- udelay(FRAME_PERIOD_US);
-
- /* And then wait an additional eight frame periods for it to be sent */
- timeout = FRAME_PERIOD_US * 8;
- do {
- udelay(1);
- v = readl(aaci->base + AACI_SLFR);
- } while ((v & SLFR_1TXB) && --timeout);
-
- if (v & SLFR_1TXB) {
- dev_err(&aaci->dev->dev, "timeout on slot 1 TX busy\n");
- v = ~0;
- goto out;
- }
-
- /* Now wait for the response frame */
- udelay(FRAME_PERIOD_US);
-
- /* And then wait an additional eight frame periods for data */
- timeout = FRAME_PERIOD_US * 8;
- do {
- udelay(1);
- cond_resched();
- v = readl(aaci->base + AACI_SLFR) & (SLFR_1RXV|SLFR_2RXV);
- } while ((v != (SLFR_1RXV|SLFR_2RXV)) && --timeout);
-
- if (v != (SLFR_1RXV|SLFR_2RXV)) {
- dev_err(&aaci->dev->dev, "timeout on RX valid\n");
- v = ~0;
- goto out;
- }
-
- do {
- v = readl(aaci->base + AACI_SL1RX) >> 12;
- if (v == reg) {
- v = readl(aaci->base + AACI_SL2RX) >> 4;
- break;
- } else if (--retries) {
- dev_warn(&aaci->dev->dev,
- "ac97 read back fail. retry\n");
- continue;
- } else {
- dev_warn(&aaci->dev->dev,
- "wrong ac97 register read back (%x != %x)\n",
- v, reg);
- v = ~0;
- }
- } while (retries);
- out:
- mutex_unlock(&aaci->ac97_sem);
- return v;
-}
-
-static inline void
-aaci_chan_wait_ready(struct aaci_runtime *aacirun, unsigned long mask)
-{
- u32 val;
- int timeout = 5000;
-
- do {
- udelay(1);
- val = readl(aacirun->base + AACI_SR);
- } while (val & mask && timeout--);
-}
-
-
-
-/*
- * Interrupt support.
- */
-static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
-{
- if (mask & ISR_ORINTR) {
- dev_warn(&aaci->dev->dev, "RX overrun on chan %d\n", channel);
- writel(ICLR_RXOEC1 << channel, aaci->base + AACI_INTCLR);
- }
-
- if (mask & ISR_RXTOINTR) {
- dev_warn(&aaci->dev->dev, "RX timeout on chan %d\n", channel);
- writel(ICLR_RXTOFEC1 << channel, aaci->base + AACI_INTCLR);
- }
-
- if (mask & ISR_RXINTR) {
- struct aaci_runtime *aacirun = &aaci->capture;
- bool period_elapsed = false;
- void *ptr;
-
- if (!aacirun->substream || !aacirun->start) {
- dev_warn(&aaci->dev->dev, "RX interrupt???\n");
- writel(0, aacirun->base + AACI_IE);
- return;
- }
-
- spin_lock(&aacirun->lock);
-
- ptr = aacirun->ptr;
- do {
- unsigned int len = aacirun->fifo_bytes;
- u32 val;
-
- if (aacirun->bytes <= 0) {
- aacirun->bytes += aacirun->period;
- period_elapsed = true;
- }
- if (!(aacirun->cr & CR_EN))
- break;
-
- val = readl(aacirun->base + AACI_SR);
- if (!(val & SR_RXHF))
- break;
- if (!(val & SR_RXFF))
- len >>= 1;
-
- aacirun->bytes -= len;
-
- /* reading 16 bytes at a time */
- for( ; len > 0; len -= 16) {
- asm(
- "ldmia %1, {r0, r1, r2, r3}\n\t"
- "stmia %0!, {r0, r1, r2, r3}"
- : "+r" (ptr)
- : "r" (aacirun->fifo)
- : "r0", "r1", "r2", "r3", "cc");
-
- if (ptr >= aacirun->end)
- ptr = aacirun->start;
- }
- } while(1);
-
- aacirun->ptr = ptr;
-
- spin_unlock(&aacirun->lock);
-
- if (period_elapsed)
- snd_pcm_period_elapsed(aacirun->substream);
- }
-
- if (mask & ISR_URINTR) {
- dev_dbg(&aaci->dev->dev, "TX underrun on chan %d\n", channel);
- writel(ICLR_TXUEC1 << channel, aaci->base + AACI_INTCLR);
- }
-
- if (mask & ISR_TXINTR) {
- struct aaci_runtime *aacirun = &aaci->playback;
- bool period_elapsed = false;
- void *ptr;
-
- if (!aacirun->substream || !aacirun->start) {
- dev_warn(&aaci->dev->dev, "TX interrupt???\n");
- writel(0, aacirun->base + AACI_IE);
- return;
- }
-
- spin_lock(&aacirun->lock);
-
- ptr = aacirun->ptr;
- do {
- unsigned int len = aacirun->fifo_bytes;
- u32 val;
-
- if (aacirun->bytes <= 0) {
- aacirun->bytes += aacirun->period;
- period_elapsed = true;
- }
- if (!(aacirun->cr & CR_EN))
- break;
-
- val = readl(aacirun->base + AACI_SR);
- if (!(val & SR_TXHE))
- break;
- if (!(val & SR_TXFE))
- len >>= 1;
-
- aacirun->bytes -= len;
-
- /* writing 16 bytes at a time */
- for ( ; len > 0; len -= 16) {
- asm(
- "ldmia %0!, {r0, r1, r2, r3}\n\t"
- "stmia %1, {r0, r1, r2, r3}"
- : "+r" (ptr)
- : "r" (aacirun->fifo)
- : "r0", "r1", "r2", "r3", "cc");
-
- if (ptr >= aacirun->end)
- ptr = aacirun->start;
- }
- } while (1);
-
- aacirun->ptr = ptr;
-
- spin_unlock(&aacirun->lock);
-
- if (period_elapsed)
- snd_pcm_period_elapsed(aacirun->substream);
- }
-}
-
-static irqreturn_t aaci_irq(int irq, void *devid)
-{
- struct aaci *aaci = devid;
- u32 mask;
- int i;
-
- mask = readl(aaci->base + AACI_ALLINTS);
- if (mask) {
- u32 m = mask;
- for (i = 0; i < 4; i++, m >>= 7) {
- if (m & 0x7f) {
- aaci_fifo_irq(aaci, i, m);
- }
- }
- }
-
- return mask ? IRQ_HANDLED : IRQ_NONE;
-}
-
-
-
-/*
- * ALSA support.
- */
-static struct snd_pcm_hardware aaci_hw_info = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_RESUME,
-
- /*
- * ALSA doesn't support 18-bit or 20-bit packed into 32-bit
- * words. It also doesn't support 12-bit at all.
- */
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
-
- /* rates are setup from the AC'97 codec */
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 64 * 1024,
- .period_bytes_min = 256,
- .period_bytes_max = PAGE_SIZE,
- .periods_min = 4,
- .periods_max = PAGE_SIZE / 16,
-};
-
-/*
- * We can support two and four channel audio. Unfortunately
- * six channel audio requires a non-standard channel ordering:
- * 2 -> FL(3), FR(4)
- * 4 -> FL(3), FR(4), SL(7), SR(8)
- * 6 -> FL(3), FR(4), SL(7), SR(8), C(6), LFE(9) (required)
- * FL(3), FR(4), C(6), SL(7), SR(8), LFE(9) (actual)
- * This requires an ALSA configuration file to correct.
- */
-static int aaci_rule_channels(struct snd_pcm_hw_params *p,
- struct snd_pcm_hw_rule *rule)
-{
- static unsigned int channel_list[] = { 2, 4, 6 };
- struct aaci *aaci = rule->private;
- unsigned int mask = 1 << 0, slots;
-
- /* pcms[0] is the our 5.1 PCM instance. */
- slots = aaci->ac97_bus->pcms[0].r[0].slots;
- if (slots & (1 << AC97_SLOT_PCM_SLEFT)) {
- mask |= 1 << 1;
- if (slots & (1 << AC97_SLOT_LFE))
- mask |= 1 << 2;
- }
-
- return snd_interval_list(hw_param_interval(p, rule->var),
- ARRAY_SIZE(channel_list), channel_list, mask);
-}
-
-static int aaci_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct aaci *aaci = substream->private_data;
- struct aaci_runtime *aacirun;
- int ret = 0;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- aacirun = &aaci->playback;
- } else {
- aacirun = &aaci->capture;
- }
-
- aacirun->substream = substream;
- runtime->private_data = aacirun;
- runtime->hw = aaci_hw_info;
- runtime->hw.rates = aacirun->pcm->rates;
- snd_pcm_limit_hw_rates(runtime);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- runtime->hw.channels_max = 6;
-
- /* Add rule describing channel dependency. */
- ret = snd_pcm_hw_rule_add(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- aaci_rule_channels, aaci,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
- if (ret)
- return ret;
-
- if (aacirun->pcm->r[1].slots)
- snd_ac97_pcm_double_rate_rules(runtime);
- }
-
- /*
- * ALSA wants the byte-size of the FIFOs. As we only support
- * 16-bit samples, this is twice the FIFO depth irrespective
- * of whether it's in compact mode or not.
- */
- runtime->hw.fifo_size = aaci->fifo_depth * 2;
-
- mutex_lock(&aaci->irq_lock);
- if (!aaci->users++) {
- ret = request_irq(aaci->dev->irq[0], aaci_irq,
- IRQF_SHARED, DRIVER_NAME, aaci);
- if (ret != 0)
- aaci->users--;
- }
- mutex_unlock(&aaci->irq_lock);
-
- return ret;
-}
-
-
-/*
- * Common ALSA stuff
- */
-static int aaci_pcm_close(struct snd_pcm_substream *substream)
-{
- struct aaci *aaci = substream->private_data;
- struct aaci_runtime *aacirun = substream->runtime->private_data;
-
- WARN_ON(aacirun->cr & CR_EN);
-
- aacirun->substream = NULL;
-
- mutex_lock(&aaci->irq_lock);
- if (!--aaci->users)
- free_irq(aaci->dev->irq[0], aaci);
- mutex_unlock(&aaci->irq_lock);
-
- return 0;
-}
-
-static int aaci_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct aaci_runtime *aacirun = substream->runtime->private_data;
-
- /*
- * This must not be called with the device enabled.
- */
- WARN_ON(aacirun->cr & CR_EN);
-
- if (aacirun->pcm_open)
- snd_ac97_pcm_close(aacirun->pcm);
- aacirun->pcm_open = 0;
-
- /*
- * Clear out the DMA and any allocated buffers.
- */
- snd_pcm_lib_free_pages(substream);
-
- return 0;
-}
-
-/* Channel to slot mask */
-static const u32 channels_to_slotmask[] = {
- [2] = CR_SL3 | CR_SL4,
- [4] = CR_SL3 | CR_SL4 | CR_SL7 | CR_SL8,
- [6] = CR_SL3 | CR_SL4 | CR_SL7 | CR_SL8 | CR_SL6 | CR_SL9,
-};
-
-static int aaci_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct aaci_runtime *aacirun = substream->runtime->private_data;
- unsigned int channels = params_channels(params);
- unsigned int rate = params_rate(params);
- int dbl = rate > 48000;
- int err;
-
- aaci_pcm_hw_free(substream);
- if (aacirun->pcm_open) {
- snd_ac97_pcm_close(aacirun->pcm);
- aacirun->pcm_open = 0;
- }
-
- /* channels is already limited to 2, 4, or 6 by aaci_rule_channels */
- if (dbl && channels != 2)
- return -EINVAL;
-
- err = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(params));
- if (err >= 0) {
- struct aaci *aaci = substream->private_data;
-
- err = snd_ac97_pcm_open(aacirun->pcm, rate, channels,
- aacirun->pcm->r[dbl].slots);
-
- aacirun->pcm_open = err == 0;
- aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16;
- aacirun->cr |= channels_to_slotmask[channels + dbl * 2];
-
- /*
- * fifo_bytes is the number of bytes we transfer to/from
- * the FIFO, including padding. So that's x4. As we're
- * in compact mode, the FIFO is half the size.
- */
- aacirun->fifo_bytes = aaci->fifo_depth * 4 / 2;
- }
-
- return err;
-}
-
-static int aaci_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct aaci_runtime *aacirun = runtime->private_data;
-
- aacirun->period = snd_pcm_lib_period_bytes(substream);
- aacirun->start = runtime->dma_area;
- aacirun->end = aacirun->start + snd_pcm_lib_buffer_bytes(substream);
- aacirun->ptr = aacirun->start;
- aacirun->bytes = aacirun->period;
-
- return 0;
-}
-
-static snd_pcm_uframes_t aaci_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct aaci_runtime *aacirun = runtime->private_data;
- ssize_t bytes = aacirun->ptr - aacirun->start;
-
- return bytes_to_frames(runtime, bytes);
-}
-
-
-/*
- * Playback specific ALSA stuff
- */
-static void aaci_pcm_playback_stop(struct aaci_runtime *aacirun)
-{
- u32 ie;
-
- ie = readl(aacirun->base + AACI_IE);
- ie &= ~(IE_URIE|IE_TXIE);
- writel(ie, aacirun->base + AACI_IE);
- aacirun->cr &= ~CR_EN;
- aaci_chan_wait_ready(aacirun, SR_TXB);
- writel(aacirun->cr, aacirun->base + AACI_TXCR);
-}
-
-static void aaci_pcm_playback_start(struct aaci_runtime *aacirun)
-{
- u32 ie;
-
- aaci_chan_wait_ready(aacirun, SR_TXB);
- aacirun->cr |= CR_EN;
-
- ie = readl(aacirun->base + AACI_IE);
- ie |= IE_URIE | IE_TXIE;
- writel(ie, aacirun->base + AACI_IE);
- writel(aacirun->cr, aacirun->base + AACI_TXCR);
-}
-
-static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct aaci_runtime *aacirun = substream->runtime->private_data;
- unsigned long flags;
- int ret = 0;
-
- spin_lock_irqsave(&aacirun->lock, flags);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- aaci_pcm_playback_start(aacirun);
- break;
-
- case SNDRV_PCM_TRIGGER_RESUME:
- aaci_pcm_playback_start(aacirun);
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- aaci_pcm_playback_stop(aacirun);
- break;
-
- case SNDRV_PCM_TRIGGER_SUSPEND:
- aaci_pcm_playback_stop(aacirun);
- break;
-
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- break;
-
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- break;
-
- default:
- ret = -EINVAL;
- }
-
- spin_unlock_irqrestore(&aacirun->lock, flags);
-
- return ret;
-}
-
-static struct snd_pcm_ops aaci_playback_ops = {
- .open = aaci_pcm_open,
- .close = aaci_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = aaci_pcm_hw_params,
- .hw_free = aaci_pcm_hw_free,
- .prepare = aaci_pcm_prepare,
- .trigger = aaci_pcm_playback_trigger,
- .pointer = aaci_pcm_pointer,
-};
-
-static void aaci_pcm_capture_stop(struct aaci_runtime *aacirun)
-{
- u32 ie;
-
- aaci_chan_wait_ready(aacirun, SR_RXB);
-
- ie = readl(aacirun->base + AACI_IE);
- ie &= ~(IE_ORIE | IE_RXIE);
- writel(ie, aacirun->base+AACI_IE);
-
- aacirun->cr &= ~CR_EN;
-
- writel(aacirun->cr, aacirun->base + AACI_RXCR);
-}
-
-static void aaci_pcm_capture_start(struct aaci_runtime *aacirun)
-{
- u32 ie;
-
- aaci_chan_wait_ready(aacirun, SR_RXB);
-
-#ifdef DEBUG
- /* RX Timeout value: bits 28:17 in RXCR */
- aacirun->cr |= 0xf << 17;
-#endif
-
- aacirun->cr |= CR_EN;
- writel(aacirun->cr, aacirun->base + AACI_RXCR);
-
- ie = readl(aacirun->base + AACI_IE);
- ie |= IE_ORIE |IE_RXIE; // overrun and rx interrupt -- half full
- writel(ie, aacirun->base + AACI_IE);
-}
-
-static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct aaci_runtime *aacirun = substream->runtime->private_data;
- unsigned long flags;
- int ret = 0;
-
- spin_lock_irqsave(&aacirun->lock, flags);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- aaci_pcm_capture_start(aacirun);
- break;
-
- case SNDRV_PCM_TRIGGER_RESUME:
- aaci_pcm_capture_start(aacirun);
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- aaci_pcm_capture_stop(aacirun);
- break;
-
- case SNDRV_PCM_TRIGGER_SUSPEND:
- aaci_pcm_capture_stop(aacirun);
- break;
-
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- break;
-
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- break;
-
- default:
- ret = -EINVAL;
- }
-
- spin_unlock_irqrestore(&aacirun->lock, flags);
-
- return ret;
-}
-
-static int aaci_pcm_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct aaci *aaci = substream->private_data;
-
- aaci_pcm_prepare(substream);
-
- /* allow changing of sample rate */
- aaci_ac97_write(aaci->ac97, AC97_EXTENDED_STATUS, 0x0001); /* VRA */
- aaci_ac97_write(aaci->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
- aaci_ac97_write(aaci->ac97, AC97_PCM_MIC_ADC_RATE, runtime->rate);
-
- /* Record select: Mic: 0, Aux: 3, Line: 4 */
- aaci_ac97_write(aaci->ac97, AC97_REC_SEL, 0x0404);
-
- return 0;
-}
-
-static struct snd_pcm_ops aaci_capture_ops = {
- .open = aaci_pcm_open,
- .close = aaci_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = aaci_pcm_hw_params,
- .hw_free = aaci_pcm_hw_free,
- .prepare = aaci_pcm_capture_prepare,
- .trigger = aaci_pcm_capture_trigger,
- .pointer = aaci_pcm_pointer,
-};
-
-/*
- * Power Management.
- */
-#ifdef CONFIG_PM
-static int aaci_do_suspend(struct snd_card *card, unsigned int state)
-{
- struct aaci *aaci = card->private_data;
- snd_power_change_state(card, SNDRV_CTL_POWER_D3cold);
- snd_pcm_suspend_all(aaci->pcm);
- return 0;
-}
-
-static int aaci_do_resume(struct snd_card *card, unsigned int state)
-{
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-
-static int aaci_suspend(struct amba_device *dev, pm_message_t state)
-{
- struct snd_card *card = amba_get_drvdata(dev);
- return card ? aaci_do_suspend(card) : 0;
-}
-
-static int aaci_resume(struct amba_device *dev)
-{
- struct snd_card *card = amba_get_drvdata(dev);
- return card ? aaci_do_resume(card) : 0;
-}
-#else
-#define aaci_do_suspend NULL
-#define aaci_do_resume NULL
-#define aaci_suspend NULL
-#define aaci_resume NULL
-#endif
-
-
-static struct ac97_pcm ac97_defs[] __devinitdata = {
- [0] = { /* Front PCM */
- .exclusive = 1,
- .r = {
- [0] = {
- .slots = (1 << AC97_SLOT_PCM_LEFT) |
- (1 << AC97_SLOT_PCM_RIGHT) |
- (1 << AC97_SLOT_PCM_CENTER) |
- (1 << AC97_SLOT_PCM_SLEFT) |
- (1 << AC97_SLOT_PCM_SRIGHT) |
- (1 << AC97_SLOT_LFE),
- },
- [1] = {
- .slots = (1 << AC97_SLOT_PCM_LEFT) |
- (1 << AC97_SLOT_PCM_RIGHT) |
- (1 << AC97_SLOT_PCM_LEFT_0) |
- (1 << AC97_SLOT_PCM_RIGHT_0),
- },
- },
- },
- [1] = { /* PCM in */
- .stream = 1,
- .exclusive = 1,
- .r = {
- [0] = {
- .slots = (1 << AC97_SLOT_PCM_LEFT) |
- (1 << AC97_SLOT_PCM_RIGHT),
- },
- },
- },
- [2] = { /* Mic in */
- .stream = 1,
- .exclusive = 1,
- .r = {
- [0] = {
- .slots = (1 << AC97_SLOT_MIC),
- },
- },
- }
-};
-
-static struct snd_ac97_bus_ops aaci_bus_ops = {
- .write = aaci_ac97_write,
- .read = aaci_ac97_read,
-};
-
-static int __devinit aaci_probe_ac97(struct aaci *aaci)
-{
- struct snd_ac97_template ac97_template;
- struct snd_ac97_bus *ac97_bus;
- struct snd_ac97 *ac97;
- int ret;
-
- /*
- * Assert AACIRESET for 2us
- */
- writel(0, aaci->base + AACI_RESET);
- udelay(2);
- writel(RESET_NRST, aaci->base + AACI_RESET);
-
- /*
- * Give the AC'97 codec more than enough time
- * to wake up. (42us = ~2 frames at 48kHz.)
- */
- udelay(FRAME_PERIOD_US * 2);
-
- ret = snd_ac97_bus(aaci->card, 0, &aaci_bus_ops, aaci, &ac97_bus);
- if (ret)
- goto out;
-
- ac97_bus->clock = 48000;
- aaci->ac97_bus = ac97_bus;
-
- memset(&ac97_template, 0, sizeof(struct snd_ac97_template));
- ac97_template.private_data = aaci;
- ac97_template.num = 0;
- ac97_template.scaps = AC97_SCAP_SKIP_MODEM;
-
- ret = snd_ac97_mixer(ac97_bus, &ac97_template, &ac97);
- if (ret)
- goto out;
- aaci->ac97 = ac97;
-
- /*
- * Disable AC97 PC Beep input on audio codecs.
- */
- if (ac97_is_audio(ac97))
- snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x801e);
-
- ret = snd_ac97_pcm_assign(ac97_bus, ARRAY_SIZE(ac97_defs), ac97_defs);
- if (ret)
- goto out;
-
- aaci->playback.pcm = &ac97_bus->pcms[0];
- aaci->capture.pcm = &ac97_bus->pcms[1];
-
- out:
- return ret;
-}
-
-static void aaci_free_card(struct snd_card *card)
-{
- struct aaci *aaci = card->private_data;
- if (aaci->base)
- iounmap(aaci->base);
-}
-
-static struct aaci * __devinit aaci_init_card(struct amba_device *dev)
-{
- struct aaci *aaci;
- struct snd_card *card;
- int err;
-
- err = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
- THIS_MODULE, sizeof(struct aaci), &card);
- if (err < 0)
- return NULL;
-
- card->private_free = aaci_free_card;
-
- strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver));
- strlcpy(card->shortname, "ARM AC'97 Interface", sizeof(card->shortname));
- snprintf(card->longname, sizeof(card->longname),
- "%s PL%03x rev%u at 0x%08llx, irq %d",
- card->shortname, amba_part(dev), amba_rev(dev),
- (unsigned long long)dev->res.start, dev->irq[0]);
-
- aaci = card->private_data;
- mutex_init(&aaci->ac97_sem);
- mutex_init(&aaci->irq_lock);
- aaci->card = card;
- aaci->dev = dev;
-
- /* Set MAINCR to allow slot 1 and 2 data IO */
- aaci->maincr = MAINCR_IE | MAINCR_SL1RXEN | MAINCR_SL1TXEN |
- MAINCR_SL2RXEN | MAINCR_SL2TXEN;
-
- return aaci;
-}
-
-static int __devinit aaci_init_pcm(struct aaci *aaci)
-{
- struct snd_pcm *pcm;
- int ret;
-
- ret = snd_pcm_new(aaci->card, "AACI AC'97", 0, 1, 1, &pcm);
- if (ret == 0) {
- aaci->pcm = pcm;
- pcm->private_data = aaci;
- pcm->info_flags = 0;
-
- strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name));
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops);
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- NULL, 0, 64 * 1024);
- }
-
- return ret;
-}
-
-static unsigned int __devinit aaci_size_fifo(struct aaci *aaci)
-{
- struct aaci_runtime *aacirun = &aaci->playback;
- int i;
-
- /*
- * Enable the channel, but don't assign it to any slots, so
- * it won't empty onto the AC'97 link.
- */
- writel(CR_FEN | CR_SZ16 | CR_EN, aacirun->base + AACI_TXCR);
-
- for (i = 0; !(readl(aacirun->base + AACI_SR) & SR_TXFF) && i < 4096; i++)
- writel(0, aacirun->fifo);
-
- writel(0, aacirun->base + AACI_TXCR);
-
- /*
- * Re-initialise the AACI after the FIFO depth test, to
- * ensure that the FIFOs are empty. Unfortunately, merely
- * disabling the channel doesn't clear the FIFO.
- */
- writel(aaci->maincr & ~MAINCR_IE, aaci->base + AACI_MAINCR);
- readl(aaci->base + AACI_MAINCR);
- udelay(1);
- writel(aaci->maincr, aaci->base + AACI_MAINCR);
-
- /*
- * If we hit 4096 entries, we failed. Go back to the specified
- * fifo depth.
- */
- if (i == 4096)
- i = 8;
-
- return i;
-}
-
-static int __devinit aaci_probe(struct amba_device *dev,
- const struct amba_id *id)
-{
- struct aaci *aaci;
- int ret, i;
-
- ret = amba_request_regions(dev, NULL);
- if (ret)
- return ret;
-
- aaci = aaci_init_card(dev);
- if (!aaci) {
- ret = -ENOMEM;
- goto out;
- }
-
- aaci->base = ioremap(dev->res.start, resource_size(&dev->res));
- if (!aaci->base) {
- ret = -ENOMEM;
- goto out;
- }
-
- /*
- * Playback uses AACI channel 0
- */
- spin_lock_init(&aaci->playback.lock);
- aaci->playback.base = aaci->base + AACI_CSCH1;
- aaci->playback.fifo = aaci->base + AACI_DR1;
-
- /*
- * Capture uses AACI channel 0
- */
- spin_lock_init(&aaci->capture.lock);
- aaci->capture.base = aaci->base + AACI_CSCH1;
- aaci->capture.fifo = aaci->base + AACI_DR1;
-
- for (i = 0; i < 4; i++) {
- void __iomem *base = aaci->base + i * 0x14;
-
- writel(0, base + AACI_IE);
- writel(0, base + AACI_TXCR);
- writel(0, base + AACI_RXCR);
- }
-
- writel(0x1fff, aaci->base + AACI_INTCLR);
- writel(aaci->maincr, aaci->base + AACI_MAINCR);
- /*
- * Fix: ac97 read back fail errors by reading
- * from any arbitrary aaci register.
- */
- readl(aaci->base + AACI_CSCH1);
- ret = aaci_probe_ac97(aaci);
- if (ret)
- goto out;
-
- /*
- * Size the FIFOs (must be multiple of 16).
- * This is the number of entries in the FIFO.
- */
- aaci->fifo_depth = aaci_size_fifo(aaci);
- if (aaci->fifo_depth & 15) {
- printk(KERN_WARNING "AACI: FIFO depth %d not supported\n",
- aaci->fifo_depth);
- ret = -ENODEV;
- goto out;
- }
-
- ret = aaci_init_pcm(aaci);
- if (ret)
- goto out;
-
- snd_card_set_dev(aaci->card, &dev->dev);
-
- ret = snd_card_register(aaci->card);
- if (ret == 0) {
- dev_info(&dev->dev, "%s\n", aaci->card->longname);
- dev_info(&dev->dev, "FIFO %u entries\n", aaci->fifo_depth);
- amba_set_drvdata(dev, aaci->card);
- return ret;
- }
-
- out:
- if (aaci)
- snd_card_free(aaci->card);
- amba_release_regions(dev);
- return ret;
-}
-
-static int __devexit aaci_remove(struct amba_device *dev)
-{
- struct snd_card *card = amba_get_drvdata(dev);
-
- amba_set_drvdata(dev, NULL);
-
- if (card) {
- struct aaci *aaci = card->private_data;
- writel(0, aaci->base + AACI_MAINCR);
-
- snd_card_free(card);
- amba_release_regions(dev);
- }
-
- return 0;
-}
-
-static struct amba_id aaci_ids[] = {
- {
- .id = 0x00041041,
- .mask = 0x000fffff,
- },
- { 0, 0 },
-};
-
-MODULE_DEVICE_TABLE(amba, aaci_ids);
-
-static struct amba_driver aaci_driver = {
- .drv = {
- .name = DRIVER_NAME,
- },
- .probe = aaci_probe,
- .remove = __devexit_p(aaci_remove),
- .suspend = aaci_suspend,
- .resume = aaci_resume,
- .id_table = aaci_ids,
-};
-
-module_amba_driver(aaci_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("ARM PrimeCell PL041 Advanced Audio CODEC Interface driver");
diff --git a/ANDROID_3.4.5/sound/arm/aaci.h b/ANDROID_3.4.5/sound/arm/aaci.h
deleted file mode 100644
index 5791bd5b..00000000
--- a/ANDROID_3.4.5/sound/arm/aaci.h
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * linux/sound/arm/aaci.c - ARM PrimeCell AACI PL041 driver
- *
- * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef AACI_H
-#define AACI_H
-
-/*
- * Control and status register offsets
- * P39.
- */
-#define AACI_CSCH1 0x000
-#define AACI_CSCH2 0x014
-#define AACI_CSCH3 0x028
-#define AACI_CSCH4 0x03c
-
-#define AACI_RXCR 0x000 /* 29 bits Control Rx FIFO */
-#define AACI_TXCR 0x004 /* 17 bits Control Tx FIFO */
-#define AACI_SR 0x008 /* 12 bits Status */
-#define AACI_ISR 0x00c /* 7 bits Int Status */
-#define AACI_IE 0x010 /* 7 bits Int Enable */
-
-/*
- * Other registers
- */
-#define AACI_SL1RX 0x050
-#define AACI_SL1TX 0x054
-#define AACI_SL2RX 0x058
-#define AACI_SL2TX 0x05c
-#define AACI_SL12RX 0x060
-#define AACI_SL12TX 0x064
-#define AACI_SLFR 0x068 /* slot flags */
-#define AACI_SLISTAT 0x06c /* slot interrupt status */
-#define AACI_SLIEN 0x070 /* slot interrupt enable */
-#define AACI_INTCLR 0x074 /* interrupt clear */
-#define AACI_MAINCR 0x078 /* main control */
-#define AACI_RESET 0x07c /* reset control */
-#define AACI_SYNC 0x080 /* sync control */
-#define AACI_ALLINTS 0x084 /* all fifo interrupt status */
-#define AACI_MAINFR 0x088 /* main flag register */
-#define AACI_DR1 0x090 /* data read/written fifo 1 */
-#define AACI_DR2 0x0b0 /* data read/written fifo 2 */
-#define AACI_DR3 0x0d0 /* data read/written fifo 3 */
-#define AACI_DR4 0x0f0 /* data read/written fifo 4 */
-
-/*
- * TX/RX fifo control register (CR). P48
- */
-#define CR_FEN (1 << 16) /* fifo enable */
-#define CR_COMPACT (1 << 15) /* compact mode */
-#define CR_SZ16 (0 << 13) /* 16 bits */
-#define CR_SZ18 (1 << 13) /* 18 bits */
-#define CR_SZ20 (2 << 13) /* 20 bits */
-#define CR_SZ12 (3 << 13) /* 12 bits */
-#define CR_SL12 (1 << 12)
-#define CR_SL11 (1 << 11)
-#define CR_SL10 (1 << 10)
-#define CR_SL9 (1 << 9)
-#define CR_SL8 (1 << 8)
-#define CR_SL7 (1 << 7)
-#define CR_SL6 (1 << 6)
-#define CR_SL5 (1 << 5)
-#define CR_SL4 (1 << 4)
-#define CR_SL3 (1 << 3)
-#define CR_SL2 (1 << 2)
-#define CR_SL1 (1 << 1)
-#define CR_EN (1 << 0) /* transmit enable */
-
-/*
- * status register bits. P49
- */
-#define SR_RXTOFE (1 << 11) /* rx timeout fifo empty */
-#define SR_TXTO (1 << 10) /* rx timeout fifo nonempty */
-#define SR_TXU (1 << 9) /* tx underrun */
-#define SR_RXO (1 << 8) /* rx overrun */
-#define SR_TXB (1 << 7) /* tx busy */
-#define SR_RXB (1 << 6) /* rx busy */
-#define SR_TXFF (1 << 5) /* tx fifo full */
-#define SR_RXFF (1 << 4) /* rx fifo full */
-#define SR_TXHE (1 << 3) /* tx fifo half empty */
-#define SR_RXHF (1 << 2) /* rx fifo half full */
-#define SR_TXFE (1 << 1) /* tx fifo empty */
-#define SR_RXFE (1 << 0) /* rx fifo empty */
-
-/*
- * interrupt status register bits.
- */
-#define ISR_RXTOFEINTR (1 << 6) /* rx fifo empty */
-#define ISR_URINTR (1 << 5) /* tx underflow */
-#define ISR_ORINTR (1 << 4) /* rx overflow */
-#define ISR_RXINTR (1 << 3) /* rx fifo */
-#define ISR_TXINTR (1 << 2) /* tx fifo intr */
-#define ISR_RXTOINTR (1 << 1) /* tx timeout */
-#define ISR_TXCINTR (1 << 0) /* tx complete */
-
-/*
- * interrupt enable register bits.
- */
-#define IE_RXTOIE (1 << 6)
-#define IE_URIE (1 << 5)
-#define IE_ORIE (1 << 4)
-#define IE_RXIE (1 << 3)
-#define IE_TXIE (1 << 2)
-#define IE_RXTIE (1 << 1)
-#define IE_TXCIE (1 << 0)
-
-/*
- * interrupt status. P51
- */
-#define ISR_RXTOFE (1 << 6) /* rx timeout fifo empty */
-#define ISR_UR (1 << 5) /* tx fifo underrun */
-#define ISR_OR (1 << 4) /* rx fifo overrun */
-#define ISR_RX (1 << 3) /* rx interrupt status */
-#define ISR_TX (1 << 2) /* tx interrupt status */
-#define ISR_RXTO (1 << 1) /* rx timeout */
-#define ISR_TXC (1 << 0) /* tx complete */
-
-/*
- * interrupt enable. P52
- */
-#define IE_RXTOFE (1 << 6) /* rx timeout fifo empty */
-#define IE_UR (1 << 5) /* tx fifo underrun */
-#define IE_OR (1 << 4) /* rx fifo overrun */
-#define IE_RX (1 << 3) /* rx interrupt status */
-#define IE_TX (1 << 2) /* tx interrupt status */
-#define IE_RXTO (1 << 1) /* rx timeout */
-#define IE_TXC (1 << 0) /* tx complete */
-
-/*
- * slot flag register bits. P56
- */
-#define SLFR_RWIS (1 << 13) /* raw wake-up interrupt status */
-#define SLFR_RGPIOINTR (1 << 12) /* raw gpio interrupt */
-#define SLFR_12TXE (1 << 11) /* slot 12 tx empty */
-#define SLFR_12RXV (1 << 10) /* slot 12 rx valid */
-#define SLFR_2TXE (1 << 9) /* slot 2 tx empty */
-#define SLFR_2RXV (1 << 8) /* slot 2 rx valid */
-#define SLFR_1TXE (1 << 7) /* slot 1 tx empty */
-#define SLFR_1RXV (1 << 6) /* slot 1 rx valid */
-#define SLFR_12TXB (1 << 5) /* slot 12 tx busy */
-#define SLFR_12RXB (1 << 4) /* slot 12 rx busy */
-#define SLFR_2TXB (1 << 3) /* slot 2 tx busy */
-#define SLFR_2RXB (1 << 2) /* slot 2 rx busy */
-#define SLFR_1TXB (1 << 1) /* slot 1 tx busy */
-#define SLFR_1RXB (1 << 0) /* slot 1 rx busy */
-
-/*
- * Interrupt clear register.
- */
-#define ICLR_RXTOFEC4 (1 << 12)
-#define ICLR_RXTOFEC3 (1 << 11)
-#define ICLR_RXTOFEC2 (1 << 10)
-#define ICLR_RXTOFEC1 (1 << 9)
-#define ICLR_TXUEC4 (1 << 8)
-#define ICLR_TXUEC3 (1 << 7)
-#define ICLR_TXUEC2 (1 << 6)
-#define ICLR_TXUEC1 (1 << 5)
-#define ICLR_RXOEC4 (1 << 4)
-#define ICLR_RXOEC3 (1 << 3)
-#define ICLR_RXOEC2 (1 << 2)
-#define ICLR_RXOEC1 (1 << 1)
-#define ICLR_WISC (1 << 0)
-
-/*
- * Main control register bits. P62
- */
-#define MAINCR_SCRA(x) ((x) << 10) /* secondary codec reg access */
-#define MAINCR_DMAEN (1 << 9) /* dma enable */
-#define MAINCR_SL12TXEN (1 << 8) /* slot 12 transmit enable */
-#define MAINCR_SL12RXEN (1 << 7) /* slot 12 receive enable */
-#define MAINCR_SL2TXEN (1 << 6) /* slot 2 transmit enable */
-#define MAINCR_SL2RXEN (1 << 5) /* slot 2 receive enable */
-#define MAINCR_SL1TXEN (1 << 4) /* slot 1 transmit enable */
-#define MAINCR_SL1RXEN (1 << 3) /* slot 1 receive enable */
-#define MAINCR_LPM (1 << 2) /* low power mode */
-#define MAINCR_LOOPBK (1 << 1) /* loopback */
-#define MAINCR_IE (1 << 0) /* aaci interface enable */
-
-/*
- * Reset register bits. P65
- */
-#define RESET_NRST (1 << 0)
-
-/*
- * Sync register bits. P65
- */
-#define SYNC_FORCE (1 << 0)
-
-/*
- * Main flag register bits. P66
- */
-#define MAINFR_TXB (1 << 1) /* transmit busy */
-#define MAINFR_RXB (1 << 0) /* receive busy */
-
-
-
-struct aaci_runtime {
- void __iomem *base;
- void __iomem *fifo;
- spinlock_t lock;
-
- struct ac97_pcm *pcm;
- int pcm_open;
-
- u32 cr;
- struct snd_pcm_substream *substream;
-
- unsigned int period; /* byte size of a "period" */
-
- /*
- * PIO support
- */
- void *start;
- void *end;
- void *ptr;
- int bytes;
- unsigned int fifo_bytes;
-};
-
-struct aaci {
- struct amba_device *dev;
- struct snd_card *card;
- void __iomem *base;
- unsigned int fifo_depth;
- unsigned int users;
- struct mutex irq_lock;
-
- /* AC'97 */
- struct mutex ac97_sem;
- struct snd_ac97_bus *ac97_bus;
- struct snd_ac97 *ac97;
-
- u32 maincr;
-
- struct aaci_runtime playback;
- struct aaci_runtime capture;
-
- struct snd_pcm *pcm;
-};
-
-#define ACSTREAM_FRONT 0
-#define ACSTREAM_SURROUND 1
-#define ACSTREAM_LFE 2
-
-#endif
diff --git a/ANDROID_3.4.5/sound/arm/pxa2xx-ac97-lib.c b/ANDROID_3.4.5/sound/arm/pxa2xx-ac97-lib.c
deleted file mode 100644
index 48d7c0aa..00000000
--- a/ANDROID_3.4.5/sound/arm/pxa2xx-ac97-lib.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * Based on sound/arm/pxa2xx-ac97.c and sound/soc/pxa/pxa2xx-ac97.c
- * which contain:
- *
- * Author: Nicolas Pitre
- * Created: Dec 02, 2004
- * Copyright: MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/io.h>
-
-#include <sound/ac97_codec.h>
-#include <sound/pxa2xx-lib.h>
-
-#include <mach/irqs.h>
-#include <mach/regs-ac97.h>
-#include <mach/audio.h>
-
-static DEFINE_MUTEX(car_mutex);
-static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
-static volatile long gsr_bits;
-static struct clk *ac97_clk;
-static struct clk *ac97conf_clk;
-static int reset_gpio;
-
-extern void pxa27x_assert_ac97reset(int reset_gpio, int on);
-
-/*
- * Beware PXA27x bugs:
- *
- * o Slot 12 read from modem space will hang controller.
- * o CDONE, SDONE interrupt fails after any slot 12 IO.
- *
- * We therefore have an hybrid approach for waiting on SDONE (interrupt or
- * 1 jiffy timeout if interrupt never comes).
- */
-
-unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
-{
- unsigned short val = -1;
- volatile u32 *reg_addr;
-
- mutex_lock(&car_mutex);
-
- /* set up primary or secondary codec space */
- if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
- reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
- else
- reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
- reg_addr += (reg >> 1);
-
- /* start read access across the ac97 link */
- GSR = GSR_CDONE | GSR_SDONE;
- gsr_bits = 0;
- val = *reg_addr;
- if (reg == AC97_GPIO_STATUS)
- goto out;
- if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1) <= 0 &&
- !((GSR | gsr_bits) & GSR_SDONE)) {
- printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n",
- __func__, reg, GSR | gsr_bits);
- val = -1;
- goto out;
- }
-
- /* valid data now */
- GSR = GSR_CDONE | GSR_SDONE;
- gsr_bits = 0;
- val = *reg_addr;
- /* but we've just started another cycle... */
- wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
-
-out: mutex_unlock(&car_mutex);
- return val;
-}
-EXPORT_SYMBOL_GPL(pxa2xx_ac97_read);
-
-void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short val)
-{
- volatile u32 *reg_addr;
-
- mutex_lock(&car_mutex);
-
- /* set up primary or secondary codec space */
- if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
- reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
- else
- reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
- reg_addr += (reg >> 1);
-
- GSR = GSR_CDONE | GSR_SDONE;
- gsr_bits = 0;
- *reg_addr = val;
- if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1) <= 0 &&
- !((GSR | gsr_bits) & GSR_CDONE))
- printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
- __func__, reg, GSR | gsr_bits);
-
- mutex_unlock(&car_mutex);
-}
-EXPORT_SYMBOL_GPL(pxa2xx_ac97_write);
-
-#ifdef CONFIG_PXA25x
-static inline void pxa_ac97_warm_pxa25x(void)
-{
- gsr_bits = 0;
-
- GCR |= GCR_WARM_RST | GCR_PRIRDY_IEN | GCR_SECRDY_IEN;
- wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
-}
-
-static inline void pxa_ac97_cold_pxa25x(void)
-{
- GCR &= GCR_COLD_RST; /* clear everything but nCRST */
- GCR &= ~GCR_COLD_RST; /* then assert nCRST */
-
- gsr_bits = 0;
-
- GCR = GCR_COLD_RST;
- GCR |= GCR_CDONE_IE|GCR_SDONE_IE;
- wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
-}
-#endif
-
-#ifdef CONFIG_PXA27x
-static inline void pxa_ac97_warm_pxa27x(void)
-{
- gsr_bits = 0;
-
- /* warm reset broken on Bulverde, so manually keep AC97 reset high */
- pxa27x_assert_ac97reset(reset_gpio, 1);
- udelay(10);
- GCR |= GCR_WARM_RST;
- pxa27x_assert_ac97reset(reset_gpio, 0);
- udelay(500);
-}
-
-static inline void pxa_ac97_cold_pxa27x(void)
-{
- GCR &= GCR_COLD_RST; /* clear everything but nCRST */
- GCR &= ~GCR_COLD_RST; /* then assert nCRST */
-
- gsr_bits = 0;
-
- /* PXA27x Developers Manual section 13.5.2.2.1 */
- clk_enable(ac97conf_clk);
- udelay(5);
- clk_disable(ac97conf_clk);
- GCR = GCR_COLD_RST;
- udelay(50);
-}
-#endif
-
-#ifdef CONFIG_PXA3xx
-static inline void pxa_ac97_warm_pxa3xx(void)
-{
- int timeout = 100;
-
- gsr_bits = 0;
-
- /* Can't use interrupts */
- GCR |= GCR_WARM_RST;
- while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
- mdelay(1);
-}
-
-static inline void pxa_ac97_cold_pxa3xx(void)
-{
- int timeout = 1000;
-
- /* Hold CLKBPB for 100us */
- GCR = 0;
- GCR = GCR_CLKBPB;
- udelay(100);
- GCR = 0;
-
- GCR &= GCR_COLD_RST; /* clear everything but nCRST */
- GCR &= ~GCR_COLD_RST; /* then assert nCRST */
-
- gsr_bits = 0;
-
- /* Can't use interrupts on PXA3xx */
- GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
-
- GCR = GCR_WARM_RST | GCR_COLD_RST;
- while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--)
- mdelay(10);
-}
-#endif
-
-bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
-{
- unsigned long gsr;
-
-#ifdef CONFIG_PXA25x
- if (cpu_is_pxa25x())
- pxa_ac97_warm_pxa25x();
- else
-#endif
-#ifdef CONFIG_PXA27x
- if (cpu_is_pxa27x())
- pxa_ac97_warm_pxa27x();
- else
-#endif
-#ifdef CONFIG_PXA3xx
- if (cpu_is_pxa3xx())
- pxa_ac97_warm_pxa3xx();
- else
-#endif
- BUG();
- gsr = GSR | gsr_bits;
- if (!(gsr & (GSR_PCR | GSR_SCR))) {
- printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
- __func__, gsr);
-
- return false;
- }
-
- return true;
-}
-EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
-
-bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
-{
- unsigned long gsr;
-
-#ifdef CONFIG_PXA25x
- if (cpu_is_pxa25x())
- pxa_ac97_cold_pxa25x();
- else
-#endif
-#ifdef CONFIG_PXA27x
- if (cpu_is_pxa27x())
- pxa_ac97_cold_pxa27x();
- else
-#endif
-#ifdef CONFIG_PXA3xx
- if (cpu_is_pxa3xx())
- pxa_ac97_cold_pxa3xx();
- else
-#endif
- BUG();
-
- gsr = GSR | gsr_bits;
- if (!(gsr & (GSR_PCR | GSR_SCR))) {
- printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
- __func__, gsr);
-
- return false;
- }
-
- return true;
-}
-EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_cold_reset);
-
-
-void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97)
-{
- GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
- GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
-}
-EXPORT_SYMBOL_GPL(pxa2xx_ac97_finish_reset);
-
-static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id)
-{
- long status;
-
- status = GSR;
- if (status) {
- GSR = status;
- gsr_bits |= status;
- wake_up(&gsr_wq);
-
- /* Although we don't use those we still need to clear them
- since they tend to spuriously trigger when MMC is used
- (hardware bug? go figure)... */
- if (cpu_is_pxa27x()) {
- MISR = MISR_EOC;
- PISR = PISR_EOC;
- MCSR = MCSR_EOC;
- }
-
- return IRQ_HANDLED;
- }
-
- return IRQ_NONE;
-}
-
-#ifdef CONFIG_PM
-int pxa2xx_ac97_hw_suspend(void)
-{
- GCR |= GCR_ACLINK_OFF;
- clk_disable(ac97_clk);
- return 0;
-}
-EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend);
-
-int pxa2xx_ac97_hw_resume(void)
-{
- clk_enable(ac97_clk);
- return 0;
-}
-EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume);
-#endif
-
-int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
-{
- int ret;
- pxa2xx_audio_ops_t *pdata = dev->dev.platform_data;
-
- if (pdata) {
- switch (pdata->reset_gpio) {
- case 95:
- case 113:
- reset_gpio = pdata->reset_gpio;
- break;
- case 0:
- reset_gpio = 113;
- break;
- case -1:
- break;
- default:
- dev_err(&dev->dev, "Invalid reset GPIO %d\n",
- pdata->reset_gpio);
- }
- } else {
- if (cpu_is_pxa27x())
- reset_gpio = 113;
- }
-
- if (cpu_is_pxa27x()) {
- /* Use GPIO 113 as AC97 Reset on Bulverde */
- pxa27x_assert_ac97reset(reset_gpio, 0);
- ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK");
- if (IS_ERR(ac97conf_clk)) {
- ret = PTR_ERR(ac97conf_clk);
- ac97conf_clk = NULL;
- goto err_conf;
- }
- }
-
- ac97_clk = clk_get(&dev->dev, "AC97CLK");
- if (IS_ERR(ac97_clk)) {
- ret = PTR_ERR(ac97_clk);
- ac97_clk = NULL;
- goto err_clk;
- }
-
- ret = clk_enable(ac97_clk);
- if (ret)
- goto err_clk2;
-
- ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, 0, "AC97", NULL);
- if (ret < 0)
- goto err_irq;
-
- return 0;
-
-err_irq:
- GCR |= GCR_ACLINK_OFF;
-err_clk2:
- clk_put(ac97_clk);
- ac97_clk = NULL;
-err_clk:
- if (ac97conf_clk) {
- clk_put(ac97conf_clk);
- ac97conf_clk = NULL;
- }
-err_conf:
- return ret;
-}
-EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe);
-
-void pxa2xx_ac97_hw_remove(struct platform_device *dev)
-{
- GCR |= GCR_ACLINK_OFF;
- free_irq(IRQ_AC97, NULL);
- if (ac97conf_clk) {
- clk_put(ac97conf_clk);
- ac97conf_clk = NULL;
- }
- clk_disable(ac97_clk);
- clk_put(ac97_clk);
- ac97_clk = NULL;
-}
-EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_remove);
-
-MODULE_AUTHOR("Nicolas Pitre");
-MODULE_DESCRIPTION("Intel/Marvell PXA sound library");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/arm/pxa2xx-ac97.c b/ANDROID_3.4.5/sound/arm/pxa2xx-ac97.c
deleted file mode 100644
index afef72c4..00000000
--- a/ANDROID_3.4.5/sound/arm/pxa2xx-ac97.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * linux/sound/pxa2xx-ac97.c -- AC97 support for the Intel PXA2xx chip.
- *
- * Author: Nicolas Pitre
- * Created: Dec 02, 2004
- * Copyright: MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-#include <sound/pxa2xx-lib.h>
-
-#include <mach/regs-ac97.h>
-#include <mach/audio.h>
-
-#include "pxa2xx-pcm.h"
-
-static void pxa2xx_ac97_reset(struct snd_ac97 *ac97)
-{
- if (!pxa2xx_ac97_try_cold_reset(ac97)) {
- pxa2xx_ac97_try_warm_reset(ac97);
- }
-
- pxa2xx_ac97_finish_reset(ac97);
-}
-
-static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
- .read = pxa2xx_ac97_read,
- .write = pxa2xx_ac97_write,
- .reset = pxa2xx_ac97_reset,
-};
-
-static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_out = {
- .name = "AC97 PCM out",
- .dev_addr = __PREG(PCDR),
- .drcmr = &DRCMR(12),
- .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
- DCMD_BURST32 | DCMD_WIDTH4,
-};
-
-static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_in = {
- .name = "AC97 PCM in",
- .dev_addr = __PREG(PCDR),
- .drcmr = &DRCMR(11),
- .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
- DCMD_BURST32 | DCMD_WIDTH4,
-};
-
-static struct snd_pcm *pxa2xx_ac97_pcm;
-static struct snd_ac97 *pxa2xx_ac97_ac97;
-
-static int pxa2xx_ac97_pcm_startup(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- pxa2xx_audio_ops_t *platform_ops;
- int r;
-
- runtime->hw.channels_min = 2;
- runtime->hw.channels_max = 2;
-
- r = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
- AC97_RATES_FRONT_DAC : AC97_RATES_ADC;
- runtime->hw.rates = pxa2xx_ac97_ac97->rates[r];
- snd_pcm_limit_hw_rates(runtime);
-
- platform_ops = substream->pcm->card->dev->platform_data;
- if (platform_ops && platform_ops->startup)
- return platform_ops->startup(substream, platform_ops->priv);
- else
- return 0;
-}
-
-static void pxa2xx_ac97_pcm_shutdown(struct snd_pcm_substream *substream)
-{
- pxa2xx_audio_ops_t *platform_ops;
-
- platform_ops = substream->pcm->card->dev->platform_data;
- if (platform_ops && platform_ops->shutdown)
- platform_ops->shutdown(substream, platform_ops->priv);
-}
-
-static int pxa2xx_ac97_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
- AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE;
- return snd_ac97_set_rate(pxa2xx_ac97_ac97, reg, runtime->rate);
-}
-
-static struct pxa2xx_pcm_client pxa2xx_ac97_pcm_client = {
- .playback_params = &pxa2xx_ac97_pcm_out,
- .capture_params = &pxa2xx_ac97_pcm_in,
- .startup = pxa2xx_ac97_pcm_startup,
- .shutdown = pxa2xx_ac97_pcm_shutdown,
- .prepare = pxa2xx_ac97_pcm_prepare,
-};
-
-#ifdef CONFIG_PM
-
-static int pxa2xx_ac97_do_suspend(struct snd_card *card, pm_message_t state)
-{
- pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3cold);
- snd_pcm_suspend_all(pxa2xx_ac97_pcm);
- snd_ac97_suspend(pxa2xx_ac97_ac97);
- if (platform_ops && platform_ops->suspend)
- platform_ops->suspend(platform_ops->priv);
-
- return pxa2xx_ac97_hw_suspend();
-}
-
-static int pxa2xx_ac97_do_resume(struct snd_card *card)
-{
- pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data;
- int rc;
-
- rc = pxa2xx_ac97_hw_resume();
- if (rc)
- return rc;
-
- if (platform_ops && platform_ops->resume)
- platform_ops->resume(platform_ops->priv);
- snd_ac97_resume(pxa2xx_ac97_ac97);
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
-
- return 0;
-}
-
-static int pxa2xx_ac97_suspend(struct device *dev)
-{
- struct snd_card *card = dev_get_drvdata(dev);
- int ret = 0;
-
- if (card)
- ret = pxa2xx_ac97_do_suspend(card, PMSG_SUSPEND);
-
- return ret;
-}
-
-static int pxa2xx_ac97_resume(struct device *dev)
-{
- struct snd_card *card = dev_get_drvdata(dev);
- int ret = 0;
-
- if (card)
- ret = pxa2xx_ac97_do_resume(card);
-
- return ret;
-}
-
-static const struct dev_pm_ops pxa2xx_ac97_pm_ops = {
- .suspend = pxa2xx_ac97_suspend,
- .resume = pxa2xx_ac97_resume,
-};
-#endif
-
-static int __devinit pxa2xx_ac97_probe(struct platform_device *dev)
-{
- struct snd_card *card;
- struct snd_ac97_bus *ac97_bus;
- struct snd_ac97_template ac97_template;
- int ret;
- pxa2xx_audio_ops_t *pdata = dev->dev.platform_data;
-
- if (dev->id >= 0) {
- dev_err(&dev->dev, "PXA2xx has only one AC97 port.\n");
- ret = -ENXIO;
- goto err_dev;
- }
-
- ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
- THIS_MODULE, 0, &card);
- if (ret < 0)
- goto err;
-
- card->dev = &dev->dev;
- strncpy(card->driver, dev->dev.driver->name, sizeof(card->driver));
-
- ret = pxa2xx_pcm_new(card, &pxa2xx_ac97_pcm_client, &pxa2xx_ac97_pcm);
- if (ret)
- goto err;
-
- ret = pxa2xx_ac97_hw_probe(dev);
- if (ret)
- goto err;
-
- ret = snd_ac97_bus(card, 0, &pxa2xx_ac97_ops, NULL, &ac97_bus);
- if (ret)
- goto err_remove;
- memset(&ac97_template, 0, sizeof(ac97_template));
- ret = snd_ac97_mixer(ac97_bus, &ac97_template, &pxa2xx_ac97_ac97);
- if (ret)
- goto err_remove;
-
- snprintf(card->shortname, sizeof(card->shortname),
- "%s", snd_ac97_get_short_name(pxa2xx_ac97_ac97));
- snprintf(card->longname, sizeof(card->longname),
- "%s (%s)", dev->dev.driver->name, card->mixername);
-
- if (pdata && pdata->codec_pdata[0])
- snd_ac97_dev_add_pdata(ac97_bus->codec[0], pdata->codec_pdata[0]);
- snd_card_set_dev(card, &dev->dev);
- ret = snd_card_register(card);
- if (ret == 0) {
- platform_set_drvdata(dev, card);
- return 0;
- }
-
-err_remove:
- pxa2xx_ac97_hw_remove(dev);
-err:
- if (card)
- snd_card_free(card);
-err_dev:
- return ret;
-}
-
-static int __devexit pxa2xx_ac97_remove(struct platform_device *dev)
-{
- struct snd_card *card = platform_get_drvdata(dev);
-
- if (card) {
- snd_card_free(card);
- platform_set_drvdata(dev, NULL);
- pxa2xx_ac97_hw_remove(dev);
- }
-
- return 0;
-}
-
-static struct platform_driver pxa2xx_ac97_driver = {
- .probe = pxa2xx_ac97_probe,
- .remove = __devexit_p(pxa2xx_ac97_remove),
- .driver = {
- .name = "pxa2xx-ac97",
- .owner = THIS_MODULE,
-#ifdef CONFIG_PM
- .pm = &pxa2xx_ac97_pm_ops,
-#endif
- },
-};
-
-module_platform_driver(pxa2xx_ac97_driver);
-
-MODULE_AUTHOR("Nicolas Pitre");
-MODULE_DESCRIPTION("AC97 driver for the Intel PXA2xx chip");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:pxa2xx-ac97");
diff --git a/ANDROID_3.4.5/sound/arm/pxa2xx-pcm-lib.c b/ANDROID_3.4.5/sound/arm/pxa2xx-pcm-lib.c
deleted file mode 100644
index 76e0d569..00000000
--- a/ANDROID_3.4.5/sound/arm/pxa2xx-pcm-lib.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/pxa2xx-lib.h>
-
-#include <mach/dma.h>
-
-#include "pxa2xx-pcm.h"
-
-static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME,
- .formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- .period_bytes_min = 32,
- .period_bytes_max = 8192 - 32,
- .periods_min = 1,
- .periods_max = PAGE_SIZE/sizeof(pxa_dma_desc),
- .buffer_bytes_max = 128 * 1024,
- .fifo_size = 32,
-};
-
-int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct pxa2xx_runtime_data *rtd = runtime->private_data;
- size_t totsize = params_buffer_bytes(params);
- size_t period = params_period_bytes(params);
- pxa_dma_desc *dma_desc;
- dma_addr_t dma_buff_phys, next_desc_phys;
-
- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
- runtime->dma_bytes = totsize;
-
- dma_desc = rtd->dma_desc_array;
- next_desc_phys = rtd->dma_desc_array_phys;
- dma_buff_phys = runtime->dma_addr;
- do {
- next_desc_phys += sizeof(pxa_dma_desc);
- dma_desc->ddadr = next_desc_phys;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- dma_desc->dsadr = dma_buff_phys;
- dma_desc->dtadr = rtd->params->dev_addr;
- } else {
- dma_desc->dsadr = rtd->params->dev_addr;
- dma_desc->dtadr = dma_buff_phys;
- }
- if (period > totsize)
- period = totsize;
- dma_desc->dcmd = rtd->params->dcmd | period | DCMD_ENDIRQEN;
- dma_desc++;
- dma_buff_phys += period;
- } while (totsize -= period);
- dma_desc[-1].ddadr = rtd->dma_desc_array_phys;
-
- return 0;
-}
-EXPORT_SYMBOL(__pxa2xx_pcm_hw_params);
-
-int __pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
-
- if (rtd && rtd->params && rtd->params->drcmr)
- *rtd->params->drcmr = 0;
-
- snd_pcm_set_runtime_buffer(substream, NULL);
- return 0;
-}
-EXPORT_SYMBOL(__pxa2xx_pcm_hw_free);
-
-int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
- int ret = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys;
- DCSR(prtd->dma_ch) = DCSR_RUN;
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- DCSR(prtd->dma_ch) &= ~DCSR_RUN;
- break;
-
- case SNDRV_PCM_TRIGGER_RESUME:
- DCSR(prtd->dma_ch) |= DCSR_RUN;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys;
- DCSR(prtd->dma_ch) |= DCSR_RUN;
- break;
-
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-EXPORT_SYMBOL(pxa2xx_pcm_trigger);
-
-snd_pcm_uframes_t
-pxa2xx_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct pxa2xx_runtime_data *prtd = runtime->private_data;
-
- dma_addr_t ptr = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
- DSADR(prtd->dma_ch) : DTADR(prtd->dma_ch);
- snd_pcm_uframes_t x = bytes_to_frames(runtime, ptr - runtime->dma_addr);
-
- if (x == runtime->buffer_size)
- x = 0;
- return x;
-}
-EXPORT_SYMBOL(pxa2xx_pcm_pointer);
-
-int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
-
- if (!prtd || !prtd->params)
- return 0;
-
- if (prtd->dma_ch == -1)
- return -EINVAL;
-
- DCSR(prtd->dma_ch) &= ~DCSR_RUN;
- DCSR(prtd->dma_ch) = 0;
- DCMD(prtd->dma_ch) = 0;
- *prtd->params->drcmr = prtd->dma_ch | DRCMR_MAPVLD;
-
- return 0;
-}
-EXPORT_SYMBOL(__pxa2xx_pcm_prepare);
-
-void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id)
-{
- struct snd_pcm_substream *substream = dev_id;
- struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
- int dcsr;
-
- dcsr = DCSR(dma_ch);
- DCSR(dma_ch) = dcsr & ~DCSR_STOPIRQEN;
-
- if (dcsr & DCSR_ENDINTR) {
- snd_pcm_period_elapsed(substream);
- } else {
- printk(KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n",
- rtd->params->name, dma_ch, dcsr);
- snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
- }
-}
-EXPORT_SYMBOL(pxa2xx_pcm_dma_irq);
-
-int __pxa2xx_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct pxa2xx_runtime_data *rtd;
- int ret;
-
- runtime->hw = pxa2xx_pcm_hardware;
-
- /*
- * For mysterious reasons (and despite what the manual says)
- * playback samples are lost if the DMA count is not a multiple
- * of the DMA burst size. Let's add a rule to enforce that.
- */
- ret = snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
- if (ret)
- goto out;
-
- ret = snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
- if (ret)
- goto out;
-
- ret = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (ret < 0)
- goto out;
-
- ret = -ENOMEM;
- rtd = kzalloc(sizeof(*rtd), GFP_KERNEL);
- if (!rtd)
- goto out;
- rtd->dma_desc_array =
- dma_alloc_writecombine(substream->pcm->card->dev, PAGE_SIZE,
- &rtd->dma_desc_array_phys, GFP_KERNEL);
- if (!rtd->dma_desc_array)
- goto err1;
-
- rtd->dma_ch = -1;
- runtime->private_data = rtd;
- return 0;
-
- err1:
- kfree(rtd);
- out:
- return ret;
-}
-EXPORT_SYMBOL(__pxa2xx_pcm_open);
-
-int __pxa2xx_pcm_close(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct pxa2xx_runtime_data *rtd = runtime->private_data;
-
- dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE,
- rtd->dma_desc_array, rtd->dma_desc_array_phys);
- kfree(rtd);
- return 0;
-}
-EXPORT_SYMBOL(__pxa2xx_pcm_close);
-
-int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- return dma_mmap_writecombine(substream->pcm->card->dev, vma,
- runtime->dma_area,
- runtime->dma_addr,
- runtime->dma_bytes);
-}
-EXPORT_SYMBOL(pxa2xx_pcm_mmap);
-
-int pxa2xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
- struct snd_pcm_substream *substream = pcm->streams[stream].substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = pxa2xx_pcm_hardware.buffer_bytes_max;
- buf->dev.type = SNDRV_DMA_TYPE_DEV;
- buf->dev.dev = pcm->card->dev;
- buf->private_data = NULL;
- buf->area = dma_alloc_writecombine(pcm->card->dev, size,
- &buf->addr, GFP_KERNEL);
- if (!buf->area)
- return -ENOMEM;
- buf->bytes = size;
- return 0;
-}
-EXPORT_SYMBOL(pxa2xx_pcm_preallocate_dma_buffer);
-
-void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- struct snd_dma_buffer *buf;
- int stream;
-
- for (stream = 0; stream < 2; stream++) {
- substream = pcm->streams[stream].substream;
- if (!substream)
- continue;
- buf = &substream->dma_buffer;
- if (!buf->area)
- continue;
- dma_free_writecombine(pcm->card->dev, buf->bytes,
- buf->area, buf->addr);
- buf->area = NULL;
- }
-}
-EXPORT_SYMBOL(pxa2xx_pcm_free_dma_buffers);
-
-MODULE_AUTHOR("Nicolas Pitre");
-MODULE_DESCRIPTION("Intel PXA2xx sound library");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/arm/pxa2xx-pcm.c b/ANDROID_3.4.5/sound/arm/pxa2xx-pcm.c
deleted file mode 100644
index 26422a35..00000000
--- a/ANDROID_3.4.5/sound/arm/pxa2xx-pcm.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * linux/sound/arm/pxa2xx-pcm.c -- ALSA PCM interface for the Intel PXA2xx chip
- *
- * Author: Nicolas Pitre
- * Created: Nov 30, 2004
- * Copyright: (C) 2004 MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pxa2xx-lib.h>
-
-#include "pxa2xx-pcm.h"
-
-static int pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct pxa2xx_pcm_client *client = substream->private_data;
-
- __pxa2xx_pcm_prepare(substream);
-
- return client->prepare(substream);
-}
-
-static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
-{
- struct pxa2xx_pcm_client *client = substream->private_data;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct pxa2xx_runtime_data *rtd;
- int ret;
-
- ret = __pxa2xx_pcm_open(substream);
- if (ret)
- goto out;
-
- rtd = runtime->private_data;
-
- rtd->params = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
- client->playback_params : client->capture_params;
- ret = pxa_request_dma(rtd->params->name, DMA_PRIO_LOW,
- pxa2xx_pcm_dma_irq, substream);
- if (ret < 0)
- goto err2;
- rtd->dma_ch = ret;
-
- ret = client->startup(substream);
- if (!ret)
- goto out;
-
- pxa_free_dma(rtd->dma_ch);
- err2:
- __pxa2xx_pcm_close(substream);
- out:
- return ret;
-}
-
-static int pxa2xx_pcm_close(struct snd_pcm_substream *substream)
-{
- struct pxa2xx_pcm_client *client = substream->private_data;
- struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
-
- pxa_free_dma(rtd->dma_ch);
- client->shutdown(substream);
-
- return __pxa2xx_pcm_close(substream);
-}
-
-static struct snd_pcm_ops pxa2xx_pcm_ops = {
- .open = pxa2xx_pcm_open,
- .close = pxa2xx_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = __pxa2xx_pcm_hw_params,
- .hw_free = __pxa2xx_pcm_hw_free,
- .prepare = pxa2xx_pcm_prepare,
- .trigger = pxa2xx_pcm_trigger,
- .pointer = pxa2xx_pcm_pointer,
- .mmap = pxa2xx_pcm_mmap,
-};
-
-static u64 pxa2xx_pcm_dmamask = 0xffffffff;
-
-int pxa2xx_pcm_new(struct snd_card *card, struct pxa2xx_pcm_client *client,
- struct snd_pcm **rpcm)
-{
- struct snd_pcm *pcm;
- int play = client->playback_params ? 1 : 0;
- int capt = client->capture_params ? 1 : 0;
- int ret;
-
- ret = snd_pcm_new(card, "PXA2xx-PCM", 0, play, capt, &pcm);
- if (ret)
- goto out;
-
- pcm->private_data = client;
- pcm->private_free = pxa2xx_pcm_free_dma_buffers;
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &pxa2xx_pcm_dmamask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = 0xffffffff;
-
- if (play) {
- int stream = SNDRV_PCM_STREAM_PLAYBACK;
- snd_pcm_set_ops(pcm, stream, &pxa2xx_pcm_ops);
- ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, stream);
- if (ret)
- goto out;
- }
- if (capt) {
- int stream = SNDRV_PCM_STREAM_CAPTURE;
- snd_pcm_set_ops(pcm, stream, &pxa2xx_pcm_ops);
- ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, stream);
- if (ret)
- goto out;
- }
-
- if (rpcm)
- *rpcm = pcm;
- ret = 0;
-
- out:
- return ret;
-}
-
-EXPORT_SYMBOL(pxa2xx_pcm_new);
-
-MODULE_AUTHOR("Nicolas Pitre");
-MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/arm/pxa2xx-pcm.h b/ANDROID_3.4.5/sound/arm/pxa2xx-pcm.h
deleted file mode 100644
index 65f86b56..00000000
--- a/ANDROID_3.4.5/sound/arm/pxa2xx-pcm.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * linux/sound/arm/pxa2xx-pcm.h -- ALSA PCM interface for the Intel PXA2xx chip
- *
- * Author: Nicolas Pitre
- * Created: Nov 30, 2004
- * Copyright: MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <mach/dma.h>
-
-struct pxa2xx_runtime_data {
- int dma_ch;
- struct pxa2xx_pcm_dma_params *params;
- pxa_dma_desc *dma_desc_array;
- dma_addr_t dma_desc_array_phys;
-};
-
-struct pxa2xx_pcm_client {
- struct pxa2xx_pcm_dma_params *playback_params;
- struct pxa2xx_pcm_dma_params *capture_params;
- int (*startup)(struct snd_pcm_substream *);
- void (*shutdown)(struct snd_pcm_substream *);
- int (*prepare)(struct snd_pcm_substream *);
-};
-
-extern int pxa2xx_pcm_new(struct snd_card *, struct pxa2xx_pcm_client *, struct snd_pcm **);
-
diff --git a/ANDROID_3.4.5/sound/atmel/Kconfig b/ANDROID_3.4.5/sound/atmel/Kconfig
deleted file mode 100644
index 94de43a0..00000000
--- a/ANDROID_3.4.5/sound/atmel/Kconfig
+++ /dev/null
@@ -1,19 +0,0 @@
-menu "Atmel devices (AVR32 and AT91)"
- depends on AVR32 || ARCH_AT91
-
-config SND_ATMEL_ABDAC
- tristate "Atmel Audio Bitstream DAC (ABDAC) driver"
- select SND_PCM
- depends on DW_DMAC && AVR32
- help
- ALSA sound driver for the Atmel Audio Bitstream DAC (ABDAC).
-
-config SND_ATMEL_AC97C
- tristate "Atmel AC97 Controller (AC97C) driver"
- select SND_PCM
- select SND_AC97_CODEC
- depends on (DW_DMAC && AVR32) || ARCH_AT91
- help
- ALSA sound driver for the Atmel AC97 controller.
-
-endmenu
diff --git a/ANDROID_3.4.5/sound/atmel/Makefile b/ANDROID_3.4.5/sound/atmel/Makefile
deleted file mode 100644
index 219dcfac..00000000
--- a/ANDROID_3.4.5/sound/atmel/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-snd-atmel-abdac-objs := abdac.o
-snd-atmel-ac97c-objs := ac97c.o
-
-obj-$(CONFIG_SND_ATMEL_ABDAC) += snd-atmel-abdac.o
-obj-$(CONFIG_SND_ATMEL_AC97C) += snd-atmel-ac97c.o
diff --git a/ANDROID_3.4.5/sound/atmel/abdac.c b/ANDROID_3.4.5/sound/atmel/abdac.c
deleted file mode 100644
index f7c2bb08..00000000
--- a/ANDROID_3.4.5/sound/atmel/abdac.c
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
- * Driver for the Atmel on-chip Audio Bitstream DAC (ABDAC)
- *
- * Copyright (C) 2006-2009 Atmel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- */
-#include <linux/clk.h>
-#include <linux/bitmap.h>
-#include <linux/dw_dmac.h>
-#include <linux/dmaengine.h>
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/types.h>
-#include <linux/io.h>
-
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/atmel-abdac.h>
-
-/* DAC register offsets */
-#define DAC_DATA 0x0000
-#define DAC_CTRL 0x0008
-#define DAC_INT_MASK 0x000c
-#define DAC_INT_EN 0x0010
-#define DAC_INT_DIS 0x0014
-#define DAC_INT_CLR 0x0018
-#define DAC_INT_STATUS 0x001c
-
-/* Bitfields in CTRL */
-#define DAC_SWAP_OFFSET 30
-#define DAC_SWAP_SIZE 1
-#define DAC_EN_OFFSET 31
-#define DAC_EN_SIZE 1
-
-/* Bitfields in INT_MASK/INT_EN/INT_DIS/INT_STATUS/INT_CLR */
-#define DAC_UNDERRUN_OFFSET 28
-#define DAC_UNDERRUN_SIZE 1
-#define DAC_TX_READY_OFFSET 29
-#define DAC_TX_READY_SIZE 1
-
-/* Bit manipulation macros */
-#define DAC_BIT(name) \
- (1 << DAC_##name##_OFFSET)
-#define DAC_BF(name, value) \
- (((value) & ((1 << DAC_##name##_SIZE) - 1)) \
- << DAC_##name##_OFFSET)
-#define DAC_BFEXT(name, value) \
- (((value) >> DAC_##name##_OFFSET) \
- & ((1 << DAC_##name##_SIZE) - 1))
-#define DAC_BFINS(name, value, old) \
- (((old) & ~(((1 << DAC_##name##_SIZE) - 1) \
- << DAC_##name##_OFFSET)) \
- | DAC_BF(name, value))
-
-/* Register access macros */
-#define dac_readl(port, reg) \
- __raw_readl((port)->regs + DAC_##reg)
-#define dac_writel(port, reg, value) \
- __raw_writel((value), (port)->regs + DAC_##reg)
-
-/*
- * ABDAC supports a maximum of 6 different rates from a generic clock. The
- * generic clock has a power of two divider, which gives 6 steps from 192 kHz
- * to 5112 Hz.
- */
-#define MAX_NUM_RATES 6
-/* ALSA seems to use rates between 192000 Hz and 5112 Hz. */
-#define RATE_MAX 192000
-#define RATE_MIN 5112
-
-enum {
- DMA_READY = 0,
-};
-
-struct atmel_abdac_dma {
- struct dma_chan *chan;
- struct dw_cyclic_desc *cdesc;
-};
-
-struct atmel_abdac {
- struct clk *pclk;
- struct clk *sample_clk;
- struct platform_device *pdev;
- struct atmel_abdac_dma dma;
-
- struct snd_pcm_hw_constraint_list constraints_rates;
- struct snd_pcm_substream *substream;
- struct snd_card *card;
- struct snd_pcm *pcm;
-
- void __iomem *regs;
- unsigned long flags;
- unsigned int rates[MAX_NUM_RATES];
- unsigned int rates_num;
- int irq;
-};
-
-#define get_dac(card) ((struct atmel_abdac *)(card)->private_data)
-
-/* This function is called by the DMA driver. */
-static void atmel_abdac_dma_period_done(void *arg)
-{
- struct atmel_abdac *dac = arg;
- snd_pcm_period_elapsed(dac->substream);
-}
-
-static int atmel_abdac_prepare_dma(struct atmel_abdac *dac,
- struct snd_pcm_substream *substream,
- enum dma_data_direction direction)
-{
- struct dma_chan *chan = dac->dma.chan;
- struct dw_cyclic_desc *cdesc;
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long buffer_len, period_len;
-
- /*
- * We don't do DMA on "complex" transfers, i.e. with
- * non-halfword-aligned buffers or lengths.
- */
- if (runtime->dma_addr & 1 || runtime->buffer_size & 1) {
- dev_dbg(&dac->pdev->dev, "too complex transfer\n");
- return -EINVAL;
- }
-
- buffer_len = frames_to_bytes(runtime, runtime->buffer_size);
- period_len = frames_to_bytes(runtime, runtime->period_size);
-
- cdesc = dw_dma_cyclic_prep(chan, runtime->dma_addr, buffer_len,
- period_len, DMA_MEM_TO_DEV);
- if (IS_ERR(cdesc)) {
- dev_dbg(&dac->pdev->dev, "could not prepare cyclic DMA\n");
- return PTR_ERR(cdesc);
- }
-
- cdesc->period_callback = atmel_abdac_dma_period_done;
- cdesc->period_callback_param = dac;
-
- dac->dma.cdesc = cdesc;
-
- set_bit(DMA_READY, &dac->flags);
-
- return 0;
-}
-
-static struct snd_pcm_hardware atmel_abdac_hw = {
- .info = (SNDRV_PCM_INFO_MMAP
- | SNDRV_PCM_INFO_MMAP_VALID
- | SNDRV_PCM_INFO_INTERLEAVED
- | SNDRV_PCM_INFO_BLOCK_TRANSFER
- | SNDRV_PCM_INFO_RESUME
- | SNDRV_PCM_INFO_PAUSE),
- .formats = (SNDRV_PCM_FMTBIT_S16_BE),
- .rates = (SNDRV_PCM_RATE_KNOT),
- .rate_min = RATE_MIN,
- .rate_max = RATE_MAX,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 64 * 4096,
- .period_bytes_min = 4096,
- .period_bytes_max = 4096,
- .periods_min = 6,
- .periods_max = 64,
-};
-
-static int atmel_abdac_open(struct snd_pcm_substream *substream)
-{
- struct atmel_abdac *dac = snd_pcm_substream_chip(substream);
-
- dac->substream = substream;
- atmel_abdac_hw.rate_max = dac->rates[dac->rates_num - 1];
- atmel_abdac_hw.rate_min = dac->rates[0];
- substream->runtime->hw = atmel_abdac_hw;
-
- return snd_pcm_hw_constraint_list(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE, &dac->constraints_rates);
-}
-
-static int atmel_abdac_close(struct snd_pcm_substream *substream)
-{
- struct atmel_abdac *dac = snd_pcm_substream_chip(substream);
- dac->substream = NULL;
- return 0;
-}
-
-static int atmel_abdac_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct atmel_abdac *dac = snd_pcm_substream_chip(substream);
- int retval;
-
- retval = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- if (retval < 0)
- return retval;
- /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
- if (retval == 1)
- if (test_and_clear_bit(DMA_READY, &dac->flags))
- dw_dma_cyclic_free(dac->dma.chan);
-
- return retval;
-}
-
-static int atmel_abdac_hw_free(struct snd_pcm_substream *substream)
-{
- struct atmel_abdac *dac = snd_pcm_substream_chip(substream);
- if (test_and_clear_bit(DMA_READY, &dac->flags))
- dw_dma_cyclic_free(dac->dma.chan);
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int atmel_abdac_prepare(struct snd_pcm_substream *substream)
-{
- struct atmel_abdac *dac = snd_pcm_substream_chip(substream);
- int retval;
-
- retval = clk_set_rate(dac->sample_clk, 256 * substream->runtime->rate);
- if (retval)
- return retval;
-
- if (!test_bit(DMA_READY, &dac->flags))
- retval = atmel_abdac_prepare_dma(dac, substream, DMA_TO_DEVICE);
-
- return retval;
-}
-
-static int atmel_abdac_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct atmel_abdac *dac = snd_pcm_substream_chip(substream);
- int retval = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
- case SNDRV_PCM_TRIGGER_RESUME: /* fall through */
- case SNDRV_PCM_TRIGGER_START:
- clk_enable(dac->sample_clk);
- retval = dw_dma_cyclic_start(dac->dma.chan);
- if (retval)
- goto out;
- dac_writel(dac, CTRL, DAC_BIT(EN));
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */
- case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */
- case SNDRV_PCM_TRIGGER_STOP:
- dw_dma_cyclic_stop(dac->dma.chan);
- dac_writel(dac, DATA, 0);
- dac_writel(dac, CTRL, 0);
- clk_disable(dac->sample_clk);
- break;
- default:
- retval = -EINVAL;
- break;
- }
-out:
- return retval;
-}
-
-static snd_pcm_uframes_t
-atmel_abdac_pointer(struct snd_pcm_substream *substream)
-{
- struct atmel_abdac *dac = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_uframes_t frames;
- unsigned long bytes;
-
- bytes = dw_dma_get_src_addr(dac->dma.chan);
- bytes -= runtime->dma_addr;
-
- frames = bytes_to_frames(runtime, bytes);
- if (frames >= runtime->buffer_size)
- frames -= runtime->buffer_size;
-
- return frames;
-}
-
-static irqreturn_t abdac_interrupt(int irq, void *dev_id)
-{
- struct atmel_abdac *dac = dev_id;
- u32 status;
-
- status = dac_readl(dac, INT_STATUS);
- if (status & DAC_BIT(UNDERRUN)) {
- dev_err(&dac->pdev->dev, "underrun detected\n");
- dac_writel(dac, INT_CLR, DAC_BIT(UNDERRUN));
- } else {
- dev_err(&dac->pdev->dev, "spurious interrupt (status=0x%x)\n",
- status);
- dac_writel(dac, INT_CLR, status);
- }
-
- return IRQ_HANDLED;
-}
-
-static struct snd_pcm_ops atmel_abdac_ops = {
- .open = atmel_abdac_open,
- .close = atmel_abdac_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = atmel_abdac_hw_params,
- .hw_free = atmel_abdac_hw_free,
- .prepare = atmel_abdac_prepare,
- .trigger = atmel_abdac_trigger,
- .pointer = atmel_abdac_pointer,
-};
-
-static int __devinit atmel_abdac_pcm_new(struct atmel_abdac *dac)
-{
- struct snd_pcm_hardware hw = atmel_abdac_hw;
- struct snd_pcm *pcm;
- int retval;
-
- retval = snd_pcm_new(dac->card, dac->card->shortname,
- dac->pdev->id, 1, 0, &pcm);
- if (retval)
- return retval;
-
- strcpy(pcm->name, dac->card->shortname);
- pcm->private_data = dac;
- pcm->info_flags = 0;
- dac->pcm = pcm;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &atmel_abdac_ops);
-
- retval = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- &dac->pdev->dev, hw.periods_min * hw.period_bytes_min,
- hw.buffer_bytes_max);
-
- return retval;
-}
-
-static bool filter(struct dma_chan *chan, void *slave)
-{
- struct dw_dma_slave *dws = slave;
-
- if (dws->dma_dev == chan->device->dev) {
- chan->private = dws;
- return true;
- } else
- return false;
-}
-
-static int set_sample_rates(struct atmel_abdac *dac)
-{
- long new_rate = RATE_MAX;
- int retval = -EINVAL;
- int index = 0;
-
- /* we start at 192 kHz and work our way down to 5112 Hz */
- while (new_rate >= RATE_MIN && index < (MAX_NUM_RATES + 1)) {
- new_rate = clk_round_rate(dac->sample_clk, 256 * new_rate);
- if (new_rate < 0)
- break;
- /* make sure we are below the ABDAC clock */
- if (new_rate <= clk_get_rate(dac->pclk)) {
- dac->rates[index] = new_rate / 256;
- index++;
- }
- /* divide by 256 and then by two to get next rate */
- new_rate /= 256 * 2;
- }
-
- if (index) {
- int i;
-
- /* reverse array, smallest go first */
- for (i = 0; i < (index / 2); i++) {
- unsigned int tmp = dac->rates[index - 1 - i];
- dac->rates[index - 1 - i] = dac->rates[i];
- dac->rates[i] = tmp;
- }
-
- dac->constraints_rates.count = index;
- dac->constraints_rates.list = dac->rates;
- dac->constraints_rates.mask = 0;
- dac->rates_num = index;
-
- retval = 0;
- }
-
- return retval;
-}
-
-static int __devinit atmel_abdac_probe(struct platform_device *pdev)
-{
- struct snd_card *card;
- struct atmel_abdac *dac;
- struct resource *regs;
- struct atmel_abdac_pdata *pdata;
- struct clk *pclk;
- struct clk *sample_clk;
- int retval;
- int irq;
-
- regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!regs) {
- dev_dbg(&pdev->dev, "no memory resource\n");
- return -ENXIO;
- }
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_dbg(&pdev->dev, "could not get IRQ number\n");
- return irq;
- }
-
- pdata = pdev->dev.platform_data;
- if (!pdata) {
- dev_dbg(&pdev->dev, "no platform data\n");
- return -ENXIO;
- }
-
- pclk = clk_get(&pdev->dev, "pclk");
- if (IS_ERR(pclk)) {
- dev_dbg(&pdev->dev, "no peripheral clock\n");
- return PTR_ERR(pclk);
- }
- sample_clk = clk_get(&pdev->dev, "sample_clk");
- if (IS_ERR(sample_clk)) {
- dev_dbg(&pdev->dev, "no sample clock\n");
- retval = PTR_ERR(sample_clk);
- goto out_put_pclk;
- }
- clk_enable(pclk);
-
- retval = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
- THIS_MODULE, sizeof(struct atmel_abdac), &card);
- if (retval) {
- dev_dbg(&pdev->dev, "could not create sound card device\n");
- goto out_put_sample_clk;
- }
-
- dac = get_dac(card);
-
- dac->irq = irq;
- dac->card = card;
- dac->pclk = pclk;
- dac->sample_clk = sample_clk;
- dac->pdev = pdev;
-
- retval = set_sample_rates(dac);
- if (retval < 0) {
- dev_dbg(&pdev->dev, "could not set supported rates\n");
- goto out_free_card;
- }
-
- dac->regs = ioremap(regs->start, resource_size(regs));
- if (!dac->regs) {
- dev_dbg(&pdev->dev, "could not remap register memory\n");
- goto out_free_card;
- }
-
- /* make sure the DAC is silent and disabled */
- dac_writel(dac, DATA, 0);
- dac_writel(dac, CTRL, 0);
-
- retval = request_irq(irq, abdac_interrupt, 0, "abdac", dac);
- if (retval) {
- dev_dbg(&pdev->dev, "could not request irq\n");
- goto out_unmap_regs;
- }
-
- snd_card_set_dev(card, &pdev->dev);
-
- if (pdata->dws.dma_dev) {
- dma_cap_mask_t mask;
-
- dma_cap_zero(mask);
- dma_cap_set(DMA_SLAVE, mask);
-
- dac->dma.chan = dma_request_channel(mask, filter, &pdata->dws);
- if (dac->dma.chan) {
- struct dma_slave_config dma_conf = {
- .dst_addr = regs->start + DAC_DATA,
- .dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
- .src_maxburst = 1,
- .dst_maxburst = 1,
- .direction = DMA_MEM_TO_DEV,
- .device_fc = false,
- };
-
- dmaengine_slave_config(dac->dma.chan, &dma_conf);
- }
- }
- if (!pdata->dws.dma_dev || !dac->dma.chan) {
- dev_dbg(&pdev->dev, "DMA not available\n");
- retval = -ENODEV;
- goto out_unset_card_dev;
- }
-
- strcpy(card->driver, "Atmel ABDAC");
- strcpy(card->shortname, "Atmel ABDAC");
- sprintf(card->longname, "Atmel Audio Bitstream DAC");
-
- retval = atmel_abdac_pcm_new(dac);
- if (retval) {
- dev_dbg(&pdev->dev, "could not register ABDAC pcm device\n");
- goto out_release_dma;
- }
-
- retval = snd_card_register(card);
- if (retval) {
- dev_dbg(&pdev->dev, "could not register sound card\n");
- goto out_release_dma;
- }
-
- platform_set_drvdata(pdev, card);
-
- dev_info(&pdev->dev, "Atmel ABDAC at 0x%p using %s\n",
- dac->regs, dev_name(&dac->dma.chan->dev->device));
-
- return retval;
-
-out_release_dma:
- dma_release_channel(dac->dma.chan);
- dac->dma.chan = NULL;
-out_unset_card_dev:
- snd_card_set_dev(card, NULL);
- free_irq(irq, dac);
-out_unmap_regs:
- iounmap(dac->regs);
-out_free_card:
- snd_card_free(card);
-out_put_sample_clk:
- clk_put(sample_clk);
- clk_disable(pclk);
-out_put_pclk:
- clk_put(pclk);
- return retval;
-}
-
-#ifdef CONFIG_PM
-static int atmel_abdac_suspend(struct platform_device *pdev, pm_message_t msg)
-{
- struct snd_card *card = platform_get_drvdata(pdev);
- struct atmel_abdac *dac = card->private_data;
-
- dw_dma_cyclic_stop(dac->dma.chan);
- clk_disable(dac->sample_clk);
- clk_disable(dac->pclk);
-
- return 0;
-}
-
-static int atmel_abdac_resume(struct platform_device *pdev)
-{
- struct snd_card *card = platform_get_drvdata(pdev);
- struct atmel_abdac *dac = card->private_data;
-
- clk_enable(dac->pclk);
- clk_enable(dac->sample_clk);
- if (test_bit(DMA_READY, &dac->flags))
- dw_dma_cyclic_start(dac->dma.chan);
-
- return 0;
-}
-#else
-#define atmel_abdac_suspend NULL
-#define atmel_abdac_resume NULL
-#endif
-
-static int __devexit atmel_abdac_remove(struct platform_device *pdev)
-{
- struct snd_card *card = platform_get_drvdata(pdev);
- struct atmel_abdac *dac = get_dac(card);
-
- clk_put(dac->sample_clk);
- clk_disable(dac->pclk);
- clk_put(dac->pclk);
-
- dma_release_channel(dac->dma.chan);
- dac->dma.chan = NULL;
- snd_card_set_dev(card, NULL);
- iounmap(dac->regs);
- free_irq(dac->irq, dac);
- snd_card_free(card);
-
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-static struct platform_driver atmel_abdac_driver = {
- .remove = __devexit_p(atmel_abdac_remove),
- .driver = {
- .name = "atmel_abdac",
- },
- .suspend = atmel_abdac_suspend,
- .resume = atmel_abdac_resume,
-};
-
-static int __init atmel_abdac_init(void)
-{
- return platform_driver_probe(&atmel_abdac_driver,
- atmel_abdac_probe);
-}
-module_init(atmel_abdac_init);
-
-static void __exit atmel_abdac_exit(void)
-{
- platform_driver_unregister(&atmel_abdac_driver);
-}
-module_exit(atmel_abdac_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Driver for Atmel Audio Bitstream DAC (ABDAC)");
-MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
diff --git a/ANDROID_3.4.5/sound/atmel/ac97c.c b/ANDROID_3.4.5/sound/atmel/ac97c.c
deleted file mode 100644
index 115313ef..00000000
--- a/ANDROID_3.4.5/sound/atmel/ac97c.c
+++ /dev/null
@@ -1,1231 +0,0 @@
-/*
- * Driver for Atmel AC97C
- *
- * Copyright (C) 2005-2009 Atmel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- */
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/bitmap.h>
-#include <linux/device.h>
-#include <linux/dmaengine.h>
-#include <linux/dma-mapping.h>
-#include <linux/atmel_pdc.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/mutex.h>
-#include <linux/gpio.h>
-#include <linux/types.h>
-#include <linux/io.h>
-
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/ac97_codec.h>
-#include <sound/atmel-ac97c.h>
-#include <sound/memalloc.h>
-
-#include <linux/dw_dmac.h>
-
-#include <mach/cpu.h>
-#include <mach/gpio.h>
-
-#ifdef CONFIG_ARCH_AT91
-#include <mach/hardware.h>
-#endif
-
-#include "ac97c.h"
-
-enum {
- DMA_TX_READY = 0,
- DMA_RX_READY,
- DMA_TX_CHAN_PRESENT,
- DMA_RX_CHAN_PRESENT,
-};
-
-/* Serialize access to opened variable */
-static DEFINE_MUTEX(opened_mutex);
-
-struct atmel_ac97c_dma {
- struct dma_chan *rx_chan;
- struct dma_chan *tx_chan;
-};
-
-struct atmel_ac97c {
- struct clk *pclk;
- struct platform_device *pdev;
- struct atmel_ac97c_dma dma;
-
- struct snd_pcm_substream *playback_substream;
- struct snd_pcm_substream *capture_substream;
- struct snd_card *card;
- struct snd_pcm *pcm;
- struct snd_ac97 *ac97;
- struct snd_ac97_bus *ac97_bus;
-
- u64 cur_format;
- unsigned int cur_rate;
- unsigned long flags;
- int playback_period, capture_period;
- /* Serialize access to opened variable */
- spinlock_t lock;
- void __iomem *regs;
- int irq;
- int opened;
- int reset_pin;
-};
-
-#define get_chip(card) ((struct atmel_ac97c *)(card)->private_data)
-
-#define ac97c_writel(chip, reg, val) \
- __raw_writel((val), (chip)->regs + AC97C_##reg)
-#define ac97c_readl(chip, reg) \
- __raw_readl((chip)->regs + AC97C_##reg)
-
-/* This function is called by the DMA driver. */
-static void atmel_ac97c_dma_playback_period_done(void *arg)
-{
- struct atmel_ac97c *chip = arg;
- snd_pcm_period_elapsed(chip->playback_substream);
-}
-
-static void atmel_ac97c_dma_capture_period_done(void *arg)
-{
- struct atmel_ac97c *chip = arg;
- snd_pcm_period_elapsed(chip->capture_substream);
-}
-
-static int atmel_ac97c_prepare_dma(struct atmel_ac97c *chip,
- struct snd_pcm_substream *substream,
- enum dma_transfer_direction direction)
-{
- struct dma_chan *chan;
- struct dw_cyclic_desc *cdesc;
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long buffer_len, period_len;
-
- /*
- * We don't do DMA on "complex" transfers, i.e. with
- * non-halfword-aligned buffers or lengths.
- */
- if (runtime->dma_addr & 1 || runtime->buffer_size & 1) {
- dev_dbg(&chip->pdev->dev, "too complex transfer\n");
- return -EINVAL;
- }
-
- if (direction == DMA_MEM_TO_DEV)
- chan = chip->dma.tx_chan;
- else
- chan = chip->dma.rx_chan;
-
- buffer_len = frames_to_bytes(runtime, runtime->buffer_size);
- period_len = frames_to_bytes(runtime, runtime->period_size);
-
- cdesc = dw_dma_cyclic_prep(chan, runtime->dma_addr, buffer_len,
- period_len, direction);
- if (IS_ERR(cdesc)) {
- dev_dbg(&chip->pdev->dev, "could not prepare cyclic DMA\n");
- return PTR_ERR(cdesc);
- }
-
- if (direction == DMA_MEM_TO_DEV) {
- cdesc->period_callback = atmel_ac97c_dma_playback_period_done;
- set_bit(DMA_TX_READY, &chip->flags);
- } else {
- cdesc->period_callback = atmel_ac97c_dma_capture_period_done;
- set_bit(DMA_RX_READY, &chip->flags);
- }
-
- cdesc->period_callback_param = chip;
-
- return 0;
-}
-
-static struct snd_pcm_hardware atmel_ac97c_hw = {
- .info = (SNDRV_PCM_INFO_MMAP
- | SNDRV_PCM_INFO_MMAP_VALID
- | SNDRV_PCM_INFO_INTERLEAVED
- | SNDRV_PCM_INFO_BLOCK_TRANSFER
- | SNDRV_PCM_INFO_JOINT_DUPLEX
- | SNDRV_PCM_INFO_RESUME
- | SNDRV_PCM_INFO_PAUSE),
- .formats = (SNDRV_PCM_FMTBIT_S16_BE
- | SNDRV_PCM_FMTBIT_S16_LE),
- .rates = (SNDRV_PCM_RATE_CONTINUOUS),
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 2 * 2 * 64 * 2048,
- .period_bytes_min = 4096,
- .period_bytes_max = 4096,
- .periods_min = 6,
- .periods_max = 64,
-};
-
-static int atmel_ac97c_playback_open(struct snd_pcm_substream *substream)
-{
- struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- mutex_lock(&opened_mutex);
- chip->opened++;
- runtime->hw = atmel_ac97c_hw;
- if (chip->cur_rate) {
- runtime->hw.rate_min = chip->cur_rate;
- runtime->hw.rate_max = chip->cur_rate;
- }
- if (chip->cur_format)
- runtime->hw.formats = (1ULL << chip->cur_format);
- mutex_unlock(&opened_mutex);
- chip->playback_substream = substream;
- return 0;
-}
-
-static int atmel_ac97c_capture_open(struct snd_pcm_substream *substream)
-{
- struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- mutex_lock(&opened_mutex);
- chip->opened++;
- runtime->hw = atmel_ac97c_hw;
- if (chip->cur_rate) {
- runtime->hw.rate_min = chip->cur_rate;
- runtime->hw.rate_max = chip->cur_rate;
- }
- if (chip->cur_format)
- runtime->hw.formats = (1ULL << chip->cur_format);
- mutex_unlock(&opened_mutex);
- chip->capture_substream = substream;
- return 0;
-}
-
-static int atmel_ac97c_playback_close(struct snd_pcm_substream *substream)
-{
- struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
-
- mutex_lock(&opened_mutex);
- chip->opened--;
- if (!chip->opened) {
- chip->cur_rate = 0;
- chip->cur_format = 0;
- }
- mutex_unlock(&opened_mutex);
-
- chip->playback_substream = NULL;
-
- return 0;
-}
-
-static int atmel_ac97c_capture_close(struct snd_pcm_substream *substream)
-{
- struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
-
- mutex_lock(&opened_mutex);
- chip->opened--;
- if (!chip->opened) {
- chip->cur_rate = 0;
- chip->cur_format = 0;
- }
- mutex_unlock(&opened_mutex);
-
- chip->capture_substream = NULL;
-
- return 0;
-}
-
-static int atmel_ac97c_playback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
- int retval;
-
- retval = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- if (retval < 0)
- return retval;
- /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
- if (cpu_is_at32ap7000()) {
- /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
- if (retval == 1)
- if (test_and_clear_bit(DMA_TX_READY, &chip->flags))
- dw_dma_cyclic_free(chip->dma.tx_chan);
- }
- /* Set restrictions to params. */
- mutex_lock(&opened_mutex);
- chip->cur_rate = params_rate(hw_params);
- chip->cur_format = params_format(hw_params);
- mutex_unlock(&opened_mutex);
-
- return retval;
-}
-
-static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
- int retval;
-
- retval = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- if (retval < 0)
- return retval;
- /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
- if (cpu_is_at32ap7000()) {
- if (retval < 0)
- return retval;
- /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
- if (retval == 1)
- if (test_and_clear_bit(DMA_RX_READY, &chip->flags))
- dw_dma_cyclic_free(chip->dma.rx_chan);
- }
-
- /* Set restrictions to params. */
- mutex_lock(&opened_mutex);
- chip->cur_rate = params_rate(hw_params);
- chip->cur_format = params_format(hw_params);
- mutex_unlock(&opened_mutex);
-
- return retval;
-}
-
-static int atmel_ac97c_playback_hw_free(struct snd_pcm_substream *substream)
-{
- struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
- if (cpu_is_at32ap7000()) {
- if (test_and_clear_bit(DMA_TX_READY, &chip->flags))
- dw_dma_cyclic_free(chip->dma.tx_chan);
- }
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int atmel_ac97c_capture_hw_free(struct snd_pcm_substream *substream)
-{
- struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
- if (cpu_is_at32ap7000()) {
- if (test_and_clear_bit(DMA_RX_READY, &chip->flags))
- dw_dma_cyclic_free(chip->dma.rx_chan);
- }
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int block_size = frames_to_bytes(runtime, runtime->period_size);
- unsigned long word = ac97c_readl(chip, OCA);
- int retval;
-
- chip->playback_period = 0;
- word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
-
- /* assign channels to AC97C channel A */
- switch (runtime->channels) {
- case 1:
- word |= AC97C_CH_ASSIGN(PCM_LEFT, A);
- break;
- case 2:
- word |= AC97C_CH_ASSIGN(PCM_LEFT, A)
- | AC97C_CH_ASSIGN(PCM_RIGHT, A);
- break;
- default:
- /* TODO: support more than two channels */
- return -EINVAL;
- }
- ac97c_writel(chip, OCA, word);
-
- /* configure sample format and size */
- word = ac97c_readl(chip, CAMR);
- if (chip->opened <= 1)
- word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
- else
- word |= AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
-
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_S16_LE:
- if (cpu_is_at32ap7000())
- word |= AC97C_CMR_CEM_LITTLE;
- break;
- case SNDRV_PCM_FORMAT_S16_BE: /* fall through */
- word &= ~(AC97C_CMR_CEM_LITTLE);
- break;
- default:
- word = ac97c_readl(chip, OCA);
- word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
- ac97c_writel(chip, OCA, word);
- return -EINVAL;
- }
-
- /* Enable underrun interrupt on channel A */
- word |= AC97C_CSR_UNRUN;
-
- ac97c_writel(chip, CAMR, word);
-
- /* Enable channel A event interrupt */
- word = ac97c_readl(chip, IMR);
- word |= AC97C_SR_CAEVT;
- ac97c_writel(chip, IER, word);
-
- /* set variable rate if needed */
- if (runtime->rate != 48000) {
- word = ac97c_readl(chip, MR);
- word |= AC97C_MR_VRA;
- ac97c_writel(chip, MR, word);
- } else {
- word = ac97c_readl(chip, MR);
- word &= ~(AC97C_MR_VRA);
- ac97c_writel(chip, MR, word);
- }
-
- retval = snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE,
- runtime->rate);
- if (retval)
- dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n",
- runtime->rate);
-
- if (cpu_is_at32ap7000()) {
- if (!test_bit(DMA_TX_READY, &chip->flags))
- retval = atmel_ac97c_prepare_dma(chip, substream,
- DMA_MEM_TO_DEV);
- } else {
- /* Initialize and start the PDC */
- writel(runtime->dma_addr, chip->regs + ATMEL_PDC_TPR);
- writel(block_size / 2, chip->regs + ATMEL_PDC_TCR);
- writel(runtime->dma_addr + block_size,
- chip->regs + ATMEL_PDC_TNPR);
- writel(block_size / 2, chip->regs + ATMEL_PDC_TNCR);
- }
-
- return retval;
-}
-
-static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int block_size = frames_to_bytes(runtime, runtime->period_size);
- unsigned long word = ac97c_readl(chip, ICA);
- int retval;
-
- chip->capture_period = 0;
- word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
-
- /* assign channels to AC97C channel A */
- switch (runtime->channels) {
- case 1:
- word |= AC97C_CH_ASSIGN(PCM_LEFT, A);
- break;
- case 2:
- word |= AC97C_CH_ASSIGN(PCM_LEFT, A)
- | AC97C_CH_ASSIGN(PCM_RIGHT, A);
- break;
- default:
- /* TODO: support more than two channels */
- return -EINVAL;
- }
- ac97c_writel(chip, ICA, word);
-
- /* configure sample format and size */
- word = ac97c_readl(chip, CAMR);
- if (chip->opened <= 1)
- word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
- else
- word |= AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
-
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_S16_LE:
- if (cpu_is_at32ap7000())
- word |= AC97C_CMR_CEM_LITTLE;
- break;
- case SNDRV_PCM_FORMAT_S16_BE: /* fall through */
- word &= ~(AC97C_CMR_CEM_LITTLE);
- break;
- default:
- word = ac97c_readl(chip, ICA);
- word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
- ac97c_writel(chip, ICA, word);
- return -EINVAL;
- }
-
- /* Enable overrun interrupt on channel A */
- word |= AC97C_CSR_OVRUN;
-
- ac97c_writel(chip, CAMR, word);
-
- /* Enable channel A event interrupt */
- word = ac97c_readl(chip, IMR);
- word |= AC97C_SR_CAEVT;
- ac97c_writel(chip, IER, word);
-
- /* set variable rate if needed */
- if (runtime->rate != 48000) {
- word = ac97c_readl(chip, MR);
- word |= AC97C_MR_VRA;
- ac97c_writel(chip, MR, word);
- } else {
- word = ac97c_readl(chip, MR);
- word &= ~(AC97C_MR_VRA);
- ac97c_writel(chip, MR, word);
- }
-
- retval = snd_ac97_set_rate(chip->ac97, AC97_PCM_LR_ADC_RATE,
- runtime->rate);
- if (retval)
- dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n",
- runtime->rate);
-
- if (cpu_is_at32ap7000()) {
- if (!test_bit(DMA_RX_READY, &chip->flags))
- retval = atmel_ac97c_prepare_dma(chip, substream,
- DMA_DEV_TO_MEM);
- } else {
- /* Initialize and start the PDC */
- writel(runtime->dma_addr, chip->regs + ATMEL_PDC_RPR);
- writel(block_size / 2, chip->regs + ATMEL_PDC_RCR);
- writel(runtime->dma_addr + block_size,
- chip->regs + ATMEL_PDC_RNPR);
- writel(block_size / 2, chip->regs + ATMEL_PDC_RNCR);
- }
-
- return retval;
-}
-
-static int
-atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
- unsigned long camr, ptcr = 0;
- int retval = 0;
-
- camr = ac97c_readl(chip, CAMR);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
- case SNDRV_PCM_TRIGGER_RESUME: /* fall through */
- case SNDRV_PCM_TRIGGER_START:
- if (cpu_is_at32ap7000()) {
- retval = dw_dma_cyclic_start(chip->dma.tx_chan);
- if (retval)
- goto out;
- } else {
- ptcr = ATMEL_PDC_TXTEN;
- }
- camr |= AC97C_CMR_CENA | AC97C_CSR_ENDTX;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */
- case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */
- case SNDRV_PCM_TRIGGER_STOP:
- if (cpu_is_at32ap7000())
- dw_dma_cyclic_stop(chip->dma.tx_chan);
- else
- ptcr |= ATMEL_PDC_TXTDIS;
- if (chip->opened <= 1)
- camr &= ~AC97C_CMR_CENA;
- break;
- default:
- retval = -EINVAL;
- goto out;
- }
-
- ac97c_writel(chip, CAMR, camr);
- if (!cpu_is_at32ap7000())
- writel(ptcr, chip->regs + ATMEL_PDC_PTCR);
-out:
- return retval;
-}
-
-static int
-atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
- unsigned long camr, ptcr = 0;
- int retval = 0;
-
- camr = ac97c_readl(chip, CAMR);
- ptcr = readl(chip->regs + ATMEL_PDC_PTSR);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
- case SNDRV_PCM_TRIGGER_RESUME: /* fall through */
- case SNDRV_PCM_TRIGGER_START:
- if (cpu_is_at32ap7000()) {
- retval = dw_dma_cyclic_start(chip->dma.rx_chan);
- if (retval)
- goto out;
- } else {
- ptcr = ATMEL_PDC_RXTEN;
- }
- camr |= AC97C_CMR_CENA | AC97C_CSR_ENDRX;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */
- case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */
- case SNDRV_PCM_TRIGGER_STOP:
- if (cpu_is_at32ap7000())
- dw_dma_cyclic_stop(chip->dma.rx_chan);
- else
- ptcr |= (ATMEL_PDC_RXTDIS);
- if (chip->opened <= 1)
- camr &= ~AC97C_CMR_CENA;
- break;
- default:
- retval = -EINVAL;
- break;
- }
-
- ac97c_writel(chip, CAMR, camr);
- if (!cpu_is_at32ap7000())
- writel(ptcr, chip->regs + ATMEL_PDC_PTCR);
-out:
- return retval;
-}
-
-static snd_pcm_uframes_t
-atmel_ac97c_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_uframes_t frames;
- unsigned long bytes;
-
- if (cpu_is_at32ap7000())
- bytes = dw_dma_get_src_addr(chip->dma.tx_chan);
- else
- bytes = readl(chip->regs + ATMEL_PDC_TPR);
- bytes -= runtime->dma_addr;
-
- frames = bytes_to_frames(runtime, bytes);
- if (frames >= runtime->buffer_size)
- frames -= runtime->buffer_size;
- return frames;
-}
-
-static snd_pcm_uframes_t
-atmel_ac97c_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_uframes_t frames;
- unsigned long bytes;
-
- if (cpu_is_at32ap7000())
- bytes = dw_dma_get_dst_addr(chip->dma.rx_chan);
- else
- bytes = readl(chip->regs + ATMEL_PDC_RPR);
- bytes -= runtime->dma_addr;
-
- frames = bytes_to_frames(runtime, bytes);
- if (frames >= runtime->buffer_size)
- frames -= runtime->buffer_size;
- return frames;
-}
-
-static struct snd_pcm_ops atmel_ac97_playback_ops = {
- .open = atmel_ac97c_playback_open,
- .close = atmel_ac97c_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = atmel_ac97c_playback_hw_params,
- .hw_free = atmel_ac97c_playback_hw_free,
- .prepare = atmel_ac97c_playback_prepare,
- .trigger = atmel_ac97c_playback_trigger,
- .pointer = atmel_ac97c_playback_pointer,
-};
-
-static struct snd_pcm_ops atmel_ac97_capture_ops = {
- .open = atmel_ac97c_capture_open,
- .close = atmel_ac97c_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = atmel_ac97c_capture_hw_params,
- .hw_free = atmel_ac97c_capture_hw_free,
- .prepare = atmel_ac97c_capture_prepare,
- .trigger = atmel_ac97c_capture_trigger,
- .pointer = atmel_ac97c_capture_pointer,
-};
-
-static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
-{
- struct atmel_ac97c *chip = (struct atmel_ac97c *)dev;
- irqreturn_t retval = IRQ_NONE;
- u32 sr = ac97c_readl(chip, SR);
- u32 casr = ac97c_readl(chip, CASR);
- u32 cosr = ac97c_readl(chip, COSR);
- u32 camr = ac97c_readl(chip, CAMR);
-
- if (sr & AC97C_SR_CAEVT) {
- struct snd_pcm_runtime *runtime;
- int offset, next_period, block_size;
- dev_dbg(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n",
- casr & AC97C_CSR_OVRUN ? " OVRUN" : "",
- casr & AC97C_CSR_RXRDY ? " RXRDY" : "",
- casr & AC97C_CSR_UNRUN ? " UNRUN" : "",
- casr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "",
- casr & AC97C_CSR_TXRDY ? " TXRDY" : "",
- !casr ? " NONE" : "");
- if (!cpu_is_at32ap7000()) {
- if ((casr & camr) & AC97C_CSR_ENDTX) {
- runtime = chip->playback_substream->runtime;
- block_size = frames_to_bytes(runtime,
- runtime->period_size);
- chip->playback_period++;
-
- if (chip->playback_period == runtime->periods)
- chip->playback_period = 0;
- next_period = chip->playback_period + 1;
- if (next_period == runtime->periods)
- next_period = 0;
-
- offset = block_size * next_period;
-
- writel(runtime->dma_addr + offset,
- chip->regs + ATMEL_PDC_TNPR);
- writel(block_size / 2,
- chip->regs + ATMEL_PDC_TNCR);
-
- snd_pcm_period_elapsed(
- chip->playback_substream);
- }
- if ((casr & camr) & AC97C_CSR_ENDRX) {
- runtime = chip->capture_substream->runtime;
- block_size = frames_to_bytes(runtime,
- runtime->period_size);
- chip->capture_period++;
-
- if (chip->capture_period == runtime->periods)
- chip->capture_period = 0;
- next_period = chip->capture_period + 1;
- if (next_period == runtime->periods)
- next_period = 0;
-
- offset = block_size * next_period;
-
- writel(runtime->dma_addr + offset,
- chip->regs + ATMEL_PDC_RNPR);
- writel(block_size / 2,
- chip->regs + ATMEL_PDC_RNCR);
- snd_pcm_period_elapsed(chip->capture_substream);
- }
- }
- retval = IRQ_HANDLED;
- }
-
- if (sr & AC97C_SR_COEVT) {
- dev_info(&chip->pdev->dev, "codec channel event%s%s%s%s%s\n",
- cosr & AC97C_CSR_OVRUN ? " OVRUN" : "",
- cosr & AC97C_CSR_RXRDY ? " RXRDY" : "",
- cosr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "",
- cosr & AC97C_CSR_TXRDY ? " TXRDY" : "",
- !cosr ? " NONE" : "");
- retval = IRQ_HANDLED;
- }
-
- if (retval == IRQ_NONE) {
- dev_err(&chip->pdev->dev, "spurious interrupt sr 0x%08x "
- "casr 0x%08x cosr 0x%08x\n", sr, casr, cosr);
- }
-
- return retval;
-}
-
-static struct ac97_pcm at91_ac97_pcm_defs[] __devinitdata = {
- /* Playback */
- {
- .exclusive = 1,
- .r = { {
- .slots = ((1 << AC97_SLOT_PCM_LEFT)
- | (1 << AC97_SLOT_PCM_RIGHT)),
- } },
- },
- /* PCM in */
- {
- .stream = 1,
- .exclusive = 1,
- .r = { {
- .slots = ((1 << AC97_SLOT_PCM_LEFT)
- | (1 << AC97_SLOT_PCM_RIGHT)),
- } }
- },
- /* Mic in */
- {
- .stream = 1,
- .exclusive = 1,
- .r = { {
- .slots = (1<<AC97_SLOT_MIC),
- } }
- },
-};
-
-static int __devinit atmel_ac97c_pcm_new(struct atmel_ac97c *chip)
-{
- struct snd_pcm *pcm;
- struct snd_pcm_hardware hw = atmel_ac97c_hw;
- int capture, playback, retval, err;
-
- capture = test_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
- playback = test_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
-
- if (!cpu_is_at32ap7000()) {
- err = snd_ac97_pcm_assign(chip->ac97_bus,
- ARRAY_SIZE(at91_ac97_pcm_defs),
- at91_ac97_pcm_defs);
- if (err)
- return err;
- }
- retval = snd_pcm_new(chip->card, chip->card->shortname,
- chip->pdev->id, playback, capture, &pcm);
- if (retval)
- return retval;
-
- if (capture)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &atmel_ac97_capture_ops);
- if (playback)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &atmel_ac97_playback_ops);
-
- retval = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- &chip->pdev->dev, hw.periods_min * hw.period_bytes_min,
- hw.buffer_bytes_max);
- if (retval)
- return retval;
-
- pcm->private_data = chip;
- pcm->info_flags = 0;
- strcpy(pcm->name, chip->card->shortname);
- chip->pcm = pcm;
-
- return 0;
-}
-
-static int atmel_ac97c_mixer_new(struct atmel_ac97c *chip)
-{
- struct snd_ac97_template template;
- memset(&template, 0, sizeof(template));
- template.private_data = chip;
- return snd_ac97_mixer(chip->ac97_bus, &template, &chip->ac97);
-}
-
-static void atmel_ac97c_write(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short val)
-{
- struct atmel_ac97c *chip = get_chip(ac97);
- unsigned long word;
- int timeout = 40;
-
- word = (reg & 0x7f) << 16 | val;
-
- do {
- if (ac97c_readl(chip, COSR) & AC97C_CSR_TXRDY) {
- ac97c_writel(chip, COTHR, word);
- return;
- }
- udelay(1);
- } while (--timeout);
-
- dev_dbg(&chip->pdev->dev, "codec write timeout\n");
-}
-
-static unsigned short atmel_ac97c_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- struct atmel_ac97c *chip = get_chip(ac97);
- unsigned long word;
- int timeout = 40;
- int write = 10;
-
- word = (0x80 | (reg & 0x7f)) << 16;
-
- if ((ac97c_readl(chip, COSR) & AC97C_CSR_RXRDY) != 0)
- ac97c_readl(chip, CORHR);
-
-retry_write:
- timeout = 40;
-
- do {
- if ((ac97c_readl(chip, COSR) & AC97C_CSR_TXRDY) != 0) {
- ac97c_writel(chip, COTHR, word);
- goto read_reg;
- }
- udelay(10);
- } while (--timeout);
-
- if (!--write)
- goto timed_out;
- goto retry_write;
-
-read_reg:
- do {
- if ((ac97c_readl(chip, COSR) & AC97C_CSR_RXRDY) != 0) {
- unsigned short val = ac97c_readl(chip, CORHR);
- return val;
- }
- udelay(10);
- } while (--timeout);
-
- if (!--write)
- goto timed_out;
- goto retry_write;
-
-timed_out:
- dev_dbg(&chip->pdev->dev, "codec read timeout\n");
- return 0xffff;
-}
-
-static bool filter(struct dma_chan *chan, void *slave)
-{
- struct dw_dma_slave *dws = slave;
-
- if (dws->dma_dev == chan->device->dev) {
- chan->private = dws;
- return true;
- } else
- return false;
-}
-
-static void atmel_ac97c_reset(struct atmel_ac97c *chip)
-{
- ac97c_writel(chip, MR, 0);
- ac97c_writel(chip, MR, AC97C_MR_ENA);
- ac97c_writel(chip, CAMR, 0);
- ac97c_writel(chip, COMR, 0);
-
- if (gpio_is_valid(chip->reset_pin)) {
- gpio_set_value(chip->reset_pin, 0);
- /* AC97 v2.2 specifications says minimum 1 us. */
- udelay(2);
- gpio_set_value(chip->reset_pin, 1);
- } else {
- ac97c_writel(chip, MR, AC97C_MR_WRST | AC97C_MR_ENA);
- udelay(2);
- ac97c_writel(chip, MR, AC97C_MR_ENA);
- }
-}
-
-static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
-{
- struct snd_card *card;
- struct atmel_ac97c *chip;
- struct resource *regs;
- struct ac97c_platform_data *pdata;
- struct clk *pclk;
- static struct snd_ac97_bus_ops ops = {
- .write = atmel_ac97c_write,
- .read = atmel_ac97c_read,
- };
- int retval;
- int irq;
-
- regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!regs) {
- dev_dbg(&pdev->dev, "no memory resource\n");
- return -ENXIO;
- }
-
- pdata = pdev->dev.platform_data;
- if (!pdata) {
- dev_dbg(&pdev->dev, "no platform data\n");
- return -ENXIO;
- }
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_dbg(&pdev->dev, "could not get irq\n");
- return -ENXIO;
- }
-
- if (cpu_is_at32ap7000()) {
- pclk = clk_get(&pdev->dev, "pclk");
- } else {
- pclk = clk_get(&pdev->dev, "ac97_clk");
- }
-
- if (IS_ERR(pclk)) {
- dev_dbg(&pdev->dev, "no peripheral clock\n");
- return PTR_ERR(pclk);
- }
- clk_enable(pclk);
-
- retval = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
- THIS_MODULE, sizeof(struct atmel_ac97c), &card);
- if (retval) {
- dev_dbg(&pdev->dev, "could not create sound card device\n");
- goto err_snd_card_new;
- }
-
- chip = get_chip(card);
-
- retval = request_irq(irq, atmel_ac97c_interrupt, 0, "AC97C", chip);
- if (retval) {
- dev_dbg(&pdev->dev, "unable to request irq %d\n", irq);
- goto err_request_irq;
- }
- chip->irq = irq;
-
- spin_lock_init(&chip->lock);
-
- strcpy(card->driver, "Atmel AC97C");
- strcpy(card->shortname, "Atmel AC97C");
- sprintf(card->longname, "Atmel AC97 controller");
-
- chip->card = card;
- chip->pclk = pclk;
- chip->pdev = pdev;
- chip->regs = ioremap(regs->start, resource_size(regs));
-
- if (!chip->regs) {
- dev_dbg(&pdev->dev, "could not remap register memory\n");
- goto err_ioremap;
- }
-
- if (gpio_is_valid(pdata->reset_pin)) {
- if (gpio_request(pdata->reset_pin, "reset_pin")) {
- dev_dbg(&pdev->dev, "reset pin not available\n");
- chip->reset_pin = -ENODEV;
- } else {
- gpio_direction_output(pdata->reset_pin, 1);
- chip->reset_pin = pdata->reset_pin;
- }
- }
-
- snd_card_set_dev(card, &pdev->dev);
-
- atmel_ac97c_reset(chip);
-
- /* Enable overrun interrupt from codec channel */
- ac97c_writel(chip, COMR, AC97C_CSR_OVRUN);
- ac97c_writel(chip, IER, ac97c_readl(chip, IMR) | AC97C_SR_COEVT);
-
- retval = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus);
- if (retval) {
- dev_dbg(&pdev->dev, "could not register on ac97 bus\n");
- goto err_ac97_bus;
- }
-
- retval = atmel_ac97c_mixer_new(chip);
- if (retval) {
- dev_dbg(&pdev->dev, "could not register ac97 mixer\n");
- goto err_ac97_bus;
- }
-
- if (cpu_is_at32ap7000()) {
- if (pdata->rx_dws.dma_dev) {
- dma_cap_mask_t mask;
-
- dma_cap_zero(mask);
- dma_cap_set(DMA_SLAVE, mask);
-
- chip->dma.rx_chan = dma_request_channel(mask, filter,
- &pdata->rx_dws);
- if (chip->dma.rx_chan) {
- struct dma_slave_config dma_conf = {
- .src_addr = regs->start + AC97C_CARHR +
- 2,
- .src_addr_width =
- DMA_SLAVE_BUSWIDTH_2_BYTES,
- .src_maxburst = 1,
- .dst_maxburst = 1,
- .direction = DMA_DEV_TO_MEM,
- .device_fc = false,
- };
-
- dmaengine_slave_config(chip->dma.rx_chan,
- &dma_conf);
- }
-
- dev_info(&chip->pdev->dev, "using %s for DMA RX\n",
- dev_name(&chip->dma.rx_chan->dev->device));
- set_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
- }
-
- if (pdata->tx_dws.dma_dev) {
- dma_cap_mask_t mask;
-
- dma_cap_zero(mask);
- dma_cap_set(DMA_SLAVE, mask);
-
- chip->dma.tx_chan = dma_request_channel(mask, filter,
- &pdata->tx_dws);
- if (chip->dma.tx_chan) {
- struct dma_slave_config dma_conf = {
- .dst_addr = regs->start + AC97C_CATHR +
- 2,
- .dst_addr_width =
- DMA_SLAVE_BUSWIDTH_2_BYTES,
- .src_maxburst = 1,
- .dst_maxburst = 1,
- .direction = DMA_MEM_TO_DEV,
- .device_fc = false,
- };
-
- dmaengine_slave_config(chip->dma.tx_chan,
- &dma_conf);
- }
-
- dev_info(&chip->pdev->dev, "using %s for DMA TX\n",
- dev_name(&chip->dma.tx_chan->dev->device));
- set_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
- }
-
- if (!test_bit(DMA_RX_CHAN_PRESENT, &chip->flags) &&
- !test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) {
- dev_dbg(&pdev->dev, "DMA not available\n");
- retval = -ENODEV;
- goto err_dma;
- }
- } else {
- /* Just pretend that we have DMA channel(for at91 i is actually
- * the PDC) */
- set_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
- set_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
- }
-
- retval = atmel_ac97c_pcm_new(chip);
- if (retval) {
- dev_dbg(&pdev->dev, "could not register ac97 pcm device\n");
- goto err_dma;
- }
-
- retval = snd_card_register(card);
- if (retval) {
- dev_dbg(&pdev->dev, "could not register sound card\n");
- goto err_dma;
- }
-
- platform_set_drvdata(pdev, card);
-
- dev_info(&pdev->dev, "Atmel AC97 controller at 0x%p, irq = %d\n",
- chip->regs, irq);
-
- return 0;
-
-err_dma:
- if (cpu_is_at32ap7000()) {
- if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags))
- dma_release_channel(chip->dma.rx_chan);
- if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags))
- dma_release_channel(chip->dma.tx_chan);
- clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
- clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
- chip->dma.rx_chan = NULL;
- chip->dma.tx_chan = NULL;
- }
-err_ac97_bus:
- snd_card_set_dev(card, NULL);
-
- if (gpio_is_valid(chip->reset_pin))
- gpio_free(chip->reset_pin);
-
- iounmap(chip->regs);
-err_ioremap:
- free_irq(irq, chip);
-err_request_irq:
- snd_card_free(card);
-err_snd_card_new:
- clk_disable(pclk);
- clk_put(pclk);
- return retval;
-}
-
-#ifdef CONFIG_PM
-static int atmel_ac97c_suspend(struct platform_device *pdev, pm_message_t msg)
-{
- struct snd_card *card = platform_get_drvdata(pdev);
- struct atmel_ac97c *chip = card->private_data;
-
- if (cpu_is_at32ap7000()) {
- if (test_bit(DMA_RX_READY, &chip->flags))
- dw_dma_cyclic_stop(chip->dma.rx_chan);
- if (test_bit(DMA_TX_READY, &chip->flags))
- dw_dma_cyclic_stop(chip->dma.tx_chan);
- }
- clk_disable(chip->pclk);
-
- return 0;
-}
-
-static int atmel_ac97c_resume(struct platform_device *pdev)
-{
- struct snd_card *card = platform_get_drvdata(pdev);
- struct atmel_ac97c *chip = card->private_data;
-
- clk_enable(chip->pclk);
- if (cpu_is_at32ap7000()) {
- if (test_bit(DMA_RX_READY, &chip->flags))
- dw_dma_cyclic_start(chip->dma.rx_chan);
- if (test_bit(DMA_TX_READY, &chip->flags))
- dw_dma_cyclic_start(chip->dma.tx_chan);
- }
- return 0;
-}
-#else
-#define atmel_ac97c_suspend NULL
-#define atmel_ac97c_resume NULL
-#endif
-
-static int __devexit atmel_ac97c_remove(struct platform_device *pdev)
-{
- struct snd_card *card = platform_get_drvdata(pdev);
- struct atmel_ac97c *chip = get_chip(card);
-
- if (gpio_is_valid(chip->reset_pin))
- gpio_free(chip->reset_pin);
-
- ac97c_writel(chip, CAMR, 0);
- ac97c_writel(chip, COMR, 0);
- ac97c_writel(chip, MR, 0);
-
- clk_disable(chip->pclk);
- clk_put(chip->pclk);
- iounmap(chip->regs);
- free_irq(chip->irq, chip);
-
- if (cpu_is_at32ap7000()) {
- if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags))
- dma_release_channel(chip->dma.rx_chan);
- if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags))
- dma_release_channel(chip->dma.tx_chan);
- clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
- clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
- chip->dma.rx_chan = NULL;
- chip->dma.tx_chan = NULL;
- }
-
- snd_card_set_dev(card, NULL);
- snd_card_free(card);
-
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-static struct platform_driver atmel_ac97c_driver = {
- .remove = __devexit_p(atmel_ac97c_remove),
- .driver = {
- .name = "atmel_ac97c",
- },
- .suspend = atmel_ac97c_suspend,
- .resume = atmel_ac97c_resume,
-};
-
-static int __init atmel_ac97c_init(void)
-{
- return platform_driver_probe(&atmel_ac97c_driver,
- atmel_ac97c_probe);
-}
-module_init(atmel_ac97c_init);
-
-static void __exit atmel_ac97c_exit(void)
-{
- platform_driver_unregister(&atmel_ac97c_driver);
-}
-module_exit(atmel_ac97c_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Driver for Atmel AC97 controller");
-MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
diff --git a/ANDROID_3.4.5/sound/atmel/ac97c.h b/ANDROID_3.4.5/sound/atmel/ac97c.h
deleted file mode 100644
index ecbba502..00000000
--- a/ANDROID_3.4.5/sound/atmel/ac97c.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Register definitions for Atmel AC97C
- *
- * Copyright (C) 2005-2009 Atmel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-#ifndef __SOUND_ATMEL_AC97C_H
-#define __SOUND_ATMEL_AC97C_H
-
-#define AC97C_MR 0x08
-#define AC97C_ICA 0x10
-#define AC97C_OCA 0x14
-#define AC97C_CARHR 0x20
-#define AC97C_CATHR 0x24
-#define AC97C_CASR 0x28
-#define AC97C_CAMR 0x2c
-#define AC97C_CORHR 0x40
-#define AC97C_COTHR 0x44
-#define AC97C_COSR 0x48
-#define AC97C_COMR 0x4c
-#define AC97C_SR 0x50
-#define AC97C_IER 0x54
-#define AC97C_IDR 0x58
-#define AC97C_IMR 0x5c
-#define AC97C_VERSION 0xfc
-
-#define AC97C_CATPR PDC_TPR
-#define AC97C_CATCR PDC_TCR
-#define AC97C_CATNPR PDC_TNPR
-#define AC97C_CATNCR PDC_TNCR
-#define AC97C_CARPR PDC_RPR
-#define AC97C_CARCR PDC_RCR
-#define AC97C_CARNPR PDC_RNPR
-#define AC97C_CARNCR PDC_RNCR
-#define AC97C_PTCR PDC_PTCR
-
-#define AC97C_MR_ENA (1 << 0)
-#define AC97C_MR_WRST (1 << 1)
-#define AC97C_MR_VRA (1 << 2)
-
-#define AC97C_CSR_TXRDY (1 << 0)
-#define AC97C_CSR_TXEMPTY (1 << 1)
-#define AC97C_CSR_UNRUN (1 << 2)
-#define AC97C_CSR_RXRDY (1 << 4)
-#define AC97C_CSR_OVRUN (1 << 5)
-#define AC97C_CSR_ENDTX (1 << 10)
-#define AC97C_CSR_ENDRX (1 << 14)
-
-#define AC97C_CMR_SIZE_20 (0 << 16)
-#define AC97C_CMR_SIZE_18 (1 << 16)
-#define AC97C_CMR_SIZE_16 (2 << 16)
-#define AC97C_CMR_SIZE_10 (3 << 16)
-#define AC97C_CMR_CEM_LITTLE (1 << 18)
-#define AC97C_CMR_CEM_BIG (0 << 18)
-#define AC97C_CMR_CENA (1 << 21)
-#define AC97C_CMR_DMAEN (1 << 22)
-
-#define AC97C_SR_CAEVT (1 << 3)
-#define AC97C_SR_COEVT (1 << 2)
-#define AC97C_SR_WKUP (1 << 1)
-#define AC97C_SR_SOF (1 << 0)
-
-#define AC97C_CH_MASK(slot) \
- (0x7 << (3 * (AC97_SLOT_##slot - 3)))
-#define AC97C_CH_ASSIGN(slot, channel) \
- (AC97C_CHANNEL_##channel << (3 * (AC97_SLOT_##slot - 3)))
-#define AC97C_CHANNEL_NONE 0x0
-#define AC97C_CHANNEL_A 0x1
-
-#endif /* __SOUND_ATMEL_AC97C_H */
diff --git a/ANDROID_3.4.5/sound/core/Kconfig b/ANDROID_3.4.5/sound/core/Kconfig
deleted file mode 100644
index 72261551..00000000
--- a/ANDROID_3.4.5/sound/core/Kconfig
+++ /dev/null
@@ -1,220 +0,0 @@
-# ALSA soundcard-configuration
-config SND_TIMER
- tristate
-
-config SND_PCM
- tristate
- select SND_TIMER
-
-config SND_HWDEP
- tristate
-
-config SND_RAWMIDI
- tristate
-
-config SND_COMPRESS_OFFLOAD
- tristate
-
-# To be effective this also requires INPUT - users should say:
-# select SND_JACK if INPUT=y || INPUT=SND
-# to avoid having to force INPUT on.
-config SND_JACK
- bool
-
-config SND_SEQUENCER
- tristate "Sequencer support"
- select SND_TIMER
- help
- Say Y or M to enable MIDI sequencer and router support. This
- feature allows routing and enqueueing of MIDI events. Events
- can be processed at a given time.
-
- Many programs require this feature, so you should enable it
- unless you know what you're doing.
-
-config SND_SEQ_DUMMY
- tristate "Sequencer dummy client"
- depends on SND_SEQUENCER
- help
- Say Y here to enable the dummy sequencer client. This client
- is a simple MIDI-through client: all normal input events are
- redirected to the output port immediately.
-
- You don't need this unless you want to connect many MIDI
- devices or applications together.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-seq-dummy.
-
-config SND_OSSEMUL
- select SOUND_OSS_CORE
- bool
-
-config SND_MIXER_OSS
- tristate "OSS Mixer API"
- select SND_OSSEMUL
- help
- To enable OSS mixer API emulation (/dev/mixer*), say Y here
- and read <file:Documentation/sound/alsa/OSS-Emulation.txt>.
-
- Many programs still use the OSS API, so say Y.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-mixer-oss.
-
-config SND_PCM_OSS
- tristate "OSS PCM (digital audio) API"
- select SND_OSSEMUL
- select SND_PCM
- help
- To enable OSS digital audio (PCM) emulation (/dev/dsp*), say Y
- here and read <file:Documentation/sound/alsa/OSS-Emulation.txt>.
-
- Many programs still use the OSS API, so say Y.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-pcm-oss.
-
-config SND_PCM_OSS_PLUGINS
- bool "OSS PCM (digital audio) API - Include plugin system"
- depends on SND_PCM_OSS
- default y
- help
- If you disable this option, the ALSA's OSS PCM API will not
- support conversion of channels, formats and rates. It will
- behave like most of new OSS/Free drivers in 2.4/2.6 kernels.
-
-config SND_SEQUENCER_OSS
- bool "OSS Sequencer API"
- depends on SND_SEQUENCER
- select SND_OSSEMUL
- help
- Say Y here to enable OSS sequencer emulation (both
- /dev/sequencer and /dev/music interfaces).
-
- Many programs still use the OSS API, so say Y.
-
- If you choose M in "Sequencer support" (SND_SEQUENCER),
- this will be compiled as a module. The module will be called
- snd-seq-oss.
-
-config SND_HRTIMER
- tristate "HR-timer backend support"
- depends on HIGH_RES_TIMERS
- select SND_TIMER
- help
- Say Y here to enable HR-timer backend for ALSA timer. ALSA uses
- the hrtimer as a precise timing source. The ALSA sequencer code
- also can use this timing source.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-hrtimer.
-
-config SND_SEQ_HRTIMER_DEFAULT
- bool "Use HR-timer as default sequencer timer"
- depends on SND_HRTIMER && SND_SEQUENCER
- default y
- help
- Say Y here to use the HR-timer backend as the default sequencer
- timer.
-
-config SND_RTCTIMER
- tristate "RTC Timer support"
- depends on RTC
- select SND_TIMER
- help
- Say Y here to enable RTC timer support for ALSA. ALSA uses
- the RTC timer as a precise timing source and maps the RTC
- timer to ALSA's timer interface. The ALSA sequencer code also
- can use this timing source.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-rtctimer.
-
- Note that this option is exclusive with the new RTC drivers
- (CONFIG_RTC_CLASS) since this requires the old API.
-
-config SND_SEQ_RTCTIMER_DEFAULT
- bool "Use RTC as default sequencer timer"
- depends on SND_RTCTIMER && SND_SEQUENCER
- depends on !SND_SEQ_HRTIMER_DEFAULT
- default y
- help
- Say Y here to use the RTC timer as the default sequencer
- timer. This is strongly recommended because it ensures
- precise MIDI timing even when the system timer runs at less
- than 1000 Hz.
-
- If in doubt, say Y.
-
-config SND_DYNAMIC_MINORS
- bool "Dynamic device file minor numbers"
- help
- If you say Y here, the minor numbers of ALSA device files in
- /dev/snd/ are allocated dynamically. This allows you to have
- more than 8 sound cards, but requires a dynamic device file
- system like udev.
-
- If you are unsure about this, say N here.
-
-config SND_SUPPORT_OLD_API
- bool "Support old ALSA API"
- select SND_HWDEP
- default y
- help
- Say Y here to support the obsolete ALSA PCM API (ver.0.9.0 rc3
- or older).
-
-config SND_VERBOSE_PROCFS
- bool "Verbose procfs contents"
- depends on PROC_FS
- default y
- help
- Say Y here to include code for verbose procfs contents (provides
- useful information to developers when a problem occurs). On the
- other side, it makes the ALSA subsystem larger.
-
-config SND_VERBOSE_PRINTK
- bool "Verbose printk"
- help
- Say Y here to enable verbose log messages. These messages
- will help to identify source file and position containing
- printed messages.
-
- You don't need this unless you're debugging ALSA.
-
-config SND_DEBUG
- bool "Debug"
- help
- Say Y here to enable ALSA debug code.
-
-config SND_DEBUG_VERBOSE
- bool "More verbose debug"
- depends on SND_DEBUG
- help
- Say Y here to enable extra-verbose debugging messages.
-
- Let me repeat: it enables EXTRA-VERBOSE DEBUGGING messages.
- So, say Y only if you are ready to be annoyed.
-
-config SND_PCM_XRUN_DEBUG
- bool "Enable PCM ring buffer overrun/underrun debugging"
- default n
- depends on SND_DEBUG && SND_VERBOSE_PROCFS
- help
- Say Y to enable the PCM ring buffer overrun/underrun debugging.
- It is usually not required, but if you have trouble with
- sound clicking when system is loaded, it may help to determine
- the process or driver which causes the scheduling gaps.
-
-config SND_VMASTER
- bool
-
-config SND_KCTL_JACK
- bool
-
-config SND_DMA_SGBUF
- def_bool y
- depends on X86
-
-source "sound/core/seq/Kconfig"
diff --git a/ANDROID_3.4.5/sound/core/Makefile b/ANDROID_3.4.5/sound/core/Makefile
deleted file mode 100644
index 43d41174..00000000
--- a/ANDROID_3.4.5/sound/core/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 1999,2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-y := sound.o init.o memory.o info.o control.o misc.o device.o
-snd-$(CONFIG_ISA_DMA_API) += isadma.o
-snd-$(CONFIG_SND_OSSEMUL) += sound_oss.o info_oss.o
-snd-$(CONFIG_SND_VMASTER) += vmaster.o
-snd-$(CONFIG_SND_KCTL_JACK) += ctljack.o
-snd-$(CONFIG_SND_JACK) += jack.o
-
-snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \
- pcm_memory.o
-
-snd-page-alloc-y := memalloc.o
-snd-page-alloc-$(CONFIG_SND_DMA_SGBUF) += sgbuf.o
-
-snd-rawmidi-objs := rawmidi.o
-snd-timer-objs := timer.o
-snd-hrtimer-objs := hrtimer.o
-snd-rtctimer-objs := rtctimer.o
-snd-hwdep-objs := hwdep.o
-
-snd-compress-objs := compress_offload.o
-
-obj-$(CONFIG_SND) += snd.o
-obj-$(CONFIG_SND_HWDEP) += snd-hwdep.o
-obj-$(CONFIG_SND_TIMER) += snd-timer.o
-obj-$(CONFIG_SND_HRTIMER) += snd-hrtimer.o
-obj-$(CONFIG_SND_RTCTIMER) += snd-rtctimer.o
-obj-$(CONFIG_SND_PCM) += snd-pcm.o snd-page-alloc.o
-obj-$(CONFIG_SND_RAWMIDI) += snd-rawmidi.o
-
-obj-$(CONFIG_SND_OSSEMUL) += oss/
-obj-$(CONFIG_SND_SEQUENCER) += seq/
-
-obj-$(CONFIG_SND_COMPRESS_OFFLOAD) += snd-compress.o
diff --git a/ANDROID_3.4.5/sound/core/compress_offload.c b/ANDROID_3.4.5/sound/core/compress_offload.c
deleted file mode 100644
index a58cf359..00000000
--- a/ANDROID_3.4.5/sound/core/compress_offload.c
+++ /dev/null
@@ -1,773 +0,0 @@
-/*
- * compress_core.c - compress offload core
- *
- * Copyright (C) 2011 Intel Corporation
- * Authors: Vinod Koul <vinod.koul@linux.intel.com>
- * Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- */
-#define FORMAT(fmt) "%s: %d: " fmt, __func__, __LINE__
-#define pr_fmt(fmt) KBUILD_MODNAME ": " FORMAT(fmt)
-
-#include <linux/file.h>
-#include <linux/fs.h>
-#include <linux/list.h>
-#include <linux/mm.h>
-#include <linux/mutex.h>
-#include <linux/poll.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/uio.h>
-#include <linux/uaccess.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/compress_params.h>
-#include <sound/compress_offload.h>
-#include <sound/compress_driver.h>
-
-/* TODO:
- * - add substream support for multiple devices in case of
- * SND_DYNAMIC_MINORS is not used
- * - Multiple node representation
- * driver should be able to register multiple nodes
- */
-
-static DEFINE_MUTEX(device_mutex);
-
-struct snd_compr_file {
- unsigned long caps;
- struct snd_compr_stream stream;
-};
-
-/*
- * a note on stream states used:
- * we use follwing states in the compressed core
- * SNDRV_PCM_STATE_OPEN: When stream has been opened.
- * SNDRV_PCM_STATE_SETUP: When stream has been initialized. This is done by
- * calling SNDRV_COMPRESS_SET_PARAMS. running streams will come to this
- * state at stop by calling SNDRV_COMPRESS_STOP, or at end of drain.
- * SNDRV_PCM_STATE_RUNNING: When stream has been started and is
- * decoding/encoding and rendering/capturing data.
- * SNDRV_PCM_STATE_DRAINING: When stream is draining current data. This is done
- * by calling SNDRV_COMPRESS_DRAIN.
- * SNDRV_PCM_STATE_PAUSED: When stream is paused. This is done by calling
- * SNDRV_COMPRESS_PAUSE. It can be stopped or resumed by calling
- * SNDRV_COMPRESS_STOP or SNDRV_COMPRESS_RESUME respectively.
- */
-static int snd_compr_open(struct inode *inode, struct file *f)
-{
- struct snd_compr *compr;
- struct snd_compr_file *data;
- struct snd_compr_runtime *runtime;
- enum snd_compr_direction dirn;
- int maj = imajor(inode);
- int ret;
-
- if (f->f_flags & O_WRONLY)
- dirn = SND_COMPRESS_PLAYBACK;
- else if (f->f_flags & O_RDONLY)
- dirn = SND_COMPRESS_CAPTURE;
- else {
- pr_err("invalid direction\n");
- return -EINVAL;
- }
-
- if (maj == snd_major)
- compr = snd_lookup_minor_data(iminor(inode),
- SNDRV_DEVICE_TYPE_COMPRESS);
- else
- return -EBADFD;
-
- if (compr == NULL) {
- pr_err("no device data!!!\n");
- return -ENODEV;
- }
-
- if (dirn != compr->direction) {
- pr_err("this device doesn't support this direction\n");
- snd_card_unref(compr->card);
- return -EINVAL;
- }
-
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (!data) {
- snd_card_unref(compr->card);
- return -ENOMEM;
- }
- data->stream.ops = compr->ops;
- data->stream.direction = dirn;
- data->stream.private_data = compr->private_data;
- data->stream.device = compr;
- runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
- if (!runtime) {
- kfree(data);
- snd_card_unref(compr->card);
- return -ENOMEM;
- }
- runtime->state = SNDRV_PCM_STATE_OPEN;
- init_waitqueue_head(&runtime->sleep);
- data->stream.runtime = runtime;
- f->private_data = (void *)data;
- mutex_lock(&compr->lock);
- ret = compr->ops->open(&data->stream);
- mutex_unlock(&compr->lock);
- if (ret) {
- kfree(runtime);
- kfree(data);
- }
- snd_card_unref(compr->card);
- return 0;
-}
-
-static int snd_compr_free(struct inode *inode, struct file *f)
-{
- struct snd_compr_file *data = f->private_data;
- data->stream.ops->free(&data->stream);
- kfree(data->stream.runtime->buffer);
- kfree(data->stream.runtime);
- kfree(data);
- return 0;
-}
-
-static void snd_compr_update_tstamp(struct snd_compr_stream *stream,
- struct snd_compr_tstamp *tstamp)
-{
- if (!stream->ops->pointer)
- return;
- stream->ops->pointer(stream, tstamp);
- pr_debug("dsp consumed till %d total %d bytes\n",
- tstamp->byte_offset, tstamp->copied_total);
- stream->runtime->hw_pointer = tstamp->byte_offset;
- stream->runtime->total_bytes_transferred = tstamp->copied_total;
-}
-
-static size_t snd_compr_calc_avail(struct snd_compr_stream *stream,
- struct snd_compr_avail *avail)
-{
- long avail_calc; /*this needs to be signed variable */
-
- snd_compr_update_tstamp(stream, &avail->tstamp);
-
- /* FIXME: This needs to be different for capture stream,
- available is # of compressed data, for playback it's
- remainder of buffer */
-
- if (stream->runtime->total_bytes_available == 0 &&
- stream->runtime->state == SNDRV_PCM_STATE_SETUP) {
- pr_debug("detected init and someone forgot to do a write\n");
- return stream->runtime->buffer_size;
- }
- pr_debug("app wrote %lld, DSP consumed %lld\n",
- stream->runtime->total_bytes_available,
- stream->runtime->total_bytes_transferred);
- if (stream->runtime->total_bytes_available ==
- stream->runtime->total_bytes_transferred) {
- pr_debug("both pointers are same, returning full avail\n");
- return stream->runtime->buffer_size;
- }
-
- /* FIXME: this routine isn't consistent, in one test we use
- * cumulative values and in the other byte offsets. Do we
- * really need the byte offsets if the cumulative values have
- * been updated? In the PCM interface app_ptr and hw_ptr are
- * already cumulative */
-
- avail_calc = stream->runtime->buffer_size -
- (stream->runtime->app_pointer - stream->runtime->hw_pointer);
- pr_debug("calc avail as %ld, app_ptr %lld, hw+ptr %lld\n", avail_calc,
- stream->runtime->app_pointer,
- stream->runtime->hw_pointer);
- if (avail_calc >= stream->runtime->buffer_size)
- avail_calc -= stream->runtime->buffer_size;
- pr_debug("ret avail as %ld\n", avail_calc);
- avail->avail = avail_calc;
- return avail_calc;
-}
-
-static inline size_t snd_compr_get_avail(struct snd_compr_stream *stream)
-{
- struct snd_compr_avail avail;
-
- return snd_compr_calc_avail(stream, &avail);
-}
-
-static int
-snd_compr_ioctl_avail(struct snd_compr_stream *stream, unsigned long arg)
-{
- struct snd_compr_avail ioctl_avail;
- size_t avail;
-
- avail = snd_compr_calc_avail(stream, &ioctl_avail);
- ioctl_avail.avail = avail;
-
- if (copy_to_user((__u64 __user *)arg,
- &ioctl_avail, sizeof(ioctl_avail)))
- return -EFAULT;
- return 0;
-}
-
-static int snd_compr_write_data(struct snd_compr_stream *stream,
- const char __user *buf, size_t count)
-{
- void *dstn;
- size_t copy;
- struct snd_compr_runtime *runtime = stream->runtime;
-
- dstn = runtime->buffer + runtime->app_pointer;
- pr_debug("copying %ld at %lld\n",
- (unsigned long)count, runtime->app_pointer);
- if (count < runtime->buffer_size - runtime->app_pointer) {
- if (copy_from_user(dstn, buf, count))
- return -EFAULT;
- runtime->app_pointer += count;
- } else {
- copy = runtime->buffer_size - runtime->app_pointer;
- if (copy_from_user(dstn, buf, copy))
- return -EFAULT;
- if (copy_from_user(runtime->buffer, buf + copy, count - copy))
- return -EFAULT;
- runtime->app_pointer = count - copy;
- }
- /* if DSP cares, let it know data has been written */
- if (stream->ops->ack)
- stream->ops->ack(stream, count);
- return count;
-}
-
-static ssize_t snd_compr_write(struct file *f, const char __user *buf,
- size_t count, loff_t *offset)
-{
- struct snd_compr_file *data = f->private_data;
- struct snd_compr_stream *stream;
- size_t avail;
- int retval;
-
- if (snd_BUG_ON(!data))
- return -EFAULT;
-
- stream = &data->stream;
- mutex_lock(&stream->device->lock);
- /* write is allowed when stream is running or has been steup */
- if (stream->runtime->state != SNDRV_PCM_STATE_SETUP &&
- stream->runtime->state != SNDRV_PCM_STATE_RUNNING) {
- mutex_unlock(&stream->device->lock);
- return -EBADFD;
- }
-
- avail = snd_compr_get_avail(stream);
- pr_debug("avail returned %ld\n", (unsigned long)avail);
- /* calculate how much we can write to buffer */
- if (avail > count)
- avail = count;
-
- if (stream->ops->copy)
- retval = stream->ops->copy(stream, buf, avail);
- else
- retval = snd_compr_write_data(stream, buf, avail);
- if (retval > 0)
- stream->runtime->total_bytes_available += retval;
-
- /* while initiating the stream, write should be called before START
- * call, so in setup move state */
- if (stream->runtime->state == SNDRV_PCM_STATE_SETUP) {
- stream->runtime->state = SNDRV_PCM_STATE_PREPARED;
- pr_debug("stream prepared, Houston we are good to go\n");
- }
-
- mutex_unlock(&stream->device->lock);
- return retval;
-}
-
-
-static ssize_t snd_compr_read(struct file *f, char __user *buf,
- size_t count, loff_t *offset)
-{
- return -ENXIO;
-}
-
-static int snd_compr_mmap(struct file *f, struct vm_area_struct *vma)
-{
- return -ENXIO;
-}
-
-static inline int snd_compr_get_poll(struct snd_compr_stream *stream)
-{
- if (stream->direction == SND_COMPRESS_PLAYBACK)
- return POLLOUT | POLLWRNORM;
- else
- return POLLIN | POLLRDNORM;
-}
-
-static unsigned int snd_compr_poll(struct file *f, poll_table *wait)
-{
- struct snd_compr_file *data = f->private_data;
- struct snd_compr_stream *stream;
- size_t avail;
- int retval = 0;
-
- if (snd_BUG_ON(!data))
- return -EFAULT;
- stream = &data->stream;
- if (snd_BUG_ON(!stream))
- return -EFAULT;
-
- mutex_lock(&stream->device->lock);
- if (stream->runtime->state == SNDRV_PCM_STATE_PAUSED ||
- stream->runtime->state == SNDRV_PCM_STATE_OPEN) {
- retval = -EBADFD;
- goto out;
- }
- poll_wait(f, &stream->runtime->sleep, wait);
-
- avail = snd_compr_get_avail(stream);
- pr_debug("avail is %ld\n", (unsigned long)avail);
- /* check if we have at least one fragment to fill */
- switch (stream->runtime->state) {
- case SNDRV_PCM_STATE_DRAINING:
- /* stream has been woken up after drain is complete
- * draining done so set stream state to stopped
- */
- retval = snd_compr_get_poll(stream);
- stream->runtime->state = SNDRV_PCM_STATE_SETUP;
- break;
- case SNDRV_PCM_STATE_RUNNING:
- case SNDRV_PCM_STATE_PREPARED:
- case SNDRV_PCM_STATE_PAUSED:
- if (avail >= stream->runtime->fragment_size)
- retval = snd_compr_get_poll(stream);
- break;
- default:
- if (stream->direction == SND_COMPRESS_PLAYBACK)
- retval = POLLOUT | POLLWRNORM | POLLERR;
- else
- retval = POLLIN | POLLRDNORM | POLLERR;
- break;
- }
-out:
- mutex_unlock(&stream->device->lock);
- return retval;
-}
-
-static int
-snd_compr_get_caps(struct snd_compr_stream *stream, unsigned long arg)
-{
- int retval;
- struct snd_compr_caps caps;
-
- if (!stream->ops->get_caps)
- return -ENXIO;
-
- retval = stream->ops->get_caps(stream, &caps);
- if (retval)
- goto out;
- if (copy_to_user((void __user *)arg, &caps, sizeof(caps)))
- retval = -EFAULT;
-out:
- return retval;
-}
-
-static int
-snd_compr_get_codec_caps(struct snd_compr_stream *stream, unsigned long arg)
-{
- int retval;
- struct snd_compr_codec_caps *caps;
-
- if (!stream->ops->get_codec_caps)
- return -ENXIO;
-
- caps = kmalloc(sizeof(*caps), GFP_KERNEL);
- if (!caps)
- return -ENOMEM;
-
- retval = stream->ops->get_codec_caps(stream, caps);
- if (retval)
- goto out;
- if (copy_to_user((void __user *)arg, caps, sizeof(*caps)))
- retval = -EFAULT;
-
-out:
- kfree(caps);
- return retval;
-}
-
-/* revisit this with snd_pcm_preallocate_xxx */
-static int snd_compr_allocate_buffer(struct snd_compr_stream *stream,
- struct snd_compr_params *params)
-{
- unsigned int buffer_size;
- void *buffer;
-
- buffer_size = params->buffer.fragment_size * params->buffer.fragments;
- if (stream->ops->copy) {
- buffer = NULL;
- /* if copy is defined the driver will be required to copy
- * the data from core
- */
- } else {
- buffer = kmalloc(buffer_size, GFP_KERNEL);
- if (!buffer)
- return -ENOMEM;
- }
- stream->runtime->fragment_size = params->buffer.fragment_size;
- stream->runtime->fragments = params->buffer.fragments;
- stream->runtime->buffer = buffer;
- stream->runtime->buffer_size = buffer_size;
- return 0;
-}
-
-static int
-snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
-{
- struct snd_compr_params *params;
- int retval;
-
- if (stream->runtime->state == SNDRV_PCM_STATE_OPEN) {
- /*
- * we should allow parameter change only when stream has been
- * opened not in other cases
- */
- params = kmalloc(sizeof(*params), GFP_KERNEL);
- if (!params)
- return -ENOMEM;
- if (copy_from_user(params, (void __user *)arg, sizeof(*params))) {
- retval = -EFAULT;
- goto out;
- }
- retval = snd_compr_allocate_buffer(stream, params);
- if (retval) {
- retval = -ENOMEM;
- goto out;
- }
- retval = stream->ops->set_params(stream, params);
- if (retval)
- goto out;
- stream->runtime->state = SNDRV_PCM_STATE_SETUP;
- } else {
- return -EPERM;
- }
-out:
- kfree(params);
- return retval;
-}
-
-static int
-snd_compr_get_params(struct snd_compr_stream *stream, unsigned long arg)
-{
- struct snd_codec *params;
- int retval;
-
- if (!stream->ops->get_params)
- return -EBADFD;
-
- params = kmalloc(sizeof(*params), GFP_KERNEL);
- if (!params)
- return -ENOMEM;
- retval = stream->ops->get_params(stream, params);
- if (retval)
- goto out;
- if (copy_to_user((char __user *)arg, params, sizeof(*params)))
- retval = -EFAULT;
-
-out:
- kfree(params);
- return retval;
-}
-
-static inline int
-snd_compr_tstamp(struct snd_compr_stream *stream, unsigned long arg)
-{
- struct snd_compr_tstamp tstamp;
-
- snd_compr_update_tstamp(stream, &tstamp);
- return copy_to_user((struct snd_compr_tstamp __user *)arg,
- &tstamp, sizeof(tstamp)) ? -EFAULT : 0;
-}
-
-static int snd_compr_pause(struct snd_compr_stream *stream)
-{
- int retval;
-
- if (stream->runtime->state != SNDRV_PCM_STATE_RUNNING)
- return -EPERM;
- retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_PUSH);
- if (!retval) {
- stream->runtime->state = SNDRV_PCM_STATE_PAUSED;
- wake_up(&stream->runtime->sleep);
- }
- return retval;
-}
-
-static int snd_compr_resume(struct snd_compr_stream *stream)
-{
- int retval;
-
- if (stream->runtime->state != SNDRV_PCM_STATE_PAUSED)
- return -EPERM;
- retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
- if (!retval)
- stream->runtime->state = SNDRV_PCM_STATE_RUNNING;
- return retval;
-}
-
-static int snd_compr_start(struct snd_compr_stream *stream)
-{
- int retval;
-
- if (stream->runtime->state != SNDRV_PCM_STATE_PREPARED)
- return -EPERM;
- retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_START);
- if (!retval)
- stream->runtime->state = SNDRV_PCM_STATE_RUNNING;
- return retval;
-}
-
-static int snd_compr_stop(struct snd_compr_stream *stream)
-{
- int retval;
-
- if (stream->runtime->state == SNDRV_PCM_STATE_PREPARED ||
- stream->runtime->state == SNDRV_PCM_STATE_SETUP)
- return -EPERM;
- retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP);
- if (!retval) {
- stream->runtime->state = SNDRV_PCM_STATE_SETUP;
- wake_up(&stream->runtime->sleep);
- }
- return retval;
-}
-
-static int snd_compr_drain(struct snd_compr_stream *stream)
-{
- int retval;
-
- if (stream->runtime->state == SNDRV_PCM_STATE_PREPARED ||
- stream->runtime->state == SNDRV_PCM_STATE_SETUP)
- return -EPERM;
- retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_DRAIN);
- if (!retval) {
- stream->runtime->state = SNDRV_PCM_STATE_DRAINING;
- wake_up(&stream->runtime->sleep);
- }
- return retval;
-}
-
-static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
-{
- struct snd_compr_file *data = f->private_data;
- struct snd_compr_stream *stream;
- int retval = -ENOTTY;
-
- if (snd_BUG_ON(!data))
- return -EFAULT;
- stream = &data->stream;
- if (snd_BUG_ON(!stream))
- return -EFAULT;
- mutex_lock(&stream->device->lock);
- switch (_IOC_NR(cmd)) {
- case _IOC_NR(SNDRV_COMPRESS_IOCTL_VERSION):
- put_user(SNDRV_COMPRESS_VERSION,
- (int __user *)arg) ? -EFAULT : 0;
- break;
- case _IOC_NR(SNDRV_COMPRESS_GET_CAPS):
- retval = snd_compr_get_caps(stream, arg);
- break;
- case _IOC_NR(SNDRV_COMPRESS_GET_CODEC_CAPS):
- retval = snd_compr_get_codec_caps(stream, arg);
- break;
- case _IOC_NR(SNDRV_COMPRESS_SET_PARAMS):
- retval = snd_compr_set_params(stream, arg);
- break;
- case _IOC_NR(SNDRV_COMPRESS_GET_PARAMS):
- retval = snd_compr_get_params(stream, arg);
- break;
- case _IOC_NR(SNDRV_COMPRESS_TSTAMP):
- retval = snd_compr_tstamp(stream, arg);
- break;
- case _IOC_NR(SNDRV_COMPRESS_AVAIL):
- retval = snd_compr_ioctl_avail(stream, arg);
- break;
- case _IOC_NR(SNDRV_COMPRESS_PAUSE):
- retval = snd_compr_pause(stream);
- break;
- case _IOC_NR(SNDRV_COMPRESS_RESUME):
- retval = snd_compr_resume(stream);
- break;
- case _IOC_NR(SNDRV_COMPRESS_START):
- retval = snd_compr_start(stream);
- break;
- case _IOC_NR(SNDRV_COMPRESS_STOP):
- retval = snd_compr_stop(stream);
- break;
- case _IOC_NR(SNDRV_COMPRESS_DRAIN):
- retval = snd_compr_drain(stream);
- break;
- }
- mutex_unlock(&stream->device->lock);
- return retval;
-}
-
-static const struct file_operations snd_compr_file_ops = {
- .owner = THIS_MODULE,
- .open = snd_compr_open,
- .release = snd_compr_free,
- .write = snd_compr_write,
- .read = snd_compr_read,
- .unlocked_ioctl = snd_compr_ioctl,
- .mmap = snd_compr_mmap,
- .poll = snd_compr_poll,
-};
-
-static int snd_compress_dev_register(struct snd_device *device)
-{
- int ret = -EINVAL;
- char str[16];
- struct snd_compr *compr;
-
- if (snd_BUG_ON(!device || !device->device_data))
- return -EBADFD;
- compr = device->device_data;
-
- sprintf(str, "comprC%iD%i", compr->card->number, compr->device);
- pr_debug("reg %s for device %s, direction %d\n", str, compr->name,
- compr->direction);
- /* register compressed device */
- ret = snd_register_device(SNDRV_DEVICE_TYPE_COMPRESS, compr->card,
- compr->device, &snd_compr_file_ops, compr, str);
- if (ret < 0) {
- pr_err("snd_register_device failed\n %d", ret);
- return ret;
- }
- return ret;
-
-}
-
-static int snd_compress_dev_disconnect(struct snd_device *device)
-{
- struct snd_compr *compr;
-
- compr = device->device_data;
- snd_unregister_device(compr->direction, compr->card, compr->device);
- return 0;
-}
-
-/*
- * snd_compress_new: create new compress device
- * @card: sound card pointer
- * @device: device number
- * @dirn: device direction, should be of type enum snd_compr_direction
- * @compr: compress device pointer
- */
-int snd_compress_new(struct snd_card *card, int device,
- int dirn, struct snd_compr *compr)
-{
- static struct snd_device_ops ops = {
- .dev_free = NULL,
- .dev_register = snd_compress_dev_register,
- .dev_disconnect = snd_compress_dev_disconnect,
- };
-
- compr->card = card;
- compr->device = device;
- compr->direction = dirn;
- return snd_device_new(card, SNDRV_DEV_COMPRESS, compr, &ops);
-}
-EXPORT_SYMBOL_GPL(snd_compress_new);
-
-static int snd_compress_add_device(struct snd_compr *device)
-{
- int ret;
-
- if (!device->card)
- return -EINVAL;
-
- /* register the card */
- ret = snd_card_register(device->card);
- if (ret)
- goto out;
- return 0;
-
-out:
- pr_err("failed with %d\n", ret);
- return ret;
-
-}
-
-static int snd_compress_remove_device(struct snd_compr *device)
-{
- return snd_card_free(device->card);
-}
-
-/**
- * snd_compress_register - register compressed device
- *
- * @device: compressed device to register
- */
-int snd_compress_register(struct snd_compr *device)
-{
- int retval;
-
- if (device->name == NULL || device->dev == NULL || device->ops == NULL)
- return -EINVAL;
-
- pr_debug("Registering compressed device %s\n", device->name);
- if (snd_BUG_ON(!device->ops->open))
- return -EINVAL;
- if (snd_BUG_ON(!device->ops->free))
- return -EINVAL;
- if (snd_BUG_ON(!device->ops->set_params))
- return -EINVAL;
- if (snd_BUG_ON(!device->ops->trigger))
- return -EINVAL;
-
- mutex_init(&device->lock);
-
- /* register a compressed card */
- mutex_lock(&device_mutex);
- retval = snd_compress_add_device(device);
- mutex_unlock(&device_mutex);
- return retval;
-}
-EXPORT_SYMBOL_GPL(snd_compress_register);
-
-int snd_compress_deregister(struct snd_compr *device)
-{
- pr_debug("Removing compressed device %s\n", device->name);
- mutex_lock(&device_mutex);
- snd_compress_remove_device(device);
- mutex_unlock(&device_mutex);
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_compress_deregister);
-
-static int __init snd_compress_init(void)
-{
- return 0;
-}
-
-static void __exit snd_compress_exit(void)
-{
-}
-
-module_init(snd_compress_init);
-module_exit(snd_compress_exit);
-
-MODULE_DESCRIPTION("ALSA Compressed offload framework");
-MODULE_AUTHOR("Vinod Koul <vinod.koul@linux.intel.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/sound/core/control.c b/ANDROID_3.4.5/sound/core/control.c
deleted file mode 100644
index daa4fc88..00000000
--- a/ANDROID_3.4.5/sound/core/control.c
+++ /dev/null
@@ -1,1726 +0,0 @@
-/*
- * Routines for driver control interface
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/threads.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/minors.h>
-#include <sound/info.h>
-#include <sound/control.h>
-
-/* max number of user-defined controls */
-#define MAX_USER_CONTROLS 32
-#define MAX_CONTROL_COUNT 1028
-
-struct snd_kctl_ioctl {
- struct list_head list; /* list of all ioctls */
- snd_kctl_ioctl_func_t fioctl;
-};
-
-static DECLARE_RWSEM(snd_ioctl_rwsem);
-static LIST_HEAD(snd_control_ioctls);
-#ifdef CONFIG_COMPAT
-static LIST_HEAD(snd_control_compat_ioctls);
-#endif
-
-static int snd_ctl_open(struct inode *inode, struct file *file)
-{
- unsigned long flags;
- struct snd_card *card;
- struct snd_ctl_file *ctl;
- int err;
-
- err = nonseekable_open(inode, file);
- if (err < 0)
- return err;
-
- card = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_CONTROL);
- if (!card) {
- err = -ENODEV;
- goto __error1;
- }
- err = snd_card_file_add(card, file);
- if (err < 0) {
- err = -ENODEV;
- goto __error1;
- }
- if (!try_module_get(card->module)) {
- err = -EFAULT;
- goto __error2;
- }
- ctl = kzalloc(sizeof(*ctl), GFP_KERNEL);
- if (ctl == NULL) {
- err = -ENOMEM;
- goto __error;
- }
- INIT_LIST_HEAD(&ctl->events);
- init_waitqueue_head(&ctl->change_sleep);
- spin_lock_init(&ctl->read_lock);
- ctl->card = card;
- ctl->prefer_pcm_subdevice = -1;
- ctl->prefer_rawmidi_subdevice = -1;
- ctl->pid = get_pid(task_pid(current));
- file->private_data = ctl;
- write_lock_irqsave(&card->ctl_files_rwlock, flags);
- list_add_tail(&ctl->list, &card->ctl_files);
- write_unlock_irqrestore(&card->ctl_files_rwlock, flags);
- snd_card_unref(card);
- return 0;
-
- __error:
- module_put(card->module);
- __error2:
- snd_card_file_remove(card, file);
- __error1:
- if (card)
- snd_card_unref(card);
- return err;
-}
-
-static void snd_ctl_empty_read_queue(struct snd_ctl_file * ctl)
-{
- unsigned long flags;
- struct snd_kctl_event *cread;
-
- spin_lock_irqsave(&ctl->read_lock, flags);
- while (!list_empty(&ctl->events)) {
- cread = snd_kctl_event(ctl->events.next);
- list_del(&cread->list);
- kfree(cread);
- }
- spin_unlock_irqrestore(&ctl->read_lock, flags);
-}
-
-static int snd_ctl_release(struct inode *inode, struct file *file)
-{
- unsigned long flags;
- struct snd_card *card;
- struct snd_ctl_file *ctl;
- struct snd_kcontrol *control;
- unsigned int idx;
-
- ctl = file->private_data;
- file->private_data = NULL;
- card = ctl->card;
- write_lock_irqsave(&card->ctl_files_rwlock, flags);
- list_del(&ctl->list);
- write_unlock_irqrestore(&card->ctl_files_rwlock, flags);
- down_write(&card->controls_rwsem);
- list_for_each_entry(control, &card->controls, list)
- for (idx = 0; idx < control->count; idx++)
- if (control->vd[idx].owner == ctl)
- control->vd[idx].owner = NULL;
- up_write(&card->controls_rwsem);
- snd_ctl_empty_read_queue(ctl);
- put_pid(ctl->pid);
- kfree(ctl);
- module_put(card->module);
- snd_card_file_remove(card, file);
- return 0;
-}
-
-void snd_ctl_notify(struct snd_card *card, unsigned int mask,
- struct snd_ctl_elem_id *id)
-{
- unsigned long flags;
- struct snd_ctl_file *ctl;
- struct snd_kctl_event *ev;
-
- if (snd_BUG_ON(!card || !id))
- return;
- read_lock(&card->ctl_files_rwlock);
-#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
- card->mixer_oss_change_count++;
-#endif
- list_for_each_entry(ctl, &card->ctl_files, list) {
- if (!ctl->subscribed)
- continue;
- spin_lock_irqsave(&ctl->read_lock, flags);
- list_for_each_entry(ev, &ctl->events, list) {
- if (ev->id.numid == id->numid) {
- ev->mask |= mask;
- goto _found;
- }
- }
- ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
- if (ev) {
- ev->id = *id;
- ev->mask = mask;
- list_add_tail(&ev->list, &ctl->events);
- } else {
- snd_printk(KERN_ERR "No memory available to allocate event\n");
- }
- _found:
- wake_up(&ctl->change_sleep);
- spin_unlock_irqrestore(&ctl->read_lock, flags);
- kill_fasync(&ctl->fasync, SIGIO, POLL_IN);
- }
- read_unlock(&card->ctl_files_rwlock);
-}
-
-EXPORT_SYMBOL(snd_ctl_notify);
-
-/**
- * snd_ctl_new - create a control instance from the template
- * @control: the control template
- * @access: the default control access
- *
- * Allocates a new struct snd_kcontrol instance and copies the given template
- * to the new instance. It does not copy volatile data (access).
- *
- * Returns the pointer of the new instance, or NULL on failure.
- */
-static struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control,
- unsigned int access)
-{
- struct snd_kcontrol *kctl;
- unsigned int idx;
-
- if (snd_BUG_ON(!control || !control->count))
- return NULL;
-
- if (control->count > MAX_CONTROL_COUNT)
- return NULL;
-
- kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL);
- if (kctl == NULL) {
- snd_printk(KERN_ERR "Cannot allocate control instance\n");
- return NULL;
- }
- *kctl = *control;
- for (idx = 0; idx < kctl->count; idx++)
- kctl->vd[idx].access = access;
- return kctl;
-}
-
-/**
- * snd_ctl_new1 - create a control instance from the template
- * @ncontrol: the initialization record
- * @private_data: the private data to set
- *
- * Allocates a new struct snd_kcontrol instance and initialize from the given
- * template. When the access field of ncontrol is 0, it's assumed as
- * READWRITE access. When the count field is 0, it's assumes as one.
- *
- * Returns the pointer of the newly generated instance, or NULL on failure.
- */
-struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
- void *private_data)
-{
- struct snd_kcontrol kctl;
- unsigned int access;
-
- if (snd_BUG_ON(!ncontrol || !ncontrol->info))
- return NULL;
- memset(&kctl, 0, sizeof(kctl));
- kctl.id.iface = ncontrol->iface;
- kctl.id.device = ncontrol->device;
- kctl.id.subdevice = ncontrol->subdevice;
- if (ncontrol->name) {
- strlcpy(kctl.id.name, ncontrol->name, sizeof(kctl.id.name));
- if (strcmp(ncontrol->name, kctl.id.name) != 0)
- snd_printk(KERN_WARNING
- "Control name '%s' truncated to '%s'\n",
- ncontrol->name, kctl.id.name);
- }
- kctl.id.index = ncontrol->index;
- kctl.count = ncontrol->count ? ncontrol->count : 1;
- access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
- (ncontrol->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
- SNDRV_CTL_ELEM_ACCESS_INACTIVE|
- SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE|
- SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND|
- SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK));
- kctl.info = ncontrol->info;
- kctl.get = ncontrol->get;
- kctl.put = ncontrol->put;
- kctl.tlv.p = ncontrol->tlv.p;
- kctl.private_value = ncontrol->private_value;
- kctl.private_data = private_data;
- return snd_ctl_new(&kctl, access);
-}
-
-EXPORT_SYMBOL(snd_ctl_new1);
-
-/**
- * snd_ctl_free_one - release the control instance
- * @kcontrol: the control instance
- *
- * Releases the control instance created via snd_ctl_new()
- * or snd_ctl_new1().
- * Don't call this after the control was added to the card.
- */
-void snd_ctl_free_one(struct snd_kcontrol *kcontrol)
-{
- if (kcontrol) {
- if (kcontrol->private_free)
- kcontrol->private_free(kcontrol);
- kfree(kcontrol);
- }
-}
-
-EXPORT_SYMBOL(snd_ctl_free_one);
-
-static bool snd_ctl_remove_numid_conflict(struct snd_card *card,
- unsigned int count)
-{
- struct snd_kcontrol *kctl;
-
- list_for_each_entry(kctl, &card->controls, list) {
- if (kctl->id.numid < card->last_numid + 1 + count &&
- kctl->id.numid + kctl->count > card->last_numid + 1) {
- card->last_numid = kctl->id.numid + kctl->count - 1;
- return true;
- }
- }
- return false;
-}
-
-static int snd_ctl_find_hole(struct snd_card *card, unsigned int count)
-{
- unsigned int iter = 100000;
-
- while (snd_ctl_remove_numid_conflict(card, count)) {
- if (--iter == 0) {
- /* this situation is very unlikely */
- snd_printk(KERN_ERR "unable to allocate new control numid\n");
- return -ENOMEM;
- }
- }
- return 0;
-}
-
-/**
- * snd_ctl_add - add the control instance to the card
- * @card: the card instance
- * @kcontrol: the control instance to add
- *
- * Adds the control instance created via snd_ctl_new() or
- * snd_ctl_new1() to the given card. Assigns also an unique
- * numid used for fast search.
- *
- * Returns zero if successful, or a negative error code on failure.
- *
- * It frees automatically the control which cannot be added.
- */
-int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
-{
- struct snd_ctl_elem_id id;
- unsigned int idx;
- int err = -EINVAL;
-
- if (! kcontrol)
- return err;
- if (snd_BUG_ON(!card || !kcontrol->info))
- goto error;
- id = kcontrol->id;
- down_write(&card->controls_rwsem);
- if (snd_ctl_find_id(card, &id)) {
- up_write(&card->controls_rwsem);
- snd_printd(KERN_ERR "control %i:%i:%i:%s:%i is already present\n",
- id.iface,
- id.device,
- id.subdevice,
- id.name,
- id.index);
- err = -EBUSY;
- goto error;
- }
- if (snd_ctl_find_hole(card, kcontrol->count) < 0) {
- up_write(&card->controls_rwsem);
- err = -ENOMEM;
- goto error;
- }
- list_add_tail(&kcontrol->list, &card->controls);
- card->controls_count += kcontrol->count;
- kcontrol->id.numid = card->last_numid + 1;
- card->last_numid += kcontrol->count;
- up_write(&card->controls_rwsem);
- for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
- return 0;
-
- error:
- snd_ctl_free_one(kcontrol);
- return err;
-}
-
-EXPORT_SYMBOL(snd_ctl_add);
-
-/**
- * snd_ctl_replace - replace the control instance of the card
- * @card: the card instance
- * @kcontrol: the control instance to replace
- * @add_on_replace: add the control if not already added
- *
- * Replaces the given control. If the given control does not exist
- * and the add_on_replace flag is set, the control is added. If the
- * control exists, it is destroyed first.
- *
- * Returns zero if successful, or a negative error code on failure.
- *
- * It frees automatically the control which cannot be added or replaced.
- */
-int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol,
- bool add_on_replace)
-{
- struct snd_ctl_elem_id id;
- unsigned int idx;
- struct snd_kcontrol *old;
- int ret;
-
- if (!kcontrol)
- return -EINVAL;
- if (snd_BUG_ON(!card || !kcontrol->info)) {
- ret = -EINVAL;
- goto error;
- }
- id = kcontrol->id;
- down_write(&card->controls_rwsem);
- old = snd_ctl_find_id(card, &id);
- if (!old) {
- if (add_on_replace)
- goto add;
- up_write(&card->controls_rwsem);
- ret = -EINVAL;
- goto error;
- }
- ret = snd_ctl_remove(card, old);
- if (ret < 0) {
- up_write(&card->controls_rwsem);
- goto error;
- }
-add:
- if (snd_ctl_find_hole(card, kcontrol->count) < 0) {
- up_write(&card->controls_rwsem);
- ret = -ENOMEM;
- goto error;
- }
- list_add_tail(&kcontrol->list, &card->controls);
- card->controls_count += kcontrol->count;
- kcontrol->id.numid = card->last_numid + 1;
- card->last_numid += kcontrol->count;
- up_write(&card->controls_rwsem);
- for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
- return 0;
-
-error:
- snd_ctl_free_one(kcontrol);
- return ret;
-}
-EXPORT_SYMBOL(snd_ctl_replace);
-
-/**
- * snd_ctl_remove - remove the control from the card and release it
- * @card: the card instance
- * @kcontrol: the control instance to remove
- *
- * Removes the control from the card and then releases the instance.
- * You don't need to call snd_ctl_free_one(). You must be in
- * the write lock - down_write(&card->controls_rwsem).
- *
- * Returns 0 if successful, or a negative error code on failure.
- */
-int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol)
-{
- struct snd_ctl_elem_id id;
- unsigned int idx;
-
- if (snd_BUG_ON(!card || !kcontrol))
- return -EINVAL;
- list_del(&kcontrol->list);
- card->controls_count -= kcontrol->count;
- id = kcontrol->id;
- for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_REMOVE, &id);
- snd_ctl_free_one(kcontrol);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_ctl_remove);
-
-/**
- * snd_ctl_remove_id - remove the control of the given id and release it
- * @card: the card instance
- * @id: the control id to remove
- *
- * Finds the control instance with the given id, removes it from the
- * card list and releases it.
- *
- * Returns 0 if successful, or a negative error code on failure.
- */
-int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id)
-{
- struct snd_kcontrol *kctl;
- int ret;
-
- down_write(&card->controls_rwsem);
- kctl = snd_ctl_find_id(card, id);
- if (kctl == NULL) {
- up_write(&card->controls_rwsem);
- return -ENOENT;
- }
- ret = snd_ctl_remove(card, kctl);
- up_write(&card->controls_rwsem);
- return ret;
-}
-
-EXPORT_SYMBOL(snd_ctl_remove_id);
-
-/**
- * snd_ctl_remove_user_ctl - remove and release the unlocked user control
- * @file: active control handle
- * @id: the control id to remove
- *
- * Finds the control instance with the given id, removes it from the
- * card list and releases it.
- *
- * Returns 0 if successful, or a negative error code on failure.
- */
-static int snd_ctl_remove_user_ctl(struct snd_ctl_file * file,
- struct snd_ctl_elem_id *id)
-{
- struct snd_card *card = file->card;
- struct snd_kcontrol *kctl;
- int idx, ret;
-
- down_write(&card->controls_rwsem);
- kctl = snd_ctl_find_id(card, id);
- if (kctl == NULL) {
- ret = -ENOENT;
- goto error;
- }
- if (!(kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_USER)) {
- ret = -EINVAL;
- goto error;
- }
- for (idx = 0; idx < kctl->count; idx++)
- if (kctl->vd[idx].owner != NULL && kctl->vd[idx].owner != file) {
- ret = -EBUSY;
- goto error;
- }
- ret = snd_ctl_remove(card, kctl);
- if (ret < 0)
- goto error;
- card->user_ctl_count--;
-error:
- up_write(&card->controls_rwsem);
- return ret;
-}
-
-/**
- * snd_ctl_activate_id - activate/inactivate the control of the given id
- * @card: the card instance
- * @id: the control id to activate/inactivate
- * @active: non-zero to activate
- *
- * Finds the control instance with the given id, and activate or
- * inactivate the control together with notification, if changed.
- *
- * Returns 0 if unchanged, 1 if changed, or a negative error code on failure.
- */
-int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id,
- int active)
-{
- struct snd_kcontrol *kctl;
- struct snd_kcontrol_volatile *vd;
- unsigned int index_offset;
- int ret;
-
- down_write(&card->controls_rwsem);
- kctl = snd_ctl_find_id(card, id);
- if (kctl == NULL) {
- ret = -ENOENT;
- goto unlock;
- }
- index_offset = snd_ctl_get_ioff(kctl, &kctl->id);
- vd = &kctl->vd[index_offset];
- ret = 0;
- if (active) {
- if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE))
- goto unlock;
- vd->access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- } else {
- if (vd->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE)
- goto unlock;
- vd->access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- }
- ret = 1;
- unlock:
- up_write(&card->controls_rwsem);
- if (ret > 0)
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, id);
- return ret;
-}
-EXPORT_SYMBOL_GPL(snd_ctl_activate_id);
-
-/**
- * snd_ctl_rename_id - replace the id of a control on the card
- * @card: the card instance
- * @src_id: the old id
- * @dst_id: the new id
- *
- * Finds the control with the old id from the card, and replaces the
- * id with the new one.
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id,
- struct snd_ctl_elem_id *dst_id)
-{
- struct snd_kcontrol *kctl;
-
- down_write(&card->controls_rwsem);
- kctl = snd_ctl_find_id(card, src_id);
- if (kctl == NULL) {
- up_write(&card->controls_rwsem);
- return -ENOENT;
- }
- kctl->id = *dst_id;
- kctl->id.numid = card->last_numid + 1;
- card->last_numid += kctl->count;
- up_write(&card->controls_rwsem);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_ctl_rename_id);
-
-/**
- * snd_ctl_find_numid - find the control instance with the given number-id
- * @card: the card instance
- * @numid: the number-id to search
- *
- * Finds the control instance with the given number-id from the card.
- *
- * Returns the pointer of the instance if found, or NULL if not.
- *
- * The caller must down card->controls_rwsem before calling this function
- * (if the race condition can happen).
- */
-struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numid)
-{
- struct snd_kcontrol *kctl;
-
- if (snd_BUG_ON(!card || !numid))
- return NULL;
- list_for_each_entry(kctl, &card->controls, list) {
- if (kctl->id.numid <= numid && kctl->id.numid + kctl->count > numid)
- return kctl;
- }
- return NULL;
-}
-
-EXPORT_SYMBOL(snd_ctl_find_numid);
-
-/**
- * snd_ctl_find_id - find the control instance with the given id
- * @card: the card instance
- * @id: the id to search
- *
- * Finds the control instance with the given id from the card.
- *
- * Returns the pointer of the instance if found, or NULL if not.
- *
- * The caller must down card->controls_rwsem before calling this function
- * (if the race condition can happen).
- */
-struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card,
- struct snd_ctl_elem_id *id)
-{
- struct snd_kcontrol *kctl;
-
- if (snd_BUG_ON(!card || !id))
- return NULL;
- if (id->numid != 0)
- return snd_ctl_find_numid(card, id->numid);
- list_for_each_entry(kctl, &card->controls, list) {
- if (kctl->id.iface != id->iface)
- continue;
- if (kctl->id.device != id->device)
- continue;
- if (kctl->id.subdevice != id->subdevice)
- continue;
- if (strncmp(kctl->id.name, id->name, sizeof(kctl->id.name)))
- continue;
- if (kctl->id.index > id->index)
- continue;
- if (kctl->id.index + kctl->count <= id->index)
- continue;
- return kctl;
- }
- return NULL;
-}
-
-EXPORT_SYMBOL(snd_ctl_find_id);
-
-static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl,
- unsigned int cmd, void __user *arg)
-{
- struct snd_ctl_card_info *info;
-
- info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (! info)
- return -ENOMEM;
- down_read(&snd_ioctl_rwsem);
- info->card = card->number;
- strlcpy(info->id, card->id, sizeof(info->id));
- strlcpy(info->driver, card->driver, sizeof(info->driver));
- strlcpy(info->name, card->shortname, sizeof(info->name));
- strlcpy(info->longname, card->longname, sizeof(info->longname));
- strlcpy(info->mixername, card->mixername, sizeof(info->mixername));
- strlcpy(info->components, card->components, sizeof(info->components));
- up_read(&snd_ioctl_rwsem);
- if (copy_to_user(arg, info, sizeof(struct snd_ctl_card_info))) {
- kfree(info);
- return -EFAULT;
- }
- kfree(info);
- return 0;
-}
-
-static int snd_ctl_elem_list(struct snd_card *card,
- struct snd_ctl_elem_list __user *_list)
-{
- struct list_head *plist;
- struct snd_ctl_elem_list list;
- struct snd_kcontrol *kctl;
- struct snd_ctl_elem_id *dst, *id;
- unsigned int offset, space, jidx;
-
- if (copy_from_user(&list, _list, sizeof(list)))
- return -EFAULT;
- offset = list.offset;
- space = list.space;
- /* try limit maximum space */
- if (space > 16384)
- return -ENOMEM;
- if (space > 0) {
- /* allocate temporary buffer for atomic operation */
- dst = vmalloc(space * sizeof(struct snd_ctl_elem_id));
- if (dst == NULL)
- return -ENOMEM;
- down_read(&card->controls_rwsem);
- list.count = card->controls_count;
- plist = card->controls.next;
- while (plist != &card->controls) {
- if (offset == 0)
- break;
- kctl = snd_kcontrol(plist);
- if (offset < kctl->count)
- break;
- offset -= kctl->count;
- plist = plist->next;
- }
- list.used = 0;
- id = dst;
- while (space > 0 && plist != &card->controls) {
- kctl = snd_kcontrol(plist);
- for (jidx = offset; space > 0 && jidx < kctl->count; jidx++) {
- snd_ctl_build_ioff(id, kctl, jidx);
- id++;
- space--;
- list.used++;
- }
- plist = plist->next;
- offset = 0;
- }
- up_read(&card->controls_rwsem);
- if (list.used > 0 &&
- copy_to_user(list.pids, dst,
- list.used * sizeof(struct snd_ctl_elem_id))) {
- vfree(dst);
- return -EFAULT;
- }
- vfree(dst);
- } else {
- down_read(&card->controls_rwsem);
- list.count = card->controls_count;
- up_read(&card->controls_rwsem);
- }
- if (copy_to_user(_list, &list, sizeof(list)))
- return -EFAULT;
- return 0;
-}
-
-static int snd_ctl_elem_info(struct snd_ctl_file *ctl,
- struct snd_ctl_elem_info *info)
-{
- struct snd_card *card = ctl->card;
- struct snd_kcontrol *kctl;
- struct snd_kcontrol_volatile *vd;
- unsigned int index_offset;
- int result;
-
- down_read(&card->controls_rwsem);
- kctl = snd_ctl_find_id(card, &info->id);
- if (kctl == NULL) {
- up_read(&card->controls_rwsem);
- return -ENOENT;
- }
-#ifdef CONFIG_SND_DEBUG
- info->access = 0;
-#endif
- result = kctl->info(kctl, info);
- if (result >= 0) {
- snd_BUG_ON(info->access);
- index_offset = snd_ctl_get_ioff(kctl, &info->id);
- vd = &kctl->vd[index_offset];
- snd_ctl_build_ioff(&info->id, kctl, index_offset);
- info->access = vd->access;
- if (vd->owner) {
- info->access |= SNDRV_CTL_ELEM_ACCESS_LOCK;
- if (vd->owner == ctl)
- info->access |= SNDRV_CTL_ELEM_ACCESS_OWNER;
- info->owner = pid_vnr(vd->owner->pid);
- } else {
- info->owner = -1;
- }
- }
- up_read(&card->controls_rwsem);
- return result;
-}
-
-static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl,
- struct snd_ctl_elem_info __user *_info)
-{
- struct snd_ctl_elem_info info;
- int result;
-
- if (copy_from_user(&info, _info, sizeof(info)))
- return -EFAULT;
- snd_power_lock(ctl->card);
- result = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0);
- if (result >= 0)
- result = snd_ctl_elem_info(ctl, &info);
- snd_power_unlock(ctl->card);
- if (result >= 0)
- if (copy_to_user(_info, &info, sizeof(info)))
- return -EFAULT;
- return result;
-}
-
-static int snd_ctl_elem_read(struct snd_card *card,
- struct snd_ctl_elem_value *control)
-{
- struct snd_kcontrol *kctl;
- struct snd_kcontrol_volatile *vd;
- unsigned int index_offset;
- int result;
-
- down_read(&card->controls_rwsem);
- kctl = snd_ctl_find_id(card, &control->id);
- if (kctl == NULL) {
- result = -ENOENT;
- } else {
- index_offset = snd_ctl_get_ioff(kctl, &control->id);
- vd = &kctl->vd[index_offset];
- if ((vd->access & SNDRV_CTL_ELEM_ACCESS_READ) &&
- kctl->get != NULL) {
- snd_ctl_build_ioff(&control->id, kctl, index_offset);
- result = kctl->get(kctl, control);
- } else
- result = -EPERM;
- }
- up_read(&card->controls_rwsem);
- return result;
-}
-
-static int snd_ctl_elem_read_user(struct snd_card *card,
- struct snd_ctl_elem_value __user *_control)
-{
- struct snd_ctl_elem_value *control;
- int result;
-
- control = memdup_user(_control, sizeof(*control));
- if (IS_ERR(control))
- return PTR_ERR(control);
-
- snd_power_lock(card);
- result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
- if (result >= 0)
- result = snd_ctl_elem_read(card, control);
- snd_power_unlock(card);
- if (result >= 0)
- if (copy_to_user(_control, control, sizeof(*control)))
- result = -EFAULT;
- kfree(control);
- return result;
-}
-
-static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
- struct snd_ctl_elem_value *control)
-{
- struct snd_kcontrol *kctl;
- struct snd_kcontrol_volatile *vd;
- unsigned int index_offset;
- int result;
-
- down_read(&card->controls_rwsem);
- kctl = snd_ctl_find_id(card, &control->id);
- if (kctl == NULL) {
- result = -ENOENT;
- } else {
- index_offset = snd_ctl_get_ioff(kctl, &control->id);
- vd = &kctl->vd[index_offset];
- if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) ||
- kctl->put == NULL ||
- (file && vd->owner && vd->owner != file)) {
- result = -EPERM;
- } else {
- snd_ctl_build_ioff(&control->id, kctl, index_offset);
- result = kctl->put(kctl, control);
- }
- if (result > 0) {
- up_read(&card->controls_rwsem);
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
- &control->id);
- return 0;
- }
- }
- up_read(&card->controls_rwsem);
- return result;
-}
-
-static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
- struct snd_ctl_elem_value __user *_control)
-{
- struct snd_ctl_elem_value *control;
- struct snd_card *card;
- int result;
-
- control = memdup_user(_control, sizeof(*control));
- if (IS_ERR(control))
- return PTR_ERR(control);
-
- card = file->card;
- snd_power_lock(card);
- result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
- if (result >= 0)
- result = snd_ctl_elem_write(card, file, control);
- snd_power_unlock(card);
- if (result >= 0)
- if (copy_to_user(_control, control, sizeof(*control)))
- result = -EFAULT;
- kfree(control);
- return result;
-}
-
-static int snd_ctl_elem_lock(struct snd_ctl_file *file,
- struct snd_ctl_elem_id __user *_id)
-{
- struct snd_card *card = file->card;
- struct snd_ctl_elem_id id;
- struct snd_kcontrol *kctl;
- struct snd_kcontrol_volatile *vd;
- int result;
-
- if (copy_from_user(&id, _id, sizeof(id)))
- return -EFAULT;
- down_write(&card->controls_rwsem);
- kctl = snd_ctl_find_id(card, &id);
- if (kctl == NULL) {
- result = -ENOENT;
- } else {
- vd = &kctl->vd[snd_ctl_get_ioff(kctl, &id)];
- if (vd->owner != NULL)
- result = -EBUSY;
- else {
- vd->owner = file;
- result = 0;
- }
- }
- up_write(&card->controls_rwsem);
- return result;
-}
-
-static int snd_ctl_elem_unlock(struct snd_ctl_file *file,
- struct snd_ctl_elem_id __user *_id)
-{
- struct snd_card *card = file->card;
- struct snd_ctl_elem_id id;
- struct snd_kcontrol *kctl;
- struct snd_kcontrol_volatile *vd;
- int result;
-
- if (copy_from_user(&id, _id, sizeof(id)))
- return -EFAULT;
- down_write(&card->controls_rwsem);
- kctl = snd_ctl_find_id(card, &id);
- if (kctl == NULL) {
- result = -ENOENT;
- } else {
- vd = &kctl->vd[snd_ctl_get_ioff(kctl, &id)];
- if (vd->owner == NULL)
- result = -EINVAL;
- else if (vd->owner != file)
- result = -EPERM;
- else {
- vd->owner = NULL;
- result = 0;
- }
- }
- up_write(&card->controls_rwsem);
- return result;
-}
-
-struct user_element {
- struct snd_ctl_elem_info info;
- void *elem_data; /* element data */
- unsigned long elem_data_size; /* size of element data in bytes */
- void *tlv_data; /* TLV data */
- unsigned long tlv_data_size; /* TLV data size */
- void *priv_data; /* private data (like strings for enumerated type) */
-};
-
-static int snd_ctl_elem_user_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct user_element *ue = kcontrol->private_data;
-
- *uinfo = ue->info;
- return 0;
-}
-
-static int snd_ctl_elem_user_enum_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct user_element *ue = kcontrol->private_data;
- const char *names;
- unsigned int item;
-
- item = uinfo->value.enumerated.item;
-
- *uinfo = ue->info;
-
- item = min(item, uinfo->value.enumerated.items - 1);
- uinfo->value.enumerated.item = item;
-
- names = ue->priv_data;
- for (; item > 0; --item)
- names += strlen(names) + 1;
- strcpy(uinfo->value.enumerated.name, names);
-
- return 0;
-}
-
-static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct user_element *ue = kcontrol->private_data;
-
- memcpy(&ucontrol->value, ue->elem_data, ue->elem_data_size);
- return 0;
-}
-
-static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int change;
- struct user_element *ue = kcontrol->private_data;
-
- change = memcmp(&ucontrol->value, ue->elem_data, ue->elem_data_size) != 0;
- if (change)
- memcpy(ue->elem_data, &ucontrol->value, ue->elem_data_size);
- return change;
-}
-
-static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol,
- int op_flag,
- unsigned int size,
- unsigned int __user *tlv)
-{
- struct user_element *ue = kcontrol->private_data;
- int change = 0;
- void *new_data;
-
- if (op_flag > 0) {
- if (size > 1024 * 128) /* sane value */
- return -EINVAL;
-
- new_data = memdup_user(tlv, size);
- if (IS_ERR(new_data))
- return PTR_ERR(new_data);
- change = ue->tlv_data_size != size;
- if (!change)
- change = memcmp(ue->tlv_data, new_data, size);
- kfree(ue->tlv_data);
- ue->tlv_data = new_data;
- ue->tlv_data_size = size;
- } else {
- if (! ue->tlv_data_size || ! ue->tlv_data)
- return -ENXIO;
- if (size < ue->tlv_data_size)
- return -ENOSPC;
- if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size))
- return -EFAULT;
- }
- return change;
-}
-
-static int snd_ctl_elem_init_enum_names(struct user_element *ue)
-{
- char *names, *p;
- size_t buf_len, name_len;
- unsigned int i;
- const uintptr_t user_ptrval = ue->info.value.enumerated.names_ptr;
-
- if (ue->info.value.enumerated.names_length > 64 * 1024)
- return -EINVAL;
-
- names = memdup_user((const void __user *)user_ptrval,
- ue->info.value.enumerated.names_length);
- if (IS_ERR(names))
- return PTR_ERR(names);
-
- /* check that there are enough valid names */
- buf_len = ue->info.value.enumerated.names_length;
- p = names;
- for (i = 0; i < ue->info.value.enumerated.items; ++i) {
- name_len = strnlen(p, buf_len);
- if (name_len == 0 || name_len >= 64 || name_len == buf_len) {
- kfree(names);
- return -EINVAL;
- }
- p += name_len + 1;
- buf_len -= name_len + 1;
- }
-
- ue->priv_data = names;
- ue->info.value.enumerated.names_ptr = 0;
-
- return 0;
-}
-
-static void snd_ctl_elem_user_free(struct snd_kcontrol *kcontrol)
-{
- struct user_element *ue = kcontrol->private_data;
-
- kfree(ue->tlv_data);
- kfree(ue->priv_data);
- kfree(ue);
-}
-
-static int snd_ctl_elem_add(struct snd_ctl_file *file,
- struct snd_ctl_elem_info *info, int replace)
-{
- struct snd_card *card = file->card;
- struct snd_kcontrol kctl, *_kctl;
- unsigned int access;
- long private_size;
- struct user_element *ue;
- int idx, err;
-
- if (!replace && card->user_ctl_count >= MAX_USER_CONTROLS)
- return -ENOMEM;
- if (info->count < 1)
- return -EINVAL;
- access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
- (info->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
- SNDRV_CTL_ELEM_ACCESS_INACTIVE|
- SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE));
- info->id.numid = 0;
- memset(&kctl, 0, sizeof(kctl));
- down_write(&card->controls_rwsem);
- _kctl = snd_ctl_find_id(card, &info->id);
- err = 0;
- if (_kctl) {
- if (replace)
- err = snd_ctl_remove(card, _kctl);
- else
- err = -EBUSY;
- } else {
- if (replace)
- err = -ENOENT;
- }
- up_write(&card->controls_rwsem);
- if (err < 0)
- return err;
- memcpy(&kctl.id, &info->id, sizeof(info->id));
- kctl.count = info->owner ? info->owner : 1;
- access |= SNDRV_CTL_ELEM_ACCESS_USER;
- if (info->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED)
- kctl.info = snd_ctl_elem_user_enum_info;
- else
- kctl.info = snd_ctl_elem_user_info;
- if (access & SNDRV_CTL_ELEM_ACCESS_READ)
- kctl.get = snd_ctl_elem_user_get;
- if (access & SNDRV_CTL_ELEM_ACCESS_WRITE)
- kctl.put = snd_ctl_elem_user_put;
- if (access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) {
- kctl.tlv.c = snd_ctl_elem_user_tlv;
- access |= SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
- }
- switch (info->type) {
- case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
- case SNDRV_CTL_ELEM_TYPE_INTEGER:
- private_size = sizeof(long);
- if (info->count > 128)
- return -EINVAL;
- break;
- case SNDRV_CTL_ELEM_TYPE_INTEGER64:
- private_size = sizeof(long long);
- if (info->count > 64)
- return -EINVAL;
- break;
- case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
- private_size = sizeof(unsigned int);
- if (info->count > 128 || info->value.enumerated.items == 0)
- return -EINVAL;
- break;
- case SNDRV_CTL_ELEM_TYPE_BYTES:
- private_size = sizeof(unsigned char);
- if (info->count > 512)
- return -EINVAL;
- break;
- case SNDRV_CTL_ELEM_TYPE_IEC958:
- private_size = sizeof(struct snd_aes_iec958);
- if (info->count != 1)
- return -EINVAL;
- break;
- default:
- return -EINVAL;
- }
- private_size *= info->count;
- ue = kzalloc(sizeof(struct user_element) + private_size, GFP_KERNEL);
- if (ue == NULL)
- return -ENOMEM;
- ue->info = *info;
- ue->info.access = 0;
- ue->elem_data = (char *)ue + sizeof(*ue);
- ue->elem_data_size = private_size;
- if (ue->info.type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) {
- err = snd_ctl_elem_init_enum_names(ue);
- if (err < 0) {
- kfree(ue);
- return err;
- }
- }
- kctl.private_free = snd_ctl_elem_user_free;
- _kctl = snd_ctl_new(&kctl, access);
- if (_kctl == NULL) {
- kfree(ue->priv_data);
- kfree(ue);
- return -ENOMEM;
- }
- _kctl->private_data = ue;
- for (idx = 0; idx < _kctl->count; idx++)
- _kctl->vd[idx].owner = file;
- err = snd_ctl_add(card, _kctl);
- if (err < 0)
- return err;
-
- down_write(&card->controls_rwsem);
- card->user_ctl_count++;
- up_write(&card->controls_rwsem);
-
- return 0;
-}
-
-static int snd_ctl_elem_add_user(struct snd_ctl_file *file,
- struct snd_ctl_elem_info __user *_info, int replace)
-{
- struct snd_ctl_elem_info info;
- if (copy_from_user(&info, _info, sizeof(info)))
- return -EFAULT;
- return snd_ctl_elem_add(file, &info, replace);
-}
-
-static int snd_ctl_elem_remove(struct snd_ctl_file *file,
- struct snd_ctl_elem_id __user *_id)
-{
- struct snd_ctl_elem_id id;
-
- if (copy_from_user(&id, _id, sizeof(id)))
- return -EFAULT;
- return snd_ctl_remove_user_ctl(file, &id);
-}
-
-static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr)
-{
- int subscribe;
- if (get_user(subscribe, ptr))
- return -EFAULT;
- if (subscribe < 0) {
- subscribe = file->subscribed;
- if (put_user(subscribe, ptr))
- return -EFAULT;
- return 0;
- }
- if (subscribe) {
- file->subscribed = 1;
- return 0;
- } else if (file->subscribed) {
- snd_ctl_empty_read_queue(file);
- file->subscribed = 0;
- }
- return 0;
-}
-
-static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
- struct snd_ctl_tlv __user *_tlv,
- int op_flag)
-{
- struct snd_card *card = file->card;
- struct snd_ctl_tlv tlv;
- struct snd_kcontrol *kctl;
- struct snd_kcontrol_volatile *vd;
- unsigned int len;
- int err = 0;
-
- if (copy_from_user(&tlv, _tlv, sizeof(tlv)))
- return -EFAULT;
- if (tlv.length < sizeof(unsigned int) * 2)
- return -EINVAL;
- down_read(&card->controls_rwsem);
- kctl = snd_ctl_find_numid(card, tlv.numid);
- if (kctl == NULL) {
- err = -ENOENT;
- goto __kctl_end;
- }
- if (kctl->tlv.p == NULL) {
- err = -ENXIO;
- goto __kctl_end;
- }
- vd = &kctl->vd[tlv.numid - kctl->id.numid];
- if ((op_flag == 0 && (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) == 0) ||
- (op_flag > 0 && (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) == 0) ||
- (op_flag < 0 && (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND) == 0)) {
- err = -ENXIO;
- goto __kctl_end;
- }
- if (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
- if (vd->owner != NULL && vd->owner != file) {
- err = -EPERM;
- goto __kctl_end;
- }
- err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv);
- if (err > 0) {
- up_read(&card->controls_rwsem);
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id);
- return 0;
- }
- } else {
- if (op_flag) {
- err = -ENXIO;
- goto __kctl_end;
- }
- len = kctl->tlv.p[1] + 2 * sizeof(unsigned int);
- if (tlv.length < len) {
- err = -ENOMEM;
- goto __kctl_end;
- }
- if (copy_to_user(_tlv->tlv, kctl->tlv.p, len))
- err = -EFAULT;
- }
- __kctl_end:
- up_read(&card->controls_rwsem);
- return err;
-}
-
-static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct snd_ctl_file *ctl;
- struct snd_card *card;
- struct snd_kctl_ioctl *p;
- void __user *argp = (void __user *)arg;
- int __user *ip = argp;
- int err;
-
- ctl = file->private_data;
- card = ctl->card;
- if (snd_BUG_ON(!card))
- return -ENXIO;
- switch (cmd) {
- case SNDRV_CTL_IOCTL_PVERSION:
- return put_user(SNDRV_CTL_VERSION, ip) ? -EFAULT : 0;
- case SNDRV_CTL_IOCTL_CARD_INFO:
- return snd_ctl_card_info(card, ctl, cmd, argp);
- case SNDRV_CTL_IOCTL_ELEM_LIST:
- return snd_ctl_elem_list(card, argp);
- case SNDRV_CTL_IOCTL_ELEM_INFO:
- return snd_ctl_elem_info_user(ctl, argp);
- case SNDRV_CTL_IOCTL_ELEM_READ:
- return snd_ctl_elem_read_user(card, argp);
- case SNDRV_CTL_IOCTL_ELEM_WRITE:
- return snd_ctl_elem_write_user(ctl, argp);
- case SNDRV_CTL_IOCTL_ELEM_LOCK:
- return snd_ctl_elem_lock(ctl, argp);
- case SNDRV_CTL_IOCTL_ELEM_UNLOCK:
- return snd_ctl_elem_unlock(ctl, argp);
- case SNDRV_CTL_IOCTL_ELEM_ADD:
- return snd_ctl_elem_add_user(ctl, argp, 0);
- case SNDRV_CTL_IOCTL_ELEM_REPLACE:
- return snd_ctl_elem_add_user(ctl, argp, 1);
- case SNDRV_CTL_IOCTL_ELEM_REMOVE:
- return snd_ctl_elem_remove(ctl, argp);
- case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
- return snd_ctl_subscribe_events(ctl, ip);
- case SNDRV_CTL_IOCTL_TLV_READ:
- return snd_ctl_tlv_ioctl(ctl, argp, 0);
- case SNDRV_CTL_IOCTL_TLV_WRITE:
- return snd_ctl_tlv_ioctl(ctl, argp, 1);
- case SNDRV_CTL_IOCTL_TLV_COMMAND:
- return snd_ctl_tlv_ioctl(ctl, argp, -1);
- case SNDRV_CTL_IOCTL_POWER:
- return -ENOPROTOOPT;
- case SNDRV_CTL_IOCTL_POWER_STATE:
-#ifdef CONFIG_PM
- return put_user(card->power_state, ip) ? -EFAULT : 0;
-#else
- return put_user(SNDRV_CTL_POWER_D0, ip) ? -EFAULT : 0;
-#endif
- }
- down_read(&snd_ioctl_rwsem);
- list_for_each_entry(p, &snd_control_ioctls, list) {
- err = p->fioctl(card, ctl, cmd, arg);
- if (err != -ENOIOCTLCMD) {
- up_read(&snd_ioctl_rwsem);
- return err;
- }
- }
- up_read(&snd_ioctl_rwsem);
- snd_printdd("unknown ioctl = 0x%x\n", cmd);
- return -ENOTTY;
-}
-
-static ssize_t snd_ctl_read(struct file *file, char __user *buffer,
- size_t count, loff_t * offset)
-{
- struct snd_ctl_file *ctl;
- int err = 0;
- ssize_t result = 0;
-
- ctl = file->private_data;
- if (snd_BUG_ON(!ctl || !ctl->card))
- return -ENXIO;
- if (!ctl->subscribed)
- return -EBADFD;
- if (count < sizeof(struct snd_ctl_event))
- return -EINVAL;
- spin_lock_irq(&ctl->read_lock);
- while (count >= sizeof(struct snd_ctl_event)) {
- struct snd_ctl_event ev;
- struct snd_kctl_event *kev;
- while (list_empty(&ctl->events)) {
- wait_queue_t wait;
- if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) {
- err = -EAGAIN;
- goto __end_lock;
- }
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&ctl->change_sleep, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
- spin_unlock_irq(&ctl->read_lock);
- schedule();
- remove_wait_queue(&ctl->change_sleep, &wait);
- if (ctl->card->shutdown)
- return -ENODEV;
- if (signal_pending(current))
- return -ERESTARTSYS;
- spin_lock_irq(&ctl->read_lock);
- }
- kev = snd_kctl_event(ctl->events.next);
- ev.type = SNDRV_CTL_EVENT_ELEM;
- ev.data.elem.mask = kev->mask;
- ev.data.elem.id = kev->id;
- list_del(&kev->list);
- spin_unlock_irq(&ctl->read_lock);
- kfree(kev);
- if (copy_to_user(buffer, &ev, sizeof(struct snd_ctl_event))) {
- err = -EFAULT;
- goto __end;
- }
- spin_lock_irq(&ctl->read_lock);
- buffer += sizeof(struct snd_ctl_event);
- count -= sizeof(struct snd_ctl_event);
- result += sizeof(struct snd_ctl_event);
- }
- __end_lock:
- spin_unlock_irq(&ctl->read_lock);
- __end:
- return result > 0 ? result : err;
-}
-
-static unsigned int snd_ctl_poll(struct file *file, poll_table * wait)
-{
- unsigned int mask;
- struct snd_ctl_file *ctl;
-
- ctl = file->private_data;
- if (!ctl->subscribed)
- return 0;
- poll_wait(file, &ctl->change_sleep, wait);
-
- mask = 0;
- if (!list_empty(&ctl->events))
- mask |= POLLIN | POLLRDNORM;
-
- return mask;
-}
-
-/*
- * register the device-specific control-ioctls.
- * called from each device manager like pcm.c, hwdep.c, etc.
- */
-static int _snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn, struct list_head *lists)
-{
- struct snd_kctl_ioctl *pn;
-
- pn = kzalloc(sizeof(struct snd_kctl_ioctl), GFP_KERNEL);
- if (pn == NULL)
- return -ENOMEM;
- pn->fioctl = fcn;
- down_write(&snd_ioctl_rwsem);
- list_add_tail(&pn->list, lists);
- up_write(&snd_ioctl_rwsem);
- return 0;
-}
-
-int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn)
-{
- return _snd_ctl_register_ioctl(fcn, &snd_control_ioctls);
-}
-
-EXPORT_SYMBOL(snd_ctl_register_ioctl);
-
-#ifdef CONFIG_COMPAT
-int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn)
-{
- return _snd_ctl_register_ioctl(fcn, &snd_control_compat_ioctls);
-}
-
-EXPORT_SYMBOL(snd_ctl_register_ioctl_compat);
-#endif
-
-/*
- * de-register the device-specific control-ioctls.
- */
-static int _snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn,
- struct list_head *lists)
-{
- struct snd_kctl_ioctl *p;
-
- if (snd_BUG_ON(!fcn))
- return -EINVAL;
- down_write(&snd_ioctl_rwsem);
- list_for_each_entry(p, lists, list) {
- if (p->fioctl == fcn) {
- list_del(&p->list);
- up_write(&snd_ioctl_rwsem);
- kfree(p);
- return 0;
- }
- }
- up_write(&snd_ioctl_rwsem);
- snd_BUG();
- return -EINVAL;
-}
-
-int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn)
-{
- return _snd_ctl_unregister_ioctl(fcn, &snd_control_ioctls);
-}
-
-EXPORT_SYMBOL(snd_ctl_unregister_ioctl);
-
-#ifdef CONFIG_COMPAT
-int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn)
-{
- return _snd_ctl_unregister_ioctl(fcn, &snd_control_compat_ioctls);
-}
-
-EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat);
-#endif
-
-static int snd_ctl_fasync(int fd, struct file * file, int on)
-{
- struct snd_ctl_file *ctl;
-
- ctl = file->private_data;
- return fasync_helper(fd, file, on, &ctl->fasync);
-}
-
-/*
- * ioctl32 compat
- */
-#ifdef CONFIG_COMPAT
-#include "control_compat.c"
-#else
-#define snd_ctl_ioctl_compat NULL
-#endif
-
-/*
- * INIT PART
- */
-
-static const struct file_operations snd_ctl_f_ops =
-{
- .owner = THIS_MODULE,
- .read = snd_ctl_read,
- .open = snd_ctl_open,
- .release = snd_ctl_release,
- .llseek = no_llseek,
- .poll = snd_ctl_poll,
- .unlocked_ioctl = snd_ctl_ioctl,
- .compat_ioctl = snd_ctl_ioctl_compat,
- .fasync = snd_ctl_fasync,
-};
-
-/*
- * registration of the control device
- */
-static int snd_ctl_dev_register(struct snd_device *device)
-{
- struct snd_card *card = device->device_data;
- int err, cardnum;
- char name[16];
-
- if (snd_BUG_ON(!card))
- return -ENXIO;
- cardnum = card->number;
- if (snd_BUG_ON(cardnum < 0 || cardnum >= SNDRV_CARDS))
- return -ENXIO;
- sprintf(name, "controlC%i", cardnum);
- if ((err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL, card, -1,
- &snd_ctl_f_ops, card, name)) < 0)
- return err;
- return 0;
-}
-
-/*
- * disconnection of the control device
- */
-static int snd_ctl_dev_disconnect(struct snd_device *device)
-{
- struct snd_card *card = device->device_data;
- struct snd_ctl_file *ctl;
- int err, cardnum;
-
- if (snd_BUG_ON(!card))
- return -ENXIO;
- cardnum = card->number;
- if (snd_BUG_ON(cardnum < 0 || cardnum >= SNDRV_CARDS))
- return -ENXIO;
-
- read_lock(&card->ctl_files_rwlock);
- list_for_each_entry(ctl, &card->ctl_files, list) {
- wake_up(&ctl->change_sleep);
- kill_fasync(&ctl->fasync, SIGIO, POLL_ERR);
- }
- read_unlock(&card->ctl_files_rwlock);
-
- if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL,
- card, -1)) < 0)
- return err;
- return 0;
-}
-
-/*
- * free all controls
- */
-static int snd_ctl_dev_free(struct snd_device *device)
-{
- struct snd_card *card = device->device_data;
- struct snd_kcontrol *control;
-
- down_write(&card->controls_rwsem);
- while (!list_empty(&card->controls)) {
- control = snd_kcontrol(card->controls.next);
- snd_ctl_remove(card, control);
- }
- up_write(&card->controls_rwsem);
- return 0;
-}
-
-/*
- * create control core:
- * called from init.c
- */
-int snd_ctl_create(struct snd_card *card)
-{
- static struct snd_device_ops ops = {
- .dev_free = snd_ctl_dev_free,
- .dev_register = snd_ctl_dev_register,
- .dev_disconnect = snd_ctl_dev_disconnect,
- };
-
- if (snd_BUG_ON(!card))
- return -ENXIO;
- return snd_device_new(card, SNDRV_DEV_CONTROL, card, &ops);
-}
-
-/*
- * Frequently used control callbacks/helpers
- */
-int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_ctl_boolean_mono_info);
-
-int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_ctl_boolean_stereo_info);
-
-/**
- * snd_ctl_enum_info - fills the info structure for an enumerated control
- * @info: the structure to be filled
- * @channels: the number of the control's channels; often one
- * @items: the number of control values; also the size of @names
- * @names: an array containing the names of all control values
- *
- * Sets all required fields in @info to their appropriate values.
- * If the control's accessibility is not the default (readable and writable),
- * the caller has to fill @info->access.
- */
-int snd_ctl_enum_info(struct snd_ctl_elem_info *info, unsigned int channels,
- unsigned int items, const char *const names[])
-{
- info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- info->count = channels;
- info->value.enumerated.items = items;
- if (info->value.enumerated.item >= items)
- info->value.enumerated.item = items - 1;
- strlcpy(info->value.enumerated.name,
- names[info->value.enumerated.item],
- sizeof(info->value.enumerated.name));
- return 0;
-}
-EXPORT_SYMBOL(snd_ctl_enum_info);
diff --git a/ANDROID_3.4.5/sound/core/control_compat.c b/ANDROID_3.4.5/sound/core/control_compat.c
deleted file mode 100644
index 2bb95a7a..00000000
--- a/ANDROID_3.4.5/sound/core/control_compat.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * compat ioctls for control API
- *
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* this file included from control.c */
-
-#include <linux/compat.h>
-#include <linux/slab.h>
-
-struct snd_ctl_elem_list32 {
- u32 offset;
- u32 space;
- u32 used;
- u32 count;
- u32 pids;
- unsigned char reserved[50];
-} /* don't set packed attribute here */;
-
-static int snd_ctl_elem_list_compat(struct snd_card *card,
- struct snd_ctl_elem_list32 __user *data32)
-{
- struct snd_ctl_elem_list __user *data;
- compat_caddr_t ptr;
- int err;
-
- data = compat_alloc_user_space(sizeof(*data));
-
- /* offset, space, used, count */
- if (copy_in_user(data, data32, 4 * sizeof(u32)))
- return -EFAULT;
- /* pids */
- if (get_user(ptr, &data32->pids) ||
- put_user(compat_ptr(ptr), &data->pids))
- return -EFAULT;
- err = snd_ctl_elem_list(card, data);
- if (err < 0)
- return err;
- /* copy the result */
- if (copy_in_user(data32, data, 4 * sizeof(u32)))
- return -EFAULT;
- return 0;
-}
-
-/*
- * control element info
- * it uses union, so the things are not easy..
- */
-
-struct snd_ctl_elem_info32 {
- struct snd_ctl_elem_id id; // the size of struct is same
- s32 type;
- u32 access;
- u32 count;
- s32 owner;
- union {
- struct {
- s32 min;
- s32 max;
- s32 step;
- } integer;
- struct {
- u64 min;
- u64 max;
- u64 step;
- } integer64;
- struct {
- u32 items;
- u32 item;
- char name[64];
- u64 names_ptr;
- u32 names_length;
- } enumerated;
- unsigned char reserved[128];
- } value;
- unsigned char reserved[64];
-} __attribute__((packed));
-
-static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl,
- struct snd_ctl_elem_info32 __user *data32)
-{
- struct snd_ctl_elem_info *data;
- int err;
-
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (! data)
- return -ENOMEM;
-
- err = -EFAULT;
- /* copy id */
- if (copy_from_user(&data->id, &data32->id, sizeof(data->id)))
- goto error;
- /* we need to copy the item index.
- * hope this doesn't break anything..
- */
- if (get_user(data->value.enumerated.item, &data32->value.enumerated.item))
- goto error;
-
- snd_power_lock(ctl->card);
- err = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0);
- if (err >= 0)
- err = snd_ctl_elem_info(ctl, data);
- snd_power_unlock(ctl->card);
-
- if (err < 0)
- goto error;
- /* restore info to 32bit */
- err = -EFAULT;
- /* id, type, access, count */
- if (copy_to_user(&data32->id, &data->id, sizeof(data->id)) ||
- copy_to_user(&data32->type, &data->type, 3 * sizeof(u32)))
- goto error;
- if (put_user(data->owner, &data32->owner))
- goto error;
- switch (data->type) {
- case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
- case SNDRV_CTL_ELEM_TYPE_INTEGER:
- if (put_user(data->value.integer.min, &data32->value.integer.min) ||
- put_user(data->value.integer.max, &data32->value.integer.max) ||
- put_user(data->value.integer.step, &data32->value.integer.step))
- goto error;
- break;
- case SNDRV_CTL_ELEM_TYPE_INTEGER64:
- if (copy_to_user(&data32->value.integer64,
- &data->value.integer64,
- sizeof(data->value.integer64)))
- goto error;
- break;
- case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
- if (copy_to_user(&data32->value.enumerated,
- &data->value.enumerated,
- sizeof(data->value.enumerated)))
- goto error;
- break;
- default:
- break;
- }
- err = 0;
- error:
- kfree(data);
- return err;
-}
-
-/* read / write */
-struct snd_ctl_elem_value32 {
- struct snd_ctl_elem_id id;
- unsigned int indirect; /* bit-field causes misalignment */
- union {
- s32 integer[128];
- unsigned char data[512];
-#ifndef CONFIG_X86_64
- s64 integer64[64];
-#endif
- } value;
- unsigned char reserved[128];
-};
-
-
-/* get the value type and count of the control */
-static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id,
- int *countp)
-{
- struct snd_kcontrol *kctl;
- struct snd_ctl_elem_info *info;
- int err;
-
- down_read(&card->controls_rwsem);
- kctl = snd_ctl_find_id(card, id);
- if (! kctl) {
- up_read(&card->controls_rwsem);
- return -ENXIO;
- }
- info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (info == NULL) {
- up_read(&card->controls_rwsem);
- return -ENOMEM;
- }
- info->id = *id;
- err = kctl->info(kctl, info);
- up_read(&card->controls_rwsem);
- if (err >= 0) {
- err = info->type;
- *countp = info->count;
- }
- kfree(info);
- return err;
-}
-
-static int get_elem_size(int type, int count)
-{
- switch (type) {
- case SNDRV_CTL_ELEM_TYPE_INTEGER64:
- return sizeof(s64) * count;
- case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
- return sizeof(int) * count;
- case SNDRV_CTL_ELEM_TYPE_BYTES:
- return 512;
- case SNDRV_CTL_ELEM_TYPE_IEC958:
- return sizeof(struct snd_aes_iec958);
- default:
- return -1;
- }
-}
-
-static int copy_ctl_value_from_user(struct snd_card *card,
- struct snd_ctl_elem_value *data,
- struct snd_ctl_elem_value32 __user *data32,
- int *typep, int *countp)
-{
- int i, type, size;
- int uninitialized_var(count);
- unsigned int indirect;
-
- if (copy_from_user(&data->id, &data32->id, sizeof(data->id)))
- return -EFAULT;
- if (get_user(indirect, &data32->indirect))
- return -EFAULT;
- if (indirect)
- return -EINVAL;
- type = get_ctl_type(card, &data->id, &count);
- if (type < 0)
- return type;
-
- if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
- type == SNDRV_CTL_ELEM_TYPE_INTEGER) {
- for (i = 0; i < count; i++) {
- int val;
- if (get_user(val, &data32->value.integer[i]))
- return -EFAULT;
- data->value.integer.value[i] = val;
- }
- } else {
- size = get_elem_size(type, count);
- if (size < 0) {
- printk(KERN_ERR "snd_ioctl32_ctl_elem_value: unknown type %d\n", type);
- return -EINVAL;
- }
- if (copy_from_user(data->value.bytes.data,
- data32->value.data, size))
- return -EFAULT;
- }
-
- *typep = type;
- *countp = count;
- return 0;
-}
-
-/* restore the value to 32bit */
-static int copy_ctl_value_to_user(struct snd_ctl_elem_value32 __user *data32,
- struct snd_ctl_elem_value *data,
- int type, int count)
-{
- int i, size;
-
- if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
- type == SNDRV_CTL_ELEM_TYPE_INTEGER) {
- for (i = 0; i < count; i++) {
- int val;
- val = data->value.integer.value[i];
- if (put_user(val, &data32->value.integer[i]))
- return -EFAULT;
- }
- } else {
- size = get_elem_size(type, count);
- if (copy_to_user(data32->value.data,
- data->value.bytes.data, size))
- return -EFAULT;
- }
- return 0;
-}
-
-static int snd_ctl_elem_read_user_compat(struct snd_card *card,
- struct snd_ctl_elem_value32 __user *data32)
-{
- struct snd_ctl_elem_value *data;
- int err, type, count;
-
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
-
- if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0)
- goto error;
-
- snd_power_lock(card);
- err = snd_power_wait(card, SNDRV_CTL_POWER_D0);
- if (err >= 0)
- err = snd_ctl_elem_read(card, data);
- snd_power_unlock(card);
- if (err >= 0)
- err = copy_ctl_value_to_user(data32, data, type, count);
- error:
- kfree(data);
- return err;
-}
-
-static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
- struct snd_ctl_elem_value32 __user *data32)
-{
- struct snd_ctl_elem_value *data;
- struct snd_card *card = file->card;
- int err, type, count;
-
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
-
- if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0)
- goto error;
-
- snd_power_lock(card);
- err = snd_power_wait(card, SNDRV_CTL_POWER_D0);
- if (err >= 0)
- err = snd_ctl_elem_write(card, file, data);
- snd_power_unlock(card);
- if (err >= 0)
- err = copy_ctl_value_to_user(data32, data, type, count);
- error:
- kfree(data);
- return err;
-}
-
-/* add or replace a user control */
-static int snd_ctl_elem_add_compat(struct snd_ctl_file *file,
- struct snd_ctl_elem_info32 __user *data32,
- int replace)
-{
- struct snd_ctl_elem_info *data;
- int err;
-
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (! data)
- return -ENOMEM;
-
- err = -EFAULT;
- /* id, type, access, count */ \
- if (copy_from_user(&data->id, &data32->id, sizeof(data->id)) ||
- copy_from_user(&data->type, &data32->type, 3 * sizeof(u32)))
- goto error;
- if (get_user(data->owner, &data32->owner) ||
- get_user(data->type, &data32->type))
- goto error;
- switch (data->type) {
- case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
- case SNDRV_CTL_ELEM_TYPE_INTEGER:
- if (get_user(data->value.integer.min, &data32->value.integer.min) ||
- get_user(data->value.integer.max, &data32->value.integer.max) ||
- get_user(data->value.integer.step, &data32->value.integer.step))
- goto error;
- break;
- case SNDRV_CTL_ELEM_TYPE_INTEGER64:
- if (copy_from_user(&data->value.integer64,
- &data32->value.integer64,
- sizeof(data->value.integer64)))
- goto error;
- break;
- case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
- if (copy_from_user(&data->value.enumerated,
- &data32->value.enumerated,
- sizeof(data->value.enumerated)))
- goto error;
- data->value.enumerated.names_ptr =
- (uintptr_t)compat_ptr(data->value.enumerated.names_ptr);
- break;
- default:
- break;
- }
- err = snd_ctl_elem_add(file, data, replace);
- error:
- kfree(data);
- return err;
-}
-
-enum {
- SNDRV_CTL_IOCTL_ELEM_LIST32 = _IOWR('U', 0x10, struct snd_ctl_elem_list32),
- SNDRV_CTL_IOCTL_ELEM_INFO32 = _IOWR('U', 0x11, struct snd_ctl_elem_info32),
- SNDRV_CTL_IOCTL_ELEM_READ32 = _IOWR('U', 0x12, struct snd_ctl_elem_value32),
- SNDRV_CTL_IOCTL_ELEM_WRITE32 = _IOWR('U', 0x13, struct snd_ctl_elem_value32),
- SNDRV_CTL_IOCTL_ELEM_ADD32 = _IOWR('U', 0x17, struct snd_ctl_elem_info32),
- SNDRV_CTL_IOCTL_ELEM_REPLACE32 = _IOWR('U', 0x18, struct snd_ctl_elem_info32),
-};
-
-static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct snd_ctl_file *ctl;
- struct snd_kctl_ioctl *p;
- void __user *argp = compat_ptr(arg);
- int err;
-
- ctl = file->private_data;
- if (snd_BUG_ON(!ctl || !ctl->card))
- return -ENXIO;
-
- switch (cmd) {
- case SNDRV_CTL_IOCTL_PVERSION:
- case SNDRV_CTL_IOCTL_CARD_INFO:
- case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
- case SNDRV_CTL_IOCTL_POWER:
- case SNDRV_CTL_IOCTL_POWER_STATE:
- case SNDRV_CTL_IOCTL_ELEM_LOCK:
- case SNDRV_CTL_IOCTL_ELEM_UNLOCK:
- case SNDRV_CTL_IOCTL_ELEM_REMOVE:
- case SNDRV_CTL_IOCTL_TLV_READ:
- case SNDRV_CTL_IOCTL_TLV_WRITE:
- case SNDRV_CTL_IOCTL_TLV_COMMAND:
- return snd_ctl_ioctl(file, cmd, (unsigned long)argp);
- case SNDRV_CTL_IOCTL_ELEM_LIST32:
- return snd_ctl_elem_list_compat(ctl->card, argp);
- case SNDRV_CTL_IOCTL_ELEM_INFO32:
- return snd_ctl_elem_info_compat(ctl, argp);
- case SNDRV_CTL_IOCTL_ELEM_READ32:
- return snd_ctl_elem_read_user_compat(ctl->card, argp);
- case SNDRV_CTL_IOCTL_ELEM_WRITE32:
- return snd_ctl_elem_write_user_compat(ctl, argp);
- case SNDRV_CTL_IOCTL_ELEM_ADD32:
- return snd_ctl_elem_add_compat(ctl, argp, 0);
- case SNDRV_CTL_IOCTL_ELEM_REPLACE32:
- return snd_ctl_elem_add_compat(ctl, argp, 1);
- }
-
- down_read(&snd_ioctl_rwsem);
- list_for_each_entry(p, &snd_control_compat_ioctls, list) {
- if (p->fioctl) {
- err = p->fioctl(ctl->card, ctl, cmd, arg);
- if (err != -ENOIOCTLCMD) {
- up_read(&snd_ioctl_rwsem);
- return err;
- }
- }
- }
- up_read(&snd_ioctl_rwsem);
- return -ENOIOCTLCMD;
-}
diff --git a/ANDROID_3.4.5/sound/core/ctljack.c b/ANDROID_3.4.5/sound/core/ctljack.c
deleted file mode 100644
index e4b38fbe..00000000
--- a/ANDROID_3.4.5/sound/core/ctljack.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Helper functions for jack-detection kcontrols
- *
- * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/export.h>
-#include <sound/core.h>
-#include <sound/control.h>
-
-#define jack_detect_kctl_info snd_ctl_boolean_mono_info
-
-static int jack_detect_kctl_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = kcontrol->private_value;
- return 0;
-}
-
-static struct snd_kcontrol_new jack_detect_kctl = {
- /* name is filled later */
- .iface = SNDRV_CTL_ELEM_IFACE_CARD,
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .info = jack_detect_kctl_info,
- .get = jack_detect_kctl_get,
-};
-
-struct snd_kcontrol *
-snd_kctl_jack_new(const char *name, int idx, void *private_data)
-{
- struct snd_kcontrol *kctl;
- kctl = snd_ctl_new1(&jack_detect_kctl, private_data);
- if (!kctl)
- return NULL;
- snprintf(kctl->id.name, sizeof(kctl->id.name), "%s Jack", name);
- kctl->id.index = idx;
- kctl->private_value = 0;
- return kctl;
-}
-EXPORT_SYMBOL_GPL(snd_kctl_jack_new);
-
-void snd_kctl_jack_report(struct snd_card *card,
- struct snd_kcontrol *kctl, bool status)
-{
- if (kctl->private_value == status)
- return;
- kctl->private_value = status;
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
-}
-EXPORT_SYMBOL_GPL(snd_kctl_jack_report);
diff --git a/ANDROID_3.4.5/sound/core/device.c b/ANDROID_3.4.5/sound/core/device.c
deleted file mode 100644
index f03cb544..00000000
--- a/ANDROID_3.4.5/sound/core/device.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Device management routines
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/export.h>
-#include <linux/errno.h>
-#include <sound/core.h>
-
-/**
- * snd_device_new - create an ALSA device component
- * @card: the card instance
- * @type: the device type, SNDRV_DEV_XXX
- * @device_data: the data pointer of this device
- * @ops: the operator table
- *
- * Creates a new device component for the given data pointer.
- * The device will be assigned to the card and managed together
- * by the card.
- *
- * The data pointer plays a role as the identifier, too, so the
- * pointer address must be unique and unchanged.
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_device_new(struct snd_card *card, snd_device_type_t type,
- void *device_data, struct snd_device_ops *ops)
-{
- struct snd_device *dev;
-
- if (snd_BUG_ON(!card || !device_data || !ops))
- return -ENXIO;
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (dev == NULL) {
- snd_printk(KERN_ERR "Cannot allocate device\n");
- return -ENOMEM;
- }
- dev->card = card;
- dev->type = type;
- dev->state = SNDRV_DEV_BUILD;
- dev->device_data = device_data;
- dev->ops = ops;
- list_add(&dev->list, &card->devices); /* add to the head of list */
- return 0;
-}
-
-EXPORT_SYMBOL(snd_device_new);
-
-/**
- * snd_device_free - release the device from the card
- * @card: the card instance
- * @device_data: the data pointer to release
- *
- * Removes the device from the list on the card and invokes the
- * callbacks, dev_disconnect and dev_free, corresponding to the state.
- * Then release the device.
- *
- * Returns zero if successful, or a negative error code on failure or if the
- * device not found.
- */
-int snd_device_free(struct snd_card *card, void *device_data)
-{
- struct snd_device *dev;
-
- if (snd_BUG_ON(!card || !device_data))
- return -ENXIO;
- list_for_each_entry(dev, &card->devices, list) {
- if (dev->device_data != device_data)
- continue;
- /* unlink */
- list_del(&dev->list);
- if (dev->state == SNDRV_DEV_REGISTERED &&
- dev->ops->dev_disconnect)
- if (dev->ops->dev_disconnect(dev))
- snd_printk(KERN_ERR
- "device disconnect failure\n");
- if (dev->ops->dev_free) {
- if (dev->ops->dev_free(dev))
- snd_printk(KERN_ERR "device free failure\n");
- }
- kfree(dev);
- return 0;
- }
- snd_printd("device free %p (from %pF), not found\n", device_data,
- __builtin_return_address(0));
- return -ENXIO;
-}
-
-EXPORT_SYMBOL(snd_device_free);
-
-/**
- * snd_device_disconnect - disconnect the device
- * @card: the card instance
- * @device_data: the data pointer to disconnect
- *
- * Turns the device into the disconnection state, invoking
- * dev_disconnect callback, if the device was already registered.
- *
- * Usually called from snd_card_disconnect().
- *
- * Returns zero if successful, or a negative error code on failure or if the
- * device not found.
- */
-int snd_device_disconnect(struct snd_card *card, void *device_data)
-{
- struct snd_device *dev;
-
- if (snd_BUG_ON(!card || !device_data))
- return -ENXIO;
- list_for_each_entry(dev, &card->devices, list) {
- if (dev->device_data != device_data)
- continue;
- if (dev->state == SNDRV_DEV_REGISTERED &&
- dev->ops->dev_disconnect) {
- if (dev->ops->dev_disconnect(dev))
- snd_printk(KERN_ERR "device disconnect failure\n");
- dev->state = SNDRV_DEV_DISCONNECTED;
- }
- return 0;
- }
- snd_printd("device disconnect %p (from %pF), not found\n", device_data,
- __builtin_return_address(0));
- return -ENXIO;
-}
-
-/**
- * snd_device_register - register the device
- * @card: the card instance
- * @device_data: the data pointer to register
- *
- * Registers the device which was already created via
- * snd_device_new(). Usually this is called from snd_card_register(),
- * but it can be called later if any new devices are created after
- * invocation of snd_card_register().
- *
- * Returns zero if successful, or a negative error code on failure or if the
- * device not found.
- */
-int snd_device_register(struct snd_card *card, void *device_data)
-{
- struct snd_device *dev;
- int err;
-
- if (snd_BUG_ON(!card || !device_data))
- return -ENXIO;
- list_for_each_entry(dev, &card->devices, list) {
- if (dev->device_data != device_data)
- continue;
- if (dev->state == SNDRV_DEV_BUILD && dev->ops->dev_register) {
- if ((err = dev->ops->dev_register(dev)) < 0)
- return err;
- dev->state = SNDRV_DEV_REGISTERED;
- return 0;
- }
- snd_printd("snd_device_register busy\n");
- return -EBUSY;
- }
- snd_BUG();
- return -ENXIO;
-}
-
-EXPORT_SYMBOL(snd_device_register);
-
-/*
- * register all the devices on the card.
- * called from init.c
- */
-int snd_device_register_all(struct snd_card *card)
-{
- struct snd_device *dev;
- int err;
-
- if (snd_BUG_ON(!card))
- return -ENXIO;
- list_for_each_entry(dev, &card->devices, list) {
- if (dev->state == SNDRV_DEV_BUILD && dev->ops->dev_register) {
- if ((err = dev->ops->dev_register(dev)) < 0)
- return err;
- dev->state = SNDRV_DEV_REGISTERED;
- }
- }
- return 0;
-}
-
-/*
- * disconnect all the devices on the card.
- * called from init.c
- */
-int snd_device_disconnect_all(struct snd_card *card)
-{
- struct snd_device *dev;
- int err = 0;
-
- if (snd_BUG_ON(!card))
- return -ENXIO;
- list_for_each_entry(dev, &card->devices, list) {
- if (snd_device_disconnect(card, dev->device_data) < 0)
- err = -ENXIO;
- }
- return err;
-}
-
-/*
- * release all the devices on the card.
- * called from init.c
- */
-int snd_device_free_all(struct snd_card *card, snd_device_cmd_t cmd)
-{
- struct snd_device *dev;
- int err;
- unsigned int range_low, range_high, type;
-
- if (snd_BUG_ON(!card))
- return -ENXIO;
- range_low = (__force unsigned int)cmd * SNDRV_DEV_TYPE_RANGE_SIZE;
- range_high = range_low + SNDRV_DEV_TYPE_RANGE_SIZE - 1;
- __again:
- list_for_each_entry(dev, &card->devices, list) {
- type = (__force unsigned int)dev->type;
- if (type >= range_low && type <= range_high) {
- if ((err = snd_device_free(card, dev->device_data)) < 0)
- return err;
- goto __again;
- }
- }
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/core/hrtimer.c b/ANDROID_3.4.5/sound/core/hrtimer.c
deleted file mode 100644
index b8b31c43..00000000
--- a/ANDROID_3.4.5/sound/core/hrtimer.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * ALSA timer back-end using hrtimer
- * Copyright (C) 2008 Takashi Iwai
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/hrtimer.h>
-#include <sound/core.h>
-#include <sound/timer.h>
-
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("ALSA hrtimer backend");
-MODULE_LICENSE("GPL");
-
-MODULE_ALIAS("snd-timer-" __stringify(SNDRV_TIMER_GLOBAL_HRTIMER));
-
-#define NANO_SEC 1000000000UL /* 10^9 in sec */
-static unsigned int resolution;
-
-struct snd_hrtimer {
- struct snd_timer *timer;
- struct hrtimer hrt;
- atomic_t running;
-};
-
-static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
-{
- struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt);
- struct snd_timer *t = stime->timer;
- unsigned long oruns;
-
- if (!atomic_read(&stime->running))
- return HRTIMER_NORESTART;
-
- oruns = hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution));
- snd_timer_interrupt(stime->timer, t->sticks * oruns);
-
- if (!atomic_read(&stime->running))
- return HRTIMER_NORESTART;
- return HRTIMER_RESTART;
-}
-
-static int snd_hrtimer_open(struct snd_timer *t)
-{
- struct snd_hrtimer *stime;
-
- stime = kmalloc(sizeof(*stime), GFP_KERNEL);
- if (!stime)
- return -ENOMEM;
- hrtimer_init(&stime->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- stime->timer = t;
- stime->hrt.function = snd_hrtimer_callback;
- atomic_set(&stime->running, 0);
- t->private_data = stime;
- return 0;
-}
-
-static int snd_hrtimer_close(struct snd_timer *t)
-{
- struct snd_hrtimer *stime = t->private_data;
-
- if (stime) {
- hrtimer_cancel(&stime->hrt);
- kfree(stime);
- t->private_data = NULL;
- }
- return 0;
-}
-
-static int snd_hrtimer_start(struct snd_timer *t)
-{
- struct snd_hrtimer *stime = t->private_data;
-
- atomic_set(&stime->running, 0);
- hrtimer_cancel(&stime->hrt);
- hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution),
- HRTIMER_MODE_REL);
- atomic_set(&stime->running, 1);
- return 0;
-}
-
-static int snd_hrtimer_stop(struct snd_timer *t)
-{
- struct snd_hrtimer *stime = t->private_data;
- atomic_set(&stime->running, 0);
- return 0;
-}
-
-static struct snd_timer_hardware hrtimer_hw = {
- .flags = SNDRV_TIMER_HW_AUTO | SNDRV_TIMER_HW_TASKLET,
- .open = snd_hrtimer_open,
- .close = snd_hrtimer_close,
- .start = snd_hrtimer_start,
- .stop = snd_hrtimer_stop,
-};
-
-/*
- * entry functions
- */
-
-static struct snd_timer *mytimer;
-
-static int __init snd_hrtimer_init(void)
-{
- struct snd_timer *timer;
- struct timespec tp;
- int err;
-
- hrtimer_get_res(CLOCK_MONOTONIC, &tp);
- if (tp.tv_sec > 0 || !tp.tv_nsec) {
- snd_printk(KERN_ERR
- "snd-hrtimer: Invalid resolution %u.%09u",
- (unsigned)tp.tv_sec, (unsigned)tp.tv_nsec);
- return -EINVAL;
- }
- resolution = tp.tv_nsec;
-
- /* Create a new timer and set up the fields */
- err = snd_timer_global_new("hrtimer", SNDRV_TIMER_GLOBAL_HRTIMER,
- &timer);
- if (err < 0)
- return err;
-
- timer->module = THIS_MODULE;
- strcpy(timer->name, "HR timer");
- timer->hw = hrtimer_hw;
- timer->hw.resolution = resolution;
- timer->hw.ticks = NANO_SEC / resolution;
-
- err = snd_timer_global_register(timer);
- if (err < 0) {
- snd_timer_global_free(timer);
- return err;
- }
- mytimer = timer; /* remember this */
-
- return 0;
-}
-
-static void __exit snd_hrtimer_exit(void)
-{
- if (mytimer) {
- snd_timer_global_free(mytimer);
- mytimer = NULL;
- }
-}
-
-module_init(snd_hrtimer_init);
-module_exit(snd_hrtimer_exit);
diff --git a/ANDROID_3.4.5/sound/core/hwdep.c b/ANDROID_3.4.5/sound/core/hwdep.c
deleted file mode 100644
index 3f7f6628..00000000
--- a/ANDROID_3.4.5/sound/core/hwdep.c
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * Hardware dependent layer
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/major.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/mutex.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/minors.h>
-#include <sound/hwdep.h>
-#include <sound/info.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Hardware dependent layer");
-MODULE_LICENSE("GPL");
-
-static LIST_HEAD(snd_hwdep_devices);
-static DEFINE_MUTEX(register_mutex);
-
-static int snd_hwdep_free(struct snd_hwdep *hwdep);
-static int snd_hwdep_dev_free(struct snd_device *device);
-static int snd_hwdep_dev_register(struct snd_device *device);
-static int snd_hwdep_dev_disconnect(struct snd_device *device);
-
-
-static struct snd_hwdep *snd_hwdep_search(struct snd_card *card, int device)
-{
- struct snd_hwdep *hwdep;
-
- list_for_each_entry(hwdep, &snd_hwdep_devices, list)
- if (hwdep->card == card && hwdep->device == device)
- return hwdep;
- return NULL;
-}
-
-static loff_t snd_hwdep_llseek(struct file * file, loff_t offset, int orig)
-{
- struct snd_hwdep *hw = file->private_data;
- if (hw->ops.llseek)
- return hw->ops.llseek(hw, file, offset, orig);
- return -ENXIO;
-}
-
-static ssize_t snd_hwdep_read(struct file * file, char __user *buf,
- size_t count, loff_t *offset)
-{
- struct snd_hwdep *hw = file->private_data;
- if (hw->ops.read)
- return hw->ops.read(hw, buf, count, offset);
- return -ENXIO;
-}
-
-static ssize_t snd_hwdep_write(struct file * file, const char __user *buf,
- size_t count, loff_t *offset)
-{
- struct snd_hwdep *hw = file->private_data;
- if (hw->ops.write)
- return hw->ops.write(hw, buf, count, offset);
- return -ENXIO;
-}
-
-static int snd_hwdep_open(struct inode *inode, struct file * file)
-{
- int major = imajor(inode);
- struct snd_hwdep *hw;
- int err;
- wait_queue_t wait;
-
- if (major == snd_major) {
- hw = snd_lookup_minor_data(iminor(inode),
- SNDRV_DEVICE_TYPE_HWDEP);
-#ifdef CONFIG_SND_OSSEMUL
- } else if (major == SOUND_MAJOR) {
- hw = snd_lookup_oss_minor_data(iminor(inode),
- SNDRV_OSS_DEVICE_TYPE_DMFM);
-#endif
- } else
- return -ENXIO;
- if (hw == NULL)
- return -ENODEV;
-
- if (!try_module_get(hw->card->module)) {
- snd_card_unref(hw->card);
- return -EFAULT;
- }
-
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&hw->open_wait, &wait);
- mutex_lock(&hw->open_mutex);
- while (1) {
- if (hw->exclusive && hw->used > 0) {
- err = -EBUSY;
- break;
- }
- if (!hw->ops.open) {
- err = 0;
- break;
- }
- err = hw->ops.open(hw, file);
- if (err >= 0)
- break;
- if (err == -EAGAIN) {
- if (file->f_flags & O_NONBLOCK) {
- err = -EBUSY;
- break;
- }
- } else
- break;
- set_current_state(TASK_INTERRUPTIBLE);
- mutex_unlock(&hw->open_mutex);
- schedule();
- mutex_lock(&hw->open_mutex);
- if (hw->card->shutdown) {
- err = -ENODEV;
- break;
- }
- if (signal_pending(current)) {
- err = -ERESTARTSYS;
- break;
- }
- }
- remove_wait_queue(&hw->open_wait, &wait);
- if (err >= 0) {
- err = snd_card_file_add(hw->card, file);
- if (err >= 0) {
- file->private_data = hw;
- hw->used++;
- } else {
- if (hw->ops.release)
- hw->ops.release(hw, file);
- }
- }
- mutex_unlock(&hw->open_mutex);
- if (err < 0)
- module_put(hw->card->module);
- snd_card_unref(hw->card);
- return err;
-}
-
-static int snd_hwdep_release(struct inode *inode, struct file * file)
-{
- int err = 0;
- struct snd_hwdep *hw = file->private_data;
- struct module *mod = hw->card->module;
-
- mutex_lock(&hw->open_mutex);
- if (hw->ops.release)
- err = hw->ops.release(hw, file);
- if (hw->used > 0)
- hw->used--;
- mutex_unlock(&hw->open_mutex);
- wake_up(&hw->open_wait);
-
- snd_card_file_remove(hw->card, file);
- module_put(mod);
- return err;
-}
-
-static unsigned int snd_hwdep_poll(struct file * file, poll_table * wait)
-{
- struct snd_hwdep *hw = file->private_data;
- if (hw->ops.poll)
- return hw->ops.poll(hw, file, wait);
- return 0;
-}
-
-static int snd_hwdep_info(struct snd_hwdep *hw,
- struct snd_hwdep_info __user *_info)
-{
- struct snd_hwdep_info info;
-
- memset(&info, 0, sizeof(info));
- info.card = hw->card->number;
- strlcpy(info.id, hw->id, sizeof(info.id));
- strlcpy(info.name, hw->name, sizeof(info.name));
- info.iface = hw->iface;
- if (copy_to_user(_info, &info, sizeof(info)))
- return -EFAULT;
- return 0;
-}
-
-static int snd_hwdep_dsp_status(struct snd_hwdep *hw,
- struct snd_hwdep_dsp_status __user *_info)
-{
- struct snd_hwdep_dsp_status info;
- int err;
-
- if (! hw->ops.dsp_status)
- return -ENXIO;
- memset(&info, 0, sizeof(info));
- info.dsp_loaded = hw->dsp_loaded;
- if ((err = hw->ops.dsp_status(hw, &info)) < 0)
- return err;
- if (copy_to_user(_info, &info, sizeof(info)))
- return -EFAULT;
- return 0;
-}
-
-static int snd_hwdep_dsp_load(struct snd_hwdep *hw,
- struct snd_hwdep_dsp_image __user *_info)
-{
- struct snd_hwdep_dsp_image info;
- int err;
-
- if (! hw->ops.dsp_load)
- return -ENXIO;
- memset(&info, 0, sizeof(info));
- if (copy_from_user(&info, _info, sizeof(info)))
- return -EFAULT;
- /* check whether the dsp was already loaded */
- if (hw->dsp_loaded & (1 << info.index))
- return -EBUSY;
- if (!access_ok(VERIFY_READ, info.image, info.length))
- return -EFAULT;
- err = hw->ops.dsp_load(hw, &info);
- if (err < 0)
- return err;
- hw->dsp_loaded |= (1 << info.index);
- return 0;
-}
-
-static long snd_hwdep_ioctl(struct file * file, unsigned int cmd,
- unsigned long arg)
-{
- struct snd_hwdep *hw = file->private_data;
- void __user *argp = (void __user *)arg;
- switch (cmd) {
- case SNDRV_HWDEP_IOCTL_PVERSION:
- return put_user(SNDRV_HWDEP_VERSION, (int __user *)argp);
- case SNDRV_HWDEP_IOCTL_INFO:
- return snd_hwdep_info(hw, argp);
- case SNDRV_HWDEP_IOCTL_DSP_STATUS:
- return snd_hwdep_dsp_status(hw, argp);
- case SNDRV_HWDEP_IOCTL_DSP_LOAD:
- return snd_hwdep_dsp_load(hw, argp);
- }
- if (hw->ops.ioctl)
- return hw->ops.ioctl(hw, file, cmd, arg);
- return -ENOTTY;
-}
-
-static int snd_hwdep_mmap(struct file * file, struct vm_area_struct * vma)
-{
- struct snd_hwdep *hw = file->private_data;
- if (hw->ops.mmap)
- return hw->ops.mmap(hw, file, vma);
- return -ENXIO;
-}
-
-static int snd_hwdep_control_ioctl(struct snd_card *card,
- struct snd_ctl_file * control,
- unsigned int cmd, unsigned long arg)
-{
- switch (cmd) {
- case SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE:
- {
- int device;
-
- if (get_user(device, (int __user *)arg))
- return -EFAULT;
- mutex_lock(&register_mutex);
-
- if (device < 0)
- device = 0;
- else if (device < SNDRV_MINOR_HWDEPS)
- device++;
- else
- device = SNDRV_MINOR_HWDEPS;
-
- while (device < SNDRV_MINOR_HWDEPS) {
- if (snd_hwdep_search(card, device))
- break;
- device++;
- }
- if (device >= SNDRV_MINOR_HWDEPS)
- device = -1;
- mutex_unlock(&register_mutex);
- if (put_user(device, (int __user *)arg))
- return -EFAULT;
- return 0;
- }
- case SNDRV_CTL_IOCTL_HWDEP_INFO:
- {
- struct snd_hwdep_info __user *info = (struct snd_hwdep_info __user *)arg;
- int device, err;
- struct snd_hwdep *hwdep;
-
- if (get_user(device, &info->device))
- return -EFAULT;
- mutex_lock(&register_mutex);
- hwdep = snd_hwdep_search(card, device);
- if (hwdep)
- err = snd_hwdep_info(hwdep, info);
- else
- err = -ENXIO;
- mutex_unlock(&register_mutex);
- return err;
- }
- }
- return -ENOIOCTLCMD;
-}
-
-#ifdef CONFIG_COMPAT
-#include "hwdep_compat.c"
-#else
-#define snd_hwdep_ioctl_compat NULL
-#endif
-
-/*
-
- */
-
-static const struct file_operations snd_hwdep_f_ops =
-{
- .owner = THIS_MODULE,
- .llseek = snd_hwdep_llseek,
- .read = snd_hwdep_read,
- .write = snd_hwdep_write,
- .open = snd_hwdep_open,
- .release = snd_hwdep_release,
- .poll = snd_hwdep_poll,
- .unlocked_ioctl = snd_hwdep_ioctl,
- .compat_ioctl = snd_hwdep_ioctl_compat,
- .mmap = snd_hwdep_mmap,
-};
-
-/**
- * snd_hwdep_new - create a new hwdep instance
- * @card: the card instance
- * @id: the id string
- * @device: the device index (zero-based)
- * @rhwdep: the pointer to store the new hwdep instance
- *
- * Creates a new hwdep instance with the given index on the card.
- * The callbacks (hwdep->ops) must be set on the returned instance
- * after this call manually by the caller.
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_hwdep_new(struct snd_card *card, char *id, int device,
- struct snd_hwdep **rhwdep)
-{
- struct snd_hwdep *hwdep;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_hwdep_dev_free,
- .dev_register = snd_hwdep_dev_register,
- .dev_disconnect = snd_hwdep_dev_disconnect,
- };
-
- if (snd_BUG_ON(!card))
- return -ENXIO;
- if (rhwdep)
- *rhwdep = NULL;
- hwdep = kzalloc(sizeof(*hwdep), GFP_KERNEL);
- if (hwdep == NULL) {
- snd_printk(KERN_ERR "hwdep: cannot allocate\n");
- return -ENOMEM;
- }
- hwdep->card = card;
- hwdep->device = device;
- if (id)
- strlcpy(hwdep->id, id, sizeof(hwdep->id));
-#ifdef CONFIG_SND_OSSEMUL
- hwdep->oss_type = -1;
-#endif
- if ((err = snd_device_new(card, SNDRV_DEV_HWDEP, hwdep, &ops)) < 0) {
- snd_hwdep_free(hwdep);
- return err;
- }
- init_waitqueue_head(&hwdep->open_wait);
- mutex_init(&hwdep->open_mutex);
- if (rhwdep)
- *rhwdep = hwdep;
- return 0;
-}
-
-static int snd_hwdep_free(struct snd_hwdep *hwdep)
-{
- if (!hwdep)
- return 0;
- if (hwdep->private_free)
- hwdep->private_free(hwdep);
- kfree(hwdep);
- return 0;
-}
-
-static int snd_hwdep_dev_free(struct snd_device *device)
-{
- struct snd_hwdep *hwdep = device->device_data;
- return snd_hwdep_free(hwdep);
-}
-
-static int snd_hwdep_dev_register(struct snd_device *device)
-{
- struct snd_hwdep *hwdep = device->device_data;
- int err;
- char name[32];
-
- mutex_lock(&register_mutex);
- if (snd_hwdep_search(hwdep->card, hwdep->device)) {
- mutex_unlock(&register_mutex);
- return -EBUSY;
- }
- list_add_tail(&hwdep->list, &snd_hwdep_devices);
- sprintf(name, "hwC%iD%i", hwdep->card->number, hwdep->device);
- if ((err = snd_register_device(SNDRV_DEVICE_TYPE_HWDEP,
- hwdep->card, hwdep->device,
- &snd_hwdep_f_ops, hwdep, name)) < 0) {
- snd_printk(KERN_ERR "unable to register hardware dependent device %i:%i\n",
- hwdep->card->number, hwdep->device);
- list_del(&hwdep->list);
- mutex_unlock(&register_mutex);
- return err;
- }
-#ifdef CONFIG_SND_OSSEMUL
- hwdep->ossreg = 0;
- if (hwdep->oss_type >= 0) {
- if ((hwdep->oss_type == SNDRV_OSS_DEVICE_TYPE_DMFM) && (hwdep->device != 0)) {
- snd_printk (KERN_WARNING "only hwdep device 0 can be registered as OSS direct FM device!\n");
- } else {
- if (snd_register_oss_device(hwdep->oss_type,
- hwdep->card, hwdep->device,
- &snd_hwdep_f_ops, hwdep,
- hwdep->oss_dev) < 0) {
- snd_printk(KERN_ERR "unable to register OSS compatibility device %i:%i\n",
- hwdep->card->number, hwdep->device);
- } else
- hwdep->ossreg = 1;
- }
- }
-#endif
- mutex_unlock(&register_mutex);
- return 0;
-}
-
-static int snd_hwdep_dev_disconnect(struct snd_device *device)
-{
- struct snd_hwdep *hwdep = device->device_data;
-
- if (snd_BUG_ON(!hwdep))
- return -ENXIO;
- mutex_lock(&register_mutex);
- if (snd_hwdep_search(hwdep->card, hwdep->device) != hwdep) {
- mutex_unlock(&register_mutex);
- return -EINVAL;
- }
- mutex_lock(&hwdep->open_mutex);
- wake_up(&hwdep->open_wait);
-#ifdef CONFIG_SND_OSSEMUL
- if (hwdep->ossreg)
- snd_unregister_oss_device(hwdep->oss_type, hwdep->card, hwdep->device);
-#endif
- snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device);
- list_del_init(&hwdep->list);
- mutex_unlock(&hwdep->open_mutex);
- mutex_unlock(&register_mutex);
- return 0;
-}
-
-#ifdef CONFIG_PROC_FS
-/*
- * Info interface
- */
-
-static void snd_hwdep_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_hwdep *hwdep;
-
- mutex_lock(&register_mutex);
- list_for_each_entry(hwdep, &snd_hwdep_devices, list)
- snd_iprintf(buffer, "%02i-%02i: %s\n",
- hwdep->card->number, hwdep->device, hwdep->name);
- mutex_unlock(&register_mutex);
-}
-
-static struct snd_info_entry *snd_hwdep_proc_entry;
-
-static void __init snd_hwdep_proc_init(void)
-{
- struct snd_info_entry *entry;
-
- if ((entry = snd_info_create_module_entry(THIS_MODULE, "hwdep", NULL)) != NULL) {
- entry->c.text.read = snd_hwdep_proc_read;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- snd_hwdep_proc_entry = entry;
-}
-
-static void __exit snd_hwdep_proc_done(void)
-{
- snd_info_free_entry(snd_hwdep_proc_entry);
-}
-#else /* !CONFIG_PROC_FS */
-#define snd_hwdep_proc_init()
-#define snd_hwdep_proc_done()
-#endif /* CONFIG_PROC_FS */
-
-
-/*
- * ENTRY functions
- */
-
-static int __init alsa_hwdep_init(void)
-{
- snd_hwdep_proc_init();
- snd_ctl_register_ioctl(snd_hwdep_control_ioctl);
- snd_ctl_register_ioctl_compat(snd_hwdep_control_ioctl);
- return 0;
-}
-
-static void __exit alsa_hwdep_exit(void)
-{
- snd_ctl_unregister_ioctl(snd_hwdep_control_ioctl);
- snd_ctl_unregister_ioctl_compat(snd_hwdep_control_ioctl);
- snd_hwdep_proc_done();
-}
-
-module_init(alsa_hwdep_init)
-module_exit(alsa_hwdep_exit)
-
-EXPORT_SYMBOL(snd_hwdep_new);
diff --git a/ANDROID_3.4.5/sound/core/hwdep_compat.c b/ANDROID_3.4.5/sound/core/hwdep_compat.c
deleted file mode 100644
index 3827c0ce..00000000
--- a/ANDROID_3.4.5/sound/core/hwdep_compat.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 32bit -> 64bit ioctl wrapper for hwdep API
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/* This file is included from hwdep.c */
-
-#include <linux/compat.h>
-
-struct snd_hwdep_dsp_image32 {
- u32 index;
- unsigned char name[64];
- u32 image; /* pointer */
- u32 length;
- u32 driver_data;
-} /* don't set packed attribute here */;
-
-static int snd_hwdep_dsp_load_compat(struct snd_hwdep *hw,
- struct snd_hwdep_dsp_image32 __user *src)
-{
- struct snd_hwdep_dsp_image __user *dst;
- compat_caddr_t ptr;
- u32 val;
-
- dst = compat_alloc_user_space(sizeof(*dst));
-
- /* index and name */
- if (copy_in_user(dst, src, 4 + 64))
- return -EFAULT;
- if (get_user(ptr, &src->image) ||
- put_user(compat_ptr(ptr), &dst->image))
- return -EFAULT;
- if (get_user(val, &src->length) ||
- put_user(val, &dst->length))
- return -EFAULT;
- if (get_user(val, &src->driver_data) ||
- put_user(val, &dst->driver_data))
- return -EFAULT;
-
- return snd_hwdep_dsp_load(hw, dst);
-}
-
-enum {
- SNDRV_HWDEP_IOCTL_DSP_LOAD32 = _IOW('H', 0x03, struct snd_hwdep_dsp_image32)
-};
-
-static long snd_hwdep_ioctl_compat(struct file * file, unsigned int cmd,
- unsigned long arg)
-{
- struct snd_hwdep *hw = file->private_data;
- void __user *argp = compat_ptr(arg);
- switch (cmd) {
- case SNDRV_HWDEP_IOCTL_PVERSION:
- case SNDRV_HWDEP_IOCTL_INFO:
- case SNDRV_HWDEP_IOCTL_DSP_STATUS:
- return snd_hwdep_ioctl(file, cmd, (unsigned long)argp);
- case SNDRV_HWDEP_IOCTL_DSP_LOAD32:
- return snd_hwdep_dsp_load_compat(hw, argp);
- }
- if (hw->ops.ioctl_compat)
- return hw->ops.ioctl_compat(hw, file, cmd, arg);
- return -ENOIOCTLCMD;
-}
diff --git a/ANDROID_3.4.5/sound/core/info.c b/ANDROID_3.4.5/sound/core/info.c
deleted file mode 100644
index c1e611c6..00000000
--- a/ANDROID_3.4.5/sound/core/info.c
+++ /dev/null
@@ -1,1016 +0,0 @@
-/*
- * Information interface for ALSA driver
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/minors.h>
-#include <sound/info.h>
-#include <sound/version.h>
-#include <linux/proc_fs.h>
-#include <linux/mutex.h>
-#include <stdarg.h>
-
-/*
- *
- */
-
-#ifdef CONFIG_PROC_FS
-
-int snd_info_check_reserved_words(const char *str)
-{
- static char *reserved[] =
- {
- "version",
- "meminfo",
- "memdebug",
- "detect",
- "devices",
- "oss",
- "cards",
- "timers",
- "synth",
- "pcm",
- "seq",
- NULL
- };
- char **xstr = reserved;
-
- while (*xstr) {
- if (!strcmp(*xstr, str))
- return 0;
- xstr++;
- }
- if (!strncmp(str, "card", 4))
- return 0;
- return 1;
-}
-
-static DEFINE_MUTEX(info_mutex);
-
-struct snd_info_private_data {
- struct snd_info_buffer *rbuffer;
- struct snd_info_buffer *wbuffer;
- struct snd_info_entry *entry;
- void *file_private_data;
-};
-
-static int snd_info_version_init(void);
-static int snd_info_version_done(void);
-static void snd_info_disconnect(struct snd_info_entry *entry);
-
-
-/* resize the proc r/w buffer */
-static int resize_info_buffer(struct snd_info_buffer *buffer,
- unsigned int nsize)
-{
- char *nbuf;
-
- nsize = PAGE_ALIGN(nsize);
- nbuf = krealloc(buffer->buffer, nsize, GFP_KERNEL);
- if (! nbuf)
- return -ENOMEM;
-
- buffer->buffer = nbuf;
- buffer->len = nsize;
- return 0;
-}
-
-/**
- * snd_iprintf - printf on the procfs buffer
- * @buffer: the procfs buffer
- * @fmt: the printf format
- *
- * Outputs the string on the procfs buffer just like printf().
- *
- * Returns the size of output string.
- */
-int snd_iprintf(struct snd_info_buffer *buffer, const char *fmt, ...)
-{
- va_list args;
- int len, res;
- int err = 0;
-
- might_sleep();
- if (buffer->stop || buffer->error)
- return 0;
- len = buffer->len - buffer->size;
- va_start(args, fmt);
- for (;;) {
- va_list ap;
- va_copy(ap, args);
- res = vsnprintf(buffer->buffer + buffer->curr, len, fmt, ap);
- va_end(ap);
- if (res < len)
- break;
- err = resize_info_buffer(buffer, buffer->len + PAGE_SIZE);
- if (err < 0)
- break;
- len = buffer->len - buffer->size;
- }
- va_end(args);
-
- if (err < 0)
- return err;
- buffer->curr += res;
- buffer->size += res;
- return res;
-}
-
-EXPORT_SYMBOL(snd_iprintf);
-
-/*
-
- */
-
-static struct proc_dir_entry *snd_proc_root;
-struct snd_info_entry *snd_seq_root;
-EXPORT_SYMBOL(snd_seq_root);
-
-#ifdef CONFIG_SND_OSSEMUL
-struct snd_info_entry *snd_oss_root;
-#endif
-
-static void snd_remove_proc_entry(struct proc_dir_entry *parent,
- struct proc_dir_entry *de)
-{
- if (de)
- remove_proc_entry(de->name, parent);
-}
-
-static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
-{
- struct snd_info_private_data *data;
- struct snd_info_entry *entry;
- loff_t ret = -EINVAL, size;
-
- data = file->private_data;
- entry = data->entry;
- mutex_lock(&entry->access);
- if (entry->content == SNDRV_INFO_CONTENT_DATA &&
- entry->c.ops->llseek) {
- offset = entry->c.ops->llseek(entry,
- data->file_private_data,
- file, offset, orig);
- goto out;
- }
- if (entry->content == SNDRV_INFO_CONTENT_DATA)
- size = entry->size;
- else
- size = 0;
- switch (orig) {
- case SEEK_SET:
- break;
- case SEEK_CUR:
- offset += file->f_pos;
- break;
- case SEEK_END:
- if (!size)
- goto out;
- offset += size;
- break;
- default:
- goto out;
- }
- if (offset < 0)
- goto out;
- if (size && offset > size)
- offset = size;
- file->f_pos = offset;
- ret = offset;
- out:
- mutex_unlock(&entry->access);
- return ret;
-}
-
-static ssize_t snd_info_entry_read(struct file *file, char __user *buffer,
- size_t count, loff_t * offset)
-{
- struct snd_info_private_data *data;
- struct snd_info_entry *entry;
- struct snd_info_buffer *buf;
- size_t size = 0;
- loff_t pos;
-
- data = file->private_data;
- if (snd_BUG_ON(!data))
- return -ENXIO;
- pos = *offset;
- if (pos < 0 || (long) pos != pos || (ssize_t) count < 0)
- return -EIO;
- if ((unsigned long) pos + (unsigned long) count < (unsigned long) pos)
- return -EIO;
- entry = data->entry;
- switch (entry->content) {
- case SNDRV_INFO_CONTENT_TEXT:
- buf = data->rbuffer;
- if (buf == NULL)
- return -EIO;
- if (pos >= buf->size)
- return 0;
- size = buf->size - pos;
- size = min(count, size);
- if (copy_to_user(buffer, buf->buffer + pos, size))
- return -EFAULT;
- break;
- case SNDRV_INFO_CONTENT_DATA:
- if (pos >= entry->size)
- return 0;
- if (entry->c.ops->read) {
- size = entry->size - pos;
- size = min(count, size);
- size = entry->c.ops->read(entry,
- data->file_private_data,
- file, buffer, size, pos);
- }
- break;
- }
- if ((ssize_t) size > 0)
- *offset = pos + size;
- return size;
-}
-
-static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer,
- size_t count, loff_t * offset)
-{
- struct snd_info_private_data *data;
- struct snd_info_entry *entry;
- struct snd_info_buffer *buf;
- ssize_t size = 0;
- loff_t pos;
-
- data = file->private_data;
- if (snd_BUG_ON(!data))
- return -ENXIO;
- entry = data->entry;
- pos = *offset;
- if (pos < 0 || (long) pos != pos || (ssize_t) count < 0)
- return -EIO;
- if ((unsigned long) pos + (unsigned long) count < (unsigned long) pos)
- return -EIO;
- switch (entry->content) {
- case SNDRV_INFO_CONTENT_TEXT:
- buf = data->wbuffer;
- if (buf == NULL)
- return -EIO;
- mutex_lock(&entry->access);
- if (pos + count >= buf->len) {
- if (resize_info_buffer(buf, pos + count)) {
- mutex_unlock(&entry->access);
- return -ENOMEM;
- }
- }
- if (copy_from_user(buf->buffer + pos, buffer, count)) {
- mutex_unlock(&entry->access);
- return -EFAULT;
- }
- buf->size = pos + count;
- mutex_unlock(&entry->access);
- size = count;
- break;
- case SNDRV_INFO_CONTENT_DATA:
- if (entry->c.ops->write && count > 0) {
- size_t maxsize = entry->size - pos;
- count = min(count, maxsize);
- size = entry->c.ops->write(entry,
- data->file_private_data,
- file, buffer, count, pos);
- }
- break;
- }
- if ((ssize_t) size > 0)
- *offset = pos + size;
- return size;
-}
-
-static int snd_info_entry_open(struct inode *inode, struct file *file)
-{
- struct snd_info_entry *entry;
- struct snd_info_private_data *data;
- struct snd_info_buffer *buffer;
- struct proc_dir_entry *p;
- int mode, err;
-
- mutex_lock(&info_mutex);
- p = PDE(inode);
- entry = p == NULL ? NULL : (struct snd_info_entry *)p->data;
- if (entry == NULL || ! entry->p) {
- mutex_unlock(&info_mutex);
- return -ENODEV;
- }
- if (!try_module_get(entry->module)) {
- err = -EFAULT;
- goto __error1;
- }
- mode = file->f_flags & O_ACCMODE;
- if (mode == O_RDONLY || mode == O_RDWR) {
- if ((entry->content == SNDRV_INFO_CONTENT_DATA &&
- entry->c.ops->read == NULL)) {
- err = -ENODEV;
- goto __error;
- }
- }
- if (mode == O_WRONLY || mode == O_RDWR) {
- if ((entry->content == SNDRV_INFO_CONTENT_DATA &&
- entry->c.ops->write == NULL)) {
- err = -ENODEV;
- goto __error;
- }
- }
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (data == NULL) {
- err = -ENOMEM;
- goto __error;
- }
- data->entry = entry;
- switch (entry->content) {
- case SNDRV_INFO_CONTENT_TEXT:
- if (mode == O_RDONLY || mode == O_RDWR) {
- buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
- if (buffer == NULL)
- goto __nomem;
- data->rbuffer = buffer;
- buffer->len = PAGE_SIZE;
- buffer->buffer = kmalloc(buffer->len, GFP_KERNEL);
- if (buffer->buffer == NULL)
- goto __nomem;
- }
- if (mode == O_WRONLY || mode == O_RDWR) {
- buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
- if (buffer == NULL)
- goto __nomem;
- data->wbuffer = buffer;
- buffer->len = PAGE_SIZE;
- buffer->buffer = kmalloc(buffer->len, GFP_KERNEL);
- if (buffer->buffer == NULL)
- goto __nomem;
- }
- break;
- case SNDRV_INFO_CONTENT_DATA: /* data */
- if (entry->c.ops->open) {
- if ((err = entry->c.ops->open(entry, mode,
- &data->file_private_data)) < 0) {
- kfree(data);
- goto __error;
- }
- }
- break;
- }
- file->private_data = data;
- mutex_unlock(&info_mutex);
- if (entry->content == SNDRV_INFO_CONTENT_TEXT &&
- (mode == O_RDONLY || mode == O_RDWR)) {
- if (entry->c.text.read) {
- mutex_lock(&entry->access);
- entry->c.text.read(entry, data->rbuffer);
- mutex_unlock(&entry->access);
- }
- }
- return 0;
-
- __nomem:
- if (data->rbuffer) {
- kfree(data->rbuffer->buffer);
- kfree(data->rbuffer);
- }
- if (data->wbuffer) {
- kfree(data->wbuffer->buffer);
- kfree(data->wbuffer);
- }
- kfree(data);
- err = -ENOMEM;
- __error:
- module_put(entry->module);
- __error1:
- mutex_unlock(&info_mutex);
- return err;
-}
-
-static int snd_info_entry_release(struct inode *inode, struct file *file)
-{
- struct snd_info_entry *entry;
- struct snd_info_private_data *data;
- int mode;
-
- mode = file->f_flags & O_ACCMODE;
- data = file->private_data;
- entry = data->entry;
- switch (entry->content) {
- case SNDRV_INFO_CONTENT_TEXT:
- if (data->rbuffer) {
- kfree(data->rbuffer->buffer);
- kfree(data->rbuffer);
- }
- if (data->wbuffer) {
- if (entry->c.text.write) {
- entry->c.text.write(entry, data->wbuffer);
- if (data->wbuffer->error) {
- snd_printk(KERN_WARNING "data write error to %s (%i)\n",
- entry->name,
- data->wbuffer->error);
- }
- }
- kfree(data->wbuffer->buffer);
- kfree(data->wbuffer);
- }
- break;
- case SNDRV_INFO_CONTENT_DATA:
- if (entry->c.ops->release)
- entry->c.ops->release(entry, mode,
- data->file_private_data);
- break;
- }
- module_put(entry->module);
- kfree(data);
- return 0;
-}
-
-static unsigned int snd_info_entry_poll(struct file *file, poll_table * wait)
-{
- struct snd_info_private_data *data;
- struct snd_info_entry *entry;
- unsigned int mask;
-
- data = file->private_data;
- if (data == NULL)
- return 0;
- entry = data->entry;
- mask = 0;
- switch (entry->content) {
- case SNDRV_INFO_CONTENT_DATA:
- if (entry->c.ops->poll)
- return entry->c.ops->poll(entry,
- data->file_private_data,
- file, wait);
- if (entry->c.ops->read)
- mask |= POLLIN | POLLRDNORM;
- if (entry->c.ops->write)
- mask |= POLLOUT | POLLWRNORM;
- break;
- }
- return mask;
-}
-
-static long snd_info_entry_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct snd_info_private_data *data;
- struct snd_info_entry *entry;
-
- data = file->private_data;
- if (data == NULL)
- return 0;
- entry = data->entry;
- switch (entry->content) {
- case SNDRV_INFO_CONTENT_DATA:
- if (entry->c.ops->ioctl)
- return entry->c.ops->ioctl(entry,
- data->file_private_data,
- file, cmd, arg);
- break;
- }
- return -ENOTTY;
-}
-
-static int snd_info_entry_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct inode *inode = file->f_path.dentry->d_inode;
- struct snd_info_private_data *data;
- struct snd_info_entry *entry;
-
- data = file->private_data;
- if (data == NULL)
- return 0;
- entry = data->entry;
- switch (entry->content) {
- case SNDRV_INFO_CONTENT_DATA:
- if (entry->c.ops->mmap)
- return entry->c.ops->mmap(entry,
- data->file_private_data,
- inode, file, vma);
- break;
- }
- return -ENXIO;
-}
-
-static const struct file_operations snd_info_entry_operations =
-{
- .owner = THIS_MODULE,
- .llseek = snd_info_entry_llseek,
- .read = snd_info_entry_read,
- .write = snd_info_entry_write,
- .poll = snd_info_entry_poll,
- .unlocked_ioctl = snd_info_entry_ioctl,
- .mmap = snd_info_entry_mmap,
- .open = snd_info_entry_open,
- .release = snd_info_entry_release,
-};
-
-int __init snd_info_init(void)
-{
- struct proc_dir_entry *p;
-
- p = proc_mkdir("asound", NULL);
- if (p == NULL)
- return -ENOMEM;
- snd_proc_root = p;
-#ifdef CONFIG_SND_OSSEMUL
- {
- struct snd_info_entry *entry;
- if ((entry = snd_info_create_module_entry(THIS_MODULE, "oss", NULL)) == NULL)
- return -ENOMEM;
- entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- return -ENOMEM;
- }
- snd_oss_root = entry;
- }
-#endif
-#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
- {
- struct snd_info_entry *entry;
- if ((entry = snd_info_create_module_entry(THIS_MODULE, "seq", NULL)) == NULL)
- return -ENOMEM;
- entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- return -ENOMEM;
- }
- snd_seq_root = entry;
- }
-#endif
- snd_info_version_init();
- snd_minor_info_init();
- snd_minor_info_oss_init();
- snd_card_info_init();
- return 0;
-}
-
-int __exit snd_info_done(void)
-{
- snd_card_info_done();
- snd_minor_info_oss_done();
- snd_minor_info_done();
- snd_info_version_done();
- if (snd_proc_root) {
-#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
- snd_info_free_entry(snd_seq_root);
-#endif
-#ifdef CONFIG_SND_OSSEMUL
- snd_info_free_entry(snd_oss_root);
-#endif
- snd_remove_proc_entry(NULL, snd_proc_root);
- }
- return 0;
-}
-
-/*
-
- */
-
-
-/*
- * create a card proc file
- * called from init.c
- */
-int snd_info_card_create(struct snd_card *card)
-{
- char str[8];
- struct snd_info_entry *entry;
-
- if (snd_BUG_ON(!card))
- return -ENXIO;
-
- sprintf(str, "card%i", card->number);
- if ((entry = snd_info_create_module_entry(card->module, str, NULL)) == NULL)
- return -ENOMEM;
- entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- return -ENOMEM;
- }
- card->proc_root = entry;
- return 0;
-}
-
-/*
- * register the card proc file
- * called from init.c
- */
-int snd_info_card_register(struct snd_card *card)
-{
- struct proc_dir_entry *p;
-
- if (snd_BUG_ON(!card))
- return -ENXIO;
-
- if (!strcmp(card->id, card->proc_root->name))
- return 0;
-
- p = proc_symlink(card->id, snd_proc_root, card->proc_root->name);
- if (p == NULL)
- return -ENOMEM;
- card->proc_root_link = p;
- return 0;
-}
-
-/*
- * called on card->id change
- */
-void snd_info_card_id_change(struct snd_card *card)
-{
- mutex_lock(&info_mutex);
- if (card->proc_root_link) {
- snd_remove_proc_entry(snd_proc_root, card->proc_root_link);
- card->proc_root_link = NULL;
- }
- if (strcmp(card->id, card->proc_root->name))
- card->proc_root_link = proc_symlink(card->id,
- snd_proc_root,
- card->proc_root->name);
- mutex_unlock(&info_mutex);
-}
-
-/*
- * de-register the card proc file
- * called from init.c
- */
-void snd_info_card_disconnect(struct snd_card *card)
-{
- if (!card)
- return;
- mutex_lock(&info_mutex);
- if (card->proc_root_link) {
- snd_remove_proc_entry(snd_proc_root, card->proc_root_link);
- card->proc_root_link = NULL;
- }
- if (card->proc_root)
- snd_info_disconnect(card->proc_root);
- mutex_unlock(&info_mutex);
-}
-
-/*
- * release the card proc file resources
- * called from init.c
- */
-int snd_info_card_free(struct snd_card *card)
-{
- if (!card)
- return 0;
- snd_info_free_entry(card->proc_root);
- card->proc_root = NULL;
- return 0;
-}
-
-
-/**
- * snd_info_get_line - read one line from the procfs buffer
- * @buffer: the procfs buffer
- * @line: the buffer to store
- * @len: the max. buffer size - 1
- *
- * Reads one line from the buffer and stores the string.
- *
- * Returns zero if successful, or 1 if error or EOF.
- */
-int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len)
-{
- int c = -1;
-
- if (len <= 0 || buffer->stop || buffer->error)
- return 1;
- while (--len > 0) {
- c = buffer->buffer[buffer->curr++];
- if (c == '\n') {
- if (buffer->curr >= buffer->size)
- buffer->stop = 1;
- break;
- }
- *line++ = c;
- if (buffer->curr >= buffer->size) {
- buffer->stop = 1;
- break;
- }
- }
- while (c != '\n' && !buffer->stop) {
- c = buffer->buffer[buffer->curr++];
- if (buffer->curr >= buffer->size)
- buffer->stop = 1;
- }
- *line = '\0';
- return 0;
-}
-
-EXPORT_SYMBOL(snd_info_get_line);
-
-/**
- * snd_info_get_str - parse a string token
- * @dest: the buffer to store the string token
- * @src: the original string
- * @len: the max. length of token - 1
- *
- * Parses the original string and copy a token to the given
- * string buffer.
- *
- * Returns the updated pointer of the original string so that
- * it can be used for the next call.
- */
-const char *snd_info_get_str(char *dest, const char *src, int len)
-{
- int c;
-
- while (*src == ' ' || *src == '\t')
- src++;
- if (*src == '"' || *src == '\'') {
- c = *src++;
- while (--len > 0 && *src && *src != c) {
- *dest++ = *src++;
- }
- if (*src == c)
- src++;
- } else {
- while (--len > 0 && *src && *src != ' ' && *src != '\t') {
- *dest++ = *src++;
- }
- }
- *dest = 0;
- while (*src == ' ' || *src == '\t')
- src++;
- return src;
-}
-
-EXPORT_SYMBOL(snd_info_get_str);
-
-/**
- * snd_info_create_entry - create an info entry
- * @name: the proc file name
- *
- * Creates an info entry with the given file name and initializes as
- * the default state.
- *
- * Usually called from other functions such as
- * snd_info_create_card_entry().
- *
- * Returns the pointer of the new instance, or NULL on failure.
- */
-static struct snd_info_entry *snd_info_create_entry(const char *name)
-{
- struct snd_info_entry *entry;
- entry = kzalloc(sizeof(*entry), GFP_KERNEL);
- if (entry == NULL)
- return NULL;
- entry->name = kstrdup(name, GFP_KERNEL);
- if (entry->name == NULL) {
- kfree(entry);
- return NULL;
- }
- entry->mode = S_IFREG | S_IRUGO;
- entry->content = SNDRV_INFO_CONTENT_TEXT;
- mutex_init(&entry->access);
- INIT_LIST_HEAD(&entry->children);
- INIT_LIST_HEAD(&entry->list);
- return entry;
-}
-
-/**
- * snd_info_create_module_entry - create an info entry for the given module
- * @module: the module pointer
- * @name: the file name
- * @parent: the parent directory
- *
- * Creates a new info entry and assigns it to the given module.
- *
- * Returns the pointer of the new instance, or NULL on failure.
- */
-struct snd_info_entry *snd_info_create_module_entry(struct module * module,
- const char *name,
- struct snd_info_entry *parent)
-{
- struct snd_info_entry *entry = snd_info_create_entry(name);
- if (entry) {
- entry->module = module;
- entry->parent = parent;
- }
- return entry;
-}
-
-EXPORT_SYMBOL(snd_info_create_module_entry);
-
-/**
- * snd_info_create_card_entry - create an info entry for the given card
- * @card: the card instance
- * @name: the file name
- * @parent: the parent directory
- *
- * Creates a new info entry and assigns it to the given card.
- *
- * Returns the pointer of the new instance, or NULL on failure.
- */
-struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card,
- const char *name,
- struct snd_info_entry * parent)
-{
- struct snd_info_entry *entry = snd_info_create_entry(name);
- if (entry) {
- entry->module = card->module;
- entry->card = card;
- entry->parent = parent;
- }
- return entry;
-}
-
-EXPORT_SYMBOL(snd_info_create_card_entry);
-
-static void snd_info_disconnect(struct snd_info_entry *entry)
-{
- struct list_head *p, *n;
- struct proc_dir_entry *root;
-
- list_for_each_safe(p, n, &entry->children) {
- snd_info_disconnect(list_entry(p, struct snd_info_entry, list));
- }
-
- if (! entry->p)
- return;
- list_del_init(&entry->list);
- root = entry->parent == NULL ? snd_proc_root : entry->parent->p;
- snd_BUG_ON(!root);
- snd_remove_proc_entry(root, entry->p);
- entry->p = NULL;
-}
-
-static int snd_info_dev_free_entry(struct snd_device *device)
-{
- struct snd_info_entry *entry = device->device_data;
- snd_info_free_entry(entry);
- return 0;
-}
-
-static int snd_info_dev_register_entry(struct snd_device *device)
-{
- struct snd_info_entry *entry = device->device_data;
- return snd_info_register(entry);
-}
-
-/**
- * snd_card_proc_new - create an info entry for the given card
- * @card: the card instance
- * @name: the file name
- * @entryp: the pointer to store the new info entry
- *
- * Creates a new info entry and assigns it to the given card.
- * Unlike snd_info_create_card_entry(), this function registers the
- * info entry as an ALSA device component, so that it can be
- * unregistered/released without explicit call.
- * Also, you don't have to register this entry via snd_info_register(),
- * since this will be registered by snd_card_register() automatically.
- *
- * The parent is assumed as card->proc_root.
- *
- * For releasing this entry, use snd_device_free() instead of
- * snd_info_free_entry().
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_card_proc_new(struct snd_card *card, const char *name,
- struct snd_info_entry **entryp)
-{
- static struct snd_device_ops ops = {
- .dev_free = snd_info_dev_free_entry,
- .dev_register = snd_info_dev_register_entry,
- /* disconnect is done via snd_info_card_disconnect() */
- };
- struct snd_info_entry *entry;
- int err;
-
- entry = snd_info_create_card_entry(card, name, card->proc_root);
- if (! entry)
- return -ENOMEM;
- if ((err = snd_device_new(card, SNDRV_DEV_INFO, entry, &ops)) < 0) {
- snd_info_free_entry(entry);
- return err;
- }
- if (entryp)
- *entryp = entry;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_card_proc_new);
-
-/**
- * snd_info_free_entry - release the info entry
- * @entry: the info entry
- *
- * Releases the info entry. Don't call this after registered.
- */
-void snd_info_free_entry(struct snd_info_entry * entry)
-{
- if (entry == NULL)
- return;
- if (entry->p) {
- mutex_lock(&info_mutex);
- snd_info_disconnect(entry);
- mutex_unlock(&info_mutex);
- }
- kfree(entry->name);
- if (entry->private_free)
- entry->private_free(entry);
- kfree(entry);
-}
-
-EXPORT_SYMBOL(snd_info_free_entry);
-
-/**
- * snd_info_register - register the info entry
- * @entry: the info entry
- *
- * Registers the proc info entry.
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_info_register(struct snd_info_entry * entry)
-{
- struct proc_dir_entry *root, *p = NULL;
-
- if (snd_BUG_ON(!entry))
- return -ENXIO;
- root = entry->parent == NULL ? snd_proc_root : entry->parent->p;
- mutex_lock(&info_mutex);
- p = create_proc_entry(entry->name, entry->mode, root);
- if (!p) {
- mutex_unlock(&info_mutex);
- return -ENOMEM;
- }
- if (!S_ISDIR(entry->mode))
- p->proc_fops = &snd_info_entry_operations;
- p->size = entry->size;
- p->data = entry;
- entry->p = p;
- if (entry->parent)
- list_add_tail(&entry->list, &entry->parent->children);
- mutex_unlock(&info_mutex);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_info_register);
-
-/*
-
- */
-
-static struct snd_info_entry *snd_info_version_entry;
-
-static void snd_info_version_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- snd_iprintf(buffer,
- "Advanced Linux Sound Architecture Driver Version "
- CONFIG_SND_VERSION CONFIG_SND_DATE ".\n"
- );
-}
-
-static int __init snd_info_version_init(void)
-{
- struct snd_info_entry *entry;
-
- entry = snd_info_create_module_entry(THIS_MODULE, "version", NULL);
- if (entry == NULL)
- return -ENOMEM;
- entry->c.text.read = snd_info_version_read;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- return -ENOMEM;
- }
- snd_info_version_entry = entry;
- return 0;
-}
-
-static int __exit snd_info_version_done(void)
-{
- snd_info_free_entry(snd_info_version_entry);
- return 0;
-}
-
-#endif /* CONFIG_PROC_FS */
diff --git a/ANDROID_3.4.5/sound/core/info_oss.c b/ANDROID_3.4.5/sound/core/info_oss.c
deleted file mode 100644
index cf42ab50..00000000
--- a/ANDROID_3.4.5/sound/core/info_oss.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Information interface for ALSA driver
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/string.h>
-#include <linux/export.h>
-#include <sound/core.h>
-#include <sound/minors.h>
-#include <sound/info.h>
-#include <sound/version.h>
-#include <linux/utsname.h>
-#include <linux/mutex.h>
-
-#if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS)
-
-/*
- * OSS compatible part
- */
-
-static DEFINE_MUTEX(strings);
-static char *snd_sndstat_strings[SNDRV_CARDS][SNDRV_OSS_INFO_DEV_COUNT];
-static struct snd_info_entry *snd_sndstat_proc_entry;
-
-int snd_oss_info_register(int dev, int num, char *string)
-{
- char *x;
-
- if (snd_BUG_ON(dev < 0 || dev >= SNDRV_OSS_INFO_DEV_COUNT))
- return -ENXIO;
- if (snd_BUG_ON(num < 0 || num >= SNDRV_CARDS))
- return -ENXIO;
- mutex_lock(&strings);
- if (string == NULL) {
- if ((x = snd_sndstat_strings[num][dev]) != NULL) {
- kfree(x);
- x = NULL;
- }
- } else {
- x = kstrdup(string, GFP_KERNEL);
- if (x == NULL) {
- mutex_unlock(&strings);
- return -ENOMEM;
- }
- }
- snd_sndstat_strings[num][dev] = x;
- mutex_unlock(&strings);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_oss_info_register);
-
-static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int dev)
-{
- int idx, ok = -1;
- char *str;
-
- snd_iprintf(buf, "\n%s:", id);
- mutex_lock(&strings);
- for (idx = 0; idx < SNDRV_CARDS; idx++) {
- str = snd_sndstat_strings[idx][dev];
- if (str) {
- if (ok < 0) {
- snd_iprintf(buf, "\n");
- ok++;
- }
- snd_iprintf(buf, "%i: %s\n", idx, str);
- }
- }
- mutex_unlock(&strings);
- if (ok < 0)
- snd_iprintf(buf, " NOT ENABLED IN CONFIG\n");
- return ok;
-}
-
-static void snd_sndstat_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- snd_iprintf(buffer, "Sound Driver:3.8.1a-980706 (ALSA v" CONFIG_SND_VERSION " emulation code)\n");
- snd_iprintf(buffer, "Kernel: %s %s %s %s %s\n",
- init_utsname()->sysname,
- init_utsname()->nodename,
- init_utsname()->release,
- init_utsname()->version,
- init_utsname()->machine);
- snd_iprintf(buffer, "Config options: 0\n");
- snd_iprintf(buffer, "\nInstalled drivers: \n");
- snd_iprintf(buffer, "Type 10: ALSA emulation\n");
- snd_iprintf(buffer, "\nCard config: \n");
- snd_card_info_read_oss(buffer);
- snd_sndstat_show_strings(buffer, "Audio devices", SNDRV_OSS_INFO_DEV_AUDIO);
- snd_sndstat_show_strings(buffer, "Synth devices", SNDRV_OSS_INFO_DEV_SYNTH);
- snd_sndstat_show_strings(buffer, "Midi devices", SNDRV_OSS_INFO_DEV_MIDI);
- snd_sndstat_show_strings(buffer, "Timers", SNDRV_OSS_INFO_DEV_TIMERS);
- snd_sndstat_show_strings(buffer, "Mixers", SNDRV_OSS_INFO_DEV_MIXERS);
-}
-
-int snd_info_minor_register(void)
-{
- struct snd_info_entry *entry;
-
- memset(snd_sndstat_strings, 0, sizeof(snd_sndstat_strings));
- if ((entry = snd_info_create_module_entry(THIS_MODULE, "sndstat", snd_oss_root)) != NULL) {
- entry->c.text.read = snd_sndstat_proc_read;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- snd_sndstat_proc_entry = entry;
- return 0;
-}
-
-int snd_info_minor_unregister(void)
-{
- snd_info_free_entry(snd_sndstat_proc_entry);
- snd_sndstat_proc_entry = NULL;
- return 0;
-}
-
-#endif /* CONFIG_SND_OSSEMUL */
diff --git a/ANDROID_3.4.5/sound/core/init.c b/ANDROID_3.4.5/sound/core/init.c
deleted file mode 100644
index 7b012d15..00000000
--- a/ANDROID_3.4.5/sound/core/init.c
+++ /dev/null
@@ -1,991 +0,0 @@
-/*
- * Initialization routines
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/file.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/ctype.h>
-#include <linux/pm.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/info.h>
-
-/* monitor files for graceful shutdown (hotplug) */
-struct snd_monitor_file {
- struct file *file;
- const struct file_operations *disconnected_f_op;
- struct list_head shutdown_list; /* still need to shutdown */
- struct list_head list; /* link of monitor files */
-};
-
-static DEFINE_SPINLOCK(shutdown_lock);
-static LIST_HEAD(shutdown_files);
-
-static const struct file_operations snd_shutdown_f_ops;
-
-static unsigned int snd_cards_lock; /* locked for registering/using */
-struct snd_card *snd_cards[SNDRV_CARDS];
-EXPORT_SYMBOL(snd_cards);
-
-static DEFINE_MUTEX(snd_card_mutex);
-
-static char *slots[SNDRV_CARDS];
-module_param_array(slots, charp, NULL, 0444);
-MODULE_PARM_DESC(slots, "Module names assigned to the slots.");
-
-/* return non-zero if the given index is reserved for the given
- * module via slots option
- */
-static int module_slot_match(struct module *module, int idx)
-{
- int match = 1;
-#ifdef MODULE
- const char *s1, *s2;
-
- if (!module || !module->name || !slots[idx])
- return 0;
-
- s1 = module->name;
- s2 = slots[idx];
- if (*s2 == '!') {
- match = 0; /* negative match */
- s2++;
- }
- /* compare module name strings
- * hyphens are handled as equivalent with underscore
- */
- for (;;) {
- char c1 = *s1++;
- char c2 = *s2++;
- if (c1 == '-')
- c1 = '_';
- if (c2 == '-')
- c2 = '_';
- if (c1 != c2)
- return !match;
- if (!c1)
- break;
- }
-#endif /* MODULE */
- return match;
-}
-
-#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
-int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag);
-EXPORT_SYMBOL(snd_mixer_oss_notify_callback);
-#endif
-
-#ifdef CONFIG_PROC_FS
-static void snd_card_id_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- snd_iprintf(buffer, "%s\n", entry->card->id);
-}
-
-static inline int init_info_for_card(struct snd_card *card)
-{
- int err;
- struct snd_info_entry *entry;
-
- if ((err = snd_info_card_register(card)) < 0) {
- snd_printd("unable to create card info\n");
- return err;
- }
- if ((entry = snd_info_create_card_entry(card, "id", card->proc_root)) == NULL) {
- snd_printd("unable to create card entry\n");
- return err;
- }
- entry->c.text.read = snd_card_id_read;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- card->proc_id = entry;
- return 0;
-}
-#else /* !CONFIG_PROC_FS */
-#define init_info_for_card(card)
-#endif
-
-/**
- * snd_card_create - create and initialize a soundcard structure
- * @idx: card index (address) [0 ... (SNDRV_CARDS-1)]
- * @xid: card identification (ASCII string)
- * @module: top level module for locking
- * @extra_size: allocate this extra size after the main soundcard structure
- * @card_ret: the pointer to store the created card instance
- *
- * Creates and initializes a soundcard structure.
- *
- * The function allocates snd_card instance via kzalloc with the given
- * space for the driver to use freely. The allocated struct is stored
- * in the given card_ret pointer.
- *
- * Returns zero if successful or a negative error code.
- */
-int snd_card_create(int idx, const char *xid,
- struct module *module, int extra_size,
- struct snd_card **card_ret)
-{
- struct snd_card *card;
- int err, idx2;
-
- if (snd_BUG_ON(!card_ret))
- return -EINVAL;
- *card_ret = NULL;
-
- if (extra_size < 0)
- extra_size = 0;
- card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL);
- if (!card)
- return -ENOMEM;
- if (xid)
- strlcpy(card->id, xid, sizeof(card->id));
- err = 0;
- mutex_lock(&snd_card_mutex);
- if (idx < 0) {
- for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)
- /* idx == -1 == 0xffff means: take any free slot */
- if (~snd_cards_lock & idx & 1<<idx2) {
- if (module_slot_match(module, idx2)) {
- idx = idx2;
- break;
- }
- }
- }
- if (idx < 0) {
- for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)
- /* idx == -1 == 0xffff means: take any free slot */
- if (~snd_cards_lock & idx & 1<<idx2) {
- if (!slots[idx2] || !*slots[idx2]) {
- idx = idx2;
- break;
- }
- }
- }
- if (idx < 0)
- err = -ENODEV;
- else if (idx < snd_ecards_limit) {
- if (snd_cards_lock & (1 << idx))
- err = -EBUSY; /* invalid */
- } else if (idx >= SNDRV_CARDS)
- err = -ENODEV;
- if (err < 0) {
- mutex_unlock(&snd_card_mutex);
- snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i), error: %d\n",
- idx, snd_ecards_limit - 1, err);
- goto __error;
- }
- snd_cards_lock |= 1 << idx; /* lock it */
- if (idx >= snd_ecards_limit)
- snd_ecards_limit = idx + 1; /* increase the limit */
- mutex_unlock(&snd_card_mutex);
- card->number = idx;
- card->module = module;
- INIT_LIST_HEAD(&card->devices);
- init_rwsem(&card->controls_rwsem);
- rwlock_init(&card->ctl_files_rwlock);
- INIT_LIST_HEAD(&card->controls);
- INIT_LIST_HEAD(&card->ctl_files);
- spin_lock_init(&card->files_lock);
- INIT_LIST_HEAD(&card->files_list);
- init_waitqueue_head(&card->shutdown_sleep);
- atomic_set(&card->refcount, 0);
-#ifdef CONFIG_PM
- mutex_init(&card->power_lock);
- init_waitqueue_head(&card->power_sleep);
-#endif
- /* the control interface cannot be accessed from the user space until */
- /* snd_cards_bitmask and snd_cards are set with snd_card_register */
- err = snd_ctl_create(card);
- if (err < 0) {
- snd_printk(KERN_ERR "unable to register control minors\n");
- goto __error;
- }
- err = snd_info_card_create(card);
- if (err < 0) {
- snd_printk(KERN_ERR "unable to create card info\n");
- goto __error_ctl;
- }
- if (extra_size > 0)
- card->private_data = (char *)card + sizeof(struct snd_card);
- *card_ret = card;
- return 0;
-
- __error_ctl:
- snd_device_free_all(card, SNDRV_DEV_CMD_PRE);
- __error:
- kfree(card);
- return err;
-}
-EXPORT_SYMBOL(snd_card_create);
-
-/* return non-zero if a card is already locked */
-int snd_card_locked(int card)
-{
- int locked;
-
- mutex_lock(&snd_card_mutex);
- locked = snd_cards_lock & (1 << card);
- mutex_unlock(&snd_card_mutex);
- return locked;
-}
-
-static loff_t snd_disconnect_llseek(struct file *file, loff_t offset, int orig)
-{
- return -ENODEV;
-}
-
-static ssize_t snd_disconnect_read(struct file *file, char __user *buf,
- size_t count, loff_t *offset)
-{
- return -ENODEV;
-}
-
-static ssize_t snd_disconnect_write(struct file *file, const char __user *buf,
- size_t count, loff_t *offset)
-{
- return -ENODEV;
-}
-
-static int snd_disconnect_release(struct inode *inode, struct file *file)
-{
- struct snd_monitor_file *df = NULL, *_df;
-
- spin_lock(&shutdown_lock);
- list_for_each_entry(_df, &shutdown_files, shutdown_list) {
- if (_df->file == file) {
- df = _df;
- list_del_init(&df->shutdown_list);
- break;
- }
- }
- spin_unlock(&shutdown_lock);
-
- if (likely(df)) {
- if ((file->f_flags & FASYNC) && df->disconnected_f_op->fasync)
- df->disconnected_f_op->fasync(-1, file, 0);
- return df->disconnected_f_op->release(inode, file);
- }
-
- panic("%s(%p, %p) failed!", __func__, inode, file);
-}
-
-static unsigned int snd_disconnect_poll(struct file * file, poll_table * wait)
-{
- return POLLERR | POLLNVAL;
-}
-
-static long snd_disconnect_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- return -ENODEV;
-}
-
-static int snd_disconnect_mmap(struct file *file, struct vm_area_struct *vma)
-{
- return -ENODEV;
-}
-
-static int snd_disconnect_fasync(int fd, struct file *file, int on)
-{
- return -ENODEV;
-}
-
-static const struct file_operations snd_shutdown_f_ops =
-{
- .owner = THIS_MODULE,
- .llseek = snd_disconnect_llseek,
- .read = snd_disconnect_read,
- .write = snd_disconnect_write,
- .release = snd_disconnect_release,
- .poll = snd_disconnect_poll,
- .unlocked_ioctl = snd_disconnect_ioctl,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = snd_disconnect_ioctl,
-#endif
- .mmap = snd_disconnect_mmap,
- .fasync = snd_disconnect_fasync
-};
-
-/**
- * snd_card_disconnect - disconnect all APIs from the file-operations (user space)
- * @card: soundcard structure
- *
- * Disconnects all APIs from the file-operations (user space).
- *
- * Returns zero, otherwise a negative error code.
- *
- * Note: The current implementation replaces all active file->f_op with special
- * dummy file operations (they do nothing except release).
- */
-int snd_card_disconnect(struct snd_card *card)
-{
- struct snd_monitor_file *mfile;
- int err;
-
- if (!card)
- return -EINVAL;
-
- spin_lock(&card->files_lock);
- if (card->shutdown) {
- spin_unlock(&card->files_lock);
- return 0;
- }
- card->shutdown = 1;
- spin_unlock(&card->files_lock);
-
- /* phase 1: disable fops (user space) operations for ALSA API */
- mutex_lock(&snd_card_mutex);
- snd_cards[card->number] = NULL;
- snd_cards_lock &= ~(1 << card->number);
- mutex_unlock(&snd_card_mutex);
-
- /* phase 2: replace file->f_op with special dummy operations */
-
- spin_lock(&card->files_lock);
- list_for_each_entry(mfile, &card->files_list, list) {
- /* it's critical part, use endless loop */
- /* we have no room to fail */
- mfile->disconnected_f_op = mfile->file->f_op;
-
- spin_lock(&shutdown_lock);
- list_add(&mfile->shutdown_list, &shutdown_files);
- spin_unlock(&shutdown_lock);
-
- mfile->file->f_op = &snd_shutdown_f_ops;
- fops_get(mfile->file->f_op);
- }
- spin_unlock(&card->files_lock);
-
- /* phase 3: notify all connected devices about disconnection */
- /* at this point, they cannot respond to any calls except release() */
-
-#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
- if (snd_mixer_oss_notify_callback)
- snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_DISCONNECT);
-#endif
-
- /* notify all devices that we are disconnected */
- err = snd_device_disconnect_all(card);
- if (err < 0)
- snd_printk(KERN_ERR "not all devices for card %i can be disconnected\n", card->number);
-
- snd_info_card_disconnect(card);
- if (card->card_dev) {
- device_unregister(card->card_dev);
- card->card_dev = NULL;
- }
-#ifdef CONFIG_PM
- wake_up(&card->power_sleep);
-#endif
- return 0;
-}
-
-EXPORT_SYMBOL(snd_card_disconnect);
-
-/**
- * snd_card_free - frees given soundcard structure
- * @card: soundcard structure
- *
- * This function releases the soundcard structure and the all assigned
- * devices automatically. That is, you don't have to release the devices
- * by yourself.
- *
- * Returns zero. Frees all associated devices and frees the control
- * interface associated to given soundcard.
- */
-static int snd_card_do_free(struct snd_card *card)
-{
-#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
- if (snd_mixer_oss_notify_callback)
- snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_FREE);
-#endif
- if (snd_device_free_all(card, SNDRV_DEV_CMD_PRE) < 0) {
- snd_printk(KERN_ERR "unable to free all devices (pre)\n");
- /* Fatal, but this situation should never occur */
- }
- if (snd_device_free_all(card, SNDRV_DEV_CMD_NORMAL) < 0) {
- snd_printk(KERN_ERR "unable to free all devices (normal)\n");
- /* Fatal, but this situation should never occur */
- }
- if (snd_device_free_all(card, SNDRV_DEV_CMD_POST) < 0) {
- snd_printk(KERN_ERR "unable to free all devices (post)\n");
- /* Fatal, but this situation should never occur */
- }
- if (card->private_free)
- card->private_free(card);
- snd_info_free_entry(card->proc_id);
- if (snd_info_card_free(card) < 0) {
- snd_printk(KERN_WARNING "unable to free card info\n");
- /* Not fatal error */
- }
- kfree(card);
- return 0;
-}
-
-/**
- * snd_card_unref - release the reference counter
- * @card: the card instance
- *
- * Decrements the reference counter. When it reaches to zero, wake up
- * the sleeper and call the destructor if needed.
- */
-void snd_card_unref(struct snd_card *card)
-{
- if (atomic_dec_and_test(&card->refcount)) {
- wake_up(&card->shutdown_sleep);
- if (card->free_on_last_close)
- snd_card_do_free(card);
- }
-}
-EXPORT_SYMBOL(snd_card_unref);
-
-int snd_card_free_when_closed(struct snd_card *card)
-{
- int ret;
-
- atomic_inc(&card->refcount);
- ret = snd_card_disconnect(card);
- if (ret) {
- atomic_dec(&card->refcount);
- return ret;
- }
-
- card->free_on_last_close = 1;
- if (atomic_dec_and_test(&card->refcount))
- snd_card_do_free(card);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_card_free_when_closed);
-
-int snd_card_free(struct snd_card *card)
-{
- int ret = snd_card_disconnect(card);
- if (ret)
- return ret;
-
- /* wait, until all devices are ready for the free operation */
- wait_event(card->shutdown_sleep, !atomic_read(&card->refcount));
- snd_card_do_free(card);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_card_free);
-
-/* retrieve the last word of shortname or longname */
-static const char *retrieve_id_from_card_name(const char *name)
-{
- const char *spos = name;
-
- while (*name) {
- if (isspace(*name) && isalnum(name[1]))
- spos = name + 1;
- name++;
- }
- return spos;
-}
-
-/* return true if the given id string doesn't conflict any other card ids */
-static bool card_id_ok(struct snd_card *card, const char *id)
-{
- int i;
- if (!snd_info_check_reserved_words(id))
- return false;
- for (i = 0; i < snd_ecards_limit; i++) {
- if (snd_cards[i] && snd_cards[i] != card &&
- !strcmp(snd_cards[i]->id, id))
- return false;
- }
- return true;
-}
-
-/* copy to card->id only with valid letters from nid */
-static void copy_valid_id_string(struct snd_card *card, const char *src,
- const char *nid)
-{
- char *id = card->id;
-
- while (*nid && !isalnum(*nid))
- nid++;
- if (isdigit(*nid))
- *id++ = isalpha(*src) ? *src : 'D';
- while (*nid && (size_t)(id - card->id) < sizeof(card->id) - 1) {
- if (isalnum(*nid))
- *id++ = *nid;
- nid++;
- }
- *id = 0;
-}
-
-/* Set card->id from the given string
- * If the string conflicts with other ids, add a suffix to make it unique.
- */
-static void snd_card_set_id_no_lock(struct snd_card *card, const char *src,
- const char *nid)
-{
- int len, loops;
- bool with_suffix;
- bool is_default = false;
- char *id;
-
- copy_valid_id_string(card, src, nid);
- id = card->id;
-
- again:
- /* use "Default" for obviously invalid strings
- * ("card" conflicts with proc directories)
- */
- if (!*id || !strncmp(id, "card", 4)) {
- strcpy(id, "Default");
- is_default = true;
- }
-
- with_suffix = false;
- for (loops = 0; loops < SNDRV_CARDS; loops++) {
- if (card_id_ok(card, id))
- return; /* OK */
-
- len = strlen(id);
- if (!with_suffix) {
- /* add the "_X" suffix */
- char *spos = id + len;
- if (len > sizeof(card->id) - 3)
- spos = id + sizeof(card->id) - 3;
- strcpy(spos, "_1");
- with_suffix = true;
- } else {
- /* modify the existing suffix */
- if (id[len - 1] != '9')
- id[len - 1]++;
- else
- id[len - 1] = 'A';
- }
- }
- /* fallback to the default id */
- if (!is_default) {
- *id = 0;
- goto again;
- }
- /* last resort... */
- snd_printk(KERN_ERR "unable to set card id (%s)\n", id);
- if (card->proc_root->name)
- strcpy(card->id, card->proc_root->name);
-}
-
-/**
- * snd_card_set_id - set card identification name
- * @card: soundcard structure
- * @nid: new identification string
- *
- * This function sets the card identification and checks for name
- * collisions.
- */
-void snd_card_set_id(struct snd_card *card, const char *nid)
-{
- /* check if user specified own card->id */
- if (card->id[0] != '\0')
- return;
- mutex_lock(&snd_card_mutex);
- snd_card_set_id_no_lock(card, nid, nid);
- mutex_unlock(&snd_card_mutex);
-}
-EXPORT_SYMBOL(snd_card_set_id);
-
-static ssize_t
-card_id_show_attr(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct snd_card *card = dev_get_drvdata(dev);
- return snprintf(buf, PAGE_SIZE, "%s\n", card ? card->id : "(null)");
-}
-
-static ssize_t
-card_id_store_attr(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct snd_card *card = dev_get_drvdata(dev);
- char buf1[sizeof(card->id)];
- size_t copy = count > sizeof(card->id) - 1 ?
- sizeof(card->id) - 1 : count;
- size_t idx;
- int c;
-
- for (idx = 0; idx < copy; idx++) {
- c = buf[idx];
- if (!isalnum(c) && c != '_' && c != '-')
- return -EINVAL;
- }
- memcpy(buf1, buf, copy);
- buf1[copy] = '\0';
- mutex_lock(&snd_card_mutex);
- if (!card_id_ok(NULL, buf1)) {
- mutex_unlock(&snd_card_mutex);
- return -EEXIST;
- }
- strcpy(card->id, buf1);
- snd_info_card_id_change(card);
- mutex_unlock(&snd_card_mutex);
-
- return count;
-}
-
-static struct device_attribute card_id_attrs =
- __ATTR(id, S_IRUGO | S_IWUSR, card_id_show_attr, card_id_store_attr);
-
-static ssize_t
-card_number_show_attr(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct snd_card *card = dev_get_drvdata(dev);
- return snprintf(buf, PAGE_SIZE, "%i\n", card ? card->number : -1);
-}
-
-static struct device_attribute card_number_attrs =
- __ATTR(number, S_IRUGO, card_number_show_attr, NULL);
-
-/**
- * snd_card_register - register the soundcard
- * @card: soundcard structure
- *
- * This function registers all the devices assigned to the soundcard.
- * Until calling this, the ALSA control interface is blocked from the
- * external accesses. Thus, you should call this function at the end
- * of the initialization of the card.
- *
- * Returns zero otherwise a negative error code if the registration failed.
- */
-int snd_card_register(struct snd_card *card)
-{
- int err;
-
- if (snd_BUG_ON(!card))
- return -EINVAL;
-
- if (!card->card_dev) {
- card->card_dev = device_create(sound_class, card->dev,
- MKDEV(0, 0), card,
- "card%i", card->number);
- if (IS_ERR(card->card_dev))
- card->card_dev = NULL;
- }
-
- if ((err = snd_device_register_all(card)) < 0)
- return err;
- mutex_lock(&snd_card_mutex);
- if (snd_cards[card->number]) {
- /* already registered */
- mutex_unlock(&snd_card_mutex);
- return 0;
- }
- if (*card->id) {
- /* make a unique id name from the given string */
- char tmpid[sizeof(card->id)];
- memcpy(tmpid, card->id, sizeof(card->id));
- snd_card_set_id_no_lock(card, tmpid, tmpid);
- } else {
- /* create an id from either shortname or longname */
- const char *src;
- src = *card->shortname ? card->shortname : card->longname;
- snd_card_set_id_no_lock(card, src,
- retrieve_id_from_card_name(src));
- }
- snd_cards[card->number] = card;
- mutex_unlock(&snd_card_mutex);
- init_info_for_card(card);
-#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
- if (snd_mixer_oss_notify_callback)
- snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER);
-#endif
- if (card->card_dev) {
- err = device_create_file(card->card_dev, &card_id_attrs);
- if (err < 0)
- return err;
- err = device_create_file(card->card_dev, &card_number_attrs);
- if (err < 0)
- return err;
- }
-
- return 0;
-}
-
-EXPORT_SYMBOL(snd_card_register);
-
-#ifdef CONFIG_PROC_FS
-static struct snd_info_entry *snd_card_info_entry;
-
-static void snd_card_info_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- int idx, count;
- struct snd_card *card;
-
- for (idx = count = 0; idx < SNDRV_CARDS; idx++) {
- mutex_lock(&snd_card_mutex);
- if ((card = snd_cards[idx]) != NULL) {
- count++;
- snd_iprintf(buffer, "%2i [%-15s]: %s - %s\n",
- idx,
- card->id,
- card->driver,
- card->shortname);
- snd_iprintf(buffer, " %s\n",
- card->longname);
- }
- mutex_unlock(&snd_card_mutex);
- }
- if (!count)
- snd_iprintf(buffer, "--- no soundcards ---\n");
-}
-
-#ifdef CONFIG_SND_OSSEMUL
-
-void snd_card_info_read_oss(struct snd_info_buffer *buffer)
-{
- int idx, count;
- struct snd_card *card;
-
- for (idx = count = 0; idx < SNDRV_CARDS; idx++) {
- mutex_lock(&snd_card_mutex);
- if ((card = snd_cards[idx]) != NULL) {
- count++;
- snd_iprintf(buffer, "%s\n", card->longname);
- }
- mutex_unlock(&snd_card_mutex);
- }
- if (!count) {
- snd_iprintf(buffer, "--- no soundcards ---\n");
- }
-}
-
-#endif
-
-#ifdef MODULE
-static struct snd_info_entry *snd_card_module_info_entry;
-static void snd_card_module_info_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- int idx;
- struct snd_card *card;
-
- for (idx = 0; idx < SNDRV_CARDS; idx++) {
- mutex_lock(&snd_card_mutex);
- if ((card = snd_cards[idx]) != NULL)
- snd_iprintf(buffer, "%2i %s\n",
- idx, card->module->name);
- mutex_unlock(&snd_card_mutex);
- }
-}
-#endif
-
-int __init snd_card_info_init(void)
-{
- struct snd_info_entry *entry;
-
- entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL);
- if (! entry)
- return -ENOMEM;
- entry->c.text.read = snd_card_info_read;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- return -ENOMEM;
- }
- snd_card_info_entry = entry;
-
-#ifdef MODULE
- entry = snd_info_create_module_entry(THIS_MODULE, "modules", NULL);
- if (entry) {
- entry->c.text.read = snd_card_module_info_read;
- if (snd_info_register(entry) < 0)
- snd_info_free_entry(entry);
- else
- snd_card_module_info_entry = entry;
- }
-#endif
-
- return 0;
-}
-
-int __exit snd_card_info_done(void)
-{
- snd_info_free_entry(snd_card_info_entry);
-#ifdef MODULE
- snd_info_free_entry(snd_card_module_info_entry);
-#endif
- return 0;
-}
-
-#endif /* CONFIG_PROC_FS */
-
-/**
- * snd_component_add - add a component string
- * @card: soundcard structure
- * @component: the component id string
- *
- * This function adds the component id string to the supported list.
- * The component can be referred from the alsa-lib.
- *
- * Returns zero otherwise a negative error code.
- */
-
-int snd_component_add(struct snd_card *card, const char *component)
-{
- char *ptr;
- int len = strlen(component);
-
- ptr = strstr(card->components, component);
- if (ptr != NULL) {
- if (ptr[len] == '\0' || ptr[len] == ' ') /* already there */
- return 1;
- }
- if (strlen(card->components) + 1 + len + 1 > sizeof(card->components)) {
- snd_BUG();
- return -ENOMEM;
- }
- if (card->components[0] != '\0')
- strcat(card->components, " ");
- strcat(card->components, component);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_component_add);
-
-/**
- * snd_card_file_add - add the file to the file list of the card
- * @card: soundcard structure
- * @file: file pointer
- *
- * This function adds the file to the file linked-list of the card.
- * This linked-list is used to keep tracking the connection state,
- * and to avoid the release of busy resources by hotplug.
- *
- * Returns zero or a negative error code.
- */
-int snd_card_file_add(struct snd_card *card, struct file *file)
-{
- struct snd_monitor_file *mfile;
-
- mfile = kmalloc(sizeof(*mfile), GFP_KERNEL);
- if (mfile == NULL)
- return -ENOMEM;
- mfile->file = file;
- mfile->disconnected_f_op = NULL;
- INIT_LIST_HEAD(&mfile->shutdown_list);
- spin_lock(&card->files_lock);
- if (card->shutdown) {
- spin_unlock(&card->files_lock);
- kfree(mfile);
- return -ENODEV;
- }
- list_add(&mfile->list, &card->files_list);
- atomic_inc(&card->refcount);
- spin_unlock(&card->files_lock);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_card_file_add);
-
-/**
- * snd_card_file_remove - remove the file from the file list
- * @card: soundcard structure
- * @file: file pointer
- *
- * This function removes the file formerly added to the card via
- * snd_card_file_add() function.
- * If all files are removed and snd_card_free_when_closed() was
- * called beforehand, it processes the pending release of
- * resources.
- *
- * Returns zero or a negative error code.
- */
-int snd_card_file_remove(struct snd_card *card, struct file *file)
-{
- struct snd_monitor_file *mfile, *found = NULL;
-
- spin_lock(&card->files_lock);
- list_for_each_entry(mfile, &card->files_list, list) {
- if (mfile->file == file) {
- list_del(&mfile->list);
- spin_lock(&shutdown_lock);
- list_del(&mfile->shutdown_list);
- spin_unlock(&shutdown_lock);
- if (mfile->disconnected_f_op)
- fops_put(mfile->disconnected_f_op);
- found = mfile;
- break;
- }
- }
- spin_unlock(&card->files_lock);
- if (!found) {
- snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file);
- return -ENOENT;
- }
- kfree(found);
- snd_card_unref(card);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_card_file_remove);
-
-#ifdef CONFIG_PM
-/**
- * snd_power_wait - wait until the power-state is changed.
- * @card: soundcard structure
- * @power_state: expected power state
- *
- * Waits until the power-state is changed.
- *
- * Note: the power lock must be active before call.
- */
-int snd_power_wait(struct snd_card *card, unsigned int power_state)
-{
- wait_queue_t wait;
- int result = 0;
-
- /* fastpath */
- if (snd_power_get_state(card) == power_state)
- return 0;
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&card->power_sleep, &wait);
- while (1) {
- if (card->shutdown) {
- result = -ENODEV;
- break;
- }
- if (snd_power_get_state(card) == power_state)
- break;
- set_current_state(TASK_UNINTERRUPTIBLE);
- snd_power_unlock(card);
- schedule_timeout(30 * HZ);
- snd_power_lock(card);
- }
- remove_wait_queue(&card->power_sleep, &wait);
- return result;
-}
-
-EXPORT_SYMBOL(snd_power_wait);
-#endif /* CONFIG_PM */
diff --git a/ANDROID_3.4.5/sound/core/isadma.c b/ANDROID_3.4.5/sound/core/isadma.c
deleted file mode 100644
index c0f1208b..00000000
--- a/ANDROID_3.4.5/sound/core/isadma.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * ISA DMA support functions
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- * Defining following add some delay. Maybe this helps for some broken
- * ISA DMA controllers.
- */
-
-#undef HAVE_REALLY_SLOW_DMA_CONTROLLER
-
-#include <linux/export.h>
-#include <sound/core.h>
-#include <asm/dma.h>
-
-/**
- * snd_dma_program - program an ISA DMA transfer
- * @dma: the dma number
- * @addr: the physical address of the buffer
- * @size: the DMA transfer size
- * @mode: the DMA transfer mode, DMA_MODE_XXX
- *
- * Programs an ISA DMA transfer for the given buffer.
- */
-void snd_dma_program(unsigned long dma,
- unsigned long addr, unsigned int size,
- unsigned short mode)
-{
- unsigned long flags;
-
- flags = claim_dma_lock();
- disable_dma(dma);
- clear_dma_ff(dma);
- set_dma_mode(dma, mode);
- set_dma_addr(dma, addr);
- set_dma_count(dma, size);
- if (!(mode & DMA_MODE_NO_ENABLE))
- enable_dma(dma);
- release_dma_lock(flags);
-}
-
-EXPORT_SYMBOL(snd_dma_program);
-
-/**
- * snd_dma_disable - stop the ISA DMA transfer
- * @dma: the dma number
- *
- * Stops the ISA DMA transfer.
- */
-void snd_dma_disable(unsigned long dma)
-{
- unsigned long flags;
-
- flags = claim_dma_lock();
- clear_dma_ff(dma);
- disable_dma(dma);
- release_dma_lock(flags);
-}
-
-EXPORT_SYMBOL(snd_dma_disable);
-
-/**
- * snd_dma_pointer - return the current pointer to DMA transfer buffer in bytes
- * @dma: the dma number
- * @size: the dma transfer size
- *
- * Returns the current pointer in DMA tranfer buffer in bytes
- */
-unsigned int snd_dma_pointer(unsigned long dma, unsigned int size)
-{
- unsigned long flags;
- unsigned int result, result1;
-
- flags = claim_dma_lock();
- clear_dma_ff(dma);
- if (!isa_dma_bridge_buggy)
- disable_dma(dma);
- result = get_dma_residue(dma);
- /*
- * HACK - read the counter again and choose higher value in order to
- * avoid reading during counter lower byte roll over if the
- * isa_dma_bridge_buggy is set.
- */
- result1 = get_dma_residue(dma);
- if (!isa_dma_bridge_buggy)
- enable_dma(dma);
- release_dma_lock(flags);
- if (unlikely(result < result1))
- result = result1;
-#ifdef CONFIG_SND_DEBUG
- if (result > size)
- snd_printk(KERN_ERR "pointer (0x%x) for DMA #%ld is greater than transfer size (0x%x)\n", result, dma, size);
-#endif
- if (result >= size || result == 0)
- return 0;
- else
- return size - result;
-}
-
-EXPORT_SYMBOL(snd_dma_pointer);
diff --git a/ANDROID_3.4.5/sound/core/jack.c b/ANDROID_3.4.5/sound/core/jack.c
deleted file mode 100644
index 471e1e3b..00000000
--- a/ANDROID_3.4.5/sound/core/jack.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Jack abstraction layer
- *
- * Copyright 2008 Wolfson Microelectronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/input.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/jack.h>
-#include <sound/core.h>
-
-static int jack_switch_types[SND_JACK_SWITCH_TYPES] = {
- SW_HEADPHONE_INSERT,
- SW_MICROPHONE_INSERT,
- SW_LINEOUT_INSERT,
- SW_JACK_PHYSICAL_INSERT,
- SW_VIDEOOUT_INSERT,
- SW_LINEIN_INSERT,
-};
-
-static int snd_jack_dev_free(struct snd_device *device)
-{
- struct snd_jack *jack = device->device_data;
-
- if (jack->private_free)
- jack->private_free(jack);
-
- /* If the input device is registered with the input subsystem
- * then we need to use a different deallocator. */
- if (jack->registered)
- input_unregister_device(jack->input_dev);
- else
- input_free_device(jack->input_dev);
-
- kfree(jack->id);
- kfree(jack);
-
- return 0;
-}
-
-static int snd_jack_dev_register(struct snd_device *device)
-{
- struct snd_jack *jack = device->device_data;
- struct snd_card *card = device->card;
- int err, i;
-
- snprintf(jack->name, sizeof(jack->name), "%s %s",
- card->shortname, jack->id);
- jack->input_dev->name = jack->name;
-
- /* Default to the sound card device. */
- if (!jack->input_dev->dev.parent)
- jack->input_dev->dev.parent = snd_card_get_device_link(card);
-
- /* Add capabilities for any keys that are enabled */
- for (i = 0; i < ARRAY_SIZE(jack->key); i++) {
- int testbit = SND_JACK_BTN_0 >> i;
-
- if (!(jack->type & testbit))
- continue;
-
- if (!jack->key[i])
- jack->key[i] = BTN_0 + i;
-
- input_set_capability(jack->input_dev, EV_KEY, jack->key[i]);
- }
-
- err = input_register_device(jack->input_dev);
- if (err == 0)
- jack->registered = 1;
-
- return err;
-}
-
-/**
- * snd_jack_new - Create a new jack
- * @card: the card instance
- * @id: an identifying string for this jack
- * @type: a bitmask of enum snd_jack_type values that can be detected by
- * this jack
- * @jjack: Used to provide the allocated jack object to the caller.
- *
- * Creates a new jack object.
- *
- * Returns zero if successful, or a negative error code on failure.
- * On success jjack will be initialised.
- */
-int snd_jack_new(struct snd_card *card, const char *id, int type,
- struct snd_jack **jjack)
-{
- struct snd_jack *jack;
- int err;
- int i;
- static struct snd_device_ops ops = {
- .dev_free = snd_jack_dev_free,
- .dev_register = snd_jack_dev_register,
- };
-
- jack = kzalloc(sizeof(struct snd_jack), GFP_KERNEL);
- if (jack == NULL)
- return -ENOMEM;
-
- jack->id = kstrdup(id, GFP_KERNEL);
-
- jack->input_dev = input_allocate_device();
- if (jack->input_dev == NULL) {
- err = -ENOMEM;
- goto fail_input;
- }
-
- jack->input_dev->phys = "ALSA";
-
- jack->type = type;
-
- for (i = 0; i < SND_JACK_SWITCH_TYPES; i++)
- if (type & (1 << i))
- input_set_capability(jack->input_dev, EV_SW,
- jack_switch_types[i]);
-
- err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops);
- if (err < 0)
- goto fail_input;
-
- *jjack = jack;
-
- return 0;
-
-fail_input:
- input_free_device(jack->input_dev);
- kfree(jack->id);
- kfree(jack);
- return err;
-}
-EXPORT_SYMBOL(snd_jack_new);
-
-/**
- * snd_jack_set_parent - Set the parent device for a jack
- *
- * @jack: The jack to configure
- * @parent: The device to set as parent for the jack.
- *
- * Set the parent for the jack input device in the device tree. This
- * function is only valid prior to registration of the jack. If no
- * parent is configured then the parent device will be the sound card.
- */
-void snd_jack_set_parent(struct snd_jack *jack, struct device *parent)
-{
- WARN_ON(jack->registered);
-
- jack->input_dev->dev.parent = parent;
-}
-EXPORT_SYMBOL(snd_jack_set_parent);
-
-/**
- * snd_jack_set_key - Set a key mapping on a jack
- *
- * @jack: The jack to configure
- * @type: Jack report type for this key
- * @keytype: Input layer key type to be reported
- *
- * Map a SND_JACK_BTN_ button type to an input layer key, allowing
- * reporting of keys on accessories via the jack abstraction. If no
- * mapping is provided but keys are enabled in the jack type then
- * BTN_n numeric buttons will be reported.
- *
- * Note that this is intended to be use by simple devices with small
- * numbers of keys that can be reported. It is also possible to
- * access the input device directly - devices with complex input
- * capabilities on accessories should consider doing this rather than
- * using this abstraction.
- *
- * This function may only be called prior to registration of the jack.
- */
-int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type,
- int keytype)
-{
- int key = fls(SND_JACK_BTN_0) - fls(type);
-
- WARN_ON(jack->registered);
-
- if (!keytype || key >= ARRAY_SIZE(jack->key))
- return -EINVAL;
-
- jack->type |= type;
- jack->key[key] = keytype;
-
- return 0;
-}
-EXPORT_SYMBOL(snd_jack_set_key);
-
-/**
- * snd_jack_report - Report the current status of a jack
- *
- * @jack: The jack to report status for
- * @status: The current status of the jack
- */
-void snd_jack_report(struct snd_jack *jack, int status)
-{
- int i;
-
- if (!jack)
- return;
-
- for (i = 0; i < ARRAY_SIZE(jack->key); i++) {
- int testbit = SND_JACK_BTN_0 >> i;
-
- if (jack->type & testbit)
- input_report_key(jack->input_dev, jack->key[i],
- status & testbit);
- }
-
- for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) {
- int testbit = 1 << i;
- if (jack->type & testbit)
- input_report_switch(jack->input_dev,
- jack_switch_types[i],
- status & testbit);
- }
-
- input_sync(jack->input_dev);
-}
-EXPORT_SYMBOL(snd_jack_report);
-
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_DESCRIPTION("Jack detection support for ALSA");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/core/memalloc.c b/ANDROID_3.4.5/sound/core/memalloc.c
deleted file mode 100644
index 69156923..00000000
--- a/ANDROID_3.4.5/sound/core/memalloc.c
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Takashi Iwai <tiwai@suse.de>
- *
- * Generic memory allocators
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/module.h>
-#include <linux/proc_fs.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/seq_file.h>
-#include <asm/uaccess.h>
-#include <linux/dma-mapping.h>
-#include <linux/moduleparam.h>
-#include <linux/mutex.h>
-#include <sound/memalloc.h>
-
-
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>, Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Memory allocator for ALSA system.");
-MODULE_LICENSE("GPL");
-
-
-/*
- */
-
-static DEFINE_MUTEX(list_mutex);
-static LIST_HEAD(mem_list_head);
-
-/* buffer preservation list */
-struct snd_mem_list {
- struct snd_dma_buffer buffer;
- unsigned int id;
- struct list_head list;
-};
-
-/* id for pre-allocated buffers */
-#define SNDRV_DMA_DEVICE_UNUSED (unsigned int)-1
-
-/*
- *
- * Generic memory allocators
- *
- */
-
-static long snd_allocated_pages; /* holding the number of allocated pages */
-
-static inline void inc_snd_pages(int order)
-{
- snd_allocated_pages += 1 << order;
-}
-
-static inline void dec_snd_pages(int order)
-{
- snd_allocated_pages -= 1 << order;
-}
-
-/**
- * snd_malloc_pages - allocate pages with the given size
- * @size: the size to allocate in bytes
- * @gfp_flags: the allocation conditions, GFP_XXX
- *
- * Allocates the physically contiguous pages with the given size.
- *
- * Returns the pointer of the buffer, or NULL if no enoguh memory.
- */
-void *snd_malloc_pages(size_t size, gfp_t gfp_flags)
-{
- int pg;
- void *res;
-
- if (WARN_ON(!size))
- return NULL;
- if (WARN_ON(!gfp_flags))
- return NULL;
- gfp_flags |= __GFP_COMP; /* compound page lets parts be mapped */
- pg = get_order(size);
- if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL)
- inc_snd_pages(pg);
- return res;
-}
-
-/**
- * snd_free_pages - release the pages
- * @ptr: the buffer pointer to release
- * @size: the allocated buffer size
- *
- * Releases the buffer allocated via snd_malloc_pages().
- */
-void snd_free_pages(void *ptr, size_t size)
-{
- int pg;
-
- if (ptr == NULL)
- return;
- pg = get_order(size);
- dec_snd_pages(pg);
- free_pages((unsigned long) ptr, pg);
-}
-
-/*
- *
- * Bus-specific memory allocators
- *
- */
-
-#ifdef CONFIG_HAS_DMA
-/* allocate the coherent DMA pages */
-static void *snd_malloc_dev_pages(struct device *dev, size_t size, dma_addr_t *dma)
-{
- int pg;
- void *res;
- gfp_t gfp_flags;
-
- if (WARN_ON(!dma))
- return NULL;
- pg = get_order(size);
- gfp_flags = GFP_KERNEL
- | __GFP_COMP /* compound page lets parts be mapped */
- | __GFP_NORETRY /* don't trigger OOM-killer */
- | __GFP_NOWARN; /* no stack trace print - this call is non-critical */
- res = dma_alloc_coherent(dev, PAGE_SIZE << pg, dma, gfp_flags);
- if (res != NULL)
- inc_snd_pages(pg);
-
- return res;
-}
-
-/* free the coherent DMA pages */
-static void snd_free_dev_pages(struct device *dev, size_t size, void *ptr,
- dma_addr_t dma)
-{
- int pg;
-
- if (ptr == NULL)
- return;
- pg = get_order(size);
- dec_snd_pages(pg);
- dma_free_coherent(dev, PAGE_SIZE << pg, ptr, dma);
-}
-#endif /* CONFIG_HAS_DMA */
-
-/*
- *
- * ALSA generic memory management
- *
- */
-
-
-/**
- * snd_dma_alloc_pages - allocate the buffer area according to the given type
- * @type: the DMA buffer type
- * @device: the device pointer
- * @size: the buffer size to allocate
- * @dmab: buffer allocation record to store the allocated data
- *
- * Calls the memory-allocator function for the corresponding
- * buffer type.
- *
- * Returns zero if the buffer with the given size is allocated successfully,
- * other a negative value at error.
- */
-int snd_dma_alloc_pages(int type, struct device *device, size_t size,
- struct snd_dma_buffer *dmab)
-{
- if (WARN_ON(!size))
- return -ENXIO;
- if (WARN_ON(!dmab))
- return -ENXIO;
-
- dmab->dev.type = type;
- dmab->dev.dev = device;
- dmab->bytes = 0;
- switch (type) {
- case SNDRV_DMA_TYPE_CONTINUOUS:
- dmab->area = snd_malloc_pages(size,
- (__force gfp_t)(unsigned long)device);
- dmab->addr = 0;
- break;
-#ifdef CONFIG_HAS_DMA
- case SNDRV_DMA_TYPE_DEV:
- dmab->area = snd_malloc_dev_pages(device, size, &dmab->addr);
- break;
-#endif
-#ifdef CONFIG_SND_DMA_SGBUF
- case SNDRV_DMA_TYPE_DEV_SG:
- snd_malloc_sgbuf_pages(device, size, dmab, NULL);
- break;
-#endif
- default:
- printk(KERN_ERR "snd-malloc: invalid device type %d\n", type);
- dmab->area = NULL;
- dmab->addr = 0;
- return -ENXIO;
- }
- if (! dmab->area)
- return -ENOMEM;
- dmab->bytes = size;
- return 0;
-}
-
-/**
- * snd_dma_alloc_pages_fallback - allocate the buffer area according to the given type with fallback
- * @type: the DMA buffer type
- * @device: the device pointer
- * @size: the buffer size to allocate
- * @dmab: buffer allocation record to store the allocated data
- *
- * Calls the memory-allocator function for the corresponding
- * buffer type. When no space is left, this function reduces the size and
- * tries to allocate again. The size actually allocated is stored in
- * res_size argument.
- *
- * Returns zero if the buffer with the given size is allocated successfully,
- * other a negative value at error.
- */
-int snd_dma_alloc_pages_fallback(int type, struct device *device, size_t size,
- struct snd_dma_buffer *dmab)
-{
- int err;
-
- while ((err = snd_dma_alloc_pages(type, device, size, dmab)) < 0) {
- size_t aligned_size;
- if (err != -ENOMEM)
- return err;
- if (size <= PAGE_SIZE)
- return -ENOMEM;
- aligned_size = PAGE_SIZE << get_order(size);
- if (size != aligned_size)
- size = aligned_size;
- else
- size >>= 1;
- }
- if (! dmab->area)
- return -ENOMEM;
- return 0;
-}
-
-
-/**
- * snd_dma_free_pages - release the allocated buffer
- * @dmab: the buffer allocation record to release
- *
- * Releases the allocated buffer via snd_dma_alloc_pages().
- */
-void snd_dma_free_pages(struct snd_dma_buffer *dmab)
-{
- switch (dmab->dev.type) {
- case SNDRV_DMA_TYPE_CONTINUOUS:
- snd_free_pages(dmab->area, dmab->bytes);
- break;
-#ifdef CONFIG_HAS_DMA
- case SNDRV_DMA_TYPE_DEV:
- snd_free_dev_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr);
- break;
-#endif
-#ifdef CONFIG_SND_DMA_SGBUF
- case SNDRV_DMA_TYPE_DEV_SG:
- snd_free_sgbuf_pages(dmab);
- break;
-#endif
- default:
- printk(KERN_ERR "snd-malloc: invalid device type %d\n", dmab->dev.type);
- }
-}
-
-
-/**
- * snd_dma_get_reserved - get the reserved buffer for the given device
- * @dmab: the buffer allocation record to store
- * @id: the buffer id
- *
- * Looks for the reserved-buffer list and re-uses if the same buffer
- * is found in the list. When the buffer is found, it's removed from the free list.
- *
- * Returns the size of buffer if the buffer is found, or zero if not found.
- */
-size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id)
-{
- struct snd_mem_list *mem;
-
- if (WARN_ON(!dmab))
- return 0;
-
- mutex_lock(&list_mutex);
- list_for_each_entry(mem, &mem_list_head, list) {
- if (mem->id == id &&
- (mem->buffer.dev.dev == NULL || dmab->dev.dev == NULL ||
- ! memcmp(&mem->buffer.dev, &dmab->dev, sizeof(dmab->dev)))) {
- struct device *dev = dmab->dev.dev;
- list_del(&mem->list);
- *dmab = mem->buffer;
- if (dmab->dev.dev == NULL)
- dmab->dev.dev = dev;
- kfree(mem);
- mutex_unlock(&list_mutex);
- return dmab->bytes;
- }
- }
- mutex_unlock(&list_mutex);
- return 0;
-}
-
-/**
- * snd_dma_reserve_buf - reserve the buffer
- * @dmab: the buffer to reserve
- * @id: the buffer id
- *
- * Reserves the given buffer as a reserved buffer.
- *
- * Returns zero if successful, or a negative code at error.
- */
-int snd_dma_reserve_buf(struct snd_dma_buffer *dmab, unsigned int id)
-{
- struct snd_mem_list *mem;
-
- if (WARN_ON(!dmab))
- return -EINVAL;
- mem = kmalloc(sizeof(*mem), GFP_KERNEL);
- if (! mem)
- return -ENOMEM;
- mutex_lock(&list_mutex);
- mem->buffer = *dmab;
- mem->id = id;
- list_add_tail(&mem->list, &mem_list_head);
- mutex_unlock(&list_mutex);
- return 0;
-}
-
-/*
- * purge all reserved buffers
- */
-static void free_all_reserved_pages(void)
-{
- struct list_head *p;
- struct snd_mem_list *mem;
-
- mutex_lock(&list_mutex);
- while (! list_empty(&mem_list_head)) {
- p = mem_list_head.next;
- mem = list_entry(p, struct snd_mem_list, list);
- list_del(p);
- snd_dma_free_pages(&mem->buffer);
- kfree(mem);
- }
- mutex_unlock(&list_mutex);
-}
-
-
-#ifdef CONFIG_PROC_FS
-/*
- * proc file interface
- */
-#define SND_MEM_PROC_FILE "driver/snd-page-alloc"
-static struct proc_dir_entry *snd_mem_proc;
-
-static int snd_mem_proc_read(struct seq_file *seq, void *offset)
-{
- long pages = snd_allocated_pages >> (PAGE_SHIFT-12);
- struct snd_mem_list *mem;
- int devno;
- static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG" };
-
- mutex_lock(&list_mutex);
- seq_printf(seq, "pages : %li bytes (%li pages per %likB)\n",
- pages * PAGE_SIZE, pages, PAGE_SIZE / 1024);
- devno = 0;
- list_for_each_entry(mem, &mem_list_head, list) {
- devno++;
- seq_printf(seq, "buffer %d : ID %08x : type %s\n",
- devno, mem->id, types[mem->buffer.dev.type]);
- seq_printf(seq, " addr = 0x%lx, size = %d bytes\n",
- (unsigned long)mem->buffer.addr,
- (int)mem->buffer.bytes);
- }
- mutex_unlock(&list_mutex);
- return 0;
-}
-
-static int snd_mem_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, snd_mem_proc_read, NULL);
-}
-
-/* FIXME: for pci only - other bus? */
-#ifdef CONFIG_PCI
-#define gettoken(bufp) strsep(bufp, " \t\n")
-
-static ssize_t snd_mem_proc_write(struct file *file, const char __user * buffer,
- size_t count, loff_t * ppos)
-{
- char buf[128];
- char *token, *p;
-
- if (count > sizeof(buf) - 1)
- return -EINVAL;
- if (copy_from_user(buf, buffer, count))
- return -EFAULT;
- buf[count] = '\0';
-
- p = buf;
- token = gettoken(&p);
- if (! token || *token == '#')
- return count;
- if (strcmp(token, "add") == 0) {
- char *endp;
- int vendor, device, size, buffers;
- long mask;
- int i, alloced;
- struct pci_dev *pci;
-
- if ((token = gettoken(&p)) == NULL ||
- (vendor = simple_strtol(token, NULL, 0)) <= 0 ||
- (token = gettoken(&p)) == NULL ||
- (device = simple_strtol(token, NULL, 0)) <= 0 ||
- (token = gettoken(&p)) == NULL ||
- (mask = simple_strtol(token, NULL, 0)) < 0 ||
- (token = gettoken(&p)) == NULL ||
- (size = memparse(token, &endp)) < 64*1024 ||
- size > 16*1024*1024 /* too big */ ||
- (token = gettoken(&p)) == NULL ||
- (buffers = simple_strtol(token, NULL, 0)) <= 0 ||
- buffers > 4) {
- printk(KERN_ERR "snd-page-alloc: invalid proc write format\n");
- return count;
- }
- vendor &= 0xffff;
- device &= 0xffff;
-
- alloced = 0;
- pci = NULL;
- while ((pci = pci_get_device(vendor, device, pci)) != NULL) {
- if (mask > 0 && mask < 0xffffffff) {
- if (pci_set_dma_mask(pci, mask) < 0 ||
- pci_set_consistent_dma_mask(pci, mask) < 0) {
- printk(KERN_ERR "snd-page-alloc: cannot set DMA mask %lx for pci %04x:%04x\n", mask, vendor, device);
- pci_dev_put(pci);
- return count;
- }
- }
- for (i = 0; i < buffers; i++) {
- struct snd_dma_buffer dmab;
- memset(&dmab, 0, sizeof(dmab));
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
- size, &dmab) < 0) {
- printk(KERN_ERR "snd-page-alloc: cannot allocate buffer pages (size = %d)\n", size);
- pci_dev_put(pci);
- return count;
- }
- snd_dma_reserve_buf(&dmab, snd_dma_pci_buf_id(pci));
- }
- alloced++;
- }
- if (! alloced) {
- for (i = 0; i < buffers; i++) {
- struct snd_dma_buffer dmab;
- memset(&dmab, 0, sizeof(dmab));
- /* FIXME: We can allocate only in ZONE_DMA
- * without a device pointer!
- */
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, NULL,
- size, &dmab) < 0) {
- printk(KERN_ERR "snd-page-alloc: cannot allocate buffer pages (size = %d)\n", size);
- break;
- }
- snd_dma_reserve_buf(&dmab, (unsigned int)((vendor << 16) | device));
- }
- }
- } else if (strcmp(token, "erase") == 0)
- /* FIXME: need for releasing each buffer chunk? */
- free_all_reserved_pages();
- else
- printk(KERN_ERR "snd-page-alloc: invalid proc cmd\n");
- return count;
-}
-#endif /* CONFIG_PCI */
-
-static const struct file_operations snd_mem_proc_fops = {
- .owner = THIS_MODULE,
- .open = snd_mem_proc_open,
- .read = seq_read,
-#ifdef CONFIG_PCI
- .write = snd_mem_proc_write,
-#endif
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-#endif /* CONFIG_PROC_FS */
-
-/*
- * module entry
- */
-
-static int __init snd_mem_init(void)
-{
-#ifdef CONFIG_PROC_FS
- snd_mem_proc = proc_create(SND_MEM_PROC_FILE, 0644, NULL,
- &snd_mem_proc_fops);
-#endif
- return 0;
-}
-
-static void __exit snd_mem_exit(void)
-{
- remove_proc_entry(SND_MEM_PROC_FILE, NULL);
- free_all_reserved_pages();
- if (snd_allocated_pages > 0)
- printk(KERN_ERR "snd-malloc: Memory leak? pages not freed = %li\n", snd_allocated_pages);
-}
-
-
-module_init(snd_mem_init)
-module_exit(snd_mem_exit)
-
-
-/*
- * exports
- */
-EXPORT_SYMBOL(snd_dma_alloc_pages);
-EXPORT_SYMBOL(snd_dma_alloc_pages_fallback);
-EXPORT_SYMBOL(snd_dma_free_pages);
-
-EXPORT_SYMBOL(snd_dma_get_reserved_buf);
-EXPORT_SYMBOL(snd_dma_reserve_buf);
-
-EXPORT_SYMBOL(snd_malloc_pages);
-EXPORT_SYMBOL(snd_free_pages);
diff --git a/ANDROID_3.4.5/sound/core/memory.c b/ANDROID_3.4.5/sound/core/memory.c
deleted file mode 100644
index 66a278d0..00000000
--- a/ANDROID_3.4.5/sound/core/memory.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- * Misc memory accessors
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/export.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <sound/core.h>
-
-/**
- * copy_to_user_fromio - copy data from mmio-space to user-space
- * @dst: the destination pointer on user-space
- * @src: the source pointer on mmio
- * @count: the data size to copy in bytes
- *
- * Copies the data from mmio-space to user-space.
- *
- * Returns zero if successful, or non-zero on failure.
- */
-int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count)
-{
-#if defined(__i386__) || defined(CONFIG_SPARC32)
- return copy_to_user(dst, (const void __force*)src, count) ? -EFAULT : 0;
-#else
- char buf[256];
- while (count) {
- size_t c = count;
- if (c > sizeof(buf))
- c = sizeof(buf);
- memcpy_fromio(buf, (void __iomem *)src, c);
- if (copy_to_user(dst, buf, c))
- return -EFAULT;
- count -= c;
- dst += c;
- src += c;
- }
- return 0;
-#endif
-}
-
-EXPORT_SYMBOL(copy_to_user_fromio);
-
-/**
- * copy_from_user_toio - copy data from user-space to mmio-space
- * @dst: the destination pointer on mmio-space
- * @src: the source pointer on user-space
- * @count: the data size to copy in bytes
- *
- * Copies the data from user-space to mmio-space.
- *
- * Returns zero if successful, or non-zero on failure.
- */
-int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count)
-{
-#if defined(__i386__) || defined(CONFIG_SPARC32)
- return copy_from_user((void __force *)dst, src, count) ? -EFAULT : 0;
-#else
- char buf[256];
- while (count) {
- size_t c = count;
- if (c > sizeof(buf))
- c = sizeof(buf);
- if (copy_from_user(buf, src, c))
- return -EFAULT;
- memcpy_toio(dst, buf, c);
- count -= c;
- dst += c;
- src += c;
- }
- return 0;
-#endif
-}
-
-EXPORT_SYMBOL(copy_from_user_toio);
diff --git a/ANDROID_3.4.5/sound/core/misc.c b/ANDROID_3.4.5/sound/core/misc.c
deleted file mode 100644
index 76816792..00000000
--- a/ANDROID_3.4.5/sound/core/misc.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Misc and compatibility things
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/export.h>
-#include <linux/moduleparam.h>
-#include <linux/time.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <sound/core.h>
-
-#ifdef CONFIG_SND_DEBUG
-
-#ifdef CONFIG_SND_DEBUG_VERBOSE
-#define DEFAULT_DEBUG_LEVEL 2
-#else
-#define DEFAULT_DEBUG_LEVEL 1
-#endif
-
-static int debug = DEFAULT_DEBUG_LEVEL;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level (0 = disable)");
-
-#endif /* CONFIG_SND_DEBUG */
-
-void release_and_free_resource(struct resource *res)
-{
- if (res) {
- release_resource(res);
- kfree(res);
- }
-}
-
-EXPORT_SYMBOL(release_and_free_resource);
-
-#ifdef CONFIG_SND_VERBOSE_PRINTK
-/* strip the leading path if the given path is absolute */
-static const char *sanity_file_name(const char *path)
-{
- if (*path == '/')
- return strrchr(path, '/') + 1;
- else
- return path;
-}
-#endif
-
-#if defined(CONFIG_SND_DEBUG) || defined(CONFIG_SND_VERBOSE_PRINTK)
-void __snd_printk(unsigned int level, const char *path, int line,
- const char *format, ...)
-{
- va_list args;
-#ifdef CONFIG_SND_VERBOSE_PRINTK
- struct va_format vaf;
- char verbose_fmt[] = KERN_DEFAULT "ALSA %s:%d %pV";
-#endif
-
-#ifdef CONFIG_SND_DEBUG
- if (debug < level)
- return;
-#endif
-
- va_start(args, format);
-#ifdef CONFIG_SND_VERBOSE_PRINTK
- vaf.fmt = format;
- vaf.va = &args;
- if (format[0] == '<' && format[2] == '>') {
- memcpy(verbose_fmt, format, 3);
- vaf.fmt = format + 3;
- } else if (level)
- memcpy(verbose_fmt, KERN_DEBUG, 3);
- printk(verbose_fmt, sanity_file_name(path), line, &vaf);
-#else
- vprintk(format, args);
-#endif
- va_end(args);
-}
-EXPORT_SYMBOL_GPL(__snd_printk);
-#endif
-
-#ifdef CONFIG_PCI
-#include <linux/pci.h>
-/**
- * snd_pci_quirk_lookup_id - look up a PCI SSID quirk list
- * @vendor: PCI SSV id
- * @device: PCI SSD id
- * @list: quirk list, terminated by a null entry
- *
- * Look through the given quirk list and finds a matching entry
- * with the same PCI SSID. When subdevice is 0, all subdevice
- * values may match.
- *
- * Returns the matched entry pointer, or NULL if nothing matched.
- */
-const struct snd_pci_quirk *
-snd_pci_quirk_lookup_id(u16 vendor, u16 device,
- const struct snd_pci_quirk *list)
-{
- const struct snd_pci_quirk *q;
-
- for (q = list; q->subvendor; q++) {
- if (q->subvendor != vendor)
- continue;
- if (!q->subdevice ||
- (device & q->subdevice_mask) == q->subdevice)
- return q;
- }
- return NULL;
-}
-EXPORT_SYMBOL(snd_pci_quirk_lookup_id);
-
-/**
- * snd_pci_quirk_lookup - look up a PCI SSID quirk list
- * @pci: pci_dev handle
- * @list: quirk list, terminated by a null entry
- *
- * Look through the given quirk list and finds a matching entry
- * with the same PCI SSID. When subdevice is 0, all subdevice
- * values may match.
- *
- * Returns the matched entry pointer, or NULL if nothing matched.
- */
-const struct snd_pci_quirk *
-snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list)
-{
- return snd_pci_quirk_lookup_id(pci->subsystem_vendor,
- pci->subsystem_device,
- list);
-}
-EXPORT_SYMBOL(snd_pci_quirk_lookup);
-#endif
diff --git a/ANDROID_3.4.5/sound/core/oss/Makefile b/ANDROID_3.4.5/sound/core/oss/Makefile
deleted file mode 100644
index 10a79453..00000000
--- a/ANDROID_3.4.5/sound/core/oss/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-mixer-oss-objs := mixer_oss.o
-
-snd-pcm-oss-y := pcm_oss.o
-snd-pcm-oss-$(CONFIG_SND_PCM_OSS_PLUGINS) += pcm_plugin.o \
- io.o copy.o linear.o mulaw.o route.o rate.o
-
-obj-$(CONFIG_SND_MIXER_OSS) += snd-mixer-oss.o
-obj-$(CONFIG_SND_PCM_OSS) += snd-pcm-oss.o
diff --git a/ANDROID_3.4.5/sound/core/oss/copy.c b/ANDROID_3.4.5/sound/core/oss/copy.c
deleted file mode 100644
index 05b58d4f..00000000
--- a/ANDROID_3.4.5/sound/core/oss/copy.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Linear conversion Plug-In
- * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
- *
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include "pcm_plugin.h"
-
-static snd_pcm_sframes_t copy_transfer(struct snd_pcm_plugin *plugin,
- const struct snd_pcm_plugin_channel *src_channels,
- struct snd_pcm_plugin_channel *dst_channels,
- snd_pcm_uframes_t frames)
-{
- unsigned int channel;
- unsigned int nchannels;
-
- if (snd_BUG_ON(!plugin || !src_channels || !dst_channels))
- return -ENXIO;
- if (frames == 0)
- return 0;
- nchannels = plugin->src_format.channels;
- for (channel = 0; channel < nchannels; channel++) {
- if (snd_BUG_ON(src_channels->area.first % 8 ||
- src_channels->area.step % 8))
- return -ENXIO;
- if (snd_BUG_ON(dst_channels->area.first % 8 ||
- dst_channels->area.step % 8))
- return -ENXIO;
- if (!src_channels->enabled) {
- if (dst_channels->wanted)
- snd_pcm_area_silence(&dst_channels->area, 0, frames, plugin->dst_format.format);
- dst_channels->enabled = 0;
- continue;
- }
- dst_channels->enabled = 1;
- snd_pcm_area_copy(&src_channels->area, 0, &dst_channels->area, 0, frames, plugin->src_format.format);
- src_channels++;
- dst_channels++;
- }
- return frames;
-}
-
-int snd_pcm_plugin_build_copy(struct snd_pcm_substream *plug,
- struct snd_pcm_plugin_format *src_format,
- struct snd_pcm_plugin_format *dst_format,
- struct snd_pcm_plugin **r_plugin)
-{
- int err;
- struct snd_pcm_plugin *plugin;
- int width;
-
- if (snd_BUG_ON(!r_plugin))
- return -ENXIO;
- *r_plugin = NULL;
-
- if (snd_BUG_ON(src_format->format != dst_format->format))
- return -ENXIO;
- if (snd_BUG_ON(src_format->rate != dst_format->rate))
- return -ENXIO;
- if (snd_BUG_ON(src_format->channels != dst_format->channels))
- return -ENXIO;
-
- width = snd_pcm_format_physical_width(src_format->format);
- if (snd_BUG_ON(width <= 0))
- return -ENXIO;
-
- err = snd_pcm_plugin_build(plug, "copy", src_format, dst_format,
- 0, &plugin);
- if (err < 0)
- return err;
- plugin->transfer = copy_transfer;
- *r_plugin = plugin;
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/core/oss/io.c b/ANDROID_3.4.5/sound/core/oss/io.c
deleted file mode 100644
index 6faa1d71..00000000
--- a/ANDROID_3.4.5/sound/core/oss/io.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * PCM I/O Plug-In Interface
- * Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include "pcm_plugin.h"
-
-#define pcm_write(plug,buf,count) snd_pcm_oss_write3(plug,buf,count,1)
-#define pcm_writev(plug,vec,count) snd_pcm_oss_writev3(plug,vec,count,1)
-#define pcm_read(plug,buf,count) snd_pcm_oss_read3(plug,buf,count,1)
-#define pcm_readv(plug,vec,count) snd_pcm_oss_readv3(plug,vec,count,1)
-
-/*
- * Basic io plugin
- */
-
-static snd_pcm_sframes_t io_playback_transfer(struct snd_pcm_plugin *plugin,
- const struct snd_pcm_plugin_channel *src_channels,
- struct snd_pcm_plugin_channel *dst_channels,
- snd_pcm_uframes_t frames)
-{
- if (snd_BUG_ON(!plugin))
- return -ENXIO;
- if (snd_BUG_ON(!src_channels))
- return -ENXIO;
- if (plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) {
- return pcm_write(plugin->plug, src_channels->area.addr, frames);
- } else {
- int channel, channels = plugin->dst_format.channels;
- void **bufs = (void**)plugin->extra_data;
- if (snd_BUG_ON(!bufs))
- return -ENXIO;
- for (channel = 0; channel < channels; channel++) {
- if (src_channels[channel].enabled)
- bufs[channel] = src_channels[channel].area.addr;
- else
- bufs[channel] = NULL;
- }
- return pcm_writev(plugin->plug, bufs, frames);
- }
-}
-
-static snd_pcm_sframes_t io_capture_transfer(struct snd_pcm_plugin *plugin,
- const struct snd_pcm_plugin_channel *src_channels,
- struct snd_pcm_plugin_channel *dst_channels,
- snd_pcm_uframes_t frames)
-{
- if (snd_BUG_ON(!plugin))
- return -ENXIO;
- if (snd_BUG_ON(!dst_channels))
- return -ENXIO;
- if (plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) {
- return pcm_read(plugin->plug, dst_channels->area.addr, frames);
- } else {
- int channel, channels = plugin->dst_format.channels;
- void **bufs = (void**)plugin->extra_data;
- if (snd_BUG_ON(!bufs))
- return -ENXIO;
- for (channel = 0; channel < channels; channel++) {
- if (dst_channels[channel].enabled)
- bufs[channel] = dst_channels[channel].area.addr;
- else
- bufs[channel] = NULL;
- }
- return pcm_readv(plugin->plug, bufs, frames);
- }
- return 0;
-}
-
-static snd_pcm_sframes_t io_src_channels(struct snd_pcm_plugin *plugin,
- snd_pcm_uframes_t frames,
- struct snd_pcm_plugin_channel **channels)
-{
- int err;
- unsigned int channel;
- struct snd_pcm_plugin_channel *v;
- err = snd_pcm_plugin_client_channels(plugin, frames, &v);
- if (err < 0)
- return err;
- *channels = v;
- if (plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) {
- for (channel = 0; channel < plugin->src_format.channels; ++channel, ++v)
- v->wanted = 1;
- }
- return frames;
-}
-
-int snd_pcm_plugin_build_io(struct snd_pcm_substream *plug,
- struct snd_pcm_hw_params *params,
- struct snd_pcm_plugin **r_plugin)
-{
- int err;
- struct snd_pcm_plugin_format format;
- struct snd_pcm_plugin *plugin;
-
- if (snd_BUG_ON(!r_plugin))
- return -ENXIO;
- *r_plugin = NULL;
- if (snd_BUG_ON(!plug || !params))
- return -ENXIO;
- format.format = params_format(params);
- format.rate = params_rate(params);
- format.channels = params_channels(params);
- err = snd_pcm_plugin_build(plug, "I/O io",
- &format, &format,
- sizeof(void *) * format.channels,
- &plugin);
- if (err < 0)
- return err;
- plugin->access = params_access(params);
- if (snd_pcm_plug_stream(plug) == SNDRV_PCM_STREAM_PLAYBACK) {
- plugin->transfer = io_playback_transfer;
- if (plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED)
- plugin->client_channels = io_src_channels;
- } else {
- plugin->transfer = io_capture_transfer;
- }
-
- *r_plugin = plugin;
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/core/oss/linear.c b/ANDROID_3.4.5/sound/core/oss/linear.c
deleted file mode 100644
index 2045697f..00000000
--- a/ANDROID_3.4.5/sound/core/oss/linear.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Linear conversion Plug-In
- * Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>,
- * Abramo Bagnara <abramo@alsa-project.org>
- *
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include "pcm_plugin.h"
-
-/*
- * Basic linear conversion plugin
- */
-
-struct linear_priv {
- int cvt_endian; /* need endian conversion? */
- unsigned int src_ofs; /* byte offset in source format */
- unsigned int dst_ofs; /* byte soffset in destination format */
- unsigned int copy_ofs; /* byte offset in temporary u32 data */
- unsigned int dst_bytes; /* byte size of destination format */
- unsigned int copy_bytes; /* bytes to copy per conversion */
- unsigned int flip; /* MSB flip for signeness, done after endian conv */
-};
-
-static inline void do_convert(struct linear_priv *data,
- unsigned char *dst, unsigned char *src)
-{
- unsigned int tmp = 0;
- unsigned char *p = (unsigned char *)&tmp;
-
- memcpy(p + data->copy_ofs, src + data->src_ofs, data->copy_bytes);
- if (data->cvt_endian)
- tmp = swab32(tmp);
- tmp ^= data->flip;
- memcpy(dst, p + data->dst_ofs, data->dst_bytes);
-}
-
-static void convert(struct snd_pcm_plugin *plugin,
- const struct snd_pcm_plugin_channel *src_channels,
- struct snd_pcm_plugin_channel *dst_channels,
- snd_pcm_uframes_t frames)
-{
- struct linear_priv *data = (struct linear_priv *)plugin->extra_data;
- int channel;
- int nchannels = plugin->src_format.channels;
- for (channel = 0; channel < nchannels; ++channel) {
- char *src;
- char *dst;
- int src_step, dst_step;
- snd_pcm_uframes_t frames1;
- if (!src_channels[channel].enabled) {
- if (dst_channels[channel].wanted)
- snd_pcm_area_silence(&dst_channels[channel].area, 0, frames, plugin->dst_format.format);
- dst_channels[channel].enabled = 0;
- continue;
- }
- dst_channels[channel].enabled = 1;
- src = src_channels[channel].area.addr + src_channels[channel].area.first / 8;
- dst = dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
- src_step = src_channels[channel].area.step / 8;
- dst_step = dst_channels[channel].area.step / 8;
- frames1 = frames;
- while (frames1-- > 0) {
- do_convert(data, dst, src);
- src += src_step;
- dst += dst_step;
- }
- }
-}
-
-static snd_pcm_sframes_t linear_transfer(struct snd_pcm_plugin *plugin,
- const struct snd_pcm_plugin_channel *src_channels,
- struct snd_pcm_plugin_channel *dst_channels,
- snd_pcm_uframes_t frames)
-{
- if (snd_BUG_ON(!plugin || !src_channels || !dst_channels))
- return -ENXIO;
- if (frames == 0)
- return 0;
-#ifdef CONFIG_SND_DEBUG
- {
- unsigned int channel;
- for (channel = 0; channel < plugin->src_format.channels; channel++) {
- if (snd_BUG_ON(src_channels[channel].area.first % 8 ||
- src_channels[channel].area.step % 8))
- return -ENXIO;
- if (snd_BUG_ON(dst_channels[channel].area.first % 8 ||
- dst_channels[channel].area.step % 8))
- return -ENXIO;
- }
- }
-#endif
- convert(plugin, src_channels, dst_channels, frames);
- return frames;
-}
-
-static void init_data(struct linear_priv *data,
- snd_pcm_format_t src_format, snd_pcm_format_t dst_format)
-{
- int src_le, dst_le, src_bytes, dst_bytes;
-
- src_bytes = snd_pcm_format_width(src_format) / 8;
- dst_bytes = snd_pcm_format_width(dst_format) / 8;
- src_le = snd_pcm_format_little_endian(src_format) > 0;
- dst_le = snd_pcm_format_little_endian(dst_format) > 0;
-
- data->dst_bytes = dst_bytes;
- data->cvt_endian = src_le != dst_le;
- data->copy_bytes = src_bytes < dst_bytes ? src_bytes : dst_bytes;
- if (src_le) {
- data->copy_ofs = 4 - data->copy_bytes;
- data->src_ofs = src_bytes - data->copy_bytes;
- } else
- data->src_ofs = snd_pcm_format_physical_width(src_format) / 8 -
- src_bytes;
- if (dst_le)
- data->dst_ofs = 4 - data->dst_bytes;
- else
- data->dst_ofs = snd_pcm_format_physical_width(dst_format) / 8 -
- dst_bytes;
- if (snd_pcm_format_signed(src_format) !=
- snd_pcm_format_signed(dst_format)) {
- if (dst_le)
- data->flip = (__force u32)cpu_to_le32(0x80000000);
- else
- data->flip = (__force u32)cpu_to_be32(0x80000000);
- }
-}
-
-int snd_pcm_plugin_build_linear(struct snd_pcm_substream *plug,
- struct snd_pcm_plugin_format *src_format,
- struct snd_pcm_plugin_format *dst_format,
- struct snd_pcm_plugin **r_plugin)
-{
- int err;
- struct linear_priv *data;
- struct snd_pcm_plugin *plugin;
-
- if (snd_BUG_ON(!r_plugin))
- return -ENXIO;
- *r_plugin = NULL;
-
- if (snd_BUG_ON(src_format->rate != dst_format->rate))
- return -ENXIO;
- if (snd_BUG_ON(src_format->channels != dst_format->channels))
- return -ENXIO;
- if (snd_BUG_ON(!snd_pcm_format_linear(src_format->format) ||
- !snd_pcm_format_linear(dst_format->format)))
- return -ENXIO;
-
- err = snd_pcm_plugin_build(plug, "linear format conversion",
- src_format, dst_format,
- sizeof(struct linear_priv), &plugin);
- if (err < 0)
- return err;
- data = (struct linear_priv *)plugin->extra_data;
- init_data(data, src_format->format, dst_format->format);
- plugin->transfer = linear_transfer;
- *r_plugin = plugin;
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/core/oss/mixer_oss.c b/ANDROID_3.4.5/sound/core/oss/mixer_oss.c
deleted file mode 100644
index c3537688..00000000
--- a/ANDROID_3.4.5/sound/core/oss/mixer_oss.c
+++ /dev/null
@@ -1,1422 +0,0 @@
-/*
- * OSS emulation layer for the mixer interface
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/string.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/minors.h>
-#include <sound/control.h>
-#include <sound/info.h>
-#include <sound/mixer_oss.h>
-#include <linux/soundcard.h>
-
-#define OSS_ALSAEMULVER _SIOR ('M', 249, int)
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Mixer OSS emulation for ALSA.");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_MIXER);
-
-static int snd_mixer_oss_open(struct inode *inode, struct file *file)
-{
- struct snd_card *card;
- struct snd_mixer_oss_file *fmixer;
- int err;
-
- err = nonseekable_open(inode, file);
- if (err < 0)
- return err;
-
- card = snd_lookup_oss_minor_data(iminor(inode),
- SNDRV_OSS_DEVICE_TYPE_MIXER);
- if (card == NULL)
- return -ENODEV;
- if (card->mixer_oss == NULL) {
- snd_card_unref(card);
- return -ENODEV;
- }
- err = snd_card_file_add(card, file);
- if (err < 0) {
- snd_card_unref(card);
- return err;
- }
- fmixer = kzalloc(sizeof(*fmixer), GFP_KERNEL);
- if (fmixer == NULL) {
- snd_card_file_remove(card, file);
- snd_card_unref(card);
- return -ENOMEM;
- }
- fmixer->card = card;
- fmixer->mixer = card->mixer_oss;
- file->private_data = fmixer;
- if (!try_module_get(card->module)) {
- kfree(fmixer);
- snd_card_file_remove(card, file);
- snd_card_unref(card);
- return -EFAULT;
- }
- snd_card_unref(card);
- return 0;
-}
-
-static int snd_mixer_oss_release(struct inode *inode, struct file *file)
-{
- struct snd_mixer_oss_file *fmixer;
-
- if (file->private_data) {
- fmixer = file->private_data;
- module_put(fmixer->card->module);
- snd_card_file_remove(fmixer->card, file);
- kfree(fmixer);
- }
- return 0;
-}
-
-static int snd_mixer_oss_info(struct snd_mixer_oss_file *fmixer,
- mixer_info __user *_info)
-{
- struct snd_card *card = fmixer->card;
- struct snd_mixer_oss *mixer = fmixer->mixer;
- struct mixer_info info;
-
- memset(&info, 0, sizeof(info));
- strlcpy(info.id, mixer && mixer->id[0] ? mixer->id : card->driver, sizeof(info.id));
- strlcpy(info.name, mixer && mixer->name[0] ? mixer->name : card->mixername, sizeof(info.name));
- info.modify_counter = card->mixer_oss_change_count;
- if (copy_to_user(_info, &info, sizeof(info)))
- return -EFAULT;
- return 0;
-}
-
-static int snd_mixer_oss_info_obsolete(struct snd_mixer_oss_file *fmixer,
- _old_mixer_info __user *_info)
-{
- struct snd_card *card = fmixer->card;
- struct snd_mixer_oss *mixer = fmixer->mixer;
- _old_mixer_info info;
-
- memset(&info, 0, sizeof(info));
- strlcpy(info.id, mixer && mixer->id[0] ? mixer->id : card->driver, sizeof(info.id));
- strlcpy(info.name, mixer && mixer->name[0] ? mixer->name : card->mixername, sizeof(info.name));
- if (copy_to_user(_info, &info, sizeof(info)))
- return -EFAULT;
- return 0;
-}
-
-static int snd_mixer_oss_caps(struct snd_mixer_oss_file *fmixer)
-{
- struct snd_mixer_oss *mixer = fmixer->mixer;
- int result = 0;
-
- if (mixer == NULL)
- return -EIO;
- if (mixer->get_recsrc && mixer->put_recsrc)
- result |= SOUND_CAP_EXCL_INPUT;
- return result;
-}
-
-static int snd_mixer_oss_devmask(struct snd_mixer_oss_file *fmixer)
-{
- struct snd_mixer_oss *mixer = fmixer->mixer;
- struct snd_mixer_oss_slot *pslot;
- int result = 0, chn;
-
- if (mixer == NULL)
- return -EIO;
- for (chn = 0; chn < 31; chn++) {
- pslot = &mixer->slots[chn];
- if (pslot->put_volume || pslot->put_recsrc)
- result |= 1 << chn;
- }
- return result;
-}
-
-static int snd_mixer_oss_stereodevs(struct snd_mixer_oss_file *fmixer)
-{
- struct snd_mixer_oss *mixer = fmixer->mixer;
- struct snd_mixer_oss_slot *pslot;
- int result = 0, chn;
-
- if (mixer == NULL)
- return -EIO;
- for (chn = 0; chn < 31; chn++) {
- pslot = &mixer->slots[chn];
- if (pslot->put_volume && pslot->stereo)
- result |= 1 << chn;
- }
- return result;
-}
-
-static int snd_mixer_oss_recmask(struct snd_mixer_oss_file *fmixer)
-{
- struct snd_mixer_oss *mixer = fmixer->mixer;
- int result = 0;
-
- if (mixer == NULL)
- return -EIO;
- if (mixer->put_recsrc && mixer->get_recsrc) { /* exclusive */
- result = mixer->mask_recsrc;
- } else {
- struct snd_mixer_oss_slot *pslot;
- int chn;
- for (chn = 0; chn < 31; chn++) {
- pslot = &mixer->slots[chn];
- if (pslot->put_recsrc)
- result |= 1 << chn;
- }
- }
- return result;
-}
-
-static int snd_mixer_oss_get_recsrc(struct snd_mixer_oss_file *fmixer)
-{
- struct snd_mixer_oss *mixer = fmixer->mixer;
- int result = 0;
-
- if (mixer == NULL)
- return -EIO;
- if (mixer->put_recsrc && mixer->get_recsrc) { /* exclusive */
- int err;
- unsigned int index;
- if ((err = mixer->get_recsrc(fmixer, &index)) < 0)
- return err;
- result = 1 << index;
- } else {
- struct snd_mixer_oss_slot *pslot;
- int chn;
- for (chn = 0; chn < 31; chn++) {
- pslot = &mixer->slots[chn];
- if (pslot->get_recsrc) {
- int active = 0;
- pslot->get_recsrc(fmixer, pslot, &active);
- if (active)
- result |= 1 << chn;
- }
- }
- }
- return mixer->oss_recsrc = result;
-}
-
-static int snd_mixer_oss_set_recsrc(struct snd_mixer_oss_file *fmixer, int recsrc)
-{
- struct snd_mixer_oss *mixer = fmixer->mixer;
- struct snd_mixer_oss_slot *pslot;
- int chn, active;
- unsigned int index;
- int result = 0;
-
- if (mixer == NULL)
- return -EIO;
- if (mixer->get_recsrc && mixer->put_recsrc) { /* exclusive input */
- if (recsrc & ~mixer->oss_recsrc)
- recsrc &= ~mixer->oss_recsrc;
- mixer->put_recsrc(fmixer, ffz(~recsrc));
- mixer->get_recsrc(fmixer, &index);
- result = 1 << index;
- }
- for (chn = 0; chn < 31; chn++) {
- pslot = &mixer->slots[chn];
- if (pslot->put_recsrc) {
- active = (recsrc & (1 << chn)) ? 1 : 0;
- pslot->put_recsrc(fmixer, pslot, active);
- }
- }
- if (! result) {
- for (chn = 0; chn < 31; chn++) {
- pslot = &mixer->slots[chn];
- if (pslot->get_recsrc) {
- active = 0;
- pslot->get_recsrc(fmixer, pslot, &active);
- if (active)
- result |= 1 << chn;
- }
- }
- }
- return result;
-}
-
-static int snd_mixer_oss_get_volume(struct snd_mixer_oss_file *fmixer, int slot)
-{
- struct snd_mixer_oss *mixer = fmixer->mixer;
- struct snd_mixer_oss_slot *pslot;
- int result = 0, left, right;
-
- if (mixer == NULL || slot > 30)
- return -EIO;
- pslot = &mixer->slots[slot];
- left = pslot->volume[0];
- right = pslot->volume[1];
- if (pslot->get_volume)
- result = pslot->get_volume(fmixer, pslot, &left, &right);
- if (!pslot->stereo)
- right = left;
- if (snd_BUG_ON(left < 0 || left > 100))
- return -EIO;
- if (snd_BUG_ON(right < 0 || right > 100))
- return -EIO;
- if (result >= 0) {
- pslot->volume[0] = left;
- pslot->volume[1] = right;
- result = (left & 0xff) | ((right & 0xff) << 8);
- }
- return result;
-}
-
-static int snd_mixer_oss_set_volume(struct snd_mixer_oss_file *fmixer,
- int slot, int volume)
-{
- struct snd_mixer_oss *mixer = fmixer->mixer;
- struct snd_mixer_oss_slot *pslot;
- int result = 0, left = volume & 0xff, right = (volume >> 8) & 0xff;
-
- if (mixer == NULL || slot > 30)
- return -EIO;
- pslot = &mixer->slots[slot];
- if (left > 100)
- left = 100;
- if (right > 100)
- right = 100;
- if (!pslot->stereo)
- right = left;
- if (pslot->put_volume)
- result = pslot->put_volume(fmixer, pslot, left, right);
- if (result < 0)
- return result;
- pslot->volume[0] = left;
- pslot->volume[1] = right;
- return (left & 0xff) | ((right & 0xff) << 8);
-}
-
-static int snd_mixer_oss_ioctl1(struct snd_mixer_oss_file *fmixer, unsigned int cmd, unsigned long arg)
-{
- void __user *argp = (void __user *)arg;
- int __user *p = argp;
- int tmp;
-
- if (snd_BUG_ON(!fmixer))
- return -ENXIO;
- if (((cmd >> 8) & 0xff) == 'M') {
- switch (cmd) {
- case SOUND_MIXER_INFO:
- return snd_mixer_oss_info(fmixer, argp);
- case SOUND_OLD_MIXER_INFO:
- return snd_mixer_oss_info_obsolete(fmixer, argp);
- case SOUND_MIXER_WRITE_RECSRC:
- if (get_user(tmp, p))
- return -EFAULT;
- tmp = snd_mixer_oss_set_recsrc(fmixer, tmp);
- if (tmp < 0)
- return tmp;
- return put_user(tmp, p);
- case OSS_GETVERSION:
- return put_user(SNDRV_OSS_VERSION, p);
- case OSS_ALSAEMULVER:
- return put_user(1, p);
- case SOUND_MIXER_READ_DEVMASK:
- tmp = snd_mixer_oss_devmask(fmixer);
- if (tmp < 0)
- return tmp;
- return put_user(tmp, p);
- case SOUND_MIXER_READ_STEREODEVS:
- tmp = snd_mixer_oss_stereodevs(fmixer);
- if (tmp < 0)
- return tmp;
- return put_user(tmp, p);
- case SOUND_MIXER_READ_RECMASK:
- tmp = snd_mixer_oss_recmask(fmixer);
- if (tmp < 0)
- return tmp;
- return put_user(tmp, p);
- case SOUND_MIXER_READ_CAPS:
- tmp = snd_mixer_oss_caps(fmixer);
- if (tmp < 0)
- return tmp;
- return put_user(tmp, p);
- case SOUND_MIXER_READ_RECSRC:
- tmp = snd_mixer_oss_get_recsrc(fmixer);
- if (tmp < 0)
- return tmp;
- return put_user(tmp, p);
- }
- }
- if (cmd & SIOC_IN) {
- if (get_user(tmp, p))
- return -EFAULT;
- tmp = snd_mixer_oss_set_volume(fmixer, cmd & 0xff, tmp);
- if (tmp < 0)
- return tmp;
- return put_user(tmp, p);
- } else if (cmd & SIOC_OUT) {
- tmp = snd_mixer_oss_get_volume(fmixer, cmd & 0xff);
- if (tmp < 0)
- return tmp;
- return put_user(tmp, p);
- }
- return -ENXIO;
-}
-
-static long snd_mixer_oss_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- return snd_mixer_oss_ioctl1(file->private_data, cmd, arg);
-}
-
-int snd_mixer_oss_ioctl_card(struct snd_card *card, unsigned int cmd, unsigned long arg)
-{
- struct snd_mixer_oss_file fmixer;
-
- if (snd_BUG_ON(!card))
- return -ENXIO;
- if (card->mixer_oss == NULL)
- return -ENXIO;
- memset(&fmixer, 0, sizeof(fmixer));
- fmixer.card = card;
- fmixer.mixer = card->mixer_oss;
- return snd_mixer_oss_ioctl1(&fmixer, cmd, arg);
-}
-
-#ifdef CONFIG_COMPAT
-/* all compatible */
-#define snd_mixer_oss_ioctl_compat snd_mixer_oss_ioctl
-#else
-#define snd_mixer_oss_ioctl_compat NULL
-#endif
-
-/*
- * REGISTRATION PART
- */
-
-static const struct file_operations snd_mixer_oss_f_ops =
-{
- .owner = THIS_MODULE,
- .open = snd_mixer_oss_open,
- .release = snd_mixer_oss_release,
- .llseek = no_llseek,
- .unlocked_ioctl = snd_mixer_oss_ioctl,
- .compat_ioctl = snd_mixer_oss_ioctl_compat,
-};
-
-/*
- * utilities
- */
-
-static long snd_mixer_oss_conv(long val, long omin, long omax, long nmin, long nmax)
-{
- long orange = omax - omin, nrange = nmax - nmin;
-
- if (orange == 0)
- return 0;
- return ((nrange * (val - omin)) + (orange / 2)) / orange + nmin;
-}
-
-/* convert from alsa native to oss values (0-100) */
-static long snd_mixer_oss_conv1(long val, long min, long max, int *old)
-{
- if (val == snd_mixer_oss_conv(*old, 0, 100, min, max))
- return *old;
- return snd_mixer_oss_conv(val, min, max, 0, 100);
-}
-
-/* convert from oss to alsa native values */
-static long snd_mixer_oss_conv2(long val, long min, long max)
-{
- return snd_mixer_oss_conv(val, 0, 100, min, max);
-}
-
-#if 0
-static void snd_mixer_oss_recsrce_set(struct snd_card *card, int slot)
-{
- struct snd_mixer_oss *mixer = card->mixer_oss;
- if (mixer)
- mixer->mask_recsrc |= 1 << slot;
-}
-
-static int snd_mixer_oss_recsrce_get(struct snd_card *card, int slot)
-{
- struct snd_mixer_oss *mixer = card->mixer_oss;
- if (mixer && (mixer->mask_recsrc & (1 << slot)))
- return 1;
- return 0;
-}
-#endif
-
-#define SNDRV_MIXER_OSS_SIGNATURE 0x65999250
-
-#define SNDRV_MIXER_OSS_ITEM_GLOBAL 0
-#define SNDRV_MIXER_OSS_ITEM_GSWITCH 1
-#define SNDRV_MIXER_OSS_ITEM_GROUTE 2
-#define SNDRV_MIXER_OSS_ITEM_GVOLUME 3
-#define SNDRV_MIXER_OSS_ITEM_PSWITCH 4
-#define SNDRV_MIXER_OSS_ITEM_PROUTE 5
-#define SNDRV_MIXER_OSS_ITEM_PVOLUME 6
-#define SNDRV_MIXER_OSS_ITEM_CSWITCH 7
-#define SNDRV_MIXER_OSS_ITEM_CROUTE 8
-#define SNDRV_MIXER_OSS_ITEM_CVOLUME 9
-#define SNDRV_MIXER_OSS_ITEM_CAPTURE 10
-
-#define SNDRV_MIXER_OSS_ITEM_COUNT 11
-
-#define SNDRV_MIXER_OSS_PRESENT_GLOBAL (1<<0)
-#define SNDRV_MIXER_OSS_PRESENT_GSWITCH (1<<1)
-#define SNDRV_MIXER_OSS_PRESENT_GROUTE (1<<2)
-#define SNDRV_MIXER_OSS_PRESENT_GVOLUME (1<<3)
-#define SNDRV_MIXER_OSS_PRESENT_PSWITCH (1<<4)
-#define SNDRV_MIXER_OSS_PRESENT_PROUTE (1<<5)
-#define SNDRV_MIXER_OSS_PRESENT_PVOLUME (1<<6)
-#define SNDRV_MIXER_OSS_PRESENT_CSWITCH (1<<7)
-#define SNDRV_MIXER_OSS_PRESENT_CROUTE (1<<8)
-#define SNDRV_MIXER_OSS_PRESENT_CVOLUME (1<<9)
-#define SNDRV_MIXER_OSS_PRESENT_CAPTURE (1<<10)
-
-struct slot {
- unsigned int signature;
- unsigned int present;
- unsigned int channels;
- unsigned int numid[SNDRV_MIXER_OSS_ITEM_COUNT];
- unsigned int capture_item;
- struct snd_mixer_oss_assign_table *assigned;
- unsigned int allocated: 1;
-};
-
-#define ID_UNKNOWN ((unsigned int)-1)
-
-static struct snd_kcontrol *snd_mixer_oss_test_id(struct snd_mixer_oss *mixer, const char *name, int index)
-{
- struct snd_card *card = mixer->card;
- struct snd_ctl_elem_id id;
-
- memset(&id, 0, sizeof(id));
- id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strlcpy(id.name, name, sizeof(id.name));
- id.index = index;
- return snd_ctl_find_id(card, &id);
-}
-
-static void snd_mixer_oss_get_volume1_vol(struct snd_mixer_oss_file *fmixer,
- struct snd_mixer_oss_slot *pslot,
- unsigned int numid,
- int *left, int *right)
-{
- struct snd_ctl_elem_info *uinfo;
- struct snd_ctl_elem_value *uctl;
- struct snd_kcontrol *kctl;
- struct snd_card *card = fmixer->card;
-
- if (numid == ID_UNKNOWN)
- return;
- down_read(&card->controls_rwsem);
- if ((kctl = snd_ctl_find_numid(card, numid)) == NULL) {
- up_read(&card->controls_rwsem);
- return;
- }
- uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
- uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
- if (uinfo == NULL || uctl == NULL)
- goto __unalloc;
- if (kctl->info(kctl, uinfo))
- goto __unalloc;
- if (kctl->get(kctl, uctl))
- goto __unalloc;
- if (uinfo->type == SNDRV_CTL_ELEM_TYPE_BOOLEAN &&
- uinfo->value.integer.min == 0 && uinfo->value.integer.max == 1)
- goto __unalloc;
- *left = snd_mixer_oss_conv1(uctl->value.integer.value[0], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[0]);
- if (uinfo->count > 1)
- *right = snd_mixer_oss_conv1(uctl->value.integer.value[1], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[1]);
- __unalloc:
- up_read(&card->controls_rwsem);
- kfree(uctl);
- kfree(uinfo);
-}
-
-static void snd_mixer_oss_get_volume1_sw(struct snd_mixer_oss_file *fmixer,
- struct snd_mixer_oss_slot *pslot,
- unsigned int numid,
- int *left, int *right,
- int route)
-{
- struct snd_ctl_elem_info *uinfo;
- struct snd_ctl_elem_value *uctl;
- struct snd_kcontrol *kctl;
- struct snd_card *card = fmixer->card;
-
- if (numid == ID_UNKNOWN)
- return;
- down_read(&card->controls_rwsem);
- if ((kctl = snd_ctl_find_numid(card, numid)) == NULL) {
- up_read(&card->controls_rwsem);
- return;
- }
- uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
- uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
- if (uinfo == NULL || uctl == NULL)
- goto __unalloc;
- if (kctl->info(kctl, uinfo))
- goto __unalloc;
- if (kctl->get(kctl, uctl))
- goto __unalloc;
- if (!uctl->value.integer.value[0]) {
- *left = 0;
- if (uinfo->count == 1)
- *right = 0;
- }
- if (uinfo->count > 1 && !uctl->value.integer.value[route ? 3 : 1])
- *right = 0;
- __unalloc:
- up_read(&card->controls_rwsem);
- kfree(uctl);
- kfree(uinfo);
-}
-
-static int snd_mixer_oss_get_volume1(struct snd_mixer_oss_file *fmixer,
- struct snd_mixer_oss_slot *pslot,
- int *left, int *right)
-{
- struct slot *slot = pslot->private_data;
-
- *left = *right = 100;
- if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) {
- snd_mixer_oss_get_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right);
- } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GVOLUME) {
- snd_mixer_oss_get_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GVOLUME], left, right);
- } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GLOBAL) {
- snd_mixer_oss_get_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GLOBAL], left, right);
- }
- if (slot->present & SNDRV_MIXER_OSS_PRESENT_PSWITCH) {
- snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PSWITCH], left, right, 0);
- } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GSWITCH) {
- snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GSWITCH], left, right, 0);
- } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_PROUTE) {
- snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PROUTE], left, right, 1);
- } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GROUTE) {
- snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GROUTE], left, right, 1);
- }
- return 0;
-}
-
-static void snd_mixer_oss_put_volume1_vol(struct snd_mixer_oss_file *fmixer,
- struct snd_mixer_oss_slot *pslot,
- unsigned int numid,
- int left, int right)
-{
- struct snd_ctl_elem_info *uinfo;
- struct snd_ctl_elem_value *uctl;
- struct snd_kcontrol *kctl;
- struct snd_card *card = fmixer->card;
- int res;
-
- if (numid == ID_UNKNOWN)
- return;
- down_read(&card->controls_rwsem);
- if ((kctl = snd_ctl_find_numid(card, numid)) == NULL) {
- up_read(&card->controls_rwsem);
- return;
- }
- uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
- uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
- if (uinfo == NULL || uctl == NULL)
- goto __unalloc;
- if (kctl->info(kctl, uinfo))
- goto __unalloc;
- if (uinfo->type == SNDRV_CTL_ELEM_TYPE_BOOLEAN &&
- uinfo->value.integer.min == 0 && uinfo->value.integer.max == 1)
- goto __unalloc;
- uctl->value.integer.value[0] = snd_mixer_oss_conv2(left, uinfo->value.integer.min, uinfo->value.integer.max);
- if (uinfo->count > 1)
- uctl->value.integer.value[1] = snd_mixer_oss_conv2(right, uinfo->value.integer.min, uinfo->value.integer.max);
- if ((res = kctl->put(kctl, uctl)) < 0)
- goto __unalloc;
- if (res > 0)
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
- __unalloc:
- up_read(&card->controls_rwsem);
- kfree(uctl);
- kfree(uinfo);
-}
-
-static void snd_mixer_oss_put_volume1_sw(struct snd_mixer_oss_file *fmixer,
- struct snd_mixer_oss_slot *pslot,
- unsigned int numid,
- int left, int right,
- int route)
-{
- struct snd_ctl_elem_info *uinfo;
- struct snd_ctl_elem_value *uctl;
- struct snd_kcontrol *kctl;
- struct snd_card *card = fmixer->card;
- int res;
-
- if (numid == ID_UNKNOWN)
- return;
- down_read(&card->controls_rwsem);
- if ((kctl = snd_ctl_find_numid(card, numid)) == NULL) {
- up_read(&card->controls_rwsem);
- return;
- }
- uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
- uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
- if (uinfo == NULL || uctl == NULL)
- goto __unalloc;
- if (kctl->info(kctl, uinfo))
- goto __unalloc;
- if (uinfo->count > 1) {
- uctl->value.integer.value[0] = left > 0 ? 1 : 0;
- uctl->value.integer.value[route ? 3 : 1] = right > 0 ? 1 : 0;
- if (route) {
- uctl->value.integer.value[1] =
- uctl->value.integer.value[2] = 0;
- }
- } else {
- uctl->value.integer.value[0] = (left > 0 || right > 0) ? 1 : 0;
- }
- if ((res = kctl->put(kctl, uctl)) < 0)
- goto __unalloc;
- if (res > 0)
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
- __unalloc:
- up_read(&card->controls_rwsem);
- kfree(uctl);
- kfree(uinfo);
-}
-
-static int snd_mixer_oss_put_volume1(struct snd_mixer_oss_file *fmixer,
- struct snd_mixer_oss_slot *pslot,
- int left, int right)
-{
- struct slot *slot = pslot->private_data;
-
- if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) {
- snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right);
- if (slot->present & SNDRV_MIXER_OSS_PRESENT_CVOLUME)
- snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CVOLUME], left, right);
- } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_CVOLUME) {
- snd_mixer_oss_put_volume1_vol(fmixer, pslot,
- slot->numid[SNDRV_MIXER_OSS_ITEM_CVOLUME], left, right);
- } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GVOLUME) {
- snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GVOLUME], left, right);
- } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GLOBAL) {
- snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GLOBAL], left, right);
- }
- if (left || right) {
- if (slot->present & SNDRV_MIXER_OSS_PRESENT_PSWITCH)
- snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PSWITCH], left, right, 0);
- if (slot->present & SNDRV_MIXER_OSS_PRESENT_CSWITCH)
- snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CSWITCH], left, right, 0);
- if (slot->present & SNDRV_MIXER_OSS_PRESENT_GSWITCH)
- snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GSWITCH], left, right, 0);
- if (slot->present & SNDRV_MIXER_OSS_PRESENT_PROUTE)
- snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PROUTE], left, right, 1);
- if (slot->present & SNDRV_MIXER_OSS_PRESENT_CROUTE)
- snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CROUTE], left, right, 1);
- if (slot->present & SNDRV_MIXER_OSS_PRESENT_GROUTE)
- snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GROUTE], left, right, 1);
- } else {
- if (slot->present & SNDRV_MIXER_OSS_PRESENT_PSWITCH) {
- snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PSWITCH], left, right, 0);
- } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_CSWITCH) {
- snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CSWITCH], left, right, 0);
- } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GSWITCH) {
- snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GSWITCH], left, right, 0);
- } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_PROUTE) {
- snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PROUTE], left, right, 1);
- } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_CROUTE) {
- snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CROUTE], left, right, 1);
- } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GROUTE) {
- snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GROUTE], left, right, 1);
- }
- }
- return 0;
-}
-
-static int snd_mixer_oss_get_recsrc1_sw(struct snd_mixer_oss_file *fmixer,
- struct snd_mixer_oss_slot *pslot,
- int *active)
-{
- struct slot *slot = pslot->private_data;
- int left, right;
-
- left = right = 1;
- snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CSWITCH], &left, &right, 0);
- *active = (left || right) ? 1 : 0;
- return 0;
-}
-
-static int snd_mixer_oss_get_recsrc1_route(struct snd_mixer_oss_file *fmixer,
- struct snd_mixer_oss_slot *pslot,
- int *active)
-{
- struct slot *slot = pslot->private_data;
- int left, right;
-
- left = right = 1;
- snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CROUTE], &left, &right, 1);
- *active = (left || right) ? 1 : 0;
- return 0;
-}
-
-static int snd_mixer_oss_put_recsrc1_sw(struct snd_mixer_oss_file *fmixer,
- struct snd_mixer_oss_slot *pslot,
- int active)
-{
- struct slot *slot = pslot->private_data;
-
- snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CSWITCH], active, active, 0);
- return 0;
-}
-
-static int snd_mixer_oss_put_recsrc1_route(struct snd_mixer_oss_file *fmixer,
- struct snd_mixer_oss_slot *pslot,
- int active)
-{
- struct slot *slot = pslot->private_data;
-
- snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CROUTE], active, active, 1);
- return 0;
-}
-
-static int snd_mixer_oss_get_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned int *active_index)
-{
- struct snd_card *card = fmixer->card;
- struct snd_mixer_oss *mixer = fmixer->mixer;
- struct snd_kcontrol *kctl;
- struct snd_mixer_oss_slot *pslot;
- struct slot *slot;
- struct snd_ctl_elem_info *uinfo;
- struct snd_ctl_elem_value *uctl;
- int err, idx;
-
- uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
- uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
- if (uinfo == NULL || uctl == NULL) {
- err = -ENOMEM;
- goto __free_only;
- }
- down_read(&card->controls_rwsem);
- kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
- if (! kctl) {
- err = -ENOENT;
- goto __unlock;
- }
- if ((err = kctl->info(kctl, uinfo)) < 0)
- goto __unlock;
- if ((err = kctl->get(kctl, uctl)) < 0)
- goto __unlock;
- for (idx = 0; idx < 32; idx++) {
- if (!(mixer->mask_recsrc & (1 << idx)))
- continue;
- pslot = &mixer->slots[idx];
- slot = pslot->private_data;
- if (slot->signature != SNDRV_MIXER_OSS_SIGNATURE)
- continue;
- if (!(slot->present & SNDRV_MIXER_OSS_PRESENT_CAPTURE))
- continue;
- if (slot->capture_item == uctl->value.enumerated.item[0]) {
- *active_index = idx;
- break;
- }
- }
- err = 0;
- __unlock:
- up_read(&card->controls_rwsem);
- __free_only:
- kfree(uctl);
- kfree(uinfo);
- return err;
-}
-
-static int snd_mixer_oss_put_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned int active_index)
-{
- struct snd_card *card = fmixer->card;
- struct snd_mixer_oss *mixer = fmixer->mixer;
- struct snd_kcontrol *kctl;
- struct snd_mixer_oss_slot *pslot;
- struct slot *slot = NULL;
- struct snd_ctl_elem_info *uinfo;
- struct snd_ctl_elem_value *uctl;
- int err;
- unsigned int idx;
-
- uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
- uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
- if (uinfo == NULL || uctl == NULL) {
- err = -ENOMEM;
- goto __free_only;
- }
- down_read(&card->controls_rwsem);
- kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
- if (! kctl) {
- err = -ENOENT;
- goto __unlock;
- }
- if ((err = kctl->info(kctl, uinfo)) < 0)
- goto __unlock;
- for (idx = 0; idx < 32; idx++) {
- if (!(mixer->mask_recsrc & (1 << idx)))
- continue;
- pslot = &mixer->slots[idx];
- slot = pslot->private_data;
- if (slot->signature != SNDRV_MIXER_OSS_SIGNATURE)
- continue;
- if (!(slot->present & SNDRV_MIXER_OSS_PRESENT_CAPTURE))
- continue;
- if (idx == active_index)
- break;
- slot = NULL;
- }
- if (! slot)
- goto __unlock;
- for (idx = 0; idx < uinfo->count; idx++)
- uctl->value.enumerated.item[idx] = slot->capture_item;
- err = kctl->put(kctl, uctl);
- if (err > 0)
- snd_ctl_notify(fmixer->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
- err = 0;
- __unlock:
- up_read(&card->controls_rwsem);
- __free_only:
- kfree(uctl);
- kfree(uinfo);
- return err;
-}
-
-struct snd_mixer_oss_assign_table {
- int oss_id;
- const char *name;
- int index;
-};
-
-static int snd_mixer_oss_build_test(struct snd_mixer_oss *mixer, struct slot *slot, const char *name, int index, int item)
-{
- struct snd_ctl_elem_info *info;
- struct snd_kcontrol *kcontrol;
- struct snd_card *card = mixer->card;
- int err;
-
- down_read(&card->controls_rwsem);
- kcontrol = snd_mixer_oss_test_id(mixer, name, index);
- if (kcontrol == NULL) {
- up_read(&card->controls_rwsem);
- return 0;
- }
- info = kmalloc(sizeof(*info), GFP_KERNEL);
- if (! info) {
- up_read(&card->controls_rwsem);
- return -ENOMEM;
- }
- if ((err = kcontrol->info(kcontrol, info)) < 0) {
- up_read(&card->controls_rwsem);
- kfree(info);
- return err;
- }
- slot->numid[item] = kcontrol->id.numid;
- up_read(&card->controls_rwsem);
- if (info->count > slot->channels)
- slot->channels = info->count;
- slot->present |= 1 << item;
- kfree(info);
- return 0;
-}
-
-static void snd_mixer_oss_slot_free(struct snd_mixer_oss_slot *chn)
-{
- struct slot *p = chn->private_data;
- if (p) {
- if (p->allocated && p->assigned) {
- kfree(p->assigned->name);
- kfree(p->assigned);
- }
- kfree(p);
- }
-}
-
-static void mixer_slot_clear(struct snd_mixer_oss_slot *rslot)
-{
- int idx = rslot->number; /* remember this */
- if (rslot->private_free)
- rslot->private_free(rslot);
- memset(rslot, 0, sizeof(*rslot));
- rslot->number = idx;
-}
-
-/* In a separate function to keep gcc 3.2 happy - do NOT merge this in
- snd_mixer_oss_build_input! */
-static int snd_mixer_oss_build_test_all(struct snd_mixer_oss *mixer,
- struct snd_mixer_oss_assign_table *ptr,
- struct slot *slot)
-{
- char str[64];
- int err;
-
- err = snd_mixer_oss_build_test(mixer, slot, ptr->name, ptr->index,
- SNDRV_MIXER_OSS_ITEM_GLOBAL);
- if (err)
- return err;
- sprintf(str, "%s Switch", ptr->name);
- err = snd_mixer_oss_build_test(mixer, slot, str, ptr->index,
- SNDRV_MIXER_OSS_ITEM_GSWITCH);
- if (err)
- return err;
- sprintf(str, "%s Route", ptr->name);
- err = snd_mixer_oss_build_test(mixer, slot, str, ptr->index,
- SNDRV_MIXER_OSS_ITEM_GROUTE);
- if (err)
- return err;
- sprintf(str, "%s Volume", ptr->name);
- err = snd_mixer_oss_build_test(mixer, slot, str, ptr->index,
- SNDRV_MIXER_OSS_ITEM_GVOLUME);
- if (err)
- return err;
- sprintf(str, "%s Playback Switch", ptr->name);
- err = snd_mixer_oss_build_test(mixer, slot, str, ptr->index,
- SNDRV_MIXER_OSS_ITEM_PSWITCH);
- if (err)
- return err;
- sprintf(str, "%s Playback Route", ptr->name);
- err = snd_mixer_oss_build_test(mixer, slot, str, ptr->index,
- SNDRV_MIXER_OSS_ITEM_PROUTE);
- if (err)
- return err;
- sprintf(str, "%s Playback Volume", ptr->name);
- err = snd_mixer_oss_build_test(mixer, slot, str, ptr->index,
- SNDRV_MIXER_OSS_ITEM_PVOLUME);
- if (err)
- return err;
- sprintf(str, "%s Capture Switch", ptr->name);
- err = snd_mixer_oss_build_test(mixer, slot, str, ptr->index,
- SNDRV_MIXER_OSS_ITEM_CSWITCH);
- if (err)
- return err;
- sprintf(str, "%s Capture Route", ptr->name);
- err = snd_mixer_oss_build_test(mixer, slot, str, ptr->index,
- SNDRV_MIXER_OSS_ITEM_CROUTE);
- if (err)
- return err;
- sprintf(str, "%s Capture Volume", ptr->name);
- err = snd_mixer_oss_build_test(mixer, slot, str, ptr->index,
- SNDRV_MIXER_OSS_ITEM_CVOLUME);
- if (err)
- return err;
-
- return 0;
-}
-
-/*
- * build an OSS mixer element.
- * ptr_allocated means the entry is dynamically allocated (change via proc file).
- * when replace_old = 1, the old entry is replaced with the new one.
- */
-static int snd_mixer_oss_build_input(struct snd_mixer_oss *mixer, struct snd_mixer_oss_assign_table *ptr, int ptr_allocated, int replace_old)
-{
- struct slot slot;
- struct slot *pslot;
- struct snd_kcontrol *kctl;
- struct snd_mixer_oss_slot *rslot;
- char str[64];
-
- /* check if already assigned */
- if (mixer->slots[ptr->oss_id].get_volume && ! replace_old)
- return 0;
-
- memset(&slot, 0, sizeof(slot));
- memset(slot.numid, 0xff, sizeof(slot.numid)); /* ID_UNKNOWN */
- if (snd_mixer_oss_build_test_all(mixer, ptr, &slot))
- return 0;
- down_read(&mixer->card->controls_rwsem);
- if (ptr->index == 0 && (kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0)) != NULL) {
- struct snd_ctl_elem_info *uinfo;
-
- uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
- if (! uinfo) {
- up_read(&mixer->card->controls_rwsem);
- return -ENOMEM;
- }
-
- if (kctl->info(kctl, uinfo)) {
- up_read(&mixer->card->controls_rwsem);
- return 0;
- }
- strcpy(str, ptr->name);
- if (!strcmp(str, "Master"))
- strcpy(str, "Mix");
- if (!strcmp(str, "Master Mono"))
- strcpy(str, "Mix Mono");
- slot.capture_item = 0;
- if (!strcmp(uinfo->value.enumerated.name, str)) {
- slot.present |= SNDRV_MIXER_OSS_PRESENT_CAPTURE;
- } else {
- for (slot.capture_item = 1; slot.capture_item < uinfo->value.enumerated.items; slot.capture_item++) {
- uinfo->value.enumerated.item = slot.capture_item;
- if (kctl->info(kctl, uinfo)) {
- up_read(&mixer->card->controls_rwsem);
- return 0;
- }
- if (!strcmp(uinfo->value.enumerated.name, str)) {
- slot.present |= SNDRV_MIXER_OSS_PRESENT_CAPTURE;
- break;
- }
- }
- }
- kfree(uinfo);
- }
- up_read(&mixer->card->controls_rwsem);
- if (slot.present != 0) {
- pslot = kmalloc(sizeof(slot), GFP_KERNEL);
- if (! pslot)
- return -ENOMEM;
- *pslot = slot;
- pslot->signature = SNDRV_MIXER_OSS_SIGNATURE;
- pslot->assigned = ptr;
- pslot->allocated = ptr_allocated;
- rslot = &mixer->slots[ptr->oss_id];
- mixer_slot_clear(rslot);
- rslot->stereo = slot.channels > 1 ? 1 : 0;
- rslot->get_volume = snd_mixer_oss_get_volume1;
- rslot->put_volume = snd_mixer_oss_put_volume1;
- /* note: ES18xx have both Capture Source and XX Capture Volume !!! */
- if (slot.present & SNDRV_MIXER_OSS_PRESENT_CSWITCH) {
- rslot->get_recsrc = snd_mixer_oss_get_recsrc1_sw;
- rslot->put_recsrc = snd_mixer_oss_put_recsrc1_sw;
- } else if (slot.present & SNDRV_MIXER_OSS_PRESENT_CROUTE) {
- rslot->get_recsrc = snd_mixer_oss_get_recsrc1_route;
- rslot->put_recsrc = snd_mixer_oss_put_recsrc1_route;
- } else if (slot.present & SNDRV_MIXER_OSS_PRESENT_CAPTURE) {
- mixer->mask_recsrc |= 1 << ptr->oss_id;
- }
- rslot->private_data = pslot;
- rslot->private_free = snd_mixer_oss_slot_free;
- return 1;
- }
- return 0;
-}
-
-#ifdef CONFIG_PROC_FS
-/*
- */
-#define MIXER_VOL(name) [SOUND_MIXER_##name] = #name
-static char *oss_mixer_names[SNDRV_OSS_MAX_MIXERS] = {
- MIXER_VOL(VOLUME),
- MIXER_VOL(BASS),
- MIXER_VOL(TREBLE),
- MIXER_VOL(SYNTH),
- MIXER_VOL(PCM),
- MIXER_VOL(SPEAKER),
- MIXER_VOL(LINE),
- MIXER_VOL(MIC),
- MIXER_VOL(CD),
- MIXER_VOL(IMIX),
- MIXER_VOL(ALTPCM),
- MIXER_VOL(RECLEV),
- MIXER_VOL(IGAIN),
- MIXER_VOL(OGAIN),
- MIXER_VOL(LINE1),
- MIXER_VOL(LINE2),
- MIXER_VOL(LINE3),
- MIXER_VOL(DIGITAL1),
- MIXER_VOL(DIGITAL2),
- MIXER_VOL(DIGITAL3),
- MIXER_VOL(PHONEIN),
- MIXER_VOL(PHONEOUT),
- MIXER_VOL(VIDEO),
- MIXER_VOL(RADIO),
- MIXER_VOL(MONITOR),
-};
-
-/*
- * /proc interface
- */
-
-static void snd_mixer_oss_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_mixer_oss *mixer = entry->private_data;
- int i;
-
- mutex_lock(&mixer->reg_mutex);
- for (i = 0; i < SNDRV_OSS_MAX_MIXERS; i++) {
- struct slot *p;
-
- if (! oss_mixer_names[i])
- continue;
- p = (struct slot *)mixer->slots[i].private_data;
- snd_iprintf(buffer, "%s ", oss_mixer_names[i]);
- if (p && p->assigned)
- snd_iprintf(buffer, "\"%s\" %d\n",
- p->assigned->name,
- p->assigned->index);
- else
- snd_iprintf(buffer, "\"\" 0\n");
- }
- mutex_unlock(&mixer->reg_mutex);
-}
-
-static void snd_mixer_oss_proc_write(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_mixer_oss *mixer = entry->private_data;
- char line[128], str[32], idxstr[16];
- const char *cptr;
- int ch, idx;
- struct snd_mixer_oss_assign_table *tbl;
- struct slot *slot;
-
- while (!snd_info_get_line(buffer, line, sizeof(line))) {
- cptr = snd_info_get_str(str, line, sizeof(str));
- for (ch = 0; ch < SNDRV_OSS_MAX_MIXERS; ch++)
- if (oss_mixer_names[ch] && strcmp(oss_mixer_names[ch], str) == 0)
- break;
- if (ch >= SNDRV_OSS_MAX_MIXERS) {
- snd_printk(KERN_ERR "mixer_oss: invalid OSS volume '%s'\n", str);
- continue;
- }
- cptr = snd_info_get_str(str, cptr, sizeof(str));
- if (! *str) {
- /* remove the entry */
- mutex_lock(&mixer->reg_mutex);
- mixer_slot_clear(&mixer->slots[ch]);
- mutex_unlock(&mixer->reg_mutex);
- continue;
- }
- snd_info_get_str(idxstr, cptr, sizeof(idxstr));
- idx = simple_strtoul(idxstr, NULL, 10);
- if (idx >= 0x4000) { /* too big */
- snd_printk(KERN_ERR "mixer_oss: invalid index %d\n", idx);
- continue;
- }
- mutex_lock(&mixer->reg_mutex);
- slot = (struct slot *)mixer->slots[ch].private_data;
- if (slot && slot->assigned &&
- slot->assigned->index == idx && ! strcmp(slot->assigned->name, str))
- /* not changed */
- goto __unlock;
- tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
- if (! tbl) {
- snd_printk(KERN_ERR "mixer_oss: no memory\n");
- goto __unlock;
- }
- tbl->oss_id = ch;
- tbl->name = kstrdup(str, GFP_KERNEL);
- if (! tbl->name) {
- kfree(tbl);
- goto __unlock;
- }
- tbl->index = idx;
- if (snd_mixer_oss_build_input(mixer, tbl, 1, 1) <= 0) {
- kfree(tbl->name);
- kfree(tbl);
- }
- __unlock:
- mutex_unlock(&mixer->reg_mutex);
- }
-}
-
-static void snd_mixer_oss_proc_init(struct snd_mixer_oss *mixer)
-{
- struct snd_info_entry *entry;
-
- entry = snd_info_create_card_entry(mixer->card, "oss_mixer",
- mixer->card->proc_root);
- if (! entry)
- return;
- entry->content = SNDRV_INFO_CONTENT_TEXT;
- entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
- entry->c.text.read = snd_mixer_oss_proc_read;
- entry->c.text.write = snd_mixer_oss_proc_write;
- entry->private_data = mixer;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- mixer->proc_entry = entry;
-}
-
-static void snd_mixer_oss_proc_done(struct snd_mixer_oss *mixer)
-{
- snd_info_free_entry(mixer->proc_entry);
- mixer->proc_entry = NULL;
-}
-#else /* !CONFIG_PROC_FS */
-#define snd_mixer_oss_proc_init(mix)
-#define snd_mixer_oss_proc_done(mix)
-#endif /* CONFIG_PROC_FS */
-
-static void snd_mixer_oss_build(struct snd_mixer_oss *mixer)
-{
- static struct snd_mixer_oss_assign_table table[] = {
- { SOUND_MIXER_VOLUME, "Master", 0 },
- { SOUND_MIXER_VOLUME, "Front", 0 }, /* fallback */
- { SOUND_MIXER_BASS, "Tone Control - Bass", 0 },
- { SOUND_MIXER_TREBLE, "Tone Control - Treble", 0 },
- { SOUND_MIXER_SYNTH, "Synth", 0 },
- { SOUND_MIXER_SYNTH, "FM", 0 }, /* fallback */
- { SOUND_MIXER_SYNTH, "Music", 0 }, /* fallback */
- { SOUND_MIXER_PCM, "PCM", 0 },
- { SOUND_MIXER_SPEAKER, "Beep", 0 },
- { SOUND_MIXER_SPEAKER, "PC Speaker", 0 }, /* fallback */
- { SOUND_MIXER_SPEAKER, "Speaker", 0 }, /* fallback */
- { SOUND_MIXER_LINE, "Line", 0 },
- { SOUND_MIXER_MIC, "Mic", 0 },
- { SOUND_MIXER_CD, "CD", 0 },
- { SOUND_MIXER_IMIX, "Monitor Mix", 0 },
- { SOUND_MIXER_ALTPCM, "PCM", 1 },
- { SOUND_MIXER_ALTPCM, "Headphone", 0 }, /* fallback */
- { SOUND_MIXER_ALTPCM, "Wave", 0 }, /* fallback */
- { SOUND_MIXER_RECLEV, "-- nothing --", 0 },
- { SOUND_MIXER_IGAIN, "Capture", 0 },
- { SOUND_MIXER_OGAIN, "Playback", 0 },
- { SOUND_MIXER_LINE1, "Aux", 0 },
- { SOUND_MIXER_LINE2, "Aux", 1 },
- { SOUND_MIXER_LINE3, "Aux", 2 },
- { SOUND_MIXER_DIGITAL1, "Digital", 0 },
- { SOUND_MIXER_DIGITAL1, "IEC958", 0 }, /* fallback */
- { SOUND_MIXER_DIGITAL1, "IEC958 Optical", 0 }, /* fallback */
- { SOUND_MIXER_DIGITAL1, "IEC958 Coaxial", 0 }, /* fallback */
- { SOUND_MIXER_DIGITAL2, "Digital", 1 },
- { SOUND_MIXER_DIGITAL3, "Digital", 2 },
- { SOUND_MIXER_PHONEIN, "Phone", 0 },
- { SOUND_MIXER_PHONEOUT, "Master Mono", 0 },
- { SOUND_MIXER_PHONEOUT, "Speaker", 0 }, /*fallback*/
- { SOUND_MIXER_PHONEOUT, "Mono", 0 }, /*fallback*/
- { SOUND_MIXER_PHONEOUT, "Phone", 0 }, /* fallback */
- { SOUND_MIXER_VIDEO, "Video", 0 },
- { SOUND_MIXER_RADIO, "Radio", 0 },
- { SOUND_MIXER_MONITOR, "Monitor", 0 }
- };
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(table); idx++)
- snd_mixer_oss_build_input(mixer, &table[idx], 0, 0);
- if (mixer->mask_recsrc) {
- mixer->get_recsrc = snd_mixer_oss_get_recsrc2;
- mixer->put_recsrc = snd_mixer_oss_put_recsrc2;
- }
-}
-
-/*
- *
- */
-
-static int snd_mixer_oss_free1(void *private)
-{
- struct snd_mixer_oss *mixer = private;
- struct snd_card *card;
- int idx;
-
- if (!mixer)
- return 0;
- card = mixer->card;
- if (snd_BUG_ON(mixer != card->mixer_oss))
- return -ENXIO;
- card->mixer_oss = NULL;
- for (idx = 0; idx < SNDRV_OSS_MAX_MIXERS; idx++) {
- struct snd_mixer_oss_slot *chn = &mixer->slots[idx];
- if (chn->private_free)
- chn->private_free(chn);
- }
- kfree(mixer);
- return 0;
-}
-
-static int snd_mixer_oss_notify_handler(struct snd_card *card, int cmd)
-{
- struct snd_mixer_oss *mixer;
-
- if (cmd == SND_MIXER_OSS_NOTIFY_REGISTER) {
- char name[128];
- int idx, err;
-
- mixer = kcalloc(2, sizeof(*mixer), GFP_KERNEL);
- if (mixer == NULL)
- return -ENOMEM;
- mutex_init(&mixer->reg_mutex);
- sprintf(name, "mixer%i%i", card->number, 0);
- if ((err = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER,
- card, 0,
- &snd_mixer_oss_f_ops, card,
- name)) < 0) {
- snd_printk(KERN_ERR "unable to register OSS mixer device %i:%i\n",
- card->number, 0);
- kfree(mixer);
- return err;
- }
- mixer->oss_dev_alloc = 1;
- mixer->card = card;
- if (*card->mixername)
- strlcpy(mixer->name, card->mixername, sizeof(mixer->name));
- else
- strlcpy(mixer->name, name, sizeof(mixer->name));
-#ifdef SNDRV_OSS_INFO_DEV_MIXERS
- snd_oss_info_register(SNDRV_OSS_INFO_DEV_MIXERS,
- card->number,
- mixer->name);
-#endif
- for (idx = 0; idx < SNDRV_OSS_MAX_MIXERS; idx++)
- mixer->slots[idx].number = idx;
- card->mixer_oss = mixer;
- snd_mixer_oss_build(mixer);
- snd_mixer_oss_proc_init(mixer);
- } else {
- mixer = card->mixer_oss;
- if (mixer == NULL)
- return 0;
- if (mixer->oss_dev_alloc) {
-#ifdef SNDRV_OSS_INFO_DEV_MIXERS
- snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_MIXERS, mixer->card->number);
-#endif
- snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER, mixer->card, 0);
- mixer->oss_dev_alloc = 0;
- }
- if (cmd == SND_MIXER_OSS_NOTIFY_DISCONNECT)
- return 0;
- snd_mixer_oss_proc_done(mixer);
- return snd_mixer_oss_free1(mixer);
- }
- return 0;
-}
-
-static int __init alsa_mixer_oss_init(void)
-{
- int idx;
-
- snd_mixer_oss_notify_callback = snd_mixer_oss_notify_handler;
- for (idx = 0; idx < SNDRV_CARDS; idx++) {
- if (snd_cards[idx])
- snd_mixer_oss_notify_handler(snd_cards[idx], SND_MIXER_OSS_NOTIFY_REGISTER);
- }
- return 0;
-}
-
-static void __exit alsa_mixer_oss_exit(void)
-{
- int idx;
-
- snd_mixer_oss_notify_callback = NULL;
- for (idx = 0; idx < SNDRV_CARDS; idx++) {
- if (snd_cards[idx])
- snd_mixer_oss_notify_handler(snd_cards[idx], SND_MIXER_OSS_NOTIFY_FREE);
- }
-}
-
-module_init(alsa_mixer_oss_init)
-module_exit(alsa_mixer_oss_exit)
-
-EXPORT_SYMBOL(snd_mixer_oss_ioctl_card);
diff --git a/ANDROID_3.4.5/sound/core/oss/mulaw.c b/ANDROID_3.4.5/sound/core/oss/mulaw.c
deleted file mode 100644
index 7915564b..00000000
--- a/ANDROID_3.4.5/sound/core/oss/mulaw.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Mu-Law conversion Plug-In Interface
- * Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
- * Uros Bizjak <uros@kss-loka.si>
- *
- * Based on reference implementation by Sun Microsystems, Inc.
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include "pcm_plugin.h"
-
-#define SIGN_BIT (0x80) /* Sign bit for a u-law byte. */
-#define QUANT_MASK (0xf) /* Quantization field mask. */
-#define NSEGS (8) /* Number of u-law segments. */
-#define SEG_SHIFT (4) /* Left shift for segment number. */
-#define SEG_MASK (0x70) /* Segment field mask. */
-
-static inline int val_seg(int val)
-{
- int r = 0;
- val >>= 7;
- if (val & 0xf0) {
- val >>= 4;
- r += 4;
- }
- if (val & 0x0c) {
- val >>= 2;
- r += 2;
- }
- if (val & 0x02)
- r += 1;
- return r;
-}
-
-#define BIAS (0x84) /* Bias for linear code. */
-
-/*
- * linear2ulaw() - Convert a linear PCM value to u-law
- *
- * In order to simplify the encoding process, the original linear magnitude
- * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
- * (33 - 8191). The result can be seen in the following encoding table:
- *
- * Biased Linear Input Code Compressed Code
- * ------------------------ ---------------
- * 00000001wxyza 000wxyz
- * 0000001wxyzab 001wxyz
- * 000001wxyzabc 010wxyz
- * 00001wxyzabcd 011wxyz
- * 0001wxyzabcde 100wxyz
- * 001wxyzabcdef 101wxyz
- * 01wxyzabcdefg 110wxyz
- * 1wxyzabcdefgh 111wxyz
- *
- * Each biased linear code has a leading 1 which identifies the segment
- * number. The value of the segment number is equal to 7 minus the number
- * of leading 0's. The quantization interval is directly available as the
- * four bits wxyz. * The trailing bits (a - h) are ignored.
- *
- * Ordinarily the complement of the resulting code word is used for
- * transmission, and so the code word is complemented before it is returned.
- *
- * For further information see John C. Bellamy's Digital Telephony, 1982,
- * John Wiley & Sons, pps 98-111 and 472-476.
- */
-static unsigned char linear2ulaw(int pcm_val) /* 2's complement (16-bit range) */
-{
- int mask;
- int seg;
- unsigned char uval;
-
- /* Get the sign and the magnitude of the value. */
- if (pcm_val < 0) {
- pcm_val = BIAS - pcm_val;
- mask = 0x7F;
- } else {
- pcm_val += BIAS;
- mask = 0xFF;
- }
- if (pcm_val > 0x7FFF)
- pcm_val = 0x7FFF;
-
- /* Convert the scaled magnitude to segment number. */
- seg = val_seg(pcm_val);
-
- /*
- * Combine the sign, segment, quantization bits;
- * and complement the code word.
- */
- uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
- return uval ^ mask;
-}
-
-/*
- * ulaw2linear() - Convert a u-law value to 16-bit linear PCM
- *
- * First, a biased linear code is derived from the code word. An unbiased
- * output can then be obtained by subtracting 33 from the biased code.
- *
- * Note that this function expects to be passed the complement of the
- * original code word. This is in keeping with ISDN conventions.
- */
-static int ulaw2linear(unsigned char u_val)
-{
- int t;
-
- /* Complement to obtain normal u-law value. */
- u_val = ~u_val;
-
- /*
- * Extract and bias the quantization bits. Then
- * shift up by the segment number and subtract out the bias.
- */
- t = ((u_val & QUANT_MASK) << 3) + BIAS;
- t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
-
- return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
-}
-
-/*
- * Basic Mu-Law plugin
- */
-
-typedef void (*mulaw_f)(struct snd_pcm_plugin *plugin,
- const struct snd_pcm_plugin_channel *src_channels,
- struct snd_pcm_plugin_channel *dst_channels,
- snd_pcm_uframes_t frames);
-
-struct mulaw_priv {
- mulaw_f func;
- int cvt_endian; /* need endian conversion? */
- unsigned int native_ofs; /* byte offset in native format */
- unsigned int copy_ofs; /* byte offset in s16 format */
- unsigned int native_bytes; /* byte size of the native format */
- unsigned int copy_bytes; /* bytes to copy per conversion */
- u16 flip; /* MSB flip for signedness, done after endian conversion */
-};
-
-static inline void cvt_s16_to_native(struct mulaw_priv *data,
- unsigned char *dst, u16 sample)
-{
- sample ^= data->flip;
- if (data->cvt_endian)
- sample = swab16(sample);
- if (data->native_bytes > data->copy_bytes)
- memset(dst, 0, data->native_bytes);
- memcpy(dst + data->native_ofs, (char *)&sample + data->copy_ofs,
- data->copy_bytes);
-}
-
-static void mulaw_decode(struct snd_pcm_plugin *plugin,
- const struct snd_pcm_plugin_channel *src_channels,
- struct snd_pcm_plugin_channel *dst_channels,
- snd_pcm_uframes_t frames)
-{
- struct mulaw_priv *data = (struct mulaw_priv *)plugin->extra_data;
- int channel;
- int nchannels = plugin->src_format.channels;
- for (channel = 0; channel < nchannels; ++channel) {
- char *src;
- char *dst;
- int src_step, dst_step;
- snd_pcm_uframes_t frames1;
- if (!src_channels[channel].enabled) {
- if (dst_channels[channel].wanted)
- snd_pcm_area_silence(&dst_channels[channel].area, 0, frames, plugin->dst_format.format);
- dst_channels[channel].enabled = 0;
- continue;
- }
- dst_channels[channel].enabled = 1;
- src = src_channels[channel].area.addr + src_channels[channel].area.first / 8;
- dst = dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
- src_step = src_channels[channel].area.step / 8;
- dst_step = dst_channels[channel].area.step / 8;
- frames1 = frames;
- while (frames1-- > 0) {
- signed short sample = ulaw2linear(*src);
- cvt_s16_to_native(data, dst, sample);
- src += src_step;
- dst += dst_step;
- }
- }
-}
-
-static inline signed short cvt_native_to_s16(struct mulaw_priv *data,
- unsigned char *src)
-{
- u16 sample = 0;
- memcpy((char *)&sample + data->copy_ofs, src + data->native_ofs,
- data->copy_bytes);
- if (data->cvt_endian)
- sample = swab16(sample);
- sample ^= data->flip;
- return (signed short)sample;
-}
-
-static void mulaw_encode(struct snd_pcm_plugin *plugin,
- const struct snd_pcm_plugin_channel *src_channels,
- struct snd_pcm_plugin_channel *dst_channels,
- snd_pcm_uframes_t frames)
-{
- struct mulaw_priv *data = (struct mulaw_priv *)plugin->extra_data;
- int channel;
- int nchannels = plugin->src_format.channels;
- for (channel = 0; channel < nchannels; ++channel) {
- char *src;
- char *dst;
- int src_step, dst_step;
- snd_pcm_uframes_t frames1;
- if (!src_channels[channel].enabled) {
- if (dst_channels[channel].wanted)
- snd_pcm_area_silence(&dst_channels[channel].area, 0, frames, plugin->dst_format.format);
- dst_channels[channel].enabled = 0;
- continue;
- }
- dst_channels[channel].enabled = 1;
- src = src_channels[channel].area.addr + src_channels[channel].area.first / 8;
- dst = dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
- src_step = src_channels[channel].area.step / 8;
- dst_step = dst_channels[channel].area.step / 8;
- frames1 = frames;
- while (frames1-- > 0) {
- signed short sample = cvt_native_to_s16(data, src);
- *dst = linear2ulaw(sample);
- src += src_step;
- dst += dst_step;
- }
- }
-}
-
-static snd_pcm_sframes_t mulaw_transfer(struct snd_pcm_plugin *plugin,
- const struct snd_pcm_plugin_channel *src_channels,
- struct snd_pcm_plugin_channel *dst_channels,
- snd_pcm_uframes_t frames)
-{
- struct mulaw_priv *data;
-
- if (snd_BUG_ON(!plugin || !src_channels || !dst_channels))
- return -ENXIO;
- if (frames == 0)
- return 0;
-#ifdef CONFIG_SND_DEBUG
- {
- unsigned int channel;
- for (channel = 0; channel < plugin->src_format.channels; channel++) {
- if (snd_BUG_ON(src_channels[channel].area.first % 8 ||
- src_channels[channel].area.step % 8))
- return -ENXIO;
- if (snd_BUG_ON(dst_channels[channel].area.first % 8 ||
- dst_channels[channel].area.step % 8))
- return -ENXIO;
- }
- }
-#endif
- data = (struct mulaw_priv *)plugin->extra_data;
- data->func(plugin, src_channels, dst_channels, frames);
- return frames;
-}
-
-static void init_data(struct mulaw_priv *data, snd_pcm_format_t format)
-{
-#ifdef SNDRV_LITTLE_ENDIAN
- data->cvt_endian = snd_pcm_format_big_endian(format) > 0;
-#else
- data->cvt_endian = snd_pcm_format_little_endian(format) > 0;
-#endif
- if (!snd_pcm_format_signed(format))
- data->flip = 0x8000;
- data->native_bytes = snd_pcm_format_physical_width(format) / 8;
- data->copy_bytes = data->native_bytes < 2 ? 1 : 2;
- if (snd_pcm_format_little_endian(format)) {
- data->native_ofs = data->native_bytes - data->copy_bytes;
- data->copy_ofs = 2 - data->copy_bytes;
- } else {
- /* S24 in 4bytes need an 1 byte offset */
- data->native_ofs = data->native_bytes -
- snd_pcm_format_width(format) / 8;
- }
-}
-
-int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug,
- struct snd_pcm_plugin_format *src_format,
- struct snd_pcm_plugin_format *dst_format,
- struct snd_pcm_plugin **r_plugin)
-{
- int err;
- struct mulaw_priv *data;
- struct snd_pcm_plugin *plugin;
- struct snd_pcm_plugin_format *format;
- mulaw_f func;
-
- if (snd_BUG_ON(!r_plugin))
- return -ENXIO;
- *r_plugin = NULL;
-
- if (snd_BUG_ON(src_format->rate != dst_format->rate))
- return -ENXIO;
- if (snd_BUG_ON(src_format->channels != dst_format->channels))
- return -ENXIO;
-
- if (dst_format->format == SNDRV_PCM_FORMAT_MU_LAW) {
- format = src_format;
- func = mulaw_encode;
- }
- else if (src_format->format == SNDRV_PCM_FORMAT_MU_LAW) {
- format = dst_format;
- func = mulaw_decode;
- }
- else {
- snd_BUG();
- return -EINVAL;
- }
- if (snd_BUG_ON(!snd_pcm_format_linear(format->format)))
- return -ENXIO;
-
- err = snd_pcm_plugin_build(plug, "Mu-Law<->linear conversion",
- src_format, dst_format,
- sizeof(struct mulaw_priv), &plugin);
- if (err < 0)
- return err;
- data = (struct mulaw_priv *)plugin->extra_data;
- data->func = func;
- init_data(data, format->format);
- plugin->transfer = mulaw_transfer;
- *r_plugin = plugin;
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/core/oss/pcm_oss.c b/ANDROID_3.4.5/sound/core/oss/pcm_oss.c
deleted file mode 100644
index 4c1cc517..00000000
--- a/ANDROID_3.4.5/sound/core/oss/pcm_oss.c
+++ /dev/null
@@ -1,3117 +0,0 @@
-/*
- * Digital Audio (PCM) abstract layer / OSS compatible
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#if 0
-#define PLUGIN_DEBUG
-#endif
-#if 0
-#define OSS_DEBUG
-#endif
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/vmalloc.h>
-#include <linux/module.h>
-#include <linux/math64.h>
-#include <linux/string.h>
-#include <sound/core.h>
-#include <sound/minors.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include "pcm_plugin.h"
-#include <sound/info.h>
-#include <linux/soundcard.h>
-#include <sound/initval.h>
-#include <sound/mixer_oss.h>
-
-#define OSS_ALSAEMULVER _SIOR ('M', 249, int)
-
-static int dsp_map[SNDRV_CARDS];
-static int adsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
-static bool nonblock_open = 1;
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Abramo Bagnara <abramo@alsa-project.org>");
-MODULE_DESCRIPTION("PCM OSS emulation for ALSA.");
-MODULE_LICENSE("GPL");
-module_param_array(dsp_map, int, NULL, 0444);
-MODULE_PARM_DESC(dsp_map, "PCM device number assigned to 1st OSS device.");
-module_param_array(adsp_map, int, NULL, 0444);
-MODULE_PARM_DESC(adsp_map, "PCM device number assigned to 2nd OSS device.");
-module_param(nonblock_open, bool, 0644);
-MODULE_PARM_DESC(nonblock_open, "Don't block opening busy PCM devices.");
-MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_PCM);
-MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_PCM1);
-
-static int snd_pcm_oss_get_rate(struct snd_pcm_oss_file *pcm_oss_file);
-static int snd_pcm_oss_get_channels(struct snd_pcm_oss_file *pcm_oss_file);
-static int snd_pcm_oss_get_format(struct snd_pcm_oss_file *pcm_oss_file);
-
-static inline mm_segment_t snd_enter_user(void)
-{
- mm_segment_t fs = get_fs();
- set_fs(get_ds());
- return fs;
-}
-
-static inline void snd_leave_user(mm_segment_t fs)
-{
- set_fs(fs);
-}
-
-/*
- * helper functions to process hw_params
- */
-static int snd_interval_refine_min(struct snd_interval *i, unsigned int min, int openmin)
-{
- int changed = 0;
- if (i->min < min) {
- i->min = min;
- i->openmin = openmin;
- changed = 1;
- } else if (i->min == min && !i->openmin && openmin) {
- i->openmin = 1;
- changed = 1;
- }
- if (i->integer) {
- if (i->openmin) {
- i->min++;
- i->openmin = 0;
- }
- }
- if (snd_interval_checkempty(i)) {
- snd_interval_none(i);
- return -EINVAL;
- }
- return changed;
-}
-
-static int snd_interval_refine_max(struct snd_interval *i, unsigned int max, int openmax)
-{
- int changed = 0;
- if (i->max > max) {
- i->max = max;
- i->openmax = openmax;
- changed = 1;
- } else if (i->max == max && !i->openmax && openmax) {
- i->openmax = 1;
- changed = 1;
- }
- if (i->integer) {
- if (i->openmax) {
- i->max--;
- i->openmax = 0;
- }
- }
- if (snd_interval_checkempty(i)) {
- snd_interval_none(i);
- return -EINVAL;
- }
- return changed;
-}
-
-static int snd_interval_refine_set(struct snd_interval *i, unsigned int val)
-{
- struct snd_interval t;
- t.empty = 0;
- t.min = t.max = val;
- t.openmin = t.openmax = 0;
- t.integer = 1;
- return snd_interval_refine(i, &t);
-}
-
-/**
- * snd_pcm_hw_param_value_min
- * @params: the hw_params instance
- * @var: parameter to retrieve
- * @dir: pointer to the direction (-1,0,1) or NULL
- *
- * Return the minimum value for field PAR.
- */
-static unsigned int
-snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params,
- snd_pcm_hw_param_t var, int *dir)
-{
- if (hw_is_mask(var)) {
- if (dir)
- *dir = 0;
- return snd_mask_min(hw_param_mask_c(params, var));
- }
- if (hw_is_interval(var)) {
- const struct snd_interval *i = hw_param_interval_c(params, var);
- if (dir)
- *dir = i->openmin;
- return snd_interval_min(i);
- }
- return -EINVAL;
-}
-
-/**
- * snd_pcm_hw_param_value_max
- * @params: the hw_params instance
- * @var: parameter to retrieve
- * @dir: pointer to the direction (-1,0,1) or NULL
- *
- * Return the maximum value for field PAR.
- */
-static unsigned int
-snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params,
- snd_pcm_hw_param_t var, int *dir)
-{
- if (hw_is_mask(var)) {
- if (dir)
- *dir = 0;
- return snd_mask_max(hw_param_mask_c(params, var));
- }
- if (hw_is_interval(var)) {
- const struct snd_interval *i = hw_param_interval_c(params, var);
- if (dir)
- *dir = - (int) i->openmax;
- return snd_interval_max(i);
- }
- return -EINVAL;
-}
-
-static int _snd_pcm_hw_param_mask(struct snd_pcm_hw_params *params,
- snd_pcm_hw_param_t var,
- const struct snd_mask *val)
-{
- int changed;
- changed = snd_mask_refine(hw_param_mask(params, var), val);
- if (changed) {
- params->cmask |= 1 << var;
- params->rmask |= 1 << var;
- }
- return changed;
-}
-
-static int snd_pcm_hw_param_mask(struct snd_pcm_substream *pcm,
- struct snd_pcm_hw_params *params,
- snd_pcm_hw_param_t var,
- const struct snd_mask *val)
-{
- int changed = _snd_pcm_hw_param_mask(params, var, val);
- if (changed < 0)
- return changed;
- if (params->rmask) {
- int err = snd_pcm_hw_refine(pcm, params);
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-static int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params,
- snd_pcm_hw_param_t var, unsigned int val,
- int dir)
-{
- int changed;
- int open = 0;
- if (dir) {
- if (dir > 0) {
- open = 1;
- } else if (dir < 0) {
- if (val > 0) {
- open = 1;
- val--;
- }
- }
- }
- if (hw_is_mask(var))
- changed = snd_mask_refine_min(hw_param_mask(params, var),
- val + !!open);
- else if (hw_is_interval(var))
- changed = snd_interval_refine_min(hw_param_interval(params, var),
- val, open);
- else
- return -EINVAL;
- if (changed) {
- params->cmask |= 1 << var;
- params->rmask |= 1 << var;
- }
- return changed;
-}
-
-/**
- * snd_pcm_hw_param_min
- * @pcm: PCM instance
- * @params: the hw_params instance
- * @var: parameter to retrieve
- * @val: minimal value
- * @dir: pointer to the direction (-1,0,1) or NULL
- *
- * Inside configuration space defined by PARAMS remove from PAR all
- * values < VAL. Reduce configuration space accordingly.
- * Return new minimum or -EINVAL if the configuration space is empty
- */
-static int snd_pcm_hw_param_min(struct snd_pcm_substream *pcm,
- struct snd_pcm_hw_params *params,
- snd_pcm_hw_param_t var, unsigned int val,
- int *dir)
-{
- int changed = _snd_pcm_hw_param_min(params, var, val, dir ? *dir : 0);
- if (changed < 0)
- return changed;
- if (params->rmask) {
- int err = snd_pcm_hw_refine(pcm, params);
- if (err < 0)
- return err;
- }
- return snd_pcm_hw_param_value_min(params, var, dir);
-}
-
-static int _snd_pcm_hw_param_max(struct snd_pcm_hw_params *params,
- snd_pcm_hw_param_t var, unsigned int val,
- int dir)
-{
- int changed;
- int open = 0;
- if (dir) {
- if (dir < 0) {
- open = 1;
- } else if (dir > 0) {
- open = 1;
- val++;
- }
- }
- if (hw_is_mask(var)) {
- if (val == 0 && open) {
- snd_mask_none(hw_param_mask(params, var));
- changed = -EINVAL;
- } else
- changed = snd_mask_refine_max(hw_param_mask(params, var),
- val - !!open);
- } else if (hw_is_interval(var))
- changed = snd_interval_refine_max(hw_param_interval(params, var),
- val, open);
- else
- return -EINVAL;
- if (changed) {
- params->cmask |= 1 << var;
- params->rmask |= 1 << var;
- }
- return changed;
-}
-
-/**
- * snd_pcm_hw_param_max
- * @pcm: PCM instance
- * @params: the hw_params instance
- * @var: parameter to retrieve
- * @val: maximal value
- * @dir: pointer to the direction (-1,0,1) or NULL
- *
- * Inside configuration space defined by PARAMS remove from PAR all
- * values >= VAL + 1. Reduce configuration space accordingly.
- * Return new maximum or -EINVAL if the configuration space is empty
- */
-static int snd_pcm_hw_param_max(struct snd_pcm_substream *pcm,
- struct snd_pcm_hw_params *params,
- snd_pcm_hw_param_t var, unsigned int val,
- int *dir)
-{
- int changed = _snd_pcm_hw_param_max(params, var, val, dir ? *dir : 0);
- if (changed < 0)
- return changed;
- if (params->rmask) {
- int err = snd_pcm_hw_refine(pcm, params);
- if (err < 0)
- return err;
- }
- return snd_pcm_hw_param_value_max(params, var, dir);
-}
-
-static int boundary_sub(int a, int adir,
- int b, int bdir,
- int *c, int *cdir)
-{
- adir = adir < 0 ? -1 : (adir > 0 ? 1 : 0);
- bdir = bdir < 0 ? -1 : (bdir > 0 ? 1 : 0);
- *c = a - b;
- *cdir = adir - bdir;
- if (*cdir == -2) {
- (*c)--;
- } else if (*cdir == 2) {
- (*c)++;
- }
- return 0;
-}
-
-static int boundary_lt(unsigned int a, int adir,
- unsigned int b, int bdir)
-{
- if (adir < 0) {
- a--;
- adir = 1;
- } else if (adir > 0)
- adir = 1;
- if (bdir < 0) {
- b--;
- bdir = 1;
- } else if (bdir > 0)
- bdir = 1;
- return a < b || (a == b && adir < bdir);
-}
-
-/* Return 1 if min is nearer to best than max */
-static int boundary_nearer(int min, int mindir,
- int best, int bestdir,
- int max, int maxdir)
-{
- int dmin, dmindir;
- int dmax, dmaxdir;
- boundary_sub(best, bestdir, min, mindir, &dmin, &dmindir);
- boundary_sub(max, maxdir, best, bestdir, &dmax, &dmaxdir);
- return boundary_lt(dmin, dmindir, dmax, dmaxdir);
-}
-
-/**
- * snd_pcm_hw_param_near
- * @pcm: PCM instance
- * @params: the hw_params instance
- * @var: parameter to retrieve
- * @best: value to set
- * @dir: pointer to the direction (-1,0,1) or NULL
- *
- * Inside configuration space defined by PARAMS set PAR to the available value
- * nearest to VAL. Reduce configuration space accordingly.
- * This function cannot be called for SNDRV_PCM_HW_PARAM_ACCESS,
- * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT.
- * Return the value found.
- */
-static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm,
- struct snd_pcm_hw_params *params,
- snd_pcm_hw_param_t var, unsigned int best,
- int *dir)
-{
- struct snd_pcm_hw_params *save = NULL;
- int v;
- unsigned int saved_min;
- int last = 0;
- int min, max;
- int mindir, maxdir;
- int valdir = dir ? *dir : 0;
- /* FIXME */
- if (best > INT_MAX)
- best = INT_MAX;
- min = max = best;
- mindir = maxdir = valdir;
- if (maxdir > 0)
- maxdir = 0;
- else if (maxdir == 0)
- maxdir = -1;
- else {
- maxdir = 1;
- max--;
- }
- save = kmalloc(sizeof(*save), GFP_KERNEL);
- if (save == NULL)
- return -ENOMEM;
- *save = *params;
- saved_min = min;
- min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir);
- if (min >= 0) {
- struct snd_pcm_hw_params *params1;
- if (max < 0)
- goto _end;
- if ((unsigned int)min == saved_min && mindir == valdir)
- goto _end;
- params1 = kmalloc(sizeof(*params1), GFP_KERNEL);
- if (params1 == NULL) {
- kfree(save);
- return -ENOMEM;
- }
- *params1 = *save;
- max = snd_pcm_hw_param_max(pcm, params1, var, max, &maxdir);
- if (max < 0) {
- kfree(params1);
- goto _end;
- }
- if (boundary_nearer(max, maxdir, best, valdir, min, mindir)) {
- *params = *params1;
- last = 1;
- }
- kfree(params1);
- } else {
- *params = *save;
- max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
- if (max < 0) {
- kfree(save);
- return max;
- }
- last = 1;
- }
- _end:
- kfree(save);
- if (last)
- v = snd_pcm_hw_param_last(pcm, params, var, dir);
- else
- v = snd_pcm_hw_param_first(pcm, params, var, dir);
- snd_BUG_ON(v < 0);
- return v;
-}
-
-static int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params,
- snd_pcm_hw_param_t var, unsigned int val,
- int dir)
-{
- int changed;
- if (hw_is_mask(var)) {
- struct snd_mask *m = hw_param_mask(params, var);
- if (val == 0 && dir < 0) {
- changed = -EINVAL;
- snd_mask_none(m);
- } else {
- if (dir > 0)
- val++;
- else if (dir < 0)
- val--;
- changed = snd_mask_refine_set(hw_param_mask(params, var), val);
- }
- } else if (hw_is_interval(var)) {
- struct snd_interval *i = hw_param_interval(params, var);
- if (val == 0 && dir < 0) {
- changed = -EINVAL;
- snd_interval_none(i);
- } else if (dir == 0)
- changed = snd_interval_refine_set(i, val);
- else {
- struct snd_interval t;
- t.openmin = 1;
- t.openmax = 1;
- t.empty = 0;
- t.integer = 0;
- if (dir < 0) {
- t.min = val - 1;
- t.max = val;
- } else {
- t.min = val;
- t.max = val+1;
- }
- changed = snd_interval_refine(i, &t);
- }
- } else
- return -EINVAL;
- if (changed) {
- params->cmask |= 1 << var;
- params->rmask |= 1 << var;
- }
- return changed;
-}
-
-/**
- * snd_pcm_hw_param_set
- * @pcm: PCM instance
- * @params: the hw_params instance
- * @var: parameter to retrieve
- * @val: value to set
- * @dir: pointer to the direction (-1,0,1) or NULL
- *
- * Inside configuration space defined by PARAMS remove from PAR all
- * values != VAL. Reduce configuration space accordingly.
- * Return VAL or -EINVAL if the configuration space is empty
- */
-static int snd_pcm_hw_param_set(struct snd_pcm_substream *pcm,
- struct snd_pcm_hw_params *params,
- snd_pcm_hw_param_t var, unsigned int val,
- int dir)
-{
- int changed = _snd_pcm_hw_param_set(params, var, val, dir);
- if (changed < 0)
- return changed;
- if (params->rmask) {
- int err = snd_pcm_hw_refine(pcm, params);
- if (err < 0)
- return err;
- }
- return snd_pcm_hw_param_value(params, var, NULL);
-}
-
-static int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params,
- snd_pcm_hw_param_t var)
-{
- int changed;
- changed = snd_interval_setinteger(hw_param_interval(params, var));
- if (changed) {
- params->cmask |= 1 << var;
- params->rmask |= 1 << var;
- }
- return changed;
-}
-
-/*
- * plugin
- */
-
-#ifdef CONFIG_SND_PCM_OSS_PLUGINS
-static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_pcm_plugin *plugin, *next;
-
- plugin = runtime->oss.plugin_first;
- while (plugin) {
- next = plugin->next;
- snd_pcm_plugin_free(plugin);
- plugin = next;
- }
- runtime->oss.plugin_first = runtime->oss.plugin_last = NULL;
- return 0;
-}
-
-static int snd_pcm_plugin_insert(struct snd_pcm_plugin *plugin)
-{
- struct snd_pcm_runtime *runtime = plugin->plug->runtime;
- plugin->next = runtime->oss.plugin_first;
- plugin->prev = NULL;
- if (runtime->oss.plugin_first) {
- runtime->oss.plugin_first->prev = plugin;
- runtime->oss.plugin_first = plugin;
- } else {
- runtime->oss.plugin_last =
- runtime->oss.plugin_first = plugin;
- }
- return 0;
-}
-
-int snd_pcm_plugin_append(struct snd_pcm_plugin *plugin)
-{
- struct snd_pcm_runtime *runtime = plugin->plug->runtime;
- plugin->next = NULL;
- plugin->prev = runtime->oss.plugin_last;
- if (runtime->oss.plugin_last) {
- runtime->oss.plugin_last->next = plugin;
- runtime->oss.plugin_last = plugin;
- } else {
- runtime->oss.plugin_last =
- runtime->oss.plugin_first = plugin;
- }
- return 0;
-}
-#endif /* CONFIG_SND_PCM_OSS_PLUGINS */
-
-static long snd_pcm_oss_bytes(struct snd_pcm_substream *substream, long frames)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- long buffer_size = snd_pcm_lib_buffer_bytes(substream);
- long bytes = frames_to_bytes(runtime, frames);
- if (buffer_size == runtime->oss.buffer_bytes)
- return bytes;
-#if BITS_PER_LONG >= 64
- return runtime->oss.buffer_bytes * bytes / buffer_size;
-#else
- {
- u64 bsize = (u64)runtime->oss.buffer_bytes * (u64)bytes;
- return div_u64(bsize, buffer_size);
- }
-#endif
-}
-
-static long snd_pcm_alsa_frames(struct snd_pcm_substream *substream, long bytes)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- long buffer_size = snd_pcm_lib_buffer_bytes(substream);
- if (buffer_size == runtime->oss.buffer_bytes)
- return bytes_to_frames(runtime, bytes);
- return bytes_to_frames(runtime, (buffer_size * bytes) / runtime->oss.buffer_bytes);
-}
-
-static inline
-snd_pcm_uframes_t get_hw_ptr_period(struct snd_pcm_runtime *runtime)
-{
- return runtime->hw_ptr_interrupt;
-}
-
-/* define extended formats in the recent OSS versions (if any) */
-/* linear formats */
-#define AFMT_S32_LE 0x00001000
-#define AFMT_S32_BE 0x00002000
-#define AFMT_S24_LE 0x00008000
-#define AFMT_S24_BE 0x00010000
-#define AFMT_S24_PACKED 0x00040000
-
-/* other supported formats */
-#define AFMT_FLOAT 0x00004000
-#define AFMT_SPDIF_RAW 0x00020000
-
-/* unsupported formats */
-#define AFMT_AC3 0x00000400
-#define AFMT_VORBIS 0x00000800
-
-static snd_pcm_format_t snd_pcm_oss_format_from(int format)
-{
- switch (format) {
- case AFMT_MU_LAW: return SNDRV_PCM_FORMAT_MU_LAW;
- case AFMT_A_LAW: return SNDRV_PCM_FORMAT_A_LAW;
- case AFMT_IMA_ADPCM: return SNDRV_PCM_FORMAT_IMA_ADPCM;
- case AFMT_U8: return SNDRV_PCM_FORMAT_U8;
- case AFMT_S16_LE: return SNDRV_PCM_FORMAT_S16_LE;
- case AFMT_S16_BE: return SNDRV_PCM_FORMAT_S16_BE;
- case AFMT_S8: return SNDRV_PCM_FORMAT_S8;
- case AFMT_U16_LE: return SNDRV_PCM_FORMAT_U16_LE;
- case AFMT_U16_BE: return SNDRV_PCM_FORMAT_U16_BE;
- case AFMT_MPEG: return SNDRV_PCM_FORMAT_MPEG;
- case AFMT_S32_LE: return SNDRV_PCM_FORMAT_S32_LE;
- case AFMT_S32_BE: return SNDRV_PCM_FORMAT_S32_BE;
- case AFMT_S24_LE: return SNDRV_PCM_FORMAT_S24_LE;
- case AFMT_S24_BE: return SNDRV_PCM_FORMAT_S24_BE;
- case AFMT_S24_PACKED: return SNDRV_PCM_FORMAT_S24_3LE;
- case AFMT_FLOAT: return SNDRV_PCM_FORMAT_FLOAT;
- case AFMT_SPDIF_RAW: return SNDRV_PCM_FORMAT_IEC958_SUBFRAME;
- default: return SNDRV_PCM_FORMAT_U8;
- }
-}
-
-static int snd_pcm_oss_format_to(snd_pcm_format_t format)
-{
- switch (format) {
- case SNDRV_PCM_FORMAT_MU_LAW: return AFMT_MU_LAW;
- case SNDRV_PCM_FORMAT_A_LAW: return AFMT_A_LAW;
- case SNDRV_PCM_FORMAT_IMA_ADPCM: return AFMT_IMA_ADPCM;
- case SNDRV_PCM_FORMAT_U8: return AFMT_U8;
- case SNDRV_PCM_FORMAT_S16_LE: return AFMT_S16_LE;
- case SNDRV_PCM_FORMAT_S16_BE: return AFMT_S16_BE;
- case SNDRV_PCM_FORMAT_S8: return AFMT_S8;
- case SNDRV_PCM_FORMAT_U16_LE: return AFMT_U16_LE;
- case SNDRV_PCM_FORMAT_U16_BE: return AFMT_U16_BE;
- case SNDRV_PCM_FORMAT_MPEG: return AFMT_MPEG;
- case SNDRV_PCM_FORMAT_S32_LE: return AFMT_S32_LE;
- case SNDRV_PCM_FORMAT_S32_BE: return AFMT_S32_BE;
- case SNDRV_PCM_FORMAT_S24_LE: return AFMT_S24_LE;
- case SNDRV_PCM_FORMAT_S24_BE: return AFMT_S24_BE;
- case SNDRV_PCM_FORMAT_S24_3LE: return AFMT_S24_PACKED;
- case SNDRV_PCM_FORMAT_FLOAT: return AFMT_FLOAT;
- case SNDRV_PCM_FORMAT_IEC958_SUBFRAME: return AFMT_SPDIF_RAW;
- default: return -EINVAL;
- }
-}
-
-static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *oss_params,
- struct snd_pcm_hw_params *slave_params)
-{
- size_t s;
- size_t oss_buffer_size, oss_period_size, oss_periods;
- size_t min_period_size, max_period_size;
- struct snd_pcm_runtime *runtime = substream->runtime;
- size_t oss_frame_size;
-
- oss_frame_size = snd_pcm_format_physical_width(params_format(oss_params)) *
- params_channels(oss_params) / 8;
-
- oss_buffer_size = snd_pcm_plug_client_size(substream,
- snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL)) * oss_frame_size;
- oss_buffer_size = 1 << ld2(oss_buffer_size);
- if (atomic_read(&substream->mmap_count)) {
- if (oss_buffer_size > runtime->oss.mmap_bytes)
- oss_buffer_size = runtime->oss.mmap_bytes;
- }
-
- if (substream->oss.setup.period_size > 16)
- oss_period_size = substream->oss.setup.period_size;
- else if (runtime->oss.fragshift) {
- oss_period_size = 1 << runtime->oss.fragshift;
- if (oss_period_size > oss_buffer_size / 2)
- oss_period_size = oss_buffer_size / 2;
- } else {
- int sd;
- size_t bytes_per_sec = params_rate(oss_params) * snd_pcm_format_physical_width(params_format(oss_params)) * params_channels(oss_params) / 8;
-
- oss_period_size = oss_buffer_size;
- do {
- oss_period_size /= 2;
- } while (oss_period_size > bytes_per_sec);
- if (runtime->oss.subdivision == 0) {
- sd = 4;
- if (oss_period_size / sd > 4096)
- sd *= 2;
- if (oss_period_size / sd < 4096)
- sd = 1;
- } else
- sd = runtime->oss.subdivision;
- oss_period_size /= sd;
- if (oss_period_size < 16)
- oss_period_size = 16;
- }
-
- min_period_size = snd_pcm_plug_client_size(substream,
- snd_pcm_hw_param_value_min(slave_params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, NULL));
- min_period_size *= oss_frame_size;
- min_period_size = 1 << (ld2(min_period_size - 1) + 1);
- if (oss_period_size < min_period_size)
- oss_period_size = min_period_size;
-
- max_period_size = snd_pcm_plug_client_size(substream,
- snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, NULL));
- max_period_size *= oss_frame_size;
- max_period_size = 1 << ld2(max_period_size);
- if (oss_period_size > max_period_size)
- oss_period_size = max_period_size;
-
- oss_periods = oss_buffer_size / oss_period_size;
-
- if (substream->oss.setup.periods > 1)
- oss_periods = substream->oss.setup.periods;
-
- s = snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIODS, NULL);
- if (runtime->oss.maxfrags && s > runtime->oss.maxfrags)
- s = runtime->oss.maxfrags;
- if (oss_periods > s)
- oss_periods = s;
-
- s = snd_pcm_hw_param_value_min(slave_params, SNDRV_PCM_HW_PARAM_PERIODS, NULL);
- if (s < 2)
- s = 2;
- if (oss_periods < s)
- oss_periods = s;
-
- while (oss_period_size * oss_periods > oss_buffer_size)
- oss_period_size /= 2;
-
- if (oss_period_size < 16)
- return -EINVAL;
- runtime->oss.period_bytes = oss_period_size;
- runtime->oss.period_frames = 1;
- runtime->oss.periods = oss_periods;
- return 0;
-}
-
-static int choose_rate(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params, unsigned int best_rate)
-{
- struct snd_interval *it;
- struct snd_pcm_hw_params *save;
- unsigned int rate, prev;
-
- save = kmalloc(sizeof(*save), GFP_KERNEL);
- if (save == NULL)
- return -ENOMEM;
- *save = *params;
- it = hw_param_interval(save, SNDRV_PCM_HW_PARAM_RATE);
-
- /* try multiples of the best rate */
- rate = best_rate;
- for (;;) {
- if (it->max < rate || (it->max == rate && it->openmax))
- break;
- if (it->min < rate || (it->min == rate && !it->openmin)) {
- int ret;
- ret = snd_pcm_hw_param_set(substream, params,
- SNDRV_PCM_HW_PARAM_RATE,
- rate, 0);
- if (ret == (int)rate) {
- kfree(save);
- return rate;
- }
- *params = *save;
- }
- prev = rate;
- rate += best_rate;
- if (rate <= prev)
- break;
- }
-
- /* not found, use the nearest rate */
- kfree(save);
- return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL);
-}
-
-static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_pcm_hw_params *params, *sparams;
- struct snd_pcm_sw_params *sw_params;
- ssize_t oss_buffer_size, oss_period_size;
- size_t oss_frame_size;
- int err;
- int direct;
- snd_pcm_format_t format, sformat;
- int n;
- struct snd_mask sformat_mask;
- struct snd_mask mask;
-
- if (mutex_lock_interruptible(&runtime->oss.params_lock))
- return -EINTR;
- sw_params = kmalloc(sizeof(*sw_params), GFP_KERNEL);
- params = kmalloc(sizeof(*params), GFP_KERNEL);
- sparams = kmalloc(sizeof(*sparams), GFP_KERNEL);
- if (!sw_params || !params || !sparams) {
- snd_printd("No memory\n");
- err = -ENOMEM;
- goto failure;
- }
-
- if (atomic_read(&substream->mmap_count))
- direct = 1;
- else
- direct = substream->oss.setup.direct;
-
- _snd_pcm_hw_params_any(sparams);
- _snd_pcm_hw_param_setinteger(sparams, SNDRV_PCM_HW_PARAM_PERIODS);
- _snd_pcm_hw_param_min(sparams, SNDRV_PCM_HW_PARAM_PERIODS, 2, 0);
- snd_mask_none(&mask);
- if (atomic_read(&substream->mmap_count))
- snd_mask_set(&mask, (__force int)SNDRV_PCM_ACCESS_MMAP_INTERLEAVED);
- else {
- snd_mask_set(&mask, (__force int)SNDRV_PCM_ACCESS_RW_INTERLEAVED);
- if (!direct)
- snd_mask_set(&mask, (__force int)SNDRV_PCM_ACCESS_RW_NONINTERLEAVED);
- }
- err = snd_pcm_hw_param_mask(substream, sparams, SNDRV_PCM_HW_PARAM_ACCESS, &mask);
- if (err < 0) {
- snd_printd("No usable accesses\n");
- err = -EINVAL;
- goto failure;
- }
- choose_rate(substream, sparams, runtime->oss.rate);
- snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_CHANNELS, runtime->oss.channels, NULL);
-
- format = snd_pcm_oss_format_from(runtime->oss.format);
-
- sformat_mask = *hw_param_mask(sparams, SNDRV_PCM_HW_PARAM_FORMAT);
- if (direct)
- sformat = format;
- else
- sformat = snd_pcm_plug_slave_format(format, &sformat_mask);
-
- if ((__force int)sformat < 0 ||
- !snd_mask_test(&sformat_mask, (__force int)sformat)) {
- for (sformat = (__force snd_pcm_format_t)0;
- (__force int)sformat <= (__force int)SNDRV_PCM_FORMAT_LAST;
- sformat = (__force snd_pcm_format_t)((__force int)sformat + 1)) {
- if (snd_mask_test(&sformat_mask, (__force int)sformat) &&
- snd_pcm_oss_format_to(sformat) >= 0)
- break;
- }
- if ((__force int)sformat > (__force int)SNDRV_PCM_FORMAT_LAST) {
- snd_printd("Cannot find a format!!!\n");
- err = -EINVAL;
- goto failure;
- }
- }
- err = _snd_pcm_hw_param_set(sparams, SNDRV_PCM_HW_PARAM_FORMAT, (__force int)sformat, 0);
- if (err < 0)
- goto failure;
-
- if (direct) {
- memcpy(params, sparams, sizeof(*params));
- } else {
- _snd_pcm_hw_params_any(params);
- _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_ACCESS,
- (__force int)SNDRV_PCM_ACCESS_RW_INTERLEAVED, 0);
- _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_FORMAT,
- (__force int)snd_pcm_oss_format_from(runtime->oss.format), 0);
- _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_CHANNELS,
- runtime->oss.channels, 0);
- _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_RATE,
- runtime->oss.rate, 0);
- pdprintf("client: access = %i, format = %i, channels = %i, rate = %i\n",
- params_access(params), params_format(params),
- params_channels(params), params_rate(params));
- }
- pdprintf("slave: access = %i, format = %i, channels = %i, rate = %i\n",
- params_access(sparams), params_format(sparams),
- params_channels(sparams), params_rate(sparams));
-
- oss_frame_size = snd_pcm_format_physical_width(params_format(params)) *
- params_channels(params) / 8;
-
-#ifdef CONFIG_SND_PCM_OSS_PLUGINS
- snd_pcm_oss_plugin_clear(substream);
- if (!direct) {
- /* add necessary plugins */
- snd_pcm_oss_plugin_clear(substream);
- if ((err = snd_pcm_plug_format_plugins(substream,
- params,
- sparams)) < 0) {
- snd_printd("snd_pcm_plug_format_plugins failed: %i\n", err);
- snd_pcm_oss_plugin_clear(substream);
- goto failure;
- }
- if (runtime->oss.plugin_first) {
- struct snd_pcm_plugin *plugin;
- if ((err = snd_pcm_plugin_build_io(substream, sparams, &plugin)) < 0) {
- snd_printd("snd_pcm_plugin_build_io failed: %i\n", err);
- snd_pcm_oss_plugin_clear(substream);
- goto failure;
- }
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- err = snd_pcm_plugin_append(plugin);
- } else {
- err = snd_pcm_plugin_insert(plugin);
- }
- if (err < 0) {
- snd_pcm_oss_plugin_clear(substream);
- goto failure;
- }
- }
- }
-#endif
-
- err = snd_pcm_oss_period_size(substream, params, sparams);
- if (err < 0)
- goto failure;
-
- n = snd_pcm_plug_slave_size(substream, runtime->oss.period_bytes / oss_frame_size);
- err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, n, NULL);
- if (err < 0)
- goto failure;
-
- err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIODS,
- runtime->oss.periods, NULL);
- if (err < 0)
- goto failure;
-
- snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
-
- if ((err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_HW_PARAMS, sparams)) < 0) {
- snd_printd("HW_PARAMS failed: %i\n", err);
- goto failure;
- }
-
- memset(sw_params, 0, sizeof(*sw_params));
- if (runtime->oss.trigger) {
- sw_params->start_threshold = 1;
- } else {
- sw_params->start_threshold = runtime->boundary;
- }
- if (atomic_read(&substream->mmap_count) ||
- substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- sw_params->stop_threshold = runtime->boundary;
- else
- sw_params->stop_threshold = runtime->buffer_size;
- sw_params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
- sw_params->period_step = 1;
- sw_params->avail_min = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
- 1 : runtime->period_size;
- if (atomic_read(&substream->mmap_count) ||
- substream->oss.setup.nosilence) {
- sw_params->silence_threshold = 0;
- sw_params->silence_size = 0;
- } else {
- snd_pcm_uframes_t frames;
- frames = runtime->period_size + 16;
- if (frames > runtime->buffer_size)
- frames = runtime->buffer_size;
- sw_params->silence_threshold = frames;
- sw_params->silence_size = frames;
- }
-
- if ((err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_SW_PARAMS, sw_params)) < 0) {
- snd_printd("SW_PARAMS failed: %i\n", err);
- goto failure;
- }
-
- runtime->oss.periods = params_periods(sparams);
- oss_period_size = snd_pcm_plug_client_size(substream, params_period_size(sparams));
- if (oss_period_size < 0) {
- err = -EINVAL;
- goto failure;
- }
-#ifdef CONFIG_SND_PCM_OSS_PLUGINS
- if (runtime->oss.plugin_first) {
- err = snd_pcm_plug_alloc(substream, oss_period_size);
- if (err < 0)
- goto failure;
- }
-#endif
- oss_period_size *= oss_frame_size;
-
- oss_buffer_size = oss_period_size * runtime->oss.periods;
- if (oss_buffer_size < 0) {
- err = -EINVAL;
- goto failure;
- }
-
- runtime->oss.period_bytes = oss_period_size;
- runtime->oss.buffer_bytes = oss_buffer_size;
-
- pdprintf("oss: period bytes = %i, buffer bytes = %i\n",
- runtime->oss.period_bytes,
- runtime->oss.buffer_bytes);
- pdprintf("slave: period_size = %i, buffer_size = %i\n",
- params_period_size(sparams),
- params_buffer_size(sparams));
-
- runtime->oss.format = snd_pcm_oss_format_to(params_format(params));
- runtime->oss.channels = params_channels(params);
- runtime->oss.rate = params_rate(params);
-
- vfree(runtime->oss.buffer);
- runtime->oss.buffer = vmalloc(runtime->oss.period_bytes);
- if (!runtime->oss.buffer) {
- err = -ENOMEM;
- goto failure;
- }
-
- runtime->oss.params = 0;
- runtime->oss.prepare = 1;
- runtime->oss.buffer_used = 0;
- if (runtime->dma_area)
- snd_pcm_format_set_silence(runtime->format, runtime->dma_area, bytes_to_samples(runtime, runtime->dma_bytes));
-
- runtime->oss.period_frames = snd_pcm_alsa_frames(substream, oss_period_size);
-
- err = 0;
-failure:
- kfree(sw_params);
- kfree(params);
- kfree(sparams);
- mutex_unlock(&runtime->oss.params_lock);
- return err;
-}
-
-static int snd_pcm_oss_get_active_substream(struct snd_pcm_oss_file *pcm_oss_file, struct snd_pcm_substream **r_substream)
-{
- int idx, err;
- struct snd_pcm_substream *asubstream = NULL, *substream;
-
- for (idx = 0; idx < 2; idx++) {
- substream = pcm_oss_file->streams[idx];
- if (substream == NULL)
- continue;
- if (asubstream == NULL)
- asubstream = substream;
- if (substream->runtime->oss.params) {
- err = snd_pcm_oss_change_params(substream);
- if (err < 0)
- return err;
- }
- }
- if (!asubstream)
- return -EIO;
- if (r_substream)
- *r_substream = asubstream;
- return 0;
-}
-
-static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream)
-{
- int err;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL);
- if (err < 0) {
- snd_printd("snd_pcm_oss_prepare: SNDRV_PCM_IOCTL_PREPARE failed\n");
- return err;
- }
- runtime->oss.prepare = 0;
- runtime->oss.prev_hw_ptr_period = 0;
- runtime->oss.period_ptr = 0;
- runtime->oss.buffer_used = 0;
-
- return 0;
-}
-
-static int snd_pcm_oss_make_ready(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime;
- int err;
-
- if (substream == NULL)
- return 0;
- runtime = substream->runtime;
- if (runtime->oss.params) {
- err = snd_pcm_oss_change_params(substream);
- if (err < 0)
- return err;
- }
- if (runtime->oss.prepare) {
- err = snd_pcm_oss_prepare(substream);
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-static int snd_pcm_oss_capture_position_fixup(struct snd_pcm_substream *substream, snd_pcm_sframes_t *delay)
-{
- struct snd_pcm_runtime *runtime;
- snd_pcm_uframes_t frames;
- int err = 0;
-
- while (1) {
- err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, delay);
- if (err < 0)
- break;
- runtime = substream->runtime;
- if (*delay <= (snd_pcm_sframes_t)runtime->buffer_size)
- break;
- /* in case of overrun, skip whole periods like OSS/Linux driver does */
- /* until avail(delay) <= buffer_size */
- frames = (*delay - runtime->buffer_size) + runtime->period_size - 1;
- frames /= runtime->period_size;
- frames *= runtime->period_size;
- err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_FORWARD, &frames);
- if (err < 0)
- break;
- }
- return err;
-}
-
-snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream, const char *ptr, snd_pcm_uframes_t frames, int in_kernel)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int ret;
- while (1) {
- if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
- runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
-#ifdef OSS_DEBUG
- if (runtime->status->state == SNDRV_PCM_STATE_XRUN)
- printk(KERN_DEBUG "pcm_oss: write: "
- "recovering from XRUN\n");
- else
- printk(KERN_DEBUG "pcm_oss: write: "
- "recovering from SUSPEND\n");
-#endif
- ret = snd_pcm_oss_prepare(substream);
- if (ret < 0)
- break;
- }
- if (in_kernel) {
- mm_segment_t fs;
- fs = snd_enter_user();
- ret = snd_pcm_lib_write(substream, (void __force __user *)ptr, frames);
- snd_leave_user(fs);
- } else {
- ret = snd_pcm_lib_write(substream, (void __force __user *)ptr, frames);
- }
- if (ret != -EPIPE && ret != -ESTRPIPE)
- break;
- /* test, if we can't store new data, because the stream */
- /* has not been started */
- if (runtime->status->state == SNDRV_PCM_STATE_PREPARED)
- return -EAGAIN;
- }
- return ret;
-}
-
-snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream, char *ptr, snd_pcm_uframes_t frames, int in_kernel)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_sframes_t delay;
- int ret;
- while (1) {
- if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
- runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
-#ifdef OSS_DEBUG
- if (runtime->status->state == SNDRV_PCM_STATE_XRUN)
- printk(KERN_DEBUG "pcm_oss: read: "
- "recovering from XRUN\n");
- else
- printk(KERN_DEBUG "pcm_oss: read: "
- "recovering from SUSPEND\n");
-#endif
- ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL);
- if (ret < 0)
- break;
- } else if (runtime->status->state == SNDRV_PCM_STATE_SETUP) {
- ret = snd_pcm_oss_prepare(substream);
- if (ret < 0)
- break;
- }
- ret = snd_pcm_oss_capture_position_fixup(substream, &delay);
- if (ret < 0)
- break;
- if (in_kernel) {
- mm_segment_t fs;
- fs = snd_enter_user();
- ret = snd_pcm_lib_read(substream, (void __force __user *)ptr, frames);
- snd_leave_user(fs);
- } else {
- ret = snd_pcm_lib_read(substream, (void __force __user *)ptr, frames);
- }
- if (ret == -EPIPE) {
- if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
- ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
- if (ret < 0)
- break;
- }
- continue;
- }
- if (ret != -ESTRPIPE)
- break;
- }
- return ret;
-}
-
-snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream, void **bufs, snd_pcm_uframes_t frames, int in_kernel)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int ret;
- while (1) {
- if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
- runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
-#ifdef OSS_DEBUG
- if (runtime->status->state == SNDRV_PCM_STATE_XRUN)
- printk(KERN_DEBUG "pcm_oss: writev: "
- "recovering from XRUN\n");
- else
- printk(KERN_DEBUG "pcm_oss: writev: "
- "recovering from SUSPEND\n");
-#endif
- ret = snd_pcm_oss_prepare(substream);
- if (ret < 0)
- break;
- }
- if (in_kernel) {
- mm_segment_t fs;
- fs = snd_enter_user();
- ret = snd_pcm_lib_writev(substream, (void __user **)bufs, frames);
- snd_leave_user(fs);
- } else {
- ret = snd_pcm_lib_writev(substream, (void __user **)bufs, frames);
- }
- if (ret != -EPIPE && ret != -ESTRPIPE)
- break;
-
- /* test, if we can't store new data, because the stream */
- /* has not been started */
- if (runtime->status->state == SNDRV_PCM_STATE_PREPARED)
- return -EAGAIN;
- }
- return ret;
-}
-
-snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream, void **bufs, snd_pcm_uframes_t frames, int in_kernel)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int ret;
- while (1) {
- if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
- runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
-#ifdef OSS_DEBUG
- if (runtime->status->state == SNDRV_PCM_STATE_XRUN)
- printk(KERN_DEBUG "pcm_oss: readv: "
- "recovering from XRUN\n");
- else
- printk(KERN_DEBUG "pcm_oss: readv: "
- "recovering from SUSPEND\n");
-#endif
- ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL);
- if (ret < 0)
- break;
- } else if (runtime->status->state == SNDRV_PCM_STATE_SETUP) {
- ret = snd_pcm_oss_prepare(substream);
- if (ret < 0)
- break;
- }
- if (in_kernel) {
- mm_segment_t fs;
- fs = snd_enter_user();
- ret = snd_pcm_lib_readv(substream, (void __user **)bufs, frames);
- snd_leave_user(fs);
- } else {
- ret = snd_pcm_lib_readv(substream, (void __user **)bufs, frames);
- }
- if (ret != -EPIPE && ret != -ESTRPIPE)
- break;
- }
- return ret;
-}
-
-static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const char *buf, size_t bytes, int in_kernel)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_sframes_t frames, frames1;
-#ifdef CONFIG_SND_PCM_OSS_PLUGINS
- if (runtime->oss.plugin_first) {
- struct snd_pcm_plugin_channel *channels;
- size_t oss_frame_bytes = (runtime->oss.plugin_first->src_width * runtime->oss.plugin_first->src_format.channels) / 8;
- if (!in_kernel) {
- if (copy_from_user(runtime->oss.buffer, (const char __force __user *)buf, bytes))
- return -EFAULT;
- buf = runtime->oss.buffer;
- }
- frames = bytes / oss_frame_bytes;
- frames1 = snd_pcm_plug_client_channels_buf(substream, (char *)buf, frames, &channels);
- if (frames1 < 0)
- return frames1;
- frames1 = snd_pcm_plug_write_transfer(substream, channels, frames1);
- if (frames1 <= 0)
- return frames1;
- bytes = frames1 * oss_frame_bytes;
- } else
-#endif
- {
- frames = bytes_to_frames(runtime, bytes);
- frames1 = snd_pcm_oss_write3(substream, buf, frames, in_kernel);
- if (frames1 <= 0)
- return frames1;
- bytes = frames_to_bytes(runtime, frames1);
- }
- return bytes;
-}
-
-static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const char __user *buf, size_t bytes)
-{
- size_t xfer = 0;
- ssize_t tmp;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- if (atomic_read(&substream->mmap_count))
- return -ENXIO;
-
- if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
- return tmp;
- mutex_lock(&runtime->oss.params_lock);
- while (bytes > 0) {
- if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
- tmp = bytes;
- if (tmp + runtime->oss.buffer_used > runtime->oss.period_bytes)
- tmp = runtime->oss.period_bytes - runtime->oss.buffer_used;
- if (tmp > 0) {
- if (copy_from_user(runtime->oss.buffer + runtime->oss.buffer_used, buf, tmp)) {
- tmp = -EFAULT;
- goto err;
- }
- }
- runtime->oss.buffer_used += tmp;
- buf += tmp;
- bytes -= tmp;
- xfer += tmp;
- if (substream->oss.setup.partialfrag ||
- runtime->oss.buffer_used == runtime->oss.period_bytes) {
- tmp = snd_pcm_oss_write2(substream, runtime->oss.buffer + runtime->oss.period_ptr,
- runtime->oss.buffer_used - runtime->oss.period_ptr, 1);
- if (tmp <= 0)
- goto err;
- runtime->oss.bytes += tmp;
- runtime->oss.period_ptr += tmp;
- runtime->oss.period_ptr %= runtime->oss.period_bytes;
- if (runtime->oss.period_ptr == 0 ||
- runtime->oss.period_ptr == runtime->oss.buffer_used)
- runtime->oss.buffer_used = 0;
- else if ((substream->f_flags & O_NONBLOCK) != 0) {
- tmp = -EAGAIN;
- goto err;
- }
- }
- } else {
- tmp = snd_pcm_oss_write2(substream,
- (const char __force *)buf,
- runtime->oss.period_bytes, 0);
- if (tmp <= 0)
- goto err;
- runtime->oss.bytes += tmp;
- buf += tmp;
- bytes -= tmp;
- xfer += tmp;
- if ((substream->f_flags & O_NONBLOCK) != 0 &&
- tmp != runtime->oss.period_bytes)
- break;
- }
- }
- mutex_unlock(&runtime->oss.params_lock);
- return xfer;
-
- err:
- mutex_unlock(&runtime->oss.params_lock);
- return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
-}
-
-static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf, size_t bytes, int in_kernel)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_sframes_t frames, frames1;
-#ifdef CONFIG_SND_PCM_OSS_PLUGINS
- char __user *final_dst = (char __force __user *)buf;
- if (runtime->oss.plugin_first) {
- struct snd_pcm_plugin_channel *channels;
- size_t oss_frame_bytes = (runtime->oss.plugin_last->dst_width * runtime->oss.plugin_last->dst_format.channels) / 8;
- if (!in_kernel)
- buf = runtime->oss.buffer;
- frames = bytes / oss_frame_bytes;
- frames1 = snd_pcm_plug_client_channels_buf(substream, buf, frames, &channels);
- if (frames1 < 0)
- return frames1;
- frames1 = snd_pcm_plug_read_transfer(substream, channels, frames1);
- if (frames1 <= 0)
- return frames1;
- bytes = frames1 * oss_frame_bytes;
- if (!in_kernel && copy_to_user(final_dst, buf, bytes))
- return -EFAULT;
- } else
-#endif
- {
- frames = bytes_to_frames(runtime, bytes);
- frames1 = snd_pcm_oss_read3(substream, buf, frames, in_kernel);
- if (frames1 <= 0)
- return frames1;
- bytes = frames_to_bytes(runtime, frames1);
- }
- return bytes;
-}
-
-static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __user *buf, size_t bytes)
-{
- size_t xfer = 0;
- ssize_t tmp;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- if (atomic_read(&substream->mmap_count))
- return -ENXIO;
-
- if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
- return tmp;
- mutex_lock(&runtime->oss.params_lock);
- while (bytes > 0) {
- if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
- if (runtime->oss.buffer_used == 0) {
- tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1);
- if (tmp <= 0)
- goto err;
- runtime->oss.bytes += tmp;
- runtime->oss.period_ptr = tmp;
- runtime->oss.buffer_used = tmp;
- }
- tmp = bytes;
- if ((size_t) tmp > runtime->oss.buffer_used)
- tmp = runtime->oss.buffer_used;
- if (copy_to_user(buf, runtime->oss.buffer + (runtime->oss.period_ptr - runtime->oss.buffer_used), tmp)) {
- tmp = -EFAULT;
- goto err;
- }
- buf += tmp;
- bytes -= tmp;
- xfer += tmp;
- runtime->oss.buffer_used -= tmp;
- } else {
- tmp = snd_pcm_oss_read2(substream, (char __force *)buf,
- runtime->oss.period_bytes, 0);
- if (tmp <= 0)
- goto err;
- runtime->oss.bytes += tmp;
- buf += tmp;
- bytes -= tmp;
- xfer += tmp;
- }
- }
- mutex_unlock(&runtime->oss.params_lock);
- return xfer;
-
- err:
- mutex_unlock(&runtime->oss.params_lock);
- return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
-}
-
-static int snd_pcm_oss_reset(struct snd_pcm_oss_file *pcm_oss_file)
-{
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
- int i;
-
- for (i = 0; i < 2; i++) {
- substream = pcm_oss_file->streams[i];
- if (!substream)
- continue;
- runtime = substream->runtime;
- snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
- runtime->oss.prepare = 1;
- runtime->oss.buffer_used = 0;
- runtime->oss.prev_hw_ptr_period = 0;
- runtime->oss.period_ptr = 0;
- }
- return 0;
-}
-
-static int snd_pcm_oss_post(struct snd_pcm_oss_file *pcm_oss_file)
-{
- struct snd_pcm_substream *substream;
- int err;
-
- substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
- if (substream != NULL) {
- if ((err = snd_pcm_oss_make_ready(substream)) < 0)
- return err;
- snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_START, NULL);
- }
- /* note: all errors from the start action are ignored */
- /* OSS apps do not know, how to handle them */
- return 0;
-}
-
-static int snd_pcm_oss_sync1(struct snd_pcm_substream *substream, size_t size)
-{
- struct snd_pcm_runtime *runtime;
- ssize_t result = 0;
- snd_pcm_state_t state;
- long res;
- wait_queue_t wait;
-
- runtime = substream->runtime;
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&runtime->sleep, &wait);
-#ifdef OSS_DEBUG
- printk(KERN_DEBUG "sync1: size = %li\n", size);
-#endif
- while (1) {
- result = snd_pcm_oss_write2(substream, runtime->oss.buffer, size, 1);
- if (result > 0) {
- runtime->oss.buffer_used = 0;
- result = 0;
- break;
- }
- if (result != 0 && result != -EAGAIN)
- break;
- result = 0;
- set_current_state(TASK_INTERRUPTIBLE);
- snd_pcm_stream_lock_irq(substream);
- state = runtime->status->state;
- snd_pcm_stream_unlock_irq(substream);
- if (state != SNDRV_PCM_STATE_RUNNING) {
- set_current_state(TASK_RUNNING);
- break;
- }
- res = schedule_timeout(10 * HZ);
- if (signal_pending(current)) {
- result = -ERESTARTSYS;
- break;
- }
- if (res == 0) {
- snd_printk(KERN_ERR "OSS sync error - DMA timeout\n");
- result = -EIO;
- break;
- }
- }
- remove_wait_queue(&runtime->sleep, &wait);
- return result;
-}
-
-static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
-{
- int err = 0;
- unsigned int saved_f_flags;
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
- snd_pcm_format_t format;
- unsigned long width;
- size_t size;
-
- substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
- if (substream != NULL) {
- runtime = substream->runtime;
- if (atomic_read(&substream->mmap_count))
- goto __direct;
- if ((err = snd_pcm_oss_make_ready(substream)) < 0)
- return err;
- format = snd_pcm_oss_format_from(runtime->oss.format);
- width = snd_pcm_format_physical_width(format);
- mutex_lock(&runtime->oss.params_lock);
- if (runtime->oss.buffer_used > 0) {
-#ifdef OSS_DEBUG
- printk(KERN_DEBUG "sync: buffer_used\n");
-#endif
- size = (8 * (runtime->oss.period_bytes - runtime->oss.buffer_used) + 7) / width;
- snd_pcm_format_set_silence(format,
- runtime->oss.buffer + runtime->oss.buffer_used,
- size);
- err = snd_pcm_oss_sync1(substream, runtime->oss.period_bytes);
- if (err < 0) {
- mutex_unlock(&runtime->oss.params_lock);
- return err;
- }
- } else if (runtime->oss.period_ptr > 0) {
-#ifdef OSS_DEBUG
- printk(KERN_DEBUG "sync: period_ptr\n");
-#endif
- size = runtime->oss.period_bytes - runtime->oss.period_ptr;
- snd_pcm_format_set_silence(format,
- runtime->oss.buffer,
- size * 8 / width);
- err = snd_pcm_oss_sync1(substream, size);
- if (err < 0) {
- mutex_unlock(&runtime->oss.params_lock);
- return err;
- }
- }
- /*
- * The ALSA's period might be a bit large than OSS one.
- * Fill the remain portion of ALSA period with zeros.
- */
- size = runtime->control->appl_ptr % runtime->period_size;
- if (size > 0) {
- size = runtime->period_size - size;
- if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) {
- size = (runtime->frame_bits * size) / 8;
- while (size > 0) {
- mm_segment_t fs;
- size_t size1 = size < runtime->oss.period_bytes ? size : runtime->oss.period_bytes;
- size -= size1;
- size1 *= 8;
- size1 /= runtime->sample_bits;
- snd_pcm_format_set_silence(runtime->format,
- runtime->oss.buffer,
- size1);
- size1 /= runtime->channels; /* frames */
- fs = snd_enter_user();
- snd_pcm_lib_write(substream, (void __force __user *)runtime->oss.buffer, size1);
- snd_leave_user(fs);
- }
- } else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) {
- void __user *buffers[runtime->channels];
- memset(buffers, 0, runtime->channels * sizeof(void *));
- snd_pcm_lib_writev(substream, buffers, size);
- }
- }
- mutex_unlock(&runtime->oss.params_lock);
- /*
- * finish sync: drain the buffer
- */
- __direct:
- saved_f_flags = substream->f_flags;
- substream->f_flags &= ~O_NONBLOCK;
- err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL);
- substream->f_flags = saved_f_flags;
- if (err < 0)
- return err;
- runtime->oss.prepare = 1;
- }
-
- substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
- if (substream != NULL) {
- if ((err = snd_pcm_oss_make_ready(substream)) < 0)
- return err;
- runtime = substream->runtime;
- err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
- if (err < 0)
- return err;
- runtime->oss.buffer_used = 0;
- runtime->oss.prepare = 1;
- }
- return 0;
-}
-
-static int snd_pcm_oss_set_rate(struct snd_pcm_oss_file *pcm_oss_file, int rate)
-{
- int idx;
-
- for (idx = 1; idx >= 0; --idx) {
- struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
- struct snd_pcm_runtime *runtime;
- if (substream == NULL)
- continue;
- runtime = substream->runtime;
- if (rate < 1000)
- rate = 1000;
- else if (rate > 192000)
- rate = 192000;
- if (runtime->oss.rate != rate) {
- runtime->oss.params = 1;
- runtime->oss.rate = rate;
- }
- }
- return snd_pcm_oss_get_rate(pcm_oss_file);
-}
-
-static int snd_pcm_oss_get_rate(struct snd_pcm_oss_file *pcm_oss_file)
-{
- struct snd_pcm_substream *substream;
- int err;
-
- if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
- return err;
- return substream->runtime->oss.rate;
-}
-
-static int snd_pcm_oss_set_channels(struct snd_pcm_oss_file *pcm_oss_file, unsigned int channels)
-{
- int idx;
- if (channels < 1)
- channels = 1;
- if (channels > 128)
- return -EINVAL;
- for (idx = 1; idx >= 0; --idx) {
- struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
- struct snd_pcm_runtime *runtime;
- if (substream == NULL)
- continue;
- runtime = substream->runtime;
- if (runtime->oss.channels != channels) {
- runtime->oss.params = 1;
- runtime->oss.channels = channels;
- }
- }
- return snd_pcm_oss_get_channels(pcm_oss_file);
-}
-
-static int snd_pcm_oss_get_channels(struct snd_pcm_oss_file *pcm_oss_file)
-{
- struct snd_pcm_substream *substream;
- int err;
-
- if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
- return err;
- return substream->runtime->oss.channels;
-}
-
-static int snd_pcm_oss_get_block_size(struct snd_pcm_oss_file *pcm_oss_file)
-{
- struct snd_pcm_substream *substream;
- int err;
-
- if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
- return err;
- return substream->runtime->oss.period_bytes;
-}
-
-static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
-{
- struct snd_pcm_substream *substream;
- int err;
- int direct;
- struct snd_pcm_hw_params *params;
- unsigned int formats = 0;
- struct snd_mask format_mask;
- int fmt;
-
- if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
- return err;
- if (atomic_read(&substream->mmap_count))
- direct = 1;
- else
- direct = substream->oss.setup.direct;
- if (!direct)
- return AFMT_MU_LAW | AFMT_U8 |
- AFMT_S16_LE | AFMT_S16_BE |
- AFMT_S8 | AFMT_U16_LE |
- AFMT_U16_BE |
- AFMT_S32_LE | AFMT_S32_BE |
- AFMT_S24_LE | AFMT_S24_BE |
- AFMT_S24_PACKED;
- params = kmalloc(sizeof(*params), GFP_KERNEL);
- if (!params)
- return -ENOMEM;
- _snd_pcm_hw_params_any(params);
- err = snd_pcm_hw_refine(substream, params);
- format_mask = *hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
- kfree(params);
- if (err < 0)
- return err;
- for (fmt = 0; fmt < 32; ++fmt) {
- if (snd_mask_test(&format_mask, fmt)) {
- int f = snd_pcm_oss_format_to(fmt);
- if (f >= 0)
- formats |= f;
- }
- }
- return formats;
-}
-
-static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format)
-{
- int formats, idx;
-
- if (format != AFMT_QUERY) {
- formats = snd_pcm_oss_get_formats(pcm_oss_file);
- if (formats < 0)
- return formats;
- if (!(formats & format))
- format = AFMT_U8;
- for (idx = 1; idx >= 0; --idx) {
- struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
- struct snd_pcm_runtime *runtime;
- if (substream == NULL)
- continue;
- runtime = substream->runtime;
- if (runtime->oss.format != format) {
- runtime->oss.params = 1;
- runtime->oss.format = format;
- }
- }
- }
- return snd_pcm_oss_get_format(pcm_oss_file);
-}
-
-static int snd_pcm_oss_get_format(struct snd_pcm_oss_file *pcm_oss_file)
-{
- struct snd_pcm_substream *substream;
- int err;
-
- if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
- return err;
- return substream->runtime->oss.format;
-}
-
-static int snd_pcm_oss_set_subdivide1(struct snd_pcm_substream *substream, int subdivide)
-{
- struct snd_pcm_runtime *runtime;
-
- if (substream == NULL)
- return 0;
- runtime = substream->runtime;
- if (subdivide == 0) {
- subdivide = runtime->oss.subdivision;
- if (subdivide == 0)
- subdivide = 1;
- return subdivide;
- }
- if (runtime->oss.subdivision || runtime->oss.fragshift)
- return -EINVAL;
- if (subdivide != 1 && subdivide != 2 && subdivide != 4 &&
- subdivide != 8 && subdivide != 16)
- return -EINVAL;
- runtime->oss.subdivision = subdivide;
- runtime->oss.params = 1;
- return subdivide;
-}
-
-static int snd_pcm_oss_set_subdivide(struct snd_pcm_oss_file *pcm_oss_file, int subdivide)
-{
- int err = -EINVAL, idx;
-
- for (idx = 1; idx >= 0; --idx) {
- struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
- if (substream == NULL)
- continue;
- if ((err = snd_pcm_oss_set_subdivide1(substream, subdivide)) < 0)
- return err;
- }
- return err;
-}
-
-static int snd_pcm_oss_set_fragment1(struct snd_pcm_substream *substream, unsigned int val)
-{
- struct snd_pcm_runtime *runtime;
-
- if (substream == NULL)
- return 0;
- runtime = substream->runtime;
- if (runtime->oss.subdivision || runtime->oss.fragshift)
- return -EINVAL;
- runtime->oss.fragshift = val & 0xffff;
- runtime->oss.maxfrags = (val >> 16) & 0xffff;
- if (runtime->oss.fragshift < 4) /* < 16 */
- runtime->oss.fragshift = 4;
- if (runtime->oss.maxfrags < 2)
- runtime->oss.maxfrags = 2;
- runtime->oss.params = 1;
- return 0;
-}
-
-static int snd_pcm_oss_set_fragment(struct snd_pcm_oss_file *pcm_oss_file, unsigned int val)
-{
- int err = -EINVAL, idx;
-
- for (idx = 1; idx >= 0; --idx) {
- struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
- if (substream == NULL)
- continue;
- if ((err = snd_pcm_oss_set_fragment1(substream, val)) < 0)
- return err;
- }
- return err;
-}
-
-static int snd_pcm_oss_nonblock(struct file * file)
-{
- spin_lock(&file->f_lock);
- file->f_flags |= O_NONBLOCK;
- spin_unlock(&file->f_lock);
- return 0;
-}
-
-static int snd_pcm_oss_get_caps1(struct snd_pcm_substream *substream, int res)
-{
-
- if (substream == NULL) {
- res &= ~DSP_CAP_DUPLEX;
- return res;
- }
-#ifdef DSP_CAP_MULTI
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- if (substream->pstr->substream_count > 1)
- res |= DSP_CAP_MULTI;
-#endif
- /* DSP_CAP_REALTIME is set all times: */
- /* all ALSA drivers can return actual pointer in ring buffer */
-#if defined(DSP_CAP_REALTIME) && 0
- {
- struct snd_pcm_runtime *runtime = substream->runtime;
- if (runtime->info & (SNDRV_PCM_INFO_BLOCK_TRANSFER|SNDRV_PCM_INFO_BATCH))
- res &= ~DSP_CAP_REALTIME;
- }
-#endif
- return res;
-}
-
-static int snd_pcm_oss_get_caps(struct snd_pcm_oss_file *pcm_oss_file)
-{
- int result, idx;
-
- result = DSP_CAP_TRIGGER | DSP_CAP_MMAP | DSP_CAP_DUPLEX | DSP_CAP_REALTIME;
- for (idx = 0; idx < 2; idx++) {
- struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
- result = snd_pcm_oss_get_caps1(substream, result);
- }
- result |= 0x0001; /* revision - same as SB AWE 64 */
- return result;
-}
-
-static void snd_pcm_oss_simulate_fill(struct snd_pcm_substream *substream,
- snd_pcm_uframes_t hw_ptr)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_uframes_t appl_ptr;
- appl_ptr = hw_ptr + runtime->buffer_size;
- appl_ptr %= runtime->boundary;
- runtime->control->appl_ptr = appl_ptr;
-}
-
-static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int trigger)
-{
- struct snd_pcm_runtime *runtime;
- struct snd_pcm_substream *psubstream = NULL, *csubstream = NULL;
- int err, cmd;
-
-#ifdef OSS_DEBUG
- printk(KERN_DEBUG "pcm_oss: trigger = 0x%x\n", trigger);
-#endif
-
- psubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
- csubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
-
- if (psubstream) {
- if ((err = snd_pcm_oss_make_ready(psubstream)) < 0)
- return err;
- }
- if (csubstream) {
- if ((err = snd_pcm_oss_make_ready(csubstream)) < 0)
- return err;
- }
- if (psubstream) {
- runtime = psubstream->runtime;
- if (trigger & PCM_ENABLE_OUTPUT) {
- if (runtime->oss.trigger)
- goto _skip1;
- if (atomic_read(&psubstream->mmap_count))
- snd_pcm_oss_simulate_fill(psubstream,
- get_hw_ptr_period(runtime));
- runtime->oss.trigger = 1;
- runtime->start_threshold = 1;
- cmd = SNDRV_PCM_IOCTL_START;
- } else {
- if (!runtime->oss.trigger)
- goto _skip1;
- runtime->oss.trigger = 0;
- runtime->start_threshold = runtime->boundary;
- cmd = SNDRV_PCM_IOCTL_DROP;
- runtime->oss.prepare = 1;
- }
- err = snd_pcm_kernel_ioctl(psubstream, cmd, NULL);
- if (err < 0)
- return err;
- }
- _skip1:
- if (csubstream) {
- runtime = csubstream->runtime;
- if (trigger & PCM_ENABLE_INPUT) {
- if (runtime->oss.trigger)
- goto _skip2;
- runtime->oss.trigger = 1;
- runtime->start_threshold = 1;
- cmd = SNDRV_PCM_IOCTL_START;
- } else {
- if (!runtime->oss.trigger)
- goto _skip2;
- runtime->oss.trigger = 0;
- runtime->start_threshold = runtime->boundary;
- cmd = SNDRV_PCM_IOCTL_DROP;
- runtime->oss.prepare = 1;
- }
- err = snd_pcm_kernel_ioctl(csubstream, cmd, NULL);
- if (err < 0)
- return err;
- }
- _skip2:
- return 0;
-}
-
-static int snd_pcm_oss_get_trigger(struct snd_pcm_oss_file *pcm_oss_file)
-{
- struct snd_pcm_substream *psubstream = NULL, *csubstream = NULL;
- int result = 0;
-
- psubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
- csubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
- if (psubstream && psubstream->runtime && psubstream->runtime->oss.trigger)
- result |= PCM_ENABLE_OUTPUT;
- if (csubstream && csubstream->runtime && csubstream->runtime->oss.trigger)
- result |= PCM_ENABLE_INPUT;
- return result;
-}
-
-static int snd_pcm_oss_get_odelay(struct snd_pcm_oss_file *pcm_oss_file)
-{
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
- snd_pcm_sframes_t delay;
- int err;
-
- substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
- if (substream == NULL)
- return -EINVAL;
- if ((err = snd_pcm_oss_make_ready(substream)) < 0)
- return err;
- runtime = substream->runtime;
- if (runtime->oss.params || runtime->oss.prepare)
- return 0;
- err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, &delay);
- if (err == -EPIPE)
- delay = 0; /* hack for broken OSS applications */
- else if (err < 0)
- return err;
- return snd_pcm_oss_bytes(substream, delay);
-}
-
-static int snd_pcm_oss_get_ptr(struct snd_pcm_oss_file *pcm_oss_file, int stream, struct count_info __user * _info)
-{
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
- snd_pcm_sframes_t delay;
- int fixup;
- struct count_info info;
- int err;
-
- if (_info == NULL)
- return -EFAULT;
- substream = pcm_oss_file->streams[stream];
- if (substream == NULL)
- return -EINVAL;
- if ((err = snd_pcm_oss_make_ready(substream)) < 0)
- return err;
- runtime = substream->runtime;
- if (runtime->oss.params || runtime->oss.prepare) {
- memset(&info, 0, sizeof(info));
- if (copy_to_user(_info, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- }
- if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
- err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, &delay);
- if (err == -EPIPE || err == -ESTRPIPE || (! err && delay < 0)) {
- err = 0;
- delay = 0;
- fixup = 0;
- } else {
- fixup = runtime->oss.buffer_used;
- }
- } else {
- err = snd_pcm_oss_capture_position_fixup(substream, &delay);
- fixup = -runtime->oss.buffer_used;
- }
- if (err < 0)
- return err;
- info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size);
- if (atomic_read(&substream->mmap_count)) {
- snd_pcm_sframes_t n;
- delay = get_hw_ptr_period(runtime);
- n = delay - runtime->oss.prev_hw_ptr_period;
- if (n < 0)
- n += runtime->boundary;
- info.blocks = n / runtime->period_size;
- runtime->oss.prev_hw_ptr_period = delay;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- snd_pcm_oss_simulate_fill(substream, delay);
- info.bytes = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr) & INT_MAX;
- } else {
- delay = snd_pcm_oss_bytes(substream, delay);
- if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (substream->oss.setup.buggyptr)
- info.blocks = (runtime->oss.buffer_bytes - delay - fixup) / runtime->oss.period_bytes;
- else
- info.blocks = (delay + fixup) / runtime->oss.period_bytes;
- info.bytes = (runtime->oss.bytes - delay) & INT_MAX;
- } else {
- delay += fixup;
- info.blocks = delay / runtime->oss.period_bytes;
- info.bytes = (runtime->oss.bytes + delay) & INT_MAX;
- }
- }
- if (copy_to_user(_info, &info, sizeof(info)))
- return -EFAULT;
- return 0;
-}
-
-static int snd_pcm_oss_get_space(struct snd_pcm_oss_file *pcm_oss_file, int stream, struct audio_buf_info __user *_info)
-{
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
- snd_pcm_sframes_t avail;
- int fixup;
- struct audio_buf_info info;
- int err;
-
- if (_info == NULL)
- return -EFAULT;
- substream = pcm_oss_file->streams[stream];
- if (substream == NULL)
- return -EINVAL;
- runtime = substream->runtime;
-
- if (runtime->oss.params &&
- (err = snd_pcm_oss_change_params(substream)) < 0)
- return err;
-
- info.fragsize = runtime->oss.period_bytes;
- info.fragstotal = runtime->periods;
- if (runtime->oss.prepare) {
- if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
- info.bytes = runtime->oss.period_bytes * runtime->oss.periods;
- info.fragments = runtime->oss.periods;
- } else {
- info.bytes = 0;
- info.fragments = 0;
- }
- } else {
- if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
- err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, &avail);
- if (err == -EPIPE || err == -ESTRPIPE || (! err && avail < 0)) {
- avail = runtime->buffer_size;
- err = 0;
- fixup = 0;
- } else {
- avail = runtime->buffer_size - avail;
- fixup = -runtime->oss.buffer_used;
- }
- } else {
- err = snd_pcm_oss_capture_position_fixup(substream, &avail);
- fixup = runtime->oss.buffer_used;
- }
- if (err < 0)
- return err;
- info.bytes = snd_pcm_oss_bytes(substream, avail) + fixup;
- info.fragments = info.bytes / runtime->oss.period_bytes;
- }
-
-#ifdef OSS_DEBUG
- printk(KERN_DEBUG "pcm_oss: space: bytes = %i, fragments = %i, "
- "fragstotal = %i, fragsize = %i\n",
- info.bytes, info.fragments, info.fragstotal, info.fragsize);
-#endif
- if (copy_to_user(_info, &info, sizeof(info)))
- return -EFAULT;
- return 0;
-}
-
-static int snd_pcm_oss_get_mapbuf(struct snd_pcm_oss_file *pcm_oss_file, int stream, struct buffmem_desc __user * _info)
-{
- // it won't be probably implemented
- // snd_printd("TODO: snd_pcm_oss_get_mapbuf\n");
- return -EINVAL;
-}
-
-static const char *strip_task_path(const char *path)
-{
- const char *ptr, *ptrl = NULL;
- for (ptr = path; *ptr; ptr++) {
- if (*ptr == '/')
- ptrl = ptr + 1;
- }
- return ptrl;
-}
-
-static void snd_pcm_oss_look_for_setup(struct snd_pcm *pcm, int stream,
- const char *task_name,
- struct snd_pcm_oss_setup *rsetup)
-{
- struct snd_pcm_oss_setup *setup;
-
- mutex_lock(&pcm->streams[stream].oss.setup_mutex);
- do {
- for (setup = pcm->streams[stream].oss.setup_list; setup;
- setup = setup->next) {
- if (!strcmp(setup->task_name, task_name))
- goto out;
- }
- } while ((task_name = strip_task_path(task_name)) != NULL);
- out:
- if (setup)
- *rsetup = *setup;
- mutex_unlock(&pcm->streams[stream].oss.setup_mutex);
-}
-
-static void snd_pcm_oss_release_substream(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime;
- runtime = substream->runtime;
- vfree(runtime->oss.buffer);
- runtime->oss.buffer = NULL;
-#ifdef CONFIG_SND_PCM_OSS_PLUGINS
- snd_pcm_oss_plugin_clear(substream);
-#endif
- substream->oss.oss = 0;
-}
-
-static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream,
- struct snd_pcm_oss_setup *setup,
- int minor)
-{
- struct snd_pcm_runtime *runtime;
-
- substream->oss.oss = 1;
- substream->oss.setup = *setup;
- if (setup->nonblock)
- substream->f_flags |= O_NONBLOCK;
- else if (setup->block)
- substream->f_flags &= ~O_NONBLOCK;
- runtime = substream->runtime;
- runtime->oss.params = 1;
- runtime->oss.trigger = 1;
- runtime->oss.rate = 8000;
- mutex_init(&runtime->oss.params_lock);
- switch (SNDRV_MINOR_OSS_DEVICE(minor)) {
- case SNDRV_MINOR_OSS_PCM_8:
- runtime->oss.format = AFMT_U8;
- break;
- case SNDRV_MINOR_OSS_PCM_16:
- runtime->oss.format = AFMT_S16_LE;
- break;
- default:
- runtime->oss.format = AFMT_MU_LAW;
- }
- runtime->oss.channels = 1;
- runtime->oss.fragshift = 0;
- runtime->oss.maxfrags = 0;
- runtime->oss.subdivision = 0;
- substream->pcm_release = snd_pcm_oss_release_substream;
-}
-
-static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file)
-{
- int cidx;
- if (!pcm_oss_file)
- return 0;
- for (cidx = 0; cidx < 2; ++cidx) {
- struct snd_pcm_substream *substream = pcm_oss_file->streams[cidx];
- if (substream)
- snd_pcm_release_substream(substream);
- }
- kfree(pcm_oss_file);
- return 0;
-}
-
-static int snd_pcm_oss_open_file(struct file *file,
- struct snd_pcm *pcm,
- struct snd_pcm_oss_file **rpcm_oss_file,
- int minor,
- struct snd_pcm_oss_setup *setup)
-{
- int idx, err;
- struct snd_pcm_oss_file *pcm_oss_file;
- struct snd_pcm_substream *substream;
- fmode_t f_mode = file->f_mode;
-
- if (rpcm_oss_file)
- *rpcm_oss_file = NULL;
-
- pcm_oss_file = kzalloc(sizeof(*pcm_oss_file), GFP_KERNEL);
- if (pcm_oss_file == NULL)
- return -ENOMEM;
-
- if ((f_mode & (FMODE_WRITE|FMODE_READ)) == (FMODE_WRITE|FMODE_READ) &&
- (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX))
- f_mode = FMODE_WRITE;
-
- file->f_flags &= ~O_APPEND;
- for (idx = 0; idx < 2; idx++) {
- if (setup[idx].disable)
- continue;
- if (! pcm->streams[idx].substream_count)
- continue; /* no matching substream */
- if (idx == SNDRV_PCM_STREAM_PLAYBACK) {
- if (! (f_mode & FMODE_WRITE))
- continue;
- } else {
- if (! (f_mode & FMODE_READ))
- continue;
- }
- err = snd_pcm_open_substream(pcm, idx, file, &substream);
- if (err < 0) {
- snd_pcm_oss_release_file(pcm_oss_file);
- return err;
- }
-
- pcm_oss_file->streams[idx] = substream;
- substream->file = pcm_oss_file;
- snd_pcm_oss_init_substream(substream, &setup[idx], minor);
- }
-
- if (!pcm_oss_file->streams[0] && !pcm_oss_file->streams[1]) {
- snd_pcm_oss_release_file(pcm_oss_file);
- return -EINVAL;
- }
-
- file->private_data = pcm_oss_file;
- if (rpcm_oss_file)
- *rpcm_oss_file = pcm_oss_file;
- return 0;
-}
-
-
-static int snd_task_name(struct task_struct *task, char *name, size_t size)
-{
- unsigned int idx;
-
- if (snd_BUG_ON(!task || !name || size < 2))
- return -EINVAL;
- for (idx = 0; idx < sizeof(task->comm) && idx + 1 < size; idx++)
- name[idx] = task->comm[idx];
- name[idx] = '\0';
- return 0;
-}
-
-static int snd_pcm_oss_open(struct inode *inode, struct file *file)
-{
- int err;
- char task_name[32];
- struct snd_pcm *pcm;
- struct snd_pcm_oss_file *pcm_oss_file;
- struct snd_pcm_oss_setup setup[2];
- int nonblock;
- wait_queue_t wait;
-
- err = nonseekable_open(inode, file);
- if (err < 0)
- return err;
-
- pcm = snd_lookup_oss_minor_data(iminor(inode),
- SNDRV_OSS_DEVICE_TYPE_PCM);
- if (pcm == NULL) {
- err = -ENODEV;
- goto __error1;
- }
- err = snd_card_file_add(pcm->card, file);
- if (err < 0)
- goto __error1;
- if (!try_module_get(pcm->card->module)) {
- err = -EFAULT;
- goto __error2;
- }
- if (snd_task_name(current, task_name, sizeof(task_name)) < 0) {
- err = -EFAULT;
- goto __error;
- }
- memset(setup, 0, sizeof(setup));
- if (file->f_mode & FMODE_WRITE)
- snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- task_name, &setup[0]);
- if (file->f_mode & FMODE_READ)
- snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_CAPTURE,
- task_name, &setup[1]);
-
- nonblock = !!(file->f_flags & O_NONBLOCK);
- if (!nonblock)
- nonblock = nonblock_open;
-
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&pcm->open_wait, &wait);
- mutex_lock(&pcm->open_mutex);
- while (1) {
- err = snd_pcm_oss_open_file(file, pcm, &pcm_oss_file,
- iminor(inode), setup);
- if (err >= 0)
- break;
- if (err == -EAGAIN) {
- if (nonblock) {
- err = -EBUSY;
- break;
- }
- } else
- break;
- set_current_state(TASK_INTERRUPTIBLE);
- mutex_unlock(&pcm->open_mutex);
- schedule();
- mutex_lock(&pcm->open_mutex);
- if (pcm->card->shutdown) {
- err = -ENODEV;
- break;
- }
- if (signal_pending(current)) {
- err = -ERESTARTSYS;
- break;
- }
- }
- remove_wait_queue(&pcm->open_wait, &wait);
- mutex_unlock(&pcm->open_mutex);
- if (err < 0)
- goto __error;
- snd_card_unref(pcm->card);
- return err;
-
- __error:
- module_put(pcm->card->module);
- __error2:
- snd_card_file_remove(pcm->card, file);
- __error1:
- if (pcm)
- snd_card_unref(pcm->card);
- return err;
-}
-
-static int snd_pcm_oss_release(struct inode *inode, struct file *file)
-{
- struct snd_pcm *pcm;
- struct snd_pcm_substream *substream;
- struct snd_pcm_oss_file *pcm_oss_file;
-
- pcm_oss_file = file->private_data;
- substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
- if (substream == NULL)
- substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
- if (snd_BUG_ON(!substream))
- return -ENXIO;
- pcm = substream->pcm;
- if (!pcm->card->shutdown)
- snd_pcm_oss_sync(pcm_oss_file);
- mutex_lock(&pcm->open_mutex);
- snd_pcm_oss_release_file(pcm_oss_file);
- mutex_unlock(&pcm->open_mutex);
- wake_up(&pcm->open_wait);
- module_put(pcm->card->module);
- snd_card_file_remove(pcm->card, file);
- return 0;
-}
-
-static long snd_pcm_oss_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct snd_pcm_oss_file *pcm_oss_file;
- int __user *p = (int __user *)arg;
- int res;
-
- pcm_oss_file = file->private_data;
- if (cmd == OSS_GETVERSION)
- return put_user(SNDRV_OSS_VERSION, p);
- if (cmd == OSS_ALSAEMULVER)
- return put_user(1, p);
-#if defined(CONFIG_SND_MIXER_OSS) || (defined(MODULE) && defined(CONFIG_SND_MIXER_OSS_MODULE))
- if (((cmd >> 8) & 0xff) == 'M') { /* mixer ioctl - for OSS compatibility */
- struct snd_pcm_substream *substream;
- int idx;
- for (idx = 0; idx < 2; ++idx) {
- substream = pcm_oss_file->streams[idx];
- if (substream != NULL)
- break;
- }
- if (snd_BUG_ON(idx >= 2))
- return -ENXIO;
- return snd_mixer_oss_ioctl_card(substream->pcm->card, cmd, arg);
- }
-#endif
- if (((cmd >> 8) & 0xff) != 'P')
- return -EINVAL;
-#ifdef OSS_DEBUG
- printk(KERN_DEBUG "pcm_oss: ioctl = 0x%x\n", cmd);
-#endif
- switch (cmd) {
- case SNDCTL_DSP_RESET:
- return snd_pcm_oss_reset(pcm_oss_file);
- case SNDCTL_DSP_SYNC:
- return snd_pcm_oss_sync(pcm_oss_file);
- case SNDCTL_DSP_SPEED:
- if (get_user(res, p))
- return -EFAULT;
- if ((res = snd_pcm_oss_set_rate(pcm_oss_file, res))<0)
- return res;
- return put_user(res, p);
- case SOUND_PCM_READ_RATE:
- res = snd_pcm_oss_get_rate(pcm_oss_file);
- if (res < 0)
- return res;
- return put_user(res, p);
- case SNDCTL_DSP_STEREO:
- if (get_user(res, p))
- return -EFAULT;
- res = res > 0 ? 2 : 1;
- if ((res = snd_pcm_oss_set_channels(pcm_oss_file, res)) < 0)
- return res;
- return put_user(--res, p);
- case SNDCTL_DSP_GETBLKSIZE:
- res = snd_pcm_oss_get_block_size(pcm_oss_file);
- if (res < 0)
- return res;
- return put_user(res, p);
- case SNDCTL_DSP_SETFMT:
- if (get_user(res, p))
- return -EFAULT;
- res = snd_pcm_oss_set_format(pcm_oss_file, res);
- if (res < 0)
- return res;
- return put_user(res, p);
- case SOUND_PCM_READ_BITS:
- res = snd_pcm_oss_get_format(pcm_oss_file);
- if (res < 0)
- return res;
- return put_user(res, p);
- case SNDCTL_DSP_CHANNELS:
- if (get_user(res, p))
- return -EFAULT;
- res = snd_pcm_oss_set_channels(pcm_oss_file, res);
- if (res < 0)
- return res;
- return put_user(res, p);
- case SOUND_PCM_READ_CHANNELS:
- res = snd_pcm_oss_get_channels(pcm_oss_file);
- if (res < 0)
- return res;
- return put_user(res, p);
- case SOUND_PCM_WRITE_FILTER:
- case SOUND_PCM_READ_FILTER:
- return -EIO;
- case SNDCTL_DSP_POST:
- return snd_pcm_oss_post(pcm_oss_file);
- case SNDCTL_DSP_SUBDIVIDE:
- if (get_user(res, p))
- return -EFAULT;
- res = snd_pcm_oss_set_subdivide(pcm_oss_file, res);
- if (res < 0)
- return res;
- return put_user(res, p);
- case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(res, p))
- return -EFAULT;
- return snd_pcm_oss_set_fragment(pcm_oss_file, res);
- case SNDCTL_DSP_GETFMTS:
- res = snd_pcm_oss_get_formats(pcm_oss_file);
- if (res < 0)
- return res;
- return put_user(res, p);
- case SNDCTL_DSP_GETOSPACE:
- case SNDCTL_DSP_GETISPACE:
- return snd_pcm_oss_get_space(pcm_oss_file,
- cmd == SNDCTL_DSP_GETISPACE ?
- SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK,
- (struct audio_buf_info __user *) arg);
- case SNDCTL_DSP_NONBLOCK:
- return snd_pcm_oss_nonblock(file);
- case SNDCTL_DSP_GETCAPS:
- res = snd_pcm_oss_get_caps(pcm_oss_file);
- if (res < 0)
- return res;
- return put_user(res, p);
- case SNDCTL_DSP_GETTRIGGER:
- res = snd_pcm_oss_get_trigger(pcm_oss_file);
- if (res < 0)
- return res;
- return put_user(res, p);
- case SNDCTL_DSP_SETTRIGGER:
- if (get_user(res, p))
- return -EFAULT;
- return snd_pcm_oss_set_trigger(pcm_oss_file, res);
- case SNDCTL_DSP_GETIPTR:
- case SNDCTL_DSP_GETOPTR:
- return snd_pcm_oss_get_ptr(pcm_oss_file,
- cmd == SNDCTL_DSP_GETIPTR ?
- SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK,
- (struct count_info __user *) arg);
- case SNDCTL_DSP_MAPINBUF:
- case SNDCTL_DSP_MAPOUTBUF:
- return snd_pcm_oss_get_mapbuf(pcm_oss_file,
- cmd == SNDCTL_DSP_MAPINBUF ?
- SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK,
- (struct buffmem_desc __user *) arg);
- case SNDCTL_DSP_SETSYNCRO:
- /* stop DMA now.. */
- return 0;
- case SNDCTL_DSP_SETDUPLEX:
- if (snd_pcm_oss_get_caps(pcm_oss_file) & DSP_CAP_DUPLEX)
- return 0;
- return -EIO;
- case SNDCTL_DSP_GETODELAY:
- res = snd_pcm_oss_get_odelay(pcm_oss_file);
- if (res < 0) {
- /* it's for sure, some broken apps don't check for error codes */
- put_user(0, p);
- return res;
- }
- return put_user(res, p);
- case SNDCTL_DSP_PROFILE:
- return 0; /* silently ignore */
- default:
- snd_printd("pcm_oss: unknown command = 0x%x\n", cmd);
- }
- return -EINVAL;
-}
-
-#ifdef CONFIG_COMPAT
-/* all compatible */
-#define snd_pcm_oss_ioctl_compat snd_pcm_oss_ioctl
-#else
-#define snd_pcm_oss_ioctl_compat NULL
-#endif
-
-static ssize_t snd_pcm_oss_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
-{
- struct snd_pcm_oss_file *pcm_oss_file;
- struct snd_pcm_substream *substream;
-
- pcm_oss_file = file->private_data;
- substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
- if (substream == NULL)
- return -ENXIO;
- substream->f_flags = file->f_flags & O_NONBLOCK;
-#ifndef OSS_DEBUG
- return snd_pcm_oss_read1(substream, buf, count);
-#else
- {
- ssize_t res = snd_pcm_oss_read1(substream, buf, count);
- printk(KERN_DEBUG "pcm_oss: read %li bytes "
- "(returned %li bytes)\n", (long)count, (long)res);
- return res;
- }
-#endif
-}
-
-static ssize_t snd_pcm_oss_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
-{
- struct snd_pcm_oss_file *pcm_oss_file;
- struct snd_pcm_substream *substream;
- long result;
-
- pcm_oss_file = file->private_data;
- substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
- if (substream == NULL)
- return -ENXIO;
- substream->f_flags = file->f_flags & O_NONBLOCK;
- result = snd_pcm_oss_write1(substream, buf, count);
-#ifdef OSS_DEBUG
- printk(KERN_DEBUG "pcm_oss: write %li bytes (wrote %li bytes)\n",
- (long)count, (long)result);
-#endif
- return result;
-}
-
-static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- if (atomic_read(&substream->mmap_count))
- return runtime->oss.prev_hw_ptr_period !=
- get_hw_ptr_period(runtime);
- else
- return snd_pcm_playback_avail(runtime) >=
- runtime->oss.period_frames;
-}
-
-static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- if (atomic_read(&substream->mmap_count))
- return runtime->oss.prev_hw_ptr_period !=
- get_hw_ptr_period(runtime);
- else
- return snd_pcm_capture_avail(runtime) >=
- runtime->oss.period_frames;
-}
-
-static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait)
-{
- struct snd_pcm_oss_file *pcm_oss_file;
- unsigned int mask;
- struct snd_pcm_substream *psubstream = NULL, *csubstream = NULL;
-
- pcm_oss_file = file->private_data;
-
- psubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
- csubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
-
- mask = 0;
- if (psubstream != NULL) {
- struct snd_pcm_runtime *runtime = psubstream->runtime;
- poll_wait(file, &runtime->sleep, wait);
- snd_pcm_stream_lock_irq(psubstream);
- if (runtime->status->state != SNDRV_PCM_STATE_DRAINING &&
- (runtime->status->state != SNDRV_PCM_STATE_RUNNING ||
- snd_pcm_oss_playback_ready(psubstream)))
- mask |= POLLOUT | POLLWRNORM;
- snd_pcm_stream_unlock_irq(psubstream);
- }
- if (csubstream != NULL) {
- struct snd_pcm_runtime *runtime = csubstream->runtime;
- snd_pcm_state_t ostate;
- poll_wait(file, &runtime->sleep, wait);
- snd_pcm_stream_lock_irq(csubstream);
- if ((ostate = runtime->status->state) != SNDRV_PCM_STATE_RUNNING ||
- snd_pcm_oss_capture_ready(csubstream))
- mask |= POLLIN | POLLRDNORM;
- snd_pcm_stream_unlock_irq(csubstream);
- if (ostate != SNDRV_PCM_STATE_RUNNING && runtime->oss.trigger) {
- struct snd_pcm_oss_file ofile;
- memset(&ofile, 0, sizeof(ofile));
- ofile.streams[SNDRV_PCM_STREAM_CAPTURE] = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
- runtime->oss.trigger = 0;
- snd_pcm_oss_set_trigger(&ofile, PCM_ENABLE_INPUT);
- }
- }
-
- return mask;
-}
-
-static int snd_pcm_oss_mmap(struct file *file, struct vm_area_struct *area)
-{
- struct snd_pcm_oss_file *pcm_oss_file;
- struct snd_pcm_substream *substream = NULL;
- struct snd_pcm_runtime *runtime;
- int err;
-
-#ifdef OSS_DEBUG
- printk(KERN_DEBUG "pcm_oss: mmap begin\n");
-#endif
- pcm_oss_file = file->private_data;
- switch ((area->vm_flags & (VM_READ | VM_WRITE))) {
- case VM_READ | VM_WRITE:
- substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
- if (substream)
- break;
- /* Fall through */
- case VM_READ:
- substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
- break;
- case VM_WRITE:
- substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
- break;
- default:
- return -EINVAL;
- }
- /* set VM_READ access as well to fix memset() routines that do
- reads before writes (to improve performance) */
- area->vm_flags |= VM_READ;
- if (substream == NULL)
- return -ENXIO;
- runtime = substream->runtime;
- if (!(runtime->info & SNDRV_PCM_INFO_MMAP_VALID))
- return -EIO;
- if (runtime->info & SNDRV_PCM_INFO_INTERLEAVED)
- runtime->access = SNDRV_PCM_ACCESS_MMAP_INTERLEAVED;
- else
- return -EIO;
-
- if (runtime->oss.params) {
- if ((err = snd_pcm_oss_change_params(substream)) < 0)
- return err;
- }
-#ifdef CONFIG_SND_PCM_OSS_PLUGINS
- if (runtime->oss.plugin_first != NULL)
- return -EIO;
-#endif
-
- if (area->vm_pgoff != 0)
- return -EINVAL;
-
- err = snd_pcm_mmap_data(substream, file, area);
- if (err < 0)
- return err;
- runtime->oss.mmap_bytes = area->vm_end - area->vm_start;
- runtime->silence_threshold = 0;
- runtime->silence_size = 0;
-#ifdef OSS_DEBUG
- printk(KERN_DEBUG "pcm_oss: mmap ok, bytes = 0x%x\n",
- runtime->oss.mmap_bytes);
-#endif
- /* In mmap mode we never stop */
- runtime->stop_threshold = runtime->boundary;
-
- return 0;
-}
-
-#ifdef CONFIG_SND_VERBOSE_PROCFS
-/*
- * /proc interface
- */
-
-static void snd_pcm_oss_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_pcm_str *pstr = entry->private_data;
- struct snd_pcm_oss_setup *setup = pstr->oss.setup_list;
- mutex_lock(&pstr->oss.setup_mutex);
- while (setup) {
- snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n",
- setup->task_name,
- setup->periods,
- setup->period_size,
- setup->disable ? " disable" : "",
- setup->direct ? " direct" : "",
- setup->block ? " block" : "",
- setup->nonblock ? " non-block" : "",
- setup->partialfrag ? " partial-frag" : "",
- setup->nosilence ? " no-silence" : "");
- setup = setup->next;
- }
- mutex_unlock(&pstr->oss.setup_mutex);
-}
-
-static void snd_pcm_oss_proc_free_setup_list(struct snd_pcm_str * pstr)
-{
- struct snd_pcm_oss_setup *setup, *setupn;
-
- for (setup = pstr->oss.setup_list, pstr->oss.setup_list = NULL;
- setup; setup = setupn) {
- setupn = setup->next;
- kfree(setup->task_name);
- kfree(setup);
- }
- pstr->oss.setup_list = NULL;
-}
-
-static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_pcm_str *pstr = entry->private_data;
- char line[128], str[32], task_name[32];
- const char *ptr;
- int idx1;
- struct snd_pcm_oss_setup *setup, *setup1, template;
-
- while (!snd_info_get_line(buffer, line, sizeof(line))) {
- mutex_lock(&pstr->oss.setup_mutex);
- memset(&template, 0, sizeof(template));
- ptr = snd_info_get_str(task_name, line, sizeof(task_name));
- if (!strcmp(task_name, "clear") || !strcmp(task_name, "erase")) {
- snd_pcm_oss_proc_free_setup_list(pstr);
- mutex_unlock(&pstr->oss.setup_mutex);
- continue;
- }
- for (setup = pstr->oss.setup_list; setup; setup = setup->next) {
- if (!strcmp(setup->task_name, task_name)) {
- template = *setup;
- break;
- }
- }
- ptr = snd_info_get_str(str, ptr, sizeof(str));
- template.periods = simple_strtoul(str, NULL, 10);
- ptr = snd_info_get_str(str, ptr, sizeof(str));
- template.period_size = simple_strtoul(str, NULL, 10);
- for (idx1 = 31; idx1 >= 0; idx1--)
- if (template.period_size & (1 << idx1))
- break;
- for (idx1--; idx1 >= 0; idx1--)
- template.period_size &= ~(1 << idx1);
- do {
- ptr = snd_info_get_str(str, ptr, sizeof(str));
- if (!strcmp(str, "disable")) {
- template.disable = 1;
- } else if (!strcmp(str, "direct")) {
- template.direct = 1;
- } else if (!strcmp(str, "block")) {
- template.block = 1;
- } else if (!strcmp(str, "non-block")) {
- template.nonblock = 1;
- } else if (!strcmp(str, "partial-frag")) {
- template.partialfrag = 1;
- } else if (!strcmp(str, "no-silence")) {
- template.nosilence = 1;
- } else if (!strcmp(str, "buggy-ptr")) {
- template.buggyptr = 1;
- }
- } while (*str);
- if (setup == NULL) {
- setup = kmalloc(sizeof(*setup), GFP_KERNEL);
- if (! setup) {
- buffer->error = -ENOMEM;
- mutex_unlock(&pstr->oss.setup_mutex);
- return;
- }
- if (pstr->oss.setup_list == NULL)
- pstr->oss.setup_list = setup;
- else {
- for (setup1 = pstr->oss.setup_list;
- setup1->next; setup1 = setup1->next);
- setup1->next = setup;
- }
- template.task_name = kstrdup(task_name, GFP_KERNEL);
- if (! template.task_name) {
- kfree(setup);
- buffer->error = -ENOMEM;
- mutex_unlock(&pstr->oss.setup_mutex);
- return;
- }
- }
- *setup = template;
- mutex_unlock(&pstr->oss.setup_mutex);
- }
-}
-
-static void snd_pcm_oss_proc_init(struct snd_pcm *pcm)
-{
- int stream;
- for (stream = 0; stream < 2; ++stream) {
- struct snd_info_entry *entry;
- struct snd_pcm_str *pstr = &pcm->streams[stream];
- if (pstr->substream_count == 0)
- continue;
- if ((entry = snd_info_create_card_entry(pcm->card, "oss", pstr->proc_root)) != NULL) {
- entry->content = SNDRV_INFO_CONTENT_TEXT;
- entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
- entry->c.text.read = snd_pcm_oss_proc_read;
- entry->c.text.write = snd_pcm_oss_proc_write;
- entry->private_data = pstr;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- pstr->oss.proc_entry = entry;
- }
-}
-
-static void snd_pcm_oss_proc_done(struct snd_pcm *pcm)
-{
- int stream;
- for (stream = 0; stream < 2; ++stream) {
- struct snd_pcm_str *pstr = &pcm->streams[stream];
- snd_info_free_entry(pstr->oss.proc_entry);
- pstr->oss.proc_entry = NULL;
- snd_pcm_oss_proc_free_setup_list(pstr);
- }
-}
-#else /* !CONFIG_SND_VERBOSE_PROCFS */
-#define snd_pcm_oss_proc_init(pcm)
-#define snd_pcm_oss_proc_done(pcm)
-#endif /* CONFIG_SND_VERBOSE_PROCFS */
-
-/*
- * ENTRY functions
- */
-
-static const struct file_operations snd_pcm_oss_f_reg =
-{
- .owner = THIS_MODULE,
- .read = snd_pcm_oss_read,
- .write = snd_pcm_oss_write,
- .open = snd_pcm_oss_open,
- .release = snd_pcm_oss_release,
- .llseek = no_llseek,
- .poll = snd_pcm_oss_poll,
- .unlocked_ioctl = snd_pcm_oss_ioctl,
- .compat_ioctl = snd_pcm_oss_ioctl_compat,
- .mmap = snd_pcm_oss_mmap,
-};
-
-static void register_oss_dsp(struct snd_pcm *pcm, int index)
-{
- char name[128];
- sprintf(name, "dsp%i%i", pcm->card->number, pcm->device);
- if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM,
- pcm->card, index, &snd_pcm_oss_f_reg,
- pcm, name) < 0) {
- snd_printk(KERN_ERR "unable to register OSS PCM device %i:%i\n",
- pcm->card->number, pcm->device);
- }
-}
-
-static int snd_pcm_oss_register_minor(struct snd_pcm *pcm)
-{
- pcm->oss.reg = 0;
- if (dsp_map[pcm->card->number] == (int)pcm->device) {
- char name[128];
- int duplex;
- register_oss_dsp(pcm, 0);
- duplex = (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count > 0 &&
- pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count &&
- !(pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX));
- sprintf(name, "%s%s", pcm->name, duplex ? " (DUPLEX)" : "");
-#ifdef SNDRV_OSS_INFO_DEV_AUDIO
- snd_oss_info_register(SNDRV_OSS_INFO_DEV_AUDIO,
- pcm->card->number,
- name);
-#endif
- pcm->oss.reg++;
- pcm->oss.reg_mask |= 1;
- }
- if (adsp_map[pcm->card->number] == (int)pcm->device) {
- register_oss_dsp(pcm, 1);
- pcm->oss.reg++;
- pcm->oss.reg_mask |= 2;
- }
-
- if (pcm->oss.reg)
- snd_pcm_oss_proc_init(pcm);
-
- return 0;
-}
-
-static int snd_pcm_oss_disconnect_minor(struct snd_pcm *pcm)
-{
- if (pcm->oss.reg) {
- if (pcm->oss.reg_mask & 1) {
- pcm->oss.reg_mask &= ~1;
- snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM,
- pcm->card, 0);
- }
- if (pcm->oss.reg_mask & 2) {
- pcm->oss.reg_mask &= ~2;
- snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM,
- pcm->card, 1);
- }
- if (dsp_map[pcm->card->number] == (int)pcm->device) {
-#ifdef SNDRV_OSS_INFO_DEV_AUDIO
- snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_AUDIO, pcm->card->number);
-#endif
- }
- pcm->oss.reg = 0;
- }
- return 0;
-}
-
-static int snd_pcm_oss_unregister_minor(struct snd_pcm *pcm)
-{
- snd_pcm_oss_disconnect_minor(pcm);
- snd_pcm_oss_proc_done(pcm);
- return 0;
-}
-
-static struct snd_pcm_notify snd_pcm_oss_notify =
-{
- .n_register = snd_pcm_oss_register_minor,
- .n_disconnect = snd_pcm_oss_disconnect_minor,
- .n_unregister = snd_pcm_oss_unregister_minor,
-};
-
-static int __init alsa_pcm_oss_init(void)
-{
- int i;
- int err;
-
- /* check device map table */
- for (i = 0; i < SNDRV_CARDS; i++) {
- if (dsp_map[i] < 0 || dsp_map[i] >= SNDRV_PCM_DEVICES) {
- snd_printk(KERN_ERR "invalid dsp_map[%d] = %d\n",
- i, dsp_map[i]);
- dsp_map[i] = 0;
- }
- if (adsp_map[i] < 0 || adsp_map[i] >= SNDRV_PCM_DEVICES) {
- snd_printk(KERN_ERR "invalid adsp_map[%d] = %d\n",
- i, adsp_map[i]);
- adsp_map[i] = 1;
- }
- }
- if ((err = snd_pcm_notify(&snd_pcm_oss_notify, 0)) < 0)
- return err;
- return 0;
-}
-
-static void __exit alsa_pcm_oss_exit(void)
-{
- snd_pcm_notify(&snd_pcm_oss_notify, 1);
-}
-
-module_init(alsa_pcm_oss_init)
-module_exit(alsa_pcm_oss_exit)
diff --git a/ANDROID_3.4.5/sound/core/oss/pcm_plugin.c b/ANDROID_3.4.5/sound/core/oss/pcm_plugin.c
deleted file mode 100644
index 71cc3ddf..00000000
--- a/ANDROID_3.4.5/sound/core/oss/pcm_plugin.c
+++ /dev/null
@@ -1,756 +0,0 @@
-/*
- * PCM Plug-In shared (kernel/library) code
- * Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
- * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
- *
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#if 0
-#define PLUGIN_DEBUG
-#endif
-
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/vmalloc.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include "pcm_plugin.h"
-
-#define snd_pcm_plug_first(plug) ((plug)->runtime->oss.plugin_first)
-#define snd_pcm_plug_last(plug) ((plug)->runtime->oss.plugin_last)
-
-/*
- * because some cards might have rates "very close", we ignore
- * all "resampling" requests within +-5%
- */
-static int rate_match(unsigned int src_rate, unsigned int dst_rate)
-{
- unsigned int low = (src_rate * 95) / 100;
- unsigned int high = (src_rate * 105) / 100;
- return dst_rate >= low && dst_rate <= high;
-}
-
-static int snd_pcm_plugin_alloc(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t frames)
-{
- struct snd_pcm_plugin_format *format;
- ssize_t width;
- size_t size;
- unsigned int channel;
- struct snd_pcm_plugin_channel *c;
-
- if (plugin->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- format = &plugin->src_format;
- } else {
- format = &plugin->dst_format;
- }
- if ((width = snd_pcm_format_physical_width(format->format)) < 0)
- return width;
- size = frames * format->channels * width;
- if (snd_BUG_ON(size % 8))
- return -ENXIO;
- size /= 8;
- if (plugin->buf_frames < frames) {
- vfree(plugin->buf);
- plugin->buf = vmalloc(size);
- plugin->buf_frames = frames;
- }
- if (!plugin->buf) {
- plugin->buf_frames = 0;
- return -ENOMEM;
- }
- c = plugin->buf_channels;
- if (plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) {
- for (channel = 0; channel < format->channels; channel++, c++) {
- c->frames = frames;
- c->enabled = 1;
- c->wanted = 0;
- c->area.addr = plugin->buf;
- c->area.first = channel * width;
- c->area.step = format->channels * width;
- }
- } else if (plugin->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) {
- if (snd_BUG_ON(size % format->channels))
- return -EINVAL;
- size /= format->channels;
- for (channel = 0; channel < format->channels; channel++, c++) {
- c->frames = frames;
- c->enabled = 1;
- c->wanted = 0;
- c->area.addr = plugin->buf + (channel * size);
- c->area.first = 0;
- c->area.step = width;
- }
- } else
- return -EINVAL;
- return 0;
-}
-
-int snd_pcm_plug_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t frames)
-{
- int err;
- if (snd_BUG_ON(!snd_pcm_plug_first(plug)))
- return -ENXIO;
- if (snd_pcm_plug_stream(plug) == SNDRV_PCM_STREAM_PLAYBACK) {
- struct snd_pcm_plugin *plugin = snd_pcm_plug_first(plug);
- while (plugin->next) {
- if (plugin->dst_frames)
- frames = plugin->dst_frames(plugin, frames);
- if (snd_BUG_ON(frames <= 0))
- return -ENXIO;
- plugin = plugin->next;
- err = snd_pcm_plugin_alloc(plugin, frames);
- if (err < 0)
- return err;
- }
- } else {
- struct snd_pcm_plugin *plugin = snd_pcm_plug_last(plug);
- while (plugin->prev) {
- if (plugin->src_frames)
- frames = plugin->src_frames(plugin, frames);
- if (snd_BUG_ON(frames <= 0))
- return -ENXIO;
- plugin = plugin->prev;
- err = snd_pcm_plugin_alloc(plugin, frames);
- if (err < 0)
- return err;
- }
- }
- return 0;
-}
-
-
-snd_pcm_sframes_t snd_pcm_plugin_client_channels(struct snd_pcm_plugin *plugin,
- snd_pcm_uframes_t frames,
- struct snd_pcm_plugin_channel **channels)
-{
- *channels = plugin->buf_channels;
- return frames;
-}
-
-int snd_pcm_plugin_build(struct snd_pcm_substream *plug,
- const char *name,
- struct snd_pcm_plugin_format *src_format,
- struct snd_pcm_plugin_format *dst_format,
- size_t extra,
- struct snd_pcm_plugin **ret)
-{
- struct snd_pcm_plugin *plugin;
- unsigned int channels;
-
- if (snd_BUG_ON(!plug))
- return -ENXIO;
- if (snd_BUG_ON(!src_format || !dst_format))
- return -ENXIO;
- plugin = kzalloc(sizeof(*plugin) + extra, GFP_KERNEL);
- if (plugin == NULL)
- return -ENOMEM;
- plugin->name = name;
- plugin->plug = plug;
- plugin->stream = snd_pcm_plug_stream(plug);
- plugin->access = SNDRV_PCM_ACCESS_RW_INTERLEAVED;
- plugin->src_format = *src_format;
- plugin->src_width = snd_pcm_format_physical_width(src_format->format);
- snd_BUG_ON(plugin->src_width <= 0);
- plugin->dst_format = *dst_format;
- plugin->dst_width = snd_pcm_format_physical_width(dst_format->format);
- snd_BUG_ON(plugin->dst_width <= 0);
- if (plugin->stream == SNDRV_PCM_STREAM_PLAYBACK)
- channels = src_format->channels;
- else
- channels = dst_format->channels;
- plugin->buf_channels = kcalloc(channels, sizeof(*plugin->buf_channels), GFP_KERNEL);
- if (plugin->buf_channels == NULL) {
- snd_pcm_plugin_free(plugin);
- return -ENOMEM;
- }
- plugin->client_channels = snd_pcm_plugin_client_channels;
- *ret = plugin;
- return 0;
-}
-
-int snd_pcm_plugin_free(struct snd_pcm_plugin *plugin)
-{
- if (! plugin)
- return 0;
- if (plugin->private_free)
- plugin->private_free(plugin);
- kfree(plugin->buf_channels);
- vfree(plugin->buf);
- kfree(plugin);
- return 0;
-}
-
-snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *plug, snd_pcm_uframes_t drv_frames)
-{
- struct snd_pcm_plugin *plugin, *plugin_prev, *plugin_next;
- int stream = snd_pcm_plug_stream(plug);
-
- if (snd_BUG_ON(!plug))
- return -ENXIO;
- if (drv_frames == 0)
- return 0;
- if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
- plugin = snd_pcm_plug_last(plug);
- while (plugin && drv_frames > 0) {
- plugin_prev = plugin->prev;
- if (plugin->src_frames)
- drv_frames = plugin->src_frames(plugin, drv_frames);
- plugin = plugin_prev;
- }
- } else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
- plugin = snd_pcm_plug_first(plug);
- while (plugin && drv_frames > 0) {
- plugin_next = plugin->next;
- if (plugin->dst_frames)
- drv_frames = plugin->dst_frames(plugin, drv_frames);
- plugin = plugin_next;
- }
- } else
- snd_BUG();
- return drv_frames;
-}
-
-snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *plug, snd_pcm_uframes_t clt_frames)
-{
- struct snd_pcm_plugin *plugin, *plugin_prev, *plugin_next;
- snd_pcm_sframes_t frames;
- int stream = snd_pcm_plug_stream(plug);
-
- if (snd_BUG_ON(!plug))
- return -ENXIO;
- if (clt_frames == 0)
- return 0;
- frames = clt_frames;
- if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
- plugin = snd_pcm_plug_first(plug);
- while (plugin && frames > 0) {
- plugin_next = plugin->next;
- if (plugin->dst_frames) {
- frames = plugin->dst_frames(plugin, frames);
- if (frames < 0)
- return frames;
- }
- plugin = plugin_next;
- }
- } else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
- plugin = snd_pcm_plug_last(plug);
- while (plugin) {
- plugin_prev = plugin->prev;
- if (plugin->src_frames) {
- frames = plugin->src_frames(plugin, frames);
- if (frames < 0)
- return frames;
- }
- plugin = plugin_prev;
- }
- } else
- snd_BUG();
- return frames;
-}
-
-static int snd_pcm_plug_formats(struct snd_mask *mask, snd_pcm_format_t format)
-{
- struct snd_mask formats = *mask;
- u64 linfmts = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
- SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_U16_BE | SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_U24_BE | SNDRV_PCM_FMTBIT_S24_BE |
- SNDRV_PCM_FMTBIT_U24_3LE | SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_U24_3BE | SNDRV_PCM_FMTBIT_S24_3BE |
- SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_U32_BE | SNDRV_PCM_FMTBIT_S32_BE);
- snd_mask_set(&formats, (__force int)SNDRV_PCM_FORMAT_MU_LAW);
-
- if (formats.bits[0] & (u32)linfmts)
- formats.bits[0] |= (u32)linfmts;
- if (formats.bits[1] & (u32)(linfmts >> 32))
- formats.bits[1] |= (u32)(linfmts >> 32);
- return snd_mask_test(&formats, (__force int)format);
-}
-
-static snd_pcm_format_t preferred_formats[] = {
- SNDRV_PCM_FORMAT_S16_LE,
- SNDRV_PCM_FORMAT_S16_BE,
- SNDRV_PCM_FORMAT_U16_LE,
- SNDRV_PCM_FORMAT_U16_BE,
- SNDRV_PCM_FORMAT_S24_3LE,
- SNDRV_PCM_FORMAT_S24_3BE,
- SNDRV_PCM_FORMAT_U24_3LE,
- SNDRV_PCM_FORMAT_U24_3BE,
- SNDRV_PCM_FORMAT_S24_LE,
- SNDRV_PCM_FORMAT_S24_BE,
- SNDRV_PCM_FORMAT_U24_LE,
- SNDRV_PCM_FORMAT_U24_BE,
- SNDRV_PCM_FORMAT_S32_LE,
- SNDRV_PCM_FORMAT_S32_BE,
- SNDRV_PCM_FORMAT_U32_LE,
- SNDRV_PCM_FORMAT_U32_BE,
- SNDRV_PCM_FORMAT_S8,
- SNDRV_PCM_FORMAT_U8
-};
-
-snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format,
- struct snd_mask *format_mask)
-{
- int i;
-
- if (snd_mask_test(format_mask, (__force int)format))
- return format;
- if (!snd_pcm_plug_formats(format_mask, format))
- return (__force snd_pcm_format_t)-EINVAL;
- if (snd_pcm_format_linear(format)) {
- unsigned int width = snd_pcm_format_width(format);
- int unsignd = snd_pcm_format_unsigned(format) > 0;
- int big = snd_pcm_format_big_endian(format) > 0;
- unsigned int badness, best = -1;
- snd_pcm_format_t best_format = (__force snd_pcm_format_t)-1;
- for (i = 0; i < ARRAY_SIZE(preferred_formats); i++) {
- snd_pcm_format_t f = preferred_formats[i];
- unsigned int w;
- if (!snd_mask_test(format_mask, (__force int)f))
- continue;
- w = snd_pcm_format_width(f);
- if (w >= width)
- badness = w - width;
- else
- badness = width - w + 32;
- badness += snd_pcm_format_unsigned(f) != unsignd;
- badness += snd_pcm_format_big_endian(f) != big;
- if (badness < best) {
- best_format = f;
- best = badness;
- }
- }
- if ((__force int)best_format >= 0)
- return best_format;
- else
- return (__force snd_pcm_format_t)-EINVAL;
- } else {
- switch (format) {
- case SNDRV_PCM_FORMAT_MU_LAW:
- for (i = 0; i < ARRAY_SIZE(preferred_formats); ++i) {
- snd_pcm_format_t format1 = preferred_formats[i];
- if (snd_mask_test(format_mask, (__force int)format1))
- return format1;
- }
- default:
- return (__force snd_pcm_format_t)-EINVAL;
- }
- }
-}
-
-int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug,
- struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_params *slave_params)
-{
- struct snd_pcm_plugin_format tmpformat;
- struct snd_pcm_plugin_format dstformat;
- struct snd_pcm_plugin_format srcformat;
- snd_pcm_access_t src_access, dst_access;
- struct snd_pcm_plugin *plugin = NULL;
- int err;
- int stream = snd_pcm_plug_stream(plug);
- int slave_interleaved = (params_channels(slave_params) == 1 ||
- params_access(slave_params) == SNDRV_PCM_ACCESS_RW_INTERLEAVED);
-
- switch (stream) {
- case SNDRV_PCM_STREAM_PLAYBACK:
- dstformat.format = params_format(slave_params);
- dstformat.rate = params_rate(slave_params);
- dstformat.channels = params_channels(slave_params);
- srcformat.format = params_format(params);
- srcformat.rate = params_rate(params);
- srcformat.channels = params_channels(params);
- src_access = SNDRV_PCM_ACCESS_RW_INTERLEAVED;
- dst_access = (slave_interleaved ? SNDRV_PCM_ACCESS_RW_INTERLEAVED :
- SNDRV_PCM_ACCESS_RW_NONINTERLEAVED);
- break;
- case SNDRV_PCM_STREAM_CAPTURE:
- dstformat.format = params_format(params);
- dstformat.rate = params_rate(params);
- dstformat.channels = params_channels(params);
- srcformat.format = params_format(slave_params);
- srcformat.rate = params_rate(slave_params);
- srcformat.channels = params_channels(slave_params);
- src_access = (slave_interleaved ? SNDRV_PCM_ACCESS_RW_INTERLEAVED :
- SNDRV_PCM_ACCESS_RW_NONINTERLEAVED);
- dst_access = SNDRV_PCM_ACCESS_RW_INTERLEAVED;
- break;
- default:
- snd_BUG();
- return -EINVAL;
- }
- tmpformat = srcformat;
-
- pdprintf("srcformat: format=%i, rate=%i, channels=%i\n",
- srcformat.format,
- srcformat.rate,
- srcformat.channels);
- pdprintf("dstformat: format=%i, rate=%i, channels=%i\n",
- dstformat.format,
- dstformat.rate,
- dstformat.channels);
-
- /* Format change (linearization) */
- if (! rate_match(srcformat.rate, dstformat.rate) &&
- ! snd_pcm_format_linear(srcformat.format)) {
- if (srcformat.format != SNDRV_PCM_FORMAT_MU_LAW)
- return -EINVAL;
- tmpformat.format = SNDRV_PCM_FORMAT_S16;
- err = snd_pcm_plugin_build_mulaw(plug,
- &srcformat, &tmpformat,
- &plugin);
- if (err < 0)
- return err;
- err = snd_pcm_plugin_append(plugin);
- if (err < 0) {
- snd_pcm_plugin_free(plugin);
- return err;
- }
- srcformat = tmpformat;
- src_access = dst_access;
- }
-
- /* channels reduction */
- if (srcformat.channels > dstformat.channels) {
- tmpformat.channels = dstformat.channels;
- err = snd_pcm_plugin_build_route(plug, &srcformat, &tmpformat, &plugin);
- pdprintf("channels reduction: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err);
- if (err < 0)
- return err;
- err = snd_pcm_plugin_append(plugin);
- if (err < 0) {
- snd_pcm_plugin_free(plugin);
- return err;
- }
- srcformat = tmpformat;
- src_access = dst_access;
- }
-
- /* rate resampling */
- if (!rate_match(srcformat.rate, dstformat.rate)) {
- if (srcformat.format != SNDRV_PCM_FORMAT_S16) {
- /* convert to S16 for resampling */
- tmpformat.format = SNDRV_PCM_FORMAT_S16;
- err = snd_pcm_plugin_build_linear(plug,
- &srcformat, &tmpformat,
- &plugin);
- if (err < 0)
- return err;
- err = snd_pcm_plugin_append(plugin);
- if (err < 0) {
- snd_pcm_plugin_free(plugin);
- return err;
- }
- srcformat = tmpformat;
- src_access = dst_access;
- }
- tmpformat.rate = dstformat.rate;
- err = snd_pcm_plugin_build_rate(plug,
- &srcformat, &tmpformat,
- &plugin);
- pdprintf("rate down resampling: src=%i, dst=%i returns %i\n", srcformat.rate, tmpformat.rate, err);
- if (err < 0)
- return err;
- err = snd_pcm_plugin_append(plugin);
- if (err < 0) {
- snd_pcm_plugin_free(plugin);
- return err;
- }
- srcformat = tmpformat;
- src_access = dst_access;
- }
-
- /* format change */
- if (srcformat.format != dstformat.format) {
- tmpformat.format = dstformat.format;
- if (srcformat.format == SNDRV_PCM_FORMAT_MU_LAW ||
- tmpformat.format == SNDRV_PCM_FORMAT_MU_LAW) {
- err = snd_pcm_plugin_build_mulaw(plug,
- &srcformat, &tmpformat,
- &plugin);
- }
- else if (snd_pcm_format_linear(srcformat.format) &&
- snd_pcm_format_linear(tmpformat.format)) {
- err = snd_pcm_plugin_build_linear(plug,
- &srcformat, &tmpformat,
- &plugin);
- }
- else
- return -EINVAL;
- pdprintf("format change: src=%i, dst=%i returns %i\n", srcformat.format, tmpformat.format, err);
- if (err < 0)
- return err;
- err = snd_pcm_plugin_append(plugin);
- if (err < 0) {
- snd_pcm_plugin_free(plugin);
- return err;
- }
- srcformat = tmpformat;
- src_access = dst_access;
- }
-
- /* channels extension */
- if (srcformat.channels < dstformat.channels) {
- tmpformat.channels = dstformat.channels;
- err = snd_pcm_plugin_build_route(plug, &srcformat, &tmpformat, &plugin);
- pdprintf("channels extension: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err);
- if (err < 0)
- return err;
- err = snd_pcm_plugin_append(plugin);
- if (err < 0) {
- snd_pcm_plugin_free(plugin);
- return err;
- }
- srcformat = tmpformat;
- src_access = dst_access;
- }
-
- /* de-interleave */
- if (src_access != dst_access) {
- err = snd_pcm_plugin_build_copy(plug,
- &srcformat,
- &tmpformat,
- &plugin);
- pdprintf("interleave change (copy: returns %i)\n", err);
- if (err < 0)
- return err;
- err = snd_pcm_plugin_append(plugin);
- if (err < 0) {
- snd_pcm_plugin_free(plugin);
- return err;
- }
- }
-
- return 0;
-}
-
-snd_pcm_sframes_t snd_pcm_plug_client_channels_buf(struct snd_pcm_substream *plug,
- char *buf,
- snd_pcm_uframes_t count,
- struct snd_pcm_plugin_channel **channels)
-{
- struct snd_pcm_plugin *plugin;
- struct snd_pcm_plugin_channel *v;
- struct snd_pcm_plugin_format *format;
- int width, nchannels, channel;
- int stream = snd_pcm_plug_stream(plug);
-
- if (snd_BUG_ON(!buf))
- return -ENXIO;
- if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
- plugin = snd_pcm_plug_first(plug);
- format = &plugin->src_format;
- } else {
- plugin = snd_pcm_plug_last(plug);
- format = &plugin->dst_format;
- }
- v = plugin->buf_channels;
- *channels = v;
- if ((width = snd_pcm_format_physical_width(format->format)) < 0)
- return width;
- nchannels = format->channels;
- if (snd_BUG_ON(plugin->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED &&
- format->channels > 1))
- return -ENXIO;
- for (channel = 0; channel < nchannels; channel++, v++) {
- v->frames = count;
- v->enabled = 1;
- v->wanted = (stream == SNDRV_PCM_STREAM_CAPTURE);
- v->area.addr = buf;
- v->area.first = channel * width;
- v->area.step = nchannels * width;
- }
- return count;
-}
-
-snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *plug, struct snd_pcm_plugin_channel *src_channels, snd_pcm_uframes_t size)
-{
- struct snd_pcm_plugin *plugin, *next;
- struct snd_pcm_plugin_channel *dst_channels;
- int err;
- snd_pcm_sframes_t frames = size;
-
- plugin = snd_pcm_plug_first(plug);
- while (plugin && frames > 0) {
- if ((next = plugin->next) != NULL) {
- snd_pcm_sframes_t frames1 = frames;
- if (plugin->dst_frames)
- frames1 = plugin->dst_frames(plugin, frames);
- if ((err = next->client_channels(next, frames1, &dst_channels)) < 0) {
- return err;
- }
- if (err != frames1) {
- frames = err;
- if (plugin->src_frames)
- frames = plugin->src_frames(plugin, frames1);
- }
- } else
- dst_channels = NULL;
- pdprintf("write plugin: %s, %li\n", plugin->name, frames);
- if ((frames = plugin->transfer(plugin, src_channels, dst_channels, frames)) < 0)
- return frames;
- src_channels = dst_channels;
- plugin = next;
- }
- return snd_pcm_plug_client_size(plug, frames);
-}
-
-snd_pcm_sframes_t snd_pcm_plug_read_transfer(struct snd_pcm_substream *plug, struct snd_pcm_plugin_channel *dst_channels_final, snd_pcm_uframes_t size)
-{
- struct snd_pcm_plugin *plugin, *next;
- struct snd_pcm_plugin_channel *src_channels, *dst_channels;
- snd_pcm_sframes_t frames = size;
- int err;
-
- frames = snd_pcm_plug_slave_size(plug, frames);
- if (frames < 0)
- return frames;
-
- src_channels = NULL;
- plugin = snd_pcm_plug_first(plug);
- while (plugin && frames > 0) {
- if ((next = plugin->next) != NULL) {
- if ((err = plugin->client_channels(plugin, frames, &dst_channels)) < 0) {
- return err;
- }
- frames = err;
- } else {
- dst_channels = dst_channels_final;
- }
- pdprintf("read plugin: %s, %li\n", plugin->name, frames);
- if ((frames = plugin->transfer(plugin, src_channels, dst_channels, frames)) < 0)
- return frames;
- plugin = next;
- src_channels = dst_channels;
- }
- return frames;
-}
-
-int snd_pcm_area_silence(const struct snd_pcm_channel_area *dst_area, size_t dst_offset,
- size_t samples, snd_pcm_format_t format)
-{
- /* FIXME: sub byte resolution and odd dst_offset */
- unsigned char *dst;
- unsigned int dst_step;
- int width;
- const unsigned char *silence;
- if (!dst_area->addr)
- return 0;
- dst = dst_area->addr + (dst_area->first + dst_area->step * dst_offset) / 8;
- width = snd_pcm_format_physical_width(format);
- if (width <= 0)
- return -EINVAL;
- if (dst_area->step == (unsigned int) width && width >= 8)
- return snd_pcm_format_set_silence(format, dst, samples);
- silence = snd_pcm_format_silence_64(format);
- if (! silence)
- return -EINVAL;
- dst_step = dst_area->step / 8;
- if (width == 4) {
- /* Ima ADPCM */
- int dstbit = dst_area->first % 8;
- int dstbit_step = dst_area->step % 8;
- while (samples-- > 0) {
- if (dstbit)
- *dst &= 0xf0;
- else
- *dst &= 0x0f;
- dst += dst_step;
- dstbit += dstbit_step;
- if (dstbit == 8) {
- dst++;
- dstbit = 0;
- }
- }
- } else {
- width /= 8;
- while (samples-- > 0) {
- memcpy(dst, silence, width);
- dst += dst_step;
- }
- }
- return 0;
-}
-
-int snd_pcm_area_copy(const struct snd_pcm_channel_area *src_area, size_t src_offset,
- const struct snd_pcm_channel_area *dst_area, size_t dst_offset,
- size_t samples, snd_pcm_format_t format)
-{
- /* FIXME: sub byte resolution and odd dst_offset */
- char *src, *dst;
- int width;
- int src_step, dst_step;
- src = src_area->addr + (src_area->first + src_area->step * src_offset) / 8;
- if (!src_area->addr)
- return snd_pcm_area_silence(dst_area, dst_offset, samples, format);
- dst = dst_area->addr + (dst_area->first + dst_area->step * dst_offset) / 8;
- if (!dst_area->addr)
- return 0;
- width = snd_pcm_format_physical_width(format);
- if (width <= 0)
- return -EINVAL;
- if (src_area->step == (unsigned int) width &&
- dst_area->step == (unsigned int) width && width >= 8) {
- size_t bytes = samples * width / 8;
- memcpy(dst, src, bytes);
- return 0;
- }
- src_step = src_area->step / 8;
- dst_step = dst_area->step / 8;
- if (width == 4) {
- /* Ima ADPCM */
- int srcbit = src_area->first % 8;
- int srcbit_step = src_area->step % 8;
- int dstbit = dst_area->first % 8;
- int dstbit_step = dst_area->step % 8;
- while (samples-- > 0) {
- unsigned char srcval;
- if (srcbit)
- srcval = *src & 0x0f;
- else
- srcval = (*src & 0xf0) >> 4;
- if (dstbit)
- *dst = (*dst & 0xf0) | srcval;
- else
- *dst = (*dst & 0x0f) | (srcval << 4);
- src += src_step;
- srcbit += srcbit_step;
- if (srcbit == 8) {
- src++;
- srcbit = 0;
- }
- dst += dst_step;
- dstbit += dstbit_step;
- if (dstbit == 8) {
- dst++;
- dstbit = 0;
- }
- }
- } else {
- width /= 8;
- while (samples-- > 0) {
- memcpy(dst, src, width);
- src += src_step;
- dst += dst_step;
- }
- }
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/core/oss/pcm_plugin.h b/ANDROID_3.4.5/sound/core/oss/pcm_plugin.h
deleted file mode 100644
index a5035c23..00000000
--- a/ANDROID_3.4.5/sound/core/oss/pcm_plugin.h
+++ /dev/null
@@ -1,185 +0,0 @@
-#ifndef __PCM_PLUGIN_H
-#define __PCM_PLUGIN_H
-
-/*
- * Digital Audio (Plugin interface) abstract layer
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifdef CONFIG_SND_PCM_OSS_PLUGINS
-
-#define snd_pcm_plug_stream(plug) ((plug)->stream)
-
-enum snd_pcm_plugin_action {
- INIT = 0,
- PREPARE = 1,
-};
-
-struct snd_pcm_channel_area {
- void *addr; /* base address of channel samples */
- unsigned int first; /* offset to first sample in bits */
- unsigned int step; /* samples distance in bits */
-};
-
-struct snd_pcm_plugin_channel {
- void *aptr; /* pointer to the allocated area */
- struct snd_pcm_channel_area area;
- snd_pcm_uframes_t frames; /* allocated frames */
- unsigned int enabled:1; /* channel need to be processed */
- unsigned int wanted:1; /* channel is wanted */
-};
-
-struct snd_pcm_plugin_format {
- snd_pcm_format_t format;
- unsigned int rate;
- unsigned int channels;
-};
-
-struct snd_pcm_plugin {
- const char *name; /* plug-in name */
- int stream;
- struct snd_pcm_plugin_format src_format; /* source format */
- struct snd_pcm_plugin_format dst_format; /* destination format */
- int src_width; /* sample width in bits */
- int dst_width; /* sample width in bits */
- snd_pcm_access_t access;
- snd_pcm_sframes_t (*src_frames)(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t dst_frames);
- snd_pcm_sframes_t (*dst_frames)(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t src_frames);
- snd_pcm_sframes_t (*client_channels)(struct snd_pcm_plugin *plugin,
- snd_pcm_uframes_t frames,
- struct snd_pcm_plugin_channel **channels);
- snd_pcm_sframes_t (*transfer)(struct snd_pcm_plugin *plugin,
- const struct snd_pcm_plugin_channel *src_channels,
- struct snd_pcm_plugin_channel *dst_channels,
- snd_pcm_uframes_t frames);
- int (*action)(struct snd_pcm_plugin *plugin,
- enum snd_pcm_plugin_action action,
- unsigned long data);
- struct snd_pcm_plugin *prev;
- struct snd_pcm_plugin *next;
- struct snd_pcm_substream *plug;
- void *private_data;
- void (*private_free)(struct snd_pcm_plugin *plugin);
- char *buf;
- snd_pcm_uframes_t buf_frames;
- struct snd_pcm_plugin_channel *buf_channels;
- char extra_data[0];
-};
-
-int snd_pcm_plugin_build(struct snd_pcm_substream *handle,
- const char *name,
- struct snd_pcm_plugin_format *src_format,
- struct snd_pcm_plugin_format *dst_format,
- size_t extra,
- struct snd_pcm_plugin **ret);
-int snd_pcm_plugin_free(struct snd_pcm_plugin *plugin);
-int snd_pcm_plugin_clear(struct snd_pcm_plugin **first);
-int snd_pcm_plug_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t frames);
-snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t drv_size);
-snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t clt_size);
-
-#define FULL ROUTE_PLUGIN_RESOLUTION
-#define HALF ROUTE_PLUGIN_RESOLUTION / 2
-
-int snd_pcm_plugin_build_io(struct snd_pcm_substream *handle,
- struct snd_pcm_hw_params *params,
- struct snd_pcm_plugin **r_plugin);
-int snd_pcm_plugin_build_linear(struct snd_pcm_substream *handle,
- struct snd_pcm_plugin_format *src_format,
- struct snd_pcm_plugin_format *dst_format,
- struct snd_pcm_plugin **r_plugin);
-int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *handle,
- struct snd_pcm_plugin_format *src_format,
- struct snd_pcm_plugin_format *dst_format,
- struct snd_pcm_plugin **r_plugin);
-int snd_pcm_plugin_build_rate(struct snd_pcm_substream *handle,
- struct snd_pcm_plugin_format *src_format,
- struct snd_pcm_plugin_format *dst_format,
- struct snd_pcm_plugin **r_plugin);
-int snd_pcm_plugin_build_route(struct snd_pcm_substream *handle,
- struct snd_pcm_plugin_format *src_format,
- struct snd_pcm_plugin_format *dst_format,
- struct snd_pcm_plugin **r_plugin);
-int snd_pcm_plugin_build_copy(struct snd_pcm_substream *handle,
- struct snd_pcm_plugin_format *src_format,
- struct snd_pcm_plugin_format *dst_format,
- struct snd_pcm_plugin **r_plugin);
-
-int snd_pcm_plug_format_plugins(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_params *slave_params);
-
-snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format,
- struct snd_mask *format_mask);
-
-int snd_pcm_plugin_append(struct snd_pcm_plugin *plugin);
-
-snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *handle,
- struct snd_pcm_plugin_channel *src_channels,
- snd_pcm_uframes_t size);
-snd_pcm_sframes_t snd_pcm_plug_read_transfer(struct snd_pcm_substream *handle,
- struct snd_pcm_plugin_channel *dst_channels_final,
- snd_pcm_uframes_t size);
-
-snd_pcm_sframes_t snd_pcm_plug_client_channels_buf(struct snd_pcm_substream *handle,
- char *buf, snd_pcm_uframes_t count,
- struct snd_pcm_plugin_channel **channels);
-
-snd_pcm_sframes_t snd_pcm_plugin_client_channels(struct snd_pcm_plugin *plugin,
- snd_pcm_uframes_t frames,
- struct snd_pcm_plugin_channel **channels);
-
-int snd_pcm_area_silence(const struct snd_pcm_channel_area *dst_channel,
- size_t dst_offset,
- size_t samples, snd_pcm_format_t format);
-int snd_pcm_area_copy(const struct snd_pcm_channel_area *src_channel,
- size_t src_offset,
- const struct snd_pcm_channel_area *dst_channel,
- size_t dst_offset,
- size_t samples, snd_pcm_format_t format);
-
-void *snd_pcm_plug_buf_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t size);
-void snd_pcm_plug_buf_unlock(struct snd_pcm_substream *plug, void *ptr);
-snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream,
- const char *ptr, snd_pcm_uframes_t size,
- int in_kernel);
-snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream,
- char *ptr, snd_pcm_uframes_t size, int in_kernel);
-snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream,
- void **bufs, snd_pcm_uframes_t frames,
- int in_kernel);
-snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream,
- void **bufs, snd_pcm_uframes_t frames,
- int in_kernel);
-
-#else
-
-static inline snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t drv_size) { return drv_size; }
-static inline snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t clt_size) { return clt_size; }
-static inline int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask) { return format; }
-
-#endif
-
-#ifdef PLUGIN_DEBUG
-#define pdprintf(fmt, args...) printk(KERN_DEBUG "plugin: " fmt, ##args)
-#else
-#define pdprintf(fmt, args...)
-#endif
-
-#endif /* __PCM_PLUGIN_H */
diff --git a/ANDROID_3.4.5/sound/core/oss/rate.c b/ANDROID_3.4.5/sound/core/oss/rate.c
deleted file mode 100644
index 2fa9299a..00000000
--- a/ANDROID_3.4.5/sound/core/oss/rate.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Rate conversion Plug-In
- * Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include "pcm_plugin.h"
-
-#define SHIFT 11
-#define BITS (1<<SHIFT)
-#define R_MASK (BITS-1)
-
-/*
- * Basic rate conversion plugin
- */
-
-struct rate_channel {
- signed short last_S1;
- signed short last_S2;
-};
-
-typedef void (*rate_f)(struct snd_pcm_plugin *plugin,
- const struct snd_pcm_plugin_channel *src_channels,
- struct snd_pcm_plugin_channel *dst_channels,
- int src_frames, int dst_frames);
-
-struct rate_priv {
- unsigned int pitch;
- unsigned int pos;
- rate_f func;
- snd_pcm_sframes_t old_src_frames, old_dst_frames;
- struct rate_channel channels[0];
-};
-
-static void rate_init(struct snd_pcm_plugin *plugin)
-{
- unsigned int channel;
- struct rate_priv *data = (struct rate_priv *)plugin->extra_data;
- data->pos = 0;
- for (channel = 0; channel < plugin->src_format.channels; channel++) {
- data->channels[channel].last_S1 = 0;
- data->channels[channel].last_S2 = 0;
- }
-}
-
-static void resample_expand(struct snd_pcm_plugin *plugin,
- const struct snd_pcm_plugin_channel *src_channels,
- struct snd_pcm_plugin_channel *dst_channels,
- int src_frames, int dst_frames)
-{
- unsigned int pos = 0;
- signed int val;
- signed short S1, S2;
- signed short *src, *dst;
- unsigned int channel;
- int src_step, dst_step;
- int src_frames1, dst_frames1;
- struct rate_priv *data = (struct rate_priv *)plugin->extra_data;
- struct rate_channel *rchannels = data->channels;
-
- for (channel = 0; channel < plugin->src_format.channels; channel++) {
- pos = data->pos;
- S1 = rchannels->last_S1;
- S2 = rchannels->last_S2;
- if (!src_channels[channel].enabled) {
- if (dst_channels[channel].wanted)
- snd_pcm_area_silence(&dst_channels[channel].area, 0, dst_frames, plugin->dst_format.format);
- dst_channels[channel].enabled = 0;
- continue;
- }
- dst_channels[channel].enabled = 1;
- src = (signed short *)src_channels[channel].area.addr +
- src_channels[channel].area.first / 8 / 2;
- dst = (signed short *)dst_channels[channel].area.addr +
- dst_channels[channel].area.first / 8 / 2;
- src_step = src_channels[channel].area.step / 8 / 2;
- dst_step = dst_channels[channel].area.step / 8 / 2;
- src_frames1 = src_frames;
- dst_frames1 = dst_frames;
- while (dst_frames1-- > 0) {
- if (pos & ~R_MASK) {
- pos &= R_MASK;
- S1 = S2;
- if (src_frames1-- > 0) {
- S2 = *src;
- src += src_step;
- }
- }
- val = S1 + ((S2 - S1) * (signed int)pos) / BITS;
- if (val < -32768)
- val = -32768;
- else if (val > 32767)
- val = 32767;
- *dst = val;
- dst += dst_step;
- pos += data->pitch;
- }
- rchannels->last_S1 = S1;
- rchannels->last_S2 = S2;
- rchannels++;
- }
- data->pos = pos;
-}
-
-static void resample_shrink(struct snd_pcm_plugin *plugin,
- const struct snd_pcm_plugin_channel *src_channels,
- struct snd_pcm_plugin_channel *dst_channels,
- int src_frames, int dst_frames)
-{
- unsigned int pos = 0;
- signed int val;
- signed short S1, S2;
- signed short *src, *dst;
- unsigned int channel;
- int src_step, dst_step;
- int src_frames1, dst_frames1;
- struct rate_priv *data = (struct rate_priv *)plugin->extra_data;
- struct rate_channel *rchannels = data->channels;
-
- for (channel = 0; channel < plugin->src_format.channels; ++channel) {
- pos = data->pos;
- S1 = rchannels->last_S1;
- S2 = rchannels->last_S2;
- if (!src_channels[channel].enabled) {
- if (dst_channels[channel].wanted)
- snd_pcm_area_silence(&dst_channels[channel].area, 0, dst_frames, plugin->dst_format.format);
- dst_channels[channel].enabled = 0;
- continue;
- }
- dst_channels[channel].enabled = 1;
- src = (signed short *)src_channels[channel].area.addr +
- src_channels[channel].area.first / 8 / 2;
- dst = (signed short *)dst_channels[channel].area.addr +
- dst_channels[channel].area.first / 8 / 2;
- src_step = src_channels[channel].area.step / 8 / 2;
- dst_step = dst_channels[channel].area.step / 8 / 2;
- src_frames1 = src_frames;
- dst_frames1 = dst_frames;
- while (dst_frames1 > 0) {
- S1 = S2;
- if (src_frames1-- > 0) {
- S2 = *src;
- src += src_step;
- }
- if (pos & ~R_MASK) {
- pos &= R_MASK;
- val = S1 + ((S2 - S1) * (signed int)pos) / BITS;
- if (val < -32768)
- val = -32768;
- else if (val > 32767)
- val = 32767;
- *dst = val;
- dst += dst_step;
- dst_frames1--;
- }
- pos += data->pitch;
- }
- rchannels->last_S1 = S1;
- rchannels->last_S2 = S2;
- rchannels++;
- }
- data->pos = pos;
-}
-
-static snd_pcm_sframes_t rate_src_frames(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t frames)
-{
- struct rate_priv *data;
- snd_pcm_sframes_t res;
-
- if (snd_BUG_ON(!plugin))
- return -ENXIO;
- if (frames == 0)
- return 0;
- data = (struct rate_priv *)plugin->extra_data;
- if (plugin->src_format.rate < plugin->dst_format.rate) {
- res = (((frames * data->pitch) + (BITS/2)) >> SHIFT);
- } else {
- res = (((frames << SHIFT) + (data->pitch / 2)) / data->pitch);
- }
- if (data->old_src_frames > 0) {
- snd_pcm_sframes_t frames1 = frames, res1 = data->old_dst_frames;
- while (data->old_src_frames < frames1) {
- frames1 >>= 1;
- res1 <<= 1;
- }
- while (data->old_src_frames > frames1) {
- frames1 <<= 1;
- res1 >>= 1;
- }
- if (data->old_src_frames == frames1)
- return res1;
- }
- data->old_src_frames = frames;
- data->old_dst_frames = res;
- return res;
-}
-
-static snd_pcm_sframes_t rate_dst_frames(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t frames)
-{
- struct rate_priv *data;
- snd_pcm_sframes_t res;
-
- if (snd_BUG_ON(!plugin))
- return -ENXIO;
- if (frames == 0)
- return 0;
- data = (struct rate_priv *)plugin->extra_data;
- if (plugin->src_format.rate < plugin->dst_format.rate) {
- res = (((frames << SHIFT) + (data->pitch / 2)) / data->pitch);
- } else {
- res = (((frames * data->pitch) + (BITS/2)) >> SHIFT);
- }
- if (data->old_dst_frames > 0) {
- snd_pcm_sframes_t frames1 = frames, res1 = data->old_src_frames;
- while (data->old_dst_frames < frames1) {
- frames1 >>= 1;
- res1 <<= 1;
- }
- while (data->old_dst_frames > frames1) {
- frames1 <<= 1;
- res1 >>= 1;
- }
- if (data->old_dst_frames == frames1)
- return res1;
- }
- data->old_dst_frames = frames;
- data->old_src_frames = res;
- return res;
-}
-
-static snd_pcm_sframes_t rate_transfer(struct snd_pcm_plugin *plugin,
- const struct snd_pcm_plugin_channel *src_channels,
- struct snd_pcm_plugin_channel *dst_channels,
- snd_pcm_uframes_t frames)
-{
- snd_pcm_uframes_t dst_frames;
- struct rate_priv *data;
-
- if (snd_BUG_ON(!plugin || !src_channels || !dst_channels))
- return -ENXIO;
- if (frames == 0)
- return 0;
-#ifdef CONFIG_SND_DEBUG
- {
- unsigned int channel;
- for (channel = 0; channel < plugin->src_format.channels; channel++) {
- if (snd_BUG_ON(src_channels[channel].area.first % 8 ||
- src_channels[channel].area.step % 8))
- return -ENXIO;
- if (snd_BUG_ON(dst_channels[channel].area.first % 8 ||
- dst_channels[channel].area.step % 8))
- return -ENXIO;
- }
- }
-#endif
-
- dst_frames = rate_dst_frames(plugin, frames);
- if (dst_frames > dst_channels[0].frames)
- dst_frames = dst_channels[0].frames;
- data = (struct rate_priv *)plugin->extra_data;
- data->func(plugin, src_channels, dst_channels, frames, dst_frames);
- return dst_frames;
-}
-
-static int rate_action(struct snd_pcm_plugin *plugin,
- enum snd_pcm_plugin_action action,
- unsigned long udata)
-{
- if (snd_BUG_ON(!plugin))
- return -ENXIO;
- switch (action) {
- case INIT:
- case PREPARE:
- rate_init(plugin);
- break;
- default:
- break;
- }
- return 0; /* silenty ignore other actions */
-}
-
-int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug,
- struct snd_pcm_plugin_format *src_format,
- struct snd_pcm_plugin_format *dst_format,
- struct snd_pcm_plugin **r_plugin)
-{
- int err;
- struct rate_priv *data;
- struct snd_pcm_plugin *plugin;
-
- if (snd_BUG_ON(!r_plugin))
- return -ENXIO;
- *r_plugin = NULL;
-
- if (snd_BUG_ON(src_format->channels != dst_format->channels))
- return -ENXIO;
- if (snd_BUG_ON(src_format->channels <= 0))
- return -ENXIO;
- if (snd_BUG_ON(src_format->format != SNDRV_PCM_FORMAT_S16))
- return -ENXIO;
- if (snd_BUG_ON(dst_format->format != SNDRV_PCM_FORMAT_S16))
- return -ENXIO;
- if (snd_BUG_ON(src_format->rate == dst_format->rate))
- return -ENXIO;
-
- err = snd_pcm_plugin_build(plug, "rate conversion",
- src_format, dst_format,
- sizeof(struct rate_priv) +
- src_format->channels * sizeof(struct rate_channel),
- &plugin);
- if (err < 0)
- return err;
- data = (struct rate_priv *)plugin->extra_data;
- if (src_format->rate < dst_format->rate) {
- data->pitch = ((src_format->rate << SHIFT) + (dst_format->rate >> 1)) / dst_format->rate;
- data->func = resample_expand;
- } else {
- data->pitch = ((dst_format->rate << SHIFT) + (src_format->rate >> 1)) / src_format->rate;
- data->func = resample_shrink;
- }
- data->pos = 0;
- rate_init(plugin);
- data->old_src_frames = data->old_dst_frames = 0;
- plugin->transfer = rate_transfer;
- plugin->src_frames = rate_src_frames;
- plugin->dst_frames = rate_dst_frames;
- plugin->action = rate_action;
- *r_plugin = plugin;
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/core/oss/route.c b/ANDROID_3.4.5/sound/core/oss/route.c
deleted file mode 100644
index c8171f57..00000000
--- a/ANDROID_3.4.5/sound/core/oss/route.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Route Plug-In
- * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
- *
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include "pcm_plugin.h"
-
-static void zero_areas(struct snd_pcm_plugin_channel *dvp, int ndsts,
- snd_pcm_uframes_t frames, snd_pcm_format_t format)
-{
- int dst = 0;
- for (; dst < ndsts; ++dst) {
- if (dvp->wanted)
- snd_pcm_area_silence(&dvp->area, 0, frames, format);
- dvp->enabled = 0;
- dvp++;
- }
-}
-
-static inline void copy_area(const struct snd_pcm_plugin_channel *src_channel,
- struct snd_pcm_plugin_channel *dst_channel,
- snd_pcm_uframes_t frames, snd_pcm_format_t format)
-{
- dst_channel->enabled = 1;
- snd_pcm_area_copy(&src_channel->area, 0, &dst_channel->area, 0, frames, format);
-}
-
-static snd_pcm_sframes_t route_transfer(struct snd_pcm_plugin *plugin,
- const struct snd_pcm_plugin_channel *src_channels,
- struct snd_pcm_plugin_channel *dst_channels,
- snd_pcm_uframes_t frames)
-{
- int nsrcs, ndsts, dst;
- struct snd_pcm_plugin_channel *dvp;
- snd_pcm_format_t format;
-
- if (snd_BUG_ON(!plugin || !src_channels || !dst_channels))
- return -ENXIO;
- if (frames == 0)
- return 0;
-
- nsrcs = plugin->src_format.channels;
- ndsts = plugin->dst_format.channels;
-
- format = plugin->dst_format.format;
- dvp = dst_channels;
- if (nsrcs <= 1) {
- /* expand to all channels */
- for (dst = 0; dst < ndsts; ++dst) {
- copy_area(src_channels, dvp, frames, format);
- dvp++;
- }
- return frames;
- }
-
- for (dst = 0; dst < ndsts && dst < nsrcs; ++dst) {
- copy_area(src_channels, dvp, frames, format);
- dvp++;
- src_channels++;
- }
- if (dst < ndsts)
- zero_areas(dvp, ndsts - dst, frames, format);
- return frames;
-}
-
-int snd_pcm_plugin_build_route(struct snd_pcm_substream *plug,
- struct snd_pcm_plugin_format *src_format,
- struct snd_pcm_plugin_format *dst_format,
- struct snd_pcm_plugin **r_plugin)
-{
- struct snd_pcm_plugin *plugin;
- int err;
-
- if (snd_BUG_ON(!r_plugin))
- return -ENXIO;
- *r_plugin = NULL;
- if (snd_BUG_ON(src_format->rate != dst_format->rate))
- return -ENXIO;
- if (snd_BUG_ON(src_format->format != dst_format->format))
- return -ENXIO;
-
- err = snd_pcm_plugin_build(plug, "route conversion",
- src_format, dst_format, 0, &plugin);
- if (err < 0)
- return err;
-
- plugin->transfer = route_transfer;
- *r_plugin = plugin;
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/core/pcm.c b/ANDROID_3.4.5/sound/core/pcm.c
deleted file mode 100644
index e30e1be3..00000000
--- a/ANDROID_3.4.5/sound/core/pcm.c
+++ /dev/null
@@ -1,1220 +0,0 @@
-/*
- * Digital Audio (PCM) abstract layer
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/time.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/minors.h>
-#include <sound/pcm.h>
-#include <sound/control.h>
-#include <sound/info.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Abramo Bagnara <abramo@alsa-project.org>");
-MODULE_DESCRIPTION("Midlevel PCM code for ALSA.");
-MODULE_LICENSE("GPL");
-
-static LIST_HEAD(snd_pcm_devices);
-static LIST_HEAD(snd_pcm_notify_list);
-static DEFINE_MUTEX(register_mutex);
-
-static int snd_pcm_free(struct snd_pcm *pcm);
-static int snd_pcm_dev_free(struct snd_device *device);
-static int snd_pcm_dev_register(struct snd_device *device);
-static int snd_pcm_dev_disconnect(struct snd_device *device);
-
-static struct snd_pcm *snd_pcm_get(struct snd_card *card, int device)
-{
- struct snd_pcm *pcm;
-
- list_for_each_entry(pcm, &snd_pcm_devices, list) {
- if (pcm->card == card && pcm->device == device)
- return pcm;
- }
- return NULL;
-}
-
-static int snd_pcm_next(struct snd_card *card, int device)
-{
- struct snd_pcm *pcm;
-
- list_for_each_entry(pcm, &snd_pcm_devices, list) {
- if (pcm->card == card && pcm->device > device)
- return pcm->device;
- else if (pcm->card->number > card->number)
- return -1;
- }
- return -1;
-}
-
-static int snd_pcm_add(struct snd_pcm *newpcm)
-{
- struct snd_pcm *pcm;
-
- list_for_each_entry(pcm, &snd_pcm_devices, list) {
- if (pcm->card == newpcm->card && pcm->device == newpcm->device)
- return -EBUSY;
- if (pcm->card->number > newpcm->card->number ||
- (pcm->card == newpcm->card &&
- pcm->device > newpcm->device)) {
- list_add(&newpcm->list, pcm->list.prev);
- return 0;
- }
- }
- list_add_tail(&newpcm->list, &snd_pcm_devices);
- return 0;
-}
-
-static int snd_pcm_control_ioctl(struct snd_card *card,
- struct snd_ctl_file *control,
- unsigned int cmd, unsigned long arg)
-{
- switch (cmd) {
- case SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE:
- {
- int device;
-
- if (get_user(device, (int __user *)arg))
- return -EFAULT;
- mutex_lock(&register_mutex);
- device = snd_pcm_next(card, device);
- mutex_unlock(&register_mutex);
- if (put_user(device, (int __user *)arg))
- return -EFAULT;
- return 0;
- }
- case SNDRV_CTL_IOCTL_PCM_INFO:
- {
- struct snd_pcm_info __user *info;
- unsigned int device, subdevice;
- int stream;
- struct snd_pcm *pcm;
- struct snd_pcm_str *pstr;
- struct snd_pcm_substream *substream;
- int err;
-
- info = (struct snd_pcm_info __user *)arg;
- if (get_user(device, &info->device))
- return -EFAULT;
- if (get_user(stream, &info->stream))
- return -EFAULT;
- if (stream < 0 || stream > 1)
- return -EINVAL;
- if (get_user(subdevice, &info->subdevice))
- return -EFAULT;
- mutex_lock(&register_mutex);
- pcm = snd_pcm_get(card, device);
- if (pcm == NULL) {
- err = -ENXIO;
- goto _error;
- }
- pstr = &pcm->streams[stream];
- if (pstr->substream_count == 0) {
- err = -ENOENT;
- goto _error;
- }
- if (subdevice >= pstr->substream_count) {
- err = -ENXIO;
- goto _error;
- }
- for (substream = pstr->substream; substream;
- substream = substream->next)
- if (substream->number == (int)subdevice)
- break;
- if (substream == NULL) {
- err = -ENXIO;
- goto _error;
- }
- err = snd_pcm_info_user(substream, info);
- _error:
- mutex_unlock(&register_mutex);
- return err;
- }
- case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE:
- {
- int val;
-
- if (get_user(val, (int __user *)arg))
- return -EFAULT;
- control->prefer_pcm_subdevice = val;
- return 0;
- }
- }
- return -ENOIOCTLCMD;
-}
-
-#define FORMAT(v) [SNDRV_PCM_FORMAT_##v] = #v
-
-static char *snd_pcm_format_names[] = {
- FORMAT(S8),
- FORMAT(U8),
- FORMAT(S16_LE),
- FORMAT(S16_BE),
- FORMAT(U16_LE),
- FORMAT(U16_BE),
- FORMAT(S24_LE),
- FORMAT(S24_BE),
- FORMAT(U24_LE),
- FORMAT(U24_BE),
- FORMAT(S32_LE),
- FORMAT(S32_BE),
- FORMAT(U32_LE),
- FORMAT(U32_BE),
- FORMAT(FLOAT_LE),
- FORMAT(FLOAT_BE),
- FORMAT(FLOAT64_LE),
- FORMAT(FLOAT64_BE),
- FORMAT(IEC958_SUBFRAME_LE),
- FORMAT(IEC958_SUBFRAME_BE),
- FORMAT(MU_LAW),
- FORMAT(A_LAW),
- FORMAT(IMA_ADPCM),
- FORMAT(MPEG),
- FORMAT(GSM),
- FORMAT(SPECIAL),
- FORMAT(S24_3LE),
- FORMAT(S24_3BE),
- FORMAT(U24_3LE),
- FORMAT(U24_3BE),
- FORMAT(S20_3LE),
- FORMAT(S20_3BE),
- FORMAT(U20_3LE),
- FORMAT(U20_3BE),
- FORMAT(S18_3LE),
- FORMAT(S18_3BE),
- FORMAT(U18_3LE),
- FORMAT(U18_3BE),
- FORMAT(G723_24),
- FORMAT(G723_24_1B),
- FORMAT(G723_40),
- FORMAT(G723_40_1B),
-};
-
-const char *snd_pcm_format_name(snd_pcm_format_t format)
-{
- if ((__force unsigned int)format >= ARRAY_SIZE(snd_pcm_format_names))
- return "Unknown";
- return snd_pcm_format_names[(__force unsigned int)format];
-}
-EXPORT_SYMBOL_GPL(snd_pcm_format_name);
-
-#ifdef CONFIG_SND_VERBOSE_PROCFS
-
-#define STATE(v) [SNDRV_PCM_STATE_##v] = #v
-#define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v
-#define READY(v) [SNDRV_PCM_READY_##v] = #v
-#define XRUN(v) [SNDRV_PCM_XRUN_##v] = #v
-#define SILENCE(v) [SNDRV_PCM_SILENCE_##v] = #v
-#define TSTAMP(v) [SNDRV_PCM_TSTAMP_##v] = #v
-#define ACCESS(v) [SNDRV_PCM_ACCESS_##v] = #v
-#define START(v) [SNDRV_PCM_START_##v] = #v
-#define SUBFORMAT(v) [SNDRV_PCM_SUBFORMAT_##v] = #v
-
-static char *snd_pcm_stream_names[] = {
- STREAM(PLAYBACK),
- STREAM(CAPTURE),
-};
-
-static char *snd_pcm_state_names[] = {
- STATE(OPEN),
- STATE(SETUP),
- STATE(PREPARED),
- STATE(RUNNING),
- STATE(XRUN),
- STATE(DRAINING),
- STATE(PAUSED),
- STATE(SUSPENDED),
-};
-
-static char *snd_pcm_access_names[] = {
- ACCESS(MMAP_INTERLEAVED),
- ACCESS(MMAP_NONINTERLEAVED),
- ACCESS(MMAP_COMPLEX),
- ACCESS(RW_INTERLEAVED),
- ACCESS(RW_NONINTERLEAVED),
-};
-
-static char *snd_pcm_subformat_names[] = {
- SUBFORMAT(STD),
-};
-
-static char *snd_pcm_tstamp_mode_names[] = {
- TSTAMP(NONE),
- TSTAMP(ENABLE),
-};
-
-static const char *snd_pcm_stream_name(int stream)
-{
- return snd_pcm_stream_names[stream];
-}
-
-static const char *snd_pcm_access_name(snd_pcm_access_t access)
-{
- return snd_pcm_access_names[(__force int)access];
-}
-
-static const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat)
-{
- return snd_pcm_subformat_names[(__force int)subformat];
-}
-
-static const char *snd_pcm_tstamp_mode_name(int mode)
-{
- return snd_pcm_tstamp_mode_names[mode];
-}
-
-static const char *snd_pcm_state_name(snd_pcm_state_t state)
-{
- return snd_pcm_state_names[(__force int)state];
-}
-
-#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
-#include <linux/soundcard.h>
-
-static const char *snd_pcm_oss_format_name(int format)
-{
- switch (format) {
- case AFMT_MU_LAW:
- return "MU_LAW";
- case AFMT_A_LAW:
- return "A_LAW";
- case AFMT_IMA_ADPCM:
- return "IMA_ADPCM";
- case AFMT_U8:
- return "U8";
- case AFMT_S16_LE:
- return "S16_LE";
- case AFMT_S16_BE:
- return "S16_BE";
- case AFMT_S8:
- return "S8";
- case AFMT_U16_LE:
- return "U16_LE";
- case AFMT_U16_BE:
- return "U16_BE";
- case AFMT_MPEG:
- return "MPEG";
- default:
- return "unknown";
- }
-}
-#endif
-
-static void snd_pcm_proc_info_read(struct snd_pcm_substream *substream,
- struct snd_info_buffer *buffer)
-{
- struct snd_pcm_info *info;
- int err;
-
- if (! substream)
- return;
-
- info = kmalloc(sizeof(*info), GFP_KERNEL);
- if (! info) {
- printk(KERN_DEBUG "snd_pcm_proc_info_read: cannot malloc\n");
- return;
- }
-
- err = snd_pcm_info(substream, info);
- if (err < 0) {
- snd_iprintf(buffer, "error %d\n", err);
- kfree(info);
- return;
- }
- snd_iprintf(buffer, "card: %d\n", info->card);
- snd_iprintf(buffer, "device: %d\n", info->device);
- snd_iprintf(buffer, "subdevice: %d\n", info->subdevice);
- snd_iprintf(buffer, "stream: %s\n", snd_pcm_stream_name(info->stream));
- snd_iprintf(buffer, "id: %s\n", info->id);
- snd_iprintf(buffer, "name: %s\n", info->name);
- snd_iprintf(buffer, "subname: %s\n", info->subname);
- snd_iprintf(buffer, "class: %d\n", info->dev_class);
- snd_iprintf(buffer, "subclass: %d\n", info->dev_subclass);
- snd_iprintf(buffer, "subdevices_count: %d\n", info->subdevices_count);
- snd_iprintf(buffer, "subdevices_avail: %d\n", info->subdevices_avail);
- kfree(info);
-}
-
-static void snd_pcm_stream_proc_info_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- snd_pcm_proc_info_read(((struct snd_pcm_str *)entry->private_data)->substream,
- buffer);
-}
-
-static void snd_pcm_substream_proc_info_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- snd_pcm_proc_info_read(entry->private_data, buffer);
-}
-
-static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_pcm_substream *substream = entry->private_data;
- struct snd_pcm_runtime *runtime;
-
- mutex_lock(&substream->pcm->open_mutex);
- runtime = substream->runtime;
- if (!runtime) {
- snd_iprintf(buffer, "closed\n");
- goto unlock;
- }
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
- snd_iprintf(buffer, "no setup\n");
- goto unlock;
- }
- snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access));
- snd_iprintf(buffer, "format: %s\n", snd_pcm_format_name(runtime->format));
- snd_iprintf(buffer, "subformat: %s\n", snd_pcm_subformat_name(runtime->subformat));
- snd_iprintf(buffer, "channels: %u\n", runtime->channels);
- snd_iprintf(buffer, "rate: %u (%u/%u)\n", runtime->rate, runtime->rate_num, runtime->rate_den);
- snd_iprintf(buffer, "period_size: %lu\n", runtime->period_size);
- snd_iprintf(buffer, "buffer_size: %lu\n", runtime->buffer_size);
-#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
- if (substream->oss.oss) {
- snd_iprintf(buffer, "OSS format: %s\n", snd_pcm_oss_format_name(runtime->oss.format));
- snd_iprintf(buffer, "OSS channels: %u\n", runtime->oss.channels);
- snd_iprintf(buffer, "OSS rate: %u\n", runtime->oss.rate);
- snd_iprintf(buffer, "OSS period bytes: %lu\n", (unsigned long)runtime->oss.period_bytes);
- snd_iprintf(buffer, "OSS periods: %u\n", runtime->oss.periods);
- snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames);
- }
-#endif
- unlock:
- mutex_unlock(&substream->pcm->open_mutex);
-}
-
-static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_pcm_substream *substream = entry->private_data;
- struct snd_pcm_runtime *runtime;
-
- mutex_lock(&substream->pcm->open_mutex);
- runtime = substream->runtime;
- if (!runtime) {
- snd_iprintf(buffer, "closed\n");
- goto unlock;
- }
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
- snd_iprintf(buffer, "no setup\n");
- goto unlock;
- }
- snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode));
- snd_iprintf(buffer, "period_step: %u\n", runtime->period_step);
- snd_iprintf(buffer, "avail_min: %lu\n", runtime->control->avail_min);
- snd_iprintf(buffer, "start_threshold: %lu\n", runtime->start_threshold);
- snd_iprintf(buffer, "stop_threshold: %lu\n", runtime->stop_threshold);
- snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold);
- snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size);
- snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary);
- unlock:
- mutex_unlock(&substream->pcm->open_mutex);
-}
-
-static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_pcm_substream *substream = entry->private_data;
- struct snd_pcm_runtime *runtime;
- struct snd_pcm_status status;
- int err;
-
- mutex_lock(&substream->pcm->open_mutex);
- runtime = substream->runtime;
- if (!runtime) {
- snd_iprintf(buffer, "closed\n");
- goto unlock;
- }
- memset(&status, 0, sizeof(status));
- err = snd_pcm_status(substream, &status);
- if (err < 0) {
- snd_iprintf(buffer, "error %d\n", err);
- goto unlock;
- }
- snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state));
- snd_iprintf(buffer, "owner_pid : %d\n", pid_vnr(substream->pid));
- snd_iprintf(buffer, "trigger_time: %ld.%09ld\n",
- status.trigger_tstamp.tv_sec, status.trigger_tstamp.tv_nsec);
- snd_iprintf(buffer, "tstamp : %ld.%09ld\n",
- status.tstamp.tv_sec, status.tstamp.tv_nsec);
- snd_iprintf(buffer, "delay : %ld\n", status.delay);
- snd_iprintf(buffer, "avail : %ld\n", status.avail);
- snd_iprintf(buffer, "avail_max : %ld\n", status.avail_max);
- snd_iprintf(buffer, "-----\n");
- snd_iprintf(buffer, "hw_ptr : %ld\n", runtime->status->hw_ptr);
- snd_iprintf(buffer, "appl_ptr : %ld\n", runtime->control->appl_ptr);
- unlock:
- mutex_unlock(&substream->pcm->open_mutex);
-}
-
-#ifdef CONFIG_SND_PCM_XRUN_DEBUG
-static void snd_pcm_xrun_debug_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_pcm_str *pstr = entry->private_data;
- snd_iprintf(buffer, "%d\n", pstr->xrun_debug);
-}
-
-static void snd_pcm_xrun_debug_write(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_pcm_str *pstr = entry->private_data;
- char line[64];
- if (!snd_info_get_line(buffer, line, sizeof(line)))
- pstr->xrun_debug = simple_strtoul(line, NULL, 10);
-}
-#endif
-
-static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
-{
- struct snd_pcm *pcm = pstr->pcm;
- struct snd_info_entry *entry;
- char name[16];
-
- sprintf(name, "pcm%i%c", pcm->device,
- pstr->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c');
- if ((entry = snd_info_create_card_entry(pcm->card, name, pcm->card->proc_root)) == NULL)
- return -ENOMEM;
- entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- return -ENOMEM;
- }
- pstr->proc_root = entry;
-
- if ((entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root)) != NULL) {
- snd_info_set_text_ops(entry, pstr, snd_pcm_stream_proc_info_read);
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- pstr->proc_info_entry = entry;
-
-#ifdef CONFIG_SND_PCM_XRUN_DEBUG
- if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug",
- pstr->proc_root)) != NULL) {
- entry->c.text.read = snd_pcm_xrun_debug_read;
- entry->c.text.write = snd_pcm_xrun_debug_write;
- entry->mode |= S_IWUSR;
- entry->private_data = pstr;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- pstr->proc_xrun_debug_entry = entry;
-#endif
- return 0;
-}
-
-static int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr)
-{
-#ifdef CONFIG_SND_PCM_XRUN_DEBUG
- snd_info_free_entry(pstr->proc_xrun_debug_entry);
- pstr->proc_xrun_debug_entry = NULL;
-#endif
- snd_info_free_entry(pstr->proc_info_entry);
- pstr->proc_info_entry = NULL;
- snd_info_free_entry(pstr->proc_root);
- pstr->proc_root = NULL;
- return 0;
-}
-
-static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
-{
- struct snd_info_entry *entry;
- struct snd_card *card;
- char name[16];
-
- card = substream->pcm->card;
-
- sprintf(name, "sub%i", substream->number);
- if ((entry = snd_info_create_card_entry(card, name, substream->pstr->proc_root)) == NULL)
- return -ENOMEM;
- entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- return -ENOMEM;
- }
- substream->proc_root = entry;
-
- if ((entry = snd_info_create_card_entry(card, "info", substream->proc_root)) != NULL) {
- snd_info_set_text_ops(entry, substream,
- snd_pcm_substream_proc_info_read);
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- substream->proc_info_entry = entry;
-
- if ((entry = snd_info_create_card_entry(card, "hw_params", substream->proc_root)) != NULL) {
- snd_info_set_text_ops(entry, substream,
- snd_pcm_substream_proc_hw_params_read);
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- substream->proc_hw_params_entry = entry;
-
- if ((entry = snd_info_create_card_entry(card, "sw_params", substream->proc_root)) != NULL) {
- snd_info_set_text_ops(entry, substream,
- snd_pcm_substream_proc_sw_params_read);
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- substream->proc_sw_params_entry = entry;
-
- if ((entry = snd_info_create_card_entry(card, "status", substream->proc_root)) != NULL) {
- snd_info_set_text_ops(entry, substream,
- snd_pcm_substream_proc_status_read);
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- substream->proc_status_entry = entry;
-
- return 0;
-}
-
-static int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream)
-{
- snd_info_free_entry(substream->proc_info_entry);
- substream->proc_info_entry = NULL;
- snd_info_free_entry(substream->proc_hw_params_entry);
- substream->proc_hw_params_entry = NULL;
- snd_info_free_entry(substream->proc_sw_params_entry);
- substream->proc_sw_params_entry = NULL;
- snd_info_free_entry(substream->proc_status_entry);
- substream->proc_status_entry = NULL;
- snd_info_free_entry(substream->proc_root);
- substream->proc_root = NULL;
- return 0;
-}
-#else /* !CONFIG_SND_VERBOSE_PROCFS */
-static inline int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) { return 0; }
-static inline int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr) { return 0; }
-static inline int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) { return 0; }
-static inline int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream) { return 0; }
-#endif /* CONFIG_SND_VERBOSE_PROCFS */
-
-/**
- * snd_pcm_new_stream - create a new PCM stream
- * @pcm: the pcm instance
- * @stream: the stream direction, SNDRV_PCM_STREAM_XXX
- * @substream_count: the number of substreams
- *
- * Creates a new stream for the pcm.
- * The corresponding stream on the pcm must have been empty before
- * calling this, i.e. zero must be given to the argument of
- * snd_pcm_new().
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
-{
- int idx, err;
- struct snd_pcm_str *pstr = &pcm->streams[stream];
- struct snd_pcm_substream *substream, *prev;
-
-#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
- mutex_init(&pstr->oss.setup_mutex);
-#endif
- pstr->stream = stream;
- pstr->pcm = pcm;
- pstr->substream_count = substream_count;
- if (substream_count > 0 && !pcm->internal) {
- err = snd_pcm_stream_proc_init(pstr);
- if (err < 0) {
- snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
- return err;
- }
- }
- prev = NULL;
- for (idx = 0, prev = NULL; idx < substream_count; idx++) {
- substream = kzalloc(sizeof(*substream), GFP_KERNEL);
- if (substream == NULL) {
- snd_printk(KERN_ERR "Cannot allocate PCM substream\n");
- return -ENOMEM;
- }
- substream->pcm = pcm;
- substream->pstr = pstr;
- substream->number = idx;
- substream->stream = stream;
- sprintf(substream->name, "subdevice #%i", idx);
- substream->buffer_bytes_max = UINT_MAX;
- if (prev == NULL)
- pstr->substream = substream;
- else
- prev->next = substream;
-
- if (!pcm->internal) {
- err = snd_pcm_substream_proc_init(substream);
- if (err < 0) {
- snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
- if (prev == NULL)
- pstr->substream = NULL;
- else
- prev->next = NULL;
- kfree(substream);
- return err;
- }
- }
- substream->group = &substream->self_group;
- spin_lock_init(&substream->self_group.lock);
- INIT_LIST_HEAD(&substream->self_group.substreams);
- list_add_tail(&substream->link_list, &substream->self_group.substreams);
- atomic_set(&substream->mmap_count, 0);
- prev = substream;
- }
- return 0;
-}
-
-EXPORT_SYMBOL(snd_pcm_new_stream);
-
-static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
- int playback_count, int capture_count, bool internal,
- struct snd_pcm **rpcm)
-{
- struct snd_pcm *pcm;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_pcm_dev_free,
- .dev_register = snd_pcm_dev_register,
- .dev_disconnect = snd_pcm_dev_disconnect,
- };
-
- if (snd_BUG_ON(!card))
- return -ENXIO;
- if (rpcm)
- *rpcm = NULL;
- pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
- if (pcm == NULL) {
- snd_printk(KERN_ERR "Cannot allocate PCM\n");
- return -ENOMEM;
- }
- pcm->card = card;
- pcm->device = device;
- pcm->internal = internal;
- if (id)
- strlcpy(pcm->id, id, sizeof(pcm->id));
- if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) {
- snd_pcm_free(pcm);
- return err;
- }
- if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_CAPTURE, capture_count)) < 0) {
- snd_pcm_free(pcm);
- return err;
- }
- mutex_init(&pcm->open_mutex);
- init_waitqueue_head(&pcm->open_wait);
- if ((err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)) < 0) {
- snd_pcm_free(pcm);
- return err;
- }
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-/**
- * snd_pcm_new - create a new PCM instance
- * @card: the card instance
- * @id: the id string
- * @device: the device index (zero based)
- * @playback_count: the number of substreams for playback
- * @capture_count: the number of substreams for capture
- * @rpcm: the pointer to store the new pcm instance
- *
- * Creates a new PCM instance.
- *
- * The pcm operators have to be set afterwards to the new instance
- * via snd_pcm_set_ops().
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_pcm_new(struct snd_card *card, const char *id, int device,
- int playback_count, int capture_count, struct snd_pcm **rpcm)
-{
- return _snd_pcm_new(card, id, device, playback_count, capture_count,
- false, rpcm);
-}
-EXPORT_SYMBOL(snd_pcm_new);
-
-/**
- * snd_pcm_new_internal - create a new internal PCM instance
- * @card: the card instance
- * @id: the id string
- * @device: the device index (zero based - shared with normal PCMs)
- * @playback_count: the number of substreams for playback
- * @capture_count: the number of substreams for capture
- * @rpcm: the pointer to store the new pcm instance
- *
- * Creates a new internal PCM instance with no userspace device or procfs
- * entries. This is used by ASoC Back End PCMs in order to create a PCM that
- * will only be used internally by kernel drivers. i.e. it cannot be opened
- * by userspace. It provides existing ASoC components drivers with a substream
- * and access to any private data.
- *
- * The pcm operators have to be set afterwards to the new instance
- * via snd_pcm_set_ops().
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_pcm_new_internal(struct snd_card *card, const char *id, int device,
- int playback_count, int capture_count,
- struct snd_pcm **rpcm)
-{
- return _snd_pcm_new(card, id, device, playback_count, capture_count,
- true, rpcm);
-}
-EXPORT_SYMBOL(snd_pcm_new_internal);
-
-static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
-{
- struct snd_pcm_substream *substream, *substream_next;
-#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
- struct snd_pcm_oss_setup *setup, *setupn;
-#endif
- substream = pstr->substream;
- while (substream) {
- substream_next = substream->next;
- snd_pcm_timer_done(substream);
- snd_pcm_substream_proc_done(substream);
- kfree(substream);
- substream = substream_next;
- }
- snd_pcm_stream_proc_done(pstr);
-#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
- for (setup = pstr->oss.setup_list; setup; setup = setupn) {
- setupn = setup->next;
- kfree(setup->task_name);
- kfree(setup);
- }
-#endif
-}
-
-static int snd_pcm_free(struct snd_pcm *pcm)
-{
- struct snd_pcm_notify *notify;
-
- if (!pcm)
- return 0;
- list_for_each_entry(notify, &snd_pcm_notify_list, list) {
- notify->n_unregister(pcm);
- }
- if (pcm->private_free)
- pcm->private_free(pcm);
- snd_pcm_lib_preallocate_free_for_all(pcm);
- snd_pcm_free_stream(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK]);
- snd_pcm_free_stream(&pcm->streams[SNDRV_PCM_STREAM_CAPTURE]);
- kfree(pcm);
- return 0;
-}
-
-static int snd_pcm_dev_free(struct snd_device *device)
-{
- struct snd_pcm *pcm = device->device_data;
- return snd_pcm_free(pcm);
-}
-
-int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
- struct file *file,
- struct snd_pcm_substream **rsubstream)
-{
- struct snd_pcm_str * pstr;
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
- struct snd_ctl_file *kctl;
- struct snd_card *card;
- int prefer_subdevice = -1;
- size_t size;
-
- if (snd_BUG_ON(!pcm || !rsubstream))
- return -ENXIO;
- *rsubstream = NULL;
- pstr = &pcm->streams[stream];
- if (pstr->substream == NULL || pstr->substream_count == 0)
- return -ENODEV;
-
- card = pcm->card;
- read_lock(&card->ctl_files_rwlock);
- list_for_each_entry(kctl, &card->ctl_files, list) {
- if (kctl->pid == task_pid(current)) {
- prefer_subdevice = kctl->prefer_pcm_subdevice;
- if (prefer_subdevice != -1)
- break;
- }
- }
- read_unlock(&card->ctl_files_rwlock);
-
- switch (stream) {
- case SNDRV_PCM_STREAM_PLAYBACK:
- if (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX) {
- for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; substream; substream = substream->next) {
- if (SUBSTREAM_BUSY(substream))
- return -EAGAIN;
- }
- }
- break;
- case SNDRV_PCM_STREAM_CAPTURE:
- if (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX) {
- for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next) {
- if (SUBSTREAM_BUSY(substream))
- return -EAGAIN;
- }
- }
- break;
- default:
- return -EINVAL;
- }
-
- if (file->f_flags & O_APPEND) {
- if (prefer_subdevice < 0) {
- if (pstr->substream_count > 1)
- return -EINVAL; /* must be unique */
- substream = pstr->substream;
- } else {
- for (substream = pstr->substream; substream;
- substream = substream->next)
- if (substream->number == prefer_subdevice)
- break;
- }
- if (! substream)
- return -ENODEV;
- if (! SUBSTREAM_BUSY(substream))
- return -EBADFD;
- substream->ref_count++;
- *rsubstream = substream;
- return 0;
- }
-
- if (prefer_subdevice >= 0) {
- for (substream = pstr->substream; substream; substream = substream->next)
- if (!SUBSTREAM_BUSY(substream) && substream->number == prefer_subdevice)
- goto __ok;
- }
- for (substream = pstr->substream; substream; substream = substream->next)
- if (!SUBSTREAM_BUSY(substream))
- break;
- __ok:
- if (substream == NULL)
- return -EAGAIN;
-
- runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
- if (runtime == NULL)
- return -ENOMEM;
-
- size = PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status));
- runtime->status = snd_malloc_pages(size, GFP_KERNEL);
- if (runtime->status == NULL) {
- kfree(runtime);
- return -ENOMEM;
- }
- memset((void*)runtime->status, 0, size);
-
- size = PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control));
- runtime->control = snd_malloc_pages(size, GFP_KERNEL);
- if (runtime->control == NULL) {
- snd_free_pages((void*)runtime->status,
- PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)));
- kfree(runtime);
- return -ENOMEM;
- }
- memset((void*)runtime->control, 0, size);
-
- init_waitqueue_head(&runtime->sleep);
- init_waitqueue_head(&runtime->tsleep);
-
- runtime->status->state = SNDRV_PCM_STATE_OPEN;
-
- substream->runtime = runtime;
- substream->private_data = pcm->private_data;
- substream->ref_count = 1;
- substream->f_flags = file->f_flags;
- substream->pid = get_pid(task_pid(current));
- pstr->substream_opened++;
- *rsubstream = substream;
- return 0;
-}
-
-void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime;
-
- if (PCM_RUNTIME_CHECK(substream))
- return;
- runtime = substream->runtime;
- if (runtime->private_free != NULL)
- runtime->private_free(runtime);
- snd_free_pages((void*)runtime->status,
- PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)));
- snd_free_pages((void*)runtime->control,
- PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)));
- kfree(runtime->hw_constraints.rules);
-#ifdef CONFIG_SND_PCM_XRUN_DEBUG
- if (runtime->hwptr_log)
- kfree(runtime->hwptr_log);
-#endif
- kfree(runtime);
- substream->runtime = NULL;
- put_pid(substream->pid);
- substream->pid = NULL;
- substream->pstr->substream_opened--;
-}
-
-static ssize_t show_pcm_class(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct snd_pcm *pcm;
- const char *str;
- static const char *strs[SNDRV_PCM_CLASS_LAST + 1] = {
- [SNDRV_PCM_CLASS_GENERIC] = "generic",
- [SNDRV_PCM_CLASS_MULTI] = "multi",
- [SNDRV_PCM_CLASS_MODEM] = "modem",
- [SNDRV_PCM_CLASS_DIGITIZER] = "digitizer",
- };
-
- if (! (pcm = dev_get_drvdata(dev)) ||
- pcm->dev_class > SNDRV_PCM_CLASS_LAST)
- str = "none";
- else
- str = strs[pcm->dev_class];
- return snprintf(buf, PAGE_SIZE, "%s\n", str);
-}
-
-static struct device_attribute pcm_attrs =
- __ATTR(pcm_class, S_IRUGO, show_pcm_class, NULL);
-
-static int snd_pcm_dev_register(struct snd_device *device)
-{
- int cidx, err;
- struct snd_pcm_substream *substream;
- struct snd_pcm_notify *notify;
- char str[16];
- struct snd_pcm *pcm;
- struct device *dev;
-
- if (snd_BUG_ON(!device || !device->device_data))
- return -ENXIO;
- pcm = device->device_data;
- mutex_lock(&register_mutex);
- err = snd_pcm_add(pcm);
- if (err) {
- mutex_unlock(&register_mutex);
- return err;
- }
- for (cidx = 0; cidx < 2; cidx++) {
- int devtype = -1;
- if (pcm->streams[cidx].substream == NULL || pcm->internal)
- continue;
- switch (cidx) {
- case SNDRV_PCM_STREAM_PLAYBACK:
- sprintf(str, "pcmC%iD%ip", pcm->card->number, pcm->device);
- devtype = SNDRV_DEVICE_TYPE_PCM_PLAYBACK;
- break;
- case SNDRV_PCM_STREAM_CAPTURE:
- sprintf(str, "pcmC%iD%ic", pcm->card->number, pcm->device);
- devtype = SNDRV_DEVICE_TYPE_PCM_CAPTURE;
- break;
- }
- /* device pointer to use, pcm->dev takes precedence if
- * it is assigned, otherwise fall back to card's device
- * if possible */
- dev = pcm->dev;
- if (!dev)
- dev = snd_card_get_device_link(pcm->card);
- /* register pcm */
- err = snd_register_device_for_dev(devtype, pcm->card,
- pcm->device,
- &snd_pcm_f_ops[cidx],
- pcm, str, dev);
- if (err < 0) {
- list_del(&pcm->list);
- mutex_unlock(&register_mutex);
- return err;
- }
- snd_add_device_sysfs_file(devtype, pcm->card, pcm->device,
- &pcm_attrs);
- for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
- snd_pcm_timer_init(substream);
- }
-
- list_for_each_entry(notify, &snd_pcm_notify_list, list)
- notify->n_register(pcm);
-
- mutex_unlock(&register_mutex);
- return 0;
-}
-
-static int snd_pcm_dev_disconnect(struct snd_device *device)
-{
- struct snd_pcm *pcm = device->device_data;
- struct snd_pcm_notify *notify;
- struct snd_pcm_substream *substream;
- int cidx, devtype;
-
- mutex_lock(&register_mutex);
- if (list_empty(&pcm->list))
- goto unlock;
-
- mutex_lock(&pcm->open_mutex);
- wake_up(&pcm->open_wait);
- list_del_init(&pcm->list);
- for (cidx = 0; cidx < 2; cidx++)
- for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) {
- snd_pcm_stream_lock_irq(substream);
- if (substream->runtime) {
- substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED;
- wake_up(&substream->runtime->sleep);
- wake_up(&substream->runtime->tsleep);
- }
- snd_pcm_stream_unlock_irq(substream);
- }
- list_for_each_entry(notify, &snd_pcm_notify_list, list) {
- notify->n_disconnect(pcm);
- }
- for (cidx = 0; cidx < 2; cidx++) {
- devtype = -1;
- switch (cidx) {
- case SNDRV_PCM_STREAM_PLAYBACK:
- devtype = SNDRV_DEVICE_TYPE_PCM_PLAYBACK;
- break;
- case SNDRV_PCM_STREAM_CAPTURE:
- devtype = SNDRV_DEVICE_TYPE_PCM_CAPTURE;
- break;
- }
- snd_unregister_device(devtype, pcm->card, pcm->device);
- }
- mutex_unlock(&pcm->open_mutex);
- unlock:
- mutex_unlock(&register_mutex);
- return 0;
-}
-
-int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
-{
- struct snd_pcm *pcm;
-
- if (snd_BUG_ON(!notify ||
- !notify->n_register ||
- !notify->n_unregister ||
- !notify->n_disconnect))
- return -EINVAL;
- mutex_lock(&register_mutex);
- if (nfree) {
- list_del(&notify->list);
- list_for_each_entry(pcm, &snd_pcm_devices, list)
- notify->n_unregister(pcm);
- } else {
- list_add_tail(&notify->list, &snd_pcm_notify_list);
- list_for_each_entry(pcm, &snd_pcm_devices, list)
- notify->n_register(pcm);
- }
- mutex_unlock(&register_mutex);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_pcm_notify);
-
-#ifdef CONFIG_PROC_FS
-/*
- * Info interface
- */
-
-static void snd_pcm_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_pcm *pcm;
-
- mutex_lock(&register_mutex);
- list_for_each_entry(pcm, &snd_pcm_devices, list) {
- snd_iprintf(buffer, "%02i-%02i: %s : %s",
- pcm->card->number, pcm->device, pcm->id, pcm->name);
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream)
- snd_iprintf(buffer, " : playback %i",
- pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count);
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream)
- snd_iprintf(buffer, " : capture %i",
- pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count);
- snd_iprintf(buffer, "\n");
- }
- mutex_unlock(&register_mutex);
-}
-
-static struct snd_info_entry *snd_pcm_proc_entry;
-
-static void snd_pcm_proc_init(void)
-{
- struct snd_info_entry *entry;
-
- if ((entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL)) != NULL) {
- snd_info_set_text_ops(entry, NULL, snd_pcm_proc_read);
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- snd_pcm_proc_entry = entry;
-}
-
-static void snd_pcm_proc_done(void)
-{
- snd_info_free_entry(snd_pcm_proc_entry);
-}
-
-#else /* !CONFIG_PROC_FS */
-#define snd_pcm_proc_init()
-#define snd_pcm_proc_done()
-#endif /* CONFIG_PROC_FS */
-
-
-/*
- * ENTRY functions
- */
-
-static int __init alsa_pcm_init(void)
-{
- snd_ctl_register_ioctl(snd_pcm_control_ioctl);
- snd_ctl_register_ioctl_compat(snd_pcm_control_ioctl);
- snd_pcm_proc_init();
- return 0;
-}
-
-static void __exit alsa_pcm_exit(void)
-{
- snd_ctl_unregister_ioctl(snd_pcm_control_ioctl);
- snd_ctl_unregister_ioctl_compat(snd_pcm_control_ioctl);
- snd_pcm_proc_done();
-}
-
-module_init(alsa_pcm_init)
-module_exit(alsa_pcm_exit)
diff --git a/ANDROID_3.4.5/sound/core/pcm_compat.c b/ANDROID_3.4.5/sound/core/pcm_compat.c
deleted file mode 100644
index 91cdf943..00000000
--- a/ANDROID_3.4.5/sound/core/pcm_compat.c
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
- * 32bit -> 64bit ioctl wrapper for PCM API
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/* This file included from pcm_native.c */
-
-#include <linux/compat.h>
-#include <linux/slab.h>
-
-static int snd_pcm_ioctl_delay_compat(struct snd_pcm_substream *substream,
- s32 __user *src)
-{
- snd_pcm_sframes_t delay;
- mm_segment_t fs;
- int err;
-
- fs = snd_enter_user();
- err = snd_pcm_delay(substream, &delay);
- snd_leave_user(fs);
- if (err < 0)
- return err;
- if (put_user(delay, src))
- return -EFAULT;
- return err;
-}
-
-static int snd_pcm_ioctl_rewind_compat(struct snd_pcm_substream *substream,
- u32 __user *src)
-{
- snd_pcm_uframes_t frames;
- int err;
-
- if (get_user(frames, src))
- return -EFAULT;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- err = snd_pcm_playback_rewind(substream, frames);
- else
- err = snd_pcm_capture_rewind(substream, frames);
- if (put_user(err, src))
- return -EFAULT;
- return err < 0 ? err : 0;
-}
-
-static int snd_pcm_ioctl_forward_compat(struct snd_pcm_substream *substream,
- u32 __user *src)
-{
- snd_pcm_uframes_t frames;
- int err;
-
- if (get_user(frames, src))
- return -EFAULT;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- err = snd_pcm_playback_forward(substream, frames);
- else
- err = snd_pcm_capture_forward(substream, frames);
- if (put_user(err, src))
- return -EFAULT;
- return err < 0 ? err : 0;
-}
-
-struct snd_pcm_hw_params32 {
- u32 flags;
- struct snd_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - SNDRV_PCM_HW_PARAM_FIRST_MASK + 1]; /* this must be identical */
- struct snd_mask mres[5]; /* reserved masks */
- struct snd_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
- struct snd_interval ires[9]; /* reserved intervals */
- u32 rmask;
- u32 cmask;
- u32 info;
- u32 msbits;
- u32 rate_num;
- u32 rate_den;
- u32 fifo_size;
- unsigned char reserved[64];
-};
-
-struct snd_pcm_sw_params32 {
- s32 tstamp_mode;
- u32 period_step;
- u32 sleep_min;
- u32 avail_min;
- u32 xfer_align;
- u32 start_threshold;
- u32 stop_threshold;
- u32 silence_threshold;
- u32 silence_size;
- u32 boundary;
- unsigned char reserved[64];
-};
-
-/* recalcuate the boundary within 32bit */
-static snd_pcm_uframes_t recalculate_boundary(struct snd_pcm_runtime *runtime)
-{
- snd_pcm_uframes_t boundary;
-
- if (! runtime->buffer_size)
- return 0;
- boundary = runtime->buffer_size;
- while (boundary * 2 <= 0x7fffffffUL - runtime->buffer_size)
- boundary *= 2;
- return boundary;
-}
-
-static int snd_pcm_ioctl_sw_params_compat(struct snd_pcm_substream *substream,
- struct snd_pcm_sw_params32 __user *src)
-{
- struct snd_pcm_sw_params params;
- snd_pcm_uframes_t boundary;
- int err;
-
- memset(&params, 0, sizeof(params));
- if (get_user(params.tstamp_mode, &src->tstamp_mode) ||
- get_user(params.period_step, &src->period_step) ||
- get_user(params.sleep_min, &src->sleep_min) ||
- get_user(params.avail_min, &src->avail_min) ||
- get_user(params.xfer_align, &src->xfer_align) ||
- get_user(params.start_threshold, &src->start_threshold) ||
- get_user(params.stop_threshold, &src->stop_threshold) ||
- get_user(params.silence_threshold, &src->silence_threshold) ||
- get_user(params.silence_size, &src->silence_size))
- return -EFAULT;
- /*
- * Check silent_size parameter. Since we have 64bit boundary,
- * silence_size must be compared with the 32bit boundary.
- */
- boundary = recalculate_boundary(substream->runtime);
- if (boundary && params.silence_size >= boundary)
- params.silence_size = substream->runtime->boundary;
- err = snd_pcm_sw_params(substream, &params);
- if (err < 0)
- return err;
- if (boundary && put_user(boundary, &src->boundary))
- return -EFAULT;
- return err;
-}
-
-struct snd_pcm_channel_info32 {
- u32 channel;
- u32 offset;
- u32 first;
- u32 step;
-};
-
-static int snd_pcm_ioctl_channel_info_compat(struct snd_pcm_substream *substream,
- struct snd_pcm_channel_info32 __user *src)
-{
- struct snd_pcm_channel_info info;
- int err;
-
- if (get_user(info.channel, &src->channel) ||
- get_user(info.offset, &src->offset) ||
- get_user(info.first, &src->first) ||
- get_user(info.step, &src->step))
- return -EFAULT;
- err = snd_pcm_channel_info(substream, &info);
- if (err < 0)
- return err;
- if (put_user(info.channel, &src->channel) ||
- put_user(info.offset, &src->offset) ||
- put_user(info.first, &src->first) ||
- put_user(info.step, &src->step))
- return -EFAULT;
- return err;
-}
-
-struct snd_pcm_status32 {
- s32 state;
- struct compat_timespec trigger_tstamp;
- struct compat_timespec tstamp;
- u32 appl_ptr;
- u32 hw_ptr;
- s32 delay;
- u32 avail;
- u32 avail_max;
- u32 overrange;
- s32 suspended_state;
- unsigned char reserved[60];
-} __attribute__((packed));
-
-
-static int snd_pcm_status_user_compat(struct snd_pcm_substream *substream,
- struct snd_pcm_status32 __user *src)
-{
- struct snd_pcm_status status;
- int err;
-
- err = snd_pcm_status(substream, &status);
- if (err < 0)
- return err;
-
- if (put_user(status.state, &src->state) ||
- put_user(status.trigger_tstamp.tv_sec, &src->trigger_tstamp.tv_sec) ||
- put_user(status.trigger_tstamp.tv_nsec, &src->trigger_tstamp.tv_nsec) ||
- put_user(status.tstamp.tv_sec, &src->tstamp.tv_sec) ||
- put_user(status.tstamp.tv_nsec, &src->tstamp.tv_nsec) ||
- put_user(status.appl_ptr, &src->appl_ptr) ||
- put_user(status.hw_ptr, &src->hw_ptr) ||
- put_user(status.delay, &src->delay) ||
- put_user(status.avail, &src->avail) ||
- put_user(status.avail_max, &src->avail_max) ||
- put_user(status.overrange, &src->overrange) ||
- put_user(status.suspended_state, &src->suspended_state))
- return -EFAULT;
-
- return err;
-}
-
-/* both for HW_PARAMS and HW_REFINE */
-static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream,
- int refine,
- struct snd_pcm_hw_params32 __user *data32)
-{
- struct snd_pcm_hw_params *data;
- struct snd_pcm_runtime *runtime;
- int err;
-
- if (! (runtime = substream->runtime))
- return -ENOTTY;
-
- /* only fifo_size is different, so just copy all */
- data = memdup_user(data32, sizeof(*data32));
- if (IS_ERR(data))
- return PTR_ERR(data);
-
- if (refine)
- err = snd_pcm_hw_refine(substream, data);
- else
- err = snd_pcm_hw_params(substream, data);
- if (err < 0)
- goto error;
- if (copy_to_user(data32, data, sizeof(*data32)) ||
- put_user(data->fifo_size, &data32->fifo_size)) {
- err = -EFAULT;
- goto error;
- }
-
- if (! refine) {
- unsigned int new_boundary = recalculate_boundary(runtime);
- if (new_boundary)
- runtime->boundary = new_boundary;
- }
- error:
- kfree(data);
- return err;
-}
-
-
-/*
- */
-struct snd_xferi32 {
- s32 result;
- u32 buf;
- u32 frames;
-};
-
-static int snd_pcm_ioctl_xferi_compat(struct snd_pcm_substream *substream,
- int dir, struct snd_xferi32 __user *data32)
-{
- compat_caddr_t buf;
- u32 frames;
- int err;
-
- if (! substream->runtime)
- return -ENOTTY;
- if (substream->stream != dir)
- return -EINVAL;
- if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
- return -EBADFD;
-
- if (get_user(buf, &data32->buf) ||
- get_user(frames, &data32->frames))
- return -EFAULT;
-
- if (dir == SNDRV_PCM_STREAM_PLAYBACK)
- err = snd_pcm_lib_write(substream, compat_ptr(buf), frames);
- else
- err = snd_pcm_lib_read(substream, compat_ptr(buf), frames);
- if (err < 0)
- return err;
- /* copy the result */
- if (put_user(err, &data32->result))
- return -EFAULT;
- return 0;
-}
-
-
-/* snd_xfern needs remapping of bufs */
-struct snd_xfern32 {
- s32 result;
- u32 bufs; /* this is void **; */
- u32 frames;
-};
-
-/*
- * xfern ioctl nees to copy (up to) 128 pointers on stack.
- * although we may pass the copied pointers through f_op->ioctl, but the ioctl
- * handler there expands again the same 128 pointers on stack, so it is better
- * to handle the function (calling pcm_readv/writev) directly in this handler.
- */
-static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream,
- int dir, struct snd_xfern32 __user *data32)
-{
- compat_caddr_t buf;
- compat_caddr_t __user *bufptr;
- u32 frames;
- void __user **bufs;
- int err, ch, i;
-
- if (! substream->runtime)
- return -ENOTTY;
- if (substream->stream != dir)
- return -EINVAL;
-
- if ((ch = substream->runtime->channels) > 128)
- return -EINVAL;
- if (get_user(buf, &data32->bufs) ||
- get_user(frames, &data32->frames))
- return -EFAULT;
- bufptr = compat_ptr(buf);
- bufs = kmalloc(sizeof(void __user *) * ch, GFP_KERNEL);
- if (bufs == NULL)
- return -ENOMEM;
- for (i = 0; i < ch; i++) {
- u32 ptr;
- if (get_user(ptr, bufptr)) {
- kfree(bufs);
- return -EFAULT;
- }
- bufs[i] = compat_ptr(ptr);
- bufptr++;
- }
- if (dir == SNDRV_PCM_STREAM_PLAYBACK)
- err = snd_pcm_lib_writev(substream, bufs, frames);
- else
- err = snd_pcm_lib_readv(substream, bufs, frames);
- if (err >= 0) {
- if (put_user(err, &data32->result))
- err = -EFAULT;
- }
- kfree(bufs);
- return err;
-}
-
-
-struct snd_pcm_mmap_status32 {
- s32 state;
- s32 pad1;
- u32 hw_ptr;
- struct compat_timespec tstamp;
- s32 suspended_state;
-} __attribute__((packed));
-
-struct snd_pcm_mmap_control32 {
- u32 appl_ptr;
- u32 avail_min;
-};
-
-struct snd_pcm_sync_ptr32 {
- u32 flags;
- union {
- struct snd_pcm_mmap_status32 status;
- unsigned char reserved[64];
- } s;
- union {
- struct snd_pcm_mmap_control32 control;
- unsigned char reserved[64];
- } c;
-} __attribute__((packed));
-
-static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
- struct snd_pcm_sync_ptr32 __user *src)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- volatile struct snd_pcm_mmap_status *status;
- volatile struct snd_pcm_mmap_control *control;
- u32 sflags;
- struct snd_pcm_mmap_control scontrol;
- struct snd_pcm_mmap_status sstatus;
- snd_pcm_uframes_t boundary;
- int err;
-
- if (snd_BUG_ON(!runtime))
- return -EINVAL;
-
- if (get_user(sflags, &src->flags) ||
- get_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
- get_user(scontrol.avail_min, &src->c.control.avail_min))
- return -EFAULT;
- if (sflags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
- err = snd_pcm_hwsync(substream);
- if (err < 0)
- return err;
- }
- status = runtime->status;
- control = runtime->control;
- boundary = recalculate_boundary(runtime);
- if (! boundary)
- boundary = 0x7fffffff;
- snd_pcm_stream_lock_irq(substream);
- /* FIXME: we should consider the boundary for the sync from app */
- if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL))
- control->appl_ptr = scontrol.appl_ptr;
- else
- scontrol.appl_ptr = control->appl_ptr % boundary;
- if (!(sflags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN))
- control->avail_min = scontrol.avail_min;
- else
- scontrol.avail_min = control->avail_min;
- sstatus.state = status->state;
- sstatus.hw_ptr = status->hw_ptr % boundary;
- sstatus.tstamp = status->tstamp;
- sstatus.suspended_state = status->suspended_state;
- snd_pcm_stream_unlock_irq(substream);
- if (put_user(sstatus.state, &src->s.status.state) ||
- put_user(sstatus.hw_ptr, &src->s.status.hw_ptr) ||
- put_user(sstatus.tstamp.tv_sec, &src->s.status.tstamp.tv_sec) ||
- put_user(sstatus.tstamp.tv_nsec, &src->s.status.tstamp.tv_nsec) ||
- put_user(sstatus.suspended_state, &src->s.status.suspended_state) ||
- put_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
- put_user(scontrol.avail_min, &src->c.control.avail_min))
- return -EFAULT;
-
- return 0;
-}
-
-
-/*
- */
-enum {
- SNDRV_PCM_IOCTL_HW_REFINE32 = _IOWR('A', 0x10, struct snd_pcm_hw_params32),
- SNDRV_PCM_IOCTL_HW_PARAMS32 = _IOWR('A', 0x11, struct snd_pcm_hw_params32),
- SNDRV_PCM_IOCTL_SW_PARAMS32 = _IOWR('A', 0x13, struct snd_pcm_sw_params32),
- SNDRV_PCM_IOCTL_STATUS32 = _IOR('A', 0x20, struct snd_pcm_status32),
- SNDRV_PCM_IOCTL_DELAY32 = _IOR('A', 0x21, s32),
- SNDRV_PCM_IOCTL_CHANNEL_INFO32 = _IOR('A', 0x32, struct snd_pcm_channel_info32),
- SNDRV_PCM_IOCTL_REWIND32 = _IOW('A', 0x46, u32),
- SNDRV_PCM_IOCTL_FORWARD32 = _IOW('A', 0x49, u32),
- SNDRV_PCM_IOCTL_WRITEI_FRAMES32 = _IOW('A', 0x50, struct snd_xferi32),
- SNDRV_PCM_IOCTL_READI_FRAMES32 = _IOR('A', 0x51, struct snd_xferi32),
- SNDRV_PCM_IOCTL_WRITEN_FRAMES32 = _IOW('A', 0x52, struct snd_xfern32),
- SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct snd_xfern32),
- SNDRV_PCM_IOCTL_SYNC_PTR32 = _IOWR('A', 0x23, struct snd_pcm_sync_ptr32),
-
-};
-
-static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct snd_pcm_file *pcm_file;
- struct snd_pcm_substream *substream;
- void __user *argp = compat_ptr(arg);
-
- pcm_file = file->private_data;
- if (! pcm_file)
- return -ENOTTY;
- substream = pcm_file->substream;
- if (! substream)
- return -ENOTTY;
-
- /*
- * When PCM is used on 32bit mode, we need to disable
- * mmap of PCM status/control records because of the size
- * incompatibility.
- */
- pcm_file->no_compat_mmap = 1;
-
- switch (cmd) {
- case SNDRV_PCM_IOCTL_PVERSION:
- case SNDRV_PCM_IOCTL_INFO:
- case SNDRV_PCM_IOCTL_TSTAMP:
- case SNDRV_PCM_IOCTL_TTSTAMP:
- case SNDRV_PCM_IOCTL_HWSYNC:
- case SNDRV_PCM_IOCTL_PREPARE:
- case SNDRV_PCM_IOCTL_RESET:
- case SNDRV_PCM_IOCTL_START:
- case SNDRV_PCM_IOCTL_DROP:
- case SNDRV_PCM_IOCTL_DRAIN:
- case SNDRV_PCM_IOCTL_PAUSE:
- case SNDRV_PCM_IOCTL_HW_FREE:
- case SNDRV_PCM_IOCTL_RESUME:
- case SNDRV_PCM_IOCTL_XRUN:
- case SNDRV_PCM_IOCTL_LINK:
- case SNDRV_PCM_IOCTL_UNLINK:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- return snd_pcm_playback_ioctl1(file, substream, cmd, argp);
- else
- return snd_pcm_capture_ioctl1(file, substream, cmd, argp);
- case SNDRV_PCM_IOCTL_HW_REFINE32:
- return snd_pcm_ioctl_hw_params_compat(substream, 1, argp);
- case SNDRV_PCM_IOCTL_HW_PARAMS32:
- return snd_pcm_ioctl_hw_params_compat(substream, 0, argp);
- case SNDRV_PCM_IOCTL_SW_PARAMS32:
- return snd_pcm_ioctl_sw_params_compat(substream, argp);
- case SNDRV_PCM_IOCTL_STATUS32:
- return snd_pcm_status_user_compat(substream, argp);
- case SNDRV_PCM_IOCTL_SYNC_PTR32:
- return snd_pcm_ioctl_sync_ptr_compat(substream, argp);
- case SNDRV_PCM_IOCTL_CHANNEL_INFO32:
- return snd_pcm_ioctl_channel_info_compat(substream, argp);
- case SNDRV_PCM_IOCTL_WRITEI_FRAMES32:
- return snd_pcm_ioctl_xferi_compat(substream, SNDRV_PCM_STREAM_PLAYBACK, argp);
- case SNDRV_PCM_IOCTL_READI_FRAMES32:
- return snd_pcm_ioctl_xferi_compat(substream, SNDRV_PCM_STREAM_CAPTURE, argp);
- case SNDRV_PCM_IOCTL_WRITEN_FRAMES32:
- return snd_pcm_ioctl_xfern_compat(substream, SNDRV_PCM_STREAM_PLAYBACK, argp);
- case SNDRV_PCM_IOCTL_READN_FRAMES32:
- return snd_pcm_ioctl_xfern_compat(substream, SNDRV_PCM_STREAM_CAPTURE, argp);
- case SNDRV_PCM_IOCTL_DELAY32:
- return snd_pcm_ioctl_delay_compat(substream, argp);
- case SNDRV_PCM_IOCTL_REWIND32:
- return snd_pcm_ioctl_rewind_compat(substream, argp);
- case SNDRV_PCM_IOCTL_FORWARD32:
- return snd_pcm_ioctl_forward_compat(substream, argp);
- }
-
- return -ENOIOCTLCMD;
-}
diff --git a/ANDROID_3.4.5/sound/core/pcm_lib.c b/ANDROID_3.4.5/sound/core/pcm_lib.c
deleted file mode 100644
index 4d189411..00000000
--- a/ANDROID_3.4.5/sound/core/pcm_lib.c
+++ /dev/null
@@ -1,2289 +0,0 @@
-/*
- * Digital Audio (PCM) abstract layer
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Abramo Bagnara <abramo@alsa-project.org>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/math64.h>
-#include <linux/export.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/info.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/timer.h>
-
-/*
- * fill ring buffer with silence
- * runtime->silence_start: starting pointer to silence area
- * runtime->silence_filled: size filled with silence
- * runtime->silence_threshold: threshold from application
- * runtime->silence_size: maximal size from application
- *
- * when runtime->silence_size >= runtime->boundary - fill processed area with silence immediately
- */
-void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_uframes_t new_hw_ptr)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_uframes_t frames, ofs, transfer;
-
- if (runtime->silence_size < runtime->boundary) {
- snd_pcm_sframes_t noise_dist, n;
- if (runtime->silence_start != runtime->control->appl_ptr) {
- n = runtime->control->appl_ptr - runtime->silence_start;
- if (n < 0)
- n += runtime->boundary;
- if ((snd_pcm_uframes_t)n < runtime->silence_filled)
- runtime->silence_filled -= n;
- else
- runtime->silence_filled = 0;
- runtime->silence_start = runtime->control->appl_ptr;
- }
- if (runtime->silence_filled >= runtime->buffer_size)
- return;
- noise_dist = snd_pcm_playback_hw_avail(runtime) + runtime->silence_filled;
- if (noise_dist >= (snd_pcm_sframes_t) runtime->silence_threshold)
- return;
- frames = runtime->silence_threshold - noise_dist;
- if (frames > runtime->silence_size)
- frames = runtime->silence_size;
- } else {
- if (new_hw_ptr == ULONG_MAX) { /* initialization */
- snd_pcm_sframes_t avail = snd_pcm_playback_hw_avail(runtime);
- if (avail > runtime->buffer_size)
- avail = runtime->buffer_size;
- runtime->silence_filled = avail > 0 ? avail : 0;
- runtime->silence_start = (runtime->status->hw_ptr +
- runtime->silence_filled) %
- runtime->boundary;
- } else {
- ofs = runtime->status->hw_ptr;
- frames = new_hw_ptr - ofs;
- if ((snd_pcm_sframes_t)frames < 0)
- frames += runtime->boundary;
- runtime->silence_filled -= frames;
- if ((snd_pcm_sframes_t)runtime->silence_filled < 0) {
- runtime->silence_filled = 0;
- runtime->silence_start = new_hw_ptr;
- } else {
- runtime->silence_start = ofs;
- }
- }
- frames = runtime->buffer_size - runtime->silence_filled;
- }
- if (snd_BUG_ON(frames > runtime->buffer_size))
- return;
- if (frames == 0)
- return;
- ofs = runtime->silence_start % runtime->buffer_size;
- while (frames > 0) {
- transfer = ofs + frames > runtime->buffer_size ? runtime->buffer_size - ofs : frames;
- if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED ||
- runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
- if (substream->ops->silence) {
- int err;
- err = substream->ops->silence(substream, -1, ofs, transfer);
- snd_BUG_ON(err < 0);
- } else {
- char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, ofs);
- snd_pcm_format_set_silence(runtime->format, hwbuf, transfer * runtime->channels);
- }
- } else {
- unsigned int c;
- unsigned int channels = runtime->channels;
- if (substream->ops->silence) {
- for (c = 0; c < channels; ++c) {
- int err;
- err = substream->ops->silence(substream, c, ofs, transfer);
- snd_BUG_ON(err < 0);
- }
- } else {
- size_t dma_csize = runtime->dma_bytes / channels;
- for (c = 0; c < channels; ++c) {
- char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, ofs);
- snd_pcm_format_set_silence(runtime->format, hwbuf, transfer);
- }
- }
- }
- runtime->silence_filled += transfer;
- frames -= transfer;
- ofs = 0;
- }
-}
-
-#ifdef CONFIG_SND_DEBUG
-void snd_pcm_debug_name(struct snd_pcm_substream *substream,
- char *name, size_t len)
-{
- snprintf(name, len, "pcmC%dD%d%c:%d",
- substream->pcm->card->number,
- substream->pcm->device,
- substream->stream ? 'c' : 'p',
- substream->number);
-}
-EXPORT_SYMBOL(snd_pcm_debug_name);
-#endif
-
-#define XRUN_DEBUG_BASIC (1<<0)
-#define XRUN_DEBUG_STACK (1<<1) /* dump also stack */
-#define XRUN_DEBUG_JIFFIESCHECK (1<<2) /* do jiffies check */
-#define XRUN_DEBUG_PERIODUPDATE (1<<3) /* full period update info */
-#define XRUN_DEBUG_HWPTRUPDATE (1<<4) /* full hwptr update info */
-#define XRUN_DEBUG_LOG (1<<5) /* show last 10 positions on err */
-#define XRUN_DEBUG_LOGONCE (1<<6) /* do above only once */
-
-#ifdef CONFIG_SND_PCM_XRUN_DEBUG
-
-#define xrun_debug(substream, mask) \
- ((substream)->pstr->xrun_debug & (mask))
-#else
-#define xrun_debug(substream, mask) 0
-#endif
-
-#define dump_stack_on_xrun(substream) do { \
- if (xrun_debug(substream, XRUN_DEBUG_STACK)) \
- dump_stack(); \
- } while (0)
-
-static void xrun(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
- snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
- snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
- if (xrun_debug(substream, XRUN_DEBUG_BASIC)) {
- char name[16];
- snd_pcm_debug_name(substream, name, sizeof(name));
- snd_printd(KERN_DEBUG "XRUN: %s\n", name);
- dump_stack_on_xrun(substream);
- }
-}
-
-#ifdef CONFIG_SND_PCM_XRUN_DEBUG
-#define hw_ptr_error(substream, fmt, args...) \
- do { \
- if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \
- xrun_log_show(substream); \
- if (printk_ratelimit()) { \
- snd_printd("PCM: " fmt, ##args); \
- } \
- dump_stack_on_xrun(substream); \
- } \
- } while (0)
-
-#define XRUN_LOG_CNT 10
-
-struct hwptr_log_entry {
- unsigned int in_interrupt;
- unsigned long jiffies;
- snd_pcm_uframes_t pos;
- snd_pcm_uframes_t period_size;
- snd_pcm_uframes_t buffer_size;
- snd_pcm_uframes_t old_hw_ptr;
- snd_pcm_uframes_t hw_ptr_base;
-};
-
-struct snd_pcm_hwptr_log {
- unsigned int idx;
- unsigned int hit: 1;
- struct hwptr_log_entry entries[XRUN_LOG_CNT];
-};
-
-static void xrun_log(struct snd_pcm_substream *substream,
- snd_pcm_uframes_t pos, int in_interrupt)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_pcm_hwptr_log *log = runtime->hwptr_log;
- struct hwptr_log_entry *entry;
-
- if (log == NULL) {
- log = kzalloc(sizeof(*log), GFP_ATOMIC);
- if (log == NULL)
- return;
- runtime->hwptr_log = log;
- } else {
- if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit)
- return;
- }
- entry = &log->entries[log->idx];
- entry->in_interrupt = in_interrupt;
- entry->jiffies = jiffies;
- entry->pos = pos;
- entry->period_size = runtime->period_size;
- entry->buffer_size = runtime->buffer_size;
- entry->old_hw_ptr = runtime->status->hw_ptr;
- entry->hw_ptr_base = runtime->hw_ptr_base;
- log->idx = (log->idx + 1) % XRUN_LOG_CNT;
-}
-
-static void xrun_log_show(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_hwptr_log *log = substream->runtime->hwptr_log;
- struct hwptr_log_entry *entry;
- char name[16];
- unsigned int idx;
- int cnt;
-
- if (log == NULL)
- return;
- if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit)
- return;
- snd_pcm_debug_name(substream, name, sizeof(name));
- for (cnt = 0, idx = log->idx; cnt < XRUN_LOG_CNT; cnt++) {
- entry = &log->entries[idx];
- if (entry->period_size == 0)
- break;
- snd_printd("hwptr log: %s: %sj=%lu, pos=%ld/%ld/%ld, "
- "hwptr=%ld/%ld\n",
- name, entry->in_interrupt ? "[Q] " : "",
- entry->jiffies,
- (unsigned long)entry->pos,
- (unsigned long)entry->period_size,
- (unsigned long)entry->buffer_size,
- (unsigned long)entry->old_hw_ptr,
- (unsigned long)entry->hw_ptr_base);
- idx++;
- idx %= XRUN_LOG_CNT;
- }
- log->hit = 1;
-}
-
-#else /* ! CONFIG_SND_PCM_XRUN_DEBUG */
-
-#define hw_ptr_error(substream, fmt, args...) do { } while (0)
-#define xrun_log(substream, pos, in_interrupt) do { } while (0)
-#define xrun_log_show(substream) do { } while (0)
-
-#endif
-
-int snd_pcm_update_state(struct snd_pcm_substream *substream,
- struct snd_pcm_runtime *runtime)
-{
- snd_pcm_uframes_t avail;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- avail = snd_pcm_playback_avail(runtime);
- else
- avail = snd_pcm_capture_avail(runtime);
- if (avail > runtime->avail_max)
- runtime->avail_max = avail;
- if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
- if (avail >= runtime->buffer_size) {
- snd_pcm_drain_done(substream);
- return -EPIPE;
- }
- } else {
- if (avail >= runtime->stop_threshold) {
- xrun(substream);
- return -EPIPE;
- }
- }
- if (runtime->twake) {
- if (avail >= runtime->twake)
- wake_up(&runtime->tsleep);
- } else if (avail >= runtime->control->avail_min)
- wake_up(&runtime->sleep);
- return 0;
-}
-
-static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
- unsigned int in_interrupt)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_uframes_t pos;
- snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_base;
- snd_pcm_sframes_t hdelta, delta;
- unsigned long jdelta;
-
- old_hw_ptr = runtime->status->hw_ptr;
- pos = substream->ops->pointer(substream);
- if (pos == SNDRV_PCM_POS_XRUN) {
- xrun(substream);
- return -EPIPE;
- }
- if (pos >= runtime->buffer_size) {
- if (printk_ratelimit()) {
- char name[16];
- snd_pcm_debug_name(substream, name, sizeof(name));
- xrun_log_show(substream);
- snd_printd(KERN_ERR "BUG: %s, pos = %ld, "
- "buffer size = %ld, period size = %ld\n",
- name, pos, runtime->buffer_size,
- runtime->period_size);
- }
- pos = 0;
- }
- pos -= pos % runtime->min_align;
- if (xrun_debug(substream, XRUN_DEBUG_LOG))
- xrun_log(substream, pos, in_interrupt);
- hw_base = runtime->hw_ptr_base;
- new_hw_ptr = hw_base + pos;
- if (in_interrupt) {
- /* we know that one period was processed */
- /* delta = "expected next hw_ptr" for in_interrupt != 0 */
- delta = runtime->hw_ptr_interrupt + runtime->period_size;
- if (delta > new_hw_ptr) {
- /* check for double acknowledged interrupts */
- hdelta = jiffies - runtime->hw_ptr_jiffies;
- if (hdelta > runtime->hw_ptr_buffer_jiffies/2) {
- hw_base += runtime->buffer_size;
- if (hw_base >= runtime->boundary)
- hw_base = 0;
- new_hw_ptr = hw_base + pos;
- goto __delta;
- }
- }
- }
- /* new_hw_ptr might be lower than old_hw_ptr in case when */
- /* pointer crosses the end of the ring buffer */
- if (new_hw_ptr < old_hw_ptr) {
- hw_base += runtime->buffer_size;
- if (hw_base >= runtime->boundary)
- hw_base = 0;
- new_hw_ptr = hw_base + pos;
- }
- __delta:
- delta = new_hw_ptr - old_hw_ptr;
- if (delta < 0)
- delta += runtime->boundary;
- if (xrun_debug(substream, in_interrupt ?
- XRUN_DEBUG_PERIODUPDATE : XRUN_DEBUG_HWPTRUPDATE)) {
- char name[16];
- snd_pcm_debug_name(substream, name, sizeof(name));
- snd_printd("%s_update: %s: pos=%u/%u/%u, "
- "hwptr=%ld/%ld/%ld/%ld\n",
- in_interrupt ? "period" : "hwptr",
- name,
- (unsigned int)pos,
- (unsigned int)runtime->period_size,
- (unsigned int)runtime->buffer_size,
- (unsigned long)delta,
- (unsigned long)old_hw_ptr,
- (unsigned long)new_hw_ptr,
- (unsigned long)runtime->hw_ptr_base);
- }
-
- if (runtime->no_period_wakeup) {
- snd_pcm_sframes_t xrun_threshold;
- /*
- * Without regular period interrupts, we have to check
- * the elapsed time to detect xruns.
- */
- jdelta = jiffies - runtime->hw_ptr_jiffies;
- if (jdelta < runtime->hw_ptr_buffer_jiffies / 2)
- goto no_delta_check;
- hdelta = jdelta - delta * HZ / runtime->rate;
- xrun_threshold = runtime->hw_ptr_buffer_jiffies / 2 + 1;
- while (hdelta > xrun_threshold) {
- delta += runtime->buffer_size;
- hw_base += runtime->buffer_size;
- if (hw_base >= runtime->boundary)
- hw_base = 0;
- new_hw_ptr = hw_base + pos;
- hdelta -= runtime->hw_ptr_buffer_jiffies;
- }
- goto no_delta_check;
- }
-
- /* something must be really wrong */
- if (delta >= runtime->buffer_size + runtime->period_size) {
- hw_ptr_error(substream,
- "Unexpected hw_pointer value %s"
- "(stream=%i, pos=%ld, new_hw_ptr=%ld, "
- "old_hw_ptr=%ld)\n",
- in_interrupt ? "[Q] " : "[P]",
- substream->stream, (long)pos,
- (long)new_hw_ptr, (long)old_hw_ptr);
- return 0;
- }
-
- /* Do jiffies check only in xrun_debug mode */
- if (!xrun_debug(substream, XRUN_DEBUG_JIFFIESCHECK))
- goto no_jiffies_check;
-
- /* Skip the jiffies check for hardwares with BATCH flag.
- * Such hardware usually just increases the position at each IRQ,
- * thus it can't give any strange position.
- */
- if (runtime->hw.info & SNDRV_PCM_INFO_BATCH)
- goto no_jiffies_check;
- hdelta = delta;
- if (hdelta < runtime->delay)
- goto no_jiffies_check;
- hdelta -= runtime->delay;
- jdelta = jiffies - runtime->hw_ptr_jiffies;
- if (((hdelta * HZ) / runtime->rate) > jdelta + HZ/100) {
- delta = jdelta /
- (((runtime->period_size * HZ) / runtime->rate)
- + HZ/100);
- /* move new_hw_ptr according jiffies not pos variable */
- new_hw_ptr = old_hw_ptr;
- hw_base = delta;
- /* use loop to avoid checks for delta overflows */
- /* the delta value is small or zero in most cases */
- while (delta > 0) {
- new_hw_ptr += runtime->period_size;
- if (new_hw_ptr >= runtime->boundary)
- new_hw_ptr -= runtime->boundary;
- delta--;
- }
- /* align hw_base to buffer_size */
- hw_ptr_error(substream,
- "hw_ptr skipping! %s"
- "(pos=%ld, delta=%ld, period=%ld, "
- "jdelta=%lu/%lu/%lu, hw_ptr=%ld/%ld)\n",
- in_interrupt ? "[Q] " : "",
- (long)pos, (long)hdelta,
- (long)runtime->period_size, jdelta,
- ((hdelta * HZ) / runtime->rate), hw_base,
- (unsigned long)old_hw_ptr,
- (unsigned long)new_hw_ptr);
- /* reset values to proper state */
- delta = 0;
- hw_base = new_hw_ptr - (new_hw_ptr % runtime->buffer_size);
- }
- no_jiffies_check:
- if (delta > runtime->period_size + runtime->period_size / 2) {
- hw_ptr_error(substream,
- "Lost interrupts? %s"
- "(stream=%i, delta=%ld, new_hw_ptr=%ld, "
- "old_hw_ptr=%ld)\n",
- in_interrupt ? "[Q] " : "",
- substream->stream, (long)delta,
- (long)new_hw_ptr,
- (long)old_hw_ptr);
- }
-
- no_delta_check:
- if (runtime->status->hw_ptr == new_hw_ptr)
- return 0;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
- runtime->silence_size > 0)
- snd_pcm_playback_silence(substream, new_hw_ptr);
-
- if (in_interrupt) {
- delta = new_hw_ptr - runtime->hw_ptr_interrupt;
- if (delta < 0)
- delta += runtime->boundary;
- delta -= (snd_pcm_uframes_t)delta % runtime->period_size;
- runtime->hw_ptr_interrupt += delta;
- if (runtime->hw_ptr_interrupt >= runtime->boundary)
- runtime->hw_ptr_interrupt -= runtime->boundary;
- }
- runtime->hw_ptr_base = hw_base;
- runtime->status->hw_ptr = new_hw_ptr;
- runtime->hw_ptr_jiffies = jiffies;
- if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
- snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
-
- return snd_pcm_update_state(substream, runtime);
-}
-
-/* CAUTION: call it with irq disabled */
-int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
-{
- return snd_pcm_update_hw_ptr0(substream, 0);
-}
-
-/**
- * snd_pcm_set_ops - set the PCM operators
- * @pcm: the pcm instance
- * @direction: stream direction, SNDRV_PCM_STREAM_XXX
- * @ops: the operator table
- *
- * Sets the given PCM operators to the pcm instance.
- */
-void snd_pcm_set_ops(struct snd_pcm *pcm, int direction, struct snd_pcm_ops *ops)
-{
- struct snd_pcm_str *stream = &pcm->streams[direction];
- struct snd_pcm_substream *substream;
-
- for (substream = stream->substream; substream != NULL; substream = substream->next)
- substream->ops = ops;
-}
-
-EXPORT_SYMBOL(snd_pcm_set_ops);
-
-/**
- * snd_pcm_sync - set the PCM sync id
- * @substream: the pcm substream
- *
- * Sets the PCM sync identifier for the card.
- */
-void snd_pcm_set_sync(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- runtime->sync.id32[0] = substream->pcm->card->number;
- runtime->sync.id32[1] = -1;
- runtime->sync.id32[2] = -1;
- runtime->sync.id32[3] = -1;
-}
-
-EXPORT_SYMBOL(snd_pcm_set_sync);
-
-/*
- * Standard ioctl routine
- */
-
-static inline unsigned int div32(unsigned int a, unsigned int b,
- unsigned int *r)
-{
- if (b == 0) {
- *r = 0;
- return UINT_MAX;
- }
- *r = a % b;
- return a / b;
-}
-
-static inline unsigned int div_down(unsigned int a, unsigned int b)
-{
- if (b == 0)
- return UINT_MAX;
- return a / b;
-}
-
-static inline unsigned int div_up(unsigned int a, unsigned int b)
-{
- unsigned int r;
- unsigned int q;
- if (b == 0)
- return UINT_MAX;
- q = div32(a, b, &r);
- if (r)
- ++q;
- return q;
-}
-
-static inline unsigned int mul(unsigned int a, unsigned int b)
-{
- if (a == 0)
- return 0;
- if (div_down(UINT_MAX, a) < b)
- return UINT_MAX;
- return a * b;
-}
-
-static inline unsigned int muldiv32(unsigned int a, unsigned int b,
- unsigned int c, unsigned int *r)
-{
- u_int64_t n = (u_int64_t) a * b;
- if (c == 0) {
- snd_BUG_ON(!n);
- *r = 0;
- return UINT_MAX;
- }
- n = div_u64_rem(n, c, r);
- if (n >= UINT_MAX) {
- *r = 0;
- return UINT_MAX;
- }
- return n;
-}
-
-/**
- * snd_interval_refine - refine the interval value of configurator
- * @i: the interval value to refine
- * @v: the interval value to refer to
- *
- * Refines the interval value with the reference value.
- * The interval is changed to the range satisfying both intervals.
- * The interval status (min, max, integer, etc.) are evaluated.
- *
- * Returns non-zero if the value is changed, zero if not changed.
- */
-int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v)
-{
- int changed = 0;
- if (snd_BUG_ON(snd_interval_empty(i)))
- return -EINVAL;
- if (i->min < v->min) {
- i->min = v->min;
- i->openmin = v->openmin;
- changed = 1;
- } else if (i->min == v->min && !i->openmin && v->openmin) {
- i->openmin = 1;
- changed = 1;
- }
- if (i->max > v->max) {
- i->max = v->max;
- i->openmax = v->openmax;
- changed = 1;
- } else if (i->max == v->max && !i->openmax && v->openmax) {
- i->openmax = 1;
- changed = 1;
- }
- if (!i->integer && v->integer) {
- i->integer = 1;
- changed = 1;
- }
- if (i->integer) {
- if (i->openmin) {
- i->min++;
- i->openmin = 0;
- }
- if (i->openmax) {
- i->max--;
- i->openmax = 0;
- }
- } else if (!i->openmin && !i->openmax && i->min == i->max)
- i->integer = 1;
- if (snd_interval_checkempty(i)) {
- snd_interval_none(i);
- return -EINVAL;
- }
- return changed;
-}
-
-EXPORT_SYMBOL(snd_interval_refine);
-
-static int snd_interval_refine_first(struct snd_interval *i)
-{
- if (snd_BUG_ON(snd_interval_empty(i)))
- return -EINVAL;
- if (snd_interval_single(i))
- return 0;
- i->max = i->min;
- i->openmax = i->openmin;
- if (i->openmax)
- i->max++;
- return 1;
-}
-
-static int snd_interval_refine_last(struct snd_interval *i)
-{
- if (snd_BUG_ON(snd_interval_empty(i)))
- return -EINVAL;
- if (snd_interval_single(i))
- return 0;
- i->min = i->max;
- i->openmin = i->openmax;
- if (i->openmin)
- i->min--;
- return 1;
-}
-
-void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c)
-{
- if (a->empty || b->empty) {
- snd_interval_none(c);
- return;
- }
- c->empty = 0;
- c->min = mul(a->min, b->min);
- c->openmin = (a->openmin || b->openmin);
- c->max = mul(a->max, b->max);
- c->openmax = (a->openmax || b->openmax);
- c->integer = (a->integer && b->integer);
-}
-
-/**
- * snd_interval_div - refine the interval value with division
- * @a: dividend
- * @b: divisor
- * @c: quotient
- *
- * c = a / b
- *
- * Returns non-zero if the value is changed, zero if not changed.
- */
-void snd_interval_div(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c)
-{
- unsigned int r;
- if (a->empty || b->empty) {
- snd_interval_none(c);
- return;
- }
- c->empty = 0;
- c->min = div32(a->min, b->max, &r);
- c->openmin = (r || a->openmin || b->openmax);
- if (b->min > 0) {
- c->max = div32(a->max, b->min, &r);
- if (r) {
- c->max++;
- c->openmax = 1;
- } else
- c->openmax = (a->openmax || b->openmin);
- } else {
- c->max = UINT_MAX;
- c->openmax = 0;
- }
- c->integer = 0;
-}
-
-/**
- * snd_interval_muldivk - refine the interval value
- * @a: dividend 1
- * @b: dividend 2
- * @k: divisor (as integer)
- * @c: result
- *
- * c = a * b / k
- *
- * Returns non-zero if the value is changed, zero if not changed.
- */
-void snd_interval_muldivk(const struct snd_interval *a, const struct snd_interval *b,
- unsigned int k, struct snd_interval *c)
-{
- unsigned int r;
- if (a->empty || b->empty) {
- snd_interval_none(c);
- return;
- }
- c->empty = 0;
- c->min = muldiv32(a->min, b->min, k, &r);
- c->openmin = (r || a->openmin || b->openmin);
- c->max = muldiv32(a->max, b->max, k, &r);
- if (r) {
- c->max++;
- c->openmax = 1;
- } else
- c->openmax = (a->openmax || b->openmax);
- c->integer = 0;
-}
-
-/**
- * snd_interval_mulkdiv - refine the interval value
- * @a: dividend 1
- * @k: dividend 2 (as integer)
- * @b: divisor
- * @c: result
- *
- * c = a * k / b
- *
- * Returns non-zero if the value is changed, zero if not changed.
- */
-void snd_interval_mulkdiv(const struct snd_interval *a, unsigned int k,
- const struct snd_interval *b, struct snd_interval *c)
-{
- unsigned int r;
- if (a->empty || b->empty) {
- snd_interval_none(c);
- return;
- }
- c->empty = 0;
- c->min = muldiv32(a->min, k, b->max, &r);
- c->openmin = (r || a->openmin || b->openmax);
- if (b->min > 0) {
- c->max = muldiv32(a->max, k, b->min, &r);
- if (r) {
- c->max++;
- c->openmax = 1;
- } else
- c->openmax = (a->openmax || b->openmin);
- } else {
- c->max = UINT_MAX;
- c->openmax = 0;
- }
- c->integer = 0;
-}
-
-/* ---- */
-
-
-/**
- * snd_interval_ratnum - refine the interval value
- * @i: interval to refine
- * @rats_count: number of ratnum_t
- * @rats: ratnum_t array
- * @nump: pointer to store the resultant numerator
- * @denp: pointer to store the resultant denominator
- *
- * Returns non-zero if the value is changed, zero if not changed.
- */
-int snd_interval_ratnum(struct snd_interval *i,
- unsigned int rats_count, struct snd_ratnum *rats,
- unsigned int *nump, unsigned int *denp)
-{
- unsigned int best_num, best_den;
- int best_diff;
- unsigned int k;
- struct snd_interval t;
- int err;
- unsigned int result_num, result_den;
- int result_diff;
-
- best_num = best_den = best_diff = 0;
- for (k = 0; k < rats_count; ++k) {
- unsigned int num = rats[k].num;
- unsigned int den;
- unsigned int q = i->min;
- int diff;
- if (q == 0)
- q = 1;
- den = div_up(num, q);
- if (den < rats[k].den_min)
- continue;
- if (den > rats[k].den_max)
- den = rats[k].den_max;
- else {
- unsigned int r;
- r = (den - rats[k].den_min) % rats[k].den_step;
- if (r != 0)
- den -= r;
- }
- diff = num - q * den;
- if (diff < 0)
- diff = -diff;
- if (best_num == 0 ||
- diff * best_den < best_diff * den) {
- best_diff = diff;
- best_den = den;
- best_num = num;
- }
- }
- if (best_den == 0) {
- i->empty = 1;
- return -EINVAL;
- }
- t.min = div_down(best_num, best_den);
- t.openmin = !!(best_num % best_den);
-
- result_num = best_num;
- result_diff = best_diff;
- result_den = best_den;
- best_num = best_den = best_diff = 0;
- for (k = 0; k < rats_count; ++k) {
- unsigned int num = rats[k].num;
- unsigned int den;
- unsigned int q = i->max;
- int diff;
- if (q == 0) {
- i->empty = 1;
- return -EINVAL;
- }
- den = div_down(num, q);
- if (den > rats[k].den_max)
- continue;
- if (den < rats[k].den_min)
- den = rats[k].den_min;
- else {
- unsigned int r;
- r = (den - rats[k].den_min) % rats[k].den_step;
- if (r != 0)
- den += rats[k].den_step - r;
- }
- diff = q * den - num;
- if (diff < 0)
- diff = -diff;
- if (best_num == 0 ||
- diff * best_den < best_diff * den) {
- best_diff = diff;
- best_den = den;
- best_num = num;
- }
- }
- if (best_den == 0) {
- i->empty = 1;
- return -EINVAL;
- }
- t.max = div_up(best_num, best_den);
- t.openmax = !!(best_num % best_den);
- t.integer = 0;
- err = snd_interval_refine(i, &t);
- if (err < 0)
- return err;
-
- if (snd_interval_single(i)) {
- if (best_diff * result_den < result_diff * best_den) {
- result_num = best_num;
- result_den = best_den;
- }
- if (nump)
- *nump = result_num;
- if (denp)
- *denp = result_den;
- }
- return err;
-}
-
-EXPORT_SYMBOL(snd_interval_ratnum);
-
-/**
- * snd_interval_ratden - refine the interval value
- * @i: interval to refine
- * @rats_count: number of struct ratden
- * @rats: struct ratden array
- * @nump: pointer to store the resultant numerator
- * @denp: pointer to store the resultant denominator
- *
- * Returns non-zero if the value is changed, zero if not changed.
- */
-static int snd_interval_ratden(struct snd_interval *i,
- unsigned int rats_count, struct snd_ratden *rats,
- unsigned int *nump, unsigned int *denp)
-{
- unsigned int best_num, best_diff, best_den;
- unsigned int k;
- struct snd_interval t;
- int err;
-
- best_num = best_den = best_diff = 0;
- for (k = 0; k < rats_count; ++k) {
- unsigned int num;
- unsigned int den = rats[k].den;
- unsigned int q = i->min;
- int diff;
- num = mul(q, den);
- if (num > rats[k].num_max)
- continue;
- if (num < rats[k].num_min)
- num = rats[k].num_max;
- else {
- unsigned int r;
- r = (num - rats[k].num_min) % rats[k].num_step;
- if (r != 0)
- num += rats[k].num_step - r;
- }
- diff = num - q * den;
- if (best_num == 0 ||
- diff * best_den < best_diff * den) {
- best_diff = diff;
- best_den = den;
- best_num = num;
- }
- }
- if (best_den == 0) {
- i->empty = 1;
- return -EINVAL;
- }
- t.min = div_down(best_num, best_den);
- t.openmin = !!(best_num % best_den);
-
- best_num = best_den = best_diff = 0;
- for (k = 0; k < rats_count; ++k) {
- unsigned int num;
- unsigned int den = rats[k].den;
- unsigned int q = i->max;
- int diff;
- num = mul(q, den);
- if (num < rats[k].num_min)
- continue;
- if (num > rats[k].num_max)
- num = rats[k].num_max;
- else {
- unsigned int r;
- r = (num - rats[k].num_min) % rats[k].num_step;
- if (r != 0)
- num -= r;
- }
- diff = q * den - num;
- if (best_num == 0 ||
- diff * best_den < best_diff * den) {
- best_diff = diff;
- best_den = den;
- best_num = num;
- }
- }
- if (best_den == 0) {
- i->empty = 1;
- return -EINVAL;
- }
- t.max = div_up(best_num, best_den);
- t.openmax = !!(best_num % best_den);
- t.integer = 0;
- err = snd_interval_refine(i, &t);
- if (err < 0)
- return err;
-
- if (snd_interval_single(i)) {
- if (nump)
- *nump = best_num;
- if (denp)
- *denp = best_den;
- }
- return err;
-}
-
-/**
- * snd_interval_list - refine the interval value from the list
- * @i: the interval value to refine
- * @count: the number of elements in the list
- * @list: the value list
- * @mask: the bit-mask to evaluate
- *
- * Refines the interval value from the list.
- * When mask is non-zero, only the elements corresponding to bit 1 are
- * evaluated.
- *
- * Returns non-zero if the value is changed, zero if not changed.
- */
-int snd_interval_list(struct snd_interval *i, unsigned int count,
- const unsigned int *list, unsigned int mask)
-{
- unsigned int k;
- struct snd_interval list_range;
-
- if (!count) {
- i->empty = 1;
- return -EINVAL;
- }
- snd_interval_any(&list_range);
- list_range.min = UINT_MAX;
- list_range.max = 0;
- for (k = 0; k < count; k++) {
- if (mask && !(mask & (1 << k)))
- continue;
- if (!snd_interval_test(i, list[k]))
- continue;
- list_range.min = min(list_range.min, list[k]);
- list_range.max = max(list_range.max, list[k]);
- }
- return snd_interval_refine(i, &list_range);
-}
-
-EXPORT_SYMBOL(snd_interval_list);
-
-static int snd_interval_step(struct snd_interval *i, unsigned int min, unsigned int step)
-{
- unsigned int n;
- int changed = 0;
- n = (i->min - min) % step;
- if (n != 0 || i->openmin) {
- i->min += step - n;
- changed = 1;
- }
- n = (i->max - min) % step;
- if (n != 0 || i->openmax) {
- i->max -= n;
- changed = 1;
- }
- if (snd_interval_checkempty(i)) {
- i->empty = 1;
- return -EINVAL;
- }
- return changed;
-}
-
-/* Info constraints helpers */
-
-/**
- * snd_pcm_hw_rule_add - add the hw-constraint rule
- * @runtime: the pcm runtime instance
- * @cond: condition bits
- * @var: the variable to evaluate
- * @func: the evaluation function
- * @private: the private data pointer passed to function
- * @dep: the dependent variables
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
- int var,
- snd_pcm_hw_rule_func_t func, void *private,
- int dep, ...)
-{
- struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
- struct snd_pcm_hw_rule *c;
- unsigned int k;
- va_list args;
- va_start(args, dep);
- if (constrs->rules_num >= constrs->rules_all) {
- struct snd_pcm_hw_rule *new;
- unsigned int new_rules = constrs->rules_all + 16;
- new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL);
- if (!new) {
- va_end(args);
- return -ENOMEM;
- }
- if (constrs->rules) {
- memcpy(new, constrs->rules,
- constrs->rules_num * sizeof(*c));
- kfree(constrs->rules);
- }
- constrs->rules = new;
- constrs->rules_all = new_rules;
- }
- c = &constrs->rules[constrs->rules_num];
- c->cond = cond;
- c->func = func;
- c->var = var;
- c->private = private;
- k = 0;
- while (1) {
- if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps))) {
- va_end(args);
- return -EINVAL;
- }
- c->deps[k++] = dep;
- if (dep < 0)
- break;
- dep = va_arg(args, int);
- }
- constrs->rules_num++;
- va_end(args);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_pcm_hw_rule_add);
-
-/**
- * snd_pcm_hw_constraint_mask - apply the given bitmap mask constraint
- * @runtime: PCM runtime instance
- * @var: hw_params variable to apply the mask
- * @mask: the bitmap mask
- *
- * Apply the constraint of the given bitmap mask to a 32-bit mask parameter.
- */
-int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
- u_int32_t mask)
-{
- struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
- struct snd_mask *maskp = constrs_mask(constrs, var);
- *maskp->bits &= mask;
- memset(maskp->bits + 1, 0, (SNDRV_MASK_MAX-32) / 8); /* clear rest */
- if (*maskp->bits == 0)
- return -EINVAL;
- return 0;
-}
-
-/**
- * snd_pcm_hw_constraint_mask64 - apply the given bitmap mask constraint
- * @runtime: PCM runtime instance
- * @var: hw_params variable to apply the mask
- * @mask: the 64bit bitmap mask
- *
- * Apply the constraint of the given bitmap mask to a 64-bit mask parameter.
- */
-int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
- u_int64_t mask)
-{
- struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
- struct snd_mask *maskp = constrs_mask(constrs, var);
- maskp->bits[0] &= (u_int32_t)mask;
- maskp->bits[1] &= (u_int32_t)(mask >> 32);
- memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX-64) / 8); /* clear rest */
- if (! maskp->bits[0] && ! maskp->bits[1])
- return -EINVAL;
- return 0;
-}
-
-/**
- * snd_pcm_hw_constraint_integer - apply an integer constraint to an interval
- * @runtime: PCM runtime instance
- * @var: hw_params variable to apply the integer constraint
- *
- * Apply the constraint of integer to an interval parameter.
- */
-int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var)
-{
- struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
- return snd_interval_setinteger(constrs_interval(constrs, var));
-}
-
-EXPORT_SYMBOL(snd_pcm_hw_constraint_integer);
-
-/**
- * snd_pcm_hw_constraint_minmax - apply a min/max range constraint to an interval
- * @runtime: PCM runtime instance
- * @var: hw_params variable to apply the range
- * @min: the minimal value
- * @max: the maximal value
- *
- * Apply the min/max range constraint to an interval parameter.
- */
-int snd_pcm_hw_constraint_minmax(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
- unsigned int min, unsigned int max)
-{
- struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
- struct snd_interval t;
- t.min = min;
- t.max = max;
- t.openmin = t.openmax = 0;
- t.integer = 0;
- return snd_interval_refine(constrs_interval(constrs, var), &t);
-}
-
-EXPORT_SYMBOL(snd_pcm_hw_constraint_minmax);
-
-static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_pcm_hw_constraint_list *list = rule->private;
- return snd_interval_list(hw_param_interval(params, rule->var), list->count, list->list, list->mask);
-}
-
-
-/**
- * snd_pcm_hw_constraint_list - apply a list of constraints to a parameter
- * @runtime: PCM runtime instance
- * @cond: condition bits
- * @var: hw_params variable to apply the list constraint
- * @l: list
- *
- * Apply the list of constraints to an interval parameter.
- */
-int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime,
- unsigned int cond,
- snd_pcm_hw_param_t var,
- struct snd_pcm_hw_constraint_list *l)
-{
- return snd_pcm_hw_rule_add(runtime, cond, var,
- snd_pcm_hw_rule_list, l,
- var, -1);
-}
-
-EXPORT_SYMBOL(snd_pcm_hw_constraint_list);
-
-static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_pcm_hw_constraint_ratnums *r = rule->private;
- unsigned int num = 0, den = 0;
- int err;
- err = snd_interval_ratnum(hw_param_interval(params, rule->var),
- r->nrats, r->rats, &num, &den);
- if (err >= 0 && den && rule->var == SNDRV_PCM_HW_PARAM_RATE) {
- params->rate_num = num;
- params->rate_den = den;
- }
- return err;
-}
-
-/**
- * snd_pcm_hw_constraint_ratnums - apply ratnums constraint to a parameter
- * @runtime: PCM runtime instance
- * @cond: condition bits
- * @var: hw_params variable to apply the ratnums constraint
- * @r: struct snd_ratnums constriants
- */
-int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime,
- unsigned int cond,
- snd_pcm_hw_param_t var,
- struct snd_pcm_hw_constraint_ratnums *r)
-{
- return snd_pcm_hw_rule_add(runtime, cond, var,
- snd_pcm_hw_rule_ratnums, r,
- var, -1);
-}
-
-EXPORT_SYMBOL(snd_pcm_hw_constraint_ratnums);
-
-static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_pcm_hw_constraint_ratdens *r = rule->private;
- unsigned int num = 0, den = 0;
- int err = snd_interval_ratden(hw_param_interval(params, rule->var),
- r->nrats, r->rats, &num, &den);
- if (err >= 0 && den && rule->var == SNDRV_PCM_HW_PARAM_RATE) {
- params->rate_num = num;
- params->rate_den = den;
- }
- return err;
-}
-
-/**
- * snd_pcm_hw_constraint_ratdens - apply ratdens constraint to a parameter
- * @runtime: PCM runtime instance
- * @cond: condition bits
- * @var: hw_params variable to apply the ratdens constraint
- * @r: struct snd_ratdens constriants
- */
-int snd_pcm_hw_constraint_ratdens(struct snd_pcm_runtime *runtime,
- unsigned int cond,
- snd_pcm_hw_param_t var,
- struct snd_pcm_hw_constraint_ratdens *r)
-{
- return snd_pcm_hw_rule_add(runtime, cond, var,
- snd_pcm_hw_rule_ratdens, r,
- var, -1);
-}
-
-EXPORT_SYMBOL(snd_pcm_hw_constraint_ratdens);
-
-static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- unsigned int l = (unsigned long) rule->private;
- int width = l & 0xffff;
- unsigned int msbits = l >> 16;
- struct snd_interval *i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS);
- if (snd_interval_single(i) && snd_interval_value(i) == width)
- params->msbits = msbits;
- return 0;
-}
-
-/**
- * snd_pcm_hw_constraint_msbits - add a hw constraint msbits rule
- * @runtime: PCM runtime instance
- * @cond: condition bits
- * @width: sample bits width
- * @msbits: msbits width
- */
-int snd_pcm_hw_constraint_msbits(struct snd_pcm_runtime *runtime,
- unsigned int cond,
- unsigned int width,
- unsigned int msbits)
-{
- unsigned long l = (msbits << 16) | width;
- return snd_pcm_hw_rule_add(runtime, cond, -1,
- snd_pcm_hw_rule_msbits,
- (void*) l,
- SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1);
-}
-
-EXPORT_SYMBOL(snd_pcm_hw_constraint_msbits);
-
-static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- unsigned long step = (unsigned long) rule->private;
- return snd_interval_step(hw_param_interval(params, rule->var), 0, step);
-}
-
-/**
- * snd_pcm_hw_constraint_step - add a hw constraint step rule
- * @runtime: PCM runtime instance
- * @cond: condition bits
- * @var: hw_params variable to apply the step constraint
- * @step: step size
- */
-int snd_pcm_hw_constraint_step(struct snd_pcm_runtime *runtime,
- unsigned int cond,
- snd_pcm_hw_param_t var,
- unsigned long step)
-{
- return snd_pcm_hw_rule_add(runtime, cond, var,
- snd_pcm_hw_rule_step, (void *) step,
- var, -1);
-}
-
-EXPORT_SYMBOL(snd_pcm_hw_constraint_step);
-
-static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
-{
- static unsigned int pow2_sizes[] = {
- 1<<0, 1<<1, 1<<2, 1<<3, 1<<4, 1<<5, 1<<6, 1<<7,
- 1<<8, 1<<9, 1<<10, 1<<11, 1<<12, 1<<13, 1<<14, 1<<15,
- 1<<16, 1<<17, 1<<18, 1<<19, 1<<20, 1<<21, 1<<22, 1<<23,
- 1<<24, 1<<25, 1<<26, 1<<27, 1<<28, 1<<29, 1<<30
- };
- return snd_interval_list(hw_param_interval(params, rule->var),
- ARRAY_SIZE(pow2_sizes), pow2_sizes, 0);
-}
-
-/**
- * snd_pcm_hw_constraint_pow2 - add a hw constraint power-of-2 rule
- * @runtime: PCM runtime instance
- * @cond: condition bits
- * @var: hw_params variable to apply the power-of-2 constraint
- */
-int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime,
- unsigned int cond,
- snd_pcm_hw_param_t var)
-{
- return snd_pcm_hw_rule_add(runtime, cond, var,
- snd_pcm_hw_rule_pow2, NULL,
- var, -1);
-}
-
-EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2);
-
-static int snd_pcm_hw_rule_noresample_func(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- unsigned int base_rate = (unsigned int)(uintptr_t)rule->private;
- struct snd_interval *rate;
-
- rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
- return snd_interval_list(rate, 1, &base_rate, 0);
-}
-
-/**
- * snd_pcm_hw_rule_noresample - add a rule to allow disabling hw resampling
- * @runtime: PCM runtime instance
- * @base_rate: the rate at which the hardware does not resample
- */
-int snd_pcm_hw_rule_noresample(struct snd_pcm_runtime *runtime,
- unsigned int base_rate)
-{
- return snd_pcm_hw_rule_add(runtime, SNDRV_PCM_HW_PARAMS_NORESAMPLE,
- SNDRV_PCM_HW_PARAM_RATE,
- snd_pcm_hw_rule_noresample_func,
- (void *)(uintptr_t)base_rate,
- SNDRV_PCM_HW_PARAM_RATE, -1);
-}
-EXPORT_SYMBOL(snd_pcm_hw_rule_noresample);
-
-static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params,
- snd_pcm_hw_param_t var)
-{
- if (hw_is_mask(var)) {
- snd_mask_any(hw_param_mask(params, var));
- params->cmask |= 1 << var;
- params->rmask |= 1 << var;
- return;
- }
- if (hw_is_interval(var)) {
- snd_interval_any(hw_param_interval(params, var));
- params->cmask |= 1 << var;
- params->rmask |= 1 << var;
- return;
- }
- snd_BUG();
-}
-
-void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params)
-{
- unsigned int k;
- memset(params, 0, sizeof(*params));
- for (k = SNDRV_PCM_HW_PARAM_FIRST_MASK; k <= SNDRV_PCM_HW_PARAM_LAST_MASK; k++)
- _snd_pcm_hw_param_any(params, k);
- for (k = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++)
- _snd_pcm_hw_param_any(params, k);
- params->info = ~0U;
-}
-
-EXPORT_SYMBOL(_snd_pcm_hw_params_any);
-
-/**
- * snd_pcm_hw_param_value - return @params field @var value
- * @params: the hw_params instance
- * @var: parameter to retrieve
- * @dir: pointer to the direction (-1,0,1) or %NULL
- *
- * Return the value for field @var if it's fixed in configuration space
- * defined by @params. Return -%EINVAL otherwise.
- */
-int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params,
- snd_pcm_hw_param_t var, int *dir)
-{
- if (hw_is_mask(var)) {
- const struct snd_mask *mask = hw_param_mask_c(params, var);
- if (!snd_mask_single(mask))
- return -EINVAL;
- if (dir)
- *dir = 0;
- return snd_mask_value(mask);
- }
- if (hw_is_interval(var)) {
- const struct snd_interval *i = hw_param_interval_c(params, var);
- if (!snd_interval_single(i))
- return -EINVAL;
- if (dir)
- *dir = i->openmin;
- return snd_interval_value(i);
- }
- return -EINVAL;
-}
-
-EXPORT_SYMBOL(snd_pcm_hw_param_value);
-
-void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params,
- snd_pcm_hw_param_t var)
-{
- if (hw_is_mask(var)) {
- snd_mask_none(hw_param_mask(params, var));
- params->cmask |= 1 << var;
- params->rmask |= 1 << var;
- } else if (hw_is_interval(var)) {
- snd_interval_none(hw_param_interval(params, var));
- params->cmask |= 1 << var;
- params->rmask |= 1 << var;
- } else {
- snd_BUG();
- }
-}
-
-EXPORT_SYMBOL(_snd_pcm_hw_param_setempty);
-
-static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params,
- snd_pcm_hw_param_t var)
-{
- int changed;
- if (hw_is_mask(var))
- changed = snd_mask_refine_first(hw_param_mask(params, var));
- else if (hw_is_interval(var))
- changed = snd_interval_refine_first(hw_param_interval(params, var));
- else
- return -EINVAL;
- if (changed) {
- params->cmask |= 1 << var;
- params->rmask |= 1 << var;
- }
- return changed;
-}
-
-
-/**
- * snd_pcm_hw_param_first - refine config space and return minimum value
- * @pcm: PCM instance
- * @params: the hw_params instance
- * @var: parameter to retrieve
- * @dir: pointer to the direction (-1,0,1) or %NULL
- *
- * Inside configuration space defined by @params remove from @var all
- * values > minimum. Reduce configuration space accordingly.
- * Return the minimum.
- */
-int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm,
- struct snd_pcm_hw_params *params,
- snd_pcm_hw_param_t var, int *dir)
-{
- int changed = _snd_pcm_hw_param_first(params, var);
- if (changed < 0)
- return changed;
- if (params->rmask) {
- int err = snd_pcm_hw_refine(pcm, params);
- if (snd_BUG_ON(err < 0))
- return err;
- }
- return snd_pcm_hw_param_value(params, var, dir);
-}
-
-EXPORT_SYMBOL(snd_pcm_hw_param_first);
-
-static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params,
- snd_pcm_hw_param_t var)
-{
- int changed;
- if (hw_is_mask(var))
- changed = snd_mask_refine_last(hw_param_mask(params, var));
- else if (hw_is_interval(var))
- changed = snd_interval_refine_last(hw_param_interval(params, var));
- else
- return -EINVAL;
- if (changed) {
- params->cmask |= 1 << var;
- params->rmask |= 1 << var;
- }
- return changed;
-}
-
-
-/**
- * snd_pcm_hw_param_last - refine config space and return maximum value
- * @pcm: PCM instance
- * @params: the hw_params instance
- * @var: parameter to retrieve
- * @dir: pointer to the direction (-1,0,1) or %NULL
- *
- * Inside configuration space defined by @params remove from @var all
- * values < maximum. Reduce configuration space accordingly.
- * Return the maximum.
- */
-int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm,
- struct snd_pcm_hw_params *params,
- snd_pcm_hw_param_t var, int *dir)
-{
- int changed = _snd_pcm_hw_param_last(params, var);
- if (changed < 0)
- return changed;
- if (params->rmask) {
- int err = snd_pcm_hw_refine(pcm, params);
- if (snd_BUG_ON(err < 0))
- return err;
- }
- return snd_pcm_hw_param_value(params, var, dir);
-}
-
-EXPORT_SYMBOL(snd_pcm_hw_param_last);
-
-/**
- * snd_pcm_hw_param_choose - choose a configuration defined by @params
- * @pcm: PCM instance
- * @params: the hw_params instance
- *
- * Choose one configuration from configuration space defined by @params.
- * The configuration chosen is that obtained fixing in this order:
- * first access, first format, first subformat, min channels,
- * min rate, min period time, max buffer size, min tick time
- */
-int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm,
- struct snd_pcm_hw_params *params)
-{
- static int vars[] = {
- SNDRV_PCM_HW_PARAM_ACCESS,
- SNDRV_PCM_HW_PARAM_FORMAT,
- SNDRV_PCM_HW_PARAM_SUBFORMAT,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- SNDRV_PCM_HW_PARAM_RATE,
- SNDRV_PCM_HW_PARAM_PERIOD_TIME,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- SNDRV_PCM_HW_PARAM_TICK_TIME,
- -1
- };
- int err, *v;
-
- for (v = vars; *v != -1; v++) {
- if (*v != SNDRV_PCM_HW_PARAM_BUFFER_SIZE)
- err = snd_pcm_hw_param_first(pcm, params, *v, NULL);
- else
- err = snd_pcm_hw_param_last(pcm, params, *v, NULL);
- if (snd_BUG_ON(err < 0))
- return err;
- }
- return 0;
-}
-
-static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream,
- void *arg)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long flags;
- snd_pcm_stream_lock_irqsave(substream, flags);
- if (snd_pcm_running(substream) &&
- snd_pcm_update_hw_ptr(substream) >= 0)
- runtime->status->hw_ptr %= runtime->buffer_size;
- else
- runtime->status->hw_ptr = 0;
- snd_pcm_stream_unlock_irqrestore(substream, flags);
- return 0;
-}
-
-static int snd_pcm_lib_ioctl_channel_info(struct snd_pcm_substream *substream,
- void *arg)
-{
- struct snd_pcm_channel_info *info = arg;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int width;
- if (!(runtime->info & SNDRV_PCM_INFO_MMAP)) {
- info->offset = -1;
- return 0;
- }
- width = snd_pcm_format_physical_width(runtime->format);
- if (width < 0)
- return width;
- info->offset = 0;
- switch (runtime->access) {
- case SNDRV_PCM_ACCESS_MMAP_INTERLEAVED:
- case SNDRV_PCM_ACCESS_RW_INTERLEAVED:
- info->first = info->channel * width;
- info->step = runtime->channels * width;
- break;
- case SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED:
- case SNDRV_PCM_ACCESS_RW_NONINTERLEAVED:
- {
- size_t size = runtime->dma_bytes / runtime->channels;
- info->first = info->channel * size * 8;
- info->step = width;
- break;
- }
- default:
- snd_BUG();
- break;
- }
- return 0;
-}
-
-static int snd_pcm_lib_ioctl_fifo_size(struct snd_pcm_substream *substream,
- void *arg)
-{
- struct snd_pcm_hw_params *params = arg;
- snd_pcm_format_t format;
- int channels, width;
-
- params->fifo_size = substream->runtime->hw.fifo_size;
- if (!(substream->runtime->hw.info & SNDRV_PCM_INFO_FIFO_IN_FRAMES)) {
- format = params_format(params);
- channels = params_channels(params);
- width = snd_pcm_format_physical_width(format);
- params->fifo_size /= width * channels;
- }
- return 0;
-}
-
-/**
- * snd_pcm_lib_ioctl - a generic PCM ioctl callback
- * @substream: the pcm substream instance
- * @cmd: ioctl command
- * @arg: ioctl argument
- *
- * Processes the generic ioctl commands for PCM.
- * Can be passed as the ioctl callback for PCM ops.
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
- unsigned int cmd, void *arg)
-{
- switch (cmd) {
- case SNDRV_PCM_IOCTL1_INFO:
- return 0;
- case SNDRV_PCM_IOCTL1_RESET:
- return snd_pcm_lib_ioctl_reset(substream, arg);
- case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
- return snd_pcm_lib_ioctl_channel_info(substream, arg);
- case SNDRV_PCM_IOCTL1_FIFO_SIZE:
- return snd_pcm_lib_ioctl_fifo_size(substream, arg);
- }
- return -ENXIO;
-}
-
-EXPORT_SYMBOL(snd_pcm_lib_ioctl);
-
-/**
- * snd_pcm_period_elapsed - update the pcm status for the next period
- * @substream: the pcm substream instance
- *
- * This function is called from the interrupt handler when the
- * PCM has processed the period size. It will update the current
- * pointer, wake up sleepers, etc.
- *
- * Even if more than one periods have elapsed since the last call, you
- * have to call this only once.
- */
-void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime;
- unsigned long flags;
-
- if (PCM_RUNTIME_CHECK(substream))
- return;
- runtime = substream->runtime;
-
- if (runtime->transfer_ack_begin)
- runtime->transfer_ack_begin(substream);
-
- snd_pcm_stream_lock_irqsave(substream, flags);
- if (!snd_pcm_running(substream) ||
- snd_pcm_update_hw_ptr0(substream, 1) < 0)
- goto _end;
-
- if (substream->timer_running)
- snd_timer_interrupt(substream->timer, 1);
- _end:
- snd_pcm_stream_unlock_irqrestore(substream, flags);
- if (runtime->transfer_ack_end)
- runtime->transfer_ack_end(substream);
- kill_fasync(&runtime->fasync, SIGIO, POLL_IN);
-}
-
-EXPORT_SYMBOL(snd_pcm_period_elapsed);
-
-/*
- * Wait until avail_min data becomes available
- * Returns a negative error code if any error occurs during operation.
- * The available space is stored on availp. When err = 0 and avail = 0
- * on the capture stream, it indicates the stream is in DRAINING state.
- */
-static int wait_for_avail(struct snd_pcm_substream *substream,
- snd_pcm_uframes_t *availp)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int is_playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
- wait_queue_t wait;
- int err = 0;
- snd_pcm_uframes_t avail = 0;
- long wait_time, tout;
-
- init_waitqueue_entry(&wait, current);
- set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(&runtime->tsleep, &wait);
-
- if (runtime->no_period_wakeup)
- wait_time = MAX_SCHEDULE_TIMEOUT;
- else {
- wait_time = 10;
- if (runtime->rate) {
- long t = runtime->period_size * 2 / runtime->rate;
- wait_time = max(t, wait_time);
- }
- wait_time = msecs_to_jiffies(wait_time * 1000);
- }
-
- for (;;) {
- if (signal_pending(current)) {
- err = -ERESTARTSYS;
- break;
- }
-
- /*
- * We need to check if space became available already
- * (and thus the wakeup happened already) first to close
- * the race of space already having become available.
- * This check must happen after been added to the waitqueue
- * and having current state be INTERRUPTIBLE.
- */
- if (is_playback)
- avail = snd_pcm_playback_avail(runtime);
- else
- avail = snd_pcm_capture_avail(runtime);
- if (avail >= runtime->twake)
- break;
- snd_pcm_stream_unlock_irq(substream);
-
- tout = schedule_timeout(wait_time);
-
- snd_pcm_stream_lock_irq(substream);
- set_current_state(TASK_INTERRUPTIBLE);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_SUSPENDED:
- err = -ESTRPIPE;
- goto _endloop;
- case SNDRV_PCM_STATE_XRUN:
- err = -EPIPE;
- goto _endloop;
- case SNDRV_PCM_STATE_DRAINING:
- if (is_playback)
- err = -EPIPE;
- else
- avail = 0; /* indicate draining */
- goto _endloop;
- case SNDRV_PCM_STATE_OPEN:
- case SNDRV_PCM_STATE_SETUP:
- case SNDRV_PCM_STATE_DISCONNECTED:
- err = -EBADFD;
- goto _endloop;
- }
- if (!tout) {
- snd_printd("%s write error (DMA or IRQ trouble?)\n",
- is_playback ? "playback" : "capture");
- err = -EIO;
- break;
- }
- }
- _endloop:
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&runtime->tsleep, &wait);
- *availp = avail;
- return err;
-}
-
-static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream,
- unsigned int hwoff,
- unsigned long data, unsigned int off,
- snd_pcm_uframes_t frames)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
- char __user *buf = (char __user *) data + frames_to_bytes(runtime, off);
- if (substream->ops->copy) {
- if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0)
- return err;
- } else {
- char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff);
- if (copy_from_user(hwbuf, buf, frames_to_bytes(runtime, frames)))
- return -EFAULT;
- }
- return 0;
-}
-
-typedef int (*transfer_f)(struct snd_pcm_substream *substream, unsigned int hwoff,
- unsigned long data, unsigned int off,
- snd_pcm_uframes_t size);
-
-static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
- unsigned long data,
- snd_pcm_uframes_t size,
- int nonblock,
- transfer_f transfer)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_uframes_t xfer = 0;
- snd_pcm_uframes_t offset = 0;
- int err = 0;
-
- if (size == 0)
- return 0;
-
- snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_PREPARED:
- case SNDRV_PCM_STATE_RUNNING:
- case SNDRV_PCM_STATE_PAUSED:
- break;
- case SNDRV_PCM_STATE_XRUN:
- err = -EPIPE;
- goto _end_unlock;
- case SNDRV_PCM_STATE_SUSPENDED:
- err = -ESTRPIPE;
- goto _end_unlock;
- default:
- err = -EBADFD;
- goto _end_unlock;
- }
-
- runtime->twake = runtime->control->avail_min ? : 1;
- while (size > 0) {
- snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
- snd_pcm_uframes_t avail;
- snd_pcm_uframes_t cont;
- if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
- snd_pcm_update_hw_ptr(substream);
- avail = snd_pcm_playback_avail(runtime);
- if (!avail) {
- if (nonblock) {
- err = -EAGAIN;
- goto _end_unlock;
- }
- runtime->twake = min_t(snd_pcm_uframes_t, size,
- runtime->control->avail_min ? : 1);
- err = wait_for_avail(substream, &avail);
- if (err < 0)
- goto _end_unlock;
- }
- frames = size > avail ? avail : size;
- cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size;
- if (frames > cont)
- frames = cont;
- if (snd_BUG_ON(!frames)) {
- runtime->twake = 0;
- snd_pcm_stream_unlock_irq(substream);
- return -EINVAL;
- }
- appl_ptr = runtime->control->appl_ptr;
- appl_ofs = appl_ptr % runtime->buffer_size;
- snd_pcm_stream_unlock_irq(substream);
- err = transfer(substream, appl_ofs, data, offset, frames);
- snd_pcm_stream_lock_irq(substream);
- if (err < 0)
- goto _end_unlock;
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_XRUN:
- err = -EPIPE;
- goto _end_unlock;
- case SNDRV_PCM_STATE_SUSPENDED:
- err = -ESTRPIPE;
- goto _end_unlock;
- default:
- break;
- }
- appl_ptr += frames;
- if (appl_ptr >= runtime->boundary)
- appl_ptr -= runtime->boundary;
- runtime->control->appl_ptr = appl_ptr;
- if (substream->ops->ack)
- substream->ops->ack(substream);
-
- offset += frames;
- size -= frames;
- xfer += frames;
- if (runtime->status->state == SNDRV_PCM_STATE_PREPARED &&
- snd_pcm_playback_hw_avail(runtime) >= (snd_pcm_sframes_t)runtime->start_threshold) {
- err = snd_pcm_start(substream);
- if (err < 0)
- goto _end_unlock;
- }
- }
- _end_unlock:
- runtime->twake = 0;
- if (xfer > 0 && err >= 0)
- snd_pcm_update_state(substream, runtime);
- snd_pcm_stream_unlock_irq(substream);
- return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
-}
-
-/* sanity-check for read/write methods */
-static int pcm_sanity_check(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime;
- if (PCM_RUNTIME_CHECK(substream))
- return -ENXIO;
- runtime = substream->runtime;
- if (snd_BUG_ON(!substream->ops->copy && !runtime->dma_area))
- return -EINVAL;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
- return -EBADFD;
- return 0;
-}
-
-snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const void __user *buf, snd_pcm_uframes_t size)
-{
- struct snd_pcm_runtime *runtime;
- int nonblock;
- int err;
-
- err = pcm_sanity_check(substream);
- if (err < 0)
- return err;
- runtime = substream->runtime;
- nonblock = !!(substream->f_flags & O_NONBLOCK);
-
- if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED &&
- runtime->channels > 1)
- return -EINVAL;
- return snd_pcm_lib_write1(substream, (unsigned long)buf, size, nonblock,
- snd_pcm_lib_write_transfer);
-}
-
-EXPORT_SYMBOL(snd_pcm_lib_write);
-
-static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream,
- unsigned int hwoff,
- unsigned long data, unsigned int off,
- snd_pcm_uframes_t frames)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
- void __user **bufs = (void __user **)data;
- int channels = runtime->channels;
- int c;
- if (substream->ops->copy) {
- if (snd_BUG_ON(!substream->ops->silence))
- return -EINVAL;
- for (c = 0; c < channels; ++c, ++bufs) {
- if (*bufs == NULL) {
- if ((err = substream->ops->silence(substream, c, hwoff, frames)) < 0)
- return err;
- } else {
- char __user *buf = *bufs + samples_to_bytes(runtime, off);
- if ((err = substream->ops->copy(substream, c, hwoff, buf, frames)) < 0)
- return err;
- }
- }
- } else {
- /* default transfer behaviour */
- size_t dma_csize = runtime->dma_bytes / channels;
- for (c = 0; c < channels; ++c, ++bufs) {
- char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff);
- if (*bufs == NULL) {
- snd_pcm_format_set_silence(runtime->format, hwbuf, frames);
- } else {
- char __user *buf = *bufs + samples_to_bytes(runtime, off);
- if (copy_from_user(hwbuf, buf, samples_to_bytes(runtime, frames)))
- return -EFAULT;
- }
- }
- }
- return 0;
-}
-
-snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream,
- void __user **bufs,
- snd_pcm_uframes_t frames)
-{
- struct snd_pcm_runtime *runtime;
- int nonblock;
- int err;
-
- err = pcm_sanity_check(substream);
- if (err < 0)
- return err;
- runtime = substream->runtime;
- nonblock = !!(substream->f_flags & O_NONBLOCK);
-
- if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
- return -EINVAL;
- return snd_pcm_lib_write1(substream, (unsigned long)bufs, frames,
- nonblock, snd_pcm_lib_writev_transfer);
-}
-
-EXPORT_SYMBOL(snd_pcm_lib_writev);
-
-static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream,
- unsigned int hwoff,
- unsigned long data, unsigned int off,
- snd_pcm_uframes_t frames)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
- char __user *buf = (char __user *) data + frames_to_bytes(runtime, off);
- if (substream->ops->copy) {
- if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0)
- return err;
- } else {
- char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff);
- if (copy_to_user(buf, hwbuf, frames_to_bytes(runtime, frames)))
- return -EFAULT;
- }
- return 0;
-}
-
-static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
- unsigned long data,
- snd_pcm_uframes_t size,
- int nonblock,
- transfer_f transfer)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_uframes_t xfer = 0;
- snd_pcm_uframes_t offset = 0;
- int err = 0;
-
- if (size == 0)
- return 0;
-
- snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_PREPARED:
- if (size >= runtime->start_threshold) {
- err = snd_pcm_start(substream);
- if (err < 0)
- goto _end_unlock;
- }
- break;
- case SNDRV_PCM_STATE_DRAINING:
- case SNDRV_PCM_STATE_RUNNING:
- case SNDRV_PCM_STATE_PAUSED:
- break;
- case SNDRV_PCM_STATE_XRUN:
- err = -EPIPE;
- goto _end_unlock;
- case SNDRV_PCM_STATE_SUSPENDED:
- err = -ESTRPIPE;
- goto _end_unlock;
- default:
- err = -EBADFD;
- goto _end_unlock;
- }
-
- runtime->twake = runtime->control->avail_min ? : 1;
- while (size > 0) {
- snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
- snd_pcm_uframes_t avail;
- snd_pcm_uframes_t cont;
- if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
- snd_pcm_update_hw_ptr(substream);
- avail = snd_pcm_capture_avail(runtime);
- if (!avail) {
- if (runtime->status->state ==
- SNDRV_PCM_STATE_DRAINING) {
- snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
- goto _end_unlock;
- }
- if (nonblock) {
- err = -EAGAIN;
- goto _end_unlock;
- }
- runtime->twake = min_t(snd_pcm_uframes_t, size,
- runtime->control->avail_min ? : 1);
- err = wait_for_avail(substream, &avail);
- if (err < 0)
- goto _end_unlock;
- if (!avail)
- continue; /* draining */
- }
- frames = size > avail ? avail : size;
- cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size;
- if (frames > cont)
- frames = cont;
- if (snd_BUG_ON(!frames)) {
- runtime->twake = 0;
- snd_pcm_stream_unlock_irq(substream);
- return -EINVAL;
- }
- appl_ptr = runtime->control->appl_ptr;
- appl_ofs = appl_ptr % runtime->buffer_size;
- snd_pcm_stream_unlock_irq(substream);
- err = transfer(substream, appl_ofs, data, offset, frames);
- snd_pcm_stream_lock_irq(substream);
- if (err < 0)
- goto _end_unlock;
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_XRUN:
- err = -EPIPE;
- goto _end_unlock;
- case SNDRV_PCM_STATE_SUSPENDED:
- err = -ESTRPIPE;
- goto _end_unlock;
- default:
- break;
- }
- appl_ptr += frames;
- if (appl_ptr >= runtime->boundary)
- appl_ptr -= runtime->boundary;
- runtime->control->appl_ptr = appl_ptr;
- if (substream->ops->ack)
- substream->ops->ack(substream);
-
- offset += frames;
- size -= frames;
- xfer += frames;
- }
- _end_unlock:
- runtime->twake = 0;
- if (xfer > 0 && err >= 0)
- snd_pcm_update_state(substream, runtime);
- snd_pcm_stream_unlock_irq(substream);
- return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
-}
-
-snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __user *buf, snd_pcm_uframes_t size)
-{
- struct snd_pcm_runtime *runtime;
- int nonblock;
- int err;
-
- err = pcm_sanity_check(substream);
- if (err < 0)
- return err;
- runtime = substream->runtime;
- nonblock = !!(substream->f_flags & O_NONBLOCK);
- if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED)
- return -EINVAL;
- return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer);
-}
-
-EXPORT_SYMBOL(snd_pcm_lib_read);
-
-static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream,
- unsigned int hwoff,
- unsigned long data, unsigned int off,
- snd_pcm_uframes_t frames)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
- void __user **bufs = (void __user **)data;
- int channels = runtime->channels;
- int c;
- if (substream->ops->copy) {
- for (c = 0; c < channels; ++c, ++bufs) {
- char __user *buf;
- if (*bufs == NULL)
- continue;
- buf = *bufs + samples_to_bytes(runtime, off);
- if ((err = substream->ops->copy(substream, c, hwoff, buf, frames)) < 0)
- return err;
- }
- } else {
- snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels;
- for (c = 0; c < channels; ++c, ++bufs) {
- char *hwbuf;
- char __user *buf;
- if (*bufs == NULL)
- continue;
-
- hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff);
- buf = *bufs + samples_to_bytes(runtime, off);
- if (copy_to_user(buf, hwbuf, samples_to_bytes(runtime, frames)))
- return -EFAULT;
- }
- }
- return 0;
-}
-
-snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream,
- void __user **bufs,
- snd_pcm_uframes_t frames)
-{
- struct snd_pcm_runtime *runtime;
- int nonblock;
- int err;
-
- err = pcm_sanity_check(substream);
- if (err < 0)
- return err;
- runtime = substream->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
- return -EBADFD;
-
- nonblock = !!(substream->f_flags & O_NONBLOCK);
- if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
- return -EINVAL;
- return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer);
-}
-
-EXPORT_SYMBOL(snd_pcm_lib_readv);
diff --git a/ANDROID_3.4.5/sound/core/pcm_memory.c b/ANDROID_3.4.5/sound/core/pcm_memory.c
deleted file mode 100644
index 95713136..00000000
--- a/ANDROID_3.4.5/sound/core/pcm_memory.c
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- * Digital Audio (PCM) abstract layer
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/time.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/moduleparam.h>
-#include <linux/vmalloc.h>
-#include <linux/export.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/info.h>
-#include <sound/initval.h>
-
-static int preallocate_dma = 1;
-module_param(preallocate_dma, int, 0444);
-MODULE_PARM_DESC(preallocate_dma, "Preallocate DMA memory when the PCM devices are initialized.");
-
-static int maximum_substreams = 4;
-module_param(maximum_substreams, int, 0444);
-MODULE_PARM_DESC(maximum_substreams, "Maximum substreams with preallocated DMA memory.");
-
-static const size_t snd_minimum_buffer = 16384;
-
-
-/*
- * try to allocate as the large pages as possible.
- * stores the resultant memory size in *res_size.
- *
- * the minimum size is snd_minimum_buffer. it should be power of 2.
- */
-static int preallocate_pcm_pages(struct snd_pcm_substream *substream, size_t size)
-{
- struct snd_dma_buffer *dmab = &substream->dma_buffer;
- int err;
-
- /* already reserved? */
- if (snd_dma_get_reserved_buf(dmab, substream->dma_buf_id) > 0) {
- if (dmab->bytes >= size)
- return 0; /* yes */
- /* no, free the reserved block */
- snd_dma_free_pages(dmab);
- dmab->bytes = 0;
- }
-
- do {
- if ((err = snd_dma_alloc_pages(dmab->dev.type, dmab->dev.dev,
- size, dmab)) < 0) {
- if (err != -ENOMEM)
- return err; /* fatal error */
- } else
- return 0;
- size >>= 1;
- } while (size >= snd_minimum_buffer);
- dmab->bytes = 0; /* tell error */
- return 0;
-}
-
-/*
- * release the preallocated buffer if not yet done.
- */
-static void snd_pcm_lib_preallocate_dma_free(struct snd_pcm_substream *substream)
-{
- if (substream->dma_buffer.area == NULL)
- return;
- if (substream->dma_buf_id)
- snd_dma_reserve_buf(&substream->dma_buffer, substream->dma_buf_id);
- else
- snd_dma_free_pages(&substream->dma_buffer);
- substream->dma_buffer.area = NULL;
-}
-
-/**
- * snd_pcm_lib_preallocate_free - release the preallocated buffer of the specified substream.
- * @substream: the pcm substream instance
- *
- * Releases the pre-allocated buffer of the given substream.
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_pcm_lib_preallocate_free(struct snd_pcm_substream *substream)
-{
- snd_pcm_lib_preallocate_dma_free(substream);
-#ifdef CONFIG_SND_VERBOSE_PROCFS
- snd_info_free_entry(substream->proc_prealloc_max_entry);
- substream->proc_prealloc_max_entry = NULL;
- snd_info_free_entry(substream->proc_prealloc_entry);
- substream->proc_prealloc_entry = NULL;
-#endif
- return 0;
-}
-
-/**
- * snd_pcm_lib_preallocate_free_for_all - release all pre-allocated buffers on the pcm
- * @pcm: the pcm instance
- *
- * Releases all the pre-allocated buffers on the given pcm.
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- int stream;
-
- for (stream = 0; stream < 2; stream++)
- for (substream = pcm->streams[stream].substream; substream; substream = substream->next)
- snd_pcm_lib_preallocate_free(substream);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all);
-
-#ifdef CONFIG_SND_VERBOSE_PROCFS
-/*
- * read callback for prealloc proc file
- *
- * prints the current allocated size in kB.
- */
-static void snd_pcm_lib_preallocate_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_pcm_substream *substream = entry->private_data;
- snd_iprintf(buffer, "%lu\n", (unsigned long) substream->dma_buffer.bytes / 1024);
-}
-
-/*
- * read callback for prealloc_max proc file
- *
- * prints the maximum allowed size in kB.
- */
-static void snd_pcm_lib_preallocate_max_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_pcm_substream *substream = entry->private_data;
- snd_iprintf(buffer, "%lu\n", (unsigned long) substream->dma_max / 1024);
-}
-
-/*
- * write callback for prealloc proc file
- *
- * accepts the preallocation size in kB.
- */
-static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_pcm_substream *substream = entry->private_data;
- char line[64], str[64];
- size_t size;
- struct snd_dma_buffer new_dmab;
-
- if (substream->runtime) {
- buffer->error = -EBUSY;
- return;
- }
- if (!snd_info_get_line(buffer, line, sizeof(line))) {
- snd_info_get_str(str, line, sizeof(str));
- size = simple_strtoul(str, NULL, 10) * 1024;
- if ((size != 0 && size < 8192) || size > substream->dma_max) {
- buffer->error = -EINVAL;
- return;
- }
- if (substream->dma_buffer.bytes == size)
- return;
- memset(&new_dmab, 0, sizeof(new_dmab));
- new_dmab.dev = substream->dma_buffer.dev;
- if (size > 0) {
- if (snd_dma_alloc_pages(substream->dma_buffer.dev.type,
- substream->dma_buffer.dev.dev,
- size, &new_dmab) < 0) {
- buffer->error = -ENOMEM;
- return;
- }
- substream->buffer_bytes_max = size;
- } else {
- substream->buffer_bytes_max = UINT_MAX;
- }
- if (substream->dma_buffer.area)
- snd_dma_free_pages(&substream->dma_buffer);
- substream->dma_buffer = new_dmab;
- } else {
- buffer->error = -EINVAL;
- }
-}
-
-static inline void preallocate_info_init(struct snd_pcm_substream *substream)
-{
- struct snd_info_entry *entry;
-
- if ((entry = snd_info_create_card_entry(substream->pcm->card, "prealloc", substream->proc_root)) != NULL) {
- entry->c.text.read = snd_pcm_lib_preallocate_proc_read;
- entry->c.text.write = snd_pcm_lib_preallocate_proc_write;
- entry->mode |= S_IWUSR;
- entry->private_data = substream;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- substream->proc_prealloc_entry = entry;
- if ((entry = snd_info_create_card_entry(substream->pcm->card, "prealloc_max", substream->proc_root)) != NULL) {
- entry->c.text.read = snd_pcm_lib_preallocate_max_proc_read;
- entry->private_data = substream;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- substream->proc_prealloc_max_entry = entry;
-}
-
-#else /* !CONFIG_SND_VERBOSE_PROCFS */
-#define preallocate_info_init(s)
-#endif /* CONFIG_SND_VERBOSE_PROCFS */
-
-/*
- * pre-allocate the buffer and create a proc file for the substream
- */
-static int snd_pcm_lib_preallocate_pages1(struct snd_pcm_substream *substream,
- size_t size, size_t max)
-{
-
- if (size > 0 && preallocate_dma && substream->number < maximum_substreams)
- preallocate_pcm_pages(substream, size);
-
- if (substream->dma_buffer.bytes > 0)
- substream->buffer_bytes_max = substream->dma_buffer.bytes;
- substream->dma_max = max;
- preallocate_info_init(substream);
- return 0;
-}
-
-
-/**
- * snd_pcm_lib_preallocate_pages - pre-allocation for the given DMA type
- * @substream: the pcm substream instance
- * @type: DMA type (SNDRV_DMA_TYPE_*)
- * @data: DMA type dependent data
- * @size: the requested pre-allocation size in bytes
- * @max: the max. allowed pre-allocation size
- *
- * Do pre-allocation for the given DMA buffer type.
- *
- * When substream->dma_buf_id is set, the function tries to look for
- * the reserved buffer, and the buffer is not freed but reserved at
- * destruction time. The dma_buf_id must be unique for all systems
- * (in the same DMA buffer type) e.g. using snd_dma_pci_buf_id().
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_pcm_lib_preallocate_pages(struct snd_pcm_substream *substream,
- int type, struct device *data,
- size_t size, size_t max)
-{
- substream->dma_buffer.dev.type = type;
- substream->dma_buffer.dev.dev = data;
- return snd_pcm_lib_preallocate_pages1(substream, size, max);
-}
-
-EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages);
-
-/**
- * snd_pcm_lib_preallocate_pages_for_all - pre-allocation for continuous memory type (all substreams)
- * @pcm: the pcm instance
- * @type: DMA type (SNDRV_DMA_TYPE_*)
- * @data: DMA type dependent data
- * @size: the requested pre-allocation size in bytes
- * @max: the max. allowed pre-allocation size
- *
- * Do pre-allocation to all substreams of the given pcm for the
- * specified DMA type.
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm,
- int type, void *data,
- size_t size, size_t max)
-{
- struct snd_pcm_substream *substream;
- int stream, err;
-
- for (stream = 0; stream < 2; stream++)
- for (substream = pcm->streams[stream].substream; substream; substream = substream->next)
- if ((err = snd_pcm_lib_preallocate_pages(substream, type, data, size, max)) < 0)
- return err;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all);
-
-#ifdef CONFIG_SND_DMA_SGBUF
-/**
- * snd_pcm_sgbuf_ops_page - get the page struct at the given offset
- * @substream: the pcm substream instance
- * @offset: the buffer offset
- *
- * Returns the page struct at the given buffer offset.
- * Used as the page callback of PCM ops.
- */
-struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigned long offset)
-{
- struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
-
- unsigned int idx = offset >> PAGE_SHIFT;
- if (idx >= (unsigned int)sgbuf->pages)
- return NULL;
- return sgbuf->page_table[idx];
-}
-
-EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page);
-
-/*
- * compute the max chunk size with continuous pages on sg-buffer
- */
-unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
- unsigned int ofs, unsigned int size)
-{
- struct snd_sg_buf *sg = snd_pcm_substream_sgbuf(substream);
- unsigned int start, end, pg;
-
- start = ofs >> PAGE_SHIFT;
- end = (ofs + size - 1) >> PAGE_SHIFT;
- /* check page continuity */
- pg = sg->table[start].addr >> PAGE_SHIFT;
- for (;;) {
- start++;
- if (start > end)
- break;
- pg++;
- if ((sg->table[start].addr >> PAGE_SHIFT) != pg)
- return (start << PAGE_SHIFT) - ofs;
- }
- /* ok, all on continuous pages */
- return size;
-}
-EXPORT_SYMBOL(snd_pcm_sgbuf_get_chunk_size);
-#endif /* CONFIG_SND_DMA_SGBUF */
-
-/**
- * snd_pcm_lib_malloc_pages - allocate the DMA buffer
- * @substream: the substream to allocate the DMA buffer to
- * @size: the requested buffer size in bytes
- *
- * Allocates the DMA buffer on the BUS type given earlier to
- * snd_pcm_lib_preallocate_xxx_pages().
- *
- * Returns 1 if the buffer is changed, 0 if not changed, or a negative
- * code on failure.
- */
-int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size)
-{
- struct snd_pcm_runtime *runtime;
- struct snd_dma_buffer *dmab = NULL;
-
- if (PCM_RUNTIME_CHECK(substream))
- return -EINVAL;
- if (snd_BUG_ON(substream->dma_buffer.dev.type ==
- SNDRV_DMA_TYPE_UNKNOWN))
- return -EINVAL;
- runtime = substream->runtime;
-
- if (runtime->dma_buffer_p) {
- /* perphaps, we might free the large DMA memory region
- to save some space here, but the actual solution
- costs us less time */
- if (runtime->dma_buffer_p->bytes >= size) {
- runtime->dma_bytes = size;
- return 0; /* ok, do not change */
- }
- snd_pcm_lib_free_pages(substream);
- }
- if (substream->dma_buffer.area != NULL &&
- substream->dma_buffer.bytes >= size) {
- dmab = &substream->dma_buffer; /* use the pre-allocated buffer */
- } else {
- dmab = kzalloc(sizeof(*dmab), GFP_KERNEL);
- if (! dmab)
- return -ENOMEM;
- dmab->dev = substream->dma_buffer.dev;
- if (snd_dma_alloc_pages(substream->dma_buffer.dev.type,
- substream->dma_buffer.dev.dev,
- size, dmab) < 0) {
- kfree(dmab);
- return -ENOMEM;
- }
- }
- snd_pcm_set_runtime_buffer(substream, dmab);
- runtime->dma_bytes = size;
- return 1; /* area was changed */
-}
-
-EXPORT_SYMBOL(snd_pcm_lib_malloc_pages);
-
-/**
- * snd_pcm_lib_free_pages - release the allocated DMA buffer.
- * @substream: the substream to release the DMA buffer
- *
- * Releases the DMA buffer allocated via snd_pcm_lib_malloc_pages().
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime;
-
- if (PCM_RUNTIME_CHECK(substream))
- return -EINVAL;
- runtime = substream->runtime;
- if (runtime->dma_area == NULL)
- return 0;
- if (runtime->dma_buffer_p != &substream->dma_buffer) {
- /* it's a newly allocated buffer. release it now. */
- snd_dma_free_pages(runtime->dma_buffer_p);
- kfree(runtime->dma_buffer_p);
- }
- snd_pcm_set_runtime_buffer(substream, NULL);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_pcm_lib_free_pages);
-
-int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream,
- size_t size, gfp_t gfp_flags)
-{
- struct snd_pcm_runtime *runtime;
-
- if (PCM_RUNTIME_CHECK(substream))
- return -EINVAL;
- runtime = substream->runtime;
- if (runtime->dma_area) {
- if (runtime->dma_bytes >= size)
- return 0; /* already large enough */
- vfree(runtime->dma_area);
- }
- runtime->dma_area = __vmalloc(size, gfp_flags, PAGE_KERNEL);
- if (!runtime->dma_area)
- return -ENOMEM;
- runtime->dma_bytes = size;
- return 1;
-}
-EXPORT_SYMBOL(_snd_pcm_lib_alloc_vmalloc_buffer);
-
-/**
- * snd_pcm_lib_free_vmalloc_buffer - free vmalloc buffer
- * @substream: the substream with a buffer allocated by
- * snd_pcm_lib_alloc_vmalloc_buffer()
- */
-int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime;
-
- if (PCM_RUNTIME_CHECK(substream))
- return -EINVAL;
- runtime = substream->runtime;
- vfree(runtime->dma_area);
- runtime->dma_area = NULL;
- return 0;
-}
-EXPORT_SYMBOL(snd_pcm_lib_free_vmalloc_buffer);
-
-/**
- * snd_pcm_lib_get_vmalloc_page - map vmalloc buffer offset to page struct
- * @substream: the substream with a buffer allocated by
- * snd_pcm_lib_alloc_vmalloc_buffer()
- * @offset: offset in the buffer
- *
- * This function is to be used as the page callback in the PCM ops.
- */
-struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream,
- unsigned long offset)
-{
- return vmalloc_to_page(substream->runtime->dma_area + offset);
-}
-EXPORT_SYMBOL(snd_pcm_lib_get_vmalloc_page);
diff --git a/ANDROID_3.4.5/sound/core/pcm_misc.c b/ANDROID_3.4.5/sound/core/pcm_misc.c
deleted file mode 100644
index 9c9eff9a..00000000
--- a/ANDROID_3.4.5/sound/core/pcm_misc.c
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- * PCM Interface - misc routines
- * Copyright (c) 1998 by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <linux/export.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#define SND_PCM_FORMAT_UNKNOWN (-1)
-
-/* NOTE: "signed" prefix must be given below since the default char is
- * unsigned on some architectures!
- */
-struct pcm_format_data {
- unsigned char width; /* bit width */
- unsigned char phys; /* physical bit width */
- signed char le; /* 0 = big-endian, 1 = little-endian, -1 = others */
- signed char signd; /* 0 = unsigned, 1 = signed, -1 = others */
- unsigned char silence[8]; /* silence data to fill */
-};
-
-/* we do lots of calculations on snd_pcm_format_t; shut up sparse */
-#define INT __force int
-
-static struct pcm_format_data pcm_formats[(INT)SNDRV_PCM_FORMAT_LAST+1] = {
- [SNDRV_PCM_FORMAT_S8] = {
- .width = 8, .phys = 8, .le = -1, .signd = 1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_U8] = {
- .width = 8, .phys = 8, .le = -1, .signd = 0,
- .silence = { 0x80 },
- },
- [SNDRV_PCM_FORMAT_S16_LE] = {
- .width = 16, .phys = 16, .le = 1, .signd = 1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_S16_BE] = {
- .width = 16, .phys = 16, .le = 0, .signd = 1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_U16_LE] = {
- .width = 16, .phys = 16, .le = 1, .signd = 0,
- .silence = { 0x00, 0x80 },
- },
- [SNDRV_PCM_FORMAT_U16_BE] = {
- .width = 16, .phys = 16, .le = 0, .signd = 0,
- .silence = { 0x80, 0x00 },
- },
- [SNDRV_PCM_FORMAT_S24_LE] = {
- .width = 24, .phys = 32, .le = 1, .signd = 1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_S24_BE] = {
- .width = 24, .phys = 32, .le = 0, .signd = 1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_U24_LE] = {
- .width = 24, .phys = 32, .le = 1, .signd = 0,
- .silence = { 0x00, 0x00, 0x80 },
- },
- [SNDRV_PCM_FORMAT_U24_BE] = {
- .width = 24, .phys = 32, .le = 0, .signd = 0,
- .silence = { 0x00, 0x80, 0x00, 0x00 },
- },
- [SNDRV_PCM_FORMAT_S32_LE] = {
- .width = 32, .phys = 32, .le = 1, .signd = 1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_S32_BE] = {
- .width = 32, .phys = 32, .le = 0, .signd = 1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_U32_LE] = {
- .width = 32, .phys = 32, .le = 1, .signd = 0,
- .silence = { 0x00, 0x00, 0x00, 0x80 },
- },
- [SNDRV_PCM_FORMAT_U32_BE] = {
- .width = 32, .phys = 32, .le = 0, .signd = 0,
- .silence = { 0x80, 0x00, 0x00, 0x00 },
- },
- [SNDRV_PCM_FORMAT_FLOAT_LE] = {
- .width = 32, .phys = 32, .le = 1, .signd = -1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_FLOAT_BE] = {
- .width = 32, .phys = 32, .le = 0, .signd = -1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_FLOAT64_LE] = {
- .width = 64, .phys = 64, .le = 1, .signd = -1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_FLOAT64_BE] = {
- .width = 64, .phys = 64, .le = 0, .signd = -1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE] = {
- .width = 32, .phys = 32, .le = 1, .signd = -1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE] = {
- .width = 32, .phys = 32, .le = 0, .signd = -1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_MU_LAW] = {
- .width = 8, .phys = 8, .le = -1, .signd = -1,
- .silence = { 0x7f },
- },
- [SNDRV_PCM_FORMAT_A_LAW] = {
- .width = 8, .phys = 8, .le = -1, .signd = -1,
- .silence = { 0x55 },
- },
- [SNDRV_PCM_FORMAT_IMA_ADPCM] = {
- .width = 4, .phys = 4, .le = -1, .signd = -1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_G723_24] = {
- .width = 3, .phys = 3, .le = -1, .signd = -1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_G723_40] = {
- .width = 5, .phys = 5, .le = -1, .signd = -1,
- .silence = {},
- },
- /* FIXME: the following three formats are not defined properly yet */
- [SNDRV_PCM_FORMAT_MPEG] = {
- .le = -1, .signd = -1,
- },
- [SNDRV_PCM_FORMAT_GSM] = {
- .le = -1, .signd = -1,
- },
- [SNDRV_PCM_FORMAT_SPECIAL] = {
- .le = -1, .signd = -1,
- },
- [SNDRV_PCM_FORMAT_S24_3LE] = {
- .width = 24, .phys = 24, .le = 1, .signd = 1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_S24_3BE] = {
- .width = 24, .phys = 24, .le = 0, .signd = 1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_U24_3LE] = {
- .width = 24, .phys = 24, .le = 1, .signd = 0,
- .silence = { 0x00, 0x00, 0x80 },
- },
- [SNDRV_PCM_FORMAT_U24_3BE] = {
- .width = 24, .phys = 24, .le = 0, .signd = 0,
- .silence = { 0x80, 0x00, 0x00 },
- },
- [SNDRV_PCM_FORMAT_S20_3LE] = {
- .width = 20, .phys = 24, .le = 1, .signd = 1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_S20_3BE] = {
- .width = 20, .phys = 24, .le = 0, .signd = 1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_U20_3LE] = {
- .width = 20, .phys = 24, .le = 1, .signd = 0,
- .silence = { 0x00, 0x00, 0x08 },
- },
- [SNDRV_PCM_FORMAT_U20_3BE] = {
- .width = 20, .phys = 24, .le = 0, .signd = 0,
- .silence = { 0x08, 0x00, 0x00 },
- },
- [SNDRV_PCM_FORMAT_S18_3LE] = {
- .width = 18, .phys = 24, .le = 1, .signd = 1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_S18_3BE] = {
- .width = 18, .phys = 24, .le = 0, .signd = 1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_U18_3LE] = {
- .width = 18, .phys = 24, .le = 1, .signd = 0,
- .silence = { 0x00, 0x00, 0x02 },
- },
- [SNDRV_PCM_FORMAT_U18_3BE] = {
- .width = 18, .phys = 24, .le = 0, .signd = 0,
- .silence = { 0x02, 0x00, 0x00 },
- },
- [SNDRV_PCM_FORMAT_G723_24_1B] = {
- .width = 3, .phys = 8, .le = -1, .signd = -1,
- .silence = {},
- },
- [SNDRV_PCM_FORMAT_G723_40_1B] = {
- .width = 5, .phys = 8, .le = -1, .signd = -1,
- .silence = {},
- },
-};
-
-
-/**
- * snd_pcm_format_signed - Check the PCM format is signed linear
- * @format: the format to check
- *
- * Returns 1 if the given PCM format is signed linear, 0 if unsigned
- * linear, and a negative error code for non-linear formats.
- */
-int snd_pcm_format_signed(snd_pcm_format_t format)
-{
- int val;
- if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
- return -EINVAL;
- if ((val = pcm_formats[(INT)format].signd) < 0)
- return -EINVAL;
- return val;
-}
-
-EXPORT_SYMBOL(snd_pcm_format_signed);
-
-/**
- * snd_pcm_format_unsigned - Check the PCM format is unsigned linear
- * @format: the format to check
- *
- * Returns 1 if the given PCM format is unsigned linear, 0 if signed
- * linear, and a negative error code for non-linear formats.
- */
-int snd_pcm_format_unsigned(snd_pcm_format_t format)
-{
- int val;
-
- val = snd_pcm_format_signed(format);
- if (val < 0)
- return val;
- return !val;
-}
-
-EXPORT_SYMBOL(snd_pcm_format_unsigned);
-
-/**
- * snd_pcm_format_linear - Check the PCM format is linear
- * @format: the format to check
- *
- * Returns 1 if the given PCM format is linear, 0 if not.
- */
-int snd_pcm_format_linear(snd_pcm_format_t format)
-{
- return snd_pcm_format_signed(format) >= 0;
-}
-
-EXPORT_SYMBOL(snd_pcm_format_linear);
-
-/**
- * snd_pcm_format_little_endian - Check the PCM format is little-endian
- * @format: the format to check
- *
- * Returns 1 if the given PCM format is little-endian, 0 if
- * big-endian, or a negative error code if endian not specified.
- */
-int snd_pcm_format_little_endian(snd_pcm_format_t format)
-{
- int val;
- if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
- return -EINVAL;
- if ((val = pcm_formats[(INT)format].le) < 0)
- return -EINVAL;
- return val;
-}
-
-EXPORT_SYMBOL(snd_pcm_format_little_endian);
-
-/**
- * snd_pcm_format_big_endian - Check the PCM format is big-endian
- * @format: the format to check
- *
- * Returns 1 if the given PCM format is big-endian, 0 if
- * little-endian, or a negative error code if endian not specified.
- */
-int snd_pcm_format_big_endian(snd_pcm_format_t format)
-{
- int val;
-
- val = snd_pcm_format_little_endian(format);
- if (val < 0)
- return val;
- return !val;
-}
-
-EXPORT_SYMBOL(snd_pcm_format_big_endian);
-
-/**
- * snd_pcm_format_width - return the bit-width of the format
- * @format: the format to check
- *
- * Returns the bit-width of the format, or a negative error code
- * if unknown format.
- */
-int snd_pcm_format_width(snd_pcm_format_t format)
-{
- int val;
- if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
- return -EINVAL;
- if ((val = pcm_formats[(INT)format].width) == 0)
- return -EINVAL;
- return val;
-}
-
-EXPORT_SYMBOL(snd_pcm_format_width);
-
-/**
- * snd_pcm_format_physical_width - return the physical bit-width of the format
- * @format: the format to check
- *
- * Returns the physical bit-width of the format, or a negative error code
- * if unknown format.
- */
-int snd_pcm_format_physical_width(snd_pcm_format_t format)
-{
- int val;
- if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
- return -EINVAL;
- if ((val = pcm_formats[(INT)format].phys) == 0)
- return -EINVAL;
- return val;
-}
-
-EXPORT_SYMBOL(snd_pcm_format_physical_width);
-
-/**
- * snd_pcm_format_size - return the byte size of samples on the given format
- * @format: the format to check
- * @samples: sampling rate
- *
- * Returns the byte size of the given samples for the format, or a
- * negative error code if unknown format.
- */
-ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples)
-{
- int phys_width = snd_pcm_format_physical_width(format);
- if (phys_width < 0)
- return -EINVAL;
- return samples * phys_width / 8;
-}
-
-EXPORT_SYMBOL(snd_pcm_format_size);
-
-/**
- * snd_pcm_format_silence_64 - return the silent data in 8 bytes array
- * @format: the format to check
- *
- * Returns the format pattern to fill or NULL if error.
- */
-const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format)
-{
- if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
- return NULL;
- if (! pcm_formats[(INT)format].phys)
- return NULL;
- return pcm_formats[(INT)format].silence;
-}
-
-EXPORT_SYMBOL(snd_pcm_format_silence_64);
-
-/**
- * snd_pcm_format_set_silence - set the silence data on the buffer
- * @format: the PCM format
- * @data: the buffer pointer
- * @samples: the number of samples to set silence
- *
- * Sets the silence data on the buffer for the given samples.
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int samples)
-{
- int width;
- unsigned char *dst, *pat;
-
- if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
- return -EINVAL;
- if (samples == 0)
- return 0;
- width = pcm_formats[(INT)format].phys; /* physical width */
- pat = pcm_formats[(INT)format].silence;
- if (! width)
- return -EINVAL;
- /* signed or 1 byte data */
- if (pcm_formats[(INT)format].signd == 1 || width <= 8) {
- unsigned int bytes = samples * width / 8;
- memset(data, *pat, bytes);
- return 0;
- }
- /* non-zero samples, fill using a loop */
- width /= 8;
- dst = data;
-#if 0
- while (samples--) {
- memcpy(dst, pat, width);
- dst += width;
- }
-#else
- /* a bit optimization for constant width */
- switch (width) {
- case 2:
- while (samples--) {
- memcpy(dst, pat, 2);
- dst += 2;
- }
- break;
- case 3:
- while (samples--) {
- memcpy(dst, pat, 3);
- dst += 3;
- }
- break;
- case 4:
- while (samples--) {
- memcpy(dst, pat, 4);
- dst += 4;
- }
- break;
- case 8:
- while (samples--) {
- memcpy(dst, pat, 8);
- dst += 8;
- }
- break;
- }
-#endif
- return 0;
-}
-
-EXPORT_SYMBOL(snd_pcm_format_set_silence);
-
-/**
- * snd_pcm_limit_hw_rates - determine rate_min/rate_max fields
- * @runtime: the runtime instance
- *
- * Determines the rate_min and rate_max fields from the rates bits of
- * the given runtime->hw.
- *
- * Returns zero if successful.
- */
-int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime)
-{
- int i;
- for (i = 0; i < (int)snd_pcm_known_rates.count; i++) {
- if (runtime->hw.rates & (1 << i)) {
- runtime->hw.rate_min = snd_pcm_known_rates.list[i];
- break;
- }
- }
- for (i = (int)snd_pcm_known_rates.count - 1; i >= 0; i--) {
- if (runtime->hw.rates & (1 << i)) {
- runtime->hw.rate_max = snd_pcm_known_rates.list[i];
- break;
- }
- }
- return 0;
-}
-
-EXPORT_SYMBOL(snd_pcm_limit_hw_rates);
-
-/**
- * snd_pcm_rate_to_rate_bit - converts sample rate to SNDRV_PCM_RATE_xxx bit
- * @rate: the sample rate to convert
- *
- * Returns the SNDRV_PCM_RATE_xxx flag that corresponds to the given rate, or
- * SNDRV_PCM_RATE_KNOT for an unknown rate.
- */
-unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate)
-{
- unsigned int i;
-
- for (i = 0; i < snd_pcm_known_rates.count; i++)
- if (snd_pcm_known_rates.list[i] == rate)
- return 1u << i;
- return SNDRV_PCM_RATE_KNOT;
-}
-EXPORT_SYMBOL(snd_pcm_rate_to_rate_bit);
diff --git a/ANDROID_3.4.5/sound/core/pcm_native.c b/ANDROID_3.4.5/sound/core/pcm_native.c
deleted file mode 100644
index d535b341..00000000
--- a/ANDROID_3.4.5/sound/core/pcm_native.c
+++ /dev/null
@@ -1,3492 +0,0 @@
-/*
- * Digital Audio (PCM) abstract layer
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/file.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/pm_qos.h>
-#include <linux/uio.h>
-#include <linux/dma-mapping.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/info.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/timer.h>
-#include <sound/minors.h>
-#include <asm/io.h>
-#if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
-#include <dma-coherence.h>
-#endif
-
-/*
- * Compatibility
- */
-
-struct snd_pcm_hw_params_old {
- unsigned int flags;
- unsigned int masks[SNDRV_PCM_HW_PARAM_SUBFORMAT -
- SNDRV_PCM_HW_PARAM_ACCESS + 1];
- struct snd_interval intervals[SNDRV_PCM_HW_PARAM_TICK_TIME -
- SNDRV_PCM_HW_PARAM_SAMPLE_BITS + 1];
- unsigned int rmask;
- unsigned int cmask;
- unsigned int info;
- unsigned int msbits;
- unsigned int rate_num;
- unsigned int rate_den;
- snd_pcm_uframes_t fifo_size;
- unsigned char reserved[64];
-};
-
-#ifdef CONFIG_SND_SUPPORT_OLD_API
-#define SNDRV_PCM_IOCTL_HW_REFINE_OLD _IOWR('A', 0x10, struct snd_pcm_hw_params_old)
-#define SNDRV_PCM_IOCTL_HW_PARAMS_OLD _IOWR('A', 0x11, struct snd_pcm_hw_params_old)
-
-static int snd_pcm_hw_refine_old_user(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params_old __user * _oparams);
-static int snd_pcm_hw_params_old_user(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params_old __user * _oparams);
-#endif
-static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream);
-
-/*
- *
- */
-
-DEFINE_RWLOCK(snd_pcm_link_rwlock);
-EXPORT_SYMBOL(snd_pcm_link_rwlock);
-
-static DECLARE_RWSEM(snd_pcm_link_rwsem);
-
-static inline mm_segment_t snd_enter_user(void)
-{
- mm_segment_t fs = get_fs();
- set_fs(get_ds());
- return fs;
-}
-
-static inline void snd_leave_user(mm_segment_t fs)
-{
- set_fs(fs);
-}
-
-
-
-int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info)
-{
- struct snd_pcm_runtime *runtime;
- struct snd_pcm *pcm = substream->pcm;
- struct snd_pcm_str *pstr = substream->pstr;
-
- memset(info, 0, sizeof(*info));
- info->card = pcm->card->number;
- info->device = pcm->device;
- info->stream = substream->stream;
- info->subdevice = substream->number;
- strlcpy(info->id, pcm->id, sizeof(info->id));
- strlcpy(info->name, pcm->name, sizeof(info->name));
- info->dev_class = pcm->dev_class;
- info->dev_subclass = pcm->dev_subclass;
- info->subdevices_count = pstr->substream_count;
- info->subdevices_avail = pstr->substream_count - pstr->substream_opened;
- strlcpy(info->subname, substream->name, sizeof(info->subname));
- runtime = substream->runtime;
- /* AB: FIXME!!! This is definitely nonsense */
- if (runtime) {
- info->sync = runtime->sync;
- substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_INFO, info);
- }
- return 0;
-}
-
-int snd_pcm_info_user(struct snd_pcm_substream *substream,
- struct snd_pcm_info __user * _info)
-{
- struct snd_pcm_info *info;
- int err;
-
- info = kmalloc(sizeof(*info), GFP_KERNEL);
- if (! info)
- return -ENOMEM;
- err = snd_pcm_info(substream, info);
- if (err >= 0) {
- if (copy_to_user(_info, info, sizeof(*info)))
- err = -EFAULT;
- }
- kfree(info);
- return err;
-}
-
-#undef RULES_DEBUG
-
-#ifdef RULES_DEBUG
-#define HW_PARAM(v) [SNDRV_PCM_HW_PARAM_##v] = #v
-static const char * const snd_pcm_hw_param_names[] = {
- HW_PARAM(ACCESS),
- HW_PARAM(FORMAT),
- HW_PARAM(SUBFORMAT),
- HW_PARAM(SAMPLE_BITS),
- HW_PARAM(FRAME_BITS),
- HW_PARAM(CHANNELS),
- HW_PARAM(RATE),
- HW_PARAM(PERIOD_TIME),
- HW_PARAM(PERIOD_SIZE),
- HW_PARAM(PERIOD_BYTES),
- HW_PARAM(PERIODS),
- HW_PARAM(BUFFER_TIME),
- HW_PARAM(BUFFER_SIZE),
- HW_PARAM(BUFFER_BYTES),
- HW_PARAM(TICK_TIME),
-};
-#endif
-
-int snd_pcm_hw_refine(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- unsigned int k;
- struct snd_pcm_hardware *hw;
- struct snd_interval *i = NULL;
- struct snd_mask *m = NULL;
- struct snd_pcm_hw_constraints *constrs = &substream->runtime->hw_constraints;
- unsigned int rstamps[constrs->rules_num];
- unsigned int vstamps[SNDRV_PCM_HW_PARAM_LAST_INTERVAL + 1];
- unsigned int stamp = 2;
- int changed, again;
-
- params->info = 0;
- params->fifo_size = 0;
- if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_SAMPLE_BITS))
- params->msbits = 0;
- if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_RATE)) {
- params->rate_num = 0;
- params->rate_den = 0;
- }
-
- for (k = SNDRV_PCM_HW_PARAM_FIRST_MASK; k <= SNDRV_PCM_HW_PARAM_LAST_MASK; k++) {
- m = hw_param_mask(params, k);
- if (snd_mask_empty(m))
- return -EINVAL;
- if (!(params->rmask & (1 << k)))
- continue;
-#ifdef RULES_DEBUG
- printk(KERN_DEBUG "%s = ", snd_pcm_hw_param_names[k]);
- printk("%04x%04x%04x%04x -> ", m->bits[3], m->bits[2], m->bits[1], m->bits[0]);
-#endif
- changed = snd_mask_refine(m, constrs_mask(constrs, k));
-#ifdef RULES_DEBUG
- printk("%04x%04x%04x%04x\n", m->bits[3], m->bits[2], m->bits[1], m->bits[0]);
-#endif
- if (changed)
- params->cmask |= 1 << k;
- if (changed < 0)
- return changed;
- }
-
- for (k = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++) {
- i = hw_param_interval(params, k);
- if (snd_interval_empty(i))
- return -EINVAL;
- if (!(params->rmask & (1 << k)))
- continue;
-#ifdef RULES_DEBUG
- printk(KERN_DEBUG "%s = ", snd_pcm_hw_param_names[k]);
- if (i->empty)
- printk("empty");
- else
- printk("%c%u %u%c",
- i->openmin ? '(' : '[', i->min,
- i->max, i->openmax ? ')' : ']');
- printk(" -> ");
-#endif
- changed = snd_interval_refine(i, constrs_interval(constrs, k));
-#ifdef RULES_DEBUG
- if (i->empty)
- printk("empty\n");
- else
- printk("%c%u %u%c\n",
- i->openmin ? '(' : '[', i->min,
- i->max, i->openmax ? ')' : ']');
-#endif
- if (changed)
- params->cmask |= 1 << k;
- if (changed < 0)
- return changed;
- }
-
- for (k = 0; k < constrs->rules_num; k++)
- rstamps[k] = 0;
- for (k = 0; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++)
- vstamps[k] = (params->rmask & (1 << k)) ? 1 : 0;
- do {
- again = 0;
- for (k = 0; k < constrs->rules_num; k++) {
- struct snd_pcm_hw_rule *r = &constrs->rules[k];
- unsigned int d;
- int doit = 0;
- if (r->cond && !(r->cond & params->flags))
- continue;
- for (d = 0; r->deps[d] >= 0; d++) {
- if (vstamps[r->deps[d]] > rstamps[k]) {
- doit = 1;
- break;
- }
- }
- if (!doit)
- continue;
-#ifdef RULES_DEBUG
- printk(KERN_DEBUG "Rule %d [%p]: ", k, r->func);
- if (r->var >= 0) {
- printk("%s = ", snd_pcm_hw_param_names[r->var]);
- if (hw_is_mask(r->var)) {
- m = hw_param_mask(params, r->var);
- printk("%x", *m->bits);
- } else {
- i = hw_param_interval(params, r->var);
- if (i->empty)
- printk("empty");
- else
- printk("%c%u %u%c",
- i->openmin ? '(' : '[', i->min,
- i->max, i->openmax ? ')' : ']');
- }
- }
-#endif
- changed = r->func(params, r);
-#ifdef RULES_DEBUG
- if (r->var >= 0) {
- printk(" -> ");
- if (hw_is_mask(r->var))
- printk("%x", *m->bits);
- else {
- if (i->empty)
- printk("empty");
- else
- printk("%c%u %u%c",
- i->openmin ? '(' : '[', i->min,
- i->max, i->openmax ? ')' : ']');
- }
- }
- printk("\n");
-#endif
- rstamps[k] = stamp;
- if (changed && r->var >= 0) {
- params->cmask |= (1 << r->var);
- vstamps[r->var] = stamp;
- again = 1;
- }
- if (changed < 0)
- return changed;
- stamp++;
- }
- } while (again);
- if (!params->msbits) {
- i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS);
- if (snd_interval_single(i))
- params->msbits = snd_interval_value(i);
- }
-
- if (!params->rate_den) {
- i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
- if (snd_interval_single(i)) {
- params->rate_num = snd_interval_value(i);
- params->rate_den = 1;
- }
- }
-
- hw = &substream->runtime->hw;
- if (!params->info)
- params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES;
- if (!params->fifo_size) {
- m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
- i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- if (snd_mask_min(m) == snd_mask_max(m) &&
- snd_interval_min(i) == snd_interval_max(i)) {
- changed = substream->ops->ioctl(substream,
- SNDRV_PCM_IOCTL1_FIFO_SIZE, params);
- if (changed < 0)
- return changed;
- }
- }
- params->rmask = 0;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_pcm_hw_refine);
-
-static int snd_pcm_hw_refine_user(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params __user * _params)
-{
- struct snd_pcm_hw_params *params;
- int err;
-
- params = memdup_user(_params, sizeof(*params));
- if (IS_ERR(params))
- return PTR_ERR(params);
-
- err = snd_pcm_hw_refine(substream, params);
- if (copy_to_user(_params, params, sizeof(*params))) {
- if (!err)
- err = -EFAULT;
- }
-
- kfree(params);
- return err;
-}
-
-static int period_to_usecs(struct snd_pcm_runtime *runtime)
-{
- int usecs;
-
- if (! runtime->rate)
- return -1; /* invalid */
-
- /* take 75% of period time as the deadline */
- usecs = (750000 / runtime->rate) * runtime->period_size;
- usecs += ((750000 % runtime->rate) * runtime->period_size) /
- runtime->rate;
-
- return usecs;
-}
-
-static void snd_pcm_set_state(struct snd_pcm_substream *substream, int state)
-{
- snd_pcm_stream_lock_irq(substream);
- if (substream->runtime->status->state != SNDRV_PCM_STATE_DISCONNECTED)
- substream->runtime->status->state = state;
- snd_pcm_stream_unlock_irq(substream);
-}
-
-static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_pcm_runtime *runtime;
- int err, usecs;
- unsigned int bits;
- snd_pcm_uframes_t frames;
-
- if (PCM_RUNTIME_CHECK(substream))
- return -ENXIO;
- runtime = substream->runtime;
- snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_OPEN:
- case SNDRV_PCM_STATE_SETUP:
- case SNDRV_PCM_STATE_PREPARED:
- break;
- default:
- snd_pcm_stream_unlock_irq(substream);
- return -EBADFD;
- }
- snd_pcm_stream_unlock_irq(substream);
-#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
- if (!substream->oss.oss)
-#endif
- if (atomic_read(&substream->mmap_count))
- return -EBADFD;
-
- params->rmask = ~0U;
- err = snd_pcm_hw_refine(substream, params);
- if (err < 0)
- goto _error;
-
- err = snd_pcm_hw_params_choose(substream, params);
- if (err < 0)
- goto _error;
-
- if (substream->ops->hw_params != NULL) {
- err = substream->ops->hw_params(substream, params);
- if (err < 0)
- goto _error;
- }
-
- runtime->access = params_access(params);
- runtime->format = params_format(params);
- runtime->subformat = params_subformat(params);
- runtime->channels = params_channels(params);
- runtime->rate = params_rate(params);
- runtime->period_size = params_period_size(params);
- runtime->periods = params_periods(params);
- runtime->buffer_size = params_buffer_size(params);
- runtime->info = params->info;
- runtime->rate_num = params->rate_num;
- runtime->rate_den = params->rate_den;
- runtime->no_period_wakeup =
- (params->info & SNDRV_PCM_INFO_NO_PERIOD_WAKEUP) &&
- (params->flags & SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP);
-
- bits = snd_pcm_format_physical_width(runtime->format);
- runtime->sample_bits = bits;
- bits *= runtime->channels;
- runtime->frame_bits = bits;
- frames = 1;
- while (bits % 8 != 0) {
- bits *= 2;
- frames *= 2;
- }
- runtime->byte_align = bits / 8;
- runtime->min_align = frames;
-
- /* Default sw params */
- runtime->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
- runtime->period_step = 1;
- runtime->control->avail_min = runtime->period_size;
- runtime->start_threshold = 1;
- runtime->stop_threshold = runtime->buffer_size;
- runtime->silence_threshold = 0;
- runtime->silence_size = 0;
- runtime->boundary = runtime->buffer_size;
- while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size)
- runtime->boundary *= 2;
-
- snd_pcm_timer_resolution_change(substream);
- snd_pcm_set_state(substream, SNDRV_PCM_STATE_SETUP);
-
- if (pm_qos_request_active(&substream->latency_pm_qos_req))
- pm_qos_remove_request(&substream->latency_pm_qos_req);
- if ((usecs = period_to_usecs(runtime)) >= 0)
- pm_qos_add_request(&substream->latency_pm_qos_req,
- PM_QOS_CPU_DMA_LATENCY, usecs);
- return 0;
- _error:
- /* hardware might be unusable from this time,
- so we force application to retry to set
- the correct hardware parameter settings */
- snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
- if (substream->ops->hw_free != NULL)
- substream->ops->hw_free(substream);
- return err;
-}
-
-static int snd_pcm_hw_params_user(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params __user * _params)
-{
- struct snd_pcm_hw_params *params;
- int err;
-
- params = memdup_user(_params, sizeof(*params));
- if (IS_ERR(params))
- return PTR_ERR(params);
-
- err = snd_pcm_hw_params(substream, params);
- if (copy_to_user(_params, params, sizeof(*params))) {
- if (!err)
- err = -EFAULT;
- }
-
- kfree(params);
- return err;
-}
-
-static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime;
- int result = 0;
-
- if (PCM_RUNTIME_CHECK(substream))
- return -ENXIO;
- runtime = substream->runtime;
- snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_SETUP:
- case SNDRV_PCM_STATE_PREPARED:
- break;
- default:
- snd_pcm_stream_unlock_irq(substream);
- return -EBADFD;
- }
- snd_pcm_stream_unlock_irq(substream);
- if (atomic_read(&substream->mmap_count))
- return -EBADFD;
- if (substream->ops->hw_free)
- result = substream->ops->hw_free(substream);
- snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
- pm_qos_remove_request(&substream->latency_pm_qos_req);
- return result;
-}
-
-static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_sw_params *params)
-{
- struct snd_pcm_runtime *runtime;
- int err;
-
- if (PCM_RUNTIME_CHECK(substream))
- return -ENXIO;
- runtime = substream->runtime;
- snd_pcm_stream_lock_irq(substream);
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
- snd_pcm_stream_unlock_irq(substream);
- return -EBADFD;
- }
- snd_pcm_stream_unlock_irq(substream);
-
- if (params->tstamp_mode > SNDRV_PCM_TSTAMP_LAST)
- return -EINVAL;
- if (params->avail_min == 0)
- return -EINVAL;
- if (params->silence_size >= runtime->boundary) {
- if (params->silence_threshold != 0)
- return -EINVAL;
- } else {
- if (params->silence_size > params->silence_threshold)
- return -EINVAL;
- if (params->silence_threshold > runtime->buffer_size)
- return -EINVAL;
- }
- err = 0;
- snd_pcm_stream_lock_irq(substream);
- runtime->tstamp_mode = params->tstamp_mode;
- runtime->period_step = params->period_step;
- runtime->control->avail_min = params->avail_min;
- runtime->start_threshold = params->start_threshold;
- runtime->stop_threshold = params->stop_threshold;
- runtime->silence_threshold = params->silence_threshold;
- runtime->silence_size = params->silence_size;
- params->boundary = runtime->boundary;
- if (snd_pcm_running(substream)) {
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
- runtime->silence_size > 0)
- snd_pcm_playback_silence(substream, ULONG_MAX);
- err = snd_pcm_update_state(substream, runtime);
- }
- snd_pcm_stream_unlock_irq(substream);
- return err;
-}
-
-static int snd_pcm_sw_params_user(struct snd_pcm_substream *substream,
- struct snd_pcm_sw_params __user * _params)
-{
- struct snd_pcm_sw_params params;
- int err;
- if (copy_from_user(&params, _params, sizeof(params)))
- return -EFAULT;
- err = snd_pcm_sw_params(substream, &params);
- if (copy_to_user(_params, &params, sizeof(params)))
- return -EFAULT;
- return err;
-}
-
-int snd_pcm_status(struct snd_pcm_substream *substream,
- struct snd_pcm_status *status)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- snd_pcm_stream_lock_irq(substream);
- status->state = runtime->status->state;
- status->suspended_state = runtime->status->suspended_state;
- if (status->state == SNDRV_PCM_STATE_OPEN)
- goto _end;
- status->trigger_tstamp = runtime->trigger_tstamp;
- if (snd_pcm_running(substream)) {
- snd_pcm_update_hw_ptr(substream);
- if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) {
- status->tstamp = runtime->status->tstamp;
- goto _tstamp_end;
- }
- }
- snd_pcm_gettime(runtime, &status->tstamp);
- _tstamp_end:
- status->appl_ptr = runtime->control->appl_ptr;
- status->hw_ptr = runtime->status->hw_ptr;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- status->avail = snd_pcm_playback_avail(runtime);
- if (runtime->status->state == SNDRV_PCM_STATE_RUNNING ||
- runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
- status->delay = runtime->buffer_size - status->avail;
- status->delay += runtime->delay;
- } else
- status->delay = 0;
- } else {
- status->avail = snd_pcm_capture_avail(runtime);
- if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
- status->delay = status->avail + runtime->delay;
- else
- status->delay = 0;
- }
- status->avail_max = runtime->avail_max;
- status->overrange = runtime->overrange;
- runtime->avail_max = 0;
- runtime->overrange = 0;
- _end:
- snd_pcm_stream_unlock_irq(substream);
- return 0;
-}
-
-static int snd_pcm_status_user(struct snd_pcm_substream *substream,
- struct snd_pcm_status __user * _status)
-{
- struct snd_pcm_status status;
- int res;
-
- memset(&status, 0, sizeof(status));
- res = snd_pcm_status(substream, &status);
- if (res < 0)
- return res;
- if (copy_to_user(_status, &status, sizeof(status)))
- return -EFAULT;
- return 0;
-}
-
-static int snd_pcm_channel_info(struct snd_pcm_substream *substream,
- struct snd_pcm_channel_info * info)
-{
- struct snd_pcm_runtime *runtime;
- unsigned int channel;
-
- channel = info->channel;
- runtime = substream->runtime;
- snd_pcm_stream_lock_irq(substream);
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
- snd_pcm_stream_unlock_irq(substream);
- return -EBADFD;
- }
- snd_pcm_stream_unlock_irq(substream);
- if (channel >= runtime->channels)
- return -EINVAL;
- memset(info, 0, sizeof(*info));
- info->channel = channel;
- return substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_CHANNEL_INFO, info);
-}
-
-static int snd_pcm_channel_info_user(struct snd_pcm_substream *substream,
- struct snd_pcm_channel_info __user * _info)
-{
- struct snd_pcm_channel_info info;
- int res;
-
- if (copy_from_user(&info, _info, sizeof(info)))
- return -EFAULT;
- res = snd_pcm_channel_info(substream, &info);
- if (res < 0)
- return res;
- if (copy_to_user(_info, &info, sizeof(info)))
- return -EFAULT;
- return 0;
-}
-
-static void snd_pcm_trigger_tstamp(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- if (runtime->trigger_master == NULL)
- return;
- if (runtime->trigger_master == substream) {
- snd_pcm_gettime(runtime, &runtime->trigger_tstamp);
- } else {
- snd_pcm_trigger_tstamp(runtime->trigger_master);
- runtime->trigger_tstamp = runtime->trigger_master->runtime->trigger_tstamp;
- }
- runtime->trigger_master = NULL;
-}
-
-struct action_ops {
- int (*pre_action)(struct snd_pcm_substream *substream, int state);
- int (*do_action)(struct snd_pcm_substream *substream, int state);
- void (*undo_action)(struct snd_pcm_substream *substream, int state);
- void (*post_action)(struct snd_pcm_substream *substream, int state);
-};
-
-/*
- * this functions is core for handling of linked stream
- * Note: the stream state might be changed also on failure
- * Note2: call with calling stream lock + link lock
- */
-static int snd_pcm_action_group(struct action_ops *ops,
- struct snd_pcm_substream *substream,
- int state, int do_lock)
-{
- struct snd_pcm_substream *s = NULL;
- struct snd_pcm_substream *s1;
- int res = 0;
-
- snd_pcm_group_for_each_entry(s, substream) {
- if (do_lock && s != substream)
- spin_lock_nested(&s->self_group.lock,
- SINGLE_DEPTH_NESTING);
- res = ops->pre_action(s, state);
- if (res < 0)
- goto _unlock;
- }
- snd_pcm_group_for_each_entry(s, substream) {
- res = ops->do_action(s, state);
- if (res < 0) {
- if (ops->undo_action) {
- snd_pcm_group_for_each_entry(s1, substream) {
- if (s1 == s) /* failed stream */
- break;
- ops->undo_action(s1, state);
- }
- }
- s = NULL; /* unlock all */
- goto _unlock;
- }
- }
- snd_pcm_group_for_each_entry(s, substream) {
- ops->post_action(s, state);
- }
- _unlock:
- if (do_lock) {
- /* unlock streams */
- snd_pcm_group_for_each_entry(s1, substream) {
- if (s1 != substream)
- spin_unlock(&s1->self_group.lock);
- if (s1 == s) /* end */
- break;
- }
- }
- return res;
-}
-
-/*
- * Note: call with stream lock
- */
-static int snd_pcm_action_single(struct action_ops *ops,
- struct snd_pcm_substream *substream,
- int state)
-{
- int res;
-
- res = ops->pre_action(substream, state);
- if (res < 0)
- return res;
- res = ops->do_action(substream, state);
- if (res == 0)
- ops->post_action(substream, state);
- else if (ops->undo_action)
- ops->undo_action(substream, state);
- return res;
-}
-
-/*
- * Note: call with stream lock
- */
-static int snd_pcm_action(struct action_ops *ops,
- struct snd_pcm_substream *substream,
- int state)
-{
- int res;
-
- if (snd_pcm_stream_linked(substream)) {
- if (!spin_trylock(&substream->group->lock)) {
- spin_unlock(&substream->self_group.lock);
- spin_lock(&substream->group->lock);
- spin_lock(&substream->self_group.lock);
- }
- res = snd_pcm_action_group(ops, substream, state, 1);
- spin_unlock(&substream->group->lock);
- } else {
- res = snd_pcm_action_single(ops, substream, state);
- }
- return res;
-}
-
-/*
- * Note: don't use any locks before
- */
-static int snd_pcm_action_lock_irq(struct action_ops *ops,
- struct snd_pcm_substream *substream,
- int state)
-{
- int res;
-
- read_lock_irq(&snd_pcm_link_rwlock);
- if (snd_pcm_stream_linked(substream)) {
- spin_lock(&substream->group->lock);
- spin_lock(&substream->self_group.lock);
- res = snd_pcm_action_group(ops, substream, state, 1);
- spin_unlock(&substream->self_group.lock);
- spin_unlock(&substream->group->lock);
- } else {
- spin_lock(&substream->self_group.lock);
- res = snd_pcm_action_single(ops, substream, state);
- spin_unlock(&substream->self_group.lock);
- }
- read_unlock_irq(&snd_pcm_link_rwlock);
- return res;
-}
-
-/*
- */
-static int snd_pcm_action_nonatomic(struct action_ops *ops,
- struct snd_pcm_substream *substream,
- int state)
-{
- int res;
-
- down_read(&snd_pcm_link_rwsem);
- if (snd_pcm_stream_linked(substream))
- res = snd_pcm_action_group(ops, substream, state, 0);
- else
- res = snd_pcm_action_single(ops, substream, state);
- up_read(&snd_pcm_link_rwsem);
- return res;
-}
-
-/*
- * start callbacks
- */
-static int snd_pcm_pre_start(struct snd_pcm_substream *substream, int state)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- if (runtime->status->state != SNDRV_PCM_STATE_PREPARED)
- return -EBADFD;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
- !snd_pcm_playback_data(substream))
- return -EPIPE;
- runtime->trigger_master = substream;
- return 0;
-}
-
-static int snd_pcm_do_start(struct snd_pcm_substream *substream, int state)
-{
- if (substream->runtime->trigger_master != substream)
- return 0;
- return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
-}
-
-static void snd_pcm_undo_start(struct snd_pcm_substream *substream, int state)
-{
- if (substream->runtime->trigger_master == substream)
- substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
-}
-
-static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_trigger_tstamp(substream);
- runtime->hw_ptr_jiffies = jiffies;
- runtime->hw_ptr_buffer_jiffies = (runtime->buffer_size * HZ) /
- runtime->rate;
- runtime->status->state = state;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
- runtime->silence_size > 0)
- snd_pcm_playback_silence(substream, ULONG_MAX);
- if (substream->timer)
- snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTART,
- &runtime->trigger_tstamp);
-}
-
-static struct action_ops snd_pcm_action_start = {
- .pre_action = snd_pcm_pre_start,
- .do_action = snd_pcm_do_start,
- .undo_action = snd_pcm_undo_start,
- .post_action = snd_pcm_post_start
-};
-
-/**
- * snd_pcm_start - start all linked streams
- * @substream: the PCM substream instance
- */
-int snd_pcm_start(struct snd_pcm_substream *substream)
-{
- return snd_pcm_action(&snd_pcm_action_start, substream,
- SNDRV_PCM_STATE_RUNNING);
-}
-
-/*
- * stop callbacks
- */
-static int snd_pcm_pre_stop(struct snd_pcm_substream *substream, int state)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
- return -EBADFD;
- runtime->trigger_master = substream;
- return 0;
-}
-
-static int snd_pcm_do_stop(struct snd_pcm_substream *substream, int state)
-{
- if (substream->runtime->trigger_master == substream &&
- snd_pcm_running(substream))
- substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
- return 0; /* unconditonally stop all substreams */
-}
-
-static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- if (runtime->status->state != state) {
- snd_pcm_trigger_tstamp(substream);
- if (substream->timer)
- snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTOP,
- &runtime->trigger_tstamp);
- runtime->status->state = state;
- }
- wake_up(&runtime->sleep);
- wake_up(&runtime->tsleep);
-}
-
-static struct action_ops snd_pcm_action_stop = {
- .pre_action = snd_pcm_pre_stop,
- .do_action = snd_pcm_do_stop,
- .post_action = snd_pcm_post_stop
-};
-
-/**
- * snd_pcm_stop - try to stop all running streams in the substream group
- * @substream: the PCM substream instance
- * @state: PCM state after stopping the stream
- *
- * The state of each stream is then changed to the given state unconditionally.
- */
-int snd_pcm_stop(struct snd_pcm_substream *substream, snd_pcm_state_t state)
-{
- return snd_pcm_action(&snd_pcm_action_stop, substream, state);
-}
-
-EXPORT_SYMBOL(snd_pcm_stop);
-
-/**
- * snd_pcm_drain_done - stop the DMA only when the given stream is playback
- * @substream: the PCM substream
- *
- * After stopping, the state is changed to SETUP.
- * Unlike snd_pcm_stop(), this affects only the given stream.
- */
-int snd_pcm_drain_done(struct snd_pcm_substream *substream)
-{
- return snd_pcm_action_single(&snd_pcm_action_stop, substream,
- SNDRV_PCM_STATE_SETUP);
-}
-
-/*
- * pause callbacks
- */
-static int snd_pcm_pre_pause(struct snd_pcm_substream *substream, int push)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- if (!(runtime->info & SNDRV_PCM_INFO_PAUSE))
- return -ENOSYS;
- if (push) {
- if (runtime->status->state != SNDRV_PCM_STATE_RUNNING)
- return -EBADFD;
- } else if (runtime->status->state != SNDRV_PCM_STATE_PAUSED)
- return -EBADFD;
- runtime->trigger_master = substream;
- return 0;
-}
-
-static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push)
-{
- if (substream->runtime->trigger_master != substream)
- return 0;
- /* some drivers might use hw_ptr to recover from the pause -
- update the hw_ptr now */
- if (push)
- snd_pcm_update_hw_ptr(substream);
- /* The jiffies check in snd_pcm_update_hw_ptr*() is done by
- * a delta between the current jiffies, this gives a large enough
- * delta, effectively to skip the check once.
- */
- substream->runtime->hw_ptr_jiffies = jiffies - HZ * 1000;
- return substream->ops->trigger(substream,
- push ? SNDRV_PCM_TRIGGER_PAUSE_PUSH :
- SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
-}
-
-static void snd_pcm_undo_pause(struct snd_pcm_substream *substream, int push)
-{
- if (substream->runtime->trigger_master == substream)
- substream->ops->trigger(substream,
- push ? SNDRV_PCM_TRIGGER_PAUSE_RELEASE :
- SNDRV_PCM_TRIGGER_PAUSE_PUSH);
-}
-
-static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_trigger_tstamp(substream);
- if (push) {
- runtime->status->state = SNDRV_PCM_STATE_PAUSED;
- if (substream->timer)
- snd_timer_notify(substream->timer,
- SNDRV_TIMER_EVENT_MPAUSE,
- &runtime->trigger_tstamp);
- wake_up(&runtime->sleep);
- wake_up(&runtime->tsleep);
- } else {
- runtime->status->state = SNDRV_PCM_STATE_RUNNING;
- if (substream->timer)
- snd_timer_notify(substream->timer,
- SNDRV_TIMER_EVENT_MCONTINUE,
- &runtime->trigger_tstamp);
- }
-}
-
-static struct action_ops snd_pcm_action_pause = {
- .pre_action = snd_pcm_pre_pause,
- .do_action = snd_pcm_do_pause,
- .undo_action = snd_pcm_undo_pause,
- .post_action = snd_pcm_post_pause
-};
-
-/*
- * Push/release the pause for all linked streams.
- */
-static int snd_pcm_pause(struct snd_pcm_substream *substream, int push)
-{
- return snd_pcm_action(&snd_pcm_action_pause, substream, push);
-}
-
-#ifdef CONFIG_PM
-/* suspend */
-
-static int snd_pcm_pre_suspend(struct snd_pcm_substream *substream, int state)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
- return -EBUSY;
- runtime->trigger_master = substream;
- return 0;
-}
-
-static int snd_pcm_do_suspend(struct snd_pcm_substream *substream, int state)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- if (runtime->trigger_master != substream)
- return 0;
- if (! snd_pcm_running(substream))
- return 0;
- substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND);
- return 0; /* suspend unconditionally */
-}
-
-static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_trigger_tstamp(substream);
- if (substream->timer)
- snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSUSPEND,
- &runtime->trigger_tstamp);
- runtime->status->suspended_state = runtime->status->state;
- runtime->status->state = SNDRV_PCM_STATE_SUSPENDED;
- wake_up(&runtime->sleep);
- wake_up(&runtime->tsleep);
-}
-
-static struct action_ops snd_pcm_action_suspend = {
- .pre_action = snd_pcm_pre_suspend,
- .do_action = snd_pcm_do_suspend,
- .post_action = snd_pcm_post_suspend
-};
-
-/**
- * snd_pcm_suspend - trigger SUSPEND to all linked streams
- * @substream: the PCM substream
- *
- * After this call, all streams are changed to SUSPENDED state.
- */
-int snd_pcm_suspend(struct snd_pcm_substream *substream)
-{
- int err;
- unsigned long flags;
-
- if (! substream)
- return 0;
-
- snd_pcm_stream_lock_irqsave(substream, flags);
- err = snd_pcm_action(&snd_pcm_action_suspend, substream, 0);
- snd_pcm_stream_unlock_irqrestore(substream, flags);
- return err;
-}
-
-EXPORT_SYMBOL(snd_pcm_suspend);
-
-/**
- * snd_pcm_suspend_all - trigger SUSPEND to all substreams in the given pcm
- * @pcm: the PCM instance
- *
- * After this call, all streams are changed to SUSPENDED state.
- */
-int snd_pcm_suspend_all(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- int stream, err = 0;
-
- if (! pcm)
- return 0;
-
- for (stream = 0; stream < 2; stream++) {
- for (substream = pcm->streams[stream].substream;
- substream; substream = substream->next) {
- /* FIXME: the open/close code should lock this as well */
- if (substream->runtime == NULL)
- continue;
- err = snd_pcm_suspend(substream);
- if (err < 0 && err != -EBUSY)
- return err;
- }
- }
- return 0;
-}
-
-EXPORT_SYMBOL(snd_pcm_suspend_all);
-
-/* resume */
-
-static int snd_pcm_pre_resume(struct snd_pcm_substream *substream, int state)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- if (!(runtime->info & SNDRV_PCM_INFO_RESUME))
- return -ENOSYS;
- runtime->trigger_master = substream;
- return 0;
-}
-
-static int snd_pcm_do_resume(struct snd_pcm_substream *substream, int state)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- if (runtime->trigger_master != substream)
- return 0;
- /* DMA not running previously? */
- if (runtime->status->suspended_state != SNDRV_PCM_STATE_RUNNING &&
- (runtime->status->suspended_state != SNDRV_PCM_STATE_DRAINING ||
- substream->stream != SNDRV_PCM_STREAM_PLAYBACK))
- return 0;
- return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_RESUME);
-}
-
-static void snd_pcm_undo_resume(struct snd_pcm_substream *substream, int state)
-{
- if (substream->runtime->trigger_master == substream &&
- snd_pcm_running(substream))
- substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND);
-}
-
-static void snd_pcm_post_resume(struct snd_pcm_substream *substream, int state)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_trigger_tstamp(substream);
- if (substream->timer)
- snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MRESUME,
- &runtime->trigger_tstamp);
- runtime->status->state = runtime->status->suspended_state;
-}
-
-static struct action_ops snd_pcm_action_resume = {
- .pre_action = snd_pcm_pre_resume,
- .do_action = snd_pcm_do_resume,
- .undo_action = snd_pcm_undo_resume,
- .post_action = snd_pcm_post_resume
-};
-
-static int snd_pcm_resume(struct snd_pcm_substream *substream)
-{
- struct snd_card *card = substream->pcm->card;
- int res;
-
- snd_power_lock(card);
- if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0)
- res = snd_pcm_action_lock_irq(&snd_pcm_action_resume, substream, 0);
- snd_power_unlock(card);
- return res;
-}
-
-#else
-
-static int snd_pcm_resume(struct snd_pcm_substream *substream)
-{
- return -ENOSYS;
-}
-
-#endif /* CONFIG_PM */
-
-/*
- * xrun ioctl
- *
- * Change the RUNNING stream(s) to XRUN state.
- */
-static int snd_pcm_xrun(struct snd_pcm_substream *substream)
-{
- struct snd_card *card = substream->pcm->card;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int result;
-
- snd_power_lock(card);
- if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
- result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
- if (result < 0)
- goto _unlock;
- }
-
- snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_XRUN:
- result = 0; /* already there */
- break;
- case SNDRV_PCM_STATE_RUNNING:
- result = snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
- break;
- default:
- result = -EBADFD;
- }
- snd_pcm_stream_unlock_irq(substream);
- _unlock:
- snd_power_unlock(card);
- return result;
-}
-
-/*
- * reset ioctl
- */
-static int snd_pcm_pre_reset(struct snd_pcm_substream *substream, int state)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_RUNNING:
- case SNDRV_PCM_STATE_PREPARED:
- case SNDRV_PCM_STATE_PAUSED:
- case SNDRV_PCM_STATE_SUSPENDED:
- return 0;
- default:
- return -EBADFD;
- }
-}
-
-static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err = substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL);
- if (err < 0)
- return err;
- runtime->hw_ptr_base = 0;
- runtime->hw_ptr_interrupt = runtime->status->hw_ptr -
- runtime->status->hw_ptr % runtime->period_size;
- runtime->silence_start = runtime->status->hw_ptr;
- runtime->silence_filled = 0;
- return 0;
-}
-
-static void snd_pcm_post_reset(struct snd_pcm_substream *substream, int state)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- runtime->control->appl_ptr = runtime->status->hw_ptr;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
- runtime->silence_size > 0)
- snd_pcm_playback_silence(substream, ULONG_MAX);
-}
-
-static struct action_ops snd_pcm_action_reset = {
- .pre_action = snd_pcm_pre_reset,
- .do_action = snd_pcm_do_reset,
- .post_action = snd_pcm_post_reset
-};
-
-static int snd_pcm_reset(struct snd_pcm_substream *substream)
-{
- return snd_pcm_action_nonatomic(&snd_pcm_action_reset, substream, 0);
-}
-
-/*
- * prepare ioctl
- */
-/* we use the second argument for updating f_flags */
-static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream,
- int f_flags)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
- runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
- return -EBADFD;
- if (snd_pcm_running(substream))
- return -EBUSY;
- substream->f_flags = f_flags;
- return 0;
-}
-
-static int snd_pcm_do_prepare(struct snd_pcm_substream *substream, int state)
-{
- int err;
- err = substream->ops->prepare(substream);
- if (err < 0)
- return err;
- return snd_pcm_do_reset(substream, 0);
-}
-
-static void snd_pcm_post_prepare(struct snd_pcm_substream *substream, int state)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- runtime->control->appl_ptr = runtime->status->hw_ptr;
- snd_pcm_set_state(substream, SNDRV_PCM_STATE_PREPARED);
-}
-
-static struct action_ops snd_pcm_action_prepare = {
- .pre_action = snd_pcm_pre_prepare,
- .do_action = snd_pcm_do_prepare,
- .post_action = snd_pcm_post_prepare
-};
-
-/**
- * snd_pcm_prepare - prepare the PCM substream to be triggerable
- * @substream: the PCM substream instance
- * @file: file to refer f_flags
- */
-static int snd_pcm_prepare(struct snd_pcm_substream *substream,
- struct file *file)
-{
- int res;
- struct snd_card *card = substream->pcm->card;
- int f_flags;
-
- if (file)
- f_flags = file->f_flags;
- else
- f_flags = substream->f_flags;
-
- snd_power_lock(card);
- if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0)
- res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare,
- substream, f_flags);
- snd_power_unlock(card);
- return res;
-}
-
-/*
- * drain ioctl
- */
-
-static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state)
-{
- substream->runtime->trigger_master = substream;
- return 0;
-}
-
-static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_PREPARED:
- /* start playback stream if possible */
- if (! snd_pcm_playback_empty(substream)) {
- snd_pcm_do_start(substream, SNDRV_PCM_STATE_DRAINING);
- snd_pcm_post_start(substream, SNDRV_PCM_STATE_DRAINING);
- }
- break;
- case SNDRV_PCM_STATE_RUNNING:
- runtime->status->state = SNDRV_PCM_STATE_DRAINING;
- break;
- default:
- break;
- }
- } else {
- /* stop running stream */
- if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) {
- int new_state = snd_pcm_capture_avail(runtime) > 0 ?
- SNDRV_PCM_STATE_DRAINING : SNDRV_PCM_STATE_SETUP;
- snd_pcm_do_stop(substream, new_state);
- snd_pcm_post_stop(substream, new_state);
- }
- }
- return 0;
-}
-
-static void snd_pcm_post_drain_init(struct snd_pcm_substream *substream, int state)
-{
-}
-
-static struct action_ops snd_pcm_action_drain_init = {
- .pre_action = snd_pcm_pre_drain_init,
- .do_action = snd_pcm_do_drain_init,
- .post_action = snd_pcm_post_drain_init
-};
-
-static int snd_pcm_drop(struct snd_pcm_substream *substream);
-
-/*
- * Drain the stream(s).
- * When the substream is linked, sync until the draining of all playback streams
- * is finished.
- * After this call, all streams are supposed to be either SETUP or DRAINING
- * (capture only) state.
- */
-static int snd_pcm_drain(struct snd_pcm_substream *substream,
- struct file *file)
-{
- struct snd_card *card;
- struct snd_pcm_runtime *runtime;
- struct snd_pcm_substream *s;
- wait_queue_t wait;
- int result = 0;
- int nonblock = 0;
-
- card = substream->pcm->card;
- runtime = substream->runtime;
-
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
- return -EBADFD;
-
- snd_power_lock(card);
- if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
- result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
- if (result < 0) {
- snd_power_unlock(card);
- return result;
- }
- }
-
- if (file) {
- if (file->f_flags & O_NONBLOCK)
- nonblock = 1;
- } else if (substream->f_flags & O_NONBLOCK)
- nonblock = 1;
-
- down_read(&snd_pcm_link_rwsem);
- snd_pcm_stream_lock_irq(substream);
- /* resume pause */
- if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
- snd_pcm_pause(substream, 0);
-
- /* pre-start/stop - all running streams are changed to DRAINING state */
- result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0);
- if (result < 0)
- goto unlock;
- /* in non-blocking, we don't wait in ioctl but let caller poll */
- if (nonblock) {
- result = -EAGAIN;
- goto unlock;
- }
-
- for (;;) {
- long tout;
- struct snd_pcm_runtime *to_check;
- if (signal_pending(current)) {
- result = -ERESTARTSYS;
- break;
- }
- /* find a substream to drain */
- to_check = NULL;
- snd_pcm_group_for_each_entry(s, substream) {
- if (s->stream != SNDRV_PCM_STREAM_PLAYBACK)
- continue;
- runtime = s->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
- to_check = runtime;
- break;
- }
- }
- if (!to_check)
- break; /* all drained */
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&to_check->sleep, &wait);
- snd_pcm_stream_unlock_irq(substream);
- up_read(&snd_pcm_link_rwsem);
- snd_power_unlock(card);
- if (runtime->no_period_wakeup)
- tout = MAX_SCHEDULE_TIMEOUT;
- else {
- tout = 10;
- if (runtime->rate) {
- long t = runtime->period_size * 2 / runtime->rate;
- tout = max(t, tout);
- }
- tout = msecs_to_jiffies(tout * 1000);
- }
- tout = schedule_timeout_interruptible(tout);
- snd_power_lock(card);
- down_read(&snd_pcm_link_rwsem);
- snd_pcm_stream_lock_irq(substream);
- remove_wait_queue(&to_check->sleep, &wait);
- if (card->shutdown) {
- result = -ENODEV;
- break;
- }
- if (tout == 0) {
- if (substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
- result = -ESTRPIPE;
- else {
- snd_printd("playback drain error (DMA or IRQ trouble?)\n");
- snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
- result = -EIO;
- }
- break;
- }
- }
-
- unlock:
- snd_pcm_stream_unlock_irq(substream);
- up_read(&snd_pcm_link_rwsem);
- snd_power_unlock(card);
-
- return result;
-}
-
-/*
- * drop ioctl
- *
- * Immediately put all linked substreams into SETUP state.
- */
-static int snd_pcm_drop(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime;
- int result = 0;
-
- if (PCM_RUNTIME_CHECK(substream))
- return -ENXIO;
- runtime = substream->runtime;
-
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
- runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED ||
- runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
- return -EBADFD;
-
- snd_pcm_stream_lock_irq(substream);
- /* resume pause */
- if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
- snd_pcm_pause(substream, 0);
-
- snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
- /* runtime->control->appl_ptr = runtime->status->hw_ptr; */
- snd_pcm_stream_unlock_irq(substream);
-
- return result;
-}
-
-
-/* WARNING: Don't forget to fput back the file */
-static struct file *snd_pcm_file_fd(int fd)
-{
- struct file *file;
- struct inode *inode;
- unsigned int minor;
-
- file = fget(fd);
- if (!file)
- return NULL;
- inode = file->f_path.dentry->d_inode;
- if (!S_ISCHR(inode->i_mode) ||
- imajor(inode) != snd_major) {
- fput(file);
- return NULL;
- }
- minor = iminor(inode);
- if (!snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_PLAYBACK) &&
- !snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_CAPTURE)) {
- fput(file);
- return NULL;
- }
- return file;
-}
-
-/*
- * PCM link handling
- */
-static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
-{
- int res = 0;
- struct file *file;
- struct snd_pcm_file *pcm_file;
- struct snd_pcm_substream *substream1;
- struct snd_pcm_group *group;
-
- file = snd_pcm_file_fd(fd);
- if (!file)
- return -EBADFD;
- pcm_file = file->private_data;
- substream1 = pcm_file->substream;
- group = kmalloc(sizeof(*group), GFP_KERNEL);
- if (!group) {
- res = -ENOMEM;
- goto _nolock;
- }
- down_write(&snd_pcm_link_rwsem);
- write_lock_irq(&snd_pcm_link_rwlock);
- if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN ||
- substream->runtime->status->state != substream1->runtime->status->state) {
- res = -EBADFD;
- goto _end;
- }
- if (snd_pcm_stream_linked(substream1)) {
- res = -EALREADY;
- goto _end;
- }
- if (!snd_pcm_stream_linked(substream)) {
- substream->group = group;
- spin_lock_init(&substream->group->lock);
- INIT_LIST_HEAD(&substream->group->substreams);
- list_add_tail(&substream->link_list, &substream->group->substreams);
- substream->group->count = 1;
- }
- list_add_tail(&substream1->link_list, &substream->group->substreams);
- substream->group->count++;
- substream1->group = substream->group;
- _end:
- write_unlock_irq(&snd_pcm_link_rwlock);
- up_write(&snd_pcm_link_rwsem);
- _nolock:
- snd_card_unref(substream1->pcm->card);
- fput(file);
- if (res < 0)
- kfree(group);
- return res;
-}
-
-static void relink_to_local(struct snd_pcm_substream *substream)
-{
- substream->group = &substream->self_group;
- INIT_LIST_HEAD(&substream->self_group.substreams);
- list_add_tail(&substream->link_list, &substream->self_group.substreams);
-}
-
-static int snd_pcm_unlink(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_substream *s;
- int res = 0;
-
- down_write(&snd_pcm_link_rwsem);
- write_lock_irq(&snd_pcm_link_rwlock);
- if (!snd_pcm_stream_linked(substream)) {
- res = -EALREADY;
- goto _end;
- }
- list_del(&substream->link_list);
- substream->group->count--;
- if (substream->group->count == 1) { /* detach the last stream, too */
- snd_pcm_group_for_each_entry(s, substream) {
- relink_to_local(s);
- break;
- }
- kfree(substream->group);
- }
- relink_to_local(substream);
- _end:
- write_unlock_irq(&snd_pcm_link_rwlock);
- up_write(&snd_pcm_link_rwsem);
- return res;
-}
-
-/*
- * hw configurator
- */
-static int snd_pcm_hw_rule_mul(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_interval t;
- snd_interval_mul(hw_param_interval_c(params, rule->deps[0]),
- hw_param_interval_c(params, rule->deps[1]), &t);
- return snd_interval_refine(hw_param_interval(params, rule->var), &t);
-}
-
-static int snd_pcm_hw_rule_div(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_interval t;
- snd_interval_div(hw_param_interval_c(params, rule->deps[0]),
- hw_param_interval_c(params, rule->deps[1]), &t);
- return snd_interval_refine(hw_param_interval(params, rule->var), &t);
-}
-
-static int snd_pcm_hw_rule_muldivk(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_interval t;
- snd_interval_muldivk(hw_param_interval_c(params, rule->deps[0]),
- hw_param_interval_c(params, rule->deps[1]),
- (unsigned long) rule->private, &t);
- return snd_interval_refine(hw_param_interval(params, rule->var), &t);
-}
-
-static int snd_pcm_hw_rule_mulkdiv(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_interval t;
- snd_interval_mulkdiv(hw_param_interval_c(params, rule->deps[0]),
- (unsigned long) rule->private,
- hw_param_interval_c(params, rule->deps[1]), &t);
- return snd_interval_refine(hw_param_interval(params, rule->var), &t);
-}
-
-static int snd_pcm_hw_rule_format(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- unsigned int k;
- struct snd_interval *i = hw_param_interval(params, rule->deps[0]);
- struct snd_mask m;
- struct snd_mask *mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
- snd_mask_any(&m);
- for (k = 0; k <= SNDRV_PCM_FORMAT_LAST; ++k) {
- int bits;
- if (! snd_mask_test(mask, k))
- continue;
- bits = snd_pcm_format_physical_width(k);
- if (bits <= 0)
- continue; /* ignore invalid formats */
- if ((unsigned)bits < i->min || (unsigned)bits > i->max)
- snd_mask_reset(&m, k);
- }
- return snd_mask_refine(mask, &m);
-}
-
-static int snd_pcm_hw_rule_sample_bits(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_interval t;
- unsigned int k;
- t.min = UINT_MAX;
- t.max = 0;
- t.openmin = 0;
- t.openmax = 0;
- for (k = 0; k <= SNDRV_PCM_FORMAT_LAST; ++k) {
- int bits;
- if (! snd_mask_test(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), k))
- continue;
- bits = snd_pcm_format_physical_width(k);
- if (bits <= 0)
- continue; /* ignore invalid formats */
- if (t.min > (unsigned)bits)
- t.min = bits;
- if (t.max < (unsigned)bits)
- t.max = bits;
- }
- t.integer = 1;
- return snd_interval_refine(hw_param_interval(params, rule->var), &t);
-}
-
-#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12
-#error "Change this table"
-#endif
-
-static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100,
- 48000, 64000, 88200, 96000, 176400, 192000 };
-
-const struct snd_pcm_hw_constraint_list snd_pcm_known_rates = {
- .count = ARRAY_SIZE(rates),
- .list = rates,
-};
-
-static int snd_pcm_hw_rule_rate(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_pcm_hardware *hw = rule->private;
- return snd_interval_list(hw_param_interval(params, rule->var),
- snd_pcm_known_rates.count,
- snd_pcm_known_rates.list, hw->rates);
-}
-
-static int snd_pcm_hw_rule_buffer_bytes_max(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_interval t;
- struct snd_pcm_substream *substream = rule->private;
- t.min = 0;
- t.max = substream->buffer_bytes_max;
- t.openmin = 0;
- t.openmax = 0;
- t.integer = 1;
- return snd_interval_refine(hw_param_interval(params, rule->var), &t);
-}
-
-int snd_pcm_hw_constraints_init(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
- int k, err;
-
- for (k = SNDRV_PCM_HW_PARAM_FIRST_MASK; k <= SNDRV_PCM_HW_PARAM_LAST_MASK; k++) {
- snd_mask_any(constrs_mask(constrs, k));
- }
-
- for (k = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++) {
- snd_interval_any(constrs_interval(constrs, k));
- }
-
- snd_interval_setinteger(constrs_interval(constrs, SNDRV_PCM_HW_PARAM_CHANNELS));
- snd_interval_setinteger(constrs_interval(constrs, SNDRV_PCM_HW_PARAM_BUFFER_SIZE));
- snd_interval_setinteger(constrs_interval(constrs, SNDRV_PCM_HW_PARAM_BUFFER_BYTES));
- snd_interval_setinteger(constrs_interval(constrs, SNDRV_PCM_HW_PARAM_SAMPLE_BITS));
- snd_interval_setinteger(constrs_interval(constrs, SNDRV_PCM_HW_PARAM_FRAME_BITS));
-
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
- snd_pcm_hw_rule_format, NULL,
- SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
- snd_pcm_hw_rule_sample_bits, NULL,
- SNDRV_PCM_HW_PARAM_FORMAT,
- SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
- snd_pcm_hw_rule_div, NULL,
- SNDRV_PCM_HW_PARAM_FRAME_BITS, SNDRV_PCM_HW_PARAM_CHANNELS, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FRAME_BITS,
- snd_pcm_hw_rule_mul, NULL,
- SNDRV_PCM_HW_PARAM_SAMPLE_BITS, SNDRV_PCM_HW_PARAM_CHANNELS, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FRAME_BITS,
- snd_pcm_hw_rule_mulkdiv, (void*) 8,
- SNDRV_PCM_HW_PARAM_PERIOD_BYTES, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FRAME_BITS,
- snd_pcm_hw_rule_mulkdiv, (void*) 8,
- SNDRV_PCM_HW_PARAM_BUFFER_BYTES, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- snd_pcm_hw_rule_div, NULL,
- SNDRV_PCM_HW_PARAM_FRAME_BITS, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- snd_pcm_hw_rule_mulkdiv, (void*) 1000000,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE, SNDRV_PCM_HW_PARAM_PERIOD_TIME, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- snd_pcm_hw_rule_mulkdiv, (void*) 1000000,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE, SNDRV_PCM_HW_PARAM_BUFFER_TIME, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS,
- snd_pcm_hw_rule_div, NULL,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- snd_pcm_hw_rule_div, NULL,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE, SNDRV_PCM_HW_PARAM_PERIODS, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- snd_pcm_hw_rule_mulkdiv, (void*) 8,
- SNDRV_PCM_HW_PARAM_PERIOD_BYTES, SNDRV_PCM_HW_PARAM_FRAME_BITS, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- snd_pcm_hw_rule_muldivk, (void*) 1000000,
- SNDRV_PCM_HW_PARAM_PERIOD_TIME, SNDRV_PCM_HW_PARAM_RATE, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- snd_pcm_hw_rule_mul, NULL,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE, SNDRV_PCM_HW_PARAM_PERIODS, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- snd_pcm_hw_rule_mulkdiv, (void*) 8,
- SNDRV_PCM_HW_PARAM_BUFFER_BYTES, SNDRV_PCM_HW_PARAM_FRAME_BITS, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- snd_pcm_hw_rule_muldivk, (void*) 1000000,
- SNDRV_PCM_HW_PARAM_BUFFER_TIME, SNDRV_PCM_HW_PARAM_RATE, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- snd_pcm_hw_rule_muldivk, (void*) 8,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE, SNDRV_PCM_HW_PARAM_FRAME_BITS, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
- snd_pcm_hw_rule_muldivk, (void*) 8,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE, SNDRV_PCM_HW_PARAM_FRAME_BITS, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_TIME,
- snd_pcm_hw_rule_mulkdiv, (void*) 1000000,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE, SNDRV_PCM_HW_PARAM_RATE, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_TIME,
- snd_pcm_hw_rule_mulkdiv, (void*) 1000000,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE, SNDRV_PCM_HW_PARAM_RATE, -1);
- if (err < 0)
- return err;
- return 0;
-}
-
-int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_pcm_hardware *hw = &runtime->hw;
- int err;
- unsigned int mask = 0;
-
- if (hw->info & SNDRV_PCM_INFO_INTERLEAVED)
- mask |= 1 << SNDRV_PCM_ACCESS_RW_INTERLEAVED;
- if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED)
- mask |= 1 << SNDRV_PCM_ACCESS_RW_NONINTERLEAVED;
- if (hw->info & SNDRV_PCM_INFO_MMAP) {
- if (hw->info & SNDRV_PCM_INFO_INTERLEAVED)
- mask |= 1 << SNDRV_PCM_ACCESS_MMAP_INTERLEAVED;
- if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED)
- mask |= 1 << SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED;
- if (hw->info & SNDRV_PCM_INFO_COMPLEX)
- mask |= 1 << SNDRV_PCM_ACCESS_MMAP_COMPLEX;
- }
- err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_ACCESS, mask);
- if (err < 0)
- return err;
-
- err = snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT, hw->formats);
- if (err < 0)
- return err;
-
- err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT, 1 << SNDRV_PCM_SUBFORMAT_STD);
- if (err < 0)
- return err;
-
- err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS,
- hw->channels_min, hw->channels_max);
- if (err < 0)
- return err;
-
- err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE,
- hw->rate_min, hw->rate_max);
- if (err < 0)
- return err;
-
- err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- hw->period_bytes_min, hw->period_bytes_max);
- if (err < 0)
- return err;
-
- err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIODS,
- hw->periods_min, hw->periods_max);
- if (err < 0)
- return err;
-
- err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
- hw->period_bytes_min, hw->buffer_bytes_max);
- if (err < 0)
- return err;
-
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
- snd_pcm_hw_rule_buffer_bytes_max, substream,
- SNDRV_PCM_HW_PARAM_BUFFER_BYTES, -1);
- if (err < 0)
- return err;
-
- /* FIXME: remove */
- if (runtime->dma_bytes) {
- err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, runtime->dma_bytes);
- if (err < 0)
- return -EINVAL;
- }
-
- if (!(hw->rates & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))) {
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- snd_pcm_hw_rule_rate, hw,
- SNDRV_PCM_HW_PARAM_RATE, -1);
- if (err < 0)
- return err;
- }
-
- /* FIXME: this belong to lowlevel */
- snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
-
- return 0;
-}
-
-static void pcm_release_private(struct snd_pcm_substream *substream)
-{
- snd_pcm_unlink(substream);
-}
-
-void snd_pcm_release_substream(struct snd_pcm_substream *substream)
-{
- substream->ref_count--;
- if (substream->ref_count > 0)
- return;
-
- snd_pcm_drop(substream);
- if (substream->hw_opened) {
- if (substream->ops->hw_free != NULL)
- substream->ops->hw_free(substream);
- substream->ops->close(substream);
- substream->hw_opened = 0;
- }
- if (pm_qos_request_active(&substream->latency_pm_qos_req))
- pm_qos_remove_request(&substream->latency_pm_qos_req);
- if (substream->pcm_release) {
- substream->pcm_release(substream);
- substream->pcm_release = NULL;
- }
- snd_pcm_detach_substream(substream);
-}
-
-EXPORT_SYMBOL(snd_pcm_release_substream);
-
-int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
- struct file *file,
- struct snd_pcm_substream **rsubstream)
-{
- struct snd_pcm_substream *substream;
- int err;
-
- err = snd_pcm_attach_substream(pcm, stream, file, &substream);
- if (err < 0)
- return err;
- if (substream->ref_count > 1) {
- *rsubstream = substream;
- return 0;
- }
-
- err = snd_pcm_hw_constraints_init(substream);
- if (err < 0) {
- snd_printd("snd_pcm_hw_constraints_init failed\n");
- goto error;
- }
-
- if ((err = substream->ops->open(substream)) < 0)
- goto error;
-
- substream->hw_opened = 1;
-
- err = snd_pcm_hw_constraints_complete(substream);
- if (err < 0) {
- snd_printd("snd_pcm_hw_constraints_complete failed\n");
- goto error;
- }
-
- *rsubstream = substream;
- return 0;
-
- error:
- snd_pcm_release_substream(substream);
- return err;
-}
-
-EXPORT_SYMBOL(snd_pcm_open_substream);
-
-static int snd_pcm_open_file(struct file *file,
- struct snd_pcm *pcm,
- int stream)
-{
- struct snd_pcm_file *pcm_file;
- struct snd_pcm_substream *substream;
- int err;
-
- err = snd_pcm_open_substream(pcm, stream, file, &substream);
- if (err < 0)
- return err;
-
- pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL);
- if (pcm_file == NULL) {
- snd_pcm_release_substream(substream);
- return -ENOMEM;
- }
- pcm_file->substream = substream;
- if (substream->ref_count == 1) {
- substream->file = pcm_file;
- substream->pcm_release = pcm_release_private;
- }
- file->private_data = pcm_file;
-
- return 0;
-}
-
-static int snd_pcm_playback_open(struct inode *inode, struct file *file)
-{
- struct snd_pcm *pcm;
- int err = nonseekable_open(inode, file);
- if (err < 0)
- return err;
- pcm = snd_lookup_minor_data(iminor(inode),
- SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
- err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK);
- if (pcm)
- snd_card_unref(pcm->card);
- return err;
-}
-
-static int snd_pcm_capture_open(struct inode *inode, struct file *file)
-{
- struct snd_pcm *pcm;
- int err = nonseekable_open(inode, file);
- if (err < 0)
- return err;
- pcm = snd_lookup_minor_data(iminor(inode),
- SNDRV_DEVICE_TYPE_PCM_CAPTURE);
- err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE);
- if (pcm)
- snd_card_unref(pcm->card);
- return err;
-}
-
-static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
-{
- int err;
- wait_queue_t wait;
-
- if (pcm == NULL) {
- err = -ENODEV;
- goto __error1;
- }
- err = snd_card_file_add(pcm->card, file);
- if (err < 0)
- goto __error1;
- if (!try_module_get(pcm->card->module)) {
- err = -EFAULT;
- goto __error2;
- }
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&pcm->open_wait, &wait);
- mutex_lock(&pcm->open_mutex);
- while (1) {
- err = snd_pcm_open_file(file, pcm, stream);
- if (err >= 0)
- break;
- if (err == -EAGAIN) {
- if (file->f_flags & O_NONBLOCK) {
- err = -EBUSY;
- break;
- }
- } else
- break;
- set_current_state(TASK_INTERRUPTIBLE);
- mutex_unlock(&pcm->open_mutex);
- schedule();
- mutex_lock(&pcm->open_mutex);
- if (pcm->card->shutdown) {
- err = -ENODEV;
- break;
- }
- if (signal_pending(current)) {
- err = -ERESTARTSYS;
- break;
- }
- }
- remove_wait_queue(&pcm->open_wait, &wait);
- mutex_unlock(&pcm->open_mutex);
- if (err < 0)
- goto __error;
- return err;
-
- __error:
- module_put(pcm->card->module);
- __error2:
- snd_card_file_remove(pcm->card, file);
- __error1:
- return err;
-}
-
-static int snd_pcm_release(struct inode *inode, struct file *file)
-{
- struct snd_pcm *pcm;
- struct snd_pcm_substream *substream;
- struct snd_pcm_file *pcm_file;
-
- pcm_file = file->private_data;
- substream = pcm_file->substream;
- if (snd_BUG_ON(!substream))
- return -ENXIO;
- pcm = substream->pcm;
- mutex_lock(&pcm->open_mutex);
- snd_pcm_release_substream(substream);
- kfree(pcm_file);
- mutex_unlock(&pcm->open_mutex);
- wake_up(&pcm->open_wait);
- module_put(pcm->card->module);
- snd_card_file_remove(pcm->card, file);
- return 0;
-}
-
-static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *substream,
- snd_pcm_uframes_t frames)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_sframes_t appl_ptr;
- snd_pcm_sframes_t ret;
- snd_pcm_sframes_t hw_avail;
-
- if (frames == 0)
- return 0;
-
- snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_PREPARED:
- break;
- case SNDRV_PCM_STATE_DRAINING:
- case SNDRV_PCM_STATE_RUNNING:
- if (snd_pcm_update_hw_ptr(substream) >= 0)
- break;
- /* Fall through */
- case SNDRV_PCM_STATE_XRUN:
- ret = -EPIPE;
- goto __end;
- case SNDRV_PCM_STATE_SUSPENDED:
- ret = -ESTRPIPE;
- goto __end;
- default:
- ret = -EBADFD;
- goto __end;
- }
-
- hw_avail = snd_pcm_playback_hw_avail(runtime);
- if (hw_avail <= 0) {
- ret = 0;
- goto __end;
- }
- if (frames > (snd_pcm_uframes_t)hw_avail)
- frames = hw_avail;
- appl_ptr = runtime->control->appl_ptr - frames;
- if (appl_ptr < 0)
- appl_ptr += runtime->boundary;
- runtime->control->appl_ptr = appl_ptr;
- ret = frames;
- __end:
- snd_pcm_stream_unlock_irq(substream);
- return ret;
-}
-
-static snd_pcm_sframes_t snd_pcm_capture_rewind(struct snd_pcm_substream *substream,
- snd_pcm_uframes_t frames)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_sframes_t appl_ptr;
- snd_pcm_sframes_t ret;
- snd_pcm_sframes_t hw_avail;
-
- if (frames == 0)
- return 0;
-
- snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_PREPARED:
- case SNDRV_PCM_STATE_DRAINING:
- break;
- case SNDRV_PCM_STATE_RUNNING:
- if (snd_pcm_update_hw_ptr(substream) >= 0)
- break;
- /* Fall through */
- case SNDRV_PCM_STATE_XRUN:
- ret = -EPIPE;
- goto __end;
- case SNDRV_PCM_STATE_SUSPENDED:
- ret = -ESTRPIPE;
- goto __end;
- default:
- ret = -EBADFD;
- goto __end;
- }
-
- hw_avail = snd_pcm_capture_hw_avail(runtime);
- if (hw_avail <= 0) {
- ret = 0;
- goto __end;
- }
- if (frames > (snd_pcm_uframes_t)hw_avail)
- frames = hw_avail;
- appl_ptr = runtime->control->appl_ptr - frames;
- if (appl_ptr < 0)
- appl_ptr += runtime->boundary;
- runtime->control->appl_ptr = appl_ptr;
- ret = frames;
- __end:
- snd_pcm_stream_unlock_irq(substream);
- return ret;
-}
-
-static snd_pcm_sframes_t snd_pcm_playback_forward(struct snd_pcm_substream *substream,
- snd_pcm_uframes_t frames)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_sframes_t appl_ptr;
- snd_pcm_sframes_t ret;
- snd_pcm_sframes_t avail;
-
- if (frames == 0)
- return 0;
-
- snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_PREPARED:
- case SNDRV_PCM_STATE_PAUSED:
- break;
- case SNDRV_PCM_STATE_DRAINING:
- case SNDRV_PCM_STATE_RUNNING:
- if (snd_pcm_update_hw_ptr(substream) >= 0)
- break;
- /* Fall through */
- case SNDRV_PCM_STATE_XRUN:
- ret = -EPIPE;
- goto __end;
- case SNDRV_PCM_STATE_SUSPENDED:
- ret = -ESTRPIPE;
- goto __end;
- default:
- ret = -EBADFD;
- goto __end;
- }
-
- avail = snd_pcm_playback_avail(runtime);
- if (avail <= 0) {
- ret = 0;
- goto __end;
- }
- if (frames > (snd_pcm_uframes_t)avail)
- frames = avail;
- appl_ptr = runtime->control->appl_ptr + frames;
- if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary)
- appl_ptr -= runtime->boundary;
- runtime->control->appl_ptr = appl_ptr;
- ret = frames;
- __end:
- snd_pcm_stream_unlock_irq(substream);
- return ret;
-}
-
-static snd_pcm_sframes_t snd_pcm_capture_forward(struct snd_pcm_substream *substream,
- snd_pcm_uframes_t frames)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_sframes_t appl_ptr;
- snd_pcm_sframes_t ret;
- snd_pcm_sframes_t avail;
-
- if (frames == 0)
- return 0;
-
- snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_PREPARED:
- case SNDRV_PCM_STATE_DRAINING:
- case SNDRV_PCM_STATE_PAUSED:
- break;
- case SNDRV_PCM_STATE_RUNNING:
- if (snd_pcm_update_hw_ptr(substream) >= 0)
- break;
- /* Fall through */
- case SNDRV_PCM_STATE_XRUN:
- ret = -EPIPE;
- goto __end;
- case SNDRV_PCM_STATE_SUSPENDED:
- ret = -ESTRPIPE;
- goto __end;
- default:
- ret = -EBADFD;
- goto __end;
- }
-
- avail = snd_pcm_capture_avail(runtime);
- if (avail <= 0) {
- ret = 0;
- goto __end;
- }
- if (frames > (snd_pcm_uframes_t)avail)
- frames = avail;
- appl_ptr = runtime->control->appl_ptr + frames;
- if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary)
- appl_ptr -= runtime->boundary;
- runtime->control->appl_ptr = appl_ptr;
- ret = frames;
- __end:
- snd_pcm_stream_unlock_irq(substream);
- return ret;
-}
-
-static int snd_pcm_hwsync(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_DRAINING:
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- goto __badfd;
- case SNDRV_PCM_STATE_RUNNING:
- if ((err = snd_pcm_update_hw_ptr(substream)) < 0)
- break;
- /* Fall through */
- case SNDRV_PCM_STATE_PREPARED:
- case SNDRV_PCM_STATE_SUSPENDED:
- err = 0;
- break;
- case SNDRV_PCM_STATE_XRUN:
- err = -EPIPE;
- break;
- default:
- __badfd:
- err = -EBADFD;
- break;
- }
- snd_pcm_stream_unlock_irq(substream);
- return err;
-}
-
-static int snd_pcm_delay(struct snd_pcm_substream *substream,
- snd_pcm_sframes_t __user *res)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
- snd_pcm_sframes_t n = 0;
-
- snd_pcm_stream_lock_irq(substream);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_DRAINING:
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- goto __badfd;
- case SNDRV_PCM_STATE_RUNNING:
- if ((err = snd_pcm_update_hw_ptr(substream)) < 0)
- break;
- /* Fall through */
- case SNDRV_PCM_STATE_PREPARED:
- case SNDRV_PCM_STATE_SUSPENDED:
- err = 0;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- n = snd_pcm_playback_hw_avail(runtime);
- else
- n = snd_pcm_capture_avail(runtime);
- n += runtime->delay;
- break;
- case SNDRV_PCM_STATE_XRUN:
- err = -EPIPE;
- break;
- default:
- __badfd:
- err = -EBADFD;
- break;
- }
- snd_pcm_stream_unlock_irq(substream);
- if (!err)
- if (put_user(n, res))
- err = -EFAULT;
- return err;
-}
-
-static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
- struct snd_pcm_sync_ptr __user *_sync_ptr)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_pcm_sync_ptr sync_ptr;
- volatile struct snd_pcm_mmap_status *status;
- volatile struct snd_pcm_mmap_control *control;
- int err;
-
- memset(&sync_ptr, 0, sizeof(sync_ptr));
- if (get_user(sync_ptr.flags, (unsigned __user *)&(_sync_ptr->flags)))
- return -EFAULT;
- if (copy_from_user(&sync_ptr.c.control, &(_sync_ptr->c.control), sizeof(struct snd_pcm_mmap_control)))
- return -EFAULT;
- status = runtime->status;
- control = runtime->control;
- if (sync_ptr.flags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
- err = snd_pcm_hwsync(substream);
- if (err < 0)
- return err;
- }
- snd_pcm_stream_lock_irq(substream);
- if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_APPL))
- control->appl_ptr = sync_ptr.c.control.appl_ptr;
- else
- sync_ptr.c.control.appl_ptr = control->appl_ptr;
- if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN))
- control->avail_min = sync_ptr.c.control.avail_min;
- else
- sync_ptr.c.control.avail_min = control->avail_min;
- sync_ptr.s.status.state = status->state;
- sync_ptr.s.status.hw_ptr = status->hw_ptr;
- sync_ptr.s.status.tstamp = status->tstamp;
- sync_ptr.s.status.suspended_state = status->suspended_state;
- snd_pcm_stream_unlock_irq(substream);
- if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr)))
- return -EFAULT;
- return 0;
-}
-
-static int snd_pcm_tstamp(struct snd_pcm_substream *substream, int __user *_arg)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int arg;
-
- if (get_user(arg, _arg))
- return -EFAULT;
- if (arg < 0 || arg > SNDRV_PCM_TSTAMP_TYPE_LAST)
- return -EINVAL;
- runtime->tstamp_type = SNDRV_PCM_TSTAMP_TYPE_GETTIMEOFDAY;
- if (arg == SNDRV_PCM_TSTAMP_TYPE_MONOTONIC)
- runtime->tstamp_type = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC;
- return 0;
-}
-
-static int snd_pcm_common_ioctl1(struct file *file,
- struct snd_pcm_substream *substream,
- unsigned int cmd, void __user *arg)
-{
- switch (cmd) {
- case SNDRV_PCM_IOCTL_PVERSION:
- return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0;
- case SNDRV_PCM_IOCTL_INFO:
- return snd_pcm_info_user(substream, arg);
- case SNDRV_PCM_IOCTL_TSTAMP: /* just for compatibility */
- return 0;
- case SNDRV_PCM_IOCTL_TTSTAMP:
- return snd_pcm_tstamp(substream, arg);
- case SNDRV_PCM_IOCTL_HW_REFINE:
- return snd_pcm_hw_refine_user(substream, arg);
- case SNDRV_PCM_IOCTL_HW_PARAMS:
- return snd_pcm_hw_params_user(substream, arg);
- case SNDRV_PCM_IOCTL_HW_FREE:
- return snd_pcm_hw_free(substream);
- case SNDRV_PCM_IOCTL_SW_PARAMS:
- return snd_pcm_sw_params_user(substream, arg);
- case SNDRV_PCM_IOCTL_STATUS:
- return snd_pcm_status_user(substream, arg);
- case SNDRV_PCM_IOCTL_CHANNEL_INFO:
- return snd_pcm_channel_info_user(substream, arg);
- case SNDRV_PCM_IOCTL_PREPARE:
- return snd_pcm_prepare(substream, file);
- case SNDRV_PCM_IOCTL_RESET:
- return snd_pcm_reset(substream);
- case SNDRV_PCM_IOCTL_START:
- return snd_pcm_action_lock_irq(&snd_pcm_action_start, substream, SNDRV_PCM_STATE_RUNNING);
- case SNDRV_PCM_IOCTL_LINK:
- return snd_pcm_link(substream, (int)(unsigned long) arg);
- case SNDRV_PCM_IOCTL_UNLINK:
- return snd_pcm_unlink(substream);
- case SNDRV_PCM_IOCTL_RESUME:
- return snd_pcm_resume(substream);
- case SNDRV_PCM_IOCTL_XRUN:
- return snd_pcm_xrun(substream);
- case SNDRV_PCM_IOCTL_HWSYNC:
- return snd_pcm_hwsync(substream);
- case SNDRV_PCM_IOCTL_DELAY:
- return snd_pcm_delay(substream, arg);
- case SNDRV_PCM_IOCTL_SYNC_PTR:
- return snd_pcm_sync_ptr(substream, arg);
-#ifdef CONFIG_SND_SUPPORT_OLD_API
- case SNDRV_PCM_IOCTL_HW_REFINE_OLD:
- return snd_pcm_hw_refine_old_user(substream, arg);
- case SNDRV_PCM_IOCTL_HW_PARAMS_OLD:
- return snd_pcm_hw_params_old_user(substream, arg);
-#endif
- case SNDRV_PCM_IOCTL_DRAIN:
- return snd_pcm_drain(substream, file);
- case SNDRV_PCM_IOCTL_DROP:
- return snd_pcm_drop(substream);
- case SNDRV_PCM_IOCTL_PAUSE:
- {
- int res;
- snd_pcm_stream_lock_irq(substream);
- res = snd_pcm_pause(substream, (int)(unsigned long)arg);
- snd_pcm_stream_unlock_irq(substream);
- return res;
- }
- }
- snd_printd("unknown ioctl = 0x%x\n", cmd);
- return -ENOTTY;
-}
-
-static int snd_pcm_playback_ioctl1(struct file *file,
- struct snd_pcm_substream *substream,
- unsigned int cmd, void __user *arg)
-{
- if (snd_BUG_ON(!substream))
- return -ENXIO;
- if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_PLAYBACK))
- return -EINVAL;
- switch (cmd) {
- case SNDRV_PCM_IOCTL_WRITEI_FRAMES:
- {
- struct snd_xferi xferi;
- struct snd_xferi __user *_xferi = arg;
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_sframes_t result;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
- return -EBADFD;
- if (put_user(0, &_xferi->result))
- return -EFAULT;
- if (copy_from_user(&xferi, _xferi, sizeof(xferi)))
- return -EFAULT;
- result = snd_pcm_lib_write(substream, xferi.buf, xferi.frames);
- __put_user(result, &_xferi->result);
- return result < 0 ? result : 0;
- }
- case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
- {
- struct snd_xfern xfern;
- struct snd_xfern __user *_xfern = arg;
- struct snd_pcm_runtime *runtime = substream->runtime;
- void __user **bufs;
- snd_pcm_sframes_t result;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
- return -EBADFD;
- if (runtime->channels > 128)
- return -EINVAL;
- if (put_user(0, &_xfern->result))
- return -EFAULT;
- if (copy_from_user(&xfern, _xfern, sizeof(xfern)))
- return -EFAULT;
-
- bufs = memdup_user(xfern.bufs,
- sizeof(void *) * runtime->channels);
- if (IS_ERR(bufs))
- return PTR_ERR(bufs);
- result = snd_pcm_lib_writev(substream, bufs, xfern.frames);
- kfree(bufs);
- __put_user(result, &_xfern->result);
- return result < 0 ? result : 0;
- }
- case SNDRV_PCM_IOCTL_REWIND:
- {
- snd_pcm_uframes_t frames;
- snd_pcm_uframes_t __user *_frames = arg;
- snd_pcm_sframes_t result;
- if (get_user(frames, _frames))
- return -EFAULT;
- if (put_user(0, _frames))
- return -EFAULT;
- result = snd_pcm_playback_rewind(substream, frames);
- __put_user(result, _frames);
- return result < 0 ? result : 0;
- }
- case SNDRV_PCM_IOCTL_FORWARD:
- {
- snd_pcm_uframes_t frames;
- snd_pcm_uframes_t __user *_frames = arg;
- snd_pcm_sframes_t result;
- if (get_user(frames, _frames))
- return -EFAULT;
- if (put_user(0, _frames))
- return -EFAULT;
- result = snd_pcm_playback_forward(substream, frames);
- __put_user(result, _frames);
- return result < 0 ? result : 0;
- }
- }
- return snd_pcm_common_ioctl1(file, substream, cmd, arg);
-}
-
-static int snd_pcm_capture_ioctl1(struct file *file,
- struct snd_pcm_substream *substream,
- unsigned int cmd, void __user *arg)
-{
- if (snd_BUG_ON(!substream))
- return -ENXIO;
- if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_CAPTURE))
- return -EINVAL;
- switch (cmd) {
- case SNDRV_PCM_IOCTL_READI_FRAMES:
- {
- struct snd_xferi xferi;
- struct snd_xferi __user *_xferi = arg;
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_sframes_t result;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
- return -EBADFD;
- if (put_user(0, &_xferi->result))
- return -EFAULT;
- if (copy_from_user(&xferi, _xferi, sizeof(xferi)))
- return -EFAULT;
- result = snd_pcm_lib_read(substream, xferi.buf, xferi.frames);
- __put_user(result, &_xferi->result);
- return result < 0 ? result : 0;
- }
- case SNDRV_PCM_IOCTL_READN_FRAMES:
- {
- struct snd_xfern xfern;
- struct snd_xfern __user *_xfern = arg;
- struct snd_pcm_runtime *runtime = substream->runtime;
- void *bufs;
- snd_pcm_sframes_t result;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
- return -EBADFD;
- if (runtime->channels > 128)
- return -EINVAL;
- if (put_user(0, &_xfern->result))
- return -EFAULT;
- if (copy_from_user(&xfern, _xfern, sizeof(xfern)))
- return -EFAULT;
-
- bufs = memdup_user(xfern.bufs,
- sizeof(void *) * runtime->channels);
- if (IS_ERR(bufs))
- return PTR_ERR(bufs);
- result = snd_pcm_lib_readv(substream, bufs, xfern.frames);
- kfree(bufs);
- __put_user(result, &_xfern->result);
- return result < 0 ? result : 0;
- }
- case SNDRV_PCM_IOCTL_REWIND:
- {
- snd_pcm_uframes_t frames;
- snd_pcm_uframes_t __user *_frames = arg;
- snd_pcm_sframes_t result;
- if (get_user(frames, _frames))
- return -EFAULT;
- if (put_user(0, _frames))
- return -EFAULT;
- result = snd_pcm_capture_rewind(substream, frames);
- __put_user(result, _frames);
- return result < 0 ? result : 0;
- }
- case SNDRV_PCM_IOCTL_FORWARD:
- {
- snd_pcm_uframes_t frames;
- snd_pcm_uframes_t __user *_frames = arg;
- snd_pcm_sframes_t result;
- if (get_user(frames, _frames))
- return -EFAULT;
- if (put_user(0, _frames))
- return -EFAULT;
- result = snd_pcm_capture_forward(substream, frames);
- __put_user(result, _frames);
- return result < 0 ? result : 0;
- }
- }
- return snd_pcm_common_ioctl1(file, substream, cmd, arg);
-}
-
-static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct snd_pcm_file *pcm_file;
-
- pcm_file = file->private_data;
-
- if (((cmd >> 8) & 0xff) != 'A')
- return -ENOTTY;
-
- return snd_pcm_playback_ioctl1(file, pcm_file->substream, cmd,
- (void __user *)arg);
-}
-
-static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct snd_pcm_file *pcm_file;
-
- pcm_file = file->private_data;
-
- if (((cmd >> 8) & 0xff) != 'A')
- return -ENOTTY;
-
- return snd_pcm_capture_ioctl1(file, pcm_file->substream, cmd,
- (void __user *)arg);
-}
-
-int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
- unsigned int cmd, void *arg)
-{
- mm_segment_t fs;
- int result;
-
- fs = snd_enter_user();
- switch (substream->stream) {
- case SNDRV_PCM_STREAM_PLAYBACK:
- result = snd_pcm_playback_ioctl1(NULL, substream, cmd,
- (void __user *)arg);
- break;
- case SNDRV_PCM_STREAM_CAPTURE:
- result = snd_pcm_capture_ioctl1(NULL, substream, cmd,
- (void __user *)arg);
- break;
- default:
- result = -EINVAL;
- break;
- }
- snd_leave_user(fs);
- return result;
-}
-
-EXPORT_SYMBOL(snd_pcm_kernel_ioctl);
-
-static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count,
- loff_t * offset)
-{
- struct snd_pcm_file *pcm_file;
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
- snd_pcm_sframes_t result;
-
- pcm_file = file->private_data;
- substream = pcm_file->substream;
- if (PCM_RUNTIME_CHECK(substream))
- return -ENXIO;
- runtime = substream->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
- return -EBADFD;
- if (!frame_aligned(runtime, count))
- return -EINVAL;
- count = bytes_to_frames(runtime, count);
- result = snd_pcm_lib_read(substream, buf, count);
- if (result > 0)
- result = frames_to_bytes(runtime, result);
- return result;
-}
-
-static ssize_t snd_pcm_write(struct file *file, const char __user *buf,
- size_t count, loff_t * offset)
-{
- struct snd_pcm_file *pcm_file;
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
- snd_pcm_sframes_t result;
-
- pcm_file = file->private_data;
- substream = pcm_file->substream;
- if (PCM_RUNTIME_CHECK(substream))
- return -ENXIO;
- runtime = substream->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
- return -EBADFD;
- if (!frame_aligned(runtime, count))
- return -EINVAL;
- count = bytes_to_frames(runtime, count);
- result = snd_pcm_lib_write(substream, buf, count);
- if (result > 0)
- result = frames_to_bytes(runtime, result);
- return result;
-}
-
-static ssize_t snd_pcm_aio_read(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t pos)
-
-{
- struct snd_pcm_file *pcm_file;
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
- snd_pcm_sframes_t result;
- unsigned long i;
- void __user **bufs;
- snd_pcm_uframes_t frames;
-
- pcm_file = iocb->ki_filp->private_data;
- substream = pcm_file->substream;
- if (PCM_RUNTIME_CHECK(substream))
- return -ENXIO;
- runtime = substream->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
- return -EBADFD;
- if (nr_segs > 1024 || nr_segs != runtime->channels)
- return -EINVAL;
- if (!frame_aligned(runtime, iov->iov_len))
- return -EINVAL;
- frames = bytes_to_samples(runtime, iov->iov_len);
- bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL);
- if (bufs == NULL)
- return -ENOMEM;
- for (i = 0; i < nr_segs; ++i)
- bufs[i] = iov[i].iov_base;
- result = snd_pcm_lib_readv(substream, bufs, frames);
- if (result > 0)
- result = frames_to_bytes(runtime, result);
- kfree(bufs);
- return result;
-}
-
-static ssize_t snd_pcm_aio_write(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t pos)
-{
- struct snd_pcm_file *pcm_file;
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
- snd_pcm_sframes_t result;
- unsigned long i;
- void __user **bufs;
- snd_pcm_uframes_t frames;
-
- pcm_file = iocb->ki_filp->private_data;
- substream = pcm_file->substream;
- if (PCM_RUNTIME_CHECK(substream))
- return -ENXIO;
- runtime = substream->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
- return -EBADFD;
- if (nr_segs > 128 || nr_segs != runtime->channels ||
- !frame_aligned(runtime, iov->iov_len))
- return -EINVAL;
- frames = bytes_to_samples(runtime, iov->iov_len);
- bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL);
- if (bufs == NULL)
- return -ENOMEM;
- for (i = 0; i < nr_segs; ++i)
- bufs[i] = iov[i].iov_base;
- result = snd_pcm_lib_writev(substream, bufs, frames);
- if (result > 0)
- result = frames_to_bytes(runtime, result);
- kfree(bufs);
- return result;
-}
-
-static unsigned int snd_pcm_playback_poll(struct file *file, poll_table * wait)
-{
- struct snd_pcm_file *pcm_file;
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
- unsigned int mask;
- snd_pcm_uframes_t avail;
-
- pcm_file = file->private_data;
-
- substream = pcm_file->substream;
- if (PCM_RUNTIME_CHECK(substream))
- return -ENXIO;
- runtime = substream->runtime;
-
- poll_wait(file, &runtime->sleep, wait);
-
- snd_pcm_stream_lock_irq(substream);
- avail = snd_pcm_playback_avail(runtime);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_RUNNING:
- case SNDRV_PCM_STATE_PREPARED:
- case SNDRV_PCM_STATE_PAUSED:
- if (avail >= runtime->control->avail_min) {
- mask = POLLOUT | POLLWRNORM;
- break;
- }
- /* Fall through */
- case SNDRV_PCM_STATE_DRAINING:
- mask = 0;
- break;
- default:
- mask = POLLOUT | POLLWRNORM | POLLERR;
- break;
- }
- snd_pcm_stream_unlock_irq(substream);
- return mask;
-}
-
-static unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait)
-{
- struct snd_pcm_file *pcm_file;
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
- unsigned int mask;
- snd_pcm_uframes_t avail;
-
- pcm_file = file->private_data;
-
- substream = pcm_file->substream;
- if (PCM_RUNTIME_CHECK(substream))
- return -ENXIO;
- runtime = substream->runtime;
-
- poll_wait(file, &runtime->sleep, wait);
-
- snd_pcm_stream_lock_irq(substream);
- avail = snd_pcm_capture_avail(runtime);
- switch (runtime->status->state) {
- case SNDRV_PCM_STATE_RUNNING:
- case SNDRV_PCM_STATE_PREPARED:
- case SNDRV_PCM_STATE_PAUSED:
- if (avail >= runtime->control->avail_min) {
- mask = POLLIN | POLLRDNORM;
- break;
- }
- mask = 0;
- break;
- case SNDRV_PCM_STATE_DRAINING:
- if (avail > 0) {
- mask = POLLIN | POLLRDNORM;
- break;
- }
- /* Fall through */
- default:
- mask = POLLIN | POLLRDNORM | POLLERR;
- break;
- }
- snd_pcm_stream_unlock_irq(substream);
- return mask;
-}
-
-/*
- * mmap support
- */
-
-/*
- * Only on coherent architectures, we can mmap the status and the control records
- * for effcient data transfer. On others, we have to use HWSYNC ioctl...
- */
-#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_ALPHA)
-/*
- * mmap status record
- */
-static int snd_pcm_mmap_status_fault(struct vm_area_struct *area,
- struct vm_fault *vmf)
-{
- struct snd_pcm_substream *substream = area->vm_private_data;
- struct snd_pcm_runtime *runtime;
-
- if (substream == NULL)
- return VM_FAULT_SIGBUS;
- runtime = substream->runtime;
- vmf->page = virt_to_page(runtime->status);
- get_page(vmf->page);
- return 0;
-}
-
-static const struct vm_operations_struct snd_pcm_vm_ops_status =
-{
- .fault = snd_pcm_mmap_status_fault,
-};
-
-static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file,
- struct vm_area_struct *area)
-{
- long size;
- if (!(area->vm_flags & VM_READ))
- return -EINVAL;
- size = area->vm_end - area->vm_start;
- if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)))
- return -EINVAL;
- area->vm_ops = &snd_pcm_vm_ops_status;
- area->vm_private_data = substream;
- area->vm_flags |= VM_RESERVED;
- return 0;
-}
-
-/*
- * mmap control record
- */
-static int snd_pcm_mmap_control_fault(struct vm_area_struct *area,
- struct vm_fault *vmf)
-{
- struct snd_pcm_substream *substream = area->vm_private_data;
- struct snd_pcm_runtime *runtime;
-
- if (substream == NULL)
- return VM_FAULT_SIGBUS;
- runtime = substream->runtime;
- vmf->page = virt_to_page(runtime->control);
- get_page(vmf->page);
- return 0;
-}
-
-static const struct vm_operations_struct snd_pcm_vm_ops_control =
-{
- .fault = snd_pcm_mmap_control_fault,
-};
-
-static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file *file,
- struct vm_area_struct *area)
-{
- long size;
- if (!(area->vm_flags & VM_READ))
- return -EINVAL;
- size = area->vm_end - area->vm_start;
- if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)))
- return -EINVAL;
- area->vm_ops = &snd_pcm_vm_ops_control;
- area->vm_private_data = substream;
- area->vm_flags |= VM_RESERVED;
- return 0;
-}
-#else /* ! coherent mmap */
-/*
- * don't support mmap for status and control records.
- */
-static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file,
- struct vm_area_struct *area)
-{
- return -ENXIO;
-}
-static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file *file,
- struct vm_area_struct *area)
-{
- return -ENXIO;
-}
-#endif /* coherent mmap */
-
-static inline struct page *
-snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs)
-{
- void *vaddr = substream->runtime->dma_area + ofs;
-#if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
- if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV)
- return virt_to_page(CAC_ADDR(vaddr));
-#endif
-#if defined(CONFIG_PPC32) && defined(CONFIG_NOT_COHERENT_CACHE)
- if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) {
- dma_addr_t addr = substream->runtime->dma_addr + ofs;
- addr -= get_dma_offset(substream->dma_buffer.dev.dev);
- /* assume dma_handle set via pfn_to_phys() in
- * mm/dma-noncoherent.c
- */
- return pfn_to_page(addr >> PAGE_SHIFT);
- }
-#endif
- return virt_to_page(vaddr);
-}
-
-/*
- * fault callback for mmapping a RAM page
- */
-static int snd_pcm_mmap_data_fault(struct vm_area_struct *area,
- struct vm_fault *vmf)
-{
- struct snd_pcm_substream *substream = area->vm_private_data;
- struct snd_pcm_runtime *runtime;
- unsigned long offset;
- struct page * page;
- size_t dma_bytes;
-
- if (substream == NULL)
- return VM_FAULT_SIGBUS;
- runtime = substream->runtime;
- offset = vmf->pgoff << PAGE_SHIFT;
- dma_bytes = PAGE_ALIGN(runtime->dma_bytes);
- if (offset > dma_bytes - PAGE_SIZE)
- return VM_FAULT_SIGBUS;
- if (substream->ops->page)
- page = substream->ops->page(substream, offset);
- else
- page = snd_pcm_default_page_ops(substream, offset);
- if (!page)
- return VM_FAULT_SIGBUS;
- get_page(page);
- vmf->page = page;
- return 0;
-}
-
-static const struct vm_operations_struct snd_pcm_vm_ops_data = {
- .open = snd_pcm_mmap_data_open,
- .close = snd_pcm_mmap_data_close,
-};
-
-static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = {
- .open = snd_pcm_mmap_data_open,
- .close = snd_pcm_mmap_data_close,
- .fault = snd_pcm_mmap_data_fault,
-};
-
-#ifndef ARCH_HAS_DMA_MMAP_COHERENT
-/* This should be defined / handled globally! */
-#ifdef CONFIG_ARM
-#define ARCH_HAS_DMA_MMAP_COHERENT
-#endif
-#endif
-
-/*
- * mmap the DMA buffer on RAM
- */
-int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *area)
-{
- area->vm_flags |= VM_RESERVED;
-#ifdef ARCH_HAS_DMA_MMAP_COHERENT
- if (!substream->ops->page &&
- substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV)
- return dma_mmap_coherent(substream->dma_buffer.dev.dev,
- area,
- substream->runtime->dma_area,
- substream->runtime->dma_addr,
- area->vm_end - area->vm_start);
-#elif defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
- if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV &&
- !plat_device_is_coherent(substream->dma_buffer.dev.dev))
- area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
-#endif /* ARCH_HAS_DMA_MMAP_COHERENT */
- /* mmap with fault handler */
- area->vm_ops = &snd_pcm_vm_ops_data_fault;
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_pcm_lib_default_mmap);
-
-/*
- * mmap the DMA buffer on I/O memory area
- */
-#if SNDRV_PCM_INFO_MMAP_IOMEM
-int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
- struct vm_area_struct *area)
-{
- long size;
- unsigned long offset;
-
- area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
- area->vm_flags |= VM_IO;
- size = area->vm_end - area->vm_start;
- offset = area->vm_pgoff << PAGE_SHIFT;
- if (io_remap_pfn_range(area, area->vm_start,
- (substream->runtime->dma_addr + offset) >> PAGE_SHIFT,
- size, area->vm_page_prot))
- return -EAGAIN;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem);
-#endif /* SNDRV_PCM_INFO_MMAP */
-
-/*
- * mmap DMA buffer
- */
-int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
- struct vm_area_struct *area)
-{
- struct snd_pcm_runtime *runtime;
- long size;
- unsigned long offset;
- size_t dma_bytes;
- int err;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (!(area->vm_flags & (VM_WRITE|VM_READ)))
- return -EINVAL;
- } else {
- if (!(area->vm_flags & VM_READ))
- return -EINVAL;
- }
- runtime = substream->runtime;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
- return -EBADFD;
- if (!(runtime->info & SNDRV_PCM_INFO_MMAP))
- return -ENXIO;
- if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED ||
- runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
- return -EINVAL;
- size = area->vm_end - area->vm_start;
- offset = area->vm_pgoff << PAGE_SHIFT;
- dma_bytes = PAGE_ALIGN(runtime->dma_bytes);
- if ((size_t)size > dma_bytes)
- return -EINVAL;
- if (offset > dma_bytes - size)
- return -EINVAL;
-
- area->vm_ops = &snd_pcm_vm_ops_data;
- area->vm_private_data = substream;
- if (substream->ops->mmap)
- err = substream->ops->mmap(substream, area);
- else
- err = snd_pcm_lib_default_mmap(substream, area);
- if (!err)
- atomic_inc(&substream->mmap_count);
- return err;
-}
-
-EXPORT_SYMBOL(snd_pcm_mmap_data);
-
-static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area)
-{
- struct snd_pcm_file * pcm_file;
- struct snd_pcm_substream *substream;
- unsigned long offset;
-
- pcm_file = file->private_data;
- substream = pcm_file->substream;
- if (PCM_RUNTIME_CHECK(substream))
- return -ENXIO;
-
- offset = area->vm_pgoff << PAGE_SHIFT;
- switch (offset) {
- case SNDRV_PCM_MMAP_OFFSET_STATUS:
- if (pcm_file->no_compat_mmap)
- return -ENXIO;
- return snd_pcm_mmap_status(substream, file, area);
- case SNDRV_PCM_MMAP_OFFSET_CONTROL:
- if (pcm_file->no_compat_mmap)
- return -ENXIO;
- return snd_pcm_mmap_control(substream, file, area);
- default:
- return snd_pcm_mmap_data(substream, file, area);
- }
- return 0;
-}
-
-static int snd_pcm_fasync(int fd, struct file * file, int on)
-{
- struct snd_pcm_file * pcm_file;
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
-
- pcm_file = file->private_data;
- substream = pcm_file->substream;
- if (PCM_RUNTIME_CHECK(substream))
- return -ENXIO;
- runtime = substream->runtime;
- return fasync_helper(fd, file, on, &runtime->fasync);
-}
-
-/*
- * ioctl32 compat
- */
-#ifdef CONFIG_COMPAT
-#include "pcm_compat.c"
-#else
-#define snd_pcm_ioctl_compat NULL
-#endif
-
-/*
- * To be removed helpers to keep binary compatibility
- */
-
-#ifdef CONFIG_SND_SUPPORT_OLD_API
-#define __OLD_TO_NEW_MASK(x) ((x&7)|((x&0x07fffff8)<<5))
-#define __NEW_TO_OLD_MASK(x) ((x&7)|((x&0xffffff00)>>5))
-
-static void snd_pcm_hw_convert_from_old_params(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_params_old *oparams)
-{
- unsigned int i;
-
- memset(params, 0, sizeof(*params));
- params->flags = oparams->flags;
- for (i = 0; i < ARRAY_SIZE(oparams->masks); i++)
- params->masks[i].bits[0] = oparams->masks[i];
- memcpy(params->intervals, oparams->intervals, sizeof(oparams->intervals));
- params->rmask = __OLD_TO_NEW_MASK(oparams->rmask);
- params->cmask = __OLD_TO_NEW_MASK(oparams->cmask);
- params->info = oparams->info;
- params->msbits = oparams->msbits;
- params->rate_num = oparams->rate_num;
- params->rate_den = oparams->rate_den;
- params->fifo_size = oparams->fifo_size;
-}
-
-static void snd_pcm_hw_convert_to_old_params(struct snd_pcm_hw_params_old *oparams,
- struct snd_pcm_hw_params *params)
-{
- unsigned int i;
-
- memset(oparams, 0, sizeof(*oparams));
- oparams->flags = params->flags;
- for (i = 0; i < ARRAY_SIZE(oparams->masks); i++)
- oparams->masks[i] = params->masks[i].bits[0];
- memcpy(oparams->intervals, params->intervals, sizeof(oparams->intervals));
- oparams->rmask = __NEW_TO_OLD_MASK(params->rmask);
- oparams->cmask = __NEW_TO_OLD_MASK(params->cmask);
- oparams->info = params->info;
- oparams->msbits = params->msbits;
- oparams->rate_num = params->rate_num;
- oparams->rate_den = params->rate_den;
- oparams->fifo_size = params->fifo_size;
-}
-
-static int snd_pcm_hw_refine_old_user(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params_old __user * _oparams)
-{
- struct snd_pcm_hw_params *params;
- struct snd_pcm_hw_params_old *oparams = NULL;
- int err;
-
- params = kmalloc(sizeof(*params), GFP_KERNEL);
- if (!params)
- return -ENOMEM;
-
- oparams = memdup_user(_oparams, sizeof(*oparams));
- if (IS_ERR(oparams)) {
- err = PTR_ERR(oparams);
- goto out;
- }
- snd_pcm_hw_convert_from_old_params(params, oparams);
- err = snd_pcm_hw_refine(substream, params);
- snd_pcm_hw_convert_to_old_params(oparams, params);
- if (copy_to_user(_oparams, oparams, sizeof(*oparams))) {
- if (!err)
- err = -EFAULT;
- }
-
- kfree(oparams);
-out:
- kfree(params);
- return err;
-}
-
-static int snd_pcm_hw_params_old_user(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params_old __user * _oparams)
-{
- struct snd_pcm_hw_params *params;
- struct snd_pcm_hw_params_old *oparams = NULL;
- int err;
-
- params = kmalloc(sizeof(*params), GFP_KERNEL);
- if (!params)
- return -ENOMEM;
-
- oparams = memdup_user(_oparams, sizeof(*oparams));
- if (IS_ERR(oparams)) {
- err = PTR_ERR(oparams);
- goto out;
- }
- snd_pcm_hw_convert_from_old_params(params, oparams);
- err = snd_pcm_hw_params(substream, params);
- snd_pcm_hw_convert_to_old_params(oparams, params);
- if (copy_to_user(_oparams, oparams, sizeof(*oparams))) {
- if (!err)
- err = -EFAULT;
- }
-
- kfree(oparams);
-out:
- kfree(params);
- return err;
-}
-#endif /* CONFIG_SND_SUPPORT_OLD_API */
-
-#ifndef CONFIG_MMU
-static unsigned long snd_pcm_get_unmapped_area(struct file *file,
- unsigned long addr,
- unsigned long len,
- unsigned long pgoff,
- unsigned long flags)
-{
- struct snd_pcm_file *pcm_file = file->private_data;
- struct snd_pcm_substream *substream = pcm_file->substream;
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long offset = pgoff << PAGE_SHIFT;
-
- switch (offset) {
- case SNDRV_PCM_MMAP_OFFSET_STATUS:
- return (unsigned long)runtime->status;
- case SNDRV_PCM_MMAP_OFFSET_CONTROL:
- return (unsigned long)runtime->control;
- default:
- return (unsigned long)runtime->dma_area + offset;
- }
-}
-#else
-# define snd_pcm_get_unmapped_area NULL
-#endif
-
-/*
- * Register section
- */
-
-const struct file_operations snd_pcm_f_ops[2] = {
- {
- .owner = THIS_MODULE,
- .write = snd_pcm_write,
- .aio_write = snd_pcm_aio_write,
- .open = snd_pcm_playback_open,
- .release = snd_pcm_release,
- .llseek = no_llseek,
- .poll = snd_pcm_playback_poll,
- .unlocked_ioctl = snd_pcm_playback_ioctl,
- .compat_ioctl = snd_pcm_ioctl_compat,
- .mmap = snd_pcm_mmap,
- .fasync = snd_pcm_fasync,
- .get_unmapped_area = snd_pcm_get_unmapped_area,
- },
- {
- .owner = THIS_MODULE,
- .read = snd_pcm_read,
- .aio_read = snd_pcm_aio_read,
- .open = snd_pcm_capture_open,
- .release = snd_pcm_release,
- .llseek = no_llseek,
- .poll = snd_pcm_capture_poll,
- .unlocked_ioctl = snd_pcm_capture_ioctl,
- .compat_ioctl = snd_pcm_ioctl_compat,
- .mmap = snd_pcm_mmap,
- .fasync = snd_pcm_fasync,
- .get_unmapped_area = snd_pcm_get_unmapped_area,
- }
-};
diff --git a/ANDROID_3.4.5/sound/core/pcm_timer.c b/ANDROID_3.4.5/sound/core/pcm_timer.c
deleted file mode 100644
index b01d9481..00000000
--- a/ANDROID_3.4.5/sound/core/pcm_timer.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Digital Audio (PCM) abstract layer
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <linux/gcd.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/timer.h>
-
-/*
- * Timer functions
- */
-
-void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream)
-{
- unsigned long rate, mult, fsize, l, post;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- mult = 1000000000;
- rate = runtime->rate;
- if (snd_BUG_ON(!rate))
- return;
- l = gcd(mult, rate);
- mult /= l;
- rate /= l;
- fsize = runtime->period_size;
- if (snd_BUG_ON(!fsize))
- return;
- l = gcd(rate, fsize);
- rate /= l;
- fsize /= l;
- post = 1;
- while ((mult * fsize) / fsize != mult) {
- mult /= 2;
- post *= 2;
- }
- if (rate == 0) {
- snd_printk(KERN_ERR "pcm timer resolution out of range (rate = %u, period_size = %lu)\n", runtime->rate, runtime->period_size);
- runtime->timer_resolution = -1;
- return;
- }
- runtime->timer_resolution = (mult * fsize / rate) * post;
-}
-
-static unsigned long snd_pcm_timer_resolution(struct snd_timer * timer)
-{
- struct snd_pcm_substream *substream;
-
- substream = timer->private_data;
- return substream->runtime ? substream->runtime->timer_resolution : 0;
-}
-
-static int snd_pcm_timer_start(struct snd_timer * timer)
-{
- struct snd_pcm_substream *substream;
-
- substream = snd_timer_chip(timer);
- substream->timer_running = 1;
- return 0;
-}
-
-static int snd_pcm_timer_stop(struct snd_timer * timer)
-{
- struct snd_pcm_substream *substream;
-
- substream = snd_timer_chip(timer);
- substream->timer_running = 0;
- return 0;
-}
-
-static struct snd_timer_hardware snd_pcm_timer =
-{
- .flags = SNDRV_TIMER_HW_AUTO | SNDRV_TIMER_HW_SLAVE,
- .resolution = 0,
- .ticks = 1,
- .c_resolution = snd_pcm_timer_resolution,
- .start = snd_pcm_timer_start,
- .stop = snd_pcm_timer_stop,
-};
-
-/*
- * Init functions
- */
-
-static void snd_pcm_timer_free(struct snd_timer *timer)
-{
- struct snd_pcm_substream *substream = timer->private_data;
- substream->timer = NULL;
-}
-
-void snd_pcm_timer_init(struct snd_pcm_substream *substream)
-{
- struct snd_timer_id tid;
- struct snd_timer *timer;
-
- tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
- tid.dev_class = SNDRV_TIMER_CLASS_PCM;
- tid.card = substream->pcm->card->number;
- tid.device = substream->pcm->device;
- tid.subdevice = (substream->number << 1) | (substream->stream & 1);
- if (snd_timer_new(substream->pcm->card, "PCM", &tid, &timer) < 0)
- return;
- sprintf(timer->name, "PCM %s %i-%i-%i",
- substream->stream == SNDRV_PCM_STREAM_CAPTURE ?
- "capture" : "playback",
- tid.card, tid.device, tid.subdevice);
- timer->hw = snd_pcm_timer;
- if (snd_device_register(timer->card, timer) < 0) {
- snd_device_free(timer->card, timer);
- return;
- }
- timer->private_data = substream;
- timer->private_free = snd_pcm_timer_free;
- substream->timer = timer;
-}
-
-void snd_pcm_timer_done(struct snd_pcm_substream *substream)
-{
- if (substream->timer) {
- snd_device_free(substream->pcm->card, substream->timer);
- substream->timer = NULL;
- }
-}
diff --git a/ANDROID_3.4.5/sound/core/rawmidi.c b/ANDROID_3.4.5/sound/core/rawmidi.c
deleted file mode 100644
index 1bb95aee..00000000
--- a/ANDROID_3.4.5/sound/core/rawmidi.c
+++ /dev/null
@@ -1,1726 +0,0 @@
-/*
- * Abstract layer for MIDI v1.0 stream
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <sound/core.h>
-#include <linux/major.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/mutex.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <sound/rawmidi.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/minors.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Midlevel RawMidi code for ALSA.");
-MODULE_LICENSE("GPL");
-
-#ifdef CONFIG_SND_OSSEMUL
-static int midi_map[SNDRV_CARDS];
-static int amidi_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
-module_param_array(midi_map, int, NULL, 0444);
-MODULE_PARM_DESC(midi_map, "Raw MIDI device number assigned to 1st OSS device.");
-module_param_array(amidi_map, int, NULL, 0444);
-MODULE_PARM_DESC(amidi_map, "Raw MIDI device number assigned to 2nd OSS device.");
-#endif /* CONFIG_SND_OSSEMUL */
-
-static int snd_rawmidi_free(struct snd_rawmidi *rawmidi);
-static int snd_rawmidi_dev_free(struct snd_device *device);
-static int snd_rawmidi_dev_register(struct snd_device *device);
-static int snd_rawmidi_dev_disconnect(struct snd_device *device);
-
-static LIST_HEAD(snd_rawmidi_devices);
-static DEFINE_MUTEX(register_mutex);
-
-static struct snd_rawmidi *snd_rawmidi_search(struct snd_card *card, int device)
-{
- struct snd_rawmidi *rawmidi;
-
- list_for_each_entry(rawmidi, &snd_rawmidi_devices, list)
- if (rawmidi->card == card && rawmidi->device == device)
- return rawmidi;
- return NULL;
-}
-
-static inline unsigned short snd_rawmidi_file_flags(struct file *file)
-{
- switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) {
- case FMODE_WRITE:
- return SNDRV_RAWMIDI_LFLG_OUTPUT;
- case FMODE_READ:
- return SNDRV_RAWMIDI_LFLG_INPUT;
- default:
- return SNDRV_RAWMIDI_LFLG_OPEN;
- }
-}
-
-static inline int snd_rawmidi_ready(struct snd_rawmidi_substream *substream)
-{
- struct snd_rawmidi_runtime *runtime = substream->runtime;
- return runtime->avail >= runtime->avail_min;
-}
-
-static inline int snd_rawmidi_ready_append(struct snd_rawmidi_substream *substream,
- size_t count)
-{
- struct snd_rawmidi_runtime *runtime = substream->runtime;
- return runtime->avail >= runtime->avail_min &&
- (!substream->append || runtime->avail >= count);
-}
-
-static void snd_rawmidi_input_event_work(struct work_struct *work)
-{
- struct snd_rawmidi_runtime *runtime =
- container_of(work, struct snd_rawmidi_runtime, event_work);
- if (runtime->event)
- runtime->event(runtime->substream);
-}
-
-static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
-{
- struct snd_rawmidi_runtime *runtime;
-
- if ((runtime = kzalloc(sizeof(*runtime), GFP_KERNEL)) == NULL)
- return -ENOMEM;
- runtime->substream = substream;
- spin_lock_init(&runtime->lock);
- init_waitqueue_head(&runtime->sleep);
- INIT_WORK(&runtime->event_work, snd_rawmidi_input_event_work);
- runtime->event = NULL;
- runtime->buffer_size = PAGE_SIZE;
- runtime->avail_min = 1;
- if (substream->stream == SNDRV_RAWMIDI_STREAM_INPUT)
- runtime->avail = 0;
- else
- runtime->avail = runtime->buffer_size;
- if ((runtime->buffer = kmalloc(runtime->buffer_size, GFP_KERNEL)) == NULL) {
- kfree(runtime);
- return -ENOMEM;
- }
- runtime->appl_ptr = runtime->hw_ptr = 0;
- substream->runtime = runtime;
- return 0;
-}
-
-static int snd_rawmidi_runtime_free(struct snd_rawmidi_substream *substream)
-{
- struct snd_rawmidi_runtime *runtime = substream->runtime;
-
- kfree(runtime->buffer);
- kfree(runtime);
- substream->runtime = NULL;
- return 0;
-}
-
-static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *substream,int up)
-{
- if (!substream->opened)
- return;
- substream->ops->trigger(substream, up);
-}
-
-static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- if (!substream->opened)
- return;
- substream->ops->trigger(substream, up);
- if (!up)
- cancel_work_sync(&substream->runtime->event_work);
-}
-
-int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- struct snd_rawmidi_runtime *runtime = substream->runtime;
-
- snd_rawmidi_output_trigger(substream, 0);
- runtime->drain = 0;
- spin_lock_irqsave(&runtime->lock, flags);
- runtime->appl_ptr = runtime->hw_ptr = 0;
- runtime->avail = runtime->buffer_size;
- spin_unlock_irqrestore(&runtime->lock, flags);
- return 0;
-}
-
-int snd_rawmidi_drain_output(struct snd_rawmidi_substream *substream)
-{
- int err;
- long timeout;
- struct snd_rawmidi_runtime *runtime = substream->runtime;
-
- err = 0;
- runtime->drain = 1;
- timeout = wait_event_interruptible_timeout(runtime->sleep,
- (runtime->avail >= runtime->buffer_size),
- 10*HZ);
- if (signal_pending(current))
- err = -ERESTARTSYS;
- if (runtime->avail < runtime->buffer_size && !timeout) {
- snd_printk(KERN_WARNING "rawmidi drain error (avail = %li, buffer_size = %li)\n", (long)runtime->avail, (long)runtime->buffer_size);
- err = -EIO;
- }
- runtime->drain = 0;
- if (err != -ERESTARTSYS) {
- /* we need wait a while to make sure that Tx FIFOs are empty */
- if (substream->ops->drain)
- substream->ops->drain(substream);
- else
- msleep(50);
- snd_rawmidi_drop_output(substream);
- }
- return err;
-}
-
-int snd_rawmidi_drain_input(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- struct snd_rawmidi_runtime *runtime = substream->runtime;
-
- snd_rawmidi_input_trigger(substream, 0);
- runtime->drain = 0;
- spin_lock_irqsave(&runtime->lock, flags);
- runtime->appl_ptr = runtime->hw_ptr = 0;
- runtime->avail = 0;
- spin_unlock_irqrestore(&runtime->lock, flags);
- return 0;
-}
-
-/* look for an available substream for the given stream direction;
- * if a specific subdevice is given, try to assign it
- */
-static int assign_substream(struct snd_rawmidi *rmidi, int subdevice,
- int stream, int mode,
- struct snd_rawmidi_substream **sub_ret)
-{
- struct snd_rawmidi_substream *substream;
- struct snd_rawmidi_str *s = &rmidi->streams[stream];
- static unsigned int info_flags[2] = {
- [SNDRV_RAWMIDI_STREAM_OUTPUT] = SNDRV_RAWMIDI_INFO_OUTPUT,
- [SNDRV_RAWMIDI_STREAM_INPUT] = SNDRV_RAWMIDI_INFO_INPUT,
- };
-
- if (!(rmidi->info_flags & info_flags[stream]))
- return -ENXIO;
- if (subdevice >= 0 && subdevice >= s->substream_count)
- return -ENODEV;
-
- list_for_each_entry(substream, &s->substreams, list) {
- if (substream->opened) {
- if (stream == SNDRV_RAWMIDI_STREAM_INPUT ||
- !(mode & SNDRV_RAWMIDI_LFLG_APPEND) ||
- !substream->append)
- continue;
- }
- if (subdevice < 0 || subdevice == substream->number) {
- *sub_ret = substream;
- return 0;
- }
- }
- return -EAGAIN;
-}
-
-/* open and do ref-counting for the given substream */
-static int open_substream(struct snd_rawmidi *rmidi,
- struct snd_rawmidi_substream *substream,
- int mode)
-{
- int err;
-
- if (substream->use_count == 0) {
- err = snd_rawmidi_runtime_create(substream);
- if (err < 0)
- return err;
- err = substream->ops->open(substream);
- if (err < 0) {
- snd_rawmidi_runtime_free(substream);
- return err;
- }
- substream->opened = 1;
- substream->active_sensing = 0;
- if (mode & SNDRV_RAWMIDI_LFLG_APPEND)
- substream->append = 1;
- substream->pid = get_pid(task_pid(current));
- rmidi->streams[substream->stream].substream_opened++;
- }
- substream->use_count++;
- return 0;
-}
-
-static void close_substream(struct snd_rawmidi *rmidi,
- struct snd_rawmidi_substream *substream,
- int cleanup);
-
-static int rawmidi_open_priv(struct snd_rawmidi *rmidi, int subdevice, int mode,
- struct snd_rawmidi_file *rfile)
-{
- struct snd_rawmidi_substream *sinput = NULL, *soutput = NULL;
- int err;
-
- rfile->input = rfile->output = NULL;
- if (mode & SNDRV_RAWMIDI_LFLG_INPUT) {
- err = assign_substream(rmidi, subdevice,
- SNDRV_RAWMIDI_STREAM_INPUT,
- mode, &sinput);
- if (err < 0)
- return err;
- }
- if (mode & SNDRV_RAWMIDI_LFLG_OUTPUT) {
- err = assign_substream(rmidi, subdevice,
- SNDRV_RAWMIDI_STREAM_OUTPUT,
- mode, &soutput);
- if (err < 0)
- return err;
- }
-
- if (sinput) {
- err = open_substream(rmidi, sinput, mode);
- if (err < 0)
- return err;
- }
- if (soutput) {
- err = open_substream(rmidi, soutput, mode);
- if (err < 0) {
- if (sinput)
- close_substream(rmidi, sinput, 0);
- return err;
- }
- }
-
- rfile->rmidi = rmidi;
- rfile->input = sinput;
- rfile->output = soutput;
- return 0;
-}
-
-/* called from sound/core/seq/seq_midi.c */
-int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
- int mode, struct snd_rawmidi_file * rfile)
-{
- struct snd_rawmidi *rmidi;
- int err;
-
- if (snd_BUG_ON(!rfile))
- return -EINVAL;
-
- mutex_lock(&register_mutex);
- rmidi = snd_rawmidi_search(card, device);
- if (rmidi == NULL) {
- mutex_unlock(&register_mutex);
- return -ENODEV;
- }
- if (!try_module_get(rmidi->card->module)) {
- mutex_unlock(&register_mutex);
- return -ENXIO;
- }
- mutex_unlock(&register_mutex);
-
- mutex_lock(&rmidi->open_mutex);
- err = rawmidi_open_priv(rmidi, subdevice, mode, rfile);
- mutex_unlock(&rmidi->open_mutex);
- if (err < 0)
- module_put(rmidi->card->module);
- return err;
-}
-
-static int snd_rawmidi_open(struct inode *inode, struct file *file)
-{
- int maj = imajor(inode);
- struct snd_card *card;
- int subdevice;
- unsigned short fflags;
- int err;
- struct snd_rawmidi *rmidi;
- struct snd_rawmidi_file *rawmidi_file = NULL;
- wait_queue_t wait;
- struct snd_ctl_file *kctl;
-
- if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK))
- return -EINVAL; /* invalid combination */
-
- err = nonseekable_open(inode, file);
- if (err < 0)
- return err;
-
- if (maj == snd_major) {
- rmidi = snd_lookup_minor_data(iminor(inode),
- SNDRV_DEVICE_TYPE_RAWMIDI);
-#ifdef CONFIG_SND_OSSEMUL
- } else if (maj == SOUND_MAJOR) {
- rmidi = snd_lookup_oss_minor_data(iminor(inode),
- SNDRV_OSS_DEVICE_TYPE_MIDI);
-#endif
- } else
- return -ENXIO;
-
- if (rmidi == NULL)
- return -ENODEV;
-
- if (!try_module_get(rmidi->card->module)) {
- snd_card_unref(rmidi->card);
- return -ENXIO;
- }
-
- mutex_lock(&rmidi->open_mutex);
- card = rmidi->card;
- err = snd_card_file_add(card, file);
- if (err < 0)
- goto __error_card;
- fflags = snd_rawmidi_file_flags(file);
- if ((file->f_flags & O_APPEND) || maj == SOUND_MAJOR) /* OSS emul? */
- fflags |= SNDRV_RAWMIDI_LFLG_APPEND;
- rawmidi_file = kmalloc(sizeof(*rawmidi_file), GFP_KERNEL);
- if (rawmidi_file == NULL) {
- err = -ENOMEM;
- goto __error;
- }
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&rmidi->open_wait, &wait);
- while (1) {
- subdevice = -1;
- read_lock(&card->ctl_files_rwlock);
- list_for_each_entry(kctl, &card->ctl_files, list) {
- if (kctl->pid == task_pid(current)) {
- subdevice = kctl->prefer_rawmidi_subdevice;
- if (subdevice != -1)
- break;
- }
- }
- read_unlock(&card->ctl_files_rwlock);
- err = rawmidi_open_priv(rmidi, subdevice, fflags, rawmidi_file);
- if (err >= 0)
- break;
- if (err == -EAGAIN) {
- if (file->f_flags & O_NONBLOCK) {
- err = -EBUSY;
- break;
- }
- } else
- break;
- set_current_state(TASK_INTERRUPTIBLE);
- mutex_unlock(&rmidi->open_mutex);
- schedule();
- mutex_lock(&rmidi->open_mutex);
- if (rmidi->card->shutdown) {
- err = -ENODEV;
- break;
- }
- if (signal_pending(current)) {
- err = -ERESTARTSYS;
- break;
- }
- }
- remove_wait_queue(&rmidi->open_wait, &wait);
- if (err < 0) {
- kfree(rawmidi_file);
- goto __error;
- }
-#ifdef CONFIG_SND_OSSEMUL
- if (rawmidi_file->input && rawmidi_file->input->runtime)
- rawmidi_file->input->runtime->oss = (maj == SOUND_MAJOR);
- if (rawmidi_file->output && rawmidi_file->output->runtime)
- rawmidi_file->output->runtime->oss = (maj == SOUND_MAJOR);
-#endif
- file->private_data = rawmidi_file;
- mutex_unlock(&rmidi->open_mutex);
- snd_card_unref(rmidi->card);
- return 0;
-
- __error:
- snd_card_file_remove(card, file);
- __error_card:
- mutex_unlock(&rmidi->open_mutex);
- module_put(rmidi->card->module);
- snd_card_unref(rmidi->card);
- return err;
-}
-
-static void close_substream(struct snd_rawmidi *rmidi,
- struct snd_rawmidi_substream *substream,
- int cleanup)
-{
- if (--substream->use_count)
- return;
-
- if (cleanup) {
- if (substream->stream == SNDRV_RAWMIDI_STREAM_INPUT)
- snd_rawmidi_input_trigger(substream, 0);
- else {
- if (substream->active_sensing) {
- unsigned char buf = 0xfe;
- /* sending single active sensing message
- * to shut the device up
- */
- snd_rawmidi_kernel_write(substream, &buf, 1);
- }
- if (snd_rawmidi_drain_output(substream) == -ERESTARTSYS)
- snd_rawmidi_output_trigger(substream, 0);
- }
- }
- substream->ops->close(substream);
- if (substream->runtime->private_free)
- substream->runtime->private_free(substream);
- snd_rawmidi_runtime_free(substream);
- substream->opened = 0;
- substream->append = 0;
- put_pid(substream->pid);
- substream->pid = NULL;
- rmidi->streams[substream->stream].substream_opened--;
-}
-
-static void rawmidi_release_priv(struct snd_rawmidi_file *rfile)
-{
- struct snd_rawmidi *rmidi;
-
- rmidi = rfile->rmidi;
- mutex_lock(&rmidi->open_mutex);
- if (rfile->input) {
- close_substream(rmidi, rfile->input, 1);
- rfile->input = NULL;
- }
- if (rfile->output) {
- close_substream(rmidi, rfile->output, 1);
- rfile->output = NULL;
- }
- rfile->rmidi = NULL;
- mutex_unlock(&rmidi->open_mutex);
- wake_up(&rmidi->open_wait);
-}
-
-/* called from sound/core/seq/seq_midi.c */
-int snd_rawmidi_kernel_release(struct snd_rawmidi_file *rfile)
-{
- struct snd_rawmidi *rmidi;
-
- if (snd_BUG_ON(!rfile))
- return -ENXIO;
-
- rmidi = rfile->rmidi;
- rawmidi_release_priv(rfile);
- module_put(rmidi->card->module);
- return 0;
-}
-
-static int snd_rawmidi_release(struct inode *inode, struct file *file)
-{
- struct snd_rawmidi_file *rfile;
- struct snd_rawmidi *rmidi;
- struct module *module;
-
- rfile = file->private_data;
- rmidi = rfile->rmidi;
- rawmidi_release_priv(rfile);
- kfree(rfile);
- module = rmidi->card->module;
- snd_card_file_remove(rmidi->card, file);
- module_put(module);
- return 0;
-}
-
-static int snd_rawmidi_info(struct snd_rawmidi_substream *substream,
- struct snd_rawmidi_info *info)
-{
- struct snd_rawmidi *rmidi;
-
- if (substream == NULL)
- return -ENODEV;
- rmidi = substream->rmidi;
- memset(info, 0, sizeof(*info));
- info->card = rmidi->card->number;
- info->device = rmidi->device;
- info->subdevice = substream->number;
- info->stream = substream->stream;
- info->flags = rmidi->info_flags;
- strcpy(info->id, rmidi->id);
- strcpy(info->name, rmidi->name);
- strcpy(info->subname, substream->name);
- info->subdevices_count = substream->pstr->substream_count;
- info->subdevices_avail = (substream->pstr->substream_count -
- substream->pstr->substream_opened);
- return 0;
-}
-
-static int snd_rawmidi_info_user(struct snd_rawmidi_substream *substream,
- struct snd_rawmidi_info __user * _info)
-{
- struct snd_rawmidi_info info;
- int err;
- if ((err = snd_rawmidi_info(substream, &info)) < 0)
- return err;
- if (copy_to_user(_info, &info, sizeof(struct snd_rawmidi_info)))
- return -EFAULT;
- return 0;
-}
-
-int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info)
-{
- struct snd_rawmidi *rmidi;
- struct snd_rawmidi_str *pstr;
- struct snd_rawmidi_substream *substream;
-
- mutex_lock(&register_mutex);
- rmidi = snd_rawmidi_search(card, info->device);
- mutex_unlock(&register_mutex);
- if (!rmidi)
- return -ENXIO;
- if (info->stream < 0 || info->stream > 1)
- return -EINVAL;
- pstr = &rmidi->streams[info->stream];
- if (pstr->substream_count == 0)
- return -ENOENT;
- if (info->subdevice >= pstr->substream_count)
- return -ENXIO;
- list_for_each_entry(substream, &pstr->substreams, list) {
- if ((unsigned int)substream->number == info->subdevice)
- return snd_rawmidi_info(substream, info);
- }
- return -ENXIO;
-}
-
-static int snd_rawmidi_info_select_user(struct snd_card *card,
- struct snd_rawmidi_info __user *_info)
-{
- int err;
- struct snd_rawmidi_info info;
- if (get_user(info.device, &_info->device))
- return -EFAULT;
- if (get_user(info.stream, &_info->stream))
- return -EFAULT;
- if (get_user(info.subdevice, &_info->subdevice))
- return -EFAULT;
- if ((err = snd_rawmidi_info_select(card, &info)) < 0)
- return err;
- if (copy_to_user(_info, &info, sizeof(struct snd_rawmidi_info)))
- return -EFAULT;
- return 0;
-}
-
-int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
- struct snd_rawmidi_params * params)
-{
- char *newbuf;
- struct snd_rawmidi_runtime *runtime = substream->runtime;
-
- if (substream->append && substream->use_count > 1)
- return -EBUSY;
- snd_rawmidi_drain_output(substream);
- if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) {
- return -EINVAL;
- }
- if (params->avail_min < 1 || params->avail_min > params->buffer_size) {
- return -EINVAL;
- }
- if (params->buffer_size != runtime->buffer_size) {
- newbuf = krealloc(runtime->buffer, params->buffer_size,
- GFP_KERNEL);
- if (!newbuf)
- return -ENOMEM;
- runtime->buffer = newbuf;
- runtime->buffer_size = params->buffer_size;
- runtime->avail = runtime->buffer_size;
- }
- runtime->avail_min = params->avail_min;
- substream->active_sensing = !params->no_active_sensing;
- return 0;
-}
-
-int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,
- struct snd_rawmidi_params * params)
-{
- char *newbuf;
- struct snd_rawmidi_runtime *runtime = substream->runtime;
-
- snd_rawmidi_drain_input(substream);
- if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) {
- return -EINVAL;
- }
- if (params->avail_min < 1 || params->avail_min > params->buffer_size) {
- return -EINVAL;
- }
- if (params->buffer_size != runtime->buffer_size) {
- newbuf = krealloc(runtime->buffer, params->buffer_size,
- GFP_KERNEL);
- if (!newbuf)
- return -ENOMEM;
- runtime->buffer = newbuf;
- runtime->buffer_size = params->buffer_size;
- }
- runtime->avail_min = params->avail_min;
- return 0;
-}
-
-static int snd_rawmidi_output_status(struct snd_rawmidi_substream *substream,
- struct snd_rawmidi_status * status)
-{
- struct snd_rawmidi_runtime *runtime = substream->runtime;
-
- memset(status, 0, sizeof(*status));
- status->stream = SNDRV_RAWMIDI_STREAM_OUTPUT;
- spin_lock_irq(&runtime->lock);
- status->avail = runtime->avail;
- spin_unlock_irq(&runtime->lock);
- return 0;
-}
-
-static int snd_rawmidi_input_status(struct snd_rawmidi_substream *substream,
- struct snd_rawmidi_status * status)
-{
- struct snd_rawmidi_runtime *runtime = substream->runtime;
-
- memset(status, 0, sizeof(*status));
- status->stream = SNDRV_RAWMIDI_STREAM_INPUT;
- spin_lock_irq(&runtime->lock);
- status->avail = runtime->avail;
- status->xruns = runtime->xruns;
- runtime->xruns = 0;
- spin_unlock_irq(&runtime->lock);
- return 0;
-}
-
-static long snd_rawmidi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct snd_rawmidi_file *rfile;
- void __user *argp = (void __user *)arg;
-
- rfile = file->private_data;
- if (((cmd >> 8) & 0xff) != 'W')
- return -ENOTTY;
- switch (cmd) {
- case SNDRV_RAWMIDI_IOCTL_PVERSION:
- return put_user(SNDRV_RAWMIDI_VERSION, (int __user *)argp) ? -EFAULT : 0;
- case SNDRV_RAWMIDI_IOCTL_INFO:
- {
- int stream;
- struct snd_rawmidi_info __user *info = argp;
- if (get_user(stream, &info->stream))
- return -EFAULT;
- switch (stream) {
- case SNDRV_RAWMIDI_STREAM_INPUT:
- return snd_rawmidi_info_user(rfile->input, info);
- case SNDRV_RAWMIDI_STREAM_OUTPUT:
- return snd_rawmidi_info_user(rfile->output, info);
- default:
- return -EINVAL;
- }
- }
- case SNDRV_RAWMIDI_IOCTL_PARAMS:
- {
- struct snd_rawmidi_params params;
- if (copy_from_user(&params, argp, sizeof(struct snd_rawmidi_params)))
- return -EFAULT;
- switch (params.stream) {
- case SNDRV_RAWMIDI_STREAM_OUTPUT:
- if (rfile->output == NULL)
- return -EINVAL;
- return snd_rawmidi_output_params(rfile->output, &params);
- case SNDRV_RAWMIDI_STREAM_INPUT:
- if (rfile->input == NULL)
- return -EINVAL;
- return snd_rawmidi_input_params(rfile->input, &params);
- default:
- return -EINVAL;
- }
- }
- case SNDRV_RAWMIDI_IOCTL_STATUS:
- {
- int err = 0;
- struct snd_rawmidi_status status;
- if (copy_from_user(&status, argp, sizeof(struct snd_rawmidi_status)))
- return -EFAULT;
- switch (status.stream) {
- case SNDRV_RAWMIDI_STREAM_OUTPUT:
- if (rfile->output == NULL)
- return -EINVAL;
- err = snd_rawmidi_output_status(rfile->output, &status);
- break;
- case SNDRV_RAWMIDI_STREAM_INPUT:
- if (rfile->input == NULL)
- return -EINVAL;
- err = snd_rawmidi_input_status(rfile->input, &status);
- break;
- default:
- return -EINVAL;
- }
- if (err < 0)
- return err;
- if (copy_to_user(argp, &status, sizeof(struct snd_rawmidi_status)))
- return -EFAULT;
- return 0;
- }
- case SNDRV_RAWMIDI_IOCTL_DROP:
- {
- int val;
- if (get_user(val, (int __user *) argp))
- return -EFAULT;
- switch (val) {
- case SNDRV_RAWMIDI_STREAM_OUTPUT:
- if (rfile->output == NULL)
- return -EINVAL;
- return snd_rawmidi_drop_output(rfile->output);
- default:
- return -EINVAL;
- }
- }
- case SNDRV_RAWMIDI_IOCTL_DRAIN:
- {
- int val;
- if (get_user(val, (int __user *) argp))
- return -EFAULT;
- switch (val) {
- case SNDRV_RAWMIDI_STREAM_OUTPUT:
- if (rfile->output == NULL)
- return -EINVAL;
- return snd_rawmidi_drain_output(rfile->output);
- case SNDRV_RAWMIDI_STREAM_INPUT:
- if (rfile->input == NULL)
- return -EINVAL;
- return snd_rawmidi_drain_input(rfile->input);
- default:
- return -EINVAL;
- }
- }
-#ifdef CONFIG_SND_DEBUG
- default:
- snd_printk(KERN_WARNING "rawmidi: unknown command = 0x%x\n", cmd);
-#endif
- }
- return -ENOTTY;
-}
-
-static int snd_rawmidi_control_ioctl(struct snd_card *card,
- struct snd_ctl_file *control,
- unsigned int cmd,
- unsigned long arg)
-{
- void __user *argp = (void __user *)arg;
-
- switch (cmd) {
- case SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE:
- {
- int device;
-
- if (get_user(device, (int __user *)argp))
- return -EFAULT;
- if (device >= SNDRV_RAWMIDI_DEVICES) /* next device is -1 */
- device = SNDRV_RAWMIDI_DEVICES - 1;
- mutex_lock(&register_mutex);
- device = device < 0 ? 0 : device + 1;
- while (device < SNDRV_RAWMIDI_DEVICES) {
- if (snd_rawmidi_search(card, device))
- break;
- device++;
- }
- if (device == SNDRV_RAWMIDI_DEVICES)
- device = -1;
- mutex_unlock(&register_mutex);
- if (put_user(device, (int __user *)argp))
- return -EFAULT;
- return 0;
- }
- case SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE:
- {
- int val;
-
- if (get_user(val, (int __user *)argp))
- return -EFAULT;
- control->prefer_rawmidi_subdevice = val;
- return 0;
- }
- case SNDRV_CTL_IOCTL_RAWMIDI_INFO:
- return snd_rawmidi_info_select_user(card, argp);
- }
- return -ENOIOCTLCMD;
-}
-
-/**
- * snd_rawmidi_receive - receive the input data from the device
- * @substream: the rawmidi substream
- * @buffer: the buffer pointer
- * @count: the data size to read
- *
- * Reads the data from the internal buffer.
- *
- * Returns the size of read data, or a negative error code on failure.
- */
-int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
- const unsigned char *buffer, int count)
-{
- unsigned long flags;
- int result = 0, count1;
- struct snd_rawmidi_runtime *runtime = substream->runtime;
-
- if (!substream->opened)
- return -EBADFD;
- if (runtime->buffer == NULL) {
- snd_printd("snd_rawmidi_receive: input is not active!!!\n");
- return -EINVAL;
- }
- spin_lock_irqsave(&runtime->lock, flags);
- if (count == 1) { /* special case, faster code */
- substream->bytes++;
- if (runtime->avail < runtime->buffer_size) {
- runtime->buffer[runtime->hw_ptr++] = buffer[0];
- runtime->hw_ptr %= runtime->buffer_size;
- runtime->avail++;
- result++;
- } else {
- runtime->xruns++;
- }
- } else {
- substream->bytes += count;
- count1 = runtime->buffer_size - runtime->hw_ptr;
- if (count1 > count)
- count1 = count;
- if (count1 > (int)(runtime->buffer_size - runtime->avail))
- count1 = runtime->buffer_size - runtime->avail;
- memcpy(runtime->buffer + runtime->hw_ptr, buffer, count1);
- runtime->hw_ptr += count1;
- runtime->hw_ptr %= runtime->buffer_size;
- runtime->avail += count1;
- count -= count1;
- result += count1;
- if (count > 0) {
- buffer += count1;
- count1 = count;
- if (count1 > (int)(runtime->buffer_size - runtime->avail)) {
- count1 = runtime->buffer_size - runtime->avail;
- runtime->xruns += count - count1;
- }
- if (count1 > 0) {
- memcpy(runtime->buffer, buffer, count1);
- runtime->hw_ptr = count1;
- runtime->avail += count1;
- result += count1;
- }
- }
- }
- if (result > 0) {
- if (runtime->event)
- schedule_work(&runtime->event_work);
- else if (snd_rawmidi_ready(substream))
- wake_up(&runtime->sleep);
- }
- spin_unlock_irqrestore(&runtime->lock, flags);
- return result;
-}
-
-static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream,
- unsigned char __user *userbuf,
- unsigned char *kernelbuf, long count)
-{
- unsigned long flags;
- long result = 0, count1;
- struct snd_rawmidi_runtime *runtime = substream->runtime;
-
- while (count > 0 && runtime->avail) {
- count1 = runtime->buffer_size - runtime->appl_ptr;
- if (count1 > count)
- count1 = count;
- spin_lock_irqsave(&runtime->lock, flags);
- if (count1 > (int)runtime->avail)
- count1 = runtime->avail;
- if (kernelbuf)
- memcpy(kernelbuf + result, runtime->buffer + runtime->appl_ptr, count1);
- if (userbuf) {
- spin_unlock_irqrestore(&runtime->lock, flags);
- if (copy_to_user(userbuf + result,
- runtime->buffer + runtime->appl_ptr, count1)) {
- return result > 0 ? result : -EFAULT;
- }
- spin_lock_irqsave(&runtime->lock, flags);
- }
- runtime->appl_ptr += count1;
- runtime->appl_ptr %= runtime->buffer_size;
- runtime->avail -= count1;
- spin_unlock_irqrestore(&runtime->lock, flags);
- result += count1;
- count -= count1;
- }
- return result;
-}
-
-long snd_rawmidi_kernel_read(struct snd_rawmidi_substream *substream,
- unsigned char *buf, long count)
-{
- snd_rawmidi_input_trigger(substream, 1);
- return snd_rawmidi_kernel_read1(substream, NULL/*userbuf*/, buf, count);
-}
-
-static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t count,
- loff_t *offset)
-{
- long result;
- int count1;
- struct snd_rawmidi_file *rfile;
- struct snd_rawmidi_substream *substream;
- struct snd_rawmidi_runtime *runtime;
-
- rfile = file->private_data;
- substream = rfile->input;
- if (substream == NULL)
- return -EIO;
- runtime = substream->runtime;
- snd_rawmidi_input_trigger(substream, 1);
- result = 0;
- while (count > 0) {
- spin_lock_irq(&runtime->lock);
- while (!snd_rawmidi_ready(substream)) {
- wait_queue_t wait;
- if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) {
- spin_unlock_irq(&runtime->lock);
- return result > 0 ? result : -EAGAIN;
- }
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&runtime->sleep, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
- spin_unlock_irq(&runtime->lock);
- schedule();
- remove_wait_queue(&runtime->sleep, &wait);
- if (rfile->rmidi->card->shutdown)
- return -ENODEV;
- if (signal_pending(current))
- return result > 0 ? result : -ERESTARTSYS;
- if (!runtime->avail)
- return result > 0 ? result : -EIO;
- spin_lock_irq(&runtime->lock);
- }
- spin_unlock_irq(&runtime->lock);
- count1 = snd_rawmidi_kernel_read1(substream,
- (unsigned char __user *)buf,
- NULL/*kernelbuf*/,
- count);
- if (count1 < 0)
- return result > 0 ? result : count1;
- result += count1;
- buf += count1;
- count -= count1;
- }
- return result;
-}
-
-/**
- * snd_rawmidi_transmit_empty - check whether the output buffer is empty
- * @substream: the rawmidi substream
- *
- * Returns 1 if the internal output buffer is empty, 0 if not.
- */
-int snd_rawmidi_transmit_empty(struct snd_rawmidi_substream *substream)
-{
- struct snd_rawmidi_runtime *runtime = substream->runtime;
- int result;
- unsigned long flags;
-
- if (runtime->buffer == NULL) {
- snd_printd("snd_rawmidi_transmit_empty: output is not active!!!\n");
- return 1;
- }
- spin_lock_irqsave(&runtime->lock, flags);
- result = runtime->avail >= runtime->buffer_size;
- spin_unlock_irqrestore(&runtime->lock, flags);
- return result;
-}
-
-/**
- * snd_rawmidi_transmit_peek - copy data from the internal buffer
- * @substream: the rawmidi substream
- * @buffer: the buffer pointer
- * @count: data size to transfer
- *
- * Copies data from the internal output buffer to the given buffer.
- *
- * Call this in the interrupt handler when the midi output is ready,
- * and call snd_rawmidi_transmit_ack() after the transmission is
- * finished.
- *
- * Returns the size of copied data, or a negative error code on failure.
- */
-int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
- unsigned char *buffer, int count)
-{
- unsigned long flags;
- int result, count1;
- struct snd_rawmidi_runtime *runtime = substream->runtime;
-
- if (runtime->buffer == NULL) {
- snd_printd("snd_rawmidi_transmit_peek: output is not active!!!\n");
- return -EINVAL;
- }
- result = 0;
- spin_lock_irqsave(&runtime->lock, flags);
- if (runtime->avail >= runtime->buffer_size) {
- /* warning: lowlevel layer MUST trigger down the hardware */
- goto __skip;
- }
- if (count == 1) { /* special case, faster code */
- *buffer = runtime->buffer[runtime->hw_ptr];
- result++;
- } else {
- count1 = runtime->buffer_size - runtime->hw_ptr;
- if (count1 > count)
- count1 = count;
- if (count1 > (int)(runtime->buffer_size - runtime->avail))
- count1 = runtime->buffer_size - runtime->avail;
- memcpy(buffer, runtime->buffer + runtime->hw_ptr, count1);
- count -= count1;
- result += count1;
- if (count > 0) {
- if (count > (int)(runtime->buffer_size - runtime->avail - count1))
- count = runtime->buffer_size - runtime->avail - count1;
- memcpy(buffer + count1, runtime->buffer, count);
- result += count;
- }
- }
- __skip:
- spin_unlock_irqrestore(&runtime->lock, flags);
- return result;
-}
-
-/**
- * snd_rawmidi_transmit_ack - acknowledge the transmission
- * @substream: the rawmidi substream
- * @count: the tranferred count
- *
- * Advances the hardware pointer for the internal output buffer with
- * the given size and updates the condition.
- * Call after the transmission is finished.
- *
- * Returns the advanced size if successful, or a negative error code on failure.
- */
-int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
-{
- unsigned long flags;
- struct snd_rawmidi_runtime *runtime = substream->runtime;
-
- if (runtime->buffer == NULL) {
- snd_printd("snd_rawmidi_transmit_ack: output is not active!!!\n");
- return -EINVAL;
- }
- spin_lock_irqsave(&runtime->lock, flags);
- snd_BUG_ON(runtime->avail + count > runtime->buffer_size);
- runtime->hw_ptr += count;
- runtime->hw_ptr %= runtime->buffer_size;
- runtime->avail += count;
- substream->bytes += count;
- if (count > 0) {
- if (runtime->drain || snd_rawmidi_ready(substream))
- wake_up(&runtime->sleep);
- }
- spin_unlock_irqrestore(&runtime->lock, flags);
- return count;
-}
-
-/**
- * snd_rawmidi_transmit - copy from the buffer to the device
- * @substream: the rawmidi substream
- * @buffer: the buffer pointer
- * @count: the data size to transfer
- *
- * Copies data from the buffer to the device and advances the pointer.
- *
- * Returns the copied size if successful, or a negative error code on failure.
- */
-int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream,
- unsigned char *buffer, int count)
-{
- if (!substream->opened)
- return -EBADFD;
- count = snd_rawmidi_transmit_peek(substream, buffer, count);
- if (count < 0)
- return count;
- return snd_rawmidi_transmit_ack(substream, count);
-}
-
-static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
- const unsigned char __user *userbuf,
- const unsigned char *kernelbuf,
- long count)
-{
- unsigned long flags;
- long count1, result;
- struct snd_rawmidi_runtime *runtime = substream->runtime;
-
- if (snd_BUG_ON(!kernelbuf && !userbuf))
- return -EINVAL;
- if (snd_BUG_ON(!runtime->buffer))
- return -EINVAL;
-
- result = 0;
- spin_lock_irqsave(&runtime->lock, flags);
- if (substream->append) {
- if ((long)runtime->avail < count) {
- spin_unlock_irqrestore(&runtime->lock, flags);
- return -EAGAIN;
- }
- }
- while (count > 0 && runtime->avail > 0) {
- count1 = runtime->buffer_size - runtime->appl_ptr;
- if (count1 > count)
- count1 = count;
- if (count1 > (long)runtime->avail)
- count1 = runtime->avail;
- if (kernelbuf)
- memcpy(runtime->buffer + runtime->appl_ptr,
- kernelbuf + result, count1);
- else if (userbuf) {
- spin_unlock_irqrestore(&runtime->lock, flags);
- if (copy_from_user(runtime->buffer + runtime->appl_ptr,
- userbuf + result, count1)) {
- spin_lock_irqsave(&runtime->lock, flags);
- result = result > 0 ? result : -EFAULT;
- goto __end;
- }
- spin_lock_irqsave(&runtime->lock, flags);
- }
- runtime->appl_ptr += count1;
- runtime->appl_ptr %= runtime->buffer_size;
- runtime->avail -= count1;
- result += count1;
- count -= count1;
- }
- __end:
- count1 = runtime->avail < runtime->buffer_size;
- spin_unlock_irqrestore(&runtime->lock, flags);
- if (count1)
- snd_rawmidi_output_trigger(substream, 1);
- return result;
-}
-
-long snd_rawmidi_kernel_write(struct snd_rawmidi_substream *substream,
- const unsigned char *buf, long count)
-{
- return snd_rawmidi_kernel_write1(substream, NULL, buf, count);
-}
-
-static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf,
- size_t count, loff_t *offset)
-{
- long result, timeout;
- int count1;
- struct snd_rawmidi_file *rfile;
- struct snd_rawmidi_runtime *runtime;
- struct snd_rawmidi_substream *substream;
-
- rfile = file->private_data;
- substream = rfile->output;
- runtime = substream->runtime;
- /* we cannot put an atomic message to our buffer */
- if (substream->append && count > runtime->buffer_size)
- return -EIO;
- result = 0;
- while (count > 0) {
- spin_lock_irq(&runtime->lock);
- while (!snd_rawmidi_ready_append(substream, count)) {
- wait_queue_t wait;
- if (file->f_flags & O_NONBLOCK) {
- spin_unlock_irq(&runtime->lock);
- return result > 0 ? result : -EAGAIN;
- }
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&runtime->sleep, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
- spin_unlock_irq(&runtime->lock);
- timeout = schedule_timeout(30 * HZ);
- remove_wait_queue(&runtime->sleep, &wait);
- if (rfile->rmidi->card->shutdown)
- return -ENODEV;
- if (signal_pending(current))
- return result > 0 ? result : -ERESTARTSYS;
- if (!runtime->avail && !timeout)
- return result > 0 ? result : -EIO;
- spin_lock_irq(&runtime->lock);
- }
- spin_unlock_irq(&runtime->lock);
- count1 = snd_rawmidi_kernel_write1(substream, buf, NULL, count);
- if (count1 < 0)
- return result > 0 ? result : count1;
- result += count1;
- buf += count1;
- if ((size_t)count1 < count && (file->f_flags & O_NONBLOCK))
- break;
- count -= count1;
- }
- if (file->f_flags & O_DSYNC) {
- spin_lock_irq(&runtime->lock);
- while (runtime->avail != runtime->buffer_size) {
- wait_queue_t wait;
- unsigned int last_avail = runtime->avail;
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&runtime->sleep, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
- spin_unlock_irq(&runtime->lock);
- timeout = schedule_timeout(30 * HZ);
- remove_wait_queue(&runtime->sleep, &wait);
- if (signal_pending(current))
- return result > 0 ? result : -ERESTARTSYS;
- if (runtime->avail == last_avail && !timeout)
- return result > 0 ? result : -EIO;
- spin_lock_irq(&runtime->lock);
- }
- spin_unlock_irq(&runtime->lock);
- }
- return result;
-}
-
-static unsigned int snd_rawmidi_poll(struct file *file, poll_table * wait)
-{
- struct snd_rawmidi_file *rfile;
- struct snd_rawmidi_runtime *runtime;
- unsigned int mask;
-
- rfile = file->private_data;
- if (rfile->input != NULL) {
- runtime = rfile->input->runtime;
- snd_rawmidi_input_trigger(rfile->input, 1);
- poll_wait(file, &runtime->sleep, wait);
- }
- if (rfile->output != NULL) {
- runtime = rfile->output->runtime;
- poll_wait(file, &runtime->sleep, wait);
- }
- mask = 0;
- if (rfile->input != NULL) {
- if (snd_rawmidi_ready(rfile->input))
- mask |= POLLIN | POLLRDNORM;
- }
- if (rfile->output != NULL) {
- if (snd_rawmidi_ready(rfile->output))
- mask |= POLLOUT | POLLWRNORM;
- }
- return mask;
-}
-
-/*
- */
-#ifdef CONFIG_COMPAT
-#include "rawmidi_compat.c"
-#else
-#define snd_rawmidi_ioctl_compat NULL
-#endif
-
-/*
-
- */
-
-static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_rawmidi *rmidi;
- struct snd_rawmidi_substream *substream;
- struct snd_rawmidi_runtime *runtime;
-
- rmidi = entry->private_data;
- snd_iprintf(buffer, "%s\n\n", rmidi->name);
- mutex_lock(&rmidi->open_mutex);
- if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT) {
- list_for_each_entry(substream,
- &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams,
- list) {
- snd_iprintf(buffer,
- "Output %d\n"
- " Tx bytes : %lu\n",
- substream->number,
- (unsigned long) substream->bytes);
- if (substream->opened) {
- snd_iprintf(buffer,
- " Owner PID : %d\n",
- pid_vnr(substream->pid));
- runtime = substream->runtime;
- snd_iprintf(buffer,
- " Mode : %s\n"
- " Buffer size : %lu\n"
- " Avail : %lu\n",
- runtime->oss ? "OSS compatible" : "native",
- (unsigned long) runtime->buffer_size,
- (unsigned long) runtime->avail);
- }
- }
- }
- if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_INPUT) {
- list_for_each_entry(substream,
- &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams,
- list) {
- snd_iprintf(buffer,
- "Input %d\n"
- " Rx bytes : %lu\n",
- substream->number,
- (unsigned long) substream->bytes);
- if (substream->opened) {
- snd_iprintf(buffer,
- " Owner PID : %d\n",
- pid_vnr(substream->pid));
- runtime = substream->runtime;
- snd_iprintf(buffer,
- " Buffer size : %lu\n"
- " Avail : %lu\n"
- " Overruns : %lu\n",
- (unsigned long) runtime->buffer_size,
- (unsigned long) runtime->avail,
- (unsigned long) runtime->xruns);
- }
- }
- }
- mutex_unlock(&rmidi->open_mutex);
-}
-
-/*
- * Register functions
- */
-
-static const struct file_operations snd_rawmidi_f_ops =
-{
- .owner = THIS_MODULE,
- .read = snd_rawmidi_read,
- .write = snd_rawmidi_write,
- .open = snd_rawmidi_open,
- .release = snd_rawmidi_release,
- .llseek = no_llseek,
- .poll = snd_rawmidi_poll,
- .unlocked_ioctl = snd_rawmidi_ioctl,
- .compat_ioctl = snd_rawmidi_ioctl_compat,
-};
-
-static int snd_rawmidi_alloc_substreams(struct snd_rawmidi *rmidi,
- struct snd_rawmidi_str *stream,
- int direction,
- int count)
-{
- struct snd_rawmidi_substream *substream;
- int idx;
-
- for (idx = 0; idx < count; idx++) {
- substream = kzalloc(sizeof(*substream), GFP_KERNEL);
- if (substream == NULL) {
- snd_printk(KERN_ERR "rawmidi: cannot allocate substream\n");
- return -ENOMEM;
- }
- substream->stream = direction;
- substream->number = idx;
- substream->rmidi = rmidi;
- substream->pstr = stream;
- list_add_tail(&substream->list, &stream->substreams);
- stream->substream_count++;
- }
- return 0;
-}
-
-/**
- * snd_rawmidi_new - create a rawmidi instance
- * @card: the card instance
- * @id: the id string
- * @device: the device index
- * @output_count: the number of output streams
- * @input_count: the number of input streams
- * @rrawmidi: the pointer to store the new rawmidi instance
- *
- * Creates a new rawmidi instance.
- * Use snd_rawmidi_set_ops() to set the operators to the new instance.
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_rawmidi_new(struct snd_card *card, char *id, int device,
- int output_count, int input_count,
- struct snd_rawmidi ** rrawmidi)
-{
- struct snd_rawmidi *rmidi;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_rawmidi_dev_free,
- .dev_register = snd_rawmidi_dev_register,
- .dev_disconnect = snd_rawmidi_dev_disconnect,
- };
-
- if (snd_BUG_ON(!card))
- return -ENXIO;
- if (rrawmidi)
- *rrawmidi = NULL;
- rmidi = kzalloc(sizeof(*rmidi), GFP_KERNEL);
- if (rmidi == NULL) {
- snd_printk(KERN_ERR "rawmidi: cannot allocate\n");
- return -ENOMEM;
- }
- rmidi->card = card;
- rmidi->device = device;
- mutex_init(&rmidi->open_mutex);
- init_waitqueue_head(&rmidi->open_wait);
- INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams);
- INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams);
-
- if (id != NULL)
- strlcpy(rmidi->id, id, sizeof(rmidi->id));
- if ((err = snd_rawmidi_alloc_substreams(rmidi,
- &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT],
- SNDRV_RAWMIDI_STREAM_INPUT,
- input_count)) < 0) {
- snd_rawmidi_free(rmidi);
- return err;
- }
- if ((err = snd_rawmidi_alloc_substreams(rmidi,
- &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT],
- SNDRV_RAWMIDI_STREAM_OUTPUT,
- output_count)) < 0) {
- snd_rawmidi_free(rmidi);
- return err;
- }
- if ((err = snd_device_new(card, SNDRV_DEV_RAWMIDI, rmidi, &ops)) < 0) {
- snd_rawmidi_free(rmidi);
- return err;
- }
- if (rrawmidi)
- *rrawmidi = rmidi;
- return 0;
-}
-
-static void snd_rawmidi_free_substreams(struct snd_rawmidi_str *stream)
-{
- struct snd_rawmidi_substream *substream;
-
- while (!list_empty(&stream->substreams)) {
- substream = list_entry(stream->substreams.next, struct snd_rawmidi_substream, list);
- list_del(&substream->list);
- kfree(substream);
- }
-}
-
-static int snd_rawmidi_free(struct snd_rawmidi *rmidi)
-{
- if (!rmidi)
- return 0;
-
- snd_info_free_entry(rmidi->proc_entry);
- rmidi->proc_entry = NULL;
- mutex_lock(&register_mutex);
- if (rmidi->ops && rmidi->ops->dev_unregister)
- rmidi->ops->dev_unregister(rmidi);
- mutex_unlock(&register_mutex);
-
- snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]);
- snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]);
- if (rmidi->private_free)
- rmidi->private_free(rmidi);
- kfree(rmidi);
- return 0;
-}
-
-static int snd_rawmidi_dev_free(struct snd_device *device)
-{
- struct snd_rawmidi *rmidi = device->device_data;
- return snd_rawmidi_free(rmidi);
-}
-
-#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
-static void snd_rawmidi_dev_seq_free(struct snd_seq_device *device)
-{
- struct snd_rawmidi *rmidi = device->private_data;
- rmidi->seq_dev = NULL;
-}
-#endif
-
-static int snd_rawmidi_dev_register(struct snd_device *device)
-{
- int err;
- struct snd_info_entry *entry;
- char name[16];
- struct snd_rawmidi *rmidi = device->device_data;
-
- if (rmidi->device >= SNDRV_RAWMIDI_DEVICES)
- return -ENOMEM;
- mutex_lock(&register_mutex);
- if (snd_rawmidi_search(rmidi->card, rmidi->device)) {
- mutex_unlock(&register_mutex);
- return -EBUSY;
- }
- list_add_tail(&rmidi->list, &snd_rawmidi_devices);
- sprintf(name, "midiC%iD%i", rmidi->card->number, rmidi->device);
- if ((err = snd_register_device(SNDRV_DEVICE_TYPE_RAWMIDI,
- rmidi->card, rmidi->device,
- &snd_rawmidi_f_ops, rmidi, name)) < 0) {
- snd_printk(KERN_ERR "unable to register rawmidi device %i:%i\n", rmidi->card->number, rmidi->device);
- list_del(&rmidi->list);
- mutex_unlock(&register_mutex);
- return err;
- }
- if (rmidi->ops && rmidi->ops->dev_register &&
- (err = rmidi->ops->dev_register(rmidi)) < 0) {
- snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
- list_del(&rmidi->list);
- mutex_unlock(&register_mutex);
- return err;
- }
-#ifdef CONFIG_SND_OSSEMUL
- rmidi->ossreg = 0;
- if ((int)rmidi->device == midi_map[rmidi->card->number]) {
- if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI,
- rmidi->card, 0, &snd_rawmidi_f_ops,
- rmidi, name) < 0) {
- snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 0);
- } else {
- rmidi->ossreg++;
-#ifdef SNDRV_OSS_INFO_DEV_MIDI
- snd_oss_info_register(SNDRV_OSS_INFO_DEV_MIDI, rmidi->card->number, rmidi->name);
-#endif
- }
- }
- if ((int)rmidi->device == amidi_map[rmidi->card->number]) {
- if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI,
- rmidi->card, 1, &snd_rawmidi_f_ops,
- rmidi, name) < 0) {
- snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 1);
- } else {
- rmidi->ossreg++;
- }
- }
-#endif /* CONFIG_SND_OSSEMUL */
- mutex_unlock(&register_mutex);
- sprintf(name, "midi%d", rmidi->device);
- entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root);
- if (entry) {
- entry->private_data = rmidi;
- entry->c.text.read = snd_rawmidi_proc_info_read;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- rmidi->proc_entry = entry;
-#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
- if (!rmidi->ops || !rmidi->ops->dev_register) { /* own registration mechanism */
- if (snd_seq_device_new(rmidi->card, rmidi->device, SNDRV_SEQ_DEV_ID_MIDISYNTH, 0, &rmidi->seq_dev) >= 0) {
- rmidi->seq_dev->private_data = rmidi;
- rmidi->seq_dev->private_free = snd_rawmidi_dev_seq_free;
- sprintf(rmidi->seq_dev->name, "MIDI %d-%d", rmidi->card->number, rmidi->device);
- snd_device_register(rmidi->card, rmidi->seq_dev);
- }
- }
-#endif
- return 0;
-}
-
-static int snd_rawmidi_dev_disconnect(struct snd_device *device)
-{
- struct snd_rawmidi *rmidi = device->device_data;
- int dir;
-
- mutex_lock(&register_mutex);
- mutex_lock(&rmidi->open_mutex);
- wake_up(&rmidi->open_wait);
- list_del_init(&rmidi->list);
- for (dir = 0; dir < 2; dir++) {
- struct snd_rawmidi_substream *s;
- list_for_each_entry(s, &rmidi->streams[dir].substreams, list) {
- if (s->runtime)
- wake_up(&s->runtime->sleep);
- }
- }
-
-#ifdef CONFIG_SND_OSSEMUL
- if (rmidi->ossreg) {
- if ((int)rmidi->device == midi_map[rmidi->card->number]) {
- snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, rmidi->card, 0);
-#ifdef SNDRV_OSS_INFO_DEV_MIDI
- snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_MIDI, rmidi->card->number);
-#endif
- }
- if ((int)rmidi->device == amidi_map[rmidi->card->number])
- snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, rmidi->card, 1);
- rmidi->ossreg = 0;
- }
-#endif /* CONFIG_SND_OSSEMUL */
- snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
- mutex_unlock(&rmidi->open_mutex);
- mutex_unlock(&register_mutex);
- return 0;
-}
-
-/**
- * snd_rawmidi_set_ops - set the rawmidi operators
- * @rmidi: the rawmidi instance
- * @stream: the stream direction, SNDRV_RAWMIDI_STREAM_XXX
- * @ops: the operator table
- *
- * Sets the rawmidi operators for the given stream direction.
- */
-void snd_rawmidi_set_ops(struct snd_rawmidi *rmidi, int stream,
- struct snd_rawmidi_ops *ops)
-{
- struct snd_rawmidi_substream *substream;
-
- list_for_each_entry(substream, &rmidi->streams[stream].substreams, list)
- substream->ops = ops;
-}
-
-/*
- * ENTRY functions
- */
-
-static int __init alsa_rawmidi_init(void)
-{
-
- snd_ctl_register_ioctl(snd_rawmidi_control_ioctl);
- snd_ctl_register_ioctl_compat(snd_rawmidi_control_ioctl);
-#ifdef CONFIG_SND_OSSEMUL
- { int i;
- /* check device map table */
- for (i = 0; i < SNDRV_CARDS; i++) {
- if (midi_map[i] < 0 || midi_map[i] >= SNDRV_RAWMIDI_DEVICES) {
- snd_printk(KERN_ERR "invalid midi_map[%d] = %d\n", i, midi_map[i]);
- midi_map[i] = 0;
- }
- if (amidi_map[i] < 0 || amidi_map[i] >= SNDRV_RAWMIDI_DEVICES) {
- snd_printk(KERN_ERR "invalid amidi_map[%d] = %d\n", i, amidi_map[i]);
- amidi_map[i] = 1;
- }
- }
- }
-#endif /* CONFIG_SND_OSSEMUL */
- return 0;
-}
-
-static void __exit alsa_rawmidi_exit(void)
-{
- snd_ctl_unregister_ioctl(snd_rawmidi_control_ioctl);
- snd_ctl_unregister_ioctl_compat(snd_rawmidi_control_ioctl);
-}
-
-module_init(alsa_rawmidi_init)
-module_exit(alsa_rawmidi_exit)
-
-EXPORT_SYMBOL(snd_rawmidi_output_params);
-EXPORT_SYMBOL(snd_rawmidi_input_params);
-EXPORT_SYMBOL(snd_rawmidi_drop_output);
-EXPORT_SYMBOL(snd_rawmidi_drain_output);
-EXPORT_SYMBOL(snd_rawmidi_drain_input);
-EXPORT_SYMBOL(snd_rawmidi_receive);
-EXPORT_SYMBOL(snd_rawmidi_transmit_empty);
-EXPORT_SYMBOL(snd_rawmidi_transmit_peek);
-EXPORT_SYMBOL(snd_rawmidi_transmit_ack);
-EXPORT_SYMBOL(snd_rawmidi_transmit);
-EXPORT_SYMBOL(snd_rawmidi_new);
-EXPORT_SYMBOL(snd_rawmidi_set_ops);
-EXPORT_SYMBOL(snd_rawmidi_info_select);
-EXPORT_SYMBOL(snd_rawmidi_kernel_open);
-EXPORT_SYMBOL(snd_rawmidi_kernel_release);
-EXPORT_SYMBOL(snd_rawmidi_kernel_read);
-EXPORT_SYMBOL(snd_rawmidi_kernel_write);
diff --git a/ANDROID_3.4.5/sound/core/rawmidi_compat.c b/ANDROID_3.4.5/sound/core/rawmidi_compat.c
deleted file mode 100644
index 5268c1f5..00000000
--- a/ANDROID_3.4.5/sound/core/rawmidi_compat.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 32bit -> 64bit ioctl wrapper for raw MIDI API
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/* This file included from rawmidi.c */
-
-#include <linux/compat.h>
-
-struct snd_rawmidi_params32 {
- s32 stream;
- u32 buffer_size;
- u32 avail_min;
- unsigned int no_active_sensing; /* avoid bit-field */
- unsigned char reserved[16];
-} __attribute__((packed));
-
-static int snd_rawmidi_ioctl_params_compat(struct snd_rawmidi_file *rfile,
- struct snd_rawmidi_params32 __user *src)
-{
- struct snd_rawmidi_params params;
- unsigned int val;
-
- if (rfile->output == NULL)
- return -EINVAL;
- if (get_user(params.stream, &src->stream) ||
- get_user(params.buffer_size, &src->buffer_size) ||
- get_user(params.avail_min, &src->avail_min) ||
- get_user(val, &src->no_active_sensing))
- return -EFAULT;
- params.no_active_sensing = val;
- switch (params.stream) {
- case SNDRV_RAWMIDI_STREAM_OUTPUT:
- return snd_rawmidi_output_params(rfile->output, &params);
- case SNDRV_RAWMIDI_STREAM_INPUT:
- return snd_rawmidi_input_params(rfile->input, &params);
- }
- return -EINVAL;
-}
-
-struct snd_rawmidi_status32 {
- s32 stream;
- struct compat_timespec tstamp;
- u32 avail;
- u32 xruns;
- unsigned char reserved[16];
-} __attribute__((packed));
-
-static int snd_rawmidi_ioctl_status_compat(struct snd_rawmidi_file *rfile,
- struct snd_rawmidi_status32 __user *src)
-{
- int err;
- struct snd_rawmidi_status status;
-
- if (rfile->output == NULL)
- return -EINVAL;
- if (get_user(status.stream, &src->stream))
- return -EFAULT;
-
- switch (status.stream) {
- case SNDRV_RAWMIDI_STREAM_OUTPUT:
- err = snd_rawmidi_output_status(rfile->output, &status);
- break;
- case SNDRV_RAWMIDI_STREAM_INPUT:
- err = snd_rawmidi_input_status(rfile->input, &status);
- break;
- default:
- return -EINVAL;
- }
- if (err < 0)
- return err;
-
- if (put_user(status.tstamp.tv_sec, &src->tstamp.tv_sec) ||
- put_user(status.tstamp.tv_nsec, &src->tstamp.tv_nsec) ||
- put_user(status.avail, &src->avail) ||
- put_user(status.xruns, &src->xruns))
- return -EFAULT;
-
- return 0;
-}
-
-enum {
- SNDRV_RAWMIDI_IOCTL_PARAMS32 = _IOWR('W', 0x10, struct snd_rawmidi_params32),
- SNDRV_RAWMIDI_IOCTL_STATUS32 = _IOWR('W', 0x20, struct snd_rawmidi_status32),
-};
-
-static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct snd_rawmidi_file *rfile;
- void __user *argp = compat_ptr(arg);
-
- rfile = file->private_data;
- switch (cmd) {
- case SNDRV_RAWMIDI_IOCTL_PVERSION:
- case SNDRV_RAWMIDI_IOCTL_INFO:
- case SNDRV_RAWMIDI_IOCTL_DROP:
- case SNDRV_RAWMIDI_IOCTL_DRAIN:
- return snd_rawmidi_ioctl(file, cmd, (unsigned long)argp);
- case SNDRV_RAWMIDI_IOCTL_PARAMS32:
- return snd_rawmidi_ioctl_params_compat(rfile, argp);
- case SNDRV_RAWMIDI_IOCTL_STATUS32:
- return snd_rawmidi_ioctl_status_compat(rfile, argp);
- }
- return -ENOIOCTLCMD;
-}
diff --git a/ANDROID_3.4.5/sound/core/rtctimer.c b/ANDROID_3.4.5/sound/core/rtctimer.c
deleted file mode 100644
index e85e72ba..00000000
--- a/ANDROID_3.4.5/sound/core/rtctimer.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * RTC based high-frequency timer
- *
- * Copyright (C) 2000 Takashi Iwai
- * based on rtctimer.c by Steve Ratcliffe
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/log2.h>
-#include <sound/core.h>
-#include <sound/timer.h>
-
-#if defined(CONFIG_RTC) || defined(CONFIG_RTC_MODULE)
-
-#include <linux/mc146818rtc.h>
-
-#define RTC_FREQ 1024 /* default frequency */
-#define NANO_SEC 1000000000L /* 10^9 in sec */
-
-/*
- * prototypes
- */
-static int rtctimer_open(struct snd_timer *t);
-static int rtctimer_close(struct snd_timer *t);
-static int rtctimer_start(struct snd_timer *t);
-static int rtctimer_stop(struct snd_timer *t);
-
-
-/*
- * The hardware dependent description for this timer.
- */
-static struct snd_timer_hardware rtc_hw = {
- .flags = SNDRV_TIMER_HW_AUTO |
- SNDRV_TIMER_HW_FIRST |
- SNDRV_TIMER_HW_TASKLET,
- .ticks = 100000000L, /* FIXME: XXX */
- .open = rtctimer_open,
- .close = rtctimer_close,
- .start = rtctimer_start,
- .stop = rtctimer_stop,
-};
-
-static int rtctimer_freq = RTC_FREQ; /* frequency */
-static struct snd_timer *rtctimer;
-static struct tasklet_struct rtc_tasklet;
-static rtc_task_t rtc_task;
-
-
-static int
-rtctimer_open(struct snd_timer *t)
-{
- int err;
-
- err = rtc_register(&rtc_task);
- if (err < 0)
- return err;
- t->private_data = &rtc_task;
- return 0;
-}
-
-static int
-rtctimer_close(struct snd_timer *t)
-{
- rtc_task_t *rtc = t->private_data;
- if (rtc) {
- rtc_unregister(rtc);
- tasklet_kill(&rtc_tasklet);
- t->private_data = NULL;
- }
- return 0;
-}
-
-static int
-rtctimer_start(struct snd_timer *timer)
-{
- rtc_task_t *rtc = timer->private_data;
- if (snd_BUG_ON(!rtc))
- return -EINVAL;
- rtc_control(rtc, RTC_IRQP_SET, rtctimer_freq);
- rtc_control(rtc, RTC_PIE_ON, 0);
- return 0;
-}
-
-static int
-rtctimer_stop(struct snd_timer *timer)
-{
- rtc_task_t *rtc = timer->private_data;
- if (snd_BUG_ON(!rtc))
- return -EINVAL;
- rtc_control(rtc, RTC_PIE_OFF, 0);
- return 0;
-}
-
-static void rtctimer_tasklet(unsigned long data)
-{
- snd_timer_interrupt((struct snd_timer *)data, 1);
-}
-
-/*
- * interrupt
- */
-static void rtctimer_interrupt(void *private_data)
-{
- tasklet_schedule(private_data);
-}
-
-
-/*
- * ENTRY functions
- */
-static int __init rtctimer_init(void)
-{
- int err;
- struct snd_timer *timer;
-
- if (rtctimer_freq < 2 || rtctimer_freq > 8192 ||
- !is_power_of_2(rtctimer_freq)) {
- snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n",
- rtctimer_freq);
- return -EINVAL;
- }
-
- /* Create a new timer and set up the fields */
- err = snd_timer_global_new("rtc", SNDRV_TIMER_GLOBAL_RTC, &timer);
- if (err < 0)
- return err;
-
- timer->module = THIS_MODULE;
- strcpy(timer->name, "RTC timer");
- timer->hw = rtc_hw;
- timer->hw.resolution = NANO_SEC / rtctimer_freq;
-
- tasklet_init(&rtc_tasklet, rtctimer_tasklet, (unsigned long)timer);
-
- /* set up RTC callback */
- rtc_task.func = rtctimer_interrupt;
- rtc_task.private_data = &rtc_tasklet;
-
- err = snd_timer_global_register(timer);
- if (err < 0) {
- snd_timer_global_free(timer);
- return err;
- }
- rtctimer = timer; /* remember this */
-
- return 0;
-}
-
-static void __exit rtctimer_exit(void)
-{
- if (rtctimer) {
- snd_timer_global_free(rtctimer);
- rtctimer = NULL;
- }
-}
-
-
-/*
- * exported stuff
- */
-module_init(rtctimer_init)
-module_exit(rtctimer_exit)
-
-module_param(rtctimer_freq, int, 0444);
-MODULE_PARM_DESC(rtctimer_freq, "timer frequency in Hz");
-
-MODULE_LICENSE("GPL");
-
-MODULE_ALIAS("snd-timer-" __stringify(SNDRV_TIMER_GLOBAL_RTC));
-
-#endif /* CONFIG_RTC || CONFIG_RTC_MODULE */
diff --git a/ANDROID_3.4.5/sound/core/seq/Kconfig b/ANDROID_3.4.5/sound/core/seq/Kconfig
deleted file mode 100644
index b851fd89..00000000
--- a/ANDROID_3.4.5/sound/core/seq/Kconfig
+++ /dev/null
@@ -1,16 +0,0 @@
-# define SND_XXX_SEQ to min(SND_SEQUENCER,SND_XXX)
-
-config SND_RAWMIDI_SEQ
- def_tristate SND_SEQUENCER && SND_RAWMIDI
-
-config SND_OPL3_LIB_SEQ
- def_tristate SND_SEQUENCER && SND_OPL3_LIB
-
-config SND_OPL4_LIB_SEQ
- def_tristate SND_SEQUENCER && SND_OPL4_LIB
-
-config SND_SBAWE_SEQ
- def_tristate SND_SEQUENCER && SND_SBAWE
-
-config SND_EMU10K1_SEQ
- def_tristate SND_SEQUENCER && SND_EMU10K1
diff --git a/ANDROID_3.4.5/sound/core/seq/Makefile b/ANDROID_3.4.5/sound/core/seq/Makefile
deleted file mode 100644
index 941f64a8..00000000
--- a/ANDROID_3.4.5/sound/core/seq/Makefile
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-seq-device-objs := seq_device.o
-snd-seq-objs := seq.o seq_lock.o seq_clientmgr.o seq_memory.o seq_queue.o \
- seq_fifo.o seq_prioq.o seq_timer.o \
- seq_system.o seq_ports.o seq_info.o
-snd-seq-midi-objs := seq_midi.o
-snd-seq-midi-emul-objs := seq_midi_emul.o
-snd-seq-midi-event-objs := seq_midi_event.o
-snd-seq-dummy-objs := seq_dummy.o
-snd-seq-virmidi-objs := seq_virmidi.o
-
-obj-$(CONFIG_SND_SEQUENCER) += snd-seq.o snd-seq-device.o
-ifeq ($(CONFIG_SND_SEQUENCER_OSS),y)
- obj-$(CONFIG_SND_SEQUENCER) += snd-seq-midi-event.o
- obj-$(CONFIG_SND_SEQUENCER) += oss/
-endif
-obj-$(CONFIG_SND_SEQ_DUMMY) += snd-seq-dummy.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_VIRMIDI) += snd-seq-virmidi.o snd-seq-midi-event.o
-obj-$(CONFIG_SND_RAWMIDI_SEQ) += snd-seq-midi.o snd-seq-midi-event.o
-obj-$(CONFIG_SND_OPL3_LIB_SEQ) += snd-seq-midi-event.o snd-seq-midi-emul.o
-obj-$(CONFIG_SND_OPL4_LIB_SEQ) += snd-seq-midi-event.o snd-seq-midi-emul.o
-obj-$(CONFIG_SND_SBAWE_SEQ) += snd-seq-midi-emul.o snd-seq-virmidi.o
-obj-$(CONFIG_SND_EMU10K1_SEQ) += snd-seq-midi-emul.o snd-seq-virmidi.o
diff --git a/ANDROID_3.4.5/sound/core/seq/oss/Makefile b/ANDROID_3.4.5/sound/core/seq/oss/Makefile
deleted file mode 100644
index b38406b8..00000000
--- a/ANDROID_3.4.5/sound/core/seq/oss/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-seq-oss-objs := seq_oss.o seq_oss_init.o seq_oss_timer.o seq_oss_ioctl.o \
- seq_oss_event.o seq_oss_rw.o seq_oss_synth.o \
- seq_oss_midi.o seq_oss_readq.o seq_oss_writeq.o
-
-obj-$(CONFIG_SND_SEQUENCER) += snd-seq-oss.o
diff --git a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss.c b/ANDROID_3.4.5/sound/core/seq/oss/seq_oss.c
deleted file mode 100644
index 8d4d5e85..00000000
--- a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * OSS compatible sequencer driver
- *
- * registration of device and proc
- *
- * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <sound/core.h>
-#include <sound/minors.h>
-#include <sound/initval.h>
-#include "seq_oss_device.h"
-#include "seq_oss_synth.h"
-
-/*
- * module option
- */
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("OSS-compatible sequencer module");
-MODULE_LICENSE("GPL");
-/* Takashi says this is really only for sound-service-0-, but this is OK. */
-MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_SEQUENCER);
-MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_MUSIC);
-
-#ifdef SNDRV_SEQ_OSS_DEBUG
-module_param(seq_oss_debug, int, 0644);
-MODULE_PARM_DESC(seq_oss_debug, "debug option");
-int seq_oss_debug = 0;
-#endif
-
-
-/*
- * prototypes
- */
-static int register_device(void);
-static void unregister_device(void);
-#ifdef CONFIG_PROC_FS
-static int register_proc(void);
-static void unregister_proc(void);
-#else
-static inline int register_proc(void) { return 0; }
-static inline void unregister_proc(void) {}
-#endif
-
-static int odev_open(struct inode *inode, struct file *file);
-static int odev_release(struct inode *inode, struct file *file);
-static ssize_t odev_read(struct file *file, char __user *buf, size_t count, loff_t *offset);
-static ssize_t odev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset);
-static long odev_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
-static unsigned int odev_poll(struct file *file, poll_table * wait);
-
-
-/*
- * module interface
- */
-
-static int __init alsa_seq_oss_init(void)
-{
- int rc;
- static struct snd_seq_dev_ops ops = {
- snd_seq_oss_synth_register,
- snd_seq_oss_synth_unregister,
- };
-
- snd_seq_autoload_lock();
- if ((rc = register_device()) < 0)
- goto error;
- if ((rc = register_proc()) < 0) {
- unregister_device();
- goto error;
- }
- if ((rc = snd_seq_oss_create_client()) < 0) {
- unregister_proc();
- unregister_device();
- goto error;
- }
-
- if ((rc = snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_OSS, &ops,
- sizeof(struct snd_seq_oss_reg))) < 0) {
- snd_seq_oss_delete_client();
- unregister_proc();
- unregister_device();
- goto error;
- }
-
- /* success */
- snd_seq_oss_synth_init();
-
- error:
- snd_seq_autoload_unlock();
- return rc;
-}
-
-static void __exit alsa_seq_oss_exit(void)
-{
- snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_OSS);
- snd_seq_oss_delete_client();
- unregister_proc();
- unregister_device();
-}
-
-module_init(alsa_seq_oss_init)
-module_exit(alsa_seq_oss_exit)
-
-/*
- * ALSA minor device interface
- */
-
-static DEFINE_MUTEX(register_mutex);
-
-static int
-odev_open(struct inode *inode, struct file *file)
-{
- int level, rc;
-
- if (iminor(inode) == SNDRV_MINOR_OSS_MUSIC)
- level = SNDRV_SEQ_OSS_MODE_MUSIC;
- else
- level = SNDRV_SEQ_OSS_MODE_SYNTH;
-
- mutex_lock(&register_mutex);
- rc = snd_seq_oss_open(file, level);
- mutex_unlock(&register_mutex);
-
- return rc;
-}
-
-static int
-odev_release(struct inode *inode, struct file *file)
-{
- struct seq_oss_devinfo *dp;
-
- if ((dp = file->private_data) == NULL)
- return 0;
-
- snd_seq_oss_drain_write(dp);
-
- mutex_lock(&register_mutex);
- snd_seq_oss_release(dp);
- mutex_unlock(&register_mutex);
-
- return 0;
-}
-
-static ssize_t
-odev_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
-{
- struct seq_oss_devinfo *dp;
- dp = file->private_data;
- if (snd_BUG_ON(!dp))
- return -ENXIO;
- return snd_seq_oss_read(dp, buf, count);
-}
-
-
-static ssize_t
-odev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
-{
- struct seq_oss_devinfo *dp;
- dp = file->private_data;
- if (snd_BUG_ON(!dp))
- return -ENXIO;
- return snd_seq_oss_write(dp, buf, count, file);
-}
-
-static long
-odev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct seq_oss_devinfo *dp;
- dp = file->private_data;
- if (snd_BUG_ON(!dp))
- return -ENXIO;
- return snd_seq_oss_ioctl(dp, cmd, arg);
-}
-
-#ifdef CONFIG_COMPAT
-#define odev_ioctl_compat odev_ioctl
-#else
-#define odev_ioctl_compat NULL
-#endif
-
-static unsigned int
-odev_poll(struct file *file, poll_table * wait)
-{
- struct seq_oss_devinfo *dp;
- dp = file->private_data;
- if (snd_BUG_ON(!dp))
- return -ENXIO;
- return snd_seq_oss_poll(dp, file, wait);
-}
-
-/*
- * registration of sequencer minor device
- */
-
-static const struct file_operations seq_oss_f_ops =
-{
- .owner = THIS_MODULE,
- .read = odev_read,
- .write = odev_write,
- .open = odev_open,
- .release = odev_release,
- .poll = odev_poll,
- .unlocked_ioctl = odev_ioctl,
- .compat_ioctl = odev_ioctl_compat,
- .llseek = noop_llseek,
-};
-
-static int __init
-register_device(void)
-{
- int rc;
-
- mutex_lock(&register_mutex);
- if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER,
- NULL, 0,
- &seq_oss_f_ops, NULL,
- SNDRV_SEQ_OSS_DEVNAME)) < 0) {
- snd_printk(KERN_ERR "can't register device seq\n");
- mutex_unlock(&register_mutex);
- return rc;
- }
- if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC,
- NULL, 0,
- &seq_oss_f_ops, NULL,
- SNDRV_SEQ_OSS_DEVNAME)) < 0) {
- snd_printk(KERN_ERR "can't register device music\n");
- snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0);
- mutex_unlock(&register_mutex);
- return rc;
- }
- debug_printk(("device registered\n"));
- mutex_unlock(&register_mutex);
- return 0;
-}
-
-static void
-unregister_device(void)
-{
- mutex_lock(&register_mutex);
- debug_printk(("device unregistered\n"));
- if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, NULL, 0) < 0)
- snd_printk(KERN_ERR "error unregister device music\n");
- if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0) < 0)
- snd_printk(KERN_ERR "error unregister device seq\n");
- mutex_unlock(&register_mutex);
-}
-
-/*
- * /proc interface
- */
-
-#ifdef CONFIG_PROC_FS
-
-static struct snd_info_entry *info_entry;
-
-static void
-info_read(struct snd_info_entry *entry, struct snd_info_buffer *buf)
-{
- mutex_lock(&register_mutex);
- snd_iprintf(buf, "OSS sequencer emulation version %s\n", SNDRV_SEQ_OSS_VERSION_STR);
- snd_seq_oss_system_info_read(buf);
- snd_seq_oss_synth_info_read(buf);
- snd_seq_oss_midi_info_read(buf);
- mutex_unlock(&register_mutex);
-}
-
-
-static int __init
-register_proc(void)
-{
- struct snd_info_entry *entry;
-
- entry = snd_info_create_module_entry(THIS_MODULE, SNDRV_SEQ_OSS_PROCNAME, snd_seq_root);
- if (entry == NULL)
- return -ENOMEM;
-
- entry->content = SNDRV_INFO_CONTENT_TEXT;
- entry->private_data = NULL;
- entry->c.text.read = info_read;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- return -ENOMEM;
- }
- info_entry = entry;
- return 0;
-}
-
-static void
-unregister_proc(void)
-{
- snd_info_free_entry(info_entry);
- info_entry = NULL;
-}
-#endif /* CONFIG_PROC_FS */
diff --git a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_device.h b/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_device.h
deleted file mode 100644
index c0154a95..00000000
--- a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_device.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * OSS compatible sequencer driver
- *
- * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __SEQ_OSS_DEVICE_H
-#define __SEQ_OSS_DEVICE_H
-
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <sound/core.h>
-#include <sound/seq_oss.h>
-#include <sound/rawmidi.h>
-#include <sound/seq_kernel.h>
-#include <sound/info.h>
-
-/* enable debug print */
-#define SNDRV_SEQ_OSS_DEBUG
-
-/* max. applications */
-#define SNDRV_SEQ_OSS_MAX_CLIENTS 16
-#define SNDRV_SEQ_OSS_MAX_SYNTH_DEVS 16
-#define SNDRV_SEQ_OSS_MAX_MIDI_DEVS 32
-
-/* version */
-#define SNDRV_SEQ_OSS_MAJOR_VERSION 0
-#define SNDRV_SEQ_OSS_MINOR_VERSION 1
-#define SNDRV_SEQ_OSS_TINY_VERSION 8
-#define SNDRV_SEQ_OSS_VERSION_STR "0.1.8"
-
-/* device and proc interface name */
-#define SNDRV_SEQ_OSS_DEVNAME "seq_oss"
-#define SNDRV_SEQ_OSS_PROCNAME "oss"
-
-
-/*
- * type definitions
- */
-
-typedef unsigned int reltime_t;
-typedef unsigned int abstime_t;
-
-
-/*
- * synthesizer channel information
- */
-struct seq_oss_chinfo {
- int note, vel;
-};
-
-/*
- * synthesizer information
- */
-struct seq_oss_synthinfo {
- struct snd_seq_oss_arg arg;
- struct seq_oss_chinfo *ch;
- struct seq_oss_synth_sysex *sysex;
- int nr_voices;
- int opened;
- int is_midi;
- int midi_mapped;
-};
-
-
-/*
- * sequencer client information
- */
-
-struct seq_oss_devinfo {
-
- int index; /* application index */
- int cseq; /* sequencer client number */
- int port; /* sequencer port number */
- int queue; /* sequencer queue number */
-
- struct snd_seq_addr addr; /* address of this device */
-
- int seq_mode; /* sequencer mode */
- int file_mode; /* file access */
-
- /* midi device table */
- int max_mididev;
-
- /* synth device table */
- int max_synthdev;
- struct seq_oss_synthinfo synths[SNDRV_SEQ_OSS_MAX_SYNTH_DEVS];
- int synth_opened;
-
- /* output queue */
- struct seq_oss_writeq *writeq;
-
- /* midi input queue */
- struct seq_oss_readq *readq;
-
- /* timer */
- struct seq_oss_timer *timer;
-};
-
-
-/*
- * function prototypes
- */
-
-/* create/delete OSS sequencer client */
-int snd_seq_oss_create_client(void);
-int snd_seq_oss_delete_client(void);
-
-/* device file interface */
-int snd_seq_oss_open(struct file *file, int level);
-void snd_seq_oss_release(struct seq_oss_devinfo *dp);
-int snd_seq_oss_ioctl(struct seq_oss_devinfo *dp, unsigned int cmd, unsigned long arg);
-int snd_seq_oss_read(struct seq_oss_devinfo *dev, char __user *buf, int count);
-int snd_seq_oss_write(struct seq_oss_devinfo *dp, const char __user *buf, int count, struct file *opt);
-unsigned int snd_seq_oss_poll(struct seq_oss_devinfo *dp, struct file *file, poll_table * wait);
-
-void snd_seq_oss_reset(struct seq_oss_devinfo *dp);
-void snd_seq_oss_drain_write(struct seq_oss_devinfo *dp);
-
-/* */
-void snd_seq_oss_process_queue(struct seq_oss_devinfo *dp, abstime_t time);
-
-
-/* proc interface */
-void snd_seq_oss_system_info_read(struct snd_info_buffer *buf);
-void snd_seq_oss_midi_info_read(struct snd_info_buffer *buf);
-void snd_seq_oss_synth_info_read(struct snd_info_buffer *buf);
-void snd_seq_oss_readq_info_read(struct seq_oss_readq *q, struct snd_info_buffer *buf);
-
-/* file mode macros */
-#define is_read_mode(mode) ((mode) & SNDRV_SEQ_OSS_FILE_READ)
-#define is_write_mode(mode) ((mode) & SNDRV_SEQ_OSS_FILE_WRITE)
-#define is_nonblock_mode(mode) ((mode) & SNDRV_SEQ_OSS_FILE_NONBLOCK)
-
-/* dispatch event */
-static inline int
-snd_seq_oss_dispatch(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, int atomic, int hop)
-{
- return snd_seq_kernel_client_dispatch(dp->cseq, ev, atomic, hop);
-}
-
-/* ioctl */
-static inline int
-snd_seq_oss_control(struct seq_oss_devinfo *dp, unsigned int type, void *arg)
-{
- return snd_seq_kernel_client_ctl(dp->cseq, type, arg);
-}
-
-/* fill the addresses in header */
-static inline void
-snd_seq_oss_fill_addr(struct seq_oss_devinfo *dp, struct snd_seq_event *ev,
- int dest_client, int dest_port)
-{
- ev->queue = dp->queue;
- ev->source = dp->addr;
- ev->dest.client = dest_client;
- ev->dest.port = dest_port;
-}
-
-
-/* misc. functions for proc interface */
-char *enabled_str(int bool);
-
-
-/* for debug */
-#ifdef SNDRV_SEQ_OSS_DEBUG
-extern int seq_oss_debug;
-#define debug_printk(x) do { if (seq_oss_debug > 0) snd_printd x; } while (0)
-#else
-#define debug_printk(x) /**/
-#endif
-
-#endif /* __SEQ_OSS_DEVICE_H */
diff --git a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_event.c b/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_event.c
deleted file mode 100644
index 066f5f3e..00000000
--- a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_event.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * OSS compatible sequencer driver
- *
- * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "seq_oss_device.h"
-#include "seq_oss_synth.h"
-#include "seq_oss_midi.h"
-#include "seq_oss_event.h"
-#include "seq_oss_timer.h"
-#include <sound/seq_oss_legacy.h>
-#include "seq_oss_readq.h"
-#include "seq_oss_writeq.h"
-
-
-/*
- * prototypes
- */
-static int extended_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev);
-static int chn_voice_event(struct seq_oss_devinfo *dp, union evrec *event_rec, struct snd_seq_event *ev);
-static int chn_common_event(struct seq_oss_devinfo *dp, union evrec *event_rec, struct snd_seq_event *ev);
-static int timing_event(struct seq_oss_devinfo *dp, union evrec *event_rec, struct snd_seq_event *ev);
-static int local_event(struct seq_oss_devinfo *dp, union evrec *event_rec, struct snd_seq_event *ev);
-static int old_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev);
-static int note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev);
-static int note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev);
-static int set_note_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int note, int vel, struct snd_seq_event *ev);
-static int set_control_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int param, int val, struct snd_seq_event *ev);
-static int set_echo_event(struct seq_oss_devinfo *dp, union evrec *rec, struct snd_seq_event *ev);
-
-
-/*
- * convert an OSS event to ALSA event
- * return 0 : enqueued
- * non-zero : invalid - ignored
- */
-
-int
-snd_seq_oss_process_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev)
-{
- switch (q->s.code) {
- case SEQ_EXTENDED:
- return extended_event(dp, q, ev);
-
- case EV_CHN_VOICE:
- return chn_voice_event(dp, q, ev);
-
- case EV_CHN_COMMON:
- return chn_common_event(dp, q, ev);
-
- case EV_TIMING:
- return timing_event(dp, q, ev);
-
- case EV_SEQ_LOCAL:
- return local_event(dp, q, ev);
-
- case EV_SYSEX:
- return snd_seq_oss_synth_sysex(dp, q->x.dev, q->x.buf, ev);
-
- case SEQ_MIDIPUTC:
- if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC)
- return -EINVAL;
- /* put a midi byte */
- if (! is_write_mode(dp->file_mode))
- break;
- if (snd_seq_oss_midi_open(dp, q->s.dev, SNDRV_SEQ_OSS_FILE_WRITE))
- break;
- if (snd_seq_oss_midi_filemode(dp, q->s.dev) & SNDRV_SEQ_OSS_FILE_WRITE)
- return snd_seq_oss_midi_putc(dp, q->s.dev, q->s.parm1, ev);
- break;
-
- case SEQ_ECHO:
- if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC)
- return -EINVAL;
- return set_echo_event(dp, q, ev);
-
- case SEQ_PRIVATE:
- if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC)
- return -EINVAL;
- return snd_seq_oss_synth_raw_event(dp, q->c[1], q->c, ev);
-
- default:
- if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC)
- return -EINVAL;
- return old_event(dp, q, ev);
- }
- return -EINVAL;
-}
-
-/* old type events: mode1 only */
-static int
-old_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev)
-{
- switch (q->s.code) {
- case SEQ_NOTEOFF:
- return note_off_event(dp, 0, q->n.chn, q->n.note, q->n.vel, ev);
-
- case SEQ_NOTEON:
- return note_on_event(dp, 0, q->n.chn, q->n.note, q->n.vel, ev);
-
- case SEQ_WAIT:
- /* skip */
- break;
-
- case SEQ_PGMCHANGE:
- return set_control_event(dp, 0, SNDRV_SEQ_EVENT_PGMCHANGE,
- q->n.chn, 0, q->n.note, ev);
-
- case SEQ_SYNCTIMER:
- return snd_seq_oss_timer_reset(dp->timer);
- }
-
- return -EINVAL;
-}
-
-/* 8bytes extended event: mode1 only */
-static int
-extended_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev)
-{
- int val;
-
- switch (q->e.cmd) {
- case SEQ_NOTEOFF:
- return note_off_event(dp, q->e.dev, q->e.chn, q->e.p1, q->e.p2, ev);
-
- case SEQ_NOTEON:
- return note_on_event(dp, q->e.dev, q->e.chn, q->e.p1, q->e.p2, ev);
-
- case SEQ_PGMCHANGE:
- return set_control_event(dp, q->e.dev, SNDRV_SEQ_EVENT_PGMCHANGE,
- q->e.chn, 0, q->e.p1, ev);
-
- case SEQ_AFTERTOUCH:
- return set_control_event(dp, q->e.dev, SNDRV_SEQ_EVENT_CHANPRESS,
- q->e.chn, 0, q->e.p1, ev);
-
- case SEQ_BALANCE:
- /* convert -128:127 to 0:127 */
- val = (char)q->e.p1;
- val = (val + 128) / 2;
- return set_control_event(dp, q->e.dev, SNDRV_SEQ_EVENT_CONTROLLER,
- q->e.chn, CTL_PAN, val, ev);
-
- case SEQ_CONTROLLER:
- val = ((short)q->e.p3 << 8) | (short)q->e.p2;
- switch (q->e.p1) {
- case CTRL_PITCH_BENDER: /* SEQ1 V2 control */
- /* -0x2000:0x1fff */
- return set_control_event(dp, q->e.dev,
- SNDRV_SEQ_EVENT_PITCHBEND,
- q->e.chn, 0, val, ev);
- case CTRL_PITCH_BENDER_RANGE:
- /* conversion: 100/semitone -> 128/semitone */
- return set_control_event(dp, q->e.dev,
- SNDRV_SEQ_EVENT_REGPARAM,
- q->e.chn, 0, val*128/100, ev);
- default:
- return set_control_event(dp, q->e.dev,
- SNDRV_SEQ_EVENT_CONTROL14,
- q->e.chn, q->e.p1, val, ev);
- }
-
- case SEQ_VOLMODE:
- return snd_seq_oss_synth_raw_event(dp, q->e.dev, q->c, ev);
-
- }
- return -EINVAL;
-}
-
-/* channel voice events: mode1 and 2 */
-static int
-chn_voice_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev)
-{
- if (q->v.chn >= 32)
- return -EINVAL;
- switch (q->v.cmd) {
- case MIDI_NOTEON:
- return note_on_event(dp, q->v.dev, q->v.chn, q->v.note, q->v.parm, ev);
-
- case MIDI_NOTEOFF:
- return note_off_event(dp, q->v.dev, q->v.chn, q->v.note, q->v.parm, ev);
-
- case MIDI_KEY_PRESSURE:
- return set_note_event(dp, q->v.dev, SNDRV_SEQ_EVENT_KEYPRESS,
- q->v.chn, q->v.note, q->v.parm, ev);
-
- }
- return -EINVAL;
-}
-
-/* channel common events: mode1 and 2 */
-static int
-chn_common_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev)
-{
- if (q->l.chn >= 32)
- return -EINVAL;
- switch (q->l.cmd) {
- case MIDI_PGM_CHANGE:
- return set_control_event(dp, q->l.dev, SNDRV_SEQ_EVENT_PGMCHANGE,
- q->l.chn, 0, q->l.p1, ev);
-
- case MIDI_CTL_CHANGE:
- return set_control_event(dp, q->l.dev, SNDRV_SEQ_EVENT_CONTROLLER,
- q->l.chn, q->l.p1, q->l.val, ev);
-
- case MIDI_PITCH_BEND:
- /* conversion: 0:0x3fff -> -0x2000:0x1fff */
- return set_control_event(dp, q->l.dev, SNDRV_SEQ_EVENT_PITCHBEND,
- q->l.chn, 0, q->l.val - 8192, ev);
-
- case MIDI_CHN_PRESSURE:
- return set_control_event(dp, q->l.dev, SNDRV_SEQ_EVENT_CHANPRESS,
- q->l.chn, 0, q->l.val, ev);
- }
- return -EINVAL;
-}
-
-/* timer events: mode1 and mode2 */
-static int
-timing_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev)
-{
- switch (q->t.cmd) {
- case TMR_ECHO:
- if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC)
- return set_echo_event(dp, q, ev);
- else {
- union evrec tmp;
- memset(&tmp, 0, sizeof(tmp));
- /* XXX: only for little-endian! */
- tmp.echo = (q->t.time << 8) | SEQ_ECHO;
- return set_echo_event(dp, &tmp, ev);
- }
-
- case TMR_STOP:
- if (dp->seq_mode)
- return snd_seq_oss_timer_stop(dp->timer);
- return 0;
-
- case TMR_CONTINUE:
- if (dp->seq_mode)
- return snd_seq_oss_timer_continue(dp->timer);
- return 0;
-
- case TMR_TEMPO:
- if (dp->seq_mode)
- return snd_seq_oss_timer_tempo(dp->timer, q->t.time);
- return 0;
- }
-
- return -EINVAL;
-}
-
-/* local events: mode1 and 2 */
-static int
-local_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev)
-{
- return -EINVAL;
-}
-
-/*
- * process note-on event for OSS synth
- * three different modes are available:
- * - SNDRV_SEQ_OSS_PROCESS_EVENTS (for one-voice per channel mode)
- * Accept note 255 as volume change.
- * - SNDRV_SEQ_OSS_PASS_EVENTS
- * Pass all events to lowlevel driver anyway
- * - SNDRV_SEQ_OSS_PROCESS_KEYPRESS (mostly for Emu8000)
- * Use key-pressure if note >= 128
- */
-static int
-note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev)
-{
- struct seq_oss_synthinfo *info = &dp->synths[dev];
- switch (info->arg.event_passing) {
- case SNDRV_SEQ_OSS_PROCESS_EVENTS:
- if (! info->ch || ch < 0 || ch >= info->nr_voices) {
- /* pass directly */
- return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev);
- }
-
- if (note == 255 && info->ch[ch].note >= 0) {
- /* volume control */
- int type;
- //if (! vel)
- /* set volume to zero -- note off */
- // type = SNDRV_SEQ_EVENT_NOTEOFF;
- //else
- if (info->ch[ch].vel)
- /* sample already started -- volume change */
- type = SNDRV_SEQ_EVENT_KEYPRESS;
- else
- /* sample not started -- start now */
- type = SNDRV_SEQ_EVENT_NOTEON;
- info->ch[ch].vel = vel;
- return set_note_event(dp, dev, type, ch, info->ch[ch].note, vel, ev);
- } else if (note >= 128)
- return -EINVAL; /* invalid */
-
- if (note != info->ch[ch].note && info->ch[ch].note >= 0)
- /* note changed - note off at beginning */
- set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEOFF, ch, info->ch[ch].note, 0, ev);
- /* set current status */
- info->ch[ch].note = note;
- info->ch[ch].vel = vel;
- if (vel) /* non-zero velocity - start the note now */
- return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev);
- return -EINVAL;
-
- case SNDRV_SEQ_OSS_PASS_EVENTS:
- /* pass the event anyway */
- return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev);
-
- case SNDRV_SEQ_OSS_PROCESS_KEYPRESS:
- if (note >= 128) /* key pressure: shifted by 128 */
- return set_note_event(dp, dev, SNDRV_SEQ_EVENT_KEYPRESS, ch, note - 128, vel, ev);
- else /* normal note-on event */
- return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev);
- }
- return -EINVAL;
-}
-
-/*
- * process note-off event for OSS synth
- */
-static int
-note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev)
-{
- struct seq_oss_synthinfo *info = &dp->synths[dev];
- switch (info->arg.event_passing) {
- case SNDRV_SEQ_OSS_PROCESS_EVENTS:
- if (! info->ch || ch < 0 || ch >= info->nr_voices) {
- /* pass directly */
- return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev);
- }
-
- if (info->ch[ch].note >= 0) {
- note = info->ch[ch].note;
- info->ch[ch].vel = 0;
- info->ch[ch].note = -1;
- return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEOFF, ch, note, vel, ev);
- }
- return -EINVAL; /* invalid */
-
- case SNDRV_SEQ_OSS_PASS_EVENTS:
- case SNDRV_SEQ_OSS_PROCESS_KEYPRESS:
- /* pass the event anyway */
- return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEOFF, ch, note, vel, ev);
-
- }
- return -EINVAL;
-}
-
-/*
- * create a note event
- */
-static int
-set_note_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int note, int vel, struct snd_seq_event *ev)
-{
- if (! snd_seq_oss_synth_is_valid(dp, dev))
- return -ENXIO;
-
- ev->type = type;
- snd_seq_oss_synth_addr(dp, dev, ev);
- ev->data.note.channel = ch;
- ev->data.note.note = note;
- ev->data.note.velocity = vel;
-
- return 0;
-}
-
-/*
- * create a control event
- */
-static int
-set_control_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int param, int val, struct snd_seq_event *ev)
-{
- if (! snd_seq_oss_synth_is_valid(dp, dev))
- return -ENXIO;
-
- ev->type = type;
- snd_seq_oss_synth_addr(dp, dev, ev);
- ev->data.control.channel = ch;
- ev->data.control.param = param;
- ev->data.control.value = val;
-
- return 0;
-}
-
-/*
- * create an echo event
- */
-static int
-set_echo_event(struct seq_oss_devinfo *dp, union evrec *rec, struct snd_seq_event *ev)
-{
- ev->type = SNDRV_SEQ_EVENT_ECHO;
- /* echo back to itself */
- snd_seq_oss_fill_addr(dp, ev, dp->addr.client, dp->addr.port);
- memcpy(&ev->data, rec, LONG_EVENT_SIZE);
- return 0;
-}
-
-/*
- * event input callback from ALSA sequencer:
- * the echo event is processed here.
- */
-int
-snd_seq_oss_event_input(struct snd_seq_event *ev, int direct, void *private_data,
- int atomic, int hop)
-{
- struct seq_oss_devinfo *dp = (struct seq_oss_devinfo *)private_data;
- union evrec *rec;
-
- if (ev->type != SNDRV_SEQ_EVENT_ECHO)
- return snd_seq_oss_midi_input(ev, direct, private_data);
-
- if (ev->source.client != dp->cseq)
- return 0; /* ignored */
-
- rec = (union evrec*)&ev->data;
- if (rec->s.code == SEQ_SYNCTIMER) {
- /* sync echo back */
- snd_seq_oss_writeq_wakeup(dp->writeq, rec->t.time);
-
- } else {
- /* echo back event */
- if (dp->readq == NULL)
- return 0;
- snd_seq_oss_readq_put_event(dp->readq, rec);
- }
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_event.h b/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_event.h
deleted file mode 100644
index 9a4d9adb..00000000
--- a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_event.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * OSS compatible sequencer driver
- *
- * seq_oss_event.h - OSS event queue record
- *
- * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __SEQ_OSS_EVENT_H
-#define __SEQ_OSS_EVENT_H
-
-#include "seq_oss_device.h"
-
-#define SHORT_EVENT_SIZE 4
-#define LONG_EVENT_SIZE 8
-
-/* short event (4bytes) */
-struct evrec_short {
- unsigned char code;
- unsigned char parm1;
- unsigned char dev;
- unsigned char parm2;
-};
-
-/* short note events (4bytes) */
-struct evrec_note {
- unsigned char code;
- unsigned char chn;
- unsigned char note;
- unsigned char vel;
-};
-
-/* long timer events (8bytes) */
-struct evrec_timer {
- unsigned char code;
- unsigned char cmd;
- unsigned char dummy1, dummy2;
- unsigned int time;
-};
-
-/* long extended events (8bytes) */
-struct evrec_extended {
- unsigned char code;
- unsigned char cmd;
- unsigned char dev;
- unsigned char chn;
- unsigned char p1, p2, p3, p4;
-};
-
-/* long channel events (8bytes) */
-struct evrec_long {
- unsigned char code;
- unsigned char dev;
- unsigned char cmd;
- unsigned char chn;
- unsigned char p1, p2;
- unsigned short val;
-};
-
-/* channel voice events (8bytes) */
-struct evrec_voice {
- unsigned char code;
- unsigned char dev;
- unsigned char cmd;
- unsigned char chn;
- unsigned char note, parm;
- unsigned short dummy;
-};
-
-/* sysex events (8bytes) */
-struct evrec_sysex {
- unsigned char code;
- unsigned char dev;
- unsigned char buf[6];
-};
-
-/* event record */
-union evrec {
- struct evrec_short s;
- struct evrec_note n;
- struct evrec_long l;
- struct evrec_voice v;
- struct evrec_timer t;
- struct evrec_extended e;
- struct evrec_sysex x;
- unsigned int echo;
- unsigned char c[LONG_EVENT_SIZE];
-};
-
-#define ev_is_long(ev) ((ev)->s.code >= 128)
-#define ev_length(ev) ((ev)->s.code >= 128 ? LONG_EVENT_SIZE : SHORT_EVENT_SIZE)
-
-int snd_seq_oss_process_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev);
-int snd_seq_oss_process_timer_event(struct seq_oss_timer *rec, union evrec *q);
-int snd_seq_oss_event_input(struct snd_seq_event *ev, int direct, void *private_data, int atomic, int hop);
-
-
-#endif /* __SEQ_OSS_EVENT_H */
diff --git a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_init.c b/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_init.c
deleted file mode 100644
index e3cb46fe..00000000
--- a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_init.c
+++ /dev/null
@@ -1,546 +0,0 @@
-/*
- * OSS compatible sequencer driver
- *
- * open/close and reset interface
- *
- * Copyright (C) 1998-1999 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "seq_oss_device.h"
-#include "seq_oss_synth.h"
-#include "seq_oss_midi.h"
-#include "seq_oss_writeq.h"
-#include "seq_oss_readq.h"
-#include "seq_oss_timer.h"
-#include "seq_oss_event.h"
-#include <linux/init.h>
-#include <linux/export.h>
-#include <linux/moduleparam.h>
-#include <linux/slab.h>
-
-/*
- * common variables
- */
-static int maxqlen = SNDRV_SEQ_OSS_MAX_QLEN;
-module_param(maxqlen, int, 0444);
-MODULE_PARM_DESC(maxqlen, "maximum queue length");
-
-static int system_client = -1; /* ALSA sequencer client number */
-static int system_port = -1;
-
-static int num_clients;
-static struct seq_oss_devinfo *client_table[SNDRV_SEQ_OSS_MAX_CLIENTS];
-
-
-/*
- * prototypes
- */
-static int receive_announce(struct snd_seq_event *ev, int direct, void *private, int atomic, int hop);
-static int translate_mode(struct file *file);
-static int create_port(struct seq_oss_devinfo *dp);
-static int delete_port(struct seq_oss_devinfo *dp);
-static int alloc_seq_queue(struct seq_oss_devinfo *dp);
-static int delete_seq_queue(int queue);
-static void free_devinfo(void *private);
-
-#define call_ctl(type,rec) snd_seq_kernel_client_ctl(system_client, type, rec)
-
-
-/*
- * create sequencer client for OSS sequencer
- */
-int __init
-snd_seq_oss_create_client(void)
-{
- int rc;
- struct snd_seq_port_info *port;
- struct snd_seq_port_callback port_callback;
-
- port = kmalloc(sizeof(*port), GFP_KERNEL);
- if (!port) {
- rc = -ENOMEM;
- goto __error;
- }
-
- /* create ALSA client */
- rc = snd_seq_create_kernel_client(NULL, SNDRV_SEQ_CLIENT_OSS,
- "OSS sequencer");
- if (rc < 0)
- goto __error;
-
- system_client = rc;
- debug_printk(("new client = %d\n", rc));
-
- /* look up midi devices */
- snd_seq_oss_midi_lookup_ports(system_client);
-
- /* create annoucement receiver port */
- memset(port, 0, sizeof(*port));
- strcpy(port->name, "Receiver");
- port->addr.client = system_client;
- port->capability = SNDRV_SEQ_PORT_CAP_WRITE; /* receive only */
- port->type = 0;
-
- memset(&port_callback, 0, sizeof(port_callback));
- /* don't set port_callback.owner here. otherwise the module counter
- * is incremented and we can no longer release the module..
- */
- port_callback.event_input = receive_announce;
- port->kernel = &port_callback;
-
- call_ctl(SNDRV_SEQ_IOCTL_CREATE_PORT, port);
- if ((system_port = port->addr.port) >= 0) {
- struct snd_seq_port_subscribe subs;
-
- memset(&subs, 0, sizeof(subs));
- subs.sender.client = SNDRV_SEQ_CLIENT_SYSTEM;
- subs.sender.port = SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE;
- subs.dest.client = system_client;
- subs.dest.port = system_port;
- call_ctl(SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &subs);
- }
- rc = 0;
-
- __error:
- kfree(port);
- return rc;
-}
-
-
-/*
- * receive annoucement from system port, and check the midi device
- */
-static int
-receive_announce(struct snd_seq_event *ev, int direct, void *private, int atomic, int hop)
-{
- struct snd_seq_port_info pinfo;
-
- if (atomic)
- return 0; /* it must not happen */
-
- switch (ev->type) {
- case SNDRV_SEQ_EVENT_PORT_START:
- case SNDRV_SEQ_EVENT_PORT_CHANGE:
- if (ev->data.addr.client == system_client)
- break; /* ignore myself */
- memset(&pinfo, 0, sizeof(pinfo));
- pinfo.addr = ev->data.addr;
- if (call_ctl(SNDRV_SEQ_IOCTL_GET_PORT_INFO, &pinfo) >= 0)
- snd_seq_oss_midi_check_new_port(&pinfo);
- break;
-
- case SNDRV_SEQ_EVENT_PORT_EXIT:
- if (ev->data.addr.client == system_client)
- break; /* ignore myself */
- snd_seq_oss_midi_check_exit_port(ev->data.addr.client,
- ev->data.addr.port);
- break;
- }
- return 0;
-}
-
-
-/*
- * delete OSS sequencer client
- */
-int
-snd_seq_oss_delete_client(void)
-{
- if (system_client >= 0)
- snd_seq_delete_kernel_client(system_client);
-
- snd_seq_oss_midi_clear_all();
-
- return 0;
-}
-
-
-/*
- * open sequencer device
- */
-int
-snd_seq_oss_open(struct file *file, int level)
-{
- int i, rc;
- struct seq_oss_devinfo *dp;
-
- dp = kzalloc(sizeof(*dp), GFP_KERNEL);
- if (!dp) {
- snd_printk(KERN_ERR "can't malloc device info\n");
- return -ENOMEM;
- }
- debug_printk(("oss_open: dp = %p\n", dp));
-
- dp->cseq = system_client;
- dp->port = -1;
- dp->queue = -1;
-
- for (i = 0; i < SNDRV_SEQ_OSS_MAX_CLIENTS; i++) {
- if (client_table[i] == NULL)
- break;
- }
-
- dp->index = i;
- if (i >= SNDRV_SEQ_OSS_MAX_CLIENTS) {
- snd_printk(KERN_ERR "too many applications\n");
- rc = -ENOMEM;
- goto _error;
- }
-
- /* look up synth and midi devices */
- snd_seq_oss_synth_setup(dp);
- snd_seq_oss_midi_setup(dp);
-
- if (dp->synth_opened == 0 && dp->max_mididev == 0) {
- /* snd_printk(KERN_ERR "no device found\n"); */
- rc = -ENODEV;
- goto _error;
- }
-
- /* create port */
- debug_printk(("create new port\n"));
- rc = create_port(dp);
- if (rc < 0) {
- snd_printk(KERN_ERR "can't create port\n");
- goto _error;
- }
-
- /* allocate queue */
- debug_printk(("allocate queue\n"));
- rc = alloc_seq_queue(dp);
- if (rc < 0)
- goto _error;
-
- /* set address */
- dp->addr.client = dp->cseq;
- dp->addr.port = dp->port;
- /*dp->addr.queue = dp->queue;*/
- /*dp->addr.channel = 0;*/
-
- dp->seq_mode = level;
-
- /* set up file mode */
- dp->file_mode = translate_mode(file);
-
- /* initialize read queue */
- debug_printk(("initialize read queue\n"));
- if (is_read_mode(dp->file_mode)) {
- dp->readq = snd_seq_oss_readq_new(dp, maxqlen);
- if (!dp->readq) {
- rc = -ENOMEM;
- goto _error;
- }
- }
-
- /* initialize write queue */
- debug_printk(("initialize write queue\n"));
- if (is_write_mode(dp->file_mode)) {
- dp->writeq = snd_seq_oss_writeq_new(dp, maxqlen);
- if (!dp->writeq) {
- rc = -ENOMEM;
- goto _error;
- }
- }
-
- /* initialize timer */
- debug_printk(("initialize timer\n"));
- dp->timer = snd_seq_oss_timer_new(dp);
- if (!dp->timer) {
- snd_printk(KERN_ERR "can't alloc timer\n");
- rc = -ENOMEM;
- goto _error;
- }
- debug_printk(("timer initialized\n"));
-
- /* set private data pointer */
- file->private_data = dp;
-
- /* set up for mode2 */
- if (level == SNDRV_SEQ_OSS_MODE_MUSIC)
- snd_seq_oss_synth_setup_midi(dp);
- else if (is_read_mode(dp->file_mode))
- snd_seq_oss_midi_open_all(dp, SNDRV_SEQ_OSS_FILE_READ);
-
- client_table[dp->index] = dp;
- num_clients++;
-
- debug_printk(("open done\n"));
- return 0;
-
- _error:
- snd_seq_oss_synth_cleanup(dp);
- snd_seq_oss_midi_cleanup(dp);
- delete_seq_queue(dp->queue);
- delete_port(dp);
-
- return rc;
-}
-
-/*
- * translate file flags to private mode
- */
-static int
-translate_mode(struct file *file)
-{
- int file_mode = 0;
- if ((file->f_flags & O_ACCMODE) != O_RDONLY)
- file_mode |= SNDRV_SEQ_OSS_FILE_WRITE;
- if ((file->f_flags & O_ACCMODE) != O_WRONLY)
- file_mode |= SNDRV_SEQ_OSS_FILE_READ;
- if (file->f_flags & O_NONBLOCK)
- file_mode |= SNDRV_SEQ_OSS_FILE_NONBLOCK;
- return file_mode;
-}
-
-
-/*
- * create sequencer port
- */
-static int
-create_port(struct seq_oss_devinfo *dp)
-{
- int rc;
- struct snd_seq_port_info port;
- struct snd_seq_port_callback callback;
-
- memset(&port, 0, sizeof(port));
- port.addr.client = dp->cseq;
- sprintf(port.name, "Sequencer-%d", dp->index);
- port.capability = SNDRV_SEQ_PORT_CAP_READ|SNDRV_SEQ_PORT_CAP_WRITE; /* no subscription */
- port.type = SNDRV_SEQ_PORT_TYPE_SPECIFIC;
- port.midi_channels = 128;
- port.synth_voices = 128;
-
- memset(&callback, 0, sizeof(callback));
- callback.owner = THIS_MODULE;
- callback.private_data = dp;
- callback.event_input = snd_seq_oss_event_input;
- callback.private_free = free_devinfo;
- port.kernel = &callback;
-
- rc = call_ctl(SNDRV_SEQ_IOCTL_CREATE_PORT, &port);
- if (rc < 0)
- return rc;
-
- dp->port = port.addr.port;
- debug_printk(("new port = %d\n", port.addr.port));
-
- return 0;
-}
-
-/*
- * delete ALSA port
- */
-static int
-delete_port(struct seq_oss_devinfo *dp)
-{
- if (dp->port < 0) {
- kfree(dp);
- return 0;
- }
-
- debug_printk(("delete_port %i\n", dp->port));
- return snd_seq_event_port_detach(dp->cseq, dp->port);
-}
-
-/*
- * allocate a queue
- */
-static int
-alloc_seq_queue(struct seq_oss_devinfo *dp)
-{
- struct snd_seq_queue_info qinfo;
- int rc;
-
- memset(&qinfo, 0, sizeof(qinfo));
- qinfo.owner = system_client;
- qinfo.locked = 1;
- strcpy(qinfo.name, "OSS Sequencer Emulation");
- if ((rc = call_ctl(SNDRV_SEQ_IOCTL_CREATE_QUEUE, &qinfo)) < 0)
- return rc;
- dp->queue = qinfo.queue;
- return 0;
-}
-
-/*
- * release queue
- */
-static int
-delete_seq_queue(int queue)
-{
- struct snd_seq_queue_info qinfo;
- int rc;
-
- if (queue < 0)
- return 0;
- memset(&qinfo, 0, sizeof(qinfo));
- qinfo.queue = queue;
- rc = call_ctl(SNDRV_SEQ_IOCTL_DELETE_QUEUE, &qinfo);
- if (rc < 0)
- printk(KERN_ERR "seq-oss: unable to delete queue %d (%d)\n", queue, rc);
- return rc;
-}
-
-
-/*
- * free device informations - private_free callback of port
- */
-static void
-free_devinfo(void *private)
-{
- struct seq_oss_devinfo *dp = (struct seq_oss_devinfo *)private;
-
- if (dp->timer)
- snd_seq_oss_timer_delete(dp->timer);
-
- if (dp->writeq)
- snd_seq_oss_writeq_delete(dp->writeq);
-
- if (dp->readq)
- snd_seq_oss_readq_delete(dp->readq);
-
- kfree(dp);
-}
-
-
-/*
- * close sequencer device
- */
-void
-snd_seq_oss_release(struct seq_oss_devinfo *dp)
-{
- int queue;
-
- client_table[dp->index] = NULL;
- num_clients--;
-
- debug_printk(("resetting..\n"));
- snd_seq_oss_reset(dp);
-
- debug_printk(("cleaning up..\n"));
- snd_seq_oss_synth_cleanup(dp);
- snd_seq_oss_midi_cleanup(dp);
-
- /* clear slot */
- debug_printk(("releasing resource..\n"));
- queue = dp->queue;
- if (dp->port >= 0)
- delete_port(dp);
- delete_seq_queue(queue);
-
- debug_printk(("release done\n"));
-}
-
-
-/*
- * Wait until the queue is empty (if we don't have nonblock)
- */
-void
-snd_seq_oss_drain_write(struct seq_oss_devinfo *dp)
-{
- if (! dp->timer->running)
- return;
- if (is_write_mode(dp->file_mode) && !is_nonblock_mode(dp->file_mode) &&
- dp->writeq) {
- debug_printk(("syncing..\n"));
- while (snd_seq_oss_writeq_sync(dp->writeq))
- ;
- }
-}
-
-
-/*
- * reset sequencer devices
- */
-void
-snd_seq_oss_reset(struct seq_oss_devinfo *dp)
-{
- int i;
-
- /* reset all synth devices */
- for (i = 0; i < dp->max_synthdev; i++)
- snd_seq_oss_synth_reset(dp, i);
-
- /* reset all midi devices */
- if (dp->seq_mode != SNDRV_SEQ_OSS_MODE_MUSIC) {
- for (i = 0; i < dp->max_mididev; i++)
- snd_seq_oss_midi_reset(dp, i);
- }
-
- /* remove queues */
- if (dp->readq)
- snd_seq_oss_readq_clear(dp->readq);
- if (dp->writeq)
- snd_seq_oss_writeq_clear(dp->writeq);
-
- /* reset timer */
- snd_seq_oss_timer_stop(dp->timer);
-}
-
-
-#ifdef CONFIG_PROC_FS
-/*
- * misc. functions for proc interface
- */
-char *
-enabled_str(int bool)
-{
- return bool ? "enabled" : "disabled";
-}
-
-static char *
-filemode_str(int val)
-{
- static char *str[] = {
- "none", "read", "write", "read/write",
- };
- return str[val & SNDRV_SEQ_OSS_FILE_ACMODE];
-}
-
-
-/*
- * proc interface
- */
-void
-snd_seq_oss_system_info_read(struct snd_info_buffer *buf)
-{
- int i;
- struct seq_oss_devinfo *dp;
-
- snd_iprintf(buf, "ALSA client number %d\n", system_client);
- snd_iprintf(buf, "ALSA receiver port %d\n", system_port);
-
- snd_iprintf(buf, "\nNumber of applications: %d\n", num_clients);
- for (i = 0; i < num_clients; i++) {
- snd_iprintf(buf, "\nApplication %d: ", i);
- if ((dp = client_table[i]) == NULL) {
- snd_iprintf(buf, "*empty*\n");
- continue;
- }
- snd_iprintf(buf, "port %d : queue %d\n", dp->port, dp->queue);
- snd_iprintf(buf, " sequencer mode = %s : file open mode = %s\n",
- (dp->seq_mode ? "music" : "synth"),
- filemode_str(dp->file_mode));
- if (dp->seq_mode)
- snd_iprintf(buf, " timer tempo = %d, timebase = %d\n",
- dp->timer->oss_tempo, dp->timer->oss_timebase);
- snd_iprintf(buf, " max queue length %d\n", maxqlen);
- if (is_read_mode(dp->file_mode) && dp->readq)
- snd_seq_oss_readq_info_read(dp->readq, buf);
- }
-}
-#endif /* CONFIG_PROC_FS */
diff --git a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_ioctl.c b/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_ioctl.c
deleted file mode 100644
index 5ac701c9..00000000
--- a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_ioctl.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * OSS compatible sequencer driver
- *
- * OSS compatible i/o control
- *
- * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "seq_oss_device.h"
-#include "seq_oss_readq.h"
-#include "seq_oss_writeq.h"
-#include "seq_oss_timer.h"
-#include "seq_oss_synth.h"
-#include "seq_oss_midi.h"
-#include "seq_oss_event.h"
-
-static int snd_seq_oss_synth_info_user(struct seq_oss_devinfo *dp, void __user *arg)
-{
- struct synth_info info;
-
- if (copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
- if (snd_seq_oss_synth_make_info(dp, info.device, &info) < 0)
- return -EINVAL;
- if (copy_to_user(arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
-}
-
-static int snd_seq_oss_midi_info_user(struct seq_oss_devinfo *dp, void __user *arg)
-{
- struct midi_info info;
-
- if (copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
- if (snd_seq_oss_midi_make_info(dp, info.device, &info) < 0)
- return -EINVAL;
- if (copy_to_user(arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
-}
-
-static int snd_seq_oss_oob_user(struct seq_oss_devinfo *dp, void __user *arg)
-{
- unsigned char ev[8];
- struct snd_seq_event tmpev;
-
- if (copy_from_user(ev, arg, 8))
- return -EFAULT;
- memset(&tmpev, 0, sizeof(tmpev));
- snd_seq_oss_fill_addr(dp, &tmpev, dp->addr.port, dp->addr.client);
- tmpev.time.tick = 0;
- if (! snd_seq_oss_process_event(dp, (union evrec *)ev, &tmpev)) {
- snd_seq_oss_dispatch(dp, &tmpev, 0, 0);
- }
- return 0;
-}
-
-int
-snd_seq_oss_ioctl(struct seq_oss_devinfo *dp, unsigned int cmd, unsigned long carg)
-{
- int dev, val;
- void __user *arg = (void __user *)carg;
- int __user *p = arg;
-
- switch (cmd) {
- case SNDCTL_TMR_TIMEBASE:
- case SNDCTL_TMR_TEMPO:
- case SNDCTL_TMR_START:
- case SNDCTL_TMR_STOP:
- case SNDCTL_TMR_CONTINUE:
- case SNDCTL_TMR_METRONOME:
- case SNDCTL_TMR_SOURCE:
- case SNDCTL_TMR_SELECT:
- case SNDCTL_SEQ_CTRLRATE:
- return snd_seq_oss_timer_ioctl(dp->timer, cmd, arg);
-
- case SNDCTL_SEQ_PANIC:
- debug_printk(("panic\n"));
- snd_seq_oss_reset(dp);
- return -EINVAL;
-
- case SNDCTL_SEQ_SYNC:
- debug_printk(("sync\n"));
- if (! is_write_mode(dp->file_mode) || dp->writeq == NULL)
- return 0;
- while (snd_seq_oss_writeq_sync(dp->writeq))
- ;
- if (signal_pending(current))
- return -ERESTARTSYS;
- return 0;
-
- case SNDCTL_SEQ_RESET:
- debug_printk(("reset\n"));
- snd_seq_oss_reset(dp);
- return 0;
-
- case SNDCTL_SEQ_TESTMIDI:
- debug_printk(("test midi\n"));
- if (get_user(dev, p))
- return -EFAULT;
- return snd_seq_oss_midi_open(dp, dev, dp->file_mode);
-
- case SNDCTL_SEQ_GETINCOUNT:
- debug_printk(("get in count\n"));
- if (dp->readq == NULL || ! is_read_mode(dp->file_mode))
- return 0;
- return put_user(dp->readq->qlen, p) ? -EFAULT : 0;
-
- case SNDCTL_SEQ_GETOUTCOUNT:
- debug_printk(("get out count\n"));
- if (! is_write_mode(dp->file_mode) || dp->writeq == NULL)
- return 0;
- return put_user(snd_seq_oss_writeq_get_free_size(dp->writeq), p) ? -EFAULT : 0;
-
- case SNDCTL_SEQ_GETTIME:
- debug_printk(("get time\n"));
- return put_user(snd_seq_oss_timer_cur_tick(dp->timer), p) ? -EFAULT : 0;
-
- case SNDCTL_SEQ_RESETSAMPLES:
- debug_printk(("reset samples\n"));
- if (get_user(dev, p))
- return -EFAULT;
- return snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
-
- case SNDCTL_SEQ_NRSYNTHS:
- debug_printk(("nr synths\n"));
- return put_user(dp->max_synthdev, p) ? -EFAULT : 0;
-
- case SNDCTL_SEQ_NRMIDIS:
- debug_printk(("nr midis\n"));
- return put_user(dp->max_mididev, p) ? -EFAULT : 0;
-
- case SNDCTL_SYNTH_MEMAVL:
- debug_printk(("mem avail\n"));
- if (get_user(dev, p))
- return -EFAULT;
- val = snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
- return put_user(val, p) ? -EFAULT : 0;
-
- case SNDCTL_FM_4OP_ENABLE:
- debug_printk(("4op\n"));
- if (get_user(dev, p))
- return -EFAULT;
- snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
- return 0;
-
- case SNDCTL_SYNTH_INFO:
- case SNDCTL_SYNTH_ID:
- debug_printk(("synth info\n"));
- return snd_seq_oss_synth_info_user(dp, arg);
-
- case SNDCTL_SEQ_OUTOFBAND:
- debug_printk(("out of band\n"));
- return snd_seq_oss_oob_user(dp, arg);
-
- case SNDCTL_MIDI_INFO:
- debug_printk(("midi info\n"));
- return snd_seq_oss_midi_info_user(dp, arg);
-
- case SNDCTL_SEQ_THRESHOLD:
- debug_printk(("threshold\n"));
- if (! is_write_mode(dp->file_mode))
- return 0;
- if (get_user(val, p))
- return -EFAULT;
- if (val < 1)
- val = 1;
- if (val >= dp->writeq->maxlen)
- val = dp->writeq->maxlen - 1;
- snd_seq_oss_writeq_set_output(dp->writeq, val);
- return 0;
-
- case SNDCTL_MIDI_PRETIME:
- debug_printk(("pretime\n"));
- if (dp->readq == NULL || !is_read_mode(dp->file_mode))
- return 0;
- if (get_user(val, p))
- return -EFAULT;
- if (val <= 0)
- val = -1;
- else
- val = (HZ * val) / 10;
- dp->readq->pre_event_timeout = val;
- return put_user(val, p) ? -EFAULT : 0;
-
- default:
- debug_printk(("others\n"));
- if (! is_write_mode(dp->file_mode))
- return -EIO;
- return snd_seq_oss_synth_ioctl(dp, 0, cmd, carg);
- }
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_midi.c b/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_midi.c
deleted file mode 100644
index 677dc845..00000000
--- a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_midi.c
+++ /dev/null
@@ -1,714 +0,0 @@
-/*
- * OSS compatible sequencer driver
- *
- * MIDI device handlers
- *
- * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <sound/asoundef.h>
-#include "seq_oss_midi.h"
-#include "seq_oss_readq.h"
-#include "seq_oss_timer.h"
-#include "seq_oss_event.h"
-#include <sound/seq_midi_event.h>
-#include "../seq_lock.h"
-#include <linux/init.h>
-#include <linux/slab.h>
-
-
-/*
- * constants
- */
-#define SNDRV_SEQ_OSS_MAX_MIDI_NAME 30
-
-/*
- * definition of midi device record
- */
-struct seq_oss_midi {
- int seq_device; /* device number */
- int client; /* sequencer client number */
- int port; /* sequencer port number */
- unsigned int flags; /* port capability */
- int opened; /* flag for opening */
- unsigned char name[SNDRV_SEQ_OSS_MAX_MIDI_NAME];
- struct snd_midi_event *coder; /* MIDI event coder */
- struct seq_oss_devinfo *devinfo; /* assigned OSSseq device */
- snd_use_lock_t use_lock;
-};
-
-
-/*
- * midi device table
- */
-static int max_midi_devs;
-static struct seq_oss_midi *midi_devs[SNDRV_SEQ_OSS_MAX_MIDI_DEVS];
-
-static DEFINE_SPINLOCK(register_lock);
-
-/*
- * prototypes
- */
-static struct seq_oss_midi *get_mdev(int dev);
-static struct seq_oss_midi *get_mididev(struct seq_oss_devinfo *dp, int dev);
-static int send_synth_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, int dev);
-static int send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, struct seq_oss_midi *mdev);
-
-/*
- * look up the existing ports
- * this looks a very exhausting job.
- */
-int __init
-snd_seq_oss_midi_lookup_ports(int client)
-{
- struct snd_seq_client_info *clinfo;
- struct snd_seq_port_info *pinfo;
-
- clinfo = kzalloc(sizeof(*clinfo), GFP_KERNEL);
- pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL);
- if (! clinfo || ! pinfo) {
- kfree(clinfo);
- kfree(pinfo);
- return -ENOMEM;
- }
- clinfo->client = -1;
- while (snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT, clinfo) == 0) {
- if (clinfo->client == client)
- continue; /* ignore myself */
- pinfo->addr.client = clinfo->client;
- pinfo->addr.port = -1;
- while (snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, pinfo) == 0)
- snd_seq_oss_midi_check_new_port(pinfo);
- }
- kfree(clinfo);
- kfree(pinfo);
- return 0;
-}
-
-
-/*
- */
-static struct seq_oss_midi *
-get_mdev(int dev)
-{
- struct seq_oss_midi *mdev;
- unsigned long flags;
-
- spin_lock_irqsave(&register_lock, flags);
- mdev = midi_devs[dev];
- if (mdev)
- snd_use_lock_use(&mdev->use_lock);
- spin_unlock_irqrestore(&register_lock, flags);
- return mdev;
-}
-
-/*
- * look for the identical slot
- */
-static struct seq_oss_midi *
-find_slot(int client, int port)
-{
- int i;
- struct seq_oss_midi *mdev;
- unsigned long flags;
-
- spin_lock_irqsave(&register_lock, flags);
- for (i = 0; i < max_midi_devs; i++) {
- mdev = midi_devs[i];
- if (mdev && mdev->client == client && mdev->port == port) {
- /* found! */
- snd_use_lock_use(&mdev->use_lock);
- spin_unlock_irqrestore(&register_lock, flags);
- return mdev;
- }
- }
- spin_unlock_irqrestore(&register_lock, flags);
- return NULL;
-}
-
-
-#define PERM_WRITE (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_SUBS_WRITE)
-#define PERM_READ (SNDRV_SEQ_PORT_CAP_READ|SNDRV_SEQ_PORT_CAP_SUBS_READ)
-/*
- * register a new port if it doesn't exist yet
- */
-int
-snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo)
-{
- int i;
- struct seq_oss_midi *mdev;
- unsigned long flags;
-
- debug_printk(("check for MIDI client %d port %d\n", pinfo->addr.client, pinfo->addr.port));
- /* the port must include generic midi */
- if (! (pinfo->type & SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC))
- return 0;
- /* either read or write subscribable */
- if ((pinfo->capability & PERM_WRITE) != PERM_WRITE &&
- (pinfo->capability & PERM_READ) != PERM_READ)
- return 0;
-
- /*
- * look for the identical slot
- */
- if ((mdev = find_slot(pinfo->addr.client, pinfo->addr.port)) != NULL) {
- /* already exists */
- snd_use_lock_free(&mdev->use_lock);
- return 0;
- }
-
- /*
- * allocate midi info record
- */
- if ((mdev = kzalloc(sizeof(*mdev), GFP_KERNEL)) == NULL) {
- snd_printk(KERN_ERR "can't malloc midi info\n");
- return -ENOMEM;
- }
-
- /* copy the port information */
- mdev->client = pinfo->addr.client;
- mdev->port = pinfo->addr.port;
- mdev->flags = pinfo->capability;
- mdev->opened = 0;
- snd_use_lock_init(&mdev->use_lock);
-
- /* copy and truncate the name of synth device */
- strlcpy(mdev->name, pinfo->name, sizeof(mdev->name));
-
- /* create MIDI coder */
- if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &mdev->coder) < 0) {
- snd_printk(KERN_ERR "can't malloc midi coder\n");
- kfree(mdev);
- return -ENOMEM;
- }
- /* OSS sequencer adds running status to all sequences */
- snd_midi_event_no_status(mdev->coder, 1);
-
- /*
- * look for en empty slot
- */
- spin_lock_irqsave(&register_lock, flags);
- for (i = 0; i < max_midi_devs; i++) {
- if (midi_devs[i] == NULL)
- break;
- }
- if (i >= max_midi_devs) {
- if (max_midi_devs >= SNDRV_SEQ_OSS_MAX_MIDI_DEVS) {
- spin_unlock_irqrestore(&register_lock, flags);
- snd_midi_event_free(mdev->coder);
- kfree(mdev);
- return -ENOMEM;
- }
- max_midi_devs++;
- }
- mdev->seq_device = i;
- midi_devs[mdev->seq_device] = mdev;
- spin_unlock_irqrestore(&register_lock, flags);
-
- return 0;
-}
-
-/*
- * release the midi device if it was registered
- */
-int
-snd_seq_oss_midi_check_exit_port(int client, int port)
-{
- struct seq_oss_midi *mdev;
- unsigned long flags;
- int index;
-
- if ((mdev = find_slot(client, port)) != NULL) {
- spin_lock_irqsave(&register_lock, flags);
- midi_devs[mdev->seq_device] = NULL;
- spin_unlock_irqrestore(&register_lock, flags);
- snd_use_lock_free(&mdev->use_lock);
- snd_use_lock_sync(&mdev->use_lock);
- if (mdev->coder)
- snd_midi_event_free(mdev->coder);
- kfree(mdev);
- }
- spin_lock_irqsave(&register_lock, flags);
- for (index = max_midi_devs - 1; index >= 0; index--) {
- if (midi_devs[index])
- break;
- }
- max_midi_devs = index + 1;
- spin_unlock_irqrestore(&register_lock, flags);
- return 0;
-}
-
-
-/*
- * release the midi device if it was registered
- */
-void
-snd_seq_oss_midi_clear_all(void)
-{
- int i;
- struct seq_oss_midi *mdev;
- unsigned long flags;
-
- spin_lock_irqsave(&register_lock, flags);
- for (i = 0; i < max_midi_devs; i++) {
- if ((mdev = midi_devs[i]) != NULL) {
- if (mdev->coder)
- snd_midi_event_free(mdev->coder);
- kfree(mdev);
- midi_devs[i] = NULL;
- }
- }
- max_midi_devs = 0;
- spin_unlock_irqrestore(&register_lock, flags);
-}
-
-
-/*
- * set up midi tables
- */
-void
-snd_seq_oss_midi_setup(struct seq_oss_devinfo *dp)
-{
- dp->max_mididev = max_midi_devs;
-}
-
-/*
- * clean up midi tables
- */
-void
-snd_seq_oss_midi_cleanup(struct seq_oss_devinfo *dp)
-{
- int i;
- for (i = 0; i < dp->max_mididev; i++)
- snd_seq_oss_midi_close(dp, i);
- dp->max_mididev = 0;
-}
-
-
-/*
- * open all midi devices. ignore errors.
- */
-void
-snd_seq_oss_midi_open_all(struct seq_oss_devinfo *dp, int file_mode)
-{
- int i;
- for (i = 0; i < dp->max_mididev; i++)
- snd_seq_oss_midi_open(dp, i, file_mode);
-}
-
-
-/*
- * get the midi device information
- */
-static struct seq_oss_midi *
-get_mididev(struct seq_oss_devinfo *dp, int dev)
-{
- if (dev < 0 || dev >= dp->max_mididev)
- return NULL;
- return get_mdev(dev);
-}
-
-
-/*
- * open the midi device if not opened yet
- */
-int
-snd_seq_oss_midi_open(struct seq_oss_devinfo *dp, int dev, int fmode)
-{
- int perm;
- struct seq_oss_midi *mdev;
- struct snd_seq_port_subscribe subs;
-
- if ((mdev = get_mididev(dp, dev)) == NULL)
- return -ENODEV;
-
- /* already used? */
- if (mdev->opened && mdev->devinfo != dp) {
- snd_use_lock_free(&mdev->use_lock);
- return -EBUSY;
- }
-
- perm = 0;
- if (is_write_mode(fmode))
- perm |= PERM_WRITE;
- if (is_read_mode(fmode))
- perm |= PERM_READ;
- perm &= mdev->flags;
- if (perm == 0) {
- snd_use_lock_free(&mdev->use_lock);
- return -ENXIO;
- }
-
- /* already opened? */
- if ((mdev->opened & perm) == perm) {
- snd_use_lock_free(&mdev->use_lock);
- return 0;
- }
-
- perm &= ~mdev->opened;
-
- memset(&subs, 0, sizeof(subs));
-
- if (perm & PERM_WRITE) {
- subs.sender = dp->addr;
- subs.dest.client = mdev->client;
- subs.dest.port = mdev->port;
- if (snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &subs) >= 0)
- mdev->opened |= PERM_WRITE;
- }
- if (perm & PERM_READ) {
- subs.sender.client = mdev->client;
- subs.sender.port = mdev->port;
- subs.dest = dp->addr;
- subs.flags = SNDRV_SEQ_PORT_SUBS_TIMESTAMP;
- subs.queue = dp->queue; /* queue for timestamps */
- if (snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &subs) >= 0)
- mdev->opened |= PERM_READ;
- }
-
- if (! mdev->opened) {
- snd_use_lock_free(&mdev->use_lock);
- return -ENXIO;
- }
-
- mdev->devinfo = dp;
- snd_use_lock_free(&mdev->use_lock);
- return 0;
-}
-
-/*
- * close the midi device if already opened
- */
-int
-snd_seq_oss_midi_close(struct seq_oss_devinfo *dp, int dev)
-{
- struct seq_oss_midi *mdev;
- struct snd_seq_port_subscribe subs;
-
- if ((mdev = get_mididev(dp, dev)) == NULL)
- return -ENODEV;
- if (! mdev->opened || mdev->devinfo != dp) {
- snd_use_lock_free(&mdev->use_lock);
- return 0;
- }
-
- debug_printk(("closing client %d port %d mode %d\n", mdev->client, mdev->port, mdev->opened));
- memset(&subs, 0, sizeof(subs));
- if (mdev->opened & PERM_WRITE) {
- subs.sender = dp->addr;
- subs.dest.client = mdev->client;
- subs.dest.port = mdev->port;
- snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, &subs);
- }
- if (mdev->opened & PERM_READ) {
- subs.sender.client = mdev->client;
- subs.sender.port = mdev->port;
- subs.dest = dp->addr;
- snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, &subs);
- }
-
- mdev->opened = 0;
- mdev->devinfo = NULL;
-
- snd_use_lock_free(&mdev->use_lock);
- return 0;
-}
-
-/*
- * change seq capability flags to file mode flags
- */
-int
-snd_seq_oss_midi_filemode(struct seq_oss_devinfo *dp, int dev)
-{
- struct seq_oss_midi *mdev;
- int mode;
-
- if ((mdev = get_mididev(dp, dev)) == NULL)
- return 0;
-
- mode = 0;
- if (mdev->opened & PERM_WRITE)
- mode |= SNDRV_SEQ_OSS_FILE_WRITE;
- if (mdev->opened & PERM_READ)
- mode |= SNDRV_SEQ_OSS_FILE_READ;
-
- snd_use_lock_free(&mdev->use_lock);
- return mode;
-}
-
-/*
- * reset the midi device and close it:
- * so far, only close the device.
- */
-void
-snd_seq_oss_midi_reset(struct seq_oss_devinfo *dp, int dev)
-{
- struct seq_oss_midi *mdev;
-
- if ((mdev = get_mididev(dp, dev)) == NULL)
- return;
- if (! mdev->opened) {
- snd_use_lock_free(&mdev->use_lock);
- return;
- }
-
- if (mdev->opened & PERM_WRITE) {
- struct snd_seq_event ev;
- int c;
-
- debug_printk(("resetting client %d port %d\n", mdev->client, mdev->port));
- memset(&ev, 0, sizeof(ev));
- ev.dest.client = mdev->client;
- ev.dest.port = mdev->port;
- ev.queue = dp->queue;
- ev.source.port = dp->port;
- if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH) {
- ev.type = SNDRV_SEQ_EVENT_SENSING;
- snd_seq_oss_dispatch(dp, &ev, 0, 0);
- }
- for (c = 0; c < 16; c++) {
- ev.type = SNDRV_SEQ_EVENT_CONTROLLER;
- ev.data.control.channel = c;
- ev.data.control.param = MIDI_CTL_ALL_NOTES_OFF;
- snd_seq_oss_dispatch(dp, &ev, 0, 0);
- if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) {
- ev.data.control.param =
- MIDI_CTL_RESET_CONTROLLERS;
- snd_seq_oss_dispatch(dp, &ev, 0, 0);
- ev.type = SNDRV_SEQ_EVENT_PITCHBEND;
- ev.data.control.value = 0;
- snd_seq_oss_dispatch(dp, &ev, 0, 0);
- }
- }
- }
- // snd_seq_oss_midi_close(dp, dev);
- snd_use_lock_free(&mdev->use_lock);
-}
-
-
-/*
- * get client/port of the specified MIDI device
- */
-void
-snd_seq_oss_midi_get_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_addr *addr)
-{
- struct seq_oss_midi *mdev;
-
- if ((mdev = get_mididev(dp, dev)) == NULL)
- return;
- addr->client = mdev->client;
- addr->port = mdev->port;
- snd_use_lock_free(&mdev->use_lock);
-}
-
-
-/*
- * input callback - this can be atomic
- */
-int
-snd_seq_oss_midi_input(struct snd_seq_event *ev, int direct, void *private_data)
-{
- struct seq_oss_devinfo *dp = (struct seq_oss_devinfo *)private_data;
- struct seq_oss_midi *mdev;
- int rc;
-
- if (dp->readq == NULL)
- return 0;
- if ((mdev = find_slot(ev->source.client, ev->source.port)) == NULL)
- return 0;
- if (! (mdev->opened & PERM_READ)) {
- snd_use_lock_free(&mdev->use_lock);
- return 0;
- }
-
- if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC)
- rc = send_synth_event(dp, ev, mdev->seq_device);
- else
- rc = send_midi_event(dp, ev, mdev);
-
- snd_use_lock_free(&mdev->use_lock);
- return rc;
-}
-
-/*
- * convert ALSA sequencer event to OSS synth event
- */
-static int
-send_synth_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, int dev)
-{
- union evrec ossev;
-
- memset(&ossev, 0, sizeof(ossev));
-
- switch (ev->type) {
- case SNDRV_SEQ_EVENT_NOTEON:
- ossev.v.cmd = MIDI_NOTEON; break;
- case SNDRV_SEQ_EVENT_NOTEOFF:
- ossev.v.cmd = MIDI_NOTEOFF; break;
- case SNDRV_SEQ_EVENT_KEYPRESS:
- ossev.v.cmd = MIDI_KEY_PRESSURE; break;
- case SNDRV_SEQ_EVENT_CONTROLLER:
- ossev.l.cmd = MIDI_CTL_CHANGE; break;
- case SNDRV_SEQ_EVENT_PGMCHANGE:
- ossev.l.cmd = MIDI_PGM_CHANGE; break;
- case SNDRV_SEQ_EVENT_CHANPRESS:
- ossev.l.cmd = MIDI_CHN_PRESSURE; break;
- case SNDRV_SEQ_EVENT_PITCHBEND:
- ossev.l.cmd = MIDI_PITCH_BEND; break;
- default:
- return 0; /* not supported */
- }
-
- ossev.v.dev = dev;
-
- switch (ev->type) {
- case SNDRV_SEQ_EVENT_NOTEON:
- case SNDRV_SEQ_EVENT_NOTEOFF:
- case SNDRV_SEQ_EVENT_KEYPRESS:
- ossev.v.code = EV_CHN_VOICE;
- ossev.v.note = ev->data.note.note;
- ossev.v.parm = ev->data.note.velocity;
- ossev.v.chn = ev->data.note.channel;
- break;
- case SNDRV_SEQ_EVENT_CONTROLLER:
- case SNDRV_SEQ_EVENT_PGMCHANGE:
- case SNDRV_SEQ_EVENT_CHANPRESS:
- ossev.l.code = EV_CHN_COMMON;
- ossev.l.p1 = ev->data.control.param;
- ossev.l.val = ev->data.control.value;
- ossev.l.chn = ev->data.control.channel;
- break;
- case SNDRV_SEQ_EVENT_PITCHBEND:
- ossev.l.code = EV_CHN_COMMON;
- ossev.l.val = ev->data.control.value + 8192;
- ossev.l.chn = ev->data.control.channel;
- break;
- }
-
- snd_seq_oss_readq_put_timestamp(dp->readq, ev->time.tick, dp->seq_mode);
- snd_seq_oss_readq_put_event(dp->readq, &ossev);
-
- return 0;
-}
-
-/*
- * decode event and send MIDI bytes to read queue
- */
-static int
-send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, struct seq_oss_midi *mdev)
-{
- char msg[32];
- int len;
-
- snd_seq_oss_readq_put_timestamp(dp->readq, ev->time.tick, dp->seq_mode);
- if (!dp->timer->running)
- len = snd_seq_oss_timer_start(dp->timer);
- if (ev->type == SNDRV_SEQ_EVENT_SYSEX) {
- if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) == SNDRV_SEQ_EVENT_LENGTH_VARIABLE)
- snd_seq_oss_readq_puts(dp->readq, mdev->seq_device,
- ev->data.ext.ptr, ev->data.ext.len);
- } else {
- len = snd_midi_event_decode(mdev->coder, msg, sizeof(msg), ev);
- if (len > 0)
- snd_seq_oss_readq_puts(dp->readq, mdev->seq_device, msg, len);
- }
-
- return 0;
-}
-
-
-/*
- * dump midi data
- * return 0 : enqueued
- * non-zero : invalid - ignored
- */
-int
-snd_seq_oss_midi_putc(struct seq_oss_devinfo *dp, int dev, unsigned char c, struct snd_seq_event *ev)
-{
- struct seq_oss_midi *mdev;
-
- if ((mdev = get_mididev(dp, dev)) == NULL)
- return -ENODEV;
- if (snd_midi_event_encode_byte(mdev->coder, c, ev) > 0) {
- snd_seq_oss_fill_addr(dp, ev, mdev->client, mdev->port);
- snd_use_lock_free(&mdev->use_lock);
- return 0;
- }
- snd_use_lock_free(&mdev->use_lock);
- return -EINVAL;
-}
-
-/*
- * create OSS compatible midi_info record
- */
-int
-snd_seq_oss_midi_make_info(struct seq_oss_devinfo *dp, int dev, struct midi_info *inf)
-{
- struct seq_oss_midi *mdev;
-
- if ((mdev = get_mididev(dp, dev)) == NULL)
- return -ENXIO;
- inf->device = dev;
- inf->dev_type = 0; /* FIXME: ?? */
- inf->capabilities = 0; /* FIXME: ?? */
- strlcpy(inf->name, mdev->name, sizeof(inf->name));
- snd_use_lock_free(&mdev->use_lock);
- return 0;
-}
-
-
-#ifdef CONFIG_PROC_FS
-/*
- * proc interface
- */
-static char *
-capmode_str(int val)
-{
- val &= PERM_READ|PERM_WRITE;
- if (val == (PERM_READ|PERM_WRITE))
- return "read/write";
- else if (val == PERM_READ)
- return "read";
- else if (val == PERM_WRITE)
- return "write";
- else
- return "none";
-}
-
-void
-snd_seq_oss_midi_info_read(struct snd_info_buffer *buf)
-{
- int i;
- struct seq_oss_midi *mdev;
-
- snd_iprintf(buf, "\nNumber of MIDI devices: %d\n", max_midi_devs);
- for (i = 0; i < max_midi_devs; i++) {
- snd_iprintf(buf, "\nmidi %d: ", i);
- mdev = get_mdev(i);
- if (mdev == NULL) {
- snd_iprintf(buf, "*empty*\n");
- continue;
- }
- snd_iprintf(buf, "[%s] ALSA port %d:%d\n", mdev->name,
- mdev->client, mdev->port);
- snd_iprintf(buf, " capability %s / opened %s\n",
- capmode_str(mdev->flags),
- capmode_str(mdev->opened));
- snd_use_lock_free(&mdev->use_lock);
- }
-}
-#endif /* CONFIG_PROC_FS */
diff --git a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_midi.h b/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_midi.h
deleted file mode 100644
index 84eb866b..00000000
--- a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_midi.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * OSS compatible sequencer driver
- *
- * midi device information
- *
- * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __SEQ_OSS_MIDI_H
-#define __SEQ_OSS_MIDI_H
-
-#include "seq_oss_device.h"
-#include <sound/seq_oss_legacy.h>
-
-int snd_seq_oss_midi_lookup_ports(int client);
-int snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo);
-int snd_seq_oss_midi_check_exit_port(int client, int port);
-void snd_seq_oss_midi_clear_all(void);
-
-void snd_seq_oss_midi_setup(struct seq_oss_devinfo *dp);
-void snd_seq_oss_midi_cleanup(struct seq_oss_devinfo *dp);
-
-int snd_seq_oss_midi_open(struct seq_oss_devinfo *dp, int dev, int file_mode);
-void snd_seq_oss_midi_open_all(struct seq_oss_devinfo *dp, int file_mode);
-int snd_seq_oss_midi_close(struct seq_oss_devinfo *dp, int dev);
-void snd_seq_oss_midi_reset(struct seq_oss_devinfo *dp, int dev);
-int snd_seq_oss_midi_putc(struct seq_oss_devinfo *dp, int dev, unsigned char c,
- struct snd_seq_event *ev);
-int snd_seq_oss_midi_input(struct snd_seq_event *ev, int direct, void *private);
-int snd_seq_oss_midi_filemode(struct seq_oss_devinfo *dp, int dev);
-int snd_seq_oss_midi_make_info(struct seq_oss_devinfo *dp, int dev, struct midi_info *inf);
-void snd_seq_oss_midi_get_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_addr *addr);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_readq.c b/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_readq.c
deleted file mode 100644
index 73661c4a..00000000
--- a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_readq.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * OSS compatible sequencer driver
- *
- * seq_oss_readq.c - MIDI input queue
- *
- * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "seq_oss_readq.h"
-#include "seq_oss_event.h"
-#include <sound/seq_oss_legacy.h>
-#include "../seq_lock.h"
-#include <linux/wait.h>
-#include <linux/slab.h>
-
-/*
- * constants
- */
-//#define SNDRV_SEQ_OSS_MAX_TIMEOUT (unsigned long)(-1)
-#define SNDRV_SEQ_OSS_MAX_TIMEOUT (HZ * 3600)
-
-
-/*
- * prototypes
- */
-
-
-/*
- * create a read queue
- */
-struct seq_oss_readq *
-snd_seq_oss_readq_new(struct seq_oss_devinfo *dp, int maxlen)
-{
- struct seq_oss_readq *q;
-
- if ((q = kzalloc(sizeof(*q), GFP_KERNEL)) == NULL) {
- snd_printk(KERN_ERR "can't malloc read queue\n");
- return NULL;
- }
-
- if ((q->q = kcalloc(maxlen, sizeof(union evrec), GFP_KERNEL)) == NULL) {
- snd_printk(KERN_ERR "can't malloc read queue buffer\n");
- kfree(q);
- return NULL;
- }
-
- q->maxlen = maxlen;
- q->qlen = 0;
- q->head = q->tail = 0;
- init_waitqueue_head(&q->midi_sleep);
- spin_lock_init(&q->lock);
- q->pre_event_timeout = SNDRV_SEQ_OSS_MAX_TIMEOUT;
- q->input_time = (unsigned long)-1;
-
- return q;
-}
-
-/*
- * delete the read queue
- */
-void
-snd_seq_oss_readq_delete(struct seq_oss_readq *q)
-{
- if (q) {
- kfree(q->q);
- kfree(q);
- }
-}
-
-/*
- * reset the read queue
- */
-void
-snd_seq_oss_readq_clear(struct seq_oss_readq *q)
-{
- if (q->qlen) {
- q->qlen = 0;
- q->head = q->tail = 0;
- }
- /* if someone sleeping, wake'em up */
- if (waitqueue_active(&q->midi_sleep))
- wake_up(&q->midi_sleep);
- q->input_time = (unsigned long)-1;
-}
-
-/*
- * put a midi byte
- */
-int
-snd_seq_oss_readq_puts(struct seq_oss_readq *q, int dev, unsigned char *data, int len)
-{
- union evrec rec;
- int result;
-
- memset(&rec, 0, sizeof(rec));
- rec.c[0] = SEQ_MIDIPUTC;
- rec.c[2] = dev;
-
- while (len-- > 0) {
- rec.c[1] = *data++;
- result = snd_seq_oss_readq_put_event(q, &rec);
- if (result < 0)
- return result;
- }
- return 0;
-}
-
-/*
- * copy an event to input queue:
- * return zero if enqueued
- */
-int
-snd_seq_oss_readq_put_event(struct seq_oss_readq *q, union evrec *ev)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&q->lock, flags);
- if (q->qlen >= q->maxlen - 1) {
- spin_unlock_irqrestore(&q->lock, flags);
- return -ENOMEM;
- }
-
- memcpy(&q->q[q->tail], ev, sizeof(*ev));
- q->tail = (q->tail + 1) % q->maxlen;
- q->qlen++;
-
- /* wake up sleeper */
- if (waitqueue_active(&q->midi_sleep))
- wake_up(&q->midi_sleep);
-
- spin_unlock_irqrestore(&q->lock, flags);
-
- return 0;
-}
-
-
-/*
- * pop queue
- * caller must hold lock
- */
-int
-snd_seq_oss_readq_pick(struct seq_oss_readq *q, union evrec *rec)
-{
- if (q->qlen == 0)
- return -EAGAIN;
- memcpy(rec, &q->q[q->head], sizeof(*rec));
- return 0;
-}
-
-/*
- * sleep until ready
- */
-void
-snd_seq_oss_readq_wait(struct seq_oss_readq *q)
-{
- wait_event_interruptible_timeout(q->midi_sleep,
- (q->qlen > 0 || q->head == q->tail),
- q->pre_event_timeout);
-}
-
-/*
- * drain one record
- * caller must hold lock
- */
-void
-snd_seq_oss_readq_free(struct seq_oss_readq *q)
-{
- if (q->qlen > 0) {
- q->head = (q->head + 1) % q->maxlen;
- q->qlen--;
- }
-}
-
-/*
- * polling/select:
- * return non-zero if readq is not empty.
- */
-unsigned int
-snd_seq_oss_readq_poll(struct seq_oss_readq *q, struct file *file, poll_table *wait)
-{
- poll_wait(file, &q->midi_sleep, wait);
- return q->qlen;
-}
-
-/*
- * put a timestamp
- */
-int
-snd_seq_oss_readq_put_timestamp(struct seq_oss_readq *q, unsigned long curt, int seq_mode)
-{
- if (curt != q->input_time) {
- union evrec rec;
- memset(&rec, 0, sizeof(rec));
- switch (seq_mode) {
- case SNDRV_SEQ_OSS_MODE_SYNTH:
- rec.echo = (curt << 8) | SEQ_WAIT;
- snd_seq_oss_readq_put_event(q, &rec);
- break;
- case SNDRV_SEQ_OSS_MODE_MUSIC:
- rec.t.code = EV_TIMING;
- rec.t.cmd = TMR_WAIT_ABS;
- rec.t.time = curt;
- snd_seq_oss_readq_put_event(q, &rec);
- break;
- }
- q->input_time = curt;
- }
- return 0;
-}
-
-
-#ifdef CONFIG_PROC_FS
-/*
- * proc interface
- */
-void
-snd_seq_oss_readq_info_read(struct seq_oss_readq *q, struct snd_info_buffer *buf)
-{
- snd_iprintf(buf, " read queue [%s] length = %d : tick = %ld\n",
- (waitqueue_active(&q->midi_sleep) ? "sleeping":"running"),
- q->qlen, q->input_time);
-}
-#endif /* CONFIG_PROC_FS */
diff --git a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_readq.h b/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_readq.h
deleted file mode 100644
index f1463f1f..00000000
--- a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_readq.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * OSS compatible sequencer driver
- * read fifo queue
- *
- * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __SEQ_OSS_READQ_H
-#define __SEQ_OSS_READQ_H
-
-#include "seq_oss_device.h"
-
-
-/*
- * definition of read queue
- */
-struct seq_oss_readq {
- union evrec *q;
- int qlen;
- int maxlen;
- int head, tail;
- unsigned long pre_event_timeout;
- unsigned long input_time;
- wait_queue_head_t midi_sleep;
- spinlock_t lock;
-};
-
-struct seq_oss_readq *snd_seq_oss_readq_new(struct seq_oss_devinfo *dp, int maxlen);
-void snd_seq_oss_readq_delete(struct seq_oss_readq *q);
-void snd_seq_oss_readq_clear(struct seq_oss_readq *readq);
-unsigned int snd_seq_oss_readq_poll(struct seq_oss_readq *readq, struct file *file, poll_table *wait);
-int snd_seq_oss_readq_puts(struct seq_oss_readq *readq, int dev, unsigned char *data, int len);
-int snd_seq_oss_readq_put_event(struct seq_oss_readq *readq, union evrec *ev);
-int snd_seq_oss_readq_put_timestamp(struct seq_oss_readq *readq, unsigned long curt, int seq_mode);
-int snd_seq_oss_readq_pick(struct seq_oss_readq *q, union evrec *rec);
-void snd_seq_oss_readq_wait(struct seq_oss_readq *q);
-void snd_seq_oss_readq_free(struct seq_oss_readq *q);
-
-#define snd_seq_oss_readq_lock(q, flags) spin_lock_irqsave(&(q)->lock, flags)
-#define snd_seq_oss_readq_unlock(q, flags) spin_unlock_irqrestore(&(q)->lock, flags)
-
-#endif
diff --git a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_rw.c b/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_rw.c
deleted file mode 100644
index 6a7b6ace..00000000
--- a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_rw.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * OSS compatible sequencer driver
- *
- * read/write/select interface to device file
- *
- * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "seq_oss_device.h"
-#include "seq_oss_readq.h"
-#include "seq_oss_writeq.h"
-#include "seq_oss_synth.h"
-#include <sound/seq_oss_legacy.h>
-#include "seq_oss_event.h"
-#include "seq_oss_timer.h"
-#include "../seq_clientmgr.h"
-
-
-/*
- * protoypes
- */
-static int insert_queue(struct seq_oss_devinfo *dp, union evrec *rec, struct file *opt);
-
-
-/*
- * read interface
- */
-
-int
-snd_seq_oss_read(struct seq_oss_devinfo *dp, char __user *buf, int count)
-{
- struct seq_oss_readq *readq = dp->readq;
- int result = 0, err = 0;
- int ev_len;
- union evrec rec;
- unsigned long flags;
-
- if (readq == NULL || ! is_read_mode(dp->file_mode))
- return -ENXIO;
-
- while (count >= SHORT_EVENT_SIZE) {
- snd_seq_oss_readq_lock(readq, flags);
- err = snd_seq_oss_readq_pick(readq, &rec);
- if (err == -EAGAIN &&
- !is_nonblock_mode(dp->file_mode) && result == 0) {
- snd_seq_oss_readq_unlock(readq, flags);
- snd_seq_oss_readq_wait(readq);
- snd_seq_oss_readq_lock(readq, flags);
- if (signal_pending(current))
- err = -ERESTARTSYS;
- else
- err = snd_seq_oss_readq_pick(readq, &rec);
- }
- if (err < 0) {
- snd_seq_oss_readq_unlock(readq, flags);
- break;
- }
- ev_len = ev_length(&rec);
- if (ev_len < count) {
- snd_seq_oss_readq_unlock(readq, flags);
- break;
- }
- snd_seq_oss_readq_free(readq);
- snd_seq_oss_readq_unlock(readq, flags);
- if (copy_to_user(buf, &rec, ev_len)) {
- err = -EFAULT;
- break;
- }
- result += ev_len;
- buf += ev_len;
- count -= ev_len;
- }
- return result > 0 ? result : err;
-}
-
-
-/*
- * write interface
- */
-
-int
-snd_seq_oss_write(struct seq_oss_devinfo *dp, const char __user *buf, int count, struct file *opt)
-{
- int result = 0, err = 0;
- int ev_size, fmt;
- union evrec rec;
-
- if (! is_write_mode(dp->file_mode) || dp->writeq == NULL)
- return -ENXIO;
-
- while (count >= SHORT_EVENT_SIZE) {
- if (copy_from_user(&rec, buf, SHORT_EVENT_SIZE)) {
- err = -EFAULT;
- break;
- }
- if (rec.s.code == SEQ_FULLSIZE) {
- /* load patch */
- if (result > 0) {
- err = -EINVAL;
- break;
- }
- fmt = (*(unsigned short *)rec.c) & 0xffff;
- /* FIXME the return value isn't correct */
- return snd_seq_oss_synth_load_patch(dp, rec.s.dev,
- fmt, buf, 0, count);
- }
- if (ev_is_long(&rec)) {
- /* extended code */
- if (rec.s.code == SEQ_EXTENDED &&
- dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) {
- err = -EINVAL;
- break;
- }
- ev_size = LONG_EVENT_SIZE;
- if (count < ev_size)
- break;
- /* copy the reset 4 bytes */
- if (copy_from_user(rec.c + SHORT_EVENT_SIZE,
- buf + SHORT_EVENT_SIZE,
- LONG_EVENT_SIZE - SHORT_EVENT_SIZE)) {
- err = -EFAULT;
- break;
- }
- } else {
- /* old-type code */
- if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) {
- err = -EINVAL;
- break;
- }
- ev_size = SHORT_EVENT_SIZE;
- }
-
- /* insert queue */
- if ((err = insert_queue(dp, &rec, opt)) < 0)
- break;
-
- result += ev_size;
- buf += ev_size;
- count -= ev_size;
- }
- return result > 0 ? result : err;
-}
-
-
-/*
- * insert event record to write queue
- * return: 0 = OK, non-zero = NG
- */
-static int
-insert_queue(struct seq_oss_devinfo *dp, union evrec *rec, struct file *opt)
-{
- int rc = 0;
- struct snd_seq_event event;
-
- /* if this is a timing event, process the current time */
- if (snd_seq_oss_process_timer_event(dp->timer, rec))
- return 0; /* no need to insert queue */
-
- /* parse this event */
- memset(&event, 0, sizeof(event));
- /* set dummy -- to be sure */
- event.type = SNDRV_SEQ_EVENT_NOTEOFF;
- snd_seq_oss_fill_addr(dp, &event, dp->addr.port, dp->addr.client);
-
- if (snd_seq_oss_process_event(dp, rec, &event))
- return 0; /* invalid event - no need to insert queue */
-
- event.time.tick = snd_seq_oss_timer_cur_tick(dp->timer);
- if (dp->timer->realtime || !dp->timer->running) {
- snd_seq_oss_dispatch(dp, &event, 0, 0);
- } else {
- if (is_nonblock_mode(dp->file_mode))
- rc = snd_seq_kernel_client_enqueue(dp->cseq, &event, 0, 0);
- else
- rc = snd_seq_kernel_client_enqueue_blocking(dp->cseq, &event, opt, 0, 0);
- }
- return rc;
-}
-
-
-/*
- * select / poll
- */
-
-unsigned int
-snd_seq_oss_poll(struct seq_oss_devinfo *dp, struct file *file, poll_table * wait)
-{
- unsigned int mask = 0;
-
- /* input */
- if (dp->readq && is_read_mode(dp->file_mode)) {
- if (snd_seq_oss_readq_poll(dp->readq, file, wait))
- mask |= POLLIN | POLLRDNORM;
- }
-
- /* output */
- if (dp->writeq && is_write_mode(dp->file_mode)) {
- if (snd_seq_kernel_client_write_poll(dp->cseq, file, wait))
- mask |= POLLOUT | POLLWRNORM;
- }
- return mask;
-}
diff --git a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_synth.c b/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_synth.c
deleted file mode 100644
index c5b773a1..00000000
--- a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_synth.c
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
- * OSS compatible sequencer driver
- *
- * synth device handlers
- *
- * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "seq_oss_synth.h"
-#include "seq_oss_midi.h"
-#include "../seq_lock.h"
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-/*
- * constants
- */
-#define SNDRV_SEQ_OSS_MAX_SYNTH_NAME 30
-#define MAX_SYSEX_BUFLEN 128
-
-
-/*
- * definition of synth info records
- */
-
-/* sysex buffer */
-struct seq_oss_synth_sysex {
- int len;
- int skip;
- unsigned char buf[MAX_SYSEX_BUFLEN];
-};
-
-/* synth info */
-struct seq_oss_synth {
- int seq_device;
-
- /* for synth_info */
- int synth_type;
- int synth_subtype;
- int nr_voices;
-
- char name[SNDRV_SEQ_OSS_MAX_SYNTH_NAME];
- struct snd_seq_oss_callback oper;
-
- int opened;
-
- void *private_data;
- snd_use_lock_t use_lock;
-};
-
-
-/*
- * device table
- */
-static int max_synth_devs;
-static struct seq_oss_synth *synth_devs[SNDRV_SEQ_OSS_MAX_SYNTH_DEVS];
-static struct seq_oss_synth midi_synth_dev = {
- -1, /* seq_device */
- SYNTH_TYPE_MIDI, /* synth_type */
- 0, /* synth_subtype */
- 16, /* nr_voices */
- "MIDI", /* name */
-};
-
-static DEFINE_SPINLOCK(register_lock);
-
-/*
- * prototypes
- */
-static struct seq_oss_synth *get_synthdev(struct seq_oss_devinfo *dp, int dev);
-static void reset_channels(struct seq_oss_synthinfo *info);
-
-/*
- * global initialization
- */
-void __init
-snd_seq_oss_synth_init(void)
-{
- snd_use_lock_init(&midi_synth_dev.use_lock);
-}
-
-/*
- * registration of the synth device
- */
-int
-snd_seq_oss_synth_register(struct snd_seq_device *dev)
-{
- int i;
- struct seq_oss_synth *rec;
- struct snd_seq_oss_reg *reg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
- unsigned long flags;
-
- if ((rec = kzalloc(sizeof(*rec), GFP_KERNEL)) == NULL) {
- snd_printk(KERN_ERR "can't malloc synth info\n");
- return -ENOMEM;
- }
- rec->seq_device = -1;
- rec->synth_type = reg->type;
- rec->synth_subtype = reg->subtype;
- rec->nr_voices = reg->nvoices;
- rec->oper = reg->oper;
- rec->private_data = reg->private_data;
- rec->opened = 0;
- snd_use_lock_init(&rec->use_lock);
-
- /* copy and truncate the name of synth device */
- strlcpy(rec->name, dev->name, sizeof(rec->name));
-
- /* registration */
- spin_lock_irqsave(&register_lock, flags);
- for (i = 0; i < max_synth_devs; i++) {
- if (synth_devs[i] == NULL)
- break;
- }
- if (i >= max_synth_devs) {
- if (max_synth_devs >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS) {
- spin_unlock_irqrestore(&register_lock, flags);
- snd_printk(KERN_ERR "no more synth slot\n");
- kfree(rec);
- return -ENOMEM;
- }
- max_synth_devs++;
- }
- rec->seq_device = i;
- synth_devs[i] = rec;
- debug_printk(("synth %s registered %d\n", rec->name, i));
- spin_unlock_irqrestore(&register_lock, flags);
- dev->driver_data = rec;
-#ifdef SNDRV_OSS_INFO_DEV_SYNTH
- if (i < SNDRV_CARDS)
- snd_oss_info_register(SNDRV_OSS_INFO_DEV_SYNTH, i, rec->name);
-#endif
- return 0;
-}
-
-
-int
-snd_seq_oss_synth_unregister(struct snd_seq_device *dev)
-{
- int index;
- struct seq_oss_synth *rec = dev->driver_data;
- unsigned long flags;
-
- spin_lock_irqsave(&register_lock, flags);
- for (index = 0; index < max_synth_devs; index++) {
- if (synth_devs[index] == rec)
- break;
- }
- if (index >= max_synth_devs) {
- spin_unlock_irqrestore(&register_lock, flags);
- snd_printk(KERN_ERR "can't unregister synth\n");
- return -EINVAL;
- }
- synth_devs[index] = NULL;
- if (index == max_synth_devs - 1) {
- for (index--; index >= 0; index--) {
- if (synth_devs[index])
- break;
- }
- max_synth_devs = index + 1;
- }
- spin_unlock_irqrestore(&register_lock, flags);
-#ifdef SNDRV_OSS_INFO_DEV_SYNTH
- if (rec->seq_device < SNDRV_CARDS)
- snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_SYNTH, rec->seq_device);
-#endif
-
- snd_use_lock_sync(&rec->use_lock);
- kfree(rec);
-
- return 0;
-}
-
-
-/*
- */
-static struct seq_oss_synth *
-get_sdev(int dev)
-{
- struct seq_oss_synth *rec;
- unsigned long flags;
-
- spin_lock_irqsave(&register_lock, flags);
- rec = synth_devs[dev];
- if (rec)
- snd_use_lock_use(&rec->use_lock);
- spin_unlock_irqrestore(&register_lock, flags);
- return rec;
-}
-
-
-/*
- * set up synth tables
- */
-
-void
-snd_seq_oss_synth_setup(struct seq_oss_devinfo *dp)
-{
- int i;
- struct seq_oss_synth *rec;
- struct seq_oss_synthinfo *info;
-
- dp->max_synthdev = max_synth_devs;
- dp->synth_opened = 0;
- memset(dp->synths, 0, sizeof(dp->synths));
- for (i = 0; i < dp->max_synthdev; i++) {
- rec = get_sdev(i);
- if (rec == NULL)
- continue;
- if (rec->oper.open == NULL || rec->oper.close == NULL) {
- snd_use_lock_free(&rec->use_lock);
- continue;
- }
- info = &dp->synths[i];
- info->arg.app_index = dp->port;
- info->arg.file_mode = dp->file_mode;
- info->arg.seq_mode = dp->seq_mode;
- if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH)
- info->arg.event_passing = SNDRV_SEQ_OSS_PROCESS_EVENTS;
- else
- info->arg.event_passing = SNDRV_SEQ_OSS_PASS_EVENTS;
- info->opened = 0;
- if (!try_module_get(rec->oper.owner)) {
- snd_use_lock_free(&rec->use_lock);
- continue;
- }
- if (rec->oper.open(&info->arg, rec->private_data) < 0) {
- module_put(rec->oper.owner);
- snd_use_lock_free(&rec->use_lock);
- continue;
- }
- info->nr_voices = rec->nr_voices;
- if (info->nr_voices > 0) {
- info->ch = kcalloc(info->nr_voices, sizeof(struct seq_oss_chinfo), GFP_KERNEL);
- if (!info->ch) {
- snd_printk(KERN_ERR "Cannot malloc\n");
- rec->oper.close(&info->arg);
- module_put(rec->oper.owner);
- snd_use_lock_free(&rec->use_lock);
- continue;
- }
- reset_channels(info);
- }
- debug_printk(("synth %d assigned\n", i));
- info->opened++;
- rec->opened++;
- dp->synth_opened++;
- snd_use_lock_free(&rec->use_lock);
- }
-}
-
-
-/*
- * set up synth tables for MIDI emulation - /dev/music mode only
- */
-
-void
-snd_seq_oss_synth_setup_midi(struct seq_oss_devinfo *dp)
-{
- int i;
-
- if (dp->max_synthdev >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS)
- return;
-
- for (i = 0; i < dp->max_mididev; i++) {
- struct seq_oss_synthinfo *info;
- info = &dp->synths[dp->max_synthdev];
- if (snd_seq_oss_midi_open(dp, i, dp->file_mode) < 0)
- continue;
- info->arg.app_index = dp->port;
- info->arg.file_mode = dp->file_mode;
- info->arg.seq_mode = dp->seq_mode;
- info->arg.private_data = info;
- info->is_midi = 1;
- info->midi_mapped = i;
- info->arg.event_passing = SNDRV_SEQ_OSS_PASS_EVENTS;
- snd_seq_oss_midi_get_addr(dp, i, &info->arg.addr);
- info->opened = 1;
- midi_synth_dev.opened++;
- dp->max_synthdev++;
- if (dp->max_synthdev >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS)
- break;
- }
-}
-
-
-/*
- * clean up synth tables
- */
-
-void
-snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp)
-{
- int i;
- struct seq_oss_synth *rec;
- struct seq_oss_synthinfo *info;
-
- if (snd_BUG_ON(dp->max_synthdev >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS))
- return;
- for (i = 0; i < dp->max_synthdev; i++) {
- info = &dp->synths[i];
- if (! info->opened)
- continue;
- if (info->is_midi) {
- if (midi_synth_dev.opened > 0) {
- snd_seq_oss_midi_close(dp, info->midi_mapped);
- midi_synth_dev.opened--;
- }
- } else {
- rec = get_sdev(i);
- if (rec == NULL)
- continue;
- if (rec->opened > 0) {
- debug_printk(("synth %d closed\n", i));
- rec->oper.close(&info->arg);
- module_put(rec->oper.owner);
- rec->opened = 0;
- }
- snd_use_lock_free(&rec->use_lock);
- }
- kfree(info->sysex);
- info->sysex = NULL;
- kfree(info->ch);
- info->ch = NULL;
- }
- dp->synth_opened = 0;
- dp->max_synthdev = 0;
-}
-
-/*
- * check if the specified device is MIDI mapped device
- */
-static int
-is_midi_dev(struct seq_oss_devinfo *dp, int dev)
-{
- if (dev < 0 || dev >= dp->max_synthdev)
- return 0;
- if (dp->synths[dev].is_midi)
- return 1;
- return 0;
-}
-
-/*
- * return synth device information pointer
- */
-static struct seq_oss_synth *
-get_synthdev(struct seq_oss_devinfo *dp, int dev)
-{
- struct seq_oss_synth *rec;
- if (dev < 0 || dev >= dp->max_synthdev)
- return NULL;
- if (! dp->synths[dev].opened)
- return NULL;
- if (dp->synths[dev].is_midi)
- return &midi_synth_dev;
- if ((rec = get_sdev(dev)) == NULL)
- return NULL;
- if (! rec->opened) {
- snd_use_lock_free(&rec->use_lock);
- return NULL;
- }
- return rec;
-}
-
-
-/*
- * reset note and velocity on each channel.
- */
-static void
-reset_channels(struct seq_oss_synthinfo *info)
-{
- int i;
- if (info->ch == NULL || ! info->nr_voices)
- return;
- for (i = 0; i < info->nr_voices; i++) {
- info->ch[i].note = -1;
- info->ch[i].vel = 0;
- }
-}
-
-
-/*
- * reset synth device:
- * call reset callback. if no callback is defined, send a heartbeat
- * event to the corresponding port.
- */
-void
-snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev)
-{
- struct seq_oss_synth *rec;
- struct seq_oss_synthinfo *info;
-
- if (snd_BUG_ON(dev < 0 || dev >= dp->max_synthdev))
- return;
- info = &dp->synths[dev];
- if (! info->opened)
- return;
- if (info->sysex)
- info->sysex->len = 0; /* reset sysex */
- reset_channels(info);
- if (info->is_midi) {
- if (midi_synth_dev.opened <= 0)
- return;
- snd_seq_oss_midi_reset(dp, info->midi_mapped);
- /* reopen the device */
- snd_seq_oss_midi_close(dp, dev);
- if (snd_seq_oss_midi_open(dp, info->midi_mapped,
- dp->file_mode) < 0) {
- midi_synth_dev.opened--;
- info->opened = 0;
- kfree(info->sysex);
- info->sysex = NULL;
- kfree(info->ch);
- info->ch = NULL;
- }
- return;
- }
-
- rec = get_sdev(dev);
- if (rec == NULL)
- return;
- if (rec->oper.reset) {
- rec->oper.reset(&info->arg);
- } else {
- struct snd_seq_event ev;
- memset(&ev, 0, sizeof(ev));
- snd_seq_oss_fill_addr(dp, &ev, info->arg.addr.client,
- info->arg.addr.port);
- ev.type = SNDRV_SEQ_EVENT_RESET;
- snd_seq_oss_dispatch(dp, &ev, 0, 0);
- }
- snd_use_lock_free(&rec->use_lock);
-}
-
-
-/*
- * load a patch record:
- * call load_patch callback function
- */
-int
-snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
- const char __user *buf, int p, int c)
-{
- struct seq_oss_synth *rec;
- int rc;
-
- if (dev < 0 || dev >= dp->max_synthdev)
- return -ENXIO;
-
- if (is_midi_dev(dp, dev))
- return 0;
- if ((rec = get_synthdev(dp, dev)) == NULL)
- return -ENXIO;
-
- if (rec->oper.load_patch == NULL)
- rc = -ENXIO;
- else
- rc = rec->oper.load_patch(&dp->synths[dev].arg, fmt, buf, p, c);
- snd_use_lock_free(&rec->use_lock);
- return rc;
-}
-
-/*
- * check if the device is valid synth device
- */
-int
-snd_seq_oss_synth_is_valid(struct seq_oss_devinfo *dp, int dev)
-{
- struct seq_oss_synth *rec;
- rec = get_synthdev(dp, dev);
- if (rec) {
- snd_use_lock_free(&rec->use_lock);
- return 1;
- }
- return 0;
-}
-
-
-/*
- * receive OSS 6 byte sysex packet:
- * the full sysex message will be sent if it reaches to the end of data
- * (0xff).
- */
-int
-snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf, struct snd_seq_event *ev)
-{
- int i, send;
- unsigned char *dest;
- struct seq_oss_synth_sysex *sysex;
-
- if (! snd_seq_oss_synth_is_valid(dp, dev))
- return -ENXIO;
-
- sysex = dp->synths[dev].sysex;
- if (sysex == NULL) {
- sysex = kzalloc(sizeof(*sysex), GFP_KERNEL);
- if (sysex == NULL)
- return -ENOMEM;
- dp->synths[dev].sysex = sysex;
- }
-
- send = 0;
- dest = sysex->buf + sysex->len;
- /* copy 6 byte packet to the buffer */
- for (i = 0; i < 6; i++) {
- if (buf[i] == 0xff) {
- send = 1;
- break;
- }
- dest[i] = buf[i];
- sysex->len++;
- if (sysex->len >= MAX_SYSEX_BUFLEN) {
- sysex->len = 0;
- sysex->skip = 1;
- break;
- }
- }
-
- if (sysex->len && send) {
- if (sysex->skip) {
- sysex->skip = 0;
- sysex->len = 0;
- return -EINVAL; /* skip */
- }
- /* copy the data to event record and send it */
- ev->flags = SNDRV_SEQ_EVENT_LENGTH_VARIABLE;
- if (snd_seq_oss_synth_addr(dp, dev, ev))
- return -EINVAL;
- ev->data.ext.len = sysex->len;
- ev->data.ext.ptr = sysex->buf;
- sysex->len = 0;
- return 0;
- }
-
- return -EINVAL; /* skip */
-}
-
-/*
- * fill the event source/destination addresses
- */
-int
-snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev)
-{
- if (! snd_seq_oss_synth_is_valid(dp, dev))
- return -EINVAL;
- snd_seq_oss_fill_addr(dp, ev, dp->synths[dev].arg.addr.client,
- dp->synths[dev].arg.addr.port);
- return 0;
-}
-
-
-/*
- * OSS compatible ioctl
- */
-int
-snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, unsigned long addr)
-{
- struct seq_oss_synth *rec;
- int rc;
-
- if (is_midi_dev(dp, dev))
- return -ENXIO;
- if ((rec = get_synthdev(dp, dev)) == NULL)
- return -ENXIO;
- if (rec->oper.ioctl == NULL)
- rc = -ENXIO;
- else
- rc = rec->oper.ioctl(&dp->synths[dev].arg, cmd, addr);
- snd_use_lock_free(&rec->use_lock);
- return rc;
-}
-
-
-/*
- * send OSS raw events - SEQ_PRIVATE and SEQ_VOLUME
- */
-int
-snd_seq_oss_synth_raw_event(struct seq_oss_devinfo *dp, int dev, unsigned char *data, struct snd_seq_event *ev)
-{
- if (! snd_seq_oss_synth_is_valid(dp, dev) || is_midi_dev(dp, dev))
- return -ENXIO;
- ev->type = SNDRV_SEQ_EVENT_OSS;
- memcpy(ev->data.raw8.d, data, 8);
- return snd_seq_oss_synth_addr(dp, dev, ev);
-}
-
-
-/*
- * create OSS compatible synth_info record
- */
-int
-snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_info *inf)
-{
- struct seq_oss_synth *rec;
-
- if (dev < 0 || dev >= dp->max_synthdev)
- return -ENXIO;
-
- if (dp->synths[dev].is_midi) {
- struct midi_info minf;
- snd_seq_oss_midi_make_info(dp, dp->synths[dev].midi_mapped, &minf);
- inf->synth_type = SYNTH_TYPE_MIDI;
- inf->synth_subtype = 0;
- inf->nr_voices = 16;
- inf->device = dev;
- strlcpy(inf->name, minf.name, sizeof(inf->name));
- } else {
- if ((rec = get_synthdev(dp, dev)) == NULL)
- return -ENXIO;
- inf->synth_type = rec->synth_type;
- inf->synth_subtype = rec->synth_subtype;
- inf->nr_voices = rec->nr_voices;
- inf->device = dev;
- strlcpy(inf->name, rec->name, sizeof(inf->name));
- snd_use_lock_free(&rec->use_lock);
- }
- return 0;
-}
-
-
-#ifdef CONFIG_PROC_FS
-/*
- * proc interface
- */
-void
-snd_seq_oss_synth_info_read(struct snd_info_buffer *buf)
-{
- int i;
- struct seq_oss_synth *rec;
-
- snd_iprintf(buf, "\nNumber of synth devices: %d\n", max_synth_devs);
- for (i = 0; i < max_synth_devs; i++) {
- snd_iprintf(buf, "\nsynth %d: ", i);
- rec = get_sdev(i);
- if (rec == NULL) {
- snd_iprintf(buf, "*empty*\n");
- continue;
- }
- snd_iprintf(buf, "[%s]\n", rec->name);
- snd_iprintf(buf, " type 0x%x : subtype 0x%x : voices %d\n",
- rec->synth_type, rec->synth_subtype,
- rec->nr_voices);
- snd_iprintf(buf, " capabilities : ioctl %s / load_patch %s\n",
- enabled_str((long)rec->oper.ioctl),
- enabled_str((long)rec->oper.load_patch));
- snd_use_lock_free(&rec->use_lock);
- }
-}
-#endif /* CONFIG_PROC_FS */
diff --git a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_synth.h b/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_synth.h
deleted file mode 100644
index dbdfcbb8..00000000
--- a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_synth.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * OSS compatible sequencer driver
- *
- * synth device information
- *
- * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __SEQ_OSS_SYNTH_H
-#define __SEQ_OSS_SYNTH_H
-
-#include "seq_oss_device.h"
-#include <sound/seq_oss_legacy.h>
-#include <sound/seq_device.h>
-
-void snd_seq_oss_synth_init(void);
-int snd_seq_oss_synth_register(struct snd_seq_device *dev);
-int snd_seq_oss_synth_unregister(struct snd_seq_device *dev);
-void snd_seq_oss_synth_setup(struct seq_oss_devinfo *dp);
-void snd_seq_oss_synth_setup_midi(struct seq_oss_devinfo *dp);
-void snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp);
-
-void snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev);
-int snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
- const char __user *buf, int p, int c);
-int snd_seq_oss_synth_is_valid(struct seq_oss_devinfo *dp, int dev);
-int snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf,
- struct snd_seq_event *ev);
-int snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev);
-int snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd,
- unsigned long addr);
-int snd_seq_oss_synth_raw_event(struct seq_oss_devinfo *dp, int dev,
- unsigned char *data, struct snd_seq_event *ev);
-
-int snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_info *inf);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_timer.c b/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_timer.c
deleted file mode 100644
index ab59cbfb..00000000
--- a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_timer.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * OSS compatible sequencer driver
- *
- * Timer control routines
- *
- * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "seq_oss_timer.h"
-#include "seq_oss_event.h"
-#include <sound/seq_oss_legacy.h>
-#include <linux/slab.h>
-
-/*
- */
-#define MIN_OSS_TEMPO 8
-#define MAX_OSS_TEMPO 360
-#define MIN_OSS_TIMEBASE 1
-#define MAX_OSS_TIMEBASE 1000
-
-/*
- */
-static void calc_alsa_tempo(struct seq_oss_timer *timer);
-static int send_timer_event(struct seq_oss_devinfo *dp, int type, int value);
-
-
-/*
- * create and register a new timer.
- * if queue is not started yet, start it.
- */
-struct seq_oss_timer *
-snd_seq_oss_timer_new(struct seq_oss_devinfo *dp)
-{
- struct seq_oss_timer *rec;
-
- rec = kzalloc(sizeof(*rec), GFP_KERNEL);
- if (rec == NULL)
- return NULL;
-
- rec->dp = dp;
- rec->cur_tick = 0;
- rec->realtime = 0;
- rec->running = 0;
- rec->oss_tempo = 60;
- rec->oss_timebase = 100;
- calc_alsa_tempo(rec);
-
- return rec;
-}
-
-
-/*
- * delete timer.
- * if no more timer exists, stop the queue.
- */
-void
-snd_seq_oss_timer_delete(struct seq_oss_timer *rec)
-{
- if (rec) {
- snd_seq_oss_timer_stop(rec);
- kfree(rec);
- }
-}
-
-
-/*
- * process one timing event
- * return 1 : event proceseed -- skip this event
- * 0 : not a timer event -- enqueue this event
- */
-int
-snd_seq_oss_process_timer_event(struct seq_oss_timer *rec, union evrec *ev)
-{
- abstime_t parm = ev->t.time;
-
- if (ev->t.code == EV_TIMING) {
- switch (ev->t.cmd) {
- case TMR_WAIT_REL:
- parm += rec->cur_tick;
- rec->realtime = 0;
- /* continue to next */
- case TMR_WAIT_ABS:
- if (parm == 0) {
- rec->realtime = 1;
- } else if (parm >= rec->cur_tick) {
- rec->realtime = 0;
- rec->cur_tick = parm;
- }
- return 1; /* skip this event */
-
- case TMR_START:
- snd_seq_oss_timer_start(rec);
- return 1;
-
- }
- } else if (ev->s.code == SEQ_WAIT) {
- /* time = from 1 to 3 bytes */
- parm = (ev->echo >> 8) & 0xffffff;
- if (parm > rec->cur_tick) {
- /* set next event time */
- rec->cur_tick = parm;
- rec->realtime = 0;
- }
- return 1;
- }
-
- return 0;
-}
-
-
-/*
- * convert tempo units
- */
-static void
-calc_alsa_tempo(struct seq_oss_timer *timer)
-{
- timer->tempo = (60 * 1000000) / timer->oss_tempo;
- timer->ppq = timer->oss_timebase;
-}
-
-
-/*
- * dispatch a timer event
- */
-static int
-send_timer_event(struct seq_oss_devinfo *dp, int type, int value)
-{
- struct snd_seq_event ev;
-
- memset(&ev, 0, sizeof(ev));
- ev.type = type;
- ev.source.client = dp->cseq;
- ev.source.port = 0;
- ev.dest.client = SNDRV_SEQ_CLIENT_SYSTEM;
- ev.dest.port = SNDRV_SEQ_PORT_SYSTEM_TIMER;
- ev.queue = dp->queue;
- ev.data.queue.queue = dp->queue;
- ev.data.queue.param.value = value;
- return snd_seq_kernel_client_dispatch(dp->cseq, &ev, 1, 0);
-}
-
-/*
- * set queue tempo and start queue
- */
-int
-snd_seq_oss_timer_start(struct seq_oss_timer *timer)
-{
- struct seq_oss_devinfo *dp = timer->dp;
- struct snd_seq_queue_tempo tmprec;
-
- if (timer->running)
- snd_seq_oss_timer_stop(timer);
-
- memset(&tmprec, 0, sizeof(tmprec));
- tmprec.queue = dp->queue;
- tmprec.ppq = timer->ppq;
- tmprec.tempo = timer->tempo;
- snd_seq_set_queue_tempo(dp->cseq, &tmprec);
-
- send_timer_event(dp, SNDRV_SEQ_EVENT_START, 0);
- timer->running = 1;
- timer->cur_tick = 0;
- return 0;
-}
-
-
-/*
- * stop queue
- */
-int
-snd_seq_oss_timer_stop(struct seq_oss_timer *timer)
-{
- if (! timer->running)
- return 0;
- send_timer_event(timer->dp, SNDRV_SEQ_EVENT_STOP, 0);
- timer->running = 0;
- return 0;
-}
-
-
-/*
- * continue queue
- */
-int
-snd_seq_oss_timer_continue(struct seq_oss_timer *timer)
-{
- if (timer->running)
- return 0;
- send_timer_event(timer->dp, SNDRV_SEQ_EVENT_CONTINUE, 0);
- timer->running = 1;
- return 0;
-}
-
-
-/*
- * change queue tempo
- */
-int
-snd_seq_oss_timer_tempo(struct seq_oss_timer *timer, int value)
-{
- if (value < MIN_OSS_TEMPO)
- value = MIN_OSS_TEMPO;
- else if (value > MAX_OSS_TEMPO)
- value = MAX_OSS_TEMPO;
- timer->oss_tempo = value;
- calc_alsa_tempo(timer);
- if (timer->running)
- send_timer_event(timer->dp, SNDRV_SEQ_EVENT_TEMPO, timer->tempo);
- return 0;
-}
-
-
-/*
- * ioctls
- */
-int
-snd_seq_oss_timer_ioctl(struct seq_oss_timer *timer, unsigned int cmd, int __user *arg)
-{
- int value;
-
- if (cmd == SNDCTL_SEQ_CTRLRATE) {
- debug_printk(("ctrl rate\n"));
- /* if *arg == 0, just return the current rate */
- if (get_user(value, arg))
- return -EFAULT;
- if (value)
- return -EINVAL;
- value = ((timer->oss_tempo * timer->oss_timebase) + 30) / 60;
- return put_user(value, arg) ? -EFAULT : 0;
- }
-
- if (timer->dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH)
- return 0;
-
- switch (cmd) {
- case SNDCTL_TMR_START:
- debug_printk(("timer start\n"));
- return snd_seq_oss_timer_start(timer);
- case SNDCTL_TMR_STOP:
- debug_printk(("timer stop\n"));
- return snd_seq_oss_timer_stop(timer);
- case SNDCTL_TMR_CONTINUE:
- debug_printk(("timer continue\n"));
- return snd_seq_oss_timer_continue(timer);
- case SNDCTL_TMR_TEMPO:
- debug_printk(("timer tempo\n"));
- if (get_user(value, arg))
- return -EFAULT;
- return snd_seq_oss_timer_tempo(timer, value);
- case SNDCTL_TMR_TIMEBASE:
- debug_printk(("timer timebase\n"));
- if (get_user(value, arg))
- return -EFAULT;
- if (value < MIN_OSS_TIMEBASE)
- value = MIN_OSS_TIMEBASE;
- else if (value > MAX_OSS_TIMEBASE)
- value = MAX_OSS_TIMEBASE;
- timer->oss_timebase = value;
- calc_alsa_tempo(timer);
- return 0;
-
- case SNDCTL_TMR_METRONOME:
- case SNDCTL_TMR_SELECT:
- case SNDCTL_TMR_SOURCE:
- debug_printk(("timer XXX\n"));
- /* not supported */
- return 0;
- }
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_timer.h b/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_timer.h
deleted file mode 100644
index b995bd68..00000000
--- a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_timer.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * OSS compatible sequencer driver
- * timer handling routines
- *
- * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __SEQ_OSS_TIMER_H
-#define __SEQ_OSS_TIMER_H
-
-#include "seq_oss_device.h"
-
-/*
- * timer information definition
- */
-struct seq_oss_timer {
- struct seq_oss_devinfo *dp;
- reltime_t cur_tick;
- int realtime;
- int running;
- int tempo, ppq; /* ALSA queue */
- int oss_tempo, oss_timebase;
-};
-
-
-struct seq_oss_timer *snd_seq_oss_timer_new(struct seq_oss_devinfo *dp);
-void snd_seq_oss_timer_delete(struct seq_oss_timer *dp);
-
-int snd_seq_oss_timer_start(struct seq_oss_timer *timer);
-int snd_seq_oss_timer_stop(struct seq_oss_timer *timer);
-int snd_seq_oss_timer_continue(struct seq_oss_timer *timer);
-int snd_seq_oss_timer_tempo(struct seq_oss_timer *timer, int value);
-#define snd_seq_oss_timer_reset snd_seq_oss_timer_start
-
-int snd_seq_oss_timer_ioctl(struct seq_oss_timer *timer, unsigned int cmd, int __user *arg);
-
-/*
- * get current processed time
- */
-static inline abstime_t
-snd_seq_oss_timer_cur_tick(struct seq_oss_timer *timer)
-{
- return timer->cur_tick;
-}
-
-
-/*
- * is realtime event?
- */
-static inline int
-snd_seq_oss_timer_is_realtime(struct seq_oss_timer *timer)
-{
- return timer->realtime;
-}
-
-#endif
diff --git a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_writeq.c b/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_writeq.c
deleted file mode 100644
index d50338bb..00000000
--- a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_writeq.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * OSS compatible sequencer driver
- *
- * seq_oss_writeq.c - write queue and sync
- *
- * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "seq_oss_writeq.h"
-#include "seq_oss_event.h"
-#include "seq_oss_timer.h"
-#include <sound/seq_oss_legacy.h>
-#include "../seq_lock.h"
-#include "../seq_clientmgr.h"
-#include <linux/wait.h>
-#include <linux/slab.h>
-
-
-/*
- * create a write queue record
- */
-struct seq_oss_writeq *
-snd_seq_oss_writeq_new(struct seq_oss_devinfo *dp, int maxlen)
-{
- struct seq_oss_writeq *q;
- struct snd_seq_client_pool pool;
-
- if ((q = kzalloc(sizeof(*q), GFP_KERNEL)) == NULL)
- return NULL;
- q->dp = dp;
- q->maxlen = maxlen;
- spin_lock_init(&q->sync_lock);
- q->sync_event_put = 0;
- q->sync_time = 0;
- init_waitqueue_head(&q->sync_sleep);
-
- memset(&pool, 0, sizeof(pool));
- pool.client = dp->cseq;
- pool.output_pool = maxlen;
- pool.output_room = maxlen / 2;
-
- snd_seq_oss_control(dp, SNDRV_SEQ_IOCTL_SET_CLIENT_POOL, &pool);
-
- return q;
-}
-
-/*
- * delete the write queue
- */
-void
-snd_seq_oss_writeq_delete(struct seq_oss_writeq *q)
-{
- if (q) {
- snd_seq_oss_writeq_clear(q); /* to be sure */
- kfree(q);
- }
-}
-
-
-/*
- * reset the write queue
- */
-void
-snd_seq_oss_writeq_clear(struct seq_oss_writeq *q)
-{
- struct snd_seq_remove_events reset;
-
- memset(&reset, 0, sizeof(reset));
- reset.remove_mode = SNDRV_SEQ_REMOVE_OUTPUT; /* remove all */
- snd_seq_oss_control(q->dp, SNDRV_SEQ_IOCTL_REMOVE_EVENTS, &reset);
-
- /* wake up sleepers if any */
- snd_seq_oss_writeq_wakeup(q, 0);
-}
-
-/*
- * wait until the write buffer has enough room
- */
-int
-snd_seq_oss_writeq_sync(struct seq_oss_writeq *q)
-{
- struct seq_oss_devinfo *dp = q->dp;
- abstime_t time;
-
- time = snd_seq_oss_timer_cur_tick(dp->timer);
- if (q->sync_time >= time)
- return 0; /* already finished */
-
- if (! q->sync_event_put) {
- struct snd_seq_event ev;
- union evrec *rec;
-
- /* put echoback event */
- memset(&ev, 0, sizeof(ev));
- ev.flags = 0;
- ev.type = SNDRV_SEQ_EVENT_ECHO;
- ev.time.tick = time;
- /* echo back to itself */
- snd_seq_oss_fill_addr(dp, &ev, dp->addr.client, dp->addr.port);
- rec = (union evrec *)&ev.data;
- rec->t.code = SEQ_SYNCTIMER;
- rec->t.time = time;
- q->sync_event_put = 1;
- snd_seq_kernel_client_enqueue_blocking(dp->cseq, &ev, NULL, 0, 0);
- }
-
- wait_event_interruptible_timeout(q->sync_sleep, ! q->sync_event_put, HZ);
- if (signal_pending(current))
- /* interrupted - return 0 to finish sync */
- q->sync_event_put = 0;
- if (! q->sync_event_put || q->sync_time >= time)
- return 0;
- return 1;
-}
-
-/*
- * wake up sync - echo event was catched
- */
-void
-snd_seq_oss_writeq_wakeup(struct seq_oss_writeq *q, abstime_t time)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&q->sync_lock, flags);
- q->sync_time = time;
- q->sync_event_put = 0;
- if (waitqueue_active(&q->sync_sleep)) {
- wake_up(&q->sync_sleep);
- }
- spin_unlock_irqrestore(&q->sync_lock, flags);
-}
-
-
-/*
- * return the unused pool size
- */
-int
-snd_seq_oss_writeq_get_free_size(struct seq_oss_writeq *q)
-{
- struct snd_seq_client_pool pool;
- pool.client = q->dp->cseq;
- snd_seq_oss_control(q->dp, SNDRV_SEQ_IOCTL_GET_CLIENT_POOL, &pool);
- return pool.output_free;
-}
-
-
-/*
- * set output threshold size from ioctl
- */
-void
-snd_seq_oss_writeq_set_output(struct seq_oss_writeq *q, int val)
-{
- struct snd_seq_client_pool pool;
- pool.client = q->dp->cseq;
- snd_seq_oss_control(q->dp, SNDRV_SEQ_IOCTL_GET_CLIENT_POOL, &pool);
- pool.output_room = val;
- snd_seq_oss_control(q->dp, SNDRV_SEQ_IOCTL_SET_CLIENT_POOL, &pool);
-}
-
diff --git a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_writeq.h b/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_writeq.h
deleted file mode 100644
index c469d296..00000000
--- a/ANDROID_3.4.5/sound/core/seq/oss/seq_oss_writeq.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * OSS compatible sequencer driver
- * write priority queue
- *
- * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __SEQ_OSS_WRITEQ_H
-#define __SEQ_OSS_WRITEQ_H
-
-#include "seq_oss_device.h"
-
-
-struct seq_oss_writeq {
- struct seq_oss_devinfo *dp;
- int maxlen;
- abstime_t sync_time;
- int sync_event_put;
- wait_queue_head_t sync_sleep;
- spinlock_t sync_lock;
-};
-
-
-/*
- * seq_oss_writeq.c
- */
-struct seq_oss_writeq *snd_seq_oss_writeq_new(struct seq_oss_devinfo *dp, int maxlen);
-void snd_seq_oss_writeq_delete(struct seq_oss_writeq *q);
-void snd_seq_oss_writeq_clear(struct seq_oss_writeq *q);
-int snd_seq_oss_writeq_sync(struct seq_oss_writeq *q);
-void snd_seq_oss_writeq_wakeup(struct seq_oss_writeq *q, abstime_t time);
-int snd_seq_oss_writeq_get_free_size(struct seq_oss_writeq *q);
-void snd_seq_oss_writeq_set_output(struct seq_oss_writeq *q, int size);
-
-
-#endif
diff --git a/ANDROID_3.4.5/sound/core/seq/seq.c b/ANDROID_3.4.5/sound/core/seq/seq.c
deleted file mode 100644
index 71211056..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * ALSA sequencer main module
- * Copyright (c) 1998-1999 by Frank van de Pol <fvdpol@coil.demon.nl>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-
-#include <sound/seq_kernel.h>
-#include "seq_clientmgr.h"
-#include "seq_memory.h"
-#include "seq_queue.h"
-#include "seq_lock.h"
-#include "seq_timer.h"
-#include "seq_system.h"
-#include "seq_info.h"
-#include <sound/minors.h>
-#include <sound/seq_device.h>
-
-#if defined(CONFIG_SND_SEQ_DUMMY_MODULE)
-int seq_client_load[15] = {[0] = SNDRV_SEQ_CLIENT_DUMMY, [1 ... 14] = -1};
-#else
-int seq_client_load[15] = {[0 ... 14] = -1};
-#endif
-int seq_default_timer_class = SNDRV_TIMER_CLASS_GLOBAL;
-int seq_default_timer_sclass = SNDRV_TIMER_SCLASS_NONE;
-int seq_default_timer_card = -1;
-int seq_default_timer_device =
-#ifdef CONFIG_SND_SEQ_HRTIMER_DEFAULT
- SNDRV_TIMER_GLOBAL_HRTIMER
-#elif defined(CONFIG_SND_SEQ_RTCTIMER_DEFAULT)
- SNDRV_TIMER_GLOBAL_RTC
-#else
- SNDRV_TIMER_GLOBAL_SYSTEM
-#endif
- ;
-int seq_default_timer_subdevice = 0;
-int seq_default_timer_resolution = 0; /* Hz */
-
-MODULE_AUTHOR("Frank van de Pol <fvdpol@coil.demon.nl>, Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Advanced Linux Sound Architecture sequencer.");
-MODULE_LICENSE("GPL");
-
-module_param_array(seq_client_load, int, NULL, 0444);
-MODULE_PARM_DESC(seq_client_load, "The numbers of global (system) clients to load through kmod.");
-module_param(seq_default_timer_class, int, 0644);
-MODULE_PARM_DESC(seq_default_timer_class, "The default timer class.");
-module_param(seq_default_timer_sclass, int, 0644);
-MODULE_PARM_DESC(seq_default_timer_sclass, "The default timer slave class.");
-module_param(seq_default_timer_card, int, 0644);
-MODULE_PARM_DESC(seq_default_timer_card, "The default timer card number.");
-module_param(seq_default_timer_device, int, 0644);
-MODULE_PARM_DESC(seq_default_timer_device, "The default timer device number.");
-module_param(seq_default_timer_subdevice, int, 0644);
-MODULE_PARM_DESC(seq_default_timer_subdevice, "The default timer subdevice number.");
-module_param(seq_default_timer_resolution, int, 0644);
-MODULE_PARM_DESC(seq_default_timer_resolution, "The default timer resolution in Hz.");
-
-MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_SEQUENCER);
-MODULE_ALIAS("devname:snd/seq");
-
-/*
- * INIT PART
- */
-
-static int __init alsa_seq_init(void)
-{
- int err;
-
- snd_seq_autoload_lock();
- if ((err = client_init_data()) < 0)
- goto error;
-
- /* init memory, room for selected events */
- if ((err = snd_sequencer_memory_init()) < 0)
- goto error;
-
- /* init event queues */
- if ((err = snd_seq_queues_init()) < 0)
- goto error;
-
- /* register sequencer device */
- if ((err = snd_sequencer_device_init()) < 0)
- goto error;
-
- /* register proc interface */
- if ((err = snd_seq_info_init()) < 0)
- goto error;
-
- /* register our internal client */
- if ((err = snd_seq_system_client_init()) < 0)
- goto error;
-
- error:
- snd_seq_autoload_unlock();
- return err;
-}
-
-static void __exit alsa_seq_exit(void)
-{
- /* unregister our internal client */
- snd_seq_system_client_done();
-
- /* unregister proc interface */
- snd_seq_info_done();
-
- /* delete timing queues */
- snd_seq_queues_delete();
-
- /* unregister sequencer device */
- snd_sequencer_device_done();
-
- /* release event memory */
- snd_sequencer_memory_done();
-}
-
-module_init(alsa_seq_init)
-module_exit(alsa_seq_exit)
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_clientmgr.c b/ANDROID_3.4.5/sound/core/seq/seq_clientmgr.c
deleted file mode 100644
index 4dc6bae8..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_clientmgr.c
+++ /dev/null
@@ -1,2591 +0,0 @@
-/*
- * ALSA sequencer Client Manager
- * Copyright (c) 1998-2001 by Frank van de Pol <fvdpol@coil.demon.nl>
- * Jaroslav Kysela <perex@perex.cz>
- * Takashi Iwai <tiwai@suse.de>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/export.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/minors.h>
-#include <linux/kmod.h>
-
-#include <sound/seq_kernel.h>
-#include "seq_clientmgr.h"
-#include "seq_memory.h"
-#include "seq_queue.h"
-#include "seq_timer.h"
-#include "seq_info.h"
-#include "seq_system.h"
-#include <sound/seq_device.h>
-#ifdef CONFIG_COMPAT
-#include <linux/compat.h>
-#endif
-
-/* Client Manager
-
- * this module handles the connections of userland and kernel clients
- *
- */
-
-/*
- * There are four ranges of client numbers (last two shared):
- * 0..15: global clients
- * 16..127: statically allocated client numbers for cards 0..27
- * 128..191: dynamically allocated client numbers for cards 28..31
- * 128..191: dynamically allocated client numbers for applications
- */
-
-/* number of kernel non-card clients */
-#define SNDRV_SEQ_GLOBAL_CLIENTS 16
-/* clients per cards, for static clients */
-#define SNDRV_SEQ_CLIENTS_PER_CARD 4
-/* dynamically allocated client numbers (both kernel drivers and user space) */
-#define SNDRV_SEQ_DYNAMIC_CLIENTS_BEGIN 128
-
-#define SNDRV_SEQ_LFLG_INPUT 0x0001
-#define SNDRV_SEQ_LFLG_OUTPUT 0x0002
-#define SNDRV_SEQ_LFLG_OPEN (SNDRV_SEQ_LFLG_INPUT|SNDRV_SEQ_LFLG_OUTPUT)
-
-static DEFINE_SPINLOCK(clients_lock);
-static DEFINE_MUTEX(register_mutex);
-
-/*
- * client table
- */
-static char clienttablock[SNDRV_SEQ_MAX_CLIENTS];
-static struct snd_seq_client *clienttab[SNDRV_SEQ_MAX_CLIENTS];
-static struct snd_seq_usage client_usage;
-
-/*
- * prototypes
- */
-static int bounce_error_event(struct snd_seq_client *client,
- struct snd_seq_event *event,
- int err, int atomic, int hop);
-static int snd_seq_deliver_single_event(struct snd_seq_client *client,
- struct snd_seq_event *event,
- int filter, int atomic, int hop);
-
-/*
- */
-
-static inline mm_segment_t snd_enter_user(void)
-{
- mm_segment_t fs = get_fs();
- set_fs(get_ds());
- return fs;
-}
-
-static inline void snd_leave_user(mm_segment_t fs)
-{
- set_fs(fs);
-}
-
-/*
- */
-static inline unsigned short snd_seq_file_flags(struct file *file)
-{
- switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) {
- case FMODE_WRITE:
- return SNDRV_SEQ_LFLG_OUTPUT;
- case FMODE_READ:
- return SNDRV_SEQ_LFLG_INPUT;
- default:
- return SNDRV_SEQ_LFLG_OPEN;
- }
-}
-
-static inline int snd_seq_write_pool_allocated(struct snd_seq_client *client)
-{
- return snd_seq_total_cells(client->pool) > 0;
-}
-
-/* return pointer to client structure for specified id */
-static struct snd_seq_client *clientptr(int clientid)
-{
- if (clientid < 0 || clientid >= SNDRV_SEQ_MAX_CLIENTS) {
- snd_printd("Seq: oops. Trying to get pointer to client %d\n",
- clientid);
- return NULL;
- }
- return clienttab[clientid];
-}
-
-struct snd_seq_client *snd_seq_client_use_ptr(int clientid)
-{
- unsigned long flags;
- struct snd_seq_client *client;
-
- if (clientid < 0 || clientid >= SNDRV_SEQ_MAX_CLIENTS) {
- snd_printd("Seq: oops. Trying to get pointer to client %d\n",
- clientid);
- return NULL;
- }
- spin_lock_irqsave(&clients_lock, flags);
- client = clientptr(clientid);
- if (client)
- goto __lock;
- if (clienttablock[clientid]) {
- spin_unlock_irqrestore(&clients_lock, flags);
- return NULL;
- }
- spin_unlock_irqrestore(&clients_lock, flags);
-#ifdef CONFIG_MODULES
- if (!in_interrupt()) {
- static char client_requested[SNDRV_SEQ_GLOBAL_CLIENTS];
- static char card_requested[SNDRV_CARDS];
- if (clientid < SNDRV_SEQ_GLOBAL_CLIENTS) {
- int idx;
-
- if (!client_requested[clientid]) {
- client_requested[clientid] = 1;
- for (idx = 0; idx < 15; idx++) {
- if (seq_client_load[idx] < 0)
- break;
- if (seq_client_load[idx] == clientid) {
- request_module("snd-seq-client-%i",
- clientid);
- break;
- }
- }
- }
- } else if (clientid < SNDRV_SEQ_DYNAMIC_CLIENTS_BEGIN) {
- int card = (clientid - SNDRV_SEQ_GLOBAL_CLIENTS) /
- SNDRV_SEQ_CLIENTS_PER_CARD;
- if (card < snd_ecards_limit) {
- if (! card_requested[card]) {
- card_requested[card] = 1;
- snd_request_card(card);
- }
- snd_seq_device_load_drivers();
- }
- }
- spin_lock_irqsave(&clients_lock, flags);
- client = clientptr(clientid);
- if (client)
- goto __lock;
- spin_unlock_irqrestore(&clients_lock, flags);
- }
-#endif
- return NULL;
-
- __lock:
- snd_use_lock_use(&client->use_lock);
- spin_unlock_irqrestore(&clients_lock, flags);
- return client;
-}
-
-static void usage_alloc(struct snd_seq_usage *res, int num)
-{
- res->cur += num;
- if (res->cur > res->peak)
- res->peak = res->cur;
-}
-
-static void usage_free(struct snd_seq_usage *res, int num)
-{
- res->cur -= num;
-}
-
-/* initialise data structures */
-int __init client_init_data(void)
-{
- /* zap out the client table */
- memset(&clienttablock, 0, sizeof(clienttablock));
- memset(&clienttab, 0, sizeof(clienttab));
- return 0;
-}
-
-
-static struct snd_seq_client *seq_create_client1(int client_index, int poolsize)
-{
- unsigned long flags;
- int c;
- struct snd_seq_client *client;
-
- /* init client data */
- client = kzalloc(sizeof(*client), GFP_KERNEL);
- if (client == NULL)
- return NULL;
- client->pool = snd_seq_pool_new(poolsize);
- if (client->pool == NULL) {
- kfree(client);
- return NULL;
- }
- client->type = NO_CLIENT;
- snd_use_lock_init(&client->use_lock);
- rwlock_init(&client->ports_lock);
- mutex_init(&client->ports_mutex);
- INIT_LIST_HEAD(&client->ports_list_head);
-
- /* find free slot in the client table */
- spin_lock_irqsave(&clients_lock, flags);
- if (client_index < 0) {
- for (c = SNDRV_SEQ_DYNAMIC_CLIENTS_BEGIN;
- c < SNDRV_SEQ_MAX_CLIENTS;
- c++) {
- if (clienttab[c] || clienttablock[c])
- continue;
- clienttab[client->number = c] = client;
- spin_unlock_irqrestore(&clients_lock, flags);
- return client;
- }
- } else {
- if (clienttab[client_index] == NULL && !clienttablock[client_index]) {
- clienttab[client->number = client_index] = client;
- spin_unlock_irqrestore(&clients_lock, flags);
- return client;
- }
- }
- spin_unlock_irqrestore(&clients_lock, flags);
- snd_seq_pool_delete(&client->pool);
- kfree(client);
- return NULL; /* no free slot found or busy, return failure code */
-}
-
-
-static int seq_free_client1(struct snd_seq_client *client)
-{
- unsigned long flags;
-
- if (!client)
- return 0;
- snd_seq_delete_all_ports(client);
- snd_seq_queue_client_leave(client->number);
- spin_lock_irqsave(&clients_lock, flags);
- clienttablock[client->number] = 1;
- clienttab[client->number] = NULL;
- spin_unlock_irqrestore(&clients_lock, flags);
- snd_use_lock_sync(&client->use_lock);
- snd_seq_queue_client_termination(client->number);
- if (client->pool)
- snd_seq_pool_delete(&client->pool);
- spin_lock_irqsave(&clients_lock, flags);
- clienttablock[client->number] = 0;
- spin_unlock_irqrestore(&clients_lock, flags);
- return 0;
-}
-
-
-static void seq_free_client(struct snd_seq_client * client)
-{
- mutex_lock(&register_mutex);
- switch (client->type) {
- case NO_CLIENT:
- snd_printk(KERN_WARNING "Seq: Trying to free unused client %d\n",
- client->number);
- break;
- case USER_CLIENT:
- case KERNEL_CLIENT:
- seq_free_client1(client);
- usage_free(&client_usage, 1);
- break;
-
- default:
- snd_printk(KERN_ERR "Seq: Trying to free client %d with undefined type = %d\n",
- client->number, client->type);
- }
- mutex_unlock(&register_mutex);
-
- snd_seq_system_client_ev_client_exit(client->number);
-}
-
-
-
-/* -------------------------------------------------------- */
-
-/* create a user client */
-static int snd_seq_open(struct inode *inode, struct file *file)
-{
- int c, mode; /* client id */
- struct snd_seq_client *client;
- struct snd_seq_user_client *user;
- int err;
-
- err = nonseekable_open(inode, file);
- if (err < 0)
- return err;
-
- if (mutex_lock_interruptible(&register_mutex))
- return -ERESTARTSYS;
- client = seq_create_client1(-1, SNDRV_SEQ_DEFAULT_EVENTS);
- if (client == NULL) {
- mutex_unlock(&register_mutex);
- return -ENOMEM; /* failure code */
- }
-
- mode = snd_seq_file_flags(file);
- if (mode & SNDRV_SEQ_LFLG_INPUT)
- client->accept_input = 1;
- if (mode & SNDRV_SEQ_LFLG_OUTPUT)
- client->accept_output = 1;
-
- user = &client->data.user;
- user->fifo = NULL;
- user->fifo_pool_size = 0;
-
- if (mode & SNDRV_SEQ_LFLG_INPUT) {
- user->fifo_pool_size = SNDRV_SEQ_DEFAULT_CLIENT_EVENTS;
- user->fifo = snd_seq_fifo_new(user->fifo_pool_size);
- if (user->fifo == NULL) {
- seq_free_client1(client);
- kfree(client);
- mutex_unlock(&register_mutex);
- return -ENOMEM;
- }
- }
-
- usage_alloc(&client_usage, 1);
- client->type = USER_CLIENT;
- mutex_unlock(&register_mutex);
-
- c = client->number;
- file->private_data = client;
-
- /* fill client data */
- user->file = file;
- sprintf(client->name, "Client-%d", c);
-
- /* make others aware this new client */
- snd_seq_system_client_ev_client_start(c);
-
- return 0;
-}
-
-/* delete a user client */
-static int snd_seq_release(struct inode *inode, struct file *file)
-{
- struct snd_seq_client *client = file->private_data;
-
- if (client) {
- seq_free_client(client);
- if (client->data.user.fifo)
- snd_seq_fifo_delete(&client->data.user.fifo);
- kfree(client);
- }
-
- return 0;
-}
-
-
-/* handle client read() */
-/* possible error values:
- * -ENXIO invalid client or file open mode
- * -ENOSPC FIFO overflow (the flag is cleared after this error report)
- * -EINVAL no enough user-space buffer to write the whole event
- * -EFAULT seg. fault during copy to user space
- */
-static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count,
- loff_t *offset)
-{
- struct snd_seq_client *client = file->private_data;
- struct snd_seq_fifo *fifo;
- int err;
- long result = 0;
- struct snd_seq_event_cell *cell;
-
- if (!(snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_INPUT))
- return -ENXIO;
-
- if (!access_ok(VERIFY_WRITE, buf, count))
- return -EFAULT;
-
- /* check client structures are in place */
- if (snd_BUG_ON(!client))
- return -ENXIO;
-
- if (!client->accept_input || (fifo = client->data.user.fifo) == NULL)
- return -ENXIO;
-
- if (atomic_read(&fifo->overflow) > 0) {
- /* buffer overflow is detected */
- snd_seq_fifo_clear(fifo);
- /* return error code */
- return -ENOSPC;
- }
-
- cell = NULL;
- err = 0;
- snd_seq_fifo_lock(fifo);
-
- /* while data available in queue */
- while (count >= sizeof(struct snd_seq_event)) {
- int nonblock;
-
- nonblock = (file->f_flags & O_NONBLOCK) || result > 0;
- if ((err = snd_seq_fifo_cell_out(fifo, &cell, nonblock)) < 0) {
- break;
- }
- if (snd_seq_ev_is_variable(&cell->event)) {
- struct snd_seq_event tmpev;
- tmpev = cell->event;
- tmpev.data.ext.len &= ~SNDRV_SEQ_EXT_MASK;
- if (copy_to_user(buf, &tmpev, sizeof(struct snd_seq_event))) {
- err = -EFAULT;
- break;
- }
- count -= sizeof(struct snd_seq_event);
- buf += sizeof(struct snd_seq_event);
- err = snd_seq_expand_var_event(&cell->event, count,
- (char __force *)buf, 0,
- sizeof(struct snd_seq_event));
- if (err < 0)
- break;
- result += err;
- count -= err;
- buf += err;
- } else {
- if (copy_to_user(buf, &cell->event, sizeof(struct snd_seq_event))) {
- err = -EFAULT;
- break;
- }
- count -= sizeof(struct snd_seq_event);
- buf += sizeof(struct snd_seq_event);
- }
- snd_seq_cell_free(cell);
- cell = NULL; /* to be sure */
- result += sizeof(struct snd_seq_event);
- }
-
- if (err < 0) {
- if (cell)
- snd_seq_fifo_cell_putback(fifo, cell);
- if (err == -EAGAIN && result > 0)
- err = 0;
- }
- snd_seq_fifo_unlock(fifo);
-
- return (err < 0) ? err : result;
-}
-
-
-/*
- * check access permission to the port
- */
-static int check_port_perm(struct snd_seq_client_port *port, unsigned int flags)
-{
- if ((port->capability & flags) != flags)
- return 0;
- return flags;
-}
-
-/*
- * check if the destination client is available, and return the pointer
- * if filter is non-zero, client filter bitmap is tested.
- */
-static struct snd_seq_client *get_event_dest_client(struct snd_seq_event *event,
- int filter)
-{
- struct snd_seq_client *dest;
-
- dest = snd_seq_client_use_ptr(event->dest.client);
- if (dest == NULL)
- return NULL;
- if (! dest->accept_input)
- goto __not_avail;
- if ((dest->filter & SNDRV_SEQ_FILTER_USE_EVENT) &&
- ! test_bit(event->type, dest->event_filter))
- goto __not_avail;
- if (filter && !(dest->filter & filter))
- goto __not_avail;
-
- return dest; /* ok - accessible */
-__not_avail:
- snd_seq_client_unlock(dest);
- return NULL;
-}
-
-
-/*
- * Return the error event.
- *
- * If the receiver client is a user client, the original event is
- * encapsulated in SNDRV_SEQ_EVENT_BOUNCE as variable length event. If
- * the original event is also variable length, the external data is
- * copied after the event record.
- * If the receiver client is a kernel client, the original event is
- * quoted in SNDRV_SEQ_EVENT_KERNEL_ERROR, since this requires no extra
- * kmalloc.
- */
-static int bounce_error_event(struct snd_seq_client *client,
- struct snd_seq_event *event,
- int err, int atomic, int hop)
-{
- struct snd_seq_event bounce_ev;
- int result;
-
- if (client == NULL ||
- ! (client->filter & SNDRV_SEQ_FILTER_BOUNCE) ||
- ! client->accept_input)
- return 0; /* ignored */
-
- /* set up quoted error */
- memset(&bounce_ev, 0, sizeof(bounce_ev));
- bounce_ev.type = SNDRV_SEQ_EVENT_KERNEL_ERROR;
- bounce_ev.flags = SNDRV_SEQ_EVENT_LENGTH_FIXED;
- bounce_ev.queue = SNDRV_SEQ_QUEUE_DIRECT;
- bounce_ev.source.client = SNDRV_SEQ_CLIENT_SYSTEM;
- bounce_ev.source.port = SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE;
- bounce_ev.dest.client = client->number;
- bounce_ev.dest.port = event->source.port;
- bounce_ev.data.quote.origin = event->dest;
- bounce_ev.data.quote.event = event;
- bounce_ev.data.quote.value = -err; /* use positive value */
- result = snd_seq_deliver_single_event(NULL, &bounce_ev, 0, atomic, hop + 1);
- if (result < 0) {
- client->event_lost++;
- return result;
- }
-
- return result;
-}
-
-
-/*
- * rewrite the time-stamp of the event record with the curren time
- * of the given queue.
- * return non-zero if updated.
- */
-static int update_timestamp_of_queue(struct snd_seq_event *event,
- int queue, int real_time)
-{
- struct snd_seq_queue *q;
-
- q = queueptr(queue);
- if (! q)
- return 0;
- event->queue = queue;
- event->flags &= ~SNDRV_SEQ_TIME_STAMP_MASK;
- if (real_time) {
- event->time.time = snd_seq_timer_get_cur_time(q->timer);
- event->flags |= SNDRV_SEQ_TIME_STAMP_REAL;
- } else {
- event->time.tick = snd_seq_timer_get_cur_tick(q->timer);
- event->flags |= SNDRV_SEQ_TIME_STAMP_TICK;
- }
- queuefree(q);
- return 1;
-}
-
-
-/*
- * deliver an event to the specified destination.
- * if filter is non-zero, client filter bitmap is tested.
- *
- * RETURN VALUE: 0 : if succeeded
- * <0 : error
- */
-static int snd_seq_deliver_single_event(struct snd_seq_client *client,
- struct snd_seq_event *event,
- int filter, int atomic, int hop)
-{
- struct snd_seq_client *dest = NULL;
- struct snd_seq_client_port *dest_port = NULL;
- int result = -ENOENT;
- int direct;
-
- direct = snd_seq_ev_is_direct(event);
-
- dest = get_event_dest_client(event, filter);
- if (dest == NULL)
- goto __skip;
- dest_port = snd_seq_port_use_ptr(dest, event->dest.port);
- if (dest_port == NULL)
- goto __skip;
-
- /* check permission */
- if (! check_port_perm(dest_port, SNDRV_SEQ_PORT_CAP_WRITE)) {
- result = -EPERM;
- goto __skip;
- }
-
- if (dest_port->timestamping)
- update_timestamp_of_queue(event, dest_port->time_queue,
- dest_port->time_real);
-
- switch (dest->type) {
- case USER_CLIENT:
- if (dest->data.user.fifo)
- result = snd_seq_fifo_event_in(dest->data.user.fifo, event);
- break;
-
- case KERNEL_CLIENT:
- if (dest_port->event_input == NULL)
- break;
- result = dest_port->event_input(event, direct,
- dest_port->private_data,
- atomic, hop);
- break;
- default:
- break;
- }
-
- __skip:
- if (dest_port)
- snd_seq_port_unlock(dest_port);
- if (dest)
- snd_seq_client_unlock(dest);
-
- if (result < 0 && !direct) {
- result = bounce_error_event(client, event, result, atomic, hop);
- }
- return result;
-}
-
-
-/*
- * send the event to all subscribers:
- */
-static int deliver_to_subscribers(struct snd_seq_client *client,
- struct snd_seq_event *event,
- int atomic, int hop)
-{
- struct snd_seq_subscribers *subs;
- int err = 0, num_ev = 0;
- struct snd_seq_event event_saved;
- struct snd_seq_client_port *src_port;
- struct snd_seq_port_subs_info *grp;
-
- src_port = snd_seq_port_use_ptr(client, event->source.port);
- if (src_port == NULL)
- return -EINVAL; /* invalid source port */
- /* save original event record */
- event_saved = *event;
- grp = &src_port->c_src;
-
- /* lock list */
- if (atomic)
- read_lock(&grp->list_lock);
- else
- down_read(&grp->list_mutex);
- list_for_each_entry(subs, &grp->list_head, src_list) {
- event->dest = subs->info.dest;
- if (subs->info.flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP)
- /* convert time according to flag with subscription */
- update_timestamp_of_queue(event, subs->info.queue,
- subs->info.flags & SNDRV_SEQ_PORT_SUBS_TIME_REAL);
- err = snd_seq_deliver_single_event(client, event,
- 0, atomic, hop);
- if (err < 0)
- break;
- num_ev++;
- /* restore original event record */
- *event = event_saved;
- }
- if (atomic)
- read_unlock(&grp->list_lock);
- else
- up_read(&grp->list_mutex);
- *event = event_saved; /* restore */
- snd_seq_port_unlock(src_port);
- return (err < 0) ? err : num_ev;
-}
-
-
-#ifdef SUPPORT_BROADCAST
-/*
- * broadcast to all ports:
- */
-static int port_broadcast_event(struct snd_seq_client *client,
- struct snd_seq_event *event,
- int atomic, int hop)
-{
- int num_ev = 0, err = 0;
- struct snd_seq_client *dest_client;
- struct snd_seq_client_port *port;
-
- dest_client = get_event_dest_client(event, SNDRV_SEQ_FILTER_BROADCAST);
- if (dest_client == NULL)
- return 0; /* no matching destination */
-
- read_lock(&dest_client->ports_lock);
- list_for_each_entry(port, &dest_client->ports_list_head, list) {
- event->dest.port = port->addr.port;
- /* pass NULL as source client to avoid error bounce */
- err = snd_seq_deliver_single_event(NULL, event,
- SNDRV_SEQ_FILTER_BROADCAST,
- atomic, hop);
- if (err < 0)
- break;
- num_ev++;
- }
- read_unlock(&dest_client->ports_lock);
- snd_seq_client_unlock(dest_client);
- event->dest.port = SNDRV_SEQ_ADDRESS_BROADCAST; /* restore */
- return (err < 0) ? err : num_ev;
-}
-
-/*
- * send the event to all clients:
- * if destination port is also ADDRESS_BROADCAST, deliver to all ports.
- */
-static int broadcast_event(struct snd_seq_client *client,
- struct snd_seq_event *event, int atomic, int hop)
-{
- int err = 0, num_ev = 0;
- int dest;
- struct snd_seq_addr addr;
-
- addr = event->dest; /* save */
-
- for (dest = 0; dest < SNDRV_SEQ_MAX_CLIENTS; dest++) {
- /* don't send to itself */
- if (dest == client->number)
- continue;
- event->dest.client = dest;
- event->dest.port = addr.port;
- if (addr.port == SNDRV_SEQ_ADDRESS_BROADCAST)
- err = port_broadcast_event(client, event, atomic, hop);
- else
- /* pass NULL as source client to avoid error bounce */
- err = snd_seq_deliver_single_event(NULL, event,
- SNDRV_SEQ_FILTER_BROADCAST,
- atomic, hop);
- if (err < 0)
- break;
- num_ev += err;
- }
- event->dest = addr; /* restore */
- return (err < 0) ? err : num_ev;
-}
-
-
-/* multicast - not supported yet */
-static int multicast_event(struct snd_seq_client *client, struct snd_seq_event *event,
- int atomic, int hop)
-{
- snd_printd("seq: multicast not supported yet.\n");
- return 0; /* ignored */
-}
-#endif /* SUPPORT_BROADCAST */
-
-
-/* deliver an event to the destination port(s).
- * if the event is to subscribers or broadcast, the event is dispatched
- * to multiple targets.
- *
- * RETURN VALUE: n > 0 : the number of delivered events.
- * n == 0 : the event was not passed to any client.
- * n < 0 : error - event was not processed.
- */
-static int snd_seq_deliver_event(struct snd_seq_client *client, struct snd_seq_event *event,
- int atomic, int hop)
-{
- int result;
-
- hop++;
- if (hop >= SNDRV_SEQ_MAX_HOPS) {
- snd_printd("too long delivery path (%d:%d->%d:%d)\n",
- event->source.client, event->source.port,
- event->dest.client, event->dest.port);
- return -EMLINK;
- }
-
- if (event->queue == SNDRV_SEQ_ADDRESS_SUBSCRIBERS ||
- event->dest.client == SNDRV_SEQ_ADDRESS_SUBSCRIBERS)
- result = deliver_to_subscribers(client, event, atomic, hop);
-#ifdef SUPPORT_BROADCAST
- else if (event->queue == SNDRV_SEQ_ADDRESS_BROADCAST ||
- event->dest.client == SNDRV_SEQ_ADDRESS_BROADCAST)
- result = broadcast_event(client, event, atomic, hop);
- else if (event->dest.client >= SNDRV_SEQ_MAX_CLIENTS)
- result = multicast_event(client, event, atomic, hop);
- else if (event->dest.port == SNDRV_SEQ_ADDRESS_BROADCAST)
- result = port_broadcast_event(client, event, atomic, hop);
-#endif
- else
- result = snd_seq_deliver_single_event(client, event, 0, atomic, hop);
-
- return result;
-}
-
-/*
- * dispatch an event cell:
- * This function is called only from queue check routines in timer
- * interrupts or after enqueued.
- * The event cell shall be released or re-queued in this function.
- *
- * RETURN VALUE: n > 0 : the number of delivered events.
- * n == 0 : the event was not passed to any client.
- * n < 0 : error - event was not processed.
- */
-int snd_seq_dispatch_event(struct snd_seq_event_cell *cell, int atomic, int hop)
-{
- struct snd_seq_client *client;
- int result;
-
- if (snd_BUG_ON(!cell))
- return -EINVAL;
-
- client = snd_seq_client_use_ptr(cell->event.source.client);
- if (client == NULL) {
- snd_seq_cell_free(cell); /* release this cell */
- return -EINVAL;
- }
-
- if (cell->event.type == SNDRV_SEQ_EVENT_NOTE) {
- /* NOTE event:
- * the event cell is re-used as a NOTE-OFF event and
- * enqueued again.
- */
- struct snd_seq_event tmpev, *ev;
-
- /* reserve this event to enqueue note-off later */
- tmpev = cell->event;
- tmpev.type = SNDRV_SEQ_EVENT_NOTEON;
- result = snd_seq_deliver_event(client, &tmpev, atomic, hop);
-
- /*
- * This was originally a note event. We now re-use the
- * cell for the note-off event.
- */
-
- ev = &cell->event;
- ev->type = SNDRV_SEQ_EVENT_NOTEOFF;
- ev->flags |= SNDRV_SEQ_PRIORITY_HIGH;
-
- /* add the duration time */
- switch (ev->flags & SNDRV_SEQ_TIME_STAMP_MASK) {
- case SNDRV_SEQ_TIME_STAMP_TICK:
- ev->time.tick += ev->data.note.duration;
- break;
- case SNDRV_SEQ_TIME_STAMP_REAL:
- /* unit for duration is ms */
- ev->time.time.tv_nsec += 1000000 * (ev->data.note.duration % 1000);
- ev->time.time.tv_sec += ev->data.note.duration / 1000 +
- ev->time.time.tv_nsec / 1000000000;
- ev->time.time.tv_nsec %= 1000000000;
- break;
- }
- ev->data.note.velocity = ev->data.note.off_velocity;
-
- /* Now queue this cell as the note off event */
- if (snd_seq_enqueue_event(cell, atomic, hop) < 0)
- snd_seq_cell_free(cell); /* release this cell */
-
- } else {
- /* Normal events:
- * event cell is freed after processing the event
- */
-
- result = snd_seq_deliver_event(client, &cell->event, atomic, hop);
- snd_seq_cell_free(cell);
- }
-
- snd_seq_client_unlock(client);
- return result;
-}
-
-
-/* Allocate a cell from client pool and enqueue it to queue:
- * if pool is empty and blocking is TRUE, sleep until a new cell is
- * available.
- */
-static int snd_seq_client_enqueue_event(struct snd_seq_client *client,
- struct snd_seq_event *event,
- struct file *file, int blocking,
- int atomic, int hop)
-{
- struct snd_seq_event_cell *cell;
- int err;
-
- /* special queue values - force direct passing */
- if (event->queue == SNDRV_SEQ_ADDRESS_SUBSCRIBERS) {
- event->dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS;
- event->queue = SNDRV_SEQ_QUEUE_DIRECT;
- } else
-#ifdef SUPPORT_BROADCAST
- if (event->queue == SNDRV_SEQ_ADDRESS_BROADCAST) {
- event->dest.client = SNDRV_SEQ_ADDRESS_BROADCAST;
- event->queue = SNDRV_SEQ_QUEUE_DIRECT;
- }
-#endif
- if (event->dest.client == SNDRV_SEQ_ADDRESS_SUBSCRIBERS) {
- /* check presence of source port */
- struct snd_seq_client_port *src_port = snd_seq_port_use_ptr(client, event->source.port);
- if (src_port == NULL)
- return -EINVAL;
- snd_seq_port_unlock(src_port);
- }
-
- /* direct event processing without enqueued */
- if (snd_seq_ev_is_direct(event)) {
- if (event->type == SNDRV_SEQ_EVENT_NOTE)
- return -EINVAL; /* this event must be enqueued! */
- return snd_seq_deliver_event(client, event, atomic, hop);
- }
-
- /* Not direct, normal queuing */
- if (snd_seq_queue_is_used(event->queue, client->number) <= 0)
- return -EINVAL; /* invalid queue */
- if (! snd_seq_write_pool_allocated(client))
- return -ENXIO; /* queue is not allocated */
-
- /* allocate an event cell */
- err = snd_seq_event_dup(client->pool, event, &cell, !blocking || atomic, file);
- if (err < 0)
- return err;
-
- /* we got a cell. enqueue it. */
- if ((err = snd_seq_enqueue_event(cell, atomic, hop)) < 0) {
- snd_seq_cell_free(cell);
- return err;
- }
-
- return 0;
-}
-
-
-/*
- * check validity of event type and data length.
- * return non-zero if invalid.
- */
-static int check_event_type_and_length(struct snd_seq_event *ev)
-{
- switch (snd_seq_ev_length_type(ev)) {
- case SNDRV_SEQ_EVENT_LENGTH_FIXED:
- if (snd_seq_ev_is_variable_type(ev))
- return -EINVAL;
- break;
- case SNDRV_SEQ_EVENT_LENGTH_VARIABLE:
- if (! snd_seq_ev_is_variable_type(ev) ||
- (ev->data.ext.len & ~SNDRV_SEQ_EXT_MASK) >= SNDRV_SEQ_MAX_EVENT_LEN)
- return -EINVAL;
- break;
- case SNDRV_SEQ_EVENT_LENGTH_VARUSR:
- if (! snd_seq_ev_is_direct(ev))
- return -EINVAL;
- break;
- }
- return 0;
-}
-
-
-/* handle write() */
-/* possible error values:
- * -ENXIO invalid client or file open mode
- * -ENOMEM malloc failed
- * -EFAULT seg. fault during copy from user space
- * -EINVAL invalid event
- * -EAGAIN no space in output pool
- * -EINTR interrupts while sleep
- * -EMLINK too many hops
- * others depends on return value from driver callback
- */
-static ssize_t snd_seq_write(struct file *file, const char __user *buf,
- size_t count, loff_t *offset)
-{
- struct snd_seq_client *client = file->private_data;
- int written = 0, len;
- int err = -EINVAL;
- struct snd_seq_event event;
-
- if (!(snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_OUTPUT))
- return -ENXIO;
-
- /* check client structures are in place */
- if (snd_BUG_ON(!client))
- return -ENXIO;
-
- if (!client->accept_output || client->pool == NULL)
- return -ENXIO;
-
- /* allocate the pool now if the pool is not allocated yet */
- if (client->pool->size > 0 && !snd_seq_write_pool_allocated(client)) {
- if (snd_seq_pool_init(client->pool) < 0)
- return -ENOMEM;
- }
-
- /* only process whole events */
- while (count >= sizeof(struct snd_seq_event)) {
- /* Read in the event header from the user */
- len = sizeof(event);
- if (copy_from_user(&event, buf, len)) {
- err = -EFAULT;
- break;
- }
- event.source.client = client->number; /* fill in client number */
- /* Check for extension data length */
- if (check_event_type_and_length(&event)) {
- err = -EINVAL;
- break;
- }
-
- /* check for special events */
- if (event.type == SNDRV_SEQ_EVENT_NONE)
- goto __skip_event;
- else if (snd_seq_ev_is_reserved(&event)) {
- err = -EINVAL;
- break;
- }
-
- if (snd_seq_ev_is_variable(&event)) {
- int extlen = event.data.ext.len & ~SNDRV_SEQ_EXT_MASK;
- if ((size_t)(extlen + len) > count) {
- /* back out, will get an error this time or next */
- err = -EINVAL;
- break;
- }
- /* set user space pointer */
- event.data.ext.len = extlen | SNDRV_SEQ_EXT_USRPTR;
- event.data.ext.ptr = (char __force *)buf
- + sizeof(struct snd_seq_event);
- len += extlen; /* increment data length */
- } else {
-#ifdef CONFIG_COMPAT
- if (client->convert32 && snd_seq_ev_is_varusr(&event)) {
- void *ptr = (void __force *)compat_ptr(event.data.raw32.d[1]);
- event.data.ext.ptr = ptr;
- }
-#endif
- }
-
- /* ok, enqueue it */
- err = snd_seq_client_enqueue_event(client, &event, file,
- !(file->f_flags & O_NONBLOCK),
- 0, 0);
- if (err < 0)
- break;
-
- __skip_event:
- /* Update pointers and counts */
- count -= len;
- buf += len;
- written += len;
- }
-
- return written ? written : err;
-}
-
-
-/*
- * handle polling
- */
-static unsigned int snd_seq_poll(struct file *file, poll_table * wait)
-{
- struct snd_seq_client *client = file->private_data;
- unsigned int mask = 0;
-
- /* check client structures are in place */
- if (snd_BUG_ON(!client))
- return -ENXIO;
-
- if ((snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_INPUT) &&
- client->data.user.fifo) {
-
- /* check if data is available in the outqueue */
- if (snd_seq_fifo_poll_wait(client->data.user.fifo, file, wait))
- mask |= POLLIN | POLLRDNORM;
- }
-
- if (snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_OUTPUT) {
-
- /* check if data is available in the pool */
- if (!snd_seq_write_pool_allocated(client) ||
- snd_seq_pool_poll_wait(client->pool, file, wait))
- mask |= POLLOUT | POLLWRNORM;
- }
-
- return mask;
-}
-
-
-/*-----------------------------------------------------*/
-
-
-/* SYSTEM_INFO ioctl() */
-static int snd_seq_ioctl_system_info(struct snd_seq_client *client, void __user *arg)
-{
- struct snd_seq_system_info info;
-
- memset(&info, 0, sizeof(info));
- /* fill the info fields */
- info.queues = SNDRV_SEQ_MAX_QUEUES;
- info.clients = SNDRV_SEQ_MAX_CLIENTS;
- info.ports = 256; /* fixed limit */
- info.channels = 256; /* fixed limit */
- info.cur_clients = client_usage.cur;
- info.cur_queues = snd_seq_queue_get_cur_queues();
-
- if (copy_to_user(arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
-}
-
-
-/* RUNNING_MODE ioctl() */
-static int snd_seq_ioctl_running_mode(struct snd_seq_client *client, void __user *arg)
-{
- struct snd_seq_running_info info;
- struct snd_seq_client *cptr;
- int err = 0;
-
- if (copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
-
- /* requested client number */
- cptr = snd_seq_client_use_ptr(info.client);
- if (cptr == NULL)
- return -ENOENT; /* don't change !!! */
-
-#ifdef SNDRV_BIG_ENDIAN
- if (! info.big_endian) {
- err = -EINVAL;
- goto __err;
- }
-#else
- if (info.big_endian) {
- err = -EINVAL;
- goto __err;
- }
-
-#endif
- if (info.cpu_mode > sizeof(long)) {
- err = -EINVAL;
- goto __err;
- }
- cptr->convert32 = (info.cpu_mode < sizeof(long));
- __err:
- snd_seq_client_unlock(cptr);
- return err;
-}
-
-/* CLIENT_INFO ioctl() */
-static void get_client_info(struct snd_seq_client *cptr,
- struct snd_seq_client_info *info)
-{
- info->client = cptr->number;
-
- /* fill the info fields */
- info->type = cptr->type;
- strcpy(info->name, cptr->name);
- info->filter = cptr->filter;
- info->event_lost = cptr->event_lost;
- memcpy(info->event_filter, cptr->event_filter, 32);
- info->num_ports = cptr->num_ports;
- memset(info->reserved, 0, sizeof(info->reserved));
-}
-
-static int snd_seq_ioctl_get_client_info(struct snd_seq_client *client,
- void __user *arg)
-{
- struct snd_seq_client *cptr;
- struct snd_seq_client_info client_info;
-
- if (copy_from_user(&client_info, arg, sizeof(client_info)))
- return -EFAULT;
-
- /* requested client number */
- cptr = snd_seq_client_use_ptr(client_info.client);
- if (cptr == NULL)
- return -ENOENT; /* don't change !!! */
-
- get_client_info(cptr, &client_info);
- snd_seq_client_unlock(cptr);
-
- if (copy_to_user(arg, &client_info, sizeof(client_info)))
- return -EFAULT;
- return 0;
-}
-
-
-/* CLIENT_INFO ioctl() */
-static int snd_seq_ioctl_set_client_info(struct snd_seq_client *client,
- void __user *arg)
-{
- struct snd_seq_client_info client_info;
-
- if (copy_from_user(&client_info, arg, sizeof(client_info)))
- return -EFAULT;
-
- /* it is not allowed to set the info fields for an another client */
- if (client->number != client_info.client)
- return -EPERM;
- /* also client type must be set now */
- if (client->type != client_info.type)
- return -EINVAL;
-
- /* fill the info fields */
- if (client_info.name[0])
- strlcpy(client->name, client_info.name, sizeof(client->name));
-
- client->filter = client_info.filter;
- client->event_lost = client_info.event_lost;
- memcpy(client->event_filter, client_info.event_filter, 32);
-
- return 0;
-}
-
-
-/*
- * CREATE PORT ioctl()
- */
-static int snd_seq_ioctl_create_port(struct snd_seq_client *client,
- void __user *arg)
-{
- struct snd_seq_client_port *port;
- struct snd_seq_port_info info;
- struct snd_seq_port_callback *callback;
-
- if (copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
-
- /* it is not allowed to create the port for an another client */
- if (info.addr.client != client->number)
- return -EPERM;
-
- port = snd_seq_create_port(client, (info.flags & SNDRV_SEQ_PORT_FLG_GIVEN_PORT) ? info.addr.port : -1);
- if (port == NULL)
- return -ENOMEM;
-
- if (client->type == USER_CLIENT && info.kernel) {
- snd_seq_delete_port(client, port->addr.port);
- return -EINVAL;
- }
- if (client->type == KERNEL_CLIENT) {
- if ((callback = info.kernel) != NULL) {
- if (callback->owner)
- port->owner = callback->owner;
- port->private_data = callback->private_data;
- port->private_free = callback->private_free;
- port->callback_all = callback->callback_all;
- port->event_input = callback->event_input;
- port->c_src.open = callback->subscribe;
- port->c_src.close = callback->unsubscribe;
- port->c_dest.open = callback->use;
- port->c_dest.close = callback->unuse;
- }
- }
-
- info.addr = port->addr;
-
- snd_seq_set_port_info(port, &info);
- snd_seq_system_client_ev_port_start(port->addr.client, port->addr.port);
-
- if (copy_to_user(arg, &info, sizeof(info)))
- return -EFAULT;
-
- return 0;
-}
-
-/*
- * DELETE PORT ioctl()
- */
-static int snd_seq_ioctl_delete_port(struct snd_seq_client *client,
- void __user *arg)
-{
- struct snd_seq_port_info info;
- int err;
-
- /* set passed parameters */
- if (copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
-
- /* it is not allowed to remove the port for an another client */
- if (info.addr.client != client->number)
- return -EPERM;
-
- err = snd_seq_delete_port(client, info.addr.port);
- if (err >= 0)
- snd_seq_system_client_ev_port_exit(client->number, info.addr.port);
- return err;
-}
-
-
-/*
- * GET_PORT_INFO ioctl() (on any client)
- */
-static int snd_seq_ioctl_get_port_info(struct snd_seq_client *client,
- void __user *arg)
-{
- struct snd_seq_client *cptr;
- struct snd_seq_client_port *port;
- struct snd_seq_port_info info;
-
- if (copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
- cptr = snd_seq_client_use_ptr(info.addr.client);
- if (cptr == NULL)
- return -ENXIO;
-
- port = snd_seq_port_use_ptr(cptr, info.addr.port);
- if (port == NULL) {
- snd_seq_client_unlock(cptr);
- return -ENOENT; /* don't change */
- }
-
- /* get port info */
- snd_seq_get_port_info(port, &info);
- snd_seq_port_unlock(port);
- snd_seq_client_unlock(cptr);
-
- if (copy_to_user(arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
-}
-
-
-/*
- * SET_PORT_INFO ioctl() (only ports on this/own client)
- */
-static int snd_seq_ioctl_set_port_info(struct snd_seq_client *client,
- void __user *arg)
-{
- struct snd_seq_client_port *port;
- struct snd_seq_port_info info;
-
- if (copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
-
- if (info.addr.client != client->number) /* only set our own ports ! */
- return -EPERM;
- port = snd_seq_port_use_ptr(client, info.addr.port);
- if (port) {
- snd_seq_set_port_info(port, &info);
- snd_seq_port_unlock(port);
- }
- return 0;
-}
-
-
-/*
- * port subscription (connection)
- */
-#define PERM_RD (SNDRV_SEQ_PORT_CAP_READ|SNDRV_SEQ_PORT_CAP_SUBS_READ)
-#define PERM_WR (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_SUBS_WRITE)
-
-static int check_subscription_permission(struct snd_seq_client *client,
- struct snd_seq_client_port *sport,
- struct snd_seq_client_port *dport,
- struct snd_seq_port_subscribe *subs)
-{
- if (client->number != subs->sender.client &&
- client->number != subs->dest.client) {
- /* connection by third client - check export permission */
- if (check_port_perm(sport, SNDRV_SEQ_PORT_CAP_NO_EXPORT))
- return -EPERM;
- if (check_port_perm(dport, SNDRV_SEQ_PORT_CAP_NO_EXPORT))
- return -EPERM;
- }
-
- /* check read permission */
- /* if sender or receiver is the subscribing client itself,
- * no permission check is necessary
- */
- if (client->number != subs->sender.client) {
- if (! check_port_perm(sport, PERM_RD))
- return -EPERM;
- }
- /* check write permission */
- if (client->number != subs->dest.client) {
- if (! check_port_perm(dport, PERM_WR))
- return -EPERM;
- }
- return 0;
-}
-
-/*
- * send an subscription notify event to user client:
- * client must be user client.
- */
-int snd_seq_client_notify_subscription(int client, int port,
- struct snd_seq_port_subscribe *info,
- int evtype)
-{
- struct snd_seq_event event;
-
- memset(&event, 0, sizeof(event));
- event.type = evtype;
- event.data.connect.dest = info->dest;
- event.data.connect.sender = info->sender;
-
- return snd_seq_system_notify(client, port, &event); /* non-atomic */
-}
-
-
-/*
- * add to port's subscription list IOCTL interface
- */
-static int snd_seq_ioctl_subscribe_port(struct snd_seq_client *client,
- void __user *arg)
-{
- int result = -EINVAL;
- struct snd_seq_client *receiver = NULL, *sender = NULL;
- struct snd_seq_client_port *sport = NULL, *dport = NULL;
- struct snd_seq_port_subscribe subs;
-
- if (copy_from_user(&subs, arg, sizeof(subs)))
- return -EFAULT;
-
- if ((receiver = snd_seq_client_use_ptr(subs.dest.client)) == NULL)
- goto __end;
- if ((sender = snd_seq_client_use_ptr(subs.sender.client)) == NULL)
- goto __end;
- if ((sport = snd_seq_port_use_ptr(sender, subs.sender.port)) == NULL)
- goto __end;
- if ((dport = snd_seq_port_use_ptr(receiver, subs.dest.port)) == NULL)
- goto __end;
-
- result = check_subscription_permission(client, sport, dport, &subs);
- if (result < 0)
- goto __end;
-
- /* connect them */
- result = snd_seq_port_connect(client, sender, sport, receiver, dport, &subs);
- if (! result) /* broadcast announce */
- snd_seq_client_notify_subscription(SNDRV_SEQ_ADDRESS_SUBSCRIBERS, 0,
- &subs, SNDRV_SEQ_EVENT_PORT_SUBSCRIBED);
- __end:
- if (sport)
- snd_seq_port_unlock(sport);
- if (dport)
- snd_seq_port_unlock(dport);
- if (sender)
- snd_seq_client_unlock(sender);
- if (receiver)
- snd_seq_client_unlock(receiver);
- return result;
-}
-
-
-/*
- * remove from port's subscription list
- */
-static int snd_seq_ioctl_unsubscribe_port(struct snd_seq_client *client,
- void __user *arg)
-{
- int result = -ENXIO;
- struct snd_seq_client *receiver = NULL, *sender = NULL;
- struct snd_seq_client_port *sport = NULL, *dport = NULL;
- struct snd_seq_port_subscribe subs;
-
- if (copy_from_user(&subs, arg, sizeof(subs)))
- return -EFAULT;
-
- if ((receiver = snd_seq_client_use_ptr(subs.dest.client)) == NULL)
- goto __end;
- if ((sender = snd_seq_client_use_ptr(subs.sender.client)) == NULL)
- goto __end;
- if ((sport = snd_seq_port_use_ptr(sender, subs.sender.port)) == NULL)
- goto __end;
- if ((dport = snd_seq_port_use_ptr(receiver, subs.dest.port)) == NULL)
- goto __end;
-
- result = check_subscription_permission(client, sport, dport, &subs);
- if (result < 0)
- goto __end;
-
- result = snd_seq_port_disconnect(client, sender, sport, receiver, dport, &subs);
- if (! result) /* broadcast announce */
- snd_seq_client_notify_subscription(SNDRV_SEQ_ADDRESS_SUBSCRIBERS, 0,
- &subs, SNDRV_SEQ_EVENT_PORT_UNSUBSCRIBED);
- __end:
- if (sport)
- snd_seq_port_unlock(sport);
- if (dport)
- snd_seq_port_unlock(dport);
- if (sender)
- snd_seq_client_unlock(sender);
- if (receiver)
- snd_seq_client_unlock(receiver);
- return result;
-}
-
-
-/* CREATE_QUEUE ioctl() */
-static int snd_seq_ioctl_create_queue(struct snd_seq_client *client,
- void __user *arg)
-{
- struct snd_seq_queue_info info;
- int result;
- struct snd_seq_queue *q;
-
- if (copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
-
- result = snd_seq_queue_alloc(client->number, info.locked, info.flags);
- if (result < 0)
- return result;
-
- q = queueptr(result);
- if (q == NULL)
- return -EINVAL;
-
- info.queue = q->queue;
- info.locked = q->locked;
- info.owner = q->owner;
-
- /* set queue name */
- if (! info.name[0])
- snprintf(info.name, sizeof(info.name), "Queue-%d", q->queue);
- strlcpy(q->name, info.name, sizeof(q->name));
- queuefree(q);
-
- if (copy_to_user(arg, &info, sizeof(info)))
- return -EFAULT;
-
- return 0;
-}
-
-/* DELETE_QUEUE ioctl() */
-static int snd_seq_ioctl_delete_queue(struct snd_seq_client *client,
- void __user *arg)
-{
- struct snd_seq_queue_info info;
-
- if (copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
-
- return snd_seq_queue_delete(client->number, info.queue);
-}
-
-/* GET_QUEUE_INFO ioctl() */
-static int snd_seq_ioctl_get_queue_info(struct snd_seq_client *client,
- void __user *arg)
-{
- struct snd_seq_queue_info info;
- struct snd_seq_queue *q;
-
- if (copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
-
- q = queueptr(info.queue);
- if (q == NULL)
- return -EINVAL;
-
- memset(&info, 0, sizeof(info));
- info.queue = q->queue;
- info.owner = q->owner;
- info.locked = q->locked;
- strlcpy(info.name, q->name, sizeof(info.name));
- queuefree(q);
-
- if (copy_to_user(arg, &info, sizeof(info)))
- return -EFAULT;
-
- return 0;
-}
-
-/* SET_QUEUE_INFO ioctl() */
-static int snd_seq_ioctl_set_queue_info(struct snd_seq_client *client,
- void __user *arg)
-{
- struct snd_seq_queue_info info;
- struct snd_seq_queue *q;
-
- if (copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
-
- if (info.owner != client->number)
- return -EINVAL;
-
- /* change owner/locked permission */
- if (snd_seq_queue_check_access(info.queue, client->number)) {
- if (snd_seq_queue_set_owner(info.queue, client->number, info.locked) < 0)
- return -EPERM;
- if (info.locked)
- snd_seq_queue_use(info.queue, client->number, 1);
- } else {
- return -EPERM;
- }
-
- q = queueptr(info.queue);
- if (! q)
- return -EINVAL;
- if (q->owner != client->number) {
- queuefree(q);
- return -EPERM;
- }
- strlcpy(q->name, info.name, sizeof(q->name));
- queuefree(q);
-
- return 0;
-}
-
-/* GET_NAMED_QUEUE ioctl() */
-static int snd_seq_ioctl_get_named_queue(struct snd_seq_client *client, void __user *arg)
-{
- struct snd_seq_queue_info info;
- struct snd_seq_queue *q;
-
- if (copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
-
- q = snd_seq_queue_find_name(info.name);
- if (q == NULL)
- return -EINVAL;
- info.queue = q->queue;
- info.owner = q->owner;
- info.locked = q->locked;
- queuefree(q);
-
- if (copy_to_user(arg, &info, sizeof(info)))
- return -EFAULT;
-
- return 0;
-}
-
-/* GET_QUEUE_STATUS ioctl() */
-static int snd_seq_ioctl_get_queue_status(struct snd_seq_client *client,
- void __user *arg)
-{
- struct snd_seq_queue_status status;
- struct snd_seq_queue *queue;
- struct snd_seq_timer *tmr;
-
- if (copy_from_user(&status, arg, sizeof(status)))
- return -EFAULT;
-
- queue = queueptr(status.queue);
- if (queue == NULL)
- return -EINVAL;
- memset(&status, 0, sizeof(status));
- status.queue = queue->queue;
-
- tmr = queue->timer;
- status.events = queue->tickq->cells + queue->timeq->cells;
-
- status.time = snd_seq_timer_get_cur_time(tmr);
- status.tick = snd_seq_timer_get_cur_tick(tmr);
-
- status.running = tmr->running;
-
- status.flags = queue->flags;
- queuefree(queue);
-
- if (copy_to_user(arg, &status, sizeof(status)))
- return -EFAULT;
- return 0;
-}
-
-
-/* GET_QUEUE_TEMPO ioctl() */
-static int snd_seq_ioctl_get_queue_tempo(struct snd_seq_client *client,
- void __user *arg)
-{
- struct snd_seq_queue_tempo tempo;
- struct snd_seq_queue *queue;
- struct snd_seq_timer *tmr;
-
- if (copy_from_user(&tempo, arg, sizeof(tempo)))
- return -EFAULT;
-
- queue = queueptr(tempo.queue);
- if (queue == NULL)
- return -EINVAL;
- memset(&tempo, 0, sizeof(tempo));
- tempo.queue = queue->queue;
-
- tmr = queue->timer;
-
- tempo.tempo = tmr->tempo;
- tempo.ppq = tmr->ppq;
- tempo.skew_value = tmr->skew;
- tempo.skew_base = tmr->skew_base;
- queuefree(queue);
-
- if (copy_to_user(arg, &tempo, sizeof(tempo)))
- return -EFAULT;
- return 0;
-}
-
-
-/* SET_QUEUE_TEMPO ioctl() */
-int snd_seq_set_queue_tempo(int client, struct snd_seq_queue_tempo *tempo)
-{
- if (!snd_seq_queue_check_access(tempo->queue, client))
- return -EPERM;
- return snd_seq_queue_timer_set_tempo(tempo->queue, client, tempo);
-}
-
-EXPORT_SYMBOL(snd_seq_set_queue_tempo);
-
-static int snd_seq_ioctl_set_queue_tempo(struct snd_seq_client *client,
- void __user *arg)
-{
- int result;
- struct snd_seq_queue_tempo tempo;
-
- if (copy_from_user(&tempo, arg, sizeof(tempo)))
- return -EFAULT;
-
- result = snd_seq_set_queue_tempo(client->number, &tempo);
- return result < 0 ? result : 0;
-}
-
-
-/* GET_QUEUE_TIMER ioctl() */
-static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client,
- void __user *arg)
-{
- struct snd_seq_queue_timer timer;
- struct snd_seq_queue *queue;
- struct snd_seq_timer *tmr;
-
- if (copy_from_user(&timer, arg, sizeof(timer)))
- return -EFAULT;
-
- queue = queueptr(timer.queue);
- if (queue == NULL)
- return -EINVAL;
-
- if (mutex_lock_interruptible(&queue->timer_mutex)) {
- queuefree(queue);
- return -ERESTARTSYS;
- }
- tmr = queue->timer;
- memset(&timer, 0, sizeof(timer));
- timer.queue = queue->queue;
-
- timer.type = tmr->type;
- if (tmr->type == SNDRV_SEQ_TIMER_ALSA) {
- timer.u.alsa.id = tmr->alsa_id;
- timer.u.alsa.resolution = tmr->preferred_resolution;
- }
- mutex_unlock(&queue->timer_mutex);
- queuefree(queue);
-
- if (copy_to_user(arg, &timer, sizeof(timer)))
- return -EFAULT;
- return 0;
-}
-
-
-/* SET_QUEUE_TIMER ioctl() */
-static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client,
- void __user *arg)
-{
- int result = 0;
- struct snd_seq_queue_timer timer;
-
- if (copy_from_user(&timer, arg, sizeof(timer)))
- return -EFAULT;
-
- if (timer.type != SNDRV_SEQ_TIMER_ALSA)
- return -EINVAL;
-
- if (snd_seq_queue_check_access(timer.queue, client->number)) {
- struct snd_seq_queue *q;
- struct snd_seq_timer *tmr;
-
- q = queueptr(timer.queue);
- if (q == NULL)
- return -ENXIO;
- if (mutex_lock_interruptible(&q->timer_mutex)) {
- queuefree(q);
- return -ERESTARTSYS;
- }
- tmr = q->timer;
- snd_seq_queue_timer_close(timer.queue);
- tmr->type = timer.type;
- if (tmr->type == SNDRV_SEQ_TIMER_ALSA) {
- tmr->alsa_id = timer.u.alsa.id;
- tmr->preferred_resolution = timer.u.alsa.resolution;
- }
- result = snd_seq_queue_timer_open(timer.queue);
- mutex_unlock(&q->timer_mutex);
- queuefree(q);
- } else {
- return -EPERM;
- }
-
- return result;
-}
-
-
-/* GET_QUEUE_CLIENT ioctl() */
-static int snd_seq_ioctl_get_queue_client(struct snd_seq_client *client,
- void __user *arg)
-{
- struct snd_seq_queue_client info;
- int used;
-
- if (copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
-
- used = snd_seq_queue_is_used(info.queue, client->number);
- if (used < 0)
- return -EINVAL;
- info.used = used;
- info.client = client->number;
-
- if (copy_to_user(arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
-}
-
-
-/* SET_QUEUE_CLIENT ioctl() */
-static int snd_seq_ioctl_set_queue_client(struct snd_seq_client *client,
- void __user *arg)
-{
- int err;
- struct snd_seq_queue_client info;
-
- if (copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
-
- if (info.used >= 0) {
- err = snd_seq_queue_use(info.queue, client->number, info.used);
- if (err < 0)
- return err;
- }
-
- return snd_seq_ioctl_get_queue_client(client, arg);
-}
-
-
-/* GET_CLIENT_POOL ioctl() */
-static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client,
- void __user *arg)
-{
- struct snd_seq_client_pool info;
- struct snd_seq_client *cptr;
-
- if (copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
-
- cptr = snd_seq_client_use_ptr(info.client);
- if (cptr == NULL)
- return -ENOENT;
- memset(&info, 0, sizeof(info));
- info.output_pool = cptr->pool->size;
- info.output_room = cptr->pool->room;
- info.output_free = info.output_pool;
- info.output_free = snd_seq_unused_cells(cptr->pool);
- if (cptr->type == USER_CLIENT) {
- info.input_pool = cptr->data.user.fifo_pool_size;
- info.input_free = info.input_pool;
- if (cptr->data.user.fifo)
- info.input_free = snd_seq_unused_cells(cptr->data.user.fifo->pool);
- } else {
- info.input_pool = 0;
- info.input_free = 0;
- }
- snd_seq_client_unlock(cptr);
-
- if (copy_to_user(arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
-}
-
-/* SET_CLIENT_POOL ioctl() */
-static int snd_seq_ioctl_set_client_pool(struct snd_seq_client *client,
- void __user *arg)
-{
- struct snd_seq_client_pool info;
- int rc;
-
- if (copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
-
- if (client->number != info.client)
- return -EINVAL; /* can't change other clients */
-
- if (info.output_pool >= 1 && info.output_pool <= SNDRV_SEQ_MAX_EVENTS &&
- (! snd_seq_write_pool_allocated(client) ||
- info.output_pool != client->pool->size)) {
- if (snd_seq_write_pool_allocated(client)) {
- /* remove all existing cells */
- snd_seq_queue_client_leave_cells(client->number);
- snd_seq_pool_done(client->pool);
- }
- client->pool->size = info.output_pool;
- rc = snd_seq_pool_init(client->pool);
- if (rc < 0)
- return rc;
- }
- if (client->type == USER_CLIENT && client->data.user.fifo != NULL &&
- info.input_pool >= 1 &&
- info.input_pool <= SNDRV_SEQ_MAX_CLIENT_EVENTS &&
- info.input_pool != client->data.user.fifo_pool_size) {
- /* change pool size */
- rc = snd_seq_fifo_resize(client->data.user.fifo, info.input_pool);
- if (rc < 0)
- return rc;
- client->data.user.fifo_pool_size = info.input_pool;
- }
- if (info.output_room >= 1 &&
- info.output_room <= client->pool->size) {
- client->pool->room = info.output_room;
- }
-
- return snd_seq_ioctl_get_client_pool(client, arg);
-}
-
-
-/* REMOVE_EVENTS ioctl() */
-static int snd_seq_ioctl_remove_events(struct snd_seq_client *client,
- void __user *arg)
-{
- struct snd_seq_remove_events info;
-
- if (copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
-
- /*
- * Input mostly not implemented XXX.
- */
- if (info.remove_mode & SNDRV_SEQ_REMOVE_INPUT) {
- /*
- * No restrictions so for a user client we can clear
- * the whole fifo
- */
- if (client->type == USER_CLIENT)
- snd_seq_fifo_clear(client->data.user.fifo);
- }
-
- if (info.remove_mode & SNDRV_SEQ_REMOVE_OUTPUT)
- snd_seq_queue_remove_cells(client->number, &info);
-
- return 0;
-}
-
-
-/*
- * get subscription info
- */
-static int snd_seq_ioctl_get_subscription(struct snd_seq_client *client,
- void __user *arg)
-{
- int result;
- struct snd_seq_client *sender = NULL;
- struct snd_seq_client_port *sport = NULL;
- struct snd_seq_port_subscribe subs;
- struct snd_seq_subscribers *p;
-
- if (copy_from_user(&subs, arg, sizeof(subs)))
- return -EFAULT;
-
- result = -EINVAL;
- if ((sender = snd_seq_client_use_ptr(subs.sender.client)) == NULL)
- goto __end;
- if ((sport = snd_seq_port_use_ptr(sender, subs.sender.port)) == NULL)
- goto __end;
- p = snd_seq_port_get_subscription(&sport->c_src, &subs.dest);
- if (p) {
- result = 0;
- subs = p->info;
- } else
- result = -ENOENT;
-
- __end:
- if (sport)
- snd_seq_port_unlock(sport);
- if (sender)
- snd_seq_client_unlock(sender);
- if (result >= 0) {
- if (copy_to_user(arg, &subs, sizeof(subs)))
- return -EFAULT;
- }
- return result;
-}
-
-
-/*
- * get subscription info - check only its presence
- */
-static int snd_seq_ioctl_query_subs(struct snd_seq_client *client,
- void __user *arg)
-{
- int result = -ENXIO;
- struct snd_seq_client *cptr = NULL;
- struct snd_seq_client_port *port = NULL;
- struct snd_seq_query_subs subs;
- struct snd_seq_port_subs_info *group;
- struct list_head *p;
- int i;
-
- if (copy_from_user(&subs, arg, sizeof(subs)))
- return -EFAULT;
-
- if ((cptr = snd_seq_client_use_ptr(subs.root.client)) == NULL)
- goto __end;
- if ((port = snd_seq_port_use_ptr(cptr, subs.root.port)) == NULL)
- goto __end;
-
- switch (subs.type) {
- case SNDRV_SEQ_QUERY_SUBS_READ:
- group = &port->c_src;
- break;
- case SNDRV_SEQ_QUERY_SUBS_WRITE:
- group = &port->c_dest;
- break;
- default:
- goto __end;
- }
-
- down_read(&group->list_mutex);
- /* search for the subscriber */
- subs.num_subs = group->count;
- i = 0;
- result = -ENOENT;
- list_for_each(p, &group->list_head) {
- if (i++ == subs.index) {
- /* found! */
- struct snd_seq_subscribers *s;
- if (subs.type == SNDRV_SEQ_QUERY_SUBS_READ) {
- s = list_entry(p, struct snd_seq_subscribers, src_list);
- subs.addr = s->info.dest;
- } else {
- s = list_entry(p, struct snd_seq_subscribers, dest_list);
- subs.addr = s->info.sender;
- }
- subs.flags = s->info.flags;
- subs.queue = s->info.queue;
- result = 0;
- break;
- }
- }
- up_read(&group->list_mutex);
-
- __end:
- if (port)
- snd_seq_port_unlock(port);
- if (cptr)
- snd_seq_client_unlock(cptr);
- if (result >= 0) {
- if (copy_to_user(arg, &subs, sizeof(subs)))
- return -EFAULT;
- }
- return result;
-}
-
-
-/*
- * query next client
- */
-static int snd_seq_ioctl_query_next_client(struct snd_seq_client *client,
- void __user *arg)
-{
- struct snd_seq_client *cptr = NULL;
- struct snd_seq_client_info info;
-
- if (copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
-
- /* search for next client */
- info.client++;
- if (info.client < 0)
- info.client = 0;
- for (; info.client < SNDRV_SEQ_MAX_CLIENTS; info.client++) {
- cptr = snd_seq_client_use_ptr(info.client);
- if (cptr)
- break; /* found */
- }
- if (cptr == NULL)
- return -ENOENT;
-
- get_client_info(cptr, &info);
- snd_seq_client_unlock(cptr);
-
- if (copy_to_user(arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
-}
-
-/*
- * query next port
- */
-static int snd_seq_ioctl_query_next_port(struct snd_seq_client *client,
- void __user *arg)
-{
- struct snd_seq_client *cptr;
- struct snd_seq_client_port *port = NULL;
- struct snd_seq_port_info info;
-
- if (copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
- cptr = snd_seq_client_use_ptr(info.addr.client);
- if (cptr == NULL)
- return -ENXIO;
-
- /* search for next port */
- info.addr.port++;
- port = snd_seq_port_query_nearest(cptr, &info);
- if (port == NULL) {
- snd_seq_client_unlock(cptr);
- return -ENOENT;
- }
-
- /* get port info */
- info.addr = port->addr;
- snd_seq_get_port_info(port, &info);
- snd_seq_port_unlock(port);
- snd_seq_client_unlock(cptr);
-
- if (copy_to_user(arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
-}
-
-/* -------------------------------------------------------- */
-
-static struct seq_ioctl_table {
- unsigned int cmd;
- int (*func)(struct snd_seq_client *client, void __user * arg);
-} ioctl_tables[] = {
- { SNDRV_SEQ_IOCTL_SYSTEM_INFO, snd_seq_ioctl_system_info },
- { SNDRV_SEQ_IOCTL_RUNNING_MODE, snd_seq_ioctl_running_mode },
- { SNDRV_SEQ_IOCTL_GET_CLIENT_INFO, snd_seq_ioctl_get_client_info },
- { SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, snd_seq_ioctl_set_client_info },
- { SNDRV_SEQ_IOCTL_CREATE_PORT, snd_seq_ioctl_create_port },
- { SNDRV_SEQ_IOCTL_DELETE_PORT, snd_seq_ioctl_delete_port },
- { SNDRV_SEQ_IOCTL_GET_PORT_INFO, snd_seq_ioctl_get_port_info },
- { SNDRV_SEQ_IOCTL_SET_PORT_INFO, snd_seq_ioctl_set_port_info },
- { SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, snd_seq_ioctl_subscribe_port },
- { SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, snd_seq_ioctl_unsubscribe_port },
- { SNDRV_SEQ_IOCTL_CREATE_QUEUE, snd_seq_ioctl_create_queue },
- { SNDRV_SEQ_IOCTL_DELETE_QUEUE, snd_seq_ioctl_delete_queue },
- { SNDRV_SEQ_IOCTL_GET_QUEUE_INFO, snd_seq_ioctl_get_queue_info },
- { SNDRV_SEQ_IOCTL_SET_QUEUE_INFO, snd_seq_ioctl_set_queue_info },
- { SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE, snd_seq_ioctl_get_named_queue },
- { SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS, snd_seq_ioctl_get_queue_status },
- { SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO, snd_seq_ioctl_get_queue_tempo },
- { SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO, snd_seq_ioctl_set_queue_tempo },
- { SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER, snd_seq_ioctl_get_queue_timer },
- { SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER, snd_seq_ioctl_set_queue_timer },
- { SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT, snd_seq_ioctl_get_queue_client },
- { SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT, snd_seq_ioctl_set_queue_client },
- { SNDRV_SEQ_IOCTL_GET_CLIENT_POOL, snd_seq_ioctl_get_client_pool },
- { SNDRV_SEQ_IOCTL_SET_CLIENT_POOL, snd_seq_ioctl_set_client_pool },
- { SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION, snd_seq_ioctl_get_subscription },
- { SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT, snd_seq_ioctl_query_next_client },
- { SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, snd_seq_ioctl_query_next_port },
- { SNDRV_SEQ_IOCTL_REMOVE_EVENTS, snd_seq_ioctl_remove_events },
- { SNDRV_SEQ_IOCTL_QUERY_SUBS, snd_seq_ioctl_query_subs },
- { 0, NULL },
-};
-
-static int snd_seq_do_ioctl(struct snd_seq_client *client, unsigned int cmd,
- void __user *arg)
-{
- struct seq_ioctl_table *p;
-
- switch (cmd) {
- case SNDRV_SEQ_IOCTL_PVERSION:
- /* return sequencer version number */
- return put_user(SNDRV_SEQ_VERSION, (int __user *)arg) ? -EFAULT : 0;
- case SNDRV_SEQ_IOCTL_CLIENT_ID:
- /* return the id of this client */
- return put_user(client->number, (int __user *)arg) ? -EFAULT : 0;
- }
-
- if (! arg)
- return -EFAULT;
- for (p = ioctl_tables; p->cmd; p++) {
- if (p->cmd == cmd)
- return p->func(client, arg);
- }
- snd_printd("seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n",
- cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
- return -ENOTTY;
-}
-
-
-static long snd_seq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct snd_seq_client *client = file->private_data;
-
- if (snd_BUG_ON(!client))
- return -ENXIO;
-
- return snd_seq_do_ioctl(client, cmd, (void __user *) arg);
-}
-
-#ifdef CONFIG_COMPAT
-#include "seq_compat.c"
-#else
-#define snd_seq_ioctl_compat NULL
-#endif
-
-/* -------------------------------------------------------- */
-
-
-/* exported to kernel modules */
-int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
- const char *name_fmt, ...)
-{
- struct snd_seq_client *client;
- va_list args;
-
- if (snd_BUG_ON(in_interrupt()))
- return -EBUSY;
-
- if (card && client_index >= SNDRV_SEQ_CLIENTS_PER_CARD)
- return -EINVAL;
- if (card == NULL && client_index >= SNDRV_SEQ_GLOBAL_CLIENTS)
- return -EINVAL;
-
- if (mutex_lock_interruptible(&register_mutex))
- return -ERESTARTSYS;
-
- if (card) {
- client_index += SNDRV_SEQ_GLOBAL_CLIENTS
- + card->number * SNDRV_SEQ_CLIENTS_PER_CARD;
- if (client_index >= SNDRV_SEQ_DYNAMIC_CLIENTS_BEGIN)
- client_index = -1;
- }
-
- /* empty write queue as default */
- client = seq_create_client1(client_index, 0);
- if (client == NULL) {
- mutex_unlock(&register_mutex);
- return -EBUSY; /* failure code */
- }
- usage_alloc(&client_usage, 1);
-
- client->accept_input = 1;
- client->accept_output = 1;
-
- va_start(args, name_fmt);
- vsnprintf(client->name, sizeof(client->name), name_fmt, args);
- va_end(args);
-
- client->type = KERNEL_CLIENT;
- mutex_unlock(&register_mutex);
-
- /* make others aware this new client */
- snd_seq_system_client_ev_client_start(client->number);
-
- /* return client number to caller */
- return client->number;
-}
-
-EXPORT_SYMBOL(snd_seq_create_kernel_client);
-
-/* exported to kernel modules */
-int snd_seq_delete_kernel_client(int client)
-{
- struct snd_seq_client *ptr;
-
- if (snd_BUG_ON(in_interrupt()))
- return -EBUSY;
-
- ptr = clientptr(client);
- if (ptr == NULL)
- return -EINVAL;
-
- seq_free_client(ptr);
- kfree(ptr);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_seq_delete_kernel_client);
-
-/* skeleton to enqueue event, called from snd_seq_kernel_client_enqueue
- * and snd_seq_kernel_client_enqueue_blocking
- */
-static int kernel_client_enqueue(int client, struct snd_seq_event *ev,
- struct file *file, int blocking,
- int atomic, int hop)
-{
- struct snd_seq_client *cptr;
- int result;
-
- if (snd_BUG_ON(!ev))
- return -EINVAL;
-
- if (ev->type == SNDRV_SEQ_EVENT_NONE)
- return 0; /* ignore this */
- if (ev->type == SNDRV_SEQ_EVENT_KERNEL_ERROR)
- return -EINVAL; /* quoted events can't be enqueued */
-
- /* fill in client number */
- ev->source.client = client;
-
- if (check_event_type_and_length(ev))
- return -EINVAL;
-
- cptr = snd_seq_client_use_ptr(client);
- if (cptr == NULL)
- return -EINVAL;
-
- if (! cptr->accept_output)
- result = -EPERM;
- else /* send it */
- result = snd_seq_client_enqueue_event(cptr, ev, file, blocking, atomic, hop);
-
- snd_seq_client_unlock(cptr);
- return result;
-}
-
-/*
- * exported, called by kernel clients to enqueue events (w/o blocking)
- *
- * RETURN VALUE: zero if succeed, negative if error
- */
-int snd_seq_kernel_client_enqueue(int client, struct snd_seq_event * ev,
- int atomic, int hop)
-{
- return kernel_client_enqueue(client, ev, NULL, 0, atomic, hop);
-}
-
-EXPORT_SYMBOL(snd_seq_kernel_client_enqueue);
-
-/*
- * exported, called by kernel clients to enqueue events (with blocking)
- *
- * RETURN VALUE: zero if succeed, negative if error
- */
-int snd_seq_kernel_client_enqueue_blocking(int client, struct snd_seq_event * ev,
- struct file *file,
- int atomic, int hop)
-{
- return kernel_client_enqueue(client, ev, file, 1, atomic, hop);
-}
-
-EXPORT_SYMBOL(snd_seq_kernel_client_enqueue_blocking);
-
-/*
- * exported, called by kernel clients to dispatch events directly to other
- * clients, bypassing the queues. Event time-stamp will be updated.
- *
- * RETURN VALUE: negative = delivery failed,
- * zero, or positive: the number of delivered events
- */
-int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event * ev,
- int atomic, int hop)
-{
- struct snd_seq_client *cptr;
- int result;
-
- if (snd_BUG_ON(!ev))
- return -EINVAL;
-
- /* fill in client number */
- ev->queue = SNDRV_SEQ_QUEUE_DIRECT;
- ev->source.client = client;
-
- if (check_event_type_and_length(ev))
- return -EINVAL;
-
- cptr = snd_seq_client_use_ptr(client);
- if (cptr == NULL)
- return -EINVAL;
-
- if (!cptr->accept_output)
- result = -EPERM;
- else
- result = snd_seq_deliver_event(cptr, ev, atomic, hop);
-
- snd_seq_client_unlock(cptr);
- return result;
-}
-
-EXPORT_SYMBOL(snd_seq_kernel_client_dispatch);
-
-/*
- * exported, called by kernel clients to perform same functions as with
- * userland ioctl()
- */
-int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg)
-{
- struct snd_seq_client *client;
- mm_segment_t fs;
- int result;
-
- client = clientptr(clientid);
- if (client == NULL)
- return -ENXIO;
- fs = snd_enter_user();
- result = snd_seq_do_ioctl(client, cmd, (void __force __user *)arg);
- snd_leave_user(fs);
- return result;
-}
-
-EXPORT_SYMBOL(snd_seq_kernel_client_ctl);
-
-/* exported (for OSS emulator) */
-int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table *wait)
-{
- struct snd_seq_client *client;
-
- client = clientptr(clientid);
- if (client == NULL)
- return -ENXIO;
-
- if (! snd_seq_write_pool_allocated(client))
- return 1;
- if (snd_seq_pool_poll_wait(client->pool, file, wait))
- return 1;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_seq_kernel_client_write_poll);
-
-/*---------------------------------------------------------------------------*/
-
-#ifdef CONFIG_PROC_FS
-/*
- * /proc interface
- */
-static void snd_seq_info_dump_subscribers(struct snd_info_buffer *buffer,
- struct snd_seq_port_subs_info *group,
- int is_src, char *msg)
-{
- struct list_head *p;
- struct snd_seq_subscribers *s;
- int count = 0;
-
- down_read(&group->list_mutex);
- if (list_empty(&group->list_head)) {
- up_read(&group->list_mutex);
- return;
- }
- snd_iprintf(buffer, msg);
- list_for_each(p, &group->list_head) {
- if (is_src)
- s = list_entry(p, struct snd_seq_subscribers, src_list);
- else
- s = list_entry(p, struct snd_seq_subscribers, dest_list);
- if (count++)
- snd_iprintf(buffer, ", ");
- snd_iprintf(buffer, "%d:%d",
- is_src ? s->info.dest.client : s->info.sender.client,
- is_src ? s->info.dest.port : s->info.sender.port);
- if (s->info.flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP)
- snd_iprintf(buffer, "[%c:%d]", ((s->info.flags & SNDRV_SEQ_PORT_SUBS_TIME_REAL) ? 'r' : 't'), s->info.queue);
- if (group->exclusive)
- snd_iprintf(buffer, "[ex]");
- }
- up_read(&group->list_mutex);
- snd_iprintf(buffer, "\n");
-}
-
-#define FLAG_PERM_RD(perm) ((perm) & SNDRV_SEQ_PORT_CAP_READ ? ((perm) & SNDRV_SEQ_PORT_CAP_SUBS_READ ? 'R' : 'r') : '-')
-#define FLAG_PERM_WR(perm) ((perm) & SNDRV_SEQ_PORT_CAP_WRITE ? ((perm) & SNDRV_SEQ_PORT_CAP_SUBS_WRITE ? 'W' : 'w') : '-')
-#define FLAG_PERM_EX(perm) ((perm) & SNDRV_SEQ_PORT_CAP_NO_EXPORT ? '-' : 'e')
-
-#define FLAG_PERM_DUPLEX(perm) ((perm) & SNDRV_SEQ_PORT_CAP_DUPLEX ? 'X' : '-')
-
-static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer,
- struct snd_seq_client *client)
-{
- struct snd_seq_client_port *p;
-
- mutex_lock(&client->ports_mutex);
- list_for_each_entry(p, &client->ports_list_head, list) {
- snd_iprintf(buffer, " Port %3d : \"%s\" (%c%c%c%c)\n",
- p->addr.port, p->name,
- FLAG_PERM_RD(p->capability),
- FLAG_PERM_WR(p->capability),
- FLAG_PERM_EX(p->capability),
- FLAG_PERM_DUPLEX(p->capability));
- snd_seq_info_dump_subscribers(buffer, &p->c_src, 1, " Connecting To: ");
- snd_seq_info_dump_subscribers(buffer, &p->c_dest, 0, " Connected From: ");
- }
- mutex_unlock(&client->ports_mutex);
-}
-
-
-/* exported to seq_info.c */
-void snd_seq_info_clients_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- int c;
- struct snd_seq_client *client;
-
- snd_iprintf(buffer, "Client info\n");
- snd_iprintf(buffer, " cur clients : %d\n", client_usage.cur);
- snd_iprintf(buffer, " peak clients : %d\n", client_usage.peak);
- snd_iprintf(buffer, " max clients : %d\n", SNDRV_SEQ_MAX_CLIENTS);
- snd_iprintf(buffer, "\n");
-
- /* list the client table */
- for (c = 0; c < SNDRV_SEQ_MAX_CLIENTS; c++) {
- client = snd_seq_client_use_ptr(c);
- if (client == NULL)
- continue;
- if (client->type == NO_CLIENT) {
- snd_seq_client_unlock(client);
- continue;
- }
-
- snd_iprintf(buffer, "Client %3d : \"%s\" [%s]\n",
- c, client->name,
- client->type == USER_CLIENT ? "User" : "Kernel");
- snd_seq_info_dump_ports(buffer, client);
- if (snd_seq_write_pool_allocated(client)) {
- snd_iprintf(buffer, " Output pool :\n");
- snd_seq_info_pool(buffer, client->pool, " ");
- }
- if (client->type == USER_CLIENT && client->data.user.fifo &&
- client->data.user.fifo->pool) {
- snd_iprintf(buffer, " Input pool :\n");
- snd_seq_info_pool(buffer, client->data.user.fifo->pool, " ");
- }
- snd_seq_client_unlock(client);
- }
-}
-#endif /* CONFIG_PROC_FS */
-
-/*---------------------------------------------------------------------------*/
-
-
-/*
- * REGISTRATION PART
- */
-
-static const struct file_operations snd_seq_f_ops =
-{
- .owner = THIS_MODULE,
- .read = snd_seq_read,
- .write = snd_seq_write,
- .open = snd_seq_open,
- .release = snd_seq_release,
- .llseek = no_llseek,
- .poll = snd_seq_poll,
- .unlocked_ioctl = snd_seq_ioctl,
- .compat_ioctl = snd_seq_ioctl_compat,
-};
-
-/*
- * register sequencer device
- */
-int __init snd_sequencer_device_init(void)
-{
- int err;
-
- if (mutex_lock_interruptible(&register_mutex))
- return -ERESTARTSYS;
-
- if ((err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0,
- &snd_seq_f_ops, NULL, "seq")) < 0) {
- mutex_unlock(&register_mutex);
- return err;
- }
-
- mutex_unlock(&register_mutex);
-
- return 0;
-}
-
-
-
-/*
- * unregister sequencer device
- */
-void __exit snd_sequencer_device_done(void)
-{
- snd_unregister_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0);
-}
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_clientmgr.h b/ANDROID_3.4.5/sound/core/seq/seq_clientmgr.h
deleted file mode 100644
index 20f0a725..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_clientmgr.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * ALSA sequencer Client Manager
- * Copyright (c) 1998-1999 by Frank van de Pol <fvdpol@coil.demon.nl>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __SND_SEQ_CLIENTMGR_H
-#define __SND_SEQ_CLIENTMGR_H
-
-#include <sound/seq_kernel.h>
-#include <linux/bitops.h>
-#include "seq_fifo.h"
-#include "seq_ports.h"
-#include "seq_lock.h"
-
-
-/* client manager */
-
-struct snd_seq_user_client {
- struct file *file; /* file struct of client */
- /* ... */
-
- /* fifo */
- struct snd_seq_fifo *fifo; /* queue for incoming events */
- int fifo_pool_size;
-};
-
-struct snd_seq_kernel_client {
- /* ... */
-};
-
-
-struct snd_seq_client {
- snd_seq_client_type_t type;
- unsigned int accept_input: 1,
- accept_output: 1;
- char name[64]; /* client name */
- int number; /* client number */
- unsigned int filter; /* filter flags */
- DECLARE_BITMAP(event_filter, 256);
- snd_use_lock_t use_lock;
- int event_lost;
- /* ports */
- int num_ports; /* number of ports */
- struct list_head ports_list_head;
- rwlock_t ports_lock;
- struct mutex ports_mutex;
- int convert32; /* convert 32->64bit */
-
- /* output pool */
- struct snd_seq_pool *pool; /* memory pool for this client */
-
- union {
- struct snd_seq_user_client user;
- struct snd_seq_kernel_client kernel;
- } data;
-};
-
-/* usage statistics */
-struct snd_seq_usage {
- int cur;
- int peak;
-};
-
-
-int client_init_data(void);
-int snd_sequencer_device_init(void);
-void snd_sequencer_device_done(void);
-
-/* get locked pointer to client */
-struct snd_seq_client *snd_seq_client_use_ptr(int clientid);
-
-/* unlock pointer to client */
-#define snd_seq_client_unlock(client) snd_use_lock_free(&(client)->use_lock)
-
-/* dispatch event to client(s) */
-int snd_seq_dispatch_event(struct snd_seq_event_cell *cell, int atomic, int hop);
-
-/* exported to other modules */
-int snd_seq_kernel_client_enqueue(int client, struct snd_seq_event *ev, int atomic, int hop);
-int snd_seq_kernel_client_enqueue_blocking(int client, struct snd_seq_event * ev,
- struct file *file, int atomic, int hop);
-int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table *wait);
-int snd_seq_client_notify_subscription(int client, int port,
- struct snd_seq_port_subscribe *info, int evtype);
-
-extern int seq_client_load[15];
-
-#endif
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_compat.c b/ANDROID_3.4.5/sound/core/seq/seq_compat.c
deleted file mode 100644
index 81f7c109..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_compat.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 32bit -> 64bit ioctl wrapper for sequencer API
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/* This file included from seq.c */
-
-#include <linux/compat.h>
-#include <linux/slab.h>
-
-struct snd_seq_port_info32 {
- struct snd_seq_addr addr; /* client/port numbers */
- char name[64]; /* port name */
-
- u32 capability; /* port capability bits */
- u32 type; /* port type bits */
- s32 midi_channels; /* channels per MIDI port */
- s32 midi_voices; /* voices per MIDI port */
- s32 synth_voices; /* voices per SYNTH port */
-
- s32 read_use; /* R/O: subscribers for output (from this port) */
- s32 write_use; /* R/O: subscribers for input (to this port) */
-
- u32 kernel; /* reserved for kernel use (must be NULL) */
- u32 flags; /* misc. conditioning */
- unsigned char time_queue; /* queue # for timestamping */
- char reserved[59]; /* for future use */
-};
-
-static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned int cmd,
- struct snd_seq_port_info32 __user *data32)
-{
- int err = -EFAULT;
- struct snd_seq_port_info *data;
- mm_segment_t fs;
-
- data = memdup_user(data32, sizeof(*data32));
- if (IS_ERR(data))
- return PTR_ERR(data);
-
- if (get_user(data->flags, &data32->flags) ||
- get_user(data->time_queue, &data32->time_queue))
- goto error;
- data->kernel = NULL;
-
- fs = snd_enter_user();
- err = snd_seq_do_ioctl(client, cmd, data);
- snd_leave_user(fs);
- if (err < 0)
- goto error;
-
- if (copy_to_user(data32, data, sizeof(*data32)) ||
- put_user(data->flags, &data32->flags) ||
- put_user(data->time_queue, &data32->time_queue))
- err = -EFAULT;
-
- error:
- kfree(data);
- return err;
-}
-
-
-
-/*
- */
-
-enum {
- SNDRV_SEQ_IOCTL_CREATE_PORT32 = _IOWR('S', 0x20, struct snd_seq_port_info32),
- SNDRV_SEQ_IOCTL_DELETE_PORT32 = _IOW ('S', 0x21, struct snd_seq_port_info32),
- SNDRV_SEQ_IOCTL_GET_PORT_INFO32 = _IOWR('S', 0x22, struct snd_seq_port_info32),
- SNDRV_SEQ_IOCTL_SET_PORT_INFO32 = _IOW ('S', 0x23, struct snd_seq_port_info32),
- SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32 = _IOWR('S', 0x52, struct snd_seq_port_info32),
-};
-
-static long snd_seq_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct snd_seq_client *client = file->private_data;
- void __user *argp = compat_ptr(arg);
-
- if (snd_BUG_ON(!client))
- return -ENXIO;
-
- switch (cmd) {
- case SNDRV_SEQ_IOCTL_PVERSION:
- case SNDRV_SEQ_IOCTL_CLIENT_ID:
- case SNDRV_SEQ_IOCTL_SYSTEM_INFO:
- case SNDRV_SEQ_IOCTL_GET_CLIENT_INFO:
- case SNDRV_SEQ_IOCTL_SET_CLIENT_INFO:
- case SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT:
- case SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT:
- case SNDRV_SEQ_IOCTL_CREATE_QUEUE:
- case SNDRV_SEQ_IOCTL_DELETE_QUEUE:
- case SNDRV_SEQ_IOCTL_GET_QUEUE_INFO:
- case SNDRV_SEQ_IOCTL_SET_QUEUE_INFO:
- case SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE:
- case SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS:
- case SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO:
- case SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO:
- case SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER:
- case SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER:
- case SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT:
- case SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT:
- case SNDRV_SEQ_IOCTL_GET_CLIENT_POOL:
- case SNDRV_SEQ_IOCTL_SET_CLIENT_POOL:
- case SNDRV_SEQ_IOCTL_REMOVE_EVENTS:
- case SNDRV_SEQ_IOCTL_QUERY_SUBS:
- case SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION:
- case SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT:
- case SNDRV_SEQ_IOCTL_RUNNING_MODE:
- return snd_seq_do_ioctl(client, cmd, argp);
- case SNDRV_SEQ_IOCTL_CREATE_PORT32:
- return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_CREATE_PORT, argp);
- case SNDRV_SEQ_IOCTL_DELETE_PORT32:
- return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_DELETE_PORT, argp);
- case SNDRV_SEQ_IOCTL_GET_PORT_INFO32:
- return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_GET_PORT_INFO, argp);
- case SNDRV_SEQ_IOCTL_SET_PORT_INFO32:
- return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_SET_PORT_INFO, argp);
- case SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32:
- return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, argp);
- }
- return -ENOIOCTLCMD;
-}
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_device.c b/ANDROID_3.4.5/sound/core/seq/seq_device.c
deleted file mode 100644
index 5cf8d65e..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_device.c
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * ALSA sequencer device management
- * Copyright (c) 1999 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
- *----------------------------------------------------------------
- *
- * This device handler separates the card driver module from sequencer
- * stuff (sequencer core, synth drivers, etc), so that user can avoid
- * to spend unnecessary resources e.g. if he needs only listening to
- * MP3s.
- *
- * The card (or lowlevel) driver creates a sequencer device entry
- * via snd_seq_device_new(). This is an entry pointer to communicate
- * with the sequencer device "driver", which is involved with the
- * actual part to communicate with the sequencer core.
- * Each sequencer device entry has an id string and the corresponding
- * driver with the same id is loaded when required. For example,
- * lowlevel codes to access emu8000 chip on sbawe card are included in
- * emu8000-synth module. To activate this module, the hardware
- * resources like i/o port are passed via snd_seq_device argument.
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/seq_device.h>
-#include <sound/seq_kernel.h>
-#include <sound/initval.h>
-#include <linux/kmod.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("ALSA sequencer device management");
-MODULE_LICENSE("GPL");
-
-/* driver state */
-#define DRIVER_EMPTY 0
-#define DRIVER_LOADED (1<<0)
-#define DRIVER_REQUESTED (1<<1)
-#define DRIVER_LOCKED (1<<2)
-
-struct ops_list {
- char id[ID_LEN]; /* driver id */
- int driver; /* driver state */
- int used; /* reference counter */
- int argsize; /* argument size */
-
- /* operators */
- struct snd_seq_dev_ops ops;
-
- /* registred devices */
- struct list_head dev_list; /* list of devices */
- int num_devices; /* number of associated devices */
- int num_init_devices; /* number of initialized devices */
- struct mutex reg_mutex;
-
- struct list_head list; /* next driver */
-};
-
-
-static LIST_HEAD(opslist);
-static int num_ops;
-static DEFINE_MUTEX(ops_mutex);
-#ifdef CONFIG_PROC_FS
-static struct snd_info_entry *info_entry;
-#endif
-
-/*
- * prototypes
- */
-static int snd_seq_device_free(struct snd_seq_device *dev);
-static int snd_seq_device_dev_free(struct snd_device *device);
-static int snd_seq_device_dev_register(struct snd_device *device);
-static int snd_seq_device_dev_disconnect(struct snd_device *device);
-
-static int init_device(struct snd_seq_device *dev, struct ops_list *ops);
-static int free_device(struct snd_seq_device *dev, struct ops_list *ops);
-static struct ops_list *find_driver(char *id, int create_if_empty);
-static struct ops_list *create_driver(char *id);
-static void unlock_driver(struct ops_list *ops);
-static void remove_drivers(void);
-
-/*
- * show all drivers and their status
- */
-
-#ifdef CONFIG_PROC_FS
-static void snd_seq_device_info(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct ops_list *ops;
-
- mutex_lock(&ops_mutex);
- list_for_each_entry(ops, &opslist, list) {
- snd_iprintf(buffer, "snd-%s%s%s%s,%d\n",
- ops->id,
- ops->driver & DRIVER_LOADED ? ",loaded" : (ops->driver == DRIVER_EMPTY ? ",empty" : ""),
- ops->driver & DRIVER_REQUESTED ? ",requested" : "",
- ops->driver & DRIVER_LOCKED ? ",locked" : "",
- ops->num_devices);
- }
- mutex_unlock(&ops_mutex);
-}
-#endif
-
-/*
- * load all registered drivers (called from seq_clientmgr.c)
- */
-
-#ifdef CONFIG_MODULES
-/* avoid auto-loading during module_init() */
-static int snd_seq_in_init;
-void snd_seq_autoload_lock(void)
-{
- snd_seq_in_init++;
-}
-
-void snd_seq_autoload_unlock(void)
-{
- snd_seq_in_init--;
-}
-#endif
-
-void snd_seq_device_load_drivers(void)
-{
-#ifdef CONFIG_MODULES
- struct ops_list *ops;
-
- /* Calling request_module during module_init()
- * may cause blocking.
- */
- if (snd_seq_in_init)
- return;
-
- mutex_lock(&ops_mutex);
- list_for_each_entry(ops, &opslist, list) {
- if (! (ops->driver & DRIVER_LOADED) &&
- ! (ops->driver & DRIVER_REQUESTED)) {
- ops->used++;
- mutex_unlock(&ops_mutex);
- ops->driver |= DRIVER_REQUESTED;
- request_module("snd-%s", ops->id);
- mutex_lock(&ops_mutex);
- ops->used--;
- }
- }
- mutex_unlock(&ops_mutex);
-#endif
-}
-
-/*
- * register a sequencer device
- * card = card info (NULL allowed)
- * device = device number (if any)
- * id = id of driver
- * result = return pointer (NULL allowed if unnecessary)
- */
-int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize,
- struct snd_seq_device **result)
-{
- struct snd_seq_device *dev;
- struct ops_list *ops;
- int err;
- static struct snd_device_ops dops = {
- .dev_free = snd_seq_device_dev_free,
- .dev_register = snd_seq_device_dev_register,
- .dev_disconnect = snd_seq_device_dev_disconnect,
- };
-
- if (result)
- *result = NULL;
-
- if (snd_BUG_ON(!id))
- return -EINVAL;
-
- ops = find_driver(id, 1);
- if (ops == NULL)
- return -ENOMEM;
-
- dev = kzalloc(sizeof(*dev)*2 + argsize, GFP_KERNEL);
- if (dev == NULL) {
- unlock_driver(ops);
- return -ENOMEM;
- }
-
- /* set up device info */
- dev->card = card;
- dev->device = device;
- strlcpy(dev->id, id, sizeof(dev->id));
- dev->argsize = argsize;
- dev->status = SNDRV_SEQ_DEVICE_FREE;
-
- /* add this device to the list */
- mutex_lock(&ops->reg_mutex);
- list_add_tail(&dev->list, &ops->dev_list);
- ops->num_devices++;
- mutex_unlock(&ops->reg_mutex);
-
- unlock_driver(ops);
-
- if ((err = snd_device_new(card, SNDRV_DEV_SEQUENCER, dev, &dops)) < 0) {
- snd_seq_device_free(dev);
- return err;
- }
-
- if (result)
- *result = dev;
-
- return 0;
-}
-
-/*
- * free the existing device
- */
-static int snd_seq_device_free(struct snd_seq_device *dev)
-{
- struct ops_list *ops;
-
- if (snd_BUG_ON(!dev))
- return -EINVAL;
-
- ops = find_driver(dev->id, 0);
- if (ops == NULL)
- return -ENXIO;
-
- /* remove the device from the list */
- mutex_lock(&ops->reg_mutex);
- list_del(&dev->list);
- ops->num_devices--;
- mutex_unlock(&ops->reg_mutex);
-
- free_device(dev, ops);
- if (dev->private_free)
- dev->private_free(dev);
- kfree(dev);
-
- unlock_driver(ops);
-
- return 0;
-}
-
-static int snd_seq_device_dev_free(struct snd_device *device)
-{
- struct snd_seq_device *dev = device->device_data;
- return snd_seq_device_free(dev);
-}
-
-/*
- * register the device
- */
-static int snd_seq_device_dev_register(struct snd_device *device)
-{
- struct snd_seq_device *dev = device->device_data;
- struct ops_list *ops;
-
- ops = find_driver(dev->id, 0);
- if (ops == NULL)
- return -ENOENT;
-
- /* initialize this device if the corresponding driver was
- * already loaded
- */
- if (ops->driver & DRIVER_LOADED)
- init_device(dev, ops);
-
- unlock_driver(ops);
- return 0;
-}
-
-/*
- * disconnect the device
- */
-static int snd_seq_device_dev_disconnect(struct snd_device *device)
-{
- struct snd_seq_device *dev = device->device_data;
- struct ops_list *ops;
-
- ops = find_driver(dev->id, 0);
- if (ops == NULL)
- return -ENOENT;
-
- free_device(dev, ops);
-
- unlock_driver(ops);
- return 0;
-}
-
-/*
- * register device driver
- * id = driver id
- * entry = driver operators - duplicated to each instance
- */
-int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry,
- int argsize)
-{
- struct ops_list *ops;
- struct snd_seq_device *dev;
-
- if (id == NULL || entry == NULL ||
- entry->init_device == NULL || entry->free_device == NULL)
- return -EINVAL;
-
- snd_seq_autoload_lock();
- ops = find_driver(id, 1);
- if (ops == NULL) {
- snd_seq_autoload_unlock();
- return -ENOMEM;
- }
- if (ops->driver & DRIVER_LOADED) {
- snd_printk(KERN_WARNING "driver_register: driver '%s' already exists\n", id);
- unlock_driver(ops);
- snd_seq_autoload_unlock();
- return -EBUSY;
- }
-
- mutex_lock(&ops->reg_mutex);
- /* copy driver operators */
- ops->ops = *entry;
- ops->driver |= DRIVER_LOADED;
- ops->argsize = argsize;
-
- /* initialize existing devices if necessary */
- list_for_each_entry(dev, &ops->dev_list, list) {
- init_device(dev, ops);
- }
- mutex_unlock(&ops->reg_mutex);
-
- unlock_driver(ops);
- snd_seq_autoload_unlock();
-
- return 0;
-}
-
-
-/*
- * create driver record
- */
-static struct ops_list * create_driver(char *id)
-{
- struct ops_list *ops;
-
- ops = kzalloc(sizeof(*ops), GFP_KERNEL);
- if (ops == NULL)
- return ops;
-
- /* set up driver entry */
- strlcpy(ops->id, id, sizeof(ops->id));
- mutex_init(&ops->reg_mutex);
- /*
- * The ->reg_mutex locking rules are per-driver, so we create
- * separate per-driver lock classes:
- */
- lockdep_set_class(&ops->reg_mutex, (struct lock_class_key *)id);
-
- ops->driver = DRIVER_EMPTY;
- INIT_LIST_HEAD(&ops->dev_list);
- /* lock this instance */
- ops->used = 1;
-
- /* register driver entry */
- mutex_lock(&ops_mutex);
- list_add_tail(&ops->list, &opslist);
- num_ops++;
- mutex_unlock(&ops_mutex);
-
- return ops;
-}
-
-
-/*
- * unregister the specified driver
- */
-int snd_seq_device_unregister_driver(char *id)
-{
- struct ops_list *ops;
- struct snd_seq_device *dev;
-
- ops = find_driver(id, 0);
- if (ops == NULL)
- return -ENXIO;
- if (! (ops->driver & DRIVER_LOADED) ||
- (ops->driver & DRIVER_LOCKED)) {
- snd_printk(KERN_ERR "driver_unregister: cannot unload driver '%s': status=%x\n",
- id, ops->driver);
- unlock_driver(ops);
- return -EBUSY;
- }
-
- /* close and release all devices associated with this driver */
- mutex_lock(&ops->reg_mutex);
- ops->driver |= DRIVER_LOCKED; /* do not remove this driver recursively */
- list_for_each_entry(dev, &ops->dev_list, list) {
- free_device(dev, ops);
- }
-
- ops->driver = 0;
- if (ops->num_init_devices > 0)
- snd_printk(KERN_ERR "free_driver: init_devices > 0!! (%d)\n",
- ops->num_init_devices);
- mutex_unlock(&ops->reg_mutex);
-
- unlock_driver(ops);
-
- /* remove empty driver entries */
- remove_drivers();
-
- return 0;
-}
-
-
-/*
- * remove empty driver entries
- */
-static void remove_drivers(void)
-{
- struct list_head *head;
-
- mutex_lock(&ops_mutex);
- head = opslist.next;
- while (head != &opslist) {
- struct ops_list *ops = list_entry(head, struct ops_list, list);
- if (! (ops->driver & DRIVER_LOADED) &&
- ops->used == 0 && ops->num_devices == 0) {
- head = head->next;
- list_del(&ops->list);
- kfree(ops);
- num_ops--;
- } else
- head = head->next;
- }
- mutex_unlock(&ops_mutex);
-}
-
-/*
- * initialize the device - call init_device operator
- */
-static int init_device(struct snd_seq_device *dev, struct ops_list *ops)
-{
- if (! (ops->driver & DRIVER_LOADED))
- return 0; /* driver is not loaded yet */
- if (dev->status != SNDRV_SEQ_DEVICE_FREE)
- return 0; /* already initialized */
- if (ops->argsize != dev->argsize) {
- snd_printk(KERN_ERR "incompatible device '%s' for plug-in '%s' (%d %d)\n",
- dev->name, ops->id, ops->argsize, dev->argsize);
- return -EINVAL;
- }
- if (ops->ops.init_device(dev) >= 0) {
- dev->status = SNDRV_SEQ_DEVICE_REGISTERED;
- ops->num_init_devices++;
- } else {
- snd_printk(KERN_ERR "init_device failed: %s: %s\n",
- dev->name, dev->id);
- }
-
- return 0;
-}
-
-/*
- * release the device - call free_device operator
- */
-static int free_device(struct snd_seq_device *dev, struct ops_list *ops)
-{
- int result;
-
- if (! (ops->driver & DRIVER_LOADED))
- return 0; /* driver is not loaded yet */
- if (dev->status != SNDRV_SEQ_DEVICE_REGISTERED)
- return 0; /* not registered */
- if (ops->argsize != dev->argsize) {
- snd_printk(KERN_ERR "incompatible device '%s' for plug-in '%s' (%d %d)\n",
- dev->name, ops->id, ops->argsize, dev->argsize);
- return -EINVAL;
- }
- if ((result = ops->ops.free_device(dev)) >= 0 || result == -ENXIO) {
- dev->status = SNDRV_SEQ_DEVICE_FREE;
- dev->driver_data = NULL;
- ops->num_init_devices--;
- } else {
- snd_printk(KERN_ERR "free_device failed: %s: %s\n",
- dev->name, dev->id);
- }
-
- return 0;
-}
-
-/*
- * find the matching driver with given id
- */
-static struct ops_list * find_driver(char *id, int create_if_empty)
-{
- struct ops_list *ops;
-
- mutex_lock(&ops_mutex);
- list_for_each_entry(ops, &opslist, list) {
- if (strcmp(ops->id, id) == 0) {
- ops->used++;
- mutex_unlock(&ops_mutex);
- return ops;
- }
- }
- mutex_unlock(&ops_mutex);
- if (create_if_empty)
- return create_driver(id);
- return NULL;
-}
-
-static void unlock_driver(struct ops_list *ops)
-{
- mutex_lock(&ops_mutex);
- ops->used--;
- mutex_unlock(&ops_mutex);
-}
-
-
-/*
- * module part
- */
-
-static int __init alsa_seq_device_init(void)
-{
-#ifdef CONFIG_PROC_FS
- info_entry = snd_info_create_module_entry(THIS_MODULE, "drivers",
- snd_seq_root);
- if (info_entry == NULL)
- return -ENOMEM;
- info_entry->content = SNDRV_INFO_CONTENT_TEXT;
- info_entry->c.text.read = snd_seq_device_info;
- if (snd_info_register(info_entry) < 0) {
- snd_info_free_entry(info_entry);
- return -ENOMEM;
- }
-#endif
- return 0;
-}
-
-static void __exit alsa_seq_device_exit(void)
-{
- remove_drivers();
-#ifdef CONFIG_PROC_FS
- snd_info_free_entry(info_entry);
-#endif
- if (num_ops)
- snd_printk(KERN_ERR "drivers not released (%d)\n", num_ops);
-}
-
-module_init(alsa_seq_device_init)
-module_exit(alsa_seq_device_exit)
-
-EXPORT_SYMBOL(snd_seq_device_load_drivers);
-EXPORT_SYMBOL(snd_seq_device_new);
-EXPORT_SYMBOL(snd_seq_device_register_driver);
-EXPORT_SYMBOL(snd_seq_device_unregister_driver);
-EXPORT_SYMBOL(snd_seq_autoload_lock);
-EXPORT_SYMBOL(snd_seq_autoload_unlock);
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_dummy.c b/ANDROID_3.4.5/sound/core/seq/seq_dummy.c
deleted file mode 100644
index dbc55071..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_dummy.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * ALSA sequencer MIDI-through client
- * Copyright (c) 1999-2000 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include "seq_clientmgr.h"
-#include <sound/initval.h>
-#include <sound/asoundef.h>
-
-/*
-
- Sequencer MIDI-through client
-
- This gives a simple midi-through client. All the normal input events
- are redirected to output port immediately.
- The routing can be done via aconnect program in alsa-utils.
-
- Each client has a static client number 62 (= SNDRV_SEQ_CLIENT_DUMMY).
- If you want to auto-load this module, you may add the following alias
- in your /etc/conf.modules file.
-
- alias snd-seq-client-62 snd-seq-dummy
-
- The module is loaded on demand for client 62, or /proc/asound/seq/
- is accessed. If you don't need this module to be loaded, alias
- snd-seq-client-62 as "off". This will help modprobe.
-
- The number of ports to be created can be specified via the module
- parameter "ports". For example, to create four ports, add the
- following option in a configuration file under /etc/modprobe.d/:
-
- option snd-seq-dummy ports=4
-
- The model option "duplex=1" enables duplex operation to the port.
- In duplex mode, a pair of ports are created instead of single port,
- and events are tunneled between pair-ports. For example, input to
- port A is sent to output port of another port B and vice versa.
- In duplex mode, each port has DUPLEX capability.
-
- */
-
-
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("ALSA sequencer MIDI-through client");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("snd-seq-client-" __stringify(SNDRV_SEQ_CLIENT_DUMMY));
-
-static int ports = 1;
-static bool duplex;
-
-module_param(ports, int, 0444);
-MODULE_PARM_DESC(ports, "number of ports to be created");
-module_param(duplex, bool, 0444);
-MODULE_PARM_DESC(duplex, "create DUPLEX ports");
-
-struct snd_seq_dummy_port {
- int client;
- int port;
- int duplex;
- int connect;
-};
-
-static int my_client = -1;
-
-/*
- * unuse callback - send ALL_SOUNDS_OFF and RESET_CONTROLLERS events
- * to subscribers.
- * Note: this callback is called only after all subscribers are removed.
- */
-static int
-dummy_unuse(void *private_data, struct snd_seq_port_subscribe *info)
-{
- struct snd_seq_dummy_port *p;
- int i;
- struct snd_seq_event ev;
-
- p = private_data;
- memset(&ev, 0, sizeof(ev));
- if (p->duplex)
- ev.source.port = p->connect;
- else
- ev.source.port = p->port;
- ev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS;
- ev.type = SNDRV_SEQ_EVENT_CONTROLLER;
- for (i = 0; i < 16; i++) {
- ev.data.control.channel = i;
- ev.data.control.param = MIDI_CTL_ALL_SOUNDS_OFF;
- snd_seq_kernel_client_dispatch(p->client, &ev, 0, 0);
- ev.data.control.param = MIDI_CTL_RESET_CONTROLLERS;
- snd_seq_kernel_client_dispatch(p->client, &ev, 0, 0);
- }
- return 0;
-}
-
-/*
- * event input callback - just redirect events to subscribers
- */
-static int
-dummy_input(struct snd_seq_event *ev, int direct, void *private_data,
- int atomic, int hop)
-{
- struct snd_seq_dummy_port *p;
- struct snd_seq_event tmpev;
-
- p = private_data;
- if (ev->source.client == SNDRV_SEQ_CLIENT_SYSTEM ||
- ev->type == SNDRV_SEQ_EVENT_KERNEL_ERROR)
- return 0; /* ignore system messages */
- tmpev = *ev;
- if (p->duplex)
- tmpev.source.port = p->connect;
- else
- tmpev.source.port = p->port;
- tmpev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS;
- return snd_seq_kernel_client_dispatch(p->client, &tmpev, atomic, hop);
-}
-
-/*
- * free_private callback
- */
-static void
-dummy_free(void *private_data)
-{
- kfree(private_data);
-}
-
-/*
- * create a port
- */
-static struct snd_seq_dummy_port __init *
-create_port(int idx, int type)
-{
- struct snd_seq_port_info pinfo;
- struct snd_seq_port_callback pcb;
- struct snd_seq_dummy_port *rec;
-
- if ((rec = kzalloc(sizeof(*rec), GFP_KERNEL)) == NULL)
- return NULL;
-
- rec->client = my_client;
- rec->duplex = duplex;
- rec->connect = 0;
- memset(&pinfo, 0, sizeof(pinfo));
- pinfo.addr.client = my_client;
- if (duplex)
- sprintf(pinfo.name, "Midi Through Port-%d:%c", idx,
- (type ? 'B' : 'A'));
- else
- sprintf(pinfo.name, "Midi Through Port-%d", idx);
- pinfo.capability = SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ;
- pinfo.capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
- if (duplex)
- pinfo.capability |= SNDRV_SEQ_PORT_CAP_DUPLEX;
- pinfo.type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC
- | SNDRV_SEQ_PORT_TYPE_SOFTWARE
- | SNDRV_SEQ_PORT_TYPE_PORT;
- memset(&pcb, 0, sizeof(pcb));
- pcb.owner = THIS_MODULE;
- pcb.unuse = dummy_unuse;
- pcb.event_input = dummy_input;
- pcb.private_free = dummy_free;
- pcb.private_data = rec;
- pinfo.kernel = &pcb;
- if (snd_seq_kernel_client_ctl(my_client, SNDRV_SEQ_IOCTL_CREATE_PORT, &pinfo) < 0) {
- kfree(rec);
- return NULL;
- }
- rec->port = pinfo.addr.port;
- return rec;
-}
-
-/*
- * register client and create ports
- */
-static int __init
-register_client(void)
-{
- struct snd_seq_dummy_port *rec1, *rec2;
- int i;
-
- if (ports < 1) {
- snd_printk(KERN_ERR "invalid number of ports %d\n", ports);
- return -EINVAL;
- }
-
- /* create client */
- my_client = snd_seq_create_kernel_client(NULL, SNDRV_SEQ_CLIENT_DUMMY,
- "Midi Through");
- if (my_client < 0)
- return my_client;
-
- /* create ports */
- for (i = 0; i < ports; i++) {
- rec1 = create_port(i, 0);
- if (rec1 == NULL) {
- snd_seq_delete_kernel_client(my_client);
- return -ENOMEM;
- }
- if (duplex) {
- rec2 = create_port(i, 1);
- if (rec2 == NULL) {
- snd_seq_delete_kernel_client(my_client);
- return -ENOMEM;
- }
- rec1->connect = rec2->port;
- rec2->connect = rec1->port;
- }
- }
-
- return 0;
-}
-
-/*
- * delete client if exists
- */
-static void __exit
-delete_client(void)
-{
- if (my_client >= 0)
- snd_seq_delete_kernel_client(my_client);
-}
-
-/*
- * Init part
- */
-
-static int __init alsa_seq_dummy_init(void)
-{
- int err;
- snd_seq_autoload_lock();
- err = register_client();
- snd_seq_autoload_unlock();
- return err;
-}
-
-static void __exit alsa_seq_dummy_exit(void)
-{
- delete_client();
-}
-
-module_init(alsa_seq_dummy_init)
-module_exit(alsa_seq_dummy_exit)
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_fifo.c b/ANDROID_3.4.5/sound/core/seq/seq_fifo.c
deleted file mode 100644
index 0d75afa7..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_fifo.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * ALSA sequencer FIFO
- * Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <sound/core.h>
-#include <linux/slab.h>
-#include "seq_fifo.h"
-#include "seq_lock.h"
-
-
-/* FIFO */
-
-/* create new fifo */
-struct snd_seq_fifo *snd_seq_fifo_new(int poolsize)
-{
- struct snd_seq_fifo *f;
-
- f = kzalloc(sizeof(*f), GFP_KERNEL);
- if (f == NULL) {
- snd_printd("malloc failed for snd_seq_fifo_new() \n");
- return NULL;
- }
-
- f->pool = snd_seq_pool_new(poolsize);
- if (f->pool == NULL) {
- kfree(f);
- return NULL;
- }
- if (snd_seq_pool_init(f->pool) < 0) {
- snd_seq_pool_delete(&f->pool);
- kfree(f);
- return NULL;
- }
-
- spin_lock_init(&f->lock);
- snd_use_lock_init(&f->use_lock);
- init_waitqueue_head(&f->input_sleep);
- atomic_set(&f->overflow, 0);
-
- f->head = NULL;
- f->tail = NULL;
- f->cells = 0;
-
- return f;
-}
-
-void snd_seq_fifo_delete(struct snd_seq_fifo **fifo)
-{
- struct snd_seq_fifo *f;
-
- if (snd_BUG_ON(!fifo))
- return;
- f = *fifo;
- if (snd_BUG_ON(!f))
- return;
- *fifo = NULL;
-
- snd_seq_fifo_clear(f);
-
- /* wake up clients if any */
- if (waitqueue_active(&f->input_sleep))
- wake_up(&f->input_sleep);
-
- /* release resources...*/
- /*....................*/
-
- if (f->pool) {
- snd_seq_pool_done(f->pool);
- snd_seq_pool_delete(&f->pool);
- }
-
- kfree(f);
-}
-
-static struct snd_seq_event_cell *fifo_cell_out(struct snd_seq_fifo *f);
-
-/* clear queue */
-void snd_seq_fifo_clear(struct snd_seq_fifo *f)
-{
- struct snd_seq_event_cell *cell;
- unsigned long flags;
-
- /* clear overflow flag */
- atomic_set(&f->overflow, 0);
-
- snd_use_lock_sync(&f->use_lock);
- spin_lock_irqsave(&f->lock, flags);
- /* drain the fifo */
- while ((cell = fifo_cell_out(f)) != NULL) {
- snd_seq_cell_free(cell);
- }
- spin_unlock_irqrestore(&f->lock, flags);
-}
-
-
-/* enqueue event to fifo */
-int snd_seq_fifo_event_in(struct snd_seq_fifo *f,
- struct snd_seq_event *event)
-{
- struct snd_seq_event_cell *cell;
- unsigned long flags;
- int err;
-
- if (snd_BUG_ON(!f))
- return -EINVAL;
-
- snd_use_lock_use(&f->use_lock);
- err = snd_seq_event_dup(f->pool, event, &cell, 1, NULL); /* always non-blocking */
- if (err < 0) {
- if (err == -ENOMEM)
- atomic_inc(&f->overflow);
- snd_use_lock_free(&f->use_lock);
- return err;
- }
-
- /* append new cells to fifo */
- spin_lock_irqsave(&f->lock, flags);
- if (f->tail != NULL)
- f->tail->next = cell;
- f->tail = cell;
- if (f->head == NULL)
- f->head = cell;
- f->cells++;
- spin_unlock_irqrestore(&f->lock, flags);
-
- /* wakeup client */
- if (waitqueue_active(&f->input_sleep))
- wake_up(&f->input_sleep);
-
- snd_use_lock_free(&f->use_lock);
-
- return 0; /* success */
-
-}
-
-/* dequeue cell from fifo */
-static struct snd_seq_event_cell *fifo_cell_out(struct snd_seq_fifo *f)
-{
- struct snd_seq_event_cell *cell;
-
- if ((cell = f->head) != NULL) {
- f->head = cell->next;
-
- /* reset tail if this was the last element */
- if (f->tail == cell)
- f->tail = NULL;
-
- cell->next = NULL;
- f->cells--;
- }
-
- return cell;
-}
-
-/* dequeue cell from fifo and copy on user space */
-int snd_seq_fifo_cell_out(struct snd_seq_fifo *f,
- struct snd_seq_event_cell **cellp, int nonblock)
-{
- struct snd_seq_event_cell *cell;
- unsigned long flags;
- wait_queue_t wait;
-
- if (snd_BUG_ON(!f))
- return -EINVAL;
-
- *cellp = NULL;
- init_waitqueue_entry(&wait, current);
- spin_lock_irqsave(&f->lock, flags);
- while ((cell = fifo_cell_out(f)) == NULL) {
- if (nonblock) {
- /* non-blocking - return immediately */
- spin_unlock_irqrestore(&f->lock, flags);
- return -EAGAIN;
- }
- set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(&f->input_sleep, &wait);
- spin_unlock_irq(&f->lock);
- schedule();
- spin_lock_irq(&f->lock);
- remove_wait_queue(&f->input_sleep, &wait);
- if (signal_pending(current)) {
- spin_unlock_irqrestore(&f->lock, flags);
- return -ERESTARTSYS;
- }
- }
- spin_unlock_irqrestore(&f->lock, flags);
- *cellp = cell;
-
- return 0;
-}
-
-
-void snd_seq_fifo_cell_putback(struct snd_seq_fifo *f,
- struct snd_seq_event_cell *cell)
-{
- unsigned long flags;
-
- if (cell) {
- spin_lock_irqsave(&f->lock, flags);
- cell->next = f->head;
- f->head = cell;
- f->cells++;
- spin_unlock_irqrestore(&f->lock, flags);
- }
-}
-
-
-/* polling; return non-zero if queue is available */
-int snd_seq_fifo_poll_wait(struct snd_seq_fifo *f, struct file *file,
- poll_table *wait)
-{
- poll_wait(file, &f->input_sleep, wait);
- return (f->cells > 0);
-}
-
-/* change the size of pool; all old events are removed */
-int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize)
-{
- unsigned long flags;
- struct snd_seq_pool *newpool, *oldpool;
- struct snd_seq_event_cell *cell, *next, *oldhead;
-
- if (snd_BUG_ON(!f || !f->pool))
- return -EINVAL;
-
- /* allocate new pool */
- newpool = snd_seq_pool_new(poolsize);
- if (newpool == NULL)
- return -ENOMEM;
- if (snd_seq_pool_init(newpool) < 0) {
- snd_seq_pool_delete(&newpool);
- return -ENOMEM;
- }
-
- spin_lock_irqsave(&f->lock, flags);
- /* remember old pool */
- oldpool = f->pool;
- oldhead = f->head;
- /* exchange pools */
- f->pool = newpool;
- f->head = NULL;
- f->tail = NULL;
- f->cells = 0;
- /* NOTE: overflow flag is not cleared */
- spin_unlock_irqrestore(&f->lock, flags);
-
- /* release cells in old pool */
- for (cell = oldhead; cell; cell = next) {
- next = cell->next;
- snd_seq_cell_free(cell);
- }
- snd_seq_pool_delete(&oldpool);
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_fifo.h b/ANDROID_3.4.5/sound/core/seq/seq_fifo.h
deleted file mode 100644
index 062c446e..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_fifo.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * ALSA sequencer FIFO
- * Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __SND_SEQ_FIFO_H
-#define __SND_SEQ_FIFO_H
-
-#include "seq_memory.h"
-#include "seq_lock.h"
-
-
-/* === FIFO === */
-
-struct snd_seq_fifo {
- struct snd_seq_pool *pool; /* FIFO pool */
- struct snd_seq_event_cell *head; /* pointer to head of fifo */
- struct snd_seq_event_cell *tail; /* pointer to tail of fifo */
- int cells;
- spinlock_t lock;
- snd_use_lock_t use_lock;
- wait_queue_head_t input_sleep;
- atomic_t overflow;
-
-};
-
-/* create new fifo (constructor) */
-struct snd_seq_fifo *snd_seq_fifo_new(int poolsize);
-
-/* delete fifo (destructor) */
-void snd_seq_fifo_delete(struct snd_seq_fifo **f);
-
-
-/* enqueue event to fifo */
-int snd_seq_fifo_event_in(struct snd_seq_fifo *f, struct snd_seq_event *event);
-
-/* lock fifo from release */
-#define snd_seq_fifo_lock(fifo) snd_use_lock_use(&(fifo)->use_lock)
-#define snd_seq_fifo_unlock(fifo) snd_use_lock_free(&(fifo)->use_lock)
-
-/* get a cell from fifo - fifo should be locked */
-int snd_seq_fifo_cell_out(struct snd_seq_fifo *f, struct snd_seq_event_cell **cellp, int nonblock);
-
-/* free dequeued cell - fifo should be locked */
-void snd_seq_fifo_cell_putback(struct snd_seq_fifo *f, struct snd_seq_event_cell *cell);
-
-/* clean up queue */
-void snd_seq_fifo_clear(struct snd_seq_fifo *f);
-
-/* polling */
-int snd_seq_fifo_poll_wait(struct snd_seq_fifo *f, struct file *file, poll_table *wait);
-
-/* resize pool in fifo */
-int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize);
-
-
-#endif
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_info.c b/ANDROID_3.4.5/sound/core/seq/seq_info.c
deleted file mode 100644
index acf77694..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_info.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * ALSA sequencer /proc interface
- * Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/export.h>
-#include <sound/core.h>
-
-#include "seq_info.h"
-#include "seq_clientmgr.h"
-#include "seq_timer.h"
-
-#ifdef CONFIG_PROC_FS
-static struct snd_info_entry *queues_entry;
-static struct snd_info_entry *clients_entry;
-static struct snd_info_entry *timer_entry;
-
-
-static struct snd_info_entry * __init
-create_info_entry(char *name, void (*read)(struct snd_info_entry *,
- struct snd_info_buffer *))
-{
- struct snd_info_entry *entry;
-
- entry = snd_info_create_module_entry(THIS_MODULE, name, snd_seq_root);
- if (entry == NULL)
- return NULL;
- entry->content = SNDRV_INFO_CONTENT_TEXT;
- entry->c.text.read = read;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- return NULL;
- }
- return entry;
-}
-
-/* create all our /proc entries */
-int __init snd_seq_info_init(void)
-{
- queues_entry = create_info_entry("queues",
- snd_seq_info_queues_read);
- clients_entry = create_info_entry("clients",
- snd_seq_info_clients_read);
- timer_entry = create_info_entry("timer", snd_seq_info_timer_read);
- return 0;
-}
-
-int __exit snd_seq_info_done(void)
-{
- snd_info_free_entry(queues_entry);
- snd_info_free_entry(clients_entry);
- snd_info_free_entry(timer_entry);
- return 0;
-}
-#endif
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_info.h b/ANDROID_3.4.5/sound/core/seq/seq_info.h
deleted file mode 100644
index 4892a7f3..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_info.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * ALSA sequencer /proc info
- * Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __SND_SEQ_INFO_H
-#define __SND_SEQ_INFO_H
-
-#include <sound/info.h>
-#include <sound/seq_kernel.h>
-
-void snd_seq_info_clients_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer);
-void snd_seq_info_timer_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer);
-void snd_seq_info_queues_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer);
-
-
-#ifdef CONFIG_PROC_FS
-int snd_seq_info_init( void );
-int snd_seq_info_done( void );
-#else
-static inline int snd_seq_info_init(void) { return 0; }
-static inline int snd_seq_info_done(void) { return 0; }
-#endif
-
-#endif
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_lock.c b/ANDROID_3.4.5/sound/core/seq/seq_lock.c
deleted file mode 100644
index 2cfe50c7..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_lock.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Do sleep inside a spin-lock
- * Copyright (c) 1999 by Takashi Iwai <tiwai@suse.de>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/export.h>
-#include <sound/core.h>
-#include "seq_lock.h"
-
-#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
-
-/* wait until all locks are released */
-void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
-{
- int max_count = 5 * HZ;
-
- if (atomic_read(lockp) < 0) {
- printk(KERN_WARNING "seq_lock: lock trouble [counter = %d] in %s:%d\n", atomic_read(lockp), file, line);
- return;
- }
- while (atomic_read(lockp) > 0) {
- if (max_count == 0) {
- snd_printk(KERN_WARNING "seq_lock: timeout [%d left] in %s:%d\n", atomic_read(lockp), file, line);
- break;
- }
- schedule_timeout_uninterruptible(1);
- max_count--;
- }
-}
-
-EXPORT_SYMBOL(snd_use_lock_sync_helper);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_lock.h b/ANDROID_3.4.5/sound/core/seq/seq_lock.h
deleted file mode 100644
index 54044bc2..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_lock.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef __SND_SEQ_LOCK_H
-#define __SND_SEQ_LOCK_H
-
-#include <linux/sched.h>
-
-#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
-
-typedef atomic_t snd_use_lock_t;
-
-/* initialize lock */
-#define snd_use_lock_init(lockp) atomic_set(lockp, 0)
-
-/* increment lock */
-#define snd_use_lock_use(lockp) atomic_inc(lockp)
-
-/* release lock */
-#define snd_use_lock_free(lockp) atomic_dec(lockp)
-
-/* wait until all locks are released */
-void snd_use_lock_sync_helper(snd_use_lock_t *lock, const char *file, int line);
-#define snd_use_lock_sync(lockp) snd_use_lock_sync_helper(lockp, __BASE_FILE__, __LINE__)
-
-#else /* SMP || CONFIG_SND_DEBUG */
-
-typedef spinlock_t snd_use_lock_t; /* dummy */
-#define snd_use_lock_init(lockp) /**/
-#define snd_use_lock_use(lockp) /**/
-#define snd_use_lock_free(lockp) /**/
-#define snd_use_lock_sync(lockp) /**/
-
-#endif /* SMP || CONFIG_SND_DEBUG */
-
-#endif /* __SND_SEQ_LOCK_H */
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_memory.c b/ANDROID_3.4.5/sound/core/seq/seq_memory.c
deleted file mode 100644
index f478f770..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_memory.c
+++ /dev/null
@@ -1,521 +0,0 @@
-/*
- * ALSA sequencer Memory Manager
- * Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl>
- * Jaroslav Kysela <perex@perex.cz>
- * 2000 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/export.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <sound/core.h>
-
-#include <sound/seq_kernel.h>
-#include "seq_memory.h"
-#include "seq_queue.h"
-#include "seq_info.h"
-#include "seq_lock.h"
-
-static inline int snd_seq_pool_available(struct snd_seq_pool *pool)
-{
- return pool->total_elements - atomic_read(&pool->counter);
-}
-
-static inline int snd_seq_output_ok(struct snd_seq_pool *pool)
-{
- return snd_seq_pool_available(pool) >= pool->room;
-}
-
-/*
- * Variable length event:
- * The event like sysex uses variable length type.
- * The external data may be stored in three different formats.
- * 1) kernel space
- * This is the normal case.
- * ext.data.len = length
- * ext.data.ptr = buffer pointer
- * 2) user space
- * When an event is generated via read(), the external data is
- * kept in user space until expanded.
- * ext.data.len = length | SNDRV_SEQ_EXT_USRPTR
- * ext.data.ptr = userspace pointer
- * 3) chained cells
- * When the variable length event is enqueued (in prioq or fifo),
- * the external data is decomposed to several cells.
- * ext.data.len = length | SNDRV_SEQ_EXT_CHAINED
- * ext.data.ptr = the additiona cell head
- * -> cell.next -> cell.next -> ..
- */
-
-/*
- * exported:
- * call dump function to expand external data.
- */
-
-static int get_var_len(const struct snd_seq_event *event)
-{
- if ((event->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE)
- return -EINVAL;
-
- return event->data.ext.len & ~SNDRV_SEQ_EXT_MASK;
-}
-
-int snd_seq_dump_var_event(const struct snd_seq_event *event,
- snd_seq_dump_func_t func, void *private_data)
-{
- int len, err;
- struct snd_seq_event_cell *cell;
-
- if ((len = get_var_len(event)) <= 0)
- return len;
-
- if (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR) {
- char buf[32];
- char __user *curptr = (char __force __user *)event->data.ext.ptr;
- while (len > 0) {
- int size = sizeof(buf);
- if (len < size)
- size = len;
- if (copy_from_user(buf, curptr, size))
- return -EFAULT;
- err = func(private_data, buf, size);
- if (err < 0)
- return err;
- curptr += size;
- len -= size;
- }
- return 0;
- } if (! (event->data.ext.len & SNDRV_SEQ_EXT_CHAINED)) {
- return func(private_data, event->data.ext.ptr, len);
- }
-
- cell = (struct snd_seq_event_cell *)event->data.ext.ptr;
- for (; len > 0 && cell; cell = cell->next) {
- int size = sizeof(struct snd_seq_event);
- if (len < size)
- size = len;
- err = func(private_data, &cell->event, size);
- if (err < 0)
- return err;
- len -= size;
- }
- return 0;
-}
-
-EXPORT_SYMBOL(snd_seq_dump_var_event);
-
-
-/*
- * exported:
- * expand the variable length event to linear buffer space.
- */
-
-static int seq_copy_in_kernel(char **bufptr, const void *src, int size)
-{
- memcpy(*bufptr, src, size);
- *bufptr += size;
- return 0;
-}
-
-static int seq_copy_in_user(char __user **bufptr, const void *src, int size)
-{
- if (copy_to_user(*bufptr, src, size))
- return -EFAULT;
- *bufptr += size;
- return 0;
-}
-
-int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char *buf,
- int in_kernel, int size_aligned)
-{
- int len, newlen;
- int err;
-
- if ((len = get_var_len(event)) < 0)
- return len;
- newlen = len;
- if (size_aligned > 0)
- newlen = roundup(len, size_aligned);
- if (count < newlen)
- return -EAGAIN;
-
- if (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR) {
- if (! in_kernel)
- return -EINVAL;
- if (copy_from_user(buf, (void __force __user *)event->data.ext.ptr, len))
- return -EFAULT;
- return newlen;
- }
- err = snd_seq_dump_var_event(event,
- in_kernel ? (snd_seq_dump_func_t)seq_copy_in_kernel :
- (snd_seq_dump_func_t)seq_copy_in_user,
- &buf);
- return err < 0 ? err : newlen;
-}
-
-EXPORT_SYMBOL(snd_seq_expand_var_event);
-
-/*
- * release this cell, free extended data if available
- */
-
-static inline void free_cell(struct snd_seq_pool *pool,
- struct snd_seq_event_cell *cell)
-{
- cell->next = pool->free;
- pool->free = cell;
- atomic_dec(&pool->counter);
-}
-
-void snd_seq_cell_free(struct snd_seq_event_cell * cell)
-{
- unsigned long flags;
- struct snd_seq_pool *pool;
-
- if (snd_BUG_ON(!cell))
- return;
- pool = cell->pool;
- if (snd_BUG_ON(!pool))
- return;
-
- spin_lock_irqsave(&pool->lock, flags);
- free_cell(pool, cell);
- if (snd_seq_ev_is_variable(&cell->event)) {
- if (cell->event.data.ext.len & SNDRV_SEQ_EXT_CHAINED) {
- struct snd_seq_event_cell *curp, *nextptr;
- curp = cell->event.data.ext.ptr;
- for (; curp; curp = nextptr) {
- nextptr = curp->next;
- curp->next = pool->free;
- free_cell(pool, curp);
- }
- }
- }
- if (waitqueue_active(&pool->output_sleep)) {
- /* has enough space now? */
- if (snd_seq_output_ok(pool))
- wake_up(&pool->output_sleep);
- }
- spin_unlock_irqrestore(&pool->lock, flags);
-}
-
-
-/*
- * allocate an event cell.
- */
-static int snd_seq_cell_alloc(struct snd_seq_pool *pool,
- struct snd_seq_event_cell **cellp,
- int nonblock, struct file *file)
-{
- struct snd_seq_event_cell *cell;
- unsigned long flags;
- int err = -EAGAIN;
- wait_queue_t wait;
-
- if (pool == NULL)
- return -EINVAL;
-
- *cellp = NULL;
-
- init_waitqueue_entry(&wait, current);
- spin_lock_irqsave(&pool->lock, flags);
- if (pool->ptr == NULL) { /* not initialized */
- snd_printd("seq: pool is not initialized\n");
- err = -EINVAL;
- goto __error;
- }
- while (pool->free == NULL && ! nonblock && ! pool->closing) {
-
- set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(&pool->output_sleep, &wait);
- spin_unlock_irq(&pool->lock);
- schedule();
- spin_lock_irq(&pool->lock);
- remove_wait_queue(&pool->output_sleep, &wait);
- /* interrupted? */
- if (signal_pending(current)) {
- err = -ERESTARTSYS;
- goto __error;
- }
- }
- if (pool->closing) { /* closing.. */
- err = -ENOMEM;
- goto __error;
- }
-
- cell = pool->free;
- if (cell) {
- int used;
- pool->free = cell->next;
- atomic_inc(&pool->counter);
- used = atomic_read(&pool->counter);
- if (pool->max_used < used)
- pool->max_used = used;
- pool->event_alloc_success++;
- /* clear cell pointers */
- cell->next = NULL;
- err = 0;
- } else
- pool->event_alloc_failures++;
- *cellp = cell;
-
-__error:
- spin_unlock_irqrestore(&pool->lock, flags);
- return err;
-}
-
-
-/*
- * duplicate the event to a cell.
- * if the event has external data, the data is decomposed to additional
- * cells.
- */
-int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event,
- struct snd_seq_event_cell **cellp, int nonblock,
- struct file *file)
-{
- int ncells, err;
- unsigned int extlen;
- struct snd_seq_event_cell *cell;
-
- *cellp = NULL;
-
- ncells = 0;
- extlen = 0;
- if (snd_seq_ev_is_variable(event)) {
- extlen = event->data.ext.len & ~SNDRV_SEQ_EXT_MASK;
- ncells = (extlen + sizeof(struct snd_seq_event) - 1) / sizeof(struct snd_seq_event);
- }
- if (ncells >= pool->total_elements)
- return -ENOMEM;
-
- err = snd_seq_cell_alloc(pool, &cell, nonblock, file);
- if (err < 0)
- return err;
-
- /* copy the event */
- cell->event = *event;
-
- /* decompose */
- if (snd_seq_ev_is_variable(event)) {
- int len = extlen;
- int is_chained = event->data.ext.len & SNDRV_SEQ_EXT_CHAINED;
- int is_usrptr = event->data.ext.len & SNDRV_SEQ_EXT_USRPTR;
- struct snd_seq_event_cell *src, *tmp, *tail;
- char *buf;
-
- cell->event.data.ext.len = extlen | SNDRV_SEQ_EXT_CHAINED;
- cell->event.data.ext.ptr = NULL;
-
- src = (struct snd_seq_event_cell *)event->data.ext.ptr;
- buf = (char *)event->data.ext.ptr;
- tail = NULL;
-
- while (ncells-- > 0) {
- int size = sizeof(struct snd_seq_event);
- if (len < size)
- size = len;
- err = snd_seq_cell_alloc(pool, &tmp, nonblock, file);
- if (err < 0)
- goto __error;
- if (cell->event.data.ext.ptr == NULL)
- cell->event.data.ext.ptr = tmp;
- if (tail)
- tail->next = tmp;
- tail = tmp;
- /* copy chunk */
- if (is_chained && src) {
- tmp->event = src->event;
- src = src->next;
- } else if (is_usrptr) {
- if (copy_from_user(&tmp->event, (char __force __user *)buf, size)) {
- err = -EFAULT;
- goto __error;
- }
- } else {
- memcpy(&tmp->event, buf, size);
- }
- buf += size;
- len -= size;
- }
- }
-
- *cellp = cell;
- return 0;
-
-__error:
- snd_seq_cell_free(cell);
- return err;
-}
-
-
-/* poll wait */
-int snd_seq_pool_poll_wait(struct snd_seq_pool *pool, struct file *file,
- poll_table *wait)
-{
- poll_wait(file, &pool->output_sleep, wait);
- return snd_seq_output_ok(pool);
-}
-
-
-/* allocate room specified number of events */
-int snd_seq_pool_init(struct snd_seq_pool *pool)
-{
- int cell;
- struct snd_seq_event_cell *cellptr;
- unsigned long flags;
-
- if (snd_BUG_ON(!pool))
- return -EINVAL;
- if (pool->ptr) /* should be atomic? */
- return 0;
-
- pool->ptr = vmalloc(sizeof(struct snd_seq_event_cell) * pool->size);
- if (pool->ptr == NULL) {
- snd_printd("seq: malloc for sequencer events failed\n");
- return -ENOMEM;
- }
-
- /* add new cells to the free cell list */
- spin_lock_irqsave(&pool->lock, flags);
- pool->free = NULL;
-
- for (cell = 0; cell < pool->size; cell++) {
- cellptr = pool->ptr + cell;
- cellptr->pool = pool;
- cellptr->next = pool->free;
- pool->free = cellptr;
- }
- pool->room = (pool->size + 1) / 2;
-
- /* init statistics */
- pool->max_used = 0;
- pool->total_elements = pool->size;
- spin_unlock_irqrestore(&pool->lock, flags);
- return 0;
-}
-
-/* remove events */
-int snd_seq_pool_done(struct snd_seq_pool *pool)
-{
- unsigned long flags;
- struct snd_seq_event_cell *ptr;
- int max_count = 5 * HZ;
-
- if (snd_BUG_ON(!pool))
- return -EINVAL;
-
- /* wait for closing all threads */
- spin_lock_irqsave(&pool->lock, flags);
- pool->closing = 1;
- spin_unlock_irqrestore(&pool->lock, flags);
-
- if (waitqueue_active(&pool->output_sleep))
- wake_up(&pool->output_sleep);
-
- while (atomic_read(&pool->counter) > 0) {
- if (max_count == 0) {
- snd_printk(KERN_WARNING "snd_seq_pool_done timeout: %d cells remain\n", atomic_read(&pool->counter));
- break;
- }
- schedule_timeout_uninterruptible(1);
- max_count--;
- }
-
- /* release all resources */
- spin_lock_irqsave(&pool->lock, flags);
- ptr = pool->ptr;
- pool->ptr = NULL;
- pool->free = NULL;
- pool->total_elements = 0;
- spin_unlock_irqrestore(&pool->lock, flags);
-
- vfree(ptr);
-
- spin_lock_irqsave(&pool->lock, flags);
- pool->closing = 0;
- spin_unlock_irqrestore(&pool->lock, flags);
-
- return 0;
-}
-
-
-/* init new memory pool */
-struct snd_seq_pool *snd_seq_pool_new(int poolsize)
-{
- struct snd_seq_pool *pool;
-
- /* create pool block */
- pool = kzalloc(sizeof(*pool), GFP_KERNEL);
- if (pool == NULL) {
- snd_printd("seq: malloc failed for pool\n");
- return NULL;
- }
- spin_lock_init(&pool->lock);
- pool->ptr = NULL;
- pool->free = NULL;
- pool->total_elements = 0;
- atomic_set(&pool->counter, 0);
- pool->closing = 0;
- init_waitqueue_head(&pool->output_sleep);
-
- pool->size = poolsize;
-
- /* init statistics */
- pool->max_used = 0;
- return pool;
-}
-
-/* remove memory pool */
-int snd_seq_pool_delete(struct snd_seq_pool **ppool)
-{
- struct snd_seq_pool *pool = *ppool;
-
- *ppool = NULL;
- if (pool == NULL)
- return 0;
- snd_seq_pool_done(pool);
- kfree(pool);
- return 0;
-}
-
-/* initialize sequencer memory */
-int __init snd_sequencer_memory_init(void)
-{
- return 0;
-}
-
-/* release sequencer memory */
-void __exit snd_sequencer_memory_done(void)
-{
-}
-
-
-/* exported to seq_clientmgr.c */
-void snd_seq_info_pool(struct snd_info_buffer *buffer,
- struct snd_seq_pool *pool, char *space)
-{
- if (pool == NULL)
- return;
- snd_iprintf(buffer, "%sPool size : %d\n", space, pool->total_elements);
- snd_iprintf(buffer, "%sCells in use : %d\n", space, atomic_read(&pool->counter));
- snd_iprintf(buffer, "%sPeak cells in use : %d\n", space, pool->max_used);
- snd_iprintf(buffer, "%sAlloc success : %d\n", space, pool->event_alloc_success);
- snd_iprintf(buffer, "%sAlloc failures : %d\n", space, pool->event_alloc_failures);
-}
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_memory.h b/ANDROID_3.4.5/sound/core/seq/seq_memory.h
deleted file mode 100644
index 4a2ec779..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_memory.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * ALSA sequencer Memory Manager
- * Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __SND_SEQ_MEMORYMGR_H
-#define __SND_SEQ_MEMORYMGR_H
-
-#include <sound/seq_kernel.h>
-#include <linux/poll.h>
-
-struct snd_info_buffer;
-
-/* container for sequencer event (internal use) */
-struct snd_seq_event_cell {
- struct snd_seq_event event;
- struct snd_seq_pool *pool; /* used pool */
- struct snd_seq_event_cell *next; /* next cell */
-};
-
-/* design note: the pool is a contiguous block of memory, if we dynamicly
- want to add additional cells to the pool be better store this in another
- pool as we need to know the base address of the pool when releasing
- memory. */
-
-struct snd_seq_pool {
- struct snd_seq_event_cell *ptr; /* pointer to first event chunk */
- struct snd_seq_event_cell *free; /* pointer to the head of the free list */
-
- int total_elements; /* pool size actually allocated */
- atomic_t counter; /* cells free */
-
- int size; /* pool size to be allocated */
- int room; /* watermark for sleep/wakeup */
-
- int closing;
-
- /* statistics */
- int max_used;
- int event_alloc_nopool;
- int event_alloc_failures;
- int event_alloc_success;
-
- /* Write locking */
- wait_queue_head_t output_sleep;
-
- /* Pool lock */
- spinlock_t lock;
-};
-
-void snd_seq_cell_free(struct snd_seq_event_cell *cell);
-
-int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event,
- struct snd_seq_event_cell **cellp, int nonblock, struct file *file);
-
-/* return number of unused (free) cells */
-static inline int snd_seq_unused_cells(struct snd_seq_pool *pool)
-{
- return pool ? pool->total_elements - atomic_read(&pool->counter) : 0;
-}
-
-/* return total number of allocated cells */
-static inline int snd_seq_total_cells(struct snd_seq_pool *pool)
-{
- return pool ? pool->total_elements : 0;
-}
-
-/* init pool - allocate events */
-int snd_seq_pool_init(struct snd_seq_pool *pool);
-
-/* done pool - free events */
-int snd_seq_pool_done(struct snd_seq_pool *pool);
-
-/* create pool */
-struct snd_seq_pool *snd_seq_pool_new(int poolsize);
-
-/* remove pool */
-int snd_seq_pool_delete(struct snd_seq_pool **pool);
-
-/* init memory */
-int snd_sequencer_memory_init(void);
-
-/* release event memory */
-void snd_sequencer_memory_done(void);
-
-/* polling */
-int snd_seq_pool_poll_wait(struct snd_seq_pool *pool, struct file *file, poll_table *wait);
-
-void snd_seq_info_pool(struct snd_info_buffer *buffer,
- struct snd_seq_pool *pool, char *space);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_midi.c b/ANDROID_3.4.5/sound/core/seq/seq_midi.c
deleted file mode 100644
index 64069dbf..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_midi.c
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- * Generic MIDI synth driver for ALSA sequencer
- * Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl>
- * Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
-Possible options for midisynth module:
- - automatic opening of midi ports on first received event or subscription
- (close will be performed when client leaves)
-*/
-
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <sound/core.h>
-#include <sound/rawmidi.h>
-#include <sound/seq_kernel.h>
-#include <sound/seq_device.h>
-#include <sound/seq_midi_event.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Frank van de Pol <fvdpol@coil.demon.nl>, Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Advanced Linux Sound Architecture sequencer MIDI synth.");
-MODULE_LICENSE("GPL");
-static int output_buffer_size = PAGE_SIZE;
-module_param(output_buffer_size, int, 0644);
-MODULE_PARM_DESC(output_buffer_size, "Output buffer size in bytes.");
-static int input_buffer_size = PAGE_SIZE;
-module_param(input_buffer_size, int, 0644);
-MODULE_PARM_DESC(input_buffer_size, "Input buffer size in bytes.");
-
-/* data for this midi synth driver */
-struct seq_midisynth {
- struct snd_card *card;
- int device;
- int subdevice;
- struct snd_rawmidi_file input_rfile;
- struct snd_rawmidi_file output_rfile;
- int seq_client;
- int seq_port;
- struct snd_midi_event *parser;
-};
-
-struct seq_midisynth_client {
- int seq_client;
- int num_ports;
- int ports_per_device[SNDRV_RAWMIDI_DEVICES];
- struct seq_midisynth *ports[SNDRV_RAWMIDI_DEVICES];
-};
-
-static struct seq_midisynth_client *synths[SNDRV_CARDS];
-static DEFINE_MUTEX(register_mutex);
-
-/* handle rawmidi input event (MIDI v1.0 stream) */
-static void snd_midi_input_event(struct snd_rawmidi_substream *substream)
-{
- struct snd_rawmidi_runtime *runtime;
- struct seq_midisynth *msynth;
- struct snd_seq_event ev;
- char buf[16], *pbuf;
- long res, count;
-
- if (substream == NULL)
- return;
- runtime = substream->runtime;
- msynth = runtime->private_data;
- if (msynth == NULL)
- return;
- memset(&ev, 0, sizeof(ev));
- while (runtime->avail > 0) {
- res = snd_rawmidi_kernel_read(substream, buf, sizeof(buf));
- if (res <= 0)
- continue;
- if (msynth->parser == NULL)
- continue;
- pbuf = buf;
- while (res > 0) {
- count = snd_midi_event_encode(msynth->parser, pbuf, res, &ev);
- if (count < 0)
- break;
- pbuf += count;
- res -= count;
- if (ev.type != SNDRV_SEQ_EVENT_NONE) {
- ev.source.port = msynth->seq_port;
- ev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS;
- snd_seq_kernel_client_dispatch(msynth->seq_client, &ev, 1, 0);
- /* clear event and reset header */
- memset(&ev, 0, sizeof(ev));
- }
- }
- }
-}
-
-static int dump_midi(struct snd_rawmidi_substream *substream, const char *buf, int count)
-{
- struct snd_rawmidi_runtime *runtime;
- int tmp;
-
- if (snd_BUG_ON(!substream || !buf))
- return -EINVAL;
- runtime = substream->runtime;
- if ((tmp = runtime->avail) < count) {
- if (printk_ratelimit())
- snd_printk(KERN_ERR "MIDI output buffer overrun\n");
- return -ENOMEM;
- }
- if (snd_rawmidi_kernel_write(substream, buf, count) < count)
- return -EINVAL;
- return 0;
-}
-
-static int event_process_midi(struct snd_seq_event *ev, int direct,
- void *private_data, int atomic, int hop)
-{
- struct seq_midisynth *msynth = private_data;
- unsigned char msg[10]; /* buffer for constructing midi messages */
- struct snd_rawmidi_substream *substream;
- int len;
-
- if (snd_BUG_ON(!msynth))
- return -EINVAL;
- substream = msynth->output_rfile.output;
- if (substream == NULL)
- return -ENODEV;
- if (ev->type == SNDRV_SEQ_EVENT_SYSEX) { /* special case, to save space */
- if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE) {
- /* invalid event */
- snd_printd("seq_midi: invalid sysex event flags = 0x%x\n", ev->flags);
- return 0;
- }
- snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)dump_midi, substream);
- snd_midi_event_reset_decode(msynth->parser);
- } else {
- if (msynth->parser == NULL)
- return -EIO;
- len = snd_midi_event_decode(msynth->parser, msg, sizeof(msg), ev);
- if (len < 0)
- return 0;
- if (dump_midi(substream, msg, len) < 0)
- snd_midi_event_reset_decode(msynth->parser);
- }
- return 0;
-}
-
-
-static int snd_seq_midisynth_new(struct seq_midisynth *msynth,
- struct snd_card *card,
- int device,
- int subdevice)
-{
- if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &msynth->parser) < 0)
- return -ENOMEM;
- msynth->card = card;
- msynth->device = device;
- msynth->subdevice = subdevice;
- return 0;
-}
-
-/* open associated midi device for input */
-static int midisynth_subscribe(void *private_data, struct snd_seq_port_subscribe *info)
-{
- int err;
- struct seq_midisynth *msynth = private_data;
- struct snd_rawmidi_runtime *runtime;
- struct snd_rawmidi_params params;
-
- /* open midi port */
- if ((err = snd_rawmidi_kernel_open(msynth->card, msynth->device,
- msynth->subdevice,
- SNDRV_RAWMIDI_LFLG_INPUT,
- &msynth->input_rfile)) < 0) {
- snd_printd("midi input open failed!!!\n");
- return err;
- }
- runtime = msynth->input_rfile.input->runtime;
- memset(&params, 0, sizeof(params));
- params.avail_min = 1;
- params.buffer_size = input_buffer_size;
- if ((err = snd_rawmidi_input_params(msynth->input_rfile.input, &params)) < 0) {
- snd_rawmidi_kernel_release(&msynth->input_rfile);
- return err;
- }
- snd_midi_event_reset_encode(msynth->parser);
- runtime->event = snd_midi_input_event;
- runtime->private_data = msynth;
- snd_rawmidi_kernel_read(msynth->input_rfile.input, NULL, 0);
- return 0;
-}
-
-/* close associated midi device for input */
-static int midisynth_unsubscribe(void *private_data, struct snd_seq_port_subscribe *info)
-{
- int err;
- struct seq_midisynth *msynth = private_data;
-
- if (snd_BUG_ON(!msynth->input_rfile.input))
- return -EINVAL;
- err = snd_rawmidi_kernel_release(&msynth->input_rfile);
- return err;
-}
-
-/* open associated midi device for output */
-static int midisynth_use(void *private_data, struct snd_seq_port_subscribe *info)
-{
- int err;
- struct seq_midisynth *msynth = private_data;
- struct snd_rawmidi_params params;
-
- /* open midi port */
- if ((err = snd_rawmidi_kernel_open(msynth->card, msynth->device,
- msynth->subdevice,
- SNDRV_RAWMIDI_LFLG_OUTPUT,
- &msynth->output_rfile)) < 0) {
- snd_printd("midi output open failed!!!\n");
- return err;
- }
- memset(&params, 0, sizeof(params));
- params.avail_min = 1;
- params.buffer_size = output_buffer_size;
- params.no_active_sensing = 1;
- if ((err = snd_rawmidi_output_params(msynth->output_rfile.output, &params)) < 0) {
- snd_rawmidi_kernel_release(&msynth->output_rfile);
- return err;
- }
- snd_midi_event_reset_decode(msynth->parser);
- return 0;
-}
-
-/* close associated midi device for output */
-static int midisynth_unuse(void *private_data, struct snd_seq_port_subscribe *info)
-{
- struct seq_midisynth *msynth = private_data;
-
- if (snd_BUG_ON(!msynth->output_rfile.output))
- return -EINVAL;
- snd_rawmidi_drain_output(msynth->output_rfile.output);
- return snd_rawmidi_kernel_release(&msynth->output_rfile);
-}
-
-/* delete given midi synth port */
-static void snd_seq_midisynth_delete(struct seq_midisynth *msynth)
-{
- if (msynth == NULL)
- return;
-
- if (msynth->seq_client > 0) {
- /* delete port */
- snd_seq_event_port_detach(msynth->seq_client, msynth->seq_port);
- }
-
- if (msynth->parser)
- snd_midi_event_free(msynth->parser);
-}
-
-/* register new midi synth port */
-static int
-snd_seq_midisynth_register_port(struct snd_seq_device *dev)
-{
- struct seq_midisynth_client *client;
- struct seq_midisynth *msynth, *ms;
- struct snd_seq_port_info *port;
- struct snd_rawmidi_info *info;
- struct snd_rawmidi *rmidi = dev->private_data;
- int newclient = 0;
- unsigned int p, ports;
- struct snd_seq_port_callback pcallbacks;
- struct snd_card *card = dev->card;
- int device = dev->device;
- unsigned int input_count = 0, output_count = 0;
-
- if (snd_BUG_ON(!card || device < 0 || device >= SNDRV_RAWMIDI_DEVICES))
- return -EINVAL;
- info = kmalloc(sizeof(*info), GFP_KERNEL);
- if (! info)
- return -ENOMEM;
- info->device = device;
- info->stream = SNDRV_RAWMIDI_STREAM_OUTPUT;
- info->subdevice = 0;
- if (snd_rawmidi_info_select(card, info) >= 0)
- output_count = info->subdevices_count;
- info->stream = SNDRV_RAWMIDI_STREAM_INPUT;
- if (snd_rawmidi_info_select(card, info) >= 0) {
- input_count = info->subdevices_count;
- }
- ports = output_count;
- if (ports < input_count)
- ports = input_count;
- if (ports == 0) {
- kfree(info);
- return -ENODEV;
- }
- if (ports > (256 / SNDRV_RAWMIDI_DEVICES))
- ports = 256 / SNDRV_RAWMIDI_DEVICES;
-
- mutex_lock(&register_mutex);
- client = synths[card->number];
- if (client == NULL) {
- newclient = 1;
- client = kzalloc(sizeof(*client), GFP_KERNEL);
- if (client == NULL) {
- mutex_unlock(&register_mutex);
- kfree(info);
- return -ENOMEM;
- }
- client->seq_client =
- snd_seq_create_kernel_client(
- card, 0, "%s", card->shortname[0] ?
- (const char *)card->shortname : "External MIDI");
- if (client->seq_client < 0) {
- kfree(client);
- mutex_unlock(&register_mutex);
- kfree(info);
- return -ENOMEM;
- }
- }
-
- msynth = kcalloc(ports, sizeof(struct seq_midisynth), GFP_KERNEL);
- port = kmalloc(sizeof(*port), GFP_KERNEL);
- if (msynth == NULL || port == NULL)
- goto __nomem;
-
- for (p = 0; p < ports; p++) {
- ms = &msynth[p];
-
- if (snd_seq_midisynth_new(ms, card, device, p) < 0)
- goto __nomem;
-
- /* declare port */
- memset(port, 0, sizeof(*port));
- port->addr.client = client->seq_client;
- port->addr.port = device * (256 / SNDRV_RAWMIDI_DEVICES) + p;
- port->flags = SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
- memset(info, 0, sizeof(*info));
- info->device = device;
- if (p < output_count)
- info->stream = SNDRV_RAWMIDI_STREAM_OUTPUT;
- else
- info->stream = SNDRV_RAWMIDI_STREAM_INPUT;
- info->subdevice = p;
- if (snd_rawmidi_info_select(card, info) >= 0)
- strcpy(port->name, info->subname);
- if (! port->name[0]) {
- if (info->name[0]) {
- if (ports > 1)
- snprintf(port->name, sizeof(port->name), "%s-%d", info->name, p);
- else
- snprintf(port->name, sizeof(port->name), "%s", info->name);
- } else {
- /* last resort */
- if (ports > 1)
- sprintf(port->name, "MIDI %d-%d-%d", card->number, device, p);
- else
- sprintf(port->name, "MIDI %d-%d", card->number, device);
- }
- }
- if ((info->flags & SNDRV_RAWMIDI_INFO_OUTPUT) && p < output_count)
- port->capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SYNC_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
- if ((info->flags & SNDRV_RAWMIDI_INFO_INPUT) && p < input_count)
- port->capability |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SYNC_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ;
- if ((port->capability & (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ)) == (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ) &&
- info->flags & SNDRV_RAWMIDI_INFO_DUPLEX)
- port->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX;
- port->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC
- | SNDRV_SEQ_PORT_TYPE_HARDWARE
- | SNDRV_SEQ_PORT_TYPE_PORT;
- port->midi_channels = 16;
- memset(&pcallbacks, 0, sizeof(pcallbacks));
- pcallbacks.owner = THIS_MODULE;
- pcallbacks.private_data = ms;
- pcallbacks.subscribe = midisynth_subscribe;
- pcallbacks.unsubscribe = midisynth_unsubscribe;
- pcallbacks.use = midisynth_use;
- pcallbacks.unuse = midisynth_unuse;
- pcallbacks.event_input = event_process_midi;
- port->kernel = &pcallbacks;
- if (rmidi->ops && rmidi->ops->get_port_info)
- rmidi->ops->get_port_info(rmidi, p, port);
- if (snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_CREATE_PORT, port)<0)
- goto __nomem;
- ms->seq_client = client->seq_client;
- ms->seq_port = port->addr.port;
- }
- client->ports_per_device[device] = ports;
- client->ports[device] = msynth;
- client->num_ports++;
- if (newclient)
- synths[card->number] = client;
- mutex_unlock(&register_mutex);
- kfree(info);
- kfree(port);
- return 0; /* success */
-
- __nomem:
- if (msynth != NULL) {
- for (p = 0; p < ports; p++)
- snd_seq_midisynth_delete(&msynth[p]);
- kfree(msynth);
- }
- if (newclient) {
- snd_seq_delete_kernel_client(client->seq_client);
- kfree(client);
- }
- kfree(info);
- kfree(port);
- mutex_unlock(&register_mutex);
- return -ENOMEM;
-}
-
-/* release midi synth port */
-static int
-snd_seq_midisynth_unregister_port(struct snd_seq_device *dev)
-{
- struct seq_midisynth_client *client;
- struct seq_midisynth *msynth;
- struct snd_card *card = dev->card;
- int device = dev->device, p, ports;
-
- mutex_lock(&register_mutex);
- client = synths[card->number];
- if (client == NULL || client->ports[device] == NULL) {
- mutex_unlock(&register_mutex);
- return -ENODEV;
- }
- ports = client->ports_per_device[device];
- client->ports_per_device[device] = 0;
- msynth = client->ports[device];
- client->ports[device] = NULL;
- for (p = 0; p < ports; p++)
- snd_seq_midisynth_delete(&msynth[p]);
- kfree(msynth);
- client->num_ports--;
- if (client->num_ports <= 0) {
- snd_seq_delete_kernel_client(client->seq_client);
- synths[card->number] = NULL;
- kfree(client);
- }
- mutex_unlock(&register_mutex);
- return 0;
-}
-
-
-static int __init alsa_seq_midi_init(void)
-{
- static struct snd_seq_dev_ops ops = {
- snd_seq_midisynth_register_port,
- snd_seq_midisynth_unregister_port,
- };
- memset(&synths, 0, sizeof(synths));
- snd_seq_autoload_lock();
- snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_MIDISYNTH, &ops, 0);
- snd_seq_autoload_unlock();
- return 0;
-}
-
-static void __exit alsa_seq_midi_exit(void)
-{
- snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_MIDISYNTH);
-}
-
-module_init(alsa_seq_midi_init)
-module_exit(alsa_seq_midi_exit)
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_midi_emul.c b/ANDROID_3.4.5/sound/core/seq/seq_midi_emul.c
deleted file mode 100644
index 6f64471d..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_midi_emul.c
+++ /dev/null
@@ -1,740 +0,0 @@
-/*
- * GM/GS/XG midi module.
- *
- * Copyright (C) 1999 Steve Ratcliffe
- *
- * Based on awe_wave.c by Takashi Iwai
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-/*
- * This module is used to keep track of the current midi state.
- * It can be used for drivers that are required to emulate midi when
- * the hardware doesn't.
- *
- * It was written for a AWE64 driver, but there should be no AWE specific
- * code in here. If there is it should be reported as a bug.
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/seq_kernel.h>
-#include <sound/seq_midi_emul.h>
-#include <sound/initval.h>
-#include <sound/asoundef.h>
-
-MODULE_AUTHOR("Takashi Iwai / Steve Ratcliffe");
-MODULE_DESCRIPTION("Advanced Linux Sound Architecture sequencer MIDI emulation.");
-MODULE_LICENSE("GPL");
-
-/* Prototypes for static functions */
-static void note_off(struct snd_midi_op *ops, void *drv,
- struct snd_midi_channel *chan,
- int note, int vel);
-static void do_control(struct snd_midi_op *ops, void *private,
- struct snd_midi_channel_set *chset,
- struct snd_midi_channel *chan,
- int control, int value);
-static void rpn(struct snd_midi_op *ops, void *drv, struct snd_midi_channel *chan,
- struct snd_midi_channel_set *chset);
-static void nrpn(struct snd_midi_op *ops, void *drv, struct snd_midi_channel *chan,
- struct snd_midi_channel_set *chset);
-static void sysex(struct snd_midi_op *ops, void *private, unsigned char *sysex,
- int len, struct snd_midi_channel_set *chset);
-static void all_sounds_off(struct snd_midi_op *ops, void *private,
- struct snd_midi_channel *chan);
-static void all_notes_off(struct snd_midi_op *ops, void *private,
- struct snd_midi_channel *chan);
-static void snd_midi_reset_controllers(struct snd_midi_channel *chan);
-static void reset_all_channels(struct snd_midi_channel_set *chset);
-
-
-/*
- * Process an event in a driver independent way. This means dealing
- * with RPN, NRPN, SysEx etc that are defined for common midi applications
- * such as GM, GS and XG.
- * There modes that this module will run in are:
- * Generic MIDI - no interpretation at all, it will just save current values
- * of controllers etc.
- * GM - You can use all gm_ prefixed elements of chan. Controls, RPN, NRPN,
- * SysEx will be interpreded as defined in General Midi.
- * GS - You can use all gs_ prefixed elements of chan. Codes for GS will be
- * interpreted.
- * XG - You can use all xg_ prefixed elements of chan. Codes for XG will
- * be interpreted.
- */
-void
-snd_midi_process_event(struct snd_midi_op *ops,
- struct snd_seq_event *ev,
- struct snd_midi_channel_set *chanset)
-{
- struct snd_midi_channel *chan;
- void *drv;
- int dest_channel = 0;
-
- if (ev == NULL || chanset == NULL) {
- snd_printd("ev or chanbase NULL (snd_midi_process_event)\n");
- return;
- }
- if (chanset->channels == NULL)
- return;
-
- if (snd_seq_ev_is_channel_type(ev)) {
- dest_channel = ev->data.note.channel;
- if (dest_channel >= chanset->max_channels) {
- snd_printd("dest channel is %d, max is %d\n",
- dest_channel, chanset->max_channels);
- return;
- }
- }
-
- chan = chanset->channels + dest_channel;
- drv = chanset->private_data;
-
- /* EVENT_NOTE should be processed before queued */
- if (ev->type == SNDRV_SEQ_EVENT_NOTE)
- return;
-
- /* Make sure that we don't have a note on that should really be
- * a note off */
- if (ev->type == SNDRV_SEQ_EVENT_NOTEON && ev->data.note.velocity == 0)
- ev->type = SNDRV_SEQ_EVENT_NOTEOFF;
-
- /* Make sure the note is within array range */
- if (ev->type == SNDRV_SEQ_EVENT_NOTEON ||
- ev->type == SNDRV_SEQ_EVENT_NOTEOFF ||
- ev->type == SNDRV_SEQ_EVENT_KEYPRESS) {
- if (ev->data.note.note >= 128)
- return;
- }
-
- switch (ev->type) {
- case SNDRV_SEQ_EVENT_NOTEON:
- if (chan->note[ev->data.note.note] & SNDRV_MIDI_NOTE_ON) {
- if (ops->note_off)
- ops->note_off(drv, ev->data.note.note, 0, chan);
- }
- chan->note[ev->data.note.note] = SNDRV_MIDI_NOTE_ON;
- if (ops->note_on)
- ops->note_on(drv, ev->data.note.note, ev->data.note.velocity, chan);
- break;
- case SNDRV_SEQ_EVENT_NOTEOFF:
- if (! (chan->note[ev->data.note.note] & SNDRV_MIDI_NOTE_ON))
- break;
- if (ops->note_off)
- note_off(ops, drv, chan, ev->data.note.note, ev->data.note.velocity);
- break;
- case SNDRV_SEQ_EVENT_KEYPRESS:
- if (ops->key_press)
- ops->key_press(drv, ev->data.note.note, ev->data.note.velocity, chan);
- break;
- case SNDRV_SEQ_EVENT_CONTROLLER:
- do_control(ops, drv, chanset, chan,
- ev->data.control.param, ev->data.control.value);
- break;
- case SNDRV_SEQ_EVENT_PGMCHANGE:
- chan->midi_program = ev->data.control.value;
- break;
- case SNDRV_SEQ_EVENT_PITCHBEND:
- chan->midi_pitchbend = ev->data.control.value;
- if (ops->control)
- ops->control(drv, MIDI_CTL_PITCHBEND, chan);
- break;
- case SNDRV_SEQ_EVENT_CHANPRESS:
- chan->midi_pressure = ev->data.control.value;
- if (ops->control)
- ops->control(drv, MIDI_CTL_CHAN_PRESSURE, chan);
- break;
- case SNDRV_SEQ_EVENT_CONTROL14:
- /* Best guess is that this is any of the 14 bit controller values */
- if (ev->data.control.param < 32) {
- /* set low part first */
- chan->control[ev->data.control.param + 32] =
- ev->data.control.value & 0x7f;
- do_control(ops, drv, chanset, chan,
- ev->data.control.param,
- ((ev->data.control.value>>7) & 0x7f));
- } else
- do_control(ops, drv, chanset, chan,
- ev->data.control.param,
- ev->data.control.value);
- break;
- case SNDRV_SEQ_EVENT_NONREGPARAM:
- /* Break it back into its controller values */
- chan->param_type = SNDRV_MIDI_PARAM_TYPE_NONREGISTERED;
- chan->control[MIDI_CTL_MSB_DATA_ENTRY]
- = (ev->data.control.value >> 7) & 0x7f;
- chan->control[MIDI_CTL_LSB_DATA_ENTRY]
- = ev->data.control.value & 0x7f;
- chan->control[MIDI_CTL_NONREG_PARM_NUM_MSB]
- = (ev->data.control.param >> 7) & 0x7f;
- chan->control[MIDI_CTL_NONREG_PARM_NUM_LSB]
- = ev->data.control.param & 0x7f;
- nrpn(ops, drv, chan, chanset);
- break;
- case SNDRV_SEQ_EVENT_REGPARAM:
- /* Break it back into its controller values */
- chan->param_type = SNDRV_MIDI_PARAM_TYPE_REGISTERED;
- chan->control[MIDI_CTL_MSB_DATA_ENTRY]
- = (ev->data.control.value >> 7) & 0x7f;
- chan->control[MIDI_CTL_LSB_DATA_ENTRY]
- = ev->data.control.value & 0x7f;
- chan->control[MIDI_CTL_REGIST_PARM_NUM_MSB]
- = (ev->data.control.param >> 7) & 0x7f;
- chan->control[MIDI_CTL_REGIST_PARM_NUM_LSB]
- = ev->data.control.param & 0x7f;
- rpn(ops, drv, chan, chanset);
- break;
- case SNDRV_SEQ_EVENT_SYSEX:
- if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) == SNDRV_SEQ_EVENT_LENGTH_VARIABLE) {
- unsigned char sysexbuf[64];
- int len;
- len = snd_seq_expand_var_event(ev, sizeof(sysexbuf), sysexbuf, 1, 0);
- if (len > 0)
- sysex(ops, drv, sysexbuf, len, chanset);
- }
- break;
- case SNDRV_SEQ_EVENT_SONGPOS:
- case SNDRV_SEQ_EVENT_SONGSEL:
- case SNDRV_SEQ_EVENT_CLOCK:
- case SNDRV_SEQ_EVENT_START:
- case SNDRV_SEQ_EVENT_CONTINUE:
- case SNDRV_SEQ_EVENT_STOP:
- case SNDRV_SEQ_EVENT_QFRAME:
- case SNDRV_SEQ_EVENT_TEMPO:
- case SNDRV_SEQ_EVENT_TIMESIGN:
- case SNDRV_SEQ_EVENT_KEYSIGN:
- goto not_yet;
- case SNDRV_SEQ_EVENT_SENSING:
- break;
- case SNDRV_SEQ_EVENT_CLIENT_START:
- case SNDRV_SEQ_EVENT_CLIENT_EXIT:
- case SNDRV_SEQ_EVENT_CLIENT_CHANGE:
- case SNDRV_SEQ_EVENT_PORT_START:
- case SNDRV_SEQ_EVENT_PORT_EXIT:
- case SNDRV_SEQ_EVENT_PORT_CHANGE:
- case SNDRV_SEQ_EVENT_ECHO:
- not_yet:
- default:
- /*snd_printd("Unimplemented event %d\n", ev->type);*/
- break;
- }
-}
-
-
-/*
- * release note
- */
-static void
-note_off(struct snd_midi_op *ops, void *drv, struct snd_midi_channel *chan,
- int note, int vel)
-{
- if (chan->gm_hold) {
- /* Hold this note until pedal is turned off */
- chan->note[note] |= SNDRV_MIDI_NOTE_RELEASED;
- } else if (chan->note[note] & SNDRV_MIDI_NOTE_SOSTENUTO) {
- /* Mark this note as release; it will be turned off when sostenuto
- * is turned off */
- chan->note[note] |= SNDRV_MIDI_NOTE_RELEASED;
- } else {
- chan->note[note] = 0;
- if (ops->note_off)
- ops->note_off(drv, note, vel, chan);
- }
-}
-
-/*
- * Do all driver independent operations for this controller and pass
- * events that need to take place immediately to the driver.
- */
-static void
-do_control(struct snd_midi_op *ops, void *drv, struct snd_midi_channel_set *chset,
- struct snd_midi_channel *chan, int control, int value)
-{
- int i;
-
- /* Switches */
- if ((control >=64 && control <=69) || (control >= 80 && control <= 83)) {
- /* These are all switches; either off or on so set to 0 or 127 */
- value = (value >= 64)? 127: 0;
- }
- chan->control[control] = value;
-
- switch (control) {
- case MIDI_CTL_SUSTAIN:
- if (value == 0) {
- /* Sustain has been released, turn off held notes */
- for (i = 0; i < 128; i++) {
- if (chan->note[i] & SNDRV_MIDI_NOTE_RELEASED) {
- chan->note[i] = SNDRV_MIDI_NOTE_OFF;
- if (ops->note_off)
- ops->note_off(drv, i, 0, chan);
- }
- }
- }
- break;
- case MIDI_CTL_PORTAMENTO:
- break;
- case MIDI_CTL_SOSTENUTO:
- if (value) {
- /* Mark each note that is currently held down */
- for (i = 0; i < 128; i++) {
- if (chan->note[i] & SNDRV_MIDI_NOTE_ON)
- chan->note[i] |= SNDRV_MIDI_NOTE_SOSTENUTO;
- }
- } else {
- /* release all notes that were held */
- for (i = 0; i < 128; i++) {
- if (chan->note[i] & SNDRV_MIDI_NOTE_SOSTENUTO) {
- chan->note[i] &= ~SNDRV_MIDI_NOTE_SOSTENUTO;
- if (chan->note[i] & SNDRV_MIDI_NOTE_RELEASED) {
- chan->note[i] = SNDRV_MIDI_NOTE_OFF;
- if (ops->note_off)
- ops->note_off(drv, i, 0, chan);
- }
- }
- }
- }
- break;
- case MIDI_CTL_MSB_DATA_ENTRY:
- chan->control[MIDI_CTL_LSB_DATA_ENTRY] = 0;
- /* go through here */
- case MIDI_CTL_LSB_DATA_ENTRY:
- if (chan->param_type == SNDRV_MIDI_PARAM_TYPE_REGISTERED)
- rpn(ops, drv, chan, chset);
- else
- nrpn(ops, drv, chan, chset);
- break;
- case MIDI_CTL_REGIST_PARM_NUM_LSB:
- case MIDI_CTL_REGIST_PARM_NUM_MSB:
- chan->param_type = SNDRV_MIDI_PARAM_TYPE_REGISTERED;
- break;
- case MIDI_CTL_NONREG_PARM_NUM_LSB:
- case MIDI_CTL_NONREG_PARM_NUM_MSB:
- chan->param_type = SNDRV_MIDI_PARAM_TYPE_NONREGISTERED;
- break;
-
- case MIDI_CTL_ALL_SOUNDS_OFF:
- all_sounds_off(ops, drv, chan);
- break;
-
- case MIDI_CTL_ALL_NOTES_OFF:
- all_notes_off(ops, drv, chan);
- break;
-
- case MIDI_CTL_MSB_BANK:
- if (chset->midi_mode == SNDRV_MIDI_MODE_XG) {
- if (value == 127)
- chan->drum_channel = 1;
- else
- chan->drum_channel = 0;
- }
- break;
- case MIDI_CTL_LSB_BANK:
- break;
-
- case MIDI_CTL_RESET_CONTROLLERS:
- snd_midi_reset_controllers(chan);
- break;
-
- case MIDI_CTL_SOFT_PEDAL:
- case MIDI_CTL_LEGATO_FOOTSWITCH:
- case MIDI_CTL_HOLD2:
- case MIDI_CTL_SC1_SOUND_VARIATION:
- case MIDI_CTL_SC2_TIMBRE:
- case MIDI_CTL_SC3_RELEASE_TIME:
- case MIDI_CTL_SC4_ATTACK_TIME:
- case MIDI_CTL_SC5_BRIGHTNESS:
- case MIDI_CTL_E1_REVERB_DEPTH:
- case MIDI_CTL_E2_TREMOLO_DEPTH:
- case MIDI_CTL_E3_CHORUS_DEPTH:
- case MIDI_CTL_E4_DETUNE_DEPTH:
- case MIDI_CTL_E5_PHASER_DEPTH:
- goto notyet;
- notyet:
- default:
- if (ops->control)
- ops->control(drv, control, chan);
- break;
- }
-}
-
-
-/*
- * initialize the MIDI status
- */
-void
-snd_midi_channel_set_clear(struct snd_midi_channel_set *chset)
-{
- int i;
-
- chset->midi_mode = SNDRV_MIDI_MODE_GM;
- chset->gs_master_volume = 127;
-
- for (i = 0; i < chset->max_channels; i++) {
- struct snd_midi_channel *chan = chset->channels + i;
- memset(chan->note, 0, sizeof(chan->note));
-
- chan->midi_aftertouch = 0;
- chan->midi_pressure = 0;
- chan->midi_program = 0;
- chan->midi_pitchbend = 0;
- snd_midi_reset_controllers(chan);
- chan->gm_rpn_pitch_bend_range = 256; /* 2 semitones */
- chan->gm_rpn_fine_tuning = 0;
- chan->gm_rpn_coarse_tuning = 0;
-
- if (i == 9)
- chan->drum_channel = 1;
- else
- chan->drum_channel = 0;
- }
-}
-
-/*
- * Process a rpn message.
- */
-static void
-rpn(struct snd_midi_op *ops, void *drv, struct snd_midi_channel *chan,
- struct snd_midi_channel_set *chset)
-{
- int type;
- int val;
-
- if (chset->midi_mode != SNDRV_MIDI_MODE_NONE) {
- type = (chan->control[MIDI_CTL_REGIST_PARM_NUM_MSB] << 8) |
- chan->control[MIDI_CTL_REGIST_PARM_NUM_LSB];
- val = (chan->control[MIDI_CTL_MSB_DATA_ENTRY] << 7) |
- chan->control[MIDI_CTL_LSB_DATA_ENTRY];
-
- switch (type) {
- case 0x0000: /* Pitch bend sensitivity */
- /* MSB only / 1 semitone per 128 */
- chan->gm_rpn_pitch_bend_range = val;
- break;
-
- case 0x0001: /* fine tuning: */
- /* MSB/LSB, 8192=center, 100/8192 cent step */
- chan->gm_rpn_fine_tuning = val - 8192;
- break;
-
- case 0x0002: /* coarse tuning */
- /* MSB only / 8192=center, 1 semitone per 128 */
- chan->gm_rpn_coarse_tuning = val - 8192;
- break;
-
- case 0x7F7F: /* "lock-in" RPN */
- /* ignored */
- break;
- }
- }
- /* should call nrpn or rpn callback here.. */
-}
-
-/*
- * Process an nrpn message.
- */
-static void
-nrpn(struct snd_midi_op *ops, void *drv, struct snd_midi_channel *chan,
- struct snd_midi_channel_set *chset)
-{
- /* parse XG NRPNs here if possible */
- if (ops->nrpn)
- ops->nrpn(drv, chan, chset);
-}
-
-
-/*
- * convert channel parameter in GS sysex
- */
-static int
-get_channel(unsigned char cmd)
-{
- int p = cmd & 0x0f;
- if (p == 0)
- p = 9;
- else if (p < 10)
- p--;
- return p;
-}
-
-
-/*
- * Process a sysex message.
- */
-static void
-sysex(struct snd_midi_op *ops, void *private, unsigned char *buf, int len,
- struct snd_midi_channel_set *chset)
-{
- /* GM on */
- static unsigned char gm_on_macro[] = {
- 0x7e,0x7f,0x09,0x01,
- };
- /* XG on */
- static unsigned char xg_on_macro[] = {
- 0x43,0x10,0x4c,0x00,0x00,0x7e,0x00,
- };
- /* GS prefix
- * drum channel: XX=0x1?(channel), YY=0x15, ZZ=on/off
- * reverb mode: XX=0x01, YY=0x30, ZZ=0-7
- * chorus mode: XX=0x01, YY=0x38, ZZ=0-7
- * master vol: XX=0x00, YY=0x04, ZZ=0-127
- */
- static unsigned char gs_pfx_macro[] = {
- 0x41,0x10,0x42,0x12,0x40,/*XX,YY,ZZ*/
- };
-
- int parsed = SNDRV_MIDI_SYSEX_NOT_PARSED;
-
- if (len <= 0 || buf[0] != 0xf0)
- return;
- /* skip first byte */
- buf++;
- len--;
-
- /* GM on */
- if (len >= (int)sizeof(gm_on_macro) &&
- memcmp(buf, gm_on_macro, sizeof(gm_on_macro)) == 0) {
- if (chset->midi_mode != SNDRV_MIDI_MODE_GS &&
- chset->midi_mode != SNDRV_MIDI_MODE_XG) {
- chset->midi_mode = SNDRV_MIDI_MODE_GM;
- reset_all_channels(chset);
- parsed = SNDRV_MIDI_SYSEX_GM_ON;
- }
- }
-
- /* GS macros */
- else if (len >= 8 &&
- memcmp(buf, gs_pfx_macro, sizeof(gs_pfx_macro)) == 0) {
- if (chset->midi_mode != SNDRV_MIDI_MODE_GS &&
- chset->midi_mode != SNDRV_MIDI_MODE_XG)
- chset->midi_mode = SNDRV_MIDI_MODE_GS;
-
- if (buf[5] == 0x00 && buf[6] == 0x7f && buf[7] == 0x00) {
- /* GS reset */
- parsed = SNDRV_MIDI_SYSEX_GS_RESET;
- reset_all_channels(chset);
- }
-
- else if ((buf[5] & 0xf0) == 0x10 && buf[6] == 0x15) {
- /* drum pattern */
- int p = get_channel(buf[5]);
- if (p < chset->max_channels) {
- parsed = SNDRV_MIDI_SYSEX_GS_DRUM_CHANNEL;
- if (buf[7])
- chset->channels[p].drum_channel = 1;
- else
- chset->channels[p].drum_channel = 0;
- }
-
- } else if ((buf[5] & 0xf0) == 0x10 && buf[6] == 0x21) {
- /* program */
- int p = get_channel(buf[5]);
- if (p < chset->max_channels &&
- ! chset->channels[p].drum_channel) {
- parsed = SNDRV_MIDI_SYSEX_GS_DRUM_CHANNEL;
- chset->channels[p].midi_program = buf[7];
- }
-
- } else if (buf[5] == 0x01 && buf[6] == 0x30) {
- /* reverb mode */
- parsed = SNDRV_MIDI_SYSEX_GS_REVERB_MODE;
- chset->gs_reverb_mode = buf[7];
-
- } else if (buf[5] == 0x01 && buf[6] == 0x38) {
- /* chorus mode */
- parsed = SNDRV_MIDI_SYSEX_GS_CHORUS_MODE;
- chset->gs_chorus_mode = buf[7];
-
- } else if (buf[5] == 0x00 && buf[6] == 0x04) {
- /* master volume */
- parsed = SNDRV_MIDI_SYSEX_GS_MASTER_VOLUME;
- chset->gs_master_volume = buf[7];
-
- }
- }
-
- /* XG on */
- else if (len >= (int)sizeof(xg_on_macro) &&
- memcmp(buf, xg_on_macro, sizeof(xg_on_macro)) == 0) {
- int i;
- chset->midi_mode = SNDRV_MIDI_MODE_XG;
- parsed = SNDRV_MIDI_SYSEX_XG_ON;
- /* reset CC#0 for drums */
- for (i = 0; i < chset->max_channels; i++) {
- if (chset->channels[i].drum_channel)
- chset->channels[i].control[MIDI_CTL_MSB_BANK] = 127;
- else
- chset->channels[i].control[MIDI_CTL_MSB_BANK] = 0;
- }
- }
-
- if (ops->sysex)
- ops->sysex(private, buf - 1, len + 1, parsed, chset);
-}
-
-/*
- * all sound off
- */
-static void
-all_sounds_off(struct snd_midi_op *ops, void *drv, struct snd_midi_channel *chan)
-{
- int n;
-
- if (! ops->note_terminate)
- return;
- for (n = 0; n < 128; n++) {
- if (chan->note[n]) {
- ops->note_terminate(drv, n, chan);
- chan->note[n] = 0;
- }
- }
-}
-
-/*
- * all notes off
- */
-static void
-all_notes_off(struct snd_midi_op *ops, void *drv, struct snd_midi_channel *chan)
-{
- int n;
-
- if (! ops->note_off)
- return;
- for (n = 0; n < 128; n++) {
- if (chan->note[n] == SNDRV_MIDI_NOTE_ON)
- note_off(ops, drv, chan, n, 0);
- }
-}
-
-/*
- * Initialise a single midi channel control block.
- */
-static void snd_midi_channel_init(struct snd_midi_channel *p, int n)
-{
- if (p == NULL)
- return;
-
- memset(p, 0, sizeof(struct snd_midi_channel));
- p->private = NULL;
- p->number = n;
-
- snd_midi_reset_controllers(p);
- p->gm_rpn_pitch_bend_range = 256; /* 2 semitones */
- p->gm_rpn_fine_tuning = 0;
- p->gm_rpn_coarse_tuning = 0;
-
- if (n == 9)
- p->drum_channel = 1; /* Default ch 10 as drums */
-}
-
-/*
- * Allocate and initialise a set of midi channel control blocks.
- */
-static struct snd_midi_channel *snd_midi_channel_init_set(int n)
-{
- struct snd_midi_channel *chan;
- int i;
-
- chan = kmalloc(n * sizeof(struct snd_midi_channel), GFP_KERNEL);
- if (chan) {
- for (i = 0; i < n; i++)
- snd_midi_channel_init(chan+i, i);
- }
-
- return chan;
-}
-
-/*
- * reset all midi channels
- */
-static void
-reset_all_channels(struct snd_midi_channel_set *chset)
-{
- int ch;
- for (ch = 0; ch < chset->max_channels; ch++) {
- struct snd_midi_channel *chan = chset->channels + ch;
- snd_midi_reset_controllers(chan);
- chan->gm_rpn_pitch_bend_range = 256; /* 2 semitones */
- chan->gm_rpn_fine_tuning = 0;
- chan->gm_rpn_coarse_tuning = 0;
-
- if (ch == 9)
- chan->drum_channel = 1;
- else
- chan->drum_channel = 0;
- }
-}
-
-
-/*
- * Allocate and initialise a midi channel set.
- */
-struct snd_midi_channel_set *snd_midi_channel_alloc_set(int n)
-{
- struct snd_midi_channel_set *chset;
-
- chset = kmalloc(sizeof(*chset), GFP_KERNEL);
- if (chset) {
- chset->channels = snd_midi_channel_init_set(n);
- chset->private_data = NULL;
- chset->max_channels = n;
- }
- return chset;
-}
-
-/*
- * Reset the midi controllers on a particular channel to default values.
- */
-static void snd_midi_reset_controllers(struct snd_midi_channel *chan)
-{
- memset(chan->control, 0, sizeof(chan->control));
- chan->gm_volume = 127;
- chan->gm_expression = 127;
- chan->gm_pan = 64;
-}
-
-
-/*
- * Free a midi channel set.
- */
-void snd_midi_channel_free_set(struct snd_midi_channel_set *chset)
-{
- if (chset == NULL)
- return;
- kfree(chset->channels);
- kfree(chset);
-}
-
-static int __init alsa_seq_midi_emul_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_seq_midi_emul_exit(void)
-{
-}
-
-module_init(alsa_seq_midi_emul_init)
-module_exit(alsa_seq_midi_emul_exit)
-
-EXPORT_SYMBOL(snd_midi_process_event);
-EXPORT_SYMBOL(snd_midi_channel_set_clear);
-EXPORT_SYMBOL(snd_midi_channel_alloc_set);
-EXPORT_SYMBOL(snd_midi_channel_free_set);
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_midi_event.c b/ANDROID_3.4.5/sound/core/seq/seq_midi_event.c
deleted file mode 100644
index 37db7ba4..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_midi_event.c
+++ /dev/null
@@ -1,550 +0,0 @@
-/*
- * MIDI byte <-> sequencer event coder
- *
- * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>,
- * Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/seq_kernel.h>
-#include <sound/seq_midi_event.h>
-#include <sound/asoundef.h>
-
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>, Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("MIDI byte <-> sequencer event coder");
-MODULE_LICENSE("GPL");
-
-/* event type, index into status_event[] */
-/* from 0 to 6 are normal commands (note off, on, etc.) for 0x9?-0xe? */
-#define ST_INVALID 7
-#define ST_SPECIAL 8
-#define ST_SYSEX ST_SPECIAL
-/* from 8 to 15 are events for 0xf0-0xf7 */
-
-
-/*
- * prototypes
- */
-static void note_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
-static void one_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
-static void pitchbend_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
-static void two_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
-static void one_param_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
-static void songpos_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
-static void note_decode(struct snd_seq_event *ev, unsigned char *buf);
-static void one_param_decode(struct snd_seq_event *ev, unsigned char *buf);
-static void pitchbend_decode(struct snd_seq_event *ev, unsigned char *buf);
-static void two_param_decode(struct snd_seq_event *ev, unsigned char *buf);
-static void songpos_decode(struct snd_seq_event *ev, unsigned char *buf);
-
-/*
- * event list
- */
-static struct status_event_list {
- int event;
- int qlen;
- void (*encode)(struct snd_midi_event *dev, struct snd_seq_event *ev);
- void (*decode)(struct snd_seq_event *ev, unsigned char *buf);
-} status_event[] = {
- /* 0x80 - 0xef */
- {SNDRV_SEQ_EVENT_NOTEOFF, 2, note_event, note_decode},
- {SNDRV_SEQ_EVENT_NOTEON, 2, note_event, note_decode},
- {SNDRV_SEQ_EVENT_KEYPRESS, 2, note_event, note_decode},
- {SNDRV_SEQ_EVENT_CONTROLLER, 2, two_param_ctrl_event, two_param_decode},
- {SNDRV_SEQ_EVENT_PGMCHANGE, 1, one_param_ctrl_event, one_param_decode},
- {SNDRV_SEQ_EVENT_CHANPRESS, 1, one_param_ctrl_event, one_param_decode},
- {SNDRV_SEQ_EVENT_PITCHBEND, 2, pitchbend_ctrl_event, pitchbend_decode},
- /* invalid */
- {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL},
- /* 0xf0 - 0xff */
- {SNDRV_SEQ_EVENT_SYSEX, 1, NULL, NULL}, /* sysex: 0xf0 */
- {SNDRV_SEQ_EVENT_QFRAME, 1, one_param_event, one_param_decode}, /* 0xf1 */
- {SNDRV_SEQ_EVENT_SONGPOS, 2, songpos_event, songpos_decode}, /* 0xf2 */
- {SNDRV_SEQ_EVENT_SONGSEL, 1, one_param_event, one_param_decode}, /* 0xf3 */
- {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf4 */
- {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf5 */
- {SNDRV_SEQ_EVENT_TUNE_REQUEST, 0, NULL, NULL}, /* 0xf6 */
- {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf7 */
- {SNDRV_SEQ_EVENT_CLOCK, 0, NULL, NULL}, /* 0xf8 */
- {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf9 */
- {SNDRV_SEQ_EVENT_START, 0, NULL, NULL}, /* 0xfa */
- {SNDRV_SEQ_EVENT_CONTINUE, 0, NULL, NULL}, /* 0xfb */
- {SNDRV_SEQ_EVENT_STOP, 0, NULL, NULL}, /* 0xfc */
- {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xfd */
- {SNDRV_SEQ_EVENT_SENSING, 0, NULL, NULL}, /* 0xfe */
- {SNDRV_SEQ_EVENT_RESET, 0, NULL, NULL}, /* 0xff */
-};
-
-static int extra_decode_ctrl14(struct snd_midi_event *dev, unsigned char *buf, int len,
- struct snd_seq_event *ev);
-static int extra_decode_xrpn(struct snd_midi_event *dev, unsigned char *buf, int count,
- struct snd_seq_event *ev);
-
-static struct extra_event_list {
- int event;
- int (*decode)(struct snd_midi_event *dev, unsigned char *buf, int len,
- struct snd_seq_event *ev);
-} extra_event[] = {
- {SNDRV_SEQ_EVENT_CONTROL14, extra_decode_ctrl14},
- {SNDRV_SEQ_EVENT_NONREGPARAM, extra_decode_xrpn},
- {SNDRV_SEQ_EVENT_REGPARAM, extra_decode_xrpn},
-};
-
-/*
- * new/delete record
- */
-
-int snd_midi_event_new(int bufsize, struct snd_midi_event **rdev)
-{
- struct snd_midi_event *dev;
-
- *rdev = NULL;
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (dev == NULL)
- return -ENOMEM;
- if (bufsize > 0) {
- dev->buf = kmalloc(bufsize, GFP_KERNEL);
- if (dev->buf == NULL) {
- kfree(dev);
- return -ENOMEM;
- }
- }
- dev->bufsize = bufsize;
- dev->lastcmd = 0xff;
- dev->type = ST_INVALID;
- spin_lock_init(&dev->lock);
- *rdev = dev;
- return 0;
-}
-
-void snd_midi_event_free(struct snd_midi_event *dev)
-{
- if (dev != NULL) {
- kfree(dev->buf);
- kfree(dev);
- }
-}
-
-/*
- * initialize record
- */
-static inline void reset_encode(struct snd_midi_event *dev)
-{
- dev->read = 0;
- dev->qlen = 0;
- dev->type = ST_INVALID;
-}
-
-void snd_midi_event_reset_encode(struct snd_midi_event *dev)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&dev->lock, flags);
- reset_encode(dev);
- spin_unlock_irqrestore(&dev->lock, flags);
-}
-
-void snd_midi_event_reset_decode(struct snd_midi_event *dev)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&dev->lock, flags);
- dev->lastcmd = 0xff;
- spin_unlock_irqrestore(&dev->lock, flags);
-}
-
-#if 0
-void snd_midi_event_init(struct snd_midi_event *dev)
-{
- snd_midi_event_reset_encode(dev);
- snd_midi_event_reset_decode(dev);
-}
-#endif /* 0 */
-
-void snd_midi_event_no_status(struct snd_midi_event *dev, int on)
-{
- dev->nostat = on ? 1 : 0;
-}
-
-/*
- * resize buffer
- */
-#if 0
-int snd_midi_event_resize_buffer(struct snd_midi_event *dev, int bufsize)
-{
- unsigned char *new_buf, *old_buf;
- unsigned long flags;
-
- if (bufsize == dev->bufsize)
- return 0;
- new_buf = kmalloc(bufsize, GFP_KERNEL);
- if (new_buf == NULL)
- return -ENOMEM;
- spin_lock_irqsave(&dev->lock, flags);
- old_buf = dev->buf;
- dev->buf = new_buf;
- dev->bufsize = bufsize;
- reset_encode(dev);
- spin_unlock_irqrestore(&dev->lock, flags);
- kfree(old_buf);
- return 0;
-}
-#endif /* 0 */
-
-/*
- * read bytes and encode to sequencer event if finished
- * return the size of encoded bytes
- */
-long snd_midi_event_encode(struct snd_midi_event *dev, unsigned char *buf, long count,
- struct snd_seq_event *ev)
-{
- long result = 0;
- int rc;
-
- ev->type = SNDRV_SEQ_EVENT_NONE;
-
- while (count-- > 0) {
- rc = snd_midi_event_encode_byte(dev, *buf++, ev);
- result++;
- if (rc < 0)
- return rc;
- else if (rc > 0)
- return result;
- }
-
- return result;
-}
-
-/*
- * read one byte and encode to sequencer event:
- * return 1 if MIDI bytes are encoded to an event
- * 0 data is not finished
- * negative for error
- */
-int snd_midi_event_encode_byte(struct snd_midi_event *dev, int c,
- struct snd_seq_event *ev)
-{
- int rc = 0;
- unsigned long flags;
-
- c &= 0xff;
-
- if (c >= MIDI_CMD_COMMON_CLOCK) {
- /* real-time event */
- ev->type = status_event[ST_SPECIAL + c - 0xf0].event;
- ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
- ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED;
- return ev->type != SNDRV_SEQ_EVENT_NONE;
- }
-
- spin_lock_irqsave(&dev->lock, flags);
- if ((c & 0x80) &&
- (c != MIDI_CMD_COMMON_SYSEX_END || dev->type != ST_SYSEX)) {
- /* new command */
- dev->buf[0] = c;
- if ((c & 0xf0) == 0xf0) /* system messages */
- dev->type = (c & 0x0f) + ST_SPECIAL;
- else
- dev->type = (c >> 4) & 0x07;
- dev->read = 1;
- dev->qlen = status_event[dev->type].qlen;
- } else {
- if (dev->qlen > 0) {
- /* rest of command */
- dev->buf[dev->read++] = c;
- if (dev->type != ST_SYSEX)
- dev->qlen--;
- } else {
- /* running status */
- dev->buf[1] = c;
- dev->qlen = status_event[dev->type].qlen - 1;
- dev->read = 2;
- }
- }
- if (dev->qlen == 0) {
- ev->type = status_event[dev->type].event;
- ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
- ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED;
- if (status_event[dev->type].encode) /* set data values */
- status_event[dev->type].encode(dev, ev);
- if (dev->type >= ST_SPECIAL)
- dev->type = ST_INVALID;
- rc = 1;
- } else if (dev->type == ST_SYSEX) {
- if (c == MIDI_CMD_COMMON_SYSEX_END ||
- dev->read >= dev->bufsize) {
- ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
- ev->flags |= SNDRV_SEQ_EVENT_LENGTH_VARIABLE;
- ev->type = SNDRV_SEQ_EVENT_SYSEX;
- ev->data.ext.len = dev->read;
- ev->data.ext.ptr = dev->buf;
- if (c != MIDI_CMD_COMMON_SYSEX_END)
- dev->read = 0; /* continue to parse */
- else
- reset_encode(dev); /* all parsed */
- rc = 1;
- }
- }
-
- spin_unlock_irqrestore(&dev->lock, flags);
- return rc;
-}
-
-/* encode note event */
-static void note_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
-{
- ev->data.note.channel = dev->buf[0] & 0x0f;
- ev->data.note.note = dev->buf[1];
- ev->data.note.velocity = dev->buf[2];
-}
-
-/* encode one parameter controls */
-static void one_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
-{
- ev->data.control.channel = dev->buf[0] & 0x0f;
- ev->data.control.value = dev->buf[1];
-}
-
-/* encode pitch wheel change */
-static void pitchbend_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
-{
- ev->data.control.channel = dev->buf[0] & 0x0f;
- ev->data.control.value = (int)dev->buf[2] * 128 + (int)dev->buf[1] - 8192;
-}
-
-/* encode midi control change */
-static void two_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
-{
- ev->data.control.channel = dev->buf[0] & 0x0f;
- ev->data.control.param = dev->buf[1];
- ev->data.control.value = dev->buf[2];
-}
-
-/* encode one parameter value*/
-static void one_param_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
-{
- ev->data.control.value = dev->buf[1];
-}
-
-/* encode song position */
-static void songpos_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
-{
- ev->data.control.value = (int)dev->buf[2] * 128 + (int)dev->buf[1];
-}
-
-/*
- * decode from a sequencer event to midi bytes
- * return the size of decoded midi events
- */
-long snd_midi_event_decode(struct snd_midi_event *dev, unsigned char *buf, long count,
- struct snd_seq_event *ev)
-{
- unsigned int cmd, type;
-
- if (ev->type == SNDRV_SEQ_EVENT_NONE)
- return -ENOENT;
-
- for (type = 0; type < ARRAY_SIZE(status_event); type++) {
- if (ev->type == status_event[type].event)
- goto __found;
- }
- for (type = 0; type < ARRAY_SIZE(extra_event); type++) {
- if (ev->type == extra_event[type].event)
- return extra_event[type].decode(dev, buf, count, ev);
- }
- return -ENOENT;
-
- __found:
- if (type >= ST_SPECIAL)
- cmd = 0xf0 + (type - ST_SPECIAL);
- else
- /* data.note.channel and data.control.channel is identical */
- cmd = 0x80 | (type << 4) | (ev->data.note.channel & 0x0f);
-
-
- if (cmd == MIDI_CMD_COMMON_SYSEX) {
- snd_midi_event_reset_decode(dev);
- return snd_seq_expand_var_event(ev, count, buf, 1, 0);
- } else {
- int qlen;
- unsigned char xbuf[4];
- unsigned long flags;
-
- spin_lock_irqsave(&dev->lock, flags);
- if ((cmd & 0xf0) == 0xf0 || dev->lastcmd != cmd || dev->nostat) {
- dev->lastcmd = cmd;
- spin_unlock_irqrestore(&dev->lock, flags);
- xbuf[0] = cmd;
- if (status_event[type].decode)
- status_event[type].decode(ev, xbuf + 1);
- qlen = status_event[type].qlen + 1;
- } else {
- spin_unlock_irqrestore(&dev->lock, flags);
- if (status_event[type].decode)
- status_event[type].decode(ev, xbuf + 0);
- qlen = status_event[type].qlen;
- }
- if (count < qlen)
- return -ENOMEM;
- memcpy(buf, xbuf, qlen);
- return qlen;
- }
-}
-
-
-/* decode note event */
-static void note_decode(struct snd_seq_event *ev, unsigned char *buf)
-{
- buf[0] = ev->data.note.note & 0x7f;
- buf[1] = ev->data.note.velocity & 0x7f;
-}
-
-/* decode one parameter controls */
-static void one_param_decode(struct snd_seq_event *ev, unsigned char *buf)
-{
- buf[0] = ev->data.control.value & 0x7f;
-}
-
-/* decode pitch wheel change */
-static void pitchbend_decode(struct snd_seq_event *ev, unsigned char *buf)
-{
- int value = ev->data.control.value + 8192;
- buf[0] = value & 0x7f;
- buf[1] = (value >> 7) & 0x7f;
-}
-
-/* decode midi control change */
-static void two_param_decode(struct snd_seq_event *ev, unsigned char *buf)
-{
- buf[0] = ev->data.control.param & 0x7f;
- buf[1] = ev->data.control.value & 0x7f;
-}
-
-/* decode song position */
-static void songpos_decode(struct snd_seq_event *ev, unsigned char *buf)
-{
- buf[0] = ev->data.control.value & 0x7f;
- buf[1] = (ev->data.control.value >> 7) & 0x7f;
-}
-
-/* decode 14bit control */
-static int extra_decode_ctrl14(struct snd_midi_event *dev, unsigned char *buf,
- int count, struct snd_seq_event *ev)
-{
- unsigned char cmd;
- int idx = 0;
-
- cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f);
- if (ev->data.control.param < 0x20) {
- if (count < 4)
- return -ENOMEM;
- if (dev->nostat && count < 6)
- return -ENOMEM;
- if (cmd != dev->lastcmd || dev->nostat) {
- if (count < 5)
- return -ENOMEM;
- buf[idx++] = dev->lastcmd = cmd;
- }
- buf[idx++] = ev->data.control.param;
- buf[idx++] = (ev->data.control.value >> 7) & 0x7f;
- if (dev->nostat)
- buf[idx++] = cmd;
- buf[idx++] = ev->data.control.param + 0x20;
- buf[idx++] = ev->data.control.value & 0x7f;
- } else {
- if (count < 2)
- return -ENOMEM;
- if (cmd != dev->lastcmd || dev->nostat) {
- if (count < 3)
- return -ENOMEM;
- buf[idx++] = dev->lastcmd = cmd;
- }
- buf[idx++] = ev->data.control.param & 0x7f;
- buf[idx++] = ev->data.control.value & 0x7f;
- }
- return idx;
-}
-
-/* decode reg/nonreg param */
-static int extra_decode_xrpn(struct snd_midi_event *dev, unsigned char *buf,
- int count, struct snd_seq_event *ev)
-{
- unsigned char cmd;
- char *cbytes;
- static char cbytes_nrpn[4] = { MIDI_CTL_NONREG_PARM_NUM_MSB,
- MIDI_CTL_NONREG_PARM_NUM_LSB,
- MIDI_CTL_MSB_DATA_ENTRY,
- MIDI_CTL_LSB_DATA_ENTRY };
- static char cbytes_rpn[4] = { MIDI_CTL_REGIST_PARM_NUM_MSB,
- MIDI_CTL_REGIST_PARM_NUM_LSB,
- MIDI_CTL_MSB_DATA_ENTRY,
- MIDI_CTL_LSB_DATA_ENTRY };
- unsigned char bytes[4];
- int idx = 0, i;
-
- if (count < 8)
- return -ENOMEM;
- if (dev->nostat && count < 12)
- return -ENOMEM;
- cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f);
- bytes[0] = (ev->data.control.param & 0x3f80) >> 7;
- bytes[1] = ev->data.control.param & 0x007f;
- bytes[2] = (ev->data.control.value & 0x3f80) >> 7;
- bytes[3] = ev->data.control.value & 0x007f;
- if (cmd != dev->lastcmd && !dev->nostat) {
- if (count < 9)
- return -ENOMEM;
- buf[idx++] = dev->lastcmd = cmd;
- }
- cbytes = ev->type == SNDRV_SEQ_EVENT_NONREGPARAM ? cbytes_nrpn : cbytes_rpn;
- for (i = 0; i < 4; i++) {
- if (dev->nostat)
- buf[idx++] = dev->lastcmd = cmd;
- buf[idx++] = cbytes[i];
- buf[idx++] = bytes[i];
- }
- return idx;
-}
-
-/*
- * exports
- */
-
-EXPORT_SYMBOL(snd_midi_event_new);
-EXPORT_SYMBOL(snd_midi_event_free);
-EXPORT_SYMBOL(snd_midi_event_reset_encode);
-EXPORT_SYMBOL(snd_midi_event_reset_decode);
-EXPORT_SYMBOL(snd_midi_event_no_status);
-EXPORT_SYMBOL(snd_midi_event_encode);
-EXPORT_SYMBOL(snd_midi_event_encode_byte);
-EXPORT_SYMBOL(snd_midi_event_decode);
-
-static int __init alsa_seq_midi_event_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_seq_midi_event_exit(void)
-{
-}
-
-module_init(alsa_seq_midi_event_init)
-module_exit(alsa_seq_midi_event_exit)
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_ports.c b/ANDROID_3.4.5/sound/core/seq/seq_ports.c
deleted file mode 100644
index 9516e5ce..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_ports.c
+++ /dev/null
@@ -1,685 +0,0 @@
-/*
- * ALSA sequencer Ports
- * Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl>
- * Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <sound/core.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include "seq_system.h"
-#include "seq_ports.h"
-#include "seq_clientmgr.h"
-
-/*
-
- registration of client ports
-
- */
-
-
-/*
-
-NOTE: the current implementation of the port structure as a linked list is
-not optimal for clients that have many ports. For sending messages to all
-subscribers of a port we first need to find the address of the port
-structure, which means we have to traverse the list. A direct access table
-(array) would be better, but big preallocated arrays waste memory.
-
-Possible actions:
-
-1) leave it this way, a client does normaly does not have more than a few
-ports
-
-2) replace the linked list of ports by a array of pointers which is
-dynamicly kmalloced. When a port is added or deleted we can simply allocate
-a new array, copy the corresponding pointers, and delete the old one. We
-then only need a pointer to this array, and an integer that tells us how
-much elements are in array.
-
-*/
-
-/* return pointer to port structure - port is locked if found */
-struct snd_seq_client_port *snd_seq_port_use_ptr(struct snd_seq_client *client,
- int num)
-{
- struct snd_seq_client_port *port;
-
- if (client == NULL)
- return NULL;
- read_lock(&client->ports_lock);
- list_for_each_entry(port, &client->ports_list_head, list) {
- if (port->addr.port == num) {
- if (port->closing)
- break; /* deleting now */
- snd_use_lock_use(&port->use_lock);
- read_unlock(&client->ports_lock);
- return port;
- }
- }
- read_unlock(&client->ports_lock);
- return NULL; /* not found */
-}
-
-
-/* search for the next port - port is locked if found */
-struct snd_seq_client_port *snd_seq_port_query_nearest(struct snd_seq_client *client,
- struct snd_seq_port_info *pinfo)
-{
- int num;
- struct snd_seq_client_port *port, *found;
-
- num = pinfo->addr.port;
- found = NULL;
- read_lock(&client->ports_lock);
- list_for_each_entry(port, &client->ports_list_head, list) {
- if (port->addr.port < num)
- continue;
- if (port->addr.port == num) {
- found = port;
- break;
- }
- if (found == NULL || port->addr.port < found->addr.port)
- found = port;
- }
- if (found) {
- if (found->closing)
- found = NULL;
- else
- snd_use_lock_use(&found->use_lock);
- }
- read_unlock(&client->ports_lock);
- return found;
-}
-
-
-/* initialize snd_seq_port_subs_info */
-static void port_subs_info_init(struct snd_seq_port_subs_info *grp)
-{
- INIT_LIST_HEAD(&grp->list_head);
- grp->count = 0;
- grp->exclusive = 0;
- rwlock_init(&grp->list_lock);
- init_rwsem(&grp->list_mutex);
- grp->open = NULL;
- grp->close = NULL;
-}
-
-
-/* create a port, port number is returned (-1 on failure) */
-struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
- int port)
-{
- unsigned long flags;
- struct snd_seq_client_port *new_port, *p;
- int num = -1;
-
- /* sanity check */
- if (snd_BUG_ON(!client))
- return NULL;
-
- if (client->num_ports >= SNDRV_SEQ_MAX_PORTS - 1) {
- snd_printk(KERN_WARNING "too many ports for client %d\n", client->number);
- return NULL;
- }
-
- /* create a new port */
- new_port = kzalloc(sizeof(*new_port), GFP_KERNEL);
- if (! new_port) {
- snd_printd("malloc failed for registering client port\n");
- return NULL; /* failure, out of memory */
- }
- /* init port data */
- new_port->addr.client = client->number;
- new_port->addr.port = -1;
- new_port->owner = THIS_MODULE;
- sprintf(new_port->name, "port-%d", num);
- snd_use_lock_init(&new_port->use_lock);
- port_subs_info_init(&new_port->c_src);
- port_subs_info_init(&new_port->c_dest);
-
- num = port >= 0 ? port : 0;
- mutex_lock(&client->ports_mutex);
- write_lock_irqsave(&client->ports_lock, flags);
- list_for_each_entry(p, &client->ports_list_head, list) {
- if (p->addr.port > num)
- break;
- if (port < 0) /* auto-probe mode */
- num = p->addr.port + 1;
- }
- /* insert the new port */
- list_add_tail(&new_port->list, &p->list);
- client->num_ports++;
- new_port->addr.port = num; /* store the port number in the port */
- write_unlock_irqrestore(&client->ports_lock, flags);
- mutex_unlock(&client->ports_mutex);
- sprintf(new_port->name, "port-%d", num);
-
- return new_port;
-}
-
-/* */
-enum group_type {
- SRC_LIST, DEST_LIST
-};
-
-static int subscribe_port(struct snd_seq_client *client,
- struct snd_seq_client_port *port,
- struct snd_seq_port_subs_info *grp,
- struct snd_seq_port_subscribe *info, int send_ack);
-static int unsubscribe_port(struct snd_seq_client *client,
- struct snd_seq_client_port *port,
- struct snd_seq_port_subs_info *grp,
- struct snd_seq_port_subscribe *info, int send_ack);
-
-
-static struct snd_seq_client_port *get_client_port(struct snd_seq_addr *addr,
- struct snd_seq_client **cp)
-{
- struct snd_seq_client_port *p;
- *cp = snd_seq_client_use_ptr(addr->client);
- if (*cp) {
- p = snd_seq_port_use_ptr(*cp, addr->port);
- if (! p) {
- snd_seq_client_unlock(*cp);
- *cp = NULL;
- }
- return p;
- }
- return NULL;
-}
-
-/*
- * remove all subscribers on the list
- * this is called from port_delete, for each src and dest list.
- */
-static void clear_subscriber_list(struct snd_seq_client *client,
- struct snd_seq_client_port *port,
- struct snd_seq_port_subs_info *grp,
- int grptype)
-{
- struct list_head *p, *n;
-
- list_for_each_safe(p, n, &grp->list_head) {
- struct snd_seq_subscribers *subs;
- struct snd_seq_client *c;
- struct snd_seq_client_port *aport;
-
- if (grptype == SRC_LIST) {
- subs = list_entry(p, struct snd_seq_subscribers, src_list);
- aport = get_client_port(&subs->info.dest, &c);
- } else {
- subs = list_entry(p, struct snd_seq_subscribers, dest_list);
- aport = get_client_port(&subs->info.sender, &c);
- }
- list_del(p);
- unsubscribe_port(client, port, grp, &subs->info, 0);
- if (!aport) {
- /* looks like the connected port is being deleted.
- * we decrease the counter, and when both ports are deleted
- * remove the subscriber info
- */
- if (atomic_dec_and_test(&subs->ref_count))
- kfree(subs);
- } else {
- /* ok we got the connected port */
- struct snd_seq_port_subs_info *agrp;
- agrp = (grptype == SRC_LIST) ? &aport->c_dest : &aport->c_src;
- down_write(&agrp->list_mutex);
- if (grptype == SRC_LIST)
- list_del(&subs->dest_list);
- else
- list_del(&subs->src_list);
- up_write(&agrp->list_mutex);
- unsubscribe_port(c, aport, agrp, &subs->info, 1);
- kfree(subs);
- snd_seq_port_unlock(aport);
- snd_seq_client_unlock(c);
- }
- }
-}
-
-/* delete port data */
-static int port_delete(struct snd_seq_client *client,
- struct snd_seq_client_port *port)
-{
- /* set closing flag and wait for all port access are gone */
- port->closing = 1;
- snd_use_lock_sync(&port->use_lock);
-
- /* clear subscribers info */
- clear_subscriber_list(client, port, &port->c_src, SRC_LIST);
- clear_subscriber_list(client, port, &port->c_dest, DEST_LIST);
-
- if (port->private_free)
- port->private_free(port->private_data);
-
- snd_BUG_ON(port->c_src.count != 0);
- snd_BUG_ON(port->c_dest.count != 0);
-
- kfree(port);
- return 0;
-}
-
-
-/* delete a port with the given port id */
-int snd_seq_delete_port(struct snd_seq_client *client, int port)
-{
- unsigned long flags;
- struct snd_seq_client_port *found = NULL, *p;
-
- mutex_lock(&client->ports_mutex);
- write_lock_irqsave(&client->ports_lock, flags);
- list_for_each_entry(p, &client->ports_list_head, list) {
- if (p->addr.port == port) {
- /* ok found. delete from the list at first */
- list_del(&p->list);
- client->num_ports--;
- found = p;
- break;
- }
- }
- write_unlock_irqrestore(&client->ports_lock, flags);
- mutex_unlock(&client->ports_mutex);
- if (found)
- return port_delete(client, found);
- else
- return -ENOENT;
-}
-
-/* delete the all ports belonging to the given client */
-int snd_seq_delete_all_ports(struct snd_seq_client *client)
-{
- unsigned long flags;
- struct list_head deleted_list;
- struct snd_seq_client_port *port, *tmp;
-
- /* move the port list to deleted_list, and
- * clear the port list in the client data.
- */
- mutex_lock(&client->ports_mutex);
- write_lock_irqsave(&client->ports_lock, flags);
- if (! list_empty(&client->ports_list_head)) {
- list_add(&deleted_list, &client->ports_list_head);
- list_del_init(&client->ports_list_head);
- } else {
- INIT_LIST_HEAD(&deleted_list);
- }
- client->num_ports = 0;
- write_unlock_irqrestore(&client->ports_lock, flags);
-
- /* remove each port in deleted_list */
- list_for_each_entry_safe(port, tmp, &deleted_list, list) {
- list_del(&port->list);
- snd_seq_system_client_ev_port_exit(port->addr.client, port->addr.port);
- port_delete(client, port);
- }
- mutex_unlock(&client->ports_mutex);
- return 0;
-}
-
-/* set port info fields */
-int snd_seq_set_port_info(struct snd_seq_client_port * port,
- struct snd_seq_port_info * info)
-{
- if (snd_BUG_ON(!port || !info))
- return -EINVAL;
-
- /* set port name */
- if (info->name[0])
- strlcpy(port->name, info->name, sizeof(port->name));
-
- /* set capabilities */
- port->capability = info->capability;
-
- /* get port type */
- port->type = info->type;
-
- /* information about supported channels/voices */
- port->midi_channels = info->midi_channels;
- port->midi_voices = info->midi_voices;
- port->synth_voices = info->synth_voices;
-
- /* timestamping */
- port->timestamping = (info->flags & SNDRV_SEQ_PORT_FLG_TIMESTAMP) ? 1 : 0;
- port->time_real = (info->flags & SNDRV_SEQ_PORT_FLG_TIME_REAL) ? 1 : 0;
- port->time_queue = info->time_queue;
-
- return 0;
-}
-
-/* get port info fields */
-int snd_seq_get_port_info(struct snd_seq_client_port * port,
- struct snd_seq_port_info * info)
-{
- if (snd_BUG_ON(!port || !info))
- return -EINVAL;
-
- /* get port name */
- strlcpy(info->name, port->name, sizeof(info->name));
-
- /* get capabilities */
- info->capability = port->capability;
-
- /* get port type */
- info->type = port->type;
-
- /* information about supported channels/voices */
- info->midi_channels = port->midi_channels;
- info->midi_voices = port->midi_voices;
- info->synth_voices = port->synth_voices;
-
- /* get subscriber counts */
- info->read_use = port->c_src.count;
- info->write_use = port->c_dest.count;
-
- /* timestamping */
- info->flags = 0;
- if (port->timestamping) {
- info->flags |= SNDRV_SEQ_PORT_FLG_TIMESTAMP;
- if (port->time_real)
- info->flags |= SNDRV_SEQ_PORT_FLG_TIME_REAL;
- info->time_queue = port->time_queue;
- }
-
- return 0;
-}
-
-
-
-/*
- * call callback functions (if any):
- * the callbacks are invoked only when the first (for connection) or
- * the last subscription (for disconnection) is done. Second or later
- * subscription results in increment of counter, but no callback is
- * invoked.
- * This feature is useful if these callbacks are associated with
- * initialization or termination of devices (see seq_midi.c).
- *
- * If callback_all option is set, the callback function is invoked
- * at each connection/disconnection.
- */
-
-static int subscribe_port(struct snd_seq_client *client,
- struct snd_seq_client_port *port,
- struct snd_seq_port_subs_info *grp,
- struct snd_seq_port_subscribe *info,
- int send_ack)
-{
- int err = 0;
-
- if (!try_module_get(port->owner))
- return -EFAULT;
- grp->count++;
- if (grp->open && (port->callback_all || grp->count == 1)) {
- err = grp->open(port->private_data, info);
- if (err < 0) {
- module_put(port->owner);
- grp->count--;
- }
- }
- if (err >= 0 && send_ack && client->type == USER_CLIENT)
- snd_seq_client_notify_subscription(port->addr.client, port->addr.port,
- info, SNDRV_SEQ_EVENT_PORT_SUBSCRIBED);
-
- return err;
-}
-
-static int unsubscribe_port(struct snd_seq_client *client,
- struct snd_seq_client_port *port,
- struct snd_seq_port_subs_info *grp,
- struct snd_seq_port_subscribe *info,
- int send_ack)
-{
- int err = 0;
-
- if (! grp->count)
- return -EINVAL;
- grp->count--;
- if (grp->close && (port->callback_all || grp->count == 0))
- err = grp->close(port->private_data, info);
- if (send_ack && client->type == USER_CLIENT)
- snd_seq_client_notify_subscription(port->addr.client, port->addr.port,
- info, SNDRV_SEQ_EVENT_PORT_UNSUBSCRIBED);
- module_put(port->owner);
- return err;
-}
-
-
-
-/* check if both addresses are identical */
-static inline int addr_match(struct snd_seq_addr *r, struct snd_seq_addr *s)
-{
- return (r->client == s->client) && (r->port == s->port);
-}
-
-/* check the two subscribe info match */
-/* if flags is zero, checks only sender and destination addresses */
-static int match_subs_info(struct snd_seq_port_subscribe *r,
- struct snd_seq_port_subscribe *s)
-{
- if (addr_match(&r->sender, &s->sender) &&
- addr_match(&r->dest, &s->dest)) {
- if (r->flags && r->flags == s->flags)
- return r->queue == s->queue;
- else if (! r->flags)
- return 1;
- }
- return 0;
-}
-
-
-/* connect two ports */
-int snd_seq_port_connect(struct snd_seq_client *connector,
- struct snd_seq_client *src_client,
- struct snd_seq_client_port *src_port,
- struct snd_seq_client *dest_client,
- struct snd_seq_client_port *dest_port,
- struct snd_seq_port_subscribe *info)
-{
- struct snd_seq_port_subs_info *src = &src_port->c_src;
- struct snd_seq_port_subs_info *dest = &dest_port->c_dest;
- struct snd_seq_subscribers *subs, *s;
- int err, src_called = 0;
- unsigned long flags;
- int exclusive;
-
- subs = kzalloc(sizeof(*subs), GFP_KERNEL);
- if (! subs)
- return -ENOMEM;
-
- subs->info = *info;
- atomic_set(&subs->ref_count, 2);
-
- down_write(&src->list_mutex);
- down_write_nested(&dest->list_mutex, SINGLE_DEPTH_NESTING);
-
- exclusive = info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE ? 1 : 0;
- err = -EBUSY;
- if (exclusive) {
- if (! list_empty(&src->list_head) || ! list_empty(&dest->list_head))
- goto __error;
- } else {
- if (src->exclusive || dest->exclusive)
- goto __error;
- /* check whether already exists */
- list_for_each_entry(s, &src->list_head, src_list) {
- if (match_subs_info(info, &s->info))
- goto __error;
- }
- list_for_each_entry(s, &dest->list_head, dest_list) {
- if (match_subs_info(info, &s->info))
- goto __error;
- }
- }
-
- if ((err = subscribe_port(src_client, src_port, src, info,
- connector->number != src_client->number)) < 0)
- goto __error;
- src_called = 1;
-
- if ((err = subscribe_port(dest_client, dest_port, dest, info,
- connector->number != dest_client->number)) < 0)
- goto __error;
-
- /* add to list */
- write_lock_irqsave(&src->list_lock, flags);
- // write_lock(&dest->list_lock); // no other lock yet
- list_add_tail(&subs->src_list, &src->list_head);
- list_add_tail(&subs->dest_list, &dest->list_head);
- // write_unlock(&dest->list_lock); // no other lock yet
- write_unlock_irqrestore(&src->list_lock, flags);
-
- src->exclusive = dest->exclusive = exclusive;
-
- up_write(&dest->list_mutex);
- up_write(&src->list_mutex);
- return 0;
-
- __error:
- if (src_called)
- unsubscribe_port(src_client, src_port, src, info,
- connector->number != src_client->number);
- kfree(subs);
- up_write(&dest->list_mutex);
- up_write(&src->list_mutex);
- return err;
-}
-
-
-/* remove the connection */
-int snd_seq_port_disconnect(struct snd_seq_client *connector,
- struct snd_seq_client *src_client,
- struct snd_seq_client_port *src_port,
- struct snd_seq_client *dest_client,
- struct snd_seq_client_port *dest_port,
- struct snd_seq_port_subscribe *info)
-{
- struct snd_seq_port_subs_info *src = &src_port->c_src;
- struct snd_seq_port_subs_info *dest = &dest_port->c_dest;
- struct snd_seq_subscribers *subs;
- int err = -ENOENT;
- unsigned long flags;
-
- down_write(&src->list_mutex);
- down_write_nested(&dest->list_mutex, SINGLE_DEPTH_NESTING);
-
- /* look for the connection */
- list_for_each_entry(subs, &src->list_head, src_list) {
- if (match_subs_info(info, &subs->info)) {
- write_lock_irqsave(&src->list_lock, flags);
- // write_lock(&dest->list_lock); // no lock yet
- list_del(&subs->src_list);
- list_del(&subs->dest_list);
- // write_unlock(&dest->list_lock);
- write_unlock_irqrestore(&src->list_lock, flags);
- src->exclusive = dest->exclusive = 0;
- unsubscribe_port(src_client, src_port, src, info,
- connector->number != src_client->number);
- unsubscribe_port(dest_client, dest_port, dest, info,
- connector->number != dest_client->number);
- kfree(subs);
- err = 0;
- break;
- }
- }
-
- up_write(&dest->list_mutex);
- up_write(&src->list_mutex);
- return err;
-}
-
-
-/* get matched subscriber */
-struct snd_seq_subscribers *snd_seq_port_get_subscription(struct snd_seq_port_subs_info *src_grp,
- struct snd_seq_addr *dest_addr)
-{
- struct snd_seq_subscribers *s, *found = NULL;
-
- down_read(&src_grp->list_mutex);
- list_for_each_entry(s, &src_grp->list_head, src_list) {
- if (addr_match(dest_addr, &s->info.dest)) {
- found = s;
- break;
- }
- }
- up_read(&src_grp->list_mutex);
- return found;
-}
-
-/*
- * Attach a device driver that wants to receive events from the
- * sequencer. Returns the new port number on success.
- * A driver that wants to receive the events converted to midi, will
- * use snd_seq_midisynth_register_port().
- */
-/* exported */
-int snd_seq_event_port_attach(int client,
- struct snd_seq_port_callback *pcbp,
- int cap, int type, int midi_channels,
- int midi_voices, char *portname)
-{
- struct snd_seq_port_info portinfo;
- int ret;
-
- /* Set up the port */
- memset(&portinfo, 0, sizeof(portinfo));
- portinfo.addr.client = client;
- strlcpy(portinfo.name, portname ? portname : "Unamed port",
- sizeof(portinfo.name));
-
- portinfo.capability = cap;
- portinfo.type = type;
- portinfo.kernel = pcbp;
- portinfo.midi_channels = midi_channels;
- portinfo.midi_voices = midi_voices;
-
- /* Create it */
- ret = snd_seq_kernel_client_ctl(client,
- SNDRV_SEQ_IOCTL_CREATE_PORT,
- &portinfo);
-
- if (ret >= 0)
- ret = portinfo.addr.port;
-
- return ret;
-}
-
-EXPORT_SYMBOL(snd_seq_event_port_attach);
-
-/*
- * Detach the driver from a port.
- */
-/* exported */
-int snd_seq_event_port_detach(int client, int port)
-{
- struct snd_seq_port_info portinfo;
- int err;
-
- memset(&portinfo, 0, sizeof(portinfo));
- portinfo.addr.client = client;
- portinfo.addr.port = port;
- err = snd_seq_kernel_client_ctl(client,
- SNDRV_SEQ_IOCTL_DELETE_PORT,
- &portinfo);
-
- return err;
-}
-
-EXPORT_SYMBOL(snd_seq_event_port_detach);
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_ports.h b/ANDROID_3.4.5/sound/core/seq/seq_ports.h
deleted file mode 100644
index 9d711711..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_ports.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * ALSA sequencer Ports
- * Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __SND_SEQ_PORTS_H
-#define __SND_SEQ_PORTS_H
-
-#include <sound/seq_kernel.h>
-#include "seq_lock.h"
-
-/* list of 'exported' ports */
-
-/* Client ports that are not exported are still accessible, but are
- anonymous ports.
-
- If a port supports SUBSCRIPTION, that port can send events to all
- subscribersto a special address, with address
- (queue==SNDRV_SEQ_ADDRESS_SUBSCRIBERS). The message is then send to all
- recipients that are registered in the subscription list. A typical
- application for these SUBSCRIPTION events is handling of incoming MIDI
- data. The port doesn't 'know' what other clients are interested in this
- message. If for instance a MIDI recording application would like to receive
- the events from that port, it will first have to subscribe with that port.
-
-*/
-
-struct snd_seq_subscribers {
- struct snd_seq_port_subscribe info; /* additional info */
- struct list_head src_list; /* link of sources */
- struct list_head dest_list; /* link of destinations */
- atomic_t ref_count;
-};
-
-struct snd_seq_port_subs_info {
- struct list_head list_head; /* list of subscribed ports */
- unsigned int count; /* count of subscribers */
- unsigned int exclusive: 1; /* exclusive mode */
- struct rw_semaphore list_mutex;
- rwlock_t list_lock;
- int (*open)(void *private_data, struct snd_seq_port_subscribe *info);
- int (*close)(void *private_data, struct snd_seq_port_subscribe *info);
-};
-
-struct snd_seq_client_port {
-
- struct snd_seq_addr addr; /* client/port number */
- struct module *owner; /* owner of this port */
- char name[64]; /* port name */
- struct list_head list; /* port list */
- snd_use_lock_t use_lock;
-
- /* subscribers */
- struct snd_seq_port_subs_info c_src; /* read (sender) list */
- struct snd_seq_port_subs_info c_dest; /* write (dest) list */
-
- int (*event_input)(struct snd_seq_event *ev, int direct, void *private_data,
- int atomic, int hop);
- void (*private_free)(void *private_data);
- void *private_data;
- unsigned int callback_all : 1;
- unsigned int closing : 1;
- unsigned int timestamping: 1;
- unsigned int time_real: 1;
- int time_queue;
-
- /* capability, inport, output, sync */
- unsigned int capability; /* port capability bits */
- unsigned int type; /* port type bits */
-
- /* supported channels */
- int midi_channels;
- int midi_voices;
- int synth_voices;
-
-};
-
-struct snd_seq_client;
-
-/* return pointer to port structure and lock port */
-struct snd_seq_client_port *snd_seq_port_use_ptr(struct snd_seq_client *client, int num);
-
-/* search for next port - port is locked if found */
-struct snd_seq_client_port *snd_seq_port_query_nearest(struct snd_seq_client *client,
- struct snd_seq_port_info *pinfo);
-
-/* unlock the port */
-#define snd_seq_port_unlock(port) snd_use_lock_free(&(port)->use_lock)
-
-/* create a port, port number is returned (-1 on failure) */
-struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, int port_index);
-
-/* delete a port */
-int snd_seq_delete_port(struct snd_seq_client *client, int port);
-
-/* delete all ports */
-int snd_seq_delete_all_ports(struct snd_seq_client *client);
-
-/* set port info fields */
-int snd_seq_set_port_info(struct snd_seq_client_port *port,
- struct snd_seq_port_info *info);
-
-/* get port info fields */
-int snd_seq_get_port_info(struct snd_seq_client_port *port,
- struct snd_seq_port_info *info);
-
-/* add subscriber to subscription list */
-int snd_seq_port_connect(struct snd_seq_client *caller,
- struct snd_seq_client *s, struct snd_seq_client_port *sp,
- struct snd_seq_client *d, struct snd_seq_client_port *dp,
- struct snd_seq_port_subscribe *info);
-
-/* remove subscriber from subscription list */
-int snd_seq_port_disconnect(struct snd_seq_client *caller,
- struct snd_seq_client *s, struct snd_seq_client_port *sp,
- struct snd_seq_client *d, struct snd_seq_client_port *dp,
- struct snd_seq_port_subscribe *info);
-
-/* subscribe port */
-int snd_seq_port_subscribe(struct snd_seq_client_port *port,
- struct snd_seq_port_subscribe *info);
-
-/* get matched subscriber */
-struct snd_seq_subscribers *snd_seq_port_get_subscription(struct snd_seq_port_subs_info *src_grp,
- struct snd_seq_addr *dest_addr);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_prioq.c b/ANDROID_3.4.5/sound/core/seq/seq_prioq.c
deleted file mode 100644
index 29896ab2..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_prioq.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * ALSA sequencer Priority Queue
- * Copyright (c) 1998-1999 by Frank van de Pol <fvdpol@coil.demon.nl>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include "seq_timer.h"
-#include "seq_prioq.h"
-
-
-/* Implementation is a simple linked list for now...
-
- This priority queue orders the events on timestamp. For events with an
- equeal timestamp the queue behaves as a FIFO.
-
- *
- * +-------+
- * Head --> | first |
- * +-------+
- * |next
- * +-----v-+
- * | |
- * +-------+
- * |
- * +-----v-+
- * | |
- * +-------+
- * |
- * +-----v-+
- * Tail --> | last |
- * +-------+
- *
-
- */
-
-
-
-/* create new prioq (constructor) */
-struct snd_seq_prioq *snd_seq_prioq_new(void)
-{
- struct snd_seq_prioq *f;
-
- f = kzalloc(sizeof(*f), GFP_KERNEL);
- if (f == NULL) {
- snd_printd("oops: malloc failed for snd_seq_prioq_new()\n");
- return NULL;
- }
-
- spin_lock_init(&f->lock);
- f->head = NULL;
- f->tail = NULL;
- f->cells = 0;
-
- return f;
-}
-
-/* delete prioq (destructor) */
-void snd_seq_prioq_delete(struct snd_seq_prioq **fifo)
-{
- struct snd_seq_prioq *f = *fifo;
- *fifo = NULL;
-
- if (f == NULL) {
- snd_printd("oops: snd_seq_prioq_delete() called with NULL prioq\n");
- return;
- }
-
- /* release resources...*/
- /*....................*/
-
- if (f->cells > 0) {
- /* drain prioQ */
- while (f->cells > 0)
- snd_seq_cell_free(snd_seq_prioq_cell_out(f));
- }
-
- kfree(f);
-}
-
-
-
-
-/* compare timestamp between events */
-/* return 1 if a >= b; 0 */
-static inline int compare_timestamp(struct snd_seq_event *a,
- struct snd_seq_event *b)
-{
- if ((a->flags & SNDRV_SEQ_TIME_STAMP_MASK) == SNDRV_SEQ_TIME_STAMP_TICK) {
- /* compare ticks */
- return (snd_seq_compare_tick_time(&a->time.tick, &b->time.tick));
- } else {
- /* compare real time */
- return (snd_seq_compare_real_time(&a->time.time, &b->time.time));
- }
-}
-
-/* compare timestamp between events */
-/* return negative if a < b;
- * zero if a = b;
- * positive if a > b;
- */
-static inline int compare_timestamp_rel(struct snd_seq_event *a,
- struct snd_seq_event *b)
-{
- if ((a->flags & SNDRV_SEQ_TIME_STAMP_MASK) == SNDRV_SEQ_TIME_STAMP_TICK) {
- /* compare ticks */
- if (a->time.tick > b->time.tick)
- return 1;
- else if (a->time.tick == b->time.tick)
- return 0;
- else
- return -1;
- } else {
- /* compare real time */
- if (a->time.time.tv_sec > b->time.time.tv_sec)
- return 1;
- else if (a->time.time.tv_sec == b->time.time.tv_sec) {
- if (a->time.time.tv_nsec > b->time.time.tv_nsec)
- return 1;
- else if (a->time.time.tv_nsec == b->time.time.tv_nsec)
- return 0;
- else
- return -1;
- } else
- return -1;
- }
-}
-
-/* enqueue cell to prioq */
-int snd_seq_prioq_cell_in(struct snd_seq_prioq * f,
- struct snd_seq_event_cell * cell)
-{
- struct snd_seq_event_cell *cur, *prev;
- unsigned long flags;
- int count;
- int prior;
-
- if (snd_BUG_ON(!f || !cell))
- return -EINVAL;
-
- /* check flags */
- prior = (cell->event.flags & SNDRV_SEQ_PRIORITY_MASK);
-
- spin_lock_irqsave(&f->lock, flags);
-
- /* check if this element needs to inserted at the end (ie. ordered
- data is inserted) This will be very likeley if a sequencer
- application or midi file player is feeding us (sequential) data */
- if (f->tail && !prior) {
- if (compare_timestamp(&cell->event, &f->tail->event)) {
- /* add new cell to tail of the fifo */
- f->tail->next = cell;
- f->tail = cell;
- cell->next = NULL;
- f->cells++;
- spin_unlock_irqrestore(&f->lock, flags);
- return 0;
- }
- }
- /* traverse list of elements to find the place where the new cell is
- to be inserted... Note that this is a order n process ! */
-
- prev = NULL; /* previous cell */
- cur = f->head; /* cursor */
-
- count = 10000; /* FIXME: enough big, isn't it? */
- while (cur != NULL) {
- /* compare timestamps */
- int rel = compare_timestamp_rel(&cell->event, &cur->event);
- if (rel < 0)
- /* new cell has earlier schedule time, */
- break;
- else if (rel == 0 && prior)
- /* equal schedule time and prior to others */
- break;
- /* new cell has equal or larger schedule time, */
- /* move cursor to next cell */
- prev = cur;
- cur = cur->next;
- if (! --count) {
- spin_unlock_irqrestore(&f->lock, flags);
- snd_printk(KERN_ERR "cannot find a pointer.. infinite loop?\n");
- return -EINVAL;
- }
- }
-
- /* insert it before cursor */
- if (prev != NULL)
- prev->next = cell;
- cell->next = cur;
-
- if (f->head == cur) /* this is the first cell, set head to it */
- f->head = cell;
- if (cur == NULL) /* reached end of the list */
- f->tail = cell;
- f->cells++;
- spin_unlock_irqrestore(&f->lock, flags);
- return 0;
-}
-
-/* dequeue cell from prioq */
-struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f)
-{
- struct snd_seq_event_cell *cell;
- unsigned long flags;
-
- if (f == NULL) {
- snd_printd("oops: snd_seq_prioq_cell_in() called with NULL prioq\n");
- return NULL;
- }
- spin_lock_irqsave(&f->lock, flags);
-
- cell = f->head;
- if (cell) {
- f->head = cell->next;
-
- /* reset tail if this was the last element */
- if (f->tail == cell)
- f->tail = NULL;
-
- cell->next = NULL;
- f->cells--;
- }
-
- spin_unlock_irqrestore(&f->lock, flags);
- return cell;
-}
-
-/* return number of events available in prioq */
-int snd_seq_prioq_avail(struct snd_seq_prioq * f)
-{
- if (f == NULL) {
- snd_printd("oops: snd_seq_prioq_cell_in() called with NULL prioq\n");
- return 0;
- }
- return f->cells;
-}
-
-
-/* peek at cell at the head of the prioq */
-struct snd_seq_event_cell *snd_seq_prioq_cell_peek(struct snd_seq_prioq * f)
-{
- if (f == NULL) {
- snd_printd("oops: snd_seq_prioq_cell_in() called with NULL prioq\n");
- return NULL;
- }
- return f->head;
-}
-
-
-static inline int prioq_match(struct snd_seq_event_cell *cell,
- int client, int timestamp)
-{
- if (cell->event.source.client == client ||
- cell->event.dest.client == client)
- return 1;
- if (!timestamp)
- return 0;
- switch (cell->event.flags & SNDRV_SEQ_TIME_STAMP_MASK) {
- case SNDRV_SEQ_TIME_STAMP_TICK:
- if (cell->event.time.tick)
- return 1;
- break;
- case SNDRV_SEQ_TIME_STAMP_REAL:
- if (cell->event.time.time.tv_sec ||
- cell->event.time.time.tv_nsec)
- return 1;
- break;
- }
- return 0;
-}
-
-/* remove cells for left client */
-void snd_seq_prioq_leave(struct snd_seq_prioq * f, int client, int timestamp)
-{
- register struct snd_seq_event_cell *cell, *next;
- unsigned long flags;
- struct snd_seq_event_cell *prev = NULL;
- struct snd_seq_event_cell *freefirst = NULL, *freeprev = NULL, *freenext;
-
- /* collect all removed cells */
- spin_lock_irqsave(&f->lock, flags);
- cell = f->head;
- while (cell) {
- next = cell->next;
- if (prioq_match(cell, client, timestamp)) {
- /* remove cell from prioq */
- if (cell == f->head) {
- f->head = cell->next;
- } else {
- prev->next = cell->next;
- }
- if (cell == f->tail)
- f->tail = cell->next;
- f->cells--;
- /* add cell to free list */
- cell->next = NULL;
- if (freefirst == NULL) {
- freefirst = cell;
- } else {
- freeprev->next = cell;
- }
- freeprev = cell;
- } else {
-#if 0
- printk(KERN_DEBUG "type = %i, source = %i, dest = %i, "
- "client = %i\n",
- cell->event.type,
- cell->event.source.client,
- cell->event.dest.client,
- client);
-#endif
- prev = cell;
- }
- cell = next;
- }
- spin_unlock_irqrestore(&f->lock, flags);
-
- /* remove selected cells */
- while (freefirst) {
- freenext = freefirst->next;
- snd_seq_cell_free(freefirst);
- freefirst = freenext;
- }
-}
-
-static int prioq_remove_match(struct snd_seq_remove_events *info,
- struct snd_seq_event *ev)
-{
- int res;
-
- if (info->remove_mode & SNDRV_SEQ_REMOVE_DEST) {
- if (ev->dest.client != info->dest.client ||
- ev->dest.port != info->dest.port)
- return 0;
- }
- if (info->remove_mode & SNDRV_SEQ_REMOVE_DEST_CHANNEL) {
- if (! snd_seq_ev_is_channel_type(ev))
- return 0;
- /* data.note.channel and data.control.channel are identical */
- if (ev->data.note.channel != info->channel)
- return 0;
- }
- if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_AFTER) {
- if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK)
- res = snd_seq_compare_tick_time(&ev->time.tick, &info->time.tick);
- else
- res = snd_seq_compare_real_time(&ev->time.time, &info->time.time);
- if (!res)
- return 0;
- }
- if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_BEFORE) {
- if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK)
- res = snd_seq_compare_tick_time(&ev->time.tick, &info->time.tick);
- else
- res = snd_seq_compare_real_time(&ev->time.time, &info->time.time);
- if (res)
- return 0;
- }
- if (info->remove_mode & SNDRV_SEQ_REMOVE_EVENT_TYPE) {
- if (ev->type != info->type)
- return 0;
- }
- if (info->remove_mode & SNDRV_SEQ_REMOVE_IGNORE_OFF) {
- /* Do not remove off events */
- switch (ev->type) {
- case SNDRV_SEQ_EVENT_NOTEOFF:
- /* case SNDRV_SEQ_EVENT_SAMPLE_STOP: */
- return 0;
- default:
- break;
- }
- }
- if (info->remove_mode & SNDRV_SEQ_REMOVE_TAG_MATCH) {
- if (info->tag != ev->tag)
- return 0;
- }
-
- return 1;
-}
-
-/* remove cells matching remove criteria */
-void snd_seq_prioq_remove_events(struct snd_seq_prioq * f, int client,
- struct snd_seq_remove_events *info)
-{
- struct snd_seq_event_cell *cell, *next;
- unsigned long flags;
- struct snd_seq_event_cell *prev = NULL;
- struct snd_seq_event_cell *freefirst = NULL, *freeprev = NULL, *freenext;
-
- /* collect all removed cells */
- spin_lock_irqsave(&f->lock, flags);
- cell = f->head;
-
- while (cell) {
- next = cell->next;
- if (cell->event.source.client == client &&
- prioq_remove_match(info, &cell->event)) {
-
- /* remove cell from prioq */
- if (cell == f->head) {
- f->head = cell->next;
- } else {
- prev->next = cell->next;
- }
-
- if (cell == f->tail)
- f->tail = cell->next;
- f->cells--;
-
- /* add cell to free list */
- cell->next = NULL;
- if (freefirst == NULL) {
- freefirst = cell;
- } else {
- freeprev->next = cell;
- }
-
- freeprev = cell;
- } else {
- prev = cell;
- }
- cell = next;
- }
- spin_unlock_irqrestore(&f->lock, flags);
-
- /* remove selected cells */
- while (freefirst) {
- freenext = freefirst->next;
- snd_seq_cell_free(freefirst);
- freefirst = freenext;
- }
-}
-
-
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_prioq.h b/ANDROID_3.4.5/sound/core/seq/seq_prioq.h
deleted file mode 100644
index d38bb78d..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_prioq.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * ALSA sequencer Priority Queue
- * Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __SND_SEQ_PRIOQ_H
-#define __SND_SEQ_PRIOQ_H
-
-#include "seq_memory.h"
-
-
-/* === PRIOQ === */
-
-struct snd_seq_prioq {
- struct snd_seq_event_cell *head; /* pointer to head of prioq */
- struct snd_seq_event_cell *tail; /* pointer to tail of prioq */
- int cells;
- spinlock_t lock;
-};
-
-
-/* create new prioq (constructor) */
-struct snd_seq_prioq *snd_seq_prioq_new(void);
-
-/* delete prioq (destructor) */
-void snd_seq_prioq_delete(struct snd_seq_prioq **fifo);
-
-/* enqueue cell to prioq */
-int snd_seq_prioq_cell_in(struct snd_seq_prioq *f, struct snd_seq_event_cell *cell);
-
-/* dequeue cell from prioq */
-struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f);
-
-/* return number of events available in prioq */
-int snd_seq_prioq_avail(struct snd_seq_prioq *f);
-
-/* peek at cell at the head of the prioq */
-struct snd_seq_event_cell *snd_seq_prioq_cell_peek(struct snd_seq_prioq *f);
-
-/* client left queue */
-void snd_seq_prioq_leave(struct snd_seq_prioq *f, int client, int timestamp);
-
-/* Remove events */
-void snd_seq_prioq_remove_events(struct snd_seq_prioq *f, int client,
- struct snd_seq_remove_events *info);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_queue.c b/ANDROID_3.4.5/sound/core/seq/seq_queue.c
deleted file mode 100644
index f9077361..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_queue.c
+++ /dev/null
@@ -1,793 +0,0 @@
-/*
- * ALSA sequencer Timing queue handling
- * Copyright (c) 1998-1999 by Frank van de Pol <fvdpol@coil.demon.nl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * MAJOR CHANGES
- * Nov. 13, 1999 Takashi Iwai <iwai@ww.uni-erlangen.de>
- * - Queues are allocated dynamically via ioctl.
- * - When owner client is deleted, all owned queues are deleted, too.
- * - Owner of unlocked queue is kept unmodified even if it is
- * manipulated by other clients.
- * - Owner field in SET_QUEUE_OWNER ioctl must be identical with the
- * caller client. i.e. Changing owner to a third client is not
- * allowed.
- *
- * Aug. 30, 2000 Takashi Iwai
- * - Queues are managed in static array again, but with better way.
- * The API itself is identical.
- * - The queue is locked when struct snd_seq_queue pointer is returned via
- * queueptr(). This pointer *MUST* be released afterward by
- * queuefree(ptr).
- * - Addition of experimental sync support.
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-
-#include "seq_memory.h"
-#include "seq_queue.h"
-#include "seq_clientmgr.h"
-#include "seq_fifo.h"
-#include "seq_timer.h"
-#include "seq_info.h"
-
-/* list of allocated queues */
-static struct snd_seq_queue *queue_list[SNDRV_SEQ_MAX_QUEUES];
-static DEFINE_SPINLOCK(queue_list_lock);
-/* number of queues allocated */
-static int num_queues;
-
-int snd_seq_queue_get_cur_queues(void)
-{
- return num_queues;
-}
-
-/*----------------------------------------------------------------*/
-
-/* assign queue id and insert to list */
-static int queue_list_add(struct snd_seq_queue *q)
-{
- int i;
- unsigned long flags;
-
- spin_lock_irqsave(&queue_list_lock, flags);
- for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
- if (! queue_list[i]) {
- queue_list[i] = q;
- q->queue = i;
- num_queues++;
- spin_unlock_irqrestore(&queue_list_lock, flags);
- return i;
- }
- }
- spin_unlock_irqrestore(&queue_list_lock, flags);
- return -1;
-}
-
-static struct snd_seq_queue *queue_list_remove(int id, int client)
-{
- struct snd_seq_queue *q;
- unsigned long flags;
-
- spin_lock_irqsave(&queue_list_lock, flags);
- q = queue_list[id];
- if (q) {
- spin_lock(&q->owner_lock);
- if (q->owner == client) {
- /* found */
- q->klocked = 1;
- spin_unlock(&q->owner_lock);
- queue_list[id] = NULL;
- num_queues--;
- spin_unlock_irqrestore(&queue_list_lock, flags);
- return q;
- }
- spin_unlock(&q->owner_lock);
- }
- spin_unlock_irqrestore(&queue_list_lock, flags);
- return NULL;
-}
-
-/*----------------------------------------------------------------*/
-
-/* create new queue (constructor) */
-static struct snd_seq_queue *queue_new(int owner, int locked)
-{
- struct snd_seq_queue *q;
-
- q = kzalloc(sizeof(*q), GFP_KERNEL);
- if (q == NULL) {
- snd_printd("malloc failed for snd_seq_queue_new()\n");
- return NULL;
- }
-
- spin_lock_init(&q->owner_lock);
- spin_lock_init(&q->check_lock);
- mutex_init(&q->timer_mutex);
- snd_use_lock_init(&q->use_lock);
- q->queue = -1;
-
- q->tickq = snd_seq_prioq_new();
- q->timeq = snd_seq_prioq_new();
- q->timer = snd_seq_timer_new();
- if (q->tickq == NULL || q->timeq == NULL || q->timer == NULL) {
- snd_seq_prioq_delete(&q->tickq);
- snd_seq_prioq_delete(&q->timeq);
- snd_seq_timer_delete(&q->timer);
- kfree(q);
- return NULL;
- }
-
- q->owner = owner;
- q->locked = locked;
- q->klocked = 0;
-
- return q;
-}
-
-/* delete queue (destructor) */
-static void queue_delete(struct snd_seq_queue *q)
-{
- /* stop and release the timer */
- snd_seq_timer_stop(q->timer);
- snd_seq_timer_close(q);
- /* wait until access free */
- snd_use_lock_sync(&q->use_lock);
- /* release resources... */
- snd_seq_prioq_delete(&q->tickq);
- snd_seq_prioq_delete(&q->timeq);
- snd_seq_timer_delete(&q->timer);
-
- kfree(q);
-}
-
-
-/*----------------------------------------------------------------*/
-
-/* setup queues */
-int __init snd_seq_queues_init(void)
-{
- /*
- memset(queue_list, 0, sizeof(queue_list));
- num_queues = 0;
- */
- return 0;
-}
-
-/* delete all existing queues */
-void __exit snd_seq_queues_delete(void)
-{
- int i;
-
- /* clear list */
- for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
- if (queue_list[i])
- queue_delete(queue_list[i]);
- }
-}
-
-/* allocate a new queue -
- * return queue index value or negative value for error
- */
-int snd_seq_queue_alloc(int client, int locked, unsigned int info_flags)
-{
- struct snd_seq_queue *q;
-
- q = queue_new(client, locked);
- if (q == NULL)
- return -ENOMEM;
- q->info_flags = info_flags;
- if (queue_list_add(q) < 0) {
- queue_delete(q);
- return -ENOMEM;
- }
- snd_seq_queue_use(q->queue, client, 1); /* use this queue */
- return q->queue;
-}
-
-/* delete a queue - queue must be owned by the client */
-int snd_seq_queue_delete(int client, int queueid)
-{
- struct snd_seq_queue *q;
-
- if (queueid < 0 || queueid >= SNDRV_SEQ_MAX_QUEUES)
- return -EINVAL;
- q = queue_list_remove(queueid, client);
- if (q == NULL)
- return -EINVAL;
- queue_delete(q);
-
- return 0;
-}
-
-
-/* return pointer to queue structure for specified id */
-struct snd_seq_queue *queueptr(int queueid)
-{
- struct snd_seq_queue *q;
- unsigned long flags;
-
- if (queueid < 0 || queueid >= SNDRV_SEQ_MAX_QUEUES)
- return NULL;
- spin_lock_irqsave(&queue_list_lock, flags);
- q = queue_list[queueid];
- if (q)
- snd_use_lock_use(&q->use_lock);
- spin_unlock_irqrestore(&queue_list_lock, flags);
- return q;
-}
-
-/* return the (first) queue matching with the specified name */
-struct snd_seq_queue *snd_seq_queue_find_name(char *name)
-{
- int i;
- struct snd_seq_queue *q;
-
- for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
- if ((q = queueptr(i)) != NULL) {
- if (strncmp(q->name, name, sizeof(q->name)) == 0)
- return q;
- queuefree(q);
- }
- }
- return NULL;
-}
-
-
-/* -------------------------------------------------------- */
-
-void snd_seq_check_queue(struct snd_seq_queue *q, int atomic, int hop)
-{
- unsigned long flags;
- struct snd_seq_event_cell *cell;
-
- if (q == NULL)
- return;
-
- /* make this function non-reentrant */
- spin_lock_irqsave(&q->check_lock, flags);
- if (q->check_blocked) {
- q->check_again = 1;
- spin_unlock_irqrestore(&q->check_lock, flags);
- return; /* other thread is already checking queues */
- }
- q->check_blocked = 1;
- spin_unlock_irqrestore(&q->check_lock, flags);
-
- __again:
- /* Process tick queue... */
- while ((cell = snd_seq_prioq_cell_peek(q->tickq)) != NULL) {
- if (snd_seq_compare_tick_time(&q->timer->tick.cur_tick,
- &cell->event.time.tick)) {
- cell = snd_seq_prioq_cell_out(q->tickq);
- if (cell)
- snd_seq_dispatch_event(cell, atomic, hop);
- } else {
- /* event remains in the queue */
- break;
- }
- }
-
-
- /* Process time queue... */
- while ((cell = snd_seq_prioq_cell_peek(q->timeq)) != NULL) {
- if (snd_seq_compare_real_time(&q->timer->cur_time,
- &cell->event.time.time)) {
- cell = snd_seq_prioq_cell_out(q->timeq);
- if (cell)
- snd_seq_dispatch_event(cell, atomic, hop);
- } else {
- /* event remains in the queue */
- break;
- }
- }
-
- /* free lock */
- spin_lock_irqsave(&q->check_lock, flags);
- if (q->check_again) {
- q->check_again = 0;
- spin_unlock_irqrestore(&q->check_lock, flags);
- goto __again;
- }
- q->check_blocked = 0;
- spin_unlock_irqrestore(&q->check_lock, flags);
-}
-
-
-/* enqueue a event to singe queue */
-int snd_seq_enqueue_event(struct snd_seq_event_cell *cell, int atomic, int hop)
-{
- int dest, err;
- struct snd_seq_queue *q;
-
- if (snd_BUG_ON(!cell))
- return -EINVAL;
- dest = cell->event.queue; /* destination queue */
- q = queueptr(dest);
- if (q == NULL)
- return -EINVAL;
- /* handle relative time stamps, convert them into absolute */
- if ((cell->event.flags & SNDRV_SEQ_TIME_MODE_MASK) == SNDRV_SEQ_TIME_MODE_REL) {
- switch (cell->event.flags & SNDRV_SEQ_TIME_STAMP_MASK) {
- case SNDRV_SEQ_TIME_STAMP_TICK:
- cell->event.time.tick += q->timer->tick.cur_tick;
- break;
-
- case SNDRV_SEQ_TIME_STAMP_REAL:
- snd_seq_inc_real_time(&cell->event.time.time,
- &q->timer->cur_time);
- break;
- }
- cell->event.flags &= ~SNDRV_SEQ_TIME_MODE_MASK;
- cell->event.flags |= SNDRV_SEQ_TIME_MODE_ABS;
- }
- /* enqueue event in the real-time or midi queue */
- switch (cell->event.flags & SNDRV_SEQ_TIME_STAMP_MASK) {
- case SNDRV_SEQ_TIME_STAMP_TICK:
- err = snd_seq_prioq_cell_in(q->tickq, cell);
- break;
-
- case SNDRV_SEQ_TIME_STAMP_REAL:
- default:
- err = snd_seq_prioq_cell_in(q->timeq, cell);
- break;
- }
-
- if (err < 0) {
- queuefree(q); /* unlock */
- return err;
- }
-
- /* trigger dispatching */
- snd_seq_check_queue(q, atomic, hop);
-
- queuefree(q); /* unlock */
-
- return 0;
-}
-
-
-/*----------------------------------------------------------------*/
-
-static inline int check_access(struct snd_seq_queue *q, int client)
-{
- return (q->owner == client) || (!q->locked && !q->klocked);
-}
-
-/* check if the client has permission to modify queue parameters.
- * if it does, lock the queue
- */
-static int queue_access_lock(struct snd_seq_queue *q, int client)
-{
- unsigned long flags;
- int access_ok;
-
- spin_lock_irqsave(&q->owner_lock, flags);
- access_ok = check_access(q, client);
- if (access_ok)
- q->klocked = 1;
- spin_unlock_irqrestore(&q->owner_lock, flags);
- return access_ok;
-}
-
-/* unlock the queue */
-static inline void queue_access_unlock(struct snd_seq_queue *q)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&q->owner_lock, flags);
- q->klocked = 0;
- spin_unlock_irqrestore(&q->owner_lock, flags);
-}
-
-/* exported - only checking permission */
-int snd_seq_queue_check_access(int queueid, int client)
-{
- struct snd_seq_queue *q = queueptr(queueid);
- int access_ok;
- unsigned long flags;
-
- if (! q)
- return 0;
- spin_lock_irqsave(&q->owner_lock, flags);
- access_ok = check_access(q, client);
- spin_unlock_irqrestore(&q->owner_lock, flags);
- queuefree(q);
- return access_ok;
-}
-
-/*----------------------------------------------------------------*/
-
-/*
- * change queue's owner and permission
- */
-int snd_seq_queue_set_owner(int queueid, int client, int locked)
-{
- struct snd_seq_queue *q = queueptr(queueid);
-
- if (q == NULL)
- return -EINVAL;
-
- if (! queue_access_lock(q, client)) {
- queuefree(q);
- return -EPERM;
- }
-
- q->locked = locked ? 1 : 0;
- q->owner = client;
- queue_access_unlock(q);
- queuefree(q);
-
- return 0;
-}
-
-
-/*----------------------------------------------------------------*/
-
-/* open timer -
- * q->use mutex should be down before calling this function to avoid
- * confliction with snd_seq_queue_use()
- */
-int snd_seq_queue_timer_open(int queueid)
-{
- int result = 0;
- struct snd_seq_queue *queue;
- struct snd_seq_timer *tmr;
-
- queue = queueptr(queueid);
- if (queue == NULL)
- return -EINVAL;
- tmr = queue->timer;
- if ((result = snd_seq_timer_open(queue)) < 0) {
- snd_seq_timer_defaults(tmr);
- result = snd_seq_timer_open(queue);
- }
- queuefree(queue);
- return result;
-}
-
-/* close timer -
- * q->use mutex should be down before calling this function
- */
-int snd_seq_queue_timer_close(int queueid)
-{
- struct snd_seq_queue *queue;
- int result = 0;
-
- queue = queueptr(queueid);
- if (queue == NULL)
- return -EINVAL;
- snd_seq_timer_close(queue);
- queuefree(queue);
- return result;
-}
-
-/* change queue tempo and ppq */
-int snd_seq_queue_timer_set_tempo(int queueid, int client,
- struct snd_seq_queue_tempo *info)
-{
- struct snd_seq_queue *q = queueptr(queueid);
- int result;
-
- if (q == NULL)
- return -EINVAL;
- if (! queue_access_lock(q, client)) {
- queuefree(q);
- return -EPERM;
- }
-
- result = snd_seq_timer_set_tempo(q->timer, info->tempo);
- if (result >= 0)
- result = snd_seq_timer_set_ppq(q->timer, info->ppq);
- if (result >= 0 && info->skew_base > 0)
- result = snd_seq_timer_set_skew(q->timer, info->skew_value,
- info->skew_base);
- queue_access_unlock(q);
- queuefree(q);
- return result;
-}
-
-
-/* use or unuse this queue -
- * if it is the first client, starts the timer.
- * if it is not longer used by any clients, stop the timer.
- */
-int snd_seq_queue_use(int queueid, int client, int use)
-{
- struct snd_seq_queue *queue;
-
- queue = queueptr(queueid);
- if (queue == NULL)
- return -EINVAL;
- mutex_lock(&queue->timer_mutex);
- if (use) {
- if (!test_and_set_bit(client, queue->clients_bitmap))
- queue->clients++;
- } else {
- if (test_and_clear_bit(client, queue->clients_bitmap))
- queue->clients--;
- }
- if (queue->clients) {
- if (use && queue->clients == 1)
- snd_seq_timer_defaults(queue->timer);
- snd_seq_timer_open(queue);
- } else {
- snd_seq_timer_close(queue);
- }
- mutex_unlock(&queue->timer_mutex);
- queuefree(queue);
- return 0;
-}
-
-/*
- * check if queue is used by the client
- * return negative value if the queue is invalid.
- * return 0 if not used, 1 if used.
- */
-int snd_seq_queue_is_used(int queueid, int client)
-{
- struct snd_seq_queue *q;
- int result;
-
- q = queueptr(queueid);
- if (q == NULL)
- return -EINVAL; /* invalid queue */
- result = test_bit(client, q->clients_bitmap) ? 1 : 0;
- queuefree(q);
- return result;
-}
-
-
-/*----------------------------------------------------------------*/
-
-/* notification that client has left the system -
- * stop the timer on all queues owned by this client
- */
-void snd_seq_queue_client_termination(int client)
-{
- unsigned long flags;
- int i;
- struct snd_seq_queue *q;
-
- for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
- if ((q = queueptr(i)) == NULL)
- continue;
- spin_lock_irqsave(&q->owner_lock, flags);
- if (q->owner == client)
- q->klocked = 1;
- spin_unlock_irqrestore(&q->owner_lock, flags);
- if (q->owner == client) {
- if (q->timer->running)
- snd_seq_timer_stop(q->timer);
- snd_seq_timer_reset(q->timer);
- }
- queuefree(q);
- }
-}
-
-/* final stage notification -
- * remove cells for no longer exist client (for non-owned queue)
- * or delete this queue (for owned queue)
- */
-void snd_seq_queue_client_leave(int client)
-{
- int i;
- struct snd_seq_queue *q;
-
- /* delete own queues from queue list */
- for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
- if ((q = queue_list_remove(i, client)) != NULL)
- queue_delete(q);
- }
-
- /* remove cells from existing queues -
- * they are not owned by this client
- */
- for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
- if ((q = queueptr(i)) == NULL)
- continue;
- if (test_bit(client, q->clients_bitmap)) {
- snd_seq_prioq_leave(q->tickq, client, 0);
- snd_seq_prioq_leave(q->timeq, client, 0);
- snd_seq_queue_use(q->queue, client, 0);
- }
- queuefree(q);
- }
-}
-
-
-
-/*----------------------------------------------------------------*/
-
-/* remove cells from all queues */
-void snd_seq_queue_client_leave_cells(int client)
-{
- int i;
- struct snd_seq_queue *q;
-
- for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
- if ((q = queueptr(i)) == NULL)
- continue;
- snd_seq_prioq_leave(q->tickq, client, 0);
- snd_seq_prioq_leave(q->timeq, client, 0);
- queuefree(q);
- }
-}
-
-/* remove cells based on flush criteria */
-void snd_seq_queue_remove_cells(int client, struct snd_seq_remove_events *info)
-{
- int i;
- struct snd_seq_queue *q;
-
- for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
- if ((q = queueptr(i)) == NULL)
- continue;
- if (test_bit(client, q->clients_bitmap) &&
- (! (info->remove_mode & SNDRV_SEQ_REMOVE_DEST) ||
- q->queue == info->queue)) {
- snd_seq_prioq_remove_events(q->tickq, client, info);
- snd_seq_prioq_remove_events(q->timeq, client, info);
- }
- queuefree(q);
- }
-}
-
-/*----------------------------------------------------------------*/
-
-/*
- * send events to all subscribed ports
- */
-static void queue_broadcast_event(struct snd_seq_queue *q, struct snd_seq_event *ev,
- int atomic, int hop)
-{
- struct snd_seq_event sev;
-
- sev = *ev;
-
- sev.flags = SNDRV_SEQ_TIME_STAMP_TICK|SNDRV_SEQ_TIME_MODE_ABS;
- sev.time.tick = q->timer->tick.cur_tick;
- sev.queue = q->queue;
- sev.data.queue.queue = q->queue;
-
- /* broadcast events from Timer port */
- sev.source.client = SNDRV_SEQ_CLIENT_SYSTEM;
- sev.source.port = SNDRV_SEQ_PORT_SYSTEM_TIMER;
- sev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS;
- snd_seq_kernel_client_dispatch(SNDRV_SEQ_CLIENT_SYSTEM, &sev, atomic, hop);
-}
-
-/*
- * process a received queue-control event.
- * this function is exported for seq_sync.c.
- */
-static void snd_seq_queue_process_event(struct snd_seq_queue *q,
- struct snd_seq_event *ev,
- int atomic, int hop)
-{
- switch (ev->type) {
- case SNDRV_SEQ_EVENT_START:
- snd_seq_prioq_leave(q->tickq, ev->source.client, 1);
- snd_seq_prioq_leave(q->timeq, ev->source.client, 1);
- if (! snd_seq_timer_start(q->timer))
- queue_broadcast_event(q, ev, atomic, hop);
- break;
-
- case SNDRV_SEQ_EVENT_CONTINUE:
- if (! snd_seq_timer_continue(q->timer))
- queue_broadcast_event(q, ev, atomic, hop);
- break;
-
- case SNDRV_SEQ_EVENT_STOP:
- snd_seq_timer_stop(q->timer);
- queue_broadcast_event(q, ev, atomic, hop);
- break;
-
- case SNDRV_SEQ_EVENT_TEMPO:
- snd_seq_timer_set_tempo(q->timer, ev->data.queue.param.value);
- queue_broadcast_event(q, ev, atomic, hop);
- break;
-
- case SNDRV_SEQ_EVENT_SETPOS_TICK:
- if (snd_seq_timer_set_position_tick(q->timer, ev->data.queue.param.time.tick) == 0) {
- queue_broadcast_event(q, ev, atomic, hop);
- }
- break;
-
- case SNDRV_SEQ_EVENT_SETPOS_TIME:
- if (snd_seq_timer_set_position_time(q->timer, ev->data.queue.param.time.time) == 0) {
- queue_broadcast_event(q, ev, atomic, hop);
- }
- break;
- case SNDRV_SEQ_EVENT_QUEUE_SKEW:
- if (snd_seq_timer_set_skew(q->timer,
- ev->data.queue.param.skew.value,
- ev->data.queue.param.skew.base) == 0) {
- queue_broadcast_event(q, ev, atomic, hop);
- }
- break;
- }
-}
-
-
-/*
- * Queue control via timer control port:
- * this function is exported as a callback of timer port.
- */
-int snd_seq_control_queue(struct snd_seq_event *ev, int atomic, int hop)
-{
- struct snd_seq_queue *q;
-
- if (snd_BUG_ON(!ev))
- return -EINVAL;
- q = queueptr(ev->data.queue.queue);
-
- if (q == NULL)
- return -EINVAL;
-
- if (! queue_access_lock(q, ev->source.client)) {
- queuefree(q);
- return -EPERM;
- }
-
- snd_seq_queue_process_event(q, ev, atomic, hop);
-
- queue_access_unlock(q);
- queuefree(q);
- return 0;
-}
-
-
-/*----------------------------------------------------------------*/
-
-#ifdef CONFIG_PROC_FS
-/* exported to seq_info.c */
-void snd_seq_info_queues_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- int i, bpm;
- struct snd_seq_queue *q;
- struct snd_seq_timer *tmr;
-
- for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
- if ((q = queueptr(i)) == NULL)
- continue;
-
- tmr = q->timer;
- if (tmr->tempo)
- bpm = 60000000 / tmr->tempo;
- else
- bpm = 0;
-
- snd_iprintf(buffer, "queue %d: [%s]\n", q->queue, q->name);
- snd_iprintf(buffer, "owned by client : %d\n", q->owner);
- snd_iprintf(buffer, "lock status : %s\n", q->locked ? "Locked" : "Free");
- snd_iprintf(buffer, "queued time events : %d\n", snd_seq_prioq_avail(q->timeq));
- snd_iprintf(buffer, "queued tick events : %d\n", snd_seq_prioq_avail(q->tickq));
- snd_iprintf(buffer, "timer state : %s\n", tmr->running ? "Running" : "Stopped");
- snd_iprintf(buffer, "timer PPQ : %d\n", tmr->ppq);
- snd_iprintf(buffer, "current tempo : %d\n", tmr->tempo);
- snd_iprintf(buffer, "current BPM : %d\n", bpm);
- snd_iprintf(buffer, "current time : %d.%09d s\n", tmr->cur_time.tv_sec, tmr->cur_time.tv_nsec);
- snd_iprintf(buffer, "current tick : %d\n", tmr->tick.cur_tick);
- snd_iprintf(buffer, "\n");
- queuefree(q);
- }
-}
-#endif /* CONFIG_PROC_FS */
-
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_queue.h b/ANDROID_3.4.5/sound/core/seq/seq_queue.h
deleted file mode 100644
index 30c81114..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_queue.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * ALSA sequencer Queue handling
- * Copyright (c) 1998-1999 by Frank van de Pol <fvdpol@coil.demon.nl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __SND_SEQ_QUEUE_H
-#define __SND_SEQ_QUEUE_H
-
-#include "seq_memory.h"
-#include "seq_prioq.h"
-#include "seq_timer.h"
-#include "seq_lock.h"
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/bitops.h>
-
-#define SEQ_QUEUE_NO_OWNER (-1)
-
-struct snd_seq_queue {
- int queue; /* queue number */
-
- char name[64]; /* name of this queue */
-
- struct snd_seq_prioq *tickq; /* midi tick event queue */
- struct snd_seq_prioq *timeq; /* real-time event queue */
-
- struct snd_seq_timer *timer; /* time keeper for this queue */
- int owner; /* client that 'owns' the timer */
- unsigned int locked:1, /* timer is only accesibble by owner if set */
- klocked:1, /* kernel lock (after START) */
- check_again:1,
- check_blocked:1;
-
- unsigned int flags; /* status flags */
- unsigned int info_flags; /* info for sync */
-
- spinlock_t owner_lock;
- spinlock_t check_lock;
-
- /* clients which uses this queue (bitmap) */
- DECLARE_BITMAP(clients_bitmap, SNDRV_SEQ_MAX_CLIENTS);
- unsigned int clients; /* users of this queue */
- struct mutex timer_mutex;
-
- snd_use_lock_t use_lock;
-};
-
-
-/* get the number of current queues */
-int snd_seq_queue_get_cur_queues(void);
-
-/* init queues structure */
-int snd_seq_queues_init(void);
-
-/* delete queues */
-void snd_seq_queues_delete(void);
-
-
-/* create new queue (constructor) */
-int snd_seq_queue_alloc(int client, int locked, unsigned int flags);
-
-/* delete queue (destructor) */
-int snd_seq_queue_delete(int client, int queueid);
-
-/* notification that client has left the system */
-void snd_seq_queue_client_termination(int client);
-
-/* final stage */
-void snd_seq_queue_client_leave(int client);
-
-/* enqueue a event received from one the clients */
-int snd_seq_enqueue_event(struct snd_seq_event_cell *cell, int atomic, int hop);
-
-/* Remove events */
-void snd_seq_queue_client_leave_cells(int client);
-void snd_seq_queue_remove_cells(int client, struct snd_seq_remove_events *info);
-
-/* return pointer to queue structure for specified id */
-struct snd_seq_queue *queueptr(int queueid);
-/* unlock */
-#define queuefree(q) snd_use_lock_free(&(q)->use_lock)
-
-/* return the (first) queue matching with the specified name */
-struct snd_seq_queue *snd_seq_queue_find_name(char *name);
-
-/* check single queue and dispatch events */
-void snd_seq_check_queue(struct snd_seq_queue *q, int atomic, int hop);
-
-/* access to queue's parameters */
-int snd_seq_queue_check_access(int queueid, int client);
-int snd_seq_queue_timer_set_tempo(int queueid, int client, struct snd_seq_queue_tempo *info);
-int snd_seq_queue_set_owner(int queueid, int client, int locked);
-int snd_seq_queue_set_locked(int queueid, int client, int locked);
-int snd_seq_queue_timer_open(int queueid);
-int snd_seq_queue_timer_close(int queueid);
-int snd_seq_queue_use(int queueid, int client, int use);
-int snd_seq_queue_is_used(int queueid, int client);
-
-int snd_seq_control_queue(struct snd_seq_event *ev, int atomic, int hop);
-
-/*
- * 64bit division - for sync stuff..
- */
-#if defined(i386) || defined(i486)
-
-#define udiv_qrnnd(q, r, n1, n0, d) \
- __asm__ ("divl %4" \
- : "=a" ((u32)(q)), \
- "=d" ((u32)(r)) \
- : "0" ((u32)(n0)), \
- "1" ((u32)(n1)), \
- "rm" ((u32)(d)))
-
-#define u64_div(x,y,q) do {u32 __tmp; udiv_qrnnd(q, __tmp, (x)>>32, x, y);} while (0)
-#define u64_mod(x,y,r) do {u32 __tmp; udiv_qrnnd(__tmp, q, (x)>>32, x, y);} while (0)
-#define u64_divmod(x,y,q,r) udiv_qrnnd(q, r, (x)>>32, x, y)
-
-#else
-#define u64_div(x,y,q) ((q) = (u32)((u64)(x) / (u64)(y)))
-#define u64_mod(x,y,r) ((r) = (u32)((u64)(x) % (u64)(y)))
-#define u64_divmod(x,y,q,r) (u64_div(x,y,q), u64_mod(x,y,r))
-#endif
-
-
-#endif
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_system.c b/ANDROID_3.4.5/sound/core/seq/seq_system.c
deleted file mode 100644
index 8ce1d0b4..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_system.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * ALSA sequencer System services Client
- * Copyright (c) 1998-1999 by Frank van de Pol <fvdpol@coil.demon.nl>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/export.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include "seq_system.h"
-#include "seq_timer.h"
-#include "seq_queue.h"
-
-/* internal client that provide system services, access to timer etc. */
-
-/*
- * Port "Timer"
- * - send tempo /start/stop etc. events to this port to manipulate the
- * queue's timer. The queue address is specified in
- * data.queue.queue.
- * - this port supports subscription. The received timer events are
- * broadcasted to all subscribed clients. The modified tempo
- * value is stored on data.queue.value.
- * The modifier client/port is not send.
- *
- * Port "Announce"
- * - does not receive message
- * - supports supscription. For each client or port attaching to or
- * detaching from the system an announcement is send to the subscribed
- * clients.
- *
- * Idea: the subscription mechanism might also work handy for distributing
- * synchronisation and timing information. In this case we would ideally have
- * a list of subscribers for each type of sync (time, tick), for each timing
- * queue.
- *
- * NOTE: the queue to be started, stopped, etc. must be specified
- * in data.queue.addr.queue field. queue is used only for
- * scheduling, and no longer referred as affected queue.
- * They are used only for timer broadcast (see above).
- * -- iwai
- */
-
-
-/* client id of our system client */
-static int sysclient = -1;
-
-/* port id numbers for this client */
-static int announce_port = -1;
-
-
-
-/* fill standard header data, source port & channel are filled in */
-static int setheader(struct snd_seq_event * ev, int client, int port)
-{
- if (announce_port < 0)
- return -ENODEV;
-
- memset(ev, 0, sizeof(struct snd_seq_event));
-
- ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
- ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED;
-
- ev->source.client = sysclient;
- ev->source.port = announce_port;
- ev->dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS;
-
- /* fill data */
- /*ev->data.addr.queue = SNDRV_SEQ_ADDRESS_UNKNOWN;*/
- ev->data.addr.client = client;
- ev->data.addr.port = port;
-
- return 0;
-}
-
-
-/* entry points for broadcasting system events */
-void snd_seq_system_broadcast(int client, int port, int type)
-{
- struct snd_seq_event ev;
-
- if (setheader(&ev, client, port) < 0)
- return;
- ev.type = type;
- snd_seq_kernel_client_dispatch(sysclient, &ev, 0, 0);
-}
-
-/* entry points for broadcasting system events */
-int snd_seq_system_notify(int client, int port, struct snd_seq_event *ev)
-{
- ev->flags = SNDRV_SEQ_EVENT_LENGTH_FIXED;
- ev->source.client = sysclient;
- ev->source.port = announce_port;
- ev->dest.client = client;
- ev->dest.port = port;
- return snd_seq_kernel_client_dispatch(sysclient, ev, 0, 0);
-}
-
-/* call-back handler for timer events */
-static int event_input_timer(struct snd_seq_event * ev, int direct, void *private_data, int atomic, int hop)
-{
- return snd_seq_control_queue(ev, atomic, hop);
-}
-
-/* register our internal client */
-int __init snd_seq_system_client_init(void)
-{
- struct snd_seq_port_callback pcallbacks;
- struct snd_seq_port_info *port;
-
- port = kzalloc(sizeof(*port), GFP_KERNEL);
- if (!port)
- return -ENOMEM;
-
- memset(&pcallbacks, 0, sizeof(pcallbacks));
- pcallbacks.owner = THIS_MODULE;
- pcallbacks.event_input = event_input_timer;
-
- /* register client */
- sysclient = snd_seq_create_kernel_client(NULL, 0, "System");
-
- /* register timer */
- strcpy(port->name, "Timer");
- port->capability = SNDRV_SEQ_PORT_CAP_WRITE; /* accept queue control */
- port->capability |= SNDRV_SEQ_PORT_CAP_READ|SNDRV_SEQ_PORT_CAP_SUBS_READ; /* for broadcast */
- port->kernel = &pcallbacks;
- port->type = 0;
- port->flags = SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
- port->addr.client = sysclient;
- port->addr.port = SNDRV_SEQ_PORT_SYSTEM_TIMER;
- snd_seq_kernel_client_ctl(sysclient, SNDRV_SEQ_IOCTL_CREATE_PORT, port);
-
- /* register announcement port */
- strcpy(port->name, "Announce");
- port->capability = SNDRV_SEQ_PORT_CAP_READ|SNDRV_SEQ_PORT_CAP_SUBS_READ; /* for broadcast only */
- port->kernel = NULL;
- port->type = 0;
- port->flags = SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
- port->addr.client = sysclient;
- port->addr.port = SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE;
- snd_seq_kernel_client_ctl(sysclient, SNDRV_SEQ_IOCTL_CREATE_PORT, port);
- announce_port = port->addr.port;
-
- kfree(port);
- return 0;
-}
-
-
-/* unregister our internal client */
-void __exit snd_seq_system_client_done(void)
-{
- int oldsysclient = sysclient;
-
- if (oldsysclient >= 0) {
- sysclient = -1;
- announce_port = -1;
- snd_seq_delete_kernel_client(oldsysclient);
- }
-}
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_system.h b/ANDROID_3.4.5/sound/core/seq/seq_system.h
deleted file mode 100644
index cf2cfa23..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_system.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * ALSA sequencer System Client
- * Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __SND_SEQ_SYSTEM_H
-#define __SND_SEQ_SYSTEM_H
-
-#include <sound/seq_kernel.h>
-
-
-/* entry points for broadcasting system events */
-void snd_seq_system_broadcast(int client, int port, int type);
-
-#define snd_seq_system_client_ev_client_start(client) snd_seq_system_broadcast(client, 0, SNDRV_SEQ_EVENT_CLIENT_START)
-#define snd_seq_system_client_ev_client_exit(client) snd_seq_system_broadcast(client, 0, SNDRV_SEQ_EVENT_CLIENT_EXIT)
-#define snd_seq_system_client_ev_client_change(client) snd_seq_system_broadcast(client, 0, SNDRV_SEQ_EVENT_CLIENT_CHANGE)
-#define snd_seq_system_client_ev_port_start(client, port) snd_seq_system_broadcast(client, port, SNDRV_SEQ_EVENT_PORT_START)
-#define snd_seq_system_client_ev_port_exit(client, port) snd_seq_system_broadcast(client, port, SNDRV_SEQ_EVENT_PORT_EXIT)
-#define snd_seq_system_client_ev_port_change(client, port) snd_seq_system_broadcast(client, port, SNDRV_SEQ_EVENT_PORT_CHANGE)
-
-int snd_seq_system_notify(int client, int port, struct snd_seq_event *ev);
-
-/* register our internal client */
-int snd_seq_system_client_init(void);
-
-/* unregister our internal client */
-void snd_seq_system_client_done(void);
-
-
-#endif
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_timer.c b/ANDROID_3.4.5/sound/core/seq/seq_timer.c
deleted file mode 100644
index 160b1bd0..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_timer.c
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * ALSA sequencer Timer
- * Copyright (c) 1998-1999 by Frank van de Pol <fvdpol@coil.demon.nl>
- * Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <sound/core.h>
-#include <linux/slab.h>
-#include "seq_timer.h"
-#include "seq_queue.h"
-#include "seq_info.h"
-
-/* allowed sequencer timer frequencies, in Hz */
-#define MIN_FREQUENCY 10
-#define MAX_FREQUENCY 6250
-#define DEFAULT_FREQUENCY 1000
-
-#define SKEW_BASE 0x10000 /* 16bit shift */
-
-static void snd_seq_timer_set_tick_resolution(struct snd_seq_timer *tmr)
-{
- if (tmr->tempo < 1000000)
- tmr->tick.resolution = (tmr->tempo * 1000) / tmr->ppq;
- else {
- /* might overflow.. */
- unsigned int s;
- s = tmr->tempo % tmr->ppq;
- s = (s * 1000) / tmr->ppq;
- tmr->tick.resolution = (tmr->tempo / tmr->ppq) * 1000;
- tmr->tick.resolution += s;
- }
- if (tmr->tick.resolution <= 0)
- tmr->tick.resolution = 1;
- snd_seq_timer_update_tick(&tmr->tick, 0);
-}
-
-/* create new timer (constructor) */
-struct snd_seq_timer *snd_seq_timer_new(void)
-{
- struct snd_seq_timer *tmr;
-
- tmr = kzalloc(sizeof(*tmr), GFP_KERNEL);
- if (tmr == NULL) {
- snd_printd("malloc failed for snd_seq_timer_new() \n");
- return NULL;
- }
- spin_lock_init(&tmr->lock);
-
- /* reset setup to defaults */
- snd_seq_timer_defaults(tmr);
-
- /* reset time */
- snd_seq_timer_reset(tmr);
-
- return tmr;
-}
-
-/* delete timer (destructor) */
-void snd_seq_timer_delete(struct snd_seq_timer **tmr)
-{
- struct snd_seq_timer *t = *tmr;
- *tmr = NULL;
-
- if (t == NULL) {
- snd_printd("oops: snd_seq_timer_delete() called with NULL timer\n");
- return;
- }
- t->running = 0;
-
- /* reset time */
- snd_seq_timer_stop(t);
- snd_seq_timer_reset(t);
-
- kfree(t);
-}
-
-void snd_seq_timer_defaults(struct snd_seq_timer * tmr)
-{
- /* setup defaults */
- tmr->ppq = 96; /* 96 PPQ */
- tmr->tempo = 500000; /* 120 BPM */
- snd_seq_timer_set_tick_resolution(tmr);
- tmr->running = 0;
-
- tmr->type = SNDRV_SEQ_TIMER_ALSA;
- tmr->alsa_id.dev_class = seq_default_timer_class;
- tmr->alsa_id.dev_sclass = seq_default_timer_sclass;
- tmr->alsa_id.card = seq_default_timer_card;
- tmr->alsa_id.device = seq_default_timer_device;
- tmr->alsa_id.subdevice = seq_default_timer_subdevice;
- tmr->preferred_resolution = seq_default_timer_resolution;
-
- tmr->skew = tmr->skew_base = SKEW_BASE;
-}
-
-void snd_seq_timer_reset(struct snd_seq_timer * tmr)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&tmr->lock, flags);
-
- /* reset time & songposition */
- tmr->cur_time.tv_sec = 0;
- tmr->cur_time.tv_nsec = 0;
-
- tmr->tick.cur_tick = 0;
- tmr->tick.fraction = 0;
-
- spin_unlock_irqrestore(&tmr->lock, flags);
-}
-
-
-/* called by timer interrupt routine. the period time since previous invocation is passed */
-static void snd_seq_timer_interrupt(struct snd_timer_instance *timeri,
- unsigned long resolution,
- unsigned long ticks)
-{
- unsigned long flags;
- struct snd_seq_queue *q = timeri->callback_data;
- struct snd_seq_timer *tmr;
-
- if (q == NULL)
- return;
- tmr = q->timer;
- if (tmr == NULL)
- return;
- if (!tmr->running)
- return;
-
- resolution *= ticks;
- if (tmr->skew != tmr->skew_base) {
- /* FIXME: assuming skew_base = 0x10000 */
- resolution = (resolution >> 16) * tmr->skew +
- (((resolution & 0xffff) * tmr->skew) >> 16);
- }
-
- spin_lock_irqsave(&tmr->lock, flags);
-
- /* update timer */
- snd_seq_inc_time_nsec(&tmr->cur_time, resolution);
-
- /* calculate current tick */
- snd_seq_timer_update_tick(&tmr->tick, resolution);
-
- /* register actual time of this timer update */
- do_gettimeofday(&tmr->last_update);
-
- spin_unlock_irqrestore(&tmr->lock, flags);
-
- /* check queues and dispatch events */
- snd_seq_check_queue(q, 1, 0);
-}
-
-/* set current tempo */
-int snd_seq_timer_set_tempo(struct snd_seq_timer * tmr, int tempo)
-{
- unsigned long flags;
-
- if (snd_BUG_ON(!tmr))
- return -EINVAL;
- if (tempo <= 0)
- return -EINVAL;
- spin_lock_irqsave(&tmr->lock, flags);
- if ((unsigned int)tempo != tmr->tempo) {
- tmr->tempo = tempo;
- snd_seq_timer_set_tick_resolution(tmr);
- }
- spin_unlock_irqrestore(&tmr->lock, flags);
- return 0;
-}
-
-/* set current ppq */
-int snd_seq_timer_set_ppq(struct snd_seq_timer * tmr, int ppq)
-{
- unsigned long flags;
-
- if (snd_BUG_ON(!tmr))
- return -EINVAL;
- if (ppq <= 0)
- return -EINVAL;
- spin_lock_irqsave(&tmr->lock, flags);
- if (tmr->running && (ppq != tmr->ppq)) {
- /* refuse to change ppq on running timers */
- /* because it will upset the song position (ticks) */
- spin_unlock_irqrestore(&tmr->lock, flags);
- snd_printd("seq: cannot change ppq of a running timer\n");
- return -EBUSY;
- }
-
- tmr->ppq = ppq;
- snd_seq_timer_set_tick_resolution(tmr);
- spin_unlock_irqrestore(&tmr->lock, flags);
- return 0;
-}
-
-/* set current tick position */
-int snd_seq_timer_set_position_tick(struct snd_seq_timer *tmr,
- snd_seq_tick_time_t position)
-{
- unsigned long flags;
-
- if (snd_BUG_ON(!tmr))
- return -EINVAL;
-
- spin_lock_irqsave(&tmr->lock, flags);
- tmr->tick.cur_tick = position;
- tmr->tick.fraction = 0;
- spin_unlock_irqrestore(&tmr->lock, flags);
- return 0;
-}
-
-/* set current real-time position */
-int snd_seq_timer_set_position_time(struct snd_seq_timer *tmr,
- snd_seq_real_time_t position)
-{
- unsigned long flags;
-
- if (snd_BUG_ON(!tmr))
- return -EINVAL;
-
- snd_seq_sanity_real_time(&position);
- spin_lock_irqsave(&tmr->lock, flags);
- tmr->cur_time = position;
- spin_unlock_irqrestore(&tmr->lock, flags);
- return 0;
-}
-
-/* set timer skew */
-int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew,
- unsigned int base)
-{
- unsigned long flags;
-
- if (snd_BUG_ON(!tmr))
- return -EINVAL;
-
- /* FIXME */
- if (base != SKEW_BASE) {
- snd_printd("invalid skew base 0x%x\n", base);
- return -EINVAL;
- }
- spin_lock_irqsave(&tmr->lock, flags);
- tmr->skew = skew;
- spin_unlock_irqrestore(&tmr->lock, flags);
- return 0;
-}
-
-int snd_seq_timer_open(struct snd_seq_queue *q)
-{
- struct snd_timer_instance *t;
- struct snd_seq_timer *tmr;
- char str[32];
- int err;
-
- tmr = q->timer;
- if (snd_BUG_ON(!tmr))
- return -EINVAL;
- if (tmr->timeri)
- return -EBUSY;
- sprintf(str, "sequencer queue %i", q->queue);
- if (tmr->type != SNDRV_SEQ_TIMER_ALSA) /* standard ALSA timer */
- return -EINVAL;
- if (tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_SLAVE)
- tmr->alsa_id.dev_sclass = SNDRV_TIMER_SCLASS_SEQUENCER;
- err = snd_timer_open(&t, str, &tmr->alsa_id, q->queue);
- if (err < 0 && tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_SLAVE) {
- if (tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_GLOBAL ||
- tmr->alsa_id.device != SNDRV_TIMER_GLOBAL_SYSTEM) {
- struct snd_timer_id tid;
- memset(&tid, 0, sizeof(tid));
- tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL;
- tid.dev_sclass = SNDRV_TIMER_SCLASS_SEQUENCER;
- tid.card = -1;
- tid.device = SNDRV_TIMER_GLOBAL_SYSTEM;
- err = snd_timer_open(&t, str, &tid, q->queue);
- }
- if (err < 0) {
- snd_printk(KERN_ERR "seq fatal error: cannot create timer (%i)\n", err);
- return err;
- }
- }
- t->callback = snd_seq_timer_interrupt;
- t->callback_data = q;
- t->flags |= SNDRV_TIMER_IFLG_AUTO;
- tmr->timeri = t;
- return 0;
-}
-
-int snd_seq_timer_close(struct snd_seq_queue *q)
-{
- struct snd_seq_timer *tmr;
-
- tmr = q->timer;
- if (snd_BUG_ON(!tmr))
- return -EINVAL;
- if (tmr->timeri) {
- snd_timer_stop(tmr->timeri);
- snd_timer_close(tmr->timeri);
- tmr->timeri = NULL;
- }
- return 0;
-}
-
-int snd_seq_timer_stop(struct snd_seq_timer * tmr)
-{
- if (! tmr->timeri)
- return -EINVAL;
- if (!tmr->running)
- return 0;
- tmr->running = 0;
- snd_timer_pause(tmr->timeri);
- return 0;
-}
-
-static int initialize_timer(struct snd_seq_timer *tmr)
-{
- struct snd_timer *t;
- unsigned long freq;
-
- t = tmr->timeri->timer;
- if (snd_BUG_ON(!t))
- return -EINVAL;
-
- freq = tmr->preferred_resolution;
- if (!freq)
- freq = DEFAULT_FREQUENCY;
- else if (freq < MIN_FREQUENCY)
- freq = MIN_FREQUENCY;
- else if (freq > MAX_FREQUENCY)
- freq = MAX_FREQUENCY;
-
- tmr->ticks = 1;
- if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) {
- unsigned long r = t->hw.resolution;
- if (! r && t->hw.c_resolution)
- r = t->hw.c_resolution(t);
- if (r) {
- tmr->ticks = (unsigned int)(1000000000uL / (r * freq));
- if (! tmr->ticks)
- tmr->ticks = 1;
- }
- }
- tmr->initialized = 1;
- return 0;
-}
-
-int snd_seq_timer_start(struct snd_seq_timer * tmr)
-{
- if (! tmr->timeri)
- return -EINVAL;
- if (tmr->running)
- snd_seq_timer_stop(tmr);
- snd_seq_timer_reset(tmr);
- if (initialize_timer(tmr) < 0)
- return -EINVAL;
- snd_timer_start(tmr->timeri, tmr->ticks);
- tmr->running = 1;
- do_gettimeofday(&tmr->last_update);
- return 0;
-}
-
-int snd_seq_timer_continue(struct snd_seq_timer * tmr)
-{
- if (! tmr->timeri)
- return -EINVAL;
- if (tmr->running)
- return -EBUSY;
- if (! tmr->initialized) {
- snd_seq_timer_reset(tmr);
- if (initialize_timer(tmr) < 0)
- return -EINVAL;
- }
- snd_timer_start(tmr->timeri, tmr->ticks);
- tmr->running = 1;
- do_gettimeofday(&tmr->last_update);
- return 0;
-}
-
-/* return current 'real' time. use timeofday() to get better granularity. */
-snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr)
-{
- snd_seq_real_time_t cur_time;
-
- cur_time = tmr->cur_time;
- if (tmr->running) {
- struct timeval tm;
- int usec;
- do_gettimeofday(&tm);
- usec = (int)(tm.tv_usec - tmr->last_update.tv_usec);
- if (usec < 0) {
- cur_time.tv_nsec += (1000000 + usec) * 1000;
- cur_time.tv_sec += tm.tv_sec - tmr->last_update.tv_sec - 1;
- } else {
- cur_time.tv_nsec += usec * 1000;
- cur_time.tv_sec += tm.tv_sec - tmr->last_update.tv_sec;
- }
- snd_seq_sanity_real_time(&cur_time);
- }
-
- return cur_time;
-}
-
-/* TODO: use interpolation on tick queue (will only be useful for very
- high PPQ values) */
-snd_seq_tick_time_t snd_seq_timer_get_cur_tick(struct snd_seq_timer *tmr)
-{
- return tmr->tick.cur_tick;
-}
-
-
-#ifdef CONFIG_PROC_FS
-/* exported to seq_info.c */
-void snd_seq_info_timer_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- int idx;
- struct snd_seq_queue *q;
- struct snd_seq_timer *tmr;
- struct snd_timer_instance *ti;
- unsigned long resolution;
-
- for (idx = 0; idx < SNDRV_SEQ_MAX_QUEUES; idx++) {
- q = queueptr(idx);
- if (q == NULL)
- continue;
- if ((tmr = q->timer) == NULL ||
- (ti = tmr->timeri) == NULL) {
- queuefree(q);
- continue;
- }
- snd_iprintf(buffer, "Timer for queue %i : %s\n", q->queue, ti->timer->name);
- resolution = snd_timer_resolution(ti) * tmr->ticks;
- snd_iprintf(buffer, " Period time : %lu.%09lu\n", resolution / 1000000000, resolution % 1000000000);
- snd_iprintf(buffer, " Skew : %u / %u\n", tmr->skew, tmr->skew_base);
- queuefree(q);
- }
-}
-#endif /* CONFIG_PROC_FS */
-
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_timer.h b/ANDROID_3.4.5/sound/core/seq/seq_timer.h
deleted file mode 100644
index 88dfb718..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_timer.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * ALSA sequencer Timer
- * Copyright (c) 1998-1999 by Frank van de Pol <fvdpol@coil.demon.nl>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __SND_SEQ_TIMER_H
-#define __SND_SEQ_TIMER_H
-
-#include <sound/timer.h>
-#include <sound/seq_kernel.h>
-
-struct snd_seq_timer_tick {
- snd_seq_tick_time_t cur_tick; /* current tick */
- unsigned long resolution; /* time per tick in nsec */
- unsigned long fraction; /* current time per tick in nsec */
-};
-
-struct snd_seq_timer {
- /* ... tempo / offset / running state */
-
- unsigned int running:1, /* running state of queue */
- initialized:1; /* timer is initialized */
-
- unsigned int tempo; /* current tempo, us/tick */
- int ppq; /* time resolution, ticks/quarter */
-
- snd_seq_real_time_t cur_time; /* current time */
- struct snd_seq_timer_tick tick; /* current tick */
- int tick_updated;
-
- int type; /* timer type */
- struct snd_timer_id alsa_id; /* ALSA's timer ID */
- struct snd_timer_instance *timeri; /* timer instance */
- unsigned int ticks;
- unsigned long preferred_resolution; /* timer resolution, ticks/sec */
-
- unsigned int skew;
- unsigned int skew_base;
-
- struct timeval last_update; /* time of last clock update, used for interpolation */
-
- spinlock_t lock;
-};
-
-
-/* create new timer (constructor) */
-struct snd_seq_timer *snd_seq_timer_new(void);
-
-/* delete timer (destructor) */
-void snd_seq_timer_delete(struct snd_seq_timer **tmr);
-
-/* */
-static inline void snd_seq_timer_update_tick(struct snd_seq_timer_tick *tick,
- unsigned long resolution)
-{
- if (tick->resolution > 0) {
- tick->fraction += resolution;
- tick->cur_tick += (unsigned int)(tick->fraction / tick->resolution);
- tick->fraction %= tick->resolution;
- }
-}
-
-
-/* compare timestamp between events */
-/* return 1 if a >= b; otherwise return 0 */
-static inline int snd_seq_compare_tick_time(snd_seq_tick_time_t *a, snd_seq_tick_time_t *b)
-{
- /* compare ticks */
- return (*a >= *b);
-}
-
-static inline int snd_seq_compare_real_time(snd_seq_real_time_t *a, snd_seq_real_time_t *b)
-{
- /* compare real time */
- if (a->tv_sec > b->tv_sec)
- return 1;
- if ((a->tv_sec == b->tv_sec) && (a->tv_nsec >= b->tv_nsec))
- return 1;
- return 0;
-}
-
-
-static inline void snd_seq_sanity_real_time(snd_seq_real_time_t *tm)
-{
- while (tm->tv_nsec >= 1000000000) {
- /* roll-over */
- tm->tv_nsec -= 1000000000;
- tm->tv_sec++;
- }
-}
-
-
-/* increment timestamp */
-static inline void snd_seq_inc_real_time(snd_seq_real_time_t *tm, snd_seq_real_time_t *inc)
-{
- tm->tv_sec += inc->tv_sec;
- tm->tv_nsec += inc->tv_nsec;
- snd_seq_sanity_real_time(tm);
-}
-
-static inline void snd_seq_inc_time_nsec(snd_seq_real_time_t *tm, unsigned long nsec)
-{
- tm->tv_nsec += nsec;
- snd_seq_sanity_real_time(tm);
-}
-
-/* called by timer isr */
-struct snd_seq_queue;
-int snd_seq_timer_open(struct snd_seq_queue *q);
-int snd_seq_timer_close(struct snd_seq_queue *q);
-int snd_seq_timer_midi_open(struct snd_seq_queue *q);
-int snd_seq_timer_midi_close(struct snd_seq_queue *q);
-void snd_seq_timer_defaults(struct snd_seq_timer *tmr);
-void snd_seq_timer_reset(struct snd_seq_timer *tmr);
-int snd_seq_timer_stop(struct snd_seq_timer *tmr);
-int snd_seq_timer_start(struct snd_seq_timer *tmr);
-int snd_seq_timer_continue(struct snd_seq_timer *tmr);
-int snd_seq_timer_set_tempo(struct snd_seq_timer *tmr, int tempo);
-int snd_seq_timer_set_ppq(struct snd_seq_timer *tmr, int ppq);
-int snd_seq_timer_set_position_tick(struct snd_seq_timer *tmr, snd_seq_tick_time_t position);
-int snd_seq_timer_set_position_time(struct snd_seq_timer *tmr, snd_seq_real_time_t position);
-int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew, unsigned int base);
-snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr);
-snd_seq_tick_time_t snd_seq_timer_get_cur_tick(struct snd_seq_timer *tmr);
-
-extern int seq_default_timer_class;
-extern int seq_default_timer_sclass;
-extern int seq_default_timer_card;
-extern int seq_default_timer_device;
-extern int seq_default_timer_subdevice;
-extern int seq_default_timer_resolution;
-
-#endif
diff --git a/ANDROID_3.4.5/sound/core/seq/seq_virmidi.c b/ANDROID_3.4.5/sound/core/seq/seq_virmidi.c
deleted file mode 100644
index 4b50e604..00000000
--- a/ANDROID_3.4.5/sound/core/seq/seq_virmidi.c
+++ /dev/null
@@ -1,543 +0,0 @@
-/*
- * Virtual Raw MIDI client on Sequencer
- *
- * Copyright (c) 2000 by Takashi Iwai <tiwai@suse.de>,
- * Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- * Virtual Raw MIDI client
- *
- * The virtual rawmidi client is a sequencer client which associate
- * a rawmidi device file. The created rawmidi device file can be
- * accessed as a normal raw midi, but its MIDI source and destination
- * are arbitrary. For example, a user-client software synth connected
- * to this port can be used as a normal midi device as well.
- *
- * The virtual rawmidi device accepts also multiple opens. Each file
- * has its own input buffer, so that no conflict would occur. The drain
- * of input/output buffer acts only to the local buffer.
- *
- */
-
-#include <linux/init.h>
-#include <linux/wait.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/rawmidi.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/minors.h>
-#include <sound/seq_kernel.h>
-#include <sound/seq_midi_event.h>
-#include <sound/seq_virmidi.h>
-
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("Virtual Raw MIDI client on Sequencer");
-MODULE_LICENSE("GPL");
-
-/*
- * initialize an event record
- */
-static void snd_virmidi_init_event(struct snd_virmidi *vmidi,
- struct snd_seq_event *ev)
-{
- memset(ev, 0, sizeof(*ev));
- ev->source.port = vmidi->port;
- switch (vmidi->seq_mode) {
- case SNDRV_VIRMIDI_SEQ_DISPATCH:
- ev->dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS;
- break;
- case SNDRV_VIRMIDI_SEQ_ATTACH:
- /* FIXME: source and destination are same - not good.. */
- ev->dest.client = vmidi->client;
- ev->dest.port = vmidi->port;
- break;
- }
- ev->type = SNDRV_SEQ_EVENT_NONE;
-}
-
-/*
- * decode input event and put to read buffer of each opened file
- */
-static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev,
- struct snd_seq_event *ev)
-{
- struct snd_virmidi *vmidi;
- unsigned char msg[4];
- int len;
-
- read_lock(&rdev->filelist_lock);
- list_for_each_entry(vmidi, &rdev->filelist, list) {
- if (!vmidi->trigger)
- continue;
- if (ev->type == SNDRV_SEQ_EVENT_SYSEX) {
- if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE)
- continue;
- snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)snd_rawmidi_receive, vmidi->substream);
- } else {
- len = snd_midi_event_decode(vmidi->parser, msg, sizeof(msg), ev);
- if (len > 0)
- snd_rawmidi_receive(vmidi->substream, msg, len);
- }
- }
- read_unlock(&rdev->filelist_lock);
-
- return 0;
-}
-
-/*
- * receive an event from the remote virmidi port
- *
- * for rawmidi inputs, you can call this function from the event
- * handler of a remote port which is attached to the virmidi via
- * SNDRV_VIRMIDI_SEQ_ATTACH.
- */
-#if 0
-int snd_virmidi_receive(struct snd_rawmidi *rmidi, struct snd_seq_event *ev)
-{
- struct snd_virmidi_dev *rdev;
-
- rdev = rmidi->private_data;
- return snd_virmidi_dev_receive_event(rdev, ev);
-}
-#endif /* 0 */
-
-/*
- * event handler of virmidi port
- */
-static int snd_virmidi_event_input(struct snd_seq_event *ev, int direct,
- void *private_data, int atomic, int hop)
-{
- struct snd_virmidi_dev *rdev;
-
- rdev = private_data;
- if (!(rdev->flags & SNDRV_VIRMIDI_USE))
- return 0; /* ignored */
- return snd_virmidi_dev_receive_event(rdev, ev);
-}
-
-/*
- * trigger rawmidi stream for input
- */
-static void snd_virmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct snd_virmidi *vmidi = substream->runtime->private_data;
-
- if (up) {
- vmidi->trigger = 1;
- } else {
- vmidi->trigger = 0;
- }
-}
-
-/*
- * trigger rawmidi stream for output
- */
-static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct snd_virmidi *vmidi = substream->runtime->private_data;
- int count, res;
- unsigned char buf[32], *pbuf;
-
- if (up) {
- vmidi->trigger = 1;
- if (vmidi->seq_mode == SNDRV_VIRMIDI_SEQ_DISPATCH &&
- !(vmidi->rdev->flags & SNDRV_VIRMIDI_SUBSCRIBE)) {
- snd_rawmidi_transmit_ack(substream, substream->runtime->buffer_size - substream->runtime->avail);
- return; /* ignored */
- }
- if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
- if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
- return;
- vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
- }
- while (1) {
- count = snd_rawmidi_transmit_peek(substream, buf, sizeof(buf));
- if (count <= 0)
- break;
- pbuf = buf;
- while (count > 0) {
- res = snd_midi_event_encode(vmidi->parser, pbuf, count, &vmidi->event);
- if (res < 0) {
- snd_midi_event_reset_encode(vmidi->parser);
- continue;
- }
- snd_rawmidi_transmit_ack(substream, res);
- pbuf += res;
- count -= res;
- if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
- if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
- return;
- vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
- }
- }
- }
- } else {
- vmidi->trigger = 0;
- }
-}
-
-/*
- * open rawmidi handle for input
- */
-static int snd_virmidi_input_open(struct snd_rawmidi_substream *substream)
-{
- struct snd_virmidi_dev *rdev = substream->rmidi->private_data;
- struct snd_rawmidi_runtime *runtime = substream->runtime;
- struct snd_virmidi *vmidi;
- unsigned long flags;
-
- vmidi = kzalloc(sizeof(*vmidi), GFP_KERNEL);
- if (vmidi == NULL)
- return -ENOMEM;
- vmidi->substream = substream;
- if (snd_midi_event_new(0, &vmidi->parser) < 0) {
- kfree(vmidi);
- return -ENOMEM;
- }
- vmidi->seq_mode = rdev->seq_mode;
- vmidi->client = rdev->client;
- vmidi->port = rdev->port;
- runtime->private_data = vmidi;
- write_lock_irqsave(&rdev->filelist_lock, flags);
- list_add_tail(&vmidi->list, &rdev->filelist);
- write_unlock_irqrestore(&rdev->filelist_lock, flags);
- vmidi->rdev = rdev;
- return 0;
-}
-
-/*
- * open rawmidi handle for output
- */
-static int snd_virmidi_output_open(struct snd_rawmidi_substream *substream)
-{
- struct snd_virmidi_dev *rdev = substream->rmidi->private_data;
- struct snd_rawmidi_runtime *runtime = substream->runtime;
- struct snd_virmidi *vmidi;
-
- vmidi = kzalloc(sizeof(*vmidi), GFP_KERNEL);
- if (vmidi == NULL)
- return -ENOMEM;
- vmidi->substream = substream;
- if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &vmidi->parser) < 0) {
- kfree(vmidi);
- return -ENOMEM;
- }
- vmidi->seq_mode = rdev->seq_mode;
- vmidi->client = rdev->client;
- vmidi->port = rdev->port;
- snd_virmidi_init_event(vmidi, &vmidi->event);
- vmidi->rdev = rdev;
- runtime->private_data = vmidi;
- return 0;
-}
-
-/*
- * close rawmidi handle for input
- */
-static int snd_virmidi_input_close(struct snd_rawmidi_substream *substream)
-{
- struct snd_virmidi *vmidi = substream->runtime->private_data;
- snd_midi_event_free(vmidi->parser);
- list_del(&vmidi->list);
- substream->runtime->private_data = NULL;
- kfree(vmidi);
- return 0;
-}
-
-/*
- * close rawmidi handle for output
- */
-static int snd_virmidi_output_close(struct snd_rawmidi_substream *substream)
-{
- struct snd_virmidi *vmidi = substream->runtime->private_data;
- snd_midi_event_free(vmidi->parser);
- substream->runtime->private_data = NULL;
- kfree(vmidi);
- return 0;
-}
-
-/*
- * subscribe callback - allow output to rawmidi device
- */
-static int snd_virmidi_subscribe(void *private_data,
- struct snd_seq_port_subscribe *info)
-{
- struct snd_virmidi_dev *rdev;
-
- rdev = private_data;
- if (!try_module_get(rdev->card->module))
- return -EFAULT;
- rdev->flags |= SNDRV_VIRMIDI_SUBSCRIBE;
- return 0;
-}
-
-/*
- * unsubscribe callback - disallow output to rawmidi device
- */
-static int snd_virmidi_unsubscribe(void *private_data,
- struct snd_seq_port_subscribe *info)
-{
- struct snd_virmidi_dev *rdev;
-
- rdev = private_data;
- rdev->flags &= ~SNDRV_VIRMIDI_SUBSCRIBE;
- module_put(rdev->card->module);
- return 0;
-}
-
-
-/*
- * use callback - allow input to rawmidi device
- */
-static int snd_virmidi_use(void *private_data,
- struct snd_seq_port_subscribe *info)
-{
- struct snd_virmidi_dev *rdev;
-
- rdev = private_data;
- if (!try_module_get(rdev->card->module))
- return -EFAULT;
- rdev->flags |= SNDRV_VIRMIDI_USE;
- return 0;
-}
-
-/*
- * unuse callback - disallow input to rawmidi device
- */
-static int snd_virmidi_unuse(void *private_data,
- struct snd_seq_port_subscribe *info)
-{
- struct snd_virmidi_dev *rdev;
-
- rdev = private_data;
- rdev->flags &= ~SNDRV_VIRMIDI_USE;
- module_put(rdev->card->module);
- return 0;
-}
-
-
-/*
- * Register functions
- */
-
-static struct snd_rawmidi_ops snd_virmidi_input_ops = {
- .open = snd_virmidi_input_open,
- .close = snd_virmidi_input_close,
- .trigger = snd_virmidi_input_trigger,
-};
-
-static struct snd_rawmidi_ops snd_virmidi_output_ops = {
- .open = snd_virmidi_output_open,
- .close = snd_virmidi_output_close,
- .trigger = snd_virmidi_output_trigger,
-};
-
-/*
- * create a sequencer client and a port
- */
-static int snd_virmidi_dev_attach_seq(struct snd_virmidi_dev *rdev)
-{
- int client;
- struct snd_seq_port_callback pcallbacks;
- struct snd_seq_port_info *pinfo;
- int err;
-
- if (rdev->client >= 0)
- return 0;
-
- pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL);
- if (!pinfo) {
- err = -ENOMEM;
- goto __error;
- }
-
- client = snd_seq_create_kernel_client(rdev->card, rdev->device,
- "%s %d-%d", rdev->rmidi->name,
- rdev->card->number,
- rdev->device);
- if (client < 0) {
- err = client;
- goto __error;
- }
- rdev->client = client;
-
- /* create a port */
- pinfo->addr.client = client;
- sprintf(pinfo->name, "VirMIDI %d-%d", rdev->card->number, rdev->device);
- /* set all capabilities */
- pinfo->capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SYNC_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
- pinfo->capability |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SYNC_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ;
- pinfo->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX;
- pinfo->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC
- | SNDRV_SEQ_PORT_TYPE_SOFTWARE
- | SNDRV_SEQ_PORT_TYPE_PORT;
- pinfo->midi_channels = 16;
- memset(&pcallbacks, 0, sizeof(pcallbacks));
- pcallbacks.owner = THIS_MODULE;
- pcallbacks.private_data = rdev;
- pcallbacks.subscribe = snd_virmidi_subscribe;
- pcallbacks.unsubscribe = snd_virmidi_unsubscribe;
- pcallbacks.use = snd_virmidi_use;
- pcallbacks.unuse = snd_virmidi_unuse;
- pcallbacks.event_input = snd_virmidi_event_input;
- pinfo->kernel = &pcallbacks;
- err = snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_CREATE_PORT, pinfo);
- if (err < 0) {
- snd_seq_delete_kernel_client(client);
- rdev->client = -1;
- goto __error;
- }
-
- rdev->port = pinfo->addr.port;
- err = 0; /* success */
-
- __error:
- kfree(pinfo);
- return err;
-}
-
-
-/*
- * release the sequencer client
- */
-static void snd_virmidi_dev_detach_seq(struct snd_virmidi_dev *rdev)
-{
- if (rdev->client >= 0) {
- snd_seq_delete_kernel_client(rdev->client);
- rdev->client = -1;
- }
-}
-
-/*
- * register the device
- */
-static int snd_virmidi_dev_register(struct snd_rawmidi *rmidi)
-{
- struct snd_virmidi_dev *rdev = rmidi->private_data;
- int err;
-
- switch (rdev->seq_mode) {
- case SNDRV_VIRMIDI_SEQ_DISPATCH:
- err = snd_virmidi_dev_attach_seq(rdev);
- if (err < 0)
- return err;
- break;
- case SNDRV_VIRMIDI_SEQ_ATTACH:
- if (rdev->client == 0)
- return -EINVAL;
- /* should check presence of port more strictly.. */
- break;
- default:
- snd_printk(KERN_ERR "seq_mode is not set: %d\n", rdev->seq_mode);
- return -EINVAL;
- }
- return 0;
-}
-
-
-/*
- * unregister the device
- */
-static int snd_virmidi_dev_unregister(struct snd_rawmidi *rmidi)
-{
- struct snd_virmidi_dev *rdev = rmidi->private_data;
-
- if (rdev->seq_mode == SNDRV_VIRMIDI_SEQ_DISPATCH)
- snd_virmidi_dev_detach_seq(rdev);
- return 0;
-}
-
-/*
- *
- */
-static struct snd_rawmidi_global_ops snd_virmidi_global_ops = {
- .dev_register = snd_virmidi_dev_register,
- .dev_unregister = snd_virmidi_dev_unregister,
-};
-
-/*
- * free device
- */
-static void snd_virmidi_free(struct snd_rawmidi *rmidi)
-{
- struct snd_virmidi_dev *rdev = rmidi->private_data;
- kfree(rdev);
-}
-
-/*
- * create a new device
- *
- */
-/* exported */
-int snd_virmidi_new(struct snd_card *card, int device, struct snd_rawmidi **rrmidi)
-{
- struct snd_rawmidi *rmidi;
- struct snd_virmidi_dev *rdev;
- int err;
-
- *rrmidi = NULL;
- if ((err = snd_rawmidi_new(card, "VirMidi", device,
- 16, /* may be configurable */
- 16, /* may be configurable */
- &rmidi)) < 0)
- return err;
- strcpy(rmidi->name, rmidi->id);
- rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
- if (rdev == NULL) {
- snd_device_free(card, rmidi);
- return -ENOMEM;
- }
- rdev->card = card;
- rdev->rmidi = rmidi;
- rdev->device = device;
- rdev->client = -1;
- rwlock_init(&rdev->filelist_lock);
- INIT_LIST_HEAD(&rdev->filelist);
- rdev->seq_mode = SNDRV_VIRMIDI_SEQ_DISPATCH;
- rmidi->private_data = rdev;
- rmidi->private_free = snd_virmidi_free;
- rmidi->ops = &snd_virmidi_global_ops;
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_virmidi_input_ops);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_virmidi_output_ops);
- rmidi->info_flags = SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
- *rrmidi = rmidi;
- return 0;
-}
-
-/*
- * ENTRY functions
- */
-
-static int __init alsa_virmidi_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_virmidi_exit(void)
-{
-}
-
-module_init(alsa_virmidi_init)
-module_exit(alsa_virmidi_exit)
-
-EXPORT_SYMBOL(snd_virmidi_new);
diff --git a/ANDROID_3.4.5/sound/core/sgbuf.c b/ANDROID_3.4.5/sound/core/sgbuf.c
deleted file mode 100644
index 4e7ec2b4..00000000
--- a/ANDROID_3.4.5/sound/core/sgbuf.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Scatter-Gather buffer
- *
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <sound/memalloc.h>
-
-
-/* table entries are align to 32 */
-#define SGBUF_TBL_ALIGN 32
-#define sgbuf_align_table(tbl) ALIGN((tbl), SGBUF_TBL_ALIGN)
-
-int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab)
-{
- struct snd_sg_buf *sgbuf = dmab->private_data;
- struct snd_dma_buffer tmpb;
- int i;
-
- if (! sgbuf)
- return -EINVAL;
-
- if (dmab->area)
- vunmap(dmab->area);
- dmab->area = NULL;
-
- tmpb.dev.type = SNDRV_DMA_TYPE_DEV;
- tmpb.dev.dev = sgbuf->dev;
- for (i = 0; i < sgbuf->pages; i++) {
- if (!(sgbuf->table[i].addr & ~PAGE_MASK))
- continue; /* continuous pages */
- tmpb.area = sgbuf->table[i].buf;
- tmpb.addr = sgbuf->table[i].addr & PAGE_MASK;
- tmpb.bytes = (sgbuf->table[i].addr & ~PAGE_MASK) << PAGE_SHIFT;
- snd_dma_free_pages(&tmpb);
- }
-
- kfree(sgbuf->table);
- kfree(sgbuf->page_table);
- kfree(sgbuf);
- dmab->private_data = NULL;
-
- return 0;
-}
-
-#define MAX_ALLOC_PAGES 32
-
-void *snd_malloc_sgbuf_pages(struct device *device,
- size_t size, struct snd_dma_buffer *dmab,
- size_t *res_size)
-{
- struct snd_sg_buf *sgbuf;
- unsigned int i, pages, chunk, maxpages;
- struct snd_dma_buffer tmpb;
- struct snd_sg_page *table;
- struct page **pgtable;
-
- dmab->area = NULL;
- dmab->addr = 0;
- dmab->private_data = sgbuf = kzalloc(sizeof(*sgbuf), GFP_KERNEL);
- if (! sgbuf)
- return NULL;
- sgbuf->dev = device;
- pages = snd_sgbuf_aligned_pages(size);
- sgbuf->tblsize = sgbuf_align_table(pages);
- table = kcalloc(sgbuf->tblsize, sizeof(*table), GFP_KERNEL);
- if (!table)
- goto _failed;
- sgbuf->table = table;
- pgtable = kcalloc(sgbuf->tblsize, sizeof(*pgtable), GFP_KERNEL);
- if (!pgtable)
- goto _failed;
- sgbuf->page_table = pgtable;
-
- /* allocate pages */
- maxpages = MAX_ALLOC_PAGES;
- while (pages > 0) {
- chunk = pages;
- /* don't be too eager to take a huge chunk */
- if (chunk > maxpages)
- chunk = maxpages;
- chunk <<= PAGE_SHIFT;
- if (snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV, device,
- chunk, &tmpb) < 0) {
- if (!sgbuf->pages)
- return NULL;
- if (!res_size)
- goto _failed;
- size = sgbuf->pages * PAGE_SIZE;
- break;
- }
- chunk = tmpb.bytes >> PAGE_SHIFT;
- for (i = 0; i < chunk; i++) {
- table->buf = tmpb.area;
- table->addr = tmpb.addr;
- if (!i)
- table->addr |= chunk; /* mark head */
- table++;
- *pgtable++ = virt_to_page(tmpb.area);
- tmpb.area += PAGE_SIZE;
- tmpb.addr += PAGE_SIZE;
- }
- sgbuf->pages += chunk;
- pages -= chunk;
- if (chunk < maxpages)
- maxpages = chunk;
- }
-
- sgbuf->size = size;
- dmab->area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP, PAGE_KERNEL);
- if (! dmab->area)
- goto _failed;
- if (res_size)
- *res_size = sgbuf->size;
- return dmab->area;
-
- _failed:
- snd_free_sgbuf_pages(dmab); /* free the table */
- return NULL;
-}
diff --git a/ANDROID_3.4.5/sound/core/sound.c b/ANDROID_3.4.5/sound/core/sound.c
deleted file mode 100644
index 3700d96f..00000000
--- a/ANDROID_3.4.5/sound/core/sound.c
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * Advanced Linux Sound Architecture
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/minors.h>
-#include <sound/info.h>
-#include <sound/version.h>
-#include <sound/control.h>
-#include <sound/initval.h>
-#include <linux/kmod.h>
-#include <linux/mutex.h>
-
-static int major = CONFIG_SND_MAJOR;
-int snd_major;
-EXPORT_SYMBOL(snd_major);
-
-static int cards_limit = 1;
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Advanced Linux Sound Architecture driver for soundcards.");
-MODULE_LICENSE("GPL");
-module_param(major, int, 0444);
-MODULE_PARM_DESC(major, "Major # for sound driver.");
-module_param(cards_limit, int, 0444);
-MODULE_PARM_DESC(cards_limit, "Count of auto-loadable soundcards.");
-MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR);
-
-/* this one holds the actual max. card number currently available.
- * as default, it's identical with cards_limit option. when more
- * modules are loaded manually, this limit number increases, too.
- */
-int snd_ecards_limit;
-EXPORT_SYMBOL(snd_ecards_limit);
-
-static struct snd_minor *snd_minors[SNDRV_OS_MINORS];
-static DEFINE_MUTEX(sound_mutex);
-
-#ifdef CONFIG_MODULES
-
-/**
- * snd_request_card - try to load the card module
- * @card: the card number
- *
- * Tries to load the module "snd-card-X" for the given card number
- * via request_module. Returns immediately if already loaded.
- */
-void snd_request_card(int card)
-{
- if (snd_card_locked(card))
- return;
- if (card < 0 || card >= cards_limit)
- return;
- request_module("snd-card-%i", card);
-}
-
-EXPORT_SYMBOL(snd_request_card);
-
-static void snd_request_other(int minor)
-{
- char *str;
-
- switch (minor) {
- case SNDRV_MINOR_SEQUENCER: str = "snd-seq"; break;
- case SNDRV_MINOR_TIMER: str = "snd-timer"; break;
- default: return;
- }
- request_module(str);
-}
-
-#endif /* modular kernel */
-
-/**
- * snd_lookup_minor_data - get user data of a registered device
- * @minor: the minor number
- * @type: device type (SNDRV_DEVICE_TYPE_XXX)
- *
- * Checks that a minor device with the specified type is registered, and returns
- * its user data pointer.
- *
- * This function increments the reference counter of the card instance
- * if an associated instance with the given minor number and type is found.
- * The caller must call snd_card_unref() appropriately later.
- */
-void *snd_lookup_minor_data(unsigned int minor, int type)
-{
- struct snd_minor *mreg;
- void *private_data;
-
- if (minor >= ARRAY_SIZE(snd_minors))
- return NULL;
- mutex_lock(&sound_mutex);
- mreg = snd_minors[minor];
- if (mreg && mreg->type == type) {
- private_data = mreg->private_data;
- if (private_data && mreg->card_ptr)
- atomic_inc(&mreg->card_ptr->refcount);
- } else
- private_data = NULL;
- mutex_unlock(&sound_mutex);
- return private_data;
-}
-
-EXPORT_SYMBOL(snd_lookup_minor_data);
-
-#ifdef CONFIG_MODULES
-static struct snd_minor *autoload_device(unsigned int minor)
-{
- int dev;
- mutex_unlock(&sound_mutex); /* release lock temporarily */
- dev = SNDRV_MINOR_DEVICE(minor);
- if (dev == SNDRV_MINOR_CONTROL) {
- /* /dev/aloadC? */
- int card = SNDRV_MINOR_CARD(minor);
- if (snd_cards[card] == NULL)
- snd_request_card(card);
- } else if (dev == SNDRV_MINOR_GLOBAL) {
- /* /dev/aloadSEQ */
- snd_request_other(minor);
- }
- mutex_lock(&sound_mutex); /* reacuire lock */
- return snd_minors[minor];
-}
-#else /* !CONFIG_MODULES */
-#define autoload_device(minor) NULL
-#endif /* CONFIG_MODULES */
-
-static int snd_open(struct inode *inode, struct file *file)
-{
- unsigned int minor = iminor(inode);
- struct snd_minor *mptr = NULL;
- const struct file_operations *old_fops;
- int err = 0;
-
- if (minor >= ARRAY_SIZE(snd_minors))
- return -ENODEV;
- mutex_lock(&sound_mutex);
- mptr = snd_minors[minor];
- if (mptr == NULL) {
- mptr = autoload_device(minor);
- if (!mptr) {
- mutex_unlock(&sound_mutex);
- return -ENODEV;
- }
- }
- old_fops = file->f_op;
- file->f_op = fops_get(mptr->f_ops);
- if (file->f_op == NULL) {
- file->f_op = old_fops;
- err = -ENODEV;
- }
- mutex_unlock(&sound_mutex);
- if (err < 0)
- return err;
-
- if (file->f_op->open) {
- err = file->f_op->open(inode, file);
- if (err) {
- fops_put(file->f_op);
- file->f_op = fops_get(old_fops);
- }
- }
- fops_put(old_fops);
- return err;
-}
-
-static const struct file_operations snd_fops =
-{
- .owner = THIS_MODULE,
- .open = snd_open,
- .llseek = noop_llseek,
-};
-
-#ifdef CONFIG_SND_DYNAMIC_MINORS
-static int snd_find_free_minor(int type)
-{
- int minor;
-
- /* static minors for module auto loading */
- if (type == SNDRV_DEVICE_TYPE_SEQUENCER)
- return SNDRV_MINOR_SEQUENCER;
- if (type == SNDRV_DEVICE_TYPE_TIMER)
- return SNDRV_MINOR_TIMER;
-
- for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) {
- /* skip static minors still used for module auto loading */
- if (SNDRV_MINOR_DEVICE(minor) == SNDRV_MINOR_CONTROL)
- continue;
- if (minor == SNDRV_MINOR_SEQUENCER ||
- minor == SNDRV_MINOR_TIMER)
- continue;
- if (!snd_minors[minor])
- return minor;
- }
- return -EBUSY;
-}
-#else
-static int snd_kernel_minor(int type, struct snd_card *card, int dev)
-{
- int minor;
-
- switch (type) {
- case SNDRV_DEVICE_TYPE_SEQUENCER:
- case SNDRV_DEVICE_TYPE_TIMER:
- minor = type;
- break;
- case SNDRV_DEVICE_TYPE_CONTROL:
- if (snd_BUG_ON(!card))
- return -EINVAL;
- minor = SNDRV_MINOR(card->number, type);
- break;
- case SNDRV_DEVICE_TYPE_HWDEP:
- case SNDRV_DEVICE_TYPE_RAWMIDI:
- case SNDRV_DEVICE_TYPE_PCM_PLAYBACK:
- case SNDRV_DEVICE_TYPE_PCM_CAPTURE:
- case SNDRV_DEVICE_TYPE_COMPRESS:
- if (snd_BUG_ON(!card))
- return -EINVAL;
- minor = SNDRV_MINOR(card->number, type + dev);
- break;
- default:
- return -EINVAL;
- }
- if (snd_BUG_ON(minor < 0 || minor >= SNDRV_OS_MINORS))
- return -EINVAL;
- return minor;
-}
-#endif
-
-/**
- * snd_register_device_for_dev - Register the ALSA device file for the card
- * @type: the device type, SNDRV_DEVICE_TYPE_XXX
- * @card: the card instance
- * @dev: the device index
- * @f_ops: the file operations
- * @private_data: user pointer for f_ops->open()
- * @name: the device file name
- * @device: the &struct device to link this new device to
- *
- * Registers an ALSA device file for the given card.
- * The operators have to be set in reg parameter.
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
- const struct file_operations *f_ops,
- void *private_data,
- const char *name, struct device *device)
-{
- int minor;
- struct snd_minor *preg;
-
- if (snd_BUG_ON(!name))
- return -EINVAL;
- preg = kmalloc(sizeof *preg, GFP_KERNEL);
- if (preg == NULL)
- return -ENOMEM;
- preg->type = type;
- preg->card = card ? card->number : -1;
- preg->device = dev;
- preg->f_ops = f_ops;
- preg->private_data = private_data;
- preg->card_ptr = card;
- mutex_lock(&sound_mutex);
-#ifdef CONFIG_SND_DYNAMIC_MINORS
- minor = snd_find_free_minor(type);
-#else
- minor = snd_kernel_minor(type, card, dev);
- if (minor >= 0 && snd_minors[minor])
- minor = -EBUSY;
-#endif
- if (minor < 0) {
- mutex_unlock(&sound_mutex);
- kfree(preg);
- return minor;
- }
- snd_minors[minor] = preg;
- preg->dev = device_create(sound_class, device, MKDEV(major, minor),
- private_data, "%s", name);
- if (IS_ERR(preg->dev)) {
- snd_minors[minor] = NULL;
- mutex_unlock(&sound_mutex);
- minor = PTR_ERR(preg->dev);
- kfree(preg);
- return minor;
- }
-
- mutex_unlock(&sound_mutex);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_register_device_for_dev);
-
-/* find the matching minor record
- * return the index of snd_minor, or -1 if not found
- */
-static int find_snd_minor(int type, struct snd_card *card, int dev)
-{
- int cardnum, minor;
- struct snd_minor *mptr;
-
- cardnum = card ? card->number : -1;
- for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor)
- if ((mptr = snd_minors[minor]) != NULL &&
- mptr->type == type &&
- mptr->card == cardnum &&
- mptr->device == dev)
- return minor;
- return -1;
-}
-
-/**
- * snd_unregister_device - unregister the device on the given card
- * @type: the device type, SNDRV_DEVICE_TYPE_XXX
- * @card: the card instance
- * @dev: the device index
- *
- * Unregisters the device file already registered via
- * snd_register_device().
- *
- * Returns zero if sucecessful, or a negative error code on failure
- */
-int snd_unregister_device(int type, struct snd_card *card, int dev)
-{
- int minor;
-
- mutex_lock(&sound_mutex);
- minor = find_snd_minor(type, card, dev);
- if (minor < 0) {
- mutex_unlock(&sound_mutex);
- return -EINVAL;
- }
-
- device_destroy(sound_class, MKDEV(major, minor));
-
- kfree(snd_minors[minor]);
- snd_minors[minor] = NULL;
- mutex_unlock(&sound_mutex);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_unregister_device);
-
-int snd_add_device_sysfs_file(int type, struct snd_card *card, int dev,
- struct device_attribute *attr)
-{
- int minor, ret = -EINVAL;
- struct device *d;
-
- mutex_lock(&sound_mutex);
- minor = find_snd_minor(type, card, dev);
- if (minor >= 0 && (d = snd_minors[minor]->dev) != NULL)
- ret = device_create_file(d, attr);
- mutex_unlock(&sound_mutex);
- return ret;
-
-}
-
-EXPORT_SYMBOL(snd_add_device_sysfs_file);
-
-#ifdef CONFIG_PROC_FS
-/*
- * INFO PART
- */
-
-static struct snd_info_entry *snd_minor_info_entry;
-
-static const char *snd_device_type_name(int type)
-{
- switch (type) {
- case SNDRV_DEVICE_TYPE_CONTROL:
- return "control";
- case SNDRV_DEVICE_TYPE_HWDEP:
- return "hardware dependent";
- case SNDRV_DEVICE_TYPE_RAWMIDI:
- return "raw midi";
- case SNDRV_DEVICE_TYPE_PCM_PLAYBACK:
- return "digital audio playback";
- case SNDRV_DEVICE_TYPE_PCM_CAPTURE:
- return "digital audio capture";
- case SNDRV_DEVICE_TYPE_SEQUENCER:
- return "sequencer";
- case SNDRV_DEVICE_TYPE_TIMER:
- return "timer";
- default:
- return "?";
- }
-}
-
-static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- int minor;
- struct snd_minor *mptr;
-
- mutex_lock(&sound_mutex);
- for (minor = 0; minor < SNDRV_OS_MINORS; ++minor) {
- if (!(mptr = snd_minors[minor]))
- continue;
- if (mptr->card >= 0) {
- if (mptr->device >= 0)
- snd_iprintf(buffer, "%3i: [%2i-%2i]: %s\n",
- minor, mptr->card, mptr->device,
- snd_device_type_name(mptr->type));
- else
- snd_iprintf(buffer, "%3i: [%2i] : %s\n",
- minor, mptr->card,
- snd_device_type_name(mptr->type));
- } else
- snd_iprintf(buffer, "%3i: : %s\n", minor,
- snd_device_type_name(mptr->type));
- }
- mutex_unlock(&sound_mutex);
-}
-
-int __init snd_minor_info_init(void)
-{
- struct snd_info_entry *entry;
-
- entry = snd_info_create_module_entry(THIS_MODULE, "devices", NULL);
- if (entry) {
- entry->c.text.read = snd_minor_info_read;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- snd_minor_info_entry = entry;
- return 0;
-}
-
-int __exit snd_minor_info_done(void)
-{
- snd_info_free_entry(snd_minor_info_entry);
- return 0;
-}
-#endif /* CONFIG_PROC_FS */
-
-/*
- * INIT PART
- */
-
-static int __init alsa_sound_init(void)
-{
- snd_major = major;
- snd_ecards_limit = cards_limit;
- if (register_chrdev(major, "alsa", &snd_fops)) {
- snd_printk(KERN_ERR "unable to register native major device number %d\n", major);
- return -EIO;
- }
- if (snd_info_init() < 0) {
- unregister_chrdev(major, "alsa");
- return -ENOMEM;
- }
- snd_info_minor_register();
-#ifndef MODULE
- printk(KERN_INFO "Advanced Linux Sound Architecture Driver Version " CONFIG_SND_VERSION CONFIG_SND_DATE ".\n");
-#endif
- return 0;
-}
-
-static void __exit alsa_sound_exit(void)
-{
- snd_info_minor_unregister();
- snd_info_done();
- unregister_chrdev(major, "alsa");
-}
-
-subsys_initcall(alsa_sound_init);
-module_exit(alsa_sound_exit);
diff --git a/ANDROID_3.4.5/sound/core/sound_oss.c b/ANDROID_3.4.5/sound/core/sound_oss.c
deleted file mode 100644
index ec860091..00000000
--- a/ANDROID_3.4.5/sound/core/sound_oss.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Advanced Linux Sound Architecture
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifdef CONFIG_SND_OSSEMUL
-
-#if !defined(CONFIG_SOUND) && !(defined(MODULE) && defined(CONFIG_SOUND_MODULE))
-#error "Enable the OSS soundcore multiplexer (CONFIG_SOUND) in the kernel."
-#endif
-
-#include <linux/init.h>
-#include <linux/export.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/minors.h>
-#include <sound/info.h>
-#include <linux/sound.h>
-#include <linux/mutex.h>
-
-#define SNDRV_OSS_MINORS 128
-
-static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS];
-static DEFINE_MUTEX(sound_oss_mutex);
-
-/* NOTE: This function increments the refcount of the associated card like
- * snd_lookup_minor_data(); the caller must call snd_card_unref() appropriately
- */
-void *snd_lookup_oss_minor_data(unsigned int minor, int type)
-{
- struct snd_minor *mreg;
- void *private_data;
-
- if (minor >= ARRAY_SIZE(snd_oss_minors))
- return NULL;
- mutex_lock(&sound_oss_mutex);
- mreg = snd_oss_minors[minor];
- if (mreg && mreg->type == type) {
- private_data = mreg->private_data;
- if (private_data && mreg->card_ptr)
- atomic_inc(&mreg->card_ptr->refcount);
- } else
- private_data = NULL;
- mutex_unlock(&sound_oss_mutex);
- return private_data;
-}
-
-EXPORT_SYMBOL(snd_lookup_oss_minor_data);
-
-static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev)
-{
- int minor;
-
- switch (type) {
- case SNDRV_OSS_DEVICE_TYPE_MIXER:
- if (snd_BUG_ON(!card || dev < 0 || dev > 1))
- return -EINVAL;
- minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_MIXER1 : SNDRV_MINOR_OSS_MIXER));
- break;
- case SNDRV_OSS_DEVICE_TYPE_SEQUENCER:
- minor = SNDRV_MINOR_OSS_SEQUENCER;
- break;
- case SNDRV_OSS_DEVICE_TYPE_MUSIC:
- minor = SNDRV_MINOR_OSS_MUSIC;
- break;
- case SNDRV_OSS_DEVICE_TYPE_PCM:
- if (snd_BUG_ON(!card || dev < 0 || dev > 1))
- return -EINVAL;
- minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_PCM1 : SNDRV_MINOR_OSS_PCM));
- break;
- case SNDRV_OSS_DEVICE_TYPE_MIDI:
- if (snd_BUG_ON(!card || dev < 0 || dev > 1))
- return -EINVAL;
- minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_MIDI1 : SNDRV_MINOR_OSS_MIDI));
- break;
- case SNDRV_OSS_DEVICE_TYPE_DMFM:
- minor = SNDRV_MINOR_OSS(card->number, SNDRV_MINOR_OSS_DMFM);
- break;
- case SNDRV_OSS_DEVICE_TYPE_SNDSTAT:
- minor = SNDRV_MINOR_OSS_SNDSTAT;
- break;
- default:
- return -EINVAL;
- }
- if (minor < 0 || minor >= SNDRV_OSS_MINORS)
- return -EINVAL;
- return minor;
-}
-
-int snd_register_oss_device(int type, struct snd_card *card, int dev,
- const struct file_operations *f_ops, void *private_data,
- const char *name)
-{
- int minor = snd_oss_kernel_minor(type, card, dev);
- int minor_unit;
- struct snd_minor *preg;
- int cidx = SNDRV_MINOR_OSS_CARD(minor);
- int track2 = -1;
- int register1 = -1, register2 = -1;
- struct device *carddev = snd_card_get_device_link(card);
-
- if (card && card->number >= 8)
- return 0; /* ignore silently */
- if (minor < 0)
- return minor;
- preg = kmalloc(sizeof(struct snd_minor), GFP_KERNEL);
- if (preg == NULL)
- return -ENOMEM;
- preg->type = type;
- preg->card = card ? card->number : -1;
- preg->device = dev;
- preg->f_ops = f_ops;
- preg->private_data = private_data;
- preg->card_ptr = card;
- mutex_lock(&sound_oss_mutex);
- snd_oss_minors[minor] = preg;
- minor_unit = SNDRV_MINOR_OSS_DEVICE(minor);
- switch (minor_unit) {
- case SNDRV_MINOR_OSS_PCM:
- track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_AUDIO);
- break;
- case SNDRV_MINOR_OSS_MIDI:
- track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI);
- break;
- case SNDRV_MINOR_OSS_MIDI1:
- track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI1);
- break;
- }
- register1 = register_sound_special_device(f_ops, minor, carddev);
- if (register1 != minor)
- goto __end;
- if (track2 >= 0) {
- register2 = register_sound_special_device(f_ops, track2,
- carddev);
- if (register2 != track2)
- goto __end;
- snd_oss_minors[track2] = preg;
- }
- mutex_unlock(&sound_oss_mutex);
- return 0;
-
- __end:
- if (register2 >= 0)
- unregister_sound_special(register2);
- if (register1 >= 0)
- unregister_sound_special(register1);
- snd_oss_minors[minor] = NULL;
- mutex_unlock(&sound_oss_mutex);
- kfree(preg);
- return -EBUSY;
-}
-
-EXPORT_SYMBOL(snd_register_oss_device);
-
-int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
-{
- int minor = snd_oss_kernel_minor(type, card, dev);
- int cidx = SNDRV_MINOR_OSS_CARD(minor);
- int track2 = -1;
- struct snd_minor *mptr;
-
- if (card && card->number >= 8)
- return 0;
- if (minor < 0)
- return minor;
- mutex_lock(&sound_oss_mutex);
- mptr = snd_oss_minors[minor];
- if (mptr == NULL) {
- mutex_unlock(&sound_oss_mutex);
- return -ENOENT;
- }
- unregister_sound_special(minor);
- switch (SNDRV_MINOR_OSS_DEVICE(minor)) {
- case SNDRV_MINOR_OSS_PCM:
- track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_AUDIO);
- break;
- case SNDRV_MINOR_OSS_MIDI:
- track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI);
- break;
- case SNDRV_MINOR_OSS_MIDI1:
- track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI1);
- break;
- }
- if (track2 >= 0) {
- unregister_sound_special(track2);
- snd_oss_minors[track2] = NULL;
- }
- snd_oss_minors[minor] = NULL;
- mutex_unlock(&sound_oss_mutex);
- kfree(mptr);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_unregister_oss_device);
-
-/*
- * INFO PART
- */
-
-#ifdef CONFIG_PROC_FS
-
-static struct snd_info_entry *snd_minor_info_oss_entry;
-
-static const char *snd_oss_device_type_name(int type)
-{
- switch (type) {
- case SNDRV_OSS_DEVICE_TYPE_MIXER:
- return "mixer";
- case SNDRV_OSS_DEVICE_TYPE_SEQUENCER:
- case SNDRV_OSS_DEVICE_TYPE_MUSIC:
- return "sequencer";
- case SNDRV_OSS_DEVICE_TYPE_PCM:
- return "digital audio";
- case SNDRV_OSS_DEVICE_TYPE_MIDI:
- return "raw midi";
- case SNDRV_OSS_DEVICE_TYPE_DMFM:
- return "hardware dependent";
- default:
- return "?";
- }
-}
-
-static void snd_minor_info_oss_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- int minor;
- struct snd_minor *mptr;
-
- mutex_lock(&sound_oss_mutex);
- for (minor = 0; minor < SNDRV_OSS_MINORS; ++minor) {
- if (!(mptr = snd_oss_minors[minor]))
- continue;
- if (mptr->card >= 0)
- snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", minor,
- mptr->card, mptr->device,
- snd_oss_device_type_name(mptr->type));
- else
- snd_iprintf(buffer, "%3i: : %s\n", minor,
- snd_oss_device_type_name(mptr->type));
- }
- mutex_unlock(&sound_oss_mutex);
-}
-
-
-int __init snd_minor_info_oss_init(void)
-{
- struct snd_info_entry *entry;
-
- entry = snd_info_create_module_entry(THIS_MODULE, "devices", snd_oss_root);
- if (entry) {
- entry->c.text.read = snd_minor_info_oss_read;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- snd_minor_info_oss_entry = entry;
- return 0;
-}
-
-int __exit snd_minor_info_oss_done(void)
-{
- snd_info_free_entry(snd_minor_info_oss_entry);
- return 0;
-}
-#endif /* CONFIG_PROC_FS */
-
-#endif /* CONFIG_SND_OSSEMUL */
diff --git a/ANDROID_3.4.5/sound/core/timer.c b/ANDROID_3.4.5/sound/core/timer.c
deleted file mode 100644
index 6ddcf06f..00000000
--- a/ANDROID_3.4.5/sound/core/timer.c
+++ /dev/null
@@ -1,1999 +0,0 @@
-/*
- * Timers abstract layer
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <sound/core.h>
-#include <sound/timer.h>
-#include <sound/control.h>
-#include <sound/info.h>
-#include <sound/minors.h>
-#include <sound/initval.h>
-#include <linux/kmod.h>
-
-#if defined(CONFIG_SND_HRTIMER) || defined(CONFIG_SND_HRTIMER_MODULE)
-#define DEFAULT_TIMER_LIMIT 4
-#elif defined(CONFIG_SND_RTCTIMER) || defined(CONFIG_SND_RTCTIMER_MODULE)
-#define DEFAULT_TIMER_LIMIT 2
-#else
-#define DEFAULT_TIMER_LIMIT 1
-#endif
-
-static int timer_limit = DEFAULT_TIMER_LIMIT;
-static int timer_tstamp_monotonic = 1;
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("ALSA timer interface");
-MODULE_LICENSE("GPL");
-module_param(timer_limit, int, 0444);
-MODULE_PARM_DESC(timer_limit, "Maximum global timers in system.");
-module_param(timer_tstamp_monotonic, int, 0444);
-MODULE_PARM_DESC(timer_tstamp_monotonic, "Use posix monotonic clock source for timestamps (default).");
-
-MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_TIMER);
-MODULE_ALIAS("devname:snd/timer");
-
-struct snd_timer_user {
- struct snd_timer_instance *timeri;
- int tread; /* enhanced read with timestamps and events */
- unsigned long ticks;
- unsigned long overrun;
- int qhead;
- int qtail;
- int qused;
- int queue_size;
- struct snd_timer_read *queue;
- struct snd_timer_tread *tqueue;
- spinlock_t qlock;
- unsigned long last_resolution;
- unsigned int filter;
- struct timespec tstamp; /* trigger tstamp */
- wait_queue_head_t qchange_sleep;
- struct fasync_struct *fasync;
- struct mutex tread_sem;
-};
-
-/* list of timers */
-static LIST_HEAD(snd_timer_list);
-
-/* list of slave instances */
-static LIST_HEAD(snd_timer_slave_list);
-
-/* lock for slave active lists */
-static DEFINE_SPINLOCK(slave_active_lock);
-
-static DEFINE_MUTEX(register_mutex);
-
-static int snd_timer_free(struct snd_timer *timer);
-static int snd_timer_dev_free(struct snd_device *device);
-static int snd_timer_dev_register(struct snd_device *device);
-static int snd_timer_dev_disconnect(struct snd_device *device);
-
-static void snd_timer_reschedule(struct snd_timer * timer, unsigned long ticks_left);
-
-/*
- * create a timer instance with the given owner string.
- * when timer is not NULL, increments the module counter
- */
-static struct snd_timer_instance *snd_timer_instance_new(char *owner,
- struct snd_timer *timer)
-{
- struct snd_timer_instance *timeri;
- timeri = kzalloc(sizeof(*timeri), GFP_KERNEL);
- if (timeri == NULL)
- return NULL;
- timeri->owner = kstrdup(owner, GFP_KERNEL);
- if (! timeri->owner) {
- kfree(timeri);
- return NULL;
- }
- INIT_LIST_HEAD(&timeri->open_list);
- INIT_LIST_HEAD(&timeri->active_list);
- INIT_LIST_HEAD(&timeri->ack_list);
- INIT_LIST_HEAD(&timeri->slave_list_head);
- INIT_LIST_HEAD(&timeri->slave_active_head);
-
- timeri->timer = timer;
- if (timer && !try_module_get(timer->module)) {
- kfree(timeri->owner);
- kfree(timeri);
- return NULL;
- }
-
- return timeri;
-}
-
-/*
- * find a timer instance from the given timer id
- */
-static struct snd_timer *snd_timer_find(struct snd_timer_id *tid)
-{
- struct snd_timer *timer = NULL;
-
- list_for_each_entry(timer, &snd_timer_list, device_list) {
- if (timer->tmr_class != tid->dev_class)
- continue;
- if ((timer->tmr_class == SNDRV_TIMER_CLASS_CARD ||
- timer->tmr_class == SNDRV_TIMER_CLASS_PCM) &&
- (timer->card == NULL ||
- timer->card->number != tid->card))
- continue;
- if (timer->tmr_device != tid->device)
- continue;
- if (timer->tmr_subdevice != tid->subdevice)
- continue;
- return timer;
- }
- return NULL;
-}
-
-#ifdef CONFIG_MODULES
-
-static void snd_timer_request(struct snd_timer_id *tid)
-{
- switch (tid->dev_class) {
- case SNDRV_TIMER_CLASS_GLOBAL:
- if (tid->device < timer_limit)
- request_module("snd-timer-%i", tid->device);
- break;
- case SNDRV_TIMER_CLASS_CARD:
- case SNDRV_TIMER_CLASS_PCM:
- if (tid->card < snd_ecards_limit)
- request_module("snd-card-%i", tid->card);
- break;
- default:
- break;
- }
-}
-
-#endif
-
-/*
- * look for a master instance matching with the slave id of the given slave.
- * when found, relink the open_link of the slave.
- *
- * call this with register_mutex down.
- */
-static void snd_timer_check_slave(struct snd_timer_instance *slave)
-{
- struct snd_timer *timer;
- struct snd_timer_instance *master;
-
- /* FIXME: it's really dumb to look up all entries.. */
- list_for_each_entry(timer, &snd_timer_list, device_list) {
- list_for_each_entry(master, &timer->open_list_head, open_list) {
- if (slave->slave_class == master->slave_class &&
- slave->slave_id == master->slave_id) {
- list_move_tail(&slave->open_list,
- &master->slave_list_head);
- spin_lock_irq(&slave_active_lock);
- slave->master = master;
- slave->timer = master->timer;
- spin_unlock_irq(&slave_active_lock);
- return;
- }
- }
- }
-}
-
-/*
- * look for slave instances matching with the slave id of the given master.
- * when found, relink the open_link of slaves.
- *
- * call this with register_mutex down.
- */
-static void snd_timer_check_master(struct snd_timer_instance *master)
-{
- struct snd_timer_instance *slave, *tmp;
-
- /* check all pending slaves */
- list_for_each_entry_safe(slave, tmp, &snd_timer_slave_list, open_list) {
- if (slave->slave_class == master->slave_class &&
- slave->slave_id == master->slave_id) {
- list_move_tail(&slave->open_list, &master->slave_list_head);
- spin_lock_irq(&slave_active_lock);
- slave->master = master;
- slave->timer = master->timer;
- if (slave->flags & SNDRV_TIMER_IFLG_RUNNING)
- list_add_tail(&slave->active_list,
- &master->slave_active_head);
- spin_unlock_irq(&slave_active_lock);
- }
- }
-}
-
-/*
- * open a timer instance
- * when opening a master, the slave id must be here given.
- */
-int snd_timer_open(struct snd_timer_instance **ti,
- char *owner, struct snd_timer_id *tid,
- unsigned int slave_id)
-{
- struct snd_timer *timer;
- struct snd_timer_instance *timeri = NULL;
-
- if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) {
- /* open a slave instance */
- if (tid->dev_sclass <= SNDRV_TIMER_SCLASS_NONE ||
- tid->dev_sclass > SNDRV_TIMER_SCLASS_OSS_SEQUENCER) {
- snd_printd("invalid slave class %i\n", tid->dev_sclass);
- return -EINVAL;
- }
- mutex_lock(&register_mutex);
- timeri = snd_timer_instance_new(owner, NULL);
- if (!timeri) {
- mutex_unlock(&register_mutex);
- return -ENOMEM;
- }
- timeri->slave_class = tid->dev_sclass;
- timeri->slave_id = tid->device;
- timeri->flags |= SNDRV_TIMER_IFLG_SLAVE;
- list_add_tail(&timeri->open_list, &snd_timer_slave_list);
- snd_timer_check_slave(timeri);
- mutex_unlock(&register_mutex);
- *ti = timeri;
- return 0;
- }
-
- /* open a master instance */
- mutex_lock(&register_mutex);
- timer = snd_timer_find(tid);
-#ifdef CONFIG_MODULES
- if (!timer) {
- mutex_unlock(&register_mutex);
- snd_timer_request(tid);
- mutex_lock(&register_mutex);
- timer = snd_timer_find(tid);
- }
-#endif
- if (!timer) {
- mutex_unlock(&register_mutex);
- return -ENODEV;
- }
- if (!list_empty(&timer->open_list_head)) {
- timeri = list_entry(timer->open_list_head.next,
- struct snd_timer_instance, open_list);
- if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
- mutex_unlock(&register_mutex);
- return -EBUSY;
- }
- }
- timeri = snd_timer_instance_new(owner, timer);
- if (!timeri) {
- mutex_unlock(&register_mutex);
- return -ENOMEM;
- }
- timeri->slave_class = tid->dev_sclass;
- timeri->slave_id = slave_id;
- if (list_empty(&timer->open_list_head) && timer->hw.open)
- timer->hw.open(timer);
- list_add_tail(&timeri->open_list, &timer->open_list_head);
- snd_timer_check_master(timeri);
- mutex_unlock(&register_mutex);
- *ti = timeri;
- return 0;
-}
-
-static int _snd_timer_stop(struct snd_timer_instance *timeri,
- int keep_flag, int event);
-
-/*
- * close a timer instance
- */
-int snd_timer_close(struct snd_timer_instance *timeri)
-{
- struct snd_timer *timer = NULL;
- struct snd_timer_instance *slave, *tmp;
-
- if (snd_BUG_ON(!timeri))
- return -ENXIO;
-
- /* force to stop the timer */
- snd_timer_stop(timeri);
-
- if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
- /* wait, until the active callback is finished */
- spin_lock_irq(&slave_active_lock);
- while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) {
- spin_unlock_irq(&slave_active_lock);
- udelay(10);
- spin_lock_irq(&slave_active_lock);
- }
- spin_unlock_irq(&slave_active_lock);
- mutex_lock(&register_mutex);
- list_del(&timeri->open_list);
- mutex_unlock(&register_mutex);
- } else {
- timer = timeri->timer;
- if (snd_BUG_ON(!timer))
- goto out;
- /* wait, until the active callback is finished */
- spin_lock_irq(&timer->lock);
- while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) {
- spin_unlock_irq(&timer->lock);
- udelay(10);
- spin_lock_irq(&timer->lock);
- }
- spin_unlock_irq(&timer->lock);
- mutex_lock(&register_mutex);
- list_del(&timeri->open_list);
- if (timer && list_empty(&timer->open_list_head) &&
- timer->hw.close)
- timer->hw.close(timer);
- /* remove slave links */
- list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head,
- open_list) {
- spin_lock_irq(&slave_active_lock);
- _snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION);
- list_move_tail(&slave->open_list, &snd_timer_slave_list);
- slave->master = NULL;
- slave->timer = NULL;
- spin_unlock_irq(&slave_active_lock);
- }
- mutex_unlock(&register_mutex);
- }
- out:
- if (timeri->private_free)
- timeri->private_free(timeri);
- kfree(timeri->owner);
- kfree(timeri);
- if (timer)
- module_put(timer->module);
- return 0;
-}
-
-unsigned long snd_timer_resolution(struct snd_timer_instance *timeri)
-{
- struct snd_timer * timer;
-
- if (timeri == NULL)
- return 0;
- if ((timer = timeri->timer) != NULL) {
- if (timer->hw.c_resolution)
- return timer->hw.c_resolution(timer);
- return timer->hw.resolution;
- }
- return 0;
-}
-
-static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
-{
- struct snd_timer *timer;
- unsigned long flags;
- unsigned long resolution = 0;
- struct snd_timer_instance *ts;
- struct timespec tstamp;
-
- if (timer_tstamp_monotonic)
- do_posix_clock_monotonic_gettime(&tstamp);
- else
- getnstimeofday(&tstamp);
- if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_START ||
- event > SNDRV_TIMER_EVENT_PAUSE))
- return;
- if (event == SNDRV_TIMER_EVENT_START ||
- event == SNDRV_TIMER_EVENT_CONTINUE)
- resolution = snd_timer_resolution(ti);
- if (ti->ccallback)
- ti->ccallback(ti, event, &tstamp, resolution);
- if (ti->flags & SNDRV_TIMER_IFLG_SLAVE)
- return;
- timer = ti->timer;
- if (timer == NULL)
- return;
- if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
- return;
- spin_lock_irqsave(&timer->lock, flags);
- list_for_each_entry(ts, &ti->slave_active_head, active_list)
- if (ts->ccallback)
- ts->ccallback(ti, event + 100, &tstamp, resolution);
- spin_unlock_irqrestore(&timer->lock, flags);
-}
-
-static int snd_timer_start1(struct snd_timer *timer, struct snd_timer_instance *timeri,
- unsigned long sticks)
-{
- list_move_tail(&timeri->active_list, &timer->active_list_head);
- if (timer->running) {
- if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
- goto __start_now;
- timer->flags |= SNDRV_TIMER_FLG_RESCHED;
- timeri->flags |= SNDRV_TIMER_IFLG_START;
- return 1; /* delayed start */
- } else {
- timer->sticks = sticks;
- timer->hw.start(timer);
- __start_now:
- timer->running++;
- timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
- return 0;
- }
-}
-
-static int snd_timer_start_slave(struct snd_timer_instance *timeri)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&slave_active_lock, flags);
- timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
- if (timeri->master)
- list_add_tail(&timeri->active_list,
- &timeri->master->slave_active_head);
- spin_unlock_irqrestore(&slave_active_lock, flags);
- return 1; /* delayed start */
-}
-
-/*
- * start the timer instance
- */
-int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks)
-{
- struct snd_timer *timer;
- int result = -EINVAL;
- unsigned long flags;
-
- if (timeri == NULL || ticks < 1)
- return -EINVAL;
- if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
- result = snd_timer_start_slave(timeri);
- snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
- return result;
- }
- timer = timeri->timer;
- if (timer == NULL)
- return -EINVAL;
- spin_lock_irqsave(&timer->lock, flags);
- timeri->ticks = timeri->cticks = ticks;
- timeri->pticks = 0;
- result = snd_timer_start1(timer, timeri, ticks);
- spin_unlock_irqrestore(&timer->lock, flags);
- snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
- return result;
-}
-
-static int _snd_timer_stop(struct snd_timer_instance * timeri,
- int keep_flag, int event)
-{
- struct snd_timer *timer;
- unsigned long flags;
-
- if (snd_BUG_ON(!timeri))
- return -ENXIO;
-
- if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
- if (!keep_flag) {
- spin_lock_irqsave(&slave_active_lock, flags);
- timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
- spin_unlock_irqrestore(&slave_active_lock, flags);
- }
- goto __end;
- }
- timer = timeri->timer;
- if (!timer)
- return -EINVAL;
- spin_lock_irqsave(&timer->lock, flags);
- list_del_init(&timeri->ack_list);
- list_del_init(&timeri->active_list);
- if ((timeri->flags & SNDRV_TIMER_IFLG_RUNNING) &&
- !(--timer->running)) {
- timer->hw.stop(timer);
- if (timer->flags & SNDRV_TIMER_FLG_RESCHED) {
- timer->flags &= ~SNDRV_TIMER_FLG_RESCHED;
- snd_timer_reschedule(timer, 0);
- if (timer->flags & SNDRV_TIMER_FLG_CHANGE) {
- timer->flags &= ~SNDRV_TIMER_FLG_CHANGE;
- timer->hw.start(timer);
- }
- }
- }
- if (!keep_flag)
- timeri->flags &=
- ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
- spin_unlock_irqrestore(&timer->lock, flags);
- __end:
- if (event != SNDRV_TIMER_EVENT_RESOLUTION)
- snd_timer_notify1(timeri, event);
- return 0;
-}
-
-/*
- * stop the timer instance.
- *
- * do not call this from the timer callback!
- */
-int snd_timer_stop(struct snd_timer_instance *timeri)
-{
- struct snd_timer *timer;
- unsigned long flags;
- int err;
-
- err = _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_STOP);
- if (err < 0)
- return err;
- timer = timeri->timer;
- if (!timer)
- return -EINVAL;
- spin_lock_irqsave(&timer->lock, flags);
- timeri->cticks = timeri->ticks;
- timeri->pticks = 0;
- spin_unlock_irqrestore(&timer->lock, flags);
- return 0;
-}
-
-/*
- * start again.. the tick is kept.
- */
-int snd_timer_continue(struct snd_timer_instance *timeri)
-{
- struct snd_timer *timer;
- int result = -EINVAL;
- unsigned long flags;
-
- if (timeri == NULL)
- return result;
- if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
- return snd_timer_start_slave(timeri);
- timer = timeri->timer;
- if (! timer)
- return -EINVAL;
- spin_lock_irqsave(&timer->lock, flags);
- if (!timeri->cticks)
- timeri->cticks = 1;
- timeri->pticks = 0;
- result = snd_timer_start1(timer, timeri, timer->sticks);
- spin_unlock_irqrestore(&timer->lock, flags);
- snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_CONTINUE);
- return result;
-}
-
-/*
- * pause.. remember the ticks left
- */
-int snd_timer_pause(struct snd_timer_instance * timeri)
-{
- return _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_PAUSE);
-}
-
-/*
- * reschedule the timer
- *
- * start pending instances and check the scheduling ticks.
- * when the scheduling ticks is changed set CHANGE flag to reprogram the timer.
- */
-static void snd_timer_reschedule(struct snd_timer * timer, unsigned long ticks_left)
-{
- struct snd_timer_instance *ti;
- unsigned long ticks = ~0UL;
-
- list_for_each_entry(ti, &timer->active_list_head, active_list) {
- if (ti->flags & SNDRV_TIMER_IFLG_START) {
- ti->flags &= ~SNDRV_TIMER_IFLG_START;
- ti->flags |= SNDRV_TIMER_IFLG_RUNNING;
- timer->running++;
- }
- if (ti->flags & SNDRV_TIMER_IFLG_RUNNING) {
- if (ticks > ti->cticks)
- ticks = ti->cticks;
- }
- }
- if (ticks == ~0UL) {
- timer->flags &= ~SNDRV_TIMER_FLG_RESCHED;
- return;
- }
- if (ticks > timer->hw.ticks)
- ticks = timer->hw.ticks;
- if (ticks_left != ticks)
- timer->flags |= SNDRV_TIMER_FLG_CHANGE;
- timer->sticks = ticks;
-}
-
-/*
- * timer tasklet
- *
- */
-static void snd_timer_tasklet(unsigned long arg)
-{
- struct snd_timer *timer = (struct snd_timer *) arg;
- struct snd_timer_instance *ti;
- struct list_head *p;
- unsigned long resolution, ticks;
- unsigned long flags;
-
- spin_lock_irqsave(&timer->lock, flags);
- /* now process all callbacks */
- while (!list_empty(&timer->sack_list_head)) {
- p = timer->sack_list_head.next; /* get first item */
- ti = list_entry(p, struct snd_timer_instance, ack_list);
-
- /* remove from ack_list and make empty */
- list_del_init(p);
-
- ticks = ti->pticks;
- ti->pticks = 0;
- resolution = ti->resolution;
-
- ti->flags |= SNDRV_TIMER_IFLG_CALLBACK;
- spin_unlock(&timer->lock);
- if (ti->callback)
- ti->callback(ti, resolution, ticks);
- spin_lock(&timer->lock);
- ti->flags &= ~SNDRV_TIMER_IFLG_CALLBACK;
- }
- spin_unlock_irqrestore(&timer->lock, flags);
-}
-
-/*
- * timer interrupt
- *
- * ticks_left is usually equal to timer->sticks.
- *
- */
-void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
-{
- struct snd_timer_instance *ti, *ts, *tmp;
- unsigned long resolution, ticks;
- struct list_head *p, *ack_list_head;
- unsigned long flags;
- int use_tasklet = 0;
-
- if (timer == NULL)
- return;
-
- spin_lock_irqsave(&timer->lock, flags);
-
- /* remember the current resolution */
- if (timer->hw.c_resolution)
- resolution = timer->hw.c_resolution(timer);
- else
- resolution = timer->hw.resolution;
-
- /* loop for all active instances
- * Here we cannot use list_for_each_entry because the active_list of a
- * processed instance is relinked to done_list_head before the callback
- * is called.
- */
- list_for_each_entry_safe(ti, tmp, &timer->active_list_head,
- active_list) {
- if (!(ti->flags & SNDRV_TIMER_IFLG_RUNNING))
- continue;
- ti->pticks += ticks_left;
- ti->resolution = resolution;
- if (ti->cticks < ticks_left)
- ti->cticks = 0;
- else
- ti->cticks -= ticks_left;
- if (ti->cticks) /* not expired */
- continue;
- if (ti->flags & SNDRV_TIMER_IFLG_AUTO) {
- ti->cticks = ti->ticks;
- } else {
- ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
- if (--timer->running)
- list_del(&ti->active_list);
- }
- if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
- (ti->flags & SNDRV_TIMER_IFLG_FAST))
- ack_list_head = &timer->ack_list_head;
- else
- ack_list_head = &timer->sack_list_head;
- if (list_empty(&ti->ack_list))
- list_add_tail(&ti->ack_list, ack_list_head);
- list_for_each_entry(ts, &ti->slave_active_head, active_list) {
- ts->pticks = ti->pticks;
- ts->resolution = resolution;
- if (list_empty(&ts->ack_list))
- list_add_tail(&ts->ack_list, ack_list_head);
- }
- }
- if (timer->flags & SNDRV_TIMER_FLG_RESCHED)
- snd_timer_reschedule(timer, timer->sticks);
- if (timer->running) {
- if (timer->hw.flags & SNDRV_TIMER_HW_STOP) {
- timer->hw.stop(timer);
- timer->flags |= SNDRV_TIMER_FLG_CHANGE;
- }
- if (!(timer->hw.flags & SNDRV_TIMER_HW_AUTO) ||
- (timer->flags & SNDRV_TIMER_FLG_CHANGE)) {
- /* restart timer */
- timer->flags &= ~SNDRV_TIMER_FLG_CHANGE;
- timer->hw.start(timer);
- }
- } else {
- timer->hw.stop(timer);
- }
-
- /* now process all fast callbacks */
- while (!list_empty(&timer->ack_list_head)) {
- p = timer->ack_list_head.next; /* get first item */
- ti = list_entry(p, struct snd_timer_instance, ack_list);
-
- /* remove from ack_list and make empty */
- list_del_init(p);
-
- ticks = ti->pticks;
- ti->pticks = 0;
-
- ti->flags |= SNDRV_TIMER_IFLG_CALLBACK;
- spin_unlock(&timer->lock);
- if (ti->callback)
- ti->callback(ti, resolution, ticks);
- spin_lock(&timer->lock);
- ti->flags &= ~SNDRV_TIMER_IFLG_CALLBACK;
- }
-
- /* do we have any slow callbacks? */
- use_tasklet = !list_empty(&timer->sack_list_head);
- spin_unlock_irqrestore(&timer->lock, flags);
-
- if (use_tasklet)
- tasklet_schedule(&timer->task_queue);
-}
-
-/*
-
- */
-
-int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
- struct snd_timer **rtimer)
-{
- struct snd_timer *timer;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_timer_dev_free,
- .dev_register = snd_timer_dev_register,
- .dev_disconnect = snd_timer_dev_disconnect,
- };
-
- if (snd_BUG_ON(!tid))
- return -EINVAL;
- if (rtimer)
- *rtimer = NULL;
- timer = kzalloc(sizeof(*timer), GFP_KERNEL);
- if (timer == NULL) {
- snd_printk(KERN_ERR "timer: cannot allocate\n");
- return -ENOMEM;
- }
- timer->tmr_class = tid->dev_class;
- timer->card = card;
- timer->tmr_device = tid->device;
- timer->tmr_subdevice = tid->subdevice;
- if (id)
- strlcpy(timer->id, id, sizeof(timer->id));
- INIT_LIST_HEAD(&timer->device_list);
- INIT_LIST_HEAD(&timer->open_list_head);
- INIT_LIST_HEAD(&timer->active_list_head);
- INIT_LIST_HEAD(&timer->ack_list_head);
- INIT_LIST_HEAD(&timer->sack_list_head);
- spin_lock_init(&timer->lock);
- tasklet_init(&timer->task_queue, snd_timer_tasklet,
- (unsigned long)timer);
- if (card != NULL) {
- timer->module = card->module;
- err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops);
- if (err < 0) {
- snd_timer_free(timer);
- return err;
- }
- }
- if (rtimer)
- *rtimer = timer;
- return 0;
-}
-
-static int snd_timer_free(struct snd_timer *timer)
-{
- if (!timer)
- return 0;
-
- mutex_lock(&register_mutex);
- if (! list_empty(&timer->open_list_head)) {
- struct list_head *p, *n;
- struct snd_timer_instance *ti;
- snd_printk(KERN_WARNING "timer %p is busy?\n", timer);
- list_for_each_safe(p, n, &timer->open_list_head) {
- list_del_init(p);
- ti = list_entry(p, struct snd_timer_instance, open_list);
- ti->timer = NULL;
- }
- }
- list_del(&timer->device_list);
- mutex_unlock(&register_mutex);
-
- if (timer->private_free)
- timer->private_free(timer);
- kfree(timer);
- return 0;
-}
-
-static int snd_timer_dev_free(struct snd_device *device)
-{
- struct snd_timer *timer = device->device_data;
- return snd_timer_free(timer);
-}
-
-static int snd_timer_dev_register(struct snd_device *dev)
-{
- struct snd_timer *timer = dev->device_data;
- struct snd_timer *timer1;
-
- if (snd_BUG_ON(!timer || !timer->hw.start || !timer->hw.stop))
- return -ENXIO;
- if (!(timer->hw.flags & SNDRV_TIMER_HW_SLAVE) &&
- !timer->hw.resolution && timer->hw.c_resolution == NULL)
- return -EINVAL;
-
- mutex_lock(&register_mutex);
- list_for_each_entry(timer1, &snd_timer_list, device_list) {
- if (timer1->tmr_class > timer->tmr_class)
- break;
- if (timer1->tmr_class < timer->tmr_class)
- continue;
- if (timer1->card && timer->card) {
- if (timer1->card->number > timer->card->number)
- break;
- if (timer1->card->number < timer->card->number)
- continue;
- }
- if (timer1->tmr_device > timer->tmr_device)
- break;
- if (timer1->tmr_device < timer->tmr_device)
- continue;
- if (timer1->tmr_subdevice > timer->tmr_subdevice)
- break;
- if (timer1->tmr_subdevice < timer->tmr_subdevice)
- continue;
- /* conflicts.. */
- mutex_unlock(&register_mutex);
- return -EBUSY;
- }
- list_add_tail(&timer->device_list, &timer1->device_list);
- mutex_unlock(&register_mutex);
- return 0;
-}
-
-static int snd_timer_dev_disconnect(struct snd_device *device)
-{
- struct snd_timer *timer = device->device_data;
- mutex_lock(&register_mutex);
- list_del_init(&timer->device_list);
- mutex_unlock(&register_mutex);
- return 0;
-}
-
-void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstamp)
-{
- unsigned long flags;
- unsigned long resolution = 0;
- struct snd_timer_instance *ti, *ts;
-
- if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE))
- return;
- if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_MSTART ||
- event > SNDRV_TIMER_EVENT_MRESUME))
- return;
- spin_lock_irqsave(&timer->lock, flags);
- if (event == SNDRV_TIMER_EVENT_MSTART ||
- event == SNDRV_TIMER_EVENT_MCONTINUE ||
- event == SNDRV_TIMER_EVENT_MRESUME) {
- if (timer->hw.c_resolution)
- resolution = timer->hw.c_resolution(timer);
- else
- resolution = timer->hw.resolution;
- }
- list_for_each_entry(ti, &timer->active_list_head, active_list) {
- if (ti->ccallback)
- ti->ccallback(ti, event, tstamp, resolution);
- list_for_each_entry(ts, &ti->slave_active_head, active_list)
- if (ts->ccallback)
- ts->ccallback(ts, event, tstamp, resolution);
- }
- spin_unlock_irqrestore(&timer->lock, flags);
-}
-
-/*
- * exported functions for global timers
- */
-int snd_timer_global_new(char *id, int device, struct snd_timer **rtimer)
-{
- struct snd_timer_id tid;
-
- tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL;
- tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
- tid.card = -1;
- tid.device = device;
- tid.subdevice = 0;
- return snd_timer_new(NULL, id, &tid, rtimer);
-}
-
-int snd_timer_global_free(struct snd_timer *timer)
-{
- return snd_timer_free(timer);
-}
-
-int snd_timer_global_register(struct snd_timer *timer)
-{
- struct snd_device dev;
-
- memset(&dev, 0, sizeof(dev));
- dev.device_data = timer;
- return snd_timer_dev_register(&dev);
-}
-
-/*
- * System timer
- */
-
-struct snd_timer_system_private {
- struct timer_list tlist;
- unsigned long last_expires;
- unsigned long last_jiffies;
- unsigned long correction;
-};
-
-static void snd_timer_s_function(unsigned long data)
-{
- struct snd_timer *timer = (struct snd_timer *)data;
- struct snd_timer_system_private *priv = timer->private_data;
- unsigned long jiff = jiffies;
- if (time_after(jiff, priv->last_expires))
- priv->correction += (long)jiff - (long)priv->last_expires;
- snd_timer_interrupt(timer, (long)jiff - (long)priv->last_jiffies);
-}
-
-static int snd_timer_s_start(struct snd_timer * timer)
-{
- struct snd_timer_system_private *priv;
- unsigned long njiff;
-
- priv = (struct snd_timer_system_private *) timer->private_data;
- njiff = (priv->last_jiffies = jiffies);
- if (priv->correction > timer->sticks - 1) {
- priv->correction -= timer->sticks - 1;
- njiff++;
- } else {
- njiff += timer->sticks - priv->correction;
- priv->correction = 0;
- }
- priv->last_expires = priv->tlist.expires = njiff;
- add_timer(&priv->tlist);
- return 0;
-}
-
-static int snd_timer_s_stop(struct snd_timer * timer)
-{
- struct snd_timer_system_private *priv;
- unsigned long jiff;
-
- priv = (struct snd_timer_system_private *) timer->private_data;
- del_timer(&priv->tlist);
- jiff = jiffies;
- if (time_before(jiff, priv->last_expires))
- timer->sticks = priv->last_expires - jiff;
- else
- timer->sticks = 1;
- priv->correction = 0;
- return 0;
-}
-
-static struct snd_timer_hardware snd_timer_system =
-{
- .flags = SNDRV_TIMER_HW_FIRST | SNDRV_TIMER_HW_TASKLET,
- .resolution = 1000000000L / HZ,
- .ticks = 10000000L,
- .start = snd_timer_s_start,
- .stop = snd_timer_s_stop
-};
-
-static void snd_timer_free_system(struct snd_timer *timer)
-{
- kfree(timer->private_data);
-}
-
-static int snd_timer_register_system(void)
-{
- struct snd_timer *timer;
- struct snd_timer_system_private *priv;
- int err;
-
- err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer);
- if (err < 0)
- return err;
- strcpy(timer->name, "system timer");
- timer->hw = snd_timer_system;
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (priv == NULL) {
- snd_timer_free(timer);
- return -ENOMEM;
- }
- init_timer(&priv->tlist);
- priv->tlist.function = snd_timer_s_function;
- priv->tlist.data = (unsigned long) timer;
- timer->private_data = priv;
- timer->private_free = snd_timer_free_system;
- return snd_timer_global_register(timer);
-}
-
-#ifdef CONFIG_PROC_FS
-/*
- * Info interface
- */
-
-static void snd_timer_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_timer *timer;
- struct snd_timer_instance *ti;
-
- mutex_lock(&register_mutex);
- list_for_each_entry(timer, &snd_timer_list, device_list) {
- switch (timer->tmr_class) {
- case SNDRV_TIMER_CLASS_GLOBAL:
- snd_iprintf(buffer, "G%i: ", timer->tmr_device);
- break;
- case SNDRV_TIMER_CLASS_CARD:
- snd_iprintf(buffer, "C%i-%i: ",
- timer->card->number, timer->tmr_device);
- break;
- case SNDRV_TIMER_CLASS_PCM:
- snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number,
- timer->tmr_device, timer->tmr_subdevice);
- break;
- default:
- snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class,
- timer->card ? timer->card->number : -1,
- timer->tmr_device, timer->tmr_subdevice);
- }
- snd_iprintf(buffer, "%s :", timer->name);
- if (timer->hw.resolution)
- snd_iprintf(buffer, " %lu.%03luus (%lu ticks)",
- timer->hw.resolution / 1000,
- timer->hw.resolution % 1000,
- timer->hw.ticks);
- if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
- snd_iprintf(buffer, " SLAVE");
- snd_iprintf(buffer, "\n");
- list_for_each_entry(ti, &timer->open_list_head, open_list)
- snd_iprintf(buffer, " Client %s : %s\n",
- ti->owner ? ti->owner : "unknown",
- ti->flags & (SNDRV_TIMER_IFLG_START |
- SNDRV_TIMER_IFLG_RUNNING)
- ? "running" : "stopped");
- }
- mutex_unlock(&register_mutex);
-}
-
-static struct snd_info_entry *snd_timer_proc_entry;
-
-static void __init snd_timer_proc_init(void)
-{
- struct snd_info_entry *entry;
-
- entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL);
- if (entry != NULL) {
- entry->c.text.read = snd_timer_proc_read;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- snd_timer_proc_entry = entry;
-}
-
-static void __exit snd_timer_proc_done(void)
-{
- snd_info_free_entry(snd_timer_proc_entry);
-}
-#else /* !CONFIG_PROC_FS */
-#define snd_timer_proc_init()
-#define snd_timer_proc_done()
-#endif
-
-/*
- * USER SPACE interface
- */
-
-static void snd_timer_user_interrupt(struct snd_timer_instance *timeri,
- unsigned long resolution,
- unsigned long ticks)
-{
- struct snd_timer_user *tu = timeri->callback_data;
- struct snd_timer_read *r;
- int prev;
-
- spin_lock(&tu->qlock);
- if (tu->qused > 0) {
- prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1;
- r = &tu->queue[prev];
- if (r->resolution == resolution) {
- r->ticks += ticks;
- goto __wake;
- }
- }
- if (tu->qused >= tu->queue_size) {
- tu->overrun++;
- } else {
- r = &tu->queue[tu->qtail++];
- tu->qtail %= tu->queue_size;
- r->resolution = resolution;
- r->ticks = ticks;
- tu->qused++;
- }
- __wake:
- spin_unlock(&tu->qlock);
- kill_fasync(&tu->fasync, SIGIO, POLL_IN);
- wake_up(&tu->qchange_sleep);
-}
-
-static void snd_timer_user_append_to_tqueue(struct snd_timer_user *tu,
- struct snd_timer_tread *tread)
-{
- if (tu->qused >= tu->queue_size) {
- tu->overrun++;
- } else {
- memcpy(&tu->tqueue[tu->qtail++], tread, sizeof(*tread));
- tu->qtail %= tu->queue_size;
- tu->qused++;
- }
-}
-
-static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
- int event,
- struct timespec *tstamp,
- unsigned long resolution)
-{
- struct snd_timer_user *tu = timeri->callback_data;
- struct snd_timer_tread r1;
- unsigned long flags;
-
- if (event >= SNDRV_TIMER_EVENT_START &&
- event <= SNDRV_TIMER_EVENT_PAUSE)
- tu->tstamp = *tstamp;
- if ((tu->filter & (1 << event)) == 0 || !tu->tread)
- return;
- r1.event = event;
- r1.tstamp = *tstamp;
- r1.val = resolution;
- spin_lock_irqsave(&tu->qlock, flags);
- snd_timer_user_append_to_tqueue(tu, &r1);
- spin_unlock_irqrestore(&tu->qlock, flags);
- kill_fasync(&tu->fasync, SIGIO, POLL_IN);
- wake_up(&tu->qchange_sleep);
-}
-
-static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
- unsigned long resolution,
- unsigned long ticks)
-{
- struct snd_timer_user *tu = timeri->callback_data;
- struct snd_timer_tread *r, r1;
- struct timespec tstamp;
- int prev, append = 0;
-
- memset(&tstamp, 0, sizeof(tstamp));
- spin_lock(&tu->qlock);
- if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION) |
- (1 << SNDRV_TIMER_EVENT_TICK))) == 0) {
- spin_unlock(&tu->qlock);
- return;
- }
- if (tu->last_resolution != resolution || ticks > 0) {
- if (timer_tstamp_monotonic)
- do_posix_clock_monotonic_gettime(&tstamp);
- else
- getnstimeofday(&tstamp);
- }
- if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) &&
- tu->last_resolution != resolution) {
- r1.event = SNDRV_TIMER_EVENT_RESOLUTION;
- r1.tstamp = tstamp;
- r1.val = resolution;
- snd_timer_user_append_to_tqueue(tu, &r1);
- tu->last_resolution = resolution;
- append++;
- }
- if ((tu->filter & (1 << SNDRV_TIMER_EVENT_TICK)) == 0)
- goto __wake;
- if (ticks == 0)
- goto __wake;
- if (tu->qused > 0) {
- prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1;
- r = &tu->tqueue[prev];
- if (r->event == SNDRV_TIMER_EVENT_TICK) {
- r->tstamp = tstamp;
- r->val += ticks;
- append++;
- goto __wake;
- }
- }
- r1.event = SNDRV_TIMER_EVENT_TICK;
- r1.tstamp = tstamp;
- r1.val = ticks;
- snd_timer_user_append_to_tqueue(tu, &r1);
- append++;
- __wake:
- spin_unlock(&tu->qlock);
- if (append == 0)
- return;
- kill_fasync(&tu->fasync, SIGIO, POLL_IN);
- wake_up(&tu->qchange_sleep);
-}
-
-static int snd_timer_user_open(struct inode *inode, struct file *file)
-{
- struct snd_timer_user *tu;
- int err;
-
- err = nonseekable_open(inode, file);
- if (err < 0)
- return err;
-
- tu = kzalloc(sizeof(*tu), GFP_KERNEL);
- if (tu == NULL)
- return -ENOMEM;
- spin_lock_init(&tu->qlock);
- init_waitqueue_head(&tu->qchange_sleep);
- mutex_init(&tu->tread_sem);
- tu->ticks = 1;
- tu->queue_size = 128;
- tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read),
- GFP_KERNEL);
- if (tu->queue == NULL) {
- kfree(tu);
- return -ENOMEM;
- }
- file->private_data = tu;
- return 0;
-}
-
-static int snd_timer_user_release(struct inode *inode, struct file *file)
-{
- struct snd_timer_user *tu;
-
- if (file->private_data) {
- tu = file->private_data;
- file->private_data = NULL;
- if (tu->timeri)
- snd_timer_close(tu->timeri);
- kfree(tu->queue);
- kfree(tu->tqueue);
- kfree(tu);
- }
- return 0;
-}
-
-static void snd_timer_user_zero_id(struct snd_timer_id *id)
-{
- id->dev_class = SNDRV_TIMER_CLASS_NONE;
- id->dev_sclass = SNDRV_TIMER_SCLASS_NONE;
- id->card = -1;
- id->device = -1;
- id->subdevice = -1;
-}
-
-static void snd_timer_user_copy_id(struct snd_timer_id *id, struct snd_timer *timer)
-{
- id->dev_class = timer->tmr_class;
- id->dev_sclass = SNDRV_TIMER_SCLASS_NONE;
- id->card = timer->card ? timer->card->number : -1;
- id->device = timer->tmr_device;
- id->subdevice = timer->tmr_subdevice;
-}
-
-static int snd_timer_user_next_device(struct snd_timer_id __user *_tid)
-{
- struct snd_timer_id id;
- struct snd_timer *timer;
- struct list_head *p;
-
- if (copy_from_user(&id, _tid, sizeof(id)))
- return -EFAULT;
- mutex_lock(&register_mutex);
- if (id.dev_class < 0) { /* first item */
- if (list_empty(&snd_timer_list))
- snd_timer_user_zero_id(&id);
- else {
- timer = list_entry(snd_timer_list.next,
- struct snd_timer, device_list);
- snd_timer_user_copy_id(&id, timer);
- }
- } else {
- switch (id.dev_class) {
- case SNDRV_TIMER_CLASS_GLOBAL:
- id.device = id.device < 0 ? 0 : id.device + 1;
- list_for_each(p, &snd_timer_list) {
- timer = list_entry(p, struct snd_timer, device_list);
- if (timer->tmr_class > SNDRV_TIMER_CLASS_GLOBAL) {
- snd_timer_user_copy_id(&id, timer);
- break;
- }
- if (timer->tmr_device >= id.device) {
- snd_timer_user_copy_id(&id, timer);
- break;
- }
- }
- if (p == &snd_timer_list)
- snd_timer_user_zero_id(&id);
- break;
- case SNDRV_TIMER_CLASS_CARD:
- case SNDRV_TIMER_CLASS_PCM:
- if (id.card < 0) {
- id.card = 0;
- } else {
- if (id.card < 0) {
- id.card = 0;
- } else {
- if (id.device < 0) {
- id.device = 0;
- } else {
- if (id.subdevice < 0) {
- id.subdevice = 0;
- } else {
- id.subdevice++;
- }
- }
- }
- }
- list_for_each(p, &snd_timer_list) {
- timer = list_entry(p, struct snd_timer, device_list);
- if (timer->tmr_class > id.dev_class) {
- snd_timer_user_copy_id(&id, timer);
- break;
- }
- if (timer->tmr_class < id.dev_class)
- continue;
- if (timer->card->number > id.card) {
- snd_timer_user_copy_id(&id, timer);
- break;
- }
- if (timer->card->number < id.card)
- continue;
- if (timer->tmr_device > id.device) {
- snd_timer_user_copy_id(&id, timer);
- break;
- }
- if (timer->tmr_device < id.device)
- continue;
- if (timer->tmr_subdevice > id.subdevice) {
- snd_timer_user_copy_id(&id, timer);
- break;
- }
- if (timer->tmr_subdevice < id.subdevice)
- continue;
- snd_timer_user_copy_id(&id, timer);
- break;
- }
- if (p == &snd_timer_list)
- snd_timer_user_zero_id(&id);
- break;
- default:
- snd_timer_user_zero_id(&id);
- }
- }
- mutex_unlock(&register_mutex);
- if (copy_to_user(_tid, &id, sizeof(*_tid)))
- return -EFAULT;
- return 0;
-}
-
-static int snd_timer_user_ginfo(struct file *file,
- struct snd_timer_ginfo __user *_ginfo)
-{
- struct snd_timer_ginfo *ginfo;
- struct snd_timer_id tid;
- struct snd_timer *t;
- struct list_head *p;
- int err = 0;
-
- ginfo = memdup_user(_ginfo, sizeof(*ginfo));
- if (IS_ERR(ginfo))
- return PTR_ERR(ginfo);
-
- tid = ginfo->tid;
- memset(ginfo, 0, sizeof(*ginfo));
- ginfo->tid = tid;
- mutex_lock(&register_mutex);
- t = snd_timer_find(&tid);
- if (t != NULL) {
- ginfo->card = t->card ? t->card->number : -1;
- if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
- ginfo->flags |= SNDRV_TIMER_FLG_SLAVE;
- strlcpy(ginfo->id, t->id, sizeof(ginfo->id));
- strlcpy(ginfo->name, t->name, sizeof(ginfo->name));
- ginfo->resolution = t->hw.resolution;
- if (t->hw.resolution_min > 0) {
- ginfo->resolution_min = t->hw.resolution_min;
- ginfo->resolution_max = t->hw.resolution_max;
- }
- list_for_each(p, &t->open_list_head) {
- ginfo->clients++;
- }
- } else {
- err = -ENODEV;
- }
- mutex_unlock(&register_mutex);
- if (err >= 0 && copy_to_user(_ginfo, ginfo, sizeof(*ginfo)))
- err = -EFAULT;
- kfree(ginfo);
- return err;
-}
-
-static int snd_timer_user_gparams(struct file *file,
- struct snd_timer_gparams __user *_gparams)
-{
- struct snd_timer_gparams gparams;
- struct snd_timer *t;
- int err;
-
- if (copy_from_user(&gparams, _gparams, sizeof(gparams)))
- return -EFAULT;
- mutex_lock(&register_mutex);
- t = snd_timer_find(&gparams.tid);
- if (!t) {
- err = -ENODEV;
- goto _error;
- }
- if (!list_empty(&t->open_list_head)) {
- err = -EBUSY;
- goto _error;
- }
- if (!t->hw.set_period) {
- err = -ENOSYS;
- goto _error;
- }
- err = t->hw.set_period(t, gparams.period_num, gparams.period_den);
-_error:
- mutex_unlock(&register_mutex);
- return err;
-}
-
-static int snd_timer_user_gstatus(struct file *file,
- struct snd_timer_gstatus __user *_gstatus)
-{
- struct snd_timer_gstatus gstatus;
- struct snd_timer_id tid;
- struct snd_timer *t;
- int err = 0;
-
- if (copy_from_user(&gstatus, _gstatus, sizeof(gstatus)))
- return -EFAULT;
- tid = gstatus.tid;
- memset(&gstatus, 0, sizeof(gstatus));
- gstatus.tid = tid;
- mutex_lock(&register_mutex);
- t = snd_timer_find(&tid);
- if (t != NULL) {
- if (t->hw.c_resolution)
- gstatus.resolution = t->hw.c_resolution(t);
- else
- gstatus.resolution = t->hw.resolution;
- if (t->hw.precise_resolution) {
- t->hw.precise_resolution(t, &gstatus.resolution_num,
- &gstatus.resolution_den);
- } else {
- gstatus.resolution_num = gstatus.resolution;
- gstatus.resolution_den = 1000000000uL;
- }
- } else {
- err = -ENODEV;
- }
- mutex_unlock(&register_mutex);
- if (err >= 0 && copy_to_user(_gstatus, &gstatus, sizeof(gstatus)))
- err = -EFAULT;
- return err;
-}
-
-static int snd_timer_user_tselect(struct file *file,
- struct snd_timer_select __user *_tselect)
-{
- struct snd_timer_user *tu;
- struct snd_timer_select tselect;
- char str[32];
- int err = 0;
-
- tu = file->private_data;
- mutex_lock(&tu->tread_sem);
- if (tu->timeri) {
- snd_timer_close(tu->timeri);
- tu->timeri = NULL;
- }
- if (copy_from_user(&tselect, _tselect, sizeof(tselect))) {
- err = -EFAULT;
- goto __err;
- }
- sprintf(str, "application %i", current->pid);
- if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE)
- tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION;
- err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid);
- if (err < 0)
- goto __err;
-
- kfree(tu->queue);
- tu->queue = NULL;
- kfree(tu->tqueue);
- tu->tqueue = NULL;
- if (tu->tread) {
- tu->tqueue = kmalloc(tu->queue_size * sizeof(struct snd_timer_tread),
- GFP_KERNEL);
- if (tu->tqueue == NULL)
- err = -ENOMEM;
- } else {
- tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read),
- GFP_KERNEL);
- if (tu->queue == NULL)
- err = -ENOMEM;
- }
-
- if (err < 0) {
- snd_timer_close(tu->timeri);
- tu->timeri = NULL;
- } else {
- tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST;
- tu->timeri->callback = tu->tread
- ? snd_timer_user_tinterrupt : snd_timer_user_interrupt;
- tu->timeri->ccallback = snd_timer_user_ccallback;
- tu->timeri->callback_data = (void *)tu;
- }
-
- __err:
- mutex_unlock(&tu->tread_sem);
- return err;
-}
-
-static int snd_timer_user_info(struct file *file,
- struct snd_timer_info __user *_info)
-{
- struct snd_timer_user *tu;
- struct snd_timer_info *info;
- struct snd_timer *t;
- int err = 0;
-
- tu = file->private_data;
- if (!tu->timeri)
- return -EBADFD;
- t = tu->timeri->timer;
- if (!t)
- return -EBADFD;
-
- info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (! info)
- return -ENOMEM;
- info->card = t->card ? t->card->number : -1;
- if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
- info->flags |= SNDRV_TIMER_FLG_SLAVE;
- strlcpy(info->id, t->id, sizeof(info->id));
- strlcpy(info->name, t->name, sizeof(info->name));
- info->resolution = t->hw.resolution;
- if (copy_to_user(_info, info, sizeof(*_info)))
- err = -EFAULT;
- kfree(info);
- return err;
-}
-
-static int snd_timer_user_params(struct file *file,
- struct snd_timer_params __user *_params)
-{
- struct snd_timer_user *tu;
- struct snd_timer_params params;
- struct snd_timer *t;
- struct snd_timer_read *tr;
- struct snd_timer_tread *ttr;
- int err;
-
- tu = file->private_data;
- if (!tu->timeri)
- return -EBADFD;
- t = tu->timeri->timer;
- if (!t)
- return -EBADFD;
- if (copy_from_user(&params, _params, sizeof(params)))
- return -EFAULT;
- if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE) && params.ticks < 1) {
- err = -EINVAL;
- goto _end;
- }
- if (params.queue_size > 0 &&
- (params.queue_size < 32 || params.queue_size > 1024)) {
- err = -EINVAL;
- goto _end;
- }
- if (params.filter & ~((1<<SNDRV_TIMER_EVENT_RESOLUTION)|
- (1<<SNDRV_TIMER_EVENT_TICK)|
- (1<<SNDRV_TIMER_EVENT_START)|
- (1<<SNDRV_TIMER_EVENT_STOP)|
- (1<<SNDRV_TIMER_EVENT_CONTINUE)|
- (1<<SNDRV_TIMER_EVENT_PAUSE)|
- (1<<SNDRV_TIMER_EVENT_SUSPEND)|
- (1<<SNDRV_TIMER_EVENT_RESUME)|
- (1<<SNDRV_TIMER_EVENT_MSTART)|
- (1<<SNDRV_TIMER_EVENT_MSTOP)|
- (1<<SNDRV_TIMER_EVENT_MCONTINUE)|
- (1<<SNDRV_TIMER_EVENT_MPAUSE)|
- (1<<SNDRV_TIMER_EVENT_MSUSPEND)|
- (1<<SNDRV_TIMER_EVENT_MRESUME))) {
- err = -EINVAL;
- goto _end;
- }
- snd_timer_stop(tu->timeri);
- spin_lock_irq(&t->lock);
- tu->timeri->flags &= ~(SNDRV_TIMER_IFLG_AUTO|
- SNDRV_TIMER_IFLG_EXCLUSIVE|
- SNDRV_TIMER_IFLG_EARLY_EVENT);
- if (params.flags & SNDRV_TIMER_PSFLG_AUTO)
- tu->timeri->flags |= SNDRV_TIMER_IFLG_AUTO;
- if (params.flags & SNDRV_TIMER_PSFLG_EXCLUSIVE)
- tu->timeri->flags |= SNDRV_TIMER_IFLG_EXCLUSIVE;
- if (params.flags & SNDRV_TIMER_PSFLG_EARLY_EVENT)
- tu->timeri->flags |= SNDRV_TIMER_IFLG_EARLY_EVENT;
- spin_unlock_irq(&t->lock);
- if (params.queue_size > 0 &&
- (unsigned int)tu->queue_size != params.queue_size) {
- if (tu->tread) {
- ttr = kmalloc(params.queue_size * sizeof(*ttr),
- GFP_KERNEL);
- if (ttr) {
- kfree(tu->tqueue);
- tu->queue_size = params.queue_size;
- tu->tqueue = ttr;
- }
- } else {
- tr = kmalloc(params.queue_size * sizeof(*tr),
- GFP_KERNEL);
- if (tr) {
- kfree(tu->queue);
- tu->queue_size = params.queue_size;
- tu->queue = tr;
- }
- }
- }
- tu->qhead = tu->qtail = tu->qused = 0;
- if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) {
- if (tu->tread) {
- struct snd_timer_tread tread;
- tread.event = SNDRV_TIMER_EVENT_EARLY;
- tread.tstamp.tv_sec = 0;
- tread.tstamp.tv_nsec = 0;
- tread.val = 0;
- snd_timer_user_append_to_tqueue(tu, &tread);
- } else {
- struct snd_timer_read *r = &tu->queue[0];
- r->resolution = 0;
- r->ticks = 0;
- tu->qused++;
- tu->qtail++;
- }
- }
- tu->filter = params.filter;
- tu->ticks = params.ticks;
- err = 0;
- _end:
- if (copy_to_user(_params, &params, sizeof(params)))
- return -EFAULT;
- return err;
-}
-
-static int snd_timer_user_status(struct file *file,
- struct snd_timer_status __user *_status)
-{
- struct snd_timer_user *tu;
- struct snd_timer_status status;
-
- tu = file->private_data;
- if (!tu->timeri)
- return -EBADFD;
- memset(&status, 0, sizeof(status));
- status.tstamp = tu->tstamp;
- status.resolution = snd_timer_resolution(tu->timeri);
- status.lost = tu->timeri->lost;
- status.overrun = tu->overrun;
- spin_lock_irq(&tu->qlock);
- status.queue = tu->qused;
- spin_unlock_irq(&tu->qlock);
- if (copy_to_user(_status, &status, sizeof(status)))
- return -EFAULT;
- return 0;
-}
-
-static int snd_timer_user_start(struct file *file)
-{
- int err;
- struct snd_timer_user *tu;
-
- tu = file->private_data;
- if (!tu->timeri)
- return -EBADFD;
- snd_timer_stop(tu->timeri);
- tu->timeri->lost = 0;
- tu->last_resolution = 0;
- return (err = snd_timer_start(tu->timeri, tu->ticks)) < 0 ? err : 0;
-}
-
-static int snd_timer_user_stop(struct file *file)
-{
- int err;
- struct snd_timer_user *tu;
-
- tu = file->private_data;
- if (!tu->timeri)
- return -EBADFD;
- return (err = snd_timer_stop(tu->timeri)) < 0 ? err : 0;
-}
-
-static int snd_timer_user_continue(struct file *file)
-{
- int err;
- struct snd_timer_user *tu;
-
- tu = file->private_data;
- if (!tu->timeri)
- return -EBADFD;
- tu->timeri->lost = 0;
- return (err = snd_timer_continue(tu->timeri)) < 0 ? err : 0;
-}
-
-static int snd_timer_user_pause(struct file *file)
-{
- int err;
- struct snd_timer_user *tu;
-
- tu = file->private_data;
- if (!tu->timeri)
- return -EBADFD;
- return (err = snd_timer_pause(tu->timeri)) < 0 ? err : 0;
-}
-
-enum {
- SNDRV_TIMER_IOCTL_START_OLD = _IO('T', 0x20),
- SNDRV_TIMER_IOCTL_STOP_OLD = _IO('T', 0x21),
- SNDRV_TIMER_IOCTL_CONTINUE_OLD = _IO('T', 0x22),
- SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23),
-};
-
-static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct snd_timer_user *tu;
- void __user *argp = (void __user *)arg;
- int __user *p = argp;
-
- tu = file->private_data;
- switch (cmd) {
- case SNDRV_TIMER_IOCTL_PVERSION:
- return put_user(SNDRV_TIMER_VERSION, p) ? -EFAULT : 0;
- case SNDRV_TIMER_IOCTL_NEXT_DEVICE:
- return snd_timer_user_next_device(argp);
- case SNDRV_TIMER_IOCTL_TREAD:
- {
- int xarg;
-
- mutex_lock(&tu->tread_sem);
- if (tu->timeri) { /* too late */
- mutex_unlock(&tu->tread_sem);
- return -EBUSY;
- }
- if (get_user(xarg, p)) {
- mutex_unlock(&tu->tread_sem);
- return -EFAULT;
- }
- tu->tread = xarg ? 1 : 0;
- mutex_unlock(&tu->tread_sem);
- return 0;
- }
- case SNDRV_TIMER_IOCTL_GINFO:
- return snd_timer_user_ginfo(file, argp);
- case SNDRV_TIMER_IOCTL_GPARAMS:
- return snd_timer_user_gparams(file, argp);
- case SNDRV_TIMER_IOCTL_GSTATUS:
- return snd_timer_user_gstatus(file, argp);
- case SNDRV_TIMER_IOCTL_SELECT:
- return snd_timer_user_tselect(file, argp);
- case SNDRV_TIMER_IOCTL_INFO:
- return snd_timer_user_info(file, argp);
- case SNDRV_TIMER_IOCTL_PARAMS:
- return snd_timer_user_params(file, argp);
- case SNDRV_TIMER_IOCTL_STATUS:
- return snd_timer_user_status(file, argp);
- case SNDRV_TIMER_IOCTL_START:
- case SNDRV_TIMER_IOCTL_START_OLD:
- return snd_timer_user_start(file);
- case SNDRV_TIMER_IOCTL_STOP:
- case SNDRV_TIMER_IOCTL_STOP_OLD:
- return snd_timer_user_stop(file);
- case SNDRV_TIMER_IOCTL_CONTINUE:
- case SNDRV_TIMER_IOCTL_CONTINUE_OLD:
- return snd_timer_user_continue(file);
- case SNDRV_TIMER_IOCTL_PAUSE:
- case SNDRV_TIMER_IOCTL_PAUSE_OLD:
- return snd_timer_user_pause(file);
- }
- return -ENOTTY;
-}
-
-static int snd_timer_user_fasync(int fd, struct file * file, int on)
-{
- struct snd_timer_user *tu;
-
- tu = file->private_data;
- return fasync_helper(fd, file, on, &tu->fasync);
-}
-
-static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
- size_t count, loff_t *offset)
-{
- struct snd_timer_user *tu;
- long result = 0, unit;
- int err = 0;
-
- tu = file->private_data;
- unit = tu->tread ? sizeof(struct snd_timer_tread) : sizeof(struct snd_timer_read);
- spin_lock_irq(&tu->qlock);
- while ((long)count - result >= unit) {
- while (!tu->qused) {
- wait_queue_t wait;
-
- if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) {
- err = -EAGAIN;
- break;
- }
-
- set_current_state(TASK_INTERRUPTIBLE);
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&tu->qchange_sleep, &wait);
-
- spin_unlock_irq(&tu->qlock);
- schedule();
- spin_lock_irq(&tu->qlock);
-
- remove_wait_queue(&tu->qchange_sleep, &wait);
-
- if (signal_pending(current)) {
- err = -ERESTARTSYS;
- break;
- }
- }
-
- spin_unlock_irq(&tu->qlock);
- if (err < 0)
- goto _error;
-
- if (tu->tread) {
- if (copy_to_user(buffer, &tu->tqueue[tu->qhead++],
- sizeof(struct snd_timer_tread))) {
- err = -EFAULT;
- goto _error;
- }
- } else {
- if (copy_to_user(buffer, &tu->queue[tu->qhead++],
- sizeof(struct snd_timer_read))) {
- err = -EFAULT;
- goto _error;
- }
- }
-
- tu->qhead %= tu->queue_size;
-
- result += unit;
- buffer += unit;
-
- spin_lock_irq(&tu->qlock);
- tu->qused--;
- }
- spin_unlock_irq(&tu->qlock);
- _error:
- return result > 0 ? result : err;
-}
-
-static unsigned int snd_timer_user_poll(struct file *file, poll_table * wait)
-{
- unsigned int mask;
- struct snd_timer_user *tu;
-
- tu = file->private_data;
-
- poll_wait(file, &tu->qchange_sleep, wait);
-
- mask = 0;
- if (tu->qused)
- mask |= POLLIN | POLLRDNORM;
-
- return mask;
-}
-
-#ifdef CONFIG_COMPAT
-#include "timer_compat.c"
-#else
-#define snd_timer_user_ioctl_compat NULL
-#endif
-
-static const struct file_operations snd_timer_f_ops =
-{
- .owner = THIS_MODULE,
- .read = snd_timer_user_read,
- .open = snd_timer_user_open,
- .release = snd_timer_user_release,
- .llseek = no_llseek,
- .poll = snd_timer_user_poll,
- .unlocked_ioctl = snd_timer_user_ioctl,
- .compat_ioctl = snd_timer_user_ioctl_compat,
- .fasync = snd_timer_user_fasync,
-};
-
-/*
- * ENTRY functions
- */
-
-static int __init alsa_timer_init(void)
-{
- int err;
-
-#ifdef SNDRV_OSS_INFO_DEV_TIMERS
- snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1,
- "system timer");
-#endif
-
- if ((err = snd_timer_register_system()) < 0)
- snd_printk(KERN_ERR "unable to register system timer (%i)\n",
- err);
- if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0,
- &snd_timer_f_ops, NULL, "timer")) < 0)
- snd_printk(KERN_ERR "unable to register timer device (%i)\n",
- err);
- snd_timer_proc_init();
- return 0;
-}
-
-static void __exit alsa_timer_exit(void)
-{
- struct list_head *p, *n;
-
- snd_unregister_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0);
- /* unregister the system timer */
- list_for_each_safe(p, n, &snd_timer_list) {
- struct snd_timer *timer = list_entry(p, struct snd_timer, device_list);
- snd_timer_free(timer);
- }
- snd_timer_proc_done();
-#ifdef SNDRV_OSS_INFO_DEV_TIMERS
- snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1);
-#endif
-}
-
-module_init(alsa_timer_init)
-module_exit(alsa_timer_exit)
-
-EXPORT_SYMBOL(snd_timer_open);
-EXPORT_SYMBOL(snd_timer_close);
-EXPORT_SYMBOL(snd_timer_resolution);
-EXPORT_SYMBOL(snd_timer_start);
-EXPORT_SYMBOL(snd_timer_stop);
-EXPORT_SYMBOL(snd_timer_continue);
-EXPORT_SYMBOL(snd_timer_pause);
-EXPORT_SYMBOL(snd_timer_new);
-EXPORT_SYMBOL(snd_timer_notify);
-EXPORT_SYMBOL(snd_timer_global_new);
-EXPORT_SYMBOL(snd_timer_global_free);
-EXPORT_SYMBOL(snd_timer_global_register);
-EXPORT_SYMBOL(snd_timer_interrupt);
diff --git a/ANDROID_3.4.5/sound/core/timer_compat.c b/ANDROID_3.4.5/sound/core/timer_compat.c
deleted file mode 100644
index e05802ae..00000000
--- a/ANDROID_3.4.5/sound/core/timer_compat.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 32bit -> 64bit ioctl wrapper for timer API
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/* This file included from timer.c */
-
-#include <linux/compat.h>
-
-struct snd_timer_info32 {
- u32 flags;
- s32 card;
- unsigned char id[64];
- unsigned char name[80];
- u32 reserved0;
- u32 resolution;
- unsigned char reserved[64];
-};
-
-static int snd_timer_user_info_compat(struct file *file,
- struct snd_timer_info32 __user *_info)
-{
- struct snd_timer_user *tu;
- struct snd_timer_info32 info;
- struct snd_timer *t;
-
- tu = file->private_data;
- if (snd_BUG_ON(!tu->timeri))
- return -ENXIO;
- t = tu->timeri->timer;
- if (snd_BUG_ON(!t))
- return -ENXIO;
- memset(&info, 0, sizeof(info));
- info.card = t->card ? t->card->number : -1;
- if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
- info.flags |= SNDRV_TIMER_FLG_SLAVE;
- strlcpy(info.id, t->id, sizeof(info.id));
- strlcpy(info.name, t->name, sizeof(info.name));
- info.resolution = t->hw.resolution;
- if (copy_to_user(_info, &info, sizeof(*_info)))
- return -EFAULT;
- return 0;
-}
-
-struct snd_timer_status32 {
- struct compat_timespec tstamp;
- u32 resolution;
- u32 lost;
- u32 overrun;
- u32 queue;
- unsigned char reserved[64];
-};
-
-static int snd_timer_user_status_compat(struct file *file,
- struct snd_timer_status32 __user *_status)
-{
- struct snd_timer_user *tu;
- struct snd_timer_status status;
-
- tu = file->private_data;
- if (snd_BUG_ON(!tu->timeri))
- return -ENXIO;
- memset(&status, 0, sizeof(status));
- status.tstamp = tu->tstamp;
- status.resolution = snd_timer_resolution(tu->timeri);
- status.lost = tu->timeri->lost;
- status.overrun = tu->overrun;
- spin_lock_irq(&tu->qlock);
- status.queue = tu->qused;
- spin_unlock_irq(&tu->qlock);
- if (copy_to_user(_status, &status, sizeof(status)))
- return -EFAULT;
- return 0;
-}
-
-/*
- */
-
-enum {
- SNDRV_TIMER_IOCTL_INFO32 = _IOR('T', 0x11, struct snd_timer_info32),
- SNDRV_TIMER_IOCTL_STATUS32 = _IOW('T', 0x14, struct snd_timer_status32),
-};
-
-static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
-{
- void __user *argp = compat_ptr(arg);
-
- switch (cmd) {
- case SNDRV_TIMER_IOCTL_PVERSION:
- case SNDRV_TIMER_IOCTL_TREAD:
- case SNDRV_TIMER_IOCTL_GINFO:
- case SNDRV_TIMER_IOCTL_GPARAMS:
- case SNDRV_TIMER_IOCTL_GSTATUS:
- case SNDRV_TIMER_IOCTL_SELECT:
- case SNDRV_TIMER_IOCTL_PARAMS:
- case SNDRV_TIMER_IOCTL_START:
- case SNDRV_TIMER_IOCTL_START_OLD:
- case SNDRV_TIMER_IOCTL_STOP:
- case SNDRV_TIMER_IOCTL_STOP_OLD:
- case SNDRV_TIMER_IOCTL_CONTINUE:
- case SNDRV_TIMER_IOCTL_CONTINUE_OLD:
- case SNDRV_TIMER_IOCTL_PAUSE:
- case SNDRV_TIMER_IOCTL_PAUSE_OLD:
- case SNDRV_TIMER_IOCTL_NEXT_DEVICE:
- return snd_timer_user_ioctl(file, cmd, (unsigned long)argp);
- case SNDRV_TIMER_IOCTL_INFO32:
- return snd_timer_user_info_compat(file, argp);
- case SNDRV_TIMER_IOCTL_STATUS32:
- return snd_timer_user_status_compat(file, argp);
- }
- return -ENOIOCTLCMD;
-}
diff --git a/ANDROID_3.4.5/sound/core/vmaster.c b/ANDROID_3.4.5/sound/core/vmaster.c
deleted file mode 100644
index 85758613..00000000
--- a/ANDROID_3.4.5/sound/core/vmaster.c
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * Virtual master and slave controls
- *
- * Copyright (c) 2008 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
-
-#include <linux/slab.h>
-#include <linux/export.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-
-/*
- * a subset of information returned via ctl info callback
- */
-struct link_ctl_info {
- snd_ctl_elem_type_t type; /* value type */
- int count; /* item count */
- int min_val, max_val; /* min, max values */
-};
-
-/*
- * link master - this contains a list of slave controls that are
- * identical types, i.e. info returns the same value type and value
- * ranges, but may have different number of counts.
- *
- * The master control is so far only mono volume/switch for simplicity.
- * The same value will be applied to all slaves.
- */
-struct link_master {
- struct list_head slaves;
- struct link_ctl_info info;
- int val; /* the master value */
- unsigned int tlv[4];
- void (*hook)(void *private_data, int);
- void *hook_private_data;
-};
-
-/*
- * link slave - this contains a slave control element
- *
- * It fakes the control callbacsk with additional attenuation by the
- * master control. A slave may have either one or two channels.
- */
-
-struct link_slave {
- struct list_head list;
- struct link_master *master;
- struct link_ctl_info info;
- int vals[2]; /* current values */
- unsigned int flags;
- struct snd_kcontrol *kctl; /* original kcontrol pointer */
- struct snd_kcontrol slave; /* the copy of original control entry */
-};
-
-static int slave_update(struct link_slave *slave)
-{
- struct snd_ctl_elem_value *uctl;
- int err, ch;
-
- uctl = kmalloc(sizeof(*uctl), GFP_KERNEL);
- if (!uctl)
- return -ENOMEM;
- uctl->id = slave->slave.id;
- err = slave->slave.get(&slave->slave, uctl);
- for (ch = 0; ch < slave->info.count; ch++)
- slave->vals[ch] = uctl->value.integer.value[ch];
- kfree(uctl);
- return 0;
-}
-
-/* get the slave ctl info and save the initial values */
-static int slave_init(struct link_slave *slave)
-{
- struct snd_ctl_elem_info *uinfo;
- int err;
-
- if (slave->info.count) {
- /* already initialized */
- if (slave->flags & SND_CTL_SLAVE_NEED_UPDATE)
- return slave_update(slave);
- return 0;
- }
-
- uinfo = kmalloc(sizeof(*uinfo), GFP_KERNEL);
- if (!uinfo)
- return -ENOMEM;
- uinfo->id = slave->slave.id;
- err = slave->slave.info(&slave->slave, uinfo);
- if (err < 0) {
- kfree(uinfo);
- return err;
- }
- slave->info.type = uinfo->type;
- slave->info.count = uinfo->count;
- if (slave->info.count > 2 ||
- (slave->info.type != SNDRV_CTL_ELEM_TYPE_INTEGER &&
- slave->info.type != SNDRV_CTL_ELEM_TYPE_BOOLEAN)) {
- snd_printk(KERN_ERR "invalid slave element\n");
- kfree(uinfo);
- return -EINVAL;
- }
- slave->info.min_val = uinfo->value.integer.min;
- slave->info.max_val = uinfo->value.integer.max;
- kfree(uinfo);
-
- return slave_update(slave);
-}
-
-/* initialize master volume */
-static int master_init(struct link_master *master)
-{
- struct link_slave *slave;
-
- if (master->info.count)
- return 0; /* already initialized */
-
- list_for_each_entry(slave, &master->slaves, list) {
- int err = slave_init(slave);
- if (err < 0)
- return err;
- master->info = slave->info;
- master->info.count = 1; /* always mono */
- /* set full volume as default (= no attenuation) */
- master->val = master->info.max_val;
- if (master->hook)
- master->hook(master->hook_private_data, master->val);
- return 1;
- }
- return -ENOENT;
-}
-
-static int slave_get_val(struct link_slave *slave,
- struct snd_ctl_elem_value *ucontrol)
-{
- int err, ch;
-
- err = slave_init(slave);
- if (err < 0)
- return err;
- for (ch = 0; ch < slave->info.count; ch++)
- ucontrol->value.integer.value[ch] = slave->vals[ch];
- return 0;
-}
-
-static int slave_put_val(struct link_slave *slave,
- struct snd_ctl_elem_value *ucontrol)
-{
- int err, ch, vol;
-
- err = master_init(slave->master);
- if (err < 0)
- return err;
-
- switch (slave->info.type) {
- case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
- for (ch = 0; ch < slave->info.count; ch++)
- ucontrol->value.integer.value[ch] &=
- !!slave->master->val;
- break;
- case SNDRV_CTL_ELEM_TYPE_INTEGER:
- for (ch = 0; ch < slave->info.count; ch++) {
- /* max master volume is supposed to be 0 dB */
- vol = ucontrol->value.integer.value[ch];
- vol += slave->master->val - slave->master->info.max_val;
- if (vol < slave->info.min_val)
- vol = slave->info.min_val;
- else if (vol > slave->info.max_val)
- vol = slave->info.max_val;
- ucontrol->value.integer.value[ch] = vol;
- }
- break;
- }
- return slave->slave.put(&slave->slave, ucontrol);
-}
-
-/*
- * ctl callbacks for slaves
- */
-static int slave_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct link_slave *slave = snd_kcontrol_chip(kcontrol);
- return slave->slave.info(&slave->slave, uinfo);
-}
-
-static int slave_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct link_slave *slave = snd_kcontrol_chip(kcontrol);
- return slave_get_val(slave, ucontrol);
-}
-
-static int slave_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct link_slave *slave = snd_kcontrol_chip(kcontrol);
- int err, ch, changed = 0;
-
- err = slave_init(slave);
- if (err < 0)
- return err;
- for (ch = 0; ch < slave->info.count; ch++) {
- if (slave->vals[ch] != ucontrol->value.integer.value[ch]) {
- changed = 1;
- slave->vals[ch] = ucontrol->value.integer.value[ch];
- }
- }
- if (!changed)
- return 0;
- return slave_put_val(slave, ucontrol);
-}
-
-static int slave_tlv_cmd(struct snd_kcontrol *kcontrol,
- int op_flag, unsigned int size,
- unsigned int __user *tlv)
-{
- struct link_slave *slave = snd_kcontrol_chip(kcontrol);
- /* FIXME: this assumes that the max volume is 0 dB */
- return slave->slave.tlv.c(&slave->slave, op_flag, size, tlv);
-}
-
-static void slave_free(struct snd_kcontrol *kcontrol)
-{
- struct link_slave *slave = snd_kcontrol_chip(kcontrol);
- if (slave->slave.private_free)
- slave->slave.private_free(&slave->slave);
- if (slave->master)
- list_del(&slave->list);
- kfree(slave);
-}
-
-/*
- * Add a slave control to the group with the given master control
- *
- * All slaves must be the same type (returning the same information
- * via info callback). The function doesn't check it, so it's your
- * responsibility.
- *
- * Also, some additional limitations:
- * - at most two channels
- * - logarithmic volume control (dB level), no linear volume
- * - master can only attenuate the volume, no gain
- */
-int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave,
- unsigned int flags)
-{
- struct link_master *master_link = snd_kcontrol_chip(master);
- struct link_slave *srec;
-
- srec = kzalloc(sizeof(*srec) +
- slave->count * sizeof(*slave->vd), GFP_KERNEL);
- if (!srec)
- return -ENOMEM;
- srec->kctl = slave;
- srec->slave = *slave;
- memcpy(srec->slave.vd, slave->vd, slave->count * sizeof(*slave->vd));
- srec->master = master_link;
- srec->flags = flags;
-
- /* override callbacks */
- slave->info = slave_info;
- slave->get = slave_get;
- slave->put = slave_put;
- if (slave->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK)
- slave->tlv.c = slave_tlv_cmd;
- slave->private_data = srec;
- slave->private_free = slave_free;
-
- list_add_tail(&srec->list, &master_link->slaves);
- return 0;
-}
-EXPORT_SYMBOL(_snd_ctl_add_slave);
-
-/*
- * ctl callbacks for master controls
- */
-static int master_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct link_master *master = snd_kcontrol_chip(kcontrol);
- int ret;
-
- ret = master_init(master);
- if (ret < 0)
- return ret;
- uinfo->type = master->info.type;
- uinfo->count = master->info.count;
- uinfo->value.integer.min = master->info.min_val;
- uinfo->value.integer.max = master->info.max_val;
- return 0;
-}
-
-static int master_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct link_master *master = snd_kcontrol_chip(kcontrol);
- int err = master_init(master);
- if (err < 0)
- return err;
- ucontrol->value.integer.value[0] = master->val;
- return 0;
-}
-
-static int master_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct link_master *master = snd_kcontrol_chip(kcontrol);
- struct link_slave *slave;
- struct snd_ctl_elem_value *uval;
- int err, old_val;
-
- err = master_init(master);
- if (err < 0)
- return err;
- old_val = master->val;
- if (ucontrol->value.integer.value[0] == old_val)
- return 0;
-
- uval = kmalloc(sizeof(*uval), GFP_KERNEL);
- if (!uval)
- return -ENOMEM;
- list_for_each_entry(slave, &master->slaves, list) {
- master->val = old_val;
- uval->id = slave->slave.id;
- slave_get_val(slave, uval);
- master->val = ucontrol->value.integer.value[0];
- slave_put_val(slave, uval);
- }
- kfree(uval);
- if (master->hook && !err)
- master->hook(master->hook_private_data, master->val);
- return 1;
-}
-
-static void master_free(struct snd_kcontrol *kcontrol)
-{
- struct link_master *master = snd_kcontrol_chip(kcontrol);
- struct link_slave *slave, *n;
-
- /* free all slave links and retore the original slave kctls */
- list_for_each_entry_safe(slave, n, &master->slaves, list) {
- struct snd_kcontrol *sctl = slave->kctl;
- struct list_head olist = sctl->list;
- memcpy(sctl, &slave->slave, sizeof(*sctl));
- memcpy(sctl->vd, slave->slave.vd,
- sctl->count * sizeof(*sctl->vd));
- sctl->list = olist; /* keep the current linked-list */
- kfree(slave);
- }
- kfree(master);
-}
-
-
-/**
- * snd_ctl_make_virtual_master - Create a virtual master control
- * @name: name string of the control element to create
- * @tlv: optional TLV int array for dB information
- *
- * Creates a virtual matster control with the given name string.
- * Returns the created control element, or NULL for errors (ENOMEM).
- *
- * After creating a vmaster element, you can add the slave controls
- * via snd_ctl_add_slave() or snd_ctl_add_slave_uncached().
- *
- * The optional argument @tlv can be used to specify the TLV information
- * for dB scale of the master control. It should be a single element
- * with #SNDRV_CTL_TLVT_DB_SCALE, #SNDRV_CTL_TLV_DB_MINMAX or
- * #SNDRV_CTL_TLVT_DB_MINMAX_MUTE type, and should be the max 0dB.
- */
-struct snd_kcontrol *snd_ctl_make_virtual_master(char *name,
- const unsigned int *tlv)
-{
- struct link_master *master;
- struct snd_kcontrol *kctl;
- struct snd_kcontrol_new knew;
-
- memset(&knew, 0, sizeof(knew));
- knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- knew.name = name;
- knew.info = master_info;
-
- master = kzalloc(sizeof(*master), GFP_KERNEL);
- if (!master)
- return NULL;
- INIT_LIST_HEAD(&master->slaves);
-
- kctl = snd_ctl_new1(&knew, master);
- if (!kctl) {
- kfree(master);
- return NULL;
- }
- /* override some callbacks */
- kctl->info = master_info;
- kctl->get = master_get;
- kctl->put = master_put;
- kctl->private_free = master_free;
-
- /* additional (constant) TLV read */
- if (tlv &&
- (tlv[0] == SNDRV_CTL_TLVT_DB_SCALE ||
- tlv[0] == SNDRV_CTL_TLVT_DB_MINMAX ||
- tlv[0] == SNDRV_CTL_TLVT_DB_MINMAX_MUTE)) {
- kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
- memcpy(master->tlv, tlv, sizeof(master->tlv));
- kctl->tlv.p = master->tlv;
- }
-
- return kctl;
-}
-EXPORT_SYMBOL(snd_ctl_make_virtual_master);
-
-/**
- * snd_ctl_add_vmaster_hook - Add a hook to a vmaster control
- * @kcontrol: vmaster kctl element
- * @hook: the hook function
- * @private_data: the private_data pointer to be saved
- *
- * Adds the given hook to the vmaster control element so that it's called
- * at each time when the value is changed.
- */
-int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kcontrol,
- void (*hook)(void *private_data, int),
- void *private_data)
-{
- struct link_master *master = snd_kcontrol_chip(kcontrol);
- master->hook = hook;
- master->hook_private_data = private_data;
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_ctl_add_vmaster_hook);
-
-/**
- * snd_ctl_sync_vmaster_hook - Sync the vmaster hook
- * @kcontrol: vmaster kctl element
- *
- * Call the hook function to synchronize with the current value of the given
- * vmaster element. NOP when NULL is passed to @kcontrol or the hook doesn't
- * exist.
- */
-void snd_ctl_sync_vmaster_hook(struct snd_kcontrol *kcontrol)
-{
- struct link_master *master;
- if (!kcontrol)
- return;
- master = snd_kcontrol_chip(kcontrol);
- if (master->hook)
- master->hook(master->hook_private_data, master->val);
-}
-EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster_hook);
diff --git a/ANDROID_3.4.5/sound/drivers/Kconfig b/ANDROID_3.4.5/sound/drivers/Kconfig
deleted file mode 100644
index fe5ae09f..00000000
--- a/ANDROID_3.4.5/sound/drivers/Kconfig
+++ /dev/null
@@ -1,223 +0,0 @@
-config SND_MPU401_UART
- tristate
- select SND_RAWMIDI
-
-config SND_OPL3_LIB
- tristate
- select SND_TIMER
- select SND_HWDEP
-
-config SND_OPL4_LIB
- tristate
- select SND_TIMER
- select SND_HWDEP
-
-config SND_VX_LIB
- tristate
- select SND_HWDEP
- select SND_PCM
-
-config SND_AC97_CODEC
- tristate
- select SND_PCM
- select AC97_BUS
- select SND_VMASTER
-
-menuconfig SND_DRIVERS
- bool "Generic sound devices"
- default y
- help
- Support for generic sound devices.
-
-if SND_DRIVERS
-
-config SND_PCSP
- tristate "PC-Speaker support (READ HELP!)"
- depends on PCSPKR_PLATFORM && X86 && HIGH_RES_TIMERS
- depends on INPUT
- depends on EXPERIMENTAL
- select SND_PCM
- help
- If you don't have a sound card in your computer, you can include a
- driver for the PC speaker which allows it to act like a primitive
- sound card.
- This driver also replaces the pcspkr driver for beeps.
-
- You can compile this as a module which will be called snd-pcsp.
-
- WARNING: if you already have a soundcard, enabling this
- driver may lead to a problem. Namely, it may get loaded
- before the other sound driver of yours, making the
- pc-speaker a default sound device. Which is likely not
- what you want. To make this driver play nicely with other
- sound driver, you can add this in a configuration file under
- /etc/modprobe.d/ directory:
- options snd-pcsp index=2
-
- You don't need this driver if you only want your pc-speaker to beep.
- You don't need this driver if you have a tablet piezo beeper
- in your PC instead of the real speaker.
-
- Say N if you have a sound card.
- Say M if you don't.
- Say Y only if you really know what you do.
-
-config SND_DUMMY
- tristate "Dummy (/dev/null) soundcard"
- select SND_PCM
- help
- Say Y here to include the dummy driver. This driver does
- nothing, but emulates various mixer controls and PCM devices.
-
- You don't need this unless you're testing the hardware support
- of programs using the ALSA API.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-dummy.
-
-config SND_ALOOP
- tristate "Generic loopback driver (PCM)"
- select SND_PCM
- help
- Say 'Y' or 'M' to include support for the PCM loopback device.
- This module returns played samples back to the user space using
- the standard ALSA PCM device. The devices are routed 0->1 and
- 1->0, where first number is the playback PCM device and second
- number is the capture device. Module creates two PCM devices and
- configured number of substreams (see the pcm_substreams module
- parameter).
-
- The looback device allow time sychronization with an external
- timing source using the time shift universal control (+-20%
- of system time).
-
- To compile this driver as a module, choose M here: the module
- will be called snd-aloop.
-
-config SND_VIRMIDI
- tristate "Virtual MIDI soundcard"
- depends on SND_SEQUENCER
- select SND_TIMER
- select SND_RAWMIDI
- help
- Say Y here to include the virtual MIDI driver. This driver
- allows to connect applications using raw MIDI devices to
- sequencer clients.
-
- If you don't know what MIDI is, say N here.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-virmidi.
-
-config SND_MTPAV
- tristate "MOTU MidiTimePiece AV multiport MIDI"
- select SND_RAWMIDI
- help
- To use a MOTU MidiTimePiece AV multiport MIDI adapter
- connected to the parallel port, say Y here and make sure that
- the standard parallel port driver isn't used for the port.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-mtpav.
-
-config SND_MTS64
- tristate "ESI Miditerminal 4140 driver"
- depends on PARPORT
- select SND_RAWMIDI
- help
- The ESI Miditerminal 4140 is a 4 In 4 Out MIDI Interface with
- additional SMPTE Timecode capabilities for the parallel port.
-
- Say 'Y' to include support for this device.
-
- To compile this driver as a module, chose 'M' here: the module
- will be called snd-mts64.
-
-config SND_SERIAL_U16550
- tristate "UART16550 serial MIDI driver"
- select SND_RAWMIDI
- help
- To include support for MIDI serial port interfaces, say Y here
- and read <file:Documentation/sound/alsa/serial-u16550.txt>.
- This driver works with serial UARTs 16550 and better.
-
- This driver accesses the serial port hardware directly, so
- make sure that the standard serial driver isn't used or
- deactivated with setserial before loading this driver.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-serial-u16550.
-
-config SND_MPU401
- tristate "Generic MPU-401 UART driver"
- select SND_MPU401_UART
- help
- Say Y here to include support for MIDI ports compatible with
- the Roland MPU-401 interface in UART mode.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-mpu401.
-
-config SND_PORTMAN2X4
- tristate "Portman 2x4 driver"
- depends on PARPORT
- select SND_RAWMIDI
- help
- Say Y here to include support for Midiman Portman 2x4 parallel
- port MIDI device.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-portman2x4.
-
-config SND_ML403_AC97CR
- tristate "Xilinx ML403 AC97 Controller Reference"
- depends on XILINX_VIRTEX
- select SND_AC97_CODEC
- help
- Say Y here to include support for the
- opb_ac97_controller_ref_v1_00_a ip core found in Xilinx's ML403
- reference design.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-ml403_ac97cr.
-
-config SND_AC97_POWER_SAVE
- bool "AC97 Power-Saving Mode"
- depends on SND_AC97_CODEC
- default n
- help
- Say Y here to enable the aggressive power-saving support of
- AC97 codecs. In this mode, the power-mode is dynamically
- controlled at each open/close.
-
- The mode is activated by passing 'power_save=X' to the
- snd-ac97-codec driver module, where 'X' is the time-out
- value, a nonnegative integer that specifies how many
- seconds of idle time the driver must count before it may
- put the AC97 into power-save mode; a value of 0 (zero)
- disables the use of this power-save mode.
-
- After the snd-ac97-codec driver module has been loaded,
- the 'power_save' parameter can be set via sysfs as follows:
-
- echo 10 > /sys/module/snd_ac97_codec/parameters/power_save
-
- In this case, the time-out is set to 10 seconds; setting
- the time-out to 1 second (the minimum activation value)
- isn't recommended because many applications try to reopen
- the device frequently. A value of 10 seconds would be a
- good choice for normal operations.
-
- See Documentation/sound/alsa/powersave.txt for more details.
-
-config SND_AC97_POWER_SAVE_DEFAULT
- int "Default time-out for AC97 power-save mode"
- depends on SND_AC97_POWER_SAVE
- default 0
- help
- The default time-out value in seconds for AC97 automatic
- power-save mode. 0 means to disable the power-save mode.
-
- See SND_AC97_POWER_SAVE for more details.
-
-endif # SND_DRIVERS
diff --git a/ANDROID_3.4.5/sound/drivers/Makefile b/ANDROID_3.4.5/sound/drivers/Makefile
deleted file mode 100644
index 1a8440c8..00000000
--- a/ANDROID_3.4.5/sound/drivers/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-dummy-objs := dummy.o
-snd-aloop-objs := aloop.o
-snd-mtpav-objs := mtpav.o
-snd-mts64-objs := mts64.o
-snd-portman2x4-objs := portman2x4.o
-snd-serial-u16550-objs := serial-u16550.o
-snd-virmidi-objs := virmidi.o
-snd-ml403-ac97cr-objs := ml403-ac97cr.o pcm-indirect2.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_DUMMY) += snd-dummy.o
-obj-$(CONFIG_SND_ALOOP) += snd-aloop.o
-obj-$(CONFIG_SND_VIRMIDI) += snd-virmidi.o
-obj-$(CONFIG_SND_SERIAL_U16550) += snd-serial-u16550.o
-obj-$(CONFIG_SND_MTPAV) += snd-mtpav.o
-obj-$(CONFIG_SND_MTS64) += snd-mts64.o
-obj-$(CONFIG_SND_PORTMAN2X4) += snd-portman2x4.o
-obj-$(CONFIG_SND_ML403_AC97CR) += snd-ml403-ac97cr.o
-
-obj-$(CONFIG_SND) += opl3/ opl4/ mpu401/ vx/ pcsp/
diff --git a/ANDROID_3.4.5/sound/drivers/aloop.c b/ANDROID_3.4.5/sound/drivers/aloop.c
deleted file mode 100644
index ad079b63..00000000
--- a/ANDROID_3.4.5/sound/drivers/aloop.c
+++ /dev/null
@@ -1,1258 +0,0 @@
-/*
- * Loopback soundcard
- *
- * Original code:
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- * More accurate positioning and full-duplex support:
- * Copyright (c) Ahmet İnan <ainan at mathematik.uni-freiburg.de>
- *
- * Major (almost complete) rewrite:
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- *
- * A next major update in 2010 (separate timers for playback and capture):
- * Copyright (c) Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/jiffies.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/info.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("A loopback soundcard");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ALSA,Loopback soundcard}}");
-
-#define MAX_PCM_SUBSTREAMS 8
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
-static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
-static int pcm_notify[SNDRV_CARDS];
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for loopback soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for loopback soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable this loopback soundcard.");
-module_param_array(pcm_substreams, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-8) for loopback driver.");
-module_param_array(pcm_notify, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_notify, "Break capture when PCM format/rate/channels changes.");
-
-#define NO_PITCH 100000
-
-struct loopback_pcm;
-
-struct loopback_cable {
- spinlock_t lock;
- struct loopback_pcm *streams[2];
- struct snd_pcm_hardware hw;
- /* flags */
- unsigned int valid;
- unsigned int running;
- unsigned int pause;
-};
-
-struct loopback_setup {
- unsigned int notify: 1;
- unsigned int rate_shift;
- unsigned int format;
- unsigned int rate;
- unsigned int channels;
- struct snd_ctl_elem_id active_id;
- struct snd_ctl_elem_id format_id;
- struct snd_ctl_elem_id rate_id;
- struct snd_ctl_elem_id channels_id;
-};
-
-struct loopback {
- struct snd_card *card;
- struct mutex cable_lock;
- struct loopback_cable *cables[MAX_PCM_SUBSTREAMS][2];
- struct snd_pcm *pcm[2];
- struct loopback_setup setup[MAX_PCM_SUBSTREAMS][2];
-};
-
-struct loopback_pcm {
- struct loopback *loopback;
- struct snd_pcm_substream *substream;
- struct loopback_cable *cable;
- unsigned int pcm_buffer_size;
- unsigned int buf_pos; /* position in buffer */
- unsigned int silent_size;
- /* PCM parameters */
- unsigned int pcm_period_size;
- unsigned int pcm_bps; /* bytes per second */
- unsigned int pcm_salign; /* bytes per sample * channels */
- unsigned int pcm_rate_shift; /* rate shift value */
- /* flags */
- unsigned int period_update_pending :1;
- /* timer stuff */
- unsigned int irq_pos; /* fractional IRQ position */
- unsigned int period_size_frac;
- unsigned long last_jiffies;
- struct timer_list timer;
-};
-
-static struct platform_device *devices[SNDRV_CARDS];
-
-static inline unsigned int byte_pos(struct loopback_pcm *dpcm, unsigned int x)
-{
- if (dpcm->pcm_rate_shift == NO_PITCH) {
- x /= HZ;
- } else {
- x = div_u64(NO_PITCH * (unsigned long long)x,
- HZ * (unsigned long long)dpcm->pcm_rate_shift);
- }
- return x - (x % dpcm->pcm_salign);
-}
-
-static inline unsigned int frac_pos(struct loopback_pcm *dpcm, unsigned int x)
-{
- if (dpcm->pcm_rate_shift == NO_PITCH) { /* no pitch */
- return x * HZ;
- } else {
- x = div_u64(dpcm->pcm_rate_shift * (unsigned long long)x * HZ,
- NO_PITCH);
- }
- return x;
-}
-
-static inline struct loopback_setup *get_setup(struct loopback_pcm *dpcm)
-{
- int device = dpcm->substream->pstr->pcm->device;
-
- if (dpcm->substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- device ^= 1;
- return &dpcm->loopback->setup[dpcm->substream->number][device];
-}
-
-static inline unsigned int get_notify(struct loopback_pcm *dpcm)
-{
- return get_setup(dpcm)->notify;
-}
-
-static inline unsigned int get_rate_shift(struct loopback_pcm *dpcm)
-{
- return get_setup(dpcm)->rate_shift;
-}
-
-static void loopback_timer_start(struct loopback_pcm *dpcm)
-{
- unsigned long tick;
- unsigned int rate_shift = get_rate_shift(dpcm);
-
- if (rate_shift != dpcm->pcm_rate_shift) {
- dpcm->pcm_rate_shift = rate_shift;
- dpcm->period_size_frac = frac_pos(dpcm, dpcm->pcm_period_size);
- }
- if (dpcm->period_size_frac <= dpcm->irq_pos) {
- dpcm->irq_pos %= dpcm->period_size_frac;
- dpcm->period_update_pending = 1;
- }
- tick = dpcm->period_size_frac - dpcm->irq_pos;
- tick = (tick + dpcm->pcm_bps - 1) / dpcm->pcm_bps;
- dpcm->timer.expires = jiffies + tick;
- add_timer(&dpcm->timer);
-}
-
-static inline void loopback_timer_stop(struct loopback_pcm *dpcm)
-{
- del_timer(&dpcm->timer);
- dpcm->timer.expires = 0;
-}
-
-#define CABLE_VALID_PLAYBACK (1 << SNDRV_PCM_STREAM_PLAYBACK)
-#define CABLE_VALID_CAPTURE (1 << SNDRV_PCM_STREAM_CAPTURE)
-#define CABLE_VALID_BOTH (CABLE_VALID_PLAYBACK|CABLE_VALID_CAPTURE)
-
-static int loopback_check_format(struct loopback_cable *cable, int stream)
-{
- struct snd_pcm_runtime *runtime, *cruntime;
- struct loopback_setup *setup;
- struct snd_card *card;
- int check;
-
- if (cable->valid != CABLE_VALID_BOTH) {
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
- goto __notify;
- return 0;
- }
- runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
- substream->runtime;
- cruntime = cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
- substream->runtime;
- check = runtime->format != cruntime->format ||
- runtime->rate != cruntime->rate ||
- runtime->channels != cruntime->channels;
- if (!check)
- return 0;
- if (stream == SNDRV_PCM_STREAM_CAPTURE) {
- return -EIO;
- } else {
- snd_pcm_stop(cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
- substream, SNDRV_PCM_STATE_DRAINING);
- __notify:
- runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
- substream->runtime;
- setup = get_setup(cable->streams[SNDRV_PCM_STREAM_PLAYBACK]);
- card = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->loopback->card;
- if (setup->format != runtime->format) {
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
- &setup->format_id);
- setup->format = runtime->format;
- }
- if (setup->rate != runtime->rate) {
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
- &setup->rate_id);
- setup->rate = runtime->rate;
- }
- if (setup->channels != runtime->channels) {
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
- &setup->channels_id);
- setup->channels = runtime->channels;
- }
- }
- return 0;
-}
-
-static void loopback_active_notify(struct loopback_pcm *dpcm)
-{
- snd_ctl_notify(dpcm->loopback->card,
- SNDRV_CTL_EVENT_MASK_VALUE,
- &get_setup(dpcm)->active_id);
-}
-
-static int loopback_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct loopback_pcm *dpcm = runtime->private_data;
- struct loopback_cable *cable = dpcm->cable;
- int err, stream = 1 << substream->stream;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- err = loopback_check_format(cable, substream->stream);
- if (err < 0)
- return err;
- dpcm->last_jiffies = jiffies;
- dpcm->pcm_rate_shift = 0;
- spin_lock(&cable->lock);
- cable->running |= stream;
- cable->pause &= ~stream;
- spin_unlock(&cable->lock);
- loopback_timer_start(dpcm);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- loopback_active_notify(dpcm);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- spin_lock(&cable->lock);
- cable->running &= ~stream;
- cable->pause &= ~stream;
- spin_unlock(&cable->lock);
- loopback_timer_stop(dpcm);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- loopback_active_notify(dpcm);
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- spin_lock(&cable->lock);
- cable->pause |= stream;
- spin_unlock(&cable->lock);
- loopback_timer_stop(dpcm);
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- spin_lock(&cable->lock);
- dpcm->last_jiffies = jiffies;
- cable->pause &= ~stream;
- spin_unlock(&cable->lock);
- loopback_timer_start(dpcm);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static void params_change_substream(struct loopback_pcm *dpcm,
- struct snd_pcm_runtime *runtime)
-{
- struct snd_pcm_runtime *dst_runtime;
-
- if (dpcm == NULL || dpcm->substream == NULL)
- return;
- dst_runtime = dpcm->substream->runtime;
- if (dst_runtime == NULL)
- return;
- dst_runtime->hw = dpcm->cable->hw;
-}
-
-static void params_change(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct loopback_pcm *dpcm = runtime->private_data;
- struct loopback_cable *cable = dpcm->cable;
-
- cable->hw.formats = (1ULL << runtime->format);
- cable->hw.rate_min = runtime->rate;
- cable->hw.rate_max = runtime->rate;
- cable->hw.channels_min = runtime->channels;
- cable->hw.channels_max = runtime->channels;
- params_change_substream(cable->streams[SNDRV_PCM_STREAM_PLAYBACK],
- runtime);
- params_change_substream(cable->streams[SNDRV_PCM_STREAM_CAPTURE],
- runtime);
-}
-
-static int loopback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct loopback_pcm *dpcm = runtime->private_data;
- struct loopback_cable *cable = dpcm->cable;
- int bps, salign;
-
- salign = (snd_pcm_format_width(runtime->format) *
- runtime->channels) / 8;
- bps = salign * runtime->rate;
- if (bps <= 0 || salign <= 0)
- return -EINVAL;
-
- dpcm->buf_pos = 0;
- dpcm->pcm_buffer_size = frames_to_bytes(runtime, runtime->buffer_size);
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- /* clear capture buffer */
- dpcm->silent_size = dpcm->pcm_buffer_size;
- snd_pcm_format_set_silence(runtime->format, runtime->dma_area,
- runtime->buffer_size * runtime->channels);
- }
-
- dpcm->irq_pos = 0;
- dpcm->period_update_pending = 0;
- dpcm->pcm_bps = bps;
- dpcm->pcm_salign = salign;
- dpcm->pcm_period_size = frames_to_bytes(runtime, runtime->period_size);
-
- mutex_lock(&dpcm->loopback->cable_lock);
- if (!(cable->valid & ~(1 << substream->stream)) ||
- (get_setup(dpcm)->notify &&
- substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
- params_change(substream);
- cable->valid |= 1 << substream->stream;
- mutex_unlock(&dpcm->loopback->cable_lock);
-
- return 0;
-}
-
-static void clear_capture_buf(struct loopback_pcm *dpcm, unsigned int bytes)
-{
- struct snd_pcm_runtime *runtime = dpcm->substream->runtime;
- char *dst = runtime->dma_area;
- unsigned int dst_off = dpcm->buf_pos;
-
- if (dpcm->silent_size >= dpcm->pcm_buffer_size)
- return;
- if (dpcm->silent_size + bytes > dpcm->pcm_buffer_size)
- bytes = dpcm->pcm_buffer_size - dpcm->silent_size;
-
- for (;;) {
- unsigned int size = bytes;
- if (dst_off + size > dpcm->pcm_buffer_size)
- size = dpcm->pcm_buffer_size - dst_off;
- snd_pcm_format_set_silence(runtime->format, dst + dst_off,
- bytes_to_frames(runtime, size) *
- runtime->channels);
- dpcm->silent_size += size;
- bytes -= size;
- if (!bytes)
- break;
- dst_off = 0;
- }
-}
-
-static void copy_play_buf(struct loopback_pcm *play,
- struct loopback_pcm *capt,
- unsigned int bytes)
-{
- struct snd_pcm_runtime *runtime = play->substream->runtime;
- char *src = runtime->dma_area;
- char *dst = capt->substream->runtime->dma_area;
- unsigned int src_off = play->buf_pos;
- unsigned int dst_off = capt->buf_pos;
- unsigned int clear_bytes = 0;
-
- /* check if playback is draining, trim the capture copy size
- * when our pointer is at the end of playback ring buffer */
- if (runtime->status->state == SNDRV_PCM_STATE_DRAINING &&
- snd_pcm_playback_hw_avail(runtime) < runtime->buffer_size) {
- snd_pcm_uframes_t appl_ptr, appl_ptr1, diff;
- appl_ptr = appl_ptr1 = runtime->control->appl_ptr;
- appl_ptr1 -= appl_ptr1 % runtime->buffer_size;
- appl_ptr1 += play->buf_pos / play->pcm_salign;
- if (appl_ptr < appl_ptr1)
- appl_ptr1 -= runtime->buffer_size;
- diff = (appl_ptr - appl_ptr1) * play->pcm_salign;
- if (diff < bytes) {
- clear_bytes = bytes - diff;
- bytes = diff;
- }
- }
-
- for (;;) {
- unsigned int size = bytes;
- if (src_off + size > play->pcm_buffer_size)
- size = play->pcm_buffer_size - src_off;
- if (dst_off + size > capt->pcm_buffer_size)
- size = capt->pcm_buffer_size - dst_off;
- memcpy(dst + dst_off, src + src_off, size);
- capt->silent_size = 0;
- bytes -= size;
- if (!bytes)
- break;
- src_off = (src_off + size) % play->pcm_buffer_size;
- dst_off = (dst_off + size) % capt->pcm_buffer_size;
- }
-
- if (clear_bytes > 0) {
- clear_capture_buf(capt, clear_bytes);
- capt->silent_size = 0;
- }
-}
-
-#define BYTEPOS_UPDATE_POSONLY 0
-#define BYTEPOS_UPDATE_CLEAR 1
-#define BYTEPOS_UPDATE_COPY 2
-
-static void loopback_bytepos_update(struct loopback_pcm *dpcm,
- unsigned int delta,
- unsigned int cmd)
-{
- unsigned int count;
- unsigned long last_pos;
-
- last_pos = byte_pos(dpcm, dpcm->irq_pos);
- dpcm->irq_pos += delta * dpcm->pcm_bps;
- count = byte_pos(dpcm, dpcm->irq_pos) - last_pos;
- if (!count)
- return;
- if (cmd == BYTEPOS_UPDATE_CLEAR)
- clear_capture_buf(dpcm, count);
- else if (cmd == BYTEPOS_UPDATE_COPY)
- copy_play_buf(dpcm->cable->streams[SNDRV_PCM_STREAM_PLAYBACK],
- dpcm->cable->streams[SNDRV_PCM_STREAM_CAPTURE],
- count);
- dpcm->buf_pos += count;
- dpcm->buf_pos %= dpcm->pcm_buffer_size;
- if (dpcm->irq_pos >= dpcm->period_size_frac) {
- dpcm->irq_pos %= dpcm->period_size_frac;
- dpcm->period_update_pending = 1;
- }
-}
-
-static unsigned int loopback_pos_update(struct loopback_cable *cable)
-{
- struct loopback_pcm *dpcm_play =
- cable->streams[SNDRV_PCM_STREAM_PLAYBACK];
- struct loopback_pcm *dpcm_capt =
- cable->streams[SNDRV_PCM_STREAM_CAPTURE];
- unsigned long delta_play = 0, delta_capt = 0;
- unsigned int running;
- unsigned long flags;
-
- spin_lock_irqsave(&cable->lock, flags);
- running = cable->running ^ cable->pause;
- if (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) {
- delta_play = jiffies - dpcm_play->last_jiffies;
- dpcm_play->last_jiffies += delta_play;
- }
-
- if (running & (1 << SNDRV_PCM_STREAM_CAPTURE)) {
- delta_capt = jiffies - dpcm_capt->last_jiffies;
- dpcm_capt->last_jiffies += delta_capt;
- }
-
- if (delta_play == 0 && delta_capt == 0)
- goto unlock;
-
- if (delta_play > delta_capt) {
- loopback_bytepos_update(dpcm_play, delta_play - delta_capt,
- BYTEPOS_UPDATE_POSONLY);
- delta_play = delta_capt;
- } else if (delta_play < delta_capt) {
- loopback_bytepos_update(dpcm_capt, delta_capt - delta_play,
- BYTEPOS_UPDATE_CLEAR);
- delta_capt = delta_play;
- }
-
- if (delta_play == 0 && delta_capt == 0)
- goto unlock;
-
- /* note delta_capt == delta_play at this moment */
- loopback_bytepos_update(dpcm_capt, delta_capt, BYTEPOS_UPDATE_COPY);
- loopback_bytepos_update(dpcm_play, delta_play, BYTEPOS_UPDATE_POSONLY);
- unlock:
- spin_unlock_irqrestore(&cable->lock, flags);
- return running;
-}
-
-static void loopback_timer_function(unsigned long data)
-{
- struct loopback_pcm *dpcm = (struct loopback_pcm *)data;
- unsigned int running;
-
- running = loopback_pos_update(dpcm->cable);
- if (running & (1 << dpcm->substream->stream)) {
- loopback_timer_start(dpcm);
- if (dpcm->period_update_pending) {
- dpcm->period_update_pending = 0;
- snd_pcm_period_elapsed(dpcm->substream);
- }
- }
-}
-
-static snd_pcm_uframes_t loopback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct loopback_pcm *dpcm = runtime->private_data;
-
- loopback_pos_update(dpcm->cable);
- return bytes_to_frames(runtime, dpcm->buf_pos);
-}
-
-static struct snd_pcm_hardware loopback_pcm_hardware =
-{
- .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE),
- .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |
- SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_192000,
- .rate_min = 8000,
- .rate_max = 192000,
- .channels_min = 1,
- .channels_max = 32,
- .buffer_bytes_max = 2 * 1024 * 1024,
- .period_bytes_min = 64,
- /* note check overflow in frac_pos() using pcm_rate_shift before
- changing period_bytes_max value */
- .period_bytes_max = 1024 * 1024,
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static void loopback_runtime_free(struct snd_pcm_runtime *runtime)
-{
- struct loopback_pcm *dpcm = runtime->private_data;
- kfree(dpcm);
-}
-
-static int loopback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- return snd_pcm_lib_alloc_vmalloc_buffer(substream,
- params_buffer_bytes(params));
-}
-
-static int loopback_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct loopback_pcm *dpcm = runtime->private_data;
- struct loopback_cable *cable = dpcm->cable;
-
- mutex_lock(&dpcm->loopback->cable_lock);
- cable->valid &= ~(1 << substream->stream);
- mutex_unlock(&dpcm->loopback->cable_lock);
- return snd_pcm_lib_free_vmalloc_buffer(substream);
-}
-
-static unsigned int get_cable_index(struct snd_pcm_substream *substream)
-{
- if (!substream->pcm->device)
- return substream->stream;
- else
- return !substream->stream;
-}
-
-static int rule_format(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
-
- struct snd_pcm_hardware *hw = rule->private;
- struct snd_mask *maskp = hw_param_mask(params, rule->var);
-
- maskp->bits[0] &= (u_int32_t)hw->formats;
- maskp->bits[1] &= (u_int32_t)(hw->formats >> 32);
- memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX-64) / 8); /* clear rest */
- if (! maskp->bits[0] && ! maskp->bits[1])
- return -EINVAL;
- return 0;
-}
-
-static int rule_rate(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_pcm_hardware *hw = rule->private;
- struct snd_interval t;
-
- t.min = hw->rate_min;
- t.max = hw->rate_max;
- t.openmin = t.openmax = 0;
- t.integer = 0;
- return snd_interval_refine(hw_param_interval(params, rule->var), &t);
-}
-
-static int rule_channels(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_pcm_hardware *hw = rule->private;
- struct snd_interval t;
-
- t.min = hw->channels_min;
- t.max = hw->channels_max;
- t.openmin = t.openmax = 0;
- t.integer = 0;
- return snd_interval_refine(hw_param_interval(params, rule->var), &t);
-}
-
-static int loopback_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct loopback *loopback = substream->private_data;
- struct loopback_pcm *dpcm;
- struct loopback_cable *cable;
- int err = 0;
- int dev = get_cable_index(substream);
-
- mutex_lock(&loopback->cable_lock);
- dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
- if (!dpcm) {
- err = -ENOMEM;
- goto unlock;
- }
- dpcm->loopback = loopback;
- dpcm->substream = substream;
- setup_timer(&dpcm->timer, loopback_timer_function,
- (unsigned long)dpcm);
-
- cable = loopback->cables[substream->number][dev];
- if (!cable) {
- cable = kzalloc(sizeof(*cable), GFP_KERNEL);
- if (!cable) {
- kfree(dpcm);
- err = -ENOMEM;
- goto unlock;
- }
- spin_lock_init(&cable->lock);
- cable->hw = loopback_pcm_hardware;
- loopback->cables[substream->number][dev] = cable;
- }
- dpcm->cable = cable;
- cable->streams[substream->stream] = dpcm;
-
- snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
-
- /* use dynamic rules based on actual runtime->hw values */
- /* note that the default rules created in the PCM midlevel code */
- /* are cached -> they do not reflect the actual state */
- err = snd_pcm_hw_rule_add(runtime, 0,
- SNDRV_PCM_HW_PARAM_FORMAT,
- rule_format, &runtime->hw,
- SNDRV_PCM_HW_PARAM_FORMAT, -1);
- if (err < 0)
- goto unlock;
- err = snd_pcm_hw_rule_add(runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- rule_rate, &runtime->hw,
- SNDRV_PCM_HW_PARAM_RATE, -1);
- if (err < 0)
- goto unlock;
- err = snd_pcm_hw_rule_add(runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- rule_channels, &runtime->hw,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
- if (err < 0)
- goto unlock;
-
- runtime->private_data = dpcm;
- runtime->private_free = loopback_runtime_free;
- if (get_notify(dpcm))
- runtime->hw = loopback_pcm_hardware;
- else
- runtime->hw = cable->hw;
- unlock:
- mutex_unlock(&loopback->cable_lock);
- return err;
-}
-
-static int loopback_close(struct snd_pcm_substream *substream)
-{
- struct loopback *loopback = substream->private_data;
- struct loopback_pcm *dpcm = substream->runtime->private_data;
- struct loopback_cable *cable;
- int dev = get_cable_index(substream);
-
- loopback_timer_stop(dpcm);
- mutex_lock(&loopback->cable_lock);
- cable = loopback->cables[substream->number][dev];
- if (cable->streams[!substream->stream]) {
- /* other stream is still alive */
- cable->streams[substream->stream] = NULL;
- } else {
- /* free the cable */
- loopback->cables[substream->number][dev] = NULL;
- kfree(cable);
- }
- mutex_unlock(&loopback->cable_lock);
- return 0;
-}
-
-static struct snd_pcm_ops loopback_playback_ops = {
- .open = loopback_open,
- .close = loopback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = loopback_hw_params,
- .hw_free = loopback_hw_free,
- .prepare = loopback_prepare,
- .trigger = loopback_trigger,
- .pointer = loopback_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
-};
-
-static struct snd_pcm_ops loopback_capture_ops = {
- .open = loopback_open,
- .close = loopback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = loopback_hw_params,
- .hw_free = loopback_hw_free,
- .prepare = loopback_prepare,
- .trigger = loopback_trigger,
- .pointer = loopback_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
-};
-
-static int __devinit loopback_pcm_new(struct loopback *loopback,
- int device, int substreams)
-{
- struct snd_pcm *pcm;
- int err;
-
- err = snd_pcm_new(loopback->card, "Loopback PCM", device,
- substreams, substreams, &pcm);
- if (err < 0)
- return err;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &loopback_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &loopback_capture_ops);
-
- pcm->private_data = loopback;
- pcm->info_flags = 0;
- strcpy(pcm->name, "Loopback PCM");
-
- loopback->pcm[device] = pcm;
- return 0;
-}
-
-static int loopback_rate_shift_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 80000;
- uinfo->value.integer.max = 120000;
- uinfo->value.integer.step = 1;
- return 0;
-}
-
-static int loopback_rate_shift_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct loopback *loopback = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] =
- loopback->setup[kcontrol->id.subdevice]
- [kcontrol->id.device].rate_shift;
- return 0;
-}
-
-static int loopback_rate_shift_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct loopback *loopback = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change = 0;
-
- val = ucontrol->value.integer.value[0];
- if (val < 80000)
- val = 80000;
- if (val > 120000)
- val = 120000;
- mutex_lock(&loopback->cable_lock);
- if (val != loopback->setup[kcontrol->id.subdevice]
- [kcontrol->id.device].rate_shift) {
- loopback->setup[kcontrol->id.subdevice]
- [kcontrol->id.device].rate_shift = val;
- change = 1;
- }
- mutex_unlock(&loopback->cable_lock);
- return change;
-}
-
-static int loopback_notify_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct loopback *loopback = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] =
- loopback->setup[kcontrol->id.subdevice]
- [kcontrol->id.device].notify;
- return 0;
-}
-
-static int loopback_notify_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct loopback *loopback = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change = 0;
-
- val = ucontrol->value.integer.value[0] ? 1 : 0;
- if (val != loopback->setup[kcontrol->id.subdevice]
- [kcontrol->id.device].notify) {
- loopback->setup[kcontrol->id.subdevice]
- [kcontrol->id.device].notify = val;
- change = 1;
- }
- return change;
-}
-
-static int loopback_active_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct loopback *loopback = snd_kcontrol_chip(kcontrol);
- struct loopback_cable *cable = loopback->cables
- [kcontrol->id.subdevice][kcontrol->id.device ^ 1];
- unsigned int val = 0;
-
- if (cable != NULL)
- val = (cable->running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ?
- 1 : 0;
- ucontrol->value.integer.value[0] = val;
- return 0;
-}
-
-static int loopback_format_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = SNDRV_PCM_FORMAT_LAST;
- uinfo->value.integer.step = 1;
- return 0;
-}
-
-static int loopback_format_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct loopback *loopback = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] =
- loopback->setup[kcontrol->id.subdevice]
- [kcontrol->id.device].format;
- return 0;
-}
-
-static int loopback_rate_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 192000;
- uinfo->value.integer.step = 1;
- return 0;
-}
-
-static int loopback_rate_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct loopback *loopback = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] =
- loopback->setup[kcontrol->id.subdevice]
- [kcontrol->id.device].rate;
- return 0;
-}
-
-static int loopback_channels_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 1;
- uinfo->value.integer.max = 1024;
- uinfo->value.integer.step = 1;
- return 0;
-}
-
-static int loopback_channels_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct loopback *loopback = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] =
- loopback->setup[kcontrol->id.subdevice]
- [kcontrol->id.device].channels;
- return 0;
-}
-
-static struct snd_kcontrol_new loopback_controls[] __devinitdata = {
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "PCM Rate Shift 100000",
- .info = loopback_rate_shift_info,
- .get = loopback_rate_shift_get,
- .put = loopback_rate_shift_put,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "PCM Notify",
- .info = snd_ctl_boolean_mono_info,
- .get = loopback_notify_get,
- .put = loopback_notify_put,
-},
-#define ACTIVE_IDX 2
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "PCM Slave Active",
- .info = snd_ctl_boolean_mono_info,
- .get = loopback_active_get,
-},
-#define FORMAT_IDX 3
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "PCM Slave Format",
- .info = loopback_format_info,
- .get = loopback_format_get
-},
-#define RATE_IDX 4
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "PCM Slave Rate",
- .info = loopback_rate_info,
- .get = loopback_rate_get
-},
-#define CHANNELS_IDX 5
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "PCM Slave Channels",
- .info = loopback_channels_info,
- .get = loopback_channels_get
-}
-};
-
-static int __devinit loopback_mixer_new(struct loopback *loopback, int notify)
-{
- struct snd_card *card = loopback->card;
- struct snd_pcm *pcm;
- struct snd_kcontrol *kctl;
- struct loopback_setup *setup;
- int err, dev, substr, substr_count, idx;
-
- strcpy(card->mixername, "Loopback Mixer");
- for (dev = 0; dev < 2; dev++) {
- pcm = loopback->pcm[dev];
- substr_count =
- pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count;
- for (substr = 0; substr < substr_count; substr++) {
- setup = &loopback->setup[substr][dev];
- setup->notify = notify;
- setup->rate_shift = NO_PITCH;
- setup->format = SNDRV_PCM_FORMAT_S16_LE;
- setup->rate = 48000;
- setup->channels = 2;
- for (idx = 0; idx < ARRAY_SIZE(loopback_controls);
- idx++) {
- kctl = snd_ctl_new1(&loopback_controls[idx],
- loopback);
- if (!kctl)
- return -ENOMEM;
- kctl->id.device = dev;
- kctl->id.subdevice = substr;
- switch (idx) {
- case ACTIVE_IDX:
- setup->active_id = kctl->id;
- break;
- case FORMAT_IDX:
- setup->format_id = kctl->id;
- break;
- case RATE_IDX:
- setup->rate_id = kctl->id;
- break;
- case CHANNELS_IDX:
- setup->channels_id = kctl->id;
- break;
- default:
- break;
- }
- err = snd_ctl_add(card, kctl);
- if (err < 0)
- return err;
- }
- }
- }
- return 0;
-}
-
-#ifdef CONFIG_PROC_FS
-
-static void print_dpcm_info(struct snd_info_buffer *buffer,
- struct loopback_pcm *dpcm,
- const char *id)
-{
- snd_iprintf(buffer, " %s\n", id);
- if (dpcm == NULL) {
- snd_iprintf(buffer, " inactive\n");
- return;
- }
- snd_iprintf(buffer, " buffer_size:\t%u\n", dpcm->pcm_buffer_size);
- snd_iprintf(buffer, " buffer_pos:\t\t%u\n", dpcm->buf_pos);
- snd_iprintf(buffer, " silent_size:\t%u\n", dpcm->silent_size);
- snd_iprintf(buffer, " period_size:\t%u\n", dpcm->pcm_period_size);
- snd_iprintf(buffer, " bytes_per_sec:\t%u\n", dpcm->pcm_bps);
- snd_iprintf(buffer, " sample_align:\t%u\n", dpcm->pcm_salign);
- snd_iprintf(buffer, " rate_shift:\t\t%u\n", dpcm->pcm_rate_shift);
- snd_iprintf(buffer, " update_pending:\t%u\n",
- dpcm->period_update_pending);
- snd_iprintf(buffer, " irq_pos:\t\t%u\n", dpcm->irq_pos);
- snd_iprintf(buffer, " period_frac:\t%u\n", dpcm->period_size_frac);
- snd_iprintf(buffer, " last_jiffies:\t%lu (%lu)\n",
- dpcm->last_jiffies, jiffies);
- snd_iprintf(buffer, " timer_expires:\t%lu\n", dpcm->timer.expires);
-}
-
-static void print_substream_info(struct snd_info_buffer *buffer,
- struct loopback *loopback,
- int sub,
- int num)
-{
- struct loopback_cable *cable = loopback->cables[sub][num];
-
- snd_iprintf(buffer, "Cable %i substream %i:\n", num, sub);
- if (cable == NULL) {
- snd_iprintf(buffer, " inactive\n");
- return;
- }
- snd_iprintf(buffer, " valid: %u\n", cable->valid);
- snd_iprintf(buffer, " running: %u\n", cable->running);
- snd_iprintf(buffer, " pause: %u\n", cable->pause);
- print_dpcm_info(buffer, cable->streams[0], "Playback");
- print_dpcm_info(buffer, cable->streams[1], "Capture");
-}
-
-static void print_cable_info(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct loopback *loopback = entry->private_data;
- int sub, num;
-
- mutex_lock(&loopback->cable_lock);
- num = entry->name[strlen(entry->name)-1];
- num = num == '0' ? 0 : 1;
- for (sub = 0; sub < MAX_PCM_SUBSTREAMS; sub++)
- print_substream_info(buffer, loopback, sub, num);
- mutex_unlock(&loopback->cable_lock);
-}
-
-static int __devinit loopback_proc_new(struct loopback *loopback, int cidx)
-{
- char name[32];
- struct snd_info_entry *entry;
- int err;
-
- snprintf(name, sizeof(name), "cable#%d", cidx);
- err = snd_card_proc_new(loopback->card, name, &entry);
- if (err < 0)
- return err;
-
- snd_info_set_text_ops(entry, loopback, print_cable_info);
- return 0;
-}
-
-#else /* !CONFIG_PROC_FS */
-
-#define loopback_proc_new(loopback, cidx) do { } while (0)
-
-#endif
-
-static int __devinit loopback_probe(struct platform_device *devptr)
-{
- struct snd_card *card;
- struct loopback *loopback;
- int dev = devptr->id;
- int err;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct loopback), &card);
- if (err < 0)
- return err;
- loopback = card->private_data;
-
- if (pcm_substreams[dev] < 1)
- pcm_substreams[dev] = 1;
- if (pcm_substreams[dev] > MAX_PCM_SUBSTREAMS)
- pcm_substreams[dev] = MAX_PCM_SUBSTREAMS;
-
- loopback->card = card;
- mutex_init(&loopback->cable_lock);
-
- err = loopback_pcm_new(loopback, 0, pcm_substreams[dev]);
- if (err < 0)
- goto __nodev;
- err = loopback_pcm_new(loopback, 1, pcm_substreams[dev]);
- if (err < 0)
- goto __nodev;
- err = loopback_mixer_new(loopback, pcm_notify[dev] ? 1 : 0);
- if (err < 0)
- goto __nodev;
- loopback_proc_new(loopback, 0);
- loopback_proc_new(loopback, 1);
- strcpy(card->driver, "Loopback");
- strcpy(card->shortname, "Loopback");
- sprintf(card->longname, "Loopback %i", dev + 1);
- err = snd_card_register(card);
- if (!err) {
- platform_set_drvdata(devptr, card);
- return 0;
- }
- __nodev:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit loopback_remove(struct platform_device *devptr)
-{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int loopback_suspend(struct platform_device *pdev,
- pm_message_t state)
-{
- struct snd_card *card = platform_get_drvdata(pdev);
- struct loopback *loopback = card->private_data;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-
- snd_pcm_suspend_all(loopback->pcm[0]);
- snd_pcm_suspend_all(loopback->pcm[1]);
- return 0;
-}
-
-static int loopback_resume(struct platform_device *pdev)
-{
- struct snd_card *card = platform_get_drvdata(pdev);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif
-
-#define SND_LOOPBACK_DRIVER "snd_aloop"
-
-static struct platform_driver loopback_driver = {
- .probe = loopback_probe,
- .remove = __devexit_p(loopback_remove),
-#ifdef CONFIG_PM
- .suspend = loopback_suspend,
- .resume = loopback_resume,
-#endif
- .driver = {
- .name = SND_LOOPBACK_DRIVER
- },
-};
-
-static void loopback_unregister_all(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(devices); ++i)
- platform_device_unregister(devices[i]);
- platform_driver_unregister(&loopback_driver);
-}
-
-static int __init alsa_card_loopback_init(void)
-{
- int i, err, cards;
-
- err = platform_driver_register(&loopback_driver);
- if (err < 0)
- return err;
-
-
- cards = 0;
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (!enable[i])
- continue;
- device = platform_device_register_simple(SND_LOOPBACK_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- devices[i] = device;
- cards++;
- }
- if (!cards) {
-#ifdef MODULE
- printk(KERN_ERR "aloop: No loopback enabled\n");
-#endif
- loopback_unregister_all();
- return -ENODEV;
- }
- return 0;
-}
-
-static void __exit alsa_card_loopback_exit(void)
-{
- loopback_unregister_all();
-}
-
-module_init(alsa_card_loopback_init)
-module_exit(alsa_card_loopback_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/dummy.c b/ANDROID_3.4.5/sound/drivers/dummy.c
deleted file mode 100644
index ad9434fd..00000000
--- a/ANDROID_3.4.5/sound/drivers/dummy.c
+++ /dev/null
@@ -1,1157 +0,0 @@
-/*
- * Dummy soundcard
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/jiffies.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/hrtimer.h>
-#include <linux/math64.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/pcm.h>
-#include <sound/rawmidi.h>
-#include <sound/info.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Dummy soundcard (/dev/null)");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ALSA,Dummy soundcard}}");
-
-#define MAX_PCM_DEVICES 4
-#define MAX_PCM_SUBSTREAMS 128
-#define MAX_MIDI_DEVICES 2
-
-/* defaults */
-#define MAX_BUFFER_SIZE (64*1024)
-#define MIN_PERIOD_SIZE 64
-#define MAX_PERIOD_SIZE MAX_BUFFER_SIZE
-#define USE_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE)
-#define USE_RATE SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000
-#define USE_RATE_MIN 5500
-#define USE_RATE_MAX 48000
-#define USE_CHANNELS_MIN 1
-#define USE_CHANNELS_MAX 2
-#define USE_PERIODS_MIN 1
-#define USE_PERIODS_MAX 1024
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
-static char *model[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = NULL};
-static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
-static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
-//static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
-#ifdef CONFIG_HIGH_RES_TIMERS
-static bool hrtimer = 1;
-#endif
-static bool fake_buffer = 1;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for dummy soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for dummy soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable this dummy soundcard.");
-module_param_array(model, charp, NULL, 0444);
-MODULE_PARM_DESC(model, "Soundcard model.");
-module_param_array(pcm_devs, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver.");
-module_param_array(pcm_substreams, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-128) for dummy driver.");
-//module_param_array(midi_devs, int, NULL, 0444);
-//MODULE_PARM_DESC(midi_devs, "MIDI devices # (0-2) for dummy driver.");
-module_param(fake_buffer, bool, 0444);
-MODULE_PARM_DESC(fake_buffer, "Fake buffer allocations.");
-#ifdef CONFIG_HIGH_RES_TIMERS
-module_param(hrtimer, bool, 0644);
-MODULE_PARM_DESC(hrtimer, "Use hrtimer as the timer source.");
-#endif
-
-static struct platform_device *devices[SNDRV_CARDS];
-
-#define MIXER_ADDR_MASTER 0
-#define MIXER_ADDR_LINE 1
-#define MIXER_ADDR_MIC 2
-#define MIXER_ADDR_SYNTH 3
-#define MIXER_ADDR_CD 4
-#define MIXER_ADDR_LAST 4
-
-struct dummy_timer_ops {
- int (*create)(struct snd_pcm_substream *);
- void (*free)(struct snd_pcm_substream *);
- int (*prepare)(struct snd_pcm_substream *);
- int (*start)(struct snd_pcm_substream *);
- int (*stop)(struct snd_pcm_substream *);
- snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *);
-};
-
-struct dummy_model {
- const char *name;
- int (*playback_constraints)(struct snd_pcm_runtime *runtime);
- int (*capture_constraints)(struct snd_pcm_runtime *runtime);
- u64 formats;
- size_t buffer_bytes_max;
- size_t period_bytes_min;
- size_t period_bytes_max;
- unsigned int periods_min;
- unsigned int periods_max;
- unsigned int rates;
- unsigned int rate_min;
- unsigned int rate_max;
- unsigned int channels_min;
- unsigned int channels_max;
-};
-
-struct snd_dummy {
- struct snd_card *card;
- struct dummy_model *model;
- struct snd_pcm *pcm;
- struct snd_pcm_hardware pcm_hw;
- spinlock_t mixer_lock;
- int mixer_volume[MIXER_ADDR_LAST+1][2];
- int capture_source[MIXER_ADDR_LAST+1][2];
- const struct dummy_timer_ops *timer_ops;
-};
-
-/*
- * card models
- */
-
-static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
-{
- int err;
- err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0)
- return err;
- err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX);
- if (err < 0)
- return err;
- return 0;
-}
-
-struct dummy_model model_emu10k1 = {
- .name = "emu10k1",
- .playback_constraints = emu10k1_playback_constraints,
- .buffer_bytes_max = 128 * 1024,
-};
-
-struct dummy_model model_rme9652 = {
- .name = "rme9652",
- .buffer_bytes_max = 26 * 64 * 1024,
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .channels_min = 26,
- .channels_max = 26,
- .periods_min = 2,
- .periods_max = 2,
-};
-
-struct dummy_model model_ice1712 = {
- .name = "ice1712",
- .buffer_bytes_max = 256 * 1024,
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .channels_min = 10,
- .channels_max = 10,
- .periods_min = 1,
- .periods_max = 1024,
-};
-
-struct dummy_model model_uda1341 = {
- .name = "uda1341",
- .buffer_bytes_max = 16380,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .channels_min = 2,
- .channels_max = 2,
- .periods_min = 2,
- .periods_max = 255,
-};
-
-struct dummy_model model_ac97 = {
- .name = "ac97",
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
-};
-
-struct dummy_model model_ca0106 = {
- .name = "ca0106",
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .buffer_bytes_max = ((65536-64)*8),
- .period_bytes_max = (65536-64),
- .periods_min = 2,
- .periods_max = 8,
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_192000,
- .rate_min = 48000,
- .rate_max = 192000,
-};
-
-struct dummy_model *dummy_models[] = {
- &model_emu10k1,
- &model_rme9652,
- &model_ice1712,
- &model_uda1341,
- &model_ac97,
- &model_ca0106,
- NULL
-};
-
-/*
- * system timer interface
- */
-
-struct dummy_systimer_pcm {
- spinlock_t lock;
- struct timer_list timer;
- unsigned long base_time;
- unsigned int frac_pos; /* fractional sample position (based HZ) */
- unsigned int frac_period_rest;
- unsigned int frac_buffer_size; /* buffer_size * HZ */
- unsigned int frac_period_size; /* period_size * HZ */
- unsigned int rate;
- int elapsed;
- struct snd_pcm_substream *substream;
-};
-
-static void dummy_systimer_rearm(struct dummy_systimer_pcm *dpcm)
-{
- dpcm->timer.expires = jiffies +
- (dpcm->frac_period_rest + dpcm->rate - 1) / dpcm->rate;
- add_timer(&dpcm->timer);
-}
-
-static void dummy_systimer_update(struct dummy_systimer_pcm *dpcm)
-{
- unsigned long delta;
-
- delta = jiffies - dpcm->base_time;
- if (!delta)
- return;
- dpcm->base_time += delta;
- delta *= dpcm->rate;
- dpcm->frac_pos += delta;
- while (dpcm->frac_pos >= dpcm->frac_buffer_size)
- dpcm->frac_pos -= dpcm->frac_buffer_size;
- while (dpcm->frac_period_rest <= delta) {
- dpcm->elapsed++;
- dpcm->frac_period_rest += dpcm->frac_period_size;
- }
- dpcm->frac_period_rest -= delta;
-}
-
-static int dummy_systimer_start(struct snd_pcm_substream *substream)
-{
- struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
- spin_lock(&dpcm->lock);
- dpcm->base_time = jiffies;
- dummy_systimer_rearm(dpcm);
- spin_unlock(&dpcm->lock);
- return 0;
-}
-
-static int dummy_systimer_stop(struct snd_pcm_substream *substream)
-{
- struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
- spin_lock(&dpcm->lock);
- del_timer(&dpcm->timer);
- spin_unlock(&dpcm->lock);
- return 0;
-}
-
-static int dummy_systimer_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct dummy_systimer_pcm *dpcm = runtime->private_data;
-
- dpcm->frac_pos = 0;
- dpcm->rate = runtime->rate;
- dpcm->frac_buffer_size = runtime->buffer_size * HZ;
- dpcm->frac_period_size = runtime->period_size * HZ;
- dpcm->frac_period_rest = dpcm->frac_period_size;
- dpcm->elapsed = 0;
-
- return 0;
-}
-
-static void dummy_systimer_callback(unsigned long data)
-{
- struct dummy_systimer_pcm *dpcm = (struct dummy_systimer_pcm *)data;
- unsigned long flags;
- int elapsed = 0;
-
- spin_lock_irqsave(&dpcm->lock, flags);
- dummy_systimer_update(dpcm);
- dummy_systimer_rearm(dpcm);
- elapsed = dpcm->elapsed;
- dpcm->elapsed = 0;
- spin_unlock_irqrestore(&dpcm->lock, flags);
- if (elapsed)
- snd_pcm_period_elapsed(dpcm->substream);
-}
-
-static snd_pcm_uframes_t
-dummy_systimer_pointer(struct snd_pcm_substream *substream)
-{
- struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
- snd_pcm_uframes_t pos;
-
- spin_lock(&dpcm->lock);
- dummy_systimer_update(dpcm);
- pos = dpcm->frac_pos / HZ;
- spin_unlock(&dpcm->lock);
- return pos;
-}
-
-static int dummy_systimer_create(struct snd_pcm_substream *substream)
-{
- struct dummy_systimer_pcm *dpcm;
-
- dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
- if (!dpcm)
- return -ENOMEM;
- substream->runtime->private_data = dpcm;
- init_timer(&dpcm->timer);
- dpcm->timer.data = (unsigned long) dpcm;
- dpcm->timer.function = dummy_systimer_callback;
- spin_lock_init(&dpcm->lock);
- dpcm->substream = substream;
- return 0;
-}
-
-static void dummy_systimer_free(struct snd_pcm_substream *substream)
-{
- kfree(substream->runtime->private_data);
-}
-
-static struct dummy_timer_ops dummy_systimer_ops = {
- .create = dummy_systimer_create,
- .free = dummy_systimer_free,
- .prepare = dummy_systimer_prepare,
- .start = dummy_systimer_start,
- .stop = dummy_systimer_stop,
- .pointer = dummy_systimer_pointer,
-};
-
-#ifdef CONFIG_HIGH_RES_TIMERS
-/*
- * hrtimer interface
- */
-
-struct dummy_hrtimer_pcm {
- ktime_t base_time;
- ktime_t period_time;
- atomic_t running;
- struct hrtimer timer;
- struct tasklet_struct tasklet;
- struct snd_pcm_substream *substream;
-};
-
-static void dummy_hrtimer_pcm_elapsed(unsigned long priv)
-{
- struct dummy_hrtimer_pcm *dpcm = (struct dummy_hrtimer_pcm *)priv;
- if (atomic_read(&dpcm->running))
- snd_pcm_period_elapsed(dpcm->substream);
-}
-
-static enum hrtimer_restart dummy_hrtimer_callback(struct hrtimer *timer)
-{
- struct dummy_hrtimer_pcm *dpcm;
-
- dpcm = container_of(timer, struct dummy_hrtimer_pcm, timer);
- if (!atomic_read(&dpcm->running))
- return HRTIMER_NORESTART;
- tasklet_schedule(&dpcm->tasklet);
- hrtimer_forward_now(timer, dpcm->period_time);
- return HRTIMER_RESTART;
-}
-
-static int dummy_hrtimer_start(struct snd_pcm_substream *substream)
-{
- struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data;
-
- dpcm->base_time = hrtimer_cb_get_time(&dpcm->timer);
- hrtimer_start(&dpcm->timer, dpcm->period_time, HRTIMER_MODE_REL);
- atomic_set(&dpcm->running, 1);
- return 0;
-}
-
-static int dummy_hrtimer_stop(struct snd_pcm_substream *substream)
-{
- struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data;
-
- atomic_set(&dpcm->running, 0);
- hrtimer_cancel(&dpcm->timer);
- return 0;
-}
-
-static inline void dummy_hrtimer_sync(struct dummy_hrtimer_pcm *dpcm)
-{
- tasklet_kill(&dpcm->tasklet);
-}
-
-static snd_pcm_uframes_t
-dummy_hrtimer_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct dummy_hrtimer_pcm *dpcm = runtime->private_data;
- u64 delta;
- u32 pos;
-
- delta = ktime_us_delta(hrtimer_cb_get_time(&dpcm->timer),
- dpcm->base_time);
- delta = div_u64(delta * runtime->rate + 999999, 1000000);
- div_u64_rem(delta, runtime->buffer_size, &pos);
- return pos;
-}
-
-static int dummy_hrtimer_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct dummy_hrtimer_pcm *dpcm = runtime->private_data;
- unsigned int period, rate;
- long sec;
- unsigned long nsecs;
-
- dummy_hrtimer_sync(dpcm);
- period = runtime->period_size;
- rate = runtime->rate;
- sec = period / rate;
- period %= rate;
- nsecs = div_u64((u64)period * 1000000000UL + rate - 1, rate);
- dpcm->period_time = ktime_set(sec, nsecs);
-
- return 0;
-}
-
-static int dummy_hrtimer_create(struct snd_pcm_substream *substream)
-{
- struct dummy_hrtimer_pcm *dpcm;
-
- dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
- if (!dpcm)
- return -ENOMEM;
- substream->runtime->private_data = dpcm;
- hrtimer_init(&dpcm->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- dpcm->timer.function = dummy_hrtimer_callback;
- dpcm->substream = substream;
- atomic_set(&dpcm->running, 0);
- tasklet_init(&dpcm->tasklet, dummy_hrtimer_pcm_elapsed,
- (unsigned long)dpcm);
- return 0;
-}
-
-static void dummy_hrtimer_free(struct snd_pcm_substream *substream)
-{
- struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data;
- dummy_hrtimer_sync(dpcm);
- kfree(dpcm);
-}
-
-static struct dummy_timer_ops dummy_hrtimer_ops = {
- .create = dummy_hrtimer_create,
- .free = dummy_hrtimer_free,
- .prepare = dummy_hrtimer_prepare,
- .start = dummy_hrtimer_start,
- .stop = dummy_hrtimer_stop,
- .pointer = dummy_hrtimer_pointer,
-};
-
-#endif /* CONFIG_HIGH_RES_TIMERS */
-
-/*
- * PCM interface
- */
-
-static int dummy_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- return dummy->timer_ops->start(substream);
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- return dummy->timer_ops->stop(substream);
- }
- return -EINVAL;
-}
-
-static int dummy_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
-
- return dummy->timer_ops->prepare(substream);
-}
-
-static snd_pcm_uframes_t dummy_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
-
- return dummy->timer_ops->pointer(substream);
-}
-
-static struct snd_pcm_hardware dummy_pcm_hardware = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = USE_FORMATS,
- .rates = USE_RATE,
- .rate_min = USE_RATE_MIN,
- .rate_max = USE_RATE_MAX,
- .channels_min = USE_CHANNELS_MIN,
- .channels_max = USE_CHANNELS_MAX,
- .buffer_bytes_max = MAX_BUFFER_SIZE,
- .period_bytes_min = MIN_PERIOD_SIZE,
- .period_bytes_max = MAX_PERIOD_SIZE,
- .periods_min = USE_PERIODS_MIN,
- .periods_max = USE_PERIODS_MAX,
- .fifo_size = 0,
-};
-
-static int dummy_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- if (fake_buffer) {
- /* runtime->dma_bytes has to be set manually to allow mmap */
- substream->runtime->dma_bytes = params_buffer_bytes(hw_params);
- return 0;
- }
- return snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-}
-
-static int dummy_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- if (fake_buffer)
- return 0;
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int dummy_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
- struct dummy_model *model = dummy->model;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- dummy->timer_ops = &dummy_systimer_ops;
-#ifdef CONFIG_HIGH_RES_TIMERS
- if (hrtimer)
- dummy->timer_ops = &dummy_hrtimer_ops;
-#endif
-
- err = dummy->timer_ops->create(substream);
- if (err < 0)
- return err;
-
- runtime->hw = dummy->pcm_hw;
- if (substream->pcm->device & 1) {
- runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED;
- runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED;
- }
- if (substream->pcm->device & 2)
- runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID);
-
- if (model == NULL)
- return 0;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (model->playback_constraints)
- err = model->playback_constraints(substream->runtime);
- } else {
- if (model->capture_constraints)
- err = model->capture_constraints(substream->runtime);
- }
- if (err < 0) {
- dummy->timer_ops->free(substream);
- return err;
- }
- return 0;
-}
-
-static int dummy_pcm_close(struct snd_pcm_substream *substream)
-{
- struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
- dummy->timer_ops->free(substream);
- return 0;
-}
-
-/*
- * dummy buffer handling
- */
-
-static void *dummy_page[2];
-
-static void free_fake_buffer(void)
-{
- if (fake_buffer) {
- int i;
- for (i = 0; i < 2; i++)
- if (dummy_page[i]) {
- free_page((unsigned long)dummy_page[i]);
- dummy_page[i] = NULL;
- }
- }
-}
-
-static int alloc_fake_buffer(void)
-{
- int i;
-
- if (!fake_buffer)
- return 0;
- for (i = 0; i < 2; i++) {
- dummy_page[i] = (void *)get_zeroed_page(GFP_KERNEL);
- if (!dummy_page[i]) {
- free_fake_buffer();
- return -ENOMEM;
- }
- }
- return 0;
-}
-
-static int dummy_pcm_copy(struct snd_pcm_substream *substream,
- int channel, snd_pcm_uframes_t pos,
- void __user *dst, snd_pcm_uframes_t count)
-{
- return 0; /* do nothing */
-}
-
-static int dummy_pcm_silence(struct snd_pcm_substream *substream,
- int channel, snd_pcm_uframes_t pos,
- snd_pcm_uframes_t count)
-{
- return 0; /* do nothing */
-}
-
-static struct page *dummy_pcm_page(struct snd_pcm_substream *substream,
- unsigned long offset)
-{
- return virt_to_page(dummy_page[substream->stream]); /* the same page */
-}
-
-static struct snd_pcm_ops dummy_pcm_ops = {
- .open = dummy_pcm_open,
- .close = dummy_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = dummy_pcm_hw_params,
- .hw_free = dummy_pcm_hw_free,
- .prepare = dummy_pcm_prepare,
- .trigger = dummy_pcm_trigger,
- .pointer = dummy_pcm_pointer,
-};
-
-static struct snd_pcm_ops dummy_pcm_ops_no_buf = {
- .open = dummy_pcm_open,
- .close = dummy_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = dummy_pcm_hw_params,
- .hw_free = dummy_pcm_hw_free,
- .prepare = dummy_pcm_prepare,
- .trigger = dummy_pcm_trigger,
- .pointer = dummy_pcm_pointer,
- .copy = dummy_pcm_copy,
- .silence = dummy_pcm_silence,
- .page = dummy_pcm_page,
-};
-
-static int __devinit snd_card_dummy_pcm(struct snd_dummy *dummy, int device,
- int substreams)
-{
- struct snd_pcm *pcm;
- struct snd_pcm_ops *ops;
- int err;
-
- err = snd_pcm_new(dummy->card, "Dummy PCM", device,
- substreams, substreams, &pcm);
- if (err < 0)
- return err;
- dummy->pcm = pcm;
- if (fake_buffer)
- ops = &dummy_pcm_ops_no_buf;
- else
- ops = &dummy_pcm_ops;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, ops);
- pcm->private_data = dummy;
- pcm->info_flags = 0;
- strcpy(pcm->name, "Dummy PCM");
- if (!fake_buffer) {
- snd_pcm_lib_preallocate_pages_for_all(pcm,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- 0, 64*1024);
- }
- return 0;
-}
-
-/*
- * mixer interface
- */
-
-#define DUMMY_VOLUME(xname, xindex, addr) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .name = xname, .index = xindex, \
- .info = snd_dummy_volume_info, \
- .get = snd_dummy_volume_get, .put = snd_dummy_volume_put, \
- .private_value = addr, \
- .tlv = { .p = db_scale_dummy } }
-
-static int snd_dummy_volume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = -50;
- uinfo->value.integer.max = 100;
- return 0;
-}
-
-static int snd_dummy_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
- int addr = kcontrol->private_value;
-
- spin_lock_irq(&dummy->mixer_lock);
- ucontrol->value.integer.value[0] = dummy->mixer_volume[addr][0];
- ucontrol->value.integer.value[1] = dummy->mixer_volume[addr][1];
- spin_unlock_irq(&dummy->mixer_lock);
- return 0;
-}
-
-static int snd_dummy_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
- int change, addr = kcontrol->private_value;
- int left, right;
-
- left = ucontrol->value.integer.value[0];
- if (left < -50)
- left = -50;
- if (left > 100)
- left = 100;
- right = ucontrol->value.integer.value[1];
- if (right < -50)
- right = -50;
- if (right > 100)
- right = 100;
- spin_lock_irq(&dummy->mixer_lock);
- change = dummy->mixer_volume[addr][0] != left ||
- dummy->mixer_volume[addr][1] != right;
- dummy->mixer_volume[addr][0] = left;
- dummy->mixer_volume[addr][1] = right;
- spin_unlock_irq(&dummy->mixer_lock);
- return change;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_dummy, -4500, 30, 0);
-
-#define DUMMY_CAPSRC(xname, xindex, addr) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_dummy_capsrc_info, \
- .get = snd_dummy_capsrc_get, .put = snd_dummy_capsrc_put, \
- .private_value = addr }
-
-#define snd_dummy_capsrc_info snd_ctl_boolean_stereo_info
-
-static int snd_dummy_capsrc_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
- int addr = kcontrol->private_value;
-
- spin_lock_irq(&dummy->mixer_lock);
- ucontrol->value.integer.value[0] = dummy->capture_source[addr][0];
- ucontrol->value.integer.value[1] = dummy->capture_source[addr][1];
- spin_unlock_irq(&dummy->mixer_lock);
- return 0;
-}
-
-static int snd_dummy_capsrc_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
- int change, addr = kcontrol->private_value;
- int left, right;
-
- left = ucontrol->value.integer.value[0] & 1;
- right = ucontrol->value.integer.value[1] & 1;
- spin_lock_irq(&dummy->mixer_lock);
- change = dummy->capture_source[addr][0] != left &&
- dummy->capture_source[addr][1] != right;
- dummy->capture_source[addr][0] = left;
- dummy->capture_source[addr][1] = right;
- spin_unlock_irq(&dummy->mixer_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_dummy_controls[] = {
-DUMMY_VOLUME("Master Volume", 0, MIXER_ADDR_MASTER),
-DUMMY_CAPSRC("Master Capture Switch", 0, MIXER_ADDR_MASTER),
-DUMMY_VOLUME("Synth Volume", 0, MIXER_ADDR_SYNTH),
-DUMMY_CAPSRC("Synth Capture Switch", 0, MIXER_ADDR_SYNTH),
-DUMMY_VOLUME("Line Volume", 0, MIXER_ADDR_LINE),
-DUMMY_CAPSRC("Line Capture Switch", 0, MIXER_ADDR_LINE),
-DUMMY_VOLUME("Mic Volume", 0, MIXER_ADDR_MIC),
-DUMMY_CAPSRC("Mic Capture Switch", 0, MIXER_ADDR_MIC),
-DUMMY_VOLUME("CD Volume", 0, MIXER_ADDR_CD),
-DUMMY_CAPSRC("CD Capture Switch", 0, MIXER_ADDR_CD)
-};
-
-static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy)
-{
- struct snd_card *card = dummy->card;
- unsigned int idx;
- int err;
-
- spin_lock_init(&dummy->mixer_lock);
- strcpy(card->mixername, "Dummy Mixer");
-
- for (idx = 0; idx < ARRAY_SIZE(snd_dummy_controls); idx++) {
- err = snd_ctl_add(card, snd_ctl_new1(&snd_dummy_controls[idx], dummy));
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_PROC_FS)
-/*
- * proc interface
- */
-static void print_formats(struct snd_dummy *dummy,
- struct snd_info_buffer *buffer)
-{
- int i;
-
- for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {
- if (dummy->pcm_hw.formats & (1ULL << i))
- snd_iprintf(buffer, " %s", snd_pcm_format_name(i));
- }
-}
-
-static void print_rates(struct snd_dummy *dummy,
- struct snd_info_buffer *buffer)
-{
- static int rates[] = {
- 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000,
- 64000, 88200, 96000, 176400, 192000,
- };
- int i;
-
- if (dummy->pcm_hw.rates & SNDRV_PCM_RATE_CONTINUOUS)
- snd_iprintf(buffer, " continuous");
- if (dummy->pcm_hw.rates & SNDRV_PCM_RATE_KNOT)
- snd_iprintf(buffer, " knot");
- for (i = 0; i < ARRAY_SIZE(rates); i++)
- if (dummy->pcm_hw.rates & (1 << i))
- snd_iprintf(buffer, " %d", rates[i]);
-}
-
-#define get_dummy_int_ptr(dummy, ofs) \
- (unsigned int *)((char *)&((dummy)->pcm_hw) + (ofs))
-#define get_dummy_ll_ptr(dummy, ofs) \
- (unsigned long long *)((char *)&((dummy)->pcm_hw) + (ofs))
-
-struct dummy_hw_field {
- const char *name;
- const char *format;
- unsigned int offset;
- unsigned int size;
-};
-#define FIELD_ENTRY(item, fmt) { \
- .name = #item, \
- .format = fmt, \
- .offset = offsetof(struct snd_pcm_hardware, item), \
- .size = sizeof(dummy_pcm_hardware.item) }
-
-static struct dummy_hw_field fields[] = {
- FIELD_ENTRY(formats, "%#llx"),
- FIELD_ENTRY(rates, "%#x"),
- FIELD_ENTRY(rate_min, "%d"),
- FIELD_ENTRY(rate_max, "%d"),
- FIELD_ENTRY(channels_min, "%d"),
- FIELD_ENTRY(channels_max, "%d"),
- FIELD_ENTRY(buffer_bytes_max, "%ld"),
- FIELD_ENTRY(period_bytes_min, "%ld"),
- FIELD_ENTRY(period_bytes_max, "%ld"),
- FIELD_ENTRY(periods_min, "%d"),
- FIELD_ENTRY(periods_max, "%d"),
-};
-
-static void dummy_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_dummy *dummy = entry->private_data;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(fields); i++) {
- snd_iprintf(buffer, "%s ", fields[i].name);
- if (fields[i].size == sizeof(int))
- snd_iprintf(buffer, fields[i].format,
- *get_dummy_int_ptr(dummy, fields[i].offset));
- else
- snd_iprintf(buffer, fields[i].format,
- *get_dummy_ll_ptr(dummy, fields[i].offset));
- if (!strcmp(fields[i].name, "formats"))
- print_formats(dummy, buffer);
- else if (!strcmp(fields[i].name, "rates"))
- print_rates(dummy, buffer);
- snd_iprintf(buffer, "\n");
- }
-}
-
-static void dummy_proc_write(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_dummy *dummy = entry->private_data;
- char line[64];
-
- while (!snd_info_get_line(buffer, line, sizeof(line))) {
- char item[20];
- const char *ptr;
- unsigned long long val;
- int i;
-
- ptr = snd_info_get_str(item, line, sizeof(item));
- for (i = 0; i < ARRAY_SIZE(fields); i++) {
- if (!strcmp(item, fields[i].name))
- break;
- }
- if (i >= ARRAY_SIZE(fields))
- continue;
- snd_info_get_str(item, ptr, sizeof(item));
- if (strict_strtoull(item, 0, &val))
- continue;
- if (fields[i].size == sizeof(int))
- *get_dummy_int_ptr(dummy, fields[i].offset) = val;
- else
- *get_dummy_ll_ptr(dummy, fields[i].offset) = val;
- }
-}
-
-static void __devinit dummy_proc_init(struct snd_dummy *chip)
-{
- struct snd_info_entry *entry;
-
- if (!snd_card_proc_new(chip->card, "dummy_pcm", &entry)) {
- snd_info_set_text_ops(entry, chip, dummy_proc_read);
- entry->c.text.write = dummy_proc_write;
- entry->mode |= S_IWUSR;
- entry->private_data = chip;
- }
-}
-#else
-#define dummy_proc_init(x)
-#endif /* CONFIG_SND_DEBUG && CONFIG_PROC_FS */
-
-static int __devinit snd_dummy_probe(struct platform_device *devptr)
-{
- struct snd_card *card;
- struct snd_dummy *dummy;
- struct dummy_model *m = NULL, **mdl;
- int idx, err;
- int dev = devptr->id;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_dummy), &card);
- if (err < 0)
- return err;
- dummy = card->private_data;
- dummy->card = card;
- for (mdl = dummy_models; *mdl && model[dev]; mdl++) {
- if (strcmp(model[dev], (*mdl)->name) == 0) {
- printk(KERN_INFO
- "snd-dummy: Using model '%s' for card %i\n",
- (*mdl)->name, card->number);
- m = dummy->model = *mdl;
- break;
- }
- }
- for (idx = 0; idx < MAX_PCM_DEVICES && idx < pcm_devs[dev]; idx++) {
- if (pcm_substreams[dev] < 1)
- pcm_substreams[dev] = 1;
- if (pcm_substreams[dev] > MAX_PCM_SUBSTREAMS)
- pcm_substreams[dev] = MAX_PCM_SUBSTREAMS;
- err = snd_card_dummy_pcm(dummy, idx, pcm_substreams[dev]);
- if (err < 0)
- goto __nodev;
- }
-
- dummy->pcm_hw = dummy_pcm_hardware;
- if (m) {
- if (m->formats)
- dummy->pcm_hw.formats = m->formats;
- if (m->buffer_bytes_max)
- dummy->pcm_hw.buffer_bytes_max = m->buffer_bytes_max;
- if (m->period_bytes_min)
- dummy->pcm_hw.period_bytes_min = m->period_bytes_min;
- if (m->period_bytes_max)
- dummy->pcm_hw.period_bytes_max = m->period_bytes_max;
- if (m->periods_min)
- dummy->pcm_hw.periods_min = m->periods_min;
- if (m->periods_max)
- dummy->pcm_hw.periods_max = m->periods_max;
- if (m->rates)
- dummy->pcm_hw.rates = m->rates;
- if (m->rate_min)
- dummy->pcm_hw.rate_min = m->rate_min;
- if (m->rate_max)
- dummy->pcm_hw.rate_max = m->rate_max;
- if (m->channels_min)
- dummy->pcm_hw.channels_min = m->channels_min;
- if (m->channels_max)
- dummy->pcm_hw.channels_max = m->channels_max;
- }
-
- err = snd_card_dummy_new_mixer(dummy);
- if (err < 0)
- goto __nodev;
- strcpy(card->driver, "Dummy");
- strcpy(card->shortname, "Dummy");
- sprintf(card->longname, "Dummy %i", dev + 1);
-
- dummy_proc_init(dummy);
-
- snd_card_set_dev(card, &devptr->dev);
-
- err = snd_card_register(card);
- if (err == 0) {
- platform_set_drvdata(devptr, card);
- return 0;
- }
- __nodev:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit snd_dummy_remove(struct platform_device *devptr)
-{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int snd_dummy_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct snd_card *card = platform_get_drvdata(pdev);
- struct snd_dummy *dummy = card->private_data;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(dummy->pcm);
- return 0;
-}
-
-static int snd_dummy_resume(struct platform_device *pdev)
-{
- struct snd_card *card = platform_get_drvdata(pdev);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif
-
-#define SND_DUMMY_DRIVER "snd_dummy"
-
-static struct platform_driver snd_dummy_driver = {
- .probe = snd_dummy_probe,
- .remove = __devexit_p(snd_dummy_remove),
-#ifdef CONFIG_PM
- .suspend = snd_dummy_suspend,
- .resume = snd_dummy_resume,
-#endif
- .driver = {
- .name = SND_DUMMY_DRIVER
- },
-};
-
-static void snd_dummy_unregister_all(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(devices); ++i)
- platform_device_unregister(devices[i]);
- platform_driver_unregister(&snd_dummy_driver);
- free_fake_buffer();
-}
-
-static int __init alsa_card_dummy_init(void)
-{
- int i, cards, err;
-
- err = platform_driver_register(&snd_dummy_driver);
- if (err < 0)
- return err;
-
- err = alloc_fake_buffer();
- if (err < 0) {
- platform_driver_unregister(&snd_dummy_driver);
- return err;
- }
-
- cards = 0;
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i])
- continue;
- device = platform_device_register_simple(SND_DUMMY_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- devices[i] = device;
- cards++;
- }
- if (!cards) {
-#ifdef MODULE
- printk(KERN_ERR "Dummy soundcard not found or device busy\n");
-#endif
- snd_dummy_unregister_all();
- return -ENODEV;
- }
- return 0;
-}
-
-static void __exit alsa_card_dummy_exit(void)
-{
- snd_dummy_unregister_all();
-}
-
-module_init(alsa_card_dummy_init)
-module_exit(alsa_card_dummy_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/ml403-ac97cr.c b/ANDROID_3.4.5/sound/drivers/ml403-ac97cr.c
deleted file mode 100644
index 6c83b1ae..00000000
--- a/ANDROID_3.4.5/sound/drivers/ml403-ac97cr.c
+++ /dev/null
@@ -1,1344 +0,0 @@
-/*
- * ALSA driver for Xilinx ML403 AC97 Controller Reference
- * IP: opb_ac97_controller_ref_v1_00_a (EDK 8.1i)
- * IP: opb_ac97_controller_ref_v1_00_a (EDK 9.1i)
- *
- * Copyright (c) by 2007 Joachim Foerster <JOFT@gmx.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/* Some notes / status of this driver:
- *
- * - Don't wonder about some strange implementations of things - especially the
- * (heavy) shadowing of codec registers, with which I tried to reduce read
- * accesses to a minimum, because after a variable amount of accesses, the AC97
- * controller doesn't raise the register access finished bit anymore ...
- *
- * - Playback support seems to be pretty stable - no issues here.
- * - Capture support "works" now, too. Overruns don't happen any longer so often.
- * But there might still be some ...
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include <linux/platform_device.h>
-
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-
-/* HZ */
-#include <linux/param.h>
-/* jiffies, time_*() */
-#include <linux/jiffies.h>
-/* schedule_timeout*() */
-#include <linux/sched.h>
-/* spin_lock*() */
-#include <linux/spinlock.h>
-/* struct mutex, mutex_init(), mutex_*lock() */
-#include <linux/mutex.h>
-
-/* snd_printk(), snd_printd() */
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/ac97_codec.h>
-
-#include "pcm-indirect2.h"
-
-
-#define SND_ML403_AC97CR_DRIVER "ml403-ac97cr"
-
-MODULE_AUTHOR("Joachim Foerster <JOFT@gmx.de>");
-MODULE_DESCRIPTION("Xilinx ML403 AC97 Controller Reference");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Xilinx,ML403 AC97 Controller Reference}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for ML403 AC97 Controller Reference.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for ML403 AC97 Controller Reference.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable this ML403 AC97 Controller Reference.");
-
-/* Special feature options */
-/*#define CODEC_WRITE_CHECK_RAF*/ /* don't return after a write to a codec
- * register, while RAF bit is not set
- */
-/* Debug options for code which may be removed completely in a final version */
-#ifdef CONFIG_SND_DEBUG
-/*#define CODEC_STAT*/ /* turn on some minimal "statistics"
- * about codec register usage
- */
-#define SND_PCM_INDIRECT2_STAT /* turn on some "statistics" about the
- * process of copying bytes from the
- * intermediate buffer to the hardware
- * fifo and the other way round
- */
-#endif
-
-/* Definition of a "level/facility dependent" printk(); may be removed
- * completely in a final version
- */
-#undef PDEBUG
-#ifdef CONFIG_SND_DEBUG
-/* "facilities" for PDEBUG */
-#define UNKNOWN (1<<0)
-#define CODEC_SUCCESS (1<<1)
-#define CODEC_FAKE (1<<2)
-#define INIT_INFO (1<<3)
-#define INIT_FAILURE (1<<4)
-#define WORK_INFO (1<<5)
-#define WORK_FAILURE (1<<6)
-
-#define PDEBUG_FACILITIES (UNKNOWN | INIT_FAILURE | WORK_FAILURE)
-
-#define PDEBUG(fac, fmt, args...) do { \
- if (fac & PDEBUG_FACILITIES) \
- snd_printd(KERN_DEBUG SND_ML403_AC97CR_DRIVER ": " \
- fmt, ##args); \
- } while (0)
-#else
-#define PDEBUG(fac, fmt, args...) /* nothing */
-#endif
-
-
-
-/* Defines for "waits"/timeouts (portions of HZ=250 on arch/ppc by default) */
-#define CODEC_TIMEOUT_ON_INIT 5 /* timeout for checking for codec
- * readiness (after insmod)
- */
-#ifndef CODEC_WRITE_CHECK_RAF
-#define CODEC_WAIT_AFTER_WRITE 100 /* general, static wait after a write
- * access to a codec register, may be
- * 0 to completely remove wait
- */
-#else
-#define CODEC_TIMEOUT_AFTER_WRITE 5 /* timeout after a write access to a
- * codec register, if RAF bit is used
- */
-#endif
-#define CODEC_TIMEOUT_AFTER_READ 5 /* timeout after a read access to a
- * codec register (checking RAF bit)
- */
-
-/* Infrastructure for codec register shadowing */
-#define LM4550_REG_OK (1<<0) /* register exists */
-#define LM4550_REG_DONEREAD (1<<1) /* read register once, value should be
- * the same currently in the register
- */
-#define LM4550_REG_NOSAVE (1<<2) /* values written to this register will
- * not be saved in the register
- */
-#define LM4550_REG_NOSHADOW (1<<3) /* don't do register shadowing, use plain
- * hardware access
- */
-#define LM4550_REG_READONLY (1<<4) /* register is read only */
-#define LM4550_REG_FAKEPROBE (1<<5) /* fake write _and_ read actions during
- * probe() correctly
- */
-#define LM4550_REG_FAKEREAD (1<<6) /* fake read access, always return
- * default value
- */
-#define LM4550_REG_ALLFAKE (LM4550_REG_FAKEREAD | LM4550_REG_FAKEPROBE)
-
-struct lm4550_reg {
- u16 value;
- u16 flag;
- u16 wmask;
- u16 def;
-};
-
-struct lm4550_reg lm4550_regfile[64] = {
- [AC97_RESET / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_NOSAVE \
- | LM4550_REG_FAKEREAD,
- .def = 0x0D50},
- [AC97_MASTER / 2] = {.flag = LM4550_REG_OK
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x9F1F,
- .def = 0x8000},
- [AC97_HEADPHONE / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x9F1F,
- .def = 0x8000},
- [AC97_MASTER_MONO / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x801F,
- .def = 0x8000},
- [AC97_PC_BEEP / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x801E,
- .def = 0x0},
- [AC97_PHONE / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x801F,
- .def = 0x8008},
- [AC97_MIC / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x805F,
- .def = 0x8008},
- [AC97_LINE / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x9F1F,
- .def = 0x8808},
- [AC97_CD / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x9F1F,
- .def = 0x8808},
- [AC97_VIDEO / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x9F1F,
- .def = 0x8808},
- [AC97_AUX / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x9F1F,
- .def = 0x8808},
- [AC97_PCM / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x9F1F,
- .def = 0x8008},
- [AC97_REC_SEL / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x707,
- .def = 0x0},
- [AC97_REC_GAIN / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .wmask = 0x8F0F,
- .def = 0x8000},
- [AC97_GENERAL_PURPOSE / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .def = 0x0,
- .wmask = 0xA380},
- [AC97_3D_CONTROL / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEREAD \
- | LM4550_REG_READONLY,
- .def = 0x0101},
- [AC97_POWERDOWN / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_NOSHADOW \
- | LM4550_REG_NOSAVE,
- .wmask = 0xFF00},
- /* may not write ones to
- * REF/ANL/DAC/ADC bits
- * FIXME: Is this ok?
- */
- [AC97_EXTENDED_ID / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEREAD \
- | LM4550_REG_READONLY,
- .def = 0x0201}, /* primary codec */
- [AC97_EXTENDED_STATUS / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_NOSHADOW \
- | LM4550_REG_NOSAVE,
- .wmask = 0x1},
- [AC97_PCM_FRONT_DAC_RATE / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .def = 0xBB80,
- .wmask = 0xFFFF},
- [AC97_PCM_LR_ADC_RATE / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_FAKEPROBE,
- .def = 0xBB80,
- .wmask = 0xFFFF},
- [AC97_VENDOR_ID1 / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_READONLY \
- | LM4550_REG_FAKEREAD,
- .def = 0x4E53},
- [AC97_VENDOR_ID2 / 2] = {.flag = LM4550_REG_OK \
- | LM4550_REG_READONLY \
- | LM4550_REG_FAKEREAD,
- .def = 0x4350}
-};
-
-#define LM4550_RF_OK(reg) (lm4550_regfile[reg / 2].flag & LM4550_REG_OK)
-
-static void lm4550_regfile_init(void)
-{
- int i;
- for (i = 0; i < 64; i++)
- if (lm4550_regfile[i].flag & LM4550_REG_FAKEPROBE)
- lm4550_regfile[i].value = lm4550_regfile[i].def;
-}
-
-static void lm4550_regfile_write_values_after_init(struct snd_ac97 *ac97)
-{
- int i;
- for (i = 0; i < 64; i++)
- if ((lm4550_regfile[i].flag & LM4550_REG_FAKEPROBE) &&
- (lm4550_regfile[i].value != lm4550_regfile[i].def)) {
- PDEBUG(CODEC_FAKE, "lm4550_regfile_write_values_after_"
- "init(): reg=0x%x value=0x%x / %d is different "
- "from def=0x%x / %d\n",
- i, lm4550_regfile[i].value,
- lm4550_regfile[i].value, lm4550_regfile[i].def,
- lm4550_regfile[i].def);
- snd_ac97_write(ac97, i * 2, lm4550_regfile[i].value);
- lm4550_regfile[i].flag |= LM4550_REG_DONEREAD;
- }
-}
-
-
-/* direct registers */
-#define CR_REG(ml403_ac97cr, x) ((ml403_ac97cr)->port + CR_REG_##x)
-
-#define CR_REG_PLAYFIFO 0x00
-#define CR_PLAYDATA(a) ((a) & 0xFFFF)
-
-#define CR_REG_RECFIFO 0x04
-#define CR_RECDATA(a) ((a) & 0xFFFF)
-
-#define CR_REG_STATUS 0x08
-#define CR_RECOVER (1<<7)
-#define CR_PLAYUNDER (1<<6)
-#define CR_CODECREADY (1<<5)
-#define CR_RAF (1<<4)
-#define CR_RECEMPTY (1<<3)
-#define CR_RECFULL (1<<2)
-#define CR_PLAYHALF (1<<1)
-#define CR_PLAYFULL (1<<0)
-
-#define CR_REG_RESETFIFO 0x0C
-#define CR_RECRESET (1<<1)
-#define CR_PLAYRESET (1<<0)
-
-#define CR_REG_CODEC_ADDR 0x10
-/* UG082 says:
- * #define CR_CODEC_ADDR(a) ((a) << 1)
- * #define CR_CODEC_READ (1<<0)
- * #define CR_CODEC_WRITE (0<<0)
- */
-/* RefDesign example says: */
-#define CR_CODEC_ADDR(a) ((a) << 0)
-#define CR_CODEC_READ (1<<7)
-#define CR_CODEC_WRITE (0<<7)
-
-#define CR_REG_CODEC_DATAREAD 0x14
-#define CR_CODEC_DATAREAD(v) ((v) & 0xFFFF)
-
-#define CR_REG_CODEC_DATAWRITE 0x18
-#define CR_CODEC_DATAWRITE(v) ((v) & 0xFFFF)
-
-#define CR_FIFO_SIZE 32
-
-struct snd_ml403_ac97cr {
- /* lock for access to (controller) registers */
- spinlock_t reg_lock;
- /* mutex for the whole sequence of accesses to (controller) registers
- * which affect codec registers
- */
- struct mutex cdc_mutex;
-
- int irq; /* for playback */
- int enable_irq; /* for playback */
-
- int capture_irq;
- int enable_capture_irq;
-
- struct resource *res_port;
- void *port;
-
- struct snd_ac97 *ac97;
- int ac97_fake;
-#ifdef CODEC_STAT
- int ac97_read;
- int ac97_write;
-#endif
-
- struct platform_device *pfdev;
- struct snd_card *card;
- struct snd_pcm *pcm;
- struct snd_pcm_substream *playback_substream;
- struct snd_pcm_substream *capture_substream;
-
- struct snd_pcm_indirect2 ind_rec; /* for playback */
- struct snd_pcm_indirect2 capture_ind2_rec;
-};
-
-static struct snd_pcm_hardware snd_ml403_ac97cr_playback = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_BE,
- .rates = (SNDRV_PCM_RATE_CONTINUOUS |
- SNDRV_PCM_RATE_8000_48000),
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = CR_FIFO_SIZE/2,
- .period_bytes_max = (64*1024),
- .periods_min = 2,
- .periods_max = (128*1024)/(CR_FIFO_SIZE/2),
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_ml403_ac97cr_capture = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_BE,
- .rates = (SNDRV_PCM_RATE_CONTINUOUS |
- SNDRV_PCM_RATE_8000_48000),
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = CR_FIFO_SIZE/2,
- .period_bytes_max = (64*1024),
- .periods_min = 2,
- .periods_max = (128*1024)/(CR_FIFO_SIZE/2),
- .fifo_size = 0,
-};
-
-static size_t
-snd_ml403_ac97cr_playback_ind2_zero(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- int copied_words = 0;
- u32 full = 0;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
-
- spin_lock(&ml403_ac97cr->reg_lock);
- while ((full = (in_be32(CR_REG(ml403_ac97cr, STATUS)) &
- CR_PLAYFULL)) != CR_PLAYFULL) {
- out_be32(CR_REG(ml403_ac97cr, PLAYFIFO), 0);
- copied_words++;
- }
- rec->hw_ready = 0;
- spin_unlock(&ml403_ac97cr->reg_lock);
-
- return (size_t) (copied_words * 2);
-}
-
-static size_t
-snd_ml403_ac97cr_playback_ind2_copy(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec,
- size_t bytes)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- u16 *src;
- int copied_words = 0;
- u32 full = 0;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
- src = (u16 *)(substream->runtime->dma_area + rec->sw_data);
-
- spin_lock(&ml403_ac97cr->reg_lock);
- while (((full = (in_be32(CR_REG(ml403_ac97cr, STATUS)) &
- CR_PLAYFULL)) != CR_PLAYFULL) && (bytes > 1)) {
- out_be32(CR_REG(ml403_ac97cr, PLAYFIFO),
- CR_PLAYDATA(src[copied_words]));
- copied_words++;
- bytes = bytes - 2;
- }
- if (full != CR_PLAYFULL)
- rec->hw_ready = 1;
- else
- rec->hw_ready = 0;
- spin_unlock(&ml403_ac97cr->reg_lock);
-
- return (size_t) (copied_words * 2);
-}
-
-static size_t
-snd_ml403_ac97cr_capture_ind2_null(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- int copied_words = 0;
- u32 empty = 0;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
-
- spin_lock(&ml403_ac97cr->reg_lock);
- while ((empty = (in_be32(CR_REG(ml403_ac97cr, STATUS)) &
- CR_RECEMPTY)) != CR_RECEMPTY) {
- volatile u32 trash;
-
- trash = CR_RECDATA(in_be32(CR_REG(ml403_ac97cr, RECFIFO)));
- /* Hmmmm, really necessary? Don't want call to in_be32()
- * to be optimised away!
- */
- trash++;
- copied_words++;
- }
- rec->hw_ready = 0;
- spin_unlock(&ml403_ac97cr->reg_lock);
-
- return (size_t) (copied_words * 2);
-}
-
-static size_t
-snd_ml403_ac97cr_capture_ind2_copy(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec, size_t bytes)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- u16 *dst;
- int copied_words = 0;
- u32 empty = 0;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
- dst = (u16 *)(substream->runtime->dma_area + rec->sw_data);
-
- spin_lock(&ml403_ac97cr->reg_lock);
- while (((empty = (in_be32(CR_REG(ml403_ac97cr, STATUS)) &
- CR_RECEMPTY)) != CR_RECEMPTY) && (bytes > 1)) {
- dst[copied_words] = CR_RECDATA(in_be32(CR_REG(ml403_ac97cr,
- RECFIFO)));
- copied_words++;
- bytes = bytes - 2;
- }
- if (empty != CR_RECEMPTY)
- rec->hw_ready = 1;
- else
- rec->hw_ready = 0;
- spin_unlock(&ml403_ac97cr->reg_lock);
-
- return (size_t) (copied_words * 2);
-}
-
-static snd_pcm_uframes_t
-snd_ml403_ac97cr_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- struct snd_pcm_indirect2 *ind2_rec = NULL;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
-
- if (substream == ml403_ac97cr->playback_substream)
- ind2_rec = &ml403_ac97cr->ind_rec;
- if (substream == ml403_ac97cr->capture_substream)
- ind2_rec = &ml403_ac97cr->capture_ind2_rec;
-
- if (ind2_rec != NULL)
- return snd_pcm_indirect2_pointer(substream, ind2_rec);
- return (snd_pcm_uframes_t) 0;
-}
-
-static int
-snd_ml403_ac97cr_pcm_playback_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- int err = 0;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- PDEBUG(WORK_INFO, "trigger(playback): START\n");
- ml403_ac97cr->ind_rec.hw_ready = 1;
-
- /* clear play FIFO */
- out_be32(CR_REG(ml403_ac97cr, RESETFIFO), CR_PLAYRESET);
-
- /* enable play irq */
- ml403_ac97cr->enable_irq = 1;
- enable_irq(ml403_ac97cr->irq);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- PDEBUG(WORK_INFO, "trigger(playback): STOP\n");
- ml403_ac97cr->ind_rec.hw_ready = 0;
-#ifdef SND_PCM_INDIRECT2_STAT
- snd_pcm_indirect2_stat(substream, &ml403_ac97cr->ind_rec);
-#endif
- /* disable play irq */
- disable_irq_nosync(ml403_ac97cr->irq);
- ml403_ac97cr->enable_irq = 0;
- break;
- default:
- err = -EINVAL;
- break;
- }
- PDEBUG(WORK_INFO, "trigger(playback): (done)\n");
- return err;
-}
-
-static int
-snd_ml403_ac97cr_pcm_capture_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- int err = 0;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- PDEBUG(WORK_INFO, "trigger(capture): START\n");
- ml403_ac97cr->capture_ind2_rec.hw_ready = 0;
-
- /* clear record FIFO */
- out_be32(CR_REG(ml403_ac97cr, RESETFIFO), CR_RECRESET);
-
- /* enable record irq */
- ml403_ac97cr->enable_capture_irq = 1;
- enable_irq(ml403_ac97cr->capture_irq);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- PDEBUG(WORK_INFO, "trigger(capture): STOP\n");
- ml403_ac97cr->capture_ind2_rec.hw_ready = 0;
-#ifdef SND_PCM_INDIRECT2_STAT
- snd_pcm_indirect2_stat(substream,
- &ml403_ac97cr->capture_ind2_rec);
-#endif
- /* disable capture irq */
- disable_irq_nosync(ml403_ac97cr->capture_irq);
- ml403_ac97cr->enable_capture_irq = 0;
- break;
- default:
- err = -EINVAL;
- break;
- }
- PDEBUG(WORK_INFO, "trigger(capture): (done)\n");
- return err;
-}
-
-static int
-snd_ml403_ac97cr_pcm_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- struct snd_pcm_runtime *runtime;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
- runtime = substream->runtime;
-
- PDEBUG(WORK_INFO,
- "prepare(): period_bytes=%d, minperiod_bytes=%d\n",
- snd_pcm_lib_period_bytes(substream), CR_FIFO_SIZE / 2);
-
- /* set sampling rate */
- snd_ac97_set_rate(ml403_ac97cr->ac97, AC97_PCM_FRONT_DAC_RATE,
- runtime->rate);
- PDEBUG(WORK_INFO, "prepare(): rate=%d\n", runtime->rate);
-
- /* init struct for intermediate buffer */
- memset(&ml403_ac97cr->ind_rec, 0,
- sizeof(struct snd_pcm_indirect2));
- ml403_ac97cr->ind_rec.hw_buffer_size = CR_FIFO_SIZE;
- ml403_ac97cr->ind_rec.sw_buffer_size =
- snd_pcm_lib_buffer_bytes(substream);
- ml403_ac97cr->ind_rec.min_periods = -1;
- ml403_ac97cr->ind_rec.min_multiple =
- snd_pcm_lib_period_bytes(substream) / (CR_FIFO_SIZE / 2);
- PDEBUG(WORK_INFO, "prepare(): hw_buffer_size=%d, "
- "sw_buffer_size=%d, min_multiple=%d\n",
- CR_FIFO_SIZE, ml403_ac97cr->ind_rec.sw_buffer_size,
- ml403_ac97cr->ind_rec.min_multiple);
- return 0;
-}
-
-static int
-snd_ml403_ac97cr_pcm_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- struct snd_pcm_runtime *runtime;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
- runtime = substream->runtime;
-
- PDEBUG(WORK_INFO,
- "prepare(capture): period_bytes=%d, minperiod_bytes=%d\n",
- snd_pcm_lib_period_bytes(substream), CR_FIFO_SIZE / 2);
-
- /* set sampling rate */
- snd_ac97_set_rate(ml403_ac97cr->ac97, AC97_PCM_LR_ADC_RATE,
- runtime->rate);
- PDEBUG(WORK_INFO, "prepare(capture): rate=%d\n", runtime->rate);
-
- /* init struct for intermediate buffer */
- memset(&ml403_ac97cr->capture_ind2_rec, 0,
- sizeof(struct snd_pcm_indirect2));
- ml403_ac97cr->capture_ind2_rec.hw_buffer_size = CR_FIFO_SIZE;
- ml403_ac97cr->capture_ind2_rec.sw_buffer_size =
- snd_pcm_lib_buffer_bytes(substream);
- ml403_ac97cr->capture_ind2_rec.min_multiple =
- snd_pcm_lib_period_bytes(substream) / (CR_FIFO_SIZE / 2);
- PDEBUG(WORK_INFO, "prepare(capture): hw_buffer_size=%d, "
- "sw_buffer_size=%d, min_multiple=%d\n", CR_FIFO_SIZE,
- ml403_ac97cr->capture_ind2_rec.sw_buffer_size,
- ml403_ac97cr->capture_ind2_rec.min_multiple);
- return 0;
-}
-
-static int snd_ml403_ac97cr_hw_free(struct snd_pcm_substream *substream)
-{
- PDEBUG(WORK_INFO, "hw_free()\n");
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int
-snd_ml403_ac97cr_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- PDEBUG(WORK_INFO, "hw_params(): desired buffer bytes=%d, desired "
- "period bytes=%d\n",
- params_buffer_bytes(hw_params), params_period_bytes(hw_params));
- return snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-}
-
-static int snd_ml403_ac97cr_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- struct snd_pcm_runtime *runtime;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
- runtime = substream->runtime;
-
- PDEBUG(WORK_INFO, "open(playback)\n");
- ml403_ac97cr->playback_substream = substream;
- runtime->hw = snd_ml403_ac97cr_playback;
-
- snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- CR_FIFO_SIZE / 2);
- return 0;
-}
-
-static int snd_ml403_ac97cr_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- struct snd_pcm_runtime *runtime;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
- runtime = substream->runtime;
-
- PDEBUG(WORK_INFO, "open(capture)\n");
- ml403_ac97cr->capture_substream = substream;
- runtime->hw = snd_ml403_ac97cr_capture;
-
- snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- CR_FIFO_SIZE / 2);
- return 0;
-}
-
-static int snd_ml403_ac97cr_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
-
- PDEBUG(WORK_INFO, "close(playback)\n");
- ml403_ac97cr->playback_substream = NULL;
- return 0;
-}
-
-static int snd_ml403_ac97cr_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
-
- ml403_ac97cr = snd_pcm_substream_chip(substream);
-
- PDEBUG(WORK_INFO, "close(capture)\n");
- ml403_ac97cr->capture_substream = NULL;
- return 0;
-}
-
-static struct snd_pcm_ops snd_ml403_ac97cr_playback_ops = {
- .open = snd_ml403_ac97cr_playback_open,
- .close = snd_ml403_ac97cr_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ml403_ac97cr_hw_params,
- .hw_free = snd_ml403_ac97cr_hw_free,
- .prepare = snd_ml403_ac97cr_pcm_playback_prepare,
- .trigger = snd_ml403_ac97cr_pcm_playback_trigger,
- .pointer = snd_ml403_ac97cr_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_ml403_ac97cr_capture_ops = {
- .open = snd_ml403_ac97cr_capture_open,
- .close = snd_ml403_ac97cr_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ml403_ac97cr_hw_params,
- .hw_free = snd_ml403_ac97cr_hw_free,
- .prepare = snd_ml403_ac97cr_pcm_capture_prepare,
- .trigger = snd_ml403_ac97cr_pcm_capture_trigger,
- .pointer = snd_ml403_ac97cr_pcm_pointer,
-};
-
-static irqreturn_t snd_ml403_ac97cr_irq(int irq, void *dev_id)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- struct platform_device *pfdev;
- int cmp_irq;
-
- ml403_ac97cr = (struct snd_ml403_ac97cr *)dev_id;
- if (ml403_ac97cr == NULL)
- return IRQ_NONE;
-
- pfdev = ml403_ac97cr->pfdev;
-
- /* playback interrupt */
- cmp_irq = platform_get_irq(pfdev, 0);
- if (irq == cmp_irq) {
- if (ml403_ac97cr->enable_irq)
- snd_pcm_indirect2_playback_interrupt(
- ml403_ac97cr->playback_substream,
- &ml403_ac97cr->ind_rec,
- snd_ml403_ac97cr_playback_ind2_copy,
- snd_ml403_ac97cr_playback_ind2_zero);
- else
- goto __disable_irq;
- } else {
- /* record interrupt */
- cmp_irq = platform_get_irq(pfdev, 1);
- if (irq == cmp_irq) {
- if (ml403_ac97cr->enable_capture_irq)
- snd_pcm_indirect2_capture_interrupt(
- ml403_ac97cr->capture_substream,
- &ml403_ac97cr->capture_ind2_rec,
- snd_ml403_ac97cr_capture_ind2_copy,
- snd_ml403_ac97cr_capture_ind2_null);
- else
- goto __disable_irq;
- } else
- return IRQ_NONE;
- }
- return IRQ_HANDLED;
-
-__disable_irq:
- PDEBUG(INIT_INFO, "irq(): irq %d is meant to be disabled! So, now try "
- "to disable it _really_!\n", irq);
- disable_irq_nosync(irq);
- return IRQ_HANDLED;
-}
-
-static unsigned short
-snd_ml403_ac97cr_codec_read(struct snd_ac97 *ac97, unsigned short reg)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr = ac97->private_data;
-#ifdef CODEC_STAT
- u32 stat;
- u32 rafaccess = 0;
-#endif
- unsigned long end_time;
- u16 value = 0;
-
- if (!LM4550_RF_OK(reg)) {
- snd_printk(KERN_WARNING SND_ML403_AC97CR_DRIVER ": "
- "access to unknown/unused codec register 0x%x "
- "ignored!\n", reg);
- return 0;
- }
- /* check if we can fake/answer this access from our shadow register */
- if ((lm4550_regfile[reg / 2].flag &
- (LM4550_REG_DONEREAD | LM4550_REG_ALLFAKE)) &&
- !(lm4550_regfile[reg / 2].flag & LM4550_REG_NOSHADOW)) {
- if (lm4550_regfile[reg / 2].flag & LM4550_REG_FAKEREAD) {
- PDEBUG(CODEC_FAKE, "codec_read(): faking read from "
- "reg=0x%x, val=0x%x / %d\n",
- reg, lm4550_regfile[reg / 2].def,
- lm4550_regfile[reg / 2].def);
- return lm4550_regfile[reg / 2].def;
- } else if ((lm4550_regfile[reg / 2].flag &
- LM4550_REG_FAKEPROBE) &&
- ml403_ac97cr->ac97_fake) {
- PDEBUG(CODEC_FAKE, "codec_read(): faking read from "
- "reg=0x%x, val=0x%x / %d (probe)\n",
- reg, lm4550_regfile[reg / 2].value,
- lm4550_regfile[reg / 2].value);
- return lm4550_regfile[reg / 2].value;
- } else {
-#ifdef CODEC_STAT
- PDEBUG(CODEC_FAKE, "codec_read(): read access "
- "answered by shadow register 0x%x (value=0x%x "
- "/ %d) (cw=%d cr=%d)\n",
- reg, lm4550_regfile[reg / 2].value,
- lm4550_regfile[reg / 2].value,
- ml403_ac97cr->ac97_write,
- ml403_ac97cr->ac97_read);
-#else
- PDEBUG(CODEC_FAKE, "codec_read(): read access "
- "answered by shadow register 0x%x (value=0x%x "
- "/ %d)\n",
- reg, lm4550_regfile[reg / 2].value,
- lm4550_regfile[reg / 2].value);
-#endif
- return lm4550_regfile[reg / 2].value;
- }
- }
- /* if we are here, we _have_ to access the codec really, no faking */
- if (mutex_lock_interruptible(&ml403_ac97cr->cdc_mutex) != 0)
- return 0;
-#ifdef CODEC_STAT
- ml403_ac97cr->ac97_read++;
-#endif
- spin_lock(&ml403_ac97cr->reg_lock);
- out_be32(CR_REG(ml403_ac97cr, CODEC_ADDR),
- CR_CODEC_ADDR(reg) | CR_CODEC_READ);
- spin_unlock(&ml403_ac97cr->reg_lock);
- end_time = jiffies + (HZ / CODEC_TIMEOUT_AFTER_READ);
- do {
- spin_lock(&ml403_ac97cr->reg_lock);
-#ifdef CODEC_STAT
- rafaccess++;
- stat = in_be32(CR_REG(ml403_ac97cr, STATUS));
- if ((stat & CR_RAF) == CR_RAF) {
- value = CR_CODEC_DATAREAD(
- in_be32(CR_REG(ml403_ac97cr, CODEC_DATAREAD)));
- PDEBUG(CODEC_SUCCESS, "codec_read(): (done) reg=0x%x, "
- "value=0x%x / %d (STATUS=0x%x)\n",
- reg, value, value, stat);
-#else
- if ((in_be32(CR_REG(ml403_ac97cr, STATUS)) &
- CR_RAF) == CR_RAF) {
- value = CR_CODEC_DATAREAD(
- in_be32(CR_REG(ml403_ac97cr, CODEC_DATAREAD)));
- PDEBUG(CODEC_SUCCESS, "codec_read(): (done) "
- "reg=0x%x, value=0x%x / %d\n",
- reg, value, value);
-#endif
- lm4550_regfile[reg / 2].value = value;
- lm4550_regfile[reg / 2].flag |= LM4550_REG_DONEREAD;
- spin_unlock(&ml403_ac97cr->reg_lock);
- mutex_unlock(&ml403_ac97cr->cdc_mutex);
- return value;
- }
- spin_unlock(&ml403_ac97cr->reg_lock);
- schedule_timeout_uninterruptible(1);
- } while (time_after(end_time, jiffies));
- /* read the DATAREAD register anyway, see comment below */
- spin_lock(&ml403_ac97cr->reg_lock);
- value =
- CR_CODEC_DATAREAD(in_be32(CR_REG(ml403_ac97cr, CODEC_DATAREAD)));
- spin_unlock(&ml403_ac97cr->reg_lock);
-#ifdef CODEC_STAT
- snd_printk(KERN_WARNING SND_ML403_AC97CR_DRIVER ": "
- "timeout while codec read! "
- "(reg=0x%x, last STATUS=0x%x, DATAREAD=0x%x / %d, %d) "
- "(cw=%d, cr=%d)\n",
- reg, stat, value, value, rafaccess,
- ml403_ac97cr->ac97_write, ml403_ac97cr->ac97_read);
-#else
- snd_printk(KERN_WARNING SND_ML403_AC97CR_DRIVER ": "
- "timeout while codec read! "
- "(reg=0x%x, DATAREAD=0x%x / %d)\n",
- reg, value, value);
-#endif
- /* BUG: This is PURE speculation! But after _most_ read timeouts the
- * value in the register is ok!
- */
- lm4550_regfile[reg / 2].value = value;
- lm4550_regfile[reg / 2].flag |= LM4550_REG_DONEREAD;
- mutex_unlock(&ml403_ac97cr->cdc_mutex);
- return value;
-}
-
-static void
-snd_ml403_ac97cr_codec_write(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short val)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr = ac97->private_data;
-
-#ifdef CODEC_STAT
- u32 stat;
- u32 rafaccess = 0;
-#endif
-#ifdef CODEC_WRITE_CHECK_RAF
- unsigned long end_time;
-#endif
-
- if (!LM4550_RF_OK(reg)) {
- snd_printk(KERN_WARNING SND_ML403_AC97CR_DRIVER ": "
- "access to unknown/unused codec register 0x%x "
- "ignored!\n", reg);
- return;
- }
- if (lm4550_regfile[reg / 2].flag & LM4550_REG_READONLY) {
- snd_printk(KERN_WARNING SND_ML403_AC97CR_DRIVER ": "
- "write access to read only codec register 0x%x "
- "ignored!\n", reg);
- return;
- }
- if ((val & lm4550_regfile[reg / 2].wmask) != val) {
- snd_printk(KERN_WARNING SND_ML403_AC97CR_DRIVER ": "
- "write access to codec register 0x%x "
- "with bad value 0x%x / %d!\n",
- reg, val, val);
- val = val & lm4550_regfile[reg / 2].wmask;
- }
- if (((lm4550_regfile[reg / 2].flag & LM4550_REG_FAKEPROBE) &&
- ml403_ac97cr->ac97_fake) &&
- !(lm4550_regfile[reg / 2].flag & LM4550_REG_NOSHADOW)) {
- PDEBUG(CODEC_FAKE, "codec_write(): faking write to reg=0x%x, "
- "val=0x%x / %d\n", reg, val, val);
- lm4550_regfile[reg / 2].value = (val &
- lm4550_regfile[reg / 2].wmask);
- return;
- }
- if (mutex_lock_interruptible(&ml403_ac97cr->cdc_mutex) != 0)
- return;
-#ifdef CODEC_STAT
- ml403_ac97cr->ac97_write++;
-#endif
- spin_lock(&ml403_ac97cr->reg_lock);
- out_be32(CR_REG(ml403_ac97cr, CODEC_DATAWRITE),
- CR_CODEC_DATAWRITE(val));
- out_be32(CR_REG(ml403_ac97cr, CODEC_ADDR),
- CR_CODEC_ADDR(reg) | CR_CODEC_WRITE);
- spin_unlock(&ml403_ac97cr->reg_lock);
-#ifdef CODEC_WRITE_CHECK_RAF
- /* check CR_CODEC_RAF bit to see if write access to register is done;
- * loop until bit is set or timeout happens
- */
- end_time = jiffies + HZ / CODEC_TIMEOUT_AFTER_WRITE;
- do {
- spin_lock(&ml403_ac97cr->reg_lock);
-#ifdef CODEC_STAT
- rafaccess++;
- stat = in_be32(CR_REG(ml403_ac97cr, STATUS))
- if ((stat & CR_RAF) == CR_RAF) {
-#else
- if ((in_be32(CR_REG(ml403_ac97cr, STATUS)) &
- CR_RAF) == CR_RAF) {
-#endif
- PDEBUG(CODEC_SUCCESS, "codec_write(): (done) "
- "reg=0x%x, value=%d / 0x%x\n",
- reg, val, val);
- if (!(lm4550_regfile[reg / 2].flag &
- LM4550_REG_NOSHADOW) &&
- !(lm4550_regfile[reg / 2].flag &
- LM4550_REG_NOSAVE))
- lm4550_regfile[reg / 2].value = val;
- lm4550_regfile[reg / 2].flag |= LM4550_REG_DONEREAD;
- spin_unlock(&ml403_ac97cr->reg_lock);
- mutex_unlock(&ml403_ac97cr->cdc_mutex);
- return;
- }
- spin_unlock(&ml403_ac97cr->reg_lock);
- schedule_timeout_uninterruptible(1);
- } while (time_after(end_time, jiffies));
-#ifdef CODEC_STAT
- snd_printk(KERN_WARNING SND_ML403_AC97CR_DRIVER ": "
- "timeout while codec write "
- "(reg=0x%x, val=0x%x / %d, last STATUS=0x%x, %d) "
- "(cw=%d, cr=%d)\n",
- reg, val, val, stat, rafaccess, ml403_ac97cr->ac97_write,
- ml403_ac97cr->ac97_read);
-#else
- snd_printk(KERN_WARNING SND_ML403_AC97CR_DRIVER ": "
- "timeout while codec write (reg=0x%x, val=0x%x / %d)\n",
- reg, val, val);
-#endif
-#else /* CODEC_WRITE_CHECK_RAF */
-#if CODEC_WAIT_AFTER_WRITE > 0
- /* officially, in AC97 spec there is no possibility for a AC97
- * controller to determine, if write access is done or not - so: How
- * is Xilinx able to provide a RAF bit for write access?
- * => very strange, thus just don't check RAF bit (compare with
- * Xilinx's example app in EDK 8.1i) and wait
- */
- schedule_timeout_uninterruptible(HZ / CODEC_WAIT_AFTER_WRITE);
-#endif
- PDEBUG(CODEC_SUCCESS, "codec_write(): (done) "
- "reg=0x%x, value=%d / 0x%x (no RAF check)\n",
- reg, val, val);
-#endif
- mutex_unlock(&ml403_ac97cr->cdc_mutex);
- return;
-}
-
-static int __devinit
-snd_ml403_ac97cr_chip_init(struct snd_ml403_ac97cr *ml403_ac97cr)
-{
- unsigned long end_time;
- PDEBUG(INIT_INFO, "chip_init():\n");
- end_time = jiffies + HZ / CODEC_TIMEOUT_ON_INIT;
- do {
- if (in_be32(CR_REG(ml403_ac97cr, STATUS)) & CR_CODECREADY) {
- /* clear both hardware FIFOs */
- out_be32(CR_REG(ml403_ac97cr, RESETFIFO),
- CR_RECRESET | CR_PLAYRESET);
- PDEBUG(INIT_INFO, "chip_init(): (done)\n");
- return 0;
- }
- schedule_timeout_uninterruptible(1);
- } while (time_after(end_time, jiffies));
- snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": "
- "timeout while waiting for codec, "
- "not ready!\n");
- return -EBUSY;
-}
-
-static int snd_ml403_ac97cr_free(struct snd_ml403_ac97cr *ml403_ac97cr)
-{
- PDEBUG(INIT_INFO, "free():\n");
- /* irq release */
- if (ml403_ac97cr->irq >= 0)
- free_irq(ml403_ac97cr->irq, ml403_ac97cr);
- if (ml403_ac97cr->capture_irq >= 0)
- free_irq(ml403_ac97cr->capture_irq, ml403_ac97cr);
- /* give back "port" */
- if (ml403_ac97cr->port != NULL)
- iounmap(ml403_ac97cr->port);
- kfree(ml403_ac97cr);
- PDEBUG(INIT_INFO, "free(): (done)\n");
- return 0;
-}
-
-static int snd_ml403_ac97cr_dev_free(struct snd_device *snddev)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr = snddev->device_data;
- PDEBUG(INIT_INFO, "dev_free():\n");
- return snd_ml403_ac97cr_free(ml403_ac97cr);
-}
-
-static int __devinit
-snd_ml403_ac97cr_create(struct snd_card *card, struct platform_device *pfdev,
- struct snd_ml403_ac97cr **rml403_ac97cr)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_ml403_ac97cr_dev_free,
- };
- struct resource *resource;
- int irq;
-
- *rml403_ac97cr = NULL;
- ml403_ac97cr = kzalloc(sizeof(*ml403_ac97cr), GFP_KERNEL);
- if (ml403_ac97cr == NULL)
- return -ENOMEM;
- spin_lock_init(&ml403_ac97cr->reg_lock);
- mutex_init(&ml403_ac97cr->cdc_mutex);
- ml403_ac97cr->card = card;
- ml403_ac97cr->pfdev = pfdev;
- ml403_ac97cr->irq = -1;
- ml403_ac97cr->enable_irq = 0;
- ml403_ac97cr->capture_irq = -1;
- ml403_ac97cr->enable_capture_irq = 0;
- ml403_ac97cr->port = NULL;
- ml403_ac97cr->res_port = NULL;
-
- PDEBUG(INIT_INFO, "Trying to reserve resources now ...\n");
- resource = platform_get_resource(pfdev, IORESOURCE_MEM, 0);
- /* get "port" */
- ml403_ac97cr->port = ioremap_nocache(resource->start,
- (resource->end) -
- (resource->start) + 1);
- if (ml403_ac97cr->port == NULL) {
- snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": "
- "unable to remap memory region (%pR)\n",
- resource);
- snd_ml403_ac97cr_free(ml403_ac97cr);
- return -EBUSY;
- }
- snd_printk(KERN_INFO SND_ML403_AC97CR_DRIVER ": "
- "remap controller memory region to "
- "0x%x done\n", (unsigned int)ml403_ac97cr->port);
- /* get irq */
- irq = platform_get_irq(pfdev, 0);
- if (request_irq(irq, snd_ml403_ac97cr_irq, 0,
- dev_name(&pfdev->dev), (void *)ml403_ac97cr)) {
- snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": "
- "unable to grab IRQ %d\n",
- irq);
- snd_ml403_ac97cr_free(ml403_ac97cr);
- return -EBUSY;
- }
- ml403_ac97cr->irq = irq;
- snd_printk(KERN_INFO SND_ML403_AC97CR_DRIVER ": "
- "request (playback) irq %d done\n",
- ml403_ac97cr->irq);
- irq = platform_get_irq(pfdev, 1);
- if (request_irq(irq, snd_ml403_ac97cr_irq, 0,
- dev_name(&pfdev->dev), (void *)ml403_ac97cr)) {
- snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": "
- "unable to grab IRQ %d\n",
- irq);
- snd_ml403_ac97cr_free(ml403_ac97cr);
- return -EBUSY;
- }
- ml403_ac97cr->capture_irq = irq;
- snd_printk(KERN_INFO SND_ML403_AC97CR_DRIVER ": "
- "request (capture) irq %d done\n",
- ml403_ac97cr->capture_irq);
-
- err = snd_ml403_ac97cr_chip_init(ml403_ac97cr);
- if (err < 0) {
- snd_ml403_ac97cr_free(ml403_ac97cr);
- return err;
- }
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ml403_ac97cr, &ops);
- if (err < 0) {
- PDEBUG(INIT_FAILURE, "probe(): snd_device_new() failed!\n");
- snd_ml403_ac97cr_free(ml403_ac97cr);
- return err;
- }
-
- *rml403_ac97cr = ml403_ac97cr;
- return 0;
-}
-
-static void snd_ml403_ac97cr_mixer_free(struct snd_ac97 *ac97)
-{
- struct snd_ml403_ac97cr *ml403_ac97cr = ac97->private_data;
- PDEBUG(INIT_INFO, "mixer_free():\n");
- ml403_ac97cr->ac97 = NULL;
- PDEBUG(INIT_INFO, "mixer_free(): (done)\n");
-}
-
-static int __devinit
-snd_ml403_ac97cr_mixer(struct snd_ml403_ac97cr *ml403_ac97cr)
-{
- struct snd_ac97_bus *bus;
- struct snd_ac97_template ac97;
- int err;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_ml403_ac97cr_codec_write,
- .read = snd_ml403_ac97cr_codec_read,
- };
- PDEBUG(INIT_INFO, "mixer():\n");
- err = snd_ac97_bus(ml403_ac97cr->card, 0, &ops, NULL, &bus);
- if (err < 0)
- return err;
-
- memset(&ac97, 0, sizeof(ac97));
- ml403_ac97cr->ac97_fake = 1;
- lm4550_regfile_init();
-#ifdef CODEC_STAT
- ml403_ac97cr->ac97_read = 0;
- ml403_ac97cr->ac97_write = 0;
-#endif
- ac97.private_data = ml403_ac97cr;
- ac97.private_free = snd_ml403_ac97cr_mixer_free;
- ac97.scaps = AC97_SCAP_AUDIO | AC97_SCAP_SKIP_MODEM |
- AC97_SCAP_NO_SPDIF;
- err = snd_ac97_mixer(bus, &ac97, &ml403_ac97cr->ac97);
- ml403_ac97cr->ac97_fake = 0;
- lm4550_regfile_write_values_after_init(ml403_ac97cr->ac97);
- PDEBUG(INIT_INFO, "mixer(): (done) snd_ac97_mixer()=%d\n", err);
- return err;
-}
-
-static int __devinit
-snd_ml403_ac97cr_pcm(struct snd_ml403_ac97cr *ml403_ac97cr, int device,
- struct snd_pcm **rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
- err = snd_pcm_new(ml403_ac97cr->card, "ML403AC97CR/1", device, 1, 1,
- &pcm);
- if (err < 0)
- return err;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_ml403_ac97cr_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_ml403_ac97cr_capture_ops);
- pcm->private_data = ml403_ac97cr;
- pcm->info_flags = 0;
- strcpy(pcm->name, "ML403AC97CR DAC/ADC");
- ml403_ac97cr->pcm = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- 64 * 1024,
- 128 * 1024);
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-static int __devinit snd_ml403_ac97cr_probe(struct platform_device *pfdev)
-{
- struct snd_card *card;
- struct snd_ml403_ac97cr *ml403_ac97cr = NULL;
- int err;
- int dev = pfdev->id;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev])
- return -ENOENT;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
- err = snd_ml403_ac97cr_create(card, pfdev, &ml403_ac97cr);
- if (err < 0) {
- PDEBUG(INIT_FAILURE, "probe(): create failed!\n");
- snd_card_free(card);
- return err;
- }
- PDEBUG(INIT_INFO, "probe(): create done\n");
- card->private_data = ml403_ac97cr;
- err = snd_ml403_ac97cr_mixer(ml403_ac97cr);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- PDEBUG(INIT_INFO, "probe(): mixer done\n");
- err = snd_ml403_ac97cr_pcm(ml403_ac97cr, 0, NULL);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- PDEBUG(INIT_INFO, "probe(): PCM done\n");
- strcpy(card->driver, SND_ML403_AC97CR_DRIVER);
- strcpy(card->shortname, "ML403 AC97 Controller Reference");
- sprintf(card->longname, "%s %s at 0x%lx, irq %i & %i, device %i",
- card->shortname, card->driver,
- (unsigned long)ml403_ac97cr->port, ml403_ac97cr->irq,
- ml403_ac97cr->capture_irq, dev + 1);
-
- snd_card_set_dev(card, &pfdev->dev);
-
- err = snd_card_register(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- platform_set_drvdata(pfdev, card);
- PDEBUG(INIT_INFO, "probe(): (done)\n");
- return 0;
-}
-
-static int snd_ml403_ac97cr_remove(struct platform_device *pfdev)
-{
- snd_card_free(platform_get_drvdata(pfdev));
- platform_set_drvdata(pfdev, NULL);
- return 0;
-}
-
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:" SND_ML403_AC97CR_DRIVER);
-
-static struct platform_driver snd_ml403_ac97cr_driver = {
- .probe = snd_ml403_ac97cr_probe,
- .remove = snd_ml403_ac97cr_remove,
- .driver = {
- .name = SND_ML403_AC97CR_DRIVER,
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(snd_ml403_ac97cr_driver);
diff --git a/ANDROID_3.4.5/sound/drivers/mpu401/Makefile b/ANDROID_3.4.5/sound/drivers/mpu401/Makefile
deleted file mode 100644
index 918f83f3..00000000
--- a/ANDROID_3.4.5/sound/drivers/mpu401/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-mpu401-objs := mpu401.o
-snd-mpu401-uart-objs := mpu401_uart.o
-
-obj-$(CONFIG_SND_MPU401_UART) += snd-mpu401-uart.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_MPU401) += snd-mpu401.o
diff --git a/ANDROID_3.4.5/sound/drivers/mpu401/mpu401.c b/ANDROID_3.4.5/sound/drivers/mpu401/mpu401.c
deleted file mode 100644
index 86f5fbc2..00000000
--- a/ANDROID_3.4.5/sound/drivers/mpu401/mpu401.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Driver for generic MPU-401 boards (UART mode only)
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Copyright (c) 2004 by Castet Matthieu <castet.matthieu@free.fr>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/pnp.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/mpu401.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("MPU-401 UART");
-MODULE_LICENSE("GPL");
-
-static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* exclude the first card */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
-#ifdef CONFIG_PNP
-static bool pnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
-#endif
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* MPU-401 port number */
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* MPU-401 IRQ */
-static bool uart_enter[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for MPU-401 device.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for MPU-401 device.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable MPU-401 device.");
-#ifdef CONFIG_PNP
-module_param_array(pnp, bool, NULL, 0444);
-MODULE_PARM_DESC(pnp, "PnP detection for MPU-401 device.");
-#endif
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for MPU-401 device.");
-module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device.");
-module_param_array(uart_enter, bool, NULL, 0444);
-MODULE_PARM_DESC(uart_enter, "Issue UART_ENTER command at open.");
-
-static struct platform_device *platform_devices[SNDRV_CARDS];
-static int pnp_registered;
-static unsigned int snd_mpu401_devices;
-
-static int snd_mpu401_create(int dev, struct snd_card **rcard)
-{
- struct snd_card *card;
- int err;
-
- if (!uart_enter[dev])
- snd_printk(KERN_ERR "the uart_enter option is obsolete; remove it\n");
-
- *rcard = NULL;
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
- strcpy(card->driver, "MPU-401 UART");
- strcpy(card->shortname, card->driver);
- sprintf(card->longname, "%s at %#lx, ", card->shortname, port[dev]);
- if (irq[dev] >= 0) {
- sprintf(card->longname + strlen(card->longname), "irq %d", irq[dev]);
- } else {
- strcat(card->longname, "polled");
- }
-
- err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port[dev], 0,
- irq[dev], NULL);
- if (err < 0) {
- printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]);
- goto _err;
- }
-
- *rcard = card;
- return 0;
-
- _err:
- snd_card_free(card);
- return err;
-}
-
-static int __devinit snd_mpu401_probe(struct platform_device *devptr)
-{
- int dev = devptr->id;
- int err;
- struct snd_card *card;
-
- if (port[dev] == SNDRV_AUTO_PORT) {
- snd_printk(KERN_ERR "specify port\n");
- return -EINVAL;
- }
- if (irq[dev] == SNDRV_AUTO_IRQ) {
- snd_printk(KERN_ERR "specify or disable IRQ\n");
- return -EINVAL;
- }
- err = snd_mpu401_create(dev, &card);
- if (err < 0)
- return err;
- snd_card_set_dev(card, &devptr->dev);
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- platform_set_drvdata(devptr, card);
- return 0;
-}
-
-static int __devexit snd_mpu401_remove(struct platform_device *devptr)
-{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
- return 0;
-}
-
-#define SND_MPU401_DRIVER "snd_mpu401"
-
-static struct platform_driver snd_mpu401_driver = {
- .probe = snd_mpu401_probe,
- .remove = __devexit_p(snd_mpu401_remove),
- .driver = {
- .name = SND_MPU401_DRIVER
- },
-};
-
-
-#ifdef CONFIG_PNP
-
-#define IO_EXTENT 2
-
-static struct pnp_device_id snd_mpu401_pnpids[] = {
- { .id = "PNPb006" },
- { .id = "" }
-};
-
-MODULE_DEVICE_TABLE(pnp, snd_mpu401_pnpids);
-
-static int __devinit snd_mpu401_pnp(int dev, struct pnp_dev *device,
- const struct pnp_device_id *id)
-{
- if (!pnp_port_valid(device, 0) ||
- pnp_port_flags(device, 0) & IORESOURCE_DISABLED) {
- snd_printk(KERN_ERR "no PnP port\n");
- return -ENODEV;
- }
- if (pnp_port_len(device, 0) < IO_EXTENT) {
- snd_printk(KERN_ERR "PnP port length is %llu, expected %d\n",
- (unsigned long long)pnp_port_len(device, 0),
- IO_EXTENT);
- return -ENODEV;
- }
- port[dev] = pnp_port_start(device, 0);
-
- if (!pnp_irq_valid(device, 0) ||
- pnp_irq_flags(device, 0) & IORESOURCE_DISABLED) {
- snd_printk(KERN_WARNING "no PnP irq, using polling\n");
- irq[dev] = -1;
- } else {
- irq[dev] = pnp_irq(device, 0);
- }
- return 0;
-}
-
-static int __devinit snd_mpu401_pnp_probe(struct pnp_dev *pnp_dev,
- const struct pnp_device_id *id)
-{
- static int dev;
- struct snd_card *card;
- int err;
-
- for ( ; dev < SNDRV_CARDS; ++dev) {
- if (!enable[dev] || !pnp[dev])
- continue;
- err = snd_mpu401_pnp(dev, pnp_dev, id);
- if (err < 0)
- return err;
- err = snd_mpu401_create(dev, &card);
- if (err < 0)
- return err;
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- snd_card_set_dev(card, &pnp_dev->dev);
- pnp_set_drvdata(pnp_dev, card);
- snd_mpu401_devices++;
- ++dev;
- return 0;
- }
- return -ENODEV;
-}
-
-static void __devexit snd_mpu401_pnp_remove(struct pnp_dev *dev)
-{
- struct snd_card *card = (struct snd_card *) pnp_get_drvdata(dev);
-
- snd_card_disconnect(card);
- snd_card_free_when_closed(card);
-}
-
-static struct pnp_driver snd_mpu401_pnp_driver = {
- .name = "mpu401",
- .id_table = snd_mpu401_pnpids,
- .probe = snd_mpu401_pnp_probe,
- .remove = __devexit_p(snd_mpu401_pnp_remove),
-};
-#else
-static struct pnp_driver snd_mpu401_pnp_driver;
-#endif
-
-static void snd_mpu401_unregister_all(void)
-{
- int i;
-
- if (pnp_registered)
- pnp_unregister_driver(&snd_mpu401_pnp_driver);
- for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
- platform_device_unregister(platform_devices[i]);
- platform_driver_unregister(&snd_mpu401_driver);
-}
-
-static int __init alsa_card_mpu401_init(void)
-{
- int i, err;
-
- if ((err = platform_driver_register(&snd_mpu401_driver)) < 0)
- return err;
-
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i])
- continue;
-#ifdef CONFIG_PNP
- if (pnp[i])
- continue;
-#endif
- device = platform_device_register_simple(SND_MPU401_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- platform_devices[i] = device;
- snd_mpu401_devices++;
- }
- err = pnp_register_driver(&snd_mpu401_pnp_driver);
- if (!err)
- pnp_registered = 1;
-
- if (!snd_mpu401_devices) {
-#ifdef MODULE
- printk(KERN_ERR "MPU-401 device not found or device busy\n");
-#endif
- snd_mpu401_unregister_all();
- return -ENODEV;
- }
- return 0;
-}
-
-static void __exit alsa_card_mpu401_exit(void)
-{
- snd_mpu401_unregister_all();
-}
-
-module_init(alsa_card_mpu401_init)
-module_exit(alsa_card_mpu401_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/mpu401/mpu401_uart.c b/ANDROID_3.4.5/sound/drivers/mpu401/mpu401_uart.c
deleted file mode 100644
index 1cff331a..00000000
--- a/ANDROID_3.4.5/sound/drivers/mpu401/mpu401_uart.c
+++ /dev/null
@@ -1,632 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Routines for control of MPU-401 in UART mode
- *
- * MPU-401 supports UART mode which is not capable generate transmit
- * interrupts thus output is done via polling. Without interrupt,
- * input is done also via polling. Do not expect good performance.
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * 13-03-2003:
- * Added support for different kind of hardware I/O. Build in choices
- * are port and mmio. For other kind of I/O, set mpu->read and
- * mpu->write to your own I/O functions.
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/errno.h>
-#include <sound/core.h>
-#include <sound/mpu401.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Routines for control of MPU-401 in UART mode");
-MODULE_LICENSE("GPL");
-
-static void snd_mpu401_uart_input_read(struct snd_mpu401 * mpu);
-static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu);
-
-/*
-
- */
-
-#define snd_mpu401_input_avail(mpu) \
- (!(mpu->read(mpu, MPU401C(mpu)) & MPU401_RX_EMPTY))
-#define snd_mpu401_output_ready(mpu) \
- (!(mpu->read(mpu, MPU401C(mpu)) & MPU401_TX_FULL))
-
-/* Build in lowlevel io */
-static void mpu401_write_port(struct snd_mpu401 *mpu, unsigned char data,
- unsigned long addr)
-{
- outb(data, addr);
-}
-
-static unsigned char mpu401_read_port(struct snd_mpu401 *mpu,
- unsigned long addr)
-{
- return inb(addr);
-}
-
-static void mpu401_write_mmio(struct snd_mpu401 *mpu, unsigned char data,
- unsigned long addr)
-{
- writeb(data, (void __iomem *)addr);
-}
-
-static unsigned char mpu401_read_mmio(struct snd_mpu401 *mpu,
- unsigned long addr)
-{
- return readb((void __iomem *)addr);
-}
-/* */
-
-static void snd_mpu401_uart_clear_rx(struct snd_mpu401 *mpu)
-{
- int timeout = 100000;
- for (; timeout > 0 && snd_mpu401_input_avail(mpu); timeout--)
- mpu->read(mpu, MPU401D(mpu));
-#ifdef CONFIG_SND_DEBUG
- if (timeout <= 0)
- snd_printk(KERN_ERR "cmd: clear rx timeout (status = 0x%x)\n",
- mpu->read(mpu, MPU401C(mpu)));
-#endif
-}
-
-static void uart_interrupt_tx(struct snd_mpu401 *mpu)
-{
- unsigned long flags;
-
- if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) &&
- test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) {
- spin_lock_irqsave(&mpu->output_lock, flags);
- snd_mpu401_uart_output_write(mpu);
- spin_unlock_irqrestore(&mpu->output_lock, flags);
- }
-}
-
-static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu)
-{
- unsigned long flags;
-
- if (mpu->info_flags & MPU401_INFO_INPUT) {
- spin_lock_irqsave(&mpu->input_lock, flags);
- if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode))
- snd_mpu401_uart_input_read(mpu);
- else
- snd_mpu401_uart_clear_rx(mpu);
- spin_unlock_irqrestore(&mpu->input_lock, flags);
- }
- if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
- /* ok. for better Tx performance try do some output
- when input is done */
- uart_interrupt_tx(mpu);
-}
-
-/**
- * snd_mpu401_uart_interrupt - generic MPU401-UART interrupt handler
- * @irq: the irq number
- * @dev_id: mpu401 instance
- *
- * Processes the interrupt for MPU401-UART i/o.
- */
-irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id)
-{
- struct snd_mpu401 *mpu = dev_id;
-
- if (mpu == NULL)
- return IRQ_NONE;
- _snd_mpu401_uart_interrupt(mpu);
- return IRQ_HANDLED;
-}
-
-EXPORT_SYMBOL(snd_mpu401_uart_interrupt);
-
-/**
- * snd_mpu401_uart_interrupt_tx - generic MPU401-UART transmit irq handler
- * @irq: the irq number
- * @dev_id: mpu401 instance
- *
- * Processes the interrupt for MPU401-UART output.
- */
-irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id)
-{
- struct snd_mpu401 *mpu = dev_id;
-
- if (mpu == NULL)
- return IRQ_NONE;
- uart_interrupt_tx(mpu);
- return IRQ_HANDLED;
-}
-
-EXPORT_SYMBOL(snd_mpu401_uart_interrupt_tx);
-
-/*
- * timer callback
- * reprogram the timer and call the interrupt job
- */
-static void snd_mpu401_uart_timer(unsigned long data)
-{
- struct snd_mpu401 *mpu = (struct snd_mpu401 *)data;
- unsigned long flags;
-
- spin_lock_irqsave(&mpu->timer_lock, flags);
- /*mpu->mode |= MPU401_MODE_TIMER;*/
- mpu->timer.expires = 1 + jiffies;
- add_timer(&mpu->timer);
- spin_unlock_irqrestore(&mpu->timer_lock, flags);
- if (mpu->rmidi)
- _snd_mpu401_uart_interrupt(mpu);
-}
-
-/*
- * initialize the timer callback if not programmed yet
- */
-static void snd_mpu401_uart_add_timer (struct snd_mpu401 *mpu, int input)
-{
- unsigned long flags;
-
- spin_lock_irqsave (&mpu->timer_lock, flags);
- if (mpu->timer_invoked == 0) {
- init_timer(&mpu->timer);
- mpu->timer.data = (unsigned long)mpu;
- mpu->timer.function = snd_mpu401_uart_timer;
- mpu->timer.expires = 1 + jiffies;
- add_timer(&mpu->timer);
- }
- mpu->timer_invoked |= input ? MPU401_MODE_INPUT_TIMER :
- MPU401_MODE_OUTPUT_TIMER;
- spin_unlock_irqrestore (&mpu->timer_lock, flags);
-}
-
-/*
- * remove the timer callback if still active
- */
-static void snd_mpu401_uart_remove_timer (struct snd_mpu401 *mpu, int input)
-{
- unsigned long flags;
-
- spin_lock_irqsave (&mpu->timer_lock, flags);
- if (mpu->timer_invoked) {
- mpu->timer_invoked &= input ? ~MPU401_MODE_INPUT_TIMER :
- ~MPU401_MODE_OUTPUT_TIMER;
- if (! mpu->timer_invoked)
- del_timer(&mpu->timer);
- }
- spin_unlock_irqrestore (&mpu->timer_lock, flags);
-}
-
-/*
- * send a UART command
- * return zero if successful, non-zero for some errors
- */
-
-static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd,
- int ack)
-{
- unsigned long flags;
- int timeout, ok;
-
- spin_lock_irqsave(&mpu->input_lock, flags);
- if (mpu->hardware != MPU401_HW_TRID4DWAVE) {
- mpu->write(mpu, 0x00, MPU401D(mpu));
- /*snd_mpu401_uart_clear_rx(mpu);*/
- }
- /* ok. standard MPU-401 initialization */
- if (mpu->hardware != MPU401_HW_SB) {
- for (timeout = 1000; timeout > 0 &&
- !snd_mpu401_output_ready(mpu); timeout--)
- udelay(10);
-#ifdef CONFIG_SND_DEBUG
- if (!timeout)
- snd_printk(KERN_ERR "cmd: tx timeout (status = 0x%x)\n",
- mpu->read(mpu, MPU401C(mpu)));
-#endif
- }
- mpu->write(mpu, cmd, MPU401C(mpu));
- if (ack && !(mpu->info_flags & MPU401_INFO_NO_ACK)) {
- ok = 0;
- timeout = 10000;
- while (!ok && timeout-- > 0) {
- if (snd_mpu401_input_avail(mpu)) {
- if (mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK)
- ok = 1;
- }
- }
- if (!ok && mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK)
- ok = 1;
- } else
- ok = 1;
- spin_unlock_irqrestore(&mpu->input_lock, flags);
- if (!ok) {
- snd_printk(KERN_ERR "cmd: 0x%x failed at 0x%lx "
- "(status = 0x%x, data = 0x%x)\n", cmd, mpu->port,
- mpu->read(mpu, MPU401C(mpu)),
- mpu->read(mpu, MPU401D(mpu)));
- return 1;
- }
- return 0;
-}
-
-static int snd_mpu401_do_reset(struct snd_mpu401 *mpu)
-{
- if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1))
- return -EIO;
- if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 0))
- return -EIO;
- return 0;
-}
-
-/*
- * input/output open/close - protected by open_mutex in rawmidi.c
- */
-static int snd_mpu401_uart_input_open(struct snd_rawmidi_substream *substream)
-{
- struct snd_mpu401 *mpu;
- int err;
-
- mpu = substream->rmidi->private_data;
- if (mpu->open_input && (err = mpu->open_input(mpu)) < 0)
- return err;
- if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) {
- if (snd_mpu401_do_reset(mpu) < 0)
- goto error_out;
- }
- mpu->substream_input = substream;
- set_bit(MPU401_MODE_BIT_INPUT, &mpu->mode);
- return 0;
-
-error_out:
- if (mpu->open_input && mpu->close_input)
- mpu->close_input(mpu);
- return -EIO;
-}
-
-static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream)
-{
- struct snd_mpu401 *mpu;
- int err;
-
- mpu = substream->rmidi->private_data;
- if (mpu->open_output && (err = mpu->open_output(mpu)) < 0)
- return err;
- if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) {
- if (snd_mpu401_do_reset(mpu) < 0)
- goto error_out;
- }
- mpu->substream_output = substream;
- set_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode);
- return 0;
-
-error_out:
- if (mpu->open_output && mpu->close_output)
- mpu->close_output(mpu);
- return -EIO;
-}
-
-static int snd_mpu401_uart_input_close(struct snd_rawmidi_substream *substream)
-{
- struct snd_mpu401 *mpu;
- int err = 0;
-
- mpu = substream->rmidi->private_data;
- clear_bit(MPU401_MODE_BIT_INPUT, &mpu->mode);
- mpu->substream_input = NULL;
- if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode))
- err = snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0);
- if (mpu->close_input)
- mpu->close_input(mpu);
- if (err)
- return -EIO;
- return 0;
-}
-
-static int snd_mpu401_uart_output_close(struct snd_rawmidi_substream *substream)
-{
- struct snd_mpu401 *mpu;
- int err = 0;
-
- mpu = substream->rmidi->private_data;
- clear_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode);
- mpu->substream_output = NULL;
- if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode))
- err = snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0);
- if (mpu->close_output)
- mpu->close_output(mpu);
- if (err)
- return -EIO;
- return 0;
-}
-
-/*
- * trigger input callback
- */
-static void
-snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- unsigned long flags;
- struct snd_mpu401 *mpu;
- int max = 64;
-
- mpu = substream->rmidi->private_data;
- if (up) {
- if (! test_and_set_bit(MPU401_MODE_BIT_INPUT_TRIGGER,
- &mpu->mode)) {
- /* first time - flush FIFO */
- while (max-- > 0)
- mpu->read(mpu, MPU401D(mpu));
- if (mpu->info_flags & MPU401_INFO_USE_TIMER)
- snd_mpu401_uart_add_timer(mpu, 1);
- }
-
- /* read data in advance */
- spin_lock_irqsave(&mpu->input_lock, flags);
- snd_mpu401_uart_input_read(mpu);
- spin_unlock_irqrestore(&mpu->input_lock, flags);
- } else {
- if (mpu->info_flags & MPU401_INFO_USE_TIMER)
- snd_mpu401_uart_remove_timer(mpu, 1);
- clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode);
- }
-
-}
-
-/*
- * transfer input pending data
- * call with input_lock spinlock held
- */
-static void snd_mpu401_uart_input_read(struct snd_mpu401 * mpu)
-{
- int max = 128;
- unsigned char byte;
-
- while (max-- > 0) {
- if (! snd_mpu401_input_avail(mpu))
- break; /* input not available */
- byte = mpu->read(mpu, MPU401D(mpu));
- if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode))
- snd_rawmidi_receive(mpu->substream_input, &byte, 1);
- }
-}
-
-/*
- * Tx FIFO sizes:
- * CS4237B - 16 bytes
- * AudioDrive ES1688 - 12 bytes
- * S3 SonicVibes - 8 bytes
- * SoundBlaster AWE 64 - 2 bytes (ugly hardware)
- */
-
-/*
- * write output pending bytes
- * call with output_lock spinlock held
- */
-static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu)
-{
- unsigned char byte;
- int max = 256;
-
- do {
- if (snd_rawmidi_transmit_peek(mpu->substream_output,
- &byte, 1) == 1) {
- /*
- * Try twice because there is hardware that insists on
- * setting the output busy bit after each write.
- */
- if (!snd_mpu401_output_ready(mpu) &&
- !snd_mpu401_output_ready(mpu))
- break; /* Tx FIFO full - try again later */
- mpu->write(mpu, byte, MPU401D(mpu));
- snd_rawmidi_transmit_ack(mpu->substream_output, 1);
- } else {
- snd_mpu401_uart_remove_timer (mpu, 0);
- break; /* no other data - leave the tx loop */
- }
- } while (--max > 0);
-}
-
-/*
- * output trigger callback
- */
-static void
-snd_mpu401_uart_output_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- unsigned long flags;
- struct snd_mpu401 *mpu;
-
- mpu = substream->rmidi->private_data;
- if (up) {
- set_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode);
-
- /* try to add the timer at each output trigger,
- * since the output timer might have been removed in
- * snd_mpu401_uart_output_write().
- */
- if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
- snd_mpu401_uart_add_timer(mpu, 0);
-
- /* output pending data */
- spin_lock_irqsave(&mpu->output_lock, flags);
- snd_mpu401_uart_output_write(mpu);
- spin_unlock_irqrestore(&mpu->output_lock, flags);
- } else {
- if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
- snd_mpu401_uart_remove_timer(mpu, 0);
- clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode);
- }
-}
-
-/*
-
- */
-
-static struct snd_rawmidi_ops snd_mpu401_uart_output =
-{
- .open = snd_mpu401_uart_output_open,
- .close = snd_mpu401_uart_output_close,
- .trigger = snd_mpu401_uart_output_trigger,
-};
-
-static struct snd_rawmidi_ops snd_mpu401_uart_input =
-{
- .open = snd_mpu401_uart_input_open,
- .close = snd_mpu401_uart_input_close,
- .trigger = snd_mpu401_uart_input_trigger,
-};
-
-static void snd_mpu401_uart_free(struct snd_rawmidi *rmidi)
-{
- struct snd_mpu401 *mpu = rmidi->private_data;
- if (mpu->irq >= 0)
- free_irq(mpu->irq, (void *) mpu);
- release_and_free_resource(mpu->res);
- kfree(mpu);
-}
-
-/**
- * snd_mpu401_uart_new - create an MPU401-UART instance
- * @card: the card instance
- * @device: the device index, zero-based
- * @hardware: the hardware type, MPU401_HW_XXXX
- * @port: the base address of MPU401 port
- * @info_flags: bitflags MPU401_INFO_XXX
- * @irq: the ISA irq number, -1 if not to be allocated
- * @rrawmidi: the pointer to store the new rawmidi instance
- *
- * Creates a new MPU-401 instance.
- *
- * Note that the rawmidi instance is returned on the rrawmidi argument,
- * not the mpu401 instance itself. To access to the mpu401 instance,
- * cast from rawmidi->private_data (with struct snd_mpu401 magic-cast).
- *
- * Returns zero if successful, or a negative error code.
- */
-int snd_mpu401_uart_new(struct snd_card *card, int device,
- unsigned short hardware,
- unsigned long port,
- unsigned int info_flags,
- int irq,
- struct snd_rawmidi ** rrawmidi)
-{
- struct snd_mpu401 *mpu;
- struct snd_rawmidi *rmidi;
- int in_enable, out_enable;
- int err;
-
- if (rrawmidi)
- *rrawmidi = NULL;
- if (! (info_flags & (MPU401_INFO_INPUT | MPU401_INFO_OUTPUT)))
- info_flags |= MPU401_INFO_INPUT | MPU401_INFO_OUTPUT;
- in_enable = (info_flags & MPU401_INFO_INPUT) ? 1 : 0;
- out_enable = (info_flags & MPU401_INFO_OUTPUT) ? 1 : 0;
- if ((err = snd_rawmidi_new(card, "MPU-401U", device,
- out_enable, in_enable, &rmidi)) < 0)
- return err;
- mpu = kzalloc(sizeof(*mpu), GFP_KERNEL);
- if (mpu == NULL) {
- snd_printk(KERN_ERR "mpu401_uart: cannot allocate\n");
- snd_device_free(card, rmidi);
- return -ENOMEM;
- }
- rmidi->private_data = mpu;
- rmidi->private_free = snd_mpu401_uart_free;
- spin_lock_init(&mpu->input_lock);
- spin_lock_init(&mpu->output_lock);
- spin_lock_init(&mpu->timer_lock);
- mpu->hardware = hardware;
- if (! (info_flags & MPU401_INFO_INTEGRATED)) {
- int res_size = hardware == MPU401_HW_PC98II ? 4 : 2;
- mpu->res = request_region(port, res_size, "MPU401 UART");
- if (mpu->res == NULL) {
- snd_printk(KERN_ERR "mpu401_uart: "
- "unable to grab port 0x%lx size %d\n",
- port, res_size);
- snd_device_free(card, rmidi);
- return -EBUSY;
- }
- }
- if (info_flags & MPU401_INFO_MMIO) {
- mpu->write = mpu401_write_mmio;
- mpu->read = mpu401_read_mmio;
- } else {
- mpu->write = mpu401_write_port;
- mpu->read = mpu401_read_port;
- }
- mpu->port = port;
- if (hardware == MPU401_HW_PC98II)
- mpu->cport = port + 2;
- else
- mpu->cport = port + 1;
- if (irq >= 0) {
- if (request_irq(irq, snd_mpu401_uart_interrupt, 0,
- "MPU401 UART", (void *) mpu)) {
- snd_printk(KERN_ERR "mpu401_uart: "
- "unable to grab IRQ %d\n", irq);
- snd_device_free(card, rmidi);
- return -EBUSY;
- }
- }
- if (irq < 0 && !(info_flags & MPU401_INFO_IRQ_HOOK))
- info_flags |= MPU401_INFO_USE_TIMER;
- mpu->info_flags = info_flags;
- mpu->irq = irq;
- if (card->shortname[0])
- snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI",
- card->shortname);
- else
- sprintf(rmidi->name, "MPU-401 MIDI %d-%d",card->number, device);
- if (out_enable) {
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
- &snd_mpu401_uart_output);
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
- }
- if (in_enable) {
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
- &snd_mpu401_uart_input);
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
- if (out_enable)
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX;
- }
- mpu->rmidi = rmidi;
- if (rrawmidi)
- *rrawmidi = rmidi;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_mpu401_uart_new);
-
-/*
- * INIT part
- */
-
-static int __init alsa_mpu401_uart_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_mpu401_uart_exit(void)
-{
-}
-
-module_init(alsa_mpu401_uart_init)
-module_exit(alsa_mpu401_uart_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/mtpav.c b/ANDROID_3.4.5/sound/drivers/mtpav.c
deleted file mode 100644
index 76930793..00000000
--- a/ANDROID_3.4.5/sound/drivers/mtpav.c
+++ /dev/null
@@ -1,792 +0,0 @@
-/*
- * MOTU Midi Timepiece ALSA Main routines
- * Copyright by Michael T. Mayers (c) Jan 09, 2000
- * mail: michael@tweakoz.com
- * Thanks to John Galbraith
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
- * This driver is for the 'Mark Of The Unicorn' (MOTU)
- * MidiTimePiece AV multiport MIDI interface
- *
- * IOPORTS
- * -------
- * 8 MIDI Ins and 8 MIDI outs
- * Video Sync In (BNC), Word Sync Out (BNC),
- * ADAT Sync Out (DB9)
- * SMPTE in/out (1/4")
- * 2 programmable pedal/footswitch inputs and 4 programmable MIDI controller knobs.
- * Macintosh RS422 serial port
- * RS422 "network" port for ganging multiple MTP's
- * PC Parallel Port ( which this driver currently uses )
- *
- * MISC FEATURES
- * -------------
- * Hardware MIDI routing, merging, and filtering
- * MIDI Synchronization to Video, ADAT, SMPTE and other Clock sources
- * 128 'scene' memories, recallable from MIDI program change
- *
- *
- * ChangeLog
- * Jun 11 2001 Takashi Iwai <tiwai@suse.de>
- * - Recoded & debugged
- * - Added timer interrupt for midi outputs
- * - hwports is between 1 and 8, which specifies the number of hardware ports.
- * The three global ports, computer, adat and broadcast ports, are created
- * always after h/w and remote ports.
- *
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-#include <linux/moduleparam.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/rawmidi.h>
-#include <linux/delay.h>
-
-/*
- * globals
- */
-MODULE_AUTHOR("Michael T. Mayers");
-MODULE_DESCRIPTION("MOTU MidiTimePiece AV multiport MIDI");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{MOTU,MidiTimePiece AV multiport MIDI}}");
-
-// io resources
-#define MTPAV_IOBASE 0x378
-#define MTPAV_IRQ 7
-#define MTPAV_MAX_PORTS 8
-
-static int index = SNDRV_DEFAULT_IDX1;
-static char *id = SNDRV_DEFAULT_STR1;
-static long port = MTPAV_IOBASE; /* 0x378, 0x278 */
-static int irq = MTPAV_IRQ; /* 7, 5 */
-static int hwports = MTPAV_MAX_PORTS; /* use hardware ports 1-8 */
-
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for MotuMTPAV MIDI.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for MotuMTPAV MIDI.");
-module_param(port, long, 0444);
-MODULE_PARM_DESC(port, "Parallel port # for MotuMTPAV MIDI.");
-module_param(irq, int, 0444);
-MODULE_PARM_DESC(irq, "Parallel IRQ # for MotuMTPAV MIDI.");
-module_param(hwports, int, 0444);
-MODULE_PARM_DESC(hwports, "Hardware ports # for MotuMTPAV MIDI.");
-
-static struct platform_device *device;
-
-/*
- * defines
- */
-//#define USE_FAKE_MTP // don't actually read/write to MTP device (for debugging without an actual unit) (does not work yet)
-
-// parallel port usage masks
-#define SIGS_BYTE 0x08
-#define SIGS_RFD 0x80
-#define SIGS_IRQ 0x40
-#define SIGS_IN0 0x10
-#define SIGS_IN1 0x20
-
-#define SIGC_WRITE 0x04
-#define SIGC_READ 0x08
-#define SIGC_INTEN 0x10
-
-#define DREG 0
-#define SREG 1
-#define CREG 2
-
-//
-#define MTPAV_MODE_INPUT_OPENED 0x01
-#define MTPAV_MODE_OUTPUT_OPENED 0x02
-#define MTPAV_MODE_INPUT_TRIGGERED 0x04
-#define MTPAV_MODE_OUTPUT_TRIGGERED 0x08
-
-#define NUMPORTS (0x12+1)
-
-
-/*
- */
-
-struct mtpav_port {
- u8 number;
- u8 hwport;
- u8 mode;
- u8 running_status;
- struct snd_rawmidi_substream *input;
- struct snd_rawmidi_substream *output;
-};
-
-struct mtpav {
- struct snd_card *card;
- unsigned long port;
- struct resource *res_port;
- int irq; /* interrupt (for inputs) */
- spinlock_t spinlock;
- int share_irq; /* number of accesses to input interrupts */
- int istimer; /* number of accesses to timer interrupts */
- struct timer_list timer; /* timer interrupts for outputs */
- struct snd_rawmidi *rmidi;
- int num_ports; /* number of hw ports (1-8) */
- struct mtpav_port ports[NUMPORTS]; /* all ports including computer, adat and bc */
-
- u32 inmidiport; /* selected input midi port */
- u32 inmidistate; /* during midi command 0xf5 */
-
- u32 outmidihwport; /* selected output midi hw port */
-};
-
-
-/*
- * possible hardware ports (selected by 0xf5 port message)
- * 0x00 all ports
- * 0x01 .. 0x08 this MTP's ports 1..8
- * 0x09 .. 0x10 networked MTP's ports (9..16)
- * 0x11 networked MTP's computer port
- * 0x63 to ADAT
- *
- * mappig:
- * subdevice 0 - (X-1) ports
- * X - (2*X-1) networked ports
- * X computer
- * X+1 ADAT
- * X+2 all ports
- *
- * where X = chip->num_ports
- */
-
-#define MTPAV_PIDX_COMPUTER 0
-#define MTPAV_PIDX_ADAT 1
-#define MTPAV_PIDX_BROADCAST 2
-
-
-static int translate_subdevice_to_hwport(struct mtpav *chip, int subdev)
-{
- if (subdev < 0)
- return 0x01; /* invalid - use port 0 as default */
- else if (subdev < chip->num_ports)
- return subdev + 1; /* single mtp port */
- else if (subdev < chip->num_ports * 2)
- return subdev - chip->num_ports + 0x09; /* remote port */
- else if (subdev == chip->num_ports * 2 + MTPAV_PIDX_COMPUTER)
- return 0x11; /* computer port */
- else if (subdev == chip->num_ports + MTPAV_PIDX_ADAT)
- return 0x63; /* ADAT */
- return 0; /* all ports */
-}
-
-static int translate_hwport_to_subdevice(struct mtpav *chip, int hwport)
-{
- int p;
- if (hwport <= 0x00) /* all ports */
- return chip->num_ports + MTPAV_PIDX_BROADCAST;
- else if (hwport <= 0x08) { /* single port */
- p = hwport - 1;
- if (p >= chip->num_ports)
- p = 0;
- return p;
- } else if (hwport <= 0x10) { /* remote port */
- p = hwport - 0x09 + chip->num_ports;
- if (p >= chip->num_ports * 2)
- p = chip->num_ports;
- return p;
- } else if (hwport == 0x11) /* computer port */
- return chip->num_ports + MTPAV_PIDX_COMPUTER;
- else /* ADAT */
- return chip->num_ports + MTPAV_PIDX_ADAT;
-}
-
-
-/*
- */
-
-static u8 snd_mtpav_getreg(struct mtpav *chip, u16 reg)
-{
- u8 rval = 0;
-
- if (reg == SREG) {
- rval = inb(chip->port + SREG);
- rval = (rval & 0xf8);
- } else if (reg == CREG) {
- rval = inb(chip->port + CREG);
- rval = (rval & 0x1c);
- }
-
- return rval;
-}
-
-/*
- */
-
-static inline void snd_mtpav_mputreg(struct mtpav *chip, u16 reg, u8 val)
-{
- if (reg == DREG || reg == CREG)
- outb(val, chip->port + reg);
-}
-
-/*
- */
-
-static void snd_mtpav_wait_rfdhi(struct mtpav *chip)
-{
- int counts = 10000;
- u8 sbyte;
-
- sbyte = snd_mtpav_getreg(chip, SREG);
- while (!(sbyte & SIGS_RFD) && counts--) {
- sbyte = snd_mtpav_getreg(chip, SREG);
- udelay(10);
- }
-}
-
-static void snd_mtpav_send_byte(struct mtpav *chip, u8 byte)
-{
- u8 tcbyt;
- u8 clrwrite;
- u8 setwrite;
-
- snd_mtpav_wait_rfdhi(chip);
-
- /////////////////
-
- tcbyt = snd_mtpav_getreg(chip, CREG);
- clrwrite = tcbyt & (SIGC_WRITE ^ 0xff);
- setwrite = tcbyt | SIGC_WRITE;
-
- snd_mtpav_mputreg(chip, DREG, byte);
- snd_mtpav_mputreg(chip, CREG, clrwrite); // clear write bit
-
- snd_mtpav_mputreg(chip, CREG, setwrite); // set write bit
-
-}
-
-
-/*
- */
-
-/* call this with spin lock held */
-static void snd_mtpav_output_port_write(struct mtpav *mtp_card,
- struct mtpav_port *portp,
- struct snd_rawmidi_substream *substream)
-{
- u8 outbyte;
-
- // Get the outbyte first, so we can emulate running status if
- // necessary
- if (snd_rawmidi_transmit(substream, &outbyte, 1) != 1)
- return;
-
- // send port change command if necessary
-
- if (portp->hwport != mtp_card->outmidihwport) {
- mtp_card->outmidihwport = portp->hwport;
-
- snd_mtpav_send_byte(mtp_card, 0xf5);
- snd_mtpav_send_byte(mtp_card, portp->hwport);
- /*
- snd_printk(KERN_DEBUG "new outport: 0x%x\n",
- (unsigned int) portp->hwport);
- */
- if (!(outbyte & 0x80) && portp->running_status)
- snd_mtpav_send_byte(mtp_card, portp->running_status);
- }
-
- // send data
-
- do {
- if (outbyte & 0x80)
- portp->running_status = outbyte;
-
- snd_mtpav_send_byte(mtp_card, outbyte);
- } while (snd_rawmidi_transmit(substream, &outbyte, 1) == 1);
-}
-
-static void snd_mtpav_output_write(struct snd_rawmidi_substream *substream)
-{
- struct mtpav *mtp_card = substream->rmidi->private_data;
- struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
-
- spin_lock_irqsave(&mtp_card->spinlock, flags);
- snd_mtpav_output_port_write(mtp_card, portp, substream);
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
-}
-
-
-/*
- * mtpav control
- */
-
-static void snd_mtpav_portscan(struct mtpav *chip) // put mtp into smart routing mode
-{
- u8 p;
-
- for (p = 0; p < 8; p++) {
- snd_mtpav_send_byte(chip, 0xf5);
- snd_mtpav_send_byte(chip, p);
- snd_mtpav_send_byte(chip, 0xfe);
- }
-}
-
-/*
- */
-
-static int snd_mtpav_input_open(struct snd_rawmidi_substream *substream)
-{
- struct mtpav *mtp_card = substream->rmidi->private_data;
- struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
-
- spin_lock_irqsave(&mtp_card->spinlock, flags);
- portp->mode |= MTPAV_MODE_INPUT_OPENED;
- portp->input = substream;
- if (mtp_card->share_irq++ == 0)
- snd_mtpav_mputreg(mtp_card, CREG, (SIGC_INTEN | SIGC_WRITE)); // enable pport interrupts
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
- return 0;
-}
-
-/*
- */
-
-static int snd_mtpav_input_close(struct snd_rawmidi_substream *substream)
-{
- struct mtpav *mtp_card = substream->rmidi->private_data;
- struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
-
- spin_lock_irqsave(&mtp_card->spinlock, flags);
- portp->mode &= ~MTPAV_MODE_INPUT_OPENED;
- portp->input = NULL;
- if (--mtp_card->share_irq == 0)
- snd_mtpav_mputreg(mtp_card, CREG, 0); // disable pport interrupts
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
- return 0;
-}
-
-/*
- */
-
-static void snd_mtpav_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct mtpav *mtp_card = substream->rmidi->private_data;
- struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
-
- spin_lock_irqsave(&mtp_card->spinlock, flags);
- if (up)
- portp->mode |= MTPAV_MODE_INPUT_TRIGGERED;
- else
- portp->mode &= ~MTPAV_MODE_INPUT_TRIGGERED;
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
-
-}
-
-
-/*
- * timer interrupt for outputs
- */
-
-static void snd_mtpav_output_timer(unsigned long data)
-{
- unsigned long flags;
- struct mtpav *chip = (struct mtpav *)data;
- int p;
-
- spin_lock_irqsave(&chip->spinlock, flags);
- /* reprogram timer */
- chip->timer.expires = 1 + jiffies;
- add_timer(&chip->timer);
- /* process each port */
- for (p = 0; p <= chip->num_ports * 2 + MTPAV_PIDX_BROADCAST; p++) {
- struct mtpav_port *portp = &chip->ports[p];
- if ((portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED) && portp->output)
- snd_mtpav_output_port_write(chip, portp, portp->output);
- }
- spin_unlock_irqrestore(&chip->spinlock, flags);
-}
-
-/* spinlock held! */
-static void snd_mtpav_add_output_timer(struct mtpav *chip)
-{
- chip->timer.expires = 1 + jiffies;
- add_timer(&chip->timer);
-}
-
-/* spinlock held! */
-static void snd_mtpav_remove_output_timer(struct mtpav *chip)
-{
- del_timer(&chip->timer);
-}
-
-/*
- */
-
-static int snd_mtpav_output_open(struct snd_rawmidi_substream *substream)
-{
- struct mtpav *mtp_card = substream->rmidi->private_data;
- struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
-
- spin_lock_irqsave(&mtp_card->spinlock, flags);
- portp->mode |= MTPAV_MODE_OUTPUT_OPENED;
- portp->output = substream;
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
- return 0;
-};
-
-/*
- */
-
-static int snd_mtpav_output_close(struct snd_rawmidi_substream *substream)
-{
- struct mtpav *mtp_card = substream->rmidi->private_data;
- struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
-
- spin_lock_irqsave(&mtp_card->spinlock, flags);
- portp->mode &= ~MTPAV_MODE_OUTPUT_OPENED;
- portp->output = NULL;
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
- return 0;
-};
-
-/*
- */
-
-static void snd_mtpav_output_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct mtpav *mtp_card = substream->rmidi->private_data;
- struct mtpav_port *portp = &mtp_card->ports[substream->number];
- unsigned long flags;
-
- spin_lock_irqsave(&mtp_card->spinlock, flags);
- if (up) {
- if (! (portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED)) {
- if (mtp_card->istimer++ == 0)
- snd_mtpav_add_output_timer(mtp_card);
- portp->mode |= MTPAV_MODE_OUTPUT_TRIGGERED;
- }
- } else {
- portp->mode &= ~MTPAV_MODE_OUTPUT_TRIGGERED;
- if (--mtp_card->istimer == 0)
- snd_mtpav_remove_output_timer(mtp_card);
- }
- spin_unlock_irqrestore(&mtp_card->spinlock, flags);
-
- if (up)
- snd_mtpav_output_write(substream);
-}
-
-/*
- * midi interrupt for inputs
- */
-
-static void snd_mtpav_inmidi_process(struct mtpav *mcrd, u8 inbyte)
-{
- struct mtpav_port *portp;
-
- if ((int)mcrd->inmidiport > mcrd->num_ports * 2 + MTPAV_PIDX_BROADCAST)
- return;
-
- portp = &mcrd->ports[mcrd->inmidiport];
- if (portp->mode & MTPAV_MODE_INPUT_TRIGGERED)
- snd_rawmidi_receive(portp->input, &inbyte, 1);
-}
-
-static void snd_mtpav_inmidi_h(struct mtpav *mcrd, u8 inbyte)
-{
- if (inbyte >= 0xf8) {
- /* real-time midi code */
- snd_mtpav_inmidi_process(mcrd, inbyte);
- return;
- }
-
- if (mcrd->inmidistate == 0) { // awaiting command
- if (inbyte == 0xf5) // MTP port #
- mcrd->inmidistate = 1;
- else
- snd_mtpav_inmidi_process(mcrd, inbyte);
- } else if (mcrd->inmidistate) {
- mcrd->inmidiport = translate_hwport_to_subdevice(mcrd, inbyte);
- mcrd->inmidistate = 0;
- }
-}
-
-static void snd_mtpav_read_bytes(struct mtpav *mcrd)
-{
- u8 clrread, setread;
- u8 mtp_read_byte;
- u8 sr, cbyt;
- int i;
-
- u8 sbyt = snd_mtpav_getreg(mcrd, SREG);
-
- /* printk(KERN_DEBUG "snd_mtpav_read_bytes() sbyt: 0x%x\n", sbyt); */
-
- if (!(sbyt & SIGS_BYTE))
- return;
-
- cbyt = snd_mtpav_getreg(mcrd, CREG);
- clrread = cbyt & (SIGC_READ ^ 0xff);
- setread = cbyt | SIGC_READ;
-
- do {
-
- mtp_read_byte = 0;
- for (i = 0; i < 4; i++) {
- snd_mtpav_mputreg(mcrd, CREG, setread);
- sr = snd_mtpav_getreg(mcrd, SREG);
- snd_mtpav_mputreg(mcrd, CREG, clrread);
-
- sr &= SIGS_IN0 | SIGS_IN1;
- sr >>= 4;
- mtp_read_byte |= sr << (i * 2);
- }
-
- snd_mtpav_inmidi_h(mcrd, mtp_read_byte);
-
- sbyt = snd_mtpav_getreg(mcrd, SREG);
-
- } while (sbyt & SIGS_BYTE);
-}
-
-static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id)
-{
- struct mtpav *mcard = dev_id;
-
- spin_lock(&mcard->spinlock);
- snd_mtpav_read_bytes(mcard);
- spin_unlock(&mcard->spinlock);
- return IRQ_HANDLED;
-}
-
-/*
- * get ISA resources
- */
-static int __devinit snd_mtpav_get_ISA(struct mtpav * mcard)
-{
- if ((mcard->res_port = request_region(port, 3, "MotuMTPAV MIDI")) == NULL) {
- snd_printk(KERN_ERR "MTVAP port 0x%lx is busy\n", port);
- return -EBUSY;
- }
- mcard->port = port;
- if (request_irq(irq, snd_mtpav_irqh, 0, "MOTU MTPAV", mcard)) {
- snd_printk(KERN_ERR "MTVAP IRQ %d busy\n", irq);
- return -EBUSY;
- }
- mcard->irq = irq;
- return 0;
-}
-
-
-/*
- */
-
-static struct snd_rawmidi_ops snd_mtpav_output = {
- .open = snd_mtpav_output_open,
- .close = snd_mtpav_output_close,
- .trigger = snd_mtpav_output_trigger,
-};
-
-static struct snd_rawmidi_ops snd_mtpav_input = {
- .open = snd_mtpav_input_open,
- .close = snd_mtpav_input_close,
- .trigger = snd_mtpav_input_trigger,
-};
-
-
-/*
- * get RAWMIDI resources
- */
-
-static void __devinit snd_mtpav_set_name(struct mtpav *chip,
- struct snd_rawmidi_substream *substream)
-{
- if (substream->number >= 0 && substream->number < chip->num_ports)
- sprintf(substream->name, "MTP direct %d", (substream->number % chip->num_ports) + 1);
- else if (substream->number >= 8 && substream->number < chip->num_ports * 2)
- sprintf(substream->name, "MTP remote %d", (substream->number % chip->num_ports) + 1);
- else if (substream->number == chip->num_ports * 2)
- strcpy(substream->name, "MTP computer");
- else if (substream->number == chip->num_ports * 2 + 1)
- strcpy(substream->name, "MTP ADAT");
- else
- strcpy(substream->name, "MTP broadcast");
-}
-
-static int __devinit snd_mtpav_get_RAWMIDI(struct mtpav *mcard)
-{
- int rval;
- struct snd_rawmidi *rawmidi;
- struct snd_rawmidi_substream *substream;
- struct list_head *list;
-
- if (hwports < 1)
- hwports = 1;
- else if (hwports > 8)
- hwports = 8;
- mcard->num_ports = hwports;
-
- if ((rval = snd_rawmidi_new(mcard->card, "MotuMIDI", 0,
- mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1,
- mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1,
- &mcard->rmidi)) < 0)
- return rval;
- rawmidi = mcard->rmidi;
- rawmidi->private_data = mcard;
-
- list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) {
- substream = list_entry(list, struct snd_rawmidi_substream, list);
- snd_mtpav_set_name(mcard, substream);
- substream->ops = &snd_mtpav_input;
- }
- list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
- substream = list_entry(list, struct snd_rawmidi_substream, list);
- snd_mtpav_set_name(mcard, substream);
- substream->ops = &snd_mtpav_output;
- mcard->ports[substream->number].hwport = translate_subdevice_to_hwport(mcard, substream->number);
- }
- rawmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
- sprintf(rawmidi->name, "MTP AV MIDI");
- return 0;
-}
-
-/*
- */
-
-static void snd_mtpav_free(struct snd_card *card)
-{
- struct mtpav *crd = card->private_data;
- unsigned long flags;
-
- spin_lock_irqsave(&crd->spinlock, flags);
- if (crd->istimer > 0)
- snd_mtpav_remove_output_timer(crd);
- spin_unlock_irqrestore(&crd->spinlock, flags);
- if (crd->irq >= 0)
- free_irq(crd->irq, (void *)crd);
- release_and_free_resource(crd->res_port);
-}
-
-/*
- */
-static int __devinit snd_mtpav_probe(struct platform_device *dev)
-{
- struct snd_card *card;
- int err;
- struct mtpav *mtp_card;
-
- err = snd_card_create(index, id, THIS_MODULE, sizeof(*mtp_card), &card);
- if (err < 0)
- return err;
-
- mtp_card = card->private_data;
- spin_lock_init(&mtp_card->spinlock);
- init_timer(&mtp_card->timer);
- mtp_card->card = card;
- mtp_card->irq = -1;
- mtp_card->share_irq = 0;
- mtp_card->inmidistate = 0;
- mtp_card->outmidihwport = 0xffffffff;
- init_timer(&mtp_card->timer);
- mtp_card->timer.function = snd_mtpav_output_timer;
- mtp_card->timer.data = (unsigned long) mtp_card;
-
- card->private_free = snd_mtpav_free;
-
- err = snd_mtpav_get_RAWMIDI(mtp_card);
- if (err < 0)
- goto __error;
-
- mtp_card->inmidiport = mtp_card->num_ports + MTPAV_PIDX_BROADCAST;
-
- err = snd_mtpav_get_ISA(mtp_card);
- if (err < 0)
- goto __error;
-
- strcpy(card->driver, "MTPAV");
- strcpy(card->shortname, "MTPAV on parallel port");
- snprintf(card->longname, sizeof(card->longname),
- "MTPAV on parallel port at 0x%lx", port);
-
- snd_mtpav_portscan(mtp_card);
-
- snd_card_set_dev(card, &dev->dev);
- err = snd_card_register(mtp_card->card);
- if (err < 0)
- goto __error;
-
- platform_set_drvdata(dev, card);
- printk(KERN_INFO "Motu MidiTimePiece on parallel port irq: %d ioport: 0x%lx\n", irq, port);
- return 0;
-
- __error:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit snd_mtpav_remove(struct platform_device *devptr)
-{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
- return 0;
-}
-
-#define SND_MTPAV_DRIVER "snd_mtpav"
-
-static struct platform_driver snd_mtpav_driver = {
- .probe = snd_mtpav_probe,
- .remove = __devexit_p(snd_mtpav_remove),
- .driver = {
- .name = SND_MTPAV_DRIVER
- },
-};
-
-static int __init alsa_card_mtpav_init(void)
-{
- int err;
-
- if ((err = platform_driver_register(&snd_mtpav_driver)) < 0)
- return err;
-
- device = platform_device_register_simple(SND_MTPAV_DRIVER, -1, NULL, 0);
- if (!IS_ERR(device)) {
- if (platform_get_drvdata(device))
- return 0;
- platform_device_unregister(device);
- err = -ENODEV;
- } else
- err = PTR_ERR(device);
- platform_driver_unregister(&snd_mtpav_driver);
- return err;
-}
-
-static void __exit alsa_card_mtpav_exit(void)
-{
- platform_device_unregister(device);
- platform_driver_unregister(&snd_mtpav_driver);
-}
-
-module_init(alsa_card_mtpav_init)
-module_exit(alsa_card_mtpav_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/mts64.c b/ANDROID_3.4.5/sound/drivers/mts64.c
deleted file mode 100644
index 621e60e2..00000000
--- a/ANDROID_3.4.5/sound/drivers/mts64.c
+++ /dev/null
@@ -1,1090 +0,0 @@
-/*
- * ALSA Driver for Ego Systems Inc. (ESI) Miditerminal 4140
- * Copyright (c) 2006 by Matthias König <mk@phasorlab.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/parport.h>
-#include <linux/spinlock.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/rawmidi.h>
-#include <sound/control.h>
-
-#define CARD_NAME "Miditerminal 4140"
-#define DRIVER_NAME "MTS64"
-#define PLATFORM_DRIVER "snd_mts64"
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-static struct platform_device *platform_devices[SNDRV_CARDS];
-static int device_count;
-
-module_param_array(index, int, NULL, S_IRUGO);
-MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
-module_param_array(id, charp, NULL, S_IRUGO);
-MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, S_IRUGO);
-MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
-
-MODULE_AUTHOR("Matthias Koenig <mk@phasorlab.de>");
-MODULE_DESCRIPTION("ESI Miditerminal 4140");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ESI,Miditerminal 4140}}");
-
-/*********************************************************************
- * Chip specific
- *********************************************************************/
-#define MTS64_NUM_INPUT_PORTS 5
-#define MTS64_NUM_OUTPUT_PORTS 4
-#define MTS64_SMPTE_SUBSTREAM 4
-
-struct mts64 {
- spinlock_t lock;
- struct snd_card *card;
- struct snd_rawmidi *rmidi;
- struct pardevice *pardev;
- int pardev_claimed;
-
- int open_count;
- int current_midi_output_port;
- int current_midi_input_port;
- u8 mode[MTS64_NUM_INPUT_PORTS];
- struct snd_rawmidi_substream *midi_input_substream[MTS64_NUM_INPUT_PORTS];
- int smpte_switch;
- u8 time[4]; /* [0]=hh, [1]=mm, [2]=ss, [3]=ff */
- u8 fps;
-};
-
-static int snd_mts64_free(struct mts64 *mts)
-{
- kfree(mts);
- return 0;
-}
-
-static int __devinit snd_mts64_create(struct snd_card *card,
- struct pardevice *pardev,
- struct mts64 **rchip)
-{
- struct mts64 *mts;
-
- *rchip = NULL;
-
- mts = kzalloc(sizeof(struct mts64), GFP_KERNEL);
- if (mts == NULL)
- return -ENOMEM;
-
- /* Init chip specific data */
- spin_lock_init(&mts->lock);
- mts->card = card;
- mts->pardev = pardev;
- mts->current_midi_output_port = -1;
- mts->current_midi_input_port = -1;
-
- *rchip = mts;
-
- return 0;
-}
-
-/*********************************************************************
- * HW register related constants
- *********************************************************************/
-
-/* Status Bits */
-#define MTS64_STAT_BSY 0x80
-#define MTS64_STAT_BIT_SET 0x20 /* readout process, bit is set */
-#define MTS64_STAT_PORT 0x10 /* read byte is a port number */
-
-/* Control Bits */
-#define MTS64_CTL_READOUT 0x08 /* enable readout */
-#define MTS64_CTL_WRITE_CMD 0x06
-#define MTS64_CTL_WRITE_DATA 0x02
-#define MTS64_CTL_STROBE 0x01
-
-/* Command */
-#define MTS64_CMD_RESET 0xfe
-#define MTS64_CMD_PROBE 0x8f /* Used in probing procedure */
-#define MTS64_CMD_SMPTE_SET_TIME 0xe8
-#define MTS64_CMD_SMPTE_SET_FPS 0xee
-#define MTS64_CMD_SMPTE_STOP 0xef
-#define MTS64_CMD_SMPTE_FPS_24 0xe3
-#define MTS64_CMD_SMPTE_FPS_25 0xe2
-#define MTS64_CMD_SMPTE_FPS_2997 0xe4
-#define MTS64_CMD_SMPTE_FPS_30D 0xe1
-#define MTS64_CMD_SMPTE_FPS_30 0xe0
-#define MTS64_CMD_COM_OPEN 0xf8 /* setting the communication mode */
-#define MTS64_CMD_COM_CLOSE1 0xff /* clearing communication mode */
-#define MTS64_CMD_COM_CLOSE2 0xf5
-
-/*********************************************************************
- * Hardware specific functions
- *********************************************************************/
-static void mts64_enable_readout(struct parport *p);
-static void mts64_disable_readout(struct parport *p);
-static int mts64_device_ready(struct parport *p);
-static int mts64_device_init(struct parport *p);
-static int mts64_device_open(struct mts64 *mts);
-static int mts64_device_close(struct mts64 *mts);
-static u8 mts64_map_midi_input(u8 c);
-static int mts64_probe(struct parport *p);
-static u16 mts64_read(struct parport *p);
-static u8 mts64_read_char(struct parport *p);
-static void mts64_smpte_start(struct parport *p,
- u8 hours, u8 minutes,
- u8 seconds, u8 frames,
- u8 idx);
-static void mts64_smpte_stop(struct parport *p);
-static void mts64_write_command(struct parport *p, u8 c);
-static void mts64_write_data(struct parport *p, u8 c);
-static void mts64_write_midi(struct mts64 *mts, u8 c, int midiport);
-
-
-/* Enables the readout procedure
- *
- * Before we can read a midi byte from the device, we have to set
- * bit 3 of control port.
- */
-static void mts64_enable_readout(struct parport *p)
-{
- u8 c;
-
- c = parport_read_control(p);
- c |= MTS64_CTL_READOUT;
- parport_write_control(p, c);
-}
-
-/* Disables readout
- *
- * Readout is disabled by clearing bit 3 of control
- */
-static void mts64_disable_readout(struct parport *p)
-{
- u8 c;
-
- c = parport_read_control(p);
- c &= ~MTS64_CTL_READOUT;
- parport_write_control(p, c);
-}
-
-/* waits for device ready
- *
- * Checks if BUSY (Bit 7 of status) is clear
- * 1 device ready
- * 0 failure
- */
-static int mts64_device_ready(struct parport *p)
-{
- int i;
- u8 c;
-
- for (i = 0; i < 0xffff; ++i) {
- c = parport_read_status(p);
- c &= MTS64_STAT_BSY;
- if (c != 0)
- return 1;
- }
-
- return 0;
-}
-
-/* Init device (LED blinking startup magic)
- *
- * Returns:
- * 0 init ok
- * -EIO failure
- */
-static int __devinit mts64_device_init(struct parport *p)
-{
- int i;
-
- mts64_write_command(p, MTS64_CMD_RESET);
-
- for (i = 0; i < 64; ++i) {
- msleep(100);
-
- if (mts64_probe(p) == 0) {
- /* success */
- mts64_disable_readout(p);
- return 0;
- }
- }
- mts64_disable_readout(p);
-
- return -EIO;
-}
-
-/*
- * Opens the device (set communication mode)
- */
-static int mts64_device_open(struct mts64 *mts)
-{
- int i;
- struct parport *p = mts->pardev->port;
-
- for (i = 0; i < 5; ++i)
- mts64_write_command(p, MTS64_CMD_COM_OPEN);
-
- return 0;
-}
-
-/*
- * Close device (clear communication mode)
- */
-static int mts64_device_close(struct mts64 *mts)
-{
- int i;
- struct parport *p = mts->pardev->port;
-
- for (i = 0; i < 5; ++i) {
- mts64_write_command(p, MTS64_CMD_COM_CLOSE1);
- mts64_write_command(p, MTS64_CMD_COM_CLOSE2);
- }
-
- return 0;
-}
-
-/* map hardware port to substream number
- *
- * When reading a byte from the device, the device tells us
- * on what port the byte is. This HW port has to be mapped to
- * the midiport (substream number).
- * substream 0-3 are Midiports 1-4
- * substream 4 is SMPTE Timecode
- * The mapping is done by the table:
- * HW | 0 | 1 | 2 | 3 | 4
- * SW | 0 | 1 | 4 | 2 | 3
- */
-static u8 mts64_map_midi_input(u8 c)
-{
- static u8 map[] = { 0, 1, 4, 2, 3 };
-
- return map[c];
-}
-
-
-/* Probe parport for device
- *
- * Do we have a Miditerminal 4140 on parport?
- * Returns:
- * 0 device found
- * -ENODEV no device
- */
-static int __devinit mts64_probe(struct parport *p)
-{
- u8 c;
-
- mts64_smpte_stop(p);
- mts64_write_command(p, MTS64_CMD_PROBE);
-
- msleep(50);
-
- c = mts64_read(p);
-
- c &= 0x00ff;
- if (c != MTS64_CMD_PROBE)
- return -ENODEV;
- else
- return 0;
-
-}
-
-/* Read byte incl. status from device
- *
- * Returns:
- * data in lower 8 bits and status in upper 8 bits
- */
-static u16 mts64_read(struct parport *p)
-{
- u8 data, status;
-
- mts64_device_ready(p);
- mts64_enable_readout(p);
- status = parport_read_status(p);
- data = mts64_read_char(p);
- mts64_disable_readout(p);
-
- return (status << 8) | data;
-}
-
-/* Read a byte from device
- *
- * Note, that readout mode has to be enabled.
- * readout procedure is as follows:
- * - Write number of the Bit to read to DATA
- * - Read STATUS
- * - Bit 5 of STATUS indicates if Bit is set
- *
- * Returns:
- * Byte read from device
- */
-static u8 mts64_read_char(struct parport *p)
-{
- u8 c = 0;
- u8 status;
- u8 i;
-
- for (i = 0; i < 8; ++i) {
- parport_write_data(p, i);
- c >>= 1;
- status = parport_read_status(p);
- if (status & MTS64_STAT_BIT_SET)
- c |= 0x80;
- }
-
- return c;
-}
-
-/* Starts SMPTE Timecode generation
- *
- * The device creates SMPTE Timecode by hardware.
- * 0 24 fps
- * 1 25 fps
- * 2 29.97 fps
- * 3 30 fps (Drop-frame)
- * 4 30 fps
- */
-static void mts64_smpte_start(struct parport *p,
- u8 hours, u8 minutes,
- u8 seconds, u8 frames,
- u8 idx)
-{
- static u8 fps[5] = { MTS64_CMD_SMPTE_FPS_24,
- MTS64_CMD_SMPTE_FPS_25,
- MTS64_CMD_SMPTE_FPS_2997,
- MTS64_CMD_SMPTE_FPS_30D,
- MTS64_CMD_SMPTE_FPS_30 };
-
- mts64_write_command(p, MTS64_CMD_SMPTE_SET_TIME);
- mts64_write_command(p, frames);
- mts64_write_command(p, seconds);
- mts64_write_command(p, minutes);
- mts64_write_command(p, hours);
-
- mts64_write_command(p, MTS64_CMD_SMPTE_SET_FPS);
- mts64_write_command(p, fps[idx]);
-}
-
-/* Stops SMPTE Timecode generation
- */
-static void mts64_smpte_stop(struct parport *p)
-{
- mts64_write_command(p, MTS64_CMD_SMPTE_STOP);
-}
-
-/* Write a command byte to device
- */
-static void mts64_write_command(struct parport *p, u8 c)
-{
- mts64_device_ready(p);
-
- parport_write_data(p, c);
-
- parport_write_control(p, MTS64_CTL_WRITE_CMD);
- parport_write_control(p, MTS64_CTL_WRITE_CMD | MTS64_CTL_STROBE);
- parport_write_control(p, MTS64_CTL_WRITE_CMD);
-}
-
-/* Write a data byte to device
- */
-static void mts64_write_data(struct parport *p, u8 c)
-{
- mts64_device_ready(p);
-
- parport_write_data(p, c);
-
- parport_write_control(p, MTS64_CTL_WRITE_DATA);
- parport_write_control(p, MTS64_CTL_WRITE_DATA | MTS64_CTL_STROBE);
- parport_write_control(p, MTS64_CTL_WRITE_DATA);
-}
-
-/* Write a MIDI byte to midiport
- *
- * midiport ranges from 0-3 and maps to Ports 1-4
- * assumptions: communication mode is on
- */
-static void mts64_write_midi(struct mts64 *mts, u8 c,
- int midiport)
-{
- struct parport *p = mts->pardev->port;
-
- /* check current midiport */
- if (mts->current_midi_output_port != midiport)
- mts64_write_command(p, midiport);
-
- /* write midi byte */
- mts64_write_data(p, c);
-}
-
-/*********************************************************************
- * Control elements
- *********************************************************************/
-
-/* SMPTE Switch */
-#define snd_mts64_ctl_smpte_switch_info snd_ctl_boolean_mono_info
-
-static int snd_mts64_ctl_smpte_switch_get(struct snd_kcontrol* kctl,
- struct snd_ctl_elem_value *uctl)
-{
- struct mts64 *mts = snd_kcontrol_chip(kctl);
-
- spin_lock_irq(&mts->lock);
- uctl->value.integer.value[0] = mts->smpte_switch;
- spin_unlock_irq(&mts->lock);
-
- return 0;
-}
-
-/* smpte_switch is not accessed from IRQ handler, so we just need
- to protect the HW access */
-static int snd_mts64_ctl_smpte_switch_put(struct snd_kcontrol* kctl,
- struct snd_ctl_elem_value *uctl)
-{
- struct mts64 *mts = snd_kcontrol_chip(kctl);
- int changed = 0;
- int val = !!uctl->value.integer.value[0];
-
- spin_lock_irq(&mts->lock);
- if (mts->smpte_switch == val)
- goto __out;
-
- changed = 1;
- mts->smpte_switch = val;
- if (mts->smpte_switch) {
- mts64_smpte_start(mts->pardev->port,
- mts->time[0], mts->time[1],
- mts->time[2], mts->time[3],
- mts->fps);
- } else {
- mts64_smpte_stop(mts->pardev->port);
- }
-__out:
- spin_unlock_irq(&mts->lock);
- return changed;
-}
-
-static struct snd_kcontrol_new mts64_ctl_smpte_switch __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
- .name = "SMPTE Playback Switch",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = 0,
- .info = snd_mts64_ctl_smpte_switch_info,
- .get = snd_mts64_ctl_smpte_switch_get,
- .put = snd_mts64_ctl_smpte_switch_put
-};
-
-/* Time */
-static int snd_mts64_ctl_smpte_time_h_info(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 23;
- return 0;
-}
-
-static int snd_mts64_ctl_smpte_time_f_info(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 99;
- return 0;
-}
-
-static int snd_mts64_ctl_smpte_time_info(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 59;
- return 0;
-}
-
-static int snd_mts64_ctl_smpte_time_get(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_value *uctl)
-{
- struct mts64 *mts = snd_kcontrol_chip(kctl);
- int idx = kctl->private_value;
-
- spin_lock_irq(&mts->lock);
- uctl->value.integer.value[0] = mts->time[idx];
- spin_unlock_irq(&mts->lock);
-
- return 0;
-}
-
-static int snd_mts64_ctl_smpte_time_put(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_value *uctl)
-{
- struct mts64 *mts = snd_kcontrol_chip(kctl);
- int idx = kctl->private_value;
- unsigned int time = uctl->value.integer.value[0] % 60;
- int changed = 0;
-
- spin_lock_irq(&mts->lock);
- if (mts->time[idx] != time) {
- changed = 1;
- mts->time[idx] = time;
- }
- spin_unlock_irq(&mts->lock);
-
- return changed;
-}
-
-static struct snd_kcontrol_new mts64_ctl_smpte_time_hours __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
- .name = "SMPTE Time Hours",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = 0,
- .info = snd_mts64_ctl_smpte_time_h_info,
- .get = snd_mts64_ctl_smpte_time_get,
- .put = snd_mts64_ctl_smpte_time_put
-};
-
-static struct snd_kcontrol_new mts64_ctl_smpte_time_minutes __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
- .name = "SMPTE Time Minutes",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = 1,
- .info = snd_mts64_ctl_smpte_time_info,
- .get = snd_mts64_ctl_smpte_time_get,
- .put = snd_mts64_ctl_smpte_time_put
-};
-
-static struct snd_kcontrol_new mts64_ctl_smpte_time_seconds __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
- .name = "SMPTE Time Seconds",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = 2,
- .info = snd_mts64_ctl_smpte_time_info,
- .get = snd_mts64_ctl_smpte_time_get,
- .put = snd_mts64_ctl_smpte_time_put
-};
-
-static struct snd_kcontrol_new mts64_ctl_smpte_time_frames __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
- .name = "SMPTE Time Frames",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = 3,
- .info = snd_mts64_ctl_smpte_time_f_info,
- .get = snd_mts64_ctl_smpte_time_get,
- .put = snd_mts64_ctl_smpte_time_put
-};
-
-/* FPS */
-static int snd_mts64_ctl_smpte_fps_info(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[5] = { "24",
- "25",
- "29.97",
- "30D",
- "30" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 5;
- if (uinfo->value.enumerated.item > 4)
- uinfo->value.enumerated.item = 4;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-static int snd_mts64_ctl_smpte_fps_get(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_value *uctl)
-{
- struct mts64 *mts = snd_kcontrol_chip(kctl);
-
- spin_lock_irq(&mts->lock);
- uctl->value.enumerated.item[0] = mts->fps;
- spin_unlock_irq(&mts->lock);
-
- return 0;
-}
-
-static int snd_mts64_ctl_smpte_fps_put(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_value *uctl)
-{
- struct mts64 *mts = snd_kcontrol_chip(kctl);
- int changed = 0;
-
- if (uctl->value.enumerated.item[0] >= 5)
- return -EINVAL;
- spin_lock_irq(&mts->lock);
- if (mts->fps != uctl->value.enumerated.item[0]) {
- changed = 1;
- mts->fps = uctl->value.enumerated.item[0];
- }
- spin_unlock_irq(&mts->lock);
-
- return changed;
-}
-
-static struct snd_kcontrol_new mts64_ctl_smpte_fps __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
- .name = "SMPTE Fps",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = 0,
- .info = snd_mts64_ctl_smpte_fps_info,
- .get = snd_mts64_ctl_smpte_fps_get,
- .put = snd_mts64_ctl_smpte_fps_put
-};
-
-
-static int __devinit snd_mts64_ctl_create(struct snd_card *card,
- struct mts64 *mts)
-{
- int err, i;
- static struct snd_kcontrol_new *control[] __devinitdata = {
- &mts64_ctl_smpte_switch,
- &mts64_ctl_smpte_time_hours,
- &mts64_ctl_smpte_time_minutes,
- &mts64_ctl_smpte_time_seconds,
- &mts64_ctl_smpte_time_frames,
- &mts64_ctl_smpte_fps,
- NULL };
-
- for (i = 0; control[i]; ++i) {
- err = snd_ctl_add(card, snd_ctl_new1(control[i], mts));
- if (err < 0) {
- snd_printd("Cannot create control: %s\n",
- control[i]->name);
- return err;
- }
- }
-
- return 0;
-}
-
-/*********************************************************************
- * Rawmidi
- *********************************************************************/
-#define MTS64_MODE_INPUT_TRIGGERED 0x01
-
-static int snd_mts64_rawmidi_open(struct snd_rawmidi_substream *substream)
-{
- struct mts64 *mts = substream->rmidi->private_data;
-
- if (mts->open_count == 0) {
- /* We don't need a spinlock here, because this is just called
- if the device has not been opened before.
- So there aren't any IRQs from the device */
- mts64_device_open(mts);
-
- msleep(50);
- }
- ++(mts->open_count);
-
- return 0;
-}
-
-static int snd_mts64_rawmidi_close(struct snd_rawmidi_substream *substream)
-{
- struct mts64 *mts = substream->rmidi->private_data;
- unsigned long flags;
-
- --(mts->open_count);
- if (mts->open_count == 0) {
- /* We need the spinlock_irqsave here because we can still
- have IRQs at this point */
- spin_lock_irqsave(&mts->lock, flags);
- mts64_device_close(mts);
- spin_unlock_irqrestore(&mts->lock, flags);
-
- msleep(500);
-
- } else if (mts->open_count < 0)
- mts->open_count = 0;
-
- return 0;
-}
-
-static void snd_mts64_rawmidi_output_trigger(struct snd_rawmidi_substream *substream,
- int up)
-{
- struct mts64 *mts = substream->rmidi->private_data;
- u8 data;
- unsigned long flags;
-
- spin_lock_irqsave(&mts->lock, flags);
- while (snd_rawmidi_transmit_peek(substream, &data, 1) == 1) {
- mts64_write_midi(mts, data, substream->number+1);
- snd_rawmidi_transmit_ack(substream, 1);
- }
- spin_unlock_irqrestore(&mts->lock, flags);
-}
-
-static void snd_mts64_rawmidi_input_trigger(struct snd_rawmidi_substream *substream,
- int up)
-{
- struct mts64 *mts = substream->rmidi->private_data;
- unsigned long flags;
-
- spin_lock_irqsave(&mts->lock, flags);
- if (up)
- mts->mode[substream->number] |= MTS64_MODE_INPUT_TRIGGERED;
- else
- mts->mode[substream->number] &= ~MTS64_MODE_INPUT_TRIGGERED;
-
- spin_unlock_irqrestore(&mts->lock, flags);
-}
-
-static struct snd_rawmidi_ops snd_mts64_rawmidi_output_ops = {
- .open = snd_mts64_rawmidi_open,
- .close = snd_mts64_rawmidi_close,
- .trigger = snd_mts64_rawmidi_output_trigger
-};
-
-static struct snd_rawmidi_ops snd_mts64_rawmidi_input_ops = {
- .open = snd_mts64_rawmidi_open,
- .close = snd_mts64_rawmidi_close,
- .trigger = snd_mts64_rawmidi_input_trigger
-};
-
-/* Create and initialize the rawmidi component */
-static int __devinit snd_mts64_rawmidi_create(struct snd_card *card)
-{
- struct mts64 *mts = card->private_data;
- struct snd_rawmidi *rmidi;
- struct snd_rawmidi_substream *substream;
- struct list_head *list;
- int err;
-
- err = snd_rawmidi_new(card, CARD_NAME, 0,
- MTS64_NUM_OUTPUT_PORTS,
- MTS64_NUM_INPUT_PORTS,
- &rmidi);
- if (err < 0)
- return err;
-
- rmidi->private_data = mts;
- strcpy(rmidi->name, CARD_NAME);
- rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
-
- mts->rmidi = rmidi;
-
- /* register rawmidi ops */
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
- &snd_mts64_rawmidi_output_ops);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
- &snd_mts64_rawmidi_input_ops);
-
- /* name substreams */
- /* output */
- list_for_each(list,
- &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
- substream = list_entry(list, struct snd_rawmidi_substream, list);
- sprintf(substream->name,
- "Miditerminal %d", substream->number+1);
- }
- /* input */
- list_for_each(list,
- &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) {
- substream = list_entry(list, struct snd_rawmidi_substream, list);
- mts->midi_input_substream[substream->number] = substream;
- switch(substream->number) {
- case MTS64_SMPTE_SUBSTREAM:
- strcpy(substream->name, "Miditerminal SMPTE");
- break;
- default:
- sprintf(substream->name,
- "Miditerminal %d", substream->number+1);
- }
- }
-
- /* controls */
- err = snd_mts64_ctl_create(card, mts);
-
- return err;
-}
-
-/*********************************************************************
- * parport stuff
- *********************************************************************/
-static void snd_mts64_interrupt(void *private)
-{
- struct mts64 *mts = ((struct snd_card*)private)->private_data;
- u16 ret;
- u8 status, data;
- struct snd_rawmidi_substream *substream;
-
- spin_lock(&mts->lock);
- ret = mts64_read(mts->pardev->port);
- data = ret & 0x00ff;
- status = ret >> 8;
-
- if (status & MTS64_STAT_PORT) {
- mts->current_midi_input_port = mts64_map_midi_input(data);
- } else {
- if (mts->current_midi_input_port == -1)
- goto __out;
- substream = mts->midi_input_substream[mts->current_midi_input_port];
- if (mts->mode[substream->number] & MTS64_MODE_INPUT_TRIGGERED)
- snd_rawmidi_receive(substream, &data, 1);
- }
-__out:
- spin_unlock(&mts->lock);
-}
-
-static int __devinit snd_mts64_probe_port(struct parport *p)
-{
- struct pardevice *pardev;
- int res;
-
- pardev = parport_register_device(p, DRIVER_NAME,
- NULL, NULL, NULL,
- 0, NULL);
- if (!pardev)
- return -EIO;
-
- if (parport_claim(pardev)) {
- parport_unregister_device(pardev);
- return -EIO;
- }
-
- res = mts64_probe(p);
-
- parport_release(pardev);
- parport_unregister_device(pardev);
-
- return res;
-}
-
-static void __devinit snd_mts64_attach(struct parport *p)
-{
- struct platform_device *device;
-
- device = platform_device_alloc(PLATFORM_DRIVER, device_count);
- if (!device)
- return;
-
- /* Temporary assignment to forward the parport */
- platform_set_drvdata(device, p);
-
- if (platform_device_add(device) < 0) {
- platform_device_put(device);
- return;
- }
-
- /* Since we dont get the return value of probe
- * We need to check if device probing succeeded or not */
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- return;
- }
-
- /* register device in global table */
- platform_devices[device_count] = device;
- device_count++;
-}
-
-static void snd_mts64_detach(struct parport *p)
-{
- /* nothing to do here */
-}
-
-static struct parport_driver mts64_parport_driver = {
- .name = "mts64",
- .attach = snd_mts64_attach,
- .detach = snd_mts64_detach
-};
-
-/*********************************************************************
- * platform stuff
- *********************************************************************/
-static void snd_mts64_card_private_free(struct snd_card *card)
-{
- struct mts64 *mts = card->private_data;
- struct pardevice *pardev = mts->pardev;
-
- if (pardev) {
- if (mts->pardev_claimed)
- parport_release(pardev);
- parport_unregister_device(pardev);
- }
-
- snd_mts64_free(mts);
-}
-
-static int __devinit snd_mts64_probe(struct platform_device *pdev)
-{
- struct pardevice *pardev;
- struct parport *p;
- int dev = pdev->id;
- struct snd_card *card = NULL;
- struct mts64 *mts = NULL;
- int err;
-
- p = platform_get_drvdata(pdev);
- platform_set_drvdata(pdev, NULL);
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev])
- return -ENOENT;
- if ((err = snd_mts64_probe_port(p)) < 0)
- return err;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0) {
- snd_printd("Cannot create card\n");
- return err;
- }
- strcpy(card->driver, DRIVER_NAME);
- strcpy(card->shortname, "ESI " CARD_NAME);
- sprintf(card->longname, "%s at 0x%lx, irq %i",
- card->shortname, p->base, p->irq);
-
- pardev = parport_register_device(p, /* port */
- DRIVER_NAME, /* name */
- NULL, /* preempt */
- NULL, /* wakeup */
- snd_mts64_interrupt, /* ISR */
- PARPORT_DEV_EXCL, /* flags */
- (void *)card); /* private */
- if (pardev == NULL) {
- snd_printd("Cannot register pardevice\n");
- err = -EIO;
- goto __err;
- }
-
- if ((err = snd_mts64_create(card, pardev, &mts)) < 0) {
- snd_printd("Cannot create main component\n");
- parport_unregister_device(pardev);
- goto __err;
- }
- card->private_data = mts;
- card->private_free = snd_mts64_card_private_free;
-
- if ((err = snd_mts64_rawmidi_create(card)) < 0) {
- snd_printd("Creating Rawmidi component failed\n");
- goto __err;
- }
-
- /* claim parport */
- if (parport_claim(pardev)) {
- snd_printd("Cannot claim parport 0x%lx\n", pardev->port->base);
- err = -EIO;
- goto __err;
- }
- mts->pardev_claimed = 1;
-
- /* init device */
- if ((err = mts64_device_init(p)) < 0)
- goto __err;
-
- platform_set_drvdata(pdev, card);
-
- snd_card_set_dev(card, &pdev->dev);
-
- /* At this point card will be usable */
- if ((err = snd_card_register(card)) < 0) {
- snd_printd("Cannot register card\n");
- goto __err;
- }
-
- snd_printk(KERN_INFO "ESI Miditerminal 4140 on 0x%lx\n", p->base);
- return 0;
-
-__err:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit snd_mts64_remove(struct platform_device *pdev)
-{
- struct snd_card *card = platform_get_drvdata(pdev);
-
- if (card)
- snd_card_free(card);
-
- return 0;
-}
-
-
-static struct platform_driver snd_mts64_driver = {
- .probe = snd_mts64_probe,
- .remove = __devexit_p(snd_mts64_remove),
- .driver = {
- .name = PLATFORM_DRIVER
- }
-};
-
-/*********************************************************************
- * module init stuff
- *********************************************************************/
-static void snd_mts64_unregister_all(void)
-{
- int i;
-
- for (i = 0; i < SNDRV_CARDS; ++i) {
- if (platform_devices[i]) {
- platform_device_unregister(platform_devices[i]);
- platform_devices[i] = NULL;
- }
- }
- platform_driver_unregister(&snd_mts64_driver);
- parport_unregister_driver(&mts64_parport_driver);
-}
-
-static int __init snd_mts64_module_init(void)
-{
- int err;
-
- if ((err = platform_driver_register(&snd_mts64_driver)) < 0)
- return err;
-
- if (parport_register_driver(&mts64_parport_driver) != 0) {
- platform_driver_unregister(&snd_mts64_driver);
- return -EIO;
- }
-
- if (device_count == 0) {
- snd_mts64_unregister_all();
- return -ENODEV;
- }
-
- return 0;
-}
-
-static void __exit snd_mts64_module_exit(void)
-{
- snd_mts64_unregister_all();
-}
-
-module_init(snd_mts64_module_init);
-module_exit(snd_mts64_module_exit);
diff --git a/ANDROID_3.4.5/sound/drivers/opl3/Makefile b/ANDROID_3.4.5/sound/drivers/opl3/Makefile
deleted file mode 100644
index 7f2c2a10..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl3/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-opl3-lib-objs := opl3_lib.o opl3_synth.o
-snd-opl3-synth-y := opl3_seq.o opl3_midi.o opl3_drums.o
-snd-opl3-synth-$(CONFIG_SND_SEQUENCER_OSS) += opl3_oss.o
-
-obj-$(CONFIG_SND_OPL3_LIB) += snd-opl3-lib.o
-obj-$(CONFIG_SND_OPL4_LIB) += snd-opl3-lib.o
-obj-$(CONFIG_SND_OPL3_LIB_SEQ) += snd-opl3-synth.o
diff --git a/ANDROID_3.4.5/sound/drivers/opl3/opl3_drums.c b/ANDROID_3.4.5/sound/drivers/opl3/opl3_drums.c
deleted file mode 100644
index 73694380..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl3/opl3_drums.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (c) by Uros Bizjak <uros@kss-loka.si>
- *
- * OPL2/OPL3/OPL4 FM routines for internal percussion channels
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "opl3_voice.h"
-
-extern char snd_opl3_regmap[MAX_OPL2_VOICES][4];
-
-static char snd_opl3_drum_table[47] =
-{
- OPL3_BASSDRUM_ON, OPL3_BASSDRUM_ON, OPL3_HIHAT_ON, /* 35 - 37 */
- OPL3_SNAREDRUM_ON, OPL3_HIHAT_ON, OPL3_SNAREDRUM_ON, /* 38 - 40 */
- OPL3_BASSDRUM_ON, OPL3_HIHAT_ON, OPL3_BASSDRUM_ON, /* 41 - 43 */
- OPL3_HIHAT_ON, OPL3_TOMTOM_ON, OPL3_HIHAT_ON, /* 44 - 46 */
- OPL3_TOMTOM_ON, OPL3_TOMTOM_ON, OPL3_CYMBAL_ON, /* 47 - 49 */
-
- OPL3_TOMTOM_ON, OPL3_CYMBAL_ON, OPL3_CYMBAL_ON, /* 50 - 52 */
- OPL3_CYMBAL_ON, OPL3_CYMBAL_ON, OPL3_CYMBAL_ON, /* 53 - 55 */
- OPL3_HIHAT_ON, OPL3_CYMBAL_ON, OPL3_TOMTOM_ON, /* 56 - 58 */
- OPL3_CYMBAL_ON, OPL3_TOMTOM_ON, OPL3_TOMTOM_ON, /* 59 - 61 */
- OPL3_HIHAT_ON, OPL3_TOMTOM_ON, OPL3_TOMTOM_ON, /* 62 - 64 */
-
- OPL3_TOMTOM_ON, OPL3_TOMTOM_ON, OPL3_TOMTOM_ON, /* 65 - 67 */
- OPL3_TOMTOM_ON, OPL3_HIHAT_ON, OPL3_HIHAT_ON, /* 68 - 70 */
- OPL3_HIHAT_ON, OPL3_HIHAT_ON, OPL3_TOMTOM_ON, /* 71 - 73 */
- OPL3_TOMTOM_ON, OPL3_TOMTOM_ON, OPL3_TOMTOM_ON, /* 74 - 76 */
- OPL3_TOMTOM_ON, OPL3_TOMTOM_ON, OPL3_TOMTOM_ON, /* 77 - 79 */
- OPL3_CYMBAL_ON, OPL3_CYMBAL_ON /* 80 - 81 */
-};
-
-struct snd_opl3_drum_voice {
- int voice;
- int op;
- unsigned char am_vib;
- unsigned char ksl_level;
- unsigned char attack_decay;
- unsigned char sustain_release;
- unsigned char feedback_connection;
- unsigned char wave_select;
-};
-
-struct snd_opl3_drum_note {
- int voice;
- unsigned char fnum;
- unsigned char octave_f;
- unsigned char feedback_connection;
-};
-
-static struct snd_opl3_drum_voice bass_op0 = {6, 0, 0x00, 0x32, 0xf8, 0x66, 0x30, 0x00};
-static struct snd_opl3_drum_voice bass_op1 = {6, 1, 0x00, 0x03, 0xf6, 0x57, 0x30, 0x00};
-static struct snd_opl3_drum_note bass_note = {6, 0x90, 0x09};
-
-static struct snd_opl3_drum_voice hihat = {7, 0, 0x00, 0x03, 0xf0, 0x06, 0x20, 0x00};
-
-static struct snd_opl3_drum_voice snare = {7, 1, 0x00, 0x03, 0xf0, 0x07, 0x20, 0x02};
-static struct snd_opl3_drum_note snare_note = {7, 0xf4, 0x0d};
-
-static struct snd_opl3_drum_voice tomtom = {8, 0, 0x02, 0x03, 0xf0, 0x06, 0x10, 0x00};
-static struct snd_opl3_drum_note tomtom_note = {8, 0xf4, 0x09};
-
-static struct snd_opl3_drum_voice cymbal = {8, 1, 0x04, 0x03, 0xf0, 0x06, 0x10, 0x00};
-
-/*
- * set drum voice characteristics
- */
-static void snd_opl3_drum_voice_set(struct snd_opl3 *opl3,
- struct snd_opl3_drum_voice *data)
-{
- unsigned char op_offset = snd_opl3_regmap[data->voice][data->op];
- unsigned char voice_offset = data->voice;
- unsigned short opl3_reg;
-
- /* Set OPL3 AM_VIB register */
- opl3_reg = OPL3_LEFT | (OPL3_REG_AM_VIB + op_offset);
- opl3->command(opl3, opl3_reg, data->am_vib);
-
- /* Set OPL3 KSL_LEVEL register */
- opl3_reg = OPL3_LEFT | (OPL3_REG_KSL_LEVEL + op_offset);
- opl3->command(opl3, opl3_reg, data->ksl_level);
-
- /* Set OPL3 ATTACK_DECAY register */
- opl3_reg = OPL3_LEFT | (OPL3_REG_ATTACK_DECAY + op_offset);
- opl3->command(opl3, opl3_reg, data->attack_decay);
-
- /* Set OPL3 SUSTAIN_RELEASE register */
- opl3_reg = OPL3_LEFT | (OPL3_REG_SUSTAIN_RELEASE + op_offset);
- opl3->command(opl3, opl3_reg, data->sustain_release);
-
- /* Set OPL3 FEEDBACK_CONNECTION register */
- opl3_reg = OPL3_LEFT | (OPL3_REG_FEEDBACK_CONNECTION + voice_offset);
- opl3->command(opl3, opl3_reg, data->feedback_connection);
-
- /* Select waveform */
- opl3_reg = OPL3_LEFT | (OPL3_REG_WAVE_SELECT + op_offset);
- opl3->command(opl3, opl3_reg, data->wave_select);
-}
-
-/*
- * Set drum voice pitch
- */
-static void snd_opl3_drum_note_set(struct snd_opl3 *opl3,
- struct snd_opl3_drum_note *data)
-{
- unsigned char voice_offset = data->voice;
- unsigned short opl3_reg;
-
- /* Set OPL3 FNUM_LOW register */
- opl3_reg = OPL3_LEFT | (OPL3_REG_FNUM_LOW + voice_offset);
- opl3->command(opl3, opl3_reg, data->fnum);
-
- /* Set OPL3 KEYON_BLOCK register */
- opl3_reg = OPL3_LEFT | (OPL3_REG_KEYON_BLOCK + voice_offset);
- opl3->command(opl3, opl3_reg, data->octave_f);
-}
-
-/*
- * Set drum voice volume and position
- */
-static void snd_opl3_drum_vol_set(struct snd_opl3 *opl3,
- struct snd_opl3_drum_voice *data,
- int vel, struct snd_midi_channel *chan)
-{
- unsigned char op_offset = snd_opl3_regmap[data->voice][data->op];
- unsigned char voice_offset = data->voice;
- unsigned char reg_val;
- unsigned short opl3_reg;
-
- /* Set OPL3 KSL_LEVEL register */
- reg_val = data->ksl_level;
- snd_opl3_calc_volume(&reg_val, vel, chan);
- opl3_reg = OPL3_LEFT | (OPL3_REG_KSL_LEVEL + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- /* Set OPL3 FEEDBACK_CONNECTION register */
- /* Set output voice connection */
- reg_val = data->feedback_connection | OPL3_STEREO_BITS;
- if (chan->gm_pan < 43)
- reg_val &= ~OPL3_VOICE_TO_RIGHT;
- if (chan->gm_pan > 85)
- reg_val &= ~OPL3_VOICE_TO_LEFT;
- opl3_reg = OPL3_LEFT | (OPL3_REG_FEEDBACK_CONNECTION + voice_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-}
-
-/*
- * Loads drum voices at init time
- */
-void snd_opl3_load_drums(struct snd_opl3 *opl3)
-{
- snd_opl3_drum_voice_set(opl3, &bass_op0);
- snd_opl3_drum_voice_set(opl3, &bass_op1);
- snd_opl3_drum_note_set(opl3, &bass_note);
-
- snd_opl3_drum_voice_set(opl3, &hihat);
-
- snd_opl3_drum_voice_set(opl3, &snare);
- snd_opl3_drum_note_set(opl3, &snare_note);
-
- snd_opl3_drum_voice_set(opl3, &tomtom);
- snd_opl3_drum_note_set(opl3, &tomtom_note);
-
- snd_opl3_drum_voice_set(opl3, &cymbal);
-}
-
-/*
- * Switch drum voice on or off
- */
-void snd_opl3_drum_switch(struct snd_opl3 *opl3, int note, int vel, int on_off,
- struct snd_midi_channel *chan)
-{
- unsigned char drum_mask;
- struct snd_opl3_drum_voice *drum_voice;
-
- if (!(opl3->drum_reg & OPL3_PERCUSSION_ENABLE))
- return;
-
- if ((note < 35) || (note > 81))
- return;
- drum_mask = snd_opl3_drum_table[note - 35];
-
- if (on_off) {
- switch (drum_mask) {
- case OPL3_BASSDRUM_ON:
- drum_voice = &bass_op1;
- break;
- case OPL3_HIHAT_ON:
- drum_voice = &hihat;
- break;
- case OPL3_SNAREDRUM_ON:
- drum_voice = &snare;
- break;
- case OPL3_TOMTOM_ON:
- drum_voice = &tomtom;
- break;
- case OPL3_CYMBAL_ON:
- drum_voice = &cymbal;
- break;
- default:
- drum_voice = &tomtom;
- }
-
- snd_opl3_drum_vol_set(opl3, drum_voice, vel, chan);
- opl3->drum_reg |= drum_mask;
- } else {
- opl3->drum_reg &= ~drum_mask;
- }
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION,
- opl3->drum_reg);
-}
diff --git a/ANDROID_3.4.5/sound/drivers/opl3/opl3_lib.c b/ANDROID_3.4.5/sound/drivers/opl3/opl3_lib.c
deleted file mode 100644
index 33d9a857..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl3/opl3_lib.c
+++ /dev/null
@@ -1,561 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
- * Hannu Savolainen 1993-1996,
- * Rob Hooft
- *
- * Routines for control of AdLib FM cards (OPL2/OPL3/OPL4 chips)
- *
- * Most if code is ported from OSS/Lite.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <sound/opl3.h>
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <sound/minors.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Hannu Savolainen 1993-1996, Rob Hooft");
-MODULE_DESCRIPTION("Routines for control of AdLib FM cards (OPL2/OPL3/OPL4 chips)");
-MODULE_LICENSE("GPL");
-
-extern char snd_opl3_regmap[MAX_OPL2_VOICES][4];
-
-static void snd_opl2_command(struct snd_opl3 * opl3, unsigned short cmd, unsigned char val)
-{
- unsigned long flags;
- unsigned long port;
-
- /*
- * The original 2-OP synth requires a quite long delay
- * after writing to a register.
- */
-
- port = (cmd & OPL3_RIGHT) ? opl3->r_port : opl3->l_port;
-
- spin_lock_irqsave(&opl3->reg_lock, flags);
-
- outb((unsigned char) cmd, port);
- udelay(10);
-
- outb((unsigned char) val, port + 1);
- udelay(30);
-
- spin_unlock_irqrestore(&opl3->reg_lock, flags);
-}
-
-static void snd_opl3_command(struct snd_opl3 * opl3, unsigned short cmd, unsigned char val)
-{
- unsigned long flags;
- unsigned long port;
-
- /*
- * The OPL-3 survives with just two INBs
- * after writing to a register.
- */
-
- port = (cmd & OPL3_RIGHT) ? opl3->r_port : opl3->l_port;
-
- spin_lock_irqsave(&opl3->reg_lock, flags);
-
- outb((unsigned char) cmd, port);
- inb(opl3->l_port);
- inb(opl3->l_port);
-
- outb((unsigned char) val, port + 1);
- inb(opl3->l_port);
- inb(opl3->l_port);
-
- spin_unlock_irqrestore(&opl3->reg_lock, flags);
-}
-
-static int snd_opl3_detect(struct snd_opl3 * opl3)
-{
- /*
- * This function returns 1 if the FM chip is present at the given I/O port
- * The detection algorithm plays with the timer built in the FM chip and
- * looks for a change in the status register.
- *
- * Note! The timers of the FM chip are not connected to AdLib (and compatible)
- * boards.
- *
- * Note2! The chip is initialized if detected.
- */
-
- unsigned char stat1, stat2, signature;
-
- /* Reset timers 1 and 2 */
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER1_MASK | OPL3_TIMER2_MASK);
- /* Reset the IRQ of the FM chip */
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_IRQ_RESET);
- signature = stat1 = inb(opl3->l_port); /* Status register */
- if ((stat1 & 0xe0) != 0x00) { /* Should be 0x00 */
- snd_printd("OPL3: stat1 = 0x%x\n", stat1);
- return -ENODEV;
- }
- /* Set timer1 to 0xff */
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER1, 0xff);
- /* Unmask and start timer 1 */
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER2_MASK | OPL3_TIMER1_START);
- /* Now we have to delay at least 80us */
- udelay(200);
- /* Read status after timers have expired */
- stat2 = inb(opl3->l_port);
- /* Stop the timers */
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER1_MASK | OPL3_TIMER2_MASK);
- /* Reset the IRQ of the FM chip */
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_IRQ_RESET);
- if ((stat2 & 0xe0) != 0xc0) { /* There is no YM3812 */
- snd_printd("OPL3: stat2 = 0x%x\n", stat2);
- return -ENODEV;
- }
-
- /* If the toplevel code knows exactly the type of chip, don't try
- to detect it. */
- if (opl3->hardware != OPL3_HW_AUTO)
- return 0;
-
- /* There is a FM chip on this address. Detect the type (OPL2 to OPL4) */
- if (signature == 0x06) { /* OPL2 */
- opl3->hardware = OPL3_HW_OPL2;
- } else {
- /*
- * If we had an OPL4 chip, opl3->hardware would have been set
- * by the OPL4 driver; so we can assume OPL3 here.
- */
- if (snd_BUG_ON(!opl3->r_port))
- return -ENODEV;
- opl3->hardware = OPL3_HW_OPL3;
- }
- return 0;
-}
-
-/*
- * AdLib timers
- */
-
-/*
- * Timer 1 - 80us
- */
-
-static int snd_opl3_timer1_start(struct snd_timer * timer)
-{
- unsigned long flags;
- unsigned char tmp;
- unsigned int ticks;
- struct snd_opl3 *opl3;
-
- opl3 = snd_timer_chip(timer);
- spin_lock_irqsave(&opl3->timer_lock, flags);
- ticks = timer->sticks;
- tmp = (opl3->timer_enable | OPL3_TIMER1_START) & ~OPL3_TIMER1_MASK;
- opl3->timer_enable = tmp;
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER1, 256 - ticks); /* timer 1 count */
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp); /* enable timer 1 IRQ */
- spin_unlock_irqrestore(&opl3->timer_lock, flags);
- return 0;
-}
-
-static int snd_opl3_timer1_stop(struct snd_timer * timer)
-{
- unsigned long flags;
- unsigned char tmp;
- struct snd_opl3 *opl3;
-
- opl3 = snd_timer_chip(timer);
- spin_lock_irqsave(&opl3->timer_lock, flags);
- tmp = (opl3->timer_enable | OPL3_TIMER1_MASK) & ~OPL3_TIMER1_START;
- opl3->timer_enable = tmp;
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp); /* disable timer #1 */
- spin_unlock_irqrestore(&opl3->timer_lock, flags);
- return 0;
-}
-
-/*
- * Timer 2 - 320us
- */
-
-static int snd_opl3_timer2_start(struct snd_timer * timer)
-{
- unsigned long flags;
- unsigned char tmp;
- unsigned int ticks;
- struct snd_opl3 *opl3;
-
- opl3 = snd_timer_chip(timer);
- spin_lock_irqsave(&opl3->timer_lock, flags);
- ticks = timer->sticks;
- tmp = (opl3->timer_enable | OPL3_TIMER2_START) & ~OPL3_TIMER2_MASK;
- opl3->timer_enable = tmp;
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER2, 256 - ticks); /* timer 1 count */
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp); /* enable timer 1 IRQ */
- spin_unlock_irqrestore(&opl3->timer_lock, flags);
- return 0;
-}
-
-static int snd_opl3_timer2_stop(struct snd_timer * timer)
-{
- unsigned long flags;
- unsigned char tmp;
- struct snd_opl3 *opl3;
-
- opl3 = snd_timer_chip(timer);
- spin_lock_irqsave(&opl3->timer_lock, flags);
- tmp = (opl3->timer_enable | OPL3_TIMER2_MASK) & ~OPL3_TIMER2_START;
- opl3->timer_enable = tmp;
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp); /* disable timer #1 */
- spin_unlock_irqrestore(&opl3->timer_lock, flags);
- return 0;
-}
-
-/*
-
- */
-
-static struct snd_timer_hardware snd_opl3_timer1 =
-{
- .flags = SNDRV_TIMER_HW_STOP,
- .resolution = 80000,
- .ticks = 256,
- .start = snd_opl3_timer1_start,
- .stop = snd_opl3_timer1_stop,
-};
-
-static struct snd_timer_hardware snd_opl3_timer2 =
-{
- .flags = SNDRV_TIMER_HW_STOP,
- .resolution = 320000,
- .ticks = 256,
- .start = snd_opl3_timer2_start,
- .stop = snd_opl3_timer2_stop,
-};
-
-static int snd_opl3_timer1_init(struct snd_opl3 * opl3, int timer_no)
-{
- struct snd_timer *timer = NULL;
- struct snd_timer_id tid;
- int err;
-
- tid.dev_class = SNDRV_TIMER_CLASS_CARD;
- tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
- tid.card = opl3->card->number;
- tid.device = timer_no;
- tid.subdevice = 0;
- if ((err = snd_timer_new(opl3->card, "AdLib timer #1", &tid, &timer)) >= 0) {
- strcpy(timer->name, "AdLib timer #1");
- timer->private_data = opl3;
- timer->hw = snd_opl3_timer1;
- }
- opl3->timer1 = timer;
- return err;
-}
-
-static int snd_opl3_timer2_init(struct snd_opl3 * opl3, int timer_no)
-{
- struct snd_timer *timer = NULL;
- struct snd_timer_id tid;
- int err;
-
- tid.dev_class = SNDRV_TIMER_CLASS_CARD;
- tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
- tid.card = opl3->card->number;
- tid.device = timer_no;
- tid.subdevice = 0;
- if ((err = snd_timer_new(opl3->card, "AdLib timer #2", &tid, &timer)) >= 0) {
- strcpy(timer->name, "AdLib timer #2");
- timer->private_data = opl3;
- timer->hw = snd_opl3_timer2;
- }
- opl3->timer2 = timer;
- return err;
-}
-
-/*
-
- */
-
-void snd_opl3_interrupt(struct snd_hwdep * hw)
-{
- unsigned char status;
- struct snd_opl3 *opl3;
- struct snd_timer *timer;
-
- if (hw == NULL)
- return;
-
- opl3 = hw->private_data;
- status = inb(opl3->l_port);
-#if 0
- snd_printk(KERN_DEBUG "AdLib IRQ status = 0x%x\n", status);
-#endif
- if (!(status & 0x80))
- return;
-
- if (status & 0x40) {
- timer = opl3->timer1;
- snd_timer_interrupt(timer, timer->sticks);
- }
- if (status & 0x20) {
- timer = opl3->timer2;
- snd_timer_interrupt(timer, timer->sticks);
- }
-}
-
-EXPORT_SYMBOL(snd_opl3_interrupt);
-
-/*
-
- */
-
-static int snd_opl3_free(struct snd_opl3 *opl3)
-{
- if (snd_BUG_ON(!opl3))
- return -ENXIO;
- if (opl3->private_free)
- opl3->private_free(opl3);
- snd_opl3_clear_patches(opl3);
- release_and_free_resource(opl3->res_l_port);
- release_and_free_resource(opl3->res_r_port);
- kfree(opl3);
- return 0;
-}
-
-static int snd_opl3_dev_free(struct snd_device *device)
-{
- struct snd_opl3 *opl3 = device->device_data;
- return snd_opl3_free(opl3);
-}
-
-int snd_opl3_new(struct snd_card *card,
- unsigned short hardware,
- struct snd_opl3 **ropl3)
-{
- static struct snd_device_ops ops = {
- .dev_free = snd_opl3_dev_free,
- };
- struct snd_opl3 *opl3;
- int err;
-
- *ropl3 = NULL;
- opl3 = kzalloc(sizeof(*opl3), GFP_KERNEL);
- if (opl3 == NULL) {
- snd_printk(KERN_ERR "opl3: cannot allocate\n");
- return -ENOMEM;
- }
-
- opl3->card = card;
- opl3->hardware = hardware;
- spin_lock_init(&opl3->reg_lock);
- spin_lock_init(&opl3->timer_lock);
-
- if ((err = snd_device_new(card, SNDRV_DEV_CODEC, opl3, &ops)) < 0) {
- snd_opl3_free(opl3);
- return err;
- }
-
- *ropl3 = opl3;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_opl3_new);
-
-int snd_opl3_init(struct snd_opl3 *opl3)
-{
- if (! opl3->command) {
- printk(KERN_ERR "snd_opl3_init: command not defined!\n");
- return -EINVAL;
- }
-
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TEST, OPL3_ENABLE_WAVE_SELECT);
- /* Melodic mode */
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 0x00);
-
- switch (opl3->hardware & OPL3_HW_MASK) {
- case OPL3_HW_OPL2:
- opl3->max_voices = MAX_OPL2_VOICES;
- break;
- case OPL3_HW_OPL3:
- case OPL3_HW_OPL4:
- opl3->max_voices = MAX_OPL3_VOICES;
- /* Enter OPL3 mode */
- opl3->command(opl3, OPL3_RIGHT | OPL3_REG_MODE, OPL3_OPL3_ENABLE);
- }
- return 0;
-}
-
-EXPORT_SYMBOL(snd_opl3_init);
-
-int snd_opl3_create(struct snd_card *card,
- unsigned long l_port,
- unsigned long r_port,
- unsigned short hardware,
- int integrated,
- struct snd_opl3 ** ropl3)
-{
- struct snd_opl3 *opl3;
- int err;
-
- *ropl3 = NULL;
- if ((err = snd_opl3_new(card, hardware, &opl3)) < 0)
- return err;
- if (! integrated) {
- if ((opl3->res_l_port = request_region(l_port, 2, "OPL2/3 (left)")) == NULL) {
- snd_printk(KERN_ERR "opl3: can't grab left port 0x%lx\n", l_port);
- snd_device_free(card, opl3);
- return -EBUSY;
- }
- if (r_port != 0 &&
- (opl3->res_r_port = request_region(r_port, 2, "OPL2/3 (right)")) == NULL) {
- snd_printk(KERN_ERR "opl3: can't grab right port 0x%lx\n", r_port);
- snd_device_free(card, opl3);
- return -EBUSY;
- }
- }
- opl3->l_port = l_port;
- opl3->r_port = r_port;
-
- switch (opl3->hardware) {
- /* some hardware doesn't support timers */
- case OPL3_HW_OPL3_SV:
- case OPL3_HW_OPL3_CS:
- case OPL3_HW_OPL3_FM801:
- opl3->command = &snd_opl3_command;
- break;
- default:
- opl3->command = &snd_opl2_command;
- if ((err = snd_opl3_detect(opl3)) < 0) {
- snd_printd("OPL2/3 chip not detected at 0x%lx/0x%lx\n",
- opl3->l_port, opl3->r_port);
- snd_device_free(card, opl3);
- return err;
- }
- /* detect routine returns correct hardware type */
- switch (opl3->hardware & OPL3_HW_MASK) {
- case OPL3_HW_OPL3:
- case OPL3_HW_OPL4:
- opl3->command = &snd_opl3_command;
- }
- }
-
- snd_opl3_init(opl3);
-
- *ropl3 = opl3;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_opl3_create);
-
-int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev)
-{
- int err;
-
- if (timer1_dev >= 0)
- if ((err = snd_opl3_timer1_init(opl3, timer1_dev)) < 0)
- return err;
- if (timer2_dev >= 0) {
- if ((err = snd_opl3_timer2_init(opl3, timer2_dev)) < 0) {
- snd_device_free(opl3->card, opl3->timer1);
- opl3->timer1 = NULL;
- return err;
- }
- }
- return 0;
-}
-
-EXPORT_SYMBOL(snd_opl3_timer_new);
-
-int snd_opl3_hwdep_new(struct snd_opl3 * opl3,
- int device, int seq_device,
- struct snd_hwdep ** rhwdep)
-{
- struct snd_hwdep *hw;
- struct snd_card *card = opl3->card;
- int err;
-
- if (rhwdep)
- *rhwdep = NULL;
-
- /* create hardware dependent device (direct FM) */
-
- if ((err = snd_hwdep_new(card, "OPL2/OPL3", device, &hw)) < 0) {
- snd_device_free(card, opl3);
- return err;
- }
- hw->private_data = opl3;
- hw->exclusive = 1;
-#ifdef CONFIG_SND_OSSEMUL
- if (device == 0) {
- hw->oss_type = SNDRV_OSS_DEVICE_TYPE_DMFM;
- sprintf(hw->oss_dev, "dmfm%i", card->number);
- }
-#endif
- strcpy(hw->name, hw->id);
- switch (opl3->hardware & OPL3_HW_MASK) {
- case OPL3_HW_OPL2:
- strcpy(hw->name, "OPL2 FM");
- hw->iface = SNDRV_HWDEP_IFACE_OPL2;
- break;
- case OPL3_HW_OPL3:
- strcpy(hw->name, "OPL3 FM");
- hw->iface = SNDRV_HWDEP_IFACE_OPL3;
- break;
- case OPL3_HW_OPL4:
- strcpy(hw->name, "OPL4 FM");
- hw->iface = SNDRV_HWDEP_IFACE_OPL4;
- break;
- }
-
- /* operators - only ioctl */
- hw->ops.open = snd_opl3_open;
- hw->ops.ioctl = snd_opl3_ioctl;
- hw->ops.write = snd_opl3_write;
- hw->ops.release = snd_opl3_release;
-
- opl3->hwdep = hw;
- opl3->seq_dev_num = seq_device;
-#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
- if (snd_seq_device_new(card, seq_device, SNDRV_SEQ_DEV_ID_OPL3,
- sizeof(struct snd_opl3 *), &opl3->seq_dev) >= 0) {
- strcpy(opl3->seq_dev->name, hw->name);
- *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(opl3->seq_dev) = opl3;
- }
-#endif
- if (rhwdep)
- *rhwdep = hw;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_opl3_hwdep_new);
-
-/*
- * INIT part
- */
-
-static int __init alsa_opl3_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_opl3_exit(void)
-{
-}
-
-module_init(alsa_opl3_init)
-module_exit(alsa_opl3_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/opl3/opl3_midi.c b/ANDROID_3.4.5/sound/drivers/opl3/opl3_midi.c
deleted file mode 100644
index 2bfe4bcb..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl3/opl3_midi.c
+++ /dev/null
@@ -1,881 +0,0 @@
-/*
- * Copyright (c) by Uros Bizjak <uros@kss-loka.si>
- *
- * Midi synth routines for OPL2/OPL3/OPL4 FM
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#undef DEBUG_ALLOC
-#undef DEBUG_MIDI
-
-#include "opl3_voice.h"
-#include <sound/asoundef.h>
-
-extern char snd_opl3_regmap[MAX_OPL2_VOICES][4];
-
-extern bool use_internal_drums;
-
-static void snd_opl3_note_off_unsafe(void *p, int note, int vel,
- struct snd_midi_channel *chan);
-/*
- * The next table looks magical, but it certainly is not. Its values have
- * been calculated as table[i]=8*log(i/64)/log(2) with an obvious exception
- * for i=0. This log-table converts a linear volume-scaling (0..127) to a
- * logarithmic scaling as present in the FM-synthesizer chips. so : Volume
- * 64 = 0 db = relative volume 0 and: Volume 32 = -6 db = relative
- * volume -8 it was implemented as a table because it is only 128 bytes and
- * it saves a lot of log() calculations. (Rob Hooft <hooft@chem.ruu.nl>)
- */
-
-static char opl3_volume_table[128] =
-{
- -63, -48, -40, -35, -32, -29, -27, -26,
- -24, -23, -21, -20, -19, -18, -18, -17,
- -16, -15, -15, -14, -13, -13, -12, -12,
- -11, -11, -10, -10, -10, -9, -9, -8,
- -8, -8, -7, -7, -7, -6, -6, -6,
- -5, -5, -5, -5, -4, -4, -4, -4,
- -3, -3, -3, -3, -2, -2, -2, -2,
- -2, -1, -1, -1, -1, 0, 0, 0,
- 0, 0, 0, 1, 1, 1, 1, 1,
- 1, 2, 2, 2, 2, 2, 2, 2,
- 3, 3, 3, 3, 3, 3, 3, 4,
- 4, 4, 4, 4, 4, 4, 4, 5,
- 5, 5, 5, 5, 5, 5, 5, 5,
- 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 8, 8, 8, 8, 8
-};
-
-void snd_opl3_calc_volume(unsigned char *volbyte, int vel,
- struct snd_midi_channel *chan)
-{
- int oldvol, newvol, n;
- int volume;
-
- volume = (vel * chan->gm_volume * chan->gm_expression) / (127*127);
- if (volume > 127)
- volume = 127;
-
- oldvol = OPL3_TOTAL_LEVEL_MASK - (*volbyte & OPL3_TOTAL_LEVEL_MASK);
-
- newvol = opl3_volume_table[volume] + oldvol;
- if (newvol > OPL3_TOTAL_LEVEL_MASK)
- newvol = OPL3_TOTAL_LEVEL_MASK;
- else if (newvol < 0)
- newvol = 0;
-
- n = OPL3_TOTAL_LEVEL_MASK - (newvol & OPL3_TOTAL_LEVEL_MASK);
-
- *volbyte = (*volbyte & OPL3_KSL_MASK) | (n & OPL3_TOTAL_LEVEL_MASK);
-}
-
-/*
- * Converts the note frequency to block and fnum values for the FM chip
- */
-static short opl3_note_table[16] =
-{
- 305, 323, /* for pitch bending, -2 semitones */
- 343, 363, 385, 408, 432, 458, 485, 514, 544, 577, 611, 647,
- 686, 726 /* for pitch bending, +2 semitones */
-};
-
-static void snd_opl3_calc_pitch(unsigned char *fnum, unsigned char *blocknum,
- int note, struct snd_midi_channel *chan)
-{
- int block = ((note / 12) & 0x07) - 1;
- int idx = (note % 12) + 2;
- int freq;
-
- if (chan->midi_pitchbend) {
- int pitchbend = chan->midi_pitchbend;
- int segment;
-
- if (pitchbend > 0x1FFF)
- pitchbend = 0x1FFF;
-
- segment = pitchbend / 0x1000;
- freq = opl3_note_table[idx+segment];
- freq += ((opl3_note_table[idx+segment+1] - freq) *
- (pitchbend % 0x1000)) / 0x1000;
- } else {
- freq = opl3_note_table[idx];
- }
-
- *fnum = (unsigned char) freq;
- *blocknum = ((freq >> 8) & OPL3_FNUM_HIGH_MASK) |
- ((block << 2) & OPL3_BLOCKNUM_MASK);
-}
-
-
-#ifdef DEBUG_ALLOC
-static void debug_alloc(struct snd_opl3 *opl3, char *s, int voice) {
- int i;
- char *str = "x.24";
-
- printk(KERN_DEBUG "time %.5i: %s [%.2i]: ", opl3->use_time, s, voice);
- for (i = 0; i < opl3->max_voices; i++)
- printk("%c", *(str + opl3->voices[i].state + 1));
- printk("\n");
-}
-#endif
-
-/*
- * Get a FM voice (channel) to play a note on.
- */
-static int opl3_get_voice(struct snd_opl3 *opl3, int instr_4op,
- struct snd_midi_channel *chan) {
- int chan_4op_1; /* first voice for 4op instrument */
- int chan_4op_2; /* second voice for 4op instrument */
-
- struct snd_opl3_voice *vp, *vp2;
- unsigned int voice_time;
- int i;
-
-#ifdef DEBUG_ALLOC
- char *alloc_type[3] = { "FREE ", "CHEAP ", "EXPENSIVE" };
-#endif
-
- /* This is our "allocation cost" table */
- enum {
- FREE = 0, CHEAP, EXPENSIVE, END
- };
-
- /* Keeps track of what we are finding */
- struct best {
- unsigned int time;
- int voice;
- } best[END];
- struct best *bp;
-
- for (i = 0; i < END; i++) {
- best[i].time = (unsigned int)(-1); /* XXX MAX_?INT really */;
- best[i].voice = -1;
- }
-
- /* Look through all the channels for the most suitable. */
- for (i = 0; i < opl3->max_voices; i++) {
- vp = &opl3->voices[i];
-
- if (vp->state == SNDRV_OPL3_ST_NOT_AVAIL)
- /* skip unavailable channels, allocated by
- drum voices or by bounded 4op voices) */
- continue;
-
- voice_time = vp->time;
- bp = best;
-
- chan_4op_1 = ((i < 3) || (i > 8 && i < 12));
- chan_4op_2 = ((i > 2 && i < 6) || (i > 11 && i < 15));
- if (instr_4op) {
- /* allocate 4op voice */
- /* skip channels unavailable to 4op instrument */
- if (!chan_4op_1)
- continue;
-
- if (vp->state)
- /* kill one voice, CHEAP */
- bp++;
- /* get state of bounded 2op channel
- to be allocated for 4op instrument */
- vp2 = &opl3->voices[i + 3];
- if (vp2->state == SNDRV_OPL3_ST_ON_2OP) {
- /* kill two voices, EXPENSIVE */
- bp++;
- voice_time = (voice_time > vp->time) ?
- voice_time : vp->time;
- }
- } else {
- /* allocate 2op voice */
- if ((chan_4op_1) || (chan_4op_2))
- /* use bounded channels for 2op, CHEAP */
- bp++;
- else if (vp->state)
- /* kill one voice on 2op channel, CHEAP */
- bp++;
- /* raise kill cost to EXPENSIVE for all channels */
- if (vp->state)
- bp++;
- }
- if (voice_time < bp->time) {
- bp->time = voice_time;
- bp->voice = i;
- }
- }
-
- for (i = 0; i < END; i++) {
- if (best[i].voice >= 0) {
-#ifdef DEBUG_ALLOC
- printk(KERN_DEBUG "%s %iop allocation on voice %i\n",
- alloc_type[i], instr_4op ? 4 : 2,
- best[i].voice);
-#endif
- return best[i].voice;
- }
- }
- /* not found */
- return -1;
-}
-
-/* ------------------------------ */
-
-/*
- * System timer interrupt function
- */
-void snd_opl3_timer_func(unsigned long data)
-{
-
- struct snd_opl3 *opl3 = (struct snd_opl3 *)data;
- unsigned long flags;
- int again = 0;
- int i;
-
- spin_lock_irqsave(&opl3->voice_lock, flags);
- for (i = 0; i < opl3->max_voices; i++) {
- struct snd_opl3_voice *vp = &opl3->voices[i];
- if (vp->state > 0 && vp->note_off_check) {
- if (vp->note_off == jiffies)
- snd_opl3_note_off_unsafe(opl3, vp->note, 0,
- vp->chan);
- else
- again++;
- }
- }
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
-
- spin_lock_irqsave(&opl3->sys_timer_lock, flags);
- if (again) {
- opl3->tlist.expires = jiffies + 1; /* invoke again */
- add_timer(&opl3->tlist);
- } else {
- opl3->sys_timer_status = 0;
- }
- spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
-}
-
-/*
- * Start system timer
- */
-static void snd_opl3_start_timer(struct snd_opl3 *opl3)
-{
- unsigned long flags;
- spin_lock_irqsave(&opl3->sys_timer_lock, flags);
- if (! opl3->sys_timer_status) {
- opl3->tlist.expires = jiffies + 1;
- add_timer(&opl3->tlist);
- opl3->sys_timer_status = 1;
- }
- spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
-}
-
-/* ------------------------------ */
-
-
-static int snd_opl3_oss_map[MAX_OPL3_VOICES] = {
- 0, 1, 2, 9, 10, 11, 6, 7, 8, 15, 16, 17, 3, 4 ,5, 12, 13, 14
-};
-
-/*
- * Start a note.
- */
-void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
-{
- struct snd_opl3 *opl3;
- int instr_4op;
-
- int voice;
- struct snd_opl3_voice *vp, *vp2;
- unsigned short connect_mask;
- unsigned char connection;
- unsigned char vol_op[4];
-
- int extra_prg = 0;
-
- unsigned short reg_side;
- unsigned char op_offset;
- unsigned char voice_offset;
- unsigned short opl3_reg;
- unsigned char reg_val;
- unsigned char prg, bank;
-
- int key = note;
- unsigned char fnum, blocknum;
- int i;
-
- struct fm_patch *patch;
- struct fm_instrument *fm;
- unsigned long flags;
-
- opl3 = p;
-
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG "Note on, ch %i, inst %i, note %i, vel %i\n",
- chan->number, chan->midi_program, note, vel);
-#endif
-
- /* in SYNTH mode, application takes care of voices */
- /* in SEQ mode, drum voice numbers are notes on drum channel */
- if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
- if (chan->drum_channel) {
- /* percussion instruments are located in bank 128 */
- bank = 128;
- prg = note;
- } else {
- bank = chan->gm_bank_select;
- prg = chan->midi_program;
- }
- } else {
- /* Prepare for OSS mode */
- if (chan->number >= MAX_OPL3_VOICES)
- return;
-
- /* OSS instruments are located in bank 127 */
- bank = 127;
- prg = chan->midi_program;
- }
-
- spin_lock_irqsave(&opl3->voice_lock, flags);
-
- if (use_internal_drums) {
- snd_opl3_drum_switch(opl3, note, vel, 1, chan);
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
- return;
- }
-
- __extra_prg:
- patch = snd_opl3_find_patch(opl3, prg, bank, 0);
- if (!patch) {
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
- return;
- }
-
- fm = &patch->inst;
- switch (patch->type) {
- case FM_PATCH_OPL2:
- instr_4op = 0;
- break;
- case FM_PATCH_OPL3:
- if (opl3->hardware >= OPL3_HW_OPL3) {
- instr_4op = 1;
- break;
- }
- default:
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
- return;
- }
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG " --> OPL%i instrument: %s\n",
- instr_4op ? 3 : 2, patch->name);
-#endif
- /* in SYNTH mode, application takes care of voices */
- /* in SEQ mode, allocate voice on free OPL3 channel */
- if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
- voice = opl3_get_voice(opl3, instr_4op, chan);
- } else {
- /* remap OSS voice */
- voice = snd_opl3_oss_map[chan->number];
- }
-
- if (voice < MAX_OPL2_VOICES) {
- /* Left register block for voices 0 .. 8 */
- reg_side = OPL3_LEFT;
- voice_offset = voice;
- connect_mask = (OPL3_LEFT_4OP_0 << voice_offset) & 0x07;
- } else {
- /* Right register block for voices 9 .. 17 */
- reg_side = OPL3_RIGHT;
- voice_offset = voice - MAX_OPL2_VOICES;
- connect_mask = (OPL3_RIGHT_4OP_0 << voice_offset) & 0x38;
- }
-
- /* kill voice on channel */
- vp = &opl3->voices[voice];
- if (vp->state > 0) {
- opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
- reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT;
- opl3->command(opl3, opl3_reg, reg_val);
- }
- if (instr_4op) {
- vp2 = &opl3->voices[voice + 3];
- if (vp->state > 0) {
- opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK +
- voice_offset + 3);
- reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT;
- opl3->command(opl3, opl3_reg, reg_val);
- }
- }
-
- /* set connection register */
- if (instr_4op) {
- if ((opl3->connection_reg ^ connect_mask) & connect_mask) {
- opl3->connection_reg |= connect_mask;
- /* set connection bit */
- opl3_reg = OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT;
- opl3->command(opl3, opl3_reg, opl3->connection_reg);
- }
- } else {
- if ((opl3->connection_reg ^ ~connect_mask) & connect_mask) {
- opl3->connection_reg &= ~connect_mask;
- /* clear connection bit */
- opl3_reg = OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT;
- opl3->command(opl3, opl3_reg, opl3->connection_reg);
- }
- }
-
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG " --> setting OPL3 connection: 0x%x\n",
- opl3->connection_reg);
-#endif
- /*
- * calculate volume depending on connection
- * between FM operators (see include/opl3.h)
- */
- for (i = 0; i < (instr_4op ? 4 : 2); i++)
- vol_op[i] = fm->op[i].ksl_level;
-
- connection = fm->feedback_connection[0] & 0x01;
- if (instr_4op) {
- connection <<= 1;
- connection |= fm->feedback_connection[1] & 0x01;
-
- snd_opl3_calc_volume(&vol_op[3], vel, chan);
- switch (connection) {
- case 0x03:
- snd_opl3_calc_volume(&vol_op[2], vel, chan);
- /* fallthru */
- case 0x02:
- snd_opl3_calc_volume(&vol_op[0], vel, chan);
- break;
- case 0x01:
- snd_opl3_calc_volume(&vol_op[1], vel, chan);
- }
- } else {
- snd_opl3_calc_volume(&vol_op[1], vel, chan);
- if (connection)
- snd_opl3_calc_volume(&vol_op[0], vel, chan);
- }
-
- /* Program the FM voice characteristics */
- for (i = 0; i < (instr_4op ? 4 : 2); i++) {
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG " --> programming operator %i\n", i);
-#endif
- op_offset = snd_opl3_regmap[voice_offset][i];
-
- /* Set OPL3 AM_VIB register of requested voice/operator */
- reg_val = fm->op[i].am_vib;
- opl3_reg = reg_side | (OPL3_REG_AM_VIB + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- /* Set OPL3 KSL_LEVEL register of requested voice/operator */
- reg_val = vol_op[i];
- opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- /* Set OPL3 ATTACK_DECAY register of requested voice/operator */
- reg_val = fm->op[i].attack_decay;
- opl3_reg = reg_side | (OPL3_REG_ATTACK_DECAY + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- /* Set OPL3 SUSTAIN_RELEASE register of requested voice/operator */
- reg_val = fm->op[i].sustain_release;
- opl3_reg = reg_side | (OPL3_REG_SUSTAIN_RELEASE + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- /* Select waveform */
- reg_val = fm->op[i].wave_select;
- opl3_reg = reg_side | (OPL3_REG_WAVE_SELECT + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
- }
-
- /* Set operator feedback and 2op inter-operator connection */
- reg_val = fm->feedback_connection[0];
- /* Set output voice connection */
- reg_val |= OPL3_STEREO_BITS;
- if (chan->gm_pan < 43)
- reg_val &= ~OPL3_VOICE_TO_RIGHT;
- if (chan->gm_pan > 85)
- reg_val &= ~OPL3_VOICE_TO_LEFT;
- opl3_reg = reg_side | (OPL3_REG_FEEDBACK_CONNECTION + voice_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- if (instr_4op) {
- /* Set 4op inter-operator connection */
- reg_val = fm->feedback_connection[1] & OPL3_CONNECTION_BIT;
- /* Set output voice connection */
- reg_val |= OPL3_STEREO_BITS;
- if (chan->gm_pan < 43)
- reg_val &= ~OPL3_VOICE_TO_RIGHT;
- if (chan->gm_pan > 85)
- reg_val &= ~OPL3_VOICE_TO_LEFT;
- opl3_reg = reg_side | (OPL3_REG_FEEDBACK_CONNECTION +
- voice_offset + 3);
- opl3->command(opl3, opl3_reg, reg_val);
- }
-
- /*
- * Special treatment of percussion notes for fm:
- * Requested pitch is really program, and pitch for
- * device is whatever was specified in the patch library.
- */
- if (fm->fix_key)
- note = fm->fix_key;
- /*
- * use transpose if defined in patch library
- */
- if (fm->trnsps)
- note += (fm->trnsps - 64);
-
- snd_opl3_calc_pitch(&fnum, &blocknum, note, chan);
-
- /* Set OPL3 FNUM_LOW register of requested voice */
- opl3_reg = reg_side | (OPL3_REG_FNUM_LOW + voice_offset);
- opl3->command(opl3, opl3_reg, fnum);
-
- opl3->voices[voice].keyon_reg = blocknum;
-
- /* Set output sound flag */
- blocknum |= OPL3_KEYON_BIT;
-
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG " --> trigger voice %i\n", voice);
-#endif
- /* Set OPL3 KEYON_BLOCK register of requested voice */
- opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
- opl3->command(opl3, opl3_reg, blocknum);
-
- /* kill note after fixed duration (in centiseconds) */
- if (fm->fix_dur) {
- opl3->voices[voice].note_off = jiffies +
- (fm->fix_dur * HZ) / 100;
- snd_opl3_start_timer(opl3);
- opl3->voices[voice].note_off_check = 1;
- } else
- opl3->voices[voice].note_off_check = 0;
-
- /* get extra pgm, but avoid possible loops */
- extra_prg = (extra_prg) ? 0 : fm->modes;
-
- /* do the bookkeeping */
- vp->time = opl3->use_time++;
- vp->note = key;
- vp->chan = chan;
-
- if (instr_4op) {
- vp->state = SNDRV_OPL3_ST_ON_4OP;
-
- vp2 = &opl3->voices[voice + 3];
- vp2->time = opl3->use_time++;
- vp2->note = key;
- vp2->chan = chan;
- vp2->state = SNDRV_OPL3_ST_NOT_AVAIL;
- } else {
- if (vp->state == SNDRV_OPL3_ST_ON_4OP) {
- /* 4op killed by 2op, release bounded voice */
- vp2 = &opl3->voices[voice + 3];
- vp2->time = opl3->use_time++;
- vp2->state = SNDRV_OPL3_ST_OFF;
- }
- vp->state = SNDRV_OPL3_ST_ON_2OP;
- }
-
-#ifdef DEBUG_ALLOC
- debug_alloc(opl3, "note on ", voice);
-#endif
-
- /* allocate extra program if specified in patch library */
- if (extra_prg) {
- if (extra_prg > 128) {
- bank = 128;
- /* percussions start at 35 */
- prg = extra_prg - 128 + 35 - 1;
- } else {
- bank = 0;
- prg = extra_prg - 1;
- }
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG " *** allocating extra program\n");
-#endif
- goto __extra_prg;
- }
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
-}
-
-static void snd_opl3_kill_voice(struct snd_opl3 *opl3, int voice)
-{
- unsigned short reg_side;
- unsigned char voice_offset;
- unsigned short opl3_reg;
-
- struct snd_opl3_voice *vp, *vp2;
-
- if (snd_BUG_ON(voice >= MAX_OPL3_VOICES))
- return;
-
- vp = &opl3->voices[voice];
- if (voice < MAX_OPL2_VOICES) {
- /* Left register block for voices 0 .. 8 */
- reg_side = OPL3_LEFT;
- voice_offset = voice;
- } else {
- /* Right register block for voices 9 .. 17 */
- reg_side = OPL3_RIGHT;
- voice_offset = voice - MAX_OPL2_VOICES;
- }
-
- /* kill voice */
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG " --> kill voice %i\n", voice);
-#endif
- opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
- /* clear Key ON bit */
- opl3->command(opl3, opl3_reg, vp->keyon_reg);
-
- /* do the bookkeeping */
- vp->time = opl3->use_time++;
-
- if (vp->state == SNDRV_OPL3_ST_ON_4OP) {
- vp2 = &opl3->voices[voice + 3];
-
- vp2->time = opl3->use_time++;
- vp2->state = SNDRV_OPL3_ST_OFF;
- }
- vp->state = SNDRV_OPL3_ST_OFF;
-#ifdef DEBUG_ALLOC
- debug_alloc(opl3, "note off", voice);
-#endif
-
-}
-
-/*
- * Release a note in response to a midi note off.
- */
-static void snd_opl3_note_off_unsafe(void *p, int note, int vel,
- struct snd_midi_channel *chan)
-{
- struct snd_opl3 *opl3;
-
- int voice;
- struct snd_opl3_voice *vp;
-
- opl3 = p;
-
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG "Note off, ch %i, inst %i, note %i\n",
- chan->number, chan->midi_program, note);
-#endif
-
- if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
- if (chan->drum_channel && use_internal_drums) {
- snd_opl3_drum_switch(opl3, note, vel, 0, chan);
- return;
- }
- /* this loop will hopefully kill all extra voices, because
- they are grouped by the same channel and note values */
- for (voice = 0; voice < opl3->max_voices; voice++) {
- vp = &opl3->voices[voice];
- if (vp->state > 0 && vp->chan == chan && vp->note == note) {
- snd_opl3_kill_voice(opl3, voice);
- }
- }
- } else {
- /* remap OSS voices */
- if (chan->number < MAX_OPL3_VOICES) {
- voice = snd_opl3_oss_map[chan->number];
- snd_opl3_kill_voice(opl3, voice);
- }
- }
-}
-
-void snd_opl3_note_off(void *p, int note, int vel,
- struct snd_midi_channel *chan)
-{
- struct snd_opl3 *opl3 = p;
- unsigned long flags;
-
- spin_lock_irqsave(&opl3->voice_lock, flags);
- snd_opl3_note_off_unsafe(p, note, vel, chan);
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
-}
-
-/*
- * key pressure change
- */
-void snd_opl3_key_press(void *p, int note, int vel, struct snd_midi_channel *chan)
-{
- struct snd_opl3 *opl3;
-
- opl3 = p;
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG "Key pressure, ch#: %i, inst#: %i\n",
- chan->number, chan->midi_program);
-#endif
-}
-
-/*
- * terminate note
- */
-void snd_opl3_terminate_note(void *p, int note, struct snd_midi_channel *chan)
-{
- struct snd_opl3 *opl3;
-
- opl3 = p;
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG "Terminate note, ch#: %i, inst#: %i\n",
- chan->number, chan->midi_program);
-#endif
-}
-
-static void snd_opl3_update_pitch(struct snd_opl3 *opl3, int voice)
-{
- unsigned short reg_side;
- unsigned char voice_offset;
- unsigned short opl3_reg;
-
- unsigned char fnum, blocknum;
-
- struct snd_opl3_voice *vp;
-
- if (snd_BUG_ON(voice >= MAX_OPL3_VOICES))
- return;
-
- vp = &opl3->voices[voice];
- if (vp->chan == NULL)
- return; /* not allocated? */
-
- if (voice < MAX_OPL2_VOICES) {
- /* Left register block for voices 0 .. 8 */
- reg_side = OPL3_LEFT;
- voice_offset = voice;
- } else {
- /* Right register block for voices 9 .. 17 */
- reg_side = OPL3_RIGHT;
- voice_offset = voice - MAX_OPL2_VOICES;
- }
-
- snd_opl3_calc_pitch(&fnum, &blocknum, vp->note, vp->chan);
-
- /* Set OPL3 FNUM_LOW register of requested voice */
- opl3_reg = reg_side | (OPL3_REG_FNUM_LOW + voice_offset);
- opl3->command(opl3, opl3_reg, fnum);
-
- vp->keyon_reg = blocknum;
-
- /* Set output sound flag */
- blocknum |= OPL3_KEYON_BIT;
-
- /* Set OPL3 KEYON_BLOCK register of requested voice */
- opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
- opl3->command(opl3, opl3_reg, blocknum);
-
- vp->time = opl3->use_time++;
-}
-
-/*
- * Update voice pitch controller
- */
-static void snd_opl3_pitch_ctrl(struct snd_opl3 *opl3, struct snd_midi_channel *chan)
-{
- int voice;
- struct snd_opl3_voice *vp;
-
- unsigned long flags;
-
- spin_lock_irqsave(&opl3->voice_lock, flags);
-
- if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
- for (voice = 0; voice < opl3->max_voices; voice++) {
- vp = &opl3->voices[voice];
- if (vp->state > 0 && vp->chan == chan) {
- snd_opl3_update_pitch(opl3, voice);
- }
- }
- } else {
- /* remap OSS voices */
- if (chan->number < MAX_OPL3_VOICES) {
- voice = snd_opl3_oss_map[chan->number];
- snd_opl3_update_pitch(opl3, voice);
- }
- }
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
-}
-
-/*
- * Deal with a controller type event. This includes all types of
- * control events, not just the midi controllers
- */
-void snd_opl3_control(void *p, int type, struct snd_midi_channel *chan)
-{
- struct snd_opl3 *opl3;
-
- opl3 = p;
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG "Controller, TYPE = %i, ch#: %i, inst#: %i\n",
- type, chan->number, chan->midi_program);
-#endif
-
- switch (type) {
- case MIDI_CTL_MSB_MODWHEEL:
- if (chan->control[MIDI_CTL_MSB_MODWHEEL] > 63)
- opl3->drum_reg |= OPL3_VIBRATO_DEPTH;
- else
- opl3->drum_reg &= ~OPL3_VIBRATO_DEPTH;
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION,
- opl3->drum_reg);
- break;
- case MIDI_CTL_E2_TREMOLO_DEPTH:
- if (chan->control[MIDI_CTL_E2_TREMOLO_DEPTH] > 63)
- opl3->drum_reg |= OPL3_TREMOLO_DEPTH;
- else
- opl3->drum_reg &= ~OPL3_TREMOLO_DEPTH;
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION,
- opl3->drum_reg);
- break;
- case MIDI_CTL_PITCHBEND:
- snd_opl3_pitch_ctrl(opl3, chan);
- break;
- }
-}
-
-/*
- * NRPN events
- */
-void snd_opl3_nrpn(void *p, struct snd_midi_channel *chan,
- struct snd_midi_channel_set *chset)
-{
- struct snd_opl3 *opl3;
-
- opl3 = p;
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG "NRPN, ch#: %i, inst#: %i\n",
- chan->number, chan->midi_program);
-#endif
-}
-
-/*
- * receive sysex
- */
-void snd_opl3_sysex(void *p, unsigned char *buf, int len,
- int parsed, struct snd_midi_channel_set *chset)
-{
- struct snd_opl3 *opl3;
-
- opl3 = p;
-#ifdef DEBUG_MIDI
- snd_printk(KERN_DEBUG "SYSEX\n");
-#endif
-}
diff --git a/ANDROID_3.4.5/sound/drivers/opl3/opl3_oss.c b/ANDROID_3.4.5/sound/drivers/opl3/opl3_oss.c
deleted file mode 100644
index c1cb249a..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl3/opl3_oss.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Interface for OSS sequencer emulation
- *
- * Copyright (C) 2000 Uros Bizjak <uros@kss-loka.si>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/export.h>
-#include "opl3_voice.h"
-
-static int snd_opl3_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure);
-static int snd_opl3_close_seq_oss(struct snd_seq_oss_arg *arg);
-static int snd_opl3_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd, unsigned long ioarg);
-static int snd_opl3_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format, const char __user *buf, int offs, int count);
-static int snd_opl3_reset_seq_oss(struct snd_seq_oss_arg *arg);
-
-/* */
-
-static inline mm_segment_t snd_enter_user(void)
-{
- mm_segment_t fs = get_fs();
- set_fs(get_ds());
- return fs;
-}
-
-static inline void snd_leave_user(mm_segment_t fs)
-{
- set_fs(fs);
-}
-
-/* operators */
-
-extern struct snd_midi_op opl3_ops;
-
-static struct snd_seq_oss_callback oss_callback = {
- .owner = THIS_MODULE,
- .open = snd_opl3_open_seq_oss,
- .close = snd_opl3_close_seq_oss,
- .ioctl = snd_opl3_ioctl_seq_oss,
- .load_patch = snd_opl3_load_patch_seq_oss,
- .reset = snd_opl3_reset_seq_oss,
-};
-
-static int snd_opl3_oss_event_input(struct snd_seq_event *ev, int direct,
- void *private_data, int atomic, int hop)
-{
- struct snd_opl3 *opl3 = private_data;
-
- if (ev->type != SNDRV_SEQ_EVENT_OSS)
- snd_midi_process_event(&opl3_ops, ev, opl3->oss_chset);
- return 0;
-}
-
-/* ------------------------------ */
-
-static void snd_opl3_oss_free_port(void *private_data)
-{
- struct snd_opl3 *opl3 = private_data;
-
- snd_midi_channel_free_set(opl3->oss_chset);
-}
-
-static int snd_opl3_oss_create_port(struct snd_opl3 * opl3)
-{
- struct snd_seq_port_callback callbacks;
- char name[32];
- int voices, opl_ver;
-
- voices = (opl3->hardware < OPL3_HW_OPL3) ?
- MAX_OPL2_VOICES : MAX_OPL3_VOICES;
- opl3->oss_chset = snd_midi_channel_alloc_set(voices);
- if (opl3->oss_chset == NULL)
- return -ENOMEM;
- opl3->oss_chset->private_data = opl3;
-
- memset(&callbacks, 0, sizeof(callbacks));
- callbacks.owner = THIS_MODULE;
- callbacks.event_input = snd_opl3_oss_event_input;
- callbacks.private_free = snd_opl3_oss_free_port;
- callbacks.private_data = opl3;
-
- opl_ver = (opl3->hardware & OPL3_HW_MASK) >> 8;
- sprintf(name, "OPL%i OSS Port", opl_ver);
-
- opl3->oss_chset->client = opl3->seq_client;
- opl3->oss_chset->port = snd_seq_event_port_attach(opl3->seq_client, &callbacks,
- SNDRV_SEQ_PORT_CAP_WRITE,
- SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
- SNDRV_SEQ_PORT_TYPE_MIDI_GM |
- SNDRV_SEQ_PORT_TYPE_HARDWARE |
- SNDRV_SEQ_PORT_TYPE_SYNTHESIZER,
- voices, voices,
- name);
- if (opl3->oss_chset->port < 0) {
- int port;
- port = opl3->oss_chset->port;
- snd_midi_channel_free_set(opl3->oss_chset);
- return port;
- }
- return 0;
-}
-
-/* ------------------------------ */
-
-/* register OSS synth */
-void snd_opl3_init_seq_oss(struct snd_opl3 *opl3, char *name)
-{
- struct snd_seq_oss_reg *arg;
- struct snd_seq_device *dev;
-
- if (snd_seq_device_new(opl3->card, 0, SNDRV_SEQ_DEV_ID_OSS,
- sizeof(struct snd_seq_oss_reg), &dev) < 0)
- return;
-
- opl3->oss_seq_dev = dev;
- strlcpy(dev->name, name, sizeof(dev->name));
- arg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
- arg->type = SYNTH_TYPE_FM;
- if (opl3->hardware < OPL3_HW_OPL3) {
- arg->subtype = FM_TYPE_ADLIB;
- arg->nvoices = MAX_OPL2_VOICES;
- } else {
- arg->subtype = FM_TYPE_OPL3;
- arg->nvoices = MAX_OPL3_VOICES;
- }
- arg->oper = oss_callback;
- arg->private_data = opl3;
-
- if (snd_opl3_oss_create_port(opl3)) {
- /* register to OSS synth table */
- snd_device_register(opl3->card, dev);
- }
-}
-
-/* unregister */
-void snd_opl3_free_seq_oss(struct snd_opl3 *opl3)
-{
- if (opl3->oss_seq_dev) {
- /* The instance should have been released in prior */
- opl3->oss_seq_dev = NULL;
- }
-}
-
-/* ------------------------------ */
-
-/* open OSS sequencer */
-static int snd_opl3_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure)
-{
- struct snd_opl3 *opl3 = closure;
- int err;
-
- if (snd_BUG_ON(!arg))
- return -ENXIO;
-
- if ((err = snd_opl3_synth_setup(opl3)) < 0)
- return err;
-
- /* fill the argument data */
- arg->private_data = opl3;
- arg->addr.client = opl3->oss_chset->client;
- arg->addr.port = opl3->oss_chset->port;
-
- if ((err = snd_opl3_synth_use_inc(opl3)) < 0)
- return err;
-
- opl3->synth_mode = SNDRV_OPL3_MODE_SYNTH;
- return 0;
-}
-
-/* close OSS sequencer */
-static int snd_opl3_close_seq_oss(struct snd_seq_oss_arg *arg)
-{
- struct snd_opl3 *opl3;
-
- if (snd_BUG_ON(!arg))
- return -ENXIO;
- opl3 = arg->private_data;
-
- snd_opl3_synth_cleanup(opl3);
-
- snd_opl3_synth_use_dec(opl3);
- return 0;
-}
-
-/* load patch */
-
-/* from sound_config.h */
-#define SBFM_MAXINSTR 256
-
-static int snd_opl3_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format,
- const char __user *buf, int offs, int count)
-{
- struct snd_opl3 *opl3;
- struct sbi_instrument sbi;
- char name[32];
- int err, type;
-
- if (snd_BUG_ON(!arg))
- return -ENXIO;
- opl3 = arg->private_data;
-
- if (format == FM_PATCH)
- type = FM_PATCH_OPL2;
- else if (format == OPL3_PATCH)
- type = FM_PATCH_OPL3;
- else
- return -EINVAL;
-
- if (count < (int)sizeof(sbi)) {
- snd_printk(KERN_ERR "FM Error: Patch record too short\n");
- return -EINVAL;
- }
- if (copy_from_user(&sbi, buf, sizeof(sbi)))
- return -EFAULT;
-
- if (sbi.channel < 0 || sbi.channel >= SBFM_MAXINSTR) {
- snd_printk(KERN_ERR "FM Error: Invalid instrument number %d\n",
- sbi.channel);
- return -EINVAL;
- }
-
- memset(name, 0, sizeof(name));
- sprintf(name, "Chan%d", sbi.channel);
-
- err = snd_opl3_load_patch(opl3, sbi.channel, 127, type, name, NULL,
- sbi.operators);
- if (err < 0)
- return err;
-
- return sizeof(sbi);
-}
-
-/* ioctl */
-static int snd_opl3_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd,
- unsigned long ioarg)
-{
- struct snd_opl3 *opl3;
-
- if (snd_BUG_ON(!arg))
- return -ENXIO;
- opl3 = arg->private_data;
- switch (cmd) {
- case SNDCTL_FM_LOAD_INSTR:
- snd_printk(KERN_ERR "OPL3: "
- "Obsolete ioctl(SNDCTL_FM_LOAD_INSTR) used. "
- "Fix the program.\n");
- return -EINVAL;
-
- case SNDCTL_SYNTH_MEMAVL:
- return 0x7fffffff;
-
- case SNDCTL_FM_4OP_ENABLE:
- // handled automatically by OPL instrument type
- return 0;
-
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-/* reset device */
-static int snd_opl3_reset_seq_oss(struct snd_seq_oss_arg *arg)
-{
- struct snd_opl3 *opl3;
-
- if (snd_BUG_ON(!arg))
- return -ENXIO;
- opl3 = arg->private_data;
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/drivers/opl3/opl3_seq.c b/ANDROID_3.4.5/sound/drivers/opl3/opl3_seq.c
deleted file mode 100644
index 68399538..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl3/opl3_seq.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (c) by Uros Bizjak <uros@kss-loka.si>
- *
- * Midi Sequencer interface routines for OPL2/OPL3/OPL4 FM
- *
- * OPL2/3 FM instrument loader:
- * alsa-tools/seq/sbiload/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "opl3_voice.h"
-#include <linux/init.h>
-#include <linux/moduleparam.h>
-#include <linux/module.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Uros Bizjak <uros@kss-loka.si>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("ALSA driver for OPL3 FM synth");
-
-bool use_internal_drums = 0;
-module_param(use_internal_drums, bool, 0444);
-MODULE_PARM_DESC(use_internal_drums, "Enable internal OPL2/3 drums.");
-
-int snd_opl3_synth_use_inc(struct snd_opl3 * opl3)
-{
- if (!try_module_get(opl3->card->module))
- return -EFAULT;
- return 0;
-
-}
-
-void snd_opl3_synth_use_dec(struct snd_opl3 * opl3)
-{
- module_put(opl3->card->module);
-}
-
-int snd_opl3_synth_setup(struct snd_opl3 * opl3)
-{
- int idx;
- struct snd_hwdep *hwdep = opl3->hwdep;
-
- mutex_lock(&hwdep->open_mutex);
- if (hwdep->used) {
- mutex_unlock(&hwdep->open_mutex);
- return -EBUSY;
- }
- hwdep->used++;
- mutex_unlock(&hwdep->open_mutex);
-
- snd_opl3_reset(opl3);
-
- for (idx = 0; idx < MAX_OPL3_VOICES; idx++) {
- opl3->voices[idx].state = SNDRV_OPL3_ST_OFF;
- opl3->voices[idx].time = 0;
- opl3->voices[idx].keyon_reg = 0x00;
- }
- opl3->use_time = 0;
- opl3->connection_reg = 0x00;
- if (opl3->hardware >= OPL3_HW_OPL3) {
- /* Clear 4-op connections */
- opl3->command(opl3, OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT,
- opl3->connection_reg);
- opl3->max_voices = MAX_OPL3_VOICES;
- }
- return 0;
-}
-
-void snd_opl3_synth_cleanup(struct snd_opl3 * opl3)
-{
- unsigned long flags;
- struct snd_hwdep *hwdep;
-
- /* Stop system timer */
- spin_lock_irqsave(&opl3->sys_timer_lock, flags);
- if (opl3->sys_timer_status) {
- del_timer(&opl3->tlist);
- opl3->sys_timer_status = 0;
- }
- spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
-
- snd_opl3_reset(opl3);
- hwdep = opl3->hwdep;
- mutex_lock(&hwdep->open_mutex);
- hwdep->used--;
- mutex_unlock(&hwdep->open_mutex);
- wake_up(&hwdep->open_wait);
-}
-
-static int snd_opl3_synth_use(void *private_data, struct snd_seq_port_subscribe * info)
-{
- struct snd_opl3 *opl3 = private_data;
- int err;
-
- if ((err = snd_opl3_synth_setup(opl3)) < 0)
- return err;
-
- if (use_internal_drums) {
- /* Percussion mode */
- opl3->voices[6].state = opl3->voices[7].state =
- opl3->voices[8].state = SNDRV_OPL3_ST_NOT_AVAIL;
- snd_opl3_load_drums(opl3);
- opl3->drum_reg = OPL3_PERCUSSION_ENABLE;
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, opl3->drum_reg);
- } else {
- opl3->drum_reg = 0x00;
- }
-
- if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM) {
- if ((err = snd_opl3_synth_use_inc(opl3)) < 0)
- return err;
- }
- opl3->synth_mode = SNDRV_OPL3_MODE_SEQ;
- return 0;
-}
-
-static int snd_opl3_synth_unuse(void *private_data, struct snd_seq_port_subscribe * info)
-{
- struct snd_opl3 *opl3 = private_data;
-
- snd_opl3_synth_cleanup(opl3);
-
- if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM)
- snd_opl3_synth_use_dec(opl3);
- return 0;
-}
-
-/*
- * MIDI emulation operators
- */
-struct snd_midi_op opl3_ops = {
- .note_on = snd_opl3_note_on,
- .note_off = snd_opl3_note_off,
- .key_press = snd_opl3_key_press,
- .note_terminate = snd_opl3_terminate_note,
- .control = snd_opl3_control,
- .nrpn = snd_opl3_nrpn,
- .sysex = snd_opl3_sysex,
-};
-
-static int snd_opl3_synth_event_input(struct snd_seq_event * ev, int direct,
- void *private_data, int atomic, int hop)
-{
- struct snd_opl3 *opl3 = private_data;
-
- snd_midi_process_event(&opl3_ops, ev, opl3->chset);
- return 0;
-}
-
-/* ------------------------------ */
-
-static void snd_opl3_synth_free_port(void *private_data)
-{
- struct snd_opl3 *opl3 = private_data;
-
- snd_midi_channel_free_set(opl3->chset);
-}
-
-static int snd_opl3_synth_create_port(struct snd_opl3 * opl3)
-{
- struct snd_seq_port_callback callbacks;
- char name[32];
- int voices, opl_ver;
-
- voices = (opl3->hardware < OPL3_HW_OPL3) ?
- MAX_OPL2_VOICES : MAX_OPL3_VOICES;
- opl3->chset = snd_midi_channel_alloc_set(16);
- if (opl3->chset == NULL)
- return -ENOMEM;
- opl3->chset->private_data = opl3;
-
- memset(&callbacks, 0, sizeof(callbacks));
- callbacks.owner = THIS_MODULE;
- callbacks.use = snd_opl3_synth_use;
- callbacks.unuse = snd_opl3_synth_unuse;
- callbacks.event_input = snd_opl3_synth_event_input;
- callbacks.private_free = snd_opl3_synth_free_port;
- callbacks.private_data = opl3;
-
- opl_ver = (opl3->hardware & OPL3_HW_MASK) >> 8;
- sprintf(name, "OPL%i FM Port", opl_ver);
-
- opl3->chset->client = opl3->seq_client;
- opl3->chset->port = snd_seq_event_port_attach(opl3->seq_client, &callbacks,
- SNDRV_SEQ_PORT_CAP_WRITE |
- SNDRV_SEQ_PORT_CAP_SUBS_WRITE,
- SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
- SNDRV_SEQ_PORT_TYPE_MIDI_GM |
- SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE |
- SNDRV_SEQ_PORT_TYPE_HARDWARE |
- SNDRV_SEQ_PORT_TYPE_SYNTHESIZER,
- 16, voices,
- name);
- if (opl3->chset->port < 0) {
- int port;
- port = opl3->chset->port;
- snd_midi_channel_free_set(opl3->chset);
- return port;
- }
- return 0;
-}
-
-/* ------------------------------ */
-
-static int snd_opl3_seq_new_device(struct snd_seq_device *dev)
-{
- struct snd_opl3 *opl3;
- int client, err;
- char name[32];
- int opl_ver;
-
- opl3 = *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
- if (opl3 == NULL)
- return -EINVAL;
-
- spin_lock_init(&opl3->voice_lock);
-
- opl3->seq_client = -1;
-
- /* allocate new client */
- opl_ver = (opl3->hardware & OPL3_HW_MASK) >> 8;
- sprintf(name, "OPL%i FM synth", opl_ver);
- client = opl3->seq_client =
- snd_seq_create_kernel_client(opl3->card, opl3->seq_dev_num,
- name);
- if (client < 0)
- return client;
-
- if ((err = snd_opl3_synth_create_port(opl3)) < 0) {
- snd_seq_delete_kernel_client(client);
- opl3->seq_client = -1;
- return err;
- }
-
- /* setup system timer */
- init_timer(&opl3->tlist);
- opl3->tlist.function = snd_opl3_timer_func;
- opl3->tlist.data = (unsigned long) opl3;
- spin_lock_init(&opl3->sys_timer_lock);
- opl3->sys_timer_status = 0;
-
-#ifdef CONFIG_SND_SEQUENCER_OSS
- snd_opl3_init_seq_oss(opl3, name);
-#endif
- return 0;
-}
-
-static int snd_opl3_seq_delete_device(struct snd_seq_device *dev)
-{
- struct snd_opl3 *opl3;
-
- opl3 = *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
- if (opl3 == NULL)
- return -EINVAL;
-
-#ifdef CONFIG_SND_SEQUENCER_OSS
- snd_opl3_free_seq_oss(opl3);
-#endif
- if (opl3->seq_client >= 0) {
- snd_seq_delete_kernel_client(opl3->seq_client);
- opl3->seq_client = -1;
- }
- return 0;
-}
-
-static int __init alsa_opl3_seq_init(void)
-{
- static struct snd_seq_dev_ops ops =
- {
- snd_opl3_seq_new_device,
- snd_opl3_seq_delete_device
- };
-
- return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_OPL3, &ops,
- sizeof(struct snd_opl3 *));
-}
-
-static void __exit alsa_opl3_seq_exit(void)
-{
- snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_OPL3);
-}
-
-module_init(alsa_opl3_seq_init)
-module_exit(alsa_opl3_seq_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/opl3/opl3_synth.c b/ANDROID_3.4.5/sound/drivers/opl3/opl3_synth.c
deleted file mode 100644
index 742a4b64..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl3/opl3_synth.c
+++ /dev/null
@@ -1,616 +0,0 @@
-/*
- * Copyright (c) by Uros Bizjak <uros@kss-loka.si>
- *
- * Routines for OPL2/OPL3/OPL4 control
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/slab.h>
-#include <linux/export.h>
-#include <sound/opl3.h>
-#include <sound/asound_fm.h>
-
-#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
-#define OPL3_SUPPORT_SYNTH
-#endif
-
-/*
- * There is 18 possible 2 OP voices
- * (9 in the left and 9 in the right).
- * The first OP is the modulator and 2nd is the carrier.
- *
- * The first three voices in the both sides may be connected
- * with another voice to a 4 OP voice. For example voice 0
- * can be connected with voice 3. The operators of voice 3 are
- * used as operators 3 and 4 of the new 4 OP voice.
- * In this case the 2 OP voice number 0 is the 'first half' and
- * voice 3 is the second.
- */
-
-
-/*
- * Register offset table for OPL2/3 voices,
- * OPL2 / one OPL3 register array side only
- */
-
-char snd_opl3_regmap[MAX_OPL2_VOICES][4] =
-{
-/* OP1 OP2 OP3 OP4 */
-/* ------------------------ */
- { 0x00, 0x03, 0x08, 0x0b },
- { 0x01, 0x04, 0x09, 0x0c },
- { 0x02, 0x05, 0x0a, 0x0d },
-
- { 0x08, 0x0b, 0x00, 0x00 },
- { 0x09, 0x0c, 0x00, 0x00 },
- { 0x0a, 0x0d, 0x00, 0x00 },
-
- { 0x10, 0x13, 0x00, 0x00 }, /* used by percussive voices */
- { 0x11, 0x14, 0x00, 0x00 }, /* if the percussive mode */
- { 0x12, 0x15, 0x00, 0x00 } /* is selected (only left reg block) */
-};
-
-EXPORT_SYMBOL(snd_opl3_regmap);
-
-/*
- * prototypes
- */
-static int snd_opl3_play_note(struct snd_opl3 * opl3, struct snd_dm_fm_note * note);
-static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * voice);
-static int snd_opl3_set_params(struct snd_opl3 * opl3, struct snd_dm_fm_params * params);
-static int snd_opl3_set_mode(struct snd_opl3 * opl3, int mode);
-static int snd_opl3_set_connection(struct snd_opl3 * opl3, int connection);
-
-/* ------------------------------ */
-
-/*
- * open the device exclusively
- */
-int snd_opl3_open(struct snd_hwdep * hw, struct file *file)
-{
- return 0;
-}
-
-/*
- * ioctl for hwdep device:
- */
-int snd_opl3_ioctl(struct snd_hwdep * hw, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct snd_opl3 *opl3 = hw->private_data;
- void __user *argp = (void __user *)arg;
-
- if (snd_BUG_ON(!opl3))
- return -EINVAL;
-
- switch (cmd) {
- /* get information */
- case SNDRV_DM_FM_IOCTL_INFO:
- {
- struct snd_dm_fm_info info;
-
- info.fm_mode = opl3->fm_mode;
- info.rhythm = opl3->rhythm;
- if (copy_to_user(argp, &info, sizeof(struct snd_dm_fm_info)))
- return -EFAULT;
- return 0;
- }
-
- case SNDRV_DM_FM_IOCTL_RESET:
-#ifdef CONFIG_SND_OSSEMUL
- case SNDRV_DM_FM_OSS_IOCTL_RESET:
-#endif
- snd_opl3_reset(opl3);
- return 0;
-
- case SNDRV_DM_FM_IOCTL_PLAY_NOTE:
-#ifdef CONFIG_SND_OSSEMUL
- case SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE:
-#endif
- {
- struct snd_dm_fm_note note;
- if (copy_from_user(&note, argp, sizeof(struct snd_dm_fm_note)))
- return -EFAULT;
- return snd_opl3_play_note(opl3, &note);
- }
-
- case SNDRV_DM_FM_IOCTL_SET_VOICE:
-#ifdef CONFIG_SND_OSSEMUL
- case SNDRV_DM_FM_OSS_IOCTL_SET_VOICE:
-#endif
- {
- struct snd_dm_fm_voice voice;
- if (copy_from_user(&voice, argp, sizeof(struct snd_dm_fm_voice)))
- return -EFAULT;
- return snd_opl3_set_voice(opl3, &voice);
- }
-
- case SNDRV_DM_FM_IOCTL_SET_PARAMS:
-#ifdef CONFIG_SND_OSSEMUL
- case SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS:
-#endif
- {
- struct snd_dm_fm_params params;
- if (copy_from_user(&params, argp, sizeof(struct snd_dm_fm_params)))
- return -EFAULT;
- return snd_opl3_set_params(opl3, &params);
- }
-
- case SNDRV_DM_FM_IOCTL_SET_MODE:
-#ifdef CONFIG_SND_OSSEMUL
- case SNDRV_DM_FM_OSS_IOCTL_SET_MODE:
-#endif
- return snd_opl3_set_mode(opl3, (int) arg);
-
- case SNDRV_DM_FM_IOCTL_SET_CONNECTION:
-#ifdef CONFIG_SND_OSSEMUL
- case SNDRV_DM_FM_OSS_IOCTL_SET_OPL:
-#endif
- return snd_opl3_set_connection(opl3, (int) arg);
-
-#ifdef OPL3_SUPPORT_SYNTH
- case SNDRV_DM_FM_IOCTL_CLEAR_PATCHES:
- snd_opl3_clear_patches(opl3);
- return 0;
-#endif
-
-#ifdef CONFIG_SND_DEBUG
- default:
- snd_printk(KERN_WARNING "unknown IOCTL: 0x%x\n", cmd);
-#endif
- }
- return -ENOTTY;
-}
-
-/*
- * close the device
- */
-int snd_opl3_release(struct snd_hwdep * hw, struct file *file)
-{
- struct snd_opl3 *opl3 = hw->private_data;
-
- snd_opl3_reset(opl3);
- return 0;
-}
-
-#ifdef OPL3_SUPPORT_SYNTH
-/*
- * write the device - load patches
- */
-long snd_opl3_write(struct snd_hwdep *hw, const char __user *buf, long count,
- loff_t *offset)
-{
- struct snd_opl3 *opl3 = hw->private_data;
- long result = 0;
- int err = 0;
- struct sbi_patch inst;
-
- while (count >= sizeof(inst)) {
- unsigned char type;
- if (copy_from_user(&inst, buf, sizeof(inst)))
- return -EFAULT;
- if (!memcmp(inst.key, FM_KEY_SBI, 4) ||
- !memcmp(inst.key, FM_KEY_2OP, 4))
- type = FM_PATCH_OPL2;
- else if (!memcmp(inst.key, FM_KEY_4OP, 4))
- type = FM_PATCH_OPL3;
- else /* invalid type */
- break;
- err = snd_opl3_load_patch(opl3, inst.prog, inst.bank, type,
- inst.name, inst.extension,
- inst.data);
- if (err < 0)
- break;
- result += sizeof(inst);
- count -= sizeof(inst);
- }
- return result > 0 ? result : err;
-}
-
-
-/*
- * Patch management
- */
-
-/* offsets for SBI params */
-#define AM_VIB 0
-#define KSL_LEVEL 2
-#define ATTACK_DECAY 4
-#define SUSTAIN_RELEASE 6
-#define WAVE_SELECT 8
-
-/* offset for SBI instrument */
-#define CONNECTION 10
-#define OFFSET_4OP 11
-
-/*
- * load a patch, obviously.
- *
- * loaded on the given program and bank numbers with the given type
- * (FM_PATCH_OPLx).
- * data is the pointer of SBI record _without_ header (key and name).
- * name is the name string of the patch.
- * ext is the extension data of 7 bytes long (stored in name of SBI
- * data up to offset 25), or NULL to skip.
- * return 0 if successful or a negative error code.
- */
-int snd_opl3_load_patch(struct snd_opl3 *opl3,
- int prog, int bank, int type,
- const char *name,
- const unsigned char *ext,
- const unsigned char *data)
-{
- struct fm_patch *patch;
- int i;
-
- patch = snd_opl3_find_patch(opl3, prog, bank, 1);
- if (!patch)
- return -ENOMEM;
-
- patch->type = type;
-
- for (i = 0; i < 2; i++) {
- patch->inst.op[i].am_vib = data[AM_VIB + i];
- patch->inst.op[i].ksl_level = data[KSL_LEVEL + i];
- patch->inst.op[i].attack_decay = data[ATTACK_DECAY + i];
- patch->inst.op[i].sustain_release = data[SUSTAIN_RELEASE + i];
- patch->inst.op[i].wave_select = data[WAVE_SELECT + i];
- }
- patch->inst.feedback_connection[0] = data[CONNECTION];
-
- if (type == FM_PATCH_OPL3) {
- for (i = 0; i < 2; i++) {
- patch->inst.op[i+2].am_vib =
- data[OFFSET_4OP + AM_VIB + i];
- patch->inst.op[i+2].ksl_level =
- data[OFFSET_4OP + KSL_LEVEL + i];
- patch->inst.op[i+2].attack_decay =
- data[OFFSET_4OP + ATTACK_DECAY + i];
- patch->inst.op[i+2].sustain_release =
- data[OFFSET_4OP + SUSTAIN_RELEASE + i];
- patch->inst.op[i+2].wave_select =
- data[OFFSET_4OP + WAVE_SELECT + i];
- }
- patch->inst.feedback_connection[1] =
- data[OFFSET_4OP + CONNECTION];
- }
-
- if (ext) {
- patch->inst.echo_delay = ext[0];
- patch->inst.echo_atten = ext[1];
- patch->inst.chorus_spread = ext[2];
- patch->inst.trnsps = ext[3];
- patch->inst.fix_dur = ext[4];
- patch->inst.modes = ext[5];
- patch->inst.fix_key = ext[6];
- }
-
- if (name)
- strlcpy(patch->name, name, sizeof(patch->name));
-
- return 0;
-}
-EXPORT_SYMBOL(snd_opl3_load_patch);
-
-/*
- * find a patch with the given program and bank numbers, returns its pointer
- * if no matching patch is found and create_patch is set, it creates a
- * new patch object.
- */
-struct fm_patch *snd_opl3_find_patch(struct snd_opl3 *opl3, int prog, int bank,
- int create_patch)
-{
- /* pretty dumb hash key */
- unsigned int key = (prog + bank) % OPL3_PATCH_HASH_SIZE;
- struct fm_patch *patch;
-
- for (patch = opl3->patch_table[key]; patch; patch = patch->next) {
- if (patch->prog == prog && patch->bank == bank)
- return patch;
- }
- if (!create_patch)
- return NULL;
-
- patch = kzalloc(sizeof(*patch), GFP_KERNEL);
- if (!patch)
- return NULL;
- patch->prog = prog;
- patch->bank = bank;
- patch->next = opl3->patch_table[key];
- opl3->patch_table[key] = patch;
- return patch;
-}
-EXPORT_SYMBOL(snd_opl3_find_patch);
-
-/*
- * Clear all patches of the given OPL3 instance
- */
-void snd_opl3_clear_patches(struct snd_opl3 *opl3)
-{
- int i;
- for (i = 0; i < OPL3_PATCH_HASH_SIZE; i++) {
- struct fm_patch *patch, *next;
- for (patch = opl3->patch_table[i]; patch; patch = next) {
- next = patch->next;
- kfree(patch);
- }
- }
- memset(opl3->patch_table, 0, sizeof(opl3->patch_table));
-}
-#endif /* OPL3_SUPPORT_SYNTH */
-
-/* ------------------------------ */
-
-void snd_opl3_reset(struct snd_opl3 * opl3)
-{
- unsigned short opl3_reg;
-
- unsigned short reg_side;
- unsigned char voice_offset;
-
- int max_voices, i;
-
- max_voices = (opl3->hardware < OPL3_HW_OPL3) ?
- MAX_OPL2_VOICES : MAX_OPL3_VOICES;
-
- for (i = 0; i < max_voices; i++) {
- /* Get register array side and offset of voice */
- if (i < MAX_OPL2_VOICES) {
- /* Left register block for voices 0 .. 8 */
- reg_side = OPL3_LEFT;
- voice_offset = i;
- } else {
- /* Right register block for voices 9 .. 17 */
- reg_side = OPL3_RIGHT;
- voice_offset = i - MAX_OPL2_VOICES;
- }
- opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + snd_opl3_regmap[voice_offset][0]);
- opl3->command(opl3, opl3_reg, OPL3_TOTAL_LEVEL_MASK); /* Operator 1 volume */
- opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + snd_opl3_regmap[voice_offset][1]);
- opl3->command(opl3, opl3_reg, OPL3_TOTAL_LEVEL_MASK); /* Operator 2 volume */
-
- opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
- opl3->command(opl3, opl3_reg, 0x00); /* Note off */
- }
-
- opl3->max_voices = MAX_OPL2_VOICES;
- opl3->fm_mode = SNDRV_DM_FM_MODE_OPL2;
-
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_TEST, OPL3_ENABLE_WAVE_SELECT);
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 0x00); /* Melodic mode */
- opl3->rhythm = 0;
-}
-
-EXPORT_SYMBOL(snd_opl3_reset);
-
-static int snd_opl3_play_note(struct snd_opl3 * opl3, struct snd_dm_fm_note * note)
-{
- unsigned short reg_side;
- unsigned char voice_offset;
-
- unsigned short opl3_reg;
- unsigned char reg_val;
-
- /* Voices 0 - 8 in OPL2 mode */
- /* Voices 0 - 17 in OPL3 mode */
- if (note->voice >= ((opl3->fm_mode == SNDRV_DM_FM_MODE_OPL3) ?
- MAX_OPL3_VOICES : MAX_OPL2_VOICES))
- return -EINVAL;
-
- /* Get register array side and offset of voice */
- if (note->voice < MAX_OPL2_VOICES) {
- /* Left register block for voices 0 .. 8 */
- reg_side = OPL3_LEFT;
- voice_offset = note->voice;
- } else {
- /* Right register block for voices 9 .. 17 */
- reg_side = OPL3_RIGHT;
- voice_offset = note->voice - MAX_OPL2_VOICES;
- }
-
- /* Set lower 8 bits of note frequency */
- reg_val = (unsigned char) note->fnum;
- opl3_reg = reg_side | (OPL3_REG_FNUM_LOW + voice_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- reg_val = 0x00;
- /* Set output sound flag */
- if (note->key_on)
- reg_val |= OPL3_KEYON_BIT;
- /* Set octave */
- reg_val |= (note->octave << 2) & OPL3_BLOCKNUM_MASK;
- /* Set higher 2 bits of note frequency */
- reg_val |= (unsigned char) (note->fnum >> 8) & OPL3_FNUM_HIGH_MASK;
-
- /* Set OPL3 KEYON_BLOCK register of requested voice */
- opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- return 0;
-}
-
-
-static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * voice)
-{
- unsigned short reg_side;
- unsigned char op_offset;
- unsigned char voice_offset;
-
- unsigned short opl3_reg;
- unsigned char reg_val;
-
- /* Only operators 1 and 2 */
- if (voice->op > 1)
- return -EINVAL;
- /* Voices 0 - 8 in OPL2 mode */
- /* Voices 0 - 17 in OPL3 mode */
- if (voice->voice >= ((opl3->fm_mode == SNDRV_DM_FM_MODE_OPL3) ?
- MAX_OPL3_VOICES : MAX_OPL2_VOICES))
- return -EINVAL;
-
- /* Get register array side and offset of voice */
- if (voice->voice < MAX_OPL2_VOICES) {
- /* Left register block for voices 0 .. 8 */
- reg_side = OPL3_LEFT;
- voice_offset = voice->voice;
- } else {
- /* Right register block for voices 9 .. 17 */
- reg_side = OPL3_RIGHT;
- voice_offset = voice->voice - MAX_OPL2_VOICES;
- }
- /* Get register offset of operator */
- op_offset = snd_opl3_regmap[voice_offset][voice->op];
-
- reg_val = 0x00;
- /* Set amplitude modulation (tremolo) effect */
- if (voice->am)
- reg_val |= OPL3_TREMOLO_ON;
- /* Set vibrato effect */
- if (voice->vibrato)
- reg_val |= OPL3_VIBRATO_ON;
- /* Set sustaining sound phase */
- if (voice->do_sustain)
- reg_val |= OPL3_SUSTAIN_ON;
- /* Set keyboard scaling bit */
- if (voice->kbd_scale)
- reg_val |= OPL3_KSR;
- /* Set harmonic or frequency multiplier */
- reg_val |= voice->harmonic & OPL3_MULTIPLE_MASK;
-
- /* Set OPL3 AM_VIB register of requested voice/operator */
- opl3_reg = reg_side | (OPL3_REG_AM_VIB + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- /* Set decreasing volume of higher notes */
- reg_val = (voice->scale_level << 6) & OPL3_KSL_MASK;
- /* Set output volume */
- reg_val |= ~voice->volume & OPL3_TOTAL_LEVEL_MASK;
-
- /* Set OPL3 KSL_LEVEL register of requested voice/operator */
- opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- /* Set attack phase level */
- reg_val = (voice->attack << 4) & OPL3_ATTACK_MASK;
- /* Set decay phase level */
- reg_val |= voice->decay & OPL3_DECAY_MASK;
-
- /* Set OPL3 ATTACK_DECAY register of requested voice/operator */
- opl3_reg = reg_side | (OPL3_REG_ATTACK_DECAY + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- /* Set sustain phase level */
- reg_val = (voice->sustain << 4) & OPL3_SUSTAIN_MASK;
- /* Set release phase level */
- reg_val |= voice->release & OPL3_RELEASE_MASK;
-
- /* Set OPL3 SUSTAIN_RELEASE register of requested voice/operator */
- opl3_reg = reg_side | (OPL3_REG_SUSTAIN_RELEASE + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- /* Set inter-operator feedback */
- reg_val = (voice->feedback << 1) & OPL3_FEEDBACK_MASK;
- /* Set inter-operator connection */
- if (voice->connection)
- reg_val |= OPL3_CONNECTION_BIT;
- /* OPL-3 only */
- if (opl3->fm_mode == SNDRV_DM_FM_MODE_OPL3) {
- if (voice->left)
- reg_val |= OPL3_VOICE_TO_LEFT;
- if (voice->right)
- reg_val |= OPL3_VOICE_TO_RIGHT;
- }
- /* Feedback/connection bits are applicable to voice */
- opl3_reg = reg_side | (OPL3_REG_FEEDBACK_CONNECTION + voice_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- /* Select waveform */
- reg_val = voice->waveform & OPL3_WAVE_SELECT_MASK;
- opl3_reg = reg_side | (OPL3_REG_WAVE_SELECT + op_offset);
- opl3->command(opl3, opl3_reg, reg_val);
-
- return 0;
-}
-
-static int snd_opl3_set_params(struct snd_opl3 * opl3, struct snd_dm_fm_params * params)
-{
- unsigned char reg_val;
-
- reg_val = 0x00;
- /* Set keyboard split method */
- if (params->kbd_split)
- reg_val |= OPL3_KEYBOARD_SPLIT;
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_KBD_SPLIT, reg_val);
-
- reg_val = 0x00;
- /* Set amplitude modulation (tremolo) depth */
- if (params->am_depth)
- reg_val |= OPL3_TREMOLO_DEPTH;
- /* Set vibrato depth */
- if (params->vib_depth)
- reg_val |= OPL3_VIBRATO_DEPTH;
- /* Set percussion mode */
- if (params->rhythm) {
- reg_val |= OPL3_PERCUSSION_ENABLE;
- opl3->rhythm = 1;
- } else {
- opl3->rhythm = 0;
- }
- /* Play percussion instruments */
- if (params->bass)
- reg_val |= OPL3_BASSDRUM_ON;
- if (params->snare)
- reg_val |= OPL3_SNAREDRUM_ON;
- if (params->tomtom)
- reg_val |= OPL3_TOMTOM_ON;
- if (params->cymbal)
- reg_val |= OPL3_CYMBAL_ON;
- if (params->hihat)
- reg_val |= OPL3_HIHAT_ON;
-
- opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, reg_val);
- return 0;
-}
-
-static int snd_opl3_set_mode(struct snd_opl3 * opl3, int mode)
-{
- if ((mode == SNDRV_DM_FM_MODE_OPL3) && (opl3->hardware < OPL3_HW_OPL3))
- return -EINVAL;
-
- opl3->fm_mode = mode;
- if (opl3->hardware >= OPL3_HW_OPL3)
- opl3->command(opl3, OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT, 0x00); /* Clear 4-op connections */
-
- return 0;
-}
-
-static int snd_opl3_set_connection(struct snd_opl3 * opl3, int connection)
-{
- unsigned char reg_val;
-
- /* OPL-3 only */
- if (opl3->fm_mode != SNDRV_DM_FM_MODE_OPL3)
- return -EINVAL;
-
- reg_val = connection & (OPL3_RIGHT_4OP_0 | OPL3_RIGHT_4OP_1 | OPL3_RIGHT_4OP_2 |
- OPL3_LEFT_4OP_0 | OPL3_LEFT_4OP_1 | OPL3_LEFT_4OP_2);
- /* Set 4-op connections */
- opl3->command(opl3, OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT, reg_val);
-
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/drivers/opl3/opl3_voice.h b/ANDROID_3.4.5/sound/drivers/opl3/opl3_voice.h
deleted file mode 100644
index a371c075..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl3/opl3_voice.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef __OPL3_VOICE_H
-#define __OPL3_VOICE_H
-
-/*
- * Copyright (c) 2000 Uros Bizjak <uros@kss-loka.si>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <sound/opl3.h>
-
-/* Prototypes for opl3_seq.c */
-int snd_opl3_synth_use_inc(struct snd_opl3 * opl3);
-void snd_opl3_synth_use_dec(struct snd_opl3 * opl3);
-int snd_opl3_synth_setup(struct snd_opl3 * opl3);
-void snd_opl3_synth_cleanup(struct snd_opl3 * opl3);
-
-/* Prototypes for opl3_midi.c */
-void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan);
-void snd_opl3_note_off(void *p, int note, int vel, struct snd_midi_channel *chan);
-void snd_opl3_key_press(void *p, int note, int vel, struct snd_midi_channel *chan);
-void snd_opl3_terminate_note(void *p, int note, struct snd_midi_channel *chan);
-void snd_opl3_control(void *p, int type, struct snd_midi_channel *chan);
-void snd_opl3_nrpn(void *p, struct snd_midi_channel *chan, struct snd_midi_channel_set *chset);
-void snd_opl3_sysex(void *p, unsigned char *buf, int len, int parsed, struct snd_midi_channel_set *chset);
-
-void snd_opl3_calc_volume(unsigned char *reg, int vel, struct snd_midi_channel *chan);
-void snd_opl3_timer_func(unsigned long data);
-
-/* Prototypes for opl3_drums.c */
-void snd_opl3_load_drums(struct snd_opl3 *opl3);
-void snd_opl3_drum_switch(struct snd_opl3 *opl3, int note, int on_off, int vel, struct snd_midi_channel *chan);
-
-/* Prototypes for opl3_oss.c */
-#ifdef CONFIG_SND_SEQUENCER_OSS
-void snd_opl3_init_seq_oss(struct snd_opl3 *opl3, char *name);
-void snd_opl3_free_seq_oss(struct snd_opl3 *opl3);
-#endif
-
-#endif
diff --git a/ANDROID_3.4.5/sound/drivers/opl4/Makefile b/ANDROID_3.4.5/sound/drivers/opl4/Makefile
deleted file mode 100644
index b94009b0..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl4/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-opl4-lib-objs := opl4_lib.o opl4_mixer.o opl4_proc.o
-snd-opl4-synth-objs := opl4_seq.o opl4_synth.o yrw801.o
-
-obj-$(CONFIG_SND_OPL4_LIB) += snd-opl4-lib.o
-obj-$(CONFIG_SND_OPL4_LIB_SEQ) += snd-opl4-synth.o
diff --git a/ANDROID_3.4.5/sound/drivers/opl4/opl4_lib.c b/ANDROID_3.4.5/sound/drivers/opl4/opl4_lib.c
deleted file mode 100644
index b953fb4a..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl4/opl4_lib.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Functions for accessing OPL4 devices
- * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "opl4_local.h"
-#include <sound/initval.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <asm/io.h>
-
-MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
-MODULE_DESCRIPTION("OPL4 driver");
-MODULE_LICENSE("GPL");
-
-static void inline snd_opl4_wait(struct snd_opl4 *opl4)
-{
- int timeout = 10;
- while ((inb(opl4->fm_port) & OPL4_STATUS_BUSY) && --timeout > 0)
- ;
-}
-
-void snd_opl4_write(struct snd_opl4 *opl4, u8 reg, u8 value)
-{
- snd_opl4_wait(opl4);
- outb(reg, opl4->pcm_port);
-
- snd_opl4_wait(opl4);
- outb(value, opl4->pcm_port + 1);
-}
-
-EXPORT_SYMBOL(snd_opl4_write);
-
-u8 snd_opl4_read(struct snd_opl4 *opl4, u8 reg)
-{
- snd_opl4_wait(opl4);
- outb(reg, opl4->pcm_port);
-
- snd_opl4_wait(opl4);
- return inb(opl4->pcm_port + 1);
-}
-
-EXPORT_SYMBOL(snd_opl4_read);
-
-void snd_opl4_read_memory(struct snd_opl4 *opl4, char *buf, int offset, int size)
-{
- unsigned long flags;
- u8 memcfg;
-
- spin_lock_irqsave(&opl4->reg_lock, flags);
-
- memcfg = snd_opl4_read(opl4, OPL4_REG_MEMORY_CONFIGURATION);
- snd_opl4_write(opl4, OPL4_REG_MEMORY_CONFIGURATION, memcfg | OPL4_MODE_BIT);
-
- snd_opl4_write(opl4, OPL4_REG_MEMORY_ADDRESS_HIGH, offset >> 16);
- snd_opl4_write(opl4, OPL4_REG_MEMORY_ADDRESS_MID, offset >> 8);
- snd_opl4_write(opl4, OPL4_REG_MEMORY_ADDRESS_LOW, offset);
-
- snd_opl4_wait(opl4);
- outb(OPL4_REG_MEMORY_DATA, opl4->pcm_port);
- snd_opl4_wait(opl4);
- insb(opl4->pcm_port + 1, buf, size);
-
- snd_opl4_write(opl4, OPL4_REG_MEMORY_CONFIGURATION, memcfg);
-
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
-}
-
-EXPORT_SYMBOL(snd_opl4_read_memory);
-
-void snd_opl4_write_memory(struct snd_opl4 *opl4, const char *buf, int offset, int size)
-{
- unsigned long flags;
- u8 memcfg;
-
- spin_lock_irqsave(&opl4->reg_lock, flags);
-
- memcfg = snd_opl4_read(opl4, OPL4_REG_MEMORY_CONFIGURATION);
- snd_opl4_write(opl4, OPL4_REG_MEMORY_CONFIGURATION, memcfg | OPL4_MODE_BIT);
-
- snd_opl4_write(opl4, OPL4_REG_MEMORY_ADDRESS_HIGH, offset >> 16);
- snd_opl4_write(opl4, OPL4_REG_MEMORY_ADDRESS_MID, offset >> 8);
- snd_opl4_write(opl4, OPL4_REG_MEMORY_ADDRESS_LOW, offset);
-
- snd_opl4_wait(opl4);
- outb(OPL4_REG_MEMORY_DATA, opl4->pcm_port);
- snd_opl4_wait(opl4);
- outsb(opl4->pcm_port + 1, buf, size);
-
- snd_opl4_write(opl4, OPL4_REG_MEMORY_CONFIGURATION, memcfg);
-
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
-}
-
-EXPORT_SYMBOL(snd_opl4_write_memory);
-
-static void snd_opl4_enable_opl4(struct snd_opl4 *opl4)
-{
- outb(OPL3_REG_MODE, opl4->fm_port + 2);
- inb(opl4->fm_port);
- inb(opl4->fm_port);
- outb(OPL3_OPL3_ENABLE | OPL3_OPL4_ENABLE, opl4->fm_port + 3);
- inb(opl4->fm_port);
- inb(opl4->fm_port);
-}
-
-static int snd_opl4_detect(struct snd_opl4 *opl4)
-{
- u8 id1, id2;
-
- snd_opl4_enable_opl4(opl4);
-
- id1 = snd_opl4_read(opl4, OPL4_REG_MEMORY_CONFIGURATION);
- snd_printdd("OPL4[02]=%02x\n", id1);
- switch (id1 & OPL4_DEVICE_ID_MASK) {
- case 0x20:
- opl4->hardware = OPL3_HW_OPL4;
- break;
- case 0x40:
- opl4->hardware = OPL3_HW_OPL4_ML;
- break;
- default:
- return -ENODEV;
- }
-
- snd_opl4_write(opl4, OPL4_REG_MIX_CONTROL_FM, 0x00);
- snd_opl4_write(opl4, OPL4_REG_MIX_CONTROL_PCM, 0xff);
- id1 = snd_opl4_read(opl4, OPL4_REG_MIX_CONTROL_FM);
- id2 = snd_opl4_read(opl4, OPL4_REG_MIX_CONTROL_PCM);
- snd_printdd("OPL4 id1=%02x id2=%02x\n", id1, id2);
- if (id1 != 0x00 || id2 != 0xff)
- return -ENODEV;
-
- snd_opl4_write(opl4, OPL4_REG_MIX_CONTROL_FM, 0x3f);
- snd_opl4_write(opl4, OPL4_REG_MIX_CONTROL_PCM, 0x3f);
- snd_opl4_write(opl4, OPL4_REG_MEMORY_CONFIGURATION, 0x00);
- return 0;
-}
-
-#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
-static void snd_opl4_seq_dev_free(struct snd_seq_device *seq_dev)
-{
- struct snd_opl4 *opl4 = seq_dev->private_data;
- opl4->seq_dev = NULL;
-}
-
-static int snd_opl4_create_seq_dev(struct snd_opl4 *opl4, int seq_device)
-{
- opl4->seq_dev_num = seq_device;
- if (snd_seq_device_new(opl4->card, seq_device, SNDRV_SEQ_DEV_ID_OPL4,
- sizeof(struct snd_opl4 *), &opl4->seq_dev) >= 0) {
- strcpy(opl4->seq_dev->name, "OPL4 Wavetable");
- *(struct snd_opl4 **)SNDRV_SEQ_DEVICE_ARGPTR(opl4->seq_dev) = opl4;
- opl4->seq_dev->private_data = opl4;
- opl4->seq_dev->private_free = snd_opl4_seq_dev_free;
- }
- return 0;
-}
-#endif
-
-static void snd_opl4_free(struct snd_opl4 *opl4)
-{
-#ifdef CONFIG_PROC_FS
- snd_opl4_free_proc(opl4);
-#endif
- release_and_free_resource(opl4->res_fm_port);
- release_and_free_resource(opl4->res_pcm_port);
- kfree(opl4);
-}
-
-static int snd_opl4_dev_free(struct snd_device *device)
-{
- struct snd_opl4 *opl4 = device->device_data;
- snd_opl4_free(opl4);
- return 0;
-}
-
-int snd_opl4_create(struct snd_card *card,
- unsigned long fm_port, unsigned long pcm_port,
- int seq_device,
- struct snd_opl3 **ropl3, struct snd_opl4 **ropl4)
-{
- struct snd_opl4 *opl4;
- struct snd_opl3 *opl3;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_opl4_dev_free
- };
-
- if (ropl3)
- *ropl3 = NULL;
- if (ropl4)
- *ropl4 = NULL;
-
- opl4 = kzalloc(sizeof(*opl4), GFP_KERNEL);
- if (!opl4)
- return -ENOMEM;
-
- opl4->res_fm_port = request_region(fm_port, 8, "OPL4 FM");
- opl4->res_pcm_port = request_region(pcm_port, 8, "OPL4 PCM/MIX");
- if (!opl4->res_fm_port || !opl4->res_pcm_port) {
- snd_printk(KERN_ERR "opl4: can't grab ports 0x%lx, 0x%lx\n", fm_port, pcm_port);
- snd_opl4_free(opl4);
- return -EBUSY;
- }
-
- opl4->card = card;
- opl4->fm_port = fm_port;
- opl4->pcm_port = pcm_port;
- spin_lock_init(&opl4->reg_lock);
- mutex_init(&opl4->access_mutex);
-
- err = snd_opl4_detect(opl4);
- if (err < 0) {
- snd_opl4_free(opl4);
- snd_printd("OPL4 chip not detected at %#lx/%#lx\n", fm_port, pcm_port);
- return err;
- }
-
- err = snd_device_new(card, SNDRV_DEV_CODEC, opl4, &ops);
- if (err < 0) {
- snd_opl4_free(opl4);
- return err;
- }
-
- err = snd_opl3_create(card, fm_port, fm_port + 2, opl4->hardware, 1, &opl3);
- if (err < 0) {
- snd_device_free(card, opl4);
- return err;
- }
-
- /* opl3 initialization disabled opl4, so reenable */
- snd_opl4_enable_opl4(opl4);
-
- snd_opl4_create_mixer(opl4);
-#ifdef CONFIG_PROC_FS
- snd_opl4_create_proc(opl4);
-#endif
-
-#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
- opl4->seq_client = -1;
- if (opl4->hardware < OPL3_HW_OPL4_ML)
- snd_opl4_create_seq_dev(opl4, seq_device);
-#endif
-
- if (ropl3)
- *ropl3 = opl3;
- if (ropl4)
- *ropl4 = opl4;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_opl4_create);
-
-static int __init alsa_opl4_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_opl4_exit(void)
-{
-}
-
-module_init(alsa_opl4_init)
-module_exit(alsa_opl4_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/opl4/opl4_local.h b/ANDROID_3.4.5/sound/drivers/opl4/opl4_local.h
deleted file mode 100644
index 470e5a75..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl4/opl4_local.h
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Local definitions for the OPL4 driver
- *
- * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed and/or modified under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef __OPL4_LOCAL_H
-#define __OPL4_LOCAL_H
-
-#include <sound/opl4.h>
-
-/*
- * Register numbers
- */
-
-#define OPL4_REG_TEST0 0x00
-#define OPL4_REG_TEST1 0x01
-
-#define OPL4_REG_MEMORY_CONFIGURATION 0x02
-#define OPL4_MODE_BIT 0x01
-#define OPL4_MTYPE_BIT 0x02
-#define OPL4_TONE_HEADER_MASK 0x1c
-#define OPL4_DEVICE_ID_MASK 0xe0
-
-#define OPL4_REG_MEMORY_ADDRESS_HIGH 0x03
-#define OPL4_REG_MEMORY_ADDRESS_MID 0x04
-#define OPL4_REG_MEMORY_ADDRESS_LOW 0x05
-#define OPL4_REG_MEMORY_DATA 0x06
-
-/*
- * Offsets to the register banks for voices. To get the
- * register number just add the voice number to the bank offset.
- *
- * Wave Table Number low bits (0x08 to 0x1F)
- */
-#define OPL4_REG_TONE_NUMBER 0x08
-
-/* Wave Table Number high bit, F-Number low bits (0x20 to 0x37) */
-#define OPL4_REG_F_NUMBER 0x20
-#define OPL4_TONE_NUMBER_BIT8 0x01
-#define OPL4_F_NUMBER_LOW_MASK 0xfe
-
-/* F-Number high bits, Octave, Pseudo-Reverb (0x38 to 0x4F) */
-#define OPL4_REG_OCTAVE 0x38
-#define OPL4_F_NUMBER_HIGH_MASK 0x07
-#define OPL4_BLOCK_MASK 0xf0
-#define OPL4_PSEUDO_REVERB_BIT 0x08
-
-/* Total Level, Level Direct (0x50 to 0x67) */
-#define OPL4_REG_LEVEL 0x50
-#define OPL4_TOTAL_LEVEL_MASK 0xfe
-#define OPL4_LEVEL_DIRECT_BIT 0x01
-
-/* Key On, Damp, LFO RST, CH, Panpot (0x68 to 0x7F) */
-#define OPL4_REG_MISC 0x68
-#define OPL4_KEY_ON_BIT 0x80
-#define OPL4_DAMP_BIT 0x40
-#define OPL4_LFO_RESET_BIT 0x20
-#define OPL4_OUTPUT_CHANNEL_BIT 0x10
-#define OPL4_PAN_POT_MASK 0x0f
-
-/* LFO, VIB (0x80 to 0x97) */
-#define OPL4_REG_LFO_VIBRATO 0x80
-#define OPL4_LFO_FREQUENCY_MASK 0x38
-#define OPL4_VIBRATO_DEPTH_MASK 0x07
-#define OPL4_CHORUS_SEND_MASK 0xc0 /* ML only */
-
-/* Attack / Decay 1 rate (0x98 to 0xAF) */
-#define OPL4_REG_ATTACK_DECAY1 0x98
-#define OPL4_ATTACK_RATE_MASK 0xf0
-#define OPL4_DECAY1_RATE_MASK 0x0f
-
-/* Decay level / 2 rate (0xB0 to 0xC7) */
-#define OPL4_REG_LEVEL_DECAY2 0xb0
-#define OPL4_DECAY_LEVEL_MASK 0xf0
-#define OPL4_DECAY2_RATE_MASK 0x0f
-
-/* Release rate / Rate correction (0xC8 to 0xDF) */
-#define OPL4_REG_RELEASE_CORRECTION 0xc8
-#define OPL4_RELEASE_RATE_MASK 0x0f
-#define OPL4_RATE_INTERPOLATION_MASK 0xf0
-
-/* AM (0xE0 to 0xF7) */
-#define OPL4_REG_TREMOLO 0xe0
-#define OPL4_TREMOLO_DEPTH_MASK 0x07
-#define OPL4_REVERB_SEND_MASK 0xe0 /* ML only */
-
-/* Mixer */
-#define OPL4_REG_MIX_CONTROL_FM 0xf8
-#define OPL4_REG_MIX_CONTROL_PCM 0xf9
-#define OPL4_MIX_LEFT_MASK 0x07
-#define OPL4_MIX_RIGHT_MASK 0x38
-
-#define OPL4_REG_ATC 0xfa
-#define OPL4_ATC_BIT 0x01 /* ???, ML only */
-
-/* bits in the OPL3 Status register */
-#define OPL4_STATUS_BUSY 0x01
-#define OPL4_STATUS_LOAD 0x02
-
-
-#define OPL4_MAX_VOICES 24
-
-#define SNDRV_SEQ_DEV_ID_OPL4 "opl4-synth"
-
-
-struct opl4_sound {
- u16 tone;
- s16 pitch_offset;
- u8 key_scaling;
- s8 panpot;
- u8 vibrato;
- u8 tone_attenuate;
- u8 volume_factor;
- u8 reg_lfo_vibrato;
- u8 reg_attack_decay1;
- u8 reg_level_decay2;
- u8 reg_release_correction;
- u8 reg_tremolo;
-};
-
-struct opl4_region {
- u8 key_min, key_max;
- struct opl4_sound sound;
-};
-
-struct opl4_region_ptr {
- int count;
- const struct opl4_region *regions;
-};
-
-struct opl4_voice {
- struct list_head list;
- int number;
- struct snd_midi_channel *chan;
- int note;
- int velocity;
- const struct opl4_sound *sound;
- u8 level_direct;
- u8 reg_f_number;
- u8 reg_misc;
- u8 reg_lfo_vibrato;
-};
-
-struct snd_opl4 {
- unsigned long fm_port;
- unsigned long pcm_port;
- struct resource *res_fm_port;
- struct resource *res_pcm_port;
- unsigned short hardware;
- spinlock_t reg_lock;
- struct snd_card *card;
-
-#ifdef CONFIG_PROC_FS
- struct snd_info_entry *proc_entry;
- int memory_access;
-#endif
- struct mutex access_mutex;
-
-#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
- int used;
-
- int seq_dev_num;
- int seq_client;
- struct snd_seq_device *seq_dev;
-
- struct snd_midi_channel_set *chset;
- struct opl4_voice voices[OPL4_MAX_VOICES];
- struct list_head off_voices;
- struct list_head on_voices;
-#endif
-};
-
-/* opl4_lib.c */
-void snd_opl4_write(struct snd_opl4 *opl4, u8 reg, u8 value);
-u8 snd_opl4_read(struct snd_opl4 *opl4, u8 reg);
-void snd_opl4_read_memory(struct snd_opl4 *opl4, char *buf, int offset, int size);
-void snd_opl4_write_memory(struct snd_opl4 *opl4, const char *buf, int offset, int size);
-
-/* opl4_mixer.c */
-int snd_opl4_create_mixer(struct snd_opl4 *opl4);
-
-#ifdef CONFIG_PROC_FS
-/* opl4_proc.c */
-int snd_opl4_create_proc(struct snd_opl4 *opl4);
-void snd_opl4_free_proc(struct snd_opl4 *opl4);
-#endif
-
-/* opl4_seq.c */
-extern int volume_boost;
-
-/* opl4_synth.c */
-void snd_opl4_synth_reset(struct snd_opl4 *opl4);
-void snd_opl4_synth_shutdown(struct snd_opl4 *opl4);
-void snd_opl4_note_on(void *p, int note, int vel, struct snd_midi_channel *chan);
-void snd_opl4_note_off(void *p, int note, int vel, struct snd_midi_channel *chan);
-void snd_opl4_terminate_note(void *p, int note, struct snd_midi_channel *chan);
-void snd_opl4_control(void *p, int type, struct snd_midi_channel *chan);
-void snd_opl4_sysex(void *p, unsigned char *buf, int len, int parsed, struct snd_midi_channel_set *chset);
-
-/* yrw801.c */
-int snd_yrw801_detect(struct snd_opl4 *opl4);
-extern const struct opl4_region_ptr snd_yrw801_regions[];
-
-#endif /* __OPL4_LOCAL_H */
diff --git a/ANDROID_3.4.5/sound/drivers/opl4/opl4_mixer.c b/ANDROID_3.4.5/sound/drivers/opl4/opl4_mixer.c
deleted file mode 100644
index 04079de4..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl4/opl4_mixer.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * OPL4 mixer functions
- * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "opl4_local.h"
-#include <sound/control.h>
-
-static int snd_opl4_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 7;
- return 0;
-}
-
-static int snd_opl4_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_opl4 *opl4 = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- u8 reg = kcontrol->private_value;
- u8 value;
-
- spin_lock_irqsave(&opl4->reg_lock, flags);
- value = snd_opl4_read(opl4, reg);
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
- ucontrol->value.integer.value[0] = 7 - (value & 7);
- ucontrol->value.integer.value[1] = 7 - ((value >> 3) & 7);
- return 0;
-}
-
-static int snd_opl4_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_opl4 *opl4 = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- u8 reg = kcontrol->private_value;
- u8 value, old_value;
-
- value = (7 - (ucontrol->value.integer.value[0] & 7)) |
- ((7 - (ucontrol->value.integer.value[1] & 7)) << 3);
- spin_lock_irqsave(&opl4->reg_lock, flags);
- old_value = snd_opl4_read(opl4, reg);
- snd_opl4_write(opl4, reg, value);
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
- return value != old_value;
-}
-
-static struct snd_kcontrol_new snd_opl4_controls[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "FM Playback Volume",
- .info = snd_opl4_ctl_info,
- .get = snd_opl4_ctl_get,
- .put = snd_opl4_ctl_put,
- .private_value = OPL4_REG_MIX_CONTROL_FM
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Wavetable Playback Volume",
- .info = snd_opl4_ctl_info,
- .get = snd_opl4_ctl_get,
- .put = snd_opl4_ctl_put,
- .private_value = OPL4_REG_MIX_CONTROL_PCM
- }
-};
-
-int snd_opl4_create_mixer(struct snd_opl4 *opl4)
-{
- struct snd_card *card = opl4->card;
- int i, err;
-
- strcat(card->mixername, ",OPL4");
-
- for (i = 0; i < 2; ++i) {
- err = snd_ctl_add(card, snd_ctl_new1(&snd_opl4_controls[i], opl4));
- if (err < 0)
- return err;
- }
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/drivers/opl4/opl4_proc.c b/ANDROID_3.4.5/sound/drivers/opl4/opl4_proc.c
deleted file mode 100644
index 9b824bfc..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl4/opl4_proc.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Functions for the OPL4 proc file
- * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "opl4_local.h"
-#include <linux/vmalloc.h>
-#include <linux/export.h>
-#include <sound/info.h>
-
-#ifdef CONFIG_PROC_FS
-
-static int snd_opl4_mem_proc_open(struct snd_info_entry *entry,
- unsigned short mode, void **file_private_data)
-{
- struct snd_opl4 *opl4 = entry->private_data;
-
- mutex_lock(&opl4->access_mutex);
- if (opl4->memory_access) {
- mutex_unlock(&opl4->access_mutex);
- return -EBUSY;
- }
- opl4->memory_access++;
- mutex_unlock(&opl4->access_mutex);
- return 0;
-}
-
-static int snd_opl4_mem_proc_release(struct snd_info_entry *entry,
- unsigned short mode, void *file_private_data)
-{
- struct snd_opl4 *opl4 = entry->private_data;
-
- mutex_lock(&opl4->access_mutex);
- opl4->memory_access--;
- mutex_unlock(&opl4->access_mutex);
- return 0;
-}
-
-static ssize_t snd_opl4_mem_proc_read(struct snd_info_entry *entry,
- void *file_private_data,
- struct file *file, char __user *_buf,
- size_t count, loff_t pos)
-{
- struct snd_opl4 *opl4 = entry->private_data;
- char* buf;
-
- buf = vmalloc(count);
- if (!buf)
- return -ENOMEM;
- snd_opl4_read_memory(opl4, buf, pos, count);
- if (copy_to_user(_buf, buf, count)) {
- vfree(buf);
- return -EFAULT;
- }
- vfree(buf);
- return count;
-}
-
-static ssize_t snd_opl4_mem_proc_write(struct snd_info_entry *entry,
- void *file_private_data,
- struct file *file,
- const char __user *_buf,
- size_t count, loff_t pos)
-{
- struct snd_opl4 *opl4 = entry->private_data;
- char *buf;
-
- buf = vmalloc(count);
- if (!buf)
- return -ENOMEM;
- if (copy_from_user(buf, _buf, count)) {
- vfree(buf);
- return -EFAULT;
- }
- snd_opl4_write_memory(opl4, buf, pos, count);
- vfree(buf);
- return count;
-}
-
-static struct snd_info_entry_ops snd_opl4_mem_proc_ops = {
- .open = snd_opl4_mem_proc_open,
- .release = snd_opl4_mem_proc_release,
- .read = snd_opl4_mem_proc_read,
- .write = snd_opl4_mem_proc_write,
-};
-
-int snd_opl4_create_proc(struct snd_opl4 *opl4)
-{
- struct snd_info_entry *entry;
-
- entry = snd_info_create_card_entry(opl4->card, "opl4-mem", opl4->card->proc_root);
- if (entry) {
- if (opl4->hardware < OPL3_HW_OPL4_ML) {
- /* OPL4 can access 4 MB external ROM/SRAM */
- entry->mode |= S_IWUSR;
- entry->size = 4 * 1024 * 1024;
- } else {
- /* OPL4-ML has 1 MB internal ROM */
- entry->size = 1 * 1024 * 1024;
- }
- entry->content = SNDRV_INFO_CONTENT_DATA;
- entry->c.ops = &snd_opl4_mem_proc_ops;
- entry->module = THIS_MODULE;
- entry->private_data = opl4;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- opl4->proc_entry = entry;
- return 0;
-}
-
-void snd_opl4_free_proc(struct snd_opl4 *opl4)
-{
- snd_info_free_entry(opl4->proc_entry);
-}
-
-#endif /* CONFIG_PROC_FS */
diff --git a/ANDROID_3.4.5/sound/drivers/opl4/opl4_seq.c b/ANDROID_3.4.5/sound/drivers/opl4/opl4_seq.c
deleted file mode 100644
index 99197699..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl4/opl4_seq.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * OPL4 sequencer functions
- *
- * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed and/or modified under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "opl4_local.h"
-#include <linux/init.h>
-#include <linux/moduleparam.h>
-#include <linux/module.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
-MODULE_DESCRIPTION("OPL4 wavetable synth driver");
-MODULE_LICENSE("Dual BSD/GPL");
-
-int volume_boost = 8;
-
-module_param(volume_boost, int, 0644);
-MODULE_PARM_DESC(volume_boost, "Additional volume for OPL4 wavetable sounds.");
-
-static int snd_opl4_seq_use_inc(struct snd_opl4 *opl4)
-{
- if (!try_module_get(opl4->card->module))
- return -EFAULT;
- return 0;
-}
-
-static void snd_opl4_seq_use_dec(struct snd_opl4 *opl4)
-{
- module_put(opl4->card->module);
-}
-
-static int snd_opl4_seq_use(void *private_data, struct snd_seq_port_subscribe *info)
-{
- struct snd_opl4 *opl4 = private_data;
- int err;
-
- mutex_lock(&opl4->access_mutex);
-
- if (opl4->used) {
- mutex_unlock(&opl4->access_mutex);
- return -EBUSY;
- }
- opl4->used++;
-
- if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM) {
- err = snd_opl4_seq_use_inc(opl4);
- if (err < 0) {
- mutex_unlock(&opl4->access_mutex);
- return err;
- }
- }
-
- mutex_unlock(&opl4->access_mutex);
-
- snd_opl4_synth_reset(opl4);
- return 0;
-}
-
-static int snd_opl4_seq_unuse(void *private_data, struct snd_seq_port_subscribe *info)
-{
- struct snd_opl4 *opl4 = private_data;
-
- snd_opl4_synth_shutdown(opl4);
-
- mutex_lock(&opl4->access_mutex);
- opl4->used--;
- mutex_unlock(&opl4->access_mutex);
-
- if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM)
- snd_opl4_seq_use_dec(opl4);
- return 0;
-}
-
-static struct snd_midi_op opl4_ops = {
- .note_on = snd_opl4_note_on,
- .note_off = snd_opl4_note_off,
- .note_terminate = snd_opl4_terminate_note,
- .control = snd_opl4_control,
- .sysex = snd_opl4_sysex,
-};
-
-static int snd_opl4_seq_event_input(struct snd_seq_event *ev, int direct,
- void *private_data, int atomic, int hop)
-{
- struct snd_opl4 *opl4 = private_data;
-
- snd_midi_process_event(&opl4_ops, ev, opl4->chset);
- return 0;
-}
-
-static void snd_opl4_seq_free_port(void *private_data)
-{
- struct snd_opl4 *opl4 = private_data;
-
- snd_midi_channel_free_set(opl4->chset);
-}
-
-static int snd_opl4_seq_new_device(struct snd_seq_device *dev)
-{
- struct snd_opl4 *opl4;
- int client;
- struct snd_seq_port_callback pcallbacks;
-
- opl4 = *(struct snd_opl4 **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
- if (!opl4)
- return -EINVAL;
-
- if (snd_yrw801_detect(opl4) < 0)
- return -ENODEV;
-
- opl4->chset = snd_midi_channel_alloc_set(16);
- if (!opl4->chset)
- return -ENOMEM;
- opl4->chset->private_data = opl4;
-
- /* allocate new client */
- client = snd_seq_create_kernel_client(opl4->card, opl4->seq_dev_num,
- "OPL4 Wavetable");
- if (client < 0) {
- snd_midi_channel_free_set(opl4->chset);
- return client;
- }
- opl4->seq_client = client;
- opl4->chset->client = client;
-
- /* create new port */
- memset(&pcallbacks, 0, sizeof(pcallbacks));
- pcallbacks.owner = THIS_MODULE;
- pcallbacks.use = snd_opl4_seq_use;
- pcallbacks.unuse = snd_opl4_seq_unuse;
- pcallbacks.event_input = snd_opl4_seq_event_input;
- pcallbacks.private_free = snd_opl4_seq_free_port;
- pcallbacks.private_data = opl4;
-
- opl4->chset->port = snd_seq_event_port_attach(client, &pcallbacks,
- SNDRV_SEQ_PORT_CAP_WRITE |
- SNDRV_SEQ_PORT_CAP_SUBS_WRITE,
- SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
- SNDRV_SEQ_PORT_TYPE_MIDI_GM |
- SNDRV_SEQ_PORT_TYPE_HARDWARE |
- SNDRV_SEQ_PORT_TYPE_SYNTHESIZER,
- 16, 24,
- "OPL4 Wavetable Port");
- if (opl4->chset->port < 0) {
- int err = opl4->chset->port;
- snd_midi_channel_free_set(opl4->chset);
- snd_seq_delete_kernel_client(client);
- opl4->seq_client = -1;
- return err;
- }
- return 0;
-}
-
-static int snd_opl4_seq_delete_device(struct snd_seq_device *dev)
-{
- struct snd_opl4 *opl4;
-
- opl4 = *(struct snd_opl4 **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
- if (!opl4)
- return -EINVAL;
-
- if (opl4->seq_client >= 0) {
- snd_seq_delete_kernel_client(opl4->seq_client);
- opl4->seq_client = -1;
- }
- return 0;
-}
-
-static int __init alsa_opl4_synth_init(void)
-{
- static struct snd_seq_dev_ops ops = {
- snd_opl4_seq_new_device,
- snd_opl4_seq_delete_device
- };
-
- return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_OPL4, &ops,
- sizeof(struct snd_opl4 *));
-}
-
-static void __exit alsa_opl4_synth_exit(void)
-{
- snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_OPL4);
-}
-
-module_init(alsa_opl4_synth_init)
-module_exit(alsa_opl4_synth_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/opl4/opl4_synth.c b/ANDROID_3.4.5/sound/drivers/opl4/opl4_synth.c
deleted file mode 100644
index 49b9e240..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl4/opl4_synth.c
+++ /dev/null
@@ -1,634 +0,0 @@
-/*
- * OPL4 MIDI synthesizer functions
- *
- * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed and/or modified under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "opl4_local.h"
-#include <linux/delay.h>
-#include <asm/io.h>
-#include <sound/asoundef.h>
-
-/* GM2 controllers */
-#ifndef MIDI_CTL_RELEASE_TIME
-#define MIDI_CTL_RELEASE_TIME 0x48
-#define MIDI_CTL_ATTACK_TIME 0x49
-#define MIDI_CTL_DECAY_TIME 0x4b
-#define MIDI_CTL_VIBRATO_RATE 0x4c
-#define MIDI_CTL_VIBRATO_DEPTH 0x4d
-#define MIDI_CTL_VIBRATO_DELAY 0x4e
-#endif
-
-/*
- * This table maps 100/128 cents to F_NUMBER.
- */
-static const s16 snd_opl4_pitch_map[0x600] = {
- 0x000,0x000,0x001,0x001,0x002,0x002,0x003,0x003,
- 0x004,0x004,0x005,0x005,0x006,0x006,0x006,0x007,
- 0x007,0x008,0x008,0x009,0x009,0x00a,0x00a,0x00b,
- 0x00b,0x00c,0x00c,0x00d,0x00d,0x00d,0x00e,0x00e,
- 0x00f,0x00f,0x010,0x010,0x011,0x011,0x012,0x012,
- 0x013,0x013,0x014,0x014,0x015,0x015,0x015,0x016,
- 0x016,0x017,0x017,0x018,0x018,0x019,0x019,0x01a,
- 0x01a,0x01b,0x01b,0x01c,0x01c,0x01d,0x01d,0x01e,
- 0x01e,0x01e,0x01f,0x01f,0x020,0x020,0x021,0x021,
- 0x022,0x022,0x023,0x023,0x024,0x024,0x025,0x025,
- 0x026,0x026,0x027,0x027,0x028,0x028,0x029,0x029,
- 0x029,0x02a,0x02a,0x02b,0x02b,0x02c,0x02c,0x02d,
- 0x02d,0x02e,0x02e,0x02f,0x02f,0x030,0x030,0x031,
- 0x031,0x032,0x032,0x033,0x033,0x034,0x034,0x035,
- 0x035,0x036,0x036,0x037,0x037,0x038,0x038,0x038,
- 0x039,0x039,0x03a,0x03a,0x03b,0x03b,0x03c,0x03c,
- 0x03d,0x03d,0x03e,0x03e,0x03f,0x03f,0x040,0x040,
- 0x041,0x041,0x042,0x042,0x043,0x043,0x044,0x044,
- 0x045,0x045,0x046,0x046,0x047,0x047,0x048,0x048,
- 0x049,0x049,0x04a,0x04a,0x04b,0x04b,0x04c,0x04c,
- 0x04d,0x04d,0x04e,0x04e,0x04f,0x04f,0x050,0x050,
- 0x051,0x051,0x052,0x052,0x053,0x053,0x054,0x054,
- 0x055,0x055,0x056,0x056,0x057,0x057,0x058,0x058,
- 0x059,0x059,0x05a,0x05a,0x05b,0x05b,0x05c,0x05c,
- 0x05d,0x05d,0x05e,0x05e,0x05f,0x05f,0x060,0x060,
- 0x061,0x061,0x062,0x062,0x063,0x063,0x064,0x064,
- 0x065,0x065,0x066,0x066,0x067,0x067,0x068,0x068,
- 0x069,0x069,0x06a,0x06a,0x06b,0x06b,0x06c,0x06c,
- 0x06d,0x06d,0x06e,0x06e,0x06f,0x06f,0x070,0x071,
- 0x071,0x072,0x072,0x073,0x073,0x074,0x074,0x075,
- 0x075,0x076,0x076,0x077,0x077,0x078,0x078,0x079,
- 0x079,0x07a,0x07a,0x07b,0x07b,0x07c,0x07c,0x07d,
- 0x07d,0x07e,0x07e,0x07f,0x07f,0x080,0x081,0x081,
- 0x082,0x082,0x083,0x083,0x084,0x084,0x085,0x085,
- 0x086,0x086,0x087,0x087,0x088,0x088,0x089,0x089,
- 0x08a,0x08a,0x08b,0x08b,0x08c,0x08d,0x08d,0x08e,
- 0x08e,0x08f,0x08f,0x090,0x090,0x091,0x091,0x092,
- 0x092,0x093,0x093,0x094,0x094,0x095,0x096,0x096,
- 0x097,0x097,0x098,0x098,0x099,0x099,0x09a,0x09a,
- 0x09b,0x09b,0x09c,0x09c,0x09d,0x09d,0x09e,0x09f,
- 0x09f,0x0a0,0x0a0,0x0a1,0x0a1,0x0a2,0x0a2,0x0a3,
- 0x0a3,0x0a4,0x0a4,0x0a5,0x0a6,0x0a6,0x0a7,0x0a7,
- 0x0a8,0x0a8,0x0a9,0x0a9,0x0aa,0x0aa,0x0ab,0x0ab,
- 0x0ac,0x0ad,0x0ad,0x0ae,0x0ae,0x0af,0x0af,0x0b0,
- 0x0b0,0x0b1,0x0b1,0x0b2,0x0b2,0x0b3,0x0b4,0x0b4,
- 0x0b5,0x0b5,0x0b6,0x0b6,0x0b7,0x0b7,0x0b8,0x0b8,
- 0x0b9,0x0ba,0x0ba,0x0bb,0x0bb,0x0bc,0x0bc,0x0bd,
- 0x0bd,0x0be,0x0be,0x0bf,0x0c0,0x0c0,0x0c1,0x0c1,
- 0x0c2,0x0c2,0x0c3,0x0c3,0x0c4,0x0c4,0x0c5,0x0c6,
- 0x0c6,0x0c7,0x0c7,0x0c8,0x0c8,0x0c9,0x0c9,0x0ca,
- 0x0cb,0x0cb,0x0cc,0x0cc,0x0cd,0x0cd,0x0ce,0x0ce,
- 0x0cf,0x0d0,0x0d0,0x0d1,0x0d1,0x0d2,0x0d2,0x0d3,
- 0x0d3,0x0d4,0x0d5,0x0d5,0x0d6,0x0d6,0x0d7,0x0d7,
- 0x0d8,0x0d8,0x0d9,0x0da,0x0da,0x0db,0x0db,0x0dc,
- 0x0dc,0x0dd,0x0de,0x0de,0x0df,0x0df,0x0e0,0x0e0,
- 0x0e1,0x0e1,0x0e2,0x0e3,0x0e3,0x0e4,0x0e4,0x0e5,
- 0x0e5,0x0e6,0x0e7,0x0e7,0x0e8,0x0e8,0x0e9,0x0e9,
- 0x0ea,0x0eb,0x0eb,0x0ec,0x0ec,0x0ed,0x0ed,0x0ee,
- 0x0ef,0x0ef,0x0f0,0x0f0,0x0f1,0x0f1,0x0f2,0x0f3,
- 0x0f3,0x0f4,0x0f4,0x0f5,0x0f5,0x0f6,0x0f7,0x0f7,
- 0x0f8,0x0f8,0x0f9,0x0f9,0x0fa,0x0fb,0x0fb,0x0fc,
- 0x0fc,0x0fd,0x0fd,0x0fe,0x0ff,0x0ff,0x100,0x100,
- 0x101,0x101,0x102,0x103,0x103,0x104,0x104,0x105,
- 0x106,0x106,0x107,0x107,0x108,0x108,0x109,0x10a,
- 0x10a,0x10b,0x10b,0x10c,0x10c,0x10d,0x10e,0x10e,
- 0x10f,0x10f,0x110,0x111,0x111,0x112,0x112,0x113,
- 0x114,0x114,0x115,0x115,0x116,0x116,0x117,0x118,
- 0x118,0x119,0x119,0x11a,0x11b,0x11b,0x11c,0x11c,
- 0x11d,0x11e,0x11e,0x11f,0x11f,0x120,0x120,0x121,
- 0x122,0x122,0x123,0x123,0x124,0x125,0x125,0x126,
- 0x126,0x127,0x128,0x128,0x129,0x129,0x12a,0x12b,
- 0x12b,0x12c,0x12c,0x12d,0x12e,0x12e,0x12f,0x12f,
- 0x130,0x131,0x131,0x132,0x132,0x133,0x134,0x134,
- 0x135,0x135,0x136,0x137,0x137,0x138,0x138,0x139,
- 0x13a,0x13a,0x13b,0x13b,0x13c,0x13d,0x13d,0x13e,
- 0x13e,0x13f,0x140,0x140,0x141,0x141,0x142,0x143,
- 0x143,0x144,0x144,0x145,0x146,0x146,0x147,0x148,
- 0x148,0x149,0x149,0x14a,0x14b,0x14b,0x14c,0x14c,
- 0x14d,0x14e,0x14e,0x14f,0x14f,0x150,0x151,0x151,
- 0x152,0x153,0x153,0x154,0x154,0x155,0x156,0x156,
- 0x157,0x157,0x158,0x159,0x159,0x15a,0x15b,0x15b,
- 0x15c,0x15c,0x15d,0x15e,0x15e,0x15f,0x160,0x160,
- 0x161,0x161,0x162,0x163,0x163,0x164,0x165,0x165,
- 0x166,0x166,0x167,0x168,0x168,0x169,0x16a,0x16a,
- 0x16b,0x16b,0x16c,0x16d,0x16d,0x16e,0x16f,0x16f,
- 0x170,0x170,0x171,0x172,0x172,0x173,0x174,0x174,
- 0x175,0x175,0x176,0x177,0x177,0x178,0x179,0x179,
- 0x17a,0x17a,0x17b,0x17c,0x17c,0x17d,0x17e,0x17e,
- 0x17f,0x180,0x180,0x181,0x181,0x182,0x183,0x183,
- 0x184,0x185,0x185,0x186,0x187,0x187,0x188,0x188,
- 0x189,0x18a,0x18a,0x18b,0x18c,0x18c,0x18d,0x18e,
- 0x18e,0x18f,0x190,0x190,0x191,0x191,0x192,0x193,
- 0x193,0x194,0x195,0x195,0x196,0x197,0x197,0x198,
- 0x199,0x199,0x19a,0x19a,0x19b,0x19c,0x19c,0x19d,
- 0x19e,0x19e,0x19f,0x1a0,0x1a0,0x1a1,0x1a2,0x1a2,
- 0x1a3,0x1a4,0x1a4,0x1a5,0x1a6,0x1a6,0x1a7,0x1a8,
- 0x1a8,0x1a9,0x1a9,0x1aa,0x1ab,0x1ab,0x1ac,0x1ad,
- 0x1ad,0x1ae,0x1af,0x1af,0x1b0,0x1b1,0x1b1,0x1b2,
- 0x1b3,0x1b3,0x1b4,0x1b5,0x1b5,0x1b6,0x1b7,0x1b7,
- 0x1b8,0x1b9,0x1b9,0x1ba,0x1bb,0x1bb,0x1bc,0x1bd,
- 0x1bd,0x1be,0x1bf,0x1bf,0x1c0,0x1c1,0x1c1,0x1c2,
- 0x1c3,0x1c3,0x1c4,0x1c5,0x1c5,0x1c6,0x1c7,0x1c7,
- 0x1c8,0x1c9,0x1c9,0x1ca,0x1cb,0x1cb,0x1cc,0x1cd,
- 0x1cd,0x1ce,0x1cf,0x1cf,0x1d0,0x1d1,0x1d1,0x1d2,
- 0x1d3,0x1d3,0x1d4,0x1d5,0x1d5,0x1d6,0x1d7,0x1d7,
- 0x1d8,0x1d9,0x1d9,0x1da,0x1db,0x1db,0x1dc,0x1dd,
- 0x1dd,0x1de,0x1df,0x1df,0x1e0,0x1e1,0x1e1,0x1e2,
- 0x1e3,0x1e4,0x1e4,0x1e5,0x1e6,0x1e6,0x1e7,0x1e8,
- 0x1e8,0x1e9,0x1ea,0x1ea,0x1eb,0x1ec,0x1ec,0x1ed,
- 0x1ee,0x1ee,0x1ef,0x1f0,0x1f0,0x1f1,0x1f2,0x1f3,
- 0x1f3,0x1f4,0x1f5,0x1f5,0x1f6,0x1f7,0x1f7,0x1f8,
- 0x1f9,0x1f9,0x1fa,0x1fb,0x1fb,0x1fc,0x1fd,0x1fe,
- 0x1fe,0x1ff,0x200,0x200,0x201,0x202,0x202,0x203,
- 0x204,0x205,0x205,0x206,0x207,0x207,0x208,0x209,
- 0x209,0x20a,0x20b,0x20b,0x20c,0x20d,0x20e,0x20e,
- 0x20f,0x210,0x210,0x211,0x212,0x212,0x213,0x214,
- 0x215,0x215,0x216,0x217,0x217,0x218,0x219,0x21a,
- 0x21a,0x21b,0x21c,0x21c,0x21d,0x21e,0x21e,0x21f,
- 0x220,0x221,0x221,0x222,0x223,0x223,0x224,0x225,
- 0x226,0x226,0x227,0x228,0x228,0x229,0x22a,0x22b,
- 0x22b,0x22c,0x22d,0x22d,0x22e,0x22f,0x230,0x230,
- 0x231,0x232,0x232,0x233,0x234,0x235,0x235,0x236,
- 0x237,0x237,0x238,0x239,0x23a,0x23a,0x23b,0x23c,
- 0x23c,0x23d,0x23e,0x23f,0x23f,0x240,0x241,0x241,
- 0x242,0x243,0x244,0x244,0x245,0x246,0x247,0x247,
- 0x248,0x249,0x249,0x24a,0x24b,0x24c,0x24c,0x24d,
- 0x24e,0x24f,0x24f,0x250,0x251,0x251,0x252,0x253,
- 0x254,0x254,0x255,0x256,0x257,0x257,0x258,0x259,
- 0x259,0x25a,0x25b,0x25c,0x25c,0x25d,0x25e,0x25f,
- 0x25f,0x260,0x261,0x262,0x262,0x263,0x264,0x265,
- 0x265,0x266,0x267,0x267,0x268,0x269,0x26a,0x26a,
- 0x26b,0x26c,0x26d,0x26d,0x26e,0x26f,0x270,0x270,
- 0x271,0x272,0x273,0x273,0x274,0x275,0x276,0x276,
- 0x277,0x278,0x279,0x279,0x27a,0x27b,0x27c,0x27c,
- 0x27d,0x27e,0x27f,0x27f,0x280,0x281,0x282,0x282,
- 0x283,0x284,0x285,0x285,0x286,0x287,0x288,0x288,
- 0x289,0x28a,0x28b,0x28b,0x28c,0x28d,0x28e,0x28e,
- 0x28f,0x290,0x291,0x291,0x292,0x293,0x294,0x294,
- 0x295,0x296,0x297,0x298,0x298,0x299,0x29a,0x29b,
- 0x29b,0x29c,0x29d,0x29e,0x29e,0x29f,0x2a0,0x2a1,
- 0x2a1,0x2a2,0x2a3,0x2a4,0x2a5,0x2a5,0x2a6,0x2a7,
- 0x2a8,0x2a8,0x2a9,0x2aa,0x2ab,0x2ab,0x2ac,0x2ad,
- 0x2ae,0x2af,0x2af,0x2b0,0x2b1,0x2b2,0x2b2,0x2b3,
- 0x2b4,0x2b5,0x2b5,0x2b6,0x2b7,0x2b8,0x2b9,0x2b9,
- 0x2ba,0x2bb,0x2bc,0x2bc,0x2bd,0x2be,0x2bf,0x2c0,
- 0x2c0,0x2c1,0x2c2,0x2c3,0x2c4,0x2c4,0x2c5,0x2c6,
- 0x2c7,0x2c7,0x2c8,0x2c9,0x2ca,0x2cb,0x2cb,0x2cc,
- 0x2cd,0x2ce,0x2ce,0x2cf,0x2d0,0x2d1,0x2d2,0x2d2,
- 0x2d3,0x2d4,0x2d5,0x2d6,0x2d6,0x2d7,0x2d8,0x2d9,
- 0x2da,0x2da,0x2db,0x2dc,0x2dd,0x2dd,0x2de,0x2df,
- 0x2e0,0x2e1,0x2e1,0x2e2,0x2e3,0x2e4,0x2e5,0x2e5,
- 0x2e6,0x2e7,0x2e8,0x2e9,0x2e9,0x2ea,0x2eb,0x2ec,
- 0x2ed,0x2ed,0x2ee,0x2ef,0x2f0,0x2f1,0x2f1,0x2f2,
- 0x2f3,0x2f4,0x2f5,0x2f5,0x2f6,0x2f7,0x2f8,0x2f9,
- 0x2f9,0x2fa,0x2fb,0x2fc,0x2fd,0x2fd,0x2fe,0x2ff,
- 0x300,0x301,0x302,0x302,0x303,0x304,0x305,0x306,
- 0x306,0x307,0x308,0x309,0x30a,0x30a,0x30b,0x30c,
- 0x30d,0x30e,0x30f,0x30f,0x310,0x311,0x312,0x313,
- 0x313,0x314,0x315,0x316,0x317,0x318,0x318,0x319,
- 0x31a,0x31b,0x31c,0x31c,0x31d,0x31e,0x31f,0x320,
- 0x321,0x321,0x322,0x323,0x324,0x325,0x326,0x326,
- 0x327,0x328,0x329,0x32a,0x32a,0x32b,0x32c,0x32d,
- 0x32e,0x32f,0x32f,0x330,0x331,0x332,0x333,0x334,
- 0x334,0x335,0x336,0x337,0x338,0x339,0x339,0x33a,
- 0x33b,0x33c,0x33d,0x33e,0x33e,0x33f,0x340,0x341,
- 0x342,0x343,0x343,0x344,0x345,0x346,0x347,0x348,
- 0x349,0x349,0x34a,0x34b,0x34c,0x34d,0x34e,0x34e,
- 0x34f,0x350,0x351,0x352,0x353,0x353,0x354,0x355,
- 0x356,0x357,0x358,0x359,0x359,0x35a,0x35b,0x35c,
- 0x35d,0x35e,0x35f,0x35f,0x360,0x361,0x362,0x363,
- 0x364,0x364,0x365,0x366,0x367,0x368,0x369,0x36a,
- 0x36a,0x36b,0x36c,0x36d,0x36e,0x36f,0x370,0x370,
- 0x371,0x372,0x373,0x374,0x375,0x376,0x377,0x377,
- 0x378,0x379,0x37a,0x37b,0x37c,0x37d,0x37d,0x37e,
- 0x37f,0x380,0x381,0x382,0x383,0x383,0x384,0x385,
- 0x386,0x387,0x388,0x389,0x38a,0x38a,0x38b,0x38c,
- 0x38d,0x38e,0x38f,0x390,0x391,0x391,0x392,0x393,
- 0x394,0x395,0x396,0x397,0x398,0x398,0x399,0x39a,
- 0x39b,0x39c,0x39d,0x39e,0x39f,0x39f,0x3a0,0x3a1,
- 0x3a2,0x3a3,0x3a4,0x3a5,0x3a6,0x3a7,0x3a7,0x3a8,
- 0x3a9,0x3aa,0x3ab,0x3ac,0x3ad,0x3ae,0x3ae,0x3af,
- 0x3b0,0x3b1,0x3b2,0x3b3,0x3b4,0x3b5,0x3b6,0x3b6,
- 0x3b7,0x3b8,0x3b9,0x3ba,0x3bb,0x3bc,0x3bd,0x3be,
- 0x3bf,0x3bf,0x3c0,0x3c1,0x3c2,0x3c3,0x3c4,0x3c5,
- 0x3c6,0x3c7,0x3c7,0x3c8,0x3c9,0x3ca,0x3cb,0x3cc,
- 0x3cd,0x3ce,0x3cf,0x3d0,0x3d1,0x3d1,0x3d2,0x3d3,
- 0x3d4,0x3d5,0x3d6,0x3d7,0x3d8,0x3d9,0x3da,0x3da,
- 0x3db,0x3dc,0x3dd,0x3de,0x3df,0x3e0,0x3e1,0x3e2,
- 0x3e3,0x3e4,0x3e4,0x3e5,0x3e6,0x3e7,0x3e8,0x3e9,
- 0x3ea,0x3eb,0x3ec,0x3ed,0x3ee,0x3ef,0x3ef,0x3f0,
- 0x3f1,0x3f2,0x3f3,0x3f4,0x3f5,0x3f6,0x3f7,0x3f8,
- 0x3f9,0x3fa,0x3fa,0x3fb,0x3fc,0x3fd,0x3fe,0x3ff
-};
-
-/*
- * Attenuation according to GM recommendations, in -0.375 dB units.
- * table[v] = 40 * log(v / 127) / -0.375
- */
-static unsigned char snd_opl4_volume_table[128] = {
- 255,224,192,173,160,150,141,134,
- 128,122,117,113,109,105,102, 99,
- 96, 93, 90, 88, 85, 83, 81, 79,
- 77, 75, 73, 71, 70, 68, 67, 65,
- 64, 62, 61, 59, 58, 57, 56, 54,
- 53, 52, 51, 50, 49, 48, 47, 46,
- 45, 44, 43, 42, 41, 40, 39, 39,
- 38, 37, 36, 35, 34, 34, 33, 32,
- 31, 31, 30, 29, 29, 28, 27, 27,
- 26, 25, 25, 24, 24, 23, 22, 22,
- 21, 21, 20, 19, 19, 18, 18, 17,
- 17, 16, 16, 15, 15, 14, 14, 13,
- 13, 12, 12, 11, 11, 10, 10, 9,
- 9, 9, 8, 8, 7, 7, 6, 6,
- 6, 5, 5, 4, 4, 4, 3, 3,
- 2, 2, 2, 1, 1, 0, 0, 0
-};
-
-/*
- * Initializes all voices.
- */
-void snd_opl4_synth_reset(struct snd_opl4 *opl4)
-{
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&opl4->reg_lock, flags);
- for (i = 0; i < OPL4_MAX_VOICES; i++)
- snd_opl4_write(opl4, OPL4_REG_MISC + i, OPL4_DAMP_BIT);
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
-
- INIT_LIST_HEAD(&opl4->off_voices);
- INIT_LIST_HEAD(&opl4->on_voices);
- memset(opl4->voices, 0, sizeof(opl4->voices));
- for (i = 0; i < OPL4_MAX_VOICES; i++) {
- opl4->voices[i].number = i;
- list_add_tail(&opl4->voices[i].list, &opl4->off_voices);
- }
-
- snd_midi_channel_set_clear(opl4->chset);
-}
-
-/*
- * Shuts down all voices.
- */
-void snd_opl4_synth_shutdown(struct snd_opl4 *opl4)
-{
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&opl4->reg_lock, flags);
- for (i = 0; i < OPL4_MAX_VOICES; i++)
- snd_opl4_write(opl4, OPL4_REG_MISC + i,
- opl4->voices[i].reg_misc & ~OPL4_KEY_ON_BIT);
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
-}
-
-/*
- * Executes the callback for all voices playing the specified note.
- */
-static void snd_opl4_do_for_note(struct snd_opl4 *opl4, int note, struct snd_midi_channel *chan,
- void (*func)(struct snd_opl4 *opl4, struct opl4_voice *voice))
-{
- int i;
- unsigned long flags;
- struct opl4_voice *voice;
-
- spin_lock_irqsave(&opl4->reg_lock, flags);
- for (i = 0; i < OPL4_MAX_VOICES; i++) {
- voice = &opl4->voices[i];
- if (voice->chan == chan && voice->note == note) {
- func(opl4, voice);
- }
- }
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
-}
-
-/*
- * Executes the callback for all voices of to the specified channel.
- */
-static void snd_opl4_do_for_channel(struct snd_opl4 *opl4,
- struct snd_midi_channel *chan,
- void (*func)(struct snd_opl4 *opl4, struct opl4_voice *voice))
-{
- int i;
- unsigned long flags;
- struct opl4_voice *voice;
-
- spin_lock_irqsave(&opl4->reg_lock, flags);
- for (i = 0; i < OPL4_MAX_VOICES; i++) {
- voice = &opl4->voices[i];
- if (voice->chan == chan) {
- func(opl4, voice);
- }
- }
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
-}
-
-/*
- * Executes the callback for all active voices.
- */
-static void snd_opl4_do_for_all(struct snd_opl4 *opl4,
- void (*func)(struct snd_opl4 *opl4, struct opl4_voice *voice))
-{
- int i;
- unsigned long flags;
- struct opl4_voice *voice;
-
- spin_lock_irqsave(&opl4->reg_lock, flags);
- for (i = 0; i < OPL4_MAX_VOICES; i++) {
- voice = &opl4->voices[i];
- if (voice->chan)
- func(opl4, voice);
- }
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
-}
-
-static void snd_opl4_update_volume(struct snd_opl4 *opl4, struct opl4_voice *voice)
-{
- int att;
-
- att = voice->sound->tone_attenuate;
- att += snd_opl4_volume_table[opl4->chset->gs_master_volume & 0x7f];
- att += snd_opl4_volume_table[voice->chan->gm_volume & 0x7f];
- att += snd_opl4_volume_table[voice->chan->gm_expression & 0x7f];
- att += snd_opl4_volume_table[voice->velocity];
- att = 0x7f - (0x7f - att) * (voice->sound->volume_factor) / 0xfe - volume_boost;
- if (att < 0)
- att = 0;
- else if (att > 0x7e)
- att = 0x7e;
- snd_opl4_write(opl4, OPL4_REG_LEVEL + voice->number,
- (att << 1) | voice->level_direct);
- voice->level_direct = 0;
-}
-
-static void snd_opl4_update_pan(struct snd_opl4 *opl4, struct opl4_voice *voice)
-{
- int pan = voice->sound->panpot;
-
- if (!voice->chan->drum_channel)
- pan += (voice->chan->control[MIDI_CTL_MSB_PAN] - 0x40) >> 3;
- if (pan < -7)
- pan = -7;
- else if (pan > 7)
- pan = 7;
- voice->reg_misc = (voice->reg_misc & ~OPL4_PAN_POT_MASK)
- | (pan & OPL4_PAN_POT_MASK);
- snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
-}
-
-static void snd_opl4_update_vibrato_depth(struct snd_opl4 *opl4,
- struct opl4_voice *voice)
-{
- int depth;
-
- if (voice->chan->drum_channel)
- return;
- depth = (7 - voice->sound->vibrato)
- * (voice->chan->control[MIDI_CTL_VIBRATO_DEPTH] & 0x7f);
- depth = (depth >> 7) + voice->sound->vibrato;
- voice->reg_lfo_vibrato &= ~OPL4_VIBRATO_DEPTH_MASK;
- voice->reg_lfo_vibrato |= depth & OPL4_VIBRATO_DEPTH_MASK;
- snd_opl4_write(opl4, OPL4_REG_LFO_VIBRATO + voice->number,
- voice->reg_lfo_vibrato);
-}
-
-static void snd_opl4_update_pitch(struct snd_opl4 *opl4,
- struct opl4_voice *voice)
-{
- struct snd_midi_channel *chan = voice->chan;
- int note, pitch, octave;
-
- note = chan->drum_channel ? 60 : voice->note;
- /*
- * pitch is in 100/128 cents, so 0x80 is one semitone and
- * 0x600 is one octave.
- */
- pitch = ((note - 60) << 7) * voice->sound->key_scaling / 100 + (60 << 7);
- pitch += voice->sound->pitch_offset;
- if (!chan->drum_channel)
- pitch += chan->gm_rpn_coarse_tuning;
- pitch += chan->gm_rpn_fine_tuning >> 7;
- pitch += chan->midi_pitchbend * chan->gm_rpn_pitch_bend_range / 0x2000;
- if (pitch < 0)
- pitch = 0;
- else if (pitch >= 0x6000)
- pitch = 0x5fff;
- octave = pitch / 0x600 - 8;
- pitch = snd_opl4_pitch_map[pitch % 0x600];
-
- snd_opl4_write(opl4, OPL4_REG_OCTAVE + voice->number,
- (octave << 4) | ((pitch >> 7) & OPL4_F_NUMBER_HIGH_MASK));
- voice->reg_f_number = (voice->reg_f_number & OPL4_TONE_NUMBER_BIT8)
- | ((pitch << 1) & OPL4_F_NUMBER_LOW_MASK);
- snd_opl4_write(opl4, OPL4_REG_F_NUMBER + voice->number, voice->reg_f_number);
-}
-
-static void snd_opl4_update_tone_parameters(struct snd_opl4 *opl4,
- struct opl4_voice *voice)
-{
- snd_opl4_write(opl4, OPL4_REG_ATTACK_DECAY1 + voice->number,
- voice->sound->reg_attack_decay1);
- snd_opl4_write(opl4, OPL4_REG_LEVEL_DECAY2 + voice->number,
- voice->sound->reg_level_decay2);
- snd_opl4_write(opl4, OPL4_REG_RELEASE_CORRECTION + voice->number,
- voice->sound->reg_release_correction);
- snd_opl4_write(opl4, OPL4_REG_TREMOLO + voice->number,
- voice->sound->reg_tremolo);
-}
-
-/* allocate one voice */
-static struct opl4_voice *snd_opl4_get_voice(struct snd_opl4 *opl4)
-{
- /* first, try to get the oldest key-off voice */
- if (!list_empty(&opl4->off_voices))
- return list_entry(opl4->off_voices.next, struct opl4_voice, list);
- /* then get the oldest key-on voice */
- snd_BUG_ON(list_empty(&opl4->on_voices));
- return list_entry(opl4->on_voices.next, struct opl4_voice, list);
-}
-
-static void snd_opl4_wait_for_wave_headers(struct snd_opl4 *opl4)
-{
- int timeout = 200;
-
- while ((inb(opl4->fm_port) & OPL4_STATUS_LOAD) && --timeout > 0)
- udelay(10);
-}
-
-void snd_opl4_note_on(void *private_data, int note, int vel, struct snd_midi_channel *chan)
-{
- struct snd_opl4 *opl4 = private_data;
- const struct opl4_region_ptr *regions;
- struct opl4_voice *voice[2];
- const struct opl4_sound *sound[2];
- int voices = 0, i;
- unsigned long flags;
-
- /* determine the number of voices and voice parameters */
- i = chan->drum_channel ? 0x80 : (chan->midi_program & 0x7f);
- regions = &snd_yrw801_regions[i];
- for (i = 0; i < regions->count; i++) {
- if (note >= regions->regions[i].key_min &&
- note <= regions->regions[i].key_max) {
- sound[voices] = &regions->regions[i].sound;
- if (++voices >= 2)
- break;
- }
- }
-
- /* allocate and initialize the needed voices */
- spin_lock_irqsave(&opl4->reg_lock, flags);
- for (i = 0; i < voices; i++) {
- voice[i] = snd_opl4_get_voice(opl4);
- list_del(&voice[i]->list);
- list_add_tail(&voice[i]->list, &opl4->on_voices);
- voice[i]->chan = chan;
- voice[i]->note = note;
- voice[i]->velocity = vel & 0x7f;
- voice[i]->sound = sound[i];
- }
-
- /* set tone number (triggers header loading) */
- for (i = 0; i < voices; i++) {
- voice[i]->reg_f_number =
- (sound[i]->tone >> 8) & OPL4_TONE_NUMBER_BIT8;
- snd_opl4_write(opl4, OPL4_REG_F_NUMBER + voice[i]->number,
- voice[i]->reg_f_number);
- snd_opl4_write(opl4, OPL4_REG_TONE_NUMBER + voice[i]->number,
- sound[i]->tone & 0xff);
- }
-
- /* set parameters which can be set while loading */
- for (i = 0; i < voices; i++) {
- voice[i]->reg_misc = OPL4_LFO_RESET_BIT;
- snd_opl4_update_pan(opl4, voice[i]);
- snd_opl4_update_pitch(opl4, voice[i]);
- voice[i]->level_direct = OPL4_LEVEL_DIRECT_BIT;
- snd_opl4_update_volume(opl4, voice[i]);
- }
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
-
- /* wait for completion of loading */
- snd_opl4_wait_for_wave_headers(opl4);
-
- /* set remaining parameters */
- spin_lock_irqsave(&opl4->reg_lock, flags);
- for (i = 0; i < voices; i++) {
- snd_opl4_update_tone_parameters(opl4, voice[i]);
- voice[i]->reg_lfo_vibrato = voice[i]->sound->reg_lfo_vibrato;
- snd_opl4_update_vibrato_depth(opl4, voice[i]);
- }
-
- /* finally, switch on all voices */
- for (i = 0; i < voices; i++) {
- voice[i]->reg_misc =
- (voice[i]->reg_misc & 0x1f) | OPL4_KEY_ON_BIT;
- snd_opl4_write(opl4, OPL4_REG_MISC + voice[i]->number,
- voice[i]->reg_misc);
- }
- spin_unlock_irqrestore(&opl4->reg_lock, flags);
-}
-
-static void snd_opl4_voice_off(struct snd_opl4 *opl4, struct opl4_voice *voice)
-{
- list_del(&voice->list);
- list_add_tail(&voice->list, &opl4->off_voices);
-
- voice->reg_misc &= ~OPL4_KEY_ON_BIT;
- snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
-}
-
-void snd_opl4_note_off(void *private_data, int note, int vel, struct snd_midi_channel *chan)
-{
- struct snd_opl4 *opl4 = private_data;
-
- snd_opl4_do_for_note(opl4, note, chan, snd_opl4_voice_off);
-}
-
-static void snd_opl4_terminate_voice(struct snd_opl4 *opl4, struct opl4_voice *voice)
-{
- list_del(&voice->list);
- list_add_tail(&voice->list, &opl4->off_voices);
-
- voice->reg_misc = (voice->reg_misc & ~OPL4_KEY_ON_BIT) | OPL4_DAMP_BIT;
- snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
-}
-
-void snd_opl4_terminate_note(void *private_data, int note, struct snd_midi_channel *chan)
-{
- struct snd_opl4 *opl4 = private_data;
-
- snd_opl4_do_for_note(opl4, note, chan, snd_opl4_terminate_voice);
-}
-
-void snd_opl4_control(void *private_data, int type, struct snd_midi_channel *chan)
-{
- struct snd_opl4 *opl4 = private_data;
-
- switch (type) {
- case MIDI_CTL_MSB_MODWHEEL:
- chan->control[MIDI_CTL_VIBRATO_DEPTH] = chan->control[MIDI_CTL_MSB_MODWHEEL];
- snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_vibrato_depth);
- break;
- case MIDI_CTL_MSB_MAIN_VOLUME:
- snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_volume);
- break;
- case MIDI_CTL_MSB_PAN:
- snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_pan);
- break;
- case MIDI_CTL_MSB_EXPRESSION:
- snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_volume);
- break;
- case MIDI_CTL_VIBRATO_RATE:
- /* not yet supported */
- break;
- case MIDI_CTL_VIBRATO_DEPTH:
- snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_vibrato_depth);
- break;
- case MIDI_CTL_VIBRATO_DELAY:
- /* not yet supported */
- break;
- case MIDI_CTL_E1_REVERB_DEPTH:
- /*
- * Each OPL4 voice has a bit called "Pseudo-Reverb", but
- * IMHO _not_ using it enhances the listening experience.
- */
- break;
- case MIDI_CTL_PITCHBEND:
- snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_pitch);
- break;
- }
-}
-
-void snd_opl4_sysex(void *private_data, unsigned char *buf, int len,
- int parsed, struct snd_midi_channel_set *chset)
-{
- struct snd_opl4 *opl4 = private_data;
-
- if (parsed == SNDRV_MIDI_SYSEX_GS_MASTER_VOLUME)
- snd_opl4_do_for_all(opl4, snd_opl4_update_volume);
-}
diff --git a/ANDROID_3.4.5/sound/drivers/opl4/yrw801.c b/ANDROID_3.4.5/sound/drivers/opl4/yrw801.c
deleted file mode 100644
index 6c335492..00000000
--- a/ANDROID_3.4.5/sound/drivers/opl4/yrw801.c
+++ /dev/null
@@ -1,961 +0,0 @@
-/*
- * Information about the Yamaha YRW801 wavetable ROM chip
- *
- * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed and/or modified under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "opl4_local.h"
-
-int snd_yrw801_detect(struct snd_opl4 *opl4)
-{
- char buf[15];
-
- snd_opl4_read_memory(opl4, buf, 0x001200, 15);
- if (memcmp(buf, "CopyrightYAMAHA", 15))
- return -ENODEV;
- snd_opl4_read_memory(opl4, buf, 0x1ffffe, 2);
- if (buf[0] != 0x01)
- return -ENODEV;
- snd_printdd("YRW801 ROM version %02x.%02x\n", buf[0], buf[1]);
- return 0;
-}
-
-/*
- * The instrument definitions are stored statically because, in practice, the
- * OPL4 is always coupled with a YRW801. Dynamic instrument loading would be
- * required if downloading sample data to external SRAM was actually supported
- * by this driver.
- */
-
-static const struct opl4_region regions_00[] = { /* Acoustic Grand Piano */
- {0x14, 0x27, {0x12c,7474,100, 0,0,0x00,0xc8,0x20,0xf2,0x13,0x08,0x0}},
- {0x28, 0x2d, {0x12d,6816,100, 0,0,0x00,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x2e, 0x33, {0x12e,5899,100, 0,0,0x00,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x34, 0x39, {0x12f,5290,100, 0,0,0x00,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x3a, 0x3f, {0x130,4260,100, 0,0,0x0a,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x40, 0x45, {0x131,3625,100, 0,0,0x0a,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x46, 0x4b, {0x132,3116,100, 0,0,0x04,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x4c, 0x52, {0x133,2081,100, 0,0,0x03,0xc8,0x20,0xf2,0x14,0x18,0x0}},
- {0x53, 0x58, {0x134,1444,100, 0,0,0x07,0xc8,0x20,0xf3,0x14,0x18,0x0}},
- {0x59, 0x6d, {0x135,1915,100, 0,0,0x00,0xc8,0x20,0xf4,0x15,0x08,0x0}}
-};
-static const struct opl4_region regions_01[] = { /* Bright Acoustic Piano */
- {0x14, 0x2d, {0x12c,7474,100, 0,0,0x00,0xc8,0x20,0xf2,0x13,0x08,0x0}},
- {0x2e, 0x33, {0x12d,6816,100, 0,0,0x00,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x34, 0x39, {0x12e,5899,100, 0,0,0x00,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x3a, 0x3f, {0x12f,5290,100, 0,0,0x00,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x40, 0x45, {0x130,4260,100, 0,0,0x0a,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x46, 0x4b, {0x131,3625,100, 0,0,0x0a,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x4c, 0x52, {0x132,3116,100, 0,0,0x04,0xc8,0x20,0xf2,0x14,0x08,0x0}},
- {0x53, 0x58, {0x133,2081,100, 0,0,0x07,0xc8,0x20,0xf2,0x14,0x18,0x0}},
- {0x59, 0x5e, {0x134,1444,100, 0,0,0x0a,0xc8,0x20,0xf3,0x14,0x18,0x0}},
- {0x5f, 0x6d, {0x135,1915,100, 0,0,0x00,0xc8,0x20,0xf4,0x15,0x08,0x0}}
-};
-static const struct opl4_region regions_02[] = { /* Electric Grand Piano */
- {0x14, 0x2d, {0x12c,7476,100, 1,0,0x00,0xae,0x20,0xf2,0x13,0x07,0x0}},
- {0x2e, 0x33, {0x12d,6818,100, 1,0,0x00,0xae,0x20,0xf2,0x14,0x07,0x0}},
- {0x34, 0x39, {0x12e,5901,100, 1,0,0x00,0xae,0x20,0xf2,0x14,0x07,0x0}},
- {0x3a, 0x3f, {0x12f,5292,100, 1,0,0x00,0xae,0x20,0xf2,0x14,0x07,0x0}},
- {0x40, 0x45, {0x130,4262,100, 1,0,0x00,0xae,0x20,0xf2,0x14,0x07,0x0}},
- {0x46, 0x4b, {0x131,3627,100, 1,0,0x00,0xae,0x20,0xf2,0x14,0x07,0x0}},
- {0x4c, 0x52, {0x132,3118,100, 1,0,0x00,0xae,0x20,0xf2,0x14,0x07,0x0}},
- {0x53, 0x58, {0x133,2083,100, 1,0,0x00,0xae,0x20,0xf2,0x14,0x17,0x0}},
- {0x59, 0x5e, {0x134,1446,100, 1,0,0x00,0xae,0x20,0xf3,0x14,0x17,0x0}},
- {0x5f, 0x6d, {0x135,1917,100, 1,0,0x00,0xae,0x20,0xf4,0x15,0x07,0x0}},
- {0x00, 0x7f, {0x06c,6375,100,-1,0,0x00,0xc2,0x28,0xf4,0x23,0x18,0x0}}
-};
-static const struct opl4_region regions_03[] = { /* Honky-Tonk Piano */
- {0x14, 0x27, {0x12c,7474,100, 0,0,0x00,0xb4,0x20,0xf2,0x13,0x08,0x0}},
- {0x28, 0x2d, {0x12d,6816,100, 0,0,0x00,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x2e, 0x33, {0x12e,5899,100, 0,0,0x00,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x34, 0x39, {0x12f,5290,100, 0,0,0x00,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x3a, 0x3f, {0x130,4260,100, 0,0,0x0a,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x40, 0x45, {0x131,3625,100, 0,0,0x0a,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x46, 0x4b, {0x132,3116,100, 0,0,0x04,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x4c, 0x52, {0x133,2081,100, 0,0,0x03,0xb4,0x20,0xf2,0x14,0x18,0x0}},
- {0x53, 0x58, {0x134,1444,100, 0,0,0x07,0xb4,0x20,0xf3,0x14,0x18,0x0}},
- {0x59, 0x6d, {0x135,1915,100, 0,0,0x00,0xb4,0x20,0xf4,0x15,0x08,0x0}},
- {0x14, 0x27, {0x12c,7486,100, 0,0,0x00,0xb4,0x20,0xf2,0x13,0x08,0x0}},
- {0x28, 0x2d, {0x12d,6803,100, 0,0,0x00,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x2e, 0x33, {0x12e,5912,100, 0,0,0x00,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x34, 0x39, {0x12f,5275,100, 0,0,0x00,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x3a, 0x3f, {0x130,4274,100, 0,0,0x0a,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x40, 0x45, {0x131,3611,100, 0,0,0x0a,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x46, 0x4b, {0x132,3129,100, 0,0,0x04,0xb4,0x20,0xf2,0x14,0x08,0x0}},
- {0x4c, 0x52, {0x133,2074,100, 0,0,0x07,0xb4,0x20,0xf2,0x14,0x18,0x0}},
- {0x53, 0x58, {0x134,1457,100, 0,0,0x01,0xb4,0x20,0xf3,0x14,0x18,0x0}},
- {0x59, 0x6d, {0x135,1903,100, 0,0,0x00,0xb4,0x20,0xf4,0x15,0x08,0x0}}
-};
-static const struct opl4_region regions_04[] = { /* Electric Piano 1 */
- {0x15, 0x6c, {0x00b,6570,100, 0,0,0x00,0x28,0x38,0xf0,0x00,0x0c,0x0}},
- {0x00, 0x7f, {0x06c,6375,100, 0,2,0x00,0xb0,0x22,0xf4,0x23,0x19,0x0}}
-};
-static const struct opl4_region regions_05[] = { /* Electric Piano 2 */
- {0x14, 0x27, {0x12c,7476,100, 0,3,0x00,0xa2,0x1b,0xf2,0x13,0x08,0x0}},
- {0x28, 0x2d, {0x12d,6818,100, 0,3,0x00,0xa2,0x1b,0xf2,0x14,0x08,0x0}},
- {0x2e, 0x33, {0x12e,5901,100, 0,3,0x00,0xa2,0x1b,0xf2,0x14,0x08,0x0}},
- {0x34, 0x39, {0x12f,5292,100, 0,3,0x00,0xa2,0x1b,0xf2,0x14,0x08,0x0}},
- {0x3a, 0x3f, {0x130,4262,100, 0,3,0x0a,0xa2,0x1b,0xf2,0x14,0x08,0x0}},
- {0x40, 0x45, {0x131,3627,100, 0,3,0x0a,0xa2,0x1b,0xf2,0x14,0x08,0x0}},
- {0x46, 0x4b, {0x132,3118,100, 0,3,0x04,0xa2,0x1b,0xf2,0x14,0x08,0x0}},
- {0x4c, 0x52, {0x133,2083,100, 0,3,0x03,0xa2,0x1b,0xf2,0x14,0x18,0x0}},
- {0x53, 0x58, {0x134,1446,100, 0,3,0x07,0xa2,0x1b,0xf3,0x14,0x18,0x0}},
- {0x59, 0x6d, {0x135,1917,100, 0,3,0x00,0xa2,0x1b,0xf4,0x15,0x08,0x0}},
- {0x14, 0x2d, {0x12c,7472,100, 0,0,0x00,0xa2,0x18,0xf2,0x13,0x08,0x0}},
- {0x2e, 0x33, {0x12d,6814,100, 0,0,0x00,0xa2,0x18,0xf2,0x14,0x08,0x0}},
- {0x34, 0x39, {0x12e,5897,100, 0,0,0x00,0xa2,0x18,0xf2,0x14,0x08,0x0}},
- {0x3a, 0x3f, {0x12f,5288,100, 0,0,0x00,0xa2,0x18,0xf2,0x14,0x08,0x0}},
- {0x40, 0x45, {0x130,4258,100, 0,0,0x0a,0xa2,0x18,0xf2,0x14,0x08,0x0}},
- {0x46, 0x4b, {0x131,3623,100, 0,0,0x0a,0xa2,0x18,0xf2,0x14,0x08,0x0}},
- {0x4c, 0x52, {0x132,3114,100, 0,0,0x04,0xa2,0x18,0xf2,0x14,0x08,0x0}},
- {0x53, 0x58, {0x133,2079,100, 0,0,0x07,0xa2,0x18,0xf2,0x14,0x18,0x0}},
- {0x59, 0x5e, {0x134,1442,100, 0,0,0x0a,0xa2,0x18,0xf3,0x14,0x18,0x0}},
- {0x5f, 0x6d, {0x135,1913,100, 0,0,0x00,0xa2,0x18,0xf4,0x15,0x08,0x0}}
-};
-static const struct opl4_region regions_06[] = { /* Harpsichord */
- {0x15, 0x39, {0x080,5158,100, 0,0,0x00,0xb2,0x20,0xf5,0x24,0x19,0x0}},
- {0x3a, 0x3f, {0x081,4408,100, 0,0,0x00,0xb2,0x20,0xf5,0x25,0x09,0x0}},
- {0x40, 0x45, {0x082,3622,100, 0,0,0x00,0xb2,0x20,0xf5,0x25,0x09,0x0}},
- {0x46, 0x4d, {0x083,2843,100, 0,0,0x00,0xb2,0x20,0xf5,0x25,0x19,0x0}},
- {0x4e, 0x6c, {0x084,1307,100, 0,0,0x00,0xb2,0x20,0xf5,0x25,0x29,0x0}}
-};
-static const struct opl4_region regions_07[] = { /* Clavinet */
- {0x15, 0x51, {0x027,5009,100, 0,0,0x00,0xd2,0x28,0xf5,0x13,0x2b,0x0}},
- {0x52, 0x6c, {0x028,3495,100, 0,0,0x00,0xd2,0x28,0xf5,0x13,0x3b,0x0}}
-};
-static const struct opl4_region regions_08[] = { /* Celesta */
- {0x15, 0x6c, {0x02b,3267,100, 0,0,0x00,0xdc,0x20,0xf4,0x15,0x07,0x3}}
-};
-static const struct opl4_region regions_09[] = { /* Glockenspiel */
- {0x15, 0x78, {0x0f3, 285,100, 0,0,0x00,0xc2,0x28,0xf6,0x25,0x25,0x0}}
-};
-static const struct opl4_region regions_0a[] = { /* Music Box */
- {0x15, 0x6c, {0x0f3,3362,100, 0,0,0x00,0xb6,0x20,0xa6,0x25,0x25,0x0}},
- {0x15, 0x6c, {0x101,4773,100, 0,0,0x00,0xaa,0x20,0xd4,0x14,0x16,0x0}}
-};
-static const struct opl4_region regions_0b[] = { /* Vibraphone */
- {0x15, 0x6c, {0x101,4778,100, 0,0,0x00,0xc0,0x28,0xf4,0x14,0x16,0x4}}
-};
-static const struct opl4_region regions_0c[] = { /* Marimba */
- {0x15, 0x3f, {0x0f4,4778,100, 0,0,0x00,0xc4,0x38,0xf7,0x47,0x08,0x0}},
- {0x40, 0x4c, {0x0f5,3217,100, 0,0,0x00,0xc4,0x38,0xf7,0x47,0x08,0x0}},
- {0x4d, 0x5a, {0x0f5,3217,100, 0,0,0x00,0xc4,0x38,0xf7,0x48,0x08,0x0}},
- {0x5b, 0x7f, {0x0f5,3218,100, 0,0,0x00,0xc4,0x38,0xf7,0x48,0x18,0x0}}
-};
-static const struct opl4_region regions_0d[] = { /* Xylophone */
- {0x00, 0x7f, {0x136,1729,100, 0,0,0x00,0xd2,0x38,0xf0,0x06,0x36,0x0}}
-};
-static const struct opl4_region regions_0e[] = { /* Tubular Bell */
- {0x01, 0x7f, {0x0ff,3999,100, 0,1,0x00,0x90,0x21,0xf4,0xa3,0x25,0x1}}
-};
-static const struct opl4_region regions_0f[] = { /* Dulcimer */
- {0x00, 0x7f, {0x03f,4236,100, 0,1,0x00,0xbc,0x29,0xf5,0x16,0x07,0x0}},
- {0x00, 0x7f, {0x040,4236,100, 0,2,0x0e,0x94,0x2a,0xf5,0x16,0x07,0x0}}
-};
-static const struct opl4_region regions_10[] = { /* Drawbar Organ */
- {0x01, 0x7f, {0x08e,4394,100, 0,2,0x14,0xc2,0x3a,0xf0,0x00,0x0a,0x0}}
-};
-static const struct opl4_region regions_11[] = { /* Percussive Organ */
- {0x15, 0x3b, {0x08c,6062,100, 0,3,0x00,0xbe,0x3b,0xf0,0x00,0x09,0x0}},
- {0x3c, 0x6c, {0x08d,2984,100, 0,3,0x00,0xbe,0x3b,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_12[] = { /* Rock Organ */
- {0x15, 0x30, {0x128,6574,100, 0,1,0x00,0xcc,0x39,0xf0,0x00,0x0a,0x0}},
- {0x31, 0x3c, {0x129,5040,100, 0,1,0x00,0xcc,0x39,0xf0,0x00,0x0a,0x0}},
- {0x3d, 0x48, {0x12a,3498,100, 0,1,0x00,0xcc,0x39,0xf0,0x00,0x0a,0x0}},
- {0x49, 0x54, {0x12b,1957,100, 0,1,0x00,0xcc,0x39,0xf0,0x00,0x0a,0x0}},
- {0x55, 0x6c, {0x127, 423,100, 0,1,0x00,0xcc,0x39,0xf0,0x00,0x0a,0x0}}
-};
-static const struct opl4_region regions_13[] = { /* Church Organ */
- {0x15, 0x29, {0x087,7466,100, 0,1,0x00,0xc4,0x11,0xf0,0x00,0x09,0x0}},
- {0x2a, 0x30, {0x088,6456,100, 0,1,0x00,0xc4,0x11,0xf0,0x00,0x09,0x0}},
- {0x31, 0x38, {0x089,5428,100, 0,1,0x00,0xc4,0x11,0xf0,0x00,0x09,0x0}},
- {0x39, 0x41, {0x08a,4408,100, 0,1,0x00,0xc4,0x11,0xf0,0x00,0x09,0x0}},
- {0x42, 0x6c, {0x08b,3406,100, 0,1,0x00,0xc4,0x11,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_14[] = { /* Reed Organ */
- {0x00, 0x53, {0x0ac,5570,100, 0,0,0x06,0xc0,0x38,0xf0,0x00,0x09,0x1}},
- {0x54, 0x7f, {0x0ad,2497,100, 0,0,0x00,0xc0,0x38,0xf0,0x00,0x09,0x1}}
-};
-static const struct opl4_region regions_15[] = { /* Accordion */
- {0x15, 0x4c, {0x006,4261,100, 0,2,0x00,0xa4,0x22,0x90,0x00,0x09,0x0}},
- {0x4d, 0x6c, {0x007,1530,100, 0,2,0x00,0xa4,0x22,0x90,0x00,0x09,0x0}},
- {0x15, 0x6c, {0x070,4391,100, 0,3,0x00,0x8a,0x23,0xa0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_16[] = { /* Harmonica */
- {0x15, 0x6c, {0x070,4408,100, 0,0,0x00,0xae,0x30,0xa0,0x00,0x09,0x2}}
-};
-static const struct opl4_region regions_17[] = { /* Tango Accordion */
- {0x00, 0x53, {0x0ac,5573,100, 0,0,0x00,0xae,0x38,0xf0,0x00,0x09,0x0}},
- {0x54, 0x7f, {0x0ad,2500,100, 0,0,0x00,0xae,0x38,0xf0,0x00,0x09,0x0}},
- {0x15, 0x6c, {0x041,8479,100, 0,2,0x00,0x6a,0x3a,0x75,0x20,0x0a,0x0}}
-};
-static const struct opl4_region regions_18[] = { /* Nylon Guitar */
- {0x15, 0x2f, {0x0b3,6964,100, 0,0,0x05,0xca,0x28,0xf5,0x34,0x09,0x0}},
- {0x30, 0x36, {0x0b7,5567,100, 0,0,0x0c,0xca,0x28,0xf5,0x34,0x09,0x0}},
- {0x37, 0x3c, {0x0b5,4653,100, 0,0,0x00,0xca,0x28,0xf6,0x34,0x09,0x0}},
- {0x3d, 0x43, {0x0b4,3892,100, 0,0,0x00,0xca,0x28,0xf6,0x35,0x09,0x0}},
- {0x44, 0x60, {0x0b6,2723,100, 0,0,0x00,0xca,0x28,0xf6,0x35,0x19,0x0}}
-};
-static const struct opl4_region regions_19[] = { /* Steel Guitar */
- {0x15, 0x31, {0x00c,6937,100, 0,0,0x00,0xbc,0x28,0xf0,0x04,0x19,0x0}},
- {0x32, 0x38, {0x00d,5410,100, 0,0,0x00,0xbc,0x28,0xf0,0x05,0x09,0x0}},
- {0x39, 0x47, {0x00e,4379,100, 0,0,0x00,0xbc,0x28,0xf5,0x94,0x09,0x0}},
- {0x48, 0x6c, {0x00f,2843,100, 0,0,0x00,0xbc,0x28,0xf6,0x95,0x09,0x0}}
-};
-static const struct opl4_region regions_1a[] = { /* Jazz Guitar */
- {0x15, 0x31, {0x05a,6832,100, 0,0,0x00,0xca,0x28,0xf6,0x34,0x09,0x0}},
- {0x32, 0x3f, {0x05b,4897,100, 0,0,0x00,0xca,0x28,0xf6,0x34,0x09,0x0}},
- {0x40, 0x6c, {0x05c,3218,100, 0,0,0x00,0xca,0x28,0xf6,0x34,0x09,0x0}}
-};
-static const struct opl4_region regions_1b[] = { /* Clean Guitar */
- {0x15, 0x2c, {0x061,7053,100, 0,1,0x00,0xb4,0x29,0xf5,0x54,0x0a,0x0}},
- {0x2d, 0x31, {0x060,6434,100, 0,1,0x00,0xb4,0x29,0xf5,0x54,0x0a,0x0}},
- {0x32, 0x38, {0x063,5764,100, 0,1,0x00,0xbe,0x29,0xf5,0x55,0x0a,0x0}},
- {0x39, 0x3f, {0x062,4627,100, 0,1,0x00,0xb4,0x29,0xf5,0x55,0x0a,0x0}},
- {0x40, 0x44, {0x065,3963,100, 0,1,0x00,0xb4,0x29,0xf5,0x55,0x1a,0x0}},
- {0x45, 0x4b, {0x064,3313,100, 0,1,0x00,0xb4,0x29,0xf5,0x55,0x1a,0x0}},
- {0x4c, 0x54, {0x066,2462,100, 0,1,0x00,0xb4,0x29,0xf5,0x55,0x2a,0x0}},
- {0x55, 0x6c, {0x067,1307,100, 0,1,0x00,0xb4,0x29,0xf6,0x56,0x0a,0x0}}
-};
-static const struct opl4_region regions_1c[] = { /* Muted Guitar */
- {0x01, 0x7f, {0x068,4408,100, 0,0,0x00,0xcc,0x28,0xf6,0x15,0x09,0x0}}
-};
-static const struct opl4_region regions_1d[] = { /* Overdriven Guitar */
- {0x00, 0x40, {0x0a5,6589,100, 0,1,0x00,0xc0,0x29,0xf2,0x11,0x09,0x0}},
- {0x41, 0x7f, {0x0a6,5428,100, 0,1,0x00,0xc0,0x29,0xf2,0x11,0x09,0x0}}
-};
-static const struct opl4_region regions_1e[] = { /* Distortion Guitar */
- {0x15, 0x2a, {0x051,6928,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}},
- {0x2b, 0x2e, {0x052,6433,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}},
- {0x2f, 0x32, {0x053,5944,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}},
- {0x33, 0x36, {0x054,5391,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}},
- {0x37, 0x3a, {0x055,4897,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}},
- {0x3b, 0x3e, {0x056,4408,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}},
- {0x3f, 0x42, {0x057,3892,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}},
- {0x43, 0x46, {0x058,3361,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}},
- {0x47, 0x6c, {0x059,2784,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}}
-};
-static const struct opl4_region regions_1f[] = { /* Guitar Harmonics */
- {0x15, 0x44, {0x05e,5499,100, 0,0,0x00,0xce,0x28,0xf4,0x24,0x09,0x0}},
- {0x45, 0x49, {0x05d,4850,100, 0,0,0x00,0xe2,0x28,0xf4,0x24,0x09,0x0}},
- {0x4a, 0x6c, {0x05f,4259,100, 0,0,0x00,0xce,0x28,0xf4,0x24,0x09,0x0}}
-};
-static const struct opl4_region regions_20[] = { /* Acoustic Bass */
- {0x15, 0x30, {0x004,8053,100, 0,0,0x00,0xe2,0x18,0xf5,0x15,0x09,0x0}},
- {0x31, 0x6c, {0x005,4754,100, 0,0,0x00,0xe2,0x18,0xf5,0x15,0x09,0x0}}
-};
-static const struct opl4_region regions_21[] = { /* Fingered Bass */
- {0x01, 0x20, {0x04a,8762,100, 0,0,0x00,0xde,0x18,0xf6,0x14,0x09,0x0}},
- {0x21, 0x25, {0x04b,8114,100, 0,0,0x00,0xde,0x18,0xf6,0x14,0x09,0x0}},
- {0x26, 0x2a, {0x04c,7475,100, 0,0,0x00,0xde,0x18,0xf6,0x14,0x09,0x0}},
- {0x2b, 0x7f, {0x04d,6841,100, 0,0,0x00,0xde,0x18,0xf6,0x14,0x09,0x0}}
-};
-static const struct opl4_region regions_22[] = { /* Picked Bass */
- {0x15, 0x23, {0x04f,7954,100, 0,0,0x00,0xcc,0x18,0xf3,0x90,0x0a,0x0}},
- {0x24, 0x2a, {0x050,7318,100, 0,0,0x05,0xcc,0x18,0xf3,0x90,0x1a,0x0}},
- {0x2b, 0x2f, {0x06b,6654,100, 0,0,0x00,0xcc,0x18,0xf3,0x90,0x2a,0x0}},
- {0x30, 0x47, {0x069,6031,100, 0,0,0x00,0xcc,0x18,0xf5,0xb0,0x0a,0x0}},
- {0x48, 0x6c, {0x06a,5393,100, 0,0,0x00,0xcc,0x18,0xf5,0xb0,0x0a,0x0}}
-};
-static const struct opl4_region regions_23[] = { /* Fretless Bass */
- {0x01, 0x7f, {0x04e,5297,100, 0,0,0x00,0xd2,0x10,0xf3,0x63,0x19,0x0}}
-};
-static const struct opl4_region regions_24[] = { /* Slap Bass 1 */
- {0x15, 0x6c, {0x0a3,7606,100, 0,1,0x00,0xde,0x19,0xf5,0x32,0x1a,0x0}}
-};
-static const struct opl4_region regions_25[] = { /* Slap Bass 2 */
- {0x01, 0x7f, {0x0a2,6694,100, 0,0,0x00,0xda,0x20,0xb0,0x02,0x09,0x0}}
-};
-static const struct opl4_region regions_26[] = { /* Synth Bass 1 */
- {0x15, 0x6c, {0x0be,7466,100, 0,1,0x00,0xb8,0x39,0xf4,0x14,0x09,0x0}}
-};
-static const struct opl4_region regions_27[] = { /* Synth Bass 2 */
- {0x00, 0x7f, {0x117,8103,100, 0,1,0x00,0xca,0x39,0xf3,0x50,0x08,0x0}}
-};
-static const struct opl4_region regions_28[] = { /* Violin */
- {0x15, 0x3a, {0x105,5158,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
- {0x3b, 0x3f, {0x102,4754,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
- {0x40, 0x41, {0x106,4132,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
- {0x42, 0x44, {0x107,4033,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
- {0x45, 0x47, {0x108,3580,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
- {0x48, 0x4a, {0x10a,2957,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
- {0x4b, 0x4c, {0x10b,2724,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
- {0x4d, 0x4e, {0x10c,2530,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
- {0x4f, 0x51, {0x10d,2166,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
- {0x52, 0x6c, {0x109,1825,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}}
-};
-static const struct opl4_region regions_29[] = { /* Viola */
- {0x15, 0x32, {0x103,5780,100, 0,3,0x00,0xc4,0x3b,0xa3,0x20,0x09,0x0}},
- {0x33, 0x35, {0x104,5534,100, 0,3,0x00,0xc4,0x3b,0xa3,0x20,0x09,0x0}},
- {0x36, 0x38, {0x105,5158,100, 0,3,0x00,0xc4,0x3b,0xa3,0x20,0x09,0x0}},
- {0x39, 0x3d, {0x102,4754,100, 0,3,0x00,0xca,0x3b,0xa3,0x20,0x09,0x0}},
- {0x3e, 0x3f, {0x106,4132,100, 0,3,0x00,0xc4,0x3b,0xa3,0x20,0x09,0x0}},
- {0x40, 0x42, {0x107,4033,100, 0,3,0x00,0xc4,0x3b,0xa3,0x20,0x09,0x0}},
- {0x43, 0x45, {0x108,3580,100, 0,3,0x00,0xd0,0x3b,0xa3,0x20,0x09,0x0}},
- {0x46, 0x48, {0x10a,2957,100, 0,3,0x00,0xca,0x3b,0xa3,0x20,0x09,0x0}},
- {0x49, 0x4a, {0x10b,2724,100, 0,3,0x00,0xd0,0x3b,0xa3,0x20,0x09,0x0}},
- {0x4b, 0x4c, {0x10c,2530,100, 0,3,0x00,0xca,0x3b,0xa3,0x20,0x09,0x0}},
- {0x4d, 0x4f, {0x10d,2166,100, 0,3,0x00,0xd0,0x3b,0xa3,0x20,0x09,0x0}},
- {0x50, 0x6c, {0x109,1825,100, 0,3,0x00,0xd0,0x3b,0xa3,0x20,0x09,0x0}}
-};
-static const struct opl4_region regions_2a[] = { /* Cello */
- {0x15, 0x2d, {0x112,6545,100, 0,3,0x00,0xc0,0x33,0xa0,0x00,0x08,0x0}},
- {0x2e, 0x37, {0x113,5764,100, 0,3,0x00,0xc0,0x33,0xa0,0x00,0x08,0x0}},
- {0x38, 0x3e, {0x115,4378,100, 0,3,0x00,0xc0,0x33,0xa0,0x00,0x18,0x0}},
- {0x3f, 0x44, {0x116,3998,100, 0,3,0x00,0xc0,0x33,0xa0,0x00,0x18,0x0}},
- {0x45, 0x6c, {0x114,3218,100, 0,3,0x00,0xc0,0x33,0xa0,0x00,0x18,0x0}}
-};
-static const struct opl4_region regions_2b[] = { /* Contrabass */
- {0x15, 0x29, {0x110,7713,100, 0,1,0x00,0xc2,0x19,0x90,0x00,0x09,0x0}},
- {0x2a, 0x6c, {0x111,6162,100, 0,1,0x00,0xc2,0x19,0x90,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_2c[] = { /* Tremolo Strings */
- {0x15, 0x3b, {0x0b0,4810,100, 0,0,0x0a,0xde,0x38,0xf0,0x00,0x07,0x6}},
- {0x3c, 0x41, {0x035,4035,100, 0,0,0x05,0xde,0x38,0xf0,0x00,0x07,0x6}},
- {0x42, 0x47, {0x033,3129,100, 0,0,0x05,0xde,0x38,0xf0,0x00,0x07,0x6}},
- {0x48, 0x52, {0x034,2625,100, 0,0,0x05,0xde,0x38,0xf0,0x00,0x07,0x6}},
- {0x53, 0x6c, {0x0af, 936,100, 0,0,0x00,0xde,0x38,0xf0,0x00,0x07,0x6}}
-};
-static const struct opl4_region regions_2d[] = { /* Pizzicato Strings */
- {0x15, 0x32, {0x0b8,6186,100, 0,0,0x00,0xbc,0x28,0xf0,0x00,0x05,0x0}},
- {0x33, 0x3b, {0x0b9,5031,100, 0,0,0x00,0xbc,0x28,0xf0,0x00,0x05,0x0}},
- {0x3c, 0x42, {0x0bb,4146,100, 0,0,0x00,0xbc,0x28,0xf0,0x00,0x05,0x0}},
- {0x43, 0x48, {0x0ba,3245,100, 0,0,0x00,0xc2,0x28,0xf0,0x00,0x05,0x0}},
- {0x49, 0x6c, {0x0bc,2352,100, 0,0,0x00,0xbc,0x28,0xf0,0x00,0x05,0x0}}
-};
-static const struct opl4_region regions_2e[] = { /* Harp */
- {0x15, 0x46, {0x07e,3740,100, 0,1,0x00,0xd2,0x29,0xf5,0x25,0x07,0x0}},
- {0x47, 0x6c, {0x07f,2319,100, 0,1,0x00,0xd2,0x29,0xf5,0x25,0x07,0x0}}
-};
-static const struct opl4_region regions_2f[] = { /* Timpani */
- {0x15, 0x6c, {0x100,6570,100, 0,0,0x00,0xf8,0x28,0xf0,0x05,0x16,0x0}}
-};
-static const struct opl4_region regions_30[] = { /* Strings */
- {0x15, 0x3b, {0x13c,4806,100, 0,0,0x00,0xc8,0x20,0x80,0x00,0x07,0x0}},
- {0x3c, 0x41, {0x13e,4035,100, 0,0,0x00,0xc8,0x20,0x80,0x00,0x07,0x0}},
- {0x42, 0x47, {0x13d,3122,100, 0,0,0x00,0xc8,0x20,0x80,0x00,0x07,0x0}},
- {0x48, 0x52, {0x13f,2629,100, 0,0,0x00,0xbe,0x20,0x80,0x00,0x07,0x0}},
- {0x53, 0x6c, {0x140, 950,100, 0,0,0x00,0xbe,0x20,0x80,0x00,0x07,0x0}}
-};
-static const struct opl4_region regions_31[] = { /* Slow Strings */
- {0x15, 0x3b, {0x0b0,4810,100, 0,1,0x0a,0xbe,0x19,0xf0,0x00,0x07,0x0}},
- {0x3c, 0x41, {0x035,4035,100, 0,1,0x05,0xbe,0x19,0xf0,0x00,0x07,0x0}},
- {0x42, 0x47, {0x033,3129,100, 0,1,0x05,0xbe,0x19,0xf0,0x00,0x07,0x0}},
- {0x48, 0x52, {0x034,2625,100, 0,1,0x05,0xbe,0x19,0xf0,0x00,0x07,0x0}},
- {0x53, 0x6c, {0x0af, 936,100, 0,1,0x00,0xbe,0x19,0xf0,0x00,0x07,0x0}}
-};
-static const struct opl4_region regions_32[] = { /* Synth Strings 1 */
- {0x05, 0x71, {0x002,6045,100,-2,0,0x00,0xa6,0x20,0x93,0x22,0x06,0x0}},
- {0x15, 0x6c, {0x0ae,3261,100, 2,0,0x00,0xc6,0x20,0x70,0x01,0x06,0x0}}
-};
-static const struct opl4_region regions_33[] = { /* Synth Strings 2 */
- {0x15, 0x6c, {0x002,4513,100, 5,1,0x00,0xb4,0x19,0x70,0x00,0x06,0x0}},
- {0x15, 0x6c, {0x002,4501,100,-5,1,0x00,0xb4,0x19,0x70,0x00,0x06,0x0}}
-};
-static const struct opl4_region regions_34[] = { /* Choir Aahs */
- {0x15, 0x3a, {0x018,5010,100, 0,2,0x00,0xc2,0x1a,0x70,0x00,0x08,0x0}},
- {0x3b, 0x40, {0x019,4370,100, 0,2,0x00,0xc2,0x1a,0x70,0x00,0x08,0x0}},
- {0x41, 0x47, {0x01a,3478,100, 0,2,0x00,0xc2,0x1a,0x70,0x00,0x08,0x0}},
- {0x48, 0x6c, {0x01b,2197,100, 0,2,0x00,0xc2,0x1a,0x70,0x00,0x08,0x0}}
-};
-static const struct opl4_region regions_35[] = { /* Voice Oohs */
- {0x15, 0x6c, {0x029,3596,100, 0,0,0x00,0xe6,0x20,0xf7,0x20,0x08,0x0}}
-};
-static const struct opl4_region regions_36[] = { /* Synth Voice */
- {0x15, 0x6c, {0x02a,3482,100, 0,1,0x00,0xc2,0x19,0x85,0x21,0x07,0x0}}
-};
-static const struct opl4_region regions_37[] = { /* Orchestra Hit */
- {0x15, 0x6c, {0x049,4394,100, 0,0,0x00,0xfe,0x30,0x80,0x05,0x05,0x0}}
-};
-static const struct opl4_region regions_38[] = { /* Trumpet */
- {0x15, 0x3c, {0x0f6,4706,100, 0,2,0x00,0xd6,0x32,0xf3,0x20,0x0a,0x0}},
- {0x3d, 0x43, {0x0f8,3894,100, 0,2,0x00,0xd6,0x32,0xf3,0x20,0x0a,0x0}},
- {0x44, 0x48, {0x0f7,3118,100, 0,2,0x00,0xd6,0x32,0xf3,0x20,0x0a,0x0}},
- {0x49, 0x4e, {0x0fa,2322,100, 0,2,0x00,0xd6,0x32,0xf3,0x20,0x0a,0x0}},
- {0x4f, 0x55, {0x0f9,1634,100, 0,2,0x00,0xd6,0x32,0xf3,0x20,0x0a,0x0}},
- {0x56, 0x6c, {0x0fb, 786,100, 0,2,0x00,0xd6,0x32,0xf3,0x20,0x0a,0x0}}
-};
-static const struct opl4_region regions_39[] = { /* Trombone */
- {0x15, 0x3a, {0x0f0,5053,100, 0,1,0x00,0xd6,0x21,0xf0,0x00,0x09,0x0}},
- {0x3b, 0x3f, {0x0f1,4290,100, 0,1,0x00,0xd6,0x21,0xf0,0x00,0x09,0x0}},
- {0x40, 0x6c, {0x0f2,3580,100, 0,1,0x00,0xd6,0x21,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_3a[] = { /* Tuba */
- {0x15, 0x2d, {0x085,7096,100, 0,1,0x00,0xde,0x21,0xf5,0x10,0x09,0x0}},
- {0x2e, 0x6c, {0x086,6014,100, 0,1,0x00,0xde,0x21,0xf5,0x10,0x09,0x0}}
-};
-static const struct opl4_region regions_3b[] = { /* Muted Trumpet */
- {0x15, 0x45, {0x0b1,4135,100, 0,0,0x00,0xcc,0x28,0xf3,0x10,0x0a,0x1}},
- {0x46, 0x6c, {0x0b2,2599,100, 0,0,0x00,0xcc,0x28,0x83,0x10,0x0a,0x1}}
-};
-static const struct opl4_region regions_3c[] = { /* French Horns */
- {0x15, 0x49, {0x07c,3624,100, 0,2,0x00,0xd0,0x1a,0xf0,0x00,0x09,0x0}},
- {0x4a, 0x6c, {0x07d,2664,100, 0,2,0x00,0xd0,0x1a,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_3d[] = { /* Brass Section */
- {0x15, 0x42, {0x0fc,4375,100, 0,0,0x00,0xd6,0x28,0xf0,0x00,0x0a,0x0}},
- {0x43, 0x6c, {0x0fd,2854,100, 0,0,0x00,0xd6,0x28,0xf0,0x00,0x0a,0x0}}
-};
-static const struct opl4_region regions_3e[] = { /* Synth Brass 1 */
- {0x01, 0x27, {0x0d3,9094,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x28, 0x2d, {0x0da,8335,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x2e, 0x33, {0x0d4,7558,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x34, 0x39, {0x0db,6785,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x3a, 0x3f, {0x0d5,6042,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x40, 0x45, {0x0dc,5257,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x46, 0x4b, {0x0d6,4493,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x4c, 0x51, {0x0dd,3741,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x52, 0x57, {0x0d7,3012,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x58, 0x5d, {0x0de,2167,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x5e, 0x63, {0x0d8,1421,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x64, 0x7f, {0x0d9,-115,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
- {0x01, 0x27, {0x118,9103,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x28, 0x2d, {0x119,8340,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x2e, 0x33, {0x11a,7565,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x34, 0x39, {0x11b,6804,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x3a, 0x3f, {0x11c,6042,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x40, 0x45, {0x11d,5277,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x46, 0x4b, {0x11e,4520,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x4c, 0x51, {0x11f,3741,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x52, 0x57, {0x120,3012,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x58, 0x5d, {0x121,2166,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x5e, 0x64, {0x122,1421,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
- {0x65, 0x7f, {0x123,-115,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}}
-};
-static const struct opl4_region regions_3f[] = { /* Synth Brass 2 */
- {0x01, 0x27, {0x118,9113,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x28, 0x2d, {0x119,8350,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x2e, 0x33, {0x11a,7575,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x34, 0x39, {0x11b,6814,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x3a, 0x3f, {0x11c,6052,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x40, 0x45, {0x11d,5287,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x46, 0x4b, {0x11e,4530,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x4c, 0x51, {0x11f,3751,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x52, 0x57, {0x120,3022,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x58, 0x5d, {0x121,2176,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x5e, 0x64, {0x122,1431,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x65, 0x7f, {0x123,-105,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
- {0x00, 0x7f, {0x124,4034,100,-3,2,0x00,0xea,0x22,0x85,0x23,0x08,0x0}}
-};
-static const struct opl4_region regions_40[] = { /* Soprano Sax */
- {0x15, 0x3f, {0x0e3,4228,100, 0,1,0x00,0xc8,0x21,0xf5,0x20,0x0a,0x0}},
- {0x40, 0x45, {0x0e4,3495,100, 0,1,0x00,0xc8,0x21,0xf5,0x20,0x0a,0x0}},
- {0x46, 0x4b, {0x0e5,2660,100, 0,1,0x00,0xd6,0x21,0xf5,0x20,0x0a,0x0}},
- {0x4c, 0x51, {0x0e6,2002,100, 0,1,0x00,0xd6,0x21,0xf5,0x20,0x0a,0x0}},
- {0x52, 0x59, {0x0e7,1186,100, 0,1,0x00,0xd6,0x21,0xf5,0x20,0x0a,0x0}},
- {0x59, 0x6c, {0x0e8,1730,100, 0,1,0x00,0xc8,0x21,0xf5,0x20,0x0a,0x0}}
-};
-static const struct opl4_region regions_41[] = { /* Alto Sax */
- {0x15, 0x32, {0x092,6204,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x33, 0x35, {0x096,5812,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x36, 0x3a, {0x099,5318,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x3b, 0x3b, {0x08f,5076,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x3c, 0x3e, {0x093,4706,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x3f, 0x41, {0x097,4321,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x42, 0x44, {0x09a,3893,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x45, 0x47, {0x090,3497,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x48, 0x4a, {0x094,3119,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x4b, 0x4d, {0x098,2726,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x4e, 0x50, {0x09b,2393,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x51, 0x53, {0x091,2088,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
- {0x54, 0x6c, {0x095,1732,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}}
-};
-static const struct opl4_region regions_42[] = { /* Tenor Sax */
- {0x24, 0x30, {0x0e9,6301,100, 0,1,0x00,0xbc,0x19,0xf4,0x10,0x0b,0x0}},
- {0x31, 0x34, {0x0ea,5781,100, 0,1,0x00,0xbc,0x19,0xf4,0x10,0x0b,0x0}},
- {0x35, 0x3a, {0x0eb,5053,100, 0,1,0x00,0xbc,0x19,0xf4,0x10,0x0b,0x0}},
- {0x3b, 0x41, {0x0ed,4165,100, 0,1,0x00,0xbc,0x19,0xf4,0x10,0x0b,0x0}},
- {0x42, 0x47, {0x0ec,3218,100, 0,1,0x00,0xbc,0x19,0xf4,0x10,0x0b,0x0}},
- {0x48, 0x51, {0x0ee,2462,100, 0,1,0x00,0xbc,0x19,0xf4,0x10,0x0b,0x0}},
- {0x52, 0x6c, {0x0ef,1421,100, 0,1,0x00,0xbc,0x19,0xf4,0x10,0x0b,0x0}}
-};
-static const struct opl4_region regions_43[] = { /* Baritone Sax */
- {0x15, 0x2d, {0x0df,6714,100, 0,1,0x00,0xce,0x19,0xf0,0x00,0x0a,0x0}},
- {0x2e, 0x34, {0x0e1,5552,100, 0,1,0x00,0xce,0x19,0xf0,0x00,0x0a,0x0}},
- {0x35, 0x39, {0x0e2,5178,100, 0,1,0x00,0xce,0x19,0xf0,0x00,0x0a,0x0}},
- {0x3a, 0x6c, {0x0e0,4437,100, 0,1,0x00,0xce,0x19,0xf0,0x00,0x0a,0x0}}
-};
-static const struct opl4_region regions_44[] = { /* Oboe */
- {0x15, 0x3c, {0x042,4493,100, 0,1,0x00,0xe6,0x39,0xf4,0x10,0x0a,0x0}},
- {0x3d, 0x43, {0x044,3702,100, 0,1,0x00,0xdc,0x39,0xf4,0x10,0x0a,0x0}},
- {0x44, 0x49, {0x043,2956,100, 0,1,0x00,0xdc,0x39,0xf4,0x10,0x0a,0x0}},
- {0x4a, 0x4f, {0x046,2166,100, 0,1,0x00,0xdc,0x39,0xf4,0x10,0x0a,0x0}},
- {0x50, 0x55, {0x045,1420,100, 0,1,0x00,0xdc,0x39,0xf4,0x10,0x0a,0x0}},
- {0x56, 0x6c, {0x047, 630,100, 0,1,0x00,0xe6,0x39,0xf4,0x10,0x0a,0x0}}
-};
-static const struct opl4_region regions_45[] = { /* English Horn */
- {0x15, 0x38, {0x03c,5098,100, 0,1,0x00,0xc4,0x31,0xf0,0x00,0x09,0x0}},
- {0x39, 0x3e, {0x03b,4291,100, 0,1,0x00,0xc4,0x31,0xf0,0x00,0x09,0x0}},
- {0x3f, 0x6c, {0x03d,3540,100, 0,1,0x00,0xc4,0x31,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_46[] = { /* Bassoon */
- {0x15, 0x22, {0x038,7833,100, 0,1,0x00,0xc6,0x31,0xf0,0x00,0x0b,0x0}},
- {0x23, 0x2e, {0x03a,7070,100, 0,1,0x00,0xc6,0x31,0xf0,0x00,0x0b,0x0}},
- {0x2f, 0x6c, {0x039,6302,100, 0,1,0x00,0xc6,0x31,0xf0,0x00,0x0b,0x0}}
-};
-static const struct opl4_region regions_47[] = { /* Clarinet */
- {0x15, 0x3b, {0x09e,5900,100, 0,1,0x00,0xc8,0x29,0xf3,0x20,0x0a,0x0}},
- {0x3c, 0x41, {0x0a0,5158,100, 0,1,0x00,0xc8,0x29,0xf3,0x20,0x0a,0x0}},
- {0x42, 0x4a, {0x09f,4260,100, 0,1,0x00,0xc8,0x29,0xf3,0x20,0x0a,0x0}},
- {0x4b, 0x6c, {0x0a1,2957,100, 0,1,0x00,0xc8,0x29,0xf3,0x20,0x0a,0x0}}
-};
-static const struct opl4_region regions_48[] = { /* Piccolo */
- {0x15, 0x40, {0x071,4803,100, 0,0,0x00,0xe6,0x38,0xf0,0x00,0x0a,0x2}},
- {0x41, 0x4d, {0x072,3314,100, 0,0,0x00,0xe6,0x38,0xf0,0x00,0x0a,0x2}},
- {0x4e, 0x53, {0x073,1731,100, 0,0,0x00,0xe6,0x38,0xf0,0x00,0x0a,0x2}},
- {0x54, 0x5f, {0x074,2085,100, 0,0,0x00,0xe6,0x38,0xf0,0x00,0x0a,0x2}},
- {0x60, 0x6c, {0x075,1421,100, 0,0,0x00,0xe6,0x38,0xf0,0x00,0x0a,0x2}}
-};
-static const struct opl4_region regions_49[] = { /* Flute */
- {0x15, 0x40, {0x071,4803,100, 0,0,0x00,0xdc,0x38,0xf0,0x00,0x0a,0x2}},
- {0x41, 0x4d, {0x072,3314,100, 0,0,0x00,0xdc,0x38,0xf0,0x00,0x0a,0x2}},
- {0x4e, 0x6c, {0x073,1731,100, 0,0,0x00,0xe6,0x38,0xf0,0x00,0x0a,0x2}}
-};
-static const struct opl4_region regions_4a[] = { /* Recorder */
- {0x15, 0x6f, {0x0bd,4897,100, 0,0,0x00,0xec,0x30,0x70,0x00,0x09,0x1}}
-};
-static const struct opl4_region regions_4b[] = { /* Pan Flute */
- {0x15, 0x6c, {0x077,2359,100, 0,0,0x00,0xde,0x38,0xf0,0x00,0x09,0x3}}
-};
-static const struct opl4_region regions_4c[] = { /* Bottle Blow */
- {0x15, 0x6c, {0x077,2359,100, 0,0,0x00,0xc8,0x38,0xf0,0x00,0x09,0x1}},
- {0x01, 0x7f, {0x125,7372,100, 0,0,0x1e,0x80,0x00,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_4d[] = { /* Shakuhachi */
- {0x00, 0x7f, {0x0ab,4548,100, 0,0,0x00,0xd6,0x30,0xf0,0x00,0x0a,0x3}},
- {0x15, 0x6c, {0x076,3716,100, 0,0,0x00,0xa2,0x28,0x70,0x00,0x09,0x2}}
-};
-static const struct opl4_region regions_4e[] = { /* Whistle */
- {0x00, 0x7f, {0x0aa,1731,100, 0,4,0x00,0xd2,0x2c,0x70,0x00,0x0a,0x0}}
-};
-static const struct opl4_region regions_4f[] = { /* Ocarina */
- {0x00, 0x7f, {0x0aa,1731,100, 0,1,0x00,0xce,0x29,0x90,0x00,0x0a,0x1}}
-};
-static const struct opl4_region regions_50[] = { /* Square Lead */
- {0x01, 0x2a, {0x0cc,9853,100, 3,0,0x00,0xac,0x38,0xc6,0x21,0x09,0x0}},
- {0x2b, 0x36, {0x0cd,6785,100, 3,0,0x00,0xac,0x38,0xc6,0x21,0x09,0x0}},
- {0x37, 0x42, {0x0ca,5248,100, 3,0,0x00,0xac,0x38,0xc6,0x21,0x09,0x0}},
- {0x43, 0x4e, {0x0cf,3713,100, 3,0,0x00,0xac,0x38,0xc6,0x21,0x09,0x0}},
- {0x4f, 0x5a, {0x0ce,2176,100, 3,0,0x00,0xac,0x38,0xc6,0x21,0x09,0x0}},
- {0x5b, 0x7f, {0x0cb, 640,100, 3,0,0x00,0xac,0x38,0xc6,0x21,0x09,0x0}},
- {0x01, 0x2a, {0x0cc,9844,100,-3,0,0x00,0xac,0x08,0xc6,0x21,0x09,0x0}},
- {0x2b, 0x36, {0x0cd,6776,100,-3,0,0x00,0xac,0x08,0xc6,0x21,0x09,0x0}},
- {0x37, 0x42, {0x0ca,5239,100,-3,0,0x00,0xac,0x08,0xc6,0x21,0x09,0x0}},
- {0x43, 0x4e, {0x0cf,3704,100,-3,0,0x00,0xac,0x08,0xc6,0x21,0x09,0x0}},
- {0x4f, 0x5a, {0x0ce,2167,100,-3,0,0x00,0xac,0x08,0xc6,0x21,0x09,0x0}},
- {0x5b, 0x7f, {0x0cb, 631,100,-3,0,0x00,0xac,0x08,0xc6,0x21,0x09,0x0}}
-};
-static const struct opl4_region regions_51[] = { /* Sawtooth Lead */
- {0x01, 0x27, {0x118,9108,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x28, 0x2d, {0x119,8345,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x2e, 0x33, {0x11a,7570,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x34, 0x39, {0x11b,6809,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x3a, 0x3f, {0x11c,6047,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x40, 0x45, {0x11d,5282,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x46, 0x4b, {0x11e,4525,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x4c, 0x51, {0x11f,3746,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x52, 0x57, {0x120,3017,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x58, 0x5d, {0x121,2171,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x5e, 0x66, {0x122,1426,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x67, 0x7f, {0x123,-110,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x01, 0x27, {0x118,9098,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x28, 0x2d, {0x119,8335,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x2e, 0x33, {0x11a,7560,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x34, 0x39, {0x11b,6799,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x3a, 0x3f, {0x11c,6037,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x40, 0x45, {0x11d,5272,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x46, 0x4b, {0x11e,4515,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x4c, 0x51, {0x11f,3736,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x52, 0x57, {0x120,3007,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x58, 0x5d, {0x121,2161,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x5e, 0x66, {0x122,1416,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
- {0x67, 0x7f, {0x123,-120,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}}
-};
-static const struct opl4_region regions_52[] = { /* Calliope Lead */
- {0x00, 0x7f, {0x0aa,1731,100, 0,0,0x00,0xc2,0x28,0x90,0x00,0x0a,0x2}},
- {0x15, 0x6c, {0x076,3716,100, 0,0,0x00,0xb6,0x28,0xb0,0x00,0x09,0x2}}
-};
-static const struct opl4_region regions_53[] = { /* Chiffer Lead */
- {0x00, 0x7f, {0x13a,3665,100, 0,2,0x00,0xcc,0x2a,0xf0,0x10,0x09,0x1}},
- {0x01, 0x7f, {0x0fe,3660,100, 0,0,0x00,0xbe,0x28,0xf3,0x10,0x17,0x0}}
-};
-static const struct opl4_region regions_54[] = { /* Charang Lead */
- {0x00, 0x40, {0x0a5,6594,100, 0,3,0x00,0xba,0x33,0xf2,0x11,0x09,0x0}},
- {0x41, 0x7f, {0x0a6,5433,100, 0,3,0x00,0xba,0x33,0xf2,0x11,0x09,0x0}},
- {0x01, 0x27, {0x118,9098,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x28, 0x2d, {0x119,8335,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x2e, 0x33, {0x11a,7560,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x34, 0x39, {0x11b,6799,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x3a, 0x3f, {0x11c,6037,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x40, 0x45, {0x11d,5272,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x46, 0x4b, {0x11e,4515,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x4c, 0x51, {0x11f,3736,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x52, 0x57, {0x120,3007,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x58, 0x5d, {0x121,2161,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x5e, 0x66, {0x122,1416,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
- {0x67, 0x7f, {0x123,-120,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}}
-};
-static const struct opl4_region regions_55[] = { /* Voice Lead */
- {0x00, 0x7f, {0x0aa,1739,100, 0,6,0x00,0x8c,0x2e,0x90,0x00,0x0a,0x0}},
- {0x15, 0x6c, {0x02a,3474,100, 0,1,0x00,0xd8,0x29,0xf0,0x05,0x0a,0x0}}
-};
-static const struct opl4_region regions_56[] = { /* 5ths Lead */
- {0x01, 0x27, {0x118,8468,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x28, 0x2d, {0x119,7705,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x2e, 0x33, {0x11a,6930,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x34, 0x39, {0x11b,6169,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x3a, 0x3f, {0x11c,5407,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x40, 0x45, {0x11d,4642,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x46, 0x4b, {0x11e,3885,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x4c, 0x51, {0x11f,3106,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x52, 0x57, {0x120,2377,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x58, 0x5d, {0x121,1531,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x5e, 0x64, {0x122, 786,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x65, 0x7f, {0x123,-750,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
- {0x05, 0x71, {0x002,4503,100, 0,1,0x00,0xb8,0x31,0xb3,0x20,0x0b,0x0}}
-};
-static const struct opl4_region regions_57[] = { /* Bass & Lead */
- {0x00, 0x7f, {0x117,8109,100, 0,1,0x00,0xbc,0x29,0xf3,0x50,0x08,0x0}},
- {0x01, 0x27, {0x118,9097,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x28, 0x2d, {0x119,8334,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x2e, 0x33, {0x11a,7559,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x34, 0x39, {0x11b,6798,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x3a, 0x3f, {0x11c,6036,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x40, 0x45, {0x11d,5271,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x46, 0x4b, {0x11e,4514,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x4c, 0x51, {0x11f,3735,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x52, 0x57, {0x120,3006,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x58, 0x5d, {0x121,2160,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x5e, 0x66, {0x122,1415,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
- {0x67, 0x7f, {0x123,-121,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}}
-};
-static const struct opl4_region regions_58[] = { /* New Age Pad */
- {0x15, 0x6c, {0x002,4501,100, 0,4,0x00,0xa4,0x24,0x80,0x01,0x05,0x0}},
- {0x15, 0x6c, {0x0f3,4253,100, 0,3,0x00,0x8c,0x23,0xa2,0x14,0x06,0x1}}
-};
-static const struct opl4_region regions_59[] = { /* Warm Pad */
- {0x15, 0x6c, {0x04e,5306,100, 2,2,0x00,0x92,0x2a,0x34,0x23,0x05,0x2}},
- {0x15, 0x6c, {0x029,3575,100,-2,2,0x00,0xbe,0x22,0x31,0x23,0x06,0x0}}
-};
-static const struct opl4_region regions_5a[] = { /* Polysynth Pad */
- {0x01, 0x27, {0x118,9111,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x28, 0x2d, {0x119,8348,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x2e, 0x33, {0x11a,7573,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x34, 0x39, {0x11b,6812,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x3a, 0x3f, {0x11c,6050,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x40, 0x45, {0x11d,5285,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x46, 0x4b, {0x11e,4528,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x4c, 0x51, {0x11f,3749,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x52, 0x57, {0x120,3020,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x58, 0x5d, {0x121,2174,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x5e, 0x66, {0x122,1429,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x67, 0x7f, {0x123,-107,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
- {0x00, 0x7f, {0x124,4024,100, 0,2,0x00,0xae,0x22,0xe5,0x20,0x08,0x0}}
-};
-static const struct opl4_region regions_5b[] = { /* Choir Pad */
- {0x15, 0x3a, {0x018,5010,100, 0,5,0x00,0xb0,0x25,0x70,0x00,0x06,0x0}},
- {0x3b, 0x40, {0x019,4370,100, 0,5,0x00,0xb0,0x25,0x70,0x00,0x06,0x0}},
- {0x41, 0x47, {0x01a,3478,100, 0,5,0x00,0xb0,0x25,0x70,0x00,0x06,0x0}},
- {0x48, 0x6c, {0x01b,2197,100, 0,5,0x00,0xb0,0x25,0x70,0x00,0x06,0x0}},
- {0x15, 0x6c, {0x02a,3482,100, 0,4,0x00,0x98,0x24,0x65,0x21,0x06,0x0}}
-};
-static const struct opl4_region regions_5c[] = { /* Bowed Pad */
- {0x15, 0x6c, {0x101,4790,100,-1,1,0x00,0xbe,0x19,0x44,0x14,0x16,0x0}},
- {0x00, 0x7f, {0x0aa,1720,100, 1,1,0x00,0x94,0x19,0x40,0x00,0x06,0x0}}
-};
-static const struct opl4_region regions_5d[] = { /* Metallic Pad */
- {0x15, 0x31, {0x00c,6943,100, 0,2,0x00,0xa0,0x0a,0x60,0x03,0x06,0x0}},
- {0x32, 0x38, {0x00d,5416,100, 0,2,0x00,0xa0,0x0a,0x60,0x03,0x06,0x0}},
- {0x39, 0x47, {0x00e,4385,100, 0,2,0x00,0xa0,0x0a,0x60,0x03,0x06,0x0}},
- {0x48, 0x6c, {0x00f,2849,100, 0,2,0x00,0xa0,0x0a,0x60,0x03,0x06,0x0}},
- {0x00, 0x7f, {0x03f,4224,100, 0,1,0x00,0x9c,0x31,0x65,0x16,0x07,0x0}}
-};
-static const struct opl4_region regions_5e[] = { /* Halo Pad */
- {0x00, 0x7f, {0x124,4038,100, 0,2,0x00,0xa6,0x1a,0x85,0x23,0x08,0x0}},
- {0x15, 0x6c, {0x02a,3471,100, 0,3,0x00,0xc0,0x1b,0xc0,0x05,0x06,0x0}}
-};
-static const struct opl4_region regions_5f[] = { /* Sweep Pad */
- {0x01, 0x27, {0x0d3,9100,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x28, 0x2d, {0x0da,8341,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x2e, 0x33, {0x0d4,7564,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x34, 0x39, {0x0db,6791,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x3a, 0x3f, {0x0d5,6048,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x40, 0x45, {0x0dc,5263,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x46, 0x4b, {0x0d6,4499,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x4c, 0x51, {0x0dd,3747,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x52, 0x57, {0x0d7,3018,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x58, 0x5d, {0x0de,2173,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x5e, 0x63, {0x0d8,1427,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x64, 0x7f, {0x0d9,-109,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
- {0x01, 0x27, {0x0d3,9088,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x28, 0x2d, {0x0da,8329,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x2e, 0x33, {0x0d4,7552,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x34, 0x39, {0x0db,6779,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x3a, 0x3f, {0x0d5,6036,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x40, 0x45, {0x0dc,5251,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x46, 0x4b, {0x0d6,4487,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x4c, 0x51, {0x0dd,3735,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x52, 0x57, {0x0d7,3006,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x58, 0x5d, {0x0de,2161,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x5e, 0x63, {0x0d8,1415,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
- {0x64, 0x7f, {0x0d9,-121,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}}
-};
-static const struct opl4_region regions_60[] = { /* Ice Rain */
- {0x01, 0x7f, {0x04e,9345,100, 0,2,0x00,0xcc,0x22,0xa3,0x63,0x17,0x0}},
- {0x00, 0x7f, {0x143,5586, 20, 0,2,0x00,0x6e,0x2a,0xf0,0x05,0x05,0x0}}
-};
-static const struct opl4_region regions_61[] = { /* Soundtrack */
- {0x15, 0x6c, {0x002,4501,100, 0,2,0x00,0xb6,0x2a,0x60,0x01,0x05,0x0}},
- {0x15, 0x6c, {0x0f3,1160,100, 0,5,0x00,0xa8,0x2d,0x52,0x14,0x06,0x2}}
-};
-static const struct opl4_region regions_62[] = { /* Crystal */
- {0x15, 0x6c, {0x0f3,1826,100, 0,3,0x00,0xb8,0x33,0xf6,0x25,0x25,0x0}},
- {0x15, 0x2c, {0x06d,7454,100, 0,3,0x00,0xac,0x3b,0x85,0x24,0x06,0x0}},
- {0x2d, 0x36, {0x06e,5925,100, 0,3,0x00,0xac,0x3b,0x85,0x24,0x06,0x0}},
- {0x37, 0x6c, {0x06f,4403,100, 0,3,0x09,0xac,0x3b,0x85,0x24,0x06,0x0}}
-};
-static const struct opl4_region regions_63[] = { /* Atmosphere */
- {0x05, 0x71, {0x002,4509,100, 0,2,0x00,0xc8,0x32,0x73,0x22,0x06,0x1}},
- {0x15, 0x2f, {0x0b3,6964,100, 0,2,0x05,0xc2,0x32,0xf5,0x34,0x07,0x2}},
- {0x30, 0x36, {0x0b7,5567,100, 0,2,0x0c,0xc2,0x32,0xf5,0x34,0x07,0x2}},
- {0x37, 0x3c, {0x0b5,4653,100, 0,2,0x00,0xc2,0x32,0xf6,0x34,0x07,0x2}},
- {0x3d, 0x43, {0x0b4,3892,100, 0,2,0x00,0xc2,0x32,0xf6,0x35,0x07,0x2}},
- {0x44, 0x60, {0x0b6,2723,100, 0,2,0x00,0xc2,0x32,0xf6,0x35,0x17,0x2}}
-};
-static const struct opl4_region regions_64[] = { /* Brightness */
- {0x00, 0x7f, {0x137,5285,100, 0,2,0x00,0xbe,0x2a,0xa5,0x18,0x08,0x0}},
- {0x15, 0x6c, {0x02a,3481,100, 0,1,0x00,0xc8,0x29,0x80,0x05,0x05,0x0}}
-};
-static const struct opl4_region regions_65[] = { /* Goblins */
- {0x15, 0x6c, {0x002,4501,100,-1,2,0x00,0xca,0x2a,0x40,0x01,0x05,0x0}},
- {0x15, 0x6c, {0x009,9679, 20, 1,4,0x00,0x3c,0x0c,0x22,0x11,0x06,0x0}}
-};
-static const struct opl4_region regions_66[] = { /* Echoes */
- {0x15, 0x6c, {0x02a,3487,100, 0,3,0x00,0xae,0x2b,0xf5,0x21,0x06,0x0}},
- {0x00, 0x7f, {0x124,4027,100, 0,3,0x00,0xae,0x2b,0x85,0x23,0x07,0x0}}
-};
-static const struct opl4_region regions_67[] = { /* Sci-Fi */
- {0x15, 0x31, {0x00c,6940,100, 0,3,0x00,0xc8,0x2b,0x90,0x05,0x06,0x3}},
- {0x32, 0x38, {0x00d,5413,100, 0,3,0x00,0xc8,0x2b,0x90,0x05,0x06,0x3}},
- {0x39, 0x47, {0x00e,4382,100, 0,3,0x00,0xc8,0x2b,0x90,0x05,0x06,0x3}},
- {0x48, 0x6c, {0x00f,2846,100, 0,3,0x00,0xc8,0x2b,0x90,0x05,0x06,0x3}},
- {0x15, 0x6c, {0x002,4498,100, 0,2,0x00,0xd4,0x22,0x80,0x01,0x05,0x0}}
-};
-static const struct opl4_region regions_68[] = { /* Sitar */
- {0x00, 0x7f, {0x10f,4408,100, 0,2,0x00,0xc4,0x32,0xf4,0x15,0x16,0x1}}
-};
-static const struct opl4_region regions_69[] = { /* Banjo */
- {0x15, 0x34, {0x013,5685,100, 0,0,0x00,0xdc,0x38,0xf6,0x15,0x09,0x0}},
- {0x35, 0x38, {0x014,5009,100, 0,0,0x00,0xdc,0x38,0xf6,0x15,0x09,0x0}},
- {0x39, 0x3c, {0x012,4520,100, 0,0,0x00,0xdc,0x38,0xf6,0x15,0x09,0x0}},
- {0x3d, 0x44, {0x015,3622,100, 0,0,0x00,0xdc,0x38,0xf6,0x15,0x09,0x0}},
- {0x45, 0x4c, {0x017,2661,100, 0,0,0x00,0xdc,0x38,0xf6,0x15,0x09,0x0}},
- {0x4d, 0x6d, {0x016,1632,100, 0,0,0x00,0xdc,0x38,0xf6,0x15,0x09,0x0}}
-};
-static const struct opl4_region regions_6a[] = { /* Shamisen */
- {0x15, 0x6c, {0x10e,3273,100, 0,0,0x00,0xc0,0x28,0xf7,0x76,0x08,0x0}}
-};
-static const struct opl4_region regions_6b[] = { /* Koto */
- {0x00, 0x7f, {0x0a9,4033,100, 0,0,0x00,0xc6,0x20,0xf0,0x06,0x07,0x0}}
-};
-static const struct opl4_region regions_6c[] = { /* Kalimba */
- {0x00, 0x7f, {0x137,3749,100, 0,0,0x00,0xce,0x38,0xf5,0x18,0x08,0x0}}
-};
-static const struct opl4_region regions_6d[] = { /* Bagpipe */
- {0x15, 0x39, {0x0a4,7683,100, 0,4,0x00,0xc0,0x1c,0xf0,0x00,0x09,0x0}},
- {0x15, 0x39, {0x0a7,7680,100, 0,1,0x00,0xaa,0x19,0xf0,0x00,0x09,0x0}},
- {0x3a, 0x6c, {0x0a8,3697,100, 0,1,0x00,0xaa,0x19,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_6e[] = { /* Fiddle */
- {0x15, 0x3a, {0x105,5158,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
- {0x3b, 0x3f, {0x102,4754,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
- {0x40, 0x41, {0x106,4132,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
- {0x42, 0x44, {0x107,4033,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
- {0x45, 0x47, {0x108,3580,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
- {0x48, 0x4a, {0x10a,2957,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
- {0x4b, 0x4c, {0x10b,2724,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
- {0x4d, 0x4e, {0x10c,2530,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
- {0x4f, 0x51, {0x10d,2166,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
- {0x52, 0x6c, {0x109,1825,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}}
-};
-static const struct opl4_region regions_6f[] = { /* Shanai */
- {0x15, 0x6c, {0x041,6946,100, 0,1,0x00,0xc4,0x31,0x95,0x20,0x09,0x0}}
-};
-static const struct opl4_region regions_70[] = { /* Tinkle Bell */
- {0x15, 0x73, {0x0f3,1821,100, 0,3,0x00,0xc8,0x3b,0xd6,0x25,0x25,0x0}},
- {0x00, 0x7f, {0x137,5669,100, 0,3,0x00,0x66,0x3b,0xf5,0x18,0x08,0x0}}
-};
-static const struct opl4_region regions_71[] = { /* Agogo */
- {0x15, 0x74, {0x00b,2474,100, 0,0,0x00,0xd2,0x38,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_72[] = { /* Steel Drums */
- {0x01, 0x7f, {0x0fe,3670,100, 0,0,0x00,0xca,0x38,0xf3,0x06,0x17,0x1}},
- {0x15, 0x6c, {0x100,9602,100, 0,0,0x00,0x54,0x38,0xb0,0x05,0x16,0x1}}
-};
-static const struct opl4_region regions_73[] = { /* Woodblock */
- {0x15, 0x6c, {0x02c,2963, 50, 0,0,0x07,0xd4,0x00,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_74[] = { /* Taiko Drum */
- {0x13, 0x6c, {0x03e,1194, 50, 0,0,0x00,0xaa,0x38,0xf0,0x04,0x04,0x0}}
-};
-static const struct opl4_region regions_75[] = { /* Melodic Tom */
- {0x15, 0x6c, {0x0c7,6418, 50, 0,0,0x00,0xe4,0x38,0xf0,0x05,0x01,0x0}}
-};
-static const struct opl4_region regions_76[] = { /* Synth Drum */
- {0x15, 0x6c, {0x026,3898, 50, 0,0,0x00,0xd0,0x38,0xf0,0x04,0x04,0x0}}
-};
-static const struct opl4_region regions_77[] = { /* Reverse Cymbal */
- {0x15, 0x6c, {0x031,4138, 50, 0,0,0x00,0xfe,0x38,0x3a,0xf0,0x09,0x0}}
-};
-static const struct opl4_region regions_78[] = { /* Guitar Fret Noise */
- {0x15, 0x6c, {0x138,5266,100, 0,0,0x00,0xa0,0x38,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_79[] = { /* Breath Noise */
- {0x01, 0x7f, {0x125,4269,100, 0,0,0x1e,0xd0,0x38,0xf0,0x00,0x09,0x0}}
-};
-static const struct opl4_region regions_7a[] = { /* Seashore */
- {0x15, 0x6c, {0x008,2965, 20,-2,0,0x00,0xfe,0x00,0x20,0x03,0x04,0x0}},
- {0x01, 0x7f, {0x037,4394, 20, 2,0,0x14,0xfe,0x00,0x20,0x04,0x05,0x0}}
-};
-static const struct opl4_region regions_7b[] = { /* Bird Tweet */
- {0x15, 0x6c, {0x009,8078, 5,-4,7,0x00,0xc2,0x0f,0x22,0x12,0x07,0x0}},
- {0x15, 0x6c, {0x009,3583, 5, 4,5,0x00,0xae,0x15,0x72,0x12,0x07,0x0}}
-};
-static const struct opl4_region regions_7c[] = { /* Telephone Ring */
- {0x15, 0x6c, {0x003,3602, 10, 0,0,0x00,0xce,0x00,0xf0,0x00,0x0f,0x0}}
-};
-static const struct opl4_region regions_7d[] = { /* Helicopter */
- {0x0c, 0x7f, {0x001,2965, 10,-2,0,0x00,0xe0,0x08,0x30,0x01,0x07,0x0}},
- {0x01, 0x7f, {0x037,4394, 10, 2,0,0x44,0x76,0x00,0x30,0x01,0x07,0x0}}
-};
-static const struct opl4_region regions_7e[] = { /* Applause */
- {0x15, 0x6c, {0x036,8273, 20,-6,7,0x00,0xc4,0x0f,0x70,0x01,0x05,0x0}},
- {0x15, 0x6c, {0x036,8115, 5, 6,7,0x00,0xc6,0x07,0x70,0x01,0x05,0x0}}
-};
-static const struct opl4_region regions_7f[] = { /* Gun Shot */
- {0x15, 0x6c, {0x139,2858, 20, 0,0,0x00,0xbe,0x38,0xf0,0x03,0x00,0x0}}
-};
-static const struct opl4_region regions_drums[] = {
- {0x18, 0x18, {0x0cb,6397,100, 3,0,0x00,0xf4,0x38,0xc9,0x1c,0x0c,0x0}},
- {0x19, 0x19, {0x0c4,3714,100, 0,0,0x00,0xe0,0x00,0x97,0x19,0x09,0x0}},
- {0x1a, 0x1a, {0x0c4,3519,100, 0,0,0x00,0xea,0x00,0x61,0x01,0x07,0x0}},
- {0x1b, 0x1b, {0x0c4,3586,100, 0,0,0x00,0xea,0x00,0xf7,0x19,0x09,0x0}},
- {0x1c, 0x1c, {0x0c4,3586,100, 0,0,0x00,0xea,0x00,0x81,0x01,0x07,0x0}},
- {0x1e, 0x1e, {0x0c3,4783,100, 0,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x1f, 0x1f, {0x0d1,4042,100, 0,0,0x00,0xd6,0x00,0xf0,0x05,0x05,0x0}},
- {0x20, 0x20, {0x0d2,5943,100, 0,0,0x00,0xcc,0x00,0xf0,0x00,0x09,0x0}},
- {0x21, 0x21, {0x011,3842,100, 0,0,0x00,0xea,0x00,0xf0,0x16,0x06,0x0}},
- {0x23, 0x23, {0x011,4098,100, 0,0,0x00,0xea,0x00,0xf0,0x16,0x06,0x0}},
- {0x24, 0x24, {0x011,4370,100, 0,0,0x00,0xea,0x00,0xf0,0x00,0x06,0x0}},
- {0x25, 0x25, {0x0d2,4404,100, 0,0,0x00,0xd6,0x00,0xf0,0x00,0x06,0x0}},
- {0x26, 0x26, {0x0d1,4298,100, 0,0,0x00,0xd6,0x00,0xf0,0x05,0x05,0x0}},
- {0x27, 0x27, {0x00a,4403,100,-1,0,0x00,0xd6,0x00,0xf0,0x00,0x09,0x0}},
- {0x28, 0x28, {0x0d1,4554,100, 0,0,0x00,0xdc,0x00,0xf0,0x07,0x07,0x0}},
- {0x29, 0x29, {0x0c8,4242,100,-4,0,0x00,0xd6,0x00,0xf6,0x16,0x06,0x0}},
- {0x2a, 0x2a, {0x079,6160,100, 2,0,0x00,0xe0,0x00,0xf5,0x19,0x09,0x0}},
- {0x2b, 0x2b, {0x0c8,4626,100,-3,0,0x00,0xd6,0x00,0xf6,0x16,0x06,0x0}},
- {0x2c, 0x2c, {0x07b,6039,100, 2,0,0x00,0xd6,0x00,0xf0,0x00,0x09,0x0}},
- {0x2d, 0x2d, {0x0c8,5394,100,-2,0,0x00,0xd6,0x00,0xf6,0x16,0x06,0x0}},
- {0x2e, 0x2e, {0x07a,5690,100, 2,0,0x00,0xd6,0x00,0xf0,0x00,0x05,0x0}},
- {0x2f, 0x2f, {0x0c7,5185,100, 2,0,0x00,0xe0,0x00,0xf6,0x17,0x07,0x0}},
- {0x30, 0x30, {0x0c7,5650,100, 3,0,0x00,0xe0,0x00,0xf6,0x17,0x07,0x0}},
- {0x31, 0x31, {0x031,4395,100, 2,0,0x00,0xea,0x00,0xf0,0x05,0x05,0x0}},
- {0x32, 0x32, {0x0c7,6162,100, 4,0,0x00,0xe0,0x00,0xf6,0x17,0x07,0x0}},
- {0x33, 0x33, {0x02e,4391,100,-2,0,0x00,0xea,0x00,0xf0,0x05,0x05,0x0}},
- {0x34, 0x34, {0x07a,3009,100,-2,0,0x00,0xea,0x00,0xf2,0x15,0x05,0x0}},
- {0x35, 0x35, {0x021,4522,100,-3,0,0x00,0xd6,0x00,0xf0,0x05,0x05,0x0}},
- {0x36, 0x36, {0x025,5163,100, 1,0,0x00,0xe0,0x00,0xf0,0x00,0x09,0x0}},
- {0x37, 0x37, {0x031,5287,100,-1,0,0x00,0xea,0x00,0xf5,0x16,0x06,0x0}},
- {0x38, 0x38, {0x01d,4395,100, 2,0,0x00,0xe0,0x00,0xf0,0x00,0x09,0x0}},
- {0x39, 0x39, {0x031,4647,100,-2,0,0x00,0xea,0x00,0xf4,0x16,0x06,0x0}},
- {0x3a, 0x3a, {0x09d,4426,100,-4,0,0x00,0xe0,0x00,0xf4,0x17,0x07,0x0}},
- {0x3b, 0x3b, {0x02e,4659,100,-2,0,0x00,0xea,0x00,0xf0,0x06,0x06,0x0}},
- {0x3c, 0x3c, {0x01c,4769,100, 4,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x3d, 0x3d, {0x01c,4611,100, 4,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x3e, 0x3e, {0x01e,4402,100,-3,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x3f, 0x3f, {0x01f,4387,100,-3,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x40, 0x40, {0x01f,3983,100,-2,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x41, 0x41, {0x09c,4526,100, 2,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x42, 0x42, {0x09c,4016,100, 2,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x43, 0x43, {0x00b,4739,100,-4,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x44, 0x44, {0x00b,4179,100,-4,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x45, 0x45, {0x02f,4787,100,-4,0,0x00,0xd6,0x00,0xf0,0x00,0x09,0x0}},
- {0x46, 0x46, {0x030,4665,100,-4,0,0x00,0xd6,0x00,0xf0,0x00,0x09,0x0}},
- {0x47, 0x47, {0x144,4519,100, 4,0,0x00,0xea,0x00,0xf0,0x00,0x0b,0x0}},
- {0x48, 0x48, {0x144,4111,100, 4,0,0x00,0xea,0x00,0xf0,0x00,0x0b,0x0}},
- {0x49, 0x49, {0x024,6408,100, 3,0,0x00,0xe0,0x00,0xf0,0x00,0x09,0x0}},
- {0x4a, 0x4a, {0x024,4144,100, 3,0,0x00,0xcc,0x00,0xf0,0x00,0x09,0x0}},
- {0x4b, 0x4b, {0x020,4001,100, 2,0,0x00,0xe0,0x00,0xf0,0x00,0x09,0x0}},
- {0x4c, 0x4c, {0x02c,4402,100, 4,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x4d, 0x4d, {0x02c,3612,100, 4,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x4e, 0x4e, {0x022,4129,100,-2,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x4f, 0x4f, {0x023,4147,100,-2,0,0x00,0xea,0x00,0xf0,0x00,0x09,0x0}},
- {0x50, 0x50, {0x032,4412,100,-4,0,0x00,0xd6,0x00,0xf0,0x08,0x09,0x0}},
- {0x51, 0x51, {0x032,4385,100,-4,0,0x00,0xd6,0x00,0xf0,0x00,0x09,0x0}},
- {0x52, 0x52, {0x02f,5935,100,-1,0,0x00,0xd6,0x00,0xf0,0x00,0x09,0x0}}
-};
-
-#define REGION(num) { ARRAY_SIZE(regions ## num), regions ## num }
-const struct opl4_region_ptr snd_yrw801_regions[0x81] = {
- REGION(_00), REGION(_01), REGION(_02), REGION(_03),
- REGION(_04), REGION(_05), REGION(_06), REGION(_07),
- REGION(_08), REGION(_09), REGION(_0a), REGION(_0b),
- REGION(_0c), REGION(_0d), REGION(_0e), REGION(_0f),
- REGION(_10), REGION(_11), REGION(_12), REGION(_13),
- REGION(_14), REGION(_15), REGION(_16), REGION(_17),
- REGION(_18), REGION(_19), REGION(_1a), REGION(_1b),
- REGION(_1c), REGION(_1d), REGION(_1e), REGION(_1f),
- REGION(_20), REGION(_21), REGION(_22), REGION(_23),
- REGION(_24), REGION(_25), REGION(_26), REGION(_27),
- REGION(_28), REGION(_29), REGION(_2a), REGION(_2b),
- REGION(_2c), REGION(_2d), REGION(_2e), REGION(_2f),
- REGION(_30), REGION(_31), REGION(_32), REGION(_33),
- REGION(_34), REGION(_35), REGION(_36), REGION(_37),
- REGION(_38), REGION(_39), REGION(_3a), REGION(_3b),
- REGION(_3c), REGION(_3d), REGION(_3e), REGION(_3f),
- REGION(_40), REGION(_41), REGION(_42), REGION(_43),
- REGION(_44), REGION(_45), REGION(_46), REGION(_47),
- REGION(_48), REGION(_49), REGION(_4a), REGION(_4b),
- REGION(_4c), REGION(_4d), REGION(_4e), REGION(_4f),
- REGION(_50), REGION(_51), REGION(_52), REGION(_53),
- REGION(_54), REGION(_55), REGION(_56), REGION(_57),
- REGION(_58), REGION(_59), REGION(_5a), REGION(_5b),
- REGION(_5c), REGION(_5d), REGION(_5e), REGION(_5f),
- REGION(_60), REGION(_61), REGION(_62), REGION(_63),
- REGION(_64), REGION(_65), REGION(_66), REGION(_67),
- REGION(_68), REGION(_69), REGION(_6a), REGION(_6b),
- REGION(_6c), REGION(_6d), REGION(_6e), REGION(_6f),
- REGION(_70), REGION(_71), REGION(_72), REGION(_73),
- REGION(_74), REGION(_75), REGION(_76), REGION(_77),
- REGION(_78), REGION(_79), REGION(_7a), REGION(_7b),
- REGION(_7c), REGION(_7d), REGION(_7e), REGION(_7f),
- REGION(_drums)
-};
diff --git a/ANDROID_3.4.5/sound/drivers/pcm-indirect2.c b/ANDROID_3.4.5/sound/drivers/pcm-indirect2.c
deleted file mode 100644
index e73fafd7..00000000
--- a/ANDROID_3.4.5/sound/drivers/pcm-indirect2.c
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * Helper functions for indirect PCM data transfer to a simple FIFO in
- * hardware (small, no possibility to read "hardware io position",
- * updating position done by interrupt, ...)
- *
- * Copyright (c) by 2007 Joachim Foerster <JOFT@gmx.de>
- *
- * Based on "pcm-indirect.h" (alsa-driver-1.0.13) by
- *
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- * Jaroslav Kysela <perex@suse.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* snd_printk/d() */
-#include <sound/core.h>
-/* struct snd_pcm_substream, struct snd_pcm_runtime, snd_pcm_uframes_t
- * snd_pcm_period_elapsed() */
-#include <sound/pcm.h>
-
-#include "pcm-indirect2.h"
-
-#ifdef SND_PCM_INDIRECT2_STAT
-/* jiffies */
-#include <linux/jiffies.h>
-
-void snd_pcm_indirect2_stat(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int i;
- int j;
- int k;
- int seconds = (rec->lastbytetime - rec->firstbytetime) / HZ;
-
- snd_printk(KERN_DEBUG "STAT: mul_elapsed: %u, mul_elapsed_real: %d, "
- "irq_occured: %d\n",
- rec->mul_elapsed, rec->mul_elapsed_real, rec->irq_occured);
- snd_printk(KERN_DEBUG "STAT: min_multiple: %d (irqs/period)\n",
- rec->min_multiple);
- snd_printk(KERN_DEBUG "STAT: firstbytetime: %lu, lastbytetime: %lu, "
- "firstzerotime: %lu\n",
- rec->firstbytetime, rec->lastbytetime, rec->firstzerotime);
- snd_printk(KERN_DEBUG "STAT: bytes2hw: %u Bytes => (by runtime->rate) "
- "length: %d s\n",
- rec->bytes2hw, rec->bytes2hw / 2 / 2 / runtime->rate);
- snd_printk(KERN_DEBUG "STAT: (by measurement) length: %d => "
- "rate: %d Bytes/s = %d Frames/s|Hz\n",
- seconds, rec->bytes2hw / seconds,
- rec->bytes2hw / 2 / 2 / seconds);
- snd_printk(KERN_DEBUG
- "STAT: zeros2hw: %u = %d ms ~ %d * %d zero copies\n",
- rec->zeros2hw, ((rec->zeros2hw / 2 / 2) * 1000) /
- runtime->rate,
- rec->zeros2hw / (rec->hw_buffer_size / 2),
- (rec->hw_buffer_size / 2));
- snd_printk(KERN_DEBUG "STAT: pointer_calls: %u, lastdifftime: %u\n",
- rec->pointer_calls, rec->lastdifftime);
- snd_printk(KERN_DEBUG "STAT: sw_io: %d, sw_data: %d\n", rec->sw_io,
- rec->sw_data);
- snd_printk(KERN_DEBUG "STAT: byte_sizes[]:\n");
- k = 0;
- for (j = 0; j < 8; j++) {
- for (i = j * 8; i < (j + 1) * 8; i++)
- if (rec->byte_sizes[i] != 0) {
- snd_printk(KERN_DEBUG "%u: %u",
- i, rec->byte_sizes[i]);
- k++;
- }
- if (((k % 8) == 0) && (k != 0)) {
- snd_printk(KERN_DEBUG "\n");
- k = 0;
- }
- }
- snd_printk(KERN_DEBUG "\n");
- snd_printk(KERN_DEBUG "STAT: zero_sizes[]:\n");
- for (j = 0; j < 8; j++) {
- k = 0;
- for (i = j * 8; i < (j + 1) * 8; i++)
- if (rec->zero_sizes[i] != 0)
- snd_printk(KERN_DEBUG "%u: %u",
- i, rec->zero_sizes[i]);
- else
- k++;
- if (!k)
- snd_printk(KERN_DEBUG "\n");
- }
- snd_printk(KERN_DEBUG "\n");
- snd_printk(KERN_DEBUG "STAT: min_adds[]:\n");
- for (j = 0; j < 8; j++) {
- if (rec->min_adds[j] != 0)
- snd_printk(KERN_DEBUG "%u: %u", j, rec->min_adds[j]);
- }
- snd_printk(KERN_DEBUG "\n");
- snd_printk(KERN_DEBUG "STAT: mul_adds[]:\n");
- for (j = 0; j < 8; j++) {
- if (rec->mul_adds[j] != 0)
- snd_printk(KERN_DEBUG "%u: %u", j, rec->mul_adds[j]);
- }
- snd_printk(KERN_DEBUG "\n");
- snd_printk(KERN_DEBUG
- "STAT: zero_times_saved: %d, zero_times_notsaved: %d\n",
- rec->zero_times_saved, rec->zero_times_notsaved);
- /* snd_printk(KERN_DEBUG "STAT: zero_times[]\n");
- i = 0;
- for (j = 0; j < 3750; j++) {
- if (rec->zero_times[j] != 0) {
- snd_printk(KERN_DEBUG "%u: %u", j, rec->zero_times[j]);
- i++;
- }
- if (((i % 8) == 0) && (i != 0))
- snd_printk(KERN_DEBUG "\n");
- }
- snd_printk(KERN_DEBUG "\n"); */
- return;
-}
-#endif
-
-/*
- * _internal_ helper function for playback/capture transfer function
- */
-static void
-snd_pcm_indirect2_increase_min_periods(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec,
- int isplay, int iscopy,
- unsigned int bytes)
-{
- if (rec->min_periods >= 0) {
- if (iscopy) {
- rec->sw_io += bytes;
- if (rec->sw_io >= rec->sw_buffer_size)
- rec->sw_io -= rec->sw_buffer_size;
- } else if (isplay) {
- /* If application does not write data in multiples of
- * a period, move sw_data to the next correctly aligned
- * position, so that sw_io can converge to it (in the
- * next step).
- */
- if (!rec->check_alignment) {
- if (rec->bytes2hw %
- snd_pcm_lib_period_bytes(substream)) {
- unsigned bytes2hw_aligned =
- (1 +
- (rec->bytes2hw /
- snd_pcm_lib_period_bytes
- (substream))) *
- snd_pcm_lib_period_bytes
- (substream);
- rec->sw_data =
- bytes2hw_aligned %
- rec->sw_buffer_size;
-#ifdef SND_PCM_INDIRECT2_STAT
- snd_printk(KERN_DEBUG
- "STAT: @re-align: aligned "
- "bytes2hw to next period "
- "size boundary: %d "
- "(instead of %d)\n",
- bytes2hw_aligned,
- rec->bytes2hw);
- snd_printk(KERN_DEBUG
- "STAT: @re-align: sw_data "
- "moves to: %d\n",
- rec->sw_data);
-#endif
- }
- rec->check_alignment = 1;
- }
- /* We are at the end and are copying zeros into the
- * fifo.
- * Now, we have to make sure that sw_io is increased
- * until the position of sw_data: Filling the fifo with
- * the first zeros means, the last bytes were played.
- */
- if (rec->sw_io != rec->sw_data) {
- unsigned int diff;
- if (rec->sw_data > rec->sw_io)
- diff = rec->sw_data - rec->sw_io;
- else
- diff = (rec->sw_buffer_size -
- rec->sw_io) +
- rec->sw_data;
- if (bytes >= diff)
- rec->sw_io = rec->sw_data;
- else {
- rec->sw_io += bytes;
- if (rec->sw_io >= rec->sw_buffer_size)
- rec->sw_io -=
- rec->sw_buffer_size;
- }
- }
- }
- rec->min_period_count += bytes;
- if (rec->min_period_count >= (rec->hw_buffer_size / 2)) {
- rec->min_periods += (rec->min_period_count /
- (rec->hw_buffer_size / 2));
-#ifdef SND_PCM_INDIRECT2_STAT
- if ((rec->min_period_count /
- (rec->hw_buffer_size / 2)) > 7)
- snd_printk(KERN_DEBUG
- "STAT: more than 7 (%d) min_adds "
- "at once - too big to save!\n",
- (rec->min_period_count /
- (rec->hw_buffer_size / 2)));
- else
- rec->min_adds[(rec->min_period_count /
- (rec->hw_buffer_size / 2))]++;
-#endif
- rec->min_period_count = (rec->min_period_count %
- (rec->hw_buffer_size / 2));
- }
- } else if (isplay && iscopy)
- rec->min_periods = 0;
-}
-
-/*
- * helper function for playback/capture pointer callback
- */
-snd_pcm_uframes_t
-snd_pcm_indirect2_pointer(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec)
-{
-#ifdef SND_PCM_INDIRECT2_STAT
- rec->pointer_calls++;
-#endif
- return bytes_to_frames(substream->runtime, rec->sw_io);
-}
-
-/*
- * _internal_ helper function for playback interrupt callback
- */
-static void
-snd_pcm_indirect2_playback_transfer(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec,
- snd_pcm_indirect2_copy_t copy,
- snd_pcm_indirect2_zero_t zero)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_uframes_t appl_ptr = runtime->control->appl_ptr;
-
- /* runtime->control->appl_ptr: position where ALSA will write next time
- * rec->appl_ptr: position where ALSA was last time
- * diff: obviously ALSA wrote that much bytes into the intermediate
- * buffer since we checked last time
- */
- snd_pcm_sframes_t diff = appl_ptr - rec->appl_ptr;
-
- if (diff) {
-#ifdef SND_PCM_INDIRECT2_STAT
- rec->lastdifftime = jiffies;
-#endif
- if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
- diff += runtime->boundary;
- /* number of bytes "added" by ALSA increases the number of
- * bytes which are ready to "be transferred to HW"/"played"
- * Then, set rec->appl_ptr to not count bytes twice next time.
- */
- rec->sw_ready += (int)frames_to_bytes(runtime, diff);
- rec->appl_ptr = appl_ptr;
- }
- if (rec->hw_ready && (rec->sw_ready <= 0)) {
- unsigned int bytes;
-
-#ifdef SND_PCM_INDIRECT2_STAT
- if (rec->firstzerotime == 0) {
- rec->firstzerotime = jiffies;
- snd_printk(KERN_DEBUG
- "STAT: @firstzerotime: mul_elapsed: %d, "
- "min_period_count: %d\n",
- rec->mul_elapsed, rec->min_period_count);
- snd_printk(KERN_DEBUG
- "STAT: @firstzerotime: sw_io: %d, "
- "sw_data: %d, appl_ptr: %u\n",
- rec->sw_io, rec->sw_data,
- (unsigned int)appl_ptr);
- }
- if ((jiffies - rec->firstzerotime) < 3750) {
- rec->zero_times[(jiffies - rec->firstzerotime)]++;
- rec->zero_times_saved++;
- } else
- rec->zero_times_notsaved++;
-#endif
- bytes = zero(substream, rec);
-
-#ifdef SND_PCM_INDIRECT2_STAT
- rec->zeros2hw += bytes;
- if (bytes < 64)
- rec->zero_sizes[bytes]++;
- else
- snd_printk(KERN_DEBUG
- "STAT: %d zero Bytes copied to hardware at "
- "once - too big to save!\n",
- bytes);
-#endif
- snd_pcm_indirect2_increase_min_periods(substream, rec, 1, 0,
- bytes);
- return;
- }
- while (rec->hw_ready && (rec->sw_ready > 0)) {
- /* sw_to_end: max. number of bytes that can be read/take from
- * the current position (sw_data) in _one_ step
- */
- unsigned int sw_to_end = rec->sw_buffer_size - rec->sw_data;
-
- /* bytes: number of bytes we have available (for reading) */
- unsigned int bytes = rec->sw_ready;
-
- if (sw_to_end < bytes)
- bytes = sw_to_end;
- if (!bytes)
- break;
-
-#ifdef SND_PCM_INDIRECT2_STAT
- if (rec->firstbytetime == 0)
- rec->firstbytetime = jiffies;
- rec->lastbytetime = jiffies;
-#endif
- /* copy bytes from intermediate buffer position sw_data to the
- * HW and return number of bytes actually written
- * Furthermore, set hw_ready to 0, if the fifo isn't empty
- * now => more could be transferred to fifo
- */
- bytes = copy(substream, rec, bytes);
- rec->bytes2hw += bytes;
-
-#ifdef SND_PCM_INDIRECT2_STAT
- if (bytes < 64)
- rec->byte_sizes[bytes]++;
- else
- snd_printk(KERN_DEBUG
- "STAT: %d Bytes copied to hardware at once "
- "- too big to save!\n",
- bytes);
-#endif
- /* increase sw_data by the number of actually written bytes
- * (= number of taken bytes from intermediate buffer)
- */
- rec->sw_data += bytes;
- if (rec->sw_data == rec->sw_buffer_size)
- rec->sw_data = 0;
- /* now sw_data is the position where ALSA is going to write
- * in the intermediate buffer next time = position we are going
- * to read from next time
- */
-
- snd_pcm_indirect2_increase_min_periods(substream, rec, 1, 1,
- bytes);
-
- /* we read bytes from intermediate buffer, so we need to say
- * that the number of bytes ready for transfer are decreased
- * now
- */
- rec->sw_ready -= bytes;
- }
- return;
-}
-
-/*
- * helper function for playback interrupt routine
- */
-void
-snd_pcm_indirect2_playback_interrupt(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec,
- snd_pcm_indirect2_copy_t copy,
- snd_pcm_indirect2_zero_t zero)
-{
-#ifdef SND_PCM_INDIRECT2_STAT
- rec->irq_occured++;
-#endif
- /* hardware played some bytes, so there is room again (in fifo) */
- rec->hw_ready = 1;
-
- /* don't call ack() now, instead call transfer() function directly
- * (normally called by ack() )
- */
- snd_pcm_indirect2_playback_transfer(substream, rec, copy, zero);
-
- if (rec->min_periods >= rec->min_multiple) {
-#ifdef SND_PCM_INDIRECT2_STAT
- if ((rec->min_periods / rec->min_multiple) > 7)
- snd_printk(KERN_DEBUG
- "STAT: more than 7 (%d) mul_adds - too big "
- "to save!\n",
- (rec->min_periods / rec->min_multiple));
- else
- rec->mul_adds[(rec->min_periods /
- rec->min_multiple)]++;
- rec->mul_elapsed_real += (rec->min_periods /
- rec->min_multiple);
- rec->mul_elapsed++;
-#endif
- rec->min_periods = (rec->min_periods % rec->min_multiple);
- snd_pcm_period_elapsed(substream);
- }
-}
-
-/*
- * _internal_ helper function for capture interrupt callback
- */
-static void
-snd_pcm_indirect2_capture_transfer(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec,
- snd_pcm_indirect2_copy_t copy,
- snd_pcm_indirect2_zero_t null)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_uframes_t appl_ptr = runtime->control->appl_ptr;
- snd_pcm_sframes_t diff = appl_ptr - rec->appl_ptr;
-
- if (diff) {
-#ifdef SND_PCM_INDIRECT2_STAT
- rec->lastdifftime = jiffies;
-#endif
- if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
- diff += runtime->boundary;
- rec->sw_ready -= frames_to_bytes(runtime, diff);
- rec->appl_ptr = appl_ptr;
- }
- /* if hardware has something, but the intermediate buffer is full
- * => skip contents of buffer
- */
- if (rec->hw_ready && (rec->sw_ready >= (int)rec->sw_buffer_size)) {
- unsigned int bytes;
-
-#ifdef SND_PCM_INDIRECT2_STAT
- if (rec->firstzerotime == 0) {
- rec->firstzerotime = jiffies;
- snd_printk(KERN_DEBUG "STAT: (capture) "
- "@firstzerotime: mul_elapsed: %d, "
- "min_period_count: %d\n",
- rec->mul_elapsed, rec->min_period_count);
- snd_printk(KERN_DEBUG "STAT: (capture) "
- "@firstzerotime: sw_io: %d, sw_data: %d, "
- "appl_ptr: %u\n",
- rec->sw_io, rec->sw_data,
- (unsigned int)appl_ptr);
- }
- if ((jiffies - rec->firstzerotime) < 3750) {
- rec->zero_times[(jiffies - rec->firstzerotime)]++;
- rec->zero_times_saved++;
- } else
- rec->zero_times_notsaved++;
-#endif
- bytes = null(substream, rec);
-
-#ifdef SND_PCM_INDIRECT2_STAT
- rec->zeros2hw += bytes;
- if (bytes < 64)
- rec->zero_sizes[bytes]++;
- else
- snd_printk(KERN_DEBUG
- "STAT: (capture) %d zero Bytes copied to "
- "hardware at once - too big to save!\n",
- bytes);
-#endif
- snd_pcm_indirect2_increase_min_periods(substream, rec, 0, 0,
- bytes);
- /* report an overrun */
- rec->sw_io = SNDRV_PCM_POS_XRUN;
- return;
- }
- while (rec->hw_ready && (rec->sw_ready < (int)rec->sw_buffer_size)) {
- /* sw_to_end: max. number of bytes that we can write to the
- * intermediate buffer (until it's end)
- */
- size_t sw_to_end = rec->sw_buffer_size - rec->sw_data;
-
- /* bytes: max. number of bytes, which may be copied to the
- * intermediate buffer without overflow (in _one_ step)
- */
- size_t bytes = rec->sw_buffer_size - rec->sw_ready;
-
- /* limit number of bytes (for transfer) by available room in
- * the intermediate buffer
- */
- if (sw_to_end < bytes)
- bytes = sw_to_end;
- if (!bytes)
- break;
-
-#ifdef SND_PCM_INDIRECT2_STAT
- if (rec->firstbytetime == 0)
- rec->firstbytetime = jiffies;
- rec->lastbytetime = jiffies;
-#endif
- /* copy bytes from the intermediate buffer (position sw_data)
- * to the HW at most and return number of bytes actually copied
- * from HW
- * Furthermore, set hw_ready to 0, if the fifo is empty now.
- */
- bytes = copy(substream, rec, bytes);
- rec->bytes2hw += bytes;
-
-#ifdef SND_PCM_INDIRECT2_STAT
- if (bytes < 64)
- rec->byte_sizes[bytes]++;
- else
- snd_printk(KERN_DEBUG
- "STAT: (capture) %d Bytes copied to "
- "hardware at once - too big to save!\n",
- bytes);
-#endif
- /* increase sw_data by the number of actually copied bytes from
- * HW
- */
- rec->sw_data += bytes;
- if (rec->sw_data == rec->sw_buffer_size)
- rec->sw_data = 0;
-
- snd_pcm_indirect2_increase_min_periods(substream, rec, 0, 1,
- bytes);
-
- /* number of bytes in the intermediate buffer, which haven't
- * been fetched by ALSA yet.
- */
- rec->sw_ready += bytes;
- }
- return;
-}
-
-/*
- * helper function for capture interrupt routine
- */
-void
-snd_pcm_indirect2_capture_interrupt(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec,
- snd_pcm_indirect2_copy_t copy,
- snd_pcm_indirect2_zero_t null)
-{
-#ifdef SND_PCM_INDIRECT2_STAT
- rec->irq_occured++;
-#endif
- /* hardware recorded some bytes, so there is something to read from the
- * record fifo:
- */
- rec->hw_ready = 1;
-
- /* don't call ack() now, instead call transfer() function directly
- * (normally called by ack() )
- */
- snd_pcm_indirect2_capture_transfer(substream, rec, copy, null);
-
- if (rec->min_periods >= rec->min_multiple) {
-
-#ifdef SND_PCM_INDIRECT2_STAT
- if ((rec->min_periods / rec->min_multiple) > 7)
- snd_printk(KERN_DEBUG
- "STAT: more than 7 (%d) mul_adds - "
- "too big to save!\n",
- (rec->min_periods / rec->min_multiple));
- else
- rec->mul_adds[(rec->min_periods /
- rec->min_multiple)]++;
- rec->mul_elapsed_real += (rec->min_periods /
- rec->min_multiple);
- rec->mul_elapsed++;
-#endif
- rec->min_periods = (rec->min_periods % rec->min_multiple);
- snd_pcm_period_elapsed(substream);
- }
-}
diff --git a/ANDROID_3.4.5/sound/drivers/pcm-indirect2.h b/ANDROID_3.4.5/sound/drivers/pcm-indirect2.h
deleted file mode 100644
index 2ea6e460..00000000
--- a/ANDROID_3.4.5/sound/drivers/pcm-indirect2.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Helper functions for indirect PCM data transfer to a simple FIFO in
- * hardware (small, no possibility to read "hardware io position",
- * updating position done by interrupt, ...)
- *
- * Copyright (c) by 2007 Joachim Foerster <JOFT@gmx.de>
- *
- * Based on "pcm-indirect.h" (alsa-driver-1.0.13) by
- *
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- * Jaroslav Kysela <perex@suse.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __SOUND_PCM_INDIRECT2_H
-#define __SOUND_PCM_INDIRECT2_H
-
-/* struct snd_pcm_substream, struct snd_pcm_runtime, snd_pcm_uframes_t */
-#include <sound/pcm.h>
-
-/* Debug options for code which may be removed completely in a final version */
-#ifdef CONFIG_SND_DEBUG
-#define SND_PCM_INDIRECT2_STAT /* turn on some "statistics" about the
- * process of copying bytes from the
- * intermediate buffer to the hardware
- * fifo and the other way round
- */
-#endif
-
-struct snd_pcm_indirect2 {
- unsigned int hw_buffer_size; /* Byte size of hardware buffer */
- int hw_ready; /* playback: 1 = hw fifo has room left,
- * 0 = hw fifo is full
- */
- unsigned int min_multiple;
- int min_periods; /* counts number of min. periods until
- * min_multiple is reached
- */
- int min_period_count; /* counts bytes to count number of
- * min. periods
- */
-
- unsigned int sw_buffer_size; /* Byte size of software buffer */
-
- /* sw_data: position in intermediate buffer, where we will read (or
- * write) from/to next time (to transfer data to/from HW)
- */
- unsigned int sw_data; /* Offset to next dst (or src) in sw
- * ring buffer
- */
- /* easiest case (playback):
- * sw_data is nearly the same as ~ runtime->control->appl_ptr, with the
- * exception that sw_data is "behind" by the number if bytes ALSA wrote
- * to the intermediate buffer last time.
- * A call to ack() callback synchronizes both indirectly.
- */
-
- /* We have no real sw_io pointer here. Usually sw_io is pointing to the
- * current playback/capture position _inside_ the hardware. Devices
- * with plain FIFOs often have no possibility to publish this position.
- * So we say: if sw_data is updated, that means bytes were copied to
- * the hardware, we increase sw_io by that amount, because there have
- * to be as much bytes which were played. So sw_io will stay behind
- * sw_data all the time and has to converge to sw_data at the end of
- * playback.
- */
- unsigned int sw_io; /* Current software pointer in bytes */
-
- /* sw_ready: number of bytes ALSA copied to the intermediate buffer, so
- * it represents the number of bytes which wait for transfer to the HW
- */
- int sw_ready; /* Bytes ready to be transferred to/from hw */
-
- /* appl_ptr: last known position of ALSA (where ALSA is going to write
- * next time into the intermediate buffer
- */
- snd_pcm_uframes_t appl_ptr; /* Last seen appl_ptr */
-
- unsigned int bytes2hw;
- int check_alignment;
-
-#ifdef SND_PCM_INDIRECT2_STAT
- unsigned int zeros2hw;
- unsigned int mul_elapsed;
- unsigned int mul_elapsed_real;
- unsigned long firstbytetime;
- unsigned long lastbytetime;
- unsigned long firstzerotime;
- unsigned int byte_sizes[64];
- unsigned int zero_sizes[64];
- unsigned int min_adds[8];
- unsigned int mul_adds[8];
- unsigned int zero_times[3750]; /* = 15s */
- unsigned int zero_times_saved;
- unsigned int zero_times_notsaved;
- unsigned int irq_occured;
- unsigned int pointer_calls;
- unsigned int lastdifftime;
-#endif
-};
-
-typedef size_t (*snd_pcm_indirect2_copy_t) (struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec,
- size_t bytes);
-typedef size_t (*snd_pcm_indirect2_zero_t) (struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec);
-
-#ifdef SND_PCM_INDIRECT2_STAT
-void snd_pcm_indirect2_stat(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec);
-#endif
-
-snd_pcm_uframes_t
-snd_pcm_indirect2_pointer(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec);
-void
-snd_pcm_indirect2_playback_interrupt(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec,
- snd_pcm_indirect2_copy_t copy,
- snd_pcm_indirect2_zero_t zero);
-void
-snd_pcm_indirect2_capture_interrupt(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect2 *rec,
- snd_pcm_indirect2_copy_t copy,
- snd_pcm_indirect2_zero_t null);
-
-#endif /* __SOUND_PCM_INDIRECT2_H */
diff --git a/ANDROID_3.4.5/sound/drivers/pcsp/Makefile b/ANDROID_3.4.5/sound/drivers/pcsp/Makefile
deleted file mode 100644
index b19555b4..00000000
--- a/ANDROID_3.4.5/sound/drivers/pcsp/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-snd-pcsp-objs := pcsp.o pcsp_lib.o pcsp_mixer.o pcsp_input.o
-obj-$(CONFIG_SND_PCSP) += snd-pcsp.o
diff --git a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp.c b/ANDROID_3.4.5/sound/drivers/pcsp/pcsp.c
deleted file mode 100644
index 99704e6a..00000000
--- a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * PC-Speaker driver for Linux
- *
- * Copyright (C) 1997-2001 David Woodhouse
- * Copyright (C) 2001-2008 Stas Sergeev
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <linux/input.h>
-#include <linux/delay.h>
-#include <asm/bitops.h>
-#include "pcsp_input.h"
-#include "pcsp.h"
-
-MODULE_AUTHOR("Stas Sergeev <stsp@users.sourceforge.net>");
-MODULE_DESCRIPTION("PC-Speaker driver");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{PC-Speaker, pcsp}}");
-MODULE_ALIAS("platform:pcspkr");
-
-static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
-static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-static bool enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */
-static bool nopcm; /* Disable PCM capability of the driver */
-
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for pcsp soundcard.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for pcsp soundcard.");
-module_param(enable, bool, 0444);
-MODULE_PARM_DESC(enable, "Enable PC-Speaker sound.");
-module_param(nopcm, bool, 0444);
-MODULE_PARM_DESC(nopcm, "Disable PC-Speaker PCM sound. Only beeps remain.");
-
-struct snd_pcsp pcsp_chip;
-
-static int __devinit snd_pcsp_create(struct snd_card *card)
-{
- static struct snd_device_ops ops = { };
- struct timespec tp;
- int err;
- int div, min_div, order;
-
- if (!nopcm) {
- hrtimer_get_res(CLOCK_MONOTONIC, &tp);
- if (tp.tv_sec || tp.tv_nsec > PCSP_MAX_PERIOD_NS) {
- printk(KERN_ERR "PCSP: Timer resolution is not sufficient "
- "(%linS)\n", tp.tv_nsec);
- printk(KERN_ERR "PCSP: Make sure you have HPET and ACPI "
- "enabled.\n");
- printk(KERN_ERR "PCSP: Turned into nopcm mode.\n");
- nopcm = 1;
- }
- }
-
- if (loops_per_jiffy >= PCSP_MIN_LPJ && tp.tv_nsec <= PCSP_MIN_PERIOD_NS)
- min_div = MIN_DIV;
- else
- min_div = MAX_DIV;
-#if PCSP_DEBUG
- printk(KERN_DEBUG "PCSP: lpj=%li, min_div=%i, res=%li\n",
- loops_per_jiffy, min_div, tp.tv_nsec);
-#endif
-
- div = MAX_DIV / min_div;
- order = fls(div) - 1;
-
- pcsp_chip.max_treble = min(order, PCSP_MAX_TREBLE);
- pcsp_chip.treble = min(pcsp_chip.max_treble, PCSP_DEFAULT_TREBLE);
- pcsp_chip.playback_ptr = 0;
- pcsp_chip.period_ptr = 0;
- atomic_set(&pcsp_chip.timer_active, 0);
- pcsp_chip.enable = 1;
- pcsp_chip.pcspkr = 1;
-
- spin_lock_init(&pcsp_chip.substream_lock);
-
- pcsp_chip.card = card;
- pcsp_chip.port = 0x61;
- pcsp_chip.irq = -1;
- pcsp_chip.dma = -1;
-
- /* Register device */
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, &pcsp_chip, &ops);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static int __devinit snd_card_pcsp_probe(int devnum, struct device *dev)
-{
- struct snd_card *card;
- int err;
-
- if (devnum != 0)
- return -EINVAL;
-
- hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- pcsp_chip.timer.function = pcsp_do_timer;
-
- err = snd_card_create(index, id, THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- err = snd_pcsp_create(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- if (!nopcm) {
- err = snd_pcsp_new_pcm(&pcsp_chip);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- }
- err = snd_pcsp_new_mixer(&pcsp_chip, nopcm);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- snd_card_set_dev(pcsp_chip.card, dev);
-
- strcpy(card->driver, "PC-Speaker");
- strcpy(card->shortname, "pcsp");
- sprintf(card->longname, "Internal PC-Speaker at port 0x%x",
- pcsp_chip.port);
-
- err = snd_card_register(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- return 0;
-}
-
-static int __devinit alsa_card_pcsp_init(struct device *dev)
-{
- int err;
-
- err = snd_card_pcsp_probe(0, dev);
- if (err) {
- printk(KERN_ERR "PC-Speaker initialization failed.\n");
- return err;
- }
-
-#ifdef CONFIG_DEBUG_PAGEALLOC
- /* Well, CONFIG_DEBUG_PAGEALLOC makes the sound horrible. Lets alert */
- printk(KERN_WARNING "PCSP: CONFIG_DEBUG_PAGEALLOC is enabled, "
- "which may make the sound noisy.\n");
-#endif
-
- return 0;
-}
-
-static void __devexit alsa_card_pcsp_exit(struct snd_pcsp *chip)
-{
- snd_card_free(chip->card);
-}
-
-static int __devinit pcsp_probe(struct platform_device *dev)
-{
- int err;
-
- err = pcspkr_input_init(&pcsp_chip.input_dev, &dev->dev);
- if (err < 0)
- return err;
-
- err = alsa_card_pcsp_init(&dev->dev);
- if (err < 0) {
- pcspkr_input_remove(pcsp_chip.input_dev);
- return err;
- }
-
- platform_set_drvdata(dev, &pcsp_chip);
- return 0;
-}
-
-static int __devexit pcsp_remove(struct platform_device *dev)
-{
- struct snd_pcsp *chip = platform_get_drvdata(dev);
- alsa_card_pcsp_exit(chip);
- pcspkr_input_remove(chip->input_dev);
- platform_set_drvdata(dev, NULL);
- return 0;
-}
-
-static void pcsp_stop_beep(struct snd_pcsp *chip)
-{
- pcsp_sync_stop(chip);
- pcspkr_stop_sound();
-}
-
-#ifdef CONFIG_PM
-static int pcsp_suspend(struct platform_device *dev, pm_message_t state)
-{
- struct snd_pcsp *chip = platform_get_drvdata(dev);
- pcsp_stop_beep(chip);
- snd_pcm_suspend_all(chip->pcm);
- return 0;
-}
-#else
-#define pcsp_suspend NULL
-#endif /* CONFIG_PM */
-
-static void pcsp_shutdown(struct platform_device *dev)
-{
- struct snd_pcsp *chip = platform_get_drvdata(dev);
- pcsp_stop_beep(chip);
-}
-
-static struct platform_driver pcsp_platform_driver = {
- .driver = {
- .name = "pcspkr",
- .owner = THIS_MODULE,
- },
- .probe = pcsp_probe,
- .remove = __devexit_p(pcsp_remove),
- .suspend = pcsp_suspend,
- .shutdown = pcsp_shutdown,
-};
-
-static int __init pcsp_init(void)
-{
- if (!enable)
- return -ENODEV;
- return platform_driver_register(&pcsp_platform_driver);
-}
-
-static void __exit pcsp_exit(void)
-{
- platform_driver_unregister(&pcsp_platform_driver);
-}
-
-module_init(pcsp_init);
-module_exit(pcsp_exit);
diff --git a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp.h b/ANDROID_3.4.5/sound/drivers/pcsp/pcsp.h
deleted file mode 100644
index fc7a2dc4..00000000
--- a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * PC-Speaker driver for Linux
- *
- * Copyright (C) 1993-1997 Michael Beck
- * Copyright (C) 1997-2001 David Woodhouse
- * Copyright (C) 2001-2008 Stas Sergeev
- */
-
-#ifndef __PCSP_H__
-#define __PCSP_H__
-
-#include <linux/hrtimer.h>
-#include <linux/i8253.h>
-#include <linux/timex.h>
-
-#define PCSP_SOUND_VERSION 0x400 /* read 4.00 */
-#define PCSP_DEBUG 0
-
-/* default timer freq for PC-Speaker: 18643 Hz */
-#define DIV_18KHZ 64
-#define MAX_DIV DIV_18KHZ
-#define CALC_DIV(d) (MAX_DIV >> (d))
-#define CUR_DIV() CALC_DIV(chip->treble)
-#define PCSP_MAX_TREBLE 1
-
-/* unfortunately, with hrtimers 37KHz does not work very well :( */
-#define PCSP_DEFAULT_TREBLE 0
-#define MIN_DIV (MAX_DIV >> PCSP_MAX_TREBLE)
-
-/* wild guess */
-#define PCSP_MIN_LPJ 1000000
-#define PCSP_DEFAULT_SDIV (DIV_18KHZ >> 1)
-#define PCSP_DEFAULT_SRATE (PIT_TICK_RATE / PCSP_DEFAULT_SDIV)
-#define PCSP_INDEX_INC() (1 << (PCSP_MAX_TREBLE - chip->treble))
-#define PCSP_CALC_RATE(i) (PIT_TICK_RATE / CALC_DIV(i))
-#define PCSP_RATE() PCSP_CALC_RATE(chip->treble)
-#define PCSP_MIN_RATE__1 MAX_DIV/PIT_TICK_RATE
-#define PCSP_MAX_RATE__1 MIN_DIV/PIT_TICK_RATE
-#define PCSP_MAX_PERIOD_NS (1000000000ULL * PCSP_MIN_RATE__1)
-#define PCSP_MIN_PERIOD_NS (1000000000ULL * PCSP_MAX_RATE__1)
-#define PCSP_CALC_NS(div) ({ \
- u64 __val = 1000000000ULL * (div); \
- do_div(__val, PIT_TICK_RATE); \
- __val; \
-})
-#define PCSP_PERIOD_NS() PCSP_CALC_NS(CUR_DIV())
-
-#define PCSP_MAX_PERIOD_SIZE (64*1024)
-#define PCSP_MAX_PERIODS 512
-#define PCSP_BUFFER_SIZE (128*1024)
-
-struct snd_pcsp {
- struct snd_card *card;
- struct snd_pcm *pcm;
- struct input_dev *input_dev;
- struct hrtimer timer;
- unsigned short port, irq, dma;
- spinlock_t substream_lock;
- struct snd_pcm_substream *playback_substream;
- unsigned int fmt_size;
- unsigned int is_signed;
- size_t playback_ptr;
- size_t period_ptr;
- atomic_t timer_active;
- int thalf;
- u64 ns_rem;
- unsigned char val61;
- int enable;
- int max_treble;
- int treble;
- int pcspkr;
-};
-
-extern struct snd_pcsp pcsp_chip;
-
-extern enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle);
-extern void pcsp_sync_stop(struct snd_pcsp *chip);
-
-extern int snd_pcsp_new_pcm(struct snd_pcsp *chip);
-extern int snd_pcsp_new_mixer(struct snd_pcsp *chip, int nopcm);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_input.c b/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_input.c
deleted file mode 100644
index b5e2b54c..00000000
--- a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_input.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * PC Speaker beeper driver for Linux
- *
- * Copyright (c) 2002 Vojtech Pavlik
- * Copyright (c) 1992 Orest Zborowski
- *
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation
- */
-
-#include <linux/init.h>
-#include <linux/input.h>
-#include <asm/io.h>
-#include "pcsp.h"
-
-static void pcspkr_do_sound(unsigned int count)
-{
- unsigned long flags;
-
- raw_spin_lock_irqsave(&i8253_lock, flags);
-
- if (count) {
- /* set command for counter 2, 2 byte write */
- outb_p(0xB6, 0x43);
- /* select desired HZ */
- outb_p(count & 0xff, 0x42);
- outb((count >> 8) & 0xff, 0x42);
- /* enable counter 2 */
- outb_p(inb_p(0x61) | 3, 0x61);
- } else {
- /* disable counter 2 */
- outb(inb_p(0x61) & 0xFC, 0x61);
- }
-
- raw_spin_unlock_irqrestore(&i8253_lock, flags);
-}
-
-void pcspkr_stop_sound(void)
-{
- pcspkr_do_sound(0);
-}
-
-static int pcspkr_input_event(struct input_dev *dev, unsigned int type,
- unsigned int code, int value)
-{
- unsigned int count = 0;
-
- if (atomic_read(&pcsp_chip.timer_active) || !pcsp_chip.pcspkr)
- return 0;
-
- switch (type) {
- case EV_SND:
- switch (code) {
- case SND_BELL:
- if (value)
- value = 1000;
- case SND_TONE:
- break;
- default:
- return -1;
- }
- break;
-
- default:
- return -1;
- }
-
- if (value > 20 && value < 32767)
- count = PIT_TICK_RATE / value;
-
- pcspkr_do_sound(count);
-
- return 0;
-}
-
-int __devinit pcspkr_input_init(struct input_dev **rdev, struct device *dev)
-{
- int err;
-
- struct input_dev *input_dev = input_allocate_device();
- if (!input_dev)
- return -ENOMEM;
-
- input_dev->name = "PC Speaker";
- input_dev->phys = "isa0061/input0";
- input_dev->id.bustype = BUS_ISA;
- input_dev->id.vendor = 0x001f;
- input_dev->id.product = 0x0001;
- input_dev->id.version = 0x0100;
- input_dev->dev.parent = dev;
-
- input_dev->evbit[0] = BIT(EV_SND);
- input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
- input_dev->event = pcspkr_input_event;
-
- err = input_register_device(input_dev);
- if (err) {
- input_free_device(input_dev);
- return err;
- }
-
- *rdev = input_dev;
- return 0;
-}
-
-int pcspkr_input_remove(struct input_dev *dev)
-{
- pcspkr_stop_sound();
- input_unregister_device(dev); /* this also does kfree() */
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_input.h b/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_input.h
deleted file mode 100644
index e66738c7..00000000
--- a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_input.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * PC-Speaker driver for Linux
- *
- * Copyright (C) 2001-2008 Stas Sergeev
- */
-
-#ifndef __PCSP_INPUT_H__
-#define __PCSP_INPUT_H__
-
-int __devinit pcspkr_input_init(struct input_dev **rdev, struct device *dev);
-int pcspkr_input_remove(struct input_dev *dev);
-void pcspkr_stop_sound(void);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_lib.c b/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_lib.c
deleted file mode 100644
index 434981dd..00000000
--- a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_lib.c
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * PC-Speaker driver for Linux
- *
- * Copyright (C) 1993-1997 Michael Beck
- * Copyright (C) 1997-2001 David Woodhouse
- * Copyright (C) 2001-2008 Stas Sergeev
- */
-
-#include <linux/module.h>
-#include <linux/gfp.h>
-#include <linux/moduleparam.h>
-#include <linux/interrupt.h>
-#include <sound/pcm.h>
-#include <asm/io.h>
-#include "pcsp.h"
-
-static bool nforce_wa;
-module_param(nforce_wa, bool, 0444);
-MODULE_PARM_DESC(nforce_wa, "Apply NForce chipset workaround "
- "(expect bad sound)");
-
-#define DMIX_WANTS_S16 1
-
-/*
- * Call snd_pcm_period_elapsed in a tasklet
- * This avoids spinlock messes and long-running irq contexts
- */
-static void pcsp_call_pcm_elapsed(unsigned long priv)
-{
- if (atomic_read(&pcsp_chip.timer_active)) {
- struct snd_pcm_substream *substream;
- substream = pcsp_chip.playback_substream;
- if (substream)
- snd_pcm_period_elapsed(substream);
- }
-}
-
-static DECLARE_TASKLET(pcsp_pcm_tasklet, pcsp_call_pcm_elapsed, 0);
-
-/* write the port and returns the next expire time in ns;
- * called at the trigger-start and in hrtimer callback
- */
-static u64 pcsp_timer_update(struct snd_pcsp *chip)
-{
- unsigned char timer_cnt, val;
- u64 ns;
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
- unsigned long flags;
-
- if (chip->thalf) {
- outb(chip->val61, 0x61);
- chip->thalf = 0;
- return chip->ns_rem;
- }
-
- substream = chip->playback_substream;
- if (!substream)
- return 0;
-
- runtime = substream->runtime;
- /* assume it is mono! */
- val = runtime->dma_area[chip->playback_ptr + chip->fmt_size - 1];
- if (chip->is_signed)
- val ^= 0x80;
- timer_cnt = val * CUR_DIV() / 256;
-
- if (timer_cnt && chip->enable) {
- raw_spin_lock_irqsave(&i8253_lock, flags);
- if (!nforce_wa) {
- outb_p(chip->val61, 0x61);
- outb_p(timer_cnt, 0x42);
- outb(chip->val61 ^ 1, 0x61);
- } else {
- outb(chip->val61 ^ 2, 0x61);
- chip->thalf = 1;
- }
- raw_spin_unlock_irqrestore(&i8253_lock, flags);
- }
-
- chip->ns_rem = PCSP_PERIOD_NS();
- ns = (chip->thalf ? PCSP_CALC_NS(timer_cnt) : chip->ns_rem);
- chip->ns_rem -= ns;
- return ns;
-}
-
-static void pcsp_pointer_update(struct snd_pcsp *chip)
-{
- struct snd_pcm_substream *substream;
- size_t period_bytes, buffer_bytes;
- int periods_elapsed;
- unsigned long flags;
-
- /* update the playback position */
- substream = chip->playback_substream;
- if (!substream)
- return;
-
- period_bytes = snd_pcm_lib_period_bytes(substream);
- buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
-
- spin_lock_irqsave(&chip->substream_lock, flags);
- chip->playback_ptr += PCSP_INDEX_INC() * chip->fmt_size;
- periods_elapsed = chip->playback_ptr - chip->period_ptr;
- if (periods_elapsed < 0) {
-#if PCSP_DEBUG
- printk(KERN_INFO "PCSP: buffer_bytes mod period_bytes != 0 ? "
- "(%zi %zi %zi)\n",
- chip->playback_ptr, period_bytes, buffer_bytes);
-#endif
- periods_elapsed += buffer_bytes;
- }
- periods_elapsed /= period_bytes;
- /* wrap the pointer _before_ calling snd_pcm_period_elapsed(),
- * or ALSA will BUG on us. */
- chip->playback_ptr %= buffer_bytes;
-
- if (periods_elapsed) {
- chip->period_ptr += periods_elapsed * period_bytes;
- chip->period_ptr %= buffer_bytes;
- }
- spin_unlock_irqrestore(&chip->substream_lock, flags);
-
- if (periods_elapsed)
- tasklet_schedule(&pcsp_pcm_tasklet);
-}
-
-enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
-{
- struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
- int pointer_update;
- u64 ns;
-
- if (!atomic_read(&chip->timer_active) || !chip->playback_substream)
- return HRTIMER_NORESTART;
-
- pointer_update = !chip->thalf;
- ns = pcsp_timer_update(chip);
- if (!ns) {
- printk(KERN_WARNING "PCSP: unexpected stop\n");
- return HRTIMER_NORESTART;
- }
-
- if (pointer_update)
- pcsp_pointer_update(chip);
-
- hrtimer_forward(handle, hrtimer_get_expires(handle), ns_to_ktime(ns));
-
- return HRTIMER_RESTART;
-}
-
-static int pcsp_start_playing(struct snd_pcsp *chip)
-{
-#if PCSP_DEBUG
- printk(KERN_INFO "PCSP: start_playing called\n");
-#endif
- if (atomic_read(&chip->timer_active)) {
- printk(KERN_ERR "PCSP: Timer already active\n");
- return -EIO;
- }
-
- raw_spin_lock(&i8253_lock);
- chip->val61 = inb(0x61) | 0x03;
- outb_p(0x92, 0x43); /* binary, mode 1, LSB only, ch 2 */
- raw_spin_unlock(&i8253_lock);
- atomic_set(&chip->timer_active, 1);
- chip->thalf = 0;
-
- hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL);
- return 0;
-}
-
-static void pcsp_stop_playing(struct snd_pcsp *chip)
-{
-#if PCSP_DEBUG
- printk(KERN_INFO "PCSP: stop_playing called\n");
-#endif
- if (!atomic_read(&chip->timer_active))
- return;
-
- atomic_set(&chip->timer_active, 0);
- raw_spin_lock(&i8253_lock);
- /* restore the timer */
- outb_p(0xb6, 0x43); /* binary, mode 3, LSB/MSB, ch 2 */
- outb(chip->val61 & 0xFC, 0x61);
- raw_spin_unlock(&i8253_lock);
-}
-
-/*
- * Force to stop and sync the stream
- */
-void pcsp_sync_stop(struct snd_pcsp *chip)
-{
- local_irq_disable();
- pcsp_stop_playing(chip);
- local_irq_enable();
- hrtimer_cancel(&chip->timer);
- tasklet_kill(&pcsp_pcm_tasklet);
-}
-
-static int snd_pcsp_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
-#if PCSP_DEBUG
- printk(KERN_INFO "PCSP: close called\n");
-#endif
- pcsp_sync_stop(chip);
- chip->playback_substream = NULL;
- return 0;
-}
-
-static int snd_pcsp_playback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
- int err;
- pcsp_sync_stop(chip);
- err = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
- return 0;
-}
-
-static int snd_pcsp_playback_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
-#if PCSP_DEBUG
- printk(KERN_INFO "PCSP: hw_free called\n");
-#endif
- pcsp_sync_stop(chip);
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_pcsp_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
- pcsp_sync_stop(chip);
- chip->playback_ptr = 0;
- chip->period_ptr = 0;
- chip->fmt_size =
- snd_pcm_format_physical_width(substream->runtime->format) >> 3;
- chip->is_signed = snd_pcm_format_signed(substream->runtime->format);
-#if PCSP_DEBUG
- printk(KERN_INFO "PCSP: prepare called, "
- "size=%zi psize=%zi f=%zi f1=%i fsize=%i\n",
- snd_pcm_lib_buffer_bytes(substream),
- snd_pcm_lib_period_bytes(substream),
- snd_pcm_lib_buffer_bytes(substream) /
- snd_pcm_lib_period_bytes(substream),
- substream->runtime->periods,
- chip->fmt_size);
-#endif
- return 0;
-}
-
-static int snd_pcsp_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
-#if PCSP_DEBUG
- printk(KERN_INFO "PCSP: trigger called\n");
-#endif
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- return pcsp_start_playing(chip);
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- pcsp_stop_playing(chip);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static snd_pcm_uframes_t snd_pcsp_playback_pointer(struct snd_pcm_substream
- *substream)
-{
- struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
- unsigned int pos;
- spin_lock(&chip->substream_lock);
- pos = chip->playback_ptr;
- spin_unlock(&chip->substream_lock);
- return bytes_to_frames(substream->runtime, pos);
-}
-
-static struct snd_pcm_hardware snd_pcsp_playback = {
- .info = (SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_HALF_DUPLEX |
- SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
- .formats = (SNDRV_PCM_FMTBIT_U8
-#if DMIX_WANTS_S16
- | SNDRV_PCM_FMTBIT_S16_LE
-#endif
- ),
- .rates = SNDRV_PCM_RATE_KNOT,
- .rate_min = PCSP_DEFAULT_SRATE,
- .rate_max = PCSP_DEFAULT_SRATE,
- .channels_min = 1,
- .channels_max = 1,
- .buffer_bytes_max = PCSP_BUFFER_SIZE,
- .period_bytes_min = 64,
- .period_bytes_max = PCSP_MAX_PERIOD_SIZE,
- .periods_min = 2,
- .periods_max = PCSP_MAX_PERIODS,
- .fifo_size = 0,
-};
-
-static int snd_pcsp_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-#if PCSP_DEBUG
- printk(KERN_INFO "PCSP: open called\n");
-#endif
- if (atomic_read(&chip->timer_active)) {
- printk(KERN_ERR "PCSP: still active!!\n");
- return -EBUSY;
- }
- runtime->hw = snd_pcsp_playback;
- chip->playback_substream = substream;
- return 0;
-}
-
-static struct snd_pcm_ops snd_pcsp_playback_ops = {
- .open = snd_pcsp_playback_open,
- .close = snd_pcsp_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_pcsp_playback_hw_params,
- .hw_free = snd_pcsp_playback_hw_free,
- .prepare = snd_pcsp_playback_prepare,
- .trigger = snd_pcsp_trigger,
- .pointer = snd_pcsp_playback_pointer,
-};
-
-int __devinit snd_pcsp_new_pcm(struct snd_pcsp *chip)
-{
- int err;
-
- err = snd_pcm_new(chip->card, "pcspeaker", 0, 1, 0, &chip->pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(chip->pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_pcsp_playback_ops);
-
- chip->pcm->private_data = chip;
- chip->pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
- strcpy(chip->pcm->name, "pcsp");
-
- snd_pcm_lib_preallocate_pages_for_all(chip->pcm,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data
- (GFP_KERNEL), PCSP_BUFFER_SIZE,
- PCSP_BUFFER_SIZE);
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_mixer.c b/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_mixer.c
deleted file mode 100644
index 6f633f4f..00000000
--- a/ANDROID_3.4.5/sound/drivers/pcsp/pcsp_mixer.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * PC-Speaker driver for Linux
- *
- * Mixer implementation.
- * Copyright (C) 2001-2008 Stas Sergeev
- */
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include "pcsp.h"
-
-
-static int pcsp_enable_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int pcsp_enable_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = chip->enable;
- return 0;
-}
-
-static int pcsp_enable_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- int enab = ucontrol->value.integer.value[0];
- if (enab != chip->enable) {
- chip->enable = enab;
- changed = 1;
- }
- return changed;
-}
-
-static int pcsp_treble_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = chip->max_treble + 1;
- if (uinfo->value.enumerated.item > chip->max_treble)
- uinfo->value.enumerated.item = chip->max_treble;
- sprintf(uinfo->value.enumerated.name, "%lu",
- (unsigned long)PCSP_CALC_RATE(uinfo->value.enumerated.item));
- return 0;
-}
-
-static int pcsp_treble_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = chip->treble;
- return 0;
-}
-
-static int pcsp_treble_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- int treble = ucontrol->value.enumerated.item[0];
- if (treble != chip->treble) {
- chip->treble = treble;
-#if PCSP_DEBUG
- printk(KERN_INFO "PCSP: rate set to %li\n", PCSP_RATE());
-#endif
- changed = 1;
- }
- return changed;
-}
-
-static int pcsp_pcspkr_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int pcsp_pcspkr_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = chip->pcspkr;
- return 0;
-}
-
-static int pcsp_pcspkr_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcsp *chip = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- int spkr = ucontrol->value.integer.value[0];
- if (spkr != chip->pcspkr) {
- chip->pcspkr = spkr;
- changed = 1;
- }
- return changed;
-}
-
-#define PCSP_MIXER_CONTROL(ctl_type, ctl_name) \
-{ \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = ctl_name, \
- .info = pcsp_##ctl_type##_info, \
- .get = pcsp_##ctl_type##_get, \
- .put = pcsp_##ctl_type##_put, \
-}
-
-static struct snd_kcontrol_new __devinitdata snd_pcsp_controls_pcm[] = {
- PCSP_MIXER_CONTROL(enable, "Master Playback Switch"),
- PCSP_MIXER_CONTROL(treble, "BaseFRQ Playback Volume"),
-};
-
-static struct snd_kcontrol_new __devinitdata snd_pcsp_controls_spkr[] = {
- PCSP_MIXER_CONTROL(pcspkr, "Beep Playback Switch"),
-};
-
-static int __devinit snd_pcsp_ctls_add(struct snd_pcsp *chip,
- struct snd_kcontrol_new *ctls, int num)
-{
- int i, err;
- struct snd_card *card = chip->card;
- for (i = 0; i < num; i++) {
- err = snd_ctl_add(card, snd_ctl_new1(ctls + i, chip));
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-int __devinit snd_pcsp_new_mixer(struct snd_pcsp *chip, int nopcm)
-{
- int err;
- struct snd_card *card = chip->card;
-
- if (!nopcm) {
- err = snd_pcsp_ctls_add(chip, snd_pcsp_controls_pcm,
- ARRAY_SIZE(snd_pcsp_controls_pcm));
- if (err < 0)
- return err;
- }
- err = snd_pcsp_ctls_add(chip, snd_pcsp_controls_spkr,
- ARRAY_SIZE(snd_pcsp_controls_spkr));
- if (err < 0)
- return err;
-
- strcpy(card->mixername, "PC-Speaker");
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/drivers/portman2x4.c b/ANDROID_3.4.5/sound/drivers/portman2x4.c
deleted file mode 100644
index 3e32bd3d..00000000
--- a/ANDROID_3.4.5/sound/drivers/portman2x4.c
+++ /dev/null
@@ -1,879 +0,0 @@
-/*
- * Driver for Midiman Portman2x4 parallel port midi interface
- *
- * Copyright (c) by Levent Guendogdu <levon@feature-it.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * ChangeLog
- * Jan 24 2007 Matthias Koenig <mkoenig@suse.de>
- * - cleanup and rewrite
- * Sep 30 2004 Tobias Gehrig <tobias@gehrig.tk>
- * - source code cleanup
- * Sep 03 2004 Tobias Gehrig <tobias@gehrig.tk>
- * - fixed compilation problem with alsa 1.0.6a (removed MODULE_CLASSES,
- * MODULE_PARM_SYNTAX and changed MODULE_DEVICES to
- * MODULE_SUPPORTED_DEVICE)
- * Mar 24 2004 Tobias Gehrig <tobias@gehrig.tk>
- * - added 2.6 kernel support
- * Mar 18 2004 Tobias Gehrig <tobias@gehrig.tk>
- * - added parport_unregister_driver to the startup routine if the driver fails to detect a portman
- * - added support for all 4 output ports in portman_putmidi
- * Mar 17 2004 Tobias Gehrig <tobias@gehrig.tk>
- * - added checks for opened input device in interrupt handler
- * Feb 20 2004 Tobias Gehrig <tobias@gehrig.tk>
- * - ported from alsa 0.5 to 1.0
- */
-
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/parport.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/rawmidi.h>
-#include <sound/control.h>
-
-#define CARD_NAME "Portman 2x4"
-#define DRIVER_NAME "portman"
-#define PLATFORM_DRIVER "snd_portman2x4"
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-static struct platform_device *platform_devices[SNDRV_CARDS];
-static int device_count;
-
-module_param_array(index, int, NULL, S_IRUGO);
-MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
-module_param_array(id, charp, NULL, S_IRUGO);
-MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, S_IRUGO);
-MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
-
-MODULE_AUTHOR("Levent Guendogdu, Tobias Gehrig, Matthias Koenig");
-MODULE_DESCRIPTION("Midiman Portman2x4");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Midiman,Portman2x4}}");
-
-/*********************************************************************
- * Chip specific
- *********************************************************************/
-#define PORTMAN_NUM_INPUT_PORTS 2
-#define PORTMAN_NUM_OUTPUT_PORTS 4
-
-struct portman {
- spinlock_t reg_lock;
- struct snd_card *card;
- struct snd_rawmidi *rmidi;
- struct pardevice *pardev;
- int pardev_claimed;
-
- int open_count;
- int mode[PORTMAN_NUM_INPUT_PORTS];
- struct snd_rawmidi_substream *midi_input[PORTMAN_NUM_INPUT_PORTS];
-};
-
-static int portman_free(struct portman *pm)
-{
- kfree(pm);
- return 0;
-}
-
-static int __devinit portman_create(struct snd_card *card,
- struct pardevice *pardev,
- struct portman **rchip)
-{
- struct portman *pm;
-
- *rchip = NULL;
-
- pm = kzalloc(sizeof(struct portman), GFP_KERNEL);
- if (pm == NULL)
- return -ENOMEM;
-
- /* Init chip specific data */
- spin_lock_init(&pm->reg_lock);
- pm->card = card;
- pm->pardev = pardev;
-
- *rchip = pm;
-
- return 0;
-}
-
-/*********************************************************************
- * HW related constants
- *********************************************************************/
-
-/* Standard PC parallel port status register equates. */
-#define PP_STAT_BSY 0x80 /* Busy status. Inverted. */
-#define PP_STAT_ACK 0x40 /* Acknowledge. Non-Inverted. */
-#define PP_STAT_POUT 0x20 /* Paper Out. Non-Inverted. */
-#define PP_STAT_SEL 0x10 /* Select. Non-Inverted. */
-#define PP_STAT_ERR 0x08 /* Error. Non-Inverted. */
-
-/* Standard PC parallel port command register equates. */
-#define PP_CMD_IEN 0x10 /* IRQ Enable. Non-Inverted. */
-#define PP_CMD_SELI 0x08 /* Select Input. Inverted. */
-#define PP_CMD_INIT 0x04 /* Init Printer. Non-Inverted. */
-#define PP_CMD_FEED 0x02 /* Auto Feed. Inverted. */
-#define PP_CMD_STB 0x01 /* Strobe. Inverted. */
-
-/* Parallel Port Command Register as implemented by PCP2x4. */
-#define INT_EN PP_CMD_IEN /* Interrupt enable. */
-#define STROBE PP_CMD_STB /* Command strobe. */
-
-/* The parallel port command register field (b1..b3) selects the
- * various "registers" within the PC/P 2x4. These are the internal
- * address of these "registers" that must be written to the parallel
- * port command register.
- */
-#define RXDATA0 (0 << 1) /* PCP RxData channel 0. */
-#define RXDATA1 (1 << 1) /* PCP RxData channel 1. */
-#define GEN_CTL (2 << 1) /* PCP General Control Register. */
-#define SYNC_CTL (3 << 1) /* PCP Sync Control Register. */
-#define TXDATA0 (4 << 1) /* PCP TxData channel 0. */
-#define TXDATA1 (5 << 1) /* PCP TxData channel 1. */
-#define TXDATA2 (6 << 1) /* PCP TxData channel 2. */
-#define TXDATA3 (7 << 1) /* PCP TxData channel 3. */
-
-/* Parallel Port Status Register as implemented by PCP2x4. */
-#define ESTB PP_STAT_POUT /* Echoed strobe. */
-#define INT_REQ PP_STAT_ACK /* Input data int request. */
-#define BUSY PP_STAT_ERR /* Interface Busy. */
-
-/* Parallel Port Status Register BUSY and SELECT lines are multiplexed
- * between several functions. Depending on which 2x4 "register" is
- * currently selected (b1..b3), the BUSY and SELECT lines are
- * assigned as follows:
- *
- * SELECT LINE: A3 A2 A1
- * --------
- */
-#define RXAVAIL PP_STAT_SEL /* Rx Available, channel 0. 0 0 0 */
-// RXAVAIL1 PP_STAT_SEL /* Rx Available, channel 1. 0 0 1 */
-#define SYNC_STAT PP_STAT_SEL /* Reserved - Sync Status. 0 1 0 */
-// /* Reserved. 0 1 1 */
-#define TXEMPTY PP_STAT_SEL /* Tx Empty, channel 0. 1 0 0 */
-// TXEMPTY1 PP_STAT_SEL /* Tx Empty, channel 1. 1 0 1 */
-// TXEMPTY2 PP_STAT_SEL /* Tx Empty, channel 2. 1 1 0 */
-// TXEMPTY3 PP_STAT_SEL /* Tx Empty, channel 3. 1 1 1 */
-
-/* BUSY LINE: A3 A2 A1
- * --------
- */
-#define RXDATA PP_STAT_BSY /* Rx Input Data, channel 0. 0 0 0 */
-// RXDATA1 PP_STAT_BSY /* Rx Input Data, channel 1. 0 0 1 */
-#define SYNC_DATA PP_STAT_BSY /* Reserved - Sync Data. 0 1 0 */
- /* Reserved. 0 1 1 */
-#define DATA_ECHO PP_STAT_BSY /* Parallel Port Data Echo. 1 0 0 */
-#define A0_ECHO PP_STAT_BSY /* Address 0 Echo. 1 0 1 */
-#define A1_ECHO PP_STAT_BSY /* Address 1 Echo. 1 1 0 */
-#define A2_ECHO PP_STAT_BSY /* Address 2 Echo. 1 1 1 */
-
-#define PORTMAN2X4_MODE_INPUT_TRIGGERED 0x01
-
-/*********************************************************************
- * Hardware specific functions
- *********************************************************************/
-static inline void portman_write_command(struct portman *pm, u8 value)
-{
- parport_write_control(pm->pardev->port, value);
-}
-
-static inline u8 portman_read_command(struct portman *pm)
-{
- return parport_read_control(pm->pardev->port);
-}
-
-static inline u8 portman_read_status(struct portman *pm)
-{
- return parport_read_status(pm->pardev->port);
-}
-
-static inline u8 portman_read_data(struct portman *pm)
-{
- return parport_read_data(pm->pardev->port);
-}
-
-static inline void portman_write_data(struct portman *pm, u8 value)
-{
- parport_write_data(pm->pardev->port, value);
-}
-
-static void portman_write_midi(struct portman *pm,
- int port, u8 mididata)
-{
- int command = ((port + 4) << 1);
-
- /* Get entering data byte and port number in BL and BH respectively.
- * Set up Tx Channel address field for use with PP Cmd Register.
- * Store address field in BH register.
- * Inputs: AH = Output port number (0..3).
- * AL = Data byte.
- * command = TXDATA0 | INT_EN;
- * Align port num with address field (b1...b3),
- * set address for TXDatax, Strobe=0
- */
- command |= INT_EN;
-
- /* Disable interrupts so that the process is not interrupted, then
- * write the address associated with the current Tx channel to the
- * PP Command Reg. Do not set the Strobe signal yet.
- */
-
- do {
- portman_write_command(pm, command);
-
- /* While the address lines settle, write parallel output data to
- * PP Data Reg. This has no effect until Strobe signal is asserted.
- */
-
- portman_write_data(pm, mididata);
-
- /* If PCP channel's TxEmpty is set (TxEmpty is read through the PP
- * Status Register), then go write data. Else go back and wait.
- */
- } while ((portman_read_status(pm) & TXEMPTY) != TXEMPTY);
-
- /* TxEmpty is set. Maintain PC/P destination address and assert
- * Strobe through the PP Command Reg. This will Strobe data into
- * the PC/P transmitter and set the PC/P BUSY signal.
- */
-
- portman_write_command(pm, command | STROBE);
-
- /* Wait for strobe line to settle and echo back through hardware.
- * Once it has echoed back, assume that the address and data lines
- * have settled!
- */
-
- while ((portman_read_status(pm) & ESTB) == 0)
- cpu_relax();
-
- /* Release strobe and immediately re-allow interrupts. */
- portman_write_command(pm, command);
-
- while ((portman_read_status(pm) & ESTB) == ESTB)
- cpu_relax();
-
- /* PC/P BUSY is now set. We must wait until BUSY resets itself.
- * We'll reenable ints while we're waiting.
- */
-
- while ((portman_read_status(pm) & BUSY) == BUSY)
- cpu_relax();
-
- /* Data sent. */
-}
-
-
-/*
- * Read MIDI byte from port
- * Attempt to read input byte from specified hardware input port (0..).
- * Return -1 if no data
- */
-static int portman_read_midi(struct portman *pm, int port)
-{
- unsigned char midi_data = 0;
- unsigned char cmdout; /* Saved address+IE bit. */
-
- /* Make sure clocking edge is down before starting... */
- portman_write_data(pm, 0); /* Make sure edge is down. */
-
- /* Set destination address to PCP. */
- cmdout = (port << 1) | INT_EN; /* Address + IE + No Strobe. */
- portman_write_command(pm, cmdout);
-
- while ((portman_read_status(pm) & ESTB) == ESTB)
- cpu_relax(); /* Wait for strobe echo. */
-
- /* After the address lines settle, check multiplexed RxAvail signal.
- * If data is available, read it.
- */
- if ((portman_read_status(pm) & RXAVAIL) == 0)
- return -1; /* No data. */
-
- /* Set the Strobe signal to enable the Rx clocking circuitry. */
- portman_write_command(pm, cmdout | STROBE); /* Write address+IE+Strobe. */
-
- while ((portman_read_status(pm) & ESTB) == 0)
- cpu_relax(); /* Wait for strobe echo. */
-
- /* The first data bit (msb) is already sitting on the input line. */
- midi_data = (portman_read_status(pm) & 128);
- portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */
-
- /* Data bit 6. */
- portman_write_data(pm, 0); /* Cause falling edge while data settles. */
- midi_data |= (portman_read_status(pm) >> 1) & 64;
- portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */
-
- /* Data bit 5. */
- portman_write_data(pm, 0); /* Cause falling edge while data settles. */
- midi_data |= (portman_read_status(pm) >> 2) & 32;
- portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */
-
- /* Data bit 4. */
- portman_write_data(pm, 0); /* Cause falling edge while data settles. */
- midi_data |= (portman_read_status(pm) >> 3) & 16;
- portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */
-
- /* Data bit 3. */
- portman_write_data(pm, 0); /* Cause falling edge while data settles. */
- midi_data |= (portman_read_status(pm) >> 4) & 8;
- portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */
-
- /* Data bit 2. */
- portman_write_data(pm, 0); /* Cause falling edge while data settles. */
- midi_data |= (portman_read_status(pm) >> 5) & 4;
- portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */
-
- /* Data bit 1. */
- portman_write_data(pm, 0); /* Cause falling edge while data settles. */
- midi_data |= (portman_read_status(pm) >> 6) & 2;
- portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */
-
- /* Data bit 0. */
- portman_write_data(pm, 0); /* Cause falling edge while data settles. */
- midi_data |= (portman_read_status(pm) >> 7) & 1;
- portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */
- portman_write_data(pm, 0); /* Return data clock low. */
-
-
- /* De-assert Strobe and return data. */
- portman_write_command(pm, cmdout); /* Output saved address+IE. */
-
- /* Wait for strobe echo. */
- while ((portman_read_status(pm) & ESTB) == ESTB)
- cpu_relax();
-
- return (midi_data & 255); /* Shift back and return value. */
-}
-
-/*
- * Checks if any input data on the given channel is available
- * Checks RxAvail
- */
-static int portman_data_avail(struct portman *pm, int channel)
-{
- int command = INT_EN;
- switch (channel) {
- case 0:
- command |= RXDATA0;
- break;
- case 1:
- command |= RXDATA1;
- break;
- }
- /* Write hardware (assumme STROBE=0) */
- portman_write_command(pm, command);
- /* Check multiplexed RxAvail signal */
- if ((portman_read_status(pm) & RXAVAIL) == RXAVAIL)
- return 1; /* Data available */
-
- /* No Data available */
- return 0;
-}
-
-
-/*
- * Flushes any input
- */
-static void portman_flush_input(struct portman *pm, unsigned char port)
-{
- /* Local variable for counting things */
- unsigned int i = 0;
- unsigned char command = 0;
-
- switch (port) {
- case 0:
- command = RXDATA0;
- break;
- case 1:
- command = RXDATA1;
- break;
- default:
- snd_printk(KERN_WARNING
- "portman_flush_input() Won't flush port %i\n",
- port);
- return;
- }
-
- /* Set address for specified channel in port and allow to settle. */
- portman_write_command(pm, command);
-
- /* Assert the Strobe and wait for echo back. */
- portman_write_command(pm, command | STROBE);
-
- /* Wait for ESTB */
- while ((portman_read_status(pm) & ESTB) == 0)
- cpu_relax();
-
- /* Output clock cycles to the Rx circuitry. */
- portman_write_data(pm, 0);
-
- /* Flush 250 bits... */
- for (i = 0; i < 250; i++) {
- portman_write_data(pm, 1);
- portman_write_data(pm, 0);
- }
-
- /* Deassert the Strobe signal of the port and wait for it to settle. */
- portman_write_command(pm, command | INT_EN);
-
- /* Wait for settling */
- while ((portman_read_status(pm) & ESTB) == ESTB)
- cpu_relax();
-}
-
-static int portman_probe(struct parport *p)
-{
- /* Initialize the parallel port data register. Will set Rx clocks
- * low in case we happen to be addressing the Rx ports at this time.
- */
- /* 1 */
- parport_write_data(p, 0);
-
- /* Initialize the parallel port command register, thus initializing
- * hardware handshake lines to midi box:
- *
- * Strobe = 0
- * Interrupt Enable = 0
- */
- /* 2 */
- parport_write_control(p, 0);
-
- /* Check if Portman PC/P 2x4 is out there. */
- /* 3 */
- parport_write_control(p, RXDATA0); /* Write Strobe=0 to command reg. */
-
- /* Check for ESTB to be clear */
- /* 4 */
- if ((parport_read_status(p) & ESTB) == ESTB)
- return 1; /* CODE 1 - Strobe Failure. */
-
- /* Set for RXDATA0 where no damage will be done. */
- /* 5 */
- parport_write_control(p, RXDATA0 + STROBE); /* Write Strobe=1 to command reg. */
-
- /* 6 */
- if ((parport_read_status(p) & ESTB) != ESTB)
- return 1; /* CODE 1 - Strobe Failure. */
-
- /* 7 */
- parport_write_control(p, 0); /* Reset Strobe=0. */
-
- /* Check if Tx circuitry is functioning properly. If initialized
- * unit TxEmpty is false, send out char and see if if goes true.
- */
- /* 8 */
- parport_write_control(p, TXDATA0); /* Tx channel 0, strobe off. */
-
- /* If PCP channel's TxEmpty is set (TxEmpty is read through the PP
- * Status Register), then go write data. Else go back and wait.
- */
- /* 9 */
- if ((parport_read_status(p) & TXEMPTY) == 0)
- return 2;
-
- /* Return OK status. */
- return 0;
-}
-
-static int portman_device_init(struct portman *pm)
-{
- portman_flush_input(pm, 0);
- portman_flush_input(pm, 1);
-
- return 0;
-}
-
-/*********************************************************************
- * Rawmidi
- *********************************************************************/
-static int snd_portman_midi_open(struct snd_rawmidi_substream *substream)
-{
- return 0;
-}
-
-static int snd_portman_midi_close(struct snd_rawmidi_substream *substream)
-{
- return 0;
-}
-
-static void snd_portman_midi_input_trigger(struct snd_rawmidi_substream *substream,
- int up)
-{
- struct portman *pm = substream->rmidi->private_data;
- unsigned long flags;
-
- spin_lock_irqsave(&pm->reg_lock, flags);
- if (up)
- pm->mode[substream->number] |= PORTMAN2X4_MODE_INPUT_TRIGGERED;
- else
- pm->mode[substream->number] &= ~PORTMAN2X4_MODE_INPUT_TRIGGERED;
- spin_unlock_irqrestore(&pm->reg_lock, flags);
-}
-
-static void snd_portman_midi_output_trigger(struct snd_rawmidi_substream *substream,
- int up)
-{
- struct portman *pm = substream->rmidi->private_data;
- unsigned long flags;
- unsigned char byte;
-
- spin_lock_irqsave(&pm->reg_lock, flags);
- if (up) {
- while ((snd_rawmidi_transmit(substream, &byte, 1) == 1))
- portman_write_midi(pm, substream->number, byte);
- }
- spin_unlock_irqrestore(&pm->reg_lock, flags);
-}
-
-static struct snd_rawmidi_ops snd_portman_midi_output = {
- .open = snd_portman_midi_open,
- .close = snd_portman_midi_close,
- .trigger = snd_portman_midi_output_trigger,
-};
-
-static struct snd_rawmidi_ops snd_portman_midi_input = {
- .open = snd_portman_midi_open,
- .close = snd_portman_midi_close,
- .trigger = snd_portman_midi_input_trigger,
-};
-
-/* Create and initialize the rawmidi component */
-static int __devinit snd_portman_rawmidi_create(struct snd_card *card)
-{
- struct portman *pm = card->private_data;
- struct snd_rawmidi *rmidi;
- struct snd_rawmidi_substream *substream;
- int err;
-
- err = snd_rawmidi_new(card, CARD_NAME, 0,
- PORTMAN_NUM_OUTPUT_PORTS,
- PORTMAN_NUM_INPUT_PORTS,
- &rmidi);
- if (err < 0)
- return err;
-
- rmidi->private_data = pm;
- strcpy(rmidi->name, CARD_NAME);
- rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
-
- pm->rmidi = rmidi;
-
- /* register rawmidi ops */
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
- &snd_portman_midi_output);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
- &snd_portman_midi_input);
-
- /* name substreams */
- /* output */
- list_for_each_entry(substream,
- &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams,
- list) {
- sprintf(substream->name,
- "Portman2x4 %d", substream->number+1);
- }
- /* input */
- list_for_each_entry(substream,
- &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams,
- list) {
- pm->midi_input[substream->number] = substream;
- sprintf(substream->name,
- "Portman2x4 %d", substream->number+1);
- }
-
- return err;
-}
-
-/*********************************************************************
- * parport stuff
- *********************************************************************/
-static void snd_portman_interrupt(void *userdata)
-{
- unsigned char midivalue = 0;
- struct portman *pm = ((struct snd_card*)userdata)->private_data;
-
- spin_lock(&pm->reg_lock);
-
- /* While any input data is waiting */
- while ((portman_read_status(pm) & INT_REQ) == INT_REQ) {
- /* If data available on channel 0,
- read it and stuff it into the queue. */
- if (portman_data_avail(pm, 0)) {
- /* Read Midi */
- midivalue = portman_read_midi(pm, 0);
- /* put midi into queue... */
- if (pm->mode[0] & PORTMAN2X4_MODE_INPUT_TRIGGERED)
- snd_rawmidi_receive(pm->midi_input[0],
- &midivalue, 1);
-
- }
- /* If data available on channel 1,
- read it and stuff it into the queue. */
- if (portman_data_avail(pm, 1)) {
- /* Read Midi */
- midivalue = portman_read_midi(pm, 1);
- /* put midi into queue... */
- if (pm->mode[1] & PORTMAN2X4_MODE_INPUT_TRIGGERED)
- snd_rawmidi_receive(pm->midi_input[1],
- &midivalue, 1);
- }
-
- }
-
- spin_unlock(&pm->reg_lock);
-}
-
-static int __devinit snd_portman_probe_port(struct parport *p)
-{
- struct pardevice *pardev;
- int res;
-
- pardev = parport_register_device(p, DRIVER_NAME,
- NULL, NULL, NULL,
- 0, NULL);
- if (!pardev)
- return -EIO;
-
- if (parport_claim(pardev)) {
- parport_unregister_device(pardev);
- return -EIO;
- }
-
- res = portman_probe(p);
-
- parport_release(pardev);
- parport_unregister_device(pardev);
-
- return res ? -EIO : 0;
-}
-
-static void __devinit snd_portman_attach(struct parport *p)
-{
- struct platform_device *device;
-
- device = platform_device_alloc(PLATFORM_DRIVER, device_count);
- if (!device)
- return;
-
- /* Temporary assignment to forward the parport */
- platform_set_drvdata(device, p);
-
- if (platform_device_add(device) < 0) {
- platform_device_put(device);
- return;
- }
-
- /* Since we dont get the return value of probe
- * We need to check if device probing succeeded or not */
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- return;
- }
-
- /* register device in global table */
- platform_devices[device_count] = device;
- device_count++;
-}
-
-static void snd_portman_detach(struct parport *p)
-{
- /* nothing to do here */
-}
-
-static struct parport_driver portman_parport_driver = {
- .name = "portman2x4",
- .attach = snd_portman_attach,
- .detach = snd_portman_detach
-};
-
-/*********************************************************************
- * platform stuff
- *********************************************************************/
-static void snd_portman_card_private_free(struct snd_card *card)
-{
- struct portman *pm = card->private_data;
- struct pardevice *pardev = pm->pardev;
-
- if (pardev) {
- if (pm->pardev_claimed)
- parport_release(pardev);
- parport_unregister_device(pardev);
- }
-
- portman_free(pm);
-}
-
-static int __devinit snd_portman_probe(struct platform_device *pdev)
-{
- struct pardevice *pardev;
- struct parport *p;
- int dev = pdev->id;
- struct snd_card *card = NULL;
- struct portman *pm = NULL;
- int err;
-
- p = platform_get_drvdata(pdev);
- platform_set_drvdata(pdev, NULL);
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev])
- return -ENOENT;
-
- if ((err = snd_portman_probe_port(p)) < 0)
- return err;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0) {
- snd_printd("Cannot create card\n");
- return err;
- }
- strcpy(card->driver, DRIVER_NAME);
- strcpy(card->shortname, CARD_NAME);
- sprintf(card->longname, "%s at 0x%lx, irq %i",
- card->shortname, p->base, p->irq);
-
- pardev = parport_register_device(p, /* port */
- DRIVER_NAME, /* name */
- NULL, /* preempt */
- NULL, /* wakeup */
- snd_portman_interrupt, /* ISR */
- PARPORT_DEV_EXCL, /* flags */
- (void *)card); /* private */
- if (pardev == NULL) {
- snd_printd("Cannot register pardevice\n");
- err = -EIO;
- goto __err;
- }
-
- if ((err = portman_create(card, pardev, &pm)) < 0) {
- snd_printd("Cannot create main component\n");
- parport_unregister_device(pardev);
- goto __err;
- }
- card->private_data = pm;
- card->private_free = snd_portman_card_private_free;
-
- if ((err = snd_portman_rawmidi_create(card)) < 0) {
- snd_printd("Creating Rawmidi component failed\n");
- goto __err;
- }
-
- /* claim parport */
- if (parport_claim(pardev)) {
- snd_printd("Cannot claim parport 0x%lx\n", pardev->port->base);
- err = -EIO;
- goto __err;
- }
- pm->pardev_claimed = 1;
-
- /* init device */
- if ((err = portman_device_init(pm)) < 0)
- goto __err;
-
- platform_set_drvdata(pdev, card);
-
- snd_card_set_dev(card, &pdev->dev);
-
- /* At this point card will be usable */
- if ((err = snd_card_register(card)) < 0) {
- snd_printd("Cannot register card\n");
- goto __err;
- }
-
- snd_printk(KERN_INFO "Portman 2x4 on 0x%lx\n", p->base);
- return 0;
-
-__err:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit snd_portman_remove(struct platform_device *pdev)
-{
- struct snd_card *card = platform_get_drvdata(pdev);
-
- if (card)
- snd_card_free(card);
-
- return 0;
-}
-
-
-static struct platform_driver snd_portman_driver = {
- .probe = snd_portman_probe,
- .remove = __devexit_p(snd_portman_remove),
- .driver = {
- .name = PLATFORM_DRIVER
- }
-};
-
-/*********************************************************************
- * module init stuff
- *********************************************************************/
-static void snd_portman_unregister_all(void)
-{
- int i;
-
- for (i = 0; i < SNDRV_CARDS; ++i) {
- if (platform_devices[i]) {
- platform_device_unregister(platform_devices[i]);
- platform_devices[i] = NULL;
- }
- }
- platform_driver_unregister(&snd_portman_driver);
- parport_unregister_driver(&portman_parport_driver);
-}
-
-static int __init snd_portman_module_init(void)
-{
- int err;
-
- if ((err = platform_driver_register(&snd_portman_driver)) < 0)
- return err;
-
- if (parport_register_driver(&portman_parport_driver) != 0) {
- platform_driver_unregister(&snd_portman_driver);
- return -EIO;
- }
-
- if (device_count == 0) {
- snd_portman_unregister_all();
- return -ENODEV;
- }
-
- return 0;
-}
-
-static void __exit snd_portman_module_exit(void)
-{
- snd_portman_unregister_all();
-}
-
-module_init(snd_portman_module_init);
-module_exit(snd_portman_module_exit);
diff --git a/ANDROID_3.4.5/sound/drivers/serial-u16550.c b/ANDROID_3.4.5/sound/drivers/serial-u16550.c
deleted file mode 100644
index b2d0e8e4..00000000
--- a/ANDROID_3.4.5/sound/drivers/serial-u16550.c
+++ /dev/null
@@ -1,1050 +0,0 @@
-/*
- * serial.c
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
- * Isaku Yamahata <yamahata@private.email.ne.jp>,
- * George Hansper <ghansper@apana.org.au>,
- * Hannu Savolainen
- *
- * This code is based on the code from ALSA 0.5.9, but heavily rewritten.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Sat Mar 31 17:27:57 PST 2001 tim.mann@compaq.com
- * Added support for the Midiator MS-124T and for the MS-124W in
- * Single Addressed (S/A) or Multiple Burst (M/B) mode, with
- * power derived either parasitically from the serial port or
- * from a separate power supply.
- *
- * More documentation can be found in serial-u16550.txt.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/rawmidi.h>
-#include <sound/initval.h>
-
-#include <linux/serial_reg.h>
-#include <linux/jiffies.h>
-
-#include <asm/io.h>
-
-MODULE_DESCRIPTION("MIDI serial u16550");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ALSA, MIDI serial u16550}}");
-
-#define SNDRV_SERIAL_SOUNDCANVAS 0 /* Roland Soundcanvas; F5 NN selects part */
-#define SNDRV_SERIAL_MS124T 1 /* Midiator MS-124T */
-#define SNDRV_SERIAL_MS124W_SA 2 /* Midiator MS-124W in S/A mode */
-#define SNDRV_SERIAL_MS124W_MB 3 /* Midiator MS-124W in M/B mode */
-#define SNDRV_SERIAL_GENERIC 4 /* Generic Interface */
-#define SNDRV_SERIAL_MAX_ADAPTOR SNDRV_SERIAL_GENERIC
-static char *adaptor_names[] = {
- "Soundcanvas",
- "MS-124T",
- "MS-124W S/A",
- "MS-124W M/B",
- "Generic"
-};
-
-#define SNDRV_SERIAL_NORMALBUFF 0 /* Normal blocking buffer operation */
-#define SNDRV_SERIAL_DROPBUFF 1 /* Non-blocking discard operation */
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x3f8,0x2f8,0x3e8,0x2e8 */
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 3,4,5,7,9,10,11,14,15 */
-static int speed[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 38400}; /* 9600,19200,38400,57600,115200 */
-static int base[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 115200}; /* baud base */
-static int outs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; /* 1 to 16 */
-static int ins[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; /* 1 to 16 */
-static int adaptor[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = SNDRV_SERIAL_SOUNDCANVAS};
-static bool droponfull[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS -1)] = SNDRV_SERIAL_NORMALBUFF };
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Serial MIDI.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Serial MIDI.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable UART16550A chip.");
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for UART16550A chip.");
-module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for UART16550A chip.");
-module_param_array(speed, int, NULL, 0444);
-MODULE_PARM_DESC(speed, "Speed in bauds.");
-module_param_array(base, int, NULL, 0444);
-MODULE_PARM_DESC(base, "Base for divisor in bauds.");
-module_param_array(outs, int, NULL, 0444);
-MODULE_PARM_DESC(outs, "Number of MIDI outputs.");
-module_param_array(ins, int, NULL, 0444);
-MODULE_PARM_DESC(ins, "Number of MIDI inputs.");
-module_param_array(droponfull, bool, NULL, 0444);
-MODULE_PARM_DESC(droponfull, "Flag to enable drop-on-full buffer mode");
-
-module_param_array(adaptor, int, NULL, 0444);
-MODULE_PARM_DESC(adaptor, "Type of adaptor.");
-
-/*#define SNDRV_SERIAL_MS124W_MB_NOCOMBO 1*/ /* Address outs as 0-3 instead of bitmap */
-
-#define SNDRV_SERIAL_MAX_OUTS 16 /* max 64, min 16 */
-#define SNDRV_SERIAL_MAX_INS 16 /* max 64, min 16 */
-
-#define TX_BUFF_SIZE (1<<15) /* Must be 2^n */
-#define TX_BUFF_MASK (TX_BUFF_SIZE - 1)
-
-#define SERIAL_MODE_NOT_OPENED (0)
-#define SERIAL_MODE_INPUT_OPEN (1 << 0)
-#define SERIAL_MODE_OUTPUT_OPEN (1 << 1)
-#define SERIAL_MODE_INPUT_TRIGGERED (1 << 2)
-#define SERIAL_MODE_OUTPUT_TRIGGERED (1 << 3)
-
-struct snd_uart16550 {
- struct snd_card *card;
- struct snd_rawmidi *rmidi;
- struct snd_rawmidi_substream *midi_output[SNDRV_SERIAL_MAX_OUTS];
- struct snd_rawmidi_substream *midi_input[SNDRV_SERIAL_MAX_INS];
-
- int filemode; /* open status of file */
-
- spinlock_t open_lock;
-
- int irq;
-
- unsigned long base;
- struct resource *res_base;
-
- unsigned int speed;
- unsigned int speed_base;
- unsigned char divisor;
-
- unsigned char old_divisor_lsb;
- unsigned char old_divisor_msb;
- unsigned char old_line_ctrl_reg;
-
- /* parameter for using of write loop */
- short int fifo_limit; /* used in uart16550 */
- short int fifo_count; /* used in uart16550 */
-
- /* type of adaptor */
- int adaptor;
-
- /* inputs */
- int prev_in;
- unsigned char rstatus;
-
- /* outputs */
- int prev_out;
- unsigned char prev_status[SNDRV_SERIAL_MAX_OUTS];
-
- /* write buffer and its writing/reading position */
- unsigned char tx_buff[TX_BUFF_SIZE];
- int buff_in_count;
- int buff_in;
- int buff_out;
- int drop_on_full;
-
- /* wait timer */
- unsigned int timer_running:1;
- struct timer_list buffer_timer;
-
-};
-
-static struct platform_device *devices[SNDRV_CARDS];
-
-static inline void snd_uart16550_add_timer(struct snd_uart16550 *uart)
-{
- if (!uart->timer_running) {
- /* timer 38600bps * 10bit * 16byte */
- uart->buffer_timer.expires = jiffies + (HZ+255)/256;
- uart->timer_running = 1;
- add_timer(&uart->buffer_timer);
- }
-}
-
-static inline void snd_uart16550_del_timer(struct snd_uart16550 *uart)
-{
- if (uart->timer_running) {
- del_timer(&uart->buffer_timer);
- uart->timer_running = 0;
- }
-}
-
-/* This macro is only used in snd_uart16550_io_loop */
-static inline void snd_uart16550_buffer_output(struct snd_uart16550 *uart)
-{
- unsigned short buff_out = uart->buff_out;
- if (uart->buff_in_count > 0) {
- outb(uart->tx_buff[buff_out], uart->base + UART_TX);
- uart->fifo_count++;
- buff_out++;
- buff_out &= TX_BUFF_MASK;
- uart->buff_out = buff_out;
- uart->buff_in_count--;
- }
-}
-
-/* This loop should be called with interrupts disabled
- * We don't want to interrupt this,
- * as we're already handling an interrupt
- */
-static void snd_uart16550_io_loop(struct snd_uart16550 * uart)
-{
- unsigned char c, status;
- int substream;
-
- /* recall previous stream */
- substream = uart->prev_in;
-
- /* Read Loop */
- while ((status = inb(uart->base + UART_LSR)) & UART_LSR_DR) {
- /* while receive data ready */
- c = inb(uart->base + UART_RX);
-
- /* keep track of last status byte */
- if (c & 0x80)
- uart->rstatus = c;
-
- /* handle stream switch */
- if (uart->adaptor == SNDRV_SERIAL_GENERIC) {
- if (uart->rstatus == 0xf5) {
- if (c <= SNDRV_SERIAL_MAX_INS && c > 0)
- substream = c - 1;
- if (c != 0xf5)
- /* prevent future bytes from being
- interpreted as streams */
- uart->rstatus = 0;
- } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN)
- && uart->midi_input[substream])
- snd_rawmidi_receive(uart->midi_input[substream],
- &c, 1);
- } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) &&
- uart->midi_input[substream])
- snd_rawmidi_receive(uart->midi_input[substream], &c, 1);
-
- if (status & UART_LSR_OE)
- snd_printk(KERN_WARNING
- "%s: Overrun on device at 0x%lx\n",
- uart->rmidi->name, uart->base);
- }
-
- /* remember the last stream */
- uart->prev_in = substream;
-
- /* no need of check SERIAL_MODE_OUTPUT_OPEN because if not,
- buffer is never filled. */
- /* Check write status */
- if (status & UART_LSR_THRE)
- uart->fifo_count = 0;
- if (uart->adaptor == SNDRV_SERIAL_MS124W_SA
- || uart->adaptor == SNDRV_SERIAL_GENERIC) {
- /* Can't use FIFO, must send only when CTS is true */
- status = inb(uart->base + UART_MSR);
- while (uart->fifo_count == 0 && (status & UART_MSR_CTS) &&
- uart->buff_in_count > 0) {
- snd_uart16550_buffer_output(uart);
- status = inb(uart->base + UART_MSR);
- }
- } else {
- /* Write loop */
- while (uart->fifo_count < uart->fifo_limit /* Can we write ? */
- && uart->buff_in_count > 0) /* Do we want to? */
- snd_uart16550_buffer_output(uart);
- }
- if (uart->irq < 0 && uart->buff_in_count > 0)
- snd_uart16550_add_timer(uart);
-}
-
-/* NOTES ON SERVICING INTERUPTS
- * ---------------------------
- * After receiving a interrupt, it is important to indicate to the UART that
- * this has been done.
- * For a Rx interrupt, this is done by reading the received byte.
- * For a Tx interrupt this is done by either:
- * a) Writing a byte
- * b) Reading the IIR
- * It is particularly important to read the IIR if a Tx interrupt is received
- * when there is no data in tx_buff[], as in this case there no other
- * indication that the interrupt has been serviced, and it remains outstanding
- * indefinitely. This has the curious side effect that and no further interrupts
- * will be generated from this device AT ALL!!.
- * It is also desirable to clear outstanding interrupts when the device is
- * opened/closed.
- *
- *
- * Note that some devices need OUT2 to be set before they will generate
- * interrupts at all. (Possibly tied to an internal pull-up on CTS?)
- */
-static irqreturn_t snd_uart16550_interrupt(int irq, void *dev_id)
-{
- struct snd_uart16550 *uart;
-
- uart = dev_id;
- spin_lock(&uart->open_lock);
- if (uart->filemode == SERIAL_MODE_NOT_OPENED) {
- spin_unlock(&uart->open_lock);
- return IRQ_NONE;
- }
- /* indicate to the UART that the interrupt has been serviced */
- inb(uart->base + UART_IIR);
- snd_uart16550_io_loop(uart);
- spin_unlock(&uart->open_lock);
- return IRQ_HANDLED;
-}
-
-/* When the polling mode, this function calls snd_uart16550_io_loop. */
-static void snd_uart16550_buffer_timer(unsigned long data)
-{
- unsigned long flags;
- struct snd_uart16550 *uart;
-
- uart = (struct snd_uart16550 *)data;
- spin_lock_irqsave(&uart->open_lock, flags);
- snd_uart16550_del_timer(uart);
- snd_uart16550_io_loop(uart);
- spin_unlock_irqrestore(&uart->open_lock, flags);
-}
-
-/*
- * this method probes, if an uart sits on given port
- * return 0 if found
- * return negative error if not found
- */
-static int __devinit snd_uart16550_detect(struct snd_uart16550 *uart)
-{
- unsigned long io_base = uart->base;
- int ok;
- unsigned char c;
-
- /* Do some vague tests for the presence of the uart */
- if (io_base == 0 || io_base == SNDRV_AUTO_PORT) {
- return -ENODEV; /* Not configured */
- }
-
- uart->res_base = request_region(io_base, 8, "Serial MIDI");
- if (uart->res_base == NULL) {
- snd_printk(KERN_ERR "u16550: can't grab port 0x%lx\n", io_base);
- return -EBUSY;
- }
-
- /* uart detected unless one of the following tests should fail */
- ok = 1;
- /* 8 data-bits, 1 stop-bit, parity off, DLAB = 0 */
- outb(UART_LCR_WLEN8, io_base + UART_LCR); /* Line Control Register */
- c = inb(io_base + UART_IER);
- /* The top four bits of the IER should always == 0 */
- if ((c & 0xf0) != 0)
- ok = 0; /* failed */
-
- outb(0xaa, io_base + UART_SCR);
- /* Write arbitrary data into the scratch reg */
- c = inb(io_base + UART_SCR);
- /* If it comes back, it's OK */
- if (c != 0xaa)
- ok = 0; /* failed */
-
- outb(0x55, io_base + UART_SCR);
- /* Write arbitrary data into the scratch reg */
- c = inb(io_base + UART_SCR);
- /* If it comes back, it's OK */
- if (c != 0x55)
- ok = 0; /* failed */
-
- return ok;
-}
-
-static void snd_uart16550_do_open(struct snd_uart16550 * uart)
-{
- char byte;
-
- /* Initialize basic variables */
- uart->buff_in_count = 0;
- uart->buff_in = 0;
- uart->buff_out = 0;
- uart->fifo_limit = 1;
- uart->fifo_count = 0;
- uart->timer_running = 0;
-
- outb(UART_FCR_ENABLE_FIFO /* Enable FIFO's (if available) */
- | UART_FCR_CLEAR_RCVR /* Clear receiver FIFO */
- | UART_FCR_CLEAR_XMIT /* Clear transmitter FIFO */
- | UART_FCR_TRIGGER_4 /* Set FIFO trigger at 4-bytes */
- /* NOTE: interrupt generated after T=(time)4-bytes
- * if less than UART_FCR_TRIGGER bytes received
- */
- ,uart->base + UART_FCR); /* FIFO Control Register */
-
- if ((inb(uart->base + UART_IIR) & 0xf0) == 0xc0)
- uart->fifo_limit = 16;
- if (uart->divisor != 0) {
- uart->old_line_ctrl_reg = inb(uart->base + UART_LCR);
- outb(UART_LCR_DLAB /* Divisor latch access bit */
- ,uart->base + UART_LCR); /* Line Control Register */
- uart->old_divisor_lsb = inb(uart->base + UART_DLL);
- uart->old_divisor_msb = inb(uart->base + UART_DLM);
-
- outb(uart->divisor
- ,uart->base + UART_DLL); /* Divisor Latch Low */
- outb(0
- ,uart->base + UART_DLM); /* Divisor Latch High */
- /* DLAB is reset to 0 in next outb() */
- }
- /* Set serial parameters (parity off, etc) */
- outb(UART_LCR_WLEN8 /* 8 data-bits */
- | 0 /* 1 stop-bit */
- | 0 /* parity off */
- | 0 /* DLAB = 0 */
- ,uart->base + UART_LCR); /* Line Control Register */
-
- switch (uart->adaptor) {
- default:
- outb(UART_MCR_RTS /* Set Request-To-Send line active */
- | UART_MCR_DTR /* Set Data-Terminal-Ready line active */
- | UART_MCR_OUT2 /* Set OUT2 - not always required, but when
- * it is, it is ESSENTIAL for enabling interrupts
- */
- ,uart->base + UART_MCR); /* Modem Control Register */
- break;
- case SNDRV_SERIAL_MS124W_SA:
- case SNDRV_SERIAL_MS124W_MB:
- /* MS-124W can draw power from RTS and DTR if they
- are in opposite states. */
- outb(UART_MCR_RTS | (0&UART_MCR_DTR) | UART_MCR_OUT2,
- uart->base + UART_MCR);
- break;
- case SNDRV_SERIAL_MS124T:
- /* MS-124T can draw power from RTS and/or DTR (preferably
- both) if they are both asserted. */
- outb(UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2,
- uart->base + UART_MCR);
- break;
- }
-
- if (uart->irq < 0) {
- byte = (0 & UART_IER_RDI) /* Disable Receiver data interrupt */
- |(0 & UART_IER_THRI) /* Disable Transmitter holding register empty interrupt */
- ;
- } else if (uart->adaptor == SNDRV_SERIAL_MS124W_SA) {
- byte = UART_IER_RDI /* Enable Receiver data interrupt */
- | UART_IER_MSI /* Enable Modem status interrupt */
- ;
- } else if (uart->adaptor == SNDRV_SERIAL_GENERIC) {
- byte = UART_IER_RDI /* Enable Receiver data interrupt */
- | UART_IER_MSI /* Enable Modem status interrupt */
- | UART_IER_THRI /* Enable Transmitter holding register empty interrupt */
- ;
- } else {
- byte = UART_IER_RDI /* Enable Receiver data interrupt */
- | UART_IER_THRI /* Enable Transmitter holding register empty interrupt */
- ;
- }
- outb(byte, uart->base + UART_IER); /* Interrupt enable Register */
-
- inb(uart->base + UART_LSR); /* Clear any pre-existing overrun indication */
- inb(uart->base + UART_IIR); /* Clear any pre-existing transmit interrupt */
- inb(uart->base + UART_RX); /* Clear any pre-existing receive interrupt */
-}
-
-static void snd_uart16550_do_close(struct snd_uart16550 * uart)
-{
- if (uart->irq < 0)
- snd_uart16550_del_timer(uart);
-
- /* NOTE: may need to disable interrupts before de-registering out handler.
- * For now, the consequences are harmless.
- */
-
- outb((0 & UART_IER_RDI) /* Disable Receiver data interrupt */
- |(0 & UART_IER_THRI) /* Disable Transmitter holding register empty interrupt */
- ,uart->base + UART_IER); /* Interrupt enable Register */
-
- switch (uart->adaptor) {
- default:
- outb((0 & UART_MCR_RTS) /* Deactivate Request-To-Send line */
- |(0 & UART_MCR_DTR) /* Deactivate Data-Terminal-Ready line */
- |(0 & UART_MCR_OUT2) /* Deactivate OUT2 */
- ,uart->base + UART_MCR); /* Modem Control Register */
- break;
- case SNDRV_SERIAL_MS124W_SA:
- case SNDRV_SERIAL_MS124W_MB:
- /* MS-124W can draw power from RTS and DTR if they
- are in opposite states; leave it powered. */
- outb(UART_MCR_RTS | (0&UART_MCR_DTR) | (0&UART_MCR_OUT2),
- uart->base + UART_MCR);
- break;
- case SNDRV_SERIAL_MS124T:
- /* MS-124T can draw power from RTS and/or DTR (preferably
- both) if they are both asserted; leave it powered. */
- outb(UART_MCR_RTS | UART_MCR_DTR | (0&UART_MCR_OUT2),
- uart->base + UART_MCR);
- break;
- }
-
- inb(uart->base + UART_IIR); /* Clear any outstanding interrupts */
-
- /* Restore old divisor */
- if (uart->divisor != 0) {
- outb(UART_LCR_DLAB /* Divisor latch access bit */
- ,uart->base + UART_LCR); /* Line Control Register */
- outb(uart->old_divisor_lsb
- ,uart->base + UART_DLL); /* Divisor Latch Low */
- outb(uart->old_divisor_msb
- ,uart->base + UART_DLM); /* Divisor Latch High */
- /* Restore old LCR (data bits, stop bits, parity, DLAB) */
- outb(uart->old_line_ctrl_reg
- ,uart->base + UART_LCR); /* Line Control Register */
- }
-}
-
-static int snd_uart16550_input_open(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- struct snd_uart16550 *uart = substream->rmidi->private_data;
-
- spin_lock_irqsave(&uart->open_lock, flags);
- if (uart->filemode == SERIAL_MODE_NOT_OPENED)
- snd_uart16550_do_open(uart);
- uart->filemode |= SERIAL_MODE_INPUT_OPEN;
- uart->midi_input[substream->number] = substream;
- spin_unlock_irqrestore(&uart->open_lock, flags);
- return 0;
-}
-
-static int snd_uart16550_input_close(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- struct snd_uart16550 *uart = substream->rmidi->private_data;
-
- spin_lock_irqsave(&uart->open_lock, flags);
- uart->filemode &= ~SERIAL_MODE_INPUT_OPEN;
- uart->midi_input[substream->number] = NULL;
- if (uart->filemode == SERIAL_MODE_NOT_OPENED)
- snd_uart16550_do_close(uart);
- spin_unlock_irqrestore(&uart->open_lock, flags);
- return 0;
-}
-
-static void snd_uart16550_input_trigger(struct snd_rawmidi_substream *substream,
- int up)
-{
- unsigned long flags;
- struct snd_uart16550 *uart = substream->rmidi->private_data;
-
- spin_lock_irqsave(&uart->open_lock, flags);
- if (up)
- uart->filemode |= SERIAL_MODE_INPUT_TRIGGERED;
- else
- uart->filemode &= ~SERIAL_MODE_INPUT_TRIGGERED;
- spin_unlock_irqrestore(&uart->open_lock, flags);
-}
-
-static int snd_uart16550_output_open(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- struct snd_uart16550 *uart = substream->rmidi->private_data;
-
- spin_lock_irqsave(&uart->open_lock, flags);
- if (uart->filemode == SERIAL_MODE_NOT_OPENED)
- snd_uart16550_do_open(uart);
- uart->filemode |= SERIAL_MODE_OUTPUT_OPEN;
- uart->midi_output[substream->number] = substream;
- spin_unlock_irqrestore(&uart->open_lock, flags);
- return 0;
-};
-
-static int snd_uart16550_output_close(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- struct snd_uart16550 *uart = substream->rmidi->private_data;
-
- spin_lock_irqsave(&uart->open_lock, flags);
- uart->filemode &= ~SERIAL_MODE_OUTPUT_OPEN;
- uart->midi_output[substream->number] = NULL;
- if (uart->filemode == SERIAL_MODE_NOT_OPENED)
- snd_uart16550_do_close(uart);
- spin_unlock_irqrestore(&uart->open_lock, flags);
- return 0;
-};
-
-static inline int snd_uart16550_buffer_can_write(struct snd_uart16550 *uart,
- int Num)
-{
- if (uart->buff_in_count + Num < TX_BUFF_SIZE)
- return 1;
- else
- return 0;
-}
-
-static inline int snd_uart16550_write_buffer(struct snd_uart16550 *uart,
- unsigned char byte)
-{
- unsigned short buff_in = uart->buff_in;
- if (uart->buff_in_count < TX_BUFF_SIZE) {
- uart->tx_buff[buff_in] = byte;
- buff_in++;
- buff_in &= TX_BUFF_MASK;
- uart->buff_in = buff_in;
- uart->buff_in_count++;
- if (uart->irq < 0) /* polling mode */
- snd_uart16550_add_timer(uart);
- return 1;
- } else
- return 0;
-}
-
-static int snd_uart16550_output_byte(struct snd_uart16550 *uart,
- struct snd_rawmidi_substream *substream,
- unsigned char midi_byte)
-{
- if (uart->buff_in_count == 0 /* Buffer empty? */
- && ((uart->adaptor != SNDRV_SERIAL_MS124W_SA &&
- uart->adaptor != SNDRV_SERIAL_GENERIC) ||
- (uart->fifo_count == 0 /* FIFO empty? */
- && (inb(uart->base + UART_MSR) & UART_MSR_CTS)))) { /* CTS? */
-
- /* Tx Buffer Empty - try to write immediately */
- if ((inb(uart->base + UART_LSR) & UART_LSR_THRE) != 0) {
- /* Transmitter holding register (and Tx FIFO) empty */
- uart->fifo_count = 1;
- outb(midi_byte, uart->base + UART_TX);
- } else {
- if (uart->fifo_count < uart->fifo_limit) {
- uart->fifo_count++;
- outb(midi_byte, uart->base + UART_TX);
- } else {
- /* Cannot write (buffer empty) -
- * put char in buffer */
- snd_uart16550_write_buffer(uart, midi_byte);
- }
- }
- } else {
- if (!snd_uart16550_write_buffer(uart, midi_byte)) {
- snd_printk(KERN_WARNING
- "%s: Buffer overrun on device at 0x%lx\n",
- uart->rmidi->name, uart->base);
- return 0;
- }
- }
-
- return 1;
-}
-
-static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- unsigned char midi_byte, addr_byte;
- struct snd_uart16550 *uart = substream->rmidi->private_data;
- char first;
- static unsigned long lasttime = 0;
-
- /* Interrupts are disabled during the updating of the tx_buff,
- * since it is 'bad' to have two processes updating the same
- * variables (ie buff_in & buff_out)
- */
-
- spin_lock_irqsave(&uart->open_lock, flags);
-
- if (uart->irq < 0) /* polling */
- snd_uart16550_io_loop(uart);
-
- if (uart->adaptor == SNDRV_SERIAL_MS124W_MB) {
- while (1) {
- /* buffer full? */
- /* in this mode we need two bytes of space */
- if (uart->buff_in_count > TX_BUFF_SIZE - 2)
- break;
- if (snd_rawmidi_transmit(substream, &midi_byte, 1) != 1)
- break;
-#ifdef SNDRV_SERIAL_MS124W_MB_NOCOMBO
- /* select exactly one of the four ports */
- addr_byte = (1 << (substream->number + 4)) | 0x08;
-#else
- /* select any combination of the four ports */
- addr_byte = (substream->number << 4) | 0x08;
- /* ...except none */
- if (addr_byte == 0x08)
- addr_byte = 0xf8;
-#endif
- snd_uart16550_output_byte(uart, substream, addr_byte);
- /* send midi byte */
- snd_uart16550_output_byte(uart, substream, midi_byte);
- }
- } else {
- first = 0;
- while (snd_rawmidi_transmit_peek(substream, &midi_byte, 1) == 1) {
- /* Also send F5 after 3 seconds with no data
- * to handle device disconnect */
- if (first == 0 &&
- (uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS ||
- uart->adaptor == SNDRV_SERIAL_GENERIC) &&
- (uart->prev_out != substream->number ||
- time_after(jiffies, lasttime + 3*HZ))) {
-
- if (snd_uart16550_buffer_can_write(uart, 3)) {
- /* Roland Soundcanvas part selection */
- /* If this substream of the data is
- * different previous substream
- * in this uart, send the change part
- * event
- */
- uart->prev_out = substream->number;
- /* change part */
- snd_uart16550_output_byte(uart, substream,
- 0xf5);
- /* data */
- snd_uart16550_output_byte(uart, substream,
- uart->prev_out + 1);
- /* If midi_byte is a data byte,
- * send the previous status byte */
- if (midi_byte < 0x80 &&
- uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS)
- snd_uart16550_output_byte(uart, substream, uart->prev_status[uart->prev_out]);
- } else if (!uart->drop_on_full)
- break;
-
- }
-
- /* send midi byte */
- if (!snd_uart16550_output_byte(uart, substream, midi_byte) &&
- !uart->drop_on_full )
- break;
-
- if (midi_byte >= 0x80 && midi_byte < 0xf0)
- uart->prev_status[uart->prev_out] = midi_byte;
- first = 1;
-
- snd_rawmidi_transmit_ack( substream, 1 );
- }
- lasttime = jiffies;
- }
- spin_unlock_irqrestore(&uart->open_lock, flags);
-}
-
-static void snd_uart16550_output_trigger(struct snd_rawmidi_substream *substream,
- int up)
-{
- unsigned long flags;
- struct snd_uart16550 *uart = substream->rmidi->private_data;
-
- spin_lock_irqsave(&uart->open_lock, flags);
- if (up)
- uart->filemode |= SERIAL_MODE_OUTPUT_TRIGGERED;
- else
- uart->filemode &= ~SERIAL_MODE_OUTPUT_TRIGGERED;
- spin_unlock_irqrestore(&uart->open_lock, flags);
- if (up)
- snd_uart16550_output_write(substream);
-}
-
-static struct snd_rawmidi_ops snd_uart16550_output =
-{
- .open = snd_uart16550_output_open,
- .close = snd_uart16550_output_close,
- .trigger = snd_uart16550_output_trigger,
-};
-
-static struct snd_rawmidi_ops snd_uart16550_input =
-{
- .open = snd_uart16550_input_open,
- .close = snd_uart16550_input_close,
- .trigger = snd_uart16550_input_trigger,
-};
-
-static int snd_uart16550_free(struct snd_uart16550 *uart)
-{
- if (uart->irq >= 0)
- free_irq(uart->irq, uart);
- release_and_free_resource(uart->res_base);
- kfree(uart);
- return 0;
-};
-
-static int snd_uart16550_dev_free(struct snd_device *device)
-{
- struct snd_uart16550 *uart = device->device_data;
- return snd_uart16550_free(uart);
-}
-
-static int __devinit snd_uart16550_create(struct snd_card *card,
- unsigned long iobase,
- int irq,
- unsigned int speed,
- unsigned int base,
- int adaptor,
- int droponfull,
- struct snd_uart16550 **ruart)
-{
- static struct snd_device_ops ops = {
- .dev_free = snd_uart16550_dev_free,
- };
- struct snd_uart16550 *uart;
- int err;
-
-
- if ((uart = kzalloc(sizeof(*uart), GFP_KERNEL)) == NULL)
- return -ENOMEM;
- uart->adaptor = adaptor;
- uart->card = card;
- spin_lock_init(&uart->open_lock);
- uart->irq = -1;
- uart->base = iobase;
- uart->drop_on_full = droponfull;
-
- if ((err = snd_uart16550_detect(uart)) <= 0) {
- printk(KERN_ERR "no UART detected at 0x%lx\n", iobase);
- snd_uart16550_free(uart);
- return -ENODEV;
- }
-
- if (irq >= 0 && irq != SNDRV_AUTO_IRQ) {
- if (request_irq(irq, snd_uart16550_interrupt,
- 0, "Serial MIDI", uart)) {
- snd_printk(KERN_WARNING
- "irq %d busy. Using Polling.\n", irq);
- } else {
- uart->irq = irq;
- }
- }
- uart->divisor = base / speed;
- uart->speed = base / (unsigned int)uart->divisor;
- uart->speed_base = base;
- uart->prev_out = -1;
- uart->prev_in = 0;
- uart->rstatus = 0;
- memset(uart->prev_status, 0x80, sizeof(unsigned char) * SNDRV_SERIAL_MAX_OUTS);
- init_timer(&uart->buffer_timer);
- uart->buffer_timer.function = snd_uart16550_buffer_timer;
- uart->buffer_timer.data = (unsigned long)uart;
- uart->timer_running = 0;
-
- /* Register device */
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, uart, &ops)) < 0) {
- snd_uart16550_free(uart);
- return err;
- }
-
- switch (uart->adaptor) {
- case SNDRV_SERIAL_MS124W_SA:
- case SNDRV_SERIAL_MS124W_MB:
- /* MS-124W can draw power from RTS and DTR if they
- are in opposite states. */
- outb(UART_MCR_RTS | (0&UART_MCR_DTR), uart->base + UART_MCR);
- break;
- case SNDRV_SERIAL_MS124T:
- /* MS-124T can draw power from RTS and/or DTR (preferably
- both) if they are asserted. */
- outb(UART_MCR_RTS | UART_MCR_DTR, uart->base + UART_MCR);
- break;
- default:
- break;
- }
-
- if (ruart)
- *ruart = uart;
-
- return 0;
-}
-
-static void __devinit snd_uart16550_substreams(struct snd_rawmidi_str *stream)
-{
- struct snd_rawmidi_substream *substream;
-
- list_for_each_entry(substream, &stream->substreams, list) {
- sprintf(substream->name, "Serial MIDI %d", substream->number + 1);
- }
-}
-
-static int __devinit snd_uart16550_rmidi(struct snd_uart16550 *uart, int device,
- int outs, int ins,
- struct snd_rawmidi **rmidi)
-{
- struct snd_rawmidi *rrawmidi;
- int err;
-
- err = snd_rawmidi_new(uart->card, "UART Serial MIDI", device,
- outs, ins, &rrawmidi);
- if (err < 0)
- return err;
- snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_INPUT,
- &snd_uart16550_input);
- snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
- &snd_uart16550_output);
- strcpy(rrawmidi->name, "Serial MIDI");
- snd_uart16550_substreams(&rrawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]);
- snd_uart16550_substreams(&rrawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]);
- rrawmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
- rrawmidi->private_data = uart;
- if (rmidi)
- *rmidi = rrawmidi;
- return 0;
-}
-
-static int __devinit snd_serial_probe(struct platform_device *devptr)
-{
- struct snd_card *card;
- struct snd_uart16550 *uart;
- int err;
- int dev = devptr->id;
-
- switch (adaptor[dev]) {
- case SNDRV_SERIAL_SOUNDCANVAS:
- ins[dev] = 1;
- break;
- case SNDRV_SERIAL_MS124T:
- case SNDRV_SERIAL_MS124W_SA:
- outs[dev] = 1;
- ins[dev] = 1;
- break;
- case SNDRV_SERIAL_MS124W_MB:
- outs[dev] = 16;
- ins[dev] = 1;
- break;
- case SNDRV_SERIAL_GENERIC:
- break;
- default:
- snd_printk(KERN_ERR
- "Adaptor type is out of range 0-%d (%d)\n",
- SNDRV_SERIAL_MAX_ADAPTOR, adaptor[dev]);
- return -ENODEV;
- }
-
- if (outs[dev] < 1 || outs[dev] > SNDRV_SERIAL_MAX_OUTS) {
- snd_printk(KERN_ERR
- "Count of outputs is out of range 1-%d (%d)\n",
- SNDRV_SERIAL_MAX_OUTS, outs[dev]);
- return -ENODEV;
- }
-
- if (ins[dev] < 1 || ins[dev] > SNDRV_SERIAL_MAX_INS) {
- snd_printk(KERN_ERR
- "Count of inputs is out of range 1-%d (%d)\n",
- SNDRV_SERIAL_MAX_INS, ins[dev]);
- return -ENODEV;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- strcpy(card->driver, "Serial");
- strcpy(card->shortname, "Serial MIDI (UART16550A)");
-
- if ((err = snd_uart16550_create(card,
- port[dev],
- irq[dev],
- speed[dev],
- base[dev],
- adaptor[dev],
- droponfull[dev],
- &uart)) < 0)
- goto _err;
-
- err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi);
- if (err < 0)
- goto _err;
-
- sprintf(card->longname, "%s [%s] at %#lx, irq %d",
- card->shortname,
- adaptor_names[uart->adaptor],
- uart->base,
- uart->irq);
-
- snd_card_set_dev(card, &devptr->dev);
-
- if ((err = snd_card_register(card)) < 0)
- goto _err;
-
- platform_set_drvdata(devptr, card);
- return 0;
-
- _err:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit snd_serial_remove(struct platform_device *devptr)
-{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
- return 0;
-}
-
-#define SND_SERIAL_DRIVER "snd_serial_u16550"
-
-static struct platform_driver snd_serial_driver = {
- .probe = snd_serial_probe,
- .remove = __devexit_p( snd_serial_remove),
- .driver = {
- .name = SND_SERIAL_DRIVER
- },
-};
-
-static void snd_serial_unregister_all(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(devices); ++i)
- platform_device_unregister(devices[i]);
- platform_driver_unregister(&snd_serial_driver);
-}
-
-static int __init alsa_card_serial_init(void)
-{
- int i, cards, err;
-
- if ((err = platform_driver_register(&snd_serial_driver)) < 0)
- return err;
-
- cards = 0;
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i])
- continue;
- device = platform_device_register_simple(SND_SERIAL_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- devices[i] = device;
- cards++;
- }
- if (! cards) {
-#ifdef MODULE
- printk(KERN_ERR "serial midi soundcard not found or device busy\n");
-#endif
- snd_serial_unregister_all();
- return -ENODEV;
- }
- return 0;
-}
-
-static void __exit alsa_card_serial_exit(void)
-{
- snd_serial_unregister_all();
-}
-
-module_init(alsa_card_serial_init)
-module_exit(alsa_card_serial_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/virmidi.c b/ANDROID_3.4.5/sound/drivers/virmidi.c
deleted file mode 100644
index 9d97478a..00000000
--- a/ANDROID_3.4.5/sound/drivers/virmidi.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Dummy soundcard for virtual rawmidi devices
- *
- * Copyright (c) 2000 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- * VIRTUAL RAW MIDI DEVICE CARDS
- *
- * This dummy card contains up to 4 virtual rawmidi devices.
- * They are not real rawmidi devices but just associated with sequencer
- * clients, so that any input/output sources can be connected as a raw
- * MIDI device arbitrary.
- * Also, multiple access is allowed to a single rawmidi device.
- *
- * Typical usage is like following:
- * - Load snd-virmidi module.
- * # modprobe snd-virmidi index=2
- * Then, sequencer clients 72:0 to 75:0 will be created, which are
- * mapped from /dev/snd/midiC1D0 to /dev/snd/midiC1D3, respectively.
- *
- * - Connect input/output via aconnect.
- * % aconnect 64:0 72:0 # keyboard input redirection 64:0 -> 72:0
- * % aconnect 72:0 65:0 # output device redirection 72:0 -> 65:0
- *
- * - Run application using a midi device (eg. /dev/snd/midiC1D0)
- */
-
-#include <linux/init.h>
-#include <linux/wait.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/seq_kernel.h>
-#include <sound/seq_virmidi.h>
-#include <sound/initval.h>
-
-/* hack: OSS defines midi_devs, so undefine it (versioned symbols) */
-#undef midi_devs
-
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("Dummy soundcard for virtual rawmidi devices");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ALSA,Virtual rawmidi device}}");
-
-#define MAX_MIDI_DEVICES 4
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
-static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4};
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for virmidi soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for virmidi soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable this soundcard.");
-module_param_array(midi_devs, int, NULL, 0444);
-MODULE_PARM_DESC(midi_devs, "MIDI devices # (1-4)");
-
-struct snd_card_virmidi {
- struct snd_card *card;
- struct snd_rawmidi *midi[MAX_MIDI_DEVICES];
-};
-
-static struct platform_device *devices[SNDRV_CARDS];
-
-
-static int __devinit snd_virmidi_probe(struct platform_device *devptr)
-{
- struct snd_card *card;
- struct snd_card_virmidi *vmidi;
- int idx, err;
- int dev = devptr->id;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_card_virmidi), &card);
- if (err < 0)
- return err;
- vmidi = card->private_data;
- vmidi->card = card;
-
- if (midi_devs[dev] > MAX_MIDI_DEVICES) {
- snd_printk(KERN_WARNING
- "too much midi devices for virmidi %d: "
- "force to use %d\n", dev, MAX_MIDI_DEVICES);
- midi_devs[dev] = MAX_MIDI_DEVICES;
- }
- for (idx = 0; idx < midi_devs[dev]; idx++) {
- struct snd_rawmidi *rmidi;
- struct snd_virmidi_dev *rdev;
- if ((err = snd_virmidi_new(card, idx, &rmidi)) < 0)
- goto __nodev;
- rdev = rmidi->private_data;
- vmidi->midi[idx] = rmidi;
- strcpy(rmidi->name, "Virtual Raw MIDI");
- rdev->seq_mode = SNDRV_VIRMIDI_SEQ_DISPATCH;
- }
-
- strcpy(card->driver, "VirMIDI");
- strcpy(card->shortname, "VirMIDI");
- sprintf(card->longname, "Virtual MIDI Card %i", dev + 1);
-
- snd_card_set_dev(card, &devptr->dev);
-
- if ((err = snd_card_register(card)) == 0) {
- platform_set_drvdata(devptr, card);
- return 0;
- }
- __nodev:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit snd_virmidi_remove(struct platform_device *devptr)
-{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
- return 0;
-}
-
-#define SND_VIRMIDI_DRIVER "snd_virmidi"
-
-static struct platform_driver snd_virmidi_driver = {
- .probe = snd_virmidi_probe,
- .remove = __devexit_p(snd_virmidi_remove),
- .driver = {
- .name = SND_VIRMIDI_DRIVER
- },
-};
-
-static void snd_virmidi_unregister_all(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(devices); ++i)
- platform_device_unregister(devices[i]);
- platform_driver_unregister(&snd_virmidi_driver);
-}
-
-static int __init alsa_card_virmidi_init(void)
-{
- int i, cards, err;
-
- if ((err = platform_driver_register(&snd_virmidi_driver)) < 0)
- return err;
-
- cards = 0;
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i])
- continue;
- device = platform_device_register_simple(SND_VIRMIDI_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- devices[i] = device;
- cards++;
- }
- if (!cards) {
-#ifdef MODULE
- printk(KERN_ERR "Card-VirMIDI soundcard not found or device busy\n");
-#endif
- snd_virmidi_unregister_all();
- return -ENODEV;
- }
- return 0;
-}
-
-static void __exit alsa_card_virmidi_exit(void)
-{
- snd_virmidi_unregister_all();
-}
-
-module_init(alsa_card_virmidi_init)
-module_exit(alsa_card_virmidi_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/vx/Makefile b/ANDROID_3.4.5/sound/drivers/vx/Makefile
deleted file mode 100644
index 9a168a3c..00000000
--- a/ANDROID_3.4.5/sound/drivers/vx/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-vx-lib-objs := vx_core.o vx_hwdep.o vx_pcm.o vx_mixer.o vx_cmd.o vx_uer.o
-
-obj-$(CONFIG_SND_VX_LIB) += snd-vx-lib.o
diff --git a/ANDROID_3.4.5/sound/drivers/vx/vx_cmd.c b/ANDROID_3.4.5/sound/drivers/vx/vx_cmd.c
deleted file mode 100644
index 23f4857f..00000000
--- a/ANDROID_3.4.5/sound/drivers/vx/vx_cmd.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Driver for Digigram VX soundcards
- *
- * DSP commands
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/vx_core.h>
-#include "vx_cmd.h"
-
-/*
- * Array of DSP commands
- */
-static struct vx_cmd_info vx_dsp_cmds[] = {
-[CMD_VERSION] = { 0x010000, 2, RMH_SSIZE_FIXED, 1 },
-[CMD_SUPPORTED] = { 0x020000, 1, RMH_SSIZE_FIXED, 2 },
-[CMD_TEST_IT] = { 0x040000, 1, RMH_SSIZE_FIXED, 1 },
-[CMD_SEND_IRQA] = { 0x070001, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_IBL] = { 0x080000, 1, RMH_SSIZE_FIXED, 4 },
-[CMD_ASYNC] = { 0x0A0000, 1, RMH_SSIZE_ARG, 0 },
-[CMD_RES_PIPE] = { 0x400000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_FREE_PIPE] = { 0x410000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_CONF_PIPE] = { 0x42A101, 2, RMH_SSIZE_FIXED, 0 },
-[CMD_ABORT_CONF_PIPE] = { 0x42A100, 2, RMH_SSIZE_FIXED, 0 },
-[CMD_PARAM_OUTPUT_PIPE] = { 0x43A000, 2, RMH_SSIZE_FIXED, 0 },
-[CMD_STOP_PIPE] = { 0x470004, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_PIPE_STATE] = { 0x480000, 1, RMH_SSIZE_FIXED, 1 },
-[CMD_PIPE_SPL_COUNT] = { 0x49A000, 2, RMH_SSIZE_FIXED, 2 },
-[CMD_CAN_START_PIPE] = { 0x4b0000, 1, RMH_SSIZE_FIXED, 1 },
-[CMD_SIZE_HBUFFER] = { 0x4C0000, 1, RMH_SSIZE_FIXED, 1 },
-[CMD_START_STREAM] = { 0x80A000, 2, RMH_SSIZE_FIXED, 0 },
-[CMD_START_ONE_STREAM] = { 0x800000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_PAUSE_STREAM] = { 0x81A000, 2, RMH_SSIZE_FIXED, 0 },
-[CMD_PAUSE_ONE_STREAM] = { 0x810000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_STREAM_OUT_LEVEL_ADJUST] = { 0x828000, 2, RMH_SSIZE_FIXED, 0 },
-[CMD_STOP_STREAM] = { 0x830000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_FORMAT_STREAM_OUT] = { 0x868000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_FORMAT_STREAM_IN] = { 0x878800, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_GET_STREAM_STATE] = { 0x890001, 2, RMH_SSIZE_FIXED, 1 },
-[CMD_DROP_BYTES_AWAY] = { 0x8A8000, 2, RMH_SSIZE_FIXED, 0 },
-[CMD_GET_REMAINING_BYTES] = { 0x8D0800, 1, RMH_SSIZE_FIXED, 2 },
-[CMD_CONNECT_AUDIO] = { 0xC10000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_AUDIO_LEVEL_ADJUST] = { 0xC2A000, 3, RMH_SSIZE_FIXED, 0 },
-[CMD_AUDIO_VU_PIC_METER] = { 0xC3A003, 2, RMH_SSIZE_FIXED, 1 },
-[CMD_GET_AUDIO_LEVELS] = { 0xC4A000, 2, RMH_SSIZE_FIXED, 0 },
-[CMD_GET_NOTIFY_EVENT] = { 0x4D0000, 1, RMH_SSIZE_ARG, 0 },
-[CMD_INFO_NOTIFIED] = { 0x0B0000, 1, RMH_SSIZE_FIXED, 2 },
-[CMD_ACCESS_IO_FCT] = { 0x098000, 1, RMH_SSIZE_ARG, 0 },
-[CMD_STATUS_R_BUFFERS] = { 0x440000, 1, RMH_SSIZE_ARG, 0 },
-[CMD_UPDATE_R_BUFFERS] = { 0x848000, 4, RMH_SSIZE_FIXED, 0 },
-[CMD_LOAD_EFFECT_CONTEXT] = { 0x0c8000, 3, RMH_SSIZE_FIXED, 1 },
-[CMD_EFFECT_ONE_PIPE] = { 0x458000, 0, RMH_SSIZE_FIXED, 0 },
-[CMD_MODIFY_CLOCK] = { 0x0d0000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_STREAM1_OUT_SET_N_LEVELS] ={ 0x858000, 3, RMH_SSIZE_FIXED, 0 },
-[CMD_PURGE_STREAM_DCMDS] = { 0x8b8000, 3, RMH_SSIZE_FIXED, 0 },
-[CMD_NOTIFY_PIPE_TIME] = { 0x4e0000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_LOAD_EFFECT_CONTEXT_PACKET] = { 0x0c8000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_RELIC_R_BUFFER] = { 0x8e0800, 1, RMH_SSIZE_FIXED, 1 },
-[CMD_RESYNC_AUDIO_INPUTS] = { 0x0e0000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_NOTIFY_STREAM_TIME] = { 0x8f0000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_STREAM_SAMPLE_COUNT] = { 0x900000, 1, RMH_SSIZE_FIXED, 2 },
-[CMD_CONFIG_TIME_CODE] = { 0x050000, 2, RMH_SSIZE_FIXED, 0 },
-[CMD_GET_TIME_CODE] = { 0x060000, 1, RMH_SSIZE_FIXED, 5 },
-[CMD_MANAGE_SIGNAL] = { 0x0f0000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_PARAMETER_STREAM_OUT] = { 0x91A000, 3, RMH_SSIZE_FIXED, 0 },
-[CMD_READ_BOARD_FREQ] = { 0x030000, 1, RMH_SSIZE_FIXED, 2 },
-[CMD_GET_STREAM_LEVELS] = { 0x8c0000, 1, RMH_SSIZE_FIXED, 3 },
-[CMD_PURGE_PIPE_DCMDS] = { 0x4f8000, 3, RMH_SSIZE_FIXED, 0 },
-// [CMD_SET_STREAM_OUT_EFFECTS] = { 0x888000, 34, RMH_SSIZE_FIXED, 0 },
-// [CMD_GET_STREAM_OUT_EFFECTS] = { 0x928000, 2, RMH_SSIZE_FIXED, 32 },
-[CMD_CONNECT_MONITORING] = { 0xC00000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_STREAM2_OUT_SET_N_LEVELS] = { 0x938000, 3, RMH_SSIZE_FIXED, 0 },
-[CMD_CANCEL_R_BUFFERS] = { 0x948000, 4, RMH_SSIZE_FIXED, 0 },
-[CMD_NOTIFY_END_OF_BUFFER] = { 0x950000, 1, RMH_SSIZE_FIXED, 0 },
-[CMD_GET_STREAM_VU_METER] = { 0x95A000, 2, RMH_SSIZE_ARG, 0 },
-};
-
-/**
- * vx_init_rmh - initialize the RMH instance
- * @rmh: the rmh pointer to be initialized
- * @cmd: the rmh command to be set
- */
-void vx_init_rmh(struct vx_rmh *rmh, unsigned int cmd)
-{
- if (snd_BUG_ON(cmd >= CMD_LAST_INDEX))
- return;
- rmh->LgCmd = vx_dsp_cmds[cmd].length;
- rmh->LgStat = vx_dsp_cmds[cmd].st_length;
- rmh->DspStat = vx_dsp_cmds[cmd].st_type;
- rmh->Cmd[0] = vx_dsp_cmds[cmd].opcode;
-}
-
diff --git a/ANDROID_3.4.5/sound/drivers/vx/vx_cmd.h b/ANDROID_3.4.5/sound/drivers/vx/vx_cmd.h
deleted file mode 100644
index a85248ba..00000000
--- a/ANDROID_3.4.5/sound/drivers/vx/vx_cmd.h
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Driver for Digigram VX soundcards
- *
- * Definitions of DSP commands
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __VX_CMD_H
-#define __VX_CMD_H
-
-enum {
- CMD_VERSION,
- CMD_SUPPORTED,
- CMD_TEST_IT,
- CMD_SEND_IRQA,
- CMD_IBL,
- CMD_ASYNC,
- CMD_RES_PIPE,
- CMD_FREE_PIPE,
- CMD_CONF_PIPE,
- CMD_ABORT_CONF_PIPE,
- CMD_PARAM_OUTPUT_PIPE,
- CMD_STOP_PIPE,
- CMD_PIPE_STATE,
- CMD_PIPE_SPL_COUNT,
- CMD_CAN_START_PIPE,
- CMD_SIZE_HBUFFER,
- CMD_START_STREAM,
- CMD_START_ONE_STREAM,
- CMD_PAUSE_STREAM,
- CMD_PAUSE_ONE_STREAM,
- CMD_STREAM_OUT_LEVEL_ADJUST,
- CMD_STOP_STREAM,
- CMD_FORMAT_STREAM_OUT,
- CMD_FORMAT_STREAM_IN,
- CMD_GET_STREAM_STATE,
- CMD_DROP_BYTES_AWAY,
- CMD_GET_REMAINING_BYTES,
- CMD_CONNECT_AUDIO,
- CMD_AUDIO_LEVEL_ADJUST,
- CMD_AUDIO_VU_PIC_METER,
- CMD_GET_AUDIO_LEVELS,
- CMD_GET_NOTIFY_EVENT,
- CMD_INFO_NOTIFIED,
- CMD_ACCESS_IO_FCT,
- CMD_STATUS_R_BUFFERS,
- CMD_UPDATE_R_BUFFERS,
- CMD_LOAD_EFFECT_CONTEXT,
- CMD_EFFECT_ONE_PIPE,
- CMD_MODIFY_CLOCK,
- CMD_STREAM1_OUT_SET_N_LEVELS,
- CMD_PURGE_STREAM_DCMDS,
- CMD_NOTIFY_PIPE_TIME,
- CMD_LOAD_EFFECT_CONTEXT_PACKET,
- CMD_RELIC_R_BUFFER,
- CMD_RESYNC_AUDIO_INPUTS,
- CMD_NOTIFY_STREAM_TIME,
- CMD_STREAM_SAMPLE_COUNT,
- CMD_CONFIG_TIME_CODE,
- CMD_GET_TIME_CODE,
- CMD_MANAGE_SIGNAL,
- CMD_PARAMETER_STREAM_OUT,
- CMD_READ_BOARD_FREQ,
- CMD_GET_STREAM_LEVELS,
- CMD_PURGE_PIPE_DCMDS,
- // CMD_SET_STREAM_OUT_EFFECTS,
- // CMD_GET_STREAM_OUT_EFFECTS,
- CMD_CONNECT_MONITORING,
- CMD_STREAM2_OUT_SET_N_LEVELS,
- CMD_CANCEL_R_BUFFERS,
- CMD_NOTIFY_END_OF_BUFFER,
- CMD_GET_STREAM_VU_METER,
- CMD_LAST_INDEX
-};
-
-struct vx_cmd_info {
- unsigned int opcode; /* command word */
- int length; /* command length (in words) */
- int st_type; /* status type (RMH_SSIZE_XXX) */
- int st_length; /* fixed length */
-};
-
-/* Family and code op of some DSP requests. */
-#define CODE_OP_PIPE_TIME 0x004e0000
-#define CODE_OP_START_STREAM 0x00800000
-#define CODE_OP_PAUSE_STREAM 0x00810000
-#define CODE_OP_OUT_STREAM_LEVEL 0x00820000
-#define CODE_OP_UPDATE_R_BUFFERS 0x00840000
-#define CODE_OP_OUT_STREAM1_LEVEL_CURVE 0x00850000
-#define CODE_OP_OUT_STREAM2_LEVEL_CURVE 0x00930000
-#define CODE_OP_OUT_STREAM_FORMAT 0x00860000
-#define CODE_OP_STREAM_TIME 0x008f0000
-#define CODE_OP_OUT_STREAM_EXTRAPARAMETER 0x00910000
-#define CODE_OP_OUT_AUDIO_LEVEL 0x00c20000
-
-#define NOTIFY_LAST_COMMAND 0x00400000
-
-/* Values for a user delay */
-#define DC_DIFFERED_DELAY (1<<BIT_DIFFERED_COMMAND)
-#define DC_NOTIFY_DELAY (1<<BIT_NOTIFIED_COMMAND)
-#define DC_HBUFFER_DELAY (1<<BIT_TIME_RELATIVE_TO_BUFFER)
-#define DC_MULTIPLE_DELAY (1<<BIT_RESERVED)
-#define DC_STREAM_TIME_DELAY (1<<BIT_STREAM_TIME)
-#define DC_CANCELLED_DELAY (1<<BIT_CANCELLED_COMMAND)
-
-/* Values for tiDelayed field in TIME_INFO structure,
- * and for pbPause field in PLAY_BUFFER_INFO structure
- */
-#define BIT_DIFFERED_COMMAND 0
-#define BIT_NOTIFIED_COMMAND 1
-#define BIT_TIME_RELATIVE_TO_BUFFER 2
-#define BIT_RESERVED 3
-#define BIT_STREAM_TIME 4
-#define BIT_CANCELLED_COMMAND 5
-
-/* Access to the "Size" field of the response of the CMD_GET_NOTIFY_EVENT request. */
-#define GET_NOTIFY_EVENT_SIZE_FIELD_MASK 0x000000ff
-
-/* DSP commands general masks */
-#define OPCODE_MASK 0x00ff0000
-#define DSP_DIFFERED_COMMAND_MASK 0x0000C000
-
-/* Notifications (NOTIFY_INFO) */
-#define ALL_CMDS_NOTIFIED 0x0000 // reserved
-#define START_STREAM_NOTIFIED 0x0001
-#define PAUSE_STREAM_NOTIFIED 0x0002
-#define OUT_STREAM_LEVEL_NOTIFIED 0x0003
-#define OUT_STREAM_PARAMETER_NOTIFIED 0x0004 // left for backward compatibility
-#define OUT_STREAM_FORMAT_NOTIFIED 0x0004
-#define PIPE_TIME_NOTIFIED 0x0005
-#define OUT_AUDIO_LEVEL_NOTIFIED 0x0006
-#define OUT_STREAM_LEVEL_CURVE_NOTIFIED 0x0007
-#define STREAM_TIME_NOTIFIED 0x0008
-#define OUT_STREAM_EXTRAPARAMETER_NOTIFIED 0x0009
-#define UNKNOWN_COMMAND_NOTIFIED 0xffff
-
-/* Output pipe parameters setting */
-#define MASK_VALID_PIPE_MPEG_PARAM 0x000040
-#define MASK_VALID_PIPE_BACKWARD_PARAM 0x000020
-#define MASK_SET_PIPE_MPEG_PARAM 0x000002
-#define MASK_SET_PIPE_BACKWARD_PARAM 0x000001
-
-#define MASK_DSP_WORD 0x00FFFFFF
-#define MASK_ALL_STREAM 0x00FFFFFF
-#define MASK_DSP_WORD_LEVEL 0x000001FF
-#define MASK_FIRST_FIELD 0x0000001F
-#define FIELD_SIZE 5
-
-#define COMMAND_RECORD_MASK 0x000800
-
-/* PipeManagement definition bits (PIPE_DECL_INFO) */
-#define P_UNDERRUN_SKIP_SOUND_MASK 0x01
-#define P_PREPARE_FOR_MPEG3_MASK 0x02
-#define P_DO_NOT_RESET_ANALOG_LEVELS 0x04
-#define P_ALLOW_UNDER_ALLOCATION_MASK 0x08
-#define P_DATA_MODE_MASK 0x10
-#define P_ASIO_BUFFER_MANAGEMENT_MASK 0x20
-
-#define BIT_SKIP_SOUND 0x08 // bit 3
-#define BIT_DATA_MODE 0x10 // bit 4
-
-/* Bits in the CMD_MODIFY_CLOCK request. */
-#define CMD_MODIFY_CLOCK_FD_BIT 0x00000001
-#define CMD_MODIFY_CLOCK_T_BIT 0x00000002
-#define CMD_MODIFY_CLOCK_S_BIT 0x00000004
-
-/* Access to the results of the CMD_GET_TIME_CODE RMH. */
-#define TIME_CODE_V_MASK 0x00800000
-#define TIME_CODE_N_MASK 0x00400000
-#define TIME_CODE_B_MASK 0x00200000
-#define TIME_CODE_W_MASK 0x00100000
-
-/* Values for the CMD_MANAGE_SIGNAL RMH. */
-#define MANAGE_SIGNAL_TIME_CODE 0x01
-#define MANAGE_SIGNAL_MIDI 0x02
-
-/* Values for the CMD_CONFIG_TIME_CODE RMH. */
-#define CONFIG_TIME_CODE_CANCEL 0x00001000
-
-/* Mask to get only the effective time from the
- * high word out of the 2 returned by the DSP
- */
-#define PCX_TIME_HI_MASK 0x000fffff
-
-/* Values for setting a H-Buffer time */
-#define HBUFFER_TIME_HIGH 0x00200000
-#define HBUFFER_TIME_LOW 0x00000000
-
-#define NOTIFY_MASK_TIME_HIGH 0x00400000
-#define MULTIPLE_MASK_TIME_HIGH 0x00100000
-#define STREAM_MASK_TIME_HIGH 0x00800000
-
-
-/*
- *
- */
-void vx_init_rmh(struct vx_rmh *rmh, unsigned int cmd);
-
-/**
- * vx_send_pipe_cmd_params - fill first command word for pipe commands
- * @rmh: the rmh to be modified
- * @is_capture: 0 = playback, 1 = capture operation
- * @param1: first pipe-parameter
- * @param2: second pipe-parameter
- */
-static inline void vx_set_pipe_cmd_params(struct vx_rmh *rmh, int is_capture,
- int param1, int param2)
-{
- if (is_capture)
- rmh->Cmd[0] |= COMMAND_RECORD_MASK;
- rmh->Cmd[0] |= (((u32)param1 & MASK_FIRST_FIELD) << FIELD_SIZE) & MASK_DSP_WORD;
-
- if (param2)
- rmh->Cmd[0] |= ((u32)param2 & MASK_FIRST_FIELD) & MASK_DSP_WORD;
-
-}
-
-/**
- * vx_set_stream_cmd_params - fill first command word for stream commands
- * @rmh: the rmh to be modified
- * @is_capture: 0 = playback, 1 = capture operation
- * @pipe: the pipe index (zero-based)
- */
-static inline void vx_set_stream_cmd_params(struct vx_rmh *rmh, int is_capture, int pipe)
-{
- if (is_capture)
- rmh->Cmd[0] |= COMMAND_RECORD_MASK;
- rmh->Cmd[0] |= (((u32)pipe & MASK_FIRST_FIELD) << FIELD_SIZE) & MASK_DSP_WORD;
-}
-
-#endif /* __VX_CMD_H */
diff --git a/ANDROID_3.4.5/sound/drivers/vx/vx_core.c b/ANDROID_3.4.5/sound/drivers/vx/vx_core.c
deleted file mode 100644
index b8e51599..00000000
--- a/ANDROID_3.4.5/sound/drivers/vx/vx_core.c
+++ /dev/null
@@ -1,828 +0,0 @@
-/*
- * Driver for Digigram VX soundcards
- *
- * Hardware core part
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/asoundef.h>
-#include <sound/info.h>
-#include <asm/io.h>
-#include <sound/vx_core.h>
-#include "vx_cmd.h"
-
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("Common routines for Digigram VX drivers");
-MODULE_LICENSE("GPL");
-
-
-/*
- * vx_check_reg_bit - wait for the specified bit is set/reset on a register
- * @reg: register to check
- * @mask: bit mask
- * @bit: resultant bit to be checked
- * @time: time-out of loop in msec
- *
- * returns zero if a bit matches, or a negative error code.
- */
-int snd_vx_check_reg_bit(struct vx_core *chip, int reg, int mask, int bit, int time)
-{
- unsigned long end_time = jiffies + (time * HZ + 999) / 1000;
-#ifdef CONFIG_SND_DEBUG
- static char *reg_names[VX_REG_MAX] = {
- "ICR", "CVR", "ISR", "IVR", "RXH", "RXM", "RXL",
- "DMA", "CDSP", "RFREQ", "RUER/V2", "DATA", "MEMIRQ",
- "ACQ", "BIT0", "BIT1", "MIC0", "MIC1", "MIC2",
- "MIC3", "INTCSR", "CNTRL", "GPIOC",
- "LOFREQ", "HIFREQ", "CSUER", "RUER"
- };
-#endif
- do {
- if ((snd_vx_inb(chip, reg) & mask) == bit)
- return 0;
- //msleep(10);
- } while (time_after_eq(end_time, jiffies));
- snd_printd(KERN_DEBUG "vx_check_reg_bit: timeout, reg=%s, mask=0x%x, val=0x%x\n", reg_names[reg], mask, snd_vx_inb(chip, reg));
- return -EIO;
-}
-
-EXPORT_SYMBOL(snd_vx_check_reg_bit);
-
-/*
- * vx_send_irq_dsp - set command irq bit
- * @num: the requested IRQ type, IRQ_XXX
- *
- * this triggers the specified IRQ request
- * returns 0 if successful, or a negative error code.
- *
- */
-static int vx_send_irq_dsp(struct vx_core *chip, int num)
-{
- int nirq;
-
- /* wait for Hc = 0 */
- if (snd_vx_check_reg_bit(chip, VX_CVR, CVR_HC, 0, 200) < 0)
- return -EIO;
-
- nirq = num;
- if (vx_has_new_dsp(chip))
- nirq += VXP_IRQ_OFFSET;
- vx_outb(chip, CVR, (nirq >> 1) | CVR_HC);
- return 0;
-}
-
-
-/*
- * vx_reset_chk - reset CHK bit on ISR
- *
- * returns 0 if successful, or a negative error code.
- */
-static int vx_reset_chk(struct vx_core *chip)
-{
- /* Reset irq CHK */
- if (vx_send_irq_dsp(chip, IRQ_RESET_CHK) < 0)
- return -EIO;
- /* Wait until CHK = 0 */
- if (vx_check_isr(chip, ISR_CHK, 0, 200) < 0)
- return -EIO;
- return 0;
-}
-
-/*
- * vx_transfer_end - terminate message transfer
- * @cmd: IRQ message to send (IRQ_MESS_XXX_END)
- *
- * returns 0 if successful, or a negative error code.
- * the error code can be VX-specific, retrieved via vx_get_error().
- * NB: call with spinlock held!
- */
-static int vx_transfer_end(struct vx_core *chip, int cmd)
-{
- int err;
-
- if ((err = vx_reset_chk(chip)) < 0)
- return err;
-
- /* irq MESS_READ/WRITE_END */
- if ((err = vx_send_irq_dsp(chip, cmd)) < 0)
- return err;
-
- /* Wait CHK = 1 */
- if ((err = vx_wait_isr_bit(chip, ISR_CHK)) < 0)
- return err;
-
- /* If error, Read RX */
- if ((err = vx_inb(chip, ISR)) & ISR_ERR) {
- if ((err = vx_wait_for_rx_full(chip)) < 0) {
- snd_printd(KERN_DEBUG "transfer_end: error in rx_full\n");
- return err;
- }
- err = vx_inb(chip, RXH) << 16;
- err |= vx_inb(chip, RXM) << 8;
- err |= vx_inb(chip, RXL);
- snd_printd(KERN_DEBUG "transfer_end: error = 0x%x\n", err);
- return -(VX_ERR_MASK | err);
- }
- return 0;
-}
-
-/*
- * vx_read_status - return the status rmh
- * @rmh: rmh record to store the status
- *
- * returns 0 if successful, or a negative error code.
- * the error code can be VX-specific, retrieved via vx_get_error().
- * NB: call with spinlock held!
- */
-static int vx_read_status(struct vx_core *chip, struct vx_rmh *rmh)
-{
- int i, err, val, size;
-
- /* no read necessary? */
- if (rmh->DspStat == RMH_SSIZE_FIXED && rmh->LgStat == 0)
- return 0;
-
- /* Wait for RX full (with timeout protection)
- * The first word of status is in RX
- */
- err = vx_wait_for_rx_full(chip);
- if (err < 0)
- return err;
-
- /* Read RX */
- val = vx_inb(chip, RXH) << 16;
- val |= vx_inb(chip, RXM) << 8;
- val |= vx_inb(chip, RXL);
-
- /* If status given by DSP, let's decode its size */
- switch (rmh->DspStat) {
- case RMH_SSIZE_ARG:
- size = val & 0xff;
- rmh->Stat[0] = val & 0xffff00;
- rmh->LgStat = size + 1;
- break;
- case RMH_SSIZE_MASK:
- /* Let's count the arg numbers from a mask */
- rmh->Stat[0] = val;
- size = 0;
- while (val) {
- if (val & 0x01)
- size++;
- val >>= 1;
- }
- rmh->LgStat = size + 1;
- break;
- default:
- /* else retrieve the status length given by the driver */
- size = rmh->LgStat;
- rmh->Stat[0] = val; /* Val is the status 1st word */
- size--; /* hence adjust remaining length */
- break;
- }
-
- if (size < 1)
- return 0;
- if (snd_BUG_ON(size > SIZE_MAX_STATUS))
- return -EINVAL;
-
- for (i = 1; i <= size; i++) {
- /* trigger an irq MESS_WRITE_NEXT */
- err = vx_send_irq_dsp(chip, IRQ_MESS_WRITE_NEXT);
- if (err < 0)
- return err;
- /* Wait for RX full (with timeout protection) */
- err = vx_wait_for_rx_full(chip);
- if (err < 0)
- return err;
- rmh->Stat[i] = vx_inb(chip, RXH) << 16;
- rmh->Stat[i] |= vx_inb(chip, RXM) << 8;
- rmh->Stat[i] |= vx_inb(chip, RXL);
- }
-
- return vx_transfer_end(chip, IRQ_MESS_WRITE_END);
-}
-
-
-#define MASK_MORE_THAN_1_WORD_COMMAND 0x00008000
-#define MASK_1_WORD_COMMAND 0x00ff7fff
-
-/*
- * vx_send_msg_nolock - send a DSP message and read back the status
- * @rmh: the rmh record to send and receive
- *
- * returns 0 if successful, or a negative error code.
- * the error code can be VX-specific, retrieved via vx_get_error().
- *
- * this function doesn't call spinlock at all.
- */
-int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh)
-{
- int i, err;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return -EBUSY;
-
- if ((err = vx_reset_chk(chip)) < 0) {
- snd_printd(KERN_DEBUG "vx_send_msg: vx_reset_chk error\n");
- return err;
- }
-
-#if 0
- printk(KERN_DEBUG "rmh: cmd = 0x%06x, length = %d, stype = %d\n",
- rmh->Cmd[0], rmh->LgCmd, rmh->DspStat);
- if (rmh->LgCmd > 1) {
- printk(KERN_DEBUG " ");
- for (i = 1; i < rmh->LgCmd; i++)
- printk("0x%06x ", rmh->Cmd[i]);
- printk("\n");
- }
-#endif
- /* Check bit M is set according to length of the command */
- if (rmh->LgCmd > 1)
- rmh->Cmd[0] |= MASK_MORE_THAN_1_WORD_COMMAND;
- else
- rmh->Cmd[0] &= MASK_1_WORD_COMMAND;
-
- /* Wait for TX empty */
- if ((err = vx_wait_isr_bit(chip, ISR_TX_EMPTY)) < 0) {
- snd_printd(KERN_DEBUG "vx_send_msg: wait tx empty error\n");
- return err;
- }
-
- /* Write Cmd[0] */
- vx_outb(chip, TXH, (rmh->Cmd[0] >> 16) & 0xff);
- vx_outb(chip, TXM, (rmh->Cmd[0] >> 8) & 0xff);
- vx_outb(chip, TXL, rmh->Cmd[0] & 0xff);
-
- /* Trigger irq MESSAGE */
- if ((err = vx_send_irq_dsp(chip, IRQ_MESSAGE)) < 0) {
- snd_printd(KERN_DEBUG "vx_send_msg: send IRQ_MESSAGE error\n");
- return err;
- }
-
- /* Wait for CHK = 1 */
- if ((err = vx_wait_isr_bit(chip, ISR_CHK)) < 0)
- return err;
-
- /* If error, get error value from RX */
- if (vx_inb(chip, ISR) & ISR_ERR) {
- if ((err = vx_wait_for_rx_full(chip)) < 0) {
- snd_printd(KERN_DEBUG "vx_send_msg: rx_full read error\n");
- return err;
- }
- err = vx_inb(chip, RXH) << 16;
- err |= vx_inb(chip, RXM) << 8;
- err |= vx_inb(chip, RXL);
- snd_printd(KERN_DEBUG "msg got error = 0x%x at cmd[0]\n", err);
- err = -(VX_ERR_MASK | err);
- return err;
- }
-
- /* Send the other words */
- if (rmh->LgCmd > 1) {
- for (i = 1; i < rmh->LgCmd; i++) {
- /* Wait for TX ready */
- if ((err = vx_wait_isr_bit(chip, ISR_TX_READY)) < 0) {
- snd_printd(KERN_DEBUG "vx_send_msg: tx_ready error\n");
- return err;
- }
-
- /* Write Cmd[i] */
- vx_outb(chip, TXH, (rmh->Cmd[i] >> 16) & 0xff);
- vx_outb(chip, TXM, (rmh->Cmd[i] >> 8) & 0xff);
- vx_outb(chip, TXL, rmh->Cmd[i] & 0xff);
-
- /* Trigger irq MESS_READ_NEXT */
- if ((err = vx_send_irq_dsp(chip, IRQ_MESS_READ_NEXT)) < 0) {
- snd_printd(KERN_DEBUG "vx_send_msg: IRQ_READ_NEXT error\n");
- return err;
- }
- }
- /* Wait for TX empty */
- if ((err = vx_wait_isr_bit(chip, ISR_TX_READY)) < 0) {
- snd_printd(KERN_DEBUG "vx_send_msg: TX_READY error\n");
- return err;
- }
- /* End of transfer */
- err = vx_transfer_end(chip, IRQ_MESS_READ_END);
- if (err < 0)
- return err;
- }
-
- return vx_read_status(chip, rmh);
-}
-
-
-/*
- * vx_send_msg - send a DSP message with spinlock
- * @rmh: the rmh record to send and receive
- *
- * returns 0 if successful, or a negative error code.
- * see vx_send_msg_nolock().
- */
-int vx_send_msg(struct vx_core *chip, struct vx_rmh *rmh)
-{
- unsigned long flags;
- int err;
-
- spin_lock_irqsave(&chip->lock, flags);
- err = vx_send_msg_nolock(chip, rmh);
- spin_unlock_irqrestore(&chip->lock, flags);
- return err;
-}
-
-
-/*
- * vx_send_rih_nolock - send an RIH to xilinx
- * @cmd: the command to send
- *
- * returns 0 if successful, or a negative error code.
- * the error code can be VX-specific, retrieved via vx_get_error().
- *
- * this function doesn't call spinlock at all.
- *
- * unlike RMH, no command is sent to DSP.
- */
-int vx_send_rih_nolock(struct vx_core *chip, int cmd)
-{
- int err;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return -EBUSY;
-
-#if 0
- printk(KERN_DEBUG "send_rih: cmd = 0x%x\n", cmd);
-#endif
- if ((err = vx_reset_chk(chip)) < 0)
- return err;
- /* send the IRQ */
- if ((err = vx_send_irq_dsp(chip, cmd)) < 0)
- return err;
- /* Wait CHK = 1 */
- if ((err = vx_wait_isr_bit(chip, ISR_CHK)) < 0)
- return err;
- /* If error, read RX */
- if (vx_inb(chip, ISR) & ISR_ERR) {
- if ((err = vx_wait_for_rx_full(chip)) < 0)
- return err;
- err = vx_inb(chip, RXH) << 16;
- err |= vx_inb(chip, RXM) << 8;
- err |= vx_inb(chip, RXL);
- return -(VX_ERR_MASK | err);
- }
- return 0;
-}
-
-
-/*
- * vx_send_rih - send an RIH with spinlock
- * @cmd: the command to send
- *
- * see vx_send_rih_nolock().
- */
-int vx_send_rih(struct vx_core *chip, int cmd)
-{
- unsigned long flags;
- int err;
-
- spin_lock_irqsave(&chip->lock, flags);
- err = vx_send_rih_nolock(chip, cmd);
- spin_unlock_irqrestore(&chip->lock, flags);
- return err;
-}
-
-#define END_OF_RESET_WAIT_TIME 500 /* us */
-
-/**
- * snd_vx_boot_xilinx - boot up the xilinx interface
- * @boot: the boot record to load
- */
-int snd_vx_load_boot_image(struct vx_core *chip, const struct firmware *boot)
-{
- unsigned int i;
- int no_fillup = vx_has_new_dsp(chip);
-
- /* check the length of boot image */
- if (boot->size <= 0)
- return -EINVAL;
- if (boot->size % 3)
- return -EINVAL;
-#if 0
- {
- /* more strict check */
- unsigned int c = ((u32)boot->data[0] << 16) | ((u32)boot->data[1] << 8) | boot->data[2];
- if (boot->size != (c + 2) * 3)
- return -EINVAL;
- }
-#endif
-
- /* reset dsp */
- vx_reset_dsp(chip);
-
- udelay(END_OF_RESET_WAIT_TIME); /* another wait? */
-
- /* download boot strap */
- for (i = 0; i < 0x600; i += 3) {
- if (i >= boot->size) {
- if (no_fillup)
- break;
- if (vx_wait_isr_bit(chip, ISR_TX_EMPTY) < 0) {
- snd_printk(KERN_ERR "dsp boot failed at %d\n", i);
- return -EIO;
- }
- vx_outb(chip, TXH, 0);
- vx_outb(chip, TXM, 0);
- vx_outb(chip, TXL, 0);
- } else {
- const unsigned char *image = boot->data + i;
- if (vx_wait_isr_bit(chip, ISR_TX_EMPTY) < 0) {
- snd_printk(KERN_ERR "dsp boot failed at %d\n", i);
- return -EIO;
- }
- vx_outb(chip, TXH, image[0]);
- vx_outb(chip, TXM, image[1]);
- vx_outb(chip, TXL, image[2]);
- }
- }
- return 0;
-}
-
-EXPORT_SYMBOL(snd_vx_load_boot_image);
-
-/*
- * vx_test_irq_src - query the source of interrupts
- *
- * called from irq handler only
- */
-static int vx_test_irq_src(struct vx_core *chip, unsigned int *ret)
-{
- int err;
-
- vx_init_rmh(&chip->irq_rmh, CMD_TEST_IT);
- spin_lock(&chip->lock);
- err = vx_send_msg_nolock(chip, &chip->irq_rmh);
- if (err < 0)
- *ret = 0;
- else
- *ret = chip->irq_rmh.Stat[0];
- spin_unlock(&chip->lock);
- return err;
-}
-
-
-/*
- * vx_interrupt - soft irq handler
- */
-static void vx_interrupt(unsigned long private_data)
-{
- struct vx_core *chip = (struct vx_core *) private_data;
- unsigned int events;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return;
-
- if (vx_test_irq_src(chip, &events) < 0)
- return;
-
-#if 0
- if (events & 0x000800)
- printk(KERN_ERR "DSP Stream underrun ! IRQ events = 0x%x\n", events);
-#endif
- // printk(KERN_DEBUG "IRQ events = 0x%x\n", events);
-
- /* We must prevent any application using this DSP
- * and block any further request until the application
- * either unregisters or reloads the DSP
- */
- if (events & FATAL_DSP_ERROR) {
- snd_printk(KERN_ERR "vx_core: fatal DSP error!!\n");
- return;
- }
-
- /* The start on time code conditions are filled (ie the time code
- * received by the board is equal to one of those given to it).
- */
- if (events & TIME_CODE_EVENT_PENDING)
- ; /* so far, nothing to do yet */
-
- /* The frequency has changed on the board (UER mode). */
- if (events & FREQUENCY_CHANGE_EVENT_PENDING)
- vx_change_frequency(chip);
-
- /* update the pcm streams */
- vx_pcm_update_intr(chip, events);
-}
-
-
-/**
- * snd_vx_irq_handler - interrupt handler
- */
-irqreturn_t snd_vx_irq_handler(int irq, void *dev)
-{
- struct vx_core *chip = dev;
-
- if (! (chip->chip_status & VX_STAT_CHIP_INIT) ||
- (chip->chip_status & VX_STAT_IS_STALE))
- return IRQ_NONE;
- if (! vx_test_and_ack(chip))
- tasklet_schedule(&chip->tq);
- return IRQ_HANDLED;
-}
-
-EXPORT_SYMBOL(snd_vx_irq_handler);
-
-/*
- */
-static void vx_reset_board(struct vx_core *chip, int cold_reset)
-{
- if (snd_BUG_ON(!chip->ops->reset_board))
- return;
-
- /* current source, later sync'ed with target */
- chip->audio_source = VX_AUDIO_SRC_LINE;
- if (cold_reset) {
- chip->audio_source_target = chip->audio_source;
- chip->clock_source = INTERNAL_QUARTZ;
- chip->clock_mode = VX_CLOCK_MODE_AUTO;
- chip->freq = 48000;
- chip->uer_detected = VX_UER_MODE_NOT_PRESENT;
- chip->uer_bits = SNDRV_PCM_DEFAULT_CON_SPDIF;
- }
-
- chip->ops->reset_board(chip, cold_reset);
-
- vx_reset_codec(chip, cold_reset);
-
- vx_set_internal_clock(chip, chip->freq);
-
- /* Reset the DSP */
- vx_reset_dsp(chip);
-
- if (vx_is_pcmcia(chip)) {
- /* Acknowledge any pending IRQ and reset the MEMIRQ flag. */
- vx_test_and_ack(chip);
- vx_validate_irq(chip, 1);
- }
-
- /* init CBits */
- vx_set_iec958_status(chip, chip->uer_bits);
-}
-
-
-/*
- * proc interface
- */
-
-static void vx_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- struct vx_core *chip = entry->private_data;
- static char *audio_src_vxp[] = { "Line", "Mic", "Digital" };
- static char *audio_src_vx2[] = { "Analog", "Analog", "Digital" };
- static char *clock_mode[] = { "Auto", "Internal", "External" };
- static char *clock_src[] = { "Internal", "External" };
- static char *uer_type[] = { "Consumer", "Professional", "Not Present" };
-
- snd_iprintf(buffer, "%s\n", chip->card->longname);
- snd_iprintf(buffer, "Xilinx Firmware: %s\n",
- chip->chip_status & VX_STAT_XILINX_LOADED ? "Loaded" : "No");
- snd_iprintf(buffer, "Device Initialized: %s\n",
- chip->chip_status & VX_STAT_DEVICE_INIT ? "Yes" : "No");
- snd_iprintf(buffer, "DSP audio info:");
- if (chip->audio_info & VX_AUDIO_INFO_REAL_TIME)
- snd_iprintf(buffer, " realtime");
- if (chip->audio_info & VX_AUDIO_INFO_OFFLINE)
- snd_iprintf(buffer, " offline");
- if (chip->audio_info & VX_AUDIO_INFO_MPEG1)
- snd_iprintf(buffer, " mpeg1");
- if (chip->audio_info & VX_AUDIO_INFO_MPEG2)
- snd_iprintf(buffer, " mpeg2");
- if (chip->audio_info & VX_AUDIO_INFO_LINEAR_8)
- snd_iprintf(buffer, " linear8");
- if (chip->audio_info & VX_AUDIO_INFO_LINEAR_16)
- snd_iprintf(buffer, " linear16");
- if (chip->audio_info & VX_AUDIO_INFO_LINEAR_24)
- snd_iprintf(buffer, " linear24");
- snd_iprintf(buffer, "\n");
- snd_iprintf(buffer, "Input Source: %s\n", vx_is_pcmcia(chip) ?
- audio_src_vxp[chip->audio_source] :
- audio_src_vx2[chip->audio_source]);
- snd_iprintf(buffer, "Clock Mode: %s\n", clock_mode[chip->clock_mode]);
- snd_iprintf(buffer, "Clock Source: %s\n", clock_src[chip->clock_source]);
- snd_iprintf(buffer, "Frequency: %d\n", chip->freq);
- snd_iprintf(buffer, "Detected Frequency: %d\n", chip->freq_detected);
- snd_iprintf(buffer, "Detected UER type: %s\n", uer_type[chip->uer_detected]);
- snd_iprintf(buffer, "Min/Max/Cur IBL: %d/%d/%d (granularity=%d)\n",
- chip->ibl.min_size, chip->ibl.max_size, chip->ibl.size,
- chip->ibl.granularity);
-}
-
-static void vx_proc_init(struct vx_core *chip)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(chip->card, "vx-status", &entry))
- snd_info_set_text_ops(entry, chip, vx_proc_read);
-}
-
-
-/**
- * snd_vx_dsp_boot - load the DSP boot
- */
-int snd_vx_dsp_boot(struct vx_core *chip, const struct firmware *boot)
-{
- int err;
- int cold_reset = !(chip->chip_status & VX_STAT_DEVICE_INIT);
-
- vx_reset_board(chip, cold_reset);
- vx_validate_irq(chip, 0);
-
- if ((err = snd_vx_load_boot_image(chip, boot)) < 0)
- return err;
- msleep(10);
-
- return 0;
-}
-
-EXPORT_SYMBOL(snd_vx_dsp_boot);
-
-/**
- * snd_vx_dsp_load - load the DSP image
- */
-int snd_vx_dsp_load(struct vx_core *chip, const struct firmware *dsp)
-{
- unsigned int i;
- int err;
- unsigned int csum = 0;
- const unsigned char *image, *cptr;
-
- if (dsp->size % 3)
- return -EINVAL;
-
- vx_toggle_dac_mute(chip, 1);
-
- /* Transfert data buffer from PC to DSP */
- for (i = 0; i < dsp->size; i += 3) {
- image = dsp->data + i;
- /* Wait DSP ready for a new read */
- if ((err = vx_wait_isr_bit(chip, ISR_TX_EMPTY)) < 0) {
- printk(KERN_ERR
- "dsp loading error at position %d\n", i);
- return err;
- }
- cptr = image;
- csum ^= *cptr;
- csum = (csum >> 24) | (csum << 8);
- vx_outb(chip, TXH, *cptr++);
- csum ^= *cptr;
- csum = (csum >> 24) | (csum << 8);
- vx_outb(chip, TXM, *cptr++);
- csum ^= *cptr;
- csum = (csum >> 24) | (csum << 8);
- vx_outb(chip, TXL, *cptr++);
- }
- snd_printdd(KERN_DEBUG "checksum = 0x%08x\n", csum);
-
- msleep(200);
-
- if ((err = vx_wait_isr_bit(chip, ISR_CHK)) < 0)
- return err;
-
- vx_toggle_dac_mute(chip, 0);
-
- vx_test_and_ack(chip);
- vx_validate_irq(chip, 1);
-
- return 0;
-}
-
-EXPORT_SYMBOL(snd_vx_dsp_load);
-
-#ifdef CONFIG_PM
-/*
- * suspend
- */
-int snd_vx_suspend(struct vx_core *chip, pm_message_t state)
-{
- unsigned int i;
-
- snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
- chip->chip_status |= VX_STAT_IN_SUSPEND;
- for (i = 0; i < chip->hw->num_codecs; i++)
- snd_pcm_suspend_all(chip->pcm[i]);
-
- return 0;
-}
-
-EXPORT_SYMBOL(snd_vx_suspend);
-
-/*
- * resume
- */
-int snd_vx_resume(struct vx_core *chip)
-{
- int i, err;
-
- chip->chip_status &= ~VX_STAT_CHIP_INIT;
-
- for (i = 0; i < 4; i++) {
- if (! chip->firmware[i])
- continue;
- err = chip->ops->load_dsp(chip, i, chip->firmware[i]);
- if (err < 0) {
- snd_printk(KERN_ERR "vx: firmware resume error at DSP %d\n", i);
- return -EIO;
- }
- }
-
- chip->chip_status |= VX_STAT_CHIP_INIT;
- chip->chip_status &= ~VX_STAT_IN_SUSPEND;
-
- snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_vx_resume);
-#endif
-
-/**
- * snd_vx_create - constructor for struct vx_core
- * @hw: hardware specific record
- *
- * this function allocates the instance and prepare for the hardware
- * initialization.
- *
- * return the instance pointer if successful, NULL in error.
- */
-struct vx_core *snd_vx_create(struct snd_card *card, struct snd_vx_hardware *hw,
- struct snd_vx_ops *ops,
- int extra_size)
-{
- struct vx_core *chip;
-
- if (snd_BUG_ON(!card || !hw || !ops))
- return NULL;
-
- chip = kzalloc(sizeof(*chip) + extra_size, GFP_KERNEL);
- if (! chip) {
- snd_printk(KERN_ERR "vx_core: no memory\n");
- return NULL;
- }
- spin_lock_init(&chip->lock);
- spin_lock_init(&chip->irq_lock);
- chip->irq = -1;
- chip->hw = hw;
- chip->type = hw->type;
- chip->ops = ops;
- tasklet_init(&chip->tq, vx_interrupt, (unsigned long)chip);
- mutex_init(&chip->mixer_mutex);
-
- chip->card = card;
- card->private_data = chip;
- strcpy(card->driver, hw->name);
- sprintf(card->shortname, "Digigram %s", hw->name);
-
- vx_proc_init(chip);
-
- return chip;
-}
-
-EXPORT_SYMBOL(snd_vx_create);
-
-/*
- * module entries
- */
-static int __init alsa_vx_core_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_vx_core_exit(void)
-{
-}
-
-module_init(alsa_vx_core_init)
-module_exit(alsa_vx_core_exit)
diff --git a/ANDROID_3.4.5/sound/drivers/vx/vx_hwdep.c b/ANDROID_3.4.5/sound/drivers/vx/vx_hwdep.c
deleted file mode 100644
index 4a1fae99..00000000
--- a/ANDROID_3.4.5/sound/drivers/vx/vx_hwdep.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Driver for Digigram VX soundcards
- *
- * DSP firmware management
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/hwdep.h>
-#include <sound/vx_core.h>
-
-#ifdef SND_VX_FW_LOADER
-
-MODULE_FIRMWARE("vx/bx_1_vxp.b56");
-MODULE_FIRMWARE("vx/bx_1_vp4.b56");
-MODULE_FIRMWARE("vx/x1_1_vx2.xlx");
-MODULE_FIRMWARE("vx/x1_2_v22.xlx");
-MODULE_FIRMWARE("vx/x1_1_vxp.xlx");
-MODULE_FIRMWARE("vx/x1_1_vp4.xlx");
-MODULE_FIRMWARE("vx/bd56002.boot");
-MODULE_FIRMWARE("vx/bd563v2.boot");
-MODULE_FIRMWARE("vx/bd563s3.boot");
-MODULE_FIRMWARE("vx/l_1_vx2.d56");
-MODULE_FIRMWARE("vx/l_1_v22.d56");
-MODULE_FIRMWARE("vx/l_1_vxp.d56");
-MODULE_FIRMWARE("vx/l_1_vp4.d56");
-
-int snd_vx_setup_firmware(struct vx_core *chip)
-{
- static char *fw_files[VX_TYPE_NUMS][4] = {
- [VX_TYPE_BOARD] = {
- NULL, "x1_1_vx2.xlx", "bd56002.boot", "l_1_vx2.d56",
- },
- [VX_TYPE_V2] = {
- NULL, "x1_2_v22.xlx", "bd563v2.boot", "l_1_v22.d56",
- },
- [VX_TYPE_MIC] = {
- NULL, "x1_2_v22.xlx", "bd563v2.boot", "l_1_v22.d56",
- },
- [VX_TYPE_VXPOCKET] = {
- "bx_1_vxp.b56", "x1_1_vxp.xlx", "bd563s3.boot", "l_1_vxp.d56"
- },
- [VX_TYPE_VXP440] = {
- "bx_1_vp4.b56", "x1_1_vp4.xlx", "bd563s3.boot", "l_1_vp4.d56"
- },
- };
-
- int i, err;
-
- for (i = 0; i < 4; i++) {
- char path[32];
- const struct firmware *fw;
- if (! fw_files[chip->type][i])
- continue;
- sprintf(path, "vx/%s", fw_files[chip->type][i]);
- if (request_firmware(&fw, path, chip->dev)) {
- snd_printk(KERN_ERR "vx: can't load firmware %s\n", path);
- return -ENOENT;
- }
- err = chip->ops->load_dsp(chip, i, fw);
- if (err < 0) {
- release_firmware(fw);
- return err;
- }
- if (i == 1)
- chip->chip_status |= VX_STAT_XILINX_LOADED;
-#ifdef CONFIG_PM
- chip->firmware[i] = fw;
-#else
- release_firmware(fw);
-#endif
- }
-
- /* ok, we reached to the last one */
- /* create the devices if not built yet */
- if ((err = snd_vx_pcm_new(chip)) < 0)
- return err;
-
- if ((err = snd_vx_mixer_new(chip)) < 0)
- return err;
-
- if (chip->ops->add_controls)
- if ((err = chip->ops->add_controls(chip)) < 0)
- return err;
-
- chip->chip_status |= VX_STAT_DEVICE_INIT;
- chip->chip_status |= VX_STAT_CHIP_INIT;
-
- return snd_card_register(chip->card);
-}
-
-/* exported */
-void snd_vx_free_firmware(struct vx_core *chip)
-{
-#ifdef CONFIG_PM
- int i;
- for (i = 0; i < 4; i++)
- release_firmware(chip->firmware[i]);
-#endif
-}
-
-#else /* old style firmware loading */
-
-static int vx_hwdep_dsp_status(struct snd_hwdep *hw,
- struct snd_hwdep_dsp_status *info)
-{
- static char *type_ids[VX_TYPE_NUMS] = {
- [VX_TYPE_BOARD] = "vxboard",
- [VX_TYPE_V2] = "vx222",
- [VX_TYPE_MIC] = "vx222",
- [VX_TYPE_VXPOCKET] = "vxpocket",
- [VX_TYPE_VXP440] = "vxp440",
- };
- struct vx_core *vx = hw->private_data;
-
- if (snd_BUG_ON(!type_ids[vx->type]))
- return -EINVAL;
- strcpy(info->id, type_ids[vx->type]);
- if (vx_is_pcmcia(vx))
- info->num_dsps = 4;
- else
- info->num_dsps = 3;
- if (vx->chip_status & VX_STAT_CHIP_INIT)
- info->chip_ready = 1;
- info->version = VX_DRIVER_VERSION;
- return 0;
-}
-
-static void free_fw(const struct firmware *fw)
-{
- if (fw) {
- vfree(fw->data);
- kfree(fw);
- }
-}
-
-static int vx_hwdep_dsp_load(struct snd_hwdep *hw,
- struct snd_hwdep_dsp_image *dsp)
-{
- struct vx_core *vx = hw->private_data;
- int index, err;
- struct firmware *fw;
-
- if (snd_BUG_ON(!vx->ops->load_dsp))
- return -ENXIO;
-
- fw = kmalloc(sizeof(*fw), GFP_KERNEL);
- if (! fw) {
- snd_printk(KERN_ERR "cannot allocate firmware\n");
- return -ENOMEM;
- }
- fw->size = dsp->length;
- fw->data = vmalloc(fw->size);
- if (! fw->data) {
- snd_printk(KERN_ERR "cannot allocate firmware image (length=%d)\n",
- (int)fw->size);
- kfree(fw);
- return -ENOMEM;
- }
- if (copy_from_user((void *)fw->data, dsp->image, dsp->length)) {
- free_fw(fw);
- return -EFAULT;
- }
-
- index = dsp->index;
- if (! vx_is_pcmcia(vx))
- index++;
- err = vx->ops->load_dsp(vx, index, fw);
- if (err < 0) {
- free_fw(fw);
- return err;
- }
-#ifdef CONFIG_PM
- vx->firmware[index] = fw;
-#else
- free_fw(fw);
-#endif
-
- if (index == 1)
- vx->chip_status |= VX_STAT_XILINX_LOADED;
- if (index < 3)
- return 0;
-
- /* ok, we reached to the last one */
- /* create the devices if not built yet */
- if (! (vx->chip_status & VX_STAT_DEVICE_INIT)) {
- if ((err = snd_vx_pcm_new(vx)) < 0)
- return err;
-
- if ((err = snd_vx_mixer_new(vx)) < 0)
- return err;
-
- if (vx->ops->add_controls)
- if ((err = vx->ops->add_controls(vx)) < 0)
- return err;
-
- if ((err = snd_card_register(vx->card)) < 0)
- return err;
-
- vx->chip_status |= VX_STAT_DEVICE_INIT;
- }
- vx->chip_status |= VX_STAT_CHIP_INIT;
- return 0;
-}
-
-
-/* exported */
-int snd_vx_setup_firmware(struct vx_core *chip)
-{
- int err;
- struct snd_hwdep *hw;
-
- if ((err = snd_hwdep_new(chip->card, SND_VX_HWDEP_ID, 0, &hw)) < 0)
- return err;
-
- hw->iface = SNDRV_HWDEP_IFACE_VX;
- hw->private_data = chip;
- hw->ops.dsp_status = vx_hwdep_dsp_status;
- hw->ops.dsp_load = vx_hwdep_dsp_load;
- hw->exclusive = 1;
- sprintf(hw->name, "VX Loader (%s)", chip->card->driver);
- chip->hwdep = hw;
-
- return snd_card_register(chip->card);
-}
-
-/* exported */
-void snd_vx_free_firmware(struct vx_core *chip)
-{
-#ifdef CONFIG_PM
- int i;
- for (i = 0; i < 4; i++)
- free_fw(chip->firmware[i]);
-#endif
-}
-
-#endif /* SND_VX_FW_LOADER */
-
-EXPORT_SYMBOL(snd_vx_setup_firmware);
-EXPORT_SYMBOL(snd_vx_free_firmware);
diff --git a/ANDROID_3.4.5/sound/drivers/vx/vx_mixer.c b/ANDROID_3.4.5/sound/drivers/vx/vx_mixer.c
deleted file mode 100644
index c71b8d14..00000000
--- a/ANDROID_3.4.5/sound/drivers/vx/vx_mixer.c
+++ /dev/null
@@ -1,1028 +0,0 @@
-/*
- * Driver for Digigram VX soundcards
- *
- * Common mixer part
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/vx_core.h>
-#include "vx_cmd.h"
-
-
-/*
- * write a codec data (24bit)
- */
-static void vx_write_codec_reg(struct vx_core *chip, int codec, unsigned int data)
-{
- unsigned long flags;
-
- if (snd_BUG_ON(!chip->ops->write_codec))
- return;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return;
-
- spin_lock_irqsave(&chip->lock, flags);
- chip->ops->write_codec(chip, codec, data);
- spin_unlock_irqrestore(&chip->lock, flags);
-}
-
-/*
- * Data type used to access the Codec
- */
-union vx_codec_data {
- u32 l;
-#ifdef SNDRV_BIG_ENDIAN
- struct w {
- u16 h;
- u16 l;
- } w;
- struct b {
- u8 hh;
- u8 mh;
- u8 ml;
- u8 ll;
- } b;
-#else /* LITTLE_ENDIAN */
- struct w {
- u16 l;
- u16 h;
- } w;
- struct b {
- u8 ll;
- u8 ml;
- u8 mh;
- u8 hh;
- } b;
-#endif
-};
-
-#define SET_CDC_DATA_SEL(di,s) ((di).b.mh = (u8) (s))
-#define SET_CDC_DATA_REG(di,r) ((di).b.ml = (u8) (r))
-#define SET_CDC_DATA_VAL(di,d) ((di).b.ll = (u8) (d))
-#define SET_CDC_DATA_INIT(di) ((di).l = 0L, SET_CDC_DATA_SEL(di,XX_CODEC_SELECTOR))
-
-/*
- * set up codec register and write the value
- * @codec: the codec id, 0 or 1
- * @reg: register index
- * @val: data value
- */
-static void vx_set_codec_reg(struct vx_core *chip, int codec, int reg, int val)
-{
- union vx_codec_data data;
- /* DAC control register */
- SET_CDC_DATA_INIT(data);
- SET_CDC_DATA_REG(data, reg);
- SET_CDC_DATA_VAL(data, val);
- vx_write_codec_reg(chip, codec, data.l);
-}
-
-
-/*
- * vx_set_analog_output_level - set the output attenuation level
- * @codec: the output codec, 0 or 1. (1 for VXP440 only)
- * @left: left output level, 0 = mute
- * @right: right output level
- */
-static void vx_set_analog_output_level(struct vx_core *chip, int codec, int left, int right)
-{
- left = chip->hw->output_level_max - left;
- right = chip->hw->output_level_max - right;
-
- if (chip->ops->akm_write) {
- chip->ops->akm_write(chip, XX_CODEC_LEVEL_LEFT_REGISTER, left);
- chip->ops->akm_write(chip, XX_CODEC_LEVEL_RIGHT_REGISTER, right);
- } else {
- /* convert to attenuation level: 0 = 0dB (max), 0xe3 = -113.5 dB (min) */
- vx_set_codec_reg(chip, codec, XX_CODEC_LEVEL_LEFT_REGISTER, left);
- vx_set_codec_reg(chip, codec, XX_CODEC_LEVEL_RIGHT_REGISTER, right);
- }
-}
-
-
-/*
- * vx_toggle_dac_mute - mute/unmute DAC
- * @mute: 0 = unmute, 1 = mute
- */
-
-#define DAC_ATTEN_MIN 0x08
-#define DAC_ATTEN_MAX 0x38
-
-void vx_toggle_dac_mute(struct vx_core *chip, int mute)
-{
- unsigned int i;
- for (i = 0; i < chip->hw->num_codecs; i++) {
- if (chip->ops->akm_write)
- chip->ops->akm_write(chip, XX_CODEC_DAC_CONTROL_REGISTER, mute); /* XXX */
- else
- vx_set_codec_reg(chip, i, XX_CODEC_DAC_CONTROL_REGISTER,
- mute ? DAC_ATTEN_MAX : DAC_ATTEN_MIN);
- }
-}
-
-/*
- * vx_reset_codec - reset and initialize the codecs
- */
-void vx_reset_codec(struct vx_core *chip, int cold_reset)
-{
- unsigned int i;
- int port = chip->type >= VX_TYPE_VXPOCKET ? 0x75 : 0x65;
-
- chip->ops->reset_codec(chip);
-
- /* AKM codecs should be initialized in reset_codec callback */
- if (! chip->ops->akm_write) {
- /* initialize old codecs */
- for (i = 0; i < chip->hw->num_codecs; i++) {
- /* DAC control register (change level when zero crossing + mute) */
- vx_set_codec_reg(chip, i, XX_CODEC_DAC_CONTROL_REGISTER, DAC_ATTEN_MAX);
- /* ADC control register */
- vx_set_codec_reg(chip, i, XX_CODEC_ADC_CONTROL_REGISTER, 0x00);
- /* Port mode register */
- vx_set_codec_reg(chip, i, XX_CODEC_PORT_MODE_REGISTER, port);
- /* Clock control register */
- vx_set_codec_reg(chip, i, XX_CODEC_CLOCK_CONTROL_REGISTER, 0x00);
- }
- }
-
- /* mute analog output */
- for (i = 0; i < chip->hw->num_codecs; i++) {
- chip->output_level[i][0] = 0;
- chip->output_level[i][1] = 0;
- vx_set_analog_output_level(chip, i, 0, 0);
- }
-}
-
-/*
- * change the audio input source
- * @src: the target source (VX_AUDIO_SRC_XXX)
- */
-static void vx_change_audio_source(struct vx_core *chip, int src)
-{
- unsigned long flags;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return;
-
- spin_lock_irqsave(&chip->lock, flags);
- chip->ops->change_audio_source(chip, src);
- spin_unlock_irqrestore(&chip->lock, flags);
-}
-
-
-/*
- * change the audio source if necessary and possible
- * returns 1 if the source is actually changed.
- */
-int vx_sync_audio_source(struct vx_core *chip)
-{
- if (chip->audio_source_target == chip->audio_source ||
- chip->pcm_running)
- return 0;
- vx_change_audio_source(chip, chip->audio_source_target);
- chip->audio_source = chip->audio_source_target;
- return 1;
-}
-
-
-/*
- * audio level, mute, monitoring
- */
-struct vx_audio_level {
- unsigned int has_level: 1;
- unsigned int has_monitor_level: 1;
- unsigned int has_mute: 1;
- unsigned int has_monitor_mute: 1;
- unsigned int mute;
- unsigned int monitor_mute;
- short level;
- short monitor_level;
-};
-
-static int vx_adjust_audio_level(struct vx_core *chip, int audio, int capture,
- struct vx_audio_level *info)
-{
- struct vx_rmh rmh;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return -EBUSY;
-
- vx_init_rmh(&rmh, CMD_AUDIO_LEVEL_ADJUST);
- if (capture)
- rmh.Cmd[0] |= COMMAND_RECORD_MASK;
- /* Add Audio IO mask */
- rmh.Cmd[1] = 1 << audio;
- rmh.Cmd[2] = 0;
- if (info->has_level) {
- rmh.Cmd[0] |= VALID_AUDIO_IO_DIGITAL_LEVEL;
- rmh.Cmd[2] |= info->level;
- }
- if (info->has_monitor_level) {
- rmh.Cmd[0] |= VALID_AUDIO_IO_MONITORING_LEVEL;
- rmh.Cmd[2] |= ((unsigned int)info->monitor_level << 10);
- }
- if (info->has_mute) {
- rmh.Cmd[0] |= VALID_AUDIO_IO_MUTE_LEVEL;
- if (info->mute)
- rmh.Cmd[2] |= AUDIO_IO_HAS_MUTE_LEVEL;
- }
- if (info->has_monitor_mute) {
- /* validate flag for M2 at least to unmute it */
- rmh.Cmd[0] |= VALID_AUDIO_IO_MUTE_MONITORING_1 | VALID_AUDIO_IO_MUTE_MONITORING_2;
- if (info->monitor_mute)
- rmh.Cmd[2] |= AUDIO_IO_HAS_MUTE_MONITORING_1;
- }
-
- return vx_send_msg(chip, &rmh);
-}
-
-
-#if 0 // not used
-static int vx_read_audio_level(struct vx_core *chip, int audio, int capture,
- struct vx_audio_level *info)
-{
- int err;
- struct vx_rmh rmh;
-
- memset(info, 0, sizeof(*info));
- vx_init_rmh(&rmh, CMD_GET_AUDIO_LEVELS);
- if (capture)
- rmh.Cmd[0] |= COMMAND_RECORD_MASK;
- /* Add Audio IO mask */
- rmh.Cmd[1] = 1 << audio;
- err = vx_send_msg(chip, &rmh);
- if (err < 0)
- return err;
- info.level = rmh.Stat[0] & MASK_DSP_WORD_LEVEL;
- info.monitor_level = (rmh.Stat[0] >> 10) & MASK_DSP_WORD_LEVEL;
- info.mute = (rmh.Stat[i] & AUDIO_IO_HAS_MUTE_LEVEL) ? 1 : 0;
- info.monitor_mute = (rmh.Stat[i] & AUDIO_IO_HAS_MUTE_MONITORING_1) ? 1 : 0;
- return 0;
-}
-#endif // not used
-
-/*
- * set the monitoring level and mute state of the given audio
- * no more static, because must be called from vx_pcm to demute monitoring
- */
-int vx_set_monitor_level(struct vx_core *chip, int audio, int level, int active)
-{
- struct vx_audio_level info;
-
- memset(&info, 0, sizeof(info));
- info.has_monitor_level = 1;
- info.monitor_level = level;
- info.has_monitor_mute = 1;
- info.monitor_mute = !active;
- chip->audio_monitor[audio] = level;
- chip->audio_monitor_active[audio] = active;
- return vx_adjust_audio_level(chip, audio, 0, &info); /* playback only */
-}
-
-
-/*
- * set the mute status of the given audio
- */
-static int vx_set_audio_switch(struct vx_core *chip, int audio, int active)
-{
- struct vx_audio_level info;
-
- memset(&info, 0, sizeof(info));
- info.has_mute = 1;
- info.mute = !active;
- chip->audio_active[audio] = active;
- return vx_adjust_audio_level(chip, audio, 0, &info); /* playback only */
-}
-
-/*
- * set the mute status of the given audio
- */
-static int vx_set_audio_gain(struct vx_core *chip, int audio, int capture, int level)
-{
- struct vx_audio_level info;
-
- memset(&info, 0, sizeof(info));
- info.has_level = 1;
- info.level = level;
- chip->audio_gain[capture][audio] = level;
- return vx_adjust_audio_level(chip, audio, capture, &info);
-}
-
-/*
- * reset all audio levels
- */
-static void vx_reset_audio_levels(struct vx_core *chip)
-{
- unsigned int i, c;
- struct vx_audio_level info;
-
- memset(chip->audio_gain, 0, sizeof(chip->audio_gain));
- memset(chip->audio_active, 0, sizeof(chip->audio_active));
- memset(chip->audio_monitor, 0, sizeof(chip->audio_monitor));
- memset(chip->audio_monitor_active, 0, sizeof(chip->audio_monitor_active));
-
- for (c = 0; c < 2; c++) {
- for (i = 0; i < chip->hw->num_ins * 2; i++) {
- memset(&info, 0, sizeof(info));
- if (c == 0) {
- info.has_monitor_level = 1;
- info.has_mute = 1;
- info.has_monitor_mute = 1;
- }
- info.has_level = 1;
- info.level = CVAL_0DB; /* default: 0dB */
- vx_adjust_audio_level(chip, i, c, &info);
- chip->audio_gain[c][i] = CVAL_0DB;
- chip->audio_monitor[i] = CVAL_0DB;
- }
- }
-}
-
-
-/*
- * VU, peak meter record
- */
-
-#define VU_METER_CHANNELS 2
-
-struct vx_vu_meter {
- int saturated;
- int vu_level;
- int peak_level;
-};
-
-/*
- * get the VU and peak meter values
- * @audio: the audio index
- * @capture: 0 = playback, 1 = capture operation
- * @info: the array of vx_vu_meter records (size = 2).
- */
-static int vx_get_audio_vu_meter(struct vx_core *chip, int audio, int capture, struct vx_vu_meter *info)
-{
- struct vx_rmh rmh;
- int i, err;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return -EBUSY;
-
- vx_init_rmh(&rmh, CMD_AUDIO_VU_PIC_METER);
- rmh.LgStat += 2 * VU_METER_CHANNELS;
- if (capture)
- rmh.Cmd[0] |= COMMAND_RECORD_MASK;
-
- /* Add Audio IO mask */
- rmh.Cmd[1] = 0;
- for (i = 0; i < VU_METER_CHANNELS; i++)
- rmh.Cmd[1] |= 1 << (audio + i);
- err = vx_send_msg(chip, &rmh);
- if (err < 0)
- return err;
- /* Read response */
- for (i = 0; i < 2 * VU_METER_CHANNELS; i +=2) {
- info->saturated = (rmh.Stat[0] & (1 << (audio + i))) ? 1 : 0;
- info->vu_level = rmh.Stat[i + 1];
- info->peak_level = rmh.Stat[i + 2];
- info++;
- }
- return 0;
-}
-
-
-/*
- * control API entries
- */
-
-/*
- * output level control
- */
-static int vx_output_level_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = chip->hw->output_level_max;
- return 0;
-}
-
-static int vx_output_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- int codec = kcontrol->id.index;
- mutex_lock(&chip->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->output_level[codec][0];
- ucontrol->value.integer.value[1] = chip->output_level[codec][1];
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static int vx_output_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- int codec = kcontrol->id.index;
- unsigned int val[2], vmax;
-
- vmax = chip->hw->output_level_max;
- val[0] = ucontrol->value.integer.value[0];
- val[1] = ucontrol->value.integer.value[1];
- if (val[0] > vmax || val[1] > vmax)
- return -EINVAL;
- mutex_lock(&chip->mixer_mutex);
- if (val[0] != chip->output_level[codec][0] ||
- val[1] != chip->output_level[codec][1]) {
- vx_set_analog_output_level(chip, codec, val[0], val[1]);
- chip->output_level[codec][0] = val[0];
- chip->output_level[codec][1] = val[1];
- mutex_unlock(&chip->mixer_mutex);
- return 1;
- }
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static struct snd_kcontrol_new vx_control_output_level = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Master Playback Volume",
- .info = vx_output_level_info,
- .get = vx_output_level_get,
- .put = vx_output_level_put,
- /* tlv will be filled later */
-};
-
-/*
- * audio source select
- */
-static int vx_audio_src_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts_mic[3] = {
- "Digital", "Line", "Mic"
- };
- static char *texts_vx2[2] = {
- "Digital", "Analog"
- };
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- if (chip->type >= VX_TYPE_VXPOCKET) {
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item > 2)
- uinfo->value.enumerated.item = 2;
- strcpy(uinfo->value.enumerated.name,
- texts_mic[uinfo->value.enumerated.item]);
- } else {
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item > 1)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name,
- texts_vx2[uinfo->value.enumerated.item]);
- }
- return 0;
-}
-
-static int vx_audio_src_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = chip->audio_source_target;
- return 0;
-}
-
-static int vx_audio_src_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
-
- if (chip->type >= VX_TYPE_VXPOCKET) {
- if (ucontrol->value.enumerated.item[0] > 2)
- return -EINVAL;
- } else {
- if (ucontrol->value.enumerated.item[0] > 1)
- return -EINVAL;
- }
- mutex_lock(&chip->mixer_mutex);
- if (chip->audio_source_target != ucontrol->value.enumerated.item[0]) {
- chip->audio_source_target = ucontrol->value.enumerated.item[0];
- vx_sync_audio_source(chip);
- mutex_unlock(&chip->mixer_mutex);
- return 1;
- }
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static struct snd_kcontrol_new vx_control_audio_src = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = vx_audio_src_info,
- .get = vx_audio_src_get,
- .put = vx_audio_src_put,
-};
-
-/*
- * clock mode selection
- */
-static int vx_clock_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[3] = {
- "Auto", "Internal", "External"
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item > 2)
- uinfo->value.enumerated.item = 2;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int vx_clock_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = chip->clock_mode;
- return 0;
-}
-
-static int vx_clock_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
-
- if (ucontrol->value.enumerated.item[0] > 2)
- return -EINVAL;
- mutex_lock(&chip->mixer_mutex);
- if (chip->clock_mode != ucontrol->value.enumerated.item[0]) {
- chip->clock_mode = ucontrol->value.enumerated.item[0];
- vx_set_clock(chip, chip->freq);
- mutex_unlock(&chip->mixer_mutex);
- return 1;
- }
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static struct snd_kcontrol_new vx_control_clock_mode = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Clock Mode",
- .info = vx_clock_mode_info,
- .get = vx_clock_mode_get,
- .put = vx_clock_mode_put,
-};
-
-/*
- * Audio Gain
- */
-static int vx_audio_gain_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = CVAL_MAX;
- return 0;
-}
-
-static int vx_audio_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- int audio = kcontrol->private_value & 0xff;
- int capture = (kcontrol->private_value >> 8) & 1;
-
- mutex_lock(&chip->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->audio_gain[capture][audio];
- ucontrol->value.integer.value[1] = chip->audio_gain[capture][audio+1];
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static int vx_audio_gain_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- int audio = kcontrol->private_value & 0xff;
- int capture = (kcontrol->private_value >> 8) & 1;
- unsigned int val[2];
-
- val[0] = ucontrol->value.integer.value[0];
- val[1] = ucontrol->value.integer.value[1];
- if (val[0] > CVAL_MAX || val[1] > CVAL_MAX)
- return -EINVAL;
- mutex_lock(&chip->mixer_mutex);
- if (val[0] != chip->audio_gain[capture][audio] ||
- val[1] != chip->audio_gain[capture][audio+1]) {
- vx_set_audio_gain(chip, audio, capture, val[0]);
- vx_set_audio_gain(chip, audio+1, capture, val[1]);
- mutex_unlock(&chip->mixer_mutex);
- return 1;
- }
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static int vx_audio_monitor_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- int audio = kcontrol->private_value & 0xff;
-
- mutex_lock(&chip->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->audio_monitor[audio];
- ucontrol->value.integer.value[1] = chip->audio_monitor[audio+1];
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static int vx_audio_monitor_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- int audio = kcontrol->private_value & 0xff;
- unsigned int val[2];
-
- val[0] = ucontrol->value.integer.value[0];
- val[1] = ucontrol->value.integer.value[1];
- if (val[0] > CVAL_MAX || val[1] > CVAL_MAX)
- return -EINVAL;
-
- mutex_lock(&chip->mixer_mutex);
- if (val[0] != chip->audio_monitor[audio] ||
- val[1] != chip->audio_monitor[audio+1]) {
- vx_set_monitor_level(chip, audio, val[0],
- chip->audio_monitor_active[audio]);
- vx_set_monitor_level(chip, audio+1, val[1],
- chip->audio_monitor_active[audio+1]);
- mutex_unlock(&chip->mixer_mutex);
- return 1;
- }
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-#define vx_audio_sw_info snd_ctl_boolean_stereo_info
-
-static int vx_audio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- int audio = kcontrol->private_value & 0xff;
-
- mutex_lock(&chip->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->audio_active[audio];
- ucontrol->value.integer.value[1] = chip->audio_active[audio+1];
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static int vx_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- int audio = kcontrol->private_value & 0xff;
-
- mutex_lock(&chip->mixer_mutex);
- if (ucontrol->value.integer.value[0] != chip->audio_active[audio] ||
- ucontrol->value.integer.value[1] != chip->audio_active[audio+1]) {
- vx_set_audio_switch(chip, audio,
- !!ucontrol->value.integer.value[0]);
- vx_set_audio_switch(chip, audio+1,
- !!ucontrol->value.integer.value[1]);
- mutex_unlock(&chip->mixer_mutex);
- return 1;
- }
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static int vx_monitor_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- int audio = kcontrol->private_value & 0xff;
-
- mutex_lock(&chip->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->audio_monitor_active[audio];
- ucontrol->value.integer.value[1] = chip->audio_monitor_active[audio+1];
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static int vx_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- int audio = kcontrol->private_value & 0xff;
-
- mutex_lock(&chip->mixer_mutex);
- if (ucontrol->value.integer.value[0] != chip->audio_monitor_active[audio] ||
- ucontrol->value.integer.value[1] != chip->audio_monitor_active[audio+1]) {
- vx_set_monitor_level(chip, audio, chip->audio_monitor[audio],
- !!ucontrol->value.integer.value[0]);
- vx_set_monitor_level(chip, audio+1, chip->audio_monitor[audio+1],
- !!ucontrol->value.integer.value[1]);
- mutex_unlock(&chip->mixer_mutex);
- return 1;
- }
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_audio_gain, -10975, 25, 0);
-
-static struct snd_kcontrol_new vx_control_audio_gain = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- /* name will be filled later */
- .info = vx_audio_gain_info,
- .get = vx_audio_gain_get,
- .put = vx_audio_gain_put,
- .tlv = { .p = db_scale_audio_gain },
-};
-static struct snd_kcontrol_new vx_control_output_switch = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Playback Switch",
- .info = vx_audio_sw_info,
- .get = vx_audio_sw_get,
- .put = vx_audio_sw_put
-};
-static struct snd_kcontrol_new vx_control_monitor_gain = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Monitoring Volume",
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .info = vx_audio_gain_info, /* shared */
- .get = vx_audio_monitor_get,
- .put = vx_audio_monitor_put,
- .tlv = { .p = db_scale_audio_gain },
-};
-static struct snd_kcontrol_new vx_control_monitor_switch = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Monitoring Switch",
- .info = vx_audio_sw_info, /* shared */
- .get = vx_monitor_sw_get,
- .put = vx_monitor_sw_put
-};
-
-
-/*
- * IEC958 status bits
- */
-static int vx_iec958_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int vx_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&chip->mixer_mutex);
- ucontrol->value.iec958.status[0] = (chip->uer_bits >> 0) & 0xff;
- ucontrol->value.iec958.status[1] = (chip->uer_bits >> 8) & 0xff;
- ucontrol->value.iec958.status[2] = (chip->uer_bits >> 16) & 0xff;
- ucontrol->value.iec958.status[3] = (chip->uer_bits >> 24) & 0xff;
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static int vx_iec958_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.iec958.status[0] = 0xff;
- ucontrol->value.iec958.status[1] = 0xff;
- ucontrol->value.iec958.status[2] = 0xff;
- ucontrol->value.iec958.status[3] = 0xff;
- return 0;
-}
-
-static int vx_iec958_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- unsigned int val;
-
- val = (ucontrol->value.iec958.status[0] << 0) |
- (ucontrol->value.iec958.status[1] << 8) |
- (ucontrol->value.iec958.status[2] << 16) |
- (ucontrol->value.iec958.status[3] << 24);
- mutex_lock(&chip->mixer_mutex);
- if (chip->uer_bits != val) {
- chip->uer_bits = val;
- vx_set_iec958_status(chip, val);
- mutex_unlock(&chip->mixer_mutex);
- return 1;
- }
- mutex_unlock(&chip->mixer_mutex);
- return 0;
-}
-
-static struct snd_kcontrol_new vx_control_iec958_mask = {
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
- .info = vx_iec958_info, /* shared */
- .get = vx_iec958_mask_get,
-};
-
-static struct snd_kcontrol_new vx_control_iec958 = {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
- .info = vx_iec958_info,
- .get = vx_iec958_get,
- .put = vx_iec958_put
-};
-
-
-/*
- * VU meter
- */
-
-#define METER_MAX 0xff
-#define METER_SHIFT 16
-
-static int vx_vu_meter_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = METER_MAX;
- return 0;
-}
-
-static int vx_vu_meter_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- struct vx_vu_meter meter[2];
- int audio = kcontrol->private_value & 0xff;
- int capture = (kcontrol->private_value >> 8) & 1;
-
- vx_get_audio_vu_meter(chip, audio, capture, meter);
- ucontrol->value.integer.value[0] = meter[0].vu_level >> METER_SHIFT;
- ucontrol->value.integer.value[1] = meter[1].vu_level >> METER_SHIFT;
- return 0;
-}
-
-static int vx_peak_meter_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- struct vx_vu_meter meter[2];
- int audio = kcontrol->private_value & 0xff;
- int capture = (kcontrol->private_value >> 8) & 1;
-
- vx_get_audio_vu_meter(chip, audio, capture, meter);
- ucontrol->value.integer.value[0] = meter[0].peak_level >> METER_SHIFT;
- ucontrol->value.integer.value[1] = meter[1].peak_level >> METER_SHIFT;
- return 0;
-}
-
-#define vx_saturation_info snd_ctl_boolean_stereo_info
-
-static int vx_saturation_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *chip = snd_kcontrol_chip(kcontrol);
- struct vx_vu_meter meter[2];
- int audio = kcontrol->private_value & 0xff;
-
- vx_get_audio_vu_meter(chip, audio, 1, meter); /* capture only */
- ucontrol->value.integer.value[0] = meter[0].saturated;
- ucontrol->value.integer.value[1] = meter[1].saturated;
- return 0;
-}
-
-static struct snd_kcontrol_new vx_control_vu_meter = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- /* name will be filled later */
- .info = vx_vu_meter_info,
- .get = vx_vu_meter_get,
-};
-
-static struct snd_kcontrol_new vx_control_peak_meter = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- /* name will be filled later */
- .info = vx_vu_meter_info, /* shared */
- .get = vx_peak_meter_get,
-};
-
-static struct snd_kcontrol_new vx_control_saturation = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input Saturation",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = vx_saturation_info,
- .get = vx_saturation_get,
-};
-
-
-
-/*
- *
- */
-
-int snd_vx_mixer_new(struct vx_core *chip)
-{
- unsigned int i, c;
- int err;
- struct snd_kcontrol_new temp;
- struct snd_card *card = chip->card;
- char name[32];
-
- strcpy(card->mixername, card->driver);
-
- /* output level controls */
- for (i = 0; i < chip->hw->num_outs; i++) {
- temp = vx_control_output_level;
- temp.index = i;
- temp.tlv.p = chip->hw->output_level_db_scale;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- }
-
- /* PCM volumes, switches, monitoring */
- for (i = 0; i < chip->hw->num_outs; i++) {
- int val = i * 2;
- temp = vx_control_audio_gain;
- temp.index = i;
- temp.name = "PCM Playback Volume";
- temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- temp = vx_control_output_switch;
- temp.index = i;
- temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- temp = vx_control_monitor_gain;
- temp.index = i;
- temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- temp = vx_control_monitor_switch;
- temp.index = i;
- temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- }
- for (i = 0; i < chip->hw->num_outs; i++) {
- temp = vx_control_audio_gain;
- temp.index = i;
- temp.name = "PCM Capture Volume";
- temp.private_value = (i * 2) | (1 << 8);
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- }
-
- /* Audio source */
- if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_audio_src, chip))) < 0)
- return err;
- /* clock mode */
- if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_clock_mode, chip))) < 0)
- return err;
- /* IEC958 controls */
- if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_iec958_mask, chip))) < 0)
- return err;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_iec958, chip))) < 0)
- return err;
- /* VU, peak, saturation meters */
- for (c = 0; c < 2; c++) {
- static char *dir[2] = { "Output", "Input" };
- for (i = 0; i < chip->hw->num_ins; i++) {
- int val = (i * 2) | (c << 8);
- if (c == 1) {
- temp = vx_control_saturation;
- temp.index = i;
- temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- }
- sprintf(name, "%s VU Meter", dir[c]);
- temp = vx_control_vu_meter;
- temp.index = i;
- temp.name = name;
- temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- sprintf(name, "%s Peak Meter", dir[c]);
- temp = vx_control_peak_meter;
- temp.index = i;
- temp.name = name;
- temp.private_value = val;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- }
- }
- vx_reset_audio_levels(chip);
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/drivers/vx/vx_pcm.c b/ANDROID_3.4.5/sound/drivers/vx/vx_pcm.c
deleted file mode 100644
index 5e897b23..00000000
--- a/ANDROID_3.4.5/sound/drivers/vx/vx_pcm.c
+++ /dev/null
@@ -1,1283 +0,0 @@
-/*
- * Driver for Digigram VX soundcards
- *
- * PCM part
- *
- * Copyright (c) 2002,2003 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
- * STRATEGY
- * for playback, we send series of "chunks", which size is equal with the
- * IBL size, typically 126 samples. at each end of chunk, the end-of-buffer
- * interrupt is notified, and the interrupt handler will feed the next chunk.
- *
- * the current position is calculated from the sample count RMH.
- * pipe->transferred is the counter of data which has been already transferred.
- * if this counter reaches to the period size, snd_pcm_period_elapsed() will
- * be issued.
- *
- * for capture, the situation is much easier.
- * to get a low latency response, we'll check the capture streams at each
- * interrupt (capture stream has no EOB notification). if the pending
- * data is accumulated to the period size, snd_pcm_period_elapsed() is
- * called and the pointer is updated.
- *
- * the current point of read buffer is kept in pipe->hw_ptr. note that
- * this is in bytes.
- *
- *
- * TODO
- * - linked trigger for full-duplex mode.
- * - scheduled action on the stream.
- */
-
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <sound/core.h>
-#include <sound/asoundef.h>
-#include <sound/pcm.h>
-#include <sound/vx_core.h>
-#include "vx_cmd.h"
-
-
-/*
- * read three pending pcm bytes via inb()
- */
-static void vx_pcm_read_per_bytes(struct vx_core *chip, struct snd_pcm_runtime *runtime,
- struct vx_pipe *pipe)
-{
- int offset = pipe->hw_ptr;
- unsigned char *buf = (unsigned char *)(runtime->dma_area + offset);
- *buf++ = vx_inb(chip, RXH);
- if (++offset >= pipe->buffer_bytes) {
- offset = 0;
- buf = (unsigned char *)runtime->dma_area;
- }
- *buf++ = vx_inb(chip, RXM);
- if (++offset >= pipe->buffer_bytes) {
- offset = 0;
- buf = (unsigned char *)runtime->dma_area;
- }
- *buf++ = vx_inb(chip, RXL);
- if (++offset >= pipe->buffer_bytes) {
- offset = 0;
- buf = (unsigned char *)runtime->dma_area;
- }
- pipe->hw_ptr = offset;
-}
-
-/*
- * vx_set_pcx_time - convert from the PC time to the RMH status time.
- * @pc_time: the pointer for the PC-time to set
- * @dsp_time: the pointer for RMH status time array
- */
-static void vx_set_pcx_time(struct vx_core *chip, pcx_time_t *pc_time,
- unsigned int *dsp_time)
-{
- dsp_time[0] = (unsigned int)((*pc_time) >> 24) & PCX_TIME_HI_MASK;
- dsp_time[1] = (unsigned int)(*pc_time) & MASK_DSP_WORD;
-}
-
-/*
- * vx_set_differed_time - set the differed time if specified
- * @rmh: the rmh record to modify
- * @pipe: the pipe to be checked
- *
- * if the pipe is programmed with the differed time, set the DSP time
- * on the rmh and changes its command length.
- *
- * returns the increase of the command length.
- */
-static int vx_set_differed_time(struct vx_core *chip, struct vx_rmh *rmh,
- struct vx_pipe *pipe)
-{
- /* Update The length added to the RMH command by the timestamp */
- if (! (pipe->differed_type & DC_DIFFERED_DELAY))
- return 0;
-
- /* Set the T bit */
- rmh->Cmd[0] |= DSP_DIFFERED_COMMAND_MASK;
-
- /* Time stamp is the 1st following parameter */
- vx_set_pcx_time(chip, &pipe->pcx_time, &rmh->Cmd[1]);
-
- /* Add the flags to a notified differed command */
- if (pipe->differed_type & DC_NOTIFY_DELAY)
- rmh->Cmd[1] |= NOTIFY_MASK_TIME_HIGH ;
-
- /* Add the flags to a multiple differed command */
- if (pipe->differed_type & DC_MULTIPLE_DELAY)
- rmh->Cmd[1] |= MULTIPLE_MASK_TIME_HIGH;
-
- /* Add the flags to a stream-time differed command */
- if (pipe->differed_type & DC_STREAM_TIME_DELAY)
- rmh->Cmd[1] |= STREAM_MASK_TIME_HIGH;
-
- rmh->LgCmd += 2;
- return 2;
-}
-
-/*
- * vx_set_stream_format - send the stream format command
- * @pipe: the affected pipe
- * @data: format bitmask
- */
-static int vx_set_stream_format(struct vx_core *chip, struct vx_pipe *pipe,
- unsigned int data)
-{
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, pipe->is_capture ?
- CMD_FORMAT_STREAM_IN : CMD_FORMAT_STREAM_OUT);
- rmh.Cmd[0] |= pipe->number << FIELD_SIZE;
-
- /* Command might be longer since we may have to add a timestamp */
- vx_set_differed_time(chip, &rmh, pipe);
-
- rmh.Cmd[rmh.LgCmd] = (data & 0xFFFFFF00) >> 8;
- rmh.Cmd[rmh.LgCmd + 1] = (data & 0xFF) << 16 /*| (datal & 0xFFFF00) >> 8*/;
- rmh.LgCmd += 2;
-
- return vx_send_msg(chip, &rmh);
-}
-
-
-/*
- * vx_set_format - set the format of a pipe
- * @pipe: the affected pipe
- * @runtime: pcm runtime instance to be referred
- *
- * returns 0 if successful, or a negative error code.
- */
-static int vx_set_format(struct vx_core *chip, struct vx_pipe *pipe,
- struct snd_pcm_runtime *runtime)
-{
- unsigned int header = HEADER_FMT_BASE;
-
- if (runtime->channels == 1)
- header |= HEADER_FMT_MONO;
- if (snd_pcm_format_little_endian(runtime->format))
- header |= HEADER_FMT_INTEL;
- if (runtime->rate < 32000 && runtime->rate > 11025)
- header |= HEADER_FMT_UPTO32;
- else if (runtime->rate <= 11025)
- header |= HEADER_FMT_UPTO11;
-
- switch (snd_pcm_format_physical_width(runtime->format)) {
- // case 8: break;
- case 16: header |= HEADER_FMT_16BITS; break;
- case 24: header |= HEADER_FMT_24BITS; break;
- default :
- snd_BUG();
- return -EINVAL;
- };
-
- return vx_set_stream_format(chip, pipe, header);
-}
-
-/*
- * set / query the IBL size
- */
-static int vx_set_ibl(struct vx_core *chip, struct vx_ibl_info *info)
-{
- int err;
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_IBL);
- rmh.Cmd[0] |= info->size & 0x03ffff;
- err = vx_send_msg(chip, &rmh);
- if (err < 0)
- return err;
- info->size = rmh.Stat[0];
- info->max_size = rmh.Stat[1];
- info->min_size = rmh.Stat[2];
- info->granularity = rmh.Stat[3];
- snd_printdd(KERN_DEBUG "vx_set_ibl: size = %d, max = %d, min = %d, gran = %d\n",
- info->size, info->max_size, info->min_size, info->granularity);
- return 0;
-}
-
-
-/*
- * vx_get_pipe_state - get the state of a pipe
- * @pipe: the pipe to be checked
- * @state: the pointer for the returned state
- *
- * checks the state of a given pipe, and stores the state (1 = running,
- * 0 = paused) on the given pointer.
- *
- * called from trigger callback only
- */
-static int vx_get_pipe_state(struct vx_core *chip, struct vx_pipe *pipe, int *state)
-{
- int err;
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_PIPE_STATE);
- vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
- err = vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
- if (! err)
- *state = (rmh.Stat[0] & (1 << pipe->number)) ? 1 : 0;
- return err;
-}
-
-
-/*
- * vx_query_hbuffer_size - query available h-buffer size in bytes
- * @pipe: the pipe to be checked
- *
- * return the available size on h-buffer in bytes,
- * or a negative error code.
- *
- * NOTE: calling this function always switches to the stream mode.
- * you'll need to disconnect the host to get back to the
- * normal mode.
- */
-static int vx_query_hbuffer_size(struct vx_core *chip, struct vx_pipe *pipe)
-{
- int result;
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_SIZE_HBUFFER);
- vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
- if (pipe->is_capture)
- rmh.Cmd[0] |= 0x00000001;
- result = vx_send_msg(chip, &rmh);
- if (! result)
- result = rmh.Stat[0] & 0xffff;
- return result;
-}
-
-
-/*
- * vx_pipe_can_start - query whether a pipe is ready for start
- * @pipe: the pipe to be checked
- *
- * return 1 if ready, 0 if not ready, and negative value on error.
- *
- * called from trigger callback only
- */
-static int vx_pipe_can_start(struct vx_core *chip, struct vx_pipe *pipe)
-{
- int err;
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_CAN_START_PIPE);
- vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
- rmh.Cmd[0] |= 1;
-
- err = vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
- if (! err) {
- if (rmh.Stat[0])
- err = 1;
- }
- return err;
-}
-
-/*
- * vx_conf_pipe - tell the pipe to stand by and wait for IRQA.
- * @pipe: the pipe to be configured
- */
-static int vx_conf_pipe(struct vx_core *chip, struct vx_pipe *pipe)
-{
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_CONF_PIPE);
- if (pipe->is_capture)
- rmh.Cmd[0] |= COMMAND_RECORD_MASK;
- rmh.Cmd[1] = 1 << pipe->number;
- return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
-}
-
-/*
- * vx_send_irqa - trigger IRQA
- */
-static int vx_send_irqa(struct vx_core *chip)
-{
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_SEND_IRQA);
- return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
-}
-
-
-#define MAX_WAIT_FOR_DSP 250
-/*
- * vx boards do not support inter-card sync, besides
- * only 126 samples require to be prepared before a pipe can start
- */
-#define CAN_START_DELAY 2 /* wait 2ms only before asking if the pipe is ready*/
-#define WAIT_STATE_DELAY 2 /* wait 2ms after irqA was requested and check if the pipe state toggled*/
-
-/*
- * vx_toggle_pipe - start / pause a pipe
- * @pipe: the pipe to be triggered
- * @state: start = 1, pause = 0
- *
- * called from trigger callback only
- *
- */
-static int vx_toggle_pipe(struct vx_core *chip, struct vx_pipe *pipe, int state)
-{
- int err, i, cur_state;
-
- /* Check the pipe is not already in the requested state */
- if (vx_get_pipe_state(chip, pipe, &cur_state) < 0)
- return -EBADFD;
- if (state == cur_state)
- return 0;
-
- /* If a start is requested, ask the DSP to get prepared
- * and wait for a positive acknowledge (when there are
- * enough sound buffer for this pipe)
- */
- if (state) {
- for (i = 0 ; i < MAX_WAIT_FOR_DSP; i++) {
- err = vx_pipe_can_start(chip, pipe);
- if (err > 0)
- break;
- /* Wait for a few, before asking again
- * to avoid flooding the DSP with our requests
- */
- mdelay(1);
- }
- }
-
- if ((err = vx_conf_pipe(chip, pipe)) < 0)
- return err;
-
- if ((err = vx_send_irqa(chip)) < 0)
- return err;
-
- /* If it completes successfully, wait for the pipes
- * reaching the expected state before returning
- * Check one pipe only (since they are synchronous)
- */
- for (i = 0; i < MAX_WAIT_FOR_DSP; i++) {
- err = vx_get_pipe_state(chip, pipe, &cur_state);
- if (err < 0 || cur_state == state)
- break;
- err = -EIO;
- mdelay(1);
- }
- return err < 0 ? -EIO : 0;
-}
-
-
-/*
- * vx_stop_pipe - stop a pipe
- * @pipe: the pipe to be stopped
- *
- * called from trigger callback only
- */
-static int vx_stop_pipe(struct vx_core *chip, struct vx_pipe *pipe)
-{
- struct vx_rmh rmh;
- vx_init_rmh(&rmh, CMD_STOP_PIPE);
- vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
- return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
-}
-
-
-/*
- * vx_alloc_pipe - allocate a pipe and initialize the pipe instance
- * @capture: 0 = playback, 1 = capture operation
- * @audioid: the audio id to be assigned
- * @num_audio: number of audio channels
- * @pipep: the returned pipe instance
- *
- * return 0 on success, or a negative error code.
- */
-static int vx_alloc_pipe(struct vx_core *chip, int capture,
- int audioid, int num_audio,
- struct vx_pipe **pipep)
-{
- int err;
- struct vx_pipe *pipe;
- struct vx_rmh rmh;
- int data_mode;
-
- *pipep = NULL;
- vx_init_rmh(&rmh, CMD_RES_PIPE);
- vx_set_pipe_cmd_params(&rmh, capture, audioid, num_audio);
-#if 0 // NYI
- if (underrun_skip_sound)
- rmh.Cmd[0] |= BIT_SKIP_SOUND;
-#endif // NYI
- data_mode = (chip->uer_bits & IEC958_AES0_NONAUDIO) != 0;
- if (! capture && data_mode)
- rmh.Cmd[0] |= BIT_DATA_MODE;
- err = vx_send_msg(chip, &rmh);
- if (err < 0)
- return err;
-
- /* initialize the pipe record */
- pipe = kzalloc(sizeof(*pipe), GFP_KERNEL);
- if (! pipe) {
- /* release the pipe */
- vx_init_rmh(&rmh, CMD_FREE_PIPE);
- vx_set_pipe_cmd_params(&rmh, capture, audioid, 0);
- vx_send_msg(chip, &rmh);
- return -ENOMEM;
- }
-
- /* the pipe index should be identical with the audio index */
- pipe->number = audioid;
- pipe->is_capture = capture;
- pipe->channels = num_audio;
- pipe->differed_type = 0;
- pipe->pcx_time = 0;
- pipe->data_mode = data_mode;
- *pipep = pipe;
-
- return 0;
-}
-
-
-/*
- * vx_free_pipe - release a pipe
- * @pipe: pipe to be released
- */
-static int vx_free_pipe(struct vx_core *chip, struct vx_pipe *pipe)
-{
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_FREE_PIPE);
- vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
- vx_send_msg(chip, &rmh);
-
- kfree(pipe);
- return 0;
-}
-
-
-/*
- * vx_start_stream - start the stream
- *
- * called from trigger callback only
- */
-static int vx_start_stream(struct vx_core *chip, struct vx_pipe *pipe)
-{
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_START_ONE_STREAM);
- vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number);
- vx_set_differed_time(chip, &rmh, pipe);
- return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
-}
-
-
-/*
- * vx_stop_stream - stop the stream
- *
- * called from trigger callback only
- */
-static int vx_stop_stream(struct vx_core *chip, struct vx_pipe *pipe)
-{
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_STOP_STREAM);
- vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number);
- return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */
-}
-
-
-/*
- * playback hw information
- */
-
-static struct snd_pcm_hardware vx_pcm_playback_hw = {
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID /*|*/
- /*SNDRV_PCM_INFO_RESUME*/),
- .formats = (/*SNDRV_PCM_FMTBIT_U8 |*/
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 5000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 126,
- .period_bytes_max = (128*1024),
- .periods_min = 2,
- .periods_max = VX_MAX_PERIODS,
- .fifo_size = 126,
-};
-
-
-static void vx_pcm_delayed_start(unsigned long arg);
-
-/*
- * vx_pcm_playback_open - open callback for playback
- */
-static int vx_pcm_playback_open(struct snd_pcm_substream *subs)
-{
- struct snd_pcm_runtime *runtime = subs->runtime;
- struct vx_core *chip = snd_pcm_substream_chip(subs);
- struct vx_pipe *pipe = NULL;
- unsigned int audio;
- int err;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return -EBUSY;
-
- audio = subs->pcm->device * 2;
- if (snd_BUG_ON(audio >= chip->audio_outs))
- return -EINVAL;
-
- /* playback pipe may have been already allocated for monitoring */
- pipe = chip->playback_pipes[audio];
- if (! pipe) {
- /* not allocated yet */
- err = vx_alloc_pipe(chip, 0, audio, 2, &pipe); /* stereo playback */
- if (err < 0)
- return err;
- chip->playback_pipes[audio] = pipe;
- }
- /* open for playback */
- pipe->references++;
-
- pipe->substream = subs;
- tasklet_init(&pipe->start_tq, vx_pcm_delayed_start, (unsigned long)subs);
- chip->playback_pipes[audio] = pipe;
-
- runtime->hw = vx_pcm_playback_hw;
- runtime->hw.period_bytes_min = chip->ibl.size;
- runtime->private_data = pipe;
-
- /* align to 4 bytes (otherwise will be problematic when 24bit is used) */
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 4);
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4);
-
- return 0;
-}
-
-/*
- * vx_pcm_playback_close - close callback for playback
- */
-static int vx_pcm_playback_close(struct snd_pcm_substream *subs)
-{
- struct vx_core *chip = snd_pcm_substream_chip(subs);
- struct vx_pipe *pipe;
-
- if (! subs->runtime->private_data)
- return -EINVAL;
-
- pipe = subs->runtime->private_data;
-
- if (--pipe->references == 0) {
- chip->playback_pipes[pipe->number] = NULL;
- vx_free_pipe(chip, pipe);
- }
-
- return 0;
-
-}
-
-
-/*
- * vx_notify_end_of_buffer - send "end-of-buffer" notifier at the given pipe
- * @pipe: the pipe to notify
- *
- * NB: call with a certain lock.
- */
-static int vx_notify_end_of_buffer(struct vx_core *chip, struct vx_pipe *pipe)
-{
- int err;
- struct vx_rmh rmh; /* use a temporary rmh here */
-
- /* Toggle Dsp Host Interface into Message mode */
- vx_send_rih_nolock(chip, IRQ_PAUSE_START_CONNECT);
- vx_init_rmh(&rmh, CMD_NOTIFY_END_OF_BUFFER);
- vx_set_stream_cmd_params(&rmh, 0, pipe->number);
- err = vx_send_msg_nolock(chip, &rmh);
- if (err < 0)
- return err;
- /* Toggle Dsp Host Interface back to sound transfer mode */
- vx_send_rih_nolock(chip, IRQ_PAUSE_START_CONNECT);
- return 0;
-}
-
-/*
- * vx_pcm_playback_transfer_chunk - transfer a single chunk
- * @subs: substream
- * @pipe: the pipe to transfer
- * @size: chunk size in bytes
- *
- * transfer a single buffer chunk. EOB notificaton is added after that.
- * called from the interrupt handler, too.
- *
- * return 0 if ok.
- */
-static int vx_pcm_playback_transfer_chunk(struct vx_core *chip,
- struct snd_pcm_runtime *runtime,
- struct vx_pipe *pipe, int size)
-{
- int space, err = 0;
-
- space = vx_query_hbuffer_size(chip, pipe);
- if (space < 0) {
- /* disconnect the host, SIZE_HBUF command always switches to the stream mode */
- vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT);
- snd_printd("error hbuffer\n");
- return space;
- }
- if (space < size) {
- vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT);
- snd_printd("no enough hbuffer space %d\n", space);
- return -EIO; /* XRUN */
- }
-
- /* we don't need irqsave here, because this function
- * is called from either trigger callback or irq handler
- */
- spin_lock(&chip->lock);
- vx_pseudo_dma_write(chip, runtime, pipe, size);
- err = vx_notify_end_of_buffer(chip, pipe);
- /* disconnect the host, SIZE_HBUF command always switches to the stream mode */
- vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT);
- spin_unlock(&chip->lock);
- return err;
-}
-
-/*
- * update the position of the given pipe.
- * pipe->position is updated and wrapped within the buffer size.
- * pipe->transferred is updated, too, but the size is not wrapped,
- * so that the caller can check the total transferred size later
- * (to call snd_pcm_period_elapsed).
- */
-static int vx_update_pipe_position(struct vx_core *chip,
- struct snd_pcm_runtime *runtime,
- struct vx_pipe *pipe)
-{
- struct vx_rmh rmh;
- int err, update;
- u64 count;
-
- vx_init_rmh(&rmh, CMD_STREAM_SAMPLE_COUNT);
- vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
- err = vx_send_msg(chip, &rmh);
- if (err < 0)
- return err;
-
- count = ((u64)(rmh.Stat[0] & 0xfffff) << 24) | (u64)rmh.Stat[1];
- update = (int)(count - pipe->cur_count);
- pipe->cur_count = count;
- pipe->position += update;
- if (pipe->position >= (int)runtime->buffer_size)
- pipe->position %= runtime->buffer_size;
- pipe->transferred += update;
- return 0;
-}
-
-/*
- * transfer the pending playback buffer data to DSP
- * called from interrupt handler
- */
-static void vx_pcm_playback_transfer(struct vx_core *chip,
- struct snd_pcm_substream *subs,
- struct vx_pipe *pipe, int nchunks)
-{
- int i, err;
- struct snd_pcm_runtime *runtime = subs->runtime;
-
- if (! pipe->prepared || (chip->chip_status & VX_STAT_IS_STALE))
- return;
- for (i = 0; i < nchunks; i++) {
- if ((err = vx_pcm_playback_transfer_chunk(chip, runtime, pipe,
- chip->ibl.size)) < 0)
- return;
- }
-}
-
-/*
- * update the playback position and call snd_pcm_period_elapsed() if necessary
- * called from interrupt handler
- */
-static void vx_pcm_playback_update(struct vx_core *chip,
- struct snd_pcm_substream *subs,
- struct vx_pipe *pipe)
-{
- int err;
- struct snd_pcm_runtime *runtime = subs->runtime;
-
- if (pipe->running && ! (chip->chip_status & VX_STAT_IS_STALE)) {
- if ((err = vx_update_pipe_position(chip, runtime, pipe)) < 0)
- return;
- if (pipe->transferred >= (int)runtime->period_size) {
- pipe->transferred %= runtime->period_size;
- snd_pcm_period_elapsed(subs);
- }
- }
-}
-
-/*
- * start the stream and pipe.
- * this function is called from tasklet, which is invoked by the trigger
- * START callback.
- */
-static void vx_pcm_delayed_start(unsigned long arg)
-{
- struct snd_pcm_substream *subs = (struct snd_pcm_substream *)arg;
- struct vx_core *chip = subs->pcm->private_data;
- struct vx_pipe *pipe = subs->runtime->private_data;
- int err;
-
- /* printk( KERN_DEBUG "DDDD tasklet delayed start jiffies = %ld\n", jiffies);*/
-
- if ((err = vx_start_stream(chip, pipe)) < 0) {
- snd_printk(KERN_ERR "vx: cannot start stream\n");
- return;
- }
- if ((err = vx_toggle_pipe(chip, pipe, 1)) < 0) {
- snd_printk(KERN_ERR "vx: cannot start pipe\n");
- return;
- }
- /* printk( KERN_DEBUG "dddd tasklet delayed start jiffies = %ld \n", jiffies);*/
-}
-
-/*
- * vx_pcm_playback_trigger - trigger callback for playback
- */
-static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
-{
- struct vx_core *chip = snd_pcm_substream_chip(subs);
- struct vx_pipe *pipe = subs->runtime->private_data;
- int err;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return -EBUSY;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- if (! pipe->is_capture)
- vx_pcm_playback_transfer(chip, subs, pipe, 2);
- /* FIXME:
- * we trigger the pipe using tasklet, so that the interrupts are
- * issued surely after the trigger is completed.
- */
- tasklet_schedule(&pipe->start_tq);
- chip->pcm_running++;
- pipe->running = 1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- vx_toggle_pipe(chip, pipe, 0);
- vx_stop_pipe(chip, pipe);
- vx_stop_stream(chip, pipe);
- chip->pcm_running--;
- pipe->running = 0;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if ((err = vx_toggle_pipe(chip, pipe, 0)) < 0)
- return err;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if ((err = vx_toggle_pipe(chip, pipe, 1)) < 0)
- return err;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-/*
- * vx_pcm_playback_pointer - pointer callback for playback
- */
-static snd_pcm_uframes_t vx_pcm_playback_pointer(struct snd_pcm_substream *subs)
-{
- struct snd_pcm_runtime *runtime = subs->runtime;
- struct vx_pipe *pipe = runtime->private_data;
- return pipe->position;
-}
-
-/*
- * vx_pcm_hw_params - hw_params callback for playback and capture
- */
-static int vx_pcm_hw_params(struct snd_pcm_substream *subs,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_alloc_vmalloc_32_buffer
- (subs, params_buffer_bytes(hw_params));
-}
-
-/*
- * vx_pcm_hw_free - hw_free callback for playback and capture
- */
-static int vx_pcm_hw_free(struct snd_pcm_substream *subs)
-{
- return snd_pcm_lib_free_vmalloc_buffer(subs);
-}
-
-/*
- * vx_pcm_prepare - prepare callback for playback and capture
- */
-static int vx_pcm_prepare(struct snd_pcm_substream *subs)
-{
- struct vx_core *chip = snd_pcm_substream_chip(subs);
- struct snd_pcm_runtime *runtime = subs->runtime;
- struct vx_pipe *pipe = runtime->private_data;
- int err, data_mode;
- // int max_size, nchunks;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return -EBUSY;
-
- data_mode = (chip->uer_bits & IEC958_AES0_NONAUDIO) != 0;
- if (data_mode != pipe->data_mode && ! pipe->is_capture) {
- /* IEC958 status (raw-mode) was changed */
- /* we reopen the pipe */
- struct vx_rmh rmh;
- snd_printdd(KERN_DEBUG "reopen the pipe with data_mode = %d\n", data_mode);
- vx_init_rmh(&rmh, CMD_FREE_PIPE);
- vx_set_pipe_cmd_params(&rmh, 0, pipe->number, 0);
- if ((err = vx_send_msg(chip, &rmh)) < 0)
- return err;
- vx_init_rmh(&rmh, CMD_RES_PIPE);
- vx_set_pipe_cmd_params(&rmh, 0, pipe->number, pipe->channels);
- if (data_mode)
- rmh.Cmd[0] |= BIT_DATA_MODE;
- if ((err = vx_send_msg(chip, &rmh)) < 0)
- return err;
- pipe->data_mode = data_mode;
- }
-
- if (chip->pcm_running && chip->freq != runtime->rate) {
- snd_printk(KERN_ERR "vx: cannot set different clock %d "
- "from the current %d\n", runtime->rate, chip->freq);
- return -EINVAL;
- }
- vx_set_clock(chip, runtime->rate);
-
- if ((err = vx_set_format(chip, pipe, runtime)) < 0)
- return err;
-
- if (vx_is_pcmcia(chip)) {
- pipe->align = 2; /* 16bit word */
- } else {
- pipe->align = 4; /* 32bit word */
- }
-
- pipe->buffer_bytes = frames_to_bytes(runtime, runtime->buffer_size);
- pipe->period_bytes = frames_to_bytes(runtime, runtime->period_size);
- pipe->hw_ptr = 0;
-
- /* set the timestamp */
- vx_update_pipe_position(chip, runtime, pipe);
- /* clear again */
- pipe->transferred = 0;
- pipe->position = 0;
-
- pipe->prepared = 1;
-
- return 0;
-}
-
-
-/*
- * operators for PCM playback
- */
-static struct snd_pcm_ops vx_pcm_playback_ops = {
- .open = vx_pcm_playback_open,
- .close = vx_pcm_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = vx_pcm_hw_params,
- .hw_free = vx_pcm_hw_free,
- .prepare = vx_pcm_prepare,
- .trigger = vx_pcm_trigger,
- .pointer = vx_pcm_playback_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
-};
-
-
-/*
- * playback hw information
- */
-
-static struct snd_pcm_hardware vx_pcm_capture_hw = {
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID /*|*/
- /*SNDRV_PCM_INFO_RESUME*/),
- .formats = (/*SNDRV_PCM_FMTBIT_U8 |*/
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 5000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 126,
- .period_bytes_max = (128*1024),
- .periods_min = 2,
- .periods_max = VX_MAX_PERIODS,
- .fifo_size = 126,
-};
-
-
-/*
- * vx_pcm_capture_open - open callback for capture
- */
-static int vx_pcm_capture_open(struct snd_pcm_substream *subs)
-{
- struct snd_pcm_runtime *runtime = subs->runtime;
- struct vx_core *chip = snd_pcm_substream_chip(subs);
- struct vx_pipe *pipe;
- struct vx_pipe *pipe_out_monitoring = NULL;
- unsigned int audio;
- int err;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return -EBUSY;
-
- audio = subs->pcm->device * 2;
- if (snd_BUG_ON(audio >= chip->audio_ins))
- return -EINVAL;
- err = vx_alloc_pipe(chip, 1, audio, 2, &pipe);
- if (err < 0)
- return err;
- pipe->substream = subs;
- tasklet_init(&pipe->start_tq, vx_pcm_delayed_start, (unsigned long)subs);
- chip->capture_pipes[audio] = pipe;
-
- /* check if monitoring is needed */
- if (chip->audio_monitor_active[audio]) {
- pipe_out_monitoring = chip->playback_pipes[audio];
- if (! pipe_out_monitoring) {
- /* allocate a pipe */
- err = vx_alloc_pipe(chip, 0, audio, 2, &pipe_out_monitoring);
- if (err < 0)
- return err;
- chip->playback_pipes[audio] = pipe_out_monitoring;
- }
- pipe_out_monitoring->references++;
- /*
- if an output pipe is available, it's audios still may need to be
- unmuted. hence we'll have to call a mixer entry point.
- */
- vx_set_monitor_level(chip, audio, chip->audio_monitor[audio],
- chip->audio_monitor_active[audio]);
- /* assuming stereo */
- vx_set_monitor_level(chip, audio+1, chip->audio_monitor[audio+1],
- chip->audio_monitor_active[audio+1]);
- }
-
- pipe->monitoring_pipe = pipe_out_monitoring; /* default value NULL */
-
- runtime->hw = vx_pcm_capture_hw;
- runtime->hw.period_bytes_min = chip->ibl.size;
- runtime->private_data = pipe;
-
- /* align to 4 bytes (otherwise will be problematic when 24bit is used) */
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 4);
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4);
-
- return 0;
-}
-
-/*
- * vx_pcm_capture_close - close callback for capture
- */
-static int vx_pcm_capture_close(struct snd_pcm_substream *subs)
-{
- struct vx_core *chip = snd_pcm_substream_chip(subs);
- struct vx_pipe *pipe;
- struct vx_pipe *pipe_out_monitoring;
-
- if (! subs->runtime->private_data)
- return -EINVAL;
- pipe = subs->runtime->private_data;
- chip->capture_pipes[pipe->number] = NULL;
-
- pipe_out_monitoring = pipe->monitoring_pipe;
-
- /*
- if an output pipe is attached to this input,
- check if it needs to be released.
- */
- if (pipe_out_monitoring) {
- if (--pipe_out_monitoring->references == 0) {
- vx_free_pipe(chip, pipe_out_monitoring);
- chip->playback_pipes[pipe->number] = NULL;
- pipe->monitoring_pipe = NULL;
- }
- }
-
- vx_free_pipe(chip, pipe);
- return 0;
-}
-
-
-
-#define DMA_READ_ALIGN 6 /* hardware alignment for read */
-
-/*
- * vx_pcm_capture_update - update the capture buffer
- */
-static void vx_pcm_capture_update(struct vx_core *chip, struct snd_pcm_substream *subs,
- struct vx_pipe *pipe)
-{
- int size, space, count;
- struct snd_pcm_runtime *runtime = subs->runtime;
-
- if (! pipe->prepared || (chip->chip_status & VX_STAT_IS_STALE))
- return;
-
- size = runtime->buffer_size - snd_pcm_capture_avail(runtime);
- if (! size)
- return;
- size = frames_to_bytes(runtime, size);
- space = vx_query_hbuffer_size(chip, pipe);
- if (space < 0)
- goto _error;
- if (size > space)
- size = space;
- size = (size / 3) * 3; /* align to 3 bytes */
- if (size < DMA_READ_ALIGN)
- goto _error;
-
- /* keep the last 6 bytes, they will be read after disconnection */
- count = size - DMA_READ_ALIGN;
- /* read bytes until the current pointer reaches to the aligned position
- * for word-transfer
- */
- while (count > 0) {
- if ((pipe->hw_ptr % pipe->align) == 0)
- break;
- if (vx_wait_for_rx_full(chip) < 0)
- goto _error;
- vx_pcm_read_per_bytes(chip, runtime, pipe);
- count -= 3;
- }
- if (count > 0) {
- /* ok, let's accelerate! */
- int align = pipe->align * 3;
- space = (count / align) * align;
- vx_pseudo_dma_read(chip, runtime, pipe, space);
- count -= space;
- }
- /* read the rest of bytes */
- while (count > 0) {
- if (vx_wait_for_rx_full(chip) < 0)
- goto _error;
- vx_pcm_read_per_bytes(chip, runtime, pipe);
- count -= 3;
- }
- /* disconnect the host, SIZE_HBUF command always switches to the stream mode */
- vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT);
- /* read the last pending 6 bytes */
- count = DMA_READ_ALIGN;
- while (count > 0) {
- vx_pcm_read_per_bytes(chip, runtime, pipe);
- count -= 3;
- }
- /* update the position */
- pipe->transferred += size;
- if (pipe->transferred >= pipe->period_bytes) {
- pipe->transferred %= pipe->period_bytes;
- snd_pcm_period_elapsed(subs);
- }
- return;
-
- _error:
- /* disconnect the host, SIZE_HBUF command always switches to the stream mode */
- vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT);
- return;
-}
-
-/*
- * vx_pcm_capture_pointer - pointer callback for capture
- */
-static snd_pcm_uframes_t vx_pcm_capture_pointer(struct snd_pcm_substream *subs)
-{
- struct snd_pcm_runtime *runtime = subs->runtime;
- struct vx_pipe *pipe = runtime->private_data;
- return bytes_to_frames(runtime, pipe->hw_ptr);
-}
-
-/*
- * operators for PCM capture
- */
-static struct snd_pcm_ops vx_pcm_capture_ops = {
- .open = vx_pcm_capture_open,
- .close = vx_pcm_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = vx_pcm_hw_params,
- .hw_free = vx_pcm_hw_free,
- .prepare = vx_pcm_prepare,
- .trigger = vx_pcm_trigger,
- .pointer = vx_pcm_capture_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
-};
-
-
-/*
- * interrupt handler for pcm streams
- */
-void vx_pcm_update_intr(struct vx_core *chip, unsigned int events)
-{
- unsigned int i;
- struct vx_pipe *pipe;
-
-#define EVENT_MASK (END_OF_BUFFER_EVENTS_PENDING|ASYNC_EVENTS_PENDING)
-
- if (events & EVENT_MASK) {
- vx_init_rmh(&chip->irq_rmh, CMD_ASYNC);
- if (events & ASYNC_EVENTS_PENDING)
- chip->irq_rmh.Cmd[0] |= 0x00000001; /* SEL_ASYNC_EVENTS */
- if (events & END_OF_BUFFER_EVENTS_PENDING)
- chip->irq_rmh.Cmd[0] |= 0x00000002; /* SEL_END_OF_BUF_EVENTS */
-
- if (vx_send_msg(chip, &chip->irq_rmh) < 0) {
- snd_printdd(KERN_ERR "msg send error!!\n");
- return;
- }
-
- i = 1;
- while (i < chip->irq_rmh.LgStat) {
- int p, buf, capture, eob;
- p = chip->irq_rmh.Stat[i] & MASK_FIRST_FIELD;
- capture = (chip->irq_rmh.Stat[i] & 0x400000) ? 1 : 0;
- eob = (chip->irq_rmh.Stat[i] & 0x800000) ? 1 : 0;
- i++;
- if (events & ASYNC_EVENTS_PENDING)
- i++;
- buf = 1; /* force to transfer */
- if (events & END_OF_BUFFER_EVENTS_PENDING) {
- if (eob)
- buf = chip->irq_rmh.Stat[i];
- i++;
- }
- if (capture)
- continue;
- if (snd_BUG_ON(p < 0 || p >= chip->audio_outs))
- continue;
- pipe = chip->playback_pipes[p];
- if (pipe && pipe->substream) {
- vx_pcm_playback_update(chip, pipe->substream, pipe);
- vx_pcm_playback_transfer(chip, pipe->substream, pipe, buf);
- }
- }
- }
-
- /* update the capture pcm pointers as frequently as possible */
- for (i = 0; i < chip->audio_ins; i++) {
- pipe = chip->capture_pipes[i];
- if (pipe && pipe->substream)
- vx_pcm_capture_update(chip, pipe->substream, pipe);
- }
-}
-
-
-/*
- * vx_init_audio_io - check the available audio i/o and allocate pipe arrays
- */
-static int vx_init_audio_io(struct vx_core *chip)
-{
- struct vx_rmh rmh;
- int preferred;
-
- vx_init_rmh(&rmh, CMD_SUPPORTED);
- if (vx_send_msg(chip, &rmh) < 0) {
- snd_printk(KERN_ERR "vx: cannot get the supported audio data\n");
- return -ENXIO;
- }
-
- chip->audio_outs = rmh.Stat[0] & MASK_FIRST_FIELD;
- chip->audio_ins = (rmh.Stat[0] >> (FIELD_SIZE*2)) & MASK_FIRST_FIELD;
- chip->audio_info = rmh.Stat[1];
-
- /* allocate pipes */
- chip->playback_pipes = kcalloc(chip->audio_outs, sizeof(struct vx_pipe *), GFP_KERNEL);
- if (!chip->playback_pipes)
- return -ENOMEM;
- chip->capture_pipes = kcalloc(chip->audio_ins, sizeof(struct vx_pipe *), GFP_KERNEL);
- if (!chip->capture_pipes) {
- kfree(chip->playback_pipes);
- return -ENOMEM;
- }
-
- preferred = chip->ibl.size;
- chip->ibl.size = 0;
- vx_set_ibl(chip, &chip->ibl); /* query the info */
- if (preferred > 0) {
- chip->ibl.size = ((preferred + chip->ibl.granularity - 1) /
- chip->ibl.granularity) * chip->ibl.granularity;
- if (chip->ibl.size > chip->ibl.max_size)
- chip->ibl.size = chip->ibl.max_size;
- } else
- chip->ibl.size = chip->ibl.min_size; /* set to the minimum */
- vx_set_ibl(chip, &chip->ibl);
-
- return 0;
-}
-
-
-/*
- * free callback for pcm
- */
-static void snd_vx_pcm_free(struct snd_pcm *pcm)
-{
- struct vx_core *chip = pcm->private_data;
- chip->pcm[pcm->device] = NULL;
- kfree(chip->playback_pipes);
- chip->playback_pipes = NULL;
- kfree(chip->capture_pipes);
- chip->capture_pipes = NULL;
-}
-
-/*
- * snd_vx_pcm_new - create and initialize a pcm
- */
-int snd_vx_pcm_new(struct vx_core *chip)
-{
- struct snd_pcm *pcm;
- unsigned int i;
- int err;
-
- if ((err = vx_init_audio_io(chip)) < 0)
- return err;
-
- for (i = 0; i < chip->hw->num_codecs; i++) {
- unsigned int outs, ins;
- outs = chip->audio_outs > i * 2 ? 1 : 0;
- ins = chip->audio_ins > i * 2 ? 1 : 0;
- if (! outs && ! ins)
- break;
- err = snd_pcm_new(chip->card, "VX PCM", i,
- outs, ins, &pcm);
- if (err < 0)
- return err;
- if (outs)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &vx_pcm_playback_ops);
- if (ins)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &vx_pcm_capture_ops);
-
- pcm->private_data = chip;
- pcm->private_free = snd_vx_pcm_free;
- pcm->info_flags = 0;
- strcpy(pcm->name, chip->card->shortname);
- chip->pcm[i] = pcm;
- }
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/drivers/vx/vx_uer.c b/ANDROID_3.4.5/sound/drivers/vx/vx_uer.c
deleted file mode 100644
index b0560fec..00000000
--- a/ANDROID_3.4.5/sound/drivers/vx/vx_uer.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Driver for Digigram VX soundcards
- *
- * IEC958 stuff
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/delay.h>
-#include <sound/core.h>
-#include <sound/vx_core.h>
-#include "vx_cmd.h"
-
-
-/*
- * vx_modify_board_clock - tell the board that its clock has been modified
- * @sync: DSP needs to resynchronize its FIFO
- */
-static int vx_modify_board_clock(struct vx_core *chip, int sync)
-{
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_MODIFY_CLOCK);
- /* Ask the DSP to resynchronize its FIFO. */
- if (sync)
- rmh.Cmd[0] |= CMD_MODIFY_CLOCK_S_BIT;
- return vx_send_msg(chip, &rmh);
-}
-
-/*
- * vx_modify_board_inputs - resync audio inputs
- */
-static int vx_modify_board_inputs(struct vx_core *chip)
-{
- struct vx_rmh rmh;
-
- vx_init_rmh(&rmh, CMD_RESYNC_AUDIO_INPUTS);
- rmh.Cmd[0] |= 1 << 0; /* reference: AUDIO 0 */
- return vx_send_msg(chip, &rmh);
-}
-
-/*
- * vx_read_one_cbit - read one bit from UER config
- * @index: the bit index
- * returns 0 or 1.
- */
-static int vx_read_one_cbit(struct vx_core *chip, int index)
-{
- unsigned long flags;
- int val;
- spin_lock_irqsave(&chip->lock, flags);
- if (chip->type >= VX_TYPE_VXPOCKET) {
- vx_outb(chip, CSUER, 1); /* read */
- vx_outb(chip, RUER, index & XX_UER_CBITS_OFFSET_MASK);
- val = (vx_inb(chip, RUER) >> 7) & 0x01;
- } else {
- vx_outl(chip, CSUER, 1); /* read */
- vx_outl(chip, RUER, index & XX_UER_CBITS_OFFSET_MASK);
- val = (vx_inl(chip, RUER) >> 7) & 0x01;
- }
- spin_unlock_irqrestore(&chip->lock, flags);
- return val;
-}
-
-/*
- * vx_write_one_cbit - write one bit to UER config
- * @index: the bit index
- * @val: bit value, 0 or 1
- */
-static void vx_write_one_cbit(struct vx_core *chip, int index, int val)
-{
- unsigned long flags;
- val = !!val; /* 0 or 1 */
- spin_lock_irqsave(&chip->lock, flags);
- if (vx_is_pcmcia(chip)) {
- vx_outb(chip, CSUER, 0); /* write */
- vx_outb(chip, RUER, (val << 7) | (index & XX_UER_CBITS_OFFSET_MASK));
- } else {
- vx_outl(chip, CSUER, 0); /* write */
- vx_outl(chip, RUER, (val << 7) | (index & XX_UER_CBITS_OFFSET_MASK));
- }
- spin_unlock_irqrestore(&chip->lock, flags);
-}
-
-/*
- * vx_read_uer_status - read the current UER status
- * @mode: pointer to store the UER mode, VX_UER_MODE_XXX
- *
- * returns the frequency of UER, or 0 if not sync,
- * or a negative error code.
- */
-static int vx_read_uer_status(struct vx_core *chip, unsigned int *mode)
-{
- int val, freq;
-
- /* Default values */
- freq = 0;
-
- /* Read UER status */
- if (vx_is_pcmcia(chip))
- val = vx_inb(chip, CSUER);
- else
- val = vx_inl(chip, CSUER);
- if (val < 0)
- return val;
- /* If clock is present, read frequency */
- if (val & VX_SUER_CLOCK_PRESENT_MASK) {
- switch (val & VX_SUER_FREQ_MASK) {
- case VX_SUER_FREQ_32KHz_MASK:
- freq = 32000;
- break;
- case VX_SUER_FREQ_44KHz_MASK:
- freq = 44100;
- break;
- case VX_SUER_FREQ_48KHz_MASK:
- freq = 48000;
- break;
- }
- }
- if (val & VX_SUER_DATA_PRESENT_MASK)
- /* bit 0 corresponds to consumer/professional bit */
- *mode = vx_read_one_cbit(chip, 0) ?
- VX_UER_MODE_PROFESSIONAL : VX_UER_MODE_CONSUMER;
- else
- *mode = VX_UER_MODE_NOT_PRESENT;
-
- return freq;
-}
-
-
-/*
- * compute the sample clock value from frequency
- *
- * The formula is as follows:
- *
- * HexFreq = (dword) ((double) ((double) 28224000 / (double) Frequency))
- * switch ( HexFreq & 0x00000F00 )
- * case 0x00000100: ;
- * case 0x00000200:
- * case 0x00000300: HexFreq -= 0x00000201 ;
- * case 0x00000400:
- * case 0x00000500:
- * case 0x00000600:
- * case 0x00000700: HexFreq = (dword) (((double) 28224000 / (double) (Frequency*2)) - 1)
- * default : HexFreq = (dword) ((double) 28224000 / (double) (Frequency*4)) - 0x000001FF
- */
-
-static int vx_calc_clock_from_freq(struct vx_core *chip, int freq)
-{
- int hexfreq;
-
- if (snd_BUG_ON(freq <= 0))
- return 0;
-
- hexfreq = (28224000 * 10) / freq;
- hexfreq = (hexfreq + 5) / 10;
-
- /* max freq = 55125 Hz */
- if (snd_BUG_ON(hexfreq <= 0x00000200))
- return 0;
-
- if (hexfreq <= 0x03ff)
- return hexfreq - 0x00000201;
- if (hexfreq <= 0x07ff)
- return (hexfreq / 2) - 1;
- if (hexfreq <= 0x0fff)
- return (hexfreq / 4) + 0x000001ff;
-
- return 0x5fe; /* min freq = 6893 Hz */
-}
-
-
-/*
- * vx_change_clock_source - change the clock source
- * @source: the new source
- */
-static void vx_change_clock_source(struct vx_core *chip, int source)
-{
- unsigned long flags;
-
- /* we mute DAC to prevent clicks */
- vx_toggle_dac_mute(chip, 1);
- spin_lock_irqsave(&chip->lock, flags);
- chip->ops->set_clock_source(chip, source);
- chip->clock_source = source;
- spin_unlock_irqrestore(&chip->lock, flags);
- /* unmute */
- vx_toggle_dac_mute(chip, 0);
-}
-
-
-/*
- * set the internal clock
- */
-void vx_set_internal_clock(struct vx_core *chip, unsigned int freq)
-{
- int clock;
- unsigned long flags;
- /* Get real clock value */
- clock = vx_calc_clock_from_freq(chip, freq);
- snd_printdd(KERN_DEBUG "set internal clock to 0x%x from freq %d\n", clock, freq);
- spin_lock_irqsave(&chip->lock, flags);
- if (vx_is_pcmcia(chip)) {
- vx_outb(chip, HIFREQ, (clock >> 8) & 0x0f);
- vx_outb(chip, LOFREQ, clock & 0xff);
- } else {
- vx_outl(chip, HIFREQ, (clock >> 8) & 0x0f);
- vx_outl(chip, LOFREQ, clock & 0xff);
- }
- spin_unlock_irqrestore(&chip->lock, flags);
-}
-
-
-/*
- * set the iec958 status bits
- * @bits: 32-bit status bits
- */
-void vx_set_iec958_status(struct vx_core *chip, unsigned int bits)
-{
- int i;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return;
-
- for (i = 0; i < 32; i++)
- vx_write_one_cbit(chip, i, bits & (1 << i));
-}
-
-
-/*
- * vx_set_clock - change the clock and audio source if necessary
- */
-int vx_set_clock(struct vx_core *chip, unsigned int freq)
-{
- int src_changed = 0;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return 0;
-
- /* change the audio source if possible */
- vx_sync_audio_source(chip);
-
- if (chip->clock_mode == VX_CLOCK_MODE_EXTERNAL ||
- (chip->clock_mode == VX_CLOCK_MODE_AUTO &&
- chip->audio_source == VX_AUDIO_SRC_DIGITAL)) {
- if (chip->clock_source != UER_SYNC) {
- vx_change_clock_source(chip, UER_SYNC);
- mdelay(6);
- src_changed = 1;
- }
- } else if (chip->clock_mode == VX_CLOCK_MODE_INTERNAL ||
- (chip->clock_mode == VX_CLOCK_MODE_AUTO &&
- chip->audio_source != VX_AUDIO_SRC_DIGITAL)) {
- if (chip->clock_source != INTERNAL_QUARTZ) {
- vx_change_clock_source(chip, INTERNAL_QUARTZ);
- src_changed = 1;
- }
- if (chip->freq == freq)
- return 0;
- vx_set_internal_clock(chip, freq);
- if (src_changed)
- vx_modify_board_inputs(chip);
- }
- if (chip->freq == freq)
- return 0;
- chip->freq = freq;
- vx_modify_board_clock(chip, 1);
- return 0;
-}
-
-
-/*
- * vx_change_frequency - called from interrupt handler
- */
-int vx_change_frequency(struct vx_core *chip)
-{
- int freq;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return 0;
-
- if (chip->clock_source == INTERNAL_QUARTZ)
- return 0;
- /*
- * Read the real UER board frequency
- */
- freq = vx_read_uer_status(chip, &chip->uer_detected);
- if (freq < 0)
- return freq;
- /*
- * The frequency computed by the DSP is good and
- * is different from the previous computed.
- */
- if (freq == 48000 || freq == 44100 || freq == 32000)
- chip->freq_detected = freq;
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/firewire/Kconfig b/ANDROID_3.4.5/sound/firewire/Kconfig
deleted file mode 100644
index 26071489..00000000
--- a/ANDROID_3.4.5/sound/firewire/Kconfig
+++ /dev/null
@@ -1,36 +0,0 @@
-menuconfig SND_FIREWIRE
- bool "FireWire sound devices"
- depends on FIREWIRE
- default y
- help
- Support for IEEE-1394/FireWire/iLink sound devices.
-
-if SND_FIREWIRE && FIREWIRE
-
-config SND_FIREWIRE_LIB
- tristate
- depends on SND_PCM
-
-config SND_FIREWIRE_SPEAKERS
- tristate "FireWire speakers"
- select SND_PCM
- select SND_FIREWIRE_LIB
- help
- Say Y here to include support for the Griffin FireWave Surround
- and the LaCie FireWire Speakers.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-firewire-speakers.
-
-config SND_ISIGHT
- tristate "Apple iSight microphone"
- select SND_PCM
- select SND_FIREWIRE_LIB
- help
- Say Y here to include support for the front and rear microphones
- of the Apple iSight web camera.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-isight.
-
-endif # SND_FIREWIRE
diff --git a/ANDROID_3.4.5/sound/firewire/Makefile b/ANDROID_3.4.5/sound/firewire/Makefile
deleted file mode 100644
index d71ed893..00000000
--- a/ANDROID_3.4.5/sound/firewire/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-snd-firewire-lib-objs := lib.o iso-resources.o packets-buffer.o \
- fcp.o cmp.o amdtp.o
-snd-firewire-speakers-objs := speakers.o
-snd-isight-objs := isight.o
-
-obj-$(CONFIG_SND_FIREWIRE_LIB) += snd-firewire-lib.o
-obj-$(CONFIG_SND_FIREWIRE_SPEAKERS) += snd-firewire-speakers.o
-obj-$(CONFIG_SND_ISIGHT) += snd-isight.o
diff --git a/ANDROID_3.4.5/sound/firewire/amdtp.c b/ANDROID_3.4.5/sound/firewire/amdtp.c
deleted file mode 100644
index 87657dd7..00000000
--- a/ANDROID_3.4.5/sound/firewire/amdtp.c
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * Audio and Music Data Transmission Protocol (IEC 61883-6) streams
- * with Common Isochronous Packet (IEC 61883-1) headers
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- * Licensed under the terms of the GNU General Public License, version 2.
- */
-
-#include <linux/device.h>
-#include <linux/err.h>
-#include <linux/firewire.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <sound/pcm.h>
-#include "amdtp.h"
-
-#define TICKS_PER_CYCLE 3072
-#define CYCLES_PER_SECOND 8000
-#define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND)
-
-#define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 µs */
-
-#define TAG_CIP 1
-
-#define CIP_EOH (1u << 31)
-#define CIP_FMT_AM (0x10 << 24)
-#define AMDTP_FDF_AM824 (0 << 19)
-#define AMDTP_FDF_SFC_SHIFT 16
-
-/* TODO: make these configurable */
-#define INTERRUPT_INTERVAL 16
-#define QUEUE_LENGTH 48
-
-/**
- * amdtp_out_stream_init - initialize an AMDTP output stream structure
- * @s: the AMDTP output stream to initialize
- * @unit: the target of the stream
- * @flags: the packet transmission method to use
- */
-int amdtp_out_stream_init(struct amdtp_out_stream *s, struct fw_unit *unit,
- enum cip_out_flags flags)
-{
- if (flags != CIP_NONBLOCKING)
- return -EINVAL;
-
- s->unit = fw_unit_get(unit);
- s->flags = flags;
- s->context = ERR_PTR(-1);
- mutex_init(&s->mutex);
- s->packet_index = 0;
-
- return 0;
-}
-EXPORT_SYMBOL(amdtp_out_stream_init);
-
-/**
- * amdtp_out_stream_destroy - free stream resources
- * @s: the AMDTP output stream to destroy
- */
-void amdtp_out_stream_destroy(struct amdtp_out_stream *s)
-{
- WARN_ON(!IS_ERR(s->context));
- mutex_destroy(&s->mutex);
- fw_unit_put(s->unit);
-}
-EXPORT_SYMBOL(amdtp_out_stream_destroy);
-
-/**
- * amdtp_out_stream_set_rate - set the sample rate
- * @s: the AMDTP output stream to configure
- * @rate: the sample rate
- *
- * The sample rate must be set before the stream is started, and must not be
- * changed while the stream is running.
- */
-void amdtp_out_stream_set_rate(struct amdtp_out_stream *s, unsigned int rate)
-{
- static const struct {
- unsigned int rate;
- unsigned int syt_interval;
- } rate_info[] = {
- [CIP_SFC_32000] = { 32000, 8, },
- [CIP_SFC_44100] = { 44100, 8, },
- [CIP_SFC_48000] = { 48000, 8, },
- [CIP_SFC_88200] = { 88200, 16, },
- [CIP_SFC_96000] = { 96000, 16, },
- [CIP_SFC_176400] = { 176400, 32, },
- [CIP_SFC_192000] = { 192000, 32, },
- };
- unsigned int sfc;
-
- if (WARN_ON(!IS_ERR(s->context)))
- return;
-
- for (sfc = 0; sfc < ARRAY_SIZE(rate_info); ++sfc)
- if (rate_info[sfc].rate == rate) {
- s->sfc = sfc;
- s->syt_interval = rate_info[sfc].syt_interval;
- return;
- }
- WARN_ON(1);
-}
-EXPORT_SYMBOL(amdtp_out_stream_set_rate);
-
-/**
- * amdtp_out_stream_get_max_payload - get the stream's packet size
- * @s: the AMDTP output stream
- *
- * This function must not be called before the stream has been configured
- * with amdtp_out_stream_set_hw_params(), amdtp_out_stream_set_pcm(), and
- * amdtp_out_stream_set_midi().
- */
-unsigned int amdtp_out_stream_get_max_payload(struct amdtp_out_stream *s)
-{
- static const unsigned int max_data_blocks[] = {
- [CIP_SFC_32000] = 4,
- [CIP_SFC_44100] = 6,
- [CIP_SFC_48000] = 6,
- [CIP_SFC_88200] = 12,
- [CIP_SFC_96000] = 12,
- [CIP_SFC_176400] = 23,
- [CIP_SFC_192000] = 24,
- };
-
- s->data_block_quadlets = s->pcm_channels;
- s->data_block_quadlets += DIV_ROUND_UP(s->midi_ports, 8);
-
- return 8 + max_data_blocks[s->sfc] * 4 * s->data_block_quadlets;
-}
-EXPORT_SYMBOL(amdtp_out_stream_get_max_payload);
-
-static void amdtp_write_s16(struct amdtp_out_stream *s,
- struct snd_pcm_substream *pcm,
- __be32 *buffer, unsigned int frames);
-static void amdtp_write_s32(struct amdtp_out_stream *s,
- struct snd_pcm_substream *pcm,
- __be32 *buffer, unsigned int frames);
-
-/**
- * amdtp_out_stream_set_pcm_format - set the PCM format
- * @s: the AMDTP output stream to configure
- * @format: the format of the ALSA PCM device
- *
- * The sample format must be set before the stream is started, and must not be
- * changed while the stream is running.
- */
-void amdtp_out_stream_set_pcm_format(struct amdtp_out_stream *s,
- snd_pcm_format_t format)
-{
- if (WARN_ON(!IS_ERR(s->context)))
- return;
-
- switch (format) {
- default:
- WARN_ON(1);
- /* fall through */
- case SNDRV_PCM_FORMAT_S16:
- s->transfer_samples = amdtp_write_s16;
- break;
- case SNDRV_PCM_FORMAT_S32:
- s->transfer_samples = amdtp_write_s32;
- break;
- }
-}
-EXPORT_SYMBOL(amdtp_out_stream_set_pcm_format);
-
-static unsigned int calculate_data_blocks(struct amdtp_out_stream *s)
-{
- unsigned int phase, data_blocks;
-
- if (!cip_sfc_is_base_44100(s->sfc)) {
- /* Sample_rate / 8000 is an integer, and precomputed. */
- data_blocks = s->data_block_state;
- } else {
- phase = s->data_block_state;
-
- /*
- * This calculates the number of data blocks per packet so that
- * 1) the overall rate is correct and exactly synchronized to
- * the bus clock, and
- * 2) packets with a rounded-up number of blocks occur as early
- * as possible in the sequence (to prevent underruns of the
- * device's buffer).
- */
- if (s->sfc == CIP_SFC_44100)
- /* 6 6 5 6 5 6 5 ... */
- data_blocks = 5 + ((phase & 1) ^
- (phase == 0 || phase >= 40));
- else
- /* 12 11 11 11 11 ... or 23 22 22 22 22 ... */
- data_blocks = 11 * (s->sfc >> 1) + (phase == 0);
- if (++phase >= (80 >> (s->sfc >> 1)))
- phase = 0;
- s->data_block_state = phase;
- }
-
- return data_blocks;
-}
-
-static unsigned int calculate_syt(struct amdtp_out_stream *s,
- unsigned int cycle)
-{
- unsigned int syt_offset, phase, index, syt;
-
- if (s->last_syt_offset < TICKS_PER_CYCLE) {
- if (!cip_sfc_is_base_44100(s->sfc))
- syt_offset = s->last_syt_offset + s->syt_offset_state;
- else {
- /*
- * The time, in ticks, of the n'th SYT_INTERVAL sample is:
- * n * SYT_INTERVAL * 24576000 / sample_rate
- * Modulo TICKS_PER_CYCLE, the difference between successive
- * elements is about 1386.23. Rounding the results of this
- * formula to the SYT precision results in a sequence of
- * differences that begins with:
- * 1386 1386 1387 1386 1386 1386 1387 1386 1386 1386 1387 ...
- * This code generates _exactly_ the same sequence.
- */
- phase = s->syt_offset_state;
- index = phase % 13;
- syt_offset = s->last_syt_offset;
- syt_offset += 1386 + ((index && !(index & 3)) ||
- phase == 146);
- if (++phase >= 147)
- phase = 0;
- s->syt_offset_state = phase;
- }
- } else
- syt_offset = s->last_syt_offset - TICKS_PER_CYCLE;
- s->last_syt_offset = syt_offset;
-
- if (syt_offset < TICKS_PER_CYCLE) {
- syt_offset += TRANSFER_DELAY_TICKS - TICKS_PER_CYCLE;
- syt = (cycle + syt_offset / TICKS_PER_CYCLE) << 12;
- syt += syt_offset % TICKS_PER_CYCLE;
-
- return syt & 0xffff;
- } else {
- return 0xffff; /* no info */
- }
-}
-
-static void amdtp_write_s32(struct amdtp_out_stream *s,
- struct snd_pcm_substream *pcm,
- __be32 *buffer, unsigned int frames)
-{
- struct snd_pcm_runtime *runtime = pcm->runtime;
- unsigned int channels, remaining_frames, frame_step, i, c;
- const u32 *src;
-
- channels = s->pcm_channels;
- src = (void *)runtime->dma_area +
- s->pcm_buffer_pointer * (runtime->frame_bits / 8);
- remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
- frame_step = s->data_block_quadlets - channels;
-
- for (i = 0; i < frames; ++i) {
- for (c = 0; c < channels; ++c) {
- *buffer = cpu_to_be32((*src >> 8) | 0x40000000);
- src++;
- buffer++;
- }
- buffer += frame_step;
- if (--remaining_frames == 0)
- src = (void *)runtime->dma_area;
- }
-}
-
-static void amdtp_write_s16(struct amdtp_out_stream *s,
- struct snd_pcm_substream *pcm,
- __be32 *buffer, unsigned int frames)
-{
- struct snd_pcm_runtime *runtime = pcm->runtime;
- unsigned int channels, remaining_frames, frame_step, i, c;
- const u16 *src;
-
- channels = s->pcm_channels;
- src = (void *)runtime->dma_area +
- s->pcm_buffer_pointer * (runtime->frame_bits / 8);
- remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
- frame_step = s->data_block_quadlets - channels;
-
- for (i = 0; i < frames; ++i) {
- for (c = 0; c < channels; ++c) {
- *buffer = cpu_to_be32((*src << 8) | 0x40000000);
- src++;
- buffer++;
- }
- buffer += frame_step;
- if (--remaining_frames == 0)
- src = (void *)runtime->dma_area;
- }
-}
-
-static void amdtp_fill_pcm_silence(struct amdtp_out_stream *s,
- __be32 *buffer, unsigned int frames)
-{
- unsigned int i, c;
-
- for (i = 0; i < frames; ++i) {
- for (c = 0; c < s->pcm_channels; ++c)
- buffer[c] = cpu_to_be32(0x40000000);
- buffer += s->data_block_quadlets;
- }
-}
-
-static void amdtp_fill_midi(struct amdtp_out_stream *s,
- __be32 *buffer, unsigned int frames)
-{
- unsigned int i;
-
- for (i = 0; i < frames; ++i)
- buffer[s->pcm_channels + i * s->data_block_quadlets] =
- cpu_to_be32(0x80000000);
-}
-
-static void queue_out_packet(struct amdtp_out_stream *s, unsigned int cycle)
-{
- __be32 *buffer;
- unsigned int index, data_blocks, syt, ptr;
- struct snd_pcm_substream *pcm;
- struct fw_iso_packet packet;
- int err;
-
- if (s->packet_index < 0)
- return;
- index = s->packet_index;
-
- data_blocks = calculate_data_blocks(s);
- syt = calculate_syt(s, cycle);
-
- buffer = s->buffer.packets[index].buffer;
- buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) |
- (s->data_block_quadlets << 16) |
- s->data_block_counter);
- buffer[1] = cpu_to_be32(CIP_EOH | CIP_FMT_AM | AMDTP_FDF_AM824 |
- (s->sfc << AMDTP_FDF_SFC_SHIFT) | syt);
- buffer += 2;
-
- pcm = ACCESS_ONCE(s->pcm);
- if (pcm)
- s->transfer_samples(s, pcm, buffer, data_blocks);
- else
- amdtp_fill_pcm_silence(s, buffer, data_blocks);
- if (s->midi_ports)
- amdtp_fill_midi(s, buffer, data_blocks);
-
- s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff;
-
- packet.payload_length = 8 + data_blocks * 4 * s->data_block_quadlets;
- packet.interrupt = IS_ALIGNED(index + 1, INTERRUPT_INTERVAL);
- packet.skip = 0;
- packet.tag = TAG_CIP;
- packet.sy = 0;
- packet.header_length = 0;
-
- err = fw_iso_context_queue(s->context, &packet, &s->buffer.iso_buffer,
- s->buffer.packets[index].offset);
- if (err < 0) {
- dev_err(&s->unit->device, "queueing error: %d\n", err);
- s->packet_index = -1;
- amdtp_out_stream_pcm_abort(s);
- return;
- }
-
- if (++index >= QUEUE_LENGTH)
- index = 0;
- s->packet_index = index;
-
- if (pcm) {
- ptr = s->pcm_buffer_pointer + data_blocks;
- if (ptr >= pcm->runtime->buffer_size)
- ptr -= pcm->runtime->buffer_size;
- ACCESS_ONCE(s->pcm_buffer_pointer) = ptr;
-
- s->pcm_period_pointer += data_blocks;
- if (s->pcm_period_pointer >= pcm->runtime->period_size) {
- s->pcm_period_pointer -= pcm->runtime->period_size;
- snd_pcm_period_elapsed(pcm);
- }
- }
-}
-
-static void out_packet_callback(struct fw_iso_context *context, u32 cycle,
- size_t header_length, void *header, void *data)
-{
- struct amdtp_out_stream *s = data;
- unsigned int i, packets = header_length / 4;
-
- /*
- * Compute the cycle of the last queued packet.
- * (We need only the four lowest bits for the SYT, so we can ignore
- * that bits 0-11 must wrap around at 3072.)
- */
- cycle += QUEUE_LENGTH - packets;
-
- for (i = 0; i < packets; ++i)
- queue_out_packet(s, ++cycle);
- fw_iso_context_queue_flush(s->context);
-}
-
-static int queue_initial_skip_packets(struct amdtp_out_stream *s)
-{
- struct fw_iso_packet skip_packet = {
- .skip = 1,
- };
- unsigned int i;
- int err;
-
- for (i = 0; i < QUEUE_LENGTH; ++i) {
- skip_packet.interrupt = IS_ALIGNED(s->packet_index + 1,
- INTERRUPT_INTERVAL);
- err = fw_iso_context_queue(s->context, &skip_packet, NULL, 0);
- if (err < 0)
- return err;
- if (++s->packet_index >= QUEUE_LENGTH)
- s->packet_index = 0;
- }
-
- return 0;
-}
-
-/**
- * amdtp_out_stream_start - start sending packets
- * @s: the AMDTP output stream to start
- * @channel: the isochronous channel on the bus
- * @speed: firewire speed code
- *
- * The stream cannot be started until it has been configured with
- * amdtp_out_stream_set_hw_params(), amdtp_out_stream_set_pcm(), and
- * amdtp_out_stream_set_midi(); and it must be started before any
- * PCM or MIDI device can be started.
- */
-int amdtp_out_stream_start(struct amdtp_out_stream *s, int channel, int speed)
-{
- static const struct {
- unsigned int data_block;
- unsigned int syt_offset;
- } initial_state[] = {
- [CIP_SFC_32000] = { 4, 3072 },
- [CIP_SFC_48000] = { 6, 1024 },
- [CIP_SFC_96000] = { 12, 1024 },
- [CIP_SFC_192000] = { 24, 1024 },
- [CIP_SFC_44100] = { 0, 67 },
- [CIP_SFC_88200] = { 0, 67 },
- [CIP_SFC_176400] = { 0, 67 },
- };
- int err;
-
- mutex_lock(&s->mutex);
-
- if (WARN_ON(!IS_ERR(s->context) ||
- (!s->pcm_channels && !s->midi_ports))) {
- err = -EBADFD;
- goto err_unlock;
- }
-
- s->data_block_state = initial_state[s->sfc].data_block;
- s->syt_offset_state = initial_state[s->sfc].syt_offset;
- s->last_syt_offset = TICKS_PER_CYCLE;
-
- err = iso_packets_buffer_init(&s->buffer, s->unit, QUEUE_LENGTH,
- amdtp_out_stream_get_max_payload(s),
- DMA_TO_DEVICE);
- if (err < 0)
- goto err_unlock;
-
- s->context = fw_iso_context_create(fw_parent_device(s->unit)->card,
- FW_ISO_CONTEXT_TRANSMIT,
- channel, speed, 0,
- out_packet_callback, s);
- if (IS_ERR(s->context)) {
- err = PTR_ERR(s->context);
- if (err == -EBUSY)
- dev_err(&s->unit->device,
- "no free output stream on this controller\n");
- goto err_buffer;
- }
-
- amdtp_out_stream_update(s);
-
- s->packet_index = 0;
- s->data_block_counter = 0;
- err = queue_initial_skip_packets(s);
- if (err < 0)
- goto err_context;
-
- err = fw_iso_context_start(s->context, -1, 0, 0);
- if (err < 0)
- goto err_context;
-
- mutex_unlock(&s->mutex);
-
- return 0;
-
-err_context:
- fw_iso_context_destroy(s->context);
- s->context = ERR_PTR(-1);
-err_buffer:
- iso_packets_buffer_destroy(&s->buffer, s->unit);
-err_unlock:
- mutex_unlock(&s->mutex);
-
- return err;
-}
-EXPORT_SYMBOL(amdtp_out_stream_start);
-
-/**
- * amdtp_out_stream_update - update the stream after a bus reset
- * @s: the AMDTP output stream
- */
-void amdtp_out_stream_update(struct amdtp_out_stream *s)
-{
- ACCESS_ONCE(s->source_node_id_field) =
- (fw_parent_device(s->unit)->card->node_id & 0x3f) << 24;
-}
-EXPORT_SYMBOL(amdtp_out_stream_update);
-
-/**
- * amdtp_out_stream_stop - stop sending packets
- * @s: the AMDTP output stream to stop
- *
- * All PCM and MIDI devices of the stream must be stopped before the stream
- * itself can be stopped.
- */
-void amdtp_out_stream_stop(struct amdtp_out_stream *s)
-{
- mutex_lock(&s->mutex);
-
- if (IS_ERR(s->context)) {
- mutex_unlock(&s->mutex);
- return;
- }
-
- fw_iso_context_stop(s->context);
- fw_iso_context_destroy(s->context);
- s->context = ERR_PTR(-1);
- iso_packets_buffer_destroy(&s->buffer, s->unit);
-
- mutex_unlock(&s->mutex);
-}
-EXPORT_SYMBOL(amdtp_out_stream_stop);
-
-/**
- * amdtp_out_stream_pcm_abort - abort the running PCM device
- * @s: the AMDTP stream about to be stopped
- *
- * If the isochronous stream needs to be stopped asynchronously, call this
- * function first to stop the PCM device.
- */
-void amdtp_out_stream_pcm_abort(struct amdtp_out_stream *s)
-{
- struct snd_pcm_substream *pcm;
-
- pcm = ACCESS_ONCE(s->pcm);
- if (pcm) {
- snd_pcm_stream_lock_irq(pcm);
- if (snd_pcm_running(pcm))
- snd_pcm_stop(pcm, SNDRV_PCM_STATE_XRUN);
- snd_pcm_stream_unlock_irq(pcm);
- }
-}
-EXPORT_SYMBOL(amdtp_out_stream_pcm_abort);
diff --git a/ANDROID_3.4.5/sound/firewire/amdtp.h b/ANDROID_3.4.5/sound/firewire/amdtp.h
deleted file mode 100644
index 537a9cb8..00000000
--- a/ANDROID_3.4.5/sound/firewire/amdtp.h
+++ /dev/null
@@ -1,169 +0,0 @@
-#ifndef SOUND_FIREWIRE_AMDTP_H_INCLUDED
-#define SOUND_FIREWIRE_AMDTP_H_INCLUDED
-
-#include <linux/mutex.h>
-#include <linux/spinlock.h>
-#include "packets-buffer.h"
-
-/**
- * enum cip_out_flags - describes details of the streaming protocol
- * @CIP_NONBLOCKING: In non-blocking mode, each packet contains
- * sample_rate/8000 samples, with rounding up or down to adjust
- * for clock skew and left-over fractional samples. This should
- * be used if supported by the device.
- */
-enum cip_out_flags {
- CIP_NONBLOCKING = 0,
-};
-
-/**
- * enum cip_sfc - a stream's sample rate
- */
-enum cip_sfc {
- CIP_SFC_32000 = 0,
- CIP_SFC_44100 = 1,
- CIP_SFC_48000 = 2,
- CIP_SFC_88200 = 3,
- CIP_SFC_96000 = 4,
- CIP_SFC_176400 = 5,
- CIP_SFC_192000 = 6,
-};
-
-#define AMDTP_OUT_PCM_FORMAT_BITS (SNDRV_PCM_FMTBIT_S16 | \
- SNDRV_PCM_FMTBIT_S32)
-
-struct fw_unit;
-struct fw_iso_context;
-struct snd_pcm_substream;
-
-struct amdtp_out_stream {
- struct fw_unit *unit;
- enum cip_out_flags flags;
- struct fw_iso_context *context;
- struct mutex mutex;
-
- enum cip_sfc sfc;
- unsigned int data_block_quadlets;
- unsigned int pcm_channels;
- unsigned int midi_ports;
- void (*transfer_samples)(struct amdtp_out_stream *s,
- struct snd_pcm_substream *pcm,
- __be32 *buffer, unsigned int frames);
-
- unsigned int syt_interval;
- unsigned int source_node_id_field;
- struct iso_packets_buffer buffer;
-
- struct snd_pcm_substream *pcm;
-
- int packet_index;
- unsigned int data_block_counter;
-
- unsigned int data_block_state;
-
- unsigned int last_syt_offset;
- unsigned int syt_offset_state;
-
- unsigned int pcm_buffer_pointer;
- unsigned int pcm_period_pointer;
-};
-
-int amdtp_out_stream_init(struct amdtp_out_stream *s, struct fw_unit *unit,
- enum cip_out_flags flags);
-void amdtp_out_stream_destroy(struct amdtp_out_stream *s);
-
-void amdtp_out_stream_set_rate(struct amdtp_out_stream *s, unsigned int rate);
-unsigned int amdtp_out_stream_get_max_payload(struct amdtp_out_stream *s);
-
-int amdtp_out_stream_start(struct amdtp_out_stream *s, int channel, int speed);
-void amdtp_out_stream_update(struct amdtp_out_stream *s);
-void amdtp_out_stream_stop(struct amdtp_out_stream *s);
-
-void amdtp_out_stream_set_pcm_format(struct amdtp_out_stream *s,
- snd_pcm_format_t format);
-void amdtp_out_stream_pcm_abort(struct amdtp_out_stream *s);
-
-/**
- * amdtp_out_stream_set_pcm - configure format of PCM samples
- * @s: the AMDTP output stream to be configured
- * @pcm_channels: the number of PCM samples in each data block, to be encoded
- * as AM824 multi-bit linear audio
- *
- * This function must not be called while the stream is running.
- */
-static inline void amdtp_out_stream_set_pcm(struct amdtp_out_stream *s,
- unsigned int pcm_channels)
-{
- s->pcm_channels = pcm_channels;
-}
-
-/**
- * amdtp_out_stream_set_midi - configure format of MIDI data
- * @s: the AMDTP output stream to be configured
- * @midi_ports: the number of MIDI ports (i.e., MPX-MIDI Data Channels)
- *
- * This function must not be called while the stream is running.
- */
-static inline void amdtp_out_stream_set_midi(struct amdtp_out_stream *s,
- unsigned int midi_ports)
-{
- s->midi_ports = midi_ports;
-}
-
-/**
- * amdtp_out_streaming_error - check for streaming error
- * @s: the AMDTP output stream
- *
- * If this function returns true, the stream's packet queue has stopped due to
- * an asynchronous error.
- */
-static inline bool amdtp_out_streaming_error(struct amdtp_out_stream *s)
-{
- return s->packet_index < 0;
-}
-
-/**
- * amdtp_out_stream_pcm_prepare - prepare PCM device for running
- * @s: the AMDTP output stream
- *
- * This function should be called from the PCM device's .prepare callback.
- */
-static inline void amdtp_out_stream_pcm_prepare(struct amdtp_out_stream *s)
-{
- s->pcm_buffer_pointer = 0;
- s->pcm_period_pointer = 0;
-}
-
-/**
- * amdtp_out_stream_pcm_trigger - start/stop playback from a PCM device
- * @s: the AMDTP output stream
- * @pcm: the PCM device to be started, or %NULL to stop the current device
- *
- * Call this function on a running isochronous stream to enable the actual
- * transmission of PCM data. This function should be called from the PCM
- * device's .trigger callback.
- */
-static inline void amdtp_out_stream_pcm_trigger(struct amdtp_out_stream *s,
- struct snd_pcm_substream *pcm)
-{
- ACCESS_ONCE(s->pcm) = pcm;
-}
-
-/**
- * amdtp_out_stream_pcm_pointer - get the PCM buffer position
- * @s: the AMDTP output stream that transports the PCM data
- *
- * Returns the current buffer position, in frames.
- */
-static inline unsigned long
-amdtp_out_stream_pcm_pointer(struct amdtp_out_stream *s)
-{
- return ACCESS_ONCE(s->pcm_buffer_pointer);
-}
-
-static inline bool cip_sfc_is_base_44100(enum cip_sfc sfc)
-{
- return sfc & 1;
-}
-
-#endif
diff --git a/ANDROID_3.4.5/sound/firewire/cmp.c b/ANDROID_3.4.5/sound/firewire/cmp.c
deleted file mode 100644
index 76294f2a..00000000
--- a/ANDROID_3.4.5/sound/firewire/cmp.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Connection Management Procedures (IEC 61883-1) helper functions
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- * Licensed under the terms of the GNU General Public License, version 2.
- */
-
-#include <linux/device.h>
-#include <linux/firewire.h>
-#include <linux/firewire-constants.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include "lib.h"
-#include "iso-resources.h"
-#include "cmp.h"
-
-#define IMPR_SPEED_MASK 0xc0000000
-#define IMPR_SPEED_SHIFT 30
-#define IMPR_XSPEED_MASK 0x00000060
-#define IMPR_XSPEED_SHIFT 5
-#define IMPR_PLUGS_MASK 0x0000001f
-
-#define IPCR_ONLINE 0x80000000
-#define IPCR_BCAST_CONN 0x40000000
-#define IPCR_P2P_CONN_MASK 0x3f000000
-#define IPCR_P2P_CONN_SHIFT 24
-#define IPCR_CHANNEL_MASK 0x003f0000
-#define IPCR_CHANNEL_SHIFT 16
-
-enum bus_reset_handling {
- ABORT_ON_BUS_RESET,
- SUCCEED_ON_BUS_RESET,
-};
-
-static __printf(2, 3)
-void cmp_error(struct cmp_connection *c, const char *fmt, ...)
-{
- va_list va;
-
- va_start(va, fmt);
- dev_err(&c->resources.unit->device, "%cPCR%u: %pV",
- 'i', c->pcr_index, &(struct va_format){ fmt, &va });
- va_end(va);
-}
-
-static int pcr_modify(struct cmp_connection *c,
- __be32 (*modify)(struct cmp_connection *c, __be32 old),
- int (*check)(struct cmp_connection *c, __be32 pcr),
- enum bus_reset_handling bus_reset_handling)
-{
- struct fw_device *device = fw_parent_device(c->resources.unit);
- int generation = c->resources.generation;
- int rcode, errors = 0;
- __be32 old_arg, buffer[2];
- int err;
-
- buffer[0] = c->last_pcr_value;
- for (;;) {
- old_arg = buffer[0];
- buffer[1] = modify(c, buffer[0]);
-
- rcode = fw_run_transaction(
- device->card, TCODE_LOCK_COMPARE_SWAP,
- device->node_id, generation, device->max_speed,
- CSR_REGISTER_BASE + CSR_IPCR(c->pcr_index),
- buffer, 8);
-
- if (rcode == RCODE_COMPLETE) {
- if (buffer[0] == old_arg) /* success? */
- break;
-
- if (check) {
- err = check(c, buffer[0]);
- if (err < 0)
- return err;
- }
- } else if (rcode == RCODE_GENERATION)
- goto bus_reset;
- else if (rcode_is_permanent_error(rcode) || ++errors >= 3)
- goto io_error;
- }
- c->last_pcr_value = buffer[1];
-
- return 0;
-
-io_error:
- cmp_error(c, "transaction failed: %s\n", rcode_string(rcode));
- return -EIO;
-
-bus_reset:
- return bus_reset_handling == ABORT_ON_BUS_RESET ? -EAGAIN : 0;
-}
-
-
-/**
- * cmp_connection_init - initializes a connection manager
- * @c: the connection manager to initialize
- * @unit: a unit of the target device
- * @ipcr_index: the index of the iPCR on the target device
- */
-int cmp_connection_init(struct cmp_connection *c,
- struct fw_unit *unit,
- unsigned int ipcr_index)
-{
- __be32 impr_be;
- u32 impr;
- int err;
-
- err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST,
- CSR_REGISTER_BASE + CSR_IMPR,
- &impr_be, 4);
- if (err < 0)
- return err;
- impr = be32_to_cpu(impr_be);
-
- if (ipcr_index >= (impr & IMPR_PLUGS_MASK))
- return -EINVAL;
-
- err = fw_iso_resources_init(&c->resources, unit);
- if (err < 0)
- return err;
-
- c->connected = false;
- mutex_init(&c->mutex);
- c->last_pcr_value = cpu_to_be32(0x80000000);
- c->pcr_index = ipcr_index;
- c->max_speed = (impr & IMPR_SPEED_MASK) >> IMPR_SPEED_SHIFT;
- if (c->max_speed == SCODE_BETA)
- c->max_speed += (impr & IMPR_XSPEED_MASK) >> IMPR_XSPEED_SHIFT;
-
- return 0;
-}
-EXPORT_SYMBOL(cmp_connection_init);
-
-/**
- * cmp_connection_destroy - free connection manager resources
- * @c: the connection manager
- */
-void cmp_connection_destroy(struct cmp_connection *c)
-{
- WARN_ON(c->connected);
- mutex_destroy(&c->mutex);
- fw_iso_resources_destroy(&c->resources);
-}
-EXPORT_SYMBOL(cmp_connection_destroy);
-
-
-static __be32 ipcr_set_modify(struct cmp_connection *c, __be32 ipcr)
-{
- ipcr &= ~cpu_to_be32(IPCR_BCAST_CONN |
- IPCR_P2P_CONN_MASK |
- IPCR_CHANNEL_MASK);
- ipcr |= cpu_to_be32(1 << IPCR_P2P_CONN_SHIFT);
- ipcr |= cpu_to_be32(c->resources.channel << IPCR_CHANNEL_SHIFT);
-
- return ipcr;
-}
-
-static int ipcr_set_check(struct cmp_connection *c, __be32 ipcr)
-{
- if (ipcr & cpu_to_be32(IPCR_BCAST_CONN |
- IPCR_P2P_CONN_MASK)) {
- cmp_error(c, "plug is already in use\n");
- return -EBUSY;
- }
- if (!(ipcr & cpu_to_be32(IPCR_ONLINE))) {
- cmp_error(c, "plug is not on-line\n");
- return -ECONNREFUSED;
- }
-
- return 0;
-}
-
-/**
- * cmp_connection_establish - establish a connection to the target
- * @c: the connection manager
- * @max_payload_bytes: the amount of data (including CIP headers) per packet
- *
- * This function establishes a point-to-point connection from the local
- * computer to the target by allocating isochronous resources (channel and
- * bandwidth) and setting the target's input plug control register. When this
- * function succeeds, the caller is responsible for starting transmitting
- * packets.
- */
-int cmp_connection_establish(struct cmp_connection *c,
- unsigned int max_payload_bytes)
-{
- int err;
-
- if (WARN_ON(c->connected))
- return -EISCONN;
-
- c->speed = min(c->max_speed,
- fw_parent_device(c->resources.unit)->max_speed);
-
- mutex_lock(&c->mutex);
-
-retry_after_bus_reset:
- err = fw_iso_resources_allocate(&c->resources,
- max_payload_bytes, c->speed);
- if (err < 0)
- goto err_mutex;
-
- err = pcr_modify(c, ipcr_set_modify, ipcr_set_check,
- ABORT_ON_BUS_RESET);
- if (err == -EAGAIN) {
- fw_iso_resources_free(&c->resources);
- goto retry_after_bus_reset;
- }
- if (err < 0)
- goto err_resources;
-
- c->connected = true;
-
- mutex_unlock(&c->mutex);
-
- return 0;
-
-err_resources:
- fw_iso_resources_free(&c->resources);
-err_mutex:
- mutex_unlock(&c->mutex);
-
- return err;
-}
-EXPORT_SYMBOL(cmp_connection_establish);
-
-/**
- * cmp_connection_update - update the connection after a bus reset
- * @c: the connection manager
- *
- * This function must be called from the driver's .update handler to reestablish
- * any connection that might have been active.
- *
- * Returns zero on success, or a negative error code. On an error, the
- * connection is broken and the caller must stop transmitting iso packets.
- */
-int cmp_connection_update(struct cmp_connection *c)
-{
- int err;
-
- mutex_lock(&c->mutex);
-
- if (!c->connected) {
- mutex_unlock(&c->mutex);
- return 0;
- }
-
- err = fw_iso_resources_update(&c->resources);
- if (err < 0)
- goto err_unconnect;
-
- err = pcr_modify(c, ipcr_set_modify, ipcr_set_check,
- SUCCEED_ON_BUS_RESET);
- if (err < 0)
- goto err_resources;
-
- mutex_unlock(&c->mutex);
-
- return 0;
-
-err_resources:
- fw_iso_resources_free(&c->resources);
-err_unconnect:
- c->connected = false;
- mutex_unlock(&c->mutex);
-
- return err;
-}
-EXPORT_SYMBOL(cmp_connection_update);
-
-
-static __be32 ipcr_break_modify(struct cmp_connection *c, __be32 ipcr)
-{
- return ipcr & ~cpu_to_be32(IPCR_BCAST_CONN | IPCR_P2P_CONN_MASK);
-}
-
-/**
- * cmp_connection_break - break the connection to the target
- * @c: the connection manager
- *
- * This function deactives the connection in the target's input plug control
- * register, and frees the isochronous resources of the connection. Before
- * calling this function, the caller should cease transmitting packets.
- */
-void cmp_connection_break(struct cmp_connection *c)
-{
- int err;
-
- mutex_lock(&c->mutex);
-
- if (!c->connected) {
- mutex_unlock(&c->mutex);
- return;
- }
-
- err = pcr_modify(c, ipcr_break_modify, NULL, SUCCEED_ON_BUS_RESET);
- if (err < 0)
- cmp_error(c, "plug is still connected\n");
-
- fw_iso_resources_free(&c->resources);
-
- c->connected = false;
-
- mutex_unlock(&c->mutex);
-}
-EXPORT_SYMBOL(cmp_connection_break);
diff --git a/ANDROID_3.4.5/sound/firewire/cmp.h b/ANDROID_3.4.5/sound/firewire/cmp.h
deleted file mode 100644
index f47de08f..00000000
--- a/ANDROID_3.4.5/sound/firewire/cmp.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef SOUND_FIREWIRE_CMP_H_INCLUDED
-#define SOUND_FIREWIRE_CMP_H_INCLUDED
-
-#include <linux/mutex.h>
-#include <linux/types.h>
-#include "iso-resources.h"
-
-struct fw_unit;
-
-/**
- * struct cmp_connection - manages an isochronous connection to a device
- * @speed: the connection's actual speed
- *
- * This structure manages (using CMP) an isochronous stream from the local
- * computer to a device's input plug (iPCR).
- *
- * There is no corresponding oPCR created on the local computer, so it is not
- * possible to overlay connections on top of this one.
- */
-struct cmp_connection {
- int speed;
- /* private: */
- bool connected;
- struct mutex mutex;
- struct fw_iso_resources resources;
- __be32 last_pcr_value;
- unsigned int pcr_index;
- unsigned int max_speed;
-};
-
-int cmp_connection_init(struct cmp_connection *connection,
- struct fw_unit *unit,
- unsigned int ipcr_index);
-void cmp_connection_destroy(struct cmp_connection *connection);
-
-int cmp_connection_establish(struct cmp_connection *connection,
- unsigned int max_payload);
-int cmp_connection_update(struct cmp_connection *connection);
-void cmp_connection_break(struct cmp_connection *connection);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/firewire/fcp.c b/ANDROID_3.4.5/sound/firewire/fcp.c
deleted file mode 100644
index ec578b5a..00000000
--- a/ANDROID_3.4.5/sound/firewire/fcp.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Function Control Protocol (IEC 61883-1) helper functions
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- * Licensed under the terms of the GNU General Public License, version 2.
- */
-
-#include <linux/device.h>
-#include <linux/firewire.h>
-#include <linux/firewire-constants.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-#include "fcp.h"
-#include "lib.h"
-
-#define CTS_AVC 0x00
-
-#define ERROR_RETRIES 3
-#define ERROR_DELAY_MS 5
-#define FCP_TIMEOUT_MS 125
-
-static DEFINE_SPINLOCK(transactions_lock);
-static LIST_HEAD(transactions);
-
-enum fcp_state {
- STATE_PENDING,
- STATE_BUS_RESET,
- STATE_COMPLETE,
-};
-
-struct fcp_transaction {
- struct list_head list;
- struct fw_unit *unit;
- void *response_buffer;
- unsigned int response_size;
- unsigned int response_match_bytes;
- enum fcp_state state;
- wait_queue_head_t wait;
-};
-
-/**
- * fcp_avc_transaction - send an AV/C command and wait for its response
- * @unit: a unit on the target device
- * @command: a buffer containing the command frame; must be DMA-able
- * @command_size: the size of @command
- * @response: a buffer for the response frame
- * @response_size: the maximum size of @response
- * @response_match_bytes: a bitmap specifying the bytes used to detect the
- * correct response frame
- *
- * This function sends a FCP command frame to the target and waits for the
- * corresponding response frame to be returned.
- *
- * Because it is possible for multiple FCP transactions to be active at the
- * same time, the correct response frame is detected by the value of certain
- * bytes. These bytes must be set in @response before calling this function,
- * and the corresponding bits must be set in @response_match_bytes.
- *
- * @command and @response can point to the same buffer.
- *
- * Asynchronous operation (INTERIM, NOTIFY) is not supported at the moment.
- *
- * Returns the actual size of the response frame, or a negative error code.
- */
-int fcp_avc_transaction(struct fw_unit *unit,
- const void *command, unsigned int command_size,
- void *response, unsigned int response_size,
- unsigned int response_match_bytes)
-{
- struct fcp_transaction t;
- int tcode, ret, tries = 0;
-
- t.unit = unit;
- t.response_buffer = response;
- t.response_size = response_size;
- t.response_match_bytes = response_match_bytes;
- t.state = STATE_PENDING;
- init_waitqueue_head(&t.wait);
-
- spin_lock_irq(&transactions_lock);
- list_add_tail(&t.list, &transactions);
- spin_unlock_irq(&transactions_lock);
-
- for (;;) {
- tcode = command_size == 4 ? TCODE_WRITE_QUADLET_REQUEST
- : TCODE_WRITE_BLOCK_REQUEST;
- ret = snd_fw_transaction(t.unit, tcode,
- CSR_REGISTER_BASE + CSR_FCP_COMMAND,
- (void *)command, command_size);
- if (ret < 0)
- break;
-
- wait_event_timeout(t.wait, t.state != STATE_PENDING,
- msecs_to_jiffies(FCP_TIMEOUT_MS));
-
- if (t.state == STATE_COMPLETE) {
- ret = t.response_size;
- break;
- } else if (t.state == STATE_BUS_RESET) {
- msleep(ERROR_DELAY_MS);
- } else if (++tries >= ERROR_RETRIES) {
- dev_err(&t.unit->device, "FCP command timed out\n");
- ret = -EIO;
- break;
- }
- }
-
- spin_lock_irq(&transactions_lock);
- list_del(&t.list);
- spin_unlock_irq(&transactions_lock);
-
- return ret;
-}
-EXPORT_SYMBOL(fcp_avc_transaction);
-
-/**
- * fcp_bus_reset - inform the target handler about a bus reset
- * @unit: the unit that might be used by fcp_avc_transaction()
- *
- * This function must be called from the driver's .update handler to inform
- * the FCP transaction handler that a bus reset has happened. Any pending FCP
- * transactions are retried.
- */
-void fcp_bus_reset(struct fw_unit *unit)
-{
- struct fcp_transaction *t;
-
- spin_lock_irq(&transactions_lock);
- list_for_each_entry(t, &transactions, list) {
- if (t->unit == unit &&
- t->state == STATE_PENDING) {
- t->state = STATE_BUS_RESET;
- wake_up(&t->wait);
- }
- }
- spin_unlock_irq(&transactions_lock);
-}
-EXPORT_SYMBOL(fcp_bus_reset);
-
-/* checks whether the response matches the masked bytes in response_buffer */
-static bool is_matching_response(struct fcp_transaction *transaction,
- const void *response, size_t length)
-{
- const u8 *p1, *p2;
- unsigned int mask, i;
-
- p1 = response;
- p2 = transaction->response_buffer;
- mask = transaction->response_match_bytes;
-
- for (i = 0; ; ++i) {
- if ((mask & 1) && p1[i] != p2[i])
- return false;
- mask >>= 1;
- if (!mask)
- return true;
- if (--length == 0)
- return false;
- }
-}
-
-static void fcp_response(struct fw_card *card, struct fw_request *request,
- int tcode, int destination, int source,
- int generation, unsigned long long offset,
- void *data, size_t length, void *callback_data)
-{
- struct fcp_transaction *t;
- unsigned long flags;
-
- if (length < 1 || (*(const u8 *)data & 0xf0) != CTS_AVC)
- return;
-
- spin_lock_irqsave(&transactions_lock, flags);
- list_for_each_entry(t, &transactions, list) {
- struct fw_device *device = fw_parent_device(t->unit);
- if (device->card != card ||
- device->generation != generation)
- continue;
- smp_rmb(); /* node_id vs. generation */
- if (device->node_id != source)
- continue;
-
- if (t->state == STATE_PENDING &&
- is_matching_response(t, data, length)) {
- t->state = STATE_COMPLETE;
- t->response_size = min((unsigned int)length,
- t->response_size);
- memcpy(t->response_buffer, data, t->response_size);
- wake_up(&t->wait);
- }
- }
- spin_unlock_irqrestore(&transactions_lock, flags);
-}
-
-static struct fw_address_handler response_register_handler = {
- .length = 0x200,
- .address_callback = fcp_response,
-};
-
-static int __init fcp_module_init(void)
-{
- static const struct fw_address_region response_register_region = {
- .start = CSR_REGISTER_BASE + CSR_FCP_RESPONSE,
- .end = CSR_REGISTER_BASE + CSR_FCP_END,
- };
-
- fw_core_add_address_handler(&response_register_handler,
- &response_register_region);
-
- return 0;
-}
-
-static void __exit fcp_module_exit(void)
-{
- WARN_ON(!list_empty(&transactions));
- fw_core_remove_address_handler(&response_register_handler);
-}
-
-module_init(fcp_module_init);
-module_exit(fcp_module_exit);
diff --git a/ANDROID_3.4.5/sound/firewire/fcp.h b/ANDROID_3.4.5/sound/firewire/fcp.h
deleted file mode 100644
index 86595688..00000000
--- a/ANDROID_3.4.5/sound/firewire/fcp.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef SOUND_FIREWIRE_FCP_H_INCLUDED
-#define SOUND_FIREWIRE_FCP_H_INCLUDED
-
-struct fw_unit;
-
-int fcp_avc_transaction(struct fw_unit *unit,
- const void *command, unsigned int command_size,
- void *response, unsigned int response_size,
- unsigned int response_match_bytes);
-void fcp_bus_reset(struct fw_unit *unit);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/firewire/isight.c b/ANDROID_3.4.5/sound/firewire/isight.c
deleted file mode 100644
index d428ffed..00000000
--- a/ANDROID_3.4.5/sound/firewire/isight.c
+++ /dev/null
@@ -1,753 +0,0 @@
-/*
- * Apple iSight audio driver
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- * Licensed under the terms of the GNU General Public License, version 2.
- */
-
-#include <asm/byteorder.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/firewire.h>
-#include <linux/firewire-constants.h>
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <linux/mutex.h>
-#include <linux/string.h>
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/tlv.h>
-#include "lib.h"
-#include "iso-resources.h"
-#include "packets-buffer.h"
-
-#define OUI_APPLE 0x000a27
-#define MODEL_APPLE_ISIGHT 0x000008
-#define SW_ISIGHT_AUDIO 0x000010
-
-#define REG_AUDIO_ENABLE 0x000
-#define AUDIO_ENABLE 0x80000000
-#define REG_DEF_AUDIO_GAIN 0x204
-#define REG_GAIN_RAW_START 0x210
-#define REG_GAIN_RAW_END 0x214
-#define REG_GAIN_DB_START 0x218
-#define REG_GAIN_DB_END 0x21c
-#define REG_SAMPLE_RATE_INQUIRY 0x280
-#define REG_ISO_TX_CONFIG 0x300
-#define SPEED_SHIFT 16
-#define REG_SAMPLE_RATE 0x400
-#define RATE_48000 0x80000000
-#define REG_GAIN 0x500
-#define REG_MUTE 0x504
-
-#define MAX_FRAMES_PER_PACKET 475
-
-#define QUEUE_LENGTH 20
-
-struct isight {
- struct snd_card *card;
- struct fw_unit *unit;
- struct fw_device *device;
- u64 audio_base;
- struct snd_pcm_substream *pcm;
- struct mutex mutex;
- struct iso_packets_buffer buffer;
- struct fw_iso_resources resources;
- struct fw_iso_context *context;
- bool pcm_active;
- bool pcm_running;
- bool first_packet;
- int packet_index;
- u32 total_samples;
- unsigned int buffer_pointer;
- unsigned int period_counter;
- s32 gain_min, gain_max;
- unsigned int gain_tlv[4];
-};
-
-struct audio_payload {
- __be32 sample_count;
- __be32 signature;
- __be32 sample_total;
- __be32 reserved;
- __be16 samples[2 * MAX_FRAMES_PER_PACKET];
-};
-
-MODULE_DESCRIPTION("iSight audio driver");
-MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
-MODULE_LICENSE("GPL v2");
-
-static struct fw_iso_packet audio_packet = {
- .payload_length = sizeof(struct audio_payload),
- .interrupt = 1,
- .header_length = 4,
-};
-
-static void isight_update_pointers(struct isight *isight, unsigned int count)
-{
- struct snd_pcm_runtime *runtime = isight->pcm->runtime;
- unsigned int ptr;
-
- smp_wmb(); /* update buffer data before buffer pointer */
-
- ptr = isight->buffer_pointer;
- ptr += count;
- if (ptr >= runtime->buffer_size)
- ptr -= runtime->buffer_size;
- ACCESS_ONCE(isight->buffer_pointer) = ptr;
-
- isight->period_counter += count;
- if (isight->period_counter >= runtime->period_size) {
- isight->period_counter -= runtime->period_size;
- snd_pcm_period_elapsed(isight->pcm);
- }
-}
-
-static void isight_samples(struct isight *isight,
- const __be16 *samples, unsigned int count)
-{
- struct snd_pcm_runtime *runtime;
- unsigned int count1;
-
- if (!ACCESS_ONCE(isight->pcm_running))
- return;
-
- runtime = isight->pcm->runtime;
- if (isight->buffer_pointer + count <= runtime->buffer_size) {
- memcpy(runtime->dma_area + isight->buffer_pointer * 4,
- samples, count * 4);
- } else {
- count1 = runtime->buffer_size - isight->buffer_pointer;
- memcpy(runtime->dma_area + isight->buffer_pointer * 4,
- samples, count1 * 4);
- samples += count1 * 2;
- memcpy(runtime->dma_area, samples, (count - count1) * 4);
- }
-
- isight_update_pointers(isight, count);
-}
-
-static void isight_pcm_abort(struct isight *isight)
-{
- unsigned long flags;
-
- if (ACCESS_ONCE(isight->pcm_active)) {
- snd_pcm_stream_lock_irqsave(isight->pcm, flags);
- if (snd_pcm_running(isight->pcm))
- snd_pcm_stop(isight->pcm, SNDRV_PCM_STATE_XRUN);
- snd_pcm_stream_unlock_irqrestore(isight->pcm, flags);
- }
-}
-
-static void isight_dropped_samples(struct isight *isight, unsigned int total)
-{
- struct snd_pcm_runtime *runtime;
- u32 dropped;
- unsigned int count1;
-
- if (!ACCESS_ONCE(isight->pcm_running))
- return;
-
- runtime = isight->pcm->runtime;
- dropped = total - isight->total_samples;
- if (dropped < runtime->buffer_size) {
- if (isight->buffer_pointer + dropped <= runtime->buffer_size) {
- memset(runtime->dma_area + isight->buffer_pointer * 4,
- 0, dropped * 4);
- } else {
- count1 = runtime->buffer_size - isight->buffer_pointer;
- memset(runtime->dma_area + isight->buffer_pointer * 4,
- 0, count1 * 4);
- memset(runtime->dma_area, 0, (dropped - count1) * 4);
- }
- isight_update_pointers(isight, dropped);
- } else {
- isight_pcm_abort(isight);
- }
-}
-
-static void isight_packet(struct fw_iso_context *context, u32 cycle,
- size_t header_length, void *header, void *data)
-{
- struct isight *isight = data;
- const struct audio_payload *payload;
- unsigned int index, length, count, total;
- int err;
-
- if (isight->packet_index < 0)
- return;
- index = isight->packet_index;
- payload = isight->buffer.packets[index].buffer;
- length = be32_to_cpup(header) >> 16;
-
- if (likely(length >= 16 &&
- payload->signature == cpu_to_be32(0x73676874/*"sght"*/))) {
- count = be32_to_cpu(payload->sample_count);
- if (likely(count <= (length - 16) / 4)) {
- total = be32_to_cpu(payload->sample_total);
- if (unlikely(total != isight->total_samples)) {
- if (!isight->first_packet)
- isight_dropped_samples(isight, total);
- isight->first_packet = false;
- isight->total_samples = total;
- }
-
- isight_samples(isight, payload->samples, count);
- isight->total_samples += count;
- }
- }
-
- err = fw_iso_context_queue(isight->context, &audio_packet,
- &isight->buffer.iso_buffer,
- isight->buffer.packets[index].offset);
- if (err < 0) {
- dev_err(&isight->unit->device, "queueing error: %d\n", err);
- isight_pcm_abort(isight);
- isight->packet_index = -1;
- return;
- }
- fw_iso_context_queue_flush(isight->context);
-
- if (++index >= QUEUE_LENGTH)
- index = 0;
- isight->packet_index = index;
-}
-
-static int isight_connect(struct isight *isight)
-{
- int ch, err, rcode, errors = 0;
- __be32 value;
-
-retry_after_bus_reset:
- ch = fw_iso_resources_allocate(&isight->resources,
- sizeof(struct audio_payload),
- isight->device->max_speed);
- if (ch < 0) {
- err = ch;
- goto error;
- }
-
- value = cpu_to_be32(ch | (isight->device->max_speed << SPEED_SHIFT));
- for (;;) {
- rcode = fw_run_transaction(
- isight->device->card,
- TCODE_WRITE_QUADLET_REQUEST,
- isight->device->node_id,
- isight->resources.generation,
- isight->device->max_speed,
- isight->audio_base + REG_ISO_TX_CONFIG,
- &value, 4);
- if (rcode == RCODE_COMPLETE) {
- return 0;
- } else if (rcode == RCODE_GENERATION) {
- fw_iso_resources_free(&isight->resources);
- goto retry_after_bus_reset;
- } else if (rcode_is_permanent_error(rcode) || ++errors >= 3) {
- err = -EIO;
- goto err_resources;
- }
- msleep(5);
- }
-
-err_resources:
- fw_iso_resources_free(&isight->resources);
-error:
- return err;
-}
-
-static int isight_open(struct snd_pcm_substream *substream)
-{
- static const struct snd_pcm_hardware hardware = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BATCH |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER,
- .formats = SNDRV_PCM_FMTBIT_S16_BE,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 4 * 1024 * 1024,
- .period_bytes_min = MAX_FRAMES_PER_PACKET * 4,
- .period_bytes_max = 1024 * 1024,
- .periods_min = 2,
- .periods_max = UINT_MAX,
- };
- struct isight *isight = substream->private_data;
-
- substream->runtime->hw = hardware;
-
- return iso_packets_buffer_init(&isight->buffer, isight->unit,
- QUEUE_LENGTH,
- sizeof(struct audio_payload),
- DMA_FROM_DEVICE);
-}
-
-static int isight_close(struct snd_pcm_substream *substream)
-{
- struct isight *isight = substream->private_data;
-
- iso_packets_buffer_destroy(&isight->buffer, isight->unit);
-
- return 0;
-}
-
-static int isight_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct isight *isight = substream->private_data;
- int err;
-
- err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
- params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
-
- ACCESS_ONCE(isight->pcm_active) = true;
-
- return 0;
-}
-
-static int reg_read(struct isight *isight, int offset, __be32 *value)
-{
- return snd_fw_transaction(isight->unit, TCODE_READ_QUADLET_REQUEST,
- isight->audio_base + offset, value, 4);
-}
-
-static int reg_write(struct isight *isight, int offset, __be32 value)
-{
- return snd_fw_transaction(isight->unit, TCODE_WRITE_QUADLET_REQUEST,
- isight->audio_base + offset, &value, 4);
-}
-
-static void isight_stop_streaming(struct isight *isight)
-{
- if (!isight->context)
- return;
-
- fw_iso_context_stop(isight->context);
- fw_iso_context_destroy(isight->context);
- isight->context = NULL;
- fw_iso_resources_free(&isight->resources);
- reg_write(isight, REG_AUDIO_ENABLE, 0);
-}
-
-static int isight_hw_free(struct snd_pcm_substream *substream)
-{
- struct isight *isight = substream->private_data;
-
- ACCESS_ONCE(isight->pcm_active) = false;
-
- mutex_lock(&isight->mutex);
- isight_stop_streaming(isight);
- mutex_unlock(&isight->mutex);
-
- return snd_pcm_lib_free_vmalloc_buffer(substream);
-}
-
-static int isight_start_streaming(struct isight *isight)
-{
- unsigned int i;
- int err;
-
- if (isight->context) {
- if (isight->packet_index < 0)
- isight_stop_streaming(isight);
- else
- return 0;
- }
-
- err = reg_write(isight, REG_SAMPLE_RATE, cpu_to_be32(RATE_48000));
- if (err < 0)
- goto error;
-
- err = isight_connect(isight);
- if (err < 0)
- goto error;
-
- err = reg_write(isight, REG_AUDIO_ENABLE, cpu_to_be32(AUDIO_ENABLE));
- if (err < 0)
- goto err_resources;
-
- isight->context = fw_iso_context_create(isight->device->card,
- FW_ISO_CONTEXT_RECEIVE,
- isight->resources.channel,
- isight->device->max_speed,
- 4, isight_packet, isight);
- if (IS_ERR(isight->context)) {
- err = PTR_ERR(isight->context);
- isight->context = NULL;
- goto err_resources;
- }
-
- for (i = 0; i < QUEUE_LENGTH; ++i) {
- err = fw_iso_context_queue(isight->context, &audio_packet,
- &isight->buffer.iso_buffer,
- isight->buffer.packets[i].offset);
- if (err < 0)
- goto err_context;
- }
-
- isight->first_packet = true;
- isight->packet_index = 0;
-
- err = fw_iso_context_start(isight->context, -1, 0,
- FW_ISO_CONTEXT_MATCH_ALL_TAGS/*?*/);
- if (err < 0)
- goto err_context;
-
- return 0;
-
-err_context:
- fw_iso_context_destroy(isight->context);
- isight->context = NULL;
-err_resources:
- fw_iso_resources_free(&isight->resources);
- reg_write(isight, REG_AUDIO_ENABLE, 0);
-error:
- return err;
-}
-
-static int isight_prepare(struct snd_pcm_substream *substream)
-{
- struct isight *isight = substream->private_data;
- int err;
-
- isight->buffer_pointer = 0;
- isight->period_counter = 0;
-
- mutex_lock(&isight->mutex);
- err = isight_start_streaming(isight);
- mutex_unlock(&isight->mutex);
-
- return err;
-}
-
-static int isight_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct isight *isight = substream->private_data;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- ACCESS_ONCE(isight->pcm_running) = true;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- ACCESS_ONCE(isight->pcm_running) = false;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static snd_pcm_uframes_t isight_pointer(struct snd_pcm_substream *substream)
-{
- struct isight *isight = substream->private_data;
-
- return ACCESS_ONCE(isight->buffer_pointer);
-}
-
-static int isight_create_pcm(struct isight *isight)
-{
- static struct snd_pcm_ops ops = {
- .open = isight_open,
- .close = isight_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = isight_hw_params,
- .hw_free = isight_hw_free,
- .prepare = isight_prepare,
- .trigger = isight_trigger,
- .pointer = isight_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
- };
- struct snd_pcm *pcm;
- int err;
-
- err = snd_pcm_new(isight->card, "iSight", 0, 0, 1, &pcm);
- if (err < 0)
- return err;
- pcm->private_data = isight;
- strcpy(pcm->name, "iSight");
- isight->pcm = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
- isight->pcm->ops = &ops;
-
- return 0;
-}
-
-static int isight_gain_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- struct isight *isight = ctl->private_data;
-
- info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- info->count = 1;
- info->value.integer.min = isight->gain_min;
- info->value.integer.max = isight->gain_max;
-
- return 0;
-}
-
-static int isight_gain_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct isight *isight = ctl->private_data;
- __be32 gain;
- int err;
-
- err = reg_read(isight, REG_GAIN, &gain);
- if (err < 0)
- return err;
-
- value->value.integer.value[0] = (s32)be32_to_cpu(gain);
-
- return 0;
-}
-
-static int isight_gain_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct isight *isight = ctl->private_data;
-
- if (value->value.integer.value[0] < isight->gain_min ||
- value->value.integer.value[0] > isight->gain_max)
- return -EINVAL;
-
- return reg_write(isight, REG_GAIN,
- cpu_to_be32(value->value.integer.value[0]));
-}
-
-static int isight_mute_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct isight *isight = ctl->private_data;
- __be32 mute;
- int err;
-
- err = reg_read(isight, REG_MUTE, &mute);
- if (err < 0)
- return err;
-
- value->value.integer.value[0] = !mute;
-
- return 0;
-}
-
-static int isight_mute_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct isight *isight = ctl->private_data;
-
- return reg_write(isight, REG_MUTE,
- (__force __be32)!value->value.integer.value[0]);
-}
-
-static int isight_create_mixer(struct isight *isight)
-{
- static const struct snd_kcontrol_new gain_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Mic Capture Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = isight_gain_info,
- .get = isight_gain_get,
- .put = isight_gain_put,
- };
- static const struct snd_kcontrol_new mute_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Mic Capture Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = isight_mute_get,
- .put = isight_mute_put,
- };
- __be32 value;
- struct snd_kcontrol *ctl;
- int err;
-
- err = reg_read(isight, REG_GAIN_RAW_START, &value);
- if (err < 0)
- return err;
- isight->gain_min = be32_to_cpu(value);
-
- err = reg_read(isight, REG_GAIN_RAW_END, &value);
- if (err < 0)
- return err;
- isight->gain_max = be32_to_cpu(value);
-
- isight->gain_tlv[0] = SNDRV_CTL_TLVT_DB_MINMAX;
- isight->gain_tlv[1] = 2 * sizeof(unsigned int);
-
- err = reg_read(isight, REG_GAIN_DB_START, &value);
- if (err < 0)
- return err;
- isight->gain_tlv[2] = (s32)be32_to_cpu(value) * 100;
-
- err = reg_read(isight, REG_GAIN_DB_END, &value);
- if (err < 0)
- return err;
- isight->gain_tlv[3] = (s32)be32_to_cpu(value) * 100;
-
- ctl = snd_ctl_new1(&gain_control, isight);
- if (ctl)
- ctl->tlv.p = isight->gain_tlv;
- err = snd_ctl_add(isight->card, ctl);
- if (err < 0)
- return err;
-
- err = snd_ctl_add(isight->card, snd_ctl_new1(&mute_control, isight));
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static void isight_card_free(struct snd_card *card)
-{
- struct isight *isight = card->private_data;
-
- fw_iso_resources_destroy(&isight->resources);
- fw_unit_put(isight->unit);
- mutex_destroy(&isight->mutex);
-}
-
-static u64 get_unit_base(struct fw_unit *unit)
-{
- struct fw_csr_iterator i;
- int key, value;
-
- fw_csr_iterator_init(&i, unit->directory);
- while (fw_csr_iterator_next(&i, &key, &value))
- if (key == CSR_OFFSET)
- return CSR_REGISTER_BASE + value * 4;
- return 0;
-}
-
-static int isight_probe(struct device *unit_dev)
-{
- struct fw_unit *unit = fw_unit(unit_dev);
- struct fw_device *fw_dev = fw_parent_device(unit);
- struct snd_card *card;
- struct isight *isight;
- int err;
-
- err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*isight), &card);
- if (err < 0)
- return err;
- snd_card_set_dev(card, unit_dev);
-
- isight = card->private_data;
- isight->card = card;
- mutex_init(&isight->mutex);
- isight->unit = fw_unit_get(unit);
- isight->device = fw_dev;
- isight->audio_base = get_unit_base(unit);
- if (!isight->audio_base) {
- dev_err(&unit->device, "audio unit base not found\n");
- err = -ENXIO;
- goto err_unit;
- }
- fw_iso_resources_init(&isight->resources, unit);
-
- card->private_free = isight_card_free;
-
- strcpy(card->driver, "iSight");
- strcpy(card->shortname, "Apple iSight");
- snprintf(card->longname, sizeof(card->longname),
- "Apple iSight (GUID %08x%08x) at %s, S%d",
- fw_dev->config_rom[3], fw_dev->config_rom[4],
- dev_name(&unit->device), 100 << fw_dev->max_speed);
- strcpy(card->mixername, "iSight");
-
- err = isight_create_pcm(isight);
- if (err < 0)
- goto error;
-
- err = isight_create_mixer(isight);
- if (err < 0)
- goto error;
-
- err = snd_card_register(card);
- if (err < 0)
- goto error;
-
- dev_set_drvdata(unit_dev, isight);
-
- return 0;
-
-err_unit:
- fw_unit_put(isight->unit);
- mutex_destroy(&isight->mutex);
-error:
- snd_card_free(card);
- return err;
-}
-
-static int isight_remove(struct device *dev)
-{
- struct isight *isight = dev_get_drvdata(dev);
-
- isight_pcm_abort(isight);
-
- snd_card_disconnect(isight->card);
-
- mutex_lock(&isight->mutex);
- isight_stop_streaming(isight);
- mutex_unlock(&isight->mutex);
-
- snd_card_free_when_closed(isight->card);
-
- return 0;
-}
-
-static void isight_bus_reset(struct fw_unit *unit)
-{
- struct isight *isight = dev_get_drvdata(&unit->device);
-
- if (fw_iso_resources_update(&isight->resources) < 0) {
- isight_pcm_abort(isight);
-
- mutex_lock(&isight->mutex);
- isight_stop_streaming(isight);
- mutex_unlock(&isight->mutex);
- }
-}
-
-static const struct ieee1394_device_id isight_id_table[] = {
- {
- .match_flags = IEEE1394_MATCH_SPECIFIER_ID |
- IEEE1394_MATCH_VERSION,
- .specifier_id = OUI_APPLE,
- .version = SW_ISIGHT_AUDIO,
- },
- { }
-};
-MODULE_DEVICE_TABLE(ieee1394, isight_id_table);
-
-static struct fw_driver isight_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = KBUILD_MODNAME,
- .bus = &fw_bus_type,
- .probe = isight_probe,
- .remove = isight_remove,
- },
- .update = isight_bus_reset,
- .id_table = isight_id_table,
-};
-
-static int __init alsa_isight_init(void)
-{
- return driver_register(&isight_driver.driver);
-}
-
-static void __exit alsa_isight_exit(void)
-{
- driver_unregister(&isight_driver.driver);
-}
-
-module_init(alsa_isight_init);
-module_exit(alsa_isight_exit);
diff --git a/ANDROID_3.4.5/sound/firewire/iso-resources.c b/ANDROID_3.4.5/sound/firewire/iso-resources.c
deleted file mode 100644
index 5f17b77e..00000000
--- a/ANDROID_3.4.5/sound/firewire/iso-resources.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * isochronous resources helper functions
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- * Licensed under the terms of the GNU General Public License, version 2.
- */
-
-#include <linux/device.h>
-#include <linux/firewire.h>
-#include <linux/firewire-constants.h>
-#include <linux/export.h>
-#include <linux/jiffies.h>
-#include <linux/mutex.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include "iso-resources.h"
-
-/**
- * fw_iso_resources_init - initializes a &struct fw_iso_resources
- * @r: the resource manager to initialize
- * @unit: the device unit for which the resources will be needed
- *
- * If the device does not support all channel numbers, change @r->channels_mask
- * after calling this function.
- */
-int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit)
-{
- r->channels_mask = ~0uLL;
- r->unit = fw_unit_get(unit);
- mutex_init(&r->mutex);
- r->allocated = false;
-
- return 0;
-}
-EXPORT_SYMBOL(fw_iso_resources_init);
-
-/**
- * fw_iso_resources_destroy - destroy a resource manager
- * @r: the resource manager that is no longer needed
- */
-void fw_iso_resources_destroy(struct fw_iso_resources *r)
-{
- WARN_ON(r->allocated);
- mutex_destroy(&r->mutex);
- fw_unit_put(r->unit);
-}
-EXPORT_SYMBOL(fw_iso_resources_destroy);
-
-static unsigned int packet_bandwidth(unsigned int max_payload_bytes, int speed)
-{
- unsigned int bytes, s400_bytes;
-
- /* iso packets have three header quadlets and quadlet-aligned payload */
- bytes = 3 * 4 + ALIGN(max_payload_bytes, 4);
-
- /* convert to bandwidth units (quadlets at S1600 = bytes at S400) */
- if (speed <= SCODE_400)
- s400_bytes = bytes * (1 << (SCODE_400 - speed));
- else
- s400_bytes = DIV_ROUND_UP(bytes, 1 << (speed - SCODE_400));
-
- return s400_bytes;
-}
-
-static int current_bandwidth_overhead(struct fw_card *card)
-{
- /*
- * Under the usual pessimistic assumption (cable length 4.5 m), the
- * isochronous overhead for N cables is 1.797 µs + N * 0.494 µs, or
- * 88.3 + N * 24.3 in bandwidth units.
- *
- * The calculation below tries to deduce N from the current gap count.
- * If the gap count has been optimized by measuring the actual packet
- * transmission time, this derived overhead should be near the actual
- * overhead as well.
- */
- return card->gap_count < 63 ? card->gap_count * 97 / 10 + 89 : 512;
-}
-
-static int wait_isoch_resource_delay_after_bus_reset(struct fw_card *card)
-{
- for (;;) {
- s64 delay = (card->reset_jiffies + HZ) - get_jiffies_64();
- if (delay <= 0)
- return 0;
- if (schedule_timeout_interruptible(delay) > 0)
- return -ERESTARTSYS;
- }
-}
-
-/**
- * fw_iso_resources_allocate - allocate isochronous channel and bandwidth
- * @r: the resource manager
- * @max_payload_bytes: the amount of data (including CIP headers) per packet
- * @speed: the speed (e.g., SCODE_400) at which the packets will be sent
- *
- * This function allocates one isochronous channel and enough bandwidth for the
- * specified packet size.
- *
- * Returns the channel number that the caller must use for streaming, or
- * a negative error code. Due to potentionally long delays, this function is
- * interruptible and can return -ERESTARTSYS. On success, the caller is
- * responsible for calling fw_iso_resources_update() on bus resets, and
- * fw_iso_resources_free() when the resources are not longer needed.
- */
-int fw_iso_resources_allocate(struct fw_iso_resources *r,
- unsigned int max_payload_bytes, int speed)
-{
- struct fw_card *card = fw_parent_device(r->unit)->card;
- int bandwidth, channel, err;
-
- if (WARN_ON(r->allocated))
- return -EBADFD;
-
- r->bandwidth = packet_bandwidth(max_payload_bytes, speed);
-
-retry_after_bus_reset:
- spin_lock_irq(&card->lock);
- r->generation = card->generation;
- r->bandwidth_overhead = current_bandwidth_overhead(card);
- spin_unlock_irq(&card->lock);
-
- err = wait_isoch_resource_delay_after_bus_reset(card);
- if (err < 0)
- return err;
-
- mutex_lock(&r->mutex);
-
- bandwidth = r->bandwidth + r->bandwidth_overhead;
- fw_iso_resource_manage(card, r->generation, r->channels_mask,
- &channel, &bandwidth, true);
- if (channel == -EAGAIN) {
- mutex_unlock(&r->mutex);
- goto retry_after_bus_reset;
- }
- if (channel >= 0) {
- r->channel = channel;
- r->allocated = true;
- } else {
- if (channel == -EBUSY)
- dev_err(&r->unit->device,
- "isochronous resources exhausted\n");
- else
- dev_err(&r->unit->device,
- "isochronous resource allocation failed\n");
- }
-
- mutex_unlock(&r->mutex);
-
- return channel;
-}
-EXPORT_SYMBOL(fw_iso_resources_allocate);
-
-/**
- * fw_iso_resources_update - update resource allocations after a bus reset
- * @r: the resource manager
- *
- * This function must be called from the driver's .update handler to reallocate
- * any resources that were allocated before the bus reset. It is safe to call
- * this function if no resources are currently allocated.
- *
- * Returns a negative error code on failure. If this happens, the caller must
- * stop streaming.
- */
-int fw_iso_resources_update(struct fw_iso_resources *r)
-{
- struct fw_card *card = fw_parent_device(r->unit)->card;
- int bandwidth, channel;
-
- mutex_lock(&r->mutex);
-
- if (!r->allocated) {
- mutex_unlock(&r->mutex);
- return 0;
- }
-
- spin_lock_irq(&card->lock);
- r->generation = card->generation;
- r->bandwidth_overhead = current_bandwidth_overhead(card);
- spin_unlock_irq(&card->lock);
-
- bandwidth = r->bandwidth + r->bandwidth_overhead;
-
- fw_iso_resource_manage(card, r->generation, 1uLL << r->channel,
- &channel, &bandwidth, true);
- /*
- * When another bus reset happens, pretend that the allocation
- * succeeded; we will try again for the new generation later.
- */
- if (channel < 0 && channel != -EAGAIN) {
- r->allocated = false;
- if (channel == -EBUSY)
- dev_err(&r->unit->device,
- "isochronous resources exhausted\n");
- else
- dev_err(&r->unit->device,
- "isochronous resource allocation failed\n");
- }
-
- mutex_unlock(&r->mutex);
-
- return channel;
-}
-EXPORT_SYMBOL(fw_iso_resources_update);
-
-/**
- * fw_iso_resources_free - frees allocated resources
- * @r: the resource manager
- *
- * This function deallocates the channel and bandwidth, if allocated.
- */
-void fw_iso_resources_free(struct fw_iso_resources *r)
-{
- struct fw_card *card = fw_parent_device(r->unit)->card;
- int bandwidth, channel;
-
- mutex_lock(&r->mutex);
-
- if (r->allocated) {
- bandwidth = r->bandwidth + r->bandwidth_overhead;
- fw_iso_resource_manage(card, r->generation, 1uLL << r->channel,
- &channel, &bandwidth, false);
- if (channel < 0)
- dev_err(&r->unit->device,
- "isochronous resource deallocation failed\n");
-
- r->allocated = false;
- }
-
- mutex_unlock(&r->mutex);
-}
-EXPORT_SYMBOL(fw_iso_resources_free);
diff --git a/ANDROID_3.4.5/sound/firewire/iso-resources.h b/ANDROID_3.4.5/sound/firewire/iso-resources.h
deleted file mode 100644
index 5a9af7c6..00000000
--- a/ANDROID_3.4.5/sound/firewire/iso-resources.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef SOUND_FIREWIRE_ISO_RESOURCES_H_INCLUDED
-#define SOUND_FIREWIRE_ISO_RESOURCES_H_INCLUDED
-
-#include <linux/mutex.h>
-#include <linux/types.h>
-
-struct fw_unit;
-
-/**
- * struct fw_iso_resources - manages channel/bandwidth allocation
- * @channels_mask: if the device does not support all channel numbers, set this
- * bit mask to something else than the default (all ones)
- *
- * This structure manages (de)allocation of isochronous resources (channel and
- * bandwidth) for one isochronous stream.
- */
-struct fw_iso_resources {
- u64 channels_mask;
- /* private: */
- struct fw_unit *unit;
- struct mutex mutex;
- unsigned int channel;
- unsigned int bandwidth; /* in bandwidth units, without overhead */
- unsigned int bandwidth_overhead;
- int generation; /* in which allocation is valid */
- bool allocated;
-};
-
-int fw_iso_resources_init(struct fw_iso_resources *r,
- struct fw_unit *unit);
-void fw_iso_resources_destroy(struct fw_iso_resources *r);
-
-int fw_iso_resources_allocate(struct fw_iso_resources *r,
- unsigned int max_payload_bytes, int speed);
-int fw_iso_resources_update(struct fw_iso_resources *r);
-void fw_iso_resources_free(struct fw_iso_resources *r);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/firewire/lib.c b/ANDROID_3.4.5/sound/firewire/lib.c
deleted file mode 100644
index 4750cea2..00000000
--- a/ANDROID_3.4.5/sound/firewire/lib.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * miscellaneous helper functions
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- * Licensed under the terms of the GNU General Public License, version 2.
- */
-
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/firewire.h>
-#include <linux/module.h>
-#include "lib.h"
-
-#define ERROR_RETRY_DELAY_MS 5
-
-/**
- * rcode_string - convert a firewire result code to a string
- * @rcode: the result
- */
-const char *rcode_string(unsigned int rcode)
-{
- static const char *const names[] = {
- [RCODE_COMPLETE] = "complete",
- [RCODE_CONFLICT_ERROR] = "conflict error",
- [RCODE_DATA_ERROR] = "data error",
- [RCODE_TYPE_ERROR] = "type error",
- [RCODE_ADDRESS_ERROR] = "address error",
- [RCODE_SEND_ERROR] = "send error",
- [RCODE_CANCELLED] = "cancelled",
- [RCODE_BUSY] = "busy",
- [RCODE_GENERATION] = "generation",
- [RCODE_NO_ACK] = "no ack",
- };
-
- if (rcode < ARRAY_SIZE(names) && names[rcode])
- return names[rcode];
- else
- return "unknown";
-}
-EXPORT_SYMBOL(rcode_string);
-
-/**
- * snd_fw_transaction - send a request and wait for its completion
- * @unit: the driver's unit on the target device
- * @tcode: the transaction code
- * @offset: the address in the target's address space
- * @buffer: input/output data
- * @length: length of @buffer
- *
- * Submits an asynchronous request to the target device, and waits for the
- * response. The node ID and the current generation are derived from @unit.
- * On a bus reset or an error, the transaction is retried a few times.
- * Returns zero on success, or a negative error code.
- */
-int snd_fw_transaction(struct fw_unit *unit, int tcode,
- u64 offset, void *buffer, size_t length)
-{
- struct fw_device *device = fw_parent_device(unit);
- int generation, rcode, tries = 0;
-
- for (;;) {
- generation = device->generation;
- smp_rmb(); /* node_id vs. generation */
- rcode = fw_run_transaction(device->card, tcode,
- device->node_id, generation,
- device->max_speed, offset,
- buffer, length);
-
- if (rcode == RCODE_COMPLETE)
- return 0;
-
- if (rcode_is_permanent_error(rcode) || ++tries >= 3) {
- dev_err(&unit->device, "transaction failed: %s\n",
- rcode_string(rcode));
- return -EIO;
- }
-
- msleep(ERROR_RETRY_DELAY_MS);
- }
-}
-EXPORT_SYMBOL(snd_fw_transaction);
-
-MODULE_DESCRIPTION("FireWire audio helper functions");
-MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/sound/firewire/lib.h b/ANDROID_3.4.5/sound/firewire/lib.h
deleted file mode 100644
index 064f3fd9..00000000
--- a/ANDROID_3.4.5/sound/firewire/lib.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef SOUND_FIREWIRE_LIB_H_INCLUDED
-#define SOUND_FIREWIRE_LIB_H_INCLUDED
-
-#include <linux/firewire-constants.h>
-#include <linux/types.h>
-
-struct fw_unit;
-
-int snd_fw_transaction(struct fw_unit *unit, int tcode,
- u64 offset, void *buffer, size_t length);
-const char *rcode_string(unsigned int rcode);
-
-/* returns true if retrying the transaction would not make sense */
-static inline bool rcode_is_permanent_error(int rcode)
-{
- return rcode == RCODE_TYPE_ERROR || rcode == RCODE_ADDRESS_ERROR;
-}
-
-#endif
diff --git a/ANDROID_3.4.5/sound/firewire/packets-buffer.c b/ANDROID_3.4.5/sound/firewire/packets-buffer.c
deleted file mode 100644
index ea150667..00000000
--- a/ANDROID_3.4.5/sound/firewire/packets-buffer.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * helpers for managing a buffer for many packets
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- * Licensed under the terms of the GNU General Public License, version 2.
- */
-
-#include <linux/firewire.h>
-#include <linux/export.h>
-#include <linux/slab.h>
-#include "packets-buffer.h"
-
-/**
- * iso_packets_buffer_init - allocates the memory for packets
- * @b: the buffer structure to initialize
- * @unit: the device at the other end of the stream
- * @count: the number of packets
- * @packet_size: the (maximum) size of a packet, in bytes
- * @direction: %DMA_TO_DEVICE or %DMA_FROM_DEVICE
- */
-int iso_packets_buffer_init(struct iso_packets_buffer *b, struct fw_unit *unit,
- unsigned int count, unsigned int packet_size,
- enum dma_data_direction direction)
-{
- unsigned int packets_per_page, pages;
- unsigned int i, page_index, offset_in_page;
- void *p;
- int err;
-
- b->packets = kmalloc(count * sizeof(*b->packets), GFP_KERNEL);
- if (!b->packets) {
- err = -ENOMEM;
- goto error;
- }
-
- packet_size = L1_CACHE_ALIGN(packet_size);
- packets_per_page = PAGE_SIZE / packet_size;
- if (WARN_ON(!packets_per_page)) {
- err = -EINVAL;
- goto error;
- }
- pages = DIV_ROUND_UP(count, packets_per_page);
-
- err = fw_iso_buffer_init(&b->iso_buffer, fw_parent_device(unit)->card,
- pages, direction);
- if (err < 0)
- goto err_packets;
-
- for (i = 0; i < count; ++i) {
- page_index = i / packets_per_page;
- p = page_address(b->iso_buffer.pages[page_index]);
- offset_in_page = (i % packets_per_page) * packet_size;
- b->packets[i].buffer = p + offset_in_page;
- b->packets[i].offset = page_index * PAGE_SIZE + offset_in_page;
- }
-
- return 0;
-
-err_packets:
- kfree(b->packets);
-error:
- return err;
-}
-EXPORT_SYMBOL(iso_packets_buffer_init);
-
-/**
- * iso_packets_buffer_destroy - frees packet buffer resources
- * @b: the buffer structure to free
- * @unit: the device at the other end of the stream
- */
-void iso_packets_buffer_destroy(struct iso_packets_buffer *b,
- struct fw_unit *unit)
-{
- fw_iso_buffer_destroy(&b->iso_buffer, fw_parent_device(unit)->card);
- kfree(b->packets);
-}
-EXPORT_SYMBOL(iso_packets_buffer_destroy);
diff --git a/ANDROID_3.4.5/sound/firewire/packets-buffer.h b/ANDROID_3.4.5/sound/firewire/packets-buffer.h
deleted file mode 100644
index 6513c5cb..00000000
--- a/ANDROID_3.4.5/sound/firewire/packets-buffer.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef SOUND_FIREWIRE_PACKETS_BUFFER_H_INCLUDED
-#define SOUND_FIREWIRE_PACKETS_BUFFER_H_INCLUDED
-
-#include <linux/dma-mapping.h>
-#include <linux/firewire.h>
-
-/**
- * struct iso_packets_buffer - manages a buffer for many packets
- * @iso_buffer: the memory containing the packets
- * @packets: an array, with each element pointing to one packet
- */
-struct iso_packets_buffer {
- struct fw_iso_buffer iso_buffer;
- struct {
- void *buffer;
- unsigned int offset;
- } *packets;
-};
-
-int iso_packets_buffer_init(struct iso_packets_buffer *b, struct fw_unit *unit,
- unsigned int count, unsigned int packet_size,
- enum dma_data_direction direction);
-void iso_packets_buffer_destroy(struct iso_packets_buffer *b,
- struct fw_unit *unit);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/firewire/speakers.c b/ANDROID_3.4.5/sound/firewire/speakers.c
deleted file mode 100644
index 297244e6..00000000
--- a/ANDROID_3.4.5/sound/firewire/speakers.c
+++ /dev/null
@@ -1,854 +0,0 @@
-/*
- * OXFW970-based speakers driver
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- * Licensed under the terms of the GNU General Public License, version 2.
- */
-
-#include <linux/device.h>
-#include <linux/firewire.h>
-#include <linux/firewire-constants.h>
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include "cmp.h"
-#include "fcp.h"
-#include "amdtp.h"
-#include "lib.h"
-
-#define OXFORD_FIRMWARE_ID_ADDRESS (CSR_REGISTER_BASE + 0x50000)
-/* 0x970?vvvv or 0x971?vvvv, where vvvv = firmware version */
-
-#define OXFORD_HARDWARE_ID_ADDRESS (CSR_REGISTER_BASE + 0x90020)
-#define OXFORD_HARDWARE_ID_OXFW970 0x39443841
-#define OXFORD_HARDWARE_ID_OXFW971 0x39373100
-
-#define VENDOR_GRIFFIN 0x001292
-#define VENDOR_LACIE 0x00d04b
-
-#define SPECIFIER_1394TA 0x00a02d
-#define VERSION_AVC 0x010001
-
-struct device_info {
- const char *driver_name;
- const char *short_name;
- const char *long_name;
- int (*pcm_constraints)(struct snd_pcm_runtime *runtime);
- unsigned int mixer_channels;
- u8 mute_fb_id;
- u8 volume_fb_id;
-};
-
-struct fwspk {
- struct snd_card *card;
- struct fw_unit *unit;
- const struct device_info *device_info;
- struct snd_pcm_substream *pcm;
- struct mutex mutex;
- struct cmp_connection connection;
- struct amdtp_out_stream stream;
- bool stream_running;
- bool mute;
- s16 volume[6];
- s16 volume_min;
- s16 volume_max;
-};
-
-MODULE_DESCRIPTION("FireWire speakers driver");
-MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
-MODULE_LICENSE("GPL v2");
-
-static int firewave_rate_constraint(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- static unsigned int stereo_rates[] = { 48000, 96000 };
- struct snd_interval *channels =
- hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_interval *rate =
- hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
-
- /* two channels work only at 48/96 kHz */
- if (snd_interval_max(channels) < 6)
- return snd_interval_list(rate, 2, stereo_rates, 0);
- return 0;
-}
-
-static int firewave_channels_constraint(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- static const struct snd_interval all_channels = { .min = 6, .max = 6 };
- struct snd_interval *rate =
- hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
- struct snd_interval *channels =
- hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
-
- /* 32/44.1 kHz work only with all six channels */
- if (snd_interval_max(rate) < 48000)
- return snd_interval_refine(channels, &all_channels);
- return 0;
-}
-
-static int firewave_constraints(struct snd_pcm_runtime *runtime)
-{
- static unsigned int channels_list[] = { 2, 6 };
- static struct snd_pcm_hw_constraint_list channels_list_constraint = {
- .count = 2,
- .list = channels_list,
- };
- int err;
-
- runtime->hw.rates = SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_96000;
- runtime->hw.channels_max = 6;
-
- err = snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- &channels_list_constraint);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- firewave_rate_constraint, NULL,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- firewave_channels_constraint, NULL,
- SNDRV_PCM_HW_PARAM_RATE, -1);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static int lacie_speakers_constraints(struct snd_pcm_runtime *runtime)
-{
- runtime->hw.rates = SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000;
-
- return 0;
-}
-
-static int fwspk_open(struct snd_pcm_substream *substream)
-{
- static const struct snd_pcm_hardware hardware = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BATCH |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER,
- .formats = AMDTP_OUT_PCM_FORMAT_BITS,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 4 * 1024 * 1024,
- .period_bytes_min = 1,
- .period_bytes_max = UINT_MAX,
- .periods_min = 1,
- .periods_max = UINT_MAX,
- };
- struct fwspk *fwspk = substream->private_data;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- runtime->hw = hardware;
-
- err = fwspk->device_info->pcm_constraints(runtime);
- if (err < 0)
- return err;
- err = snd_pcm_limit_hw_rates(runtime);
- if (err < 0)
- return err;
-
- err = snd_pcm_hw_constraint_minmax(runtime,
- SNDRV_PCM_HW_PARAM_PERIOD_TIME,
- 5000, UINT_MAX);
- if (err < 0)
- return err;
-
- err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static int fwspk_close(struct snd_pcm_substream *substream)
-{
- return 0;
-}
-
-static void fwspk_stop_stream(struct fwspk *fwspk)
-{
- if (fwspk->stream_running) {
- amdtp_out_stream_stop(&fwspk->stream);
- cmp_connection_break(&fwspk->connection);
- fwspk->stream_running = false;
- }
-}
-
-static int fwspk_set_rate(struct fwspk *fwspk, unsigned int sfc)
-{
- u8 *buf;
- int err;
-
- buf = kmalloc(8, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- buf[0] = 0x00; /* AV/C, CONTROL */
- buf[1] = 0xff; /* unit */
- buf[2] = 0x19; /* INPUT PLUG SIGNAL FORMAT */
- buf[3] = 0x00; /* plug 0 */
- buf[4] = 0x90; /* format: audio */
- buf[5] = 0x00 | sfc; /* AM824, frequency */
- buf[6] = 0xff; /* SYT (not used) */
- buf[7] = 0xff;
-
- err = fcp_avc_transaction(fwspk->unit, buf, 8, buf, 8,
- BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5));
- if (err < 0)
- goto error;
- if (err < 6 || buf[0] != 0x09 /* ACCEPTED */) {
- dev_err(&fwspk->unit->device, "failed to set sample rate\n");
- err = -EIO;
- goto error;
- }
-
- err = 0;
-
-error:
- kfree(buf);
-
- return err;
-}
-
-static int fwspk_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct fwspk *fwspk = substream->private_data;
- int err;
-
- mutex_lock(&fwspk->mutex);
- fwspk_stop_stream(fwspk);
- mutex_unlock(&fwspk->mutex);
-
- err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
- params_buffer_bytes(hw_params));
- if (err < 0)
- goto error;
-
- amdtp_out_stream_set_rate(&fwspk->stream, params_rate(hw_params));
- amdtp_out_stream_set_pcm(&fwspk->stream, params_channels(hw_params));
-
- amdtp_out_stream_set_pcm_format(&fwspk->stream,
- params_format(hw_params));
-
- err = fwspk_set_rate(fwspk, fwspk->stream.sfc);
- if (err < 0)
- goto err_buffer;
-
- return 0;
-
-err_buffer:
- snd_pcm_lib_free_vmalloc_buffer(substream);
-error:
- return err;
-}
-
-static int fwspk_hw_free(struct snd_pcm_substream *substream)
-{
- struct fwspk *fwspk = substream->private_data;
-
- mutex_lock(&fwspk->mutex);
- fwspk_stop_stream(fwspk);
- mutex_unlock(&fwspk->mutex);
-
- return snd_pcm_lib_free_vmalloc_buffer(substream);
-}
-
-static int fwspk_prepare(struct snd_pcm_substream *substream)
-{
- struct fwspk *fwspk = substream->private_data;
- int err;
-
- mutex_lock(&fwspk->mutex);
-
- if (amdtp_out_streaming_error(&fwspk->stream))
- fwspk_stop_stream(fwspk);
-
- if (!fwspk->stream_running) {
- err = cmp_connection_establish(&fwspk->connection,
- amdtp_out_stream_get_max_payload(&fwspk->stream));
- if (err < 0)
- goto err_mutex;
-
- err = amdtp_out_stream_start(&fwspk->stream,
- fwspk->connection.resources.channel,
- fwspk->connection.speed);
- if (err < 0)
- goto err_connection;
-
- fwspk->stream_running = true;
- }
-
- mutex_unlock(&fwspk->mutex);
-
- amdtp_out_stream_pcm_prepare(&fwspk->stream);
-
- return 0;
-
-err_connection:
- cmp_connection_break(&fwspk->connection);
-err_mutex:
- mutex_unlock(&fwspk->mutex);
-
- return err;
-}
-
-static int fwspk_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct fwspk *fwspk = substream->private_data;
- struct snd_pcm_substream *pcm;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- pcm = substream;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- pcm = NULL;
- break;
- default:
- return -EINVAL;
- }
- amdtp_out_stream_pcm_trigger(&fwspk->stream, pcm);
- return 0;
-}
-
-static snd_pcm_uframes_t fwspk_pointer(struct snd_pcm_substream *substream)
-{
- struct fwspk *fwspk = substream->private_data;
-
- return amdtp_out_stream_pcm_pointer(&fwspk->stream);
-}
-
-static int fwspk_create_pcm(struct fwspk *fwspk)
-{
- static struct snd_pcm_ops ops = {
- .open = fwspk_open,
- .close = fwspk_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = fwspk_hw_params,
- .hw_free = fwspk_hw_free,
- .prepare = fwspk_prepare,
- .trigger = fwspk_trigger,
- .pointer = fwspk_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
- };
- struct snd_pcm *pcm;
- int err;
-
- err = snd_pcm_new(fwspk->card, "OXFW970", 0, 1, 0, &pcm);
- if (err < 0)
- return err;
- pcm->private_data = fwspk;
- strcpy(pcm->name, fwspk->device_info->short_name);
- fwspk->pcm = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
- fwspk->pcm->ops = &ops;
- return 0;
-}
-
-enum control_action { CTL_READ, CTL_WRITE };
-enum control_attribute {
- CTL_MIN = 0x02,
- CTL_MAX = 0x03,
- CTL_CURRENT = 0x10,
-};
-
-static int fwspk_mute_command(struct fwspk *fwspk, bool *value,
- enum control_action action)
-{
- u8 *buf;
- u8 response_ok;
- int err;
-
- buf = kmalloc(11, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- if (action == CTL_READ) {
- buf[0] = 0x01; /* AV/C, STATUS */
- response_ok = 0x0c; /* STABLE */
- } else {
- buf[0] = 0x00; /* AV/C, CONTROL */
- response_ok = 0x09; /* ACCEPTED */
- }
- buf[1] = 0x08; /* audio unit 0 */
- buf[2] = 0xb8; /* FUNCTION BLOCK */
- buf[3] = 0x81; /* function block type: feature */
- buf[4] = fwspk->device_info->mute_fb_id; /* function block ID */
- buf[5] = 0x10; /* control attribute: current */
- buf[6] = 0x02; /* selector length */
- buf[7] = 0x00; /* audio channel number */
- buf[8] = 0x01; /* control selector: mute */
- buf[9] = 0x01; /* control data length */
- if (action == CTL_READ)
- buf[10] = 0xff;
- else
- buf[10] = *value ? 0x70 : 0x60;
-
- err = fcp_avc_transaction(fwspk->unit, buf, 11, buf, 11, 0x3fe);
- if (err < 0)
- goto error;
- if (err < 11) {
- dev_err(&fwspk->unit->device, "short FCP response\n");
- err = -EIO;
- goto error;
- }
- if (buf[0] != response_ok) {
- dev_err(&fwspk->unit->device, "mute command failed\n");
- err = -EIO;
- goto error;
- }
- if (action == CTL_READ)
- *value = buf[10] == 0x70;
-
- err = 0;
-
-error:
- kfree(buf);
-
- return err;
-}
-
-static int fwspk_volume_command(struct fwspk *fwspk, s16 *value,
- unsigned int channel,
- enum control_attribute attribute,
- enum control_action action)
-{
- u8 *buf;
- u8 response_ok;
- int err;
-
- buf = kmalloc(12, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- if (action == CTL_READ) {
- buf[0] = 0x01; /* AV/C, STATUS */
- response_ok = 0x0c; /* STABLE */
- } else {
- buf[0] = 0x00; /* AV/C, CONTROL */
- response_ok = 0x09; /* ACCEPTED */
- }
- buf[1] = 0x08; /* audio unit 0 */
- buf[2] = 0xb8; /* FUNCTION BLOCK */
- buf[3] = 0x81; /* function block type: feature */
- buf[4] = fwspk->device_info->volume_fb_id; /* function block ID */
- buf[5] = attribute; /* control attribute */
- buf[6] = 0x02; /* selector length */
- buf[7] = channel; /* audio channel number */
- buf[8] = 0x02; /* control selector: volume */
- buf[9] = 0x02; /* control data length */
- if (action == CTL_READ) {
- buf[10] = 0xff;
- buf[11] = 0xff;
- } else {
- buf[10] = *value >> 8;
- buf[11] = *value;
- }
-
- err = fcp_avc_transaction(fwspk->unit, buf, 12, buf, 12, 0x3fe);
- if (err < 0)
- goto error;
- if (err < 12) {
- dev_err(&fwspk->unit->device, "short FCP response\n");
- err = -EIO;
- goto error;
- }
- if (buf[0] != response_ok) {
- dev_err(&fwspk->unit->device, "volume command failed\n");
- err = -EIO;
- goto error;
- }
- if (action == CTL_READ)
- *value = (buf[10] << 8) | buf[11];
-
- err = 0;
-
-error:
- kfree(buf);
-
- return err;
-}
-
-static int fwspk_mute_get(struct snd_kcontrol *control,
- struct snd_ctl_elem_value *value)
-{
- struct fwspk *fwspk = control->private_data;
-
- value->value.integer.value[0] = !fwspk->mute;
-
- return 0;
-}
-
-static int fwspk_mute_put(struct snd_kcontrol *control,
- struct snd_ctl_elem_value *value)
-{
- struct fwspk *fwspk = control->private_data;
- bool mute;
- int err;
-
- mute = !value->value.integer.value[0];
-
- if (mute == fwspk->mute)
- return 0;
-
- err = fwspk_mute_command(fwspk, &mute, CTL_WRITE);
- if (err < 0)
- return err;
- fwspk->mute = mute;
-
- return 1;
-}
-
-static int fwspk_volume_info(struct snd_kcontrol *control,
- struct snd_ctl_elem_info *info)
-{
- struct fwspk *fwspk = control->private_data;
-
- info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- info->count = fwspk->device_info->mixer_channels;
- info->value.integer.min = fwspk->volume_min;
- info->value.integer.max = fwspk->volume_max;
-
- return 0;
-}
-
-static const u8 channel_map[6] = { 0, 1, 4, 5, 2, 3 };
-
-static int fwspk_volume_get(struct snd_kcontrol *control,
- struct snd_ctl_elem_value *value)
-{
- struct fwspk *fwspk = control->private_data;
- unsigned int i;
-
- for (i = 0; i < fwspk->device_info->mixer_channels; ++i)
- value->value.integer.value[channel_map[i]] = fwspk->volume[i];
-
- return 0;
-}
-
-static int fwspk_volume_put(struct snd_kcontrol *control,
- struct snd_ctl_elem_value *value)
-{
- struct fwspk *fwspk = control->private_data;
- unsigned int i, changed_channels;
- bool equal_values = true;
- s16 volume;
- int err;
-
- for (i = 0; i < fwspk->device_info->mixer_channels; ++i) {
- if (value->value.integer.value[i] < fwspk->volume_min ||
- value->value.integer.value[i] > fwspk->volume_max)
- return -EINVAL;
- if (value->value.integer.value[i] !=
- value->value.integer.value[0])
- equal_values = false;
- }
-
- changed_channels = 0;
- for (i = 0; i < fwspk->device_info->mixer_channels; ++i)
- if (value->value.integer.value[channel_map[i]] !=
- fwspk->volume[i])
- changed_channels |= 1 << (i + 1);
-
- if (equal_values && changed_channels != 0)
- changed_channels = 1 << 0;
-
- for (i = 0; i <= fwspk->device_info->mixer_channels; ++i) {
- volume = value->value.integer.value[channel_map[i ? i - 1 : 0]];
- if (changed_channels & (1 << i)) {
- err = fwspk_volume_command(fwspk, &volume, i,
- CTL_CURRENT, CTL_WRITE);
- if (err < 0)
- return err;
- }
- if (i > 0)
- fwspk->volume[i - 1] = volume;
- }
-
- return changed_channels != 0;
-}
-
-static int fwspk_create_mixer(struct fwspk *fwspk)
-{
- static const struct snd_kcontrol_new controls[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Playback Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = fwspk_mute_get,
- .put = fwspk_mute_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Playback Volume",
- .info = fwspk_volume_info,
- .get = fwspk_volume_get,
- .put = fwspk_volume_put,
- },
- };
- unsigned int i, first_ch;
- int err;
-
- err = fwspk_volume_command(fwspk, &fwspk->volume_min,
- 0, CTL_MIN, CTL_READ);
- if (err < 0)
- return err;
- err = fwspk_volume_command(fwspk, &fwspk->volume_max,
- 0, CTL_MAX, CTL_READ);
- if (err < 0)
- return err;
-
- err = fwspk_mute_command(fwspk, &fwspk->mute, CTL_READ);
- if (err < 0)
- return err;
-
- first_ch = fwspk->device_info->mixer_channels == 1 ? 0 : 1;
- for (i = 0; i < fwspk->device_info->mixer_channels; ++i) {
- err = fwspk_volume_command(fwspk, &fwspk->volume[i],
- first_ch + i, CTL_CURRENT, CTL_READ);
- if (err < 0)
- return err;
- }
-
- for (i = 0; i < ARRAY_SIZE(controls); ++i) {
- err = snd_ctl_add(fwspk->card,
- snd_ctl_new1(&controls[i], fwspk));
- if (err < 0)
- return err;
- }
-
- return 0;
-}
-
-static u32 fwspk_read_firmware_version(struct fw_unit *unit)
-{
- __be32 data;
- int err;
-
- err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST,
- OXFORD_FIRMWARE_ID_ADDRESS, &data, 4);
- return err >= 0 ? be32_to_cpu(data) : 0;
-}
-
-static void fwspk_card_free(struct snd_card *card)
-{
- struct fwspk *fwspk = card->private_data;
-
- amdtp_out_stream_destroy(&fwspk->stream);
- cmp_connection_destroy(&fwspk->connection);
- fw_unit_put(fwspk->unit);
- mutex_destroy(&fwspk->mutex);
-}
-
-static const struct device_info *__devinit fwspk_detect(struct fw_device *dev)
-{
- static const struct device_info griffin_firewave = {
- .driver_name = "FireWave",
- .short_name = "FireWave",
- .long_name = "Griffin FireWave Surround",
- .pcm_constraints = firewave_constraints,
- .mixer_channels = 6,
- .mute_fb_id = 0x01,
- .volume_fb_id = 0x02,
- };
- static const struct device_info lacie_speakers = {
- .driver_name = "FWSpeakers",
- .short_name = "FireWire Speakers",
- .long_name = "LaCie FireWire Speakers",
- .pcm_constraints = lacie_speakers_constraints,
- .mixer_channels = 1,
- .mute_fb_id = 0x01,
- .volume_fb_id = 0x01,
- };
- struct fw_csr_iterator i;
- int key, value;
-
- fw_csr_iterator_init(&i, dev->config_rom);
- while (fw_csr_iterator_next(&i, &key, &value))
- if (key == CSR_VENDOR)
- switch (value) {
- case VENDOR_GRIFFIN:
- return &griffin_firewave;
- case VENDOR_LACIE:
- return &lacie_speakers;
- }
-
- return NULL;
-}
-
-static int __devinit fwspk_probe(struct device *unit_dev)
-{
- struct fw_unit *unit = fw_unit(unit_dev);
- struct fw_device *fw_dev = fw_parent_device(unit);
- struct snd_card *card;
- struct fwspk *fwspk;
- u32 firmware;
- int err;
-
- err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*fwspk), &card);
- if (err < 0)
- return err;
- snd_card_set_dev(card, unit_dev);
-
- fwspk = card->private_data;
- fwspk->card = card;
- mutex_init(&fwspk->mutex);
- fwspk->unit = fw_unit_get(unit);
- fwspk->device_info = fwspk_detect(fw_dev);
- if (!fwspk->device_info) {
- err = -ENODEV;
- goto err_unit;
- }
-
- err = cmp_connection_init(&fwspk->connection, unit, 0);
- if (err < 0)
- goto err_unit;
-
- err = amdtp_out_stream_init(&fwspk->stream, unit, CIP_NONBLOCKING);
- if (err < 0)
- goto err_connection;
-
- card->private_free = fwspk_card_free;
-
- strcpy(card->driver, fwspk->device_info->driver_name);
- strcpy(card->shortname, fwspk->device_info->short_name);
- firmware = fwspk_read_firmware_version(unit);
- snprintf(card->longname, sizeof(card->longname),
- "%s (OXFW%x %04x), GUID %08x%08x at %s, S%d",
- fwspk->device_info->long_name,
- firmware >> 20, firmware & 0xffff,
- fw_dev->config_rom[3], fw_dev->config_rom[4],
- dev_name(&unit->device), 100 << fw_dev->max_speed);
- strcpy(card->mixername, "OXFW970");
-
- err = fwspk_create_pcm(fwspk);
- if (err < 0)
- goto error;
-
- err = fwspk_create_mixer(fwspk);
- if (err < 0)
- goto error;
-
- err = snd_card_register(card);
- if (err < 0)
- goto error;
-
- dev_set_drvdata(unit_dev, fwspk);
-
- return 0;
-
-err_connection:
- cmp_connection_destroy(&fwspk->connection);
-err_unit:
- fw_unit_put(fwspk->unit);
- mutex_destroy(&fwspk->mutex);
-error:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit fwspk_remove(struct device *dev)
-{
- struct fwspk *fwspk = dev_get_drvdata(dev);
-
- amdtp_out_stream_pcm_abort(&fwspk->stream);
- snd_card_disconnect(fwspk->card);
-
- mutex_lock(&fwspk->mutex);
- fwspk_stop_stream(fwspk);
- mutex_unlock(&fwspk->mutex);
-
- snd_card_free_when_closed(fwspk->card);
-
- return 0;
-}
-
-static void fwspk_bus_reset(struct fw_unit *unit)
-{
- struct fwspk *fwspk = dev_get_drvdata(&unit->device);
-
- fcp_bus_reset(fwspk->unit);
-
- if (cmp_connection_update(&fwspk->connection) < 0) {
- amdtp_out_stream_pcm_abort(&fwspk->stream);
- mutex_lock(&fwspk->mutex);
- fwspk_stop_stream(fwspk);
- mutex_unlock(&fwspk->mutex);
- return;
- }
-
- amdtp_out_stream_update(&fwspk->stream);
-}
-
-static const struct ieee1394_device_id fwspk_id_table[] = {
- {
- .match_flags = IEEE1394_MATCH_VENDOR_ID |
- IEEE1394_MATCH_MODEL_ID |
- IEEE1394_MATCH_SPECIFIER_ID |
- IEEE1394_MATCH_VERSION,
- .vendor_id = VENDOR_GRIFFIN,
- .model_id = 0x00f970,
- .specifier_id = SPECIFIER_1394TA,
- .version = VERSION_AVC,
- },
- {
- .match_flags = IEEE1394_MATCH_VENDOR_ID |
- IEEE1394_MATCH_MODEL_ID |
- IEEE1394_MATCH_SPECIFIER_ID |
- IEEE1394_MATCH_VERSION,
- .vendor_id = VENDOR_LACIE,
- .model_id = 0x00f970,
- .specifier_id = SPECIFIER_1394TA,
- .version = VERSION_AVC,
- },
- { }
-};
-MODULE_DEVICE_TABLE(ieee1394, fwspk_id_table);
-
-static struct fw_driver fwspk_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = KBUILD_MODNAME,
- .bus = &fw_bus_type,
- .probe = fwspk_probe,
- .remove = __devexit_p(fwspk_remove),
- },
- .update = fwspk_bus_reset,
- .id_table = fwspk_id_table,
-};
-
-static int __init alsa_fwspk_init(void)
-{
- return driver_register(&fwspk_driver.driver);
-}
-
-static void __exit alsa_fwspk_exit(void)
-{
- driver_unregister(&fwspk_driver.driver);
-}
-
-module_init(alsa_fwspk_init);
-module_exit(alsa_fwspk_exit);
diff --git a/ANDROID_3.4.5/sound/i2c/Makefile b/ANDROID_3.4.5/sound/i2c/Makefile
deleted file mode 100644
index 36879bf8..00000000
--- a/ANDROID_3.4.5/sound/i2c/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-i2c-objs := i2c.o
-snd-cs8427-objs := cs8427.o
-snd-tea6330t-objs := tea6330t.o
-
-obj-$(CONFIG_SND) += other/
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_INTERWAVE_STB) += snd-tea6330t.o snd-i2c.o
-obj-$(CONFIG_SND_ICE1712) += snd-cs8427.o snd-i2c.o
-obj-$(CONFIG_SND_ICE1724) += snd-i2c.o
diff --git a/ANDROID_3.4.5/sound/i2c/cs8427.c b/ANDROID_3.4.5/sound/i2c/cs8427.c
deleted file mode 100644
index 6c2dc386..00000000
--- a/ANDROID_3.4.5/sound/i2c/cs8427.c
+++ /dev/null
@@ -1,616 +0,0 @@
-/*
- * Routines for control of the CS8427 via i2c bus
- * IEC958 (S/PDIF) receiver & transmitter by Cirrus Logic
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/bitrev.h>
-#include <linux/module.h>
-#include <asm/unaligned.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/cs8427.h>
-#include <sound/asoundef.h>
-
-static void snd_cs8427_reset(struct snd_i2c_device *cs8427);
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("IEC958 (S/PDIF) receiver & transmitter by Cirrus Logic");
-MODULE_LICENSE("GPL");
-
-#define CS8427_ADDR (0x20>>1) /* fixed address */
-
-struct cs8427_stream {
- struct snd_pcm_substream *substream;
- char hw_status[24]; /* hardware status */
- char def_status[24]; /* default status */
- char pcm_status[24]; /* PCM private status */
- char hw_udata[32];
- struct snd_kcontrol *pcm_ctl;
-};
-
-struct cs8427 {
- unsigned char regmap[0x14]; /* map of first 1 + 13 registers */
- unsigned int rate;
- unsigned int reset_timeout;
- struct cs8427_stream playback;
- struct cs8427_stream capture;
-};
-
-int snd_cs8427_reg_write(struct snd_i2c_device *device, unsigned char reg,
- unsigned char val)
-{
- int err;
- unsigned char buf[2];
-
- buf[0] = reg & 0x7f;
- buf[1] = val;
- if ((err = snd_i2c_sendbytes(device, buf, 2)) != 2) {
- snd_printk(KERN_ERR "unable to send bytes 0x%02x:0x%02x "
- "to CS8427 (%i)\n", buf[0], buf[1], err);
- return err < 0 ? err : -EIO;
- }
- return 0;
-}
-
-EXPORT_SYMBOL(snd_cs8427_reg_write);
-
-static int snd_cs8427_reg_read(struct snd_i2c_device *device, unsigned char reg)
-{
- int err;
- unsigned char buf;
-
- if ((err = snd_i2c_sendbytes(device, &reg, 1)) != 1) {
- snd_printk(KERN_ERR "unable to send register 0x%x byte "
- "to CS8427\n", reg);
- return err < 0 ? err : -EIO;
- }
- if ((err = snd_i2c_readbytes(device, &buf, 1)) != 1) {
- snd_printk(KERN_ERR "unable to read register 0x%x byte "
- "from CS8427\n", reg);
- return err < 0 ? err : -EIO;
- }
- return buf;
-}
-
-static int snd_cs8427_select_corudata(struct snd_i2c_device *device, int udata)
-{
- struct cs8427 *chip = device->private_data;
- int err;
-
- udata = udata ? CS8427_BSEL : 0;
- if (udata != (chip->regmap[CS8427_REG_CSDATABUF] & udata)) {
- chip->regmap[CS8427_REG_CSDATABUF] &= ~CS8427_BSEL;
- chip->regmap[CS8427_REG_CSDATABUF] |= udata;
- err = snd_cs8427_reg_write(device, CS8427_REG_CSDATABUF,
- chip->regmap[CS8427_REG_CSDATABUF]);
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-static int snd_cs8427_send_corudata(struct snd_i2c_device *device,
- int udata,
- unsigned char *ndata,
- int count)
-{
- struct cs8427 *chip = device->private_data;
- char *hw_data = udata ?
- chip->playback.hw_udata : chip->playback.hw_status;
- char data[32];
- int err, idx;
-
- if (!memcmp(hw_data, ndata, count))
- return 0;
- if ((err = snd_cs8427_select_corudata(device, udata)) < 0)
- return err;
- memcpy(hw_data, ndata, count);
- if (udata) {
- memset(data, 0, sizeof(data));
- if (memcmp(hw_data, data, count) == 0) {
- chip->regmap[CS8427_REG_UDATABUF] &= ~CS8427_UBMMASK;
- chip->regmap[CS8427_REG_UDATABUF] |= CS8427_UBMZEROS |
- CS8427_EFTUI;
- err = snd_cs8427_reg_write(device, CS8427_REG_UDATABUF,
- chip->regmap[CS8427_REG_UDATABUF]);
- return err < 0 ? err : 0;
- }
- }
- data[0] = CS8427_REG_AUTOINC | CS8427_REG_CORU_DATABUF;
- for (idx = 0; idx < count; idx++)
- data[idx + 1] = bitrev8(ndata[idx]);
- if (snd_i2c_sendbytes(device, data, count + 1) != count + 1)
- return -EIO;
- return 1;
-}
-
-static void snd_cs8427_free(struct snd_i2c_device *device)
-{
- kfree(device->private_data);
-}
-
-int snd_cs8427_create(struct snd_i2c_bus *bus,
- unsigned char addr,
- unsigned int reset_timeout,
- struct snd_i2c_device **r_cs8427)
-{
- static unsigned char initvals1[] = {
- CS8427_REG_CONTROL1 | CS8427_REG_AUTOINC,
- /* CS8427_REG_CONTROL1: RMCK to OMCK, valid PCM audio, disable mutes,
- TCBL=output */
- CS8427_SWCLK | CS8427_TCBLDIR,
- /* CS8427_REG_CONTROL2: hold last valid audio sample, RMCK=256*Fs,
- normal stereo operation */
- 0x00,
- /* CS8427_REG_DATAFLOW: output drivers normal operation, Tx<=serial,
- Rx=>serial */
- CS8427_TXDSERIAL | CS8427_SPDAES3RECEIVER,
- /* CS8427_REG_CLOCKSOURCE: Run off, CMCK=256*Fs,
- output time base = OMCK, input time base = recovered input clock,
- recovered input clock source is ILRCK changed to AES3INPUT
- (workaround, see snd_cs8427_reset) */
- CS8427_RXDILRCK,
- /* CS8427_REG_SERIALINPUT: Serial audio input port data format = I2S,
- 24-bit, 64*Fsi */
- CS8427_SIDEL | CS8427_SILRPOL,
- /* CS8427_REG_SERIALOUTPUT: Serial audio output port data format
- = I2S, 24-bit, 64*Fsi */
- CS8427_SODEL | CS8427_SOLRPOL,
- };
- static unsigned char initvals2[] = {
- CS8427_REG_RECVERRMASK | CS8427_REG_AUTOINC,
- /* CS8427_REG_RECVERRMASK: unmask the input PLL clock, V, confidence,
- biphase, parity status bits */
- /* CS8427_UNLOCK | CS8427_V | CS8427_CONF | CS8427_BIP | CS8427_PAR,*/
- 0xff, /* set everything */
- /* CS8427_REG_CSDATABUF:
- Registers 32-55 window to CS buffer
- Inhibit D->E transfers from overwriting first 5 bytes of CS data.
- Inhibit D->E transfers (all) of CS data.
- Allow E->F transfer of CS data.
- One byte mode; both A/B channels get same written CB data.
- A channel info is output to chip's EMPH* pin. */
- CS8427_CBMR | CS8427_DETCI,
- /* CS8427_REG_UDATABUF:
- Use internal buffer to transmit User (U) data.
- Chip's U pin is an output.
- Transmit all O's for user data.
- Inhibit D->E transfers.
- Inhibit E->F transfers. */
- CS8427_UD | CS8427_EFTUI | CS8427_DETUI,
- };
- int err;
- struct cs8427 *chip;
- struct snd_i2c_device *device;
- unsigned char buf[24];
-
- if ((err = snd_i2c_device_create(bus, "CS8427",
- CS8427_ADDR | (addr & 7),
- &device)) < 0)
- return err;
- chip = device->private_data = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- snd_i2c_device_free(device);
- return -ENOMEM;
- }
- device->private_free = snd_cs8427_free;
-
- snd_i2c_lock(bus);
- err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER);
- if (err != CS8427_VER8427A) {
- /* give second chance */
- snd_printk(KERN_WARNING "invalid CS8427 signature 0x%x: "
- "let me try again...\n", err);
- err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER);
- }
- if (err != CS8427_VER8427A) {
- snd_i2c_unlock(bus);
- snd_printk(KERN_ERR "unable to find CS8427 signature "
- "(expected 0x%x, read 0x%x),\n",
- CS8427_VER8427A, err);
- snd_printk(KERN_ERR " initialization is not completed\n");
- return -EFAULT;
- }
- /* turn off run bit while making changes to configuration */
- err = snd_cs8427_reg_write(device, CS8427_REG_CLOCKSOURCE, 0x00);
- if (err < 0)
- goto __fail;
- /* send initial values */
- memcpy(chip->regmap + (initvals1[0] & 0x7f), initvals1 + 1, 6);
- if ((err = snd_i2c_sendbytes(device, initvals1, 7)) != 7) {
- err = err < 0 ? err : -EIO;
- goto __fail;
- }
- /* Turn off CS8427 interrupt stuff that is not used in hardware */
- memset(buf, 0, 7);
- /* from address 9 to 15 */
- buf[0] = 9; /* register */
- if ((err = snd_i2c_sendbytes(device, buf, 7)) != 7)
- goto __fail;
- /* send transfer initialization sequence */
- memcpy(chip->regmap + (initvals2[0] & 0x7f), initvals2 + 1, 3);
- if ((err = snd_i2c_sendbytes(device, initvals2, 4)) != 4) {
- err = err < 0 ? err : -EIO;
- goto __fail;
- }
- /* write default channel status bytes */
- put_unaligned_le32(SNDRV_PCM_DEFAULT_CON_SPDIF, buf);
- memset(buf + 4, 0, 24 - 4);
- if (snd_cs8427_send_corudata(device, 0, buf, 24) < 0)
- goto __fail;
- memcpy(chip->playback.def_status, buf, 24);
- memcpy(chip->playback.pcm_status, buf, 24);
- snd_i2c_unlock(bus);
-
- /* turn on run bit and rock'n'roll */
- if (reset_timeout < 1)
- reset_timeout = 1;
- chip->reset_timeout = reset_timeout;
- snd_cs8427_reset(device);
-
-#if 0 // it's nice for read tests
- {
- char buf[128];
- int xx;
- buf[0] = 0x81;
- snd_i2c_sendbytes(device, buf, 1);
- snd_i2c_readbytes(device, buf, 127);
- for (xx = 0; xx < 127; xx++)
- printk(KERN_DEBUG "reg[0x%x] = 0x%x\n", xx+1, buf[xx]);
- }
-#endif
-
- if (r_cs8427)
- *r_cs8427 = device;
- return 0;
-
- __fail:
- snd_i2c_unlock(bus);
- snd_i2c_device_free(device);
- return err < 0 ? err : -EIO;
-}
-
-EXPORT_SYMBOL(snd_cs8427_create);
-
-/*
- * Reset the chip using run bit, also lock PLL using ILRCK and
- * put back AES3INPUT. This workaround is described in latest
- * CS8427 datasheet, otherwise TXDSERIAL will not work.
- */
-static void snd_cs8427_reset(struct snd_i2c_device *cs8427)
-{
- struct cs8427 *chip;
- unsigned long end_time;
- int data, aes3input = 0;
-
- if (snd_BUG_ON(!cs8427))
- return;
- chip = cs8427->private_data;
- snd_i2c_lock(cs8427->bus);
- if ((chip->regmap[CS8427_REG_CLOCKSOURCE] & CS8427_RXDAES3INPUT) ==
- CS8427_RXDAES3INPUT) /* AES3 bit is set */
- aes3input = 1;
- chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~(CS8427_RUN | CS8427_RXDMASK);
- snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,
- chip->regmap[CS8427_REG_CLOCKSOURCE]);
- udelay(200);
- chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RUN | CS8427_RXDILRCK;
- snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,
- chip->regmap[CS8427_REG_CLOCKSOURCE]);
- udelay(200);
- snd_i2c_unlock(cs8427->bus);
- end_time = jiffies + chip->reset_timeout;
- while (time_after_eq(end_time, jiffies)) {
- snd_i2c_lock(cs8427->bus);
- data = snd_cs8427_reg_read(cs8427, CS8427_REG_RECVERRORS);
- snd_i2c_unlock(cs8427->bus);
- if (!(data & CS8427_UNLOCK))
- break;
- schedule_timeout_uninterruptible(1);
- }
- snd_i2c_lock(cs8427->bus);
- chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~CS8427_RXDMASK;
- if (aes3input)
- chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RXDAES3INPUT;
- snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,
- chip->regmap[CS8427_REG_CLOCKSOURCE]);
- snd_i2c_unlock(cs8427->bus);
-}
-
-static int snd_cs8427_in_status_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 255;
- return 0;
-}
-
-static int snd_cs8427_in_status_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);
- int data;
-
- snd_i2c_lock(device->bus);
- data = snd_cs8427_reg_read(device, kcontrol->private_value);
- snd_i2c_unlock(device->bus);
- if (data < 0)
- return data;
- ucontrol->value.integer.value[0] = data;
- return 0;
-}
-
-static int snd_cs8427_qsubcode_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
- uinfo->count = 10;
- return 0;
-}
-
-static int snd_cs8427_qsubcode_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);
- unsigned char reg = CS8427_REG_QSUBCODE;
- int err;
-
- snd_i2c_lock(device->bus);
- if ((err = snd_i2c_sendbytes(device, &reg, 1)) != 1) {
- snd_printk(KERN_ERR "unable to send register 0x%x byte "
- "to CS8427\n", reg);
- snd_i2c_unlock(device->bus);
- return err < 0 ? err : -EIO;
- }
- err = snd_i2c_readbytes(device, ucontrol->value.bytes.data, 10);
- if (err != 10) {
- snd_printk(KERN_ERR "unable to read Q-subcode bytes "
- "from CS8427\n");
- snd_i2c_unlock(device->bus);
- return err < 0 ? err : -EIO;
- }
- snd_i2c_unlock(device->bus);
- return 0;
-}
-
-static int snd_cs8427_spdif_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_cs8427_spdif_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);
- struct cs8427 *chip = device->private_data;
-
- snd_i2c_lock(device->bus);
- memcpy(ucontrol->value.iec958.status, chip->playback.def_status, 24);
- snd_i2c_unlock(device->bus);
- return 0;
-}
-
-static int snd_cs8427_spdif_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);
- struct cs8427 *chip = device->private_data;
- unsigned char *status = kcontrol->private_value ?
- chip->playback.pcm_status : chip->playback.def_status;
- struct snd_pcm_runtime *runtime = chip->playback.substream ?
- chip->playback.substream->runtime : NULL;
- int err, change;
-
- snd_i2c_lock(device->bus);
- change = memcmp(ucontrol->value.iec958.status, status, 24) != 0;
- memcpy(status, ucontrol->value.iec958.status, 24);
- if (change && (kcontrol->private_value ?
- runtime != NULL : runtime == NULL)) {
- err = snd_cs8427_send_corudata(device, 0, status, 24);
- if (err < 0)
- change = err;
- }
- snd_i2c_unlock(device->bus);
- return change;
-}
-
-static int snd_cs8427_spdif_mask_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_cs8427_spdif_mask_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- memset(ucontrol->value.iec958.status, 0xff, 24);
- return 0;
-}
-
-static struct snd_kcontrol_new snd_cs8427_iec958_controls[] = {
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .info = snd_cs8427_in_status_info,
- .name = "IEC958 CS8427 Input Status",
- .access = (SNDRV_CTL_ELEM_ACCESS_READ |
- SNDRV_CTL_ELEM_ACCESS_VOLATILE),
- .get = snd_cs8427_in_status_get,
- .private_value = 15,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .info = snd_cs8427_in_status_info,
- .name = "IEC958 CS8427 Error Status",
- .access = (SNDRV_CTL_ELEM_ACCESS_READ |
- SNDRV_CTL_ELEM_ACCESS_VOLATILE),
- .get = snd_cs8427_in_status_get,
- .private_value = 16,
-},
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
- .info = snd_cs8427_spdif_mask_info,
- .get = snd_cs8427_spdif_mask_get,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
- .info = snd_cs8427_spdif_info,
- .get = snd_cs8427_spdif_get,
- .put = snd_cs8427_spdif_put,
- .private_value = 0
-},
-{
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_INACTIVE),
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
- .info = snd_cs8427_spdif_info,
- .get = snd_cs8427_spdif_get,
- .put = snd_cs8427_spdif_put,
- .private_value = 1
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .info = snd_cs8427_qsubcode_info,
- .name = "IEC958 Q-subcode Capture Default",
- .access = (SNDRV_CTL_ELEM_ACCESS_READ |
- SNDRV_CTL_ELEM_ACCESS_VOLATILE),
- .get = snd_cs8427_qsubcode_get
-}};
-
-int snd_cs8427_iec958_build(struct snd_i2c_device *cs8427,
- struct snd_pcm_substream *play_substream,
- struct snd_pcm_substream *cap_substream)
-{
- struct cs8427 *chip = cs8427->private_data;
- struct snd_kcontrol *kctl;
- unsigned int idx;
- int err;
-
- if (snd_BUG_ON(!play_substream || !cap_substream))
- return -EINVAL;
- for (idx = 0; idx < ARRAY_SIZE(snd_cs8427_iec958_controls); idx++) {
- kctl = snd_ctl_new1(&snd_cs8427_iec958_controls[idx], cs8427);
- if (kctl == NULL)
- return -ENOMEM;
- kctl->id.device = play_substream->pcm->device;
- kctl->id.subdevice = play_substream->number;
- err = snd_ctl_add(cs8427->bus->card, kctl);
- if (err < 0)
- return err;
- if (! strcmp(kctl->id.name,
- SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM)))
- chip->playback.pcm_ctl = kctl;
- }
-
- chip->playback.substream = play_substream;
- chip->capture.substream = cap_substream;
- if (snd_BUG_ON(!chip->playback.pcm_ctl))
- return -EIO;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_cs8427_iec958_build);
-
-int snd_cs8427_iec958_active(struct snd_i2c_device *cs8427, int active)
-{
- struct cs8427 *chip;
-
- if (snd_BUG_ON(!cs8427))
- return -ENXIO;
- chip = cs8427->private_data;
- if (active)
- memcpy(chip->playback.pcm_status,
- chip->playback.def_status, 24);
- chip->playback.pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(cs8427->bus->card,
- SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO,
- &chip->playback.pcm_ctl->id);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_cs8427_iec958_active);
-
-int snd_cs8427_iec958_pcm(struct snd_i2c_device *cs8427, unsigned int rate)
-{
- struct cs8427 *chip;
- char *status;
- int err, reset;
-
- if (snd_BUG_ON(!cs8427))
- return -ENXIO;
- chip = cs8427->private_data;
- status = chip->playback.pcm_status;
- snd_i2c_lock(cs8427->bus);
- if (status[0] & IEC958_AES0_PROFESSIONAL) {
- status[0] &= ~IEC958_AES0_PRO_FS;
- switch (rate) {
- case 32000: status[0] |= IEC958_AES0_PRO_FS_32000; break;
- case 44100: status[0] |= IEC958_AES0_PRO_FS_44100; break;
- case 48000: status[0] |= IEC958_AES0_PRO_FS_48000; break;
- default: status[0] |= IEC958_AES0_PRO_FS_NOTID; break;
- }
- } else {
- status[3] &= ~IEC958_AES3_CON_FS;
- switch (rate) {
- case 32000: status[3] |= IEC958_AES3_CON_FS_32000; break;
- case 44100: status[3] |= IEC958_AES3_CON_FS_44100; break;
- case 48000: status[3] |= IEC958_AES3_CON_FS_48000; break;
- }
- }
- err = snd_cs8427_send_corudata(cs8427, 0, status, 24);
- if (err > 0)
- snd_ctl_notify(cs8427->bus->card,
- SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->playback.pcm_ctl->id);
- reset = chip->rate != rate;
- chip->rate = rate;
- snd_i2c_unlock(cs8427->bus);
- if (reset)
- snd_cs8427_reset(cs8427);
- return err < 0 ? err : 0;
-}
-
-EXPORT_SYMBOL(snd_cs8427_iec958_pcm);
-
-static int __init alsa_cs8427_module_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_cs8427_module_exit(void)
-{
-}
-
-module_init(alsa_cs8427_module_init)
-module_exit(alsa_cs8427_module_exit)
diff --git a/ANDROID_3.4.5/sound/i2c/i2c.c b/ANDROID_3.4.5/sound/i2c/i2c.c
deleted file mode 100644
index 4677037f..00000000
--- a/ANDROID_3.4.5/sound/i2c/i2c.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Generic i2c interface for ALSA
- *
- * (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
- * Modified for the ALSA driver by Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <sound/core.h>
-#include <sound/i2c.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Generic i2c interface for ALSA");
-MODULE_LICENSE("GPL");
-
-static int snd_i2c_bit_sendbytes(struct snd_i2c_device *device,
- unsigned char *bytes, int count);
-static int snd_i2c_bit_readbytes(struct snd_i2c_device *device,
- unsigned char *bytes, int count);
-static int snd_i2c_bit_probeaddr(struct snd_i2c_bus *bus,
- unsigned short addr);
-
-static struct snd_i2c_ops snd_i2c_bit_ops = {
- .sendbytes = snd_i2c_bit_sendbytes,
- .readbytes = snd_i2c_bit_readbytes,
- .probeaddr = snd_i2c_bit_probeaddr,
-};
-
-static int snd_i2c_bus_free(struct snd_i2c_bus *bus)
-{
- struct snd_i2c_bus *slave;
- struct snd_i2c_device *device;
-
- if (snd_BUG_ON(!bus))
- return -EINVAL;
- while (!list_empty(&bus->devices)) {
- device = snd_i2c_device(bus->devices.next);
- snd_i2c_device_free(device);
- }
- if (bus->master)
- list_del(&bus->buses);
- else {
- while (!list_empty(&bus->buses)) {
- slave = snd_i2c_slave_bus(bus->buses.next);
- snd_device_free(bus->card, slave);
- }
- }
- if (bus->private_free)
- bus->private_free(bus);
- kfree(bus);
- return 0;
-}
-
-static int snd_i2c_bus_dev_free(struct snd_device *device)
-{
- struct snd_i2c_bus *bus = device->device_data;
- return snd_i2c_bus_free(bus);
-}
-
-int snd_i2c_bus_create(struct snd_card *card, const char *name,
- struct snd_i2c_bus *master, struct snd_i2c_bus **ri2c)
-{
- struct snd_i2c_bus *bus;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_i2c_bus_dev_free,
- };
-
- *ri2c = NULL;
- bus = kzalloc(sizeof(*bus), GFP_KERNEL);
- if (bus == NULL)
- return -ENOMEM;
- mutex_init(&bus->lock_mutex);
- INIT_LIST_HEAD(&bus->devices);
- INIT_LIST_HEAD(&bus->buses);
- bus->card = card;
- bus->ops = &snd_i2c_bit_ops;
- if (master) {
- list_add_tail(&bus->buses, &master->buses);
- bus->master = master;
- }
- strlcpy(bus->name, name, sizeof(bus->name));
- err = snd_device_new(card, SNDRV_DEV_BUS, bus, &ops);
- if (err < 0) {
- snd_i2c_bus_free(bus);
- return err;
- }
- *ri2c = bus;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_i2c_bus_create);
-
-int snd_i2c_device_create(struct snd_i2c_bus *bus, const char *name,
- unsigned char addr, struct snd_i2c_device **rdevice)
-{
- struct snd_i2c_device *device;
-
- *rdevice = NULL;
- if (snd_BUG_ON(!bus))
- return -EINVAL;
- device = kzalloc(sizeof(*device), GFP_KERNEL);
- if (device == NULL)
- return -ENOMEM;
- device->addr = addr;
- strlcpy(device->name, name, sizeof(device->name));
- list_add_tail(&device->list, &bus->devices);
- device->bus = bus;
- *rdevice = device;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_i2c_device_create);
-
-int snd_i2c_device_free(struct snd_i2c_device *device)
-{
- if (device->bus)
- list_del(&device->list);
- if (device->private_free)
- device->private_free(device);
- kfree(device);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_i2c_device_free);
-
-int snd_i2c_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count)
-{
- return device->bus->ops->sendbytes(device, bytes, count);
-}
-
-EXPORT_SYMBOL(snd_i2c_sendbytes);
-
-int snd_i2c_readbytes(struct snd_i2c_device *device, unsigned char *bytes, int count)
-{
- return device->bus->ops->readbytes(device, bytes, count);
-}
-
-EXPORT_SYMBOL(snd_i2c_readbytes);
-
-int snd_i2c_probeaddr(struct snd_i2c_bus *bus, unsigned short addr)
-{
- return bus->ops->probeaddr(bus, addr);
-}
-
-EXPORT_SYMBOL(snd_i2c_probeaddr);
-
-/*
- * bit-operations
- */
-
-static inline void snd_i2c_bit_hw_start(struct snd_i2c_bus *bus)
-{
- if (bus->hw_ops.bit->start)
- bus->hw_ops.bit->start(bus);
-}
-
-static inline void snd_i2c_bit_hw_stop(struct snd_i2c_bus *bus)
-{
- if (bus->hw_ops.bit->stop)
- bus->hw_ops.bit->stop(bus);
-}
-
-static void snd_i2c_bit_direction(struct snd_i2c_bus *bus, int clock, int data)
-{
- if (bus->hw_ops.bit->direction)
- bus->hw_ops.bit->direction(bus, clock, data);
-}
-
-static void snd_i2c_bit_set(struct snd_i2c_bus *bus, int clock, int data)
-{
- bus->hw_ops.bit->setlines(bus, clock, data);
-}
-
-#if 0
-static int snd_i2c_bit_clock(struct snd_i2c_bus *bus)
-{
- if (bus->hw_ops.bit->getclock)
- return bus->hw_ops.bit->getclock(bus);
- return -ENXIO;
-}
-#endif
-
-static int snd_i2c_bit_data(struct snd_i2c_bus *bus, int ack)
-{
- return bus->hw_ops.bit->getdata(bus, ack);
-}
-
-static void snd_i2c_bit_start(struct snd_i2c_bus *bus)
-{
- snd_i2c_bit_hw_start(bus);
- snd_i2c_bit_direction(bus, 1, 1); /* SCL - wr, SDA - wr */
- snd_i2c_bit_set(bus, 1, 1);
- snd_i2c_bit_set(bus, 1, 0);
- snd_i2c_bit_set(bus, 0, 0);
-}
-
-static void snd_i2c_bit_stop(struct snd_i2c_bus *bus)
-{
- snd_i2c_bit_set(bus, 0, 0);
- snd_i2c_bit_set(bus, 1, 0);
- snd_i2c_bit_set(bus, 1, 1);
- snd_i2c_bit_hw_stop(bus);
-}
-
-static void snd_i2c_bit_send(struct snd_i2c_bus *bus, int data)
-{
- snd_i2c_bit_set(bus, 0, data);
- snd_i2c_bit_set(bus, 1, data);
- snd_i2c_bit_set(bus, 0, data);
-}
-
-static int snd_i2c_bit_ack(struct snd_i2c_bus *bus)
-{
- int ack;
-
- snd_i2c_bit_set(bus, 0, 1);
- snd_i2c_bit_set(bus, 1, 1);
- snd_i2c_bit_direction(bus, 1, 0); /* SCL - wr, SDA - rd */
- ack = snd_i2c_bit_data(bus, 1);
- snd_i2c_bit_direction(bus, 1, 1); /* SCL - wr, SDA - wr */
- snd_i2c_bit_set(bus, 0, 1);
- return ack ? -EIO : 0;
-}
-
-static int snd_i2c_bit_sendbyte(struct snd_i2c_bus *bus, unsigned char data)
-{
- int i, err;
-
- for (i = 7; i >= 0; i--)
- snd_i2c_bit_send(bus, !!(data & (1 << i)));
- err = snd_i2c_bit_ack(bus);
- if (err < 0)
- return err;
- return 0;
-}
-
-static int snd_i2c_bit_readbyte(struct snd_i2c_bus *bus, int last)
-{
- int i;
- unsigned char data = 0;
-
- snd_i2c_bit_set(bus, 0, 1);
- snd_i2c_bit_direction(bus, 1, 0); /* SCL - wr, SDA - rd */
- for (i = 7; i >= 0; i--) {
- snd_i2c_bit_set(bus, 1, 1);
- if (snd_i2c_bit_data(bus, 0))
- data |= (1 << i);
- snd_i2c_bit_set(bus, 0, 1);
- }
- snd_i2c_bit_direction(bus, 1, 1); /* SCL - wr, SDA - wr */
- snd_i2c_bit_send(bus, !!last);
- return data;
-}
-
-static int snd_i2c_bit_sendbytes(struct snd_i2c_device *device,
- unsigned char *bytes, int count)
-{
- struct snd_i2c_bus *bus = device->bus;
- int err, res = 0;
-
- if (device->flags & SND_I2C_DEVICE_ADDRTEN)
- return -EIO; /* not yet implemented */
- snd_i2c_bit_start(bus);
- err = snd_i2c_bit_sendbyte(bus, device->addr << 1);
- if (err < 0) {
- snd_i2c_bit_hw_stop(bus);
- return err;
- }
- while (count-- > 0) {
- err = snd_i2c_bit_sendbyte(bus, *bytes++);
- if (err < 0) {
- snd_i2c_bit_hw_stop(bus);
- return err;
- }
- res++;
- }
- snd_i2c_bit_stop(bus);
- return res;
-}
-
-static int snd_i2c_bit_readbytes(struct snd_i2c_device *device,
- unsigned char *bytes, int count)
-{
- struct snd_i2c_bus *bus = device->bus;
- int err, res = 0;
-
- if (device->flags & SND_I2C_DEVICE_ADDRTEN)
- return -EIO; /* not yet implemented */
- snd_i2c_bit_start(bus);
- err = snd_i2c_bit_sendbyte(bus, (device->addr << 1) | 1);
- if (err < 0) {
- snd_i2c_bit_hw_stop(bus);
- return err;
- }
- while (count-- > 0) {
- err = snd_i2c_bit_readbyte(bus, count == 0);
- if (err < 0) {
- snd_i2c_bit_hw_stop(bus);
- return err;
- }
- *bytes++ = (unsigned char)err;
- res++;
- }
- snd_i2c_bit_stop(bus);
- return res;
-}
-
-static int snd_i2c_bit_probeaddr(struct snd_i2c_bus *bus, unsigned short addr)
-{
- int err;
-
- if (addr & 0x8000) /* 10-bit address */
- return -EIO; /* not yet implemented */
- if (addr & 0x7f80) /* invalid address */
- return -EINVAL;
- snd_i2c_bit_start(bus);
- err = snd_i2c_bit_sendbyte(bus, addr << 1);
- snd_i2c_bit_stop(bus);
- return err;
-}
-
-
-static int __init alsa_i2c_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_i2c_exit(void)
-{
-}
-
-module_init(alsa_i2c_init)
-module_exit(alsa_i2c_exit)
diff --git a/ANDROID_3.4.5/sound/i2c/other/Makefile b/ANDROID_3.4.5/sound/i2c/other/Makefile
deleted file mode 100644
index c95d8f1a..00000000
--- a/ANDROID_3.4.5/sound/i2c/other/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-ak4114-objs := ak4114.o
-snd-ak4117-objs := ak4117.o
-snd-ak4113-objs := ak4113.o
-snd-ak4xxx-adda-objs := ak4xxx-adda.o
-snd-pt2258-objs := pt2258.o
-snd-tea575x-tuner-objs := tea575x-tuner.o
-
-# Module Dependency
-obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o
-obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o
-obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4113.o snd-ak4xxx-adda.o snd-pt2258.o
-obj-$(CONFIG_SND_TEA575X) += snd-tea575x-tuner.o
diff --git a/ANDROID_3.4.5/sound/i2c/other/ak4113.c b/ANDROID_3.4.5/sound/i2c/other/ak4113.c
deleted file mode 100644
index dde5c9c9..00000000
--- a/ANDROID_3.4.5/sound/i2c/other/ak4113.c
+++ /dev/null
@@ -1,639 +0,0 @@
-/*
- * Routines for control of the AK4113 via I2C/4-wire serial interface
- * IEC958 (S/PDIF) receiver by Asahi Kasei
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Copyright (c) by Pavel Hofman <pavel.hofman@ivitera.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/ak4113.h>
-#include <sound/asoundef.h>
-#include <sound/info.h>
-
-MODULE_AUTHOR("Pavel Hofman <pavel.hofman@ivitera.com>");
-MODULE_DESCRIPTION("AK4113 IEC958 (S/PDIF) receiver by Asahi Kasei");
-MODULE_LICENSE("GPL");
-
-#define AK4113_ADDR 0x00 /* fixed address */
-
-static void ak4113_stats(struct work_struct *work);
-static void ak4113_init_regs(struct ak4113 *chip);
-
-
-static void reg_write(struct ak4113 *ak4113, unsigned char reg,
- unsigned char val)
-{
- ak4113->write(ak4113->private_data, reg, val);
- if (reg < sizeof(ak4113->regmap))
- ak4113->regmap[reg] = val;
-}
-
-static inline unsigned char reg_read(struct ak4113 *ak4113, unsigned char reg)
-{
- return ak4113->read(ak4113->private_data, reg);
-}
-
-static void snd_ak4113_free(struct ak4113 *chip)
-{
- chip->init = 1; /* don't schedule new work */
- mb();
- cancel_delayed_work_sync(&chip->work);
- kfree(chip);
-}
-
-static int snd_ak4113_dev_free(struct snd_device *device)
-{
- struct ak4113 *chip = device->device_data;
- snd_ak4113_free(chip);
- return 0;
-}
-
-int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
- ak4113_write_t *write, const unsigned char *pgm,
- void *private_data, struct ak4113 **r_ak4113)
-{
- struct ak4113 *chip;
- int err = 0;
- unsigned char reg;
- static struct snd_device_ops ops = {
- .dev_free = snd_ak4113_dev_free,
- };
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL)
- return -ENOMEM;
- spin_lock_init(&chip->lock);
- chip->card = card;
- chip->read = read;
- chip->write = write;
- chip->private_data = private_data;
- INIT_DELAYED_WORK(&chip->work, ak4113_stats);
-
- for (reg = 0; reg < AK4113_WRITABLE_REGS ; reg++)
- chip->regmap[reg] = pgm[reg];
- ak4113_init_regs(chip);
-
- chip->rcs0 = reg_read(chip, AK4113_REG_RCS0) & ~(AK4113_QINT |
- AK4113_CINT | AK4113_STC);
- chip->rcs1 = reg_read(chip, AK4113_REG_RCS1);
- chip->rcs2 = reg_read(chip, AK4113_REG_RCS2);
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
- if (err < 0)
- goto __fail;
-
- if (r_ak4113)
- *r_ak4113 = chip;
- return 0;
-
-__fail:
- snd_ak4113_free(chip);
- return err < 0 ? err : -EIO;
-}
-EXPORT_SYMBOL_GPL(snd_ak4113_create);
-
-void snd_ak4113_reg_write(struct ak4113 *chip, unsigned char reg,
- unsigned char mask, unsigned char val)
-{
- if (reg >= AK4113_WRITABLE_REGS)
- return;
- reg_write(chip, reg, (chip->regmap[reg] & ~mask) | val);
-}
-EXPORT_SYMBOL_GPL(snd_ak4113_reg_write);
-
-static void ak4113_init_regs(struct ak4113 *chip)
-{
- unsigned char old = chip->regmap[AK4113_REG_PWRDN], reg;
-
- /* bring the chip to reset state and powerdown state */
- reg_write(chip, AK4113_REG_PWRDN, old & ~(AK4113_RST|AK4113_PWN));
- udelay(200);
- /* release reset, but leave powerdown */
- reg_write(chip, AK4113_REG_PWRDN, (old | AK4113_RST) & ~AK4113_PWN);
- udelay(200);
- for (reg = 1; reg < AK4113_WRITABLE_REGS; reg++)
- reg_write(chip, reg, chip->regmap[reg]);
- /* release powerdown, everything is initialized now */
- reg_write(chip, AK4113_REG_PWRDN, old | AK4113_RST | AK4113_PWN);
-}
-
-void snd_ak4113_reinit(struct ak4113 *chip)
-{
- chip->init = 1;
- mb();
- flush_delayed_work_sync(&chip->work);
- ak4113_init_regs(chip);
- /* bring up statistics / event queing */
- chip->init = 0;
- if (chip->kctls[0])
- schedule_delayed_work(&chip->work, HZ / 10);
-}
-EXPORT_SYMBOL_GPL(snd_ak4113_reinit);
-
-static unsigned int external_rate(unsigned char rcs1)
-{
- switch (rcs1 & (AK4113_FS0|AK4113_FS1|AK4113_FS2|AK4113_FS3)) {
- case AK4113_FS_8000HZ:
- return 8000;
- case AK4113_FS_11025HZ:
- return 11025;
- case AK4113_FS_16000HZ:
- return 16000;
- case AK4113_FS_22050HZ:
- return 22050;
- case AK4113_FS_24000HZ:
- return 24000;
- case AK4113_FS_32000HZ:
- return 32000;
- case AK4113_FS_44100HZ:
- return 44100;
- case AK4113_FS_48000HZ:
- return 48000;
- case AK4113_FS_64000HZ:
- return 64000;
- case AK4113_FS_88200HZ:
- return 88200;
- case AK4113_FS_96000HZ:
- return 96000;
- case AK4113_FS_176400HZ:
- return 176400;
- case AK4113_FS_192000HZ:
- return 192000;
- default:
- return 0;
- }
-}
-
-static int snd_ak4113_in_error_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = LONG_MAX;
- return 0;
-}
-
-static int snd_ak4113_in_error_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4113 *chip = snd_kcontrol_chip(kcontrol);
- long *ptr;
-
- spin_lock_irq(&chip->lock);
- ptr = (long *)(((char *)chip) + kcontrol->private_value);
- ucontrol->value.integer.value[0] = *ptr;
- *ptr = 0;
- spin_unlock_irq(&chip->lock);
- return 0;
-}
-
-#define snd_ak4113_in_bit_info snd_ctl_boolean_mono_info
-
-static int snd_ak4113_in_bit_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4113 *chip = snd_kcontrol_chip(kcontrol);
- unsigned char reg = kcontrol->private_value & 0xff;
- unsigned char bit = (kcontrol->private_value >> 8) & 0xff;
- unsigned char inv = (kcontrol->private_value >> 31) & 1;
-
- ucontrol->value.integer.value[0] =
- ((reg_read(chip, reg) & (1 << bit)) ? 1 : 0) ^ inv;
- return 0;
-}
-
-static int snd_ak4113_rx_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 5;
- return 0;
-}
-
-static int snd_ak4113_rx_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4113 *chip = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] =
- (AK4113_IPS(chip->regmap[AK4113_REG_IO1]));
- return 0;
-}
-
-static int snd_ak4113_rx_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4113 *chip = snd_kcontrol_chip(kcontrol);
- int change;
- u8 old_val;
-
- spin_lock_irq(&chip->lock);
- old_val = chip->regmap[AK4113_REG_IO1];
- change = ucontrol->value.integer.value[0] != AK4113_IPS(old_val);
- if (change)
- reg_write(chip, AK4113_REG_IO1,
- (old_val & (~AK4113_IPS(0xff))) |
- (AK4113_IPS(ucontrol->value.integer.value[0])));
- spin_unlock_irq(&chip->lock);
- return change;
-}
-
-static int snd_ak4113_rate_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 192000;
- return 0;
-}
-
-static int snd_ak4113_rate_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4113 *chip = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = external_rate(reg_read(chip,
- AK4113_REG_RCS1));
- return 0;
-}
-
-static int snd_ak4113_spdif_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_ak4113_spdif_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4113 *chip = snd_kcontrol_chip(kcontrol);
- unsigned i;
-
- for (i = 0; i < AK4113_REG_RXCSB_SIZE; i++)
- ucontrol->value.iec958.status[i] = reg_read(chip,
- AK4113_REG_RXCSB0 + i);
- return 0;
-}
-
-static int snd_ak4113_spdif_mask_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_ak4113_spdif_mask_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- memset(ucontrol->value.iec958.status, 0xff, AK4113_REG_RXCSB_SIZE);
- return 0;
-}
-
-static int snd_ak4113_spdif_pinfo(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 0xffff;
- uinfo->count = 4;
- return 0;
-}
-
-static int snd_ak4113_spdif_pget(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4113 *chip = snd_kcontrol_chip(kcontrol);
- unsigned short tmp;
-
- ucontrol->value.integer.value[0] = 0xf8f2;
- ucontrol->value.integer.value[1] = 0x4e1f;
- tmp = reg_read(chip, AK4113_REG_Pc0) |
- (reg_read(chip, AK4113_REG_Pc1) << 8);
- ucontrol->value.integer.value[2] = tmp;
- tmp = reg_read(chip, AK4113_REG_Pd0) |
- (reg_read(chip, AK4113_REG_Pd1) << 8);
- ucontrol->value.integer.value[3] = tmp;
- return 0;
-}
-
-static int snd_ak4113_spdif_qinfo(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
- uinfo->count = AK4113_REG_QSUB_SIZE;
- return 0;
-}
-
-static int snd_ak4113_spdif_qget(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4113 *chip = snd_kcontrol_chip(kcontrol);
- unsigned i;
-
- for (i = 0; i < AK4113_REG_QSUB_SIZE; i++)
- ucontrol->value.bytes.data[i] = reg_read(chip,
- AK4113_REG_QSUB_ADDR + i);
- return 0;
-}
-
-/* Don't forget to change AK4113_CONTROLS define!!! */
-static struct snd_kcontrol_new snd_ak4113_iec958_controls[] = {
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 Parity Errors",
- .access = SNDRV_CTL_ELEM_ACCESS_READ |
- SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4113_in_error_info,
- .get = snd_ak4113_in_error_get,
- .private_value = offsetof(struct ak4113, parity_errors),
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 V-Bit Errors",
- .access = SNDRV_CTL_ELEM_ACCESS_READ |
- SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4113_in_error_info,
- .get = snd_ak4113_in_error_get,
- .private_value = offsetof(struct ak4113, v_bit_errors),
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 C-CRC Errors",
- .access = SNDRV_CTL_ELEM_ACCESS_READ |
- SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4113_in_error_info,
- .get = snd_ak4113_in_error_get,
- .private_value = offsetof(struct ak4113, ccrc_errors),
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 Q-CRC Errors",
- .access = SNDRV_CTL_ELEM_ACCESS_READ |
- SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4113_in_error_info,
- .get = snd_ak4113_in_error_get,
- .private_value = offsetof(struct ak4113, qcrc_errors),
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 External Rate",
- .access = SNDRV_CTL_ELEM_ACCESS_READ |
- SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4113_rate_info,
- .get = snd_ak4113_rate_get,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .info = snd_ak4113_spdif_mask_info,
- .get = snd_ak4113_spdif_mask_get,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
- .access = SNDRV_CTL_ELEM_ACCESS_READ |
- SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4113_spdif_info,
- .get = snd_ak4113_spdif_get,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 Preample Capture Default",
- .access = SNDRV_CTL_ELEM_ACCESS_READ |
- SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4113_spdif_pinfo,
- .get = snd_ak4113_spdif_pget,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 Q-subcode Capture Default",
- .access = SNDRV_CTL_ELEM_ACCESS_READ |
- SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4113_spdif_qinfo,
- .get = snd_ak4113_spdif_qget,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 Audio",
- .access = SNDRV_CTL_ELEM_ACCESS_READ |
- SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4113_in_bit_info,
- .get = snd_ak4113_in_bit_get,
- .private_value = (1<<31) | (1<<8) | AK4113_REG_RCS0,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 Non-PCM Bitstream",
- .access = SNDRV_CTL_ELEM_ACCESS_READ |
- SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4113_in_bit_info,
- .get = snd_ak4113_in_bit_get,
- .private_value = (0<<8) | AK4113_REG_RCS1,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 DTS Bitstream",
- .access = SNDRV_CTL_ELEM_ACCESS_READ |
- SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4113_in_bit_info,
- .get = snd_ak4113_in_bit_get,
- .private_value = (1<<8) | AK4113_REG_RCS1,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "AK4113 Input Select",
- .access = SNDRV_CTL_ELEM_ACCESS_READ |
- SNDRV_CTL_ELEM_ACCESS_WRITE,
- .info = snd_ak4113_rx_info,
- .get = snd_ak4113_rx_get,
- .put = snd_ak4113_rx_put,
-}
-};
-
-static void snd_ak4113_proc_regs_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct ak4113 *ak4113 = entry->private_data;
- int reg, val;
- /* all ak4113 registers 0x00 - 0x1c */
- for (reg = 0; reg < 0x1d; reg++) {
- val = reg_read(ak4113, reg);
- snd_iprintf(buffer, "0x%02x = 0x%02x\n", reg, val);
- }
-}
-
-static void snd_ak4113_proc_init(struct ak4113 *ak4113)
-{
- struct snd_info_entry *entry;
- if (!snd_card_proc_new(ak4113->card, "ak4113", &entry))
- snd_info_set_text_ops(entry, ak4113, snd_ak4113_proc_regs_read);
-}
-
-int snd_ak4113_build(struct ak4113 *ak4113,
- struct snd_pcm_substream *cap_substream)
-{
- struct snd_kcontrol *kctl;
- unsigned int idx;
- int err;
-
- if (snd_BUG_ON(!cap_substream))
- return -EINVAL;
- ak4113->substream = cap_substream;
- for (idx = 0; idx < AK4113_CONTROLS; idx++) {
- kctl = snd_ctl_new1(&snd_ak4113_iec958_controls[idx], ak4113);
- if (kctl == NULL)
- return -ENOMEM;
- kctl->id.device = cap_substream->pcm->device;
- kctl->id.subdevice = cap_substream->number;
- err = snd_ctl_add(ak4113->card, kctl);
- if (err < 0)
- return err;
- ak4113->kctls[idx] = kctl;
- }
- snd_ak4113_proc_init(ak4113);
- /* trigger workq */
- schedule_delayed_work(&ak4113->work, HZ / 10);
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_ak4113_build);
-
-int snd_ak4113_external_rate(struct ak4113 *ak4113)
-{
- unsigned char rcs1;
-
- rcs1 = reg_read(ak4113, AK4113_REG_RCS1);
- return external_rate(rcs1);
-}
-EXPORT_SYMBOL_GPL(snd_ak4113_external_rate);
-
-int snd_ak4113_check_rate_and_errors(struct ak4113 *ak4113, unsigned int flags)
-{
- struct snd_pcm_runtime *runtime =
- ak4113->substream ? ak4113->substream->runtime : NULL;
- unsigned long _flags;
- int res = 0;
- unsigned char rcs0, rcs1, rcs2;
- unsigned char c0, c1;
-
- rcs1 = reg_read(ak4113, AK4113_REG_RCS1);
- if (flags & AK4113_CHECK_NO_STAT)
- goto __rate;
- rcs0 = reg_read(ak4113, AK4113_REG_RCS0);
- rcs2 = reg_read(ak4113, AK4113_REG_RCS2);
- spin_lock_irqsave(&ak4113->lock, _flags);
- if (rcs0 & AK4113_PAR)
- ak4113->parity_errors++;
- if (rcs0 & AK4113_V)
- ak4113->v_bit_errors++;
- if (rcs2 & AK4113_CCRC)
- ak4113->ccrc_errors++;
- if (rcs2 & AK4113_QCRC)
- ak4113->qcrc_errors++;
- c0 = (ak4113->rcs0 & (AK4113_QINT | AK4113_CINT | AK4113_STC |
- AK4113_AUDION | AK4113_AUTO | AK4113_UNLCK)) ^
- (rcs0 & (AK4113_QINT | AK4113_CINT | AK4113_STC |
- AK4113_AUDION | AK4113_AUTO | AK4113_UNLCK));
- c1 = (ak4113->rcs1 & (AK4113_DTSCD | AK4113_NPCM | AK4113_PEM |
- AK4113_DAT | 0xf0)) ^
- (rcs1 & (AK4113_DTSCD | AK4113_NPCM | AK4113_PEM |
- AK4113_DAT | 0xf0));
- ak4113->rcs0 = rcs0 & ~(AK4113_QINT | AK4113_CINT | AK4113_STC);
- ak4113->rcs1 = rcs1;
- ak4113->rcs2 = rcs2;
- spin_unlock_irqrestore(&ak4113->lock, _flags);
-
- if (rcs0 & AK4113_PAR)
- snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4113->kctls[0]->id);
- if (rcs0 & AK4113_V)
- snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4113->kctls[1]->id);
- if (rcs2 & AK4113_CCRC)
- snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4113->kctls[2]->id);
- if (rcs2 & AK4113_QCRC)
- snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4113->kctls[3]->id);
-
- /* rate change */
- if (c1 & 0xf0)
- snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4113->kctls[4]->id);
-
- if ((c1 & AK4113_PEM) | (c0 & AK4113_CINT))
- snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4113->kctls[6]->id);
- if (c0 & AK4113_QINT)
- snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4113->kctls[8]->id);
-
- if (c0 & AK4113_AUDION)
- snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4113->kctls[9]->id);
- if (c1 & AK4113_NPCM)
- snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4113->kctls[10]->id);
- if (c1 & AK4113_DTSCD)
- snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4113->kctls[11]->id);
-
- if (ak4113->change_callback && (c0 | c1) != 0)
- ak4113->change_callback(ak4113, c0, c1);
-
-__rate:
- /* compare rate */
- res = external_rate(rcs1);
- if (!(flags & AK4113_CHECK_NO_RATE) && runtime &&
- (runtime->rate != res)) {
- snd_pcm_stream_lock_irqsave(ak4113->substream, _flags);
- if (snd_pcm_running(ak4113->substream)) {
- /*printk(KERN_DEBUG "rate changed (%i <- %i)\n",
- * runtime->rate, res); */
- snd_pcm_stop(ak4113->substream,
- SNDRV_PCM_STATE_DRAINING);
- wake_up(&runtime->sleep);
- res = 1;
- }
- snd_pcm_stream_unlock_irqrestore(ak4113->substream, _flags);
- }
- return res;
-}
-EXPORT_SYMBOL_GPL(snd_ak4113_check_rate_and_errors);
-
-static void ak4113_stats(struct work_struct *work)
-{
- struct ak4113 *chip = container_of(work, struct ak4113, work.work);
-
- if (!chip->init)
- snd_ak4113_check_rate_and_errors(chip, chip->check_flags);
-
- schedule_delayed_work(&chip->work, HZ / 10);
-}
diff --git a/ANDROID_3.4.5/sound/i2c/other/ak4114.c b/ANDROID_3.4.5/sound/i2c/other/ak4114.c
deleted file mode 100644
index fdf3c1b6..00000000
--- a/ANDROID_3.4.5/sound/i2c/other/ak4114.c
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- * Routines for control of the AK4114 via I2C and 4-wire serial interface
- * IEC958 (S/PDIF) receiver by Asahi Kasei
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/ak4114.h>
-#include <sound/asoundef.h>
-#include <sound/info.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("AK4114 IEC958 (S/PDIF) receiver by Asahi Kasei");
-MODULE_LICENSE("GPL");
-
-#define AK4114_ADDR 0x00 /* fixed address */
-
-static void ak4114_stats(struct work_struct *work);
-static void ak4114_init_regs(struct ak4114 *chip);
-
-static void reg_write(struct ak4114 *ak4114, unsigned char reg, unsigned char val)
-{
- ak4114->write(ak4114->private_data, reg, val);
- if (reg <= AK4114_REG_INT1_MASK)
- ak4114->regmap[reg] = val;
- else if (reg >= AK4114_REG_TXCSB0 && reg <= AK4114_REG_TXCSB4)
- ak4114->txcsb[reg-AK4114_REG_TXCSB0] = val;
-}
-
-static inline unsigned char reg_read(struct ak4114 *ak4114, unsigned char reg)
-{
- return ak4114->read(ak4114->private_data, reg);
-}
-
-#if 0
-static void reg_dump(struct ak4114 *ak4114)
-{
- int i;
-
- printk(KERN_DEBUG "AK4114 REG DUMP:\n");
- for (i = 0; i < 0x20; i++)
- printk(KERN_DEBUG "reg[%02x] = %02x (%02x)\n", i, reg_read(ak4114, i), i < sizeof(ak4114->regmap) ? ak4114->regmap[i] : 0);
-}
-#endif
-
-static void snd_ak4114_free(struct ak4114 *chip)
-{
- chip->init = 1; /* don't schedule new work */
- mb();
- cancel_delayed_work_sync(&chip->work);
- kfree(chip);
-}
-
-static int snd_ak4114_dev_free(struct snd_device *device)
-{
- struct ak4114 *chip = device->device_data;
- snd_ak4114_free(chip);
- return 0;
-}
-
-int snd_ak4114_create(struct snd_card *card,
- ak4114_read_t *read, ak4114_write_t *write,
- const unsigned char pgm[7], const unsigned char txcsb[5],
- void *private_data, struct ak4114 **r_ak4114)
-{
- struct ak4114 *chip;
- int err = 0;
- unsigned char reg;
- static struct snd_device_ops ops = {
- .dev_free = snd_ak4114_dev_free,
- };
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL)
- return -ENOMEM;
- spin_lock_init(&chip->lock);
- chip->card = card;
- chip->read = read;
- chip->write = write;
- chip->private_data = private_data;
- INIT_DELAYED_WORK(&chip->work, ak4114_stats);
-
- for (reg = 0; reg < 7; reg++)
- chip->regmap[reg] = pgm[reg];
- for (reg = 0; reg < 5; reg++)
- chip->txcsb[reg] = txcsb[reg];
-
- ak4114_init_regs(chip);
-
- chip->rcs0 = reg_read(chip, AK4114_REG_RCS0) & ~(AK4114_QINT | AK4114_CINT);
- chip->rcs1 = reg_read(chip, AK4114_REG_RCS1);
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0)
- goto __fail;
-
- if (r_ak4114)
- *r_ak4114 = chip;
- return 0;
-
- __fail:
- snd_ak4114_free(chip);
- return err < 0 ? err : -EIO;
-}
-
-void snd_ak4114_reg_write(struct ak4114 *chip, unsigned char reg, unsigned char mask, unsigned char val)
-{
- if (reg <= AK4114_REG_INT1_MASK)
- reg_write(chip, reg, (chip->regmap[reg] & ~mask) | val);
- else if (reg >= AK4114_REG_TXCSB0 && reg <= AK4114_REG_TXCSB4)
- reg_write(chip, reg,
- (chip->txcsb[reg-AK4114_REG_TXCSB0] & ~mask) | val);
-}
-
-static void ak4114_init_regs(struct ak4114 *chip)
-{
- unsigned char old = chip->regmap[AK4114_REG_PWRDN], reg;
-
- /* bring the chip to reset state and powerdown state */
- reg_write(chip, AK4114_REG_PWRDN, old & ~(AK4114_RST|AK4114_PWN));
- udelay(200);
- /* release reset, but leave powerdown */
- reg_write(chip, AK4114_REG_PWRDN, (old | AK4114_RST) & ~AK4114_PWN);
- udelay(200);
- for (reg = 1; reg < 7; reg++)
- reg_write(chip, reg, chip->regmap[reg]);
- for (reg = 0; reg < 5; reg++)
- reg_write(chip, reg + AK4114_REG_TXCSB0, chip->txcsb[reg]);
- /* release powerdown, everything is initialized now */
- reg_write(chip, AK4114_REG_PWRDN, old | AK4114_RST | AK4114_PWN);
-}
-
-void snd_ak4114_reinit(struct ak4114 *chip)
-{
- chip->init = 1;
- mb();
- flush_delayed_work_sync(&chip->work);
- ak4114_init_regs(chip);
- /* bring up statistics / event queing */
- chip->init = 0;
- if (chip->kctls[0])
- schedule_delayed_work(&chip->work, HZ / 10);
-}
-
-static unsigned int external_rate(unsigned char rcs1)
-{
- switch (rcs1 & (AK4114_FS0|AK4114_FS1|AK4114_FS2|AK4114_FS3)) {
- case AK4114_FS_32000HZ: return 32000;
- case AK4114_FS_44100HZ: return 44100;
- case AK4114_FS_48000HZ: return 48000;
- case AK4114_FS_88200HZ: return 88200;
- case AK4114_FS_96000HZ: return 96000;
- case AK4114_FS_176400HZ: return 176400;
- case AK4114_FS_192000HZ: return 192000;
- default: return 0;
- }
-}
-
-static int snd_ak4114_in_error_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = LONG_MAX;
- return 0;
-}
-
-static int snd_ak4114_in_error_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4114 *chip = snd_kcontrol_chip(kcontrol);
- long *ptr;
-
- spin_lock_irq(&chip->lock);
- ptr = (long *)(((char *)chip) + kcontrol->private_value);
- ucontrol->value.integer.value[0] = *ptr;
- *ptr = 0;
- spin_unlock_irq(&chip->lock);
- return 0;
-}
-
-#define snd_ak4114_in_bit_info snd_ctl_boolean_mono_info
-
-static int snd_ak4114_in_bit_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4114 *chip = snd_kcontrol_chip(kcontrol);
- unsigned char reg = kcontrol->private_value & 0xff;
- unsigned char bit = (kcontrol->private_value >> 8) & 0xff;
- unsigned char inv = (kcontrol->private_value >> 31) & 1;
-
- ucontrol->value.integer.value[0] = ((reg_read(chip, reg) & (1 << bit)) ? 1 : 0) ^ inv;
- return 0;
-}
-
-static int snd_ak4114_rate_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 192000;
- return 0;
-}
-
-static int snd_ak4114_rate_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4114 *chip = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = external_rate(reg_read(chip, AK4114_REG_RCS1));
- return 0;
-}
-
-static int snd_ak4114_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_ak4114_spdif_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4114 *chip = snd_kcontrol_chip(kcontrol);
- unsigned i;
-
- for (i = 0; i < AK4114_REG_RXCSB_SIZE; i++)
- ucontrol->value.iec958.status[i] = reg_read(chip, AK4114_REG_RXCSB0 + i);
- return 0;
-}
-
-static int snd_ak4114_spdif_playback_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4114 *chip = snd_kcontrol_chip(kcontrol);
- unsigned i;
-
- for (i = 0; i < AK4114_REG_TXCSB_SIZE; i++)
- ucontrol->value.iec958.status[i] = chip->txcsb[i];
- return 0;
-}
-
-static int snd_ak4114_spdif_playback_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4114 *chip = snd_kcontrol_chip(kcontrol);
- unsigned i;
-
- for (i = 0; i < AK4114_REG_TXCSB_SIZE; i++)
- reg_write(chip, AK4114_REG_TXCSB0 + i, ucontrol->value.iec958.status[i]);
- return 0;
-}
-
-static int snd_ak4114_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_ak4114_spdif_mask_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- memset(ucontrol->value.iec958.status, 0xff, AK4114_REG_RXCSB_SIZE);
- return 0;
-}
-
-static int snd_ak4114_spdif_pinfo(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 0xffff;
- uinfo->count = 4;
- return 0;
-}
-
-static int snd_ak4114_spdif_pget(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4114 *chip = snd_kcontrol_chip(kcontrol);
- unsigned short tmp;
-
- ucontrol->value.integer.value[0] = 0xf8f2;
- ucontrol->value.integer.value[1] = 0x4e1f;
- tmp = reg_read(chip, AK4114_REG_Pc0) | (reg_read(chip, AK4114_REG_Pc1) << 8);
- ucontrol->value.integer.value[2] = tmp;
- tmp = reg_read(chip, AK4114_REG_Pd0) | (reg_read(chip, AK4114_REG_Pd1) << 8);
- ucontrol->value.integer.value[3] = tmp;
- return 0;
-}
-
-static int snd_ak4114_spdif_qinfo(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
- uinfo->count = AK4114_REG_QSUB_SIZE;
- return 0;
-}
-
-static int snd_ak4114_spdif_qget(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4114 *chip = snd_kcontrol_chip(kcontrol);
- unsigned i;
-
- for (i = 0; i < AK4114_REG_QSUB_SIZE; i++)
- ucontrol->value.bytes.data[i] = reg_read(chip, AK4114_REG_QSUB_ADDR + i);
- return 0;
-}
-
-/* Don't forget to change AK4114_CONTROLS define!!! */
-static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = {
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 Parity Errors",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4114_in_error_info,
- .get = snd_ak4114_in_error_get,
- .private_value = offsetof(struct ak4114, parity_errors),
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 V-Bit Errors",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4114_in_error_info,
- .get = snd_ak4114_in_error_get,
- .private_value = offsetof(struct ak4114, v_bit_errors),
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 C-CRC Errors",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4114_in_error_info,
- .get = snd_ak4114_in_error_get,
- .private_value = offsetof(struct ak4114, ccrc_errors),
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 Q-CRC Errors",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4114_in_error_info,
- .get = snd_ak4114_in_error_get,
- .private_value = offsetof(struct ak4114, qcrc_errors),
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 External Rate",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4114_rate_info,
- .get = snd_ak4114_rate_get,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .info = snd_ak4114_spdif_mask_info,
- .get = snd_ak4114_spdif_mask_get,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4114_spdif_info,
- .get = snd_ak4114_spdif_playback_get,
- .put = snd_ak4114_spdif_playback_put,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .info = snd_ak4114_spdif_mask_info,
- .get = snd_ak4114_spdif_mask_get,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4114_spdif_info,
- .get = snd_ak4114_spdif_get,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 Preample Capture Default",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4114_spdif_pinfo,
- .get = snd_ak4114_spdif_pget,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 Q-subcode Capture Default",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4114_spdif_qinfo,
- .get = snd_ak4114_spdif_qget,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 Audio",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4114_in_bit_info,
- .get = snd_ak4114_in_bit_get,
- .private_value = (1<<31) | (1<<8) | AK4114_REG_RCS0,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 Non-PCM Bitstream",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4114_in_bit_info,
- .get = snd_ak4114_in_bit_get,
- .private_value = (6<<8) | AK4114_REG_RCS0,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 DTS Bitstream",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4114_in_bit_info,
- .get = snd_ak4114_in_bit_get,
- .private_value = (3<<8) | AK4114_REG_RCS0,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 PPL Lock Status",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4114_in_bit_info,
- .get = snd_ak4114_in_bit_get,
- .private_value = (1<<31) | (4<<8) | AK4114_REG_RCS0,
-}
-};
-
-
-static void snd_ak4114_proc_regs_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct ak4114 *ak4114 = entry->private_data;
- int reg, val;
- /* all ak4114 registers 0x00 - 0x1f */
- for (reg = 0; reg < 0x20; reg++) {
- val = reg_read(ak4114, reg);
- snd_iprintf(buffer, "0x%02x = 0x%02x\n", reg, val);
- }
-}
-
-static void snd_ak4114_proc_init(struct ak4114 *ak4114)
-{
- struct snd_info_entry *entry;
- if (!snd_card_proc_new(ak4114->card, "ak4114", &entry))
- snd_info_set_text_ops(entry, ak4114, snd_ak4114_proc_regs_read);
-}
-
-int snd_ak4114_build(struct ak4114 *ak4114,
- struct snd_pcm_substream *ply_substream,
- struct snd_pcm_substream *cap_substream)
-{
- struct snd_kcontrol *kctl;
- unsigned int idx;
- int err;
-
- if (snd_BUG_ON(!cap_substream))
- return -EINVAL;
- ak4114->playback_substream = ply_substream;
- ak4114->capture_substream = cap_substream;
- for (idx = 0; idx < AK4114_CONTROLS; idx++) {
- kctl = snd_ctl_new1(&snd_ak4114_iec958_controls[idx], ak4114);
- if (kctl == NULL)
- return -ENOMEM;
- if (strstr(kctl->id.name, "Playback")) {
- if (ply_substream == NULL) {
- snd_ctl_free_one(kctl);
- ak4114->kctls[idx] = NULL;
- continue;
- }
- kctl->id.device = ply_substream->pcm->device;
- kctl->id.subdevice = ply_substream->number;
- } else {
- kctl->id.device = cap_substream->pcm->device;
- kctl->id.subdevice = cap_substream->number;
- }
- err = snd_ctl_add(ak4114->card, kctl);
- if (err < 0)
- return err;
- ak4114->kctls[idx] = kctl;
- }
- snd_ak4114_proc_init(ak4114);
- /* trigger workq */
- schedule_delayed_work(&ak4114->work, HZ / 10);
- return 0;
-}
-
-/* notify kcontrols if any parameters are changed */
-static void ak4114_notify(struct ak4114 *ak4114,
- unsigned char rcs0, unsigned char rcs1,
- unsigned char c0, unsigned char c1)
-{
- if (!ak4114->kctls[0])
- return;
-
- if (rcs0 & AK4114_PAR)
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4114->kctls[0]->id);
- if (rcs0 & AK4114_V)
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4114->kctls[1]->id);
- if (rcs1 & AK4114_CCRC)
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4114->kctls[2]->id);
- if (rcs1 & AK4114_QCRC)
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4114->kctls[3]->id);
-
- /* rate change */
- if (c1 & 0xf0)
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4114->kctls[4]->id);
-
- if ((c0 & AK4114_PEM) | (c0 & AK4114_CINT))
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4114->kctls[9]->id);
- if (c0 & AK4114_QINT)
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4114->kctls[10]->id);
-
- if (c0 & AK4114_AUDION)
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4114->kctls[11]->id);
- if (c0 & AK4114_AUTO)
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4114->kctls[12]->id);
- if (c0 & AK4114_DTSCD)
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4114->kctls[13]->id);
- if (c0 & AK4114_UNLCK)
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &ak4114->kctls[14]->id);
-}
-
-int snd_ak4114_external_rate(struct ak4114 *ak4114)
-{
- unsigned char rcs1;
-
- rcs1 = reg_read(ak4114, AK4114_REG_RCS1);
- return external_rate(rcs1);
-}
-
-int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags)
-{
- struct snd_pcm_runtime *runtime = ak4114->capture_substream ? ak4114->capture_substream->runtime : NULL;
- unsigned long _flags;
- int res = 0;
- unsigned char rcs0, rcs1;
- unsigned char c0, c1;
-
- rcs1 = reg_read(ak4114, AK4114_REG_RCS1);
- if (flags & AK4114_CHECK_NO_STAT)
- goto __rate;
- rcs0 = reg_read(ak4114, AK4114_REG_RCS0);
- spin_lock_irqsave(&ak4114->lock, _flags);
- if (rcs0 & AK4114_PAR)
- ak4114->parity_errors++;
- if (rcs1 & AK4114_V)
- ak4114->v_bit_errors++;
- if (rcs1 & AK4114_CCRC)
- ak4114->ccrc_errors++;
- if (rcs1 & AK4114_QCRC)
- ak4114->qcrc_errors++;
- c0 = (ak4114->rcs0 & (AK4114_QINT | AK4114_CINT | AK4114_PEM | AK4114_AUDION | AK4114_AUTO | AK4114_UNLCK)) ^
- (rcs0 & (AK4114_QINT | AK4114_CINT | AK4114_PEM | AK4114_AUDION | AK4114_AUTO | AK4114_UNLCK));
- c1 = (ak4114->rcs1 & 0xf0) ^ (rcs1 & 0xf0);
- ak4114->rcs0 = rcs0 & ~(AK4114_QINT | AK4114_CINT);
- ak4114->rcs1 = rcs1;
- spin_unlock_irqrestore(&ak4114->lock, _flags);
-
- ak4114_notify(ak4114, rcs0, rcs1, c0, c1);
- if (ak4114->change_callback && (c0 | c1) != 0)
- ak4114->change_callback(ak4114, c0, c1);
-
- __rate:
- /* compare rate */
- res = external_rate(rcs1);
- if (!(flags & AK4114_CHECK_NO_RATE) && runtime && runtime->rate != res) {
- snd_pcm_stream_lock_irqsave(ak4114->capture_substream, _flags);
- if (snd_pcm_running(ak4114->capture_substream)) {
- // printk(KERN_DEBUG "rate changed (%i <- %i)\n", runtime->rate, res);
- snd_pcm_stop(ak4114->capture_substream, SNDRV_PCM_STATE_DRAINING);
- res = 1;
- }
- snd_pcm_stream_unlock_irqrestore(ak4114->capture_substream, _flags);
- }
- return res;
-}
-
-static void ak4114_stats(struct work_struct *work)
-{
- struct ak4114 *chip = container_of(work, struct ak4114, work.work);
-
- if (!chip->init)
- snd_ak4114_check_rate_and_errors(chip, chip->check_flags);
-
- schedule_delayed_work(&chip->work, HZ / 10);
-}
-
-EXPORT_SYMBOL(snd_ak4114_create);
-EXPORT_SYMBOL(snd_ak4114_reg_write);
-EXPORT_SYMBOL(snd_ak4114_reinit);
-EXPORT_SYMBOL(snd_ak4114_build);
-EXPORT_SYMBOL(snd_ak4114_external_rate);
-EXPORT_SYMBOL(snd_ak4114_check_rate_and_errors);
diff --git a/ANDROID_3.4.5/sound/i2c/other/ak4117.c b/ANDROID_3.4.5/sound/i2c/other/ak4117.c
deleted file mode 100644
index b4b2a51f..00000000
--- a/ANDROID_3.4.5/sound/i2c/other/ak4117.c
+++ /dev/null
@@ -1,552 +0,0 @@
-/*
- * Routines for control of the AK4117 via 4-wire serial interface
- * IEC958 (S/PDIF) receiver by Asahi Kasei
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/ak4117.h>
-#include <sound/asoundef.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("AK4117 IEC958 (S/PDIF) receiver by Asahi Kasei");
-MODULE_LICENSE("GPL");
-
-#define AK4117_ADDR 0x00 /* fixed address */
-
-static void snd_ak4117_timer(unsigned long data);
-
-static void reg_write(struct ak4117 *ak4117, unsigned char reg, unsigned char val)
-{
- ak4117->write(ak4117->private_data, reg, val);
- if (reg < sizeof(ak4117->regmap))
- ak4117->regmap[reg] = val;
-}
-
-static inline unsigned char reg_read(struct ak4117 *ak4117, unsigned char reg)
-{
- return ak4117->read(ak4117->private_data, reg);
-}
-
-#if 0
-static void reg_dump(struct ak4117 *ak4117)
-{
- int i;
-
- printk(KERN_DEBUG "AK4117 REG DUMP:\n");
- for (i = 0; i < 0x1b; i++)
- printk(KERN_DEBUG "reg[%02x] = %02x (%02x)\n", i, reg_read(ak4117, i), i < sizeof(ak4117->regmap) ? ak4117->regmap[i] : 0);
-}
-#endif
-
-static void snd_ak4117_free(struct ak4117 *chip)
-{
- del_timer(&chip->timer);
- kfree(chip);
-}
-
-static int snd_ak4117_dev_free(struct snd_device *device)
-{
- struct ak4117 *chip = device->device_data;
- snd_ak4117_free(chip);
- return 0;
-}
-
-int snd_ak4117_create(struct snd_card *card, ak4117_read_t *read, ak4117_write_t *write,
- const unsigned char pgm[5], void *private_data, struct ak4117 **r_ak4117)
-{
- struct ak4117 *chip;
- int err = 0;
- unsigned char reg;
- static struct snd_device_ops ops = {
- .dev_free = snd_ak4117_dev_free,
- };
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL)
- return -ENOMEM;
- spin_lock_init(&chip->lock);
- chip->card = card;
- chip->read = read;
- chip->write = write;
- chip->private_data = private_data;
- init_timer(&chip->timer);
- chip->timer.data = (unsigned long)chip;
- chip->timer.function = snd_ak4117_timer;
-
- for (reg = 0; reg < 5; reg++)
- chip->regmap[reg] = pgm[reg];
- snd_ak4117_reinit(chip);
-
- chip->rcs0 = reg_read(chip, AK4117_REG_RCS0) & ~(AK4117_QINT | AK4117_CINT | AK4117_STC);
- chip->rcs1 = reg_read(chip, AK4117_REG_RCS1);
- chip->rcs2 = reg_read(chip, AK4117_REG_RCS2);
-
- if ((err = snd_device_new(card, SNDRV_DEV_CODEC, chip, &ops)) < 0)
- goto __fail;
-
- if (r_ak4117)
- *r_ak4117 = chip;
- return 0;
-
- __fail:
- snd_ak4117_free(chip);
- return err < 0 ? err : -EIO;
-}
-
-void snd_ak4117_reg_write(struct ak4117 *chip, unsigned char reg, unsigned char mask, unsigned char val)
-{
- if (reg >= 5)
- return;
- reg_write(chip, reg, (chip->regmap[reg] & ~mask) | val);
-}
-
-void snd_ak4117_reinit(struct ak4117 *chip)
-{
- unsigned char old = chip->regmap[AK4117_REG_PWRDN], reg;
-
- del_timer(&chip->timer);
- chip->init = 1;
- /* bring the chip to reset state and powerdown state */
- reg_write(chip, AK4117_REG_PWRDN, 0);
- udelay(200);
- /* release reset, but leave powerdown */
- reg_write(chip, AK4117_REG_PWRDN, (old | AK4117_RST) & ~AK4117_PWN);
- udelay(200);
- for (reg = 1; reg < 5; reg++)
- reg_write(chip, reg, chip->regmap[reg]);
- /* release powerdown, everything is initialized now */
- reg_write(chip, AK4117_REG_PWRDN, old | AK4117_RST | AK4117_PWN);
- chip->init = 0;
- chip->timer.expires = 1 + jiffies;
- add_timer(&chip->timer);
-}
-
-static unsigned int external_rate(unsigned char rcs1)
-{
- switch (rcs1 & (AK4117_FS0|AK4117_FS1|AK4117_FS2|AK4117_FS3)) {
- case AK4117_FS_32000HZ: return 32000;
- case AK4117_FS_44100HZ: return 44100;
- case AK4117_FS_48000HZ: return 48000;
- case AK4117_FS_88200HZ: return 88200;
- case AK4117_FS_96000HZ: return 96000;
- case AK4117_FS_176400HZ: return 176400;
- case AK4117_FS_192000HZ: return 192000;
- default: return 0;
- }
-}
-
-static int snd_ak4117_in_error_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = LONG_MAX;
- return 0;
-}
-
-static int snd_ak4117_in_error_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
- long *ptr;
-
- spin_lock_irq(&chip->lock);
- ptr = (long *)(((char *)chip) + kcontrol->private_value);
- ucontrol->value.integer.value[0] = *ptr;
- *ptr = 0;
- spin_unlock_irq(&chip->lock);
- return 0;
-}
-
-#define snd_ak4117_in_bit_info snd_ctl_boolean_mono_info
-
-static int snd_ak4117_in_bit_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
- unsigned char reg = kcontrol->private_value & 0xff;
- unsigned char bit = (kcontrol->private_value >> 8) & 0xff;
- unsigned char inv = (kcontrol->private_value >> 31) & 1;
-
- ucontrol->value.integer.value[0] = ((reg_read(chip, reg) & (1 << bit)) ? 1 : 0) ^ inv;
- return 0;
-}
-
-static int snd_ak4117_rx_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int snd_ak4117_rx_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = (chip->regmap[AK4117_REG_IO] & AK4117_IPS) ? 1 : 0;
- return 0;
-}
-
-static int snd_ak4117_rx_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
- int change;
- u8 old_val;
-
- spin_lock_irq(&chip->lock);
- old_val = chip->regmap[AK4117_REG_IO];
- change = !!ucontrol->value.integer.value[0] != ((old_val & AK4117_IPS) ? 1 : 0);
- if (change)
- reg_write(chip, AK4117_REG_IO, (old_val & ~AK4117_IPS) | (ucontrol->value.integer.value[0] ? AK4117_IPS : 0));
- spin_unlock_irq(&chip->lock);
- return change;
-}
-
-static int snd_ak4117_rate_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 192000;
- return 0;
-}
-
-static int snd_ak4117_rate_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = external_rate(reg_read(chip, AK4117_REG_RCS1));
- return 0;
-}
-
-static int snd_ak4117_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_ak4117_spdif_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
- unsigned i;
-
- for (i = 0; i < AK4117_REG_RXCSB_SIZE; i++)
- ucontrol->value.iec958.status[i] = reg_read(chip, AK4117_REG_RXCSB0 + i);
- return 0;
-}
-
-static int snd_ak4117_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_ak4117_spdif_mask_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- memset(ucontrol->value.iec958.status, 0xff, AK4117_REG_RXCSB_SIZE);
- return 0;
-}
-
-static int snd_ak4117_spdif_pinfo(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 0xffff;
- uinfo->count = 4;
- return 0;
-}
-
-static int snd_ak4117_spdif_pget(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
- unsigned short tmp;
-
- ucontrol->value.integer.value[0] = 0xf8f2;
- ucontrol->value.integer.value[1] = 0x4e1f;
- tmp = reg_read(chip, AK4117_REG_Pc0) | (reg_read(chip, AK4117_REG_Pc1) << 8);
- ucontrol->value.integer.value[2] = tmp;
- tmp = reg_read(chip, AK4117_REG_Pd0) | (reg_read(chip, AK4117_REG_Pd1) << 8);
- ucontrol->value.integer.value[3] = tmp;
- return 0;
-}
-
-static int snd_ak4117_spdif_qinfo(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
- uinfo->count = AK4117_REG_QSUB_SIZE;
- return 0;
-}
-
-static int snd_ak4117_spdif_qget(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
- unsigned i;
-
- for (i = 0; i < AK4117_REG_QSUB_SIZE; i++)
- ucontrol->value.bytes.data[i] = reg_read(chip, AK4117_REG_QSUB_ADDR + i);
- return 0;
-}
-
-/* Don't forget to change AK4117_CONTROLS define!!! */
-static struct snd_kcontrol_new snd_ak4117_iec958_controls[] = {
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 Parity Errors",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4117_in_error_info,
- .get = snd_ak4117_in_error_get,
- .private_value = offsetof(struct ak4117, parity_errors),
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 V-Bit Errors",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4117_in_error_info,
- .get = snd_ak4117_in_error_get,
- .private_value = offsetof(struct ak4117, v_bit_errors),
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 C-CRC Errors",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4117_in_error_info,
- .get = snd_ak4117_in_error_get,
- .private_value = offsetof(struct ak4117, ccrc_errors),
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 Q-CRC Errors",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4117_in_error_info,
- .get = snd_ak4117_in_error_get,
- .private_value = offsetof(struct ak4117, qcrc_errors),
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 External Rate",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4117_rate_info,
- .get = snd_ak4117_rate_get,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .info = snd_ak4117_spdif_mask_info,
- .get = snd_ak4117_spdif_mask_get,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4117_spdif_info,
- .get = snd_ak4117_spdif_get,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 Preample Capture Default",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4117_spdif_pinfo,
- .get = snd_ak4117_spdif_pget,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 Q-subcode Capture Default",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4117_spdif_qinfo,
- .get = snd_ak4117_spdif_qget,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 Audio",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4117_in_bit_info,
- .get = snd_ak4117_in_bit_get,
- .private_value = (1<<31) | (3<<8) | AK4117_REG_RCS0,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 Non-PCM Bitstream",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4117_in_bit_info,
- .get = snd_ak4117_in_bit_get,
- .private_value = (5<<8) | AK4117_REG_RCS1,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "IEC958 DTS Bitstream",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ak4117_in_bit_info,
- .get = snd_ak4117_in_bit_get,
- .private_value = (6<<8) | AK4117_REG_RCS1,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "AK4117 Input Select",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE,
- .info = snd_ak4117_rx_info,
- .get = snd_ak4117_rx_get,
- .put = snd_ak4117_rx_put,
-}
-};
-
-int snd_ak4117_build(struct ak4117 *ak4117, struct snd_pcm_substream *cap_substream)
-{
- struct snd_kcontrol *kctl;
- unsigned int idx;
- int err;
-
- if (snd_BUG_ON(!cap_substream))
- return -EINVAL;
- ak4117->substream = cap_substream;
- for (idx = 0; idx < AK4117_CONTROLS; idx++) {
- kctl = snd_ctl_new1(&snd_ak4117_iec958_controls[idx], ak4117);
- if (kctl == NULL)
- return -ENOMEM;
- kctl->id.device = cap_substream->pcm->device;
- kctl->id.subdevice = cap_substream->number;
- err = snd_ctl_add(ak4117->card, kctl);
- if (err < 0)
- return err;
- ak4117->kctls[idx] = kctl;
- }
- return 0;
-}
-
-int snd_ak4117_external_rate(struct ak4117 *ak4117)
-{
- unsigned char rcs1;
-
- rcs1 = reg_read(ak4117, AK4117_REG_RCS1);
- return external_rate(rcs1);
-}
-
-int snd_ak4117_check_rate_and_errors(struct ak4117 *ak4117, unsigned int flags)
-{
- struct snd_pcm_runtime *runtime = ak4117->substream ? ak4117->substream->runtime : NULL;
- unsigned long _flags;
- int res = 0;
- unsigned char rcs0, rcs1, rcs2;
- unsigned char c0, c1;
-
- rcs1 = reg_read(ak4117, AK4117_REG_RCS1);
- if (flags & AK4117_CHECK_NO_STAT)
- goto __rate;
- rcs0 = reg_read(ak4117, AK4117_REG_RCS0);
- rcs2 = reg_read(ak4117, AK4117_REG_RCS2);
- // printk(KERN_DEBUG "AK IRQ: rcs0 = 0x%x, rcs1 = 0x%x, rcs2 = 0x%x\n", rcs0, rcs1, rcs2);
- spin_lock_irqsave(&ak4117->lock, _flags);
- if (rcs0 & AK4117_PAR)
- ak4117->parity_errors++;
- if (rcs0 & AK4117_V)
- ak4117->v_bit_errors++;
- if (rcs2 & AK4117_CCRC)
- ak4117->ccrc_errors++;
- if (rcs2 & AK4117_QCRC)
- ak4117->qcrc_errors++;
- c0 = (ak4117->rcs0 & (AK4117_QINT | AK4117_CINT | AK4117_STC | AK4117_AUDION | AK4117_AUTO | AK4117_UNLCK)) ^
- (rcs0 & (AK4117_QINT | AK4117_CINT | AK4117_STC | AK4117_AUDION | AK4117_AUTO | AK4117_UNLCK));
- c1 = (ak4117->rcs1 & (AK4117_DTSCD | AK4117_NPCM | AK4117_PEM | 0x0f)) ^
- (rcs1 & (AK4117_DTSCD | AK4117_NPCM | AK4117_PEM | 0x0f));
- ak4117->rcs0 = rcs0 & ~(AK4117_QINT | AK4117_CINT | AK4117_STC);
- ak4117->rcs1 = rcs1;
- ak4117->rcs2 = rcs2;
- spin_unlock_irqrestore(&ak4117->lock, _flags);
-
- if (rcs0 & AK4117_PAR)
- snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[0]->id);
- if (rcs0 & AK4117_V)
- snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[1]->id);
- if (rcs2 & AK4117_CCRC)
- snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[2]->id);
- if (rcs2 & AK4117_QCRC)
- snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[3]->id);
-
- /* rate change */
- if (c1 & 0x0f)
- snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[4]->id);
-
- if ((c1 & AK4117_PEM) | (c0 & AK4117_CINT))
- snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[6]->id);
- if (c0 & AK4117_QINT)
- snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[8]->id);
-
- if (c0 & AK4117_AUDION)
- snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[9]->id);
- if (c1 & AK4117_NPCM)
- snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[10]->id);
- if (c1 & AK4117_DTSCD)
- snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[11]->id);
-
- if (ak4117->change_callback && (c0 | c1) != 0)
- ak4117->change_callback(ak4117, c0, c1);
-
- __rate:
- /* compare rate */
- res = external_rate(rcs1);
- if (!(flags & AK4117_CHECK_NO_RATE) && runtime && runtime->rate != res) {
- snd_pcm_stream_lock_irqsave(ak4117->substream, _flags);
- if (snd_pcm_running(ak4117->substream)) {
- // printk(KERN_DEBUG "rate changed (%i <- %i)\n", runtime->rate, res);
- snd_pcm_stop(ak4117->substream, SNDRV_PCM_STATE_DRAINING);
- wake_up(&runtime->sleep);
- res = 1;
- }
- snd_pcm_stream_unlock_irqrestore(ak4117->substream, _flags);
- }
- return res;
-}
-
-static void snd_ak4117_timer(unsigned long data)
-{
- struct ak4117 *chip = (struct ak4117 *)data;
-
- if (chip->init)
- return;
- snd_ak4117_check_rate_and_errors(chip, 0);
- chip->timer.expires = 1 + jiffies;
- add_timer(&chip->timer);
-}
-
-EXPORT_SYMBOL(snd_ak4117_create);
-EXPORT_SYMBOL(snd_ak4117_reg_write);
-EXPORT_SYMBOL(snd_ak4117_reinit);
-EXPORT_SYMBOL(snd_ak4117_build);
-EXPORT_SYMBOL(snd_ak4117_external_rate);
-EXPORT_SYMBOL(snd_ak4117_check_rate_and_errors);
diff --git a/ANDROID_3.4.5/sound/i2c/other/ak4xxx-adda.c b/ANDROID_3.4.5/sound/i2c/other/ak4xxx-adda.c
deleted file mode 100644
index cef813d2..00000000
--- a/ANDROID_3.4.5/sound/i2c/other/ak4xxx-adda.c
+++ /dev/null
@@ -1,945 +0,0 @@
-/*
- * ALSA driver for AK4524 / AK4528 / AK4529 / AK4355 / AK4358 / AK4381
- * AD and DA converters
- *
- * Copyright (c) 2000-2004 Jaroslav Kysela <perex@perex.cz>,
- * Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/ak4xxx-adda.h>
-#include <sound/info.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("Routines for control of AK452x / AK43xx AD/DA converters");
-MODULE_LICENSE("GPL");
-
-/* write the given register and save the data to the cache */
-void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg,
- unsigned char val)
-{
- ak->ops.lock(ak, chip);
- ak->ops.write(ak, chip, reg, val);
-
- /* save the data */
- snd_akm4xxx_set(ak, chip, reg, val);
- ak->ops.unlock(ak, chip);
-}
-
-EXPORT_SYMBOL(snd_akm4xxx_write);
-
-/* reset procedure for AK4524 and AK4528 */
-static void ak4524_reset(struct snd_akm4xxx *ak, int state)
-{
- unsigned int chip;
- unsigned char reg;
-
- for (chip = 0; chip < ak->num_dacs/2; chip++) {
- snd_akm4xxx_write(ak, chip, 0x01, state ? 0x00 : 0x03);
- if (state)
- continue;
- /* DAC volumes */
- for (reg = 0x04; reg < ak->total_regs; reg++)
- snd_akm4xxx_write(ak, chip, reg,
- snd_akm4xxx_get(ak, chip, reg));
- }
-}
-
-/* reset procedure for AK4355 and AK4358 */
-static void ak435X_reset(struct snd_akm4xxx *ak, int state)
-{
- unsigned char reg;
-
- if (state) {
- snd_akm4xxx_write(ak, 0, 0x01, 0x02); /* reset and soft-mute */
- return;
- }
- for (reg = 0x00; reg < ak->total_regs; reg++)
- if (reg != 0x01)
- snd_akm4xxx_write(ak, 0, reg,
- snd_akm4xxx_get(ak, 0, reg));
- snd_akm4xxx_write(ak, 0, 0x01, 0x01); /* un-reset, unmute */
-}
-
-/* reset procedure for AK4381 */
-static void ak4381_reset(struct snd_akm4xxx *ak, int state)
-{
- unsigned int chip;
- unsigned char reg;
- for (chip = 0; chip < ak->num_dacs/2; chip++) {
- snd_akm4xxx_write(ak, chip, 0x00, state ? 0x0c : 0x0f);
- if (state)
- continue;
- for (reg = 0x01; reg < ak->total_regs; reg++)
- snd_akm4xxx_write(ak, chip, reg,
- snd_akm4xxx_get(ak, chip, reg));
- }
-}
-
-/*
- * reset the AKM codecs
- * @state: 1 = reset codec, 0 = restore the registers
- *
- * assert the reset operation and restores the register values to the chips.
- */
-void snd_akm4xxx_reset(struct snd_akm4xxx *ak, int state)
-{
- switch (ak->type) {
- case SND_AK4524:
- case SND_AK4528:
- case SND_AK4620:
- ak4524_reset(ak, state);
- break;
- case SND_AK4529:
- /* FIXME: needed for ak4529? */
- break;
- case SND_AK4355:
- ak435X_reset(ak, state);
- break;
- case SND_AK4358:
- ak435X_reset(ak, state);
- break;
- case SND_AK4381:
- ak4381_reset(ak, state);
- break;
- default:
- break;
- }
-}
-
-EXPORT_SYMBOL(snd_akm4xxx_reset);
-
-
-/*
- * Volume conversion table for non-linear volumes
- * from -63.5dB (mute) to 0dB step 0.5dB
- *
- * Used for AK4524/AK4620 input/ouput attenuation, AK4528, and
- * AK5365 input attenuation
- */
-static const unsigned char vol_cvt_datt[128] = {
- 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04,
- 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x06,
- 0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x0a,
- 0x0a, 0x0b, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x0f,
- 0x10, 0x10, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14,
- 0x15, 0x16, 0x17, 0x17, 0x18, 0x19, 0x1a, 0x1c,
- 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x23,
- 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2d,
- 0x2e, 0x30, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
- 0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3e, 0x3f, 0x40,
- 0x41, 0x42, 0x43, 0x44, 0x46, 0x47, 0x48, 0x4a,
- 0x4b, 0x4d, 0x4e, 0x50, 0x51, 0x52, 0x53, 0x54,
- 0x55, 0x56, 0x58, 0x59, 0x5b, 0x5c, 0x5e, 0x5f,
- 0x60, 0x61, 0x62, 0x64, 0x65, 0x66, 0x67, 0x69,
- 0x6a, 0x6c, 0x6d, 0x6f, 0x70, 0x71, 0x72, 0x73,
- 0x75, 0x76, 0x77, 0x79, 0x7a, 0x7c, 0x7d, 0x7f,
-};
-
-/*
- * dB tables
- */
-static const DECLARE_TLV_DB_SCALE(db_scale_vol_datt, -6350, 50, 1);
-static const DECLARE_TLV_DB_SCALE(db_scale_8bit, -12750, 50, 1);
-static const DECLARE_TLV_DB_SCALE(db_scale_7bit, -6350, 50, 1);
-static const DECLARE_TLV_DB_LINEAR(db_scale_linear, TLV_DB_GAIN_MUTE, 0);
-
-/*
- * initialize all the ak4xxx chips
- */
-void snd_akm4xxx_init(struct snd_akm4xxx *ak)
-{
- static const unsigned char inits_ak4524[] = {
- 0x00, 0x07, /* 0: all power up */
- 0x01, 0x00, /* 1: ADC/DAC reset */
- 0x02, 0x60, /* 2: 24bit I2S */
- 0x03, 0x19, /* 3: deemphasis off */
- 0x01, 0x03, /* 1: ADC/DAC enable */
- 0x04, 0x00, /* 4: ADC left muted */
- 0x05, 0x00, /* 5: ADC right muted */
- 0x06, 0x00, /* 6: DAC left muted */
- 0x07, 0x00, /* 7: DAC right muted */
- 0xff, 0xff
- };
- static const unsigned char inits_ak4528[] = {
- 0x00, 0x07, /* 0: all power up */
- 0x01, 0x00, /* 1: ADC/DAC reset */
- 0x02, 0x60, /* 2: 24bit I2S */
- 0x03, 0x0d, /* 3: deemphasis off, turn LR highpass filters on */
- 0x01, 0x03, /* 1: ADC/DAC enable */
- 0x04, 0x00, /* 4: ADC left muted */
- 0x05, 0x00, /* 5: ADC right muted */
- 0xff, 0xff
- };
- static const unsigned char inits_ak4529[] = {
- 0x09, 0x01, /* 9: ATS=0, RSTN=1 */
- 0x0a, 0x3f, /* A: all power up, no zero/overflow detection */
- 0x00, 0x0c, /* 0: TDM=0, 24bit I2S, SMUTE=0 */
- 0x01, 0x00, /* 1: ACKS=0, ADC, loop off */
- 0x02, 0xff, /* 2: LOUT1 muted */
- 0x03, 0xff, /* 3: ROUT1 muted */
- 0x04, 0xff, /* 4: LOUT2 muted */
- 0x05, 0xff, /* 5: ROUT2 muted */
- 0x06, 0xff, /* 6: LOUT3 muted */
- 0x07, 0xff, /* 7: ROUT3 muted */
- 0x0b, 0xff, /* B: LOUT4 muted */
- 0x0c, 0xff, /* C: ROUT4 muted */
- 0x08, 0x55, /* 8: deemphasis all off */
- 0xff, 0xff
- };
- static const unsigned char inits_ak4355[] = {
- 0x01, 0x02, /* 1: reset and soft-mute */
- 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect,
- * disable DZF, sharp roll-off, RSTN#=0 */
- 0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */
- // 0x02, 0x2e, /* quad speed */
- 0x03, 0x01, /* 3: de-emphasis off */
- 0x04, 0x00, /* 4: LOUT1 volume muted */
- 0x05, 0x00, /* 5: ROUT1 volume muted */
- 0x06, 0x00, /* 6: LOUT2 volume muted */
- 0x07, 0x00, /* 7: ROUT2 volume muted */
- 0x08, 0x00, /* 8: LOUT3 volume muted */
- 0x09, 0x00, /* 9: ROUT3 volume muted */
- 0x0a, 0x00, /* a: DATT speed=0, ignore DZF */
- 0x01, 0x01, /* 1: un-reset, unmute */
- 0xff, 0xff
- };
- static const unsigned char inits_ak4358[] = {
- 0x01, 0x02, /* 1: reset and soft-mute */
- 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect,
- * disable DZF, sharp roll-off, RSTN#=0 */
- 0x02, 0x4e, /* 2: DA's power up, normal speed, RSTN#=0 */
- /* 0x02, 0x6e,*/ /* quad speed */
- 0x03, 0x01, /* 3: de-emphasis off */
- 0x04, 0x00, /* 4: LOUT1 volume muted */
- 0x05, 0x00, /* 5: ROUT1 volume muted */
- 0x06, 0x00, /* 6: LOUT2 volume muted */
- 0x07, 0x00, /* 7: ROUT2 volume muted */
- 0x08, 0x00, /* 8: LOUT3 volume muted */
- 0x09, 0x00, /* 9: ROUT3 volume muted */
- 0x0b, 0x00, /* b: LOUT4 volume muted */
- 0x0c, 0x00, /* c: ROUT4 volume muted */
- 0x0a, 0x00, /* a: DATT speed=0, ignore DZF */
- 0x01, 0x01, /* 1: un-reset, unmute */
- 0xff, 0xff
- };
- static const unsigned char inits_ak4381[] = {
- 0x00, 0x0c, /* 0: mode3(i2s), disable auto-clock detect */
- 0x01, 0x02, /* 1: de-emphasis off, normal speed,
- * sharp roll-off, DZF off */
- // 0x01, 0x12, /* quad speed */
- 0x02, 0x00, /* 2: DZF disabled */
- 0x03, 0x00, /* 3: LATT 0 */
- 0x04, 0x00, /* 4: RATT 0 */
- 0x00, 0x0f, /* 0: power-up, un-reset */
- 0xff, 0xff
- };
- static const unsigned char inits_ak4620[] = {
- 0x00, 0x07, /* 0: normal */
- 0x01, 0x00, /* 0: reset */
- 0x01, 0x02, /* 1: RSTAD */
- 0x01, 0x03, /* 1: RSTDA */
- 0x01, 0x0f, /* 1: normal */
- 0x02, 0x60, /* 2: 24bit I2S */
- 0x03, 0x01, /* 3: deemphasis off */
- 0x04, 0x00, /* 4: LIN muted */
- 0x05, 0x00, /* 5: RIN muted */
- 0x06, 0x00, /* 6: LOUT muted */
- 0x07, 0x00, /* 7: ROUT muted */
- 0xff, 0xff
- };
-
- int chip;
- const unsigned char *ptr, *inits;
- unsigned char reg, data;
-
- memset(ak->images, 0, sizeof(ak->images));
- memset(ak->volumes, 0, sizeof(ak->volumes));
-
- switch (ak->type) {
- case SND_AK4524:
- inits = inits_ak4524;
- ak->num_chips = ak->num_dacs / 2;
- ak->name = "ak4524";
- ak->total_regs = 0x08;
- break;
- case SND_AK4528:
- inits = inits_ak4528;
- ak->num_chips = ak->num_dacs / 2;
- ak->name = "ak4528";
- ak->total_regs = 0x06;
- break;
- case SND_AK4529:
- inits = inits_ak4529;
- ak->num_chips = 1;
- ak->name = "ak4529";
- ak->total_regs = 0x0d;
- break;
- case SND_AK4355:
- inits = inits_ak4355;
- ak->num_chips = 1;
- ak->name = "ak4355";
- ak->total_regs = 0x0b;
- break;
- case SND_AK4358:
- inits = inits_ak4358;
- ak->num_chips = 1;
- ak->name = "ak4358";
- ak->total_regs = 0x10;
- break;
- case SND_AK4381:
- inits = inits_ak4381;
- ak->num_chips = ak->num_dacs / 2;
- ak->name = "ak4381";
- ak->total_regs = 0x05;
- break;
- case SND_AK5365:
- /* FIXME: any init sequence? */
- ak->num_chips = 1;
- ak->name = "ak5365";
- ak->total_regs = 0x08;
- return;
- case SND_AK4620:
- inits = inits_ak4620;
- ak->num_chips = ak->num_dacs / 2;
- ak->name = "ak4620";
- ak->total_regs = 0x08;
- break;
- default:
- snd_BUG();
- return;
- }
-
- for (chip = 0; chip < ak->num_chips; chip++) {
- ptr = inits;
- while (*ptr != 0xff) {
- reg = *ptr++;
- data = *ptr++;
- snd_akm4xxx_write(ak, chip, reg, data);
- udelay(10);
- }
- }
-}
-
-EXPORT_SYMBOL(snd_akm4xxx_init);
-
-/*
- * Mixer callbacks
- */
-#define AK_IPGA (1<<20) /* including IPGA */
-#define AK_VOL_CVT (1<<21) /* need dB conversion */
-#define AK_NEEDSMSB (1<<22) /* need MSB update bit */
-#define AK_INVERT (1<<23) /* data is inverted */
-#define AK_GET_CHIP(val) (((val) >> 8) & 0xff)
-#define AK_GET_ADDR(val) ((val) & 0xff)
-#define AK_GET_SHIFT(val) (((val) >> 16) & 0x0f)
-#define AK_GET_VOL_CVT(val) (((val) >> 21) & 1)
-#define AK_GET_IPGA(val) (((val) >> 20) & 1)
-#define AK_GET_NEEDSMSB(val) (((val) >> 22) & 1)
-#define AK_GET_INVERT(val) (((val) >> 23) & 1)
-#define AK_GET_MASK(val) (((val) >> 24) & 0xff)
-#define AK_COMPOSE(chip,addr,shift,mask) \
- (((chip) << 8) | (addr) | ((shift) << 16) | ((mask) << 24))
-
-static int snd_akm4xxx_volume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- unsigned int mask = AK_GET_MASK(kcontrol->private_value);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_akm4xxx_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
- int chip = AK_GET_CHIP(kcontrol->private_value);
- int addr = AK_GET_ADDR(kcontrol->private_value);
-
- ucontrol->value.integer.value[0] = snd_akm4xxx_get_vol(ak, chip, addr);
- return 0;
-}
-
-static int put_ak_reg(struct snd_kcontrol *kcontrol, int addr,
- unsigned char nval)
-{
- struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
- unsigned int mask = AK_GET_MASK(kcontrol->private_value);
- int chip = AK_GET_CHIP(kcontrol->private_value);
-
- if (snd_akm4xxx_get_vol(ak, chip, addr) == nval)
- return 0;
-
- snd_akm4xxx_set_vol(ak, chip, addr, nval);
- if (AK_GET_VOL_CVT(kcontrol->private_value) && nval < 128)
- nval = vol_cvt_datt[nval];
- if (AK_GET_IPGA(kcontrol->private_value) && nval >= 128)
- nval++; /* need to correct + 1 since both 127 and 128 are 0dB */
- if (AK_GET_INVERT(kcontrol->private_value))
- nval = mask - nval;
- if (AK_GET_NEEDSMSB(kcontrol->private_value))
- nval |= 0x80;
- /* printk(KERN_DEBUG "DEBUG - AK writing reg: chip %x addr %x,
- nval %x\n", chip, addr, nval); */
- snd_akm4xxx_write(ak, chip, addr, nval);
- return 1;
-}
-
-static int snd_akm4xxx_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- unsigned int mask = AK_GET_MASK(kcontrol->private_value);
- unsigned int val = ucontrol->value.integer.value[0];
- if (val > mask)
- return -EINVAL;
- return put_ak_reg(kcontrol, AK_GET_ADDR(kcontrol->private_value), val);
-}
-
-static int snd_akm4xxx_stereo_volume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- unsigned int mask = AK_GET_MASK(kcontrol->private_value);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_akm4xxx_stereo_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
- int chip = AK_GET_CHIP(kcontrol->private_value);
- int addr = AK_GET_ADDR(kcontrol->private_value);
-
- ucontrol->value.integer.value[0] = snd_akm4xxx_get_vol(ak, chip, addr);
- ucontrol->value.integer.value[1] = snd_akm4xxx_get_vol(ak, chip, addr+1);
- return 0;
-}
-
-static int snd_akm4xxx_stereo_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int addr = AK_GET_ADDR(kcontrol->private_value);
- unsigned int mask = AK_GET_MASK(kcontrol->private_value);
- unsigned int val[2];
- int change;
-
- val[0] = ucontrol->value.integer.value[0];
- val[1] = ucontrol->value.integer.value[1];
- if (val[0] > mask || val[1] > mask)
- return -EINVAL;
- change = put_ak_reg(kcontrol, addr, val[0]);
- change |= put_ak_reg(kcontrol, addr + 1, val[1]);
- return change;
-}
-
-static int snd_akm4xxx_deemphasis_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[4] = {
- "44.1kHz", "Off", "48kHz", "32kHz",
- };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 4;
- if (uinfo->value.enumerated.item >= 4)
- uinfo->value.enumerated.item = 3;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_akm4xxx_deemphasis_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
- int chip = AK_GET_CHIP(kcontrol->private_value);
- int addr = AK_GET_ADDR(kcontrol->private_value);
- int shift = AK_GET_SHIFT(kcontrol->private_value);
- ucontrol->value.enumerated.item[0] =
- (snd_akm4xxx_get(ak, chip, addr) >> shift) & 3;
- return 0;
-}
-
-static int snd_akm4xxx_deemphasis_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
- int chip = AK_GET_CHIP(kcontrol->private_value);
- int addr = AK_GET_ADDR(kcontrol->private_value);
- int shift = AK_GET_SHIFT(kcontrol->private_value);
- unsigned char nval = ucontrol->value.enumerated.item[0] & 3;
- int change;
-
- nval = (nval << shift) |
- (snd_akm4xxx_get(ak, chip, addr) & ~(3 << shift));
- change = snd_akm4xxx_get(ak, chip, addr) != nval;
- if (change)
- snd_akm4xxx_write(ak, chip, addr, nval);
- return change;
-}
-
-#define ak4xxx_switch_info snd_ctl_boolean_mono_info
-
-static int ak4xxx_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
- int chip = AK_GET_CHIP(kcontrol->private_value);
- int addr = AK_GET_ADDR(kcontrol->private_value);
- int shift = AK_GET_SHIFT(kcontrol->private_value);
- int invert = AK_GET_INVERT(kcontrol->private_value);
- /* we observe the (1<<shift) bit only */
- unsigned char val = snd_akm4xxx_get(ak, chip, addr) & (1<<shift);
- if (invert)
- val = ! val;
- ucontrol->value.integer.value[0] = (val & (1<<shift)) != 0;
- return 0;
-}
-
-static int ak4xxx_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
- int chip = AK_GET_CHIP(kcontrol->private_value);
- int addr = AK_GET_ADDR(kcontrol->private_value);
- int shift = AK_GET_SHIFT(kcontrol->private_value);
- int invert = AK_GET_INVERT(kcontrol->private_value);
- long flag = ucontrol->value.integer.value[0];
- unsigned char val, oval;
- int change;
-
- if (invert)
- flag = ! flag;
- oval = snd_akm4xxx_get(ak, chip, addr);
- if (flag)
- val = oval | (1<<shift);
- else
- val = oval & ~(1<<shift);
- change = (oval != val);
- if (change)
- snd_akm4xxx_write(ak, chip, addr, val);
- return change;
-}
-
-#define AK5365_NUM_INPUTS 5
-
-static int ak4xxx_capture_num_inputs(struct snd_akm4xxx *ak, int mixer_ch)
-{
- int num_names;
- const char **input_names;
-
- input_names = ak->adc_info[mixer_ch].input_names;
- num_names = 0;
- while (num_names < AK5365_NUM_INPUTS && input_names[num_names])
- ++num_names;
- return num_names;
-}
-
-static int ak4xxx_capture_source_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
- int mixer_ch = AK_GET_SHIFT(kcontrol->private_value);
- const char **input_names;
- int num_names, idx;
-
- num_names = ak4xxx_capture_num_inputs(ak, mixer_ch);
- if (!num_names)
- return -EINVAL;
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = num_names;
- idx = uinfo->value.enumerated.item;
- if (idx >= num_names)
- return -EINVAL;
- input_names = ak->adc_info[mixer_ch].input_names;
- strncpy(uinfo->value.enumerated.name, input_names[idx],
- sizeof(uinfo->value.enumerated.name));
- return 0;
-}
-
-static int ak4xxx_capture_source_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
- int chip = AK_GET_CHIP(kcontrol->private_value);
- int addr = AK_GET_ADDR(kcontrol->private_value);
- int mask = AK_GET_MASK(kcontrol->private_value);
- unsigned char val;
-
- val = snd_akm4xxx_get(ak, chip, addr) & mask;
- ucontrol->value.enumerated.item[0] = val;
- return 0;
-}
-
-static int ak4xxx_capture_source_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
- int mixer_ch = AK_GET_SHIFT(kcontrol->private_value);
- int chip = AK_GET_CHIP(kcontrol->private_value);
- int addr = AK_GET_ADDR(kcontrol->private_value);
- int mask = AK_GET_MASK(kcontrol->private_value);
- unsigned char oval, val;
- int num_names = ak4xxx_capture_num_inputs(ak, mixer_ch);
-
- if (ucontrol->value.enumerated.item[0] >= num_names)
- return -EINVAL;
-
- oval = snd_akm4xxx_get(ak, chip, addr);
- val = oval & ~mask;
- val |= ucontrol->value.enumerated.item[0] & mask;
- if (val != oval) {
- snd_akm4xxx_write(ak, chip, addr, val);
- return 1;
- }
- return 0;
-}
-
-/*
- * build AK4xxx controls
- */
-
-static int build_dac_controls(struct snd_akm4xxx *ak)
-{
- int idx, err, mixer_ch, num_stereo;
- struct snd_kcontrol_new knew;
-
- mixer_ch = 0;
- for (idx = 0; idx < ak->num_dacs; ) {
- /* mute control for Revolution 7.1 - AK4381 */
- if (ak->type == SND_AK4381
- && ak->dac_info[mixer_ch].switch_name) {
- memset(&knew, 0, sizeof(knew));
- knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- knew.count = 1;
- knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
- knew.name = ak->dac_info[mixer_ch].switch_name;
- knew.info = ak4xxx_switch_info;
- knew.get = ak4xxx_switch_get;
- knew.put = ak4xxx_switch_put;
- knew.access = 0;
- /* register 1, bit 0 (SMUTE): 0 = normal operation,
- 1 = mute */
- knew.private_value =
- AK_COMPOSE(idx/2, 1, 0, 0) | AK_INVERT;
- err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
- if (err < 0)
- return err;
- }
- memset(&knew, 0, sizeof(knew));
- if (! ak->dac_info || ! ak->dac_info[mixer_ch].name) {
- knew.name = "DAC Volume";
- knew.index = mixer_ch + ak->idx_offset * 2;
- num_stereo = 1;
- } else {
- knew.name = ak->dac_info[mixer_ch].name;
- num_stereo = ak->dac_info[mixer_ch].num_channels;
- }
- knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- knew.count = 1;
- knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ;
- if (num_stereo == 2) {
- knew.info = snd_akm4xxx_stereo_volume_info;
- knew.get = snd_akm4xxx_stereo_volume_get;
- knew.put = snd_akm4xxx_stereo_volume_put;
- } else {
- knew.info = snd_akm4xxx_volume_info;
- knew.get = snd_akm4xxx_volume_get;
- knew.put = snd_akm4xxx_volume_put;
- }
- switch (ak->type) {
- case SND_AK4524:
- /* register 6 & 7 */
- knew.private_value =
- AK_COMPOSE(idx/2, (idx%2) + 6, 0, 127) |
- AK_VOL_CVT;
- knew.tlv.p = db_scale_vol_datt;
- break;
- case SND_AK4528:
- /* register 4 & 5 */
- knew.private_value =
- AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127) |
- AK_VOL_CVT;
- knew.tlv.p = db_scale_vol_datt;
- break;
- case SND_AK4529: {
- /* registers 2-7 and b,c */
- int val = idx < 6 ? idx + 2 : (idx - 6) + 0xb;
- knew.private_value =
- AK_COMPOSE(0, val, 0, 255) | AK_INVERT;
- knew.tlv.p = db_scale_8bit;
- break;
- }
- case SND_AK4355:
- /* register 4-9, chip #0 only */
- knew.private_value = AK_COMPOSE(0, idx + 4, 0, 255);
- knew.tlv.p = db_scale_8bit;
- break;
- case SND_AK4358: {
- /* register 4-9 and 11-12, chip #0 only */
- int addr = idx < 6 ? idx + 4 : idx + 5;
- knew.private_value =
- AK_COMPOSE(0, addr, 0, 127) | AK_NEEDSMSB;
- knew.tlv.p = db_scale_7bit;
- break;
- }
- case SND_AK4381:
- /* register 3 & 4 */
- knew.private_value =
- AK_COMPOSE(idx/2, (idx%2) + 3, 0, 255);
- knew.tlv.p = db_scale_linear;
- break;
- case SND_AK4620:
- /* register 6 & 7 */
- knew.private_value =
- AK_COMPOSE(idx/2, (idx%2) + 6, 0, 255);
- knew.tlv.p = db_scale_linear;
- break;
- default:
- return -EINVAL;
- }
-
- err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
- if (err < 0)
- return err;
-
- idx += num_stereo;
- mixer_ch++;
- }
- return 0;
-}
-
-static int build_adc_controls(struct snd_akm4xxx *ak)
-{
- int idx, err, mixer_ch, num_stereo, max_steps;
- struct snd_kcontrol_new knew;
-
- mixer_ch = 0;
- if (ak->type == SND_AK4528)
- return 0; /* no controls */
- for (idx = 0; idx < ak->num_adcs;) {
- memset(&knew, 0, sizeof(knew));
- if (! ak->adc_info || ! ak->adc_info[mixer_ch].name) {
- knew.name = "ADC Volume";
- knew.index = mixer_ch + ak->idx_offset * 2;
- num_stereo = 1;
- } else {
- knew.name = ak->adc_info[mixer_ch].name;
- num_stereo = ak->adc_info[mixer_ch].num_channels;
- }
- knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- knew.count = 1;
- knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ;
- if (num_stereo == 2) {
- knew.info = snd_akm4xxx_stereo_volume_info;
- knew.get = snd_akm4xxx_stereo_volume_get;
- knew.put = snd_akm4xxx_stereo_volume_put;
- } else {
- knew.info = snd_akm4xxx_volume_info;
- knew.get = snd_akm4xxx_volume_get;
- knew.put = snd_akm4xxx_volume_put;
- }
- /* register 4 & 5 */
- if (ak->type == SND_AK5365)
- max_steps = 152;
- else
- max_steps = 164;
- knew.private_value =
- AK_COMPOSE(idx/2, (idx%2) + 4, 0, max_steps) |
- AK_VOL_CVT | AK_IPGA;
- knew.tlv.p = db_scale_vol_datt;
- err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
- if (err < 0)
- return err;
-
- if (ak->type == SND_AK5365 && (idx % 2) == 0) {
- if (! ak->adc_info ||
- ! ak->adc_info[mixer_ch].switch_name) {
- knew.name = "Capture Switch";
- knew.index = mixer_ch + ak->idx_offset * 2;
- } else
- knew.name = ak->adc_info[mixer_ch].switch_name;
- knew.info = ak4xxx_switch_info;
- knew.get = ak4xxx_switch_get;
- knew.put = ak4xxx_switch_put;
- knew.access = 0;
- /* register 2, bit 0 (SMUTE): 0 = normal operation,
- 1 = mute */
- knew.private_value =
- AK_COMPOSE(idx/2, 2, 0, 0) | AK_INVERT;
- err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
- if (err < 0)
- return err;
-
- memset(&knew, 0, sizeof(knew));
- knew.name = ak->adc_info[mixer_ch].selector_name;
- if (!knew.name) {
- knew.name = "Capture Channel";
- knew.index = mixer_ch + ak->idx_offset * 2;
- }
-
- knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- knew.info = ak4xxx_capture_source_info;
- knew.get = ak4xxx_capture_source_get;
- knew.put = ak4xxx_capture_source_put;
- knew.access = 0;
- /* input selector control: reg. 1, bits 0-2.
- * mis-use 'shift' to pass mixer_ch */
- knew.private_value
- = AK_COMPOSE(idx/2, 1, mixer_ch, 0x07);
- err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
- if (err < 0)
- return err;
- }
-
- idx += num_stereo;
- mixer_ch++;
- }
- return 0;
-}
-
-static int build_deemphasis(struct snd_akm4xxx *ak, int num_emphs)
-{
- int idx, err;
- struct snd_kcontrol_new knew;
-
- for (idx = 0; idx < num_emphs; idx++) {
- memset(&knew, 0, sizeof(knew));
- knew.name = "Deemphasis";
- knew.index = idx + ak->idx_offset;
- knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- knew.count = 1;
- knew.info = snd_akm4xxx_deemphasis_info;
- knew.get = snd_akm4xxx_deemphasis_get;
- knew.put = snd_akm4xxx_deemphasis_put;
- switch (ak->type) {
- case SND_AK4524:
- case SND_AK4528:
- case SND_AK4620:
- /* register 3 */
- knew.private_value = AK_COMPOSE(idx, 3, 0, 0);
- break;
- case SND_AK4529: {
- int shift = idx == 3 ? 6 : (2 - idx) * 2;
- /* register 8 with shift */
- knew.private_value = AK_COMPOSE(0, 8, shift, 0);
- break;
- }
- case SND_AK4355:
- case SND_AK4358:
- knew.private_value = AK_COMPOSE(idx, 3, 0, 0);
- break;
- case SND_AK4381:
- knew.private_value = AK_COMPOSE(idx, 1, 1, 0);
- break;
- default:
- return -EINVAL;
- }
- err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-#ifdef CONFIG_PROC_FS
-static void proc_regs_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_akm4xxx *ak = entry->private_data;
- int reg, val, chip;
- for (chip = 0; chip < ak->num_chips; chip++) {
- for (reg = 0; reg < ak->total_regs; reg++) {
- val = snd_akm4xxx_get(ak, chip, reg);
- snd_iprintf(buffer, "chip %d: 0x%02x = 0x%02x\n", chip,
- reg, val);
- }
- }
-}
-
-static int proc_init(struct snd_akm4xxx *ak)
-{
- struct snd_info_entry *entry;
- int err;
- err = snd_card_proc_new(ak->card, ak->name, &entry);
- if (err < 0)
- return err;
- snd_info_set_text_ops(entry, ak, proc_regs_read);
- return 0;
-}
-#else /* !CONFIG_PROC_FS */
-static int proc_init(struct snd_akm4xxx *ak) { return 0; }
-#endif
-
-int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak)
-{
- int err, num_emphs;
-
- err = build_dac_controls(ak);
- if (err < 0)
- return err;
-
- err = build_adc_controls(ak);
- if (err < 0)
- return err;
- if (ak->type == SND_AK4355 || ak->type == SND_AK4358)
- num_emphs = 1;
- else if (ak->type == SND_AK4620)
- num_emphs = 0;
- else
- num_emphs = ak->num_dacs / 2;
- err = build_deemphasis(ak, num_emphs);
- if (err < 0)
- return err;
- err = proc_init(ak);
- if (err < 0)
- return err;
-
- return 0;
-}
-EXPORT_SYMBOL(snd_akm4xxx_build_controls);
-
-static int __init alsa_akm4xxx_module_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_akm4xxx_module_exit(void)
-{
-}
-
-module_init(alsa_akm4xxx_module_init)
-module_exit(alsa_akm4xxx_module_exit)
diff --git a/ANDROID_3.4.5/sound/i2c/other/pt2258.c b/ANDROID_3.4.5/sound/i2c/other/pt2258.c
deleted file mode 100644
index 9fa390ba..00000000
--- a/ANDROID_3.4.5/sound/i2c/other/pt2258.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * ALSA Driver for the PT2258 volume controller.
- *
- * Copyright (c) 2006 Jochen Voss <voss@seehuhn.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/i2c.h>
-#include <sound/pt2258.h>
-#include <linux/module.h>
-
-MODULE_AUTHOR("Jochen Voss <voss@seehuhn.de>");
-MODULE_DESCRIPTION("PT2258 volume controller (Princeton Technology Corp.)");
-MODULE_LICENSE("GPL");
-
-#define PT2258_CMD_RESET 0xc0
-#define PT2258_CMD_UNMUTE 0xf8
-#define PT2258_CMD_MUTE 0xf9
-
-static const unsigned char pt2258_channel_code[12] = {
- 0x80, 0x90, /* channel 1: -10dB, -1dB */
- 0x40, 0x50, /* channel 2: -10dB, -1dB */
- 0x00, 0x10, /* channel 3: -10dB, -1dB */
- 0x20, 0x30, /* channel 4: -10dB, -1dB */
- 0x60, 0x70, /* channel 5: -10dB, -1dB */
- 0xa0, 0xb0 /* channel 6: -10dB, -1dB */
-};
-
-int snd_pt2258_reset(struct snd_pt2258 *pt)
-{
- unsigned char bytes[2];
- int i;
-
- /* reset chip */
- bytes[0] = PT2258_CMD_RESET;
- snd_i2c_lock(pt->i2c_bus);
- if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 1) != 1)
- goto __error;
- snd_i2c_unlock(pt->i2c_bus);
-
- /* mute all channels */
- pt->mute = 1;
- bytes[0] = PT2258_CMD_MUTE;
- snd_i2c_lock(pt->i2c_bus);
- if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 1) != 1)
- goto __error;
- snd_i2c_unlock(pt->i2c_bus);
-
- /* set all channels to 0dB */
- for (i = 0; i < 6; ++i)
- pt->volume[i] = 0;
- bytes[0] = 0xd0;
- bytes[1] = 0xe0;
- snd_i2c_lock(pt->i2c_bus);
- if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 2) != 2)
- goto __error;
- snd_i2c_unlock(pt->i2c_bus);
-
- return 0;
-
- __error:
- snd_i2c_unlock(pt->i2c_bus);
- snd_printk(KERN_ERR "PT2258 reset failed\n");
- return -EIO;
-}
-
-static int pt2258_stereo_volume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 79;
- return 0;
-}
-
-static int pt2258_stereo_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pt2258 *pt = kcontrol->private_data;
- int base = kcontrol->private_value;
-
- /* chip does not support register reads */
- ucontrol->value.integer.value[0] = 79 - pt->volume[base];
- ucontrol->value.integer.value[1] = 79 - pt->volume[base + 1];
- return 0;
-}
-
-static int pt2258_stereo_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pt2258 *pt = kcontrol->private_data;
- int base = kcontrol->private_value;
- unsigned char bytes[2];
- int val0, val1;
-
- val0 = 79 - ucontrol->value.integer.value[0];
- val1 = 79 - ucontrol->value.integer.value[1];
- if (val0 < 0 || val0 > 79 || val1 < 0 || val1 > 79)
- return -EINVAL;
- if (val0 == pt->volume[base] && val1 == pt->volume[base + 1])
- return 0;
-
- pt->volume[base] = val0;
- bytes[0] = pt2258_channel_code[2 * base] | (val0 / 10);
- bytes[1] = pt2258_channel_code[2 * base + 1] | (val0 % 10);
- snd_i2c_lock(pt->i2c_bus);
- if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 2) != 2)
- goto __error;
- snd_i2c_unlock(pt->i2c_bus);
-
- pt->volume[base + 1] = val1;
- bytes[0] = pt2258_channel_code[2 * base + 2] | (val1 / 10);
- bytes[1] = pt2258_channel_code[2 * base + 3] | (val1 % 10);
- snd_i2c_lock(pt->i2c_bus);
- if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 2) != 2)
- goto __error;
- snd_i2c_unlock(pt->i2c_bus);
-
- return 1;
-
- __error:
- snd_i2c_unlock(pt->i2c_bus);
- snd_printk(KERN_ERR "PT2258 access failed\n");
- return -EIO;
-}
-
-#define pt2258_switch_info snd_ctl_boolean_mono_info
-
-static int pt2258_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pt2258 *pt = kcontrol->private_data;
-
- ucontrol->value.integer.value[0] = !pt->mute;
- return 0;
-}
-
-static int pt2258_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pt2258 *pt = kcontrol->private_data;
- unsigned char bytes[2];
- int val;
-
- val = !ucontrol->value.integer.value[0];
- if (pt->mute == val)
- return 0;
-
- pt->mute = val;
- bytes[0] = val ? PT2258_CMD_MUTE : PT2258_CMD_UNMUTE;
- snd_i2c_lock(pt->i2c_bus);
- if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 1) != 1)
- goto __error;
- snd_i2c_unlock(pt->i2c_bus);
-
- return 1;
-
- __error:
- snd_i2c_unlock(pt->i2c_bus);
- snd_printk(KERN_ERR "PT2258 access failed 2\n");
- return -EIO;
-}
-
-static const DECLARE_TLV_DB_SCALE(pt2258_db_scale, -7900, 100, 0);
-
-int snd_pt2258_build_controls(struct snd_pt2258 *pt)
-{
- struct snd_kcontrol_new knew;
- char *names[3] = {
- "Mic Loopback Playback Volume",
- "Line Loopback Playback Volume",
- "CD Loopback Playback Volume"
- };
- int i, err;
-
- for (i = 0; i < 3; ++i) {
- memset(&knew, 0, sizeof(knew));
- knew.name = names[i];
- knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- knew.count = 1;
- knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ;
- knew.private_value = 2 * i;
- knew.info = pt2258_stereo_volume_info;
- knew.get = pt2258_stereo_volume_get;
- knew.put = pt2258_stereo_volume_put;
- knew.tlv.p = pt2258_db_scale;
-
- err = snd_ctl_add(pt->card, snd_ctl_new1(&knew, pt));
- if (err < 0)
- return err;
- }
-
- memset(&knew, 0, sizeof(knew));
- knew.name = "Loopback Switch";
- knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- knew.info = pt2258_switch_info;
- knew.get = pt2258_switch_get;
- knew.put = pt2258_switch_put;
- knew.access = 0;
- err = snd_ctl_add(pt->card, snd_ctl_new1(&knew, pt));
- if (err < 0)
- return err;
-
- return 0;
-}
-
-EXPORT_SYMBOL(snd_pt2258_reset);
-EXPORT_SYMBOL(snd_pt2258_build_controls);
diff --git a/ANDROID_3.4.5/sound/i2c/other/tea575x-tuner.c b/ANDROID_3.4.5/sound/i2c/other/tea575x-tuner.c
deleted file mode 100644
index a63faec5..00000000
--- a/ANDROID_3.4.5/sound/i2c/other/tea575x-tuner.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * ALSA driver for TEA5757/5759 Philips AM/FM radio tuner chips
- *
- * Copyright (c) 2004 Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-dev.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-event.h>
-#include <sound/tea575x-tuner.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips");
-MODULE_LICENSE("GPL");
-
-#define FREQ_LO (76U * 16000)
-#define FREQ_HI (108U * 16000)
-
-/*
- * definitions
- */
-
-#define TEA575X_BIT_SEARCH (1<<24) /* 1 = search action, 0 = tuned */
-#define TEA575X_BIT_UPDOWN (1<<23) /* 0 = search down, 1 = search up */
-#define TEA575X_BIT_MONO (1<<22) /* 0 = stereo, 1 = mono */
-#define TEA575X_BIT_BAND_MASK (3<<20)
-#define TEA575X_BIT_BAND_FM (0<<20)
-#define TEA575X_BIT_BAND_MW (1<<20)
-#define TEA575X_BIT_BAND_LW (1<<21)
-#define TEA575X_BIT_BAND_SW (1<<22)
-#define TEA575X_BIT_PORT_0 (1<<19) /* user bit */
-#define TEA575X_BIT_PORT_1 (1<<18) /* user bit */
-#define TEA575X_BIT_SEARCH_MASK (3<<16) /* search level */
-#define TEA575X_BIT_SEARCH_5_28 (0<<16) /* FM >5uV, AM >28uV */
-#define TEA575X_BIT_SEARCH_10_40 (1<<16) /* FM >10uV, AM > 40uV */
-#define TEA575X_BIT_SEARCH_30_63 (2<<16) /* FM >30uV, AM > 63uV */
-#define TEA575X_BIT_SEARCH_150_1000 (3<<16) /* FM > 150uV, AM > 1000uV */
-#define TEA575X_BIT_DUMMY (1<<15) /* buffer */
-#define TEA575X_BIT_FREQ_MASK 0x7fff
-
-/*
- * lowlevel part
- */
-
-static void snd_tea575x_write(struct snd_tea575x *tea, unsigned int val)
-{
- u16 l;
- u8 data;
-
- tea->ops->set_direction(tea, 1);
- udelay(16);
-
- for (l = 25; l > 0; l--) {
- data = (val >> 24) & TEA575X_DATA;
- val <<= 1; /* shift data */
- tea->ops->set_pins(tea, data | TEA575X_WREN);
- udelay(2);
- tea->ops->set_pins(tea, data | TEA575X_WREN | TEA575X_CLK);
- udelay(2);
- tea->ops->set_pins(tea, data | TEA575X_WREN);
- udelay(2);
- }
-
- if (!tea->mute)
- tea->ops->set_pins(tea, 0);
-}
-
-static u32 snd_tea575x_read(struct snd_tea575x *tea)
-{
- u16 l, rdata;
- u32 data = 0;
-
- tea->ops->set_direction(tea, 0);
- tea->ops->set_pins(tea, 0);
- udelay(16);
-
- for (l = 24; l--;) {
- tea->ops->set_pins(tea, TEA575X_CLK);
- udelay(2);
- if (!l)
- tea->tuned = tea->ops->get_pins(tea) & TEA575X_MOST ? 0 : 1;
- tea->ops->set_pins(tea, 0);
- udelay(2);
- data <<= 1; /* shift data */
- rdata = tea->ops->get_pins(tea);
- if (!l)
- tea->stereo = (rdata & TEA575X_MOST) ? 0 : 1;
- if (rdata & TEA575X_DATA)
- data++;
- udelay(2);
- }
-
- if (tea->mute)
- tea->ops->set_pins(tea, TEA575X_WREN);
-
- return data;
-}
-
-static u32 snd_tea575x_get_freq(struct snd_tea575x *tea)
-{
- u32 freq = snd_tea575x_read(tea) & TEA575X_BIT_FREQ_MASK;
-
- if (freq == 0)
- return freq;
-
- /* freq *= 12.5 */
- freq *= 125;
- freq /= 10;
- /* crystal fixup */
- if (tea->tea5759)
- freq += TEA575X_FMIF;
- else
- freq -= TEA575X_FMIF;
-
- return clamp(freq * 16, FREQ_LO, FREQ_HI); /* from kHz */
-}
-
-static void snd_tea575x_set_freq(struct snd_tea575x *tea)
-{
- u32 freq = tea->freq;
-
- freq /= 16; /* to kHz */
- /* crystal fixup */
- if (tea->tea5759)
- freq -= TEA575X_FMIF;
- else
- freq += TEA575X_FMIF;
- /* freq /= 12.5 */
- freq *= 10;
- freq /= 125;
-
- tea->val &= ~TEA575X_BIT_FREQ_MASK;
- tea->val |= freq & TEA575X_BIT_FREQ_MASK;
- snd_tea575x_write(tea, tea->val);
-}
-
-/*
- * Linux Video interface
- */
-
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *v)
-{
- struct snd_tea575x *tea = video_drvdata(file);
-
- strlcpy(v->driver, tea->v4l2_dev->name, sizeof(v->driver));
- strlcpy(v->card, tea->card, sizeof(v->card));
- strlcat(v->card, tea->tea5759 ? " TEA5759" : " TEA5757", sizeof(v->card));
- strlcpy(v->bus_info, tea->bus_info, sizeof(v->bus_info));
- v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
- if (!tea->cannot_read_data)
- v->device_caps |= V4L2_CAP_HW_FREQ_SEEK;
- v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
- return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *v)
-{
- struct snd_tea575x *tea = video_drvdata(file);
-
- if (v->index > 0)
- return -EINVAL;
-
- snd_tea575x_read(tea);
-
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
- v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
- v->rangelow = FREQ_LO;
- v->rangehigh = FREQ_HI;
- v->rxsubchans = tea->stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
- v->audmode = (tea->val & TEA575X_BIT_MONO) ?
- V4L2_TUNER_MODE_MONO : V4L2_TUNER_MODE_STEREO;
- v->signal = tea->tuned ? 0xffff : 0;
- return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
- struct v4l2_tuner *v)
-{
- struct snd_tea575x *tea = video_drvdata(file);
-
- if (v->index)
- return -EINVAL;
- tea->val &= ~TEA575X_BIT_MONO;
- if (v->audmode == V4L2_TUNER_MODE_MONO)
- tea->val |= TEA575X_BIT_MONO;
- snd_tea575x_write(tea, tea->val);
- return 0;
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct snd_tea575x *tea = video_drvdata(file);
-
- if (f->tuner != 0)
- return -EINVAL;
- f->type = V4L2_TUNER_RADIO;
- f->frequency = tea->freq;
- return 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct snd_tea575x *tea = video_drvdata(file);
-
- if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
- return -EINVAL;
-
- tea->val &= ~TEA575X_BIT_SEARCH;
- tea->freq = clamp(f->frequency, FREQ_LO, FREQ_HI);
- snd_tea575x_set_freq(tea);
- return 0;
-}
-
-static int vidioc_s_hw_freq_seek(struct file *file, void *fh,
- struct v4l2_hw_freq_seek *a)
-{
- struct snd_tea575x *tea = video_drvdata(file);
- unsigned long timeout;
- int i;
-
- if (tea->cannot_read_data)
- return -ENOTTY;
- if (a->tuner || a->wrap_around)
- return -EINVAL;
-
- /* clear the frequency, HW will fill it in */
- tea->val &= ~TEA575X_BIT_FREQ_MASK;
- tea->val |= TEA575X_BIT_SEARCH;
- if (a->seek_upward)
- tea->val |= TEA575X_BIT_UPDOWN;
- else
- tea->val &= ~TEA575X_BIT_UPDOWN;
- snd_tea575x_write(tea, tea->val);
- timeout = jiffies + msecs_to_jiffies(10000);
- for (;;) {
- if (time_after(jiffies, timeout))
- break;
- if (schedule_timeout_interruptible(msecs_to_jiffies(10))) {
- /* some signal arrived, stop search */
- tea->val &= ~TEA575X_BIT_SEARCH;
- snd_tea575x_set_freq(tea);
- return -ERESTARTSYS;
- }
- if (!(snd_tea575x_read(tea) & TEA575X_BIT_SEARCH)) {
- u32 freq;
-
- /* Found a frequency, wait until it can be read */
- for (i = 0; i < 100; i++) {
- msleep(10);
- freq = snd_tea575x_get_freq(tea);
- if (freq) /* available */
- break;
- }
- if (freq == 0) /* shouldn't happen */
- break;
- /*
- * if we moved by less than 50 kHz, or in the wrong
- * direction, continue seeking
- */
- if (abs(tea->freq - freq) < 16 * 50 ||
- (a->seek_upward && freq < tea->freq) ||
- (!a->seek_upward && freq > tea->freq)) {
- snd_tea575x_write(tea, tea->val);
- continue;
- }
- tea->freq = freq;
- tea->val &= ~TEA575X_BIT_SEARCH;
- return 0;
- }
- }
- tea->val &= ~TEA575X_BIT_SEARCH;
- snd_tea575x_set_freq(tea);
- return -EAGAIN;
-}
-
-static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct snd_tea575x *tea = container_of(ctrl->handler, struct snd_tea575x, ctrl_handler);
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- tea->mute = ctrl->val;
- snd_tea575x_set_freq(tea);
- return 0;
- }
-
- return -EINVAL;
-}
-
-static const struct v4l2_file_operations tea575x_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = video_ioctl2,
- .open = v4l2_fh_open,
- .release = v4l2_fh_release,
- .poll = v4l2_ctrl_poll,
-};
-
-static const struct v4l2_ioctl_ops tea575x_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_s_hw_freq_seek = vidioc_s_hw_freq_seek,
- .vidioc_log_status = v4l2_ctrl_log_status,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-static const struct video_device tea575x_radio = {
- .fops = &tea575x_fops,
- .ioctl_ops = &tea575x_ioctl_ops,
- .release = video_device_release_empty,
-};
-
-static const struct v4l2_ctrl_ops tea575x_ctrl_ops = {
- .s_ctrl = tea575x_s_ctrl,
-};
-
-/*
- * initialize all the tea575x chips
- */
-int snd_tea575x_init(struct snd_tea575x *tea)
-{
- int retval;
-
- tea->mute = true;
-
- /* Not all devices can or know how to read the data back.
- Such devices can set cannot_read_data to true. */
- if (!tea->cannot_read_data) {
- snd_tea575x_write(tea, 0x55AA);
- if (snd_tea575x_read(tea) != 0x55AA)
- return -ENODEV;
- }
-
- tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_5_28;
- tea->freq = 90500 * 16; /* 90.5Mhz default */
- snd_tea575x_set_freq(tea);
-
- tea->vd = tea575x_radio;
- video_set_drvdata(&tea->vd, tea);
- mutex_init(&tea->mutex);
- strlcpy(tea->vd.name, tea->v4l2_dev->name, sizeof(tea->vd.name));
- tea->vd.lock = &tea->mutex;
- tea->vd.v4l2_dev = tea->v4l2_dev;
- tea->vd.ctrl_handler = &tea->ctrl_handler;
- set_bit(V4L2_FL_USE_FH_PRIO, &tea->vd.flags);
-
- v4l2_ctrl_handler_init(&tea->ctrl_handler, 1);
- v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops, V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
- retval = tea->ctrl_handler.error;
- if (retval) {
- v4l2_err(tea->v4l2_dev, "can't initialize controls\n");
- v4l2_ctrl_handler_free(&tea->ctrl_handler);
- return retval;
- }
-
- if (tea->ext_init) {
- retval = tea->ext_init(tea);
- if (retval) {
- v4l2_ctrl_handler_free(&tea->ctrl_handler);
- return retval;
- }
- }
-
- v4l2_ctrl_handler_setup(&tea->ctrl_handler);
-
- retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->radio_nr);
- if (retval) {
- v4l2_err(tea->v4l2_dev, "can't register video device!\n");
- v4l2_ctrl_handler_free(&tea->ctrl_handler);
- return retval;
- }
-
- return 0;
-}
-
-void snd_tea575x_exit(struct snd_tea575x *tea)
-{
- video_unregister_device(&tea->vd);
- v4l2_ctrl_handler_free(&tea->ctrl_handler);
-}
-
-static int __init alsa_tea575x_module_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_tea575x_module_exit(void)
-{
-}
-
-module_init(alsa_tea575x_module_init)
-module_exit(alsa_tea575x_module_exit)
-
-EXPORT_SYMBOL(snd_tea575x_init);
-EXPORT_SYMBOL(snd_tea575x_exit);
diff --git a/ANDROID_3.4.5/sound/i2c/tea6330t.c b/ANDROID_3.4.5/sound/i2c/tea6330t.c
deleted file mode 100644
index 2d22310d..00000000
--- a/ANDROID_3.4.5/sound/i2c/tea6330t.c
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * Routines for control of the TEA6330T circuit via i2c bus
- * Sound fader control circuit for car radios by Philips Semiconductors
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/tea6330t.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Routines for control of the TEA6330T circuit via i2c bus");
-MODULE_LICENSE("GPL");
-
-#define TEA6330T_ADDR (0x80>>1) /* fixed address */
-
-#define TEA6330T_SADDR_VOLUME_LEFT 0x00 /* volume left */
-#define TEA6330T_SADDR_VOLUME_RIGHT 0x01 /* volume right */
-#define TEA6330T_SADDR_BASS 0x02 /* bass control */
-#define TEA6330T_SADDR_TREBLE 0x03 /* treble control */
-#define TEA6330T_SADDR_FADER 0x04 /* fader control */
-#define TEA6330T_MFN 0x20 /* mute control for selected channels */
-#define TEA6330T_FCH 0x10 /* select fader channels - front or rear */
-#define TEA6330T_SADDR_AUDIO_SWITCH 0x05 /* audio switch */
-#define TEA6330T_GMU 0x80 /* mute control, general mute */
-#define TEA6330T_EQN 0x40 /* equalizer switchover (0=equalizer-on) */
-
-
-struct tea6330t {
- struct snd_i2c_device *device;
- struct snd_i2c_bus *bus;
- int equalizer;
- int fader;
- unsigned char regs[8];
- unsigned char mleft, mright;
- unsigned char bass, treble;
- unsigned char max_bass, max_treble;
-};
-
-
-int snd_tea6330t_detect(struct snd_i2c_bus *bus, int equalizer)
-{
- int res;
-
- snd_i2c_lock(bus);
- res = snd_i2c_probeaddr(bus, TEA6330T_ADDR);
- snd_i2c_unlock(bus);
- return res;
-}
-
-#if 0
-static void snd_tea6330t_set(struct tea6330t *tea,
- unsigned char addr, unsigned char value)
-{
-#if 0
- printk(KERN_DEBUG "set - 0x%x/0x%x\n", addr, value);
-#endif
- snd_i2c_write(tea->bus, TEA6330T_ADDR, addr, value, 1);
-}
-#endif
-
-#define TEA6330T_MASTER_VOLUME(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_tea6330t_info_master_volume, \
- .get = snd_tea6330t_get_master_volume, .put = snd_tea6330t_put_master_volume }
-
-static int snd_tea6330t_info_master_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 43;
- return 0;
-}
-
-static int snd_tea6330t_get_master_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
-
- snd_i2c_lock(tea->bus);
- ucontrol->value.integer.value[0] = tea->mleft - 0x14;
- ucontrol->value.integer.value[1] = tea->mright - 0x14;
- snd_i2c_unlock(tea->bus);
- return 0;
-}
-
-static int snd_tea6330t_put_master_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
- int change, count, err;
- unsigned char bytes[3];
- unsigned char val1, val2;
-
- val1 = (ucontrol->value.integer.value[0] % 44) + 0x14;
- val2 = (ucontrol->value.integer.value[1] % 44) + 0x14;
- snd_i2c_lock(tea->bus);
- change = val1 != tea->mleft || val2 != tea->mright;
- tea->mleft = val1;
- tea->mright = val2;
- count = 0;
- if (tea->regs[TEA6330T_SADDR_VOLUME_LEFT] != 0) {
- bytes[count++] = TEA6330T_SADDR_VOLUME_LEFT;
- bytes[count++] = tea->regs[TEA6330T_SADDR_VOLUME_LEFT] = tea->mleft;
- }
- if (tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] != 0) {
- if (count == 0)
- bytes[count++] = TEA6330T_SADDR_VOLUME_RIGHT;
- bytes[count++] = tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] = tea->mright;
- }
- if (count > 0) {
- if ((err = snd_i2c_sendbytes(tea->device, bytes, count)) < 0)
- change = err;
- }
- snd_i2c_unlock(tea->bus);
- return change;
-}
-
-#define TEA6330T_MASTER_SWITCH(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_tea6330t_info_master_switch, \
- .get = snd_tea6330t_get_master_switch, .put = snd_tea6330t_put_master_switch }
-
-#define snd_tea6330t_info_master_switch snd_ctl_boolean_stereo_info
-
-static int snd_tea6330t_get_master_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
-
- snd_i2c_lock(tea->bus);
- ucontrol->value.integer.value[0] = tea->regs[TEA6330T_SADDR_VOLUME_LEFT] == 0 ? 0 : 1;
- ucontrol->value.integer.value[1] = tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] == 0 ? 0 : 1;
- snd_i2c_unlock(tea->bus);
- return 0;
-}
-
-static int snd_tea6330t_put_master_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
- int change, err;
- unsigned char bytes[3];
- unsigned char oval1, oval2, val1, val2;
-
- val1 = ucontrol->value.integer.value[0] & 1;
- val2 = ucontrol->value.integer.value[1] & 1;
- snd_i2c_lock(tea->bus);
- oval1 = tea->regs[TEA6330T_SADDR_VOLUME_LEFT] == 0 ? 0 : 1;
- oval2 = tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] == 0 ? 0 : 1;
- change = val1 != oval1 || val2 != oval2;
- tea->regs[TEA6330T_SADDR_VOLUME_LEFT] = val1 ? tea->mleft : 0;
- tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] = val2 ? tea->mright : 0;
- bytes[0] = TEA6330T_SADDR_VOLUME_LEFT;
- bytes[1] = tea->regs[TEA6330T_SADDR_VOLUME_LEFT];
- bytes[2] = tea->regs[TEA6330T_SADDR_VOLUME_RIGHT];
- if ((err = snd_i2c_sendbytes(tea->device, bytes, 3)) < 0)
- change = err;
- snd_i2c_unlock(tea->bus);
- return change;
-}
-
-#define TEA6330T_BASS(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_tea6330t_info_bass, \
- .get = snd_tea6330t_get_bass, .put = snd_tea6330t_put_bass }
-
-static int snd_tea6330t_info_bass(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = tea->max_bass;
- return 0;
-}
-
-static int snd_tea6330t_get_bass(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = tea->bass;
- return 0;
-}
-
-static int snd_tea6330t_put_bass(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
- int change, err;
- unsigned char bytes[2];
- unsigned char val1;
-
- val1 = ucontrol->value.integer.value[0] % (tea->max_bass + 1);
- snd_i2c_lock(tea->bus);
- tea->bass = val1;
- val1 += tea->equalizer ? 7 : 3;
- change = tea->regs[TEA6330T_SADDR_BASS] != val1;
- bytes[0] = TEA6330T_SADDR_BASS;
- bytes[1] = tea->regs[TEA6330T_SADDR_BASS] = val1;
- if ((err = snd_i2c_sendbytes(tea->device, bytes, 2)) < 0)
- change = err;
- snd_i2c_unlock(tea->bus);
- return change;
-}
-
-#define TEA6330T_TREBLE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_tea6330t_info_treble, \
- .get = snd_tea6330t_get_treble, .put = snd_tea6330t_put_treble }
-
-static int snd_tea6330t_info_treble(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = tea->max_treble;
- return 0;
-}
-
-static int snd_tea6330t_get_treble(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = tea->treble;
- return 0;
-}
-
-static int snd_tea6330t_put_treble(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
- int change, err;
- unsigned char bytes[2];
- unsigned char val1;
-
- val1 = ucontrol->value.integer.value[0] % (tea->max_treble + 1);
- snd_i2c_lock(tea->bus);
- tea->treble = val1;
- val1 += 3;
- change = tea->regs[TEA6330T_SADDR_TREBLE] != val1;
- bytes[0] = TEA6330T_SADDR_TREBLE;
- bytes[1] = tea->regs[TEA6330T_SADDR_TREBLE] = val1;
- if ((err = snd_i2c_sendbytes(tea->device, bytes, 2)) < 0)
- change = err;
- snd_i2c_unlock(tea->bus);
- return change;
-}
-
-static struct snd_kcontrol_new snd_tea6330t_controls[] = {
-TEA6330T_MASTER_SWITCH("Master Playback Switch", 0),
-TEA6330T_MASTER_VOLUME("Master Playback Volume", 0),
-TEA6330T_BASS("Tone Control - Bass", 0),
-TEA6330T_TREBLE("Tone Control - Treble", 0)
-};
-
-static void snd_tea6330_free(struct snd_i2c_device *device)
-{
- kfree(device->private_data);
-}
-
-int snd_tea6330t_update_mixer(struct snd_card *card,
- struct snd_i2c_bus *bus,
- int equalizer, int fader)
-{
- struct snd_i2c_device *device;
- struct tea6330t *tea;
- struct snd_kcontrol_new *knew;
- unsigned int idx;
- int err = -ENOMEM;
- u8 default_treble, default_bass;
- unsigned char bytes[7];
-
- tea = kzalloc(sizeof(*tea), GFP_KERNEL);
- if (tea == NULL)
- return -ENOMEM;
- if ((err = snd_i2c_device_create(bus, "TEA6330T", TEA6330T_ADDR, &device)) < 0) {
- kfree(tea);
- return err;
- }
- tea->device = device;
- tea->bus = bus;
- tea->equalizer = equalizer;
- tea->fader = fader;
- device->private_data = tea;
- device->private_free = snd_tea6330_free;
-
- snd_i2c_lock(bus);
-
- /* turn fader off and handle equalizer */
- tea->regs[TEA6330T_SADDR_FADER] = 0x3f;
- tea->regs[TEA6330T_SADDR_AUDIO_SWITCH] = equalizer ? 0 : TEA6330T_EQN;
- /* initialize mixer */
- if (!tea->equalizer) {
- tea->max_bass = 9;
- tea->max_treble = 8;
- default_bass = 3 + 4;
- tea->bass = 4;
- default_treble = 3 + 4;
- tea->treble = 4;
- } else {
- tea->max_bass = 5;
- tea->max_treble = 0;
- default_bass = 7 + 4;
- tea->bass = 4;
- default_treble = 3;
- tea->treble = 0;
- }
- tea->mleft = tea->mright = 0x14;
- tea->regs[TEA6330T_SADDR_BASS] = default_bass;
- tea->regs[TEA6330T_SADDR_TREBLE] = default_treble;
-
- /* compose I2C message and put the hardware to initial state */
- bytes[0] = TEA6330T_SADDR_VOLUME_LEFT;
- for (idx = 0; idx < 6; idx++)
- bytes[idx+1] = tea->regs[idx];
- if ((err = snd_i2c_sendbytes(device, bytes, 7)) < 0)
- goto __error;
-
- strcat(card->mixername, ",TEA6330T");
- if ((err = snd_component_add(card, "TEA6330T")) < 0)
- goto __error;
-
- for (idx = 0; idx < ARRAY_SIZE(snd_tea6330t_controls); idx++) {
- knew = &snd_tea6330t_controls[idx];
- if (tea->treble == 0 && !strcmp(knew->name, "Tone Control - Treble"))
- continue;
- if ((err = snd_ctl_add(card, snd_ctl_new1(knew, tea))) < 0)
- goto __error;
- }
-
- snd_i2c_unlock(bus);
- return 0;
-
- __error:
- snd_i2c_unlock(bus);
- snd_i2c_device_free(device);
- return err;
-}
-
-EXPORT_SYMBOL(snd_tea6330t_detect);
-EXPORT_SYMBOL(snd_tea6330t_update_mixer);
-
-/*
- * INIT part
- */
-
-static int __init alsa_tea6330t_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_tea6330t_exit(void)
-{
-}
-
-module_init(alsa_tea6330t_init)
-module_exit(alsa_tea6330t_exit)
diff --git a/ANDROID_3.4.5/sound/isa/Kconfig b/ANDROID_3.4.5/sound/isa/Kconfig
deleted file mode 100644
index 52064cfa..00000000
--- a/ANDROID_3.4.5/sound/isa/Kconfig
+++ /dev/null
@@ -1,446 +0,0 @@
-# ALSA ISA drivers
-
-config SND_WSS_LIB
- tristate
- select SND_PCM
-
-config SND_SB_COMMON
- tristate
-
-config SND_SB8_DSP
- tristate
- select SND_PCM
- select SND_SB_COMMON
-
-config SND_SB16_DSP
- tristate
- select SND_PCM
- select SND_SB_COMMON
-
-menuconfig SND_ISA
- bool "ISA sound devices"
- depends on ISA && ISA_DMA_API
- default y
- help
- Support for sound devices connected via the ISA bus.
-
-if SND_ISA
-
-config SND_ADLIB
- tristate "AdLib FM card"
- select SND_OPL3_LIB
- help
- Say Y here to include support for AdLib FM cards.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-adlib.
-
-config SND_AD1816A
- tristate "Analog Devices SoundPort AD1816A"
- depends on PNP
- select ISAPNP
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_PCM
- help
- Say Y here to include support for Analog Devices SoundPort
- AD1816A or compatible sound chips.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-ad1816a.
-
-config SND_AD1848
- tristate "Generic AD1848/CS4248 driver"
- select SND_WSS_LIB
- help
- Say Y here to include support for AD1848 (Analog Devices) or
- CS4248 (Cirrus Logic - Crystal Semiconductors) chips.
-
- For newer chips from Cirrus Logic, use the CS4231 or CS4232+
- drivers.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-ad1848.
-
-config SND_ALS100
- tristate "Diamond Tech. DT-019x and Avance Logic ALSxxx"
- depends on PNP
- select ISAPNP
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_SB16_DSP
- help
- Say Y here to include support for soundcards based on the
- Diamond Technologies DT-019X or Avance Logic chips: ALS007,
- ALS100, ALS110, ALS120 and ALS200 chips.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-als100.
-
-config SND_AZT1605
- tristate "Aztech AZT1605 Driver"
- depends on SND
- select SND_WSS_LIB
- select SND_MPU401_UART
- select SND_OPL3_LIB
- help
- Say Y here to include support for Aztech Sound Galaxy cards
- based on the AZT1605 chipset.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-azt1605.
-
-config SND_AZT2316
- tristate "Aztech AZT2316 Driver"
- depends on SND
- select SND_WSS_LIB
- select SND_MPU401_UART
- select SND_OPL3_LIB
- help
- Say Y here to include support for Aztech Sound Galaxy cards
- based on the AZT2316 chipset.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-azt2316.
-
-config SND_AZT2320
- tristate "Aztech Systems AZT2320"
- depends on PNP
- select ISAPNP
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_WSS_LIB
- help
- Say Y here to include support for soundcards based on the
- Aztech Systems AZT2320 chip.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-azt2320.
-
-config SND_CMI8330
- tristate "C-Media CMI8330"
- select SND_WSS_LIB
- select SND_SB16_DSP
- select SND_OPL3_LIB
- select SND_MPU401_UART
- help
- Say Y here to include support for soundcards based on the
- C-Media CMI8330 chip.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-cmi8330.
-
-config SND_CS4231
- tristate "Generic Cirrus Logic CS4231 driver"
- select SND_MPU401_UART
- select SND_WSS_LIB
- help
- Say Y here to include support for CS4231 chips from Cirrus
- Logic - Crystal Semiconductors.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-cs4231.
-
-config SND_CS4236
- tristate "Generic Cirrus Logic CS4232/CS4236+ driver"
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_WSS_LIB
- help
- Say Y to include support for CS4232,CS4235,CS4236,CS4237B,
- CS4238B,CS4239 chips from Cirrus Logic - Crystal
- Semiconductors.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-cs4236.
-
-config SND_ES1688
- tristate "Generic ESS ES688/ES1688 and ES968 PnP driver"
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_PCM
- help
- Say Y here to include support for ESS AudioDrive ES688 or
- ES1688 chips. Also, this module support cards with ES968 PnP chip.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-es1688.
-
-config SND_ES18XX
- tristate "Generic ESS ES18xx driver"
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_PCM
- help
- Say Y here to include support for ESS AudioDrive ES18xx chips.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-es18xx.
-
-config SND_SC6000
- tristate "Gallant SC-6000/6600/7000 and Audio Excel DSP 16"
- depends on HAS_IOPORT
- select SND_WSS_LIB
- select SND_OPL3_LIB
- select SND_MPU401_UART
- help
- Say Y here to include support for Gallant SC-6000, SC-6600, SC-7000
- cards and clones:
- Audio Excel DSP 16 and Zoltrix AV302.
-
- These cards are based on CompuMedia ASC-9308 or ASC-9408 chips.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-sc6000.
-
-config SND_GUSCLASSIC
- tristate "Gravis UltraSound Classic"
- select SND_RAWMIDI
- select SND_PCM
- help
- Say Y here to include support for Gravis UltraSound Classic
- soundcards.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-gusclassic.
-
-config SND_GUSEXTREME
- tristate "Gravis UltraSound Extreme"
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_PCM
- help
- Say Y here to include support for Gravis UltraSound Extreme
- soundcards.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-gusextreme.
-
-config SND_GUSMAX
- tristate "Gravis UltraSound MAX"
- select SND_RAWMIDI
- select SND_WSS_LIB
- help
- Say Y here to include support for Gravis UltraSound MAX
- soundcards.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-gusmax.
-
-config SND_INTERWAVE
- tristate "AMD InterWave, Gravis UltraSound PnP"
- depends on PNP
- select SND_RAWMIDI
- select SND_WSS_LIB
- help
- Say Y here to include support for AMD InterWave based
- soundcards (Gravis UltraSound Plug & Play, STB SoundRage32,
- MED3210, Dynasonic Pro, Panasonic PCA761AW).
-
- To compile this driver as a module, choose M here: the module
- will be called snd-interwave.
-
-config SND_INTERWAVE_STB
- tristate "AMD InterWave + TEA6330T (UltraSound 32-Pro)"
- depends on PNP
- select SND_RAWMIDI
- select SND_WSS_LIB
- help
- Say Y here to include support for AMD InterWave based
- soundcards with a TEA6330T bass and treble regulator
- (UltraSound 32-Pro).
-
- To compile this driver as a module, choose M here: the module
- will be called snd-interwave-stb.
-
-config SND_JAZZ16
- tristate "Media Vision Jazz16 card and compatibles"
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_SB8_DSP
- help
- Say Y here to include support for soundcards based on the
- Media Vision Jazz16 chipset: digital chip MVD1216 (Jazz16),
- codec MVA416 (CS4216) and mixer MVA514 (ICS2514).
- Media Vision's Jazz16 cards were sold under names Pro Sonic 16,
- Premium 3-D and Pro 3-D. There were also OEMs cards with the
- Jazz16 chipset.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-jazz16.
-
-config SND_OPL3SA2
- tristate "Yamaha OPL3-SA2/SA3"
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_WSS_LIB
- help
- Say Y here to include support for Yamaha OPL3-SA2 and OPL3-SA3
- chips.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-opl3sa2.
-
-config SND_OPTI92X_AD1848
- tristate "OPTi 82C92x - AD1848"
- select SND_OPL3_LIB
- select SND_OPL4_LIB
- select SND_MPU401_UART
- select SND_WSS_LIB
- help
- Say Y here to include support for soundcards based on Opti
- 82C92x or OTI-601 chips and using an AD1848 codec.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-opti92x-ad1848.
-
-config SND_OPTI92X_CS4231
- tristate "OPTi 82C92x - CS4231"
- select SND_OPL3_LIB
- select SND_OPL4_LIB
- select SND_MPU401_UART
- select SND_WSS_LIB
- help
- Say Y here to include support for soundcards based on Opti
- 82C92x chips and using a CS4231 codec.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-opti92x-cs4231.
-
-config SND_OPTI93X
- tristate "OPTi 82C93x"
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_WSS_LIB
- help
- Say Y here to include support for soundcards based on Opti
- 82C93x chips.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-opti93x.
-
-config SND_MIRO
- tristate "Miro miroSOUND PCM1pro/PCM12/PCM20radio driver"
- select SND_OPL4_LIB
- select SND_WSS_LIB
- select SND_MPU401_UART
- select SND_PCM
- help
- Say 'Y' or 'M' to include support for Miro miroSOUND PCM1 pro,
- miroSOUND PCM12 and miroSOUND PCM20 Radio soundcards.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-miro.
-
-config SND_SB8
- tristate "Sound Blaster 1.0/2.0/Pro (8-bit)"
- select SND_OPL3_LIB
- select SND_RAWMIDI
- select SND_SB8_DSP
- help
- Say Y here to include support for Creative Sound Blaster 1.0/
- 2.0/Pro (8-bit) or 100% compatible soundcards.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-sb8.
-
-config SND_SB16
- tristate "Sound Blaster 16 (PnP)"
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_SB16_DSP
- help
- Say Y here to include support for Sound Blaster 16 soundcards
- (including the Plug and Play version).
-
- To compile this driver as a module, choose M here: the module
- will be called snd-sb16.
-
-config SND_SBAWE
- tristate "Sound Blaster AWE (32,64) (PnP)"
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_SB16_DSP
- help
- Say Y here to include support for Sound Blaster AWE soundcards
- (including the Plug and Play version).
-
- To compile this driver as a module, choose M here: the module
- will be called snd-sbawe.
-
-config SND_SB16_CSP
- bool "Sound Blaster 16/AWE CSP support"
- depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC)
- select FW_LOADER
- help
- Say Y here to include support for the CSP core. This special
- coprocessor can do variable tasks like various compression and
- decompression algorithms.
-
-config SND_SSCAPE
- tristate "Ensoniq SoundScape driver"
- select SND_MPU401_UART
- select SND_WSS_LIB
- select FW_LOADER
- help
- Say Y here to include support for Ensoniq SoundScape
- and Ensoniq OEM soundcards.
-
- The PCM audio is supported on SoundScape Classic, Elite, PnP
- and VIVO cards. The supported OEM cards are SPEA Media FX and
- Reveal SC-600.
- The MIDI support is very experimental and requires binary
- firmware files called "scope.cod" and "sndscape.co?" where the
- ? is digit 0, 1, 2, 3 or 4. The firmware files can be found
- in DOS or Windows driver packages. One has to put the firmware
- files into the /lib/firmware directory.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-sscape.
-
-config SND_WAVEFRONT
- tristate "Turtle Beach Maui,Tropez,Tropez+ (Wavefront)"
- select FW_LOADER
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_WSS_LIB
- help
- Say Y here to include support for Turtle Beach Maui, Tropez
- and Tropez+ soundcards based on the Wavefront chip.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-wavefront.
-
-config SND_MSND_PINNACLE
- tristate "Turtle Beach MultiSound Pinnacle/Fiji driver"
- depends on X86 && EXPERIMENTAL
- select FW_LOADER
- select SND_MPU401_UART
- select SND_PCM
- help
- Say Y to include support for Turtle Beach MultiSound Pinnacle/
- Fiji soundcards.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-msnd-pinnacle.
-
-config SND_MSND_CLASSIC
- tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey"
- depends on X86 && EXPERIMENTAL
- select FW_LOADER
- select SND_MPU401_UART
- select SND_PCM
- help
- Say M here if you have a Turtle Beach MultiSound Classic, Tahiti or
- Monterey (not for the Pinnacle or Fiji).
-
- See <file:Documentation/sound/oss/MultiSound> for important information
- about this driver. Note that it has been discontinued, but the
- Voyetra Turtle Beach knowledge base entry for it is still available
- at <http://www.turtlebeach.com/site/kb_ftp/790.asp>.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-msnd-classic.
-
-endif # SND_ISA
-
diff --git a/ANDROID_3.4.5/sound/isa/Makefile b/ANDROID_3.4.5/sound/isa/Makefile
deleted file mode 100644
index 8d781e41..00000000
--- a/ANDROID_3.4.5/sound/isa/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-adlib-objs := adlib.o
-snd-als100-objs := als100.o
-snd-azt2320-objs := azt2320.o
-snd-cmi8330-objs := cmi8330.o
-snd-es18xx-objs := es18xx.o
-snd-opl3sa2-objs := opl3sa2.o
-snd-sc6000-objs := sc6000.o
-snd-sscape-objs := sscape.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_ADLIB) += snd-adlib.o
-obj-$(CONFIG_SND_ALS100) += snd-als100.o
-obj-$(CONFIG_SND_AZT2320) += snd-azt2320.o
-obj-$(CONFIG_SND_CMI8330) += snd-cmi8330.o
-obj-$(CONFIG_SND_ES18XX) += snd-es18xx.o
-obj-$(CONFIG_SND_OPL3SA2) += snd-opl3sa2.o
-obj-$(CONFIG_SND_SC6000) += snd-sc6000.o
-obj-$(CONFIG_SND_SSCAPE) += snd-sscape.o
-
-obj-$(CONFIG_SND) += ad1816a/ ad1848/ cs423x/ es1688/ galaxy/ gus/ msnd/ opti9xx/ \
- sb/ wavefront/ wss/
diff --git a/ANDROID_3.4.5/sound/isa/ad1816a/Makefile b/ANDROID_3.4.5/sound/isa/ad1816a/Makefile
deleted file mode 100644
index 487ab238..00000000
--- a/ANDROID_3.4.5/sound/isa/ad1816a/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-ad1816a-objs := ad1816a.o ad1816a_lib.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_AD1816A) += snd-ad1816a.o
diff --git a/ANDROID_3.4.5/sound/isa/ad1816a/ad1816a.c b/ANDROID_3.4.5/sound/isa/ad1816a/ad1816a.c
deleted file mode 100644
index 94b83b6e..00000000
--- a/ANDROID_3.4.5/sound/isa/ad1816a/ad1816a.c
+++ /dev/null
@@ -1,294 +0,0 @@
-
-/*
- card-ad1816a.c - driver for ADI SoundPort AD1816A based soundcards.
- Copyright (C) 2000 by Massimo Piccioni <dafastidio@libero.it>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/pnp.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/ad1816a.h>
-#include <sound/mpu401.h>
-#include <sound/opl3.h>
-
-#define PFX "ad1816a: "
-
-MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
-MODULE_DESCRIPTION("AD1816A, AD1815");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Highscreen,Sound-Boostar 16 3D},"
- "{Analog Devices,AD1815},"
- "{Analog Devices,AD1816A},"
- "{TerraTec,Base 64},"
- "{TerraTec,AudioSystem EWS64S},"
- "{Aztech/Newcom SC-16 3D},"
- "{Shark Predator ISA}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 1-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* Pnp setup */
-static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* Pnp setup */
-static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
-static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
-static int clockfreq[SNDRV_CARDS];
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for ad1816a based soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for ad1816a based soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable ad1816a based soundcard.");
-module_param_array(clockfreq, int, NULL, 0444);
-MODULE_PARM_DESC(clockfreq, "Clock frequency for ad1816a driver (default = 0).");
-
-struct snd_card_ad1816a {
- struct pnp_dev *dev;
- struct pnp_dev *devmpu;
-};
-
-static struct pnp_card_device_id snd_ad1816a_pnpids[] = {
- /* Analog Devices AD1815 */
- { .id = "ADS7150", .devs = { { .id = "ADS7150" }, { .id = "ADS7151" } } },
- /* Analog Device AD1816? */
- { .id = "ADS7180", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } },
- /* Analog Devices AD1816A - added by Kenneth Platz <kxp@atl.hp.com> */
- { .id = "ADS7181", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } },
- /* Analog Devices AD1816A - Aztech/Newcom SC-16 3D */
- { .id = "AZT1022", .devs = { { .id = "AZT1018" }, { .id = "AZT2002" } } },
- /* Highscreen Sound-Boostar 16 3D - added by Stefan Behnel */
- { .id = "LWC1061", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } },
- /* Highscreen Sound-Boostar 16 3D */
- { .id = "MDK1605", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } },
- /* Shark Predator ISA - added by Ken Arromdee */
- { .id = "SMM7180", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } },
- /* Analog Devices AD1816A - Terratec AudioSystem EWS64 S */
- { .id = "TER1112", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } },
- /* Analog Devices AD1816A - Terratec AudioSystem EWS64 S */
- { .id = "TER1112", .devs = { { .id = "TER1100" }, { .id = "TER1101" } } },
- /* Analog Devices AD1816A - Terratec Base 64 */
- { .id = "TER1411", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } },
- /* end */
- { .id = "" }
-};
-
-MODULE_DEVICE_TABLE(pnp_card, snd_ad1816a_pnpids);
-
-
-#define DRIVER_NAME "snd-card-ad1816a"
-
-
-static int __devinit snd_card_ad1816a_pnp(int dev, struct snd_card_ad1816a *acard,
- struct pnp_card_link *card,
- const struct pnp_card_device_id *id)
-{
- struct pnp_dev *pdev;
- int err;
-
- acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
- if (acard->dev == NULL)
- return -EBUSY;
-
- acard->devmpu = pnp_request_card_device(card, id->devs[1].id, NULL);
- if (acard->devmpu == NULL) {
- mpu_port[dev] = -1;
- snd_printk(KERN_WARNING PFX "MPU401 device busy, skipping.\n");
- }
-
- pdev = acard->dev;
-
- err = pnp_activate_dev(pdev);
- if (err < 0) {
- printk(KERN_ERR PFX "AUDIO PnP configure failure\n");
- return -EBUSY;
- }
-
- port[dev] = pnp_port_start(pdev, 2);
- fm_port[dev] = pnp_port_start(pdev, 1);
- dma1[dev] = pnp_dma(pdev, 0);
- dma2[dev] = pnp_dma(pdev, 1);
- irq[dev] = pnp_irq(pdev, 0);
-
- if (acard->devmpu == NULL)
- return 0;
-
- pdev = acard->devmpu;
-
- err = pnp_activate_dev(pdev);
- if (err < 0) {
- printk(KERN_ERR PFX "MPU401 PnP configure failure\n");
- mpu_port[dev] = -1;
- acard->devmpu = NULL;
- } else {
- mpu_port[dev] = pnp_port_start(pdev, 0);
- mpu_irq[dev] = pnp_irq(pdev, 0);
- }
-
- return 0;
-}
-
-static int __devinit snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard,
- const struct pnp_card_device_id *pid)
-{
- int error;
- struct snd_card *card;
- struct snd_card_ad1816a *acard;
- struct snd_ad1816a *chip;
- struct snd_opl3 *opl3;
- struct snd_timer *timer;
-
- error = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_card_ad1816a), &card);
- if (error < 0)
- return error;
- acard = card->private_data;
-
- if ((error = snd_card_ad1816a_pnp(dev, acard, pcard, pid))) {
- snd_card_free(card);
- return error;
- }
- snd_card_set_dev(card, &pcard->card->dev);
-
- if ((error = snd_ad1816a_create(card, port[dev],
- irq[dev],
- dma1[dev],
- dma2[dev],
- &chip)) < 0) {
- snd_card_free(card);
- return error;
- }
- if (clockfreq[dev] >= 5000 && clockfreq[dev] <= 100000)
- chip->clock_freq = clockfreq[dev];
-
- strcpy(card->driver, "AD1816A");
- strcpy(card->shortname, "ADI SoundPort AD1816A");
- sprintf(card->longname, "%s, SS at 0x%lx, irq %d, dma %d&%d",
- card->shortname, chip->port, irq[dev], dma1[dev], dma2[dev]);
-
- if ((error = snd_ad1816a_pcm(chip, 0, NULL)) < 0) {
- snd_card_free(card);
- return error;
- }
-
- if ((error = snd_ad1816a_mixer(chip)) < 0) {
- snd_card_free(card);
- return error;
- }
-
- error = snd_ad1816a_timer(chip, 0, &timer);
- if (error < 0) {
- snd_card_free(card);
- return error;
- }
-
- if (mpu_port[dev] > 0) {
- if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
- mpu_port[dev], 0, mpu_irq[dev],
- NULL) < 0)
- printk(KERN_ERR PFX "no MPU-401 device at 0x%lx.\n", mpu_port[dev]);
- }
-
- if (fm_port[dev] > 0) {
- if (snd_opl3_create(card,
- fm_port[dev], fm_port[dev] + 2,
- OPL3_HW_AUTO, 0, &opl3) < 0) {
- printk(KERN_ERR PFX "no OPL device at 0x%lx-0x%lx.\n", fm_port[dev], fm_port[dev] + 2);
- } else {
- error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
- if (error < 0) {
- snd_card_free(card);
- return error;
- }
- }
- }
-
- if ((error = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return error;
- }
- pnp_set_card_drvdata(pcard, card);
- return 0;
-}
-
-static unsigned int __devinitdata ad1816a_devices;
-
-static int __devinit snd_ad1816a_pnp_detect(struct pnp_card_link *card,
- const struct pnp_card_device_id *id)
-{
- static int dev;
- int res;
-
- for ( ; dev < SNDRV_CARDS; dev++) {
- if (!enable[dev])
- continue;
- res = snd_card_ad1816a_probe(dev, card, id);
- if (res < 0)
- return res;
- dev++;
- ad1816a_devices++;
- return 0;
- }
- return -ENODEV;
-}
-
-static void __devexit snd_ad1816a_pnp_remove(struct pnp_card_link * pcard)
-{
- snd_card_free(pnp_get_card_drvdata(pcard));
- pnp_set_card_drvdata(pcard, NULL);
-}
-
-static struct pnp_card_driver ad1816a_pnpc_driver = {
- .flags = PNP_DRIVER_RES_DISABLE,
- .name = "ad1816a",
- .id_table = snd_ad1816a_pnpids,
- .probe = snd_ad1816a_pnp_detect,
- .remove = __devexit_p(snd_ad1816a_pnp_remove),
- /* FIXME: suspend/resume */
-};
-
-static int __init alsa_card_ad1816a_init(void)
-{
- int err;
-
- err = pnp_register_card_driver(&ad1816a_pnpc_driver);
- if (err)
- return err;
-
- if (!ad1816a_devices) {
- pnp_unregister_card_driver(&ad1816a_pnpc_driver);
-#ifdef MODULE
- printk(KERN_ERR "no AD1816A based soundcards found.\n");
-#endif /* MODULE */
- return -ENODEV;
- }
- return 0;
-}
-
-static void __exit alsa_card_ad1816a_exit(void)
-{
- pnp_unregister_card_driver(&ad1816a_pnpc_driver);
-}
-
-module_init(alsa_card_ad1816a_init)
-module_exit(alsa_card_ad1816a_exit)
diff --git a/ANDROID_3.4.5/sound/isa/ad1816a/ad1816a_lib.c b/ANDROID_3.4.5/sound/isa/ad1816a/ad1816a_lib.c
deleted file mode 100644
index 177eed32..00000000
--- a/ANDROID_3.4.5/sound/isa/ad1816a/ad1816a_lib.c
+++ /dev/null
@@ -1,972 +0,0 @@
-/*
- ad1816a.c - lowlevel code for Analog Devices AD1816A chip.
- Copyright (C) 1999-2000 by Massimo Piccioni <dafastidio@libero.it>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <sound/core.h>
-#include <sound/tlv.h>
-#include <sound/ad1816a.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-
-static inline int snd_ad1816a_busy_wait(struct snd_ad1816a *chip)
-{
- int timeout;
-
- for (timeout = 1000; timeout-- > 0; udelay(10))
- if (inb(AD1816A_REG(AD1816A_CHIP_STATUS)) & AD1816A_READY)
- return 0;
-
- snd_printk(KERN_WARNING "chip busy.\n");
- return -EBUSY;
-}
-
-static inline unsigned char snd_ad1816a_in(struct snd_ad1816a *chip, unsigned char reg)
-{
- snd_ad1816a_busy_wait(chip);
- return inb(AD1816A_REG(reg));
-}
-
-static inline void snd_ad1816a_out(struct snd_ad1816a *chip, unsigned char reg,
- unsigned char value)
-{
- snd_ad1816a_busy_wait(chip);
- outb(value, AD1816A_REG(reg));
-}
-
-static inline void snd_ad1816a_out_mask(struct snd_ad1816a *chip, unsigned char reg,
- unsigned char mask, unsigned char value)
-{
- snd_ad1816a_out(chip, reg,
- (value & mask) | (snd_ad1816a_in(chip, reg) & ~mask));
-}
-
-static unsigned short snd_ad1816a_read(struct snd_ad1816a *chip, unsigned char reg)
-{
- snd_ad1816a_out(chip, AD1816A_INDIR_ADDR, reg & 0x3f);
- return snd_ad1816a_in(chip, AD1816A_INDIR_DATA_LOW) |
- (snd_ad1816a_in(chip, AD1816A_INDIR_DATA_HIGH) << 8);
-}
-
-static void snd_ad1816a_write(struct snd_ad1816a *chip, unsigned char reg,
- unsigned short value)
-{
- snd_ad1816a_out(chip, AD1816A_INDIR_ADDR, reg & 0x3f);
- snd_ad1816a_out(chip, AD1816A_INDIR_DATA_LOW, value & 0xff);
- snd_ad1816a_out(chip, AD1816A_INDIR_DATA_HIGH, (value >> 8) & 0xff);
-}
-
-static void snd_ad1816a_write_mask(struct snd_ad1816a *chip, unsigned char reg,
- unsigned short mask, unsigned short value)
-{
- snd_ad1816a_write(chip, reg,
- (value & mask) | (snd_ad1816a_read(chip, reg) & ~mask));
-}
-
-
-static unsigned char snd_ad1816a_get_format(struct snd_ad1816a *chip,
- unsigned int format, int channels)
-{
- unsigned char retval = AD1816A_FMT_LINEAR_8;
-
- switch (format) {
- case SNDRV_PCM_FORMAT_MU_LAW:
- retval = AD1816A_FMT_ULAW_8;
- break;
- case SNDRV_PCM_FORMAT_A_LAW:
- retval = AD1816A_FMT_ALAW_8;
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- retval = AD1816A_FMT_LINEAR_16_LIT;
- break;
- case SNDRV_PCM_FORMAT_S16_BE:
- retval = AD1816A_FMT_LINEAR_16_BIG;
- }
- return (channels > 1) ? (retval | AD1816A_FMT_STEREO) : retval;
-}
-
-static int snd_ad1816a_open(struct snd_ad1816a *chip, unsigned int mode)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&chip->lock, flags);
-
- if (chip->mode & mode) {
- spin_unlock_irqrestore(&chip->lock, flags);
- return -EAGAIN;
- }
-
- switch ((mode &= AD1816A_MODE_OPEN)) {
- case AD1816A_MODE_PLAYBACK:
- snd_ad1816a_out_mask(chip, AD1816A_INTERRUPT_STATUS,
- AD1816A_PLAYBACK_IRQ_PENDING, 0x00);
- snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,
- AD1816A_PLAYBACK_IRQ_ENABLE, 0xffff);
- break;
- case AD1816A_MODE_CAPTURE:
- snd_ad1816a_out_mask(chip, AD1816A_INTERRUPT_STATUS,
- AD1816A_CAPTURE_IRQ_PENDING, 0x00);
- snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,
- AD1816A_CAPTURE_IRQ_ENABLE, 0xffff);
- break;
- case AD1816A_MODE_TIMER:
- snd_ad1816a_out_mask(chip, AD1816A_INTERRUPT_STATUS,
- AD1816A_TIMER_IRQ_PENDING, 0x00);
- snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,
- AD1816A_TIMER_IRQ_ENABLE, 0xffff);
- }
- chip->mode |= mode;
-
- spin_unlock_irqrestore(&chip->lock, flags);
- return 0;
-}
-
-static void snd_ad1816a_close(struct snd_ad1816a *chip, unsigned int mode)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&chip->lock, flags);
-
- switch ((mode &= AD1816A_MODE_OPEN)) {
- case AD1816A_MODE_PLAYBACK:
- snd_ad1816a_out_mask(chip, AD1816A_INTERRUPT_STATUS,
- AD1816A_PLAYBACK_IRQ_PENDING, 0x00);
- snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,
- AD1816A_PLAYBACK_IRQ_ENABLE, 0x0000);
- break;
- case AD1816A_MODE_CAPTURE:
- snd_ad1816a_out_mask(chip, AD1816A_INTERRUPT_STATUS,
- AD1816A_CAPTURE_IRQ_PENDING, 0x00);
- snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,
- AD1816A_CAPTURE_IRQ_ENABLE, 0x0000);
- break;
- case AD1816A_MODE_TIMER:
- snd_ad1816a_out_mask(chip, AD1816A_INTERRUPT_STATUS,
- AD1816A_TIMER_IRQ_PENDING, 0x00);
- snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,
- AD1816A_TIMER_IRQ_ENABLE, 0x0000);
- }
- if (!((chip->mode &= ~mode) & AD1816A_MODE_OPEN))
- chip->mode = 0;
-
- spin_unlock_irqrestore(&chip->lock, flags);
-}
-
-
-static int snd_ad1816a_trigger(struct snd_ad1816a *chip, unsigned char what,
- int channel, int cmd, int iscapture)
-{
- int error = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_STOP:
- spin_lock(&chip->lock);
- cmd = (cmd == SNDRV_PCM_TRIGGER_START) ? 0xff: 0x00;
- /* if (what & AD1816A_PLAYBACK_ENABLE) */
- /* That is not valid, because playback and capture enable
- * are the same bit pattern, just to different addresses
- */
- if (! iscapture)
- snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG,
- AD1816A_PLAYBACK_ENABLE, cmd);
- else
- snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG,
- AD1816A_CAPTURE_ENABLE, cmd);
- spin_unlock(&chip->lock);
- break;
- default:
- snd_printk(KERN_WARNING "invalid trigger mode 0x%x.\n", what);
- error = -EINVAL;
- }
-
- return error;
-}
-
-static int snd_ad1816a_playback_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
- return snd_ad1816a_trigger(chip, AD1816A_PLAYBACK_ENABLE,
- SNDRV_PCM_STREAM_PLAYBACK, cmd, 0);
-}
-
-static int snd_ad1816a_capture_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
- return snd_ad1816a_trigger(chip, AD1816A_CAPTURE_ENABLE,
- SNDRV_PCM_STREAM_CAPTURE, cmd, 1);
-}
-
-static int snd_ad1816a_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static int snd_ad1816a_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_ad1816a_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
- unsigned long flags;
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int size, rate;
-
- spin_lock_irqsave(&chip->lock, flags);
-
- chip->p_dma_size = size = snd_pcm_lib_buffer_bytes(substream);
- snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG,
- AD1816A_PLAYBACK_ENABLE | AD1816A_PLAYBACK_PIO, 0x00);
-
- snd_dma_program(chip->dma1, runtime->dma_addr, size,
- DMA_MODE_WRITE | DMA_AUTOINIT);
-
- rate = runtime->rate;
- if (chip->clock_freq)
- rate = (rate * 33000) / chip->clock_freq;
- snd_ad1816a_write(chip, AD1816A_PLAYBACK_SAMPLE_RATE, rate);
- snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG,
- AD1816A_FMT_ALL | AD1816A_FMT_STEREO,
- snd_ad1816a_get_format(chip, runtime->format,
- runtime->channels));
-
- snd_ad1816a_write(chip, AD1816A_PLAYBACK_BASE_COUNT,
- snd_pcm_lib_period_bytes(substream) / 4 - 1);
-
- spin_unlock_irqrestore(&chip->lock, flags);
- return 0;
-}
-
-static int snd_ad1816a_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
- unsigned long flags;
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int size, rate;
-
- spin_lock_irqsave(&chip->lock, flags);
-
- chip->c_dma_size = size = snd_pcm_lib_buffer_bytes(substream);
- snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG,
- AD1816A_CAPTURE_ENABLE | AD1816A_CAPTURE_PIO, 0x00);
-
- snd_dma_program(chip->dma2, runtime->dma_addr, size,
- DMA_MODE_READ | DMA_AUTOINIT);
-
- rate = runtime->rate;
- if (chip->clock_freq)
- rate = (rate * 33000) / chip->clock_freq;
- snd_ad1816a_write(chip, AD1816A_CAPTURE_SAMPLE_RATE, rate);
- snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG,
- AD1816A_FMT_ALL | AD1816A_FMT_STEREO,
- snd_ad1816a_get_format(chip, runtime->format,
- runtime->channels));
-
- snd_ad1816a_write(chip, AD1816A_CAPTURE_BASE_COUNT,
- snd_pcm_lib_period_bytes(substream) / 4 - 1);
-
- spin_unlock_irqrestore(&chip->lock, flags);
- return 0;
-}
-
-
-static snd_pcm_uframes_t snd_ad1816a_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
- size_t ptr;
- if (!(chip->mode & AD1816A_MODE_PLAYBACK))
- return 0;
- ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size);
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-static snd_pcm_uframes_t snd_ad1816a_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
- size_t ptr;
- if (!(chip->mode & AD1816A_MODE_CAPTURE))
- return 0;
- ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size);
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-
-static irqreturn_t snd_ad1816a_interrupt(int irq, void *dev_id)
-{
- struct snd_ad1816a *chip = dev_id;
- unsigned char status;
-
- spin_lock(&chip->lock);
- status = snd_ad1816a_in(chip, AD1816A_INTERRUPT_STATUS);
- spin_unlock(&chip->lock);
-
- if ((status & AD1816A_PLAYBACK_IRQ_PENDING) && chip->playback_substream)
- snd_pcm_period_elapsed(chip->playback_substream);
-
- if ((status & AD1816A_CAPTURE_IRQ_PENDING) && chip->capture_substream)
- snd_pcm_period_elapsed(chip->capture_substream);
-
- if ((status & AD1816A_TIMER_IRQ_PENDING) && chip->timer)
- snd_timer_interrupt(chip->timer, chip->timer->sticks);
-
- spin_lock(&chip->lock);
- snd_ad1816a_out(chip, AD1816A_INTERRUPT_STATUS, 0x00);
- spin_unlock(&chip->lock);
- return IRQ_HANDLED;
-}
-
-
-static struct snd_pcm_hardware snd_ad1816a_playback = {
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
- SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S16_BE),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 55200,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_ad1816a_capture = {
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
- SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S16_BE),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 55200,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static int snd_ad1816a_timer_close(struct snd_timer *timer)
-{
- struct snd_ad1816a *chip = snd_timer_chip(timer);
- snd_ad1816a_close(chip, AD1816A_MODE_TIMER);
- return 0;
-}
-
-static int snd_ad1816a_timer_open(struct snd_timer *timer)
-{
- struct snd_ad1816a *chip = snd_timer_chip(timer);
- snd_ad1816a_open(chip, AD1816A_MODE_TIMER);
- return 0;
-}
-
-static unsigned long snd_ad1816a_timer_resolution(struct snd_timer *timer)
-{
- if (snd_BUG_ON(!timer))
- return 0;
-
- return 10000;
-}
-
-static int snd_ad1816a_timer_start(struct snd_timer *timer)
-{
- unsigned short bits;
- unsigned long flags;
- struct snd_ad1816a *chip = snd_timer_chip(timer);
- spin_lock_irqsave(&chip->lock, flags);
- bits = snd_ad1816a_read(chip, AD1816A_INTERRUPT_ENABLE);
-
- if (!(bits & AD1816A_TIMER_ENABLE)) {
- snd_ad1816a_write(chip, AD1816A_TIMER_BASE_COUNT,
- timer->sticks & 0xffff);
-
- snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,
- AD1816A_TIMER_ENABLE, 0xffff);
- }
- spin_unlock_irqrestore(&chip->lock, flags);
- return 0;
-}
-
-static int snd_ad1816a_timer_stop(struct snd_timer *timer)
-{
- unsigned long flags;
- struct snd_ad1816a *chip = snd_timer_chip(timer);
- spin_lock_irqsave(&chip->lock, flags);
-
- snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,
- AD1816A_TIMER_ENABLE, 0x0000);
-
- spin_unlock_irqrestore(&chip->lock, flags);
- return 0;
-}
-
-static struct snd_timer_hardware snd_ad1816a_timer_table = {
- .flags = SNDRV_TIMER_HW_AUTO,
- .resolution = 10000,
- .ticks = 65535,
- .open = snd_ad1816a_timer_open,
- .close = snd_ad1816a_timer_close,
- .c_resolution = snd_ad1816a_timer_resolution,
- .start = snd_ad1816a_timer_start,
- .stop = snd_ad1816a_timer_stop,
-};
-
-static int snd_ad1816a_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int error;
-
- if ((error = snd_ad1816a_open(chip, AD1816A_MODE_PLAYBACK)) < 0)
- return error;
- runtime->hw = snd_ad1816a_playback;
- snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max);
- snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max);
- chip->playback_substream = substream;
- return 0;
-}
-
-static int snd_ad1816a_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int error;
-
- if ((error = snd_ad1816a_open(chip, AD1816A_MODE_CAPTURE)) < 0)
- return error;
- runtime->hw = snd_ad1816a_capture;
- snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max);
- snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max);
- chip->capture_substream = substream;
- return 0;
-}
-
-static int snd_ad1816a_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
-
- chip->playback_substream = NULL;
- snd_ad1816a_close(chip, AD1816A_MODE_PLAYBACK);
- return 0;
-}
-
-static int snd_ad1816a_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
-
- chip->capture_substream = NULL;
- snd_ad1816a_close(chip, AD1816A_MODE_CAPTURE);
- return 0;
-}
-
-
-static void __devinit snd_ad1816a_init(struct snd_ad1816a *chip)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&chip->lock, flags);
-
- snd_ad1816a_out(chip, AD1816A_INTERRUPT_STATUS, 0x00);
- snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG,
- AD1816A_PLAYBACK_ENABLE | AD1816A_PLAYBACK_PIO, 0x00);
- snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG,
- AD1816A_CAPTURE_ENABLE | AD1816A_CAPTURE_PIO, 0x00);
- snd_ad1816a_write(chip, AD1816A_INTERRUPT_ENABLE, 0x0000);
- snd_ad1816a_write_mask(chip, AD1816A_CHIP_CONFIG,
- AD1816A_CAPTURE_NOT_EQUAL | AD1816A_WSS_ENABLE, 0xffff);
- snd_ad1816a_write(chip, AD1816A_DSP_CONFIG, 0x0000);
- snd_ad1816a_write(chip, AD1816A_POWERDOWN_CTRL, 0x0000);
-
- spin_unlock_irqrestore(&chip->lock, flags);
-}
-
-static int __devinit snd_ad1816a_probe(struct snd_ad1816a *chip)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&chip->lock, flags);
-
- switch (chip->version = snd_ad1816a_read(chip, AD1816A_VERSION_ID)) {
- case 0:
- chip->hardware = AD1816A_HW_AD1815;
- break;
- case 1:
- chip->hardware = AD1816A_HW_AD18MAX10;
- break;
- case 3:
- chip->hardware = AD1816A_HW_AD1816A;
- break;
- default:
- chip->hardware = AD1816A_HW_AUTO;
- }
-
- spin_unlock_irqrestore(&chip->lock, flags);
- return 0;
-}
-
-static int snd_ad1816a_free(struct snd_ad1816a *chip)
-{
- release_and_free_resource(chip->res_port);
- if (chip->irq >= 0)
- free_irq(chip->irq, (void *) chip);
- if (chip->dma1 >= 0) {
- snd_dma_disable(chip->dma1);
- free_dma(chip->dma1);
- }
- if (chip->dma2 >= 0) {
- snd_dma_disable(chip->dma2);
- free_dma(chip->dma2);
- }
- kfree(chip);
- return 0;
-}
-
-static int snd_ad1816a_dev_free(struct snd_device *device)
-{
- struct snd_ad1816a *chip = device->device_data;
- return snd_ad1816a_free(chip);
-}
-
-static const char __devinit *snd_ad1816a_chip_id(struct snd_ad1816a *chip)
-{
- switch (chip->hardware) {
- case AD1816A_HW_AD1816A: return "AD1816A";
- case AD1816A_HW_AD1815: return "AD1815";
- case AD1816A_HW_AD18MAX10: return "AD18max10";
- default:
- snd_printk(KERN_WARNING "Unknown chip version %d:%d.\n",
- chip->version, chip->hardware);
- return "AD1816A - unknown";
- }
-}
-
-int __devinit snd_ad1816a_create(struct snd_card *card,
- unsigned long port, int irq, int dma1, int dma2,
- struct snd_ad1816a **rchip)
-{
- static struct snd_device_ops ops = {
- .dev_free = snd_ad1816a_dev_free,
- };
- int error;
- struct snd_ad1816a *chip;
-
- *rchip = NULL;
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL)
- return -ENOMEM;
- chip->irq = -1;
- chip->dma1 = -1;
- chip->dma2 = -1;
-
- if ((chip->res_port = request_region(port, 16, "AD1816A")) == NULL) {
- snd_printk(KERN_ERR "ad1816a: can't grab port 0x%lx\n", port);
- snd_ad1816a_free(chip);
- return -EBUSY;
- }
- if (request_irq(irq, snd_ad1816a_interrupt, 0, "AD1816A", (void *) chip)) {
- snd_printk(KERN_ERR "ad1816a: can't grab IRQ %d\n", irq);
- snd_ad1816a_free(chip);
- return -EBUSY;
- }
- chip->irq = irq;
- if (request_dma(dma1, "AD1816A - 1")) {
- snd_printk(KERN_ERR "ad1816a: can't grab DMA1 %d\n", dma1);
- snd_ad1816a_free(chip);
- return -EBUSY;
- }
- chip->dma1 = dma1;
- if (request_dma(dma2, "AD1816A - 2")) {
- snd_printk(KERN_ERR "ad1816a: can't grab DMA2 %d\n", dma2);
- snd_ad1816a_free(chip);
- return -EBUSY;
- }
- chip->dma2 = dma2;
-
- chip->card = card;
- chip->port = port;
- spin_lock_init(&chip->lock);
-
- if ((error = snd_ad1816a_probe(chip))) {
- snd_ad1816a_free(chip);
- return error;
- }
-
- snd_ad1816a_init(chip);
-
- /* Register device */
- if ((error = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_ad1816a_free(chip);
- return error;
- }
-
- *rchip = chip;
- return 0;
-}
-
-static struct snd_pcm_ops snd_ad1816a_playback_ops = {
- .open = snd_ad1816a_playback_open,
- .close = snd_ad1816a_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ad1816a_hw_params,
- .hw_free = snd_ad1816a_hw_free,
- .prepare = snd_ad1816a_playback_prepare,
- .trigger = snd_ad1816a_playback_trigger,
- .pointer = snd_ad1816a_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_ad1816a_capture_ops = {
- .open = snd_ad1816a_capture_open,
- .close = snd_ad1816a_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ad1816a_hw_params,
- .hw_free = snd_ad1816a_hw_free,
- .prepare = snd_ad1816a_capture_prepare,
- .trigger = snd_ad1816a_capture_trigger,
- .pointer = snd_ad1816a_capture_pointer,
-};
-
-int __devinit snd_ad1816a_pcm(struct snd_ad1816a *chip, int device, struct snd_pcm **rpcm)
-{
- int error;
- struct snd_pcm *pcm;
-
- if ((error = snd_pcm_new(chip->card, "AD1816A", device, 1, 1, &pcm)))
- return error;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ad1816a_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ad1816a_capture_ops);
-
- pcm->private_data = chip;
- pcm->info_flags = (chip->dma1 == chip->dma2 ) ? SNDRV_PCM_INFO_JOINT_DUPLEX : 0;
-
- strcpy(pcm->name, snd_ad1816a_chip_id(chip));
- snd_ad1816a_init(chip);
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_isa_data(),
- 64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024);
-
- chip->pcm = pcm;
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-int __devinit snd_ad1816a_timer(struct snd_ad1816a *chip, int device, struct snd_timer **rtimer)
-{
- struct snd_timer *timer;
- struct snd_timer_id tid;
- int error;
-
- tid.dev_class = SNDRV_TIMER_CLASS_CARD;
- tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
- tid.card = chip->card->number;
- tid.device = device;
- tid.subdevice = 0;
- if ((error = snd_timer_new(chip->card, "AD1816A", &tid, &timer)) < 0)
- return error;
- strcpy(timer->name, snd_ad1816a_chip_id(chip));
- timer->private_data = chip;
- chip->timer = timer;
- timer->hw = snd_ad1816a_timer_table;
- if (rtimer)
- *rtimer = timer;
- return 0;
-}
-
-/*
- *
- */
-
-static int snd_ad1816a_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[8] = {
- "Line", "Mix", "CD", "Synth", "Video",
- "Mic", "Phone",
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 2;
- uinfo->value.enumerated.items = 7;
- if (uinfo->value.enumerated.item > 6)
- uinfo->value.enumerated.item = 6;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ad1816a_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- unsigned short val;
-
- spin_lock_irqsave(&chip->lock, flags);
- val = snd_ad1816a_read(chip, AD1816A_ADC_SOURCE_SEL);
- spin_unlock_irqrestore(&chip->lock, flags);
- ucontrol->value.enumerated.item[0] = (val >> 12) & 7;
- ucontrol->value.enumerated.item[1] = (val >> 4) & 7;
- return 0;
-}
-
-static int snd_ad1816a_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- unsigned short val;
- int change;
-
- if (ucontrol->value.enumerated.item[0] > 6 ||
- ucontrol->value.enumerated.item[1] > 6)
- return -EINVAL;
- val = (ucontrol->value.enumerated.item[0] << 12) |
- (ucontrol->value.enumerated.item[1] << 4);
- spin_lock_irqsave(&chip->lock, flags);
- change = snd_ad1816a_read(chip, AD1816A_ADC_SOURCE_SEL) != val;
- snd_ad1816a_write(chip, AD1816A_ADC_SOURCE_SEL, val);
- spin_unlock_irqrestore(&chip->lock, flags);
- return change;
-}
-
-#define AD1816A_SINGLE_TLV(xname, reg, shift, mask, invert, xtlv) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .name = xname, .info = snd_ad1816a_info_single, \
- .get = snd_ad1816a_get_single, .put = snd_ad1816a_put_single, \
- .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \
- .tlv = { .p = (xtlv) } }
-#define AD1816A_SINGLE(xname, reg, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ad1816a_info_single, \
- .get = snd_ad1816a_get_single, .put = snd_ad1816a_put_single, \
- .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
-
-static int snd_ad1816a_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 16) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_ad1816a_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
-
- spin_lock_irqsave(&chip->lock, flags);
- ucontrol->value.integer.value[0] = (snd_ad1816a_read(chip, reg) >> shift) & mask;
- spin_unlock_irqrestore(&chip->lock, flags);
- if (invert)
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- return 0;
-}
-
-static int snd_ad1816a_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
- int change;
- unsigned short old_val, val;
-
- val = (ucontrol->value.integer.value[0] & mask);
- if (invert)
- val = mask - val;
- val <<= shift;
- spin_lock_irqsave(&chip->lock, flags);
- old_val = snd_ad1816a_read(chip, reg);
- val = (old_val & ~(mask << shift)) | val;
- change = val != old_val;
- snd_ad1816a_write(chip, reg, val);
- spin_unlock_irqrestore(&chip->lock, flags);
- return change;
-}
-
-#define AD1816A_DOUBLE_TLV(xname, reg, shift_left, shift_right, mask, invert, xtlv) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .name = xname, .info = snd_ad1816a_info_double, \
- .get = snd_ad1816a_get_double, .put = snd_ad1816a_put_double, \
- .private_value = reg | (shift_left << 8) | (shift_right << 12) | (mask << 16) | (invert << 24), \
- .tlv = { .p = (xtlv) } }
-
-#define AD1816A_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ad1816a_info_double, \
- .get = snd_ad1816a_get_double, .put = snd_ad1816a_put_double, \
- .private_value = reg | (shift_left << 8) | (shift_right << 12) | (mask << 16) | (invert << 24) }
-
-static int snd_ad1816a_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 16) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_ad1816a_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int reg = kcontrol->private_value & 0xff;
- int shift_left = (kcontrol->private_value >> 8) & 0x0f;
- int shift_right = (kcontrol->private_value >> 12) & 0x0f;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
- unsigned short val;
-
- spin_lock_irqsave(&chip->lock, flags);
- val = snd_ad1816a_read(chip, reg);
- ucontrol->value.integer.value[0] = (val >> shift_left) & mask;
- ucontrol->value.integer.value[1] = (val >> shift_right) & mask;
- spin_unlock_irqrestore(&chip->lock, flags);
- if (invert) {
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
- }
- return 0;
-}
-
-static int snd_ad1816a_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int reg = kcontrol->private_value & 0xff;
- int shift_left = (kcontrol->private_value >> 8) & 0x0f;
- int shift_right = (kcontrol->private_value >> 12) & 0x0f;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
- int change;
- unsigned short old_val, val1, val2;
-
- val1 = ucontrol->value.integer.value[0] & mask;
- val2 = ucontrol->value.integer.value[1] & mask;
- if (invert) {
- val1 = mask - val1;
- val2 = mask - val2;
- }
- val1 <<= shift_left;
- val2 <<= shift_right;
- spin_lock_irqsave(&chip->lock, flags);
- old_val = snd_ad1816a_read(chip, reg);
- val1 = (old_val & ~((mask << shift_left) | (mask << shift_right))) | val1 | val2;
- change = val1 != old_val;
- snd_ad1816a_write(chip, reg, val1);
- spin_unlock_irqrestore(&chip->lock, flags);
- return change;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
-
-static struct snd_kcontrol_new snd_ad1816a_controls[] __devinitdata = {
-AD1816A_DOUBLE("Master Playback Switch", AD1816A_MASTER_ATT, 15, 7, 1, 1),
-AD1816A_DOUBLE_TLV("Master Playback Volume", AD1816A_MASTER_ATT, 8, 0, 31, 1,
- db_scale_5bit),
-AD1816A_DOUBLE("PCM Playback Switch", AD1816A_VOICE_ATT, 15, 7, 1, 1),
-AD1816A_DOUBLE_TLV("PCM Playback Volume", AD1816A_VOICE_ATT, 8, 0, 63, 1,
- db_scale_6bit),
-AD1816A_DOUBLE("Line Playback Switch", AD1816A_LINE_GAIN_ATT, 15, 7, 1, 1),
-AD1816A_DOUBLE_TLV("Line Playback Volume", AD1816A_LINE_GAIN_ATT, 8, 0, 31, 1,
- db_scale_5bit_12db_max),
-AD1816A_DOUBLE("CD Playback Switch", AD1816A_CD_GAIN_ATT, 15, 7, 1, 1),
-AD1816A_DOUBLE_TLV("CD Playback Volume", AD1816A_CD_GAIN_ATT, 8, 0, 31, 1,
- db_scale_5bit_12db_max),
-AD1816A_DOUBLE("Synth Playback Switch", AD1816A_SYNTH_GAIN_ATT, 15, 7, 1, 1),
-AD1816A_DOUBLE_TLV("Synth Playback Volume", AD1816A_SYNTH_GAIN_ATT, 8, 0, 31, 1,
- db_scale_5bit_12db_max),
-AD1816A_DOUBLE("FM Playback Switch", AD1816A_FM_ATT, 15, 7, 1, 1),
-AD1816A_DOUBLE_TLV("FM Playback Volume", AD1816A_FM_ATT, 8, 0, 63, 1,
- db_scale_6bit),
-AD1816A_SINGLE("Mic Playback Switch", AD1816A_MIC_GAIN_ATT, 15, 1, 1),
-AD1816A_SINGLE_TLV("Mic Playback Volume", AD1816A_MIC_GAIN_ATT, 8, 31, 1,
- db_scale_5bit_12db_max),
-AD1816A_SINGLE("Mic Boost", AD1816A_MIC_GAIN_ATT, 14, 1, 0),
-AD1816A_DOUBLE("Video Playback Switch", AD1816A_VID_GAIN_ATT, 15, 7, 1, 1),
-AD1816A_DOUBLE_TLV("Video Playback Volume", AD1816A_VID_GAIN_ATT, 8, 0, 31, 1,
- db_scale_5bit_12db_max),
-AD1816A_SINGLE("Phone Capture Switch", AD1816A_PHONE_IN_GAIN_ATT, 15, 1, 1),
-AD1816A_SINGLE_TLV("Phone Capture Volume", AD1816A_PHONE_IN_GAIN_ATT, 0, 15, 1,
- db_scale_4bit),
-AD1816A_SINGLE("Phone Playback Switch", AD1816A_PHONE_OUT_ATT, 7, 1, 1),
-AD1816A_SINGLE_TLV("Phone Playback Volume", AD1816A_PHONE_OUT_ATT, 0, 31, 1,
- db_scale_5bit),
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = snd_ad1816a_info_mux,
- .get = snd_ad1816a_get_mux,
- .put = snd_ad1816a_put_mux,
-},
-AD1816A_DOUBLE("Capture Switch", AD1816A_ADC_PGA, 15, 7, 1, 1),
-AD1816A_DOUBLE_TLV("Capture Volume", AD1816A_ADC_PGA, 8, 0, 15, 0,
- db_scale_rec_gain),
-AD1816A_SINGLE("3D Control - Switch", AD1816A_3D_PHAT_CTRL, 15, 1, 1),
-AD1816A_SINGLE("3D Control - Level", AD1816A_3D_PHAT_CTRL, 0, 15, 0),
-};
-
-int __devinit snd_ad1816a_mixer(struct snd_ad1816a *chip)
-{
- struct snd_card *card;
- unsigned int idx;
- int err;
-
- if (snd_BUG_ON(!chip || !chip->card))
- return -EINVAL;
-
- card = chip->card;
-
- strcpy(card->mixername, snd_ad1816a_chip_id(chip));
-
- for (idx = 0; idx < ARRAY_SIZE(snd_ad1816a_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_ad1816a_controls[idx], chip))) < 0)
- return err;
- }
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/isa/ad1848/Makefile b/ANDROID_3.4.5/sound/isa/ad1848/Makefile
deleted file mode 100644
index 3d6dea3f..00000000
--- a/ANDROID_3.4.5/sound/isa/ad1848/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-ad1848-objs := ad1848.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_AD1848) += snd-ad1848.o
-
diff --git a/ANDROID_3.4.5/sound/isa/ad1848/ad1848.c b/ANDROID_3.4.5/sound/isa/ad1848/ad1848.c
deleted file mode 100644
index 2af77fae..00000000
--- a/ANDROID_3.4.5/sound/isa/ad1848/ad1848.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Generic driver for AD1848/AD1847/CS4248 chips (0.1 Alpha)
- * Copyright (c) by Tugrul Galatali <galatalt@stuy.edu>,
- * Jaroslav Kysela <perex@perex.cz>
- * Based on card-4232.c by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/isa.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/wss.h>
-#include <sound/initval.h>
-
-#define CRD_NAME "Generic AD1848/AD1847/CS4248"
-#define DEV_NAME "ad1848"
-
-MODULE_DESCRIPTION(CRD_NAME);
-MODULE_AUTHOR("Tugrul Galatali <galatalt@stuy.edu>, Jaroslav Kysela <perex@perex.cz>");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Analog Devices,AD1848},"
- "{Analog Devices,AD1847},"
- "{Crystal Semiconductors,CS4248}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,11,12,15 */
-static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
-static bool thinkpad[SNDRV_CARDS]; /* Thinkpad special case */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
-module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
-module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver.");
-module_param_array(thinkpad, bool, NULL, 0444);
-MODULE_PARM_DESC(thinkpad, "Enable only for the onboard CS4248 of IBM Thinkpad 360/750/755 series.");
-
-static int __devinit snd_ad1848_match(struct device *dev, unsigned int n)
-{
- if (!enable[n])
- return 0;
-
- if (port[n] == SNDRV_AUTO_PORT) {
- dev_err(dev, "please specify port\n");
- return 0;
- }
- if (irq[n] == SNDRV_AUTO_IRQ) {
- dev_err(dev, "please specify irq\n");
- return 0;
- }
- if (dma1[n] == SNDRV_AUTO_DMA) {
- dev_err(dev, "please specify dma1\n");
- return 0;
- }
- return 1;
-}
-
-static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n)
-{
- struct snd_card *card;
- struct snd_wss *chip;
- struct snd_pcm *pcm;
- int error;
-
- error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card);
- if (error < 0)
- return error;
-
- error = snd_wss_create(card, port[n], -1, irq[n], dma1[n], -1,
- thinkpad[n] ? WSS_HW_THINKPAD : WSS_HW_DETECT,
- 0, &chip);
- if (error < 0)
- goto out;
-
- card->private_data = chip;
-
- error = snd_wss_pcm(chip, 0, &pcm);
- if (error < 0)
- goto out;
-
- error = snd_wss_mixer(chip);
- if (error < 0)
- goto out;
-
- strcpy(card->driver, "AD1848");
- strcpy(card->shortname, pcm->name);
-
- sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
- pcm->name, chip->port, irq[n], dma1[n]);
- if (thinkpad[n])
- strcat(card->longname, " [Thinkpad]");
-
- snd_card_set_dev(card, dev);
-
- error = snd_card_register(card);
- if (error < 0)
- goto out;
-
- dev_set_drvdata(dev, card);
- return 0;
-
-out: snd_card_free(card);
- return error;
-}
-
-static int __devexit snd_ad1848_remove(struct device *dev, unsigned int n)
-{
- snd_card_free(dev_get_drvdata(dev));
- dev_set_drvdata(dev, NULL);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int snd_ad1848_suspend(struct device *dev, unsigned int n, pm_message_t state)
-{
- struct snd_card *card = dev_get_drvdata(dev);
- struct snd_wss *chip = card->private_data;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- chip->suspend(chip);
- return 0;
-}
-
-static int snd_ad1848_resume(struct device *dev, unsigned int n)
-{
- struct snd_card *card = dev_get_drvdata(dev);
- struct snd_wss *chip = card->private_data;
-
- chip->resume(chip);
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif
-
-static struct isa_driver snd_ad1848_driver = {
- .match = snd_ad1848_match,
- .probe = snd_ad1848_probe,
- .remove = __devexit_p(snd_ad1848_remove),
-#ifdef CONFIG_PM
- .suspend = snd_ad1848_suspend,
- .resume = snd_ad1848_resume,
-#endif
- .driver = {
- .name = DEV_NAME
- }
-};
-
-static int __init alsa_card_ad1848_init(void)
-{
- return isa_register_driver(&snd_ad1848_driver, SNDRV_CARDS);
-}
-
-static void __exit alsa_card_ad1848_exit(void)
-{
- isa_unregister_driver(&snd_ad1848_driver);
-}
-
-module_init(alsa_card_ad1848_init);
-module_exit(alsa_card_ad1848_exit);
diff --git a/ANDROID_3.4.5/sound/isa/adlib.c b/ANDROID_3.4.5/sound/isa/adlib.c
deleted file mode 100644
index 4d50c69f..00000000
--- a/ANDROID_3.4.5/sound/isa/adlib.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * AdLib FM card driver.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/isa.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/opl3.h>
-
-#define CRD_NAME "AdLib FM"
-#define DEV_NAME "adlib"
-
-MODULE_DESCRIPTION(CRD_NAME);
-MODULE_AUTHOR("Rene Herman");
-MODULE_LICENSE("GPL");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
-
-static int __devinit snd_adlib_match(struct device *dev, unsigned int n)
-{
- if (!enable[n])
- return 0;
-
- if (port[n] == SNDRV_AUTO_PORT) {
- dev_err(dev, "please specify port\n");
- return 0;
- }
- return 1;
-}
-
-static void snd_adlib_free(struct snd_card *card)
-{
- release_and_free_resource(card->private_data);
-}
-
-static int __devinit snd_adlib_probe(struct device *dev, unsigned int n)
-{
- struct snd_card *card;
- struct snd_opl3 *opl3;
- int error;
-
- error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card);
- if (error < 0) {
- dev_err(dev, "could not create card\n");
- return error;
- }
-
- card->private_data = request_region(port[n], 4, CRD_NAME);
- if (!card->private_data) {
- dev_err(dev, "could not grab ports\n");
- error = -EBUSY;
- goto out;
- }
- card->private_free = snd_adlib_free;
-
- strcpy(card->driver, DEV_NAME);
- strcpy(card->shortname, CRD_NAME);
- sprintf(card->longname, CRD_NAME " at %#lx", port[n]);
-
- error = snd_opl3_create(card, port[n], port[n] + 2, OPL3_HW_AUTO, 1, &opl3);
- if (error < 0) {
- dev_err(dev, "could not create OPL\n");
- goto out;
- }
-
- error = snd_opl3_hwdep_new(opl3, 0, 0, NULL);
- if (error < 0) {
- dev_err(dev, "could not create FM\n");
- goto out;
- }
-
- snd_card_set_dev(card, dev);
-
- error = snd_card_register(card);
- if (error < 0) {
- dev_err(dev, "could not register card\n");
- goto out;
- }
-
- dev_set_drvdata(dev, card);
- return 0;
-
-out: snd_card_free(card);
- return error;
-}
-
-static int __devexit snd_adlib_remove(struct device *dev, unsigned int n)
-{
- snd_card_free(dev_get_drvdata(dev));
- dev_set_drvdata(dev, NULL);
- return 0;
-}
-
-static struct isa_driver snd_adlib_driver = {
- .match = snd_adlib_match,
- .probe = snd_adlib_probe,
- .remove = __devexit_p(snd_adlib_remove),
-
- .driver = {
- .name = DEV_NAME
- }
-};
-
-static int __init alsa_card_adlib_init(void)
-{
- return isa_register_driver(&snd_adlib_driver, SNDRV_CARDS);
-}
-
-static void __exit alsa_card_adlib_exit(void)
-{
- isa_unregister_driver(&snd_adlib_driver);
-}
-
-module_init(alsa_card_adlib_init);
-module_exit(alsa_card_adlib_exit);
diff --git a/ANDROID_3.4.5/sound/isa/als100.c b/ANDROID_3.4.5/sound/isa/als100.c
deleted file mode 100644
index d1f4351f..00000000
--- a/ANDROID_3.4.5/sound/isa/als100.c
+++ /dev/null
@@ -1,378 +0,0 @@
-
-/*
- card-als100.c - driver for Avance Logic ALS100 based soundcards.
- Copyright (C) 1999-2000 by Massimo Piccioni <dafastidio@libero.it>
- Copyright (C) 1999-2002 by Massimo Piccioni <dafastidio@libero.it>
-
- Thanks to Pierfrancesco 'qM2' Passerini.
-
- Generalised for soundcards based on DT-0196 and ALS-007 chips
- by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>: June 2002.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <linux/init.h>
-#include <linux/wait.h>
-#include <linux/time.h>
-#include <linux/pnp.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/mpu401.h>
-#include <sound/opl3.h>
-#include <sound/sb.h>
-
-#define PFX "als100: "
-
-MODULE_DESCRIPTION("Avance Logic ALS007/ALS1X0");
-MODULE_SUPPORTED_DEVICE("{{Diamond Technologies DT-019X},"
- "{Avance Logic ALS-007}}"
- "{{Avance Logic,ALS100 - PRO16PNP},"
- "{Avance Logic,ALS110},"
- "{Avance Logic,ALS120},"
- "{Avance Logic,ALS200},"
- "{3D Melody,MF1000},"
- "{Digimate,3D Sound},"
- "{Avance Logic,ALS120},"
- "{RTL,RTL3000}}");
-
-MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
-MODULE_LICENSE("GPL");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* PnP setup */
-static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* PnP setup */
-static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
-static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Avance Logic based soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Avance Logic based soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Avance Logic based soundcard.");
-
-MODULE_ALIAS("snd-dt019x");
-
-struct snd_card_als100 {
- struct pnp_dev *dev;
- struct pnp_dev *devmpu;
- struct pnp_dev *devopl;
- struct snd_sb *chip;
-};
-
-static struct pnp_card_device_id snd_als100_pnpids[] = {
- /* DT197A30 */
- { .id = "RWB1688",
- .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } },
- .driver_data = SB_HW_DT019X },
- /* DT0196 / ALS-007 */
- { .id = "ALS0007",
- .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } },
- .driver_data = SB_HW_DT019X },
- /* ALS100 - PRO16PNP */
- { .id = "ALS0001",
- .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } },
- .driver_data = SB_HW_ALS100 },
- /* ALS110 - MF1000 - Digimate 3D Sound */
- { .id = "ALS0110",
- .devs = { { "@@@1001" }, { "@X@1001" }, { "@H@1001" } },
- .driver_data = SB_HW_ALS100 },
- /* ALS120 */
- { .id = "ALS0120",
- .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } },
- .driver_data = SB_HW_ALS100 },
- /* ALS200 */
- { .id = "ALS0200",
- .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0001" } },
- .driver_data = SB_HW_ALS100 },
- /* ALS200 OEM */
- { .id = "ALS0200",
- .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0020" } },
- .driver_data = SB_HW_ALS100 },
- /* RTL3000 */
- { .id = "RTL3000",
- .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } },
- .driver_data = SB_HW_ALS100 },
- { .id = "" } /* end */
-};
-
-MODULE_DEVICE_TABLE(pnp_card, snd_als100_pnpids);
-
-static int __devinit snd_card_als100_pnp(int dev, struct snd_card_als100 *acard,
- struct pnp_card_link *card,
- const struct pnp_card_device_id *id)
-{
- struct pnp_dev *pdev;
- int err;
-
- acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
- if (acard->dev == NULL)
- return -ENODEV;
-
- acard->devmpu = pnp_request_card_device(card, id->devs[1].id, acard->dev);
- acard->devopl = pnp_request_card_device(card, id->devs[2].id, acard->dev);
-
- pdev = acard->dev;
-
- err = pnp_activate_dev(pdev);
- if (err < 0) {
- snd_printk(KERN_ERR PFX "AUDIO pnp configure failure\n");
- return err;
- }
- port[dev] = pnp_port_start(pdev, 0);
- if (id->driver_data == SB_HW_DT019X)
- dma8[dev] = pnp_dma(pdev, 0);
- else {
- dma8[dev] = pnp_dma(pdev, 1);
- dma16[dev] = pnp_dma(pdev, 0);
- }
- irq[dev] = pnp_irq(pdev, 0);
-
- pdev = acard->devmpu;
- if (pdev != NULL) {
- err = pnp_activate_dev(pdev);
- if (err < 0)
- goto __mpu_error;
- mpu_port[dev] = pnp_port_start(pdev, 0);
- mpu_irq[dev] = pnp_irq(pdev, 0);
- } else {
- __mpu_error:
- if (pdev) {
- pnp_release_card_device(pdev);
- snd_printk(KERN_ERR PFX "MPU401 pnp configure failure, skipping\n");
- }
- acard->devmpu = NULL;
- mpu_port[dev] = -1;
- }
-
- pdev = acard->devopl;
- if (pdev != NULL) {
- err = pnp_activate_dev(pdev);
- if (err < 0)
- goto __fm_error;
- fm_port[dev] = pnp_port_start(pdev, 0);
- } else {
- __fm_error:
- if (pdev) {
- pnp_release_card_device(pdev);
- snd_printk(KERN_ERR PFX "OPL3 pnp configure failure, skipping\n");
- }
- acard->devopl = NULL;
- fm_port[dev] = -1;
- }
-
- return 0;
-}
-
-static int __devinit snd_card_als100_probe(int dev,
- struct pnp_card_link *pcard,
- const struct pnp_card_device_id *pid)
-{
- int error;
- struct snd_sb *chip;
- struct snd_card *card;
- struct snd_card_als100 *acard;
- struct snd_opl3 *opl3;
-
- error = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_card_als100), &card);
- if (error < 0)
- return error;
- acard = card->private_data;
-
- if ((error = snd_card_als100_pnp(dev, acard, pcard, pid))) {
- snd_card_free(card);
- return error;
- }
- snd_card_set_dev(card, &pcard->card->dev);
-
- if (pid->driver_data == SB_HW_DT019X)
- dma16[dev] = -1;
-
- error = snd_sbdsp_create(card, port[dev], irq[dev],
- snd_sb16dsp_interrupt,
- dma8[dev], dma16[dev],
- pid->driver_data,
- &chip);
- if (error < 0) {
- snd_card_free(card);
- return error;
- }
- acard->chip = chip;
-
- if (pid->driver_data == SB_HW_DT019X) {
- strcpy(card->driver, "DT-019X");
- strcpy(card->shortname, "Diamond Tech. DT-019X");
- sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
- card->shortname, chip->name, chip->port,
- irq[dev], dma8[dev]);
- } else {
- strcpy(card->driver, "ALS100");
- strcpy(card->shortname, "Avance Logic ALS100");
- sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d",
- card->shortname, chip->name, chip->port,
- irq[dev], dma8[dev], dma16[dev]);
- }
-
- if ((error = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) {
- snd_card_free(card);
- return error;
- }
-
- if ((error = snd_sbmixer_new(chip)) < 0) {
- snd_card_free(card);
- return error;
- }
-
- if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
- int mpu_type = MPU401_HW_ALS100;
-
- if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
- mpu_irq[dev] = -1;
-
- if (pid->driver_data == SB_HW_DT019X)
- mpu_type = MPU401_HW_MPU401;
-
- if (snd_mpu401_uart_new(card, 0,
- mpu_type,
- mpu_port[dev], 0,
- mpu_irq[dev],
- NULL) < 0)
- snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]);
- }
-
- if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
- if (snd_opl3_create(card,
- fm_port[dev], fm_port[dev] + 2,
- OPL3_HW_AUTO, 0, &opl3) < 0) {
- snd_printk(KERN_ERR PFX "no OPL device at 0x%lx-0x%lx\n",
- fm_port[dev], fm_port[dev] + 2);
- } else {
- if ((error = snd_opl3_timer_new(opl3, 0, 1)) < 0) {
- snd_card_free(card);
- return error;
- }
- if ((error = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
- snd_card_free(card);
- return error;
- }
- }
- }
-
- if ((error = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return error;
- }
- pnp_set_card_drvdata(pcard, card);
- return 0;
-}
-
-static unsigned int __devinitdata als100_devices;
-
-static int __devinit snd_als100_pnp_detect(struct pnp_card_link *card,
- const struct pnp_card_device_id *id)
-{
- static int dev;
- int res;
-
- for ( ; dev < SNDRV_CARDS; dev++) {
- if (!enable[dev])
- continue;
- res = snd_card_als100_probe(dev, card, id);
- if (res < 0)
- return res;
- dev++;
- als100_devices++;
- return 0;
- }
- return -ENODEV;
-}
-
-static void __devexit snd_als100_pnp_remove(struct pnp_card_link * pcard)
-{
- snd_card_free(pnp_get_card_drvdata(pcard));
- pnp_set_card_drvdata(pcard, NULL);
-}
-
-#ifdef CONFIG_PM
-static int snd_als100_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
-{
- struct snd_card *card = pnp_get_card_drvdata(pcard);
- struct snd_card_als100 *acard = card->private_data;
- struct snd_sb *chip = acard->chip;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(chip->pcm);
- snd_sbmixer_suspend(chip);
- return 0;
-}
-
-static int snd_als100_pnp_resume(struct pnp_card_link *pcard)
-{
- struct snd_card *card = pnp_get_card_drvdata(pcard);
- struct snd_card_als100 *acard = card->private_data;
- struct snd_sb *chip = acard->chip;
-
- snd_sbdsp_reset(chip);
- snd_sbmixer_resume(chip);
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif
-
-static struct pnp_card_driver als100_pnpc_driver = {
- .flags = PNP_DRIVER_RES_DISABLE,
- .name = "als100",
- .id_table = snd_als100_pnpids,
- .probe = snd_als100_pnp_detect,
- .remove = __devexit_p(snd_als100_pnp_remove),
-#ifdef CONFIG_PM
- .suspend = snd_als100_pnp_suspend,
- .resume = snd_als100_pnp_resume,
-#endif
-};
-
-static int __init alsa_card_als100_init(void)
-{
- int err;
-
- err = pnp_register_card_driver(&als100_pnpc_driver);
- if (err)
- return err;
-
- if (!als100_devices) {
- pnp_unregister_card_driver(&als100_pnpc_driver);
-#ifdef MODULE
- snd_printk(KERN_ERR "no Avance Logic based soundcards found\n");
-#endif
- return -ENODEV;
- }
- return 0;
-}
-
-static void __exit alsa_card_als100_exit(void)
-{
- pnp_unregister_card_driver(&als100_pnpc_driver);
-}
-
-module_init(alsa_card_als100_init)
-module_exit(alsa_card_als100_exit)
diff --git a/ANDROID_3.4.5/sound/isa/azt2320.c b/ANDROID_3.4.5/sound/isa/azt2320.c
deleted file mode 100644
index 6a2c78ef..00000000
--- a/ANDROID_3.4.5/sound/isa/azt2320.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- card-azt2320.c - driver for Aztech Systems AZT2320 based soundcards.
- Copyright (C) 1999-2000 by Massimo Piccioni <dafastidio@libero.it>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-/*
- This driver should provide support for most Aztech AZT2320 based cards.
- Several AZT2316 chips are also supported/tested, but autoprobe doesn't
- work: all module option have to be set.
-
- No docs available for us at Aztech headquarters !!! Unbelievable ...
- No other help obtained.
-
- Thanks to Rainer Wiesner <rainer.wiesner@01019freenet.de> for the WSS
- activation method (full-duplex audio!).
-*/
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/pnp.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/wss.h>
-#include <sound/mpu401.h>
-#include <sound/opl3.h>
-
-#define PFX "azt2320: "
-
-MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
-MODULE_DESCRIPTION("Aztech Systems AZT2320");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Aztech Systems,PRO16V},"
- "{Aztech Systems,AZT2320},"
- "{Aztech Systems,AZT3300},"
- "{Aztech Systems,AZT2320},"
- "{Aztech Systems,AZT3000}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static long wss_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* Pnp setup */
-static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* Pnp setup */
-static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
-static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for azt2320 based soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for azt2320 based soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable azt2320 based soundcard.");
-
-struct snd_card_azt2320 {
- int dev_no;
- struct pnp_dev *dev;
- struct pnp_dev *devmpu;
- struct snd_wss *chip;
-};
-
-static struct pnp_card_device_id snd_azt2320_pnpids[] = {
- /* PRO16V */
- { .id = "AZT1008", .devs = { { "AZT1008" }, { "AZT2001" }, } },
- /* Aztech Sound Galaxy 16 */
- { .id = "AZT2320", .devs = { { "AZT0001" }, { "AZT0002" }, } },
- /* Packard Bell Sound III 336 AM/SP */
- { .id = "AZT3000", .devs = { { "AZT1003" }, { "AZT2001" }, } },
- /* AT3300 */
- { .id = "AZT3002", .devs = { { "AZT1004" }, { "AZT2001" }, } },
- /* --- */
- { .id = "AZT3005", .devs = { { "AZT1003" }, { "AZT2001" }, } },
- /* --- */
- { .id = "AZT3011", .devs = { { "AZT1003" }, { "AZT2001" }, } },
- { .id = "" } /* end */
-};
-
-MODULE_DEVICE_TABLE(pnp_card, snd_azt2320_pnpids);
-
-#define DRIVER_NAME "snd-card-azt2320"
-
-static int __devinit snd_card_azt2320_pnp(int dev, struct snd_card_azt2320 *acard,
- struct pnp_card_link *card,
- const struct pnp_card_device_id *id)
-{
- struct pnp_dev *pdev;
- int err;
-
- acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
- if (acard->dev == NULL)
- return -ENODEV;
-
- acard->devmpu = pnp_request_card_device(card, id->devs[1].id, NULL);
-
- pdev = acard->dev;
-
- err = pnp_activate_dev(pdev);
- if (err < 0) {
- snd_printk(KERN_ERR PFX "AUDIO pnp configure failure\n");
- return err;
- }
- port[dev] = pnp_port_start(pdev, 0);
- fm_port[dev] = pnp_port_start(pdev, 1);
- wss_port[dev] = pnp_port_start(pdev, 2);
- dma1[dev] = pnp_dma(pdev, 0);
- dma2[dev] = pnp_dma(pdev, 1);
- irq[dev] = pnp_irq(pdev, 0);
-
- pdev = acard->devmpu;
- if (pdev != NULL) {
- err = pnp_activate_dev(pdev);
- if (err < 0)
- goto __mpu_error;
- mpu_port[dev] = pnp_port_start(pdev, 0);
- mpu_irq[dev] = pnp_irq(pdev, 0);
- } else {
- __mpu_error:
- if (pdev) {
- pnp_release_card_device(pdev);
- snd_printk(KERN_ERR PFX "MPU401 pnp configure failure, skipping\n");
- }
- acard->devmpu = NULL;
- mpu_port[dev] = -1;
- }
-
- return 0;
-}
-
-/* same of snd_sbdsp_command by Jaroslav Kysela */
-static int __devinit snd_card_azt2320_command(unsigned long port, unsigned char val)
-{
- int i;
- unsigned long limit;
-
- limit = jiffies + HZ / 10;
- for (i = 50000; i && time_after(limit, jiffies); i--)
- if (!(inb(port + 0x0c) & 0x80)) {
- outb(val, port + 0x0c);
- return 0;
- }
- return -EBUSY;
-}
-
-static int __devinit snd_card_azt2320_enable_wss(unsigned long port)
-{
- int error;
-
- if ((error = snd_card_azt2320_command(port, 0x09)))
- return error;
- if ((error = snd_card_azt2320_command(port, 0x00)))
- return error;
-
- mdelay(5);
- return 0;
-}
-
-static int __devinit snd_card_azt2320_probe(int dev,
- struct pnp_card_link *pcard,
- const struct pnp_card_device_id *pid)
-{
- int error;
- struct snd_card *card;
- struct snd_card_azt2320 *acard;
- struct snd_wss *chip;
- struct snd_opl3 *opl3;
-
- error = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_card_azt2320), &card);
- if (error < 0)
- return error;
- acard = card->private_data;
-
- if ((error = snd_card_azt2320_pnp(dev, acard, pcard, pid))) {
- snd_card_free(card);
- return error;
- }
- snd_card_set_dev(card, &pcard->card->dev);
-
- if ((error = snd_card_azt2320_enable_wss(port[dev]))) {
- snd_card_free(card);
- return error;
- }
-
- error = snd_wss_create(card, wss_port[dev], -1,
- irq[dev],
- dma1[dev], dma2[dev],
- WSS_HW_DETECT, 0, &chip);
- if (error < 0) {
- snd_card_free(card);
- return error;
- }
-
- strcpy(card->driver, "AZT2320");
- strcpy(card->shortname, "Aztech AZT2320");
- sprintf(card->longname, "%s, WSS at 0x%lx, irq %i, dma %i&%i",
- card->shortname, chip->port, irq[dev], dma1[dev], dma2[dev]);
-
- error = snd_wss_pcm(chip, 0, NULL);
- if (error < 0) {
- snd_card_free(card);
- return error;
- }
- error = snd_wss_mixer(chip);
- if (error < 0) {
- snd_card_free(card);
- return error;
- }
- error = snd_wss_timer(chip, 0, NULL);
- if (error < 0) {
- snd_card_free(card);
- return error;
- }
-
- if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
- if (snd_mpu401_uart_new(card, 0, MPU401_HW_AZT2320,
- mpu_port[dev], 0,
- mpu_irq[dev], NULL) < 0)
- snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]);
- }
-
- if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
- if (snd_opl3_create(card,
- fm_port[dev], fm_port[dev] + 2,
- OPL3_HW_AUTO, 0, &opl3) < 0) {
- snd_printk(KERN_ERR PFX "no OPL device at 0x%lx-0x%lx\n",
- fm_port[dev], fm_port[dev] + 2);
- } else {
- if ((error = snd_opl3_timer_new(opl3, 1, 2)) < 0) {
- snd_card_free(card);
- return error;
- }
- if ((error = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
- snd_card_free(card);
- return error;
- }
- }
- }
-
- if ((error = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return error;
- }
- pnp_set_card_drvdata(pcard, card);
- return 0;
-}
-
-static unsigned int __devinitdata azt2320_devices;
-
-static int __devinit snd_azt2320_pnp_detect(struct pnp_card_link *card,
- const struct pnp_card_device_id *id)
-{
- static int dev;
- int res;
-
- for ( ; dev < SNDRV_CARDS; dev++) {
- if (!enable[dev])
- continue;
- res = snd_card_azt2320_probe(dev, card, id);
- if (res < 0)
- return res;
- dev++;
- azt2320_devices++;
- return 0;
- }
- return -ENODEV;
-}
-
-static void __devexit snd_azt2320_pnp_remove(struct pnp_card_link * pcard)
-{
- snd_card_free(pnp_get_card_drvdata(pcard));
- pnp_set_card_drvdata(pcard, NULL);
-}
-
-#ifdef CONFIG_PM
-static int snd_azt2320_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
-{
- struct snd_card *card = pnp_get_card_drvdata(pcard);
- struct snd_card_azt2320 *acard = card->private_data;
- struct snd_wss *chip = acard->chip;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- chip->suspend(chip);
- return 0;
-}
-
-static int snd_azt2320_pnp_resume(struct pnp_card_link *pcard)
-{
- struct snd_card *card = pnp_get_card_drvdata(pcard);
- struct snd_card_azt2320 *acard = card->private_data;
- struct snd_wss *chip = acard->chip;
-
- chip->resume(chip);
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif
-
-static struct pnp_card_driver azt2320_pnpc_driver = {
- .flags = PNP_DRIVER_RES_DISABLE,
- .name = "azt2320",
- .id_table = snd_azt2320_pnpids,
- .probe = snd_azt2320_pnp_detect,
- .remove = __devexit_p(snd_azt2320_pnp_remove),
-#ifdef CONFIG_PM
- .suspend = snd_azt2320_pnp_suspend,
- .resume = snd_azt2320_pnp_resume,
-#endif
-};
-
-static int __init alsa_card_azt2320_init(void)
-{
- int err;
-
- err = pnp_register_card_driver(&azt2320_pnpc_driver);
- if (err)
- return err;
-
- if (!azt2320_devices) {
- pnp_unregister_card_driver(&azt2320_pnpc_driver);
-#ifdef MODULE
- snd_printk(KERN_ERR "no AZT2320 based soundcards found\n");
-#endif
- return -ENODEV;
- }
- return 0;
-}
-
-static void __exit alsa_card_azt2320_exit(void)
-{
- pnp_unregister_card_driver(&azt2320_pnpc_driver);
-}
-
-module_init(alsa_card_azt2320_init)
-module_exit(alsa_card_azt2320_exit)
diff --git a/ANDROID_3.4.5/sound/isa/cmi8330.c b/ANDROID_3.4.5/sound/isa/cmi8330.c
deleted file mode 100644
index 7bd5e337..00000000
--- a/ANDROID_3.4.5/sound/isa/cmi8330.c
+++ /dev/null
@@ -1,782 +0,0 @@
-/*
- * Driver for C-Media's CMI8330 and CMI8329 soundcards.
- * Copyright (c) by George Talusan <gstalusan@uwaterloo.ca>
- * http://www.undergrad.math.uwaterloo.ca/~gstalusa
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- * NOTES
- *
- * The extended registers contain mixer settings which are largely
- * untapped for the time being.
- *
- * MPU401 and SPDIF are not supported yet. I don't have the hardware
- * to aid in coding and testing, so I won't bother.
- *
- * To quickly load the module,
- *
- * modprobe -a snd-cmi8330 sbport=0x220 sbirq=5 sbdma8=1
- * sbdma16=5 wssport=0x530 wssirq=11 wssdma=0 fmport=0x388
- *
- * This card has two mixers and two PCM devices. I've cheesed it such
- * that recording and playback can be done through the same device.
- * The driver "magically" routes the capturing to the AD1848 codec,
- * and playback to the SB16 codec. This allows for full-duplex mode
- * to some extent.
- * The utilities in alsa-utils are aware of both devices, so passing
- * the appropriate parameters to amixer and alsactl will give you
- * full control over both mixers.
- */
-
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/isa.h>
-#include <linux/pnp.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/wss.h>
-#include <sound/opl3.h>
-#include <sound/mpu401.h>
-#include <sound/sb.h>
-#include <sound/initval.h>
-
-/*
- */
-/* #define ENABLE_SB_MIXER */
-#define PLAYBACK_ON_SB
-
-/*
- */
-MODULE_AUTHOR("George Talusan <gstalusan@uwaterloo.ca>");
-MODULE_DESCRIPTION("C-Media CMI8330/CMI8329");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8330,isapnp:{CMI0001,@@@0001,@X@0001}}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
-#ifdef CONFIG_PNP
-static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
-#endif
-static long sbport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-static int sbirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
-static int sbdma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
-static int sbdma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
-static long wssport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-static int wssirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
-static int wssdma[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
-static long fmport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-static long mpuport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-static int mpuirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for CMI8330/CMI8329 soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for CMI8330/CMI8329 soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable CMI8330/CMI8329 soundcard.");
-#ifdef CONFIG_PNP
-module_param_array(isapnp, bool, NULL, 0444);
-MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
-#endif
-
-module_param_array(sbport, long, NULL, 0444);
-MODULE_PARM_DESC(sbport, "Port # for CMI8330/CMI8329 SB driver.");
-module_param_array(sbirq, int, NULL, 0444);
-MODULE_PARM_DESC(sbirq, "IRQ # for CMI8330/CMI8329 SB driver.");
-module_param_array(sbdma8, int, NULL, 0444);
-MODULE_PARM_DESC(sbdma8, "DMA8 for CMI8330/CMI8329 SB driver.");
-module_param_array(sbdma16, int, NULL, 0444);
-MODULE_PARM_DESC(sbdma16, "DMA16 for CMI8330/CMI8329 SB driver.");
-
-module_param_array(wssport, long, NULL, 0444);
-MODULE_PARM_DESC(wssport, "Port # for CMI8330/CMI8329 WSS driver.");
-module_param_array(wssirq, int, NULL, 0444);
-MODULE_PARM_DESC(wssirq, "IRQ # for CMI8330/CMI8329 WSS driver.");
-module_param_array(wssdma, int, NULL, 0444);
-MODULE_PARM_DESC(wssdma, "DMA for CMI8330/CMI8329 WSS driver.");
-
-module_param_array(fmport, long, NULL, 0444);
-MODULE_PARM_DESC(fmport, "FM port # for CMI8330/CMI8329 driver.");
-module_param_array(mpuport, long, NULL, 0444);
-MODULE_PARM_DESC(mpuport, "MPU-401 port # for CMI8330/CMI8329 driver.");
-module_param_array(mpuirq, int, NULL, 0444);
-MODULE_PARM_DESC(mpuirq, "IRQ # for CMI8330/CMI8329 MPU-401 port.");
-#ifdef CONFIG_PNP
-static int isa_registered;
-static int pnp_registered;
-#endif
-
-#define CMI8330_RMUX3D 16
-#define CMI8330_MUTEMUX 17
-#define CMI8330_OUTPUTVOL 18
-#define CMI8330_MASTVOL 19
-#define CMI8330_LINVOL 20
-#define CMI8330_CDINVOL 21
-#define CMI8330_WAVVOL 22
-#define CMI8330_RECMUX 23
-#define CMI8330_WAVGAIN 24
-#define CMI8330_LINGAIN 25
-#define CMI8330_CDINGAIN 26
-
-static unsigned char snd_cmi8330_image[((CMI8330_CDINGAIN)-16) + 1] =
-{
- 0x40, /* 16 - recording mux (SB-mixer-enabled) */
-#ifdef ENABLE_SB_MIXER
- 0x40, /* 17 - mute mux (Mode2) */
-#else
- 0x0, /* 17 - mute mux */
-#endif
- 0x0, /* 18 - vol */
- 0x0, /* 19 - master volume */
- 0x0, /* 20 - line-in volume */
- 0x0, /* 21 - cd-in volume */
- 0x0, /* 22 - wave volume */
- 0x0, /* 23 - mute/rec mux */
- 0x0, /* 24 - wave rec gain */
- 0x0, /* 25 - line-in rec gain */
- 0x0 /* 26 - cd-in rec gain */
-};
-
-typedef int (*snd_pcm_open_callback_t)(struct snd_pcm_substream *);
-
-enum card_type {
- CMI8330,
- CMI8329
-};
-
-struct snd_cmi8330 {
-#ifdef CONFIG_PNP
- struct pnp_dev *cap;
- struct pnp_dev *play;
- struct pnp_dev *mpu;
-#endif
- struct snd_card *card;
- struct snd_wss *wss;
- struct snd_sb *sb;
-
- struct snd_pcm *pcm;
- struct snd_cmi8330_stream {
- struct snd_pcm_ops ops;
- snd_pcm_open_callback_t open;
- void *private_data; /* sb or wss */
- } streams[2];
-
- enum card_type type;
-};
-
-#ifdef CONFIG_PNP
-
-static struct pnp_card_device_id snd_cmi8330_pnpids[] = {
- { .id = "CMI0001", .devs = { { "@X@0001" }, { "@@@0001" }, { "@H@0001" }, { "A@@0001" } } },
- { .id = "CMI0001", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } } },
- { .id = "" }
-};
-
-MODULE_DEVICE_TABLE(pnp_card, snd_cmi8330_pnpids);
-
-#endif
-
-
-static struct snd_kcontrol_new snd_cmi8330_controls[] __devinitdata = {
-WSS_DOUBLE("Master Playback Volume", 0,
- CMI8330_MASTVOL, CMI8330_MASTVOL, 4, 0, 15, 0),
-WSS_SINGLE("Loud Playback Switch", 0,
- CMI8330_MUTEMUX, 6, 1, 1),
-WSS_DOUBLE("PCM Playback Switch", 0,
- CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
-WSS_DOUBLE("PCM Playback Volume", 0,
- CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1),
-WSS_DOUBLE("Line Playback Switch", 0,
- CMI8330_MUTEMUX, CMI8330_MUTEMUX, 4, 3, 1, 0),
-WSS_DOUBLE("Line Playback Volume", 0,
- CMI8330_LINVOL, CMI8330_LINVOL, 4, 0, 15, 0),
-WSS_DOUBLE("Line Capture Switch", 0,
- CMI8330_RMUX3D, CMI8330_RMUX3D, 2, 1, 1, 0),
-WSS_DOUBLE("Line Capture Volume", 0,
- CMI8330_LINGAIN, CMI8330_LINGAIN, 4, 0, 15, 0),
-WSS_DOUBLE("CD Playback Switch", 0,
- CMI8330_MUTEMUX, CMI8330_MUTEMUX, 2, 1, 1, 0),
-WSS_DOUBLE("CD Capture Switch", 0,
- CMI8330_RMUX3D, CMI8330_RMUX3D, 4, 3, 1, 0),
-WSS_DOUBLE("CD Playback Volume", 0,
- CMI8330_CDINVOL, CMI8330_CDINVOL, 4, 0, 15, 0),
-WSS_DOUBLE("CD Capture Volume", 0,
- CMI8330_CDINGAIN, CMI8330_CDINGAIN, 4, 0, 15, 0),
-WSS_SINGLE("Mic Playback Switch", 0,
- CMI8330_MUTEMUX, 0, 1, 0),
-WSS_SINGLE("Mic Playback Volume", 0,
- CMI8330_OUTPUTVOL, 0, 7, 0),
-WSS_SINGLE("Mic Capture Switch", 0,
- CMI8330_RMUX3D, 0, 1, 0),
-WSS_SINGLE("Mic Capture Volume", 0,
- CMI8330_OUTPUTVOL, 5, 7, 0),
-WSS_DOUBLE("Wavetable Playback Switch", 0,
- CMI8330_RECMUX, CMI8330_RECMUX, 1, 0, 1, 0),
-WSS_DOUBLE("Wavetable Playback Volume", 0,
- CMI8330_WAVVOL, CMI8330_WAVVOL, 4, 0, 15, 0),
-WSS_DOUBLE("Wavetable Capture Switch", 0,
- CMI8330_RECMUX, CMI8330_RECMUX, 5, 4, 1, 0),
-WSS_DOUBLE("Wavetable Capture Volume", 0,
- CMI8330_WAVGAIN, CMI8330_WAVGAIN, 4, 0, 15, 0),
-WSS_SINGLE("3D Control - Switch", 0,
- CMI8330_RMUX3D, 5, 1, 1),
-WSS_SINGLE("Beep Playback Volume", 0,
- CMI8330_OUTPUTVOL, 3, 3, 0),
-WSS_DOUBLE("FM Playback Switch", 0,
- CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
-WSS_DOUBLE("FM Playback Volume", 0,
- CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1),
-WSS_SINGLE(SNDRV_CTL_NAME_IEC958("Input ", CAPTURE, SWITCH), 0,
- CMI8330_RMUX3D, 7, 1, 1),
-WSS_SINGLE(SNDRV_CTL_NAME_IEC958("Input ", PLAYBACK, SWITCH), 0,
- CMI8330_MUTEMUX, 7, 1, 1),
-};
-
-#ifdef ENABLE_SB_MIXER
-static struct sbmix_elem cmi8330_sb_mixers[] __devinitdata = {
-SB_DOUBLE("SB Master Playback Volume", SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31),
-SB_DOUBLE("Tone Control - Bass", SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15),
-SB_DOUBLE("Tone Control - Treble", SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15),
-SB_DOUBLE("SB PCM Playback Volume", SB_DSP4_PCM_DEV, (SB_DSP4_PCM_DEV + 1), 3, 3, 31),
-SB_DOUBLE("SB Synth Playback Volume", SB_DSP4_SYNTH_DEV, (SB_DSP4_SYNTH_DEV + 1), 3, 3, 31),
-SB_DOUBLE("SB CD Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1),
-SB_DOUBLE("SB CD Playback Volume", SB_DSP4_CD_DEV, (SB_DSP4_CD_DEV + 1), 3, 3, 31),
-SB_DOUBLE("SB Line Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1),
-SB_DOUBLE("SB Line Playback Volume", SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31),
-SB_SINGLE("SB Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1),
-SB_SINGLE("SB Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31),
-SB_SINGLE("SB Beep Volume", SB_DSP4_SPEAKER_DEV, 6, 3),
-SB_DOUBLE("SB Capture Volume", SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3),
-SB_DOUBLE("SB Playback Volume", SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3),
-SB_SINGLE("SB Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1),
-};
-
-static unsigned char cmi8330_sb_init_values[][2] __devinitdata = {
- { SB_DSP4_MASTER_DEV + 0, 0 },
- { SB_DSP4_MASTER_DEV + 1, 0 },
- { SB_DSP4_PCM_DEV + 0, 0 },
- { SB_DSP4_PCM_DEV + 1, 0 },
- { SB_DSP4_SYNTH_DEV + 0, 0 },
- { SB_DSP4_SYNTH_DEV + 1, 0 },
- { SB_DSP4_INPUT_LEFT, 0 },
- { SB_DSP4_INPUT_RIGHT, 0 },
- { SB_DSP4_OUTPUT_SW, 0 },
- { SB_DSP4_SPEAKER_DEV, 0 },
-};
-
-
-static int __devinit cmi8330_add_sb_mixers(struct snd_sb *chip)
-{
- int idx, err;
- unsigned long flags;
-
- spin_lock_irqsave(&chip->mixer_lock, flags);
- snd_sbmixer_write(chip, 0x00, 0x00); /* mixer reset */
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
-
- /* mute and zero volume channels */
- for (idx = 0; idx < ARRAY_SIZE(cmi8330_sb_init_values); idx++) {
- spin_lock_irqsave(&chip->mixer_lock, flags);
- snd_sbmixer_write(chip, cmi8330_sb_init_values[idx][0],
- cmi8330_sb_init_values[idx][1]);
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
- }
-
- for (idx = 0; idx < ARRAY_SIZE(cmi8330_sb_mixers); idx++) {
- if ((err = snd_sbmixer_add_ctl_elem(chip, &cmi8330_sb_mixers[idx])) < 0)
- return err;
- }
- return 0;
-}
-#endif
-
-static int __devinit snd_cmi8330_mixer(struct snd_card *card, struct snd_cmi8330 *acard)
-{
- unsigned int idx;
- int err;
-
- strcpy(card->mixername, (acard->type == CMI8329) ? "CMI8329" : "CMI8330/C3D");
-
- for (idx = 0; idx < ARRAY_SIZE(snd_cmi8330_controls); idx++) {
- err = snd_ctl_add(card,
- snd_ctl_new1(&snd_cmi8330_controls[idx],
- acard->wss));
- if (err < 0)
- return err;
- }
-
-#ifdef ENABLE_SB_MIXER
- if ((err = cmi8330_add_sb_mixers(acard->sb)) < 0)
- return err;
-#endif
- return 0;
-}
-
-#ifdef CONFIG_PNP
-static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard,
- struct pnp_card_link *card,
- const struct pnp_card_device_id *id)
-{
- struct pnp_dev *pdev;
- int err;
-
- /* CMI8329 has a device with ID A@@0001, CMI8330 does not */
- acard->type = (id->devs[3].id[0]) ? CMI8329 : CMI8330;
-
- acard->cap = pnp_request_card_device(card, id->devs[0].id, NULL);
- if (acard->cap == NULL)
- return -EBUSY;
-
- acard->play = pnp_request_card_device(card, id->devs[1].id, NULL);
- if (acard->play == NULL)
- return -EBUSY;
-
- acard->mpu = pnp_request_card_device(card, id->devs[2].id, NULL);
- if (acard->mpu == NULL)
- return -EBUSY;
-
- pdev = acard->cap;
-
- err = pnp_activate_dev(pdev);
- if (err < 0) {
- snd_printk(KERN_ERR "AD1848 PnP configure failure\n");
- return -EBUSY;
- }
- wssport[dev] = pnp_port_start(pdev, 0);
- wssdma[dev] = pnp_dma(pdev, 0);
- wssirq[dev] = pnp_irq(pdev, 0);
- if (pnp_port_start(pdev, 1))
- fmport[dev] = pnp_port_start(pdev, 1);
-
- /* allocate SB16 resources */
- pdev = acard->play;
-
- err = pnp_activate_dev(pdev);
- if (err < 0) {
- snd_printk(KERN_ERR "SB16 PnP configure failure\n");
- return -EBUSY;
- }
- sbport[dev] = pnp_port_start(pdev, 0);
- sbdma8[dev] = pnp_dma(pdev, 0);
- sbdma16[dev] = pnp_dma(pdev, 1);
- sbirq[dev] = pnp_irq(pdev, 0);
- /* On CMI8239, the OPL3 port might be present in SB16 PnP resources */
- if (fmport[dev] == SNDRV_AUTO_PORT) {
- if (pnp_port_start(pdev, 1))
- fmport[dev] = pnp_port_start(pdev, 1);
- else
- fmport[dev] = 0x388; /* Or hardwired */
- }
-
- /* allocate MPU-401 resources */
- pdev = acard->mpu;
-
- err = pnp_activate_dev(pdev);
- if (err < 0)
- snd_printk(KERN_ERR "MPU-401 PnP configure failure: will be disabled\n");
- else {
- mpuport[dev] = pnp_port_start(pdev, 0);
- mpuirq[dev] = pnp_irq(pdev, 0);
- }
- return 0;
-}
-#endif
-
-/*
- * PCM interface
- *
- * since we call the different chip interfaces for playback and capture
- * directions, we need a trick.
- *
- * - copy the ops for each direction into a local record.
- * - replace the open callback with the new one, which replaces the
- * substream->private_data with the corresponding chip instance
- * and calls again the original open callback of the chip.
- *
- */
-
-#ifdef PLAYBACK_ON_SB
-#define CMI_SB_STREAM SNDRV_PCM_STREAM_PLAYBACK
-#define CMI_AD_STREAM SNDRV_PCM_STREAM_CAPTURE
-#else
-#define CMI_SB_STREAM SNDRV_PCM_STREAM_CAPTURE
-#define CMI_AD_STREAM SNDRV_PCM_STREAM_PLAYBACK
-#endif
-
-static int snd_cmi8330_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_cmi8330 *chip = snd_pcm_substream_chip(substream);
-
- /* replace the private_data and call the original open callback */
- substream->private_data = chip->streams[SNDRV_PCM_STREAM_PLAYBACK].private_data;
- return chip->streams[SNDRV_PCM_STREAM_PLAYBACK].open(substream);
-}
-
-static int snd_cmi8330_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_cmi8330 *chip = snd_pcm_substream_chip(substream);
-
- /* replace the private_data and call the original open callback */
- substream->private_data = chip->streams[SNDRV_PCM_STREAM_CAPTURE].private_data;
- return chip->streams[SNDRV_PCM_STREAM_CAPTURE].open(substream);
-}
-
-static int __devinit snd_cmi8330_pcm(struct snd_card *card, struct snd_cmi8330 *chip)
-{
- struct snd_pcm *pcm;
- const struct snd_pcm_ops *ops;
- int err;
- static snd_pcm_open_callback_t cmi_open_callbacks[2] = {
- snd_cmi8330_playback_open,
- snd_cmi8330_capture_open
- };
-
- if ((err = snd_pcm_new(card, (chip->type == CMI8329) ? "CMI8329" : "CMI8330", 0, 1, 1, &pcm)) < 0)
- return err;
- strcpy(pcm->name, (chip->type == CMI8329) ? "CMI8329" : "CMI8330");
- pcm->private_data = chip;
-
- /* SB16 */
- ops = snd_sb16dsp_get_pcm_ops(CMI_SB_STREAM);
- chip->streams[CMI_SB_STREAM].ops = *ops;
- chip->streams[CMI_SB_STREAM].open = ops->open;
- chip->streams[CMI_SB_STREAM].ops.open = cmi_open_callbacks[CMI_SB_STREAM];
- chip->streams[CMI_SB_STREAM].private_data = chip->sb;
-
- /* AD1848 */
- ops = snd_wss_get_pcm_ops(CMI_AD_STREAM);
- chip->streams[CMI_AD_STREAM].ops = *ops;
- chip->streams[CMI_AD_STREAM].open = ops->open;
- chip->streams[CMI_AD_STREAM].ops.open = cmi_open_callbacks[CMI_AD_STREAM];
- chip->streams[CMI_AD_STREAM].private_data = chip->wss;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &chip->streams[SNDRV_PCM_STREAM_PLAYBACK].ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &chip->streams[SNDRV_PCM_STREAM_CAPTURE].ops);
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_isa_data(),
- 64*1024, 128*1024);
- chip->pcm = pcm;
-
- return 0;
-}
-
-
-#ifdef CONFIG_PM
-static int snd_cmi8330_suspend(struct snd_card *card)
-{
- struct snd_cmi8330 *acard = card->private_data;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(acard->pcm);
- acard->wss->suspend(acard->wss);
- snd_sbmixer_suspend(acard->sb);
- return 0;
-}
-
-static int snd_cmi8330_resume(struct snd_card *card)
-{
- struct snd_cmi8330 *acard = card->private_data;
-
- snd_sbdsp_reset(acard->sb);
- snd_sbmixer_suspend(acard->sb);
- acard->wss->resume(acard->wss);
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif
-
-
-/*
- */
-
-#ifdef CONFIG_PNP
-#define is_isapnp_selected(dev) isapnp[dev]
-#else
-#define is_isapnp_selected(dev) 0
-#endif
-
-#define PFX "cmi8330: "
-
-static int snd_cmi8330_card_new(int dev, struct snd_card **cardp)
-{
- struct snd_card *card;
- struct snd_cmi8330 *acard;
- int err;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_cmi8330), &card);
- if (err < 0) {
- snd_printk(KERN_ERR PFX "could not get a new card\n");
- return err;
- }
- acard = card->private_data;
- acard->card = card;
- *cardp = card;
- return 0;
-}
-
-static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
-{
- struct snd_cmi8330 *acard;
- int i, err;
- struct snd_opl3 *opl3;
-
- acard = card->private_data;
- err = snd_wss_create(card, wssport[dev] + 4, -1,
- wssirq[dev],
- wssdma[dev], -1,
- WSS_HW_DETECT, 0, &acard->wss);
- if (err < 0) {
- snd_printk(KERN_ERR PFX "AD1848 device busy??\n");
- return err;
- }
- if (acard->wss->hardware != WSS_HW_CMI8330) {
- snd_printk(KERN_ERR PFX "AD1848 not found during probe\n");
- return -ENODEV;
- }
-
- if ((err = snd_sbdsp_create(card, sbport[dev],
- sbirq[dev],
- snd_sb16dsp_interrupt,
- sbdma8[dev],
- sbdma16[dev],
- SB_HW_AUTO, &acard->sb)) < 0) {
- snd_printk(KERN_ERR PFX "SB16 device busy??\n");
- return err;
- }
- if (acard->sb->hardware != SB_HW_16) {
- snd_printk(KERN_ERR PFX "SB16 not found during probe\n");
- return err;
- }
-
- snd_wss_out(acard->wss, CS4231_MISC_INFO, 0x40); /* switch on MODE2 */
- for (i = CMI8330_RMUX3D; i <= CMI8330_CDINGAIN; i++)
- snd_wss_out(acard->wss, i,
- snd_cmi8330_image[i - CMI8330_RMUX3D]);
-
- if ((err = snd_cmi8330_mixer(card, acard)) < 0) {
- snd_printk(KERN_ERR PFX "failed to create mixers\n");
- return err;
- }
-
- if ((err = snd_cmi8330_pcm(card, acard)) < 0) {
- snd_printk(KERN_ERR PFX "failed to create pcms\n");
- return err;
- }
- if (fmport[dev] != SNDRV_AUTO_PORT) {
- if (snd_opl3_create(card,
- fmport[dev], fmport[dev] + 2,
- OPL3_HW_AUTO, 0, &opl3) < 0) {
- snd_printk(KERN_ERR PFX
- "no OPL device at 0x%lx-0x%lx ?\n",
- fmport[dev], fmport[dev] + 2);
- } else {
- err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
- if (err < 0)
- return err;
- }
- }
-
- if (mpuport[dev] != SNDRV_AUTO_PORT) {
- if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
- mpuport[dev], 0, mpuirq[dev],
- NULL) < 0)
- printk(KERN_ERR PFX "no MPU-401 device at 0x%lx.\n",
- mpuport[dev]);
- }
-
- strcpy(card->driver, (acard->type == CMI8329) ? "CMI8329" : "CMI8330/C3D");
- strcpy(card->shortname, (acard->type == CMI8329) ? "C-Media CMI8329" : "C-Media CMI8330/C3D");
- sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
- card->shortname,
- acard->wss->port,
- wssirq[dev],
- wssdma[dev]);
-
- return snd_card_register(card);
-}
-
-static int __devinit snd_cmi8330_isa_match(struct device *pdev,
- unsigned int dev)
-{
- if (!enable[dev] || is_isapnp_selected(dev))
- return 0;
- if (wssport[dev] == SNDRV_AUTO_PORT) {
- snd_printk(KERN_ERR PFX "specify wssport\n");
- return 0;
- }
- if (sbport[dev] == SNDRV_AUTO_PORT) {
- snd_printk(KERN_ERR PFX "specify sbport\n");
- return 0;
- }
- return 1;
-}
-
-static int __devinit snd_cmi8330_isa_probe(struct device *pdev,
- unsigned int dev)
-{
- struct snd_card *card;
- int err;
-
- err = snd_cmi8330_card_new(dev, &card);
- if (err < 0)
- return err;
- snd_card_set_dev(card, pdev);
- if ((err = snd_cmi8330_probe(card, dev)) < 0) {
- snd_card_free(card);
- return err;
- }
- dev_set_drvdata(pdev, card);
- return 0;
-}
-
-static int __devexit snd_cmi8330_isa_remove(struct device *devptr,
- unsigned int dev)
-{
- snd_card_free(dev_get_drvdata(devptr));
- dev_set_drvdata(devptr, NULL);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int snd_cmi8330_isa_suspend(struct device *dev, unsigned int n,
- pm_message_t state)
-{
- return snd_cmi8330_suspend(dev_get_drvdata(dev));
-}
-
-static int snd_cmi8330_isa_resume(struct device *dev, unsigned int n)
-{
- return snd_cmi8330_resume(dev_get_drvdata(dev));
-}
-#endif
-
-#define DEV_NAME "cmi8330"
-
-static struct isa_driver snd_cmi8330_driver = {
- .match = snd_cmi8330_isa_match,
- .probe = snd_cmi8330_isa_probe,
- .remove = __devexit_p(snd_cmi8330_isa_remove),
-#ifdef CONFIG_PM
- .suspend = snd_cmi8330_isa_suspend,
- .resume = snd_cmi8330_isa_resume,
-#endif
- .driver = {
- .name = DEV_NAME
- },
-};
-
-
-#ifdef CONFIG_PNP
-static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard,
- const struct pnp_card_device_id *pid)
-{
- static int dev;
- struct snd_card *card;
- int res;
-
- for ( ; dev < SNDRV_CARDS; dev++) {
- if (enable[dev] && isapnp[dev])
- break;
- }
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
-
- res = snd_cmi8330_card_new(dev, &card);
- if (res < 0)
- return res;
- if ((res = snd_cmi8330_pnp(dev, card->private_data, pcard, pid)) < 0) {
- snd_printk(KERN_ERR PFX "PnP detection failed\n");
- snd_card_free(card);
- return res;
- }
- snd_card_set_dev(card, &pcard->card->dev);
- if ((res = snd_cmi8330_probe(card, dev)) < 0) {
- snd_card_free(card);
- return res;
- }
- pnp_set_card_drvdata(pcard, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_cmi8330_pnp_remove(struct pnp_card_link * pcard)
-{
- snd_card_free(pnp_get_card_drvdata(pcard));
- pnp_set_card_drvdata(pcard, NULL);
-}
-
-#ifdef CONFIG_PM
-static int snd_cmi8330_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
-{
- return snd_cmi8330_suspend(pnp_get_card_drvdata(pcard));
-}
-
-static int snd_cmi8330_pnp_resume(struct pnp_card_link *pcard)
-{
- return snd_cmi8330_resume(pnp_get_card_drvdata(pcard));
-}
-#endif
-
-static struct pnp_card_driver cmi8330_pnpc_driver = {
- .flags = PNP_DRIVER_RES_DISABLE,
- .name = "cmi8330",
- .id_table = snd_cmi8330_pnpids,
- .probe = snd_cmi8330_pnp_detect,
- .remove = __devexit_p(snd_cmi8330_pnp_remove),
-#ifdef CONFIG_PM
- .suspend = snd_cmi8330_pnp_suspend,
- .resume = snd_cmi8330_pnp_resume,
-#endif
-};
-#endif /* CONFIG_PNP */
-
-static int __init alsa_card_cmi8330_init(void)
-{
- int err;
-
- err = isa_register_driver(&snd_cmi8330_driver, SNDRV_CARDS);
-#ifdef CONFIG_PNP
- if (!err)
- isa_registered = 1;
-
- err = pnp_register_card_driver(&cmi8330_pnpc_driver);
- if (!err)
- pnp_registered = 1;
-
- if (isa_registered)
- err = 0;
-#endif
- return err;
-}
-
-static void __exit alsa_card_cmi8330_exit(void)
-{
-#ifdef CONFIG_PNP
- if (pnp_registered)
- pnp_unregister_card_driver(&cmi8330_pnpc_driver);
-
- if (isa_registered)
-#endif
- isa_unregister_driver(&snd_cmi8330_driver);
-}
-
-module_init(alsa_card_cmi8330_init)
-module_exit(alsa_card_cmi8330_exit)
diff --git a/ANDROID_3.4.5/sound/isa/cs423x/Makefile b/ANDROID_3.4.5/sound/isa/cs423x/Makefile
deleted file mode 100644
index 6d397e8d..00000000
--- a/ANDROID_3.4.5/sound/isa/cs423x/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-cs4231-objs := cs4231.o
-snd-cs4236-objs := cs4236.o cs4236_lib.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_CS4231) += snd-cs4231.o
-obj-$(CONFIG_SND_CS4236) += snd-cs4236.o
-
-
diff --git a/ANDROID_3.4.5/sound/isa/cs423x/cs4231.c b/ANDROID_3.4.5/sound/isa/cs423x/cs4231.c
deleted file mode 100644
index 99dda45e..00000000
--- a/ANDROID_3.4.5/sound/isa/cs423x/cs4231.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Generic driver for CS4231 chips
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Originally the CS4232/CS4232A driver, modified for use on CS4231 by
- * Tugrul Galatali <galatalt@stuy.edu>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/isa.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/wss.h>
-#include <sound/mpu401.h>
-#include <sound/initval.h>
-
-#define CRD_NAME "Generic CS4231"
-#define DEV_NAME "cs4231"
-
-MODULE_DESCRIPTION(CRD_NAME);
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4231}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,11,12,15 */
-static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 9,11,12,15 */
-static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
-static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
-module_param_array(mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
-module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
-module_param_array(mpu_irq, int, NULL, 0444);
-MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
-module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver.");
-module_param_array(dma2, int, NULL, 0444);
-MODULE_PARM_DESC(dma2, "DMA2 # for " CRD_NAME " driver.");
-
-static int __devinit snd_cs4231_match(struct device *dev, unsigned int n)
-{
- if (!enable[n])
- return 0;
-
- if (port[n] == SNDRV_AUTO_PORT) {
- dev_err(dev, "please specify port\n");
- return 0;
- }
- if (irq[n] == SNDRV_AUTO_IRQ) {
- dev_err(dev, "please specify irq\n");
- return 0;
- }
- if (dma1[n] == SNDRV_AUTO_DMA) {
- dev_err(dev, "please specify dma1\n");
- return 0;
- }
- return 1;
-}
-
-static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n)
-{
- struct snd_card *card;
- struct snd_wss *chip;
- struct snd_pcm *pcm;
- int error;
-
- error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card);
- if (error < 0)
- return error;
-
- error = snd_wss_create(card, port[n], -1, irq[n], dma1[n], dma2[n],
- WSS_HW_DETECT, 0, &chip);
- if (error < 0)
- goto out;
-
- card->private_data = chip;
-
- error = snd_wss_pcm(chip, 0, &pcm);
- if (error < 0)
- goto out;
-
- strcpy(card->driver, "CS4231");
- strcpy(card->shortname, pcm->name);
-
- sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
- pcm->name, chip->port, irq[n], dma1[n]);
- if (dma2[n] >= 0)
- sprintf(card->longname + strlen(card->longname), "&%d", dma2[n]);
-
- error = snd_wss_mixer(chip);
- if (error < 0)
- goto out;
-
- error = snd_wss_timer(chip, 0, NULL);
- if (error < 0)
- goto out;
-
- if (mpu_port[n] > 0 && mpu_port[n] != SNDRV_AUTO_PORT) {
- if (mpu_irq[n] == SNDRV_AUTO_IRQ)
- mpu_irq[n] = -1;
- if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232,
- mpu_port[n], 0, mpu_irq[n],
- NULL) < 0)
- dev_warn(dev, "MPU401 not detected\n");
- }
-
- snd_card_set_dev(card, dev);
-
- error = snd_card_register(card);
- if (error < 0)
- goto out;
-
- dev_set_drvdata(dev, card);
- return 0;
-
-out: snd_card_free(card);
- return error;
-}
-
-static int __devexit snd_cs4231_remove(struct device *dev, unsigned int n)
-{
- snd_card_free(dev_get_drvdata(dev));
- dev_set_drvdata(dev, NULL);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int snd_cs4231_suspend(struct device *dev, unsigned int n, pm_message_t state)
-{
- struct snd_card *card = dev_get_drvdata(dev);
- struct snd_wss *chip = card->private_data;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- chip->suspend(chip);
- return 0;
-}
-
-static int snd_cs4231_resume(struct device *dev, unsigned int n)
-{
- struct snd_card *card = dev_get_drvdata(dev);
- struct snd_wss *chip = card->private_data;
-
- chip->resume(chip);
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif
-
-static struct isa_driver snd_cs4231_driver = {
- .match = snd_cs4231_match,
- .probe = snd_cs4231_probe,
- .remove = __devexit_p(snd_cs4231_remove),
-#ifdef CONFIG_PM
- .suspend = snd_cs4231_suspend,
- .resume = snd_cs4231_resume,
-#endif
- .driver = {
- .name = DEV_NAME
- }
-};
-
-static int __init alsa_card_cs4231_init(void)
-{
- return isa_register_driver(&snd_cs4231_driver, SNDRV_CARDS);
-}
-
-static void __exit alsa_card_cs4231_exit(void)
-{
- isa_unregister_driver(&snd_cs4231_driver);
-}
-
-module_init(alsa_card_cs4231_init);
-module_exit(alsa_card_cs4231_exit);
diff --git a/ANDROID_3.4.5/sound/isa/cs423x/cs4236.c b/ANDROID_3.4.5/sound/isa/cs423x/cs4236.c
deleted file mode 100644
index 740c51a1..00000000
--- a/ANDROID_3.4.5/sound/isa/cs423x/cs4236.c
+++ /dev/null
@@ -1,728 +0,0 @@
-/*
- * Driver for generic CS4232/CS4235/CS4236/CS4236B/CS4237B/CS4238B/CS4239 chips
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/isa.h>
-#include <linux/pnp.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/wss.h>
-#include <sound/mpu401.h>
-#include <sound/opl3.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Cirrus Logic CS4232-9");
-MODULE_SUPPORTED_DEVICE("{{Turtle Beach,TBS-2000},"
- "{Turtle Beach,Tropez Plus},"
- "{SIC CrystalWave 32},"
- "{Hewlett Packard,Omnibook 5500},"
- "{TerraTec,Maestro 32/96},"
- "{Philips,PCA70PS}},"
- "{{Crystal Semiconductors,CS4235},"
- "{Crystal Semiconductors,CS4236},"
- "{Crystal Semiconductors,CS4237},"
- "{Crystal Semiconductors,CS4238},"
- "{Crystal Semiconductors,CS4239},"
- "{Acer,AW37},"
- "{Acer,AW35/Pro},"
- "{Crystal,3D},"
- "{Crystal Computer,TidalWave128},"
- "{Dell,Optiplex GX1},"
- "{Dell,Workstation 400 sound},"
- "{EliteGroup,P5TX-LA sound},"
- "{Gallant,SC-70P},"
- "{Gateway,E1000 Onboard CS4236B},"
- "{Genius,Sound Maker 3DJ},"
- "{Hewlett Packard,HP6330 sound},"
- "{IBM,PC 300PL sound},"
- "{IBM,Aptiva 2137 E24},"
- "{IBM,IntelliStation M Pro},"
- "{Intel,Marlin Spike Mobo CS4235},"
- "{Intel PR440FX Onboard},"
- "{Guillemot,MaxiSound 16 PnP},"
- "{NewClear,3D},"
- "{TerraTec,AudioSystem EWS64L/XL},"
- "{Typhoon Soundsystem,CS4236B},"
- "{Turtle Beach,Malibu},"
- "{Unknown,Digital PC 5000 Onboard}}");
-
-MODULE_ALIAS("snd_cs4232");
-
-#define IDENT "CS4232+"
-#define DEV_NAME "cs4232+"
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
-#ifdef CONFIG_PNP
-static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
-#endif
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static long cport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;/* PnP setup */
-static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static long sb_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,11,12,15 */
-static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 9,11,12,15 */
-static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
-static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for " IDENT " soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for " IDENT " soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable " IDENT " soundcard.");
-#ifdef CONFIG_PNP
-module_param_array(isapnp, bool, NULL, 0444);
-MODULE_PARM_DESC(isapnp, "ISA PnP detection for specified soundcard.");
-#endif
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for " IDENT " driver.");
-module_param_array(cport, long, NULL, 0444);
-MODULE_PARM_DESC(cport, "Control port # for " IDENT " driver.");
-module_param_array(mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " IDENT " driver.");
-module_param_array(fm_port, long, NULL, 0444);
-MODULE_PARM_DESC(fm_port, "FM port # for " IDENT " driver.");
-module_param_array(sb_port, long, NULL, 0444);
-MODULE_PARM_DESC(sb_port, "SB port # for " IDENT " driver (optional).");
-module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for " IDENT " driver.");
-module_param_array(mpu_irq, int, NULL, 0444);
-MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " IDENT " driver.");
-module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "DMA1 # for " IDENT " driver.");
-module_param_array(dma2, int, NULL, 0444);
-MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver.");
-
-#ifdef CONFIG_PNP
-static int isa_registered;
-static int pnpc_registered;
-static int pnp_registered;
-#endif /* CONFIG_PNP */
-
-struct snd_card_cs4236 {
- struct snd_wss *chip;
- struct resource *res_sb_port;
-#ifdef CONFIG_PNP
- struct pnp_dev *wss;
- struct pnp_dev *ctrl;
- struct pnp_dev *mpu;
-#endif
-};
-
-#ifdef CONFIG_PNP
-
-/*
- * PNP BIOS
- */
-static const struct pnp_device_id snd_cs423x_pnpbiosids[] = {
- { .id = "CSC0100" },
- { .id = "CSC0000" },
- /* Guillemot Turtlebeach something appears to be cs4232 compatible
- * (untested) */
- { .id = "GIM0100" },
- { .id = "" }
-};
-MODULE_DEVICE_TABLE(pnp, snd_cs423x_pnpbiosids);
-
-#define CS423X_ISAPNP_DRIVER "cs4232_isapnp"
-static struct pnp_card_device_id snd_cs423x_pnpids[] = {
- /* Philips PCA70PS */
- { .id = "CSC0d32", .devs = { { "CSC0000" }, { "CSC0010" }, { "PNPb006" } } },
- /* TerraTec Maestro 32/96 (CS4232) */
- { .id = "CSC1a32", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* HP Omnibook 5500 onboard */
- { .id = "CSC4232", .devs = { { "CSC0000" }, { "CSC0002" }, { "CSC0003" } } },
- /* Unnamed CS4236 card (Made in Taiwan) */
- { .id = "CSC4236", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* Turtle Beach TBS-2000 (CS4232) */
- { .id = "CSC7532", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSCb006" } } },
- /* Turtle Beach Tropez Plus (CS4232) */
- { .id = "CSC7632", .devs = { { "CSC0000" }, { "CSC0010" }, { "PNPb006" } } },
- /* SIC CrystalWave 32 (CS4232) */
- { .id = "CSCf032", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* Netfinity 3000 on-board soundcard */
- { .id = "CSCe825", .devs = { { "CSC0100" }, { "CSC0110" }, { "CSC010f" } } },
- /* Intel Marlin Spike Motherboard - CS4235 */
- { .id = "CSC0225", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* Intel Marlin Spike Motherboard (#2) - CS4235 */
- { .id = "CSC0225", .devs = { { "CSC0100" }, { "CSC0110" }, { "CSC0103" } } },
- /* Unknown Intel mainboard - CS4235 */
- { .id = "CSC0225", .devs = { { "CSC0100" }, { "CSC0110" } } },
- /* Genius Sound Maker 3DJ - CS4237B */
- { .id = "CSC0437", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* Digital PC 5000 Onboard - CS4236B */
- { .id = "CSC0735", .devs = { { "CSC0000" }, { "CSC0010" } } },
- /* some unknown CS4236B */
- { .id = "CSC0b35", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* Intel PR440FX Onboard sound */
- { .id = "CSC0b36", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* CS4235 on mainboard without MPU */
- { .id = "CSC1425", .devs = { { "CSC0100" }, { "CSC0110" } } },
- /* Gateway E1000 Onboard CS4236B */
- { .id = "CSC1335", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* HP 6330 Onboard sound */
- { .id = "CSC1525", .devs = { { "CSC0100" }, { "CSC0110" }, { "CSC0103" } } },
- /* Crystal Computer TidalWave128 */
- { .id = "CSC1e37", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* ACER AW37 - CS4235 */
- { .id = "CSC4236", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* build-in soundcard in EliteGroup P5TX-LA motherboard - CS4237B */
- { .id = "CSC4237", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* Crystal 3D - CS4237B */
- { .id = "CSC4336", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* Typhoon Soundsystem PnP - CS4236B */
- { .id = "CSC4536", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* Crystal CX4235-XQ3 EP - CS4235 */
- { .id = "CSC4625", .devs = { { "CSC0100" }, { "CSC0110" }, { "CSC0103" } } },
- /* Crystal Semiconductors CS4237B */
- { .id = "CSC4637", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* NewClear 3D - CX4237B-XQ3 */
- { .id = "CSC4837", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* Dell Optiplex GX1 - CS4236B */
- { .id = "CSC6835", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* Dell P410 motherboard - CS4236B */
- { .id = "CSC6835", .devs = { { "CSC0000" }, { "CSC0010" } } },
- /* Dell Workstation 400 Onboard - CS4236B */
- { .id = "CSC6836", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* Turtle Beach Malibu - CS4237B */
- { .id = "CSC7537", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* CS4235 - onboard */
- { .id = "CSC8025", .devs = { { "CSC0100" }, { "CSC0110" }, { "CSC0103" } } },
- /* IBM Aptiva 2137 E24 Onboard - CS4237B */
- { .id = "CSC8037", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* IBM IntelliStation M Pro motherboard */
- { .id = "CSCc835", .devs = { { "CSC0000" }, { "CSC0010" } } },
- /* Guillemot MaxiSound 16 PnP - CS4236B */
- { .id = "CSC9836", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* Gallant SC-70P */
- { .id = "CSC9837", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* Techmakers MF-4236PW */
- { .id = "CSCa736", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* TerraTec AudioSystem EWS64XL - CS4236B */
- { .id = "CSCa836", .devs = { { "CSCa800" }, { "CSCa810" }, { "CSCa803" } } },
- /* TerraTec AudioSystem EWS64XL - CS4236B */
- { .id = "CSCa836", .devs = { { "CSCa800" }, { "CSCa810" } } },
- /* ACER AW37/Pro - CS4235 */
- { .id = "CSCd925", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* ACER AW35/Pro - CS4237B */
- { .id = "CSCd937", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* CS4235 without MPU401 */
- { .id = "CSCe825", .devs = { { "CSC0100" }, { "CSC0110" } } },
- /* Unknown SiS530 - CS4235 */
- { .id = "CSC4825", .devs = { { "CSC0100" }, { "CSC0110" } } },
- /* IBM IntelliStation M Pro 6898 11U - CS4236B */
- { .id = "CSCe835", .devs = { { "CSC0000" }, { "CSC0010" } } },
- /* IBM PC 300PL Onboard - CS4236B */
- { .id = "CSCe836", .devs = { { "CSC0000" }, { "CSC0010" } } },
- /* Some noname CS4236 based card */
- { .id = "CSCe936", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* CS4236B */
- { .id = "CSCf235", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* CS4236B */
- { .id = "CSCf238", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
- /* --- */
- { .id = "" } /* end */
-};
-
-MODULE_DEVICE_TABLE(pnp_card, snd_cs423x_pnpids);
-
-/* WSS initialization */
-static int __devinit snd_cs423x_pnp_init_wss(int dev, struct pnp_dev *pdev)
-{
- if (pnp_activate_dev(pdev) < 0) {
- printk(KERN_ERR IDENT " WSS PnP configure failed for WSS (out of resources?)\n");
- return -EBUSY;
- }
- port[dev] = pnp_port_start(pdev, 0);
- if (fm_port[dev] > 0)
- fm_port[dev] = pnp_port_start(pdev, 1);
- sb_port[dev] = pnp_port_start(pdev, 2);
- irq[dev] = pnp_irq(pdev, 0);
- dma1[dev] = pnp_dma(pdev, 0);
- dma2[dev] = pnp_dma(pdev, 1) == 4 ? -1 : (int)pnp_dma(pdev, 1);
- snd_printdd("isapnp WSS: wss port=0x%lx, fm port=0x%lx, sb port=0x%lx\n",
- port[dev], fm_port[dev], sb_port[dev]);
- snd_printdd("isapnp WSS: irq=%i, dma1=%i, dma2=%i\n",
- irq[dev], dma1[dev], dma2[dev]);
- return 0;
-}
-
-/* CTRL initialization */
-static int __devinit snd_cs423x_pnp_init_ctrl(int dev, struct pnp_dev *pdev)
-{
- if (pnp_activate_dev(pdev) < 0) {
- printk(KERN_ERR IDENT " CTRL PnP configure failed for WSS (out of resources?)\n");
- return -EBUSY;
- }
- cport[dev] = pnp_port_start(pdev, 0);
- snd_printdd("isapnp CTRL: control port=0x%lx\n", cport[dev]);
- return 0;
-}
-
-/* MPU initialization */
-static int __devinit snd_cs423x_pnp_init_mpu(int dev, struct pnp_dev *pdev)
-{
- if (pnp_activate_dev(pdev) < 0) {
- printk(KERN_ERR IDENT " MPU401 PnP configure failed for WSS (out of resources?)\n");
- mpu_port[dev] = SNDRV_AUTO_PORT;
- mpu_irq[dev] = SNDRV_AUTO_IRQ;
- } else {
- mpu_port[dev] = pnp_port_start(pdev, 0);
- if (mpu_irq[dev] >= 0 &&
- pnp_irq_valid(pdev, 0) && pnp_irq(pdev, 0) >= 0) {
- mpu_irq[dev] = pnp_irq(pdev, 0);
- } else {
- mpu_irq[dev] = -1; /* disable interrupt */
- }
- }
- snd_printdd("isapnp MPU: port=0x%lx, irq=%i\n", mpu_port[dev], mpu_irq[dev]);
- return 0;
-}
-
-static int __devinit snd_card_cs423x_pnp(int dev, struct snd_card_cs4236 *acard,
- struct pnp_dev *pdev,
- struct pnp_dev *cdev)
-{
- acard->wss = pdev;
- if (snd_cs423x_pnp_init_wss(dev, acard->wss) < 0)
- return -EBUSY;
- if (cdev)
- cport[dev] = pnp_port_start(cdev, 0);
- else
- cport[dev] = -1;
- return 0;
-}
-
-static int __devinit snd_card_cs423x_pnpc(int dev, struct snd_card_cs4236 *acard,
- struct pnp_card_link *card,
- const struct pnp_card_device_id *id)
-{
- acard->wss = pnp_request_card_device(card, id->devs[0].id, NULL);
- if (acard->wss == NULL)
- return -EBUSY;
- acard->ctrl = pnp_request_card_device(card, id->devs[1].id, NULL);
- if (acard->ctrl == NULL)
- return -EBUSY;
- if (id->devs[2].id[0]) {
- acard->mpu = pnp_request_card_device(card, id->devs[2].id, NULL);
- if (acard->mpu == NULL)
- return -EBUSY;
- }
-
- /* WSS initialization */
- if (snd_cs423x_pnp_init_wss(dev, acard->wss) < 0)
- return -EBUSY;
-
- /* CTRL initialization */
- if (acard->ctrl && cport[dev] > 0) {
- if (snd_cs423x_pnp_init_ctrl(dev, acard->ctrl) < 0)
- return -EBUSY;
- }
- /* MPU initialization */
- if (acard->mpu && mpu_port[dev] > 0) {
- if (snd_cs423x_pnp_init_mpu(dev, acard->mpu) < 0)
- return -EBUSY;
- }
- return 0;
-}
-#endif /* CONFIG_PNP */
-
-#ifdef CONFIG_PNP
-#define is_isapnp_selected(dev) isapnp[dev]
-#else
-#define is_isapnp_selected(dev) 0
-#endif
-
-static void snd_card_cs4236_free(struct snd_card *card)
-{
- struct snd_card_cs4236 *acard = card->private_data;
-
- release_and_free_resource(acard->res_sb_port);
-}
-
-static int snd_cs423x_card_new(int dev, struct snd_card **cardp)
-{
- struct snd_card *card;
- int err;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_card_cs4236), &card);
- if (err < 0)
- return err;
- card->private_free = snd_card_cs4236_free;
- *cardp = card;
- return 0;
-}
-
-static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
-{
- struct snd_card_cs4236 *acard;
- struct snd_pcm *pcm;
- struct snd_wss *chip;
- struct snd_opl3 *opl3;
- int err;
-
- acard = card->private_data;
- if (sb_port[dev] > 0 && sb_port[dev] != SNDRV_AUTO_PORT)
- if ((acard->res_sb_port = request_region(sb_port[dev], 16, IDENT " SB")) == NULL) {
- printk(KERN_ERR IDENT ": unable to register SB port at 0x%lx\n", sb_port[dev]);
- return -EBUSY;
- }
-
- err = snd_cs4236_create(card, port[dev], cport[dev],
- irq[dev],
- dma1[dev], dma2[dev],
- WSS_HW_DETECT3, 0, &chip);
- if (err < 0)
- return err;
-
- acard->chip = chip;
- if (chip->hardware & WSS_HW_CS4236B_MASK) {
-
- err = snd_cs4236_pcm(chip, 0, &pcm);
- if (err < 0)
- return err;
-
- err = snd_cs4236_mixer(chip);
- if (err < 0)
- return err;
- } else {
- err = snd_wss_pcm(chip, 0, &pcm);
- if (err < 0)
- return err;
-
- err = snd_wss_mixer(chip);
- if (err < 0)
- return err;
- }
- strcpy(card->driver, pcm->name);
- strcpy(card->shortname, pcm->name);
- sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i",
- pcm->name,
- chip->port,
- irq[dev],
- dma1[dev]);
- if (dma2[dev] >= 0)
- sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]);
-
- err = snd_wss_timer(chip, 0, NULL);
- if (err < 0)
- return err;
-
- if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
- if (snd_opl3_create(card,
- fm_port[dev], fm_port[dev] + 2,
- OPL3_HW_OPL3_CS, 0, &opl3) < 0) {
- printk(KERN_WARNING IDENT ": OPL3 not detected\n");
- } else {
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
- return err;
- }
- }
-
- if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
- if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
- mpu_irq[dev] = -1;
- if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232,
- mpu_port[dev], 0,
- mpu_irq[dev], NULL) < 0)
- printk(KERN_WARNING IDENT ": MPU401 not detected\n");
- }
-
- return snd_card_register(card);
-}
-
-static int __devinit snd_cs423x_isa_match(struct device *pdev,
- unsigned int dev)
-{
- if (!enable[dev] || is_isapnp_selected(dev))
- return 0;
-
- if (port[dev] == SNDRV_AUTO_PORT) {
- dev_err(pdev, "please specify port\n");
- return 0;
- }
- if (cport[dev] == SNDRV_AUTO_PORT) {
- dev_err(pdev, "please specify cport\n");
- return 0;
- }
- if (irq[dev] == SNDRV_AUTO_IRQ) {
- dev_err(pdev, "please specify irq\n");
- return 0;
- }
- if (dma1[dev] == SNDRV_AUTO_DMA) {
- dev_err(pdev, "please specify dma1\n");
- return 0;
- }
- return 1;
-}
-
-static int __devinit snd_cs423x_isa_probe(struct device *pdev,
- unsigned int dev)
-{
- struct snd_card *card;
- int err;
-
- err = snd_cs423x_card_new(dev, &card);
- if (err < 0)
- return err;
- snd_card_set_dev(card, pdev);
- if ((err = snd_cs423x_probe(card, dev)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- dev_set_drvdata(pdev, card);
- return 0;
-}
-
-static int __devexit snd_cs423x_isa_remove(struct device *pdev,
- unsigned int dev)
-{
- snd_card_free(dev_get_drvdata(pdev));
- dev_set_drvdata(pdev, NULL);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int snd_cs423x_suspend(struct snd_card *card)
-{
- struct snd_card_cs4236 *acard = card->private_data;
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- acard->chip->suspend(acard->chip);
- return 0;
-}
-
-static int snd_cs423x_resume(struct snd_card *card)
-{
- struct snd_card_cs4236 *acard = card->private_data;
- acard->chip->resume(acard->chip);
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-
-static int snd_cs423x_isa_suspend(struct device *dev, unsigned int n,
- pm_message_t state)
-{
- return snd_cs423x_suspend(dev_get_drvdata(dev));
-}
-
-static int snd_cs423x_isa_resume(struct device *dev, unsigned int n)
-{
- return snd_cs423x_resume(dev_get_drvdata(dev));
-}
-#endif
-
-static struct isa_driver cs423x_isa_driver = {
- .match = snd_cs423x_isa_match,
- .probe = snd_cs423x_isa_probe,
- .remove = __devexit_p(snd_cs423x_isa_remove),
-#ifdef CONFIG_PM
- .suspend = snd_cs423x_isa_suspend,
- .resume = snd_cs423x_isa_resume,
-#endif
- .driver = {
- .name = DEV_NAME
- },
-};
-
-
-#ifdef CONFIG_PNP
-static int __devinit snd_cs423x_pnpbios_detect(struct pnp_dev *pdev,
- const struct pnp_device_id *id)
-{
- static int dev;
- int err;
- struct snd_card *card;
- struct pnp_dev *cdev;
- char cid[PNP_ID_LEN];
-
- if (pnp_device_is_isapnp(pdev))
- return -ENOENT; /* we have another procedure - card */
- for (; dev < SNDRV_CARDS; dev++) {
- if (enable[dev] && isapnp[dev])
- break;
- }
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
-
- /* prepare second id */
- strcpy(cid, pdev->id[0].id);
- cid[5] = '1';
- cdev = NULL;
- list_for_each_entry(cdev, &(pdev->protocol->devices), protocol_list) {
- if (!strcmp(cdev->id[0].id, cid))
- break;
- }
- err = snd_cs423x_card_new(dev, &card);
- if (err < 0)
- return err;
- err = snd_card_cs423x_pnp(dev, card->private_data, pdev, cdev);
- if (err < 0) {
- printk(KERN_ERR "PnP BIOS detection failed for " IDENT "\n");
- snd_card_free(card);
- return err;
- }
- snd_card_set_dev(card, &pdev->dev);
- if ((err = snd_cs423x_probe(card, dev)) < 0) {
- snd_card_free(card);
- return err;
- }
- pnp_set_drvdata(pdev, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_cs423x_pnp_remove(struct pnp_dev *pdev)
-{
- snd_card_free(pnp_get_drvdata(pdev));
- pnp_set_drvdata(pdev, NULL);
-}
-
-#ifdef CONFIG_PM
-static int snd_cs423x_pnp_suspend(struct pnp_dev *pdev, pm_message_t state)
-{
- return snd_cs423x_suspend(pnp_get_drvdata(pdev));
-}
-
-static int snd_cs423x_pnp_resume(struct pnp_dev *pdev)
-{
- return snd_cs423x_resume(pnp_get_drvdata(pdev));
-}
-#endif
-
-static struct pnp_driver cs423x_pnp_driver = {
- .name = "cs423x-pnpbios",
- .id_table = snd_cs423x_pnpbiosids,
- .probe = snd_cs423x_pnpbios_detect,
- .remove = __devexit_p(snd_cs423x_pnp_remove),
-#ifdef CONFIG_PM
- .suspend = snd_cs423x_pnp_suspend,
- .resume = snd_cs423x_pnp_resume,
-#endif
-};
-
-static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard,
- const struct pnp_card_device_id *pid)
-{
- static int dev;
- struct snd_card *card;
- int res;
-
- for ( ; dev < SNDRV_CARDS; dev++) {
- if (enable[dev] && isapnp[dev])
- break;
- }
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
-
- res = snd_cs423x_card_new(dev, &card);
- if (res < 0)
- return res;
- if ((res = snd_card_cs423x_pnpc(dev, card->private_data, pcard, pid)) < 0) {
- printk(KERN_ERR "isapnp detection failed and probing for " IDENT
- " is not supported\n");
- snd_card_free(card);
- return res;
- }
- snd_card_set_dev(card, &pcard->card->dev);
- if ((res = snd_cs423x_probe(card, dev)) < 0) {
- snd_card_free(card);
- return res;
- }
- pnp_set_card_drvdata(pcard, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_cs423x_pnpc_remove(struct pnp_card_link * pcard)
-{
- snd_card_free(pnp_get_card_drvdata(pcard));
- pnp_set_card_drvdata(pcard, NULL);
-}
-
-#ifdef CONFIG_PM
-static int snd_cs423x_pnpc_suspend(struct pnp_card_link *pcard, pm_message_t state)
-{
- return snd_cs423x_suspend(pnp_get_card_drvdata(pcard));
-}
-
-static int snd_cs423x_pnpc_resume(struct pnp_card_link *pcard)
-{
- return snd_cs423x_resume(pnp_get_card_drvdata(pcard));
-}
-#endif
-
-static struct pnp_card_driver cs423x_pnpc_driver = {
- .flags = PNP_DRIVER_RES_DISABLE,
- .name = CS423X_ISAPNP_DRIVER,
- .id_table = snd_cs423x_pnpids,
- .probe = snd_cs423x_pnpc_detect,
- .remove = __devexit_p(snd_cs423x_pnpc_remove),
-#ifdef CONFIG_PM
- .suspend = snd_cs423x_pnpc_suspend,
- .resume = snd_cs423x_pnpc_resume,
-#endif
-};
-#endif /* CONFIG_PNP */
-
-static int __init alsa_card_cs423x_init(void)
-{
- int err;
-
- err = isa_register_driver(&cs423x_isa_driver, SNDRV_CARDS);
-#ifdef CONFIG_PNP
- if (!err)
- isa_registered = 1;
- err = pnp_register_driver(&cs423x_pnp_driver);
- if (!err)
- pnp_registered = 1;
- err = pnp_register_card_driver(&cs423x_pnpc_driver);
- if (!err)
- pnpc_registered = 1;
- if (pnp_registered)
- err = 0;
- if (isa_registered)
- err = 0;
-#endif
- return err;
-}
-
-static void __exit alsa_card_cs423x_exit(void)
-{
-#ifdef CONFIG_PNP
- if (pnpc_registered)
- pnp_unregister_card_driver(&cs423x_pnpc_driver);
- if (pnp_registered)
- pnp_unregister_driver(&cs423x_pnp_driver);
- if (isa_registered)
-#endif
- isa_unregister_driver(&cs423x_isa_driver);
-}
-
-module_init(alsa_card_cs423x_init)
-module_exit(alsa_card_cs423x_exit)
diff --git a/ANDROID_3.4.5/sound/isa/cs423x/cs4236_lib.c b/ANDROID_3.4.5/sound/isa/cs423x/cs4236_lib.c
deleted file mode 100644
index c5adca30..00000000
--- a/ANDROID_3.4.5/sound/isa/cs423x/cs4236_lib.c
+++ /dev/null
@@ -1,1089 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Routines for control of CS4235/4236B/4237B/4238B/4239 chips
- *
- * Note:
- * -----
- *
- * Bugs:
- * -----
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- * Indirect control registers (CS4236B+)
- *
- * C0
- * D8: WSS reset (all chips)
- *
- * C1 (all chips except CS4236)
- * D7-D5: version
- * D4-D0: chip id
- * 11101 - CS4235
- * 01011 - CS4236B
- * 01000 - CS4237B
- * 01001 - CS4238B
- * 11110 - CS4239
- *
- * C2
- * D7-D4: 3D Space (CS4235,CS4237B,CS4238B,CS4239)
- * D3-D0: 3D Center (CS4237B); 3D Volume (CS4238B)
- *
- * C3
- * D7: 3D Enable (CS4237B)
- * D6: 3D Mono Enable (CS4237B)
- * D5: 3D Serial Output (CS4237B,CS4238B)
- * D4: 3D Enable (CS4235,CS4238B,CS4239)
- *
- * C4
- * D7: consumer serial port enable (CS4237B,CS4238B)
- * D6: channels status block reset (CS4237B,CS4238B)
- * D5: user bit in sub-frame of digital audio data (CS4237B,CS4238B)
- * D4: validity bit bit in sub-frame of digital audio data (CS4237B,CS4238B)
- *
- * C5 lower channel status (digital serial data description) (CS4237B,CS4238B)
- * D7-D6: first two bits of category code
- * D5: lock
- * D4-D3: pre-emphasis (0 = none, 1 = 50/15us)
- * D2: copy/copyright (0 = copy inhibited)
- * D1: 0 = digital audio / 1 = non-digital audio
- *
- * C6 upper channel status (digital serial data description) (CS4237B,CS4238B)
- * D7-D6: sample frequency (0 = 44.1kHz)
- * D5: generation status (0 = no indication, 1 = original/commercially precaptureed data)
- * D4-D0: category code (upper bits)
- *
- * C7 reserved (must write 0)
- *
- * C8 wavetable control
- * D7: volume control interrupt enable (CS4235,CS4239)
- * D6: hardware volume control format (CS4235,CS4239)
- * D3: wavetable serial port enable (all chips)
- * D2: DSP serial port switch (all chips)
- * D1: disable MCLK (all chips)
- * D0: force BRESET low (all chips)
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <sound/core.h>
-#include <sound/wss.h>
-#include <sound/asoundef.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-/*
- *
- */
-
-static unsigned char snd_cs4236_ext_map[18] = {
- /* CS4236_LEFT_LINE */ 0xff,
- /* CS4236_RIGHT_LINE */ 0xff,
- /* CS4236_LEFT_MIC */ 0xdf,
- /* CS4236_RIGHT_MIC */ 0xdf,
- /* CS4236_LEFT_MIX_CTRL */ 0xe0 | 0x18,
- /* CS4236_RIGHT_MIX_CTRL */ 0xe0,
- /* CS4236_LEFT_FM */ 0xbf,
- /* CS4236_RIGHT_FM */ 0xbf,
- /* CS4236_LEFT_DSP */ 0xbf,
- /* CS4236_RIGHT_DSP */ 0xbf,
- /* CS4236_RIGHT_LOOPBACK */ 0xbf,
- /* CS4236_DAC_MUTE */ 0xe0,
- /* CS4236_ADC_RATE */ 0x01, /* 48kHz */
- /* CS4236_DAC_RATE */ 0x01, /* 48kHz */
- /* CS4236_LEFT_MASTER */ 0xbf,
- /* CS4236_RIGHT_MASTER */ 0xbf,
- /* CS4236_LEFT_WAVE */ 0xbf,
- /* CS4236_RIGHT_WAVE */ 0xbf
-};
-
-/*
- *
- */
-
-static void snd_cs4236_ctrl_out(struct snd_wss *chip,
- unsigned char reg, unsigned char val)
-{
- outb(reg, chip->cport + 3);
- outb(chip->cimage[reg] = val, chip->cport + 4);
-}
-
-static unsigned char snd_cs4236_ctrl_in(struct snd_wss *chip, unsigned char reg)
-{
- outb(reg, chip->cport + 3);
- return inb(chip->cport + 4);
-}
-
-/*
- * PCM
- */
-
-#define CLOCKS 8
-
-static struct snd_ratnum clocks[CLOCKS] = {
- { .num = 16934400, .den_min = 353, .den_max = 353, .den_step = 1 },
- { .num = 16934400, .den_min = 529, .den_max = 529, .den_step = 1 },
- { .num = 16934400, .den_min = 617, .den_max = 617, .den_step = 1 },
- { .num = 16934400, .den_min = 1058, .den_max = 1058, .den_step = 1 },
- { .num = 16934400, .den_min = 1764, .den_max = 1764, .den_step = 1 },
- { .num = 16934400, .den_min = 2117, .den_max = 2117, .den_step = 1 },
- { .num = 16934400, .den_min = 2558, .den_max = 2558, .den_step = 1 },
- { .num = 16934400/16, .den_min = 21, .den_max = 192, .den_step = 1 }
-};
-
-static struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks = {
- .nrats = CLOCKS,
- .rats = clocks,
-};
-
-static int snd_cs4236_xrate(struct snd_pcm_runtime *runtime)
-{
- return snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &hw_constraints_clocks);
-}
-
-static unsigned char divisor_to_rate_register(unsigned int divisor)
-{
- switch (divisor) {
- case 353: return 1;
- case 529: return 2;
- case 617: return 3;
- case 1058: return 4;
- case 1764: return 5;
- case 2117: return 6;
- case 2558: return 7;
- default:
- if (divisor < 21 || divisor > 192) {
- snd_BUG();
- return 192;
- }
- return divisor;
- }
-}
-
-static void snd_cs4236_playback_format(struct snd_wss *chip,
- struct snd_pcm_hw_params *params,
- unsigned char pdfr)
-{
- unsigned long flags;
- unsigned char rate = divisor_to_rate_register(params->rate_den);
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- /* set fast playback format change and clean playback FIFO */
- snd_wss_out(chip, CS4231_ALT_FEATURE_1,
- chip->image[CS4231_ALT_FEATURE_1] | 0x10);
- snd_wss_out(chip, CS4231_PLAYBK_FORMAT, pdfr & 0xf0);
- snd_wss_out(chip, CS4231_ALT_FEATURE_1,
- chip->image[CS4231_ALT_FEATURE_1] & ~0x10);
- snd_cs4236_ext_out(chip, CS4236_DAC_RATE, rate);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-
-static void snd_cs4236_capture_format(struct snd_wss *chip,
- struct snd_pcm_hw_params *params,
- unsigned char cdfr)
-{
- unsigned long flags;
- unsigned char rate = divisor_to_rate_register(params->rate_den);
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- /* set fast capture format change and clean capture FIFO */
- snd_wss_out(chip, CS4231_ALT_FEATURE_1,
- chip->image[CS4231_ALT_FEATURE_1] | 0x20);
- snd_wss_out(chip, CS4231_REC_FORMAT, cdfr & 0xf0);
- snd_wss_out(chip, CS4231_ALT_FEATURE_1,
- chip->image[CS4231_ALT_FEATURE_1] & ~0x20);
- snd_cs4236_ext_out(chip, CS4236_ADC_RATE, rate);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-
-#ifdef CONFIG_PM
-
-static void snd_cs4236_suspend(struct snd_wss *chip)
-{
- int reg;
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- for (reg = 0; reg < 32; reg++)
- chip->image[reg] = snd_wss_in(chip, reg);
- for (reg = 0; reg < 18; reg++)
- chip->eimage[reg] = snd_cs4236_ext_in(chip, CS4236_I23VAL(reg));
- for (reg = 2; reg < 9; reg++)
- chip->cimage[reg] = snd_cs4236_ctrl_in(chip, reg);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-
-static void snd_cs4236_resume(struct snd_wss *chip)
-{
- int reg;
- unsigned long flags;
-
- snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- for (reg = 0; reg < 32; reg++) {
- switch (reg) {
- case CS4236_EXT_REG:
- case CS4231_VERSION:
- case 27: /* why? CS4235 - master left */
- case 29: /* why? CS4235 - master right */
- break;
- default:
- snd_wss_out(chip, reg, chip->image[reg]);
- break;
- }
- }
- for (reg = 0; reg < 18; reg++)
- snd_cs4236_ext_out(chip, CS4236_I23VAL(reg), chip->eimage[reg]);
- for (reg = 2; reg < 9; reg++) {
- switch (reg) {
- case 7:
- break;
- default:
- snd_cs4236_ctrl_out(chip, reg, chip->cimage[reg]);
- }
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- snd_wss_mce_down(chip);
-}
-
-#endif /* CONFIG_PM */
-/*
- * This function does no fail if the chip is not CS4236B or compatible.
- * It just an equivalent to the snd_wss_create() then.
- */
-int snd_cs4236_create(struct snd_card *card,
- unsigned long port,
- unsigned long cport,
- int irq, int dma1, int dma2,
- unsigned short hardware,
- unsigned short hwshare,
- struct snd_wss **rchip)
-{
- struct snd_wss *chip;
- unsigned char ver1, ver2;
- unsigned int reg;
- int err;
-
- *rchip = NULL;
- if (hardware == WSS_HW_DETECT)
- hardware = WSS_HW_DETECT3;
-
- err = snd_wss_create(card, port, cport,
- irq, dma1, dma2, hardware, hwshare, &chip);
- if (err < 0)
- return err;
-
- if ((chip->hardware & WSS_HW_CS4236B_MASK) == 0) {
- snd_printd("chip is not CS4236+, hardware=0x%x\n",
- chip->hardware);
- *rchip = chip;
- return 0;
- }
-#if 0
- {
- int idx;
- for (idx = 0; idx < 8; idx++)
- snd_printk(KERN_DEBUG "CD%i = 0x%x\n",
- idx, inb(chip->cport + idx));
- for (idx = 0; idx < 9; idx++)
- snd_printk(KERN_DEBUG "C%i = 0x%x\n",
- idx, snd_cs4236_ctrl_in(chip, idx));
- }
-#endif
- if (cport < 0x100 || cport == SNDRV_AUTO_PORT) {
- snd_printk(KERN_ERR "please, specify control port "
- "for CS4236+ chips\n");
- snd_device_free(card, chip);
- return -ENODEV;
- }
- ver1 = snd_cs4236_ctrl_in(chip, 1);
- ver2 = snd_cs4236_ext_in(chip, CS4236_VERSION);
- snd_printdd("CS4236: [0x%lx] C1 (version) = 0x%x, ext = 0x%x\n",
- cport, ver1, ver2);
- if (ver1 != ver2) {
- snd_printk(KERN_ERR "CS4236+ chip detected, but "
- "control port 0x%lx is not valid\n", cport);
- snd_device_free(card, chip);
- return -ENODEV;
- }
- snd_cs4236_ctrl_out(chip, 0, 0x00);
- snd_cs4236_ctrl_out(chip, 2, 0xff);
- snd_cs4236_ctrl_out(chip, 3, 0x00);
- snd_cs4236_ctrl_out(chip, 4, 0x80);
- reg = ((IEC958_AES1_CON_PCM_CODER & 3) << 6) |
- IEC958_AES0_CON_EMPHASIS_NONE;
- snd_cs4236_ctrl_out(chip, 5, reg);
- snd_cs4236_ctrl_out(chip, 6, IEC958_AES1_CON_PCM_CODER >> 2);
- snd_cs4236_ctrl_out(chip, 7, 0x00);
- /*
- * 0x8c for C8 is valid for Turtle Beach Malibu - the IEC-958
- * output is working with this setup, other hardware should
- * have different signal paths and this value should be
- * selectable in the future
- */
- snd_cs4236_ctrl_out(chip, 8, 0x8c);
- chip->rate_constraint = snd_cs4236_xrate;
- chip->set_playback_format = snd_cs4236_playback_format;
- chip->set_capture_format = snd_cs4236_capture_format;
-#ifdef CONFIG_PM
- chip->suspend = snd_cs4236_suspend;
- chip->resume = snd_cs4236_resume;
-#endif
-
- /* initialize extended registers */
- for (reg = 0; reg < sizeof(snd_cs4236_ext_map); reg++)
- snd_cs4236_ext_out(chip, CS4236_I23VAL(reg),
- snd_cs4236_ext_map[reg]);
-
- /* initialize compatible but more featured registers */
- snd_wss_out(chip, CS4231_LEFT_INPUT, 0x40);
- snd_wss_out(chip, CS4231_RIGHT_INPUT, 0x40);
- snd_wss_out(chip, CS4231_AUX1_LEFT_INPUT, 0xff);
- snd_wss_out(chip, CS4231_AUX1_RIGHT_INPUT, 0xff);
- snd_wss_out(chip, CS4231_AUX2_LEFT_INPUT, 0xdf);
- snd_wss_out(chip, CS4231_AUX2_RIGHT_INPUT, 0xdf);
- snd_wss_out(chip, CS4231_RIGHT_LINE_IN, 0xff);
- snd_wss_out(chip, CS4231_LEFT_LINE_IN, 0xff);
- snd_wss_out(chip, CS4231_RIGHT_LINE_IN, 0xff);
- switch (chip->hardware) {
- case WSS_HW_CS4235:
- case WSS_HW_CS4239:
- snd_wss_out(chip, CS4235_LEFT_MASTER, 0xff);
- snd_wss_out(chip, CS4235_RIGHT_MASTER, 0xff);
- break;
- }
-
- *rchip = chip;
- return 0;
-}
-
-int snd_cs4236_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- err = snd_wss_pcm(chip, device, &pcm);
- if (err < 0)
- return err;
- pcm->info_flags &= ~SNDRV_PCM_INFO_JOINT_DUPLEX;
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-/*
- * MIXER
- */
-
-#define CS4236_SINGLE(xname, xindex, reg, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_cs4236_info_single, \
- .get = snd_cs4236_get_single, .put = snd_cs4236_put_single, \
- .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
-
-#define CS4236_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .info = snd_cs4236_info_single, \
- .get = snd_cs4236_get_single, .put = snd_cs4236_put_single, \
- .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \
- .tlv = { .p = (xtlv) } }
-
-static int snd_cs4236_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 16) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_cs4236_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- ucontrol->value.integer.value[0] = (chip->eimage[CS4236_REG(reg)] >> shift) & mask;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (invert)
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- return 0;
-}
-
-static int snd_cs4236_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
- int change;
- unsigned short val;
-
- val = (ucontrol->value.integer.value[0] & mask);
- if (invert)
- val = mask - val;
- val <<= shift;
- spin_lock_irqsave(&chip->reg_lock, flags);
- val = (chip->eimage[CS4236_REG(reg)] & ~(mask << shift)) | val;
- change = val != chip->eimage[CS4236_REG(reg)];
- snd_cs4236_ext_out(chip, reg, val);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return change;
-}
-
-#define CS4236_SINGLEC(xname, xindex, reg, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_cs4236_info_single, \
- .get = snd_cs4236_get_singlec, .put = snd_cs4236_put_singlec, \
- .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
-
-static int snd_cs4236_get_singlec(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- ucontrol->value.integer.value[0] = (chip->cimage[reg] >> shift) & mask;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (invert)
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- return 0;
-}
-
-static int snd_cs4236_put_singlec(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
- int change;
- unsigned short val;
-
- val = (ucontrol->value.integer.value[0] & mask);
- if (invert)
- val = mask - val;
- val <<= shift;
- spin_lock_irqsave(&chip->reg_lock, flags);
- val = (chip->cimage[reg] & ~(mask << shift)) | val;
- change = val != chip->cimage[reg];
- snd_cs4236_ctrl_out(chip, reg, val);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return change;
-}
-
-#define CS4236_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_cs4236_info_double, \
- .get = snd_cs4236_get_double, .put = snd_cs4236_put_double, \
- .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
-
-#define CS4236_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, \
- shift_right, mask, invert, xtlv) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .info = snd_cs4236_info_double, \
- .get = snd_cs4236_get_double, .put = snd_cs4236_put_double, \
- .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \
- (shift_right << 19) | (mask << 24) | (invert << 22), \
- .tlv = { .p = (xtlv) } }
-
-static int snd_cs4236_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 24) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_cs4236_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int shift_left = (kcontrol->private_value >> 16) & 0x07;
- int shift_right = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- ucontrol->value.integer.value[0] = (chip->eimage[CS4236_REG(left_reg)] >> shift_left) & mask;
- ucontrol->value.integer.value[1] = (chip->eimage[CS4236_REG(right_reg)] >> shift_right) & mask;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (invert) {
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
- }
- return 0;
-}
-
-static int snd_cs4236_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int shift_left = (kcontrol->private_value >> 16) & 0x07;
- int shift_right = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
- int change;
- unsigned short val1, val2;
-
- val1 = ucontrol->value.integer.value[0] & mask;
- val2 = ucontrol->value.integer.value[1] & mask;
- if (invert) {
- val1 = mask - val1;
- val2 = mask - val2;
- }
- val1 <<= shift_left;
- val2 <<= shift_right;
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (left_reg != right_reg) {
- val1 = (chip->eimage[CS4236_REG(left_reg)] & ~(mask << shift_left)) | val1;
- val2 = (chip->eimage[CS4236_REG(right_reg)] & ~(mask << shift_right)) | val2;
- change = val1 != chip->eimage[CS4236_REG(left_reg)] || val2 != chip->eimage[CS4236_REG(right_reg)];
- snd_cs4236_ext_out(chip, left_reg, val1);
- snd_cs4236_ext_out(chip, right_reg, val2);
- } else {
- val1 = (chip->eimage[CS4236_REG(left_reg)] & ~((mask << shift_left) | (mask << shift_right))) | val1 | val2;
- change = val1 != chip->eimage[CS4236_REG(left_reg)];
- snd_cs4236_ext_out(chip, left_reg, val1);
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return change;
-}
-
-#define CS4236_DOUBLE1(xname, xindex, left_reg, right_reg, shift_left, \
- shift_right, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_cs4236_info_double, \
- .get = snd_cs4236_get_double1, .put = snd_cs4236_put_double1, \
- .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
-
-#define CS4236_DOUBLE1_TLV(xname, xindex, left_reg, right_reg, shift_left, \
- shift_right, mask, invert, xtlv) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .info = snd_cs4236_info_double, \
- .get = snd_cs4236_get_double1, .put = snd_cs4236_put_double1, \
- .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \
- (shift_right << 19) | (mask << 24) | (invert << 22), \
- .tlv = { .p = (xtlv) } }
-
-static int snd_cs4236_get_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int shift_left = (kcontrol->private_value >> 16) & 0x07;
- int shift_right = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask;
- ucontrol->value.integer.value[1] = (chip->eimage[CS4236_REG(right_reg)] >> shift_right) & mask;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (invert) {
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
- }
- return 0;
-}
-
-static int snd_cs4236_put_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int shift_left = (kcontrol->private_value >> 16) & 0x07;
- int shift_right = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
- int change;
- unsigned short val1, val2;
-
- val1 = ucontrol->value.integer.value[0] & mask;
- val2 = ucontrol->value.integer.value[1] & mask;
- if (invert) {
- val1 = mask - val1;
- val2 = mask - val2;
- }
- val1 <<= shift_left;
- val2 <<= shift_right;
- spin_lock_irqsave(&chip->reg_lock, flags);
- val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
- val2 = (chip->eimage[CS4236_REG(right_reg)] & ~(mask << shift_right)) | val2;
- change = val1 != chip->image[left_reg] || val2 != chip->eimage[CS4236_REG(right_reg)];
- snd_wss_out(chip, left_reg, val1);
- snd_cs4236_ext_out(chip, right_reg, val2);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return change;
-}
-
-#define CS4236_MASTER_DIGITAL(xname, xindex, xtlv) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .info = snd_cs4236_info_double, \
- .get = snd_cs4236_get_master_digital, .put = snd_cs4236_put_master_digital, \
- .private_value = 71 << 24, \
- .tlv = { .p = (xtlv) } }
-
-static inline int snd_cs4236_mixer_master_digital_invert_volume(int vol)
-{
- return (vol < 64) ? 63 - vol : 64 + (71 - vol);
-}
-
-static int snd_cs4236_get_master_digital(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- ucontrol->value.integer.value[0] = snd_cs4236_mixer_master_digital_invert_volume(chip->eimage[CS4236_REG(CS4236_LEFT_MASTER)] & 0x7f);
- ucontrol->value.integer.value[1] = snd_cs4236_mixer_master_digital_invert_volume(chip->eimage[CS4236_REG(CS4236_RIGHT_MASTER)] & 0x7f);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
-}
-
-static int snd_cs4236_put_master_digital(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int change;
- unsigned short val1, val2;
-
- val1 = snd_cs4236_mixer_master_digital_invert_volume(ucontrol->value.integer.value[0] & 0x7f);
- val2 = snd_cs4236_mixer_master_digital_invert_volume(ucontrol->value.integer.value[1] & 0x7f);
- spin_lock_irqsave(&chip->reg_lock, flags);
- val1 = (chip->eimage[CS4236_REG(CS4236_LEFT_MASTER)] & ~0x7f) | val1;
- val2 = (chip->eimage[CS4236_REG(CS4236_RIGHT_MASTER)] & ~0x7f) | val2;
- change = val1 != chip->eimage[CS4236_REG(CS4236_LEFT_MASTER)] || val2 != chip->eimage[CS4236_REG(CS4236_RIGHT_MASTER)];
- snd_cs4236_ext_out(chip, CS4236_LEFT_MASTER, val1);
- snd_cs4236_ext_out(chip, CS4236_RIGHT_MASTER, val2);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return change;
-}
-
-#define CS4235_OUTPUT_ACCU(xname, xindex, xtlv) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .info = snd_cs4236_info_double, \
- .get = snd_cs4235_get_output_accu, .put = snd_cs4235_put_output_accu, \
- .private_value = 3 << 24, \
- .tlv = { .p = (xtlv) } }
-
-static inline int snd_cs4235_mixer_output_accu_get_volume(int vol)
-{
- switch ((vol >> 5) & 3) {
- case 0: return 1;
- case 1: return 3;
- case 2: return 2;
- case 3: return 0;
- }
- return 3;
-}
-
-static inline int snd_cs4235_mixer_output_accu_set_volume(int vol)
-{
- switch (vol & 3) {
- case 0: return 3 << 5;
- case 1: return 0 << 5;
- case 2: return 2 << 5;
- case 3: return 1 << 5;
- }
- return 1 << 5;
-}
-
-static int snd_cs4235_get_output_accu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- ucontrol->value.integer.value[0] = snd_cs4235_mixer_output_accu_get_volume(chip->image[CS4235_LEFT_MASTER]);
- ucontrol->value.integer.value[1] = snd_cs4235_mixer_output_accu_get_volume(chip->image[CS4235_RIGHT_MASTER]);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
-}
-
-static int snd_cs4235_put_output_accu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int change;
- unsigned short val1, val2;
-
- val1 = snd_cs4235_mixer_output_accu_set_volume(ucontrol->value.integer.value[0]);
- val2 = snd_cs4235_mixer_output_accu_set_volume(ucontrol->value.integer.value[1]);
- spin_lock_irqsave(&chip->reg_lock, flags);
- val1 = (chip->image[CS4235_LEFT_MASTER] & ~(3 << 5)) | val1;
- val2 = (chip->image[CS4235_RIGHT_MASTER] & ~(3 << 5)) | val2;
- change = val1 != chip->image[CS4235_LEFT_MASTER] || val2 != chip->image[CS4235_RIGHT_MASTER];
- snd_wss_out(chip, CS4235_LEFT_MASTER, val1);
- snd_wss_out(chip, CS4235_RIGHT_MASTER, val2);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return change;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_7bit, -9450, 150, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_6bit_12db_max, -8250, 150, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_5bit_22db_max, -2400, 150, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_2bit, -1800, 600, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
-
-static struct snd_kcontrol_new snd_cs4236_controls[] = {
-
-CS4236_DOUBLE("Master Digital Playback Switch", 0,
- CS4236_LEFT_MASTER, CS4236_RIGHT_MASTER, 7, 7, 1, 1),
-CS4236_DOUBLE("Master Digital Capture Switch", 0,
- CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1),
-CS4236_MASTER_DIGITAL("Master Digital Volume", 0, db_scale_7bit),
-
-CS4236_DOUBLE_TLV("Capture Boost Volume", 0,
- CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1,
- db_scale_2bit),
-
-WSS_DOUBLE("PCM Playback Switch", 0,
- CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
-WSS_DOUBLE_TLV("PCM Playback Volume", 0,
- CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
- db_scale_6bit),
-
-CS4236_DOUBLE("DSP Playback Switch", 0,
- CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1),
-CS4236_DOUBLE_TLV("DSP Playback Volume", 0,
- CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 0, 0, 63, 1,
- db_scale_6bit),
-
-CS4236_DOUBLE("FM Playback Switch", 0,
- CS4236_LEFT_FM, CS4236_RIGHT_FM, 7, 7, 1, 1),
-CS4236_DOUBLE_TLV("FM Playback Volume", 0,
- CS4236_LEFT_FM, CS4236_RIGHT_FM, 0, 0, 63, 1,
- db_scale_6bit),
-
-CS4236_DOUBLE("Wavetable Playback Switch", 0,
- CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 7, 7, 1, 1),
-CS4236_DOUBLE_TLV("Wavetable Playback Volume", 0,
- CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 0, 0, 63, 1,
- db_scale_6bit_12db_max),
-
-WSS_DOUBLE("Synth Playback Switch", 0,
- CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
-WSS_DOUBLE_TLV("Synth Volume", 0,
- CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1,
- db_scale_5bit_12db_max),
-WSS_DOUBLE("Synth Capture Switch", 0,
- CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1),
-WSS_DOUBLE("Synth Capture Bypass", 0,
- CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 5, 5, 1, 1),
-
-CS4236_DOUBLE("Mic Playback Switch", 0,
- CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1),
-CS4236_DOUBLE("Mic Capture Switch", 0,
- CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1),
-CS4236_DOUBLE_TLV("Mic Volume", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC,
- 0, 0, 31, 1, db_scale_5bit_22db_max),
-CS4236_DOUBLE("Mic Playback Boost (+20dB)", 0,
- CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 5, 5, 1, 0),
-
-WSS_DOUBLE("Line Playback Switch", 0,
- CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
-WSS_DOUBLE_TLV("Line Volume", 0,
- CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
- db_scale_5bit_12db_max),
-WSS_DOUBLE("Line Capture Switch", 0,
- CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1),
-WSS_DOUBLE("Line Capture Bypass", 0,
- CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 5, 5, 1, 1),
-
-WSS_DOUBLE("CD Playback Switch", 0,
- CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
-WSS_DOUBLE_TLV("CD Volume", 0,
- CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
- db_scale_5bit_12db_max),
-WSS_DOUBLE("CD Capture Switch", 0,
- CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1),
-
-CS4236_DOUBLE1("Mono Output Playback Switch", 0,
- CS4231_MONO_CTRL, CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1),
-CS4236_DOUBLE1("Beep Playback Switch", 0,
- CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1),
-WSS_SINGLE_TLV("Beep Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1,
- db_scale_4bit),
-WSS_SINGLE("Beep Bypass Playback Switch", 0, CS4231_MONO_CTRL, 5, 1, 0),
-
-WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT,
- 0, 0, 15, 0, db_scale_rec_gain),
-WSS_DOUBLE("Analog Loopback Capture Switch", 0,
- CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0),
-
-WSS_SINGLE("Loopback Digital Playback Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
-CS4236_DOUBLE1_TLV("Loopback Digital Playback Volume", 0,
- CS4231_LOOPBACK, CS4236_RIGHT_LOOPBACK, 2, 0, 63, 1,
- db_scale_6bit),
-};
-
-static const DECLARE_TLV_DB_SCALE(db_scale_5bit_6db_max, -5600, 200, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_2bit_16db_max, -2400, 800, 0);
-
-static struct snd_kcontrol_new snd_cs4235_controls[] = {
-
-WSS_DOUBLE("Master Playback Switch", 0,
- CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 7, 7, 1, 1),
-WSS_DOUBLE_TLV("Master Playback Volume", 0,
- CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 0, 0, 31, 1,
- db_scale_5bit_6db_max),
-
-CS4235_OUTPUT_ACCU("Playback Volume", 0, db_scale_2bit_16db_max),
-
-WSS_DOUBLE("Synth Playback Switch", 1,
- CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
-WSS_DOUBLE("Synth Capture Switch", 1,
- CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1),
-WSS_DOUBLE_TLV("Synth Volume", 1,
- CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1,
- db_scale_5bit_12db_max),
-
-CS4236_DOUBLE_TLV("Capture Volume", 0,
- CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1,
- db_scale_2bit),
-
-WSS_DOUBLE("PCM Playback Switch", 0,
- CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
-WSS_DOUBLE("PCM Capture Switch", 0,
- CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1),
-WSS_DOUBLE_TLV("PCM Volume", 0,
- CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
- db_scale_6bit),
-
-CS4236_DOUBLE("DSP Switch", 0, CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1),
-
-CS4236_DOUBLE("FM Switch", 0, CS4236_LEFT_FM, CS4236_RIGHT_FM, 7, 7, 1, 1),
-
-CS4236_DOUBLE("Wavetable Switch", 0,
- CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 7, 7, 1, 1),
-
-CS4236_DOUBLE("Mic Capture Switch", 0,
- CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1),
-CS4236_DOUBLE("Mic Playback Switch", 0,
- CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1),
-CS4236_SINGLE_TLV("Mic Volume", 0, CS4236_LEFT_MIC, 0, 31, 1,
- db_scale_5bit_22db_max),
-CS4236_SINGLE("Mic Boost (+20dB)", 0, CS4236_LEFT_MIC, 5, 1, 0),
-
-WSS_DOUBLE("Line Playback Switch", 0,
- CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
-WSS_DOUBLE("Line Capture Switch", 0,
- CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1),
-WSS_DOUBLE_TLV("Line Volume", 0,
- CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
- db_scale_5bit_12db_max),
-
-WSS_DOUBLE("CD Playback Switch", 1,
- CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
-WSS_DOUBLE("CD Capture Switch", 1,
- CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1),
-WSS_DOUBLE_TLV("CD Volume", 1,
- CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
- db_scale_5bit_12db_max),
-
-CS4236_DOUBLE1("Beep Playback Switch", 0,
- CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1),
-WSS_SINGLE("Beep Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1),
-
-WSS_DOUBLE("Analog Loopback Switch", 0,
- CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0),
-};
-
-#define CS4236_IEC958_ENABLE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_cs4236_info_single, \
- .get = snd_cs4236_get_iec958_switch, .put = snd_cs4236_put_iec958_switch, \
- .private_value = 1 << 16 }
-
-static int snd_cs4236_get_iec958_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- ucontrol->value.integer.value[0] = chip->image[CS4231_ALT_FEATURE_1] & 0x02 ? 1 : 0;
-#if 0
- printk(KERN_DEBUG "get valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, "
- "C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n",
- snd_wss_in(chip, CS4231_ALT_FEATURE_1),
- snd_cs4236_ctrl_in(chip, 3),
- snd_cs4236_ctrl_in(chip, 4),
- snd_cs4236_ctrl_in(chip, 5),
- snd_cs4236_ctrl_in(chip, 6),
- snd_cs4236_ctrl_in(chip, 8));
-#endif
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
-}
-
-static int snd_cs4236_put_iec958_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int change;
- unsigned short enable, val;
-
- enable = ucontrol->value.integer.value[0] & 1;
-
- mutex_lock(&chip->mce_mutex);
- snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- val = (chip->image[CS4231_ALT_FEATURE_1] & ~0x0e) | (0<<2) | (enable << 1);
- change = val != chip->image[CS4231_ALT_FEATURE_1];
- snd_wss_out(chip, CS4231_ALT_FEATURE_1, val);
- val = snd_cs4236_ctrl_in(chip, 4) | 0xc0;
- snd_cs4236_ctrl_out(chip, 4, val);
- udelay(100);
- val &= ~0x40;
- snd_cs4236_ctrl_out(chip, 4, val);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- snd_wss_mce_down(chip);
- mutex_unlock(&chip->mce_mutex);
-
-#if 0
- printk(KERN_DEBUG "set valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, "
- "C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n",
- snd_wss_in(chip, CS4231_ALT_FEATURE_1),
- snd_cs4236_ctrl_in(chip, 3),
- snd_cs4236_ctrl_in(chip, 4),
- snd_cs4236_ctrl_in(chip, 5),
- snd_cs4236_ctrl_in(chip, 6),
- snd_cs4236_ctrl_in(chip, 8));
-#endif
- return change;
-}
-
-static struct snd_kcontrol_new snd_cs4236_iec958_controls[] = {
-CS4236_IEC958_ENABLE("IEC958 Output Enable", 0),
-CS4236_SINGLEC("IEC958 Output Validity", 0, 4, 4, 1, 0),
-CS4236_SINGLEC("IEC958 Output User", 0, 4, 5, 1, 0),
-CS4236_SINGLEC("IEC958 Output CSBR", 0, 4, 6, 1, 0),
-CS4236_SINGLEC("IEC958 Output Channel Status Low", 0, 5, 1, 127, 0),
-CS4236_SINGLEC("IEC958 Output Channel Status High", 0, 6, 0, 255, 0)
-};
-
-static struct snd_kcontrol_new snd_cs4236_3d_controls_cs4235[] = {
-CS4236_SINGLEC("3D Control - Switch", 0, 3, 4, 1, 0),
-CS4236_SINGLEC("3D Control - Space", 0, 2, 4, 15, 1)
-};
-
-static struct snd_kcontrol_new snd_cs4236_3d_controls_cs4237[] = {
-CS4236_SINGLEC("3D Control - Switch", 0, 3, 7, 1, 0),
-CS4236_SINGLEC("3D Control - Space", 0, 2, 4, 15, 1),
-CS4236_SINGLEC("3D Control - Center", 0, 2, 0, 15, 1),
-CS4236_SINGLEC("3D Control - Mono", 0, 3, 6, 1, 0),
-CS4236_SINGLEC("3D Control - IEC958", 0, 3, 5, 1, 0)
-};
-
-static struct snd_kcontrol_new snd_cs4236_3d_controls_cs4238[] = {
-CS4236_SINGLEC("3D Control - Switch", 0, 3, 4, 1, 0),
-CS4236_SINGLEC("3D Control - Space", 0, 2, 4, 15, 1),
-CS4236_SINGLEC("3D Control - Volume", 0, 2, 0, 15, 1),
-CS4236_SINGLEC("3D Control - IEC958", 0, 3, 5, 1, 0)
-};
-
-int snd_cs4236_mixer(struct snd_wss *chip)
-{
- struct snd_card *card;
- unsigned int idx, count;
- int err;
- struct snd_kcontrol_new *kcontrol;
-
- if (snd_BUG_ON(!chip || !chip->card))
- return -EINVAL;
- card = chip->card;
- strcpy(card->mixername, snd_wss_chip_id(chip));
-
- if (chip->hardware == WSS_HW_CS4235 ||
- chip->hardware == WSS_HW_CS4239) {
- for (idx = 0; idx < ARRAY_SIZE(snd_cs4235_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4235_controls[idx], chip))) < 0)
- return err;
- }
- } else {
- for (idx = 0; idx < ARRAY_SIZE(snd_cs4236_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4236_controls[idx], chip))) < 0)
- return err;
- }
- }
- switch (chip->hardware) {
- case WSS_HW_CS4235:
- case WSS_HW_CS4239:
- count = ARRAY_SIZE(snd_cs4236_3d_controls_cs4235);
- kcontrol = snd_cs4236_3d_controls_cs4235;
- break;
- case WSS_HW_CS4237B:
- count = ARRAY_SIZE(snd_cs4236_3d_controls_cs4237);
- kcontrol = snd_cs4236_3d_controls_cs4237;
- break;
- case WSS_HW_CS4238B:
- count = ARRAY_SIZE(snd_cs4236_3d_controls_cs4238);
- kcontrol = snd_cs4236_3d_controls_cs4238;
- break;
- default:
- count = 0;
- kcontrol = NULL;
- }
- for (idx = 0; idx < count; idx++, kcontrol++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(kcontrol, chip))) < 0)
- return err;
- }
- if (chip->hardware == WSS_HW_CS4237B ||
- chip->hardware == WSS_HW_CS4238B) {
- for (idx = 0; idx < ARRAY_SIZE(snd_cs4236_iec958_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4236_iec958_controls[idx], chip))) < 0)
- return err;
- }
- }
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/isa/es1688/Makefile b/ANDROID_3.4.5/sound/isa/es1688/Makefile
deleted file mode 100644
index aee1e4dd..00000000
--- a/ANDROID_3.4.5/sound/isa/es1688/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-es1688-lib-objs := es1688_lib.o
-snd-es1688-objs := es1688.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_ES1688) += snd-es1688.o snd-es1688-lib.o
-obj-$(CONFIG_SND_GUSEXTREME) += snd-es1688-lib.o
diff --git a/ANDROID_3.4.5/sound/isa/es1688/es1688.c b/ANDROID_3.4.5/sound/isa/es1688/es1688.c
deleted file mode 100644
index b036e60f..00000000
--- a/ANDROID_3.4.5/sound/isa/es1688/es1688.c
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Driver for generic ESS AudioDrive ESx688 soundcards
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/isa.h>
-#include <linux/isapnp.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/module.h>
-#include <asm/dma.h>
-#include <sound/core.h>
-#include <sound/es1688.h>
-#include <sound/mpu401.h>
-#include <sound/opl3.h>
-#define SNDRV_LEGACY_FIND_FREE_IRQ
-#define SNDRV_LEGACY_FIND_FREE_DMA
-#include <sound/initval.h>
-
-#define CRD_NAME "Generic ESS ES1688/ES688 AudioDrive"
-#define DEV_NAME "es1688"
-
-MODULE_DESCRIPTION(CRD_NAME);
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ESS,ES688 PnP AudioDrive,pnp:ESS0100},"
- "{ESS,ES1688 PnP AudioDrive,pnp:ESS0102},"
- "{ESS,ES688 AudioDrive,pnp:ESS6881},"
- "{ESS,ES1688 AudioDrive,pnp:ESS1681}}");
-
-MODULE_ALIAS("snd_es968");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-#ifdef CONFIG_PNP
-static bool isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
-#endif
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */
-static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* Usually 0x388 */
-static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */
-static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */
-static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3 */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-#ifdef CONFIG_PNP
-module_param_array(isapnp, bool, NULL, 0444);
-MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
-#endif
-MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
-module_param_array(mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
-module_param_array(irq, int, NULL, 0444);
-module_param_array(fm_port, long, NULL, 0444);
-MODULE_PARM_DESC(fm_port, "FM port # for ES1688 driver.");
-MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
-module_param_array(mpu_irq, int, NULL, 0444);
-MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
-module_param_array(dma8, int, NULL, 0444);
-MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver.");
-
-#ifdef CONFIG_PNP
-#define is_isapnp_selected(dev) isapnp[dev]
-#else
-#define is_isapnp_selected(dev) 0
-#endif
-
-static int __devinit snd_es1688_match(struct device *dev, unsigned int n)
-{
- return enable[n] && !is_isapnp_selected(n);
-}
-
-static int __devinit snd_es1688_legacy_create(struct snd_card *card,
- struct device *dev, unsigned int n)
-{
- struct snd_es1688 *chip = card->private_data;
- static long possible_ports[] = {0x220, 0x240, 0x260};
- static int possible_irqs[] = {5, 9, 10, 7, -1};
- static int possible_dmas[] = {1, 3, 0, -1};
-
- int i, error;
-
- if (irq[n] == SNDRV_AUTO_IRQ) {
- irq[n] = snd_legacy_find_free_irq(possible_irqs);
- if (irq[n] < 0) {
- dev_err(dev, "unable to find a free IRQ\n");
- return -EBUSY;
- }
- }
- if (dma8[n] == SNDRV_AUTO_DMA) {
- dma8[n] = snd_legacy_find_free_dma(possible_dmas);
- if (dma8[n] < 0) {
- dev_err(dev, "unable to find a free DMA\n");
- return -EBUSY;
- }
- }
-
- if (port[n] != SNDRV_AUTO_PORT)
- return snd_es1688_create(card, chip, port[n], mpu_port[n],
- irq[n], mpu_irq[n], dma8[n], ES1688_HW_AUTO);
-
- i = 0;
- do {
- port[n] = possible_ports[i];
- error = snd_es1688_create(card, chip, port[n], mpu_port[n],
- irq[n], mpu_irq[n], dma8[n], ES1688_HW_AUTO);
- } while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
-
- return error;
-}
-
-static int __devinit snd_es1688_probe(struct snd_card *card, unsigned int n)
-{
- struct snd_es1688 *chip = card->private_data;
- struct snd_opl3 *opl3;
- struct snd_pcm *pcm;
- int error;
-
- error = snd_es1688_pcm(card, chip, 0, &pcm);
- if (error < 0)
- return error;
-
- error = snd_es1688_mixer(card, chip);
- if (error < 0)
- return error;
-
- strlcpy(card->driver, "ES1688", sizeof(card->driver));
- strlcpy(card->shortname, pcm->name, sizeof(card->shortname));
- snprintf(card->longname, sizeof(card->longname),
- "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port,
- chip->irq, chip->dma8);
-
- if (fm_port[n] == SNDRV_AUTO_PORT)
- fm_port[n] = port[n]; /* share the same port */
-
- if (fm_port[n] > 0) {
- if (snd_opl3_create(card, fm_port[n], fm_port[n] + 2,
- OPL3_HW_OPL3, 0, &opl3) < 0)
- dev_warn(card->dev,
- "opl3 not detected at 0x%lx\n", fm_port[n]);
- else {
- error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
- if (error < 0)
- return error;
- }
- }
-
- if (mpu_irq[n] >= 0 && mpu_irq[n] != SNDRV_AUTO_IRQ &&
- chip->mpu_port > 0) {
- error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
- chip->mpu_port, 0,
- mpu_irq[n], NULL);
- if (error < 0)
- return error;
- }
-
- return snd_card_register(card);
-}
-
-static int __devinit snd_es1688_isa_probe(struct device *dev, unsigned int n)
-{
- struct snd_card *card;
- int error;
-
- error = snd_card_create(index[n], id[n], THIS_MODULE,
- sizeof(struct snd_es1688), &card);
- if (error < 0)
- return error;
-
- error = snd_es1688_legacy_create(card, dev, n);
- if (error < 0)
- goto out;
-
- snd_card_set_dev(card, dev);
-
- error = snd_es1688_probe(card, n);
- if (error < 0)
- goto out;
-
- dev_set_drvdata(dev, card);
-
- return 0;
-out:
- snd_card_free(card);
- return error;
-}
-
-static int __devexit snd_es1688_isa_remove(struct device *dev, unsigned int n)
-{
- snd_card_free(dev_get_drvdata(dev));
- dev_set_drvdata(dev, NULL);
- return 0;
-}
-
-static struct isa_driver snd_es1688_driver = {
- .match = snd_es1688_match,
- .probe = snd_es1688_isa_probe,
- .remove = __devexit_p(snd_es1688_isa_remove),
-#if 0 /* FIXME */
- .suspend = snd_es1688_suspend,
- .resume = snd_es1688_resume,
-#endif
- .driver = {
- .name = DEV_NAME
- }
-};
-
-static int snd_es968_pnp_is_probed;
-
-#ifdef CONFIG_PNP
-static int __devinit snd_card_es968_pnp(struct snd_card *card, unsigned int n,
- struct pnp_card_link *pcard,
- const struct pnp_card_device_id *pid)
-{
- struct snd_es1688 *chip = card->private_data;
- struct pnp_dev *pdev;
- int error;
-
- pdev = pnp_request_card_device(pcard, pid->devs[0].id, NULL);
- if (pdev == NULL)
- return -ENODEV;
-
- error = pnp_activate_dev(pdev);
- if (error < 0) {
- snd_printk(KERN_ERR "ES968 pnp configure failure\n");
- return error;
- }
- port[n] = pnp_port_start(pdev, 0);
- dma8[n] = pnp_dma(pdev, 0);
- irq[n] = pnp_irq(pdev, 0);
-
- return snd_es1688_create(card, chip, port[n], mpu_port[n], irq[n],
- mpu_irq[n], dma8[n], ES1688_HW_AUTO);
-}
-
-static int __devinit snd_es968_pnp_detect(struct pnp_card_link *pcard,
- const struct pnp_card_device_id *pid)
-{
- struct snd_card *card;
- static unsigned int dev;
- int error;
- struct snd_es1688 *chip;
-
- if (snd_es968_pnp_is_probed)
- return -EBUSY;
- for ( ; dev < SNDRV_CARDS; dev++) {
- if (enable[dev] && isapnp[dev])
- break;
- }
- if (dev == SNDRV_CARDS)
- return -ENODEV;
-
- error = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_es1688), &card);
- if (error < 0)
- return error;
- chip = card->private_data;
-
- error = snd_card_es968_pnp(card, dev, pcard, pid);
- if (error < 0) {
- snd_card_free(card);
- return error;
- }
- snd_card_set_dev(card, &pcard->card->dev);
- error = snd_es1688_probe(card, dev);
- if (error < 0)
- return error;
- pnp_set_card_drvdata(pcard, card);
- snd_es968_pnp_is_probed = 1;
- return 0;
-}
-
-static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard)
-{
- snd_card_free(pnp_get_card_drvdata(pcard));
- pnp_set_card_drvdata(pcard, NULL);
- snd_es968_pnp_is_probed = 0;
-}
-
-#ifdef CONFIG_PM
-static int snd_es968_pnp_suspend(struct pnp_card_link *pcard,
- pm_message_t state)
-{
- struct snd_card *card = pnp_get_card_drvdata(pcard);
- struct snd_es1688 *chip = card->private_data;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(chip->pcm);
- return 0;
-}
-
-static int snd_es968_pnp_resume(struct pnp_card_link *pcard)
-{
- struct snd_card *card = pnp_get_card_drvdata(pcard);
- struct snd_es1688 *chip = card->private_data;
-
- snd_es1688_reset(chip);
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif
-
-static struct pnp_card_device_id snd_es968_pnpids[] = {
- { .id = "ESS0968", .devs = { { "@@@0968" }, } },
- { .id = "ESS0968", .devs = { { "ESS0968" }, } },
- { .id = "", } /* end */
-};
-
-MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids);
-
-static struct pnp_card_driver es968_pnpc_driver = {
- .flags = PNP_DRIVER_RES_DISABLE,
- .name = DEV_NAME " PnP",
- .id_table = snd_es968_pnpids,
- .probe = snd_es968_pnp_detect,
- .remove = __devexit_p(snd_es968_pnp_remove),
-#ifdef CONFIG_PM
- .suspend = snd_es968_pnp_suspend,
- .resume = snd_es968_pnp_resume,
-#endif
-};
-#endif
-
-static int __init alsa_card_es1688_init(void)
-{
-#ifdef CONFIG_PNP
- pnp_register_card_driver(&es968_pnpc_driver);
- if (snd_es968_pnp_is_probed)
- return 0;
- pnp_unregister_card_driver(&es968_pnpc_driver);
-#endif
- return isa_register_driver(&snd_es1688_driver, SNDRV_CARDS);
-}
-
-static void __exit alsa_card_es1688_exit(void)
-{
- if (!snd_es968_pnp_is_probed) {
- isa_unregister_driver(&snd_es1688_driver);
- return;
- }
-#ifdef CONFIG_PNP
- pnp_unregister_card_driver(&es968_pnpc_driver);
-#endif
-}
-
-module_init(alsa_card_es1688_init);
-module_exit(alsa_card_es1688_exit);
diff --git a/ANDROID_3.4.5/sound/isa/es1688/es1688_lib.c b/ANDROID_3.4.5/sound/isa/es1688/es1688_lib.c
deleted file mode 100644
index 1d47be81..00000000
--- a/ANDROID_3.4.5/sound/isa/es1688/es1688_lib.c
+++ /dev/null
@@ -1,1046 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Routines for control of ESS ES1688/688/488 chip
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/es1688.h>
-#include <sound/initval.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("ESS ESx688 lowlevel module");
-MODULE_LICENSE("GPL");
-
-static int snd_es1688_dsp_command(struct snd_es1688 *chip, unsigned char val)
-{
- int i;
-
- for (i = 10000; i; i--)
- if ((inb(ES1688P(chip, STATUS)) & 0x80) == 0) {
- outb(val, ES1688P(chip, COMMAND));
- return 1;
- }
-#ifdef CONFIG_SND_DEBUG
- printk(KERN_DEBUG "snd_es1688_dsp_command: timeout (0x%x)\n", val);
-#endif
- return 0;
-}
-
-static int snd_es1688_dsp_get_byte(struct snd_es1688 *chip)
-{
- int i;
-
- for (i = 1000; i; i--)
- if (inb(ES1688P(chip, DATA_AVAIL)) & 0x80)
- return inb(ES1688P(chip, READ));
- snd_printd("es1688 get byte failed: 0x%lx = 0x%x!!!\n", ES1688P(chip, DATA_AVAIL), inb(ES1688P(chip, DATA_AVAIL)));
- return -ENODEV;
-}
-
-static int snd_es1688_write(struct snd_es1688 *chip,
- unsigned char reg, unsigned char data)
-{
- if (!snd_es1688_dsp_command(chip, reg))
- return 0;
- return snd_es1688_dsp_command(chip, data);
-}
-
-static int snd_es1688_read(struct snd_es1688 *chip, unsigned char reg)
-{
- /* Read a byte from an extended mode register of ES1688 */
- if (!snd_es1688_dsp_command(chip, 0xc0))
- return -1;
- if (!snd_es1688_dsp_command(chip, reg))
- return -1;
- return snd_es1688_dsp_get_byte(chip);
-}
-
-void snd_es1688_mixer_write(struct snd_es1688 *chip,
- unsigned char reg, unsigned char data)
-{
- outb(reg, ES1688P(chip, MIXER_ADDR));
- udelay(10);
- outb(data, ES1688P(chip, MIXER_DATA));
- udelay(10);
-}
-
-static unsigned char snd_es1688_mixer_read(struct snd_es1688 *chip, unsigned char reg)
-{
- unsigned char result;
-
- outb(reg, ES1688P(chip, MIXER_ADDR));
- udelay(10);
- result = inb(ES1688P(chip, MIXER_DATA));
- udelay(10);
- return result;
-}
-
-int snd_es1688_reset(struct snd_es1688 *chip)
-{
- int i;
-
- outb(3, ES1688P(chip, RESET)); /* valid only for ESS chips, SB -> 1 */
- udelay(10);
- outb(0, ES1688P(chip, RESET));
- udelay(30);
- for (i = 0; i < 1000 && !(inb(ES1688P(chip, DATA_AVAIL)) & 0x80); i++);
- if (inb(ES1688P(chip, READ)) != 0xaa) {
- snd_printd("ess_reset at 0x%lx: failed!!!\n", chip->port);
- return -ENODEV;
- }
- snd_es1688_dsp_command(chip, 0xc6); /* enable extended mode */
- return 0;
-}
-EXPORT_SYMBOL(snd_es1688_reset);
-
-static int snd_es1688_probe(struct snd_es1688 *chip)
-{
- unsigned long flags;
- unsigned short major, minor, hw;
- int i;
-
- /*
- * initialization sequence
- */
-
- spin_lock_irqsave(&chip->reg_lock, flags); /* Some ESS1688 cards need this */
- inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
- inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
- inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
- inb(ES1688P(chip, ENABLE2)); /* ENABLE2 */
- inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
- inb(ES1688P(chip, ENABLE2)); /* ENABLE2 */
- inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
- inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
- inb(ES1688P(chip, ENABLE2)); /* ENABLE2 */
- inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */
- inb(ES1688P(chip, ENABLE0)); /* ENABLE0 */
-
- if (snd_es1688_reset(chip) < 0) {
- snd_printdd("ESS: [0x%lx] reset failed... 0x%x\n", chip->port, inb(ES1688P(chip, READ)));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return -ENODEV;
- }
- snd_es1688_dsp_command(chip, 0xe7); /* return identification */
-
- for (i = 1000, major = minor = 0; i; i--) {
- if (inb(ES1688P(chip, DATA_AVAIL)) & 0x80) {
- if (major == 0) {
- major = inb(ES1688P(chip, READ));
- } else {
- minor = inb(ES1688P(chip, READ));
- }
- }
- }
-
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- snd_printdd("ESS: [0x%lx] found.. major = 0x%x, minor = 0x%x\n", chip->port, major, minor);
-
- chip->version = (major << 8) | minor;
- if (!chip->version)
- return -ENODEV; /* probably SB */
-
- hw = ES1688_HW_AUTO;
- switch (chip->version & 0xfff0) {
- case 0x4880:
- snd_printk(KERN_ERR "[0x%lx] ESS: AudioDrive ES488 detected, "
- "but driver is in another place\n", chip->port);
- return -ENODEV;
- case 0x6880:
- hw = (chip->version & 0x0f) >= 8 ? ES1688_HW_1688 : ES1688_HW_688;
- break;
- default:
- snd_printk(KERN_ERR "[0x%lx] ESS: unknown AudioDrive chip "
- "with version 0x%x (Jazz16 soundcard?)\n",
- chip->port, chip->version);
- return -ENODEV;
- }
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_write(chip, 0xb1, 0x10); /* disable IRQ */
- snd_es1688_write(chip, 0xb2, 0x00); /* disable DMA */
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- /* enable joystick, but disable OPL3 */
- spin_lock_irqsave(&chip->mixer_lock, flags);
- snd_es1688_mixer_write(chip, 0x40, 0x01);
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
-
- return 0;
-}
-
-static int snd_es1688_init(struct snd_es1688 * chip, int enable)
-{
- static int irqs[16] = {-1, -1, 0, -1, -1, 1, -1, 2, -1, 0, 3, -1, -1, -1, -1, -1};
- unsigned long flags;
- int cfg, irq_bits, dma, dma_bits, tmp, tmp1;
-
- /* ok.. setup MPU-401 port and joystick and OPL3 */
- cfg = 0x01; /* enable joystick, but disable OPL3 */
- if (enable && chip->mpu_port >= 0x300 && chip->mpu_irq > 0 && chip->hardware != ES1688_HW_688) {
- tmp = (chip->mpu_port & 0x0f0) >> 4;
- if (tmp <= 3) {
- switch (chip->mpu_irq) {
- case 9:
- tmp1 = 4;
- break;
- case 5:
- tmp1 = 5;
- break;
- case 7:
- tmp1 = 6;
- break;
- case 10:
- tmp1 = 7;
- break;
- default:
- tmp1 = 0;
- }
- if (tmp1) {
- cfg |= (tmp << 3) | (tmp1 << 5);
- }
- }
- }
-#if 0
- snd_printk(KERN_DEBUG "mpu cfg = 0x%x\n", cfg);
-#endif
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_mixer_write(chip, 0x40, cfg);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- /* --- */
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_read(chip, 0xb1);
- snd_es1688_read(chip, 0xb2);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (enable) {
- cfg = 0xf0; /* enable only DMA counter interrupt */
- irq_bits = irqs[chip->irq & 0x0f];
- if (irq_bits < 0) {
- snd_printk(KERN_ERR "[0x%lx] ESS: bad IRQ %d "
- "for ES1688 chip!!\n",
- chip->port, chip->irq);
-#if 0
- irq_bits = 0;
- cfg = 0x10;
-#endif
- return -EINVAL;
- }
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_write(chip, 0xb1, cfg | (irq_bits << 2));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- cfg = 0xf0; /* extended mode DMA enable */
- dma = chip->dma8;
- if (dma > 3 || dma == 2) {
- snd_printk(KERN_ERR "[0x%lx] ESS: bad DMA channel %d "
- "for ES1688 chip!!\n", chip->port, dma);
-#if 0
- dma_bits = 0;
- cfg = 0x00; /* disable all DMA */
-#endif
- return -EINVAL;
- } else {
- dma_bits = dma;
- if (dma != 3)
- dma_bits++;
- }
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_write(chip, 0xb2, cfg | (dma_bits << 2));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- } else {
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_write(chip, 0xb1, 0x10); /* disable IRQ */
- snd_es1688_write(chip, 0xb2, 0x00); /* disable DMA */
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- }
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_read(chip, 0xb1);
- snd_es1688_read(chip, 0xb2);
- snd_es1688_reset(chip);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
-}
-
-/*
-
- */
-
-static struct snd_ratnum clocks[2] = {
- {
- .num = 795444,
- .den_min = 1,
- .den_max = 128,
- .den_step = 1,
- },
- {
- .num = 397722,
- .den_min = 1,
- .den_max = 128,
- .den_step = 1,
- }
-};
-
-static struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks = {
- .nrats = 2,
- .rats = clocks,
-};
-
-static void snd_es1688_set_rate(struct snd_es1688 *chip, struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int bits, divider;
-
- if (runtime->rate_num == clocks[0].num)
- bits = 256 - runtime->rate_den;
- else
- bits = 128 - runtime->rate_den;
- /* set filter register */
- divider = 256 - 7160000*20/(8*82*runtime->rate);
- /* write result to hardware */
- snd_es1688_write(chip, 0xa1, bits);
- snd_es1688_write(chip, 0xa2, divider);
-}
-
-static int snd_es1688_ioctl(struct snd_pcm_substream *substream,
- unsigned int cmd, void *arg)
-{
- return snd_pcm_lib_ioctl(substream, cmd, arg);
-}
-
-static int snd_es1688_trigger(struct snd_es1688 *chip, int cmd, unsigned char value)
-{
- int val;
-
- if (cmd == SNDRV_PCM_TRIGGER_STOP) {
- value = 0x00;
- } else if (cmd != SNDRV_PCM_TRIGGER_START) {
- return -EINVAL;
- }
- spin_lock(&chip->reg_lock);
- chip->trigger_value = value;
- val = snd_es1688_read(chip, 0xb8);
- if ((val < 0) || (val & 0x0f) == value) {
- spin_unlock(&chip->reg_lock);
- return -EINVAL; /* something is wrong */
- }
-#if 0
- printk(KERN_DEBUG "trigger: val = 0x%x, value = 0x%x\n", val, value);
- printk(KERN_DEBUG "trigger: pointer = 0x%x\n",
- snd_dma_pointer(chip->dma8, chip->dma_size));
-#endif
- snd_es1688_write(chip, 0xb8, (val & 0xf0) | value);
- spin_unlock(&chip->reg_lock);
- return 0;
-}
-
-static int snd_es1688_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static int snd_es1688_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_es1688_playback_prepare(struct snd_pcm_substream *substream)
-{
- unsigned long flags;
- struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int size = snd_pcm_lib_buffer_bytes(substream);
- unsigned int count = snd_pcm_lib_period_bytes(substream);
-
- chip->dma_size = size;
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_reset(chip);
- snd_es1688_set_rate(chip, substream);
- snd_es1688_write(chip, 0xb8, 4); /* auto init DMA mode */
- snd_es1688_write(chip, 0xa8, (snd_es1688_read(chip, 0xa8) & ~0x03) | (3 - runtime->channels));
- snd_es1688_write(chip, 0xb9, 2); /* demand mode (4 bytes/request) */
- if (runtime->channels == 1) {
- if (snd_pcm_format_width(runtime->format) == 8) {
- /* 8. bit mono */
- snd_es1688_write(chip, 0xb6, 0x80);
- snd_es1688_write(chip, 0xb7, 0x51);
- snd_es1688_write(chip, 0xb7, 0xd0);
- } else {
- /* 16. bit mono */
- snd_es1688_write(chip, 0xb6, 0x00);
- snd_es1688_write(chip, 0xb7, 0x71);
- snd_es1688_write(chip, 0xb7, 0xf4);
- }
- } else {
- if (snd_pcm_format_width(runtime->format) == 8) {
- /* 8. bit stereo */
- snd_es1688_write(chip, 0xb6, 0x80);
- snd_es1688_write(chip, 0xb7, 0x51);
- snd_es1688_write(chip, 0xb7, 0x98);
- } else {
- /* 16. bit stereo */
- snd_es1688_write(chip, 0xb6, 0x00);
- snd_es1688_write(chip, 0xb7, 0x71);
- snd_es1688_write(chip, 0xb7, 0xbc);
- }
- }
- snd_es1688_write(chip, 0xb1, (snd_es1688_read(chip, 0xb1) & 0x0f) | 0x50);
- snd_es1688_write(chip, 0xb2, (snd_es1688_read(chip, 0xb2) & 0x0f) | 0x50);
- snd_es1688_dsp_command(chip, ES1688_DSP_CMD_SPKON);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- /* --- */
- count = -count;
- snd_dma_program(chip->dma8, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_write(chip, 0xa4, (unsigned char) count);
- snd_es1688_write(chip, 0xa5, (unsigned char) (count >> 8));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
-}
-
-static int snd_es1688_playback_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
- return snd_es1688_trigger(chip, cmd, 0x05);
-}
-
-static int snd_es1688_capture_prepare(struct snd_pcm_substream *substream)
-{
- unsigned long flags;
- struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int size = snd_pcm_lib_buffer_bytes(substream);
- unsigned int count = snd_pcm_lib_period_bytes(substream);
-
- chip->dma_size = size;
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_reset(chip);
- snd_es1688_set_rate(chip, substream);
- snd_es1688_dsp_command(chip, ES1688_DSP_CMD_SPKOFF);
- snd_es1688_write(chip, 0xb8, 0x0e); /* auto init DMA mode */
- snd_es1688_write(chip, 0xa8, (snd_es1688_read(chip, 0xa8) & ~0x03) | (3 - runtime->channels));
- snd_es1688_write(chip, 0xb9, 2); /* demand mode (4 bytes/request) */
- if (runtime->channels == 1) {
- if (snd_pcm_format_width(runtime->format) == 8) {
- /* 8. bit mono */
- snd_es1688_write(chip, 0xb7, 0x51);
- snd_es1688_write(chip, 0xb7, 0xd0);
- } else {
- /* 16. bit mono */
- snd_es1688_write(chip, 0xb7, 0x71);
- snd_es1688_write(chip, 0xb7, 0xf4);
- }
- } else {
- if (snd_pcm_format_width(runtime->format) == 8) {
- /* 8. bit stereo */
- snd_es1688_write(chip, 0xb7, 0x51);
- snd_es1688_write(chip, 0xb7, 0x98);
- } else {
- /* 16. bit stereo */
- snd_es1688_write(chip, 0xb7, 0x71);
- snd_es1688_write(chip, 0xb7, 0xbc);
- }
- }
- snd_es1688_write(chip, 0xb1, (snd_es1688_read(chip, 0xb1) & 0x0f) | 0x50);
- snd_es1688_write(chip, 0xb2, (snd_es1688_read(chip, 0xb2) & 0x0f) | 0x50);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- /* --- */
- count = -count;
- snd_dma_program(chip->dma8, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1688_write(chip, 0xa4, (unsigned char) count);
- snd_es1688_write(chip, 0xa5, (unsigned char) (count >> 8));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
-}
-
-static int snd_es1688_capture_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
- return snd_es1688_trigger(chip, cmd, 0x0f);
-}
-
-static irqreturn_t snd_es1688_interrupt(int irq, void *dev_id)
-{
- struct snd_es1688 *chip = dev_id;
-
- if (chip->trigger_value == 0x05) /* ok.. playback is active */
- snd_pcm_period_elapsed(chip->playback_substream);
- if (chip->trigger_value == 0x0f) /* ok.. capture is active */
- snd_pcm_period_elapsed(chip->capture_substream);
-
- inb(ES1688P(chip, DATA_AVAIL)); /* ack interrupt */
- return IRQ_HANDLED;
-}
-
-static snd_pcm_uframes_t snd_es1688_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
- size_t ptr;
-
- if (chip->trigger_value != 0x05)
- return 0;
- ptr = snd_dma_pointer(chip->dma8, chip->dma_size);
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-static snd_pcm_uframes_t snd_es1688_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
- size_t ptr;
-
- if (chip->trigger_value != 0x0f)
- return 0;
- ptr = snd_dma_pointer(chip->dma8, chip->dma_size);
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-/*
-
- */
-
-static struct snd_pcm_hardware snd_es1688_playback =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 65536,
- .period_bytes_min = 64,
- .period_bytes_max = 65536,
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_es1688_capture =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 65536,
- .period_bytes_min = 64,
- .period_bytes_max = 65536,
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-/*
-
- */
-
-static int snd_es1688_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- if (chip->capture_substream != NULL)
- return -EAGAIN;
- chip->playback_substream = substream;
- runtime->hw = snd_es1688_playback;
- snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &hw_constraints_clocks);
- return 0;
-}
-
-static int snd_es1688_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- if (chip->playback_substream != NULL)
- return -EAGAIN;
- chip->capture_substream = substream;
- runtime->hw = snd_es1688_capture;
- snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &hw_constraints_clocks);
- return 0;
-}
-
-static int snd_es1688_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
-
- chip->playback_substream = NULL;
- return 0;
-}
-
-static int snd_es1688_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
-
- chip->capture_substream = NULL;
- return 0;
-}
-
-static int snd_es1688_free(struct snd_es1688 *chip)
-{
- if (chip->res_port) {
- snd_es1688_init(chip, 0);
- release_and_free_resource(chip->res_port);
- }
- if (chip->irq >= 0)
- free_irq(chip->irq, (void *) chip);
- if (chip->dma8 >= 0) {
- disable_dma(chip->dma8);
- free_dma(chip->dma8);
- }
- return 0;
-}
-
-static int snd_es1688_dev_free(struct snd_device *device)
-{
- struct snd_es1688 *chip = device->device_data;
- return snd_es1688_free(chip);
-}
-
-static const char *snd_es1688_chip_id(struct snd_es1688 *chip)
-{
- static char tmp[16];
- sprintf(tmp, "ES%s688 rev %i", chip->hardware == ES1688_HW_688 ? "" : "1", chip->version & 0x0f);
- return tmp;
-}
-
-int snd_es1688_create(struct snd_card *card,
- struct snd_es1688 *chip,
- unsigned long port,
- unsigned long mpu_port,
- int irq,
- int mpu_irq,
- int dma8,
- unsigned short hardware)
-{
- static struct snd_device_ops ops = {
- .dev_free = snd_es1688_dev_free,
- };
-
- int err;
-
- if (chip == NULL)
- return -ENOMEM;
- chip->irq = -1;
- chip->dma8 = -1;
-
- if ((chip->res_port = request_region(port + 4, 12, "ES1688")) == NULL) {
- snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4);
- return -EBUSY;
- }
- if (request_irq(irq, snd_es1688_interrupt, 0, "ES1688", (void *) chip)) {
- snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq);
- return -EBUSY;
- }
- chip->irq = irq;
- if (request_dma(dma8, "ES1688")) {
- snd_printk(KERN_ERR "es1688: can't grab DMA8 %d\n", dma8);
- return -EBUSY;
- }
- chip->dma8 = dma8;
-
- spin_lock_init(&chip->reg_lock);
- spin_lock_init(&chip->mixer_lock);
- chip->port = port;
- mpu_port &= ~0x000f;
- if (mpu_port < 0x300 || mpu_port > 0x330)
- mpu_port = 0;
- chip->mpu_port = mpu_port;
- chip->mpu_irq = mpu_irq;
- chip->hardware = hardware;
-
- err = snd_es1688_probe(chip);
- if (err < 0)
- return err;
-
- err = snd_es1688_init(chip, 1);
- if (err < 0)
- return err;
-
- /* Register device */
- return snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
-}
-
-static struct snd_pcm_ops snd_es1688_playback_ops = {
- .open = snd_es1688_playback_open,
- .close = snd_es1688_playback_close,
- .ioctl = snd_es1688_ioctl,
- .hw_params = snd_es1688_hw_params,
- .hw_free = snd_es1688_hw_free,
- .prepare = snd_es1688_playback_prepare,
- .trigger = snd_es1688_playback_trigger,
- .pointer = snd_es1688_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_es1688_capture_ops = {
- .open = snd_es1688_capture_open,
- .close = snd_es1688_capture_close,
- .ioctl = snd_es1688_ioctl,
- .hw_params = snd_es1688_hw_params,
- .hw_free = snd_es1688_hw_free,
- .prepare = snd_es1688_capture_prepare,
- .trigger = snd_es1688_capture_trigger,
- .pointer = snd_es1688_capture_pointer,
-};
-
-int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip,
- int device, struct snd_pcm **rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- err = snd_pcm_new(card, "ESx688", device, 1, 1, &pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1688_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_es1688_capture_ops);
-
- pcm->private_data = chip;
- pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
- sprintf(pcm->name, snd_es1688_chip_id(chip));
- chip->pcm = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_isa_data(),
- 64*1024, 64*1024);
-
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-/*
- * MIXER part
- */
-
-static int snd_es1688_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[9] = {
- "Mic", "Mic Master", "CD", "AOUT",
- "Mic1", "Mix", "Line", "Master"
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 8;
- if (uinfo->value.enumerated.item > 7)
- uinfo->value.enumerated.item = 7;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_es1688_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = snd_es1688_mixer_read(chip, ES1688_REC_DEV) & 7;
- return 0;
-}
-
-static int snd_es1688_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- unsigned char oval, nval;
- int change;
-
- if (ucontrol->value.enumerated.item[0] > 8)
- return -EINVAL;
- spin_lock_irqsave(&chip->reg_lock, flags);
- oval = snd_es1688_mixer_read(chip, ES1688_REC_DEV);
- nval = (ucontrol->value.enumerated.item[0] & 7) | (oval & ~15);
- change = nval != oval;
- if (change)
- snd_es1688_mixer_write(chip, ES1688_REC_DEV, nval);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return change;
-}
-
-#define ES1688_SINGLE(xname, xindex, reg, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_es1688_info_single, \
- .get = snd_es1688_get_single, .put = snd_es1688_put_single, \
- .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
-
-static int snd_es1688_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 16) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_es1688_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- ucontrol->value.integer.value[0] = (snd_es1688_mixer_read(chip, reg) >> shift) & mask;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (invert)
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- return 0;
-}
-
-static int snd_es1688_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
- int change;
- unsigned char oval, nval;
-
- nval = (ucontrol->value.integer.value[0] & mask);
- if (invert)
- nval = mask - nval;
- nval <<= shift;
- spin_lock_irqsave(&chip->reg_lock, flags);
- oval = snd_es1688_mixer_read(chip, reg);
- nval = (oval & ~(mask << shift)) | nval;
- change = nval != oval;
- if (change)
- snd_es1688_mixer_write(chip, reg, nval);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return change;
-}
-
-#define ES1688_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_es1688_info_double, \
- .get = snd_es1688_get_double, .put = snd_es1688_put_double, \
- .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
-
-static int snd_es1688_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 24) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_es1688_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int shift_left = (kcontrol->private_value >> 16) & 0x07;
- int shift_right = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
- unsigned char left, right;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (left_reg < 0xa0)
- left = snd_es1688_mixer_read(chip, left_reg);
- else
- left = snd_es1688_read(chip, left_reg);
- if (left_reg != right_reg) {
- if (right_reg < 0xa0)
- right = snd_es1688_mixer_read(chip, right_reg);
- else
- right = snd_es1688_read(chip, right_reg);
- } else
- right = left;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- ucontrol->value.integer.value[0] = (left >> shift_left) & mask;
- ucontrol->value.integer.value[1] = (right >> shift_right) & mask;
- if (invert) {
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
- }
- return 0;
-}
-
-static int snd_es1688_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int shift_left = (kcontrol->private_value >> 16) & 0x07;
- int shift_right = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
- int change;
- unsigned char val1, val2, oval1, oval2;
-
- val1 = ucontrol->value.integer.value[0] & mask;
- val2 = ucontrol->value.integer.value[1] & mask;
- if (invert) {
- val1 = mask - val1;
- val2 = mask - val2;
- }
- val1 <<= shift_left;
- val2 <<= shift_right;
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (left_reg != right_reg) {
- if (left_reg < 0xa0)
- oval1 = snd_es1688_mixer_read(chip, left_reg);
- else
- oval1 = snd_es1688_read(chip, left_reg);
- if (right_reg < 0xa0)
- oval2 = snd_es1688_mixer_read(chip, right_reg);
- else
- oval2 = snd_es1688_read(chip, right_reg);
- val1 = (oval1 & ~(mask << shift_left)) | val1;
- val2 = (oval2 & ~(mask << shift_right)) | val2;
- change = val1 != oval1 || val2 != oval2;
- if (change) {
- if (left_reg < 0xa0)
- snd_es1688_mixer_write(chip, left_reg, val1);
- else
- snd_es1688_write(chip, left_reg, val1);
- if (right_reg < 0xa0)
- snd_es1688_mixer_write(chip, right_reg, val1);
- else
- snd_es1688_write(chip, right_reg, val1);
- }
- } else {
- if (left_reg < 0xa0)
- oval1 = snd_es1688_mixer_read(chip, left_reg);
- else
- oval1 = snd_es1688_read(chip, left_reg);
- val1 = (oval1 & ~((mask << shift_left) | (mask << shift_right))) | val1 | val2;
- change = val1 != oval1;
- if (change) {
- if (left_reg < 0xa0)
- snd_es1688_mixer_write(chip, left_reg, val1);
- else
- snd_es1688_write(chip, left_reg, val1);
- }
-
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return change;
-}
-
-static struct snd_kcontrol_new snd_es1688_controls[] = {
-ES1688_DOUBLE("Master Playback Volume", 0, ES1688_MASTER_DEV, ES1688_MASTER_DEV, 4, 0, 15, 0),
-ES1688_DOUBLE("PCM Playback Volume", 0, ES1688_PCM_DEV, ES1688_PCM_DEV, 4, 0, 15, 0),
-ES1688_DOUBLE("Line Playback Volume", 0, ES1688_LINE_DEV, ES1688_LINE_DEV, 4, 0, 15, 0),
-ES1688_DOUBLE("CD Playback Volume", 0, ES1688_CD_DEV, ES1688_CD_DEV, 4, 0, 15, 0),
-ES1688_DOUBLE("FM Playback Volume", 0, ES1688_FM_DEV, ES1688_FM_DEV, 4, 0, 15, 0),
-ES1688_DOUBLE("Mic Playback Volume", 0, ES1688_MIC_DEV, ES1688_MIC_DEV, 4, 0, 15, 0),
-ES1688_DOUBLE("Aux Playback Volume", 0, ES1688_AUX_DEV, ES1688_AUX_DEV, 4, 0, 15, 0),
-ES1688_SINGLE("Beep Playback Volume", 0, ES1688_SPEAKER_DEV, 0, 7, 0),
-ES1688_DOUBLE("Capture Volume", 0, ES1688_RECLEV_DEV, ES1688_RECLEV_DEV, 4, 0, 15, 0),
-ES1688_SINGLE("Capture Switch", 0, ES1688_REC_DEV, 4, 1, 1),
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = snd_es1688_info_mux,
- .get = snd_es1688_get_mux,
- .put = snd_es1688_put_mux,
-},
-};
-
-#define ES1688_INIT_TABLE_SIZE (sizeof(snd_es1688_init_table)/2)
-
-static unsigned char snd_es1688_init_table[][2] = {
- { ES1688_MASTER_DEV, 0 },
- { ES1688_PCM_DEV, 0 },
- { ES1688_LINE_DEV, 0 },
- { ES1688_CD_DEV, 0 },
- { ES1688_FM_DEV, 0 },
- { ES1688_MIC_DEV, 0 },
- { ES1688_AUX_DEV, 0 },
- { ES1688_SPEAKER_DEV, 0 },
- { ES1688_RECLEV_DEV, 0 },
- { ES1688_REC_DEV, 0x17 }
-};
-
-int snd_es1688_mixer(struct snd_card *card, struct snd_es1688 *chip)
-{
- unsigned int idx;
- int err;
- unsigned char reg, val;
-
- if (snd_BUG_ON(!chip || !card))
- return -EINVAL;
-
- strcpy(card->mixername, snd_es1688_chip_id(chip));
-
- for (idx = 0; idx < ARRAY_SIZE(snd_es1688_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es1688_controls[idx], chip))) < 0)
- return err;
- }
- for (idx = 0; idx < ES1688_INIT_TABLE_SIZE; idx++) {
- reg = snd_es1688_init_table[idx][0];
- val = snd_es1688_init_table[idx][1];
- if (reg < 0xa0)
- snd_es1688_mixer_write(chip, reg, val);
- else
- snd_es1688_write(chip, reg, val);
- }
- return 0;
-}
-
-EXPORT_SYMBOL(snd_es1688_mixer_write);
-EXPORT_SYMBOL(snd_es1688_create);
-EXPORT_SYMBOL(snd_es1688_pcm);
-EXPORT_SYMBOL(snd_es1688_mixer);
-
-/*
- * INIT part
- */
-
-static int __init alsa_es1688_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_es1688_exit(void)
-{
-}
-
-module_init(alsa_es1688_init)
-module_exit(alsa_es1688_exit)
diff --git a/ANDROID_3.4.5/sound/isa/es18xx.c b/ANDROID_3.4.5/sound/isa/es18xx.c
deleted file mode 100644
index c20baafd..00000000
--- a/ANDROID_3.4.5/sound/isa/es18xx.c
+++ /dev/null
@@ -1,2434 +0,0 @@
-/*
- * Driver for generic ESS AudioDrive ES18xx soundcards
- * Copyright (c) by Christian Fischbach <fishbach@pool.informatik.rwth-aachen.de>
- * Copyright (c) by Abramo Bagnara <abramo@alsa-project.org>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-/* GENERAL NOTES:
- *
- * BUGS:
- * - There are pops (we can't delay in trigger function, cause midlevel
- * often need to trigger down and then up very quickly).
- * Any ideas?
- * - Support for 16 bit DMA seems to be broken. I've no hardware to tune it.
- */
-
-/*
- * ES1868 NOTES:
- * - The chip has one half duplex pcm (with very limited full duplex support).
- *
- * - Duplex stereophonic sound is impossible.
- * - Record and playback must share the same frequency rate.
- *
- * - The driver use dma2 for playback and dma1 for capture.
- */
-
-/*
- * ES1869 NOTES:
- *
- * - there are a first full duplex pcm and a second playback only pcm
- * (incompatible with first pcm capture)
- *
- * - there is support for the capture volume and ESS Spatializer 3D effect.
- *
- * - contrarily to some pages in DS_1869.PDF the rates can be set
- * independently.
- *
- * - Zoom Video is implemented by sharing the FM DAC, thus the user can
- * have either FM playback or Video playback but not both simultaneously.
- * The Video Playback Switch mixer control toggles this choice.
- *
- * BUGS:
- *
- * - There is a major trouble I noted:
- *
- * using both channel for playback stereo 16 bit samples at 44100 Hz
- * the second pcm (Audio1) DMA slows down irregularly and sound is garbled.
- *
- * The same happens using Audio1 for captureing.
- *
- * The Windows driver does not suffer of this (although it use Audio1
- * only for captureing). I'm unable to discover why.
- *
- */
-
-/*
- * ES1879 NOTES:
- * - When Zoom Video is enabled (reg 0x71 bit 6 toggled on) the PCM playback
- * seems to be effected (speaker_test plays a lower frequency). Can't find
- * anything in the datasheet to account for this, so a Video Playback Switch
- * control has been included to allow ZV to be enabled only when necessary.
- * Then again on at least one test system the 0x71 bit 6 enable bit is not
- * needed for ZV, so maybe the datasheet is entirely wrong here.
- */
-
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/isa.h>
-#include <linux/pnp.h>
-#include <linux/isapnp.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/mpu401.h>
-#include <sound/opl3.h>
-#define SNDRV_LEGACY_FIND_FREE_IRQ
-#define SNDRV_LEGACY_FIND_FREE_DMA
-#include <sound/initval.h>
-
-#define PFX "es18xx: "
-
-struct snd_es18xx {
- unsigned long port; /* port of ESS chip */
- unsigned long ctrl_port; /* Control port of ESS chip */
- struct resource *res_port;
- struct resource *res_mpu_port;
- struct resource *res_ctrl_port;
- int irq; /* IRQ number of ESS chip */
- int dma1; /* DMA1 */
- int dma2; /* DMA2 */
- unsigned short version; /* version of ESS chip */
- int caps; /* Chip capabilities */
- unsigned short audio2_vol; /* volume level of audio2 */
-
- unsigned short active; /* active channel mask */
- unsigned int dma1_shift;
- unsigned int dma2_shift;
-
- struct snd_pcm *pcm;
- struct snd_pcm_substream *playback_a_substream;
- struct snd_pcm_substream *capture_a_substream;
- struct snd_pcm_substream *playback_b_substream;
-
- struct snd_rawmidi *rmidi;
-
- struct snd_kcontrol *hw_volume;
- struct snd_kcontrol *hw_switch;
- struct snd_kcontrol *master_volume;
- struct snd_kcontrol *master_switch;
-
- spinlock_t reg_lock;
- spinlock_t mixer_lock;
-#ifdef CONFIG_PM
- unsigned char pm_reg;
-#endif
-#ifdef CONFIG_PNP
- struct pnp_dev *dev;
- struct pnp_dev *devc;
-#endif
-};
-
-#define AUDIO1_IRQ 0x01
-#define AUDIO2_IRQ 0x02
-#define HWV_IRQ 0x04
-#define MPU_IRQ 0x08
-
-#define ES18XX_PCM2 0x0001 /* Has two useable PCM */
-#define ES18XX_SPATIALIZER 0x0002 /* Has 3D Spatializer */
-#define ES18XX_RECMIX 0x0004 /* Has record mixer */
-#define ES18XX_DUPLEX_MONO 0x0008 /* Has mono duplex only */
-#define ES18XX_DUPLEX_SAME 0x0010 /* Playback and record must share the same rate */
-#define ES18XX_NEW_RATE 0x0020 /* More precise rate setting */
-#define ES18XX_AUXB 0x0040 /* AuxB mixer control */
-#define ES18XX_HWV 0x0080 /* Has separate hardware volume mixer controls*/
-#define ES18XX_MONO 0x0100 /* Mono_in mixer control */
-#define ES18XX_I2S 0x0200 /* I2S mixer control */
-#define ES18XX_MUTEREC 0x0400 /* Record source can be muted */
-#define ES18XX_CONTROL 0x0800 /* Has control ports */
-
-/* Power Management */
-#define ES18XX_PM 0x07
-#define ES18XX_PM_GPO0 0x01
-#define ES18XX_PM_GPO1 0x02
-#define ES18XX_PM_PDR 0x04
-#define ES18XX_PM_ANA 0x08
-#define ES18XX_PM_FM 0x020
-#define ES18XX_PM_SUS 0x080
-
-/* Lowlevel */
-
-#define DAC1 0x01
-#define ADC1 0x02
-#define DAC2 0x04
-#define MILLISECOND 10000
-
-static int snd_es18xx_dsp_command(struct snd_es18xx *chip, unsigned char val)
-{
- int i;
-
- for(i = MILLISECOND; i; i--)
- if ((inb(chip->port + 0x0C) & 0x80) == 0) {
- outb(val, chip->port + 0x0C);
- return 0;
- }
- snd_printk(KERN_ERR "dsp_command: timeout (0x%x)\n", val);
- return -EINVAL;
-}
-
-static int snd_es18xx_dsp_get_byte(struct snd_es18xx *chip)
-{
- int i;
-
- for(i = MILLISECOND/10; i; i--)
- if (inb(chip->port + 0x0C) & 0x40)
- return inb(chip->port + 0x0A);
- snd_printk(KERN_ERR "dsp_get_byte failed: 0x%lx = 0x%x!!!\n",
- chip->port + 0x0A, inb(chip->port + 0x0A));
- return -ENODEV;
-}
-
-#undef REG_DEBUG
-
-static int snd_es18xx_write(struct snd_es18xx *chip,
- unsigned char reg, unsigned char data)
-{
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- ret = snd_es18xx_dsp_command(chip, reg);
- if (ret < 0)
- goto end;
- ret = snd_es18xx_dsp_command(chip, data);
- end:
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-#ifdef REG_DEBUG
- snd_printk(KERN_DEBUG "Reg %02x set to %02x\n", reg, data);
-#endif
- return ret;
-}
-
-static int snd_es18xx_read(struct snd_es18xx *chip, unsigned char reg)
-{
- unsigned long flags;
- int ret, data;
- spin_lock_irqsave(&chip->reg_lock, flags);
- ret = snd_es18xx_dsp_command(chip, 0xC0);
- if (ret < 0)
- goto end;
- ret = snd_es18xx_dsp_command(chip, reg);
- if (ret < 0)
- goto end;
- data = snd_es18xx_dsp_get_byte(chip);
- ret = data;
-#ifdef REG_DEBUG
- snd_printk(KERN_DEBUG "Reg %02x now is %02x (%d)\n", reg, data, ret);
-#endif
- end:
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return ret;
-}
-
-/* Return old value */
-static int snd_es18xx_bits(struct snd_es18xx *chip, unsigned char reg,
- unsigned char mask, unsigned char val)
-{
- int ret;
- unsigned char old, new, oval;
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
- ret = snd_es18xx_dsp_command(chip, 0xC0);
- if (ret < 0)
- goto end;
- ret = snd_es18xx_dsp_command(chip, reg);
- if (ret < 0)
- goto end;
- ret = snd_es18xx_dsp_get_byte(chip);
- if (ret < 0) {
- goto end;
- }
- old = ret;
- oval = old & mask;
- if (val != oval) {
- ret = snd_es18xx_dsp_command(chip, reg);
- if (ret < 0)
- goto end;
- new = (old & ~mask) | (val & mask);
- ret = snd_es18xx_dsp_command(chip, new);
- if (ret < 0)
- goto end;
-#ifdef REG_DEBUG
- snd_printk(KERN_DEBUG "Reg %02x was %02x, set to %02x (%d)\n",
- reg, old, new, ret);
-#endif
- }
- ret = oval;
- end:
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return ret;
-}
-
-static inline void snd_es18xx_mixer_write(struct snd_es18xx *chip,
- unsigned char reg, unsigned char data)
-{
- unsigned long flags;
- spin_lock_irqsave(&chip->mixer_lock, flags);
- outb(reg, chip->port + 0x04);
- outb(data, chip->port + 0x05);
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
-#ifdef REG_DEBUG
- snd_printk(KERN_DEBUG "Mixer reg %02x set to %02x\n", reg, data);
-#endif
-}
-
-static inline int snd_es18xx_mixer_read(struct snd_es18xx *chip, unsigned char reg)
-{
- unsigned long flags;
- int data;
- spin_lock_irqsave(&chip->mixer_lock, flags);
- outb(reg, chip->port + 0x04);
- data = inb(chip->port + 0x05);
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
-#ifdef REG_DEBUG
- snd_printk(KERN_DEBUG "Mixer reg %02x now is %02x\n", reg, data);
-#endif
- return data;
-}
-
-/* Return old value */
-static inline int snd_es18xx_mixer_bits(struct snd_es18xx *chip, unsigned char reg,
- unsigned char mask, unsigned char val)
-{
- unsigned char old, new, oval;
- unsigned long flags;
- spin_lock_irqsave(&chip->mixer_lock, flags);
- outb(reg, chip->port + 0x04);
- old = inb(chip->port + 0x05);
- oval = old & mask;
- if (val != oval) {
- new = (old & ~mask) | (val & mask);
- outb(new, chip->port + 0x05);
-#ifdef REG_DEBUG
- snd_printk(KERN_DEBUG "Mixer reg %02x was %02x, set to %02x\n",
- reg, old, new);
-#endif
- }
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
- return oval;
-}
-
-static inline int snd_es18xx_mixer_writable(struct snd_es18xx *chip, unsigned char reg,
- unsigned char mask)
-{
- int old, expected, new;
- unsigned long flags;
- spin_lock_irqsave(&chip->mixer_lock, flags);
- outb(reg, chip->port + 0x04);
- old = inb(chip->port + 0x05);
- expected = old ^ mask;
- outb(expected, chip->port + 0x05);
- new = inb(chip->port + 0x05);
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
-#ifdef REG_DEBUG
- snd_printk(KERN_DEBUG "Mixer reg %02x was %02x, set to %02x, now is %02x\n",
- reg, old, expected, new);
-#endif
- return expected == new;
-}
-
-
-static int __devinit snd_es18xx_reset(struct snd_es18xx *chip)
-{
- int i;
- outb(0x03, chip->port + 0x06);
- inb(chip->port + 0x06);
- outb(0x00, chip->port + 0x06);
- for(i = 0; i < MILLISECOND && !(inb(chip->port + 0x0E) & 0x80); i++);
- if (inb(chip->port + 0x0A) != 0xAA)
- return -1;
- return 0;
-}
-
-static int snd_es18xx_reset_fifo(struct snd_es18xx *chip)
-{
- outb(0x02, chip->port + 0x06);
- inb(chip->port + 0x06);
- outb(0x00, chip->port + 0x06);
- return 0;
-}
-
-static struct snd_ratnum new_clocks[2] = {
- {
- .num = 793800,
- .den_min = 1,
- .den_max = 128,
- .den_step = 1,
- },
- {
- .num = 768000,
- .den_min = 1,
- .den_max = 128,
- .den_step = 1,
- }
-};
-
-static struct snd_pcm_hw_constraint_ratnums new_hw_constraints_clocks = {
- .nrats = 2,
- .rats = new_clocks,
-};
-
-static struct snd_ratnum old_clocks[2] = {
- {
- .num = 795444,
- .den_min = 1,
- .den_max = 128,
- .den_step = 1,
- },
- {
- .num = 397722,
- .den_min = 1,
- .den_max = 128,
- .den_step = 1,
- }
-};
-
-static struct snd_pcm_hw_constraint_ratnums old_hw_constraints_clocks = {
- .nrats = 2,
- .rats = old_clocks,
-};
-
-
-static void snd_es18xx_rate_set(struct snd_es18xx *chip,
- struct snd_pcm_substream *substream,
- int mode)
-{
- unsigned int bits, div0;
- struct snd_pcm_runtime *runtime = substream->runtime;
- if (chip->caps & ES18XX_NEW_RATE) {
- if (runtime->rate_num == new_clocks[0].num)
- bits = 128 - runtime->rate_den;
- else
- bits = 256 - runtime->rate_den;
- } else {
- if (runtime->rate_num == old_clocks[0].num)
- bits = 256 - runtime->rate_den;
- else
- bits = 128 - runtime->rate_den;
- }
-
- /* set filter register */
- div0 = 256 - 7160000*20/(8*82*runtime->rate);
-
- if ((chip->caps & ES18XX_PCM2) && mode == DAC2) {
- snd_es18xx_mixer_write(chip, 0x70, bits);
- /*
- * Comment from kernel oss driver:
- * FKS: fascinating: 0x72 doesn't seem to work.
- */
- snd_es18xx_write(chip, 0xA2, div0);
- snd_es18xx_mixer_write(chip, 0x72, div0);
- } else {
- snd_es18xx_write(chip, 0xA1, bits);
- snd_es18xx_write(chip, 0xA2, div0);
- }
-}
-
-static int snd_es18xx_playback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
- int shift, err;
-
- shift = 0;
- if (params_channels(hw_params) == 2)
- shift++;
- if (snd_pcm_format_width(params_format(hw_params)) == 16)
- shift++;
-
- if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) {
- if ((chip->caps & ES18XX_DUPLEX_MONO) &&
- (chip->capture_a_substream) &&
- params_channels(hw_params) != 1) {
- _snd_pcm_hw_param_setempty(hw_params, SNDRV_PCM_HW_PARAM_CHANNELS);
- return -EBUSY;
- }
- chip->dma2_shift = shift;
- } else {
- chip->dma1_shift = shift;
- }
- if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
- return err;
- return 0;
-}
-
-static int snd_es18xx_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_es18xx_playback1_prepare(struct snd_es18xx *chip,
- struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int size = snd_pcm_lib_buffer_bytes(substream);
- unsigned int count = snd_pcm_lib_period_bytes(substream);
-
- snd_es18xx_rate_set(chip, substream, DAC2);
-
- /* Transfer Count Reload */
- count = 0x10000 - count;
- snd_es18xx_mixer_write(chip, 0x74, count & 0xff);
- snd_es18xx_mixer_write(chip, 0x76, count >> 8);
-
- /* Set format */
- snd_es18xx_mixer_bits(chip, 0x7A, 0x07,
- ((runtime->channels == 1) ? 0x00 : 0x02) |
- (snd_pcm_format_width(runtime->format) == 16 ? 0x01 : 0x00) |
- (snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x04));
-
- /* Set DMA controller */
- snd_dma_program(chip->dma2, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
-
- return 0;
-}
-
-static int snd_es18xx_playback1_trigger(struct snd_es18xx *chip,
- struct snd_pcm_substream *substream,
- int cmd)
-{
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- if (chip->active & DAC2)
- return 0;
- chip->active |= DAC2;
- /* Start DMA */
- if (chip->dma2 >= 4)
- snd_es18xx_mixer_write(chip, 0x78, 0xb3);
- else
- snd_es18xx_mixer_write(chip, 0x78, 0x93);
-#ifdef AVOID_POPS
- /* Avoid pops */
- udelay(100000);
- if (chip->caps & ES18XX_PCM2)
- /* Restore Audio 2 volume */
- snd_es18xx_mixer_write(chip, 0x7C, chip->audio2_vol);
- else
- /* Enable PCM output */
- snd_es18xx_dsp_command(chip, 0xD1);
-#endif
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- if (!(chip->active & DAC2))
- return 0;
- chip->active &= ~DAC2;
- /* Stop DMA */
- snd_es18xx_mixer_write(chip, 0x78, 0x00);
-#ifdef AVOID_POPS
- udelay(25000);
- if (chip->caps & ES18XX_PCM2)
- /* Set Audio 2 volume to 0 */
- snd_es18xx_mixer_write(chip, 0x7C, 0);
- else
- /* Disable PCM output */
- snd_es18xx_dsp_command(chip, 0xD3);
-#endif
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int snd_es18xx_capture_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
- int shift, err;
-
- shift = 0;
- if ((chip->caps & ES18XX_DUPLEX_MONO) &&
- chip->playback_a_substream &&
- params_channels(hw_params) != 1) {
- _snd_pcm_hw_param_setempty(hw_params, SNDRV_PCM_HW_PARAM_CHANNELS);
- return -EBUSY;
- }
- if (params_channels(hw_params) == 2)
- shift++;
- if (snd_pcm_format_width(params_format(hw_params)) == 16)
- shift++;
- chip->dma1_shift = shift;
- if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
- return err;
- return 0;
-}
-
-static int snd_es18xx_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int size = snd_pcm_lib_buffer_bytes(substream);
- unsigned int count = snd_pcm_lib_period_bytes(substream);
-
- snd_es18xx_reset_fifo(chip);
-
- /* Set stereo/mono */
- snd_es18xx_bits(chip, 0xA8, 0x03, runtime->channels == 1 ? 0x02 : 0x01);
-
- snd_es18xx_rate_set(chip, substream, ADC1);
-
- /* Transfer Count Reload */
- count = 0x10000 - count;
- snd_es18xx_write(chip, 0xA4, count & 0xff);
- snd_es18xx_write(chip, 0xA5, count >> 8);
-
-#ifdef AVOID_POPS
- udelay(100000);
-#endif
-
- /* Set format */
- snd_es18xx_write(chip, 0xB7,
- snd_pcm_format_unsigned(runtime->format) ? 0x51 : 0x71);
- snd_es18xx_write(chip, 0xB7, 0x90 |
- ((runtime->channels == 1) ? 0x40 : 0x08) |
- (snd_pcm_format_width(runtime->format) == 16 ? 0x04 : 0x00) |
- (snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x20));
-
- /* Set DMA controller */
- snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
-
- return 0;
-}
-
-static int snd_es18xx_capture_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- if (chip->active & ADC1)
- return 0;
- chip->active |= ADC1;
- /* Start DMA */
- snd_es18xx_write(chip, 0xB8, 0x0f);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- if (!(chip->active & ADC1))
- return 0;
- chip->active &= ~ADC1;
- /* Stop DMA */
- snd_es18xx_write(chip, 0xB8, 0x00);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int snd_es18xx_playback2_prepare(struct snd_es18xx *chip,
- struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int size = snd_pcm_lib_buffer_bytes(substream);
- unsigned int count = snd_pcm_lib_period_bytes(substream);
-
- snd_es18xx_reset_fifo(chip);
-
- /* Set stereo/mono */
- snd_es18xx_bits(chip, 0xA8, 0x03, runtime->channels == 1 ? 0x02 : 0x01);
-
- snd_es18xx_rate_set(chip, substream, DAC1);
-
- /* Transfer Count Reload */
- count = 0x10000 - count;
- snd_es18xx_write(chip, 0xA4, count & 0xff);
- snd_es18xx_write(chip, 0xA5, count >> 8);
-
- /* Set format */
- snd_es18xx_write(chip, 0xB6,
- snd_pcm_format_unsigned(runtime->format) ? 0x80 : 0x00);
- snd_es18xx_write(chip, 0xB7,
- snd_pcm_format_unsigned(runtime->format) ? 0x51 : 0x71);
- snd_es18xx_write(chip, 0xB7, 0x90 |
- (runtime->channels == 1 ? 0x40 : 0x08) |
- (snd_pcm_format_width(runtime->format) == 16 ? 0x04 : 0x00) |
- (snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x20));
-
- /* Set DMA controller */
- snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
-
- return 0;
-}
-
-static int snd_es18xx_playback2_trigger(struct snd_es18xx *chip,
- struct snd_pcm_substream *substream,
- int cmd)
-{
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- if (chip->active & DAC1)
- return 0;
- chip->active |= DAC1;
- /* Start DMA */
- snd_es18xx_write(chip, 0xB8, 0x05);
-#ifdef AVOID_POPS
- /* Avoid pops */
- udelay(100000);
- /* Enable Audio 1 */
- snd_es18xx_dsp_command(chip, 0xD1);
-#endif
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- if (!(chip->active & DAC1))
- return 0;
- chip->active &= ~DAC1;
- /* Stop DMA */
- snd_es18xx_write(chip, 0xB8, 0x00);
-#ifdef AVOID_POPS
- /* Avoid pops */
- udelay(25000);
- /* Disable Audio 1 */
- snd_es18xx_dsp_command(chip, 0xD3);
-#endif
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int snd_es18xx_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
- if (substream->number == 0 && (chip->caps & ES18XX_PCM2))
- return snd_es18xx_playback1_prepare(chip, substream);
- else
- return snd_es18xx_playback2_prepare(chip, substream);
-}
-
-static int snd_es18xx_playback_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
- if (substream->number == 0 && (chip->caps & ES18XX_PCM2))
- return snd_es18xx_playback1_trigger(chip, substream, cmd);
- else
- return snd_es18xx_playback2_trigger(chip, substream, cmd);
-}
-
-static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id)
-{
- struct snd_card *card = dev_id;
- struct snd_es18xx *chip = card->private_data;
- unsigned char status;
-
- if (chip->caps & ES18XX_CONTROL) {
- /* Read Interrupt status */
- status = inb(chip->ctrl_port + 6);
- } else {
- /* Read Interrupt status */
- status = snd_es18xx_mixer_read(chip, 0x7f) >> 4;
- }
-#if 0
- else {
- status = 0;
- if (inb(chip->port + 0x0C) & 0x01)
- status |= AUDIO1_IRQ;
- if (snd_es18xx_mixer_read(chip, 0x7A) & 0x80)
- status |= AUDIO2_IRQ;
- if ((chip->caps & ES18XX_HWV) &&
- snd_es18xx_mixer_read(chip, 0x64) & 0x10)
- status |= HWV_IRQ;
- }
-#endif
-
- /* Audio 1 & Audio 2 */
- if (status & AUDIO2_IRQ) {
- if (chip->active & DAC2)
- snd_pcm_period_elapsed(chip->playback_a_substream);
- /* ack interrupt */
- snd_es18xx_mixer_bits(chip, 0x7A, 0x80, 0x00);
- }
- if (status & AUDIO1_IRQ) {
- /* ok.. capture is active */
- if (chip->active & ADC1)
- snd_pcm_period_elapsed(chip->capture_a_substream);
- /* ok.. playback2 is active */
- else if (chip->active & DAC1)
- snd_pcm_period_elapsed(chip->playback_b_substream);
- /* ack interrupt */
- inb(chip->port + 0x0E);
- }
-
- /* MPU */
- if ((status & MPU_IRQ) && chip->rmidi)
- snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
-
- /* Hardware volume */
- if (status & HWV_IRQ) {
- int split = 0;
- if (chip->caps & ES18XX_HWV) {
- split = snd_es18xx_mixer_read(chip, 0x64) & 0x80;
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->hw_switch->id);
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->hw_volume->id);
- }
- if (!split) {
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->master_switch->id);
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->master_volume->id);
- }
- /* ack interrupt */
- snd_es18xx_mixer_write(chip, 0x66, 0x00);
- }
- return IRQ_HANDLED;
-}
-
-static snd_pcm_uframes_t snd_es18xx_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
- unsigned int size = snd_pcm_lib_buffer_bytes(substream);
- int pos;
-
- if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) {
- if (!(chip->active & DAC2))
- return 0;
- pos = snd_dma_pointer(chip->dma2, size);
- return pos >> chip->dma2_shift;
- } else {
- if (!(chip->active & DAC1))
- return 0;
- pos = snd_dma_pointer(chip->dma1, size);
- return pos >> chip->dma1_shift;
- }
-}
-
-static snd_pcm_uframes_t snd_es18xx_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
- unsigned int size = snd_pcm_lib_buffer_bytes(substream);
- int pos;
-
- if (!(chip->active & ADC1))
- return 0;
- pos = snd_dma_pointer(chip->dma1, size);
- return pos >> chip->dma1_shift;
-}
-
-static struct snd_pcm_hardware snd_es18xx_playback =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 65536,
- .period_bytes_min = 64,
- .period_bytes_max = 65536,
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_es18xx_capture =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 65536,
- .period_bytes_min = 64,
- .period_bytes_max = 65536,
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static int snd_es18xx_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
-
- if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) {
- if ((chip->caps & ES18XX_DUPLEX_MONO) &&
- chip->capture_a_substream &&
- chip->capture_a_substream->runtime->channels != 1)
- return -EAGAIN;
- chip->playback_a_substream = substream;
- } else if (substream->number <= 1) {
- if (chip->capture_a_substream)
- return -EAGAIN;
- chip->playback_b_substream = substream;
- } else {
- snd_BUG();
- return -EINVAL;
- }
- substream->runtime->hw = snd_es18xx_playback;
- snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- (chip->caps & ES18XX_NEW_RATE) ? &new_hw_constraints_clocks : &old_hw_constraints_clocks);
- return 0;
-}
-
-static int snd_es18xx_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
-
- if (chip->playback_b_substream)
- return -EAGAIN;
- if ((chip->caps & ES18XX_DUPLEX_MONO) &&
- chip->playback_a_substream &&
- chip->playback_a_substream->runtime->channels != 1)
- return -EAGAIN;
- chip->capture_a_substream = substream;
- substream->runtime->hw = snd_es18xx_capture;
- snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- (chip->caps & ES18XX_NEW_RATE) ? &new_hw_constraints_clocks : &old_hw_constraints_clocks);
- return 0;
-}
-
-static int snd_es18xx_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
-
- if (substream->number == 0 && (chip->caps & ES18XX_PCM2))
- chip->playback_a_substream = NULL;
- else
- chip->playback_b_substream = NULL;
-
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-static int snd_es18xx_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
-
- chip->capture_a_substream = NULL;
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-/*
- * MIXER part
- */
-
-/* Record source mux routines:
- * Depending on the chipset this mux switches between 4, 5, or 8 possible inputs.
- * bit table for the 4/5 source mux:
- * reg 1C:
- * b2 b1 b0 muxSource
- * x 0 x microphone
- * 0 1 x CD
- * 1 1 0 line
- * 1 1 1 mixer
- * if it's "mixer" and it's a 5 source mux chipset then reg 7A bit 3 determines
- * either the play mixer or the capture mixer.
- *
- * "map4Source" translates from source number to reg bit pattern
- * "invMap4Source" translates from reg bit pattern to source number
- */
-
-static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts5Source[5] = {
- "Mic", "CD", "Line", "Master", "Mix"
- };
- static char *texts8Source[8] = {
- "Mic", "Mic Master", "CD", "AOUT",
- "Mic1", "Mix", "Line", "Master"
- };
- struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- switch (chip->version) {
- case 0x1868:
- case 0x1878:
- uinfo->value.enumerated.items = 4;
- if (uinfo->value.enumerated.item > 3)
- uinfo->value.enumerated.item = 3;
- strcpy(uinfo->value.enumerated.name,
- texts5Source[uinfo->value.enumerated.item]);
- break;
- case 0x1887:
- case 0x1888:
- uinfo->value.enumerated.items = 5;
- if (uinfo->value.enumerated.item > 4)
- uinfo->value.enumerated.item = 4;
- strcpy(uinfo->value.enumerated.name, texts5Source[uinfo->value.enumerated.item]);
- break;
- case 0x1869: /* DS somewhat contradictory for 1869: could be be 5 or 8 */
- case 0x1879:
- uinfo->value.enumerated.items = 8;
- if (uinfo->value.enumerated.item > 7)
- uinfo->value.enumerated.item = 7;
- strcpy(uinfo->value.enumerated.name, texts8Source[uinfo->value.enumerated.item]);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int snd_es18xx_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- static unsigned char invMap4Source[8] = {0, 0, 1, 1, 0, 0, 2, 3};
- struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
- int muxSource = snd_es18xx_mixer_read(chip, 0x1c) & 0x07;
- if (!(chip->version == 0x1869 || chip->version == 0x1879)) {
- muxSource = invMap4Source[muxSource];
- if (muxSource==3 &&
- (chip->version == 0x1887 || chip->version == 0x1888) &&
- (snd_es18xx_mixer_read(chip, 0x7a) & 0x08)
- )
- muxSource = 4;
- }
- ucontrol->value.enumerated.item[0] = muxSource;
- return 0;
-}
-
-static int snd_es18xx_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- static unsigned char map4Source[4] = {0, 2, 6, 7};
- struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
- unsigned char val = ucontrol->value.enumerated.item[0];
- unsigned char retVal = 0;
-
- switch (chip->version) {
- /* 5 source chips */
- case 0x1887:
- case 0x1888:
- if (val > 4)
- return -EINVAL;
- if (val == 4) {
- retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x08) != 0x08;
- val = 3;
- } else
- retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x00) != 0x00;
- /* 4 source chips */
- case 0x1868:
- case 0x1878:
- if (val > 3)
- return -EINVAL;
- val = map4Source[val];
- break;
- /* 8 source chips */
- case 0x1869:
- case 0x1879:
- if (val > 7)
- return -EINVAL;
- break;
- default:
- return -EINVAL;
- }
- return (snd_es18xx_mixer_bits(chip, 0x1c, 0x07, val) != val) || retVal;
-}
-
-#define snd_es18xx_info_spatializer_enable snd_ctl_boolean_mono_info
-
-static int snd_es18xx_get_spatializer_enable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
- unsigned char val = snd_es18xx_mixer_read(chip, 0x50);
- ucontrol->value.integer.value[0] = !!(val & 8);
- return 0;
-}
-
-static int snd_es18xx_put_spatializer_enable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
- unsigned char oval, nval;
- int change;
- nval = ucontrol->value.integer.value[0] ? 0x0c : 0x04;
- oval = snd_es18xx_mixer_read(chip, 0x50) & 0x0c;
- change = nval != oval;
- if (change) {
- snd_es18xx_mixer_write(chip, 0x50, nval & ~0x04);
- snd_es18xx_mixer_write(chip, 0x50, nval);
- }
- return change;
-}
-
-static int snd_es18xx_info_hw_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 63;
- return 0;
-}
-
-static int snd_es18xx_get_hw_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = snd_es18xx_mixer_read(chip, 0x61) & 0x3f;
- ucontrol->value.integer.value[1] = snd_es18xx_mixer_read(chip, 0x63) & 0x3f;
- return 0;
-}
-
-#define snd_es18xx_info_hw_switch snd_ctl_boolean_stereo_info
-
-static int snd_es18xx_get_hw_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = !(snd_es18xx_mixer_read(chip, 0x61) & 0x40);
- ucontrol->value.integer.value[1] = !(snd_es18xx_mixer_read(chip, 0x63) & 0x40);
- return 0;
-}
-
-static void snd_es18xx_hwv_free(struct snd_kcontrol *kcontrol)
-{
- struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
- chip->master_volume = NULL;
- chip->master_switch = NULL;
- chip->hw_volume = NULL;
- chip->hw_switch = NULL;
-}
-
-static int snd_es18xx_reg_bits(struct snd_es18xx *chip, unsigned char reg,
- unsigned char mask, unsigned char val)
-{
- if (reg < 0xa0)
- return snd_es18xx_mixer_bits(chip, reg, mask, val);
- else
- return snd_es18xx_bits(chip, reg, mask, val);
-}
-
-static int snd_es18xx_reg_read(struct snd_es18xx *chip, unsigned char reg)
-{
- if (reg < 0xa0)
- return snd_es18xx_mixer_read(chip, reg);
- else
- return snd_es18xx_read(chip, reg);
-}
-
-#define ES18XX_SINGLE(xname, xindex, reg, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_es18xx_info_single, \
- .get = snd_es18xx_get_single, .put = snd_es18xx_put_single, \
- .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
-
-static int snd_es18xx_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 16) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_es18xx_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
- int val;
-
- val = snd_es18xx_reg_read(chip, reg);
- ucontrol->value.integer.value[0] = (val >> shift) & mask;
- if (invert)
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- return 0;
-}
-
-static int snd_es18xx_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
- unsigned char val;
-
- val = (ucontrol->value.integer.value[0] & mask);
- if (invert)
- val = mask - val;
- mask <<= shift;
- val <<= shift;
- return snd_es18xx_reg_bits(chip, reg, mask, val) != val;
-}
-
-#define ES18XX_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_es18xx_info_double, \
- .get = snd_es18xx_get_double, .put = snd_es18xx_put_double, \
- .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
-
-static int snd_es18xx_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 24) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_es18xx_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int shift_left = (kcontrol->private_value >> 16) & 0x07;
- int shift_right = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
- unsigned char left, right;
-
- left = snd_es18xx_reg_read(chip, left_reg);
- if (left_reg != right_reg)
- right = snd_es18xx_reg_read(chip, right_reg);
- else
- right = left;
- ucontrol->value.integer.value[0] = (left >> shift_left) & mask;
- ucontrol->value.integer.value[1] = (right >> shift_right) & mask;
- if (invert) {
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
- }
- return 0;
-}
-
-static int snd_es18xx_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int shift_left = (kcontrol->private_value >> 16) & 0x07;
- int shift_right = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
- int change;
- unsigned char val1, val2, mask1, mask2;
-
- val1 = ucontrol->value.integer.value[0] & mask;
- val2 = ucontrol->value.integer.value[1] & mask;
- if (invert) {
- val1 = mask - val1;
- val2 = mask - val2;
- }
- val1 <<= shift_left;
- val2 <<= shift_right;
- mask1 = mask << shift_left;
- mask2 = mask << shift_right;
- if (left_reg != right_reg) {
- change = 0;
- if (snd_es18xx_reg_bits(chip, left_reg, mask1, val1) != val1)
- change = 1;
- if (snd_es18xx_reg_bits(chip, right_reg, mask2, val2) != val2)
- change = 1;
- } else {
- change = (snd_es18xx_reg_bits(chip, left_reg, mask1 | mask2,
- val1 | val2) != (val1 | val2));
- }
- return change;
-}
-
-/* Mixer controls
- * These arrays contain setup data for mixer controls.
- *
- * The controls that are universal to all chipsets are fully initialized
- * here.
- */
-static struct snd_kcontrol_new snd_es18xx_base_controls[] = {
-ES18XX_DOUBLE("Master Playback Volume", 0, 0x60, 0x62, 0, 0, 63, 0),
-ES18XX_DOUBLE("Master Playback Switch", 0, 0x60, 0x62, 6, 6, 1, 1),
-ES18XX_DOUBLE("Line Playback Volume", 0, 0x3e, 0x3e, 4, 0, 15, 0),
-ES18XX_DOUBLE("CD Playback Volume", 0, 0x38, 0x38, 4, 0, 15, 0),
-ES18XX_DOUBLE("FM Playback Volume", 0, 0x36, 0x36, 4, 0, 15, 0),
-ES18XX_DOUBLE("Mic Playback Volume", 0, 0x1a, 0x1a, 4, 0, 15, 0),
-ES18XX_DOUBLE("Aux Playback Volume", 0, 0x3a, 0x3a, 4, 0, 15, 0),
-ES18XX_SINGLE("Record Monitor", 0, 0xa8, 3, 1, 0),
-ES18XX_DOUBLE("Capture Volume", 0, 0xb4, 0xb4, 4, 0, 15, 0),
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = snd_es18xx_info_mux,
- .get = snd_es18xx_get_mux,
- .put = snd_es18xx_put_mux,
-}
-};
-
-static struct snd_kcontrol_new snd_es18xx_recmix_controls[] = {
-ES18XX_DOUBLE("PCM Capture Volume", 0, 0x69, 0x69, 4, 0, 15, 0),
-ES18XX_DOUBLE("Mic Capture Volume", 0, 0x68, 0x68, 4, 0, 15, 0),
-ES18XX_DOUBLE("Line Capture Volume", 0, 0x6e, 0x6e, 4, 0, 15, 0),
-ES18XX_DOUBLE("FM Capture Volume", 0, 0x6b, 0x6b, 4, 0, 15, 0),
-ES18XX_DOUBLE("CD Capture Volume", 0, 0x6a, 0x6a, 4, 0, 15, 0),
-ES18XX_DOUBLE("Aux Capture Volume", 0, 0x6c, 0x6c, 4, 0, 15, 0)
-};
-
-/*
- * The chipset specific mixer controls
- */
-static struct snd_kcontrol_new snd_es18xx_opt_speaker =
- ES18XX_SINGLE("Beep Playback Volume", 0, 0x3c, 0, 7, 0);
-
-static struct snd_kcontrol_new snd_es18xx_opt_1869[] = {
-ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1),
-ES18XX_SINGLE("Video Playback Switch", 0, 0x7f, 0, 1, 0),
-ES18XX_DOUBLE("Mono Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0),
-ES18XX_DOUBLE("Mono Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0)
-};
-
-static struct snd_kcontrol_new snd_es18xx_opt_1878 =
- ES18XX_DOUBLE("Video Playback Volume", 0, 0x68, 0x68, 4, 0, 15, 0);
-
-static struct snd_kcontrol_new snd_es18xx_opt_1879[] = {
-ES18XX_SINGLE("Video Playback Switch", 0, 0x71, 6, 1, 0),
-ES18XX_DOUBLE("Video Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0),
-ES18XX_DOUBLE("Video Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0)
-};
-
-static struct snd_kcontrol_new snd_es18xx_pcm1_controls[] = {
-ES18XX_DOUBLE("PCM Playback Volume", 0, 0x14, 0x14, 4, 0, 15, 0),
-};
-
-static struct snd_kcontrol_new snd_es18xx_pcm2_controls[] = {
-ES18XX_DOUBLE("PCM Playback Volume", 0, 0x7c, 0x7c, 4, 0, 15, 0),
-ES18XX_DOUBLE("PCM Playback Volume", 1, 0x14, 0x14, 4, 0, 15, 0)
-};
-
-static struct snd_kcontrol_new snd_es18xx_spatializer_controls[] = {
-ES18XX_SINGLE("3D Control - Level", 0, 0x52, 0, 63, 0),
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "3D Control - Switch",
- .info = snd_es18xx_info_spatializer_enable,
- .get = snd_es18xx_get_spatializer_enable,
- .put = snd_es18xx_put_spatializer_enable,
-}
-};
-
-static struct snd_kcontrol_new snd_es18xx_micpre1_control =
-ES18XX_SINGLE("Mic Boost (+26dB)", 0, 0xa9, 2, 1, 0);
-
-static struct snd_kcontrol_new snd_es18xx_micpre2_control =
-ES18XX_SINGLE("Mic Boost (+26dB)", 0, 0x7d, 3, 1, 0);
-
-static struct snd_kcontrol_new snd_es18xx_hw_volume_controls[] = {
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Hardware Master Playback Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .info = snd_es18xx_info_hw_volume,
- .get = snd_es18xx_get_hw_volume,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Hardware Master Playback Switch",
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .info = snd_es18xx_info_hw_switch,
- .get = snd_es18xx_get_hw_switch,
-},
-ES18XX_SINGLE("Hardware Master Volume Split", 0, 0x64, 7, 1, 0),
-};
-
-static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg)
-{
- int data;
-
- outb(reg, chip->ctrl_port);
- data = inb(chip->ctrl_port + 1);
- return data;
-}
-
-static void __devinit snd_es18xx_config_write(struct snd_es18xx *chip,
- unsigned char reg, unsigned char data)
-{
- /* No need for spinlocks, this function is used only in
- otherwise protected init code */
- outb(reg, chip->ctrl_port);
- outb(data, chip->ctrl_port + 1);
-#ifdef REG_DEBUG
- snd_printk(KERN_DEBUG "Config reg %02x set to %02x\n", reg, data);
-#endif
-}
-
-static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip,
- unsigned long mpu_port,
- unsigned long fm_port)
-{
- int mask = 0;
-
- /* enable extended mode */
- snd_es18xx_dsp_command(chip, 0xC6);
- /* Reset mixer registers */
- snd_es18xx_mixer_write(chip, 0x00, 0x00);
-
- /* Audio 1 DMA demand mode (4 bytes/request) */
- snd_es18xx_write(chip, 0xB9, 2);
- if (chip->caps & ES18XX_CONTROL) {
- /* Hardware volume IRQ */
- snd_es18xx_config_write(chip, 0x27, chip->irq);
- if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) {
- /* FM I/O */
- snd_es18xx_config_write(chip, 0x62, fm_port >> 8);
- snd_es18xx_config_write(chip, 0x63, fm_port & 0xff);
- }
- if (mpu_port > 0 && mpu_port != SNDRV_AUTO_PORT) {
- /* MPU-401 I/O */
- snd_es18xx_config_write(chip, 0x64, mpu_port >> 8);
- snd_es18xx_config_write(chip, 0x65, mpu_port & 0xff);
- /* MPU-401 IRQ */
- snd_es18xx_config_write(chip, 0x28, chip->irq);
- }
- /* Audio1 IRQ */
- snd_es18xx_config_write(chip, 0x70, chip->irq);
- /* Audio2 IRQ */
- snd_es18xx_config_write(chip, 0x72, chip->irq);
- /* Audio1 DMA */
- snd_es18xx_config_write(chip, 0x74, chip->dma1);
- /* Audio2 DMA */
- snd_es18xx_config_write(chip, 0x75, chip->dma2);
-
- /* Enable Audio 1 IRQ */
- snd_es18xx_write(chip, 0xB1, 0x50);
- /* Enable Audio 2 IRQ */
- snd_es18xx_mixer_write(chip, 0x7A, 0x40);
- /* Enable Audio 1 DMA */
- snd_es18xx_write(chip, 0xB2, 0x50);
- /* Enable MPU and hardware volume interrupt */
- snd_es18xx_mixer_write(chip, 0x64, 0x42);
- /* Enable ESS wavetable input */
- snd_es18xx_mixer_bits(chip, 0x48, 0x10, 0x10);
- }
- else {
- int irqmask, dma1mask, dma2mask;
- switch (chip->irq) {
- case 2:
- case 9:
- irqmask = 0;
- break;
- case 5:
- irqmask = 1;
- break;
- case 7:
- irqmask = 2;
- break;
- case 10:
- irqmask = 3;
- break;
- default:
- snd_printk(KERN_ERR "invalid irq %d\n", chip->irq);
- return -ENODEV;
- }
- switch (chip->dma1) {
- case 0:
- dma1mask = 1;
- break;
- case 1:
- dma1mask = 2;
- break;
- case 3:
- dma1mask = 3;
- break;
- default:
- snd_printk(KERN_ERR "invalid dma1 %d\n", chip->dma1);
- return -ENODEV;
- }
- switch (chip->dma2) {
- case 0:
- dma2mask = 0;
- break;
- case 1:
- dma2mask = 1;
- break;
- case 3:
- dma2mask = 2;
- break;
- case 5:
- dma2mask = 3;
- break;
- default:
- snd_printk(KERN_ERR "invalid dma2 %d\n", chip->dma2);
- return -ENODEV;
- }
-
- /* Enable and set Audio 1 IRQ */
- snd_es18xx_write(chip, 0xB1, 0x50 | (irqmask << 2));
- /* Enable and set Audio 1 DMA */
- snd_es18xx_write(chip, 0xB2, 0x50 | (dma1mask << 2));
- /* Set Audio 2 DMA */
- snd_es18xx_mixer_bits(chip, 0x7d, 0x07, 0x04 | dma2mask);
- /* Enable Audio 2 IRQ and DMA
- Set capture mixer input */
- snd_es18xx_mixer_write(chip, 0x7A, 0x68);
- /* Enable and set hardware volume interrupt */
- snd_es18xx_mixer_write(chip, 0x64, 0x06);
- if (mpu_port > 0 && mpu_port != SNDRV_AUTO_PORT) {
- /* MPU401 share irq with audio
- Joystick enabled
- FM enabled */
- snd_es18xx_mixer_write(chip, 0x40,
- 0x43 | (mpu_port & 0xf0) >> 1);
- }
- snd_es18xx_mixer_write(chip, 0x7f, ((irqmask + 1) << 1) | 0x01);
- }
- if (chip->caps & ES18XX_NEW_RATE) {
- /* Change behaviour of register A1
- 4x oversampling
- 2nd channel DAC asynchronous */
- snd_es18xx_mixer_write(chip, 0x71, 0x32);
- }
- if (!(chip->caps & ES18XX_PCM2)) {
- /* Enable DMA FIFO */
- snd_es18xx_write(chip, 0xB7, 0x80);
- }
- if (chip->caps & ES18XX_SPATIALIZER) {
- /* Set spatializer parameters to recommended values */
- snd_es18xx_mixer_write(chip, 0x54, 0x8f);
- snd_es18xx_mixer_write(chip, 0x56, 0x95);
- snd_es18xx_mixer_write(chip, 0x58, 0x94);
- snd_es18xx_mixer_write(chip, 0x5a, 0x80);
- }
- /* Flip the "enable I2S" bits for those chipsets that need it */
- switch (chip->version) {
- case 0x1879:
- //Leaving I2S enabled on the 1879 screws up the PCM playback (rate effected somehow)
- //so a Switch control has been added to toggle this 0x71 bit on/off:
- //snd_es18xx_mixer_bits(chip, 0x71, 0x40, 0x40);
- /* Note: we fall through on purpose here. */
- case 0x1878:
- snd_es18xx_config_write(chip, 0x29, snd_es18xx_config_read(chip, 0x29) | 0x40);
- break;
- }
- /* Mute input source */
- if (chip->caps & ES18XX_MUTEREC)
- mask = 0x10;
- if (chip->caps & ES18XX_RECMIX)
- snd_es18xx_mixer_write(chip, 0x1c, 0x05 | mask);
- else {
- snd_es18xx_mixer_write(chip, 0x1c, 0x00 | mask);
- snd_es18xx_write(chip, 0xb4, 0x00);
- }
-#ifndef AVOID_POPS
- /* Enable PCM output */
- snd_es18xx_dsp_command(chip, 0xD1);
-#endif
-
- return 0;
-}
-
-static int __devinit snd_es18xx_identify(struct snd_es18xx *chip)
-{
- int hi,lo;
-
- /* reset */
- if (snd_es18xx_reset(chip) < 0) {
- snd_printk(KERN_ERR "reset at 0x%lx failed!!!\n", chip->port);
- return -ENODEV;
- }
-
- snd_es18xx_dsp_command(chip, 0xe7);
- hi = snd_es18xx_dsp_get_byte(chip);
- if (hi < 0) {
- return hi;
- }
- lo = snd_es18xx_dsp_get_byte(chip);
- if ((lo & 0xf0) != 0x80) {
- return -ENODEV;
- }
- if (hi == 0x48) {
- chip->version = 0x488;
- return 0;
- }
- if (hi != 0x68) {
- return -ENODEV;
- }
- if ((lo & 0x0f) < 8) {
- chip->version = 0x688;
- return 0;
- }
-
- outb(0x40, chip->port + 0x04);
- udelay(10);
- hi = inb(chip->port + 0x05);
- udelay(10);
- lo = inb(chip->port + 0x05);
- if (hi != lo) {
- chip->version = hi << 8 | lo;
- chip->ctrl_port = inb(chip->port + 0x05) << 8;
- udelay(10);
- chip->ctrl_port += inb(chip->port + 0x05);
-
- if ((chip->res_ctrl_port = request_region(chip->ctrl_port, 8, "ES18xx - CTRL")) == NULL) {
- snd_printk(KERN_ERR PFX "unable go grab port 0x%lx\n", chip->ctrl_port);
- return -EBUSY;
- }
-
- return 0;
- }
-
- /* If has Hardware volume */
- if (snd_es18xx_mixer_writable(chip, 0x64, 0x04)) {
- /* If has Audio2 */
- if (snd_es18xx_mixer_writable(chip, 0x70, 0x7f)) {
- /* If has volume count */
- if (snd_es18xx_mixer_writable(chip, 0x64, 0x20)) {
- chip->version = 0x1887;
- } else {
- chip->version = 0x1888;
- }
- } else {
- chip->version = 0x1788;
- }
- }
- else
- chip->version = 0x1688;
- return 0;
-}
-
-static int __devinit snd_es18xx_probe(struct snd_es18xx *chip,
- unsigned long mpu_port,
- unsigned long fm_port)
-{
- if (snd_es18xx_identify(chip) < 0) {
- snd_printk(KERN_ERR PFX "[0x%lx] ESS chip not found\n", chip->port);
- return -ENODEV;
- }
-
- switch (chip->version) {
- case 0x1868:
- chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_CONTROL;
- break;
- case 0x1869:
- chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_MONO | ES18XX_MUTEREC | ES18XX_CONTROL | ES18XX_HWV;
- break;
- case 0x1878:
- chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_I2S | ES18XX_CONTROL;
- break;
- case 0x1879:
- chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_I2S | ES18XX_CONTROL | ES18XX_HWV;
- break;
- case 0x1887:
- case 0x1888:
- chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME;
- break;
- default:
- snd_printk(KERN_ERR "[0x%lx] unsupported chip ES%x\n",
- chip->port, chip->version);
- return -ENODEV;
- }
-
- snd_printd("[0x%lx] ESS%x chip found\n", chip->port, chip->version);
-
- if (chip->dma1 == chip->dma2)
- chip->caps &= ~(ES18XX_PCM2 | ES18XX_DUPLEX_SAME);
-
- return snd_es18xx_initialize(chip, mpu_port, fm_port);
-}
-
-static struct snd_pcm_ops snd_es18xx_playback_ops = {
- .open = snd_es18xx_playback_open,
- .close = snd_es18xx_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_es18xx_playback_hw_params,
- .hw_free = snd_es18xx_pcm_hw_free,
- .prepare = snd_es18xx_playback_prepare,
- .trigger = snd_es18xx_playback_trigger,
- .pointer = snd_es18xx_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_es18xx_capture_ops = {
- .open = snd_es18xx_capture_open,
- .close = snd_es18xx_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_es18xx_capture_hw_params,
- .hw_free = snd_es18xx_pcm_hw_free,
- .prepare = snd_es18xx_capture_prepare,
- .trigger = snd_es18xx_capture_trigger,
- .pointer = snd_es18xx_capture_pointer,
-};
-
-static int __devinit snd_es18xx_pcm(struct snd_card *card, int device,
- struct snd_pcm **rpcm)
-{
- struct snd_es18xx *chip = card->private_data;
- struct snd_pcm *pcm;
- char str[16];
- int err;
-
- if (rpcm)
- *rpcm = NULL;
- sprintf(str, "ES%x", chip->version);
- if (chip->caps & ES18XX_PCM2)
- err = snd_pcm_new(card, str, device, 2, 1, &pcm);
- else
- err = snd_pcm_new(card, str, device, 1, 1, &pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es18xx_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_es18xx_capture_ops);
-
- /* global setup */
- pcm->private_data = chip;
- pcm->info_flags = 0;
- if (chip->caps & ES18XX_DUPLEX_SAME)
- pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX;
- if (! (chip->caps & ES18XX_PCM2))
- pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX;
- sprintf(pcm->name, "ESS AudioDrive ES%x", chip->version);
- chip->pcm = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_isa_data(),
- 64*1024,
- chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024);
-
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-/* Power Management support functions */
-#ifdef CONFIG_PM
-static int snd_es18xx_suspend(struct snd_card *card, pm_message_t state)
-{
- struct snd_es18xx *chip = card->private_data;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-
- snd_pcm_suspend_all(chip->pcm);
-
- /* power down */
- chip->pm_reg = (unsigned char)snd_es18xx_read(chip, ES18XX_PM);
- chip->pm_reg |= (ES18XX_PM_FM | ES18XX_PM_SUS);
- snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg);
- snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_SUS);
-
- return 0;
-}
-
-static int snd_es18xx_resume(struct snd_card *card)
-{
- struct snd_es18xx *chip = card->private_data;
-
- /* restore PM register, we won't wake till (not 0x07) i/o activity though */
- snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_FM);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif /* CONFIG_PM */
-
-static int snd_es18xx_free(struct snd_card *card)
-{
- struct snd_es18xx *chip = card->private_data;
-
- release_and_free_resource(chip->res_port);
- release_and_free_resource(chip->res_ctrl_port);
- release_and_free_resource(chip->res_mpu_port);
- if (chip->irq >= 0)
- free_irq(chip->irq, (void *) card);
- if (chip->dma1 >= 0) {
- disable_dma(chip->dma1);
- free_dma(chip->dma1);
- }
- if (chip->dma2 >= 0 && chip->dma1 != chip->dma2) {
- disable_dma(chip->dma2);
- free_dma(chip->dma2);
- }
- return 0;
-}
-
-static int snd_es18xx_dev_free(struct snd_device *device)
-{
- return snd_es18xx_free(device->card);
-}
-
-static int __devinit snd_es18xx_new_device(struct snd_card *card,
- unsigned long port,
- unsigned long mpu_port,
- unsigned long fm_port,
- int irq, int dma1, int dma2)
-{
- struct snd_es18xx *chip = card->private_data;
- static struct snd_device_ops ops = {
- .dev_free = snd_es18xx_dev_free,
- };
- int err;
-
- spin_lock_init(&chip->reg_lock);
- spin_lock_init(&chip->mixer_lock);
- chip->port = port;
- chip->irq = -1;
- chip->dma1 = -1;
- chip->dma2 = -1;
- chip->audio2_vol = 0x00;
- chip->active = 0;
-
- chip->res_port = request_region(port, 16, "ES18xx");
- if (chip->res_port == NULL) {
- snd_es18xx_free(card);
- snd_printk(KERN_ERR PFX "unable to grap ports 0x%lx-0x%lx\n", port, port + 16 - 1);
- return -EBUSY;
- }
-
- if (request_irq(irq, snd_es18xx_interrupt, 0, "ES18xx",
- (void *) card)) {
- snd_es18xx_free(card);
- snd_printk(KERN_ERR PFX "unable to grap IRQ %d\n", irq);
- return -EBUSY;
- }
- chip->irq = irq;
-
- if (request_dma(dma1, "ES18xx DMA 1")) {
- snd_es18xx_free(card);
- snd_printk(KERN_ERR PFX "unable to grap DMA1 %d\n", dma1);
- return -EBUSY;
- }
- chip->dma1 = dma1;
-
- if (dma2 != dma1 && request_dma(dma2, "ES18xx DMA 2")) {
- snd_es18xx_free(card);
- snd_printk(KERN_ERR PFX "unable to grap DMA2 %d\n", dma2);
- return -EBUSY;
- }
- chip->dma2 = dma2;
-
- if (snd_es18xx_probe(chip, mpu_port, fm_port) < 0) {
- snd_es18xx_free(card);
- return -ENODEV;
- }
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
- if (err < 0) {
- snd_es18xx_free(card);
- return err;
- }
- return 0;
-}
-
-static int __devinit snd_es18xx_mixer(struct snd_card *card)
-{
- struct snd_es18xx *chip = card->private_data;
- int err;
- unsigned int idx;
-
- strcpy(card->mixername, chip->pcm->name);
-
- for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_base_controls); idx++) {
- struct snd_kcontrol *kctl;
- kctl = snd_ctl_new1(&snd_es18xx_base_controls[idx], chip);
- if (chip->caps & ES18XX_HWV) {
- switch (idx) {
- case 0:
- chip->master_volume = kctl;
- kctl->private_free = snd_es18xx_hwv_free;
- break;
- case 1:
- chip->master_switch = kctl;
- kctl->private_free = snd_es18xx_hwv_free;
- break;
- }
- }
- if ((err = snd_ctl_add(card, kctl)) < 0)
- return err;
- }
- if (chip->caps & ES18XX_PCM2) {
- for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_pcm2_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_pcm2_controls[idx], chip))) < 0)
- return err;
- }
- } else {
- for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_pcm1_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_pcm1_controls[idx], chip))) < 0)
- return err;
- }
- }
-
- if (chip->caps & ES18XX_RECMIX) {
- for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_recmix_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_recmix_controls[idx], chip))) < 0)
- return err;
- }
- }
- switch (chip->version) {
- default:
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_micpre1_control, chip))) < 0)
- return err;
- break;
- case 0x1869:
- case 0x1879:
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_micpre2_control, chip))) < 0)
- return err;
- break;
- }
- if (chip->caps & ES18XX_SPATIALIZER) {
- for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_spatializer_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_spatializer_controls[idx], chip))) < 0)
- return err;
- }
- }
- if (chip->caps & ES18XX_HWV) {
- for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_hw_volume_controls); idx++) {
- struct snd_kcontrol *kctl;
- kctl = snd_ctl_new1(&snd_es18xx_hw_volume_controls[idx], chip);
- if (idx == 0)
- chip->hw_volume = kctl;
- else
- chip->hw_switch = kctl;
- kctl->private_free = snd_es18xx_hwv_free;
- if ((err = snd_ctl_add(card, kctl)) < 0)
- return err;
-
- }
- }
- /* finish initializing other chipset specific controls
- */
- if (chip->version != 0x1868) {
- err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_opt_speaker,
- chip));
- if (err < 0)
- return err;
- }
- if (chip->version == 0x1869) {
- for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_opt_1869); idx++) {
- err = snd_ctl_add(card,
- snd_ctl_new1(&snd_es18xx_opt_1869[idx],
- chip));
- if (err < 0)
- return err;
- }
- } else if (chip->version == 0x1878) {
- err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_opt_1878,
- chip));
- if (err < 0)
- return err;
- } else if (chip->version == 0x1879) {
- for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_opt_1879); idx++) {
- err = snd_ctl_add(card,
- snd_ctl_new1(&snd_es18xx_opt_1879[idx],
- chip));
- if (err < 0)
- return err;
- }
- }
- return 0;
-}
-
-
-/* Card level */
-
-MODULE_AUTHOR("Christian Fischbach <fishbach@pool.informatik.rwth-aachen.de>, Abramo Bagnara <abramo@alsa-project.org>");
-MODULE_DESCRIPTION("ESS ES18xx AudioDrive");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ESS,ES1868 PnP AudioDrive},"
- "{ESS,ES1869 PnP AudioDrive},"
- "{ESS,ES1878 PnP AudioDrive},"
- "{ESS,ES1879 PnP AudioDrive},"
- "{ESS,ES1887 PnP AudioDrive},"
- "{ESS,ES1888 PnP AudioDrive},"
- "{ESS,ES1887 AudioDrive},"
- "{ESS,ES1888 AudioDrive}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
-#ifdef CONFIG_PNP
-static bool isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
-#endif
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260,0x280 */
-#ifndef CONFIG_PNP
-static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
-#else
-static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-#endif
-static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */
-static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3 */
-static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3 */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for ES18xx soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for ES18xx soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable ES18xx soundcard.");
-#ifdef CONFIG_PNP
-module_param_array(isapnp, bool, NULL, 0444);
-MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
-#endif
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for ES18xx driver.");
-module_param_array(mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port # for ES18xx driver.");
-module_param_array(fm_port, long, NULL, 0444);
-MODULE_PARM_DESC(fm_port, "FM port # for ES18xx driver.");
-module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for ES18xx driver.");
-module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "DMA 1 # for ES18xx driver.");
-module_param_array(dma2, int, NULL, 0444);
-MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver.");
-
-#ifdef CONFIG_PNP
-static int isa_registered;
-static int pnp_registered;
-static int pnpc_registered;
-
-static struct pnp_device_id snd_audiodrive_pnpbiosids[] = {
- { .id = "ESS1869" },
- { .id = "ESS1879" },
- { .id = "" } /* end */
-};
-
-MODULE_DEVICE_TABLE(pnp, snd_audiodrive_pnpbiosids);
-
-/* PnP main device initialization */
-static int __devinit snd_audiodrive_pnp_init_main(int dev, struct pnp_dev *pdev)
-{
- if (pnp_activate_dev(pdev) < 0) {
- snd_printk(KERN_ERR PFX "PnP configure failure (out of resources?)\n");
- return -EBUSY;
- }
- /* ok. hack using Vendor-Defined Card-Level registers */
- /* skip csn and logdev initialization - already done in isapnp_configure */
- if (pnp_device_is_isapnp(pdev)) {
- isapnp_cfg_begin(isapnp_card_number(pdev), isapnp_csn_number(pdev));
- isapnp_write_byte(0x27, pnp_irq(pdev, 0)); /* Hardware Volume IRQ Number */
- if (mpu_port[dev] != SNDRV_AUTO_PORT)
- isapnp_write_byte(0x28, pnp_irq(pdev, 0)); /* MPU-401 IRQ Number */
- isapnp_write_byte(0x72, pnp_irq(pdev, 0)); /* second IRQ */
- isapnp_cfg_end();
- }
- port[dev] = pnp_port_start(pdev, 0);
- fm_port[dev] = pnp_port_start(pdev, 1);
- mpu_port[dev] = pnp_port_start(pdev, 2);
- dma1[dev] = pnp_dma(pdev, 0);
- dma2[dev] = pnp_dma(pdev, 1);
- irq[dev] = pnp_irq(pdev, 0);
- snd_printdd("PnP ES18xx: port=0x%lx, fm port=0x%lx, mpu port=0x%lx\n", port[dev], fm_port[dev], mpu_port[dev]);
- snd_printdd("PnP ES18xx: dma1=%i, dma2=%i, irq=%i\n", dma1[dev], dma2[dev], irq[dev]);
- return 0;
-}
-
-static int __devinit snd_audiodrive_pnp(int dev, struct snd_es18xx *chip,
- struct pnp_dev *pdev)
-{
- chip->dev = pdev;
- if (snd_audiodrive_pnp_init_main(dev, chip->dev) < 0)
- return -EBUSY;
- return 0;
-}
-
-static struct pnp_card_device_id snd_audiodrive_pnpids[] = {
- /* ESS 1868 (integrated on Compaq dual P-Pro motherboard and Genius 18PnP 3D) */
- { .id = "ESS1868", .devs = { { "ESS1868" }, { "ESS0000" } } },
- /* ESS 1868 (integrated on Maxisound Cards) */
- { .id = "ESS1868", .devs = { { "ESS8601" }, { "ESS8600" } } },
- /* ESS 1868 (integrated on Maxisound Cards) */
- { .id = "ESS1868", .devs = { { "ESS8611" }, { "ESS8610" } } },
- /* ESS ES1869 Plug and Play AudioDrive */
- { .id = "ESS0003", .devs = { { "ESS1869" }, { "ESS0006" } } },
- /* ESS 1869 */
- { .id = "ESS1869", .devs = { { "ESS1869" }, { "ESS0006" } } },
- /* ESS 1878 */
- { .id = "ESS1878", .devs = { { "ESS1878" }, { "ESS0004" } } },
- /* ESS 1879 */
- { .id = "ESS1879", .devs = { { "ESS1879" }, { "ESS0009" } } },
- /* --- */
- { .id = "" } /* end */
-};
-
-MODULE_DEVICE_TABLE(pnp_card, snd_audiodrive_pnpids);
-
-static int __devinit snd_audiodrive_pnpc(int dev, struct snd_es18xx *chip,
- struct pnp_card_link *card,
- const struct pnp_card_device_id *id)
-{
- chip->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
- if (chip->dev == NULL)
- return -EBUSY;
-
- chip->devc = pnp_request_card_device(card, id->devs[1].id, NULL);
- if (chip->devc == NULL)
- return -EBUSY;
-
- /* Control port initialization */
- if (pnp_activate_dev(chip->devc) < 0) {
- snd_printk(KERN_ERR PFX "PnP control configure failure (out of resources?)\n");
- return -EAGAIN;
- }
- snd_printdd("pnp: port=0x%llx\n",
- (unsigned long long)pnp_port_start(chip->devc, 0));
- if (snd_audiodrive_pnp_init_main(dev, chip->dev) < 0)
- return -EBUSY;
-
- return 0;
-}
-#endif /* CONFIG_PNP */
-
-#ifdef CONFIG_PNP
-#define is_isapnp_selected(dev) isapnp[dev]
-#else
-#define is_isapnp_selected(dev) 0
-#endif
-
-static int snd_es18xx_card_new(int dev, struct snd_card **cardp)
-{
- return snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_es18xx), cardp);
-}
-
-static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev)
-{
- struct snd_es18xx *chip = card->private_data;
- struct snd_opl3 *opl3;
- int err;
-
- err = snd_es18xx_new_device(card,
- port[dev], mpu_port[dev], fm_port[dev],
- irq[dev], dma1[dev], dma2[dev]);
- if (err < 0)
- return err;
-
- sprintf(card->driver, "ES%x", chip->version);
-
- sprintf(card->shortname, "ESS AudioDrive ES%x", chip->version);
- if (dma1[dev] != dma2[dev])
- sprintf(card->longname, "%s at 0x%lx, irq %d, dma1 %d, dma2 %d",
- card->shortname,
- chip->port,
- irq[dev], dma1[dev], dma2[dev]);
- else
- sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
- card->shortname,
- chip->port,
- irq[dev], dma1[dev]);
-
- err = snd_es18xx_pcm(card, 0, NULL);
- if (err < 0)
- return err;
-
- err = snd_es18xx_mixer(card);
- if (err < 0)
- return err;
-
- if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
- if (snd_opl3_create(card, fm_port[dev], fm_port[dev] + 2,
- OPL3_HW_OPL3, 0, &opl3) < 0) {
- snd_printk(KERN_WARNING PFX
- "opl3 not detected at 0x%lx\n",
- fm_port[dev]);
- } else {
- err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
- if (err < 0)
- return err;
- }
- }
-
- if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
- err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX,
- mpu_port[dev], MPU401_INFO_IRQ_HOOK,
- -1, &chip->rmidi);
- if (err < 0)
- return err;
- }
-
- return snd_card_register(card);
-}
-
-static int __devinit snd_es18xx_isa_match(struct device *pdev, unsigned int dev)
-{
- return enable[dev] && !is_isapnp_selected(dev);
-}
-
-static int __devinit snd_es18xx_isa_probe1(int dev, struct device *devptr)
-{
- struct snd_card *card;
- int err;
-
- err = snd_es18xx_card_new(dev, &card);
- if (err < 0)
- return err;
- snd_card_set_dev(card, devptr);
- if ((err = snd_audiodrive_probe(card, dev)) < 0) {
- snd_card_free(card);
- return err;
- }
- dev_set_drvdata(devptr, card);
- return 0;
-}
-
-static int __devinit snd_es18xx_isa_probe(struct device *pdev, unsigned int dev)
-{
- int err;
- static int possible_irqs[] = {5, 9, 10, 7, 11, 12, -1};
- static int possible_dmas[] = {1, 0, 3, 5, -1};
-
- if (irq[dev] == SNDRV_AUTO_IRQ) {
- if ((irq[dev] = snd_legacy_find_free_irq(possible_irqs)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
- return -EBUSY;
- }
- }
- if (dma1[dev] == SNDRV_AUTO_DMA) {
- if ((dma1[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
- return -EBUSY;
- }
- }
- if (dma2[dev] == SNDRV_AUTO_DMA) {
- if ((dma2[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
- return -EBUSY;
- }
- }
-
- if (port[dev] != SNDRV_AUTO_PORT) {
- return snd_es18xx_isa_probe1(dev, pdev);
- } else {
- static unsigned long possible_ports[] = {0x220, 0x240, 0x260, 0x280};
- int i;
- for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
- port[dev] = possible_ports[i];
- err = snd_es18xx_isa_probe1(dev, pdev);
- if (! err)
- return 0;
- }
- return err;
- }
-}
-
-static int __devexit snd_es18xx_isa_remove(struct device *devptr,
- unsigned int dev)
-{
- snd_card_free(dev_get_drvdata(devptr));
- dev_set_drvdata(devptr, NULL);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int snd_es18xx_isa_suspend(struct device *dev, unsigned int n,
- pm_message_t state)
-{
- return snd_es18xx_suspend(dev_get_drvdata(dev), state);
-}
-
-static int snd_es18xx_isa_resume(struct device *dev, unsigned int n)
-{
- return snd_es18xx_resume(dev_get_drvdata(dev));
-}
-#endif
-
-#define DEV_NAME "es18xx"
-
-static struct isa_driver snd_es18xx_isa_driver = {
- .match = snd_es18xx_isa_match,
- .probe = snd_es18xx_isa_probe,
- .remove = __devexit_p(snd_es18xx_isa_remove),
-#ifdef CONFIG_PM
- .suspend = snd_es18xx_isa_suspend,
- .resume = snd_es18xx_isa_resume,
-#endif
- .driver = {
- .name = DEV_NAME
- },
-};
-
-
-#ifdef CONFIG_PNP
-static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev,
- const struct pnp_device_id *id)
-{
- static int dev;
- int err;
- struct snd_card *card;
-
- if (pnp_device_is_isapnp(pdev))
- return -ENOENT; /* we have another procedure - card */
- for (; dev < SNDRV_CARDS; dev++) {
- if (enable[dev] && isapnp[dev])
- break;
- }
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
-
- err = snd_es18xx_card_new(dev, &card);
- if (err < 0)
- return err;
- if ((err = snd_audiodrive_pnp(dev, card->private_data, pdev)) < 0) {
- snd_card_free(card);
- return err;
- }
- snd_card_set_dev(card, &pdev->dev);
- if ((err = snd_audiodrive_probe(card, dev)) < 0) {
- snd_card_free(card);
- return err;
- }
- pnp_set_drvdata(pdev, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_audiodrive_pnp_remove(struct pnp_dev * pdev)
-{
- snd_card_free(pnp_get_drvdata(pdev));
- pnp_set_drvdata(pdev, NULL);
-}
-
-#ifdef CONFIG_PM
-static int snd_audiodrive_pnp_suspend(struct pnp_dev *pdev, pm_message_t state)
-{
- return snd_es18xx_suspend(pnp_get_drvdata(pdev), state);
-}
-static int snd_audiodrive_pnp_resume(struct pnp_dev *pdev)
-{
- return snd_es18xx_resume(pnp_get_drvdata(pdev));
-}
-#endif
-
-static struct pnp_driver es18xx_pnp_driver = {
- .name = "es18xx-pnpbios",
- .id_table = snd_audiodrive_pnpbiosids,
- .probe = snd_audiodrive_pnp_detect,
- .remove = __devexit_p(snd_audiodrive_pnp_remove),
-#ifdef CONFIG_PM
- .suspend = snd_audiodrive_pnp_suspend,
- .resume = snd_audiodrive_pnp_resume,
-#endif
-};
-
-static int __devinit snd_audiodrive_pnpc_detect(struct pnp_card_link *pcard,
- const struct pnp_card_device_id *pid)
-{
- static int dev;
- struct snd_card *card;
- int res;
-
- for ( ; dev < SNDRV_CARDS; dev++) {
- if (enable[dev] && isapnp[dev])
- break;
- }
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
-
- res = snd_es18xx_card_new(dev, &card);
- if (res < 0)
- return res;
-
- if ((res = snd_audiodrive_pnpc(dev, card->private_data, pcard, pid)) < 0) {
- snd_card_free(card);
- return res;
- }
- snd_card_set_dev(card, &pcard->card->dev);
- if ((res = snd_audiodrive_probe(card, dev)) < 0) {
- snd_card_free(card);
- return res;
- }
-
- pnp_set_card_drvdata(pcard, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_audiodrive_pnpc_remove(struct pnp_card_link * pcard)
-{
- snd_card_free(pnp_get_card_drvdata(pcard));
- pnp_set_card_drvdata(pcard, NULL);
-}
-
-#ifdef CONFIG_PM
-static int snd_audiodrive_pnpc_suspend(struct pnp_card_link *pcard, pm_message_t state)
-{
- return snd_es18xx_suspend(pnp_get_card_drvdata(pcard), state);
-}
-
-static int snd_audiodrive_pnpc_resume(struct pnp_card_link *pcard)
-{
- return snd_es18xx_resume(pnp_get_card_drvdata(pcard));
-}
-
-#endif
-
-static struct pnp_card_driver es18xx_pnpc_driver = {
- .flags = PNP_DRIVER_RES_DISABLE,
- .name = "es18xx",
- .id_table = snd_audiodrive_pnpids,
- .probe = snd_audiodrive_pnpc_detect,
- .remove = __devexit_p(snd_audiodrive_pnpc_remove),
-#ifdef CONFIG_PM
- .suspend = snd_audiodrive_pnpc_suspend,
- .resume = snd_audiodrive_pnpc_resume,
-#endif
-};
-#endif /* CONFIG_PNP */
-
-static int __init alsa_card_es18xx_init(void)
-{
- int err;
-
- err = isa_register_driver(&snd_es18xx_isa_driver, SNDRV_CARDS);
-#ifdef CONFIG_PNP
- if (!err)
- isa_registered = 1;
-
- err = pnp_register_driver(&es18xx_pnp_driver);
- if (!err)
- pnp_registered = 1;
-
- err = pnp_register_card_driver(&es18xx_pnpc_driver);
- if (!err)
- pnpc_registered = 1;
-
- if (isa_registered || pnp_registered)
- err = 0;
-#endif
- return err;
-}
-
-static void __exit alsa_card_es18xx_exit(void)
-{
-#ifdef CONFIG_PNP
- if (pnpc_registered)
- pnp_unregister_card_driver(&es18xx_pnpc_driver);
- if (pnp_registered)
- pnp_unregister_driver(&es18xx_pnp_driver);
- if (isa_registered)
-#endif
- isa_unregister_driver(&snd_es18xx_isa_driver);
-}
-
-module_init(alsa_card_es18xx_init)
-module_exit(alsa_card_es18xx_exit)
diff --git a/ANDROID_3.4.5/sound/isa/galaxy/Makefile b/ANDROID_3.4.5/sound/isa/galaxy/Makefile
deleted file mode 100644
index e307066d..00000000
--- a/ANDROID_3.4.5/sound/isa/galaxy/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
-#
-
-snd-azt1605-objs := azt1605.o
-snd-azt2316-objs := azt2316.o
-
-obj-$(CONFIG_SND_AZT1605) += snd-azt1605.o
-obj-$(CONFIG_SND_AZT2316) += snd-azt2316.o
diff --git a/ANDROID_3.4.5/sound/isa/galaxy/azt1605.c b/ANDROID_3.4.5/sound/isa/galaxy/azt1605.c
deleted file mode 100644
index 9a97643c..00000000
--- a/ANDROID_3.4.5/sound/isa/galaxy/azt1605.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Aztech AZT1605 Driver
- * Copyright (C) 2007,2010 Rene Herman
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#define AZT1605
-
-#define CRD_NAME "Aztech AZT1605"
-#define DRV_NAME "AZT1605"
-#define DEV_NAME "azt1605"
-
-#define GALAXY_DSP_MAJOR 2
-#define GALAXY_DSP_MINOR 1
-
-#define GALAXY_CONFIG_SIZE 3
-
-/*
- * 24-bit config register
- */
-
-#define GALAXY_CONFIG_SBA_220 (0 << 0)
-#define GALAXY_CONFIG_SBA_240 (1 << 0)
-#define GALAXY_CONFIG_SBA_260 (2 << 0)
-#define GALAXY_CONFIG_SBA_280 (3 << 0)
-#define GALAXY_CONFIG_SBA_MASK GALAXY_CONFIG_SBA_280
-
-#define GALAXY_CONFIG_MPUA_300 (0 << 2)
-#define GALAXY_CONFIG_MPUA_330 (1 << 2)
-
-#define GALAXY_CONFIG_MPU_ENABLE (1 << 3)
-
-#define GALAXY_CONFIG_GAME_ENABLE (1 << 4)
-
-#define GALAXY_CONFIG_CD_PANASONIC (1 << 5)
-#define GALAXY_CONFIG_CD_MITSUMI (1 << 6)
-#define GALAXY_CONFIG_CD_MASK (\
- GALAXY_CONFIG_CD_PANASONIC | GALAXY_CONFIG_CD_MITSUMI)
-
-#define GALAXY_CONFIG_UNUSED (1 << 7)
-#define GALAXY_CONFIG_UNUSED_MASK GALAXY_CONFIG_UNUSED
-
-#define GALAXY_CONFIG_SBIRQ_2 (1 << 8)
-#define GALAXY_CONFIG_SBIRQ_3 (1 << 9)
-#define GALAXY_CONFIG_SBIRQ_5 (1 << 10)
-#define GALAXY_CONFIG_SBIRQ_7 (1 << 11)
-
-#define GALAXY_CONFIG_MPUIRQ_2 (1 << 12)
-#define GALAXY_CONFIG_MPUIRQ_3 (1 << 13)
-#define GALAXY_CONFIG_MPUIRQ_5 (1 << 14)
-#define GALAXY_CONFIG_MPUIRQ_7 (1 << 15)
-
-#define GALAXY_CONFIG_WSSA_530 (0 << 16)
-#define GALAXY_CONFIG_WSSA_604 (1 << 16)
-#define GALAXY_CONFIG_WSSA_E80 (2 << 16)
-#define GALAXY_CONFIG_WSSA_F40 (3 << 16)
-
-#define GALAXY_CONFIG_WSS_ENABLE (1 << 18)
-
-#define GALAXY_CONFIG_CDIRQ_11 (1 << 19)
-#define GALAXY_CONFIG_CDIRQ_12 (1 << 20)
-#define GALAXY_CONFIG_CDIRQ_15 (1 << 21)
-#define GALAXY_CONFIG_CDIRQ_MASK (\
- GALAXY_CONFIG_CDIRQ_11 | GALAXY_CONFIG_CDIRQ_12 |\
- GALAXY_CONFIG_CDIRQ_15)
-
-#define GALAXY_CONFIG_CDDMA_DISABLE (0 << 22)
-#define GALAXY_CONFIG_CDDMA_0 (1 << 22)
-#define GALAXY_CONFIG_CDDMA_1 (2 << 22)
-#define GALAXY_CONFIG_CDDMA_3 (3 << 22)
-#define GALAXY_CONFIG_CDDMA_MASK GALAXY_CONFIG_CDDMA_3
-
-#define GALAXY_CONFIG_MASK (\
- GALAXY_CONFIG_SBA_MASK | GALAXY_CONFIG_CD_MASK |\
- GALAXY_CONFIG_UNUSED_MASK | GALAXY_CONFIG_CDIRQ_MASK |\
- GALAXY_CONFIG_CDDMA_MASK)
-
-#include "galaxy.c"
diff --git a/ANDROID_3.4.5/sound/isa/galaxy/azt2316.c b/ANDROID_3.4.5/sound/isa/galaxy/azt2316.c
deleted file mode 100644
index 18944114..00000000
--- a/ANDROID_3.4.5/sound/isa/galaxy/azt2316.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Aztech AZT2316 Driver
- * Copyright (C) 2007,2010 Rene Herman
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#define AZT2316
-
-#define CRD_NAME "Aztech AZT2316"
-#define DRV_NAME "AZT2316"
-#define DEV_NAME "azt2316"
-
-#define GALAXY_DSP_MAJOR 3
-#define GALAXY_DSP_MINOR 1
-
-#define GALAXY_CONFIG_SIZE 4
-
-/*
- * 32-bit config register
- */
-
-#define GALAXY_CONFIG_SBA_220 (0 << 0)
-#define GALAXY_CONFIG_SBA_240 (1 << 0)
-#define GALAXY_CONFIG_SBA_260 (2 << 0)
-#define GALAXY_CONFIG_SBA_280 (3 << 0)
-#define GALAXY_CONFIG_SBA_MASK GALAXY_CONFIG_SBA_280
-
-#define GALAXY_CONFIG_SBIRQ_2 (1 << 2)
-#define GALAXY_CONFIG_SBIRQ_5 (1 << 3)
-#define GALAXY_CONFIG_SBIRQ_7 (1 << 4)
-#define GALAXY_CONFIG_SBIRQ_10 (1 << 5)
-
-#define GALAXY_CONFIG_SBDMA_DISABLE (0 << 6)
-#define GALAXY_CONFIG_SBDMA_0 (1 << 6)
-#define GALAXY_CONFIG_SBDMA_1 (2 << 6)
-#define GALAXY_CONFIG_SBDMA_3 (3 << 6)
-
-#define GALAXY_CONFIG_WSSA_530 (0 << 8)
-#define GALAXY_CONFIG_WSSA_604 (1 << 8)
-#define GALAXY_CONFIG_WSSA_E80 (2 << 8)
-#define GALAXY_CONFIG_WSSA_F40 (3 << 8)
-
-#define GALAXY_CONFIG_WSS_ENABLE (1 << 10)
-
-#define GALAXY_CONFIG_GAME_ENABLE (1 << 11)
-
-#define GALAXY_CONFIG_MPUA_300 (0 << 12)
-#define GALAXY_CONFIG_MPUA_330 (1 << 12)
-
-#define GALAXY_CONFIG_MPU_ENABLE (1 << 13)
-
-#define GALAXY_CONFIG_CDA_310 (0 << 14)
-#define GALAXY_CONFIG_CDA_320 (1 << 14)
-#define GALAXY_CONFIG_CDA_340 (2 << 14)
-#define GALAXY_CONFIG_CDA_350 (3 << 14)
-#define GALAXY_CONFIG_CDA_MASK GALAXY_CONFIG_CDA_350
-
-#define GALAXY_CONFIG_CD_DISABLE (0 << 16)
-#define GALAXY_CONFIG_CD_PANASONIC (1 << 16)
-#define GALAXY_CONFIG_CD_SONY (2 << 16)
-#define GALAXY_CONFIG_CD_MITSUMI (3 << 16)
-#define GALAXY_CONFIG_CD_AZTECH (4 << 16)
-#define GALAXY_CONFIG_CD_UNUSED_5 (5 << 16)
-#define GALAXY_CONFIG_CD_UNUSED_6 (6 << 16)
-#define GALAXY_CONFIG_CD_UNUSED_7 (7 << 16)
-#define GALAXY_CONFIG_CD_MASK GALAXY_CONFIG_CD_UNUSED_7
-
-#define GALAXY_CONFIG_CDDMA8_DISABLE (0 << 20)
-#define GALAXY_CONFIG_CDDMA8_0 (1 << 20)
-#define GALAXY_CONFIG_CDDMA8_1 (2 << 20)
-#define GALAXY_CONFIG_CDDMA8_3 (3 << 20)
-#define GALAXY_CONFIG_CDDMA8_MASK GALAXY_CONFIG_CDDMA8_3
-
-#define GALAXY_CONFIG_CDDMA16_DISABLE (0 << 22)
-#define GALAXY_CONFIG_CDDMA16_5 (1 << 22)
-#define GALAXY_CONFIG_CDDMA16_6 (2 << 22)
-#define GALAXY_CONFIG_CDDMA16_7 (3 << 22)
-#define GALAXY_CONFIG_CDDMA16_MASK GALAXY_CONFIG_CDDMA16_7
-
-#define GALAXY_CONFIG_MPUIRQ_2 (1 << 24)
-#define GALAXY_CONFIG_MPUIRQ_5 (1 << 25)
-#define GALAXY_CONFIG_MPUIRQ_7 (1 << 26)
-#define GALAXY_CONFIG_MPUIRQ_10 (1 << 27)
-
-#define GALAXY_CONFIG_CDIRQ_5 (1 << 28)
-#define GALAXY_CONFIG_CDIRQ_11 (1 << 29)
-#define GALAXY_CONFIG_CDIRQ_12 (1 << 30)
-#define GALAXY_CONFIG_CDIRQ_15 (1 << 31)
-#define GALAXY_CONFIG_CDIRQ_MASK (\
- GALAXY_CONFIG_CDIRQ_5 | GALAXY_CONFIG_CDIRQ_11 |\
- GALAXY_CONFIG_CDIRQ_12 | GALAXY_CONFIG_CDIRQ_15)
-
-#define GALAXY_CONFIG_MASK (\
- GALAXY_CONFIG_SBA_MASK | GALAXY_CONFIG_CDA_MASK |\
- GALAXY_CONFIG_CD_MASK | GALAXY_CONFIG_CDDMA16_MASK |\
- GALAXY_CONFIG_CDDMA8_MASK | GALAXY_CONFIG_CDIRQ_MASK)
-
-#include "galaxy.c"
diff --git a/ANDROID_3.4.5/sound/isa/galaxy/galaxy.c b/ANDROID_3.4.5/sound/isa/galaxy/galaxy.c
deleted file mode 100644
index 55e20782..00000000
--- a/ANDROID_3.4.5/sound/isa/galaxy/galaxy.c
+++ /dev/null
@@ -1,651 +0,0 @@
-/*
- * Aztech AZT1605/AZT2316 Driver
- * Copyright (C) 2007,2010 Rene Herman
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/isa.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <asm/processor.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/wss.h>
-#include <sound/mpu401.h>
-#include <sound/opl3.h>
-
-MODULE_DESCRIPTION(CRD_NAME);
-MODULE_AUTHOR("Rene Herman");
-MODULE_LICENSE("GPL");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
-
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-static long wss_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
-static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
-static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
-static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
-
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
-module_param_array(wss_port, long, NULL, 0444);
-MODULE_PARM_DESC(wss_port, "WSS port # for " CRD_NAME " driver.");
-module_param_array(mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
-module_param_array(fm_port, long, NULL, 0444);
-MODULE_PARM_DESC(fm_port, "FM port # for " CRD_NAME " driver.");
-module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
-module_param_array(mpu_irq, int, NULL, 0444);
-MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
-module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "Playback DMA # for " CRD_NAME " driver.");
-module_param_array(dma2, int, NULL, 0444);
-MODULE_PARM_DESC(dma2, "Capture DMA # for " CRD_NAME " driver.");
-
-/*
- * Generic SB DSP support routines
- */
-
-#define DSP_PORT_RESET 0x6
-#define DSP_PORT_READ 0xa
-#define DSP_PORT_COMMAND 0xc
-#define DSP_PORT_STATUS 0xc
-#define DSP_PORT_DATA_AVAIL 0xe
-
-#define DSP_SIGNATURE 0xaa
-
-#define DSP_COMMAND_GET_VERSION 0xe1
-
-static int __devinit dsp_get_byte(void __iomem *port, u8 *val)
-{
- int loops = 1000;
-
- while (!(ioread8(port + DSP_PORT_DATA_AVAIL) & 0x80)) {
- if (!loops--)
- return -EIO;
- cpu_relax();
- }
- *val = ioread8(port + DSP_PORT_READ);
- return 0;
-}
-
-static int __devinit dsp_reset(void __iomem *port)
-{
- u8 val;
-
- iowrite8(1, port + DSP_PORT_RESET);
- udelay(10);
- iowrite8(0, port + DSP_PORT_RESET);
-
- if (dsp_get_byte(port, &val) < 0 || val != DSP_SIGNATURE)
- return -ENODEV;
-
- return 0;
-}
-
-static int __devinit dsp_command(void __iomem *port, u8 cmd)
-{
- int loops = 1000;
-
- while (ioread8(port + DSP_PORT_STATUS) & 0x80) {
- if (!loops--)
- return -EIO;
- cpu_relax();
- }
- iowrite8(cmd, port + DSP_PORT_COMMAND);
- return 0;
-}
-
-static int __devinit dsp_get_version(void __iomem *port, u8 *major, u8 *minor)
-{
- int err;
-
- err = dsp_command(port, DSP_COMMAND_GET_VERSION);
- if (err < 0)
- return err;
-
- err = dsp_get_byte(port, major);
- if (err < 0)
- return err;
-
- err = dsp_get_byte(port, minor);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-/*
- * Generic WSS support routines
- */
-
-#define WSS_CONFIG_DMA_0 (1 << 0)
-#define WSS_CONFIG_DMA_1 (2 << 0)
-#define WSS_CONFIG_DMA_3 (3 << 0)
-#define WSS_CONFIG_DUPLEX (1 << 2)
-#define WSS_CONFIG_IRQ_7 (1 << 3)
-#define WSS_CONFIG_IRQ_9 (2 << 3)
-#define WSS_CONFIG_IRQ_10 (3 << 3)
-#define WSS_CONFIG_IRQ_11 (4 << 3)
-
-#define WSS_PORT_CONFIG 0
-#define WSS_PORT_SIGNATURE 3
-
-#define WSS_SIGNATURE 4
-
-static int __devinit wss_detect(void __iomem *wss_port)
-{
- if ((ioread8(wss_port + WSS_PORT_SIGNATURE) & 0x3f) != WSS_SIGNATURE)
- return -ENODEV;
-
- return 0;
-}
-
-static void wss_set_config(void __iomem *wss_port, u8 wss_config)
-{
- iowrite8(wss_config, wss_port + WSS_PORT_CONFIG);
-}
-
-/*
- * Aztech Sound Galaxy specifics
- */
-
-#define GALAXY_PORT_CONFIG 1024
-#define CONFIG_PORT_SET 4
-
-#define DSP_COMMAND_GALAXY_8 8
-#define GALAXY_COMMAND_GET_TYPE 5
-
-#define DSP_COMMAND_GALAXY_9 9
-#define GALAXY_COMMAND_WSSMODE 0
-#define GALAXY_COMMAND_SB8MODE 1
-
-#define GALAXY_MODE_WSS GALAXY_COMMAND_WSSMODE
-#define GALAXY_MODE_SB8 GALAXY_COMMAND_SB8MODE
-
-struct snd_galaxy {
- void __iomem *port;
- void __iomem *config_port;
- void __iomem *wss_port;
- u32 config;
- struct resource *res_port;
- struct resource *res_config_port;
- struct resource *res_wss_port;
-};
-
-static u32 config[SNDRV_CARDS];
-static u8 wss_config[SNDRV_CARDS];
-
-static int __devinit snd_galaxy_match(struct device *dev, unsigned int n)
-{
- if (!enable[n])
- return 0;
-
- switch (port[n]) {
- case SNDRV_AUTO_PORT:
- dev_err(dev, "please specify port\n");
- return 0;
- case 0x220:
- config[n] |= GALAXY_CONFIG_SBA_220;
- break;
- case 0x240:
- config[n] |= GALAXY_CONFIG_SBA_240;
- break;
- case 0x260:
- config[n] |= GALAXY_CONFIG_SBA_260;
- break;
- case 0x280:
- config[n] |= GALAXY_CONFIG_SBA_280;
- break;
- default:
- dev_err(dev, "invalid port %#lx\n", port[n]);
- return 0;
- }
-
- switch (wss_port[n]) {
- case SNDRV_AUTO_PORT:
- dev_err(dev, "please specify wss_port\n");
- return 0;
- case 0x530:
- config[n] |= GALAXY_CONFIG_WSS_ENABLE | GALAXY_CONFIG_WSSA_530;
- break;
- case 0x604:
- config[n] |= GALAXY_CONFIG_WSS_ENABLE | GALAXY_CONFIG_WSSA_604;
- break;
- case 0xe80:
- config[n] |= GALAXY_CONFIG_WSS_ENABLE | GALAXY_CONFIG_WSSA_E80;
- break;
- case 0xf40:
- config[n] |= GALAXY_CONFIG_WSS_ENABLE | GALAXY_CONFIG_WSSA_F40;
- break;
- default:
- dev_err(dev, "invalid WSS port %#lx\n", wss_port[n]);
- return 0;
- }
-
- switch (irq[n]) {
- case SNDRV_AUTO_IRQ:
- dev_err(dev, "please specify irq\n");
- return 0;
- case 7:
- wss_config[n] |= WSS_CONFIG_IRQ_7;
- break;
- case 2:
- irq[n] = 9;
- case 9:
- wss_config[n] |= WSS_CONFIG_IRQ_9;
- break;
- case 10:
- wss_config[n] |= WSS_CONFIG_IRQ_10;
- break;
- case 11:
- wss_config[n] |= WSS_CONFIG_IRQ_11;
- break;
- default:
- dev_err(dev, "invalid IRQ %d\n", irq[n]);
- return 0;
- }
-
- switch (dma1[n]) {
- case SNDRV_AUTO_DMA:
- dev_err(dev, "please specify dma1\n");
- return 0;
- case 0:
- wss_config[n] |= WSS_CONFIG_DMA_0;
- break;
- case 1:
- wss_config[n] |= WSS_CONFIG_DMA_1;
- break;
- case 3:
- wss_config[n] |= WSS_CONFIG_DMA_3;
- break;
- default:
- dev_err(dev, "invalid playback DMA %d\n", dma1[n]);
- return 0;
- }
-
- if (dma2[n] == SNDRV_AUTO_DMA || dma2[n] == dma1[n]) {
- dma2[n] = -1;
- goto mpu;
- }
-
- wss_config[n] |= WSS_CONFIG_DUPLEX;
- switch (dma2[n]) {
- case 0:
- break;
- case 1:
- if (dma1[n] == 0)
- break;
- default:
- dev_err(dev, "invalid capture DMA %d\n", dma2[n]);
- return 0;
- }
-
-mpu:
- switch (mpu_port[n]) {
- case SNDRV_AUTO_PORT:
- dev_warn(dev, "mpu_port not specified; not using MPU-401\n");
- mpu_port[n] = -1;
- goto fm;
- case 0x300:
- config[n] |= GALAXY_CONFIG_MPU_ENABLE | GALAXY_CONFIG_MPUA_300;
- break;
- case 0x330:
- config[n] |= GALAXY_CONFIG_MPU_ENABLE | GALAXY_CONFIG_MPUA_330;
- break;
- default:
- dev_err(dev, "invalid MPU port %#lx\n", mpu_port[n]);
- return 0;
- }
-
- switch (mpu_irq[n]) {
- case SNDRV_AUTO_IRQ:
- dev_warn(dev, "mpu_irq not specified: using polling mode\n");
- mpu_irq[n] = -1;
- break;
- case 2:
- mpu_irq[n] = 9;
- case 9:
- config[n] |= GALAXY_CONFIG_MPUIRQ_2;
- break;
-#ifdef AZT1605
- case 3:
- config[n] |= GALAXY_CONFIG_MPUIRQ_3;
- break;
-#endif
- case 5:
- config[n] |= GALAXY_CONFIG_MPUIRQ_5;
- break;
- case 7:
- config[n] |= GALAXY_CONFIG_MPUIRQ_7;
- break;
-#ifdef AZT2316
- case 10:
- config[n] |= GALAXY_CONFIG_MPUIRQ_10;
- break;
-#endif
- default:
- dev_err(dev, "invalid MPU IRQ %d\n", mpu_irq[n]);
- return 0;
- }
-
- if (mpu_irq[n] == irq[n]) {
- dev_err(dev, "cannot share IRQ between WSS and MPU-401\n");
- return 0;
- }
-
-fm:
- switch (fm_port[n]) {
- case SNDRV_AUTO_PORT:
- dev_warn(dev, "fm_port not specified: not using OPL3\n");
- fm_port[n] = -1;
- break;
- case 0x388:
- break;
- default:
- dev_err(dev, "illegal FM port %#lx\n", fm_port[n]);
- return 0;
- }
-
- config[n] |= GALAXY_CONFIG_GAME_ENABLE;
- return 1;
-}
-
-static int __devinit galaxy_init(struct snd_galaxy *galaxy, u8 *type)
-{
- u8 major;
- u8 minor;
- int err;
-
- err = dsp_reset(galaxy->port);
- if (err < 0)
- return err;
-
- err = dsp_get_version(galaxy->port, &major, &minor);
- if (err < 0)
- return err;
-
- if (major != GALAXY_DSP_MAJOR || minor != GALAXY_DSP_MINOR)
- return -ENODEV;
-
- err = dsp_command(galaxy->port, DSP_COMMAND_GALAXY_8);
- if (err < 0)
- return err;
-
- err = dsp_command(galaxy->port, GALAXY_COMMAND_GET_TYPE);
- if (err < 0)
- return err;
-
- err = dsp_get_byte(galaxy->port, type);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static int __devinit galaxy_set_mode(struct snd_galaxy *galaxy, u8 mode)
-{
- int err;
-
- err = dsp_command(galaxy->port, DSP_COMMAND_GALAXY_9);
- if (err < 0)
- return err;
-
- err = dsp_command(galaxy->port, mode);
- if (err < 0)
- return err;
-
-#ifdef AZT1605
- /*
- * Needed for MPU IRQ on AZT1605, but AZT2316 loses WSS again
- */
- err = dsp_reset(galaxy->port);
- if (err < 0)
- return err;
-#endif
-
- return 0;
-}
-
-static void galaxy_set_config(struct snd_galaxy *galaxy, u32 config)
-{
- u8 tmp = ioread8(galaxy->config_port + CONFIG_PORT_SET);
- int i;
-
- iowrite8(tmp | 0x80, galaxy->config_port + CONFIG_PORT_SET);
- for (i = 0; i < GALAXY_CONFIG_SIZE; i++) {
- iowrite8(config, galaxy->config_port + i);
- config >>= 8;
- }
- iowrite8(tmp & 0x7f, galaxy->config_port + CONFIG_PORT_SET);
- msleep(10);
-}
-
-static void __devinit galaxy_config(struct snd_galaxy *galaxy, u32 config)
-{
- int i;
-
- for (i = GALAXY_CONFIG_SIZE; i; i--) {
- u8 tmp = ioread8(galaxy->config_port + i - 1);
- galaxy->config = (galaxy->config << 8) | tmp;
- }
- config |= galaxy->config & GALAXY_CONFIG_MASK;
- galaxy_set_config(galaxy, config);
-}
-
-static int __devinit galaxy_wss_config(struct snd_galaxy *galaxy, u8 wss_config)
-{
- int err;
-
- err = wss_detect(galaxy->wss_port);
- if (err < 0)
- return err;
-
- wss_set_config(galaxy->wss_port, wss_config);
-
- err = galaxy_set_mode(galaxy, GALAXY_MODE_WSS);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static void snd_galaxy_free(struct snd_card *card)
-{
- struct snd_galaxy *galaxy = card->private_data;
-
- if (galaxy->wss_port) {
- wss_set_config(galaxy->wss_port, 0);
- ioport_unmap(galaxy->wss_port);
- release_and_free_resource(galaxy->res_wss_port);
- }
- if (galaxy->config_port) {
- galaxy_set_config(galaxy, galaxy->config);
- ioport_unmap(galaxy->config_port);
- release_and_free_resource(galaxy->res_config_port);
- }
- if (galaxy->port) {
- ioport_unmap(galaxy->port);
- release_and_free_resource(galaxy->res_port);
- }
-}
-
-static int __devinit snd_galaxy_probe(struct device *dev, unsigned int n)
-{
- struct snd_galaxy *galaxy;
- struct snd_wss *chip;
- struct snd_card *card;
- u8 type;
- int err;
-
- err = snd_card_create(index[n], id[n], THIS_MODULE, sizeof *galaxy,
- &card);
- if (err < 0)
- return err;
-
- snd_card_set_dev(card, dev);
-
- card->private_free = snd_galaxy_free;
- galaxy = card->private_data;
-
- galaxy->res_port = request_region(port[n], 16, DRV_NAME);
- if (!galaxy->res_port) {
- dev_err(dev, "could not grab ports %#lx-%#lx\n", port[n],
- port[n] + 15);
- err = -EBUSY;
- goto error;
- }
- galaxy->port = ioport_map(port[n], 16);
-
- err = galaxy_init(galaxy, &type);
- if (err < 0) {
- dev_err(dev, "did not find a Sound Galaxy at %#lx\n", port[n]);
- goto error;
- }
- dev_info(dev, "Sound Galaxy (type %d) found at %#lx\n", type, port[n]);
-
- galaxy->res_config_port = request_region(port[n] + GALAXY_PORT_CONFIG,
- 16, DRV_NAME);
- if (!galaxy->res_config_port) {
- dev_err(dev, "could not grab ports %#lx-%#lx\n",
- port[n] + GALAXY_PORT_CONFIG,
- port[n] + GALAXY_PORT_CONFIG + 15);
- err = -EBUSY;
- goto error;
- }
- galaxy->config_port = ioport_map(port[n] + GALAXY_PORT_CONFIG, 16);
-
- galaxy_config(galaxy, config[n]);
-
- galaxy->res_wss_port = request_region(wss_port[n], 4, DRV_NAME);
- if (!galaxy->res_wss_port) {
- dev_err(dev, "could not grab ports %#lx-%#lx\n", wss_port[n],
- wss_port[n] + 3);
- err = -EBUSY;
- goto error;
- }
- galaxy->wss_port = ioport_map(wss_port[n], 4);
-
- err = galaxy_wss_config(galaxy, wss_config[n]);
- if (err < 0) {
- dev_err(dev, "could not configure WSS\n");
- goto error;
- }
-
- strcpy(card->driver, DRV_NAME);
- strcpy(card->shortname, DRV_NAME);
- sprintf(card->longname, "%s at %#lx/%#lx, irq %d, dma %d/%d",
- card->shortname, port[n], wss_port[n], irq[n], dma1[n],
- dma2[n]);
-
- err = snd_wss_create(card, wss_port[n] + 4, -1, irq[n], dma1[n],
- dma2[n], WSS_HW_DETECT, 0, &chip);
- if (err < 0)
- goto error;
-
- err = snd_wss_pcm(chip, 0, NULL);
- if (err < 0)
- goto error;
-
- err = snd_wss_mixer(chip);
- if (err < 0)
- goto error;
-
- err = snd_wss_timer(chip, 0, NULL);
- if (err < 0)
- goto error;
-
- if (mpu_port[n] >= 0) {
- err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
- mpu_port[n], 0, mpu_irq[n], NULL);
- if (err < 0)
- goto error;
- }
-
- if (fm_port[n] >= 0) {
- struct snd_opl3 *opl3;
-
- err = snd_opl3_create(card, fm_port[n], fm_port[n] + 2,
- OPL3_HW_AUTO, 0, &opl3);
- if (err < 0) {
- dev_err(dev, "no OPL device at %#lx\n", fm_port[n]);
- goto error;
- }
- err = snd_opl3_timer_new(opl3, 1, 2);
- if (err < 0)
- goto error;
-
- err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
- if (err < 0)
- goto error;
- }
-
- err = snd_card_register(card);
- if (err < 0)
- goto error;
-
- dev_set_drvdata(dev, card);
- return 0;
-
-error:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit snd_galaxy_remove(struct device *dev, unsigned int n)
-{
- snd_card_free(dev_get_drvdata(dev));
- dev_set_drvdata(dev, NULL);
- return 0;
-}
-
-static struct isa_driver snd_galaxy_driver = {
- .match = snd_galaxy_match,
- .probe = snd_galaxy_probe,
- .remove = __devexit_p(snd_galaxy_remove),
-
- .driver = {
- .name = DEV_NAME
- }
-};
-
-static int __init alsa_card_galaxy_init(void)
-{
- return isa_register_driver(&snd_galaxy_driver, SNDRV_CARDS);
-}
-
-static void __exit alsa_card_galaxy_exit(void)
-{
- isa_unregister_driver(&snd_galaxy_driver);
-}
-
-module_init(alsa_card_galaxy_init);
-module_exit(alsa_card_galaxy_exit);
diff --git a/ANDROID_3.4.5/sound/isa/gus/Makefile b/ANDROID_3.4.5/sound/isa/gus/Makefile
deleted file mode 100644
index 6cd4ee03..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-gus-lib-objs := gus_main.o \
- gus_io.o gus_irq.o gus_timer.o \
- gus_mem.o gus_mem_proc.o gus_dram.o gus_dma.o gus_volume.o \
- gus_pcm.o gus_mixer.o \
- gus_uart.o \
- gus_reset.o
-
-snd-gusclassic-objs := gusclassic.o
-snd-gusextreme-objs := gusextreme.o
-snd-gusmax-objs := gusmax.o
-snd-interwave-objs := interwave.o
-snd-interwave-stb-objs := interwave-stb.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_GUSCLASSIC) += snd-gusclassic.o snd-gus-lib.o
-obj-$(CONFIG_SND_GUSMAX) += snd-gusmax.o snd-gus-lib.o
-obj-$(CONFIG_SND_GUSEXTREME) += snd-gusextreme.o snd-gus-lib.o
-obj-$(CONFIG_SND_INTERWAVE) += snd-interwave.o snd-gus-lib.o
-obj-$(CONFIG_SND_INTERWAVE_STB) += snd-interwave-stb.o snd-gus-lib.o
diff --git a/ANDROID_3.4.5/sound/isa/gus/gus_dma.c b/ANDROID_3.4.5/sound/isa/gus/gus_dma.c
deleted file mode 100644
index 36c27c83..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/gus_dma.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Routines for GF1 DMA control
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/dma.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/gus.h>
-
-static void snd_gf1_dma_ack(struct snd_gus_card * gus)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- snd_gf1_write8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL, 0x00);
- snd_gf1_look8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-}
-
-static void snd_gf1_dma_program(struct snd_gus_card * gus,
- unsigned int addr,
- unsigned long buf_addr,
- unsigned int count,
- unsigned int cmd)
-{
- unsigned long flags;
- unsigned int address;
- unsigned char dma_cmd;
- unsigned int address_high;
-
- snd_printdd("dma_transfer: addr=0x%x, buf=0x%lx, count=0x%x\n",
- addr, buf_addr, count);
-
- if (gus->gf1.dma1 > 3) {
- if (gus->gf1.enh_mode) {
- address = addr >> 1;
- } else {
- if (addr & 0x1f) {
- snd_printd("snd_gf1_dma_transfer: unaligned address (0x%x)?\n", addr);
- return;
- }
- address = (addr & 0x000c0000) | ((addr & 0x0003ffff) >> 1);
- }
- } else {
- address = addr;
- }
-
- dma_cmd = SNDRV_GF1_DMA_ENABLE | (unsigned short) cmd;
-#if 0
- dma_cmd |= 0x08;
-#endif
- if (dma_cmd & SNDRV_GF1_DMA_16BIT) {
- count++;
- count &= ~1; /* align */
- }
- if (gus->gf1.dma1 > 3) {
- dma_cmd |= SNDRV_GF1_DMA_WIDTH16;
- count++;
- count &= ~1; /* align */
- }
- snd_gf1_dma_ack(gus);
- snd_dma_program(gus->gf1.dma1, buf_addr, count, dma_cmd & SNDRV_GF1_DMA_READ ? DMA_MODE_READ : DMA_MODE_WRITE);
-#if 0
- snd_printk(KERN_DEBUG "address = 0x%x, count = 0x%x, dma_cmd = 0x%x\n",
- address << 1, count, dma_cmd);
-#endif
- spin_lock_irqsave(&gus->reg_lock, flags);
- if (gus->gf1.enh_mode) {
- address_high = ((address >> 16) & 0x000000f0) | (address & 0x0000000f);
- snd_gf1_write16(gus, SNDRV_GF1_GW_DRAM_DMA_LOW, (unsigned short) (address >> 4));
- snd_gf1_write8(gus, SNDRV_GF1_GB_DRAM_DMA_HIGH, (unsigned char) address_high);
- } else
- snd_gf1_write16(gus, SNDRV_GF1_GW_DRAM_DMA_LOW, (unsigned short) (address >> 4));
- snd_gf1_write8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL, dma_cmd);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-}
-
-static struct snd_gf1_dma_block *snd_gf1_dma_next_block(struct snd_gus_card * gus)
-{
- struct snd_gf1_dma_block *block;
-
- /* PCM block have bigger priority than synthesizer one */
- if (gus->gf1.dma_data_pcm) {
- block = gus->gf1.dma_data_pcm;
- if (gus->gf1.dma_data_pcm_last == block) {
- gus->gf1.dma_data_pcm =
- gus->gf1.dma_data_pcm_last = NULL;
- } else {
- gus->gf1.dma_data_pcm = block->next;
- }
- } else if (gus->gf1.dma_data_synth) {
- block = gus->gf1.dma_data_synth;
- if (gus->gf1.dma_data_synth_last == block) {
- gus->gf1.dma_data_synth =
- gus->gf1.dma_data_synth_last = NULL;
- } else {
- gus->gf1.dma_data_synth = block->next;
- }
- } else {
- block = NULL;
- }
- if (block) {
- gus->gf1.dma_ack = block->ack;
- gus->gf1.dma_private_data = block->private_data;
- }
- return block;
-}
-
-
-static void snd_gf1_dma_interrupt(struct snd_gus_card * gus)
-{
- struct snd_gf1_dma_block *block;
-
- snd_gf1_dma_ack(gus);
- if (gus->gf1.dma_ack)
- gus->gf1.dma_ack(gus, gus->gf1.dma_private_data);
- spin_lock(&gus->dma_lock);
- if (gus->gf1.dma_data_pcm == NULL &&
- gus->gf1.dma_data_synth == NULL) {
- gus->gf1.dma_ack = NULL;
- gus->gf1.dma_flags &= ~SNDRV_GF1_DMA_TRIGGER;
- spin_unlock(&gus->dma_lock);
- return;
- }
- block = snd_gf1_dma_next_block(gus);
- spin_unlock(&gus->dma_lock);
- snd_gf1_dma_program(gus, block->addr, block->buf_addr, block->count, (unsigned short) block->cmd);
- kfree(block);
-#if 0
- snd_printd(KERN_DEBUG "program dma (IRQ) - "
- "addr = 0x%x, buffer = 0x%lx, count = 0x%x, cmd = 0x%x\n",
- block->addr, block->buf_addr, block->count, block->cmd);
-#endif
-}
-
-int snd_gf1_dma_init(struct snd_gus_card * gus)
-{
- mutex_lock(&gus->dma_mutex);
- gus->gf1.dma_shared++;
- if (gus->gf1.dma_shared > 1) {
- mutex_unlock(&gus->dma_mutex);
- return 0;
- }
- gus->gf1.interrupt_handler_dma_write = snd_gf1_dma_interrupt;
- gus->gf1.dma_data_pcm =
- gus->gf1.dma_data_pcm_last =
- gus->gf1.dma_data_synth =
- gus->gf1.dma_data_synth_last = NULL;
- mutex_unlock(&gus->dma_mutex);
- return 0;
-}
-
-int snd_gf1_dma_done(struct snd_gus_card * gus)
-{
- struct snd_gf1_dma_block *block;
-
- mutex_lock(&gus->dma_mutex);
- gus->gf1.dma_shared--;
- if (!gus->gf1.dma_shared) {
- snd_dma_disable(gus->gf1.dma1);
- snd_gf1_set_default_handlers(gus, SNDRV_GF1_HANDLER_DMA_WRITE);
- snd_gf1_dma_ack(gus);
- while ((block = gus->gf1.dma_data_pcm)) {
- gus->gf1.dma_data_pcm = block->next;
- kfree(block);
- }
- while ((block = gus->gf1.dma_data_synth)) {
- gus->gf1.dma_data_synth = block->next;
- kfree(block);
- }
- gus->gf1.dma_data_pcm_last =
- gus->gf1.dma_data_synth_last = NULL;
- }
- mutex_unlock(&gus->dma_mutex);
- return 0;
-}
-
-int snd_gf1_dma_transfer_block(struct snd_gus_card * gus,
- struct snd_gf1_dma_block * __block,
- int atomic,
- int synth)
-{
- unsigned long flags;
- struct snd_gf1_dma_block *block;
-
- block = kmalloc(sizeof(*block), atomic ? GFP_ATOMIC : GFP_KERNEL);
- if (block == NULL) {
- snd_printk(KERN_ERR "gf1: DMA transfer failure; not enough memory\n");
- return -ENOMEM;
- }
- *block = *__block;
- block->next = NULL;
-
- snd_printdd("addr = 0x%x, buffer = 0x%lx, count = 0x%x, cmd = 0x%x\n",
- block->addr, (long) block->buffer, block->count,
- block->cmd);
-
- snd_printdd("gus->gf1.dma_data_pcm_last = 0x%lx\n",
- (long)gus->gf1.dma_data_pcm_last);
- snd_printdd("gus->gf1.dma_data_pcm = 0x%lx\n",
- (long)gus->gf1.dma_data_pcm);
-
- spin_lock_irqsave(&gus->dma_lock, flags);
- if (synth) {
- if (gus->gf1.dma_data_synth_last) {
- gus->gf1.dma_data_synth_last->next = block;
- gus->gf1.dma_data_synth_last = block;
- } else {
- gus->gf1.dma_data_synth =
- gus->gf1.dma_data_synth_last = block;
- }
- } else {
- if (gus->gf1.dma_data_pcm_last) {
- gus->gf1.dma_data_pcm_last->next = block;
- gus->gf1.dma_data_pcm_last = block;
- } else {
- gus->gf1.dma_data_pcm =
- gus->gf1.dma_data_pcm_last = block;
- }
- }
- if (!(gus->gf1.dma_flags & SNDRV_GF1_DMA_TRIGGER)) {
- gus->gf1.dma_flags |= SNDRV_GF1_DMA_TRIGGER;
- block = snd_gf1_dma_next_block(gus);
- spin_unlock_irqrestore(&gus->dma_lock, flags);
- if (block == NULL)
- return 0;
- snd_gf1_dma_program(gus, block->addr, block->buf_addr, block->count, (unsigned short) block->cmd);
- kfree(block);
- return 0;
- }
- spin_unlock_irqrestore(&gus->dma_lock, flags);
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/isa/gus/gus_dram.c b/ANDROID_3.4.5/sound/isa/gus/gus_dram.c
deleted file mode 100644
index fd2e2e2e..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/gus_dram.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * DRAM access routines
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/gus.h>
-#include <sound/info.h>
-
-
-static int snd_gus_dram_poke(struct snd_gus_card *gus, char __user *_buffer,
- unsigned int address, unsigned int size)
-{
- unsigned long flags;
- unsigned int size1, size2;
- char buffer[256], *pbuffer;
-
- while (size > 0) {
- size1 = size > sizeof(buffer) ? sizeof(buffer) : size;
- if (copy_from_user(buffer, _buffer, size1))
- return -EFAULT;
- if (gus->interwave) {
- spin_lock_irqsave(&gus->reg_lock, flags);
- snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01);
- snd_gf1_dram_addr(gus, address);
- outsb(GUSP(gus, DRAM), buffer, size1);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- address += size1;
- } else {
- pbuffer = buffer;
- size2 = size1;
- while (size2--)
- snd_gf1_poke(gus, address++, *pbuffer++);
- }
- size -= size1;
- _buffer += size1;
- }
- return 0;
-}
-
-
-int snd_gus_dram_write(struct snd_gus_card *gus, char __user *buffer,
- unsigned int address, unsigned int size)
-{
- return snd_gus_dram_poke(gus, buffer, address, size);
-}
-
-static int snd_gus_dram_peek(struct snd_gus_card *gus, char __user *_buffer,
- unsigned int address, unsigned int size,
- int rom)
-{
- unsigned long flags;
- unsigned int size1, size2;
- char buffer[256], *pbuffer;
-
- while (size > 0) {
- size1 = size > sizeof(buffer) ? sizeof(buffer) : size;
- if (gus->interwave) {
- spin_lock_irqsave(&gus->reg_lock, flags);
- snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, rom ? 0x03 : 0x01);
- snd_gf1_dram_addr(gus, address);
- insb(GUSP(gus, DRAM), buffer, size1);
- snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- address += size1;
- } else {
- pbuffer = buffer;
- size2 = size1;
- while (size2--)
- *pbuffer++ = snd_gf1_peek(gus, address++);
- }
- if (copy_to_user(_buffer, buffer, size1))
- return -EFAULT;
- size -= size1;
- _buffer += size1;
- }
- return 0;
-}
-
-int snd_gus_dram_read(struct snd_gus_card *gus, char __user *buffer,
- unsigned int address, unsigned int size,
- int rom)
-{
- return snd_gus_dram_peek(gus, buffer, address, size, rom);
-}
diff --git a/ANDROID_3.4.5/sound/isa/gus/gus_instr.c b/ANDROID_3.4.5/sound/isa/gus/gus_instr.c
deleted file mode 100644
index 4dc9caf8..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/gus_instr.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Routines for Gravis UltraSound soundcards - Synthesizer
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/gus.h>
-
-/*
- *
- */
-
-int snd_gus_iwffff_put_sample(void *private_data, struct iwffff_wave *wave,
- char __user *data, long len, int atomic)
-{
- struct snd_gus_card *gus = private_data;
- struct snd_gf1_mem_block *block;
- int err;
-
- if (wave->format & IWFFFF_WAVE_ROM)
- return 0; /* it's probably ok - verify the address? */
- if (wave->format & IWFFFF_WAVE_STEREO)
- return -EINVAL; /* not supported */
- block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc,
- SNDRV_GF1_MEM_OWNER_WAVE_IWFFFF,
- NULL, wave->size,
- wave->format & IWFFFF_WAVE_16BIT, 1,
- wave->share_id);
- if (block == NULL)
- return -ENOMEM;
- err = snd_gus_dram_write(gus, data,
- block->ptr, wave->size);
- if (err < 0) {
- snd_gf1_mem_lock(&gus->gf1.mem_alloc, 0);
- snd_gf1_mem_xfree(&gus->gf1.mem_alloc, block);
- snd_gf1_mem_lock(&gus->gf1.mem_alloc, 1);
- return err;
- }
- wave->address.memory = block->ptr;
- return 0;
-}
-
-int snd_gus_iwffff_get_sample(void *private_data, struct iwffff_wave *wave,
- char __user *data, long len, int atomic)
-{
- struct snd_gus_card *gus = private_data;
-
- return snd_gus_dram_read(gus, data, wave->address.memory, wave->size,
- wave->format & IWFFFF_WAVE_ROM ? 1 : 0);
-}
-
-int snd_gus_iwffff_remove_sample(void *private_data, struct iwffff_wave *wave,
- int atomic)
-{
- struct snd_gus_card *gus = private_data;
-
- if (wave->format & IWFFFF_WAVE_ROM)
- return 0; /* it's probably ok - verify the address? */
- return snd_gf1_mem_free(&gus->gf1.mem_alloc, wave->address.memory);
-}
-
-/*
- *
- */
-
-int snd_gus_gf1_put_sample(void *private_data, struct gf1_wave *wave,
- char __user *data, long len, int atomic)
-{
- struct snd_gus_card *gus = private_data;
- struct snd_gf1_mem_block *block;
- int err;
-
- if (wave->format & GF1_WAVE_STEREO)
- return -EINVAL; /* not supported */
- block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc,
- SNDRV_GF1_MEM_OWNER_WAVE_GF1,
- NULL, wave->size,
- wave->format & GF1_WAVE_16BIT, 1,
- wave->share_id);
- if (block == NULL)
- return -ENOMEM;
- err = snd_gus_dram_write(gus, data,
- block->ptr, wave->size);
- if (err < 0) {
- snd_gf1_mem_lock(&gus->gf1.mem_alloc, 0);
- snd_gf1_mem_xfree(&gus->gf1.mem_alloc, block);
- snd_gf1_mem_lock(&gus->gf1.mem_alloc, 1);
- return err;
- }
- wave->address.memory = block->ptr;
- return 0;
-}
-
-int snd_gus_gf1_get_sample(void *private_data, struct gf1_wave *wave,
- char __user *data, long len, int atomic)
-{
- struct snd_gus_card *gus = private_data;
-
- return snd_gus_dram_read(gus, data, wave->address.memory, wave->size, 0);
-}
-
-int snd_gus_gf1_remove_sample(void *private_data, struct gf1_wave *wave,
- int atomic)
-{
- struct snd_gus_card *gus = private_data;
-
- return snd_gf1_mem_free(&gus->gf1.mem_alloc, wave->address.memory);
-}
-
-/*
- *
- */
-
-int snd_gus_simple_put_sample(void *private_data, struct simple_instrument *instr,
- char __user *data, long len, int atomic)
-{
- struct snd_gus_card *gus = private_data;
- struct snd_gf1_mem_block *block;
- int err;
-
- if (instr->format & SIMPLE_WAVE_STEREO)
- return -EINVAL; /* not supported */
- block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc,
- SNDRV_GF1_MEM_OWNER_WAVE_SIMPLE,
- NULL, instr->size,
- instr->format & SIMPLE_WAVE_16BIT, 1,
- instr->share_id);
- if (block == NULL)
- return -ENOMEM;
- err = snd_gus_dram_write(gus, data, block->ptr, instr->size);
- if (err < 0) {
- snd_gf1_mem_lock(&gus->gf1.mem_alloc, 0);
- snd_gf1_mem_xfree(&gus->gf1.mem_alloc, block);
- snd_gf1_mem_lock(&gus->gf1.mem_alloc, 1);
- return err;
- }
- instr->address.memory = block->ptr;
- return 0;
-}
-
-int snd_gus_simple_get_sample(void *private_data, struct simple_instrument *instr,
- char __user *data, long len, int atomic)
-{
- struct snd_gus_card *gus = private_data;
-
- return snd_gus_dram_read(gus, data, instr->address.memory, instr->size, 0);
-}
-
-int snd_gus_simple_remove_sample(void *private_data, struct simple_instrument *instr,
- int atomic)
-{
- struct snd_gus_card *gus = private_data;
-
- return snd_gf1_mem_free(&gus->gf1.mem_alloc, instr->address.memory);
-}
diff --git a/ANDROID_3.4.5/sound/isa/gus/gus_io.c b/ANDROID_3.4.5/sound/isa/gus/gus_io.c
deleted file mode 100644
index ca79878d..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/gus_io.c
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * I/O routines for GF1/InterWave synthesizer chips
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/delay.h>
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/gus.h>
-
-void snd_gf1_delay(struct snd_gus_card * gus)
-{
- int i;
-
- for (i = 0; i < 6; i++) {
- mb();
- inb(GUSP(gus, DRAM));
- }
-}
-
-/*
- * =======================================================================
- */
-
-/*
- * ok.. stop of control registers (wave & ramp) need some special things..
- * big UltraClick (tm) elimination...
- */
-
-static inline void __snd_gf1_ctrl_stop(struct snd_gus_card * gus, unsigned char reg)
-{
- unsigned char value;
-
- outb(reg | 0x80, gus->gf1.reg_regsel);
- mb();
- value = inb(gus->gf1.reg_data8);
- mb();
- outb(reg, gus->gf1.reg_regsel);
- mb();
- outb((value | 0x03) & ~(0x80 | 0x20), gus->gf1.reg_data8);
- mb();
-}
-
-static inline void __snd_gf1_write8(struct snd_gus_card * gus,
- unsigned char reg,
- unsigned char data)
-{
- outb(reg, gus->gf1.reg_regsel);
- mb();
- outb(data, gus->gf1.reg_data8);
- mb();
-}
-
-static inline unsigned char __snd_gf1_look8(struct snd_gus_card * gus,
- unsigned char reg)
-{
- outb(reg, gus->gf1.reg_regsel);
- mb();
- return inb(gus->gf1.reg_data8);
-}
-
-static inline void __snd_gf1_write16(struct snd_gus_card * gus,
- unsigned char reg, unsigned int data)
-{
- outb(reg, gus->gf1.reg_regsel);
- mb();
- outw((unsigned short) data, gus->gf1.reg_data16);
- mb();
-}
-
-static inline unsigned short __snd_gf1_look16(struct snd_gus_card * gus,
- unsigned char reg)
-{
- outb(reg, gus->gf1.reg_regsel);
- mb();
- return inw(gus->gf1.reg_data16);
-}
-
-static inline void __snd_gf1_adlib_write(struct snd_gus_card * gus,
- unsigned char reg, unsigned char data)
-{
- outb(reg, gus->gf1.reg_timerctrl);
- inb(gus->gf1.reg_timerctrl);
- inb(gus->gf1.reg_timerctrl);
- outb(data, gus->gf1.reg_timerdata);
- inb(gus->gf1.reg_timerctrl);
- inb(gus->gf1.reg_timerctrl);
-}
-
-static inline void __snd_gf1_write_addr(struct snd_gus_card * gus, unsigned char reg,
- unsigned int addr, int w_16bit)
-{
- if (gus->gf1.enh_mode) {
- if (w_16bit)
- addr = ((addr >> 1) & ~0x0000000f) | (addr & 0x0000000f);
- __snd_gf1_write8(gus, SNDRV_GF1_VB_UPPER_ADDRESS, (unsigned char) ((addr >> 26) & 0x03));
- } else if (w_16bit)
- addr = (addr & 0x00c0000f) | ((addr & 0x003ffff0) >> 1);
- __snd_gf1_write16(gus, reg, (unsigned short) (addr >> 11));
- __snd_gf1_write16(gus, reg + 1, (unsigned short) (addr << 5));
-}
-
-static inline unsigned int __snd_gf1_read_addr(struct snd_gus_card * gus,
- unsigned char reg, short w_16bit)
-{
- unsigned int res;
-
- res = ((unsigned int) __snd_gf1_look16(gus, reg | 0x80) << 11) & 0xfff800;
- res |= ((unsigned int) __snd_gf1_look16(gus, (reg + 1) | 0x80) >> 5) & 0x0007ff;
- if (gus->gf1.enh_mode) {
- res |= (unsigned int) __snd_gf1_look8(gus, SNDRV_GF1_VB_UPPER_ADDRESS | 0x80) << 26;
- if (w_16bit)
- res = ((res << 1) & 0xffffffe0) | (res & 0x0000000f);
- } else if (w_16bit)
- res = ((res & 0x001ffff0) << 1) | (res & 0x00c0000f);
- return res;
-}
-
-
-/*
- * =======================================================================
- */
-
-void snd_gf1_ctrl_stop(struct snd_gus_card * gus, unsigned char reg)
-{
- __snd_gf1_ctrl_stop(gus, reg);
-}
-
-void snd_gf1_write8(struct snd_gus_card * gus,
- unsigned char reg,
- unsigned char data)
-{
- __snd_gf1_write8(gus, reg, data);
-}
-
-unsigned char snd_gf1_look8(struct snd_gus_card * gus, unsigned char reg)
-{
- return __snd_gf1_look8(gus, reg);
-}
-
-void snd_gf1_write16(struct snd_gus_card * gus,
- unsigned char reg,
- unsigned int data)
-{
- __snd_gf1_write16(gus, reg, data);
-}
-
-unsigned short snd_gf1_look16(struct snd_gus_card * gus, unsigned char reg)
-{
- return __snd_gf1_look16(gus, reg);
-}
-
-void snd_gf1_adlib_write(struct snd_gus_card * gus,
- unsigned char reg,
- unsigned char data)
-{
- __snd_gf1_adlib_write(gus, reg, data);
-}
-
-void snd_gf1_write_addr(struct snd_gus_card * gus, unsigned char reg,
- unsigned int addr, short w_16bit)
-{
- __snd_gf1_write_addr(gus, reg, addr, w_16bit);
-}
-
-unsigned int snd_gf1_read_addr(struct snd_gus_card * gus,
- unsigned char reg,
- short w_16bit)
-{
- return __snd_gf1_read_addr(gus, reg, w_16bit);
-}
-
-/*
-
- */
-
-void snd_gf1_i_ctrl_stop(struct snd_gus_card * gus, unsigned char reg)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- __snd_gf1_ctrl_stop(gus, reg);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-}
-
-void snd_gf1_i_write8(struct snd_gus_card * gus,
- unsigned char reg,
- unsigned char data)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- __snd_gf1_write8(gus, reg, data);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-}
-
-unsigned char snd_gf1_i_look8(struct snd_gus_card * gus, unsigned char reg)
-{
- unsigned long flags;
- unsigned char res;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- res = __snd_gf1_look8(gus, reg);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- return res;
-}
-
-void snd_gf1_i_write16(struct snd_gus_card * gus,
- unsigned char reg,
- unsigned int data)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- __snd_gf1_write16(gus, reg, data);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-}
-
-unsigned short snd_gf1_i_look16(struct snd_gus_card * gus, unsigned char reg)
-{
- unsigned long flags;
- unsigned short res;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- res = __snd_gf1_look16(gus, reg);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- return res;
-}
-
-#if 0
-
-void snd_gf1_i_adlib_write(struct snd_gus_card * gus,
- unsigned char reg,
- unsigned char data)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- __snd_gf1_adlib_write(gus, reg, data);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-}
-
-void snd_gf1_i_write_addr(struct snd_gus_card * gus, unsigned char reg,
- unsigned int addr, short w_16bit)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- __snd_gf1_write_addr(gus, reg, addr, w_16bit);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-}
-
-#endif /* 0 */
-
-#ifdef CONFIG_SND_DEBUG
-static unsigned int snd_gf1_i_read_addr(struct snd_gus_card * gus,
- unsigned char reg, short w_16bit)
-{
- unsigned int res;
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- res = __snd_gf1_read_addr(gus, reg, w_16bit);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- return res;
-}
-#endif
-
-/*
-
- */
-
-void snd_gf1_dram_addr(struct snd_gus_card * gus, unsigned int addr)
-{
- outb(0x43, gus->gf1.reg_regsel);
- mb();
- outw((unsigned short) addr, gus->gf1.reg_data16);
- mb();
- outb(0x44, gus->gf1.reg_regsel);
- mb();
- outb((unsigned char) (addr >> 16), gus->gf1.reg_data8);
- mb();
-}
-
-void snd_gf1_poke(struct snd_gus_card * gus, unsigned int addr, unsigned char data)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
- mb();
- outw((unsigned short) addr, gus->gf1.reg_data16);
- mb();
- outb(SNDRV_GF1_GB_DRAM_IO_HIGH, gus->gf1.reg_regsel);
- mb();
- outb((unsigned char) (addr >> 16), gus->gf1.reg_data8);
- mb();
- outb(data, gus->gf1.reg_dram);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-}
-
-unsigned char snd_gf1_peek(struct snd_gus_card * gus, unsigned int addr)
-{
- unsigned long flags;
- unsigned char res;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
- mb();
- outw((unsigned short) addr, gus->gf1.reg_data16);
- mb();
- outb(SNDRV_GF1_GB_DRAM_IO_HIGH, gus->gf1.reg_regsel);
- mb();
- outb((unsigned char) (addr >> 16), gus->gf1.reg_data8);
- mb();
- res = inb(gus->gf1.reg_dram);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- return res;
-}
-
-#if 0
-
-void snd_gf1_pokew(struct snd_gus_card * gus, unsigned int addr, unsigned short data)
-{
- unsigned long flags;
-
-#ifdef CONFIG_SND_DEBUG
- if (!gus->interwave)
- snd_printk(KERN_DEBUG "snd_gf1_pokew - GF1!!!\n");
-#endif
- spin_lock_irqsave(&gus->reg_lock, flags);
- outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
- mb();
- outw((unsigned short) addr, gus->gf1.reg_data16);
- mb();
- outb(SNDRV_GF1_GB_DRAM_IO_HIGH, gus->gf1.reg_regsel);
- mb();
- outb((unsigned char) (addr >> 16), gus->gf1.reg_data8);
- mb();
- outb(SNDRV_GF1_GW_DRAM_IO16, gus->gf1.reg_regsel);
- mb();
- outw(data, gus->gf1.reg_data16);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-}
-
-unsigned short snd_gf1_peekw(struct snd_gus_card * gus, unsigned int addr)
-{
- unsigned long flags;
- unsigned short res;
-
-#ifdef CONFIG_SND_DEBUG
- if (!gus->interwave)
- snd_printk(KERN_DEBUG "snd_gf1_peekw - GF1!!!\n");
-#endif
- spin_lock_irqsave(&gus->reg_lock, flags);
- outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
- mb();
- outw((unsigned short) addr, gus->gf1.reg_data16);
- mb();
- outb(SNDRV_GF1_GB_DRAM_IO_HIGH, gus->gf1.reg_regsel);
- mb();
- outb((unsigned char) (addr >> 16), gus->gf1.reg_data8);
- mb();
- outb(SNDRV_GF1_GW_DRAM_IO16, gus->gf1.reg_regsel);
- mb();
- res = inw(gus->gf1.reg_data16);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- return res;
-}
-
-void snd_gf1_dram_setmem(struct snd_gus_card * gus, unsigned int addr,
- unsigned short value, unsigned int count)
-{
- unsigned long port;
- unsigned long flags;
-
-#ifdef CONFIG_SND_DEBUG
- if (!gus->interwave)
- snd_printk(KERN_DEBUG "snd_gf1_dram_setmem - GF1!!!\n");
-#endif
- addr &= ~1;
- count >>= 1;
- port = GUSP(gus, GF1DATALOW);
- spin_lock_irqsave(&gus->reg_lock, flags);
- outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
- mb();
- outw((unsigned short) addr, gus->gf1.reg_data16);
- mb();
- outb(SNDRV_GF1_GB_DRAM_IO_HIGH, gus->gf1.reg_regsel);
- mb();
- outb((unsigned char) (addr >> 16), gus->gf1.reg_data8);
- mb();
- outb(SNDRV_GF1_GW_DRAM_IO16, gus->gf1.reg_regsel);
- while (count--)
- outw(value, port);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-}
-
-#endif /* 0 */
-
-void snd_gf1_select_active_voices(struct snd_gus_card * gus)
-{
- unsigned short voices;
-
- static unsigned short voices_tbl[32 - 14 + 1] =
- {
- 44100, 41160, 38587, 36317, 34300, 32494, 30870, 29400, 28063, 26843,
- 25725, 24696, 23746, 22866, 22050, 21289, 20580, 19916, 19293
- };
-
- voices = gus->gf1.active_voices;
- if (voices > 32)
- voices = 32;
- if (voices < 14)
- voices = 14;
- if (gus->gf1.enh_mode)
- voices = 32;
- gus->gf1.active_voices = voices;
- gus->gf1.playback_freq =
- gus->gf1.enh_mode ? 44100 : voices_tbl[voices - 14];
- if (!gus->gf1.enh_mode) {
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_ACTIVE_VOICES, 0xc0 | (voices - 1));
- udelay(100);
- }
-}
-
-#ifdef CONFIG_SND_DEBUG
-
-void snd_gf1_print_voice_registers(struct snd_gus_card * gus)
-{
- unsigned char mode;
- int voice, ctrl;
-
- voice = gus->gf1.active_voice;
- printk(KERN_INFO " -%i- GF1 voice ctrl, ramp ctrl = 0x%x, 0x%x\n", voice, ctrl = snd_gf1_i_read8(gus, 0), snd_gf1_i_read8(gus, 0x0d));
- printk(KERN_INFO " -%i- GF1 frequency = 0x%x\n", voice, snd_gf1_i_read16(gus, 1));
- printk(KERN_INFO " -%i- GF1 loop start, end = 0x%x (0x%x), 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 2, ctrl & 4), snd_gf1_i_read_addr(gus, 2, (ctrl & 4) ^ 4), snd_gf1_i_read_addr(gus, 4, ctrl & 4), snd_gf1_i_read_addr(gus, 4, (ctrl & 4) ^ 4));
- printk(KERN_INFO " -%i- GF1 ramp start, end, rate = 0x%x, 0x%x, 0x%x\n", voice, snd_gf1_i_read8(gus, 7), snd_gf1_i_read8(gus, 8), snd_gf1_i_read8(gus, 6));
- printk(KERN_INFO" -%i- GF1 volume = 0x%x\n", voice, snd_gf1_i_read16(gus, 9));
- printk(KERN_INFO " -%i- GF1 position = 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 0x0a, ctrl & 4), snd_gf1_i_read_addr(gus, 0x0a, (ctrl & 4) ^ 4));
- if (gus->interwave && snd_gf1_i_read8(gus, 0x19) & 0x01) { /* enhanced mode */
- mode = snd_gf1_i_read8(gus, 0x15);
- printk(KERN_INFO " -%i- GFA1 mode = 0x%x\n", voice, mode);
- if (mode & 0x01) { /* Effect processor */
- printk(KERN_INFO " -%i- GFA1 effect address = 0x%x\n", voice, snd_gf1_i_read_addr(gus, 0x11, ctrl & 4));
- printk(KERN_INFO " -%i- GFA1 effect volume = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x16));
- printk(KERN_INFO " -%i- GFA1 effect volume final = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x1d));
- printk(KERN_INFO " -%i- GFA1 effect acumulator = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x14));
- }
- if (mode & 0x20) {
- printk(KERN_INFO " -%i- GFA1 left offset = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x13), snd_gf1_i_read16(gus, 0x13) >> 4);
- printk(KERN_INFO " -%i- GFA1 left offset final = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1c), snd_gf1_i_read16(gus, 0x1c) >> 4);
- printk(KERN_INFO " -%i- GFA1 right offset = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x0c), snd_gf1_i_read16(gus, 0x0c) >> 4);
- printk(KERN_INFO " -%i- GFA1 right offset final = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1b), snd_gf1_i_read16(gus, 0x1b) >> 4);
- } else
- printk(KERN_INFO " -%i- GF1 pan = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
- } else
- printk(KERN_INFO " -%i- GF1 pan = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
-}
-
-#if 0
-
-void snd_gf1_print_global_registers(struct snd_gus_card * gus)
-{
- unsigned char global_mode = 0x00;
-
- printk(KERN_INFO " -G- GF1 active voices = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_ACTIVE_VOICES));
- if (gus->interwave) {
- global_mode = snd_gf1_i_read8(gus, SNDRV_GF1_GB_GLOBAL_MODE);
- printk(KERN_INFO " -G- GF1 global mode = 0x%x\n", global_mode);
- }
- if (global_mode & 0x02) /* LFO enabled? */
- printk(KERN_INFO " -G- GF1 LFO base = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_LFO_BASE));
- printk(KERN_INFO " -G- GF1 voices IRQ read = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_VOICES_IRQ_READ));
- printk(KERN_INFO " -G- GF1 DRAM DMA control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL));
- printk(KERN_INFO " -G- GF1 DRAM DMA high/low = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_HIGH), snd_gf1_i_read16(gus, SNDRV_GF1_GW_DRAM_DMA_LOW));
- printk(KERN_INFO " -G- GF1 DRAM IO high/low = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_IO_HIGH), snd_gf1_i_read16(gus, SNDRV_GF1_GW_DRAM_IO_LOW));
- if (!gus->interwave)
- printk(KERN_INFO " -G- GF1 record DMA control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL));
- printk(KERN_INFO " -G- GF1 DRAM IO 16 = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_DRAM_IO16));
- if (gus->gf1.enh_mode) {
- printk(KERN_INFO " -G- GFA1 memory config = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG));
- printk(KERN_INFO " -G- GFA1 memory control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_MEMORY_CONTROL));
- printk(KERN_INFO " -G- GFA1 FIFO record base = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_FIFO_RECORD_BASE_ADDR));
- printk(KERN_INFO " -G- GFA1 FIFO playback base = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_FIFO_PLAY_BASE_ADDR));
- printk(KERN_INFO " -G- GFA1 interleave control = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_INTERLEAVE));
- }
-}
-
-void snd_gf1_print_setup_registers(struct snd_gus_card * gus)
-{
- printk(KERN_INFO " -S- mix control = 0x%x\n", inb(GUSP(gus, MIXCNTRLREG)));
- printk(KERN_INFO " -S- IRQ status = 0x%x\n", inb(GUSP(gus, IRQSTAT)));
- printk(KERN_INFO " -S- timer control = 0x%x\n", inb(GUSP(gus, TIMERCNTRL)));
- printk(KERN_INFO " -S- timer data = 0x%x\n", inb(GUSP(gus, TIMERDATA)));
- printk(KERN_INFO " -S- status read = 0x%x\n", inb(GUSP(gus, REGCNTRLS)));
- printk(KERN_INFO " -S- Sound Blaster control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL));
- printk(KERN_INFO " -S- AdLib timer 1/2 = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_ADLIB_TIMER_1), snd_gf1_i_look8(gus, SNDRV_GF1_GB_ADLIB_TIMER_2));
- printk(KERN_INFO " -S- reset = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET));
- if (gus->interwave) {
- printk(KERN_INFO " -S- compatibility = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_COMPATIBILITY));
- printk(KERN_INFO " -S- decode control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DECODE_CONTROL));
- printk(KERN_INFO " -S- version number = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER));
- printk(KERN_INFO " -S- MPU-401 emul. control A/B = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_MPU401_CONTROL_A), snd_gf1_i_look8(gus, SNDRV_GF1_GB_MPU401_CONTROL_B));
- printk(KERN_INFO " -S- emulation IRQ = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_EMULATION_IRQ));
- }
-}
-
-void snd_gf1_peek_print_block(struct snd_gus_card * gus, unsigned int addr, int count, int w_16bit)
-{
- if (!w_16bit) {
- while (count-- > 0)
- printk(count > 0 ? "%02x:" : "%02x", snd_gf1_peek(gus, addr++));
- } else {
- while (count-- > 0) {
- printk(count > 0 ? "%04x:" : "%04x", snd_gf1_peek(gus, addr) | (snd_gf1_peek(gus, addr + 1) << 8));
- addr += 2;
- }
- }
-}
-
-#endif /* 0 */
-
-#endif
diff --git a/ANDROID_3.4.5/sound/isa/gus/gus_irq.c b/ANDROID_3.4.5/sound/isa/gus/gus_irq.c
deleted file mode 100644
index 2055aff7..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/gus_irq.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Routine for IRQ handling from GF1/InterWave chip
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/gus.h>
-
-#ifdef CONFIG_SND_DEBUG
-#define STAT_ADD(x) ((x)++)
-#else
-#define STAT_ADD(x) while (0) { ; }
-#endif
-
-irqreturn_t snd_gus_interrupt(int irq, void *dev_id)
-{
- struct snd_gus_card * gus = dev_id;
- unsigned char status;
- int loop = 100;
- int handled = 0;
-
-__again:
- status = inb(gus->gf1.reg_irqstat);
- if (status == 0)
- return IRQ_RETVAL(handled);
- handled = 1;
- /* snd_printk(KERN_DEBUG "IRQ: status = 0x%x\n", status); */
- if (status & 0x02) {
- STAT_ADD(gus->gf1.interrupt_stat_midi_in);
- if (gus->gf1.interrupt_handler_midi_in)
- gus->gf1.interrupt_handler_midi_in(gus);
- }
- if (status & 0x01) {
- STAT_ADD(gus->gf1.interrupt_stat_midi_out);
- if (gus->gf1.interrupt_handler_midi_out)
- gus->gf1.interrupt_handler_midi_out(gus);
- }
- if (status & (0x20 | 0x40)) {
- unsigned int already, _current_;
- unsigned char voice_status, voice;
- struct snd_gus_voice *pvoice;
-
- already = 0;
- while (((voice_status = snd_gf1_i_read8(gus, SNDRV_GF1_GB_VOICES_IRQ)) & 0xc0) != 0xc0) {
- voice = voice_status & 0x1f;
- _current_ = 1 << voice;
- if (already & _current_)
- continue; /* multi request */
- already |= _current_; /* mark request */
-#if 0
- printk(KERN_DEBUG "voice = %i, voice_status = 0x%x, "
- "voice_verify = %i\n",
- voice, voice_status, inb(GUSP(gus, GF1PAGE)));
-#endif
- pvoice = &gus->gf1.voices[voice];
- if (pvoice->use) {
- if (!(voice_status & 0x80)) { /* voice position IRQ */
- STAT_ADD(pvoice->interrupt_stat_wave);
- pvoice->handler_wave(gus, pvoice);
- }
- if (!(voice_status & 0x40)) { /* volume ramp IRQ */
- STAT_ADD(pvoice->interrupt_stat_volume);
- pvoice->handler_volume(gus, pvoice);
- }
- } else {
- STAT_ADD(gus->gf1.interrupt_stat_voice_lost);
- snd_gf1_i_ctrl_stop(gus, SNDRV_GF1_VB_ADDRESS_CONTROL);
- snd_gf1_i_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
- }
- }
- }
- if (status & 0x04) {
- STAT_ADD(gus->gf1.interrupt_stat_timer1);
- if (gus->gf1.interrupt_handler_timer1)
- gus->gf1.interrupt_handler_timer1(gus);
- }
- if (status & 0x08) {
- STAT_ADD(gus->gf1.interrupt_stat_timer2);
- if (gus->gf1.interrupt_handler_timer2)
- gus->gf1.interrupt_handler_timer2(gus);
- }
- if (status & 0x80) {
- if (snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL) & 0x40) {
- STAT_ADD(gus->gf1.interrupt_stat_dma_write);
- if (gus->gf1.interrupt_handler_dma_write)
- gus->gf1.interrupt_handler_dma_write(gus);
- }
- if (snd_gf1_i_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL) & 0x40) {
- STAT_ADD(gus->gf1.interrupt_stat_dma_read);
- if (gus->gf1.interrupt_handler_dma_read)
- gus->gf1.interrupt_handler_dma_read(gus);
- }
- }
- if (--loop > 0)
- goto __again;
- return IRQ_NONE;
-}
-
-#ifdef CONFIG_SND_DEBUG
-static void snd_gus_irq_info_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_gus_card *gus;
- struct snd_gus_voice *pvoice;
- int idx;
-
- gus = entry->private_data;
- snd_iprintf(buffer, "midi out = %u\n", gus->gf1.interrupt_stat_midi_out);
- snd_iprintf(buffer, "midi in = %u\n", gus->gf1.interrupt_stat_midi_in);
- snd_iprintf(buffer, "timer1 = %u\n", gus->gf1.interrupt_stat_timer1);
- snd_iprintf(buffer, "timer2 = %u\n", gus->gf1.interrupt_stat_timer2);
- snd_iprintf(buffer, "dma write = %u\n", gus->gf1.interrupt_stat_dma_write);
- snd_iprintf(buffer, "dma read = %u\n", gus->gf1.interrupt_stat_dma_read);
- snd_iprintf(buffer, "voice lost = %u\n", gus->gf1.interrupt_stat_voice_lost);
- for (idx = 0; idx < 32; idx++) {
- pvoice = &gus->gf1.voices[idx];
- snd_iprintf(buffer, "voice %i: wave = %u, volume = %u\n",
- idx,
- pvoice->interrupt_stat_wave,
- pvoice->interrupt_stat_volume);
- }
-}
-
-void snd_gus_irq_profile_init(struct snd_gus_card *gus)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(gus->card, "gusirq", &entry))
- snd_info_set_text_ops(entry, gus, snd_gus_irq_info_read);
-}
-
-#endif
diff --git a/ANDROID_3.4.5/sound/isa/gus/gus_main.c b/ANDROID_3.4.5/sound/isa/gus/gus_main.c
deleted file mode 100644
index 4490ee44..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/gus_main.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * Routines for Gravis UltraSound soundcards
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/gus.h>
-#include <sound/control.h>
-
-#include <asm/dma.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Routines for Gravis UltraSound soundcards");
-MODULE_LICENSE("GPL");
-
-static int snd_gus_init_dma_irq(struct snd_gus_card * gus, int latches);
-
-int snd_gus_use_inc(struct snd_gus_card * gus)
-{
- if (!try_module_get(gus->card->module))
- return 0;
- return 1;
-}
-
-void snd_gus_use_dec(struct snd_gus_card * gus)
-{
- module_put(gus->card->module);
-}
-
-static int snd_gus_joystick_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 31;
- return 0;
-}
-
-static int snd_gus_joystick_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = gus->joystick_dac & 31;
- return 0;
-}
-
-static int snd_gus_joystick_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int change;
- unsigned char nval;
-
- nval = ucontrol->value.integer.value[0] & 31;
- spin_lock_irqsave(&gus->reg_lock, flags);
- change = gus->joystick_dac != nval;
- gus->joystick_dac = nval;
- snd_gf1_write8(gus, SNDRV_GF1_GB_JOYSTICK_DAC_LEVEL, gus->joystick_dac);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- return change;
-}
-
-static struct snd_kcontrol_new snd_gus_joystick_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_CARD,
- .name = "Joystick Speed",
- .info = snd_gus_joystick_info,
- .get = snd_gus_joystick_get,
- .put = snd_gus_joystick_put
-};
-
-static void snd_gus_init_control(struct snd_gus_card *gus)
-{
- if (!gus->ace_flag)
- snd_ctl_add(gus->card, snd_ctl_new1(&snd_gus_joystick_control, gus));
-}
-
-/*
- *
- */
-
-static int snd_gus_free(struct snd_gus_card *gus)
-{
- if (gus->gf1.res_port2 == NULL)
- goto __hw_end;
- snd_gf1_stop(gus);
- snd_gus_init_dma_irq(gus, 0);
- __hw_end:
- release_and_free_resource(gus->gf1.res_port1);
- release_and_free_resource(gus->gf1.res_port2);
- if (gus->gf1.irq >= 0)
- free_irq(gus->gf1.irq, (void *) gus);
- if (gus->gf1.dma1 >= 0) {
- disable_dma(gus->gf1.dma1);
- free_dma(gus->gf1.dma1);
- }
- if (!gus->equal_dma && gus->gf1.dma2 >= 0) {
- disable_dma(gus->gf1.dma2);
- free_dma(gus->gf1.dma2);
- }
- kfree(gus);
- return 0;
-}
-
-static int snd_gus_dev_free(struct snd_device *device)
-{
- struct snd_gus_card *gus = device->device_data;
- return snd_gus_free(gus);
-}
-
-int snd_gus_create(struct snd_card *card,
- unsigned long port,
- int irq, int dma1, int dma2,
- int timer_dev,
- int voices,
- int pcm_channels,
- int effect,
- struct snd_gus_card **rgus)
-{
- struct snd_gus_card *gus;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_gus_dev_free,
- };
-
- *rgus = NULL;
- gus = kzalloc(sizeof(*gus), GFP_KERNEL);
- if (gus == NULL)
- return -ENOMEM;
- spin_lock_init(&gus->reg_lock);
- spin_lock_init(&gus->voice_alloc);
- spin_lock_init(&gus->active_voice_lock);
- spin_lock_init(&gus->event_lock);
- spin_lock_init(&gus->dma_lock);
- spin_lock_init(&gus->pcm_volume_level_lock);
- spin_lock_init(&gus->uart_cmd_lock);
- mutex_init(&gus->dma_mutex);
- gus->gf1.irq = -1;
- gus->gf1.dma1 = -1;
- gus->gf1.dma2 = -1;
- gus->card = card;
- gus->gf1.port = port;
- /* fill register variables for speedup */
- gus->gf1.reg_page = GUSP(gus, GF1PAGE);
- gus->gf1.reg_regsel = GUSP(gus, GF1REGSEL);
- gus->gf1.reg_data8 = GUSP(gus, GF1DATAHIGH);
- gus->gf1.reg_data16 = GUSP(gus, GF1DATALOW);
- gus->gf1.reg_irqstat = GUSP(gus, IRQSTAT);
- gus->gf1.reg_dram = GUSP(gus, DRAM);
- gus->gf1.reg_timerctrl = GUSP(gus, TIMERCNTRL);
- gus->gf1.reg_timerdata = GUSP(gus, TIMERDATA);
- /* allocate resources */
- if ((gus->gf1.res_port1 = request_region(port, 16, "GUS GF1 (Adlib/SB)")) == NULL) {
- snd_printk(KERN_ERR "gus: can't grab SB port 0x%lx\n", port);
- snd_gus_free(gus);
- return -EBUSY;
- }
- if ((gus->gf1.res_port2 = request_region(port + 0x100, 12, "GUS GF1 (Synth)")) == NULL) {
- snd_printk(KERN_ERR "gus: can't grab synth port 0x%lx\n", port + 0x100);
- snd_gus_free(gus);
- return -EBUSY;
- }
- if (irq >= 0 && request_irq(irq, snd_gus_interrupt, 0, "GUS GF1", (void *) gus)) {
- snd_printk(KERN_ERR "gus: can't grab irq %d\n", irq);
- snd_gus_free(gus);
- return -EBUSY;
- }
- gus->gf1.irq = irq;
- if (request_dma(dma1, "GUS - 1")) {
- snd_printk(KERN_ERR "gus: can't grab DMA1 %d\n", dma1);
- snd_gus_free(gus);
- return -EBUSY;
- }
- gus->gf1.dma1 = dma1;
- if (dma2 >= 0 && dma1 != dma2) {
- if (request_dma(dma2, "GUS - 2")) {
- snd_printk(KERN_ERR "gus: can't grab DMA2 %d\n", dma2);
- snd_gus_free(gus);
- return -EBUSY;
- }
- gus->gf1.dma2 = dma2;
- } else {
- gus->gf1.dma2 = gus->gf1.dma1;
- gus->equal_dma = 1;
- }
- gus->timer_dev = timer_dev;
- if (voices < 14)
- voices = 14;
- if (voices > 32)
- voices = 32;
- if (pcm_channels < 0)
- pcm_channels = 0;
- if (pcm_channels > 8)
- pcm_channels = 8;
- pcm_channels++;
- pcm_channels &= ~1;
- gus->gf1.effect = effect ? 1 : 0;
- gus->gf1.active_voices = voices;
- gus->gf1.pcm_channels = pcm_channels;
- gus->gf1.volume_ramp = 25;
- gus->gf1.smooth_pan = 1;
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, gus, &ops)) < 0) {
- snd_gus_free(gus);
- return err;
- }
- *rgus = gus;
- return 0;
-}
-
-/*
- * Memory detection routine for plain GF1 soundcards
- */
-
-static int snd_gus_detect_memory(struct snd_gus_card * gus)
-{
- int l, idx, local;
- unsigned char d;
-
- snd_gf1_poke(gus, 0L, 0xaa);
- snd_gf1_poke(gus, 1L, 0x55);
- if (snd_gf1_peek(gus, 0L) != 0xaa || snd_gf1_peek(gus, 1L) != 0x55) {
- snd_printk(KERN_ERR "plain GF1 card at 0x%lx without onboard DRAM?\n", gus->gf1.port);
- return -ENOMEM;
- }
- for (idx = 1, d = 0xab; idx < 4; idx++, d++) {
- local = idx << 18;
- snd_gf1_poke(gus, local, d);
- snd_gf1_poke(gus, local + 1, d + 1);
- if (snd_gf1_peek(gus, local) != d ||
- snd_gf1_peek(gus, local + 1) != d + 1 ||
- snd_gf1_peek(gus, 0L) != 0xaa)
- break;
- }
-#if 1
- gus->gf1.memory = idx << 18;
-#else
- gus->gf1.memory = 256 * 1024;
-#endif
- for (l = 0, local = gus->gf1.memory; l < 4; l++, local -= 256 * 1024) {
- gus->gf1.mem_alloc.banks_8[l].address =
- gus->gf1.mem_alloc.banks_8[l].size = 0;
- gus->gf1.mem_alloc.banks_16[l].address = l << 18;
- gus->gf1.mem_alloc.banks_16[l].size = local > 0 ? 256 * 1024 : 0;
- }
- gus->gf1.mem_alloc.banks_8[0].size = gus->gf1.memory;
- return 0; /* some memory were detected */
-}
-
-static int snd_gus_init_dma_irq(struct snd_gus_card * gus, int latches)
-{
- struct snd_card *card;
- unsigned long flags;
- int irq, dma1, dma2;
- static unsigned char irqs[16] =
- {0, 0, 1, 3, 0, 2, 0, 4, 0, 1, 0, 5, 6, 0, 0, 7};
- static unsigned char dmas[8] =
- {6, 1, 0, 2, 0, 3, 4, 5};
-
- if (snd_BUG_ON(!gus))
- return -EINVAL;
- card = gus->card;
- if (snd_BUG_ON(!card))
- return -EINVAL;
-
- gus->mix_cntrl_reg &= 0xf8;
- gus->mix_cntrl_reg |= 0x01; /* disable MIC, LINE IN, enable LINE OUT */
- if (gus->codec_flag || gus->ess_flag) {
- gus->mix_cntrl_reg &= ~1; /* enable LINE IN */
- gus->mix_cntrl_reg |= 4; /* enable MIC */
- }
- dma1 = gus->gf1.dma1;
- dma1 = abs(dma1);
- dma1 = dmas[dma1 & 7];
- dma2 = gus->gf1.dma2;
- dma2 = abs(dma2);
- dma2 = dmas[dma2 & 7];
- dma1 |= gus->equal_dma ? 0x40 : (dma2 << 3);
-
- if ((dma1 & 7) == 0 || (dma2 & 7) == 0) {
- snd_printk(KERN_ERR "Error! DMA isn't defined.\n");
- return -EINVAL;
- }
- irq = gus->gf1.irq;
- irq = abs(irq);
- irq = irqs[irq & 0x0f];
- if (irq == 0) {
- snd_printk(KERN_ERR "Error! IRQ isn't defined.\n");
- return -EINVAL;
- }
- irq |= 0x40;
-#if 0
- card->mixer.mix_ctrl_reg |= 0x10;
-#endif
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- outb(5, GUSP(gus, REGCNTRLS));
- outb(gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
- outb(0x00, GUSP(gus, IRQDMACNTRLREG));
- outb(0, GUSP(gus, REGCNTRLS));
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-
- udelay(100);
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- outb(0x00 | gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
- outb(dma1, GUSP(gus, IRQDMACNTRLREG));
- if (latches) {
- outb(0x40 | gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
- outb(irq, GUSP(gus, IRQDMACNTRLREG));
- }
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-
- udelay(100);
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- outb(0x00 | gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
- outb(dma1, GUSP(gus, IRQDMACNTRLREG));
- if (latches) {
- outb(0x40 | gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
- outb(irq, GUSP(gus, IRQDMACNTRLREG));
- }
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-
- snd_gf1_delay(gus);
-
- if (latches)
- gus->mix_cntrl_reg |= 0x08; /* enable latches */
- else
- gus->mix_cntrl_reg &= ~0x08; /* disable latches */
- spin_lock_irqsave(&gus->reg_lock, flags);
- outb(gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
- outb(0, GUSP(gus, GF1PAGE));
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-
- return 0;
-}
-
-static int snd_gus_check_version(struct snd_gus_card * gus)
-{
- unsigned long flags;
- unsigned char val, rev;
- struct snd_card *card;
-
- card = gus->card;
- spin_lock_irqsave(&gus->reg_lock, flags);
- outb(0x20, GUSP(gus, REGCNTRLS));
- val = inb(GUSP(gus, REGCNTRLS));
- rev = inb(GUSP(gus, BOARDVERSION));
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- snd_printdd("GF1 [0x%lx] init - val = 0x%x, rev = 0x%x\n", gus->gf1.port, val, rev);
- strcpy(card->driver, "GUS");
- strcpy(card->longname, "Gravis UltraSound Classic (2.4)");
- if ((val != 255 && (val & 0x06)) || (rev >= 5 && rev != 255)) {
- if (rev >= 5 && rev <= 9) {
- gus->ics_flag = 1;
- if (rev == 5)
- gus->ics_flipped = 1;
- card->longname[27] = '3';
- card->longname[29] = rev == 5 ? '5' : '7';
- }
- if (rev >= 10 && rev != 255) {
- if (rev >= 10 && rev <= 11) {
- strcpy(card->driver, "GUS MAX");
- strcpy(card->longname, "Gravis UltraSound MAX");
- gus->max_flag = 1;
- } else if (rev == 0x30) {
- strcpy(card->driver, "GUS ACE");
- strcpy(card->longname, "Gravis UltraSound Ace");
- gus->ace_flag = 1;
- } else if (rev == 0x50) {
- strcpy(card->driver, "GUS Extreme");
- strcpy(card->longname, "Gravis UltraSound Extreme");
- gus->ess_flag = 1;
- } else {
- snd_printk(KERN_ERR "unknown GF1 revision number at 0x%lx - 0x%x (0x%x)\n", gus->gf1.port, rev, val);
- snd_printk(KERN_ERR " please - report to <perex@perex.cz>\n");
- }
- }
- }
- strcpy(card->shortname, card->longname);
- gus->uart_enable = 1; /* standard GUSes doesn't have midi uart trouble */
- snd_gus_init_control(gus);
- return 0;
-}
-
-int snd_gus_initialize(struct snd_gus_card *gus)
-{
- int err;
-
- if (!gus->interwave) {
- if ((err = snd_gus_check_version(gus)) < 0) {
- snd_printk(KERN_ERR "version check failed\n");
- return err;
- }
- if ((err = snd_gus_detect_memory(gus)) < 0)
- return err;
- }
- if ((err = snd_gus_init_dma_irq(gus, 1)) < 0)
- return err;
- snd_gf1_start(gus);
- gus->initialized = 1;
- return 0;
-}
-
- /* gus_io.c */
-EXPORT_SYMBOL(snd_gf1_delay);
-EXPORT_SYMBOL(snd_gf1_write8);
-EXPORT_SYMBOL(snd_gf1_look8);
-EXPORT_SYMBOL(snd_gf1_write16);
-EXPORT_SYMBOL(snd_gf1_look16);
-EXPORT_SYMBOL(snd_gf1_i_write8);
-EXPORT_SYMBOL(snd_gf1_i_look8);
-EXPORT_SYMBOL(snd_gf1_i_look16);
-EXPORT_SYMBOL(snd_gf1_dram_addr);
-EXPORT_SYMBOL(snd_gf1_write_addr);
-EXPORT_SYMBOL(snd_gf1_poke);
-EXPORT_SYMBOL(snd_gf1_peek);
- /* gus_reset.c */
-EXPORT_SYMBOL(snd_gf1_alloc_voice);
-EXPORT_SYMBOL(snd_gf1_free_voice);
-EXPORT_SYMBOL(snd_gf1_ctrl_stop);
-EXPORT_SYMBOL(snd_gf1_stop_voice);
- /* gus_mixer.c */
-EXPORT_SYMBOL(snd_gf1_new_mixer);
- /* gus_pcm.c */
-EXPORT_SYMBOL(snd_gf1_pcm_new);
- /* gus.c */
-EXPORT_SYMBOL(snd_gus_use_inc);
-EXPORT_SYMBOL(snd_gus_use_dec);
-EXPORT_SYMBOL(snd_gus_create);
-EXPORT_SYMBOL(snd_gus_initialize);
- /* gus_irq.c */
-EXPORT_SYMBOL(snd_gus_interrupt);
- /* gus_uart.c */
-EXPORT_SYMBOL(snd_gf1_rawmidi_new);
- /* gus_dram.c */
-EXPORT_SYMBOL(snd_gus_dram_write);
-EXPORT_SYMBOL(snd_gus_dram_read);
- /* gus_volume.c */
-EXPORT_SYMBOL(snd_gf1_lvol_to_gvol_raw);
-EXPORT_SYMBOL(snd_gf1_translate_freq);
- /* gus_mem.c */
-EXPORT_SYMBOL(snd_gf1_mem_alloc);
-EXPORT_SYMBOL(snd_gf1_mem_xfree);
-EXPORT_SYMBOL(snd_gf1_mem_free);
-EXPORT_SYMBOL(snd_gf1_mem_lock);
-
-/*
- * INIT part
- */
-
-static int __init alsa_gus_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_gus_exit(void)
-{
-}
-
-module_init(alsa_gus_init)
-module_exit(alsa_gus_exit)
diff --git a/ANDROID_3.4.5/sound/isa/gus/gus_mem.c b/ANDROID_3.4.5/sound/isa/gus/gus_mem.c
deleted file mode 100644
index af888a02..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/gus_mem.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * GUS's memory allocation routines / bottom layer
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <sound/core.h>
-#include <sound/gus.h>
-#include <sound/info.h>
-
-#ifdef CONFIG_SND_DEBUG
-static void snd_gf1_mem_info_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer);
-#endif
-
-void snd_gf1_mem_lock(struct snd_gf1_mem * alloc, int xup)
-{
- if (!xup) {
- mutex_lock(&alloc->memory_mutex);
- } else {
- mutex_unlock(&alloc->memory_mutex);
- }
-}
-
-static struct snd_gf1_mem_block *snd_gf1_mem_xalloc(struct snd_gf1_mem * alloc,
- struct snd_gf1_mem_block * block)
-{
- struct snd_gf1_mem_block *pblock, *nblock;
-
- nblock = kmalloc(sizeof(struct snd_gf1_mem_block), GFP_KERNEL);
- if (nblock == NULL)
- return NULL;
- *nblock = *block;
- pblock = alloc->first;
- while (pblock) {
- if (pblock->ptr > nblock->ptr) {
- nblock->prev = pblock->prev;
- nblock->next = pblock;
- pblock->prev = nblock;
- if (pblock == alloc->first)
- alloc->first = nblock;
- else
- nblock->prev->next = nblock;
- mutex_unlock(&alloc->memory_mutex);
- return NULL;
- }
- pblock = pblock->next;
- }
- nblock->next = NULL;
- if (alloc->last == NULL) {
- nblock->prev = NULL;
- alloc->first = alloc->last = nblock;
- } else {
- nblock->prev = alloc->last;
- alloc->last->next = nblock;
- alloc->last = nblock;
- }
- return nblock;
-}
-
-int snd_gf1_mem_xfree(struct snd_gf1_mem * alloc, struct snd_gf1_mem_block * block)
-{
- if (block->share) { /* ok.. shared block */
- block->share--;
- mutex_unlock(&alloc->memory_mutex);
- return 0;
- }
- if (alloc->first == block) {
- alloc->first = block->next;
- if (block->next)
- block->next->prev = NULL;
- } else {
- block->prev->next = block->next;
- if (block->next)
- block->next->prev = block->prev;
- }
- if (alloc->last == block) {
- alloc->last = block->prev;
- if (block->prev)
- block->prev->next = NULL;
- } else {
- block->next->prev = block->prev;
- if (block->prev)
- block->prev->next = block->next;
- }
- kfree(block->name);
- kfree(block);
- return 0;
-}
-
-static struct snd_gf1_mem_block *snd_gf1_mem_look(struct snd_gf1_mem * alloc,
- unsigned int address)
-{
- struct snd_gf1_mem_block *block;
-
- for (block = alloc->first; block; block = block->next) {
- if (block->ptr == address) {
- return block;
- }
- }
- return NULL;
-}
-
-static struct snd_gf1_mem_block *snd_gf1_mem_share(struct snd_gf1_mem * alloc,
- unsigned int *share_id)
-{
- struct snd_gf1_mem_block *block;
-
- if (!share_id[0] && !share_id[1] &&
- !share_id[2] && !share_id[3])
- return NULL;
- for (block = alloc->first; block; block = block->next)
- if (!memcmp(share_id, block->share_id,
- sizeof(block->share_id)))
- return block;
- return NULL;
-}
-
-static int snd_gf1_mem_find(struct snd_gf1_mem * alloc,
- struct snd_gf1_mem_block * block,
- unsigned int size, int w_16, int align)
-{
- struct snd_gf1_bank_info *info = w_16 ? alloc->banks_16 : alloc->banks_8;
- unsigned int idx, boundary;
- int size1;
- struct snd_gf1_mem_block *pblock;
- unsigned int ptr1, ptr2;
-
- if (w_16 && align < 2)
- align = 2;
- block->flags = w_16 ? SNDRV_GF1_MEM_BLOCK_16BIT : 0;
- block->owner = SNDRV_GF1_MEM_OWNER_DRIVER;
- block->share = 0;
- block->share_id[0] = block->share_id[1] =
- block->share_id[2] = block->share_id[3] = 0;
- block->name = NULL;
- block->prev = block->next = NULL;
- for (pblock = alloc->first, idx = 0; pblock; pblock = pblock->next) {
- while (pblock->ptr >= (boundary = info[idx].address + info[idx].size))
- idx++;
- while (pblock->ptr + pblock->size >= (boundary = info[idx].address + info[idx].size))
- idx++;
- ptr2 = boundary;
- if (pblock->next) {
- if (pblock->ptr + pblock->size == pblock->next->ptr)
- continue;
- if (pblock->next->ptr < boundary)
- ptr2 = pblock->next->ptr;
- }
- ptr1 = ALIGN(pblock->ptr + pblock->size, align);
- if (ptr1 >= ptr2)
- continue;
- size1 = ptr2 - ptr1;
- if ((int)size <= size1) {
- block->ptr = ptr1;
- block->size = size;
- return 0;
- }
- }
- while (++idx < 4) {
- if (size <= info[idx].size) {
- /* I assume that bank address is already aligned.. */
- block->ptr = info[idx].address;
- block->size = size;
- return 0;
- }
- }
- return -ENOMEM;
-}
-
-struct snd_gf1_mem_block *snd_gf1_mem_alloc(struct snd_gf1_mem * alloc, int owner,
- char *name, int size, int w_16, int align,
- unsigned int *share_id)
-{
- struct snd_gf1_mem_block block, *nblock;
-
- snd_gf1_mem_lock(alloc, 0);
- if (share_id != NULL) {
- nblock = snd_gf1_mem_share(alloc, share_id);
- if (nblock != NULL) {
- if (size != (int)nblock->size) {
- /* TODO: remove in the future */
- snd_printk(KERN_ERR "snd_gf1_mem_alloc - share: sizes differ\n");
- goto __std;
- }
- nblock->share++;
- snd_gf1_mem_lock(alloc, 1);
- return NULL;
- }
- }
- __std:
- if (snd_gf1_mem_find(alloc, &block, size, w_16, align) < 0) {
- snd_gf1_mem_lock(alloc, 1);
- return NULL;
- }
- if (share_id != NULL)
- memcpy(&block.share_id, share_id, sizeof(block.share_id));
- block.owner = owner;
- block.name = kstrdup(name, GFP_KERNEL);
- nblock = snd_gf1_mem_xalloc(alloc, &block);
- snd_gf1_mem_lock(alloc, 1);
- return nblock;
-}
-
-int snd_gf1_mem_free(struct snd_gf1_mem * alloc, unsigned int address)
-{
- int result;
- struct snd_gf1_mem_block *block;
-
- snd_gf1_mem_lock(alloc, 0);
- if ((block = snd_gf1_mem_look(alloc, address)) != NULL) {
- result = snd_gf1_mem_xfree(alloc, block);
- snd_gf1_mem_lock(alloc, 1);
- return result;
- }
- snd_gf1_mem_lock(alloc, 1);
- return -EINVAL;
-}
-
-int snd_gf1_mem_init(struct snd_gus_card * gus)
-{
- struct snd_gf1_mem *alloc;
- struct snd_gf1_mem_block block;
-#ifdef CONFIG_SND_DEBUG
- struct snd_info_entry *entry;
-#endif
-
- alloc = &gus->gf1.mem_alloc;
- mutex_init(&alloc->memory_mutex);
- alloc->first = alloc->last = NULL;
- if (!gus->gf1.memory)
- return 0;
-
- memset(&block, 0, sizeof(block));
- block.owner = SNDRV_GF1_MEM_OWNER_DRIVER;
- if (gus->gf1.enh_mode) {
- block.ptr = 0;
- block.size = 1024;
- block.name = kstrdup("InterWave LFOs", GFP_KERNEL);
- if (snd_gf1_mem_xalloc(alloc, &block) == NULL)
- return -ENOMEM;
- }
- block.ptr = gus->gf1.default_voice_address;
- block.size = 4;
- block.name = kstrdup("Voice default (NULL's)", GFP_KERNEL);
- if (snd_gf1_mem_xalloc(alloc, &block) == NULL)
- return -ENOMEM;
-#ifdef CONFIG_SND_DEBUG
- if (! snd_card_proc_new(gus->card, "gusmem", &entry))
- snd_info_set_text_ops(entry, gus, snd_gf1_mem_info_read);
-#endif
- return 0;
-}
-
-int snd_gf1_mem_done(struct snd_gus_card * gus)
-{
- struct snd_gf1_mem *alloc;
- struct snd_gf1_mem_block *block, *nblock;
-
- alloc = &gus->gf1.mem_alloc;
- block = alloc->first;
- while (block) {
- nblock = block->next;
- snd_gf1_mem_xfree(alloc, block);
- block = nblock;
- }
- return 0;
-}
-
-#ifdef CONFIG_SND_DEBUG
-static void snd_gf1_mem_info_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_gus_card *gus;
- struct snd_gf1_mem *alloc;
- struct snd_gf1_mem_block *block;
- unsigned int total, used;
- int i;
-
- gus = entry->private_data;
- alloc = &gus->gf1.mem_alloc;
- mutex_lock(&alloc->memory_mutex);
- snd_iprintf(buffer, "8-bit banks : \n ");
- for (i = 0; i < 4; i++)
- snd_iprintf(buffer, "0x%06x (%04ik)%s", alloc->banks_8[i].address, alloc->banks_8[i].size >> 10, i + 1 < 4 ? "," : "");
- snd_iprintf(buffer, "\n"
- "16-bit banks : \n ");
- for (i = total = 0; i < 4; i++) {
- snd_iprintf(buffer, "0x%06x (%04ik)%s", alloc->banks_16[i].address, alloc->banks_16[i].size >> 10, i + 1 < 4 ? "," : "");
- total += alloc->banks_16[i].size;
- }
- snd_iprintf(buffer, "\n");
- used = 0;
- for (block = alloc->first, i = 0; block; block = block->next, i++) {
- used += block->size;
- snd_iprintf(buffer, "Block %i at 0x%lx onboard 0x%x size %i (0x%x):\n", i, (long) block, block->ptr, block->size, block->size);
- if (block->share ||
- block->share_id[0] || block->share_id[1] ||
- block->share_id[2] || block->share_id[3])
- snd_iprintf(buffer, " Share : %i [id0 0x%x] [id1 0x%x] [id2 0x%x] [id3 0x%x]\n",
- block->share,
- block->share_id[0], block->share_id[1],
- block->share_id[2], block->share_id[3]);
- snd_iprintf(buffer, " Flags :%s\n",
- block->flags & SNDRV_GF1_MEM_BLOCK_16BIT ? " 16-bit" : "");
- snd_iprintf(buffer, " Owner : ");
- switch (block->owner) {
- case SNDRV_GF1_MEM_OWNER_DRIVER:
- snd_iprintf(buffer, "driver - %s\n", block->name);
- break;
- case SNDRV_GF1_MEM_OWNER_WAVE_SIMPLE:
- snd_iprintf(buffer, "SIMPLE wave\n");
- break;
- case SNDRV_GF1_MEM_OWNER_WAVE_GF1:
- snd_iprintf(buffer, "GF1 wave\n");
- break;
- case SNDRV_GF1_MEM_OWNER_WAVE_IWFFFF:
- snd_iprintf(buffer, "IWFFFF wave\n");
- break;
- default:
- snd_iprintf(buffer, "unknown\n");
- }
- }
- snd_iprintf(buffer, " Total: memory = %i, used = %i, free = %i\n",
- total, used, total - used);
- mutex_unlock(&alloc->memory_mutex);
-#if 0
- ultra_iprintf(buffer, " Verify: free = %i, max 8-bit block = %i, max 16-bit block = %i\n",
- ultra_memory_free_size(card, &card->gf1.mem_alloc),
- ultra_memory_free_block(card, &card->gf1.mem_alloc, 0),
- ultra_memory_free_block(card, &card->gf1.mem_alloc, 1));
-#endif
-}
-#endif
diff --git a/ANDROID_3.4.5/sound/isa/gus/gus_mem_proc.c b/ANDROID_3.4.5/sound/isa/gus/gus_mem_proc.c
deleted file mode 100644
index 2ccb3fad..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/gus_mem_proc.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * GUS's memory access via proc filesystem
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/gus.h>
-#include <sound/info.h>
-
-struct gus_proc_private {
- int rom; /* data are in ROM */
- unsigned int address;
- unsigned int size;
- struct snd_gus_card * gus;
-};
-
-static ssize_t snd_gf1_mem_proc_dump(struct snd_info_entry *entry,
- void *file_private_data,
- struct file *file, char __user *buf,
- size_t count, loff_t pos)
-{
- struct gus_proc_private *priv = entry->private_data;
- struct snd_gus_card *gus = priv->gus;
- int err;
-
- err = snd_gus_dram_read(gus, buf, pos, count, priv->rom);
- if (err < 0)
- return err;
- return count;
-}
-
-static void snd_gf1_mem_proc_free(struct snd_info_entry *entry)
-{
- struct gus_proc_private *priv = entry->private_data;
- kfree(priv);
-}
-
-static struct snd_info_entry_ops snd_gf1_mem_proc_ops = {
- .read = snd_gf1_mem_proc_dump,
-};
-
-int snd_gf1_mem_proc_init(struct snd_gus_card * gus)
-{
- int idx;
- char name[16];
- struct gus_proc_private *priv;
- struct snd_info_entry *entry;
-
- for (idx = 0; idx < 4; idx++) {
- if (gus->gf1.mem_alloc.banks_8[idx].size > 0) {
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (priv == NULL)
- return -ENOMEM;
- priv->gus = gus;
- sprintf(name, "gus-ram-%i", idx);
- if (! snd_card_proc_new(gus->card, name, &entry)) {
- entry->content = SNDRV_INFO_CONTENT_DATA;
- entry->private_data = priv;
- entry->private_free = snd_gf1_mem_proc_free;
- entry->c.ops = &snd_gf1_mem_proc_ops;
- priv->address = gus->gf1.mem_alloc.banks_8[idx].address;
- priv->size = entry->size = gus->gf1.mem_alloc.banks_8[idx].size;
- }
- }
- }
- for (idx = 0; idx < 4; idx++) {
- if (gus->gf1.rom_present & (1 << idx)) {
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (priv == NULL)
- return -ENOMEM;
- priv->rom = 1;
- priv->gus = gus;
- sprintf(name, "gus-rom-%i", idx);
- if (! snd_card_proc_new(gus->card, name, &entry)) {
- entry->content = SNDRV_INFO_CONTENT_DATA;
- entry->private_data = priv;
- entry->private_free = snd_gf1_mem_proc_free;
- entry->c.ops = &snd_gf1_mem_proc_ops;
- priv->address = idx * 4096 * 1024;
- priv->size = entry->size = gus->gf1.rom_memory;
- }
- }
- }
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/isa/gus/gus_mixer.c b/ANDROID_3.4.5/sound/isa/gus/gus_mixer.c
deleted file mode 100644
index 0dd43414..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/gus_mixer.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Routines for control of ICS 2101 chip and "mixer" in GF1 chip
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/gus.h>
-
-/*
- *
- */
-
-#define GF1_SINGLE(xname, xindex, shift, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_gf1_info_single, \
- .get = snd_gf1_get_single, .put = snd_gf1_put_single, \
- .private_value = shift | (invert << 8) }
-
-#define snd_gf1_info_single snd_ctl_boolean_mono_info
-
-static int snd_gf1_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
- int shift = kcontrol->private_value & 0xff;
- int invert = (kcontrol->private_value >> 8) & 1;
-
- ucontrol->value.integer.value[0] = (gus->mix_cntrl_reg >> shift) & 1;
- if (invert)
- ucontrol->value.integer.value[0] ^= 1;
- return 0;
-}
-
-static int snd_gf1_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int shift = kcontrol->private_value & 0xff;
- int invert = (kcontrol->private_value >> 8) & 1;
- int change;
- unsigned char oval, nval;
-
- nval = ucontrol->value.integer.value[0] & 1;
- if (invert)
- nval ^= 1;
- nval <<= shift;
- spin_lock_irqsave(&gus->reg_lock, flags);
- oval = gus->mix_cntrl_reg;
- nval = (oval & ~(1 << shift)) | nval;
- change = nval != oval;
- outb(gus->mix_cntrl_reg = nval, GUSP(gus, MIXCNTRLREG));
- outb(gus->gf1.active_voice = 0, GUSP(gus, GF1PAGE));
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- return change;
-}
-
-#define ICS_DOUBLE(xname, xindex, addr) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_ics_info_double, \
- .get = snd_ics_get_double, .put = snd_ics_put_double, \
- .private_value = addr }
-
-static int snd_ics_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 127;
- return 0;
-}
-
-static int snd_ics_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int addr = kcontrol->private_value & 0xff;
- unsigned char left, right;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- left = gus->gf1.ics_regs[addr][0];
- right = gus->gf1.ics_regs[addr][1];
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- ucontrol->value.integer.value[0] = left & 127;
- ucontrol->value.integer.value[1] = right & 127;
- return 0;
-}
-
-static int snd_ics_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int addr = kcontrol->private_value & 0xff;
- int change;
- unsigned char val1, val2, oval1, oval2, tmp;
-
- val1 = ucontrol->value.integer.value[0] & 127;
- val2 = ucontrol->value.integer.value[1] & 127;
- spin_lock_irqsave(&gus->reg_lock, flags);
- oval1 = gus->gf1.ics_regs[addr][0];
- oval2 = gus->gf1.ics_regs[addr][1];
- change = val1 != oval1 || val2 != oval2;
- gus->gf1.ics_regs[addr][0] = val1;
- gus->gf1.ics_regs[addr][1] = val2;
- if (gus->ics_flag && gus->ics_flipped &&
- (addr == SNDRV_ICS_GF1_DEV || addr == SNDRV_ICS_MASTER_DEV)) {
- tmp = val1;
- val1 = val2;
- val2 = tmp;
- }
- addr <<= 3;
- outb(addr | 0, GUSP(gus, MIXCNTRLPORT));
- outb(1, GUSP(gus, MIXDATAPORT));
- outb(addr | 2, GUSP(gus, MIXCNTRLPORT));
- outb((unsigned char) val1, GUSP(gus, MIXDATAPORT));
- outb(addr | 1, GUSP(gus, MIXCNTRLPORT));
- outb(2, GUSP(gus, MIXDATAPORT));
- outb(addr | 3, GUSP(gus, MIXCNTRLPORT));
- outb((unsigned char) val2, GUSP(gus, MIXDATAPORT));
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- return change;
-}
-
-static struct snd_kcontrol_new snd_gf1_controls[] = {
-GF1_SINGLE("Master Playback Switch", 0, 1, 1),
-GF1_SINGLE("Line Switch", 0, 0, 1),
-GF1_SINGLE("Mic Switch", 0, 2, 0)
-};
-
-static struct snd_kcontrol_new snd_ics_controls[] = {
-GF1_SINGLE("Master Playback Switch", 0, 1, 1),
-ICS_DOUBLE("Master Playback Volume", 0, SNDRV_ICS_MASTER_DEV),
-ICS_DOUBLE("Synth Playback Volume", 0, SNDRV_ICS_GF1_DEV),
-GF1_SINGLE("Line Switch", 0, 0, 1),
-ICS_DOUBLE("Line Playback Volume", 0, SNDRV_ICS_LINE_DEV),
-GF1_SINGLE("Mic Switch", 0, 2, 0),
-ICS_DOUBLE("Mic Playback Volume", 0, SNDRV_ICS_MIC_DEV),
-ICS_DOUBLE("CD Playback Volume", 0, SNDRV_ICS_CD_DEV)
-};
-
-int snd_gf1_new_mixer(struct snd_gus_card * gus)
-{
- struct snd_card *card;
- unsigned int idx, max;
- int err;
-
- if (snd_BUG_ON(!gus))
- return -EINVAL;
- card = gus->card;
- if (snd_BUG_ON(!card))
- return -EINVAL;
-
- if (gus->ics_flag)
- snd_component_add(card, "ICS2101");
- if (card->mixername[0] == '\0') {
- strcpy(card->mixername, gus->ics_flag ? "GF1,ICS2101" : "GF1");
- } else {
- if (gus->ics_flag)
- strcat(card->mixername, ",ICS2101");
- strcat(card->mixername, ",GF1");
- }
-
- if (!gus->ics_flag) {
- max = gus->ess_flag ? 1 : ARRAY_SIZE(snd_gf1_controls);
- for (idx = 0; idx < max; idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_gf1_controls[idx], gus))) < 0)
- return err;
- }
- } else {
- for (idx = 0; idx < ARRAY_SIZE(snd_ics_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_ics_controls[idx], gus))) < 0)
- return err;
- }
- }
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/isa/gus/gus_pcm.c b/ANDROID_3.4.5/sound/isa/gus/gus_pcm.c
deleted file mode 100644
index 2dcf45bf..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/gus_pcm.c
+++ /dev/null
@@ -1,910 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Routines for control of GF1 chip (PCM things)
- *
- * InterWave chips supports interleaved DMA, but this feature isn't used in
- * this code.
- *
- * This code emulates autoinit DMA transfer for playback, recording by GF1
- * chip doesn't support autoinit DMA.
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/dma.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/gus.h>
-#include <sound/pcm_params.h>
-#include "gus_tables.h"
-
-/* maximum rate */
-
-#define SNDRV_GF1_PCM_RATE 48000
-
-#define SNDRV_GF1_PCM_PFLG_NONE 0
-#define SNDRV_GF1_PCM_PFLG_ACTIVE (1<<0)
-#define SNDRV_GF1_PCM_PFLG_NEUTRAL (2<<0)
-
-struct gus_pcm_private {
- struct snd_gus_card * gus;
- struct snd_pcm_substream *substream;
- spinlock_t lock;
- unsigned int voices;
- struct snd_gus_voice *pvoices[2];
- unsigned int memory;
- unsigned short flags;
- unsigned char voice_ctrl, ramp_ctrl;
- unsigned int bpos;
- unsigned int blocks;
- unsigned int block_size;
- unsigned int dma_size;
- wait_queue_head_t sleep;
- atomic_t dma_count;
- int final_volume;
-};
-
-static int snd_gf1_pcm_use_dma = 1;
-
-static void snd_gf1_pcm_block_change_ack(struct snd_gus_card * gus, void *private_data)
-{
- struct gus_pcm_private *pcmp = private_data;
-
- if (pcmp) {
- atomic_dec(&pcmp->dma_count);
- wake_up(&pcmp->sleep);
- }
-}
-
-static int snd_gf1_pcm_block_change(struct snd_pcm_substream *substream,
- unsigned int offset,
- unsigned int addr,
- unsigned int count)
-{
- struct snd_gf1_dma_block block;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct gus_pcm_private *pcmp = runtime->private_data;
-
- count += offset & 31;
- offset &= ~31;
- /*
- snd_printk(KERN_DEBUG "block change - offset = 0x%x, count = 0x%x\n",
- offset, count);
- */
- memset(&block, 0, sizeof(block));
- block.cmd = SNDRV_GF1_DMA_IRQ;
- if (snd_pcm_format_unsigned(runtime->format))
- block.cmd |= SNDRV_GF1_DMA_UNSIGNED;
- if (snd_pcm_format_width(runtime->format) == 16)
- block.cmd |= SNDRV_GF1_DMA_16BIT;
- block.addr = addr & ~31;
- block.buffer = runtime->dma_area + offset;
- block.buf_addr = runtime->dma_addr + offset;
- block.count = count;
- block.private_data = pcmp;
- block.ack = snd_gf1_pcm_block_change_ack;
- if (!snd_gf1_dma_transfer_block(pcmp->gus, &block, 0, 0))
- atomic_inc(&pcmp->dma_count);
- return 0;
-}
-
-static void snd_gf1_pcm_trigger_up(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct gus_pcm_private *pcmp = runtime->private_data;
- struct snd_gus_card * gus = pcmp->gus;
- unsigned long flags;
- unsigned char voice_ctrl, ramp_ctrl;
- unsigned short rate;
- unsigned int curr, begin, end;
- unsigned short vol;
- unsigned char pan;
- unsigned int voice;
-
- spin_lock_irqsave(&pcmp->lock, flags);
- if (pcmp->flags & SNDRV_GF1_PCM_PFLG_ACTIVE) {
- spin_unlock_irqrestore(&pcmp->lock, flags);
- return;
- }
- pcmp->flags |= SNDRV_GF1_PCM_PFLG_ACTIVE;
- pcmp->final_volume = 0;
- spin_unlock_irqrestore(&pcmp->lock, flags);
- rate = snd_gf1_translate_freq(gus, runtime->rate << 4);
- /* enable WAVE IRQ */
- voice_ctrl = snd_pcm_format_width(runtime->format) == 16 ? 0x24 : 0x20;
- /* enable RAMP IRQ + rollover */
- ramp_ctrl = 0x24;
- if (pcmp->blocks == 1) {
- voice_ctrl |= 0x08; /* loop enable */
- ramp_ctrl &= ~0x04; /* disable rollover */
- }
- for (voice = 0; voice < pcmp->voices; voice++) {
- begin = pcmp->memory + voice * (pcmp->dma_size / runtime->channels);
- curr = begin + (pcmp->bpos * pcmp->block_size) / runtime->channels;
- end = curr + (pcmp->block_size / runtime->channels);
- end -= snd_pcm_format_width(runtime->format) == 16 ? 2 : 1;
- /*
- snd_printk(KERN_DEBUG "init: curr=0x%x, begin=0x%x, end=0x%x, "
- "ctrl=0x%x, ramp=0x%x, rate=0x%x\n",
- curr, begin, end, voice_ctrl, ramp_ctrl, rate);
- */
- pan = runtime->channels == 2 ? (!voice ? 1 : 14) : 8;
- vol = !voice ? gus->gf1.pcm_volume_level_left : gus->gf1.pcm_volume_level_right;
- spin_lock_irqsave(&gus->reg_lock, flags);
- snd_gf1_select_voice(gus, pcmp->pvoices[voice]->number);
- snd_gf1_write8(gus, SNDRV_GF1_VB_PAN, pan);
- snd_gf1_write16(gus, SNDRV_GF1_VW_FREQUENCY, rate);
- snd_gf1_write_addr(gus, SNDRV_GF1_VA_START, begin << 4, voice_ctrl & 4);
- snd_gf1_write_addr(gus, SNDRV_GF1_VA_END, end << 4, voice_ctrl & 4);
- snd_gf1_write_addr(gus, SNDRV_GF1_VA_CURRENT, curr << 4, voice_ctrl & 4);
- snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, SNDRV_GF1_MIN_VOLUME << 4);
- snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_RATE, 0x2f);
- snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_START, SNDRV_GF1_MIN_OFFSET);
- snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_END, vol >> 8);
- snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, ramp_ctrl);
- if (!gus->gf1.enh_mode) {
- snd_gf1_delay(gus);
- snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, ramp_ctrl);
- }
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- }
- spin_lock_irqsave(&gus->reg_lock, flags);
- for (voice = 0; voice < pcmp->voices; voice++) {
- snd_gf1_select_voice(gus, pcmp->pvoices[voice]->number);
- if (gus->gf1.enh_mode)
- snd_gf1_write8(gus, SNDRV_GF1_VB_MODE, 0x00); /* deactivate voice */
- snd_gf1_write8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL, voice_ctrl);
- voice_ctrl &= ~0x20;
- }
- voice_ctrl |= 0x20;
- if (!gus->gf1.enh_mode) {
- snd_gf1_delay(gus);
- for (voice = 0; voice < pcmp->voices; voice++) {
- snd_gf1_select_voice(gus, pcmp->pvoices[voice]->number);
- snd_gf1_write8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL, voice_ctrl);
- voice_ctrl &= ~0x20; /* disable IRQ for next voice */
- }
- }
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-}
-
-static void snd_gf1_pcm_interrupt_wave(struct snd_gus_card * gus,
- struct snd_gus_voice *pvoice)
-{
- struct gus_pcm_private * pcmp;
- struct snd_pcm_runtime *runtime;
- unsigned char voice_ctrl, ramp_ctrl;
- unsigned int idx;
- unsigned int end, step;
-
- if (!pvoice->private_data) {
- snd_printd("snd_gf1_pcm: unknown wave irq?\n");
- snd_gf1_smart_stop_voice(gus, pvoice->number);
- return;
- }
- pcmp = pvoice->private_data;
- if (pcmp == NULL) {
- snd_printd("snd_gf1_pcm: unknown wave irq?\n");
- snd_gf1_smart_stop_voice(gus, pvoice->number);
- return;
- }
- gus = pcmp->gus;
- runtime = pcmp->substream->runtime;
-
- spin_lock(&gus->reg_lock);
- snd_gf1_select_voice(gus, pvoice->number);
- voice_ctrl = snd_gf1_read8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL) & ~0x8b;
- ramp_ctrl = (snd_gf1_read8(gus, SNDRV_GF1_VB_VOLUME_CONTROL) & ~0xa4) | 0x03;
-#if 0
- snd_gf1_select_voice(gus, pvoice->number);
- printk(KERN_DEBUG "position = 0x%x\n",
- (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4));
- snd_gf1_select_voice(gus, pcmp->pvoices[1]->number);
- printk(KERN_DEBUG "position = 0x%x\n",
- (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4));
- snd_gf1_select_voice(gus, pvoice->number);
-#endif
- pcmp->bpos++;
- pcmp->bpos %= pcmp->blocks;
- if (pcmp->bpos + 1 >= pcmp->blocks) { /* last block? */
- voice_ctrl |= 0x08; /* enable loop */
- } else {
- ramp_ctrl |= 0x04; /* enable rollover */
- }
- end = pcmp->memory + (((pcmp->bpos + 1) * pcmp->block_size) / runtime->channels);
- end -= voice_ctrl & 4 ? 2 : 1;
- step = pcmp->dma_size / runtime->channels;
- voice_ctrl |= 0x20;
- if (!pcmp->final_volume) {
- ramp_ctrl |= 0x20;
- ramp_ctrl &= ~0x03;
- }
- for (idx = 0; idx < pcmp->voices; idx++, end += step) {
- snd_gf1_select_voice(gus, pcmp->pvoices[idx]->number);
- snd_gf1_write_addr(gus, SNDRV_GF1_VA_END, end << 4, voice_ctrl & 4);
- snd_gf1_write8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL, voice_ctrl);
- snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, ramp_ctrl);
- voice_ctrl &= ~0x20;
- }
- if (!gus->gf1.enh_mode) {
- snd_gf1_delay(gus);
- voice_ctrl |= 0x20;
- for (idx = 0; idx < pcmp->voices; idx++) {
- snd_gf1_select_voice(gus, pcmp->pvoices[idx]->number);
- snd_gf1_write8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL, voice_ctrl);
- snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, ramp_ctrl);
- voice_ctrl &= ~0x20;
- }
- }
- spin_unlock(&gus->reg_lock);
-
- snd_pcm_period_elapsed(pcmp->substream);
-#if 0
- if ((runtime->flags & SNDRV_PCM_FLG_MMAP) &&
- *runtime->state == SNDRV_PCM_STATE_RUNNING) {
- end = pcmp->bpos * pcmp->block_size;
- if (runtime->channels > 1) {
- snd_gf1_pcm_block_change(pcmp->substream, end, pcmp->memory + (end / 2), pcmp->block_size / 2);
- snd_gf1_pcm_block_change(pcmp->substream, end + (pcmp->block_size / 2), pcmp->memory + (pcmp->dma_size / 2) + (end / 2), pcmp->block_size / 2);
- } else {
- snd_gf1_pcm_block_change(pcmp->substream, end, pcmp->memory + end, pcmp->block_size);
- }
- }
-#endif
-}
-
-static void snd_gf1_pcm_interrupt_volume(struct snd_gus_card * gus,
- struct snd_gus_voice * pvoice)
-{
- unsigned short vol;
- int cvoice;
- struct gus_pcm_private *pcmp = pvoice->private_data;
-
- /* stop ramp, but leave rollover bit untouched */
- spin_lock(&gus->reg_lock);
- snd_gf1_select_voice(gus, pvoice->number);
- snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
- spin_unlock(&gus->reg_lock);
- if (pcmp == NULL)
- return;
- /* are we active? */
- if (!(pcmp->flags & SNDRV_GF1_PCM_PFLG_ACTIVE))
- return;
- /* load real volume - better precision */
- cvoice = pcmp->pvoices[0] == pvoice ? 0 : 1;
- if (pcmp->substream == NULL)
- return;
- vol = !cvoice ? gus->gf1.pcm_volume_level_left : gus->gf1.pcm_volume_level_right;
- spin_lock(&gus->reg_lock);
- snd_gf1_select_voice(gus, pvoice->number);
- snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, vol);
- pcmp->final_volume = 1;
- spin_unlock(&gus->reg_lock);
-}
-
-static void snd_gf1_pcm_volume_change(struct snd_gus_card * gus)
-{
-}
-
-static int snd_gf1_pcm_poke_block(struct snd_gus_card *gus, unsigned char *buf,
- unsigned int pos, unsigned int count,
- int w16, int invert)
-{
- unsigned int len;
- unsigned long flags;
-
- /*
- printk(KERN_DEBUG
- "poke block; buf = 0x%x, pos = %i, count = %i, port = 0x%x\n",
- (int)buf, pos, count, gus->gf1.port);
- */
- while (count > 0) {
- len = count;
- if (len > 512) /* limit, to allow IRQ */
- len = 512;
- count -= len;
- if (gus->interwave) {
- spin_lock_irqsave(&gus->reg_lock, flags);
- snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01 | (invert ? 0x08 : 0x00));
- snd_gf1_dram_addr(gus, pos);
- if (w16) {
- outb(SNDRV_GF1_GW_DRAM_IO16, GUSP(gus, GF1REGSEL));
- outsw(GUSP(gus, GF1DATALOW), buf, len >> 1);
- } else {
- outsb(GUSP(gus, DRAM), buf, len);
- }
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- buf += 512;
- pos += 512;
- } else {
- invert = invert ? 0x80 : 0x00;
- if (w16) {
- len >>= 1;
- while (len--) {
- snd_gf1_poke(gus, pos++, *buf++);
- snd_gf1_poke(gus, pos++, *buf++ ^ invert);
- }
- } else {
- while (len--)
- snd_gf1_poke(gus, pos++, *buf++ ^ invert);
- }
- }
- if (count > 0 && !in_interrupt()) {
- schedule_timeout_interruptible(1);
- if (signal_pending(current))
- return -EAGAIN;
- }
- }
- return 0;
-}
-
-static int snd_gf1_pcm_playback_copy(struct snd_pcm_substream *substream,
- int voice,
- snd_pcm_uframes_t pos,
- void __user *src,
- snd_pcm_uframes_t count)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct gus_pcm_private *pcmp = runtime->private_data;
- unsigned int bpos, len;
-
- bpos = samples_to_bytes(runtime, pos) + (voice * (pcmp->dma_size / 2));
- len = samples_to_bytes(runtime, count);
- if (snd_BUG_ON(bpos > pcmp->dma_size))
- return -EIO;
- if (snd_BUG_ON(bpos + len > pcmp->dma_size))
- return -EIO;
- if (copy_from_user(runtime->dma_area + bpos, src, len))
- return -EFAULT;
- if (snd_gf1_pcm_use_dma && len > 32) {
- return snd_gf1_pcm_block_change(substream, bpos, pcmp->memory + bpos, len);
- } else {
- struct snd_gus_card *gus = pcmp->gus;
- int err, w16, invert;
-
- w16 = (snd_pcm_format_width(runtime->format) == 16);
- invert = snd_pcm_format_unsigned(runtime->format);
- if ((err = snd_gf1_pcm_poke_block(gus, runtime->dma_area + bpos, pcmp->memory + bpos, len, w16, invert)) < 0)
- return err;
- }
- return 0;
-}
-
-static int snd_gf1_pcm_playback_silence(struct snd_pcm_substream *substream,
- int voice,
- snd_pcm_uframes_t pos,
- snd_pcm_uframes_t count)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct gus_pcm_private *pcmp = runtime->private_data;
- unsigned int bpos, len;
-
- bpos = samples_to_bytes(runtime, pos) + (voice * (pcmp->dma_size / 2));
- len = samples_to_bytes(runtime, count);
- if (snd_BUG_ON(bpos > pcmp->dma_size))
- return -EIO;
- if (snd_BUG_ON(bpos + len > pcmp->dma_size))
- return -EIO;
- snd_pcm_format_set_silence(runtime->format, runtime->dma_area + bpos, count);
- if (snd_gf1_pcm_use_dma && len > 32) {
- return snd_gf1_pcm_block_change(substream, bpos, pcmp->memory + bpos, len);
- } else {
- struct snd_gus_card *gus = pcmp->gus;
- int err, w16, invert;
-
- w16 = (snd_pcm_format_width(runtime->format) == 16);
- invert = snd_pcm_format_unsigned(runtime->format);
- if ((err = snd_gf1_pcm_poke_block(gus, runtime->dma_area + bpos, pcmp->memory + bpos, len, w16, invert)) < 0)
- return err;
- }
- return 0;
-}
-
-static int snd_gf1_pcm_playback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct gus_pcm_private *pcmp = runtime->private_data;
- int err;
-
- if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
- return err;
- if (err > 0) { /* change */
- struct snd_gf1_mem_block *block;
- if (pcmp->memory > 0) {
- snd_gf1_mem_free(&gus->gf1.mem_alloc, pcmp->memory);
- pcmp->memory = 0;
- }
- if ((block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc,
- SNDRV_GF1_MEM_OWNER_DRIVER,
- "GF1 PCM",
- runtime->dma_bytes, 1, 32,
- NULL)) == NULL)
- return -ENOMEM;
- pcmp->memory = block->ptr;
- }
- pcmp->voices = params_channels(hw_params);
- if (pcmp->pvoices[0] == NULL) {
- if ((pcmp->pvoices[0] = snd_gf1_alloc_voice(pcmp->gus, SNDRV_GF1_VOICE_TYPE_PCM, 0, 0)) == NULL)
- return -ENOMEM;
- pcmp->pvoices[0]->handler_wave = snd_gf1_pcm_interrupt_wave;
- pcmp->pvoices[0]->handler_volume = snd_gf1_pcm_interrupt_volume;
- pcmp->pvoices[0]->volume_change = snd_gf1_pcm_volume_change;
- pcmp->pvoices[0]->private_data = pcmp;
- }
- if (pcmp->voices > 1 && pcmp->pvoices[1] == NULL) {
- if ((pcmp->pvoices[1] = snd_gf1_alloc_voice(pcmp->gus, SNDRV_GF1_VOICE_TYPE_PCM, 0, 0)) == NULL)
- return -ENOMEM;
- pcmp->pvoices[1]->handler_wave = snd_gf1_pcm_interrupt_wave;
- pcmp->pvoices[1]->handler_volume = snd_gf1_pcm_interrupt_volume;
- pcmp->pvoices[1]->volume_change = snd_gf1_pcm_volume_change;
- pcmp->pvoices[1]->private_data = pcmp;
- } else if (pcmp->voices == 1) {
- if (pcmp->pvoices[1]) {
- snd_gf1_free_voice(pcmp->gus, pcmp->pvoices[1]);
- pcmp->pvoices[1] = NULL;
- }
- }
- return 0;
-}
-
-static int snd_gf1_pcm_playback_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct gus_pcm_private *pcmp = runtime->private_data;
-
- snd_pcm_lib_free_pages(substream);
- if (pcmp->pvoices[0]) {
- snd_gf1_free_voice(pcmp->gus, pcmp->pvoices[0]);
- pcmp->pvoices[0] = NULL;
- }
- if (pcmp->pvoices[1]) {
- snd_gf1_free_voice(pcmp->gus, pcmp->pvoices[1]);
- pcmp->pvoices[1] = NULL;
- }
- if (pcmp->memory > 0) {
- snd_gf1_mem_free(&pcmp->gus->gf1.mem_alloc, pcmp->memory);
- pcmp->memory = 0;
- }
- return 0;
-}
-
-static int snd_gf1_pcm_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct gus_pcm_private *pcmp = runtime->private_data;
-
- pcmp->bpos = 0;
- pcmp->dma_size = snd_pcm_lib_buffer_bytes(substream);
- pcmp->block_size = snd_pcm_lib_period_bytes(substream);
- pcmp->blocks = pcmp->dma_size / pcmp->block_size;
- return 0;
-}
-
-static int snd_gf1_pcm_playback_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct gus_pcm_private *pcmp = runtime->private_data;
- int voice;
-
- if (cmd == SNDRV_PCM_TRIGGER_START) {
- snd_gf1_pcm_trigger_up(substream);
- } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
- spin_lock(&pcmp->lock);
- pcmp->flags &= ~SNDRV_GF1_PCM_PFLG_ACTIVE;
- spin_unlock(&pcmp->lock);
- voice = pcmp->pvoices[0]->number;
- snd_gf1_stop_voices(gus, voice, voice);
- if (pcmp->pvoices[1]) {
- voice = pcmp->pvoices[1]->number;
- snd_gf1_stop_voices(gus, voice, voice);
- }
- } else {
- return -EINVAL;
- }
- return 0;
-}
-
-static snd_pcm_uframes_t snd_gf1_pcm_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct gus_pcm_private *pcmp = runtime->private_data;
- unsigned int pos;
- unsigned char voice_ctrl;
-
- pos = 0;
- spin_lock(&gus->reg_lock);
- if (pcmp->flags & SNDRV_GF1_PCM_PFLG_ACTIVE) {
- snd_gf1_select_voice(gus, pcmp->pvoices[0]->number);
- voice_ctrl = snd_gf1_read8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL);
- pos = (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4) - pcmp->memory;
- if (substream->runtime->channels > 1)
- pos <<= 1;
- pos = bytes_to_frames(runtime, pos);
- }
- spin_unlock(&gus->reg_lock);
- return pos;
-}
-
-static struct snd_ratnum clock = {
- .num = 9878400/16,
- .den_min = 2,
- .den_max = 257,
- .den_step = 1,
-};
-
-static struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks = {
- .nrats = 1,
- .rats = &clock,
-};
-
-static int snd_gf1_pcm_capture_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
-
- gus->c_dma_size = params_buffer_bytes(hw_params);
- gus->c_period_size = params_period_bytes(hw_params);
- gus->c_pos = 0;
- gus->gf1.pcm_rcntrl_reg = 0x21; /* IRQ at end, enable & start */
- if (params_channels(hw_params) > 1)
- gus->gf1.pcm_rcntrl_reg |= 2;
- if (gus->gf1.dma2 > 3)
- gus->gf1.pcm_rcntrl_reg |= 4;
- if (snd_pcm_format_unsigned(params_format(hw_params)))
- gus->gf1.pcm_rcntrl_reg |= 0x80;
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static int snd_gf1_pcm_capture_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_gf1_pcm_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_RECORD_RATE, runtime->rate_den - 2);
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL, 0); /* disable sampling */
- snd_gf1_i_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL); /* Sampling Control Register */
- snd_dma_program(gus->gf1.dma2, runtime->dma_addr, gus->c_period_size, DMA_MODE_READ);
- return 0;
-}
-
-static int snd_gf1_pcm_capture_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
- int val;
-
- if (cmd == SNDRV_PCM_TRIGGER_START) {
- val = gus->gf1.pcm_rcntrl_reg;
- } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
- val = 0;
- } else {
- return -EINVAL;
- }
-
- spin_lock(&gus->reg_lock);
- snd_gf1_write8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL, val);
- snd_gf1_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL);
- spin_unlock(&gus->reg_lock);
- return 0;
-}
-
-static snd_pcm_uframes_t snd_gf1_pcm_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
- int pos = snd_dma_pointer(gus->gf1.dma2, gus->c_period_size);
- pos = bytes_to_frames(substream->runtime, (gus->c_pos + pos) % gus->c_dma_size);
- return pos;
-}
-
-static void snd_gf1_pcm_interrupt_dma_read(struct snd_gus_card * gus)
-{
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL, 0); /* disable sampling */
- snd_gf1_i_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL); /* Sampling Control Register */
- if (gus->pcm_cap_substream != NULL) {
- snd_gf1_pcm_capture_prepare(gus->pcm_cap_substream);
- snd_gf1_pcm_capture_trigger(gus->pcm_cap_substream, SNDRV_PCM_TRIGGER_START);
- gus->c_pos += gus->c_period_size;
- snd_pcm_period_elapsed(gus->pcm_cap_substream);
- }
-}
-
-static struct snd_pcm_hardware snd_gf1_pcm_playback =
-{
- .info = SNDRV_PCM_INFO_NONINTERLEAVED,
- .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 5510,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_gf1_pcm_capture =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_44100,
- .rate_min = 5510,
- .rate_max = 44100,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static void snd_gf1_pcm_playback_free(struct snd_pcm_runtime *runtime)
-{
- kfree(runtime->private_data);
-}
-
-static int snd_gf1_pcm_playback_open(struct snd_pcm_substream *substream)
-{
- struct gus_pcm_private *pcmp;
- struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- pcmp = kzalloc(sizeof(*pcmp), GFP_KERNEL);
- if (pcmp == NULL)
- return -ENOMEM;
- pcmp->gus = gus;
- spin_lock_init(&pcmp->lock);
- init_waitqueue_head(&pcmp->sleep);
- atomic_set(&pcmp->dma_count, 0);
-
- runtime->private_data = pcmp;
- runtime->private_free = snd_gf1_pcm_playback_free;
-
-#if 0
- printk(KERN_DEBUG "playback.buffer = 0x%lx, gf1.pcm_buffer = 0x%lx\n",
- (long) pcm->playback.buffer, (long) gus->gf1.pcm_buffer);
-#endif
- if ((err = snd_gf1_dma_init(gus)) < 0)
- return err;
- pcmp->flags = SNDRV_GF1_PCM_PFLG_NONE;
- pcmp->substream = substream;
- runtime->hw = snd_gf1_pcm_playback;
- snd_pcm_limit_isa_dma_size(gus->gf1.dma1, &runtime->hw.buffer_bytes_max);
- snd_pcm_limit_isa_dma_size(gus->gf1.dma1, &runtime->hw.period_bytes_max);
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64);
- return 0;
-}
-
-static int snd_gf1_pcm_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct gus_pcm_private *pcmp = runtime->private_data;
-
- if (!wait_event_timeout(pcmp->sleep, (atomic_read(&pcmp->dma_count) <= 0), 2*HZ))
- snd_printk(KERN_ERR "gf1 pcm - serious DMA problem\n");
-
- snd_gf1_dma_done(gus);
- return 0;
-}
-
-static int snd_gf1_pcm_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
-
- gus->gf1.interrupt_handler_dma_read = snd_gf1_pcm_interrupt_dma_read;
- gus->pcm_cap_substream = substream;
- substream->runtime->hw = snd_gf1_pcm_capture;
- snd_pcm_limit_isa_dma_size(gus->gf1.dma2, &runtime->hw.buffer_bytes_max);
- snd_pcm_limit_isa_dma_size(gus->gf1.dma2, &runtime->hw.period_bytes_max);
- snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &hw_constraints_clocks);
- return 0;
-}
-
-static int snd_gf1_pcm_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
-
- gus->pcm_cap_substream = NULL;
- snd_gf1_set_default_handlers(gus, SNDRV_GF1_HANDLER_DMA_READ);
- return 0;
-}
-
-static int snd_gf1_pcm_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 127;
- return 0;
-}
-
-static int snd_gf1_pcm_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
-
- spin_lock_irqsave(&gus->pcm_volume_level_lock, flags);
- ucontrol->value.integer.value[0] = gus->gf1.pcm_volume_level_left1;
- ucontrol->value.integer.value[1] = gus->gf1.pcm_volume_level_right1;
- spin_unlock_irqrestore(&gus->pcm_volume_level_lock, flags);
- return 0;
-}
-
-static int snd_gf1_pcm_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int change;
- unsigned int idx;
- unsigned short val1, val2, vol;
- struct gus_pcm_private *pcmp;
- struct snd_gus_voice *pvoice;
-
- val1 = ucontrol->value.integer.value[0] & 127;
- val2 = ucontrol->value.integer.value[1] & 127;
- spin_lock_irqsave(&gus->pcm_volume_level_lock, flags);
- change = val1 != gus->gf1.pcm_volume_level_left1 ||
- val2 != gus->gf1.pcm_volume_level_right1;
- gus->gf1.pcm_volume_level_left1 = val1;
- gus->gf1.pcm_volume_level_right1 = val2;
- gus->gf1.pcm_volume_level_left = snd_gf1_lvol_to_gvol_raw(val1 << 9) << 4;
- gus->gf1.pcm_volume_level_right = snd_gf1_lvol_to_gvol_raw(val2 << 9) << 4;
- spin_unlock_irqrestore(&gus->pcm_volume_level_lock, flags);
- /* are we active? */
- spin_lock_irqsave(&gus->voice_alloc, flags);
- for (idx = 0; idx < 32; idx++) {
- pvoice = &gus->gf1.voices[idx];
- if (!pvoice->pcm)
- continue;
- pcmp = pvoice->private_data;
- if (!(pcmp->flags & SNDRV_GF1_PCM_PFLG_ACTIVE))
- continue;
- /* load real volume - better precision */
- spin_lock(&gus->reg_lock);
- snd_gf1_select_voice(gus, pvoice->number);
- snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
- vol = pvoice == pcmp->pvoices[0] ? gus->gf1.pcm_volume_level_left : gus->gf1.pcm_volume_level_right;
- snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, vol);
- pcmp->final_volume = 1;
- spin_unlock(&gus->reg_lock);
- }
- spin_unlock_irqrestore(&gus->voice_alloc, flags);
- return change;
-}
-
-static struct snd_kcontrol_new snd_gf1_pcm_volume_control =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Playback Volume",
- .info = snd_gf1_pcm_volume_info,
- .get = snd_gf1_pcm_volume_get,
- .put = snd_gf1_pcm_volume_put
-};
-
-static struct snd_kcontrol_new snd_gf1_pcm_volume_control1 =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "GPCM Playback Volume",
- .info = snd_gf1_pcm_volume_info,
- .get = snd_gf1_pcm_volume_get,
- .put = snd_gf1_pcm_volume_put
-};
-
-static struct snd_pcm_ops snd_gf1_pcm_playback_ops = {
- .open = snd_gf1_pcm_playback_open,
- .close = snd_gf1_pcm_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_gf1_pcm_playback_hw_params,
- .hw_free = snd_gf1_pcm_playback_hw_free,
- .prepare = snd_gf1_pcm_playback_prepare,
- .trigger = snd_gf1_pcm_playback_trigger,
- .pointer = snd_gf1_pcm_playback_pointer,
- .copy = snd_gf1_pcm_playback_copy,
- .silence = snd_gf1_pcm_playback_silence,
-};
-
-static struct snd_pcm_ops snd_gf1_pcm_capture_ops = {
- .open = snd_gf1_pcm_capture_open,
- .close = snd_gf1_pcm_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_gf1_pcm_capture_hw_params,
- .hw_free = snd_gf1_pcm_capture_hw_free,
- .prepare = snd_gf1_pcm_capture_prepare,
- .trigger = snd_gf1_pcm_capture_trigger,
- .pointer = snd_gf1_pcm_capture_pointer,
-};
-
-int snd_gf1_pcm_new(struct snd_gus_card * gus, int pcm_dev, int control_index, struct snd_pcm ** rpcm)
-{
- struct snd_card *card;
- struct snd_kcontrol *kctl;
- struct snd_pcm *pcm;
- struct snd_pcm_substream *substream;
- int capture, err;
-
- if (rpcm)
- *rpcm = NULL;
- card = gus->card;
- capture = !gus->interwave && !gus->ess_flag && !gus->ace_flag ? 1 : 0;
- err = snd_pcm_new(card,
- gus->interwave ? "AMD InterWave" : "GF1",
- pcm_dev,
- gus->gf1.pcm_channels / 2,
- capture,
- &pcm);
- if (err < 0)
- return err;
- pcm->private_data = gus;
- /* playback setup */
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_gf1_pcm_playback_ops);
-
- for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)
- snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV,
- snd_dma_isa_data(),
- 64*1024, gus->gf1.dma1 > 3 ? 128*1024 : 64*1024);
-
- pcm->info_flags = 0;
- pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
- if (capture) {
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_gf1_pcm_capture_ops);
- if (gus->gf1.dma2 == gus->gf1.dma1)
- pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX;
- snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
- SNDRV_DMA_TYPE_DEV, snd_dma_isa_data(),
- 64*1024, gus->gf1.dma2 > 3 ? 128*1024 : 64*1024);
- }
- strcpy(pcm->name, pcm->id);
- if (gus->interwave) {
- sprintf(pcm->name + strlen(pcm->name), " rev %c", gus->revision + 'A');
- }
- strcat(pcm->name, " (synth)");
- gus->pcm = pcm;
-
- if (gus->codec_flag)
- kctl = snd_ctl_new1(&snd_gf1_pcm_volume_control1, gus);
- else
- kctl = snd_ctl_new1(&snd_gf1_pcm_volume_control, gus);
- if ((err = snd_ctl_add(card, kctl)) < 0)
- return err;
- kctl->id.index = control_index;
-
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/isa/gus/gus_reset.c b/ANDROID_3.4.5/sound/isa/gus/gus_reset.c
deleted file mode 100644
index 3d1fed0c..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/gus_reset.c
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/gus.h>
-
-extern void snd_gf1_timers_init(struct snd_gus_card * gus);
-extern void snd_gf1_timers_done(struct snd_gus_card * gus);
-extern int snd_gf1_synth_init(struct snd_gus_card * gus);
-extern void snd_gf1_synth_done(struct snd_gus_card * gus);
-
-/*
- * ok.. default interrupt handlers...
- */
-
-static void snd_gf1_default_interrupt_handler_midi_out(struct snd_gus_card * gus)
-{
- snd_gf1_uart_cmd(gus, gus->gf1.uart_cmd &= ~0x20);
-}
-
-static void snd_gf1_default_interrupt_handler_midi_in(struct snd_gus_card * gus)
-{
- snd_gf1_uart_cmd(gus, gus->gf1.uart_cmd &= ~0x80);
-}
-
-static void snd_gf1_default_interrupt_handler_timer1(struct snd_gus_card * gus)
-{
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, gus->gf1.timer_enabled &= ~4);
-}
-
-static void snd_gf1_default_interrupt_handler_timer2(struct snd_gus_card * gus)
-{
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, gus->gf1.timer_enabled &= ~8);
-}
-
-static void snd_gf1_default_interrupt_handler_wave_and_volume(struct snd_gus_card * gus, struct snd_gus_voice * voice)
-{
- snd_gf1_i_ctrl_stop(gus, 0x00);
- snd_gf1_i_ctrl_stop(gus, 0x0d);
-}
-
-static void snd_gf1_default_interrupt_handler_dma_write(struct snd_gus_card * gus)
-{
- snd_gf1_i_write8(gus, 0x41, 0x00);
-}
-
-static void snd_gf1_default_interrupt_handler_dma_read(struct snd_gus_card * gus)
-{
- snd_gf1_i_write8(gus, 0x49, 0x00);
-}
-
-void snd_gf1_set_default_handlers(struct snd_gus_card * gus, unsigned int what)
-{
- if (what & SNDRV_GF1_HANDLER_MIDI_OUT)
- gus->gf1.interrupt_handler_midi_out = snd_gf1_default_interrupt_handler_midi_out;
- if (what & SNDRV_GF1_HANDLER_MIDI_IN)
- gus->gf1.interrupt_handler_midi_in = snd_gf1_default_interrupt_handler_midi_in;
- if (what & SNDRV_GF1_HANDLER_TIMER1)
- gus->gf1.interrupt_handler_timer1 = snd_gf1_default_interrupt_handler_timer1;
- if (what & SNDRV_GF1_HANDLER_TIMER2)
- gus->gf1.interrupt_handler_timer2 = snd_gf1_default_interrupt_handler_timer2;
- if (what & SNDRV_GF1_HANDLER_VOICE) {
- struct snd_gus_voice *voice;
-
- voice = &gus->gf1.voices[what & 0xffff];
- voice->handler_wave =
- voice->handler_volume = snd_gf1_default_interrupt_handler_wave_and_volume;
- voice->handler_effect = NULL;
- voice->volume_change = NULL;
- }
- if (what & SNDRV_GF1_HANDLER_DMA_WRITE)
- gus->gf1.interrupt_handler_dma_write = snd_gf1_default_interrupt_handler_dma_write;
- if (what & SNDRV_GF1_HANDLER_DMA_READ)
- gus->gf1.interrupt_handler_dma_read = snd_gf1_default_interrupt_handler_dma_read;
-}
-
-/*
-
- */
-
-static void snd_gf1_clear_regs(struct snd_gus_card * gus)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- inb(GUSP(gus, IRQSTAT));
- snd_gf1_write8(gus, 0x41, 0); /* DRAM DMA Control Register */
- snd_gf1_write8(gus, 0x45, 0); /* Timer Control */
- snd_gf1_write8(gus, 0x49, 0); /* Sampling Control Register */
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-}
-
-static void snd_gf1_look_regs(struct snd_gus_card * gus)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- snd_gf1_look8(gus, 0x41); /* DRAM DMA Control Register */
- snd_gf1_look8(gus, 0x49); /* Sampling Control Register */
- inb(GUSP(gus, IRQSTAT));
- snd_gf1_read8(gus, 0x0f); /* IRQ Source Register */
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-}
-
-/*
- * put selected GF1 voices to initial stage...
- */
-
-void snd_gf1_smart_stop_voice(struct snd_gus_card * gus, unsigned short voice)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- snd_gf1_select_voice(gus, voice);
-#if 0
- printk(KERN_DEBUG " -%i- smart stop voice - volume = 0x%x\n", voice, snd_gf1_i_read16(gus, SNDRV_GF1_VW_VOLUME));
-#endif
- snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_ADDRESS_CONTROL);
- snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-}
-
-void snd_gf1_stop_voice(struct snd_gus_card * gus, unsigned short voice)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- snd_gf1_select_voice(gus, voice);
-#if 0
- printk(KERN_DEBUG " -%i- stop voice - volume = 0x%x\n", voice, snd_gf1_i_read16(gus, SNDRV_GF1_VW_VOLUME));
-#endif
- snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_ADDRESS_CONTROL);
- snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
- if (gus->gf1.enh_mode)
- snd_gf1_write8(gus, SNDRV_GF1_VB_ACCUMULATOR, 0);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-#if 0
- snd_gf1_lfo_shutdown(gus, voice, ULTRA_LFO_VIBRATO);
- snd_gf1_lfo_shutdown(gus, voice, ULTRA_LFO_TREMOLO);
-#endif
-}
-
-static void snd_gf1_clear_voices(struct snd_gus_card * gus, unsigned short v_min,
- unsigned short v_max)
-{
- unsigned long flags;
- unsigned int daddr;
- unsigned short i, w_16;
-
- daddr = gus->gf1.default_voice_address << 4;
- for (i = v_min; i <= v_max; i++) {
-#if 0
- if (gus->gf1.syn_voices)
- gus->gf1.syn_voices[i].flags = ~VFLG_DYNAMIC;
-#endif
- spin_lock_irqsave(&gus->reg_lock, flags);
- snd_gf1_select_voice(gus, i);
- snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_ADDRESS_CONTROL); /* Voice Control Register = voice stop */
- snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL); /* Volume Ramp Control Register = ramp off */
- if (gus->gf1.enh_mode)
- snd_gf1_write8(gus, SNDRV_GF1_VB_MODE, gus->gf1.memory ? 0x02 : 0x82); /* Deactivate voice */
- w_16 = snd_gf1_read8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL) & 0x04;
- snd_gf1_write16(gus, SNDRV_GF1_VW_FREQUENCY, 0x400);
- snd_gf1_write_addr(gus, SNDRV_GF1_VA_START, daddr, w_16);
- snd_gf1_write_addr(gus, SNDRV_GF1_VA_END, daddr, w_16);
- snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_START, 0);
- snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_END, 0);
- snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_RATE, 0);
- snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, 0);
- snd_gf1_write_addr(gus, SNDRV_GF1_VA_CURRENT, daddr, w_16);
- snd_gf1_write8(gus, SNDRV_GF1_VB_PAN, 7);
- if (gus->gf1.enh_mode) {
- snd_gf1_write8(gus, SNDRV_GF1_VB_ACCUMULATOR, 0);
- snd_gf1_write16(gus, SNDRV_GF1_VW_EFFECT_VOLUME, 0);
- snd_gf1_write16(gus, SNDRV_GF1_VW_EFFECT_VOLUME_FINAL, 0);
- }
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-#if 0
- snd_gf1_lfo_shutdown(gus, i, ULTRA_LFO_VIBRATO);
- snd_gf1_lfo_shutdown(gus, i, ULTRA_LFO_TREMOLO);
-#endif
- }
-}
-
-void snd_gf1_stop_voices(struct snd_gus_card * gus, unsigned short v_min, unsigned short v_max)
-{
- unsigned long flags;
- short i, ramp_ok;
- unsigned short ramp_end;
-
- if (!in_interrupt()) { /* this can't be done in interrupt */
- for (i = v_min, ramp_ok = 0; i <= v_max; i++) {
- spin_lock_irqsave(&gus->reg_lock, flags);
- snd_gf1_select_voice(gus, i);
- ramp_end = snd_gf1_read16(gus, 9) >> 8;
- if (ramp_end > SNDRV_GF1_MIN_OFFSET) {
- ramp_ok++;
- snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_RATE, 20); /* ramp rate */
- snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_START, SNDRV_GF1_MIN_OFFSET); /* ramp start */
- snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_END, ramp_end); /* ramp end */
- snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, 0x40); /* ramp down */
- if (gus->gf1.enh_mode) {
- snd_gf1_delay(gus);
- snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, 0x40);
- }
- }
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- }
- msleep_interruptible(50);
- }
- snd_gf1_clear_voices(gus, v_min, v_max);
-}
-
-static void snd_gf1_alloc_voice_use(struct snd_gus_card * gus,
- struct snd_gus_voice * pvoice,
- int type, int client, int port)
-{
- pvoice->use = 1;
- switch (type) {
- case SNDRV_GF1_VOICE_TYPE_PCM:
- gus->gf1.pcm_alloc_voices++;
- pvoice->pcm = 1;
- break;
- case SNDRV_GF1_VOICE_TYPE_SYNTH:
- pvoice->synth = 1;
- pvoice->client = client;
- pvoice->port = port;
- break;
- case SNDRV_GF1_VOICE_TYPE_MIDI:
- pvoice->midi = 1;
- pvoice->client = client;
- pvoice->port = port;
- break;
- }
-}
-
-struct snd_gus_voice *snd_gf1_alloc_voice(struct snd_gus_card * gus, int type, int client, int port)
-{
- struct snd_gus_voice *pvoice;
- unsigned long flags;
- int idx;
-
- spin_lock_irqsave(&gus->voice_alloc, flags);
- if (type == SNDRV_GF1_VOICE_TYPE_PCM) {
- if (gus->gf1.pcm_alloc_voices >= gus->gf1.pcm_channels) {
- spin_unlock_irqrestore(&gus->voice_alloc, flags);
- return NULL;
- }
- }
- for (idx = 0; idx < 32; idx++) {
- pvoice = &gus->gf1.voices[idx];
- if (!pvoice->use) {
- snd_gf1_alloc_voice_use(gus, pvoice, type, client, port);
- spin_unlock_irqrestore(&gus->voice_alloc, flags);
- return pvoice;
- }
- }
- for (idx = 0; idx < 32; idx++) {
- pvoice = &gus->gf1.voices[idx];
- if (pvoice->midi && !pvoice->client) {
- snd_gf1_clear_voices(gus, pvoice->number, pvoice->number);
- snd_gf1_alloc_voice_use(gus, pvoice, type, client, port);
- spin_unlock_irqrestore(&gus->voice_alloc, flags);
- return pvoice;
- }
- }
- spin_unlock_irqrestore(&gus->voice_alloc, flags);
- return NULL;
-}
-
-void snd_gf1_free_voice(struct snd_gus_card * gus, struct snd_gus_voice *voice)
-{
- unsigned long flags;
- void (*private_free)(struct snd_gus_voice *voice);
- void *private_data;
-
- if (voice == NULL || !voice->use)
- return;
- snd_gf1_set_default_handlers(gus, SNDRV_GF1_HANDLER_VOICE | voice->number);
- snd_gf1_clear_voices(gus, voice->number, voice->number);
- spin_lock_irqsave(&gus->voice_alloc, flags);
- private_free = voice->private_free;
- private_data = voice->private_data;
- voice->private_free = NULL;
- voice->private_data = NULL;
- if (voice->pcm)
- gus->gf1.pcm_alloc_voices--;
- voice->use = voice->pcm = 0;
- voice->sample_ops = NULL;
- spin_unlock_irqrestore(&gus->voice_alloc, flags);
- if (private_free)
- private_free(voice);
-}
-
-/*
- * call this function only by start of driver
- */
-
-int snd_gf1_start(struct snd_gus_card * gus)
-{
- unsigned long flags;
- unsigned int i;
-
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */
- udelay(160);
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* disable IRQ & DAC */
- udelay(160);
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_JOYSTICK_DAC_LEVEL, gus->joystick_dac);
-
- snd_gf1_set_default_handlers(gus, SNDRV_GF1_HANDLER_ALL);
- for (i = 0; i < 32; i++) {
- gus->gf1.voices[i].number = i;
- snd_gf1_set_default_handlers(gus, SNDRV_GF1_HANDLER_VOICE | i);
- }
-
- snd_gf1_uart_cmd(gus, 0x03); /* huh.. this cleanup took me some time... */
-
- if (gus->gf1.enh_mode) { /* enhanced mode !!!! */
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_GLOBAL_MODE, snd_gf1_i_look8(gus, SNDRV_GF1_GB_GLOBAL_MODE) | 0x01);
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01);
- }
- snd_gf1_clear_regs(gus);
- snd_gf1_select_active_voices(gus);
- snd_gf1_delay(gus);
- gus->gf1.default_voice_address = gus->gf1.memory > 0 ? 0 : 512 - 8;
- /* initialize LFOs & clear LFOs memory */
- if (gus->gf1.enh_mode && gus->gf1.memory) {
- gus->gf1.hw_lfo = 1;
- gus->gf1.default_voice_address += 1024;
- } else {
- gus->gf1.sw_lfo = 1;
- }
-#if 0
- snd_gf1_lfo_init(gus);
-#endif
- if (gus->gf1.memory > 0)
- for (i = 0; i < 4; i++)
- snd_gf1_poke(gus, gus->gf1.default_voice_address + i, 0);
- snd_gf1_clear_regs(gus);
- snd_gf1_clear_voices(gus, 0, 31);
- snd_gf1_look_regs(gus);
- udelay(160);
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 7); /* Reset Register = IRQ enable, DAC enable */
- udelay(160);
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 7); /* Reset Register = IRQ enable, DAC enable */
- if (gus->gf1.enh_mode) { /* enhanced mode !!!! */
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_GLOBAL_MODE, snd_gf1_i_look8(gus, SNDRV_GF1_GB_GLOBAL_MODE) | 0x01);
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01);
- }
- while ((snd_gf1_i_read8(gus, SNDRV_GF1_GB_VOICES_IRQ) & 0xc0) != 0xc0);
-
- spin_lock_irqsave(&gus->reg_lock, flags);
- outb(gus->gf1.active_voice = 0, GUSP(gus, GF1PAGE));
- outb(gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
- spin_unlock_irqrestore(&gus->reg_lock, flags);
-
- snd_gf1_timers_init(gus);
- snd_gf1_look_regs(gus);
- snd_gf1_mem_init(gus);
- snd_gf1_mem_proc_init(gus);
-#ifdef CONFIG_SND_DEBUG
- snd_gus_irq_profile_init(gus);
-#endif
-
-#if 0
- if (gus->pnp_flag) {
- if (gus->chip.playback_fifo_size > 0)
- snd_gf1_i_write16(gus, SNDRV_GF1_GW_FIFO_RECORD_BASE_ADDR, gus->chip.playback_fifo_block->ptr >> 8);
- if (gus->chip.record_fifo_size > 0)
- snd_gf1_i_write16(gus, SNDRV_GF1_GW_FIFO_PLAY_BASE_ADDR, gus->chip.record_fifo_block->ptr >> 8);
- snd_gf1_i_write16(gus, SNDRV_GF1_GW_FIFO_SIZE, gus->chip.interwave_fifo_reg);
- }
-#endif
-
- return 0;
-}
-
-/*
- * call this function only by shutdown of driver
- */
-
-int snd_gf1_stop(struct snd_gus_card * gus)
-{
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, 0); /* stop all timers */
- snd_gf1_stop_voices(gus, 0, 31); /* stop all voices */
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* disable IRQ & DAC */
- snd_gf1_timers_done(gus);
- snd_gf1_mem_done(gus);
-#if 0
- snd_gf1_lfo_done(gus);
-#endif
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/isa/gus/gus_tables.h b/ANDROID_3.4.5/sound/isa/gus/gus_tables.h
deleted file mode 100644
index 42a4ca0d..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/gus_tables.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define SNDRV_GF1_SCALE_TABLE_SIZE 128
-#define SNDRV_GF1_ATTEN_TABLE_SIZE 128
-
-#ifdef __GUS_TABLES_ALLOC__
-
-#if 0
-
-unsigned int snd_gf1_scale_table[SNDRV_GF1_SCALE_TABLE_SIZE] =
-{
- 8372, 8870, 9397, 9956, 10548, 11175,
- 11840, 12544, 13290, 14080, 14917, 15804,
- 16744, 17740, 18795, 19912, 21096, 22351,
- 23680, 25088, 26580, 28160, 29834, 31609,
- 33488, 35479, 37589, 39824, 42192, 44701,
- 47359, 50175, 53159, 56320, 59669, 63217,
- 66976, 70959, 75178, 79649, 84385, 89402,
- 94719, 100351, 106318, 112640, 119338, 126434,
- 133952, 141918, 150356, 159297, 168769, 178805,
- 189437, 200702, 212636, 225280, 238676, 252868,
- 267905, 283835, 300713, 318594, 337539, 357610,
- 378874, 401403, 425272, 450560, 477352, 505737,
- 535809, 567670, 601425, 637188, 675077, 715219,
- 757749, 802807, 850544, 901120, 954703, 1011473,
- 1071618, 1135340, 1202851, 1274376, 1350154, 1430439,
- 1515497, 1605613, 1701088, 1802240, 1909407, 2022946,
- 2143237, 2270680, 2405702, 2548752, 2700309, 2860878,
- 3030994, 3211227, 3402176, 3604480, 3818814, 4045892,
- 4286473, 4541360, 4811404, 5097505, 5400618, 5721755,
- 6061989, 6422453, 6804352, 7208960, 7637627, 8091784,
- 8572947, 9082720, 9622807, 10195009, 10801236, 11443511,
- 12123977, 12844906
-};
-
-#endif /* 0 */
-
-unsigned short snd_gf1_atten_table[SNDRV_GF1_ATTEN_TABLE_SIZE] = {
- 4095 /* 0 */,1789 /* 1 */,1533 /* 2 */,1383 /* 3 */,1277 /* 4 */,
- 1195 /* 5 */,1127 /* 6 */,1070 /* 7 */,1021 /* 8 */,978 /* 9 */,
- 939 /* 10 */,903 /* 11 */,871 /* 12 */,842 /* 13 */,814 /* 14 */,
- 789 /* 15 */,765 /* 16 */,743 /* 17 */,722 /* 18 */,702 /* 19 */,
- 683 /* 20 */,665 /* 21 */,647 /* 22 */,631 /* 23 */,615 /* 24 */,
- 600 /* 25 */,586 /* 26 */,572 /* 27 */,558 /* 28 */,545 /* 29 */,
- 533 /* 30 */,521 /* 31 */,509 /* 32 */,498 /* 33 */,487 /* 34 */,
- 476 /* 35 */,466 /* 36 */,455 /* 37 */,446 /* 38 */,436 /* 39 */,
- 427 /* 40 */,418 /* 41 */,409 /* 42 */,400 /* 43 */,391 /* 44 */,
- 383 /* 45 */,375 /* 46 */,367 /* 47 */,359 /* 48 */,352 /* 49 */,
- 344 /* 50 */,337 /* 51 */,330 /* 52 */,323 /* 53 */,316 /* 54 */,
- 309 /* 55 */,302 /* 56 */,296 /* 57 */,289 /* 58 */,283 /* 59 */,
- 277 /* 60 */,271 /* 61 */,265 /* 62 */,259 /* 63 */,253 /* 64 */,
- 247 /* 65 */,242 /* 66 */,236 /* 67 */,231 /* 68 */,225 /* 69 */,
- 220 /* 70 */,215 /* 71 */,210 /* 72 */,205 /* 73 */,199 /* 74 */,
- 195 /* 75 */,190 /* 76 */,185 /* 77 */,180 /* 78 */,175 /* 79 */,
- 171 /* 80 */,166 /* 81 */,162 /* 82 */,157 /* 83 */,153 /* 84 */,
- 148 /* 85 */,144 /* 86 */,140 /* 87 */,135 /* 88 */,131 /* 89 */,
- 127 /* 90 */,123 /* 91 */,119 /* 92 */,115 /* 93 */,111 /* 94 */,
- 107 /* 95 */,103 /* 96 */,100 /* 97 */,96 /* 98 */,92 /* 99 */,
- 88 /* 100 */,85 /* 101 */,81 /* 102 */,77 /* 103 */,74 /* 104 */,
- 70 /* 105 */,67 /* 106 */,63 /* 107 */,60 /* 108 */,56 /* 109 */,
- 53 /* 110 */,50 /* 111 */,46 /* 112 */,43 /* 113 */,40 /* 114 */,
- 37 /* 115 */,33 /* 116 */,30 /* 117 */,27 /* 118 */,24 /* 119 */,
- 21 /* 120 */,18 /* 121 */,15 /* 122 */,12 /* 123 */,9 /* 124 */,
- 6 /* 125 */,3 /* 126 */,0 /* 127 */,
-};
-
-#else
-
-extern unsigned int snd_gf1_scale_table[SNDRV_GF1_SCALE_TABLE_SIZE];
-extern unsigned short snd_gf1_atten_table[SNDRV_GF1_ATTEN_TABLE_SIZE];
-
-#endif
diff --git a/ANDROID_3.4.5/sound/isa/gus/gus_timer.c b/ANDROID_3.4.5/sound/isa/gus/gus_timer.c
deleted file mode 100644
index c5372714..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/gus_timer.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Routines for Gravis UltraSound soundcards - Timers
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- * GUS have similar timers as AdLib (OPL2/OPL3 chips).
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/gus.h>
-
-/*
- * Timer 1 - 80us
- */
-
-static int snd_gf1_timer1_start(struct snd_timer * timer)
-{
- unsigned long flags;
- unsigned char tmp;
- unsigned int ticks;
- struct snd_gus_card *gus;
-
- gus = snd_timer_chip(timer);
- spin_lock_irqsave(&gus->reg_lock, flags);
- ticks = timer->sticks;
- tmp = (gus->gf1.timer_enabled |= 4);
- snd_gf1_write8(gus, SNDRV_GF1_GB_ADLIB_TIMER_1, 256 - ticks); /* timer 1 count */
- snd_gf1_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, tmp); /* enable timer 1 IRQ */
- snd_gf1_adlib_write(gus, 0x04, tmp >> 2); /* timer 2 start */
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- return 0;
-}
-
-static int snd_gf1_timer1_stop(struct snd_timer * timer)
-{
- unsigned long flags;
- unsigned char tmp;
- struct snd_gus_card *gus;
-
- gus = snd_timer_chip(timer);
- spin_lock_irqsave(&gus->reg_lock, flags);
- tmp = (gus->gf1.timer_enabled &= ~4);
- snd_gf1_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, tmp); /* disable timer #1 */
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- return 0;
-}
-
-/*
- * Timer 2 - 320us
- */
-
-static int snd_gf1_timer2_start(struct snd_timer * timer)
-{
- unsigned long flags;
- unsigned char tmp;
- unsigned int ticks;
- struct snd_gus_card *gus;
-
- gus = snd_timer_chip(timer);
- spin_lock_irqsave(&gus->reg_lock, flags);
- ticks = timer->sticks;
- tmp = (gus->gf1.timer_enabled |= 8);
- snd_gf1_write8(gus, SNDRV_GF1_GB_ADLIB_TIMER_2, 256 - ticks); /* timer 2 count */
- snd_gf1_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, tmp); /* enable timer 2 IRQ */
- snd_gf1_adlib_write(gus, 0x04, tmp >> 2); /* timer 2 start */
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- return 0;
-}
-
-static int snd_gf1_timer2_stop(struct snd_timer * timer)
-{
- unsigned long flags;
- unsigned char tmp;
- struct snd_gus_card *gus;
-
- gus = snd_timer_chip(timer);
- spin_lock_irqsave(&gus->reg_lock, flags);
- tmp = (gus->gf1.timer_enabled &= ~8);
- snd_gf1_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, tmp); /* disable timer #1 */
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- return 0;
-}
-
-/*
-
- */
-
-static void snd_gf1_interrupt_timer1(struct snd_gus_card * gus)
-{
- struct snd_timer *timer = gus->gf1.timer1;
-
- if (timer == NULL)
- return;
- snd_timer_interrupt(timer, timer->sticks);
-}
-
-static void snd_gf1_interrupt_timer2(struct snd_gus_card * gus)
-{
- struct snd_timer *timer = gus->gf1.timer2;
-
- if (timer == NULL)
- return;
- snd_timer_interrupt(timer, timer->sticks);
-}
-
-/*
-
- */
-
-static struct snd_timer_hardware snd_gf1_timer1 =
-{
- .flags = SNDRV_TIMER_HW_STOP,
- .resolution = 80000,
- .ticks = 256,
- .start = snd_gf1_timer1_start,
- .stop = snd_gf1_timer1_stop,
-};
-
-static struct snd_timer_hardware snd_gf1_timer2 =
-{
- .flags = SNDRV_TIMER_HW_STOP,
- .resolution = 320000,
- .ticks = 256,
- .start = snd_gf1_timer2_start,
- .stop = snd_gf1_timer2_stop,
-};
-
-static void snd_gf1_timer1_free(struct snd_timer *timer)
-{
- struct snd_gus_card *gus = timer->private_data;
- gus->gf1.timer1 = NULL;
-}
-
-static void snd_gf1_timer2_free(struct snd_timer *timer)
-{
- struct snd_gus_card *gus = timer->private_data;
- gus->gf1.timer2 = NULL;
-}
-
-void snd_gf1_timers_init(struct snd_gus_card * gus)
-{
- struct snd_timer *timer;
- struct snd_timer_id tid;
-
- if (gus->gf1.timer1 != NULL || gus->gf1.timer2 != NULL)
- return;
-
- gus->gf1.interrupt_handler_timer1 = snd_gf1_interrupt_timer1;
- gus->gf1.interrupt_handler_timer2 = snd_gf1_interrupt_timer2;
-
- tid.dev_class = SNDRV_TIMER_CLASS_CARD;
- tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
- tid.card = gus->card->number;
- tid.device = gus->timer_dev;
- tid.subdevice = 0;
-
- if (snd_timer_new(gus->card, "GF1 timer", &tid, &timer) >= 0) {
- strcpy(timer->name, "GF1 timer #1");
- timer->private_data = gus;
- timer->private_free = snd_gf1_timer1_free;
- timer->hw = snd_gf1_timer1;
- }
- gus->gf1.timer1 = timer;
-
- tid.device++;
-
- if (snd_timer_new(gus->card, "GF1 timer", &tid, &timer) >= 0) {
- strcpy(timer->name, "GF1 timer #2");
- timer->private_data = gus;
- timer->private_free = snd_gf1_timer2_free;
- timer->hw = snd_gf1_timer2;
- }
- gus->gf1.timer2 = timer;
-}
-
-void snd_gf1_timers_done(struct snd_gus_card * gus)
-{
- snd_gf1_set_default_handlers(gus, SNDRV_GF1_HANDLER_TIMER1 | SNDRV_GF1_HANDLER_TIMER2);
- if (gus->gf1.timer1) {
- snd_device_free(gus->card, gus->gf1.timer1);
- gus->gf1.timer1 = NULL;
- }
- if (gus->gf1.timer2) {
- snd_device_free(gus->card, gus->gf1.timer2);
- gus->gf1.timer2 = NULL;
- }
-}
diff --git a/ANDROID_3.4.5/sound/isa/gus/gus_uart.c b/ANDROID_3.4.5/sound/isa/gus/gus_uart.c
deleted file mode 100644
index 21cc42e4..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/gus_uart.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Routines for the GF1 MIDI interface - like UART 6850
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/gus.h>
-
-static void snd_gf1_interrupt_midi_in(struct snd_gus_card * gus)
-{
- int count;
- unsigned char stat, data, byte;
- unsigned long flags;
-
- count = 10;
- while (count) {
- spin_lock_irqsave(&gus->uart_cmd_lock, flags);
- stat = snd_gf1_uart_stat(gus);
- if (!(stat & 0x01)) { /* data in Rx FIFO? */
- spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
- count--;
- continue;
- }
- count = 100; /* arm counter to new value */
- data = snd_gf1_uart_get(gus);
- if (!(gus->gf1.uart_cmd & 0x80)) {
- spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
- continue;
- }
- if (stat & 0x10) { /* framing error */
- gus->gf1.uart_framing++;
- spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
- continue;
- }
- byte = snd_gf1_uart_get(gus);
- spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
- snd_rawmidi_receive(gus->midi_substream_input, &byte, 1);
- if (stat & 0x20) {
- gus->gf1.uart_overrun++;
- }
- }
-}
-
-static void snd_gf1_interrupt_midi_out(struct snd_gus_card * gus)
-{
- char byte;
- unsigned long flags;
-
- /* try unlock output */
- if (snd_gf1_uart_stat(gus) & 0x01)
- snd_gf1_interrupt_midi_in(gus);
-
- spin_lock_irqsave(&gus->uart_cmd_lock, flags);
- if (snd_gf1_uart_stat(gus) & 0x02) { /* Tx FIFO free? */
- if (snd_rawmidi_transmit(gus->midi_substream_output, &byte, 1) != 1) { /* no other bytes or error */
- snd_gf1_uart_cmd(gus, gus->gf1.uart_cmd & ~0x20); /* disable Tx interrupt */
- } else {
- snd_gf1_uart_put(gus, byte);
- }
- }
- spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
-}
-
-static void snd_gf1_uart_reset(struct snd_gus_card * gus, int close)
-{
- snd_gf1_uart_cmd(gus, 0x03); /* reset */
- if (!close && gus->uart_enable) {
- udelay(160);
- snd_gf1_uart_cmd(gus, 0x00); /* normal operations */
- }
-}
-
-static int snd_gf1_uart_output_open(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- struct snd_gus_card *gus;
-
- gus = substream->rmidi->private_data;
- spin_lock_irqsave(&gus->uart_cmd_lock, flags);
- if (!(gus->gf1.uart_cmd & 0x80)) { /* input active? */
- snd_gf1_uart_reset(gus, 0);
- }
- gus->gf1.interrupt_handler_midi_out = snd_gf1_interrupt_midi_out;
- gus->midi_substream_output = substream;
- spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
-#if 0
- snd_printk(KERN_DEBUG "write init - cmd = 0x%x, stat = 0x%x\n", gus->gf1.uart_cmd, snd_gf1_uart_stat(gus));
-#endif
- return 0;
-}
-
-static int snd_gf1_uart_input_open(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- struct snd_gus_card *gus;
- int i;
-
- gus = substream->rmidi->private_data;
- spin_lock_irqsave(&gus->uart_cmd_lock, flags);
- if (gus->gf1.interrupt_handler_midi_out != snd_gf1_interrupt_midi_out) {
- snd_gf1_uart_reset(gus, 0);
- }
- gus->gf1.interrupt_handler_midi_in = snd_gf1_interrupt_midi_in;
- gus->midi_substream_input = substream;
- if (gus->uart_enable) {
- for (i = 0; i < 1000 && (snd_gf1_uart_stat(gus) & 0x01); i++)
- snd_gf1_uart_get(gus); /* clean Rx */
- if (i >= 1000)
- snd_printk(KERN_ERR "gus midi uart init read - cleanup error\n");
- }
- spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
-#if 0
- snd_printk(KERN_DEBUG
- "read init - enable = %i, cmd = 0x%x, stat = 0x%x\n",
- gus->uart_enable, gus->gf1.uart_cmd, snd_gf1_uart_stat(gus));
- snd_printk(KERN_DEBUG
- "[0x%x] reg (ctrl/status) = 0x%x, reg (data) = 0x%x "
- "(page = 0x%x)\n",
- gus->gf1.port + 0x100, inb(gus->gf1.port + 0x100),
- inb(gus->gf1.port + 0x101), inb(gus->gf1.port + 0x102));
-#endif
- return 0;
-}
-
-static int snd_gf1_uart_output_close(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- struct snd_gus_card *gus;
-
- gus = substream->rmidi->private_data;
- spin_lock_irqsave(&gus->uart_cmd_lock, flags);
- if (gus->gf1.interrupt_handler_midi_in != snd_gf1_interrupt_midi_in)
- snd_gf1_uart_reset(gus, 1);
- snd_gf1_set_default_handlers(gus, SNDRV_GF1_HANDLER_MIDI_OUT);
- gus->midi_substream_output = NULL;
- spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
- return 0;
-}
-
-static int snd_gf1_uart_input_close(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- struct snd_gus_card *gus;
-
- gus = substream->rmidi->private_data;
- spin_lock_irqsave(&gus->uart_cmd_lock, flags);
- if (gus->gf1.interrupt_handler_midi_out != snd_gf1_interrupt_midi_out)
- snd_gf1_uart_reset(gus, 1);
- snd_gf1_set_default_handlers(gus, SNDRV_GF1_HANDLER_MIDI_IN);
- gus->midi_substream_input = NULL;
- spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
- return 0;
-}
-
-static void snd_gf1_uart_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct snd_gus_card *gus;
- unsigned long flags;
-
- gus = substream->rmidi->private_data;
-
- spin_lock_irqsave(&gus->uart_cmd_lock, flags);
- if (up) {
- if ((gus->gf1.uart_cmd & 0x80) == 0)
- snd_gf1_uart_cmd(gus, gus->gf1.uart_cmd | 0x80); /* enable Rx interrupts */
- } else {
- if (gus->gf1.uart_cmd & 0x80)
- snd_gf1_uart_cmd(gus, gus->gf1.uart_cmd & ~0x80); /* disable Rx interrupts */
- }
- spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
-}
-
-static void snd_gf1_uart_output_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- unsigned long flags;
- struct snd_gus_card *gus;
- char byte;
- int timeout;
-
- gus = substream->rmidi->private_data;
-
- spin_lock_irqsave(&gus->uart_cmd_lock, flags);
- if (up) {
- if ((gus->gf1.uart_cmd & 0x20) == 0) {
- spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
- /* wait for empty Rx - Tx is probably unlocked */
- timeout = 10000;
- while (timeout-- > 0 && snd_gf1_uart_stat(gus) & 0x01);
- /* Tx FIFO free? */
- spin_lock_irqsave(&gus->uart_cmd_lock, flags);
- if (gus->gf1.uart_cmd & 0x20) {
- spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
- return;
- }
- if (snd_gf1_uart_stat(gus) & 0x02) {
- if (snd_rawmidi_transmit(substream, &byte, 1) != 1) {
- spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
- return;
- }
- snd_gf1_uart_put(gus, byte);
- }
- snd_gf1_uart_cmd(gus, gus->gf1.uart_cmd | 0x20); /* enable Tx interrupt */
- }
- } else {
- if (gus->gf1.uart_cmd & 0x20)
- snd_gf1_uart_cmd(gus, gus->gf1.uart_cmd & ~0x20);
- }
- spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
-}
-
-static struct snd_rawmidi_ops snd_gf1_uart_output =
-{
- .open = snd_gf1_uart_output_open,
- .close = snd_gf1_uart_output_close,
- .trigger = snd_gf1_uart_output_trigger,
-};
-
-static struct snd_rawmidi_ops snd_gf1_uart_input =
-{
- .open = snd_gf1_uart_input_open,
- .close = snd_gf1_uart_input_close,
- .trigger = snd_gf1_uart_input_trigger,
-};
-
-int snd_gf1_rawmidi_new(struct snd_gus_card * gus, int device, struct snd_rawmidi ** rrawmidi)
-{
- struct snd_rawmidi *rmidi;
- int err;
-
- if (rrawmidi)
- *rrawmidi = NULL;
- if ((err = snd_rawmidi_new(gus->card, "GF1", device, 1, 1, &rmidi)) < 0)
- return err;
- strcpy(rmidi->name, gus->interwave ? "AMD InterWave" : "GF1");
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_gf1_uart_output);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_gf1_uart_input);
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
- rmidi->private_data = gus;
- gus->midi_uart = rmidi;
- if (rrawmidi)
- *rrawmidi = rmidi;
- return err;
-}
diff --git a/ANDROID_3.4.5/sound/isa/gus/gus_volume.c b/ANDROID_3.4.5/sound/isa/gus/gus_volume.c
deleted file mode 100644
index 3dd841ae..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/gus_volume.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <linux/export.h>
-#include <sound/core.h>
-#include <sound/gus.h>
-#define __GUS_TABLES_ALLOC__
-#include "gus_tables.h"
-
-EXPORT_SYMBOL(snd_gf1_atten_table); /* for snd-gus-synth module */
-
-unsigned short snd_gf1_lvol_to_gvol_raw(unsigned int vol)
-{
- unsigned short e, m, tmp;
-
- if (vol > 65535)
- vol = 65535;
- tmp = vol;
- e = 7;
- if (tmp < 128) {
- while (e > 0 && tmp < (1 << e))
- e--;
- } else {
- while (tmp > 255) {
- tmp >>= 1;
- e++;
- }
- }
- m = vol - (1 << e);
- if (m > 0) {
- if (e > 8)
- m >>= e - 8;
- else if (e < 8)
- m <<= 8 - e;
- m &= 255;
- }
- return (e << 8) | m;
-}
-
-#if 0
-
-unsigned int snd_gf1_gvol_to_lvol_raw(unsigned short gf1_vol)
-{
- unsigned int rvol;
- unsigned short e, m;
-
- if (!gf1_vol)
- return 0;
- e = gf1_vol >> 8;
- m = (unsigned char) gf1_vol;
- rvol = 1 << e;
- if (e > 8)
- return rvol | (m << (e - 8));
- return rvol | (m >> (8 - e));
-}
-
-unsigned int snd_gf1_calc_ramp_rate(struct snd_gus_card * gus,
- unsigned short start,
- unsigned short end,
- unsigned int us)
-{
- static unsigned char vol_rates[19] =
- {
- 23, 24, 26, 28, 29, 31, 32, 34,
- 36, 37, 39, 40, 42, 44, 45, 47,
- 49, 50, 52
- };
- unsigned short range, increment, value, i;
-
- start >>= 4;
- end >>= 4;
- if (start < end)
- us /= end - start;
- else
- us /= start - end;
- range = 4;
- value = gus->gf1.enh_mode ?
- vol_rates[0] :
- vol_rates[gus->gf1.active_voices - 14];
- for (i = 0; i < 3; i++) {
- if (us < value) {
- range = i;
- break;
- } else
- value <<= 3;
- }
- if (range == 4) {
- range = 3;
- increment = 1;
- } else
- increment = (value + (value >> 1)) / us;
- return (range << 6) | (increment & 0x3f);
-}
-
-#endif /* 0 */
-
-unsigned short snd_gf1_translate_freq(struct snd_gus_card * gus, unsigned int freq16)
-{
- freq16 >>= 3;
- if (freq16 < 50)
- freq16 = 50;
- if (freq16 & 0xf8000000) {
- freq16 = ~0xf8000000;
- snd_printk(KERN_ERR "snd_gf1_translate_freq: overflow - freq = 0x%x\n", freq16);
- }
- return ((freq16 << 9) + (gus->gf1.playback_freq >> 1)) / gus->gf1.playback_freq;
-}
-
-#if 0
-
-short snd_gf1_compute_vibrato(short cents, unsigned short fc_register)
-{
- static short vibrato_table[] =
- {
- 0, 0, 32, 592, 61, 1175, 93, 1808,
- 124, 2433, 152, 3007, 182, 3632, 213, 4290,
- 241, 4834, 255, 5200
- };
-
- long depth;
- short *vi1, *vi2, pcents, v1;
-
- pcents = cents < 0 ? -cents : cents;
- for (vi1 = vibrato_table, vi2 = vi1 + 2; pcents > *vi2; vi1 = vi2, vi2 += 2);
- v1 = *(vi1 + 1);
- /* The FC table above is a list of pairs. The first number in the pair */
- /* is the cents index from 0-255 cents, and the second number in the */
- /* pair is the FC adjustment needed to change the pitch by the indexed */
- /* number of cents. The table was created for an FC of 32768. */
- /* The following expression does a linear interpolation against the */
- /* approximated log curve in the table above, and then scales the number */
- /* by the FC before the LFO. This calculation also adjusts the output */
- /* value to produce the appropriate depth for the hardware. The depth */
- /* is 2 * desired FC + 1. */
- depth = (((int) (*(vi2 + 1) - *vi1) * (pcents - *vi1) / (*vi2 - *vi1)) + v1) * fc_register >> 14;
- if (depth)
- depth++;
- if (depth > 255)
- depth = 255;
- return cents < 0 ? -(short) depth : (short) depth;
-}
-
-unsigned short snd_gf1_compute_pitchbend(unsigned short pitchbend, unsigned short sens)
-{
- static long log_table[] = {1024, 1085, 1149, 1218, 1290, 1367, 1448, 1534, 1625, 1722, 1825, 1933};
- int wheel, sensitivity;
- unsigned int mantissa, f1, f2;
- unsigned short semitones, f1_index, f2_index, f1_power, f2_power;
- char bend_down = 0;
- int bend;
-
- if (!sens)
- return 1024;
- wheel = (int) pitchbend - 8192;
- sensitivity = ((int) sens * wheel) / 128;
- if (sensitivity < 0) {
- bend_down = 1;
- sensitivity = -sensitivity;
- }
- semitones = (unsigned int) (sensitivity >> 13);
- mantissa = sensitivity % 8192;
- f1_index = semitones % 12;
- f2_index = (semitones + 1) % 12;
- f1_power = semitones / 12;
- f2_power = (semitones + 1) / 12;
- f1 = log_table[f1_index] << f1_power;
- f2 = log_table[f2_index] << f2_power;
- bend = (int) ((((f2 - f1) * mantissa) >> 13) + f1);
- if (bend_down)
- bend = 1048576L / bend;
- return bend;
-}
-
-unsigned short snd_gf1_compute_freq(unsigned int freq,
- unsigned int rate,
- unsigned short mix_rate)
-{
- unsigned int fc;
- int scale = 0;
-
- while (freq >= 4194304L) {
- scale++;
- freq >>= 1;
- }
- fc = (freq << 10) / rate;
- if (fc > 97391L) {
- fc = 97391;
- snd_printk(KERN_ERR "patch: (1) fc frequency overflow - %u\n", fc);
- }
- fc = (fc * 44100UL) / mix_rate;
- while (scale--)
- fc <<= 1;
- if (fc > 65535L) {
- fc = 65535;
- snd_printk(KERN_ERR "patch: (2) fc frequency overflow - %u\n", fc);
- }
- return (unsigned short) fc;
-}
-
-#endif /* 0 */
diff --git a/ANDROID_3.4.5/sound/isa/gus/gusclassic.c b/ANDROID_3.4.5/sound/isa/gus/gusclassic.c
deleted file mode 100644
index bf633367..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/gusclassic.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Driver for Gravis UltraSound Classic soundcard
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/isa.h>
-#include <linux/delay.h>
-#include <linux/time.h>
-#include <linux/module.h>
-#include <asm/dma.h>
-#include <sound/core.h>
-#include <sound/gus.h>
-#define SNDRV_LEGACY_FIND_FREE_IRQ
-#define SNDRV_LEGACY_FIND_FREE_DMA
-#include <sound/initval.h>
-
-#define CRD_NAME "Gravis UltraSound Classic"
-#define DEV_NAME "gusclassic"
-
-MODULE_DESCRIPTION(CRD_NAME);
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Classic}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x230,0x240,0x250,0x260 */
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 3,5,9,11,12,15 */
-static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3,5,6,7 */
-static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3,5,6,7 */
-static int joystick_dac[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 29};
- /* 0 to 31, (0.59V-4.52V or 0.389V-2.98V) */
-static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24};
-static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
-module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
-module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver.");
-module_param_array(dma2, int, NULL, 0444);
-MODULE_PARM_DESC(dma2, "DMA2 # for " CRD_NAME " driver.");
-module_param_array(joystick_dac, int, NULL, 0444);
-MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for " CRD_NAME " driver.");
-module_param_array(channels, int, NULL, 0444);
-MODULE_PARM_DESC(channels, "GF1 channels for " CRD_NAME " driver.");
-module_param_array(pcm_channels, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for " CRD_NAME " driver.");
-
-static int __devinit snd_gusclassic_match(struct device *dev, unsigned int n)
-{
- return enable[n];
-}
-
-static int __devinit snd_gusclassic_create(struct snd_card *card,
- struct device *dev, unsigned int n, struct snd_gus_card **rgus)
-{
- static long possible_ports[] = {0x220, 0x230, 0x240, 0x250, 0x260};
- static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1};
- static int possible_dmas[] = {5, 6, 7, 1, 3, -1};
-
- int i, error;
-
- if (irq[n] == SNDRV_AUTO_IRQ) {
- irq[n] = snd_legacy_find_free_irq(possible_irqs);
- if (irq[n] < 0) {
- dev_err(dev, "unable to find a free IRQ\n");
- return -EBUSY;
- }
- }
- if (dma1[n] == SNDRV_AUTO_DMA) {
- dma1[n] = snd_legacy_find_free_dma(possible_dmas);
- if (dma1[n] < 0) {
- dev_err(dev, "unable to find a free DMA1\n");
- return -EBUSY;
- }
- }
- if (dma2[n] == SNDRV_AUTO_DMA) {
- dma2[n] = snd_legacy_find_free_dma(possible_dmas);
- if (dma2[n] < 0) {
- dev_err(dev, "unable to find a free DMA2\n");
- return -EBUSY;
- }
- }
-
- if (port[n] != SNDRV_AUTO_PORT)
- return snd_gus_create(card, port[n], irq[n], dma1[n], dma2[n],
- 0, channels[n], pcm_channels[n], 0, rgus);
-
- i = 0;
- do {
- port[n] = possible_ports[i];
- error = snd_gus_create(card, port[n], irq[n], dma1[n], dma2[n],
- 0, channels[n], pcm_channels[n], 0, rgus);
- } while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
-
- return error;
-}
-
-static int __devinit snd_gusclassic_detect(struct snd_gus_card *gus)
-{
- unsigned char d;
-
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
- snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
- return -ENODEV;
- }
- udelay(160);
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* release reset */
- udelay(160);
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
- snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
- return -ENODEV;
- }
- return 0;
-}
-
-static int __devinit snd_gusclassic_probe(struct device *dev, unsigned int n)
-{
- struct snd_card *card;
- struct snd_gus_card *gus;
- int error;
-
- error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card);
- if (error < 0)
- return error;
-
- if (pcm_channels[n] < 2)
- pcm_channels[n] = 2;
-
- error = snd_gusclassic_create(card, dev, n, &gus);
- if (error < 0)
- goto out;
-
- error = snd_gusclassic_detect(gus);
- if (error < 0)
- goto out;
-
- gus->joystick_dac = joystick_dac[n];
-
- error = snd_gus_initialize(gus);
- if (error < 0)
- goto out;
-
- error = -ENODEV;
- if (gus->max_flag || gus->ess_flag) {
- dev_err(dev, "GUS Classic or ACE soundcard was "
- "not detected at 0x%lx\n", gus->gf1.port);
- goto out;
- }
-
- error = snd_gf1_new_mixer(gus);
- if (error < 0)
- goto out;
-
- error = snd_gf1_pcm_new(gus, 0, 0, NULL);
- if (error < 0)
- goto out;
-
- if (!gus->ace_flag) {
- error = snd_gf1_rawmidi_new(gus, 0, NULL);
- if (error < 0)
- goto out;
- }
-
- sprintf(card->longname + strlen(card->longname),
- " at 0x%lx, irq %d, dma %d",
- gus->gf1.port, gus->gf1.irq, gus->gf1.dma1);
-
- if (gus->gf1.dma2 >= 0)
- sprintf(card->longname + strlen(card->longname),
- "&%d", gus->gf1.dma2);
-
- snd_card_set_dev(card, dev);
-
- error = snd_card_register(card);
- if (error < 0)
- goto out;
-
- dev_set_drvdata(dev, card);
- return 0;
-
-out: snd_card_free(card);
- return error;
-}
-
-static int __devexit snd_gusclassic_remove(struct device *dev, unsigned int n)
-{
- snd_card_free(dev_get_drvdata(dev));
- dev_set_drvdata(dev, NULL);
- return 0;
-}
-
-static struct isa_driver snd_gusclassic_driver = {
- .match = snd_gusclassic_match,
- .probe = snd_gusclassic_probe,
- .remove = __devexit_p(snd_gusclassic_remove),
-#if 0 /* FIXME */
- .suspend = snd_gusclassic_suspend,
- .remove = snd_gusclassic_remove,
-#endif
- .driver = {
- .name = DEV_NAME
- }
-};
-
-static int __init alsa_card_gusclassic_init(void)
-{
- return isa_register_driver(&snd_gusclassic_driver, SNDRV_CARDS);
-}
-
-static void __exit alsa_card_gusclassic_exit(void)
-{
- isa_unregister_driver(&snd_gusclassic_driver);
-}
-
-module_init(alsa_card_gusclassic_init);
-module_exit(alsa_card_gusclassic_exit);
diff --git a/ANDROID_3.4.5/sound/isa/gus/gusextreme.c b/ANDROID_3.4.5/sound/isa/gus/gusextreme.c
deleted file mode 100644
index bc10cc26..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/gusextreme.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * Driver for Gravis UltraSound Extreme soundcards
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/isa.h>
-#include <linux/delay.h>
-#include <linux/time.h>
-#include <linux/module.h>
-#include <asm/dma.h>
-#include <sound/core.h>
-#include <sound/gus.h>
-#include <sound/es1688.h>
-#include <sound/mpu401.h>
-#include <sound/opl3.h>
-#define SNDRV_LEGACY_AUTO_PROBE
-#define SNDRV_LEGACY_FIND_FREE_IRQ
-#define SNDRV_LEGACY_FIND_FREE_DMA
-#include <sound/initval.h>
-
-#define CRD_NAME "Gravis UltraSound Extreme"
-#define DEV_NAME "gusextreme"
-
-MODULE_DESCRIPTION(CRD_NAME);
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Extreme}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */
-static long gf1_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS) - 1] = -1}; /* 0x210,0x220,0x230,0x240,0x250,0x260,0x270 */
-static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS) - 1] = -1}; /* 0x300,0x310,0x320 */
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */
-static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */
-static int gf1_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 2,3,5,9,11,12,15 */
-static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3 */
-static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
-static int joystick_dac[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 29};
- /* 0 to 31, (0.59V-4.52V or 0.389V-2.98V) */
-static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24};
-static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
-module_param_array(gf1_port, long, NULL, 0444);
-MODULE_PARM_DESC(gf1_port, "GF1 port # for " CRD_NAME " driver (optional).");
-module_param_array(mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
-module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
-module_param_array(mpu_irq, int, NULL, 0444);
-MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
-module_param_array(gf1_irq, int, NULL, 0444);
-MODULE_PARM_DESC(gf1_irq, "GF1 IRQ # for " CRD_NAME " driver.");
-module_param_array(dma8, int, NULL, 0444);
-MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver.");
-module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "GF1 DMA # for " CRD_NAME " driver.");
-module_param_array(joystick_dac, int, NULL, 0444);
-MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for " CRD_NAME " driver.");
-module_param_array(channels, int, NULL, 0444);
-MODULE_PARM_DESC(channels, "GF1 channels for " CRD_NAME " driver.");
-module_param_array(pcm_channels, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for " CRD_NAME " driver.");
-
-static int __devinit snd_gusextreme_match(struct device *dev, unsigned int n)
-{
- return enable[n];
-}
-
-static int __devinit snd_gusextreme_es1688_create(struct snd_card *card,
- struct snd_es1688 *chip, struct device *dev, unsigned int n)
-{
- static long possible_ports[] = {0x220, 0x240, 0x260};
- static int possible_irqs[] = {5, 9, 10, 7, -1};
- static int possible_dmas[] = {1, 3, 0, -1};
-
- int i, error;
-
- if (irq[n] == SNDRV_AUTO_IRQ) {
- irq[n] = snd_legacy_find_free_irq(possible_irqs);
- if (irq[n] < 0) {
- dev_err(dev, "unable to find a free IRQ for ES1688\n");
- return -EBUSY;
- }
- }
- if (dma8[n] == SNDRV_AUTO_DMA) {
- dma8[n] = snd_legacy_find_free_dma(possible_dmas);
- if (dma8[n] < 0) {
- dev_err(dev, "unable to find a free DMA for ES1688\n");
- return -EBUSY;
- }
- }
-
- if (port[n] != SNDRV_AUTO_PORT)
- return snd_es1688_create(card, chip, port[n], mpu_port[n],
- irq[n], mpu_irq[n], dma8[n], ES1688_HW_1688);
-
- i = 0;
- do {
- port[n] = possible_ports[i];
- error = snd_es1688_create(card, chip, port[n], mpu_port[n],
- irq[n], mpu_irq[n], dma8[n], ES1688_HW_1688);
- } while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
-
- return error;
-}
-
-static int __devinit snd_gusextreme_gus_card_create(struct snd_card *card,
- struct device *dev, unsigned int n, struct snd_gus_card **rgus)
-{
- static int possible_irqs[] = {11, 12, 15, 9, 5, 7, 3, -1};
- static int possible_dmas[] = {5, 6, 7, 3, 1, -1};
-
- if (gf1_irq[n] == SNDRV_AUTO_IRQ) {
- gf1_irq[n] = snd_legacy_find_free_irq(possible_irqs);
- if (gf1_irq[n] < 0) {
- dev_err(dev, "unable to find a free IRQ for GF1\n");
- return -EBUSY;
- }
- }
- if (dma1[n] == SNDRV_AUTO_DMA) {
- dma1[n] = snd_legacy_find_free_dma(possible_dmas);
- if (dma1[n] < 0) {
- dev_err(dev, "unable to find a free DMA for GF1\n");
- return -EBUSY;
- }
- }
- return snd_gus_create(card, gf1_port[n], gf1_irq[n], dma1[n], -1,
- 0, channels[n], pcm_channels[n], 0, rgus);
-}
-
-static int __devinit snd_gusextreme_detect(struct snd_gus_card *gus,
- struct snd_es1688 *es1688)
-{
- unsigned long flags;
- unsigned char d;
-
- /*
- * This is main stuff - enable access to GF1 chip...
- * I'm not sure, if this will work for card which have
- * ES1688 chip in another place than 0x220.
- *
- * I used reverse-engineering in DOSEMU. [--jk]
- *
- * ULTRINIT.EXE:
- * 0x230 = 0,2,3
- * 0x240 = 2,0,1
- * 0x250 = 2,0,3
- * 0x260 = 2,2,1
- */
-
- spin_lock_irqsave(&es1688->mixer_lock, flags);
- snd_es1688_mixer_write(es1688, 0x40, 0x0b); /* don't change!!! */
- spin_unlock_irqrestore(&es1688->mixer_lock, flags);
-
- spin_lock_irqsave(&es1688->reg_lock, flags);
- outb(gus->gf1.port & 0x040 ? 2 : 0, ES1688P(es1688, INIT1));
- outb(0, 0x201);
- outb(gus->gf1.port & 0x020 ? 2 : 0, ES1688P(es1688, INIT1));
- outb(0, 0x201);
- outb(gus->gf1.port & 0x010 ? 3 : 1, ES1688P(es1688, INIT1));
- spin_unlock_irqrestore(&es1688->reg_lock, flags);
-
- udelay(100);
-
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
- snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
- return -EIO;
- }
- udelay(160);
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* release reset */
- udelay(160);
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
- snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
- return -EIO;
- }
-
- return 0;
-}
-
-static int __devinit snd_gusextreme_mixer(struct snd_card *card)
-{
- struct snd_ctl_elem_id id1, id2;
- int error;
-
- memset(&id1, 0, sizeof(id1));
- memset(&id2, 0, sizeof(id2));
- id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-
- /* reassign AUX to SYNTHESIZER */
- strcpy(id1.name, "Aux Playback Volume");
- strcpy(id2.name, "Synth Playback Volume");
- error = snd_ctl_rename_id(card, &id1, &id2);
- if (error < 0)
- return error;
-
- /* reassign Master Playback Switch to Synth Playback Switch */
- strcpy(id1.name, "Master Playback Switch");
- strcpy(id2.name, "Synth Playback Switch");
- error = snd_ctl_rename_id(card, &id1, &id2);
- if (error < 0)
- return error;
-
- return 0;
-}
-
-static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
-{
- struct snd_card *card;
- struct snd_gus_card *gus;
- struct snd_es1688 *es1688;
- struct snd_opl3 *opl3;
- int error;
-
- error = snd_card_create(index[n], id[n], THIS_MODULE,
- sizeof(struct snd_es1688), &card);
- if (error < 0)
- return error;
-
- es1688 = card->private_data;
-
- if (mpu_port[n] == SNDRV_AUTO_PORT)
- mpu_port[n] = 0;
-
- if (mpu_irq[n] > 15)
- mpu_irq[n] = -1;
-
- error = snd_gusextreme_es1688_create(card, es1688, dev, n);
- if (error < 0)
- goto out;
-
- if (gf1_port[n] < 0)
- gf1_port[n] = es1688->port + 0x20;
-
- error = snd_gusextreme_gus_card_create(card, dev, n, &gus);
- if (error < 0)
- goto out;
-
- error = snd_gusextreme_detect(gus, es1688);
- if (error < 0)
- goto out;
-
- gus->joystick_dac = joystick_dac[n];
-
- error = snd_gus_initialize(gus);
- if (error < 0)
- goto out;
-
- error = -ENODEV;
- if (!gus->ess_flag) {
- dev_err(dev, "GUS Extreme soundcard was not "
- "detected at 0x%lx\n", gus->gf1.port);
- goto out;
- }
- gus->codec_flag = 1;
-
- error = snd_es1688_pcm(card, es1688, 0, NULL);
- if (error < 0)
- goto out;
-
- error = snd_es1688_mixer(card, es1688);
- if (error < 0)
- goto out;
-
- snd_component_add(card, "ES1688");
-
- if (pcm_channels[n] > 0) {
- error = snd_gf1_pcm_new(gus, 1, 1, NULL);
- if (error < 0)
- goto out;
- }
-
- error = snd_gf1_new_mixer(gus);
- if (error < 0)
- goto out;
-
- error = snd_gusextreme_mixer(card);
- if (error < 0)
- goto out;
-
- if (snd_opl3_create(card, es1688->port, es1688->port + 2,
- OPL3_HW_OPL3, 0, &opl3) < 0)
- dev_warn(dev, "opl3 not detected at 0x%lx\n", es1688->port);
- else {
- error = snd_opl3_hwdep_new(opl3, 0, 2, NULL);
- if (error < 0)
- goto out;
- }
-
- if (es1688->mpu_port >= 0x300) {
- error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
- es1688->mpu_port, 0, mpu_irq[n], NULL);
- if (error < 0)
- goto out;
- }
-
- sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, "
- "irq %i&%i, dma %i&%i", es1688->port,
- gus->gf1.irq, es1688->irq, gus->gf1.dma1, es1688->dma8);
-
- snd_card_set_dev(card, dev);
-
- error = snd_card_register(card);
- if (error < 0)
- goto out;
-
- dev_set_drvdata(dev, card);
- return 0;
-
-out: snd_card_free(card);
- return error;
-}
-
-static int __devexit snd_gusextreme_remove(struct device *dev, unsigned int n)
-{
- snd_card_free(dev_get_drvdata(dev));
- dev_set_drvdata(dev, NULL);
- return 0;
-}
-
-static struct isa_driver snd_gusextreme_driver = {
- .match = snd_gusextreme_match,
- .probe = snd_gusextreme_probe,
- .remove = __devexit_p(snd_gusextreme_remove),
-#if 0 /* FIXME */
- .suspend = snd_gusextreme_suspend,
- .resume = snd_gusextreme_resume,
-#endif
- .driver = {
- .name = DEV_NAME
- }
-};
-
-static int __init alsa_card_gusextreme_init(void)
-{
- return isa_register_driver(&snd_gusextreme_driver, SNDRV_CARDS);
-}
-
-static void __exit alsa_card_gusextreme_exit(void)
-{
- isa_unregister_driver(&snd_gusextreme_driver);
-}
-
-module_init(alsa_card_gusextreme_init);
-module_exit(alsa_card_gusextreme_exit);
diff --git a/ANDROID_3.4.5/sound/isa/gus/gusmax.c b/ANDROID_3.4.5/sound/isa/gus/gusmax.c
deleted file mode 100644
index 41c3f448..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/gusmax.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * Driver for Gravis UltraSound MAX soundcard
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/isa.h>
-#include <linux/delay.h>
-#include <linux/time.h>
-#include <linux/module.h>
-#include <asm/dma.h>
-#include <sound/core.h>
-#include <sound/gus.h>
-#include <sound/wss.h>
-#define SNDRV_LEGACY_FIND_FREE_IRQ
-#define SNDRV_LEGACY_FIND_FREE_DMA
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Gravis UltraSound MAX");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound MAX}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x230,0x240,0x250,0x260 */
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 2,3,5,9,11,12,15 */
-static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3,5,6,7 */
-static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3,5,6,7 */
-static int joystick_dac[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 29};
- /* 0 to 31, (0.59V-4.52V or 0.389V-2.98V) */
-static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24};
-static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for GUS MAX soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for GUS MAX soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable GUS MAX soundcard.");
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for GUS MAX driver.");
-module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for GUS MAX driver.");
-module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "DMA1 # for GUS MAX driver.");
-module_param_array(dma2, int, NULL, 0444);
-MODULE_PARM_DESC(dma2, "DMA2 # for GUS MAX driver.");
-module_param_array(joystick_dac, int, NULL, 0444);
-MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for GUS MAX driver.");
-module_param_array(channels, int, NULL, 0444);
-MODULE_PARM_DESC(channels, "Used GF1 channels for GUS MAX driver.");
-module_param_array(pcm_channels, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS MAX driver.");
-
-struct snd_gusmax {
- int irq;
- struct snd_card *card;
- struct snd_gus_card *gus;
- struct snd_wss *wss;
- unsigned short gus_status_reg;
- unsigned short pcm_status_reg;
-};
-
-#define PFX "gusmax: "
-
-static int __devinit snd_gusmax_detect(struct snd_gus_card * gus)
-{
- unsigned char d;
-
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
- snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
- return -ENODEV;
- }
- udelay(160);
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* release reset */
- udelay(160);
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
- snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
- return -ENODEV;
- }
-
- return 0;
-}
-
-static irqreturn_t snd_gusmax_interrupt(int irq, void *dev_id)
-{
- struct snd_gusmax *maxcard = dev_id;
- int loop, max = 5;
- int handled = 0;
-
- do {
- loop = 0;
- if (inb(maxcard->gus_status_reg)) {
- handled = 1;
- snd_gus_interrupt(irq, maxcard->gus);
- loop++;
- }
- if (inb(maxcard->pcm_status_reg) & 0x01) { /* IRQ bit is set? */
- handled = 1;
- snd_wss_interrupt(irq, maxcard->wss);
- loop++;
- }
- } while (loop && --max > 0);
- return IRQ_RETVAL(handled);
-}
-
-static void __devinit snd_gusmax_init(int dev, struct snd_card *card,
- struct snd_gus_card * gus)
-{
- gus->equal_irq = 1;
- gus->codec_flag = 1;
- gus->joystick_dac = joystick_dac[dev];
- /* init control register */
- gus->max_cntrl_val = (gus->gf1.port >> 4) & 0x0f;
- if (gus->gf1.dma1 > 3)
- gus->max_cntrl_val |= 0x10;
- if (gus->gf1.dma2 > 3)
- gus->max_cntrl_val |= 0x20;
- gus->max_cntrl_val |= 0x40;
- outb(gus->max_cntrl_val, GUSP(gus, MAXCNTRLPORT));
-}
-
-static int __devinit snd_gusmax_mixer(struct snd_wss *chip)
-{
- struct snd_card *card = chip->card;
- struct snd_ctl_elem_id id1, id2;
- int err;
-
- memset(&id1, 0, sizeof(id1));
- memset(&id2, 0, sizeof(id2));
- id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- /* reassign AUXA to SYNTHESIZER */
- strcpy(id1.name, "Aux Playback Switch");
- strcpy(id2.name, "Synth Playback Switch");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
- return err;
- strcpy(id1.name, "Aux Playback Volume");
- strcpy(id2.name, "Synth Playback Volume");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
- return err;
- /* reassign AUXB to CD */
- strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
- strcpy(id2.name, "CD Playback Switch");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
- return err;
- strcpy(id1.name, "Aux Playback Volume");
- strcpy(id2.name, "CD Playback Volume");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
- return err;
-#if 0
- /* reassign Mono Input to MIC */
- if (snd_mixer_group_rename(mixer,
- SNDRV_MIXER_IN_MONO, 0,
- SNDRV_MIXER_IN_MIC, 0) < 0)
- goto __error;
- if (snd_mixer_elem_rename(mixer,
- SNDRV_MIXER_IN_MONO, 0, SNDRV_MIXER_ETYPE_INPUT,
- SNDRV_MIXER_IN_MIC, 0) < 0)
- goto __error;
- if (snd_mixer_elem_rename(mixer,
- "Mono Capture Volume", 0, SNDRV_MIXER_ETYPE_VOLUME1,
- "Mic Capture Volume", 0) < 0)
- goto __error;
- if (snd_mixer_elem_rename(mixer,
- "Mono Capture Switch", 0, SNDRV_MIXER_ETYPE_SWITCH1,
- "Mic Capture Switch", 0) < 0)
- goto __error;
-#endif
- return 0;
-}
-
-static void snd_gusmax_free(struct snd_card *card)
-{
- struct snd_gusmax *maxcard = card->private_data;
-
- if (maxcard == NULL)
- return;
- if (maxcard->irq >= 0)
- free_irq(maxcard->irq, (void *)maxcard);
-}
-
-static int __devinit snd_gusmax_match(struct device *pdev, unsigned int dev)
-{
- return enable[dev];
-}
-
-static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev)
-{
- static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
- static int possible_dmas[] = {5, 6, 7, 1, 3, -1};
- int xirq, xdma1, xdma2, err;
- struct snd_card *card;
- struct snd_gus_card *gus = NULL;
- struct snd_wss *wss;
- struct snd_gusmax *maxcard;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_gusmax), &card);
- if (err < 0)
- return err;
- card->private_free = snd_gusmax_free;
- maxcard = card->private_data;
- maxcard->card = card;
- maxcard->irq = -1;
-
- xirq = irq[dev];
- if (xirq == SNDRV_AUTO_IRQ) {
- if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
- err = -EBUSY;
- goto _err;
- }
- }
- xdma1 = dma1[dev];
- if (xdma1 == SNDRV_AUTO_DMA) {
- if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
- err = -EBUSY;
- goto _err;
- }
- }
- xdma2 = dma2[dev];
- if (xdma2 == SNDRV_AUTO_DMA) {
- if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
- err = -EBUSY;
- goto _err;
- }
- }
-
- if (port[dev] != SNDRV_AUTO_PORT) {
- err = snd_gus_create(card,
- port[dev],
- -xirq, xdma1, xdma2,
- 0, channels[dev],
- pcm_channels[dev],
- 0, &gus);
- } else {
- static unsigned long possible_ports[] = {
- 0x220, 0x230, 0x240, 0x250, 0x260
- };
- int i;
- for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
- err = snd_gus_create(card,
- possible_ports[i],
- -xirq, xdma1, xdma2,
- 0, channels[dev],
- pcm_channels[dev],
- 0, &gus);
- if (err >= 0) {
- port[dev] = possible_ports[i];
- break;
- }
- }
- }
- if (err < 0)
- goto _err;
-
- if ((err = snd_gusmax_detect(gus)) < 0)
- goto _err;
-
- maxcard->gus_status_reg = gus->gf1.reg_irqstat;
- maxcard->pcm_status_reg = gus->gf1.port + 0x10c + 2;
- snd_gusmax_init(dev, card, gus);
- if ((err = snd_gus_initialize(gus)) < 0)
- goto _err;
-
- if (!gus->max_flag) {
- snd_printk(KERN_ERR PFX "GUS MAX soundcard was not detected at 0x%lx\n", gus->gf1.port);
- err = -ENODEV;
- goto _err;
- }
-
- if (request_irq(xirq, snd_gusmax_interrupt, 0, "GUS MAX", (void *)maxcard)) {
- snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq);
- err = -EBUSY;
- goto _err;
- }
- maxcard->irq = xirq;
-
- err = snd_wss_create(card,
- gus->gf1.port + 0x10c, -1, xirq,
- xdma2 < 0 ? xdma1 : xdma2, xdma1,
- WSS_HW_DETECT,
- WSS_HWSHARE_IRQ |
- WSS_HWSHARE_DMA1 |
- WSS_HWSHARE_DMA2,
- &wss);
- if (err < 0)
- goto _err;
-
- err = snd_wss_pcm(wss, 0, NULL);
- if (err < 0)
- goto _err;
-
- err = snd_wss_mixer(wss);
- if (err < 0)
- goto _err;
-
- err = snd_wss_timer(wss, 2, NULL);
- if (err < 0)
- goto _err;
-
- if (pcm_channels[dev] > 0) {
- if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0)
- goto _err;
- }
- err = snd_gusmax_mixer(wss);
- if (err < 0)
- goto _err;
-
- err = snd_gf1_rawmidi_new(gus, 0, NULL);
- if (err < 0)
- goto _err;
-
- sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %i, dma %i", gus->gf1.port, xirq, xdma1);
- if (xdma2 >= 0)
- sprintf(card->longname + strlen(card->longname), "&%i", xdma2);
-
- snd_card_set_dev(card, pdev);
-
- err = snd_card_register(card);
- if (err < 0)
- goto _err;
-
- maxcard->gus = gus;
- maxcard->wss = wss;
-
- dev_set_drvdata(pdev, card);
- return 0;
-
- _err:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit snd_gusmax_remove(struct device *devptr, unsigned int dev)
-{
- snd_card_free(dev_get_drvdata(devptr));
- dev_set_drvdata(devptr, NULL);
- return 0;
-}
-
-#define DEV_NAME "gusmax"
-
-static struct isa_driver snd_gusmax_driver = {
- .match = snd_gusmax_match,
- .probe = snd_gusmax_probe,
- .remove = __devexit_p(snd_gusmax_remove),
- /* FIXME: suspend/resume */
- .driver = {
- .name = DEV_NAME
- },
-};
-
-static int __init alsa_card_gusmax_init(void)
-{
- return isa_register_driver(&snd_gusmax_driver, SNDRV_CARDS);
-}
-
-static void __exit alsa_card_gusmax_exit(void)
-{
- isa_unregister_driver(&snd_gusmax_driver);
-}
-
-module_init(alsa_card_gusmax_init)
-module_exit(alsa_card_gusmax_exit)
diff --git a/ANDROID_3.4.5/sound/isa/gus/interwave-stb.c b/ANDROID_3.4.5/sound/isa/gus/interwave-stb.c
deleted file mode 100644
index dbe4f48a..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/interwave-stb.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define SNDRV_STB
-#include "interwave.c"
diff --git a/ANDROID_3.4.5/sound/isa/gus/interwave.c b/ANDROID_3.4.5/sound/isa/gus/interwave.c
deleted file mode 100644
index a76bc8d2..00000000
--- a/ANDROID_3.4.5/sound/isa/gus/interwave.c
+++ /dev/null
@@ -1,947 +0,0 @@
-/*
- * Driver for AMD InterWave soundcard
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * 1999/07/22 Erik Inge Bolso <knan@mo.himolde.no>
- * * mixer group handlers
- *
- */
-
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/isa.h>
-#include <linux/delay.h>
-#include <linux/pnp.h>
-#include <linux/module.h>
-#include <asm/dma.h>
-#include <sound/core.h>
-#include <sound/gus.h>
-#include <sound/wss.h>
-#ifdef SNDRV_STB
-#include <sound/tea6330t.h>
-#endif
-#define SNDRV_LEGACY_FIND_FREE_IRQ
-#define SNDRV_LEGACY_FIND_FREE_DMA
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_LICENSE("GPL");
-#ifndef SNDRV_STB
-MODULE_DESCRIPTION("AMD InterWave");
-MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Plug & Play},"
- "{STB,SoundRage32},"
- "{MED,MED3210},"
- "{Dynasonix,Dynasonix Pro},"
- "{Panasonic,PCA761AW}}");
-#else
-MODULE_DESCRIPTION("AMD InterWave STB with TEA6330T");
-MODULE_SUPPORTED_DEVICE("{{AMD,InterWave STB with TEA6330T}}");
-#endif
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
-#ifdef CONFIG_PNP
-static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
-#endif
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x210,0x220,0x230,0x240,0x250,0x260 */
-#ifdef SNDRV_STB
-static long port_tc[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x350,0x360,0x370,0x380 */
-#endif
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 2,3,5,9,11,12,15 */
-static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
-static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
-static int joystick_dac[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 29};
- /* 0 to 31, (0.59V-4.52V or 0.389V-2.98V) */
-static int midi[SNDRV_CARDS];
-static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
-static int effect[SNDRV_CARDS];
-
-#ifdef SNDRV_STB
-#define PFX "interwave-stb: "
-#define INTERWAVE_DRIVER "snd_interwave_stb"
-#define INTERWAVE_PNP_DRIVER "interwave-stb"
-#else
-#define PFX "interwave: "
-#define INTERWAVE_DRIVER "snd_interwave"
-#define INTERWAVE_PNP_DRIVER "interwave"
-#endif
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for InterWave soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for InterWave soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable InterWave soundcard.");
-#ifdef CONFIG_PNP
-module_param_array(isapnp, bool, NULL, 0444);
-MODULE_PARM_DESC(isapnp, "ISA PnP detection for specified soundcard.");
-#endif
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for InterWave driver.");
-#ifdef SNDRV_STB
-module_param_array(port_tc, long, NULL, 0444);
-MODULE_PARM_DESC(port_tc, "Tone control (TEA6330T - i2c bus) port # for InterWave driver.");
-#endif
-module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for InterWave driver.");
-module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "DMA1 # for InterWave driver.");
-module_param_array(dma2, int, NULL, 0444);
-MODULE_PARM_DESC(dma2, "DMA2 # for InterWave driver.");
-module_param_array(joystick_dac, int, NULL, 0444);
-MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for InterWave driver.");
-module_param_array(midi, int, NULL, 0444);
-MODULE_PARM_DESC(midi, "MIDI UART enable for InterWave driver.");
-module_param_array(pcm_channels, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for InterWave driver.");
-module_param_array(effect, int, NULL, 0444);
-MODULE_PARM_DESC(effect, "Effects enable for InterWave driver.");
-
-struct snd_interwave {
- int irq;
- struct snd_card *card;
- struct snd_gus_card *gus;
- struct snd_wss *wss;
-#ifdef SNDRV_STB
- struct resource *i2c_res;
-#endif
- unsigned short gus_status_reg;
- unsigned short pcm_status_reg;
-#ifdef CONFIG_PNP
- struct pnp_dev *dev;
-#ifdef SNDRV_STB
- struct pnp_dev *devtc;
-#endif
-#endif
-};
-
-
-#ifdef CONFIG_PNP
-static int isa_registered;
-static int pnp_registered;
-
-static struct pnp_card_device_id snd_interwave_pnpids[] = {
-#ifndef SNDRV_STB
- /* Gravis UltraSound Plug & Play */
- { .id = "GRV0001", .devs = { { .id = "GRV0000" } } },
- /* STB SoundRage32 */
- { .id = "STB011a", .devs = { { .id = "STB0010" } } },
- /* MED3210 */
- { .id = "DXP3201", .devs = { { .id = "DXP0010" } } },
- /* Dynasonic Pro */
- /* This device also have CDC1117:DynaSonix Pro Audio Effects Processor */
- { .id = "CDC1111", .devs = { { .id = "CDC1112" } } },
- /* Panasonic PCA761AW Audio Card */
- { .id = "ADV55ff", .devs = { { .id = "ADV0010" } } },
- /* InterWave STB without TEA6330T */
- { .id = "ADV550a", .devs = { { .id = "ADV0010" } } },
-#else
- /* InterWave STB with TEA6330T */
- { .id = "ADV550a", .devs = { { .id = "ADV0010" }, { .id = "ADV0015" } } },
-#endif
- { .id = "" }
-};
-
-MODULE_DEVICE_TABLE(pnp_card, snd_interwave_pnpids);
-
-#endif /* CONFIG_PNP */
-
-
-#ifdef SNDRV_STB
-static void snd_interwave_i2c_setlines(struct snd_i2c_bus *bus, int ctrl, int data)
-{
- unsigned long port = bus->private_value;
-
-#if 0
- printk(KERN_DEBUG "i2c_setlines - 0x%lx <- %i,%i\n", port, ctrl, data);
-#endif
- outb((data << 1) | ctrl, port);
- udelay(10);
-}
-
-static int snd_interwave_i2c_getclockline(struct snd_i2c_bus *bus)
-{
- unsigned long port = bus->private_value;
- unsigned char res;
-
- res = inb(port) & 1;
-#if 0
- printk(KERN_DEBUG "i2c_getclockline - 0x%lx -> %i\n", port, res);
-#endif
- return res;
-}
-
-static int snd_interwave_i2c_getdataline(struct snd_i2c_bus *bus, int ack)
-{
- unsigned long port = bus->private_value;
- unsigned char res;
-
- if (ack)
- udelay(10);
- res = (inb(port) & 2) >> 1;
-#if 0
- printk(KERN_DEBUG "i2c_getdataline - 0x%lx -> %i\n", port, res);
-#endif
- return res;
-}
-
-static struct snd_i2c_bit_ops snd_interwave_i2c_bit_ops = {
- .setlines = snd_interwave_i2c_setlines,
- .getclock = snd_interwave_i2c_getclockline,
- .getdata = snd_interwave_i2c_getdataline,
-};
-
-static int __devinit snd_interwave_detect_stb(struct snd_interwave *iwcard,
- struct snd_gus_card * gus, int dev,
- struct snd_i2c_bus **rbus)
-{
- unsigned long port;
- struct snd_i2c_bus *bus;
- struct snd_card *card = iwcard->card;
- char name[32];
- int err;
-
- *rbus = NULL;
- port = port_tc[dev];
- if (port == SNDRV_AUTO_PORT) {
- port = 0x350;
- if (gus->gf1.port == 0x250) {
- port = 0x360;
- }
- while (port <= 0x380) {
- if ((iwcard->i2c_res = request_region(port, 1, "InterWave (I2C bus)")) != NULL)
- break;
- port += 0x10;
- }
- } else {
- iwcard->i2c_res = request_region(port, 1, "InterWave (I2C bus)");
- }
- if (iwcard->i2c_res == NULL) {
- snd_printk(KERN_ERR "interwave: can't grab i2c bus port\n");
- return -ENODEV;
- }
-
- sprintf(name, "InterWave-%i", card->number);
- if ((err = snd_i2c_bus_create(card, name, NULL, &bus)) < 0)
- return err;
- bus->private_value = port;
- bus->hw_ops.bit = &snd_interwave_i2c_bit_ops;
- if ((err = snd_tea6330t_detect(bus, 0)) < 0)
- return err;
- *rbus = bus;
- return 0;
-}
-#endif
-
-static int __devinit snd_interwave_detect(struct snd_interwave *iwcard,
- struct snd_gus_card * gus,
- int dev
-#ifdef SNDRV_STB
- , struct snd_i2c_bus **rbus
-#endif
- )
-{
- unsigned long flags;
- unsigned char rev1, rev2;
- int d;
-
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
- snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
- return -ENODEV;
- }
- udelay(160);
- snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* release reset */
- udelay(160);
- if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
- snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
- return -ENODEV;
- }
- spin_lock_irqsave(&gus->reg_lock, flags);
- rev1 = snd_gf1_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER);
- snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, ~rev1);
- rev2 = snd_gf1_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER);
- snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, rev1);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- snd_printdd("[0x%lx] InterWave check - rev1=0x%x, rev2=0x%x\n", gus->gf1.port, rev1, rev2);
- if ((rev1 & 0xf0) == (rev2 & 0xf0) &&
- (rev1 & 0x0f) != (rev2 & 0x0f)) {
- snd_printdd("[0x%lx] InterWave check - passed\n", gus->gf1.port);
- gus->interwave = 1;
- strcpy(gus->card->shortname, "AMD InterWave");
- gus->revision = rev1 >> 4;
-#ifndef SNDRV_STB
- return 0; /* ok.. We have an InterWave board */
-#else
- return snd_interwave_detect_stb(iwcard, gus, dev, rbus);
-#endif
- }
- snd_printdd("[0x%lx] InterWave check - failed\n", gus->gf1.port);
- return -ENODEV;
-}
-
-static irqreturn_t snd_interwave_interrupt(int irq, void *dev_id)
-{
- struct snd_interwave *iwcard = dev_id;
- int loop, max = 5;
- int handled = 0;
-
- do {
- loop = 0;
- if (inb(iwcard->gus_status_reg)) {
- handled = 1;
- snd_gus_interrupt(irq, iwcard->gus);
- loop++;
- }
- if (inb(iwcard->pcm_status_reg) & 0x01) { /* IRQ bit is set? */
- handled = 1;
- snd_wss_interrupt(irq, iwcard->wss);
- loop++;
- }
- } while (loop && --max > 0);
- return IRQ_RETVAL(handled);
-}
-
-static void __devinit snd_interwave_reset(struct snd_gus_card * gus)
-{
- snd_gf1_write8(gus, SNDRV_GF1_GB_RESET, 0x00);
- udelay(160);
- snd_gf1_write8(gus, SNDRV_GF1_GB_RESET, 0x01);
- udelay(160);
-}
-
-static void __devinit snd_interwave_bank_sizes(struct snd_gus_card * gus, int *sizes)
-{
- unsigned int idx;
- unsigned int local;
- unsigned char d;
-
- for (idx = 0; idx < 4; idx++) {
- sizes[idx] = 0;
- d = 0x55;
- for (local = idx << 22;
- local < (idx << 22) + 0x400000;
- local += 0x40000, d++) {
- snd_gf1_poke(gus, local, d);
- snd_gf1_poke(gus, local + 1, d + 1);
-#if 0
- printk(KERN_DEBUG "d = 0x%x, local = 0x%x, "
- "local + 1 = 0x%x, idx << 22 = 0x%x\n",
- d,
- snd_gf1_peek(gus, local),
- snd_gf1_peek(gus, local + 1),
- snd_gf1_peek(gus, idx << 22));
-#endif
- if (snd_gf1_peek(gus, local) != d ||
- snd_gf1_peek(gus, local + 1) != d + 1 ||
- snd_gf1_peek(gus, idx << 22) != 0x55)
- break;
- sizes[idx]++;
- }
- }
-#if 0
- printk(KERN_DEBUG "sizes: %i %i %i %i\n",
- sizes[0], sizes[1], sizes[2], sizes[3]);
-#endif
-}
-
-struct rom_hdr {
- /* 000 */ unsigned char iwave[8];
- /* 008 */ unsigned char rom_hdr_revision;
- /* 009 */ unsigned char series_number;
- /* 010 */ unsigned char series_name[16];
- /* 026 */ unsigned char date[10];
- /* 036 */ unsigned short vendor_revision_major;
- /* 038 */ unsigned short vendor_revision_minor;
- /* 040 */ unsigned int rom_size;
- /* 044 */ unsigned char copyright[128];
- /* 172 */ unsigned char vendor_name[64];
- /* 236 */ unsigned char rom_description[128];
- /* 364 */ unsigned char pad[147];
- /* 511 */ unsigned char csum;
-};
-
-static void __devinit snd_interwave_detect_memory(struct snd_gus_card * gus)
-{
- static unsigned int lmc[13] =
- {
- 0x00000001, 0x00000101, 0x01010101, 0x00000401,
- 0x04040401, 0x00040101, 0x04040101, 0x00000004,
- 0x00000404, 0x04040404, 0x00000010, 0x00001010,
- 0x10101010
- };
-
- int bank_pos, pages;
- unsigned int i, lmct;
- int psizes[4];
- unsigned char iwave[8];
- unsigned char csum;
-
- snd_interwave_reset(gus);
- snd_gf1_write8(gus, SNDRV_GF1_GB_GLOBAL_MODE, snd_gf1_read8(gus, SNDRV_GF1_GB_GLOBAL_MODE) | 0x01); /* enhanced mode */
- snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01); /* DRAM I/O cycles selected */
- snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xff10) | 0x004c);
- /* ok.. simple test of memory size */
- pages = 0;
- snd_gf1_poke(gus, 0, 0x55);
- snd_gf1_poke(gus, 1, 0xaa);
-#if 1
- if (snd_gf1_peek(gus, 0) == 0x55 && snd_gf1_peek(gus, 1) == 0xaa)
-#else
- if (0) /* ok.. for testing of 0k RAM */
-#endif
- {
- snd_interwave_bank_sizes(gus, psizes);
- lmct = (psizes[3] << 24) | (psizes[2] << 16) |
- (psizes[1] << 8) | psizes[0];
-#if 0
- printk(KERN_DEBUG "lmct = 0x%08x\n", lmct);
-#endif
- for (i = 0; i < ARRAY_SIZE(lmc); i++)
- if (lmct == lmc[i]) {
-#if 0
- printk(KERN_DEBUG "found !!! %i\n", i);
-#endif
- snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xfff0) | i);
- snd_interwave_bank_sizes(gus, psizes);
- break;
- }
- if (i >= ARRAY_SIZE(lmc) && !gus->gf1.enh_mode)
- snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xfff0) | 2);
- for (i = 0; i < 4; i++) {
- gus->gf1.mem_alloc.banks_8[i].address =
- gus->gf1.mem_alloc.banks_16[i].address = i << 22;
- gus->gf1.mem_alloc.banks_8[i].size =
- gus->gf1.mem_alloc.banks_16[i].size = psizes[i] << 18;
- pages += psizes[i];
- }
- }
- pages <<= 18;
- gus->gf1.memory = pages;
-
- snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x03); /* select ROM */
- snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xff1f) | (4 << 5));
- gus->gf1.rom_banks = 0;
- gus->gf1.rom_memory = 0;
- for (bank_pos = 0; bank_pos < 16L * 1024L * 1024L; bank_pos += 4L * 1024L * 1024L) {
- for (i = 0; i < 8; ++i)
- iwave[i] = snd_gf1_peek(gus, bank_pos + i);
-#ifdef CONFIG_SND_DEBUG_ROM
- printk(KERN_DEBUG "ROM at 0x%06x = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", bank_pos,
- iwave[0], iwave[1], iwave[2], iwave[3],
- iwave[4], iwave[5], iwave[6], iwave[7]);
-#endif
- if (strncmp(iwave, "INTRWAVE", 8))
- continue; /* first check */
- csum = 0;
- for (i = 0; i < sizeof(struct rom_hdr); i++)
- csum += snd_gf1_peek(gus, bank_pos + i);
-#ifdef CONFIG_SND_DEBUG_ROM
- printk(KERN_DEBUG "ROM checksum = 0x%x (computed)\n", csum);
-#endif
- if (csum != 0)
- continue; /* not valid rom */
- gus->gf1.rom_banks++;
- gus->gf1.rom_present |= 1 << (bank_pos >> 22);
- gus->gf1.rom_memory = snd_gf1_peek(gus, bank_pos + 40) |
- (snd_gf1_peek(gus, bank_pos + 41) << 8) |
- (snd_gf1_peek(gus, bank_pos + 42) << 16) |
- (snd_gf1_peek(gus, bank_pos + 43) << 24);
- }
-#if 0
- if (gus->gf1.rom_memory > 0) {
- if (gus->gf1.rom_banks == 1 && gus->gf1.rom_present == 8)
- gus->card->type = SNDRV_CARD_TYPE_IW_DYNASONIC;
- }
-#endif
- snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x00); /* select RAM */
-
- if (!gus->gf1.enh_mode)
- snd_interwave_reset(gus);
-}
-
-static void __devinit snd_interwave_init(int dev, struct snd_gus_card * gus)
-{
- unsigned long flags;
-
- /* ok.. some InterWave specific initialization */
- spin_lock_irqsave(&gus->reg_lock, flags);
- snd_gf1_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, 0x00);
- snd_gf1_write8(gus, SNDRV_GF1_GB_COMPATIBILITY, 0x1f);
- snd_gf1_write8(gus, SNDRV_GF1_GB_DECODE_CONTROL, 0x49);
- snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, 0x11);
- snd_gf1_write8(gus, SNDRV_GF1_GB_MPU401_CONTROL_A, 0x00);
- snd_gf1_write8(gus, SNDRV_GF1_GB_MPU401_CONTROL_B, 0x30);
- snd_gf1_write8(gus, SNDRV_GF1_GB_EMULATION_IRQ, 0x00);
- spin_unlock_irqrestore(&gus->reg_lock, flags);
- gus->equal_irq = 1;
- gus->codec_flag = 1;
- gus->interwave = 1;
- gus->max_flag = 1;
- gus->joystick_dac = joystick_dac[dev];
-
-}
-
-static struct snd_kcontrol_new snd_interwave_controls[] = {
-WSS_DOUBLE("Master Playback Switch", 0,
- CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 7, 7, 1, 1),
-WSS_DOUBLE("Master Playback Volume", 0,
- CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 0, 0, 31, 1),
-WSS_DOUBLE("Mic Playback Switch", 0,
- CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 7, 7, 1, 1),
-WSS_DOUBLE("Mic Playback Volume", 0,
- CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 0, 0, 31, 1)
-};
-
-static int __devinit snd_interwave_mixer(struct snd_wss *chip)
-{
- struct snd_card *card = chip->card;
- struct snd_ctl_elem_id id1, id2;
- unsigned int idx;
- int err;
-
- memset(&id1, 0, sizeof(id1));
- memset(&id2, 0, sizeof(id2));
- id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-#if 0
- /* remove mono microphone controls */
- strcpy(id1.name, "Mic Playback Switch");
- if ((err = snd_ctl_remove_id(card, &id1)) < 0)
- return err;
- strcpy(id1.name, "Mic Playback Volume");
- if ((err = snd_ctl_remove_id(card, &id1)) < 0)
- return err;
-#endif
- /* add new master and mic controls */
- for (idx = 0; idx < ARRAY_SIZE(snd_interwave_controls); idx++)
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_interwave_controls[idx], chip))) < 0)
- return err;
- snd_wss_out(chip, CS4231_LINE_LEFT_OUTPUT, 0x9f);
- snd_wss_out(chip, CS4231_LINE_RIGHT_OUTPUT, 0x9f);
- snd_wss_out(chip, CS4231_LEFT_MIC_INPUT, 0x9f);
- snd_wss_out(chip, CS4231_RIGHT_MIC_INPUT, 0x9f);
- /* reassign AUXA to SYNTHESIZER */
- strcpy(id1.name, "Aux Playback Switch");
- strcpy(id2.name, "Synth Playback Switch");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
- return err;
- strcpy(id1.name, "Aux Playback Volume");
- strcpy(id2.name, "Synth Playback Volume");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
- return err;
- /* reassign AUXB to CD */
- strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
- strcpy(id2.name, "CD Playback Switch");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
- return err;
- strcpy(id1.name, "Aux Playback Volume");
- strcpy(id2.name, "CD Playback Volume");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
- return err;
- return 0;
-}
-
-#ifdef CONFIG_PNP
-
-static int __devinit snd_interwave_pnp(int dev, struct snd_interwave *iwcard,
- struct pnp_card_link *card,
- const struct pnp_card_device_id *id)
-{
- struct pnp_dev *pdev;
- int err;
-
- iwcard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
- if (iwcard->dev == NULL)
- return -EBUSY;
-
-#ifdef SNDRV_STB
- iwcard->devtc = pnp_request_card_device(card, id->devs[1].id, NULL);
- if (iwcard->devtc == NULL)
- return -EBUSY;
-#endif
- /* Synth & Codec initialization */
- pdev = iwcard->dev;
-
- err = pnp_activate_dev(pdev);
- if (err < 0) {
- snd_printk(KERN_ERR "InterWave PnP configure failure (out of resources?)\n");
- return err;
- }
- if (pnp_port_start(pdev, 0) + 0x100 != pnp_port_start(pdev, 1) ||
- pnp_port_start(pdev, 0) + 0x10c != pnp_port_start(pdev, 2)) {
- snd_printk(KERN_ERR "PnP configure failure (wrong ports)\n");
- return -ENOENT;
- }
- port[dev] = pnp_port_start(pdev, 0);
- dma1[dev] = pnp_dma(pdev, 0);
- if (dma2[dev] >= 0)
- dma2[dev] = pnp_dma(pdev, 1);
- irq[dev] = pnp_irq(pdev, 0);
- snd_printdd("isapnp IW: sb port=0x%llx, gf1 port=0x%llx, codec port=0x%llx\n",
- (unsigned long long)pnp_port_start(pdev, 0),
- (unsigned long long)pnp_port_start(pdev, 1),
- (unsigned long long)pnp_port_start(pdev, 2));
- snd_printdd("isapnp IW: dma1=%i, dma2=%i, irq=%i\n", dma1[dev], dma2[dev], irq[dev]);
-#ifdef SNDRV_STB
- /* Tone Control initialization */
- pdev = iwcard->devtc;
-
- err = pnp_activate_dev(pdev);
- if (err < 0) {
- snd_printk(KERN_ERR "InterWave ToneControl PnP configure failure (out of resources?)\n");
- return err;
- }
- port_tc[dev] = pnp_port_start(pdev, 0);
- snd_printdd("isapnp IW: tone control port=0x%lx\n", port_tc[dev]);
-#endif
- return 0;
-}
-#endif /* CONFIG_PNP */
-
-static void snd_interwave_free(struct snd_card *card)
-{
- struct snd_interwave *iwcard = card->private_data;
-
- if (iwcard == NULL)
- return;
-#ifdef SNDRV_STB
- release_and_free_resource(iwcard->i2c_res);
-#endif
- if (iwcard->irq >= 0)
- free_irq(iwcard->irq, (void *)iwcard);
-}
-
-static int snd_interwave_card_new(int dev, struct snd_card **cardp)
-{
- struct snd_card *card;
- struct snd_interwave *iwcard;
- int err;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_interwave), &card);
- if (err < 0)
- return err;
- iwcard = card->private_data;
- iwcard->card = card;
- iwcard->irq = -1;
- card->private_free = snd_interwave_free;
- *cardp = card;
- return 0;
-}
-
-static int __devinit snd_interwave_probe(struct snd_card *card, int dev)
-{
- int xirq, xdma1, xdma2;
- struct snd_interwave *iwcard = card->private_data;
- struct snd_wss *wss;
- struct snd_gus_card *gus;
-#ifdef SNDRV_STB
- struct snd_i2c_bus *i2c_bus;
-#endif
- struct snd_pcm *pcm;
- char *str;
- int err;
-
- xirq = irq[dev];
- xdma1 = dma1[dev];
- xdma2 = dma2[dev];
-
- if ((err = snd_gus_create(card,
- port[dev],
- -xirq, xdma1, xdma2,
- 0, 32,
- pcm_channels[dev], effect[dev], &gus)) < 0)
- return err;
-
- if ((err = snd_interwave_detect(iwcard, gus, dev
-#ifdef SNDRV_STB
- , &i2c_bus
-#endif
- )) < 0)
- return err;
-
- iwcard->gus_status_reg = gus->gf1.reg_irqstat;
- iwcard->pcm_status_reg = gus->gf1.port + 0x10c + 2;
-
- snd_interwave_init(dev, gus);
- snd_interwave_detect_memory(gus);
- if ((err = snd_gus_initialize(gus)) < 0)
- return err;
-
- if (request_irq(xirq, snd_interwave_interrupt, 0,
- "InterWave", iwcard)) {
- snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq);
- return -EBUSY;
- }
- iwcard->irq = xirq;
-
- err = snd_wss_create(card,
- gus->gf1.port + 0x10c, -1, xirq,
- xdma2 < 0 ? xdma1 : xdma2, xdma1,
- WSS_HW_INTERWAVE,
- WSS_HWSHARE_IRQ |
- WSS_HWSHARE_DMA1 |
- WSS_HWSHARE_DMA2,
- &wss);
- if (err < 0)
- return err;
-
- err = snd_wss_pcm(wss, 0, &pcm);
- if (err < 0)
- return err;
-
- sprintf(pcm->name + strlen(pcm->name), " rev %c", gus->revision + 'A');
- strcat(pcm->name, " (codec)");
-
- err = snd_wss_timer(wss, 2, NULL);
- if (err < 0)
- return err;
-
- err = snd_wss_mixer(wss);
- if (err < 0)
- return err;
-
- if (pcm_channels[dev] > 0) {
- err = snd_gf1_pcm_new(gus, 1, 1, NULL);
- if (err < 0)
- return err;
- }
- err = snd_interwave_mixer(wss);
- if (err < 0)
- return err;
-
-#ifdef SNDRV_STB
- {
- struct snd_ctl_elem_id id1, id2;
- memset(&id1, 0, sizeof(id1));
- memset(&id2, 0, sizeof(id2));
- id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(id1.name, "Master Playback Switch");
- strcpy(id2.name, id1.name);
- id2.index = 1;
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
- return err;
- strcpy(id1.name, "Master Playback Volume");
- strcpy(id2.name, id1.name);
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
- return err;
- if ((err = snd_tea6330t_update_mixer(card, i2c_bus, 0, 1)) < 0)
- return err;
- }
-#endif
-
- gus->uart_enable = midi[dev];
- if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0)
- return err;
-
-#ifndef SNDRV_STB
- str = "AMD InterWave";
- if (gus->gf1.rom_banks == 1 && gus->gf1.rom_present == 8)
- str = "Dynasonic 3-D";
-#else
- str = "InterWave STB";
-#endif
- strcpy(card->driver, str);
- strcpy(card->shortname, str);
- sprintf(card->longname, "%s at 0x%lx, irq %i, dma %d",
- str,
- gus->gf1.port,
- xirq,
- xdma1);
- if (xdma2 >= 0)
- sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
-
- err = snd_card_register(card);
- if (err < 0)
- return err;
-
- iwcard->wss = wss;
- iwcard->gus = gus;
- return 0;
-}
-
-static int __devinit snd_interwave_isa_probe1(int dev, struct device *devptr)
-{
- struct snd_card *card;
- int err;
-
- err = snd_interwave_card_new(dev, &card);
- if (err < 0)
- return err;
-
- snd_card_set_dev(card, devptr);
- if ((err = snd_interwave_probe(card, dev)) < 0) {
- snd_card_free(card);
- return err;
- }
- dev_set_drvdata(devptr, card);
- return 0;
-}
-
-static int __devinit snd_interwave_isa_match(struct device *pdev,
- unsigned int dev)
-{
- if (!enable[dev])
- return 0;
-#ifdef CONFIG_PNP
- if (isapnp[dev])
- return 0;
-#endif
- return 1;
-}
-
-static int __devinit snd_interwave_isa_probe(struct device *pdev,
- unsigned int dev)
-{
- int err;
- static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
- static int possible_dmas[] = {0, 1, 3, 5, 6, 7, -1};
-
- if (irq[dev] == SNDRV_AUTO_IRQ) {
- if ((irq[dev] = snd_legacy_find_free_irq(possible_irqs)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
- return -EBUSY;
- }
- }
- if (dma1[dev] == SNDRV_AUTO_DMA) {
- if ((dma1[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
- return -EBUSY;
- }
- }
- if (dma2[dev] == SNDRV_AUTO_DMA) {
- if ((dma2[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
- return -EBUSY;
- }
- }
-
- if (port[dev] != SNDRV_AUTO_PORT)
- return snd_interwave_isa_probe1(dev, pdev);
- else {
- static long possible_ports[] = {0x210, 0x220, 0x230, 0x240, 0x250, 0x260};
- int i;
- for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
- port[dev] = possible_ports[i];
- err = snd_interwave_isa_probe1(dev, pdev);
- if (! err)
- return 0;
- }
- return err;
- }
-}
-
-static int __devexit snd_interwave_isa_remove(struct device *devptr, unsigned int dev)
-{
- snd_card_free(dev_get_drvdata(devptr));
- dev_set_drvdata(devptr, NULL);
- return 0;
-}
-
-static struct isa_driver snd_interwave_driver = {
- .match = snd_interwave_isa_match,
- .probe = snd_interwave_isa_probe,
- .remove = __devexit_p(snd_interwave_isa_remove),
- /* FIXME: suspend,resume */
- .driver = {
- .name = INTERWAVE_DRIVER
- },
-};
-
-#ifdef CONFIG_PNP
-static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard,
- const struct pnp_card_device_id *pid)
-{
- static int dev;
- struct snd_card *card;
- int res;
-
- for ( ; dev < SNDRV_CARDS; dev++) {
- if (enable[dev] && isapnp[dev])
- break;
- }
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
-
- res = snd_interwave_card_new(dev, &card);
- if (res < 0)
- return res;
-
- if ((res = snd_interwave_pnp(dev, card->private_data, pcard, pid)) < 0) {
- snd_card_free(card);
- return res;
- }
- snd_card_set_dev(card, &pcard->card->dev);
- if ((res = snd_interwave_probe(card, dev)) < 0) {
- snd_card_free(card);
- return res;
- }
- pnp_set_card_drvdata(pcard, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_interwave_pnp_remove(struct pnp_card_link * pcard)
-{
- snd_card_free(pnp_get_card_drvdata(pcard));
- pnp_set_card_drvdata(pcard, NULL);
-}
-
-static struct pnp_card_driver interwave_pnpc_driver = {
- .flags = PNP_DRIVER_RES_DISABLE,
- .name = INTERWAVE_PNP_DRIVER,
- .id_table = snd_interwave_pnpids,
- .probe = snd_interwave_pnp_detect,
- .remove = __devexit_p(snd_interwave_pnp_remove),
- /* FIXME: suspend,resume */
-};
-
-#endif /* CONFIG_PNP */
-
-static int __init alsa_card_interwave_init(void)
-{
- int err;
-
- err = isa_register_driver(&snd_interwave_driver, SNDRV_CARDS);
-#ifdef CONFIG_PNP
- if (!err)
- isa_registered = 1;
-
- err = pnp_register_card_driver(&interwave_pnpc_driver);
- if (!err)
- pnp_registered = 1;
-
- if (isa_registered)
- err = 0;
-#endif
- return err;
-}
-
-static void __exit alsa_card_interwave_exit(void)
-{
-#ifdef CONFIG_PNP
- if (pnp_registered)
- pnp_unregister_card_driver(&interwave_pnpc_driver);
- if (isa_registered)
-#endif
- isa_unregister_driver(&snd_interwave_driver);
-}
-
-module_init(alsa_card_interwave_init)
-module_exit(alsa_card_interwave_exit)
diff --git a/ANDROID_3.4.5/sound/isa/msnd/Makefile b/ANDROID_3.4.5/sound/isa/msnd/Makefile
deleted file mode 100644
index 2171c0aa..00000000
--- a/ANDROID_3.4.5/sound/isa/msnd/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-
-snd-msnd-lib-objs := msnd.o msnd_midi.o msnd_pinnacle_mixer.o
-snd-msnd-pinnacle-objs := msnd_pinnacle.o
-snd-msnd-classic-objs := msnd_classic.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_MSND_PINNACLE) += snd-msnd-pinnacle.o snd-msnd-lib.o
-obj-$(CONFIG_SND_MSND_CLASSIC) += snd-msnd-classic.o snd-msnd-lib.o
-
diff --git a/ANDROID_3.4.5/sound/isa/msnd/msnd.c b/ANDROID_3.4.5/sound/isa/msnd/msnd.c
deleted file mode 100644
index 1cee18fb..00000000
--- a/ANDROID_3.4.5/sound/isa/msnd/msnd.c
+++ /dev/null
@@ -1,708 +0,0 @@
-/*********************************************************************
- *
- * 2002/06/30 Karsten Wiese:
- * removed kernel-version dependencies.
- * ripped from linux kernel 2.4.18 (OSS Implementation) by me.
- * In the OSS Version, this file is compiled to a separate MODULE,
- * that is used by the pinnacle and the classic driver.
- * since there is no classic driver for alsa yet (i dont have a classic
- * & writing one blindfold is difficult) this file's object is statically
- * linked into the pinnacle-driver-module for now. look for the string
- * "uncomment this to make this a module again"
- * to do guess what.
- *
- * the following is a copy of the 2.4.18 OSS FREE file-heading comment:
- *
- * msnd.c - Driver Base
- *
- * Turtle Beach MultiSound Sound Card Driver for Linux
- *
- * Copyright (C) 1998 Andrew Veliath
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ********************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/fs.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-
-#include "msnd.h"
-
-#define LOGNAME "msnd"
-
-
-void snd_msnd_init_queue(void *base, int start, int size)
-{
- writew(PCTODSP_BASED(start), base + JQS_wStart);
- writew(PCTODSP_OFFSET(size) - 1, base + JQS_wSize);
- writew(0, base + JQS_wHead);
- writew(0, base + JQS_wTail);
-}
-EXPORT_SYMBOL(snd_msnd_init_queue);
-
-static int snd_msnd_wait_TXDE(struct snd_msnd *dev)
-{
- unsigned int io = dev->io;
- int timeout = 1000;
-
- while (timeout-- > 0)
- if (inb(io + HP_ISR) & HPISR_TXDE)
- return 0;
-
- return -EIO;
-}
-
-static int snd_msnd_wait_HC0(struct snd_msnd *dev)
-{
- unsigned int io = dev->io;
- int timeout = 1000;
-
- while (timeout-- > 0)
- if (!(inb(io + HP_CVR) & HPCVR_HC))
- return 0;
-
- return -EIO;
-}
-
-int snd_msnd_send_dsp_cmd(struct snd_msnd *dev, u8 cmd)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&dev->lock, flags);
- if (snd_msnd_wait_HC0(dev) == 0) {
- outb(cmd, dev->io + HP_CVR);
- spin_unlock_irqrestore(&dev->lock, flags);
- return 0;
- }
- spin_unlock_irqrestore(&dev->lock, flags);
-
- snd_printd(KERN_ERR LOGNAME ": Send DSP command timeout\n");
-
- return -EIO;
-}
-EXPORT_SYMBOL(snd_msnd_send_dsp_cmd);
-
-int snd_msnd_send_word(struct snd_msnd *dev, unsigned char high,
- unsigned char mid, unsigned char low)
-{
- unsigned int io = dev->io;
-
- if (snd_msnd_wait_TXDE(dev) == 0) {
- outb(high, io + HP_TXH);
- outb(mid, io + HP_TXM);
- outb(low, io + HP_TXL);
- return 0;
- }
-
- snd_printd(KERN_ERR LOGNAME ": Send host word timeout\n");
-
- return -EIO;
-}
-EXPORT_SYMBOL(snd_msnd_send_word);
-
-int snd_msnd_upload_host(struct snd_msnd *dev, const u8 *bin, int len)
-{
- int i;
-
- if (len % 3 != 0) {
- snd_printk(KERN_ERR LOGNAME
- ": Upload host data not multiple of 3!\n");
- return -EINVAL;
- }
-
- for (i = 0; i < len; i += 3)
- if (snd_msnd_send_word(dev, bin[i], bin[i + 1], bin[i + 2]))
- return -EIO;
-
- inb(dev->io + HP_RXL);
- inb(dev->io + HP_CVR);
-
- return 0;
-}
-EXPORT_SYMBOL(snd_msnd_upload_host);
-
-int snd_msnd_enable_irq(struct snd_msnd *dev)
-{
- unsigned long flags;
-
- if (dev->irq_ref++)
- return 0;
-
- snd_printdd(LOGNAME ": Enabling IRQ\n");
-
- spin_lock_irqsave(&dev->lock, flags);
- if (snd_msnd_wait_TXDE(dev) == 0) {
- outb(inb(dev->io + HP_ICR) | HPICR_TREQ, dev->io + HP_ICR);
- if (dev->type == msndClassic)
- outb(dev->irqid, dev->io + HP_IRQM);
-
- outb(inb(dev->io + HP_ICR) & ~HPICR_TREQ, dev->io + HP_ICR);
- outb(inb(dev->io + HP_ICR) | HPICR_RREQ, dev->io + HP_ICR);
- enable_irq(dev->irq);
- snd_msnd_init_queue(dev->DSPQ, dev->dspq_data_buff,
- dev->dspq_buff_size);
- spin_unlock_irqrestore(&dev->lock, flags);
- return 0;
- }
- spin_unlock_irqrestore(&dev->lock, flags);
-
- snd_printd(KERN_ERR LOGNAME ": Enable IRQ failed\n");
-
- return -EIO;
-}
-EXPORT_SYMBOL(snd_msnd_enable_irq);
-
-int snd_msnd_disable_irq(struct snd_msnd *dev)
-{
- unsigned long flags;
-
- if (--dev->irq_ref > 0)
- return 0;
-
- if (dev->irq_ref < 0)
- snd_printd(KERN_WARNING LOGNAME ": IRQ ref count is %d\n",
- dev->irq_ref);
-
- snd_printdd(LOGNAME ": Disabling IRQ\n");
-
- spin_lock_irqsave(&dev->lock, flags);
- if (snd_msnd_wait_TXDE(dev) == 0) {
- outb(inb(dev->io + HP_ICR) & ~HPICR_RREQ, dev->io + HP_ICR);
- if (dev->type == msndClassic)
- outb(HPIRQ_NONE, dev->io + HP_IRQM);
- disable_irq(dev->irq);
- spin_unlock_irqrestore(&dev->lock, flags);
- return 0;
- }
- spin_unlock_irqrestore(&dev->lock, flags);
-
- snd_printd(KERN_ERR LOGNAME ": Disable IRQ failed\n");
-
- return -EIO;
-}
-EXPORT_SYMBOL(snd_msnd_disable_irq);
-
-static inline long get_play_delay_jiffies(struct snd_msnd *chip, long size)
-{
- long tmp = (size * HZ * chip->play_sample_size) / 8;
- return tmp / (chip->play_sample_rate * chip->play_channels);
-}
-
-static void snd_msnd_dsp_write_flush(struct snd_msnd *chip)
-{
- if (!(chip->mode & FMODE_WRITE) || !test_bit(F_WRITING, &chip->flags))
- return;
- set_bit(F_WRITEFLUSH, &chip->flags);
-/* interruptible_sleep_on_timeout(
- &chip->writeflush,
- get_play_delay_jiffies(&chip, chip->DAPF.len));*/
- clear_bit(F_WRITEFLUSH, &chip->flags);
- if (!signal_pending(current))
- schedule_timeout_interruptible(
- get_play_delay_jiffies(chip, chip->play_period_bytes));
- clear_bit(F_WRITING, &chip->flags);
-}
-
-void snd_msnd_dsp_halt(struct snd_msnd *chip, struct file *file)
-{
- if ((file ? file->f_mode : chip->mode) & FMODE_READ) {
- clear_bit(F_READING, &chip->flags);
- snd_msnd_send_dsp_cmd(chip, HDEX_RECORD_STOP);
- snd_msnd_disable_irq(chip);
- if (file) {
- snd_printd(KERN_INFO LOGNAME
- ": Stopping read for %p\n", file);
- chip->mode &= ~FMODE_READ;
- }
- clear_bit(F_AUDIO_READ_INUSE, &chip->flags);
- }
- if ((file ? file->f_mode : chip->mode) & FMODE_WRITE) {
- if (test_bit(F_WRITING, &chip->flags)) {
- snd_msnd_dsp_write_flush(chip);
- snd_msnd_send_dsp_cmd(chip, HDEX_PLAY_STOP);
- }
- snd_msnd_disable_irq(chip);
- if (file) {
- snd_printd(KERN_INFO
- LOGNAME ": Stopping write for %p\n", file);
- chip->mode &= ~FMODE_WRITE;
- }
- clear_bit(F_AUDIO_WRITE_INUSE, &chip->flags);
- }
-}
-EXPORT_SYMBOL(snd_msnd_dsp_halt);
-
-
-int snd_msnd_DARQ(struct snd_msnd *chip, int bank)
-{
- int /*size, n,*/ timeout = 3;
- u16 wTmp;
- /* void *DAQD; */
-
- /* Increment the tail and check for queue wrap */
- wTmp = readw(chip->DARQ + JQS_wTail) + PCTODSP_OFFSET(DAQDS__size);
- if (wTmp > readw(chip->DARQ + JQS_wSize))
- wTmp = 0;
- while (wTmp == readw(chip->DARQ + JQS_wHead) && timeout--)
- udelay(1);
-
- if (chip->capturePeriods == 2) {
- void *pDAQ = chip->mappedbase + DARQ_DATA_BUFF +
- bank * DAQDS__size + DAQDS_wStart;
- unsigned short offset = 0x3000 + chip->capturePeriodBytes;
-
- if (readw(pDAQ) != PCTODSP_BASED(0x3000))
- offset = 0x3000;
- writew(PCTODSP_BASED(offset), pDAQ);
- }
-
- writew(wTmp, chip->DARQ + JQS_wTail);
-
-#if 0
- /* Get our digital audio queue struct */
- DAQD = bank * DAQDS__size + chip->mappedbase + DARQ_DATA_BUFF;
-
- /* Get length of data */
- size = readw(DAQD + DAQDS_wSize);
-
- /* Read data from the head (unprotected bank 1 access okay
- since this is only called inside an interrupt) */
- outb(HPBLKSEL_1, chip->io + HP_BLKS);
- n = msnd_fifo_write(&chip->DARF,
- (char *)(chip->base + bank * DAR_BUFF_SIZE),
- size, 0);
- if (n <= 0) {
- outb(HPBLKSEL_0, chip->io + HP_BLKS);
- return n;
- }
- outb(HPBLKSEL_0, chip->io + HP_BLKS);
-#endif
-
- return 1;
-}
-EXPORT_SYMBOL(snd_msnd_DARQ);
-
-int snd_msnd_DAPQ(struct snd_msnd *chip, int start)
-{
- u16 DAPQ_tail;
- int protect = start, nbanks = 0;
- void *DAQD;
- static int play_banks_submitted;
- /* unsigned long flags;
- spin_lock_irqsave(&chip->lock, flags); not necessary */
-
- DAPQ_tail = readw(chip->DAPQ + JQS_wTail);
- while (DAPQ_tail != readw(chip->DAPQ + JQS_wHead) || start) {
- int bank_num = DAPQ_tail / PCTODSP_OFFSET(DAQDS__size);
-
- if (start) {
- start = 0;
- play_banks_submitted = 0;
- }
-
- /* Get our digital audio queue struct */
- DAQD = bank_num * DAQDS__size + chip->mappedbase +
- DAPQ_DATA_BUFF;
-
- /* Write size of this bank */
- writew(chip->play_period_bytes, DAQD + DAQDS_wSize);
- if (play_banks_submitted < 3)
- ++play_banks_submitted;
- else if (chip->playPeriods == 2) {
- unsigned short offset = chip->play_period_bytes;
-
- if (readw(DAQD + DAQDS_wStart) != PCTODSP_BASED(0x0))
- offset = 0;
-
- writew(PCTODSP_BASED(offset), DAQD + DAQDS_wStart);
- }
- ++nbanks;
-
- /* Then advance the tail */
- /*
- if (protect)
- snd_printd(KERN_INFO "B %X %lX\n",
- bank_num, xtime.tv_usec);
- */
-
- DAPQ_tail = (++bank_num % 3) * PCTODSP_OFFSET(DAQDS__size);
- writew(DAPQ_tail, chip->DAPQ + JQS_wTail);
- /* Tell the DSP to play the bank */
- snd_msnd_send_dsp_cmd(chip, HDEX_PLAY_START);
- if (protect)
- if (2 == bank_num)
- break;
- }
- /*
- if (protect)
- snd_printd(KERN_INFO "%lX\n", xtime.tv_usec);
- */
- /* spin_unlock_irqrestore(&chip->lock, flags); not necessary */
- return nbanks;
-}
-EXPORT_SYMBOL(snd_msnd_DAPQ);
-
-static void snd_msnd_play_reset_queue(struct snd_msnd *chip,
- unsigned int pcm_periods,
- unsigned int pcm_count)
-{
- int n;
- void *pDAQ = chip->mappedbase + DAPQ_DATA_BUFF;
-
- chip->last_playbank = -1;
- chip->playLimit = pcm_count * (pcm_periods - 1);
- chip->playPeriods = pcm_periods;
- writew(PCTODSP_OFFSET(0 * DAQDS__size), chip->DAPQ + JQS_wHead);
- writew(PCTODSP_OFFSET(0 * DAQDS__size), chip->DAPQ + JQS_wTail);
-
- chip->play_period_bytes = pcm_count;
-
- for (n = 0; n < pcm_periods; ++n, pDAQ += DAQDS__size) {
- writew(PCTODSP_BASED((u32)(pcm_count * n)),
- pDAQ + DAQDS_wStart);
- writew(0, pDAQ + DAQDS_wSize);
- writew(1, pDAQ + DAQDS_wFormat);
- writew(chip->play_sample_size, pDAQ + DAQDS_wSampleSize);
- writew(chip->play_channels, pDAQ + DAQDS_wChannels);
- writew(chip->play_sample_rate, pDAQ + DAQDS_wSampleRate);
- writew(HIMT_PLAY_DONE * 0x100 + n, pDAQ + DAQDS_wIntMsg);
- writew(n, pDAQ + DAQDS_wFlags);
- }
-}
-
-static void snd_msnd_capture_reset_queue(struct snd_msnd *chip,
- unsigned int pcm_periods,
- unsigned int pcm_count)
-{
- int n;
- void *pDAQ;
- /* unsigned long flags; */
-
- /* snd_msnd_init_queue(chip->DARQ, DARQ_DATA_BUFF, DARQ_BUFF_SIZE); */
-
- chip->last_recbank = 2;
- chip->captureLimit = pcm_count * (pcm_periods - 1);
- chip->capturePeriods = pcm_periods;
- writew(PCTODSP_OFFSET(0 * DAQDS__size), chip->DARQ + JQS_wHead);
- writew(PCTODSP_OFFSET(chip->last_recbank * DAQDS__size),
- chip->DARQ + JQS_wTail);
-
-#if 0 /* Critical section: bank 1 access. this is how the OSS driver does it:*/
- spin_lock_irqsave(&chip->lock, flags);
- outb(HPBLKSEL_1, chip->io + HP_BLKS);
- memset_io(chip->mappedbase, 0, DAR_BUFF_SIZE * 3);
- outb(HPBLKSEL_0, chip->io + HP_BLKS);
- spin_unlock_irqrestore(&chip->lock, flags);
-#endif
-
- chip->capturePeriodBytes = pcm_count;
- snd_printdd("snd_msnd_capture_reset_queue() %i\n", pcm_count);
-
- pDAQ = chip->mappedbase + DARQ_DATA_BUFF;
-
- for (n = 0; n < pcm_periods; ++n, pDAQ += DAQDS__size) {
- u32 tmp = pcm_count * n;
-
- writew(PCTODSP_BASED(tmp + 0x3000), pDAQ + DAQDS_wStart);
- writew(pcm_count, pDAQ + DAQDS_wSize);
- writew(1, pDAQ + DAQDS_wFormat);
- writew(chip->capture_sample_size, pDAQ + DAQDS_wSampleSize);
- writew(chip->capture_channels, pDAQ + DAQDS_wChannels);
- writew(chip->capture_sample_rate, pDAQ + DAQDS_wSampleRate);
- writew(HIMT_RECORD_DONE * 0x100 + n, pDAQ + DAQDS_wIntMsg);
- writew(n, pDAQ + DAQDS_wFlags);
- }
-}
-
-static struct snd_pcm_hardware snd_msnd_playback = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BATCH,
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 0x3000,
- .period_bytes_min = 0x40,
- .period_bytes_max = 0x1800,
- .periods_min = 2,
- .periods_max = 3,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_msnd_capture = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BATCH,
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 0x3000,
- .period_bytes_min = 0x40,
- .period_bytes_max = 0x1800,
- .periods_min = 2,
- .periods_max = 3,
- .fifo_size = 0,
-};
-
-
-static int snd_msnd_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_msnd *chip = snd_pcm_substream_chip(substream);
-
- set_bit(F_AUDIO_WRITE_INUSE, &chip->flags);
- clear_bit(F_WRITING, &chip->flags);
- snd_msnd_enable_irq(chip);
-
- runtime->dma_area = chip->mappedbase;
- runtime->dma_bytes = 0x3000;
-
- chip->playback_substream = substream;
- runtime->hw = snd_msnd_playback;
- return 0;
-}
-
-static int snd_msnd_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_msnd *chip = snd_pcm_substream_chip(substream);
-
- snd_msnd_disable_irq(chip);
- clear_bit(F_AUDIO_WRITE_INUSE, &chip->flags);
- return 0;
-}
-
-
-static int snd_msnd_playback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- int i;
- struct snd_msnd *chip = snd_pcm_substream_chip(substream);
- void *pDAQ = chip->mappedbase + DAPQ_DATA_BUFF;
-
- chip->play_sample_size = snd_pcm_format_width(params_format(params));
- chip->play_channels = params_channels(params);
- chip->play_sample_rate = params_rate(params);
-
- for (i = 0; i < 3; ++i, pDAQ += DAQDS__size) {
- writew(chip->play_sample_size, pDAQ + DAQDS_wSampleSize);
- writew(chip->play_channels, pDAQ + DAQDS_wChannels);
- writew(chip->play_sample_rate, pDAQ + DAQDS_wSampleRate);
- }
- /* dont do this here:
- * snd_msnd_calibrate_adc(chip->play_sample_rate);
- */
-
- return 0;
-}
-
-static int snd_msnd_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_msnd *chip = snd_pcm_substream_chip(substream);
- unsigned int pcm_size = snd_pcm_lib_buffer_bytes(substream);
- unsigned int pcm_count = snd_pcm_lib_period_bytes(substream);
- unsigned int pcm_periods = pcm_size / pcm_count;
-
- snd_msnd_play_reset_queue(chip, pcm_periods, pcm_count);
- chip->playDMAPos = 0;
- return 0;
-}
-
-static int snd_msnd_playback_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_msnd *chip = snd_pcm_substream_chip(substream);
- int result = 0;
-
- if (cmd == SNDRV_PCM_TRIGGER_START) {
- snd_printdd("snd_msnd_playback_trigger(START)\n");
- chip->banksPlayed = 0;
- set_bit(F_WRITING, &chip->flags);
- snd_msnd_DAPQ(chip, 1);
- } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
- snd_printdd("snd_msnd_playback_trigger(STop)\n");
- /* interrupt diagnostic, comment this out later */
- clear_bit(F_WRITING, &chip->flags);
- snd_msnd_send_dsp_cmd(chip, HDEX_PLAY_STOP);
- } else {
- snd_printd(KERN_ERR "snd_msnd_playback_trigger(?????)\n");
- result = -EINVAL;
- }
-
- snd_printdd("snd_msnd_playback_trigger() ENDE\n");
- return result;
-}
-
-static snd_pcm_uframes_t
-snd_msnd_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_msnd *chip = snd_pcm_substream_chip(substream);
-
- return bytes_to_frames(substream->runtime, chip->playDMAPos);
-}
-
-
-static struct snd_pcm_ops snd_msnd_playback_ops = {
- .open = snd_msnd_playback_open,
- .close = snd_msnd_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_msnd_playback_hw_params,
- .prepare = snd_msnd_playback_prepare,
- .trigger = snd_msnd_playback_trigger,
- .pointer = snd_msnd_playback_pointer,
-};
-
-static int snd_msnd_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_msnd *chip = snd_pcm_substream_chip(substream);
-
- set_bit(F_AUDIO_READ_INUSE, &chip->flags);
- snd_msnd_enable_irq(chip);
- runtime->dma_area = chip->mappedbase + 0x3000;
- runtime->dma_bytes = 0x3000;
- memset(runtime->dma_area, 0, runtime->dma_bytes);
- chip->capture_substream = substream;
- runtime->hw = snd_msnd_capture;
- return 0;
-}
-
-static int snd_msnd_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_msnd *chip = snd_pcm_substream_chip(substream);
-
- snd_msnd_disable_irq(chip);
- clear_bit(F_AUDIO_READ_INUSE, &chip->flags);
- return 0;
-}
-
-static int snd_msnd_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_msnd *chip = snd_pcm_substream_chip(substream);
- unsigned int pcm_size = snd_pcm_lib_buffer_bytes(substream);
- unsigned int pcm_count = snd_pcm_lib_period_bytes(substream);
- unsigned int pcm_periods = pcm_size / pcm_count;
-
- snd_msnd_capture_reset_queue(chip, pcm_periods, pcm_count);
- chip->captureDMAPos = 0;
- return 0;
-}
-
-static int snd_msnd_capture_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_msnd *chip = snd_pcm_substream_chip(substream);
-
- if (cmd == SNDRV_PCM_TRIGGER_START) {
- chip->last_recbank = -1;
- set_bit(F_READING, &chip->flags);
- if (snd_msnd_send_dsp_cmd(chip, HDEX_RECORD_START) == 0)
- return 0;
-
- clear_bit(F_READING, &chip->flags);
- } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
- clear_bit(F_READING, &chip->flags);
- snd_msnd_send_dsp_cmd(chip, HDEX_RECORD_STOP);
- return 0;
- }
- return -EINVAL;
-}
-
-
-static snd_pcm_uframes_t
-snd_msnd_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_msnd *chip = snd_pcm_substream_chip(substream);
-
- return bytes_to_frames(runtime, chip->captureDMAPos);
-}
-
-
-static int snd_msnd_capture_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- int i;
- struct snd_msnd *chip = snd_pcm_substream_chip(substream);
- void *pDAQ = chip->mappedbase + DARQ_DATA_BUFF;
-
- chip->capture_sample_size = snd_pcm_format_width(params_format(params));
- chip->capture_channels = params_channels(params);
- chip->capture_sample_rate = params_rate(params);
-
- for (i = 0; i < 3; ++i, pDAQ += DAQDS__size) {
- writew(chip->capture_sample_size, pDAQ + DAQDS_wSampleSize);
- writew(chip->capture_channels, pDAQ + DAQDS_wChannels);
- writew(chip->capture_sample_rate, pDAQ + DAQDS_wSampleRate);
- }
- return 0;
-}
-
-
-static struct snd_pcm_ops snd_msnd_capture_ops = {
- .open = snd_msnd_capture_open,
- .close = snd_msnd_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_msnd_capture_hw_params,
- .prepare = snd_msnd_capture_prepare,
- .trigger = snd_msnd_capture_trigger,
- .pointer = snd_msnd_capture_pointer,
-};
-
-
-int snd_msnd_pcm(struct snd_card *card, int device,
- struct snd_pcm **rpcm)
-{
- struct snd_msnd *chip = card->private_data;
- struct snd_pcm *pcm;
- int err;
-
- err = snd_pcm_new(card, "MSNDPINNACLE", device, 1, 1, &pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_msnd_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_msnd_capture_ops);
-
- pcm->private_data = chip;
- strcpy(pcm->name, "Hurricane");
-
-
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-EXPORT_SYMBOL(snd_msnd_pcm);
-
-MODULE_DESCRIPTION("Common routines for Turtle Beach Multisound drivers");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/isa/msnd/msnd.h b/ANDROID_3.4.5/sound/isa/msnd/msnd.h
deleted file mode 100644
index a168ba33..00000000
--- a/ANDROID_3.4.5/sound/isa/msnd/msnd.h
+++ /dev/null
@@ -1,308 +0,0 @@
-/*********************************************************************
- *
- * msnd.h
- *
- * Turtle Beach MultiSound Sound Card Driver for Linux
- *
- * Some parts of this header file were derived from the Turtle Beach
- * MultiSound Driver Development Kit.
- *
- * Copyright (C) 1998 Andrew Veliath
- * Copyright (C) 1993 Turtle Beach Systems, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ********************************************************************/
-#ifndef __MSND_H
-#define __MSND_H
-
-#define DEFSAMPLERATE 44100
-#define DEFSAMPLESIZE SNDRV_PCM_FORMAT_S16
-#define DEFCHANNELS 1
-
-#define SRAM_BANK_SIZE 0x8000
-#define SRAM_CNTL_START 0x7F00
-#define SMA_STRUCT_START 0x7F40
-
-#define DSP_BASE_ADDR 0x4000
-#define DSP_BANK_BASE 0x4000
-
-#define AGND 0x01
-#define SIGNAL 0x02
-
-#define EXT_DSP_BIT_DCAL 0x0001
-#define EXT_DSP_BIT_MIDI_CON 0x0002
-
-#define BUFFSIZE 0x8000
-#define HOSTQ_SIZE 0x40
-
-#define DAP_BUFF_SIZE 0x2400
-
-#define DAPQ_STRUCT_SIZE 0x10
-#define DARQ_STRUCT_SIZE 0x10
-#define DAPQ_BUFF_SIZE (3 * 0x10)
-#define DARQ_BUFF_SIZE (3 * 0x10)
-#define MODQ_BUFF_SIZE 0x400
-
-#define DAPQ_DATA_BUFF 0x6C00
-#define DARQ_DATA_BUFF 0x6C30
-#define MODQ_DATA_BUFF 0x6C60
-#define MIDQ_DATA_BUFF 0x7060
-
-#define DAPQ_OFFSET SRAM_CNTL_START
-#define DARQ_OFFSET (SRAM_CNTL_START + 0x08)
-#define MODQ_OFFSET (SRAM_CNTL_START + 0x10)
-#define MIDQ_OFFSET (SRAM_CNTL_START + 0x18)
-#define DSPQ_OFFSET (SRAM_CNTL_START + 0x20)
-
-#define HP_ICR 0x00
-#define HP_CVR 0x01
-#define HP_ISR 0x02
-#define HP_IVR 0x03
-#define HP_NU 0x04
-#define HP_INFO 0x04
-#define HP_TXH 0x05
-#define HP_RXH 0x05
-#define HP_TXM 0x06
-#define HP_RXM 0x06
-#define HP_TXL 0x07
-#define HP_RXL 0x07
-
-#define HP_ICR_DEF 0x00
-#define HP_CVR_DEF 0x12
-#define HP_ISR_DEF 0x06
-#define HP_IVR_DEF 0x0f
-#define HP_NU_DEF 0x00
-
-#define HP_IRQM 0x09
-
-#define HPR_BLRC 0x08
-#define HPR_SPR1 0x09
-#define HPR_SPR2 0x0A
-#define HPR_TCL0 0x0B
-#define HPR_TCL1 0x0C
-#define HPR_TCL2 0x0D
-#define HPR_TCL3 0x0E
-#define HPR_TCL4 0x0F
-
-#define HPICR_INIT 0x80
-#define HPICR_HM1 0x40
-#define HPICR_HM0 0x20
-#define HPICR_HF1 0x10
-#define HPICR_HF0 0x08
-#define HPICR_TREQ 0x02
-#define HPICR_RREQ 0x01
-
-#define HPCVR_HC 0x80
-
-#define HPISR_HREQ 0x80
-#define HPISR_DMA 0x40
-#define HPISR_HF3 0x10
-#define HPISR_HF2 0x08
-#define HPISR_TRDY 0x04
-#define HPISR_TXDE 0x02
-#define HPISR_RXDF 0x01
-
-#define HPIO_290 0
-#define HPIO_260 1
-#define HPIO_250 2
-#define HPIO_240 3
-#define HPIO_230 4
-#define HPIO_220 5
-#define HPIO_210 6
-#define HPIO_3E0 7
-
-#define HPMEM_NONE 0
-#define HPMEM_B000 1
-#define HPMEM_C800 2
-#define HPMEM_D000 3
-#define HPMEM_D400 4
-#define HPMEM_D800 5
-#define HPMEM_E000 6
-#define HPMEM_E800 7
-
-#define HPIRQ_NONE 0
-#define HPIRQ_5 1
-#define HPIRQ_7 2
-#define HPIRQ_9 3
-#define HPIRQ_10 4
-#define HPIRQ_11 5
-#define HPIRQ_12 6
-#define HPIRQ_15 7
-
-#define HIMT_PLAY_DONE 0x00
-#define HIMT_RECORD_DONE 0x01
-#define HIMT_MIDI_EOS 0x02
-#define HIMT_MIDI_OUT 0x03
-
-#define HIMT_MIDI_IN_UCHAR 0x0E
-#define HIMT_DSP 0x0F
-
-#define HDEX_BASE 0x92
-#define HDEX_PLAY_START (0 + HDEX_BASE)
-#define HDEX_PLAY_STOP (1 + HDEX_BASE)
-#define HDEX_PLAY_PAUSE (2 + HDEX_BASE)
-#define HDEX_PLAY_RESUME (3 + HDEX_BASE)
-#define HDEX_RECORD_START (4 + HDEX_BASE)
-#define HDEX_RECORD_STOP (5 + HDEX_BASE)
-#define HDEX_MIDI_IN_START (6 + HDEX_BASE)
-#define HDEX_MIDI_IN_STOP (7 + HDEX_BASE)
-#define HDEX_MIDI_OUT_START (8 + HDEX_BASE)
-#define HDEX_MIDI_OUT_STOP (9 + HDEX_BASE)
-#define HDEX_AUX_REQ (10 + HDEX_BASE)
-
-#define HDEXAR_CLEAR_PEAKS 1
-#define HDEXAR_IN_SET_POTS 2
-#define HDEXAR_AUX_SET_POTS 3
-#define HDEXAR_CAL_A_TO_D 4
-#define HDEXAR_RD_EXT_DSP_BITS 5
-
-/* Pinnacle only HDEXAR defs */
-#define HDEXAR_SET_ANA_IN 0
-#define HDEXAR_SET_SYNTH_IN 4
-#define HDEXAR_READ_DAT_IN 5
-#define HDEXAR_MIC_SET_POTS 6
-#define HDEXAR_SET_DAT_IN 7
-
-#define HDEXAR_SET_SYNTH_48 8
-#define HDEXAR_SET_SYNTH_44 9
-
-#define HIWORD(l) ((u16)((((u32)(l)) >> 16) & 0xFFFF))
-#define LOWORD(l) ((u16)(u32)(l))
-#define HIBYTE(w) ((u8)(((u16)(w) >> 8) & 0xFF))
-#define LOBYTE(w) ((u8)(w))
-#define MAKELONG(low, hi) ((long)(((u16)(low))|(((u32)((u16)(hi)))<<16)))
-#define MAKEWORD(low, hi) ((u16)(((u8)(low))|(((u16)((u8)(hi)))<<8)))
-
-#define PCTODSP_OFFSET(w) (u16)((w)/2)
-#define PCTODSP_BASED(w) (u16)(((w)/2) + DSP_BASE_ADDR)
-#define DSPTOPC_BASED(w) (((w) - DSP_BASE_ADDR) * 2)
-
-#ifdef SLOWIO
-# undef outb
-# undef inb
-# define outb outb_p
-# define inb inb_p
-#endif
-
-/* JobQueueStruct */
-#define JQS_wStart 0x00
-#define JQS_wSize 0x02
-#define JQS_wHead 0x04
-#define JQS_wTail 0x06
-#define JQS__size 0x08
-
-/* DAQueueDataStruct */
-#define DAQDS_wStart 0x00
-#define DAQDS_wSize 0x02
-#define DAQDS_wFormat 0x04
-#define DAQDS_wSampleSize 0x06
-#define DAQDS_wChannels 0x08
-#define DAQDS_wSampleRate 0x0A
-#define DAQDS_wIntMsg 0x0C
-#define DAQDS_wFlags 0x0E
-#define DAQDS__size 0x10
-
-#include <sound/pcm.h>
-
-struct snd_msnd {
- void __iomem *mappedbase;
- int play_period_bytes;
- int playLimit;
- int playPeriods;
- int playDMAPos;
- int banksPlayed;
- int captureDMAPos;
- int capturePeriodBytes;
- int captureLimit;
- int capturePeriods;
- struct snd_card *card;
- void *msndmidi_mpu;
- struct snd_rawmidi *rmidi;
-
- /* Hardware resources */
- long io;
- int memid, irqid;
- int irq, irq_ref;
- unsigned long base;
-
- /* Motorola 56k DSP SMA */
- void __iomem *SMA;
- void __iomem *DAPQ;
- void __iomem *DARQ;
- void __iomem *MODQ;
- void __iomem *MIDQ;
- void __iomem *DSPQ;
- int dspq_data_buff, dspq_buff_size;
-
- /* State variables */
- enum { msndClassic, msndPinnacle } type;
- fmode_t mode;
- unsigned long flags;
-#define F_RESETTING 0
-#define F_HAVEDIGITAL 1
-#define F_AUDIO_WRITE_INUSE 2
-#define F_WRITING 3
-#define F_WRITEBLOCK 4
-#define F_WRITEFLUSH 5
-#define F_AUDIO_READ_INUSE 6
-#define F_READING 7
-#define F_READBLOCK 8
-#define F_EXT_MIDI_INUSE 9
-#define F_HDR_MIDI_INUSE 10
-#define F_DISABLE_WRITE_NDELAY 11
- spinlock_t lock;
- spinlock_t mixer_lock;
- int nresets;
- unsigned recsrc;
-#define LEVEL_ENTRIES 32
- int left_levels[LEVEL_ENTRIES];
- int right_levels[LEVEL_ENTRIES];
- int calibrate_signal;
- int play_sample_size, play_sample_rate, play_channels;
- int play_ndelay;
- int capture_sample_size, capture_sample_rate, capture_channels;
- int capture_ndelay;
- u8 bCurrentMidiPatch;
-
- int last_playbank, last_recbank;
- struct snd_pcm_substream *playback_substream;
- struct snd_pcm_substream *capture_substream;
-
-};
-
-void snd_msnd_init_queue(void *base, int start, int size);
-
-int snd_msnd_send_dsp_cmd(struct snd_msnd *chip, u8 cmd);
-int snd_msnd_send_word(struct snd_msnd *chip,
- unsigned char high,
- unsigned char mid,
- unsigned char low);
-int snd_msnd_upload_host(struct snd_msnd *chip,
- const u8 *bin, int len);
-int snd_msnd_enable_irq(struct snd_msnd *chip);
-int snd_msnd_disable_irq(struct snd_msnd *chip);
-void snd_msnd_dsp_halt(struct snd_msnd *chip, struct file *file);
-int snd_msnd_DAPQ(struct snd_msnd *chip, int start);
-int snd_msnd_DARQ(struct snd_msnd *chip, int start);
-int snd_msnd_pcm(struct snd_card *card, int device, struct snd_pcm **rpcm);
-
-int snd_msndmidi_new(struct snd_card *card, int device);
-void snd_msndmidi_input_read(void *mpu);
-
-void snd_msndmix_setup(struct snd_msnd *chip);
-int __devinit snd_msndmix_new(struct snd_card *card);
-int snd_msndmix_force_recsrc(struct snd_msnd *chip, int recsrc);
-#endif /* __MSND_H */
diff --git a/ANDROID_3.4.5/sound/isa/msnd/msnd_classic.c b/ANDROID_3.4.5/sound/isa/msnd/msnd_classic.c
deleted file mode 100644
index 3b23a096..00000000
--- a/ANDROID_3.4.5/sound/isa/msnd/msnd_classic.c
+++ /dev/null
@@ -1,3 +0,0 @@
-/* The work is in msnd_pinnacle.c, just define MSND_CLASSIC before it. */
-#define MSND_CLASSIC
-#include "msnd_pinnacle.c"
diff --git a/ANDROID_3.4.5/sound/isa/msnd/msnd_classic.h b/ANDROID_3.4.5/sound/isa/msnd/msnd_classic.h
deleted file mode 100644
index f18d5fa5..00000000
--- a/ANDROID_3.4.5/sound/isa/msnd/msnd_classic.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*********************************************************************
- *
- * msnd_classic.h
- *
- * Turtle Beach MultiSound Sound Card Driver for Linux
- *
- * Some parts of this header file were derived from the Turtle Beach
- * MultiSound Driver Development Kit.
- *
- * Copyright (C) 1998 Andrew Veliath
- * Copyright (C) 1993 Turtle Beach Systems, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ********************************************************************/
-#ifndef __MSND_CLASSIC_H
-#define __MSND_CLASSIC_H
-
-#define DSP_NUMIO 0x10
-
-#define HP_MEMM 0x08
-
-#define HP_BITM 0x0E
-#define HP_WAIT 0x0D
-#define HP_DSPR 0x0A
-#define HP_PROR 0x0B
-#define HP_BLKS 0x0C
-
-#define HPPRORESET_OFF 0
-#define HPPRORESET_ON 1
-
-#define HPDSPRESET_OFF 0
-#define HPDSPRESET_ON 1
-
-#define HPBLKSEL_0 0
-#define HPBLKSEL_1 1
-
-#define HPWAITSTATE_0 0
-#define HPWAITSTATE_1 1
-
-#define HPBITMODE_16 0
-#define HPBITMODE_8 1
-
-#define HIDSP_INT_PLAY_UNDER 0x00
-#define HIDSP_INT_RECORD_OVER 0x01
-#define HIDSP_INPUT_CLIPPING 0x02
-#define HIDSP_MIDI_IN_OVER 0x10
-#define HIDSP_MIDI_OVERRUN_ERR 0x13
-
-#define TIME_PRO_RESET_DONE 0x028A
-#define TIME_PRO_SYSEX 0x0040
-#define TIME_PRO_RESET 0x0032
-
-#define DAR_BUFF_SIZE 0x2000
-
-#define MIDQ_BUFF_SIZE 0x200
-#define DSPQ_BUFF_SIZE 0x40
-
-#define DSPQ_DATA_BUFF 0x7260
-
-#define MOP_SYNTH 0x10
-#define MOP_EXTOUT 0x32
-#define MOP_EXTTHRU 0x02
-#define MOP_OUTMASK 0x01
-
-#define MIP_EXTIN 0x01
-#define MIP_SYNTH 0x00
-#define MIP_INMASK 0x32
-
-/* Classic SMA Common Data */
-#define SMA_wCurrPlayBytes 0x0000
-#define SMA_wCurrRecordBytes 0x0002
-#define SMA_wCurrPlayVolLeft 0x0004
-#define SMA_wCurrPlayVolRight 0x0006
-#define SMA_wCurrInVolLeft 0x0008
-#define SMA_wCurrInVolRight 0x000a
-#define SMA_wUser_3 0x000c
-#define SMA_wUser_4 0x000e
-#define SMA_dwUser_5 0x0010
-#define SMA_dwUser_6 0x0014
-#define SMA_wUser_7 0x0018
-#define SMA_wReserved_A 0x001a
-#define SMA_wReserved_B 0x001c
-#define SMA_wReserved_C 0x001e
-#define SMA_wReserved_D 0x0020
-#define SMA_wReserved_E 0x0022
-#define SMA_wReserved_F 0x0024
-#define SMA_wReserved_G 0x0026
-#define SMA_wReserved_H 0x0028
-#define SMA_wCurrDSPStatusFlags 0x002a
-#define SMA_wCurrHostStatusFlags 0x002c
-#define SMA_wCurrInputTagBits 0x002e
-#define SMA_wCurrLeftPeak 0x0030
-#define SMA_wCurrRightPeak 0x0032
-#define SMA_wExtDSPbits 0x0034
-#define SMA_bExtHostbits 0x0036
-#define SMA_bBoardLevel 0x0037
-#define SMA_bInPotPosRight 0x0038
-#define SMA_bInPotPosLeft 0x0039
-#define SMA_bAuxPotPosRight 0x003a
-#define SMA_bAuxPotPosLeft 0x003b
-#define SMA_wCurrMastVolLeft 0x003c
-#define SMA_wCurrMastVolRight 0x003e
-#define SMA_bUser_12 0x0040
-#define SMA_bUser_13 0x0041
-#define SMA_wUser_14 0x0042
-#define SMA_wUser_15 0x0044
-#define SMA_wCalFreqAtoD 0x0046
-#define SMA_wUser_16 0x0048
-#define SMA_wUser_17 0x004a
-#define SMA__size 0x004c
-
-#define INITCODEFILE "turtlebeach/msndinit.bin"
-#define PERMCODEFILE "turtlebeach/msndperm.bin"
-#define LONGNAME "MultiSound (Classic/Monterey/Tahiti)"
-
-#endif /* __MSND_CLASSIC_H */
diff --git a/ANDROID_3.4.5/sound/isa/msnd/msnd_midi.c b/ANDROID_3.4.5/sound/isa/msnd/msnd_midi.c
deleted file mode 100644
index ffc67fd8..00000000
--- a/ANDROID_3.4.5/sound/isa/msnd/msnd_midi.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Copyright (c) 2009 by Krzysztof Helt
- * Routines for control of MPU-401 in UART mode
- *
- * MPU-401 supports UART mode which is not capable generate transmit
- * interrupts thus output is done via polling. Also, if irq < 0, then
- * input is done also via polling. Do not expect good performance.
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/errno.h>
-#include <linux/export.h>
-#include <sound/core.h>
-#include <sound/rawmidi.h>
-
-#include "msnd.h"
-
-#define MSNDMIDI_MODE_BIT_INPUT 0
-#define MSNDMIDI_MODE_BIT_OUTPUT 1
-#define MSNDMIDI_MODE_BIT_INPUT_TRIGGER 2
-#define MSNDMIDI_MODE_BIT_OUTPUT_TRIGGER 3
-
-struct snd_msndmidi {
- struct snd_msnd *dev;
-
- unsigned long mode; /* MSNDMIDI_MODE_XXXX */
-
- struct snd_rawmidi_substream *substream_input;
-
- spinlock_t input_lock;
-};
-
-/*
- * input/output open/close - protected by open_mutex in rawmidi.c
- */
-static int snd_msndmidi_input_open(struct snd_rawmidi_substream *substream)
-{
- struct snd_msndmidi *mpu;
-
- snd_printdd("snd_msndmidi_input_open()\n");
-
- mpu = substream->rmidi->private_data;
-
- mpu->substream_input = substream;
-
- snd_msnd_enable_irq(mpu->dev);
-
- snd_msnd_send_dsp_cmd(mpu->dev, HDEX_MIDI_IN_START);
- set_bit(MSNDMIDI_MODE_BIT_INPUT, &mpu->mode);
- return 0;
-}
-
-static int snd_msndmidi_input_close(struct snd_rawmidi_substream *substream)
-{
- struct snd_msndmidi *mpu;
-
- mpu = substream->rmidi->private_data;
- snd_msnd_send_dsp_cmd(mpu->dev, HDEX_MIDI_IN_STOP);
- clear_bit(MSNDMIDI_MODE_BIT_INPUT, &mpu->mode);
- mpu->substream_input = NULL;
- snd_msnd_disable_irq(mpu->dev);
- return 0;
-}
-
-static void snd_msndmidi_input_drop(struct snd_msndmidi *mpu)
-{
- u16 tail;
-
- tail = readw(mpu->dev->MIDQ + JQS_wTail);
- writew(tail, mpu->dev->MIDQ + JQS_wHead);
-}
-
-/*
- * trigger input
- */
-static void snd_msndmidi_input_trigger(struct snd_rawmidi_substream *substream,
- int up)
-{
- unsigned long flags;
- struct snd_msndmidi *mpu;
-
- snd_printdd("snd_msndmidi_input_trigger(, %i)\n", up);
-
- mpu = substream->rmidi->private_data;
- spin_lock_irqsave(&mpu->input_lock, flags);
- if (up) {
- if (!test_and_set_bit(MSNDMIDI_MODE_BIT_INPUT_TRIGGER,
- &mpu->mode))
- snd_msndmidi_input_drop(mpu);
- } else {
- clear_bit(MSNDMIDI_MODE_BIT_INPUT_TRIGGER, &mpu->mode);
- }
- spin_unlock_irqrestore(&mpu->input_lock, flags);
- if (up)
- snd_msndmidi_input_read(mpu);
-}
-
-void snd_msndmidi_input_read(void *mpuv)
-{
- unsigned long flags;
- struct snd_msndmidi *mpu = mpuv;
- void *pwMIDQData = mpu->dev->mappedbase + MIDQ_DATA_BUFF;
-
- spin_lock_irqsave(&mpu->input_lock, flags);
- while (readw(mpu->dev->MIDQ + JQS_wTail) !=
- readw(mpu->dev->MIDQ + JQS_wHead)) {
- u16 wTmp, val;
- val = readw(pwMIDQData + 2 * readw(mpu->dev->MIDQ + JQS_wHead));
-
- if (test_bit(MSNDMIDI_MODE_BIT_INPUT_TRIGGER,
- &mpu->mode))
- snd_rawmidi_receive(mpu->substream_input,
- (unsigned char *)&val, 1);
-
- wTmp = readw(mpu->dev->MIDQ + JQS_wHead) + 1;
- if (wTmp > readw(mpu->dev->MIDQ + JQS_wSize))
- writew(0, mpu->dev->MIDQ + JQS_wHead);
- else
- writew(wTmp, mpu->dev->MIDQ + JQS_wHead);
- }
- spin_unlock_irqrestore(&mpu->input_lock, flags);
-}
-EXPORT_SYMBOL(snd_msndmidi_input_read);
-
-static struct snd_rawmidi_ops snd_msndmidi_input = {
- .open = snd_msndmidi_input_open,
- .close = snd_msndmidi_input_close,
- .trigger = snd_msndmidi_input_trigger,
-};
-
-static void snd_msndmidi_free(struct snd_rawmidi *rmidi)
-{
- struct snd_msndmidi *mpu = rmidi->private_data;
- kfree(mpu);
-}
-
-int snd_msndmidi_new(struct snd_card *card, int device)
-{
- struct snd_msnd *chip = card->private_data;
- struct snd_msndmidi *mpu;
- struct snd_rawmidi *rmidi;
- int err;
-
- err = snd_rawmidi_new(card, "MSND-MIDI", device, 1, 1, &rmidi);
- if (err < 0)
- return err;
- mpu = kzalloc(sizeof(*mpu), GFP_KERNEL);
- if (mpu == NULL) {
- snd_device_free(card, rmidi);
- return -ENOMEM;
- }
- mpu->dev = chip;
- chip->msndmidi_mpu = mpu;
- rmidi->private_data = mpu;
- rmidi->private_free = snd_msndmidi_free;
- spin_lock_init(&mpu->input_lock);
- strcpy(rmidi->name, "MSND MIDI");
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
- &snd_msndmidi_input);
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/isa/msnd/msnd_pinnacle.c b/ANDROID_3.4.5/sound/isa/msnd/msnd_pinnacle.c
deleted file mode 100644
index 29cc8e16..00000000
--- a/ANDROID_3.4.5/sound/isa/msnd/msnd_pinnacle.c
+++ /dev/null
@@ -1,1245 +0,0 @@
-/*********************************************************************
- *
- * Linux multisound pinnacle/fiji driver for ALSA.
- *
- * 2002/06/30 Karsten Wiese:
- * for now this is only used to build a pinnacle / fiji driver.
- * the OSS parent of this code is designed to also support
- * the multisound classic via the file msnd_classic.c.
- * to make it easier for some brave heart to implemt classic
- * support in alsa, i left all the MSND_CLASSIC tokens in this file.
- * but for now this untested & undone.
- *
- *
- * ripped from linux kernel 2.4.18 by Karsten Wiese.
- *
- * the following is a copy of the 2.4.18 OSS FREE file-heading comment:
- *
- * Turtle Beach MultiSound Sound Card Driver for Linux
- * msnd_pinnacle.c / msnd_classic.c
- *
- * -- If MSND_CLASSIC is defined:
- *
- * -> driver for Turtle Beach Classic/Monterey/Tahiti
- *
- * -- Else
- *
- * -> driver for Turtle Beach Pinnacle/Fiji
- *
- * 12-3-2000 Modified IO port validation Steve Sycamore
- *
- * Copyright (C) 1998 Andrew Veliath
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ********************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/firmware.h>
-#include <linux/isa.h>
-#include <linux/isapnp.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/asound.h>
-#include <sound/pcm.h>
-#include <sound/mpu401.h>
-
-#ifdef MSND_CLASSIC
-# ifndef __alpha__
-# define SLOWIO
-# endif
-#endif
-#include "msnd.h"
-#ifdef MSND_CLASSIC
-# include "msnd_classic.h"
-# define LOGNAME "msnd_classic"
-#else
-# include "msnd_pinnacle.h"
-# define LOGNAME "snd_msnd_pinnacle"
-#endif
-
-static void __devinit set_default_audio_parameters(struct snd_msnd *chip)
-{
- chip->play_sample_size = DEFSAMPLESIZE;
- chip->play_sample_rate = DEFSAMPLERATE;
- chip->play_channels = DEFCHANNELS;
- chip->capture_sample_size = DEFSAMPLESIZE;
- chip->capture_sample_rate = DEFSAMPLERATE;
- chip->capture_channels = DEFCHANNELS;
-}
-
-static void snd_msnd_eval_dsp_msg(struct snd_msnd *chip, u16 wMessage)
-{
- switch (HIBYTE(wMessage)) {
- case HIMT_PLAY_DONE: {
- if (chip->banksPlayed < 3)
- snd_printdd("%08X: HIMT_PLAY_DONE: %i\n",
- (unsigned)jiffies, LOBYTE(wMessage));
-
- if (chip->last_playbank == LOBYTE(wMessage)) {
- snd_printdd("chip.last_playbank == LOBYTE(wMessage)\n");
- break;
- }
- chip->banksPlayed++;
-
- if (test_bit(F_WRITING, &chip->flags))
- snd_msnd_DAPQ(chip, 0);
-
- chip->last_playbank = LOBYTE(wMessage);
- chip->playDMAPos += chip->play_period_bytes;
- if (chip->playDMAPos > chip->playLimit)
- chip->playDMAPos = 0;
- snd_pcm_period_elapsed(chip->playback_substream);
-
- break;
- }
- case HIMT_RECORD_DONE:
- if (chip->last_recbank == LOBYTE(wMessage))
- break;
- chip->last_recbank = LOBYTE(wMessage);
- chip->captureDMAPos += chip->capturePeriodBytes;
- if (chip->captureDMAPos > (chip->captureLimit))
- chip->captureDMAPos = 0;
-
- if (test_bit(F_READING, &chip->flags))
- snd_msnd_DARQ(chip, chip->last_recbank);
-
- snd_pcm_period_elapsed(chip->capture_substream);
- break;
-
- case HIMT_DSP:
- switch (LOBYTE(wMessage)) {
-#ifndef MSND_CLASSIC
- case HIDSP_PLAY_UNDER:
-#endif
- case HIDSP_INT_PLAY_UNDER:
- snd_printd(KERN_WARNING LOGNAME ": Play underflow %i\n",
- chip->banksPlayed);
- if (chip->banksPlayed > 2)
- clear_bit(F_WRITING, &chip->flags);
- break;
-
- case HIDSP_INT_RECORD_OVER:
- snd_printd(KERN_WARNING LOGNAME ": Record overflow\n");
- clear_bit(F_READING, &chip->flags);
- break;
-
- default:
- snd_printd(KERN_WARNING LOGNAME
- ": DSP message %d 0x%02x\n",
- LOBYTE(wMessage), LOBYTE(wMessage));
- break;
- }
- break;
-
- case HIMT_MIDI_IN_UCHAR:
- if (chip->msndmidi_mpu)
- snd_msndmidi_input_read(chip->msndmidi_mpu);
- break;
-
- default:
- snd_printd(KERN_WARNING LOGNAME ": HIMT message %d 0x%02x\n",
- HIBYTE(wMessage), HIBYTE(wMessage));
- break;
- }
-}
-
-static irqreturn_t snd_msnd_interrupt(int irq, void *dev_id)
-{
- struct snd_msnd *chip = dev_id;
- void *pwDSPQData = chip->mappedbase + DSPQ_DATA_BUFF;
-
- /* Send ack to DSP */
- /* inb(chip->io + HP_RXL); */
-
- /* Evaluate queued DSP messages */
- while (readw(chip->DSPQ + JQS_wTail) != readw(chip->DSPQ + JQS_wHead)) {
- u16 wTmp;
-
- snd_msnd_eval_dsp_msg(chip,
- readw(pwDSPQData + 2 * readw(chip->DSPQ + JQS_wHead)));
-
- wTmp = readw(chip->DSPQ + JQS_wHead) + 1;
- if (wTmp > readw(chip->DSPQ + JQS_wSize))
- writew(0, chip->DSPQ + JQS_wHead);
- else
- writew(wTmp, chip->DSPQ + JQS_wHead);
- }
- /* Send ack to DSP */
- inb(chip->io + HP_RXL);
- return IRQ_HANDLED;
-}
-
-
-static int snd_msnd_reset_dsp(long io, unsigned char *info)
-{
- int timeout = 100;
-
- outb(HPDSPRESET_ON, io + HP_DSPR);
- msleep(1);
-#ifndef MSND_CLASSIC
- if (info)
- *info = inb(io + HP_INFO);
-#endif
- outb(HPDSPRESET_OFF, io + HP_DSPR);
- msleep(1);
- while (timeout-- > 0) {
- if (inb(io + HP_CVR) == HP_CVR_DEF)
- return 0;
- msleep(1);
- }
- snd_printk(KERN_ERR LOGNAME ": Cannot reset DSP\n");
-
- return -EIO;
-}
-
-static int __devinit snd_msnd_probe(struct snd_card *card)
-{
- struct snd_msnd *chip = card->private_data;
- unsigned char info;
-#ifndef MSND_CLASSIC
- char *xv, *rev = NULL;
- char *pin = "TB Pinnacle", *fiji = "TB Fiji";
- char *pinfiji = "TB Pinnacle/Fiji";
-#endif
-
- if (!request_region(chip->io, DSP_NUMIO, "probing")) {
- snd_printk(KERN_ERR LOGNAME ": I/O port conflict\n");
- return -ENODEV;
- }
-
- if (snd_msnd_reset_dsp(chip->io, &info) < 0) {
- release_region(chip->io, DSP_NUMIO);
- return -ENODEV;
- }
-
-#ifdef MSND_CLASSIC
- strcpy(card->shortname, "Classic/Tahiti/Monterey");
- strcpy(card->longname, "Turtle Beach Multisound");
- printk(KERN_INFO LOGNAME ": %s, "
- "I/O 0x%lx-0x%lx, IRQ %d, memory mapped to 0x%lX-0x%lX\n",
- card->shortname,
- chip->io, chip->io + DSP_NUMIO - 1,
- chip->irq,
- chip->base, chip->base + 0x7fff);
-#else
- switch (info >> 4) {
- case 0xf:
- xv = "<= 1.15";
- break;
- case 0x1:
- xv = "1.18/1.2";
- break;
- case 0x2:
- xv = "1.3";
- break;
- case 0x3:
- xv = "1.4";
- break;
- default:
- xv = "unknown";
- break;
- }
-
- switch (info & 0x7) {
- case 0x0:
- rev = "I";
- strcpy(card->shortname, pin);
- break;
- case 0x1:
- rev = "F";
- strcpy(card->shortname, pin);
- break;
- case 0x2:
- rev = "G";
- strcpy(card->shortname, pin);
- break;
- case 0x3:
- rev = "H";
- strcpy(card->shortname, pin);
- break;
- case 0x4:
- rev = "E";
- strcpy(card->shortname, fiji);
- break;
- case 0x5:
- rev = "C";
- strcpy(card->shortname, fiji);
- break;
- case 0x6:
- rev = "D";
- strcpy(card->shortname, fiji);
- break;
- case 0x7:
- rev = "A-B (Fiji) or A-E (Pinnacle)";
- strcpy(card->shortname, pinfiji);
- break;
- }
- strcpy(card->longname, "Turtle Beach Multisound Pinnacle");
- printk(KERN_INFO LOGNAME ": %s revision %s, Xilinx version %s, "
- "I/O 0x%lx-0x%lx, IRQ %d, memory mapped to 0x%lX-0x%lX\n",
- card->shortname,
- rev, xv,
- chip->io, chip->io + DSP_NUMIO - 1,
- chip->irq,
- chip->base, chip->base + 0x7fff);
-#endif
-
- release_region(chip->io, DSP_NUMIO);
- return 0;
-}
-
-static int snd_msnd_init_sma(struct snd_msnd *chip)
-{
- static int initted;
- u16 mastVolLeft, mastVolRight;
- unsigned long flags;
-
-#ifdef MSND_CLASSIC
- outb(chip->memid, chip->io + HP_MEMM);
-#endif
- outb(HPBLKSEL_0, chip->io + HP_BLKS);
- /* Motorola 56k shared memory base */
- chip->SMA = chip->mappedbase + SMA_STRUCT_START;
-
- if (initted) {
- mastVolLeft = readw(chip->SMA + SMA_wCurrMastVolLeft);
- mastVolRight = readw(chip->SMA + SMA_wCurrMastVolRight);
- } else
- mastVolLeft = mastVolRight = 0;
- memset_io(chip->mappedbase, 0, 0x8000);
-
- /* Critical section: bank 1 access */
- spin_lock_irqsave(&chip->lock, flags);
- outb(HPBLKSEL_1, chip->io + HP_BLKS);
- memset_io(chip->mappedbase, 0, 0x8000);
- outb(HPBLKSEL_0, chip->io + HP_BLKS);
- spin_unlock_irqrestore(&chip->lock, flags);
-
- /* Digital audio play queue */
- chip->DAPQ = chip->mappedbase + DAPQ_OFFSET;
- snd_msnd_init_queue(chip->DAPQ, DAPQ_DATA_BUFF, DAPQ_BUFF_SIZE);
-
- /* Digital audio record queue */
- chip->DARQ = chip->mappedbase + DARQ_OFFSET;
- snd_msnd_init_queue(chip->DARQ, DARQ_DATA_BUFF, DARQ_BUFF_SIZE);
-
- /* MIDI out queue */
- chip->MODQ = chip->mappedbase + MODQ_OFFSET;
- snd_msnd_init_queue(chip->MODQ, MODQ_DATA_BUFF, MODQ_BUFF_SIZE);
-
- /* MIDI in queue */
- chip->MIDQ = chip->mappedbase + MIDQ_OFFSET;
- snd_msnd_init_queue(chip->MIDQ, MIDQ_DATA_BUFF, MIDQ_BUFF_SIZE);
-
- /* DSP -> host message queue */
- chip->DSPQ = chip->mappedbase + DSPQ_OFFSET;
- snd_msnd_init_queue(chip->DSPQ, DSPQ_DATA_BUFF, DSPQ_BUFF_SIZE);
-
- /* Setup some DSP values */
-#ifndef MSND_CLASSIC
- writew(1, chip->SMA + SMA_wCurrPlayFormat);
- writew(chip->play_sample_size, chip->SMA + SMA_wCurrPlaySampleSize);
- writew(chip->play_channels, chip->SMA + SMA_wCurrPlayChannels);
- writew(chip->play_sample_rate, chip->SMA + SMA_wCurrPlaySampleRate);
-#endif
- writew(chip->play_sample_rate, chip->SMA + SMA_wCalFreqAtoD);
- writew(mastVolLeft, chip->SMA + SMA_wCurrMastVolLeft);
- writew(mastVolRight, chip->SMA + SMA_wCurrMastVolRight);
-#ifndef MSND_CLASSIC
- writel(0x00010000, chip->SMA + SMA_dwCurrPlayPitch);
- writel(0x00000001, chip->SMA + SMA_dwCurrPlayRate);
-#endif
- writew(0x303, chip->SMA + SMA_wCurrInputTagBits);
-
- initted = 1;
-
- return 0;
-}
-
-
-static int upload_dsp_code(struct snd_card *card)
-{
- struct snd_msnd *chip = card->private_data;
- const struct firmware *init_fw = NULL, *perm_fw = NULL;
- int err;
-
- outb(HPBLKSEL_0, chip->io + HP_BLKS);
-
- err = request_firmware(&init_fw, INITCODEFILE, card->dev);
- if (err < 0) {
- printk(KERN_ERR LOGNAME ": Error loading " INITCODEFILE);
- goto cleanup1;
- }
- err = request_firmware(&perm_fw, PERMCODEFILE, card->dev);
- if (err < 0) {
- printk(KERN_ERR LOGNAME ": Error loading " PERMCODEFILE);
- goto cleanup;
- }
-
- memcpy_toio(chip->mappedbase, perm_fw->data, perm_fw->size);
- if (snd_msnd_upload_host(chip, init_fw->data, init_fw->size) < 0) {
- printk(KERN_WARNING LOGNAME ": Error uploading to DSP\n");
- err = -ENODEV;
- goto cleanup;
- }
- printk(KERN_INFO LOGNAME ": DSP firmware uploaded\n");
- err = 0;
-
-cleanup:
- release_firmware(perm_fw);
-cleanup1:
- release_firmware(init_fw);
- return err;
-}
-
-#ifdef MSND_CLASSIC
-static void reset_proteus(struct snd_msnd *chip)
-{
- outb(HPPRORESET_ON, chip->io + HP_PROR);
- msleep(TIME_PRO_RESET);
- outb(HPPRORESET_OFF, chip->io + HP_PROR);
- msleep(TIME_PRO_RESET_DONE);
-}
-#endif
-
-static int snd_msnd_initialize(struct snd_card *card)
-{
- struct snd_msnd *chip = card->private_data;
- int err, timeout;
-
-#ifdef MSND_CLASSIC
- outb(HPWAITSTATE_0, chip->io + HP_WAIT);
- outb(HPBITMODE_16, chip->io + HP_BITM);
-
- reset_proteus(chip);
-#endif
- err = snd_msnd_init_sma(chip);
- if (err < 0) {
- printk(KERN_WARNING LOGNAME ": Cannot initialize SMA\n");
- return err;
- }
-
- err = snd_msnd_reset_dsp(chip->io, NULL);
- if (err < 0)
- return err;
-
- err = upload_dsp_code(card);
- if (err < 0) {
- printk(KERN_WARNING LOGNAME ": Cannot upload DSP code\n");
- return err;
- }
-
- timeout = 200;
-
- while (readw(chip->mappedbase)) {
- msleep(1);
- if (!timeout--) {
- snd_printd(KERN_ERR LOGNAME ": DSP reset timeout\n");
- return -EIO;
- }
- }
-
- snd_msndmix_setup(chip);
- return 0;
-}
-
-static int snd_msnd_dsp_full_reset(struct snd_card *card)
-{
- struct snd_msnd *chip = card->private_data;
- int rv;
-
- if (test_bit(F_RESETTING, &chip->flags) || ++chip->nresets > 10)
- return 0;
-
- set_bit(F_RESETTING, &chip->flags);
- snd_msnd_dsp_halt(chip, NULL); /* Unconditionally halt */
-
- rv = snd_msnd_initialize(card);
- if (rv)
- printk(KERN_WARNING LOGNAME ": DSP reset failed\n");
- snd_msndmix_force_recsrc(chip, 0);
- clear_bit(F_RESETTING, &chip->flags);
- return rv;
-}
-
-static int snd_msnd_dev_free(struct snd_device *device)
-{
- snd_printdd("snd_msnd_chip_free()\n");
- return 0;
-}
-
-static int snd_msnd_send_dsp_cmd_chk(struct snd_msnd *chip, u8 cmd)
-{
- if (snd_msnd_send_dsp_cmd(chip, cmd) == 0)
- return 0;
- snd_msnd_dsp_full_reset(chip->card);
- return snd_msnd_send_dsp_cmd(chip, cmd);
-}
-
-static int __devinit snd_msnd_calibrate_adc(struct snd_msnd *chip, u16 srate)
-{
- snd_printdd("snd_msnd_calibrate_adc(%i)\n", srate);
- writew(srate, chip->SMA + SMA_wCalFreqAtoD);
- if (chip->calibrate_signal == 0)
- writew(readw(chip->SMA + SMA_wCurrHostStatusFlags)
- | 0x0001, chip->SMA + SMA_wCurrHostStatusFlags);
- else
- writew(readw(chip->SMA + SMA_wCurrHostStatusFlags)
- & ~0x0001, chip->SMA + SMA_wCurrHostStatusFlags);
- if (snd_msnd_send_word(chip, 0, 0, HDEXAR_CAL_A_TO_D) == 0 &&
- snd_msnd_send_dsp_cmd_chk(chip, HDEX_AUX_REQ) == 0) {
- schedule_timeout_interruptible(msecs_to_jiffies(333));
- return 0;
- }
- printk(KERN_WARNING LOGNAME ": ADC calibration failed\n");
- return -EIO;
-}
-
-/*
- * ALSA callback function, called when attempting to open the MIDI device.
- */
-static int snd_msnd_mpu401_open(struct snd_mpu401 *mpu)
-{
- snd_msnd_enable_irq(mpu->private_data);
- snd_msnd_send_dsp_cmd(mpu->private_data, HDEX_MIDI_IN_START);
- return 0;
-}
-
-static void snd_msnd_mpu401_close(struct snd_mpu401 *mpu)
-{
- snd_msnd_send_dsp_cmd(mpu->private_data, HDEX_MIDI_IN_STOP);
- snd_msnd_disable_irq(mpu->private_data);
-}
-
-static long mpu_io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
-
-static int __devinit snd_msnd_attach(struct snd_card *card)
-{
- struct snd_msnd *chip = card->private_data;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_msnd_dev_free,
- };
-
- err = request_irq(chip->irq, snd_msnd_interrupt, 0, card->shortname,
- chip);
- if (err < 0) {
- printk(KERN_ERR LOGNAME ": Couldn't grab IRQ %d\n", chip->irq);
- return err;
- }
- if (request_region(chip->io, DSP_NUMIO, card->shortname) == NULL) {
- free_irq(chip->irq, chip);
- return -EBUSY;
- }
-
- if (!request_mem_region(chip->base, BUFFSIZE, card->shortname)) {
- printk(KERN_ERR LOGNAME
- ": unable to grab memory region 0x%lx-0x%lx\n",
- chip->base, chip->base + BUFFSIZE - 1);
- release_region(chip->io, DSP_NUMIO);
- free_irq(chip->irq, chip);
- return -EBUSY;
- }
- chip->mappedbase = ioremap_nocache(chip->base, 0x8000);
- if (!chip->mappedbase) {
- printk(KERN_ERR LOGNAME
- ": unable to map memory region 0x%lx-0x%lx\n",
- chip->base, chip->base + BUFFSIZE - 1);
- err = -EIO;
- goto err_release_region;
- }
-
- err = snd_msnd_dsp_full_reset(card);
- if (err < 0)
- goto err_release_region;
-
- /* Register device */
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
- if (err < 0)
- goto err_release_region;
-
- err = snd_msnd_pcm(card, 0, NULL);
- if (err < 0) {
- printk(KERN_ERR LOGNAME ": error creating new PCM device\n");
- goto err_release_region;
- }
-
- err = snd_msndmix_new(card);
- if (err < 0) {
- printk(KERN_ERR LOGNAME ": error creating new Mixer device\n");
- goto err_release_region;
- }
-
-
- if (mpu_io[0] != SNDRV_AUTO_PORT) {
- struct snd_mpu401 *mpu;
-
- err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
- mpu_io[0],
- MPU401_MODE_INPUT |
- MPU401_MODE_OUTPUT,
- mpu_irq[0],
- &chip->rmidi);
- if (err < 0) {
- printk(KERN_ERR LOGNAME
- ": error creating new Midi device\n");
- goto err_release_region;
- }
- mpu = chip->rmidi->private_data;
-
- mpu->open_input = snd_msnd_mpu401_open;
- mpu->close_input = snd_msnd_mpu401_close;
- mpu->private_data = chip;
- }
-
- disable_irq(chip->irq);
- snd_msnd_calibrate_adc(chip, chip->play_sample_rate);
- snd_msndmix_force_recsrc(chip, 0);
-
- err = snd_card_register(card);
- if (err < 0)
- goto err_release_region;
-
- return 0;
-
-err_release_region:
- if (chip->mappedbase)
- iounmap(chip->mappedbase);
- release_mem_region(chip->base, BUFFSIZE);
- release_region(chip->io, DSP_NUMIO);
- free_irq(chip->irq, chip);
- return err;
-}
-
-
-static void __devexit snd_msnd_unload(struct snd_card *card)
-{
- struct snd_msnd *chip = card->private_data;
-
- iounmap(chip->mappedbase);
- release_mem_region(chip->base, BUFFSIZE);
- release_region(chip->io, DSP_NUMIO);
- free_irq(chip->irq, chip);
- snd_card_free(card);
-}
-
-#ifndef MSND_CLASSIC
-
-/* Pinnacle/Fiji Logical Device Configuration */
-
-static int __devinit snd_msnd_write_cfg(int cfg, int reg, int value)
-{
- outb(reg, cfg);
- outb(value, cfg + 1);
- if (value != inb(cfg + 1)) {
- printk(KERN_ERR LOGNAME ": snd_msnd_write_cfg: I/O error\n");
- return -EIO;
- }
- return 0;
-}
-
-static int __devinit snd_msnd_write_cfg_io0(int cfg, int num, u16 io)
-{
- if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
- return -EIO;
- if (snd_msnd_write_cfg(cfg, IREG_IO0_BASEHI, HIBYTE(io)))
- return -EIO;
- if (snd_msnd_write_cfg(cfg, IREG_IO0_BASELO, LOBYTE(io)))
- return -EIO;
- return 0;
-}
-
-static int __devinit snd_msnd_write_cfg_io1(int cfg, int num, u16 io)
-{
- if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
- return -EIO;
- if (snd_msnd_write_cfg(cfg, IREG_IO1_BASEHI, HIBYTE(io)))
- return -EIO;
- if (snd_msnd_write_cfg(cfg, IREG_IO1_BASELO, LOBYTE(io)))
- return -EIO;
- return 0;
-}
-
-static int __devinit snd_msnd_write_cfg_irq(int cfg, int num, u16 irq)
-{
- if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
- return -EIO;
- if (snd_msnd_write_cfg(cfg, IREG_IRQ_NUMBER, LOBYTE(irq)))
- return -EIO;
- if (snd_msnd_write_cfg(cfg, IREG_IRQ_TYPE, IRQTYPE_EDGE))
- return -EIO;
- return 0;
-}
-
-static int __devinit snd_msnd_write_cfg_mem(int cfg, int num, int mem)
-{
- u16 wmem;
-
- mem >>= 8;
- wmem = (u16)(mem & 0xfff);
- if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
- return -EIO;
- if (snd_msnd_write_cfg(cfg, IREG_MEMBASEHI, HIBYTE(wmem)))
- return -EIO;
- if (snd_msnd_write_cfg(cfg, IREG_MEMBASELO, LOBYTE(wmem)))
- return -EIO;
- if (wmem && snd_msnd_write_cfg(cfg, IREG_MEMCONTROL,
- MEMTYPE_HIADDR | MEMTYPE_16BIT))
- return -EIO;
- return 0;
-}
-
-static int __devinit snd_msnd_activate_logical(int cfg, int num)
-{
- if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
- return -EIO;
- if (snd_msnd_write_cfg(cfg, IREG_ACTIVATE, LD_ACTIVATE))
- return -EIO;
- return 0;
-}
-
-static int __devinit snd_msnd_write_cfg_logical(int cfg, int num, u16 io0,
- u16 io1, u16 irq, int mem)
-{
- if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
- return -EIO;
- if (snd_msnd_write_cfg_io0(cfg, num, io0))
- return -EIO;
- if (snd_msnd_write_cfg_io1(cfg, num, io1))
- return -EIO;
- if (snd_msnd_write_cfg_irq(cfg, num, irq))
- return -EIO;
- if (snd_msnd_write_cfg_mem(cfg, num, mem))
- return -EIO;
- if (snd_msnd_activate_logical(cfg, num))
- return -EIO;
- return 0;
-}
-
-static int __devinit snd_msnd_pinnacle_cfg_reset(int cfg)
-{
- int i;
-
- /* Reset devices if told to */
- printk(KERN_INFO LOGNAME ": Resetting all devices\n");
- for (i = 0; i < 4; ++i)
- if (snd_msnd_write_cfg_logical(cfg, i, 0, 0, 0, 0))
- return -EIO;
-
- return 0;
-}
-#endif
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-
-module_param_array(index, int, NULL, S_IRUGO);
-MODULE_PARM_DESC(index, "Index value for msnd_pinnacle soundcard.");
-module_param_array(id, charp, NULL, S_IRUGO);
-MODULE_PARM_DESC(id, "ID string for msnd_pinnacle soundcard.");
-
-static long io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
-static long mem[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-
-#ifndef MSND_CLASSIC
-static long cfg[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-
-/* Extra Peripheral Configuration (Default: Disable) */
-static long ide_io0[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-static long ide_io1[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-static int ide_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
-
-static long joystick_io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-/* If we have the digital daugherboard... */
-static int digital[SNDRV_CARDS];
-
-/* Extra Peripheral Configuration */
-static int reset[SNDRV_CARDS];
-#endif
-
-static int write_ndelay[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 1 };
-
-static int calibrate_signal;
-
-#ifdef CONFIG_PNP
-static bool isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-module_param_array(isapnp, bool, NULL, 0444);
-MODULE_PARM_DESC(isapnp, "ISA PnP detection for specified soundcard.");
-#define has_isapnp(x) isapnp[x]
-#else
-#define has_isapnp(x) 0
-#endif
-
-MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>");
-MODULE_DESCRIPTION("Turtle Beach " LONGNAME " Linux Driver");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(INITCODEFILE);
-MODULE_FIRMWARE(PERMCODEFILE);
-
-module_param_array(io, long, NULL, S_IRUGO);
-MODULE_PARM_DESC(io, "IO port #");
-module_param_array(irq, int, NULL, S_IRUGO);
-module_param_array(mem, long, NULL, S_IRUGO);
-module_param_array(write_ndelay, int, NULL, S_IRUGO);
-module_param(calibrate_signal, int, S_IRUGO);
-#ifndef MSND_CLASSIC
-module_param_array(digital, int, NULL, S_IRUGO);
-module_param_array(cfg, long, NULL, S_IRUGO);
-module_param_array(reset, int, 0, S_IRUGO);
-module_param_array(mpu_io, long, NULL, S_IRUGO);
-module_param_array(mpu_irq, int, NULL, S_IRUGO);
-module_param_array(ide_io0, long, NULL, S_IRUGO);
-module_param_array(ide_io1, long, NULL, S_IRUGO);
-module_param_array(ide_irq, int, NULL, S_IRUGO);
-module_param_array(joystick_io, long, NULL, S_IRUGO);
-#endif
-
-
-static int __devinit snd_msnd_isa_match(struct device *pdev, unsigned int i)
-{
- if (io[i] == SNDRV_AUTO_PORT)
- return 0;
-
- if (irq[i] == SNDRV_AUTO_PORT || mem[i] == SNDRV_AUTO_PORT) {
- printk(KERN_WARNING LOGNAME ": io, irq and mem must be set\n");
- return 0;
- }
-
-#ifdef MSND_CLASSIC
- if (!(io[i] == 0x290 ||
- io[i] == 0x260 ||
- io[i] == 0x250 ||
- io[i] == 0x240 ||
- io[i] == 0x230 ||
- io[i] == 0x220 ||
- io[i] == 0x210 ||
- io[i] == 0x3e0)) {
- printk(KERN_ERR LOGNAME ": \"io\" - DSP I/O base must be set "
- " to 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x290, "
- "or 0x3E0\n");
- return 0;
- }
-#else
- if (io[i] < 0x100 || io[i] > 0x3e0 || (io[i] % 0x10) != 0) {
- printk(KERN_ERR LOGNAME
- ": \"io\" - DSP I/O base must within the range 0x100 "
- "to 0x3E0 and must be evenly divisible by 0x10\n");
- return 0;
- }
-#endif /* MSND_CLASSIC */
-
- if (!(irq[i] == 5 ||
- irq[i] == 7 ||
- irq[i] == 9 ||
- irq[i] == 10 ||
- irq[i] == 11 ||
- irq[i] == 12)) {
- printk(KERN_ERR LOGNAME
- ": \"irq\" - must be set to 5, 7, 9, 10, 11 or 12\n");
- return 0;
- }
-
- if (!(mem[i] == 0xb0000 ||
- mem[i] == 0xc8000 ||
- mem[i] == 0xd0000 ||
- mem[i] == 0xd8000 ||
- mem[i] == 0xe0000 ||
- mem[i] == 0xe8000)) {
- printk(KERN_ERR LOGNAME ": \"mem\" - must be set to "
- "0xb0000, 0xc8000, 0xd0000, 0xd8000, 0xe0000 or "
- "0xe8000\n");
- return 0;
- }
-
-#ifndef MSND_CLASSIC
- if (cfg[i] == SNDRV_AUTO_PORT) {
- printk(KERN_INFO LOGNAME ": Assuming PnP mode\n");
- } else if (cfg[i] != 0x250 && cfg[i] != 0x260 && cfg[i] != 0x270) {
- printk(KERN_INFO LOGNAME
- ": Config port must be 0x250, 0x260 or 0x270 "
- "(or unspecified for PnP mode)\n");
- return 0;
- }
-#endif /* MSND_CLASSIC */
-
- return 1;
-}
-
-static int __devinit snd_msnd_isa_probe(struct device *pdev, unsigned int idx)
-{
- int err;
- struct snd_card *card;
- struct snd_msnd *chip;
-
- if (has_isapnp(idx)
-#ifndef MSND_CLASSIC
- || cfg[idx] == SNDRV_AUTO_PORT
-#endif
- ) {
- printk(KERN_INFO LOGNAME ": Assuming PnP mode\n");
- return -ENODEV;
- }
-
- err = snd_card_create(index[idx], id[idx], THIS_MODULE,
- sizeof(struct snd_msnd), &card);
- if (err < 0)
- return err;
-
- snd_card_set_dev(card, pdev);
- chip = card->private_data;
- chip->card = card;
-
-#ifdef MSND_CLASSIC
- switch (irq[idx]) {
- case 5:
- chip->irqid = HPIRQ_5; break;
- case 7:
- chip->irqid = HPIRQ_7; break;
- case 9:
- chip->irqid = HPIRQ_9; break;
- case 10:
- chip->irqid = HPIRQ_10; break;
- case 11:
- chip->irqid = HPIRQ_11; break;
- case 12:
- chip->irqid = HPIRQ_12; break;
- }
-
- switch (mem[idx]) {
- case 0xb0000:
- chip->memid = HPMEM_B000; break;
- case 0xc8000:
- chip->memid = HPMEM_C800; break;
- case 0xd0000:
- chip->memid = HPMEM_D000; break;
- case 0xd8000:
- chip->memid = HPMEM_D800; break;
- case 0xe0000:
- chip->memid = HPMEM_E000; break;
- case 0xe8000:
- chip->memid = HPMEM_E800; break;
- }
-#else
- printk(KERN_INFO LOGNAME ": Non-PnP mode: configuring at port 0x%lx\n",
- cfg[idx]);
-
- if (!request_region(cfg[idx], 2, "Pinnacle/Fiji Config")) {
- printk(KERN_ERR LOGNAME ": Config port 0x%lx conflict\n",
- cfg[idx]);
- snd_card_free(card);
- return -EIO;
- }
- if (reset[idx])
- if (snd_msnd_pinnacle_cfg_reset(cfg[idx])) {
- err = -EIO;
- goto cfg_error;
- }
-
- /* DSP */
- err = snd_msnd_write_cfg_logical(cfg[idx], 0,
- io[idx], 0,
- irq[idx], mem[idx]);
-
- if (err)
- goto cfg_error;
-
- /* The following are Pinnacle specific */
-
- /* MPU */
- if (mpu_io[idx] != SNDRV_AUTO_PORT
- && mpu_irq[idx] != SNDRV_AUTO_IRQ) {
- printk(KERN_INFO LOGNAME
- ": Configuring MPU to I/O 0x%lx IRQ %d\n",
- mpu_io[idx], mpu_irq[idx]);
- err = snd_msnd_write_cfg_logical(cfg[idx], 1,
- mpu_io[idx], 0,
- mpu_irq[idx], 0);
-
- if (err)
- goto cfg_error;
- }
-
- /* IDE */
- if (ide_io0[idx] != SNDRV_AUTO_PORT
- && ide_io1[idx] != SNDRV_AUTO_PORT
- && ide_irq[idx] != SNDRV_AUTO_IRQ) {
- printk(KERN_INFO LOGNAME
- ": Configuring IDE to I/O 0x%lx, 0x%lx IRQ %d\n",
- ide_io0[idx], ide_io1[idx], ide_irq[idx]);
- err = snd_msnd_write_cfg_logical(cfg[idx], 2,
- ide_io0[idx], ide_io1[idx],
- ide_irq[idx], 0);
-
- if (err)
- goto cfg_error;
- }
-
- /* Joystick */
- if (joystick_io[idx] != SNDRV_AUTO_PORT) {
- printk(KERN_INFO LOGNAME
- ": Configuring joystick to I/O 0x%lx\n",
- joystick_io[idx]);
- err = snd_msnd_write_cfg_logical(cfg[idx], 3,
- joystick_io[idx], 0,
- 0, 0);
-
- if (err)
- goto cfg_error;
- }
- release_region(cfg[idx], 2);
-
-#endif /* MSND_CLASSIC */
-
- set_default_audio_parameters(chip);
-#ifdef MSND_CLASSIC
- chip->type = msndClassic;
-#else
- chip->type = msndPinnacle;
-#endif
- chip->io = io[idx];
- chip->irq = irq[idx];
- chip->base = mem[idx];
-
- chip->calibrate_signal = calibrate_signal ? 1 : 0;
- chip->recsrc = 0;
- chip->dspq_data_buff = DSPQ_DATA_BUFF;
- chip->dspq_buff_size = DSPQ_BUFF_SIZE;
- if (write_ndelay[idx])
- clear_bit(F_DISABLE_WRITE_NDELAY, &chip->flags);
- else
- set_bit(F_DISABLE_WRITE_NDELAY, &chip->flags);
-#ifndef MSND_CLASSIC
- if (digital[idx])
- set_bit(F_HAVEDIGITAL, &chip->flags);
-#endif
- spin_lock_init(&chip->lock);
- err = snd_msnd_probe(card);
- if (err < 0) {
- printk(KERN_ERR LOGNAME ": Probe failed\n");
- snd_card_free(card);
- return err;
- }
-
- err = snd_msnd_attach(card);
- if (err < 0) {
- printk(KERN_ERR LOGNAME ": Attach failed\n");
- snd_card_free(card);
- return err;
- }
- dev_set_drvdata(pdev, card);
-
- return 0;
-
-#ifndef MSND_CLASSIC
-cfg_error:
- release_region(cfg[idx], 2);
- snd_card_free(card);
- return err;
-#endif
-}
-
-static int __devexit snd_msnd_isa_remove(struct device *pdev, unsigned int dev)
-{
- snd_msnd_unload(dev_get_drvdata(pdev));
- dev_set_drvdata(pdev, NULL);
- return 0;
-}
-
-#define DEV_NAME "msnd-pinnacle"
-
-static struct isa_driver snd_msnd_driver = {
- .match = snd_msnd_isa_match,
- .probe = snd_msnd_isa_probe,
- .remove = __devexit_p(snd_msnd_isa_remove),
- /* FIXME: suspend, resume */
- .driver = {
- .name = DEV_NAME
- },
-};
-
-#ifdef CONFIG_PNP
-static int __devinit snd_msnd_pnp_detect(struct pnp_card_link *pcard,
- const struct pnp_card_device_id *pid)
-{
- static int idx;
- struct pnp_dev *pnp_dev;
- struct pnp_dev *mpu_dev;
- struct snd_card *card;
- struct snd_msnd *chip;
- int ret;
-
- for ( ; idx < SNDRV_CARDS; idx++) {
- if (has_isapnp(idx))
- break;
- }
- if (idx >= SNDRV_CARDS)
- return -ENODEV;
-
- /*
- * Check that we still have room for another sound card ...
- */
- pnp_dev = pnp_request_card_device(pcard, pid->devs[0].id, NULL);
- if (!pnp_dev)
- return -ENODEV;
-
- mpu_dev = pnp_request_card_device(pcard, pid->devs[1].id, NULL);
- if (!mpu_dev)
- return -ENODEV;
-
- if (!pnp_is_active(pnp_dev) && pnp_activate_dev(pnp_dev) < 0) {
- printk(KERN_INFO "msnd_pinnacle: device is inactive\n");
- return -EBUSY;
- }
-
- if (!pnp_is_active(mpu_dev) && pnp_activate_dev(mpu_dev) < 0) {
- printk(KERN_INFO "msnd_pinnacle: MPU device is inactive\n");
- return -EBUSY;
- }
-
- /*
- * Create a new ALSA sound card entry, in anticipation
- * of detecting our hardware ...
- */
- ret = snd_card_create(index[idx], id[idx], THIS_MODULE,
- sizeof(struct snd_msnd), &card);
- if (ret < 0)
- return ret;
-
- chip = card->private_data;
- chip->card = card;
- snd_card_set_dev(card, &pcard->card->dev);
-
- /*
- * Read the correct parameters off the ISA PnP bus ...
- */
- io[idx] = pnp_port_start(pnp_dev, 0);
- irq[idx] = pnp_irq(pnp_dev, 0);
- mem[idx] = pnp_mem_start(pnp_dev, 0);
- mpu_io[idx] = pnp_port_start(mpu_dev, 0);
- mpu_irq[idx] = pnp_irq(mpu_dev, 0);
-
- set_default_audio_parameters(chip);
-#ifdef MSND_CLASSIC
- chip->type = msndClassic;
-#else
- chip->type = msndPinnacle;
-#endif
- chip->io = io[idx];
- chip->irq = irq[idx];
- chip->base = mem[idx];
-
- chip->calibrate_signal = calibrate_signal ? 1 : 0;
- chip->recsrc = 0;
- chip->dspq_data_buff = DSPQ_DATA_BUFF;
- chip->dspq_buff_size = DSPQ_BUFF_SIZE;
- if (write_ndelay[idx])
- clear_bit(F_DISABLE_WRITE_NDELAY, &chip->flags);
- else
- set_bit(F_DISABLE_WRITE_NDELAY, &chip->flags);
-#ifndef MSND_CLASSIC
- if (digital[idx])
- set_bit(F_HAVEDIGITAL, &chip->flags);
-#endif
- spin_lock_init(&chip->lock);
- ret = snd_msnd_probe(card);
- if (ret < 0) {
- printk(KERN_ERR LOGNAME ": Probe failed\n");
- goto _release_card;
- }
-
- ret = snd_msnd_attach(card);
- if (ret < 0) {
- printk(KERN_ERR LOGNAME ": Attach failed\n");
- goto _release_card;
- }
-
- pnp_set_card_drvdata(pcard, card);
- ++idx;
- return 0;
-
-_release_card:
- snd_card_free(card);
- return ret;
-}
-
-static void __devexit snd_msnd_pnp_remove(struct pnp_card_link *pcard)
-{
- snd_msnd_unload(pnp_get_card_drvdata(pcard));
- pnp_set_card_drvdata(pcard, NULL);
-}
-
-static int isa_registered;
-static int pnp_registered;
-
-static struct pnp_card_device_id msnd_pnpids[] = {
- /* Pinnacle PnP */
- { .id = "BVJ0440", .devs = { { "TBS0000" }, { "TBS0001" } } },
- { .id = "" } /* end */
-};
-
-MODULE_DEVICE_TABLE(pnp_card, msnd_pnpids);
-
-static struct pnp_card_driver msnd_pnpc_driver = {
- .flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
- .name = "msnd_pinnacle",
- .id_table = msnd_pnpids,
- .probe = snd_msnd_pnp_detect,
- .remove = __devexit_p(snd_msnd_pnp_remove),
-};
-#endif /* CONFIG_PNP */
-
-static int __init snd_msnd_init(void)
-{
- int err;
-
- err = isa_register_driver(&snd_msnd_driver, SNDRV_CARDS);
-#ifdef CONFIG_PNP
- if (!err)
- isa_registered = 1;
-
- err = pnp_register_card_driver(&msnd_pnpc_driver);
- if (!err)
- pnp_registered = 1;
-
- if (isa_registered)
- err = 0;
-#endif
- return err;
-}
-
-static void __exit snd_msnd_exit(void)
-{
-#ifdef CONFIG_PNP
- if (pnp_registered)
- pnp_unregister_card_driver(&msnd_pnpc_driver);
- if (isa_registered)
-#endif
- isa_unregister_driver(&snd_msnd_driver);
-}
-
-module_init(snd_msnd_init);
-module_exit(snd_msnd_exit);
-
diff --git a/ANDROID_3.4.5/sound/isa/msnd/msnd_pinnacle.h b/ANDROID_3.4.5/sound/isa/msnd/msnd_pinnacle.h
deleted file mode 100644
index 48318d1e..00000000
--- a/ANDROID_3.4.5/sound/isa/msnd/msnd_pinnacle.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*********************************************************************
- *
- * msnd_pinnacle.h
- *
- * Turtle Beach MultiSound Sound Card Driver for Linux
- *
- * Some parts of this header file were derived from the Turtle Beach
- * MultiSound Driver Development Kit.
- *
- * Copyright (C) 1998 Andrew Veliath
- * Copyright (C) 1993 Turtle Beach Systems, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ********************************************************************/
-#ifndef __MSND_PINNACLE_H
-#define __MSND_PINNACLE_H
-
-#define DSP_NUMIO 0x08
-
-#define IREG_LOGDEVICE 0x07
-#define IREG_ACTIVATE 0x30
-#define LD_ACTIVATE 0x01
-#define LD_DISACTIVATE 0x00
-#define IREG_EECONTROL 0x3F
-#define IREG_MEMBASEHI 0x40
-#define IREG_MEMBASELO 0x41
-#define IREG_MEMCONTROL 0x42
-#define IREG_MEMRANGEHI 0x43
-#define IREG_MEMRANGELO 0x44
-#define MEMTYPE_8BIT 0x00
-#define MEMTYPE_16BIT 0x02
-#define MEMTYPE_RANGE 0x00
-#define MEMTYPE_HIADDR 0x01
-#define IREG_IO0_BASEHI 0x60
-#define IREG_IO0_BASELO 0x61
-#define IREG_IO1_BASEHI 0x62
-#define IREG_IO1_BASELO 0x63
-#define IREG_IRQ_NUMBER 0x70
-#define IREG_IRQ_TYPE 0x71
-#define IRQTYPE_HIGH 0x02
-#define IRQTYPE_LOW 0x00
-#define IRQTYPE_LEVEL 0x01
-#define IRQTYPE_EDGE 0x00
-
-#define HP_DSPR 0x04
-#define HP_BLKS 0x04
-
-#define HPDSPRESET_OFF 2
-#define HPDSPRESET_ON 0
-
-#define HPBLKSEL_0 2
-#define HPBLKSEL_1 3
-
-#define HIMT_DAT_OFF 0x03
-
-#define HIDSP_PLAY_UNDER 0x00
-#define HIDSP_INT_PLAY_UNDER 0x01
-#define HIDSP_SSI_TX_UNDER 0x02
-#define HIDSP_RECQ_OVERFLOW 0x08
-#define HIDSP_INT_RECORD_OVER 0x09
-#define HIDSP_SSI_RX_OVERFLOW 0x0a
-
-#define HIDSP_MIDI_IN_OVER 0x10
-
-#define HIDSP_MIDI_FRAME_ERR 0x11
-#define HIDSP_MIDI_PARITY_ERR 0x12
-#define HIDSP_MIDI_OVERRUN_ERR 0x13
-
-#define HIDSP_INPUT_CLIPPING 0x20
-#define HIDSP_MIX_CLIPPING 0x30
-#define HIDSP_DAT_IN_OFF 0x21
-
-#define TIME_PRO_RESET_DONE 0x028A
-#define TIME_PRO_SYSEX 0x001E
-#define TIME_PRO_RESET 0x0032
-
-#define DAR_BUFF_SIZE 0x1000
-
-#define MIDQ_BUFF_SIZE 0x800
-#define DSPQ_BUFF_SIZE 0x5A0
-
-#define DSPQ_DATA_BUFF 0x7860
-
-#define MOP_WAVEHDR 0
-#define MOP_EXTOUT 1
-#define MOP_HWINIT 0xfe
-#define MOP_NONE 0xff
-#define MOP_MAX 1
-
-#define MIP_EXTIN 0
-#define MIP_WAVEHDR 1
-#define MIP_HWINIT 0xfe
-#define MIP_MAX 1
-
-/* Pinnacle/Fiji SMA Common Data */
-#define SMA_wCurrPlayBytes 0x0000
-#define SMA_wCurrRecordBytes 0x0002
-#define SMA_wCurrPlayVolLeft 0x0004
-#define SMA_wCurrPlayVolRight 0x0006
-#define SMA_wCurrInVolLeft 0x0008
-#define SMA_wCurrInVolRight 0x000a
-#define SMA_wCurrMHdrVolLeft 0x000c
-#define SMA_wCurrMHdrVolRight 0x000e
-#define SMA_dwCurrPlayPitch 0x0010
-#define SMA_dwCurrPlayRate 0x0014
-#define SMA_wCurrMIDIIOPatch 0x0018
-#define SMA_wCurrPlayFormat 0x001a
-#define SMA_wCurrPlaySampleSize 0x001c
-#define SMA_wCurrPlayChannels 0x001e
-#define SMA_wCurrPlaySampleRate 0x0020
-#define SMA_wCurrRecordFormat 0x0022
-#define SMA_wCurrRecordSampleSize 0x0024
-#define SMA_wCurrRecordChannels 0x0026
-#define SMA_wCurrRecordSampleRate 0x0028
-#define SMA_wCurrDSPStatusFlags 0x002a
-#define SMA_wCurrHostStatusFlags 0x002c
-#define SMA_wCurrInputTagBits 0x002e
-#define SMA_wCurrLeftPeak 0x0030
-#define SMA_wCurrRightPeak 0x0032
-#define SMA_bMicPotPosLeft 0x0034
-#define SMA_bMicPotPosRight 0x0035
-#define SMA_bMicPotMaxLeft 0x0036
-#define SMA_bMicPotMaxRight 0x0037
-#define SMA_bInPotPosLeft 0x0038
-#define SMA_bInPotPosRight 0x0039
-#define SMA_bAuxPotPosLeft 0x003a
-#define SMA_bAuxPotPosRight 0x003b
-#define SMA_bInPotMaxLeft 0x003c
-#define SMA_bInPotMaxRight 0x003d
-#define SMA_bAuxPotMaxLeft 0x003e
-#define SMA_bAuxPotMaxRight 0x003f
-#define SMA_bInPotMaxMethod 0x0040
-#define SMA_bAuxPotMaxMethod 0x0041
-#define SMA_wCurrMastVolLeft 0x0042
-#define SMA_wCurrMastVolRight 0x0044
-#define SMA_wCalFreqAtoD 0x0046
-#define SMA_wCurrAuxVolLeft 0x0048
-#define SMA_wCurrAuxVolRight 0x004a
-#define SMA_wCurrPlay1VolLeft 0x004c
-#define SMA_wCurrPlay1VolRight 0x004e
-#define SMA_wCurrPlay2VolLeft 0x0050
-#define SMA_wCurrPlay2VolRight 0x0052
-#define SMA_wCurrPlay3VolLeft 0x0054
-#define SMA_wCurrPlay3VolRight 0x0056
-#define SMA_wCurrPlay4VolLeft 0x0058
-#define SMA_wCurrPlay4VolRight 0x005a
-#define SMA_wCurrPlay1PeakLeft 0x005c
-#define SMA_wCurrPlay1PeakRight 0x005e
-#define SMA_wCurrPlay2PeakLeft 0x0060
-#define SMA_wCurrPlay2PeakRight 0x0062
-#define SMA_wCurrPlay3PeakLeft 0x0064
-#define SMA_wCurrPlay3PeakRight 0x0066
-#define SMA_wCurrPlay4PeakLeft 0x0068
-#define SMA_wCurrPlay4PeakRight 0x006a
-#define SMA_wCurrPlayPeakLeft 0x006c
-#define SMA_wCurrPlayPeakRight 0x006e
-#define SMA_wCurrDATSR 0x0070
-#define SMA_wCurrDATRXCHNL 0x0072
-#define SMA_wCurrDATTXCHNL 0x0074
-#define SMA_wCurrDATRXRate 0x0076
-#define SMA_dwDSPPlayCount 0x0078
-#define SMA__size 0x007c
-
-#define INITCODEFILE "turtlebeach/pndspini.bin"
-#define PERMCODEFILE "turtlebeach/pndsperm.bin"
-#define LONGNAME "MultiSound (Pinnacle/Fiji)"
-
-#endif /* __MSND_PINNACLE_H */
diff --git a/ANDROID_3.4.5/sound/isa/msnd/msnd_pinnacle_mixer.c b/ANDROID_3.4.5/sound/isa/msnd/msnd_pinnacle_mixer.c
deleted file mode 100644
index 1de59d44..00000000
--- a/ANDROID_3.4.5/sound/isa/msnd/msnd_pinnacle_mixer.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/***************************************************************************
- msnd_pinnacle_mixer.c - description
- -------------------
- begin : Fre Jun 7 2002
- copyright : (C) 2002 by karsten wiese
- email : annabellesgarden@yahoo.de
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#include <linux/io.h>
-#include <linux/export.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include "msnd.h"
-#include "msnd_pinnacle.h"
-
-
-#define MSND_MIXER_VOLUME 0
-#define MSND_MIXER_PCM 1
-#define MSND_MIXER_AUX 2 /* Input source 1 (aux1) */
-#define MSND_MIXER_IMIX 3 /* Recording monitor */
-#define MSND_MIXER_SYNTH 4
-#define MSND_MIXER_SPEAKER 5
-#define MSND_MIXER_LINE 6
-#define MSND_MIXER_MIC 7
-#define MSND_MIXER_RECLEV 11 /* Recording level */
-#define MSND_MIXER_IGAIN 12 /* Input gain */
-#define MSND_MIXER_OGAIN 13 /* Output gain */
-#define MSND_MIXER_DIGITAL 17 /* Digital (input) 1 */
-
-/* Device mask bits */
-
-#define MSND_MASK_VOLUME (1 << MSND_MIXER_VOLUME)
-#define MSND_MASK_SYNTH (1 << MSND_MIXER_SYNTH)
-#define MSND_MASK_PCM (1 << MSND_MIXER_PCM)
-#define MSND_MASK_SPEAKER (1 << MSND_MIXER_SPEAKER)
-#define MSND_MASK_LINE (1 << MSND_MIXER_LINE)
-#define MSND_MASK_MIC (1 << MSND_MIXER_MIC)
-#define MSND_MASK_IMIX (1 << MSND_MIXER_IMIX)
-#define MSND_MASK_RECLEV (1 << MSND_MIXER_RECLEV)
-#define MSND_MASK_IGAIN (1 << MSND_MIXER_IGAIN)
-#define MSND_MASK_OGAIN (1 << MSND_MIXER_OGAIN)
-#define MSND_MASK_AUX (1 << MSND_MIXER_AUX)
-#define MSND_MASK_DIGITAL (1 << MSND_MIXER_DIGITAL)
-
-static int snd_msndmix_info_mux(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[3] = {
- "Analog", "MASS", "SPDIF",
- };
- struct snd_msnd *chip = snd_kcontrol_chip(kcontrol);
- unsigned items = test_bit(F_HAVEDIGITAL, &chip->flags) ? 3 : 2;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = items;
- if (uinfo->value.enumerated.item >= items)
- uinfo->value.enumerated.item = items - 1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_msndmix_get_mux(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_msnd *chip = snd_kcontrol_chip(kcontrol);
- /* MSND_MASK_IMIX is the default */
- ucontrol->value.enumerated.item[0] = 0;
-
- if (chip->recsrc & MSND_MASK_SYNTH) {
- ucontrol->value.enumerated.item[0] = 1;
- } else if ((chip->recsrc & MSND_MASK_DIGITAL) &&
- test_bit(F_HAVEDIGITAL, &chip->flags)) {
- ucontrol->value.enumerated.item[0] = 2;
- }
-
-
- return 0;
-}
-
-static int snd_msndmix_set_mux(struct snd_msnd *chip, int val)
-{
- unsigned newrecsrc;
- int change;
- unsigned char msndbyte;
-
- switch (val) {
- case 0:
- newrecsrc = MSND_MASK_IMIX;
- msndbyte = HDEXAR_SET_ANA_IN;
- break;
- case 1:
- newrecsrc = MSND_MASK_SYNTH;
- msndbyte = HDEXAR_SET_SYNTH_IN;
- break;
- case 2:
- newrecsrc = MSND_MASK_DIGITAL;
- msndbyte = HDEXAR_SET_DAT_IN;
- break;
- default:
- return -EINVAL;
- }
- change = newrecsrc != chip->recsrc;
- if (change) {
- change = 0;
- if (!snd_msnd_send_word(chip, 0, 0, msndbyte))
- if (!snd_msnd_send_dsp_cmd(chip, HDEX_AUX_REQ)) {
- chip->recsrc = newrecsrc;
- change = 1;
- }
- }
- return change;
-}
-
-static int snd_msndmix_put_mux(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_msnd *msnd = snd_kcontrol_chip(kcontrol);
- return snd_msndmix_set_mux(msnd, ucontrol->value.enumerated.item[0]);
-}
-
-
-static int snd_msndmix_volume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 100;
- return 0;
-}
-
-static int snd_msndmix_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_msnd *msnd = snd_kcontrol_chip(kcontrol);
- int addr = kcontrol->private_value;
- unsigned long flags;
-
- spin_lock_irqsave(&msnd->mixer_lock, flags);
- ucontrol->value.integer.value[0] = msnd->left_levels[addr] * 100;
- ucontrol->value.integer.value[0] /= 0xFFFF;
- ucontrol->value.integer.value[1] = msnd->right_levels[addr] * 100;
- ucontrol->value.integer.value[1] /= 0xFFFF;
- spin_unlock_irqrestore(&msnd->mixer_lock, flags);
- return 0;
-}
-
-#define update_volm(a, b) \
- do { \
- writew((dev->left_levels[a] >> 1) * \
- readw(dev->SMA + SMA_wCurrMastVolLeft) / 0xffff, \
- dev->SMA + SMA_##b##Left); \
- writew((dev->right_levels[a] >> 1) * \
- readw(dev->SMA + SMA_wCurrMastVolRight) / 0xffff, \
- dev->SMA + SMA_##b##Right); \
- } while (0);
-
-#define update_potm(d, s, ar) \
- do { \
- writeb((dev->left_levels[d] >> 8) * \
- readw(dev->SMA + SMA_wCurrMastVolLeft) / 0xffff, \
- dev->SMA + SMA_##s##Left); \
- writeb((dev->right_levels[d] >> 8) * \
- readw(dev->SMA + SMA_wCurrMastVolRight) / 0xffff, \
- dev->SMA + SMA_##s##Right); \
- if (snd_msnd_send_word(dev, 0, 0, ar) == 0) \
- snd_msnd_send_dsp_cmd(dev, HDEX_AUX_REQ); \
- } while (0);
-
-#define update_pot(d, s, ar) \
- do { \
- writeb(dev->left_levels[d] >> 8, \
- dev->SMA + SMA_##s##Left); \
- writeb(dev->right_levels[d] >> 8, \
- dev->SMA + SMA_##s##Right); \
- if (snd_msnd_send_word(dev, 0, 0, ar) == 0) \
- snd_msnd_send_dsp_cmd(dev, HDEX_AUX_REQ); \
- } while (0);
-
-
-static int snd_msndmix_set(struct snd_msnd *dev, int d, int left, int right)
-{
- int bLeft, bRight;
- int wLeft, wRight;
- int updatemaster = 0;
-
- if (d >= LEVEL_ENTRIES)
- return -EINVAL;
-
- bLeft = left * 0xff / 100;
- wLeft = left * 0xffff / 100;
-
- bRight = right * 0xff / 100;
- wRight = right * 0xffff / 100;
-
- dev->left_levels[d] = wLeft;
- dev->right_levels[d] = wRight;
-
- switch (d) {
- /* master volume unscaled controls */
- case MSND_MIXER_LINE: /* line pot control */
- /* scaled by IMIX in digital mix */
- writeb(bLeft, dev->SMA + SMA_bInPotPosLeft);
- writeb(bRight, dev->SMA + SMA_bInPotPosRight);
- if (snd_msnd_send_word(dev, 0, 0, HDEXAR_IN_SET_POTS) == 0)
- snd_msnd_send_dsp_cmd(dev, HDEX_AUX_REQ);
- break;
- case MSND_MIXER_MIC: /* mic pot control */
- if (dev->type == msndClassic)
- return -EINVAL;
- /* scaled by IMIX in digital mix */
- writeb(bLeft, dev->SMA + SMA_bMicPotPosLeft);
- writeb(bRight, dev->SMA + SMA_bMicPotPosRight);
- if (snd_msnd_send_word(dev, 0, 0, HDEXAR_MIC_SET_POTS) == 0)
- snd_msnd_send_dsp_cmd(dev, HDEX_AUX_REQ);
- break;
- case MSND_MIXER_VOLUME: /* master volume */
- writew(wLeft, dev->SMA + SMA_wCurrMastVolLeft);
- writew(wRight, dev->SMA + SMA_wCurrMastVolRight);
- /* fall through */
-
- case MSND_MIXER_AUX: /* aux pot control */
- /* scaled by master volume */
- /* fall through */
-
- /* digital controls */
- case MSND_MIXER_SYNTH: /* synth vol (dsp mix) */
- case MSND_MIXER_PCM: /* pcm vol (dsp mix) */
- case MSND_MIXER_IMIX: /* input monitor (dsp mix) */
- /* scaled by master volume */
- updatemaster = 1;
- break;
-
- default:
- return -EINVAL;
- }
-
- if (updatemaster) {
- /* update master volume scaled controls */
- update_volm(MSND_MIXER_PCM, wCurrPlayVol);
- update_volm(MSND_MIXER_IMIX, wCurrInVol);
- if (dev->type == msndPinnacle)
- update_volm(MSND_MIXER_SYNTH, wCurrMHdrVol);
- update_potm(MSND_MIXER_AUX, bAuxPotPos, HDEXAR_AUX_SET_POTS);
- }
-
- return 0;
-}
-
-static int snd_msndmix_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_msnd *msnd = snd_kcontrol_chip(kcontrol);
- int change, addr = kcontrol->private_value;
- int left, right;
- unsigned long flags;
-
- left = ucontrol->value.integer.value[0] % 101;
- right = ucontrol->value.integer.value[1] % 101;
- spin_lock_irqsave(&msnd->mixer_lock, flags);
- change = msnd->left_levels[addr] != left
- || msnd->right_levels[addr] != right;
- snd_msndmix_set(msnd, addr, left, right);
- spin_unlock_irqrestore(&msnd->mixer_lock, flags);
- return change;
-}
-
-
-#define DUMMY_VOLUME(xname, xindex, addr) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_msndmix_volume_info, \
- .get = snd_msndmix_volume_get, .put = snd_msndmix_volume_put, \
- .private_value = addr }
-
-
-static struct snd_kcontrol_new snd_msnd_controls[] = {
-DUMMY_VOLUME("Master Volume", 0, MSND_MIXER_VOLUME),
-DUMMY_VOLUME("PCM Volume", 0, MSND_MIXER_PCM),
-DUMMY_VOLUME("Aux Volume", 0, MSND_MIXER_AUX),
-DUMMY_VOLUME("Line Volume", 0, MSND_MIXER_LINE),
-DUMMY_VOLUME("Mic Volume", 0, MSND_MIXER_MIC),
-DUMMY_VOLUME("Monitor", 0, MSND_MIXER_IMIX),
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = snd_msndmix_info_mux,
- .get = snd_msndmix_get_mux,
- .put = snd_msndmix_put_mux,
-}
-};
-
-
-int __devinit snd_msndmix_new(struct snd_card *card)
-{
- struct snd_msnd *chip = card->private_data;
- unsigned int idx;
- int err;
-
- if (snd_BUG_ON(!chip))
- return -EINVAL;
- spin_lock_init(&chip->mixer_lock);
- strcpy(card->mixername, "MSND Pinnacle Mixer");
-
- for (idx = 0; idx < ARRAY_SIZE(snd_msnd_controls); idx++)
- err = snd_ctl_add(card,
- snd_ctl_new1(snd_msnd_controls + idx, chip));
- if (err < 0)
- return err;
-
- return 0;
-}
-EXPORT_SYMBOL(snd_msndmix_new);
-
-void snd_msndmix_setup(struct snd_msnd *dev)
-{
- update_pot(MSND_MIXER_LINE, bInPotPos, HDEXAR_IN_SET_POTS);
- update_potm(MSND_MIXER_AUX, bAuxPotPos, HDEXAR_AUX_SET_POTS);
- update_volm(MSND_MIXER_PCM, wCurrPlayVol);
- update_volm(MSND_MIXER_IMIX, wCurrInVol);
- if (dev->type == msndPinnacle) {
- update_pot(MSND_MIXER_MIC, bMicPotPos, HDEXAR_MIC_SET_POTS);
- update_volm(MSND_MIXER_SYNTH, wCurrMHdrVol);
- }
-}
-EXPORT_SYMBOL(snd_msndmix_setup);
-
-int snd_msndmix_force_recsrc(struct snd_msnd *dev, int recsrc)
-{
- dev->recsrc = -1;
- return snd_msndmix_set_mux(dev, recsrc);
-}
-EXPORT_SYMBOL(snd_msndmix_force_recsrc);
diff --git a/ANDROID_3.4.5/sound/isa/opl3sa2.c b/ANDROID_3.4.5/sound/isa/opl3sa2.c
deleted file mode 100644
index f6cc0b91..00000000
--- a/ANDROID_3.4.5/sound/isa/opl3sa2.c
+++ /dev/null
@@ -1,971 +0,0 @@
-/*
- * Driver for Yamaha OPL3-SA[2,3] soundcards
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/isa.h>
-#include <linux/interrupt.h>
-#include <linux/pm.h>
-#include <linux/pnp.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/wss.h>
-#include <sound/mpu401.h>
-#include <sound/opl3.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include <asm/io.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Yamaha OPL3SA2+");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Yamaha,YMF719E-S},"
- "{Genius,Sound Maker 3DX},"
- "{Yamaha,OPL3SA3},"
- "{Intel,AL440LX sound},"
- "{NeoMagic,MagicWave 3DX}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
-#ifdef CONFIG_PNP
-static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
-#endif
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0xf86,0x370,0x100 */
-static long sb_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */
-static long wss_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;/* 0x530,0xe80,0xf40,0x604 */
-static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x388 */
-static long midi_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;/* 0x330,0x300 */
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 0,1,3,5,9,11,12,15 */
-static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3,5,6,7 */
-static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3,5,6,7 */
-static int opl3sa3_ymode[SNDRV_CARDS]; /* 0,1,2,3 */ /*SL Added*/
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for OPL3-SA soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for OPL3-SA soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable OPL3-SA soundcard.");
-#ifdef CONFIG_PNP
-module_param_array(isapnp, bool, NULL, 0444);
-MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
-#endif
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for OPL3-SA driver.");
-module_param_array(sb_port, long, NULL, 0444);
-MODULE_PARM_DESC(sb_port, "SB port # for OPL3-SA driver.");
-module_param_array(wss_port, long, NULL, 0444);
-MODULE_PARM_DESC(wss_port, "WSS port # for OPL3-SA driver.");
-module_param_array(fm_port, long, NULL, 0444);
-MODULE_PARM_DESC(fm_port, "FM port # for OPL3-SA driver.");
-module_param_array(midi_port, long, NULL, 0444);
-MODULE_PARM_DESC(midi_port, "MIDI port # for OPL3-SA driver.");
-module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for OPL3-SA driver.");
-module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "DMA1 # for OPL3-SA driver.");
-module_param_array(dma2, int, NULL, 0444);
-MODULE_PARM_DESC(dma2, "DMA2 # for OPL3-SA driver.");
-module_param_array(opl3sa3_ymode, int, NULL, 0444);
-MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi.");
-
-#ifdef CONFIG_PNP
-static int isa_registered;
-static int pnp_registered;
-static int pnpc_registered;
-#endif
-
-/* control ports */
-#define OPL3SA2_PM_CTRL 0x01
-#define OPL3SA2_SYS_CTRL 0x02
-#define OPL3SA2_IRQ_CONFIG 0x03
-#define OPL3SA2_IRQ_STATUS 0x04
-#define OPL3SA2_DMA_CONFIG 0x06
-#define OPL3SA2_MASTER_LEFT 0x07
-#define OPL3SA2_MASTER_RIGHT 0x08
-#define OPL3SA2_MIC 0x09
-#define OPL3SA2_MISC 0x0A
-
-/* opl3sa3 only */
-#define OPL3SA3_DGTL_DOWN 0x12
-#define OPL3SA3_ANLG_DOWN 0x13
-#define OPL3SA3_WIDE 0x14
-#define OPL3SA3_BASS 0x15
-#define OPL3SA3_TREBLE 0x16
-
-/* power management bits */
-#define OPL3SA2_PM_ADOWN 0x20
-#define OPL3SA2_PM_PSV 0x04
-#define OPL3SA2_PM_PDN 0x02
-#define OPL3SA2_PM_PDX 0x01
-
-#define OPL3SA2_PM_D0 0x00
-#define OPL3SA2_PM_D3 (OPL3SA2_PM_ADOWN|OPL3SA2_PM_PSV|OPL3SA2_PM_PDN|OPL3SA2_PM_PDX)
-
-struct snd_opl3sa2 {
- int version; /* 2 or 3 */
- unsigned long port; /* control port */
- struct resource *res_port; /* control port resource */
- int irq;
- int single_dma;
- spinlock_t reg_lock;
- struct snd_hwdep *synth;
- struct snd_rawmidi *rmidi;
- struct snd_wss *wss;
- unsigned char ctlregs[0x20];
- int ymode; /* SL added */
- struct snd_kcontrol *master_switch;
- struct snd_kcontrol *master_volume;
-};
-
-#define PFX "opl3sa2: "
-
-#ifdef CONFIG_PNP
-
-static struct pnp_device_id snd_opl3sa2_pnpbiosids[] = {
- { .id = "YMH0021" },
- { .id = "NMX2210" }, /* Gateway Solo 2500 */
- { .id = "" } /* end */
-};
-
-MODULE_DEVICE_TABLE(pnp, snd_opl3sa2_pnpbiosids);
-
-static struct pnp_card_device_id snd_opl3sa2_pnpids[] = {
- /* Yamaha YMF719E-S (Genius Sound Maker 3DX) */
- { .id = "YMH0020", .devs = { { "YMH0021" } } },
- /* Yamaha OPL3-SA3 (integrated on Intel's Pentium II AL440LX motherboard) */
- { .id = "YMH0030", .devs = { { "YMH0021" } } },
- /* Yamaha OPL3-SA2 */
- { .id = "YMH0800", .devs = { { "YMH0021" } } },
- /* Yamaha OPL3-SA2 */
- { .id = "YMH0801", .devs = { { "YMH0021" } } },
- /* NeoMagic MagicWave 3DX */
- { .id = "NMX2200", .devs = { { "YMH2210" } } },
- /* NeoMagic MagicWave 3D */
- { .id = "NMX2200", .devs = { { "NMX2210" } } },
- /* --- */
- { .id = "" } /* end */
-};
-
-MODULE_DEVICE_TABLE(pnp_card, snd_opl3sa2_pnpids);
-
-#endif /* CONFIG_PNP */
-
-
-/* read control port (w/o spinlock) */
-static unsigned char __snd_opl3sa2_read(struct snd_opl3sa2 *chip, unsigned char reg)
-{
- unsigned char result;
-#if 0
- outb(0x1d, port); /* password */
- printk(KERN_DEBUG "read [0x%lx] = 0x%x\n", port, inb(port));
-#endif
- outb(reg, chip->port); /* register */
- result = inb(chip->port + 1);
-#if 0
- printk(KERN_DEBUG "read [0x%lx] = 0x%x [0x%x]\n",
- port, result, inb(port));
-#endif
- return result;
-}
-
-/* read control port (with spinlock) */
-static unsigned char snd_opl3sa2_read(struct snd_opl3sa2 *chip, unsigned char reg)
-{
- unsigned long flags;
- unsigned char result;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- result = __snd_opl3sa2_read(chip, reg);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return result;
-}
-
-/* write control port (w/o spinlock) */
-static void __snd_opl3sa2_write(struct snd_opl3sa2 *chip, unsigned char reg, unsigned char value)
-{
-#if 0
- outb(0x1d, port); /* password */
-#endif
- outb(reg, chip->port); /* register */
- outb(value, chip->port + 1);
- chip->ctlregs[reg] = value;
-}
-
-/* write control port (with spinlock) */
-static void snd_opl3sa2_write(struct snd_opl3sa2 *chip, unsigned char reg, unsigned char value)
-{
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
- __snd_opl3sa2_write(chip, reg, value);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-
-static int __devinit snd_opl3sa2_detect(struct snd_card *card)
-{
- struct snd_opl3sa2 *chip = card->private_data;
- unsigned long port;
- unsigned char tmp, tmp1;
- char str[2];
-
- port = chip->port;
- if ((chip->res_port = request_region(port, 2, "OPL3-SA control")) == NULL) {
- snd_printk(KERN_ERR PFX "can't grab port 0x%lx\n", port);
- return -EBUSY;
- }
- /*
- snd_printk(KERN_DEBUG "REG 0A = 0x%x\n",
- snd_opl3sa2_read(chip, 0x0a));
- */
- chip->version = 0;
- tmp = snd_opl3sa2_read(chip, OPL3SA2_MISC);
- if (tmp == 0xff) {
- snd_printd("OPL3-SA [0x%lx] detect = 0x%x\n", port, tmp);
- return -ENODEV;
- }
- switch (tmp & 0x07) {
- case 0x01:
- chip->version = 2; /* YMF711 */
- break;
- default:
- chip->version = 3;
- /* 0x02 - standard */
- /* 0x03 - YM715B */
- /* 0x04 - YM719 - OPL-SA4? */
- /* 0x05 - OPL3-SA3 - Libretto 100 */
- /* 0x07 - unknown - Neomagic MagicWave 3D */
- break;
- }
- str[0] = chip->version + '0';
- str[1] = 0;
- strcat(card->shortname, str);
- snd_opl3sa2_write(chip, OPL3SA2_MISC, tmp ^ 7);
- if ((tmp1 = snd_opl3sa2_read(chip, OPL3SA2_MISC)) != tmp) {
- snd_printd("OPL3-SA [0x%lx] detect (1) = 0x%x (0x%x)\n", port, tmp, tmp1);
- return -ENODEV;
- }
- /* try if the MIC register is accessible */
- tmp = snd_opl3sa2_read(chip, OPL3SA2_MIC);
- snd_opl3sa2_write(chip, OPL3SA2_MIC, 0x8a);
- if (((tmp1 = snd_opl3sa2_read(chip, OPL3SA2_MIC)) & 0x9f) != 0x8a) {
- snd_printd("OPL3-SA [0x%lx] detect (2) = 0x%x (0x%x)\n", port, tmp, tmp1);
- return -ENODEV;
- }
- snd_opl3sa2_write(chip, OPL3SA2_MIC, 0x9f);
- /* initialization */
- /* Power Management - full on */
- snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D0);
- if (chip->version > 2) {
- /* ymode is bits 4&5 (of 0 to 7) on all but opl3sa2 versions */
- snd_opl3sa2_write(chip, OPL3SA2_SYS_CTRL, (chip->ymode << 4));
- } else {
- /* default for opl3sa2 versions */
- snd_opl3sa2_write(chip, OPL3SA2_SYS_CTRL, 0x00);
- }
- snd_opl3sa2_write(chip, OPL3SA2_IRQ_CONFIG, 0x0d); /* Interrupt Channel Configuration - IRQ A = OPL3 + MPU + WSS */
- if (chip->single_dma) {
- snd_opl3sa2_write(chip, OPL3SA2_DMA_CONFIG, 0x03); /* DMA Configuration - DMA A = WSS-R + WSS-P */
- } else {
- snd_opl3sa2_write(chip, OPL3SA2_DMA_CONFIG, 0x21); /* DMA Configuration - DMA B = WSS-R, DMA A = WSS-P */
- }
- snd_opl3sa2_write(chip, OPL3SA2_MISC, 0x80 | (tmp & 7)); /* Miscellaneous - default */
- if (chip->version > 2) {
- snd_opl3sa2_write(chip, OPL3SA3_DGTL_DOWN, 0x00); /* Digital Block Partial Power Down - default */
- snd_opl3sa2_write(chip, OPL3SA3_ANLG_DOWN, 0x00); /* Analog Block Partial Power Down - default */
- }
- return 0;
-}
-
-static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id)
-{
- unsigned short status;
- struct snd_card *card = dev_id;
- struct snd_opl3sa2 *chip;
- int handled = 0;
-
- if (card == NULL)
- return IRQ_NONE;
-
- chip = card->private_data;
- status = snd_opl3sa2_read(chip, OPL3SA2_IRQ_STATUS);
-
- if (status & 0x20) {
- handled = 1;
- snd_opl3_interrupt(chip->synth);
- }
-
- if ((status & 0x10) && chip->rmidi != NULL) {
- handled = 1;
- snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
- }
-
- if (status & 0x07) { /* TI,CI,PI */
- handled = 1;
- snd_wss_interrupt(irq, chip->wss);
- }
-
- if (status & 0x40) { /* hardware volume change */
- handled = 1;
- /* reading from Master Lch register at 0x07 clears this bit */
- snd_opl3sa2_read(chip, OPL3SA2_MASTER_RIGHT);
- snd_opl3sa2_read(chip, OPL3SA2_MASTER_LEFT);
- if (chip->master_switch && chip->master_volume) {
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->master_switch->id);
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->master_volume->id);
- }
- }
- return IRQ_RETVAL(handled);
-}
-
-#define OPL3SA2_SINGLE(xname, xindex, reg, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_wss_info_single, \
- .get = snd_opl3sa2_get_single, .put = snd_opl3sa2_put_single, \
- .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
-#define OPL3SA2_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .name = xname, .index = xindex, \
- .info = snd_wss_info_single, \
- .get = snd_opl3sa2_get_single, .put = snd_opl3sa2_put_single, \
- .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \
- .tlv = { .p = (xtlv) } }
-
-static int snd_opl3sa2_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- ucontrol->value.integer.value[0] = (chip->ctlregs[reg] >> shift) & mask;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (invert)
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- return 0;
-}
-
-static int snd_opl3sa2_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
- int change;
- unsigned short val, oval;
-
- val = (ucontrol->value.integer.value[0] & mask);
- if (invert)
- val = mask - val;
- val <<= shift;
- spin_lock_irqsave(&chip->reg_lock, flags);
- oval = chip->ctlregs[reg];
- val = (oval & ~(mask << shift)) | val;
- change = val != oval;
- __snd_opl3sa2_write(chip, reg, val);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return change;
-}
-
-#define OPL3SA2_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_wss_info_double, \
- .get = snd_opl3sa2_get_double, .put = snd_opl3sa2_put_double, \
- .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
-#define OPL3SA2_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert, xtlv) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .name = xname, .index = xindex, \
- .info = snd_wss_info_double, \
- .get = snd_opl3sa2_get_double, .put = snd_opl3sa2_put_double, \
- .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22), \
- .tlv = { .p = (xtlv) } }
-
-static int snd_opl3sa2_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int shift_left = (kcontrol->private_value >> 16) & 0x07;
- int shift_right = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- ucontrol->value.integer.value[0] = (chip->ctlregs[left_reg] >> shift_left) & mask;
- ucontrol->value.integer.value[1] = (chip->ctlregs[right_reg] >> shift_right) & mask;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (invert) {
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
- }
- return 0;
-}
-
-static int snd_opl3sa2_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int shift_left = (kcontrol->private_value >> 16) & 0x07;
- int shift_right = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
- int change;
- unsigned short val1, val2, oval1, oval2;
-
- val1 = ucontrol->value.integer.value[0] & mask;
- val2 = ucontrol->value.integer.value[1] & mask;
- if (invert) {
- val1 = mask - val1;
- val2 = mask - val2;
- }
- val1 <<= shift_left;
- val2 <<= shift_right;
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (left_reg != right_reg) {
- oval1 = chip->ctlregs[left_reg];
- oval2 = chip->ctlregs[right_reg];
- val1 = (oval1 & ~(mask << shift_left)) | val1;
- val2 = (oval2 & ~(mask << shift_right)) | val2;
- change = val1 != oval1 || val2 != oval2;
- __snd_opl3sa2_write(chip, left_reg, val1);
- __snd_opl3sa2_write(chip, right_reg, val2);
- } else {
- oval1 = chip->ctlregs[left_reg];
- val1 = (oval1 & ~((mask << shift_left) | (mask << shift_right))) | val1 | val2;
- change = val1 != oval1;
- __snd_opl3sa2_write(chip, left_reg, val1);
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return change;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_master, -3000, 200, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
-
-static struct snd_kcontrol_new snd_opl3sa2_controls[] = {
-OPL3SA2_DOUBLE("Master Playback Switch", 0, 0x07, 0x08, 7, 7, 1, 1),
-OPL3SA2_DOUBLE_TLV("Master Playback Volume", 0, 0x07, 0x08, 0, 0, 15, 1,
- db_scale_master),
-OPL3SA2_SINGLE("Mic Playback Switch", 0, 0x09, 7, 1, 1),
-OPL3SA2_SINGLE_TLV("Mic Playback Volume", 0, 0x09, 0, 31, 1,
- db_scale_5bit_12db_max),
-OPL3SA2_SINGLE("ZV Port Switch", 0, 0x02, 0, 1, 0),
-};
-
-static struct snd_kcontrol_new snd_opl3sa2_tone_controls[] = {
-OPL3SA2_DOUBLE("3D Control - Wide", 0, 0x14, 0x14, 4, 0, 7, 0),
-OPL3SA2_DOUBLE("Tone Control - Bass", 0, 0x15, 0x15, 4, 0, 7, 0),
-OPL3SA2_DOUBLE("Tone Control - Treble", 0, 0x16, 0x16, 4, 0, 7, 0)
-};
-
-static void snd_opl3sa2_master_free(struct snd_kcontrol *kcontrol)
-{
- struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
- chip->master_switch = NULL;
- chip->master_volume = NULL;
-}
-
-static int __devinit snd_opl3sa2_mixer(struct snd_card *card)
-{
- struct snd_opl3sa2 *chip = card->private_data;
- struct snd_ctl_elem_id id1, id2;
- struct snd_kcontrol *kctl;
- unsigned int idx;
- int err;
-
- memset(&id1, 0, sizeof(id1));
- memset(&id2, 0, sizeof(id2));
- id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- /* reassign AUX0 to CD */
- strcpy(id1.name, "Aux Playback Switch");
- strcpy(id2.name, "CD Playback Switch");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
- snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n");
- return err;
- }
- strcpy(id1.name, "Aux Playback Volume");
- strcpy(id2.name, "CD Playback Volume");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
- snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n");
- return err;
- }
- /* reassign AUX1 to FM */
- strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
- strcpy(id2.name, "FM Playback Switch");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
- snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n");
- return err;
- }
- strcpy(id1.name, "Aux Playback Volume");
- strcpy(id2.name, "FM Playback Volume");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
- snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n");
- return err;
- }
- /* add OPL3SA2 controls */
- for (idx = 0; idx < ARRAY_SIZE(snd_opl3sa2_controls); idx++) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_opl3sa2_controls[idx], chip))) < 0)
- return err;
- switch (idx) {
- case 0: chip->master_switch = kctl; kctl->private_free = snd_opl3sa2_master_free; break;
- case 1: chip->master_volume = kctl; kctl->private_free = snd_opl3sa2_master_free; break;
- }
- }
- if (chip->version > 2) {
- for (idx = 0; idx < ARRAY_SIZE(snd_opl3sa2_tone_controls); idx++)
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_opl3sa2_tone_controls[idx], chip))) < 0)
- return err;
- }
- return 0;
-}
-
-/* Power Management support functions */
-#ifdef CONFIG_PM
-static int snd_opl3sa2_suspend(struct snd_card *card, pm_message_t state)
-{
- if (card) {
- struct snd_opl3sa2 *chip = card->private_data;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- chip->wss->suspend(chip->wss);
- /* power down */
- snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3);
- }
-
- return 0;
-}
-
-static int snd_opl3sa2_resume(struct snd_card *card)
-{
- struct snd_opl3sa2 *chip;
- int i;
-
- if (!card)
- return 0;
-
- chip = card->private_data;
- /* power up */
- snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D0);
-
- /* restore registers */
- for (i = 2; i <= 0x0a; i++) {
- if (i != OPL3SA2_IRQ_STATUS)
- snd_opl3sa2_write(chip, i, chip->ctlregs[i]);
- }
- if (chip->version > 2) {
- for (i = 0x12; i <= 0x16; i++)
- snd_opl3sa2_write(chip, i, chip->ctlregs[i]);
- }
- /* restore wss */
- chip->wss->resume(chip->wss);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif /* CONFIG_PM */
-
-#ifdef CONFIG_PNP
-static int __devinit snd_opl3sa2_pnp(int dev, struct snd_opl3sa2 *chip,
- struct pnp_dev *pdev)
-{
- if (pnp_activate_dev(pdev) < 0) {
- snd_printk(KERN_ERR "PnP configure failure (out of resources?)\n");
- return -EBUSY;
- }
- sb_port[dev] = pnp_port_start(pdev, 0);
- wss_port[dev] = pnp_port_start(pdev, 1);
- fm_port[dev] = pnp_port_start(pdev, 2);
- midi_port[dev] = pnp_port_start(pdev, 3);
- port[dev] = pnp_port_start(pdev, 4);
- dma1[dev] = pnp_dma(pdev, 0);
- dma2[dev] = pnp_dma(pdev, 1);
- irq[dev] = pnp_irq(pdev, 0);
- snd_printdd("%sPnP OPL3-SA: sb port=0x%lx, wss port=0x%lx, fm port=0x%lx, midi port=0x%lx\n",
- pnp_device_is_pnpbios(pdev) ? "BIOS" : "ISA", sb_port[dev], wss_port[dev], fm_port[dev], midi_port[dev]);
- snd_printdd("%sPnP OPL3-SA: control port=0x%lx, dma1=%i, dma2=%i, irq=%i\n",
- pnp_device_is_pnpbios(pdev) ? "BIOS" : "ISA", port[dev], dma1[dev], dma2[dev], irq[dev]);
- return 0;
-}
-#endif /* CONFIG_PNP */
-
-static void snd_opl3sa2_free(struct snd_card *card)
-{
- struct snd_opl3sa2 *chip = card->private_data;
- if (chip->irq >= 0)
- free_irq(chip->irq, card);
- release_and_free_resource(chip->res_port);
-}
-
-static int snd_opl3sa2_card_new(int dev, struct snd_card **cardp)
-{
- struct snd_card *card;
- struct snd_opl3sa2 *chip;
- int err;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_opl3sa2), &card);
- if (err < 0)
- return err;
- strcpy(card->driver, "OPL3SA2");
- strcpy(card->shortname, "Yamaha OPL3-SA");
- chip = card->private_data;
- spin_lock_init(&chip->reg_lock);
- chip->irq = -1;
- card->private_free = snd_opl3sa2_free;
- *cardp = card;
- return 0;
-}
-
-static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev)
-{
- int xirq, xdma1, xdma2;
- struct snd_opl3sa2 *chip;
- struct snd_wss *wss;
- struct snd_opl3 *opl3;
- int err;
-
- /* initialise this card from supplied (or default) parameter*/
- chip = card->private_data;
- chip->ymode = opl3sa3_ymode[dev] & 0x03 ;
- chip->port = port[dev];
- xirq = irq[dev];
- xdma1 = dma1[dev];
- xdma2 = dma2[dev];
- if (xdma2 < 0)
- chip->single_dma = 1;
- err = snd_opl3sa2_detect(card);
- if (err < 0)
- return err;
- err = request_irq(xirq, snd_opl3sa2_interrupt, 0,
- "OPL3-SA2", card);
- if (err) {
- snd_printk(KERN_ERR PFX "can't grab IRQ %d\n", xirq);
- return -ENODEV;
- }
- chip->irq = xirq;
- err = snd_wss_create(card,
- wss_port[dev] + 4, -1,
- xirq, xdma1, xdma2,
- WSS_HW_OPL3SA2, WSS_HWSHARE_IRQ, &wss);
- if (err < 0) {
- snd_printd("Oops, WSS not detected at 0x%lx\n", wss_port[dev] + 4);
- return err;
- }
- chip->wss = wss;
- err = snd_wss_pcm(wss, 0, NULL);
- if (err < 0)
- return err;
- err = snd_wss_mixer(wss);
- if (err < 0)
- return err;
- err = snd_opl3sa2_mixer(card);
- if (err < 0)
- return err;
- err = snd_wss_timer(wss, 0, NULL);
- if (err < 0)
- return err;
- if (fm_port[dev] >= 0x340 && fm_port[dev] < 0x400) {
- if ((err = snd_opl3_create(card, fm_port[dev],
- fm_port[dev] + 2,
- OPL3_HW_OPL3, 0, &opl3)) < 0)
- return err;
- if ((err = snd_opl3_timer_new(opl3, 1, 2)) < 0)
- return err;
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, &chip->synth)) < 0)
- return err;
- }
- if (midi_port[dev] >= 0x300 && midi_port[dev] < 0x340) {
- if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_OPL3SA2,
- midi_port[dev],
- MPU401_INFO_IRQ_HOOK, -1,
- &chip->rmidi)) < 0)
- return err;
- }
- sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
- card->shortname, chip->port, xirq, xdma1);
- if (xdma2 >= 0)
- sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
-
- return snd_card_register(card);
-}
-
-#ifdef CONFIG_PNP
-static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev,
- const struct pnp_device_id *id)
-{
- static int dev;
- int err;
- struct snd_card *card;
-
- if (pnp_device_is_isapnp(pdev))
- return -ENOENT; /* we have another procedure - card */
- for (; dev < SNDRV_CARDS; dev++) {
- if (enable[dev] && isapnp[dev])
- break;
- }
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
-
- err = snd_opl3sa2_card_new(dev, &card);
- if (err < 0)
- return err;
- if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) {
- snd_card_free(card);
- return err;
- }
- snd_card_set_dev(card, &pdev->dev);
- if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
- snd_card_free(card);
- return err;
- }
- pnp_set_drvdata(pdev, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_opl3sa2_pnp_remove(struct pnp_dev * pdev)
-{
- snd_card_free(pnp_get_drvdata(pdev));
- pnp_set_drvdata(pdev, NULL);
-}
-
-#ifdef CONFIG_PM
-static int snd_opl3sa2_pnp_suspend(struct pnp_dev *pdev, pm_message_t state)
-{
- return snd_opl3sa2_suspend(pnp_get_drvdata(pdev), state);
-}
-static int snd_opl3sa2_pnp_resume(struct pnp_dev *pdev)
-{
- return snd_opl3sa2_resume(pnp_get_drvdata(pdev));
-}
-#endif
-
-static struct pnp_driver opl3sa2_pnp_driver = {
- .name = "snd-opl3sa2-pnpbios",
- .id_table = snd_opl3sa2_pnpbiosids,
- .probe = snd_opl3sa2_pnp_detect,
- .remove = __devexit_p(snd_opl3sa2_pnp_remove),
-#ifdef CONFIG_PM
- .suspend = snd_opl3sa2_pnp_suspend,
- .resume = snd_opl3sa2_pnp_resume,
-#endif
-};
-
-static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard,
- const struct pnp_card_device_id *id)
-{
- static int dev;
- struct pnp_dev *pdev;
- int err;
- struct snd_card *card;
-
- pdev = pnp_request_card_device(pcard, id->devs[0].id, NULL);
- if (pdev == NULL) {
- snd_printk(KERN_ERR PFX "can't get pnp device from id '%s'\n",
- id->devs[0].id);
- return -EBUSY;
- }
- for (; dev < SNDRV_CARDS; dev++) {
- if (enable[dev] && isapnp[dev])
- break;
- }
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
-
- err = snd_opl3sa2_card_new(dev, &card);
- if (err < 0)
- return err;
- if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) {
- snd_card_free(card);
- return err;
- }
- snd_card_set_dev(card, &pdev->dev);
- if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
- snd_card_free(card);
- return err;
- }
- pnp_set_card_drvdata(pcard, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_opl3sa2_pnp_cremove(struct pnp_card_link * pcard)
-{
- snd_card_free(pnp_get_card_drvdata(pcard));
- pnp_set_card_drvdata(pcard, NULL);
-}
-
-#ifdef CONFIG_PM
-static int snd_opl3sa2_pnp_csuspend(struct pnp_card_link *pcard, pm_message_t state)
-{
- return snd_opl3sa2_suspend(pnp_get_card_drvdata(pcard), state);
-}
-static int snd_opl3sa2_pnp_cresume(struct pnp_card_link *pcard)
-{
- return snd_opl3sa2_resume(pnp_get_card_drvdata(pcard));
-}
-#endif
-
-static struct pnp_card_driver opl3sa2_pnpc_driver = {
- .flags = PNP_DRIVER_RES_DISABLE,
- .name = "snd-opl3sa2-cpnp",
- .id_table = snd_opl3sa2_pnpids,
- .probe = snd_opl3sa2_pnp_cdetect,
- .remove = __devexit_p(snd_opl3sa2_pnp_cremove),
-#ifdef CONFIG_PM
- .suspend = snd_opl3sa2_pnp_csuspend,
- .resume = snd_opl3sa2_pnp_cresume,
-#endif
-};
-#endif /* CONFIG_PNP */
-
-static int __devinit snd_opl3sa2_isa_match(struct device *pdev,
- unsigned int dev)
-{
- if (!enable[dev])
- return 0;
-#ifdef CONFIG_PNP
- if (isapnp[dev])
- return 0;
-#endif
- if (port[dev] == SNDRV_AUTO_PORT) {
- snd_printk(KERN_ERR PFX "specify port\n");
- return 0;
- }
- if (wss_port[dev] == SNDRV_AUTO_PORT) {
- snd_printk(KERN_ERR PFX "specify wss_port\n");
- return 0;
- }
- if (fm_port[dev] == SNDRV_AUTO_PORT) {
- snd_printk(KERN_ERR PFX "specify fm_port\n");
- return 0;
- }
- if (midi_port[dev] == SNDRV_AUTO_PORT) {
- snd_printk(KERN_ERR PFX "specify midi_port\n");
- return 0;
- }
- return 1;
-}
-
-static int __devinit snd_opl3sa2_isa_probe(struct device *pdev,
- unsigned int dev)
-{
- struct snd_card *card;
- int err;
-
- err = snd_opl3sa2_card_new(dev, &card);
- if (err < 0)
- return err;
- snd_card_set_dev(card, pdev);
- if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
- snd_card_free(card);
- return err;
- }
- dev_set_drvdata(pdev, card);
- return 0;
-}
-
-static int __devexit snd_opl3sa2_isa_remove(struct device *devptr,
- unsigned int dev)
-{
- snd_card_free(dev_get_drvdata(devptr));
- dev_set_drvdata(devptr, NULL);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int snd_opl3sa2_isa_suspend(struct device *dev, unsigned int n,
- pm_message_t state)
-{
- return snd_opl3sa2_suspend(dev_get_drvdata(dev), state);
-}
-
-static int snd_opl3sa2_isa_resume(struct device *dev, unsigned int n)
-{
- return snd_opl3sa2_resume(dev_get_drvdata(dev));
-}
-#endif
-
-#define DEV_NAME "opl3sa2"
-
-static struct isa_driver snd_opl3sa2_isa_driver = {
- .match = snd_opl3sa2_isa_match,
- .probe = snd_opl3sa2_isa_probe,
- .remove = __devexit_p(snd_opl3sa2_isa_remove),
-#ifdef CONFIG_PM
- .suspend = snd_opl3sa2_isa_suspend,
- .resume = snd_opl3sa2_isa_resume,
-#endif
- .driver = {
- .name = DEV_NAME
- },
-};
-
-static int __init alsa_card_opl3sa2_init(void)
-{
- int err;
-
- err = isa_register_driver(&snd_opl3sa2_isa_driver, SNDRV_CARDS);
-#ifdef CONFIG_PNP
- if (!err)
- isa_registered = 1;
-
- err = pnp_register_driver(&opl3sa2_pnp_driver);
- if (!err)
- pnp_registered = 1;
-
- err = pnp_register_card_driver(&opl3sa2_pnpc_driver);
- if (!err)
- pnpc_registered = 1;
-
- if (isa_registered || pnp_registered)
- err = 0;
-#endif
- return err;
-}
-
-static void __exit alsa_card_opl3sa2_exit(void)
-{
-#ifdef CONFIG_PNP
- if (pnpc_registered)
- pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
- if (pnp_registered)
- pnp_unregister_driver(&opl3sa2_pnp_driver);
- if (isa_registered)
-#endif
- isa_unregister_driver(&snd_opl3sa2_isa_driver);
-}
-
-module_init(alsa_card_opl3sa2_init)
-module_exit(alsa_card_opl3sa2_exit)
diff --git a/ANDROID_3.4.5/sound/isa/opti9xx/Makefile b/ANDROID_3.4.5/sound/isa/opti9xx/Makefile
deleted file mode 100644
index b4d894db..00000000
--- a/ANDROID_3.4.5/sound/isa/opti9xx/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-opti92x-ad1848-objs := opti92x-ad1848.o
-snd-opti92x-cs4231-objs := opti92x-cs4231.o
-snd-opti93x-objs := opti93x.o
-snd-miro-objs := miro.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_OPTI92X_AD1848) += snd-opti92x-ad1848.o
-obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-opti92x-cs4231.o
-obj-$(CONFIG_SND_OPTI93X) += snd-opti93x.o
-obj-$(CONFIG_SND_MIRO) += snd-miro.o
diff --git a/ANDROID_3.4.5/sound/isa/opti9xx/miro.c b/ANDROID_3.4.5/sound/isa/opti9xx/miro.c
deleted file mode 100644
index c24594c8..00000000
--- a/ANDROID_3.4.5/sound/isa/opti9xx/miro.c
+++ /dev/null
@@ -1,1680 +0,0 @@
-/*
- * ALSA soundcard driver for Miro miroSOUND PCM1 pro
- * miroSOUND PCM12
- * miroSOUND PCM20 Radio
- *
- * Copyright (C) 2004-2005 Martin Langer <martin-langer@gmx.de>
- *
- * Based on OSS ACI and ALSA OPTi9xx drivers
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/isa.h>
-#include <linux/pnp.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <sound/core.h>
-#include <sound/wss.h>
-#include <sound/mpu401.h>
-#include <sound/opl4.h>
-#include <sound/control.h>
-#include <sound/info.h>
-#define SNDRV_LEGACY_FIND_FREE_IRQ
-#define SNDRV_LEGACY_FIND_FREE_DMA
-#include <sound/initval.h>
-#include <sound/aci.h>
-
-MODULE_AUTHOR("Martin Langer <martin-langer@gmx.de>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Miro miroSOUND PCM1 pro, PCM12, PCM20 Radio");
-MODULE_SUPPORTED_DEVICE("{{Miro,miroSOUND PCM1 pro}, "
- "{Miro,miroSOUND PCM12}, "
- "{Miro,miroSOUND PCM20 Radio}}");
-
-static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
-static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-static long port = SNDRV_DEFAULT_PORT1; /* 0x530,0xe80,0xf40,0x604 */
-static long mpu_port = SNDRV_DEFAULT_PORT1; /* 0x300,0x310,0x320,0x330 */
-static long fm_port = SNDRV_DEFAULT_PORT1; /* 0x388 */
-static int irq = SNDRV_DEFAULT_IRQ1; /* 5,7,9,10,11 */
-static int mpu_irq = SNDRV_DEFAULT_IRQ1; /* 5,7,9,10 */
-static int dma1 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */
-static int dma2 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */
-static int wss;
-static int ide;
-#ifdef CONFIG_PNP
-static bool isapnp = 1; /* Enable ISA PnP detection */
-#endif
-
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for miro soundcard.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for miro soundcard.");
-module_param(port, long, 0444);
-MODULE_PARM_DESC(port, "WSS port # for miro driver.");
-module_param(mpu_port, long, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port # for miro driver.");
-module_param(fm_port, long, 0444);
-MODULE_PARM_DESC(fm_port, "FM Port # for miro driver.");
-module_param(irq, int, 0444);
-MODULE_PARM_DESC(irq, "WSS irq # for miro driver.");
-module_param(mpu_irq, int, 0444);
-MODULE_PARM_DESC(mpu_irq, "MPU-401 irq # for miro driver.");
-module_param(dma1, int, 0444);
-MODULE_PARM_DESC(dma1, "1st dma # for miro driver.");
-module_param(dma2, int, 0444);
-MODULE_PARM_DESC(dma2, "2nd dma # for miro driver.");
-module_param(wss, int, 0444);
-MODULE_PARM_DESC(wss, "wss mode");
-module_param(ide, int, 0444);
-MODULE_PARM_DESC(ide, "enable ide port");
-#ifdef CONFIG_PNP
-module_param(isapnp, bool, 0444);
-MODULE_PARM_DESC(isapnp, "Enable ISA PnP detection for specified soundcard.");
-#endif
-
-#define OPTi9XX_HW_DETECT 0
-#define OPTi9XX_HW_82C928 1
-#define OPTi9XX_HW_82C929 2
-#define OPTi9XX_HW_82C924 3
-#define OPTi9XX_HW_82C925 4
-#define OPTi9XX_HW_82C930 5
-#define OPTi9XX_HW_82C931 6
-#define OPTi9XX_HW_82C933 7
-#define OPTi9XX_HW_LAST OPTi9XX_HW_82C933
-
-#define OPTi9XX_MC_REG(n) n
-
-struct snd_miro {
- unsigned short hardware;
- unsigned char password;
- char name[7];
-
- struct resource *res_mc_base;
- struct resource *res_aci_port;
-
- unsigned long mc_base;
- unsigned long mc_base_size;
- unsigned long pwd_reg;
-
- spinlock_t lock;
- struct snd_pcm *pcm;
-
- long wss_base;
- int irq;
- int dma1;
- int dma2;
-
- long mpu_port;
- int mpu_irq;
-
- struct snd_miro_aci *aci;
-};
-
-static struct snd_miro_aci aci_device;
-
-static char * snd_opti9xx_names[] = {
- "unknown",
- "82C928", "82C929",
- "82C924", "82C925",
- "82C930", "82C931", "82C933"
-};
-
-static int snd_miro_pnp_is_probed;
-
-#ifdef CONFIG_PNP
-
-static struct pnp_card_device_id snd_miro_pnpids[] = {
- /* PCM20 and PCM12 in PnP mode */
- { .id = "MIR0924",
- .devs = { { "MIR0000" }, { "MIR0002" }, { "MIR0005" } }, },
- { .id = "" }
-};
-
-MODULE_DEVICE_TABLE(pnp_card, snd_miro_pnpids);
-
-#endif /* CONFIG_PNP */
-
-/*
- * ACI control
- */
-
-static int aci_busy_wait(struct snd_miro_aci *aci)
-{
- long timeout;
- unsigned char byte;
-
- for (timeout = 1; timeout <= ACI_MINTIME + 30; timeout++) {
- byte = inb(aci->aci_port + ACI_REG_BUSY);
- if ((byte & 1) == 0) {
- if (timeout >= ACI_MINTIME)
- snd_printd("aci ready in round %ld.\n",
- timeout-ACI_MINTIME);
- return byte;
- }
- if (timeout >= ACI_MINTIME) {
- long out=10*HZ;
- switch (timeout-ACI_MINTIME) {
- case 0 ... 9:
- out /= 10;
- case 10 ... 19:
- out /= 10;
- case 20 ... 30:
- out /= 10;
- default:
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(out);
- break;
- }
- }
- }
- snd_printk(KERN_ERR "aci_busy_wait() time out\n");
- return -EBUSY;
-}
-
-static inline int aci_write(struct snd_miro_aci *aci, unsigned char byte)
-{
- if (aci_busy_wait(aci) >= 0) {
- outb(byte, aci->aci_port + ACI_REG_COMMAND);
- return 0;
- } else {
- snd_printk(KERN_ERR "aci busy, aci_write(0x%x) stopped.\n", byte);
- return -EBUSY;
- }
-}
-
-static inline int aci_read(struct snd_miro_aci *aci)
-{
- unsigned char byte;
-
- if (aci_busy_wait(aci) >= 0) {
- byte = inb(aci->aci_port + ACI_REG_STATUS);
- return byte;
- } else {
- snd_printk(KERN_ERR "aci busy, aci_read() stopped.\n");
- return -EBUSY;
- }
-}
-
-int snd_aci_cmd(struct snd_miro_aci *aci, int write1, int write2, int write3)
-{
- int write[] = {write1, write2, write3};
- int value, i;
-
- if (mutex_lock_interruptible(&aci->aci_mutex))
- return -EINTR;
-
- for (i=0; i<3; i++) {
- if (write[i]< 0 || write[i] > 255)
- break;
- else {
- value = aci_write(aci, write[i]);
- if (value < 0)
- goto out;
- }
- }
-
- value = aci_read(aci);
-
-out: mutex_unlock(&aci->aci_mutex);
- return value;
-}
-EXPORT_SYMBOL(snd_aci_cmd);
-
-static int aci_getvalue(struct snd_miro_aci *aci, unsigned char index)
-{
- return snd_aci_cmd(aci, ACI_STATUS, index, -1);
-}
-
-static int aci_setvalue(struct snd_miro_aci *aci, unsigned char index,
- int value)
-{
- return snd_aci_cmd(aci, index, value, -1);
-}
-
-struct snd_miro_aci *snd_aci_get_aci(void)
-{
- if (aci_device.aci_port == 0)
- return NULL;
- return &aci_device;
-}
-EXPORT_SYMBOL(snd_aci_get_aci);
-
-/*
- * MIXER part
- */
-
-#define snd_miro_info_capture snd_ctl_boolean_mono_info
-
-static int snd_miro_get_capture(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
- int value;
-
- value = aci_getvalue(miro->aci, ACI_S_GENERAL);
- if (value < 0) {
- snd_printk(KERN_ERR "snd_miro_get_capture() failed: %d\n",
- value);
- return value;
- }
-
- ucontrol->value.integer.value[0] = value & 0x20;
-
- return 0;
-}
-
-static int snd_miro_put_capture(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
- int change, value, error;
-
- value = !(ucontrol->value.integer.value[0]);
-
- error = aci_setvalue(miro->aci, ACI_SET_SOLOMODE, value);
- if (error < 0) {
- snd_printk(KERN_ERR "snd_miro_put_capture() failed: %d\n",
- error);
- return error;
- }
-
- change = (value != miro->aci->aci_solomode);
- miro->aci->aci_solomode = value;
-
- return change;
-}
-
-static int snd_miro_info_preamp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 3;
-
- return 0;
-}
-
-static int snd_miro_get_preamp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
- int value;
-
- if (miro->aci->aci_version <= 176) {
-
- /*
- OSS says it's not readable with versions < 176.
- But it doesn't work on my card,
- which is a PCM12 with aci_version = 176.
- */
-
- ucontrol->value.integer.value[0] = miro->aci->aci_preamp;
- return 0;
- }
-
- value = aci_getvalue(miro->aci, ACI_GET_PREAMP);
- if (value < 0) {
- snd_printk(KERN_ERR "snd_miro_get_preamp() failed: %d\n",
- value);
- return value;
- }
-
- ucontrol->value.integer.value[0] = value;
-
- return 0;
-}
-
-static int snd_miro_put_preamp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
- int error, value, change;
-
- value = ucontrol->value.integer.value[0];
-
- error = aci_setvalue(miro->aci, ACI_SET_PREAMP, value);
- if (error < 0) {
- snd_printk(KERN_ERR "snd_miro_put_preamp() failed: %d\n",
- error);
- return error;
- }
-
- change = (value != miro->aci->aci_preamp);
- miro->aci->aci_preamp = value;
-
- return change;
-}
-
-#define snd_miro_info_amp snd_ctl_boolean_mono_info
-
-static int snd_miro_get_amp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = miro->aci->aci_amp;
-
- return 0;
-}
-
-static int snd_miro_put_amp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
- int error, value, change;
-
- value = ucontrol->value.integer.value[0];
-
- error = aci_setvalue(miro->aci, ACI_SET_POWERAMP, value);
- if (error < 0) {
- snd_printk(KERN_ERR "snd_miro_put_amp() to %d failed: %d\n", value, error);
- return error;
- }
-
- change = (value != miro->aci->aci_amp);
- miro->aci->aci_amp = value;
-
- return change;
-}
-
-#define MIRO_DOUBLE(ctl_name, ctl_index, get_right_reg, set_right_reg) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = ctl_name, \
- .index = ctl_index, \
- .info = snd_miro_info_double, \
- .get = snd_miro_get_double, \
- .put = snd_miro_put_double, \
- .private_value = get_right_reg | (set_right_reg << 8) \
-}
-
-static int snd_miro_info_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int reg = kcontrol->private_value & 0xff;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
-
- if ((reg >= ACI_GET_EQ1) && (reg <= ACI_GET_EQ7)) {
-
- /* equalizer elements */
-
- uinfo->value.integer.min = - 0x7f;
- uinfo->value.integer.max = 0x7f;
- } else {
-
- /* non-equalizer elements */
-
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 0x20;
- }
-
- return 0;
-}
-
-static int snd_miro_get_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *uinfo)
-{
- struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
- int left_val, right_val;
-
- int right_reg = kcontrol->private_value & 0xff;
- int left_reg = right_reg + 1;
-
- right_val = aci_getvalue(miro->aci, right_reg);
- if (right_val < 0) {
- snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", right_reg, right_val);
- return right_val;
- }
-
- left_val = aci_getvalue(miro->aci, left_reg);
- if (left_val < 0) {
- snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", left_reg, left_val);
- return left_val;
- }
-
- if ((right_reg >= ACI_GET_EQ1) && (right_reg <= ACI_GET_EQ7)) {
-
- /* equalizer elements */
-
- if (left_val < 0x80) {
- uinfo->value.integer.value[0] = left_val;
- } else {
- uinfo->value.integer.value[0] = 0x80 - left_val;
- }
-
- if (right_val < 0x80) {
- uinfo->value.integer.value[1] = right_val;
- } else {
- uinfo->value.integer.value[1] = 0x80 - right_val;
- }
-
- } else {
-
- /* non-equalizer elements */
-
- uinfo->value.integer.value[0] = 0x20 - left_val;
- uinfo->value.integer.value[1] = 0x20 - right_val;
- }
-
- return 0;
-}
-
-static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
- struct snd_miro_aci *aci = miro->aci;
- int left, right, left_old, right_old;
- int setreg_left, setreg_right, getreg_left, getreg_right;
- int change, error;
-
- left = ucontrol->value.integer.value[0];
- right = ucontrol->value.integer.value[1];
-
- setreg_right = (kcontrol->private_value >> 8) & 0xff;
- setreg_left = setreg_right + 8;
- if (setreg_right == ACI_SET_MASTER)
- setreg_left -= 7;
-
- getreg_right = kcontrol->private_value & 0xff;
- getreg_left = getreg_right + 1;
-
- left_old = aci_getvalue(aci, getreg_left);
- if (left_old < 0) {
- snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", getreg_left, left_old);
- return left_old;
- }
-
- right_old = aci_getvalue(aci, getreg_right);
- if (right_old < 0) {
- snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", getreg_right, right_old);
- return right_old;
- }
-
- if ((getreg_right >= ACI_GET_EQ1) && (getreg_right <= ACI_GET_EQ7)) {
-
- /* equalizer elements */
-
- if (left < -0x7f || left > 0x7f ||
- right < -0x7f || right > 0x7f)
- return -EINVAL;
-
- if (left_old > 0x80)
- left_old = 0x80 - left_old;
- if (right_old > 0x80)
- right_old = 0x80 - right_old;
-
- if (left >= 0) {
- error = aci_setvalue(aci, setreg_left, left);
- if (error < 0) {
- snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
- left, error);
- return error;
- }
- } else {
- error = aci_setvalue(aci, setreg_left, 0x80 - left);
- if (error < 0) {
- snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
- 0x80 - left, error);
- return error;
- }
- }
-
- if (right >= 0) {
- error = aci_setvalue(aci, setreg_right, right);
- if (error < 0) {
- snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
- right, error);
- return error;
- }
- } else {
- error = aci_setvalue(aci, setreg_right, 0x80 - right);
- if (error < 0) {
- snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
- 0x80 - right, error);
- return error;
- }
- }
-
- } else {
-
- /* non-equalizer elements */
-
- if (left < 0 || left > 0x20 ||
- right < 0 || right > 0x20)
- return -EINVAL;
-
- left_old = 0x20 - left_old;
- right_old = 0x20 - right_old;
-
- error = aci_setvalue(aci, setreg_left, 0x20 - left);
- if (error < 0) {
- snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
- 0x20 - left, error);
- return error;
- }
- error = aci_setvalue(aci, setreg_right, 0x20 - right);
- if (error < 0) {
- snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
- 0x20 - right, error);
- return error;
- }
- }
-
- change = (left != left_old) || (right != right_old);
-
- return change;
-}
-
-static struct snd_kcontrol_new snd_miro_controls[] __devinitdata = {
-MIRO_DOUBLE("Master Playback Volume", 0, ACI_GET_MASTER, ACI_SET_MASTER),
-MIRO_DOUBLE("Mic Playback Volume", 1, ACI_GET_MIC, ACI_SET_MIC),
-MIRO_DOUBLE("Line Playback Volume", 1, ACI_GET_LINE, ACI_SET_LINE),
-MIRO_DOUBLE("CD Playback Volume", 0, ACI_GET_CD, ACI_SET_CD),
-MIRO_DOUBLE("Synth Playback Volume", 0, ACI_GET_SYNTH, ACI_SET_SYNTH),
-MIRO_DOUBLE("PCM Playback Volume", 1, ACI_GET_PCM, ACI_SET_PCM),
-MIRO_DOUBLE("Aux Playback Volume", 2, ACI_GET_LINE2, ACI_SET_LINE2),
-};
-
-/* Equalizer with seven bands (only PCM20)
- from -12dB up to +12dB on each band */
-static struct snd_kcontrol_new snd_miro_eq_controls[] __devinitdata = {
-MIRO_DOUBLE("Tone Control - 28 Hz", 0, ACI_GET_EQ1, ACI_SET_EQ1),
-MIRO_DOUBLE("Tone Control - 160 Hz", 0, ACI_GET_EQ2, ACI_SET_EQ2),
-MIRO_DOUBLE("Tone Control - 400 Hz", 0, ACI_GET_EQ3, ACI_SET_EQ3),
-MIRO_DOUBLE("Tone Control - 1 kHz", 0, ACI_GET_EQ4, ACI_SET_EQ4),
-MIRO_DOUBLE("Tone Control - 2.5 kHz", 0, ACI_GET_EQ5, ACI_SET_EQ5),
-MIRO_DOUBLE("Tone Control - 6.3 kHz", 0, ACI_GET_EQ6, ACI_SET_EQ6),
-MIRO_DOUBLE("Tone Control - 16 kHz", 0, ACI_GET_EQ7, ACI_SET_EQ7),
-};
-
-static struct snd_kcontrol_new snd_miro_radio_control[] __devinitdata = {
-MIRO_DOUBLE("Radio Playback Volume", 0, ACI_GET_LINE1, ACI_SET_LINE1),
-};
-
-static struct snd_kcontrol_new snd_miro_line_control[] __devinitdata = {
-MIRO_DOUBLE("Line Playback Volume", 2, ACI_GET_LINE1, ACI_SET_LINE1),
-};
-
-static struct snd_kcontrol_new snd_miro_preamp_control[] __devinitdata = {
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Mic Boost",
- .index = 1,
- .info = snd_miro_info_preamp,
- .get = snd_miro_get_preamp,
- .put = snd_miro_put_preamp,
-}};
-
-static struct snd_kcontrol_new snd_miro_amp_control[] __devinitdata = {
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Line Boost",
- .index = 0,
- .info = snd_miro_info_amp,
- .get = snd_miro_get_amp,
- .put = snd_miro_put_amp,
-}};
-
-static struct snd_kcontrol_new snd_miro_capture_control[] __devinitdata = {
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Capture Switch",
- .index = 0,
- .info = snd_miro_info_capture,
- .get = snd_miro_get_capture,
- .put = snd_miro_put_capture,
-}};
-
-static unsigned char aci_init_values[][2] __devinitdata = {
- { ACI_SET_MUTE, 0x00 },
- { ACI_SET_POWERAMP, 0x00 },
- { ACI_SET_PREAMP, 0x00 },
- { ACI_SET_SOLOMODE, 0x00 },
- { ACI_SET_MIC + 0, 0x20 },
- { ACI_SET_MIC + 8, 0x20 },
- { ACI_SET_LINE + 0, 0x20 },
- { ACI_SET_LINE + 8, 0x20 },
- { ACI_SET_CD + 0, 0x20 },
- { ACI_SET_CD + 8, 0x20 },
- { ACI_SET_PCM + 0, 0x20 },
- { ACI_SET_PCM + 8, 0x20 },
- { ACI_SET_LINE1 + 0, 0x20 },
- { ACI_SET_LINE1 + 8, 0x20 },
- { ACI_SET_LINE2 + 0, 0x20 },
- { ACI_SET_LINE2 + 8, 0x20 },
- { ACI_SET_SYNTH + 0, 0x20 },
- { ACI_SET_SYNTH + 8, 0x20 },
- { ACI_SET_MASTER + 0, 0x20 },
- { ACI_SET_MASTER + 1, 0x20 },
-};
-
-static int __devinit snd_set_aci_init_values(struct snd_miro *miro)
-{
- int idx, error;
- struct snd_miro_aci *aci = miro->aci;
-
- /* enable WSS on PCM1 */
-
- if ((aci->aci_product == 'A') && wss) {
- error = aci_setvalue(aci, ACI_SET_WSS, wss);
- if (error < 0) {
- snd_printk(KERN_ERR "enabling WSS mode failed\n");
- return error;
- }
- }
-
- /* enable IDE port */
-
- if (ide) {
- error = aci_setvalue(aci, ACI_SET_IDE, ide);
- if (error < 0) {
- snd_printk(KERN_ERR "enabling IDE port failed\n");
- return error;
- }
- }
-
- /* set common aci values */
-
- for (idx = 0; idx < ARRAY_SIZE(aci_init_values); idx++) {
- error = aci_setvalue(aci, aci_init_values[idx][0],
- aci_init_values[idx][1]);
- if (error < 0) {
- snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
- aci_init_values[idx][0], error);
- return error;
- }
- }
- aci->aci_amp = 0;
- aci->aci_preamp = 0;
- aci->aci_solomode = 1;
-
- return 0;
-}
-
-static int __devinit snd_miro_mixer(struct snd_card *card,
- struct snd_miro *miro)
-{
- unsigned int idx;
- int err;
-
- if (snd_BUG_ON(!miro || !card))
- return -EINVAL;
-
- switch (miro->hardware) {
- case OPTi9XX_HW_82C924:
- strcpy(card->mixername, "ACI & OPTi924");
- break;
- case OPTi9XX_HW_82C929:
- strcpy(card->mixername, "ACI & OPTi929");
- break;
- default:
- snd_BUG();
- break;
- }
-
- for (idx = 0; idx < ARRAY_SIZE(snd_miro_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_controls[idx], miro))) < 0)
- return err;
- }
-
- if ((miro->aci->aci_product == 'A') ||
- (miro->aci->aci_product == 'B')) {
- /* PCM1/PCM12 with power-amp and Line 2 */
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_line_control[0], miro))) < 0)
- return err;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_amp_control[0], miro))) < 0)
- return err;
- }
-
- if ((miro->aci->aci_product == 'B') ||
- (miro->aci->aci_product == 'C')) {
- /* PCM12/PCM20 with mic-preamp */
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_preamp_control[0], miro))) < 0)
- return err;
- if (miro->aci->aci_version >= 176)
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_capture_control[0], miro))) < 0)
- return err;
- }
-
- if (miro->aci->aci_product == 'C') {
- /* PCM20 with radio and 7 band equalizer */
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_radio_control[0], miro))) < 0)
- return err;
- for (idx = 0; idx < ARRAY_SIZE(snd_miro_eq_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_eq_controls[idx], miro))) < 0)
- return err;
- }
- }
-
- return 0;
-}
-
-static long snd_legacy_find_free_ioport(long *port_table, long size)
-{
- while (*port_table != -1) {
- struct resource *res;
- if ((res = request_region(*port_table, size,
- "ALSA test")) != NULL) {
- release_and_free_resource(res);
- return *port_table;
- }
- port_table++;
- }
- return -1;
-}
-
-static int __devinit snd_miro_init(struct snd_miro *chip,
- unsigned short hardware)
-{
- static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2};
-
- chip->hardware = hardware;
- strcpy(chip->name, snd_opti9xx_names[hardware]);
-
- chip->mc_base_size = opti9xx_mc_size[hardware];
-
- spin_lock_init(&chip->lock);
-
- chip->wss_base = -1;
- chip->irq = -1;
- chip->dma1 = -1;
- chip->dma2 = -1;
- chip->mpu_port = -1;
- chip->mpu_irq = -1;
-
- chip->pwd_reg = 3;
-
-#ifdef CONFIG_PNP
- if (isapnp && chip->mc_base)
- /* PnP resource gives the least 10 bits */
- chip->mc_base |= 0xc00;
- else
-#endif
- chip->mc_base = 0xf8c;
-
- switch (hardware) {
- case OPTi9XX_HW_82C929:
- chip->password = 0xe3;
- break;
-
- case OPTi9XX_HW_82C924:
- chip->password = 0xe5;
- break;
-
- default:
- snd_printk(KERN_ERR "sorry, no support for %d\n", hardware);
- return -ENODEV;
- }
-
- return 0;
-}
-
-static unsigned char snd_miro_read(struct snd_miro *chip,
- unsigned char reg)
-{
- unsigned long flags;
- unsigned char retval = 0xff;
-
- spin_lock_irqsave(&chip->lock, flags);
- outb(chip->password, chip->mc_base + chip->pwd_reg);
-
- switch (chip->hardware) {
- case OPTi9XX_HW_82C924:
- if (reg > 7) {
- outb(reg, chip->mc_base + 8);
- outb(chip->password, chip->mc_base + chip->pwd_reg);
- retval = inb(chip->mc_base + 9);
- break;
- }
-
- case OPTi9XX_HW_82C929:
- retval = inb(chip->mc_base + reg);
- break;
-
- default:
- snd_printk(KERN_ERR "sorry, no support for %d\n", chip->hardware);
- }
-
- spin_unlock_irqrestore(&chip->lock, flags);
- return retval;
-}
-
-static void snd_miro_write(struct snd_miro *chip, unsigned char reg,
- unsigned char value)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&chip->lock, flags);
- outb(chip->password, chip->mc_base + chip->pwd_reg);
-
- switch (chip->hardware) {
- case OPTi9XX_HW_82C924:
- if (reg > 7) {
- outb(reg, chip->mc_base + 8);
- outb(chip->password, chip->mc_base + chip->pwd_reg);
- outb(value, chip->mc_base + 9);
- break;
- }
-
- case OPTi9XX_HW_82C929:
- outb(value, chip->mc_base + reg);
- break;
-
- default:
- snd_printk(KERN_ERR "sorry, no support for %d\n", chip->hardware);
- }
-
- spin_unlock_irqrestore(&chip->lock, flags);
-}
-
-
-#define snd_miro_write_mask(chip, reg, value, mask) \
- snd_miro_write(chip, reg, \
- (snd_miro_read(chip, reg) & ~(mask)) | ((value) & (mask)))
-
-/*
- * Proc Interface
- */
-
-static void snd_miro_proc_read(struct snd_info_entry * entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_miro *miro = (struct snd_miro *) entry->private_data;
- struct snd_miro_aci *aci = miro->aci;
- char* model = "unknown";
-
- /* miroSOUND PCM1 pro, early PCM12 */
-
- if ((miro->hardware == OPTi9XX_HW_82C929) &&
- (aci->aci_vendor == 'm') &&
- (aci->aci_product == 'A')) {
- switch (aci->aci_version) {
- case 3:
- model = "miroSOUND PCM1 pro";
- break;
- default:
- model = "miroSOUND PCM1 pro / (early) PCM12";
- break;
- }
- }
-
- /* miroSOUND PCM12, PCM12 (Rev. E), PCM12 pnp */
-
- if ((miro->hardware == OPTi9XX_HW_82C924) &&
- (aci->aci_vendor == 'm') &&
- (aci->aci_product == 'B')) {
- switch (aci->aci_version) {
- case 4:
- model = "miroSOUND PCM12";
- break;
- case 176:
- model = "miroSOUND PCM12 (Rev. E)";
- break;
- default:
- model = "miroSOUND PCM12 / PCM12 pnp";
- break;
- }
- }
-
- /* miroSOUND PCM20 radio */
-
- if ((miro->hardware == OPTi9XX_HW_82C924) &&
- (aci->aci_vendor == 'm') &&
- (aci->aci_product == 'C')) {
- switch (aci->aci_version) {
- case 7:
- model = "miroSOUND PCM20 radio (Rev. E)";
- break;
- default:
- model = "miroSOUND PCM20 radio";
- break;
- }
- }
-
- snd_iprintf(buffer, "\nGeneral information:\n");
- snd_iprintf(buffer, " model : %s\n", model);
- snd_iprintf(buffer, " opti : %s\n", miro->name);
- snd_iprintf(buffer, " codec : %s\n", miro->pcm->name);
- snd_iprintf(buffer, " port : 0x%lx\n", miro->wss_base);
- snd_iprintf(buffer, " irq : %d\n", miro->irq);
- snd_iprintf(buffer, " dma : %d,%d\n\n", miro->dma1, miro->dma2);
-
- snd_iprintf(buffer, "MPU-401:\n");
- snd_iprintf(buffer, " port : 0x%lx\n", miro->mpu_port);
- snd_iprintf(buffer, " irq : %d\n\n", miro->mpu_irq);
-
- snd_iprintf(buffer, "ACI information:\n");
- snd_iprintf(buffer, " vendor : ");
- switch (aci->aci_vendor) {
- case 'm':
- snd_iprintf(buffer, "Miro\n");
- break;
- default:
- snd_iprintf(buffer, "unknown (0x%x)\n", aci->aci_vendor);
- break;
- }
-
- snd_iprintf(buffer, " product : ");
- switch (aci->aci_product) {
- case 'A':
- snd_iprintf(buffer, "miroSOUND PCM1 pro / (early) PCM12\n");
- break;
- case 'B':
- snd_iprintf(buffer, "miroSOUND PCM12\n");
- break;
- case 'C':
- snd_iprintf(buffer, "miroSOUND PCM20 radio\n");
- break;
- default:
- snd_iprintf(buffer, "unknown (0x%x)\n", aci->aci_product);
- break;
- }
-
- snd_iprintf(buffer, " firmware: %d (0x%x)\n",
- aci->aci_version, aci->aci_version);
- snd_iprintf(buffer, " port : 0x%lx-0x%lx\n",
- aci->aci_port, aci->aci_port+2);
- snd_iprintf(buffer, " wss : 0x%x\n", wss);
- snd_iprintf(buffer, " ide : 0x%x\n", ide);
- snd_iprintf(buffer, " solomode: 0x%x\n", aci->aci_solomode);
- snd_iprintf(buffer, " amp : 0x%x\n", aci->aci_amp);
- snd_iprintf(buffer, " preamp : 0x%x\n", aci->aci_preamp);
-}
-
-static void __devinit snd_miro_proc_init(struct snd_card *card,
- struct snd_miro *miro)
-{
- struct snd_info_entry *entry;
-
- if (!snd_card_proc_new(card, "miro", &entry))
- snd_info_set_text_ops(entry, miro, snd_miro_proc_read);
-}
-
-/*
- * Init
- */
-
-static int __devinit snd_miro_configure(struct snd_miro *chip)
-{
- unsigned char wss_base_bits;
- unsigned char irq_bits;
- unsigned char dma_bits;
- unsigned char mpu_port_bits = 0;
- unsigned char mpu_irq_bits;
- unsigned long flags;
-
- snd_miro_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
- snd_miro_write_mask(chip, OPTi9XX_MC_REG(2), 0x20, 0x20); /* OPL4 */
- snd_miro_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
-
- switch (chip->hardware) {
- case OPTi9XX_HW_82C924:
- snd_miro_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02);
- snd_miro_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff);
- break;
- case OPTi9XX_HW_82C929:
- /* untested init commands for OPTi929 */
- snd_miro_write_mask(chip, OPTi9XX_MC_REG(4), 0x00, 0x0c);
- break;
- default:
- snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware);
- return -EINVAL;
- }
-
- /* PnP resource says it decodes only 10 bits of address */
- switch (chip->wss_base & 0x3ff) {
- case 0x130:
- chip->wss_base = 0x530;
- wss_base_bits = 0x00;
- break;
- case 0x204:
- chip->wss_base = 0x604;
- wss_base_bits = 0x03;
- break;
- case 0x280:
- chip->wss_base = 0xe80;
- wss_base_bits = 0x01;
- break;
- case 0x340:
- chip->wss_base = 0xf40;
- wss_base_bits = 0x02;
- break;
- default:
- snd_printk(KERN_ERR "WSS port 0x%lx not valid\n", chip->wss_base);
- goto __skip_base;
- }
- snd_miro_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30);
-
-__skip_base:
- switch (chip->irq) {
- case 5:
- irq_bits = 0x05;
- break;
- case 7:
- irq_bits = 0x01;
- break;
- case 9:
- irq_bits = 0x02;
- break;
- case 10:
- irq_bits = 0x03;
- break;
- case 11:
- irq_bits = 0x04;
- break;
- default:
- snd_printk(KERN_ERR "WSS irq # %d not valid\n", chip->irq);
- goto __skip_resources;
- }
-
- switch (chip->dma1) {
- case 0:
- dma_bits = 0x01;
- break;
- case 1:
- dma_bits = 0x02;
- break;
- case 3:
- dma_bits = 0x03;
- break;
- default:
- snd_printk(KERN_ERR "WSS dma1 # %d not valid\n", chip->dma1);
- goto __skip_resources;
- }
-
- if (chip->dma1 == chip->dma2) {
- snd_printk(KERN_ERR "don't want to share dmas\n");
- return -EBUSY;
- }
-
- switch (chip->dma2) {
- case 0:
- case 1:
- break;
- default:
- snd_printk(KERN_ERR "WSS dma2 # %d not valid\n", chip->dma2);
- goto __skip_resources;
- }
- dma_bits |= 0x04;
-
- spin_lock_irqsave(&chip->lock, flags);
- outb(irq_bits << 3 | dma_bits, chip->wss_base);
- spin_unlock_irqrestore(&chip->lock, flags);
-
-__skip_resources:
- if (chip->hardware > OPTi9XX_HW_82C928) {
- switch (chip->mpu_port) {
- case 0:
- case -1:
- break;
- case 0x300:
- mpu_port_bits = 0x03;
- break;
- case 0x310:
- mpu_port_bits = 0x02;
- break;
- case 0x320:
- mpu_port_bits = 0x01;
- break;
- case 0x330:
- mpu_port_bits = 0x00;
- break;
- default:
- snd_printk(KERN_ERR "MPU-401 port 0x%lx not valid\n",
- chip->mpu_port);
- goto __skip_mpu;
- }
-
- switch (chip->mpu_irq) {
- case 5:
- mpu_irq_bits = 0x02;
- break;
- case 7:
- mpu_irq_bits = 0x03;
- break;
- case 9:
- mpu_irq_bits = 0x00;
- break;
- case 10:
- mpu_irq_bits = 0x01;
- break;
- default:
- snd_printk(KERN_ERR "MPU-401 irq # %d not valid\n",
- chip->mpu_irq);
- goto __skip_mpu;
- }
-
- snd_miro_write_mask(chip, OPTi9XX_MC_REG(6),
- (chip->mpu_port <= 0) ? 0x00 :
- 0x80 | mpu_port_bits << 5 | mpu_irq_bits << 3,
- 0xf8);
- }
-__skip_mpu:
-
- return 0;
-}
-
-static int __devinit snd_miro_opti_check(struct snd_miro *chip)
-{
- unsigned char value;
-
- chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
- "OPTi9xx MC");
- if (chip->res_mc_base == NULL)
- return -ENOMEM;
-
- value = snd_miro_read(chip, OPTi9XX_MC_REG(1));
- if (value != 0xff && value != inb(chip->mc_base + OPTi9XX_MC_REG(1)))
- if (value == snd_miro_read(chip, OPTi9XX_MC_REG(1)))
- return 0;
-
- release_and_free_resource(chip->res_mc_base);
- chip->res_mc_base = NULL;
-
- return -ENODEV;
-}
-
-static int __devinit snd_card_miro_detect(struct snd_card *card,
- struct snd_miro *chip)
-{
- int i, err;
-
- for (i = OPTi9XX_HW_82C929; i <= OPTi9XX_HW_82C924; i++) {
-
- if ((err = snd_miro_init(chip, i)) < 0)
- return err;
-
- err = snd_miro_opti_check(chip);
- if (err == 0)
- return 1;
- }
-
- return -ENODEV;
-}
-
-static int __devinit snd_card_miro_aci_detect(struct snd_card *card,
- struct snd_miro *miro)
-{
- unsigned char regval;
- int i;
- struct snd_miro_aci *aci = &aci_device;
-
- miro->aci = aci;
-
- mutex_init(&aci->aci_mutex);
-
- /* get ACI port from OPTi9xx MC 4 */
-
- regval=inb(miro->mc_base + 4);
- aci->aci_port = (regval & 0x10) ? 0x344 : 0x354;
-
- miro->res_aci_port = request_region(aci->aci_port, 3, "miro aci");
- if (miro->res_aci_port == NULL) {
- snd_printk(KERN_ERR "aci i/o area 0x%lx-0x%lx already used.\n",
- aci->aci_port, aci->aci_port+2);
- return -ENOMEM;
- }
-
- /* force ACI into a known state */
- for (i = 0; i < 3; i++)
- if (snd_aci_cmd(aci, ACI_ERROR_OP, -1, -1) < 0) {
- snd_printk(KERN_ERR "can't force aci into known state.\n");
- return -ENXIO;
- }
-
- aci->aci_vendor = snd_aci_cmd(aci, ACI_READ_IDCODE, -1, -1);
- aci->aci_product = snd_aci_cmd(aci, ACI_READ_IDCODE, -1, -1);
- if (aci->aci_vendor < 0 || aci->aci_product < 0) {
- snd_printk(KERN_ERR "can't read aci id on 0x%lx.\n",
- aci->aci_port);
- return -ENXIO;
- }
-
- aci->aci_version = snd_aci_cmd(aci, ACI_READ_VERSION, -1, -1);
- if (aci->aci_version < 0) {
- snd_printk(KERN_ERR "can't read aci version on 0x%lx.\n",
- aci->aci_port);
- return -ENXIO;
- }
-
- if (snd_aci_cmd(aci, ACI_INIT, -1, -1) < 0 ||
- snd_aci_cmd(aci, ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP) < 0 ||
- snd_aci_cmd(aci, ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP) < 0) {
- snd_printk(KERN_ERR "can't initialize aci.\n");
- return -ENXIO;
- }
-
- return 0;
-}
-
-static void snd_card_miro_free(struct snd_card *card)
-{
- struct snd_miro *miro = card->private_data;
-
- release_and_free_resource(miro->res_aci_port);
- if (miro->aci)
- miro->aci->aci_port = 0;
- release_and_free_resource(miro->res_mc_base);
-}
-
-static int __devinit snd_miro_probe(struct snd_card *card)
-{
- int error;
- struct snd_miro *miro = card->private_data;
- struct snd_wss *codec;
- struct snd_timer *timer;
- struct snd_pcm *pcm;
- struct snd_rawmidi *rmidi;
-
- if (!miro->res_mc_base) {
- miro->res_mc_base = request_region(miro->mc_base,
- miro->mc_base_size,
- "miro (OPTi9xx MC)");
- if (miro->res_mc_base == NULL) {
- snd_printk(KERN_ERR "request for OPTI9xx MC failed\n");
- return -ENOMEM;
- }
- }
-
- error = snd_card_miro_aci_detect(card, miro);
- if (error < 0) {
- snd_card_free(card);
- snd_printk(KERN_ERR "unable to detect aci chip\n");
- return -ENODEV;
- }
-
- miro->wss_base = port;
- miro->mpu_port = mpu_port;
- miro->irq = irq;
- miro->mpu_irq = mpu_irq;
- miro->dma1 = dma1;
- miro->dma2 = dma2;
-
- /* init proc interface */
- snd_miro_proc_init(card, miro);
-
- error = snd_miro_configure(miro);
- if (error)
- return error;
-
- error = snd_wss_create(card, miro->wss_base + 4, -1,
- miro->irq, miro->dma1, miro->dma2,
- WSS_HW_DETECT, 0, &codec);
- if (error < 0)
- return error;
-
- error = snd_wss_pcm(codec, 0, &pcm);
- if (error < 0)
- return error;
-
- error = snd_wss_mixer(codec);
- if (error < 0)
- return error;
-
- error = snd_wss_timer(codec, 0, &timer);
- if (error < 0)
- return error;
-
- miro->pcm = pcm;
-
- error = snd_miro_mixer(card, miro);
- if (error < 0)
- return error;
-
- if (miro->aci->aci_vendor == 'm') {
- /* It looks like a miro sound card. */
- switch (miro->aci->aci_product) {
- case 'A':
- sprintf(card->shortname,
- "miroSOUND PCM1 pro / PCM12");
- break;
- case 'B':
- sprintf(card->shortname,
- "miroSOUND PCM12");
- break;
- case 'C':
- sprintf(card->shortname,
- "miroSOUND PCM20 radio");
- break;
- default:
- sprintf(card->shortname,
- "unknown miro");
- snd_printk(KERN_INFO "unknown miro aci id\n");
- break;
- }
- } else {
- snd_printk(KERN_INFO "found unsupported aci card\n");
- sprintf(card->shortname, "unknown Cardinal Technologies");
- }
-
- strcpy(card->driver, "miro");
- sprintf(card->longname, "%s: OPTi%s, %s at 0x%lx, irq %d, dma %d&%d",
- card->shortname, miro->name, pcm->name, miro->wss_base + 4,
- miro->irq, miro->dma1, miro->dma2);
-
- if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT)
- rmidi = NULL;
- else {
- error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
- mpu_port, 0, miro->mpu_irq, &rmidi);
- if (error < 0)
- snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n",
- mpu_port);
- }
-
- if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) {
- struct snd_opl3 *opl3 = NULL;
- struct snd_opl4 *opl4;
-
- if (snd_opl4_create(card, fm_port, fm_port - 8,
- 2, &opl3, &opl4) < 0)
- snd_printk(KERN_WARNING "no OPL4 device at 0x%lx\n",
- fm_port);
- }
-
- error = snd_set_aci_init_values(miro);
- if (error < 0)
- return error;
-
- return snd_card_register(card);
-}
-
-static int __devinit snd_miro_isa_match(struct device *devptr, unsigned int n)
-{
-#ifdef CONFIG_PNP
- if (snd_miro_pnp_is_probed)
- return 0;
- if (isapnp)
- return 0;
-#endif
- return 1;
-}
-
-static int __devinit snd_miro_isa_probe(struct device *devptr, unsigned int n)
-{
- static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
- static long possible_mpu_ports[] = {0x330, 0x300, 0x310, 0x320, -1};
- static int possible_irqs[] = {11, 9, 10, 7, -1};
- static int possible_mpu_irqs[] = {10, 5, 9, 7, -1};
- static int possible_dma1s[] = {3, 1, 0, -1};
- static int possible_dma2s[][2] = { {1, -1}, {0, -1}, {-1, -1},
- {0, -1} };
-
- int error;
- struct snd_miro *miro;
- struct snd_card *card;
-
- error = snd_card_create(index, id, THIS_MODULE,
- sizeof(struct snd_miro), &card);
- if (error < 0)
- return error;
-
- card->private_free = snd_card_miro_free;
- miro = card->private_data;
-
- error = snd_card_miro_detect(card, miro);
- if (error < 0) {
- snd_card_free(card);
- snd_printk(KERN_ERR "unable to detect OPTi9xx chip\n");
- return -ENODEV;
- }
-
- if (port == SNDRV_AUTO_PORT) {
- port = snd_legacy_find_free_ioport(possible_ports, 4);
- if (port < 0) {
- snd_card_free(card);
- snd_printk(KERN_ERR "unable to find a free WSS port\n");
- return -EBUSY;
- }
- }
-
- if (mpu_port == SNDRV_AUTO_PORT) {
- mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2);
- if (mpu_port < 0) {
- snd_card_free(card);
- snd_printk(KERN_ERR
- "unable to find a free MPU401 port\n");
- return -EBUSY;
- }
- }
-
- if (irq == SNDRV_AUTO_IRQ) {
- irq = snd_legacy_find_free_irq(possible_irqs);
- if (irq < 0) {
- snd_card_free(card);
- snd_printk(KERN_ERR "unable to find a free IRQ\n");
- return -EBUSY;
- }
- }
- if (mpu_irq == SNDRV_AUTO_IRQ) {
- mpu_irq = snd_legacy_find_free_irq(possible_mpu_irqs);
- if (mpu_irq < 0) {
- snd_card_free(card);
- snd_printk(KERN_ERR
- "unable to find a free MPU401 IRQ\n");
- return -EBUSY;
- }
- }
- if (dma1 == SNDRV_AUTO_DMA) {
- dma1 = snd_legacy_find_free_dma(possible_dma1s);
- if (dma1 < 0) {
- snd_card_free(card);
- snd_printk(KERN_ERR "unable to find a free DMA1\n");
- return -EBUSY;
- }
- }
- if (dma2 == SNDRV_AUTO_DMA) {
- dma2 = snd_legacy_find_free_dma(possible_dma2s[dma1 % 4]);
- if (dma2 < 0) {
- snd_card_free(card);
- snd_printk(KERN_ERR "unable to find a free DMA2\n");
- return -EBUSY;
- }
- }
-
- snd_card_set_dev(card, devptr);
-
- error = snd_miro_probe(card);
- if (error < 0) {
- snd_card_free(card);
- return error;
- }
-
- dev_set_drvdata(devptr, card);
- return 0;
-}
-
-static int __devexit snd_miro_isa_remove(struct device *devptr,
- unsigned int dev)
-{
- snd_card_free(dev_get_drvdata(devptr));
- dev_set_drvdata(devptr, NULL);
- return 0;
-}
-
-#define DEV_NAME "miro"
-
-static struct isa_driver snd_miro_driver = {
- .match = snd_miro_isa_match,
- .probe = snd_miro_isa_probe,
- .remove = __devexit_p(snd_miro_isa_remove),
- /* FIXME: suspend/resume */
- .driver = {
- .name = DEV_NAME
- },
-};
-
-#ifdef CONFIG_PNP
-
-static int __devinit snd_card_miro_pnp(struct snd_miro *chip,
- struct pnp_card_link *card,
- const struct pnp_card_device_id *pid)
-{
- struct pnp_dev *pdev;
- int err;
- struct pnp_dev *devmpu;
- struct pnp_dev *devmc;
-
- pdev = pnp_request_card_device(card, pid->devs[0].id, NULL);
- if (pdev == NULL)
- return -EBUSY;
-
- devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
- if (devmpu == NULL)
- return -EBUSY;
-
- devmc = pnp_request_card_device(card, pid->devs[2].id, NULL);
- if (devmc == NULL)
- return -EBUSY;
-
- err = pnp_activate_dev(pdev);
- if (err < 0) {
- snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err);
- return err;
- }
-
- err = pnp_activate_dev(devmc);
- if (err < 0) {
- snd_printk(KERN_ERR "MC pnp configure failure: %d\n",
- err);
- return err;
- }
-
- port = pnp_port_start(pdev, 1);
- fm_port = pnp_port_start(pdev, 2) + 8;
-
- /*
- * The MC(0) is never accessed and the miroSOUND PCM20 card does not
- * include it in the PnP resource range. OPTI93x include it.
- */
- chip->mc_base = pnp_port_start(devmc, 0) - 1;
- chip->mc_base_size = pnp_port_len(devmc, 0) + 1;
-
- irq = pnp_irq(pdev, 0);
- dma1 = pnp_dma(pdev, 0);
- dma2 = pnp_dma(pdev, 1);
-
- if (mpu_port > 0) {
- err = pnp_activate_dev(devmpu);
- if (err < 0) {
- snd_printk(KERN_ERR "MPU401 pnp configure failure\n");
- mpu_port = -1;
- return err;
- }
- mpu_port = pnp_port_start(devmpu, 0);
- mpu_irq = pnp_irq(devmpu, 0);
- }
- return 0;
-}
-
-static int __devinit snd_miro_pnp_probe(struct pnp_card_link *pcard,
- const struct pnp_card_device_id *pid)
-{
- struct snd_card *card;
- int err;
- struct snd_miro *miro;
-
- if (snd_miro_pnp_is_probed)
- return -EBUSY;
- if (!isapnp)
- return -ENODEV;
- err = snd_card_create(index, id, THIS_MODULE,
- sizeof(struct snd_miro), &card);
- if (err < 0)
- return err;
-
- card->private_free = snd_card_miro_free;
- miro = card->private_data;
-
- err = snd_card_miro_pnp(miro, pcard, pid);
- if (err) {
- snd_card_free(card);
- return err;
- }
-
- /* only miroSOUND PCM20 and PCM12 == OPTi924 */
- err = snd_miro_init(miro, OPTi9XX_HW_82C924);
- if (err) {
- snd_card_free(card);
- return err;
- }
-
- err = snd_miro_opti_check(miro);
- if (err) {
- snd_printk(KERN_ERR "OPTI chip not found\n");
- snd_card_free(card);
- return err;
- }
-
- snd_card_set_dev(card, &pcard->card->dev);
- err = snd_miro_probe(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- pnp_set_card_drvdata(pcard, card);
- snd_miro_pnp_is_probed = 1;
- return 0;
-}
-
-static void __devexit snd_miro_pnp_remove(struct pnp_card_link * pcard)
-{
- snd_card_free(pnp_get_card_drvdata(pcard));
- pnp_set_card_drvdata(pcard, NULL);
- snd_miro_pnp_is_probed = 0;
-}
-
-static struct pnp_card_driver miro_pnpc_driver = {
- .flags = PNP_DRIVER_RES_DISABLE,
- .name = "miro",
- .id_table = snd_miro_pnpids,
- .probe = snd_miro_pnp_probe,
- .remove = __devexit_p(snd_miro_pnp_remove),
-};
-#endif
-
-static int __init alsa_card_miro_init(void)
-{
-#ifdef CONFIG_PNP
- pnp_register_card_driver(&miro_pnpc_driver);
- if (snd_miro_pnp_is_probed)
- return 0;
- pnp_unregister_card_driver(&miro_pnpc_driver);
-#endif
- return isa_register_driver(&snd_miro_driver, 1);
-}
-
-static void __exit alsa_card_miro_exit(void)
-{
- if (!snd_miro_pnp_is_probed) {
- isa_unregister_driver(&snd_miro_driver);
- return;
- }
-#ifdef CONFIG_PNP
- pnp_unregister_card_driver(&miro_pnpc_driver);
-#endif
-}
-
-module_init(alsa_card_miro_init)
-module_exit(alsa_card_miro_exit)
diff --git a/ANDROID_3.4.5/sound/isa/opti9xx/opti92x-ad1848.c b/ANDROID_3.4.5/sound/isa/opti9xx/opti92x-ad1848.c
deleted file mode 100644
index d7ccf28b..00000000
--- a/ANDROID_3.4.5/sound/isa/opti9xx/opti92x-ad1848.c
+++ /dev/null
@@ -1,1165 +0,0 @@
-/*
- card-opti92x-ad1848.c - driver for OPTi 82c92x based soundcards.
- Copyright (C) 1998-2000 by Massimo Piccioni <dafastidio@libero.it>
-
- Part of this code was developed at the Italian Ministry of Air Defence,
- Sixth Division (oh, che pace ...), Rome.
-
- Thanks to Maria Grazia Pollarini, Salvatore Vassallo.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/isa.h>
-#include <linux/delay.h>
-#include <linux/pnp.h>
-#include <linux/module.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <sound/core.h>
-#include <sound/tlv.h>
-#include <sound/wss.h>
-#include <sound/mpu401.h>
-#include <sound/opl3.h>
-#ifndef OPTi93X
-#include <sound/opl4.h>
-#endif
-#define SNDRV_LEGACY_FIND_FREE_IRQ
-#define SNDRV_LEGACY_FIND_FREE_DMA
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
-MODULE_LICENSE("GPL");
-#ifdef OPTi93X
-MODULE_DESCRIPTION("OPTi93X");
-MODULE_SUPPORTED_DEVICE("{{OPTi,82C931/3}}");
-#else /* OPTi93X */
-#ifdef CS4231
-MODULE_DESCRIPTION("OPTi92X - CS4231");
-MODULE_SUPPORTED_DEVICE("{{OPTi,82C924 (CS4231)},"
- "{OPTi,82C925 (CS4231)}}");
-#else /* CS4231 */
-MODULE_DESCRIPTION("OPTi92X - AD1848");
-MODULE_SUPPORTED_DEVICE("{{OPTi,82C924 (AD1848)},"
- "{OPTi,82C925 (AD1848)},"
- "{OAK,Mozart}}");
-#endif /* CS4231 */
-#endif /* OPTi93X */
-
-static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
-static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-//static bool enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */
-#ifdef CONFIG_PNP
-static bool isapnp = true; /* Enable ISA PnP detection */
-#endif
-static long port = SNDRV_DEFAULT_PORT1; /* 0x530,0xe80,0xf40,0x604 */
-static long mpu_port = SNDRV_DEFAULT_PORT1; /* 0x300,0x310,0x320,0x330 */
-static long fm_port = SNDRV_DEFAULT_PORT1; /* 0x388 */
-static int irq = SNDRV_DEFAULT_IRQ1; /* 5,7,9,10,11 */
-static int mpu_irq = SNDRV_DEFAULT_IRQ1; /* 5,7,9,10 */
-static int dma1 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */
-#if defined(CS4231) || defined(OPTi93X)
-static int dma2 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */
-#endif /* CS4231 || OPTi93X */
-
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for opti9xx based soundcard.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for opti9xx based soundcard.");
-//module_param(enable, bool, 0444);
-//MODULE_PARM_DESC(enable, "Enable opti9xx soundcard.");
-#ifdef CONFIG_PNP
-module_param(isapnp, bool, 0444);
-MODULE_PARM_DESC(isapnp, "Enable ISA PnP detection for specified soundcard.");
-#endif
-module_param(port, long, 0444);
-MODULE_PARM_DESC(port, "WSS port # for opti9xx driver.");
-module_param(mpu_port, long, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port # for opti9xx driver.");
-module_param(fm_port, long, 0444);
-MODULE_PARM_DESC(fm_port, "FM port # for opti9xx driver.");
-module_param(irq, int, 0444);
-MODULE_PARM_DESC(irq, "WSS irq # for opti9xx driver.");
-module_param(mpu_irq, int, 0444);
-MODULE_PARM_DESC(mpu_irq, "MPU-401 irq # for opti9xx driver.");
-module_param(dma1, int, 0444);
-MODULE_PARM_DESC(dma1, "1st dma # for opti9xx driver.");
-#if defined(CS4231) || defined(OPTi93X)
-module_param(dma2, int, 0444);
-MODULE_PARM_DESC(dma2, "2nd dma # for opti9xx driver.");
-#endif /* CS4231 || OPTi93X */
-
-#define OPTi9XX_HW_82C928 1
-#define OPTi9XX_HW_82C929 2
-#define OPTi9XX_HW_82C924 3
-#define OPTi9XX_HW_82C925 4
-#define OPTi9XX_HW_82C930 5
-#define OPTi9XX_HW_82C931 6
-#define OPTi9XX_HW_82C933 7
-#define OPTi9XX_HW_LAST OPTi9XX_HW_82C933
-
-#define OPTi9XX_MC_REG(n) n
-
-#ifdef OPTi93X
-
-#define OPTi93X_STATUS 0x02
-#define OPTi93X_PORT(chip, r) ((chip)->port + OPTi93X_##r)
-
-#define OPTi93X_IRQ_PLAYBACK 0x04
-#define OPTi93X_IRQ_CAPTURE 0x08
-
-#endif /* OPTi93X */
-
-struct snd_opti9xx {
- unsigned short hardware;
- unsigned char password;
- char name[7];
-
- unsigned long mc_base;
- struct resource *res_mc_base;
- unsigned long mc_base_size;
-#ifdef OPTi93X
- unsigned long mc_indir_index;
- unsigned long mc_indir_size;
- struct resource *res_mc_indir;
- struct snd_wss *codec;
-#endif /* OPTi93X */
- unsigned long pwd_reg;
-
- spinlock_t lock;
-
- long wss_base;
- int irq;
-};
-
-static int snd_opti9xx_pnp_is_probed;
-
-#ifdef CONFIG_PNP
-
-static struct pnp_card_device_id snd_opti9xx_pnpids[] = {
-#ifndef OPTi93X
- /* OPTi 82C924 */
- { .id = "OPT0924",
- .devs = { { "OPT0000" }, { "OPT0002" }, { "OPT0005" } },
- .driver_data = 0x0924 },
- /* OPTi 82C925 */
- { .id = "OPT0925",
- .devs = { { "OPT9250" }, { "OPT0002" }, { "OPT0005" } },
- .driver_data = 0x0925 },
-#else
- /* OPTi 82C931/3 */
- { .id = "OPT0931", .devs = { { "OPT9310" }, { "OPT0002" } },
- .driver_data = 0x0931 },
-#endif /* OPTi93X */
- { .id = "" }
-};
-
-MODULE_DEVICE_TABLE(pnp_card, snd_opti9xx_pnpids);
-
-#endif /* CONFIG_PNP */
-
-#ifdef OPTi93X
-#define DEV_NAME "opti93x"
-#else
-#define DEV_NAME "opti92x"
-#endif
-
-static char * snd_opti9xx_names[] = {
- "unknown",
- "82C928", "82C929",
- "82C924", "82C925",
- "82C930", "82C931", "82C933"
-};
-
-
-static long __devinit snd_legacy_find_free_ioport(long *port_table, long size)
-{
- while (*port_table != -1) {
- if (request_region(*port_table, size, "ALSA test")) {
- release_region(*port_table, size);
- return *port_table;
- }
- port_table++;
- }
- return -1;
-}
-
-static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
- unsigned short hardware)
-{
- static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2};
-
- chip->hardware = hardware;
- strcpy(chip->name, snd_opti9xx_names[hardware]);
-
- spin_lock_init(&chip->lock);
-
- chip->irq = -1;
-
-#ifndef OPTi93X
-#ifdef CONFIG_PNP
- if (isapnp && chip->mc_base)
- /* PnP resource gives the least 10 bits */
- chip->mc_base |= 0xc00;
- else
-#endif /* CONFIG_PNP */
- {
- chip->mc_base = 0xf8c;
- chip->mc_base_size = opti9xx_mc_size[hardware];
- }
-#else
- chip->mc_base_size = opti9xx_mc_size[hardware];
-#endif
-
- switch (hardware) {
-#ifndef OPTi93X
- case OPTi9XX_HW_82C928:
- case OPTi9XX_HW_82C929:
- chip->password = (hardware == OPTi9XX_HW_82C928) ? 0xe2 : 0xe3;
- chip->pwd_reg = 3;
- break;
-
- case OPTi9XX_HW_82C924:
- case OPTi9XX_HW_82C925:
- chip->password = 0xe5;
- chip->pwd_reg = 3;
- break;
-#else /* OPTi93X */
-
- case OPTi9XX_HW_82C930:
- case OPTi9XX_HW_82C931:
- case OPTi9XX_HW_82C933:
- chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d;
- if (!chip->mc_indir_index) {
- chip->mc_indir_index = 0xe0e;
- chip->mc_indir_size = 2;
- }
- chip->password = 0xe4;
- chip->pwd_reg = 0;
- break;
-#endif /* OPTi93X */
-
- default:
- snd_printk(KERN_ERR "chip %d not supported\n", hardware);
- return -ENODEV;
- }
- return 0;
-}
-
-static unsigned char snd_opti9xx_read(struct snd_opti9xx *chip,
- unsigned char reg)
-{
- unsigned long flags;
- unsigned char retval = 0xff;
-
- spin_lock_irqsave(&chip->lock, flags);
- outb(chip->password, chip->mc_base + chip->pwd_reg);
-
- switch (chip->hardware) {
-#ifndef OPTi93X
- case OPTi9XX_HW_82C924:
- case OPTi9XX_HW_82C925:
- if (reg > 7) {
- outb(reg, chip->mc_base + 8);
- outb(chip->password, chip->mc_base + chip->pwd_reg);
- retval = inb(chip->mc_base + 9);
- break;
- }
-
- case OPTi9XX_HW_82C928:
- case OPTi9XX_HW_82C929:
- retval = inb(chip->mc_base + reg);
- break;
-#else /* OPTi93X */
-
- case OPTi9XX_HW_82C930:
- case OPTi9XX_HW_82C931:
- case OPTi9XX_HW_82C933:
- outb(reg, chip->mc_indir_index);
- outb(chip->password, chip->mc_base + chip->pwd_reg);
- retval = inb(chip->mc_indir_index + 1);
- break;
-#endif /* OPTi93X */
-
- default:
- snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware);
- }
-
- spin_unlock_irqrestore(&chip->lock, flags);
- return retval;
-}
-
-static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
- unsigned char value)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&chip->lock, flags);
- outb(chip->password, chip->mc_base + chip->pwd_reg);
-
- switch (chip->hardware) {
-#ifndef OPTi93X
- case OPTi9XX_HW_82C924:
- case OPTi9XX_HW_82C925:
- if (reg > 7) {
- outb(reg, chip->mc_base + 8);
- outb(chip->password, chip->mc_base + chip->pwd_reg);
- outb(value, chip->mc_base + 9);
- break;
- }
-
- case OPTi9XX_HW_82C928:
- case OPTi9XX_HW_82C929:
- outb(value, chip->mc_base + reg);
- break;
-#else /* OPTi93X */
-
- case OPTi9XX_HW_82C930:
- case OPTi9XX_HW_82C931:
- case OPTi9XX_HW_82C933:
- outb(reg, chip->mc_indir_index);
- outb(chip->password, chip->mc_base + chip->pwd_reg);
- outb(value, chip->mc_indir_index + 1);
- break;
-#endif /* OPTi93X */
-
- default:
- snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware);
- }
-
- spin_unlock_irqrestore(&chip->lock, flags);
-}
-
-
-#define snd_opti9xx_write_mask(chip, reg, value, mask) \
- snd_opti9xx_write(chip, reg, \
- (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask)))
-
-
-static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
- long port,
- int irq, int dma1, int dma2,
- long mpu_port, int mpu_irq)
-{
- unsigned char wss_base_bits;
- unsigned char irq_bits;
- unsigned char dma_bits;
- unsigned char mpu_port_bits = 0;
- unsigned char mpu_irq_bits;
-
- switch (chip->hardware) {
-#ifndef OPTi93X
- case OPTi9XX_HW_82C924:
- /* opti 929 mode (?), OPL3 clock output, audio enable */
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0xf0, 0xfc);
- /* enable wave audio */
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02);
-
- case OPTi9XX_HW_82C925:
- /* enable WSS mode */
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
- /* OPL3 FM synthesis */
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20);
- /* disable Sound Blaster IRQ and DMA */
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff);
-#ifdef CS4231
- /* cs4231/4248 fix enabled */
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
-#else
- /* cs4231/4248 fix disabled */
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02);
-#endif /* CS4231 */
- break;
-
- case OPTi9XX_HW_82C928:
- case OPTi9XX_HW_82C929:
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20);
- /*
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xa2, 0xae);
- */
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0x00, 0x0c);
-#ifdef CS4231
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
-#else
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02);
-#endif /* CS4231 */
- break;
-
-#else /* OPTi93X */
- case OPTi9XX_HW_82C931:
- case OPTi9XX_HW_82C933:
- /*
- * The BTC 1817DW has QS1000 wavetable which is connected
- * to the serial digital input of the OPTI931.
- */
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(21), 0x82, 0xff);
- /*
- * This bit sets OPTI931 to automaticaly select FM
- * or digital input signal.
- */
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(26), 0x01, 0x01);
- case OPTi9XX_HW_82C930: /* FALL THROUGH */
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x03);
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0x00, 0xff);
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0x10 |
- (chip->hardware == OPTi9XX_HW_82C930 ? 0x00 : 0x04),
- 0x34);
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x20, 0xbf);
- break;
-#endif /* OPTi93X */
-
- default:
- snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware);
- return -EINVAL;
- }
-
- /* PnP resource says it decodes only 10 bits of address */
- switch (port & 0x3ff) {
- case 0x130:
- chip->wss_base = 0x530;
- wss_base_bits = 0x00;
- break;
- case 0x204:
- chip->wss_base = 0x604;
- wss_base_bits = 0x03;
- break;
- case 0x280:
- chip->wss_base = 0xe80;
- wss_base_bits = 0x01;
- break;
- case 0x340:
- chip->wss_base = 0xf40;
- wss_base_bits = 0x02;
- break;
- default:
- snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", port);
- goto __skip_base;
- }
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30);
-
-__skip_base:
- switch (irq) {
-//#ifdef OPTi93X
- case 5:
- irq_bits = 0x05;
- break;
-//#endif /* OPTi93X */
- case 7:
- irq_bits = 0x01;
- break;
- case 9:
- irq_bits = 0x02;
- break;
- case 10:
- irq_bits = 0x03;
- break;
- case 11:
- irq_bits = 0x04;
- break;
- default:
- snd_printk(KERN_WARNING "WSS irq # %d not valid\n", irq);
- goto __skip_resources;
- }
-
- switch (dma1) {
- case 0:
- dma_bits = 0x01;
- break;
- case 1:
- dma_bits = 0x02;
- break;
- case 3:
- dma_bits = 0x03;
- break;
- default:
- snd_printk(KERN_WARNING "WSS dma1 # %d not valid\n", dma1);
- goto __skip_resources;
- }
-
-#if defined(CS4231) || defined(OPTi93X)
- if (dma1 == dma2) {
- snd_printk(KERN_ERR "don't want to share dmas\n");
- return -EBUSY;
- }
-
- switch (dma2) {
- case 0:
- case 1:
- break;
- default:
- snd_printk(KERN_WARNING "WSS dma2 # %d not valid\n", dma2);
- goto __skip_resources;
- }
- dma_bits |= 0x04;
-#endif /* CS4231 || OPTi93X */
-
-#ifndef OPTi93X
- outb(irq_bits << 3 | dma_bits, chip->wss_base);
-#else /* OPTi93X */
- snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits));
-#endif /* OPTi93X */
-
-__skip_resources:
- if (chip->hardware > OPTi9XX_HW_82C928) {
- switch (mpu_port) {
- case 0:
- case -1:
- break;
- case 0x300:
- mpu_port_bits = 0x03;
- break;
- case 0x310:
- mpu_port_bits = 0x02;
- break;
- case 0x320:
- mpu_port_bits = 0x01;
- break;
- case 0x330:
- mpu_port_bits = 0x00;
- break;
- default:
- snd_printk(KERN_WARNING
- "MPU-401 port 0x%lx not valid\n", mpu_port);
- goto __skip_mpu;
- }
-
- switch (mpu_irq) {
- case 5:
- mpu_irq_bits = 0x02;
- break;
- case 7:
- mpu_irq_bits = 0x03;
- break;
- case 9:
- mpu_irq_bits = 0x00;
- break;
- case 10:
- mpu_irq_bits = 0x01;
- break;
- default:
- snd_printk(KERN_WARNING "MPU-401 irq # %d not valid\n",
- mpu_irq);
- goto __skip_mpu;
- }
-
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6),
- (mpu_port <= 0) ? 0x00 :
- 0x80 | mpu_port_bits << 5 | mpu_irq_bits << 3,
- 0xf8);
- }
-__skip_mpu:
-
- return 0;
-}
-
-#ifdef OPTi93X
-
-static const DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_step, -9300, 300, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_4bit_12db_max, -3300, 300, 0);
-
-static struct snd_kcontrol_new snd_opti93x_controls[] = {
-WSS_DOUBLE("Master Playback Switch", 0,
- OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
-WSS_DOUBLE_TLV("Master Playback Volume", 0,
- OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1,
- db_scale_5bit_3db_step),
-WSS_DOUBLE_TLV("PCM Playback Volume", 0,
- CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1,
- db_scale_5bit),
-WSS_DOUBLE_TLV("FM Playback Volume", 0,
- CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1,
- db_scale_4bit_12db_max),
-WSS_DOUBLE("Line Playback Switch", 0,
- CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
-WSS_DOUBLE_TLV("Line Playback Volume", 0,
- CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1,
- db_scale_4bit_12db_max),
-WSS_DOUBLE("Mic Playback Switch", 0,
- OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1),
-WSS_DOUBLE_TLV("Mic Playback Volume", 0,
- OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1,
- db_scale_4bit_12db_max),
-WSS_DOUBLE_TLV("CD Playback Volume", 0,
- CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1,
- db_scale_4bit_12db_max),
-WSS_DOUBLE("Aux Playback Switch", 0,
- OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1),
-WSS_DOUBLE_TLV("Aux Playback Volume", 0,
- OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1,
- db_scale_4bit_12db_max),
-};
-
-static int __devinit snd_opti93x_mixer(struct snd_wss *chip)
-{
- struct snd_card *card;
- unsigned int idx;
- struct snd_ctl_elem_id id1, id2;
- int err;
-
- if (snd_BUG_ON(!chip || !chip->pcm))
- return -EINVAL;
-
- card = chip->card;
-
- strcpy(card->mixername, chip->pcm->name);
-
- memset(&id1, 0, sizeof(id1));
- memset(&id2, 0, sizeof(id2));
- id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- /* reassign AUX0 switch to CD */
- strcpy(id1.name, "Aux Playback Switch");
- strcpy(id2.name, "CD Playback Switch");
- err = snd_ctl_rename_id(card, &id1, &id2);
- if (err < 0) {
- snd_printk(KERN_ERR "Cannot rename opti93x control\n");
- return err;
- }
- /* reassign AUX1 switch to FM */
- strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
- strcpy(id2.name, "FM Playback Switch");
- err = snd_ctl_rename_id(card, &id1, &id2);
- if (err < 0) {
- snd_printk(KERN_ERR "Cannot rename opti93x control\n");
- return err;
- }
- /* remove AUX1 volume */
- strcpy(id1.name, "Aux Playback Volume"); id1.index = 1;
- snd_ctl_remove_id(card, &id1);
-
- /* Replace WSS volume controls with OPTi93x volume controls */
- id1.index = 0;
- for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) {
- strcpy(id1.name, snd_opti93x_controls[idx].name);
- snd_ctl_remove_id(card, &id1);
-
- err = snd_ctl_add(card,
- snd_ctl_new1(&snd_opti93x_controls[idx], chip));
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id)
-{
- struct snd_opti9xx *chip = dev_id;
- struct snd_wss *codec = chip->codec;
- unsigned char status;
-
- if (!codec)
- return IRQ_HANDLED;
-
- status = snd_opti9xx_read(chip, OPTi9XX_MC_REG(11));
- if ((status & OPTi93X_IRQ_PLAYBACK) && codec->playback_substream)
- snd_pcm_period_elapsed(codec->playback_substream);
- if ((status & OPTi93X_IRQ_CAPTURE) && codec->capture_substream) {
- snd_wss_overrange(codec);
- snd_pcm_period_elapsed(codec->capture_substream);
- }
- outb(0x00, OPTi93X_PORT(codec, STATUS));
- return IRQ_HANDLED;
-}
-
-#endif /* OPTi93X */
-
-static int __devinit snd_opti9xx_read_check(struct snd_opti9xx *chip)
-{
- unsigned char value;
-#ifdef OPTi93X
- unsigned long flags;
-#endif
-
- chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
- "OPTi9xx MC");
- if (chip->res_mc_base == NULL)
- return -EBUSY;
-#ifndef OPTi93X
- value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(1));
- if (value != 0xff && value != inb(chip->mc_base + OPTi9XX_MC_REG(1)))
- if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)))
- return 0;
-#else /* OPTi93X */
- chip->res_mc_indir = request_region(chip->mc_indir_index,
- chip->mc_indir_size,
- "OPTi93x MC");
- if (chip->res_mc_indir == NULL)
- return -EBUSY;
-
- spin_lock_irqsave(&chip->lock, flags);
- outb(chip->password, chip->mc_base + chip->pwd_reg);
- outb(((chip->mc_indir_index & 0x1f0) >> 4), chip->mc_base);
- spin_unlock_irqrestore(&chip->lock, flags);
-
- value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(7));
- snd_opti9xx_write(chip, OPTi9XX_MC_REG(7), 0xff - value);
- if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value)
- return 0;
-
- release_and_free_resource(chip->res_mc_indir);
- chip->res_mc_indir = NULL;
-#endif /* OPTi93X */
- release_and_free_resource(chip->res_mc_base);
- chip->res_mc_base = NULL;
-
- return -ENODEV;
-}
-
-static int __devinit snd_card_opti9xx_detect(struct snd_card *card,
- struct snd_opti9xx *chip)
-{
- int i, err;
-
-#ifndef OPTi93X
- for (i = OPTi9XX_HW_82C928; i < OPTi9XX_HW_82C930; i++) {
-#else
- for (i = OPTi9XX_HW_82C931; i >= OPTi9XX_HW_82C930; i--) {
-#endif
- err = snd_opti9xx_init(chip, i);
- if (err < 0)
- return err;
-
- err = snd_opti9xx_read_check(chip);
- if (err == 0)
- return 1;
-#ifdef OPTi93X
- chip->mc_indir_index = 0;
-#endif
- }
- return -ENODEV;
-}
-
-#ifdef CONFIG_PNP
-static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
- struct pnp_card_link *card,
- const struct pnp_card_device_id *pid)
-{
- struct pnp_dev *pdev;
- int err;
- struct pnp_dev *devmpu;
-#ifndef OPTi93X
- struct pnp_dev *devmc;
-#endif
-
- pdev = pnp_request_card_device(card, pid->devs[0].id, NULL);
- if (pdev == NULL)
- return -EBUSY;
-
- err = pnp_activate_dev(pdev);
- if (err < 0) {
- snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err);
- return err;
- }
-
-#ifdef OPTi93X
- port = pnp_port_start(pdev, 0) - 4;
- fm_port = pnp_port_start(pdev, 1) + 8;
- chip->mc_indir_index = pnp_port_start(pdev, 3) + 2;
- chip->mc_indir_size = pnp_port_len(pdev, 3) - 2;
-#else
- devmc = pnp_request_card_device(card, pid->devs[2].id, NULL);
- if (devmc == NULL)
- return -EBUSY;
-
- err = pnp_activate_dev(devmc);
- if (err < 0) {
- snd_printk(KERN_ERR "MC pnp configure failure: %d\n", err);
- return err;
- }
-
- port = pnp_port_start(pdev, 1);
- fm_port = pnp_port_start(pdev, 2) + 8;
- /*
- * The MC(0) is never accessed and card does not
- * include it in the PnP resource range. OPTI93x include it.
- */
- chip->mc_base = pnp_port_start(devmc, 0) - 1;
- chip->mc_base_size = pnp_port_len(devmc, 0) + 1;
-#endif /* OPTi93X */
- irq = pnp_irq(pdev, 0);
- dma1 = pnp_dma(pdev, 0);
-#if defined(CS4231) || defined(OPTi93X)
- dma2 = pnp_dma(pdev, 1);
-#endif /* CS4231 || OPTi93X */
-
- devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
-
- if (devmpu && mpu_port > 0) {
- err = pnp_activate_dev(devmpu);
- if (err < 0) {
- snd_printk(KERN_ERR "MPU401 pnp configure failure\n");
- mpu_port = -1;
- } else {
- mpu_port = pnp_port_start(devmpu, 0);
- mpu_irq = pnp_irq(devmpu, 0);
- }
- }
- return pid->driver_data;
-}
-#endif /* CONFIG_PNP */
-
-static void snd_card_opti9xx_free(struct snd_card *card)
-{
- struct snd_opti9xx *chip = card->private_data;
-
- if (chip) {
-#ifdef OPTi93X
- if (chip->irq > 0) {
- disable_irq(chip->irq);
- free_irq(chip->irq, chip);
- }
- release_and_free_resource(chip->res_mc_indir);
-#endif
- release_and_free_resource(chip->res_mc_base);
- }
-}
-
-static int __devinit snd_opti9xx_probe(struct snd_card *card)
-{
- static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
- int error;
- int xdma2;
- struct snd_opti9xx *chip = card->private_data;
- struct snd_wss *codec;
-#ifdef CS4231
- struct snd_timer *timer;
-#endif
- struct snd_pcm *pcm;
- struct snd_rawmidi *rmidi;
- struct snd_hwdep *synth;
-
-#if defined(CS4231) || defined(OPTi93X)
- xdma2 = dma2;
-#else
- xdma2 = -1;
-#endif
-
- if (port == SNDRV_AUTO_PORT) {
- port = snd_legacy_find_free_ioport(possible_ports, 4);
- if (port < 0) {
- snd_printk(KERN_ERR "unable to find a free WSS port\n");
- return -EBUSY;
- }
- }
- error = snd_opti9xx_configure(chip, port, irq, dma1, xdma2,
- mpu_port, mpu_irq);
- if (error)
- return error;
-
- error = snd_wss_create(card, chip->wss_base + 4, -1, irq, dma1, xdma2,
-#ifdef OPTi93X
- WSS_HW_OPTI93X, WSS_HWSHARE_IRQ,
-#else
- WSS_HW_DETECT, 0,
-#endif
- &codec);
- if (error < 0)
- return error;
-#ifdef OPTi93X
- chip->codec = codec;
-#endif
- error = snd_wss_pcm(codec, 0, &pcm);
- if (error < 0)
- return error;
- error = snd_wss_mixer(codec);
- if (error < 0)
- return error;
-#ifdef OPTi93X
- error = snd_opti93x_mixer(codec);
- if (error < 0)
- return error;
-#endif
-#ifdef CS4231
- error = snd_wss_timer(codec, 0, &timer);
- if (error < 0)
- return error;
-#endif
-#ifdef OPTi93X
- error = request_irq(irq, snd_opti93x_interrupt,
- 0, DEV_NAME" - WSS", chip);
- if (error < 0) {
- snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", irq);
- return error;
- }
-#endif
- chip->irq = irq;
- strcpy(card->driver, chip->name);
- sprintf(card->shortname, "OPTi %s", card->driver);
-#if defined(CS4231) || defined(OPTi93X)
- sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d",
- card->shortname, pcm->name,
- chip->wss_base + 4, irq, dma1, xdma2);
-#else
- sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
- card->shortname, pcm->name, chip->wss_base + 4, irq, dma1);
-#endif /* CS4231 || OPTi93X */
-
- if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT)
- rmidi = NULL;
- else {
- error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
- mpu_port, 0, mpu_irq, &rmidi);
- if (error)
- snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n",
- mpu_port);
- }
-
- if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) {
- struct snd_opl3 *opl3 = NULL;
-#ifndef OPTi93X
- if (chip->hardware == OPTi9XX_HW_82C928 ||
- chip->hardware == OPTi9XX_HW_82C929 ||
- chip->hardware == OPTi9XX_HW_82C924) {
- struct snd_opl4 *opl4;
- /* assume we have an OPL4 */
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2),
- 0x20, 0x20);
- if (snd_opl4_create(card, fm_port, fm_port - 8,
- 2, &opl3, &opl4) < 0) {
- /* no luck, use OPL3 instead */
- snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2),
- 0x00, 0x20);
- }
- }
-#endif /* !OPTi93X */
- if (!opl3 && snd_opl3_create(card, fm_port, fm_port + 2,
- OPL3_HW_AUTO, 0, &opl3) < 0) {
- snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n",
- fm_port, fm_port + 4 - 1);
- }
- if (opl3) {
- error = snd_opl3_hwdep_new(opl3, 0, 1, &synth);
- if (error < 0)
- return error;
- }
- }
-
- return snd_card_register(card);
-}
-
-static int snd_opti9xx_card_new(struct snd_card **cardp)
-{
- struct snd_card *card;
- int err;
-
- err = snd_card_create(index, id, THIS_MODULE,
- sizeof(struct snd_opti9xx), &card);
- if (err < 0)
- return err;
- card->private_free = snd_card_opti9xx_free;
- *cardp = card;
- return 0;
-}
-
-static int __devinit snd_opti9xx_isa_match(struct device *devptr,
- unsigned int dev)
-{
-#ifdef CONFIG_PNP
- if (snd_opti9xx_pnp_is_probed)
- return 0;
- if (isapnp)
- return 0;
-#endif
- return 1;
-}
-
-static int __devinit snd_opti9xx_isa_probe(struct device *devptr,
- unsigned int dev)
-{
- struct snd_card *card;
- int error;
- static long possible_mpu_ports[] = {0x300, 0x310, 0x320, 0x330, -1};
-#ifdef OPTi93X
- static int possible_irqs[] = {5, 9, 10, 11, 7, -1};
-#else
- static int possible_irqs[] = {9, 10, 11, 7, -1};
-#endif /* OPTi93X */
- static int possible_mpu_irqs[] = {5, 9, 10, 7, -1};
- static int possible_dma1s[] = {3, 1, 0, -1};
-#if defined(CS4231) || defined(OPTi93X)
- static int possible_dma2s[][2] = {{1,-1}, {0,-1}, {-1,-1}, {0,-1}};
-#endif /* CS4231 || OPTi93X */
-
- if (mpu_port == SNDRV_AUTO_PORT) {
- if ((mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2)) < 0) {
- snd_printk(KERN_ERR "unable to find a free MPU401 port\n");
- return -EBUSY;
- }
- }
- if (irq == SNDRV_AUTO_IRQ) {
- if ((irq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
- snd_printk(KERN_ERR "unable to find a free IRQ\n");
- return -EBUSY;
- }
- }
- if (mpu_irq == SNDRV_AUTO_IRQ) {
- if ((mpu_irq = snd_legacy_find_free_irq(possible_mpu_irqs)) < 0) {
- snd_printk(KERN_ERR "unable to find a free MPU401 IRQ\n");
- return -EBUSY;
- }
- }
- if (dma1 == SNDRV_AUTO_DMA) {
- if ((dma1 = snd_legacy_find_free_dma(possible_dma1s)) < 0) {
- snd_printk(KERN_ERR "unable to find a free DMA1\n");
- return -EBUSY;
- }
- }
-#if defined(CS4231) || defined(OPTi93X)
- if (dma2 == SNDRV_AUTO_DMA) {
- if ((dma2 = snd_legacy_find_free_dma(possible_dma2s[dma1 % 4])) < 0) {
- snd_printk(KERN_ERR "unable to find a free DMA2\n");
- return -EBUSY;
- }
- }
-#endif
-
- error = snd_opti9xx_card_new(&card);
- if (error < 0)
- return error;
-
- if ((error = snd_card_opti9xx_detect(card, card->private_data)) < 0) {
- snd_card_free(card);
- return error;
- }
- snd_card_set_dev(card, devptr);
- if ((error = snd_opti9xx_probe(card)) < 0) {
- snd_card_free(card);
- return error;
- }
- dev_set_drvdata(devptr, card);
- return 0;
-}
-
-static int __devexit snd_opti9xx_isa_remove(struct device *devptr,
- unsigned int dev)
-{
- snd_card_free(dev_get_drvdata(devptr));
- dev_set_drvdata(devptr, NULL);
- return 0;
-}
-
-static struct isa_driver snd_opti9xx_driver = {
- .match = snd_opti9xx_isa_match,
- .probe = snd_opti9xx_isa_probe,
- .remove = __devexit_p(snd_opti9xx_isa_remove),
- /* FIXME: suspend/resume */
- .driver = {
- .name = DEV_NAME
- },
-};
-
-#ifdef CONFIG_PNP
-static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
- const struct pnp_card_device_id *pid)
-{
- struct snd_card *card;
- int error, hw;
- struct snd_opti9xx *chip;
-
- if (snd_opti9xx_pnp_is_probed)
- return -EBUSY;
- if (! isapnp)
- return -ENODEV;
- error = snd_opti9xx_card_new(&card);
- if (error < 0)
- return error;
- chip = card->private_data;
-
- hw = snd_card_opti9xx_pnp(chip, pcard, pid);
- switch (hw) {
- case 0x0924:
- hw = OPTi9XX_HW_82C924;
- break;
- case 0x0925:
- hw = OPTi9XX_HW_82C925;
- break;
- case 0x0931:
- hw = OPTi9XX_HW_82C931;
- break;
- default:
- snd_card_free(card);
- return -ENODEV;
- }
-
- if ((error = snd_opti9xx_init(chip, hw))) {
- snd_card_free(card);
- return error;
- }
- error = snd_opti9xx_read_check(chip);
- if (error) {
- snd_printk(KERN_ERR "OPTI chip not found\n");
- snd_card_free(card);
- return error;
- }
- snd_card_set_dev(card, &pcard->card->dev);
- if ((error = snd_opti9xx_probe(card)) < 0) {
- snd_card_free(card);
- return error;
- }
- pnp_set_card_drvdata(pcard, card);
- snd_opti9xx_pnp_is_probed = 1;
- return 0;
-}
-
-static void __devexit snd_opti9xx_pnp_remove(struct pnp_card_link * pcard)
-{
- snd_card_free(pnp_get_card_drvdata(pcard));
- pnp_set_card_drvdata(pcard, NULL);
- snd_opti9xx_pnp_is_probed = 0;
-}
-
-static struct pnp_card_driver opti9xx_pnpc_driver = {
- .flags = PNP_DRIVER_RES_DISABLE,
- .name = "opti9xx",
- .id_table = snd_opti9xx_pnpids,
- .probe = snd_opti9xx_pnp_probe,
- .remove = __devexit_p(snd_opti9xx_pnp_remove),
-};
-#endif
-
-#ifdef OPTi93X
-#define CHIP_NAME "82C93x"
-#else
-#define CHIP_NAME "82C92x"
-#endif
-
-static int __init alsa_card_opti9xx_init(void)
-{
-#ifdef CONFIG_PNP
- pnp_register_card_driver(&opti9xx_pnpc_driver);
- if (snd_opti9xx_pnp_is_probed)
- return 0;
- pnp_unregister_card_driver(&opti9xx_pnpc_driver);
-#endif
- return isa_register_driver(&snd_opti9xx_driver, 1);
-}
-
-static void __exit alsa_card_opti9xx_exit(void)
-{
- if (!snd_opti9xx_pnp_is_probed) {
- isa_unregister_driver(&snd_opti9xx_driver);
- return;
- }
-#ifdef CONFIG_PNP
- pnp_unregister_card_driver(&opti9xx_pnpc_driver);
-#endif
-}
-
-module_init(alsa_card_opti9xx_init)
-module_exit(alsa_card_opti9xx_exit)
diff --git a/ANDROID_3.4.5/sound/isa/opti9xx/opti92x-cs4231.c b/ANDROID_3.4.5/sound/isa/opti9xx/opti92x-cs4231.c
deleted file mode 100644
index b17ab19f..00000000
--- a/ANDROID_3.4.5/sound/isa/opti9xx/opti92x-cs4231.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define CS4231
-#include "opti92x-ad1848.c"
diff --git a/ANDROID_3.4.5/sound/isa/opti9xx/opti93x.c b/ANDROID_3.4.5/sound/isa/opti9xx/opti93x.c
deleted file mode 100644
index bad9da52..00000000
--- a/ANDROID_3.4.5/sound/isa/opti9xx/opti93x.c
+++ /dev/null
@@ -1,3 +0,0 @@
-#define OPTi93X
-#include "opti92x-ad1848.c"
-
diff --git a/ANDROID_3.4.5/sound/isa/sb/Makefile b/ANDROID_3.4.5/sound/isa/sb/Makefile
deleted file mode 100644
index 08b9fb97..00000000
--- a/ANDROID_3.4.5/sound/isa/sb/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-sb-common-objs := sb_common.o sb_mixer.o
-snd-sb8-dsp-objs := sb8_main.o sb8_midi.o
-snd-sb16-dsp-objs := sb16_main.o
-snd-sb16-csp-objs := sb16_csp.o
-snd-sb8-objs := sb8.o
-snd-sb16-objs := sb16.o
-snd-sbawe-objs := sbawe.o emu8000.o
-snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o
-snd-jazz16-objs := jazz16.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_SB_COMMON) += snd-sb-common.o
-obj-$(CONFIG_SND_SB16_DSP) += snd-sb16-dsp.o
-obj-$(CONFIG_SND_SB8_DSP) += snd-sb8-dsp.o
-obj-$(CONFIG_SND_SB8) += snd-sb8.o
-obj-$(CONFIG_SND_SB16) += snd-sb16.o
-obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o
-obj-$(CONFIG_SND_JAZZ16) += snd-jazz16.o
-ifeq ($(CONFIG_SND_SB16_CSP),y)
- obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o
- obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o
-endif
-obj-$(CONFIG_SND_SBAWE_SEQ) += snd-emu8000-synth.o
diff --git a/ANDROID_3.4.5/sound/isa/sb/emu8000.c b/ANDROID_3.4.5/sound/isa/sb/emu8000.c
deleted file mode 100644
index 71887874..00000000
--- a/ANDROID_3.4.5/sound/isa/sb/emu8000.c
+++ /dev/null
@@ -1,1163 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * and (c) 1999 Steve Ratcliffe <steve@parabola.demon.co.uk>
- * Copyright (C) 1999-2000 Takashi Iwai <tiwai@suse.de>
- *
- * Routines for control of EMU8000 chip
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/wait.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/export.h>
-#include <linux/delay.h>
-#include <sound/core.h>
-#include <sound/emu8000.h>
-#include <sound/emu8000_reg.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <linux/init.h>
-#include <sound/control.h>
-#include <sound/initval.h>
-
-/*
- * emu8000 register controls
- */
-
-/*
- * The following routines read and write registers on the emu8000. They
- * should always be called via the EMU8000*READ/WRITE macros and never
- * directly. The macros handle the port number and command word.
- */
-/* Write a word */
-void snd_emu8000_poke(struct snd_emu8000 *emu, unsigned int port, unsigned int reg, unsigned int val)
-{
- unsigned long flags;
- spin_lock_irqsave(&emu->reg_lock, flags);
- if (reg != emu->last_reg) {
- outw((unsigned short)reg, EMU8000_PTR(emu)); /* Set register */
- emu->last_reg = reg;
- }
- outw((unsigned short)val, port); /* Send data */
- spin_unlock_irqrestore(&emu->reg_lock, flags);
-}
-
-/* Read a word */
-unsigned short snd_emu8000_peek(struct snd_emu8000 *emu, unsigned int port, unsigned int reg)
-{
- unsigned short res;
- unsigned long flags;
- spin_lock_irqsave(&emu->reg_lock, flags);
- if (reg != emu->last_reg) {
- outw((unsigned short)reg, EMU8000_PTR(emu)); /* Set register */
- emu->last_reg = reg;
- }
- res = inw(port); /* Read data */
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return res;
-}
-
-/* Write a double word */
-void snd_emu8000_poke_dw(struct snd_emu8000 *emu, unsigned int port, unsigned int reg, unsigned int val)
-{
- unsigned long flags;
- spin_lock_irqsave(&emu->reg_lock, flags);
- if (reg != emu->last_reg) {
- outw((unsigned short)reg, EMU8000_PTR(emu)); /* Set register */
- emu->last_reg = reg;
- }
- outw((unsigned short)val, port); /* Send low word of data */
- outw((unsigned short)(val>>16), port+2); /* Send high word of data */
- spin_unlock_irqrestore(&emu->reg_lock, flags);
-}
-
-/* Read a double word */
-unsigned int snd_emu8000_peek_dw(struct snd_emu8000 *emu, unsigned int port, unsigned int reg)
-{
- unsigned short low;
- unsigned int res;
- unsigned long flags;
- spin_lock_irqsave(&emu->reg_lock, flags);
- if (reg != emu->last_reg) {
- outw((unsigned short)reg, EMU8000_PTR(emu)); /* Set register */
- emu->last_reg = reg;
- }
- low = inw(port); /* Read low word of data */
- res = low + (inw(port+2) << 16);
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return res;
-}
-
-/*
- * Set up / close a channel to be used for DMA.
- */
-/*exported*/ void
-snd_emu8000_dma_chan(struct snd_emu8000 *emu, int ch, int mode)
-{
- unsigned right_bit = (mode & EMU8000_RAM_RIGHT) ? 0x01000000 : 0;
- mode &= EMU8000_RAM_MODE_MASK;
- if (mode == EMU8000_RAM_CLOSE) {
- EMU8000_CCCA_WRITE(emu, ch, 0);
- EMU8000_DCYSUSV_WRITE(emu, ch, 0x807F);
- return;
- }
- EMU8000_DCYSUSV_WRITE(emu, ch, 0x80);
- EMU8000_VTFT_WRITE(emu, ch, 0);
- EMU8000_CVCF_WRITE(emu, ch, 0);
- EMU8000_PTRX_WRITE(emu, ch, 0x40000000);
- EMU8000_CPF_WRITE(emu, ch, 0x40000000);
- EMU8000_PSST_WRITE(emu, ch, 0);
- EMU8000_CSL_WRITE(emu, ch, 0);
- if (mode == EMU8000_RAM_WRITE) /* DMA write */
- EMU8000_CCCA_WRITE(emu, ch, 0x06000000 | right_bit);
- else /* DMA read */
- EMU8000_CCCA_WRITE(emu, ch, 0x04000000 | right_bit);
-}
-
-/*
- */
-static void __devinit
-snd_emu8000_read_wait(struct snd_emu8000 *emu)
-{
- while ((EMU8000_SMALR_READ(emu) & 0x80000000) != 0) {
- schedule_timeout_interruptible(1);
- if (signal_pending(current))
- break;
- }
-}
-
-/*
- */
-static void __devinit
-snd_emu8000_write_wait(struct snd_emu8000 *emu)
-{
- while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
- schedule_timeout_interruptible(1);
- if (signal_pending(current))
- break;
- }
-}
-
-/*
- * detect a card at the given port
- */
-static int __devinit
-snd_emu8000_detect(struct snd_emu8000 *emu)
-{
- /* Initialise */
- EMU8000_HWCF1_WRITE(emu, 0x0059);
- EMU8000_HWCF2_WRITE(emu, 0x0020);
- EMU8000_HWCF3_WRITE(emu, 0x0000);
- /* Check for a recognisable emu8000 */
- /*
- if ((EMU8000_U1_READ(emu) & 0x000f) != 0x000c)
- return -ENODEV;
- */
- if ((EMU8000_HWCF1_READ(emu) & 0x007e) != 0x0058)
- return -ENODEV;
- if ((EMU8000_HWCF2_READ(emu) & 0x0003) != 0x0003)
- return -ENODEV;
-
- snd_printdd("EMU8000 [0x%lx]: Synth chip found\n",
- emu->port1);
- return 0;
-}
-
-
-/*
- * intiailize audio channels
- */
-static void __devinit
-init_audio(struct snd_emu8000 *emu)
-{
- int ch;
-
- /* turn off envelope engines */
- for (ch = 0; ch < EMU8000_CHANNELS; ch++)
- EMU8000_DCYSUSV_WRITE(emu, ch, 0x80);
-
- /* reset all other parameters to zero */
- for (ch = 0; ch < EMU8000_CHANNELS; ch++) {
- EMU8000_ENVVOL_WRITE(emu, ch, 0);
- EMU8000_ENVVAL_WRITE(emu, ch, 0);
- EMU8000_DCYSUS_WRITE(emu, ch, 0);
- EMU8000_ATKHLDV_WRITE(emu, ch, 0);
- EMU8000_LFO1VAL_WRITE(emu, ch, 0);
- EMU8000_ATKHLD_WRITE(emu, ch, 0);
- EMU8000_LFO2VAL_WRITE(emu, ch, 0);
- EMU8000_IP_WRITE(emu, ch, 0);
- EMU8000_IFATN_WRITE(emu, ch, 0);
- EMU8000_PEFE_WRITE(emu, ch, 0);
- EMU8000_FMMOD_WRITE(emu, ch, 0);
- EMU8000_TREMFRQ_WRITE(emu, ch, 0);
- EMU8000_FM2FRQ2_WRITE(emu, ch, 0);
- EMU8000_PTRX_WRITE(emu, ch, 0);
- EMU8000_VTFT_WRITE(emu, ch, 0);
- EMU8000_PSST_WRITE(emu, ch, 0);
- EMU8000_CSL_WRITE(emu, ch, 0);
- EMU8000_CCCA_WRITE(emu, ch, 0);
- }
-
- for (ch = 0; ch < EMU8000_CHANNELS; ch++) {
- EMU8000_CPF_WRITE(emu, ch, 0);
- EMU8000_CVCF_WRITE(emu, ch, 0);
- }
-}
-
-
-/*
- * initialize DMA address
- */
-static void __devinit
-init_dma(struct snd_emu8000 *emu)
-{
- EMU8000_SMALR_WRITE(emu, 0);
- EMU8000_SMARR_WRITE(emu, 0);
- EMU8000_SMALW_WRITE(emu, 0);
- EMU8000_SMARW_WRITE(emu, 0);
-}
-
-/*
- * initialization arrays; from ADIP
- */
-static unsigned short init1[128] /*__devinitdata*/ = {
- 0x03ff, 0x0030, 0x07ff, 0x0130, 0x0bff, 0x0230, 0x0fff, 0x0330,
- 0x13ff, 0x0430, 0x17ff, 0x0530, 0x1bff, 0x0630, 0x1fff, 0x0730,
- 0x23ff, 0x0830, 0x27ff, 0x0930, 0x2bff, 0x0a30, 0x2fff, 0x0b30,
- 0x33ff, 0x0c30, 0x37ff, 0x0d30, 0x3bff, 0x0e30, 0x3fff, 0x0f30,
-
- 0x43ff, 0x0030, 0x47ff, 0x0130, 0x4bff, 0x0230, 0x4fff, 0x0330,
- 0x53ff, 0x0430, 0x57ff, 0x0530, 0x5bff, 0x0630, 0x5fff, 0x0730,
- 0x63ff, 0x0830, 0x67ff, 0x0930, 0x6bff, 0x0a30, 0x6fff, 0x0b30,
- 0x73ff, 0x0c30, 0x77ff, 0x0d30, 0x7bff, 0x0e30, 0x7fff, 0x0f30,
-
- 0x83ff, 0x0030, 0x87ff, 0x0130, 0x8bff, 0x0230, 0x8fff, 0x0330,
- 0x93ff, 0x0430, 0x97ff, 0x0530, 0x9bff, 0x0630, 0x9fff, 0x0730,
- 0xa3ff, 0x0830, 0xa7ff, 0x0930, 0xabff, 0x0a30, 0xafff, 0x0b30,
- 0xb3ff, 0x0c30, 0xb7ff, 0x0d30, 0xbbff, 0x0e30, 0xbfff, 0x0f30,
-
- 0xc3ff, 0x0030, 0xc7ff, 0x0130, 0xcbff, 0x0230, 0xcfff, 0x0330,
- 0xd3ff, 0x0430, 0xd7ff, 0x0530, 0xdbff, 0x0630, 0xdfff, 0x0730,
- 0xe3ff, 0x0830, 0xe7ff, 0x0930, 0xebff, 0x0a30, 0xefff, 0x0b30,
- 0xf3ff, 0x0c30, 0xf7ff, 0x0d30, 0xfbff, 0x0e30, 0xffff, 0x0f30,
-};
-
-static unsigned short init2[128] /*__devinitdata*/ = {
- 0x03ff, 0x8030, 0x07ff, 0x8130, 0x0bff, 0x8230, 0x0fff, 0x8330,
- 0x13ff, 0x8430, 0x17ff, 0x8530, 0x1bff, 0x8630, 0x1fff, 0x8730,
- 0x23ff, 0x8830, 0x27ff, 0x8930, 0x2bff, 0x8a30, 0x2fff, 0x8b30,
- 0x33ff, 0x8c30, 0x37ff, 0x8d30, 0x3bff, 0x8e30, 0x3fff, 0x8f30,
-
- 0x43ff, 0x8030, 0x47ff, 0x8130, 0x4bff, 0x8230, 0x4fff, 0x8330,
- 0x53ff, 0x8430, 0x57ff, 0x8530, 0x5bff, 0x8630, 0x5fff, 0x8730,
- 0x63ff, 0x8830, 0x67ff, 0x8930, 0x6bff, 0x8a30, 0x6fff, 0x8b30,
- 0x73ff, 0x8c30, 0x77ff, 0x8d30, 0x7bff, 0x8e30, 0x7fff, 0x8f30,
-
- 0x83ff, 0x8030, 0x87ff, 0x8130, 0x8bff, 0x8230, 0x8fff, 0x8330,
- 0x93ff, 0x8430, 0x97ff, 0x8530, 0x9bff, 0x8630, 0x9fff, 0x8730,
- 0xa3ff, 0x8830, 0xa7ff, 0x8930, 0xabff, 0x8a30, 0xafff, 0x8b30,
- 0xb3ff, 0x8c30, 0xb7ff, 0x8d30, 0xbbff, 0x8e30, 0xbfff, 0x8f30,
-
- 0xc3ff, 0x8030, 0xc7ff, 0x8130, 0xcbff, 0x8230, 0xcfff, 0x8330,
- 0xd3ff, 0x8430, 0xd7ff, 0x8530, 0xdbff, 0x8630, 0xdfff, 0x8730,
- 0xe3ff, 0x8830, 0xe7ff, 0x8930, 0xebff, 0x8a30, 0xefff, 0x8b30,
- 0xf3ff, 0x8c30, 0xf7ff, 0x8d30, 0xfbff, 0x8e30, 0xffff, 0x8f30,
-};
-
-static unsigned short init3[128] /*__devinitdata*/ = {
- 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
- 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x8F7C, 0x167E, 0xF254,
- 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x8BAA, 0x1B6D, 0xF234,
- 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x86E7, 0x229E, 0xF224,
-
- 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x87F6, 0x2C28, 0xF254,
- 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x8F02, 0x1341, 0xF264,
- 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x8FA9, 0x3EB5, 0xF294,
- 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0xC4C3, 0x3EBB, 0xC5C3,
-
- 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x8671, 0x14FD, 0x8287,
- 0x3EBC, 0xE610, 0x3EC8, 0x8C7B, 0x031A, 0x87E6, 0x3EC8, 0x86F7,
- 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x821F, 0x3ECA, 0x8386,
- 0x3EC1, 0x8C03, 0x3EC9, 0x831E, 0x3ECA, 0x8C4C, 0x3EBF, 0x8C55,
-
- 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x8EAD, 0x3EC8, 0xD308,
- 0x3EC2, 0x8F7E, 0x3ECB, 0x8219, 0x3ECB, 0xD26E, 0x3EC5, 0x831F,
- 0x3EC6, 0xC308, 0x3EC3, 0xB2FF, 0x3EC9, 0x8265, 0x3EC9, 0x8319,
- 0x1342, 0xD36E, 0x3EC7, 0xB3FF, 0x0000, 0x8365, 0x1420, 0x9570,
-};
-
-static unsigned short init4[128] /*__devinitdata*/ = {
- 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
- 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x0F7C, 0x167E, 0x7254,
- 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x0BAA, 0x1B6D, 0x7234,
- 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x06E7, 0x229E, 0x7224,
-
- 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x07F6, 0x2C28, 0x7254,
- 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x0F02, 0x1341, 0x7264,
- 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x0FA9, 0x3EB5, 0x7294,
- 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0x44C3, 0x3EBB, 0x45C3,
-
- 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x0671, 0x14FD, 0x0287,
- 0x3EBC, 0xE610, 0x3EC8, 0x0C7B, 0x031A, 0x07E6, 0x3EC8, 0x86F7,
- 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x021F, 0x3ECA, 0x0386,
- 0x3EC1, 0x0C03, 0x3EC9, 0x031E, 0x3ECA, 0x8C4C, 0x3EBF, 0x0C55,
-
- 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x0EAD, 0x3EC8, 0xD308,
- 0x3EC2, 0x8F7E, 0x3ECB, 0x0219, 0x3ECB, 0xD26E, 0x3EC5, 0x031F,
- 0x3EC6, 0xC308, 0x3EC3, 0x32FF, 0x3EC9, 0x0265, 0x3EC9, 0x8319,
- 0x1342, 0xD36E, 0x3EC7, 0x33FF, 0x0000, 0x8365, 0x1420, 0x9570,
-};
-
-/* send an initialization array
- * Taken from the oss driver, not obvious from the doc how this
- * is meant to work
- */
-static void __devinit
-send_array(struct snd_emu8000 *emu, unsigned short *data, int size)
-{
- int i;
- unsigned short *p;
-
- p = data;
- for (i = 0; i < size; i++, p++)
- EMU8000_INIT1_WRITE(emu, i, *p);
- for (i = 0; i < size; i++, p++)
- EMU8000_INIT2_WRITE(emu, i, *p);
- for (i = 0; i < size; i++, p++)
- EMU8000_INIT3_WRITE(emu, i, *p);
- for (i = 0; i < size; i++, p++)
- EMU8000_INIT4_WRITE(emu, i, *p);
-}
-
-
-/*
- * Send initialization arrays to start up, this just follows the
- * initialisation sequence in the adip.
- */
-static void __devinit
-init_arrays(struct snd_emu8000 *emu)
-{
- send_array(emu, init1, ARRAY_SIZE(init1)/4);
-
- msleep((1024 * 1000) / 44100); /* wait for 1024 clocks */
- send_array(emu, init2, ARRAY_SIZE(init2)/4);
- send_array(emu, init3, ARRAY_SIZE(init3)/4);
-
- EMU8000_HWCF4_WRITE(emu, 0);
- EMU8000_HWCF5_WRITE(emu, 0x83);
- EMU8000_HWCF6_WRITE(emu, 0x8000);
-
- send_array(emu, init4, ARRAY_SIZE(init4)/4);
-}
-
-
-#define UNIQUE_ID1 0xa5b9
-#define UNIQUE_ID2 0x9d53
-
-/*
- * Size the onboard memory.
- * This is written so as not to need arbitrary delays after the write. It
- * seems that the only way to do this is to use the one channel and keep
- * reallocating between read and write.
- */
-static void __devinit
-size_dram(struct snd_emu8000 *emu)
-{
- int i, size, detected_size;
-
- if (emu->dram_checked)
- return;
-
- size = 0;
- detected_size = 0;
-
- /* write out a magic number */
- snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE);
- snd_emu8000_dma_chan(emu, 1, EMU8000_RAM_READ);
- EMU8000_SMALW_WRITE(emu, EMU8000_DRAM_OFFSET);
- EMU8000_SMLD_WRITE(emu, UNIQUE_ID1);
- snd_emu8000_init_fm(emu); /* This must really be here and not 2 lines back even */
-
- while (size < EMU8000_MAX_DRAM) {
-
- size += 512 * 1024; /* increment 512kbytes */
-
- /* Write a unique data on the test address.
- * if the address is out of range, the data is written on
- * 0x200000(=EMU8000_DRAM_OFFSET). Then the id word is
- * changed by this data.
- */
- /*snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE);*/
- EMU8000_SMALW_WRITE(emu, EMU8000_DRAM_OFFSET + (size>>1));
- EMU8000_SMLD_WRITE(emu, UNIQUE_ID2);
- snd_emu8000_write_wait(emu);
-
- /*
- * read the data on the just written DRAM address
- * if not the same then we have reached the end of ram.
- */
- /*snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_READ);*/
- EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET + (size>>1));
- /*snd_emu8000_read_wait(emu);*/
- EMU8000_SMLD_READ(emu); /* discard stale data */
- if (EMU8000_SMLD_READ(emu) != UNIQUE_ID2)
- break; /* no memory at this address */
-
- detected_size = size;
-
- snd_emu8000_read_wait(emu);
-
- /*
- * If it is the same it could be that the address just
- * wraps back to the beginning; so check to see if the
- * initial value has been overwritten.
- */
- EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET);
- EMU8000_SMLD_READ(emu); /* discard stale data */
- if (EMU8000_SMLD_READ(emu) != UNIQUE_ID1)
- break; /* we must have wrapped around */
- snd_emu8000_read_wait(emu);
- }
-
- /* wait until FULL bit in SMAxW register is false */
- for (i = 0; i < 10000; i++) {
- if ((EMU8000_SMALW_READ(emu) & 0x80000000) == 0)
- break;
- schedule_timeout_interruptible(1);
- if (signal_pending(current))
- break;
- }
- snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_CLOSE);
- snd_emu8000_dma_chan(emu, 1, EMU8000_RAM_CLOSE);
-
- snd_printdd("EMU8000 [0x%lx]: %d Kb on-board memory detected\n",
- emu->port1, detected_size/1024);
-
- emu->mem_size = detected_size;
- emu->dram_checked = 1;
-}
-
-
-/*
- * Initiailise the FM section. You have to do this to use sample RAM
- * and therefore lose 2 voices.
- */
-/*exported*/ void
-snd_emu8000_init_fm(struct snd_emu8000 *emu)
-{
- unsigned long flags;
-
- /* Initialize the last two channels for DRAM refresh and producing
- the reverb and chorus effects for Yamaha OPL-3 synthesizer */
-
- /* 31: FM left channel, 0xffffe0-0xffffe8 */
- EMU8000_DCYSUSV_WRITE(emu, 30, 0x80);
- EMU8000_PSST_WRITE(emu, 30, 0xFFFFFFE0); /* full left */
- EMU8000_CSL_WRITE(emu, 30, 0x00FFFFE8 | (emu->fm_chorus_depth << 24));
- EMU8000_PTRX_WRITE(emu, 30, (emu->fm_reverb_depth << 8));
- EMU8000_CPF_WRITE(emu, 30, 0);
- EMU8000_CCCA_WRITE(emu, 30, 0x00FFFFE3);
-
- /* 32: FM right channel, 0xfffff0-0xfffff8 */
- EMU8000_DCYSUSV_WRITE(emu, 31, 0x80);
- EMU8000_PSST_WRITE(emu, 31, 0x00FFFFF0); /* full right */
- EMU8000_CSL_WRITE(emu, 31, 0x00FFFFF8 | (emu->fm_chorus_depth << 24));
- EMU8000_PTRX_WRITE(emu, 31, (emu->fm_reverb_depth << 8));
- EMU8000_CPF_WRITE(emu, 31, 0x8000);
- EMU8000_CCCA_WRITE(emu, 31, 0x00FFFFF3);
-
- snd_emu8000_poke((emu), EMU8000_DATA0(emu), EMU8000_CMD(1, (30)), 0);
-
- spin_lock_irqsave(&emu->reg_lock, flags);
- while (!(inw(EMU8000_PTR(emu)) & 0x1000))
- ;
- while ((inw(EMU8000_PTR(emu)) & 0x1000))
- ;
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- snd_emu8000_poke((emu), EMU8000_DATA0(emu), EMU8000_CMD(1, (30)), 0x4828);
- /* this is really odd part.. */
- outb(0x3C, EMU8000_PTR(emu));
- outb(0, EMU8000_DATA1(emu));
-
- /* skew volume & cutoff */
- EMU8000_VTFT_WRITE(emu, 30, 0x8000FFFF);
- EMU8000_VTFT_WRITE(emu, 31, 0x8000FFFF);
-}
-
-
-/*
- * The main initialization routine.
- */
-static void __devinit
-snd_emu8000_init_hw(struct snd_emu8000 *emu)
-{
- int i;
-
- emu->last_reg = 0xffff; /* reset the last register index */
-
- /* initialize hardware configuration */
- EMU8000_HWCF1_WRITE(emu, 0x0059);
- EMU8000_HWCF2_WRITE(emu, 0x0020);
-
- /* disable audio; this seems to reduce a clicking noise a bit.. */
- EMU8000_HWCF3_WRITE(emu, 0);
-
- /* initialize audio channels */
- init_audio(emu);
-
- /* initialize DMA */
- init_dma(emu);
-
- /* initialize init arrays */
- init_arrays(emu);
-
- /*
- * Initialize the FM section of the AWE32, this is needed
- * for DRAM refresh as well
- */
- snd_emu8000_init_fm(emu);
-
- /* terminate all voices */
- for (i = 0; i < EMU8000_DRAM_VOICES; i++)
- EMU8000_DCYSUSV_WRITE(emu, 0, 0x807F);
-
- /* check DRAM memory size */
- size_dram(emu);
-
- /* enable audio */
- EMU8000_HWCF3_WRITE(emu, 0x4);
-
- /* set equzlier, chorus and reverb modes */
- snd_emu8000_update_equalizer(emu);
- snd_emu8000_update_chorus_mode(emu);
- snd_emu8000_update_reverb_mode(emu);
-}
-
-
-/*----------------------------------------------------------------
- * Bass/Treble Equalizer
- *----------------------------------------------------------------*/
-
-static unsigned short bass_parm[12][3] = {
- {0xD26A, 0xD36A, 0x0000}, /* -12 dB */
- {0xD25B, 0xD35B, 0x0000}, /* -8 */
- {0xD24C, 0xD34C, 0x0000}, /* -6 */
- {0xD23D, 0xD33D, 0x0000}, /* -4 */
- {0xD21F, 0xD31F, 0x0000}, /* -2 */
- {0xC208, 0xC308, 0x0001}, /* 0 (HW default) */
- {0xC219, 0xC319, 0x0001}, /* +2 */
- {0xC22A, 0xC32A, 0x0001}, /* +4 */
- {0xC24C, 0xC34C, 0x0001}, /* +6 */
- {0xC26E, 0xC36E, 0x0001}, /* +8 */
- {0xC248, 0xC384, 0x0002}, /* +10 */
- {0xC26A, 0xC36A, 0x0002}, /* +12 dB */
-};
-
-static unsigned short treble_parm[12][9] = {
- {0x821E, 0xC26A, 0x031E, 0xC36A, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, /* -12 dB */
- {0x821E, 0xC25B, 0x031E, 0xC35B, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
- {0x821E, 0xC24C, 0x031E, 0xC34C, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
- {0x821E, 0xC23D, 0x031E, 0xC33D, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
- {0x821E, 0xC21F, 0x031E, 0xC31F, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
- {0x821E, 0xD208, 0x031E, 0xD308, 0x021E, 0xD208, 0x831E, 0xD308, 0x0002},
- {0x821E, 0xD208, 0x031E, 0xD308, 0x021D, 0xD219, 0x831D, 0xD319, 0x0002},
- {0x821E, 0xD208, 0x031E, 0xD308, 0x021C, 0xD22A, 0x831C, 0xD32A, 0x0002},
- {0x821E, 0xD208, 0x031E, 0xD308, 0x021A, 0xD24C, 0x831A, 0xD34C, 0x0002},
- {0x821E, 0xD208, 0x031E, 0xD308, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +8 (HW default) */
- {0x821D, 0xD219, 0x031D, 0xD319, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002},
- {0x821C, 0xD22A, 0x031C, 0xD32A, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002} /* +12 dB */
-};
-
-
-/*
- * set Emu8000 digital equalizer; from 0 to 11 [-12dB - 12dB]
- */
-/*exported*/ void
-snd_emu8000_update_equalizer(struct snd_emu8000 *emu)
-{
- unsigned short w;
- int bass = emu->bass_level;
- int treble = emu->treble_level;
-
- if (bass < 0 || bass > 11 || treble < 0 || treble > 11)
- return;
- EMU8000_INIT4_WRITE(emu, 0x01, bass_parm[bass][0]);
- EMU8000_INIT4_WRITE(emu, 0x11, bass_parm[bass][1]);
- EMU8000_INIT3_WRITE(emu, 0x11, treble_parm[treble][0]);
- EMU8000_INIT3_WRITE(emu, 0x13, treble_parm[treble][1]);
- EMU8000_INIT3_WRITE(emu, 0x1b, treble_parm[treble][2]);
- EMU8000_INIT4_WRITE(emu, 0x07, treble_parm[treble][3]);
- EMU8000_INIT4_WRITE(emu, 0x0b, treble_parm[treble][4]);
- EMU8000_INIT4_WRITE(emu, 0x0d, treble_parm[treble][5]);
- EMU8000_INIT4_WRITE(emu, 0x17, treble_parm[treble][6]);
- EMU8000_INIT4_WRITE(emu, 0x19, treble_parm[treble][7]);
- w = bass_parm[bass][2] + treble_parm[treble][8];
- EMU8000_INIT4_WRITE(emu, 0x15, (unsigned short)(w + 0x0262));
- EMU8000_INIT4_WRITE(emu, 0x1d, (unsigned short)(w + 0x8362));
-}
-
-
-/*----------------------------------------------------------------
- * Chorus mode control
- *----------------------------------------------------------------*/
-
-/*
- * chorus mode parameters
- */
-#define SNDRV_EMU8000_CHORUS_1 0
-#define SNDRV_EMU8000_CHORUS_2 1
-#define SNDRV_EMU8000_CHORUS_3 2
-#define SNDRV_EMU8000_CHORUS_4 3
-#define SNDRV_EMU8000_CHORUS_FEEDBACK 4
-#define SNDRV_EMU8000_CHORUS_FLANGER 5
-#define SNDRV_EMU8000_CHORUS_SHORTDELAY 6
-#define SNDRV_EMU8000_CHORUS_SHORTDELAY2 7
-#define SNDRV_EMU8000_CHORUS_PREDEFINED 8
-/* user can define chorus modes up to 32 */
-#define SNDRV_EMU8000_CHORUS_NUMBERS 32
-
-struct soundfont_chorus_fx {
- unsigned short feedback; /* feedback level (0xE600-0xE6FF) */
- unsigned short delay_offset; /* delay (0-0x0DA3) [1/44100 sec] */
- unsigned short lfo_depth; /* LFO depth (0xBC00-0xBCFF) */
- unsigned int delay; /* right delay (0-0xFFFFFFFF) [1/256/44100 sec] */
- unsigned int lfo_freq; /* LFO freq LFO freq (0-0xFFFFFFFF) */
-};
-
-/* 5 parameters for each chorus mode; 3 x 16bit, 2 x 32bit */
-static char chorus_defined[SNDRV_EMU8000_CHORUS_NUMBERS];
-static struct soundfont_chorus_fx chorus_parm[SNDRV_EMU8000_CHORUS_NUMBERS] = {
- {0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */
- {0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */
- {0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */
- {0xE620, 0x0269, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 4 */
- {0xE680, 0x04D3, 0xBCA6, 0x00000000, 0x0000005B}, /* feedback */
- {0xE6E0, 0x044E, 0xBC37, 0x00000000, 0x00000026}, /* flanger */
- {0xE600, 0x0B06, 0xBC00, 0x0006E000, 0x00000083}, /* short delay */
- {0xE6C0, 0x0B06, 0xBC00, 0x0006E000, 0x00000083}, /* short delay + feedback */
-};
-
-/*exported*/ int
-snd_emu8000_load_chorus_fx(struct snd_emu8000 *emu, int mode, const void __user *buf, long len)
-{
- struct soundfont_chorus_fx rec;
- if (mode < SNDRV_EMU8000_CHORUS_PREDEFINED || mode >= SNDRV_EMU8000_CHORUS_NUMBERS) {
- snd_printk(KERN_WARNING "invalid chorus mode %d for uploading\n", mode);
- return -EINVAL;
- }
- if (len < (long)sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec)))
- return -EFAULT;
- chorus_parm[mode] = rec;
- chorus_defined[mode] = 1;
- return 0;
-}
-
-/*exported*/ void
-snd_emu8000_update_chorus_mode(struct snd_emu8000 *emu)
-{
- int effect = emu->chorus_mode;
- if (effect < 0 || effect >= SNDRV_EMU8000_CHORUS_NUMBERS ||
- (effect >= SNDRV_EMU8000_CHORUS_PREDEFINED && !chorus_defined[effect]))
- return;
- EMU8000_INIT3_WRITE(emu, 0x09, chorus_parm[effect].feedback);
- EMU8000_INIT3_WRITE(emu, 0x0c, chorus_parm[effect].delay_offset);
- EMU8000_INIT4_WRITE(emu, 0x03, chorus_parm[effect].lfo_depth);
- EMU8000_HWCF4_WRITE(emu, chorus_parm[effect].delay);
- EMU8000_HWCF5_WRITE(emu, chorus_parm[effect].lfo_freq);
- EMU8000_HWCF6_WRITE(emu, 0x8000);
- EMU8000_HWCF7_WRITE(emu, 0x0000);
-}
-
-/*----------------------------------------------------------------
- * Reverb mode control
- *----------------------------------------------------------------*/
-
-/*
- * reverb mode parameters
- */
-#define SNDRV_EMU8000_REVERB_ROOM1 0
-#define SNDRV_EMU8000_REVERB_ROOM2 1
-#define SNDRV_EMU8000_REVERB_ROOM3 2
-#define SNDRV_EMU8000_REVERB_HALL1 3
-#define SNDRV_EMU8000_REVERB_HALL2 4
-#define SNDRV_EMU8000_REVERB_PLATE 5
-#define SNDRV_EMU8000_REVERB_DELAY 6
-#define SNDRV_EMU8000_REVERB_PANNINGDELAY 7
-#define SNDRV_EMU8000_REVERB_PREDEFINED 8
-/* user can define reverb modes up to 32 */
-#define SNDRV_EMU8000_REVERB_NUMBERS 32
-
-struct soundfont_reverb_fx {
- unsigned short parms[28];
-};
-
-/* reverb mode settings; write the following 28 data of 16 bit length
- * on the corresponding ports in the reverb_cmds array
- */
-static char reverb_defined[SNDRV_EMU8000_CHORUS_NUMBERS];
-static struct soundfont_reverb_fx reverb_parm[SNDRV_EMU8000_REVERB_NUMBERS] = {
-{{ /* room 1 */
- 0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4,
- 0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516,
- 0xA490, 0xA590, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
- 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
-}},
-{{ /* room 2 */
- 0xB488, 0xA458, 0x9558, 0x84B5, 0x383A, 0x3EB5, 0x7284,
- 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
- 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
- 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
-}},
-{{ /* room 3 */
- 0xB488, 0xA460, 0x9560, 0x84B5, 0x383A, 0x3EB5, 0x7284,
- 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4416, 0x4516,
- 0xA490, 0xA590, 0x842C, 0x852C, 0x842C, 0x852C, 0x842B,
- 0x852B, 0x842B, 0x852B, 0x842A, 0x852A, 0x842A, 0x852A,
-}},
-{{ /* hall 1 */
- 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7284,
- 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
- 0xA440, 0xA540, 0x842B, 0x852B, 0x842B, 0x852B, 0x842A,
- 0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529,
-}},
-{{ /* hall 2 */
- 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7254,
- 0x7234, 0x7224, 0x7254, 0x7264, 0x7294, 0x44C3, 0x45C3,
- 0xA404, 0xA504, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
- 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
-}},
-{{ /* plate */
- 0xB4FF, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7234,
- 0x7234, 0x7234, 0x7234, 0x7234, 0x7234, 0x4448, 0x4548,
- 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
- 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
-}},
-{{ /* delay */
- 0xB4FF, 0xA470, 0x9500, 0x84B5, 0x333A, 0x39B5, 0x7204,
- 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
- 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
- 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
-}},
-{{ /* panning delay */
- 0xB4FF, 0xA490, 0x9590, 0x8474, 0x333A, 0x39B5, 0x7204,
- 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
- 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
- 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
-}},
-};
-
-enum { DATA1, DATA2 };
-#define AWE_INIT1(c) EMU8000_CMD(2,c), DATA1
-#define AWE_INIT2(c) EMU8000_CMD(2,c), DATA2
-#define AWE_INIT3(c) EMU8000_CMD(3,c), DATA1
-#define AWE_INIT4(c) EMU8000_CMD(3,c), DATA2
-
-static struct reverb_cmd_pair {
- unsigned short cmd, port;
-} reverb_cmds[28] = {
- {AWE_INIT1(0x03)}, {AWE_INIT1(0x05)}, {AWE_INIT4(0x1F)}, {AWE_INIT1(0x07)},
- {AWE_INIT2(0x14)}, {AWE_INIT2(0x16)}, {AWE_INIT1(0x0F)}, {AWE_INIT1(0x17)},
- {AWE_INIT1(0x1F)}, {AWE_INIT2(0x07)}, {AWE_INIT2(0x0F)}, {AWE_INIT2(0x17)},
- {AWE_INIT2(0x1D)}, {AWE_INIT2(0x1F)}, {AWE_INIT3(0x01)}, {AWE_INIT3(0x03)},
- {AWE_INIT1(0x09)}, {AWE_INIT1(0x0B)}, {AWE_INIT1(0x11)}, {AWE_INIT1(0x13)},
- {AWE_INIT1(0x19)}, {AWE_INIT1(0x1B)}, {AWE_INIT2(0x01)}, {AWE_INIT2(0x03)},
- {AWE_INIT2(0x09)}, {AWE_INIT2(0x0B)}, {AWE_INIT2(0x11)}, {AWE_INIT2(0x13)},
-};
-
-/*exported*/ int
-snd_emu8000_load_reverb_fx(struct snd_emu8000 *emu, int mode, const void __user *buf, long len)
-{
- struct soundfont_reverb_fx rec;
-
- if (mode < SNDRV_EMU8000_REVERB_PREDEFINED || mode >= SNDRV_EMU8000_REVERB_NUMBERS) {
- snd_printk(KERN_WARNING "invalid reverb mode %d for uploading\n", mode);
- return -EINVAL;
- }
- if (len < (long)sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec)))
- return -EFAULT;
- reverb_parm[mode] = rec;
- reverb_defined[mode] = 1;
- return 0;
-}
-
-/*exported*/ void
-snd_emu8000_update_reverb_mode(struct snd_emu8000 *emu)
-{
- int effect = emu->reverb_mode;
- int i;
-
- if (effect < 0 || effect >= SNDRV_EMU8000_REVERB_NUMBERS ||
- (effect >= SNDRV_EMU8000_REVERB_PREDEFINED && !reverb_defined[effect]))
- return;
- for (i = 0; i < 28; i++) {
- int port;
- if (reverb_cmds[i].port == DATA1)
- port = EMU8000_DATA1(emu);
- else
- port = EMU8000_DATA2(emu);
- snd_emu8000_poke(emu, port, reverb_cmds[i].cmd, reverb_parm[effect].parms[i]);
- }
-}
-
-
-/*----------------------------------------------------------------
- * mixer interface
- *----------------------------------------------------------------*/
-
-/*
- * bass/treble
- */
-static int mixer_bass_treble_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 11;
- return 0;
-}
-
-static int mixer_bass_treble_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->treble_level : emu->bass_level;
- return 0;
-}
-
-static int mixer_bass_treble_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int change;
- unsigned short val1;
-
- val1 = ucontrol->value.integer.value[0] % 12;
- spin_lock_irqsave(&emu->control_lock, flags);
- if (kcontrol->private_value) {
- change = val1 != emu->treble_level;
- emu->treble_level = val1;
- } else {
- change = val1 != emu->bass_level;
- emu->bass_level = val1;
- }
- spin_unlock_irqrestore(&emu->control_lock, flags);
- snd_emu8000_update_equalizer(emu);
- return change;
-}
-
-static struct snd_kcontrol_new mixer_bass_control =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Synth Tone Control - Bass",
- .info = mixer_bass_treble_info,
- .get = mixer_bass_treble_get,
- .put = mixer_bass_treble_put,
- .private_value = 0,
-};
-
-static struct snd_kcontrol_new mixer_treble_control =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Synth Tone Control - Treble",
- .info = mixer_bass_treble_info,
- .get = mixer_bass_treble_get,
- .put = mixer_bass_treble_put,
- .private_value = 1,
-};
-
-/*
- * chorus/reverb mode
- */
-static int mixer_chorus_reverb_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = kcontrol->private_value ? (SNDRV_EMU8000_CHORUS_NUMBERS-1) : (SNDRV_EMU8000_REVERB_NUMBERS-1);
- return 0;
-}
-
-static int mixer_chorus_reverb_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->chorus_mode : emu->reverb_mode;
- return 0;
-}
-
-static int mixer_chorus_reverb_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int change;
- unsigned short val1;
-
- spin_lock_irqsave(&emu->control_lock, flags);
- if (kcontrol->private_value) {
- val1 = ucontrol->value.integer.value[0] % SNDRV_EMU8000_CHORUS_NUMBERS;
- change = val1 != emu->chorus_mode;
- emu->chorus_mode = val1;
- } else {
- val1 = ucontrol->value.integer.value[0] % SNDRV_EMU8000_REVERB_NUMBERS;
- change = val1 != emu->reverb_mode;
- emu->reverb_mode = val1;
- }
- spin_unlock_irqrestore(&emu->control_lock, flags);
- if (change) {
- if (kcontrol->private_value)
- snd_emu8000_update_chorus_mode(emu);
- else
- snd_emu8000_update_reverb_mode(emu);
- }
- return change;
-}
-
-static struct snd_kcontrol_new mixer_chorus_mode_control =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Chorus Mode",
- .info = mixer_chorus_reverb_info,
- .get = mixer_chorus_reverb_get,
- .put = mixer_chorus_reverb_put,
- .private_value = 1,
-};
-
-static struct snd_kcontrol_new mixer_reverb_mode_control =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Reverb Mode",
- .info = mixer_chorus_reverb_info,
- .get = mixer_chorus_reverb_get,
- .put = mixer_chorus_reverb_put,
- .private_value = 0,
-};
-
-/*
- * FM OPL3 chorus/reverb depth
- */
-static int mixer_fm_depth_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 255;
- return 0;
-}
-
-static int mixer_fm_depth_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->fm_chorus_depth : emu->fm_reverb_depth;
- return 0;
-}
-
-static int mixer_fm_depth_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int change;
- unsigned short val1;
-
- val1 = ucontrol->value.integer.value[0] % 256;
- spin_lock_irqsave(&emu->control_lock, flags);
- if (kcontrol->private_value) {
- change = val1 != emu->fm_chorus_depth;
- emu->fm_chorus_depth = val1;
- } else {
- change = val1 != emu->fm_reverb_depth;
- emu->fm_reverb_depth = val1;
- }
- spin_unlock_irqrestore(&emu->control_lock, flags);
- if (change)
- snd_emu8000_init_fm(emu);
- return change;
-}
-
-static struct snd_kcontrol_new mixer_fm_chorus_depth_control =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "FM Chorus Depth",
- .info = mixer_fm_depth_info,
- .get = mixer_fm_depth_get,
- .put = mixer_fm_depth_put,
- .private_value = 1,
-};
-
-static struct snd_kcontrol_new mixer_fm_reverb_depth_control =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "FM Reverb Depth",
- .info = mixer_fm_depth_info,
- .get = mixer_fm_depth_get,
- .put = mixer_fm_depth_put,
- .private_value = 0,
-};
-
-
-static struct snd_kcontrol_new *mixer_defs[EMU8000_NUM_CONTROLS] = {
- &mixer_bass_control,
- &mixer_treble_control,
- &mixer_chorus_mode_control,
- &mixer_reverb_mode_control,
- &mixer_fm_chorus_depth_control,
- &mixer_fm_reverb_depth_control,
-};
-
-/*
- * create and attach mixer elements for WaveTable treble/bass controls
- */
-static int __devinit
-snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu)
-{
- int i, err = 0;
-
- if (snd_BUG_ON(!emu || !card))
- return -EINVAL;
-
- spin_lock_init(&emu->control_lock);
-
- memset(emu->controls, 0, sizeof(emu->controls));
- for (i = 0; i < EMU8000_NUM_CONTROLS; i++) {
- if ((err = snd_ctl_add(card, emu->controls[i] = snd_ctl_new1(mixer_defs[i], emu))) < 0)
- goto __error;
- }
- return 0;
-
-__error:
- for (i = 0; i < EMU8000_NUM_CONTROLS; i++) {
- down_write(&card->controls_rwsem);
- if (emu->controls[i])
- snd_ctl_remove(card, emu->controls[i]);
- up_write(&card->controls_rwsem);
- }
- return err;
-}
-
-
-/*
- * free resources
- */
-static int snd_emu8000_free(struct snd_emu8000 *hw)
-{
- release_and_free_resource(hw->res_port1);
- release_and_free_resource(hw->res_port2);
- release_and_free_resource(hw->res_port3);
- kfree(hw);
- return 0;
-}
-
-/*
- */
-static int snd_emu8000_dev_free(struct snd_device *device)
-{
- struct snd_emu8000 *hw = device->device_data;
- return snd_emu8000_free(hw);
-}
-
-/*
- * initialize and register emu8000 synth device.
- */
-int __devinit
-snd_emu8000_new(struct snd_card *card, int index, long port, int seq_ports,
- struct snd_seq_device **awe_ret)
-{
- struct snd_seq_device *awe;
- struct snd_emu8000 *hw;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_emu8000_dev_free,
- };
-
- if (awe_ret)
- *awe_ret = NULL;
-
- if (seq_ports <= 0)
- return 0;
-
- hw = kzalloc(sizeof(*hw), GFP_KERNEL);
- if (hw == NULL)
- return -ENOMEM;
- spin_lock_init(&hw->reg_lock);
- hw->index = index;
- hw->port1 = port;
- hw->port2 = port + 0x400;
- hw->port3 = port + 0x800;
- if (!(hw->res_port1 = request_region(hw->port1, 4, "Emu8000-1")) ||
- !(hw->res_port2 = request_region(hw->port2, 4, "Emu8000-2")) ||
- !(hw->res_port3 = request_region(hw->port3, 4, "Emu8000-3"))) {
- snd_printk(KERN_ERR "sbawe: can't grab ports 0x%lx, 0x%lx, 0x%lx\n", hw->port1, hw->port2, hw->port3);
- snd_emu8000_free(hw);
- return -EBUSY;
- }
- hw->mem_size = 0;
- hw->card = card;
- hw->seq_ports = seq_ports;
- hw->bass_level = 5;
- hw->treble_level = 9;
- hw->chorus_mode = 2;
- hw->reverb_mode = 4;
- hw->fm_chorus_depth = 0;
- hw->fm_reverb_depth = 0;
-
- if (snd_emu8000_detect(hw) < 0) {
- snd_emu8000_free(hw);
- return -ENODEV;
- }
-
- snd_emu8000_init_hw(hw);
- if ((err = snd_emu8000_create_mixer(card, hw)) < 0) {
- snd_emu8000_free(hw);
- return err;
- }
-
- if ((err = snd_device_new(card, SNDRV_DEV_CODEC, hw, &ops)) < 0) {
- snd_emu8000_free(hw);
- return err;
- }
-#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
- if (snd_seq_device_new(card, index, SNDRV_SEQ_DEV_ID_EMU8000,
- sizeof(struct snd_emu8000*), &awe) >= 0) {
- strcpy(awe->name, "EMU-8000");
- *(struct snd_emu8000 **)SNDRV_SEQ_DEVICE_ARGPTR(awe) = hw;
- }
-#else
- awe = NULL;
-#endif
- if (awe_ret)
- *awe_ret = awe;
-
- return 0;
-}
-
-
-/*
- * exported stuff
- */
-
-EXPORT_SYMBOL(snd_emu8000_poke);
-EXPORT_SYMBOL(snd_emu8000_peek);
-EXPORT_SYMBOL(snd_emu8000_poke_dw);
-EXPORT_SYMBOL(snd_emu8000_peek_dw);
-EXPORT_SYMBOL(snd_emu8000_dma_chan);
-EXPORT_SYMBOL(snd_emu8000_init_fm);
-EXPORT_SYMBOL(snd_emu8000_load_chorus_fx);
-EXPORT_SYMBOL(snd_emu8000_load_reverb_fx);
-EXPORT_SYMBOL(snd_emu8000_update_chorus_mode);
-EXPORT_SYMBOL(snd_emu8000_update_reverb_mode);
-EXPORT_SYMBOL(snd_emu8000_update_equalizer);
diff --git a/ANDROID_3.4.5/sound/isa/sb/emu8000_callback.c b/ANDROID_3.4.5/sound/isa/sb/emu8000_callback.c
deleted file mode 100644
index 344b4355..00000000
--- a/ANDROID_3.4.5/sound/isa/sb/emu8000_callback.c
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * synth callback routines for the emu8000 (AWE32/64)
- *
- * Copyright (C) 1999 Steve Ratcliffe
- * Copyright (C) 1999-2000 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "emu8000_local.h"
-#include <linux/export.h>
-#include <sound/asoundef.h>
-
-/*
- * prototypes
- */
-static struct snd_emux_voice *get_voice(struct snd_emux *emu,
- struct snd_emux_port *port);
-static int start_voice(struct snd_emux_voice *vp);
-static void trigger_voice(struct snd_emux_voice *vp);
-static void release_voice(struct snd_emux_voice *vp);
-static void update_voice(struct snd_emux_voice *vp, int update);
-static void reset_voice(struct snd_emux *emu, int ch);
-static void terminate_voice(struct snd_emux_voice *vp);
-static void sysex(struct snd_emux *emu, char *buf, int len, int parsed,
- struct snd_midi_channel_set *chset);
-#ifdef CONFIG_SND_SEQUENCER_OSS
-static int oss_ioctl(struct snd_emux *emu, int cmd, int p1, int p2);
-#endif
-static int load_fx(struct snd_emux *emu, int type, int mode,
- const void __user *buf, long len);
-
-static void set_pitch(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
-static void set_volume(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
-static void set_pan(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
-static void set_fmmod(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
-static void set_tremfreq(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
-static void set_fm2frq2(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
-static void set_filterQ(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
-static void snd_emu8000_tweak_voice(struct snd_emu8000 *emu, int ch);
-
-/*
- * Ensure a value is between two points
- * macro evaluates its args more than once, so changed to upper-case.
- */
-#define LIMITVALUE(x, a, b) do { if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b); } while (0)
-#define LIMITMAX(x, a) do {if ((x) > (a)) (x) = (a); } while (0)
-
-
-/*
- * set up operators
- */
-static struct snd_emux_operators emu8000_ops = {
- .owner = THIS_MODULE,
- .get_voice = get_voice,
- .prepare = start_voice,
- .trigger = trigger_voice,
- .release = release_voice,
- .update = update_voice,
- .terminate = terminate_voice,
- .reset = reset_voice,
- .sample_new = snd_emu8000_sample_new,
- .sample_free = snd_emu8000_sample_free,
- .sample_reset = snd_emu8000_sample_reset,
- .load_fx = load_fx,
- .sysex = sysex,
-#ifdef CONFIG_SND_SEQUENCER_OSS
- .oss_ioctl = oss_ioctl,
-#endif
-};
-
-void
-snd_emu8000_ops_setup(struct snd_emu8000 *hw)
-{
- hw->emu->ops = emu8000_ops;
-}
-
-
-
-/*
- * Terminate a voice
- */
-static void
-release_voice(struct snd_emux_voice *vp)
-{
- int dcysusv;
- struct snd_emu8000 *hw;
-
- hw = vp->hw;
- dcysusv = 0x8000 | (unsigned char)vp->reg.parm.modrelease;
- EMU8000_DCYSUS_WRITE(hw, vp->ch, dcysusv);
- dcysusv = 0x8000 | (unsigned char)vp->reg.parm.volrelease;
- EMU8000_DCYSUSV_WRITE(hw, vp->ch, dcysusv);
-}
-
-
-/*
- */
-static void
-terminate_voice(struct snd_emux_voice *vp)
-{
- struct snd_emu8000 *hw;
-
- hw = vp->hw;
- EMU8000_DCYSUSV_WRITE(hw, vp->ch, 0x807F);
-}
-
-
-/*
- */
-static void
-update_voice(struct snd_emux_voice *vp, int update)
-{
- struct snd_emu8000 *hw;
-
- hw = vp->hw;
- if (update & SNDRV_EMUX_UPDATE_VOLUME)
- set_volume(hw, vp);
- if (update & SNDRV_EMUX_UPDATE_PITCH)
- set_pitch(hw, vp);
- if ((update & SNDRV_EMUX_UPDATE_PAN) &&
- vp->port->ctrls[EMUX_MD_REALTIME_PAN])
- set_pan(hw, vp);
- if (update & SNDRV_EMUX_UPDATE_FMMOD)
- set_fmmod(hw, vp);
- if (update & SNDRV_EMUX_UPDATE_TREMFREQ)
- set_tremfreq(hw, vp);
- if (update & SNDRV_EMUX_UPDATE_FM2FRQ2)
- set_fm2frq2(hw, vp);
- if (update & SNDRV_EMUX_UPDATE_Q)
- set_filterQ(hw, vp);
-}
-
-
-/*
- * Find a channel (voice) within the EMU that is not in use or at least
- * less in use than other channels. Always returns a valid pointer
- * no matter what. If there is a real shortage of voices then one
- * will be cut. Such is life.
- *
- * The channel index (vp->ch) must be initialized in this routine.
- * In Emu8k, it is identical with the array index.
- */
-static struct snd_emux_voice *
-get_voice(struct snd_emux *emu, struct snd_emux_port *port)
-{
- int i;
- struct snd_emux_voice *vp;
- struct snd_emu8000 *hw;
-
- /* what we are looking for, in order of preference */
- enum {
- OFF=0, RELEASED, PLAYING, END
- };
-
- /* Keeps track of what we are finding */
- struct best {
- unsigned int time;
- int voice;
- } best[END];
- struct best *bp;
-
- hw = emu->hw;
-
- for (i = 0; i < END; i++) {
- best[i].time = (unsigned int)(-1); /* XXX MAX_?INT really */;
- best[i].voice = -1;
- }
-
- /*
- * Go through them all and get a best one to use.
- */
- for (i = 0; i < emu->max_voices; i++) {
- int state, val;
-
- vp = &emu->voices[i];
- state = vp->state;
-
- if (state == SNDRV_EMUX_ST_OFF)
- bp = best + OFF;
- else if (state == SNDRV_EMUX_ST_RELEASED ||
- state == SNDRV_EMUX_ST_PENDING) {
- bp = best + RELEASED;
- val = (EMU8000_CVCF_READ(hw, vp->ch) >> 16) & 0xffff;
- if (! val)
- bp = best + OFF;
- }
- else if (state & SNDRV_EMUX_ST_ON)
- bp = best + PLAYING;
- else
- continue;
-
- /* check if sample is finished playing (non-looping only) */
- if (state != SNDRV_EMUX_ST_OFF &&
- (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_SINGLESHOT)) {
- val = EMU8000_CCCA_READ(hw, vp->ch) & 0xffffff;
- if (val >= vp->reg.loopstart)
- bp = best + OFF;
- }
-
- if (vp->time < bp->time) {
- bp->time = vp->time;
- bp->voice = i;
- }
- }
-
- for (i = 0; i < END; i++) {
- if (best[i].voice >= 0) {
- vp = &emu->voices[best[i].voice];
- vp->ch = best[i].voice;
- return vp;
- }
- }
-
- /* not found */
- return NULL;
-}
-
-/*
- */
-static int
-start_voice(struct snd_emux_voice *vp)
-{
- unsigned int temp;
- int ch;
- int addr;
- struct snd_midi_channel *chan;
- struct snd_emu8000 *hw;
-
- hw = vp->hw;
- ch = vp->ch;
- chan = vp->chan;
-
- /* channel to be silent and idle */
- EMU8000_DCYSUSV_WRITE(hw, ch, 0x0080);
- EMU8000_VTFT_WRITE(hw, ch, 0x0000FFFF);
- EMU8000_CVCF_WRITE(hw, ch, 0x0000FFFF);
- EMU8000_PTRX_WRITE(hw, ch, 0);
- EMU8000_CPF_WRITE(hw, ch, 0);
-
- /* set pitch offset */
- set_pitch(hw, vp);
-
- /* set envelope parameters */
- EMU8000_ENVVAL_WRITE(hw, ch, vp->reg.parm.moddelay);
- EMU8000_ATKHLD_WRITE(hw, ch, vp->reg.parm.modatkhld);
- EMU8000_DCYSUS_WRITE(hw, ch, vp->reg.parm.moddcysus);
- EMU8000_ENVVOL_WRITE(hw, ch, vp->reg.parm.voldelay);
- EMU8000_ATKHLDV_WRITE(hw, ch, vp->reg.parm.volatkhld);
- /* decay/sustain parameter for volume envelope is used
- for triggerg the voice */
-
- /* cutoff and volume */
- set_volume(hw, vp);
-
- /* modulation envelope heights */
- EMU8000_PEFE_WRITE(hw, ch, vp->reg.parm.pefe);
-
- /* lfo1/2 delay */
- EMU8000_LFO1VAL_WRITE(hw, ch, vp->reg.parm.lfo1delay);
- EMU8000_LFO2VAL_WRITE(hw, ch, vp->reg.parm.lfo2delay);
-
- /* lfo1 pitch & cutoff shift */
- set_fmmod(hw, vp);
- /* lfo1 volume & freq */
- set_tremfreq(hw, vp);
- /* lfo2 pitch & freq */
- set_fm2frq2(hw, vp);
- /* pan & loop start */
- set_pan(hw, vp);
-
- /* chorus & loop end (chorus 8bit, MSB) */
- addr = vp->reg.loopend - 1;
- temp = vp->reg.parm.chorus;
- temp += (int)chan->control[MIDI_CTL_E3_CHORUS_DEPTH] * 9 / 10;
- LIMITMAX(temp, 255);
- temp = (temp <<24) | (unsigned int)addr;
- EMU8000_CSL_WRITE(hw, ch, temp);
-
- /* Q & current address (Q 4bit value, MSB) */
- addr = vp->reg.start - 1;
- temp = vp->reg.parm.filterQ;
- temp = (temp<<28) | (unsigned int)addr;
- EMU8000_CCCA_WRITE(hw, ch, temp);
-
- /* clear unknown registers */
- EMU8000_00A0_WRITE(hw, ch, 0);
- EMU8000_0080_WRITE(hw, ch, 0);
-
- /* reset volume */
- temp = vp->vtarget << 16;
- EMU8000_VTFT_WRITE(hw, ch, temp | vp->ftarget);
- EMU8000_CVCF_WRITE(hw, ch, temp | 0xff00);
-
- return 0;
-}
-
-/*
- * Start envelope
- */
-static void
-trigger_voice(struct snd_emux_voice *vp)
-{
- int ch = vp->ch;
- unsigned int temp;
- struct snd_emu8000 *hw;
-
- hw = vp->hw;
-
- /* set reverb and pitch target */
- temp = vp->reg.parm.reverb;
- temp += (int)vp->chan->control[MIDI_CTL_E1_REVERB_DEPTH] * 9 / 10;
- LIMITMAX(temp, 255);
- temp = (temp << 8) | (vp->ptarget << 16) | vp->aaux;
- EMU8000_PTRX_WRITE(hw, ch, temp);
- EMU8000_CPF_WRITE(hw, ch, vp->ptarget << 16);
- EMU8000_DCYSUSV_WRITE(hw, ch, vp->reg.parm.voldcysus);
-}
-
-/*
- * reset voice parameters
- */
-static void
-reset_voice(struct snd_emux *emu, int ch)
-{
- struct snd_emu8000 *hw;
-
- hw = emu->hw;
- EMU8000_DCYSUSV_WRITE(hw, ch, 0x807F);
- snd_emu8000_tweak_voice(hw, ch);
-}
-
-/*
- * Set the pitch of a possibly playing note.
- */
-static void
-set_pitch(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
-{
- EMU8000_IP_WRITE(hw, vp->ch, vp->apitch);
-}
-
-/*
- * Set the volume of a possibly already playing note
- */
-static void
-set_volume(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
-{
- int ifatn;
-
- ifatn = (unsigned char)vp->acutoff;
- ifatn = (ifatn << 8);
- ifatn |= (unsigned char)vp->avol;
- EMU8000_IFATN_WRITE(hw, vp->ch, ifatn);
-}
-
-/*
- * Set pan and loop start address.
- */
-static void
-set_pan(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
-{
- unsigned int temp;
-
- temp = ((unsigned int)vp->apan<<24) | ((unsigned int)vp->reg.loopstart - 1);
- EMU8000_PSST_WRITE(hw, vp->ch, temp);
-}
-
-#define MOD_SENSE 18
-
-static void
-set_fmmod(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
-{
- unsigned short fmmod;
- short pitch;
- unsigned char cutoff;
- int modulation;
-
- pitch = (char)(vp->reg.parm.fmmod>>8);
- cutoff = (vp->reg.parm.fmmod & 0xff);
- modulation = vp->chan->gm_modulation + vp->chan->midi_pressure;
- pitch += (MOD_SENSE * modulation) / 1200;
- LIMITVALUE(pitch, -128, 127);
- fmmod = ((unsigned char)pitch<<8) | cutoff;
- EMU8000_FMMOD_WRITE(hw, vp->ch, fmmod);
-}
-
-/* set tremolo (lfo1) volume & frequency */
-static void
-set_tremfreq(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
-{
- EMU8000_TREMFRQ_WRITE(hw, vp->ch, vp->reg.parm.tremfrq);
-}
-
-/* set lfo2 pitch & frequency */
-static void
-set_fm2frq2(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
-{
- unsigned short fm2frq2;
- short pitch;
- unsigned char freq;
- int modulation;
-
- pitch = (char)(vp->reg.parm.fm2frq2>>8);
- freq = vp->reg.parm.fm2frq2 & 0xff;
- modulation = vp->chan->gm_modulation + vp->chan->midi_pressure;
- pitch += (MOD_SENSE * modulation) / 1200;
- LIMITVALUE(pitch, -128, 127);
- fm2frq2 = ((unsigned char)pitch<<8) | freq;
- EMU8000_FM2FRQ2_WRITE(hw, vp->ch, fm2frq2);
-}
-
-/* set filterQ */
-static void
-set_filterQ(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
-{
- unsigned int addr;
- addr = EMU8000_CCCA_READ(hw, vp->ch) & 0xffffff;
- addr |= (vp->reg.parm.filterQ << 28);
- EMU8000_CCCA_WRITE(hw, vp->ch, addr);
-}
-
-/*
- * set the envelope & LFO parameters to the default values
- */
-static void
-snd_emu8000_tweak_voice(struct snd_emu8000 *emu, int i)
-{
- /* set all mod/vol envelope shape to minimum */
- EMU8000_ENVVOL_WRITE(emu, i, 0x8000);
- EMU8000_ENVVAL_WRITE(emu, i, 0x8000);
- EMU8000_DCYSUS_WRITE(emu, i, 0x7F7F);
- EMU8000_ATKHLDV_WRITE(emu, i, 0x7F7F);
- EMU8000_ATKHLD_WRITE(emu, i, 0x7F7F);
- EMU8000_PEFE_WRITE(emu, i, 0); /* mod envelope height to zero */
- EMU8000_LFO1VAL_WRITE(emu, i, 0x8000); /* no delay for LFO1 */
- EMU8000_LFO2VAL_WRITE(emu, i, 0x8000);
- EMU8000_IP_WRITE(emu, i, 0xE000); /* no pitch shift */
- EMU8000_IFATN_WRITE(emu, i, 0xFF00); /* volume to minimum */
- EMU8000_FMMOD_WRITE(emu, i, 0);
- EMU8000_TREMFRQ_WRITE(emu, i, 0);
- EMU8000_FM2FRQ2_WRITE(emu, i, 0);
-}
-
-/*
- * sysex callback
- */
-static void
-sysex(struct snd_emux *emu, char *buf, int len, int parsed, struct snd_midi_channel_set *chset)
-{
- struct snd_emu8000 *hw;
-
- hw = emu->hw;
-
- switch (parsed) {
- case SNDRV_MIDI_SYSEX_GS_CHORUS_MODE:
- hw->chorus_mode = chset->gs_chorus_mode;
- snd_emu8000_update_chorus_mode(hw);
- break;
-
- case SNDRV_MIDI_SYSEX_GS_REVERB_MODE:
- hw->reverb_mode = chset->gs_reverb_mode;
- snd_emu8000_update_reverb_mode(hw);
- break;
- }
-}
-
-
-#ifdef CONFIG_SND_SEQUENCER_OSS
-/*
- * OSS ioctl callback
- */
-static int
-oss_ioctl(struct snd_emux *emu, int cmd, int p1, int p2)
-{
- struct snd_emu8000 *hw;
-
- hw = emu->hw;
-
- switch (cmd) {
- case _EMUX_OSS_REVERB_MODE:
- hw->reverb_mode = p1;
- snd_emu8000_update_reverb_mode(hw);
- break;
-
- case _EMUX_OSS_CHORUS_MODE:
- hw->chorus_mode = p1;
- snd_emu8000_update_chorus_mode(hw);
- break;
-
- case _EMUX_OSS_INITIALIZE_CHIP:
- /* snd_emu8000_init(hw); */ /*ignored*/
- break;
-
- case _EMUX_OSS_EQUALIZER:
- hw->bass_level = p1;
- hw->treble_level = p2;
- snd_emu8000_update_equalizer(hw);
- break;
- }
- return 0;
-}
-#endif
-
-
-/*
- * additional patch keys
- */
-
-#define SNDRV_EMU8000_LOAD_CHORUS_FX 0x10 /* optarg=mode */
-#define SNDRV_EMU8000_LOAD_REVERB_FX 0x11 /* optarg=mode */
-
-
-/*
- * callback routine
- */
-
-static int
-load_fx(struct snd_emux *emu, int type, int mode, const void __user *buf, long len)
-{
- struct snd_emu8000 *hw;
- hw = emu->hw;
-
- /* skip header */
- buf += 16;
- len -= 16;
-
- switch (type) {
- case SNDRV_EMU8000_LOAD_CHORUS_FX:
- return snd_emu8000_load_chorus_fx(hw, mode, buf, len);
- case SNDRV_EMU8000_LOAD_REVERB_FX:
- return snd_emu8000_load_reverb_fx(hw, mode, buf, len);
- }
- return -EINVAL;
-}
-
diff --git a/ANDROID_3.4.5/sound/isa/sb/emu8000_local.h b/ANDROID_3.4.5/sound/isa/sb/emu8000_local.h
deleted file mode 100644
index 7e87c349..00000000
--- a/ANDROID_3.4.5/sound/isa/sb/emu8000_local.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef __EMU8000_LOCAL_H
-#define __EMU8000_LOCAL_H
-/*
- * Local defininitons for the emu8000 (AWE32/64)
- *
- * Copyright (C) 1999 Steve Ratcliffe
- * Copyright (C) 1999-2000 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/wait.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/emu8000.h>
-#include <sound/emu8000_reg.h>
-
-/* emu8000_patch.c */
-int snd_emu8000_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
- struct snd_util_memhdr *hdr,
- const void __user *data, long count);
-int snd_emu8000_sample_free(struct snd_emux *rec, struct snd_sf_sample *sp,
- struct snd_util_memhdr *hdr);
-void snd_emu8000_sample_reset(struct snd_emux *rec);
-
-/* emu8000_callback.c */
-void snd_emu8000_ops_setup(struct snd_emu8000 *emu);
-
-/* emu8000_pcm.c */
-int snd_emu8000_pcm_new(struct snd_card *card, struct snd_emu8000 *emu, int index);
-
-#endif /* __EMU8000_LOCAL_H */
diff --git a/ANDROID_3.4.5/sound/isa/sb/emu8000_patch.c b/ANDROID_3.4.5/sound/isa/sb/emu8000_patch.c
deleted file mode 100644
index c99c6078..00000000
--- a/ANDROID_3.4.5/sound/isa/sb/emu8000_patch.c
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * Patch routines for the emu8000 (AWE32/64)
- *
- * Copyright (C) 1999 Steve Ratcliffe
- * Copyright (C) 1999-2000 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "emu8000_local.h"
-#include <asm/uaccess.h>
-#include <linux/moduleparam.h>
-
-static int emu8000_reset_addr;
-module_param(emu8000_reset_addr, int, 0444);
-MODULE_PARM_DESC(emu8000_reset_addr, "reset write address at each time (makes slowdown)");
-
-
-/*
- * Open up channels.
- */
-static int
-snd_emu8000_open_dma(struct snd_emu8000 *emu, int write)
-{
- int i;
-
- /* reserve all 30 voices for loading */
- for (i = 0; i < EMU8000_DRAM_VOICES; i++) {
- snd_emux_lock_voice(emu->emu, i);
- snd_emu8000_dma_chan(emu, i, write);
- }
-
- /* assign voice 31 and 32 to ROM */
- EMU8000_VTFT_WRITE(emu, 30, 0);
- EMU8000_PSST_WRITE(emu, 30, 0x1d8);
- EMU8000_CSL_WRITE(emu, 30, 0x1e0);
- EMU8000_CCCA_WRITE(emu, 30, 0x1d8);
- EMU8000_VTFT_WRITE(emu, 31, 0);
- EMU8000_PSST_WRITE(emu, 31, 0x1d8);
- EMU8000_CSL_WRITE(emu, 31, 0x1e0);
- EMU8000_CCCA_WRITE(emu, 31, 0x1d8);
-
- return 0;
-}
-
-/*
- * Close all dram channels.
- */
-static void
-snd_emu8000_close_dma(struct snd_emu8000 *emu)
-{
- int i;
-
- for (i = 0; i < EMU8000_DRAM_VOICES; i++) {
- snd_emu8000_dma_chan(emu, i, EMU8000_RAM_CLOSE);
- snd_emux_unlock_voice(emu->emu, i);
- }
-}
-
-/*
- */
-
-#define BLANK_LOOP_START 4
-#define BLANK_LOOP_END 8
-#define BLANK_LOOP_SIZE 12
-#define BLANK_HEAD_SIZE 48
-
-/*
- * Read a word from userland, taking care of conversions from
- * 8bit samples etc.
- */
-static unsigned short
-read_word(const void __user *buf, int offset, int mode)
-{
- unsigned short c;
- if (mode & SNDRV_SFNT_SAMPLE_8BITS) {
- unsigned char cc;
- get_user(cc, (unsigned char __user *)buf + offset);
- c = cc << 8; /* convert 8bit -> 16bit */
- } else {
-#ifdef SNDRV_LITTLE_ENDIAN
- get_user(c, (unsigned short __user *)buf + offset);
-#else
- unsigned short cc;
- get_user(cc, (unsigned short __user *)buf + offset);
- c = swab16(cc);
-#endif
- }
- if (mode & SNDRV_SFNT_SAMPLE_UNSIGNED)
- c ^= 0x8000; /* unsigned -> signed */
- return c;
-}
-
-/*
- */
-static void
-snd_emu8000_write_wait(struct snd_emu8000 *emu)
-{
- while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
- schedule_timeout_interruptible(1);
- if (signal_pending(current))
- break;
- }
-}
-
-/*
- * write sample word data
- *
- * You should not have to keep resetting the address each time
- * as the chip is supposed to step on the next address automatically.
- * It mostly does, but during writes of some samples at random it
- * completely loses words (every one in 16 roughly but with no
- * obvious pattern).
- *
- * This is therefore much slower than need be, but is at least
- * working.
- */
-static inline void
-write_word(struct snd_emu8000 *emu, int *offset, unsigned short data)
-{
- if (emu8000_reset_addr) {
- if (emu8000_reset_addr > 1)
- snd_emu8000_write_wait(emu);
- EMU8000_SMALW_WRITE(emu, *offset);
- }
- EMU8000_SMLD_WRITE(emu, data);
- *offset += 1;
-}
-
-/*
- * Write the sample to EMU800 memory. This routine is invoked out of
- * the generic soundfont routines as a callback.
- */
-int
-snd_emu8000_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
- struct snd_util_memhdr *hdr,
- const void __user *data, long count)
-{
- int i;
- int rc;
- int offset;
- int truesize;
- int dram_offset, dram_start;
- struct snd_emu8000 *emu;
-
- emu = rec->hw;
- if (snd_BUG_ON(!sp))
- return -EINVAL;
-
- if (sp->v.size == 0)
- return 0;
-
- /* be sure loop points start < end */
- if (sp->v.loopstart > sp->v.loopend) {
- int tmp = sp->v.loopstart;
- sp->v.loopstart = sp->v.loopend;
- sp->v.loopend = tmp;
- }
-
- /* compute true data size to be loaded */
- truesize = sp->v.size;
- if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP|SNDRV_SFNT_SAMPLE_REVERSE_LOOP))
- truesize += sp->v.loopend - sp->v.loopstart;
- if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK)
- truesize += BLANK_LOOP_SIZE;
-
- sp->block = snd_util_mem_alloc(hdr, truesize * 2);
- if (sp->block == NULL) {
- /*snd_printd("EMU8000: out of memory\n");*/
- /* not ENOMEM (for compatibility) */
- return -ENOSPC;
- }
-
- if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS) {
- if (!access_ok(VERIFY_READ, data, sp->v.size))
- return -EFAULT;
- } else {
- if (!access_ok(VERIFY_READ, data, sp->v.size * 2))
- return -EFAULT;
- }
-
- /* recalculate address offset */
- sp->v.end -= sp->v.start;
- sp->v.loopstart -= sp->v.start;
- sp->v.loopend -= sp->v.start;
- sp->v.start = 0;
-
- /* dram position (in word) -- mem_offset is byte */
- dram_offset = EMU8000_DRAM_OFFSET + (sp->block->offset >> 1);
- dram_start = dram_offset;
-
- /* set the total size (store onto obsolete checksum value) */
- sp->v.truesize = truesize * 2; /* in bytes */
-
- snd_emux_terminate_all(emu->emu);
- if ((rc = snd_emu8000_open_dma(emu, EMU8000_RAM_WRITE)) != 0)
- return rc;
-
- /* Set the address to start writing at */
- snd_emu8000_write_wait(emu);
- EMU8000_SMALW_WRITE(emu, dram_offset);
-
- /*snd_emu8000_init_fm(emu);*/
-
-#if 0
- /* first block - write 48 samples for silence */
- if (! sp->block->offset) {
- for (i = 0; i < BLANK_HEAD_SIZE; i++) {
- write_word(emu, &dram_offset, 0);
- }
- }
-#endif
-
- offset = 0;
- for (i = 0; i < sp->v.size; i++) {
- unsigned short s;
-
- s = read_word(data, offset, sp->v.mode_flags);
- offset++;
- write_word(emu, &dram_offset, s);
-
- /* we may take too long time in this loop.
- * so give controls back to kernel if needed.
- */
- cond_resched();
-
- if (i == sp->v.loopend &&
- (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP|SNDRV_SFNT_SAMPLE_REVERSE_LOOP)))
- {
- int looplen = sp->v.loopend - sp->v.loopstart;
- int k;
-
- /* copy reverse loop */
- for (k = 1; k <= looplen; k++) {
- s = read_word(data, offset - k, sp->v.mode_flags);
- write_word(emu, &dram_offset, s);
- }
- if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_BIDIR_LOOP) {
- sp->v.loopend += looplen;
- } else {
- sp->v.loopstart += looplen;
- sp->v.loopend += looplen;
- }
- sp->v.end += looplen;
- }
- }
-
- /* if no blank loop is attached in the sample, add it */
- if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK) {
- for (i = 0; i < BLANK_LOOP_SIZE; i++) {
- write_word(emu, &dram_offset, 0);
- }
- if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT) {
- sp->v.loopstart = sp->v.end + BLANK_LOOP_START;
- sp->v.loopend = sp->v.end + BLANK_LOOP_END;
- }
- }
-
- /* add dram offset */
- sp->v.start += dram_start;
- sp->v.end += dram_start;
- sp->v.loopstart += dram_start;
- sp->v.loopend += dram_start;
-
- snd_emu8000_close_dma(emu);
- snd_emu8000_init_fm(emu);
-
- return 0;
-}
-
-/*
- * free a sample block
- */
-int
-snd_emu8000_sample_free(struct snd_emux *rec, struct snd_sf_sample *sp,
- struct snd_util_memhdr *hdr)
-{
- if (sp->block) {
- snd_util_mem_free(hdr, sp->block);
- sp->block = NULL;
- }
- return 0;
-}
-
-
-/*
- * sample_reset callback - terminate voices
- */
-void
-snd_emu8000_sample_reset(struct snd_emux *rec)
-{
- snd_emux_terminate_all(rec);
-}
diff --git a/ANDROID_3.4.5/sound/isa/sb/emu8000_pcm.c b/ANDROID_3.4.5/sound/isa/sb/emu8000_pcm.c
deleted file mode 100644
index 2f85c66f..00000000
--- a/ANDROID_3.4.5/sound/isa/sb/emu8000_pcm.c
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- * pcm emulation on emu8000 wavetable
- *
- * Copyright (C) 2002 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "emu8000_local.h"
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-
-/*
- * define the following if you want to use this pcm with non-interleaved mode
- */
-/* #define USE_NONINTERLEAVE */
-
-/* NOTE: for using the non-interleaved mode with alsa-lib, you have to set
- * mmap_emulation flag to 1 in your .asoundrc, such like
- *
- * pcm.emu8k {
- * type plug
- * slave.pcm {
- * type hw
- * card 0
- * device 1
- * mmap_emulation 1
- * }
- * }
- *
- * besides, for the time being, the non-interleaved mode doesn't work well on
- * alsa-lib...
- */
-
-
-struct snd_emu8k_pcm {
- struct snd_emu8000 *emu;
- struct snd_pcm_substream *substream;
-
- unsigned int allocated_bytes;
- struct snd_util_memblk *block;
- unsigned int offset;
- unsigned int buf_size;
- unsigned int period_size;
- unsigned int loop_start[2];
- unsigned int pitch;
- int panning[2];
- int last_ptr;
- int period_pos;
- int voices;
- unsigned int dram_opened: 1;
- unsigned int running: 1;
- unsigned int timer_running: 1;
- struct timer_list timer;
- spinlock_t timer_lock;
-};
-
-#define LOOP_BLANK_SIZE 8
-
-
-/*
- * open up channels for the simultaneous data transfer and playback
- */
-static int
-emu8k_open_dram_for_pcm(struct snd_emu8000 *emu, int channels)
-{
- int i;
-
- /* reserve up to 2 voices for playback */
- snd_emux_lock_voice(emu->emu, 0);
- if (channels > 1)
- snd_emux_lock_voice(emu->emu, 1);
-
- /* reserve 28 voices for loading */
- for (i = channels + 1; i < EMU8000_DRAM_VOICES; i++) {
- unsigned int mode = EMU8000_RAM_WRITE;
- snd_emux_lock_voice(emu->emu, i);
-#ifndef USE_NONINTERLEAVE
- if (channels > 1 && (i & 1) != 0)
- mode |= EMU8000_RAM_RIGHT;
-#endif
- snd_emu8000_dma_chan(emu, i, mode);
- }
-
- /* assign voice 31 and 32 to ROM */
- EMU8000_VTFT_WRITE(emu, 30, 0);
- EMU8000_PSST_WRITE(emu, 30, 0x1d8);
- EMU8000_CSL_WRITE(emu, 30, 0x1e0);
- EMU8000_CCCA_WRITE(emu, 30, 0x1d8);
- EMU8000_VTFT_WRITE(emu, 31, 0);
- EMU8000_PSST_WRITE(emu, 31, 0x1d8);
- EMU8000_CSL_WRITE(emu, 31, 0x1e0);
- EMU8000_CCCA_WRITE(emu, 31, 0x1d8);
-
- return 0;
-}
-
-/*
- */
-static void
-snd_emu8000_write_wait(struct snd_emu8000 *emu, int can_schedule)
-{
- while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
- if (can_schedule) {
- schedule_timeout_interruptible(1);
- if (signal_pending(current))
- break;
- }
- }
-}
-
-/*
- * close all channels
- */
-static void
-emu8k_close_dram(struct snd_emu8000 *emu)
-{
- int i;
-
- for (i = 0; i < 2; i++)
- snd_emux_unlock_voice(emu->emu, i);
- for (; i < EMU8000_DRAM_VOICES; i++) {
- snd_emu8000_dma_chan(emu, i, EMU8000_RAM_CLOSE);
- snd_emux_unlock_voice(emu->emu, i);
- }
-}
-
-/*
- * convert Hz to AWE32 rate offset (see emux/soundfont.c)
- */
-
-#define OFFSET_SAMPLERATE 1011119 /* base = 44100 */
-#define SAMPLERATE_RATIO 4096
-
-static int calc_rate_offset(int hz)
-{
- return snd_sf_linear_to_log(hz, OFFSET_SAMPLERATE, SAMPLERATE_RATIO);
-}
-
-
-/*
- */
-
-static struct snd_pcm_hardware emu8k_pcm_hw = {
-#ifdef USE_NONINTERLEAVE
- .info = SNDRV_PCM_INFO_NONINTERLEAVED,
-#else
- .info = SNDRV_PCM_INFO_INTERLEAVED,
-#endif
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 1024,
- .period_bytes_max = (128*1024),
- .periods_min = 2,
- .periods_max = 1024,
- .fifo_size = 0,
-
-};
-
-/*
- * get the current position at the given channel from CCCA register
- */
-static inline int emu8k_get_curpos(struct snd_emu8k_pcm *rec, int ch)
-{
- int val = EMU8000_CCCA_READ(rec->emu, ch) & 0xfffffff;
- val -= rec->loop_start[ch] - 1;
- return val;
-}
-
-
-/*
- * timer interrupt handler
- * check the current position and update the period if necessary.
- */
-static void emu8k_pcm_timer_func(unsigned long data)
-{
- struct snd_emu8k_pcm *rec = (struct snd_emu8k_pcm *)data;
- int ptr, delta;
-
- spin_lock(&rec->timer_lock);
- /* update the current pointer */
- ptr = emu8k_get_curpos(rec, 0);
- if (ptr < rec->last_ptr)
- delta = ptr + rec->buf_size - rec->last_ptr;
- else
- delta = ptr - rec->last_ptr;
- rec->period_pos += delta;
- rec->last_ptr = ptr;
-
- /* reprogram timer */
- rec->timer.expires = jiffies + 1;
- add_timer(&rec->timer);
-
- /* update period */
- if (rec->period_pos >= (int)rec->period_size) {
- rec->period_pos %= rec->period_size;
- spin_unlock(&rec->timer_lock);
- snd_pcm_period_elapsed(rec->substream);
- return;
- }
- spin_unlock(&rec->timer_lock);
-}
-
-
-/*
- * open pcm
- * creating an instance here
- */
-static int emu8k_pcm_open(struct snd_pcm_substream *subs)
-{
- struct snd_emu8000 *emu = snd_pcm_substream_chip(subs);
- struct snd_emu8k_pcm *rec;
- struct snd_pcm_runtime *runtime = subs->runtime;
-
- rec = kzalloc(sizeof(*rec), GFP_KERNEL);
- if (! rec)
- return -ENOMEM;
-
- rec->emu = emu;
- rec->substream = subs;
- runtime->private_data = rec;
-
- spin_lock_init(&rec->timer_lock);
- init_timer(&rec->timer);
- rec->timer.function = emu8k_pcm_timer_func;
- rec->timer.data = (unsigned long)rec;
-
- runtime->hw = emu8k_pcm_hw;
- runtime->hw.buffer_bytes_max = emu->mem_size - LOOP_BLANK_SIZE * 3;
- runtime->hw.period_bytes_max = runtime->hw.buffer_bytes_max / 2;
-
- /* use timer to update periods.. (specified in msec) */
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME,
- (1000000 + HZ - 1) / HZ, UINT_MAX);
-
- return 0;
-}
-
-static int emu8k_pcm_close(struct snd_pcm_substream *subs)
-{
- struct snd_emu8k_pcm *rec = subs->runtime->private_data;
- kfree(rec);
- subs->runtime->private_data = NULL;
- return 0;
-}
-
-/*
- * calculate pitch target
- */
-static int calc_pitch_target(int pitch)
-{
- int ptarget = 1 << (pitch >> 12);
- if (pitch & 0x800) ptarget += (ptarget * 0x102e) / 0x2710;
- if (pitch & 0x400) ptarget += (ptarget * 0x764) / 0x2710;
- if (pitch & 0x200) ptarget += (ptarget * 0x389) / 0x2710;
- ptarget += (ptarget >> 1);
- if (ptarget > 0xffff) ptarget = 0xffff;
- return ptarget;
-}
-
-/*
- * set up the voice
- */
-static void setup_voice(struct snd_emu8k_pcm *rec, int ch)
-{
- struct snd_emu8000 *hw = rec->emu;
- unsigned int temp;
-
- /* channel to be silent and idle */
- EMU8000_DCYSUSV_WRITE(hw, ch, 0x0080);
- EMU8000_VTFT_WRITE(hw, ch, 0x0000FFFF);
- EMU8000_CVCF_WRITE(hw, ch, 0x0000FFFF);
- EMU8000_PTRX_WRITE(hw, ch, 0);
- EMU8000_CPF_WRITE(hw, ch, 0);
-
- /* pitch offset */
- EMU8000_IP_WRITE(hw, ch, rec->pitch);
- /* set envelope parameters */
- EMU8000_ENVVAL_WRITE(hw, ch, 0x8000);
- EMU8000_ATKHLD_WRITE(hw, ch, 0x7f7f);
- EMU8000_DCYSUS_WRITE(hw, ch, 0x7f7f);
- EMU8000_ENVVOL_WRITE(hw, ch, 0x8000);
- EMU8000_ATKHLDV_WRITE(hw, ch, 0x7f7f);
- /* decay/sustain parameter for volume envelope is used
- for triggerg the voice */
- /* modulation envelope heights */
- EMU8000_PEFE_WRITE(hw, ch, 0x0);
- /* lfo1/2 delay */
- EMU8000_LFO1VAL_WRITE(hw, ch, 0x8000);
- EMU8000_LFO2VAL_WRITE(hw, ch, 0x8000);
- /* lfo1 pitch & cutoff shift */
- EMU8000_FMMOD_WRITE(hw, ch, 0);
- /* lfo1 volume & freq */
- EMU8000_TREMFRQ_WRITE(hw, ch, 0);
- /* lfo2 pitch & freq */
- EMU8000_FM2FRQ2_WRITE(hw, ch, 0);
- /* pan & loop start */
- temp = rec->panning[ch];
- temp = (temp <<24) | ((unsigned int)rec->loop_start[ch] - 1);
- EMU8000_PSST_WRITE(hw, ch, temp);
- /* chorus & loop end (chorus 8bit, MSB) */
- temp = 0; // chorus
- temp = (temp << 24) | ((unsigned int)rec->loop_start[ch] + rec->buf_size - 1);
- EMU8000_CSL_WRITE(hw, ch, temp);
- /* Q & current address (Q 4bit value, MSB) */
- temp = 0; // filterQ
- temp = (temp << 28) | ((unsigned int)rec->loop_start[ch] - 1);
- EMU8000_CCCA_WRITE(hw, ch, temp);
- /* clear unknown registers */
- EMU8000_00A0_WRITE(hw, ch, 0);
- EMU8000_0080_WRITE(hw, ch, 0);
-}
-
-/*
- * trigger the voice
- */
-static void start_voice(struct snd_emu8k_pcm *rec, int ch)
-{
- unsigned long flags;
- struct snd_emu8000 *hw = rec->emu;
- unsigned int temp, aux;
- int pt = calc_pitch_target(rec->pitch);
-
- /* cutoff and volume */
- EMU8000_IFATN_WRITE(hw, ch, 0xff00);
- EMU8000_VTFT_WRITE(hw, ch, 0xffff);
- EMU8000_CVCF_WRITE(hw, ch, 0xffff);
- /* trigger envelope */
- EMU8000_DCYSUSV_WRITE(hw, ch, 0x7f7f);
- /* set reverb and pitch target */
- temp = 0; // reverb
- if (rec->panning[ch] == 0)
- aux = 0xff;
- else
- aux = (-rec->panning[ch]) & 0xff;
- temp = (temp << 8) | (pt << 16) | aux;
- EMU8000_PTRX_WRITE(hw, ch, temp);
- EMU8000_CPF_WRITE(hw, ch, pt << 16);
-
- /* start timer */
- spin_lock_irqsave(&rec->timer_lock, flags);
- if (! rec->timer_running) {
- rec->timer.expires = jiffies + 1;
- add_timer(&rec->timer);
- rec->timer_running = 1;
- }
- spin_unlock_irqrestore(&rec->timer_lock, flags);
-}
-
-/*
- * stop the voice immediately
- */
-static void stop_voice(struct snd_emu8k_pcm *rec, int ch)
-{
- unsigned long flags;
- struct snd_emu8000 *hw = rec->emu;
-
- EMU8000_DCYSUSV_WRITE(hw, ch, 0x807F);
-
- /* stop timer */
- spin_lock_irqsave(&rec->timer_lock, flags);
- if (rec->timer_running) {
- del_timer(&rec->timer);
- rec->timer_running = 0;
- }
- spin_unlock_irqrestore(&rec->timer_lock, flags);
-}
-
-static int emu8k_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
-{
- struct snd_emu8k_pcm *rec = subs->runtime->private_data;
- int ch;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- for (ch = 0; ch < rec->voices; ch++)
- start_voice(rec, ch);
- rec->running = 1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- rec->running = 0;
- for (ch = 0; ch < rec->voices; ch++)
- stop_voice(rec, ch);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-
-/*
- * copy / silence ops
- */
-
-/*
- * this macro should be inserted in the copy/silence loops
- * to reduce the latency. without this, the system will hang up
- * during the whole loop.
- */
-#define CHECK_SCHEDULER() \
-do { \
- cond_resched();\
- if (signal_pending(current))\
- return -EAGAIN;\
-} while (0)
-
-
-#ifdef USE_NONINTERLEAVE
-/* copy one channel block */
-static int emu8k_transfer_block(struct snd_emu8000 *emu, int offset, unsigned short *buf, int count)
-{
- EMU8000_SMALW_WRITE(emu, offset);
- while (count > 0) {
- unsigned short sval;
- CHECK_SCHEDULER();
- if (get_user(sval, buf))
- return -EFAULT;
- EMU8000_SMLD_WRITE(emu, sval);
- buf++;
- count--;
- }
- return 0;
-}
-
-static int emu8k_pcm_copy(struct snd_pcm_substream *subs,
- int voice,
- snd_pcm_uframes_t pos,
- void *src,
- snd_pcm_uframes_t count)
-{
- struct snd_emu8k_pcm *rec = subs->runtime->private_data;
- struct snd_emu8000 *emu = rec->emu;
-
- snd_emu8000_write_wait(emu, 1);
- if (voice == -1) {
- unsigned short *buf = src;
- int i, err;
- count /= rec->voices;
- for (i = 0; i < rec->voices; i++) {
- err = emu8k_transfer_block(emu, pos + rec->loop_start[i], buf, count);
- if (err < 0)
- return err;
- buf += count;
- }
- return 0;
- } else {
- return emu8k_transfer_block(emu, pos + rec->loop_start[voice], src, count);
- }
-}
-
-/* make a channel block silence */
-static int emu8k_silence_block(struct snd_emu8000 *emu, int offset, int count)
-{
- EMU8000_SMALW_WRITE(emu, offset);
- while (count > 0) {
- CHECK_SCHEDULER();
- EMU8000_SMLD_WRITE(emu, 0);
- count--;
- }
- return 0;
-}
-
-static int emu8k_pcm_silence(struct snd_pcm_substream *subs,
- int voice,
- snd_pcm_uframes_t pos,
- snd_pcm_uframes_t count)
-{
- struct snd_emu8k_pcm *rec = subs->runtime->private_data;
- struct snd_emu8000 *emu = rec->emu;
-
- snd_emu8000_write_wait(emu, 1);
- if (voice == -1 && rec->voices == 1)
- voice = 0;
- if (voice == -1) {
- int err;
- err = emu8k_silence_block(emu, pos + rec->loop_start[0], count / 2);
- if (err < 0)
- return err;
- return emu8k_silence_block(emu, pos + rec->loop_start[1], count / 2);
- } else {
- return emu8k_silence_block(emu, pos + rec->loop_start[voice], count);
- }
-}
-
-#else /* interleave */
-
-/*
- * copy the interleaved data can be done easily by using
- * DMA "left" and "right" channels on emu8k engine.
- */
-static int emu8k_pcm_copy(struct snd_pcm_substream *subs,
- int voice,
- snd_pcm_uframes_t pos,
- void __user *src,
- snd_pcm_uframes_t count)
-{
- struct snd_emu8k_pcm *rec = subs->runtime->private_data;
- struct snd_emu8000 *emu = rec->emu;
- unsigned short __user *buf = src;
-
- snd_emu8000_write_wait(emu, 1);
- EMU8000_SMALW_WRITE(emu, pos + rec->loop_start[0]);
- if (rec->voices > 1)
- EMU8000_SMARW_WRITE(emu, pos + rec->loop_start[1]);
-
- while (count-- > 0) {
- unsigned short sval;
- CHECK_SCHEDULER();
- if (get_user(sval, buf))
- return -EFAULT;
- EMU8000_SMLD_WRITE(emu, sval);
- buf++;
- if (rec->voices > 1) {
- CHECK_SCHEDULER();
- if (get_user(sval, buf))
- return -EFAULT;
- EMU8000_SMRD_WRITE(emu, sval);
- buf++;
- }
- }
- return 0;
-}
-
-static int emu8k_pcm_silence(struct snd_pcm_substream *subs,
- int voice,
- snd_pcm_uframes_t pos,
- snd_pcm_uframes_t count)
-{
- struct snd_emu8k_pcm *rec = subs->runtime->private_data;
- struct snd_emu8000 *emu = rec->emu;
-
- snd_emu8000_write_wait(emu, 1);
- EMU8000_SMALW_WRITE(emu, rec->loop_start[0] + pos);
- if (rec->voices > 1)
- EMU8000_SMARW_WRITE(emu, rec->loop_start[1] + pos);
- while (count-- > 0) {
- CHECK_SCHEDULER();
- EMU8000_SMLD_WRITE(emu, 0);
- if (rec->voices > 1) {
- CHECK_SCHEDULER();
- EMU8000_SMRD_WRITE(emu, 0);
- }
- }
- return 0;
-}
-#endif
-
-
-/*
- * allocate a memory block
- */
-static int emu8k_pcm_hw_params(struct snd_pcm_substream *subs,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_emu8k_pcm *rec = subs->runtime->private_data;
-
- if (rec->block) {
- /* reallocation - release the old block */
- snd_util_mem_free(rec->emu->memhdr, rec->block);
- rec->block = NULL;
- }
-
- rec->allocated_bytes = params_buffer_bytes(hw_params) + LOOP_BLANK_SIZE * 4;
- rec->block = snd_util_mem_alloc(rec->emu->memhdr, rec->allocated_bytes);
- if (! rec->block)
- return -ENOMEM;
- rec->offset = EMU8000_DRAM_OFFSET + (rec->block->offset >> 1); /* in word */
- /* at least dma_bytes must be set for non-interleaved mode */
- subs->dma_buffer.bytes = params_buffer_bytes(hw_params);
-
- return 0;
-}
-
-/*
- * free the memory block
- */
-static int emu8k_pcm_hw_free(struct snd_pcm_substream *subs)
-{
- struct snd_emu8k_pcm *rec = subs->runtime->private_data;
-
- if (rec->block) {
- int ch;
- for (ch = 0; ch < rec->voices; ch++)
- stop_voice(rec, ch); // to be sure
- if (rec->dram_opened)
- emu8k_close_dram(rec->emu);
- snd_util_mem_free(rec->emu->memhdr, rec->block);
- rec->block = NULL;
- }
- return 0;
-}
-
-/*
- */
-static int emu8k_pcm_prepare(struct snd_pcm_substream *subs)
-{
- struct snd_emu8k_pcm *rec = subs->runtime->private_data;
-
- rec->pitch = 0xe000 + calc_rate_offset(subs->runtime->rate);
- rec->last_ptr = 0;
- rec->period_pos = 0;
-
- rec->buf_size = subs->runtime->buffer_size;
- rec->period_size = subs->runtime->period_size;
- rec->voices = subs->runtime->channels;
- rec->loop_start[0] = rec->offset + LOOP_BLANK_SIZE;
- if (rec->voices > 1)
- rec->loop_start[1] = rec->loop_start[0] + rec->buf_size + LOOP_BLANK_SIZE;
- if (rec->voices > 1) {
- rec->panning[0] = 0xff;
- rec->panning[1] = 0x00;
- } else
- rec->panning[0] = 0x80;
-
- if (! rec->dram_opened) {
- int err, i, ch;
-
- snd_emux_terminate_all(rec->emu->emu);
- if ((err = emu8k_open_dram_for_pcm(rec->emu, rec->voices)) != 0)
- return err;
- rec->dram_opened = 1;
-
- /* clear loop blanks */
- snd_emu8000_write_wait(rec->emu, 0);
- EMU8000_SMALW_WRITE(rec->emu, rec->offset);
- for (i = 0; i < LOOP_BLANK_SIZE; i++)
- EMU8000_SMLD_WRITE(rec->emu, 0);
- for (ch = 0; ch < rec->voices; ch++) {
- EMU8000_SMALW_WRITE(rec->emu, rec->loop_start[ch] + rec->buf_size);
- for (i = 0; i < LOOP_BLANK_SIZE; i++)
- EMU8000_SMLD_WRITE(rec->emu, 0);
- }
- }
-
- setup_voice(rec, 0);
- if (rec->voices > 1)
- setup_voice(rec, 1);
- return 0;
-}
-
-static snd_pcm_uframes_t emu8k_pcm_pointer(struct snd_pcm_substream *subs)
-{
- struct snd_emu8k_pcm *rec = subs->runtime->private_data;
- if (rec->running)
- return emu8k_get_curpos(rec, 0);
- return 0;
-}
-
-
-static struct snd_pcm_ops emu8k_pcm_ops = {
- .open = emu8k_pcm_open,
- .close = emu8k_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = emu8k_pcm_hw_params,
- .hw_free = emu8k_pcm_hw_free,
- .prepare = emu8k_pcm_prepare,
- .trigger = emu8k_pcm_trigger,
- .pointer = emu8k_pcm_pointer,
- .copy = emu8k_pcm_copy,
- .silence = emu8k_pcm_silence,
-};
-
-
-static void snd_emu8000_pcm_free(struct snd_pcm *pcm)
-{
- struct snd_emu8000 *emu = pcm->private_data;
- emu->pcm = NULL;
-}
-
-int snd_emu8000_pcm_new(struct snd_card *card, struct snd_emu8000 *emu, int index)
-{
- struct snd_pcm *pcm;
- int err;
-
- if ((err = snd_pcm_new(card, "Emu8000 PCM", index, 1, 0, &pcm)) < 0)
- return err;
- pcm->private_data = emu;
- pcm->private_free = snd_emu8000_pcm_free;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &emu8k_pcm_ops);
- emu->pcm = pcm;
-
- snd_device_register(card, pcm);
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/isa/sb/emu8000_synth.c b/ANDROID_3.4.5/sound/isa/sb/emu8000_synth.c
deleted file mode 100644
index 4e3fcfb1..00000000
--- a/ANDROID_3.4.5/sound/isa/sb/emu8000_synth.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * and (c) 1999 Steve Ratcliffe <steve@parabola.demon.co.uk>
- * Copyright (C) 1999-2000 Takashi Iwai <tiwai@suse.de>
- *
- * Emu8000 synth plug-in routine
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "emu8000_local.h"
-#include <linux/init.h>
-#include <linux/module.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Takashi Iwai, Steve Ratcliffe");
-MODULE_DESCRIPTION("Emu8000 synth plug-in routine");
-MODULE_LICENSE("GPL");
-
-/*----------------------------------------------------------------*/
-
-/*
- * create a new hardware dependent device for Emu8000
- */
-static int snd_emu8000_new_device(struct snd_seq_device *dev)
-{
- struct snd_emu8000 *hw;
- struct snd_emux *emu;
-
- hw = *(struct snd_emu8000**)SNDRV_SEQ_DEVICE_ARGPTR(dev);
- if (hw == NULL)
- return -EINVAL;
-
- if (hw->emu)
- return -EBUSY; /* already exists..? */
-
- if (snd_emux_new(&emu) < 0)
- return -ENOMEM;
-
- hw->emu = emu;
- snd_emu8000_ops_setup(hw);
-
- emu->hw = hw;
- emu->max_voices = EMU8000_DRAM_VOICES;
- emu->num_ports = hw->seq_ports;
-
- if (hw->memhdr) {
- snd_printk(KERN_ERR "memhdr is already initialized!?\n");
- snd_util_memhdr_free(hw->memhdr);
- }
- hw->memhdr = snd_util_memhdr_new(hw->mem_size);
- if (hw->memhdr == NULL) {
- snd_emux_free(emu);
- hw->emu = NULL;
- return -ENOMEM;
- }
-
- emu->memhdr = hw->memhdr;
- emu->midi_ports = hw->seq_ports < 2 ? hw->seq_ports : 2; /* number of virmidi ports */
- emu->midi_devidx = 1;
- emu->linear_panning = 1;
- emu->hwdep_idx = 2; /* FIXED */
-
- if (snd_emux_register(emu, dev->card, hw->index, "Emu8000") < 0) {
- snd_emux_free(emu);
- snd_util_memhdr_free(hw->memhdr);
- hw->emu = NULL;
- hw->memhdr = NULL;
- return -ENOMEM;
- }
-
- if (hw->mem_size > 0)
- snd_emu8000_pcm_new(dev->card, hw, 1);
-
- dev->driver_data = hw;
-
- return 0;
-}
-
-
-/*
- * free all resources
- */
-static int snd_emu8000_delete_device(struct snd_seq_device *dev)
-{
- struct snd_emu8000 *hw;
-
- if (dev->driver_data == NULL)
- return 0; /* no synth was allocated actually */
-
- hw = dev->driver_data;
- if (hw->pcm)
- snd_device_free(dev->card, hw->pcm);
- if (hw->emu)
- snd_emux_free(hw->emu);
- if (hw->memhdr)
- snd_util_memhdr_free(hw->memhdr);
- hw->emu = NULL;
- hw->memhdr = NULL;
- return 0;
-}
-
-/*
- * INIT part
- */
-
-static int __init alsa_emu8000_init(void)
-{
-
- static struct snd_seq_dev_ops ops = {
- snd_emu8000_new_device,
- snd_emu8000_delete_device,
- };
- return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_EMU8000, &ops,
- sizeof(struct snd_emu8000*));
-}
-
-static void __exit alsa_emu8000_exit(void)
-{
- snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_EMU8000);
-}
-
-module_init(alsa_emu8000_init)
-module_exit(alsa_emu8000_exit)
diff --git a/ANDROID_3.4.5/sound/isa/sb/jazz16.c b/ANDROID_3.4.5/sound/isa/sb/jazz16.c
deleted file mode 100644
index 410758c6..00000000
--- a/ANDROID_3.4.5/sound/isa/sb/jazz16.c
+++ /dev/null
@@ -1,404 +0,0 @@
-
-/*
- * jazz16.c - driver for Media Vision Jazz16 based soundcards.
- * Copyright (C) 2009 Krzysztof Helt <krzysztof.h1@wp.pl>
- * Based on patches posted by Rask Ingemann Lambertsen and Rene Herman.
- * Based on OSS Sound Blaster driver.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <asm/dma.h>
-#include <linux/isa.h>
-#include <sound/core.h>
-#include <sound/mpu401.h>
-#include <sound/opl3.h>
-#include <sound/sb.h>
-#define SNDRV_LEGACY_FIND_FREE_IRQ
-#define SNDRV_LEGACY_FIND_FREE_DMA
-#include <sound/initval.h>
-
-#define PFX "jazz16: "
-
-MODULE_DESCRIPTION("Media Vision Jazz16");
-MODULE_SUPPORTED_DEVICE("{{Media Vision ??? },"
- "{RTL,RTL3000}}");
-
-MODULE_AUTHOR("Krzysztof Helt <krzysztof.h1@wp.pl>");
-MODULE_LICENSE("GPL");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
-static unsigned long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-static unsigned long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
-static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
-static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
-static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Media Vision Jazz16 based soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Media Vision Jazz16 based soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Media Vision Jazz16 based soundcard.");
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for jazz16 driver.");
-module_param_array(mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port # for jazz16 driver.");
-module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for jazz16 driver.");
-module_param_array(mpu_irq, int, NULL, 0444);
-MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for jazz16 driver.");
-module_param_array(dma8, int, NULL, 0444);
-MODULE_PARM_DESC(dma8, "DMA8 # for jazz16 driver.");
-module_param_array(dma16, int, NULL, 0444);
-MODULE_PARM_DESC(dma16, "DMA16 # for jazz16 driver.");
-
-#define SB_JAZZ16_WAKEUP 0xaf
-#define SB_JAZZ16_SET_PORTS 0x50
-#define SB_DSP_GET_JAZZ_BRD_REV 0xfa
-#define SB_JAZZ16_SET_DMAINTR 0xfb
-#define SB_DSP_GET_JAZZ_MODEL 0xfe
-
-struct snd_card_jazz16 {
- struct snd_sb *chip;
-};
-
-static irqreturn_t jazz16_interrupt(int irq, void *chip)
-{
- return snd_sb8dsp_interrupt(chip);
-}
-
-static int __devinit jazz16_configure_ports(unsigned long port,
- unsigned long mpu_port, int idx)
-{
- unsigned char val;
-
- if (!request_region(0x201, 1, "jazz16 config")) {
- snd_printk(KERN_ERR "config port region is already in use.\n");
- return -EBUSY;
- }
- outb(SB_JAZZ16_WAKEUP - idx, 0x201);
- udelay(100);
- outb(SB_JAZZ16_SET_PORTS + idx, 0x201);
- udelay(100);
- val = port & 0x70;
- val |= (mpu_port & 0x30) >> 4;
- outb(val, 0x201);
-
- release_region(0x201, 1);
- return 0;
-}
-
-static int __devinit jazz16_detect_board(unsigned long port,
- unsigned long mpu_port)
-{
- int err;
- int val;
- struct snd_sb chip;
-
- if (!request_region(port, 0x10, "jazz16")) {
- snd_printk(KERN_ERR "I/O port region is already in use.\n");
- return -EBUSY;
- }
- /* just to call snd_sbdsp_command/reset/get_byte() */
- chip.port = port;
-
- err = snd_sbdsp_reset(&chip);
- if (err < 0)
- for (val = 0; val < 4; val++) {
- err = jazz16_configure_ports(port, mpu_port, val);
- if (err < 0)
- break;
-
- err = snd_sbdsp_reset(&chip);
- if (!err)
- break;
- }
- if (err < 0) {
- err = -ENODEV;
- goto err_unmap;
- }
- if (!snd_sbdsp_command(&chip, SB_DSP_GET_JAZZ_BRD_REV)) {
- err = -EBUSY;
- goto err_unmap;
- }
- val = snd_sbdsp_get_byte(&chip);
- if (val >= 0x30)
- snd_sbdsp_get_byte(&chip);
-
- if ((val & 0xf0) != 0x10) {
- err = -ENODEV;
- goto err_unmap;
- }
- if (!snd_sbdsp_command(&chip, SB_DSP_GET_JAZZ_MODEL)) {
- err = -EBUSY;
- goto err_unmap;
- }
- snd_sbdsp_get_byte(&chip);
- err = snd_sbdsp_get_byte(&chip);
- snd_printd("Media Vision Jazz16 board detected: rev 0x%x, model 0x%x\n",
- val, err);
-
- err = 0;
-
-err_unmap:
- release_region(port, 0x10);
- return err;
-}
-
-static int __devinit jazz16_configure_board(struct snd_sb *chip, int mpu_irq)
-{
- static unsigned char jazz_irq_bits[] = { 0, 0, 2, 3, 0, 1, 0, 4,
- 0, 2, 5, 0, 0, 0, 0, 6 };
- static unsigned char jazz_dma_bits[] = { 0, 1, 0, 2, 0, 3, 0, 4 };
-
- if (jazz_dma_bits[chip->dma8] == 0 ||
- jazz_dma_bits[chip->dma16] == 0 ||
- jazz_irq_bits[chip->irq] == 0)
- return -EINVAL;
-
- if (!snd_sbdsp_command(chip, SB_JAZZ16_SET_DMAINTR))
- return -EBUSY;
-
- if (!snd_sbdsp_command(chip,
- jazz_dma_bits[chip->dma8] |
- (jazz_dma_bits[chip->dma16] << 4)))
- return -EBUSY;
-
- if (!snd_sbdsp_command(chip,
- jazz_irq_bits[chip->irq] |
- (jazz_irq_bits[mpu_irq] << 4)))
- return -EBUSY;
-
- return 0;
-}
-
-static int __devinit snd_jazz16_match(struct device *devptr, unsigned int dev)
-{
- if (!enable[dev])
- return 0;
- if (port[dev] == SNDRV_AUTO_PORT) {
- snd_printk(KERN_ERR "please specify port\n");
- return 0;
- } else if (port[dev] == 0x200 || (port[dev] & ~0x270)) {
- snd_printk(KERN_ERR "incorrect port specified\n");
- return 0;
- }
- if (dma8[dev] != SNDRV_AUTO_DMA &&
- dma8[dev] != 1 && dma8[dev] != 3) {
- snd_printk(KERN_ERR "dma8 must be 1 or 3\n");
- return 0;
- }
- if (dma16[dev] != SNDRV_AUTO_DMA &&
- dma16[dev] != 5 && dma16[dev] != 7) {
- snd_printk(KERN_ERR "dma16 must be 5 or 7\n");
- return 0;
- }
- if (mpu_port[dev] != SNDRV_AUTO_PORT &&
- (mpu_port[dev] & ~0x030) != 0x300) {
- snd_printk(KERN_ERR "incorrect mpu_port specified\n");
- return 0;
- }
- if (mpu_irq[dev] != SNDRV_AUTO_DMA &&
- mpu_irq[dev] != 2 && mpu_irq[dev] != 3 &&
- mpu_irq[dev] != 5 && mpu_irq[dev] != 7) {
- snd_printk(KERN_ERR "mpu_irq must be 2, 3, 5 or 7\n");
- return 0;
- }
- return 1;
-}
-
-static int __devinit snd_jazz16_probe(struct device *devptr, unsigned int dev)
-{
- struct snd_card *card;
- struct snd_card_jazz16 *jazz16;
- struct snd_sb *chip;
- struct snd_opl3 *opl3;
- static int possible_irqs[] = {2, 3, 5, 7, 9, 10, 15, -1};
- static int possible_dmas8[] = {1, 3, -1};
- static int possible_dmas16[] = {5, 7, -1};
- int err, xirq, xdma8, xdma16, xmpu_port, xmpu_irq;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_card_jazz16), &card);
- if (err < 0)
- return err;
-
- jazz16 = card->private_data;
-
- xirq = irq[dev];
- if (xirq == SNDRV_AUTO_IRQ) {
- xirq = snd_legacy_find_free_irq(possible_irqs);
- if (xirq < 0) {
- snd_printk(KERN_ERR "unable to find a free IRQ\n");
- err = -EBUSY;
- goto err_free;
- }
- }
- xdma8 = dma8[dev];
- if (xdma8 == SNDRV_AUTO_DMA) {
- xdma8 = snd_legacy_find_free_dma(possible_dmas8);
- if (xdma8 < 0) {
- snd_printk(KERN_ERR "unable to find a free DMA8\n");
- err = -EBUSY;
- goto err_free;
- }
- }
- xdma16 = dma16[dev];
- if (xdma16 == SNDRV_AUTO_DMA) {
- xdma16 = snd_legacy_find_free_dma(possible_dmas16);
- if (xdma16 < 0) {
- snd_printk(KERN_ERR "unable to find a free DMA16\n");
- err = -EBUSY;
- goto err_free;
- }
- }
-
- xmpu_port = mpu_port[dev];
- if (xmpu_port == SNDRV_AUTO_PORT)
- xmpu_port = 0;
- err = jazz16_detect_board(port[dev], xmpu_port);
- if (err < 0) {
- printk(KERN_ERR "Media Vision Jazz16 board not detected\n");
- goto err_free;
- }
- err = snd_sbdsp_create(card, port[dev], irq[dev],
- jazz16_interrupt,
- dma8[dev], dma16[dev],
- SB_HW_JAZZ16,
- &chip);
- if (err < 0)
- goto err_free;
-
- xmpu_irq = mpu_irq[dev];
- if (xmpu_irq == SNDRV_AUTO_IRQ || mpu_port[dev] == SNDRV_AUTO_PORT)
- xmpu_irq = 0;
- err = jazz16_configure_board(chip, xmpu_irq);
- if (err < 0) {
- printk(KERN_ERR "Media Vision Jazz16 configuration failed\n");
- goto err_free;
- }
-
- jazz16->chip = chip;
-
- strcpy(card->driver, "jazz16");
- strcpy(card->shortname, "Media Vision Jazz16");
- sprintf(card->longname,
- "Media Vision Jazz16 at 0x%lx, irq %d, dma8 %d, dma16 %d",
- port[dev], xirq, xdma8, xdma16);
-
- err = snd_sb8dsp_pcm(chip, 0, NULL);
- if (err < 0)
- goto err_free;
- err = snd_sbmixer_new(chip);
- if (err < 0)
- goto err_free;
-
- err = snd_opl3_create(card, chip->port, chip->port + 2,
- OPL3_HW_AUTO, 1, &opl3);
- if (err < 0)
- snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n",
- chip->port, chip->port + 2);
- else {
- err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
- if (err < 0)
- goto err_free;
- }
- if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
- if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
- mpu_irq[dev] = -1;
-
- if (snd_mpu401_uart_new(card, 0,
- MPU401_HW_MPU401,
- mpu_port[dev], 0,
- mpu_irq[dev],
- NULL) < 0)
- snd_printk(KERN_ERR "no MPU-401 device at 0x%lx\n",
- mpu_port[dev]);
- }
-
- snd_card_set_dev(card, devptr);
-
- err = snd_card_register(card);
- if (err < 0)
- goto err_free;
-
- dev_set_drvdata(devptr, card);
- return 0;
-
-err_free:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit snd_jazz16_remove(struct device *devptr, unsigned int dev)
-{
- struct snd_card *card = dev_get_drvdata(devptr);
-
- dev_set_drvdata(devptr, NULL);
- snd_card_free(card);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int snd_jazz16_suspend(struct device *pdev, unsigned int n,
- pm_message_t state)
-{
- struct snd_card *card = dev_get_drvdata(pdev);
- struct snd_card_jazz16 *acard = card->private_data;
- struct snd_sb *chip = acard->chip;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(chip->pcm);
- snd_sbmixer_suspend(chip);
- return 0;
-}
-
-static int snd_jazz16_resume(struct device *pdev, unsigned int n)
-{
- struct snd_card *card = dev_get_drvdata(pdev);
- struct snd_card_jazz16 *acard = card->private_data;
- struct snd_sb *chip = acard->chip;
-
- snd_sbdsp_reset(chip);
- snd_sbmixer_resume(chip);
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif
-
-static struct isa_driver snd_jazz16_driver = {
- .match = snd_jazz16_match,
- .probe = snd_jazz16_probe,
- .remove = __devexit_p(snd_jazz16_remove),
-#ifdef CONFIG_PM
- .suspend = snd_jazz16_suspend,
- .resume = snd_jazz16_resume,
-#endif
- .driver = {
- .name = "jazz16"
- },
-};
-
-static int __init alsa_card_jazz16_init(void)
-{
- return isa_register_driver(&snd_jazz16_driver, SNDRV_CARDS);
-}
-
-static void __exit alsa_card_jazz16_exit(void)
-{
- isa_unregister_driver(&snd_jazz16_driver);
-}
-
-module_init(alsa_card_jazz16_init)
-module_exit(alsa_card_jazz16_exit)
diff --git a/ANDROID_3.4.5/sound/isa/sb/sb16.c b/ANDROID_3.4.5/sound/isa/sb/sb16.c
deleted file mode 100644
index 39b8eca1..00000000
--- a/ANDROID_3.4.5/sound/isa/sb/sb16.c
+++ /dev/null
@@ -1,699 +0,0 @@
-/*
- * Driver for SoundBlaster 16/AWE32/AWE64 soundcards
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/dma.h>
-#include <linux/init.h>
-#include <linux/pnp.h>
-#include <linux/err.h>
-#include <linux/isa.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/sb.h>
-#include <sound/sb16_csp.h>
-#include <sound/mpu401.h>
-#include <sound/opl3.h>
-#include <sound/emu8000.h>
-#include <sound/seq_device.h>
-#define SNDRV_LEGACY_FIND_FREE_IRQ
-#define SNDRV_LEGACY_FIND_FREE_DMA
-#include <sound/initval.h>
-
-#ifdef SNDRV_SBAWE
-#define PFX "sbawe: "
-#else
-#define PFX "sb16: "
-#endif
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_LICENSE("GPL");
-#ifndef SNDRV_SBAWE
-MODULE_DESCRIPTION("Sound Blaster 16");
-MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB 16},"
- "{Creative Labs,SB Vibra16S},"
- "{Creative Labs,SB Vibra16C},"
- "{Creative Labs,SB Vibra16CL},"
- "{Creative Labs,SB Vibra16X}}");
-#else
-MODULE_DESCRIPTION("Sound Blaster AWE");
-MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB AWE 32},"
- "{Creative Labs,SB AWE 64},"
- "{Creative Labs,SB AWE 64 Gold}}");
-#endif
-
-#if 0
-#define SNDRV_DEBUG_IRQ
-#endif
-
-#if defined(SNDRV_SBAWE) && (defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)))
-#define SNDRV_SBAWE_EMU8000
-#endif
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
-#ifdef CONFIG_PNP
-static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
-#endif
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260,0x280 */
-static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x330,0x300 */
-static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-#ifdef SNDRV_SBAWE_EMU8000
-static long awe_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-#endif
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */
-static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3 */
-static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 5,6,7 */
-static int mic_agc[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
-#ifdef CONFIG_SND_SB16_CSP
-static int csp[SNDRV_CARDS];
-#endif
-#ifdef SNDRV_SBAWE_EMU8000
-static int seq_ports[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4};
-#endif
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for SoundBlaster 16 soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for SoundBlaster 16 soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable SoundBlaster 16 soundcard.");
-#ifdef CONFIG_PNP
-module_param_array(isapnp, bool, NULL, 0444);
-MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
-#endif
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for SB16 driver.");
-module_param_array(mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port # for SB16 driver.");
-module_param_array(fm_port, long, NULL, 0444);
-MODULE_PARM_DESC(fm_port, "FM port # for SB16 PnP driver.");
-#ifdef SNDRV_SBAWE_EMU8000
-module_param_array(awe_port, long, NULL, 0444);
-MODULE_PARM_DESC(awe_port, "AWE port # for SB16 PnP driver.");
-#endif
-module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for SB16 driver.");
-module_param_array(dma8, int, NULL, 0444);
-MODULE_PARM_DESC(dma8, "8-bit DMA # for SB16 driver.");
-module_param_array(dma16, int, NULL, 0444);
-MODULE_PARM_DESC(dma16, "16-bit DMA # for SB16 driver.");
-module_param_array(mic_agc, int, NULL, 0444);
-MODULE_PARM_DESC(mic_agc, "Mic Auto-Gain-Control switch.");
-#ifdef CONFIG_SND_SB16_CSP
-module_param_array(csp, int, NULL, 0444);
-MODULE_PARM_DESC(csp, "ASP/CSP chip support.");
-#endif
-#ifdef SNDRV_SBAWE_EMU8000
-module_param_array(seq_ports, int, NULL, 0444);
-MODULE_PARM_DESC(seq_ports, "Number of sequencer ports for WaveTable synth.");
-#endif
-
-#ifdef CONFIG_PNP
-static int isa_registered;
-static int pnp_registered;
-#endif
-
-struct snd_card_sb16 {
- struct resource *fm_res; /* used to block FM i/o region for legacy cards */
- struct snd_sb *chip;
-#ifdef CONFIG_PNP
- int dev_no;
- struct pnp_dev *dev;
-#ifdef SNDRV_SBAWE_EMU8000
- struct pnp_dev *devwt;
-#endif
-#endif
-};
-
-#ifdef CONFIG_PNP
-
-static struct pnp_card_device_id snd_sb16_pnpids[] = {
-#ifndef SNDRV_SBAWE
- /* Sound Blaster 16 PnP */
- { .id = "CTL0024", .devs = { { "CTL0031" } } },
- /* Sound Blaster 16 PnP */
- { .id = "CTL0025", .devs = { { "CTL0031" } } },
- /* Sound Blaster 16 PnP */
- { .id = "CTL0026", .devs = { { "CTL0031" } } },
- /* Sound Blaster 16 PnP */
- { .id = "CTL0027", .devs = { { "CTL0031" } } },
- /* Sound Blaster 16 PnP */
- { .id = "CTL0028", .devs = { { "CTL0031" } } },
- /* Sound Blaster 16 PnP */
- { .id = "CTL0029", .devs = { { "CTL0031" } } },
- /* Sound Blaster 16 PnP */
- { .id = "CTL002a", .devs = { { "CTL0031" } } },
- /* Sound Blaster 16 PnP */
- /* Note: This card has also a CTL0051:StereoEnhance device!!! */
- { .id = "CTL002b", .devs = { { "CTL0031" } } },
- /* Sound Blaster 16 PnP */
- { .id = "CTL002c", .devs = { { "CTL0031" } } },
- /* Sound Blaster Vibra16S */
- { .id = "CTL0051", .devs = { { "CTL0001" } } },
- /* Sound Blaster Vibra16C */
- { .id = "CTL0070", .devs = { { "CTL0001" } } },
- /* Sound Blaster Vibra16CL - added by ctm@ardi.com */
- { .id = "CTL0080", .devs = { { "CTL0041" } } },
- /* Sound Blaster 16 'value' PnP. It says model ct4130 on the pcb, */
- /* but ct4131 on a sticker on the board.. */
- { .id = "CTL0086", .devs = { { "CTL0041" } } },
- /* Sound Blaster Vibra16X */
- { .id = "CTL00f0", .devs = { { "CTL0043" } } },
- /* Sound Blaster 16 (Virtual PC 2004) */
- { .id = "tBA03b0", .devs = { {.id="PNPb003" } } },
-#else /* SNDRV_SBAWE defined */
- /* Sound Blaster AWE 32 PnP */
- { .id = "CTL0035", .devs = { { "CTL0031" }, { "CTL0021" } } },
- /* Sound Blaster AWE 32 PnP */
- { .id = "CTL0039", .devs = { { "CTL0031" }, { "CTL0021" } } },
- /* Sound Blaster AWE 32 PnP */
- { .id = "CTL0042", .devs = { { "CTL0031" }, { "CTL0021" } } },
- /* Sound Blaster AWE 32 PnP */
- { .id = "CTL0043", .devs = { { "CTL0031" }, { "CTL0021" } } },
- /* Sound Blaster AWE 32 PnP */
- /* Note: This card has also a CTL0051:StereoEnhance device!!! */
- { .id = "CTL0044", .devs = { { "CTL0031" }, { "CTL0021" } } },
- /* Sound Blaster AWE 32 PnP */
- /* Note: This card has also a CTL0051:StereoEnhance device!!! */
- { .id = "CTL0045", .devs = { { "CTL0031" }, { "CTL0021" } } },
- /* Sound Blaster AWE 32 PnP */
- { .id = "CTL0046", .devs = { { "CTL0031" }, { "CTL0021" } } },
- /* Sound Blaster AWE 32 PnP */
- { .id = "CTL0047", .devs = { { "CTL0031" }, { "CTL0021" } } },
- /* Sound Blaster AWE 32 PnP */
- { .id = "CTL0048", .devs = { { "CTL0031" }, { "CTL0021" } } },
- /* Sound Blaster AWE 32 PnP */
- { .id = "CTL0054", .devs = { { "CTL0031" }, { "CTL0021" } } },
- /* Sound Blaster AWE 32 PnP */
- { .id = "CTL009a", .devs = { { "CTL0041" }, { "CTL0021" } } },
- /* Sound Blaster AWE 32 PnP */
- { .id = "CTL009c", .devs = { { "CTL0041" }, { "CTL0021" } } },
- /* Sound Blaster 32 PnP */
- { .id = "CTL009f", .devs = { { "CTL0041" }, { "CTL0021" } } },
- /* Sound Blaster AWE 64 PnP */
- { .id = "CTL009d", .devs = { { "CTL0042" }, { "CTL0022" } } },
- /* Sound Blaster AWE 64 PnP Gold */
- { .id = "CTL009e", .devs = { { "CTL0044" }, { "CTL0023" } } },
- /* Sound Blaster AWE 64 PnP Gold */
- { .id = "CTL00b2", .devs = { { "CTL0044" }, { "CTL0023" } } },
- /* Sound Blaster AWE 64 PnP */
- { .id = "CTL00c1", .devs = { { "CTL0042" }, { "CTL0022" } } },
- /* Sound Blaster AWE 64 PnP */
- { .id = "CTL00c3", .devs = { { "CTL0045" }, { "CTL0022" } } },
- /* Sound Blaster AWE 64 PnP */
- { .id = "CTL00c5", .devs = { { "CTL0045" }, { "CTL0022" } } },
- /* Sound Blaster AWE 64 PnP */
- { .id = "CTL00c7", .devs = { { "CTL0045" }, { "CTL0022" } } },
- /* Sound Blaster AWE 64 PnP */
- { .id = "CTL00e4", .devs = { { "CTL0045" }, { "CTL0022" } } },
- /* Sound Blaster AWE 64 PnP */
- { .id = "CTL00e9", .devs = { { "CTL0045" }, { "CTL0022" } } },
- /* Sound Blaster 16 PnP (AWE) */
- { .id = "CTL00ed", .devs = { { "CTL0041" }, { "CTL0070" } } },
- /* Generic entries */
- { .id = "CTLXXXX" , .devs = { { "CTL0031" }, { "CTL0021" } } },
- { .id = "CTLXXXX" , .devs = { { "CTL0041" }, { "CTL0021" } } },
- { .id = "CTLXXXX" , .devs = { { "CTL0042" }, { "CTL0022" } } },
- { .id = "CTLXXXX" , .devs = { { "CTL0044" }, { "CTL0023" } } },
- { .id = "CTLXXXX" , .devs = { { "CTL0045" }, { "CTL0022" } } },
-#endif /* SNDRV_SBAWE */
- { .id = "", }
-};
-
-MODULE_DEVICE_TABLE(pnp_card, snd_sb16_pnpids);
-
-#endif /* CONFIG_PNP */
-
-#ifdef SNDRV_SBAWE_EMU8000
-#define DRIVER_NAME "snd-card-sbawe"
-#else
-#define DRIVER_NAME "snd-card-sb16"
-#endif
-
-#ifdef CONFIG_PNP
-
-static int __devinit snd_card_sb16_pnp(int dev, struct snd_card_sb16 *acard,
- struct pnp_card_link *card,
- const struct pnp_card_device_id *id)
-{
- struct pnp_dev *pdev;
- int err;
-
- acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
- if (acard->dev == NULL)
- return -ENODEV;
-
-#ifdef SNDRV_SBAWE_EMU8000
- acard->devwt = pnp_request_card_device(card, id->devs[1].id, acard->dev);
-#endif
- /* Audio initialization */
- pdev = acard->dev;
-
- err = pnp_activate_dev(pdev);
- if (err < 0) {
- snd_printk(KERN_ERR PFX "AUDIO pnp configure failure\n");
- return err;
- }
- port[dev] = pnp_port_start(pdev, 0);
- mpu_port[dev] = pnp_port_start(pdev, 1);
- fm_port[dev] = pnp_port_start(pdev, 2);
- dma8[dev] = pnp_dma(pdev, 0);
- dma16[dev] = pnp_dma(pdev, 1);
- irq[dev] = pnp_irq(pdev, 0);
- snd_printdd("pnp SB16: port=0x%lx, mpu port=0x%lx, fm port=0x%lx\n",
- port[dev], mpu_port[dev], fm_port[dev]);
- snd_printdd("pnp SB16: dma1=%i, dma2=%i, irq=%i\n",
- dma8[dev], dma16[dev], irq[dev]);
-#ifdef SNDRV_SBAWE_EMU8000
- /* WaveTable initialization */
- pdev = acard->devwt;
- if (pdev != NULL) {
- err = pnp_activate_dev(pdev);
- if (err < 0) {
- goto __wt_error;
- }
- awe_port[dev] = pnp_port_start(pdev, 0);
- snd_printdd("pnp SB16: wavetable port=0x%llx\n",
- (unsigned long long)pnp_port_start(pdev, 0));
- } else {
-__wt_error:
- if (pdev) {
- pnp_release_card_device(pdev);
- snd_printk(KERN_ERR PFX "WaveTable pnp configure failure\n");
- }
- acard->devwt = NULL;
- awe_port[dev] = -1;
- }
-#endif
- return 0;
-}
-
-#endif /* CONFIG_PNP */
-
-static void snd_sb16_free(struct snd_card *card)
-{
- struct snd_card_sb16 *acard = card->private_data;
-
- if (acard == NULL)
- return;
- release_and_free_resource(acard->fm_res);
-}
-
-#ifdef CONFIG_PNP
-#define is_isapnp_selected(dev) isapnp[dev]
-#else
-#define is_isapnp_selected(dev) 0
-#endif
-
-static int snd_sb16_card_new(int dev, struct snd_card **cardp)
-{
- struct snd_card *card;
- int err;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_card_sb16), &card);
- if (err < 0)
- return err;
- card->private_free = snd_sb16_free;
- *cardp = card;
- return 0;
-}
-
-static int __devinit snd_sb16_probe(struct snd_card *card, int dev)
-{
- int xirq, xdma8, xdma16;
- struct snd_sb *chip;
- struct snd_card_sb16 *acard = card->private_data;
- struct snd_opl3 *opl3;
- struct snd_hwdep *synth = NULL;
-#ifdef CONFIG_SND_SB16_CSP
- struct snd_hwdep *xcsp = NULL;
-#endif
- unsigned long flags;
- int err;
-
- xirq = irq[dev];
- xdma8 = dma8[dev];
- xdma16 = dma16[dev];
-
- if ((err = snd_sbdsp_create(card,
- port[dev],
- xirq,
- snd_sb16dsp_interrupt,
- xdma8,
- xdma16,
- SB_HW_AUTO,
- &chip)) < 0)
- return err;
-
- acard->chip = chip;
- if (chip->hardware != SB_HW_16) {
- snd_printk(KERN_ERR PFX "SB 16 chip was not detected at 0x%lx\n", port[dev]);
- return -ENODEV;
- }
- chip->mpu_port = mpu_port[dev];
- if (! is_isapnp_selected(dev) && (err = snd_sb16dsp_configure(chip)) < 0)
- return err;
-
- if ((err = snd_sb16dsp_pcm(chip, 0, &chip->pcm)) < 0)
- return err;
-
- strcpy(card->driver,
-#ifdef SNDRV_SBAWE_EMU8000
- awe_port[dev] > 0 ? "SB AWE" :
-#endif
- "SB16");
- strcpy(card->shortname, chip->name);
- sprintf(card->longname, "%s at 0x%lx, irq %i, dma ",
- chip->name,
- chip->port,
- xirq);
- if (xdma8 >= 0)
- sprintf(card->longname + strlen(card->longname), "%d", xdma8);
- if (xdma16 >= 0)
- sprintf(card->longname + strlen(card->longname), "%s%d",
- xdma8 >= 0 ? "&" : "", xdma16);
-
- if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) {
- if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SB,
- chip->mpu_port,
- MPU401_INFO_IRQ_HOOK, -1,
- &chip->rmidi)) < 0)
- return err;
- chip->rmidi_callback = snd_mpu401_uart_interrupt;
- }
-
-#ifdef SNDRV_SBAWE_EMU8000
- if (awe_port[dev] == SNDRV_AUTO_PORT)
- awe_port[dev] = 0; /* disable */
-#endif
-
- if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
- if (snd_opl3_create(card, fm_port[dev], fm_port[dev] + 2,
- OPL3_HW_OPL3,
- acard->fm_res != NULL || fm_port[dev] == port[dev],
- &opl3) < 0) {
- snd_printk(KERN_ERR PFX "no OPL device at 0x%lx-0x%lx\n",
- fm_port[dev], fm_port[dev] + 2);
- } else {
-#ifdef SNDRV_SBAWE_EMU8000
- int seqdev = awe_port[dev] > 0 ? 2 : 1;
-#else
- int seqdev = 1;
-#endif
- if ((err = snd_opl3_hwdep_new(opl3, 0, seqdev, &synth)) < 0)
- return err;
- }
- }
-
- if ((err = snd_sbmixer_new(chip)) < 0)
- return err;
-
-#ifdef CONFIG_SND_SB16_CSP
- /* CSP chip on SB16ASP/AWE32 */
- if ((chip->hardware == SB_HW_16) && csp[dev]) {
- snd_sb_csp_new(chip, synth != NULL ? 1 : 0, &xcsp);
- if (xcsp) {
- chip->csp = xcsp->private_data;
- chip->hardware = SB_HW_16CSP;
- } else {
- snd_printk(KERN_INFO PFX "warning - CSP chip not detected on soundcard #%i\n", dev + 1);
- }
- }
-#endif
-#ifdef SNDRV_SBAWE_EMU8000
- if (awe_port[dev] > 0) {
- if ((err = snd_emu8000_new(card, 1, awe_port[dev],
- seq_ports[dev], NULL)) < 0) {
- snd_printk(KERN_ERR PFX "fatal error - EMU-8000 synthesizer not detected at 0x%lx\n", awe_port[dev]);
-
- return err;
- }
- }
-#endif
-
- /* setup Mic AGC */
- spin_lock_irqsave(&chip->mixer_lock, flags);
- snd_sbmixer_write(chip, SB_DSP4_MIC_AGC,
- (snd_sbmixer_read(chip, SB_DSP4_MIC_AGC) & 0x01) |
- (mic_agc[dev] ? 0x00 : 0x01));
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
-
- if ((err = snd_card_register(card)) < 0)
- return err;
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int snd_sb16_suspend(struct snd_card *card, pm_message_t state)
-{
- struct snd_card_sb16 *acard = card->private_data;
- struct snd_sb *chip = acard->chip;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(chip->pcm);
- snd_sbmixer_suspend(chip);
- return 0;
-}
-
-static int snd_sb16_resume(struct snd_card *card)
-{
- struct snd_card_sb16 *acard = card->private_data;
- struct snd_sb *chip = acard->chip;
-
- snd_sbdsp_reset(chip);
- snd_sbmixer_resume(chip);
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif
-
-static int __devinit snd_sb16_isa_probe1(int dev, struct device *pdev)
-{
- struct snd_card_sb16 *acard;
- struct snd_card *card;
- int err;
-
- err = snd_sb16_card_new(dev, &card);
- if (err < 0)
- return err;
-
- acard = card->private_data;
- /* non-PnP FM port address is hardwired with base port address */
- fm_port[dev] = port[dev];
- /* block the 0x388 port to avoid PnP conflicts */
- acard->fm_res = request_region(0x388, 4, "SoundBlaster FM");
-#ifdef SNDRV_SBAWE_EMU8000
- /* non-PnP AWE port address is hardwired with base port address */
- awe_port[dev] = port[dev] + 0x400;
-#endif
-
- snd_card_set_dev(card, pdev);
- if ((err = snd_sb16_probe(card, dev)) < 0) {
- snd_card_free(card);
- return err;
- }
- dev_set_drvdata(pdev, card);
- return 0;
-}
-
-
-static int __devinit snd_sb16_isa_match(struct device *pdev, unsigned int dev)
-{
- return enable[dev] && !is_isapnp_selected(dev);
-}
-
-static int __devinit snd_sb16_isa_probe(struct device *pdev, unsigned int dev)
-{
- int err;
- static int possible_irqs[] = {5, 9, 10, 7, -1};
- static int possible_dmas8[] = {1, 3, 0, -1};
- static int possible_dmas16[] = {5, 6, 7, -1};
-
- if (irq[dev] == SNDRV_AUTO_IRQ) {
- if ((irq[dev] = snd_legacy_find_free_irq(possible_irqs)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
- return -EBUSY;
- }
- }
- if (dma8[dev] == SNDRV_AUTO_DMA) {
- if ((dma8[dev] = snd_legacy_find_free_dma(possible_dmas8)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free 8-bit DMA\n");
- return -EBUSY;
- }
- }
- if (dma16[dev] == SNDRV_AUTO_DMA) {
- if ((dma16[dev] = snd_legacy_find_free_dma(possible_dmas16)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free 16-bit DMA\n");
- return -EBUSY;
- }
- }
-
- if (port[dev] != SNDRV_AUTO_PORT)
- return snd_sb16_isa_probe1(dev, pdev);
- else {
- static int possible_ports[] = {0x220, 0x240, 0x260, 0x280};
- int i;
- for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
- port[dev] = possible_ports[i];
- err = snd_sb16_isa_probe1(dev, pdev);
- if (! err)
- return 0;
- }
- return err;
- }
-}
-
-static int __devexit snd_sb16_isa_remove(struct device *pdev, unsigned int dev)
-{
- snd_card_free(dev_get_drvdata(pdev));
- dev_set_drvdata(pdev, NULL);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int snd_sb16_isa_suspend(struct device *dev, unsigned int n,
- pm_message_t state)
-{
- return snd_sb16_suspend(dev_get_drvdata(dev), state);
-}
-
-static int snd_sb16_isa_resume(struct device *dev, unsigned int n)
-{
- return snd_sb16_resume(dev_get_drvdata(dev));
-}
-#endif
-
-#ifdef SNDRV_SBAWE
-#define DEV_NAME "sbawe"
-#else
-#define DEV_NAME "sb16"
-#endif
-
-static struct isa_driver snd_sb16_isa_driver = {
- .match = snd_sb16_isa_match,
- .probe = snd_sb16_isa_probe,
- .remove = __devexit_p(snd_sb16_isa_remove),
-#ifdef CONFIG_PM
- .suspend = snd_sb16_isa_suspend,
- .resume = snd_sb16_isa_resume,
-#endif
- .driver = {
- .name = DEV_NAME
- },
-};
-
-
-#ifdef CONFIG_PNP
-static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard,
- const struct pnp_card_device_id *pid)
-{
- static int dev;
- struct snd_card *card;
- int res;
-
- for ( ; dev < SNDRV_CARDS; dev++) {
- if (!enable[dev] || !isapnp[dev])
- continue;
- res = snd_sb16_card_new(dev, &card);
- if (res < 0)
- return res;
- snd_card_set_dev(card, &pcard->card->dev);
- if ((res = snd_card_sb16_pnp(dev, card->private_data, pcard, pid)) < 0 ||
- (res = snd_sb16_probe(card, dev)) < 0) {
- snd_card_free(card);
- return res;
- }
- pnp_set_card_drvdata(pcard, card);
- dev++;
- return 0;
- }
-
- return -ENODEV;
-}
-
-static void __devexit snd_sb16_pnp_remove(struct pnp_card_link * pcard)
-{
- snd_card_free(pnp_get_card_drvdata(pcard));
- pnp_set_card_drvdata(pcard, NULL);
-}
-
-#ifdef CONFIG_PM
-static int snd_sb16_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
-{
- return snd_sb16_suspend(pnp_get_card_drvdata(pcard), state);
-}
-static int snd_sb16_pnp_resume(struct pnp_card_link *pcard)
-{
- return snd_sb16_resume(pnp_get_card_drvdata(pcard));
-}
-#endif
-
-static struct pnp_card_driver sb16_pnpc_driver = {
- .flags = PNP_DRIVER_RES_DISABLE,
-#ifdef SNDRV_SBAWE
- .name = "sbawe",
-#else
- .name = "sb16",
-#endif
- .id_table = snd_sb16_pnpids,
- .probe = snd_sb16_pnp_detect,
- .remove = __devexit_p(snd_sb16_pnp_remove),
-#ifdef CONFIG_PM
- .suspend = snd_sb16_pnp_suspend,
- .resume = snd_sb16_pnp_resume,
-#endif
-};
-
-#endif /* CONFIG_PNP */
-
-static int __init alsa_card_sb16_init(void)
-{
- int err;
-
- err = isa_register_driver(&snd_sb16_isa_driver, SNDRV_CARDS);
-#ifdef CONFIG_PNP
- if (!err)
- isa_registered = 1;
-
- err = pnp_register_card_driver(&sb16_pnpc_driver);
- if (!err)
- pnp_registered = 1;
-
- if (isa_registered)
- err = 0;
-#endif
- return err;
-}
-
-static void __exit alsa_card_sb16_exit(void)
-{
-#ifdef CONFIG_PNP
- if (pnp_registered)
- pnp_unregister_card_driver(&sb16_pnpc_driver);
- if (isa_registered)
-#endif
- isa_unregister_driver(&snd_sb16_isa_driver);
-}
-
-module_init(alsa_card_sb16_init)
-module_exit(alsa_card_sb16_exit)
diff --git a/ANDROID_3.4.5/sound/isa/sb/sb16_csp.c b/ANDROID_3.4.5/sound/isa/sb/sb16_csp.c
deleted file mode 100644
index c1aa21ed..00000000
--- a/ANDROID_3.4.5/sound/isa/sb/sb16_csp.c
+++ /dev/null
@@ -1,1202 +0,0 @@
-/*
- * Copyright (c) 1999 by Uros Bizjak <uros@kss-loka.si>
- * Takashi Iwai <tiwai@suse.de>
- *
- * SB16ASP/AWE32 CSP control
- *
- * CSP microcode loader:
- * alsa-tools/sb16_csp/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/info.h>
-#include <sound/sb16_csp.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Uros Bizjak <uros@kss-loka.si>");
-MODULE_DESCRIPTION("ALSA driver for SB16 Creative Signal Processor");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE("sb16/mulaw_main.csp");
-MODULE_FIRMWARE("sb16/alaw_main.csp");
-MODULE_FIRMWARE("sb16/ima_adpcm_init.csp");
-MODULE_FIRMWARE("sb16/ima_adpcm_playback.csp");
-MODULE_FIRMWARE("sb16/ima_adpcm_capture.csp");
-
-#ifdef SNDRV_LITTLE_ENDIAN
-#define CSP_HDR_VALUE(a,b,c,d) ((a) | ((b)<<8) | ((c)<<16) | ((d)<<24))
-#else
-#define CSP_HDR_VALUE(a,b,c,d) ((d) | ((c)<<8) | ((b)<<16) | ((a)<<24))
-#endif
-
-#define RIFF_HEADER CSP_HDR_VALUE('R', 'I', 'F', 'F')
-#define CSP__HEADER CSP_HDR_VALUE('C', 'S', 'P', ' ')
-#define LIST_HEADER CSP_HDR_VALUE('L', 'I', 'S', 'T')
-#define FUNC_HEADER CSP_HDR_VALUE('f', 'u', 'n', 'c')
-#define CODE_HEADER CSP_HDR_VALUE('c', 'o', 'd', 'e')
-#define INIT_HEADER CSP_HDR_VALUE('i', 'n', 'i', 't')
-#define MAIN_HEADER CSP_HDR_VALUE('m', 'a', 'i', 'n')
-
-/*
- * RIFF data format
- */
-struct riff_header {
- __u32 name;
- __u32 len;
-};
-
-struct desc_header {
- struct riff_header info;
- __u16 func_nr;
- __u16 VOC_type;
- __u16 flags_play_rec;
- __u16 flags_16bit_8bit;
- __u16 flags_stereo_mono;
- __u16 flags_rates;
-};
-
-/*
- * prototypes
- */
-static void snd_sb_csp_free(struct snd_hwdep *hw);
-static int snd_sb_csp_open(struct snd_hwdep * hw, struct file *file);
-static int snd_sb_csp_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg);
-static int snd_sb_csp_release(struct snd_hwdep * hw, struct file *file);
-
-static int csp_detect(struct snd_sb *chip, int *version);
-static int set_codec_parameter(struct snd_sb *chip, unsigned char par, unsigned char val);
-static int set_register(struct snd_sb *chip, unsigned char reg, unsigned char val);
-static int read_register(struct snd_sb *chip, unsigned char reg);
-static int set_mode_register(struct snd_sb *chip, unsigned char mode);
-static int get_version(struct snd_sb *chip);
-
-static int snd_sb_csp_riff_load(struct snd_sb_csp * p,
- struct snd_sb_csp_microcode __user * code);
-static int snd_sb_csp_unload(struct snd_sb_csp * p);
-static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __user *buf, int size, int load_flags);
-static int snd_sb_csp_autoload(struct snd_sb_csp * p, int pcm_sfmt, int play_rec_mode);
-static int snd_sb_csp_check_version(struct snd_sb_csp * p);
-
-static int snd_sb_csp_use(struct snd_sb_csp * p);
-static int snd_sb_csp_unuse(struct snd_sb_csp * p);
-static int snd_sb_csp_start(struct snd_sb_csp * p, int sample_width, int channels);
-static int snd_sb_csp_stop(struct snd_sb_csp * p);
-static int snd_sb_csp_pause(struct snd_sb_csp * p);
-static int snd_sb_csp_restart(struct snd_sb_csp * p);
-
-static int snd_sb_qsound_build(struct snd_sb_csp * p);
-static void snd_sb_qsound_destroy(struct snd_sb_csp * p);
-static int snd_sb_csp_qsound_transfer(struct snd_sb_csp * p);
-
-static int init_proc_entry(struct snd_sb_csp * p, int device);
-static void info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer);
-
-/*
- * Detect CSP chip and create a new instance
- */
-int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep)
-{
- struct snd_sb_csp *p;
- int uninitialized_var(version);
- int err;
- struct snd_hwdep *hw;
-
- if (rhwdep)
- *rhwdep = NULL;
-
- if (csp_detect(chip, &version))
- return -ENODEV;
-
- if ((err = snd_hwdep_new(chip->card, "SB16-CSP", device, &hw)) < 0)
- return err;
-
- if ((p = kzalloc(sizeof(*p), GFP_KERNEL)) == NULL) {
- snd_device_free(chip->card, hw);
- return -ENOMEM;
- }
- p->chip = chip;
- p->version = version;
-
- /* CSP operators */
- p->ops.csp_use = snd_sb_csp_use;
- p->ops.csp_unuse = snd_sb_csp_unuse;
- p->ops.csp_autoload = snd_sb_csp_autoload;
- p->ops.csp_start = snd_sb_csp_start;
- p->ops.csp_stop = snd_sb_csp_stop;
- p->ops.csp_qsound_transfer = snd_sb_csp_qsound_transfer;
-
- mutex_init(&p->access_mutex);
- sprintf(hw->name, "CSP v%d.%d", (version >> 4), (version & 0x0f));
- hw->iface = SNDRV_HWDEP_IFACE_SB16CSP;
- hw->private_data = p;
- hw->private_free = snd_sb_csp_free;
-
- /* operators - only write/ioctl */
- hw->ops.open = snd_sb_csp_open;
- hw->ops.ioctl = snd_sb_csp_ioctl;
- hw->ops.release = snd_sb_csp_release;
-
- /* create a proc entry */
- init_proc_entry(p, device);
- if (rhwdep)
- *rhwdep = hw;
- return 0;
-}
-
-/*
- * free_private for hwdep instance
- */
-static void snd_sb_csp_free(struct snd_hwdep *hwdep)
-{
- int i;
- struct snd_sb_csp *p = hwdep->private_data;
- if (p) {
- if (p->running & SNDRV_SB_CSP_ST_RUNNING)
- snd_sb_csp_stop(p);
- for (i = 0; i < ARRAY_SIZE(p->csp_programs); ++i)
- release_firmware(p->csp_programs[i]);
- kfree(p);
- }
-}
-
-/* ------------------------------ */
-
-/*
- * open the device exclusively
- */
-static int snd_sb_csp_open(struct snd_hwdep * hw, struct file *file)
-{
- struct snd_sb_csp *p = hw->private_data;
- return (snd_sb_csp_use(p));
-}
-
-/*
- * ioctl for hwdep device:
- */
-static int snd_sb_csp_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct snd_sb_csp *p = hw->private_data;
- struct snd_sb_csp_info info;
- struct snd_sb_csp_start start_info;
- int err;
-
- if (snd_BUG_ON(!p))
- return -EINVAL;
-
- if (snd_sb_csp_check_version(p))
- return -ENODEV;
-
- switch (cmd) {
- /* get information */
- case SNDRV_SB_CSP_IOCTL_INFO:
- *info.codec_name = *p->codec_name;
- info.func_nr = p->func_nr;
- info.acc_format = p->acc_format;
- info.acc_channels = p->acc_channels;
- info.acc_width = p->acc_width;
- info.acc_rates = p->acc_rates;
- info.csp_mode = p->mode;
- info.run_channels = p->run_channels;
- info.run_width = p->run_width;
- info.version = p->version;
- info.state = p->running;
- if (copy_to_user((void __user *)arg, &info, sizeof(info)))
- err = -EFAULT;
- else
- err = 0;
- break;
-
- /* load CSP microcode */
- case SNDRV_SB_CSP_IOCTL_LOAD_CODE:
- err = (p->running & SNDRV_SB_CSP_ST_RUNNING ?
- -EBUSY : snd_sb_csp_riff_load(p, (struct snd_sb_csp_microcode __user *) arg));
- break;
- case SNDRV_SB_CSP_IOCTL_UNLOAD_CODE:
- err = (p->running & SNDRV_SB_CSP_ST_RUNNING ?
- -EBUSY : snd_sb_csp_unload(p));
- break;
-
- /* change CSP running state */
- case SNDRV_SB_CSP_IOCTL_START:
- if (copy_from_user(&start_info, (void __user *) arg, sizeof(start_info)))
- err = -EFAULT;
- else
- err = snd_sb_csp_start(p, start_info.sample_width, start_info.channels);
- break;
- case SNDRV_SB_CSP_IOCTL_STOP:
- err = snd_sb_csp_stop(p);
- break;
- case SNDRV_SB_CSP_IOCTL_PAUSE:
- err = snd_sb_csp_pause(p);
- break;
- case SNDRV_SB_CSP_IOCTL_RESTART:
- err = snd_sb_csp_restart(p);
- break;
- default:
- err = -ENOTTY;
- break;
- }
-
- return err;
-}
-
-/*
- * close the device
- */
-static int snd_sb_csp_release(struct snd_hwdep * hw, struct file *file)
-{
- struct snd_sb_csp *p = hw->private_data;
- return (snd_sb_csp_unuse(p));
-}
-
-/* ------------------------------ */
-
-/*
- * acquire device
- */
-static int snd_sb_csp_use(struct snd_sb_csp * p)
-{
- mutex_lock(&p->access_mutex);
- if (p->used) {
- mutex_unlock(&p->access_mutex);
- return -EAGAIN;
- }
- p->used++;
- mutex_unlock(&p->access_mutex);
-
- return 0;
-
-}
-
-/*
- * release device
- */
-static int snd_sb_csp_unuse(struct snd_sb_csp * p)
-{
- mutex_lock(&p->access_mutex);
- p->used--;
- mutex_unlock(&p->access_mutex);
-
- return 0;
-}
-
-/*
- * load microcode via ioctl:
- * code is user-space pointer
- */
-static int snd_sb_csp_riff_load(struct snd_sb_csp * p,
- struct snd_sb_csp_microcode __user * mcode)
-{
- struct snd_sb_csp_mc_header info;
-
- unsigned char __user *data_ptr;
- unsigned char __user *data_end;
- unsigned short func_nr = 0;
-
- struct riff_header file_h, item_h, code_h;
- __u32 item_type;
- struct desc_header funcdesc_h;
-
- unsigned long flags;
- int err;
-
- if (copy_from_user(&info, mcode, sizeof(info)))
- return -EFAULT;
- data_ptr = mcode->data;
-
- if (copy_from_user(&file_h, data_ptr, sizeof(file_h)))
- return -EFAULT;
- if ((file_h.name != RIFF_HEADER) ||
- (le32_to_cpu(file_h.len) >= SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE - sizeof(file_h))) {
- snd_printd("%s: Invalid RIFF header\n", __func__);
- return -EINVAL;
- }
- data_ptr += sizeof(file_h);
- data_end = data_ptr + le32_to_cpu(file_h.len);
-
- if (copy_from_user(&item_type, data_ptr, sizeof(item_type)))
- return -EFAULT;
- if (item_type != CSP__HEADER) {
- snd_printd("%s: Invalid RIFF file type\n", __func__);
- return -EINVAL;
- }
- data_ptr += sizeof (item_type);
-
- for (; data_ptr < data_end; data_ptr += le32_to_cpu(item_h.len)) {
- if (copy_from_user(&item_h, data_ptr, sizeof(item_h)))
- return -EFAULT;
- data_ptr += sizeof(item_h);
- if (item_h.name != LIST_HEADER)
- continue;
-
- if (copy_from_user(&item_type, data_ptr, sizeof(item_type)))
- return -EFAULT;
- switch (item_type) {
- case FUNC_HEADER:
- if (copy_from_user(&funcdesc_h, data_ptr + sizeof(item_type), sizeof(funcdesc_h)))
- return -EFAULT;
- func_nr = le16_to_cpu(funcdesc_h.func_nr);
- break;
- case CODE_HEADER:
- if (func_nr != info.func_req)
- break; /* not required function, try next */
- data_ptr += sizeof(item_type);
-
- /* destroy QSound mixer element */
- if (p->mode == SNDRV_SB_CSP_MODE_QSOUND) {
- snd_sb_qsound_destroy(p);
- }
- /* Clear all flags */
- p->running = 0;
- p->mode = 0;
-
- /* load microcode blocks */
- for (;;) {
- if (data_ptr >= data_end)
- return -EINVAL;
- if (copy_from_user(&code_h, data_ptr, sizeof(code_h)))
- return -EFAULT;
-
- /* init microcode blocks */
- if (code_h.name != INIT_HEADER)
- break;
- data_ptr += sizeof(code_h);
- err = snd_sb_csp_load_user(p, data_ptr, le32_to_cpu(code_h.len),
- SNDRV_SB_CSP_LOAD_INITBLOCK);
- if (err)
- return err;
- data_ptr += le32_to_cpu(code_h.len);
- }
- /* main microcode block */
- if (copy_from_user(&code_h, data_ptr, sizeof(code_h)))
- return -EFAULT;
-
- if (code_h.name != MAIN_HEADER) {
- snd_printd("%s: Missing 'main' microcode\n", __func__);
- return -EINVAL;
- }
- data_ptr += sizeof(code_h);
- err = snd_sb_csp_load_user(p, data_ptr,
- le32_to_cpu(code_h.len), 0);
- if (err)
- return err;
-
- /* fill in codec header */
- strlcpy(p->codec_name, info.codec_name, sizeof(p->codec_name));
- p->func_nr = func_nr;
- p->mode = le16_to_cpu(funcdesc_h.flags_play_rec);
- switch (le16_to_cpu(funcdesc_h.VOC_type)) {
- case 0x0001: /* QSound decoder */
- if (le16_to_cpu(funcdesc_h.flags_play_rec) == SNDRV_SB_CSP_MODE_DSP_WRITE) {
- if (snd_sb_qsound_build(p) == 0)
- /* set QSound flag and clear all other mode flags */
- p->mode = SNDRV_SB_CSP_MODE_QSOUND;
- }
- p->acc_format = 0;
- break;
- case 0x0006: /* A Law codec */
- p->acc_format = SNDRV_PCM_FMTBIT_A_LAW;
- break;
- case 0x0007: /* Mu Law codec */
- p->acc_format = SNDRV_PCM_FMTBIT_MU_LAW;
- break;
- case 0x0011: /* what Creative thinks is IMA ADPCM codec */
- case 0x0200: /* Creative ADPCM codec */
- p->acc_format = SNDRV_PCM_FMTBIT_IMA_ADPCM;
- break;
- case 201: /* Text 2 Speech decoder */
- /* TODO: Text2Speech handling routines */
- p->acc_format = 0;
- break;
- case 0x0202: /* Fast Speech 8 codec */
- case 0x0203: /* Fast Speech 10 codec */
- p->acc_format = SNDRV_PCM_FMTBIT_SPECIAL;
- break;
- default: /* other codecs are unsupported */
- p->acc_format = p->acc_width = p->acc_rates = 0;
- p->mode = 0;
- snd_printd("%s: Unsupported CSP codec type: 0x%04x\n",
- __func__,
- le16_to_cpu(funcdesc_h.VOC_type));
- return -EINVAL;
- }
- p->acc_channels = le16_to_cpu(funcdesc_h.flags_stereo_mono);
- p->acc_width = le16_to_cpu(funcdesc_h.flags_16bit_8bit);
- p->acc_rates = le16_to_cpu(funcdesc_h.flags_rates);
-
- /* Decouple CSP from IRQ and DMAREQ lines */
- spin_lock_irqsave(&p->chip->reg_lock, flags);
- set_mode_register(p->chip, 0xfc);
- set_mode_register(p->chip, 0x00);
- spin_unlock_irqrestore(&p->chip->reg_lock, flags);
-
- /* finished loading successfully */
- p->running = SNDRV_SB_CSP_ST_LOADED; /* set LOADED flag */
- return 0;
- }
- }
- snd_printd("%s: Function #%d not found\n", __func__, info.func_req);
- return -EINVAL;
-}
-
-/*
- * unload CSP microcode
- */
-static int snd_sb_csp_unload(struct snd_sb_csp * p)
-{
- if (p->running & SNDRV_SB_CSP_ST_RUNNING)
- return -EBUSY;
- if (!(p->running & SNDRV_SB_CSP_ST_LOADED))
- return -ENXIO;
-
- /* clear supported formats */
- p->acc_format = 0;
- p->acc_channels = p->acc_width = p->acc_rates = 0;
- /* destroy QSound mixer element */
- if (p->mode == SNDRV_SB_CSP_MODE_QSOUND) {
- snd_sb_qsound_destroy(p);
- }
- /* clear all flags */
- p->running = 0;
- p->mode = 0;
- return 0;
-}
-
-/*
- * send command sequence to DSP
- */
-static inline int command_seq(struct snd_sb *chip, const unsigned char *seq, int size)
-{
- int i;
- for (i = 0; i < size; i++) {
- if (!snd_sbdsp_command(chip, seq[i]))
- return -EIO;
- }
- return 0;
-}
-
-/*
- * set CSP codec parameter
- */
-static int set_codec_parameter(struct snd_sb *chip, unsigned char par, unsigned char val)
-{
- unsigned char dsp_cmd[3];
-
- dsp_cmd[0] = 0x05; /* CSP set codec parameter */
- dsp_cmd[1] = val; /* Parameter value */
- dsp_cmd[2] = par; /* Parameter */
- command_seq(chip, dsp_cmd, 3);
- snd_sbdsp_command(chip, 0x03); /* DSP read? */
- if (snd_sbdsp_get_byte(chip) != par)
- return -EIO;
- return 0;
-}
-
-/*
- * set CSP register
- */
-static int set_register(struct snd_sb *chip, unsigned char reg, unsigned char val)
-{
- unsigned char dsp_cmd[3];
-
- dsp_cmd[0] = 0x0e; /* CSP set register */
- dsp_cmd[1] = reg; /* CSP Register */
- dsp_cmd[2] = val; /* value */
- return command_seq(chip, dsp_cmd, 3);
-}
-
-/*
- * read CSP register
- * return < 0 -> error
- */
-static int read_register(struct snd_sb *chip, unsigned char reg)
-{
- unsigned char dsp_cmd[2];
-
- dsp_cmd[0] = 0x0f; /* CSP read register */
- dsp_cmd[1] = reg; /* CSP Register */
- command_seq(chip, dsp_cmd, 2);
- return snd_sbdsp_get_byte(chip); /* Read DSP value */
-}
-
-/*
- * set CSP mode register
- */
-static int set_mode_register(struct snd_sb *chip, unsigned char mode)
-{
- unsigned char dsp_cmd[2];
-
- dsp_cmd[0] = 0x04; /* CSP set mode register */
- dsp_cmd[1] = mode; /* mode */
- return command_seq(chip, dsp_cmd, 2);
-}
-
-/*
- * Detect CSP
- * return 0 if CSP exists.
- */
-static int csp_detect(struct snd_sb *chip, int *version)
-{
- unsigned char csp_test1, csp_test2;
- unsigned long flags;
- int result = -ENODEV;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
-
- set_codec_parameter(chip, 0x00, 0x00);
- set_mode_register(chip, 0xfc); /* 0xfc = ?? */
-
- csp_test1 = read_register(chip, 0x83);
- set_register(chip, 0x83, ~csp_test1);
- csp_test2 = read_register(chip, 0x83);
- if (csp_test2 != (csp_test1 ^ 0xff))
- goto __fail;
-
- set_register(chip, 0x83, csp_test1);
- csp_test2 = read_register(chip, 0x83);
- if (csp_test2 != csp_test1)
- goto __fail;
-
- set_mode_register(chip, 0x00); /* 0x00 = ? */
-
- *version = get_version(chip);
- snd_sbdsp_reset(chip); /* reset DSP after getversion! */
- if (*version >= 0x10 && *version <= 0x1f)
- result = 0; /* valid version id */
-
- __fail:
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return result;
-}
-
-/*
- * get CSP version number
- */
-static int get_version(struct snd_sb *chip)
-{
- unsigned char dsp_cmd[2];
-
- dsp_cmd[0] = 0x08; /* SB_DSP_!something! */
- dsp_cmd[1] = 0x03; /* get chip version id? */
- command_seq(chip, dsp_cmd, 2);
-
- return (snd_sbdsp_get_byte(chip));
-}
-
-/*
- * check if the CSP version is valid
- */
-static int snd_sb_csp_check_version(struct snd_sb_csp * p)
-{
- if (p->version < 0x10 || p->version > 0x1f) {
- snd_printd("%s: Invalid CSP version: 0x%x\n", __func__, p->version);
- return 1;
- }
- return 0;
-}
-
-/*
- * download microcode to CSP (microcode should have one "main" block).
- */
-static int snd_sb_csp_load(struct snd_sb_csp * p, const unsigned char *buf, int size, int load_flags)
-{
- int status, i;
- int err;
- int result = -EIO;
- unsigned long flags;
-
- spin_lock_irqsave(&p->chip->reg_lock, flags);
- snd_sbdsp_command(p->chip, 0x01); /* CSP download command */
- if (snd_sbdsp_get_byte(p->chip)) {
- snd_printd("%s: Download command failed\n", __func__);
- goto __fail;
- }
- /* Send CSP low byte (size - 1) */
- snd_sbdsp_command(p->chip, (unsigned char)(size - 1));
- /* Send high byte */
- snd_sbdsp_command(p->chip, (unsigned char)((size - 1) >> 8));
- /* send microcode sequence */
- /* load from kernel space */
- while (size--) {
- if (!snd_sbdsp_command(p->chip, *buf++))
- goto __fail;
- }
- if (snd_sbdsp_get_byte(p->chip))
- goto __fail;
-
- if (load_flags & SNDRV_SB_CSP_LOAD_INITBLOCK) {
- i = 0;
- /* some codecs (FastSpeech) take some time to initialize */
- while (1) {
- snd_sbdsp_command(p->chip, 0x03);
- status = snd_sbdsp_get_byte(p->chip);
- if (status == 0x55 || ++i >= 10)
- break;
- udelay (10);
- }
- if (status != 0x55) {
- snd_printd("%s: Microcode initialization failed\n", __func__);
- goto __fail;
- }
- } else {
- /*
- * Read mixer register SB_DSP4_DMASETUP after loading 'main' code.
- * Start CSP chip if no 16bit DMA channel is set - some kind
- * of autorun or perhaps a bugfix?
- */
- spin_lock(&p->chip->mixer_lock);
- status = snd_sbmixer_read(p->chip, SB_DSP4_DMASETUP);
- spin_unlock(&p->chip->mixer_lock);
- if (!(status & (SB_DMASETUP_DMA7 | SB_DMASETUP_DMA6 | SB_DMASETUP_DMA5))) {
- err = (set_codec_parameter(p->chip, 0xaa, 0x00) ||
- set_codec_parameter(p->chip, 0xff, 0x00));
- snd_sbdsp_reset(p->chip); /* really! */
- if (err)
- goto __fail;
- set_mode_register(p->chip, 0xc0); /* c0 = STOP */
- set_mode_register(p->chip, 0x70); /* 70 = RUN */
- }
- }
- result = 0;
-
- __fail:
- spin_unlock_irqrestore(&p->chip->reg_lock, flags);
- return result;
-}
-
-static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __user *buf, int size, int load_flags)
-{
- int err;
- unsigned char *kbuf;
-
- kbuf = memdup_user(buf, size);
- if (IS_ERR(kbuf))
- return PTR_ERR(kbuf);
-
- err = snd_sb_csp_load(p, kbuf, size, load_flags);
-
- kfree(kbuf);
- return err;
-}
-
-static int snd_sb_csp_firmware_load(struct snd_sb_csp *p, int index, int flags)
-{
- static const char *const names[] = {
- "sb16/mulaw_main.csp",
- "sb16/alaw_main.csp",
- "sb16/ima_adpcm_init.csp",
- "sb16/ima_adpcm_playback.csp",
- "sb16/ima_adpcm_capture.csp",
- };
- const struct firmware *program;
-
- BUILD_BUG_ON(ARRAY_SIZE(names) != CSP_PROGRAM_COUNT);
- program = p->csp_programs[index];
- if (!program) {
- int err = request_firmware(&program, names[index],
- p->chip->card->dev);
- if (err < 0)
- return err;
- p->csp_programs[index] = program;
- }
- return snd_sb_csp_load(p, program->data, program->size, flags);
-}
-
-/*
- * autoload hardware codec if necessary
- * return 0 if CSP is loaded and ready to run (p->running != 0)
- */
-static int snd_sb_csp_autoload(struct snd_sb_csp * p, int pcm_sfmt, int play_rec_mode)
-{
- unsigned long flags;
- int err = 0;
-
- /* if CSP is running or manually loaded then exit */
- if (p->running & (SNDRV_SB_CSP_ST_RUNNING | SNDRV_SB_CSP_ST_LOADED))
- return -EBUSY;
-
- /* autoload microcode only if requested hardware codec is not already loaded */
- if (((1 << pcm_sfmt) & p->acc_format) && (play_rec_mode & p->mode)) {
- p->running = SNDRV_SB_CSP_ST_AUTO;
- } else {
- switch (pcm_sfmt) {
- case SNDRV_PCM_FORMAT_MU_LAW:
- err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_MULAW, 0);
- p->acc_format = SNDRV_PCM_FMTBIT_MU_LAW;
- p->mode = SNDRV_SB_CSP_MODE_DSP_READ | SNDRV_SB_CSP_MODE_DSP_WRITE;
- break;
- case SNDRV_PCM_FORMAT_A_LAW:
- err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_ALAW, 0);
- p->acc_format = SNDRV_PCM_FMTBIT_A_LAW;
- p->mode = SNDRV_SB_CSP_MODE_DSP_READ | SNDRV_SB_CSP_MODE_DSP_WRITE;
- break;
- case SNDRV_PCM_FORMAT_IMA_ADPCM:
- err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_ADPCM_INIT,
- SNDRV_SB_CSP_LOAD_INITBLOCK);
- if (err)
- break;
- if (play_rec_mode == SNDRV_SB_CSP_MODE_DSP_WRITE) {
- err = snd_sb_csp_firmware_load
- (p, CSP_PROGRAM_ADPCM_PLAYBACK, 0);
- p->mode = SNDRV_SB_CSP_MODE_DSP_WRITE;
- } else {
- err = snd_sb_csp_firmware_load
- (p, CSP_PROGRAM_ADPCM_CAPTURE, 0);
- p->mode = SNDRV_SB_CSP_MODE_DSP_READ;
- }
- p->acc_format = SNDRV_PCM_FMTBIT_IMA_ADPCM;
- break;
- default:
- /* Decouple CSP from IRQ and DMAREQ lines */
- if (p->running & SNDRV_SB_CSP_ST_AUTO) {
- spin_lock_irqsave(&p->chip->reg_lock, flags);
- set_mode_register(p->chip, 0xfc);
- set_mode_register(p->chip, 0x00);
- spin_unlock_irqrestore(&p->chip->reg_lock, flags);
- p->running = 0; /* clear autoloaded flag */
- }
- return -EINVAL;
- }
- if (err) {
- p->acc_format = 0;
- p->acc_channels = p->acc_width = p->acc_rates = 0;
-
- p->running = 0; /* clear autoloaded flag */
- p->mode = 0;
- return (err);
- } else {
- p->running = SNDRV_SB_CSP_ST_AUTO; /* set autoloaded flag */
- p->acc_width = SNDRV_SB_CSP_SAMPLE_16BIT; /* only 16 bit data */
- p->acc_channels = SNDRV_SB_CSP_MONO | SNDRV_SB_CSP_STEREO;
- p->acc_rates = SNDRV_SB_CSP_RATE_ALL; /* HW codecs accept all rates */
- }
-
- }
- return (p->running & SNDRV_SB_CSP_ST_AUTO) ? 0 : -ENXIO;
-}
-
-/*
- * start CSP
- */
-static int snd_sb_csp_start(struct snd_sb_csp * p, int sample_width, int channels)
-{
- unsigned char s_type; /* sample type */
- unsigned char mixL, mixR;
- int result = -EIO;
- unsigned long flags;
-
- if (!(p->running & (SNDRV_SB_CSP_ST_LOADED | SNDRV_SB_CSP_ST_AUTO))) {
- snd_printd("%s: Microcode not loaded\n", __func__);
- return -ENXIO;
- }
- if (p->running & SNDRV_SB_CSP_ST_RUNNING) {
- snd_printd("%s: CSP already running\n", __func__);
- return -EBUSY;
- }
- if (!(sample_width & p->acc_width)) {
- snd_printd("%s: Unsupported PCM sample width\n", __func__);
- return -EINVAL;
- }
- if (!(channels & p->acc_channels)) {
- snd_printd("%s: Invalid number of channels\n", __func__);
- return -EINVAL;
- }
-
- /* Mute PCM volume */
- spin_lock_irqsave(&p->chip->mixer_lock, flags);
- mixL = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV);
- mixR = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV + 1);
- snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL & 0x7);
- snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR & 0x7);
-
- spin_lock(&p->chip->reg_lock);
- set_mode_register(p->chip, 0xc0); /* c0 = STOP */
- set_mode_register(p->chip, 0x70); /* 70 = RUN */
-
- s_type = 0x00;
- if (channels == SNDRV_SB_CSP_MONO)
- s_type = 0x11; /* 000n 000n (n = 1 if mono) */
- if (sample_width == SNDRV_SB_CSP_SAMPLE_8BIT)
- s_type |= 0x22; /* 00dX 00dX (d = 1 if 8 bit samples) */
-
- if (set_codec_parameter(p->chip, 0x81, s_type)) {
- snd_printd("%s: Set sample type command failed\n", __func__);
- goto __fail;
- }
- if (set_codec_parameter(p->chip, 0x80, 0x00)) {
- snd_printd("%s: Codec start command failed\n", __func__);
- goto __fail;
- }
- p->run_width = sample_width;
- p->run_channels = channels;
-
- p->running |= SNDRV_SB_CSP_ST_RUNNING;
-
- if (p->mode & SNDRV_SB_CSP_MODE_QSOUND) {
- set_codec_parameter(p->chip, 0xe0, 0x01);
- /* enable QSound decoder */
- set_codec_parameter(p->chip, 0x00, 0xff);
- set_codec_parameter(p->chip, 0x01, 0xff);
- p->running |= SNDRV_SB_CSP_ST_QSOUND;
- /* set QSound startup value */
- snd_sb_csp_qsound_transfer(p);
- }
- result = 0;
-
- __fail:
- spin_unlock(&p->chip->reg_lock);
-
- /* restore PCM volume */
- snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL);
- snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR);
- spin_unlock_irqrestore(&p->chip->mixer_lock, flags);
-
- return result;
-}
-
-/*
- * stop CSP
- */
-static int snd_sb_csp_stop(struct snd_sb_csp * p)
-{
- int result;
- unsigned char mixL, mixR;
- unsigned long flags;
-
- if (!(p->running & SNDRV_SB_CSP_ST_RUNNING))
- return 0;
-
- /* Mute PCM volume */
- spin_lock_irqsave(&p->chip->mixer_lock, flags);
- mixL = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV);
- mixR = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV + 1);
- snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL & 0x7);
- snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR & 0x7);
-
- spin_lock(&p->chip->reg_lock);
- if (p->running & SNDRV_SB_CSP_ST_QSOUND) {
- set_codec_parameter(p->chip, 0xe0, 0x01);
- /* disable QSound decoder */
- set_codec_parameter(p->chip, 0x00, 0x00);
- set_codec_parameter(p->chip, 0x01, 0x00);
-
- p->running &= ~SNDRV_SB_CSP_ST_QSOUND;
- }
- result = set_mode_register(p->chip, 0xc0); /* c0 = STOP */
- spin_unlock(&p->chip->reg_lock);
-
- /* restore PCM volume */
- snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL);
- snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR);
- spin_unlock_irqrestore(&p->chip->mixer_lock, flags);
-
- if (!(result))
- p->running &= ~(SNDRV_SB_CSP_ST_PAUSED | SNDRV_SB_CSP_ST_RUNNING);
- return result;
-}
-
-/*
- * pause CSP codec and hold DMA transfer
- */
-static int snd_sb_csp_pause(struct snd_sb_csp * p)
-{
- int result;
- unsigned long flags;
-
- if (!(p->running & SNDRV_SB_CSP_ST_RUNNING))
- return -EBUSY;
-
- spin_lock_irqsave(&p->chip->reg_lock, flags);
- result = set_codec_parameter(p->chip, 0x80, 0xff);
- spin_unlock_irqrestore(&p->chip->reg_lock, flags);
- if (!(result))
- p->running |= SNDRV_SB_CSP_ST_PAUSED;
-
- return result;
-}
-
-/*
- * restart CSP codec and resume DMA transfer
- */
-static int snd_sb_csp_restart(struct snd_sb_csp * p)
-{
- int result;
- unsigned long flags;
-
- if (!(p->running & SNDRV_SB_CSP_ST_PAUSED))
- return -EBUSY;
-
- spin_lock_irqsave(&p->chip->reg_lock, flags);
- result = set_codec_parameter(p->chip, 0x80, 0x00);
- spin_unlock_irqrestore(&p->chip->reg_lock, flags);
- if (!(result))
- p->running &= ~SNDRV_SB_CSP_ST_PAUSED;
-
- return result;
-}
-
-/* ------------------------------ */
-
-/*
- * QSound mixer control for PCM
- */
-
-#define snd_sb_qsound_switch_info snd_ctl_boolean_mono_info
-
-static int snd_sb_qsound_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = p->q_enabled ? 1 : 0;
- return 0;
-}
-
-static int snd_sb_qsound_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int change;
- unsigned char nval;
-
- nval = ucontrol->value.integer.value[0] & 0x01;
- spin_lock_irqsave(&p->q_lock, flags);
- change = p->q_enabled != nval;
- p->q_enabled = nval;
- spin_unlock_irqrestore(&p->q_lock, flags);
- return change;
-}
-
-static int snd_sb_qsound_space_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = SNDRV_SB_CSP_QSOUND_MAX_RIGHT;
- return 0;
-}
-
-static int snd_sb_qsound_space_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
-
- spin_lock_irqsave(&p->q_lock, flags);
- ucontrol->value.integer.value[0] = p->qpos_left;
- ucontrol->value.integer.value[1] = p->qpos_right;
- spin_unlock_irqrestore(&p->q_lock, flags);
- return 0;
-}
-
-static int snd_sb_qsound_space_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int change;
- unsigned char nval1, nval2;
-
- nval1 = ucontrol->value.integer.value[0];
- if (nval1 > SNDRV_SB_CSP_QSOUND_MAX_RIGHT)
- nval1 = SNDRV_SB_CSP_QSOUND_MAX_RIGHT;
- nval2 = ucontrol->value.integer.value[1];
- if (nval2 > SNDRV_SB_CSP_QSOUND_MAX_RIGHT)
- nval2 = SNDRV_SB_CSP_QSOUND_MAX_RIGHT;
- spin_lock_irqsave(&p->q_lock, flags);
- change = p->qpos_left != nval1 || p->qpos_right != nval2;
- p->qpos_left = nval1;
- p->qpos_right = nval2;
- p->qpos_changed = change;
- spin_unlock_irqrestore(&p->q_lock, flags);
- return change;
-}
-
-static struct snd_kcontrol_new snd_sb_qsound_switch = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "3D Control - Switch",
- .info = snd_sb_qsound_switch_info,
- .get = snd_sb_qsound_switch_get,
- .put = snd_sb_qsound_switch_put
-};
-
-static struct snd_kcontrol_new snd_sb_qsound_space = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "3D Control - Space",
- .info = snd_sb_qsound_space_info,
- .get = snd_sb_qsound_space_get,
- .put = snd_sb_qsound_space_put
-};
-
-static int snd_sb_qsound_build(struct snd_sb_csp * p)
-{
- struct snd_card *card;
- int err;
-
- if (snd_BUG_ON(!p))
- return -EINVAL;
-
- card = p->chip->card;
- p->qpos_left = p->qpos_right = SNDRV_SB_CSP_QSOUND_MAX_RIGHT / 2;
- p->qpos_changed = 0;
-
- spin_lock_init(&p->q_lock);
-
- if ((err = snd_ctl_add(card, p->qsound_switch = snd_ctl_new1(&snd_sb_qsound_switch, p))) < 0)
- goto __error;
- if ((err = snd_ctl_add(card, p->qsound_space = snd_ctl_new1(&snd_sb_qsound_space, p))) < 0)
- goto __error;
-
- return 0;
-
- __error:
- snd_sb_qsound_destroy(p);
- return err;
-}
-
-static void snd_sb_qsound_destroy(struct snd_sb_csp * p)
-{
- struct snd_card *card;
- unsigned long flags;
-
- if (snd_BUG_ON(!p))
- return;
-
- card = p->chip->card;
-
- down_write(&card->controls_rwsem);
- if (p->qsound_switch)
- snd_ctl_remove(card, p->qsound_switch);
- if (p->qsound_space)
- snd_ctl_remove(card, p->qsound_space);
- up_write(&card->controls_rwsem);
-
- /* cancel pending transfer of QSound parameters */
- spin_lock_irqsave (&p->q_lock, flags);
- p->qpos_changed = 0;
- spin_unlock_irqrestore (&p->q_lock, flags);
-}
-
-/*
- * Transfer qsound parameters to CSP,
- * function should be called from interrupt routine
- */
-static int snd_sb_csp_qsound_transfer(struct snd_sb_csp * p)
-{
- int err = -ENXIO;
-
- spin_lock(&p->q_lock);
- if (p->running & SNDRV_SB_CSP_ST_QSOUND) {
- set_codec_parameter(p->chip, 0xe0, 0x01);
- /* left channel */
- set_codec_parameter(p->chip, 0x00, p->qpos_left);
- set_codec_parameter(p->chip, 0x02, 0x00);
- /* right channel */
- set_codec_parameter(p->chip, 0x00, p->qpos_right);
- set_codec_parameter(p->chip, 0x03, 0x00);
- err = 0;
- }
- p->qpos_changed = 0;
- spin_unlock(&p->q_lock);
- return err;
-}
-
-/* ------------------------------ */
-
-/*
- * proc interface
- */
-static int init_proc_entry(struct snd_sb_csp * p, int device)
-{
- char name[16];
- struct snd_info_entry *entry;
- sprintf(name, "cspD%d", device);
- if (! snd_card_proc_new(p->chip->card, name, &entry))
- snd_info_set_text_ops(entry, p, info_read);
- return 0;
-}
-
-static void info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- struct snd_sb_csp *p = entry->private_data;
-
- snd_iprintf(buffer, "Creative Signal Processor [v%d.%d]\n", (p->version >> 4), (p->version & 0x0f));
- snd_iprintf(buffer, "State: %cx%c%c%c\n", ((p->running & SNDRV_SB_CSP_ST_QSOUND) ? 'Q' : '-'),
- ((p->running & SNDRV_SB_CSP_ST_PAUSED) ? 'P' : '-'),
- ((p->running & SNDRV_SB_CSP_ST_RUNNING) ? 'R' : '-'),
- ((p->running & SNDRV_SB_CSP_ST_LOADED) ? 'L' : '-'));
- if (p->running & SNDRV_SB_CSP_ST_LOADED) {
- snd_iprintf(buffer, "Codec: %s [func #%d]\n", p->codec_name, p->func_nr);
- snd_iprintf(buffer, "Sample rates: ");
- if (p->acc_rates == SNDRV_SB_CSP_RATE_ALL) {
- snd_iprintf(buffer, "All\n");
- } else {
- snd_iprintf(buffer, "%s%s%s%s\n",
- ((p->acc_rates & SNDRV_SB_CSP_RATE_8000) ? "8000Hz " : ""),
- ((p->acc_rates & SNDRV_SB_CSP_RATE_11025) ? "11025Hz " : ""),
- ((p->acc_rates & SNDRV_SB_CSP_RATE_22050) ? "22050Hz " : ""),
- ((p->acc_rates & SNDRV_SB_CSP_RATE_44100) ? "44100Hz" : ""));
- }
- if (p->mode == SNDRV_SB_CSP_MODE_QSOUND) {
- snd_iprintf(buffer, "QSound decoder %sabled\n",
- p->q_enabled ? "en" : "dis");
- } else {
- snd_iprintf(buffer, "PCM format ID: 0x%x (%s/%s) [%s/%s] [%s/%s]\n",
- p->acc_format,
- ((p->acc_width & SNDRV_SB_CSP_SAMPLE_16BIT) ? "16bit" : "-"),
- ((p->acc_width & SNDRV_SB_CSP_SAMPLE_8BIT) ? "8bit" : "-"),
- ((p->acc_channels & SNDRV_SB_CSP_MONO) ? "mono" : "-"),
- ((p->acc_channels & SNDRV_SB_CSP_STEREO) ? "stereo" : "-"),
- ((p->mode & SNDRV_SB_CSP_MODE_DSP_WRITE) ? "playback" : "-"),
- ((p->mode & SNDRV_SB_CSP_MODE_DSP_READ) ? "capture" : "-"));
- }
- }
- if (p->running & SNDRV_SB_CSP_ST_AUTO) {
- snd_iprintf(buffer, "Autoloaded Mu-Law, A-Law or Ima-ADPCM hardware codec\n");
- }
- if (p->running & SNDRV_SB_CSP_ST_RUNNING) {
- snd_iprintf(buffer, "Processing %dbit %s PCM samples\n",
- ((p->run_width & SNDRV_SB_CSP_SAMPLE_16BIT) ? 16 : 8),
- ((p->run_channels & SNDRV_SB_CSP_MONO) ? "mono" : "stereo"));
- }
- if (p->running & SNDRV_SB_CSP_ST_QSOUND) {
- snd_iprintf(buffer, "Qsound position: left = 0x%x, right = 0x%x\n",
- p->qpos_left, p->qpos_right);
- }
-}
-
-/* */
-
-EXPORT_SYMBOL(snd_sb_csp_new);
-
-/*
- * INIT part
- */
-
-static int __init alsa_sb_csp_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_sb_csp_exit(void)
-{
-}
-
-module_init(alsa_sb_csp_init)
-module_exit(alsa_sb_csp_exit)
diff --git a/ANDROID_3.4.5/sound/isa/sb/sb16_main.c b/ANDROID_3.4.5/sound/isa/sb/sb16_main.c
deleted file mode 100644
index 0bbcd471..00000000
--- a/ANDROID_3.4.5/sound/isa/sb/sb16_main.c
+++ /dev/null
@@ -1,925 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Routines for control of 16-bit SoundBlaster cards and clones
- * Note: This is very ugly hardware which uses one 8-bit DMA channel and
- * second 16-bit DMA channel. Unfortunately 8-bit DMA channel can't
- * transfer 16-bit samples and 16-bit DMA channels can't transfer
- * 8-bit samples. This make full duplex more complicated than
- * can be... People, don't buy these soundcards for full 16-bit
- * duplex!!!
- * Note: 16-bit wide is assigned to first direction which made request.
- * With full duplex - playback is preferred with abstract layer.
- *
- * Note: Some chip revisions have hardware bug. Changing capture
- * channel from full-duplex 8bit DMA to 16bit DMA will block
- * 16bit DMA transfers from DSP chip (capture) until 8bit transfer
- * to DSP chip (playback) starts. This bug can be avoided with
- * "16bit DMA Allocation" setting set to Playback or Capture.
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/sb.h>
-#include <sound/sb16_csp.h>
-#include <sound/mpu401.h>
-#include <sound/control.h>
-#include <sound/info.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Routines for control of 16-bit SoundBlaster cards and clones");
-MODULE_LICENSE("GPL");
-
-#ifdef CONFIG_SND_SB16_CSP
-static void snd_sb16_csp_playback_prepare(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
-{
- if (chip->hardware == SB_HW_16CSP) {
- struct snd_sb_csp *csp = chip->csp;
-
- if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
- /* manually loaded codec */
- if ((csp->mode & SNDRV_SB_CSP_MODE_DSP_WRITE) &&
- ((1U << runtime->format) == csp->acc_format)) {
- /* Supported runtime PCM format for playback */
- if (csp->ops.csp_use(csp) == 0) {
- /* If CSP was successfully acquired */
- goto __start_CSP;
- }
- } else if ((csp->mode & SNDRV_SB_CSP_MODE_QSOUND) && (csp->q_enabled)) {
- /* QSound decoder is loaded and enabled */
- if ((1 << runtime->format) & (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE)) {
- /* Only for simple PCM formats */
- if (csp->ops.csp_use(csp) == 0) {
- /* If CSP was successfully acquired */
- goto __start_CSP;
- }
- }
- }
- } else if (csp->ops.csp_use(csp) == 0) {
- /* Acquire CSP and try to autoload hardware codec */
- if (csp->ops.csp_autoload(csp, runtime->format, SNDRV_SB_CSP_MODE_DSP_WRITE)) {
- /* Unsupported format, release CSP */
- csp->ops.csp_unuse(csp);
- } else {
- __start_CSP:
- /* Try to start CSP */
- if (csp->ops.csp_start(csp, (chip->mode & SB_MODE_PLAYBACK_16) ?
- SNDRV_SB_CSP_SAMPLE_16BIT : SNDRV_SB_CSP_SAMPLE_8BIT,
- (runtime->channels > 1) ?
- SNDRV_SB_CSP_STEREO : SNDRV_SB_CSP_MONO)) {
- /* Failed, release CSP */
- csp->ops.csp_unuse(csp);
- } else {
- /* Success, CSP acquired and running */
- chip->open = SNDRV_SB_CSP_MODE_DSP_WRITE;
- }
- }
- }
- }
-}
-
-static void snd_sb16_csp_capture_prepare(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
-{
- if (chip->hardware == SB_HW_16CSP) {
- struct snd_sb_csp *csp = chip->csp;
-
- if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
- /* manually loaded codec */
- if ((csp->mode & SNDRV_SB_CSP_MODE_DSP_READ) &&
- ((1U << runtime->format) == csp->acc_format)) {
- /* Supported runtime PCM format for capture */
- if (csp->ops.csp_use(csp) == 0) {
- /* If CSP was successfully acquired */
- goto __start_CSP;
- }
- }
- } else if (csp->ops.csp_use(csp) == 0) {
- /* Acquire CSP and try to autoload hardware codec */
- if (csp->ops.csp_autoload(csp, runtime->format, SNDRV_SB_CSP_MODE_DSP_READ)) {
- /* Unsupported format, release CSP */
- csp->ops.csp_unuse(csp);
- } else {
- __start_CSP:
- /* Try to start CSP */
- if (csp->ops.csp_start(csp, (chip->mode & SB_MODE_CAPTURE_16) ?
- SNDRV_SB_CSP_SAMPLE_16BIT : SNDRV_SB_CSP_SAMPLE_8BIT,
- (runtime->channels > 1) ?
- SNDRV_SB_CSP_STEREO : SNDRV_SB_CSP_MONO)) {
- /* Failed, release CSP */
- csp->ops.csp_unuse(csp);
- } else {
- /* Success, CSP acquired and running */
- chip->open = SNDRV_SB_CSP_MODE_DSP_READ;
- }
- }
- }
- }
-}
-
-static void snd_sb16_csp_update(struct snd_sb *chip)
-{
- if (chip->hardware == SB_HW_16CSP) {
- struct snd_sb_csp *csp = chip->csp;
-
- if (csp->qpos_changed) {
- spin_lock(&chip->reg_lock);
- csp->ops.csp_qsound_transfer (csp);
- spin_unlock(&chip->reg_lock);
- }
- }
-}
-
-static void snd_sb16_csp_playback_open(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
-{
- /* CSP decoders (QSound excluded) support only 16bit transfers */
- if (chip->hardware == SB_HW_16CSP) {
- struct snd_sb_csp *csp = chip->csp;
-
- if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
- /* manually loaded codec */
- if (csp->mode & SNDRV_SB_CSP_MODE_DSP_WRITE) {
- runtime->hw.formats |= csp->acc_format;
- }
- } else {
- /* autoloaded codecs */
- runtime->hw.formats |= SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
- SNDRV_PCM_FMTBIT_IMA_ADPCM;
- }
- }
-}
-
-static void snd_sb16_csp_playback_close(struct snd_sb *chip)
-{
- if ((chip->hardware == SB_HW_16CSP) && (chip->open == SNDRV_SB_CSP_MODE_DSP_WRITE)) {
- struct snd_sb_csp *csp = chip->csp;
-
- if (csp->ops.csp_stop(csp) == 0) {
- csp->ops.csp_unuse(csp);
- chip->open = 0;
- }
- }
-}
-
-static void snd_sb16_csp_capture_open(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
-{
- /* CSP coders support only 16bit transfers */
- if (chip->hardware == SB_HW_16CSP) {
- struct snd_sb_csp *csp = chip->csp;
-
- if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
- /* manually loaded codec */
- if (csp->mode & SNDRV_SB_CSP_MODE_DSP_READ) {
- runtime->hw.formats |= csp->acc_format;
- }
- } else {
- /* autoloaded codecs */
- runtime->hw.formats |= SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
- SNDRV_PCM_FMTBIT_IMA_ADPCM;
- }
- }
-}
-
-static void snd_sb16_csp_capture_close(struct snd_sb *chip)
-{
- if ((chip->hardware == SB_HW_16CSP) && (chip->open == SNDRV_SB_CSP_MODE_DSP_READ)) {
- struct snd_sb_csp *csp = chip->csp;
-
- if (csp->ops.csp_stop(csp) == 0) {
- csp->ops.csp_unuse(csp);
- chip->open = 0;
- }
- }
-}
-#else
-#define snd_sb16_csp_playback_prepare(chip, runtime) /*nop*/
-#define snd_sb16_csp_capture_prepare(chip, runtime) /*nop*/
-#define snd_sb16_csp_update(chip) /*nop*/
-#define snd_sb16_csp_playback_open(chip, runtime) /*nop*/
-#define snd_sb16_csp_playback_close(chip) /*nop*/
-#define snd_sb16_csp_capture_open(chip, runtime) /*nop*/
-#define snd_sb16_csp_capture_close(chip) /*nop*/
-#endif
-
-
-static void snd_sb16_setup_rate(struct snd_sb *chip,
- unsigned short rate,
- int channel)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (chip->mode & (channel == SNDRV_PCM_STREAM_PLAYBACK ? SB_MODE_PLAYBACK_16 : SB_MODE_CAPTURE_16))
- snd_sb_ack_16bit(chip);
- else
- snd_sb_ack_8bit(chip);
- if (!(chip->mode & SB_RATE_LOCK)) {
- chip->locked_rate = rate;
- snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE_IN);
- snd_sbdsp_command(chip, rate >> 8);
- snd_sbdsp_command(chip, rate & 0xff);
- snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE_OUT);
- snd_sbdsp_command(chip, rate >> 8);
- snd_sbdsp_command(chip, rate & 0xff);
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-
-static int snd_sb16_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static int snd_sb16_hw_free(struct snd_pcm_substream *substream)
-{
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-static int snd_sb16_playback_prepare(struct snd_pcm_substream *substream)
-{
- unsigned long flags;
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned char format;
- unsigned int size, count, dma;
-
- snd_sb16_csp_playback_prepare(chip, runtime);
- if (snd_pcm_format_unsigned(runtime->format) > 0) {
- format = runtime->channels > 1 ? SB_DSP4_MODE_UNS_STEREO : SB_DSP4_MODE_UNS_MONO;
- } else {
- format = runtime->channels > 1 ? SB_DSP4_MODE_SIGN_STEREO : SB_DSP4_MODE_SIGN_MONO;
- }
-
- snd_sb16_setup_rate(chip, runtime->rate, SNDRV_PCM_STREAM_PLAYBACK);
- size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream);
- dma = (chip->mode & SB_MODE_PLAYBACK_8) ? chip->dma8 : chip->dma16;
- snd_dma_program(dma, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
-
- count = snd_pcm_lib_period_bytes(substream);
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (chip->mode & SB_MODE_PLAYBACK_16) {
- count >>= 1;
- count--;
- snd_sbdsp_command(chip, SB_DSP4_OUT16_AI);
- snd_sbdsp_command(chip, format);
- snd_sbdsp_command(chip, count & 0xff);
- snd_sbdsp_command(chip, count >> 8);
- snd_sbdsp_command(chip, SB_DSP_DMA16_OFF);
- } else {
- count--;
- snd_sbdsp_command(chip, SB_DSP4_OUT8_AI);
- snd_sbdsp_command(chip, format);
- snd_sbdsp_command(chip, count & 0xff);
- snd_sbdsp_command(chip, count >> 8);
- snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
-}
-
-static int snd_sb16_playback_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- int result = 0;
-
- spin_lock(&chip->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- chip->mode |= SB_RATE_LOCK_PLAYBACK;
- snd_sbdsp_command(chip, chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- snd_sbdsp_command(chip, chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_OFF : SB_DSP_DMA8_OFF);
- /* next two lines are needed for some types of DSP4 (SB AWE 32 - 4.13) */
- if (chip->mode & SB_RATE_LOCK_CAPTURE)
- snd_sbdsp_command(chip, chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
- chip->mode &= ~SB_RATE_LOCK_PLAYBACK;
- break;
- default:
- result = -EINVAL;
- }
- spin_unlock(&chip->reg_lock);
- return result;
-}
-
-static int snd_sb16_capture_prepare(struct snd_pcm_substream *substream)
-{
- unsigned long flags;
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned char format;
- unsigned int size, count, dma;
-
- snd_sb16_csp_capture_prepare(chip, runtime);
- if (snd_pcm_format_unsigned(runtime->format) > 0) {
- format = runtime->channels > 1 ? SB_DSP4_MODE_UNS_STEREO : SB_DSP4_MODE_UNS_MONO;
- } else {
- format = runtime->channels > 1 ? SB_DSP4_MODE_SIGN_STEREO : SB_DSP4_MODE_SIGN_MONO;
- }
- snd_sb16_setup_rate(chip, runtime->rate, SNDRV_PCM_STREAM_CAPTURE);
- size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream);
- dma = (chip->mode & SB_MODE_CAPTURE_8) ? chip->dma8 : chip->dma16;
- snd_dma_program(dma, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
-
- count = snd_pcm_lib_period_bytes(substream);
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (chip->mode & SB_MODE_CAPTURE_16) {
- count >>= 1;
- count--;
- snd_sbdsp_command(chip, SB_DSP4_IN16_AI);
- snd_sbdsp_command(chip, format);
- snd_sbdsp_command(chip, count & 0xff);
- snd_sbdsp_command(chip, count >> 8);
- snd_sbdsp_command(chip, SB_DSP_DMA16_OFF);
- } else {
- count--;
- snd_sbdsp_command(chip, SB_DSP4_IN8_AI);
- snd_sbdsp_command(chip, format);
- snd_sbdsp_command(chip, count & 0xff);
- snd_sbdsp_command(chip, count >> 8);
- snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
-}
-
-static int snd_sb16_capture_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- int result = 0;
-
- spin_lock(&chip->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- chip->mode |= SB_RATE_LOCK_CAPTURE;
- snd_sbdsp_command(chip, chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- snd_sbdsp_command(chip, chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_OFF : SB_DSP_DMA8_OFF);
- /* next two lines are needed for some types of DSP4 (SB AWE 32 - 4.13) */
- if (chip->mode & SB_RATE_LOCK_PLAYBACK)
- snd_sbdsp_command(chip, chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
- chip->mode &= ~SB_RATE_LOCK_CAPTURE;
- break;
- default:
- result = -EINVAL;
- }
- spin_unlock(&chip->reg_lock);
- return result;
-}
-
-irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id)
-{
- struct snd_sb *chip = dev_id;
- unsigned char status;
- int ok;
-
- spin_lock(&chip->mixer_lock);
- status = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS);
- spin_unlock(&chip->mixer_lock);
- if ((status & SB_IRQTYPE_MPUIN) && chip->rmidi_callback)
- chip->rmidi_callback(irq, chip->rmidi->private_data);
- if (status & SB_IRQTYPE_8BIT) {
- ok = 0;
- if (chip->mode & SB_MODE_PLAYBACK_8) {
- snd_pcm_period_elapsed(chip->playback_substream);
- snd_sb16_csp_update(chip);
- ok++;
- }
- if (chip->mode & SB_MODE_CAPTURE_8) {
- snd_pcm_period_elapsed(chip->capture_substream);
- ok++;
- }
- spin_lock(&chip->reg_lock);
- if (!ok)
- snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
- snd_sb_ack_8bit(chip);
- spin_unlock(&chip->reg_lock);
- }
- if (status & SB_IRQTYPE_16BIT) {
- ok = 0;
- if (chip->mode & SB_MODE_PLAYBACK_16) {
- snd_pcm_period_elapsed(chip->playback_substream);
- snd_sb16_csp_update(chip);
- ok++;
- }
- if (chip->mode & SB_MODE_CAPTURE_16) {
- snd_pcm_period_elapsed(chip->capture_substream);
- ok++;
- }
- spin_lock(&chip->reg_lock);
- if (!ok)
- snd_sbdsp_command(chip, SB_DSP_DMA16_OFF);
- snd_sb_ack_16bit(chip);
- spin_unlock(&chip->reg_lock);
- }
- return IRQ_HANDLED;
-}
-
-/*
-
- */
-
-static snd_pcm_uframes_t snd_sb16_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- unsigned int dma;
- size_t ptr;
-
- dma = (chip->mode & SB_MODE_PLAYBACK_8) ? chip->dma8 : chip->dma16;
- ptr = snd_dma_pointer(dma, chip->p_dma_size);
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-static snd_pcm_uframes_t snd_sb16_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- unsigned int dma;
- size_t ptr;
-
- dma = (chip->mode & SB_MODE_CAPTURE_8) ? chip->dma8 : chip->dma16;
- ptr = snd_dma_pointer(dma, chip->c_dma_size);
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-/*
-
- */
-
-static struct snd_pcm_hardware snd_sb16_playback =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = 0,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_44100,
- .rate_min = 4000,
- .rate_max = 44100,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_sb16_capture =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = 0,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_44100,
- .rate_min = 4000,
- .rate_max = 44100,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-/*
- * open/close
- */
-
-static int snd_sb16_playback_open(struct snd_pcm_substream *substream)
-{
- unsigned long flags;
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- spin_lock_irqsave(&chip->open_lock, flags);
- if (chip->mode & SB_MODE_PLAYBACK) {
- spin_unlock_irqrestore(&chip->open_lock, flags);
- return -EAGAIN;
- }
- runtime->hw = snd_sb16_playback;
-
- /* skip if 16 bit DMA was reserved for capture */
- if (chip->force_mode16 & SB_MODE_CAPTURE_16)
- goto __skip_16bit;
-
- if (chip->dma16 >= 0 && !(chip->mode & SB_MODE_CAPTURE_16)) {
- chip->mode |= SB_MODE_PLAYBACK_16;
- runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE;
- /* Vibra16X hack */
- if (chip->dma16 <= 3) {
- runtime->hw.buffer_bytes_max =
- runtime->hw.period_bytes_max = 64 * 1024;
- } else {
- snd_sb16_csp_playback_open(chip, runtime);
- }
- goto __open_ok;
- }
-
- __skip_16bit:
- if (chip->dma8 >= 0 && !(chip->mode & SB_MODE_CAPTURE_8)) {
- chip->mode |= SB_MODE_PLAYBACK_8;
- /* DSP v 4.xx can transfer 16bit data through 8bit DMA channel, SBHWPG 2-7 */
- if (chip->dma16 < 0) {
- runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE;
- chip->mode |= SB_MODE_PLAYBACK_16;
- } else {
- runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8;
- }
- runtime->hw.buffer_bytes_max =
- runtime->hw.period_bytes_max = 64 * 1024;
- goto __open_ok;
- }
- spin_unlock_irqrestore(&chip->open_lock, flags);
- return -EAGAIN;
-
- __open_ok:
- if (chip->hardware == SB_HW_ALS100)
- runtime->hw.rate_max = 48000;
- if (chip->hardware == SB_HW_CS5530) {
- runtime->hw.buffer_bytes_max = 32 * 1024;
- runtime->hw.periods_min = 2;
- runtime->hw.rate_min = 44100;
- }
- if (chip->mode & SB_RATE_LOCK)
- runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate;
- chip->playback_substream = substream;
- spin_unlock_irqrestore(&chip->open_lock, flags);
- return 0;
-}
-
-static int snd_sb16_playback_close(struct snd_pcm_substream *substream)
-{
- unsigned long flags;
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
-
- snd_sb16_csp_playback_close(chip);
- spin_lock_irqsave(&chip->open_lock, flags);
- chip->playback_substream = NULL;
- chip->mode &= ~SB_MODE_PLAYBACK;
- spin_unlock_irqrestore(&chip->open_lock, flags);
- return 0;
-}
-
-static int snd_sb16_capture_open(struct snd_pcm_substream *substream)
-{
- unsigned long flags;
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- spin_lock_irqsave(&chip->open_lock, flags);
- if (chip->mode & SB_MODE_CAPTURE) {
- spin_unlock_irqrestore(&chip->open_lock, flags);
- return -EAGAIN;
- }
- runtime->hw = snd_sb16_capture;
-
- /* skip if 16 bit DMA was reserved for playback */
- if (chip->force_mode16 & SB_MODE_PLAYBACK_16)
- goto __skip_16bit;
-
- if (chip->dma16 >= 0 && !(chip->mode & SB_MODE_PLAYBACK_16)) {
- chip->mode |= SB_MODE_CAPTURE_16;
- runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE;
- /* Vibra16X hack */
- if (chip->dma16 <= 3) {
- runtime->hw.buffer_bytes_max =
- runtime->hw.period_bytes_max = 64 * 1024;
- } else {
- snd_sb16_csp_capture_open(chip, runtime);
- }
- goto __open_ok;
- }
-
- __skip_16bit:
- if (chip->dma8 >= 0 && !(chip->mode & SB_MODE_PLAYBACK_8)) {
- chip->mode |= SB_MODE_CAPTURE_8;
- /* DSP v 4.xx can transfer 16bit data through 8bit DMA channel, SBHWPG 2-7 */
- if (chip->dma16 < 0) {
- runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE;
- chip->mode |= SB_MODE_CAPTURE_16;
- } else {
- runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8;
- }
- runtime->hw.buffer_bytes_max =
- runtime->hw.period_bytes_max = 64 * 1024;
- goto __open_ok;
- }
- spin_unlock_irqrestore(&chip->open_lock, flags);
- return -EAGAIN;
-
- __open_ok:
- if (chip->hardware == SB_HW_ALS100)
- runtime->hw.rate_max = 48000;
- if (chip->hardware == SB_HW_CS5530) {
- runtime->hw.buffer_bytes_max = 32 * 1024;
- runtime->hw.periods_min = 2;
- runtime->hw.rate_min = 44100;
- }
- if (chip->mode & SB_RATE_LOCK)
- runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate;
- chip->capture_substream = substream;
- spin_unlock_irqrestore(&chip->open_lock, flags);
- return 0;
-}
-
-static int snd_sb16_capture_close(struct snd_pcm_substream *substream)
-{
- unsigned long flags;
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
-
- snd_sb16_csp_capture_close(chip);
- spin_lock_irqsave(&chip->open_lock, flags);
- chip->capture_substream = NULL;
- chip->mode &= ~SB_MODE_CAPTURE;
- spin_unlock_irqrestore(&chip->open_lock, flags);
- return 0;
-}
-
-/*
- * DMA control interface
- */
-
-static int snd_sb16_set_dma_mode(struct snd_sb *chip, int what)
-{
- if (chip->dma8 < 0 || chip->dma16 < 0) {
- if (snd_BUG_ON(what))
- return -EINVAL;
- return 0;
- }
- if (what == 0) {
- chip->force_mode16 = 0;
- } else if (what == 1) {
- chip->force_mode16 = SB_MODE_PLAYBACK_16;
- } else if (what == 2) {
- chip->force_mode16 = SB_MODE_CAPTURE_16;
- } else {
- return -EINVAL;
- }
- return 0;
-}
-
-static int snd_sb16_get_dma_mode(struct snd_sb *chip)
-{
- if (chip->dma8 < 0 || chip->dma16 < 0)
- return 0;
- switch (chip->force_mode16) {
- case SB_MODE_PLAYBACK_16:
- return 1;
- case SB_MODE_CAPTURE_16:
- return 2;
- default:
- return 0;
- }
-}
-
-static int snd_sb16_dma_control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[3] = {
- "Auto", "Playback", "Capture"
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item > 2)
- uinfo->value.enumerated.item = 2;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_sb16_dma_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sb *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- ucontrol->value.enumerated.item[0] = snd_sb16_get_dma_mode(chip);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
-}
-
-static int snd_sb16_dma_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sb *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- unsigned char nval, oval;
- int change;
-
- if ((nval = ucontrol->value.enumerated.item[0]) > 2)
- return -EINVAL;
- spin_lock_irqsave(&chip->reg_lock, flags);
- oval = snd_sb16_get_dma_mode(chip);
- change = nval != oval;
- snd_sb16_set_dma_mode(chip, nval);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return change;
-}
-
-static struct snd_kcontrol_new snd_sb16_dma_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_CARD,
- .name = "16-bit DMA Allocation",
- .info = snd_sb16_dma_control_info,
- .get = snd_sb16_dma_control_get,
- .put = snd_sb16_dma_control_put
-};
-
-/*
- * Initialization part
- */
-
-int snd_sb16dsp_configure(struct snd_sb * chip)
-{
- unsigned long flags;
- unsigned char irqreg = 0, dmareg = 0, mpureg;
- unsigned char realirq, realdma, realmpureg;
- /* note: mpu register should be present only on SB16 Vibra soundcards */
-
- // printk(KERN_DEBUG "codec->irq=%i, codec->dma8=%i, codec->dma16=%i\n", chip->irq, chip->dma8, chip->dma16);
- spin_lock_irqsave(&chip->mixer_lock, flags);
- mpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP) & ~0x06;
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
- switch (chip->irq) {
- case 2:
- case 9:
- irqreg |= SB_IRQSETUP_IRQ9;
- break;
- case 5:
- irqreg |= SB_IRQSETUP_IRQ5;
- break;
- case 7:
- irqreg |= SB_IRQSETUP_IRQ7;
- break;
- case 10:
- irqreg |= SB_IRQSETUP_IRQ10;
- break;
- default:
- return -EINVAL;
- }
- if (chip->dma8 >= 0) {
- switch (chip->dma8) {
- case 0:
- dmareg |= SB_DMASETUP_DMA0;
- break;
- case 1:
- dmareg |= SB_DMASETUP_DMA1;
- break;
- case 3:
- dmareg |= SB_DMASETUP_DMA3;
- break;
- default:
- return -EINVAL;
- }
- }
- if (chip->dma16 >= 0 && chip->dma16 != chip->dma8) {
- switch (chip->dma16) {
- case 5:
- dmareg |= SB_DMASETUP_DMA5;
- break;
- case 6:
- dmareg |= SB_DMASETUP_DMA6;
- break;
- case 7:
- dmareg |= SB_DMASETUP_DMA7;
- break;
- default:
- return -EINVAL;
- }
- }
- switch (chip->mpu_port) {
- case 0x300:
- mpureg |= 0x04;
- break;
- case 0x330:
- mpureg |= 0x00;
- break;
- default:
- mpureg |= 0x02; /* disable MPU */
- }
- spin_lock_irqsave(&chip->mixer_lock, flags);
-
- snd_sbmixer_write(chip, SB_DSP4_IRQSETUP, irqreg);
- realirq = snd_sbmixer_read(chip, SB_DSP4_IRQSETUP);
-
- snd_sbmixer_write(chip, SB_DSP4_DMASETUP, dmareg);
- realdma = snd_sbmixer_read(chip, SB_DSP4_DMASETUP);
-
- snd_sbmixer_write(chip, SB_DSP4_MPUSETUP, mpureg);
- realmpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP);
-
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
- if ((~realirq) & irqreg || (~realdma) & dmareg) {
- snd_printk(KERN_ERR "SB16 [0x%lx]: unable to set DMA & IRQ (PnP device?)\n", chip->port);
- snd_printk(KERN_ERR "SB16 [0x%lx]: wanted: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, realirq, realdma, realmpureg);
- snd_printk(KERN_ERR "SB16 [0x%lx]: got: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, irqreg, dmareg, mpureg);
- return -ENODEV;
- }
- return 0;
-}
-
-static struct snd_pcm_ops snd_sb16_playback_ops = {
- .open = snd_sb16_playback_open,
- .close = snd_sb16_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_sb16_hw_params,
- .hw_free = snd_sb16_hw_free,
- .prepare = snd_sb16_playback_prepare,
- .trigger = snd_sb16_playback_trigger,
- .pointer = snd_sb16_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_sb16_capture_ops = {
- .open = snd_sb16_capture_open,
- .close = snd_sb16_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_sb16_hw_params,
- .hw_free = snd_sb16_hw_free,
- .prepare = snd_sb16_capture_prepare,
- .trigger = snd_sb16_capture_trigger,
- .pointer = snd_sb16_capture_pointer,
-};
-
-int snd_sb16dsp_pcm(struct snd_sb * chip, int device, struct snd_pcm ** rpcm)
-{
- struct snd_card *card = chip->card;
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
- if ((err = snd_pcm_new(card, "SB16 DSP", device, 1, 1, &pcm)) < 0)
- return err;
- sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff);
- pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
- pcm->private_data = chip;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb16_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb16_capture_ops);
-
- if (chip->dma16 >= 0 && chip->dma8 != chip->dma16)
- snd_ctl_add(card, snd_ctl_new1(&snd_sb16_dma_control, chip));
- else
- pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_isa_data(),
- 64*1024, 128*1024);
-
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-const struct snd_pcm_ops *snd_sb16dsp_get_pcm_ops(int direction)
-{
- return direction == SNDRV_PCM_STREAM_PLAYBACK ?
- &snd_sb16_playback_ops : &snd_sb16_capture_ops;
-}
-
-EXPORT_SYMBOL(snd_sb16dsp_pcm);
-EXPORT_SYMBOL(snd_sb16dsp_get_pcm_ops);
-EXPORT_SYMBOL(snd_sb16dsp_configure);
-EXPORT_SYMBOL(snd_sb16dsp_interrupt);
-
-/*
- * INIT part
- */
-
-static int __init alsa_sb16_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_sb16_exit(void)
-{
-}
-
-module_init(alsa_sb16_init)
-module_exit(alsa_sb16_exit)
diff --git a/ANDROID_3.4.5/sound/isa/sb/sb8.c b/ANDROID_3.4.5/sound/isa/sb/sb8.c
deleted file mode 100644
index ab5cebea..00000000
--- a/ANDROID_3.4.5/sound/isa/sb/sb8.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Driver for SoundBlaster 1.0/2.0/Pro soundcards and compatible
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/isa.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/sb.h>
-#include <sound/opl3.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Sound Blaster 1.0/2.0/Pro");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB 1.0/SB 2.0/SB Pro}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */
-static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3 */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Sound Blaster soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Sound Blaster soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Sound Blaster soundcard.");
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for SB8 driver.");
-module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for SB8 driver.");
-module_param_array(dma8, int, NULL, 0444);
-MODULE_PARM_DESC(dma8, "8-bit DMA # for SB8 driver.");
-
-struct snd_sb8 {
- struct resource *fm_res; /* used to block FM i/o region for legacy cards */
- struct snd_sb *chip;
-};
-
-static irqreturn_t snd_sb8_interrupt(int irq, void *dev_id)
-{
- struct snd_sb *chip = dev_id;
-
- if (chip->open & SB_OPEN_PCM) {
- return snd_sb8dsp_interrupt(chip);
- } else {
- return snd_sb8dsp_midi_interrupt(chip);
- }
-}
-
-static void snd_sb8_free(struct snd_card *card)
-{
- struct snd_sb8 *acard = card->private_data;
-
- if (acard == NULL)
- return;
- release_and_free_resource(acard->fm_res);
-}
-
-static int __devinit snd_sb8_match(struct device *pdev, unsigned int dev)
-{
- if (!enable[dev])
- return 0;
- if (irq[dev] == SNDRV_AUTO_IRQ) {
- dev_err(pdev, "please specify irq\n");
- return 0;
- }
- if (dma8[dev] == SNDRV_AUTO_DMA) {
- dev_err(pdev, "please specify dma8\n");
- return 0;
- }
- return 1;
-}
-
-static int __devinit snd_sb8_probe(struct device *pdev, unsigned int dev)
-{
- struct snd_sb *chip;
- struct snd_card *card;
- struct snd_sb8 *acard;
- struct snd_opl3 *opl3;
- int err;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_sb8), &card);
- if (err < 0)
- return err;
- acard = card->private_data;
- card->private_free = snd_sb8_free;
-
- /* block the 0x388 port to avoid PnP conflicts */
- acard->fm_res = request_region(0x388, 4, "SoundBlaster FM");
-
- if (port[dev] != SNDRV_AUTO_PORT) {
- if ((err = snd_sbdsp_create(card, port[dev], irq[dev],
- snd_sb8_interrupt,
- dma8[dev],
- -1,
- SB_HW_AUTO,
- &chip)) < 0)
- goto _err;
- } else {
- /* auto-probe legacy ports */
- static unsigned long possible_ports[] = {
- 0x220, 0x240, 0x260,
- };
- int i;
- for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
- err = snd_sbdsp_create(card, possible_ports[i],
- irq[dev],
- snd_sb8_interrupt,
- dma8[dev],
- -1,
- SB_HW_AUTO,
- &chip);
- if (err >= 0) {
- port[dev] = possible_ports[i];
- break;
- }
- }
- if (i >= ARRAY_SIZE(possible_ports)) {
- err = -EINVAL;
- goto _err;
- }
- }
- acard->chip = chip;
-
- if (chip->hardware >= SB_HW_16) {
- if (chip->hardware == SB_HW_ALS100)
- snd_printk(KERN_WARNING "ALS100 chip detected at 0x%lx, try snd-als100 module\n",
- port[dev]);
- else
- snd_printk(KERN_WARNING "SB 16 chip detected at 0x%lx, try snd-sb16 module\n",
- port[dev]);
- err = -ENODEV;
- goto _err;
- }
-
- if ((err = snd_sb8dsp_pcm(chip, 0, NULL)) < 0)
- goto _err;
-
- if ((err = snd_sbmixer_new(chip)) < 0)
- goto _err;
-
- if (chip->hardware == SB_HW_10 || chip->hardware == SB_HW_20) {
- if ((err = snd_opl3_create(card, chip->port + 8, 0,
- OPL3_HW_AUTO, 1,
- &opl3)) < 0) {
- snd_printk(KERN_WARNING "sb8: no OPL device at 0x%lx\n", chip->port + 8);
- }
- } else {
- if ((err = snd_opl3_create(card, chip->port, chip->port + 2,
- OPL3_HW_AUTO, 1,
- &opl3)) < 0) {
- snd_printk(KERN_WARNING "sb8: no OPL device at 0x%lx-0x%lx\n",
- chip->port, chip->port + 2);
- }
- }
- if (err >= 0) {
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
- goto _err;
- }
-
- if ((err = snd_sb8dsp_midi(chip, 0, NULL)) < 0)
- goto _err;
-
- strcpy(card->driver, chip->hardware == SB_HW_PRO ? "SB Pro" : "SB8");
- strcpy(card->shortname, chip->name);
- sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
- chip->name,
- chip->port,
- irq[dev], dma8[dev]);
-
- snd_card_set_dev(card, pdev);
-
- if ((err = snd_card_register(card)) < 0)
- goto _err;
-
- dev_set_drvdata(pdev, card);
- return 0;
-
- _err:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit snd_sb8_remove(struct device *pdev, unsigned int dev)
-{
- snd_card_free(dev_get_drvdata(pdev));
- dev_set_drvdata(pdev, NULL);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int snd_sb8_suspend(struct device *dev, unsigned int n,
- pm_message_t state)
-{
- struct snd_card *card = dev_get_drvdata(dev);
- struct snd_sb8 *acard = card->private_data;
- struct snd_sb *chip = acard->chip;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(chip->pcm);
- snd_sbmixer_suspend(chip);
- return 0;
-}
-
-static int snd_sb8_resume(struct device *dev, unsigned int n)
-{
- struct snd_card *card = dev_get_drvdata(dev);
- struct snd_sb8 *acard = card->private_data;
- struct snd_sb *chip = acard->chip;
-
- snd_sbdsp_reset(chip);
- snd_sbmixer_resume(chip);
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif
-
-#define DEV_NAME "sb8"
-
-static struct isa_driver snd_sb8_driver = {
- .match = snd_sb8_match,
- .probe = snd_sb8_probe,
- .remove = __devexit_p(snd_sb8_remove),
-#ifdef CONFIG_PM
- .suspend = snd_sb8_suspend,
- .resume = snd_sb8_resume,
-#endif
- .driver = {
- .name = DEV_NAME
- },
-};
-
-static int __init alsa_card_sb8_init(void)
-{
- return isa_register_driver(&snd_sb8_driver, SNDRV_CARDS);
-}
-
-static void __exit alsa_card_sb8_exit(void)
-{
- isa_unregister_driver(&snd_sb8_driver);
-}
-
-module_init(alsa_card_sb8_init)
-module_exit(alsa_card_sb8_exit)
diff --git a/ANDROID_3.4.5/sound/isa/sb/sb8_main.c b/ANDROID_3.4.5/sound/isa/sb/sb8_main.c
deleted file mode 100644
index 24d4121a..00000000
--- a/ANDROID_3.4.5/sound/isa/sb/sb8_main.c
+++ /dev/null
@@ -1,646 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Uros Bizjak <uros@kss-loka.si>
- *
- * Routines for control of 8-bit SoundBlaster cards and clones
- * Please note: I don't have access to old SB8 soundcards.
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * --
- *
- * Thu Apr 29 20:36:17 BST 1999 George David Morrison <gdm@gedamo.demon.co.uk>
- * DSP can't respond to commands whilst in "high speed" mode. Caused
- * glitching during playback. Fixed.
- *
- * Wed Jul 12 22:02:55 CEST 2000 Uros Bizjak <uros@kss-loka.si>
- * Cleaned up and rewrote lowlevel routines.
- */
-
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/sb.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Uros Bizjak <uros@kss-loka.si>");
-MODULE_DESCRIPTION("Routines for control of 8-bit SoundBlaster cards and clones");
-MODULE_LICENSE("GPL");
-
-#define SB8_CLOCK 1000000
-#define SB8_DEN(v) ((SB8_CLOCK + (v) / 2) / (v))
-#define SB8_RATE(v) (SB8_CLOCK / SB8_DEN(v))
-
-static struct snd_ratnum clock = {
- .num = SB8_CLOCK,
- .den_min = 1,
- .den_max = 256,
- .den_step = 1,
-};
-
-static struct snd_pcm_hw_constraint_ratnums hw_constraints_clock = {
- .nrats = 1,
- .rats = &clock,
-};
-
-static struct snd_ratnum stereo_clocks[] = {
- {
- .num = SB8_CLOCK,
- .den_min = SB8_DEN(22050),
- .den_max = SB8_DEN(22050),
- .den_step = 1,
- },
- {
- .num = SB8_CLOCK,
- .den_min = SB8_DEN(11025),
- .den_max = SB8_DEN(11025),
- .den_step = 1,
- }
-};
-
-static int snd_sb8_hw_constraint_rate_channels(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- if (c->min > 1) {
- unsigned int num = 0, den = 0;
- int err = snd_interval_ratnum(hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE),
- 2, stereo_clocks, &num, &den);
- if (err >= 0 && den) {
- params->rate_num = num;
- params->rate_den = den;
- }
- return err;
- }
- return 0;
-}
-
-static int snd_sb8_hw_constraint_channels_rate(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
- if (r->min > SB8_RATE(22050) || r->max <= SB8_RATE(11025)) {
- struct snd_interval t = { .min = 1, .max = 1 };
- return snd_interval_refine(hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS), &t);
- }
- return 0;
-}
-
-static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream)
-{
- unsigned long flags;
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int mixreg, rate, size, count;
- unsigned char format;
- unsigned char stereo = runtime->channels > 1;
- int dma;
-
- rate = runtime->rate;
- switch (chip->hardware) {
- case SB_HW_JAZZ16:
- if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) {
- if (chip->mode & SB_MODE_CAPTURE_16)
- return -EBUSY;
- else
- chip->mode |= SB_MODE_PLAYBACK_16;
- }
- chip->playback_format = SB_DSP_LO_OUTPUT_AUTO;
- break;
- case SB_HW_PRO:
- if (runtime->channels > 1) {
- if (snd_BUG_ON(rate != SB8_RATE(11025) &&
- rate != SB8_RATE(22050)))
- return -EINVAL;
- chip->playback_format = SB_DSP_HI_OUTPUT_AUTO;
- break;
- }
- /* fallthru */
- case SB_HW_201:
- if (rate > 23000) {
- chip->playback_format = SB_DSP_HI_OUTPUT_AUTO;
- break;
- }
- /* fallthru */
- case SB_HW_20:
- chip->playback_format = SB_DSP_LO_OUTPUT_AUTO;
- break;
- case SB_HW_10:
- chip->playback_format = SB_DSP_OUTPUT;
- break;
- default:
- return -EINVAL;
- }
- if (chip->mode & SB_MODE_PLAYBACK_16) {
- format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT;
- dma = chip->dma16;
- } else {
- format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT;
- chip->mode |= SB_MODE_PLAYBACK_8;
- dma = chip->dma8;
- }
- size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream);
- count = chip->p_period_size = snd_pcm_lib_period_bytes(substream);
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON);
- if (chip->hardware == SB_HW_JAZZ16)
- snd_sbdsp_command(chip, format);
- else if (stereo) {
- /* set playback stereo mode */
- spin_lock(&chip->mixer_lock);
- mixreg = snd_sbmixer_read(chip, SB_DSP_STEREO_SW);
- snd_sbmixer_write(chip, SB_DSP_STEREO_SW, mixreg | 0x02);
- spin_unlock(&chip->mixer_lock);
-
- /* Soundblaster hardware programming reference guide, 3-23 */
- snd_sbdsp_command(chip, SB_DSP_DMA8_EXIT);
- runtime->dma_area[0] = 0x80;
- snd_dma_program(dma, runtime->dma_addr, 1, DMA_MODE_WRITE);
- /* force interrupt */
- snd_sbdsp_command(chip, SB_DSP_OUTPUT);
- snd_sbdsp_command(chip, 0);
- snd_sbdsp_command(chip, 0);
- }
- snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE);
- if (stereo) {
- snd_sbdsp_command(chip, 256 - runtime->rate_den / 2);
- spin_lock(&chip->mixer_lock);
- /* save output filter status and turn it off */
- mixreg = snd_sbmixer_read(chip, SB_DSP_PLAYBACK_FILT);
- snd_sbmixer_write(chip, SB_DSP_PLAYBACK_FILT, mixreg | 0x20);
- spin_unlock(&chip->mixer_lock);
- /* just use force_mode16 for temporary storate... */
- chip->force_mode16 = mixreg;
- } else {
- snd_sbdsp_command(chip, 256 - runtime->rate_den);
- }
- if (chip->playback_format != SB_DSP_OUTPUT) {
- if (chip->mode & SB_MODE_PLAYBACK_16)
- count /= 2;
- count--;
- snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE);
- snd_sbdsp_command(chip, count & 0xff);
- snd_sbdsp_command(chip, count >> 8);
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- snd_dma_program(dma, runtime->dma_addr,
- size, DMA_MODE_WRITE | DMA_AUTOINIT);
- return 0;
-}
-
-static int snd_sb8_playback_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- unsigned long flags;
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- unsigned int count;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- snd_sbdsp_command(chip, chip->playback_format);
- if (chip->playback_format == SB_DSP_OUTPUT) {
- count = chip->p_period_size - 1;
- snd_sbdsp_command(chip, count & 0xff);
- snd_sbdsp_command(chip, count >> 8);
- }
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- if (chip->playback_format == SB_DSP_HI_OUTPUT_AUTO) {
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_sbdsp_reset(chip);
- if (runtime->channels > 1) {
- spin_lock(&chip->mixer_lock);
- /* restore output filter and set hardware to mono mode */
- snd_sbmixer_write(chip, SB_DSP_STEREO_SW, chip->force_mode16 & ~0x02);
- spin_unlock(&chip->mixer_lock);
- }
- } else {
- snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
- }
- snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
-}
-
-static int snd_sb8_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static int snd_sb8_hw_free(struct snd_pcm_substream *substream)
-{
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream)
-{
- unsigned long flags;
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int mixreg, rate, size, count;
- unsigned char format;
- unsigned char stereo = runtime->channels > 1;
- int dma;
-
- rate = runtime->rate;
- switch (chip->hardware) {
- case SB_HW_JAZZ16:
- if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) {
- if (chip->mode & SB_MODE_PLAYBACK_16)
- return -EBUSY;
- else
- chip->mode |= SB_MODE_CAPTURE_16;
- }
- chip->capture_format = SB_DSP_LO_INPUT_AUTO;
- break;
- case SB_HW_PRO:
- if (runtime->channels > 1) {
- if (snd_BUG_ON(rate != SB8_RATE(11025) &&
- rate != SB8_RATE(22050)))
- return -EINVAL;
- chip->capture_format = SB_DSP_HI_INPUT_AUTO;
- break;
- }
- chip->capture_format = (rate > 23000) ? SB_DSP_HI_INPUT_AUTO : SB_DSP_LO_INPUT_AUTO;
- break;
- case SB_HW_201:
- if (rate > 13000) {
- chip->capture_format = SB_DSP_HI_INPUT_AUTO;
- break;
- }
- /* fallthru */
- case SB_HW_20:
- chip->capture_format = SB_DSP_LO_INPUT_AUTO;
- break;
- case SB_HW_10:
- chip->capture_format = SB_DSP_INPUT;
- break;
- default:
- return -EINVAL;
- }
- if (chip->mode & SB_MODE_CAPTURE_16) {
- format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT;
- dma = chip->dma16;
- } else {
- format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT;
- chip->mode |= SB_MODE_CAPTURE_8;
- dma = chip->dma8;
- }
- size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream);
- count = chip->c_period_size = snd_pcm_lib_period_bytes(substream);
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
- if (chip->hardware == SB_HW_JAZZ16)
- snd_sbdsp_command(chip, format);
- else if (stereo)
- snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT);
- snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE);
- if (stereo) {
- snd_sbdsp_command(chip, 256 - runtime->rate_den / 2);
- spin_lock(&chip->mixer_lock);
- /* save input filter status and turn it off */
- mixreg = snd_sbmixer_read(chip, SB_DSP_CAPTURE_FILT);
- snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, mixreg | 0x20);
- spin_unlock(&chip->mixer_lock);
- /* just use force_mode16 for temporary storate... */
- chip->force_mode16 = mixreg;
- } else {
- snd_sbdsp_command(chip, 256 - runtime->rate_den);
- }
- if (chip->capture_format != SB_DSP_INPUT) {
- if (chip->mode & SB_MODE_PLAYBACK_16)
- count /= 2;
- count--;
- snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE);
- snd_sbdsp_command(chip, count & 0xff);
- snd_sbdsp_command(chip, count >> 8);
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- snd_dma_program(dma, runtime->dma_addr,
- size, DMA_MODE_READ | DMA_AUTOINIT);
- return 0;
-}
-
-static int snd_sb8_capture_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- unsigned long flags;
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- unsigned int count;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- snd_sbdsp_command(chip, chip->capture_format);
- if (chip->capture_format == SB_DSP_INPUT) {
- count = chip->c_period_size - 1;
- snd_sbdsp_command(chip, count & 0xff);
- snd_sbdsp_command(chip, count >> 8);
- }
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- if (chip->capture_format == SB_DSP_HI_INPUT_AUTO) {
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_sbdsp_reset(chip);
- if (runtime->channels > 1) {
- /* restore input filter status */
- spin_lock(&chip->mixer_lock);
- snd_sbmixer_write(chip, SB_DSP_CAPTURE_FILT, chip->force_mode16);
- spin_unlock(&chip->mixer_lock);
- /* set hardware to mono mode */
- snd_sbdsp_command(chip, SB_DSP_MONO_8BIT);
- }
- } else {
- snd_sbdsp_command(chip, SB_DSP_DMA8_OFF);
- }
- snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
-}
-
-irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip)
-{
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
-
- snd_sb_ack_8bit(chip);
- switch (chip->mode) {
- case SB_MODE_PLAYBACK_16: /* ok.. playback is active */
- if (chip->hardware != SB_HW_JAZZ16)
- break;
- /* fallthru */
- case SB_MODE_PLAYBACK_8:
- substream = chip->playback_substream;
- runtime = substream->runtime;
- if (chip->playback_format == SB_DSP_OUTPUT)
- snd_sb8_playback_trigger(substream, SNDRV_PCM_TRIGGER_START);
- snd_pcm_period_elapsed(substream);
- break;
- case SB_MODE_CAPTURE_16:
- if (chip->hardware != SB_HW_JAZZ16)
- break;
- /* fallthru */
- case SB_MODE_CAPTURE_8:
- substream = chip->capture_substream;
- runtime = substream->runtime;
- if (chip->capture_format == SB_DSP_INPUT)
- snd_sb8_capture_trigger(substream, SNDRV_PCM_TRIGGER_START);
- snd_pcm_period_elapsed(substream);
- break;
- }
- return IRQ_HANDLED;
-}
-
-static snd_pcm_uframes_t snd_sb8_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- size_t ptr;
- int dma;
-
- if (chip->mode & SB_MODE_PLAYBACK_8)
- dma = chip->dma8;
- else if (chip->mode & SB_MODE_PLAYBACK_16)
- dma = chip->dma16;
- else
- return 0;
- ptr = snd_dma_pointer(dma, chip->p_dma_size);
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-static snd_pcm_uframes_t snd_sb8_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- size_t ptr;
- int dma;
-
- if (chip->mode & SB_MODE_CAPTURE_8)
- dma = chip->dma8;
- else if (chip->mode & SB_MODE_CAPTURE_16)
- dma = chip->dma16;
- else
- return 0;
- ptr = snd_dma_pointer(dma, chip->c_dma_size);
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-/*
-
- */
-
-static struct snd_pcm_hardware snd_sb8_playback =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_U8,
- .rates = (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000 |
- SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_22050),
- .rate_min = 4000,
- .rate_max = 23000,
- .channels_min = 1,
- .channels_max = 1,
- .buffer_bytes_max = 65536,
- .period_bytes_min = 64,
- .period_bytes_max = 65536,
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_sb8_capture =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_U8,
- .rates = (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000 |
- SNDRV_PCM_RATE_11025),
- .rate_min = 4000,
- .rate_max = 13000,
- .channels_min = 1,
- .channels_max = 1,
- .buffer_bytes_max = 65536,
- .period_bytes_min = 64,
- .period_bytes_max = 65536,
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-/*
- *
- */
-
-static int snd_sb8_open(struct snd_pcm_substream *substream)
-{
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long flags;
-
- spin_lock_irqsave(&chip->open_lock, flags);
- if (chip->open) {
- spin_unlock_irqrestore(&chip->open_lock, flags);
- return -EAGAIN;
- }
- chip->open |= SB_OPEN_PCM;
- spin_unlock_irqrestore(&chip->open_lock, flags);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- chip->playback_substream = substream;
- runtime->hw = snd_sb8_playback;
- } else {
- chip->capture_substream = substream;
- runtime->hw = snd_sb8_capture;
- }
- switch (chip->hardware) {
- case SB_HW_JAZZ16:
- if (chip->dma16 == 5 || chip->dma16 == 7)
- runtime->hw.formats |= SNDRV_PCM_FMTBIT_S16_LE;
- runtime->hw.rates |= SNDRV_PCM_RATE_8000_48000;
- runtime->hw.rate_min = 4000;
- runtime->hw.rate_max = 50000;
- runtime->hw.channels_max = 2;
- break;
- case SB_HW_PRO:
- runtime->hw.rate_max = 44100;
- runtime->hw.channels_max = 2;
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- snd_sb8_hw_constraint_rate_channels, NULL,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- SNDRV_PCM_HW_PARAM_RATE, -1);
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- snd_sb8_hw_constraint_channels_rate, NULL,
- SNDRV_PCM_HW_PARAM_RATE, -1);
- break;
- case SB_HW_201:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- runtime->hw.rate_max = 44100;
- } else {
- runtime->hw.rate_max = 15000;
- }
- default:
- break;
- }
- snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &hw_constraints_clock);
- if (chip->dma8 > 3 || chip->dma16 >= 0) {
- snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 2);
- snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 2);
- runtime->hw.buffer_bytes_max = 128 * 1024 * 1024;
- runtime->hw.period_bytes_max = 128 * 1024 * 1024;
- }
- return 0;
-}
-
-static int snd_sb8_close(struct snd_pcm_substream *substream)
-{
- unsigned long flags;
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
-
- chip->playback_substream = NULL;
- chip->capture_substream = NULL;
- spin_lock_irqsave(&chip->open_lock, flags);
- chip->open &= ~SB_OPEN_PCM;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- chip->mode &= ~SB_MODE_PLAYBACK;
- else
- chip->mode &= ~SB_MODE_CAPTURE;
- spin_unlock_irqrestore(&chip->open_lock, flags);
- return 0;
-}
-
-/*
- * Initialization part
- */
-
-static struct snd_pcm_ops snd_sb8_playback_ops = {
- .open = snd_sb8_open,
- .close = snd_sb8_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_sb8_hw_params,
- .hw_free = snd_sb8_hw_free,
- .prepare = snd_sb8_playback_prepare,
- .trigger = snd_sb8_playback_trigger,
- .pointer = snd_sb8_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_sb8_capture_ops = {
- .open = snd_sb8_open,
- .close = snd_sb8_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_sb8_hw_params,
- .hw_free = snd_sb8_hw_free,
- .prepare = snd_sb8_capture_prepare,
- .trigger = snd_sb8_capture_trigger,
- .pointer = snd_sb8_capture_pointer,
-};
-
-int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm)
-{
- struct snd_card *card = chip->card;
- struct snd_pcm *pcm;
- int err;
- size_t max_prealloc = 64 * 1024;
-
- if (rpcm)
- *rpcm = NULL;
- if ((err = snd_pcm_new(card, "SB8 DSP", device, 1, 1, &pcm)) < 0)
- return err;
- sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff);
- pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
- pcm->private_data = chip;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb8_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb8_capture_ops);
-
- if (chip->dma8 > 3 || chip->dma16 >= 0)
- max_prealloc = 128 * 1024;
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_isa_data(),
- 64*1024, max_prealloc);
-
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_sb8dsp_pcm);
-EXPORT_SYMBOL(snd_sb8dsp_interrupt);
- /* sb8_midi.c */
-EXPORT_SYMBOL(snd_sb8dsp_midi_interrupt);
-EXPORT_SYMBOL(snd_sb8dsp_midi);
-
-/*
- * INIT part
- */
-
-static int __init alsa_sb8_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_sb8_exit(void)
-{
-}
-
-module_init(alsa_sb8_init)
-module_exit(alsa_sb8_exit)
diff --git a/ANDROID_3.4.5/sound/isa/sb/sb8_midi.c b/ANDROID_3.4.5/sound/isa/sb/sb8_midi.c
deleted file mode 100644
index 988a8b73..00000000
--- a/ANDROID_3.4.5/sound/isa/sb/sb8_midi.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Routines for control of SoundBlaster cards - MIDI interface
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * --
- *
- * Sun May 9 22:54:38 BST 1999 George David Morrison <gdm@gedamo.demon.co.uk>
- * Fixed typo in snd_sb8dsp_midi_new_device which prevented midi from
- * working.
- *
- * Sun May 11 12:34:56 UTC 2003 Clemens Ladisch <clemens@ladisch.de>
- * Added full duplex UART mode for DSP version 2.0 and later.
- */
-
-#include <asm/io.h>
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/sb.h>
-
-
-irqreturn_t snd_sb8dsp_midi_interrupt(struct snd_sb *chip)
-{
- struct snd_rawmidi *rmidi;
- int max = 64;
- char byte;
-
- if (!chip)
- return IRQ_NONE;
-
- rmidi = chip->rmidi;
- if (!rmidi) {
- inb(SBP(chip, DATA_AVAIL)); /* ack interrupt */
- return IRQ_NONE;
- }
-
- spin_lock(&chip->midi_input_lock);
- while (max-- > 0) {
- if (inb(SBP(chip, DATA_AVAIL)) & 0x80) {
- byte = inb(SBP(chip, READ));
- if (chip->open & SB_OPEN_MIDI_INPUT_TRIGGER) {
- snd_rawmidi_receive(chip->midi_substream_input, &byte, 1);
- }
- }
- }
- spin_unlock(&chip->midi_input_lock);
- return IRQ_HANDLED;
-}
-
-static int snd_sb8dsp_midi_input_open(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- struct snd_sb *chip;
- unsigned int valid_open_flags;
-
- chip = substream->rmidi->private_data;
- valid_open_flags = chip->hardware >= SB_HW_20
- ? SB_OPEN_MIDI_OUTPUT | SB_OPEN_MIDI_OUTPUT_TRIGGER : 0;
- spin_lock_irqsave(&chip->open_lock, flags);
- if (chip->open & ~valid_open_flags) {
- spin_unlock_irqrestore(&chip->open_lock, flags);
- return -EAGAIN;
- }
- chip->open |= SB_OPEN_MIDI_INPUT;
- chip->midi_substream_input = substream;
- if (!(chip->open & SB_OPEN_MIDI_OUTPUT)) {
- spin_unlock_irqrestore(&chip->open_lock, flags);
- snd_sbdsp_reset(chip); /* reset DSP */
- if (chip->hardware >= SB_HW_20)
- snd_sbdsp_command(chip, SB_DSP_MIDI_UART_IRQ);
- } else {
- spin_unlock_irqrestore(&chip->open_lock, flags);
- }
- return 0;
-}
-
-static int snd_sb8dsp_midi_output_open(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- struct snd_sb *chip;
- unsigned int valid_open_flags;
-
- chip = substream->rmidi->private_data;
- valid_open_flags = chip->hardware >= SB_HW_20
- ? SB_OPEN_MIDI_INPUT | SB_OPEN_MIDI_INPUT_TRIGGER : 0;
- spin_lock_irqsave(&chip->open_lock, flags);
- if (chip->open & ~valid_open_flags) {
- spin_unlock_irqrestore(&chip->open_lock, flags);
- return -EAGAIN;
- }
- chip->open |= SB_OPEN_MIDI_OUTPUT;
- chip->midi_substream_output = substream;
- if (!(chip->open & SB_OPEN_MIDI_INPUT)) {
- spin_unlock_irqrestore(&chip->open_lock, flags);
- snd_sbdsp_reset(chip); /* reset DSP */
- if (chip->hardware >= SB_HW_20)
- snd_sbdsp_command(chip, SB_DSP_MIDI_UART_IRQ);
- } else {
- spin_unlock_irqrestore(&chip->open_lock, flags);
- }
- return 0;
-}
-
-static int snd_sb8dsp_midi_input_close(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- struct snd_sb *chip;
-
- chip = substream->rmidi->private_data;
- spin_lock_irqsave(&chip->open_lock, flags);
- chip->open &= ~(SB_OPEN_MIDI_INPUT | SB_OPEN_MIDI_INPUT_TRIGGER);
- chip->midi_substream_input = NULL;
- if (!(chip->open & SB_OPEN_MIDI_OUTPUT)) {
- spin_unlock_irqrestore(&chip->open_lock, flags);
- snd_sbdsp_reset(chip); /* reset DSP */
- } else {
- spin_unlock_irqrestore(&chip->open_lock, flags);
- }
- return 0;
-}
-
-static int snd_sb8dsp_midi_output_close(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- struct snd_sb *chip;
-
- chip = substream->rmidi->private_data;
- spin_lock_irqsave(&chip->open_lock, flags);
- chip->open &= ~(SB_OPEN_MIDI_OUTPUT | SB_OPEN_MIDI_OUTPUT_TRIGGER);
- chip->midi_substream_output = NULL;
- if (!(chip->open & SB_OPEN_MIDI_INPUT)) {
- spin_unlock_irqrestore(&chip->open_lock, flags);
- snd_sbdsp_reset(chip); /* reset DSP */
- } else {
- spin_unlock_irqrestore(&chip->open_lock, flags);
- }
- return 0;
-}
-
-static void snd_sb8dsp_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- unsigned long flags;
- struct snd_sb *chip;
-
- chip = substream->rmidi->private_data;
- spin_lock_irqsave(&chip->open_lock, flags);
- if (up) {
- if (!(chip->open & SB_OPEN_MIDI_INPUT_TRIGGER)) {
- if (chip->hardware < SB_HW_20)
- snd_sbdsp_command(chip, SB_DSP_MIDI_INPUT_IRQ);
- chip->open |= SB_OPEN_MIDI_INPUT_TRIGGER;
- }
- } else {
- if (chip->open & SB_OPEN_MIDI_INPUT_TRIGGER) {
- if (chip->hardware < SB_HW_20)
- snd_sbdsp_command(chip, SB_DSP_MIDI_INPUT_IRQ);
- chip->open &= ~SB_OPEN_MIDI_INPUT_TRIGGER;
- }
- }
- spin_unlock_irqrestore(&chip->open_lock, flags);
-}
-
-static void snd_sb8dsp_midi_output_write(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- struct snd_sb *chip;
- char byte;
- int max = 32;
-
- /* how big is Tx FIFO? */
- chip = substream->rmidi->private_data;
- while (max-- > 0) {
- spin_lock_irqsave(&chip->open_lock, flags);
- if (snd_rawmidi_transmit_peek(substream, &byte, 1) != 1) {
- chip->open &= ~SB_OPEN_MIDI_OUTPUT_TRIGGER;
- del_timer(&chip->midi_timer);
- spin_unlock_irqrestore(&chip->open_lock, flags);
- break;
- }
- if (chip->hardware >= SB_HW_20) {
- int timeout = 8;
- while ((inb(SBP(chip, STATUS)) & 0x80) != 0 && --timeout > 0)
- ;
- if (timeout == 0) {
- /* Tx FIFO full - try again later */
- spin_unlock_irqrestore(&chip->open_lock, flags);
- break;
- }
- outb(byte, SBP(chip, WRITE));
- } else {
- snd_sbdsp_command(chip, SB_DSP_MIDI_OUTPUT);
- snd_sbdsp_command(chip, byte);
- }
- snd_rawmidi_transmit_ack(substream, 1);
- spin_unlock_irqrestore(&chip->open_lock, flags);
- }
-}
-
-static void snd_sb8dsp_midi_output_timer(unsigned long data)
-{
- struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *) data;
- struct snd_sb * chip = substream->rmidi->private_data;
- unsigned long flags;
-
- spin_lock_irqsave(&chip->open_lock, flags);
- chip->midi_timer.expires = 1 + jiffies;
- add_timer(&chip->midi_timer);
- spin_unlock_irqrestore(&chip->open_lock, flags);
- snd_sb8dsp_midi_output_write(substream);
-}
-
-static void snd_sb8dsp_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- unsigned long flags;
- struct snd_sb *chip;
-
- chip = substream->rmidi->private_data;
- spin_lock_irqsave(&chip->open_lock, flags);
- if (up) {
- if (!(chip->open & SB_OPEN_MIDI_OUTPUT_TRIGGER)) {
- init_timer(&chip->midi_timer);
- chip->midi_timer.function = snd_sb8dsp_midi_output_timer;
- chip->midi_timer.data = (unsigned long) substream;
- chip->midi_timer.expires = 1 + jiffies;
- add_timer(&chip->midi_timer);
- chip->open |= SB_OPEN_MIDI_OUTPUT_TRIGGER;
- }
- } else {
- if (chip->open & SB_OPEN_MIDI_OUTPUT_TRIGGER) {
- chip->open &= ~SB_OPEN_MIDI_OUTPUT_TRIGGER;
- }
- }
- spin_unlock_irqrestore(&chip->open_lock, flags);
-
- if (up)
- snd_sb8dsp_midi_output_write(substream);
-}
-
-static struct snd_rawmidi_ops snd_sb8dsp_midi_output =
-{
- .open = snd_sb8dsp_midi_output_open,
- .close = snd_sb8dsp_midi_output_close,
- .trigger = snd_sb8dsp_midi_output_trigger,
-};
-
-static struct snd_rawmidi_ops snd_sb8dsp_midi_input =
-{
- .open = snd_sb8dsp_midi_input_open,
- .close = snd_sb8dsp_midi_input_close,
- .trigger = snd_sb8dsp_midi_input_trigger,
-};
-
-int snd_sb8dsp_midi(struct snd_sb *chip, int device, struct snd_rawmidi ** rrawmidi)
-{
- struct snd_rawmidi *rmidi;
- int err;
-
- if (rrawmidi)
- *rrawmidi = NULL;
- if ((err = snd_rawmidi_new(chip->card, "SB8 MIDI", device, 1, 1, &rmidi)) < 0)
- return err;
- strcpy(rmidi->name, "SB8 MIDI");
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_sb8dsp_midi_output);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_sb8dsp_midi_input);
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT;
- if (chip->hardware >= SB_HW_20)
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX;
- rmidi->private_data = chip;
- chip->rmidi = rmidi;
- if (rrawmidi)
- *rrawmidi = rmidi;
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/isa/sb/sb_common.c b/ANDROID_3.4.5/sound/isa/sb/sb_common.c
deleted file mode 100644
index 3ef99060..00000000
--- a/ANDROID_3.4.5/sound/isa/sb/sb_common.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Uros Bizjak <uros@kss-loka.si>
- *
- * Lowlevel routines for control of Sound Blaster cards
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/sb.h>
-#include <sound/initval.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("ALSA lowlevel driver for Sound Blaster cards");
-MODULE_LICENSE("GPL");
-
-#define BUSY_LOOPS 100000
-
-#undef IO_DEBUG
-
-int snd_sbdsp_command(struct snd_sb *chip, unsigned char val)
-{
- int i;
-#ifdef IO_DEBUG
- snd_printk(KERN_DEBUG "command 0x%x\n", val);
-#endif
- for (i = BUSY_LOOPS; i; i--)
- if ((inb(SBP(chip, STATUS)) & 0x80) == 0) {
- outb(val, SBP(chip, COMMAND));
- return 1;
- }
- snd_printd("%s [0x%lx]: timeout (0x%x)\n", __func__, chip->port, val);
- return 0;
-}
-
-int snd_sbdsp_get_byte(struct snd_sb *chip)
-{
- int val;
- int i;
- for (i = BUSY_LOOPS; i; i--) {
- if (inb(SBP(chip, DATA_AVAIL)) & 0x80) {
- val = inb(SBP(chip, READ));
-#ifdef IO_DEBUG
- snd_printk(KERN_DEBUG "get_byte 0x%x\n", val);
-#endif
- return val;
- }
- }
- snd_printd("%s [0x%lx]: timeout\n", __func__, chip->port);
- return -ENODEV;
-}
-
-int snd_sbdsp_reset(struct snd_sb *chip)
-{
- int i;
-
- outb(1, SBP(chip, RESET));
- udelay(10);
- outb(0, SBP(chip, RESET));
- udelay(30);
- for (i = BUSY_LOOPS; i; i--)
- if (inb(SBP(chip, DATA_AVAIL)) & 0x80) {
- if (inb(SBP(chip, READ)) == 0xaa)
- return 0;
- else
- break;
- }
- snd_printdd("%s [0x%lx] failed...\n", __func__, chip->port);
- return -ENODEV;
-}
-
-static int snd_sbdsp_version(struct snd_sb * chip)
-{
- unsigned int result = -ENODEV;
-
- snd_sbdsp_command(chip, SB_DSP_GET_VERSION);
- result = (short) snd_sbdsp_get_byte(chip) << 8;
- result |= (short) snd_sbdsp_get_byte(chip);
- return result;
-}
-
-static int snd_sbdsp_probe(struct snd_sb * chip)
-{
- int version;
- int major, minor;
- char *str;
- unsigned long flags;
-
- /*
- * initialization sequence
- */
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (snd_sbdsp_reset(chip) < 0) {
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return -ENODEV;
- }
- version = snd_sbdsp_version(chip);
- if (version < 0) {
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return -ENODEV;
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- major = version >> 8;
- minor = version & 0xff;
- snd_printdd("SB [0x%lx]: DSP chip found, version = %i.%i\n",
- chip->port, major, minor);
-
- switch (chip->hardware) {
- case SB_HW_AUTO:
- switch (major) {
- case 1:
- chip->hardware = SB_HW_10;
- str = "1.0";
- break;
- case 2:
- if (minor) {
- chip->hardware = SB_HW_201;
- str = "2.01+";
- } else {
- chip->hardware = SB_HW_20;
- str = "2.0";
- }
- break;
- case 3:
- chip->hardware = SB_HW_PRO;
- str = "Pro";
- break;
- case 4:
- chip->hardware = SB_HW_16;
- str = "16";
- break;
- default:
- snd_printk(KERN_INFO "SB [0x%lx]: unknown DSP chip version %i.%i\n",
- chip->port, major, minor);
- return -ENODEV;
- }
- break;
- case SB_HW_ALS100:
- str = "16 (ALS-100)";
- break;
- case SB_HW_ALS4000:
- str = "16 (ALS-4000)";
- break;
- case SB_HW_DT019X:
- str = "(DT019X/ALS007)";
- break;
- case SB_HW_CS5530:
- str = "16 (CS5530)";
- break;
- case SB_HW_JAZZ16:
- str = "Pro (Jazz16)";
- break;
- default:
- return -ENODEV;
- }
- sprintf(chip->name, "Sound Blaster %s", str);
- chip->version = (major << 8) | minor;
- return 0;
-}
-
-static int snd_sbdsp_free(struct snd_sb *chip)
-{
- if (chip->res_port)
- release_and_free_resource(chip->res_port);
- if (chip->irq >= 0)
- free_irq(chip->irq, (void *) chip);
-#ifdef CONFIG_ISA
- if (chip->dma8 >= 0) {
- disable_dma(chip->dma8);
- free_dma(chip->dma8);
- }
- if (chip->dma16 >= 0 && chip->dma16 != chip->dma8) {
- disable_dma(chip->dma16);
- free_dma(chip->dma16);
- }
-#endif
- kfree(chip);
- return 0;
-}
-
-static int snd_sbdsp_dev_free(struct snd_device *device)
-{
- struct snd_sb *chip = device->device_data;
- return snd_sbdsp_free(chip);
-}
-
-int snd_sbdsp_create(struct snd_card *card,
- unsigned long port,
- int irq,
- irq_handler_t irq_handler,
- int dma8,
- int dma16,
- unsigned short hardware,
- struct snd_sb **r_chip)
-{
- struct snd_sb *chip;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_sbdsp_dev_free,
- };
-
- if (snd_BUG_ON(!r_chip))
- return -EINVAL;
- *r_chip = NULL;
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL)
- return -ENOMEM;
- spin_lock_init(&chip->reg_lock);
- spin_lock_init(&chip->open_lock);
- spin_lock_init(&chip->midi_input_lock);
- spin_lock_init(&chip->mixer_lock);
- chip->irq = -1;
- chip->dma8 = -1;
- chip->dma16 = -1;
- chip->port = port;
-
- if (request_irq(irq, irq_handler,
- (hardware == SB_HW_ALS4000 ||
- hardware == SB_HW_CS5530) ?
- IRQF_SHARED : 0,
- "SoundBlaster", (void *) chip)) {
- snd_printk(KERN_ERR "sb: can't grab irq %d\n", irq);
- snd_sbdsp_free(chip);
- return -EBUSY;
- }
- chip->irq = irq;
-
- if (hardware == SB_HW_ALS4000)
- goto __skip_allocation;
-
- if ((chip->res_port = request_region(port, 16, "SoundBlaster")) == NULL) {
- snd_printk(KERN_ERR "sb: can't grab port 0x%lx\n", port);
- snd_sbdsp_free(chip);
- return -EBUSY;
- }
-
-#ifdef CONFIG_ISA
- if (dma8 >= 0 && request_dma(dma8, "SoundBlaster - 8bit")) {
- snd_printk(KERN_ERR "sb: can't grab DMA8 %d\n", dma8);
- snd_sbdsp_free(chip);
- return -EBUSY;
- }
- chip->dma8 = dma8;
- if (dma16 >= 0) {
- if (hardware != SB_HW_ALS100 && (dma16 < 5 || dma16 > 7)) {
- /* no duplex */
- dma16 = -1;
- } else if (request_dma(dma16, "SoundBlaster - 16bit")) {
- snd_printk(KERN_ERR "sb: can't grab DMA16 %d\n", dma16);
- snd_sbdsp_free(chip);
- return -EBUSY;
- }
- }
- chip->dma16 = dma16;
-#endif
-
- __skip_allocation:
- chip->card = card;
- chip->hardware = hardware;
- if ((err = snd_sbdsp_probe(chip)) < 0) {
- snd_sbdsp_free(chip);
- return err;
- }
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_sbdsp_free(chip);
- return err;
- }
- *r_chip = chip;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_sbdsp_command);
-EXPORT_SYMBOL(snd_sbdsp_get_byte);
-EXPORT_SYMBOL(snd_sbdsp_reset);
-EXPORT_SYMBOL(snd_sbdsp_create);
-/* sb_mixer.c */
-EXPORT_SYMBOL(snd_sbmixer_write);
-EXPORT_SYMBOL(snd_sbmixer_read);
-EXPORT_SYMBOL(snd_sbmixer_new);
-EXPORT_SYMBOL(snd_sbmixer_add_ctl);
-#ifdef CONFIG_PM
-EXPORT_SYMBOL(snd_sbmixer_suspend);
-EXPORT_SYMBOL(snd_sbmixer_resume);
-#endif
-
-/*
- * INIT part
- */
-
-static int __init alsa_sb_common_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_sb_common_exit(void)
-{
-}
-
-module_init(alsa_sb_common_init)
-module_exit(alsa_sb_common_exit)
diff --git a/ANDROID_3.4.5/sound/isa/sb/sb_mixer.c b/ANDROID_3.4.5/sound/isa/sb/sb_mixer.c
deleted file mode 100644
index 6496822c..00000000
--- a/ANDROID_3.4.5/sound/isa/sb/sb_mixer.c
+++ /dev/null
@@ -1,978 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Routines for Sound Blaster mixer control
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/sb.h>
-#include <sound/control.h>
-
-#undef IO_DEBUG
-
-void snd_sbmixer_write(struct snd_sb *chip, unsigned char reg, unsigned char data)
-{
- outb(reg, SBP(chip, MIXER_ADDR));
- udelay(10);
- outb(data, SBP(chip, MIXER_DATA));
- udelay(10);
-#ifdef IO_DEBUG
- snd_printk(KERN_DEBUG "mixer_write 0x%x 0x%x\n", reg, data);
-#endif
-}
-
-unsigned char snd_sbmixer_read(struct snd_sb *chip, unsigned char reg)
-{
- unsigned char result;
-
- outb(reg, SBP(chip, MIXER_ADDR));
- udelay(10);
- result = inb(SBP(chip, MIXER_DATA));
- udelay(10);
-#ifdef IO_DEBUG
- snd_printk(KERN_DEBUG "mixer_read 0x%x 0x%x\n", reg, result);
-#endif
- return result;
-}
-
-/*
- * Single channel mixer element
- */
-
-static int snd_sbmixer_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 24) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_sbmixer_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 16) & 0xff;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- unsigned char val;
-
- spin_lock_irqsave(&sb->mixer_lock, flags);
- val = (snd_sbmixer_read(sb, reg) >> shift) & mask;
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
- ucontrol->value.integer.value[0] = val;
- return 0;
-}
-
-static int snd_sbmixer_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 16) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int change;
- unsigned char val, oval;
-
- val = (ucontrol->value.integer.value[0] & mask) << shift;
- spin_lock_irqsave(&sb->mixer_lock, flags);
- oval = snd_sbmixer_read(sb, reg);
- val = (oval & ~(mask << shift)) | val;
- change = val != oval;
- if (change)
- snd_sbmixer_write(sb, reg, val);
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
- return change;
-}
-
-/*
- * Double channel mixer element
- */
-
-static int snd_sbmixer_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 24) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_sbmixer_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int left_shift = (kcontrol->private_value >> 16) & 0x07;
- int right_shift = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- unsigned char left, right;
-
- spin_lock_irqsave(&sb->mixer_lock, flags);
- left = (snd_sbmixer_read(sb, left_reg) >> left_shift) & mask;
- right = (snd_sbmixer_read(sb, right_reg) >> right_shift) & mask;
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
- ucontrol->value.integer.value[0] = left;
- ucontrol->value.integer.value[1] = right;
- return 0;
-}
-
-static int snd_sbmixer_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int left_shift = (kcontrol->private_value >> 16) & 0x07;
- int right_shift = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int change;
- unsigned char left, right, oleft, oright;
-
- left = (ucontrol->value.integer.value[0] & mask) << left_shift;
- right = (ucontrol->value.integer.value[1] & mask) << right_shift;
- spin_lock_irqsave(&sb->mixer_lock, flags);
- if (left_reg == right_reg) {
- oleft = snd_sbmixer_read(sb, left_reg);
- left = (oleft & ~((mask << left_shift) | (mask << right_shift))) | left | right;
- change = left != oleft;
- if (change)
- snd_sbmixer_write(sb, left_reg, left);
- } else {
- oleft = snd_sbmixer_read(sb, left_reg);
- oright = snd_sbmixer_read(sb, right_reg);
- left = (oleft & ~(mask << left_shift)) | left;
- right = (oright & ~(mask << right_shift)) | right;
- change = left != oleft || right != oright;
- if (change) {
- snd_sbmixer_write(sb, left_reg, left);
- snd_sbmixer_write(sb, right_reg, right);
- }
- }
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
- return change;
-}
-
-/*
- * DT-019x / ALS-007 capture/input switch
- */
-
-static int snd_dt019x_input_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static const char *texts[5] = {
- "CD", "Mic", "Line", "Synth", "Master"
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 5;
- if (uinfo->value.enumerated.item > 4)
- uinfo->value.enumerated.item = 4;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_dt019x_input_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- unsigned char oval;
-
- spin_lock_irqsave(&sb->mixer_lock, flags);
- oval = snd_sbmixer_read(sb, SB_DT019X_CAPTURE_SW);
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
- switch (oval & 0x07) {
- case SB_DT019X_CAP_CD:
- ucontrol->value.enumerated.item[0] = 0;
- break;
- case SB_DT019X_CAP_MIC:
- ucontrol->value.enumerated.item[0] = 1;
- break;
- case SB_DT019X_CAP_LINE:
- ucontrol->value.enumerated.item[0] = 2;
- break;
- case SB_DT019X_CAP_MAIN:
- ucontrol->value.enumerated.item[0] = 4;
- break;
- /* To record the synth on these cards you must record the main. */
- /* Thus SB_DT019X_CAP_SYNTH == SB_DT019X_CAP_MAIN and would cause */
- /* duplicate case labels if left uncommented. */
- /* case SB_DT019X_CAP_SYNTH:
- * ucontrol->value.enumerated.item[0] = 3;
- * break;
- */
- default:
- ucontrol->value.enumerated.item[0] = 4;
- break;
- }
- return 0;
-}
-
-static int snd_dt019x_input_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int change;
- unsigned char nval, oval;
-
- if (ucontrol->value.enumerated.item[0] > 4)
- return -EINVAL;
- switch (ucontrol->value.enumerated.item[0]) {
- case 0:
- nval = SB_DT019X_CAP_CD;
- break;
- case 1:
- nval = SB_DT019X_CAP_MIC;
- break;
- case 2:
- nval = SB_DT019X_CAP_LINE;
- break;
- case 3:
- nval = SB_DT019X_CAP_SYNTH;
- break;
- case 4:
- nval = SB_DT019X_CAP_MAIN;
- break;
- default:
- nval = SB_DT019X_CAP_MAIN;
- }
- spin_lock_irqsave(&sb->mixer_lock, flags);
- oval = snd_sbmixer_read(sb, SB_DT019X_CAPTURE_SW);
- change = nval != oval;
- if (change)
- snd_sbmixer_write(sb, SB_DT019X_CAPTURE_SW, nval);
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
- return change;
-}
-
-/*
- * ALS4000 mono recording control switch
- */
-
-static int snd_als4k_mono_capture_route_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static const char *texts[3] = {
- "L chan only", "R chan only", "L ch/2 + R ch/2"
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item > 2)
- uinfo->value.enumerated.item = 2;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_als4k_mono_capture_route_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- unsigned char oval;
-
- spin_lock_irqsave(&sb->mixer_lock, flags);
- oval = snd_sbmixer_read(sb, SB_ALS4000_MONO_IO_CTRL);
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
- oval >>= 6;
- if (oval > 2)
- oval = 2;
-
- ucontrol->value.enumerated.item[0] = oval;
- return 0;
-}
-
-static int snd_als4k_mono_capture_route_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int change;
- unsigned char nval, oval;
-
- if (ucontrol->value.enumerated.item[0] > 2)
- return -EINVAL;
- spin_lock_irqsave(&sb->mixer_lock, flags);
- oval = snd_sbmixer_read(sb, SB_ALS4000_MONO_IO_CTRL);
-
- nval = (oval & ~(3 << 6))
- | (ucontrol->value.enumerated.item[0] << 6);
- change = nval != oval;
- if (change)
- snd_sbmixer_write(sb, SB_ALS4000_MONO_IO_CTRL, nval);
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
- return change;
-}
-
-/*
- * SBPRO input multiplexer
- */
-
-static int snd_sb8mixer_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static const char *texts[3] = {
- "Mic", "CD", "Line"
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item > 2)
- uinfo->value.enumerated.item = 2;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-
-static int snd_sb8mixer_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- unsigned char oval;
-
- spin_lock_irqsave(&sb->mixer_lock, flags);
- oval = snd_sbmixer_read(sb, SB_DSP_CAPTURE_SOURCE);
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
- switch ((oval >> 0x01) & 0x03) {
- case SB_DSP_MIXS_CD:
- ucontrol->value.enumerated.item[0] = 1;
- break;
- case SB_DSP_MIXS_LINE:
- ucontrol->value.enumerated.item[0] = 2;
- break;
- default:
- ucontrol->value.enumerated.item[0] = 0;
- break;
- }
- return 0;
-}
-
-static int snd_sb8mixer_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int change;
- unsigned char nval, oval;
-
- if (ucontrol->value.enumerated.item[0] > 2)
- return -EINVAL;
- switch (ucontrol->value.enumerated.item[0]) {
- case 1:
- nval = SB_DSP_MIXS_CD;
- break;
- case 2:
- nval = SB_DSP_MIXS_LINE;
- break;
- default:
- nval = SB_DSP_MIXS_MIC;
- }
- nval <<= 1;
- spin_lock_irqsave(&sb->mixer_lock, flags);
- oval = snd_sbmixer_read(sb, SB_DSP_CAPTURE_SOURCE);
- nval |= oval & ~0x06;
- change = nval != oval;
- if (change)
- snd_sbmixer_write(sb, SB_DSP_CAPTURE_SOURCE, nval);
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
- return change;
-}
-
-/*
- * SB16 input switch
- */
-
-static int snd_sb16mixer_info_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 4;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int snd_sb16mixer_get_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int reg1 = kcontrol->private_value & 0xff;
- int reg2 = (kcontrol->private_value >> 8) & 0xff;
- int left_shift = (kcontrol->private_value >> 16) & 0x0f;
- int right_shift = (kcontrol->private_value >> 24) & 0x0f;
- unsigned char val1, val2;
-
- spin_lock_irqsave(&sb->mixer_lock, flags);
- val1 = snd_sbmixer_read(sb, reg1);
- val2 = snd_sbmixer_read(sb, reg2);
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
- ucontrol->value.integer.value[0] = (val1 >> left_shift) & 0x01;
- ucontrol->value.integer.value[1] = (val2 >> left_shift) & 0x01;
- ucontrol->value.integer.value[2] = (val1 >> right_shift) & 0x01;
- ucontrol->value.integer.value[3] = (val2 >> right_shift) & 0x01;
- return 0;
-}
-
-static int snd_sb16mixer_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int reg1 = kcontrol->private_value & 0xff;
- int reg2 = (kcontrol->private_value >> 8) & 0xff;
- int left_shift = (kcontrol->private_value >> 16) & 0x0f;
- int right_shift = (kcontrol->private_value >> 24) & 0x0f;
- int change;
- unsigned char val1, val2, oval1, oval2;
-
- spin_lock_irqsave(&sb->mixer_lock, flags);
- oval1 = snd_sbmixer_read(sb, reg1);
- oval2 = snd_sbmixer_read(sb, reg2);
- val1 = oval1 & ~((1 << left_shift) | (1 << right_shift));
- val2 = oval2 & ~((1 << left_shift) | (1 << right_shift));
- val1 |= (ucontrol->value.integer.value[0] & 1) << left_shift;
- val2 |= (ucontrol->value.integer.value[1] & 1) << left_shift;
- val1 |= (ucontrol->value.integer.value[2] & 1) << right_shift;
- val2 |= (ucontrol->value.integer.value[3] & 1) << right_shift;
- change = val1 != oval1 || val2 != oval2;
- if (change) {
- snd_sbmixer_write(sb, reg1, val1);
- snd_sbmixer_write(sb, reg2, val2);
- }
- spin_unlock_irqrestore(&sb->mixer_lock, flags);
- return change;
-}
-
-
-/*
- */
-/*
- */
-int snd_sbmixer_add_ctl(struct snd_sb *chip, const char *name, int index, int type, unsigned long value)
-{
- static struct snd_kcontrol_new newctls[] = {
- [SB_MIX_SINGLE] = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = snd_sbmixer_info_single,
- .get = snd_sbmixer_get_single,
- .put = snd_sbmixer_put_single,
- },
- [SB_MIX_DOUBLE] = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = snd_sbmixer_info_double,
- .get = snd_sbmixer_get_double,
- .put = snd_sbmixer_put_double,
- },
- [SB_MIX_INPUT_SW] = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = snd_sb16mixer_info_input_sw,
- .get = snd_sb16mixer_get_input_sw,
- .put = snd_sb16mixer_put_input_sw,
- },
- [SB_MIX_CAPTURE_PRO] = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = snd_sb8mixer_info_mux,
- .get = snd_sb8mixer_get_mux,
- .put = snd_sb8mixer_put_mux,
- },
- [SB_MIX_CAPTURE_DT019X] = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = snd_dt019x_input_sw_info,
- .get = snd_dt019x_input_sw_get,
- .put = snd_dt019x_input_sw_put,
- },
- [SB_MIX_MONO_CAPTURE_ALS4K] = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = snd_als4k_mono_capture_route_info,
- .get = snd_als4k_mono_capture_route_get,
- .put = snd_als4k_mono_capture_route_put,
- },
- };
- struct snd_kcontrol *ctl;
- int err;
-
- ctl = snd_ctl_new1(&newctls[type], chip);
- if (! ctl)
- return -ENOMEM;
- strlcpy(ctl->id.name, name, sizeof(ctl->id.name));
- ctl->id.index = index;
- ctl->private_value = value;
- if ((err = snd_ctl_add(chip->card, ctl)) < 0)
- return err;
- return 0;
-}
-
-/*
- * SB 2.0 specific mixer elements
- */
-
-static struct sbmix_elem snd_sb20_controls[] = {
- SB_SINGLE("Master Playback Volume", SB_DSP20_MASTER_DEV, 1, 7),
- SB_SINGLE("PCM Playback Volume", SB_DSP20_PCM_DEV, 1, 3),
- SB_SINGLE("Synth Playback Volume", SB_DSP20_FM_DEV, 1, 7),
- SB_SINGLE("CD Playback Volume", SB_DSP20_CD_DEV, 1, 7)
-};
-
-static unsigned char snd_sb20_init_values[][2] = {
- { SB_DSP20_MASTER_DEV, 0 },
- { SB_DSP20_FM_DEV, 0 },
-};
-
-/*
- * SB Pro specific mixer elements
- */
-static struct sbmix_elem snd_sbpro_controls[] = {
- SB_DOUBLE("Master Playback Volume",
- SB_DSP_MASTER_DEV, SB_DSP_MASTER_DEV, 5, 1, 7),
- SB_DOUBLE("PCM Playback Volume",
- SB_DSP_PCM_DEV, SB_DSP_PCM_DEV, 5, 1, 7),
- SB_SINGLE("PCM Playback Filter", SB_DSP_PLAYBACK_FILT, 5, 1),
- SB_DOUBLE("Synth Playback Volume",
- SB_DSP_FM_DEV, SB_DSP_FM_DEV, 5, 1, 7),
- SB_DOUBLE("CD Playback Volume", SB_DSP_CD_DEV, SB_DSP_CD_DEV, 5, 1, 7),
- SB_DOUBLE("Line Playback Volume",
- SB_DSP_LINE_DEV, SB_DSP_LINE_DEV, 5, 1, 7),
- SB_SINGLE("Mic Playback Volume", SB_DSP_MIC_DEV, 1, 3),
- {
- .name = "Capture Source",
- .type = SB_MIX_CAPTURE_PRO
- },
- SB_SINGLE("Capture Filter", SB_DSP_CAPTURE_FILT, 5, 1),
- SB_SINGLE("Capture Low-Pass Filter", SB_DSP_CAPTURE_FILT, 3, 1)
-};
-
-static unsigned char snd_sbpro_init_values[][2] = {
- { SB_DSP_MASTER_DEV, 0 },
- { SB_DSP_PCM_DEV, 0 },
- { SB_DSP_FM_DEV, 0 },
-};
-
-/*
- * SB16 specific mixer elements
- */
-static struct sbmix_elem snd_sb16_controls[] = {
- SB_DOUBLE("Master Playback Volume",
- SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31),
- SB_DOUBLE("PCM Playback Volume",
- SB_DSP4_PCM_DEV, (SB_DSP4_PCM_DEV + 1), 3, 3, 31),
- SB16_INPUT_SW("Synth Capture Route",
- SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 6, 5),
- SB_DOUBLE("Synth Playback Volume",
- SB_DSP4_SYNTH_DEV, (SB_DSP4_SYNTH_DEV + 1), 3, 3, 31),
- SB16_INPUT_SW("CD Capture Route",
- SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 2, 1),
- SB_DOUBLE("CD Playback Switch",
- SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1),
- SB_DOUBLE("CD Playback Volume",
- SB_DSP4_CD_DEV, (SB_DSP4_CD_DEV + 1), 3, 3, 31),
- SB16_INPUT_SW("Mic Capture Route",
- SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0),
- SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1),
- SB_SINGLE("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31),
- SB_SINGLE("Beep Volume", SB_DSP4_SPEAKER_DEV, 6, 3),
- SB_DOUBLE("Capture Volume",
- SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3),
- SB_DOUBLE("Playback Volume",
- SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3),
- SB16_INPUT_SW("Line Capture Route",
- SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 4, 3),
- SB_DOUBLE("Line Playback Switch",
- SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1),
- SB_DOUBLE("Line Playback Volume",
- SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31),
- SB_SINGLE("Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1),
- SB_SINGLE("3D Enhancement Switch", SB_DSP4_3DSE, 0, 1),
- SB_DOUBLE("Tone Control - Bass",
- SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15),
- SB_DOUBLE("Tone Control - Treble",
- SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15)
-};
-
-static unsigned char snd_sb16_init_values[][2] = {
- { SB_DSP4_MASTER_DEV + 0, 0 },
- { SB_DSP4_MASTER_DEV + 1, 0 },
- { SB_DSP4_PCM_DEV + 0, 0 },
- { SB_DSP4_PCM_DEV + 1, 0 },
- { SB_DSP4_SYNTH_DEV + 0, 0 },
- { SB_DSP4_SYNTH_DEV + 1, 0 },
- { SB_DSP4_INPUT_LEFT, 0 },
- { SB_DSP4_INPUT_RIGHT, 0 },
- { SB_DSP4_OUTPUT_SW, 0 },
- { SB_DSP4_SPEAKER_DEV, 0 },
-};
-
-/*
- * DT019x specific mixer elements
- */
-static struct sbmix_elem snd_dt019x_controls[] = {
- /* ALS4000 below has some parts which we might be lacking,
- * e.g. snd_als4000_ctl_mono_playback_switch - check it! */
- SB_DOUBLE("Master Playback Volume",
- SB_DT019X_MASTER_DEV, SB_DT019X_MASTER_DEV, 4, 0, 15),
- SB_DOUBLE("PCM Playback Switch",
- SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 2, 1, 1),
- SB_DOUBLE("PCM Playback Volume",
- SB_DT019X_PCM_DEV, SB_DT019X_PCM_DEV, 4, 0, 15),
- SB_DOUBLE("Synth Playback Switch",
- SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 4, 3, 1),
- SB_DOUBLE("Synth Playback Volume",
- SB_DT019X_SYNTH_DEV, SB_DT019X_SYNTH_DEV, 4, 0, 15),
- SB_DOUBLE("CD Playback Switch",
- SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1),
- SB_DOUBLE("CD Playback Volume",
- SB_DT019X_CD_DEV, SB_DT019X_CD_DEV, 4, 0, 15),
- SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1),
- SB_SINGLE("Mic Playback Volume", SB_DT019X_MIC_DEV, 4, 7),
- SB_SINGLE("Beep Volume", SB_DT019X_SPKR_DEV, 0, 7),
- SB_DOUBLE("Line Playback Switch",
- SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1),
- SB_DOUBLE("Line Playback Volume",
- SB_DT019X_LINE_DEV, SB_DT019X_LINE_DEV, 4, 0, 15),
- {
- .name = "Capture Source",
- .type = SB_MIX_CAPTURE_DT019X
- }
-};
-
-static unsigned char snd_dt019x_init_values[][2] = {
- { SB_DT019X_MASTER_DEV, 0 },
- { SB_DT019X_PCM_DEV, 0 },
- { SB_DT019X_SYNTH_DEV, 0 },
- { SB_DT019X_CD_DEV, 0 },
- { SB_DT019X_MIC_DEV, 0 }, /* Includes PC-speaker in high nibble */
- { SB_DT019X_LINE_DEV, 0 },
- { SB_DSP4_OUTPUT_SW, 0 },
- { SB_DT019X_OUTPUT_SW2, 0 },
- { SB_DT019X_CAPTURE_SW, 0x06 },
-};
-
-/*
- * ALS4000 specific mixer elements
- */
-static struct sbmix_elem snd_als4000_controls[] = {
- SB_DOUBLE("PCM Playback Switch",
- SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 2, 1, 1),
- SB_DOUBLE("Synth Playback Switch",
- SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 4, 3, 1),
- SB_SINGLE("Mic Boost (+20dB)", SB_ALS4000_MIC_IN_GAIN, 0, 0x03),
- SB_SINGLE("Master Mono Playback Switch", SB_ALS4000_MONO_IO_CTRL, 5, 1),
- {
- .name = "Master Mono Capture Route",
- .type = SB_MIX_MONO_CAPTURE_ALS4K
- },
- SB_SINGLE("Mono Playback Switch", SB_DT019X_OUTPUT_SW2, 0, 1),
- SB_SINGLE("Analog Loopback Switch", SB_ALS4000_MIC_IN_GAIN, 7, 0x01),
- SB_SINGLE("3D Control - Switch", SB_ALS4000_3D_SND_FX, 6, 0x01),
- SB_SINGLE("Digital Loopback Switch",
- SB_ALS4000_CR3_CONFIGURATION, 7, 0x01),
- /* FIXME: functionality of 3D controls might be swapped, I didn't find
- * a description of how to identify what is supposed to be what */
- SB_SINGLE("3D Control - Level", SB_ALS4000_3D_SND_FX, 0, 0x07),
- /* FIXME: maybe there's actually some standard 3D ctrl name for it?? */
- SB_SINGLE("3D Control - Freq", SB_ALS4000_3D_SND_FX, 4, 0x03),
- /* FIXME: ALS4000a.pdf mentions BBD (Bucket Brigade Device) time delay,
- * but what ALSA 3D attribute is that actually? "Center", "Depth",
- * "Wide" or "Space" or even "Level"? Assuming "Wide" for now... */
- SB_SINGLE("3D Control - Wide", SB_ALS4000_3D_TIME_DELAY, 0, 0x0f),
- SB_SINGLE("3D PowerOff Switch", SB_ALS4000_3D_TIME_DELAY, 4, 0x01),
- SB_SINGLE("Master Playback 8kHz / 20kHz LPF Switch",
- SB_ALS4000_FMDAC, 5, 0x01),
-#ifdef NOT_AVAILABLE
- SB_SINGLE("FMDAC Switch (Option ?)", SB_ALS4000_FMDAC, 0, 0x01),
- SB_SINGLE("QSound Mode", SB_ALS4000_QSOUND, 1, 0x1f),
-#endif
-};
-
-static unsigned char snd_als4000_init_values[][2] = {
- { SB_DSP4_MASTER_DEV + 0, 0 },
- { SB_DSP4_MASTER_DEV + 1, 0 },
- { SB_DSP4_PCM_DEV + 0, 0 },
- { SB_DSP4_PCM_DEV + 1, 0 },
- { SB_DSP4_SYNTH_DEV + 0, 0 },
- { SB_DSP4_SYNTH_DEV + 1, 0 },
- { SB_DSP4_SPEAKER_DEV, 0 },
- { SB_DSP4_OUTPUT_SW, 0 },
- { SB_DSP4_INPUT_LEFT, 0 },
- { SB_DSP4_INPUT_RIGHT, 0 },
- { SB_DT019X_OUTPUT_SW2, 0 },
- { SB_ALS4000_MIC_IN_GAIN, 0 },
-};
-
-/*
- */
-static int snd_sbmixer_init(struct snd_sb *chip,
- struct sbmix_elem *controls,
- int controls_count,
- unsigned char map[][2],
- int map_count,
- char *name)
-{
- unsigned long flags;
- struct snd_card *card = chip->card;
- int idx, err;
-
- /* mixer reset */
- spin_lock_irqsave(&chip->mixer_lock, flags);
- snd_sbmixer_write(chip, 0x00, 0x00);
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
-
- /* mute and zero volume channels */
- for (idx = 0; idx < map_count; idx++) {
- spin_lock_irqsave(&chip->mixer_lock, flags);
- snd_sbmixer_write(chip, map[idx][0], map[idx][1]);
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
- }
-
- for (idx = 0; idx < controls_count; idx++) {
- err = snd_sbmixer_add_ctl_elem(chip, &controls[idx]);
- if (err < 0)
- return err;
- }
- snd_component_add(card, name);
- strcpy(card->mixername, name);
- return 0;
-}
-
-int snd_sbmixer_new(struct snd_sb *chip)
-{
- struct snd_card *card;
- int err;
-
- if (snd_BUG_ON(!chip || !chip->card))
- return -EINVAL;
-
- card = chip->card;
-
- switch (chip->hardware) {
- case SB_HW_10:
- return 0; /* no mixer chip on SB1.x */
- case SB_HW_20:
- case SB_HW_201:
- if ((err = snd_sbmixer_init(chip,
- snd_sb20_controls,
- ARRAY_SIZE(snd_sb20_controls),
- snd_sb20_init_values,
- ARRAY_SIZE(snd_sb20_init_values),
- "CTL1335")) < 0)
- return err;
- break;
- case SB_HW_PRO:
- case SB_HW_JAZZ16:
- if ((err = snd_sbmixer_init(chip,
- snd_sbpro_controls,
- ARRAY_SIZE(snd_sbpro_controls),
- snd_sbpro_init_values,
- ARRAY_SIZE(snd_sbpro_init_values),
- "CTL1345")) < 0)
- return err;
- break;
- case SB_HW_16:
- case SB_HW_ALS100:
- case SB_HW_CS5530:
- if ((err = snd_sbmixer_init(chip,
- snd_sb16_controls,
- ARRAY_SIZE(snd_sb16_controls),
- snd_sb16_init_values,
- ARRAY_SIZE(snd_sb16_init_values),
- "CTL1745")) < 0)
- return err;
- break;
- case SB_HW_ALS4000:
- /* use only the first 16 controls from SB16 */
- err = snd_sbmixer_init(chip,
- snd_sb16_controls,
- 16,
- snd_sb16_init_values,
- ARRAY_SIZE(snd_sb16_init_values),
- "ALS4000");
- if (err < 0)
- return err;
- if ((err = snd_sbmixer_init(chip,
- snd_als4000_controls,
- ARRAY_SIZE(snd_als4000_controls),
- snd_als4000_init_values,
- ARRAY_SIZE(snd_als4000_init_values),
- "ALS4000")) < 0)
- return err;
- break;
- case SB_HW_DT019X:
- if ((err = snd_sbmixer_init(chip,
- snd_dt019x_controls,
- ARRAY_SIZE(snd_dt019x_controls),
- snd_dt019x_init_values,
- ARRAY_SIZE(snd_dt019x_init_values),
- "DT019X")) < 0)
- break;
- default:
- strcpy(card->mixername, "???");
- }
- return 0;
-}
-
-#ifdef CONFIG_PM
-static unsigned char sb20_saved_regs[] = {
- SB_DSP20_MASTER_DEV,
- SB_DSP20_PCM_DEV,
- SB_DSP20_FM_DEV,
- SB_DSP20_CD_DEV,
-};
-
-static unsigned char sbpro_saved_regs[] = {
- SB_DSP_MASTER_DEV,
- SB_DSP_PCM_DEV,
- SB_DSP_PLAYBACK_FILT,
- SB_DSP_FM_DEV,
- SB_DSP_CD_DEV,
- SB_DSP_LINE_DEV,
- SB_DSP_MIC_DEV,
- SB_DSP_CAPTURE_SOURCE,
- SB_DSP_CAPTURE_FILT,
-};
-
-static unsigned char sb16_saved_regs[] = {
- SB_DSP4_MASTER_DEV, SB_DSP4_MASTER_DEV + 1,
- SB_DSP4_3DSE,
- SB_DSP4_BASS_DEV, SB_DSP4_BASS_DEV + 1,
- SB_DSP4_TREBLE_DEV, SB_DSP4_TREBLE_DEV + 1,
- SB_DSP4_PCM_DEV, SB_DSP4_PCM_DEV + 1,
- SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT,
- SB_DSP4_SYNTH_DEV, SB_DSP4_SYNTH_DEV + 1,
- SB_DSP4_OUTPUT_SW,
- SB_DSP4_CD_DEV, SB_DSP4_CD_DEV + 1,
- SB_DSP4_LINE_DEV, SB_DSP4_LINE_DEV + 1,
- SB_DSP4_MIC_DEV,
- SB_DSP4_SPEAKER_DEV,
- SB_DSP4_IGAIN_DEV, SB_DSP4_IGAIN_DEV + 1,
- SB_DSP4_OGAIN_DEV, SB_DSP4_OGAIN_DEV + 1,
- SB_DSP4_MIC_AGC
-};
-
-static unsigned char dt019x_saved_regs[] = {
- SB_DT019X_MASTER_DEV,
- SB_DT019X_PCM_DEV,
- SB_DT019X_SYNTH_DEV,
- SB_DT019X_CD_DEV,
- SB_DT019X_MIC_DEV,
- SB_DT019X_SPKR_DEV,
- SB_DT019X_LINE_DEV,
- SB_DSP4_OUTPUT_SW,
- SB_DT019X_OUTPUT_SW2,
- SB_DT019X_CAPTURE_SW,
-};
-
-static unsigned char als4000_saved_regs[] = {
- /* please verify in dsheet whether regs to be added
- are actually real H/W or just dummy */
- SB_DSP4_MASTER_DEV, SB_DSP4_MASTER_DEV + 1,
- SB_DSP4_OUTPUT_SW,
- SB_DSP4_PCM_DEV, SB_DSP4_PCM_DEV + 1,
- SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT,
- SB_DSP4_SYNTH_DEV, SB_DSP4_SYNTH_DEV + 1,
- SB_DSP4_CD_DEV, SB_DSP4_CD_DEV + 1,
- SB_DSP4_MIC_DEV,
- SB_DSP4_SPEAKER_DEV,
- SB_DSP4_IGAIN_DEV, SB_DSP4_IGAIN_DEV + 1,
- SB_DSP4_OGAIN_DEV, SB_DSP4_OGAIN_DEV + 1,
- SB_DT019X_OUTPUT_SW2,
- SB_ALS4000_MONO_IO_CTRL,
- SB_ALS4000_MIC_IN_GAIN,
- SB_ALS4000_FMDAC,
- SB_ALS4000_3D_SND_FX,
- SB_ALS4000_3D_TIME_DELAY,
- SB_ALS4000_CR3_CONFIGURATION,
-};
-
-static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs)
-{
- unsigned char *val = chip->saved_regs;
- if (snd_BUG_ON(num_regs > ARRAY_SIZE(chip->saved_regs)))
- return;
- for (; num_regs; num_regs--)
- *val++ = snd_sbmixer_read(chip, *regs++);
-}
-
-static void restore_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs)
-{
- unsigned char *val = chip->saved_regs;
- if (snd_BUG_ON(num_regs > ARRAY_SIZE(chip->saved_regs)))
- return;
- for (; num_regs; num_regs--)
- snd_sbmixer_write(chip, *regs++, *val++);
-}
-
-void snd_sbmixer_suspend(struct snd_sb *chip)
-{
- switch (chip->hardware) {
- case SB_HW_20:
- case SB_HW_201:
- save_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs));
- break;
- case SB_HW_PRO:
- case SB_HW_JAZZ16:
- save_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs));
- break;
- case SB_HW_16:
- case SB_HW_ALS100:
- case SB_HW_CS5530:
- save_mixer(chip, sb16_saved_regs, ARRAY_SIZE(sb16_saved_regs));
- break;
- case SB_HW_ALS4000:
- save_mixer(chip, als4000_saved_regs, ARRAY_SIZE(als4000_saved_regs));
- break;
- case SB_HW_DT019X:
- save_mixer(chip, dt019x_saved_regs, ARRAY_SIZE(dt019x_saved_regs));
- break;
- default:
- break;
- }
-}
-
-void snd_sbmixer_resume(struct snd_sb *chip)
-{
- switch (chip->hardware) {
- case SB_HW_20:
- case SB_HW_201:
- restore_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs));
- break;
- case SB_HW_PRO:
- case SB_HW_JAZZ16:
- restore_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs));
- break;
- case SB_HW_16:
- case SB_HW_ALS100:
- case SB_HW_CS5530:
- restore_mixer(chip, sb16_saved_regs, ARRAY_SIZE(sb16_saved_regs));
- break;
- case SB_HW_ALS4000:
- restore_mixer(chip, als4000_saved_regs, ARRAY_SIZE(als4000_saved_regs));
- break;
- case SB_HW_DT019X:
- restore_mixer(chip, dt019x_saved_regs, ARRAY_SIZE(dt019x_saved_regs));
- break;
- default:
- break;
- }
-}
-#endif
diff --git a/ANDROID_3.4.5/sound/isa/sb/sbawe.c b/ANDROID_3.4.5/sound/isa/sb/sbawe.c
deleted file mode 100644
index 2ec52a34..00000000
--- a/ANDROID_3.4.5/sound/isa/sb/sbawe.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define SNDRV_SBAWE
-#include "sb16.c"
diff --git a/ANDROID_3.4.5/sound/isa/sc6000.c b/ANDROID_3.4.5/sound/isa/sc6000.c
deleted file mode 100644
index d97d0f38..00000000
--- a/ANDROID_3.4.5/sound/isa/sc6000.c
+++ /dev/null
@@ -1,728 +0,0 @@
-/*
- * Driver for Gallant SC-6000 soundcard. This card is also known as
- * Audio Excel DSP 16 or Zoltrix AV302.
- * These cards use CompuMedia ASC-9308 chip + AD1848 codec.
- * SC-6600 and SC-7000 cards are also supported. They are based on
- * CompuMedia ASC-9408 chip and CS4231 codec.
- *
- * Copyright (C) 2007 Krzysztof Helt <krzysztof.h1@wp.pl>
- *
- * I don't have documentation for this card. I used the driver
- * for OSS/Free included in the kernel source as reference.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/isa.h>
-#include <linux/io.h>
-#include <asm/dma.h>
-#include <sound/core.h>
-#include <sound/wss.h>
-#include <sound/opl3.h>
-#include <sound/mpu401.h>
-#include <sound/control.h>
-#define SNDRV_LEGACY_FIND_FREE_IRQ
-#define SNDRV_LEGACY_FIND_FREE_DMA
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Krzysztof Helt");
-MODULE_DESCRIPTION("Gallant SC-6000");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Gallant, SC-6000},"
- "{AudioExcel, Audio Excel DSP 16},"
- "{Zoltrix, AV302}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220, 0x240 */
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5, 7, 9, 10, 11 */
-static long mss_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x530, 0xe80 */
-static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
- /* 0x300, 0x310, 0x320, 0x330 */
-static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5, 7, 9, 10, 0 */
-static int dma[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0, 1, 3 */
-static bool joystick[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = false };
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for sc-6000 based soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for sc-6000 based soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable sc-6000 based soundcard.");
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for sc-6000 driver.");
-module_param_array(mss_port, long, NULL, 0444);
-MODULE_PARM_DESC(mss_port, "MSS Port # for sc-6000 driver.");
-module_param_array(mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port # for sc-6000 driver.");
-module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for sc-6000 driver.");
-module_param_array(mpu_irq, int, NULL, 0444);
-MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for sc-6000 driver.");
-module_param_array(dma, int, NULL, 0444);
-MODULE_PARM_DESC(dma, "DMA # for sc-6000 driver.");
-module_param_array(joystick, bool, NULL, 0444);
-MODULE_PARM_DESC(joystick, "Enable gameport.");
-
-/*
- * Commands of SC6000's DSP (SBPRO+special).
- * Some of them are COMMAND_xx, in the future they may change.
- */
-#define WRITE_MDIRQ_CFG 0x50 /* Set M&I&DRQ mask (the real config) */
-#define COMMAND_52 0x52 /* */
-#define READ_HARD_CFG 0x58 /* Read Hardware Config (I/O base etc) */
-#define COMMAND_5C 0x5c /* */
-#define COMMAND_60 0x60 /* */
-#define COMMAND_66 0x66 /* */
-#define COMMAND_6C 0x6c /* */
-#define COMMAND_6E 0x6e /* */
-#define COMMAND_88 0x88 /* Unknown command */
-#define DSP_INIT_MSS 0x8c /* Enable Microsoft Sound System mode */
-#define COMMAND_C5 0xc5 /* */
-#define GET_DSP_VERSION 0xe1 /* Get DSP Version */
-#define GET_DSP_COPYRIGHT 0xe3 /* Get DSP Copyright */
-
-/*
- * Offsets of SC6000 DSP I/O ports. The offset is added to base I/O port
- * to have the actual I/O port.
- * Register permissions are:
- * (wo) == Write Only
- * (ro) == Read Only
- * (w-) == Write
- * (r-) == Read
- */
-#define DSP_RESET 0x06 /* offset of DSP RESET (wo) */
-#define DSP_READ 0x0a /* offset of DSP READ (ro) */
-#define DSP_WRITE 0x0c /* offset of DSP WRITE (w-) */
-#define DSP_COMMAND 0x0c /* offset of DSP COMMAND (w-) */
-#define DSP_STATUS 0x0c /* offset of DSP STATUS (r-) */
-#define DSP_DATAVAIL 0x0e /* offset of DSP DATA AVAILABLE (ro) */
-
-#define PFX "sc6000: "
-#define DRV_NAME "SC-6000"
-
-/* hardware dependent functions */
-
-/*
- * sc6000_irq_to_softcfg - Decode irq number into cfg code.
- */
-static __devinit unsigned char sc6000_irq_to_softcfg(int irq)
-{
- unsigned char val = 0;
-
- switch (irq) {
- case 5:
- val = 0x28;
- break;
- case 7:
- val = 0x8;
- break;
- case 9:
- val = 0x10;
- break;
- case 10:
- val = 0x18;
- break;
- case 11:
- val = 0x20;
- break;
- default:
- break;
- }
- return val;
-}
-
-/*
- * sc6000_dma_to_softcfg - Decode dma number into cfg code.
- */
-static __devinit unsigned char sc6000_dma_to_softcfg(int dma)
-{
- unsigned char val = 0;
-
- switch (dma) {
- case 0:
- val = 1;
- break;
- case 1:
- val = 2;
- break;
- case 3:
- val = 3;
- break;
- default:
- break;
- }
- return val;
-}
-
-/*
- * sc6000_mpu_irq_to_softcfg - Decode MPU-401 irq number into cfg code.
- */
-static __devinit unsigned char sc6000_mpu_irq_to_softcfg(int mpu_irq)
-{
- unsigned char val = 0;
-
- switch (mpu_irq) {
- case 5:
- val = 4;
- break;
- case 7:
- val = 0x44;
- break;
- case 9:
- val = 0x84;
- break;
- case 10:
- val = 0xc4;
- break;
- default:
- break;
- }
- return val;
-}
-
-static int sc6000_wait_data(char __iomem *vport)
-{
- int loop = 1000;
- unsigned char val = 0;
-
- do {
- val = ioread8(vport + DSP_DATAVAIL);
- if (val & 0x80)
- return 0;
- cpu_relax();
- } while (loop--);
-
- return -EAGAIN;
-}
-
-static int sc6000_read(char __iomem *vport)
-{
- if (sc6000_wait_data(vport))
- return -EBUSY;
-
- return ioread8(vport + DSP_READ);
-
-}
-
-static int sc6000_write(char __iomem *vport, int cmd)
-{
- unsigned char val;
- int loop = 500000;
-
- do {
- val = ioread8(vport + DSP_STATUS);
- /*
- * DSP ready to receive data if bit 7 of val == 0
- */
- if (!(val & 0x80)) {
- iowrite8(cmd, vport + DSP_COMMAND);
- return 0;
- }
- cpu_relax();
- } while (loop--);
-
- snd_printk(KERN_ERR "DSP Command (0x%x) timeout.\n", cmd);
-
- return -EIO;
-}
-
-static int __devinit sc6000_dsp_get_answer(char __iomem *vport, int command,
- char *data, int data_len)
-{
- int len = 0;
-
- if (sc6000_write(vport, command)) {
- snd_printk(KERN_ERR "CMD 0x%x: failed!\n", command);
- return -EIO;
- }
-
- do {
- int val = sc6000_read(vport);
-
- if (val < 0)
- break;
-
- data[len++] = val;
-
- } while (len < data_len);
-
- /*
- * If no more data available, return to the caller, no error if len>0.
- * We have no other way to know when the string is finished.
- */
- return len ? len : -EIO;
-}
-
-static int __devinit sc6000_dsp_reset(char __iomem *vport)
-{
- iowrite8(1, vport + DSP_RESET);
- udelay(10);
- iowrite8(0, vport + DSP_RESET);
- udelay(20);
- if (sc6000_read(vport) == 0xaa)
- return 0;
- return -ENODEV;
-}
-
-/* detection and initialization */
-static int __devinit sc6000_hw_cfg_write(char __iomem *vport, const int *cfg)
-{
- if (sc6000_write(vport, COMMAND_6C) < 0) {
- snd_printk(KERN_WARNING "CMD 0x%x: failed!\n", COMMAND_6C);
- return -EIO;
- }
- if (sc6000_write(vport, COMMAND_5C) < 0) {
- snd_printk(KERN_ERR "CMD 0x%x: failed!\n", COMMAND_5C);
- return -EIO;
- }
- if (sc6000_write(vport, cfg[0]) < 0) {
- snd_printk(KERN_ERR "DATA 0x%x: failed!\n", cfg[0]);
- return -EIO;
- }
- if (sc6000_write(vport, cfg[1]) < 0) {
- snd_printk(KERN_ERR "DATA 0x%x: failed!\n", cfg[1]);
- return -EIO;
- }
- if (sc6000_write(vport, COMMAND_C5) < 0) {
- snd_printk(KERN_ERR "CMD 0x%x: failed!\n", COMMAND_C5);
- return -EIO;
- }
-
- return 0;
-}
-
-static int sc6000_cfg_write(char __iomem *vport, unsigned char softcfg)
-{
-
- if (sc6000_write(vport, WRITE_MDIRQ_CFG)) {
- snd_printk(KERN_ERR "CMD 0x%x: failed!\n", WRITE_MDIRQ_CFG);
- return -EIO;
- }
- if (sc6000_write(vport, softcfg)) {
- snd_printk(KERN_ERR "sc6000_cfg_write: failed!\n");
- return -EIO;
- }
- return 0;
-}
-
-static int sc6000_setup_board(char __iomem *vport, int config)
-{
- int loop = 10;
-
- do {
- if (sc6000_write(vport, COMMAND_88)) {
- snd_printk(KERN_ERR "CMD 0x%x: failed!\n",
- COMMAND_88);
- return -EIO;
- }
- } while ((sc6000_wait_data(vport) < 0) && loop--);
-
- if (sc6000_read(vport) < 0) {
- snd_printk(KERN_ERR "sc6000_read after CMD 0x%x: failed\n",
- COMMAND_88);
- return -EIO;
- }
-
- if (sc6000_cfg_write(vport, config))
- return -ENODEV;
-
- return 0;
-}
-
-static int __devinit sc6000_init_mss(char __iomem *vport, int config,
- char __iomem *vmss_port, int mss_config)
-{
- if (sc6000_write(vport, DSP_INIT_MSS)) {
- snd_printk(KERN_ERR "sc6000_init_mss [0x%x]: failed!\n",
- DSP_INIT_MSS);
- return -EIO;
- }
-
- msleep(10);
-
- if (sc6000_cfg_write(vport, config))
- return -EIO;
-
- iowrite8(mss_config, vmss_port);
-
- return 0;
-}
-
-static void __devinit sc6000_hw_cfg_encode(char __iomem *vport, int *cfg,
- long xport, long xmpu,
- long xmss_port, int joystick)
-{
- cfg[0] = 0;
- cfg[1] = 0;
- if (xport == 0x240)
- cfg[0] |= 1;
- if (xmpu != SNDRV_AUTO_PORT) {
- cfg[0] |= (xmpu & 0x30) >> 2;
- cfg[1] |= 0x20;
- }
- if (xmss_port == 0xe80)
- cfg[0] |= 0x10;
- cfg[0] |= 0x40; /* always set */
- if (!joystick)
- cfg[0] |= 0x02;
- cfg[1] |= 0x80; /* enable WSS system */
- cfg[1] &= ~0x40; /* disable IDE */
- snd_printd("hw cfg %x, %x\n", cfg[0], cfg[1]);
-}
-
-static int __devinit sc6000_init_board(char __iomem *vport,
- char __iomem *vmss_port, int dev)
-{
- char answer[15];
- char version[2];
- int mss_config = sc6000_irq_to_softcfg(irq[dev]) |
- sc6000_dma_to_softcfg(dma[dev]);
- int config = mss_config |
- sc6000_mpu_irq_to_softcfg(mpu_irq[dev]);
- int err;
- int old = 0;
-
- err = sc6000_dsp_reset(vport);
- if (err < 0) {
- snd_printk(KERN_ERR "sc6000_dsp_reset: failed!\n");
- return err;
- }
-
- memset(answer, 0, sizeof(answer));
- err = sc6000_dsp_get_answer(vport, GET_DSP_COPYRIGHT, answer, 15);
- if (err <= 0) {
- snd_printk(KERN_ERR "sc6000_dsp_copyright: failed!\n");
- return -ENODEV;
- }
- /*
- * My SC-6000 card return "SC-6000" in DSPCopyright, so
- * if we have something different, we have to be warned.
- */
- if (strncmp("SC-6000", answer, 7))
- snd_printk(KERN_WARNING "Warning: non SC-6000 audio card!\n");
-
- if (sc6000_dsp_get_answer(vport, GET_DSP_VERSION, version, 2) < 2) {
- snd_printk(KERN_ERR "sc6000_dsp_version: failed!\n");
- return -ENODEV;
- }
- printk(KERN_INFO PFX "Detected model: %s, DSP version %d.%d\n",
- answer, version[0], version[1]);
-
- /* set configuration */
- sc6000_write(vport, COMMAND_5C);
- if (sc6000_read(vport) < 0)
- old = 1;
-
- if (!old) {
- int cfg[2];
- sc6000_hw_cfg_encode(vport, &cfg[0], port[dev], mpu_port[dev],
- mss_port[dev], joystick[dev]);
- if (sc6000_hw_cfg_write(vport, cfg) < 0) {
- snd_printk(KERN_ERR "sc6000_hw_cfg_write: failed!\n");
- return -EIO;
- }
- }
- err = sc6000_setup_board(vport, config);
- if (err < 0) {
- snd_printk(KERN_ERR "sc6000_setup_board: failed!\n");
- return -ENODEV;
- }
-
- sc6000_dsp_reset(vport);
-
- if (!old) {
- sc6000_write(vport, COMMAND_60);
- sc6000_write(vport, 0x02);
- sc6000_dsp_reset(vport);
- }
-
- err = sc6000_setup_board(vport, config);
- if (err < 0) {
- snd_printk(KERN_ERR "sc6000_setup_board: failed!\n");
- return -ENODEV;
- }
- err = sc6000_init_mss(vport, config, vmss_port, mss_config);
- if (err < 0) {
- snd_printk(KERN_ERR "Cannot initialize "
- "Microsoft Sound System mode.\n");
- return -ENODEV;
- }
-
- return 0;
-}
-
-static int __devinit snd_sc6000_mixer(struct snd_wss *chip)
-{
- struct snd_card *card = chip->card;
- struct snd_ctl_elem_id id1, id2;
- int err;
-
- memset(&id1, 0, sizeof(id1));
- memset(&id2, 0, sizeof(id2));
- id1.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- /* reassign AUX0 to FM */
- strcpy(id1.name, "Aux Playback Switch");
- strcpy(id2.name, "FM Playback Switch");
- err = snd_ctl_rename_id(card, &id1, &id2);
- if (err < 0)
- return err;
- strcpy(id1.name, "Aux Playback Volume");
- strcpy(id2.name, "FM Playback Volume");
- err = snd_ctl_rename_id(card, &id1, &id2);
- if (err < 0)
- return err;
- /* reassign AUX1 to CD */
- strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
- strcpy(id2.name, "CD Playback Switch");
- err = snd_ctl_rename_id(card, &id1, &id2);
- if (err < 0)
- return err;
- strcpy(id1.name, "Aux Playback Volume");
- strcpy(id2.name, "CD Playback Volume");
- err = snd_ctl_rename_id(card, &id1, &id2);
- if (err < 0)
- return err;
- return 0;
-}
-
-static int __devinit snd_sc6000_match(struct device *devptr, unsigned int dev)
-{
- if (!enable[dev])
- return 0;
- if (port[dev] == SNDRV_AUTO_PORT) {
- printk(KERN_ERR PFX "specify IO port\n");
- return 0;
- }
- if (mss_port[dev] == SNDRV_AUTO_PORT) {
- printk(KERN_ERR PFX "specify MSS port\n");
- return 0;
- }
- if (port[dev] != 0x220 && port[dev] != 0x240) {
- printk(KERN_ERR PFX "Port must be 0x220 or 0x240\n");
- return 0;
- }
- if (mss_port[dev] != 0x530 && mss_port[dev] != 0xe80) {
- printk(KERN_ERR PFX "MSS port must be 0x530 or 0xe80\n");
- return 0;
- }
- if (irq[dev] != SNDRV_AUTO_IRQ && !sc6000_irq_to_softcfg(irq[dev])) {
- printk(KERN_ERR PFX "invalid IRQ %d\n", irq[dev]);
- return 0;
- }
- if (dma[dev] != SNDRV_AUTO_DMA && !sc6000_dma_to_softcfg(dma[dev])) {
- printk(KERN_ERR PFX "invalid DMA %d\n", dma[dev]);
- return 0;
- }
- if (mpu_port[dev] != SNDRV_AUTO_PORT &&
- (mpu_port[dev] & ~0x30L) != 0x300) {
- printk(KERN_ERR PFX "invalid MPU-401 port %lx\n",
- mpu_port[dev]);
- return 0;
- }
- if (mpu_port[dev] != SNDRV_AUTO_PORT &&
- mpu_irq[dev] != SNDRV_AUTO_IRQ && mpu_irq[dev] != 0 &&
- !sc6000_mpu_irq_to_softcfg(mpu_irq[dev])) {
- printk(KERN_ERR PFX "invalid MPU-401 IRQ %d\n", mpu_irq[dev]);
- return 0;
- }
- return 1;
-}
-
-static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
-{
- static int possible_irqs[] = { 5, 7, 9, 10, 11, -1 };
- static int possible_dmas[] = { 1, 3, 0, -1 };
- int err;
- int xirq = irq[dev];
- int xdma = dma[dev];
- struct snd_card *card;
- struct snd_wss *chip;
- struct snd_opl3 *opl3;
- char __iomem **vport;
- char __iomem *vmss_port;
-
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, sizeof(vport),
- &card);
- if (err < 0)
- return err;
-
- vport = card->private_data;
- if (xirq == SNDRV_AUTO_IRQ) {
- xirq = snd_legacy_find_free_irq(possible_irqs);
- if (xirq < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
- err = -EBUSY;
- goto err_exit;
- }
- }
-
- if (xdma == SNDRV_AUTO_DMA) {
- xdma = snd_legacy_find_free_dma(possible_dmas);
- if (xdma < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free DMA\n");
- err = -EBUSY;
- goto err_exit;
- }
- }
-
- if (!request_region(port[dev], 0x10, DRV_NAME)) {
- snd_printk(KERN_ERR PFX
- "I/O port region is already in use.\n");
- err = -EBUSY;
- goto err_exit;
- }
- *vport = devm_ioport_map(devptr, port[dev], 0x10);
- if (*vport == NULL) {
- snd_printk(KERN_ERR PFX
- "I/O port cannot be iomaped.\n");
- err = -EBUSY;
- goto err_unmap1;
- }
-
- /* to make it marked as used */
- if (!request_region(mss_port[dev], 4, DRV_NAME)) {
- snd_printk(KERN_ERR PFX
- "SC-6000 port I/O port region is already in use.\n");
- err = -EBUSY;
- goto err_unmap1;
- }
- vmss_port = devm_ioport_map(devptr, mss_port[dev], 4);
- if (!vmss_port) {
- snd_printk(KERN_ERR PFX
- "MSS port I/O cannot be iomaped.\n");
- err = -EBUSY;
- goto err_unmap2;
- }
-
- snd_printd("Initializing BASE[0x%lx] IRQ[%d] DMA[%d] MIRQ[%d]\n",
- port[dev], xirq, xdma,
- mpu_irq[dev] == SNDRV_AUTO_IRQ ? 0 : mpu_irq[dev]);
-
- err = sc6000_init_board(*vport, vmss_port, dev);
- if (err < 0)
- goto err_unmap2;
-
- err = snd_wss_create(card, mss_port[dev] + 4, -1, xirq, xdma, -1,
- WSS_HW_DETECT, 0, &chip);
- if (err < 0)
- goto err_unmap2;
-
- err = snd_wss_pcm(chip, 0, NULL);
- if (err < 0) {
- snd_printk(KERN_ERR PFX
- "error creating new WSS PCM device\n");
- goto err_unmap2;
- }
- err = snd_wss_mixer(chip);
- if (err < 0) {
- snd_printk(KERN_ERR PFX "error creating new WSS mixer\n");
- goto err_unmap2;
- }
- err = snd_sc6000_mixer(chip);
- if (err < 0) {
- snd_printk(KERN_ERR PFX "the mixer rewrite failed\n");
- goto err_unmap2;
- }
- if (snd_opl3_create(card,
- 0x388, 0x388 + 2,
- OPL3_HW_AUTO, 0, &opl3) < 0) {
- snd_printk(KERN_ERR PFX "no OPL device at 0x%x-0x%x ?\n",
- 0x388, 0x388 + 2);
- } else {
- err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
- if (err < 0)
- goto err_unmap2;
- }
-
- if (mpu_port[dev] != SNDRV_AUTO_PORT) {
- if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
- mpu_irq[dev] = -1;
- if (snd_mpu401_uart_new(card, 0,
- MPU401_HW_MPU401,
- mpu_port[dev], 0,
- mpu_irq[dev], NULL) < 0)
- snd_printk(KERN_ERR "no MPU-401 device at 0x%lx ?\n",
- mpu_port[dev]);
- }
-
- strcpy(card->driver, DRV_NAME);
- strcpy(card->shortname, "SC-6000");
- sprintf(card->longname, "Gallant SC-6000 at 0x%lx, irq %d, dma %d",
- mss_port[dev], xirq, xdma);
-
- snd_card_set_dev(card, devptr);
-
- err = snd_card_register(card);
- if (err < 0)
- goto err_unmap2;
-
- dev_set_drvdata(devptr, card);
- return 0;
-
-err_unmap2:
- sc6000_setup_board(*vport, 0);
- release_region(mss_port[dev], 4);
-err_unmap1:
- release_region(port[dev], 0x10);
-err_exit:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit snd_sc6000_remove(struct device *devptr, unsigned int dev)
-{
- struct snd_card *card = dev_get_drvdata(devptr);
- char __iomem **vport = card->private_data;
-
- if (sc6000_setup_board(*vport, 0) < 0)
- snd_printk(KERN_WARNING "sc6000_setup_board failed on exit!\n");
-
- release_region(port[dev], 0x10);
- release_region(mss_port[dev], 4);
-
- dev_set_drvdata(devptr, NULL);
- snd_card_free(card);
- return 0;
-}
-
-static struct isa_driver snd_sc6000_driver = {
- .match = snd_sc6000_match,
- .probe = snd_sc6000_probe,
- .remove = __devexit_p(snd_sc6000_remove),
- /* FIXME: suspend/resume */
- .driver = {
- .name = DRV_NAME,
- },
-};
-
-
-static int __init alsa_card_sc6000_init(void)
-{
- return isa_register_driver(&snd_sc6000_driver, SNDRV_CARDS);
-}
-
-static void __exit alsa_card_sc6000_exit(void)
-{
- isa_unregister_driver(&snd_sc6000_driver);
-}
-
-module_init(alsa_card_sc6000_init)
-module_exit(alsa_card_sc6000_exit)
diff --git a/ANDROID_3.4.5/sound/isa/sscape.c b/ANDROID_3.4.5/sound/isa/sscape.c
deleted file mode 100644
index 8490f597..00000000
--- a/ANDROID_3.4.5/sound/isa/sscape.c
+++ /dev/null
@@ -1,1359 +0,0 @@
-/*
- * Low-level ALSA driver for the ENSONIQ SoundScape
- * Copyright (c) by Chris Rankin
- *
- * This driver was written in part using information obtained from
- * the OSS/Free SoundScape driver, written by Hannu Savolainen.
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/isa.h>
-#include <linux/delay.h>
-#include <linux/firmware.h>
-#include <linux/pnp.h>
-#include <linux/spinlock.h>
-#include <linux/module.h>
-#include <asm/dma.h>
-#include <sound/core.h>
-#include <sound/wss.h>
-#include <sound/mpu401.h>
-#include <sound/initval.h>
-
-
-MODULE_AUTHOR("Chris Rankin");
-MODULE_DESCRIPTION("ENSONIQ SoundScape driver");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE("sndscape.co0");
-MODULE_FIRMWARE("sndscape.co1");
-MODULE_FIRMWARE("sndscape.co2");
-MODULE_FIRMWARE("sndscape.co3");
-MODULE_FIRMWARE("sndscape.co4");
-MODULE_FIRMWARE("scope.cod");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-static long wss_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
-static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
-static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
-static int dma[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
-static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
-static bool joystick[SNDRV_CARDS];
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index number for SoundScape soundcard");
-
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "Description for SoundScape card");
-
-module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for SoundScape driver.");
-
-module_param_array(wss_port, long, NULL, 0444);
-MODULE_PARM_DESC(wss_port, "WSS Port # for SoundScape driver.");
-
-module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for SoundScape driver.");
-
-module_param_array(mpu_irq, int, NULL, 0444);
-MODULE_PARM_DESC(mpu_irq, "MPU401 IRQ # for SoundScape driver.");
-
-module_param_array(dma, int, NULL, 0444);
-MODULE_PARM_DESC(dma, "DMA # for SoundScape driver.");
-
-module_param_array(dma2, int, NULL, 0444);
-MODULE_PARM_DESC(dma2, "DMA2 # for SoundScape driver.");
-
-module_param_array(joystick, bool, NULL, 0444);
-MODULE_PARM_DESC(joystick, "Enable gameport.");
-
-#ifdef CONFIG_PNP
-static int isa_registered;
-static int pnp_registered;
-
-static struct pnp_card_device_id sscape_pnpids[] = {
- { .id = "ENS3081", .devs = { { "ENS0000" } } }, /* Soundscape PnP */
- { .id = "ENS4081", .devs = { { "ENS1011" } } }, /* VIVO90 */
- { .id = "" } /* end */
-};
-
-MODULE_DEVICE_TABLE(pnp_card, sscape_pnpids);
-#endif
-
-
-#define HOST_CTRL_IO(i) ((i) + 2)
-#define HOST_DATA_IO(i) ((i) + 3)
-#define ODIE_ADDR_IO(i) ((i) + 4)
-#define ODIE_DATA_IO(i) ((i) + 5)
-#define CODEC_IO(i) ((i) + 8)
-
-#define IC_ODIE 1
-#define IC_OPUS 2
-
-#define RX_READY 0x01
-#define TX_READY 0x02
-
-#define CMD_ACK 0x80
-#define CMD_SET_MIDI_VOL 0x84
-#define CMD_GET_MIDI_VOL 0x85
-#define CMD_XXX_MIDI_VOL 0x86
-#define CMD_SET_EXTMIDI 0x8a
-#define CMD_GET_EXTMIDI 0x8b
-#define CMD_SET_MT32 0x8c
-#define CMD_GET_MT32 0x8d
-
-enum GA_REG {
- GA_INTSTAT_REG = 0,
- GA_INTENA_REG,
- GA_DMAA_REG,
- GA_DMAB_REG,
- GA_INTCFG_REG,
- GA_DMACFG_REG,
- GA_CDCFG_REG,
- GA_SMCFGA_REG,
- GA_SMCFGB_REG,
- GA_HMCTL_REG
-};
-
-#define DMA_8BIT 0x80
-
-
-enum card_type {
- MEDIA_FX, /* Sequoia S-1000 */
- SSCAPE, /* Sequoia S-2000 */
- SSCAPE_PNP,
- SSCAPE_VIVO,
-};
-
-struct soundscape {
- spinlock_t lock;
- unsigned io_base;
- int ic_type;
- enum card_type type;
- struct resource *io_res;
- struct resource *wss_res;
- struct snd_wss *chip;
-
- unsigned char midi_vol;
-};
-
-#define INVALID_IRQ ((unsigned)-1)
-
-
-static inline struct soundscape *get_card_soundscape(struct snd_card *c)
-{
- return (struct soundscape *) (c->private_data);
-}
-
-/*
- * Allocates some kernel memory that we can use for DMA.
- * I think this means that the memory has to map to
- * contiguous pages of physical memory.
- */
-static struct snd_dma_buffer *get_dmabuf(struct snd_dma_buffer *buf,
- unsigned long size)
-{
- if (buf) {
- if (snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV,
- snd_dma_isa_data(),
- size, buf) < 0) {
- snd_printk(KERN_ERR "sscape: Failed to allocate "
- "%lu bytes for DMA\n",
- size);
- return NULL;
- }
- }
-
- return buf;
-}
-
-/*
- * Release the DMA-able kernel memory ...
- */
-static void free_dmabuf(struct snd_dma_buffer *buf)
-{
- if (buf && buf->area)
- snd_dma_free_pages(buf);
-}
-
-/*
- * This function writes to the SoundScape's control registers,
- * but doesn't do any locking. It's up to the caller to do that.
- * This is why this function is "unsafe" ...
- */
-static inline void sscape_write_unsafe(unsigned io_base, enum GA_REG reg,
- unsigned char val)
-{
- outb(reg, ODIE_ADDR_IO(io_base));
- outb(val, ODIE_DATA_IO(io_base));
-}
-
-/*
- * Write to the SoundScape's control registers, and do the
- * necessary locking ...
- */
-static void sscape_write(struct soundscape *s, enum GA_REG reg,
- unsigned char val)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&s->lock, flags);
- sscape_write_unsafe(s->io_base, reg, val);
- spin_unlock_irqrestore(&s->lock, flags);
-}
-
-/*
- * Read from the SoundScape's control registers, but leave any
- * locking to the caller. This is why the function is "unsafe" ...
- */
-static inline unsigned char sscape_read_unsafe(unsigned io_base,
- enum GA_REG reg)
-{
- outb(reg, ODIE_ADDR_IO(io_base));
- return inb(ODIE_DATA_IO(io_base));
-}
-
-/*
- * Puts the SoundScape into "host" mode, as compared to "MIDI" mode
- */
-static inline void set_host_mode_unsafe(unsigned io_base)
-{
- outb(0x0, HOST_CTRL_IO(io_base));
-}
-
-/*
- * Puts the SoundScape into "MIDI" mode, as compared to "host" mode
- */
-static inline void set_midi_mode_unsafe(unsigned io_base)
-{
- outb(0x3, HOST_CTRL_IO(io_base));
-}
-
-/*
- * Read the SoundScape's host-mode control register, but leave
- * any locking issues to the caller ...
- */
-static inline int host_read_unsafe(unsigned io_base)
-{
- int data = -1;
- if ((inb(HOST_CTRL_IO(io_base)) & RX_READY) != 0)
- data = inb(HOST_DATA_IO(io_base));
-
- return data;
-}
-
-/*
- * Read the SoundScape's host-mode control register, performing
- * a limited amount of busy-waiting if the register isn't ready.
- * Also leaves all locking-issues to the caller ...
- */
-static int host_read_ctrl_unsafe(unsigned io_base, unsigned timeout)
-{
- int data;
-
- while (((data = host_read_unsafe(io_base)) < 0) && (timeout != 0)) {
- udelay(100);
- --timeout;
- } /* while */
-
- return data;
-}
-
-/*
- * Write to the SoundScape's host-mode control registers, but
- * leave any locking issues to the caller ...
- */
-static inline int host_write_unsafe(unsigned io_base, unsigned char data)
-{
- if ((inb(HOST_CTRL_IO(io_base)) & TX_READY) != 0) {
- outb(data, HOST_DATA_IO(io_base));
- return 1;
- }
-
- return 0;
-}
-
-/*
- * Write to the SoundScape's host-mode control registers, performing
- * a limited amount of busy-waiting if the register isn't ready.
- * Also leaves all locking-issues to the caller ...
- */
-static int host_write_ctrl_unsafe(unsigned io_base, unsigned char data,
- unsigned timeout)
-{
- int err;
-
- while (!(err = host_write_unsafe(io_base, data)) && (timeout != 0)) {
- udelay(100);
- --timeout;
- } /* while */
-
- return err;
-}
-
-
-/*
- * Check that the MIDI subsystem is operational. If it isn't,
- * then we will hang the computer if we try to use it ...
- *
- * NOTE: This check is based upon observation, not documentation.
- */
-static inline int verify_mpu401(const struct snd_mpu401 *mpu)
-{
- return ((inb(MPU401C(mpu)) & 0xc0) == 0x80);
-}
-
-/*
- * This is apparently the standard way to initailise an MPU-401
- */
-static inline void initialise_mpu401(const struct snd_mpu401 *mpu)
-{
- outb(0, MPU401D(mpu));
-}
-
-/*
- * Tell the SoundScape to activate the AD1845 chip (I think).
- * The AD1845 detection fails if we *don't* do this, so I
- * think that this is a good idea ...
- */
-static void activate_ad1845_unsafe(unsigned io_base)
-{
- unsigned char val = sscape_read_unsafe(io_base, GA_HMCTL_REG);
- sscape_write_unsafe(io_base, GA_HMCTL_REG, (val & 0xcf) | 0x10);
- sscape_write_unsafe(io_base, GA_CDCFG_REG, 0x80);
-}
-
-/*
- * Do the necessary ALSA-level cleanup to deallocate our driver ...
- */
-static void soundscape_free(struct snd_card *c)
-{
- struct soundscape *sscape = get_card_soundscape(c);
- release_and_free_resource(sscape->io_res);
- release_and_free_resource(sscape->wss_res);
- free_dma(sscape->chip->dma1);
-}
-
-/*
- * Tell the SoundScape to begin a DMA tranfer using the given channel.
- * All locking issues are left to the caller.
- */
-static void sscape_start_dma_unsafe(unsigned io_base, enum GA_REG reg)
-{
- sscape_write_unsafe(io_base, reg,
- sscape_read_unsafe(io_base, reg) | 0x01);
- sscape_write_unsafe(io_base, reg,
- sscape_read_unsafe(io_base, reg) & 0xfe);
-}
-
-/*
- * Wait for a DMA transfer to complete. This is a "limited busy-wait",
- * and all locking issues are left to the caller.
- */
-static int sscape_wait_dma_unsafe(unsigned io_base, enum GA_REG reg,
- unsigned timeout)
-{
- while (!(sscape_read_unsafe(io_base, reg) & 0x01) && (timeout != 0)) {
- udelay(100);
- --timeout;
- } /* while */
-
- return sscape_read_unsafe(io_base, reg) & 0x01;
-}
-
-/*
- * Wait for the On-Board Processor to return its start-up
- * acknowledgement sequence. This wait is too long for
- * us to perform "busy-waiting", and so we must sleep.
- * This in turn means that we must not be holding any
- * spinlocks when we call this function.
- */
-static int obp_startup_ack(struct soundscape *s, unsigned timeout)
-{
- unsigned long end_time = jiffies + msecs_to_jiffies(timeout);
-
- do {
- unsigned long flags;
- int x;
-
- spin_lock_irqsave(&s->lock, flags);
- x = host_read_unsafe(s->io_base);
- spin_unlock_irqrestore(&s->lock, flags);
- if (x == 0xfe || x == 0xff)
- return 1;
-
- msleep(10);
- } while (time_before(jiffies, end_time));
-
- return 0;
-}
-
-/*
- * Wait for the host to return its start-up acknowledgement
- * sequence. This wait is too long for us to perform
- * "busy-waiting", and so we must sleep. This in turn means
- * that we must not be holding any spinlocks when we call
- * this function.
- */
-static int host_startup_ack(struct soundscape *s, unsigned timeout)
-{
- unsigned long end_time = jiffies + msecs_to_jiffies(timeout);
-
- do {
- unsigned long flags;
- int x;
-
- spin_lock_irqsave(&s->lock, flags);
- x = host_read_unsafe(s->io_base);
- spin_unlock_irqrestore(&s->lock, flags);
- if (x == 0xfe)
- return 1;
-
- msleep(10);
- } while (time_before(jiffies, end_time));
-
- return 0;
-}
-
-/*
- * Upload a byte-stream into the SoundScape using DMA channel A.
- */
-static int upload_dma_data(struct soundscape *s, const unsigned char *data,
- size_t size)
-{
- unsigned long flags;
- struct snd_dma_buffer dma;
- int ret;
- unsigned char val;
-
- if (!get_dmabuf(&dma, PAGE_ALIGN(32 * 1024)))
- return -ENOMEM;
-
- spin_lock_irqsave(&s->lock, flags);
-
- /*
- * Reset the board ...
- */
- val = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
- sscape_write_unsafe(s->io_base, GA_HMCTL_REG, val & 0x3f);
-
- /*
- * Enable the DMA channels and configure them ...
- */
- val = (s->chip->dma1 << 4) | DMA_8BIT;
- sscape_write_unsafe(s->io_base, GA_DMAA_REG, val);
- sscape_write_unsafe(s->io_base, GA_DMAB_REG, 0x20);
-
- /*
- * Take the board out of reset ...
- */
- val = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
- sscape_write_unsafe(s->io_base, GA_HMCTL_REG, val | 0x80);
-
- /*
- * Upload the firmware to the SoundScape
- * board through the DMA channel ...
- */
- while (size != 0) {
- unsigned long len;
-
- len = min(size, dma.bytes);
- memcpy(dma.area, data, len);
- data += len;
- size -= len;
-
- snd_dma_program(s->chip->dma1, dma.addr, len, DMA_MODE_WRITE);
- sscape_start_dma_unsafe(s->io_base, GA_DMAA_REG);
- if (!sscape_wait_dma_unsafe(s->io_base, GA_DMAA_REG, 5000)) {
- /*
- * Don't forget to release this spinlock we're holding
- */
- spin_unlock_irqrestore(&s->lock, flags);
-
- snd_printk(KERN_ERR
- "sscape: DMA upload has timed out\n");
- ret = -EAGAIN;
- goto _release_dma;
- }
- } /* while */
-
- set_host_mode_unsafe(s->io_base);
- outb(0x0, s->io_base);
-
- /*
- * Boot the board ... (I think)
- */
- val = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
- sscape_write_unsafe(s->io_base, GA_HMCTL_REG, val | 0x40);
- spin_unlock_irqrestore(&s->lock, flags);
-
- /*
- * If all has gone well, then the board should acknowledge
- * the new upload and tell us that it has rebooted OK. We
- * give it 5 seconds (max) ...
- */
- ret = 0;
- if (!obp_startup_ack(s, 5000)) {
- snd_printk(KERN_ERR "sscape: No response "
- "from on-board processor after upload\n");
- ret = -EAGAIN;
- } else if (!host_startup_ack(s, 5000)) {
- snd_printk(KERN_ERR
- "sscape: SoundScape failed to initialise\n");
- ret = -EAGAIN;
- }
-
-_release_dma:
- /*
- * NOTE!!! We are NOT holding any spinlocks at this point !!!
- */
- sscape_write(s, GA_DMAA_REG, (s->ic_type == IC_OPUS ? 0x40 : 0x70));
- free_dmabuf(&dma);
-
- return ret;
-}
-
-/*
- * Upload the bootblock(?) into the SoundScape. The only
- * purpose of this block of code seems to be to tell
- * us which version of the microcode we should be using.
- */
-static int sscape_upload_bootblock(struct snd_card *card)
-{
- struct soundscape *sscape = get_card_soundscape(card);
- unsigned long flags;
- const struct firmware *init_fw = NULL;
- int data = 0;
- int ret;
-
- ret = request_firmware(&init_fw, "scope.cod", card->dev);
- if (ret < 0) {
- snd_printk(KERN_ERR "sscape: Error loading scope.cod");
- return ret;
- }
- ret = upload_dma_data(sscape, init_fw->data, init_fw->size);
-
- release_firmware(init_fw);
-
- spin_lock_irqsave(&sscape->lock, flags);
- if (ret == 0)
- data = host_read_ctrl_unsafe(sscape->io_base, 100);
-
- if (data & 0x10)
- sscape_write_unsafe(sscape->io_base, GA_SMCFGA_REG, 0x2f);
-
- spin_unlock_irqrestore(&sscape->lock, flags);
-
- data &= 0xf;
- if (ret == 0 && data > 7) {
- snd_printk(KERN_ERR
- "sscape: timeout reading firmware version\n");
- ret = -EAGAIN;
- }
-
- return (ret == 0) ? data : ret;
-}
-
-/*
- * Upload the microcode into the SoundScape.
- */
-static int sscape_upload_microcode(struct snd_card *card, int version)
-{
- struct soundscape *sscape = get_card_soundscape(card);
- const struct firmware *init_fw = NULL;
- char name[14];
- int err;
-
- snprintf(name, sizeof(name), "sndscape.co%d", version);
-
- err = request_firmware(&init_fw, name, card->dev);
- if (err < 0) {
- snd_printk(KERN_ERR "sscape: Error loading sndscape.co%d",
- version);
- return err;
- }
- err = upload_dma_data(sscape, init_fw->data, init_fw->size);
- if (err == 0)
- snd_printk(KERN_INFO "sscape: MIDI firmware loaded %d KBs\n",
- init_fw->size >> 10);
-
- release_firmware(init_fw);
-
- return err;
-}
-
-/*
- * Mixer control for the SoundScape's MIDI device.
- */
-static int sscape_midi_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 127;
- return 0;
-}
-
-static int sscape_midi_get(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_value *uctl)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kctl);
- struct snd_card *card = chip->card;
- register struct soundscape *s = get_card_soundscape(card);
- unsigned long flags;
-
- spin_lock_irqsave(&s->lock, flags);
- uctl->value.integer.value[0] = s->midi_vol;
- spin_unlock_irqrestore(&s->lock, flags);
- return 0;
-}
-
-static int sscape_midi_put(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_value *uctl)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kctl);
- struct snd_card *card = chip->card;
- struct soundscape *s = get_card_soundscape(card);
- unsigned long flags;
- int change;
- unsigned char new_val;
-
- spin_lock_irqsave(&s->lock, flags);
-
- new_val = uctl->value.integer.value[0] & 127;
- /*
- * We need to put the board into HOST mode before we
- * can send any volume-changing HOST commands ...
- */
- set_host_mode_unsafe(s->io_base);
-
- /*
- * To successfully change the MIDI volume setting, you seem to
- * have to write a volume command, write the new volume value,
- * and then perform another volume-related command. Perhaps the
- * first command is an "open" and the second command is a "close"?
- */
- if (s->midi_vol == new_val) {
- change = 0;
- goto __skip_change;
- }
- change = host_write_ctrl_unsafe(s->io_base, CMD_SET_MIDI_VOL, 100)
- && host_write_ctrl_unsafe(s->io_base, new_val, 100)
- && host_write_ctrl_unsafe(s->io_base, CMD_XXX_MIDI_VOL, 100)
- && host_write_ctrl_unsafe(s->io_base, new_val, 100);
- s->midi_vol = new_val;
-__skip_change:
-
- /*
- * Take the board out of HOST mode and back into MIDI mode ...
- */
- set_midi_mode_unsafe(s->io_base);
-
- spin_unlock_irqrestore(&s->lock, flags);
- return change;
-}
-
-static struct snd_kcontrol_new midi_mixer_ctl = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "MIDI",
- .info = sscape_midi_info,
- .get = sscape_midi_get,
- .put = sscape_midi_put
-};
-
-/*
- * The SoundScape can use two IRQs from a possible set of four.
- * These IRQs are encoded as bit patterns so that they can be
- * written to the control registers.
- */
-static unsigned __devinit get_irq_config(int sscape_type, int irq)
-{
- static const int valid_irq[] = { 9, 5, 7, 10 };
- static const int old_irq[] = { 9, 7, 5, 15 };
- unsigned cfg;
-
- if (sscape_type == MEDIA_FX) {
- for (cfg = 0; cfg < ARRAY_SIZE(old_irq); ++cfg)
- if (irq == old_irq[cfg])
- return cfg;
- } else {
- for (cfg = 0; cfg < ARRAY_SIZE(valid_irq); ++cfg)
- if (irq == valid_irq[cfg])
- return cfg;
- }
-
- return INVALID_IRQ;
-}
-
-/*
- * Perform certain arcane port-checks to see whether there
- * is a SoundScape board lurking behind the given ports.
- */
-static int __devinit detect_sscape(struct soundscape *s, long wss_io)
-{
- unsigned long flags;
- unsigned d;
- int retval = 0;
-
- spin_lock_irqsave(&s->lock, flags);
-
- /*
- * The following code is lifted from the original OSS driver,
- * and as I don't have a datasheet I cannot really comment
- * on what it is doing...
- */
- if ((inb(HOST_CTRL_IO(s->io_base)) & 0x78) != 0)
- goto _done;
-
- d = inb(ODIE_ADDR_IO(s->io_base)) & 0xf0;
- if ((d & 0x80) != 0)
- goto _done;
-
- if (d == 0)
- s->ic_type = IC_ODIE;
- else if ((d & 0x60) != 0)
- s->ic_type = IC_OPUS;
- else
- goto _done;
-
- outb(0xfa, ODIE_ADDR_IO(s->io_base));
- if ((inb(ODIE_ADDR_IO(s->io_base)) & 0x9f) != 0x0a)
- goto _done;
-
- outb(0xfe, ODIE_ADDR_IO(s->io_base));
- if ((inb(ODIE_ADDR_IO(s->io_base)) & 0x9f) != 0x0e)
- goto _done;
-
- outb(0xfe, ODIE_ADDR_IO(s->io_base));
- d = inb(ODIE_DATA_IO(s->io_base));
- if (s->type != SSCAPE_VIVO && (d & 0x9f) != 0x0e)
- goto _done;
-
- if (s->ic_type == IC_OPUS)
- activate_ad1845_unsafe(s->io_base);
-
- if (s->type == SSCAPE_VIVO)
- wss_io += 4;
-
- d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
- sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d | 0xc0);
-
- /* wait for WSS codec */
- for (d = 0; d < 500; d++) {
- if ((inb(wss_io) & 0x80) == 0)
- break;
- spin_unlock_irqrestore(&s->lock, flags);
- msleep(1);
- spin_lock_irqsave(&s->lock, flags);
- }
-
- if ((inb(wss_io) & 0x80) != 0)
- goto _done;
-
- if (inb(wss_io + 2) == 0xff)
- goto _done;
-
- d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG) & 0x3f;
- sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d);
-
- if ((inb(wss_io) & 0x80) != 0)
- s->type = MEDIA_FX;
-
- d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
- sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d | 0xc0);
- /* wait for WSS codec */
- for (d = 0; d < 500; d++) {
- if ((inb(wss_io) & 0x80) == 0)
- break;
- spin_unlock_irqrestore(&s->lock, flags);
- msleep(1);
- spin_lock_irqsave(&s->lock, flags);
- }
-
- /*
- * SoundScape successfully detected!
- */
- retval = 1;
-
-_done:
- spin_unlock_irqrestore(&s->lock, flags);
- return retval;
-}
-
-/*
- * ALSA callback function, called when attempting to open the MIDI device.
- * Check that the MIDI firmware has been loaded, because we don't want
- * to crash the machine. Also check that someone isn't using the hardware
- * IOCTL device.
- */
-static int mpu401_open(struct snd_mpu401 *mpu)
-{
- if (!verify_mpu401(mpu)) {
- snd_printk(KERN_ERR "sscape: MIDI disabled, "
- "please load firmware\n");
- return -ENODEV;
- }
-
- return 0;
-}
-
-/*
- * Initialse an MPU-401 subdevice for MIDI support on the SoundScape.
- */
-static int __devinit create_mpu401(struct snd_card *card, int devnum,
- unsigned long port, int irq)
-{
- struct soundscape *sscape = get_card_soundscape(card);
- struct snd_rawmidi *rawmidi;
- int err;
-
- err = snd_mpu401_uart_new(card, devnum, MPU401_HW_MPU401, port,
- MPU401_INFO_INTEGRATED, irq, &rawmidi);
- if (err == 0) {
- struct snd_mpu401 *mpu = rawmidi->private_data;
- mpu->open_input = mpu401_open;
- mpu->open_output = mpu401_open;
- mpu->private_data = sscape;
-
- initialise_mpu401(mpu);
- }
-
- return err;
-}
-
-
-/*
- * Create an AD1845 PCM subdevice on the SoundScape. The AD1845
- * is very much like a CS4231, with a few extra bits. We will
- * try to support at least some of the extra bits by overriding
- * some of the CS4231 callback.
- */
-static int __devinit create_ad1845(struct snd_card *card, unsigned port,
- int irq, int dma1, int dma2)
-{
- register struct soundscape *sscape = get_card_soundscape(card);
- struct snd_wss *chip;
- int err;
- int codec_type = WSS_HW_DETECT;
-
- switch (sscape->type) {
- case MEDIA_FX:
- case SSCAPE:
- /*
- * There are some freak examples of early Soundscape cards
- * with CS4231 instead of AD1848/CS4248. Unfortunately, the
- * CS4231 works only in CS4248 compatibility mode on
- * these cards so force it.
- */
- if (sscape->ic_type != IC_OPUS)
- codec_type = WSS_HW_AD1848;
- break;
-
- case SSCAPE_VIVO:
- port += 4;
- break;
- default:
- break;
- }
-
- err = snd_wss_create(card, port, -1, irq, dma1, dma2,
- codec_type, WSS_HWSHARE_DMA1, &chip);
- if (!err) {
- unsigned long flags;
- struct snd_pcm *pcm;
-
- if (sscape->type != SSCAPE_VIVO) {
- /*
- * The input clock frequency on the SoundScape must
- * be 14.31818 MHz, because we must set this register
- * to get the playback to sound correct ...
- */
- snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_wss_out(chip, AD1845_CLOCK, 0x20);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- snd_wss_mce_down(chip);
-
- }
-
- err = snd_wss_pcm(chip, 0, &pcm);
- if (err < 0) {
- snd_printk(KERN_ERR "sscape: No PCM device "
- "for AD1845 chip\n");
- goto _error;
- }
-
- err = snd_wss_mixer(chip);
- if (err < 0) {
- snd_printk(KERN_ERR "sscape: No mixer device "
- "for AD1845 chip\n");
- goto _error;
- }
- if (chip->hardware != WSS_HW_AD1848) {
- err = snd_wss_timer(chip, 0, NULL);
- if (err < 0) {
- snd_printk(KERN_ERR "sscape: No timer device "
- "for AD1845 chip\n");
- goto _error;
- }
- }
-
- if (sscape->type != SSCAPE_VIVO) {
- err = snd_ctl_add(card,
- snd_ctl_new1(&midi_mixer_ctl, chip));
- if (err < 0) {
- snd_printk(KERN_ERR "sscape: Could not create "
- "MIDI mixer control\n");
- goto _error;
- }
- }
-
- sscape->chip = chip;
- }
-
-_error:
- return err;
-}
-
-
-/*
- * Create an ALSA soundcard entry for the SoundScape, using
- * the given list of port, IRQ and DMA resources.
- */
-static int __devinit create_sscape(int dev, struct snd_card *card)
-{
- struct soundscape *sscape = get_card_soundscape(card);
- unsigned dma_cfg;
- unsigned irq_cfg;
- unsigned mpu_irq_cfg;
- struct resource *io_res;
- struct resource *wss_res;
- unsigned long flags;
- int err;
- int val;
- const char *name;
-
- /*
- * Grab IO ports that we will need to probe so that we
- * can detect and control this hardware ...
- */
- io_res = request_region(port[dev], 8, "SoundScape");
- if (!io_res) {
- snd_printk(KERN_ERR
- "sscape: can't grab port 0x%lx\n", port[dev]);
- return -EBUSY;
- }
- wss_res = NULL;
- if (sscape->type == SSCAPE_VIVO) {
- wss_res = request_region(wss_port[dev], 4, "SoundScape");
- if (!wss_res) {
- snd_printk(KERN_ERR "sscape: can't grab port 0x%lx\n",
- wss_port[dev]);
- err = -EBUSY;
- goto _release_region;
- }
- }
-
- /*
- * Grab one DMA channel ...
- */
- err = request_dma(dma[dev], "SoundScape");
- if (err < 0) {
- snd_printk(KERN_ERR "sscape: can't grab DMA %d\n", dma[dev]);
- goto _release_region;
- }
-
- spin_lock_init(&sscape->lock);
- sscape->io_res = io_res;
- sscape->wss_res = wss_res;
- sscape->io_base = port[dev];
-
- if (!detect_sscape(sscape, wss_port[dev])) {
- printk(KERN_ERR "sscape: hardware not detected at 0x%x\n",
- sscape->io_base);
- err = -ENODEV;
- goto _release_dma;
- }
-
- switch (sscape->type) {
- case MEDIA_FX:
- name = "MediaFX/SoundFX";
- break;
- case SSCAPE:
- name = "Soundscape";
- break;
- case SSCAPE_PNP:
- name = "Soundscape PnP";
- break;
- case SSCAPE_VIVO:
- name = "Soundscape VIVO";
- break;
- default:
- name = "unknown Soundscape";
- break;
- }
-
- printk(KERN_INFO "sscape: %s card detected at 0x%x, using IRQ %d, DMA %d\n",
- name, sscape->io_base, irq[dev], dma[dev]);
-
- /*
- * Check that the user didn't pass us garbage data ...
- */
- irq_cfg = get_irq_config(sscape->type, irq[dev]);
- if (irq_cfg == INVALID_IRQ) {
- snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", irq[dev]);
- err = -ENXIO;
- goto _release_dma;
- }
-
- mpu_irq_cfg = get_irq_config(sscape->type, mpu_irq[dev]);
- if (mpu_irq_cfg == INVALID_IRQ) {
- snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", mpu_irq[dev]);
- err = -ENXIO;
- goto _release_dma;
- }
-
- /*
- * Tell the on-board devices where their resources are (I think -
- * I can't be sure without a datasheet ... So many magic values!)
- */
- spin_lock_irqsave(&sscape->lock, flags);
-
- sscape_write_unsafe(sscape->io_base, GA_SMCFGA_REG, 0x2e);
- sscape_write_unsafe(sscape->io_base, GA_SMCFGB_REG, 0x00);
-
- /*
- * Enable and configure the DMA channels ...
- */
- sscape_write_unsafe(sscape->io_base, GA_DMACFG_REG, 0x50);
- dma_cfg = (sscape->ic_type == IC_OPUS ? 0x40 : 0x70);
- sscape_write_unsafe(sscape->io_base, GA_DMAA_REG, dma_cfg);
- sscape_write_unsafe(sscape->io_base, GA_DMAB_REG, 0x20);
-
- mpu_irq_cfg |= mpu_irq_cfg << 2;
- val = sscape_read_unsafe(sscape->io_base, GA_HMCTL_REG) & 0xF7;
- if (joystick[dev])
- val |= 8;
- sscape_write_unsafe(sscape->io_base, GA_HMCTL_REG, val | 0x10);
- sscape_write_unsafe(sscape->io_base, GA_INTCFG_REG, 0xf0 | mpu_irq_cfg);
- sscape_write_unsafe(sscape->io_base,
- GA_CDCFG_REG, 0x09 | DMA_8BIT
- | (dma[dev] << 4) | (irq_cfg << 1));
- /*
- * Enable the master IRQ ...
- */
- sscape_write_unsafe(sscape->io_base, GA_INTENA_REG, 0x80);
-
- spin_unlock_irqrestore(&sscape->lock, flags);
-
- /*
- * We have now enabled the codec chip, and so we should
- * detect the AD1845 device ...
- */
- err = create_ad1845(card, wss_port[dev], irq[dev],
- dma[dev], dma2[dev]);
- if (err < 0) {
- snd_printk(KERN_ERR
- "sscape: No AD1845 device at 0x%lx, IRQ %d\n",
- wss_port[dev], irq[dev]);
- goto _release_dma;
- }
- strcpy(card->driver, "SoundScape");
- strcpy(card->shortname, name);
- snprintf(card->longname, sizeof(card->longname),
- "%s at 0x%lx, IRQ %d, DMA1 %d, DMA2 %d\n",
- name, sscape->chip->port, sscape->chip->irq,
- sscape->chip->dma1, sscape->chip->dma2);
-
-#define MIDI_DEVNUM 0
- if (sscape->type != SSCAPE_VIVO) {
- err = sscape_upload_bootblock(card);
- if (err >= 0)
- err = sscape_upload_microcode(card, err);
-
- if (err == 0) {
- err = create_mpu401(card, MIDI_DEVNUM, port[dev],
- mpu_irq[dev]);
- if (err < 0) {
- snd_printk(KERN_ERR "sscape: Failed to create "
- "MPU-401 device at 0x%lx\n",
- port[dev]);
- goto _release_dma;
- }
-
- /*
- * Initialize mixer
- */
- spin_lock_irqsave(&sscape->lock, flags);
- sscape->midi_vol = 0;
- host_write_ctrl_unsafe(sscape->io_base,
- CMD_SET_MIDI_VOL, 100);
- host_write_ctrl_unsafe(sscape->io_base,
- sscape->midi_vol, 100);
- host_write_ctrl_unsafe(sscape->io_base,
- CMD_XXX_MIDI_VOL, 100);
- host_write_ctrl_unsafe(sscape->io_base,
- sscape->midi_vol, 100);
- host_write_ctrl_unsafe(sscape->io_base,
- CMD_SET_EXTMIDI, 100);
- host_write_ctrl_unsafe(sscape->io_base,
- 0, 100);
- host_write_ctrl_unsafe(sscape->io_base, CMD_ACK, 100);
-
- set_midi_mode_unsafe(sscape->io_base);
- spin_unlock_irqrestore(&sscape->lock, flags);
- }
- }
-
- /*
- * Now that we have successfully created this sound card,
- * it is safe to store the pointer.
- * NOTE: we only register the sound card's "destructor"
- * function now that our "constructor" has completed.
- */
- card->private_free = soundscape_free;
-
- return 0;
-
-_release_dma:
- free_dma(dma[dev]);
-
-_release_region:
- release_and_free_resource(wss_res);
- release_and_free_resource(io_res);
-
- return err;
-}
-
-
-static int __devinit snd_sscape_match(struct device *pdev, unsigned int i)
-{
- /*
- * Make sure we were given ALL of the other parameters.
- */
- if (port[i] == SNDRV_AUTO_PORT)
- return 0;
-
- if (irq[i] == SNDRV_AUTO_IRQ ||
- mpu_irq[i] == SNDRV_AUTO_IRQ ||
- dma[i] == SNDRV_AUTO_DMA) {
- printk(KERN_INFO
- "sscape: insufficient parameters, "
- "need IO, IRQ, MPU-IRQ and DMA\n");
- return 0;
- }
-
- return 1;
-}
-
-static int __devinit snd_sscape_probe(struct device *pdev, unsigned int dev)
-{
- struct snd_card *card;
- struct soundscape *sscape;
- int ret;
-
- ret = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct soundscape), &card);
- if (ret < 0)
- return ret;
-
- sscape = get_card_soundscape(card);
- sscape->type = SSCAPE;
-
- dma[dev] &= 0x03;
- snd_card_set_dev(card, pdev);
-
- ret = create_sscape(dev, card);
- if (ret < 0)
- goto _release_card;
-
- ret = snd_card_register(card);
- if (ret < 0) {
- snd_printk(KERN_ERR "sscape: Failed to register sound card\n");
- goto _release_card;
- }
- dev_set_drvdata(pdev, card);
- return 0;
-
-_release_card:
- snd_card_free(card);
- return ret;
-}
-
-static int __devexit snd_sscape_remove(struct device *devptr, unsigned int dev)
-{
- snd_card_free(dev_get_drvdata(devptr));
- dev_set_drvdata(devptr, NULL);
- return 0;
-}
-
-#define DEV_NAME "sscape"
-
-static struct isa_driver snd_sscape_driver = {
- .match = snd_sscape_match,
- .probe = snd_sscape_probe,
- .remove = __devexit_p(snd_sscape_remove),
- /* FIXME: suspend/resume */
- .driver = {
- .name = DEV_NAME
- },
-};
-
-#ifdef CONFIG_PNP
-static inline int __devinit get_next_autoindex(int i)
-{
- while (i < SNDRV_CARDS && port[i] != SNDRV_AUTO_PORT)
- ++i;
- return i;
-}
-
-
-static int __devinit sscape_pnp_detect(struct pnp_card_link *pcard,
- const struct pnp_card_device_id *pid)
-{
- static int idx = 0;
- struct pnp_dev *dev;
- struct snd_card *card;
- struct soundscape *sscape;
- int ret;
-
- /*
- * Allow this function to fail *quietly* if all the ISA PnP
- * devices were configured using module parameters instead.
- */
- idx = get_next_autoindex(idx);
- if (idx >= SNDRV_CARDS)
- return -ENOSPC;
-
- /*
- * Check that we still have room for another sound card ...
- */
- dev = pnp_request_card_device(pcard, pid->devs[0].id, NULL);
- if (!dev)
- return -ENODEV;
-
- if (!pnp_is_active(dev)) {
- if (pnp_activate_dev(dev) < 0) {
- snd_printk(KERN_INFO "sscape: device is inactive\n");
- return -EBUSY;
- }
- }
-
- /*
- * Create a new ALSA sound card entry, in anticipation
- * of detecting our hardware ...
- */
- ret = snd_card_create(index[idx], id[idx], THIS_MODULE,
- sizeof(struct soundscape), &card);
- if (ret < 0)
- return ret;
-
- sscape = get_card_soundscape(card);
-
- /*
- * Identify card model ...
- */
- if (!strncmp("ENS4081", pid->id, 7))
- sscape->type = SSCAPE_VIVO;
- else
- sscape->type = SSCAPE_PNP;
-
- /*
- * Read the correct parameters off the ISA PnP bus ...
- */
- port[idx] = pnp_port_start(dev, 0);
- irq[idx] = pnp_irq(dev, 0);
- mpu_irq[idx] = pnp_irq(dev, 1);
- dma[idx] = pnp_dma(dev, 0) & 0x03;
- if (sscape->type == SSCAPE_PNP) {
- dma2[idx] = dma[idx];
- wss_port[idx] = CODEC_IO(port[idx]);
- } else {
- wss_port[idx] = pnp_port_start(dev, 1);
- dma2[idx] = pnp_dma(dev, 1);
- }
- snd_card_set_dev(card, &pcard->card->dev);
-
- ret = create_sscape(idx, card);
- if (ret < 0)
- goto _release_card;
-
- ret = snd_card_register(card);
- if (ret < 0) {
- snd_printk(KERN_ERR "sscape: Failed to register sound card\n");
- goto _release_card;
- }
-
- pnp_set_card_drvdata(pcard, card);
- ++idx;
- return 0;
-
-_release_card:
- snd_card_free(card);
- return ret;
-}
-
-static void __devexit sscape_pnp_remove(struct pnp_card_link * pcard)
-{
- snd_card_free(pnp_get_card_drvdata(pcard));
- pnp_set_card_drvdata(pcard, NULL);
-}
-
-static struct pnp_card_driver sscape_pnpc_driver = {
- .flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
- .name = "sscape",
- .id_table = sscape_pnpids,
- .probe = sscape_pnp_detect,
- .remove = __devexit_p(sscape_pnp_remove),
-};
-
-#endif /* CONFIG_PNP */
-
-static int __init sscape_init(void)
-{
- int err;
-
- err = isa_register_driver(&snd_sscape_driver, SNDRV_CARDS);
-#ifdef CONFIG_PNP
- if (!err)
- isa_registered = 1;
-
- err = pnp_register_card_driver(&sscape_pnpc_driver);
- if (!err)
- pnp_registered = 1;
-
- if (isa_registered)
- err = 0;
-#endif
- return err;
-}
-
-static void __exit sscape_exit(void)
-{
-#ifdef CONFIG_PNP
- if (pnp_registered)
- pnp_unregister_card_driver(&sscape_pnpc_driver);
- if (isa_registered)
-#endif
- isa_unregister_driver(&snd_sscape_driver);
-}
-
-module_init(sscape_init);
-module_exit(sscape_exit);
diff --git a/ANDROID_3.4.5/sound/isa/wavefront/Makefile b/ANDROID_3.4.5/sound/isa/wavefront/Makefile
deleted file mode 100644
index 601bdddd..00000000
--- a/ANDROID_3.4.5/sound/isa/wavefront/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-wavefront-objs := wavefront.o wavefront_fx.o wavefront_synth.o wavefront_midi.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_WAVEFRONT) += snd-wavefront.o
diff --git a/ANDROID_3.4.5/sound/isa/wavefront/wavefront.c b/ANDROID_3.4.5/sound/isa/wavefront/wavefront.c
deleted file mode 100644
index e0a73271..00000000
--- a/ANDROID_3.4.5/sound/isa/wavefront/wavefront.c
+++ /dev/null
@@ -1,687 +0,0 @@
-/*
- * ALSA card-level driver for Turtle Beach Wavefront cards
- * (Maui,Tropez,Tropez+)
- *
- * Copyright (c) 1997-1999 by Paul Barton-Davis <pbd@op.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/err.h>
-#include <linux/isa.h>
-#include <linux/pnp.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/opl3.h>
-#include <sound/wss.h>
-#include <sound/snd_wavefront.h>
-
-MODULE_AUTHOR("Paul Barton-Davis <pbd@op.net>");
-MODULE_DESCRIPTION("Turtle Beach Wavefront");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Turtle Beach,Maui/Tropez/Tropez+}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
-#ifdef CONFIG_PNP
-static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
-#endif
-static long cs4232_pcm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static int cs4232_pcm_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,11,12,15 */
-static long cs4232_mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static int cs4232_mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 9,11,12,15 */
-static long ics2115_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static int ics2115_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 2,9,11,12,15 */
-static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
-static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
-static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
-static bool use_cs4232_midi[SNDRV_CARDS];
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for WaveFront soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for WaveFront soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable WaveFront soundcard.");
-#ifdef CONFIG_PNP
-module_param_array(isapnp, bool, NULL, 0444);
-MODULE_PARM_DESC(isapnp, "ISA PnP detection for WaveFront soundcards.");
-#endif
-module_param_array(cs4232_pcm_port, long, NULL, 0444);
-MODULE_PARM_DESC(cs4232_pcm_port, "Port # for CS4232 PCM interface.");
-module_param_array(cs4232_pcm_irq, int, NULL, 0444);
-MODULE_PARM_DESC(cs4232_pcm_irq, "IRQ # for CS4232 PCM interface.");
-module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "DMA1 # for CS4232 PCM interface.");
-module_param_array(dma2, int, NULL, 0444);
-MODULE_PARM_DESC(dma2, "DMA2 # for CS4232 PCM interface.");
-module_param_array(cs4232_mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(cs4232_mpu_port, "port # for CS4232 MPU-401 interface.");
-module_param_array(cs4232_mpu_irq, int, NULL, 0444);
-MODULE_PARM_DESC(cs4232_mpu_irq, "IRQ # for CS4232 MPU-401 interface.");
-module_param_array(ics2115_irq, int, NULL, 0444);
-MODULE_PARM_DESC(ics2115_irq, "IRQ # for ICS2115.");
-module_param_array(ics2115_port, long, NULL, 0444);
-MODULE_PARM_DESC(ics2115_port, "Port # for ICS2115.");
-module_param_array(fm_port, long, NULL, 0444);
-MODULE_PARM_DESC(fm_port, "FM port #.");
-module_param_array(use_cs4232_midi, bool, NULL, 0444);
-MODULE_PARM_DESC(use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly located inside your computer)");
-
-#ifdef CONFIG_PNP
-static int isa_registered;
-static int pnp_registered;
-
-static struct pnp_card_device_id snd_wavefront_pnpids[] = {
- /* Tropez */
- { .id = "CSC7532", .devs = { { "CSC0000" }, { "CSC0010" }, { "PnPb006" }, { "CSC0004" } } },
- /* Tropez+ */
- { .id = "CSC7632", .devs = { { "CSC0000" }, { "CSC0010" }, { "PnPb006" }, { "CSC0004" } } },
- { .id = "" }
-};
-
-MODULE_DEVICE_TABLE(pnp_card, snd_wavefront_pnpids);
-
-static int __devinit
-snd_wavefront_pnp (int dev, snd_wavefront_card_t *acard, struct pnp_card_link *card,
- const struct pnp_card_device_id *id)
-{
- struct pnp_dev *pdev;
- int err;
-
- /* Check for each logical device. */
-
- /* CS4232 chip (aka "windows sound system") is logical device 0 */
-
- acard->wss = pnp_request_card_device(card, id->devs[0].id, NULL);
- if (acard->wss == NULL)
- return -EBUSY;
-
- /* there is a game port at logical device 1, but we ignore it completely */
-
- /* the control interface is logical device 2, but we ignore it
- completely. in fact, nobody even seems to know what it
- does.
- */
-
- /* Only configure the CS4232 MIDI interface if its been
- specifically requested. It is logical device 3.
- */
-
- if (use_cs4232_midi[dev]) {
- acard->mpu = pnp_request_card_device(card, id->devs[2].id, NULL);
- if (acard->mpu == NULL)
- return -EBUSY;
- }
-
- /* The ICS2115 synth is logical device 4 */
-
- acard->synth = pnp_request_card_device(card, id->devs[3].id, NULL);
- if (acard->synth == NULL)
- return -EBUSY;
-
- /* PCM/FM initialization */
-
- pdev = acard->wss;
-
- /* An interesting note from the Tropez+ FAQ:
-
- Q. [Ports] Why is the base address of the WSS I/O ports off by 4?
-
- A. WSS I/O requires a block of 8 I/O addresses ("ports"). Of these, the first
- 4 are used to identify and configure the board. With the advent of PnP,
- these first 4 addresses have become obsolete, and software applications
- only use the last 4 addresses to control the codec chip. Therefore, the
- base address setting "skips past" the 4 unused addresses.
-
- */
-
- err = pnp_activate_dev(pdev);
- if (err < 0) {
- snd_printk(KERN_ERR "PnP WSS pnp configure failure\n");
- return err;
- }
-
- cs4232_pcm_port[dev] = pnp_port_start(pdev, 0);
- fm_port[dev] = pnp_port_start(pdev, 1);
- dma1[dev] = pnp_dma(pdev, 0);
- dma2[dev] = pnp_dma(pdev, 1);
- cs4232_pcm_irq[dev] = pnp_irq(pdev, 0);
-
- /* Synth initialization */
-
- pdev = acard->synth;
-
- err = pnp_activate_dev(pdev);
- if (err < 0) {
- snd_printk(KERN_ERR "PnP ICS2115 pnp configure failure\n");
- return err;
- }
-
- ics2115_port[dev] = pnp_port_start(pdev, 0);
- ics2115_irq[dev] = pnp_irq(pdev, 0);
-
- /* CS4232 MPU initialization. Configure this only if
- explicitly requested, since its physically inaccessible and
- consumes another IRQ.
- */
-
- if (use_cs4232_midi[dev]) {
-
- pdev = acard->mpu;
-
- err = pnp_activate_dev(pdev);
- if (err < 0) {
- snd_printk(KERN_ERR "PnP MPU401 pnp configure failure\n");
- cs4232_mpu_port[dev] = SNDRV_AUTO_PORT;
- } else {
- cs4232_mpu_port[dev] = pnp_port_start(pdev, 0);
- cs4232_mpu_irq[dev] = pnp_irq(pdev, 0);
- }
-
- snd_printk (KERN_INFO "CS4232 MPU: port=0x%lx, irq=%i\n",
- cs4232_mpu_port[dev],
- cs4232_mpu_irq[dev]);
- }
-
- snd_printdd ("CS4232: pcm port=0x%lx, fm port=0x%lx, dma1=%i, dma2=%i, irq=%i\nICS2115: port=0x%lx, irq=%i\n",
- cs4232_pcm_port[dev],
- fm_port[dev],
- dma1[dev],
- dma2[dev],
- cs4232_pcm_irq[dev],
- ics2115_port[dev],
- ics2115_irq[dev]);
-
- return 0;
-}
-
-#endif /* CONFIG_PNP */
-
-static irqreturn_t snd_wavefront_ics2115_interrupt(int irq, void *dev_id)
-{
- snd_wavefront_card_t *acard;
-
- acard = (snd_wavefront_card_t *) dev_id;
-
- if (acard == NULL)
- return IRQ_NONE;
-
- if (acard->wavefront.interrupts_are_midi) {
- snd_wavefront_midi_interrupt (acard);
- } else {
- snd_wavefront_internal_interrupt (acard);
- }
- return IRQ_HANDLED;
-}
-
-static struct snd_hwdep * __devinit
-snd_wavefront_new_synth (struct snd_card *card,
- int hw_dev,
- snd_wavefront_card_t *acard)
-{
- struct snd_hwdep *wavefront_synth;
-
- if (snd_wavefront_detect (acard) < 0) {
- return NULL;
- }
-
- if (snd_wavefront_start (&acard->wavefront) < 0) {
- return NULL;
- }
-
- if (snd_hwdep_new(card, "WaveFront", hw_dev, &wavefront_synth) < 0)
- return NULL;
- strcpy (wavefront_synth->name,
- "WaveFront (ICS2115) wavetable synthesizer");
- wavefront_synth->ops.open = snd_wavefront_synth_open;
- wavefront_synth->ops.release = snd_wavefront_synth_release;
- wavefront_synth->ops.ioctl = snd_wavefront_synth_ioctl;
-
- return wavefront_synth;
-}
-
-static struct snd_hwdep * __devinit
-snd_wavefront_new_fx (struct snd_card *card,
- int hw_dev,
- snd_wavefront_card_t *acard,
- unsigned long port)
-
-{
- struct snd_hwdep *fx_processor;
-
- if (snd_wavefront_fx_start (&acard->wavefront)) {
- snd_printk (KERN_ERR "cannot initialize YSS225 FX processor");
- return NULL;
- }
-
- if (snd_hwdep_new (card, "YSS225", hw_dev, &fx_processor) < 0)
- return NULL;
- sprintf (fx_processor->name, "YSS225 FX Processor at 0x%lx", port);
- fx_processor->ops.open = snd_wavefront_fx_open;
- fx_processor->ops.release = snd_wavefront_fx_release;
- fx_processor->ops.ioctl = snd_wavefront_fx_ioctl;
-
- return fx_processor;
-}
-
-static snd_wavefront_mpu_id internal_id = internal_mpu;
-static snd_wavefront_mpu_id external_id = external_mpu;
-
-static struct snd_rawmidi *__devinit
-snd_wavefront_new_midi (struct snd_card *card,
- int midi_dev,
- snd_wavefront_card_t *acard,
- unsigned long port,
- snd_wavefront_mpu_id mpu)
-
-{
- struct snd_rawmidi *rmidi;
- static int first = 1;
-
- if (first) {
- first = 0;
- acard->wavefront.midi.base = port;
- if (snd_wavefront_midi_start (acard)) {
- snd_printk (KERN_ERR "cannot initialize MIDI interface\n");
- return NULL;
- }
- }
-
- if (snd_rawmidi_new (card, "WaveFront MIDI", midi_dev, 1, 1, &rmidi) < 0)
- return NULL;
-
- if (mpu == internal_mpu) {
- strcpy(rmidi->name, "WaveFront MIDI (Internal)");
- rmidi->private_data = &internal_id;
- } else {
- strcpy(rmidi->name, "WaveFront MIDI (External)");
- rmidi->private_data = &external_id;
- }
-
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_wavefront_midi_output);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_wavefront_midi_input);
-
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
-
- return rmidi;
-}
-
-static void
-snd_wavefront_free(struct snd_card *card)
-{
- snd_wavefront_card_t *acard = (snd_wavefront_card_t *)card->private_data;
-
- if (acard) {
- release_and_free_resource(acard->wavefront.res_base);
- if (acard->wavefront.irq > 0)
- free_irq(acard->wavefront.irq, (void *)acard);
- }
-}
-
-static int snd_wavefront_card_new(int dev, struct snd_card **cardp)
-{
- struct snd_card *card;
- snd_wavefront_card_t *acard;
- int err;
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(snd_wavefront_card_t), &card);
- if (err < 0)
- return err;
-
- acard = card->private_data;
- acard->wavefront.irq = -1;
- spin_lock_init(&acard->wavefront.irq_lock);
- init_waitqueue_head(&acard->wavefront.interrupt_sleeper);
- spin_lock_init(&acard->wavefront.midi.open);
- spin_lock_init(&acard->wavefront.midi.virtual);
- acard->wavefront.card = card;
- card->private_free = snd_wavefront_free;
-
- *cardp = card;
- return 0;
-}
-
-static int __devinit
-snd_wavefront_probe (struct snd_card *card, int dev)
-{
- snd_wavefront_card_t *acard = card->private_data;
- struct snd_wss *chip;
- struct snd_hwdep *wavefront_synth;
- struct snd_rawmidi *ics2115_internal_rmidi = NULL;
- struct snd_rawmidi *ics2115_external_rmidi = NULL;
- struct snd_hwdep *fx_processor;
- int hw_dev = 0, midi_dev = 0, err;
-
- /* --------- PCM --------------- */
-
- err = snd_wss_create(card, cs4232_pcm_port[dev], -1,
- cs4232_pcm_irq[dev], dma1[dev], dma2[dev],
- WSS_HW_DETECT, 0, &chip);
- if (err < 0) {
- snd_printk(KERN_ERR "can't allocate WSS device\n");
- return err;
- }
-
- err = snd_wss_pcm(chip, 0, NULL);
- if (err < 0)
- return err;
-
- err = snd_wss_timer(chip, 0, NULL);
- if (err < 0)
- return err;
-
- /* ---------- OPL3 synth --------- */
-
- if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
- struct snd_opl3 *opl3;
-
- err = snd_opl3_create(card, fm_port[dev], fm_port[dev] + 2,
- OPL3_HW_OPL3_CS, 0, &opl3);
- if (err < 0) {
- snd_printk (KERN_ERR "can't allocate or detect OPL3 synth\n");
- return err;
- }
-
- err = snd_opl3_hwdep_new(opl3, hw_dev, 1, NULL);
- if (err < 0)
- return err;
- hw_dev++;
- }
-
- /* ------- ICS2115 Wavetable synth ------- */
-
- acard->wavefront.res_base = request_region(ics2115_port[dev], 16,
- "ICS2115");
- if (acard->wavefront.res_base == NULL) {
- snd_printk(KERN_ERR "unable to grab ICS2115 i/o region 0x%lx-0x%lx\n",
- ics2115_port[dev], ics2115_port[dev] + 16 - 1);
- return -EBUSY;
- }
- if (request_irq(ics2115_irq[dev], snd_wavefront_ics2115_interrupt,
- 0, "ICS2115", acard)) {
- snd_printk(KERN_ERR "unable to use ICS2115 IRQ %d\n", ics2115_irq[dev]);
- return -EBUSY;
- }
-
- acard->wavefront.irq = ics2115_irq[dev];
- acard->wavefront.base = ics2115_port[dev];
-
- wavefront_synth = snd_wavefront_new_synth(card, hw_dev, acard);
- if (wavefront_synth == NULL) {
- snd_printk (KERN_ERR "can't create WaveFront synth device\n");
- return -ENOMEM;
- }
-
- strcpy (wavefront_synth->name, "ICS2115 Wavetable MIDI Synthesizer");
- wavefront_synth->iface = SNDRV_HWDEP_IFACE_ICS2115;
- hw_dev++;
-
- /* --------- Mixer ------------ */
-
- err = snd_wss_mixer(chip);
- if (err < 0) {
- snd_printk (KERN_ERR "can't allocate mixer device\n");
- return err;
- }
-
- /* -------- CS4232 MPU-401 interface -------- */
-
- if (cs4232_mpu_port[dev] > 0 && cs4232_mpu_port[dev] != SNDRV_AUTO_PORT) {
- err = snd_mpu401_uart_new(card, midi_dev, MPU401_HW_CS4232,
- cs4232_mpu_port[dev], 0,
- cs4232_mpu_irq[dev], NULL);
- if (err < 0) {
- snd_printk (KERN_ERR "can't allocate CS4232 MPU-401 device\n");
- return err;
- }
- midi_dev++;
- }
-
- /* ------ ICS2115 internal MIDI ------------ */
-
- if (ics2115_port[dev] > 0 && ics2115_port[dev] != SNDRV_AUTO_PORT) {
- ics2115_internal_rmidi =
- snd_wavefront_new_midi (card,
- midi_dev,
- acard,
- ics2115_port[dev],
- internal_mpu);
- if (ics2115_internal_rmidi == NULL) {
- snd_printk (KERN_ERR "can't setup ICS2115 internal MIDI device\n");
- return -ENOMEM;
- }
- midi_dev++;
- }
-
- /* ------ ICS2115 external MIDI ------------ */
-
- if (ics2115_port[dev] > 0 && ics2115_port[dev] != SNDRV_AUTO_PORT) {
- ics2115_external_rmidi =
- snd_wavefront_new_midi (card,
- midi_dev,
- acard,
- ics2115_port[dev],
- external_mpu);
- if (ics2115_external_rmidi == NULL) {
- snd_printk (KERN_ERR "can't setup ICS2115 external MIDI device\n");
- return -ENOMEM;
- }
- midi_dev++;
- }
-
- /* FX processor for Tropez+ */
-
- if (acard->wavefront.has_fx) {
- fx_processor = snd_wavefront_new_fx (card,
- hw_dev,
- acard,
- ics2115_port[dev]);
- if (fx_processor == NULL) {
- snd_printk (KERN_ERR "can't setup FX device\n");
- return -ENOMEM;
- }
-
- hw_dev++;
-
- strcpy(card->driver, "Tropez+");
- strcpy(card->shortname, "Turtle Beach Tropez+");
- } else {
- /* Need a way to distinguish between Maui and Tropez */
- strcpy(card->driver, "WaveFront");
- strcpy(card->shortname, "Turtle Beach WaveFront");
- }
-
- /* ----- Register the card --------- */
-
- /* Not safe to include "Turtle Beach" in longname, due to
- length restrictions
- */
-
- sprintf(card->longname, "%s PCM 0x%lx irq %d dma %d",
- card->driver,
- chip->port,
- cs4232_pcm_irq[dev],
- dma1[dev]);
-
- if (dma2[dev] >= 0 && dma2[dev] < 8)
- sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]);
-
- if (cs4232_mpu_port[dev] > 0 && cs4232_mpu_port[dev] != SNDRV_AUTO_PORT) {
- sprintf (card->longname + strlen (card->longname),
- " MPU-401 0x%lx irq %d",
- cs4232_mpu_port[dev],
- cs4232_mpu_irq[dev]);
- }
-
- sprintf (card->longname + strlen (card->longname),
- " SYNTH 0x%lx irq %d",
- ics2115_port[dev],
- ics2115_irq[dev]);
-
- return snd_card_register(card);
-}
-
-static int __devinit snd_wavefront_isa_match(struct device *pdev,
- unsigned int dev)
-{
- if (!enable[dev])
- return 0;
-#ifdef CONFIG_PNP
- if (isapnp[dev])
- return 0;
-#endif
- if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) {
- snd_printk(KERN_ERR "specify CS4232 port\n");
- return 0;
- }
- if (ics2115_port[dev] == SNDRV_AUTO_PORT) {
- snd_printk(KERN_ERR "specify ICS2115 port\n");
- return 0;
- }
- return 1;
-}
-
-static int __devinit snd_wavefront_isa_probe(struct device *pdev,
- unsigned int dev)
-{
- struct snd_card *card;
- int err;
-
- err = snd_wavefront_card_new(dev, &card);
- if (err < 0)
- return err;
- snd_card_set_dev(card, pdev);
- if ((err = snd_wavefront_probe(card, dev)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- dev_set_drvdata(pdev, card);
- return 0;
-}
-
-static int __devexit snd_wavefront_isa_remove(struct device *devptr,
- unsigned int dev)
-{
- snd_card_free(dev_get_drvdata(devptr));
- dev_set_drvdata(devptr, NULL);
- return 0;
-}
-
-#define DEV_NAME "wavefront"
-
-static struct isa_driver snd_wavefront_driver = {
- .match = snd_wavefront_isa_match,
- .probe = snd_wavefront_isa_probe,
- .remove = __devexit_p(snd_wavefront_isa_remove),
- /* FIXME: suspend, resume */
- .driver = {
- .name = DEV_NAME
- },
-};
-
-
-#ifdef CONFIG_PNP
-static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard,
- const struct pnp_card_device_id *pid)
-{
- static int dev;
- struct snd_card *card;
- int res;
-
- for ( ; dev < SNDRV_CARDS; dev++) {
- if (enable[dev] && isapnp[dev])
- break;
- }
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
-
- res = snd_wavefront_card_new(dev, &card);
- if (res < 0)
- return res;
-
- if (snd_wavefront_pnp (dev, card->private_data, pcard, pid) < 0) {
- if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) {
- snd_printk (KERN_ERR "isapnp detection failed\n");
- snd_card_free (card);
- return -ENODEV;
- }
- }
- snd_card_set_dev(card, &pcard->card->dev);
-
- if ((res = snd_wavefront_probe(card, dev)) < 0)
- return res;
-
- pnp_set_card_drvdata(pcard, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_wavefront_pnp_remove(struct pnp_card_link * pcard)
-{
- snd_card_free(pnp_get_card_drvdata(pcard));
- pnp_set_card_drvdata(pcard, NULL);
-}
-
-static struct pnp_card_driver wavefront_pnpc_driver = {
- .flags = PNP_DRIVER_RES_DISABLE,
- .name = "wavefront",
- .id_table = snd_wavefront_pnpids,
- .probe = snd_wavefront_pnp_detect,
- .remove = __devexit_p(snd_wavefront_pnp_remove),
- /* FIXME: suspend,resume */
-};
-
-#endif /* CONFIG_PNP */
-
-static int __init alsa_card_wavefront_init(void)
-{
- int err;
-
- err = isa_register_driver(&snd_wavefront_driver, SNDRV_CARDS);
-#ifdef CONFIG_PNP
- if (!err)
- isa_registered = 1;
-
- err = pnp_register_card_driver(&wavefront_pnpc_driver);
- if (!err)
- pnp_registered = 1;
-
- if (isa_registered)
- err = 0;
-#endif
- return err;
-}
-
-static void __exit alsa_card_wavefront_exit(void)
-{
-#ifdef CONFIG_PNP
- if (pnp_registered)
- pnp_unregister_card_driver(&wavefront_pnpc_driver);
- if (isa_registered)
-#endif
- isa_unregister_driver(&snd_wavefront_driver);
-}
-
-module_init(alsa_card_wavefront_init)
-module_exit(alsa_card_wavefront_exit)
diff --git a/ANDROID_3.4.5/sound/isa/wavefront/wavefront_fx.c b/ANDROID_3.4.5/sound/isa/wavefront/wavefront_fx.c
deleted file mode 100644
index e51e0906..00000000
--- a/ANDROID_3.4.5/sound/isa/wavefront/wavefront_fx.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (c) 1998-2002 by Paul Davis <pbd@op.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <asm/io.h>
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <sound/core.h>
-#include <sound/snd_wavefront.h>
-#include <sound/initval.h>
-
-/* Control bits for the Load Control Register
- */
-
-#define FX_LSB_TRANSFER 0x01 /* transfer after DSP LSB byte written */
-#define FX_MSB_TRANSFER 0x02 /* transfer after DSP MSB byte written */
-#define FX_AUTO_INCR 0x04 /* auto-increment DSP address after transfer */
-
-#define WAIT_IDLE 0xff
-
-static int
-wavefront_fx_idle (snd_wavefront_t *dev)
-
-{
- int i;
- unsigned int x = 0x80;
-
- for (i = 0; i < 1000; i++) {
- x = inb (dev->fx_status);
- if ((x & 0x80) == 0) {
- break;
- }
- }
-
- if (x & 0x80) {
- snd_printk ("FX device never idle.\n");
- return 0;
- }
-
- return (1);
-}
-
-static void
-wavefront_fx_mute (snd_wavefront_t *dev, int onoff)
-
-{
- if (!wavefront_fx_idle(dev)) {
- return;
- }
-
- outb (onoff ? 0x02 : 0x00, dev->fx_op);
-}
-
-static int
-wavefront_fx_memset (snd_wavefront_t *dev,
- int page,
- int addr,
- int cnt,
- unsigned short *data)
-{
- if (page < 0 || page > 7) {
- snd_printk ("FX memset: "
- "page must be >= 0 and <= 7\n");
- return -(EINVAL);
- }
-
- if (addr < 0 || addr > 0x7f) {
- snd_printk ("FX memset: "
- "addr must be >= 0 and <= 7f\n");
- return -(EINVAL);
- }
-
- if (cnt == 1) {
-
- outb (FX_LSB_TRANSFER, dev->fx_lcr);
- outb (page, dev->fx_dsp_page);
- outb (addr, dev->fx_dsp_addr);
- outb ((data[0] >> 8), dev->fx_dsp_msb);
- outb ((data[0] & 0xff), dev->fx_dsp_lsb);
-
- snd_printk ("FX: addr %d:%x set to 0x%x\n",
- page, addr, data[0]);
-
- } else {
- int i;
-
- outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr);
- outb (page, dev->fx_dsp_page);
- outb (addr, dev->fx_dsp_addr);
-
- for (i = 0; i < cnt; i++) {
- outb ((data[i] >> 8), dev->fx_dsp_msb);
- outb ((data[i] & 0xff), dev->fx_dsp_lsb);
- if (!wavefront_fx_idle (dev)) {
- break;
- }
- }
-
- if (i != cnt) {
- snd_printk ("FX memset "
- "(0x%x, 0x%x, 0x%lx, %d) incomplete\n",
- page, addr, (unsigned long) data, cnt);
- return -(EIO);
- }
- }
-
- return 0;
-}
-
-int
-snd_wavefront_fx_detect (snd_wavefront_t *dev)
-
-{
- /* This is a crude check, but its the best one I have for now.
- Certainly on the Maui and the Tropez, wavefront_fx_idle() will
- report "never idle", which suggests that this test should
- work OK.
- */
-
- if (inb (dev->fx_status) & 0x80) {
- snd_printk ("Hmm, probably a Maui or Tropez.\n");
- return -1;
- }
-
- return 0;
-}
-
-int
-snd_wavefront_fx_open (struct snd_hwdep *hw, struct file *file)
-
-{
- if (!try_module_get(hw->card->module))
- return -EFAULT;
- file->private_data = hw;
- return 0;
-}
-
-int
-snd_wavefront_fx_release (struct snd_hwdep *hw, struct file *file)
-
-{
- module_put(hw->card->module);
- return 0;
-}
-
-int
-snd_wavefront_fx_ioctl (struct snd_hwdep *sdev, struct file *file,
- unsigned int cmd, unsigned long arg)
-
-{
- struct snd_card *card;
- snd_wavefront_card_t *acard;
- snd_wavefront_t *dev;
- wavefront_fx_info r;
- unsigned short *page_data = NULL;
- unsigned short *pd;
- int err = 0;
-
- card = sdev->card;
- if (snd_BUG_ON(!card))
- return -ENODEV;
- if (snd_BUG_ON(!card->private_data))
- return -ENODEV;
-
- acard = card->private_data;
- dev = &acard->wavefront;
-
- if (copy_from_user (&r, (void __user *)arg, sizeof (wavefront_fx_info)))
- return -EFAULT;
-
- switch (r.request) {
- case WFFX_MUTE:
- wavefront_fx_mute (dev, r.data[0]);
- return -EIO;
-
- case WFFX_MEMSET:
- if (r.data[2] <= 0) {
- snd_printk ("cannot write "
- "<= 0 bytes to FX\n");
- return -EIO;
- } else if (r.data[2] == 1) {
- pd = (unsigned short *) &r.data[3];
- } else {
- if (r.data[2] > 256) {
- snd_printk ("cannot write "
- "> 512 bytes to FX\n");
- return -EIO;
- }
- page_data = memdup_user((unsigned char __user *)
- r.data[3],
- r.data[2] * sizeof(short));
- if (IS_ERR(page_data))
- return PTR_ERR(page_data);
- pd = page_data;
- }
-
- err = wavefront_fx_memset (dev,
- r.data[0], /* page */
- r.data[1], /* addr */
- r.data[2], /* cnt */
- pd);
- kfree(page_data);
- break;
-
- default:
- snd_printk ("FX: ioctl %d not yet supported\n",
- r.request);
- return -ENOTTY;
- }
- return err;
-}
-
-/* YSS225 initialization.
-
- This code was developed using DOSEMU. The Turtle Beach SETUPSND
- utility was run with I/O tracing in DOSEMU enabled, and a reconstruction
- of the port I/O done, using the Yamaha faxback document as a guide
- to add more logic to the code. Its really pretty weird.
-
- This is the approach of just dumping the whole I/O
- sequence as a series of port/value pairs and a simple loop
- that outputs it.
-*/
-
-int __devinit
-snd_wavefront_fx_start (snd_wavefront_t *dev)
-{
- unsigned int i;
- int err;
- const struct firmware *firmware = NULL;
-
- if (dev->fx_initialized)
- return 0;
-
- err = request_firmware(&firmware, "yamaha/yss225_registers.bin",
- dev->card->dev);
- if (err < 0) {
- err = -1;
- goto out;
- }
-
- for (i = 0; i + 1 < firmware->size; i += 2) {
- if (firmware->data[i] >= 8 && firmware->data[i] < 16) {
- outb(firmware->data[i + 1],
- dev->base + firmware->data[i]);
- } else if (firmware->data[i] == WAIT_IDLE) {
- if (!wavefront_fx_idle(dev)) {
- err = -1;
- goto out;
- }
- } else {
- snd_printk(KERN_ERR "invalid address"
- " in register data\n");
- err = -1;
- goto out;
- }
- }
-
- dev->fx_initialized = 1;
- err = 0;
-
-out:
- release_firmware(firmware);
- return err;
-}
-
-MODULE_FIRMWARE("yamaha/yss225_registers.bin");
diff --git a/ANDROID_3.4.5/sound/isa/wavefront/wavefront_midi.c b/ANDROID_3.4.5/sound/isa/wavefront/wavefront_midi.c
deleted file mode 100644
index 65329f3a..00000000
--- a/ANDROID_3.4.5/sound/isa/wavefront/wavefront_midi.c
+++ /dev/null
@@ -1,577 +0,0 @@
-/*
- * Copyright (C) by Paul Barton-Davis 1998-1999
- *
- * This file is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this
- * software for more info.
- */
-
-/* The low level driver for the WaveFront ICS2115 MIDI interface(s)
- *
- * Note that there is also an MPU-401 emulation (actually, a UART-401
- * emulation) on the CS4232 on the Tropez and Tropez Plus. This code
- * has nothing to do with that interface at all.
- *
- * The interface is essentially just a UART-401, but is has the
- * interesting property of supporting what Turtle Beach called
- * "Virtual MIDI" mode. In this mode, there are effectively *two*
- * MIDI buses accessible via the interface, one that is routed
- * solely to/from the external WaveFront synthesizer and the other
- * corresponding to the pin/socket connector used to link external
- * MIDI devices to the board.
- *
- * This driver fully supports this mode, allowing two distinct MIDI
- * busses to be used completely independently, giving 32 channels of
- * MIDI routing, 16 to the WaveFront synth and 16 to the external MIDI
- * bus. The devices are named /dev/snd/midiCnD0 and /dev/snd/midiCnD1,
- * where `n' is the card number. Note that the device numbers may be
- * something other than 0 and 1 if the CS4232 UART/MPU-401 interface
- * is enabled.
- *
- * Switching between the two is accomplished externally by the driver
- * using the two otherwise unused MIDI bytes. See the code for more details.
- *
- * NOTE: VIRTUAL MIDI MODE IS ON BY DEFAULT (see lowlevel/isa/wavefront.c)
- *
- * The main reason to turn off Virtual MIDI mode is when you want to
- * tightly couple the WaveFront synth with an external MIDI
- * device. You won't be able to distinguish the source of any MIDI
- * data except via SysEx ID, but thats probably OK, since for the most
- * part, the WaveFront won't be sending any MIDI data at all.
- *
- * The main reason to turn on Virtual MIDI Mode is to provide two
- * completely independent 16-channel MIDI buses, one to the
- * WaveFront and one to any external MIDI devices. Given the 32
- * voice nature of the WaveFront, its pretty easy to find a use
- * for all 16 channels driving just that synth.
- *
- */
-
-#include <asm/io.h>
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <sound/core.h>
-#include <sound/snd_wavefront.h>
-
-static inline int
-wf_mpu_status (snd_wavefront_midi_t *midi)
-
-{
- return inb (midi->mpu_status_port);
-}
-
-static inline int
-input_avail (snd_wavefront_midi_t *midi)
-
-{
- return !(wf_mpu_status(midi) & INPUT_AVAIL);
-}
-
-static inline int
-output_ready (snd_wavefront_midi_t *midi)
-
-{
- return !(wf_mpu_status(midi) & OUTPUT_READY);
-}
-
-static inline int
-read_data (snd_wavefront_midi_t *midi)
-
-{
- return inb (midi->mpu_data_port);
-}
-
-static inline void
-write_data (snd_wavefront_midi_t *midi, unsigned char byte)
-
-{
- outb (byte, midi->mpu_data_port);
-}
-
-static snd_wavefront_midi_t *
-get_wavefront_midi (struct snd_rawmidi_substream *substream)
-
-{
- struct snd_card *card;
- snd_wavefront_card_t *acard;
-
- if (substream == NULL || substream->rmidi == NULL)
- return NULL;
-
- card = substream->rmidi->card;
-
- if (card == NULL)
- return NULL;
-
- if (card->private_data == NULL)
- return NULL;
-
- acard = card->private_data;
-
- return &acard->wavefront.midi;
-}
-
-static void snd_wavefront_midi_output_write(snd_wavefront_card_t *card)
-{
- snd_wavefront_midi_t *midi = &card->wavefront.midi;
- snd_wavefront_mpu_id mpu;
- unsigned long flags;
- unsigned char midi_byte;
- int max = 256, mask = 1;
- int timeout;
-
- /* Its not OK to try to change the status of "virtuality" of
- the MIDI interface while we're outputting stuff. See
- snd_wavefront_midi_{enable,disable}_virtual () for the
- other half of this.
-
- The first loop attempts to flush any data from the
- current output device, and then the second
- emits the switch byte (if necessary), and starts
- outputting data for the output device currently in use.
- */
-
- if (midi->substream_output[midi->output_mpu] == NULL) {
- goto __second;
- }
-
- while (max > 0) {
-
- /* XXX fix me - no hard timing loops allowed! */
-
- for (timeout = 30000; timeout > 0; timeout--) {
- if (output_ready (midi))
- break;
- }
-
- spin_lock_irqsave (&midi->virtual, flags);
- if ((midi->mode[midi->output_mpu] & MPU401_MODE_OUTPUT) == 0) {
- spin_unlock_irqrestore (&midi->virtual, flags);
- goto __second;
- }
- if (output_ready (midi)) {
- if (snd_rawmidi_transmit(midi->substream_output[midi->output_mpu], &midi_byte, 1) == 1) {
- if (!midi->isvirtual ||
- (midi_byte != WF_INTERNAL_SWITCH &&
- midi_byte != WF_EXTERNAL_SWITCH))
- write_data(midi, midi_byte);
- max--;
- } else {
- if (midi->istimer) {
- if (--midi->istimer <= 0)
- del_timer(&midi->timer);
- }
- midi->mode[midi->output_mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
- spin_unlock_irqrestore (&midi->virtual, flags);
- goto __second;
- }
- } else {
- spin_unlock_irqrestore (&midi->virtual, flags);
- return;
- }
- spin_unlock_irqrestore (&midi->virtual, flags);
- }
-
- __second:
-
- if (midi->substream_output[!midi->output_mpu] == NULL) {
- return;
- }
-
- while (max > 0) {
-
- /* XXX fix me - no hard timing loops allowed! */
-
- for (timeout = 30000; timeout > 0; timeout--) {
- if (output_ready (midi))
- break;
- }
-
- spin_lock_irqsave (&midi->virtual, flags);
- if (!midi->isvirtual)
- mask = 0;
- mpu = midi->output_mpu ^ mask;
- mask = 0; /* don't invert the value from now */
- if ((midi->mode[mpu] & MPU401_MODE_OUTPUT) == 0) {
- spin_unlock_irqrestore (&midi->virtual, flags);
- return;
- }
- if (snd_rawmidi_transmit_empty(midi->substream_output[mpu]))
- goto __timer;
- if (output_ready (midi)) {
- if (mpu != midi->output_mpu) {
- write_data(midi, mpu == internal_mpu ?
- WF_INTERNAL_SWITCH :
- WF_EXTERNAL_SWITCH);
- midi->output_mpu = mpu;
- } else if (snd_rawmidi_transmit(midi->substream_output[mpu], &midi_byte, 1) == 1) {
- if (!midi->isvirtual ||
- (midi_byte != WF_INTERNAL_SWITCH &&
- midi_byte != WF_EXTERNAL_SWITCH))
- write_data(midi, midi_byte);
- max--;
- } else {
- __timer:
- if (midi->istimer) {
- if (--midi->istimer <= 0)
- del_timer(&midi->timer);
- }
- midi->mode[mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
- spin_unlock_irqrestore (&midi->virtual, flags);
- return;
- }
- } else {
- spin_unlock_irqrestore (&midi->virtual, flags);
- return;
- }
- spin_unlock_irqrestore (&midi->virtual, flags);
- }
-}
-
-static int snd_wavefront_midi_input_open(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- snd_wavefront_midi_t *midi;
- snd_wavefront_mpu_id mpu;
-
- if (snd_BUG_ON(!substream || !substream->rmidi))
- return -ENXIO;
- if (snd_BUG_ON(!substream->rmidi->private_data))
- return -ENXIO;
-
- mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
-
- if ((midi = get_wavefront_midi (substream)) == NULL)
- return -EIO;
-
- spin_lock_irqsave (&midi->open, flags);
- midi->mode[mpu] |= MPU401_MODE_INPUT;
- midi->substream_input[mpu] = substream;
- spin_unlock_irqrestore (&midi->open, flags);
-
- return 0;
-}
-
-static int snd_wavefront_midi_output_open(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- snd_wavefront_midi_t *midi;
- snd_wavefront_mpu_id mpu;
-
- if (snd_BUG_ON(!substream || !substream->rmidi))
- return -ENXIO;
- if (snd_BUG_ON(!substream->rmidi->private_data))
- return -ENXIO;
-
- mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
-
- if ((midi = get_wavefront_midi (substream)) == NULL)
- return -EIO;
-
- spin_lock_irqsave (&midi->open, flags);
- midi->mode[mpu] |= MPU401_MODE_OUTPUT;
- midi->substream_output[mpu] = substream;
- spin_unlock_irqrestore (&midi->open, flags);
-
- return 0;
-}
-
-static int snd_wavefront_midi_input_close(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- snd_wavefront_midi_t *midi;
- snd_wavefront_mpu_id mpu;
-
- if (snd_BUG_ON(!substream || !substream->rmidi))
- return -ENXIO;
- if (snd_BUG_ON(!substream->rmidi->private_data))
- return -ENXIO;
-
- mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
-
- if ((midi = get_wavefront_midi (substream)) == NULL)
- return -EIO;
-
- spin_lock_irqsave (&midi->open, flags);
- midi->mode[mpu] &= ~MPU401_MODE_INPUT;
- spin_unlock_irqrestore (&midi->open, flags);
-
- return 0;
-}
-
-static int snd_wavefront_midi_output_close(struct snd_rawmidi_substream *substream)
-{
- unsigned long flags;
- snd_wavefront_midi_t *midi;
- snd_wavefront_mpu_id mpu;
-
- if (snd_BUG_ON(!substream || !substream->rmidi))
- return -ENXIO;
- if (snd_BUG_ON(!substream->rmidi->private_data))
- return -ENXIO;
-
- mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
-
- if ((midi = get_wavefront_midi (substream)) == NULL)
- return -EIO;
-
- spin_lock_irqsave (&midi->open, flags);
- midi->mode[mpu] &= ~MPU401_MODE_OUTPUT;
- spin_unlock_irqrestore (&midi->open, flags);
- return 0;
-}
-
-static void snd_wavefront_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- unsigned long flags;
- snd_wavefront_midi_t *midi;
- snd_wavefront_mpu_id mpu;
-
- if (substream == NULL || substream->rmidi == NULL)
- return;
-
- if (substream->rmidi->private_data == NULL)
- return;
-
- mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
-
- if ((midi = get_wavefront_midi (substream)) == NULL) {
- return;
- }
-
- spin_lock_irqsave (&midi->virtual, flags);
- if (up) {
- midi->mode[mpu] |= MPU401_MODE_INPUT_TRIGGER;
- } else {
- midi->mode[mpu] &= ~MPU401_MODE_INPUT_TRIGGER;
- }
- spin_unlock_irqrestore (&midi->virtual, flags);
-}
-
-static void snd_wavefront_midi_output_timer(unsigned long data)
-{
- snd_wavefront_card_t *card = (snd_wavefront_card_t *)data;
- snd_wavefront_midi_t *midi = &card->wavefront.midi;
- unsigned long flags;
-
- spin_lock_irqsave (&midi->virtual, flags);
- midi->timer.expires = 1 + jiffies;
- add_timer(&midi->timer);
- spin_unlock_irqrestore (&midi->virtual, flags);
- snd_wavefront_midi_output_write(card);
-}
-
-static void snd_wavefront_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- unsigned long flags;
- snd_wavefront_midi_t *midi;
- snd_wavefront_mpu_id mpu;
-
- if (substream == NULL || substream->rmidi == NULL)
- return;
-
- if (substream->rmidi->private_data == NULL)
- return;
-
- mpu = *((snd_wavefront_mpu_id *) substream->rmidi->private_data);
-
- if ((midi = get_wavefront_midi (substream)) == NULL) {
- return;
- }
-
- spin_lock_irqsave (&midi->virtual, flags);
- if (up) {
- if ((midi->mode[mpu] & MPU401_MODE_OUTPUT_TRIGGER) == 0) {
- if (!midi->istimer) {
- init_timer(&midi->timer);
- midi->timer.function = snd_wavefront_midi_output_timer;
- midi->timer.data = (unsigned long) substream->rmidi->card->private_data;
- midi->timer.expires = 1 + jiffies;
- add_timer(&midi->timer);
- }
- midi->istimer++;
- midi->mode[mpu] |= MPU401_MODE_OUTPUT_TRIGGER;
- }
- } else {
- midi->mode[mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER;
- }
- spin_unlock_irqrestore (&midi->virtual, flags);
-
- if (up)
- snd_wavefront_midi_output_write((snd_wavefront_card_t *)substream->rmidi->card->private_data);
-}
-
-void
-snd_wavefront_midi_interrupt (snd_wavefront_card_t *card)
-
-{
- unsigned long flags;
- snd_wavefront_midi_t *midi;
- static struct snd_rawmidi_substream *substream = NULL;
- static int mpu = external_mpu;
- int max = 128;
- unsigned char byte;
-
- midi = &card->wavefront.midi;
-
- if (!input_avail (midi)) { /* not for us */
- snd_wavefront_midi_output_write(card);
- return;
- }
-
- spin_lock_irqsave (&midi->virtual, flags);
- while (--max) {
-
- if (input_avail (midi)) {
- byte = read_data (midi);
-
- if (midi->isvirtual) {
- if (byte == WF_EXTERNAL_SWITCH) {
- substream = midi->substream_input[external_mpu];
- mpu = external_mpu;
- } else if (byte == WF_INTERNAL_SWITCH) {
- substream = midi->substream_output[internal_mpu];
- mpu = internal_mpu;
- } /* else just leave it as it is */
- } else {
- substream = midi->substream_input[internal_mpu];
- mpu = internal_mpu;
- }
-
- if (substream == NULL) {
- continue;
- }
-
- if (midi->mode[mpu] & MPU401_MODE_INPUT_TRIGGER) {
- snd_rawmidi_receive(substream, &byte, 1);
- }
- } else {
- break;
- }
- }
- spin_unlock_irqrestore (&midi->virtual, flags);
-
- snd_wavefront_midi_output_write(card);
-}
-
-void
-snd_wavefront_midi_enable_virtual (snd_wavefront_card_t *card)
-
-{
- unsigned long flags;
-
- spin_lock_irqsave (&card->wavefront.midi.virtual, flags);
- card->wavefront.midi.isvirtual = 1;
- card->wavefront.midi.output_mpu = internal_mpu;
- card->wavefront.midi.input_mpu = internal_mpu;
- spin_unlock_irqrestore (&card->wavefront.midi.virtual, flags);
-}
-
-void
-snd_wavefront_midi_disable_virtual (snd_wavefront_card_t *card)
-
-{
- unsigned long flags;
-
- spin_lock_irqsave (&card->wavefront.midi.virtual, flags);
- // snd_wavefront_midi_input_close (card->ics2115_external_rmidi);
- // snd_wavefront_midi_output_close (card->ics2115_external_rmidi);
- card->wavefront.midi.isvirtual = 0;
- spin_unlock_irqrestore (&card->wavefront.midi.virtual, flags);
-}
-
-int __devinit
-snd_wavefront_midi_start (snd_wavefront_card_t *card)
-
-{
- int ok, i;
- unsigned char rbuf[4], wbuf[4];
- snd_wavefront_t *dev;
- snd_wavefront_midi_t *midi;
-
- dev = &card->wavefront;
- midi = &dev->midi;
-
- /* The ICS2115 MPU-401 interface doesn't do anything
- until its set into UART mode.
- */
-
- /* XXX fix me - no hard timing loops allowed! */
-
- for (i = 0; i < 30000 && !output_ready (midi); i++);
-
- if (!output_ready (midi)) {
- snd_printk ("MIDI interface not ready for command\n");
- return -1;
- }
-
- /* Any interrupts received from now on
- are owned by the MIDI side of things.
- */
-
- dev->interrupts_are_midi = 1;
-
- outb (UART_MODE_ON, midi->mpu_command_port);
-
- for (ok = 0, i = 50000; i > 0 && !ok; i--) {
- if (input_avail (midi)) {
- if (read_data (midi) == MPU_ACK) {
- ok = 1;
- break;
- }
- }
- }
-
- if (!ok) {
- snd_printk ("cannot set UART mode for MIDI interface");
- dev->interrupts_are_midi = 0;
- return -1;
- }
-
- /* Route external MIDI to WaveFront synth (by default) */
-
- if (snd_wavefront_cmd (dev, WFC_MISYNTH_ON, rbuf, wbuf)) {
- snd_printk ("can't enable MIDI-IN-2-synth routing.\n");
- /* XXX error ? */
- }
-
- /* Turn on Virtual MIDI, but first *always* turn it off,
- since otherwise consecutive reloads of the driver will
- never cause the hardware to generate the initial "internal" or
- "external" source bytes in the MIDI data stream. This
- is pretty important, since the internal hardware generally will
- be used to generate none or very little MIDI output, and
- thus the only source of MIDI data is actually external. Without
- the switch bytes, the driver will think it all comes from
- the internal interface. Duh.
- */
-
- if (snd_wavefront_cmd (dev, WFC_VMIDI_OFF, rbuf, wbuf)) {
- snd_printk ("virtual MIDI mode not disabled\n");
- return 0; /* We're OK, but missing the external MIDI dev */
- }
-
- snd_wavefront_midi_enable_virtual (card);
-
- if (snd_wavefront_cmd (dev, WFC_VMIDI_ON, rbuf, wbuf)) {
- snd_printk ("cannot enable virtual MIDI mode.\n");
- snd_wavefront_midi_disable_virtual (card);
- }
- return 0;
-}
-
-struct snd_rawmidi_ops snd_wavefront_midi_output =
-{
- .open = snd_wavefront_midi_output_open,
- .close = snd_wavefront_midi_output_close,
- .trigger = snd_wavefront_midi_output_trigger,
-};
-
-struct snd_rawmidi_ops snd_wavefront_midi_input =
-{
- .open = snd_wavefront_midi_input_open,
- .close = snd_wavefront_midi_input_close,
- .trigger = snd_wavefront_midi_input_trigger,
-};
-
diff --git a/ANDROID_3.4.5/sound/isa/wavefront/wavefront_synth.c b/ANDROID_3.4.5/sound/isa/wavefront/wavefront_synth.c
deleted file mode 100644
index 405f8b6a..00000000
--- a/ANDROID_3.4.5/sound/isa/wavefront/wavefront_synth.c
+++ /dev/null
@@ -1,2199 +0,0 @@
-/* Copyright (C) by Paul Barton-Davis 1998-1999
- *
- * Some portions of this file are taken from work that is
- * copyright (C) by Hannu Savolainen 1993-1996
- *
- * This program is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-
-/*
- * An ALSA lowlevel driver for Turtle Beach ICS2115 wavetable synth
- * (Maui, Tropez, Tropez Plus)
- *
- * This driver supports the onboard wavetable synthesizer (an ICS2115),
- * including patch, sample and program loading and unloading, conversion
- * of GUS patches during loading, and full user-level access to all
- * WaveFront commands. It tries to provide semi-intelligent patch and
- * sample management as well.
- *
- */
-
-#include <asm/io.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/firmware.h>
-#include <linux/moduleparam.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/snd_wavefront.h>
-#include <sound/initval.h>
-
-static int wf_raw = 0; /* we normally check for "raw state" to firmware
- loading. if non-zero, then during driver loading, the
- state of the board is ignored, and we reset the
- board and load the firmware anyway.
- */
-
-static int fx_raw = 1; /* if this is zero, we'll leave the FX processor in
- whatever state it is when the driver is loaded.
- The default is to download the microprogram and
- associated coefficients to set it up for "default"
- operation, whatever that means.
- */
-
-static int debug_default = 0; /* you can set this to control debugging
- during driver loading. it takes any combination
- of the WF_DEBUG_* flags defined in
- wavefront.h
- */
-
-/* XXX this needs to be made firmware and hardware version dependent */
-
-#define DEFAULT_OSPATH "wavefront.os"
-static char *ospath = DEFAULT_OSPATH; /* the firmware file name */
-
-static int wait_usecs = 150; /* This magic number seems to give pretty optimal
- throughput based on my limited experimentation.
- If you want to play around with it and find a better
- value, be my guest. Remember, the idea is to
- get a number that causes us to just busy wait
- for as many WaveFront commands as possible, without
- coming up with a number so large that we hog the
- whole CPU.
-
- Specifically, with this number, out of about 134,000
- status waits, only about 250 result in a sleep.
- */
-
-static int sleep_interval = 100; /* HZ/sleep_interval seconds per sleep */
-static int sleep_tries = 50; /* number of times we'll try to sleep */
-
-static int reset_time = 2; /* hundreths of a second we wait after a HW
- reset for the expected interrupt.
- */
-
-static int ramcheck_time = 20; /* time in seconds to wait while ROM code
- checks on-board RAM.
- */
-
-static int osrun_time = 10; /* time in seconds we wait for the OS to
- start running.
- */
-module_param(wf_raw, int, 0444);
-MODULE_PARM_DESC(wf_raw, "if non-zero, assume that we need to boot the OS");
-module_param(fx_raw, int, 0444);
-MODULE_PARM_DESC(fx_raw, "if non-zero, assume that the FX process needs help");
-module_param(debug_default, int, 0444);
-MODULE_PARM_DESC(debug_default, "debug parameters for card initialization");
-module_param(wait_usecs, int, 0444);
-MODULE_PARM_DESC(wait_usecs, "how long to wait without sleeping, usecs");
-module_param(sleep_interval, int, 0444);
-MODULE_PARM_DESC(sleep_interval, "how long to sleep when waiting for reply");
-module_param(sleep_tries, int, 0444);
-MODULE_PARM_DESC(sleep_tries, "how many times to try sleeping during a wait");
-module_param(ospath, charp, 0444);
-MODULE_PARM_DESC(ospath, "pathname to processed ICS2115 OS firmware");
-module_param(reset_time, int, 0444);
-MODULE_PARM_DESC(reset_time, "how long to wait for a reset to take effect");
-module_param(ramcheck_time, int, 0444);
-MODULE_PARM_DESC(ramcheck_time, "how many seconds to wait for the RAM test");
-module_param(osrun_time, int, 0444);
-MODULE_PARM_DESC(osrun_time, "how many seconds to wait for the ICS2115 OS");
-
-/* if WF_DEBUG not defined, no run-time debugging messages will
- be available via the debug flag setting. Given the current
- beta state of the driver, this will remain set until a future
- version.
-*/
-
-#define WF_DEBUG 1
-
-#ifdef WF_DEBUG
-
-#define DPRINT(cond, ...) \
- if ((dev->debug & (cond)) == (cond)) { \
- snd_printk (__VA_ARGS__); \
- }
-#else
-#define DPRINT(cond, args...)
-#endif /* WF_DEBUG */
-
-#define LOGNAME "WaveFront: "
-
-/* bitmasks for WaveFront status port value */
-
-#define STAT_RINTR_ENABLED 0x01
-#define STAT_CAN_READ 0x02
-#define STAT_INTR_READ 0x04
-#define STAT_WINTR_ENABLED 0x10
-#define STAT_CAN_WRITE 0x20
-#define STAT_INTR_WRITE 0x40
-
-static int wavefront_delete_sample (snd_wavefront_t *, int sampnum);
-static int wavefront_find_free_sample (snd_wavefront_t *);
-
-struct wavefront_command {
- int cmd;
- char *action;
- unsigned int read_cnt;
- unsigned int write_cnt;
- int need_ack;
-};
-
-static struct {
- int errno;
- const char *errstr;
-} wavefront_errors[] = {
- { 0x01, "Bad sample number" },
- { 0x02, "Out of sample memory" },
- { 0x03, "Bad patch number" },
- { 0x04, "Error in number of voices" },
- { 0x06, "Sample load already in progress" },
- { 0x0B, "No sample load request pending" },
- { 0x0E, "Bad MIDI channel number" },
- { 0x10, "Download Record Error" },
- { 0x80, "Success" },
- { 0x0 }
-};
-
-#define NEEDS_ACK 1
-
-static struct wavefront_command wavefront_commands[] = {
- { WFC_SET_SYNTHVOL, "set synthesizer volume", 0, 1, NEEDS_ACK },
- { WFC_GET_SYNTHVOL, "get synthesizer volume", 1, 0, 0},
- { WFC_SET_NVOICES, "set number of voices", 0, 1, NEEDS_ACK },
- { WFC_GET_NVOICES, "get number of voices", 1, 0, 0 },
- { WFC_SET_TUNING, "set synthesizer tuning", 0, 2, NEEDS_ACK },
- { WFC_GET_TUNING, "get synthesizer tuning", 2, 0, 0 },
- { WFC_DISABLE_CHANNEL, "disable synth channel", 0, 1, NEEDS_ACK },
- { WFC_ENABLE_CHANNEL, "enable synth channel", 0, 1, NEEDS_ACK },
- { WFC_GET_CHANNEL_STATUS, "get synth channel status", 3, 0, 0 },
- { WFC_MISYNTH_OFF, "disable midi-in to synth", 0, 0, NEEDS_ACK },
- { WFC_MISYNTH_ON, "enable midi-in to synth", 0, 0, NEEDS_ACK },
- { WFC_VMIDI_ON, "enable virtual midi mode", 0, 0, NEEDS_ACK },
- { WFC_VMIDI_OFF, "disable virtual midi mode", 0, 0, NEEDS_ACK },
- { WFC_MIDI_STATUS, "report midi status", 1, 0, 0 },
- { WFC_FIRMWARE_VERSION, "report firmware version", 2, 0, 0 },
- { WFC_HARDWARE_VERSION, "report hardware version", 2, 0, 0 },
- { WFC_GET_NSAMPLES, "report number of samples", 2, 0, 0 },
- { WFC_INSTOUT_LEVELS, "report instantaneous output levels", 7, 0, 0 },
- { WFC_PEAKOUT_LEVELS, "report peak output levels", 7, 0, 0 },
- { WFC_DOWNLOAD_SAMPLE, "download sample",
- 0, WF_SAMPLE_BYTES, NEEDS_ACK },
- { WFC_DOWNLOAD_BLOCK, "download block", 0, 0, NEEDS_ACK},
- { WFC_DOWNLOAD_SAMPLE_HEADER, "download sample header",
- 0, WF_SAMPLE_HDR_BYTES, NEEDS_ACK },
- { WFC_UPLOAD_SAMPLE_HEADER, "upload sample header", 13, 2, 0 },
-
- /* This command requires a variable number of bytes to be written.
- There is a hack in snd_wavefront_cmd() to support this. The actual
- count is passed in as the read buffer ptr, cast appropriately.
- Ugh.
- */
-
- { WFC_DOWNLOAD_MULTISAMPLE, "download multisample", 0, 0, NEEDS_ACK },
-
- /* This one is a hack as well. We just read the first byte of the
- response, don't fetch an ACK, and leave the rest to the
- calling function. Ugly, ugly, ugly.
- */
-
- { WFC_UPLOAD_MULTISAMPLE, "upload multisample", 2, 1, 0 },
- { WFC_DOWNLOAD_SAMPLE_ALIAS, "download sample alias",
- 0, WF_ALIAS_BYTES, NEEDS_ACK },
- { WFC_UPLOAD_SAMPLE_ALIAS, "upload sample alias", WF_ALIAS_BYTES, 2, 0},
- { WFC_DELETE_SAMPLE, "delete sample", 0, 2, NEEDS_ACK },
- { WFC_IDENTIFY_SAMPLE_TYPE, "identify sample type", 5, 2, 0 },
- { WFC_UPLOAD_SAMPLE_PARAMS, "upload sample parameters" },
- { WFC_REPORT_FREE_MEMORY, "report free memory", 4, 0, 0 },
- { WFC_DOWNLOAD_PATCH, "download patch", 0, 134, NEEDS_ACK },
- { WFC_UPLOAD_PATCH, "upload patch", 132, 2, 0 },
- { WFC_DOWNLOAD_PROGRAM, "download program", 0, 33, NEEDS_ACK },
- { WFC_UPLOAD_PROGRAM, "upload program", 32, 1, 0 },
- { WFC_DOWNLOAD_EDRUM_PROGRAM, "download enhanced drum program", 0, 9,
- NEEDS_ACK},
- { WFC_UPLOAD_EDRUM_PROGRAM, "upload enhanced drum program", 8, 1, 0},
- { WFC_SET_EDRUM_CHANNEL, "set enhanced drum program channel",
- 0, 1, NEEDS_ACK },
- { WFC_DISABLE_DRUM_PROGRAM, "disable drum program", 0, 1, NEEDS_ACK },
- { WFC_REPORT_CHANNEL_PROGRAMS, "report channel program numbers",
- 32, 0, 0 },
- { WFC_NOOP, "the no-op command", 0, 0, NEEDS_ACK },
- { 0x00 }
-};
-
-static const char *
-wavefront_errorstr (int errnum)
-
-{
- int i;
-
- for (i = 0; wavefront_errors[i].errstr; i++) {
- if (wavefront_errors[i].errno == errnum) {
- return wavefront_errors[i].errstr;
- }
- }
-
- return "Unknown WaveFront error";
-}
-
-static struct wavefront_command *
-wavefront_get_command (int cmd)
-
-{
- int i;
-
- for (i = 0; wavefront_commands[i].cmd != 0; i++) {
- if (cmd == wavefront_commands[i].cmd) {
- return &wavefront_commands[i];
- }
- }
-
- return NULL;
-}
-
-static inline int
-wavefront_status (snd_wavefront_t *dev)
-
-{
- return inb (dev->status_port);
-}
-
-static int
-wavefront_sleep (int limit)
-
-{
- schedule_timeout_interruptible(limit);
-
- return signal_pending(current);
-}
-
-static int
-wavefront_wait (snd_wavefront_t *dev, int mask)
-
-{
- int i;
-
- /* Spin for a short period of time, because >99% of all
- requests to the WaveFront can be serviced inline like this.
- */
-
- for (i = 0; i < wait_usecs; i += 5) {
- if (wavefront_status (dev) & mask) {
- return 1;
- }
- udelay(5);
- }
-
- for (i = 0; i < sleep_tries; i++) {
-
- if (wavefront_status (dev) & mask) {
- return 1;
- }
-
- if (wavefront_sleep (HZ/sleep_interval)) {
- return (0);
- }
- }
-
- return (0);
-}
-
-static int
-wavefront_read (snd_wavefront_t *dev)
-
-{
- if (wavefront_wait (dev, STAT_CAN_READ))
- return inb (dev->data_port);
-
- DPRINT (WF_DEBUG_DATA, "read timeout.\n");
-
- return -1;
-}
-
-static int
-wavefront_write (snd_wavefront_t *dev, unsigned char data)
-
-{
- if (wavefront_wait (dev, STAT_CAN_WRITE)) {
- outb (data, dev->data_port);
- return 0;
- }
-
- DPRINT (WF_DEBUG_DATA, "write timeout.\n");
-
- return -1;
-}
-
-int
-snd_wavefront_cmd (snd_wavefront_t *dev,
- int cmd, unsigned char *rbuf, unsigned char *wbuf)
-
-{
- int ack;
- unsigned int i;
- int c;
- struct wavefront_command *wfcmd;
-
- if ((wfcmd = wavefront_get_command (cmd)) == NULL) {
- snd_printk ("command 0x%x not supported.\n",
- cmd);
- return 1;
- }
-
- /* Hack to handle the one variable-size write command. See
- wavefront_send_multisample() for the other half of this
- gross and ugly strategy.
- */
-
- if (cmd == WFC_DOWNLOAD_MULTISAMPLE) {
- wfcmd->write_cnt = (unsigned long) rbuf;
- rbuf = NULL;
- }
-
- DPRINT (WF_DEBUG_CMD, "0x%x [%s] (%d,%d,%d)\n",
- cmd, wfcmd->action, wfcmd->read_cnt,
- wfcmd->write_cnt, wfcmd->need_ack);
-
- if (wavefront_write (dev, cmd)) {
- DPRINT ((WF_DEBUG_IO|WF_DEBUG_CMD), "cannot request "
- "0x%x [%s].\n",
- cmd, wfcmd->action);
- return 1;
- }
-
- if (wfcmd->write_cnt > 0) {
- DPRINT (WF_DEBUG_DATA, "writing %d bytes "
- "for 0x%x\n",
- wfcmd->write_cnt, cmd);
-
- for (i = 0; i < wfcmd->write_cnt; i++) {
- if (wavefront_write (dev, wbuf[i])) {
- DPRINT (WF_DEBUG_IO, "bad write for byte "
- "%d of 0x%x [%s].\n",
- i, cmd, wfcmd->action);
- return 1;
- }
-
- DPRINT (WF_DEBUG_DATA, "write[%d] = 0x%x\n",
- i, wbuf[i]);
- }
- }
-
- if (wfcmd->read_cnt > 0) {
- DPRINT (WF_DEBUG_DATA, "reading %d ints "
- "for 0x%x\n",
- wfcmd->read_cnt, cmd);
-
- for (i = 0; i < wfcmd->read_cnt; i++) {
-
- if ((c = wavefront_read (dev)) == -1) {
- DPRINT (WF_DEBUG_IO, "bad read for byte "
- "%d of 0x%x [%s].\n",
- i, cmd, wfcmd->action);
- return 1;
- }
-
- /* Now handle errors. Lots of special cases here */
-
- if (c == 0xff) {
- if ((c = wavefront_read (dev)) == -1) {
- DPRINT (WF_DEBUG_IO, "bad read for "
- "error byte at "
- "read byte %d "
- "of 0x%x [%s].\n",
- i, cmd,
- wfcmd->action);
- return 1;
- }
-
- /* Can you believe this madness ? */
-
- if (c == 1 &&
- wfcmd->cmd == WFC_IDENTIFY_SAMPLE_TYPE) {
- rbuf[0] = WF_ST_EMPTY;
- return (0);
-
- } else if (c == 3 &&
- wfcmd->cmd == WFC_UPLOAD_PATCH) {
-
- return 3;
-
- } else if (c == 1 &&
- wfcmd->cmd == WFC_UPLOAD_PROGRAM) {
-
- return 1;
-
- } else {
-
- DPRINT (WF_DEBUG_IO, "error %d (%s) "
- "during "
- "read for byte "
- "%d of 0x%x "
- "[%s].\n",
- c,
- wavefront_errorstr (c),
- i, cmd,
- wfcmd->action);
- return 1;
-
- }
-
- } else {
- rbuf[i] = c;
- }
-
- DPRINT (WF_DEBUG_DATA, "read[%d] = 0x%x\n",i, rbuf[i]);
- }
- }
-
- if ((wfcmd->read_cnt == 0 && wfcmd->write_cnt == 0) || wfcmd->need_ack) {
-
- DPRINT (WF_DEBUG_CMD, "reading ACK for 0x%x\n", cmd);
-
- /* Some commands need an ACK, but return zero instead
- of the standard value.
- */
-
- if ((ack = wavefront_read (dev)) == 0) {
- ack = WF_ACK;
- }
-
- if (ack != WF_ACK) {
- if (ack == -1) {
- DPRINT (WF_DEBUG_IO, "cannot read ack for "
- "0x%x [%s].\n",
- cmd, wfcmd->action);
- return 1;
-
- } else {
- int err = -1; /* something unknown */
-
- if (ack == 0xff) { /* explicit error */
-
- if ((err = wavefront_read (dev)) == -1) {
- DPRINT (WF_DEBUG_DATA,
- "cannot read err "
- "for 0x%x [%s].\n",
- cmd, wfcmd->action);
- }
- }
-
- DPRINT (WF_DEBUG_IO, "0x%x [%s] "
- "failed (0x%x, 0x%x, %s)\n",
- cmd, wfcmd->action, ack, err,
- wavefront_errorstr (err));
-
- return -err;
- }
- }
-
- DPRINT (WF_DEBUG_DATA, "ack received "
- "for 0x%x [%s]\n",
- cmd, wfcmd->action);
- } else {
-
- DPRINT (WF_DEBUG_CMD, "0x%x [%s] does not need "
- "ACK (%d,%d,%d)\n",
- cmd, wfcmd->action, wfcmd->read_cnt,
- wfcmd->write_cnt, wfcmd->need_ack);
- }
-
- return 0;
-
-}
-
-/***********************************************************************
-WaveFront data munging
-
-Things here are weird. All data written to the board cannot
-have its most significant bit set. Any data item with values
-potentially > 0x7F (127) must be split across multiple bytes.
-
-Sometimes, we need to munge numeric values that are represented on
-the x86 side as 8-32 bit values. Sometimes, we need to munge data
-that is represented on the x86 side as an array of bytes. The most
-efficient approach to handling both cases seems to be to use 2
-different functions for munging and 2 for de-munging. This avoids
-weird casting and worrying about bit-level offsets.
-
-**********************************************************************/
-
-static unsigned char *
-munge_int32 (unsigned int src,
- unsigned char *dst,
- unsigned int dst_size)
-{
- unsigned int i;
-
- for (i = 0; i < dst_size; i++) {
- *dst = src & 0x7F; /* Mask high bit of LSB */
- src = src >> 7; /* Rotate Right 7 bits */
- /* Note: we leave the upper bits in place */
-
- dst++;
- };
- return dst;
-};
-
-static int
-demunge_int32 (unsigned char* src, int src_size)
-
-{
- int i;
- int outval = 0;
-
- for (i = src_size - 1; i >= 0; i--) {
- outval=(outval<<7)+src[i];
- }
-
- return outval;
-};
-
-static
-unsigned char *
-munge_buf (unsigned char *src, unsigned char *dst, unsigned int dst_size)
-
-{
- unsigned int i;
- unsigned int last = dst_size / 2;
-
- for (i = 0; i < last; i++) {
- *dst++ = src[i] & 0x7f;
- *dst++ = src[i] >> 7;
- }
- return dst;
-}
-
-static
-unsigned char *
-demunge_buf (unsigned char *src, unsigned char *dst, unsigned int src_bytes)
-
-{
- int i;
- unsigned char *end = src + src_bytes;
-
- end = src + src_bytes;
-
- /* NOTE: src and dst *CAN* point to the same address */
-
- for (i = 0; src != end; i++) {
- dst[i] = *src++;
- dst[i] |= (*src++)<<7;
- }
-
- return dst;
-}
-
-/***********************************************************************
-WaveFront: sample, patch and program management.
-***********************************************************************/
-
-static int
-wavefront_delete_sample (snd_wavefront_t *dev, int sample_num)
-
-{
- unsigned char wbuf[2];
- int x;
-
- wbuf[0] = sample_num & 0x7f;
- wbuf[1] = sample_num >> 7;
-
- if ((x = snd_wavefront_cmd (dev, WFC_DELETE_SAMPLE, NULL, wbuf)) == 0) {
- dev->sample_status[sample_num] = WF_ST_EMPTY;
- }
-
- return x;
-}
-
-static int
-wavefront_get_sample_status (snd_wavefront_t *dev, int assume_rom)
-
-{
- int i;
- unsigned char rbuf[32], wbuf[32];
- unsigned int sc_real, sc_alias, sc_multi;
-
- /* check sample status */
-
- if (snd_wavefront_cmd (dev, WFC_GET_NSAMPLES, rbuf, wbuf)) {
- snd_printk ("cannot request sample count.\n");
- return -1;
- }
-
- sc_real = sc_alias = sc_multi = dev->samples_used = 0;
-
- for (i = 0; i < WF_MAX_SAMPLE; i++) {
-
- wbuf[0] = i & 0x7f;
- wbuf[1] = i >> 7;
-
- if (snd_wavefront_cmd (dev, WFC_IDENTIFY_SAMPLE_TYPE, rbuf, wbuf)) {
- snd_printk(KERN_WARNING "cannot identify sample "
- "type of slot %d\n", i);
- dev->sample_status[i] = WF_ST_EMPTY;
- continue;
- }
-
- dev->sample_status[i] = (WF_SLOT_FILLED|rbuf[0]);
-
- if (assume_rom) {
- dev->sample_status[i] |= WF_SLOT_ROM;
- }
-
- switch (rbuf[0] & WF_ST_MASK) {
- case WF_ST_SAMPLE:
- sc_real++;
- break;
- case WF_ST_MULTISAMPLE:
- sc_multi++;
- break;
- case WF_ST_ALIAS:
- sc_alias++;
- break;
- case WF_ST_EMPTY:
- break;
-
- default:
- snd_printk ("unknown sample type for "
- "slot %d (0x%x)\n",
- i, rbuf[0]);
- }
-
- if (rbuf[0] != WF_ST_EMPTY) {
- dev->samples_used++;
- }
- }
-
- snd_printk ("%d samples used (%d real, %d aliases, %d multi), "
- "%d empty\n", dev->samples_used, sc_real, sc_alias, sc_multi,
- WF_MAX_SAMPLE - dev->samples_used);
-
-
- return (0);
-
-}
-
-static int
-wavefront_get_patch_status (snd_wavefront_t *dev)
-
-{
- unsigned char patchbuf[WF_PATCH_BYTES];
- unsigned char patchnum[2];
- wavefront_patch *p;
- int i, x, cnt, cnt2;
-
- for (i = 0; i < WF_MAX_PATCH; i++) {
- patchnum[0] = i & 0x7f;
- patchnum[1] = i >> 7;
-
- if ((x = snd_wavefront_cmd (dev, WFC_UPLOAD_PATCH, patchbuf,
- patchnum)) == 0) {
-
- dev->patch_status[i] |= WF_SLOT_FILLED;
- p = (wavefront_patch *) patchbuf;
- dev->sample_status
- [p->sample_number|(p->sample_msb<<7)] |=
- WF_SLOT_USED;
-
- } else if (x == 3) { /* Bad patch number */
- dev->patch_status[i] = 0;
- } else {
- snd_printk ("upload patch "
- "error 0x%x\n", x);
- dev->patch_status[i] = 0;
- return 1;
- }
- }
-
- /* program status has already filled in slot_used bits */
-
- for (i = 0, cnt = 0, cnt2 = 0; i < WF_MAX_PATCH; i++) {
- if (dev->patch_status[i] & WF_SLOT_FILLED) {
- cnt++;
- }
- if (dev->patch_status[i] & WF_SLOT_USED) {
- cnt2++;
- }
-
- }
- snd_printk ("%d patch slots filled, %d in use\n", cnt, cnt2);
-
- return (0);
-}
-
-static int
-wavefront_get_program_status (snd_wavefront_t *dev)
-
-{
- unsigned char progbuf[WF_PROGRAM_BYTES];
- wavefront_program prog;
- unsigned char prognum;
- int i, x, l, cnt;
-
- for (i = 0; i < WF_MAX_PROGRAM; i++) {
- prognum = i;
-
- if ((x = snd_wavefront_cmd (dev, WFC_UPLOAD_PROGRAM, progbuf,
- &prognum)) == 0) {
-
- dev->prog_status[i] |= WF_SLOT_USED;
-
- demunge_buf (progbuf, (unsigned char *) &prog,
- WF_PROGRAM_BYTES);
-
- for (l = 0; l < WF_NUM_LAYERS; l++) {
- if (prog.layer[l].mute) {
- dev->patch_status
- [prog.layer[l].patch_number] |=
- WF_SLOT_USED;
- }
- }
- } else if (x == 1) { /* Bad program number */
- dev->prog_status[i] = 0;
- } else {
- snd_printk ("upload program "
- "error 0x%x\n", x);
- dev->prog_status[i] = 0;
- }
- }
-
- for (i = 0, cnt = 0; i < WF_MAX_PROGRAM; i++) {
- if (dev->prog_status[i]) {
- cnt++;
- }
- }
-
- snd_printk ("%d programs slots in use\n", cnt);
-
- return (0);
-}
-
-static int
-wavefront_send_patch (snd_wavefront_t *dev, wavefront_patch_info *header)
-
-{
- unsigned char buf[WF_PATCH_BYTES+2];
- unsigned char *bptr;
-
- DPRINT (WF_DEBUG_LOAD_PATCH, "downloading patch %d\n",
- header->number);
-
- dev->patch_status[header->number] |= WF_SLOT_FILLED;
-
- bptr = buf;
- bptr = munge_int32 (header->number, buf, 2);
- munge_buf ((unsigned char *)&header->hdr.p, bptr, WF_PATCH_BYTES);
-
- if (snd_wavefront_cmd (dev, WFC_DOWNLOAD_PATCH, NULL, buf)) {
- snd_printk ("download patch failed\n");
- return -(EIO);
- }
-
- return (0);
-}
-
-static int
-wavefront_send_program (snd_wavefront_t *dev, wavefront_patch_info *header)
-
-{
- unsigned char buf[WF_PROGRAM_BYTES+1];
- int i;
-
- DPRINT (WF_DEBUG_LOAD_PATCH, "downloading program %d\n",
- header->number);
-
- dev->prog_status[header->number] = WF_SLOT_USED;
-
- /* XXX need to zero existing SLOT_USED bit for program_status[i]
- where `i' is the program that's being (potentially) overwritten.
- */
-
- for (i = 0; i < WF_NUM_LAYERS; i++) {
- if (header->hdr.pr.layer[i].mute) {
- dev->patch_status[header->hdr.pr.layer[i].patch_number] |=
- WF_SLOT_USED;
-
- /* XXX need to mark SLOT_USED for sample used by
- patch_number, but this means we have to load it. Ick.
- */
- }
- }
-
- buf[0] = header->number;
- munge_buf ((unsigned char *)&header->hdr.pr, &buf[1], WF_PROGRAM_BYTES);
-
- if (snd_wavefront_cmd (dev, WFC_DOWNLOAD_PROGRAM, NULL, buf)) {
- snd_printk ("download patch failed\n");
- return -(EIO);
- }
-
- return (0);
-}
-
-static int
-wavefront_freemem (snd_wavefront_t *dev)
-
-{
- char rbuf[8];
-
- if (snd_wavefront_cmd (dev, WFC_REPORT_FREE_MEMORY, rbuf, NULL)) {
- snd_printk ("can't get memory stats.\n");
- return -1;
- } else {
- return demunge_int32 (rbuf, 4);
- }
-}
-
-static int
-wavefront_send_sample (snd_wavefront_t *dev,
- wavefront_patch_info *header,
- u16 __user *dataptr,
- int data_is_unsigned)
-
-{
- /* samples are downloaded via a 16-bit wide i/o port
- (you could think of it as 2 adjacent 8-bit wide ports
- but its less efficient that way). therefore, all
- the blocksizes and so forth listed in the documentation,
- and used conventionally to refer to sample sizes,
- which are given in 8-bit units (bytes), need to be
- divided by 2.
- */
-
- u16 sample_short = 0;
- u32 length;
- u16 __user *data_end = NULL;
- unsigned int i;
- const unsigned int max_blksize = 4096/2;
- unsigned int written;
- unsigned int blocksize;
- int dma_ack;
- int blocknum;
- unsigned char sample_hdr[WF_SAMPLE_HDR_BYTES];
- unsigned char *shptr;
- int skip = 0;
- int initial_skip = 0;
-
- DPRINT (WF_DEBUG_LOAD_PATCH, "sample %sdownload for slot %d, "
- "type %d, %d bytes from 0x%lx\n",
- header->size ? "" : "header ",
- header->number, header->subkey,
- header->size,
- (unsigned long) header->dataptr);
-
- if (header->number == WAVEFRONT_FIND_FREE_SAMPLE_SLOT) {
- int x;
-
- if ((x = wavefront_find_free_sample (dev)) < 0) {
- return -ENOMEM;
- }
- snd_printk ("unspecified sample => %d\n", x);
- header->number = x;
- }
-
- if (header->size) {
-
- /* XXX it's a debatable point whether or not RDONLY semantics
- on the ROM samples should cover just the sample data or
- the sample header. For now, it only covers the sample data,
- so anyone is free at all times to rewrite sample headers.
-
- My reason for this is that we have the sample headers
- available in the WFB file for General MIDI, and so these
- can always be reset if needed. The sample data, however,
- cannot be recovered without a complete reset and firmware
- reload of the ICS2115, which is a very expensive operation.
-
- So, doing things this way allows us to honor the notion of
- "RESETSAMPLES" reasonably cheaply. Note however, that this
- is done purely at user level: there is no WFB parser in
- this driver, and so a complete reset (back to General MIDI,
- or theoretically some other configuration) is the
- responsibility of the user level library.
-
- To try to do this in the kernel would be a little
- crazy: we'd need 158K of kernel space just to hold
- a copy of the patch/program/sample header data.
- */
-
- if (dev->rom_samples_rdonly) {
- if (dev->sample_status[header->number] & WF_SLOT_ROM) {
- snd_printk ("sample slot %d "
- "write protected\n",
- header->number);
- return -EACCES;
- }
- }
-
- wavefront_delete_sample (dev, header->number);
- }
-
- if (header->size) {
- dev->freemem = wavefront_freemem (dev);
-
- if (dev->freemem < (int)header->size) {
- snd_printk ("insufficient memory to "
- "load %d byte sample.\n",
- header->size);
- return -ENOMEM;
- }
-
- }
-
- skip = WF_GET_CHANNEL(&header->hdr.s);
-
- if (skip > 0 && header->hdr.s.SampleResolution != LINEAR_16BIT) {
- snd_printk ("channel selection only "
- "possible on 16-bit samples");
- return -(EINVAL);
- }
-
- switch (skip) {
- case 0:
- initial_skip = 0;
- skip = 1;
- break;
- case 1:
- initial_skip = 0;
- skip = 2;
- break;
- case 2:
- initial_skip = 1;
- skip = 2;
- break;
- case 3:
- initial_skip = 2;
- skip = 3;
- break;
- case 4:
- initial_skip = 3;
- skip = 4;
- break;
- case 5:
- initial_skip = 4;
- skip = 5;
- break;
- case 6:
- initial_skip = 5;
- skip = 6;
- break;
- }
-
- DPRINT (WF_DEBUG_LOAD_PATCH, "channel selection: %d => "
- "initial skip = %d, skip = %d\n",
- WF_GET_CHANNEL (&header->hdr.s),
- initial_skip, skip);
-
- /* Be safe, and zero the "Unused" bits ... */
-
- WF_SET_CHANNEL(&header->hdr.s, 0);
-
- /* adjust size for 16 bit samples by dividing by two. We always
- send 16 bits per write, even for 8 bit samples, so the length
- is always half the size of the sample data in bytes.
- */
-
- length = header->size / 2;
-
- /* the data we're sent has not been munged, and in fact, the
- header we have to send isn't just a munged copy either.
- so, build the sample header right here.
- */
-
- shptr = &sample_hdr[0];
-
- shptr = munge_int32 (header->number, shptr, 2);
-
- if (header->size) {
- shptr = munge_int32 (length, shptr, 4);
- }
-
- /* Yes, a 4 byte result doesn't contain all of the offset bits,
- but the offset only uses 24 bits.
- */
-
- shptr = munge_int32 (*((u32 *) &header->hdr.s.sampleStartOffset),
- shptr, 4);
- shptr = munge_int32 (*((u32 *) &header->hdr.s.loopStartOffset),
- shptr, 4);
- shptr = munge_int32 (*((u32 *) &header->hdr.s.loopEndOffset),
- shptr, 4);
- shptr = munge_int32 (*((u32 *) &header->hdr.s.sampleEndOffset),
- shptr, 4);
-
- /* This one is truly weird. What kind of weirdo decided that in
- a system dominated by 16 and 32 bit integers, they would use
- a just 12 bits ?
- */
-
- shptr = munge_int32 (header->hdr.s.FrequencyBias, shptr, 3);
-
- /* Why is this nybblified, when the MSB is *always* zero ?
- Anyway, we can't take address of bitfield, so make a
- good-faith guess at where it starts.
- */
-
- shptr = munge_int32 (*(&header->hdr.s.FrequencyBias+1),
- shptr, 2);
-
- if (snd_wavefront_cmd (dev,
- header->size ?
- WFC_DOWNLOAD_SAMPLE : WFC_DOWNLOAD_SAMPLE_HEADER,
- NULL, sample_hdr)) {
- snd_printk ("sample %sdownload refused.\n",
- header->size ? "" : "header ");
- return -(EIO);
- }
-
- if (header->size == 0) {
- goto sent; /* Sorry. Just had to have one somewhere */
- }
-
- data_end = dataptr + length;
-
- /* Do any initial skip over an unused channel's data */
-
- dataptr += initial_skip;
-
- for (written = 0, blocknum = 0;
- written < length; written += max_blksize, blocknum++) {
-
- if ((length - written) > max_blksize) {
- blocksize = max_blksize;
- } else {
- /* round to nearest 16-byte value */
- blocksize = ALIGN(length - written, 8);
- }
-
- if (snd_wavefront_cmd (dev, WFC_DOWNLOAD_BLOCK, NULL, NULL)) {
- snd_printk ("download block "
- "request refused.\n");
- return -(EIO);
- }
-
- for (i = 0; i < blocksize; i++) {
-
- if (dataptr < data_end) {
-
- __get_user (sample_short, dataptr);
- dataptr += skip;
-
- if (data_is_unsigned) { /* GUS ? */
-
- if (WF_SAMPLE_IS_8BIT(&header->hdr.s)) {
-
- /* 8 bit sample
- resolution, sign
- extend both bytes.
- */
-
- ((unsigned char*)
- &sample_short)[0] += 0x7f;
- ((unsigned char*)
- &sample_short)[1] += 0x7f;
-
- } else {
-
- /* 16 bit sample
- resolution, sign
- extend the MSB.
- */
-
- sample_short += 0x7fff;
- }
- }
-
- } else {
-
- /* In padding section of final block:
-
- Don't fetch unsupplied data from
- user space, just continue with
- whatever the final value was.
- */
- }
-
- if (i < blocksize - 1) {
- outw (sample_short, dev->block_port);
- } else {
- outw (sample_short, dev->last_block_port);
- }
- }
-
- /* Get "DMA page acknowledge", even though its really
- nothing to do with DMA at all.
- */
-
- if ((dma_ack = wavefront_read (dev)) != WF_DMA_ACK) {
- if (dma_ack == -1) {
- snd_printk ("upload sample "
- "DMA ack timeout\n");
- return -(EIO);
- } else {
- snd_printk ("upload sample "
- "DMA ack error 0x%x\n",
- dma_ack);
- return -(EIO);
- }
- }
- }
-
- dev->sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_SAMPLE);
-
- /* Note, label is here because sending the sample header shouldn't
- alter the sample_status info at all.
- */
-
- sent:
- return (0);
-}
-
-static int
-wavefront_send_alias (snd_wavefront_t *dev, wavefront_patch_info *header)
-
-{
- unsigned char alias_hdr[WF_ALIAS_BYTES];
-
- DPRINT (WF_DEBUG_LOAD_PATCH, "download alias, %d is "
- "alias for %d\n",
- header->number,
- header->hdr.a.OriginalSample);
-
- munge_int32 (header->number, &alias_hdr[0], 2);
- munge_int32 (header->hdr.a.OriginalSample, &alias_hdr[2], 2);
- munge_int32 (*((unsigned int *)&header->hdr.a.sampleStartOffset),
- &alias_hdr[4], 4);
- munge_int32 (*((unsigned int *)&header->hdr.a.loopStartOffset),
- &alias_hdr[8], 4);
- munge_int32 (*((unsigned int *)&header->hdr.a.loopEndOffset),
- &alias_hdr[12], 4);
- munge_int32 (*((unsigned int *)&header->hdr.a.sampleEndOffset),
- &alias_hdr[16], 4);
- munge_int32 (header->hdr.a.FrequencyBias, &alias_hdr[20], 3);
- munge_int32 (*(&header->hdr.a.FrequencyBias+1), &alias_hdr[23], 2);
-
- if (snd_wavefront_cmd (dev, WFC_DOWNLOAD_SAMPLE_ALIAS, NULL, alias_hdr)) {
- snd_printk ("download alias failed.\n");
- return -(EIO);
- }
-
- dev->sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_ALIAS);
-
- return (0);
-}
-
-static int
-wavefront_send_multisample (snd_wavefront_t *dev, wavefront_patch_info *header)
-{
- int i;
- int num_samples;
- unsigned char *msample_hdr;
-
- msample_hdr = kmalloc(sizeof(WF_MSAMPLE_BYTES), GFP_KERNEL);
- if (! msample_hdr)
- return -ENOMEM;
-
- munge_int32 (header->number, &msample_hdr[0], 2);
-
- /* You'll recall at this point that the "number of samples" value
- in a wavefront_multisample struct is actually the log2 of the
- real number of samples.
- */
-
- num_samples = (1<<(header->hdr.ms.NumberOfSamples&7));
- msample_hdr[2] = (unsigned char) header->hdr.ms.NumberOfSamples;
-
- DPRINT (WF_DEBUG_LOAD_PATCH, "multi %d with %d=%d samples\n",
- header->number,
- header->hdr.ms.NumberOfSamples,
- num_samples);
-
- for (i = 0; i < num_samples; i++) {
- DPRINT(WF_DEBUG_LOAD_PATCH|WF_DEBUG_DATA, "sample[%d] = %d\n",
- i, header->hdr.ms.SampleNumber[i]);
- munge_int32 (header->hdr.ms.SampleNumber[i],
- &msample_hdr[3+(i*2)], 2);
- }
-
- /* Need a hack here to pass in the number of bytes
- to be written to the synth. This is ugly, and perhaps
- one day, I'll fix it.
- */
-
- if (snd_wavefront_cmd (dev, WFC_DOWNLOAD_MULTISAMPLE,
- (unsigned char *) (long) ((num_samples*2)+3),
- msample_hdr)) {
- snd_printk ("download of multisample failed.\n");
- kfree(msample_hdr);
- return -(EIO);
- }
-
- dev->sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_MULTISAMPLE);
-
- kfree(msample_hdr);
- return (0);
-}
-
-static int
-wavefront_fetch_multisample (snd_wavefront_t *dev,
- wavefront_patch_info *header)
-{
- int i;
- unsigned char log_ns[1];
- unsigned char number[2];
- int num_samples;
-
- munge_int32 (header->number, number, 2);
-
- if (snd_wavefront_cmd (dev, WFC_UPLOAD_MULTISAMPLE, log_ns, number)) {
- snd_printk ("upload multisample failed.\n");
- return -(EIO);
- }
-
- DPRINT (WF_DEBUG_DATA, "msample %d has %d samples\n",
- header->number, log_ns[0]);
-
- header->hdr.ms.NumberOfSamples = log_ns[0];
-
- /* get the number of samples ... */
-
- num_samples = (1 << log_ns[0]);
-
- for (i = 0; i < num_samples; i++) {
- char d[2];
- int val;
-
- if ((val = wavefront_read (dev)) == -1) {
- snd_printk ("upload multisample failed "
- "during sample loop.\n");
- return -(EIO);
- }
- d[0] = val;
-
- if ((val = wavefront_read (dev)) == -1) {
- snd_printk ("upload multisample failed "
- "during sample loop.\n");
- return -(EIO);
- }
- d[1] = val;
-
- header->hdr.ms.SampleNumber[i] =
- demunge_int32 ((unsigned char *) d, 2);
-
- DPRINT (WF_DEBUG_DATA, "msample sample[%d] = %d\n",
- i, header->hdr.ms.SampleNumber[i]);
- }
-
- return (0);
-}
-
-
-static int
-wavefront_send_drum (snd_wavefront_t *dev, wavefront_patch_info *header)
-
-{
- unsigned char drumbuf[WF_DRUM_BYTES];
- wavefront_drum *drum = &header->hdr.d;
- int i;
-
- DPRINT (WF_DEBUG_LOAD_PATCH, "downloading edrum for MIDI "
- "note %d, patch = %d\n",
- header->number, drum->PatchNumber);
-
- drumbuf[0] = header->number & 0x7f;
-
- for (i = 0; i < 4; i++) {
- munge_int32 (((unsigned char *)drum)[i], &drumbuf[1+(i*2)], 2);
- }
-
- if (snd_wavefront_cmd (dev, WFC_DOWNLOAD_EDRUM_PROGRAM, NULL, drumbuf)) {
- snd_printk ("download drum failed.\n");
- return -(EIO);
- }
-
- return (0);
-}
-
-static int
-wavefront_find_free_sample (snd_wavefront_t *dev)
-
-{
- int i;
-
- for (i = 0; i < WF_MAX_SAMPLE; i++) {
- if (!(dev->sample_status[i] & WF_SLOT_FILLED)) {
- return i;
- }
- }
- snd_printk ("no free sample slots!\n");
- return -1;
-}
-
-#if 0
-static int
-wavefront_find_free_patch (snd_wavefront_t *dev)
-
-{
- int i;
-
- for (i = 0; i < WF_MAX_PATCH; i++) {
- if (!(dev->patch_status[i] & WF_SLOT_FILLED)) {
- return i;
- }
- }
- snd_printk ("no free patch slots!\n");
- return -1;
-}
-#endif
-
-static int
-wavefront_load_patch (snd_wavefront_t *dev, const char __user *addr)
-{
- wavefront_patch_info *header;
- int err;
-
- header = kmalloc(sizeof(*header), GFP_KERNEL);
- if (! header)
- return -ENOMEM;
-
- if (copy_from_user (header, addr, sizeof(wavefront_patch_info) -
- sizeof(wavefront_any))) {
- snd_printk ("bad address for load patch.\n");
- err = -EFAULT;
- goto __error;
- }
-
- DPRINT (WF_DEBUG_LOAD_PATCH, "download "
- "Sample type: %d "
- "Sample number: %d "
- "Sample size: %d\n",
- header->subkey,
- header->number,
- header->size);
-
- switch (header->subkey) {
- case WF_ST_SAMPLE: /* sample or sample_header, based on patch->size */
-
- if (copy_from_user (&header->hdr.s, header->hdrptr,
- sizeof (wavefront_sample))) {
- err = -EFAULT;
- break;
- }
-
- err = wavefront_send_sample (dev, header, header->dataptr, 0);
- break;
-
- case WF_ST_MULTISAMPLE:
-
- if (copy_from_user (&header->hdr.s, header->hdrptr,
- sizeof (wavefront_multisample))) {
- err = -EFAULT;
- break;
- }
-
- err = wavefront_send_multisample (dev, header);
- break;
-
- case WF_ST_ALIAS:
-
- if (copy_from_user (&header->hdr.a, header->hdrptr,
- sizeof (wavefront_alias))) {
- err = -EFAULT;
- break;
- }
-
- err = wavefront_send_alias (dev, header);
- break;
-
- case WF_ST_DRUM:
- if (copy_from_user (&header->hdr.d, header->hdrptr,
- sizeof (wavefront_drum))) {
- err = -EFAULT;
- break;
- }
-
- err = wavefront_send_drum (dev, header);
- break;
-
- case WF_ST_PATCH:
- if (copy_from_user (&header->hdr.p, header->hdrptr,
- sizeof (wavefront_patch))) {
- err = -EFAULT;
- break;
- }
-
- err = wavefront_send_patch (dev, header);
- break;
-
- case WF_ST_PROGRAM:
- if (copy_from_user (&header->hdr.pr, header->hdrptr,
- sizeof (wavefront_program))) {
- err = -EFAULT;
- break;
- }
-
- err = wavefront_send_program (dev, header);
- break;
-
- default:
- snd_printk ("unknown patch type %d.\n",
- header->subkey);
- err = -EINVAL;
- break;
- }
-
- __error:
- kfree(header);
- return err;
-}
-
-/***********************************************************************
-WaveFront: hardware-dependent interface
-***********************************************************************/
-
-static void
-process_sample_hdr (u8 *buf)
-
-{
- wavefront_sample s;
- u8 *ptr;
-
- ptr = buf;
-
- /* The board doesn't send us an exact copy of a "wavefront_sample"
- in response to an Upload Sample Header command. Instead, we
- have to convert the data format back into our data structure,
- just as in the Download Sample command, where we have to do
- something very similar in the reverse direction.
- */
-
- *((u32 *) &s.sampleStartOffset) = demunge_int32 (ptr, 4); ptr += 4;
- *((u32 *) &s.loopStartOffset) = demunge_int32 (ptr, 4); ptr += 4;
- *((u32 *) &s.loopEndOffset) = demunge_int32 (ptr, 4); ptr += 4;
- *((u32 *) &s.sampleEndOffset) = demunge_int32 (ptr, 4); ptr += 4;
- *((u32 *) &s.FrequencyBias) = demunge_int32 (ptr, 3); ptr += 3;
-
- s.SampleResolution = *ptr & 0x3;
- s.Loop = *ptr & 0x8;
- s.Bidirectional = *ptr & 0x10;
- s.Reverse = *ptr & 0x40;
-
- /* Now copy it back to where it came from */
-
- memcpy (buf, (unsigned char *) &s, sizeof (wavefront_sample));
-}
-
-static int
-wavefront_synth_control (snd_wavefront_card_t *acard,
- wavefront_control *wc)
-
-{
- snd_wavefront_t *dev = &acard->wavefront;
- unsigned char patchnumbuf[2];
- int i;
-
- DPRINT (WF_DEBUG_CMD, "synth control with "
- "cmd 0x%x\n", wc->cmd);
-
- /* Pre-handling of or for various commands */
-
- switch (wc->cmd) {
-
- case WFC_DISABLE_INTERRUPTS:
- snd_printk ("interrupts disabled.\n");
- outb (0x80|0x20, dev->control_port);
- dev->interrupts_are_midi = 1;
- return 0;
-
- case WFC_ENABLE_INTERRUPTS:
- snd_printk ("interrupts enabled.\n");
- outb (0x80|0x40|0x20, dev->control_port);
- dev->interrupts_are_midi = 1;
- return 0;
-
- case WFC_INTERRUPT_STATUS:
- wc->rbuf[0] = dev->interrupts_are_midi;
- return 0;
-
- case WFC_ROMSAMPLES_RDONLY:
- dev->rom_samples_rdonly = wc->wbuf[0];
- wc->status = 0;
- return 0;
-
- case WFC_IDENTIFY_SLOT_TYPE:
- i = wc->wbuf[0] | (wc->wbuf[1] << 7);
- if (i <0 || i >= WF_MAX_SAMPLE) {
- snd_printk ("invalid slot ID %d\n",
- i);
- wc->status = EINVAL;
- return -EINVAL;
- }
- wc->rbuf[0] = dev->sample_status[i];
- wc->status = 0;
- return 0;
-
- case WFC_DEBUG_DRIVER:
- dev->debug = wc->wbuf[0];
- snd_printk ("debug = 0x%x\n", dev->debug);
- return 0;
-
- case WFC_UPLOAD_PATCH:
- munge_int32 (*((u32 *) wc->wbuf), patchnumbuf, 2);
- memcpy (wc->wbuf, patchnumbuf, 2);
- break;
-
- case WFC_UPLOAD_MULTISAMPLE:
- /* multisamples have to be handled differently, and
- cannot be dealt with properly by snd_wavefront_cmd() alone.
- */
- wc->status = wavefront_fetch_multisample
- (dev, (wavefront_patch_info *) wc->rbuf);
- return 0;
-
- case WFC_UPLOAD_SAMPLE_ALIAS:
- snd_printk ("support for sample alias upload "
- "being considered.\n");
- wc->status = EINVAL;
- return -EINVAL;
- }
-
- wc->status = snd_wavefront_cmd (dev, wc->cmd, wc->rbuf, wc->wbuf);
-
- /* Post-handling of certain commands.
-
- In particular, if the command was an upload, demunge the data
- so that the user-level doesn't have to think about it.
- */
-
- if (wc->status == 0) {
- switch (wc->cmd) {
- /* intercept any freemem requests so that we know
- we are always current with the user-level view
- of things.
- */
-
- case WFC_REPORT_FREE_MEMORY:
- dev->freemem = demunge_int32 (wc->rbuf, 4);
- break;
-
- case WFC_UPLOAD_PATCH:
- demunge_buf (wc->rbuf, wc->rbuf, WF_PATCH_BYTES);
- break;
-
- case WFC_UPLOAD_PROGRAM:
- demunge_buf (wc->rbuf, wc->rbuf, WF_PROGRAM_BYTES);
- break;
-
- case WFC_UPLOAD_EDRUM_PROGRAM:
- demunge_buf (wc->rbuf, wc->rbuf, WF_DRUM_BYTES - 1);
- break;
-
- case WFC_UPLOAD_SAMPLE_HEADER:
- process_sample_hdr (wc->rbuf);
- break;
-
- case WFC_UPLOAD_SAMPLE_ALIAS:
- snd_printk ("support for "
- "sample aliases still "
- "being considered.\n");
- break;
-
- case WFC_VMIDI_OFF:
- snd_wavefront_midi_disable_virtual (acard);
- break;
-
- case WFC_VMIDI_ON:
- snd_wavefront_midi_enable_virtual (acard);
- break;
- }
- }
-
- return 0;
-}
-
-int
-snd_wavefront_synth_open (struct snd_hwdep *hw, struct file *file)
-
-{
- if (!try_module_get(hw->card->module))
- return -EFAULT;
- file->private_data = hw;
- return 0;
-}
-
-int
-snd_wavefront_synth_release (struct snd_hwdep *hw, struct file *file)
-
-{
- module_put(hw->card->module);
- return 0;
-}
-
-int
-snd_wavefront_synth_ioctl (struct snd_hwdep *hw, struct file *file,
- unsigned int cmd, unsigned long arg)
-
-{
- struct snd_card *card;
- snd_wavefront_t *dev;
- snd_wavefront_card_t *acard;
- wavefront_control *wc;
- void __user *argp = (void __user *)arg;
- int err;
-
- card = (struct snd_card *) hw->card;
-
- if (snd_BUG_ON(!card))
- return -ENODEV;
- if (snd_BUG_ON(!card->private_data))
- return -ENODEV;
-
- acard = card->private_data;
- dev = &acard->wavefront;
-
- switch (cmd) {
- case WFCTL_LOAD_SPP:
- if (wavefront_load_patch (dev, argp) != 0) {
- return -EIO;
- }
- break;
-
- case WFCTL_WFCMD:
- wc = memdup_user(argp, sizeof(*wc));
- if (IS_ERR(wc))
- return PTR_ERR(wc);
-
- if (wavefront_synth_control (acard, wc) < 0)
- err = -EIO;
- else if (copy_to_user (argp, wc, sizeof (*wc)))
- err = -EFAULT;
- else
- err = 0;
- kfree(wc);
- return err;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-
-/***********************************************************************/
-/* WaveFront: interface for card-level wavefront module */
-/***********************************************************************/
-
-void
-snd_wavefront_internal_interrupt (snd_wavefront_card_t *card)
-{
- snd_wavefront_t *dev = &card->wavefront;
-
- /*
- Some comments on interrupts. I attempted a version of this
- driver that used interrupts throughout the code instead of
- doing busy and/or sleep-waiting. Alas, it appears that once
- the Motorola firmware is downloaded, the card *never*
- generates an RX interrupt. These are successfully generated
- during firmware loading, and after that wavefront_status()
- reports that an interrupt is pending on the card from time
- to time, but it never seems to be delivered to this
- driver. Note also that wavefront_status() continues to
- report that RX interrupts are enabled, suggesting that I
- didn't goof up and disable them by mistake.
-
- Thus, I stepped back to a prior version of
- wavefront_wait(), the only place where this really
- matters. Its sad, but I've looked through the code to check
- on things, and I really feel certain that the Motorola
- firmware prevents RX-ready interrupts.
- */
-
- if ((wavefront_status(dev) & (STAT_INTR_READ|STAT_INTR_WRITE)) == 0) {
- return;
- }
-
- spin_lock(&dev->irq_lock);
- dev->irq_ok = 1;
- dev->irq_cnt++;
- spin_unlock(&dev->irq_lock);
- wake_up(&dev->interrupt_sleeper);
-}
-
-/* STATUS REGISTER
-
-0 Host Rx Interrupt Enable (1=Enabled)
-1 Host Rx Register Full (1=Full)
-2 Host Rx Interrupt Pending (1=Interrupt)
-3 Unused
-4 Host Tx Interrupt (1=Enabled)
-5 Host Tx Register empty (1=Empty)
-6 Host Tx Interrupt Pending (1=Interrupt)
-7 Unused
-*/
-
-static int __devinit
-snd_wavefront_interrupt_bits (int irq)
-
-{
- int bits;
-
- switch (irq) {
- case 9:
- bits = 0x00;
- break;
- case 5:
- bits = 0x08;
- break;
- case 12:
- bits = 0x10;
- break;
- case 15:
- bits = 0x18;
- break;
-
- default:
- snd_printk ("invalid IRQ %d\n", irq);
- bits = -1;
- }
-
- return bits;
-}
-
-static void __devinit
-wavefront_should_cause_interrupt (snd_wavefront_t *dev,
- int val, int port, unsigned long timeout)
-
-{
- wait_queue_t wait;
-
- init_waitqueue_entry(&wait, current);
- spin_lock_irq(&dev->irq_lock);
- add_wait_queue(&dev->interrupt_sleeper, &wait);
- dev->irq_ok = 0;
- outb (val,port);
- spin_unlock_irq(&dev->irq_lock);
- while (!dev->irq_ok && time_before(jiffies, timeout)) {
- schedule_timeout_uninterruptible(1);
- barrier();
- }
-}
-
-static int __devinit
-wavefront_reset_to_cleanliness (snd_wavefront_t *dev)
-
-{
- int bits;
- int hwv[2];
-
- /* IRQ already checked */
-
- bits = snd_wavefront_interrupt_bits (dev->irq);
-
- /* try reset of port */
-
- outb (0x0, dev->control_port);
-
- /* At this point, the board is in reset, and the H/W initialization
- register is accessed at the same address as the data port.
-
- Bit 7 - Enable IRQ Driver
- 0 - Tri-state the Wave-Board drivers for the PC Bus IRQs
- 1 - Enable IRQ selected by bits 5:3 to be driven onto the PC Bus.
-
- Bit 6 - MIDI Interface Select
-
- 0 - Use the MIDI Input from the 26-pin WaveBlaster
- compatible header as the serial MIDI source
- 1 - Use the MIDI Input from the 9-pin D connector as the
- serial MIDI source.
-
- Bits 5:3 - IRQ Selection
- 0 0 0 - IRQ 2/9
- 0 0 1 - IRQ 5
- 0 1 0 - IRQ 12
- 0 1 1 - IRQ 15
- 1 0 0 - Reserved
- 1 0 1 - Reserved
- 1 1 0 - Reserved
- 1 1 1 - Reserved
-
- Bits 2:1 - Reserved
- Bit 0 - Disable Boot ROM
- 0 - memory accesses to 03FC30-03FFFFH utilize the internal Boot ROM
- 1 - memory accesses to 03FC30-03FFFFH are directed to external
- storage.
-
- */
-
- /* configure hardware: IRQ, enable interrupts,
- plus external 9-pin MIDI interface selected
- */
-
- outb (0x80 | 0x40 | bits, dev->data_port);
-
- /* CONTROL REGISTER
-
- 0 Host Rx Interrupt Enable (1=Enabled) 0x1
- 1 Unused 0x2
- 2 Unused 0x4
- 3 Unused 0x8
- 4 Host Tx Interrupt Enable 0x10
- 5 Mute (0=Mute; 1=Play) 0x20
- 6 Master Interrupt Enable (1=Enabled) 0x40
- 7 Master Reset (0=Reset; 1=Run) 0x80
-
- Take us out of reset, mute output, master + TX + RX interrupts on.
-
- We'll get an interrupt presumably to tell us that the TX
- register is clear.
- */
-
- wavefront_should_cause_interrupt(dev, 0x80|0x40|0x10|0x1,
- dev->control_port,
- (reset_time*HZ)/100);
-
- /* Note: data port is now the data port, not the h/w initialization
- port.
- */
-
- if (!dev->irq_ok) {
- snd_printk ("intr not received after h/w un-reset.\n");
- goto gone_bad;
- }
-
- /* Note: data port is now the data port, not the h/w initialization
- port.
-
- At this point, only "HW VERSION" or "DOWNLOAD OS" commands
- will work. So, issue one of them, and wait for TX
- interrupt. This can take a *long* time after a cold boot,
- while the ISC ROM does its RAM test. The SDK says up to 4
- seconds - with 12MB of RAM on a Tropez+, it takes a lot
- longer than that (~16secs). Note that the card understands
- the difference between a warm and a cold boot, so
- subsequent ISC2115 reboots (say, caused by module
- reloading) will get through this much faster.
-
- XXX Interesting question: why is no RX interrupt received first ?
- */
-
- wavefront_should_cause_interrupt(dev, WFC_HARDWARE_VERSION,
- dev->data_port, ramcheck_time*HZ);
-
- if (!dev->irq_ok) {
- snd_printk ("post-RAM-check interrupt not received.\n");
- goto gone_bad;
- }
-
- if (!wavefront_wait (dev, STAT_CAN_READ)) {
- snd_printk ("no response to HW version cmd.\n");
- goto gone_bad;
- }
-
- if ((hwv[0] = wavefront_read (dev)) == -1) {
- snd_printk ("board not responding correctly.\n");
- goto gone_bad;
- }
-
- if (hwv[0] == 0xFF) { /* NAK */
-
- /* Board's RAM test failed. Try to read error code,
- and tell us about it either way.
- */
-
- if ((hwv[0] = wavefront_read (dev)) == -1) {
- snd_printk ("on-board RAM test failed "
- "(bad error code).\n");
- } else {
- snd_printk ("on-board RAM test failed "
- "(error code: 0x%x).\n",
- hwv[0]);
- }
- goto gone_bad;
- }
-
- /* We're OK, just get the next byte of the HW version response */
-
- if ((hwv[1] = wavefront_read (dev)) == -1) {
- snd_printk ("incorrect h/w response.\n");
- goto gone_bad;
- }
-
- snd_printk ("hardware version %d.%d\n",
- hwv[0], hwv[1]);
-
- return 0;
-
-
- gone_bad:
- return (1);
-}
-
-static int __devinit
-wavefront_download_firmware (snd_wavefront_t *dev, char *path)
-
-{
- const unsigned char *buf;
- int len, err;
- int section_cnt_downloaded = 0;
- const struct firmware *firmware;
-
- err = request_firmware(&firmware, path, dev->card->dev);
- if (err < 0) {
- snd_printk(KERN_ERR "firmware (%s) download failed!!!\n", path);
- return 1;
- }
-
- len = 0;
- buf = firmware->data;
- for (;;) {
- int section_length = *(signed char *)buf;
- if (section_length == 0)
- break;
- if (section_length < 0 || section_length > WF_SECTION_MAX) {
- snd_printk(KERN_ERR
- "invalid firmware section length %d\n",
- section_length);
- goto failure;
- }
- buf++;
- len++;
-
- if (firmware->size < len + section_length) {
- snd_printk(KERN_ERR "firmware section read error.\n");
- goto failure;
- }
-
- /* Send command */
- if (wavefront_write(dev, WFC_DOWNLOAD_OS))
- goto failure;
-
- for (; section_length; section_length--) {
- if (wavefront_write(dev, *buf))
- goto failure;
- buf++;
- len++;
- }
-
- /* get ACK */
- if (!wavefront_wait(dev, STAT_CAN_READ)) {
- snd_printk(KERN_ERR "time out for firmware ACK.\n");
- goto failure;
- }
- err = inb(dev->data_port);
- if (err != WF_ACK) {
- snd_printk(KERN_ERR
- "download of section #%d not "
- "acknowledged, ack = 0x%x\n",
- section_cnt_downloaded + 1, err);
- goto failure;
- }
-
- section_cnt_downloaded++;
- }
-
- release_firmware(firmware);
- return 0;
-
- failure:
- release_firmware(firmware);
- snd_printk(KERN_ERR "firmware download failed!!!\n");
- return 1;
-}
-
-
-static int __devinit
-wavefront_do_reset (snd_wavefront_t *dev)
-
-{
- char voices[1];
-
- if (wavefront_reset_to_cleanliness (dev)) {
- snd_printk ("hw reset failed.\n");
- goto gone_bad;
- }
-
- if (dev->israw) {
- if (wavefront_download_firmware (dev, ospath)) {
- goto gone_bad;
- }
-
- dev->israw = 0;
-
- /* Wait for the OS to get running. The protocol for
- this is non-obvious, and was determined by
- using port-IO tracing in DOSemu and some
- experimentation here.
-
- Rather than using timed waits, use interrupts creatively.
- */
-
- wavefront_should_cause_interrupt (dev, WFC_NOOP,
- dev->data_port,
- (osrun_time*HZ));
-
- if (!dev->irq_ok) {
- snd_printk ("no post-OS interrupt.\n");
- goto gone_bad;
- }
-
- /* Now, do it again ! */
-
- wavefront_should_cause_interrupt (dev, WFC_NOOP,
- dev->data_port, (10*HZ));
-
- if (!dev->irq_ok) {
- snd_printk ("no post-OS interrupt(2).\n");
- goto gone_bad;
- }
-
- /* OK, no (RX/TX) interrupts any more, but leave mute
- in effect.
- */
-
- outb (0x80|0x40, dev->control_port);
- }
-
- /* SETUPSND.EXE asks for sample memory config here, but since i
- have no idea how to interpret the result, we'll forget
- about it.
- */
-
- if ((dev->freemem = wavefront_freemem (dev)) < 0) {
- goto gone_bad;
- }
-
- snd_printk ("available DRAM %dk\n", dev->freemem / 1024);
-
- if (wavefront_write (dev, 0xf0) ||
- wavefront_write (dev, 1) ||
- (wavefront_read (dev) < 0)) {
- dev->debug = 0;
- snd_printk ("MPU emulation mode not set.\n");
- goto gone_bad;
- }
-
- voices[0] = 32;
-
- if (snd_wavefront_cmd (dev, WFC_SET_NVOICES, NULL, voices)) {
- snd_printk ("cannot set number of voices to 32.\n");
- goto gone_bad;
- }
-
-
- return 0;
-
- gone_bad:
- /* reset that sucker so that it doesn't bother us. */
-
- outb (0x0, dev->control_port);
- dev->interrupts_are_midi = 0;
- return 1;
-}
-
-int __devinit
-snd_wavefront_start (snd_wavefront_t *dev)
-
-{
- int samples_are_from_rom;
-
- /* IMPORTANT: assumes that snd_wavefront_detect() and/or
- wavefront_reset_to_cleanliness() has already been called
- */
-
- if (dev->israw) {
- samples_are_from_rom = 1;
- } else {
- /* XXX is this always true ? */
- samples_are_from_rom = 0;
- }
-
- if (dev->israw || fx_raw) {
- if (wavefront_do_reset (dev)) {
- return -1;
- }
- }
- /* Check for FX device, present only on Tropez+ */
-
- dev->has_fx = (snd_wavefront_fx_detect (dev) == 0);
-
- if (dev->has_fx && fx_raw) {
- snd_wavefront_fx_start (dev);
- }
-
- wavefront_get_sample_status (dev, samples_are_from_rom);
- wavefront_get_program_status (dev);
- wavefront_get_patch_status (dev);
-
- /* Start normal operation: unreset, master interrupt enabled, no mute
- */
-
- outb (0x80|0x40|0x20, dev->control_port);
-
- return (0);
-}
-
-int __devinit
-snd_wavefront_detect (snd_wavefront_card_t *card)
-
-{
- unsigned char rbuf[4], wbuf[4];
- snd_wavefront_t *dev = &card->wavefront;
-
- /* returns zero if a WaveFront card is successfully detected.
- negative otherwise.
- */
-
- dev->israw = 0;
- dev->has_fx = 0;
- dev->debug = debug_default;
- dev->interrupts_are_midi = 0;
- dev->irq_cnt = 0;
- dev->rom_samples_rdonly = 1;
-
- if (snd_wavefront_cmd (dev, WFC_FIRMWARE_VERSION, rbuf, wbuf) == 0) {
-
- dev->fw_version[0] = rbuf[0];
- dev->fw_version[1] = rbuf[1];
-
- snd_printk ("firmware %d.%d already loaded.\n",
- rbuf[0], rbuf[1]);
-
- /* check that a command actually works */
-
- if (snd_wavefront_cmd (dev, WFC_HARDWARE_VERSION,
- rbuf, wbuf) == 0) {
- dev->hw_version[0] = rbuf[0];
- dev->hw_version[1] = rbuf[1];
- } else {
- snd_printk ("not raw, but no "
- "hardware version!\n");
- return -1;
- }
-
- if (!wf_raw) {
- return 0;
- } else {
- snd_printk ("reloading firmware as you requested.\n");
- dev->israw = 1;
- }
-
- } else {
-
- dev->israw = 1;
- snd_printk ("no response to firmware probe, assume raw.\n");
-
- }
-
- return 0;
-}
-
-MODULE_FIRMWARE(DEFAULT_OSPATH);
diff --git a/ANDROID_3.4.5/sound/isa/wss/Makefile b/ANDROID_3.4.5/sound/isa/wss/Makefile
deleted file mode 100644
index 454fee76..00000000
--- a/ANDROID_3.4.5/sound/isa/wss/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2008 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-wss-lib-objs := wss_lib.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_WSS_LIB) += snd-wss-lib.o
-
diff --git a/ANDROID_3.4.5/sound/isa/wss/wss_lib.c b/ANDROID_3.4.5/sound/isa/wss/wss_lib.c
deleted file mode 100644
index 49c8a0c2..00000000
--- a/ANDROID_3.4.5/sound/isa/wss/wss_lib.c
+++ /dev/null
@@ -1,2304 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Routines for control of CS4231(A)/CS4232/InterWave & compatible chips
- *
- * Bugs:
- * - sometimes record brokes playback with WSS portion of
- * Yamaha OPL3-SA3 chip
- * - CS4231 (GUS MAX) - still trouble with occasional noises
- * - broken initialization?
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/wss.h>
-#include <sound/pcm_params.h>
-#include <sound/tlv.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/irq.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Routines for control of CS4231(A)/CS4232/InterWave & compatible chips");
-MODULE_LICENSE("GPL");
-
-#if 0
-#define SNDRV_DEBUG_MCE
-#endif
-
-/*
- * Some variables
- */
-
-static unsigned char freq_bits[14] = {
- /* 5510 */ 0x00 | CS4231_XTAL2,
- /* 6620 */ 0x0E | CS4231_XTAL2,
- /* 8000 */ 0x00 | CS4231_XTAL1,
- /* 9600 */ 0x0E | CS4231_XTAL1,
- /* 11025 */ 0x02 | CS4231_XTAL2,
- /* 16000 */ 0x02 | CS4231_XTAL1,
- /* 18900 */ 0x04 | CS4231_XTAL2,
- /* 22050 */ 0x06 | CS4231_XTAL2,
- /* 27042 */ 0x04 | CS4231_XTAL1,
- /* 32000 */ 0x06 | CS4231_XTAL1,
- /* 33075 */ 0x0C | CS4231_XTAL2,
- /* 37800 */ 0x08 | CS4231_XTAL2,
- /* 44100 */ 0x0A | CS4231_XTAL2,
- /* 48000 */ 0x0C | CS4231_XTAL1
-};
-
-static unsigned int rates[14] = {
- 5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050,
- 27042, 32000, 33075, 37800, 44100, 48000
-};
-
-static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
- .count = ARRAY_SIZE(rates),
- .list = rates,
- .mask = 0,
-};
-
-static int snd_wss_xrate(struct snd_pcm_runtime *runtime)
-{
- return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &hw_constraints_rates);
-}
-
-static unsigned char snd_wss_original_image[32] =
-{
- 0x00, /* 00/00 - lic */
- 0x00, /* 01/01 - ric */
- 0x9f, /* 02/02 - la1ic */
- 0x9f, /* 03/03 - ra1ic */
- 0x9f, /* 04/04 - la2ic */
- 0x9f, /* 05/05 - ra2ic */
- 0xbf, /* 06/06 - loc */
- 0xbf, /* 07/07 - roc */
- 0x20, /* 08/08 - pdfr */
- CS4231_AUTOCALIB, /* 09/09 - ic */
- 0x00, /* 0a/10 - pc */
- 0x00, /* 0b/11 - ti */
- CS4231_MODE2, /* 0c/12 - mi */
- 0xfc, /* 0d/13 - lbc */
- 0x00, /* 0e/14 - pbru */
- 0x00, /* 0f/15 - pbrl */
- 0x80, /* 10/16 - afei */
- 0x01, /* 11/17 - afeii */
- 0x9f, /* 12/18 - llic */
- 0x9f, /* 13/19 - rlic */
- 0x00, /* 14/20 - tlb */
- 0x00, /* 15/21 - thb */
- 0x00, /* 16/22 - la3mic/reserved */
- 0x00, /* 17/23 - ra3mic/reserved */
- 0x00, /* 18/24 - afs */
- 0x00, /* 19/25 - lamoc/version */
- 0xcf, /* 1a/26 - mioc */
- 0x00, /* 1b/27 - ramoc/reserved */
- 0x20, /* 1c/28 - cdfr */
- 0x00, /* 1d/29 - res4 */
- 0x00, /* 1e/30 - cbru */
- 0x00, /* 1f/31 - cbrl */
-};
-
-static unsigned char snd_opti93x_original_image[32] =
-{
- 0x00, /* 00/00 - l_mixout_outctrl */
- 0x00, /* 01/01 - r_mixout_outctrl */
- 0x88, /* 02/02 - l_cd_inctrl */
- 0x88, /* 03/03 - r_cd_inctrl */
- 0x88, /* 04/04 - l_a1/fm_inctrl */
- 0x88, /* 05/05 - r_a1/fm_inctrl */
- 0x80, /* 06/06 - l_dac_inctrl */
- 0x80, /* 07/07 - r_dac_inctrl */
- 0x00, /* 08/08 - ply_dataform_reg */
- 0x00, /* 09/09 - if_conf */
- 0x00, /* 0a/10 - pin_ctrl */
- 0x00, /* 0b/11 - err_init_reg */
- 0x0a, /* 0c/12 - id_reg */
- 0x00, /* 0d/13 - reserved */
- 0x00, /* 0e/14 - ply_upcount_reg */
- 0x00, /* 0f/15 - ply_lowcount_reg */
- 0x88, /* 10/16 - reserved/l_a1_inctrl */
- 0x88, /* 11/17 - reserved/r_a1_inctrl */
- 0x88, /* 12/18 - l_line_inctrl */
- 0x88, /* 13/19 - r_line_inctrl */
- 0x88, /* 14/20 - l_mic_inctrl */
- 0x88, /* 15/21 - r_mic_inctrl */
- 0x80, /* 16/22 - l_out_outctrl */
- 0x80, /* 17/23 - r_out_outctrl */
- 0x00, /* 18/24 - reserved */
- 0x00, /* 19/25 - reserved */
- 0x00, /* 1a/26 - reserved */
- 0x00, /* 1b/27 - reserved */
- 0x00, /* 1c/28 - cap_dataform_reg */
- 0x00, /* 1d/29 - reserved */
- 0x00, /* 1e/30 - cap_upcount_reg */
- 0x00 /* 1f/31 - cap_lowcount_reg */
-};
-
-/*
- * Basic I/O functions
- */
-
-static inline void wss_outb(struct snd_wss *chip, u8 offset, u8 val)
-{
- outb(val, chip->port + offset);
-}
-
-static inline u8 wss_inb(struct snd_wss *chip, u8 offset)
-{
- return inb(chip->port + offset);
-}
-
-static void snd_wss_wait(struct snd_wss *chip)
-{
- int timeout;
-
- for (timeout = 250;
- timeout > 0 && (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
- timeout--)
- udelay(100);
-}
-
-static void snd_wss_dout(struct snd_wss *chip, unsigned char reg,
- unsigned char value)
-{
- int timeout;
-
- for (timeout = 250;
- timeout > 0 && (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
- timeout--)
- udelay(10);
- wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
- wss_outb(chip, CS4231P(REG), value);
- mb();
-}
-
-void snd_wss_out(struct snd_wss *chip, unsigned char reg, unsigned char value)
-{
- snd_wss_wait(chip);
-#ifdef CONFIG_SND_DEBUG
- if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
- snd_printk(KERN_DEBUG "out: auto calibration time out "
- "- reg = 0x%x, value = 0x%x\n", reg, value);
-#endif
- wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
- wss_outb(chip, CS4231P(REG), value);
- chip->image[reg] = value;
- mb();
- snd_printdd("codec out - reg 0x%x = 0x%x\n",
- chip->mce_bit | reg, value);
-}
-EXPORT_SYMBOL(snd_wss_out);
-
-unsigned char snd_wss_in(struct snd_wss *chip, unsigned char reg)
-{
- snd_wss_wait(chip);
-#ifdef CONFIG_SND_DEBUG
- if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
- snd_printk(KERN_DEBUG "in: auto calibration time out "
- "- reg = 0x%x\n", reg);
-#endif
- wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
- mb();
- return wss_inb(chip, CS4231P(REG));
-}
-EXPORT_SYMBOL(snd_wss_in);
-
-void snd_cs4236_ext_out(struct snd_wss *chip, unsigned char reg,
- unsigned char val)
-{
- wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17);
- wss_outb(chip, CS4231P(REG),
- reg | (chip->image[CS4236_EXT_REG] & 0x01));
- wss_outb(chip, CS4231P(REG), val);
- chip->eimage[CS4236_REG(reg)] = val;
-#if 0
- printk(KERN_DEBUG "ext out : reg = 0x%x, val = 0x%x\n", reg, val);
-#endif
-}
-EXPORT_SYMBOL(snd_cs4236_ext_out);
-
-unsigned char snd_cs4236_ext_in(struct snd_wss *chip, unsigned char reg)
-{
- wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17);
- wss_outb(chip, CS4231P(REG),
- reg | (chip->image[CS4236_EXT_REG] & 0x01));
-#if 1
- return wss_inb(chip, CS4231P(REG));
-#else
- {
- unsigned char res;
- res = wss_inb(chip, CS4231P(REG));
- printk(KERN_DEBUG "ext in : reg = 0x%x, val = 0x%x\n",
- reg, res);
- return res;
- }
-#endif
-}
-EXPORT_SYMBOL(snd_cs4236_ext_in);
-
-#if 0
-
-static void snd_wss_debug(struct snd_wss *chip)
-{
- printk(KERN_DEBUG
- "CS4231 REGS: INDEX = 0x%02x "
- " STATUS = 0x%02x\n",
- wss_inb(chip, CS4231P(REGSEL)),
- wss_inb(chip, CS4231P(STATUS)));
- printk(KERN_DEBUG
- " 0x00: left input = 0x%02x "
- " 0x10: alt 1 (CFIG 2) = 0x%02x\n",
- snd_wss_in(chip, 0x00),
- snd_wss_in(chip, 0x10));
- printk(KERN_DEBUG
- " 0x01: right input = 0x%02x "
- " 0x11: alt 2 (CFIG 3) = 0x%02x\n",
- snd_wss_in(chip, 0x01),
- snd_wss_in(chip, 0x11));
- printk(KERN_DEBUG
- " 0x02: GF1 left input = 0x%02x "
- " 0x12: left line in = 0x%02x\n",
- snd_wss_in(chip, 0x02),
- snd_wss_in(chip, 0x12));
- printk(KERN_DEBUG
- " 0x03: GF1 right input = 0x%02x "
- " 0x13: right line in = 0x%02x\n",
- snd_wss_in(chip, 0x03),
- snd_wss_in(chip, 0x13));
- printk(KERN_DEBUG
- " 0x04: CD left input = 0x%02x "
- " 0x14: timer low = 0x%02x\n",
- snd_wss_in(chip, 0x04),
- snd_wss_in(chip, 0x14));
- printk(KERN_DEBUG
- " 0x05: CD right input = 0x%02x "
- " 0x15: timer high = 0x%02x\n",
- snd_wss_in(chip, 0x05),
- snd_wss_in(chip, 0x15));
- printk(KERN_DEBUG
- " 0x06: left output = 0x%02x "
- " 0x16: left MIC (PnP) = 0x%02x\n",
- snd_wss_in(chip, 0x06),
- snd_wss_in(chip, 0x16));
- printk(KERN_DEBUG
- " 0x07: right output = 0x%02x "
- " 0x17: right MIC (PnP) = 0x%02x\n",
- snd_wss_in(chip, 0x07),
- snd_wss_in(chip, 0x17));
- printk(KERN_DEBUG
- " 0x08: playback format = 0x%02x "
- " 0x18: IRQ status = 0x%02x\n",
- snd_wss_in(chip, 0x08),
- snd_wss_in(chip, 0x18));
- printk(KERN_DEBUG
- " 0x09: iface (CFIG 1) = 0x%02x "
- " 0x19: left line out = 0x%02x\n",
- snd_wss_in(chip, 0x09),
- snd_wss_in(chip, 0x19));
- printk(KERN_DEBUG
- " 0x0a: pin control = 0x%02x "
- " 0x1a: mono control = 0x%02x\n",
- snd_wss_in(chip, 0x0a),
- snd_wss_in(chip, 0x1a));
- printk(KERN_DEBUG
- " 0x0b: init & status = 0x%02x "
- " 0x1b: right line out = 0x%02x\n",
- snd_wss_in(chip, 0x0b),
- snd_wss_in(chip, 0x1b));
- printk(KERN_DEBUG
- " 0x0c: revision & mode = 0x%02x "
- " 0x1c: record format = 0x%02x\n",
- snd_wss_in(chip, 0x0c),
- snd_wss_in(chip, 0x1c));
- printk(KERN_DEBUG
- " 0x0d: loopback = 0x%02x "
- " 0x1d: var freq (PnP) = 0x%02x\n",
- snd_wss_in(chip, 0x0d),
- snd_wss_in(chip, 0x1d));
- printk(KERN_DEBUG
- " 0x0e: ply upr count = 0x%02x "
- " 0x1e: ply lwr count = 0x%02x\n",
- snd_wss_in(chip, 0x0e),
- snd_wss_in(chip, 0x1e));
- printk(KERN_DEBUG
- " 0x0f: rec upr count = 0x%02x "
- " 0x1f: rec lwr count = 0x%02x\n",
- snd_wss_in(chip, 0x0f),
- snd_wss_in(chip, 0x1f));
-}
-
-#endif
-
-/*
- * CS4231 detection / MCE routines
- */
-
-static void snd_wss_busy_wait(struct snd_wss *chip)
-{
- int timeout;
-
- /* huh.. looks like this sequence is proper for CS4231A chip (GUS MAX) */
- for (timeout = 5; timeout > 0; timeout--)
- wss_inb(chip, CS4231P(REGSEL));
- /* end of cleanup sequence */
- for (timeout = 25000;
- timeout > 0 && (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
- timeout--)
- udelay(10);
-}
-
-void snd_wss_mce_up(struct snd_wss *chip)
-{
- unsigned long flags;
- int timeout;
-
- snd_wss_wait(chip);
-#ifdef CONFIG_SND_DEBUG
- if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
- snd_printk(KERN_DEBUG
- "mce_up - auto calibration time out (0)\n");
-#endif
- spin_lock_irqsave(&chip->reg_lock, flags);
- chip->mce_bit |= CS4231_MCE;
- timeout = wss_inb(chip, CS4231P(REGSEL));
- if (timeout == 0x80)
- snd_printk(KERN_DEBUG "mce_up [0x%lx]: "
- "serious init problem - codec still busy\n",
- chip->port);
- if (!(timeout & CS4231_MCE))
- wss_outb(chip, CS4231P(REGSEL),
- chip->mce_bit | (timeout & 0x1f));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-EXPORT_SYMBOL(snd_wss_mce_up);
-
-void snd_wss_mce_down(struct snd_wss *chip)
-{
- unsigned long flags;
- unsigned long end_time;
- int timeout;
- int hw_mask = WSS_HW_CS4231_MASK | WSS_HW_CS4232_MASK | WSS_HW_AD1848;
-
- snd_wss_busy_wait(chip);
-
-#ifdef CONFIG_SND_DEBUG
- if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
- snd_printk(KERN_DEBUG "mce_down [0x%lx] - "
- "auto calibration time out (0)\n",
- (long)CS4231P(REGSEL));
-#endif
- spin_lock_irqsave(&chip->reg_lock, flags);
- chip->mce_bit &= ~CS4231_MCE;
- timeout = wss_inb(chip, CS4231P(REGSEL));
- wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (timeout == 0x80)
- snd_printk(KERN_DEBUG "mce_down [0x%lx]: "
- "serious init problem - codec still busy\n",
- chip->port);
- if ((timeout & CS4231_MCE) == 0 || !(chip->hardware & hw_mask))
- return;
-
- /*
- * Wait for (possible -- during init auto-calibration may not be set)
- * calibration process to start. Needs up to 5 sample periods on AD1848
- * which at the slowest possible rate of 5.5125 kHz means 907 us.
- */
- msleep(1);
-
- snd_printdd("(1) jiffies = %lu\n", jiffies);
-
- /* check condition up to 250 ms */
- end_time = jiffies + msecs_to_jiffies(250);
- while (snd_wss_in(chip, CS4231_TEST_INIT) &
- CS4231_CALIB_IN_PROGRESS) {
-
- if (time_after(jiffies, end_time)) {
- snd_printk(KERN_ERR "mce_down - "
- "auto calibration time out (2)\n");
- return;
- }
- msleep(1);
- }
-
- snd_printdd("(2) jiffies = %lu\n", jiffies);
-
- /* check condition up to 100 ms */
- end_time = jiffies + msecs_to_jiffies(100);
- while (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) {
- if (time_after(jiffies, end_time)) {
- snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n");
- return;
- }
- msleep(1);
- }
-
- snd_printdd("(3) jiffies = %lu\n", jiffies);
- snd_printd("mce_down - exit = 0x%x\n", wss_inb(chip, CS4231P(REGSEL)));
-}
-EXPORT_SYMBOL(snd_wss_mce_down);
-
-static unsigned int snd_wss_get_count(unsigned char format, unsigned int size)
-{
- switch (format & 0xe0) {
- case CS4231_LINEAR_16:
- case CS4231_LINEAR_16_BIG:
- size >>= 1;
- break;
- case CS4231_ADPCM_16:
- return size >> 2;
- }
- if (format & CS4231_STEREO)
- size >>= 1;
- return size;
-}
-
-static int snd_wss_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_wss *chip = snd_pcm_substream_chip(substream);
- int result = 0;
- unsigned int what;
- struct snd_pcm_substream *s;
- int do_start;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- do_start = 1; break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- do_start = 0; break;
- default:
- return -EINVAL;
- }
-
- what = 0;
- snd_pcm_group_for_each_entry(s, substream) {
- if (s == chip->playback_substream) {
- what |= CS4231_PLAYBACK_ENABLE;
- snd_pcm_trigger_done(s, substream);
- } else if (s == chip->capture_substream) {
- what |= CS4231_RECORD_ENABLE;
- snd_pcm_trigger_done(s, substream);
- }
- }
- spin_lock(&chip->reg_lock);
- if (do_start) {
- chip->image[CS4231_IFACE_CTRL] |= what;
- if (chip->trigger)
- chip->trigger(chip, what, 1);
- } else {
- chip->image[CS4231_IFACE_CTRL] &= ~what;
- if (chip->trigger)
- chip->trigger(chip, what, 0);
- }
- snd_wss_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
- spin_unlock(&chip->reg_lock);
-#if 0
- snd_wss_debug(chip);
-#endif
- return result;
-}
-
-/*
- * CODEC I/O
- */
-
-static unsigned char snd_wss_get_rate(unsigned int rate)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(rates); i++)
- if (rate == rates[i])
- return freq_bits[i];
- // snd_BUG();
- return freq_bits[ARRAY_SIZE(rates) - 1];
-}
-
-static unsigned char snd_wss_get_format(struct snd_wss *chip,
- int format,
- int channels)
-{
- unsigned char rformat;
-
- rformat = CS4231_LINEAR_8;
- switch (format) {
- case SNDRV_PCM_FORMAT_MU_LAW: rformat = CS4231_ULAW_8; break;
- case SNDRV_PCM_FORMAT_A_LAW: rformat = CS4231_ALAW_8; break;
- case SNDRV_PCM_FORMAT_S16_LE: rformat = CS4231_LINEAR_16; break;
- case SNDRV_PCM_FORMAT_S16_BE: rformat = CS4231_LINEAR_16_BIG; break;
- case SNDRV_PCM_FORMAT_IMA_ADPCM: rformat = CS4231_ADPCM_16; break;
- }
- if (channels > 1)
- rformat |= CS4231_STEREO;
-#if 0
- snd_printk(KERN_DEBUG "get_format: 0x%x (mode=0x%x)\n", format, mode);
-#endif
- return rformat;
-}
-
-static void snd_wss_calibrate_mute(struct snd_wss *chip, int mute)
-{
- unsigned long flags;
-
- mute = mute ? 0x80 : 0;
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (chip->calibrate_mute == mute) {
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return;
- }
- if (!mute) {
- snd_wss_dout(chip, CS4231_LEFT_INPUT,
- chip->image[CS4231_LEFT_INPUT]);
- snd_wss_dout(chip, CS4231_RIGHT_INPUT,
- chip->image[CS4231_RIGHT_INPUT]);
- snd_wss_dout(chip, CS4231_LOOPBACK,
- chip->image[CS4231_LOOPBACK]);
- } else {
- snd_wss_dout(chip, CS4231_LEFT_INPUT,
- 0);
- snd_wss_dout(chip, CS4231_RIGHT_INPUT,
- 0);
- snd_wss_dout(chip, CS4231_LOOPBACK,
- 0xfd);
- }
-
- snd_wss_dout(chip, CS4231_AUX1_LEFT_INPUT,
- mute | chip->image[CS4231_AUX1_LEFT_INPUT]);
- snd_wss_dout(chip, CS4231_AUX1_RIGHT_INPUT,
- mute | chip->image[CS4231_AUX1_RIGHT_INPUT]);
- snd_wss_dout(chip, CS4231_AUX2_LEFT_INPUT,
- mute | chip->image[CS4231_AUX2_LEFT_INPUT]);
- snd_wss_dout(chip, CS4231_AUX2_RIGHT_INPUT,
- mute | chip->image[CS4231_AUX2_RIGHT_INPUT]);
- snd_wss_dout(chip, CS4231_LEFT_OUTPUT,
- mute | chip->image[CS4231_LEFT_OUTPUT]);
- snd_wss_dout(chip, CS4231_RIGHT_OUTPUT,
- mute | chip->image[CS4231_RIGHT_OUTPUT]);
- if (!(chip->hardware & WSS_HW_AD1848_MASK)) {
- snd_wss_dout(chip, CS4231_LEFT_LINE_IN,
- mute | chip->image[CS4231_LEFT_LINE_IN]);
- snd_wss_dout(chip, CS4231_RIGHT_LINE_IN,
- mute | chip->image[CS4231_RIGHT_LINE_IN]);
- snd_wss_dout(chip, CS4231_MONO_CTRL,
- mute ? 0xc0 : chip->image[CS4231_MONO_CTRL]);
- }
- if (chip->hardware == WSS_HW_INTERWAVE) {
- snd_wss_dout(chip, CS4231_LEFT_MIC_INPUT,
- mute | chip->image[CS4231_LEFT_MIC_INPUT]);
- snd_wss_dout(chip, CS4231_RIGHT_MIC_INPUT,
- mute | chip->image[CS4231_RIGHT_MIC_INPUT]);
- snd_wss_dout(chip, CS4231_LINE_LEFT_OUTPUT,
- mute | chip->image[CS4231_LINE_LEFT_OUTPUT]);
- snd_wss_dout(chip, CS4231_LINE_RIGHT_OUTPUT,
- mute | chip->image[CS4231_LINE_RIGHT_OUTPUT]);
- }
- chip->calibrate_mute = mute;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-
-static void snd_wss_playback_format(struct snd_wss *chip,
- struct snd_pcm_hw_params *params,
- unsigned char pdfr)
-{
- unsigned long flags;
- int full_calib = 1;
-
- mutex_lock(&chip->mce_mutex);
- if (chip->hardware == WSS_HW_CS4231A ||
- (chip->hardware & WSS_HW_CS4232_MASK)) {
- spin_lock_irqsave(&chip->reg_lock, flags);
- if ((chip->image[CS4231_PLAYBK_FORMAT] & 0x0f) == (pdfr & 0x0f)) { /* rate is same? */
- snd_wss_out(chip, CS4231_ALT_FEATURE_1,
- chip->image[CS4231_ALT_FEATURE_1] | 0x10);
- chip->image[CS4231_PLAYBK_FORMAT] = pdfr;
- snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
- chip->image[CS4231_PLAYBK_FORMAT]);
- snd_wss_out(chip, CS4231_ALT_FEATURE_1,
- chip->image[CS4231_ALT_FEATURE_1] &= ~0x10);
- udelay(100); /* Fixes audible clicks at least on GUS MAX */
- full_calib = 0;
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- } else if (chip->hardware == WSS_HW_AD1845) {
- unsigned rate = params_rate(params);
-
- /*
- * Program the AD1845 correctly for the playback stream.
- * Note that we do NOT need to toggle the MCE bit because
- * the PLAYBACK_ENABLE bit of the Interface Configuration
- * register is set.
- *
- * NOTE: We seem to need to write to the MSB before the LSB
- * to get the correct sample frequency.
- */
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_wss_out(chip, CS4231_PLAYBK_FORMAT, (pdfr & 0xf0));
- snd_wss_out(chip, AD1845_UPR_FREQ_SEL, (rate >> 8) & 0xff);
- snd_wss_out(chip, AD1845_LWR_FREQ_SEL, rate & 0xff);
- full_calib = 0;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- }
- if (full_calib) {
- snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (chip->hardware != WSS_HW_INTERWAVE && !chip->single_dma) {
- if (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE)
- pdfr = (pdfr & 0xf0) |
- (chip->image[CS4231_REC_FORMAT] & 0x0f);
- } else {
- chip->image[CS4231_PLAYBK_FORMAT] = pdfr;
- }
- snd_wss_out(chip, CS4231_PLAYBK_FORMAT, pdfr);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (chip->hardware == WSS_HW_OPL3SA2)
- udelay(100); /* this seems to help */
- snd_wss_mce_down(chip);
- }
- mutex_unlock(&chip->mce_mutex);
-}
-
-static void snd_wss_capture_format(struct snd_wss *chip,
- struct snd_pcm_hw_params *params,
- unsigned char cdfr)
-{
- unsigned long flags;
- int full_calib = 1;
-
- mutex_lock(&chip->mce_mutex);
- if (chip->hardware == WSS_HW_CS4231A ||
- (chip->hardware & WSS_HW_CS4232_MASK)) {
- spin_lock_irqsave(&chip->reg_lock, flags);
- if ((chip->image[CS4231_PLAYBK_FORMAT] & 0x0f) == (cdfr & 0x0f) || /* rate is same? */
- (chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) {
- snd_wss_out(chip, CS4231_ALT_FEATURE_1,
- chip->image[CS4231_ALT_FEATURE_1] | 0x20);
- snd_wss_out(chip, CS4231_REC_FORMAT,
- chip->image[CS4231_REC_FORMAT] = cdfr);
- snd_wss_out(chip, CS4231_ALT_FEATURE_1,
- chip->image[CS4231_ALT_FEATURE_1] &= ~0x20);
- full_calib = 0;
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- } else if (chip->hardware == WSS_HW_AD1845) {
- unsigned rate = params_rate(params);
-
- /*
- * Program the AD1845 correctly for the capture stream.
- * Note that we do NOT need to toggle the MCE bit because
- * the PLAYBACK_ENABLE bit of the Interface Configuration
- * register is set.
- *
- * NOTE: We seem to need to write to the MSB before the LSB
- * to get the correct sample frequency.
- */
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_wss_out(chip, CS4231_REC_FORMAT, (cdfr & 0xf0));
- snd_wss_out(chip, AD1845_UPR_FREQ_SEL, (rate >> 8) & 0xff);
- snd_wss_out(chip, AD1845_LWR_FREQ_SEL, rate & 0xff);
- full_calib = 0;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- }
- if (full_calib) {
- snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (chip->hardware != WSS_HW_INTERWAVE &&
- !(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) {
- if (chip->single_dma)
- snd_wss_out(chip, CS4231_PLAYBK_FORMAT, cdfr);
- else
- snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
- (chip->image[CS4231_PLAYBK_FORMAT] & 0xf0) |
- (cdfr & 0x0f));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- snd_wss_mce_down(chip);
- snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- }
- if (chip->hardware & WSS_HW_AD1848_MASK)
- snd_wss_out(chip, CS4231_PLAYBK_FORMAT, cdfr);
- else
- snd_wss_out(chip, CS4231_REC_FORMAT, cdfr);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- snd_wss_mce_down(chip);
- }
- mutex_unlock(&chip->mce_mutex);
-}
-
-/*
- * Timer interface
- */
-
-static unsigned long snd_wss_timer_resolution(struct snd_timer *timer)
-{
- struct snd_wss *chip = snd_timer_chip(timer);
- if (chip->hardware & WSS_HW_CS4236B_MASK)
- return 14467;
- else
- return chip->image[CS4231_PLAYBK_FORMAT] & 1 ? 9969 : 9920;
-}
-
-static int snd_wss_timer_start(struct snd_timer *timer)
-{
- unsigned long flags;
- unsigned int ticks;
- struct snd_wss *chip = snd_timer_chip(timer);
- spin_lock_irqsave(&chip->reg_lock, flags);
- ticks = timer->sticks;
- if ((chip->image[CS4231_ALT_FEATURE_1] & CS4231_TIMER_ENABLE) == 0 ||
- (unsigned char)(ticks >> 8) != chip->image[CS4231_TIMER_HIGH] ||
- (unsigned char)ticks != chip->image[CS4231_TIMER_LOW]) {
- chip->image[CS4231_TIMER_HIGH] = (unsigned char) (ticks >> 8);
- snd_wss_out(chip, CS4231_TIMER_HIGH,
- chip->image[CS4231_TIMER_HIGH]);
- chip->image[CS4231_TIMER_LOW] = (unsigned char) ticks;
- snd_wss_out(chip, CS4231_TIMER_LOW,
- chip->image[CS4231_TIMER_LOW]);
- snd_wss_out(chip, CS4231_ALT_FEATURE_1,
- chip->image[CS4231_ALT_FEATURE_1] |
- CS4231_TIMER_ENABLE);
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
-}
-
-static int snd_wss_timer_stop(struct snd_timer *timer)
-{
- unsigned long flags;
- struct snd_wss *chip = snd_timer_chip(timer);
- spin_lock_irqsave(&chip->reg_lock, flags);
- chip->image[CS4231_ALT_FEATURE_1] &= ~CS4231_TIMER_ENABLE;
- snd_wss_out(chip, CS4231_ALT_FEATURE_1,
- chip->image[CS4231_ALT_FEATURE_1]);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
-}
-
-static void snd_wss_init(struct snd_wss *chip)
-{
- unsigned long flags;
-
- snd_wss_calibrate_mute(chip, 1);
- snd_wss_mce_down(chip);
-
-#ifdef SNDRV_DEBUG_MCE
- snd_printk(KERN_DEBUG "init: (1)\n");
-#endif
- snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE |
- CS4231_PLAYBACK_PIO |
- CS4231_RECORD_ENABLE |
- CS4231_RECORD_PIO |
- CS4231_CALIB_MODE);
- chip->image[CS4231_IFACE_CTRL] |= CS4231_AUTOCALIB;
- snd_wss_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- snd_wss_mce_down(chip);
-
-#ifdef SNDRV_DEBUG_MCE
- snd_printk(KERN_DEBUG "init: (2)\n");
-#endif
-
- snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- chip->image[CS4231_IFACE_CTRL] &= ~CS4231_AUTOCALIB;
- snd_wss_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
- snd_wss_out(chip,
- CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1]);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- snd_wss_mce_down(chip);
-
-#ifdef SNDRV_DEBUG_MCE
- snd_printk(KERN_DEBUG "init: (3) - afei = 0x%x\n",
- chip->image[CS4231_ALT_FEATURE_1]);
-#endif
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_wss_out(chip, CS4231_ALT_FEATURE_2,
- chip->image[CS4231_ALT_FEATURE_2]);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
- chip->image[CS4231_PLAYBK_FORMAT]);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- snd_wss_mce_down(chip);
-
-#ifdef SNDRV_DEBUG_MCE
- snd_printk(KERN_DEBUG "init: (4)\n");
-#endif
-
- snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (!(chip->hardware & WSS_HW_AD1848_MASK))
- snd_wss_out(chip, CS4231_REC_FORMAT,
- chip->image[CS4231_REC_FORMAT]);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- snd_wss_mce_down(chip);
- snd_wss_calibrate_mute(chip, 0);
-
-#ifdef SNDRV_DEBUG_MCE
- snd_printk(KERN_DEBUG "init: (5)\n");
-#endif
-}
-
-static int snd_wss_open(struct snd_wss *chip, unsigned int mode)
-{
- unsigned long flags;
-
- mutex_lock(&chip->open_mutex);
- if ((chip->mode & mode) ||
- ((chip->mode & WSS_MODE_OPEN) && chip->single_dma)) {
- mutex_unlock(&chip->open_mutex);
- return -EAGAIN;
- }
- if (chip->mode & WSS_MODE_OPEN) {
- chip->mode |= mode;
- mutex_unlock(&chip->open_mutex);
- return 0;
- }
- /* ok. now enable and ack CODEC IRQ */
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (!(chip->hardware & WSS_HW_AD1848_MASK)) {
- snd_wss_out(chip, CS4231_IRQ_STATUS,
- CS4231_PLAYBACK_IRQ |
- CS4231_RECORD_IRQ |
- CS4231_TIMER_IRQ);
- snd_wss_out(chip, CS4231_IRQ_STATUS, 0);
- }
- wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */
- wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */
- chip->image[CS4231_PIN_CTRL] |= CS4231_IRQ_ENABLE;
- snd_wss_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]);
- if (!(chip->hardware & WSS_HW_AD1848_MASK)) {
- snd_wss_out(chip, CS4231_IRQ_STATUS,
- CS4231_PLAYBACK_IRQ |
- CS4231_RECORD_IRQ |
- CS4231_TIMER_IRQ);
- snd_wss_out(chip, CS4231_IRQ_STATUS, 0);
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- chip->mode = mode;
- mutex_unlock(&chip->open_mutex);
- return 0;
-}
-
-static void snd_wss_close(struct snd_wss *chip, unsigned int mode)
-{
- unsigned long flags;
-
- mutex_lock(&chip->open_mutex);
- chip->mode &= ~mode;
- if (chip->mode & WSS_MODE_OPEN) {
- mutex_unlock(&chip->open_mutex);
- return;
- }
- /* disable IRQ */
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (!(chip->hardware & WSS_HW_AD1848_MASK))
- snd_wss_out(chip, CS4231_IRQ_STATUS, 0);
- wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */
- wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */
- chip->image[CS4231_PIN_CTRL] &= ~CS4231_IRQ_ENABLE;
- snd_wss_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]);
-
- /* now disable record & playback */
-
- if (chip->image[CS4231_IFACE_CTRL] & (CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO |
- CS4231_RECORD_ENABLE | CS4231_RECORD_PIO)) {
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO |
- CS4231_RECORD_ENABLE | CS4231_RECORD_PIO);
- snd_wss_out(chip, CS4231_IFACE_CTRL,
- chip->image[CS4231_IFACE_CTRL]);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- snd_wss_mce_down(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- }
-
- /* clear IRQ again */
- if (!(chip->hardware & WSS_HW_AD1848_MASK))
- snd_wss_out(chip, CS4231_IRQ_STATUS, 0);
- wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */
- wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- chip->mode = 0;
- mutex_unlock(&chip->open_mutex);
-}
-
-/*
- * timer open/close
- */
-
-static int snd_wss_timer_open(struct snd_timer *timer)
-{
- struct snd_wss *chip = snd_timer_chip(timer);
- snd_wss_open(chip, WSS_MODE_TIMER);
- return 0;
-}
-
-static int snd_wss_timer_close(struct snd_timer *timer)
-{
- struct snd_wss *chip = snd_timer_chip(timer);
- snd_wss_close(chip, WSS_MODE_TIMER);
- return 0;
-}
-
-static struct snd_timer_hardware snd_wss_timer_table =
-{
- .flags = SNDRV_TIMER_HW_AUTO,
- .resolution = 9945,
- .ticks = 65535,
- .open = snd_wss_timer_open,
- .close = snd_wss_timer_close,
- .c_resolution = snd_wss_timer_resolution,
- .start = snd_wss_timer_start,
- .stop = snd_wss_timer_stop,
-};
-
-/*
- * ok.. exported functions..
- */
-
-static int snd_wss_playback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_wss *chip = snd_pcm_substream_chip(substream);
- unsigned char new_pdfr;
- int err;
-
- if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
- return err;
- new_pdfr = snd_wss_get_format(chip, params_format(hw_params),
- params_channels(hw_params)) |
- snd_wss_get_rate(params_rate(hw_params));
- chip->set_playback_format(chip, hw_params, new_pdfr);
- return 0;
-}
-
-static int snd_wss_playback_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_wss_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_wss *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long flags;
- unsigned int size = snd_pcm_lib_buffer_bytes(substream);
- unsigned int count = snd_pcm_lib_period_bytes(substream);
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- chip->p_dma_size = size;
- chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO);
- snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
- count = snd_wss_get_count(chip->image[CS4231_PLAYBK_FORMAT], count) - 1;
- snd_wss_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count);
- snd_wss_out(chip, CS4231_PLY_UPR_CNT, (unsigned char) (count >> 8));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-#if 0
- snd_wss_debug(chip);
-#endif
- return 0;
-}
-
-static int snd_wss_capture_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_wss *chip = snd_pcm_substream_chip(substream);
- unsigned char new_cdfr;
- int err;
-
- if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
- return err;
- new_cdfr = snd_wss_get_format(chip, params_format(hw_params),
- params_channels(hw_params)) |
- snd_wss_get_rate(params_rate(hw_params));
- chip->set_capture_format(chip, hw_params, new_cdfr);
- return 0;
-}
-
-static int snd_wss_capture_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_wss_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_wss *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long flags;
- unsigned int size = snd_pcm_lib_buffer_bytes(substream);
- unsigned int count = snd_pcm_lib_period_bytes(substream);
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- chip->c_dma_size = size;
- chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE | CS4231_RECORD_PIO);
- snd_dma_program(chip->dma2, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
- if (chip->hardware & WSS_HW_AD1848_MASK)
- count = snd_wss_get_count(chip->image[CS4231_PLAYBK_FORMAT],
- count);
- else
- count = snd_wss_get_count(chip->image[CS4231_REC_FORMAT],
- count);
- count--;
- if (chip->single_dma && chip->hardware != WSS_HW_INTERWAVE) {
- snd_wss_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count);
- snd_wss_out(chip, CS4231_PLY_UPR_CNT,
- (unsigned char) (count >> 8));
- } else {
- snd_wss_out(chip, CS4231_REC_LWR_CNT, (unsigned char) count);
- snd_wss_out(chip, CS4231_REC_UPR_CNT,
- (unsigned char) (count >> 8));
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
-}
-
-void snd_wss_overrange(struct snd_wss *chip)
-{
- unsigned long flags;
- unsigned char res;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- res = snd_wss_in(chip, CS4231_TEST_INIT);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (res & (0x08 | 0x02)) /* detect overrange only above 0dB; may be user selectable? */
- chip->capture_substream->runtime->overrange++;
-}
-EXPORT_SYMBOL(snd_wss_overrange);
-
-irqreturn_t snd_wss_interrupt(int irq, void *dev_id)
-{
- struct snd_wss *chip = dev_id;
- unsigned char status;
-
- if (chip->hardware & WSS_HW_AD1848_MASK)
- /* pretend it was the only possible irq for AD1848 */
- status = CS4231_PLAYBACK_IRQ;
- else
- status = snd_wss_in(chip, CS4231_IRQ_STATUS);
- if (status & CS4231_TIMER_IRQ) {
- if (chip->timer)
- snd_timer_interrupt(chip->timer, chip->timer->sticks);
- }
- if (chip->single_dma && chip->hardware != WSS_HW_INTERWAVE) {
- if (status & CS4231_PLAYBACK_IRQ) {
- if (chip->mode & WSS_MODE_PLAY) {
- if (chip->playback_substream)
- snd_pcm_period_elapsed(chip->playback_substream);
- }
- if (chip->mode & WSS_MODE_RECORD) {
- if (chip->capture_substream) {
- snd_wss_overrange(chip);
- snd_pcm_period_elapsed(chip->capture_substream);
- }
- }
- }
- } else {
- if (status & CS4231_PLAYBACK_IRQ) {
- if (chip->playback_substream)
- snd_pcm_period_elapsed(chip->playback_substream);
- }
- if (status & CS4231_RECORD_IRQ) {
- if (chip->capture_substream) {
- snd_wss_overrange(chip);
- snd_pcm_period_elapsed(chip->capture_substream);
- }
- }
- }
-
- spin_lock(&chip->reg_lock);
- status = ~CS4231_ALL_IRQS | ~status;
- if (chip->hardware & WSS_HW_AD1848_MASK)
- wss_outb(chip, CS4231P(STATUS), 0);
- else
- snd_wss_out(chip, CS4231_IRQ_STATUS, status);
- spin_unlock(&chip->reg_lock);
- return IRQ_HANDLED;
-}
-EXPORT_SYMBOL(snd_wss_interrupt);
-
-static snd_pcm_uframes_t snd_wss_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_wss *chip = snd_pcm_substream_chip(substream);
- size_t ptr;
-
- if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE))
- return 0;
- ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size);
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-static snd_pcm_uframes_t snd_wss_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_wss *chip = snd_pcm_substream_chip(substream);
- size_t ptr;
-
- if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE))
- return 0;
- ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size);
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-/*
-
- */
-
-static int snd_ad1848_probe(struct snd_wss *chip)
-{
- unsigned long timeout = jiffies + msecs_to_jiffies(1000);
- unsigned long flags;
- unsigned char r;
- unsigned short hardware = 0;
- int err = 0;
- int i;
-
- while (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) {
- if (time_after(jiffies, timeout))
- return -ENODEV;
- cond_resched();
- }
- spin_lock_irqsave(&chip->reg_lock, flags);
-
- /* set CS423x MODE 1 */
- snd_wss_dout(chip, CS4231_MISC_INFO, 0);
-
- snd_wss_dout(chip, CS4231_RIGHT_INPUT, 0x45); /* 0x55 & ~0x10 */
- r = snd_wss_in(chip, CS4231_RIGHT_INPUT);
- if (r != 0x45) {
- /* RMGE always high on AD1847 */
- if ((r & ~CS4231_ENABLE_MIC_GAIN) != 0x45) {
- err = -ENODEV;
- goto out;
- }
- hardware = WSS_HW_AD1847;
- } else {
- snd_wss_dout(chip, CS4231_LEFT_INPUT, 0xaa);
- r = snd_wss_in(chip, CS4231_LEFT_INPUT);
- /* L/RMGE always low on AT2320 */
- if ((r | CS4231_ENABLE_MIC_GAIN) != 0xaa) {
- err = -ENODEV;
- goto out;
- }
- }
-
- /* clear pending IRQ */
- wss_inb(chip, CS4231P(STATUS));
- wss_outb(chip, CS4231P(STATUS), 0);
- mb();
-
- if ((chip->hardware & WSS_HW_TYPE_MASK) != WSS_HW_DETECT)
- goto out;
-
- if (hardware) {
- chip->hardware = hardware;
- goto out;
- }
-
- r = snd_wss_in(chip, CS4231_MISC_INFO);
-
- /* set CS423x MODE 2 */
- snd_wss_dout(chip, CS4231_MISC_INFO, CS4231_MODE2);
- for (i = 0; i < 16; i++) {
- if (snd_wss_in(chip, i) != snd_wss_in(chip, 16 + i)) {
- /* we have more than 16 registers: check ID */
- if ((r & 0xf) != 0xa)
- goto out_mode;
- /*
- * on CMI8330, CS4231_VERSION is volume control and
- * can be set to 0
- */
- snd_wss_dout(chip, CS4231_VERSION, 0);
- r = snd_wss_in(chip, CS4231_VERSION) & 0xe7;
- if (!r)
- chip->hardware = WSS_HW_CMI8330;
- goto out_mode;
- }
- }
- if (r & 0x80)
- chip->hardware = WSS_HW_CS4248;
- else
- chip->hardware = WSS_HW_AD1848;
-out_mode:
- snd_wss_dout(chip, CS4231_MISC_INFO, 0);
-out:
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return err;
-}
-
-static int snd_wss_probe(struct snd_wss *chip)
-{
- unsigned long flags;
- int i, id, rev, regnum;
- unsigned char *ptr;
- unsigned int hw;
-
- id = snd_ad1848_probe(chip);
- if (id < 0)
- return id;
-
- hw = chip->hardware;
- if ((hw & WSS_HW_TYPE_MASK) == WSS_HW_DETECT) {
- for (i = 0; i < 50; i++) {
- mb();
- if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
- msleep(2);
- else {
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_wss_out(chip, CS4231_MISC_INFO,
- CS4231_MODE2);
- id = snd_wss_in(chip, CS4231_MISC_INFO) & 0x0f;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (id == 0x0a)
- break; /* this is valid value */
- }
- }
- snd_printdd("wss: port = 0x%lx, id = 0x%x\n", chip->port, id);
- if (id != 0x0a)
- return -ENODEV; /* no valid device found */
-
- rev = snd_wss_in(chip, CS4231_VERSION) & 0xe7;
- snd_printdd("CS4231: VERSION (I25) = 0x%x\n", rev);
- if (rev == 0x80) {
- unsigned char tmp = snd_wss_in(chip, 23);
- snd_wss_out(chip, 23, ~tmp);
- if (snd_wss_in(chip, 23) != tmp)
- chip->hardware = WSS_HW_AD1845;
- else
- chip->hardware = WSS_HW_CS4231;
- } else if (rev == 0xa0) {
- chip->hardware = WSS_HW_CS4231A;
- } else if (rev == 0xa2) {
- chip->hardware = WSS_HW_CS4232;
- } else if (rev == 0xb2) {
- chip->hardware = WSS_HW_CS4232A;
- } else if (rev == 0x83) {
- chip->hardware = WSS_HW_CS4236;
- } else if (rev == 0x03) {
- chip->hardware = WSS_HW_CS4236B;
- } else {
- snd_printk(KERN_ERR
- "unknown CS chip with version 0x%x\n", rev);
- return -ENODEV; /* unknown CS4231 chip? */
- }
- }
- spin_lock_irqsave(&chip->reg_lock, flags);
- wss_inb(chip, CS4231P(STATUS)); /* clear any pendings IRQ */
- wss_outb(chip, CS4231P(STATUS), 0);
- mb();
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- if (!(chip->hardware & WSS_HW_AD1848_MASK))
- chip->image[CS4231_MISC_INFO] = CS4231_MODE2;
- switch (chip->hardware) {
- case WSS_HW_INTERWAVE:
- chip->image[CS4231_MISC_INFO] = CS4231_IW_MODE3;
- break;
- case WSS_HW_CS4235:
- case WSS_HW_CS4236B:
- case WSS_HW_CS4237B:
- case WSS_HW_CS4238B:
- case WSS_HW_CS4239:
- if (hw == WSS_HW_DETECT3)
- chip->image[CS4231_MISC_INFO] = CS4231_4236_MODE3;
- else
- chip->hardware = WSS_HW_CS4236;
- break;
- }
-
- chip->image[CS4231_IFACE_CTRL] =
- (chip->image[CS4231_IFACE_CTRL] & ~CS4231_SINGLE_DMA) |
- (chip->single_dma ? CS4231_SINGLE_DMA : 0);
- if (chip->hardware != WSS_HW_OPTI93X) {
- chip->image[CS4231_ALT_FEATURE_1] = 0x80;
- chip->image[CS4231_ALT_FEATURE_2] =
- chip->hardware == WSS_HW_INTERWAVE ? 0xc2 : 0x01;
- }
- /* enable fine grained frequency selection */
- if (chip->hardware == WSS_HW_AD1845)
- chip->image[AD1845_PWR_DOWN] = 8;
-
- ptr = (unsigned char *) &chip->image;
- regnum = (chip->hardware & WSS_HW_AD1848_MASK) ? 16 : 32;
- snd_wss_mce_down(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- for (i = 0; i < regnum; i++) /* ok.. fill all registers */
- snd_wss_out(chip, i, *ptr++);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- snd_wss_mce_up(chip);
- snd_wss_mce_down(chip);
-
- mdelay(2);
-
- /* ok.. try check hardware version for CS4236+ chips */
- if ((hw & WSS_HW_TYPE_MASK) == WSS_HW_DETECT) {
- if (chip->hardware == WSS_HW_CS4236B) {
- rev = snd_cs4236_ext_in(chip, CS4236_VERSION);
- snd_cs4236_ext_out(chip, CS4236_VERSION, 0xff);
- id = snd_cs4236_ext_in(chip, CS4236_VERSION);
- snd_cs4236_ext_out(chip, CS4236_VERSION, rev);
- snd_printdd("CS4231: ext version; rev = 0x%x, id = 0x%x\n", rev, id);
- if ((id & 0x1f) == 0x1d) { /* CS4235 */
- chip->hardware = WSS_HW_CS4235;
- switch (id >> 5) {
- case 4:
- case 5:
- case 6:
- break;
- default:
- snd_printk(KERN_WARNING
- "unknown CS4235 chip "
- "(enhanced version = 0x%x)\n",
- id);
- }
- } else if ((id & 0x1f) == 0x0b) { /* CS4236/B */
- switch (id >> 5) {
- case 4:
- case 5:
- case 6:
- case 7:
- chip->hardware = WSS_HW_CS4236B;
- break;
- default:
- snd_printk(KERN_WARNING
- "unknown CS4236 chip "
- "(enhanced version = 0x%x)\n",
- id);
- }
- } else if ((id & 0x1f) == 0x08) { /* CS4237B */
- chip->hardware = WSS_HW_CS4237B;
- switch (id >> 5) {
- case 4:
- case 5:
- case 6:
- case 7:
- break;
- default:
- snd_printk(KERN_WARNING
- "unknown CS4237B chip "
- "(enhanced version = 0x%x)\n",
- id);
- }
- } else if ((id & 0x1f) == 0x09) { /* CS4238B */
- chip->hardware = WSS_HW_CS4238B;
- switch (id >> 5) {
- case 5:
- case 6:
- case 7:
- break;
- default:
- snd_printk(KERN_WARNING
- "unknown CS4238B chip "
- "(enhanced version = 0x%x)\n",
- id);
- }
- } else if ((id & 0x1f) == 0x1e) { /* CS4239 */
- chip->hardware = WSS_HW_CS4239;
- switch (id >> 5) {
- case 4:
- case 5:
- case 6:
- break;
- default:
- snd_printk(KERN_WARNING
- "unknown CS4239 chip "
- "(enhanced version = 0x%x)\n",
- id);
- }
- } else {
- snd_printk(KERN_WARNING
- "unknown CS4236/CS423xB chip "
- "(enhanced version = 0x%x)\n", id);
- }
- }
- }
- return 0; /* all things are ok.. */
-}
-
-/*
-
- */
-
-static struct snd_pcm_hardware snd_wss_playback =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_SYNC_START),
- .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
- SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
- .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 5510,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_wss_capture =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_SYNC_START),
- .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
- SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
- .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 5510,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-/*
-
- */
-
-static int snd_wss_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_wss *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- runtime->hw = snd_wss_playback;
-
- /* hardware limitation of older chipsets */
- if (chip->hardware & WSS_HW_AD1848_MASK)
- runtime->hw.formats &= ~(SNDRV_PCM_FMTBIT_IMA_ADPCM |
- SNDRV_PCM_FMTBIT_S16_BE);
-
- /* hardware bug in InterWave chipset */
- if (chip->hardware == WSS_HW_INTERWAVE && chip->dma1 > 3)
- runtime->hw.formats &= ~SNDRV_PCM_FMTBIT_MU_LAW;
-
- /* hardware limitation of cheap chips */
- if (chip->hardware == WSS_HW_CS4235 ||
- chip->hardware == WSS_HW_CS4239)
- runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE;
-
- snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max);
- snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max);
-
- if (chip->claim_dma) {
- if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma1)) < 0)
- return err;
- }
-
- err = snd_wss_open(chip, WSS_MODE_PLAY);
- if (err < 0) {
- if (chip->release_dma)
- chip->release_dma(chip, chip->dma_private_data, chip->dma1);
- snd_free_pages(runtime->dma_area, runtime->dma_bytes);
- return err;
- }
- chip->playback_substream = substream;
- snd_pcm_set_sync(substream);
- chip->rate_constraint(runtime);
- return 0;
-}
-
-static int snd_wss_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_wss *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- runtime->hw = snd_wss_capture;
-
- /* hardware limitation of older chipsets */
- if (chip->hardware & WSS_HW_AD1848_MASK)
- runtime->hw.formats &= ~(SNDRV_PCM_FMTBIT_IMA_ADPCM |
- SNDRV_PCM_FMTBIT_S16_BE);
-
- /* hardware limitation of cheap chips */
- if (chip->hardware == WSS_HW_CS4235 ||
- chip->hardware == WSS_HW_CS4239 ||
- chip->hardware == WSS_HW_OPTI93X)
- runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE;
-
- snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max);
- snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max);
-
- if (chip->claim_dma) {
- if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma2)) < 0)
- return err;
- }
-
- err = snd_wss_open(chip, WSS_MODE_RECORD);
- if (err < 0) {
- if (chip->release_dma)
- chip->release_dma(chip, chip->dma_private_data, chip->dma2);
- snd_free_pages(runtime->dma_area, runtime->dma_bytes);
- return err;
- }
- chip->capture_substream = substream;
- snd_pcm_set_sync(substream);
- chip->rate_constraint(runtime);
- return 0;
-}
-
-static int snd_wss_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_wss *chip = snd_pcm_substream_chip(substream);
-
- chip->playback_substream = NULL;
- snd_wss_close(chip, WSS_MODE_PLAY);
- return 0;
-}
-
-static int snd_wss_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_wss *chip = snd_pcm_substream_chip(substream);
-
- chip->capture_substream = NULL;
- snd_wss_close(chip, WSS_MODE_RECORD);
- return 0;
-}
-
-static void snd_wss_thinkpad_twiddle(struct snd_wss *chip, int on)
-{
- int tmp;
-
- if (!chip->thinkpad_flag)
- return;
-
- outb(0x1c, AD1848_THINKPAD_CTL_PORT1);
- tmp = inb(AD1848_THINKPAD_CTL_PORT2);
-
- if (on)
- /* turn it on */
- tmp |= AD1848_THINKPAD_CS4248_ENABLE_BIT;
- else
- /* turn it off */
- tmp &= ~AD1848_THINKPAD_CS4248_ENABLE_BIT;
-
- outb(tmp, AD1848_THINKPAD_CTL_PORT2);
-}
-
-#ifdef CONFIG_PM
-
-/* lowlevel suspend callback for CS4231 */
-static void snd_wss_suspend(struct snd_wss *chip)
-{
- int reg;
- unsigned long flags;
-
- snd_pcm_suspend_all(chip->pcm);
- spin_lock_irqsave(&chip->reg_lock, flags);
- for (reg = 0; reg < 32; reg++)
- chip->image[reg] = snd_wss_in(chip, reg);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (chip->thinkpad_flag)
- snd_wss_thinkpad_twiddle(chip, 0);
-}
-
-/* lowlevel resume callback for CS4231 */
-static void snd_wss_resume(struct snd_wss *chip)
-{
- int reg;
- unsigned long flags;
- /* int timeout; */
-
- if (chip->thinkpad_flag)
- snd_wss_thinkpad_twiddle(chip, 1);
- snd_wss_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- for (reg = 0; reg < 32; reg++) {
- switch (reg) {
- case CS4231_VERSION:
- break;
- default:
- snd_wss_out(chip, reg, chip->image[reg]);
- break;
- }
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-#if 1
- snd_wss_mce_down(chip);
-#else
- /* The following is a workaround to avoid freeze after resume on TP600E.
- This is the first half of copy of snd_wss_mce_down(), but doesn't
- include rescheduling. -- iwai
- */
- snd_wss_busy_wait(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- chip->mce_bit &= ~CS4231_MCE;
- timeout = wss_inb(chip, CS4231P(REGSEL));
- wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (timeout == 0x80)
- snd_printk(KERN_ERR "down [0x%lx]: serious init problem "
- "- codec still busy\n", chip->port);
- if ((timeout & CS4231_MCE) == 0 ||
- !(chip->hardware & (WSS_HW_CS4231_MASK | WSS_HW_CS4232_MASK))) {
- return;
- }
- snd_wss_busy_wait(chip);
-#endif
-}
-#endif /* CONFIG_PM */
-
-static int snd_wss_free(struct snd_wss *chip)
-{
- release_and_free_resource(chip->res_port);
- release_and_free_resource(chip->res_cport);
- if (chip->irq >= 0) {
- disable_irq(chip->irq);
- if (!(chip->hwshare & WSS_HWSHARE_IRQ))
- free_irq(chip->irq, (void *) chip);
- }
- if (!(chip->hwshare & WSS_HWSHARE_DMA1) && chip->dma1 >= 0) {
- snd_dma_disable(chip->dma1);
- free_dma(chip->dma1);
- }
- if (!(chip->hwshare & WSS_HWSHARE_DMA2) &&
- chip->dma2 >= 0 && chip->dma2 != chip->dma1) {
- snd_dma_disable(chip->dma2);
- free_dma(chip->dma2);
- }
- if (chip->timer)
- snd_device_free(chip->card, chip->timer);
- kfree(chip);
- return 0;
-}
-
-static int snd_wss_dev_free(struct snd_device *device)
-{
- struct snd_wss *chip = device->device_data;
- return snd_wss_free(chip);
-}
-
-const char *snd_wss_chip_id(struct snd_wss *chip)
-{
- switch (chip->hardware) {
- case WSS_HW_CS4231:
- return "CS4231";
- case WSS_HW_CS4231A:
- return "CS4231A";
- case WSS_HW_CS4232:
- return "CS4232";
- case WSS_HW_CS4232A:
- return "CS4232A";
- case WSS_HW_CS4235:
- return "CS4235";
- case WSS_HW_CS4236:
- return "CS4236";
- case WSS_HW_CS4236B:
- return "CS4236B";
- case WSS_HW_CS4237B:
- return "CS4237B";
- case WSS_HW_CS4238B:
- return "CS4238B";
- case WSS_HW_CS4239:
- return "CS4239";
- case WSS_HW_INTERWAVE:
- return "AMD InterWave";
- case WSS_HW_OPL3SA2:
- return chip->card->shortname;
- case WSS_HW_AD1845:
- return "AD1845";
- case WSS_HW_OPTI93X:
- return "OPTi 93x";
- case WSS_HW_AD1847:
- return "AD1847";
- case WSS_HW_AD1848:
- return "AD1848";
- case WSS_HW_CS4248:
- return "CS4248";
- case WSS_HW_CMI8330:
- return "CMI8330/C3D";
- default:
- return "???";
- }
-}
-EXPORT_SYMBOL(snd_wss_chip_id);
-
-static int snd_wss_new(struct snd_card *card,
- unsigned short hardware,
- unsigned short hwshare,
- struct snd_wss **rchip)
-{
- struct snd_wss *chip;
-
- *rchip = NULL;
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL)
- return -ENOMEM;
- chip->hardware = hardware;
- chip->hwshare = hwshare;
-
- spin_lock_init(&chip->reg_lock);
- mutex_init(&chip->mce_mutex);
- mutex_init(&chip->open_mutex);
- chip->card = card;
- chip->rate_constraint = snd_wss_xrate;
- chip->set_playback_format = snd_wss_playback_format;
- chip->set_capture_format = snd_wss_capture_format;
- if (chip->hardware == WSS_HW_OPTI93X)
- memcpy(&chip->image, &snd_opti93x_original_image,
- sizeof(snd_opti93x_original_image));
- else
- memcpy(&chip->image, &snd_wss_original_image,
- sizeof(snd_wss_original_image));
- if (chip->hardware & WSS_HW_AD1848_MASK) {
- chip->image[CS4231_PIN_CTRL] = 0;
- chip->image[CS4231_TEST_INIT] = 0;
- }
-
- *rchip = chip;
- return 0;
-}
-
-int snd_wss_create(struct snd_card *card,
- unsigned long port,
- unsigned long cport,
- int irq, int dma1, int dma2,
- unsigned short hardware,
- unsigned short hwshare,
- struct snd_wss **rchip)
-{
- static struct snd_device_ops ops = {
- .dev_free = snd_wss_dev_free,
- };
- struct snd_wss *chip;
- int err;
-
- err = snd_wss_new(card, hardware, hwshare, &chip);
- if (err < 0)
- return err;
-
- chip->irq = -1;
- chip->dma1 = -1;
- chip->dma2 = -1;
-
- chip->res_port = request_region(port, 4, "WSS");
- if (!chip->res_port) {
- snd_printk(KERN_ERR "wss: can't grab port 0x%lx\n", port);
- snd_wss_free(chip);
- return -EBUSY;
- }
- chip->port = port;
- if ((long)cport >= 0) {
- chip->res_cport = request_region(cport, 8, "CS4232 Control");
- if (!chip->res_cport) {
- snd_printk(KERN_ERR
- "wss: can't grab control port 0x%lx\n", cport);
- snd_wss_free(chip);
- return -ENODEV;
- }
- }
- chip->cport = cport;
- if (!(hwshare & WSS_HWSHARE_IRQ))
- if (request_irq(irq, snd_wss_interrupt, 0,
- "WSS", (void *) chip)) {
- snd_printk(KERN_ERR "wss: can't grab IRQ %d\n", irq);
- snd_wss_free(chip);
- return -EBUSY;
- }
- chip->irq = irq;
- if (!(hwshare & WSS_HWSHARE_DMA1) && request_dma(dma1, "WSS - 1")) {
- snd_printk(KERN_ERR "wss: can't grab DMA1 %d\n", dma1);
- snd_wss_free(chip);
- return -EBUSY;
- }
- chip->dma1 = dma1;
- if (!(hwshare & WSS_HWSHARE_DMA2) && dma1 != dma2 &&
- dma2 >= 0 && request_dma(dma2, "WSS - 2")) {
- snd_printk(KERN_ERR "wss: can't grab DMA2 %d\n", dma2);
- snd_wss_free(chip);
- return -EBUSY;
- }
- if (dma1 == dma2 || dma2 < 0) {
- chip->single_dma = 1;
- chip->dma2 = chip->dma1;
- } else
- chip->dma2 = dma2;
-
- if (hardware == WSS_HW_THINKPAD) {
- chip->thinkpad_flag = 1;
- chip->hardware = WSS_HW_DETECT; /* reset */
- snd_wss_thinkpad_twiddle(chip, 1);
- }
-
- /* global setup */
- if (snd_wss_probe(chip) < 0) {
- snd_wss_free(chip);
- return -ENODEV;
- }
- snd_wss_init(chip);
-
-#if 0
- if (chip->hardware & WSS_HW_CS4232_MASK) {
- if (chip->res_cport == NULL)
- snd_printk(KERN_ERR "CS4232 control port features are "
- "not accessible\n");
- }
-#endif
-
- /* Register device */
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
- if (err < 0) {
- snd_wss_free(chip);
- return err;
- }
-
-#ifdef CONFIG_PM
- /* Power Management */
- chip->suspend = snd_wss_suspend;
- chip->resume = snd_wss_resume;
-#endif
-
- *rchip = chip;
- return 0;
-}
-EXPORT_SYMBOL(snd_wss_create);
-
-static struct snd_pcm_ops snd_wss_playback_ops = {
- .open = snd_wss_playback_open,
- .close = snd_wss_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_wss_playback_hw_params,
- .hw_free = snd_wss_playback_hw_free,
- .prepare = snd_wss_playback_prepare,
- .trigger = snd_wss_trigger,
- .pointer = snd_wss_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_wss_capture_ops = {
- .open = snd_wss_capture_open,
- .close = snd_wss_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_wss_capture_hw_params,
- .hw_free = snd_wss_capture_hw_free,
- .prepare = snd_wss_capture_prepare,
- .trigger = snd_wss_trigger,
- .pointer = snd_wss_capture_pointer,
-};
-
-int snd_wss_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- err = snd_pcm_new(chip->card, "WSS", device, 1, 1, &pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_wss_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_wss_capture_ops);
-
- /* global setup */
- pcm->private_data = chip;
- pcm->info_flags = 0;
- if (chip->single_dma)
- pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX;
- if (chip->hardware != WSS_HW_INTERWAVE)
- pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX;
- strcpy(pcm->name, snd_wss_chip_id(chip));
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_isa_data(),
- 64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024);
-
- chip->pcm = pcm;
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-EXPORT_SYMBOL(snd_wss_pcm);
-
-static void snd_wss_timer_free(struct snd_timer *timer)
-{
- struct snd_wss *chip = timer->private_data;
- chip->timer = NULL;
-}
-
-int snd_wss_timer(struct snd_wss *chip, int device, struct snd_timer **rtimer)
-{
- struct snd_timer *timer;
- struct snd_timer_id tid;
- int err;
-
- /* Timer initialization */
- tid.dev_class = SNDRV_TIMER_CLASS_CARD;
- tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
- tid.card = chip->card->number;
- tid.device = device;
- tid.subdevice = 0;
- if ((err = snd_timer_new(chip->card, "CS4231", &tid, &timer)) < 0)
- return err;
- strcpy(timer->name, snd_wss_chip_id(chip));
- timer->private_data = chip;
- timer->private_free = snd_wss_timer_free;
- timer->hw = snd_wss_timer_table;
- chip->timer = timer;
- if (rtimer)
- *rtimer = timer;
- return 0;
-}
-EXPORT_SYMBOL(snd_wss_timer);
-
-/*
- * MIXER part
- */
-
-static int snd_wss_info_mux(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[4] = {
- "Line", "Aux", "Mic", "Mix"
- };
- static char *opl3sa_texts[4] = {
- "Line", "CD", "Mic", "Mix"
- };
- static char *gusmax_texts[4] = {
- "Line", "Synth", "Mic", "Mix"
- };
- char **ptexts = texts;
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
-
- if (snd_BUG_ON(!chip->card))
- return -EINVAL;
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 2;
- uinfo->value.enumerated.items = 4;
- if (uinfo->value.enumerated.item > 3)
- uinfo->value.enumerated.item = 3;
- if (!strcmp(chip->card->driver, "GUS MAX"))
- ptexts = gusmax_texts;
- switch (chip->hardware) {
- case WSS_HW_INTERWAVE:
- ptexts = gusmax_texts;
- break;
- case WSS_HW_OPTI93X:
- case WSS_HW_OPL3SA2:
- ptexts = opl3sa_texts;
- break;
- }
- strcpy(uinfo->value.enumerated.name, ptexts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_wss_get_mux(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- ucontrol->value.enumerated.item[0] = (chip->image[CS4231_LEFT_INPUT] & CS4231_MIXS_ALL) >> 6;
- ucontrol->value.enumerated.item[1] = (chip->image[CS4231_RIGHT_INPUT] & CS4231_MIXS_ALL) >> 6;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
-}
-
-static int snd_wss_put_mux(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- unsigned short left, right;
- int change;
-
- if (ucontrol->value.enumerated.item[0] > 3 ||
- ucontrol->value.enumerated.item[1] > 3)
- return -EINVAL;
- left = ucontrol->value.enumerated.item[0] << 6;
- right = ucontrol->value.enumerated.item[1] << 6;
- spin_lock_irqsave(&chip->reg_lock, flags);
- left = (chip->image[CS4231_LEFT_INPUT] & ~CS4231_MIXS_ALL) | left;
- right = (chip->image[CS4231_RIGHT_INPUT] & ~CS4231_MIXS_ALL) | right;
- change = left != chip->image[CS4231_LEFT_INPUT] ||
- right != chip->image[CS4231_RIGHT_INPUT];
- snd_wss_out(chip, CS4231_LEFT_INPUT, left);
- snd_wss_out(chip, CS4231_RIGHT_INPUT, right);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return change;
-}
-
-int snd_wss_info_single(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 16) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-EXPORT_SYMBOL(snd_wss_info_single);
-
-int snd_wss_get_single(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (invert)
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- return 0;
-}
-EXPORT_SYMBOL(snd_wss_get_single);
-
-int snd_wss_put_single(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
- int change;
- unsigned short val;
-
- val = (ucontrol->value.integer.value[0] & mask);
- if (invert)
- val = mask - val;
- val <<= shift;
- spin_lock_irqsave(&chip->reg_lock, flags);
- val = (chip->image[reg] & ~(mask << shift)) | val;
- change = val != chip->image[reg];
- snd_wss_out(chip, reg, val);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return change;
-}
-EXPORT_SYMBOL(snd_wss_put_single);
-
-int snd_wss_info_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 24) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-EXPORT_SYMBOL(snd_wss_info_double);
-
-int snd_wss_get_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int shift_left = (kcontrol->private_value >> 16) & 0x07;
- int shift_right = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask;
- ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (invert) {
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
- }
- return 0;
-}
-EXPORT_SYMBOL(snd_wss_get_double);
-
-int snd_wss_put_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int shift_left = (kcontrol->private_value >> 16) & 0x07;
- int shift_right = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
- int change;
- unsigned short val1, val2;
-
- val1 = ucontrol->value.integer.value[0] & mask;
- val2 = ucontrol->value.integer.value[1] & mask;
- if (invert) {
- val1 = mask - val1;
- val2 = mask - val2;
- }
- val1 <<= shift_left;
- val2 <<= shift_right;
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (left_reg != right_reg) {
- val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
- val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2;
- change = val1 != chip->image[left_reg] ||
- val2 != chip->image[right_reg];
- snd_wss_out(chip, left_reg, val1);
- snd_wss_out(chip, right_reg, val2);
- } else {
- mask = (mask << shift_left) | (mask << shift_right);
- val1 = (chip->image[left_reg] & ~mask) | val1 | val2;
- change = val1 != chip->image[left_reg];
- snd_wss_out(chip, left_reg, val1);
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return change;
-}
-EXPORT_SYMBOL(snd_wss_put_double);
-
-static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);
-
-static struct snd_kcontrol_new snd_wss_controls[] = {
-WSS_DOUBLE("PCM Playback Switch", 0,
- CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
-WSS_DOUBLE_TLV("PCM Playback Volume", 0,
- CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
- db_scale_6bit),
-WSS_DOUBLE("Aux Playback Switch", 0,
- CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
-WSS_DOUBLE_TLV("Aux Playback Volume", 0,
- CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
- db_scale_5bit_12db_max),
-WSS_DOUBLE("Aux Playback Switch", 1,
- CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
-WSS_DOUBLE_TLV("Aux Playback Volume", 1,
- CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
- db_scale_5bit_12db_max),
-WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT,
- 0, 0, 15, 0, db_scale_rec_gain),
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = snd_wss_info_mux,
- .get = snd_wss_get_mux,
- .put = snd_wss_put_mux,
-},
-WSS_DOUBLE("Mic Boost (+20dB)", 0,
- CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
-WSS_SINGLE("Loopback Capture Switch", 0,
- CS4231_LOOPBACK, 0, 1, 0),
-WSS_SINGLE_TLV("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1,
- db_scale_6bit),
-WSS_DOUBLE("Line Playback Switch", 0,
- CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
-WSS_DOUBLE_TLV("Line Playback Volume", 0,
- CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1,
- db_scale_5bit_12db_max),
-WSS_SINGLE("Beep Playback Switch", 0,
- CS4231_MONO_CTRL, 7, 1, 1),
-WSS_SINGLE_TLV("Beep Playback Volume", 0,
- CS4231_MONO_CTRL, 0, 15, 1,
- db_scale_4bit),
-WSS_SINGLE("Mono Output Playback Switch", 0,
- CS4231_MONO_CTRL, 6, 1, 1),
-WSS_SINGLE("Beep Bypass Playback Switch", 0,
- CS4231_MONO_CTRL, 5, 1, 0),
-};
-
-int snd_wss_mixer(struct snd_wss *chip)
-{
- struct snd_card *card;
- unsigned int idx;
- int err;
- int count = ARRAY_SIZE(snd_wss_controls);
-
- if (snd_BUG_ON(!chip || !chip->pcm))
- return -EINVAL;
-
- card = chip->card;
-
- strcpy(card->mixername, chip->pcm->name);
-
- /* Use only the first 11 entries on AD1848 */
- if (chip->hardware & WSS_HW_AD1848_MASK)
- count = 11;
- /* There is no loopback on OPTI93X */
- else if (chip->hardware == WSS_HW_OPTI93X)
- count = 9;
-
- for (idx = 0; idx < count; idx++) {
- err = snd_ctl_add(card,
- snd_ctl_new1(&snd_wss_controls[idx],
- chip));
- if (err < 0)
- return err;
- }
- return 0;
-}
-EXPORT_SYMBOL(snd_wss_mixer);
-
-const struct snd_pcm_ops *snd_wss_get_pcm_ops(int direction)
-{
- return direction == SNDRV_PCM_STREAM_PLAYBACK ?
- &snd_wss_playback_ops : &snd_wss_capture_ops;
-}
-EXPORT_SYMBOL(snd_wss_get_pcm_ops);
-
-/*
- * INIT part
- */
-
-static int __init alsa_wss_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_wss_exit(void)
-{
-}
-
-module_init(alsa_wss_init);
-module_exit(alsa_wss_exit);
diff --git a/ANDROID_3.4.5/sound/last.c b/ANDROID_3.4.5/sound/last.c
deleted file mode 100644
index 7ffc182e..00000000
--- a/ANDROID_3.4.5/sound/last.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Advanced Linux Sound Architecture
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define SNDRV_MAIN_OBJECT_FILE
-#include <linux/init.h>
-#include <sound/core.h>
-
-static int __init alsa_sound_last_init(void)
-{
- int idx, ok = 0;
-
- printk(KERN_INFO "ALSA device list:\n");
- for (idx = 0; idx < SNDRV_CARDS; idx++)
- if (snd_cards[idx] != NULL) {
- printk(KERN_INFO " #%i: %s\n", idx, snd_cards[idx]->longname);
- ok++;
- }
- if (ok == 0)
- printk(KERN_INFO " No soundcards found.\n");
- return 0;
-}
-
-late_initcall_sync(alsa_sound_last_init);
diff --git a/ANDROID_3.4.5/sound/mips/Kconfig b/ANDROID_3.4.5/sound/mips/Kconfig
deleted file mode 100644
index d2f615ab..00000000
--- a/ANDROID_3.4.5/sound/mips/Kconfig
+++ /dev/null
@@ -1,37 +0,0 @@
-# ALSA MIPS drivers
-
-menuconfig SND_MIPS
- bool "MIPS sound devices"
- depends on MIPS
- default y
- help
- Support for sound devices of MIPS architectures.
-
-if SND_MIPS
-
-config SND_SGI_O2
- tristate "SGI O2 Audio"
- depends on SGI_IP32
- help
- Sound support for the SGI O2 Workstation.
-
-config SND_SGI_HAL2
- tristate "SGI HAL2 Audio"
- depends on SGI_HAS_HAL2
- help
- Sound support for the SGI Indy and Indigo2 Workstation.
-
-
-config SND_AU1X00
- tristate "Au1x00 AC97 Port Driver (DEPRECATED)"
- depends on MIPS_ALCHEMY
- select SND_PCM
- select SND_AC97_CODEC
- help
- ALSA Sound driver for the Au1x00's AC97 port.
-
- Newer drivers for ASoC are available, please do not use
- this driver as it will be removed in the future.
-
-endif # SND_MIPS
-
diff --git a/ANDROID_3.4.5/sound/mips/Makefile b/ANDROID_3.4.5/sound/mips/Makefile
deleted file mode 100644
index 861ec0a5..00000000
--- a/ANDROID_3.4.5/sound/mips/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# Makefile for ALSA
-#
-
-snd-au1x00-objs := au1x00.o
-snd-sgi-o2-objs := sgio2audio.o ad1843.o
-snd-sgi-hal2-objs := hal2.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_AU1X00) += snd-au1x00.o
-obj-$(CONFIG_SND_SGI_O2) += snd-sgi-o2.o
-obj-$(CONFIG_SND_SGI_HAL2) += snd-sgi-hal2.o
diff --git a/ANDROID_3.4.5/sound/mips/ad1843.c b/ANDROID_3.4.5/sound/mips/ad1843.c
deleted file mode 100644
index c624510e..00000000
--- a/ANDROID_3.4.5/sound/mips/ad1843.c
+++ /dev/null
@@ -1,561 +0,0 @@
-/*
- * AD1843 low level driver
- *
- * Copyright 2003 Vivien Chappelier <vivien.chappelier@linux-mips.org>
- * Copyright 2008 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
- *
- * inspired from vwsnd.c (SGI VW audio driver)
- * Copyright 1999 Silicon Graphics, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/ad1843.h>
-
-/*
- * AD1843 bitfield definitions. All are named as in the AD1843 data
- * sheet, with ad1843_ prepended and individual bit numbers removed.
- *
- * E.g., bits LSS0 through LSS2 become ad1843_LSS.
- *
- * Only the bitfields we need are defined.
- */
-
-struct ad1843_bitfield {
- char reg;
- char lo_bit;
- char nbits;
-};
-
-static const struct ad1843_bitfield
- ad1843_PDNO = { 0, 14, 1 }, /* Converter Power-Down Flag */
- ad1843_INIT = { 0, 15, 1 }, /* Clock Initialization Flag */
- ad1843_RIG = { 2, 0, 4 }, /* Right ADC Input Gain */
- ad1843_RMGE = { 2, 4, 1 }, /* Right ADC Mic Gain Enable */
- ad1843_RSS = { 2, 5, 3 }, /* Right ADC Source Select */
- ad1843_LIG = { 2, 8, 4 }, /* Left ADC Input Gain */
- ad1843_LMGE = { 2, 12, 1 }, /* Left ADC Mic Gain Enable */
- ad1843_LSS = { 2, 13, 3 }, /* Left ADC Source Select */
- ad1843_RD2M = { 3, 0, 5 }, /* Right DAC 2 Mix Gain/Atten */
- ad1843_RD2MM = { 3, 7, 1 }, /* Right DAC 2 Mix Mute */
- ad1843_LD2M = { 3, 8, 5 }, /* Left DAC 2 Mix Gain/Atten */
- ad1843_LD2MM = { 3, 15, 1 }, /* Left DAC 2 Mix Mute */
- ad1843_RX1M = { 4, 0, 5 }, /* Right Aux 1 Mix Gain/Atten */
- ad1843_RX1MM = { 4, 7, 1 }, /* Right Aux 1 Mix Mute */
- ad1843_LX1M = { 4, 8, 5 }, /* Left Aux 1 Mix Gain/Atten */
- ad1843_LX1MM = { 4, 15, 1 }, /* Left Aux 1 Mix Mute */
- ad1843_RX2M = { 5, 0, 5 }, /* Right Aux 2 Mix Gain/Atten */
- ad1843_RX2MM = { 5, 7, 1 }, /* Right Aux 2 Mix Mute */
- ad1843_LX2M = { 5, 8, 5 }, /* Left Aux 2 Mix Gain/Atten */
- ad1843_LX2MM = { 5, 15, 1 }, /* Left Aux 2 Mix Mute */
- ad1843_RMCM = { 7, 0, 5 }, /* Right Mic Mix Gain/Atten */
- ad1843_RMCMM = { 7, 7, 1 }, /* Right Mic Mix Mute */
- ad1843_LMCM = { 7, 8, 5 }, /* Left Mic Mix Gain/Atten */
- ad1843_LMCMM = { 7, 15, 1 }, /* Left Mic Mix Mute */
- ad1843_HPOS = { 8, 4, 1 }, /* Headphone Output Voltage Swing */
- ad1843_HPOM = { 8, 5, 1 }, /* Headphone Output Mute */
- ad1843_MPOM = { 8, 6, 1 }, /* Mono Output Mute */
- ad1843_RDA1G = { 9, 0, 6 }, /* Right DAC1 Analog/Digital Gain */
- ad1843_RDA1GM = { 9, 7, 1 }, /* Right DAC1 Analog Mute */
- ad1843_LDA1G = { 9, 8, 6 }, /* Left DAC1 Analog/Digital Gain */
- ad1843_LDA1GM = { 9, 15, 1 }, /* Left DAC1 Analog Mute */
- ad1843_RDA2G = { 10, 0, 6 }, /* Right DAC2 Analog/Digital Gain */
- ad1843_RDA2GM = { 10, 7, 1 }, /* Right DAC2 Analog Mute */
- ad1843_LDA2G = { 10, 8, 6 }, /* Left DAC2 Analog/Digital Gain */
- ad1843_LDA2GM = { 10, 15, 1 }, /* Left DAC2 Analog Mute */
- ad1843_RDA1AM = { 11, 7, 1 }, /* Right DAC1 Digital Mute */
- ad1843_LDA1AM = { 11, 15, 1 }, /* Left DAC1 Digital Mute */
- ad1843_RDA2AM = { 12, 7, 1 }, /* Right DAC2 Digital Mute */
- ad1843_LDA2AM = { 12, 15, 1 }, /* Left DAC2 Digital Mute */
- ad1843_ADLC = { 15, 0, 2 }, /* ADC Left Sample Rate Source */
- ad1843_ADRC = { 15, 2, 2 }, /* ADC Right Sample Rate Source */
- ad1843_DA1C = { 15, 8, 2 }, /* DAC1 Sample Rate Source */
- ad1843_DA2C = { 15, 10, 2 }, /* DAC2 Sample Rate Source */
- ad1843_C1C = { 17, 0, 16 }, /* Clock 1 Sample Rate Select */
- ad1843_C2C = { 20, 0, 16 }, /* Clock 2 Sample Rate Select */
- ad1843_C3C = { 23, 0, 16 }, /* Clock 3 Sample Rate Select */
- ad1843_DAADL = { 25, 4, 2 }, /* Digital ADC Left Source Select */
- ad1843_DAADR = { 25, 6, 2 }, /* Digital ADC Right Source Select */
- ad1843_DAMIX = { 25, 14, 1 }, /* DAC Digital Mix Enable */
- ad1843_DRSFLT = { 25, 15, 1 }, /* Digital Reampler Filter Mode */
- ad1843_ADLF = { 26, 0, 2 }, /* ADC Left Channel Data Format */
- ad1843_ADRF = { 26, 2, 2 }, /* ADC Right Channel Data Format */
- ad1843_ADTLK = { 26, 4, 1 }, /* ADC Transmit Lock Mode Select */
- ad1843_SCF = { 26, 7, 1 }, /* SCLK Frequency Select */
- ad1843_DA1F = { 26, 8, 2 }, /* DAC1 Data Format Select */
- ad1843_DA2F = { 26, 10, 2 }, /* DAC2 Data Format Select */
- ad1843_DA1SM = { 26, 14, 1 }, /* DAC1 Stereo/Mono Mode Select */
- ad1843_DA2SM = { 26, 15, 1 }, /* DAC2 Stereo/Mono Mode Select */
- ad1843_ADLEN = { 27, 0, 1 }, /* ADC Left Channel Enable */
- ad1843_ADREN = { 27, 1, 1 }, /* ADC Right Channel Enable */
- ad1843_AAMEN = { 27, 4, 1 }, /* Analog to Analog Mix Enable */
- ad1843_ANAEN = { 27, 7, 1 }, /* Analog Channel Enable */
- ad1843_DA1EN = { 27, 8, 1 }, /* DAC1 Enable */
- ad1843_DA2EN = { 27, 9, 1 }, /* DAC2 Enable */
- ad1843_DDMEN = { 27, 12, 1 }, /* DAC2 to DAC1 Mix Enable */
- ad1843_C1EN = { 28, 11, 1 }, /* Clock Generator 1 Enable */
- ad1843_C2EN = { 28, 12, 1 }, /* Clock Generator 2 Enable */
- ad1843_C3EN = { 28, 13, 1 }, /* Clock Generator 3 Enable */
- ad1843_PDNI = { 28, 15, 1 }; /* Converter Power Down */
-
-/*
- * The various registers of the AD1843 use three different formats for
- * specifying gain. The ad1843_gain structure parameterizes the
- * formats.
- */
-
-struct ad1843_gain {
- int negative; /* nonzero if gain is negative. */
- const struct ad1843_bitfield *lfield;
- const struct ad1843_bitfield *rfield;
- const struct ad1843_bitfield *lmute;
- const struct ad1843_bitfield *rmute;
-};
-
-static const struct ad1843_gain ad1843_gain_RECLEV = {
- .negative = 0,
- .lfield = &ad1843_LIG,
- .rfield = &ad1843_RIG
-};
-static const struct ad1843_gain ad1843_gain_LINE = {
- .negative = 1,
- .lfield = &ad1843_LX1M,
- .rfield = &ad1843_RX1M,
- .lmute = &ad1843_LX1MM,
- .rmute = &ad1843_RX1MM
-};
-static const struct ad1843_gain ad1843_gain_LINE_2 = {
- .negative = 1,
- .lfield = &ad1843_LDA2G,
- .rfield = &ad1843_RDA2G,
- .lmute = &ad1843_LDA2GM,
- .rmute = &ad1843_RDA2GM
-};
-static const struct ad1843_gain ad1843_gain_MIC = {
- .negative = 1,
- .lfield = &ad1843_LMCM,
- .rfield = &ad1843_RMCM,
- .lmute = &ad1843_LMCMM,
- .rmute = &ad1843_RMCMM
-};
-static const struct ad1843_gain ad1843_gain_PCM_0 = {
- .negative = 1,
- .lfield = &ad1843_LDA1G,
- .rfield = &ad1843_RDA1G,
- .lmute = &ad1843_LDA1GM,
- .rmute = &ad1843_RDA1GM
-};
-static const struct ad1843_gain ad1843_gain_PCM_1 = {
- .negative = 1,
- .lfield = &ad1843_LD2M,
- .rfield = &ad1843_RD2M,
- .lmute = &ad1843_LD2MM,
- .rmute = &ad1843_RD2MM
-};
-
-static const struct ad1843_gain *ad1843_gain[AD1843_GAIN_SIZE] =
-{
- &ad1843_gain_RECLEV,
- &ad1843_gain_LINE,
- &ad1843_gain_LINE_2,
- &ad1843_gain_MIC,
- &ad1843_gain_PCM_0,
- &ad1843_gain_PCM_1,
-};
-
-/* read the current value of an AD1843 bitfield. */
-
-static int ad1843_read_bits(struct snd_ad1843 *ad1843,
- const struct ad1843_bitfield *field)
-{
- int w;
-
- w = ad1843->read(ad1843->chip, field->reg);
- return w >> field->lo_bit & ((1 << field->nbits) - 1);
-}
-
-/*
- * write a new value to an AD1843 bitfield and return the old value.
- */
-
-static int ad1843_write_bits(struct snd_ad1843 *ad1843,
- const struct ad1843_bitfield *field,
- int newval)
-{
- int w, mask, oldval, newbits;
-
- w = ad1843->read(ad1843->chip, field->reg);
- mask = ((1 << field->nbits) - 1) << field->lo_bit;
- oldval = (w & mask) >> field->lo_bit;
- newbits = (newval << field->lo_bit) & mask;
- w = (w & ~mask) | newbits;
- ad1843->write(ad1843->chip, field->reg, w);
-
- return oldval;
-}
-
-/*
- * ad1843_read_multi reads multiple bitfields from the same AD1843
- * register. It uses a single read cycle to do it. (Reading the
- * ad1843 requires 256 bit times at 12.288 MHz, or nearly 20
- * microseconds.)
- *
- * Called like this.
- *
- * ad1843_read_multi(ad1843, nfields,
- * &ad1843_FIELD1, &val1,
- * &ad1843_FIELD2, &val2, ...);
- */
-
-static void ad1843_read_multi(struct snd_ad1843 *ad1843, int argcount, ...)
-{
- va_list ap;
- const struct ad1843_bitfield *fp;
- int w = 0, mask, *value, reg = -1;
-
- va_start(ap, argcount);
- while (--argcount >= 0) {
- fp = va_arg(ap, const struct ad1843_bitfield *);
- value = va_arg(ap, int *);
- if (reg == -1) {
- reg = fp->reg;
- w = ad1843->read(ad1843->chip, reg);
- }
-
- mask = (1 << fp->nbits) - 1;
- *value = w >> fp->lo_bit & mask;
- }
- va_end(ap);
-}
-
-/*
- * ad1843_write_multi stores multiple bitfields into the same AD1843
- * register. It uses one read and one write cycle to do it.
- *
- * Called like this.
- *
- * ad1843_write_multi(ad1843, nfields,
- * &ad1843_FIELD1, val1,
- * &ad1843_FIELF2, val2, ...);
- */
-
-static void ad1843_write_multi(struct snd_ad1843 *ad1843, int argcount, ...)
-{
- va_list ap;
- int reg;
- const struct ad1843_bitfield *fp;
- int value;
- int w, m, mask, bits;
-
- mask = 0;
- bits = 0;
- reg = -1;
-
- va_start(ap, argcount);
- while (--argcount >= 0) {
- fp = va_arg(ap, const struct ad1843_bitfield *);
- value = va_arg(ap, int);
- if (reg == -1)
- reg = fp->reg;
- else
- BUG_ON(reg != fp->reg);
- m = ((1 << fp->nbits) - 1) << fp->lo_bit;
- mask |= m;
- bits |= (value << fp->lo_bit) & m;
- }
- va_end(ap);
-
- if (~mask & 0xFFFF)
- w = ad1843->read(ad1843->chip, reg);
- else
- w = 0;
- w = (w & ~mask) | bits;
- ad1843->write(ad1843->chip, reg, w);
-}
-
-int ad1843_get_gain_max(struct snd_ad1843 *ad1843, int id)
-{
- const struct ad1843_gain *gp = ad1843_gain[id];
- int ret;
-
- ret = (1 << gp->lfield->nbits);
- if (!gp->lmute)
- ret -= 1;
- return ret;
-}
-
-/*
- * ad1843_get_gain reads the specified register and extracts the gain value
- * using the supplied gain type.
- */
-
-int ad1843_get_gain(struct snd_ad1843 *ad1843, int id)
-{
- int lg, rg, lm, rm;
- const struct ad1843_gain *gp = ad1843_gain[id];
- unsigned short mask = (1 << gp->lfield->nbits) - 1;
-
- ad1843_read_multi(ad1843, 2, gp->lfield, &lg, gp->rfield, &rg);
- if (gp->negative) {
- lg = mask - lg;
- rg = mask - rg;
- }
- if (gp->lmute) {
- ad1843_read_multi(ad1843, 2, gp->lmute, &lm, gp->rmute, &rm);
- if (lm)
- lg = 0;
- if (rm)
- rg = 0;
- }
- return lg << 0 | rg << 8;
-}
-
-/*
- * Set an audio channel's gain.
- *
- * Returns the new gain, which may be lower than the old gain.
- */
-
-int ad1843_set_gain(struct snd_ad1843 *ad1843, int id, int newval)
-{
- const struct ad1843_gain *gp = ad1843_gain[id];
- unsigned short mask = (1 << gp->lfield->nbits) - 1;
-
- int lg = (newval >> 0) & mask;
- int rg = (newval >> 8) & mask;
- int lm = (lg == 0) ? 1 : 0;
- int rm = (rg == 0) ? 1 : 0;
-
- if (gp->negative) {
- lg = mask - lg;
- rg = mask - rg;
- }
- if (gp->lmute)
- ad1843_write_multi(ad1843, 2, gp->lmute, lm, gp->rmute, rm);
- ad1843_write_multi(ad1843, 2, gp->lfield, lg, gp->rfield, rg);
- return ad1843_get_gain(ad1843, id);
-}
-
-/* Returns the current recording source */
-
-int ad1843_get_recsrc(struct snd_ad1843 *ad1843)
-{
- int val = ad1843_read_bits(ad1843, &ad1843_LSS);
-
- if (val < 0 || val > 2) {
- val = 2;
- ad1843_write_multi(ad1843, 2,
- &ad1843_LSS, val, &ad1843_RSS, val);
- }
- return val;
-}
-
-/*
- * Set recording source.
- *
- * Returns newsrc on success, -errno on failure.
- */
-
-int ad1843_set_recsrc(struct snd_ad1843 *ad1843, int newsrc)
-{
- if (newsrc < 0 || newsrc > 2)
- return -EINVAL;
-
- ad1843_write_multi(ad1843, 2, &ad1843_LSS, newsrc, &ad1843_RSS, newsrc);
- return newsrc;
-}
-
-/* Setup ad1843 for D/A conversion. */
-
-void ad1843_setup_dac(struct snd_ad1843 *ad1843,
- unsigned int id,
- unsigned int framerate,
- snd_pcm_format_t fmt,
- unsigned int channels)
-{
- int ad_fmt = 0, ad_mode = 0;
-
- switch (fmt) {
- case SNDRV_PCM_FORMAT_S8:
- ad_fmt = 0;
- break;
- case SNDRV_PCM_FORMAT_U8:
- ad_fmt = 0;
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- ad_fmt = 1;
- break;
- case SNDRV_PCM_FORMAT_MU_LAW:
- ad_fmt = 2;
- break;
- case SNDRV_PCM_FORMAT_A_LAW:
- ad_fmt = 3;
- break;
- default:
- break;
- }
-
- switch (channels) {
- case 2:
- ad_mode = 0;
- break;
- case 1:
- ad_mode = 1;
- break;
- default:
- break;
- }
-
- if (id) {
- ad1843_write_bits(ad1843, &ad1843_C2C, framerate);
- ad1843_write_multi(ad1843, 2,
- &ad1843_DA2SM, ad_mode,
- &ad1843_DA2F, ad_fmt);
- } else {
- ad1843_write_bits(ad1843, &ad1843_C1C, framerate);
- ad1843_write_multi(ad1843, 2,
- &ad1843_DA1SM, ad_mode,
- &ad1843_DA1F, ad_fmt);
- }
-}
-
-void ad1843_shutdown_dac(struct snd_ad1843 *ad1843, unsigned int id)
-{
- if (id)
- ad1843_write_bits(ad1843, &ad1843_DA2F, 1);
- else
- ad1843_write_bits(ad1843, &ad1843_DA1F, 1);
-}
-
-void ad1843_setup_adc(struct snd_ad1843 *ad1843,
- unsigned int framerate,
- snd_pcm_format_t fmt,
- unsigned int channels)
-{
- int da_fmt = 0;
-
- switch (fmt) {
- case SNDRV_PCM_FORMAT_S8: da_fmt = 0; break;
- case SNDRV_PCM_FORMAT_U8: da_fmt = 0; break;
- case SNDRV_PCM_FORMAT_S16_LE: da_fmt = 1; break;
- case SNDRV_PCM_FORMAT_MU_LAW: da_fmt = 2; break;
- case SNDRV_PCM_FORMAT_A_LAW: da_fmt = 3; break;
- default: break;
- }
-
- ad1843_write_bits(ad1843, &ad1843_C3C, framerate);
- ad1843_write_multi(ad1843, 2,
- &ad1843_ADLF, da_fmt, &ad1843_ADRF, da_fmt);
-}
-
-void ad1843_shutdown_adc(struct snd_ad1843 *ad1843)
-{
- /* nothing to do */
-}
-
-/*
- * Fully initialize the ad1843. As described in the AD1843 data
- * sheet, section "START-UP SEQUENCE". The numbered comments are
- * subsection headings from the data sheet. See the data sheet, pages
- * 52-54, for more info.
- *
- * return 0 on success, -errno on failure. */
-
-int ad1843_init(struct snd_ad1843 *ad1843)
-{
- unsigned long later;
-
- if (ad1843_read_bits(ad1843, &ad1843_INIT) != 0) {
- printk(KERN_ERR "ad1843: AD1843 won't initialize\n");
- return -EIO;
- }
-
- ad1843_write_bits(ad1843, &ad1843_SCF, 1);
-
- /* 4. Put the conversion resources into standby. */
- ad1843_write_bits(ad1843, &ad1843_PDNI, 0);
- later = jiffies + msecs_to_jiffies(500);
-
- while (ad1843_read_bits(ad1843, &ad1843_PDNO)) {
- if (time_after(jiffies, later)) {
- printk(KERN_ERR
- "ad1843: AD1843 won't power up\n");
- return -EIO;
- }
- schedule_timeout_interruptible(5);
- }
-
- /* 5. Power up the clock generators and enable clock output pins. */
- ad1843_write_multi(ad1843, 3,
- &ad1843_C1EN, 1,
- &ad1843_C2EN, 1,
- &ad1843_C3EN, 1);
-
- /* 6. Configure conversion resources while they are in standby. */
-
- /* DAC1/2 use clock 1/2 as source, ADC uses clock 3. Always. */
- ad1843_write_multi(ad1843, 4,
- &ad1843_DA1C, 1,
- &ad1843_DA2C, 2,
- &ad1843_ADLC, 3,
- &ad1843_ADRC, 3);
-
- /* 7. Enable conversion resources. */
- ad1843_write_bits(ad1843, &ad1843_ADTLK, 1);
- ad1843_write_multi(ad1843, 7,
- &ad1843_ANAEN, 1,
- &ad1843_AAMEN, 1,
- &ad1843_DA1EN, 1,
- &ad1843_DA2EN, 1,
- &ad1843_DDMEN, 1,
- &ad1843_ADLEN, 1,
- &ad1843_ADREN, 1);
-
- /* 8. Configure conversion resources while they are enabled. */
-
- /* set gain to 0 for all channels */
- ad1843_set_gain(ad1843, AD1843_GAIN_RECLEV, 0);
- ad1843_set_gain(ad1843, AD1843_GAIN_LINE, 0);
- ad1843_set_gain(ad1843, AD1843_GAIN_LINE_2, 0);
- ad1843_set_gain(ad1843, AD1843_GAIN_MIC, 0);
- ad1843_set_gain(ad1843, AD1843_GAIN_PCM_0, 0);
- ad1843_set_gain(ad1843, AD1843_GAIN_PCM_1, 0);
-
- /* Unmute all channels. */
- /* DAC1 */
- ad1843_write_multi(ad1843, 2, &ad1843_LDA1GM, 0, &ad1843_RDA1GM, 0);
- /* DAC2 */
- ad1843_write_multi(ad1843, 2, &ad1843_LDA2GM, 0, &ad1843_RDA2GM, 0);
-
- /* Set default recording source to Line In and set
- * mic gain to +20 dB.
- */
- ad1843_set_recsrc(ad1843, 2);
- ad1843_write_multi(ad1843, 2, &ad1843_LMGE, 1, &ad1843_RMGE, 1);
-
- /* Set Speaker Out level to +/- 4V and unmute it. */
- ad1843_write_multi(ad1843, 3,
- &ad1843_HPOS, 1,
- &ad1843_HPOM, 0,
- &ad1843_MPOM, 0);
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/mips/au1x00.c b/ANDROID_3.4.5/sound/mips/au1x00.c
deleted file mode 100644
index 3f3ec0be..00000000
--- a/ANDROID_3.4.5/sound/mips/au1x00.c
+++ /dev/null
@@ -1,696 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- * Driver for AMD Au1000 MIPS Processor, AC'97 Sound Port
- *
- * Copyright 2004 Cooper Street Innovations Inc.
- * Author: Charles Eidsness <charles@cooper-street.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * History:
- *
- * 2004-09-09 Charles Eidsness -- Original verion -- based on
- * sa11xx-uda1341.c ALSA driver and the
- * au1000.c OSS driver.
- * 2004-09-09 Matt Porter -- Added support for ALSA 1.0.6
- *
- */
-
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/ac97_codec.h>
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-au1x00/au1000_dma.h>
-
-MODULE_AUTHOR("Charles Eidsness <charles@cooper-street.com>");
-MODULE_DESCRIPTION("Au1000 AC'97 ALSA Driver");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{AMD,Au1000 AC'97}}");
-
-#define PLAYBACK 0
-#define CAPTURE 1
-#define AC97_SLOT_3 0x01
-#define AC97_SLOT_4 0x02
-#define AC97_SLOT_6 0x08
-#define AC97_CMD_IRQ 31
-#define READ 0
-#define WRITE 1
-#define READ_WAIT 2
-#define RW_DONE 3
-
-struct au1000_period
-{
- u32 start;
- u32 relative_end; /*realtive to start of buffer*/
- struct au1000_period * next;
-};
-
-/*Au1000 AC97 Port Control Reisters*/
-struct au1000_ac97_reg {
- u32 volatile config;
- u32 volatile status;
- u32 volatile data;
- u32 volatile cmd;
- u32 volatile cntrl;
-};
-
-struct audio_stream {
- struct snd_pcm_substream *substream;
- int dma;
- spinlock_t dma_lock;
- struct au1000_period * buffer;
- unsigned int period_size;
- unsigned int periods;
-};
-
-struct snd_au1000 {
- struct snd_card *card;
- struct au1000_ac97_reg volatile *ac97_ioport;
-
- struct resource *ac97_res_port;
- spinlock_t ac97_lock;
- struct snd_ac97 *ac97;
-
- struct snd_pcm *pcm;
- struct audio_stream *stream[2]; /* playback & capture */
-};
-
-/*--------------------------- Local Functions --------------------------------*/
-static void
-au1000_set_ac97_xmit_slots(struct snd_au1000 *au1000, long xmit_slots)
-{
- u32 volatile ac97_config;
-
- spin_lock(&au1000->ac97_lock);
- ac97_config = au1000->ac97_ioport->config;
- ac97_config = ac97_config & ~AC97C_XMIT_SLOTS_MASK;
- ac97_config |= (xmit_slots << AC97C_XMIT_SLOTS_BIT);
- au1000->ac97_ioport->config = ac97_config;
- spin_unlock(&au1000->ac97_lock);
-}
-
-static void
-au1000_set_ac97_recv_slots(struct snd_au1000 *au1000, long recv_slots)
-{
- u32 volatile ac97_config;
-
- spin_lock(&au1000->ac97_lock);
- ac97_config = au1000->ac97_ioport->config;
- ac97_config = ac97_config & ~AC97C_RECV_SLOTS_MASK;
- ac97_config |= (recv_slots << AC97C_RECV_SLOTS_BIT);
- au1000->ac97_ioport->config = ac97_config;
- spin_unlock(&au1000->ac97_lock);
-}
-
-
-static void
-au1000_release_dma_link(struct audio_stream *stream)
-{
- struct au1000_period * pointer;
- struct au1000_period * pointer_next;
-
- stream->period_size = 0;
- stream->periods = 0;
- pointer = stream->buffer;
- if (! pointer)
- return;
- do {
- pointer_next = pointer->next;
- kfree(pointer);
- pointer = pointer_next;
- } while (pointer != stream->buffer);
- stream->buffer = NULL;
-}
-
-static int
-au1000_setup_dma_link(struct audio_stream *stream, unsigned int period_bytes,
- unsigned int periods)
-{
- struct snd_pcm_substream *substream = stream->substream;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct au1000_period *pointer;
- unsigned long dma_start;
- int i;
-
- dma_start = virt_to_phys(runtime->dma_area);
-
- if (stream->period_size == period_bytes &&
- stream->periods == periods)
- return 0; /* not changed */
-
- au1000_release_dma_link(stream);
-
- stream->period_size = period_bytes;
- stream->periods = periods;
-
- stream->buffer = kmalloc(sizeof(struct au1000_period), GFP_KERNEL);
- if (! stream->buffer)
- return -ENOMEM;
- pointer = stream->buffer;
- for (i = 0; i < periods; i++) {
- pointer->start = (u32)(dma_start + (i * period_bytes));
- pointer->relative_end = (u32) (((i+1) * period_bytes) - 0x1);
- if (i < periods - 1) {
- pointer->next = kmalloc(sizeof(struct au1000_period), GFP_KERNEL);
- if (! pointer->next) {
- au1000_release_dma_link(stream);
- return -ENOMEM;
- }
- pointer = pointer->next;
- }
- }
- pointer->next = stream->buffer;
- return 0;
-}
-
-static void
-au1000_dma_stop(struct audio_stream *stream)
-{
- if (snd_BUG_ON(!stream->buffer))
- return;
- disable_dma(stream->dma);
-}
-
-static void
-au1000_dma_start(struct audio_stream *stream)
-{
- if (snd_BUG_ON(!stream->buffer))
- return;
-
- init_dma(stream->dma);
- if (get_dma_active_buffer(stream->dma) == 0) {
- clear_dma_done0(stream->dma);
- set_dma_addr0(stream->dma, stream->buffer->start);
- set_dma_count0(stream->dma, stream->period_size >> 1);
- set_dma_addr1(stream->dma, stream->buffer->next->start);
- set_dma_count1(stream->dma, stream->period_size >> 1);
- } else {
- clear_dma_done1(stream->dma);
- set_dma_addr1(stream->dma, stream->buffer->start);
- set_dma_count1(stream->dma, stream->period_size >> 1);
- set_dma_addr0(stream->dma, stream->buffer->next->start);
- set_dma_count0(stream->dma, stream->period_size >> 1);
- }
- enable_dma_buffers(stream->dma);
- start_dma(stream->dma);
-}
-
-static irqreturn_t
-au1000_dma_interrupt(int irq, void *dev_id)
-{
- struct audio_stream *stream = (struct audio_stream *) dev_id;
- struct snd_pcm_substream *substream = stream->substream;
-
- spin_lock(&stream->dma_lock);
- switch (get_dma_buffer_done(stream->dma)) {
- case DMA_D0:
- stream->buffer = stream->buffer->next;
- clear_dma_done0(stream->dma);
- set_dma_addr0(stream->dma, stream->buffer->next->start);
- set_dma_count0(stream->dma, stream->period_size >> 1);
- enable_dma_buffer0(stream->dma);
- break;
- case DMA_D1:
- stream->buffer = stream->buffer->next;
- clear_dma_done1(stream->dma);
- set_dma_addr1(stream->dma, stream->buffer->next->start);
- set_dma_count1(stream->dma, stream->period_size >> 1);
- enable_dma_buffer1(stream->dma);
- break;
- case (DMA_D0 | DMA_D1):
- printk(KERN_ERR "DMA %d missed interrupt.\n",stream->dma);
- au1000_dma_stop(stream);
- au1000_dma_start(stream);
- break;
- case (~DMA_D0 & ~DMA_D1):
- printk(KERN_ERR "DMA %d empty irq.\n",stream->dma);
- }
- spin_unlock(&stream->dma_lock);
- snd_pcm_period_elapsed(substream);
- return IRQ_HANDLED;
-}
-
-/*-------------------------- PCM Audio Streams -------------------------------*/
-
-static unsigned int rates[] = {8000, 11025, 16000, 22050};
-static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
- .count = ARRAY_SIZE(rates),
- .list = rates,
- .mask = 0,
-};
-
-static struct snd_pcm_hardware snd_au1000_hw =
-{
- .info = (SNDRV_PCM_INFO_INTERLEAVED | \
- SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
- SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050),
- .rate_min = 8000,
- .rate_max = 22050,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 128*1024,
- .period_bytes_min = 32,
- .period_bytes_max = 16*1024,
- .periods_min = 8,
- .periods_max = 255,
- .fifo_size = 16,
-};
-
-static int
-snd_au1000_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_au1000 *au1000 = substream->pcm->private_data;
-
- au1000->stream[PLAYBACK]->substream = substream;
- au1000->stream[PLAYBACK]->buffer = NULL;
- substream->private_data = au1000->stream[PLAYBACK];
- substream->runtime->hw = snd_au1000_hw;
- return (snd_pcm_hw_constraint_list(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates) < 0);
-}
-
-static int
-snd_au1000_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_au1000 *au1000 = substream->pcm->private_data;
-
- au1000->stream[CAPTURE]->substream = substream;
- au1000->stream[CAPTURE]->buffer = NULL;
- substream->private_data = au1000->stream[CAPTURE];
- substream->runtime->hw = snd_au1000_hw;
- return (snd_pcm_hw_constraint_list(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates) < 0);
-}
-
-static int
-snd_au1000_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_au1000 *au1000 = substream->pcm->private_data;
-
- au1000->stream[PLAYBACK]->substream = NULL;
- return 0;
-}
-
-static int
-snd_au1000_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_au1000 *au1000 = substream->pcm->private_data;
-
- au1000->stream[CAPTURE]->substream = NULL;
- return 0;
-}
-
-static int
-snd_au1000_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct audio_stream *stream = substream->private_data;
- int err;
-
- err = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
- return au1000_setup_dma_link(stream,
- params_period_bytes(hw_params),
- params_periods(hw_params));
-}
-
-static int
-snd_au1000_hw_free(struct snd_pcm_substream *substream)
-{
- struct audio_stream *stream = substream->private_data;
- au1000_release_dma_link(stream);
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int
-snd_au1000_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_au1000 *au1000 = substream->pcm->private_data;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- if (runtime->channels == 1)
- au1000_set_ac97_xmit_slots(au1000, AC97_SLOT_4);
- else
- au1000_set_ac97_xmit_slots(au1000, AC97_SLOT_3 | AC97_SLOT_4);
- snd_ac97_set_rate(au1000->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate);
- return 0;
-}
-
-static int
-snd_au1000_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_au1000 *au1000 = substream->pcm->private_data;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- if (runtime->channels == 1)
- au1000_set_ac97_recv_slots(au1000, AC97_SLOT_4);
- else
- au1000_set_ac97_recv_slots(au1000, AC97_SLOT_3 | AC97_SLOT_4);
- snd_ac97_set_rate(au1000->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
- return 0;
-}
-
-static int
-snd_au1000_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct audio_stream *stream = substream->private_data;
- int err = 0;
-
- spin_lock(&stream->dma_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- au1000_dma_start(stream);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- au1000_dma_stop(stream);
- break;
- default:
- err = -EINVAL;
- break;
- }
- spin_unlock(&stream->dma_lock);
- return err;
-}
-
-static snd_pcm_uframes_t
-snd_au1000_pointer(struct snd_pcm_substream *substream)
-{
- struct audio_stream *stream = substream->private_data;
- struct snd_pcm_runtime *runtime = substream->runtime;
- long location;
-
- spin_lock(&stream->dma_lock);
- location = get_dma_residue(stream->dma);
- spin_unlock(&stream->dma_lock);
- location = stream->buffer->relative_end - location;
- if (location == -1)
- location = 0;
- return bytes_to_frames(runtime,location);
-}
-
-static struct snd_pcm_ops snd_card_au1000_playback_ops = {
- .open = snd_au1000_playback_open,
- .close = snd_au1000_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_au1000_hw_params,
- .hw_free = snd_au1000_hw_free,
- .prepare = snd_au1000_playback_prepare,
- .trigger = snd_au1000_trigger,
- .pointer = snd_au1000_pointer,
-};
-
-static struct snd_pcm_ops snd_card_au1000_capture_ops = {
- .open = snd_au1000_capture_open,
- .close = snd_au1000_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_au1000_hw_params,
- .hw_free = snd_au1000_hw_free,
- .prepare = snd_au1000_capture_prepare,
- .trigger = snd_au1000_trigger,
- .pointer = snd_au1000_pointer,
-};
-
-static int __devinit
-snd_au1000_pcm_new(struct snd_au1000 *au1000)
-{
- struct snd_pcm *pcm;
- int err;
- unsigned long flags;
-
- if ((err = snd_pcm_new(au1000->card, "AU1000 AC97 PCM", 0, 1, 1, &pcm)) < 0)
- return err;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL), 128*1024, 128*1024);
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_card_au1000_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_card_au1000_capture_ops);
-
- pcm->private_data = au1000;
- pcm->info_flags = 0;
- strcpy(pcm->name, "Au1000 AC97 PCM");
-
- spin_lock_init(&au1000->stream[PLAYBACK]->dma_lock);
- spin_lock_init(&au1000->stream[CAPTURE]->dma_lock);
-
- flags = claim_dma_lock();
- if ((au1000->stream[PLAYBACK]->dma = request_au1000_dma(DMA_ID_AC97C_TX,
- "AC97 TX", au1000_dma_interrupt, 0,
- au1000->stream[PLAYBACK])) < 0) {
- release_dma_lock(flags);
- return -EBUSY;
- }
- if ((au1000->stream[CAPTURE]->dma = request_au1000_dma(DMA_ID_AC97C_RX,
- "AC97 RX", au1000_dma_interrupt, 0,
- au1000->stream[CAPTURE])) < 0){
- release_dma_lock(flags);
- return -EBUSY;
- }
- /* enable DMA coherency in read/write DMA channels */
- set_dma_mode(au1000->stream[PLAYBACK]->dma,
- get_dma_mode(au1000->stream[PLAYBACK]->dma) & ~DMA_NC);
- set_dma_mode(au1000->stream[CAPTURE]->dma,
- get_dma_mode(au1000->stream[CAPTURE]->dma) & ~DMA_NC);
- release_dma_lock(flags);
- au1000->pcm = pcm;
- return 0;
-}
-
-
-/*-------------------------- AC97 CODEC Control ------------------------------*/
-
-static unsigned short
-snd_au1000_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
-{
- struct snd_au1000 *au1000 = ac97->private_data;
- u32 volatile cmd;
- u16 volatile data;
- int i;
-
- spin_lock(&au1000->ac97_lock);
-/* would rather use the interrupt than this polling but it works and I can't
-get the interrupt driven case to work efficiently */
- for (i = 0; i < 0x5000; i++)
- if (!(au1000->ac97_ioport->status & AC97C_CP))
- break;
- if (i == 0x5000)
- printk(KERN_ERR "au1000 AC97: AC97 command read timeout\n");
-
- cmd = (u32) reg & AC97C_INDEX_MASK;
- cmd |= AC97C_READ;
- au1000->ac97_ioport->cmd = cmd;
-
- /* now wait for the data */
- for (i = 0; i < 0x5000; i++)
- if (!(au1000->ac97_ioport->status & AC97C_CP))
- break;
- if (i == 0x5000) {
- printk(KERN_ERR "au1000 AC97: AC97 command read timeout\n");
- spin_unlock(&au1000->ac97_lock);
- return 0;
- }
-
- data = au1000->ac97_ioport->cmd & 0xffff;
- spin_unlock(&au1000->ac97_lock);
-
- return data;
-
-}
-
-
-static void
-snd_au1000_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
-{
- struct snd_au1000 *au1000 = ac97->private_data;
- u32 cmd;
- int i;
-
- spin_lock(&au1000->ac97_lock);
-/* would rather use the interrupt than this polling but it works and I can't
-get the interrupt driven case to work efficiently */
- for (i = 0; i < 0x5000; i++)
- if (!(au1000->ac97_ioport->status & AC97C_CP))
- break;
- if (i == 0x5000)
- printk(KERN_ERR "au1000 AC97: AC97 command write timeout\n");
-
- cmd = (u32) reg & AC97C_INDEX_MASK;
- cmd &= ~AC97C_READ;
- cmd |= ((u32) val << AC97C_WD_BIT);
- au1000->ac97_ioport->cmd = cmd;
- spin_unlock(&au1000->ac97_lock);
-}
-
-static int __devinit
-snd_au1000_ac97_new(struct snd_au1000 *au1000)
-{
- int err;
- struct snd_ac97_bus *pbus;
- struct snd_ac97_template ac97;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_au1000_ac97_write,
- .read = snd_au1000_ac97_read,
- };
-
- if ((au1000->ac97_res_port = request_mem_region(CPHYSADDR(AC97C_CONFIG),
- 0x100000, "Au1x00 AC97")) == NULL) {
- snd_printk(KERN_ERR "ALSA AC97: can't grap AC97 port\n");
- return -EBUSY;
- }
- au1000->ac97_ioport = (struct au1000_ac97_reg *)
- KSEG1ADDR(au1000->ac97_res_port->start);
-
- spin_lock_init(&au1000->ac97_lock);
-
- /* configure pins for AC'97
- TODO: move to board_setup.c */
- au_writel(au_readl(SYS_PINFUNC) & ~0x02, SYS_PINFUNC);
-
- /* Initialise Au1000's AC'97 Control Block */
- au1000->ac97_ioport->cntrl = AC97C_RS | AC97C_CE;
- udelay(10);
- au1000->ac97_ioport->cntrl = AC97C_CE;
- udelay(10);
-
- /* Initialise External CODEC -- cold reset */
- au1000->ac97_ioport->config = AC97C_RESET;
- udelay(10);
- au1000->ac97_ioport->config = 0x0;
- mdelay(5);
-
- /* Initialise AC97 middle-layer */
- if ((err = snd_ac97_bus(au1000->card, 0, &ops, au1000, &pbus)) < 0)
- return err;
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = au1000;
- if ((err = snd_ac97_mixer(pbus, &ac97, &au1000->ac97)) < 0)
- return err;
-
- return 0;
-}
-
-/*------------------------------ Setup / Destroy ----------------------------*/
-
-void
-snd_au1000_free(struct snd_card *card)
-{
- struct snd_au1000 *au1000 = card->private_data;
-
- if (au1000->ac97_res_port) {
- /* put internal AC97 block into reset */
- au1000->ac97_ioport->cntrl = AC97C_RS;
- au1000->ac97_ioport = NULL;
- release_and_free_resource(au1000->ac97_res_port);
- }
-
- if (au1000->stream[PLAYBACK]) {
- if (au1000->stream[PLAYBACK]->dma >= 0)
- free_au1000_dma(au1000->stream[PLAYBACK]->dma);
- kfree(au1000->stream[PLAYBACK]);
- }
-
- if (au1000->stream[CAPTURE]) {
- if (au1000->stream[CAPTURE]->dma >= 0)
- free_au1000_dma(au1000->stream[CAPTURE]->dma);
- kfree(au1000->stream[CAPTURE]);
- }
-}
-
-
-static struct snd_card *au1000_card;
-
-static int __init
-au1000_init(void)
-{
- int err;
- struct snd_card *card;
- struct snd_au1000 *au1000;
-
- err = snd_card_create(-1, "AC97", THIS_MODULE,
- sizeof(struct snd_au1000), &card);
- if (err < 0)
- return err;
-
- card->private_free = snd_au1000_free;
- au1000 = card->private_data;
- au1000->card = card;
-
- au1000->stream[PLAYBACK] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL);
- au1000->stream[CAPTURE ] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL);
- /* so that snd_au1000_free will work as intended */
- au1000->ac97_res_port = NULL;
- if (au1000->stream[PLAYBACK])
- au1000->stream[PLAYBACK]->dma = -1;
- if (au1000->stream[CAPTURE ])
- au1000->stream[CAPTURE ]->dma = -1;
-
- if (au1000->stream[PLAYBACK] == NULL ||
- au1000->stream[CAPTURE ] == NULL) {
- snd_card_free(card);
- return -ENOMEM;
- }
-
- if ((err = snd_au1000_ac97_new(au1000)) < 0 ) {
- snd_card_free(card);
- return err;
- }
-
- if ((err = snd_au1000_pcm_new(au1000)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- strcpy(card->driver, "Au1000-AC97");
- strcpy(card->shortname, "AMD Au1000-AC97");
- sprintf(card->longname, "AMD Au1000--AC97 ALSA Driver");
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- printk(KERN_INFO "ALSA AC97: Driver Initialized\n");
- au1000_card = card;
- return 0;
-}
-
-static void __exit au1000_exit(void)
-{
- snd_card_free(au1000_card);
-}
-
-module_init(au1000_init);
-module_exit(au1000_exit);
-
diff --git a/ANDROID_3.4.5/sound/mips/hal2.c b/ANDROID_3.4.5/sound/mips/hal2.c
deleted file mode 100644
index 5f88d1f0..00000000
--- a/ANDROID_3.4.5/sound/mips/hal2.c
+++ /dev/null
@@ -1,938 +0,0 @@
-/*
- * Driver for A2 audio system used in SGI machines
- * Copyright (c) 2008 Thomas Bogendoerfer <tsbogend@alpha.fanken.de>
- *
- * Based on OSS code from Ladislav Michl <ladis@linux-mips.org>, which
- * was based on code from Ulf Carlsson
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-#include <asm/sgi/hpc3.h>
-#include <asm/sgi/ip22.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/pcm-indirect.h>
-#include <sound/initval.h>
-
-#include "hal2.h"
-
-static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
-static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for SGI HAL2 soundcard.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for SGI HAL2 soundcard.");
-MODULE_DESCRIPTION("ALSA driver for SGI HAL2 audio");
-MODULE_AUTHOR("Thomas Bogendoerfer");
-MODULE_LICENSE("GPL");
-
-
-#define H2_BLOCK_SIZE 1024
-#define H2_BUF_SIZE 16384
-
-struct hal2_pbus {
- struct hpc3_pbus_dmacregs *pbus;
- int pbusnr;
- unsigned int ctrl; /* Current state of pbus->pbdma_ctrl */
-};
-
-struct hal2_desc {
- struct hpc_dma_desc desc;
- u32 pad; /* padding */
-};
-
-struct hal2_codec {
- struct snd_pcm_indirect pcm_indirect;
- struct snd_pcm_substream *substream;
-
- unsigned char *buffer;
- dma_addr_t buffer_dma;
- struct hal2_desc *desc;
- dma_addr_t desc_dma;
- int desc_count;
- struct hal2_pbus pbus;
- int voices; /* mono/stereo */
- unsigned int sample_rate;
- unsigned int master; /* Master frequency */
- unsigned short mod; /* MOD value */
- unsigned short inc; /* INC value */
-};
-
-#define H2_MIX_OUTPUT_ATT 0
-#define H2_MIX_INPUT_GAIN 1
-
-struct snd_hal2 {
- struct snd_card *card;
-
- struct hal2_ctl_regs *ctl_regs; /* HAL2 ctl registers */
- struct hal2_aes_regs *aes_regs; /* HAL2 aes registers */
- struct hal2_vol_regs *vol_regs; /* HAL2 vol registers */
- struct hal2_syn_regs *syn_regs; /* HAL2 syn registers */
-
- struct hal2_codec dac;
- struct hal2_codec adc;
-};
-
-#define H2_INDIRECT_WAIT(regs) while (hal2_read(&regs->isr) & H2_ISR_TSTATUS);
-
-#define H2_READ_ADDR(addr) (addr | (1<<7))
-#define H2_WRITE_ADDR(addr) (addr)
-
-static inline u32 hal2_read(u32 *reg)
-{
- return __raw_readl(reg);
-}
-
-static inline void hal2_write(u32 val, u32 *reg)
-{
- __raw_writel(val, reg);
-}
-
-
-static u32 hal2_i_read32(struct snd_hal2 *hal2, u16 addr)
-{
- u32 ret;
- struct hal2_ctl_regs *regs = hal2->ctl_regs;
-
- hal2_write(H2_READ_ADDR(addr), &regs->iar);
- H2_INDIRECT_WAIT(regs);
- ret = hal2_read(&regs->idr0) & 0xffff;
- hal2_write(H2_READ_ADDR(addr) | 0x1, &regs->iar);
- H2_INDIRECT_WAIT(regs);
- ret |= (hal2_read(&regs->idr0) & 0xffff) << 16;
- return ret;
-}
-
-static void hal2_i_write16(struct snd_hal2 *hal2, u16 addr, u16 val)
-{
- struct hal2_ctl_regs *regs = hal2->ctl_regs;
-
- hal2_write(val, &regs->idr0);
- hal2_write(0, &regs->idr1);
- hal2_write(0, &regs->idr2);
- hal2_write(0, &regs->idr3);
- hal2_write(H2_WRITE_ADDR(addr), &regs->iar);
- H2_INDIRECT_WAIT(regs);
-}
-
-static void hal2_i_write32(struct snd_hal2 *hal2, u16 addr, u32 val)
-{
- struct hal2_ctl_regs *regs = hal2->ctl_regs;
-
- hal2_write(val & 0xffff, &regs->idr0);
- hal2_write(val >> 16, &regs->idr1);
- hal2_write(0, &regs->idr2);
- hal2_write(0, &regs->idr3);
- hal2_write(H2_WRITE_ADDR(addr), &regs->iar);
- H2_INDIRECT_WAIT(regs);
-}
-
-static void hal2_i_setbit16(struct snd_hal2 *hal2, u16 addr, u16 bit)
-{
- struct hal2_ctl_regs *regs = hal2->ctl_regs;
-
- hal2_write(H2_READ_ADDR(addr), &regs->iar);
- H2_INDIRECT_WAIT(regs);
- hal2_write((hal2_read(&regs->idr0) & 0xffff) | bit, &regs->idr0);
- hal2_write(0, &regs->idr1);
- hal2_write(0, &regs->idr2);
- hal2_write(0, &regs->idr3);
- hal2_write(H2_WRITE_ADDR(addr), &regs->iar);
- H2_INDIRECT_WAIT(regs);
-}
-
-static void hal2_i_clearbit16(struct snd_hal2 *hal2, u16 addr, u16 bit)
-{
- struct hal2_ctl_regs *regs = hal2->ctl_regs;
-
- hal2_write(H2_READ_ADDR(addr), &regs->iar);
- H2_INDIRECT_WAIT(regs);
- hal2_write((hal2_read(&regs->idr0) & 0xffff) & ~bit, &regs->idr0);
- hal2_write(0, &regs->idr1);
- hal2_write(0, &regs->idr2);
- hal2_write(0, &regs->idr3);
- hal2_write(H2_WRITE_ADDR(addr), &regs->iar);
- H2_INDIRECT_WAIT(regs);
-}
-
-static int hal2_gain_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- switch ((int)kcontrol->private_value) {
- case H2_MIX_OUTPUT_ATT:
- uinfo->value.integer.max = 31;
- break;
- case H2_MIX_INPUT_GAIN:
- uinfo->value.integer.max = 15;
- break;
- }
- return 0;
-}
-
-static int hal2_gain_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_hal2 *hal2 = snd_kcontrol_chip(kcontrol);
- u32 tmp;
- int l, r;
-
- switch ((int)kcontrol->private_value) {
- case H2_MIX_OUTPUT_ATT:
- tmp = hal2_i_read32(hal2, H2I_DAC_C2);
- if (tmp & H2I_C2_MUTE) {
- l = 0;
- r = 0;
- } else {
- l = 31 - ((tmp >> H2I_C2_L_ATT_SHIFT) & 31);
- r = 31 - ((tmp >> H2I_C2_R_ATT_SHIFT) & 31);
- }
- break;
- case H2_MIX_INPUT_GAIN:
- tmp = hal2_i_read32(hal2, H2I_ADC_C2);
- l = (tmp >> H2I_C2_L_GAIN_SHIFT) & 15;
- r = (tmp >> H2I_C2_R_GAIN_SHIFT) & 15;
- break;
- }
- ucontrol->value.integer.value[0] = l;
- ucontrol->value.integer.value[1] = r;
-
- return 0;
-}
-
-static int hal2_gain_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_hal2 *hal2 = snd_kcontrol_chip(kcontrol);
- u32 old, new;
- int l, r;
-
- l = ucontrol->value.integer.value[0];
- r = ucontrol->value.integer.value[1];
-
- switch ((int)kcontrol->private_value) {
- case H2_MIX_OUTPUT_ATT:
- old = hal2_i_read32(hal2, H2I_DAC_C2);
- new = old & ~(H2I_C2_L_ATT_M | H2I_C2_R_ATT_M | H2I_C2_MUTE);
- if (l | r) {
- l = 31 - l;
- r = 31 - r;
- new |= (l << H2I_C2_L_ATT_SHIFT);
- new |= (r << H2I_C2_R_ATT_SHIFT);
- } else
- new |= H2I_C2_L_ATT_M | H2I_C2_R_ATT_M | H2I_C2_MUTE;
- hal2_i_write32(hal2, H2I_DAC_C2, new);
- break;
- case H2_MIX_INPUT_GAIN:
- old = hal2_i_read32(hal2, H2I_ADC_C2);
- new = old & ~(H2I_C2_L_GAIN_M | H2I_C2_R_GAIN_M);
- new |= (l << H2I_C2_L_GAIN_SHIFT);
- new |= (r << H2I_C2_R_GAIN_SHIFT);
- hal2_i_write32(hal2, H2I_ADC_C2, new);
- break;
- }
- return old != new;
-}
-
-static struct snd_kcontrol_new hal2_ctrl_headphone __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Headphone Playback Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = H2_MIX_OUTPUT_ATT,
- .info = hal2_gain_info,
- .get = hal2_gain_get,
- .put = hal2_gain_put,
-};
-
-static struct snd_kcontrol_new hal2_ctrl_mic __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Mic Capture Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = H2_MIX_INPUT_GAIN,
- .info = hal2_gain_info,
- .get = hal2_gain_get,
- .put = hal2_gain_put,
-};
-
-static int __devinit hal2_mixer_create(struct snd_hal2 *hal2)
-{
- int err;
-
- /* mute DAC */
- hal2_i_write32(hal2, H2I_DAC_C2,
- H2I_C2_L_ATT_M | H2I_C2_R_ATT_M | H2I_C2_MUTE);
- /* mute ADC */
- hal2_i_write32(hal2, H2I_ADC_C2, 0);
-
- err = snd_ctl_add(hal2->card,
- snd_ctl_new1(&hal2_ctrl_headphone, hal2));
- if (err < 0)
- return err;
-
- err = snd_ctl_add(hal2->card,
- snd_ctl_new1(&hal2_ctrl_mic, hal2));
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static irqreturn_t hal2_interrupt(int irq, void *dev_id)
-{
- struct snd_hal2 *hal2 = dev_id;
- irqreturn_t ret = IRQ_NONE;
-
- /* decide what caused this interrupt */
- if (hal2->dac.pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_INT) {
- snd_pcm_period_elapsed(hal2->dac.substream);
- ret = IRQ_HANDLED;
- }
- if (hal2->adc.pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_INT) {
- snd_pcm_period_elapsed(hal2->adc.substream);
- ret = IRQ_HANDLED;
- }
- return ret;
-}
-
-static int hal2_compute_rate(struct hal2_codec *codec, unsigned int rate)
-{
- unsigned short mod;
-
- if (44100 % rate < 48000 % rate) {
- mod = 4 * 44100 / rate;
- codec->master = 44100;
- } else {
- mod = 4 * 48000 / rate;
- codec->master = 48000;
- }
-
- codec->inc = 4;
- codec->mod = mod;
- rate = 4 * codec->master / mod;
-
- return rate;
-}
-
-static void hal2_set_dac_rate(struct snd_hal2 *hal2)
-{
- unsigned int master = hal2->dac.master;
- int inc = hal2->dac.inc;
- int mod = hal2->dac.mod;
-
- hal2_i_write16(hal2, H2I_BRES1_C1, (master == 44100) ? 1 : 0);
- hal2_i_write32(hal2, H2I_BRES1_C2,
- ((0xffff & (inc - mod - 1)) << 16) | inc);
-}
-
-static void hal2_set_adc_rate(struct snd_hal2 *hal2)
-{
- unsigned int master = hal2->adc.master;
- int inc = hal2->adc.inc;
- int mod = hal2->adc.mod;
-
- hal2_i_write16(hal2, H2I_BRES2_C1, (master == 44100) ? 1 : 0);
- hal2_i_write32(hal2, H2I_BRES2_C2,
- ((0xffff & (inc - mod - 1)) << 16) | inc);
-}
-
-static void hal2_setup_dac(struct snd_hal2 *hal2)
-{
- unsigned int fifobeg, fifoend, highwater, sample_size;
- struct hal2_pbus *pbus = &hal2->dac.pbus;
-
- /* Now we set up some PBUS information. The PBUS needs information about
- * what portion of the fifo it will use. If it's receiving or
- * transmitting, and finally whether the stream is little endian or big
- * endian. The information is written later, on the start call.
- */
- sample_size = 2 * hal2->dac.voices;
- /* Fifo should be set to hold exactly four samples. Highwater mark
- * should be set to two samples. */
- highwater = (sample_size * 2) >> 1; /* halfwords */
- fifobeg = 0; /* playback is first */
- fifoend = (sample_size * 4) >> 3; /* doublewords */
- pbus->ctrl = HPC3_PDMACTRL_RT | HPC3_PDMACTRL_LD |
- (highwater << 8) | (fifobeg << 16) | (fifoend << 24);
- /* We disable everything before we do anything at all */
- pbus->pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
- hal2_i_clearbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECTX);
- /* Setup the HAL2 for playback */
- hal2_set_dac_rate(hal2);
- /* Set endianess */
- hal2_i_clearbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECTX);
- /* Set DMA bus */
- hal2_i_setbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr));
- /* We are using 1st Bresenham clock generator for playback */
- hal2_i_write16(hal2, H2I_DAC_C1, (pbus->pbusnr << H2I_C1_DMA_SHIFT)
- | (1 << H2I_C1_CLKID_SHIFT)
- | (hal2->dac.voices << H2I_C1_DATAT_SHIFT));
-}
-
-static void hal2_setup_adc(struct snd_hal2 *hal2)
-{
- unsigned int fifobeg, fifoend, highwater, sample_size;
- struct hal2_pbus *pbus = &hal2->adc.pbus;
-
- sample_size = 2 * hal2->adc.voices;
- highwater = (sample_size * 2) >> 1; /* halfwords */
- fifobeg = (4 * 4) >> 3; /* record is second */
- fifoend = (4 * 4 + sample_size * 4) >> 3; /* doublewords */
- pbus->ctrl = HPC3_PDMACTRL_RT | HPC3_PDMACTRL_RCV | HPC3_PDMACTRL_LD |
- (highwater << 8) | (fifobeg << 16) | (fifoend << 24);
- pbus->pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
- hal2_i_clearbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECR);
- /* Setup the HAL2 for record */
- hal2_set_adc_rate(hal2);
- /* Set endianess */
- hal2_i_clearbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECR);
- /* Set DMA bus */
- hal2_i_setbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr));
- /* We are using 2nd Bresenham clock generator for record */
- hal2_i_write16(hal2, H2I_ADC_C1, (pbus->pbusnr << H2I_C1_DMA_SHIFT)
- | (2 << H2I_C1_CLKID_SHIFT)
- | (hal2->adc.voices << H2I_C1_DATAT_SHIFT));
-}
-
-static void hal2_start_dac(struct snd_hal2 *hal2)
-{
- struct hal2_pbus *pbus = &hal2->dac.pbus;
-
- pbus->pbus->pbdma_dptr = hal2->dac.desc_dma;
- pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT;
- /* enable DAC */
- hal2_i_setbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECTX);
-}
-
-static void hal2_start_adc(struct snd_hal2 *hal2)
-{
- struct hal2_pbus *pbus = &hal2->adc.pbus;
-
- pbus->pbus->pbdma_dptr = hal2->adc.desc_dma;
- pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT;
- /* enable ADC */
- hal2_i_setbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECR);
-}
-
-static inline void hal2_stop_dac(struct snd_hal2 *hal2)
-{
- hal2->dac.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
- /* The HAL2 itself may remain enabled safely */
-}
-
-static inline void hal2_stop_adc(struct snd_hal2 *hal2)
-{
- hal2->adc.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
-}
-
-static int hal2_alloc_dmabuf(struct hal2_codec *codec)
-{
- struct hal2_desc *desc;
- dma_addr_t desc_dma, buffer_dma;
- int count = H2_BUF_SIZE / H2_BLOCK_SIZE;
- int i;
-
- codec->buffer = dma_alloc_noncoherent(NULL, H2_BUF_SIZE,
- &buffer_dma, GFP_KERNEL);
- if (!codec->buffer)
- return -ENOMEM;
- desc = dma_alloc_noncoherent(NULL, count * sizeof(struct hal2_desc),
- &desc_dma, GFP_KERNEL);
- if (!desc) {
- dma_free_noncoherent(NULL, H2_BUF_SIZE,
- codec->buffer, buffer_dma);
- return -ENOMEM;
- }
- codec->buffer_dma = buffer_dma;
- codec->desc_dma = desc_dma;
- codec->desc = desc;
- for (i = 0; i < count; i++) {
- desc->desc.pbuf = buffer_dma + i * H2_BLOCK_SIZE;
- desc->desc.cntinfo = HPCDMA_XIE | H2_BLOCK_SIZE;
- desc->desc.pnext = (i == count - 1) ?
- desc_dma : desc_dma + (i + 1) * sizeof(struct hal2_desc);
- desc++;
- }
- dma_cache_sync(NULL, codec->desc, count * sizeof(struct hal2_desc),
- DMA_TO_DEVICE);
- codec->desc_count = count;
- return 0;
-}
-
-static void hal2_free_dmabuf(struct hal2_codec *codec)
-{
- dma_free_noncoherent(NULL, codec->desc_count * sizeof(struct hal2_desc),
- codec->desc, codec->desc_dma);
- dma_free_noncoherent(NULL, H2_BUF_SIZE, codec->buffer,
- codec->buffer_dma);
-}
-
-static struct snd_pcm_hardware hal2_pcm_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER),
- .formats = SNDRV_PCM_FMTBIT_S16_BE,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 65536,
- .period_bytes_min = 1024,
- .period_bytes_max = 65536,
- .periods_min = 2,
- .periods_max = 1024,
-};
-
-static int hal2_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- int err;
-
- err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static int hal2_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int hal2_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
- int err;
-
- runtime->hw = hal2_pcm_hw;
-
- err = hal2_alloc_dmabuf(&hal2->dac);
- if (err)
- return err;
- return 0;
-}
-
-static int hal2_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
-
- hal2_free_dmabuf(&hal2->dac);
- return 0;
-}
-
-static int hal2_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct hal2_codec *dac = &hal2->dac;
-
- dac->voices = runtime->channels;
- dac->sample_rate = hal2_compute_rate(dac, runtime->rate);
- memset(&dac->pcm_indirect, 0, sizeof(dac->pcm_indirect));
- dac->pcm_indirect.hw_buffer_size = H2_BUF_SIZE;
- dac->pcm_indirect.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
- dac->substream = substream;
- hal2_setup_dac(hal2);
- return 0;
-}
-
-static int hal2_playback_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- hal2->dac.pcm_indirect.hw_io = hal2->dac.buffer_dma;
- hal2->dac.pcm_indirect.hw_data = 0;
- substream->ops->ack(substream);
- hal2_start_dac(hal2);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- hal2_stop_dac(hal2);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static snd_pcm_uframes_t
-hal2_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
- struct hal2_codec *dac = &hal2->dac;
-
- return snd_pcm_indirect_playback_pointer(substream, &dac->pcm_indirect,
- dac->pbus.pbus->pbdma_bptr);
-}
-
-static void hal2_playback_transfer(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect *rec, size_t bytes)
-{
- struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
- unsigned char *buf = hal2->dac.buffer + rec->hw_data;
-
- memcpy(buf, substream->runtime->dma_area + rec->sw_data, bytes);
- dma_cache_sync(NULL, buf, bytes, DMA_TO_DEVICE);
-
-}
-
-static int hal2_playback_ack(struct snd_pcm_substream *substream)
-{
- struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
- struct hal2_codec *dac = &hal2->dac;
-
- dac->pcm_indirect.hw_queue_size = H2_BUF_SIZE / 2;
- snd_pcm_indirect_playback_transfer(substream,
- &dac->pcm_indirect,
- hal2_playback_transfer);
- return 0;
-}
-
-static int hal2_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
- struct hal2_codec *adc = &hal2->adc;
- int err;
-
- runtime->hw = hal2_pcm_hw;
-
- err = hal2_alloc_dmabuf(adc);
- if (err)
- return err;
- return 0;
-}
-
-static int hal2_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
-
- hal2_free_dmabuf(&hal2->adc);
- return 0;
-}
-
-static int hal2_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct hal2_codec *adc = &hal2->adc;
-
- adc->voices = runtime->channels;
- adc->sample_rate = hal2_compute_rate(adc, runtime->rate);
- memset(&adc->pcm_indirect, 0, sizeof(adc->pcm_indirect));
- adc->pcm_indirect.hw_buffer_size = H2_BUF_SIZE;
- adc->pcm_indirect.hw_queue_size = H2_BUF_SIZE / 2;
- adc->pcm_indirect.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
- adc->substream = substream;
- hal2_setup_adc(hal2);
- return 0;
-}
-
-static int hal2_capture_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- hal2->adc.pcm_indirect.hw_io = hal2->adc.buffer_dma;
- hal2->adc.pcm_indirect.hw_data = 0;
- printk(KERN_DEBUG "buffer_dma %x\n", hal2->adc.buffer_dma);
- hal2_start_adc(hal2);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- hal2_stop_adc(hal2);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static snd_pcm_uframes_t
-hal2_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
- struct hal2_codec *adc = &hal2->adc;
-
- return snd_pcm_indirect_capture_pointer(substream, &adc->pcm_indirect,
- adc->pbus.pbus->pbdma_bptr);
-}
-
-static void hal2_capture_transfer(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect *rec, size_t bytes)
-{
- struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
- unsigned char *buf = hal2->adc.buffer + rec->hw_data;
-
- dma_cache_sync(NULL, buf, bytes, DMA_FROM_DEVICE);
- memcpy(substream->runtime->dma_area + rec->sw_data, buf, bytes);
-}
-
-static int hal2_capture_ack(struct snd_pcm_substream *substream)
-{
- struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
- struct hal2_codec *adc = &hal2->adc;
-
- snd_pcm_indirect_capture_transfer(substream,
- &adc->pcm_indirect,
- hal2_capture_transfer);
- return 0;
-}
-
-static struct snd_pcm_ops hal2_playback_ops = {
- .open = hal2_playback_open,
- .close = hal2_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = hal2_pcm_hw_params,
- .hw_free = hal2_pcm_hw_free,
- .prepare = hal2_playback_prepare,
- .trigger = hal2_playback_trigger,
- .pointer = hal2_playback_pointer,
- .ack = hal2_playback_ack,
-};
-
-static struct snd_pcm_ops hal2_capture_ops = {
- .open = hal2_capture_open,
- .close = hal2_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = hal2_pcm_hw_params,
- .hw_free = hal2_pcm_hw_free,
- .prepare = hal2_capture_prepare,
- .trigger = hal2_capture_trigger,
- .pointer = hal2_capture_pointer,
- .ack = hal2_capture_ack,
-};
-
-static int __devinit hal2_pcm_create(struct snd_hal2 *hal2)
-{
- struct snd_pcm *pcm;
- int err;
-
- /* create first pcm device with one outputs and one input */
- err = snd_pcm_new(hal2->card, "SGI HAL2 Audio", 0, 1, 1, &pcm);
- if (err < 0)
- return err;
-
- pcm->private_data = hal2;
- strcpy(pcm->name, "SGI HAL2");
-
- /* set operators */
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &hal2_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &hal2_capture_ops);
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- 0, 1024 * 1024);
-
- return 0;
-}
-
-static int hal2_dev_free(struct snd_device *device)
-{
- struct snd_hal2 *hal2 = device->device_data;
-
- free_irq(SGI_HPCDMA_IRQ, hal2);
- kfree(hal2);
- return 0;
-}
-
-static struct snd_device_ops hal2_ops = {
- .dev_free = hal2_dev_free,
-};
-
-static void hal2_init_codec(struct hal2_codec *codec, struct hpc3_regs *hpc3,
- int index)
-{
- codec->pbus.pbusnr = index;
- codec->pbus.pbus = &hpc3->pbdma[index];
-}
-
-static int hal2_detect(struct snd_hal2 *hal2)
-{
- unsigned short board, major, minor;
- unsigned short rev;
-
- /* reset HAL2 */
- hal2_write(0, &hal2->ctl_regs->isr);
-
- /* release reset */
- hal2_write(H2_ISR_GLOBAL_RESET_N | H2_ISR_CODEC_RESET_N,
- &hal2->ctl_regs->isr);
-
-
- hal2_i_write16(hal2, H2I_RELAY_C, H2I_RELAY_C_STATE);
- rev = hal2_read(&hal2->ctl_regs->rev);
- if (rev & H2_REV_AUDIO_PRESENT)
- return -ENODEV;
-
- board = (rev & H2_REV_BOARD_M) >> 12;
- major = (rev & H2_REV_MAJOR_CHIP_M) >> 4;
- minor = (rev & H2_REV_MINOR_CHIP_M);
-
- printk(KERN_INFO "SGI HAL2 revision %i.%i.%i\n",
- board, major, minor);
-
- return 0;
-}
-
-static int hal2_create(struct snd_card *card, struct snd_hal2 **rchip)
-{
- struct snd_hal2 *hal2;
- struct hpc3_regs *hpc3 = hpc3c0;
- int err;
-
- hal2 = kzalloc(sizeof(struct snd_hal2), GFP_KERNEL);
- if (!hal2)
- return -ENOMEM;
-
- hal2->card = card;
-
- if (request_irq(SGI_HPCDMA_IRQ, hal2_interrupt, IRQF_SHARED,
- "SGI HAL2", hal2)) {
- printk(KERN_ERR "HAL2: Can't get irq %d\n", SGI_HPCDMA_IRQ);
- kfree(hal2);
- return -EAGAIN;
- }
-
- hal2->ctl_regs = (struct hal2_ctl_regs *)hpc3->pbus_extregs[0];
- hal2->aes_regs = (struct hal2_aes_regs *)hpc3->pbus_extregs[1];
- hal2->vol_regs = (struct hal2_vol_regs *)hpc3->pbus_extregs[2];
- hal2->syn_regs = (struct hal2_syn_regs *)hpc3->pbus_extregs[3];
-
- if (hal2_detect(hal2) < 0) {
- kfree(hal2);
- return -ENODEV;
- }
-
- hal2_init_codec(&hal2->dac, hpc3, 0);
- hal2_init_codec(&hal2->adc, hpc3, 1);
-
- /*
- * All DMA channel interfaces in HAL2 are designed to operate with
- * PBUS programmed for 2 cycles in D3, 2 cycles in D4 and 2 cycles
- * in D5. HAL2 is a 16-bit device which can accept both big and little
- * endian format. It assumes that even address bytes are on high
- * portion of PBUS (15:8) and assumes that HPC3 is programmed to
- * accept a live (unsynchronized) version of P_DREQ_N from HAL2.
- */
-#define HAL2_PBUS_DMACFG ((0 << HPC3_DMACFG_D3R_SHIFT) | \
- (2 << HPC3_DMACFG_D4R_SHIFT) | \
- (2 << HPC3_DMACFG_D5R_SHIFT) | \
- (0 << HPC3_DMACFG_D3W_SHIFT) | \
- (2 << HPC3_DMACFG_D4W_SHIFT) | \
- (2 << HPC3_DMACFG_D5W_SHIFT) | \
- HPC3_DMACFG_DS16 | \
- HPC3_DMACFG_EVENHI | \
- HPC3_DMACFG_RTIME | \
- (8 << HPC3_DMACFG_BURST_SHIFT) | \
- HPC3_DMACFG_DRQLIVE)
- /*
- * Ignore what's mentioned in the specification and write value which
- * works in The Real World (TM)
- */
- hpc3->pbus_dmacfg[hal2->dac.pbus.pbusnr][0] = 0x8208844;
- hpc3->pbus_dmacfg[hal2->adc.pbus.pbusnr][0] = 0x8208844;
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, hal2, &hal2_ops);
- if (err < 0) {
- free_irq(SGI_HPCDMA_IRQ, hal2);
- kfree(hal2);
- return err;
- }
- *rchip = hal2;
- return 0;
-}
-
-static int __devinit hal2_probe(struct platform_device *pdev)
-{
- struct snd_card *card;
- struct snd_hal2 *chip;
- int err;
-
- err = snd_card_create(index, id, THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- err = hal2_create(card, &chip);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- snd_card_set_dev(card, &pdev->dev);
-
- err = hal2_pcm_create(chip);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- err = hal2_mixer_create(chip);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- strcpy(card->driver, "SGI HAL2 Audio");
- strcpy(card->shortname, "SGI HAL2 Audio");
- sprintf(card->longname, "%s irq %i",
- card->shortname,
- SGI_HPCDMA_IRQ);
-
- err = snd_card_register(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- platform_set_drvdata(pdev, card);
- return 0;
-}
-
-static int __devexit hal2_remove(struct platform_device *pdev)
-{
- struct snd_card *card = platform_get_drvdata(pdev);
-
- snd_card_free(card);
- platform_set_drvdata(pdev, NULL);
- return 0;
-}
-
-static struct platform_driver hal2_driver = {
- .probe = hal2_probe,
- .remove = __devexit_p(hal2_remove),
- .driver = {
- .name = "sgihal2",
- .owner = THIS_MODULE,
- }
-};
-
-module_platform_driver(hal2_driver);
diff --git a/ANDROID_3.4.5/sound/mips/hal2.h b/ANDROID_3.4.5/sound/mips/hal2.h
deleted file mode 100644
index f19828bc..00000000
--- a/ANDROID_3.4.5/sound/mips/hal2.h
+++ /dev/null
@@ -1,245 +0,0 @@
-#ifndef __HAL2_H
-#define __HAL2_H
-
-/*
- * Driver for HAL2 sound processors
- * Copyright (c) 1999 Ulf Carlsson <ulfc@bun.falkenberg.se>
- * Copyright (c) 2001, 2002, 2003 Ladislav Michl <ladis@linux-mips.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/types.h>
-
-/* Indirect status register */
-
-#define H2_ISR_TSTATUS 0x01 /* RO: transaction status 1=busy */
-#define H2_ISR_USTATUS 0x02 /* RO: utime status bit 1=armed */
-#define H2_ISR_QUAD_MODE 0x04 /* codec mode 0=indigo 1=quad */
-#define H2_ISR_GLOBAL_RESET_N 0x08 /* chip global reset 0=reset */
-#define H2_ISR_CODEC_RESET_N 0x10 /* codec/synth reset 0=reset */
-
-/* Revision register */
-
-#define H2_REV_AUDIO_PRESENT 0x8000 /* RO: audio present 0=present */
-#define H2_REV_BOARD_M 0x7000 /* RO: bits 14:12, board revision */
-#define H2_REV_MAJOR_CHIP_M 0x00F0 /* RO: bits 7:4, major chip revision */
-#define H2_REV_MINOR_CHIP_M 0x000F /* RO: bits 3:0, minor chip revision */
-
-/* Indirect address register */
-
-/*
- * Address of indirect internal register to be accessed. A write to this
- * register initiates read or write access to the indirect registers in the
- * HAL2. Note that there af four indirect data registers for write access to
- * registers larger than 16 byte.
- */
-
-#define H2_IAR_TYPE_M 0xF000 /* bits 15:12, type of functional */
- /* block the register resides in */
- /* 1=DMA Port */
- /* 9=Global DMA Control */
- /* 2=Bresenham */
- /* 3=Unix Timer */
-#define H2_IAR_NUM_M 0x0F00 /* bits 11:8 instance of the */
- /* blockin which the indirect */
- /* register resides */
- /* If IAR_TYPE_M=DMA Port: */
- /* 1=Synth In */
- /* 2=AES In */
- /* 3=AES Out */
- /* 4=DAC Out */
- /* 5=ADC Out */
- /* 6=Synth Control */
- /* If IAR_TYPE_M=Global DMA Control: */
- /* 1=Control */
- /* If IAR_TYPE_M=Bresenham: */
- /* 1=Bresenham Clock Gen 1 */
- /* 2=Bresenham Clock Gen 2 */
- /* 3=Bresenham Clock Gen 3 */
- /* If IAR_TYPE_M=Unix Timer: */
- /* 1=Unix Timer */
-#define H2_IAR_ACCESS_SELECT 0x0080 /* 1=read 0=write */
-#define H2_IAR_PARAM 0x000C /* Parameter Select */
-#define H2_IAR_RB_INDEX_M 0x0003 /* Read Back Index */
- /* 00:word0 */
- /* 01:word1 */
- /* 10:word2 */
- /* 11:word3 */
-/*
- * HAL2 internal addressing
- *
- * The HAL2 has "indirect registers" (idr) which are accessed by writing to the
- * Indirect Data registers. Write the address to the Indirect Address register
- * to transfer the data.
- *
- * We define the H2IR_* to the read address and H2IW_* to the write address and
- * H2I_* to be fields in whatever register is referred to.
- *
- * When we write to indirect registers which are larger than one word (16 bit)
- * we have to fill more than one indirect register before writing. When we read
- * back however we have to read several times, each time with different Read
- * Back Indexes (there are defs for doing this easily).
- */
-
-/*
- * Relay Control
- */
-#define H2I_RELAY_C 0x9100
-#define H2I_RELAY_C_STATE 0x01 /* state of RELAY pin signal */
-
-/* DMA port enable */
-
-#define H2I_DMA_PORT_EN 0x9104
-#define H2I_DMA_PORT_EN_SY_IN 0x01 /* Synth_in DMA port */
-#define H2I_DMA_PORT_EN_AESRX 0x02 /* AES receiver DMA port */
-#define H2I_DMA_PORT_EN_AESTX 0x04 /* AES transmitter DMA port */
-#define H2I_DMA_PORT_EN_CODECTX 0x08 /* CODEC transmit DMA port */
-#define H2I_DMA_PORT_EN_CODECR 0x10 /* CODEC receive DMA port */
-
-#define H2I_DMA_END 0x9108 /* global dma endian select */
-#define H2I_DMA_END_SY_IN 0x01 /* Synth_in DMA port */
-#define H2I_DMA_END_AESRX 0x02 /* AES receiver DMA port */
-#define H2I_DMA_END_AESTX 0x04 /* AES transmitter DMA port */
-#define H2I_DMA_END_CODECTX 0x08 /* CODEC transmit DMA port */
-#define H2I_DMA_END_CODECR 0x10 /* CODEC receive DMA port */
- /* 0=b_end 1=l_end */
-
-#define H2I_DMA_DRV 0x910C /* global PBUS DMA enable */
-
-#define H2I_SYNTH_C 0x1104 /* Synth DMA control */
-
-#define H2I_AESRX_C 0x1204 /* AES RX dma control */
-
-#define H2I_C_TS_EN 0x20 /* Timestamp enable */
-#define H2I_C_TS_FRMT 0x40 /* Timestamp format */
-#define H2I_C_NAUDIO 0x80 /* Sign extend */
-
-/* AESRX CTL, 16 bit */
-
-#define H2I_AESTX_C 0x1304 /* AES TX DMA control */
-#define H2I_AESTX_C_CLKID_SHIFT 3 /* Bresenham Clock Gen 1-3 */
-#define H2I_AESTX_C_CLKID_M 0x18
-#define H2I_AESTX_C_DATAT_SHIFT 8 /* 1=mono 2=stereo (3=quad) */
-#define H2I_AESTX_C_DATAT_M 0x300
-
-/* CODEC registers */
-
-#define H2I_DAC_C1 0x1404 /* DAC DMA control, 16 bit */
-#define H2I_DAC_C2 0x1408 /* DAC DMA control, 32 bit */
-#define H2I_ADC_C1 0x1504 /* ADC DMA control, 16 bit */
-#define H2I_ADC_C2 0x1508 /* ADC DMA control, 32 bit */
-
-/* Bits in CTL1 register */
-
-#define H2I_C1_DMA_SHIFT 0 /* DMA channel */
-#define H2I_C1_DMA_M 0x7
-#define H2I_C1_CLKID_SHIFT 3 /* Bresenham Clock Gen 1-3 */
-#define H2I_C1_CLKID_M 0x18
-#define H2I_C1_DATAT_SHIFT 8 /* 1=mono 2=stereo (3=quad) */
-#define H2I_C1_DATAT_M 0x300
-
-/* Bits in CTL2 register */
-
-#define H2I_C2_R_GAIN_SHIFT 0 /* right a/d input gain */
-#define H2I_C2_R_GAIN_M 0xf
-#define H2I_C2_L_GAIN_SHIFT 4 /* left a/d input gain */
-#define H2I_C2_L_GAIN_M 0xf0
-#define H2I_C2_R_SEL 0x100 /* right input select */
-#define H2I_C2_L_SEL 0x200 /* left input select */
-#define H2I_C2_MUTE 0x400 /* mute */
-#define H2I_C2_DO1 0x00010000 /* digital output port bit 0 */
-#define H2I_C2_DO2 0x00020000 /* digital output port bit 1 */
-#define H2I_C2_R_ATT_SHIFT 18 /* right d/a output - */
-#define H2I_C2_R_ATT_M 0x007c0000 /* attenuation */
-#define H2I_C2_L_ATT_SHIFT 23 /* left d/a output - */
-#define H2I_C2_L_ATT_M 0x0f800000 /* attenuation */
-
-#define H2I_SYNTH_MAP_C 0x1104 /* synth dma handshake ctrl */
-
-/* Clock generator CTL 1, 16 bit */
-
-#define H2I_BRES1_C1 0x2104
-#define H2I_BRES2_C1 0x2204
-#define H2I_BRES3_C1 0x2304
-
-#define H2I_BRES_C1_SHIFT 0 /* 0=48.0 1=44.1 2=aes_rx */
-#define H2I_BRES_C1_M 0x03
-
-/* Clock generator CTL 2, 32 bit */
-
-#define H2I_BRES1_C2 0x2108
-#define H2I_BRES2_C2 0x2208
-#define H2I_BRES3_C2 0x2308
-
-#define H2I_BRES_C2_INC_SHIFT 0 /* increment value */
-#define H2I_BRES_C2_INC_M 0xffff
-#define H2I_BRES_C2_MOD_SHIFT 16 /* modcontrol value */
-#define H2I_BRES_C2_MOD_M 0xffff0000 /* modctrl=0xffff&(modinc-1) */
-
-/* Unix timer, 64 bit */
-
-#define H2I_UTIME 0x3104
-#define H2I_UTIME_0_LD 0xffff /* microseconds, LSB's */
-#define H2I_UTIME_1_LD0 0x0f /* microseconds, MSB's */
-#define H2I_UTIME_1_LD1 0xf0 /* tenths of microseconds */
-#define H2I_UTIME_2_LD 0xffff /* seconds, LSB's */
-#define H2I_UTIME_3_LD 0xffff /* seconds, MSB's */
-
-struct hal2_ctl_regs {
- u32 _unused0[4];
- u32 isr; /* 0x10 Status Register */
- u32 _unused1[3];
- u32 rev; /* 0x20 Revision Register */
- u32 _unused2[3];
- u32 iar; /* 0x30 Indirect Address Register */
- u32 _unused3[3];
- u32 idr0; /* 0x40 Indirect Data Register 0 */
- u32 _unused4[3];
- u32 idr1; /* 0x50 Indirect Data Register 1 */
- u32 _unused5[3];
- u32 idr2; /* 0x60 Indirect Data Register 2 */
- u32 _unused6[3];
- u32 idr3; /* 0x70 Indirect Data Register 3 */
-};
-
-struct hal2_aes_regs {
- u32 rx_stat[2]; /* Status registers */
- u32 rx_cr[2]; /* Control registers */
- u32 rx_ud[4]; /* User data window */
- u32 rx_st[24]; /* Channel status data */
-
- u32 tx_stat[1]; /* Status register */
- u32 tx_cr[3]; /* Control registers */
- u32 tx_ud[4]; /* User data window */
- u32 tx_st[24]; /* Channel status data */
-};
-
-struct hal2_vol_regs {
- u32 right; /* Right volume */
- u32 left; /* Left volume */
-};
-
-struct hal2_syn_regs {
- u32 _unused0[2];
- u32 page; /* DOC Page register */
- u32 regsel; /* DOC Register selection */
- u32 dlow; /* DOC Data low */
- u32 dhigh; /* DOC Data high */
- u32 irq; /* IRQ Status */
- u32 dram; /* DRAM Access */
-};
-
-#endif /* __HAL2_H */
diff --git a/ANDROID_3.4.5/sound/mips/sgio2audio.c b/ANDROID_3.4.5/sound/mips/sgio2audio.c
deleted file mode 100644
index ceaa593e..00000000
--- a/ANDROID_3.4.5/sound/mips/sgio2audio.c
+++ /dev/null
@@ -1,979 +0,0 @@
-/*
- * Sound driver for Silicon Graphics O2 Workstations A/V board audio.
- *
- * Copyright 2003 Vivien Chappelier <vivien.chappelier@linux-mips.org>
- * Copyright 2008 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
- * Mxier part taken from mace_audio.c:
- * Copyright 2007 Thorben Jändling <tj.trevelyan@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-#include <asm/ip32/ip32_ints.h>
-#include <asm/ip32/mace.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#define SNDRV_GET_ID
-#include <sound/initval.h>
-#include <sound/ad1843.h>
-
-
-MODULE_AUTHOR("Vivien Chappelier <vivien.chappelier@linux-mips.org>");
-MODULE_DESCRIPTION("SGI O2 Audio");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Silicon Graphics, O2 Audio}}");
-
-static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
-static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for SGI O2 soundcard.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for SGI O2 soundcard.");
-
-
-#define AUDIO_CONTROL_RESET BIT(0) /* 1: reset audio interface */
-#define AUDIO_CONTROL_CODEC_PRESENT BIT(1) /* 1: codec detected */
-
-#define CODEC_CONTROL_WORD_SHIFT 0
-#define CODEC_CONTROL_READ BIT(16)
-#define CODEC_CONTROL_ADDRESS_SHIFT 17
-
-#define CHANNEL_CONTROL_RESET BIT(10) /* 1: reset channel */
-#define CHANNEL_DMA_ENABLE BIT(9) /* 1: enable DMA transfer */
-#define CHANNEL_INT_THRESHOLD_DISABLED (0 << 5) /* interrupt disabled */
-#define CHANNEL_INT_THRESHOLD_25 (1 << 5) /* int on buffer >25% full */
-#define CHANNEL_INT_THRESHOLD_50 (2 << 5) /* int on buffer >50% full */
-#define CHANNEL_INT_THRESHOLD_75 (3 << 5) /* int on buffer >75% full */
-#define CHANNEL_INT_THRESHOLD_EMPTY (4 << 5) /* int on buffer empty */
-#define CHANNEL_INT_THRESHOLD_NOT_EMPTY (5 << 5) /* int on buffer !empty */
-#define CHANNEL_INT_THRESHOLD_FULL (6 << 5) /* int on buffer empty */
-#define CHANNEL_INT_THRESHOLD_NOT_FULL (7 << 5) /* int on buffer !empty */
-
-#define CHANNEL_RING_SHIFT 12
-#define CHANNEL_RING_SIZE (1 << CHANNEL_RING_SHIFT)
-#define CHANNEL_RING_MASK (CHANNEL_RING_SIZE - 1)
-
-#define CHANNEL_LEFT_SHIFT 40
-#define CHANNEL_RIGHT_SHIFT 8
-
-struct snd_sgio2audio_chan {
- int idx;
- struct snd_pcm_substream *substream;
- int pos;
- snd_pcm_uframes_t size;
- spinlock_t lock;
-};
-
-/* definition of the chip-specific record */
-struct snd_sgio2audio {
- struct snd_card *card;
-
- /* codec */
- struct snd_ad1843 ad1843;
- spinlock_t ad1843_lock;
-
- /* channels */
- struct snd_sgio2audio_chan channel[3];
-
- /* resources */
- void *ring_base;
- dma_addr_t ring_base_dma;
-};
-
-/* AD1843 access */
-
-/*
- * read_ad1843_reg returns the current contents of a 16 bit AD1843 register.
- *
- * Returns unsigned register value on success, -errno on failure.
- */
-static int read_ad1843_reg(void *priv, int reg)
-{
- struct snd_sgio2audio *chip = priv;
- int val;
- unsigned long flags;
-
- spin_lock_irqsave(&chip->ad1843_lock, flags);
-
- writeq((reg << CODEC_CONTROL_ADDRESS_SHIFT) |
- CODEC_CONTROL_READ, &mace->perif.audio.codec_control);
- wmb();
- val = readq(&mace->perif.audio.codec_control); /* flush bus */
- udelay(200);
-
- val = readq(&mace->perif.audio.codec_read);
-
- spin_unlock_irqrestore(&chip->ad1843_lock, flags);
- return val;
-}
-
-/*
- * write_ad1843_reg writes the specified value to a 16 bit AD1843 register.
- */
-static int write_ad1843_reg(void *priv, int reg, int word)
-{
- struct snd_sgio2audio *chip = priv;
- int val;
- unsigned long flags;
-
- spin_lock_irqsave(&chip->ad1843_lock, flags);
-
- writeq((reg << CODEC_CONTROL_ADDRESS_SHIFT) |
- (word << CODEC_CONTROL_WORD_SHIFT),
- &mace->perif.audio.codec_control);
- wmb();
- val = readq(&mace->perif.audio.codec_control); /* flush bus */
- udelay(200);
-
- spin_unlock_irqrestore(&chip->ad1843_lock, flags);
- return 0;
-}
-
-static int sgio2audio_gain_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = ad1843_get_gain_max(&chip->ad1843,
- (int)kcontrol->private_value);
- return 0;
-}
-
-static int sgio2audio_gain_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
- int vol;
-
- vol = ad1843_get_gain(&chip->ad1843, (int)kcontrol->private_value);
-
- ucontrol->value.integer.value[0] = (vol >> 8) & 0xFF;
- ucontrol->value.integer.value[1] = vol & 0xFF;
-
- return 0;
-}
-
-static int sgio2audio_gain_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
- int newvol, oldvol;
-
- oldvol = ad1843_get_gain(&chip->ad1843, kcontrol->private_value);
- newvol = (ucontrol->value.integer.value[0] << 8) |
- ucontrol->value.integer.value[1];
-
- newvol = ad1843_set_gain(&chip->ad1843, kcontrol->private_value,
- newvol);
-
- return newvol != oldvol;
-}
-
-static int sgio2audio_source_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static const char *texts[3] = {
- "Cam Mic", "Mic", "Line"
- };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item >= 3)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int sgio2audio_source_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = ad1843_get_recsrc(&chip->ad1843);
- return 0;
-}
-
-static int sgio2audio_source_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
- int newsrc, oldsrc;
-
- oldsrc = ad1843_get_recsrc(&chip->ad1843);
- newsrc = ad1843_set_recsrc(&chip->ad1843,
- ucontrol->value.enumerated.item[0]);
-
- return newsrc != oldsrc;
-}
-
-/* dac1/pcm0 mixer control */
-static struct snd_kcontrol_new sgio2audio_ctrl_pcm0 __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Playback Volume",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = AD1843_GAIN_PCM_0,
- .info = sgio2audio_gain_info,
- .get = sgio2audio_gain_get,
- .put = sgio2audio_gain_put,
-};
-
-/* dac2/pcm1 mixer control */
-static struct snd_kcontrol_new sgio2audio_ctrl_pcm1 __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Playback Volume",
- .index = 1,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = AD1843_GAIN_PCM_1,
- .info = sgio2audio_gain_info,
- .get = sgio2audio_gain_get,
- .put = sgio2audio_gain_put,
-};
-
-/* record level mixer control */
-static struct snd_kcontrol_new sgio2audio_ctrl_reclevel __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = AD1843_GAIN_RECLEV,
- .info = sgio2audio_gain_info,
- .get = sgio2audio_gain_get,
- .put = sgio2audio_gain_put,
-};
-
-/* record level source control */
-static struct snd_kcontrol_new sgio2audio_ctrl_recsource __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = sgio2audio_source_info,
- .get = sgio2audio_source_get,
- .put = sgio2audio_source_put,
-};
-
-/* line mixer control */
-static struct snd_kcontrol_new sgio2audio_ctrl_line __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Line Playback Volume",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = AD1843_GAIN_LINE,
- .info = sgio2audio_gain_info,
- .get = sgio2audio_gain_get,
- .put = sgio2audio_gain_put,
-};
-
-/* cd mixer control */
-static struct snd_kcontrol_new sgio2audio_ctrl_cd __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Line Playback Volume",
- .index = 1,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = AD1843_GAIN_LINE_2,
- .info = sgio2audio_gain_info,
- .get = sgio2audio_gain_get,
- .put = sgio2audio_gain_put,
-};
-
-/* mic mixer control */
-static struct snd_kcontrol_new sgio2audio_ctrl_mic __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Mic Playback Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = AD1843_GAIN_MIC,
- .info = sgio2audio_gain_info,
- .get = sgio2audio_gain_get,
- .put = sgio2audio_gain_put,
-};
-
-
-static int __devinit snd_sgio2audio_new_mixer(struct snd_sgio2audio *chip)
-{
- int err;
-
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&sgio2audio_ctrl_pcm0, chip));
- if (err < 0)
- return err;
-
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&sgio2audio_ctrl_pcm1, chip));
- if (err < 0)
- return err;
-
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&sgio2audio_ctrl_reclevel, chip));
- if (err < 0)
- return err;
-
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&sgio2audio_ctrl_recsource, chip));
- if (err < 0)
- return err;
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&sgio2audio_ctrl_line, chip));
- if (err < 0)
- return err;
-
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&sgio2audio_ctrl_cd, chip));
- if (err < 0)
- return err;
-
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&sgio2audio_ctrl_mic, chip));
- if (err < 0)
- return err;
-
- return 0;
-}
-
-/* low-level audio interface DMA */
-
-/* get data out of bounce buffer, count must be a multiple of 32 */
-/* returns 1 if a period has elapsed */
-static int snd_sgio2audio_dma_pull_frag(struct snd_sgio2audio *chip,
- unsigned int ch, unsigned int count)
-{
- int ret;
- unsigned long src_base, src_pos, dst_mask;
- unsigned char *dst_base;
- int dst_pos;
- u64 *src;
- s16 *dst;
- u64 x;
- unsigned long flags;
- struct snd_pcm_runtime *runtime = chip->channel[ch].substream->runtime;
-
- spin_lock_irqsave(&chip->channel[ch].lock, flags);
-
- src_base = (unsigned long) chip->ring_base | (ch << CHANNEL_RING_SHIFT);
- src_pos = readq(&mace->perif.audio.chan[ch].read_ptr);
- dst_base = runtime->dma_area;
- dst_pos = chip->channel[ch].pos;
- dst_mask = frames_to_bytes(runtime, runtime->buffer_size) - 1;
-
- /* check if a period has elapsed */
- chip->channel[ch].size += (count >> 3); /* in frames */
- ret = chip->channel[ch].size >= runtime->period_size;
- chip->channel[ch].size %= runtime->period_size;
-
- while (count) {
- src = (u64 *)(src_base + src_pos);
- dst = (s16 *)(dst_base + dst_pos);
-
- x = *src;
- dst[0] = (x >> CHANNEL_LEFT_SHIFT) & 0xffff;
- dst[1] = (x >> CHANNEL_RIGHT_SHIFT) & 0xffff;
-
- src_pos = (src_pos + sizeof(u64)) & CHANNEL_RING_MASK;
- dst_pos = (dst_pos + 2 * sizeof(s16)) & dst_mask;
- count -= sizeof(u64);
- }
-
- writeq(src_pos, &mace->perif.audio.chan[ch].read_ptr); /* in bytes */
- chip->channel[ch].pos = dst_pos;
-
- spin_unlock_irqrestore(&chip->channel[ch].lock, flags);
- return ret;
-}
-
-/* put some DMA data in bounce buffer, count must be a multiple of 32 */
-/* returns 1 if a period has elapsed */
-static int snd_sgio2audio_dma_push_frag(struct snd_sgio2audio *chip,
- unsigned int ch, unsigned int count)
-{
- int ret;
- s64 l, r;
- unsigned long dst_base, dst_pos, src_mask;
- unsigned char *src_base;
- int src_pos;
- u64 *dst;
- s16 *src;
- unsigned long flags;
- struct snd_pcm_runtime *runtime = chip->channel[ch].substream->runtime;
-
- spin_lock_irqsave(&chip->channel[ch].lock, flags);
-
- dst_base = (unsigned long)chip->ring_base | (ch << CHANNEL_RING_SHIFT);
- dst_pos = readq(&mace->perif.audio.chan[ch].write_ptr);
- src_base = runtime->dma_area;
- src_pos = chip->channel[ch].pos;
- src_mask = frames_to_bytes(runtime, runtime->buffer_size) - 1;
-
- /* check if a period has elapsed */
- chip->channel[ch].size += (count >> 3); /* in frames */
- ret = chip->channel[ch].size >= runtime->period_size;
- chip->channel[ch].size %= runtime->period_size;
-
- while (count) {
- src = (s16 *)(src_base + src_pos);
- dst = (u64 *)(dst_base + dst_pos);
-
- l = src[0]; /* sign extend */
- r = src[1]; /* sign extend */
-
- *dst = ((l & 0x00ffffff) << CHANNEL_LEFT_SHIFT) |
- ((r & 0x00ffffff) << CHANNEL_RIGHT_SHIFT);
-
- dst_pos = (dst_pos + sizeof(u64)) & CHANNEL_RING_MASK;
- src_pos = (src_pos + 2 * sizeof(s16)) & src_mask;
- count -= sizeof(u64);
- }
-
- writeq(dst_pos, &mace->perif.audio.chan[ch].write_ptr); /* in bytes */
- chip->channel[ch].pos = src_pos;
-
- spin_unlock_irqrestore(&chip->channel[ch].lock, flags);
- return ret;
-}
-
-static int snd_sgio2audio_dma_start(struct snd_pcm_substream *substream)
-{
- struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
- struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
- int ch = chan->idx;
-
- /* reset DMA channel */
- writeq(CHANNEL_CONTROL_RESET, &mace->perif.audio.chan[ch].control);
- udelay(10);
- writeq(0, &mace->perif.audio.chan[ch].control);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- /* push a full buffer */
- snd_sgio2audio_dma_push_frag(chip, ch, CHANNEL_RING_SIZE - 32);
- }
- /* set DMA to wake on 50% empty and enable interrupt */
- writeq(CHANNEL_DMA_ENABLE | CHANNEL_INT_THRESHOLD_50,
- &mace->perif.audio.chan[ch].control);
- return 0;
-}
-
-static int snd_sgio2audio_dma_stop(struct snd_pcm_substream *substream)
-{
- struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
-
- writeq(0, &mace->perif.audio.chan[chan->idx].control);
- return 0;
-}
-
-static irqreturn_t snd_sgio2audio_dma_in_isr(int irq, void *dev_id)
-{
- struct snd_sgio2audio_chan *chan = dev_id;
- struct snd_pcm_substream *substream;
- struct snd_sgio2audio *chip;
- int count, ch;
-
- substream = chan->substream;
- chip = snd_pcm_substream_chip(substream);
- ch = chan->idx;
-
- /* empty the ring */
- count = CHANNEL_RING_SIZE -
- readq(&mace->perif.audio.chan[ch].depth) - 32;
- if (snd_sgio2audio_dma_pull_frag(chip, ch, count))
- snd_pcm_period_elapsed(substream);
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t snd_sgio2audio_dma_out_isr(int irq, void *dev_id)
-{
- struct snd_sgio2audio_chan *chan = dev_id;
- struct snd_pcm_substream *substream;
- struct snd_sgio2audio *chip;
- int count, ch;
-
- substream = chan->substream;
- chip = snd_pcm_substream_chip(substream);
- ch = chan->idx;
- /* fill the ring */
- count = CHANNEL_RING_SIZE -
- readq(&mace->perif.audio.chan[ch].depth) - 32;
- if (snd_sgio2audio_dma_push_frag(chip, ch, count))
- snd_pcm_period_elapsed(substream);
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t snd_sgio2audio_error_isr(int irq, void *dev_id)
-{
- struct snd_sgio2audio_chan *chan = dev_id;
- struct snd_pcm_substream *substream;
-
- substream = chan->substream;
- snd_sgio2audio_dma_stop(substream);
- snd_sgio2audio_dma_start(substream);
- return IRQ_HANDLED;
-}
-
-/* PCM part */
-/* PCM hardware definition */
-static struct snd_pcm_hardware snd_sgio2audio_pcm_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER),
- .formats = SNDRV_PCM_FMTBIT_S16_BE,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 65536,
- .period_bytes_min = 32768,
- .period_bytes_max = 65536,
- .periods_min = 1,
- .periods_max = 1024,
-};
-
-/* PCM playback open callback */
-static int snd_sgio2audio_playback1_open(struct snd_pcm_substream *substream)
-{
- struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- runtime->hw = snd_sgio2audio_pcm_hw;
- runtime->private_data = &chip->channel[1];
- return 0;
-}
-
-static int snd_sgio2audio_playback2_open(struct snd_pcm_substream *substream)
-{
- struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- runtime->hw = snd_sgio2audio_pcm_hw;
- runtime->private_data = &chip->channel[2];
- return 0;
-}
-
-/* PCM capture open callback */
-static int snd_sgio2audio_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- runtime->hw = snd_sgio2audio_pcm_hw;
- runtime->private_data = &chip->channel[0];
- return 0;
-}
-
-/* PCM close callback */
-static int snd_sgio2audio_pcm_close(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- runtime->private_data = NULL;
- return 0;
-}
-
-
-/* hw_params callback */
-static int snd_sgio2audio_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_alloc_vmalloc_buffer(substream,
- params_buffer_bytes(hw_params));
-}
-
-/* hw_free callback */
-static int snd_sgio2audio_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_vmalloc_buffer(substream);
-}
-
-/* prepare callback */
-static int snd_sgio2audio_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
- int ch = chan->idx;
- unsigned long flags;
-
- spin_lock_irqsave(&chip->channel[ch].lock, flags);
-
- /* Setup the pseudo-dma transfer pointers. */
- chip->channel[ch].pos = 0;
- chip->channel[ch].size = 0;
- chip->channel[ch].substream = substream;
-
- /* set AD1843 format */
- /* hardware format is always S16_LE */
- switch (substream->stream) {
- case SNDRV_PCM_STREAM_PLAYBACK:
- ad1843_setup_dac(&chip->ad1843,
- ch - 1,
- runtime->rate,
- SNDRV_PCM_FORMAT_S16_LE,
- runtime->channels);
- break;
- case SNDRV_PCM_STREAM_CAPTURE:
- ad1843_setup_adc(&chip->ad1843,
- runtime->rate,
- SNDRV_PCM_FORMAT_S16_LE,
- runtime->channels);
- break;
- }
- spin_unlock_irqrestore(&chip->channel[ch].lock, flags);
- return 0;
-}
-
-/* trigger callback */
-static int snd_sgio2audio_pcm_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- /* start the PCM engine */
- snd_sgio2audio_dma_start(substream);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- /* stop the PCM engine */
- snd_sgio2audio_dma_stop(substream);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-/* pointer callback */
-static snd_pcm_uframes_t
-snd_sgio2audio_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
- struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
-
- /* get the current hardware pointer */
- return bytes_to_frames(substream->runtime,
- chip->channel[chan->idx].pos);
-}
-
-/* operators */
-static struct snd_pcm_ops snd_sgio2audio_playback1_ops = {
- .open = snd_sgio2audio_playback1_open,
- .close = snd_sgio2audio_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_sgio2audio_pcm_hw_params,
- .hw_free = snd_sgio2audio_pcm_hw_free,
- .prepare = snd_sgio2audio_pcm_prepare,
- .trigger = snd_sgio2audio_pcm_trigger,
- .pointer = snd_sgio2audio_pcm_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
-};
-
-static struct snd_pcm_ops snd_sgio2audio_playback2_ops = {
- .open = snd_sgio2audio_playback2_open,
- .close = snd_sgio2audio_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_sgio2audio_pcm_hw_params,
- .hw_free = snd_sgio2audio_pcm_hw_free,
- .prepare = snd_sgio2audio_pcm_prepare,
- .trigger = snd_sgio2audio_pcm_trigger,
- .pointer = snd_sgio2audio_pcm_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
-};
-
-static struct snd_pcm_ops snd_sgio2audio_capture_ops = {
- .open = snd_sgio2audio_capture_open,
- .close = snd_sgio2audio_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_sgio2audio_pcm_hw_params,
- .hw_free = snd_sgio2audio_pcm_hw_free,
- .prepare = snd_sgio2audio_pcm_prepare,
- .trigger = snd_sgio2audio_pcm_trigger,
- .pointer = snd_sgio2audio_pcm_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
-};
-
-/*
- * definitions of capture are omitted here...
- */
-
-/* create a pcm device */
-static int __devinit snd_sgio2audio_new_pcm(struct snd_sgio2audio *chip)
-{
- struct snd_pcm *pcm;
- int err;
-
- /* create first pcm device with one outputs and one input */
- err = snd_pcm_new(chip->card, "SGI O2 Audio", 0, 1, 1, &pcm);
- if (err < 0)
- return err;
-
- pcm->private_data = chip;
- strcpy(pcm->name, "SGI O2 DAC1");
-
- /* set operators */
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_sgio2audio_playback1_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_sgio2audio_capture_ops);
-
- /* create second pcm device with one outputs and no input */
- err = snd_pcm_new(chip->card, "SGI O2 Audio", 1, 1, 0, &pcm);
- if (err < 0)
- return err;
-
- pcm->private_data = chip;
- strcpy(pcm->name, "SGI O2 DAC2");
-
- /* set operators */
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_sgio2audio_playback2_ops);
-
- return 0;
-}
-
-static struct {
- int idx;
- int irq;
- irqreturn_t (*isr)(int, void *);
- const char *desc;
-} snd_sgio2_isr_table[] = {
- {
- .idx = 0,
- .irq = MACEISA_AUDIO1_DMAT_IRQ,
- .isr = snd_sgio2audio_dma_in_isr,
- .desc = "Capture DMA Channel 0"
- }, {
- .idx = 0,
- .irq = MACEISA_AUDIO1_OF_IRQ,
- .isr = snd_sgio2audio_error_isr,
- .desc = "Capture Overflow"
- }, {
- .idx = 1,
- .irq = MACEISA_AUDIO2_DMAT_IRQ,
- .isr = snd_sgio2audio_dma_out_isr,
- .desc = "Playback DMA Channel 1"
- }, {
- .idx = 1,
- .irq = MACEISA_AUDIO2_MERR_IRQ,
- .isr = snd_sgio2audio_error_isr,
- .desc = "Memory Error Channel 1"
- }, {
- .idx = 2,
- .irq = MACEISA_AUDIO3_DMAT_IRQ,
- .isr = snd_sgio2audio_dma_out_isr,
- .desc = "Playback DMA Channel 2"
- }, {
- .idx = 2,
- .irq = MACEISA_AUDIO3_MERR_IRQ,
- .isr = snd_sgio2audio_error_isr,
- .desc = "Memory Error Channel 2"
- }
-};
-
-/* ALSA driver */
-
-static int snd_sgio2audio_free(struct snd_sgio2audio *chip)
-{
- int i;
-
- /* reset interface */
- writeq(AUDIO_CONTROL_RESET, &mace->perif.audio.control);
- udelay(1);
- writeq(0, &mace->perif.audio.control);
-
- /* release IRQ's */
- for (i = 0; i < ARRAY_SIZE(snd_sgio2_isr_table); i++)
- free_irq(snd_sgio2_isr_table[i].irq,
- &chip->channel[snd_sgio2_isr_table[i].idx]);
-
- dma_free_coherent(NULL, MACEISA_RINGBUFFERS_SIZE,
- chip->ring_base, chip->ring_base_dma);
-
- /* release card data */
- kfree(chip);
- return 0;
-}
-
-static int snd_sgio2audio_dev_free(struct snd_device *device)
-{
- struct snd_sgio2audio *chip = device->device_data;
-
- return snd_sgio2audio_free(chip);
-}
-
-static struct snd_device_ops ops = {
- .dev_free = snd_sgio2audio_dev_free,
-};
-
-static int __devinit snd_sgio2audio_create(struct snd_card *card,
- struct snd_sgio2audio **rchip)
-{
- struct snd_sgio2audio *chip;
- int i, err;
-
- *rchip = NULL;
-
- /* check if a codec is attached to the interface */
- /* (Audio or Audio/Video board present) */
- if (!(readq(&mace->perif.audio.control) & AUDIO_CONTROL_CODEC_PRESENT))
- return -ENOENT;
-
- chip = kzalloc(sizeof(struct snd_sgio2audio), GFP_KERNEL);
- if (chip == NULL)
- return -ENOMEM;
-
- chip->card = card;
-
- chip->ring_base = dma_alloc_coherent(NULL, MACEISA_RINGBUFFERS_SIZE,
- &chip->ring_base_dma, GFP_USER);
- if (chip->ring_base == NULL) {
- printk(KERN_ERR
- "sgio2audio: could not allocate ring buffers\n");
- kfree(chip);
- return -ENOMEM;
- }
-
- spin_lock_init(&chip->ad1843_lock);
-
- /* initialize channels */
- for (i = 0; i < 3; i++) {
- spin_lock_init(&chip->channel[i].lock);
- chip->channel[i].idx = i;
- }
-
- /* allocate IRQs */
- for (i = 0; i < ARRAY_SIZE(snd_sgio2_isr_table); i++) {
- if (request_irq(snd_sgio2_isr_table[i].irq,
- snd_sgio2_isr_table[i].isr,
- 0,
- snd_sgio2_isr_table[i].desc,
- &chip->channel[snd_sgio2_isr_table[i].idx])) {
- snd_sgio2audio_free(chip);
- printk(KERN_ERR "sgio2audio: cannot allocate irq %d\n",
- snd_sgio2_isr_table[i].irq);
- return -EBUSY;
- }
- }
-
- /* reset the interface */
- writeq(AUDIO_CONTROL_RESET, &mace->perif.audio.control);
- udelay(1);
- writeq(0, &mace->perif.audio.control);
- msleep_interruptible(1); /* give time to recover */
-
- /* set ring base */
- writeq(chip->ring_base_dma, &mace->perif.ctrl.ringbase);
-
- /* attach the AD1843 codec */
- chip->ad1843.read = read_ad1843_reg;
- chip->ad1843.write = write_ad1843_reg;
- chip->ad1843.chip = chip;
-
- /* initialize the AD1843 codec */
- err = ad1843_init(&chip->ad1843);
- if (err < 0) {
- snd_sgio2audio_free(chip);
- return err;
- }
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
- if (err < 0) {
- snd_sgio2audio_free(chip);
- return err;
- }
- *rchip = chip;
- return 0;
-}
-
-static int __devinit snd_sgio2audio_probe(struct platform_device *pdev)
-{
- struct snd_card *card;
- struct snd_sgio2audio *chip;
- int err;
-
- err = snd_card_create(index, id, THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- err = snd_sgio2audio_create(card, &chip);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- snd_card_set_dev(card, &pdev->dev);
-
- err = snd_sgio2audio_new_pcm(chip);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- err = snd_sgio2audio_new_mixer(chip);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- strcpy(card->driver, "SGI O2 Audio");
- strcpy(card->shortname, "SGI O2 Audio");
- sprintf(card->longname, "%s irq %i-%i",
- card->shortname,
- MACEISA_AUDIO1_DMAT_IRQ,
- MACEISA_AUDIO3_MERR_IRQ);
-
- err = snd_card_register(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- platform_set_drvdata(pdev, card);
- return 0;
-}
-
-static int __devexit snd_sgio2audio_remove(struct platform_device *pdev)
-{
- struct snd_card *card = platform_get_drvdata(pdev);
-
- snd_card_free(card);
- platform_set_drvdata(pdev, NULL);
- return 0;
-}
-
-static struct platform_driver sgio2audio_driver = {
- .probe = snd_sgio2audio_probe,
- .remove = __devexit_p(snd_sgio2audio_remove),
- .driver = {
- .name = "sgio2audio",
- .owner = THIS_MODULE,
- }
-};
-
-module_platform_driver(sgio2audio_driver);
diff --git a/ANDROID_3.4.5/sound/oss/CHANGELOG b/ANDROID_3.4.5/sound/oss/CHANGELOG
deleted file mode 100644
index 8706cd66..00000000
--- a/ANDROID_3.4.5/sound/oss/CHANGELOG
+++ /dev/null
@@ -1,369 +0,0 @@
-Note these changes relate to Hannu's code and don't include the changes
-made outside of this for modularising the sound
-
-Changelog for version 3.8o
---------------------------
-
-Since 3.8h
-- Included support for OPL3-SA1 and SoftOSS
-
-Since 3.8
-- Fixed SNDCTL_DSP_GETOSPACE
-- Compatibility fixes for Linux 2.1.47
-
-Since 3.8-beta21
-- Fixed all known bugs (I think).
-
-Since 3.8-beta8
-- Lot of fixes to audio playback code in dmabuf.c
-
-Since 3.8-beta6
-- Fixed the famous Quake delay bug.
-
-Since 3.8-beta5
-- Fixed many bugs in audio playback.
-
-Since 3.8-beta4
-- Just minor changes.
-
-Since 3.8-beta1
-- Major rewrite of audio playback handling.
-- Added AWE32 support by Takashi Iwai (in ./lowlevel/).
-
-Since 3.7-beta#
-- Passing of ioctl() parameters between soundcard.c and other modules has been
-changed so that arg always points to kernel space.
-- Some bugfixes.
-
-Since 3.7-beta5
-- Disabled MIDI input with GUS PnP (Interwave). There seems to be constant
-stream of received 0x00 bytes when the MIDI receiver is enabled.
-
-Since 3.5
-- Changes almost everywhere.
-- Support for OPTi 82C924-based sound cards.
-
-Since 3.5.4-beta8
-- Fixed a bug in handling of non-fragment sized writes in 16 bit/stereo mode
- with GUS.
-- Limited minimum fragment size with some audio devices (GUS=512 and
- SB=32). These devices require more time to "recover" from processing
- of each fragment.
-
-Since 3.5.4-beta6/7
-- There seems to be problems in the OPTi 82C930 so cards based on this
- chip don't necessarily work yet. There are problems in detecting the
- MIDI interface. Also mixer volumes may be seriously wrong on some systems.
- You can safely use this driver version with C930 if it looks to work.
- However please don't complain if you have problems with it. C930 support
- should be fixed in future releases.
-- Got initialization of GUS PnP to work. With this version GUS PnP should
- work in GUS compatible mode after initialization using isapnptools.
-- Fixed a bug in handling of full duplex cards in write only mode. This has
- been causing "audio device opening" errors with RealAudio player.
-
-Since 3.5.4.beta5
-- Changes to OPTi 82C930 driver.
-- Major changes to the Soundscape driver. The driver requires now just one
- DMA channel. The extra audio/dsp device (the "Not functional" one) used
- for code download in the earlier versions has been eliminated. There is now
- just one /dev/dsp# device which is used both for code download and audio.
-
-Since 3.5.4.beta4
-- Minor changes.
-
-Since 3.5.4-beta2
-- Fixed silent playback with ESS 688/1688.
-- Got SB16 to work without the 16 bit DMA channel (only the 8 bit one
- is required for 8 and 16 bit modes).
-- Added the "lowlevel" subdirectory for additional low level drivers that
- are not part of USS core. See lowlevel/README for more info.
-- Included support for ACI mixer (by Markus Kuhn). ACI is a mixer used in
- miroPCM sound cards. See lowlevel/aci.readme for more info.
-- Support for Aztech Washington chipset (AZT2316 ASIC).
-
-Since 3.5.4-beta1
-- Reduced clicking with AD1848.
-- Support for OPTi 82C930. Only half duplex at this time. 16 bit playback
- is sometimes just white noise (occurs randomly).
-
-Since 3.5.2
-- Major changes to the SB/Jazz16/ESS driver (most parts rewritten).
- The most noticeable new feature is support for multiple SB cards at the same
- time.
-- Renamed sb16_midi.c to uart401.c. Also modified it to work also with
- other MPU401 UART compatible cards than SB16/ESS/Jazz.
-- Some changes which reduce clicking in audio playback.
-- Copying policy is now GPL.
-
-Since 3.5.1
-- TB Maui initialization support
-Since 3.5
-- Improved handling of playback underrun situations.
-
-Since 3.5-beta10
-- Bug fixing
-
-Since 3.5-beta9
-- Fixed for compatibility with Linux 1.3.70 and later.
-- Changed boot time passing of 16 bit DMA channel number to SB driver.
-
-Since 3.5-beta8
-- Minor changes
-
-Since 3.5-beta7
-- enhancements to configure program (by Jeff Tranter):
- - prompts are in same format as 1.3.x Linux kernel config program
- - on-line help for each question
- - fixed some compile warnings detected by gcc/g++ -Wall
- - minor grammatical changes to prompts
-
-Since 3.5-beta6
-- Fixed bugs in mmap() support.
-- Minor changes to Maui driver.
-
-Since 3.5-beta5
-- Fixed crash after recording with ESS688. It's generally a good
- idea to stop inbound DMA transfers before freeing the memory
- buffer.
-- Fixed handling of AD1845 codec (for example Shuttle Sound System).
-- Few other fixes.
-
-Since 3.5-beta4
-- Fixed bug in handling of uninitialized instruments with GUS.
-
-Since 3.5-beta3
-- Few changes which decrease popping at end/beginning of audio playback.
-
-Since 3.5-beta2
-- Removed MAD16+CS4231 hack made in previous version since it didn't
- help.
-- Fixed the above bug in proper way and in proper place. Many thanks
- to James Hightower.
-
-Since 3.5-beta1
-- Bug fixes.
-- Full duplex audio with MAD16+CS4231 may work now. The driver configures
- SB DMA of MAD16 so that it doesn't conflict with codec's DMA channels.
- The side effect is that all 8 bit DMA channels (0,1,3) are populated in
- duplex mode.
-
-Since 3.5-alpha9
-- Bug fixes (mostly in Jazz16 and ESS1688/688 supports).
-- Temporarily disabled recording with ESS1688/688 since it causes crash.
-- Changed audio buffer partitioning algorithm so that it selects
- smaller fragment size than earlier. This improves real time capabilities
- of the driver and makes recording to disk to work better. Unfortunately
- this change breaks some programs which assume that fragments cannot be
- shorter than 4096 bytes.
-
-Since 3.5-alpha8
-- Bug fixes
-
-Since 3.5-alpha7
-- Linux kernel compatible configuration (_EXPERIMENTAL_). Enable
- using command "cd /linux/drivers/sound;make script" and then
- just run kernel's make config normally.
-- Minor fixes to the SB support. Hopefully the driver works with
- all SB models now.
-- Added support for ESS ES1688 "AudioDrive" based cards.
-
-Since 3.5-alpha6
-- SB Pro and SB16 supports are no longer separately selectable options.
- Enabling SB enables them too.
-- Changed all #ifndef EXCLUDE_xx stuff to #ifdef CONFIG_xx. Modified
-configure to handle this.
-- Removed initialization messages from the
-modularized version. They can be enabled by using init_trace=1 in
-the insmod command line (insmod sound init_trace=1).
-- More AIX stuff.
-- Added support for synchronizing dsp/audio devices with /dev/sequencer.
-- mmap() support for dsp/audio devices.
-
-Since 3.5-alpha5
-- AIX port.
-- Changed some xxx_PATCH macros in soundcard.h to work with
- big endian machines.
-
-Since 3.5-alpha4
-- Removed the 'setfx' stuff from the version distributed with kernel
- sources. Running 'setfx' is required again.
-
-Since 3.5-alpha3
-- Moved stuff from the 'setfx' program to the AudioTrix Pro driver.
-
-Since 3.5-alpha2
-- Modifications to makefile and configure.c. Unnecessary sources
- are no longer compiled. Newly created local.h is also copied to
- /etc/soundconf. "make oldconfig" reads /etc/soundconf and produces
- new local.h which is compatible with current version of the driver.
-- Some fixes to the SB16 support.
-- Fixed random protection fault in gus_wave.c
-
-Since 3.5-alpha1
-- Modified to work with Linux-1.3.33 and later
-- Some minor changes
-
-Since 3.0.2
-- Support for CS4232 based PnP cards (AcerMagic S23 etc).
-- Full duplex support for some CS4231, CS4232 and AD1845 based cards
-(GUS MAX, AudioTrix Pro, AcerMagic S23 and many MAD16/Mozart cards
-having a codec mentioned above).
-- Almost fully rewritten loadable modules support.
-- Fixed some bugs.
-- Huge amount of testing (more testing is still required).
-- mmap() support (works with some cards). Requires much more testing.
-- Sample/patch/program loading for TB Maui/Tropez. No initialization
-since TB doesn't allow me to release that code.
-- Using CS4231 compatible codecs as timer for /dev/music.
-
-Since 3.0.1
-- Added allocation of I/O ports, DMA channels and interrupts
-to the initialization code. This may break modules support since
-the driver may not free some resources on unload. Should be fixed soon.
-
-Since 3.0
-- Some important bug fixes.
-- select() for /dev/dsp and /dev/audio (Linux only).
-(To use select() with read, you have to call read() to start
-the recording. Calling write() kills recording immediately so
-use select() carefully when you are writing a half duplex app.
-Full duplex mode is not implemented yet.) Select works also with
-/dev/sequencer and /dev/music. Maybe with /dev/midi## too.
-
-Since 3.0-beta2
-- Minor fixes.
-- Added Readme.cards
-
-Since 3.0-beta1
-- Minor fixes to the modules support.
-- Eliminated call to sb_free_irq() in ad1848.c
-- Rewritten MAD16&Mozart support (not tested with MAD16 Pro).
-- Fix to DMA initialization of PSS cards.
-- Some fixes to ad1848/cs42xx mixer support (GUS MAX, MSS, etc.)
-- Fixed some bugs in the PSS driver which caused I/O errors with
- the MSS mode (/dev/dsp).
-
-Since 3.0-950506
-- Recording with GUS MAX fixed. It works when the driver is configured
- to use two DMA channels with GUS MAX (16 bit ones recommended).
-
-Since 3.0-94xxxx
-- Too many changes
-
-Since 3.0-940818
-- Fixes for Linux 1.1.4x.
-- Disables Disney Sound System with SG NX Pro 16 (less noise).
-
-Since 2.90-2
-- Fixes to soundcard.h
-- Non blocking mode to /dev/sequencer
-- Experimental detection code for Ensoniq Soundscape.
-
-Since 2.90
-- Minor and major bug fixes
-
-Since pre-3.0-940712
-- GUS MAX support
-- Partially working MSS/WSS support (could work with some cards).
-- Hardware u-Law and A-Law support with AD1848/CS4248 and CS4231 codecs
- (GUS MAX, GUS16, WSS etc). Hardware ADPCM is possible with GUS16 and
- GUS MAX, but it doesn't work yet.
-Since pre-3.0-940426
-- AD1848/CS4248/CS4231 codec support (MSS, GUS MAX, Aztec, Orchid etc).
-This codec chip is used in various sound cards. This version is developed
-for the 16 bit daughtercard of GUS. It should work with other cards also
-if the following requirements are met:
- - The I/O, IRQ and DMA settings are jumper selectable or
- the card is initialized by booting DOS before booting Linux (etc.).
- - You add the IO, IRQ and DMA settings manually to the local.h.
- (Just define GUS16_BASE, GUS16_IRQ and GUS16_DMA). Note that
- the base address bust be the base address of the codec chip not the
- card itself. For the GUS16 these are the same but most MSS compatible
- cards have the codec located at card_base+4.
-- Some minor changes
-
-Since 2.5 (******* MAJOR REWRITE ***********)
-
-This version is based on v2.3. I have tried to maintain two versions
-together so that this one should have the same features than v2.5.
-Something may still be missing. If you notice such things, please let me
-know.
-
-The Readme.v30 contains more details.
-
-- /dev/midi## devices.
-- /dev/sequencer2
-
-Since 2.5-beta2
-- Some fine tuning to the GUS v3.7 mixer code.
-- Fixed speed limits for the plain SB (1.0 to 2.0).
-
-Since 2.5-beta
-- Fixed OPL-3 detection with SB. Caused problems with PAS16.
-- GUS v3.7 mixer support.
-
-Since 2.4
-- Mixer support for Sound Galaxy NX Pro (define __SGNXPRO__ on your local.h).
-- Fixed truncated sound on /dev/dsp when the device is closed.
-- Linear volume mode for GUS
-- Pitch bends larger than +/- 2 octaves.
-- MIDI recording for SB and SB Pro. (Untested).
-- Some other fixes.
-- SB16 MIDI and DSP drivers only initialized if SB16 actually installed.
-- Implemented better detection for OPL-3. This should be useful if you
- have an old SB Pro (the non-OPL-3 one) or a SB 2.0 clone which has a OPL-3.
-- SVR4.2 support by Ian Hartas. Initial ALPHA TEST version (untested).
-
-Since 2.3b
-- Fixed bug which made it impossible to make long recordings to disk.
- Recording was not restarted after a buffer overflow situation.
-- Limited mixer support for GUS.
-- Numerous improvements to the GUS driver by Andrew Robinson. Including
- some click removal etc.
-
-Since 2.3
-- Fixed some minor bugs in the SB16 driver.
-
-Since 2.2b
-- Full SB16 DSP support. 8/16 bit, mono/stereo
-- The SCO and FreeBSD versions should be in sync now. There are some
- problems with SB16 and GUS in the FreeBSD versions.
- The DMA buffer allocation of the SCO version has been polished but
- there could still be some problems. At least it hogs memory.
- The DMA channel
- configuration method used in the SCO/System is a hack.
-- Support for the MPU emulation of the SB16.
-- Some big arrays are now allocated boot time. This makes the BSS segment
- smaller which makes it possible to use the full driver with
- NetBSD. These arrays are not allocated if no suitable sound card is available.
-- Fixed a bug in the compute_and_set_volume in gus_wave.c
-- Fixed the too fast mono playback problem of SB Pro and PAS16.
-
-Since 2.2
-- Stereo recording for SB Pro. Somehow it was missing and nobody
- had noticed it earlier.
-- Minor polishing.
-- Interpreting of boot time arguments (sound=) for Linux.
-- Breakup of sb_dsp.c. Parts of the code has been moved to
- sb_mixer.c and sb_midi.c
-
-Since 2.1
-- Preliminary support for SB16.
- - The SB16 mixer is supported in its native mode.
- - Digitized voice capability up to 44.1 kHz/8 bit/mono
- (16 bit and stereo support coming in the next release).
-- Fixed some bugs in the digitized voice driver for PAS16.
-- Proper initialization of the SB emulation of latest PAS16 models.
-
-- Significantly improved /dev/dsp and /dev/audio support.
- - Now supports half duplex mode. It's now possible to record and
- playback without closing and reopening the device.
- - It's possible to use smaller buffers than earlier. There is a new
- ioctl(fd, SNDCTL_DSP_SUBDIVIDE, &n) where n should be 1, 2 or 4.
- This call instructs the driver to use smaller buffers. The default
- buffer size (0.5 to 1.0 seconds) is divided by n. Should be called
- immediately after opening the device.
-
-Since 2.0
-Just cosmetic changes.
diff --git a/ANDROID_3.4.5/sound/oss/Kconfig b/ANDROID_3.4.5/sound/oss/Kconfig
deleted file mode 100644
index 5849b129..00000000
--- a/ANDROID_3.4.5/sound/oss/Kconfig
+++ /dev/null
@@ -1,541 +0,0 @@
-# 18 Apr 1998, Michael Elizabeth Chastain, <mailto:mec@shout.net>
-# More hacking for modularisation.
-#
-# Prompt user for primary drivers.
-
-config SOUND_BCM_CS4297A
- tristate "Crystal Sound CS4297a (for Swarm)"
- depends on SIBYTE_SWARM
- help
- The BCM91250A has a Crystal CS4297a on synchronous serial
- port B (in addition to the DB-9 serial port). Say Y or M
- here to enable the sound chip instead of the UART. Also
- note that CONFIG_KGDB should not be enabled at the same
- time, since it also attempts to use this UART port.
-
-config SOUND_VWSND
- tristate "SGI Visual Workstation Sound"
- depends on X86_VISWS
- help
- Say Y or M if you have an SGI Visual Workstation and you want to be
- able to use its on-board audio. Read
- <file:Documentation/sound/oss/vwsnd> for more info on this driver's
- capabilities.
-
-config SOUND_MSNDCLAS
- tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey"
- depends on (m || !STANDALONE) && ISA
- help
- Say M here if you have a Turtle Beach MultiSound Classic, Tahiti or
- Monterey (not for the Pinnacle or Fiji).
-
- See <file:Documentation/sound/oss/MultiSound> for important information
- about this driver. Note that it has been discontinued, but the
- Voyetra Turtle Beach knowledge base entry for it is still available
- at <http://www.turtlebeach.com/site/kb_ftp/790.asp>.
-
-comment "Compiled-in MSND Classic support requires firmware during compilation."
- depends on SOUND_PRIME && SOUND_MSNDCLAS=y
-
-config MSNDCLAS_HAVE_BOOT
- bool
- depends on SOUND_MSNDCLAS=y && !STANDALONE
- default y
-
-config MSNDCLAS_INIT_FILE
- string "Full pathname of MSNDINIT.BIN firmware file"
- depends on SOUND_MSNDCLAS
- default "/etc/sound/msndinit.bin"
- help
- The MultiSound cards have two firmware files which are required for
- operation, and are not currently included. These files can be
- obtained from Turtle Beach. See
- <file:Documentation/sound/oss/MultiSound> for information on how to
- obtain this.
-
-config MSNDCLAS_PERM_FILE
- string "Full pathname of MSNDPERM.BIN firmware file"
- depends on SOUND_MSNDCLAS
- default "/etc/sound/msndperm.bin"
- help
- The MultiSound cards have two firmware files which are required for
- operation, and are not currently included. These files can be
- obtained from Turtle Beach. See
- <file:Documentation/sound/oss/MultiSound> for information on how to
- obtain this.
-
-config MSNDCLAS_IRQ
- int "MSND Classic IRQ 5, 7, 9, 10, 11, 12"
- depends on SOUND_MSNDCLAS=y
- default "5"
- help
- Interrupt Request line for the MultiSound Classic and related cards.
-
-config MSNDCLAS_MEM
- hex "MSND Classic memory B0000, C8000, D0000, D8000, E0000, E8000"
- depends on SOUND_MSNDCLAS=y
- default "D0000"
- help
- Memory-mapped I/O base address for the MultiSound Classic and
- related cards.
-
-config MSNDCLAS_IO
- hex "MSND Classic I/O 210, 220, 230, 240, 250, 260, 290, 3E0"
- depends on SOUND_MSNDCLAS=y
- default "290"
- help
- I/O port address for the MultiSound Classic and related cards.
-
-config SOUND_MSNDPIN
- tristate "Support for Turtle Beach MultiSound Pinnacle, Fiji"
- depends on (m || !STANDALONE) && ISA
- help
- Say M here if you have a Turtle Beach MultiSound Pinnacle or Fiji.
- See <file:Documentation/sound/oss/MultiSound> for important information
- about this driver. Note that it has been discontinued, but the
- Voyetra Turtle Beach knowledge base entry for it is still available
- at <http://www.turtlebeach.com/site/kb_ftp/600.asp>.
-
-comment "Compiled-in MSND Pinnacle support requires firmware during compilation."
- depends on SOUND_PRIME && SOUND_MSNDPIN=y
-
-config MSNDPIN_HAVE_BOOT
- bool
- depends on SOUND_MSNDPIN=y
- default y
-
-config MSNDPIN_INIT_FILE
- string "Full pathname of PNDSPINI.BIN firmware file"
- depends on SOUND_MSNDPIN
- default "/etc/sound/pndspini.bin"
- help
- The MultiSound cards have two firmware files which are required
- for operation, and are not currently included. These files can be
- obtained from Turtle Beach. See
- <file:Documentation/sound/oss/MultiSound> for information on how to
- obtain this.
-
-config MSNDPIN_PERM_FILE
- string "Full pathname of PNDSPERM.BIN firmware file"
- depends on SOUND_MSNDPIN
- default "/etc/sound/pndsperm.bin"
- help
- The MultiSound cards have two firmware files which are required for
- operation, and are not currently included. These files can be
- obtained from Turtle Beach. See
- <file:Documentation/sound/oss/MultiSound> for information on how to
- obtain this.
-
-config MSNDPIN_IRQ
- int "MSND Pinnacle IRQ 5, 7, 9, 10, 11, 12"
- depends on SOUND_MSNDPIN=y
- default "5"
- help
- Interrupt request line for the primary synthesizer on MultiSound
- Pinnacle and Fiji sound cards.
-
-config MSNDPIN_MEM
- hex "MSND Pinnacle memory B0000, C8000, D0000, D8000, E0000, E8000"
- depends on SOUND_MSNDPIN=y
- default "D0000"
- help
- Memory-mapped I/O base address for the primary synthesizer on
- MultiSound Pinnacle and Fiji sound cards.
-
-config MSNDPIN_IO
- hex "MSND Pinnacle I/O 210, 220, 230, 240, 250, 260, 290, 3E0"
- depends on SOUND_MSNDPIN=y
- default "290"
- help
- Memory-mapped I/O base address for the primary synthesizer on
- MultiSound Pinnacle and Fiji sound cards.
-
-config MSNDPIN_DIGITAL
- bool "MSND Pinnacle has S/PDIF I/O"
- depends on SOUND_MSNDPIN=y
- help
- If you have the S/PDIF daughter board for the Pinnacle or Fiji,
- answer Y here; otherwise, say N. If you have this, you will be able
- to play and record from the S/PDIF port (digital signal). See
- <file:Documentation/sound/oss/MultiSound> for information on how to make
- use of this capability.
-
-config MSNDPIN_NONPNP
- bool "MSND Pinnacle non-PnP Mode"
- depends on SOUND_MSNDPIN=y
- help
- The Pinnacle and Fiji card resources can be configured either with
- PnP, or through a configuration port. Say Y here if your card is NOT
- in PnP mode. For the Pinnacle, configuration in non-PnP mode allows
- use of the IDE and joystick peripherals on the card as well; these
- do not show up when the card is in PnP mode. Specifying zero for any
- resource of a device will disable the device. If you are running the
- card in PnP mode, you must say N here and use isapnptools to
- configure the card's resources.
-
-comment "MSND Pinnacle DSP section will be configured to above parameters."
- depends on SOUND_MSNDPIN=y && MSNDPIN_NONPNP
-
-config MSNDPIN_CFG
- hex "MSND Pinnacle config port 250,260,270"
- depends on MSNDPIN_NONPNP
- default "250"
- help
- This is the port which the Pinnacle and Fiji uses to configure the
- card's resources when not in PnP mode. If your card is in PnP mode,
- then be sure to say N to the previous option, "MSND Pinnacle Non-PnP
- Mode".
-
-comment "Pinnacle-specific Device Configuration (0 disables)"
- depends on SOUND_MSNDPIN=y && MSNDPIN_NONPNP
-
-config MSNDPIN_MPU_IO
- hex "MSND Pinnacle MPU I/O (e.g. 330)"
- depends on MSNDPIN_NONPNP
- default "0"
- help
- Memory-mapped I/O base address for the Kurzweil daughterboard
- synthesizer on MultiSound Pinnacle and Fiji sound cards.
-
-config MSNDPIN_MPU_IRQ
- int "MSND Pinnacle MPU IRQ (e.g. 9)"
- depends on MSNDPIN_NONPNP
- default "0"
- help
- Interrupt request number for the Kurzweil daughterboard
- synthesizer on MultiSound Pinnacle and Fiji sound cards.
-
-config MSNDPIN_IDE_IO0
- hex "MSND Pinnacle IDE I/O 0 (e.g. 170)"
- depends on MSNDPIN_NONPNP
- default "0"
- help
- CD-ROM drive 0 memory-mapped I/O base address for the MultiSound
- Pinnacle and Fiji sound cards.
-
-config MSNDPIN_IDE_IO1
- hex "MSND Pinnacle IDE I/O 1 (e.g. 376)"
- depends on MSNDPIN_NONPNP
- default "0"
- help
- CD-ROM drive 1 memory-mapped I/O base address for the MultiSound
- Pinnacle and Fiji sound cards.
-
-config MSNDPIN_IDE_IRQ
- int "MSND Pinnacle IDE IRQ (e.g. 15)"
- depends on MSNDPIN_NONPNP
- default "0"
- help
- Interrupt request number for the IDE CD-ROM interface on the
- MultiSound Pinnacle and Fiji sound cards.
-
-config MSNDPIN_JOYSTICK_IO
- hex "MSND Pinnacle joystick I/O (e.g. 200)"
- depends on MSNDPIN_NONPNP
- default "0"
- help
- Memory-mapped I/O base address for the joystick port on MultiSound
- Pinnacle and Fiji sound cards.
-
-config MSND_FIFOSIZE
- int "MSND buffer size (kB)"
- depends on SOUND_MSNDPIN=y || SOUND_MSNDCLAS=y
- default "128"
- help
- Configures the size of each audio buffer, in kilobytes, for
- recording and playing in the MultiSound drivers (both the Classic
- and Pinnacle). Larger values reduce the chance of data overruns at
- the expense of overall latency. If unsure, use the default.
-
-menuconfig SOUND_OSS
- tristate "OSS sound modules"
- depends on ISA_DMA_API && VIRT_TO_BUS
- help
- OSS is the Open Sound System suite of sound card drivers. They make
- sound programming easier since they provide a common API. Say Y or
- M here (the module will be called sound) if you haven't found a
- driver for your sound card above, then pick your driver from the
- list below.
-
-if SOUND_OSS
-
-config SOUND_TRACEINIT
- bool "Verbose initialisation"
- help
- Verbose soundcard initialization -- affects the format of autoprobe
- and initialization messages at boot time.
-
-config SOUND_DMAP
- bool "Persistent DMA buffers"
- ---help---
- Linux can often have problems allocating DMA buffers for ISA sound
- cards on machines with more than 16MB of RAM. This is because ISA
- DMA buffers must exist below the 16MB boundary and it is quite
- possible that a large enough free block in this region cannot be
- found after the machine has been running for a while. If you say Y
- here the DMA buffers (64Kb) will be allocated at boot time and kept
- until the shutdown. This option is only useful if you said Y to
- "OSS sound modules", above. If you said M to "OSS sound modules"
- then you can get the persistent DMA buffer functionality by passing
- the command-line argument "dmabuf=1" to the sound module.
-
- Say Y unless you have 16MB or more RAM or a PCI sound card.
-
-config SOUND_VMIDI
- tristate "Loopback MIDI device support"
- help
- Support for MIDI loopback on port 1 or 2.
-
-config SOUND_TRIX
- tristate "MediaTrix AudioTrix Pro support"
- help
- Answer Y if you have the AudioTriX Pro sound card manufactured
- by MediaTrix.
-
-config TRIX_HAVE_BOOT
- bool "Have TRXPRO.HEX firmware file"
- depends on SOUND_TRIX=y && !STANDALONE
- help
- The MediaTrix AudioTrix Pro has an on-board microcontroller which
- needs to be initialized by downloading the code from the file
- TRXPRO.HEX in the DOS driver directory. If you don't have the
- TRXPRO.HEX file handy you may skip this step. However, the SB and
- MPU-401 modes of AudioTrix Pro will not work without this file!
-
-config TRIX_BOOT_FILE
- string "Full pathname of TRXPRO.HEX firmware file"
- depends on TRIX_HAVE_BOOT
- default "/etc/sound/trxpro.hex"
- help
- Enter the full pathname of your TRXPRO.HEX file, starting from /.
-
-config SOUND_MSS
- tristate "Microsoft Sound System support"
- ---help---
- Again think carefully before answering Y to this question. It's
- safe to answer Y if you have the original Windows Sound System card
- made by Microsoft or Aztech SG 16 Pro (or NX16 Pro). Also you may
- say Y in case your card is NOT among these:
-
- ATI Stereo F/X, AdLib, Audio Excell DSP16, Cardinal DSP16,
- Ensoniq SoundScape (and compatibles made by Reveal and Spea),
- Gravis Ultrasound, Gravis Ultrasound ACE, Gravis Ultrasound Max,
- Gravis Ultrasound with 16 bit option, Logitech Sound Man 16,
- Logitech SoundMan Games, Logitech SoundMan Wave, MAD16 Pro (OPTi
- 82C929), Media Vision Jazz16, MediaTriX AudioTriX Pro, Microsoft
- Windows Sound System (MSS/WSS), Mozart (OAK OTI-601), Orchid
- SW32, Personal Sound System (PSS), Pro Audio Spectrum 16, Pro
- Audio Studio 16, Pro Sonic 16, Roland MPU-401 MIDI interface,
- Sound Blaster 1.0, Sound Blaster 16, Sound Blaster 16ASP, Sound
- Blaster 2.0, Sound Blaster AWE32, Sound Blaster Pro, TI TM4000M
- notebook, ThunderBoard, Turtle Beach Tropez, Yamaha FM
- synthesizers (OPL2, OPL3 and OPL4), 6850 UART MIDI Interface.
-
- For cards having native support in VoxWare, consult the card
- specific instructions in <file:Documentation/sound/oss/README.OSS>.
- Some drivers have their own MSS support and saying Y to this option
- will cause a conflict.
-
- If you compile the driver into the kernel, you have to add
- "ad1848=<io>,<irq>,<dma>,<dma2>[,<type>]" to the kernel command
- line.
-
-config SOUND_MPU401
- tristate "MPU-401 support (NOT for SB16)"
- ---help---
- Be careful with this question. The MPU401 interface is supported by
- all sound cards. However, some natively supported cards have their
- own driver for MPU401. Enabling this MPU401 option with these cards
- will cause a conflict. Also, enabling MPU401 on a system that
- doesn't really have a MPU401 could cause some trouble. If your card
- was in the list of supported cards, look at the card specific
- instructions in the <file:Documentation/sound/oss/README.OSS> file. It
- is safe to answer Y if you have a true MPU401 MIDI interface card.
-
- If you compile the driver into the kernel, you have to add
- "mpu401=<io>,<irq>" to the kernel command line.
-
-config SOUND_PAS
- tristate "ProAudioSpectrum 16 support"
- ---help---
- Answer Y only if you have a Pro Audio Spectrum 16, ProAudio Studio
- 16 or Logitech SoundMan 16 sound card. Answer N if you have some
- other card made by Media Vision or Logitech since those are not
- PAS16 compatible. Please read <file:Documentation/sound/oss/PAS16>.
- It is not necessary to add Sound Blaster support separately; it
- is included in PAS support.
-
- If you compile the driver into the kernel, you have to add
- "pas2=<io>,<irq>,<dma>,<dma2>,<sbio>,<sbirq>,<sbdma>,<sbdma2>
- to the kernel command line.
-
-config PAS_JOYSTICK
- bool "Enable PAS16 joystick port"
- depends on SOUND_PAS=y
- help
- Say Y here to enable the Pro Audio Spectrum 16's auxiliary joystick
- port.
-
-config SOUND_PSS
- tristate "PSS (AD1848, ADSP-2115, ESC614) support"
- help
- Answer Y or M if you have an Orchid SW32, Cardinal DSP16, Beethoven
- ADSP-16 or some other card based on the PSS chipset (AD1848 codec +
- ADSP-2115 DSP chip + Echo ESC614 ASIC CHIP). For more information on
- how to compile it into the kernel or as a module see the file
- <file:Documentation/sound/oss/PSS>.
-
- If you compile the driver into the kernel, you have to add
- "pss=<io>,<mssio>,<mssirq>,<mssdma>,<mpuio>,<mpuirq>" to the kernel
- command line.
-
-config PSS_MIXER
- bool "Enable PSS mixer (Beethoven ADSP-16 and other compatible)"
- depends on SOUND_PSS
- help
- Answer Y for Beethoven ADSP-16. You may try to say Y also for other
- cards if they have master volume, bass, treble, and you can't
- control it under Linux. If you answer N for Beethoven ADSP-16, you
- can't control master volume, bass, treble and synth volume.
-
- If you said M to "PSS support" above, you may enable or disable this
- PSS mixer with the module parameter pss_mixer. For more information
- see the file <file:Documentation/sound/oss/PSS>.
-
-config PSS_HAVE_BOOT
- bool "Have DSPxxx.LD firmware file"
- depends on SOUND_PSS && !STANDALONE
- help
- If you have the DSPxxx.LD file or SYNTH.LD file for you card, say Y
- to include this file. Without this file the synth device (OPL) may
- not work.
-
-config PSS_BOOT_FILE
- string "Full pathname of DSPxxx.LD firmware file"
- depends on PSS_HAVE_BOOT
- default "/etc/sound/dsp001.ld"
- help
- Enter the full pathname of your DSPxxx.LD file or SYNTH.LD file,
- starting from /.
-
-config SOUND_SB
- tristate "100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support"
- ---help---
- Answer Y if you have an original Sound Blaster card made by Creative
- Labs or a 100% hardware compatible clone (like the Thunderboard or
- SM Games). For an unknown card you may answer Y if the card claims
- to be Sound Blaster-compatible.
-
- Please read the file <file:Documentation/sound/oss/Soundblaster>.
-
- You should also say Y here for cards based on the Avance Logic
- ALS-007 and ALS-1X0 chips (read <file:Documentation/sound/oss/ALS>) and
- for cards based on ESS chips (read
- <file:Documentation/sound/oss/ESS1868> and
- <file:Documentation/sound/oss/ESS>). If you have an IBM Mwave
- card, say Y here and read <file:Documentation/sound/oss/mwave>.
-
- If you compile the driver into the kernel and don't want to use
- isapnp, you have to add "sb=<io>,<irq>,<dma>,<dma2>" to the kernel
- command line.
-
- You can say M here to compile this driver as a module; the module is
- called sb.
-
-config SOUND_YM3812
- tristate "Yamaha FM synthesizer (YM3812/OPL-3) support"
- ---help---
- Answer Y if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4).
- Answering Y is usually a safe and recommended choice, however some
- cards may have software (TSR) FM emulation. Enabling FM support with
- these cards may cause trouble (I don't currently know of any such
- cards, however). Please read the file
- <file:Documentation/sound/oss/OPL3> if your card has an OPL3 chip.
-
- If you compile the driver into the kernel, you have to add
- "opl3=<io>" to the kernel command line.
-
- If unsure, say Y.
-
-config SOUND_UART6850
- tristate "6850 UART support"
- help
- This option enables support for MIDI interfaces based on the 6850
- UART chip. This interface is rarely found on sound cards. It's safe
- to answer N to this question.
-
- If you compile the driver into the kernel, you have to add
- "uart6850=<io>,<irq>" to the kernel command line.
-
-config SOUND_AEDSP16
- tristate "Gallant Audio Cards (SC-6000 and SC-6600 based)"
- ---help---
- Answer Y if you have a Gallant's Audio Excel DSP 16 card. This
- driver supports Audio Excel DSP 16 but not the III nor PnP versions
- of this card.
-
- The Gallant's Audio Excel DSP 16 card can emulate either an SBPro or
- a Microsoft Sound System card, so you should have said Y to either
- "100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support"
- or "Microsoft Sound System support", above, and you need to answer
- the "MSS emulation" and "SBPro emulation" questions below
- accordingly. You should say Y to one and only one of these two
- questions.
-
- Read the <file:Documentation/sound/oss/README.OSS> file and the head of
- <file:sound/oss/aedsp16.c> as well as
- <file:Documentation/sound/oss/AudioExcelDSP16> to get more information
- about this driver and its configuration.
-
-config SC6600
- bool "SC-6600 based audio cards (new Audio Excel DSP 16)"
- depends on SOUND_AEDSP16
- help
- The SC6600 is the new version of DSP mounted on the Audio Excel DSP
- 16 cards. Find in the manual the FCC ID of your audio card and
- answer Y if you have an SC6600 DSP.
-
-config SC6600_JOY
- bool "Activate SC-6600 Joystick Interface"
- depends on SC6600
- help
- Say Y here in order to use the joystick interface of the Audio Excel
- DSP 16 card.
-
-config SC6600_CDROM
- int "SC-6600 CDROM Interface (4=None, 3=IDE, 1=Panasonic, 0=?Sony?)"
- depends on SC6600
- default "4"
- help
- This is used to activate the CD-ROM interface of the Audio Excel
- DSP 16 card. Enter: 0 for Sony, 1 for Panasonic, 2 for IDE, 4 for no
- CD-ROM present.
-
-config SC6600_CDROMBASE
- hex "SC-6600 CDROM Interface I/O Address"
- depends on SC6600
- default "0"
- help
- Base I/O port address for the CD-ROM interface of the Audio Excel
- DSP 16 card.
-
-config SOUND_VIDC
- tristate "VIDC 16-bit sound"
- depends on ARM && ARCH_ACORN
- help
- 16-bit support for the VIDC onboard sound hardware found on Acorn
- machines.
-
-config SOUND_WAVEARTIST
- tristate "Netwinder WaveArtist"
- depends on ARM && ARCH_NETWINDER
- help
- Say Y here to include support for the Rockwell WaveArtist sound
- system. This driver is mainly for the NetWinder.
-
-config SOUND_KAHLUA
- tristate "XpressAudio Sound Blaster emulation"
- depends on SOUND_SB
-
-endif # SOUND_OSS
-
diff --git a/ANDROID_3.4.5/sound/oss/Makefile b/ANDROID_3.4.5/sound/oss/Makefile
deleted file mode 100644
index 77f21b68..00000000
--- a/ANDROID_3.4.5/sound/oss/Makefile
+++ /dev/null
@@ -1,108 +0,0 @@
-# Makefile for the Linux sound card driver
-#
-# 18 Apr 1998, Michael Elizabeth Chastain, <mailto:mec@shout.net>
-# Rewritten to use lists instead of if-statements.
-
-# Each configuration option enables a list of files.
-
-obj-$(CONFIG_SOUND_OSS) += sound.o
-
-# Please leave it as is, cause the link order is significant !
-
-obj-$(CONFIG_SOUND_AEDSP16) += aedsp16.o
-obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o
-obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb_lib.o uart401.o
-obj-$(CONFIG_SOUND_MSS) += ad1848.o
-obj-$(CONFIG_SOUND_PAS) += pas2.o sb.o sb_lib.o uart401.o
-obj-$(CONFIG_SOUND_SB) += sb.o sb_lib.o uart401.o
-obj-$(CONFIG_SOUND_KAHLUA) += kahlua.o
-obj-$(CONFIG_SOUND_MPU401) += mpu401.o
-obj-$(CONFIG_SOUND_UART6850) += uart6850.o
-obj-$(CONFIG_SOUND_YM3812) += opl3.o
-obj-$(CONFIG_SOUND_VMIDI) += v_midi.o
-obj-$(CONFIG_SOUND_VIDC) += vidc_mod.o
-obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o
-obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o
-obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o
-obj-$(CONFIG_SOUND_VWSND) += vwsnd.o
-obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o
-
-obj-$(CONFIG_DMASOUND) += dmasound/
-
-# Declare multi-part drivers.
-
-sound-objs := \
- dev_table.o soundcard.o \
- audio.o dmabuf.o \
- midi_synth.o midibuf.o \
- sequencer.o sound_timer.o sys_timer.o
-
-pas2-objs := pas2_card.o pas2_midi.o pas2_mixer.o pas2_pcm.o
-sb-objs := sb_card.o
-sb_lib-objs := sb_common.o sb_audio.o sb_midi.o sb_mixer.o sb_ess.o
-vidc_mod-objs := vidc.o vidc_fill.o
-
-hostprogs-y := bin2hex hex2hex
-
-# Files generated that shall be removed upon make clean
-clean-files := msndperm.c msndinit.c pndsperm.c pndspini.c \
- pss_boot.h trix_boot.h
-
-# Firmware files that need translation
-#
-# The translated files are protected by a file that keeps track
-# of what name was used to build them. If the name changes, they
-# will be forced to be remade.
-#
-
-# Turtle Beach MultiSound
-
-ifeq ($(CONFIG_MSNDCLAS_HAVE_BOOT),y)
- $(obj)/msnd_classic.o: $(obj)/msndperm.c $(obj)/msndinit.c
-
- $(obj)/msndperm.c: $(patsubst "%", %, $(CONFIG_MSNDCLAS_PERM_FILE)) $(obj)/bin2hex
- $(obj)/bin2hex msndperm < $< > $@
-
- $(obj)/msndinit.c: $(patsubst "%", %, $(CONFIG_MSNDCLAS_INIT_FILE)) $(obj)/bin2hex
- $(obj)/bin2hex msndinit < $< > $@
-endif
-
-ifeq ($(CONFIG_MSNDPIN_HAVE_BOOT),y)
- $(obj)/msnd_pinnacle.o: $(obj)/pndsperm.c $(obj)/pndspini.c
-
- $(obj)/pndsperm.c: $(patsubst "%", %, $(CONFIG_MSNDPIN_PERM_FILE)) $(obj)/bin2hex
- $(obj)/bin2hex pndsperm < $< > $@
-
- $(obj)/pndspini.c: $(patsubst "%", %, $(CONFIG_MSNDPIN_INIT_FILE)) $(obj)/bin2hex
- $(obj)/bin2hex pndspini < $< > $@
-endif
-
-# PSS (ECHO-ADI2111)
-
-$(obj)/pss.o: $(obj)/pss_boot.h
-
-ifeq ($(CONFIG_PSS_HAVE_BOOT),y)
- $(obj)/pss_boot.h: $(patsubst "%", %, $(CONFIG_PSS_BOOT_FILE)) $(obj)/bin2hex
- $(obj)/bin2hex pss_synth < $< > $@
-else
- $(obj)/pss_boot.h:
- $(Q)( \
- echo 'static unsigned char * pss_synth = NULL;'; \
- echo 'static int pss_synthLen = 0;'; \
- ) > $@
-endif
-
-# MediaTrix AudioTrix Pro
-
-$(obj)/trix.o: $(obj)/trix_boot.h
-
-ifeq ($(CONFIG_TRIX_HAVE_BOOT),y)
- $(obj)/trix_boot.h: $(patsubst "%", %, $(CONFIG_TRIX_BOOT_FILE)) $(obj)/hex2hex
- $(obj)/hex2hex -i trix_boot < $< > $@
-else
- $(obj)/trix_boot.h:
- $(Q)( \
- echo 'static unsigned char * trix_boot = NULL;'; \
- echo 'static int trix_boot_len = 0;'; \
- ) > $@
-endif
diff --git a/ANDROID_3.4.5/sound/oss/README.FIRST b/ANDROID_3.4.5/sound/oss/README.FIRST
deleted file mode 100644
index 90fdcf06..00000000
--- a/ANDROID_3.4.5/sound/oss/README.FIRST
+++ /dev/null
@@ -1,6 +0,0 @@
-The modular sound driver patches were funded by Red Hat Software
-(www.redhat.com). The sound driver here is thus a modified version of
-Hannu's code. Please bear that in mind when considering the appropriate
-forums for bug reporting.
-
-Alan Cox
diff --git a/ANDROID_3.4.5/sound/oss/ad1848.c b/ANDROID_3.4.5/sound/oss/ad1848.c
deleted file mode 100644
index 98d23bdc..00000000
--- a/ANDROID_3.4.5/sound/oss/ad1848.c
+++ /dev/null
@@ -1,3069 +0,0 @@
-/*
- * sound/oss/ad1848.c
- *
- * The low level driver for the AD1848/CS4248 codec chip which
- * is used for example in the MS Sound System.
- *
- * The CS4231 which is used in the GUS MAX and some other cards is
- * upwards compatible with AD1848 and this driver is able to drive it.
- *
- * CS4231A and AD1845 are upward compatible with CS4231. However
- * the new features of these chips are different.
- *
- * CS4232 is a PnP audio chip which contains a CS4231A (and SB, MPU).
- * CS4232A is an improved version of CS4232.
- *
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- *
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
- * general sleep/wakeup clean up.
- * Alan Cox : reformatted. Fixed SMP bugs. Moved to kernel alloc/free
- * of irqs. Use dev_id.
- * Christoph Hellwig : adapted to module_init/module_exit
- * Aki Laukkanen : added power management support
- * Arnaldo C. de Melo : added missing restore_flags in ad1848_resume
- * Miguel Freitas : added ISA PnP support
- * Alan Cox : Added CS4236->4239 identification
- * Daniel T. Cobra : Alernate config/mixer for later chips
- * Alan Cox : Merged chip idents and config code
- *
- * TODO
- * APM save restore assist code on IBM thinkpad
- *
- * Status:
- * Tested. Believed fully functional.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/stddef.h>
-#include <linux/slab.h>
-#include <linux/isapnp.h>
-#include <linux/pnp.h>
-#include <linux/spinlock.h>
-
-#define DEB(x)
-#define DEB1(x)
-#include "sound_config.h"
-
-#include "ad1848.h"
-#include "ad1848_mixer.h"
-
-typedef struct
-{
- spinlock_t lock;
- int base;
- int irq;
- int dma1, dma2;
- int dual_dma; /* 1, when two DMA channels allocated */
- int subtype;
- unsigned char MCE_bit;
- unsigned char saved_regs[64]; /* Includes extended register space */
- int debug_flag;
-
- int audio_flags;
- int record_dev, playback_dev;
-
- int xfer_count;
- int audio_mode;
- int open_mode;
- int intr_active;
- char *chip_name, *name;
- int model;
-#define MD_1848 1
-#define MD_4231 2
-#define MD_4231A 3
-#define MD_1845 4
-#define MD_4232 5
-#define MD_C930 6
-#define MD_IWAVE 7
-#define MD_4235 8 /* Crystal Audio CS4235 */
-#define MD_1845_SSCAPE 9 /* Ensoniq Soundscape PNP*/
-#define MD_4236 10 /* 4236 and higher */
-#define MD_42xB 11 /* CS 42xB */
-#define MD_4239 12 /* CS4239 */
-
- /* Mixer parameters */
- int recmask;
- int supported_devices, orig_devices;
- int supported_rec_devices, orig_rec_devices;
- int *levels;
- short mixer_reroute[32];
- int dev_no;
- volatile unsigned long timer_ticks;
- int timer_running;
- int irq_ok;
- mixer_ents *mix_devices;
- int mixer_output_port;
-} ad1848_info;
-
-typedef struct ad1848_port_info
-{
- int open_mode;
- int speed;
- unsigned char speed_bits;
- int channels;
- int audio_format;
- unsigned char format_bits;
-}
-ad1848_port_info;
-
-static struct address_info cfg;
-static int nr_ad1848_devs;
-
-static bool deskpro_xl;
-static bool deskpro_m;
-static bool soundpro;
-
-static volatile signed char irq2dev[17] = {
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1
-};
-
-#ifndef EXCLUDE_TIMERS
-static int timer_installed = -1;
-#endif
-
-static int loaded;
-
-static int ad_format_mask[13 /*devc->model */ ] =
-{
- 0,
- AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW,
- AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM,
- AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM,
- AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW, /* AD1845 */
- AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM,
- AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM,
- AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM,
- AFMT_U8 | AFMT_S16_LE /* CS4235 */,
- AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW /* Ensoniq Soundscape*/,
- AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM,
- AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM,
- AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM
-};
-
-static ad1848_info adev_info[MAX_AUDIO_DEV];
-
-#define io_Index_Addr(d) ((d)->base)
-#define io_Indexed_Data(d) ((d)->base+1)
-#define io_Status(d) ((d)->base+2)
-#define io_Polled_IO(d) ((d)->base+3)
-
-static struct {
- unsigned char flags;
-#define CAP_F_TIMER 0x01
-} capabilities [10 /*devc->model */ ] = {
- {0}
- ,{0} /* MD_1848 */
- ,{CAP_F_TIMER} /* MD_4231 */
- ,{CAP_F_TIMER} /* MD_4231A */
- ,{CAP_F_TIMER} /* MD_1845 */
- ,{CAP_F_TIMER} /* MD_4232 */
- ,{0} /* MD_C930 */
- ,{CAP_F_TIMER} /* MD_IWAVE */
- ,{0} /* MD_4235 */
- ,{CAP_F_TIMER} /* MD_1845_SSCAPE */
-};
-
-#ifdef CONFIG_PNP
-static int isapnp = 1;
-static int isapnpjump;
-static bool reverse;
-
-static int audio_activated;
-#else
-static int isapnp;
-#endif
-
-
-
-static int ad1848_open(int dev, int mode);
-static void ad1848_close(int dev);
-static void ad1848_output_block(int dev, unsigned long buf, int count, int intrflag);
-static void ad1848_start_input(int dev, unsigned long buf, int count, int intrflag);
-static int ad1848_prepare_for_output(int dev, int bsize, int bcount);
-static int ad1848_prepare_for_input(int dev, int bsize, int bcount);
-static void ad1848_halt(int dev);
-static void ad1848_halt_input(int dev);
-static void ad1848_halt_output(int dev);
-static void ad1848_trigger(int dev, int bits);
-static irqreturn_t adintr(int irq, void *dev_id);
-
-#ifndef EXCLUDE_TIMERS
-static int ad1848_tmr_install(int dev);
-static void ad1848_tmr_reprogram(int dev);
-#endif
-
-static int ad_read(ad1848_info * devc, int reg)
-{
- int x;
- int timeout = 900000;
-
- while (timeout > 0 && inb(devc->base) == 0x80) /*Are we initializing */
- timeout--;
-
- if(reg < 32)
- {
- outb(((unsigned char) (reg & 0xff) | devc->MCE_bit), io_Index_Addr(devc));
- x = inb(io_Indexed_Data(devc));
- }
- else
- {
- int xreg, xra;
-
- xreg = (reg & 0xff) - 32;
- xra = (((xreg & 0x0f) << 4) & 0xf0) | 0x08 | ((xreg & 0x10) >> 2);
- outb(((unsigned char) (23 & 0xff) | devc->MCE_bit), io_Index_Addr(devc));
- outb(((unsigned char) (xra & 0xff)), io_Indexed_Data(devc));
- x = inb(io_Indexed_Data(devc));
- }
-
- return x;
-}
-
-static void ad_write(ad1848_info * devc, int reg, int data)
-{
- int timeout = 900000;
-
- while (timeout > 0 && inb(devc->base) == 0x80) /* Are we initializing */
- timeout--;
-
- if(reg < 32)
- {
- outb(((unsigned char) (reg & 0xff) | devc->MCE_bit), io_Index_Addr(devc));
- outb(((unsigned char) (data & 0xff)), io_Indexed_Data(devc));
- }
- else
- {
- int xreg, xra;
-
- xreg = (reg & 0xff) - 32;
- xra = (((xreg & 0x0f) << 4) & 0xf0) | 0x08 | ((xreg & 0x10) >> 2);
- outb(((unsigned char) (23 & 0xff) | devc->MCE_bit), io_Index_Addr(devc));
- outb(((unsigned char) (xra & 0xff)), io_Indexed_Data(devc));
- outb((unsigned char) (data & 0xff), io_Indexed_Data(devc));
- }
-}
-
-static void wait_for_calibration(ad1848_info * devc)
-{
- int timeout = 0;
-
- /*
- * Wait until the auto calibration process has finished.
- *
- * 1) Wait until the chip becomes ready (reads don't return 0x80).
- * 2) Wait until the ACI bit of I11 gets on and then off.
- */
-
- timeout = 100000;
- while (timeout > 0 && inb(devc->base) == 0x80)
- timeout--;
- if (inb(devc->base) & 0x80)
- printk(KERN_WARNING "ad1848: Auto calibration timed out(1).\n");
-
- timeout = 100;
- while (timeout > 0 && !(ad_read(devc, 11) & 0x20))
- timeout--;
- if (!(ad_read(devc, 11) & 0x20))
- return;
-
- timeout = 80000;
- while (timeout > 0 && (ad_read(devc, 11) & 0x20))
- timeout--;
- if (ad_read(devc, 11) & 0x20)
- if ((devc->model != MD_1845) && (devc->model != MD_1845_SSCAPE))
- printk(KERN_WARNING "ad1848: Auto calibration timed out(3).\n");
-}
-
-static void ad_mute(ad1848_info * devc)
-{
- int i;
- unsigned char prev;
-
- /*
- * Save old register settings and mute output channels
- */
-
- for (i = 6; i < 8; i++)
- {
- prev = devc->saved_regs[i] = ad_read(devc, i);
- }
-
-}
-
-static void ad_unmute(ad1848_info * devc)
-{
-}
-
-static void ad_enter_MCE(ad1848_info * devc)
-{
- int timeout = 1000;
- unsigned short prev;
-
- while (timeout > 0 && inb(devc->base) == 0x80) /*Are we initializing */
- timeout--;
-
- devc->MCE_bit = 0x40;
- prev = inb(io_Index_Addr(devc));
- if (prev & 0x40)
- {
- return;
- }
- outb((devc->MCE_bit), io_Index_Addr(devc));
-}
-
-static void ad_leave_MCE(ad1848_info * devc)
-{
- unsigned char prev, acal;
- int timeout = 1000;
-
- while (timeout > 0 && inb(devc->base) == 0x80) /*Are we initializing */
- timeout--;
-
- acal = ad_read(devc, 9);
-
- devc->MCE_bit = 0x00;
- prev = inb(io_Index_Addr(devc));
- outb((0x00), io_Index_Addr(devc)); /* Clear the MCE bit */
-
- if ((prev & 0x40) == 0) /* Not in MCE mode */
- {
- return;
- }
- outb((0x00), io_Index_Addr(devc)); /* Clear the MCE bit */
- if (acal & 0x08) /* Auto calibration is enabled */
- wait_for_calibration(devc);
-}
-
-static int ad1848_set_recmask(ad1848_info * devc, int mask)
-{
- unsigned char recdev;
- int i, n;
- unsigned long flags;
-
- mask &= devc->supported_rec_devices;
-
- /* Rename the mixer bits if necessary */
- for (i = 0; i < 32; i++)
- {
- if (devc->mixer_reroute[i] != i)
- {
- if (mask & (1 << i))
- {
- mask &= ~(1 << i);
- mask |= (1 << devc->mixer_reroute[i]);
- }
- }
- }
-
- n = 0;
- for (i = 0; i < 32; i++) /* Count selected device bits */
- if (mask & (1 << i))
- n++;
-
- spin_lock_irqsave(&devc->lock,flags);
- if (!soundpro) {
- if (n == 0)
- mask = SOUND_MASK_MIC;
- else if (n != 1) { /* Too many devices selected */
- mask &= ~devc->recmask; /* Filter out active settings */
-
- n = 0;
- for (i = 0; i < 32; i++) /* Count selected device bits */
- if (mask & (1 << i))
- n++;
-
- if (n != 1)
- mask = SOUND_MASK_MIC;
- }
- switch (mask) {
- case SOUND_MASK_MIC:
- recdev = 2;
- break;
-
- case SOUND_MASK_LINE:
- case SOUND_MASK_LINE3:
- recdev = 0;
- break;
-
- case SOUND_MASK_CD:
- case SOUND_MASK_LINE1:
- recdev = 1;
- break;
-
- case SOUND_MASK_IMIX:
- recdev = 3;
- break;
-
- default:
- mask = SOUND_MASK_MIC;
- recdev = 2;
- }
-
- recdev <<= 6;
- ad_write(devc, 0, (ad_read(devc, 0) & 0x3f) | recdev);
- ad_write(devc, 1, (ad_read(devc, 1) & 0x3f) | recdev);
- } else { /* soundpro */
- unsigned char val;
- int set_rec_bit;
- int j;
-
- for (i = 0; i < 32; i++) { /* For each bit */
- if ((devc->supported_rec_devices & (1 << i)) == 0)
- continue; /* Device not supported */
-
- for (j = LEFT_CHN; j <= RIGHT_CHN; j++) {
- if (devc->mix_devices[i][j].nbits == 0) /* Inexistent channel */
- continue;
-
- /*
- * This is tricky:
- * set_rec_bit becomes 1 if the corresponding bit in mask is set
- * then it gets flipped if the polarity is inverse
- */
- set_rec_bit = ((mask & (1 << i)) != 0) ^ devc->mix_devices[i][j].recpol;
-
- val = ad_read(devc, devc->mix_devices[i][j].recreg);
- val &= ~(1 << devc->mix_devices[i][j].recpos);
- val |= (set_rec_bit << devc->mix_devices[i][j].recpos);
- ad_write(devc, devc->mix_devices[i][j].recreg, val);
- }
- }
- }
- spin_unlock_irqrestore(&devc->lock,flags);
-
- /* Rename the mixer bits back if necessary */
- for (i = 0; i < 32; i++)
- {
- if (devc->mixer_reroute[i] != i)
- {
- if (mask & (1 << devc->mixer_reroute[i]))
- {
- mask &= ~(1 << devc->mixer_reroute[i]);
- mask |= (1 << i);
- }
- }
- }
- devc->recmask = mask;
- return mask;
-}
-
-static void oss_change_bits(ad1848_info *devc, unsigned char *regval,
- unsigned char *muteval, int dev, int chn, int newval)
-{
- unsigned char mask;
- int shift;
- int mute;
- int mutemask;
- int set_mute_bit;
-
- set_mute_bit = (newval == 0) ^ devc->mix_devices[dev][chn].mutepol;
-
- if (devc->mix_devices[dev][chn].polarity == 1) /* Reverse */
- newval = 100 - newval;
-
- mask = (1 << devc->mix_devices[dev][chn].nbits) - 1;
- shift = devc->mix_devices[dev][chn].bitpos;
-
- if (devc->mix_devices[dev][chn].mutepos == 8)
- { /* if there is no mute bit */
- mute = 0; /* No mute bit; do nothing special */
- mutemask = ~0; /* No mute bit; do nothing special */
- }
- else
- {
- mute = (set_mute_bit << devc->mix_devices[dev][chn].mutepos);
- mutemask = ~(1 << devc->mix_devices[dev][chn].mutepos);
- }
-
- newval = (int) ((newval * mask) + 50) / 100; /* Scale it */
- *regval &= ~(mask << shift); /* Clear bits */
- *regval |= (newval & mask) << shift; /* Set new value */
-
- *muteval &= mutemask;
- *muteval |= mute;
-}
-
-static int ad1848_mixer_get(ad1848_info * devc, int dev)
-{
- if (!((1 << dev) & devc->supported_devices))
- return -EINVAL;
-
- dev = devc->mixer_reroute[dev];
-
- return devc->levels[dev];
-}
-
-static void ad1848_mixer_set_channel(ad1848_info *devc, int dev, int value, int channel)
-{
- int regoffs, muteregoffs;
- unsigned char val, muteval;
- unsigned long flags;
-
- regoffs = devc->mix_devices[dev][channel].regno;
- muteregoffs = devc->mix_devices[dev][channel].mutereg;
- val = ad_read(devc, regoffs);
-
- if (muteregoffs != regoffs) {
- muteval = ad_read(devc, muteregoffs);
- oss_change_bits(devc, &val, &muteval, dev, channel, value);
- }
- else
- oss_change_bits(devc, &val, &val, dev, channel, value);
-
- spin_lock_irqsave(&devc->lock,flags);
- ad_write(devc, regoffs, val);
- devc->saved_regs[regoffs] = val;
- if (muteregoffs != regoffs) {
- ad_write(devc, muteregoffs, muteval);
- devc->saved_regs[muteregoffs] = muteval;
- }
- spin_unlock_irqrestore(&devc->lock,flags);
-}
-
-static int ad1848_mixer_set(ad1848_info * devc, int dev, int value)
-{
- int left = value & 0x000000ff;
- int right = (value & 0x0000ff00) >> 8;
- int retvol;
-
- if (dev > 31)
- return -EINVAL;
-
- if (!(devc->supported_devices & (1 << dev)))
- return -EINVAL;
-
- dev = devc->mixer_reroute[dev];
-
- if (devc->mix_devices[dev][LEFT_CHN].nbits == 0)
- return -EINVAL;
-
- if (left > 100)
- left = 100;
- if (right > 100)
- right = 100;
-
- if (devc->mix_devices[dev][RIGHT_CHN].nbits == 0) /* Mono control */
- right = left;
-
- retvol = left | (right << 8);
-
- /* Scale volumes */
- left = mix_cvt[left];
- right = mix_cvt[right];
-
- devc->levels[dev] = retvol;
-
- /*
- * Set the left channel
- */
- ad1848_mixer_set_channel(devc, dev, left, LEFT_CHN);
-
- /*
- * Set the right channel
- */
- if (devc->mix_devices[dev][RIGHT_CHN].nbits == 0)
- goto out;
- ad1848_mixer_set_channel(devc, dev, right, RIGHT_CHN);
-
- out:
- return retvol;
-}
-
-static void ad1848_mixer_reset(ad1848_info * devc)
-{
- int i;
- char name[32];
- unsigned long flags;
-
- devc->mix_devices = &(ad1848_mix_devices[0]);
-
- sprintf(name, "%s_%d", devc->chip_name, nr_ad1848_devs);
-
- for (i = 0; i < 32; i++)
- devc->mixer_reroute[i] = i;
-
- devc->supported_rec_devices = MODE1_REC_DEVICES;
-
- switch (devc->model)
- {
- case MD_4231:
- case MD_4231A:
- case MD_1845:
- case MD_1845_SSCAPE:
- devc->supported_devices = MODE2_MIXER_DEVICES;
- break;
-
- case MD_C930:
- devc->supported_devices = C930_MIXER_DEVICES;
- devc->mix_devices = &(c930_mix_devices[0]);
- break;
-
- case MD_IWAVE:
- devc->supported_devices = MODE3_MIXER_DEVICES;
- devc->mix_devices = &(iwave_mix_devices[0]);
- break;
-
- case MD_42xB:
- case MD_4239:
- devc->mix_devices = &(cs42xb_mix_devices[0]);
- devc->supported_devices = MODE3_MIXER_DEVICES;
- break;
- case MD_4232:
- case MD_4235:
- case MD_4236:
- devc->supported_devices = MODE3_MIXER_DEVICES;
- break;
-
- case MD_1848:
- if (soundpro) {
- devc->supported_devices = SPRO_MIXER_DEVICES;
- devc->supported_rec_devices = SPRO_REC_DEVICES;
- devc->mix_devices = &(spro_mix_devices[0]);
- break;
- }
-
- default:
- devc->supported_devices = MODE1_MIXER_DEVICES;
- }
-
- devc->orig_devices = devc->supported_devices;
- devc->orig_rec_devices = devc->supported_rec_devices;
-
- devc->levels = load_mixer_volumes(name, default_mixer_levels, 1);
-
- for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
- {
- if (devc->supported_devices & (1 << i))
- ad1848_mixer_set(devc, i, devc->levels[i]);
- }
-
- ad1848_set_recmask(devc, SOUND_MASK_MIC);
-
- devc->mixer_output_port = devc->levels[31] | AUDIO_HEADPHONE | AUDIO_LINE_OUT;
-
- spin_lock_irqsave(&devc->lock,flags);
- if (!soundpro) {
- if (devc->mixer_output_port & AUDIO_SPEAKER)
- ad_write(devc, 26, ad_read(devc, 26) & ~0x40); /* Unmute mono out */
- else
- ad_write(devc, 26, ad_read(devc, 26) | 0x40); /* Mute mono out */
- } else {
- /*
- * From the "wouldn't it be nice if the mixer API had (better)
- * support for custom stuff" category
- */
- /* Enable surround mode and SB16 mixer */
- ad_write(devc, 16, 0x60);
- }
- spin_unlock_irqrestore(&devc->lock,flags);
-}
-
-static int ad1848_mixer_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
- ad1848_info *devc = mixer_devs[dev]->devc;
- int val;
-
- if (cmd == SOUND_MIXER_PRIVATE1)
- {
- if (get_user(val, (int __user *)arg))
- return -EFAULT;
-
- if (val != 0xffff)
- {
- unsigned long flags;
- val &= (AUDIO_SPEAKER | AUDIO_HEADPHONE | AUDIO_LINE_OUT);
- devc->mixer_output_port = val;
- val |= AUDIO_HEADPHONE | AUDIO_LINE_OUT; /* Always on */
- devc->mixer_output_port = val;
- spin_lock_irqsave(&devc->lock,flags);
- if (val & AUDIO_SPEAKER)
- ad_write(devc, 26, ad_read(devc, 26) & ~0x40); /* Unmute mono out */
- else
- ad_write(devc, 26, ad_read(devc, 26) | 0x40); /* Mute mono out */
- spin_unlock_irqrestore(&devc->lock,flags);
- }
- val = devc->mixer_output_port;
- return put_user(val, (int __user *)arg);
- }
- if (cmd == SOUND_MIXER_PRIVATE2)
- {
- if (get_user(val, (int __user *)arg))
- return -EFAULT;
- return(ad1848_control(AD1848_MIXER_REROUTE, val));
- }
- if (((cmd >> 8) & 0xff) == 'M')
- {
- if (_SIOC_DIR(cmd) & _SIOC_WRITE)
- {
- switch (cmd & 0xff)
- {
- case SOUND_MIXER_RECSRC:
- if (get_user(val, (int __user *)arg))
- return -EFAULT;
- val = ad1848_set_recmask(devc, val);
- break;
-
- default:
- if (get_user(val, (int __user *)arg))
- return -EFAULT;
- val = ad1848_mixer_set(devc, cmd & 0xff, val);
- break;
- }
- return put_user(val, (int __user *)arg);
- }
- else
- {
- switch (cmd & 0xff)
- {
- /*
- * Return parameters
- */
-
- case SOUND_MIXER_RECSRC:
- val = devc->recmask;
- break;
-
- case SOUND_MIXER_DEVMASK:
- val = devc->supported_devices;
- break;
-
- case SOUND_MIXER_STEREODEVS:
- val = devc->supported_devices;
- if (devc->model != MD_C930)
- val &= ~(SOUND_MASK_SPEAKER | SOUND_MASK_IMIX);
- break;
-
- case SOUND_MIXER_RECMASK:
- val = devc->supported_rec_devices;
- break;
-
- case SOUND_MIXER_CAPS:
- val=SOUND_CAP_EXCL_INPUT;
- break;
-
- default:
- val = ad1848_mixer_get(devc, cmd & 0xff);
- break;
- }
- return put_user(val, (int __user *)arg);
- }
- }
- else
- return -EINVAL;
-}
-
-static int ad1848_set_speed(int dev, int arg)
-{
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
- ad1848_port_info *portc = (ad1848_port_info *) audio_devs[dev]->portc;
-
- /*
- * The sampling speed is encoded in the least significant nibble of I8. The
- * LSB selects the clock source (0=24.576 MHz, 1=16.9344 MHz) and other
- * three bits select the divisor (indirectly):
- *
- * The available speeds are in the following table. Keep the speeds in
- * the increasing order.
- */
- typedef struct
- {
- int speed;
- unsigned char bits;
- }
- speed_struct;
-
- static speed_struct speed_table[] =
- {
- {5510, (0 << 1) | 1},
- {5510, (0 << 1) | 1},
- {6620, (7 << 1) | 1},
- {8000, (0 << 1) | 0},
- {9600, (7 << 1) | 0},
- {11025, (1 << 1) | 1},
- {16000, (1 << 1) | 0},
- {18900, (2 << 1) | 1},
- {22050, (3 << 1) | 1},
- {27420, (2 << 1) | 0},
- {32000, (3 << 1) | 0},
- {33075, (6 << 1) | 1},
- {37800, (4 << 1) | 1},
- {44100, (5 << 1) | 1},
- {48000, (6 << 1) | 0}
- };
-
- int i, n, selected = -1;
-
- n = sizeof(speed_table) / sizeof(speed_struct);
-
- if (arg <= 0)
- return portc->speed;
-
- if (devc->model == MD_1845 || devc->model == MD_1845_SSCAPE) /* AD1845 has different timer than others */
- {
- if (arg < 4000)
- arg = 4000;
- if (arg > 50000)
- arg = 50000;
-
- portc->speed = arg;
- portc->speed_bits = speed_table[3].bits;
- return portc->speed;
- }
- if (arg < speed_table[0].speed)
- selected = 0;
- if (arg > speed_table[n - 1].speed)
- selected = n - 1;
-
- for (i = 1 /*really */ ; selected == -1 && i < n; i++)
- {
- if (speed_table[i].speed == arg)
- selected = i;
- else if (speed_table[i].speed > arg)
- {
- int diff1, diff2;
-
- diff1 = arg - speed_table[i - 1].speed;
- diff2 = speed_table[i].speed - arg;
-
- if (diff1 < diff2)
- selected = i - 1;
- else
- selected = i;
- }
- }
- if (selected == -1)
- {
- printk(KERN_WARNING "ad1848: Can't find speed???\n");
- selected = 3;
- }
- portc->speed = speed_table[selected].speed;
- portc->speed_bits = speed_table[selected].bits;
- return portc->speed;
-}
-
-static short ad1848_set_channels(int dev, short arg)
-{
- ad1848_port_info *portc = (ad1848_port_info *) audio_devs[dev]->portc;
-
- if (arg != 1 && arg != 2)
- return portc->channels;
-
- portc->channels = arg;
- return arg;
-}
-
-static unsigned int ad1848_set_bits(int dev, unsigned int arg)
-{
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
- ad1848_port_info *portc = (ad1848_port_info *) audio_devs[dev]->portc;
-
- static struct format_tbl
- {
- int format;
- unsigned char bits;
- }
- format2bits[] =
- {
- {
- 0, 0
- }
- ,
- {
- AFMT_MU_LAW, 1
- }
- ,
- {
- AFMT_A_LAW, 3
- }
- ,
- {
- AFMT_IMA_ADPCM, 5
- }
- ,
- {
- AFMT_U8, 0
- }
- ,
- {
- AFMT_S16_LE, 2
- }
- ,
- {
- AFMT_S16_BE, 6
- }
- ,
- {
- AFMT_S8, 0
- }
- ,
- {
- AFMT_U16_LE, 0
- }
- ,
- {
- AFMT_U16_BE, 0
- }
- };
- int i, n = sizeof(format2bits) / sizeof(struct format_tbl);
-
- if (arg == 0)
- return portc->audio_format;
-
- if (!(arg & ad_format_mask[devc->model]))
- arg = AFMT_U8;
-
- portc->audio_format = arg;
-
- for (i = 0; i < n; i++)
- if (format2bits[i].format == arg)
- {
- if ((portc->format_bits = format2bits[i].bits) == 0)
- return portc->audio_format = AFMT_U8; /* Was not supported */
-
- return arg;
- }
- /* Still hanging here. Something must be terribly wrong */
- portc->format_bits = 0;
- return portc->audio_format = AFMT_U8;
-}
-
-static struct audio_driver ad1848_audio_driver =
-{
- .owner = THIS_MODULE,
- .open = ad1848_open,
- .close = ad1848_close,
- .output_block = ad1848_output_block,
- .start_input = ad1848_start_input,
- .prepare_for_input = ad1848_prepare_for_input,
- .prepare_for_output = ad1848_prepare_for_output,
- .halt_io = ad1848_halt,
- .halt_input = ad1848_halt_input,
- .halt_output = ad1848_halt_output,
- .trigger = ad1848_trigger,
- .set_speed = ad1848_set_speed,
- .set_bits = ad1848_set_bits,
- .set_channels = ad1848_set_channels
-};
-
-static struct mixer_operations ad1848_mixer_operations =
-{
- .owner = THIS_MODULE,
- .id = "SOUNDPORT",
- .name = "AD1848/CS4248/CS4231",
- .ioctl = ad1848_mixer_ioctl
-};
-
-static int ad1848_open(int dev, int mode)
-{
- ad1848_info *devc;
- ad1848_port_info *portc;
- unsigned long flags;
-
- if (dev < 0 || dev >= num_audiodevs)
- return -ENXIO;
-
- devc = (ad1848_info *) audio_devs[dev]->devc;
- portc = (ad1848_port_info *) audio_devs[dev]->portc;
-
- /* here we don't have to protect against intr */
- spin_lock(&devc->lock);
- if (portc->open_mode || (devc->open_mode & mode))
- {
- spin_unlock(&devc->lock);
- return -EBUSY;
- }
- devc->dual_dma = 0;
-
- if (audio_devs[dev]->flags & DMA_DUPLEX)
- {
- devc->dual_dma = 1;
- }
- devc->intr_active = 0;
- devc->audio_mode = 0;
- devc->open_mode |= mode;
- portc->open_mode = mode;
- spin_unlock(&devc->lock);
- ad1848_trigger(dev, 0);
-
- if (mode & OPEN_READ)
- devc->record_dev = dev;
- if (mode & OPEN_WRITE)
- devc->playback_dev = dev;
-/*
- * Mute output until the playback really starts. This decreases clicking (hope so).
- */
- spin_lock_irqsave(&devc->lock,flags);
- ad_mute(devc);
- spin_unlock_irqrestore(&devc->lock,flags);
-
- return 0;
-}
-
-static void ad1848_close(int dev)
-{
- unsigned long flags;
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
- ad1848_port_info *portc = (ad1848_port_info *) audio_devs[dev]->portc;
-
- DEB(printk("ad1848_close(void)\n"));
-
- devc->intr_active = 0;
- ad1848_halt(dev);
-
- spin_lock_irqsave(&devc->lock,flags);
-
- devc->audio_mode = 0;
- devc->open_mode &= ~portc->open_mode;
- portc->open_mode = 0;
-
- ad_unmute(devc);
- spin_unlock_irqrestore(&devc->lock,flags);
-}
-
-static void ad1848_output_block(int dev, unsigned long buf, int count, int intrflag)
-{
- unsigned long flags, cnt;
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
- ad1848_port_info *portc = (ad1848_port_info *) audio_devs[dev]->portc;
-
- cnt = count;
-
- if (portc->audio_format == AFMT_IMA_ADPCM)
- {
- cnt /= 4;
- }
- else
- {
- if (portc->audio_format & (AFMT_S16_LE | AFMT_S16_BE)) /* 16 bit data */
- cnt >>= 1;
- }
- if (portc->channels > 1)
- cnt >>= 1;
- cnt--;
-
- if ((devc->audio_mode & PCM_ENABLE_OUTPUT) && (audio_devs[dev]->flags & DMA_AUTOMODE) &&
- intrflag &&
- cnt == devc->xfer_count)
- {
- devc->audio_mode |= PCM_ENABLE_OUTPUT;
- devc->intr_active = 1;
- return; /*
- * Auto DMA mode on. No need to react
- */
- }
- spin_lock_irqsave(&devc->lock,flags);
-
- ad_write(devc, 15, (unsigned char) (cnt & 0xff));
- ad_write(devc, 14, (unsigned char) ((cnt >> 8) & 0xff));
-
- devc->xfer_count = cnt;
- devc->audio_mode |= PCM_ENABLE_OUTPUT;
- devc->intr_active = 1;
- spin_unlock_irqrestore(&devc->lock,flags);
-}
-
-static void ad1848_start_input(int dev, unsigned long buf, int count, int intrflag)
-{
- unsigned long flags, cnt;
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
- ad1848_port_info *portc = (ad1848_port_info *) audio_devs[dev]->portc;
-
- cnt = count;
- if (portc->audio_format == AFMT_IMA_ADPCM)
- {
- cnt /= 4;
- }
- else
- {
- if (portc->audio_format & (AFMT_S16_LE | AFMT_S16_BE)) /* 16 bit data */
- cnt >>= 1;
- }
- if (portc->channels > 1)
- cnt >>= 1;
- cnt--;
-
- if ((devc->audio_mode & PCM_ENABLE_INPUT) && (audio_devs[dev]->flags & DMA_AUTOMODE) &&
- intrflag &&
- cnt == devc->xfer_count)
- {
- devc->audio_mode |= PCM_ENABLE_INPUT;
- devc->intr_active = 1;
- return; /*
- * Auto DMA mode on. No need to react
- */
- }
- spin_lock_irqsave(&devc->lock,flags);
-
- if (devc->model == MD_1848)
- {
- ad_write(devc, 15, (unsigned char) (cnt & 0xff));
- ad_write(devc, 14, (unsigned char) ((cnt >> 8) & 0xff));
- }
- else
- {
- ad_write(devc, 31, (unsigned char) (cnt & 0xff));
- ad_write(devc, 30, (unsigned char) ((cnt >> 8) & 0xff));
- }
-
- ad_unmute(devc);
-
- devc->xfer_count = cnt;
- devc->audio_mode |= PCM_ENABLE_INPUT;
- devc->intr_active = 1;
- spin_unlock_irqrestore(&devc->lock,flags);
-}
-
-static int ad1848_prepare_for_output(int dev, int bsize, int bcount)
-{
- int timeout;
- unsigned char fs, old_fs, tmp = 0;
- unsigned long flags;
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
- ad1848_port_info *portc = (ad1848_port_info *) audio_devs[dev]->portc;
-
- ad_mute(devc);
-
- spin_lock_irqsave(&devc->lock,flags);
- fs = portc->speed_bits | (portc->format_bits << 5);
-
- if (portc->channels > 1)
- fs |= 0x10;
-
- ad_enter_MCE(devc); /* Enables changes to the format select reg */
-
- if (devc->model == MD_1845 || devc->model == MD_1845_SSCAPE) /* Use alternate speed select registers */
- {
- fs &= 0xf0; /* Mask off the rate select bits */
-
- ad_write(devc, 22, (portc->speed >> 8) & 0xff); /* Speed MSB */
- ad_write(devc, 23, portc->speed & 0xff); /* Speed LSB */
- }
- old_fs = ad_read(devc, 8);
-
- if (devc->model == MD_4232 || devc->model >= MD_4236)
- {
- tmp = ad_read(devc, 16);
- ad_write(devc, 16, tmp | 0x30);
- }
- if (devc->model == MD_IWAVE)
- ad_write(devc, 17, 0xc2); /* Disable variable frequency select */
-
- ad_write(devc, 8, fs);
-
- /*
- * Write to I8 starts resynchronization. Wait until it completes.
- */
-
- timeout = 0;
- while (timeout < 100 && inb(devc->base) != 0x80)
- timeout++;
- timeout = 0;
- while (timeout < 10000 && inb(devc->base) == 0x80)
- timeout++;
-
- if (devc->model >= MD_4232)
- ad_write(devc, 16, tmp & ~0x30);
-
- ad_leave_MCE(devc); /*
- * Starts the calibration process.
- */
- spin_unlock_irqrestore(&devc->lock,flags);
- devc->xfer_count = 0;
-
-#ifndef EXCLUDE_TIMERS
- if (dev == timer_installed && devc->timer_running)
- if ((fs & 0x01) != (old_fs & 0x01))
- {
- ad1848_tmr_reprogram(dev);
- }
-#endif
- ad1848_halt_output(dev);
- return 0;
-}
-
-static int ad1848_prepare_for_input(int dev, int bsize, int bcount)
-{
- int timeout;
- unsigned char fs, old_fs, tmp = 0;
- unsigned long flags;
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
- ad1848_port_info *portc = (ad1848_port_info *) audio_devs[dev]->portc;
-
- if (devc->audio_mode)
- return 0;
-
- spin_lock_irqsave(&devc->lock,flags);
- fs = portc->speed_bits | (portc->format_bits << 5);
-
- if (portc->channels > 1)
- fs |= 0x10;
-
- ad_enter_MCE(devc); /* Enables changes to the format select reg */
-
- if ((devc->model == MD_1845) || (devc->model == MD_1845_SSCAPE)) /* Use alternate speed select registers */
- {
- fs &= 0xf0; /* Mask off the rate select bits */
-
- ad_write(devc, 22, (portc->speed >> 8) & 0xff); /* Speed MSB */
- ad_write(devc, 23, portc->speed & 0xff); /* Speed LSB */
- }
- if (devc->model == MD_4232)
- {
- tmp = ad_read(devc, 16);
- ad_write(devc, 16, tmp | 0x30);
- }
- if (devc->model == MD_IWAVE)
- ad_write(devc, 17, 0xc2); /* Disable variable frequency select */
-
- /*
- * If mode >= 2 (CS4231), set I28. It's the capture format register.
- */
-
- if (devc->model != MD_1848)
- {
- old_fs = ad_read(devc, 28);
- ad_write(devc, 28, fs);
-
- /*
- * Write to I28 starts resynchronization. Wait until it completes.
- */
-
- timeout = 0;
- while (timeout < 100 && inb(devc->base) != 0x80)
- timeout++;
-
- timeout = 0;
- while (timeout < 10000 && inb(devc->base) == 0x80)
- timeout++;
-
- if (devc->model != MD_1848 && devc->model != MD_1845 && devc->model != MD_1845_SSCAPE)
- {
- /*
- * CS4231 compatible devices don't have separate sampling rate selection
- * register for recording an playback. The I8 register is shared so we have to
- * set the speed encoding bits of it too.
- */
- unsigned char tmp = portc->speed_bits | (ad_read(devc, 8) & 0xf0);
-
- ad_write(devc, 8, tmp);
- /*
- * Write to I8 starts resynchronization. Wait until it completes.
- */
- timeout = 0;
- while (timeout < 100 && inb(devc->base) != 0x80)
- timeout++;
-
- timeout = 0;
- while (timeout < 10000 && inb(devc->base) == 0x80)
- timeout++;
- }
- }
- else
- { /* For AD1848 set I8. */
-
- old_fs = ad_read(devc, 8);
- ad_write(devc, 8, fs);
- /*
- * Write to I8 starts resynchronization. Wait until it completes.
- */
- timeout = 0;
- while (timeout < 100 && inb(devc->base) != 0x80)
- timeout++;
- timeout = 0;
- while (timeout < 10000 && inb(devc->base) == 0x80)
- timeout++;
- }
-
- if (devc->model == MD_4232)
- ad_write(devc, 16, tmp & ~0x30);
-
- ad_leave_MCE(devc); /*
- * Starts the calibration process.
- */
- spin_unlock_irqrestore(&devc->lock,flags);
- devc->xfer_count = 0;
-
-#ifndef EXCLUDE_TIMERS
- if (dev == timer_installed && devc->timer_running)
- {
- if ((fs & 0x01) != (old_fs & 0x01))
- {
- ad1848_tmr_reprogram(dev);
- }
- }
-#endif
- ad1848_halt_input(dev);
- return 0;
-}
-
-static void ad1848_halt(int dev)
-{
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
- ad1848_port_info *portc = (ad1848_port_info *) audio_devs[dev]->portc;
-
- unsigned char bits = ad_read(devc, 9);
-
- if (bits & 0x01 && (portc->open_mode & OPEN_WRITE))
- ad1848_halt_output(dev);
-
- if (bits & 0x02 && (portc->open_mode & OPEN_READ))
- ad1848_halt_input(dev);
- devc->audio_mode = 0;
-}
-
-static void ad1848_halt_input(int dev)
-{
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
- unsigned long flags;
-
- if (!(ad_read(devc, 9) & 0x02))
- return; /* Capture not enabled */
-
- spin_lock_irqsave(&devc->lock,flags);
-
- ad_mute(devc);
-
- {
- int tmout;
-
- if(!isa_dma_bridge_buggy)
- disable_dma(audio_devs[dev]->dmap_in->dma);
-
- for (tmout = 0; tmout < 100000; tmout++)
- if (ad_read(devc, 11) & 0x10)
- break;
- ad_write(devc, 9, ad_read(devc, 9) & ~0x02); /* Stop capture */
-
- if(!isa_dma_bridge_buggy)
- enable_dma(audio_devs[dev]->dmap_in->dma);
- devc->audio_mode &= ~PCM_ENABLE_INPUT;
- }
-
- outb(0, io_Status(devc)); /* Clear interrupt status */
- outb(0, io_Status(devc)); /* Clear interrupt status */
-
- devc->audio_mode &= ~PCM_ENABLE_INPUT;
-
- spin_unlock_irqrestore(&devc->lock,flags);
-}
-
-static void ad1848_halt_output(int dev)
-{
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
- unsigned long flags;
-
- if (!(ad_read(devc, 9) & 0x01))
- return; /* Playback not enabled */
-
- spin_lock_irqsave(&devc->lock,flags);
-
- ad_mute(devc);
- {
- int tmout;
-
- if(!isa_dma_bridge_buggy)
- disable_dma(audio_devs[dev]->dmap_out->dma);
-
- for (tmout = 0; tmout < 100000; tmout++)
- if (ad_read(devc, 11) & 0x10)
- break;
- ad_write(devc, 9, ad_read(devc, 9) & ~0x01); /* Stop playback */
-
- if(!isa_dma_bridge_buggy)
- enable_dma(audio_devs[dev]->dmap_out->dma);
-
- devc->audio_mode &= ~PCM_ENABLE_OUTPUT;
- }
-
- outb((0), io_Status(devc)); /* Clear interrupt status */
- outb((0), io_Status(devc)); /* Clear interrupt status */
-
- devc->audio_mode &= ~PCM_ENABLE_OUTPUT;
-
- spin_unlock_irqrestore(&devc->lock,flags);
-}
-
-static void ad1848_trigger(int dev, int state)
-{
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
- ad1848_port_info *portc = (ad1848_port_info *) audio_devs[dev]->portc;
- unsigned long flags;
- unsigned char tmp, old;
-
- spin_lock_irqsave(&devc->lock,flags);
- state &= devc->audio_mode;
-
- tmp = old = ad_read(devc, 9);
-
- if (portc->open_mode & OPEN_READ)
- {
- if (state & PCM_ENABLE_INPUT)
- tmp |= 0x02;
- else
- tmp &= ~0x02;
- }
- if (portc->open_mode & OPEN_WRITE)
- {
- if (state & PCM_ENABLE_OUTPUT)
- tmp |= 0x01;
- else
- tmp &= ~0x01;
- }
- /* ad_mute(devc); */
- if (tmp != old)
- {
- ad_write(devc, 9, tmp);
- ad_unmute(devc);
- }
- spin_unlock_irqrestore(&devc->lock,flags);
-}
-
-static void ad1848_init_hw(ad1848_info * devc)
-{
- int i;
- int *init_values;
-
- /*
- * Initial values for the indirect registers of CS4248/AD1848.
- */
- static int init_values_a[] =
- {
- 0xa8, 0xa8, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
- 0x00, 0x0c, 0x02, 0x00, 0x8a, 0x01, 0x00, 0x00,
-
- /* Positions 16 to 31 just for CS4231/2 and ad1845 */
- 0x80, 0x00, 0x10, 0x10, 0x00, 0x00, 0x1f, 0x40,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
-
- static int init_values_b[] =
- {
- /*
- Values for the newer chips
- Some of the register initialization values were changed. In
- order to get rid of the click that preceded PCM playback,
- calibration was disabled on the 10th byte. On that same byte,
- dual DMA was enabled; on the 11th byte, ADC dithering was
- enabled, since that is theoretically desirable; on the 13th
- byte, Mode 3 was selected, to enable access to extended
- registers.
- */
- 0xa8, 0xa8, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0x06, 0x00, 0xe0, 0x01, 0x00, 0x00,
- 0x80, 0x00, 0x10, 0x10, 0x00, 0x00, 0x1f, 0x40,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
-
- /*
- * Select initialisation data
- */
-
- init_values = init_values_a;
- if(devc->model >= MD_4236)
- init_values = init_values_b;
-
- for (i = 0; i < 16; i++)
- ad_write(devc, i, init_values[i]);
-
-
- ad_mute(devc); /* Initialize some variables */
- ad_unmute(devc); /* Leave it unmuted now */
-
- if (devc->model > MD_1848)
- {
- if (devc->model == MD_1845_SSCAPE)
- ad_write(devc, 12, ad_read(devc, 12) | 0x50);
- else
- ad_write(devc, 12, ad_read(devc, 12) | 0x40); /* Mode2 = enabled */
-
- if (devc->model == MD_IWAVE)
- ad_write(devc, 12, 0x6c); /* Select codec mode 3 */
-
- if (devc->model != MD_1845_SSCAPE)
- for (i = 16; i < 32; i++)
- ad_write(devc, i, init_values[i]);
-
- if (devc->model == MD_IWAVE)
- ad_write(devc, 16, 0x30); /* Playback and capture counters enabled */
- }
- if (devc->model > MD_1848)
- {
- if (devc->audio_flags & DMA_DUPLEX)
- ad_write(devc, 9, ad_read(devc, 9) & ~0x04); /* Dual DMA mode */
- else
- ad_write(devc, 9, ad_read(devc, 9) | 0x04); /* Single DMA mode */
-
- if (devc->model == MD_1845 || devc->model == MD_1845_SSCAPE)
- ad_write(devc, 27, ad_read(devc, 27) | 0x08); /* Alternate freq select enabled */
-
- if (devc->model == MD_IWAVE)
- { /* Some magic Interwave specific initialization */
- ad_write(devc, 12, 0x6c); /* Select codec mode 3 */
- ad_write(devc, 16, 0x30); /* Playback and capture counters enabled */
- ad_write(devc, 17, 0xc2); /* Alternate feature enable */
- }
- }
- else
- {
- devc->audio_flags &= ~DMA_DUPLEX;
- ad_write(devc, 9, ad_read(devc, 9) | 0x04); /* Single DMA mode */
- if (soundpro)
- ad_write(devc, 12, ad_read(devc, 12) | 0x40); /* Mode2 = enabled */
- }
-
- outb((0), io_Status(devc)); /* Clear pending interrupts */
-
- /*
- * Toggle the MCE bit. It completes the initialization phase.
- */
-
- ad_enter_MCE(devc); /* In case the bit was off */
- ad_leave_MCE(devc);
-
- ad1848_mixer_reset(devc);
-}
-
-int ad1848_detect(struct resource *ports, int *ad_flags, int *osp)
-{
- unsigned char tmp;
- ad1848_info *devc = &adev_info[nr_ad1848_devs];
- unsigned char tmp1 = 0xff, tmp2 = 0xff;
- int optiC930 = 0; /* OPTi 82C930 flag */
- int interwave = 0;
- int ad1847_flag = 0;
- int cs4248_flag = 0;
- int sscape_flag = 0;
- int io_base = ports->start;
-
- int i;
-
- DDB(printk("ad1848_detect(%x)\n", io_base));
-
- if (ad_flags)
- {
- if (*ad_flags == 0x12345678)
- {
- interwave = 1;
- *ad_flags = 0;
- }
-
- if (*ad_flags == 0x87654321)
- {
- sscape_flag = 1;
- *ad_flags = 0;
- }
-
- if (*ad_flags == 0x12345677)
- {
- cs4248_flag = 1;
- *ad_flags = 0;
- }
- }
- if (nr_ad1848_devs >= MAX_AUDIO_DEV)
- {
- printk(KERN_ERR "ad1848 - Too many audio devices\n");
- return 0;
- }
- spin_lock_init(&devc->lock);
- devc->base = io_base;
- devc->irq_ok = 0;
- devc->timer_running = 0;
- devc->MCE_bit = 0x40;
- devc->irq = 0;
- devc->open_mode = 0;
- devc->chip_name = devc->name = "AD1848";
- devc->model = MD_1848; /* AD1848 or CS4248 */
- devc->levels = NULL;
- devc->debug_flag = 0;
-
- /*
- * Check that the I/O address is in use.
- *
- * The bit 0x80 of the base I/O port is known to be 0 after the
- * chip has performed its power on initialization. Just assume
- * this has happened before the OS is starting.
- *
- * If the I/O address is unused, it typically returns 0xff.
- */
-
- if (inb(devc->base) == 0xff)
- {
- DDB(printk("ad1848_detect: The base I/O address appears to be dead\n"));
- }
-
- /*
- * Wait for the device to stop initialization
- */
-
- DDB(printk("ad1848_detect() - step 0\n"));
-
- for (i = 0; i < 10000000; i++)
- {
- unsigned char x = inb(devc->base);
-
- if (x == 0xff || !(x & 0x80))
- break;
- }
-
- DDB(printk("ad1848_detect() - step A\n"));
-
- if (inb(devc->base) == 0x80) /* Not ready. Let's wait */
- ad_leave_MCE(devc);
-
- if ((inb(devc->base) & 0x80) != 0x00) /* Not a AD1848 */
- {
- DDB(printk("ad1848 detect error - step A (%02x)\n", (int) inb(devc->base)));
- return 0;
- }
-
- /*
- * Test if it's possible to change contents of the indirect registers.
- * Registers 0 and 1 are ADC volume registers. The bit 0x10 is read only
- * so try to avoid using it.
- */
-
- DDB(printk("ad1848_detect() - step B\n"));
- ad_write(devc, 0, 0xaa);
- ad_write(devc, 1, 0x45); /* 0x55 with bit 0x10 clear */
-
- if ((tmp1 = ad_read(devc, 0)) != 0xaa || (tmp2 = ad_read(devc, 1)) != 0x45)
- {
- if (tmp2 == 0x65) /* AD1847 has couple of bits hardcoded to 1 */
- ad1847_flag = 1;
- else
- {
- DDB(printk("ad1848 detect error - step B (%x/%x)\n", tmp1, tmp2));
- return 0;
- }
- }
- DDB(printk("ad1848_detect() - step C\n"));
- ad_write(devc, 0, 0x45);
- ad_write(devc, 1, 0xaa);
-
- if ((tmp1 = ad_read(devc, 0)) != 0x45 || (tmp2 = ad_read(devc, 1)) != 0xaa)
- {
- if (tmp2 == 0x8a) /* AD1847 has few bits hardcoded to 1 */
- ad1847_flag = 1;
- else
- {
- DDB(printk("ad1848 detect error - step C (%x/%x)\n", tmp1, tmp2));
- return 0;
- }
- }
-
- /*
- * The indirect register I12 has some read only bits. Let's
- * try to change them.
- */
-
- DDB(printk("ad1848_detect() - step D\n"));
- tmp = ad_read(devc, 12);
- ad_write(devc, 12, (~tmp) & 0x0f);
-
- if ((tmp & 0x0f) != ((tmp1 = ad_read(devc, 12)) & 0x0f))
- {
- DDB(printk("ad1848 detect error - step D (%x)\n", tmp1));
- return 0;
- }
-
- /*
- * NOTE! Last 4 bits of the reg I12 tell the chip revision.
- * 0x01=RevB and 0x0A=RevC.
- */
-
- /*
- * The original AD1848/CS4248 has just 15 indirect registers. This means
- * that I0 and I16 should return the same value (etc.).
- * However this doesn't work with CS4248. Actually it seems to be impossible
- * to detect if the chip is a CS4231 or CS4248.
- * Ensure that the Mode2 enable bit of I12 is 0. Otherwise this test fails
- * with CS4231.
- */
-
- /*
- * OPTi 82C930 has mode2 control bit in another place. This test will fail
- * with it. Accept this situation as a possible indication of this chip.
- */
-
- DDB(printk("ad1848_detect() - step F\n"));
- ad_write(devc, 12, 0); /* Mode2=disabled */
-
- for (i = 0; i < 16; i++)
- {
- if ((tmp1 = ad_read(devc, i)) != (tmp2 = ad_read(devc, i + 16)))
- {
- DDB(printk("ad1848 detect step F(%d/%x/%x) - OPTi chip???\n", i, tmp1, tmp2));
- if (!ad1847_flag)
- optiC930 = 1;
- break;
- }
- }
-
- /*
- * Try to switch the chip to mode2 (CS4231) by setting the MODE2 bit (0x40).
- * The bit 0x80 is always 1 in CS4248 and CS4231.
- */
-
- DDB(printk("ad1848_detect() - step G\n"));
-
- if (ad_flags && *ad_flags == 400)
- *ad_flags = 0;
- else
- ad_write(devc, 12, 0x40); /* Set mode2, clear 0x80 */
-
-
- if (ad_flags)
- *ad_flags = 0;
-
- tmp1 = ad_read(devc, 12);
- if (tmp1 & 0x80)
- {
- if (ad_flags)
- *ad_flags |= AD_F_CS4248;
-
- devc->chip_name = "CS4248"; /* Our best knowledge just now */
- }
- if (optiC930 || (tmp1 & 0xc0) == (0x80 | 0x40))
- {
- /*
- * CS4231 detected - is it?
- *
- * Verify that setting I0 doesn't change I16.
- */
-
- DDB(printk("ad1848_detect() - step H\n"));
- ad_write(devc, 16, 0); /* Set I16 to known value */
-
- ad_write(devc, 0, 0x45);
- if ((tmp1 = ad_read(devc, 16)) != 0x45) /* No change -> CS4231? */
- {
- ad_write(devc, 0, 0xaa);
- if ((tmp1 = ad_read(devc, 16)) == 0xaa) /* Rotten bits? */
- {
- DDB(printk("ad1848 detect error - step H(%x)\n", tmp1));
- return 0;
- }
-
- /*
- * Verify that some bits of I25 are read only.
- */
-
- DDB(printk("ad1848_detect() - step I\n"));
- tmp1 = ad_read(devc, 25); /* Original bits */
- ad_write(devc, 25, ~tmp1); /* Invert all bits */
- if ((ad_read(devc, 25) & 0xe7) == (tmp1 & 0xe7))
- {
- int id;
-
- /*
- * It's at least CS4231
- */
-
- devc->chip_name = "CS4231";
- devc->model = MD_4231;
-
- /*
- * It could be an AD1845 or CS4231A as well.
- * CS4231 and AD1845 report the same revision info in I25
- * while the CS4231A reports different.
- */
-
- id = ad_read(devc, 25);
- if ((id & 0xe7) == 0x80) /* Device busy??? */
- id = ad_read(devc, 25);
- if ((id & 0xe7) == 0x80) /* Device still busy??? */
- id = ad_read(devc, 25);
- DDB(printk("ad1848_detect() - step J (%02x/%02x)\n", id, ad_read(devc, 25)));
-
- if ((id & 0xe7) == 0x80) {
- /*
- * It must be a CS4231 or AD1845. The register I23 of
- * CS4231 is undefined and it appears to be read only.
- * AD1845 uses I23 for setting sample rate. Assume
- * the chip is AD1845 if I23 is changeable.
- */
-
- unsigned char tmp = ad_read(devc, 23);
- ad_write(devc, 23, ~tmp);
-
- if (interwave)
- {
- devc->model = MD_IWAVE;
- devc->chip_name = "IWave";
- }
- else if (ad_read(devc, 23) != tmp) /* AD1845 ? */
- {
- devc->chip_name = "AD1845";
- devc->model = MD_1845;
- }
- else if (cs4248_flag)
- {
- if (ad_flags)
- *ad_flags |= AD_F_CS4248;
- devc->chip_name = "CS4248";
- devc->model = MD_1848;
- ad_write(devc, 12, ad_read(devc, 12) & ~0x40); /* Mode2 off */
- }
- ad_write(devc, 23, tmp); /* Restore */
- }
- else
- {
- switch (id & 0x1f) {
- case 3: /* CS4236/CS4235/CS42xB/CS4239 */
- {
- int xid;
- ad_write(devc, 12, ad_read(devc, 12) | 0x60); /* switch to mode 3 */
- ad_write(devc, 23, 0x9c); /* select extended register 25 */
- xid = inb(io_Indexed_Data(devc));
- ad_write(devc, 12, ad_read(devc, 12) & ~0x60); /* back to mode 0 */
- switch (xid & 0x1f)
- {
- case 0x00:
- devc->chip_name = "CS4237B(B)";
- devc->model = MD_42xB;
- break;
- case 0x08:
- /* Seems to be a 4238 ?? */
- devc->chip_name = "CS4238";
- devc->model = MD_42xB;
- break;
- case 0x09:
- devc->chip_name = "CS4238B";
- devc->model = MD_42xB;
- break;
- case 0x0b:
- devc->chip_name = "CS4236B";
- devc->model = MD_4236;
- break;
- case 0x10:
- devc->chip_name = "CS4237B";
- devc->model = MD_42xB;
- break;
- case 0x1d:
- devc->chip_name = "CS4235";
- devc->model = MD_4235;
- break;
- case 0x1e:
- devc->chip_name = "CS4239";
- devc->model = MD_4239;
- break;
- default:
- printk("Chip ident is %X.\n", xid&0x1F);
- devc->chip_name = "CS42xx";
- devc->model = MD_4232;
- break;
- }
- }
- break;
-
- case 2: /* CS4232/CS4232A */
- devc->chip_name = "CS4232";
- devc->model = MD_4232;
- break;
-
- case 0:
- if ((id & 0xe0) == 0xa0)
- {
- devc->chip_name = "CS4231A";
- devc->model = MD_4231A;
- }
- else
- {
- devc->chip_name = "CS4321";
- devc->model = MD_4231;
- }
- break;
-
- default: /* maybe */
- DDB(printk("ad1848: I25 = %02x/%02x\n", ad_read(devc, 25), ad_read(devc, 25) & 0xe7));
- if (optiC930)
- {
- devc->chip_name = "82C930";
- devc->model = MD_C930;
- }
- else
- {
- devc->chip_name = "CS4231";
- devc->model = MD_4231;
- }
- }
- }
- }
- ad_write(devc, 25, tmp1); /* Restore bits */
-
- DDB(printk("ad1848_detect() - step K\n"));
- }
- } else if (tmp1 == 0x0a) {
- /*
- * Is it perhaps a SoundPro CMI8330?
- * If so, then we should be able to change indirect registers
- * greater than I15 after activating MODE2, even though reading
- * back I12 does not show it.
- */
-
- /*
- * Let's try comparing register values
- */
- for (i = 0; i < 16; i++) {
- if ((tmp1 = ad_read(devc, i)) != (tmp2 = ad_read(devc, i + 16))) {
- DDB(printk("ad1848 detect step H(%d/%x/%x) - SoundPro chip?\n", i, tmp1, tmp2));
- soundpro = 1;
- devc->chip_name = "SoundPro CMI 8330";
- break;
- }
- }
- }
-
- DDB(printk("ad1848_detect() - step L\n"));
- if (ad_flags)
- {
- if (devc->model != MD_1848)
- *ad_flags |= AD_F_CS4231;
- }
- DDB(printk("ad1848_detect() - Detected OK\n"));
-
- if (devc->model == MD_1848 && ad1847_flag)
- devc->chip_name = "AD1847";
-
-
- if (sscape_flag == 1)
- devc->model = MD_1845_SSCAPE;
-
- return 1;
-}
-
-int ad1848_init (char *name, struct resource *ports, int irq, int dma_playback,
- int dma_capture, int share_dma, int *osp, struct module *owner)
-{
- /*
- * NOTE! If irq < 0, there is another driver which has allocated the IRQ
- * so that this driver doesn't need to allocate/deallocate it.
- * The actually used IRQ is ABS(irq).
- */
-
- int my_dev;
- char dev_name[100];
- int e;
-
- ad1848_info *devc = &adev_info[nr_ad1848_devs];
-
- ad1848_port_info *portc = NULL;
-
- devc->irq = (irq > 0) ? irq : 0;
- devc->open_mode = 0;
- devc->timer_ticks = 0;
- devc->dma1 = dma_playback;
- devc->dma2 = dma_capture;
- devc->subtype = cfg.card_subtype;
- devc->audio_flags = DMA_AUTOMODE;
- devc->playback_dev = devc->record_dev = 0;
- if (name != NULL)
- devc->name = name;
-
- if (name != NULL && name[0] != 0)
- sprintf(dev_name,
- "%s (%s)", name, devc->chip_name);
- else
- sprintf(dev_name,
- "Generic audio codec (%s)", devc->chip_name);
-
- rename_region(ports, devc->name);
-
- conf_printf2(dev_name, devc->base, devc->irq, dma_playback, dma_capture);
-
- if (devc->model == MD_1848 || devc->model == MD_C930)
- devc->audio_flags |= DMA_HARDSTOP;
-
- if (devc->model > MD_1848)
- {
- if (devc->dma1 == devc->dma2 || devc->dma2 == -1 || devc->dma1 == -1)
- devc->audio_flags &= ~DMA_DUPLEX;
- else
- devc->audio_flags |= DMA_DUPLEX;
- }
-
- portc = kmalloc(sizeof(ad1848_port_info), GFP_KERNEL);
- if(portc==NULL) {
- release_region(devc->base, 4);
- return -1;
- }
-
- if ((my_dev = sound_install_audiodrv(AUDIO_DRIVER_VERSION,
- dev_name,
- &ad1848_audio_driver,
- sizeof(struct audio_driver),
- devc->audio_flags,
- ad_format_mask[devc->model],
- devc,
- dma_playback,
- dma_capture)) < 0)
- {
- release_region(devc->base, 4);
- kfree(portc);
- return -1;
- }
-
- audio_devs[my_dev]->portc = portc;
- audio_devs[my_dev]->mixer_dev = -1;
- if (owner)
- audio_devs[my_dev]->d->owner = owner;
- memset((char *) portc, 0, sizeof(*portc));
-
- nr_ad1848_devs++;
-
- ad1848_init_hw(devc);
-
- if (irq > 0)
- {
- devc->dev_no = my_dev;
- if (request_irq(devc->irq, adintr, 0, devc->name,
- (void *)(long)my_dev) < 0)
- {
- printk(KERN_WARNING "ad1848: Unable to allocate IRQ\n");
- /* Don't free it either then.. */
- devc->irq = 0;
- }
- if (capabilities[devc->model].flags & CAP_F_TIMER)
- {
-#ifndef CONFIG_SMP
- int x;
- unsigned char tmp = ad_read(devc, 16);
-#endif
-
- devc->timer_ticks = 0;
-
- ad_write(devc, 21, 0x00); /* Timer MSB */
- ad_write(devc, 20, 0x10); /* Timer LSB */
-#ifndef CONFIG_SMP
- ad_write(devc, 16, tmp | 0x40); /* Enable timer */
- for (x = 0; x < 100000 && devc->timer_ticks == 0; x++);
- ad_write(devc, 16, tmp & ~0x40); /* Disable timer */
-
- if (devc->timer_ticks == 0)
- printk(KERN_WARNING "ad1848: Interrupt test failed (IRQ%d)\n", irq);
- else
- {
- DDB(printk("Interrupt test OK\n"));
- devc->irq_ok = 1;
- }
-#else
- devc->irq_ok = 1;
-#endif
- }
- else
- devc->irq_ok = 1; /* Couldn't test. assume it's OK */
- } else if (irq < 0)
- irq2dev[-irq] = devc->dev_no = my_dev;
-
-#ifndef EXCLUDE_TIMERS
- if ((capabilities[devc->model].flags & CAP_F_TIMER) &&
- devc->irq_ok)
- ad1848_tmr_install(my_dev);
-#endif
-
- if (!share_dma)
- {
- if (sound_alloc_dma(dma_playback, devc->name))
- printk(KERN_WARNING "ad1848.c: Can't allocate DMA%d\n", dma_playback);
-
- if (dma_capture != dma_playback)
- if (sound_alloc_dma(dma_capture, devc->name))
- printk(KERN_WARNING "ad1848.c: Can't allocate DMA%d\n", dma_capture);
- }
-
- if ((e = sound_install_mixer(MIXER_DRIVER_VERSION,
- dev_name,
- &ad1848_mixer_operations,
- sizeof(struct mixer_operations),
- devc)) >= 0)
- {
- audio_devs[my_dev]->mixer_dev = e;
- if (owner)
- mixer_devs[e]->owner = owner;
- }
- return my_dev;
-}
-
-int ad1848_control(int cmd, int arg)
-{
- ad1848_info *devc;
- unsigned long flags;
-
- if (nr_ad1848_devs < 1)
- return -ENODEV;
-
- devc = &adev_info[nr_ad1848_devs - 1];
-
- switch (cmd)
- {
- case AD1848_SET_XTAL: /* Change clock frequency of AD1845 (only ) */
- if (devc->model != MD_1845 && devc->model != MD_1845_SSCAPE)
- return -EINVAL;
- spin_lock_irqsave(&devc->lock,flags);
- ad_enter_MCE(devc);
- ad_write(devc, 29, (ad_read(devc, 29) & 0x1f) | (arg << 5));
- ad_leave_MCE(devc);
- spin_unlock_irqrestore(&devc->lock,flags);
- break;
-
- case AD1848_MIXER_REROUTE:
- {
- int o = (arg >> 8) & 0xff;
- int n = arg & 0xff;
-
- if (o < 0 || o >= SOUND_MIXER_NRDEVICES)
- return -EINVAL;
-
- if (!(devc->supported_devices & (1 << o)) &&
- !(devc->supported_rec_devices & (1 << o)))
- return -EINVAL;
-
- if (n == SOUND_MIXER_NONE)
- { /* Just hide this control */
- ad1848_mixer_set(devc, o, 0); /* Shut up it */
- devc->supported_devices &= ~(1 << o);
- devc->supported_rec_devices &= ~(1 << o);
- break;
- }
-
- /* Make the mixer control identified by o to appear as n */
- if (n < 0 || n >= SOUND_MIXER_NRDEVICES)
- return -EINVAL;
-
- devc->mixer_reroute[n] = o; /* Rename the control */
- if (devc->supported_devices & (1 << o))
- devc->supported_devices |= (1 << n);
- if (devc->supported_rec_devices & (1 << o))
- devc->supported_rec_devices |= (1 << n);
-
- devc->supported_devices &= ~(1 << o);
- devc->supported_rec_devices &= ~(1 << o);
- }
- break;
- }
- return 0;
-}
-
-void ad1848_unload(int io_base, int irq, int dma_playback, int dma_capture, int share_dma)
-{
- int i, mixer, dev = 0;
- ad1848_info *devc = NULL;
-
- for (i = 0; devc == NULL && i < nr_ad1848_devs; i++)
- {
- if (adev_info[i].base == io_base)
- {
- devc = &adev_info[i];
- dev = devc->dev_no;
- }
- }
-
- if (devc != NULL)
- {
- kfree(audio_devs[dev]->portc);
- release_region(devc->base, 4);
-
- if (!share_dma)
- {
- if (devc->irq > 0) /* There is no point in freeing irq, if it wasn't allocated */
- free_irq(devc->irq, (void *)(long)devc->dev_no);
-
- sound_free_dma(dma_playback);
-
- if (dma_playback != dma_capture)
- sound_free_dma(dma_capture);
-
- }
- mixer = audio_devs[devc->dev_no]->mixer_dev;
- if(mixer>=0)
- sound_unload_mixerdev(mixer);
-
- nr_ad1848_devs--;
- for ( ; i < nr_ad1848_devs ; i++)
- adev_info[i] = adev_info[i+1];
- }
- else
- printk(KERN_ERR "ad1848: Can't find device to be unloaded. Base=%x\n", io_base);
-}
-
-static irqreturn_t adintr(int irq, void *dev_id)
-{
- unsigned char status;
- ad1848_info *devc;
- int dev;
- int alt_stat = 0xff;
- unsigned char c930_stat = 0;
- int cnt = 0;
-
- dev = (long)dev_id;
- devc = (ad1848_info *) audio_devs[dev]->devc;
-
-interrupt_again: /* Jump back here if int status doesn't reset */
-
- status = inb(io_Status(devc));
-
- if (status == 0x80)
- printk(KERN_DEBUG "adintr: Why?\n");
- if (devc->model == MD_1848)
- outb((0), io_Status(devc)); /* Clear interrupt status */
-
- if (status & 0x01)
- {
- if (devc->model == MD_C930)
- { /* 82C930 has interrupt status register in MAD16 register MC11 */
-
- spin_lock(&devc->lock);
-
- /* 0xe0e is C930 address port
- * 0xe0f is C930 data port
- */
- outb(11, 0xe0e);
- c930_stat = inb(0xe0f);
- outb((~c930_stat), 0xe0f);
-
- spin_unlock(&devc->lock);
-
- alt_stat = (c930_stat << 2) & 0x30;
- }
- else if (devc->model != MD_1848)
- {
- spin_lock(&devc->lock);
- alt_stat = ad_read(devc, 24);
- ad_write(devc, 24, ad_read(devc, 24) & ~alt_stat); /* Selective ack */
- spin_unlock(&devc->lock);
- }
-
- if ((devc->open_mode & OPEN_READ) && (devc->audio_mode & PCM_ENABLE_INPUT) && (alt_stat & 0x20))
- {
- DMAbuf_inputintr(devc->record_dev);
- }
- if ((devc->open_mode & OPEN_WRITE) && (devc->audio_mode & PCM_ENABLE_OUTPUT) &&
- (alt_stat & 0x10))
- {
- DMAbuf_outputintr(devc->playback_dev, 1);
- }
- if (devc->model != MD_1848 && (alt_stat & 0x40)) /* Timer interrupt */
- {
- devc->timer_ticks++;
-#ifndef EXCLUDE_TIMERS
- if (timer_installed == dev && devc->timer_running)
- sound_timer_interrupt();
-#endif
- }
- }
-/*
- * Sometimes playback or capture interrupts occur while a timer interrupt
- * is being handled. The interrupt will not be retriggered if we don't
- * handle it now. Check if an interrupt is still pending and restart
- * the handler in this case.
- */
- if (inb(io_Status(devc)) & 0x01 && cnt++ < 4)
- {
- goto interrupt_again;
- }
- return IRQ_HANDLED;
-}
-
-/*
- * Experimental initialization sequence for the integrated sound system
- * of the Compaq Deskpro M.
- */
-
-static int init_deskpro_m(struct address_info *hw_config)
-{
- unsigned char tmp;
-
- if ((tmp = inb(0xc44)) == 0xff)
- {
- DDB(printk("init_deskpro_m: Dead port 0xc44\n"));
- return 0;
- }
-
- outb(0x10, 0xc44);
- outb(0x40, 0xc45);
- outb(0x00, 0xc46);
- outb(0xe8, 0xc47);
- outb(0x14, 0xc44);
- outb(0x40, 0xc45);
- outb(0x00, 0xc46);
- outb(0xe8, 0xc47);
- outb(0x10, 0xc44);
-
- return 1;
-}
-
-/*
- * Experimental initialization sequence for the integrated sound system
- * of Compaq Deskpro XL.
- */
-
-static int init_deskpro(struct address_info *hw_config)
-{
- unsigned char tmp;
-
- if ((tmp = inb(0xc44)) == 0xff)
- {
- DDB(printk("init_deskpro: Dead port 0xc44\n"));
- return 0;
- }
- outb((tmp | 0x04), 0xc44); /* Select bank 1 */
- if (inb(0xc44) != 0x04)
- {
- DDB(printk("init_deskpro: Invalid bank1 signature in port 0xc44\n"));
- return 0;
- }
- /*
- * OK. It looks like a Deskpro so let's proceed.
- */
-
- /*
- * I/O port 0xc44 Audio configuration register.
- *
- * bits 0xc0: Audio revision bits
- * 0x00 = Compaq Business Audio
- * 0x40 = MS Sound System Compatible (reset default)
- * 0x80 = Reserved
- * 0xc0 = Reserved
- * bit 0x20: No Wait State Enable
- * 0x00 = Disabled (reset default, DMA mode)
- * 0x20 = Enabled (programmed I/O mode)
- * bit 0x10: MS Sound System Decode Enable
- * 0x00 = Decoding disabled (reset default)
- * 0x10 = Decoding enabled
- * bit 0x08: FM Synthesis Decode Enable
- * 0x00 = Decoding Disabled (reset default)
- * 0x08 = Decoding enabled
- * bit 0x04 Bank select
- * 0x00 = Bank 0
- * 0x04 = Bank 1
- * bits 0x03 MSS Base address
- * 0x00 = 0x530 (reset default)
- * 0x01 = 0x604
- * 0x02 = 0xf40
- * 0x03 = 0xe80
- */
-
-#ifdef DEBUGXL
- /* Debug printing */
- printk("Port 0xc44 (before): ");
- outb((tmp & ~0x04), 0xc44);
- printk("%02x ", inb(0xc44));
- outb((tmp | 0x04), 0xc44);
- printk("%02x\n", inb(0xc44));
-#endif
-
- /* Set bank 1 of the register */
- tmp = 0x58; /* MSS Mode, MSS&FM decode enabled */
-
- switch (hw_config->io_base)
- {
- case 0x530:
- tmp |= 0x00;
- break;
- case 0x604:
- tmp |= 0x01;
- break;
- case 0xf40:
- tmp |= 0x02;
- break;
- case 0xe80:
- tmp |= 0x03;
- break;
- default:
- DDB(printk("init_deskpro: Invalid MSS port %x\n", hw_config->io_base));
- return 0;
- }
- outb((tmp & ~0x04), 0xc44); /* Write to bank=0 */
-
-#ifdef DEBUGXL
- /* Debug printing */
- printk("Port 0xc44 (after): ");
- outb((tmp & ~0x04), 0xc44); /* Select bank=0 */
- printk("%02x ", inb(0xc44));
- outb((tmp | 0x04), 0xc44); /* Select bank=1 */
- printk("%02x\n", inb(0xc44));
-#endif
-
- /*
- * I/O port 0xc45 FM Address Decode/MSS ID Register.
- *
- * bank=0, bits 0xfe: FM synthesis Decode Compare bits 7:1 (default=0x88)
- * bank=0, bit 0x01: SBIC Power Control Bit
- * 0x00 = Powered up
- * 0x01 = Powered down
- * bank=1, bits 0xfc: MSS ID (default=0x40)
- */
-
-#ifdef DEBUGXL
- /* Debug printing */
- printk("Port 0xc45 (before): ");
- outb((tmp & ~0x04), 0xc44); /* Select bank=0 */
- printk("%02x ", inb(0xc45));
- outb((tmp | 0x04), 0xc44); /* Select bank=1 */
- printk("%02x\n", inb(0xc45));
-#endif
-
- outb((tmp & ~0x04), 0xc44); /* Select bank=0 */
- outb((0x88), 0xc45); /* FM base 7:0 = 0x88 */
- outb((tmp | 0x04), 0xc44); /* Select bank=1 */
- outb((0x10), 0xc45); /* MSS ID = 0x10 (MSS port returns 0x04) */
-
-#ifdef DEBUGXL
- /* Debug printing */
- printk("Port 0xc45 (after): ");
- outb((tmp & ~0x04), 0xc44); /* Select bank=0 */
- printk("%02x ", inb(0xc45));
- outb((tmp | 0x04), 0xc44); /* Select bank=1 */
- printk("%02x\n", inb(0xc45));
-#endif
-
-
- /*
- * I/O port 0xc46 FM Address Decode/Address ASIC Revision Register.
- *
- * bank=0, bits 0xff: FM synthesis Decode Compare bits 15:8 (default=0x03)
- * bank=1, bits 0xff: Audio addressing ASIC id
- */
-
-#ifdef DEBUGXL
- /* Debug printing */
- printk("Port 0xc46 (before): ");
- outb((tmp & ~0x04), 0xc44); /* Select bank=0 */
- printk("%02x ", inb(0xc46));
- outb((tmp | 0x04), 0xc44); /* Select bank=1 */
- printk("%02x\n", inb(0xc46));
-#endif
-
- outb((tmp & ~0x04), 0xc44); /* Select bank=0 */
- outb((0x03), 0xc46); /* FM base 15:8 = 0x03 */
- outb((tmp | 0x04), 0xc44); /* Select bank=1 */
- outb((0x11), 0xc46); /* ASIC ID = 0x11 */
-
-#ifdef DEBUGXL
- /* Debug printing */
- printk("Port 0xc46 (after): ");
- outb((tmp & ~0x04), 0xc44); /* Select bank=0 */
- printk("%02x ", inb(0xc46));
- outb((tmp | 0x04), 0xc44); /* Select bank=1 */
- printk("%02x\n", inb(0xc46));
-#endif
-
- /*
- * I/O port 0xc47 FM Address Decode Register.
- *
- * bank=0, bits 0xff: Decode enable selection for various FM address bits
- * bank=1, bits 0xff: Reserved
- */
-
-#ifdef DEBUGXL
- /* Debug printing */
- printk("Port 0xc47 (before): ");
- outb((tmp & ~0x04), 0xc44); /* Select bank=0 */
- printk("%02x ", inb(0xc47));
- outb((tmp | 0x04), 0xc44); /* Select bank=1 */
- printk("%02x\n", inb(0xc47));
-#endif
-
- outb((tmp & ~0x04), 0xc44); /* Select bank=0 */
- outb((0x7c), 0xc47); /* FM decode enable bits = 0x7c */
- outb((tmp | 0x04), 0xc44); /* Select bank=1 */
- outb((0x00), 0xc47); /* Reserved bank1 = 0x00 */
-
-#ifdef DEBUGXL
- /* Debug printing */
- printk("Port 0xc47 (after): ");
- outb((tmp & ~0x04), 0xc44); /* Select bank=0 */
- printk("%02x ", inb(0xc47));
- outb((tmp | 0x04), 0xc44); /* Select bank=1 */
- printk("%02x\n", inb(0xc47));
-#endif
-
- /*
- * I/O port 0xc6f = Audio Disable Function Register
- */
-
-#ifdef DEBUGXL
- printk("Port 0xc6f (before) = %02x\n", inb(0xc6f));
-#endif
-
- outb((0x80), 0xc6f);
-
-#ifdef DEBUGXL
- printk("Port 0xc6f (after) = %02x\n", inb(0xc6f));
-#endif
-
- return 1;
-}
-
-int probe_ms_sound(struct address_info *hw_config, struct resource *ports)
-{
- unsigned char tmp;
-
- DDB(printk("Entered probe_ms_sound(%x, %d)\n", hw_config->io_base, hw_config->card_subtype));
-
- if (hw_config->card_subtype == 1) /* Has no IRQ/DMA registers */
- {
- /* check_opl3(0x388, hw_config); */
- return ad1848_detect(ports, NULL, hw_config->osp);
- }
-
- if (deskpro_xl && hw_config->card_subtype == 2) /* Compaq Deskpro XL */
- {
- if (!init_deskpro(hw_config))
- return 0;
- }
-
- if (deskpro_m) /* Compaq Deskpro M */
- {
- if (!init_deskpro_m(hw_config))
- return 0;
- }
-
- /*
- * Check if the IO port returns valid signature. The original MS Sound
- * system returns 0x04 while some cards (AudioTrix Pro for example)
- * return 0x00 or 0x0f.
- */
-
- if ((tmp = inb(hw_config->io_base + 3)) == 0xff) /* Bus float */
- {
- int ret;
-
- DDB(printk("I/O address is inactive (%x)\n", tmp));
- if (!(ret = ad1848_detect(ports, NULL, hw_config->osp)))
- return 0;
- return 1;
- }
- DDB(printk("MSS signature = %x\n", tmp & 0x3f));
- if ((tmp & 0x3f) != 0x04 &&
- (tmp & 0x3f) != 0x0f &&
- (tmp & 0x3f) != 0x00)
- {
- int ret;
-
- MDB(printk(KERN_ERR "No MSS signature detected on port 0x%x (0x%x)\n", hw_config->io_base, (int) inb(hw_config->io_base + 3)));
- DDB(printk("Trying to detect codec anyway but IRQ/DMA may not work\n"));
- if (!(ret = ad1848_detect(ports, NULL, hw_config->osp)))
- return 0;
-
- hw_config->card_subtype = 1;
- return 1;
- }
- if ((hw_config->irq != 5) &&
- (hw_config->irq != 7) &&
- (hw_config->irq != 9) &&
- (hw_config->irq != 10) &&
- (hw_config->irq != 11) &&
- (hw_config->irq != 12))
- {
- printk(KERN_ERR "MSS: Bad IRQ %d\n", hw_config->irq);
- return 0;
- }
- if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)
- {
- printk(KERN_ERR "MSS: Bad DMA %d\n", hw_config->dma);
- return 0;
- }
- /*
- * Check that DMA0 is not in use with a 8 bit board.
- */
-
- if (hw_config->dma == 0 && inb(hw_config->io_base + 3) & 0x80)
- {
- printk(KERN_ERR "MSS: Can't use DMA0 with a 8 bit card/slot\n");
- return 0;
- }
- if (hw_config->irq > 7 && hw_config->irq != 9 && inb(hw_config->io_base + 3) & 0x80)
- {
- printk(KERN_ERR "MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
- return 0;
- }
- return ad1848_detect(ports, NULL, hw_config->osp);
-}
-
-void attach_ms_sound(struct address_info *hw_config, struct resource *ports, struct module *owner)
-{
- static signed char interrupt_bits[12] =
- {
- -1, -1, -1, -1, -1, 0x00, -1, 0x08, -1, 0x10, 0x18, 0x20
- };
- signed char bits;
- char dma2_bit = 0;
-
- static char dma_bits[4] =
- {
- 1, 2, 0, 3
- };
-
- int config_port = hw_config->io_base + 0;
- int version_port = hw_config->io_base + 3;
- int dma = hw_config->dma;
- int dma2 = hw_config->dma2;
-
- if (hw_config->card_subtype == 1) /* Has no IRQ/DMA registers */
- {
- hw_config->slots[0] = ad1848_init("MS Sound System", ports,
- hw_config->irq,
- hw_config->dma,
- hw_config->dma2, 0,
- hw_config->osp,
- owner);
- return;
- }
- /*
- * Set the IRQ and DMA addresses.
- */
-
- bits = interrupt_bits[hw_config->irq];
- if (bits == -1)
- {
- printk(KERN_ERR "MSS: Bad IRQ %d\n", hw_config->irq);
- release_region(ports->start, 4);
- release_region(ports->start - 4, 4);
- return;
- }
- outb((bits | 0x40), config_port);
- if ((inb(version_port) & 0x40) == 0)
- printk(KERN_ERR "[MSS: IRQ Conflict?]\n");
-
-/*
- * Handle the capture DMA channel
- */
-
- if (dma2 != -1 && dma2 != dma)
- {
- if (!((dma == 0 && dma2 == 1) ||
- (dma == 1 && dma2 == 0) ||
- (dma == 3 && dma2 == 0)))
- { /* Unsupported combination. Try to swap channels */
- int tmp = dma;
-
- dma = dma2;
- dma2 = tmp;
- }
- if ((dma == 0 && dma2 == 1) ||
- (dma == 1 && dma2 == 0) ||
- (dma == 3 && dma2 == 0))
- {
- dma2_bit = 0x04; /* Enable capture DMA */
- }
- else
- {
- printk(KERN_WARNING "MSS: Invalid capture DMA\n");
- dma2 = dma;
- }
- }
- else
- {
- dma2 = dma;
- }
-
- hw_config->dma = dma;
- hw_config->dma2 = dma2;
-
- outb((bits | dma_bits[dma] | dma2_bit), config_port); /* Write IRQ+DMA setup */
-
- hw_config->slots[0] = ad1848_init("MS Sound System", ports,
- hw_config->irq,
- dma, dma2, 0,
- hw_config->osp,
- THIS_MODULE);
-}
-
-void unload_ms_sound(struct address_info *hw_config)
-{
- ad1848_unload(hw_config->io_base + 4,
- hw_config->irq,
- hw_config->dma,
- hw_config->dma2, 0);
- sound_unload_audiodev(hw_config->slots[0]);
- release_region(hw_config->io_base, 4);
-}
-
-#ifndef EXCLUDE_TIMERS
-
-/*
- * Timer stuff (for /dev/music).
- */
-
-static unsigned int current_interval;
-
-static unsigned int ad1848_tmr_start(int dev, unsigned int usecs)
-{
- unsigned long flags;
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
- unsigned long xtal_nsecs; /* nanoseconds per xtal oscillator tick */
- unsigned long divider;
-
- spin_lock_irqsave(&devc->lock,flags);
-
- /*
- * Length of the timer interval (in nanoseconds) depends on the
- * selected crystal oscillator. Check this from bit 0x01 of I8.
- *
- * AD1845 has just one oscillator which has cycle time of 10.050 us
- * (when a 24.576 MHz xtal oscillator is used).
- *
- * Convert requested interval to nanoseconds before computing
- * the timer divider.
- */
-
- if (devc->model == MD_1845 || devc->model == MD_1845_SSCAPE)
- xtal_nsecs = 10050;
- else if (ad_read(devc, 8) & 0x01)
- xtal_nsecs = 9920;
- else
- xtal_nsecs = 9969;
-
- divider = (usecs * 1000 + xtal_nsecs / 2) / xtal_nsecs;
-
- if (divider < 100) /* Don't allow shorter intervals than about 1ms */
- divider = 100;
-
- if (divider > 65535) /* Overflow check */
- divider = 65535;
-
- ad_write(devc, 21, (divider >> 8) & 0xff); /* Set upper bits */
- ad_write(devc, 20, divider & 0xff); /* Set lower bits */
- ad_write(devc, 16, ad_read(devc, 16) | 0x40); /* Start the timer */
- devc->timer_running = 1;
- spin_unlock_irqrestore(&devc->lock,flags);
-
- return current_interval = (divider * xtal_nsecs + 500) / 1000;
-}
-
-static void ad1848_tmr_reprogram(int dev)
-{
- /*
- * Audio driver has changed sampling rate so that a different xtal
- * oscillator was selected. We have to reprogram the timer rate.
- */
-
- ad1848_tmr_start(dev, current_interval);
- sound_timer_syncinterval(current_interval);
-}
-
-static void ad1848_tmr_disable(int dev)
-{
- unsigned long flags;
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
-
- spin_lock_irqsave(&devc->lock,flags);
- ad_write(devc, 16, ad_read(devc, 16) & ~0x40);
- devc->timer_running = 0;
- spin_unlock_irqrestore(&devc->lock,flags);
-}
-
-static void ad1848_tmr_restart(int dev)
-{
- unsigned long flags;
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
-
- if (current_interval == 0)
- return;
-
- spin_lock_irqsave(&devc->lock,flags);
- ad_write(devc, 16, ad_read(devc, 16) | 0x40);
- devc->timer_running = 1;
- spin_unlock_irqrestore(&devc->lock,flags);
-}
-
-static struct sound_lowlev_timer ad1848_tmr =
-{
- 0,
- 2,
- ad1848_tmr_start,
- ad1848_tmr_disable,
- ad1848_tmr_restart
-};
-
-static int ad1848_tmr_install(int dev)
-{
- if (timer_installed != -1)
- return 0; /* Don't install another timer */
-
- timer_installed = ad1848_tmr.dev = dev;
- sound_timer_init(&ad1848_tmr, audio_devs[dev]->name);
-
- return 1;
-}
-#endif /* EXCLUDE_TIMERS */
-
-EXPORT_SYMBOL(ad1848_detect);
-EXPORT_SYMBOL(ad1848_init);
-EXPORT_SYMBOL(ad1848_unload);
-EXPORT_SYMBOL(ad1848_control);
-EXPORT_SYMBOL(probe_ms_sound);
-EXPORT_SYMBOL(attach_ms_sound);
-EXPORT_SYMBOL(unload_ms_sound);
-
-static int __initdata io = -1;
-static int __initdata irq = -1;
-static int __initdata dma = -1;
-static int __initdata dma2 = -1;
-static int __initdata type = 0;
-
-module_param(io, int, 0); /* I/O for a raw AD1848 card */
-module_param(irq, int, 0); /* IRQ to use */
-module_param(dma, int, 0); /* First DMA channel */
-module_param(dma2, int, 0); /* Second DMA channel */
-module_param(type, int, 0); /* Card type */
-module_param(deskpro_xl, bool, 0); /* Special magic for Deskpro XL boxen */
-module_param(deskpro_m, bool, 0); /* Special magic for Deskpro M box */
-module_param(soundpro, bool, 0); /* More special magic for SoundPro chips */
-
-#ifdef CONFIG_PNP
-module_param(isapnp, int, 0);
-module_param(isapnpjump, int, 0);
-module_param(reverse, bool, 0);
-MODULE_PARM_DESC(isapnp, "When set to 0, Plug & Play support will be disabled");
-MODULE_PARM_DESC(isapnpjump, "Jumps to a specific slot in the driver's PnP table. Use the source, Luke.");
-MODULE_PARM_DESC(reverse, "When set to 1, will reverse ISAPnP search order");
-
-static struct pnp_dev *ad1848_dev = NULL;
-
-/* Please add new entries at the end of the table */
-static struct {
- char *name;
- unsigned short card_vendor, card_device,
- vendor, function;
- short mss_io, irq, dma, dma2; /* index into isapnp table */
- int type;
-} ad1848_isapnp_list[] __initdata = {
- {"CMI 8330 SoundPRO",
- ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001),
- ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001),
- 0, 0, 0,-1, 0},
- {"CS4232 based card",
- ISAPNP_ANY_ID, ISAPNP_ANY_ID,
- ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0000),
- 0, 0, 0, 1, 0},
- {"CS4232 based card",
- ISAPNP_ANY_ID, ISAPNP_ANY_ID,
- ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0100),
- 0, 0, 0, 1, 0},
- {"OPL3-SA2 WSS mode",
- ISAPNP_ANY_ID, ISAPNP_ANY_ID,
- ISAPNP_VENDOR('Y','M','H'), ISAPNP_FUNCTION(0x0021),
- 1, 0, 0, 1, 1},
- {"Advanced Gravis InterWave Audio",
- ISAPNP_VENDOR('G','R','V'), ISAPNP_DEVICE(0x0001),
- ISAPNP_VENDOR('G','R','V'), ISAPNP_FUNCTION(0x0000),
- 0, 0, 0, 1, 0},
- {NULL}
-};
-
-static struct isapnp_device_id id_table[] __devinitdata = {
- { ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001),
- ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), 0 },
- { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
- ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0000), 0 },
- { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
- ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0100), 0 },
- /* The main driver for this card is opl3sa2
- { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
- ISAPNP_VENDOR('Y','M','H'), ISAPNP_FUNCTION(0x0021), 0 },
- */
- { ISAPNP_VENDOR('G','R','V'), ISAPNP_DEVICE(0x0001),
- ISAPNP_VENDOR('G','R','V'), ISAPNP_FUNCTION(0x0000), 0 },
- {0}
-};
-
-MODULE_DEVICE_TABLE(isapnp, id_table);
-
-static struct pnp_dev *activate_dev(char *devname, char *resname, struct pnp_dev *dev)
-{
- int err;
-
- err = pnp_device_attach(dev);
- if (err < 0)
- return(NULL);
-
- if((err = pnp_activate_dev(dev)) < 0) {
- printk(KERN_ERR "ad1848: %s %s config failed (out of resources?)[%d]\n", devname, resname, err);
-
- pnp_device_detach(dev);
-
- return(NULL);
- }
- audio_activated = 1;
- return(dev);
-}
-
-static struct pnp_dev __init *ad1848_init_generic(struct pnp_card *bus,
- struct address_info *hw_config, int slot)
-{
-
- /* Configure Audio device */
- if((ad1848_dev = pnp_find_dev(bus, ad1848_isapnp_list[slot].vendor, ad1848_isapnp_list[slot].function, NULL)))
- {
- if((ad1848_dev = activate_dev(ad1848_isapnp_list[slot].name, "ad1848", ad1848_dev)))
- {
- hw_config->io_base = pnp_port_start(ad1848_dev, ad1848_isapnp_list[slot].mss_io);
- hw_config->irq = pnp_irq(ad1848_dev, ad1848_isapnp_list[slot].irq);
- hw_config->dma = pnp_dma(ad1848_dev, ad1848_isapnp_list[slot].dma);
- if(ad1848_isapnp_list[slot].dma2 != -1)
- hw_config->dma2 = pnp_dma(ad1848_dev, ad1848_isapnp_list[slot].dma2);
- else
- hw_config->dma2 = -1;
- hw_config->card_subtype = ad1848_isapnp_list[slot].type;
- } else
- return(NULL);
- } else
- return(NULL);
-
- return(ad1848_dev);
-}
-
-static int __init ad1848_isapnp_init(struct address_info *hw_config, struct pnp_card *bus, int slot)
-{
- char *busname = bus->name[0] ? bus->name : ad1848_isapnp_list[slot].name;
-
- /* Initialize this baby. */
-
- if(ad1848_init_generic(bus, hw_config, slot)) {
- /* We got it. */
-
- printk(KERN_NOTICE "ad1848: PnP reports '%s' at i/o %#x, irq %d, dma %d, %d\n",
- busname,
- hw_config->io_base, hw_config->irq, hw_config->dma,
- hw_config->dma2);
- return 1;
- }
- return 0;
-}
-
-static int __init ad1848_isapnp_probe(struct address_info *hw_config)
-{
- static int first = 1;
- int i;
-
- /* Count entries in sb_isapnp_list */
- for (i = 0; ad1848_isapnp_list[i].card_vendor != 0; i++);
- i--;
-
- /* Check and adjust isapnpjump */
- if( isapnpjump < 0 || isapnpjump > i) {
- isapnpjump = reverse ? i : 0;
- printk(KERN_ERR "ad1848: Valid range for isapnpjump is 0-%d. Adjusted to %d.\n", i, isapnpjump);
- }
-
- if(!first || !reverse)
- i = isapnpjump;
- first = 0;
- while(ad1848_isapnp_list[i].card_vendor != 0) {
- static struct pnp_card *bus = NULL;
-
- while ((bus = pnp_find_card(
- ad1848_isapnp_list[i].card_vendor,
- ad1848_isapnp_list[i].card_device,
- bus))) {
-
- if(ad1848_isapnp_init(hw_config, bus, i)) {
- isapnpjump = i; /* start next search from here */
- return 0;
- }
- }
- i += reverse ? -1 : 1;
- }
-
- return -ENODEV;
-}
-#endif
-
-
-static int __init init_ad1848(void)
-{
- printk(KERN_INFO "ad1848/cs4248 codec driver Copyright (C) by Hannu Savolainen 1993-1996\n");
-
-#ifdef CONFIG_PNP
- if(isapnp && (ad1848_isapnp_probe(&cfg) < 0) ) {
- printk(KERN_NOTICE "ad1848: No ISAPnP cards found, trying standard ones...\n");
- isapnp = 0;
- }
-#endif
-
- if(io != -1) {
- struct resource *ports;
- if( isapnp == 0 )
- {
- if(irq == -1 || dma == -1) {
- printk(KERN_WARNING "ad1848: must give I/O , IRQ and DMA.\n");
- return -EINVAL;
- }
-
- cfg.irq = irq;
- cfg.io_base = io;
- cfg.dma = dma;
- cfg.dma2 = dma2;
- cfg.card_subtype = type;
- }
-
- ports = request_region(io + 4, 4, "ad1848");
-
- if (!ports)
- return -EBUSY;
-
- if (!request_region(io, 4, "WSS config")) {
- release_region(io + 4, 4);
- return -EBUSY;
- }
-
- if (!probe_ms_sound(&cfg, ports)) {
- release_region(io + 4, 4);
- release_region(io, 4);
- return -ENODEV;
- }
- attach_ms_sound(&cfg, ports, THIS_MODULE);
- loaded = 1;
- }
- return 0;
-}
-
-static void __exit cleanup_ad1848(void)
-{
- if(loaded)
- unload_ms_sound(&cfg);
-
-#ifdef CONFIG_PNP
- if(ad1848_dev){
- if(audio_activated)
- pnp_device_detach(ad1848_dev);
- }
-#endif
-}
-
-module_init(init_ad1848);
-module_exit(cleanup_ad1848);
-
-#ifndef MODULE
-static int __init setup_ad1848(char *str)
-{
- /* io, irq, dma, dma2, type */
- int ints[6];
-
- str = get_options(str, ARRAY_SIZE(ints), ints);
-
- io = ints[1];
- irq = ints[2];
- dma = ints[3];
- dma2 = ints[4];
- type = ints[5];
-
- return 1;
-}
-
-__setup("ad1848=", setup_ad1848);
-#endif
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/oss/ad1848.h b/ANDROID_3.4.5/sound/oss/ad1848.h
deleted file mode 100644
index b95ebe28..00000000
--- a/ANDROID_3.4.5/sound/oss/ad1848.h
+++ /dev/null
@@ -1,24 +0,0 @@
-
-#include <linux/interrupt.h>
-
-#define AD_F_CS4231 0x0001 /* Returned if a CS4232 (or compatible) detected */
-#define AD_F_CS4248 0x0001 /* Returned if a CS4248 (or compatible) detected */
-
-#define AD1848_SET_XTAL 1
-#define AD1848_MIXER_REROUTE 2
-
-#define AD1848_REROUTE(oldctl, newctl) \
- ad1848_control(AD1848_MIXER_REROUTE, ((oldctl)<<8)|(newctl))
-
-
-int ad1848_init(char *name, struct resource *ports, int irq, int dma_playback,
- int dma_capture, int share_dma, int *osp, struct module *owner);
-void ad1848_unload (int io_base, int irq, int dma_playback, int dma_capture, int share_dma);
-
-int ad1848_detect (struct resource *ports, int *flags, int *osp);
-int ad1848_control(int cmd, int arg);
-
-void attach_ms_sound(struct address_info * hw_config, struct resource *ports, struct module * owner);
-
-int probe_ms_sound(struct address_info *hw_config, struct resource *ports);
-void unload_ms_sound(struct address_info *hw_info);
diff --git a/ANDROID_3.4.5/sound/oss/ad1848_mixer.h b/ANDROID_3.4.5/sound/oss/ad1848_mixer.h
deleted file mode 100644
index 2cf719b5..00000000
--- a/ANDROID_3.4.5/sound/oss/ad1848_mixer.h
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * sound/oss/ad1848_mixer.h
- *
- * Definitions for the mixer of AD1848 and compatible codecs.
- */
-
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-
-
-/*
- * The AD1848 codec has generic input lines called Line, Aux1 and Aux2.
- * Sound card manufacturers have connected actual inputs (CD, synth, line,
- * etc) to these inputs in different order. Therefore it's difficult
- * to assign mixer channels to these inputs correctly. The following
- * contains two alternative mappings. The first one is for GUS MAX and
- * the second is just a generic one (line1, line2 and line3).
- * (Actually this is not a mapping but rather some kind of interleaving
- * solution).
- */
-#define MODE1_REC_DEVICES (SOUND_MASK_LINE3 | SOUND_MASK_MIC | \
- SOUND_MASK_LINE1 | SOUND_MASK_IMIX)
-
-#define SPRO_REC_DEVICES (SOUND_MASK_LINE | SOUND_MASK_MIC | \
- SOUND_MASK_CD | SOUND_MASK_LINE1)
-
-#define MODE1_MIXER_DEVICES (SOUND_MASK_LINE1 | SOUND_MASK_MIC | \
- SOUND_MASK_LINE2 | \
- SOUND_MASK_IGAIN | \
- SOUND_MASK_PCM | SOUND_MASK_IMIX)
-
-#define MODE2_MIXER_DEVICES (SOUND_MASK_LINE1 | SOUND_MASK_LINE2 | \
- SOUND_MASK_MIC | \
- SOUND_MASK_LINE3 | SOUND_MASK_SPEAKER | \
- SOUND_MASK_IGAIN | \
- SOUND_MASK_PCM | SOUND_MASK_IMIX)
-
-#define MODE3_MIXER_DEVICES (MODE2_MIXER_DEVICES | SOUND_MASK_VOLUME)
-
-/* OPTi 82C930 has no IMIX level control, but it can still be selected as an
- * input
- */
-#define C930_MIXER_DEVICES (SOUND_MASK_LINE1 | SOUND_MASK_LINE2 | \
- SOUND_MASK_MIC | SOUND_MASK_VOLUME | \
- SOUND_MASK_LINE3 | \
- SOUND_MASK_IGAIN | SOUND_MASK_PCM)
-
-#define SPRO_MIXER_DEVICES (SOUND_MASK_VOLUME | SOUND_MASK_PCM | \
- SOUND_MASK_LINE | SOUND_MASK_SYNTH | \
- SOUND_MASK_CD | SOUND_MASK_MIC | \
- SOUND_MASK_SPEAKER | SOUND_MASK_LINE1 | \
- SOUND_MASK_OGAIN)
-
-struct mixer_def {
- unsigned int regno:6; /* register number for volume */
- unsigned int polarity:1; /* volume polarity: 0=normal, 1=reversed */
- unsigned int bitpos:3; /* position of bits in register for volume */
- unsigned int nbits:3; /* number of bits in register for volume */
- unsigned int mutereg:6; /* register number for mute bit */
- unsigned int mutepol:1; /* mute polarity: 0=normal, 1=reversed */
- unsigned int mutepos:4; /* position of mute bit in register */
- unsigned int recreg:6; /* register number for recording bit */
- unsigned int recpol:1; /* recording polarity: 0=normal, 1=reversed */
- unsigned int recpos:4; /* position of recording bit in register */
-};
-
-static char mix_cvt[101] = {
- 0, 0, 3, 7,10,13,16,19,21,23,26,28,30,32,34,35,37,39,40,42,
- 43,45,46,47,49,50,51,52,53,55,56,57,58,59,60,61,62,63,64,65,
- 65,66,67,68,69,70,70,71,72,73,73,74,75,75,76,77,77,78,79,79,
- 80,81,81,82,82,83,84,84,85,85,86,86,87,87,88,88,89,89,90,90,
- 91,91,92,92,93,93,94,94,95,95,96,96,96,97,97,98,98,98,99,99,
- 100
-};
-
-typedef struct mixer_def mixer_ent;
-typedef mixer_ent mixer_ents[2];
-
-/*
- * Most of the mixer entries work in backwards. Setting the polarity field
- * makes them to work correctly.
- *
- * The channel numbering used by individual sound cards is not fixed. Some
- * cards have assigned different meanings for the AUX1, AUX2 and LINE inputs.
- * The current version doesn't try to compensate this.
- */
-
-#define MIX_ENT(name, reg_l, pola_l, pos_l, len_l, reg_r, pola_r, pos_r, len_r, mute_bit) \
- [name] = {{reg_l, pola_l, pos_l, len_l, reg_l, 0, mute_bit, 0, 0, 8}, \
- {reg_r, pola_r, pos_r, len_r, reg_r, 0, mute_bit, 0, 0, 8}}
-
-#define MIX_ENT2(name, reg_l, pola_l, pos_l, len_l, mute_reg_l, mute_pola_l, mute_pos_l, \
- rec_reg_l, rec_pola_l, rec_pos_l, \
- reg_r, pola_r, pos_r, len_r, mute_reg_r, mute_pola_r, mute_pos_r, \
- rec_reg_r, rec_pola_r, rec_pos_r) \
- [name] = {{reg_l, pola_l, pos_l, len_l, mute_reg_l, mute_pola_l, mute_pos_l, \
- rec_reg_l, rec_pola_l, rec_pos_l}, \
- {reg_r, pola_r, pos_r, len_r, mute_reg_r, mute_pola_r, mute_pos_r, \
- rec_reg_r, rec_pola_r, rec_pos_r}}
-
-static mixer_ents ad1848_mix_devices[32] = {
- MIX_ENT(SOUND_MIXER_VOLUME, 27, 1, 0, 4, 29, 1, 0, 4, 8),
- MIX_ENT(SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_SYNTH, 4, 1, 0, 5, 5, 1, 0, 5, 7),
- MIX_ENT(SOUND_MIXER_PCM, 6, 1, 0, 6, 7, 1, 0, 6, 7),
- MIX_ENT(SOUND_MIXER_SPEAKER, 26, 1, 0, 4, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_LINE, 18, 1, 0, 5, 19, 1, 0, 5, 7),
- MIX_ENT(SOUND_MIXER_MIC, 0, 0, 5, 1, 1, 0, 5, 1, 8),
- MIX_ENT(SOUND_MIXER_CD, 2, 1, 0, 5, 3, 1, 0, 5, 7),
- MIX_ENT(SOUND_MIXER_IMIX, 13, 1, 2, 6, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_RECLEV, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_IGAIN, 0, 0, 0, 4, 1, 0, 0, 4, 8),
- MIX_ENT(SOUND_MIXER_OGAIN, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_LINE1, 2, 1, 0, 5, 3, 1, 0, 5, 7),
- MIX_ENT(SOUND_MIXER_LINE2, 4, 1, 0, 5, 5, 1, 0, 5, 7),
- MIX_ENT(SOUND_MIXER_LINE3, 18, 1, 0, 5, 19, 1, 0, 5, 7)
-};
-
-static mixer_ents iwave_mix_devices[32] = {
- MIX_ENT(SOUND_MIXER_VOLUME, 25, 1, 0, 5, 27, 1, 0, 5, 8),
- MIX_ENT(SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_SYNTH, 4, 1, 0, 5, 5, 1, 0, 5, 7),
- MIX_ENT(SOUND_MIXER_PCM, 6, 1, 0, 6, 7, 1, 0, 6, 7),
- MIX_ENT(SOUND_MIXER_SPEAKER, 26, 1, 0, 4, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_LINE, 18, 1, 0, 5, 19, 1, 0, 5, 7),
- MIX_ENT(SOUND_MIXER_MIC, 0, 0, 5, 1, 1, 0, 5, 1, 8),
- MIX_ENT(SOUND_MIXER_CD, 2, 1, 0, 5, 3, 1, 0, 5, 7),
- MIX_ENT(SOUND_MIXER_IMIX, 16, 1, 0, 5, 17, 1, 0, 5, 8),
- MIX_ENT(SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_RECLEV, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_IGAIN, 0, 0, 0, 4, 1, 0, 0, 4, 8),
- MIX_ENT(SOUND_MIXER_OGAIN, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_LINE1, 2, 1, 0, 5, 3, 1, 0, 5, 7),
- MIX_ENT(SOUND_MIXER_LINE2, 4, 1, 0, 5, 5, 1, 0, 5, 7),
- MIX_ENT(SOUND_MIXER_LINE3, 18, 1, 0, 5, 19, 1, 0, 5, 7)
-};
-
-static mixer_ents cs42xb_mix_devices[32] = {
- /* Digital master volume actually has seven bits, but we only use
- six to avoid the discontinuity when the analog gain kicks in. */
- MIX_ENT(SOUND_MIXER_VOLUME, 46, 1, 0, 6, 47, 1, 0, 6, 7),
- MIX_ENT(SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_SYNTH, 4, 1, 0, 5, 5, 1, 0, 5, 7),
- MIX_ENT(SOUND_MIXER_PCM, 6, 1, 0, 6, 7, 1, 0, 6, 7),
- MIX_ENT(SOUND_MIXER_SPEAKER, 26, 1, 0, 4, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_LINE, 18, 1, 0, 5, 19, 1, 0, 5, 7),
- MIX_ENT(SOUND_MIXER_MIC, 34, 1, 0, 5, 35, 1, 0, 5, 7),
- MIX_ENT(SOUND_MIXER_CD, 2, 1, 0, 5, 3, 1, 0, 5, 7),
- /* For the IMIX entry, it was not possible to use the MIX_ENT macro
- because the mute bit is in different positions for the two
- channels and requires reverse polarity. */
- [SOUND_MIXER_IMIX] = {{13, 1, 2, 6, 13, 1, 0, 0, 0, 8},
- {42, 1, 0, 6, 42, 1, 7, 0, 0, 8}},
- MIX_ENT(SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_RECLEV, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_IGAIN, 0, 0, 0, 4, 1, 0, 0, 4, 8),
- MIX_ENT(SOUND_MIXER_OGAIN, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_LINE1, 2, 1, 0, 5, 3, 1, 0, 5, 7),
- MIX_ENT(SOUND_MIXER_LINE2, 4, 1, 0, 5, 5, 1, 0, 5, 7),
- MIX_ENT(SOUND_MIXER_LINE3, 38, 1, 0, 6, 39, 1, 0, 6, 7)
-};
-
-/* OPTi 82C930 has somewhat different port addresses.
- * Note: VOLUME == SPEAKER, SYNTH == LINE2, LINE == LINE3, CD == LINE1
- * VOLUME, SYNTH, LINE, CD are not enabled above.
- * MIC is level of mic monitoring direct to output. Same for CD, LINE, etc.
- */
-static mixer_ents c930_mix_devices[32] = {
- MIX_ENT(SOUND_MIXER_VOLUME, 22, 1, 1, 5, 23, 1, 1, 5, 7),
- MIX_ENT(SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_SYNTH, 4, 1, 1, 4, 5, 1, 1, 4, 7),
- MIX_ENT(SOUND_MIXER_PCM, 6, 1, 0, 5, 7, 1, 0, 5, 7),
- MIX_ENT(SOUND_MIXER_SPEAKER, 22, 1, 1, 5, 23, 1, 1, 5, 7),
- MIX_ENT(SOUND_MIXER_LINE, 18, 1, 1, 4, 19, 1, 1, 4, 7),
- MIX_ENT(SOUND_MIXER_MIC, 20, 1, 1, 4, 21, 1, 1, 4, 7),
- MIX_ENT(SOUND_MIXER_CD, 2, 1, 1, 4, 3, 1, 1, 4, 7),
- MIX_ENT(SOUND_MIXER_IMIX, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_RECLEV, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_IGAIN, 0, 0, 0, 4, 1, 0, 0, 4, 8),
- MIX_ENT(SOUND_MIXER_OGAIN, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT(SOUND_MIXER_LINE1, 2, 1, 1, 4, 3, 1, 1, 4, 7),
- MIX_ENT(SOUND_MIXER_LINE2, 4, 1, 1, 4, 5, 1, 1, 4, 7),
- MIX_ENT(SOUND_MIXER_LINE3, 18, 1, 1, 4, 19, 1, 1, 4, 7)
-};
-
-static mixer_ents spro_mix_devices[32] = {
- MIX_ENT (SOUND_MIXER_VOLUME, 19, 0, 4, 4, 19, 0, 0, 4, 8),
- MIX_ENT (SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT (SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT2(SOUND_MIXER_SYNTH, 4, 1, 1, 4, 23, 0, 3, 0, 0, 8,
- 5, 1, 1, 4, 23, 0, 3, 0, 0, 8),
- MIX_ENT (SOUND_MIXER_PCM, 6, 1, 1, 4, 7, 1, 1, 4, 8),
- MIX_ENT (SOUND_MIXER_SPEAKER, 18, 0, 3, 2, 0, 0, 0, 0, 8),
- MIX_ENT2(SOUND_MIXER_LINE, 20, 0, 4, 4, 17, 1, 4, 16, 0, 2,
- 20, 0, 0, 4, 17, 1, 3, 16, 0, 1),
- MIX_ENT2(SOUND_MIXER_MIC, 18, 0, 0, 3, 17, 1, 0, 16, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- MIX_ENT2(SOUND_MIXER_CD, 21, 0, 4, 4, 17, 1, 2, 16, 0, 4,
- 21, 0, 0, 4, 17, 1, 1, 16, 0, 3),
- MIX_ENT (SOUND_MIXER_IMIX, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT (SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT (SOUND_MIXER_RECLEV, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT (SOUND_MIXER_IGAIN, 0, 0, 0, 0, 0, 0, 0, 0, 8),
- MIX_ENT (SOUND_MIXER_OGAIN, 17, 1, 6, 1, 0, 0, 0, 0, 8),
- /* This is external wavetable */
- MIX_ENT2(SOUND_MIXER_LINE1, 22, 0, 4, 4, 23, 1, 1, 23, 0, 4,
- 22, 0, 0, 4, 23, 1, 0, 23, 0, 5),
-};
-
-static int default_mixer_levels[32] =
-{
- 0x3232, /* Master Volume */
- 0x3232, /* Bass */
- 0x3232, /* Treble */
- 0x4b4b, /* FM */
- 0x3232, /* PCM */
- 0x1515, /* PC Speaker */
- 0x2020, /* Ext Line */
- 0x1010, /* Mic */
- 0x4b4b, /* CD */
- 0x0000, /* Recording monitor */
- 0x4b4b, /* Second PCM */
- 0x4b4b, /* Recording level */
- 0x4b4b, /* Input gain */
- 0x4b4b, /* Output gain */
- 0x2020, /* Line1 */
- 0x2020, /* Line2 */
- 0x1515 /* Line3 (usually line in)*/
-};
-
-#define LEFT_CHN 0
-#define RIGHT_CHN 1
-
-/*
- * Channel enable bits for ioctl(SOUND_MIXER_PRIVATE1)
- */
-
-#ifndef AUDIO_SPEAKER
-#define AUDIO_SPEAKER 0x01 /* Enable mono output */
-#define AUDIO_HEADPHONE 0x02 /* Sparc only */
-#define AUDIO_LINE_OUT 0x04 /* Sparc only */
-#endif
diff --git a/ANDROID_3.4.5/sound/oss/aedsp16.c b/ANDROID_3.4.5/sound/oss/aedsp16.c
deleted file mode 100644
index 35b5912c..00000000
--- a/ANDROID_3.4.5/sound/oss/aedsp16.c
+++ /dev/null
@@ -1,1373 +0,0 @@
-/*
- sound/oss/aedsp16.c
-
- Audio Excel DSP 16 software configuration routines
- Copyright (C) 1995,1996,1997,1998 Riccardo Facchetti (fizban@tin.it)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- */
-/*
- * Include the main OSS Lite header file. It include all the os, OSS Lite, etc
- * headers needed by this source.
- */
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include "sound_config.h"
-
-/*
-
- READ THIS
-
- This module started to configure the Audio Excel DSP 16 Sound Card.
- Now works with the SC-6000 (old aedsp16) and new SC-6600 based cards.
-
- NOTE: I have NO idea about Audio Excel DSP 16 III. If someone owns this
- audio card and want to see the kernel support for it, please contact me.
-
- Audio Excel DSP 16 is an SB pro II, Microsoft Sound System and MPU-401
- compatible card.
- It is software-only configurable (no jumpers to hard-set irq/dma/mpu-irq),
- so before this module, the only way to configure the DSP under linux was
- boot the MS-DOS loading the sound.sys device driver (this driver soft-
- configure the sound board hardware by massaging someone of its registers),
- and then ctrl-alt-del to boot linux with the DSP configured by the DOS
- driver.
-
- This module works configuring your Audio Excel DSP 16's irq, dma and
- mpu-401-irq. The OSS Lite routines rely on the fact that if the
- hardware is there, they can detect it. The problem with AEDSP16 is
- that no hardware can be found by the probe routines if the sound card
- is not configured properly. Sometimes the kernel probe routines can find
- an SBPRO even when the card is not configured (this is the standard setup
- of the card), but the SBPRO emulation don't work well if the card is not
- properly initialized. For this reason
-
- aedsp16_init_board()
-
- routine is called before the OSS Lite probe routines try to detect the
- hardware.
-
- NOTE (READ THE NOTE TOO, IT CONTAIN USEFUL INFORMATIONS)
-
- NOTE: Now it works with SC-6000 and SC-6600 based audio cards. The new cards
- have no jumper switch at all. No more WSS or MPU-401 I/O port switches. They
- have to be configured by software.
-
- NOTE: The driver is merged with the new OSS Lite sound driver. It works
- as a lowlevel driver.
-
- The Audio Excel DSP 16 Sound Card emulates both SBPRO and MSS;
- the OSS Lite sound driver can be configured for SBPRO and MSS cards
- at the same time, but the aedsp16 can't be two cards!!
- When we configure it, we have to choose the SBPRO or the MSS emulation
- for AEDSP16. We also can install a *REAL* card of the other type (see [1]).
-
- NOTE: If someone can test the combination AEDSP16+MSS or AEDSP16+SBPRO
- please let me know if it works.
-
- The MPU-401 support can be compiled in together with one of the other
- two operating modes.
-
- NOTE: This is something like plug-and-play: we have only to plug
- the AEDSP16 board in the socket, and then configure and compile
- a kernel that uses the AEDSP16 software configuration capability.
- No jumper setting is needed!
-
- For example, if you want AEDSP16 to be an SBPro, on irq 10, dma 3
- you have just to make config the OSS Lite package, configuring
- the AEDSP16 sound card, then activating the SBPro emulation mode
- and at last configuring IRQ and DMA.
- Compile the kernel and run it.
-
- NOTE: This means for SC-6000 cards that you can choose irq and dma,
- but not the I/O addresses. To change I/O addresses you have to set
- them with jumpers. For SC-6600 cards you have no jumpers so you have
- to set up your full card configuration in the make config.
-
- You can change the irq/dma/mirq settings WITHOUT THE NEED to open
- your computer and massage the jumpers (there are no irq/dma/mirq
- jumpers to be configured anyway, only I/O BASE values have to be
- configured with jumpers)
-
- For some ununderstandable reason, the card default of irq 7, dma 1,
- don't work for me. Seems to be an IRQ or DMA conflict. Under heavy
- HDD work, the kernel start to erupt out a lot of messages like:
-
- 'Sound: DMA timed out - IRQ/DRQ config error?'
-
- For what I can say, I have NOT any conflict at irq 7 (under linux I'm
- using the lp polling driver), and dma line 1 is unused as stated by
- /proc/dma. I can suppose this is a bug of AEDSP16. I know my hardware so
- I'm pretty sure I have not any conflict, but may be I'm wrong. Who knows!
- Anyway a setting of irq 10, dma 3 works really fine.
-
- NOTE: if someone can use AEDSP16 with irq 7, dma 1, please let me know
- the emulation mode, all the installed hardware and the hardware
- configuration (irq and dma settings of all the hardware).
-
- This init module should work with SBPRO+MSS, when one of the two is
- the AEDSP16 emulation and the other the real card. (see [1])
- For example:
-
- AEDSP16 (0x220) in SBPRO emu (0x220) + real MSS + other
- AEDSP16 (0x220) in MSS emu + real SBPRO (0x240) + other
-
- MPU401 should work. (see [2])
-
- [1]
- ---
- Date: Mon, 29 Jul 1997 08:35:40 +0100
- From: Mr S J Greenaway <sjg95@unixfe.rl.ac.uk>
-
- [...]
- Just to let you know got my Audio Excel (emulating a MSS) working
- with my original SB16, thanks for the driver!
- [...]
- ---
-
- [2] Not tested by me for lack of hardware.
-
- TODO, WISHES AND TECH
-
- - About I/O ports allocation -
-
- Request the 2x0h region (port base) in any case if we are using this card.
-
- NOTE: the "aedsp16 (base)" string with which we are requesting the aedsp16
- port base region (see code) does not mean necessarily that we are emulating
- sbpro. Even if this region is the sbpro I/O ports region, we use this
- region to access the control registers of the card, and if emulating
- sbpro, I/O sbpro registers too. If we are emulating MSS, the sbpro
- registers are not used, in no way, to emulate an sbpro: they are
- used only for configuration purposes.
-
- Started Fri Mar 17 16:13:18 MET 1995
-
- v0.1 (ALPHA, was a user-level program called AudioExcelDSP16.c)
- - Initial code.
- v0.2 (ALPHA)
- - Cleanups.
- - Integrated with Linux voxware v 2.90-2 kernel sound driver.
- - SoundBlaster Pro mode configuration.
- - Microsoft Sound System mode configuration.
- - MPU-401 mode configuration.
- v0.3 (ALPHA)
- - Cleanups.
- - Rearranged the code to let aedsp16_init_board be more general.
- - Erased the REALLY_SLOW_IO. We don't need it. Erased the linux/io.h
- inclusion too. We rely on os.h
- - Used the to get a variable
- len string (we are not sure about the len of Copyright string).
- This works with any SB and compatible.
- - Added the code to request_region at device init (should go in
- the main body of voxware).
- v0.4 (BETA)
- - Better configure.c patch for aedsp16 configuration (better
- logic of inclusion of AEDSP16 support)
- - Modified the conditional compilation to better support more than
- one sound card of the emulated type (read the NOTES above)
- - Moved the sb init routine from the attach to the very first
- probe in sb_card.c
- - Rearrangements and cleanups
- - Wiped out some unnecessary code and variables: this is kernel
- code so it is better save some TEXT and DATA
- - Fixed the request_region code. We must allocate the aedsp16 (sbpro)
- I/O ports in any case because they are used to access the DSP
- configuration registers and we can not allow anyone to get them.
- v0.5
- - cleanups on comments
- - prep for diffs against v3.0-proto-950402
- v0.6
- - removed the request_region()s when compiling the MODULE sound.o
- because we are not allowed (by the actual voxware structure) to
- release_region()
- v0.7 (pre ALPHA, not distributed)
- - started porting this module to kernel 1.3.84. Dummy probe/attach
- routines.
- v0.8 (ALPHA)
- - attached all the init routines.
- v0.9 (BETA)
- - Integrated with linux-pre2.0.7
- - Integrated with configuration scripts.
- - Cleaned up and beautyfied the code.
- v0.9.9 (BETA)
- - Thanks to Piercarlo Grandi: corrected the conditonal compilation code.
- Now only the code configured is compiled in, with some memory saving.
- v0.9.10
- - Integration into the sound/lowlevel/ section of the sound driver.
- - Re-organized the code.
- v0.9.11 (not distributed)
- - Rewritten the init interface-routines to initialize the AEDSP16 in
- one shot.
- - More cosmetics.
- - SC-6600 support.
- - More soft/hard configuration.
- v0.9.12
- - Refined the v0.9.11 code with conditional compilation to distinguish
- between SC-6000 and SC-6600 code.
- v1.0.0
- - Prep for merging with OSS Lite and Linux kernel 2.1.13
- - Corrected a bug in request/check/release region calls (thanks to the
- new kernel exception handling).
- v1.1
- - Revamped for integration with new modularized sound drivers: to enhance
- the flexibility of modular version, I have removed all the conditional
- compilation for SBPRO, MPU and MSS code. Now it is all managed with
- the ae_config structure.
- v1.2
- - Module informations added.
- - Removed aedsp16_delay_10msec(), now using mdelay(10)
- - All data and funcs moved to .*.init section.
- v1.3
- Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 2000/09/27
- - got rid of check_region
-
- Known Problems:
- - Audio Excel DSP 16 III don't work with this driver.
-
- Credits:
- Many thanks to Gerald Britton <gbritton@CapAccess.org>. He helped me a
- lot in testing the 0.9.11 and 0.9.12 versions of this driver.
-
- */
-
-
-#define VERSION "1.3" /* Version of Audio Excel DSP 16 driver */
-
-#undef AEDSP16_DEBUG /* Define this to 1 to enable debug code */
-#undef AEDSP16_DEBUG_MORE /* Define this to 1 to enable more debug */
-#undef AEDSP16_INFO /* Define this to 1 to enable info code */
-
-#if defined(AEDSP16_DEBUG)
-# define DBG(x) printk x
-# if defined(AEDSP16_DEBUG_MORE)
-# define DBG1(x) printk x
-# else
-# define DBG1(x)
-# endif
-#else
-# define DBG(x)
-# define DBG1(x)
-#endif
-
-/*
- * Misc definitions
- */
-#define TRUE 1
-#define FALSE 0
-
-/*
- * Region Size for request/check/release region.
- */
-#define IOBASE_REGION_SIZE 0x10
-
-/*
- * Hardware related defaults
- */
-#define DEF_AEDSP16_IOB 0x220 /* 0x220(default) 0x240 */
-#define DEF_AEDSP16_IRQ 7 /* 5 7(default) 9 10 11 */
-#define DEF_AEDSP16_MRQ 0 /* 5 7 9 10 0(default), 0 means disable */
-#define DEF_AEDSP16_DMA 1 /* 0 1(default) 3 */
-
-/*
- * Commands of AEDSP16's DSP (SBPRO+special).
- * Some of them are COMMAND_xx, in the future they may change.
- */
-#define WRITE_MDIRQ_CFG 0x50 /* Set M&I&DRQ mask (the real config) */
-#define COMMAND_52 0x52 /* */
-#define READ_HARD_CFG 0x58 /* Read Hardware Config (I/O base etc) */
-#define COMMAND_5C 0x5c /* */
-#define COMMAND_60 0x60 /* */
-#define COMMAND_66 0x66 /* */
-#define COMMAND_6C 0x6c /* */
-#define COMMAND_6E 0x6e /* */
-#define COMMAND_88 0x88 /* */
-#define DSP_INIT_MSS 0x8c /* Enable Microsoft Sound System mode */
-#define COMMAND_C5 0xc5 /* */
-#define GET_DSP_VERSION 0xe1 /* Get DSP Version */
-#define GET_DSP_COPYRIGHT 0xe3 /* Get DSP Copyright */
-
-/*
- * Offsets of AEDSP16 DSP I/O ports. The offset is added to base I/O port
- * to have the actual I/O port.
- * Register permissions are:
- * (wo) == Write Only
- * (ro) == Read Only
- * (w-) == Write
- * (r-) == Read
- */
-#define DSP_RESET 0x06 /* offset of DSP RESET (wo) */
-#define DSP_READ 0x0a /* offset of DSP READ (ro) */
-#define DSP_WRITE 0x0c /* offset of DSP WRITE (w-) */
-#define DSP_COMMAND 0x0c /* offset of DSP COMMAND (w-) */
-#define DSP_STATUS 0x0c /* offset of DSP STATUS (r-) */
-#define DSP_DATAVAIL 0x0e /* offset of DSP DATA AVAILABLE (ro) */
-
-
-#define RETRY 10 /* Various retry values on I/O opera- */
-#define STATUSRETRY 1000 /* tions. Sometimes we have to */
-#define HARDRETRY 500000 /* wait for previous cmd to complete */
-
-/*
- * Size of character arrays that store name and version of sound card
- */
-#define CARDNAMELEN 15 /* Size of the card's name in chars */
-#define CARDVERLEN 10 /* Size of the card's version in chars */
-#define CARDVERDIGITS 2 /* Number of digits in the version */
-
-#if defined(CONFIG_SC6600)
-/*
- * Bitmapped flags of hard configuration
- */
-/*
- * Decode macros (xl == low byte, xh = high byte)
- */
-#define IOBASE(xl) ((xl & 0x01)?0x240:0x220)
-#define JOY(xl) (xl & 0x02)
-#define MPUADDR(xl) ( \
- (xl & 0x0C)?0x330: \
- (xl & 0x08)?0x320: \
- (xl & 0x04)?0x310: \
- 0x300)
-#define WSSADDR(xl) ((xl & 0x10)?0xE80:0x530)
-#define CDROM(xh) (xh & 0x20)
-#define CDROMADDR(xh) (((xh & 0x1F) << 4) + 0x200)
-/*
- * Encode macros
- */
-#define BLDIOBASE(xl, val) { \
- xl &= ~0x01; \
- if (val == 0x240) \
- xl |= 0x01; \
- }
-#define BLDJOY(xl, val) { \
- xl &= ~0x02; \
- if (val == 1) \
- xl |= 0x02; \
- }
-#define BLDMPUADDR(xl, val) { \
- xl &= ~0x0C; \
- switch (val) { \
- case 0x330: \
- xl |= 0x0C; \
- break; \
- case 0x320: \
- xl |= 0x08; \
- break; \
- case 0x310: \
- xl |= 0x04; \
- break; \
- case 0x300: \
- xl |= 0x00; \
- break; \
- default: \
- xl |= 0x00; \
- break; \
- } \
- }
-#define BLDWSSADDR(xl, val) { \
- xl &= ~0x10; \
- if (val == 0xE80) \
- xl |= 0x10; \
- }
-#define BLDCDROM(xh, val) { \
- xh &= ~0x20; \
- if (val == 1) \
- xh |= 0x20; \
- }
-#define BLDCDROMADDR(xh, val) { \
- int tmp = val; \
- tmp -= 0x200; \
- tmp >>= 4; \
- tmp &= 0x1F; \
- xh |= tmp; \
- xh &= 0x7F; \
- xh |= 0x40; \
- }
-#endif /* CONFIG_SC6600 */
-
-/*
- * Bit mapped flags for calling aedsp16_init_board(), and saving the current
- * emulation mode.
- */
-#define INIT_NONE (0 )
-#define INIT_SBPRO (1<<0)
-#define INIT_MSS (1<<1)
-#define INIT_MPU401 (1<<2)
-
-static int soft_cfg __initdata = 0; /* bitmapped config */
-static int soft_cfg_mss __initdata = 0; /* bitmapped mss config */
-static int ver[CARDVERDIGITS] __initdata = {0, 0}; /* DSP Ver:
- hi->ver[0] lo->ver[1] */
-
-#if defined(CONFIG_SC6600)
-static int hard_cfg[2] /* lo<-hard_cfg[0] hi<-hard_cfg[1] */
- __initdata = { 0, 0};
-#endif /* CONFIG_SC6600 */
-
-#if defined(CONFIG_SC6600)
-/* Decoded hard configuration */
-struct d_hcfg {
- int iobase;
- int joystick;
- int mpubase;
- int wssbase;
- int cdrom;
- int cdrombase;
-};
-
-static struct d_hcfg decoded_hcfg __initdata = {0, };
-
-#endif /* CONFIG_SC6600 */
-
-/* orVals contain the values to be or'ed */
-struct orVals {
- int val; /* irq|mirq|dma */
- int or; /* soft_cfg |= TheStruct.or */
-};
-
-/* aedsp16_info contain the audio card configuration */
-struct aedsp16_info {
- int base_io; /* base I/O address for accessing card */
- int irq; /* irq value for DSP I/O */
- int mpu_irq; /* irq for mpu401 interface I/O */
- int dma; /* dma value for DSP I/O */
- int mss_base; /* base I/O for Microsoft Sound System */
- int mpu_base; /* base I/O for MPU-401 emulation */
- int init; /* Initialization status of the card */
-};
-
-/*
- * Magic values that the DSP will eat when configuring irq/mirq/dma
- */
-/* DSP IRQ conversion array */
-static struct orVals orIRQ[] __initdata = {
- {0x05, 0x28},
- {0x07, 0x08},
- {0x09, 0x10},
- {0x0a, 0x18},
- {0x0b, 0x20},
- {0x00, 0x00}
-};
-
-/* MPU-401 IRQ conversion array */
-static struct orVals orMIRQ[] __initdata = {
- {0x05, 0x04},
- {0x07, 0x44},
- {0x09, 0x84},
- {0x0a, 0xc4},
- {0x00, 0x00}
-};
-
-/* DMA Channels conversion array */
-static struct orVals orDMA[] __initdata = {
- {0x00, 0x01},
- {0x01, 0x02},
- {0x03, 0x03},
- {0x00, 0x00}
-};
-
-static struct aedsp16_info ae_config = {
- DEF_AEDSP16_IOB,
- DEF_AEDSP16_IRQ,
- DEF_AEDSP16_MRQ,
- DEF_AEDSP16_DMA,
- -1,
- -1,
- INIT_NONE
-};
-
-/*
- * Buffers to store audio card informations
- */
-static char DSPCopyright[CARDNAMELEN + 1] __initdata = {0, };
-static char DSPVersion[CARDVERLEN + 1] __initdata = {0, };
-
-static int __init aedsp16_wait_data(int port)
-{
- int loop = STATUSRETRY;
- unsigned char ret = 0;
-
- DBG1(("aedsp16_wait_data (0x%x): ", port));
-
- do {
- ret = inb(port + DSP_DATAVAIL);
- /*
- * Wait for data available (bit 7 of ret == 1)
- */
- } while (!(ret & 0x80) && loop--);
-
- if (ret & 0x80) {
- DBG1(("success.\n"));
- return TRUE;
- }
-
- DBG1(("failure.\n"));
- return FALSE;
-}
-
-static int __init aedsp16_read(int port)
-{
- int inbyte;
-
- DBG((" Read DSP Byte (0x%x): ", port));
-
- if (aedsp16_wait_data(port) == FALSE) {
- DBG(("failure.\n"));
- return -1;
- }
-
- inbyte = inb(port + DSP_READ);
-
- DBG(("read [0x%x]/{%c}.\n", inbyte, inbyte));
-
- return inbyte;
-}
-
-static int __init aedsp16_test_dsp(int port)
-{
- return ((aedsp16_read(port) == 0xaa) ? TRUE : FALSE);
-}
-
-static int __init aedsp16_dsp_reset(int port)
-{
- /*
- * Reset DSP
- */
-
- DBG(("Reset DSP:\n"));
-
- outb(1, (port + DSP_RESET));
- udelay(10);
- outb(0, (port + DSP_RESET));
- udelay(10);
- udelay(10);
- if (aedsp16_test_dsp(port) == TRUE) {
- DBG(("success.\n"));
- return TRUE;
- } else
- DBG(("failure.\n"));
- return FALSE;
-}
-
-static int __init aedsp16_write(int port, int cmd)
-{
- unsigned char ret;
- int loop = HARDRETRY;
-
- DBG((" Write DSP Byte (0x%x) [0x%x]: ", port, cmd));
-
- do {
- ret = inb(port + DSP_STATUS);
- /*
- * DSP ready to receive data if bit 7 of ret == 0
- */
- if (!(ret & 0x80)) {
- outb(cmd, port + DSP_COMMAND);
- DBG(("success.\n"));
- return 0;
- }
- } while (loop--);
-
- DBG(("timeout.\n"));
- printk("[AEDSP16] DSP Command (0x%x) timeout.\n", cmd);
-
- return -1;
-}
-
-#if defined(CONFIG_SC6600)
-
-#if defined(AEDSP16_INFO) || defined(AEDSP16_DEBUG)
-void __init aedsp16_pinfo(void) {
- DBG(("\n Base address: %x\n", decoded_hcfg.iobase));
- DBG((" Joystick : %s present\n", decoded_hcfg.joystick?"":" not"));
- DBG((" WSS addr : %x\n", decoded_hcfg.wssbase));
- DBG((" MPU-401 addr: %x\n", decoded_hcfg.mpubase));
- DBG((" CDROM : %s present\n", (decoded_hcfg.cdrom!=4)?"":" not"));
- DBG((" CDROMADDR : %x\n\n", decoded_hcfg.cdrombase));
-}
-#endif
-
-static void __init aedsp16_hard_decode(void) {
-
- DBG((" aedsp16_hard_decode: 0x%x, 0x%x\n", hard_cfg[0], hard_cfg[1]));
-
-/*
- * Decode Cfg Bytes.
- */
- decoded_hcfg.iobase = IOBASE(hard_cfg[0]);
- decoded_hcfg.joystick = JOY(hard_cfg[0]);
- decoded_hcfg.wssbase = WSSADDR(hard_cfg[0]);
- decoded_hcfg.mpubase = MPUADDR(hard_cfg[0]);
- decoded_hcfg.cdrom = CDROM(hard_cfg[1]);
- decoded_hcfg.cdrombase = CDROMADDR(hard_cfg[1]);
-
-#if defined(AEDSP16_INFO) || defined(AEDSP16_DEBUG)
- printk(" Original sound card configuration:\n");
- aedsp16_pinfo();
-#endif
-
-/*
- * Now set up the real kernel configuration.
- */
- decoded_hcfg.iobase = ae_config.base_io;
- decoded_hcfg.wssbase = ae_config.mss_base;
- decoded_hcfg.mpubase = ae_config.mpu_base;
-
-#if defined(CONFIG_SC6600_JOY)
- decoded_hcfg.joystick = CONFIG_SC6600_JOY; /* Enable */
-#endif
-#if defined(CONFIG_SC6600_CDROM)
- decoded_hcfg.cdrom = CONFIG_SC6600_CDROM; /* 4:N-3:I-2:G-1:P-0:S */
-#endif
-#if defined(CONFIG_SC6600_CDROMBASE)
- decoded_hcfg.cdrombase = CONFIG_SC6600_CDROMBASE; /* 0 Disable */
-#endif
-
-#if defined(AEDSP16_DEBUG)
- DBG((" New Values:\n"));
- aedsp16_pinfo();
-#endif
-
- DBG(("success.\n"));
-}
-
-static void __init aedsp16_hard_encode(void) {
-
- DBG((" aedsp16_hard_encode: 0x%x, 0x%x\n", hard_cfg[0], hard_cfg[1]));
-
- hard_cfg[0] = 0;
- hard_cfg[1] = 0;
-
- hard_cfg[0] |= 0x20;
-
- BLDIOBASE (hard_cfg[0], decoded_hcfg.iobase);
- BLDWSSADDR(hard_cfg[0], decoded_hcfg.wssbase);
- BLDMPUADDR(hard_cfg[0], decoded_hcfg.mpubase);
- BLDJOY(hard_cfg[0], decoded_hcfg.joystick);
- BLDCDROM(hard_cfg[1], decoded_hcfg.cdrom);
- BLDCDROMADDR(hard_cfg[1], decoded_hcfg.cdrombase);
-
-#if defined(AEDSP16_DEBUG)
- aedsp16_pinfo();
-#endif
-
- DBG((" aedsp16_hard_encode: 0x%x, 0x%x\n", hard_cfg[0], hard_cfg[1]));
- DBG(("success.\n"));
-
-}
-
-static int __init aedsp16_hard_write(int port) {
-
- DBG(("aedsp16_hard_write:\n"));
-
- if (aedsp16_write(port, COMMAND_6C)) {
- printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_6C);
- DBG(("failure.\n"));
- return FALSE;
- }
- if (aedsp16_write(port, COMMAND_5C)) {
- printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_5C);
- DBG(("failure.\n"));
- return FALSE;
- }
- if (aedsp16_write(port, hard_cfg[0])) {
- printk("[AEDSP16] DATA 0x%x: failed!\n", hard_cfg[0]);
- DBG(("failure.\n"));
- return FALSE;
- }
- if (aedsp16_write(port, hard_cfg[1])) {
- printk("[AEDSP16] DATA 0x%x: failed!\n", hard_cfg[1]);
- DBG(("failure.\n"));
- return FALSE;
- }
- if (aedsp16_write(port, COMMAND_C5)) {
- printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_C5);
- DBG(("failure.\n"));
- return FALSE;
- }
-
- DBG(("success.\n"));
-
- return TRUE;
-}
-
-static int __init aedsp16_hard_read(int port) {
-
- DBG(("aedsp16_hard_read:\n"));
-
- if (aedsp16_write(port, READ_HARD_CFG)) {
- printk("[AEDSP16] CMD 0x%x: failed!\n", READ_HARD_CFG);
- DBG(("failure.\n"));
- return FALSE;
- }
-
- if ((hard_cfg[0] = aedsp16_read(port)) == -1) {
- printk("[AEDSP16] aedsp16_read after CMD 0x%x: failed\n",
- READ_HARD_CFG);
- DBG(("failure.\n"));
- return FALSE;
- }
- if ((hard_cfg[1] = aedsp16_read(port)) == -1) {
- printk("[AEDSP16] aedsp16_read after CMD 0x%x: failed\n",
- READ_HARD_CFG);
- DBG(("failure.\n"));
- return FALSE;
- }
- if (aedsp16_read(port) == -1) {
- printk("[AEDSP16] aedsp16_read after CMD 0x%x: failed\n",
- READ_HARD_CFG);
- DBG(("failure.\n"));
- return FALSE;
- }
-
- DBG(("success.\n"));
-
- return TRUE;
-}
-
-static int __init aedsp16_ext_cfg_write(int port) {
-
- int extcfg, val;
-
- if (aedsp16_write(port, COMMAND_66)) {
- printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_66);
- return FALSE;
- }
-
- extcfg = 7;
- if (decoded_hcfg.cdrom != 2)
- extcfg = 0x0F;
- if ((decoded_hcfg.cdrom == 4) ||
- (decoded_hcfg.cdrom == 3))
- extcfg &= ~2;
- if (decoded_hcfg.cdrombase == 0)
- extcfg &= ~2;
- if (decoded_hcfg.mpubase == 0)
- extcfg &= ~1;
-
- if (aedsp16_write(port, extcfg)) {
- printk("[AEDSP16] Write extcfg: failed!\n");
- return FALSE;
- }
- if (aedsp16_write(port, 0)) {
- printk("[AEDSP16] Write extcfg: failed!\n");
- return FALSE;
- }
- if (decoded_hcfg.cdrom == 3) {
- if (aedsp16_write(port, COMMAND_52)) {
- printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_52);
- return FALSE;
- }
- if ((val = aedsp16_read(port)) == -1) {
- printk("[AEDSP16] aedsp16_read after CMD 0x%x: failed\n"
- , COMMAND_52);
- return FALSE;
- }
- val &= 0x7F;
- if (aedsp16_write(port, COMMAND_60)) {
- printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_60);
- return FALSE;
- }
- if (aedsp16_write(port, val)) {
- printk("[AEDSP16] Write val: failed!\n");
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-#endif /* CONFIG_SC6600 */
-
-static int __init aedsp16_cfg_write(int port) {
- if (aedsp16_write(port, WRITE_MDIRQ_CFG)) {
- printk("[AEDSP16] CMD 0x%x: failed!\n", WRITE_MDIRQ_CFG);
- return FALSE;
- }
- if (aedsp16_write(port, soft_cfg)) {
- printk("[AEDSP16] Initialization of (M)IRQ and DMA: failed!\n");
- return FALSE;
- }
- return TRUE;
-}
-
-static int __init aedsp16_init_mss(int port)
-{
- DBG(("aedsp16_init_mss:\n"));
-
- mdelay(10);
-
- if (aedsp16_write(port, DSP_INIT_MSS)) {
- printk("[AEDSP16] aedsp16_init_mss [0x%x]: failed!\n",
- DSP_INIT_MSS);
- DBG(("failure.\n"));
- return FALSE;
- }
-
- mdelay(10);
-
- if (aedsp16_cfg_write(port) == FALSE)
- return FALSE;
-
- outb(soft_cfg_mss, ae_config.mss_base);
-
- DBG(("success.\n"));
-
- return TRUE;
-}
-
-static int __init aedsp16_setup_board(int port) {
- int loop = RETRY;
-
-#if defined(CONFIG_SC6600)
- int val = 0;
-
- if (aedsp16_hard_read(port) == FALSE) {
- printk("[AEDSP16] aedsp16_hard_read: failed!\n");
- return FALSE;
- }
-
- if (aedsp16_write(port, COMMAND_52)) {
- printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_52);
- return FALSE;
- }
-
- if ((val = aedsp16_read(port)) == -1) {
- printk("[AEDSP16] aedsp16_read after CMD 0x%x: failed\n",
- COMMAND_52);
- return FALSE;
- }
-#endif
-
- do {
- if (aedsp16_write(port, COMMAND_88)) {
- printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_88);
- return FALSE;
- }
- mdelay(10);
- } while ((aedsp16_wait_data(port) == FALSE) && loop--);
-
- if (aedsp16_read(port) == -1) {
- printk("[AEDSP16] aedsp16_read after CMD 0x%x: failed\n",
- COMMAND_88);
- return FALSE;
- }
-
-#if !defined(CONFIG_SC6600)
- if (aedsp16_write(port, COMMAND_5C)) {
- printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_5C);
- return FALSE;
- }
-#endif
-
- if (aedsp16_cfg_write(port) == FALSE)
- return FALSE;
-
-#if defined(CONFIG_SC6600)
- if (aedsp16_write(port, COMMAND_60)) {
- printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_60);
- return FALSE;
- }
- if (aedsp16_write(port, val)) {
- printk("[AEDSP16] DATA 0x%x: failed!\n", val);
- return FALSE;
- }
- if (aedsp16_write(port, COMMAND_6E)) {
- printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_6E);
- return FALSE;
- }
- if (aedsp16_write(port, ver[0])) {
- printk("[AEDSP16] DATA 0x%x: failed!\n", ver[0]);
- return FALSE;
- }
- if (aedsp16_write(port, ver[1])) {
- printk("[AEDSP16] DATA 0x%x: failed!\n", ver[1]);
- return FALSE;
- }
-
- if (aedsp16_hard_write(port) == FALSE) {
- printk("[AEDSP16] aedsp16_hard_write: failed!\n");
- return FALSE;
- }
-
- if (aedsp16_write(port, COMMAND_5C)) {
- printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_5C);
- return FALSE;
- }
-
-#if defined(THIS_IS_A_THING_I_HAVE_NOT_TESTED_YET)
- if (aedsp16_cfg_write(port) == FALSE)
- return FALSE;
-#endif
-
-#endif
-
- return TRUE;
-}
-
-static int __init aedsp16_stdcfg(int port) {
- if (aedsp16_write(port, WRITE_MDIRQ_CFG)) {
- printk("[AEDSP16] CMD 0x%x: failed!\n", WRITE_MDIRQ_CFG);
- return FALSE;
- }
- /*
- * 0x0A == (IRQ 7, DMA 1, MIRQ 0)
- */
- if (aedsp16_write(port, 0x0A)) {
- printk("[AEDSP16] aedsp16_stdcfg: failed!\n");
- return FALSE;
- }
- return TRUE;
-}
-
-static int __init aedsp16_dsp_version(int port)
-{
- int len = 0;
- int ret;
-
- DBG(("Get DSP Version:\n"));
-
- if (aedsp16_write(ae_config.base_io, GET_DSP_VERSION)) {
- printk("[AEDSP16] CMD 0x%x: failed!\n", GET_DSP_VERSION);
- DBG(("failed.\n"));
- return FALSE;
- }
-
- do {
- if ((ret = aedsp16_read(port)) == -1) {
- DBG(("failed.\n"));
- return FALSE;
- }
- /*
- * We already know how many int are stored (2), so we know when the
- * string is finished.
- */
- ver[len++] = ret;
- } while (len < CARDVERDIGITS);
- sprintf(DSPVersion, "%d.%d", ver[0], ver[1]);
-
- DBG(("success.\n"));
-
- return TRUE;
-}
-
-static int __init aedsp16_dsp_copyright(int port)
-{
- int len = 0;
- int ret;
-
- DBG(("Get DSP Copyright:\n"));
-
- if (aedsp16_write(ae_config.base_io, GET_DSP_COPYRIGHT)) {
- printk("[AEDSP16] CMD 0x%x: failed!\n", GET_DSP_COPYRIGHT);
- DBG(("failed.\n"));
- return FALSE;
- }
-
- do {
- if ((ret = aedsp16_read(port)) == -1) {
- /*
- * If no more data available, return to the caller, no error if len>0.
- * We have no other way to know when the string is finished.
- */
- if (len)
- break;
- else {
- DBG(("failed.\n"));
- return FALSE;
- }
- }
-
- DSPCopyright[len++] = ret;
-
- } while (len < CARDNAMELEN);
-
- DBG(("success.\n"));
-
- return TRUE;
-}
-
-static void __init aedsp16_init_tables(void)
-{
- int i = 0;
-
- memset(DSPCopyright, 0, CARDNAMELEN + 1);
- memset(DSPVersion, 0, CARDVERLEN + 1);
-
- for (i = 0; orIRQ[i].or; i++)
- if (orIRQ[i].val == ae_config.irq) {
- soft_cfg |= orIRQ[i].or;
- soft_cfg_mss |= orIRQ[i].or;
- }
-
- for (i = 0; orMIRQ[i].or; i++)
- if (orMIRQ[i].or == ae_config.mpu_irq)
- soft_cfg |= orMIRQ[i].or;
-
- for (i = 0; orDMA[i].or; i++)
- if (orDMA[i].val == ae_config.dma) {
- soft_cfg |= orDMA[i].or;
- soft_cfg_mss |= orDMA[i].or;
- }
-}
-
-static int __init aedsp16_init_board(void)
-{
- aedsp16_init_tables();
-
- if (aedsp16_dsp_reset(ae_config.base_io) == FALSE) {
- printk("[AEDSP16] aedsp16_dsp_reset: failed!\n");
- return FALSE;
- }
- if (aedsp16_dsp_copyright(ae_config.base_io) == FALSE) {
- printk("[AEDSP16] aedsp16_dsp_copyright: failed!\n");
- return FALSE;
- }
-
- /*
- * My AEDSP16 card return SC-6000 in DSPCopyright, so
- * if we have something different, we have to be warned.
- */
- if (strcmp("SC-6000", DSPCopyright))
- printk("[AEDSP16] Warning: non SC-6000 audio card!\n");
-
- if (aedsp16_dsp_version(ae_config.base_io) == FALSE) {
- printk("[AEDSP16] aedsp16_dsp_version: failed!\n");
- return FALSE;
- }
-
- if (aedsp16_stdcfg(ae_config.base_io) == FALSE) {
- printk("[AEDSP16] aedsp16_stdcfg: failed!\n");
- return FALSE;
- }
-
-#if defined(CONFIG_SC6600)
- if (aedsp16_hard_read(ae_config.base_io) == FALSE) {
- printk("[AEDSP16] aedsp16_hard_read: failed!\n");
- return FALSE;
- }
-
- aedsp16_hard_decode();
-
- aedsp16_hard_encode();
-
- if (aedsp16_hard_write(ae_config.base_io) == FALSE) {
- printk("[AEDSP16] aedsp16_hard_write: failed!\n");
- return FALSE;
- }
-
- if (aedsp16_ext_cfg_write(ae_config.base_io) == FALSE) {
- printk("[AEDSP16] aedsp16_ext_cfg_write: failed!\n");
- return FALSE;
- }
-#endif /* CONFIG_SC6600 */
-
- if (aedsp16_setup_board(ae_config.base_io) == FALSE) {
- printk("[AEDSP16] aedsp16_setup_board: failed!\n");
- return FALSE;
- }
-
- if (ae_config.mss_base != -1) {
- if (ae_config.init & INIT_MSS) {
- if (aedsp16_init_mss(ae_config.base_io) == FALSE) {
- printk("[AEDSP16] Can not initialize"
- "Microsoft Sound System mode.\n");
- return FALSE;
- }
- }
- }
-
-#if !defined(MODULE) || defined(AEDSP16_INFO) || defined(AEDSP16_DEBUG)
-
- printk("Audio Excel DSP 16 init v%s (%s %s) [",
- VERSION, DSPCopyright,
- DSPVersion);
-
- if (ae_config.mpu_base != -1) {
- if (ae_config.init & INIT_MPU401) {
- printk("MPU401");
- if ((ae_config.init & INIT_MSS) ||
- (ae_config.init & INIT_SBPRO))
- printk(" ");
- }
- }
-
- if (ae_config.mss_base == -1) {
- if (ae_config.init & INIT_SBPRO) {
- printk("SBPro");
- if (ae_config.init & INIT_MSS)
- printk(" ");
- }
- }
-
- if (ae_config.mss_base != -1)
- if (ae_config.init & INIT_MSS)
- printk("MSS");
-
- printk("]\n");
-#endif /* MODULE || AEDSP16_INFO || AEDSP16_DEBUG */
-
- mdelay(10);
-
- return TRUE;
-}
-
-static int __init init_aedsp16_sb(void)
-{
- DBG(("init_aedsp16_sb: "));
-
-/*
- * If the card is already init'ed MSS, we can not init it to SBPRO too
- * because the board can not emulate simultaneously MSS and SBPRO.
- */
- if (ae_config.init & INIT_MSS)
- return FALSE;
- if (ae_config.init & INIT_SBPRO)
- return FALSE;
-
- ae_config.init |= INIT_SBPRO;
-
- DBG(("done.\n"));
-
- return TRUE;
-}
-
-static void uninit_aedsp16_sb(void)
-{
- DBG(("uninit_aedsp16_sb: "));
-
- ae_config.init &= ~INIT_SBPRO;
-
- DBG(("done.\n"));
-}
-
-static int __init init_aedsp16_mss(void)
-{
- DBG(("init_aedsp16_mss: "));
-
-/*
- * If the card is already init'ed SBPRO, we can not init it to MSS too
- * because the board can not emulate simultaneously MSS and SBPRO.
- */
- if (ae_config.init & INIT_SBPRO)
- return FALSE;
- if (ae_config.init & INIT_MSS)
- return FALSE;
-/*
- * We must allocate the CONFIG_AEDSP16_BASE region too because these are the
- * I/O ports to access card's control registers.
- */
- if (!(ae_config.init & INIT_MPU401)) {
- if (!request_region(ae_config.base_io, IOBASE_REGION_SIZE,
- "aedsp16 (base)")) {
- printk(
- "AEDSP16 BASE I/O port region is already in use.\n");
- return FALSE;
- }
- }
-
- ae_config.init |= INIT_MSS;
-
- DBG(("done.\n"));
-
- return TRUE;
-}
-
-static void uninit_aedsp16_mss(void)
-{
- DBG(("uninit_aedsp16_mss: "));
-
- if ((!(ae_config.init & INIT_MPU401)) &&
- (ae_config.init & INIT_MSS)) {
- release_region(ae_config.base_io, IOBASE_REGION_SIZE);
- DBG(("AEDSP16 base region released.\n"));
- }
-
- ae_config.init &= ~INIT_MSS;
- DBG(("done.\n"));
-}
-
-static int __init init_aedsp16_mpu(void)
-{
- DBG(("init_aedsp16_mpu: "));
-
- if (ae_config.init & INIT_MPU401)
- return FALSE;
-
-/*
- * We must request the CONFIG_AEDSP16_BASE region too because these are the I/O
- * ports to access card's control registers.
- */
- if (!(ae_config.init & (INIT_MSS | INIT_SBPRO))) {
- if (!request_region(ae_config.base_io, IOBASE_REGION_SIZE,
- "aedsp16 (base)")) {
- printk(
- "AEDSP16 BASE I/O port region is already in use.\n");
- return FALSE;
- }
- }
-
- ae_config.init |= INIT_MPU401;
-
- DBG(("done.\n"));
-
- return TRUE;
-}
-
-static void uninit_aedsp16_mpu(void)
-{
- DBG(("uninit_aedsp16_mpu: "));
-
- if ((!(ae_config.init & (INIT_MSS | INIT_SBPRO))) &&
- (ae_config.init & INIT_MPU401)) {
- release_region(ae_config.base_io, IOBASE_REGION_SIZE);
- DBG(("AEDSP16 base region released.\n"));
- }
-
- ae_config.init &= ~INIT_MPU401;
-
- DBG(("done.\n"));
-}
-
-static int __init init_aedsp16(void)
-{
- int initialized = FALSE;
-
- DBG(("Initializing BASE[0x%x] IRQ[%d] DMA[%d] MIRQ[%d]\n",
- ae_config.base_io,ae_config.irq,ae_config.dma,ae_config.mpu_irq));
-
- if (ae_config.mss_base == -1) {
- if (init_aedsp16_sb() == FALSE) {
- uninit_aedsp16_sb();
- } else {
- initialized = TRUE;
- }
- }
-
- if (ae_config.mpu_base != -1) {
- if (init_aedsp16_mpu() == FALSE) {
- uninit_aedsp16_mpu();
- } else {
- initialized = TRUE;
- }
- }
-
-/*
- * In the sequence of init routines, the MSS init MUST be the last!
- * This because of the special register programming the MSS mode needs.
- * A board reset would disable the MSS mode restoring the default SBPRO
- * mode.
- */
- if (ae_config.mss_base != -1) {
- if (init_aedsp16_mss() == FALSE) {
- uninit_aedsp16_mss();
- } else {
- initialized = TRUE;
- }
- }
-
- if (initialized)
- initialized = aedsp16_init_board();
- return initialized;
-}
-
-static void __exit uninit_aedsp16(void)
-{
- if (ae_config.mss_base != -1)
- uninit_aedsp16_mss();
- else
- uninit_aedsp16_sb();
- if (ae_config.mpu_base != -1)
- uninit_aedsp16_mpu();
-}
-
-static int __initdata io = -1;
-static int __initdata irq = -1;
-static int __initdata dma = -1;
-static int __initdata mpu_irq = -1;
-static int __initdata mss_base = -1;
-static int __initdata mpu_base = -1;
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O base address (0x220 0x240)");
-module_param(irq, int, 0);
-MODULE_PARM_DESC(irq, "IRQ line (5 7 9 10 11)");
-module_param(dma, int, 0);
-MODULE_PARM_DESC(dma, "dma line (0 1 3)");
-module_param(mpu_irq, int, 0);
-MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ line (5 7 9 10 0)");
-module_param(mss_base, int, 0);
-MODULE_PARM_DESC(mss_base, "MSS emulation I/O base address (0x530 0xE80)");
-module_param(mpu_base, int, 0);
-MODULE_PARM_DESC(mpu_base,"MPU-401 I/O base address (0x300 0x310 0x320 0x330)");
-MODULE_AUTHOR("Riccardo Facchetti <fizban@tin.it>");
-MODULE_DESCRIPTION("Audio Excel DSP 16 Driver Version " VERSION);
-MODULE_LICENSE("GPL");
-
-static int __init do_init_aedsp16(void) {
- printk("Audio Excel DSP 16 init driver Copyright (C) Riccardo Facchetti 1995-98\n");
- if (io == -1 || dma == -1 || irq == -1) {
- printk(KERN_INFO "aedsp16: I/O, IRQ and DMA are mandatory\n");
- return -EINVAL;
- }
-
- ae_config.base_io = io;
- ae_config.irq = irq;
- ae_config.dma = dma;
-
- ae_config.mss_base = mss_base;
- ae_config.mpu_base = mpu_base;
- ae_config.mpu_irq = mpu_irq;
-
- if (init_aedsp16() == FALSE) {
- printk(KERN_ERR "aedsp16: initialization failed\n");
- /*
- * XXX
- * What error should we return here ?
- */
- return -EINVAL;
- }
- return 0;
-}
-
-static void __exit cleanup_aedsp16(void) {
- uninit_aedsp16();
-}
-
-module_init(do_init_aedsp16);
-module_exit(cleanup_aedsp16);
-
-#ifndef MODULE
-static int __init setup_aedsp16(char *str)
-{
- /* io, irq, dma, mss_io, mpu_io, mpu_irq */
- int ints[7];
-
- str = get_options(str, ARRAY_SIZE(ints), ints);
-
- io = ints[1];
- irq = ints[2];
- dma = ints[3];
- mss_base = ints[4];
- mpu_base = ints[5];
- mpu_irq = ints[6];
- return 1;
-}
-
-__setup("aedsp16=", setup_aedsp16);
-#endif
diff --git a/ANDROID_3.4.5/sound/oss/audio.c b/ANDROID_3.4.5/sound/oss/audio.c
deleted file mode 100644
index 4b958b1c..00000000
--- a/ANDROID_3.4.5/sound/oss/audio.c
+++ /dev/null
@@ -1,985 +0,0 @@
-/*
- * sound/oss/audio.c
- *
- * Device file manager for /dev/audio
- */
-
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-/*
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
- * Thomas Sailer : moved several static variables into struct audio_operations
- * (which is grossly misnamed btw.) because they have the same
- * lifetime as the rest in there and dynamic allocation saves
- * 12k or so
- * Thomas Sailer : use more logical O_NONBLOCK semantics
- * Daniel Rodriksson: reworked the use of the device specific copy_user
- * still generic
- * Horst von Brand: Add missing #include <linux/string.h>
- * Chris Rankin : Update the module-usage counter for the coprocessor,
- * and decrement the counters again if we cannot open
- * the audio device.
- */
-
-#include <linux/stddef.h>
-#include <linux/string.h>
-#include <linux/kmod.h>
-
-#include "sound_config.h"
-#include "ulaw.h"
-#include "coproc.h"
-
-#define NEUTRAL8 0x80
-#define NEUTRAL16 0x00
-
-
-static int dma_ioctl(int dev, unsigned int cmd, void __user *arg);
-
-static int set_format(int dev, int fmt)
-{
- if (fmt != AFMT_QUERY)
- {
- audio_devs[dev]->local_conversion = 0;
-
- if (!(audio_devs[dev]->format_mask & fmt)) /* Not supported */
- {
- if (fmt == AFMT_MU_LAW)
- {
- fmt = AFMT_U8;
- audio_devs[dev]->local_conversion = CNV_MU_LAW;
- }
- else
- fmt = AFMT_U8; /* This is always supported */
- }
- audio_devs[dev]->audio_format = audio_devs[dev]->d->set_bits(dev, fmt);
- audio_devs[dev]->local_format = fmt;
- }
- else
- return audio_devs[dev]->local_format;
-
- if (audio_devs[dev]->local_conversion)
- return audio_devs[dev]->local_conversion;
- else
- return audio_devs[dev]->local_format;
-}
-
-int audio_open(int dev, struct file *file)
-{
- int ret;
- int bits;
- int dev_type = dev & 0x0f;
- int mode = translate_mode(file);
- const struct audio_driver *driver;
- const struct coproc_operations *coprocessor;
-
- dev = dev >> 4;
-
- if (dev_type == SND_DEV_DSP16)
- bits = 16;
- else
- bits = 8;
-
- if (dev < 0 || dev >= num_audiodevs)
- return -ENXIO;
-
- driver = audio_devs[dev]->d;
-
- if (!try_module_get(driver->owner))
- return -ENODEV;
-
- if ((ret = DMAbuf_open(dev, mode)) < 0)
- goto error_1;
-
- if ( (coprocessor = audio_devs[dev]->coproc) != NULL ) {
- if (!try_module_get(coprocessor->owner))
- goto error_2;
-
- if ((ret = coprocessor->open(coprocessor->devc, COPR_PCM)) < 0) {
- printk(KERN_WARNING "Sound: Can't access coprocessor device\n");
- goto error_3;
- }
- }
-
- audio_devs[dev]->local_conversion = 0;
-
- if (dev_type == SND_DEV_AUDIO)
- set_format(dev, AFMT_MU_LAW);
- else
- set_format(dev, bits);
-
- audio_devs[dev]->audio_mode = AM_NONE;
-
- return 0;
-
- /*
- * Clean-up stack: this is what needs (un)doing if
- * we can't open the audio device ...
- */
- error_3:
- module_put(coprocessor->owner);
-
- error_2:
- DMAbuf_release(dev, mode);
-
- error_1:
- module_put(driver->owner);
-
- return ret;
-}
-
-static void sync_output(int dev)
-{
- int p, i;
- int l;
- struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
-
- if (dmap->fragment_size <= 0)
- return;
- dmap->flags |= DMA_POST;
-
- /* Align the write pointer with fragment boundaries */
-
- if ((l = dmap->user_counter % dmap->fragment_size) > 0)
- {
- int len;
- unsigned long offs = dmap->user_counter % dmap->bytes_in_use;
-
- len = dmap->fragment_size - l;
- memset(dmap->raw_buf + offs, dmap->neutral_byte, len);
- DMAbuf_move_wrpointer(dev, len);
- }
-
- /*
- * Clean all unused buffer fragments.
- */
-
- p = dmap->qtail;
- dmap->flags |= DMA_POST;
-
- for (i = dmap->qlen + 1; i < dmap->nbufs; i++)
- {
- p = (p + 1) % dmap->nbufs;
- if (((dmap->raw_buf + p * dmap->fragment_size) + dmap->fragment_size) >
- (dmap->raw_buf + dmap->buffsize))
- printk(KERN_ERR "audio: Buffer error 2\n");
-
- memset(dmap->raw_buf + p * dmap->fragment_size,
- dmap->neutral_byte,
- dmap->fragment_size);
- }
-
- dmap->flags |= DMA_DIRTY;
-}
-
-void audio_release(int dev, struct file *file)
-{
- const struct coproc_operations *coprocessor;
- int mode = translate_mode(file);
-
- dev = dev >> 4;
-
- /*
- * We do this in DMAbuf_release(). Why are we doing it
- * here? Why don't we test the file mode before setting
- * both flags? DMAbuf_release() does.
- * ...pester...pester...pester...
- */
- audio_devs[dev]->dmap_out->closing = 1;
- audio_devs[dev]->dmap_in->closing = 1;
-
- /*
- * We need to make sure we allocated the dmap_out buffer
- * before we go mucking around with it in sync_output().
- */
- if (mode & OPEN_WRITE)
- sync_output(dev);
-
- if ( (coprocessor = audio_devs[dev]->coproc) != NULL ) {
- coprocessor->close(coprocessor->devc, COPR_PCM);
- module_put(coprocessor->owner);
- }
- DMAbuf_release(dev, mode);
-
- module_put(audio_devs[dev]->d->owner);
-}
-
-static void translate_bytes(const unsigned char *table, unsigned char *buff, int n)
-{
- unsigned long i;
-
- if (n <= 0)
- return;
-
- for (i = 0; i < n; ++i)
- buff[i] = table[buff[i]];
-}
-
-int audio_write(int dev, struct file *file, const char __user *buf, int count)
-{
- int c, p, l, buf_size, used, returned;
- int err;
- char *dma_buf;
-
- dev = dev >> 4;
-
- p = 0;
- c = count;
-
- if(count < 0)
- return -EINVAL;
-
- if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
- return -EPERM;
-
- if (audio_devs[dev]->flags & DMA_DUPLEX)
- audio_devs[dev]->audio_mode |= AM_WRITE;
- else
- audio_devs[dev]->audio_mode = AM_WRITE;
-
- if (!count) /* Flush output */
- {
- sync_output(dev);
- return 0;
- }
-
- while (c)
- {
- if ((err = DMAbuf_getwrbuffer(dev, &dma_buf, &buf_size, !!(file->f_flags & O_NONBLOCK))) < 0)
- {
- /* Handle nonblocking mode */
- if ((file->f_flags & O_NONBLOCK) && err == -EAGAIN)
- return p? p : -EAGAIN; /* No more space. Return # of accepted bytes */
- return err;
- }
- l = c;
-
- if (l > buf_size)
- l = buf_size;
-
- returned = l;
- used = l;
- if (!audio_devs[dev]->d->copy_user)
- {
- if ((dma_buf + l) >
- (audio_devs[dev]->dmap_out->raw_buf + audio_devs[dev]->dmap_out->buffsize))
- {
- printk(KERN_ERR "audio: Buffer error 3 (%lx,%d), (%lx, %d)\n", (long) dma_buf, l, (long) audio_devs[dev]->dmap_out->raw_buf, (int) audio_devs[dev]->dmap_out->buffsize);
- return -EDOM;
- }
- if (dma_buf < audio_devs[dev]->dmap_out->raw_buf)
- {
- printk(KERN_ERR "audio: Buffer error 13 (%lx<%lx)\n", (long) dma_buf, (long) audio_devs[dev]->dmap_out->raw_buf);
- return -EDOM;
- }
- if(copy_from_user(dma_buf, &(buf)[p], l))
- return -EFAULT;
- }
- else audio_devs[dev]->d->copy_user (dev,
- dma_buf, 0,
- buf, p,
- c, buf_size,
- &used, &returned,
- l);
- l = returned;
-
- if (audio_devs[dev]->local_conversion & CNV_MU_LAW)
- {
- translate_bytes(ulaw_dsp, (unsigned char *) dma_buf, l);
- }
- c -= used;
- p += used;
- DMAbuf_move_wrpointer(dev, l);
-
- }
-
- return count;
-}
-
-int audio_read(int dev, struct file *file, char __user *buf, int count)
-{
- int c, p, l;
- char *dmabuf;
- int buf_no;
-
- dev = dev >> 4;
- p = 0;
- c = count;
-
- if (!(audio_devs[dev]->open_mode & OPEN_READ))
- return -EPERM;
-
- if ((audio_devs[dev]->audio_mode & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
- sync_output(dev);
-
- if (audio_devs[dev]->flags & DMA_DUPLEX)
- audio_devs[dev]->audio_mode |= AM_READ;
- else
- audio_devs[dev]->audio_mode = AM_READ;
-
- while(c)
- {
- if ((buf_no = DMAbuf_getrdbuffer(dev, &dmabuf, &l, !!(file->f_flags & O_NONBLOCK))) < 0)
- {
- /*
- * Nonblocking mode handling. Return current # of bytes
- */
-
- if (p > 0) /* Avoid throwing away data */
- return p; /* Return it instead */
-
- if ((file->f_flags & O_NONBLOCK) && buf_no == -EAGAIN)
- return -EAGAIN;
-
- return buf_no;
- }
- if (l > c)
- l = c;
-
- /*
- * Insert any local processing here.
- */
-
- if (audio_devs[dev]->local_conversion & CNV_MU_LAW)
- {
- translate_bytes(dsp_ulaw, (unsigned char *) dmabuf, l);
- }
-
- {
- char *fixit = dmabuf;
-
- if(copy_to_user(&(buf)[p], fixit, l))
- return -EFAULT;
- };
-
- DMAbuf_rmchars(dev, buf_no, l);
-
- p += l;
- c -= l;
- }
-
- return count - c;
-}
-
-int audio_ioctl(int dev, struct file *file, unsigned int cmd, void __user *arg)
-{
- int val, count;
- unsigned long flags;
- struct dma_buffparms *dmap;
- int __user *p = arg;
-
- dev = dev >> 4;
-
- if (_IOC_TYPE(cmd) == 'C') {
- if (audio_devs[dev]->coproc) /* Coprocessor ioctl */
- return audio_devs[dev]->coproc->ioctl(audio_devs[dev]->coproc->devc, cmd, arg, 0);
- /* else
- printk(KERN_DEBUG"/dev/dsp%d: No coprocessor for this device\n", dev); */
- return -ENXIO;
- }
- else switch (cmd)
- {
- case SNDCTL_DSP_SYNC:
- if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
- return 0;
- if (audio_devs[dev]->dmap_out->fragment_size == 0)
- return 0;
- sync_output(dev);
- DMAbuf_sync(dev);
- DMAbuf_reset(dev);
- return 0;
-
- case SNDCTL_DSP_POST:
- if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
- return 0;
- if (audio_devs[dev]->dmap_out->fragment_size == 0)
- return 0;
- audio_devs[dev]->dmap_out->flags |= DMA_POST | DMA_DIRTY;
- sync_output(dev);
- dma_ioctl(dev, SNDCTL_DSP_POST, NULL);
- return 0;
-
- case SNDCTL_DSP_RESET:
- audio_devs[dev]->audio_mode = AM_NONE;
- DMAbuf_reset(dev);
- return 0;
-
- case SNDCTL_DSP_GETFMTS:
- val = audio_devs[dev]->format_mask | AFMT_MU_LAW;
- break;
-
- case SNDCTL_DSP_SETFMT:
- if (get_user(val, p))
- return -EFAULT;
- val = set_format(dev, val);
- break;
-
- case SNDCTL_DSP_GETISPACE:
- if (!(audio_devs[dev]->open_mode & OPEN_READ))
- return 0;
- if ((audio_devs[dev]->audio_mode & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
- return -EBUSY;
- return dma_ioctl(dev, cmd, arg);
-
- case SNDCTL_DSP_GETOSPACE:
- if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
- return -EPERM;
- if ((audio_devs[dev]->audio_mode & AM_READ) && !(audio_devs[dev]->flags & DMA_DUPLEX))
- return -EBUSY;
- return dma_ioctl(dev, cmd, arg);
-
- case SNDCTL_DSP_NONBLOCK:
- spin_lock(&file->f_lock);
- file->f_flags |= O_NONBLOCK;
- spin_unlock(&file->f_lock);
- return 0;
-
- case SNDCTL_DSP_GETCAPS:
- val = 1 | DSP_CAP_MMAP; /* Revision level of this ioctl() */
- if (audio_devs[dev]->flags & DMA_DUPLEX &&
- audio_devs[dev]->open_mode == OPEN_READWRITE)
- val |= DSP_CAP_DUPLEX;
- if (audio_devs[dev]->coproc)
- val |= DSP_CAP_COPROC;
- if (audio_devs[dev]->d->local_qlen) /* Device has hidden buffers */
- val |= DSP_CAP_BATCH;
- if (audio_devs[dev]->d->trigger) /* Supports SETTRIGGER */
- val |= DSP_CAP_TRIGGER;
- break;
-
- case SOUND_PCM_WRITE_RATE:
- if (get_user(val, p))
- return -EFAULT;
- val = audio_devs[dev]->d->set_speed(dev, val);
- break;
-
- case SOUND_PCM_READ_RATE:
- val = audio_devs[dev]->d->set_speed(dev, 0);
- break;
-
- case SNDCTL_DSP_STEREO:
- if (get_user(val, p))
- return -EFAULT;
- if (val > 1 || val < 0)
- return -EINVAL;
- val = audio_devs[dev]->d->set_channels(dev, val + 1) - 1;
- break;
-
- case SOUND_PCM_WRITE_CHANNELS:
- if (get_user(val, p))
- return -EFAULT;
- val = audio_devs[dev]->d->set_channels(dev, val);
- break;
-
- case SOUND_PCM_READ_CHANNELS:
- val = audio_devs[dev]->d->set_channels(dev, 0);
- break;
-
- case SOUND_PCM_READ_BITS:
- val = audio_devs[dev]->d->set_bits(dev, 0);
- break;
-
- case SNDCTL_DSP_SETDUPLEX:
- if (audio_devs[dev]->open_mode != OPEN_READWRITE)
- return -EPERM;
- return (audio_devs[dev]->flags & DMA_DUPLEX) ? 0 : -EIO;
-
- case SNDCTL_DSP_PROFILE:
- if (get_user(val, p))
- return -EFAULT;
- if (audio_devs[dev]->open_mode & OPEN_WRITE)
- audio_devs[dev]->dmap_out->applic_profile = val;
- if (audio_devs[dev]->open_mode & OPEN_READ)
- audio_devs[dev]->dmap_in->applic_profile = val;
- return 0;
-
- case SNDCTL_DSP_GETODELAY:
- dmap = audio_devs[dev]->dmap_out;
- if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
- return -EINVAL;
- if (!(dmap->flags & DMA_ALLOC_DONE))
- {
- val=0;
- break;
- }
-
- spin_lock_irqsave(&dmap->lock,flags);
- /* Compute number of bytes that have been played */
- count = DMAbuf_get_buffer_pointer (dev, dmap, DMODE_OUTPUT);
- if (count < dmap->fragment_size && dmap->qhead != 0)
- count += dmap->bytes_in_use; /* Pointer wrap not handled yet */
- count += dmap->byte_counter;
-
- /* Subtract current count from the number of bytes written by app */
- count = dmap->user_counter - count;
- if (count < 0)
- count = 0;
- spin_unlock_irqrestore(&dmap->lock,flags);
- val = count;
- break;
-
- default:
- return dma_ioctl(dev, cmd, arg);
- }
- return put_user(val, p);
-}
-
-void audio_init_devices(void)
-{
- /*
- * NOTE! This routine could be called several times during boot.
- */
-}
-
-void reorganize_buffers(int dev, struct dma_buffparms *dmap, int recording)
-{
- /*
- * This routine breaks the physical device buffers to logical ones.
- */
-
- struct audio_operations *dsp_dev = audio_devs[dev];
-
- unsigned i, n;
- unsigned sr, nc, sz, bsz;
-
- sr = dsp_dev->d->set_speed(dev, 0);
- nc = dsp_dev->d->set_channels(dev, 0);
- sz = dsp_dev->d->set_bits(dev, 0);
-
- if (sz == 8)
- dmap->neutral_byte = NEUTRAL8;
- else
- dmap->neutral_byte = NEUTRAL16;
-
- if (sr < 1 || nc < 1 || sz < 1)
- {
-/* printk(KERN_DEBUG "Warning: Invalid PCM parameters[%d] sr=%d, nc=%d, sz=%d\n", dev, sr, nc, sz);*/
- sr = DSP_DEFAULT_SPEED;
- nc = 1;
- sz = 8;
- }
-
- sz = sr * nc * sz;
-
- sz /= 8; /* #bits -> #bytes */
- dmap->data_rate = sz;
-
- if (!dmap->needs_reorg)
- return;
- dmap->needs_reorg = 0;
-
- if (dmap->fragment_size == 0)
- {
- /* Compute the fragment size using the default algorithm */
-
- /*
- * Compute a buffer size for time not exceeding 1 second.
- * Usually this algorithm gives a buffer size for 0.5 to 1.0 seconds
- * of sound (using the current speed, sample size and #channels).
- */
-
- bsz = dmap->buffsize;
- while (bsz > sz)
- bsz /= 2;
-
- if (bsz == dmap->buffsize)
- bsz /= 2; /* Needs at least 2 buffers */
-
- /*
- * Split the computed fragment to smaller parts. After 3.5a9
- * the default subdivision is 4 which should give better
- * results when recording.
- */
-
- if (dmap->subdivision == 0) /* Not already set */
- {
- dmap->subdivision = 4; /* Init to the default value */
-
- if ((bsz / dmap->subdivision) > 4096)
- dmap->subdivision *= 2;
- if ((bsz / dmap->subdivision) < 4096)
- dmap->subdivision = 1;
- }
- bsz /= dmap->subdivision;
-
- if (bsz < 16)
- bsz = 16; /* Just a sanity check */
-
- dmap->fragment_size = bsz;
- }
- else
- {
- /*
- * The process has specified the buffer size with SNDCTL_DSP_SETFRAGMENT or
- * the buffer size computation has already been done.
- */
- if (dmap->fragment_size > (dmap->buffsize / 2))
- dmap->fragment_size = (dmap->buffsize / 2);
- bsz = dmap->fragment_size;
- }
-
- if (audio_devs[dev]->min_fragment)
- if (bsz < (1 << audio_devs[dev]->min_fragment))
- bsz = 1 << audio_devs[dev]->min_fragment;
- if (audio_devs[dev]->max_fragment)
- if (bsz > (1 << audio_devs[dev]->max_fragment))
- bsz = 1 << audio_devs[dev]->max_fragment;
- bsz &= ~0x07; /* Force size which is multiple of 8 bytes */
-#ifdef OS_DMA_ALIGN_CHECK
- OS_DMA_ALIGN_CHECK(bsz);
-#endif
-
- n = dmap->buffsize / bsz;
- if (n > MAX_SUB_BUFFERS)
- n = MAX_SUB_BUFFERS;
- if (n > dmap->max_fragments)
- n = dmap->max_fragments;
-
- if (n < 2)
- {
- n = 2;
- bsz /= 2;
- }
- dmap->nbufs = n;
- dmap->bytes_in_use = n * bsz;
- dmap->fragment_size = bsz;
- dmap->max_byte_counter = (dmap->data_rate * 60 * 60) +
- dmap->bytes_in_use; /* Approximately one hour */
-
- if (dmap->raw_buf)
- {
- memset(dmap->raw_buf, dmap->neutral_byte, dmap->bytes_in_use);
- }
-
- for (i = 0; i < dmap->nbufs; i++)
- {
- dmap->counts[i] = 0;
- }
-
- dmap->flags |= DMA_ALLOC_DONE | DMA_EMPTY;
-}
-
-static int dma_subdivide(int dev, struct dma_buffparms *dmap, int fact)
-{
- if (fact == 0)
- {
- fact = dmap->subdivision;
- if (fact == 0)
- fact = 1;
- return fact;
- }
- if (dmap->subdivision != 0 || dmap->fragment_size) /* Too late to change */
- return -EINVAL;
-
- if (fact > MAX_REALTIME_FACTOR)
- return -EINVAL;
-
- if (fact != 1 && fact != 2 && fact != 4 && fact != 8 && fact != 16)
- return -EINVAL;
-
- dmap->subdivision = fact;
- return fact;
-}
-
-static int dma_set_fragment(int dev, struct dma_buffparms *dmap, int fact)
-{
- int bytes, count;
-
- if (fact == 0)
- return -EIO;
-
- if (dmap->subdivision != 0 ||
- dmap->fragment_size) /* Too late to change */
- return -EINVAL;
-
- bytes = fact & 0xffff;
- count = (fact >> 16) & 0x7fff;
-
- if (count == 0)
- count = MAX_SUB_BUFFERS;
- else if (count < MAX_SUB_BUFFERS)
- count++;
-
- if (bytes < 4 || bytes > 17) /* <16 || > 512k */
- return -EINVAL;
-
- if (count < 2)
- return -EINVAL;
-
- if (audio_devs[dev]->min_fragment > 0)
- if (bytes < audio_devs[dev]->min_fragment)
- bytes = audio_devs[dev]->min_fragment;
-
- if (audio_devs[dev]->max_fragment > 0)
- if (bytes > audio_devs[dev]->max_fragment)
- bytes = audio_devs[dev]->max_fragment;
-
-#ifdef OS_DMA_MINBITS
- if (bytes < OS_DMA_MINBITS)
- bytes = OS_DMA_MINBITS;
-#endif
-
- dmap->fragment_size = (1 << bytes);
- dmap->max_fragments = count;
-
- if (dmap->fragment_size > dmap->buffsize)
- dmap->fragment_size = dmap->buffsize;
-
- if (dmap->fragment_size == dmap->buffsize &&
- audio_devs[dev]->flags & DMA_AUTOMODE)
- dmap->fragment_size /= 2; /* Needs at least 2 buffers */
-
- dmap->subdivision = 1; /* Disable SNDCTL_DSP_SUBDIVIDE */
- return bytes | ((count - 1) << 16);
-}
-
-static int dma_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
- struct dma_buffparms *dmap_out = audio_devs[dev]->dmap_out;
- struct dma_buffparms *dmap_in = audio_devs[dev]->dmap_in;
- struct dma_buffparms *dmap;
- audio_buf_info info;
- count_info cinfo;
- int fact, ret, changed, bits, count, err;
- unsigned long flags;
-
- switch (cmd)
- {
- case SNDCTL_DSP_SUBDIVIDE:
- ret = 0;
- if (get_user(fact, (int __user *)arg))
- return -EFAULT;
- if (audio_devs[dev]->open_mode & OPEN_WRITE)
- ret = dma_subdivide(dev, dmap_out, fact);
- if (ret < 0)
- return ret;
- if (audio_devs[dev]->open_mode != OPEN_WRITE ||
- (audio_devs[dev]->flags & DMA_DUPLEX &&
- audio_devs[dev]->open_mode & OPEN_READ))
- ret = dma_subdivide(dev, dmap_in, fact);
- if (ret < 0)
- return ret;
- break;
-
- case SNDCTL_DSP_GETISPACE:
- case SNDCTL_DSP_GETOSPACE:
- dmap = dmap_out;
- if (cmd == SNDCTL_DSP_GETISPACE && !(audio_devs[dev]->open_mode & OPEN_READ))
- return -EINVAL;
- if (cmd == SNDCTL_DSP_GETOSPACE && !(audio_devs[dev]->open_mode & OPEN_WRITE))
- return -EINVAL;
- if (cmd == SNDCTL_DSP_GETISPACE && audio_devs[dev]->flags & DMA_DUPLEX)
- dmap = dmap_in;
- if (dmap->mapping_flags & DMA_MAP_MAPPED)
- return -EINVAL;
- if (!(dmap->flags & DMA_ALLOC_DONE))
- reorganize_buffers(dev, dmap, (cmd == SNDCTL_DSP_GETISPACE));
- info.fragstotal = dmap->nbufs;
- if (cmd == SNDCTL_DSP_GETISPACE)
- info.fragments = dmap->qlen;
- else
- {
- if (!DMAbuf_space_in_queue(dev))
- info.fragments = 0;
- else
- {
- info.fragments = DMAbuf_space_in_queue(dev);
- if (audio_devs[dev]->d->local_qlen)
- {
- int tmp = audio_devs[dev]->d->local_qlen(dev);
- if (tmp && info.fragments)
- tmp--; /*
- * This buffer has been counted twice
- */
- info.fragments -= tmp;
- }
- }
- }
- if (info.fragments < 0)
- info.fragments = 0;
- else if (info.fragments > dmap->nbufs)
- info.fragments = dmap->nbufs;
-
- info.fragsize = dmap->fragment_size;
- info.bytes = info.fragments * dmap->fragment_size;
-
- if (cmd == SNDCTL_DSP_GETISPACE && dmap->qlen)
- info.bytes -= dmap->counts[dmap->qhead];
- else
- {
- info.fragments = info.bytes / dmap->fragment_size;
- info.bytes -= dmap->user_counter % dmap->fragment_size;
- }
- if (copy_to_user(arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
-
- case SNDCTL_DSP_SETTRIGGER:
- if (get_user(bits, (int __user *)arg))
- return -EFAULT;
- bits &= audio_devs[dev]->open_mode;
- if (audio_devs[dev]->d->trigger == NULL)
- return -EINVAL;
- if (!(audio_devs[dev]->flags & DMA_DUPLEX) && (bits & PCM_ENABLE_INPUT) &&
- (bits & PCM_ENABLE_OUTPUT))
- return -EINVAL;
-
- if (bits & PCM_ENABLE_INPUT)
- {
- spin_lock_irqsave(&dmap_in->lock,flags);
- changed = (audio_devs[dev]->enable_bits ^ bits) & PCM_ENABLE_INPUT;
- if (changed && audio_devs[dev]->go)
- {
- reorganize_buffers(dev, dmap_in, 1);
- if ((err = audio_devs[dev]->d->prepare_for_input(dev,
- dmap_in->fragment_size, dmap_in->nbufs)) < 0) {
- spin_unlock_irqrestore(&dmap_in->lock,flags);
- return err;
- }
- dmap_in->dma_mode = DMODE_INPUT;
- audio_devs[dev]->enable_bits |= PCM_ENABLE_INPUT;
- DMAbuf_activate_recording(dev, dmap_in);
- } else
- audio_devs[dev]->enable_bits &= ~PCM_ENABLE_INPUT;
- spin_unlock_irqrestore(&dmap_in->lock,flags);
- }
- if (bits & PCM_ENABLE_OUTPUT)
- {
- spin_lock_irqsave(&dmap_out->lock,flags);
- changed = (audio_devs[dev]->enable_bits ^ bits) & PCM_ENABLE_OUTPUT;
- if (changed &&
- (dmap_out->mapping_flags & DMA_MAP_MAPPED || dmap_out->qlen > 0) &&
- audio_devs[dev]->go)
- {
- if (!(dmap_out->flags & DMA_ALLOC_DONE))
- reorganize_buffers(dev, dmap_out, 0);
- dmap_out->dma_mode = DMODE_OUTPUT;
- audio_devs[dev]->enable_bits |= PCM_ENABLE_OUTPUT;
- dmap_out->counts[dmap_out->qhead] = dmap_out->fragment_size;
- DMAbuf_launch_output(dev, dmap_out);
- } else
- audio_devs[dev]->enable_bits &= ~PCM_ENABLE_OUTPUT;
- spin_unlock_irqrestore(&dmap_out->lock,flags);
- }
-#if 0
- if (changed && audio_devs[dev]->d->trigger)
- audio_devs[dev]->d->trigger(dev, bits * audio_devs[dev]->go);
-#endif
- /* Falls through... */
-
- case SNDCTL_DSP_GETTRIGGER:
- ret = audio_devs[dev]->enable_bits;
- break;
-
- case SNDCTL_DSP_SETSYNCRO:
- if (!audio_devs[dev]->d->trigger)
- return -EINVAL;
- audio_devs[dev]->d->trigger(dev, 0);
- audio_devs[dev]->go = 0;
- return 0;
-
- case SNDCTL_DSP_GETIPTR:
- if (!(audio_devs[dev]->open_mode & OPEN_READ))
- return -EINVAL;
- spin_lock_irqsave(&dmap_in->lock,flags);
- cinfo.bytes = dmap_in->byte_counter;
- cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_in, DMODE_INPUT) & ~3;
- if (cinfo.ptr < dmap_in->fragment_size && dmap_in->qtail != 0)
- cinfo.bytes += dmap_in->bytes_in_use; /* Pointer wrap not handled yet */
- cinfo.blocks = dmap_in->qlen;
- cinfo.bytes += cinfo.ptr;
- if (dmap_in->mapping_flags & DMA_MAP_MAPPED)
- dmap_in->qlen = 0; /* Reset interrupt counter */
- spin_unlock_irqrestore(&dmap_in->lock,flags);
- if (copy_to_user(arg, &cinfo, sizeof(cinfo)))
- return -EFAULT;
- return 0;
-
- case SNDCTL_DSP_GETOPTR:
- if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
- return -EINVAL;
-
- spin_lock_irqsave(&dmap_out->lock,flags);
- cinfo.bytes = dmap_out->byte_counter;
- cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_out, DMODE_OUTPUT) & ~3;
- if (cinfo.ptr < dmap_out->fragment_size && dmap_out->qhead != 0)
- cinfo.bytes += dmap_out->bytes_in_use; /* Pointer wrap not handled yet */
- cinfo.blocks = dmap_out->qlen;
- cinfo.bytes += cinfo.ptr;
- if (dmap_out->mapping_flags & DMA_MAP_MAPPED)
- dmap_out->qlen = 0; /* Reset interrupt counter */
- spin_unlock_irqrestore(&dmap_out->lock,flags);
- if (copy_to_user(arg, &cinfo, sizeof(cinfo)))
- return -EFAULT;
- return 0;
-
- case SNDCTL_DSP_GETODELAY:
- if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
- return -EINVAL;
- if (!(dmap_out->flags & DMA_ALLOC_DONE))
- {
- ret=0;
- break;
- }
- spin_lock_irqsave(&dmap_out->lock,flags);
- /* Compute number of bytes that have been played */
- count = DMAbuf_get_buffer_pointer (dev, dmap_out, DMODE_OUTPUT);
- if (count < dmap_out->fragment_size && dmap_out->qhead != 0)
- count += dmap_out->bytes_in_use; /* Pointer wrap not handled yet */
- count += dmap_out->byte_counter;
- /* Subtract current count from the number of bytes written by app */
- count = dmap_out->user_counter - count;
- if (count < 0)
- count = 0;
- spin_unlock_irqrestore(&dmap_out->lock,flags);
- ret = count;
- break;
-
- case SNDCTL_DSP_POST:
- if (audio_devs[dev]->dmap_out->qlen > 0)
- if (!(audio_devs[dev]->dmap_out->flags & DMA_ACTIVE))
- DMAbuf_launch_output(dev, audio_devs[dev]->dmap_out);
- return 0;
-
- case SNDCTL_DSP_GETBLKSIZE:
- dmap = dmap_out;
- if (audio_devs[dev]->open_mode & OPEN_WRITE)
- reorganize_buffers(dev, dmap_out, (audio_devs[dev]->open_mode == OPEN_READ));
- if (audio_devs[dev]->open_mode == OPEN_READ ||
- (audio_devs[dev]->flags & DMA_DUPLEX &&
- audio_devs[dev]->open_mode & OPEN_READ))
- reorganize_buffers(dev, dmap_in, (audio_devs[dev]->open_mode == OPEN_READ));
- if (audio_devs[dev]->open_mode == OPEN_READ)
- dmap = dmap_in;
- ret = dmap->fragment_size;
- break;
-
- case SNDCTL_DSP_SETFRAGMENT:
- ret = 0;
- if (get_user(fact, (int __user *)arg))
- return -EFAULT;
- if (audio_devs[dev]->open_mode & OPEN_WRITE)
- ret = dma_set_fragment(dev, dmap_out, fact);
- if (ret < 0)
- return ret;
- if (audio_devs[dev]->open_mode == OPEN_READ ||
- (audio_devs[dev]->flags & DMA_DUPLEX &&
- audio_devs[dev]->open_mode & OPEN_READ))
- ret = dma_set_fragment(dev, dmap_in, fact);
- if (ret < 0)
- return ret;
- if (!arg) /* don't know what this is good for, but preserve old semantics */
- return 0;
- break;
-
- default:
- if (!audio_devs[dev]->d->ioctl)
- return -EINVAL;
- return audio_devs[dev]->d->ioctl(dev, cmd, arg);
- }
- return put_user(ret, (int __user *)arg);
-}
diff --git a/ANDROID_3.4.5/sound/oss/bin2hex.c b/ANDROID_3.4.5/sound/oss/bin2hex.c
deleted file mode 100644
index b59109eb..00000000
--- a/ANDROID_3.4.5/sound/oss/bin2hex.c
+++ /dev/null
@@ -1,39 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-int main( int argc, const char * argv [] )
-{
- const char * varname;
- int i = 0;
- int c;
- int id = 0;
-
- if(argv[1] && strcmp(argv[1],"-i")==0)
- {
- argv++;
- argc--;
- id=1;
- }
-
- if(argc==1)
- {
- fprintf(stderr, "bin2hex: [-i] firmware\n");
- exit(1);
- }
-
- varname = argv[1];
- printf( "/* automatically generated by bin2hex */\n" );
- printf( "static unsigned char %s [] %s =\n{\n", varname , id?"__initdata":"");
-
- while ( ( c = getchar( ) ) != EOF )
- {
- if ( i != 0 && i % 10 == 0 )
- printf( "\n" );
- printf( "0x%02lx,", c & 0xFFl );
- i++;
- }
-
- printf( "};\nstatic int %sLen = %d;\n", varname, i );
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/oss/coproc.h b/ANDROID_3.4.5/sound/oss/coproc.h
deleted file mode 100644
index 7bec21bb..00000000
--- a/ANDROID_3.4.5/sound/oss/coproc.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Definitions for various on board processors on the sound cards. For
- * example DSP processors.
- */
-
-/*
- * Coprocessor access types
- */
-#define COPR_CUSTOM 0x0001 /* Custom applications */
-#define COPR_MIDI 0x0002 /* MIDI (MPU-401) emulation */
-#define COPR_PCM 0x0004 /* Digitized voice applications */
-#define COPR_SYNTH 0x0008 /* Music synthesis */
diff --git a/ANDROID_3.4.5/sound/oss/dev_table.c b/ANDROID_3.4.5/sound/oss/dev_table.c
deleted file mode 100644
index d8cf3e58..00000000
--- a/ANDROID_3.4.5/sound/oss/dev_table.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * sound/oss/dev_table.c
- *
- * Device call tables.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-
-#include <linux/init.h>
-
-#include "sound_config.h"
-
-struct audio_operations *audio_devs[MAX_AUDIO_DEV];
-EXPORT_SYMBOL(audio_devs);
-
-int num_audiodevs;
-EXPORT_SYMBOL(num_audiodevs);
-
-struct mixer_operations *mixer_devs[MAX_MIXER_DEV];
-EXPORT_SYMBOL(mixer_devs);
-
-int num_mixers;
-EXPORT_SYMBOL(num_mixers);
-
-struct synth_operations *synth_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV];
-EXPORT_SYMBOL(synth_devs);
-
-int num_synths;
-
-struct midi_operations *midi_devs[MAX_MIDI_DEV];
-EXPORT_SYMBOL(midi_devs);
-
-int num_midis;
-EXPORT_SYMBOL(num_midis);
-
-struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV] = {
- &default_sound_timer, NULL
-};
-EXPORT_SYMBOL(sound_timer_devs);
-
-int num_sound_timers = 1;
-
-
-static int sound_alloc_audiodev(void);
-
-int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver,
- int driver_size, int flags, unsigned int format_mask,
- void *devc, int dma1, int dma2)
-{
- struct audio_driver *d;
- struct audio_operations *op;
- int num;
-
- if (vers != AUDIO_DRIVER_VERSION || driver_size > sizeof(struct audio_driver)) {
- printk(KERN_ERR "Sound: Incompatible audio driver for %s\n", name);
- return -(EINVAL);
- }
- num = sound_alloc_audiodev();
-
- if (num == -1) {
- printk(KERN_ERR "sound: Too many audio drivers\n");
- return -(EBUSY);
- }
- d = (struct audio_driver *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct audio_driver)));
- sound_nblocks++;
- if (sound_nblocks >= MAX_MEM_BLOCKS)
- sound_nblocks = MAX_MEM_BLOCKS - 1;
-
- op = (struct audio_operations *) (sound_mem_blocks[sound_nblocks] = vzalloc(sizeof(struct audio_operations)));
- sound_nblocks++;
- if (sound_nblocks >= MAX_MEM_BLOCKS)
- sound_nblocks = MAX_MEM_BLOCKS - 1;
-
- if (d == NULL || op == NULL) {
- printk(KERN_ERR "Sound: Can't allocate driver for (%s)\n", name);
- sound_unload_audiodev(num);
- return -(ENOMEM);
- }
- init_waitqueue_head(&op->in_sleeper);
- init_waitqueue_head(&op->out_sleeper);
- init_waitqueue_head(&op->poll_sleeper);
- if (driver_size < sizeof(struct audio_driver))
- memset((char *) d, 0, sizeof(struct audio_driver));
-
- memcpy((char *) d, (char *) driver, driver_size);
-
- op->d = d;
- strlcpy(op->name, name, sizeof(op->name));
- op->flags = flags;
- op->format_mask = format_mask;
- op->devc = devc;
-
- /*
- * Hardcoded defaults
- */
- audio_devs[num] = op;
-
- DMAbuf_init(num, dma1, dma2);
-
- audio_init_devices();
- return num;
-}
-EXPORT_SYMBOL(sound_install_audiodrv);
-
-int sound_install_mixer(int vers, char *name, struct mixer_operations *driver,
- int driver_size, void *devc)
-{
- struct mixer_operations *op;
-
- int n = sound_alloc_mixerdev();
-
- if (n == -1) {
- printk(KERN_ERR "Sound: Too many mixer drivers\n");
- return -EBUSY;
- }
- if (vers != MIXER_DRIVER_VERSION ||
- driver_size > sizeof(struct mixer_operations)) {
- printk(KERN_ERR "Sound: Incompatible mixer driver for %s\n", name);
- return -EINVAL;
- }
-
- /* FIXME: This leaks a mixer_operations struct every time its called
- until you unload sound! */
-
- op = (struct mixer_operations *) (sound_mem_blocks[sound_nblocks] = vzalloc(sizeof(struct mixer_operations)));
- sound_nblocks++;
- if (sound_nblocks >= MAX_MEM_BLOCKS)
- sound_nblocks = MAX_MEM_BLOCKS - 1;
-
- if (op == NULL) {
- printk(KERN_ERR "Sound: Can't allocate mixer driver for (%s)\n", name);
- return -ENOMEM;
- }
- memcpy((char *) op, (char *) driver, driver_size);
-
- strlcpy(op->name, name, sizeof(op->name));
- op->devc = devc;
-
- mixer_devs[n] = op;
- return n;
-}
-EXPORT_SYMBOL(sound_install_mixer);
-
-void sound_unload_audiodev(int dev)
-{
- if (dev != -1) {
- DMAbuf_deinit(dev);
- audio_devs[dev] = NULL;
- unregister_sound_dsp((dev<<4)+3);
- }
-}
-EXPORT_SYMBOL(sound_unload_audiodev);
-
-static int sound_alloc_audiodev(void)
-{
- int i = register_sound_dsp(&oss_sound_fops, -1);
- if(i==-1)
- return i;
- i>>=4;
- if(i>=num_audiodevs)
- num_audiodevs = i + 1;
- return i;
-}
-
-int sound_alloc_mididev(void)
-{
- int i = register_sound_midi(&oss_sound_fops, -1);
- if(i==-1)
- return i;
- i>>=4;
- if(i>=num_midis)
- num_midis = i + 1;
- return i;
-}
-EXPORT_SYMBOL(sound_alloc_mididev);
-
-int sound_alloc_synthdev(void)
-{
- int i;
-
- for (i = 0; i < MAX_SYNTH_DEV; i++) {
- if (synth_devs[i] == NULL) {
- if (i >= num_synths)
- num_synths++;
- return i;
- }
- }
- return -1;
-}
-EXPORT_SYMBOL(sound_alloc_synthdev);
-
-int sound_alloc_mixerdev(void)
-{
- int i = register_sound_mixer(&oss_sound_fops, -1);
- if(i==-1)
- return -1;
- i>>=4;
- if(i>=num_mixers)
- num_mixers = i + 1;
- return i;
-}
-EXPORT_SYMBOL(sound_alloc_mixerdev);
-
-int sound_alloc_timerdev(void)
-{
- int i;
-
- for (i = 0; i < MAX_TIMER_DEV; i++) {
- if (sound_timer_devs[i] == NULL) {
- if (i >= num_sound_timers)
- num_sound_timers++;
- return i;
- }
- }
- return -1;
-}
-EXPORT_SYMBOL(sound_alloc_timerdev);
-
-void sound_unload_mixerdev(int dev)
-{
- if (dev != -1) {
- mixer_devs[dev] = NULL;
- unregister_sound_mixer(dev<<4);
- num_mixers--;
- }
-}
-EXPORT_SYMBOL(sound_unload_mixerdev);
-
-void sound_unload_mididev(int dev)
-{
- if (dev != -1) {
- midi_devs[dev] = NULL;
- unregister_sound_midi((dev<<4)+2);
- }
-}
-EXPORT_SYMBOL(sound_unload_mididev);
-
-void sound_unload_synthdev(int dev)
-{
- if (dev != -1)
- synth_devs[dev] = NULL;
-}
-EXPORT_SYMBOL(sound_unload_synthdev);
-
-void sound_unload_timerdev(int dev)
-{
- if (dev != -1)
- sound_timer_devs[dev] = NULL;
-}
-EXPORT_SYMBOL(sound_unload_timerdev);
-
diff --git a/ANDROID_3.4.5/sound/oss/dev_table.h b/ANDROID_3.4.5/sound/oss/dev_table.h
deleted file mode 100644
index 0199a317..00000000
--- a/ANDROID_3.4.5/sound/oss/dev_table.h
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * dev_table.h
- *
- * Global definitions for device call tables
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-
-
-#ifndef _DEV_TABLE_H_
-#define _DEV_TABLE_H_
-
-#include <linux/spinlock.h>
-/*
- * Sound card numbers 27 to 999. (1 to 26 are defined in soundcard.h)
- * Numbers 1000 to N are reserved for driver's internal use.
- */
-
-#define SNDCARD_DESKPROXL 27 /* Compaq Deskpro XL */
-#define SNDCARD_VIDC 28 /* ARMs VIDC */
-#define SNDCARD_SBPNP 29
-#define SNDCARD_SOFTOSS 36
-#define SNDCARD_VMIDI 37
-#define SNDCARD_OPL3SA1 38 /* Note: clash in msnd.h */
-#define SNDCARD_OPL3SA1_SB 39
-#define SNDCARD_OPL3SA1_MPU 40
-#define SNDCARD_WAVEFRONT 41
-#define SNDCARD_OPL3SA2 42
-#define SNDCARD_OPL3SA2_MPU 43
-#define SNDCARD_WAVEARTIST 44 /* Waveartist */
-#define SNDCARD_OPL3SA2_MSS 45 /* Originally missed */
-#define SNDCARD_AD1816 88
-
-/*
- * NOTE! NOTE! NOTE! NOTE!
- *
- * If you modify this file, please check the dev_table.c also.
- *
- * NOTE! NOTE! NOTE! NOTE!
- */
-
-struct driver_info
-{
- char *driver_id;
- int card_subtype; /* Driver specific. Usually 0 */
- int card_type; /* From soundcard.h */
- char *name;
- void (*attach) (struct address_info *hw_config);
- int (*probe) (struct address_info *hw_config);
- void (*unload) (struct address_info *hw_config);
-};
-
-struct card_info
-{
- int card_type; /* Link (search key) to the driver list */
- struct address_info config;
- int enabled;
- void *for_driver_use;
-};
-
-
-/*
- * Device specific parameters (used only by dmabuf.c)
- */
-#define MAX_SUB_BUFFERS (32*MAX_REALTIME_FACTOR)
-
-#define DMODE_NONE 0
-#define DMODE_OUTPUT PCM_ENABLE_OUTPUT
-#define DMODE_INPUT PCM_ENABLE_INPUT
-
-struct dma_buffparms
-{
- int dma_mode; /* DMODE_INPUT, DMODE_OUTPUT or DMODE_NONE */
- int closing;
-
- /*
- * Pointers to raw buffers
- */
-
- char *raw_buf;
- unsigned long raw_buf_phys;
- int buffsize;
-
- /*
- * Device state tables
- */
-
- unsigned long flags;
-#define DMA_BUSY 0x00000001
-#define DMA_RESTART 0x00000002
-#define DMA_ACTIVE 0x00000004
-#define DMA_STARTED 0x00000008
-#define DMA_EMPTY 0x00000010
-#define DMA_ALLOC_DONE 0x00000020
-#define DMA_SYNCING 0x00000040
-#define DMA_DIRTY 0x00000080
-#define DMA_POST 0x00000100
-#define DMA_NODMA 0x00000200
-#define DMA_NOTIMEOUT 0x00000400
-
- int open_mode;
-
- /*
- * Queue parameters.
- */
- int qlen;
- int qhead;
- int qtail;
- spinlock_t lock;
-
- int cfrag; /* Current incomplete fragment (write) */
-
- int nbufs;
- int counts[MAX_SUB_BUFFERS];
- int subdivision;
-
- int fragment_size;
- int needs_reorg;
- int max_fragments;
-
- int bytes_in_use;
-
- int underrun_count;
- unsigned long byte_counter;
- unsigned long user_counter;
- unsigned long max_byte_counter;
- int data_rate; /* Bytes/second */
-
- int mapping_flags;
-#define DMA_MAP_MAPPED 0x00000001
- char neutral_byte;
- int dma; /* DMA channel */
-
- int applic_profile; /* Application profile (APF_*) */
- /* Interrupt callback stuff */
- void (*audio_callback) (int dev, int parm);
- int callback_parm;
-
- int buf_flags[MAX_SUB_BUFFERS];
-#define BUFF_EOF 0x00000001 /* Increment eof count */
-#define BUFF_DIRTY 0x00000002 /* Buffer written */
-};
-
-/*
- * Structure for use with various microcontrollers and DSP processors
- * in the recent sound cards.
- */
-typedef struct coproc_operations
-{
- char name[64];
- struct module *owner;
- int (*open) (void *devc, int sub_device);
- void (*close) (void *devc, int sub_device);
- int (*ioctl) (void *devc, unsigned int cmd, void __user * arg, int local);
- void (*reset) (void *devc);
-
- void *devc; /* Driver specific info */
-} coproc_operations;
-
-struct audio_driver
-{
- struct module *owner;
- int (*open) (int dev, int mode);
- void (*close) (int dev);
- void (*output_block) (int dev, unsigned long buf,
- int count, int intrflag);
- void (*start_input) (int dev, unsigned long buf,
- int count, int intrflag);
- int (*ioctl) (int dev, unsigned int cmd, void __user * arg);
- int (*prepare_for_input) (int dev, int bufsize, int nbufs);
- int (*prepare_for_output) (int dev, int bufsize, int nbufs);
- void (*halt_io) (int dev);
- int (*local_qlen)(int dev);
- void (*copy_user) (int dev,
- char *localbuf, int localoffs,
- const char __user *userbuf, int useroffs,
- int max_in, int max_out,
- int *used, int *returned,
- int len);
- void (*halt_input) (int dev);
- void (*halt_output) (int dev);
- void (*trigger) (int dev, int bits);
- int (*set_speed)(int dev, int speed);
- unsigned int (*set_bits)(int dev, unsigned int bits);
- short (*set_channels)(int dev, short channels);
- void (*postprocess_write)(int dev); /* Device spesific postprocessing for written data */
- void (*preprocess_read)(int dev); /* Device spesific preprocessing for read data */
- void (*mmap)(int dev);
-};
-
-struct audio_operations
-{
- char name[128];
- int flags;
-#define NOTHING_SPECIAL 0x00
-#define NEEDS_RESTART 0x01
-#define DMA_AUTOMODE 0x02
-#define DMA_DUPLEX 0x04
-#define DMA_PSEUDO_AUTOMODE 0x08
-#define DMA_HARDSTOP 0x10
-#define DMA_EXACT 0x40
-#define DMA_NORESET 0x80
- int format_mask; /* Bitmask for supported audio formats */
- void *devc; /* Driver specific info */
- struct audio_driver *d;
- void *portc; /* Driver specific info */
- struct dma_buffparms *dmap_in, *dmap_out;
- struct coproc_operations *coproc;
- int mixer_dev;
- int enable_bits;
- int open_mode;
- int go;
- int min_fragment; /* 0 == unlimited */
- int max_fragment; /* 0 == unlimited */
- int parent_dev; /* 0 -> no parent, 1 to n -> parent=parent_dev+1 */
-
- /* fields formerly in dmabuf.c */
- wait_queue_head_t in_sleeper;
- wait_queue_head_t out_sleeper;
- wait_queue_head_t poll_sleeper;
-
- /* fields formerly in audio.c */
- int audio_mode;
-
-#define AM_NONE 0
-#define AM_WRITE OPEN_WRITE
-#define AM_READ OPEN_READ
-
- int local_format;
- int audio_format;
- int local_conversion;
-#define CNV_MU_LAW 0x00000001
-
- /* large structures at the end to keep offsets small */
- struct dma_buffparms dmaps[2];
-};
-
-int *load_mixer_volumes(char *name, int *levels, int present);
-
-struct mixer_operations
-{
- struct module *owner;
- char id[16];
- char name[64];
- int (*ioctl) (int dev, unsigned int cmd, void __user * arg);
-
- void *devc;
- int modify_counter;
-};
-
-struct synth_operations
-{
- struct module *owner;
- char *id; /* Unique identifier (ASCII) max 29 char */
- struct synth_info *info;
- int midi_dev;
- int synth_type;
- int synth_subtype;
-
- int (*open) (int dev, int mode);
- void (*close) (int dev);
- int (*ioctl) (int dev, unsigned int cmd, void __user * arg);
- int (*kill_note) (int dev, int voice, int note, int velocity);
- int (*start_note) (int dev, int voice, int note, int velocity);
- int (*set_instr) (int dev, int voice, int instr);
- void (*reset) (int dev);
- void (*hw_control) (int dev, unsigned char *event);
- int (*load_patch) (int dev, int format, const char __user *addr,
- int count, int pmgr_flag);
- void (*aftertouch) (int dev, int voice, int pressure);
- void (*controller) (int dev, int voice, int ctrl_num, int value);
- void (*panning) (int dev, int voice, int value);
- void (*volume_method) (int dev, int mode);
- void (*bender) (int dev, int chn, int value);
- int (*alloc_voice) (int dev, int chn, int note, struct voice_alloc_info *alloc);
- void (*setup_voice) (int dev, int voice, int chn);
- int (*send_sysex)(int dev, unsigned char *bytes, int len);
-
- struct voice_alloc_info alloc;
- struct channel_info chn_info[16];
- int emulation;
-#define EMU_GM 1 /* General MIDI */
-#define EMU_XG 2 /* Yamaha XG */
-#define MAX_SYSEX_BUF 64
- unsigned char sysex_buf[MAX_SYSEX_BUF];
- int sysex_ptr;
-};
-
-struct midi_input_info
-{
- /* MIDI input scanner variables */
-#define MI_MAX 10
- volatile int m_busy;
- unsigned char m_buf[MI_MAX];
- unsigned char m_prev_status; /* For running status */
- int m_ptr;
-#define MST_INIT 0
-#define MST_DATA 1
-#define MST_SYSEX 2
- int m_state;
- int m_left;
-};
-
-struct midi_operations
-{
- struct module *owner;
- struct midi_info info;
- struct synth_operations *converter;
- struct midi_input_info in_info;
- int (*open) (int dev, int mode,
- void (*inputintr)(int dev, unsigned char data),
- void (*outputintr)(int dev)
- );
- void (*close) (int dev);
- int (*ioctl) (int dev, unsigned int cmd, void __user * arg);
- int (*outputc) (int dev, unsigned char data);
- int (*start_read) (int dev);
- int (*end_read) (int dev);
- void (*kick)(int dev);
- int (*command) (int dev, unsigned char *data);
- int (*buffer_status) (int dev);
- int (*prefix_cmd) (int dev, unsigned char status);
- struct coproc_operations *coproc;
- void *devc;
-};
-
-struct sound_lowlev_timer
-{
- int dev;
- int priority;
- unsigned int (*tmr_start)(int dev, unsigned int usecs);
- void (*tmr_disable)(int dev);
- void (*tmr_restart)(int dev);
-};
-
-struct sound_timer_operations
-{
- struct module *owner;
- struct sound_timer_info info;
- int priority;
- int devlink;
- int (*open)(int dev, int mode);
- void (*close)(int dev);
- int (*event)(int dev, unsigned char *ev);
- unsigned long (*get_time)(int dev);
- int (*ioctl) (int dev, unsigned int cmd, void __user * arg);
- void (*arm_timer)(int dev, long time);
-};
-
-extern struct sound_timer_operations default_sound_timer;
-
-extern struct audio_operations *audio_devs[MAX_AUDIO_DEV];
-extern int num_audiodevs;
-extern struct mixer_operations *mixer_devs[MAX_MIXER_DEV];
-extern int num_mixers;
-extern struct synth_operations *synth_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV];
-extern int num_synths;
-extern struct midi_operations *midi_devs[MAX_MIDI_DEV];
-extern int num_midis;
-extern struct sound_timer_operations * sound_timer_devs[MAX_TIMER_DEV];
-extern int num_sound_timers;
-
-extern int sound_map_buffer (int dev, struct dma_buffparms *dmap, buffmem_desc *info);
-void sound_timer_init (struct sound_lowlev_timer *t, char *name);
-void sound_dma_intr (int dev, struct dma_buffparms *dmap, int chan);
-
-#define AUDIO_DRIVER_VERSION 2
-#define MIXER_DRIVER_VERSION 2
-int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver,
- int driver_size, int flags, unsigned int format_mask,
- void *devc, int dma1, int dma2);
-int sound_install_mixer(int vers, char *name, struct mixer_operations *driver,
- int driver_size, void *devc);
-
-void sound_unload_audiodev(int dev);
-void sound_unload_mixerdev(int dev);
-void sound_unload_mididev(int dev);
-void sound_unload_synthdev(int dev);
-void sound_unload_timerdev(int dev);
-int sound_alloc_mixerdev(void);
-int sound_alloc_timerdev(void);
-int sound_alloc_synthdev(void);
-int sound_alloc_mididev(void);
-#endif /* _DEV_TABLE_H_ */
-
diff --git a/ANDROID_3.4.5/sound/oss/dmabuf.c b/ANDROID_3.4.5/sound/oss/dmabuf.c
deleted file mode 100644
index bcc3e8e0..00000000
--- a/ANDROID_3.4.5/sound/oss/dmabuf.c
+++ /dev/null
@@ -1,1268 +0,0 @@
-/*
- * sound/oss/dmabuf.c
- *
- * The DMA buffer manager for digitized voice applications
- */
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Thomas Sailer : moved several static variables into struct audio_operations
- * (which is grossly misnamed btw.) because they have the same
- * lifetime as the rest in there and dynamic allocation saves
- * 12k or so
- * Thomas Sailer : remove {in,out}_sleep_flag. It was used for the sleeper to
- * determine if it was woken up by the expiring timeout or by
- * an explicit wake_up. The return value from schedule_timeout
- * can be used instead; if 0, the wakeup was due to the timeout.
- *
- * Rob Riggs Added persistent DMA buffers (1998/10/17)
- */
-
-#define BE_CONSERVATIVE
-#define SAMPLE_ROUNDUP 0
-
-#include <linux/mm.h>
-#include <linux/gfp.h>
-#include "sound_config.h"
-
-#define DMAP_FREE_ON_CLOSE 0
-#define DMAP_KEEP_ON_CLOSE 1
-extern int sound_dmap_flag;
-
-static void dma_reset_output(int dev);
-static void dma_reset_input(int dev);
-static int local_start_dma(struct audio_operations *adev, unsigned long physaddr, int count, int dma_mode);
-
-
-
-static int debugmem; /* switched off by default */
-static int dma_buffsize = DSP_BUFFSIZE;
-
-static long dmabuf_timeout(struct dma_buffparms *dmap)
-{
- long tmout;
-
- tmout = (dmap->fragment_size * HZ) / dmap->data_rate;
- tmout += HZ / 5; /* Some safety distance */
- if (tmout < (HZ / 2))
- tmout = HZ / 2;
- if (tmout > 20 * HZ)
- tmout = 20 * HZ;
- return tmout;
-}
-
-static int sound_alloc_dmap(struct dma_buffparms *dmap)
-{
- char *start_addr, *end_addr;
- int dma_pagesize;
- int sz, size;
- struct page *page;
-
- dmap->mapping_flags &= ~DMA_MAP_MAPPED;
-
- if (dmap->raw_buf != NULL)
- return 0; /* Already done */
- if (dma_buffsize < 4096)
- dma_buffsize = 4096;
- dma_pagesize = (dmap->dma < 4) ? (64 * 1024) : (128 * 1024);
-
- /*
- * Now check for the Cyrix problem.
- */
-
- if(isa_dma_bridge_buggy==2)
- dma_pagesize=32768;
-
- dmap->raw_buf = NULL;
- dmap->buffsize = dma_buffsize;
- if (dmap->buffsize > dma_pagesize)
- dmap->buffsize = dma_pagesize;
- start_addr = NULL;
- /*
- * Now loop until we get a free buffer. Try to get smaller buffer if
- * it fails. Don't accept smaller than 8k buffer for performance
- * reasons.
- */
- while (start_addr == NULL && dmap->buffsize > PAGE_SIZE) {
- for (sz = 0, size = PAGE_SIZE; size < dmap->buffsize; sz++, size <<= 1);
- dmap->buffsize = PAGE_SIZE * (1 << sz);
- start_addr = (char *) __get_free_pages(GFP_ATOMIC|GFP_DMA|__GFP_NOWARN, sz);
- if (start_addr == NULL)
- dmap->buffsize /= 2;
- }
-
- if (start_addr == NULL) {
- printk(KERN_WARNING "Sound error: Couldn't allocate DMA buffer\n");
- return -ENOMEM;
- } else {
- /* make some checks */
- end_addr = start_addr + dmap->buffsize - 1;
-
- if (debugmem)
- printk(KERN_DEBUG "sound: start 0x%lx, end 0x%lx\n", (long) start_addr, (long) end_addr);
-
- /* now check if it fits into the same dma-pagesize */
-
- if (((long) start_addr & ~(dma_pagesize - 1)) != ((long) end_addr & ~(dma_pagesize - 1))
- || end_addr >= (char *) (MAX_DMA_ADDRESS)) {
- printk(KERN_ERR "sound: Got invalid address 0x%lx for %db DMA-buffer\n", (long) start_addr, dmap->buffsize);
- return -EFAULT;
- }
- }
- dmap->raw_buf = start_addr;
- dmap->raw_buf_phys = virt_to_bus(start_addr);
-
- for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++)
- SetPageReserved(page);
- return 0;
-}
-
-static void sound_free_dmap(struct dma_buffparms *dmap)
-{
- int sz, size;
- struct page *page;
- unsigned long start_addr, end_addr;
-
- if (dmap->raw_buf == NULL)
- return;
- if (dmap->mapping_flags & DMA_MAP_MAPPED)
- return; /* Don't free mmapped buffer. Will use it next time */
- for (sz = 0, size = PAGE_SIZE; size < dmap->buffsize; sz++, size <<= 1);
-
- start_addr = (unsigned long) dmap->raw_buf;
- end_addr = start_addr + dmap->buffsize;
-
- for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++)
- ClearPageReserved(page);
-
- free_pages((unsigned long) dmap->raw_buf, sz);
- dmap->raw_buf = NULL;
-}
-
-
-/* Intel version !!!!!!!!! */
-
-static int sound_start_dma(struct dma_buffparms *dmap, unsigned long physaddr, int count, int dma_mode)
-{
- unsigned long flags;
- int chan = dmap->dma;
-
- /* printk( "Start DMA%d %d, %d\n", chan, (int)(physaddr-dmap->raw_buf_phys), count); */
-
- flags = claim_dma_lock();
- disable_dma(chan);
- clear_dma_ff(chan);
- set_dma_mode(chan, dma_mode);
- set_dma_addr(chan, physaddr);
- set_dma_count(chan, count);
- enable_dma(chan);
- release_dma_lock(flags);
-
- return 0;
-}
-
-static void dma_init_buffers(struct dma_buffparms *dmap)
-{
- dmap->qlen = dmap->qhead = dmap->qtail = dmap->user_counter = 0;
- dmap->byte_counter = 0;
- dmap->max_byte_counter = 8000 * 60 * 60;
- dmap->bytes_in_use = dmap->buffsize;
-
- dmap->dma_mode = DMODE_NONE;
- dmap->mapping_flags = 0;
- dmap->neutral_byte = 0x80;
- dmap->data_rate = 8000;
- dmap->cfrag = -1;
- dmap->closing = 0;
- dmap->nbufs = 1;
- dmap->flags = DMA_BUSY; /* Other flags off */
-}
-
-static int open_dmap(struct audio_operations *adev, int mode, struct dma_buffparms *dmap)
-{
- int err;
-
- if (dmap->flags & DMA_BUSY)
- return -EBUSY;
- if ((err = sound_alloc_dmap(dmap)) < 0)
- return err;
-
- if (dmap->raw_buf == NULL) {
- printk(KERN_WARNING "Sound: DMA buffers not available\n");
- return -ENOSPC; /* Memory allocation failed during boot */
- }
- if (dmap->dma >= 0 && sound_open_dma(dmap->dma, adev->name)) {
- printk(KERN_WARNING "Unable to grab(2) DMA%d for the audio driver\n", dmap->dma);
- return -EBUSY;
- }
- dma_init_buffers(dmap);
- spin_lock_init(&dmap->lock);
- dmap->open_mode = mode;
- dmap->subdivision = dmap->underrun_count = 0;
- dmap->fragment_size = 0;
- dmap->max_fragments = 65536; /* Just a large value */
- dmap->byte_counter = 0;
- dmap->max_byte_counter = 8000 * 60 * 60;
- dmap->applic_profile = APF_NORMAL;
- dmap->needs_reorg = 1;
- dmap->audio_callback = NULL;
- dmap->callback_parm = 0;
- return 0;
-}
-
-static void close_dmap(struct audio_operations *adev, struct dma_buffparms *dmap)
-{
- unsigned long flags;
-
- if (dmap->dma >= 0) {
- sound_close_dma(dmap->dma);
- flags=claim_dma_lock();
- disable_dma(dmap->dma);
- release_dma_lock(flags);
- }
- if (dmap->flags & DMA_BUSY)
- dmap->dma_mode = DMODE_NONE;
- dmap->flags &= ~DMA_BUSY;
-
- if (sound_dmap_flag == DMAP_FREE_ON_CLOSE)
- sound_free_dmap(dmap);
-}
-
-
-static unsigned int default_set_bits(int dev, unsigned int bits)
-{
- mm_segment_t fs = get_fs();
-
- set_fs(get_ds());
- audio_devs[dev]->d->ioctl(dev, SNDCTL_DSP_SETFMT, (void __user *)&bits);
- set_fs(fs);
- return bits;
-}
-
-static int default_set_speed(int dev, int speed)
-{
- mm_segment_t fs = get_fs();
-
- set_fs(get_ds());
- audio_devs[dev]->d->ioctl(dev, SNDCTL_DSP_SPEED, (void __user *)&speed);
- set_fs(fs);
- return speed;
-}
-
-static short default_set_channels(int dev, short channels)
-{
- int c = channels;
- mm_segment_t fs = get_fs();
-
- set_fs(get_ds());
- audio_devs[dev]->d->ioctl(dev, SNDCTL_DSP_CHANNELS, (void __user *)&c);
- set_fs(fs);
- return c;
-}
-
-static void check_driver(struct audio_driver *d)
-{
- if (d->set_speed == NULL)
- d->set_speed = default_set_speed;
- if (d->set_bits == NULL)
- d->set_bits = default_set_bits;
- if (d->set_channels == NULL)
- d->set_channels = default_set_channels;
-}
-
-int DMAbuf_open(int dev, int mode)
-{
- struct audio_operations *adev = audio_devs[dev];
- int retval;
- struct dma_buffparms *dmap_in = NULL;
- struct dma_buffparms *dmap_out = NULL;
-
- if (!adev)
- return -ENXIO;
- if (!(adev->flags & DMA_DUPLEX))
- adev->dmap_in = adev->dmap_out;
- check_driver(adev->d);
-
- if ((retval = adev->d->open(dev, mode)) < 0)
- return retval;
- dmap_out = adev->dmap_out;
- dmap_in = adev->dmap_in;
- if (dmap_in == dmap_out)
- adev->flags &= ~DMA_DUPLEX;
-
- if (mode & OPEN_WRITE) {
- if ((retval = open_dmap(adev, mode, dmap_out)) < 0) {
- adev->d->close(dev);
- return retval;
- }
- }
- adev->enable_bits = mode;
-
- if (mode == OPEN_READ || (mode != OPEN_WRITE && (adev->flags & DMA_DUPLEX))) {
- if ((retval = open_dmap(adev, mode, dmap_in)) < 0) {
- adev->d->close(dev);
- if (mode & OPEN_WRITE)
- close_dmap(adev, dmap_out);
- return retval;
- }
- }
- adev->open_mode = mode;
- adev->go = 1;
-
- adev->d->set_bits(dev, 8);
- adev->d->set_channels(dev, 1);
- adev->d->set_speed(dev, DSP_DEFAULT_SPEED);
- if (adev->dmap_out->dma_mode == DMODE_OUTPUT)
- memset(adev->dmap_out->raw_buf, adev->dmap_out->neutral_byte,
- adev->dmap_out->bytes_in_use);
- return 0;
-}
-/* MUST not hold the spinlock */
-void DMAbuf_reset(int dev)
-{
- if (audio_devs[dev]->open_mode & OPEN_WRITE)
- dma_reset_output(dev);
-
- if (audio_devs[dev]->open_mode & OPEN_READ)
- dma_reset_input(dev);
-}
-
-static void dma_reset_output(int dev)
-{
- struct audio_operations *adev = audio_devs[dev];
- unsigned long flags,f ;
- struct dma_buffparms *dmap = adev->dmap_out;
-
- if (!(dmap->flags & DMA_STARTED)) /* DMA is not active */
- return;
-
- /*
- * First wait until the current fragment has been played completely
- */
- spin_lock_irqsave(&dmap->lock,flags);
- adev->dmap_out->flags |= DMA_SYNCING;
-
- adev->dmap_out->underrun_count = 0;
- if (!signal_pending(current) && adev->dmap_out->qlen &&
- adev->dmap_out->underrun_count == 0){
- spin_unlock_irqrestore(&dmap->lock,flags);
- interruptible_sleep_on_timeout(&adev->out_sleeper,
- dmabuf_timeout(dmap));
- spin_lock_irqsave(&dmap->lock,flags);
- }
- adev->dmap_out->flags &= ~(DMA_SYNCING | DMA_ACTIVE);
-
- /*
- * Finally shut the device off
- */
- if (!(adev->flags & DMA_DUPLEX) || !adev->d->halt_output)
- adev->d->halt_io(dev);
- else
- adev->d->halt_output(dev);
- adev->dmap_out->flags &= ~DMA_STARTED;
-
- f=claim_dma_lock();
- clear_dma_ff(dmap->dma);
- disable_dma(dmap->dma);
- release_dma_lock(f);
-
- dmap->byte_counter = 0;
- reorganize_buffers(dev, adev->dmap_out, 0);
- dmap->qlen = dmap->qhead = dmap->qtail = dmap->user_counter = 0;
- spin_unlock_irqrestore(&dmap->lock,flags);
-}
-
-static void dma_reset_input(int dev)
-{
- struct audio_operations *adev = audio_devs[dev];
- unsigned long flags;
- struct dma_buffparms *dmap = adev->dmap_in;
-
- spin_lock_irqsave(&dmap->lock,flags);
- if (!(adev->flags & DMA_DUPLEX) || !adev->d->halt_input)
- adev->d->halt_io(dev);
- else
- adev->d->halt_input(dev);
- adev->dmap_in->flags &= ~DMA_STARTED;
-
- dmap->qlen = dmap->qhead = dmap->qtail = dmap->user_counter = 0;
- dmap->byte_counter = 0;
- reorganize_buffers(dev, adev->dmap_in, 1);
- spin_unlock_irqrestore(&dmap->lock,flags);
-}
-/* MUST be called with holding the dmap->lock */
-void DMAbuf_launch_output(int dev, struct dma_buffparms *dmap)
-{
- struct audio_operations *adev = audio_devs[dev];
-
- if (!((adev->enable_bits * adev->go) & PCM_ENABLE_OUTPUT))
- return; /* Don't start DMA yet */
- dmap->dma_mode = DMODE_OUTPUT;
-
- if (!(dmap->flags & DMA_ACTIVE) || !(adev->flags & DMA_AUTOMODE) || (dmap->flags & DMA_NODMA)) {
- if (!(dmap->flags & DMA_STARTED)) {
- reorganize_buffers(dev, dmap, 0);
- if (adev->d->prepare_for_output(dev, dmap->fragment_size, dmap->nbufs))
- return;
- if (!(dmap->flags & DMA_NODMA))
- local_start_dma(adev, dmap->raw_buf_phys, dmap->bytes_in_use,DMA_MODE_WRITE);
- dmap->flags |= DMA_STARTED;
- }
- if (dmap->counts[dmap->qhead] == 0)
- dmap->counts[dmap->qhead] = dmap->fragment_size;
- dmap->dma_mode = DMODE_OUTPUT;
- adev->d->output_block(dev, dmap->raw_buf_phys + dmap->qhead * dmap->fragment_size,
- dmap->counts[dmap->qhead], 1);
- if (adev->d->trigger)
- adev->d->trigger(dev,adev->enable_bits * adev->go);
- }
- dmap->flags |= DMA_ACTIVE;
-}
-
-int DMAbuf_sync(int dev)
-{
- struct audio_operations *adev = audio_devs[dev];
- unsigned long flags;
- int n = 0;
- struct dma_buffparms *dmap;
-
- if (!adev->go && !(adev->enable_bits & PCM_ENABLE_OUTPUT))
- return 0;
-
- if (adev->dmap_out->dma_mode == DMODE_OUTPUT) {
- dmap = adev->dmap_out;
- spin_lock_irqsave(&dmap->lock,flags);
- if (dmap->qlen > 0 && !(dmap->flags & DMA_ACTIVE))
- DMAbuf_launch_output(dev, dmap);
- adev->dmap_out->flags |= DMA_SYNCING;
- adev->dmap_out->underrun_count = 0;
- while (!signal_pending(current) && n++ < adev->dmap_out->nbufs &&
- adev->dmap_out->qlen && adev->dmap_out->underrun_count == 0) {
- long t = dmabuf_timeout(dmap);
- spin_unlock_irqrestore(&dmap->lock,flags);
- /* FIXME: not safe may miss events */
- t = interruptible_sleep_on_timeout(&adev->out_sleeper, t);
- spin_lock_irqsave(&dmap->lock,flags);
- if (!t) {
- adev->dmap_out->flags &= ~DMA_SYNCING;
- spin_unlock_irqrestore(&dmap->lock,flags);
- return adev->dmap_out->qlen;
- }
- }
- adev->dmap_out->flags &= ~(DMA_SYNCING | DMA_ACTIVE);
-
- /*
- * Some devices such as GUS have huge amount of on board RAM for the
- * audio data. We have to wait until the device has finished playing.
- */
-
- /* still holding the lock */
- if (adev->d->local_qlen) { /* Device has hidden buffers */
- while (!signal_pending(current) &&
- adev->d->local_qlen(dev)){
- spin_unlock_irqrestore(&dmap->lock,flags);
- interruptible_sleep_on_timeout(&adev->out_sleeper,
- dmabuf_timeout(dmap));
- spin_lock_irqsave(&dmap->lock,flags);
- }
- }
- spin_unlock_irqrestore(&dmap->lock,flags);
- }
- adev->dmap_out->dma_mode = DMODE_NONE;
- return adev->dmap_out->qlen;
-}
-
-int DMAbuf_release(int dev, int mode)
-{
- struct audio_operations *adev = audio_devs[dev];
- struct dma_buffparms *dmap;
- unsigned long flags;
-
- dmap = adev->dmap_out;
- if (adev->open_mode & OPEN_WRITE)
- adev->dmap_out->closing = 1;
-
- if (adev->open_mode & OPEN_READ){
- adev->dmap_in->closing = 1;
- dmap = adev->dmap_in;
- }
- if (adev->open_mode & OPEN_WRITE)
- if (!(adev->dmap_out->mapping_flags & DMA_MAP_MAPPED))
- if (!signal_pending(current) && (adev->dmap_out->dma_mode == DMODE_OUTPUT))
- DMAbuf_sync(dev);
- if (adev->dmap_out->dma_mode == DMODE_OUTPUT)
- memset(adev->dmap_out->raw_buf, adev->dmap_out->neutral_byte, adev->dmap_out->bytes_in_use);
-
- DMAbuf_reset(dev);
- spin_lock_irqsave(&dmap->lock,flags);
- adev->d->close(dev);
-
- if (adev->open_mode & OPEN_WRITE)
- close_dmap(adev, adev->dmap_out);
-
- if (adev->open_mode == OPEN_READ ||
- (adev->open_mode != OPEN_WRITE &&
- (adev->flags & DMA_DUPLEX)))
- close_dmap(adev, adev->dmap_in);
- adev->open_mode = 0;
- spin_unlock_irqrestore(&dmap->lock,flags);
- return 0;
-}
-/* called with dmap->lock dold */
-int DMAbuf_activate_recording(int dev, struct dma_buffparms *dmap)
-{
- struct audio_operations *adev = audio_devs[dev];
- int err;
-
- if (!(adev->open_mode & OPEN_READ))
- return 0;
- if (!(adev->enable_bits & PCM_ENABLE_INPUT))
- return 0;
- if (dmap->dma_mode == DMODE_OUTPUT) { /* Direction change */
- /* release lock - it's not recursive */
- spin_unlock_irq(&dmap->lock);
- DMAbuf_sync(dev);
- DMAbuf_reset(dev);
- spin_lock_irq(&dmap->lock);
- dmap->dma_mode = DMODE_NONE;
- }
- if (!dmap->dma_mode) {
- reorganize_buffers(dev, dmap, 1);
- if ((err = adev->d->prepare_for_input(dev,
- dmap->fragment_size, dmap->nbufs)) < 0)
- return err;
- dmap->dma_mode = DMODE_INPUT;
- }
- if (!(dmap->flags & DMA_ACTIVE)) {
- if (dmap->needs_reorg)
- reorganize_buffers(dev, dmap, 0);
- local_start_dma(adev, dmap->raw_buf_phys, dmap->bytes_in_use, DMA_MODE_READ);
- adev->d->start_input(dev, dmap->raw_buf_phys + dmap->qtail * dmap->fragment_size,
- dmap->fragment_size, 0);
- dmap->flags |= DMA_ACTIVE;
- if (adev->d->trigger)
- adev->d->trigger(dev, adev->enable_bits * adev->go);
- }
- return 0;
-}
-/* acquires lock */
-int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock)
-{
- struct audio_operations *adev = audio_devs[dev];
- unsigned long flags;
- int err = 0, n = 0;
- struct dma_buffparms *dmap = adev->dmap_in;
- int go;
-
- if (!(adev->open_mode & OPEN_READ))
- return -EIO;
- spin_lock_irqsave(&dmap->lock,flags);
- if (dmap->needs_reorg)
- reorganize_buffers(dev, dmap, 0);
- if (adev->dmap_in->mapping_flags & DMA_MAP_MAPPED) {
-/* printk(KERN_WARNING "Sound: Can't read from mmapped device (1)\n");*/
- spin_unlock_irqrestore(&dmap->lock,flags);
- return -EINVAL;
- } else while (dmap->qlen <= 0 && n++ < 10) {
- long timeout = MAX_SCHEDULE_TIMEOUT;
- if (!(adev->enable_bits & PCM_ENABLE_INPUT) || !adev->go) {
- spin_unlock_irqrestore(&dmap->lock,flags);
- return -EAGAIN;
- }
- if ((err = DMAbuf_activate_recording(dev, dmap)) < 0) {
- spin_unlock_irqrestore(&dmap->lock,flags);
- return err;
- }
- /* Wait for the next block */
-
- if (dontblock) {
- spin_unlock_irqrestore(&dmap->lock,flags);
- return -EAGAIN;
- }
- if ((go = adev->go))
- timeout = dmabuf_timeout(dmap);
-
- spin_unlock_irqrestore(&dmap->lock,flags);
- timeout = interruptible_sleep_on_timeout(&adev->in_sleeper,
- timeout);
- if (!timeout) {
- /* FIXME: include device name */
- err = -EIO;
- printk(KERN_WARNING "Sound: DMA (input) timed out - IRQ/DRQ config error?\n");
- dma_reset_input(dev);
- } else
- err = -EINTR;
- spin_lock_irqsave(&dmap->lock,flags);
- }
- spin_unlock_irqrestore(&dmap->lock,flags);
-
- if (dmap->qlen <= 0)
- return err ? err : -EINTR;
- *buf = &dmap->raw_buf[dmap->qhead * dmap->fragment_size + dmap->counts[dmap->qhead]];
- *len = dmap->fragment_size - dmap->counts[dmap->qhead];
-
- return dmap->qhead;
-}
-
-int DMAbuf_rmchars(int dev, int buff_no, int c)
-{
- struct audio_operations *adev = audio_devs[dev];
- struct dma_buffparms *dmap = adev->dmap_in;
- int p = dmap->counts[dmap->qhead] + c;
-
- if (dmap->mapping_flags & DMA_MAP_MAPPED)
- {
-/* printk("Sound: Can't read from mmapped device (2)\n");*/
- return -EINVAL;
- }
- else if (dmap->qlen <= 0)
- return -EIO;
- else if (p >= dmap->fragment_size) { /* This buffer is completely empty */
- dmap->counts[dmap->qhead] = 0;
- dmap->qlen--;
- dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
- }
- else dmap->counts[dmap->qhead] = p;
-
- return 0;
-}
-/* MUST be called with dmap->lock hold */
-int DMAbuf_get_buffer_pointer(int dev, struct dma_buffparms *dmap, int direction)
-{
- /*
- * Try to approximate the active byte position of the DMA pointer within the
- * buffer area as well as possible.
- */
-
- int pos;
- unsigned long f;
-
- if (!(dmap->flags & DMA_ACTIVE))
- pos = 0;
- else {
- int chan = dmap->dma;
-
- f=claim_dma_lock();
- clear_dma_ff(chan);
-
- if(!isa_dma_bridge_buggy)
- disable_dma(dmap->dma);
-
- pos = get_dma_residue(chan);
-
- pos = dmap->bytes_in_use - pos;
-
- if (!(dmap->mapping_flags & DMA_MAP_MAPPED)) {
- if (direction == DMODE_OUTPUT) {
- if (dmap->qhead == 0)
- if (pos > dmap->fragment_size)
- pos = 0;
- } else {
- if (dmap->qtail == 0)
- if (pos > dmap->fragment_size)
- pos = 0;
- }
- }
- if (pos < 0)
- pos = 0;
- if (pos >= dmap->bytes_in_use)
- pos = 0;
-
- if(!isa_dma_bridge_buggy)
- enable_dma(dmap->dma);
-
- release_dma_lock(f);
- }
- /* printk( "%04x ", pos); */
-
- return pos;
-}
-
-/*
- * DMAbuf_start_devices() is called by the /dev/music driver to start
- * one or more audio devices at desired moment.
- */
-
-void DMAbuf_start_devices(unsigned int devmask)
-{
- struct audio_operations *adev;
- int dev;
-
- for (dev = 0; dev < num_audiodevs; dev++) {
- if (!(devmask & (1 << dev)))
- continue;
- if (!(adev = audio_devs[dev]))
- continue;
- if (adev->open_mode == 0)
- continue;
- if (adev->go)
- continue;
- /* OK to start the device */
- adev->go = 1;
- if (adev->d->trigger)
- adev->d->trigger(dev,adev->enable_bits * adev->go);
- }
-}
-/* via poll called without a lock ?*/
-int DMAbuf_space_in_queue(int dev)
-{
- struct audio_operations *adev = audio_devs[dev];
- int len, max, tmp;
- struct dma_buffparms *dmap = adev->dmap_out;
- int lim = dmap->nbufs;
-
- if (lim < 2)
- lim = 2;
-
- if (dmap->qlen >= lim) /* No space at all */
- return 0;
-
- /*
- * Verify that there are no more pending buffers than the limit
- * defined by the process.
- */
-
- max = dmap->max_fragments;
- if (max > lim)
- max = lim;
- len = dmap->qlen;
-
- if (adev->d->local_qlen) {
- tmp = adev->d->local_qlen(dev);
- if (tmp && len)
- tmp--; /* This buffer has been counted twice */
- len += tmp;
- }
- if (dmap->byte_counter % dmap->fragment_size) /* There is a partial fragment */
- len = len + 1;
-
- if (len >= max)
- return 0;
- return max - len;
-}
-/* MUST not hold the spinlock - this function may sleep */
-static int output_sleep(int dev, int dontblock)
-{
- struct audio_operations *adev = audio_devs[dev];
- int err = 0;
- struct dma_buffparms *dmap = adev->dmap_out;
- long timeout;
- long timeout_value;
-
- if (dontblock)
- return -EAGAIN;
- if (!(adev->enable_bits & PCM_ENABLE_OUTPUT))
- return -EAGAIN;
-
- /*
- * Wait for free space
- */
- if (signal_pending(current))
- return -EINTR;
- timeout = (adev->go && !(dmap->flags & DMA_NOTIMEOUT));
- if (timeout)
- timeout_value = dmabuf_timeout(dmap);
- else
- timeout_value = MAX_SCHEDULE_TIMEOUT;
- timeout_value = interruptible_sleep_on_timeout(&adev->out_sleeper,
- timeout_value);
- if (timeout != MAX_SCHEDULE_TIMEOUT && !timeout_value) {
- printk(KERN_WARNING "Sound: DMA (output) timed out - IRQ/DRQ config error?\n");
- dma_reset_output(dev);
- } else {
- if (signal_pending(current))
- err = -EINTR;
- }
- return err;
-}
-/* called with the lock held */
-static int find_output_space(int dev, char **buf, int *size)
-{
- struct audio_operations *adev = audio_devs[dev];
- struct dma_buffparms *dmap = adev->dmap_out;
- unsigned long active_offs;
- long len, offs;
- int maxfrags;
- int occupied_bytes = (dmap->user_counter % dmap->fragment_size);
-
- *buf = dmap->raw_buf;
- if (!(maxfrags = DMAbuf_space_in_queue(dev)) && !occupied_bytes)
- return 0;
-
-#ifdef BE_CONSERVATIVE
- active_offs = dmap->byte_counter + dmap->qhead * dmap->fragment_size;
-#else
- active_offs = max(DMAbuf_get_buffer_pointer(dev, dmap, DMODE_OUTPUT), 0);
- /* Check for pointer wrapping situation */
- if (active_offs >= dmap->bytes_in_use)
- active_offs = 0;
- active_offs += dmap->byte_counter;
-#endif
-
- offs = (dmap->user_counter % dmap->bytes_in_use) & ~SAMPLE_ROUNDUP;
- if (offs < 0 || offs >= dmap->bytes_in_use) {
- printk(KERN_ERR "Sound: Got unexpected offs %ld. Giving up.\n", offs);
- printk("Counter = %ld, bytes=%d\n", dmap->user_counter, dmap->bytes_in_use);
- return 0;
- }
- *buf = dmap->raw_buf + offs;
-
- len = active_offs + dmap->bytes_in_use - dmap->user_counter; /* Number of unused bytes in buffer */
-
- if ((offs + len) > dmap->bytes_in_use)
- len = dmap->bytes_in_use - offs;
- if (len < 0) {
- return 0;
- }
- if (len > ((maxfrags * dmap->fragment_size) - occupied_bytes))
- len = (maxfrags * dmap->fragment_size) - occupied_bytes;
- *size = len & ~SAMPLE_ROUNDUP;
- return (*size > 0);
-}
-/* acquires lock */
-int DMAbuf_getwrbuffer(int dev, char **buf, int *size, int dontblock)
-{
- struct audio_operations *adev = audio_devs[dev];
- unsigned long flags;
- int err = -EIO;
- struct dma_buffparms *dmap = adev->dmap_out;
-
- if (dmap->mapping_flags & DMA_MAP_MAPPED) {
-/* printk(KERN_DEBUG "Sound: Can't write to mmapped device (3)\n");*/
- return -EINVAL;
- }
- spin_lock_irqsave(&dmap->lock,flags);
- if (dmap->needs_reorg)
- reorganize_buffers(dev, dmap, 0);
-
- if (dmap->dma_mode == DMODE_INPUT) { /* Direction change */
- spin_unlock_irqrestore(&dmap->lock,flags);
- DMAbuf_reset(dev);
- spin_lock_irqsave(&dmap->lock,flags);
- }
- dmap->dma_mode = DMODE_OUTPUT;
-
- while (find_output_space(dev, buf, size) <= 0) {
- spin_unlock_irqrestore(&dmap->lock,flags);
- if ((err = output_sleep(dev, dontblock)) < 0) {
- return err;
- }
- spin_lock_irqsave(&dmap->lock,flags);
- }
-
- spin_unlock_irqrestore(&dmap->lock,flags);
- return 0;
-}
-/* has to acquire dmap->lock */
-int DMAbuf_move_wrpointer(int dev, int l)
-{
- struct audio_operations *adev = audio_devs[dev];
- struct dma_buffparms *dmap = adev->dmap_out;
- unsigned long ptr;
- unsigned long end_ptr, p;
- int post;
- unsigned long flags;
-
- spin_lock_irqsave(&dmap->lock,flags);
- post= (dmap->flags & DMA_POST);
- ptr = (dmap->user_counter / dmap->fragment_size) * dmap->fragment_size;
-
- dmap->flags &= ~DMA_POST;
- dmap->cfrag = -1;
- dmap->user_counter += l;
- dmap->flags |= DMA_DIRTY;
-
- if (dmap->byte_counter >= dmap->max_byte_counter) {
- /* Wrap the byte counters */
- long decr = dmap->byte_counter;
- dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use);
- decr -= dmap->byte_counter;
- dmap->user_counter -= decr;
- }
- end_ptr = (dmap->user_counter / dmap->fragment_size) * dmap->fragment_size;
-
- p = (dmap->user_counter - 1) % dmap->bytes_in_use;
- dmap->neutral_byte = dmap->raw_buf[p];
-
- /* Update the fragment based bookkeeping too */
- while (ptr < end_ptr) {
- dmap->counts[dmap->qtail] = dmap->fragment_size;
- dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
- dmap->qlen++;
- ptr += dmap->fragment_size;
- }
-
- dmap->counts[dmap->qtail] = dmap->user_counter - ptr;
-
- /*
- * Let the low level driver perform some postprocessing to
- * the written data.
- */
- if (adev->d->postprocess_write)
- adev->d->postprocess_write(dev);
-
- if (!(dmap->flags & DMA_ACTIVE))
- if (dmap->qlen > 1 || (dmap->qlen > 0 && (post || dmap->qlen >= dmap->nbufs - 1)))
- DMAbuf_launch_output(dev, dmap);
-
- spin_unlock_irqrestore(&dmap->lock,flags);
- return 0;
-}
-
-int DMAbuf_start_dma(int dev, unsigned long physaddr, int count, int dma_mode)
-{
- struct audio_operations *adev = audio_devs[dev];
- struct dma_buffparms *dmap = (dma_mode == DMA_MODE_WRITE) ? adev->dmap_out : adev->dmap_in;
-
- if (dmap->raw_buf == NULL) {
- printk(KERN_ERR "sound: DMA buffer(1) == NULL\n");
- printk("Device %d, chn=%s\n", dev, (dmap == adev->dmap_out) ? "out" : "in");
- return 0;
- }
- if (dmap->dma < 0)
- return 0;
- sound_start_dma(dmap, physaddr, count, dma_mode);
- return count;
-}
-EXPORT_SYMBOL(DMAbuf_start_dma);
-
-static int local_start_dma(struct audio_operations *adev, unsigned long physaddr, int count, int dma_mode)
-{
- struct dma_buffparms *dmap = (dma_mode == DMA_MODE_WRITE) ? adev->dmap_out : adev->dmap_in;
-
- if (dmap->raw_buf == NULL) {
- printk(KERN_ERR "sound: DMA buffer(2) == NULL\n");
- printk(KERN_ERR "Device %s, chn=%s\n", adev->name, (dmap == adev->dmap_out) ? "out" : "in");
- return 0;
- }
- if (dmap->flags & DMA_NODMA)
- return 1;
- if (dmap->dma < 0)
- return 0;
- sound_start_dma(dmap, dmap->raw_buf_phys, dmap->bytes_in_use, dma_mode | DMA_AUTOINIT);
- dmap->flags |= DMA_STARTED;
- return count;
-}
-
-static void finish_output_interrupt(int dev, struct dma_buffparms *dmap)
-{
- struct audio_operations *adev = audio_devs[dev];
-
- if (dmap->audio_callback != NULL)
- dmap->audio_callback(dev, dmap->callback_parm);
- wake_up(&adev->out_sleeper);
- wake_up(&adev->poll_sleeper);
-}
-/* called with dmap->lock held in irq context*/
-static void do_outputintr(int dev, int dummy)
-{
- struct audio_operations *adev = audio_devs[dev];
- struct dma_buffparms *dmap = adev->dmap_out;
- int this_fragment;
-
- if (dmap->raw_buf == NULL) {
- printk(KERN_ERR "Sound: Error. Audio interrupt (%d) after freeing buffers.\n", dev);
- return;
- }
- if (dmap->mapping_flags & DMA_MAP_MAPPED) { /* Virtual memory mapped access */
- /* mmapped access */
- dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
- if (dmap->qhead == 0) { /* Wrapped */
- dmap->byte_counter += dmap->bytes_in_use;
- if (dmap->byte_counter >= dmap->max_byte_counter) { /* Overflow */
- long decr = dmap->byte_counter;
- dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use);
- decr -= dmap->byte_counter;
- dmap->user_counter -= decr;
- }
- }
- dmap->qlen++; /* Yes increment it (don't decrement) */
- if (!(adev->flags & DMA_AUTOMODE))
- dmap->flags &= ~DMA_ACTIVE;
- dmap->counts[dmap->qhead] = dmap->fragment_size;
- DMAbuf_launch_output(dev, dmap);
- finish_output_interrupt(dev, dmap);
- return;
- }
-
- dmap->qlen--;
- this_fragment = dmap->qhead;
- dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
-
- if (dmap->qhead == 0) { /* Wrapped */
- dmap->byte_counter += dmap->bytes_in_use;
- if (dmap->byte_counter >= dmap->max_byte_counter) { /* Overflow */
- long decr = dmap->byte_counter;
- dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use);
- decr -= dmap->byte_counter;
- dmap->user_counter -= decr;
- }
- }
- if (!(adev->flags & DMA_AUTOMODE))
- dmap->flags &= ~DMA_ACTIVE;
-
- /*
- * This is dmap->qlen <= 0 except when closing when
- * dmap->qlen < 0
- */
-
- while (dmap->qlen <= -dmap->closing) {
- dmap->underrun_count++;
- dmap->qlen++;
- if ((dmap->flags & DMA_DIRTY) && dmap->applic_profile != APF_CPUINTENS) {
- dmap->flags &= ~DMA_DIRTY;
- memset(adev->dmap_out->raw_buf, adev->dmap_out->neutral_byte,
- adev->dmap_out->buffsize);
- }
- dmap->user_counter += dmap->fragment_size;
- dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
- }
- if (dmap->qlen > 0)
- DMAbuf_launch_output(dev, dmap);
- finish_output_interrupt(dev, dmap);
-}
-/* called in irq context */
-void DMAbuf_outputintr(int dev, int notify_only)
-{
- struct audio_operations *adev = audio_devs[dev];
- unsigned long flags;
- struct dma_buffparms *dmap = adev->dmap_out;
-
- spin_lock_irqsave(&dmap->lock,flags);
- if (!(dmap->flags & DMA_NODMA)) {
- int chan = dmap->dma, pos, n;
- unsigned long f;
-
- f=claim_dma_lock();
-
- if(!isa_dma_bridge_buggy)
- disable_dma(dmap->dma);
- clear_dma_ff(chan);
- pos = dmap->bytes_in_use - get_dma_residue(chan);
- if(!isa_dma_bridge_buggy)
- enable_dma(dmap->dma);
- release_dma_lock(f);
-
- pos = pos / dmap->fragment_size; /* Actual qhead */
- if (pos < 0 || pos >= dmap->nbufs)
- pos = 0;
- n = 0;
- while (dmap->qhead != pos && n++ < dmap->nbufs)
- do_outputintr(dev, notify_only);
- }
- else
- do_outputintr(dev, notify_only);
- spin_unlock_irqrestore(&dmap->lock,flags);
-}
-EXPORT_SYMBOL(DMAbuf_outputintr);
-
-/* called with dmap->lock held in irq context */
-static void do_inputintr(int dev)
-{
- struct audio_operations *adev = audio_devs[dev];
- struct dma_buffparms *dmap = adev->dmap_in;
-
- if (dmap->raw_buf == NULL) {
- printk(KERN_ERR "Sound: Fatal error. Audio interrupt after freeing buffers.\n");
- return;
- }
- if (dmap->mapping_flags & DMA_MAP_MAPPED) {
- dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
- if (dmap->qtail == 0) { /* Wrapped */
- dmap->byte_counter += dmap->bytes_in_use;
- if (dmap->byte_counter >= dmap->max_byte_counter) { /* Overflow */
- long decr = dmap->byte_counter;
- dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use) + dmap->bytes_in_use;
- decr -= dmap->byte_counter;
- dmap->user_counter -= decr;
- }
- }
- dmap->qlen++;
-
- if (!(adev->flags & DMA_AUTOMODE)) {
- if (dmap->needs_reorg)
- reorganize_buffers(dev, dmap, 0);
- local_start_dma(adev, dmap->raw_buf_phys, dmap->bytes_in_use,DMA_MODE_READ);
- adev->d->start_input(dev, dmap->raw_buf_phys + dmap->qtail * dmap->fragment_size,
- dmap->fragment_size, 1);
- if (adev->d->trigger)
- adev->d->trigger(dev, adev->enable_bits * adev->go);
- }
- dmap->flags |= DMA_ACTIVE;
- } else if (dmap->qlen >= (dmap->nbufs - 1)) {
- printk(KERN_WARNING "Sound: Recording overrun\n");
- dmap->underrun_count++;
-
- /* Just throw away the oldest fragment but keep the engine running */
- dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
- dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
- } else if (dmap->qlen >= 0 && dmap->qlen < dmap->nbufs) {
- dmap->qlen++;
- dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
- if (dmap->qtail == 0) { /* Wrapped */
- dmap->byte_counter += dmap->bytes_in_use;
- if (dmap->byte_counter >= dmap->max_byte_counter) { /* Overflow */
- long decr = dmap->byte_counter;
- dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use) + dmap->bytes_in_use;
- decr -= dmap->byte_counter;
- dmap->user_counter -= decr;
- }
- }
- }
- if (!(adev->flags & DMA_AUTOMODE) || (dmap->flags & DMA_NODMA)) {
- local_start_dma(adev, dmap->raw_buf_phys, dmap->bytes_in_use, DMA_MODE_READ);
- adev->d->start_input(dev, dmap->raw_buf_phys + dmap->qtail * dmap->fragment_size, dmap->fragment_size, 1);
- if (adev->d->trigger)
- adev->d->trigger(dev,adev->enable_bits * adev->go);
- }
- dmap->flags |= DMA_ACTIVE;
- if (dmap->qlen > 0)
- {
- wake_up(&adev->in_sleeper);
- wake_up(&adev->poll_sleeper);
- }
-}
-/* called in irq context */
-void DMAbuf_inputintr(int dev)
-{
- struct audio_operations *adev = audio_devs[dev];
- struct dma_buffparms *dmap = adev->dmap_in;
- unsigned long flags;
-
- spin_lock_irqsave(&dmap->lock,flags);
-
- if (!(dmap->flags & DMA_NODMA)) {
- int chan = dmap->dma, pos, n;
- unsigned long f;
-
- f=claim_dma_lock();
- if(!isa_dma_bridge_buggy)
- disable_dma(dmap->dma);
- clear_dma_ff(chan);
- pos = dmap->bytes_in_use - get_dma_residue(chan);
- if(!isa_dma_bridge_buggy)
- enable_dma(dmap->dma);
- release_dma_lock(f);
-
- pos = pos / dmap->fragment_size; /* Actual qhead */
- if (pos < 0 || pos >= dmap->nbufs)
- pos = 0;
-
- n = 0;
- while (dmap->qtail != pos && ++n < dmap->nbufs)
- do_inputintr(dev);
- } else
- do_inputintr(dev);
- spin_unlock_irqrestore(&dmap->lock,flags);
-}
-EXPORT_SYMBOL(DMAbuf_inputintr);
-
-void DMAbuf_init(int dev, int dma1, int dma2)
-{
- struct audio_operations *adev = audio_devs[dev];
- /*
- * NOTE! This routine could be called several times.
- */
-
- if (adev && adev->dmap_out == NULL) {
- if (adev->d == NULL)
- panic("OSS: audio_devs[%d]->d == NULL\n", dev);
-
- if (adev->parent_dev) { /* Use DMA map of the parent dev */
- int parent = adev->parent_dev - 1;
- adev->dmap_out = audio_devs[parent]->dmap_out;
- adev->dmap_in = audio_devs[parent]->dmap_in;
- } else {
- adev->dmap_out = adev->dmap_in = &adev->dmaps[0];
- adev->dmap_out->dma = dma1;
- if (adev->flags & DMA_DUPLEX) {
- adev->dmap_in = &adev->dmaps[1];
- adev->dmap_in->dma = dma2;
- }
- }
- /* Persistent DMA buffers allocated here */
- if (sound_dmap_flag == DMAP_KEEP_ON_CLOSE) {
- if (adev->dmap_in->raw_buf == NULL)
- sound_alloc_dmap(adev->dmap_in);
- if (adev->dmap_out->raw_buf == NULL)
- sound_alloc_dmap(adev->dmap_out);
- }
- }
-}
-
-/* No kernel lock - DMAbuf_activate_recording protected by global cli/sti */
-static unsigned int poll_input(struct file * file, int dev, poll_table *wait)
-{
- struct audio_operations *adev = audio_devs[dev];
- struct dma_buffparms *dmap = adev->dmap_in;
-
- if (!(adev->open_mode & OPEN_READ))
- return 0;
- if (dmap->mapping_flags & DMA_MAP_MAPPED) {
- if (dmap->qlen)
- return POLLIN | POLLRDNORM;
- return 0;
- }
- if (dmap->dma_mode != DMODE_INPUT) {
- if (dmap->dma_mode == DMODE_NONE &&
- adev->enable_bits & PCM_ENABLE_INPUT &&
- !dmap->qlen && adev->go) {
- unsigned long flags;
-
- spin_lock_irqsave(&dmap->lock,flags);
- DMAbuf_activate_recording(dev, dmap);
- spin_unlock_irqrestore(&dmap->lock,flags);
- }
- return 0;
- }
- if (!dmap->qlen)
- return 0;
- return POLLIN | POLLRDNORM;
-}
-
-static unsigned int poll_output(struct file * file, int dev, poll_table *wait)
-{
- struct audio_operations *adev = audio_devs[dev];
- struct dma_buffparms *dmap = adev->dmap_out;
-
- if (!(adev->open_mode & OPEN_WRITE))
- return 0;
- if (dmap->mapping_flags & DMA_MAP_MAPPED) {
- if (dmap->qlen)
- return POLLOUT | POLLWRNORM;
- return 0;
- }
- if (dmap->dma_mode == DMODE_INPUT)
- return 0;
- if (dmap->dma_mode == DMODE_NONE)
- return POLLOUT | POLLWRNORM;
- if (!DMAbuf_space_in_queue(dev))
- return 0;
- return POLLOUT | POLLWRNORM;
-}
-
-unsigned int DMAbuf_poll(struct file * file, int dev, poll_table *wait)
-{
- struct audio_operations *adev = audio_devs[dev];
- poll_wait(file, &adev->poll_sleeper, wait);
- return poll_input(file, dev, wait) | poll_output(file, dev, wait);
-}
-
-void DMAbuf_deinit(int dev)
-{
- struct audio_operations *adev = audio_devs[dev];
- /* This routine is called when driver is being unloaded */
- if (!adev)
- return;
-
- /* Persistent DMA buffers deallocated here */
- if (sound_dmap_flag == DMAP_KEEP_ON_CLOSE) {
- sound_free_dmap(adev->dmap_out);
- if (adev->flags & DMA_DUPLEX)
- sound_free_dmap(adev->dmap_in);
- }
-}
diff --git a/ANDROID_3.4.5/sound/oss/dmasound/Kconfig b/ANDROID_3.4.5/sound/oss/dmasound/Kconfig
deleted file mode 100644
index f456574a..00000000
--- a/ANDROID_3.4.5/sound/oss/dmasound/Kconfig
+++ /dev/null
@@ -1,45 +0,0 @@
-config DMASOUND_ATARI
- tristate "Atari DMA sound support"
- depends on ATARI && SOUND
- select DMASOUND
- help
- If you want to use the internal audio of your Atari in Linux, answer
- Y to this question. This will provide a Sun-like /dev/audio,
- compatible with the Linux/i386 sound system. Otherwise, say N.
-
- This driver is also available as a module ( = code which can be
- inserted in and removed from the running kernel whenever you
- want). If you want to compile it as a module, say M here and read
- <file:Documentation/kbuild/modules.txt>.
-
-config DMASOUND_PAULA
- tristate "Amiga DMA sound support"
- depends on AMIGA && SOUND
- select DMASOUND
- help
- If you want to use the internal audio of your Amiga in Linux, answer
- Y to this question. This will provide a Sun-like /dev/audio,
- compatible with the Linux/i386 sound system. Otherwise, say N.
-
- This driver is also available as a module ( = code which can be
- inserted in and removed from the running kernel whenever you
- want). If you want to compile it as a module, say M here and read
- <file:Documentation/kbuild/modules.txt>.
-
-config DMASOUND_Q40
- tristate "Q40 sound support"
- depends on Q40 && SOUND
- select DMASOUND
- help
- If you want to use the internal audio of your Q40 in Linux, answer
- Y to this question. This will provide a Sun-like /dev/audio,
- compatible with the Linux/i386 sound system. Otherwise, say N.
-
- This driver is also available as a module ( = code which can be
- inserted in and removed from the running kernel whenever you
- want). If you want to compile it as a module, say M here and read
- <file:Documentation/kbuild/modules.txt>.
-
-config DMASOUND
- tristate
- select SOUND_OSS_CORE
diff --git a/ANDROID_3.4.5/sound/oss/dmasound/Makefile b/ANDROID_3.4.5/sound/oss/dmasound/Makefile
deleted file mode 100644
index 3c153165..00000000
--- a/ANDROID_3.4.5/sound/oss/dmasound/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Makefile for the DMA sound driver
-#
-
-obj-$(CONFIG_DMASOUND_ATARI) += dmasound_core.o dmasound_atari.o
-obj-$(CONFIG_DMASOUND_PAULA) += dmasound_core.o dmasound_paula.o
-obj-$(CONFIG_DMASOUND_Q40) += dmasound_core.o dmasound_q40.o
diff --git a/ANDROID_3.4.5/sound/oss/dmasound/dmasound.h b/ANDROID_3.4.5/sound/oss/dmasound/dmasound.h
deleted file mode 100644
index 1308d8d3..00000000
--- a/ANDROID_3.4.5/sound/oss/dmasound/dmasound.h
+++ /dev/null
@@ -1,262 +0,0 @@
-#ifndef _dmasound_h_
-/*
- * linux/sound/oss/dmasound/dmasound.h
- *
- *
- * Minor numbers for the sound driver.
- *
- * Unfortunately Creative called the codec chip of SB as a DSP. For this
- * reason the /dev/dsp is reserved for digitized audio use. There is a
- * device for true DSP processors but it will be called something else.
- * In v3.0 it's /dev/sndproc but this could be a temporary solution.
- */
-#define _dmasound_h_
-
-#include <linux/types.h>
-
-#define SND_NDEVS 256 /* Number of supported devices */
-#define SND_DEV_CTL 0 /* Control port /dev/mixer */
-#define SND_DEV_SEQ 1 /* Sequencer output /dev/sequencer (FM
- synthesizer and MIDI output) */
-#define SND_DEV_MIDIN 2 /* Raw midi access */
-#define SND_DEV_DSP 3 /* Digitized voice /dev/dsp */
-#define SND_DEV_AUDIO 4 /* Sparc compatible /dev/audio */
-#define SND_DEV_DSP16 5 /* Like /dev/dsp but 16 bits/sample */
-#define SND_DEV_STATUS 6 /* /dev/sndstat */
-/* #7 not in use now. Was in 2.4. Free for use after v3.0. */
-#define SND_DEV_SEQ2 8 /* /dev/sequencer, level 2 interface */
-#define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */
-#define SND_DEV_PSS SND_DEV_SNDPROC
-
-/* switch on various prinks */
-#define DEBUG_DMASOUND 1
-
-#define MAX_AUDIO_DEV 5
-#define MAX_MIXER_DEV 4
-#define MAX_SYNTH_DEV 3
-#define MAX_MIDI_DEV 6
-#define MAX_TIMER_DEV 3
-
-#define MAX_CATCH_RADIUS 10
-
-#define le2be16(x) (((x)<<8 & 0xff00) | ((x)>>8 & 0x00ff))
-#define le2be16dbl(x) (((x)<<8 & 0xff00ff00) | ((x)>>8 & 0x00ff00ff))
-
-#define IOCTL_IN(arg, ret) \
- do { int error = get_user(ret, (int __user *)(arg)); \
- if (error) return error; \
- } while (0)
-#define IOCTL_OUT(arg, ret) ioctl_return((int __user *)(arg), ret)
-
-static inline int ioctl_return(int __user *addr, int value)
-{
- return value < 0 ? value : put_user(value, addr);
-}
-
-
- /*
- * Configuration
- */
-
-#undef HAS_8BIT_TABLES
-
-#if defined(CONFIG_DMASOUND_ATARI) || defined(CONFIG_DMASOUND_ATARI_MODULE) ||\
- defined(CONFIG_DMASOUND_PAULA) || defined(CONFIG_DMASOUND_PAULA_MODULE) ||\
- defined(CONFIG_DMASOUND_Q40) || defined(CONFIG_DMASOUND_Q40_MODULE)
-#define HAS_8BIT_TABLES
-#define MIN_BUFFERS 4
-#define MIN_BUFSIZE (1<<12) /* in bytes (- where does this come from ?) */
-#define MIN_FRAG_SIZE 8 /* not 100% sure about this */
-#define MAX_BUFSIZE (1<<17) /* Limit for Amiga is 128 kb */
-#define MAX_FRAG_SIZE 15 /* allow *4 for mono-8 => stereo-16 (for multi) */
-
-#else /* is pmac and multi is off */
-
-#define MIN_BUFFERS 2
-#define MIN_BUFSIZE (1<<8) /* in bytes */
-#define MIN_FRAG_SIZE 8
-#define MAX_BUFSIZE (1<<18) /* this is somewhat arbitrary for pmac */
-#define MAX_FRAG_SIZE 16 /* need to allow *4 for mono-8 => stereo-16 */
-#endif
-
-#define DEFAULT_N_BUFFERS 4
-#define DEFAULT_BUFF_SIZE (1<<15)
-
- /*
- * Initialization
- */
-
-extern int dmasound_init(void);
-#ifdef MODULE
-extern void dmasound_deinit(void);
-#else
-#define dmasound_deinit() do { } while (0)
-#endif
-
-/* description of the set-up applies to either hard or soft settings */
-
-typedef struct {
- int format; /* AFMT_* */
- int stereo; /* 0 = mono, 1 = stereo */
- int size; /* 8/16 bit*/
- int speed; /* speed */
-} SETTINGS;
-
- /*
- * Machine definitions
- */
-
-typedef struct {
- const char *name;
- const char *name2;
- struct module *owner;
- void *(*dma_alloc)(unsigned int, gfp_t);
- void (*dma_free)(void *, unsigned int);
- int (*irqinit)(void);
-#ifdef MODULE
- void (*irqcleanup)(void);
-#endif
- void (*init)(void);
- void (*silence)(void);
- int (*setFormat)(int);
- int (*setVolume)(int);
- int (*setBass)(int);
- int (*setTreble)(int);
- int (*setGain)(int);
- void (*play)(void);
- void (*record)(void); /* optional */
- void (*mixer_init)(void); /* optional */
- int (*mixer_ioctl)(u_int, u_long); /* optional */
- int (*write_sq_setup)(void); /* optional */
- int (*read_sq_setup)(void); /* optional */
- int (*sq_open)(fmode_t); /* optional */
- int (*state_info)(char *, size_t); /* optional */
- void (*abort_read)(void); /* optional */
- int min_dsp_speed;
- int max_dsp_speed;
- int version ;
- int hardware_afmts ; /* OSS says we only return h'ware info */
- /* when queried via SNDCTL_DSP_GETFMTS */
- int capabilities ; /* low-level reply to SNDCTL_DSP_GETCAPS */
- SETTINGS default_hard ; /* open() or init() should set something valid */
- SETTINGS default_soft ; /* you can make it look like old OSS, if you want to */
-} MACHINE;
-
- /*
- * Low level stuff
- */
-
-typedef struct {
- ssize_t (*ct_ulaw)(const u_char __user *, size_t, u_char *, ssize_t *, ssize_t);
- ssize_t (*ct_alaw)(const u_char __user *, size_t, u_char *, ssize_t *, ssize_t);
- ssize_t (*ct_s8)(const u_char __user *, size_t, u_char *, ssize_t *, ssize_t);
- ssize_t (*ct_u8)(const u_char __user *, size_t, u_char *, ssize_t *, ssize_t);
- ssize_t (*ct_s16be)(const u_char __user *, size_t, u_char *, ssize_t *, ssize_t);
- ssize_t (*ct_u16be)(const u_char __user *, size_t, u_char *, ssize_t *, ssize_t);
- ssize_t (*ct_s16le)(const u_char __user *, size_t, u_char *, ssize_t *, ssize_t);
- ssize_t (*ct_u16le)(const u_char __user *, size_t, u_char *, ssize_t *, ssize_t);
-} TRANS;
-
-struct sound_settings {
- MACHINE mach; /* machine dependent things */
- SETTINGS hard; /* hardware settings */
- SETTINGS soft; /* software settings */
- SETTINGS dsp; /* /dev/dsp default settings */
- TRANS *trans_write; /* supported translations */
- int volume_left; /* volume (range is machine dependent) */
- int volume_right;
- int bass; /* tone (range is machine dependent) */
- int treble;
- int gain;
- int minDev; /* minor device number currently open */
- spinlock_t lock;
-};
-
-extern struct sound_settings dmasound;
-
-#ifdef HAS_8BIT_TABLES
-extern char dmasound_ulaw2dma8[];
-extern char dmasound_alaw2dma8[];
-#endif
-
- /*
- * Mid level stuff
- */
-
-static inline int dmasound_set_volume(int volume)
-{
- return dmasound.mach.setVolume(volume);
-}
-
-static inline int dmasound_set_bass(int bass)
-{
- return dmasound.mach.setBass ? dmasound.mach.setBass(bass) : 50;
-}
-
-static inline int dmasound_set_treble(int treble)
-{
- return dmasound.mach.setTreble ? dmasound.mach.setTreble(treble) : 50;
-}
-
-static inline int dmasound_set_gain(int gain)
-{
- return dmasound.mach.setGain ? dmasound.mach.setGain(gain) : 100;
-}
-
-
- /*
- * Sound queue stuff, the heart of the driver
- */
-
-struct sound_queue {
- /* buffers allocated for this queue */
- int numBufs; /* real limits on what the user can have */
- int bufSize; /* in bytes */
- char **buffers;
-
- /* current parameters */
- int locked ; /* params cannot be modified when != 0 */
- int user_frags ; /* user requests this many */
- int user_frag_size ; /* of this size */
- int max_count; /* actual # fragments <= numBufs */
- int block_size; /* internal block size in bytes */
- int max_active; /* in-use fragments <= max_count */
-
- /* it shouldn't be necessary to declare any of these volatile */
- int front, rear, count;
- int rear_size;
- /*
- * The use of the playing field depends on the hardware
- *
- * Atari, PMac: The number of frames that are loaded/playing
- *
- * Amiga: Bit 0 is set: a frame is loaded
- * Bit 1 is set: a frame is playing
- */
- int active;
- wait_queue_head_t action_queue, open_queue, sync_queue;
- int non_blocking;
- int busy, syncing, xruns, died;
-};
-
-#define SLEEP(queue) interruptible_sleep_on_timeout(&queue, HZ)
-#define WAKE_UP(queue) (wake_up_interruptible(&queue))
-
-extern struct sound_queue dmasound_write_sq;
-#define write_sq dmasound_write_sq
-
-extern int dmasound_catchRadius;
-#define catchRadius dmasound_catchRadius
-
-/* define the value to be put in the byte-swap reg in mac-io
- when we want it to swap for us.
-*/
-#define BS_VAL 1
-
-#define SW_INPUT_VOLUME_SCALE 4
-#define SW_INPUT_VOLUME_DEFAULT (128 / SW_INPUT_VOLUME_SCALE)
-
-extern int expand_read_bal; /* Balance factor for reading */
-extern uint software_input_volume; /* software implemented recording volume! */
-
-#endif /* _dmasound_h_ */
diff --git a/ANDROID_3.4.5/sound/oss/dmasound/dmasound_atari.c b/ANDROID_3.4.5/sound/oss/dmasound/dmasound_atari.c
deleted file mode 100644
index 13c21446..00000000
--- a/ANDROID_3.4.5/sound/oss/dmasound/dmasound_atari.c
+++ /dev/null
@@ -1,1620 +0,0 @@
-/*
- * linux/sound/oss/dmasound/dmasound_atari.c
- *
- * Atari TT and Falcon DMA Sound Driver
- *
- * See linux/sound/oss/dmasound/dmasound_core.c for copyright and credits
- * prior to 28/01/2001
- *
- * 28/01/2001 [0.1] Iain Sandoe
- * - added versioning
- * - put in and populated the hardware_afmts field.
- * [0.2] - put in SNDCTL_DSP_GETCAPS value.
- * 01/02/2001 [0.3] - put in default hard/soft settings.
- */
-
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/soundcard.h>
-#include <linux/mm.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-
-#include <asm/uaccess.h>
-#include <asm/atariints.h>
-#include <asm/atari_stram.h>
-
-#include "dmasound.h"
-
-#define DMASOUND_ATARI_REVISION 0
-#define DMASOUND_ATARI_EDITION 3
-
-extern void atari_microwire_cmd(int cmd);
-
-static int is_falcon;
-static int write_sq_ignore_int; /* ++TeSche: used for Falcon */
-
-static int expand_bal; /* Balance factor for expanding (not volume!) */
-static int expand_data; /* Data for expanding */
-
-
-/*** Translations ************************************************************/
-
-
-/* ++TeSche: radically changed for new expanding purposes...
- *
- * These two routines now deal with copying/expanding/translating the samples
- * from user space into our buffer at the right frequency. They take care about
- * how much data there's actually to read, how much buffer space there is and
- * to convert samples into the right frequency/encoding. They will only work on
- * complete samples so it may happen they leave some bytes in the input stream
- * if the user didn't write a multiple of the current sample size. They both
- * return the number of bytes they've used from both streams so you may detect
- * such a situation. Luckily all programs should be able to cope with that.
- *
- * I think I've optimized anything as far as one can do in plain C, all
- * variables should fit in registers and the loops are really short. There's
- * one loop for every possible situation. Writing a more generalized and thus
- * parameterized loop would only produce slower code. Feel free to optimize
- * this in assembler if you like. :)
- *
- * I think these routines belong here because they're not yet really hardware
- * independent, especially the fact that the Falcon can play 16bit samples
- * only in stereo is hardcoded in both of them!
- *
- * ++geert: split in even more functions (one per format)
- */
-
-static ssize_t ata_ct_law(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t ata_ct_s8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t ata_ct_u8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t ata_ct_s16be(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t ata_ct_u16be(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t ata_ct_s16le(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t ata_ct_u16le(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t ata_ctx_law(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t ata_ctx_s8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t ata_ctx_u8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t ata_ctx_s16be(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t ata_ctx_u16be(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t ata_ctx_s16le(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t ata_ctx_u16le(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-
-
-/*** Low level stuff *********************************************************/
-
-
-static void *AtaAlloc(unsigned int size, gfp_t flags);
-static void AtaFree(void *, unsigned int size);
-static int AtaIrqInit(void);
-#ifdef MODULE
-static void AtaIrqCleanUp(void);
-#endif /* MODULE */
-static int AtaSetBass(int bass);
-static int AtaSetTreble(int treble);
-static void TTSilence(void);
-static void TTInit(void);
-static int TTSetFormat(int format);
-static int TTSetVolume(int volume);
-static int TTSetGain(int gain);
-static void FalconSilence(void);
-static void FalconInit(void);
-static int FalconSetFormat(int format);
-static int FalconSetVolume(int volume);
-static void AtaPlayNextFrame(int index);
-static void AtaPlay(void);
-static irqreturn_t AtaInterrupt(int irq, void *dummy);
-
-/*** Mid level stuff *********************************************************/
-
-static void TTMixerInit(void);
-static void FalconMixerInit(void);
-static int AtaMixerIoctl(u_int cmd, u_long arg);
-static int TTMixerIoctl(u_int cmd, u_long arg);
-static int FalconMixerIoctl(u_int cmd, u_long arg);
-static int AtaWriteSqSetup(void);
-static int AtaSqOpen(fmode_t mode);
-static int TTStateInfo(char *buffer, size_t space);
-static int FalconStateInfo(char *buffer, size_t space);
-
-
-/*** Translations ************************************************************/
-
-
-static ssize_t ata_ct_law(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- char *table = dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma8
- : dmasound_alaw2dma8;
- ssize_t count, used;
- u_char *p = &frame[*frameUsed];
-
- count = min_t(unsigned long, userCount, frameLeft);
- if (dmasound.soft.stereo)
- count &= ~1;
- used = count;
- while (count > 0) {
- u_char data;
- if (get_user(data, userPtr++))
- return -EFAULT;
- *p++ = table[data];
- count--;
- }
- *frameUsed += used;
- return used;
-}
-
-
-static ssize_t ata_ct_s8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- ssize_t count, used;
- void *p = &frame[*frameUsed];
-
- count = min_t(unsigned long, userCount, frameLeft);
- if (dmasound.soft.stereo)
- count &= ~1;
- used = count;
- if (copy_from_user(p, userPtr, count))
- return -EFAULT;
- *frameUsed += used;
- return used;
-}
-
-
-static ssize_t ata_ct_u8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- ssize_t count, used;
-
- if (!dmasound.soft.stereo) {
- u_char *p = &frame[*frameUsed];
- count = min_t(unsigned long, userCount, frameLeft);
- used = count;
- while (count > 0) {
- u_char data;
- if (get_user(data, userPtr++))
- return -EFAULT;
- *p++ = data ^ 0x80;
- count--;
- }
- } else {
- u_short *p = (u_short *)&frame[*frameUsed];
- count = min_t(unsigned long, userCount, frameLeft)>>1;
- used = count*2;
- while (count > 0) {
- u_short data;
- if (get_user(data, (u_short __user *)userPtr))
- return -EFAULT;
- userPtr += 2;
- *p++ = data ^ 0x8080;
- count--;
- }
- }
- *frameUsed += used;
- return used;
-}
-
-
-static ssize_t ata_ct_s16be(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- ssize_t count, used;
-
- if (!dmasound.soft.stereo) {
- u_short *p = (u_short *)&frame[*frameUsed];
- count = min_t(unsigned long, userCount, frameLeft)>>1;
- used = count*2;
- while (count > 0) {
- u_short data;
- if (get_user(data, (u_short __user *)userPtr))
- return -EFAULT;
- userPtr += 2;
- *p++ = data;
- *p++ = data;
- count--;
- }
- *frameUsed += used*2;
- } else {
- void *p = (u_short *)&frame[*frameUsed];
- count = min_t(unsigned long, userCount, frameLeft) & ~3;
- used = count;
- if (copy_from_user(p, userPtr, count))
- return -EFAULT;
- *frameUsed += used;
- }
- return used;
-}
-
-
-static ssize_t ata_ct_u16be(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- ssize_t count, used;
-
- if (!dmasound.soft.stereo) {
- u_short *p = (u_short *)&frame[*frameUsed];
- count = min_t(unsigned long, userCount, frameLeft)>>1;
- used = count*2;
- while (count > 0) {
- u_short data;
- if (get_user(data, (u_short __user *)userPtr))
- return -EFAULT;
- userPtr += 2;
- data ^= 0x8000;
- *p++ = data;
- *p++ = data;
- count--;
- }
- *frameUsed += used*2;
- } else {
- u_long *p = (u_long *)&frame[*frameUsed];
- count = min_t(unsigned long, userCount, frameLeft)>>2;
- used = count*4;
- while (count > 0) {
- u_int data;
- if (get_user(data, (u_int __user *)userPtr))
- return -EFAULT;
- userPtr += 4;
- *p++ = data ^ 0x80008000;
- count--;
- }
- *frameUsed += used;
- }
- return used;
-}
-
-
-static ssize_t ata_ct_s16le(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- ssize_t count, used;
-
- count = frameLeft;
- if (!dmasound.soft.stereo) {
- u_short *p = (u_short *)&frame[*frameUsed];
- count = min_t(unsigned long, userCount, frameLeft)>>1;
- used = count*2;
- while (count > 0) {
- u_short data;
- if (get_user(data, (u_short __user *)userPtr))
- return -EFAULT;
- userPtr += 2;
- data = le2be16(data);
- *p++ = data;
- *p++ = data;
- count--;
- }
- *frameUsed += used*2;
- } else {
- u_long *p = (u_long *)&frame[*frameUsed];
- count = min_t(unsigned long, userCount, frameLeft)>>2;
- used = count*4;
- while (count > 0) {
- u_long data;
- if (get_user(data, (u_int __user *)userPtr))
- return -EFAULT;
- userPtr += 4;
- data = le2be16dbl(data);
- *p++ = data;
- count--;
- }
- *frameUsed += used;
- }
- return used;
-}
-
-
-static ssize_t ata_ct_u16le(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- ssize_t count, used;
-
- count = frameLeft;
- if (!dmasound.soft.stereo) {
- u_short *p = (u_short *)&frame[*frameUsed];
- count = min_t(unsigned long, userCount, frameLeft)>>1;
- used = count*2;
- while (count > 0) {
- u_short data;
- if (get_user(data, (u_short __user *)userPtr))
- return -EFAULT;
- userPtr += 2;
- data = le2be16(data) ^ 0x8000;
- *p++ = data;
- *p++ = data;
- }
- *frameUsed += used*2;
- } else {
- u_long *p = (u_long *)&frame[*frameUsed];
- count = min_t(unsigned long, userCount, frameLeft)>>2;
- used = count;
- while (count > 0) {
- u_long data;
- if (get_user(data, (u_int __user *)userPtr))
- return -EFAULT;
- userPtr += 4;
- data = le2be16dbl(data) ^ 0x80008000;
- *p++ = data;
- count--;
- }
- *frameUsed += used;
- }
- return used;
-}
-
-
-static ssize_t ata_ctx_law(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- char *table = dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma8
- : dmasound_alaw2dma8;
- /* this should help gcc to stuff everything into registers */
- long bal = expand_bal;
- long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- ssize_t used, usedf;
-
- used = userCount;
- usedf = frameLeft;
- if (!dmasound.soft.stereo) {
- u_char *p = &frame[*frameUsed];
- u_char data = expand_data;
- while (frameLeft) {
- u_char c;
- if (bal < 0) {
- if (!userCount)
- break;
- if (get_user(c, userPtr++))
- return -EFAULT;
- data = table[c];
- userCount--;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft--;
- bal -= sSpeed;
- }
- expand_data = data;
- } else {
- u_short *p = (u_short *)&frame[*frameUsed];
- u_short data = expand_data;
- while (frameLeft >= 2) {
- u_char c;
- if (bal < 0) {
- if (userCount < 2)
- break;
- if (get_user(c, userPtr++))
- return -EFAULT;
- data = table[c] << 8;
- if (get_user(c, userPtr++))
- return -EFAULT;
- data |= table[c];
- userCount -= 2;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft -= 2;
- bal -= sSpeed;
- }
- expand_data = data;
- }
- expand_bal = bal;
- used -= userCount;
- *frameUsed += usedf-frameLeft;
- return used;
-}
-
-
-static ssize_t ata_ctx_s8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- /* this should help gcc to stuff everything into registers */
- long bal = expand_bal;
- long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- ssize_t used, usedf;
-
- used = userCount;
- usedf = frameLeft;
- if (!dmasound.soft.stereo) {
- u_char *p = &frame[*frameUsed];
- u_char data = expand_data;
- while (frameLeft) {
- if (bal < 0) {
- if (!userCount)
- break;
- if (get_user(data, userPtr++))
- return -EFAULT;
- userCount--;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft--;
- bal -= sSpeed;
- }
- expand_data = data;
- } else {
- u_short *p = (u_short *)&frame[*frameUsed];
- u_short data = expand_data;
- while (frameLeft >= 2) {
- if (bal < 0) {
- if (userCount < 2)
- break;
- if (get_user(data, (u_short __user *)userPtr))
- return -EFAULT;
- userPtr += 2;
- userCount -= 2;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft -= 2;
- bal -= sSpeed;
- }
- expand_data = data;
- }
- expand_bal = bal;
- used -= userCount;
- *frameUsed += usedf-frameLeft;
- return used;
-}
-
-
-static ssize_t ata_ctx_u8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- /* this should help gcc to stuff everything into registers */
- long bal = expand_bal;
- long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- ssize_t used, usedf;
-
- used = userCount;
- usedf = frameLeft;
- if (!dmasound.soft.stereo) {
- u_char *p = &frame[*frameUsed];
- u_char data = expand_data;
- while (frameLeft) {
- if (bal < 0) {
- if (!userCount)
- break;
- if (get_user(data, userPtr++))
- return -EFAULT;
- data ^= 0x80;
- userCount--;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft--;
- bal -= sSpeed;
- }
- expand_data = data;
- } else {
- u_short *p = (u_short *)&frame[*frameUsed];
- u_short data = expand_data;
- while (frameLeft >= 2) {
- if (bal < 0) {
- if (userCount < 2)
- break;
- if (get_user(data, (u_short __user *)userPtr))
- return -EFAULT;
- userPtr += 2;
- data ^= 0x8080;
- userCount -= 2;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft -= 2;
- bal -= sSpeed;
- }
- expand_data = data;
- }
- expand_bal = bal;
- used -= userCount;
- *frameUsed += usedf-frameLeft;
- return used;
-}
-
-
-static ssize_t ata_ctx_s16be(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- /* this should help gcc to stuff everything into registers */
- long bal = expand_bal;
- long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- ssize_t used, usedf;
-
- used = userCount;
- usedf = frameLeft;
- if (!dmasound.soft.stereo) {
- u_short *p = (u_short *)&frame[*frameUsed];
- u_short data = expand_data;
- while (frameLeft >= 4) {
- if (bal < 0) {
- if (userCount < 2)
- break;
- if (get_user(data, (u_short __user *)userPtr))
- return -EFAULT;
- userPtr += 2;
- userCount -= 2;
- bal += hSpeed;
- }
- *p++ = data;
- *p++ = data;
- frameLeft -= 4;
- bal -= sSpeed;
- }
- expand_data = data;
- } else {
- u_long *p = (u_long *)&frame[*frameUsed];
- u_long data = expand_data;
- while (frameLeft >= 4) {
- if (bal < 0) {
- if (userCount < 4)
- break;
- if (get_user(data, (u_int __user *)userPtr))
- return -EFAULT;
- userPtr += 4;
- userCount -= 4;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft -= 4;
- bal -= sSpeed;
- }
- expand_data = data;
- }
- expand_bal = bal;
- used -= userCount;
- *frameUsed += usedf-frameLeft;
- return used;
-}
-
-
-static ssize_t ata_ctx_u16be(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- /* this should help gcc to stuff everything into registers */
- long bal = expand_bal;
- long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- ssize_t used, usedf;
-
- used = userCount;
- usedf = frameLeft;
- if (!dmasound.soft.stereo) {
- u_short *p = (u_short *)&frame[*frameUsed];
- u_short data = expand_data;
- while (frameLeft >= 4) {
- if (bal < 0) {
- if (userCount < 2)
- break;
- if (get_user(data, (u_short __user *)userPtr))
- return -EFAULT;
- userPtr += 2;
- data ^= 0x8000;
- userCount -= 2;
- bal += hSpeed;
- }
- *p++ = data;
- *p++ = data;
- frameLeft -= 4;
- bal -= sSpeed;
- }
- expand_data = data;
- } else {
- u_long *p = (u_long *)&frame[*frameUsed];
- u_long data = expand_data;
- while (frameLeft >= 4) {
- if (bal < 0) {
- if (userCount < 4)
- break;
- if (get_user(data, (u_int __user *)userPtr))
- return -EFAULT;
- userPtr += 4;
- data ^= 0x80008000;
- userCount -= 4;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft -= 4;
- bal -= sSpeed;
- }
- expand_data = data;
- }
- expand_bal = bal;
- used -= userCount;
- *frameUsed += usedf-frameLeft;
- return used;
-}
-
-
-static ssize_t ata_ctx_s16le(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- /* this should help gcc to stuff everything into registers */
- long bal = expand_bal;
- long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- ssize_t used, usedf;
-
- used = userCount;
- usedf = frameLeft;
- if (!dmasound.soft.stereo) {
- u_short *p = (u_short *)&frame[*frameUsed];
- u_short data = expand_data;
- while (frameLeft >= 4) {
- if (bal < 0) {
- if (userCount < 2)
- break;
- if (get_user(data, (u_short __user *)userPtr))
- return -EFAULT;
- userPtr += 2;
- data = le2be16(data);
- userCount -= 2;
- bal += hSpeed;
- }
- *p++ = data;
- *p++ = data;
- frameLeft -= 4;
- bal -= sSpeed;
- }
- expand_data = data;
- } else {
- u_long *p = (u_long *)&frame[*frameUsed];
- u_long data = expand_data;
- while (frameLeft >= 4) {
- if (bal < 0) {
- if (userCount < 4)
- break;
- if (get_user(data, (u_int __user *)userPtr))
- return -EFAULT;
- userPtr += 4;
- data = le2be16dbl(data);
- userCount -= 4;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft -= 4;
- bal -= sSpeed;
- }
- expand_data = data;
- }
- expand_bal = bal;
- used -= userCount;
- *frameUsed += usedf-frameLeft;
- return used;
-}
-
-
-static ssize_t ata_ctx_u16le(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- /* this should help gcc to stuff everything into registers */
- long bal = expand_bal;
- long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- ssize_t used, usedf;
-
- used = userCount;
- usedf = frameLeft;
- if (!dmasound.soft.stereo) {
- u_short *p = (u_short *)&frame[*frameUsed];
- u_short data = expand_data;
- while (frameLeft >= 4) {
- if (bal < 0) {
- if (userCount < 2)
- break;
- if (get_user(data, (u_short __user *)userPtr))
- return -EFAULT;
- userPtr += 2;
- data = le2be16(data) ^ 0x8000;
- userCount -= 2;
- bal += hSpeed;
- }
- *p++ = data;
- *p++ = data;
- frameLeft -= 4;
- bal -= sSpeed;
- }
- expand_data = data;
- } else {
- u_long *p = (u_long *)&frame[*frameUsed];
- u_long data = expand_data;
- while (frameLeft >= 4) {
- if (bal < 0) {
- if (userCount < 4)
- break;
- if (get_user(data, (u_int __user *)userPtr))
- return -EFAULT;
- userPtr += 4;
- data = le2be16dbl(data) ^ 0x80008000;
- userCount -= 4;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft -= 4;
- bal -= sSpeed;
- }
- expand_data = data;
- }
- expand_bal = bal;
- used -= userCount;
- *frameUsed += usedf-frameLeft;
- return used;
-}
-
-
-static TRANS transTTNormal = {
- .ct_ulaw = ata_ct_law,
- .ct_alaw = ata_ct_law,
- .ct_s8 = ata_ct_s8,
- .ct_u8 = ata_ct_u8,
-};
-
-static TRANS transTTExpanding = {
- .ct_ulaw = ata_ctx_law,
- .ct_alaw = ata_ctx_law,
- .ct_s8 = ata_ctx_s8,
- .ct_u8 = ata_ctx_u8,
-};
-
-static TRANS transFalconNormal = {
- .ct_ulaw = ata_ct_law,
- .ct_alaw = ata_ct_law,
- .ct_s8 = ata_ct_s8,
- .ct_u8 = ata_ct_u8,
- .ct_s16be = ata_ct_s16be,
- .ct_u16be = ata_ct_u16be,
- .ct_s16le = ata_ct_s16le,
- .ct_u16le = ata_ct_u16le
-};
-
-static TRANS transFalconExpanding = {
- .ct_ulaw = ata_ctx_law,
- .ct_alaw = ata_ctx_law,
- .ct_s8 = ata_ctx_s8,
- .ct_u8 = ata_ctx_u8,
- .ct_s16be = ata_ctx_s16be,
- .ct_u16be = ata_ctx_u16be,
- .ct_s16le = ata_ctx_s16le,
- .ct_u16le = ata_ctx_u16le,
-};
-
-
-/*** Low level stuff *********************************************************/
-
-
-
-/*
- * Atari (TT/Falcon)
- */
-
-static void *AtaAlloc(unsigned int size, gfp_t flags)
-{
- return atari_stram_alloc(size, "dmasound");
-}
-
-static void AtaFree(void *obj, unsigned int size)
-{
- atari_stram_free( obj );
-}
-
-static int __init AtaIrqInit(void)
-{
- /* Set up timer A. Timer A
- will receive a signal upon end of playing from the sound
- hardware. Furthermore Timer A is able to count events
- and will cause an interrupt after a programmed number
- of events. So all we need to keep the music playing is
- to provide the sound hardware with new data upon
- an interrupt from timer A. */
- st_mfp.tim_ct_a = 0; /* ++roman: Stop timer before programming! */
- st_mfp.tim_dt_a = 1; /* Cause interrupt after first event. */
- st_mfp.tim_ct_a = 8; /* Turn on event counting. */
- /* Register interrupt handler. */
- if (request_irq(IRQ_MFP_TIMA, AtaInterrupt, IRQ_TYPE_SLOW, "DMA sound",
- AtaInterrupt))
- return 0;
- st_mfp.int_en_a |= 0x20; /* Turn interrupt on. */
- st_mfp.int_mk_a |= 0x20;
- return 1;
-}
-
-#ifdef MODULE
-static void AtaIrqCleanUp(void)
-{
- st_mfp.tim_ct_a = 0; /* stop timer */
- st_mfp.int_en_a &= ~0x20; /* turn interrupt off */
- free_irq(IRQ_MFP_TIMA, AtaInterrupt);
-}
-#endif /* MODULE */
-
-
-#define TONE_VOXWARE_TO_DB(v) \
- (((v) < 0) ? -12 : ((v) > 100) ? 12 : ((v) - 50) * 6 / 25)
-#define TONE_DB_TO_VOXWARE(v) (((v) * 25 + ((v) > 0 ? 5 : -5)) / 6 + 50)
-
-
-static int AtaSetBass(int bass)
-{
- dmasound.bass = TONE_VOXWARE_TO_DB(bass);
- atari_microwire_cmd(MW_LM1992_BASS(dmasound.bass));
- return TONE_DB_TO_VOXWARE(dmasound.bass);
-}
-
-
-static int AtaSetTreble(int treble)
-{
- dmasound.treble = TONE_VOXWARE_TO_DB(treble);
- atari_microwire_cmd(MW_LM1992_TREBLE(dmasound.treble));
- return TONE_DB_TO_VOXWARE(dmasound.treble);
-}
-
-
-
-/*
- * TT
- */
-
-
-static void TTSilence(void)
-{
- tt_dmasnd.ctrl = DMASND_CTRL_OFF;
- atari_microwire_cmd(MW_LM1992_PSG_HIGH); /* mix in PSG signal 1:1 */
-}
-
-
-static void TTInit(void)
-{
- int mode, i, idx;
- const int freq[4] = {50066, 25033, 12517, 6258};
-
- /* search a frequency that fits into the allowed error range */
-
- idx = -1;
- for (i = 0; i < ARRAY_SIZE(freq); i++)
- /* this isn't as much useful for a TT than for a Falcon, but
- * then it doesn't hurt very much to implement it for a TT too.
- */
- if ((100 * abs(dmasound.soft.speed - freq[i]) / freq[i]) < catchRadius)
- idx = i;
- if (idx > -1) {
- dmasound.soft.speed = freq[idx];
- dmasound.trans_write = &transTTNormal;
- } else
- dmasound.trans_write = &transTTExpanding;
-
- TTSilence();
- dmasound.hard = dmasound.soft;
-
- if (dmasound.hard.speed > 50066) {
- /* we would need to squeeze the sound, but we won't do that */
- dmasound.hard.speed = 50066;
- mode = DMASND_MODE_50KHZ;
- dmasound.trans_write = &transTTNormal;
- } else if (dmasound.hard.speed > 25033) {
- dmasound.hard.speed = 50066;
- mode = DMASND_MODE_50KHZ;
- } else if (dmasound.hard.speed > 12517) {
- dmasound.hard.speed = 25033;
- mode = DMASND_MODE_25KHZ;
- } else if (dmasound.hard.speed > 6258) {
- dmasound.hard.speed = 12517;
- mode = DMASND_MODE_12KHZ;
- } else {
- dmasound.hard.speed = 6258;
- mode = DMASND_MODE_6KHZ;
- }
-
- tt_dmasnd.mode = (dmasound.hard.stereo ?
- DMASND_MODE_STEREO : DMASND_MODE_MONO) |
- DMASND_MODE_8BIT | mode;
-
- expand_bal = -dmasound.soft.speed;
-}
-
-
-static int TTSetFormat(int format)
-{
- /* TT sound DMA supports only 8bit modes */
-
- switch (format) {
- case AFMT_QUERY:
- return dmasound.soft.format;
- case AFMT_MU_LAW:
- case AFMT_A_LAW:
- case AFMT_S8:
- case AFMT_U8:
- break;
- default:
- format = AFMT_S8;
- }
-
- dmasound.soft.format = format;
- dmasound.soft.size = 8;
- if (dmasound.minDev == SND_DEV_DSP) {
- dmasound.dsp.format = format;
- dmasound.dsp.size = 8;
- }
- TTInit();
-
- return format;
-}
-
-
-#define VOLUME_VOXWARE_TO_DB(v) \
- (((v) < 0) ? -40 : ((v) > 100) ? 0 : ((v) * 2) / 5 - 40)
-#define VOLUME_DB_TO_VOXWARE(v) ((((v) + 40) * 5 + 1) / 2)
-
-
-static int TTSetVolume(int volume)
-{
- dmasound.volume_left = VOLUME_VOXWARE_TO_DB(volume & 0xff);
- atari_microwire_cmd(MW_LM1992_BALLEFT(dmasound.volume_left));
- dmasound.volume_right = VOLUME_VOXWARE_TO_DB((volume & 0xff00) >> 8);
- atari_microwire_cmd(MW_LM1992_BALRIGHT(dmasound.volume_right));
- return VOLUME_DB_TO_VOXWARE(dmasound.volume_left) |
- (VOLUME_DB_TO_VOXWARE(dmasound.volume_right) << 8);
-}
-
-
-#define GAIN_VOXWARE_TO_DB(v) \
- (((v) < 0) ? -80 : ((v) > 100) ? 0 : ((v) * 4) / 5 - 80)
-#define GAIN_DB_TO_VOXWARE(v) ((((v) + 80) * 5 + 1) / 4)
-
-static int TTSetGain(int gain)
-{
- dmasound.gain = GAIN_VOXWARE_TO_DB(gain);
- atari_microwire_cmd(MW_LM1992_VOLUME(dmasound.gain));
- return GAIN_DB_TO_VOXWARE(dmasound.gain);
-}
-
-
-
-/*
- * Falcon
- */
-
-
-static void FalconSilence(void)
-{
- /* stop playback, set sample rate 50kHz for PSG sound */
- tt_dmasnd.ctrl = DMASND_CTRL_OFF;
- tt_dmasnd.mode = DMASND_MODE_50KHZ | DMASND_MODE_STEREO | DMASND_MODE_8BIT;
- tt_dmasnd.int_div = 0; /* STE compatible divider */
- tt_dmasnd.int_ctrl = 0x0;
- tt_dmasnd.cbar_src = 0x0000; /* no matrix inputs */
- tt_dmasnd.cbar_dst = 0x0000; /* no matrix outputs */
- tt_dmasnd.dac_src = 1; /* connect ADC to DAC, disconnect matrix */
- tt_dmasnd.adc_src = 3; /* ADC Input = PSG */
-}
-
-
-static void FalconInit(void)
-{
- int divider, i, idx;
- const int freq[8] = {49170, 32780, 24585, 19668, 16390, 12292, 9834, 8195};
-
- /* search a frequency that fits into the allowed error range */
-
- idx = -1;
- for (i = 0; i < ARRAY_SIZE(freq); i++)
- /* if we will tolerate 3% error 8000Hz->8195Hz (2.38%) would
- * be playable without expanding, but that now a kernel runtime
- * option
- */
- if ((100 * abs(dmasound.soft.speed - freq[i]) / freq[i]) < catchRadius)
- idx = i;
- if (idx > -1) {
- dmasound.soft.speed = freq[idx];
- dmasound.trans_write = &transFalconNormal;
- } else
- dmasound.trans_write = &transFalconExpanding;
-
- FalconSilence();
- dmasound.hard = dmasound.soft;
-
- if (dmasound.hard.size == 16) {
- /* the Falcon can play 16bit samples only in stereo */
- dmasound.hard.stereo = 1;
- }
-
- if (dmasound.hard.speed > 49170) {
- /* we would need to squeeze the sound, but we won't do that */
- dmasound.hard.speed = 49170;
- divider = 1;
- dmasound.trans_write = &transFalconNormal;
- } else if (dmasound.hard.speed > 32780) {
- dmasound.hard.speed = 49170;
- divider = 1;
- } else if (dmasound.hard.speed > 24585) {
- dmasound.hard.speed = 32780;
- divider = 2;
- } else if (dmasound.hard.speed > 19668) {
- dmasound.hard.speed = 24585;
- divider = 3;
- } else if (dmasound.hard.speed > 16390) {
- dmasound.hard.speed = 19668;
- divider = 4;
- } else if (dmasound.hard.speed > 12292) {
- dmasound.hard.speed = 16390;
- divider = 5;
- } else if (dmasound.hard.speed > 9834) {
- dmasound.hard.speed = 12292;
- divider = 7;
- } else if (dmasound.hard.speed > 8195) {
- dmasound.hard.speed = 9834;
- divider = 9;
- } else {
- dmasound.hard.speed = 8195;
- divider = 11;
- }
- tt_dmasnd.int_div = divider;
-
- /* Setup Falcon sound DMA for playback */
- tt_dmasnd.int_ctrl = 0x4; /* Timer A int at play end */
- tt_dmasnd.track_select = 0x0; /* play 1 track, track 1 */
- tt_dmasnd.cbar_src = 0x0001; /* DMA(25MHz) --> DAC */
- tt_dmasnd.cbar_dst = 0x0000;
- tt_dmasnd.rec_track_select = 0;
- tt_dmasnd.dac_src = 2; /* connect matrix to DAC */
- tt_dmasnd.adc_src = 0; /* ADC Input = Mic */
-
- tt_dmasnd.mode = (dmasound.hard.stereo ?
- DMASND_MODE_STEREO : DMASND_MODE_MONO) |
- ((dmasound.hard.size == 8) ?
- DMASND_MODE_8BIT : DMASND_MODE_16BIT) |
- DMASND_MODE_6KHZ;
-
- expand_bal = -dmasound.soft.speed;
-}
-
-
-static int FalconSetFormat(int format)
-{
- int size;
- /* Falcon sound DMA supports 8bit and 16bit modes */
-
- switch (format) {
- case AFMT_QUERY:
- return dmasound.soft.format;
- case AFMT_MU_LAW:
- case AFMT_A_LAW:
- case AFMT_U8:
- case AFMT_S8:
- size = 8;
- break;
- case AFMT_S16_BE:
- case AFMT_U16_BE:
- case AFMT_S16_LE:
- case AFMT_U16_LE:
- size = 16;
- break;
- default: /* :-) */
- size = 8;
- format = AFMT_S8;
- }
-
- dmasound.soft.format = format;
- dmasound.soft.size = size;
- if (dmasound.minDev == SND_DEV_DSP) {
- dmasound.dsp.format = format;
- dmasound.dsp.size = dmasound.soft.size;
- }
-
- FalconInit();
-
- return format;
-}
-
-
-/* This is for the Falcon output *attenuation* in 1.5dB steps,
- * i.e. output level from 0 to -22.5dB in -1.5dB steps.
- */
-#define VOLUME_VOXWARE_TO_ATT(v) \
- ((v) < 0 ? 15 : (v) > 100 ? 0 : 15 - (v) * 3 / 20)
-#define VOLUME_ATT_TO_VOXWARE(v) (100 - (v) * 20 / 3)
-
-
-static int FalconSetVolume(int volume)
-{
- dmasound.volume_left = VOLUME_VOXWARE_TO_ATT(volume & 0xff);
- dmasound.volume_right = VOLUME_VOXWARE_TO_ATT((volume & 0xff00) >> 8);
- tt_dmasnd.output_atten = dmasound.volume_left << 8 | dmasound.volume_right << 4;
- return VOLUME_ATT_TO_VOXWARE(dmasound.volume_left) |
- VOLUME_ATT_TO_VOXWARE(dmasound.volume_right) << 8;
-}
-
-
-static void AtaPlayNextFrame(int index)
-{
- char *start, *end;
-
- /* used by AtaPlay() if all doubts whether there really is something
- * to be played are already wiped out.
- */
- start = write_sq.buffers[write_sq.front];
- end = start+((write_sq.count == index) ? write_sq.rear_size
- : write_sq.block_size);
- /* end might not be a legal virtual address. */
- DMASNDSetEnd(virt_to_phys(end - 1) + 1);
- DMASNDSetBase(virt_to_phys(start));
- /* Since only an even number of samples per frame can
- be played, we might lose one byte here. (TO DO) */
- write_sq.front = (write_sq.front+1) % write_sq.max_count;
- write_sq.active++;
- tt_dmasnd.ctrl = DMASND_CTRL_ON | DMASND_CTRL_REPEAT;
-}
-
-
-static void AtaPlay(void)
-{
- /* ++TeSche: Note that write_sq.active is no longer just a flag but
- * holds the number of frames the DMA is currently programmed for
- * instead, may be 0, 1 (currently being played) or 2 (pre-programmed).
- *
- * Changes done to write_sq.count and write_sq.active are a bit more
- * subtle again so now I must admit I also prefer disabling the irq
- * here rather than considering all possible situations. But the point
- * is that disabling the irq doesn't have any bad influence on this
- * version of the driver as we benefit from having pre-programmed the
- * DMA wherever possible: There's no need to reload the DMA at the
- * exact time of an interrupt but only at some time while the
- * pre-programmed frame is playing!
- */
- atari_disable_irq(IRQ_MFP_TIMA);
-
- if (write_sq.active == 2 || /* DMA is 'full' */
- write_sq.count <= 0) { /* nothing to do */
- atari_enable_irq(IRQ_MFP_TIMA);
- return;
- }
-
- if (write_sq.active == 0) {
- /* looks like there's nothing 'in' the DMA yet, so try
- * to put two frames into it (at least one is available).
- */
- if (write_sq.count == 1 &&
- write_sq.rear_size < write_sq.block_size &&
- !write_sq.syncing) {
- /* hmmm, the only existing frame is not
- * yet filled and we're not syncing?
- */
- atari_enable_irq(IRQ_MFP_TIMA);
- return;
- }
- AtaPlayNextFrame(1);
- if (write_sq.count == 1) {
- /* no more frames */
- atari_enable_irq(IRQ_MFP_TIMA);
- return;
- }
- if (write_sq.count == 2 &&
- write_sq.rear_size < write_sq.block_size &&
- !write_sq.syncing) {
- /* hmmm, there were two frames, but the second
- * one is not yet filled and we're not syncing?
- */
- atari_enable_irq(IRQ_MFP_TIMA);
- return;
- }
- AtaPlayNextFrame(2);
- } else {
- /* there's already a frame being played so we may only stuff
- * one new into the DMA, but even if this may be the last
- * frame existing the previous one is still on write_sq.count.
- */
- if (write_sq.count == 2 &&
- write_sq.rear_size < write_sq.block_size &&
- !write_sq.syncing) {
- /* hmmm, the only existing frame is not
- * yet filled and we're not syncing?
- */
- atari_enable_irq(IRQ_MFP_TIMA);
- return;
- }
- AtaPlayNextFrame(2);
- }
- atari_enable_irq(IRQ_MFP_TIMA);
-}
-
-
-static irqreturn_t AtaInterrupt(int irq, void *dummy)
-{
-#if 0
- /* ++TeSche: if you should want to test this... */
- static int cnt;
- if (write_sq.active == 2)
- if (++cnt == 10) {
- /* simulate losing an interrupt */
- cnt = 0;
- return IRQ_HANDLED;
- }
-#endif
- spin_lock(&dmasound.lock);
- if (write_sq_ignore_int && is_falcon) {
- /* ++TeSche: Falcon only: ignore first irq because it comes
- * immediately after starting a frame. after that, irqs come
- * (almost) like on the TT.
- */
- write_sq_ignore_int = 0;
- goto out;
- }
-
- if (!write_sq.active) {
- /* playing was interrupted and sq_reset() has already cleared
- * the sq variables, so better don't do anything here.
- */
- WAKE_UP(write_sq.sync_queue);
- goto out;
- }
-
- /* Probably ;) one frame is finished. Well, in fact it may be that a
- * pre-programmed one is also finished because there has been a long
- * delay in interrupt delivery and we've completely lost one, but
- * there's no way to detect such a situation. In such a case the last
- * frame will be played more than once and the situation will recover
- * as soon as the irq gets through.
- */
- write_sq.count--;
- write_sq.active--;
-
- if (!write_sq.active) {
- tt_dmasnd.ctrl = DMASND_CTRL_OFF;
- write_sq_ignore_int = 1;
- }
-
- WAKE_UP(write_sq.action_queue);
- /* At least one block of the queue is free now
- so wake up a writing process blocked because
- of a full queue. */
-
- if ((write_sq.active != 1) || (write_sq.count != 1))
- /* We must be a bit carefully here: write_sq.count indicates the
- * number of buffers used and not the number of frames to be
- * played. If write_sq.count==1 and write_sq.active==1 that
- * means the only remaining frame was already programmed
- * earlier (and is currently running) so we mustn't call
- * AtaPlay() here, otherwise we'll play one frame too much.
- */
- AtaPlay();
-
- if (!write_sq.active) WAKE_UP(write_sq.sync_queue);
- /* We are not playing after AtaPlay(), so there
- is nothing to play any more. Wake up a process
- waiting for audio output to drain. */
-out:
- spin_unlock(&dmasound.lock);
- return IRQ_HANDLED;
-}
-
-
-/*** Mid level stuff *********************************************************/
-
-
-/*
- * /dev/mixer abstraction
- */
-
-#define RECLEVEL_VOXWARE_TO_GAIN(v) \
- ((v) < 0 ? 0 : (v) > 100 ? 15 : (v) * 3 / 20)
-#define RECLEVEL_GAIN_TO_VOXWARE(v) (((v) * 20 + 2) / 3)
-
-
-static void __init TTMixerInit(void)
-{
- atari_microwire_cmd(MW_LM1992_VOLUME(0));
- dmasound.volume_left = 0;
- atari_microwire_cmd(MW_LM1992_BALLEFT(0));
- dmasound.volume_right = 0;
- atari_microwire_cmd(MW_LM1992_BALRIGHT(0));
- atari_microwire_cmd(MW_LM1992_TREBLE(0));
- atari_microwire_cmd(MW_LM1992_BASS(0));
-}
-
-static void __init FalconMixerInit(void)
-{
- dmasound.volume_left = (tt_dmasnd.output_atten & 0xf00) >> 8;
- dmasound.volume_right = (tt_dmasnd.output_atten & 0xf0) >> 4;
-}
-
-static int AtaMixerIoctl(u_int cmd, u_long arg)
-{
- int data;
- unsigned long flags;
- switch (cmd) {
- case SOUND_MIXER_READ_SPEAKER:
- if (is_falcon || MACH_IS_TT) {
- int porta;
- spin_lock_irqsave(&dmasound.lock, flags);
- sound_ym.rd_data_reg_sel = 14;
- porta = sound_ym.rd_data_reg_sel;
- spin_unlock_irqrestore(&dmasound.lock, flags);
- return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
- }
- break;
- case SOUND_MIXER_WRITE_VOLUME:
- IOCTL_IN(arg, data);
- return IOCTL_OUT(arg, dmasound_set_volume(data));
- case SOUND_MIXER_WRITE_SPEAKER:
- if (is_falcon || MACH_IS_TT) {
- int porta;
- IOCTL_IN(arg, data);
- spin_lock_irqsave(&dmasound.lock, flags);
- sound_ym.rd_data_reg_sel = 14;
- porta = (sound_ym.rd_data_reg_sel & ~0x40) |
- (data < 50 ? 0x40 : 0);
- sound_ym.wd_data = porta;
- spin_unlock_irqrestore(&dmasound.lock, flags);
- return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
- }
- }
- return -EINVAL;
-}
-
-
-static int TTMixerIoctl(u_int cmd, u_long arg)
-{
- int data;
- switch (cmd) {
- case SOUND_MIXER_READ_RECMASK:
- return IOCTL_OUT(arg, 0);
- case SOUND_MIXER_READ_DEVMASK:
- return IOCTL_OUT(arg,
- SOUND_MASK_VOLUME | SOUND_MASK_TREBLE | SOUND_MASK_BASS |
- (MACH_IS_TT ? SOUND_MASK_SPEAKER : 0));
- case SOUND_MIXER_READ_STEREODEVS:
- return IOCTL_OUT(arg, SOUND_MASK_VOLUME);
- case SOUND_MIXER_READ_VOLUME:
- return IOCTL_OUT(arg,
- VOLUME_DB_TO_VOXWARE(dmasound.volume_left) |
- (VOLUME_DB_TO_VOXWARE(dmasound.volume_right) << 8));
- case SOUND_MIXER_READ_BASS:
- return IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(dmasound.bass));
- case SOUND_MIXER_READ_TREBLE:
- return IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(dmasound.treble));
- case SOUND_MIXER_READ_OGAIN:
- return IOCTL_OUT(arg, GAIN_DB_TO_VOXWARE(dmasound.gain));
- case SOUND_MIXER_WRITE_BASS:
- IOCTL_IN(arg, data);
- return IOCTL_OUT(arg, dmasound_set_bass(data));
- case SOUND_MIXER_WRITE_TREBLE:
- IOCTL_IN(arg, data);
- return IOCTL_OUT(arg, dmasound_set_treble(data));
- case SOUND_MIXER_WRITE_OGAIN:
- IOCTL_IN(arg, data);
- return IOCTL_OUT(arg, dmasound_set_gain(data));
- }
- return AtaMixerIoctl(cmd, arg);
-}
-
-static int FalconMixerIoctl(u_int cmd, u_long arg)
-{
- int data;
- switch (cmd) {
- case SOUND_MIXER_READ_RECMASK:
- return IOCTL_OUT(arg, SOUND_MASK_MIC);
- case SOUND_MIXER_READ_DEVMASK:
- return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC | SOUND_MASK_SPEAKER);
- case SOUND_MIXER_READ_STEREODEVS:
- return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC);
- case SOUND_MIXER_READ_VOLUME:
- return IOCTL_OUT(arg,
- VOLUME_ATT_TO_VOXWARE(dmasound.volume_left) |
- VOLUME_ATT_TO_VOXWARE(dmasound.volume_right) << 8);
- case SOUND_MIXER_READ_CAPS:
- return IOCTL_OUT(arg, SOUND_CAP_EXCL_INPUT);
- case SOUND_MIXER_WRITE_MIC:
- IOCTL_IN(arg, data);
- tt_dmasnd.input_gain =
- RECLEVEL_VOXWARE_TO_GAIN(data & 0xff) << 4 |
- RECLEVEL_VOXWARE_TO_GAIN(data >> 8 & 0xff);
- /* fall thru, return set value */
- case SOUND_MIXER_READ_MIC:
- return IOCTL_OUT(arg,
- RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain >> 4 & 0xf) |
- RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain & 0xf) << 8);
- }
- return AtaMixerIoctl(cmd, arg);
-}
-
-static int AtaWriteSqSetup(void)
-{
- write_sq_ignore_int = 0;
- return 0 ;
-}
-
-static int AtaSqOpen(fmode_t mode)
-{
- write_sq_ignore_int = 1;
- return 0 ;
-}
-
-static int TTStateInfo(char *buffer, size_t space)
-{
- int len = 0;
- len += sprintf(buffer+len, "\tvol left %ddB [-40... 0]\n",
- dmasound.volume_left);
- len += sprintf(buffer+len, "\tvol right %ddB [-40... 0]\n",
- dmasound.volume_right);
- len += sprintf(buffer+len, "\tbass %ddB [-12...+12]\n",
- dmasound.bass);
- len += sprintf(buffer+len, "\ttreble %ddB [-12...+12]\n",
- dmasound.treble);
- if (len >= space) {
- printk(KERN_ERR "dmasound_atari: overflowed state buffer alloc.\n") ;
- len = space ;
- }
- return len;
-}
-
-static int FalconStateInfo(char *buffer, size_t space)
-{
- int len = 0;
- len += sprintf(buffer+len, "\tvol left %ddB [-22.5 ... 0]\n",
- dmasound.volume_left);
- len += sprintf(buffer+len, "\tvol right %ddB [-22.5 ... 0]\n",
- dmasound.volume_right);
- if (len >= space) {
- printk(KERN_ERR "dmasound_atari: overflowed state buffer alloc.\n") ;
- len = space ;
- }
- return len;
-}
-
-
-/*** Machine definitions *****************************************************/
-
-static SETTINGS def_hard_falcon = {
- .format = AFMT_S8,
- .stereo = 0,
- .size = 8,
- .speed = 8195
-} ;
-
-static SETTINGS def_hard_tt = {
- .format = AFMT_S8,
- .stereo = 0,
- .size = 8,
- .speed = 12517
-} ;
-
-static SETTINGS def_soft = {
- .format = AFMT_U8,
- .stereo = 0,
- .size = 8,
- .speed = 8000
-} ;
-
-static __initdata MACHINE machTT = {
- .name = "Atari",
- .name2 = "TT",
- .owner = THIS_MODULE,
- .dma_alloc = AtaAlloc,
- .dma_free = AtaFree,
- .irqinit = AtaIrqInit,
-#ifdef MODULE
- .irqcleanup = AtaIrqCleanUp,
-#endif /* MODULE */
- .init = TTInit,
- .silence = TTSilence,
- .setFormat = TTSetFormat,
- .setVolume = TTSetVolume,
- .setBass = AtaSetBass,
- .setTreble = AtaSetTreble,
- .setGain = TTSetGain,
- .play = AtaPlay,
- .mixer_init = TTMixerInit,
- .mixer_ioctl = TTMixerIoctl,
- .write_sq_setup = AtaWriteSqSetup,
- .sq_open = AtaSqOpen,
- .state_info = TTStateInfo,
- .min_dsp_speed = 6258,
- .version = ((DMASOUND_ATARI_REVISION<<8) | DMASOUND_ATARI_EDITION),
- .hardware_afmts = AFMT_S8, /* h'ware-supported formats *only* here */
- .capabilities = DSP_CAP_BATCH /* As per SNDCTL_DSP_GETCAPS */
-};
-
-static __initdata MACHINE machFalcon = {
- .name = "Atari",
- .name2 = "FALCON",
- .dma_alloc = AtaAlloc,
- .dma_free = AtaFree,
- .irqinit = AtaIrqInit,
-#ifdef MODULE
- .irqcleanup = AtaIrqCleanUp,
-#endif /* MODULE */
- .init = FalconInit,
- .silence = FalconSilence,
- .setFormat = FalconSetFormat,
- .setVolume = FalconSetVolume,
- .setBass = AtaSetBass,
- .setTreble = AtaSetTreble,
- .play = AtaPlay,
- .mixer_init = FalconMixerInit,
- .mixer_ioctl = FalconMixerIoctl,
- .write_sq_setup = AtaWriteSqSetup,
- .sq_open = AtaSqOpen,
- .state_info = FalconStateInfo,
- .min_dsp_speed = 8195,
- .version = ((DMASOUND_ATARI_REVISION<<8) | DMASOUND_ATARI_EDITION),
- .hardware_afmts = (AFMT_S8 | AFMT_S16_BE), /* h'ware-supported formats *only* here */
- .capabilities = DSP_CAP_BATCH /* As per SNDCTL_DSP_GETCAPS */
-};
-
-
-/*** Config & Setup **********************************************************/
-
-
-static int __init dmasound_atari_init(void)
-{
- if (MACH_IS_ATARI && ATARIHW_PRESENT(PCM_8BIT)) {
- if (ATARIHW_PRESENT(CODEC)) {
- dmasound.mach = machFalcon;
- dmasound.mach.default_soft = def_soft ;
- dmasound.mach.default_hard = def_hard_falcon ;
- is_falcon = 1;
- } else if (ATARIHW_PRESENT(MICROWIRE)) {
- dmasound.mach = machTT;
- dmasound.mach.default_soft = def_soft ;
- dmasound.mach.default_hard = def_hard_tt ;
- is_falcon = 0;
- } else
- return -ENODEV;
- if ((st_mfp.int_en_a & st_mfp.int_mk_a & 0x20) == 0)
- return dmasound_init();
- else {
- printk("DMA sound driver: Timer A interrupt already in use\n");
- return -EBUSY;
- }
- }
- return -ENODEV;
-}
-
-static void __exit dmasound_atari_cleanup(void)
-{
- dmasound_deinit();
-}
-
-module_init(dmasound_atari_init);
-module_exit(dmasound_atari_cleanup);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/oss/dmasound/dmasound_core.c b/ANDROID_3.4.5/sound/oss/dmasound/dmasound_core.c
deleted file mode 100644
index c918313c..00000000
--- a/ANDROID_3.4.5/sound/oss/dmasound/dmasound_core.c
+++ /dev/null
@@ -1,1589 +0,0 @@
-/*
- * linux/sound/oss/dmasound/dmasound_core.c
- *
- *
- * OSS/Free compatible Atari TT/Falcon and Amiga DMA sound driver for
- * Linux/m68k
- * Extended to support Power Macintosh for Linux/ppc by Paul Mackerras
- *
- * (c) 1995 by Michael Schlueter & Michael Marte
- *
- * Michael Schlueter (michael@duck.syd.de) did the basic structure of the VFS
- * interface and the u-law to signed byte conversion.
- *
- * Michael Marte (marte@informatik.uni-muenchen.de) did the sound queue,
- * /dev/mixer, /dev/sndstat and complemented the VFS interface. He would like
- * to thank:
- * - Michael Schlueter for initial ideas and documentation on the MFP and
- * the DMA sound hardware.
- * - Therapy? for their CD 'Troublegum' which really made me rock.
- *
- * /dev/sndstat is based on code by Hannu Savolainen, the author of the
- * VoxWare family of drivers.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
- * for more details.
- *
- * History:
- *
- * 1995/8/25 First release
- *
- * 1995/9/02 Roman Hodek:
- * - Fixed atari_stram_alloc() call, the timer
- * programming and several race conditions
- * 1995/9/14 Roman Hodek:
- * - After some discussion with Michael Schlueter,
- * revised the interrupt disabling
- * - Slightly speeded up U8->S8 translation by using
- * long operations where possible
- * - Added 4:3 interpolation for /dev/audio
- *
- * 1995/9/20 Torsten Scherer:
- * - Fixed a bug in sq_write and changed /dev/audio
- * converting to play at 12517Hz instead of 6258Hz.
- *
- * 1995/9/23 Torsten Scherer:
- * - Changed sq_interrupt() and sq_play() to pre-program
- * the DMA for another frame while there's still one
- * running. This allows the IRQ response to be
- * arbitrarily delayed and playing will still continue.
- *
- * 1995/10/14 Guenther Kelleter, Torsten Scherer:
- * - Better support for Falcon audio (the Falcon doesn't
- * raise an IRQ at the end of a frame, but at the
- * beginning instead!). uses 'if (codec_dma)' in lots
- * of places to simply switch between Falcon and TT
- * code.
- *
- * 1995/11/06 Torsten Scherer:
- * - Started introducing a hardware abstraction scheme
- * (may perhaps also serve for Amigas?)
- * - Can now play samples at almost all frequencies by
- * means of a more generalized expand routine
- * - Takes a good deal of care to cut data only at
- * sample sizes
- * - Buffer size is now a kernel runtime option
- * - Implemented fsync() & several minor improvements
- * Guenther Kelleter:
- * - Useful hints and bug fixes
- * - Cross-checked it for Falcons
- *
- * 1996/3/9 Geert Uytterhoeven:
- * - Support added for Amiga, A-law, 16-bit little
- * endian.
- * - Unification to drivers/sound/dmasound.c.
- *
- * 1996/4/6 Martin Mitchell:
- * - Updated to 1.3 kernel.
- *
- * 1996/6/13 Topi Kanerva:
- * - Fixed things that were broken (mainly the amiga
- * 14-bit routines)
- * - /dev/sndstat shows now the real hardware frequency
- * - The lowpass filter is disabled by default now
- *
- * 1996/9/25 Geert Uytterhoeven:
- * - Modularization
- *
- * 1998/6/10 Andreas Schwab:
- * - Converted to use sound_core
- *
- * 1999/12/28 Richard Zidlicky:
- * - Added support for Q40
- *
- * 2000/2/27 Geert Uytterhoeven:
- * - Clean up and split the code into 4 parts:
- * o dmasound_core: machine-independent code
- * o dmasound_atari: Atari TT and Falcon support
- * o dmasound_awacs: Apple PowerMac support
- * o dmasound_paula: Amiga support
- *
- * 2000/3/25 Geert Uytterhoeven:
- * - Integration of dmasound_q40
- * - Small clean ups
- *
- * 2001/01/26 [1.0] Iain Sandoe
- * - make /dev/sndstat show revision & edition info.
- * - since dmasound.mach.sq_setup() can fail on pmac
- * its type has been changed to int and the returns
- * are checked.
- * [1.1] - stop missing translations from being called.
- * 2001/02/08 [1.2] - remove unused translation tables & move machine-
- * specific tables to low-level.
- * - return correct info. for SNDCTL_DSP_GETFMTS.
- * [1.3] - implement SNDCTL_DSP_GETCAPS fully.
- * [1.4] - make /dev/sndstat text length usage deterministic.
- * - make /dev/sndstat call to low-level
- * dmasound.mach.state_info() pass max space to ll driver.
- * - tidy startup banners and output info.
- * [1.5] - tidy up a little (removed some unused #defines in
- * dmasound.h)
- * - fix up HAS_RECORD conditionalisation.
- * - add record code in places it is missing...
- * - change buf-sizes to bytes to allow < 1kb for pmac
- * if user param entry is < 256 the value is taken to
- * be in kb > 256 is taken to be in bytes.
- * - make default buff/frag params conditional on
- * machine to allow smaller values for pmac.
- * - made the ioctls, read & write comply with the OSS
- * rules on setting params.
- * - added parsing of _setup() params for record.
- * 2001/04/04 [1.6] - fix bug where sample rates higher than maximum were
- * being reported as OK.
- * - fix open() to return -EBUSY as per OSS doc. when
- * audio is in use - this is independent of O_NOBLOCK.
- * - fix bug where SNDCTL_DSP_POST was blocking.
- */
-
- /* Record capability notes 30/01/2001:
- * At present these observations apply only to pmac LL driver (the only one
- * that can do record, at present). However, if other LL drivers for machines
- * with record are added they may apply.
- *
- * The fragment parameters for the record and play channels are separate.
- * However, if the driver is opened O_RDWR there is no way (in the current OSS
- * API) to specify their values independently for the record and playback
- * channels. Since the only common factor between the input & output is the
- * sample rate (on pmac) it should be possible to open /dev/dspX O_WRONLY and
- * /dev/dspY O_RDONLY. The input & output channels could then have different
- * characteristics (other than the first that sets sample rate claiming the
- * right to set it for ever). As it stands, the format, channels, number of
- * bits & sample rate are assumed to be common. In the future perhaps these
- * should be the responsibility of the LL driver - and then if a card really
- * does not share items between record & playback they can be specified
- * separately.
-*/
-
-/* Thread-safeness of shared_resources notes: 31/01/2001
- * If the user opens O_RDWR and then splits record & play between two threads
- * both of which inherit the fd - and then starts changing things from both
- * - we will have difficulty telling.
- *
- * It's bad application coding - but ...
- * TODO: think about how to sort this out... without bogging everything down in
- * semaphores.
- *
- * Similarly, the OSS spec says "all changes to parameters must be between
- * open() and the first read() or write(). - and a bit later on (by
- * implication) "between SNDCTL_DSP_RESET and the first read() or write() after
- * it". If the app is multi-threaded and this rule is broken between threads
- * we will have trouble spotting it - and the fault will be rather obscure :-(
- *
- * We will try and put out at least a kmsg if we see it happen... but I think
- * it will be quite hard to trap it with an -EXXX return... because we can't
- * see the fault until after the damage is done.
-*/
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/sound.h>
-#include <linux/init.h>
-#include <linux/soundcard.h>
-#include <linux/poll.h>
-#include <linux/mutex.h>
-
-#include <asm/uaccess.h>
-
-#include "dmasound.h"
-
-#define DMASOUND_CORE_REVISION 1
-#define DMASOUND_CORE_EDITION 6
-
- /*
- * Declarations
- */
-
-static DEFINE_MUTEX(dmasound_core_mutex);
-int dmasound_catchRadius = 0;
-module_param(dmasound_catchRadius, int, 0);
-
-static unsigned int numWriteBufs = DEFAULT_N_BUFFERS;
-module_param(numWriteBufs, int, 0);
-static unsigned int writeBufSize = DEFAULT_BUFF_SIZE ; /* in bytes */
-module_param(writeBufSize, int, 0);
-
-MODULE_LICENSE("GPL");
-
-#ifdef MODULE
-static int sq_unit = -1;
-static int mixer_unit = -1;
-static int state_unit = -1;
-static int irq_installed;
-#endif /* MODULE */
-
-/* control over who can modify resources shared between play/record */
-static fmode_t shared_resource_owner;
-static int shared_resources_initialised;
-
- /*
- * Mid level stuff
- */
-
-struct sound_settings dmasound = {
- .lock = __SPIN_LOCK_UNLOCKED(dmasound.lock)
-};
-
-static inline void sound_silence(void)
-{
- dmasound.mach.silence(); /* _MUST_ stop DMA */
-}
-
-static inline int sound_set_format(int format)
-{
- return dmasound.mach.setFormat(format);
-}
-
-
-static int sound_set_speed(int speed)
-{
- if (speed < 0)
- return dmasound.soft.speed;
-
- /* trap out-of-range speed settings.
- at present we allow (arbitrarily) low rates - using soft
- up-conversion - but we can't allow > max because there is
- no soft down-conversion.
- */
- if (dmasound.mach.max_dsp_speed &&
- (speed > dmasound.mach.max_dsp_speed))
- speed = dmasound.mach.max_dsp_speed ;
-
- dmasound.soft.speed = speed;
-
- if (dmasound.minDev == SND_DEV_DSP)
- dmasound.dsp.speed = dmasound.soft.speed;
-
- return dmasound.soft.speed;
-}
-
-static int sound_set_stereo(int stereo)
-{
- if (stereo < 0)
- return dmasound.soft.stereo;
-
- stereo = !!stereo; /* should be 0 or 1 now */
-
- dmasound.soft.stereo = stereo;
- if (dmasound.minDev == SND_DEV_DSP)
- dmasound.dsp.stereo = stereo;
-
- return stereo;
-}
-
-static ssize_t sound_copy_translate(TRANS *trans, const u_char __user *userPtr,
- size_t userCount, u_char frame[],
- ssize_t *frameUsed, ssize_t frameLeft)
-{
- ssize_t (*ct_func)(const u_char __user *, size_t, u_char *, ssize_t *, ssize_t);
-
- switch (dmasound.soft.format) {
- case AFMT_MU_LAW:
- ct_func = trans->ct_ulaw;
- break;
- case AFMT_A_LAW:
- ct_func = trans->ct_alaw;
- break;
- case AFMT_S8:
- ct_func = trans->ct_s8;
- break;
- case AFMT_U8:
- ct_func = trans->ct_u8;
- break;
- case AFMT_S16_BE:
- ct_func = trans->ct_s16be;
- break;
- case AFMT_U16_BE:
- ct_func = trans->ct_u16be;
- break;
- case AFMT_S16_LE:
- ct_func = trans->ct_s16le;
- break;
- case AFMT_U16_LE:
- ct_func = trans->ct_u16le;
- break;
- default:
- return 0;
- }
- /* if the user has requested a non-existent translation don't try
- to call it but just return 0 bytes moved
- */
- if (ct_func)
- return ct_func(userPtr, userCount, frame, frameUsed, frameLeft);
- return 0;
-}
-
- /*
- * /dev/mixer abstraction
- */
-
-static struct {
- int busy;
- int modify_counter;
-} mixer;
-
-static int mixer_open(struct inode *inode, struct file *file)
-{
- mutex_lock(&dmasound_core_mutex);
- if (!try_module_get(dmasound.mach.owner)) {
- mutex_unlock(&dmasound_core_mutex);
- return -ENODEV;
- }
- mixer.busy = 1;
- mutex_unlock(&dmasound_core_mutex);
- return 0;
-}
-
-static int mixer_release(struct inode *inode, struct file *file)
-{
- mutex_lock(&dmasound_core_mutex);
- mixer.busy = 0;
- module_put(dmasound.mach.owner);
- mutex_unlock(&dmasound_core_mutex);
- return 0;
-}
-
-static int mixer_ioctl(struct file *file, u_int cmd, u_long arg)
-{
- if (_SIOC_DIR(cmd) & _SIOC_WRITE)
- mixer.modify_counter++;
- switch (cmd) {
- case OSS_GETVERSION:
- return IOCTL_OUT(arg, SOUND_VERSION);
- case SOUND_MIXER_INFO:
- {
- mixer_info info;
- memset(&info, 0, sizeof(info));
- strlcpy(info.id, dmasound.mach.name2, sizeof(info.id));
- strlcpy(info.name, dmasound.mach.name2, sizeof(info.name));
- info.modify_counter = mixer.modify_counter;
- if (copy_to_user((void __user *)arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- }
- }
- if (dmasound.mach.mixer_ioctl)
- return dmasound.mach.mixer_ioctl(cmd, arg);
- return -EINVAL;
-}
-
-static long mixer_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
-{
- int ret;
-
- mutex_lock(&dmasound_core_mutex);
- ret = mixer_ioctl(file, cmd, arg);
- mutex_unlock(&dmasound_core_mutex);
-
- return ret;
-}
-
-static const struct file_operations mixer_fops =
-{
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .unlocked_ioctl = mixer_unlocked_ioctl,
- .open = mixer_open,
- .release = mixer_release,
-};
-
-static void mixer_init(void)
-{
-#ifndef MODULE
- int mixer_unit;
-#endif
- mixer_unit = register_sound_mixer(&mixer_fops, -1);
- if (mixer_unit < 0)
- return;
-
- mixer.busy = 0;
- dmasound.treble = 0;
- dmasound.bass = 0;
- if (dmasound.mach.mixer_init)
- dmasound.mach.mixer_init();
-}
-
-
- /*
- * Sound queue stuff, the heart of the driver
- */
-
-struct sound_queue dmasound_write_sq;
-static void sq_reset_output(void) ;
-
-static int sq_allocate_buffers(struct sound_queue *sq, int num, int size)
-{
- int i;
-
- if (sq->buffers)
- return 0;
- sq->numBufs = num;
- sq->bufSize = size;
- sq->buffers = kmalloc (num * sizeof(char *), GFP_KERNEL);
- if (!sq->buffers)
- return -ENOMEM;
- for (i = 0; i < num; i++) {
- sq->buffers[i] = dmasound.mach.dma_alloc(size, GFP_KERNEL);
- if (!sq->buffers[i]) {
- while (i--)
- dmasound.mach.dma_free(sq->buffers[i], size);
- kfree(sq->buffers);
- sq->buffers = NULL;
- return -ENOMEM;
- }
- }
- return 0;
-}
-
-static void sq_release_buffers(struct sound_queue *sq)
-{
- int i;
-
- if (sq->buffers) {
- for (i = 0; i < sq->numBufs; i++)
- dmasound.mach.dma_free(sq->buffers[i], sq->bufSize);
- kfree(sq->buffers);
- sq->buffers = NULL;
- }
-}
-
-
-static int sq_setup(struct sound_queue *sq)
-{
- int (*setup_func)(void) = NULL;
- int hard_frame ;
-
- if (sq->locked) { /* are we already set? - and not changeable */
-#ifdef DEBUG_DMASOUND
-printk("dmasound_core: tried to sq_setup a locked queue\n") ;
-#endif
- return -EINVAL ;
- }
- sq->locked = 1 ; /* don't think we have a race prob. here _check_ */
-
- /* make sure that the parameters are set up
- This should have been done already...
- */
-
- dmasound.mach.init();
-
- /* OK. If the user has set fragment parameters explicitly, then we
- should leave them alone... as long as they are valid.
- Invalid user fragment params can occur if we allow the whole buffer
- to be used when the user requests the fragments sizes (with no soft
- x-lation) and then the user subsequently sets a soft x-lation that
- requires increased internal buffering.
-
- Othwerwise (if the user did not set them) OSS says that we should
- select frag params on the basis of 0.5 s output & 0.1 s input
- latency. (TODO. For now we will copy in the defaults.)
- */
-
- if (sq->user_frags <= 0) {
- sq->max_count = sq->numBufs ;
- sq->max_active = sq->numBufs ;
- sq->block_size = sq->bufSize;
- /* set up the user info */
- sq->user_frags = sq->numBufs ;
- sq->user_frag_size = sq->bufSize ;
- sq->user_frag_size *=
- (dmasound.soft.size * (dmasound.soft.stereo+1) ) ;
- sq->user_frag_size /=
- (dmasound.hard.size * (dmasound.hard.stereo+1) ) ;
- } else {
- /* work out requested block size */
- sq->block_size = sq->user_frag_size ;
- sq->block_size *=
- (dmasound.hard.size * (dmasound.hard.stereo+1) ) ;
- sq->block_size /=
- (dmasound.soft.size * (dmasound.soft.stereo+1) ) ;
- /* the user wants to write frag-size chunks */
- sq->block_size *= dmasound.hard.speed ;
- sq->block_size /= dmasound.soft.speed ;
- /* this only works for size values which are powers of 2 */
- hard_frame =
- (dmasound.hard.size * (dmasound.hard.stereo+1))/8 ;
- sq->block_size += (hard_frame - 1) ;
- sq->block_size &= ~(hard_frame - 1) ; /* make sure we are aligned */
- /* let's just check for obvious mistakes */
- if ( sq->block_size <= 0 || sq->block_size > sq->bufSize) {
-#ifdef DEBUG_DMASOUND
-printk("dmasound_core: invalid frag size (user set %d)\n", sq->user_frag_size) ;
-#endif
- sq->block_size = sq->bufSize ;
- }
- if ( sq->user_frags <= sq->numBufs ) {
- sq->max_count = sq->user_frags ;
- /* if user has set max_active - then use it */
- sq->max_active = (sq->max_active <= sq->max_count) ?
- sq->max_active : sq->max_count ;
- } else {
-#ifdef DEBUG_DMASOUND
-printk("dmasound_core: invalid frag count (user set %d)\n", sq->user_frags) ;
-#endif
- sq->max_count =
- sq->max_active = sq->numBufs ;
- }
- }
- sq->front = sq->count = sq->rear_size = 0;
- sq->syncing = 0;
- sq->active = 0;
-
- if (sq == &write_sq) {
- sq->rear = -1;
- setup_func = dmasound.mach.write_sq_setup;
- }
- if (setup_func)
- return setup_func();
- return 0 ;
-}
-
-static inline void sq_play(void)
-{
- dmasound.mach.play();
-}
-
-static ssize_t sq_write(struct file *file, const char __user *src, size_t uLeft,
- loff_t *ppos)
-{
- ssize_t uWritten = 0;
- u_char *dest;
- ssize_t uUsed = 0, bUsed, bLeft;
- unsigned long flags ;
-
- /* ++TeSche: Is something like this necessary?
- * Hey, that's an honest question! Or does any other part of the
- * filesystem already checks this situation? I really don't know.
- */
- if (uLeft == 0)
- return 0;
-
- /* implement any changes we have made to the soft/hard params.
- this is not satisfactory really, all we have done up to now is to
- say what we would like - there hasn't been any real checking of capability
- */
-
- if (shared_resources_initialised == 0) {
- dmasound.mach.init() ;
- shared_resources_initialised = 1 ;
- }
-
- /* set up the sq if it is not already done. This may seem a dumb place
- to do it - but it is what OSS requires. It means that write() can
- return memory allocation errors. To avoid this possibility use the
- GETBLKSIZE or GETOSPACE ioctls (after you've fiddled with all the
- params you want to change) - these ioctls also force the setup.
- */
-
- if (write_sq.locked == 0) {
- if ((uWritten = sq_setup(&write_sq)) < 0) return uWritten ;
- uWritten = 0 ;
- }
-
-/* FIXME: I think that this may be the wrong behaviour when we get strapped
- for time and the cpu is close to being (or actually) behind in sending data.
- - because we've lost the time that the N samples, already in the buffer,
- would have given us to get here with the next lot from the user.
-*/
- /* The interrupt doesn't start to play the last, incomplete frame.
- * Thus we can append to it without disabling the interrupts! (Note
- * also that write_sq.rear isn't affected by the interrupt.)
- */
-
- /* as of 1.6 this behaviour changes if SNDCTL_DSP_POST has been issued:
- this will mimic the behaviour of syncing and allow the sq_play() to
- queue a partial fragment. Since sq_play() may/will be called from
- the IRQ handler - at least on Pmac we have to deal with it.
- The strategy - possibly not optimum - is to kill _POST status if we
- get here. This seems, at least, reasonable - in the sense that POST
- is supposed to indicate that we might not write before the queue
- is drained - and if we get here in time then it does not apply.
- */
-
- spin_lock_irqsave(&dmasound.lock, flags);
- write_sq.syncing &= ~2 ; /* take out POST status */
- spin_unlock_irqrestore(&dmasound.lock, flags);
-
- if (write_sq.count > 0 &&
- (bLeft = write_sq.block_size-write_sq.rear_size) > 0) {
- dest = write_sq.buffers[write_sq.rear];
- bUsed = write_sq.rear_size;
- uUsed = sound_copy_translate(dmasound.trans_write, src, uLeft,
- dest, &bUsed, bLeft);
- if (uUsed <= 0)
- return uUsed;
- src += uUsed;
- uWritten += uUsed;
- uLeft = (uUsed <= uLeft) ? (uLeft - uUsed) : 0 ; /* paranoia */
- write_sq.rear_size = bUsed;
- }
-
- while (uLeft) {
- while (write_sq.count >= write_sq.max_active) {
- sq_play();
- if (write_sq.non_blocking)
- return uWritten > 0 ? uWritten : -EAGAIN;
- SLEEP(write_sq.action_queue);
- if (signal_pending(current))
- return uWritten > 0 ? uWritten : -EINTR;
- }
-
- /* Here, we can avoid disabling the interrupt by first
- * copying and translating the data, and then updating
- * the write_sq variables. Until this is done, the interrupt
- * won't see the new frame and we can work on it
- * undisturbed.
- */
-
- dest = write_sq.buffers[(write_sq.rear+1) % write_sq.max_count];
- bUsed = 0;
- bLeft = write_sq.block_size;
- uUsed = sound_copy_translate(dmasound.trans_write, src, uLeft,
- dest, &bUsed, bLeft);
- if (uUsed <= 0)
- break;
- src += uUsed;
- uWritten += uUsed;
- uLeft = (uUsed <= uLeft) ? (uLeft - uUsed) : 0 ; /* paranoia */
- if (bUsed) {
- write_sq.rear = (write_sq.rear+1) % write_sq.max_count;
- write_sq.rear_size = bUsed;
- write_sq.count++;
- }
- } /* uUsed may have been 0 */
-
- sq_play();
-
- return uUsed < 0? uUsed: uWritten;
-}
-
-static unsigned int sq_poll(struct file *file, struct poll_table_struct *wait)
-{
- unsigned int mask = 0;
- int retVal;
-
- if (write_sq.locked == 0) {
- if ((retVal = sq_setup(&write_sq)) < 0)
- return retVal;
- return 0;
- }
- if (file->f_mode & FMODE_WRITE )
- poll_wait(file, &write_sq.action_queue, wait);
- if (file->f_mode & FMODE_WRITE)
- if (write_sq.count < write_sq.max_active || write_sq.block_size - write_sq.rear_size > 0)
- mask |= POLLOUT | POLLWRNORM;
- return mask;
-
-}
-
-static inline void sq_init_waitqueue(struct sound_queue *sq)
-{
- init_waitqueue_head(&sq->action_queue);
- init_waitqueue_head(&sq->open_queue);
- init_waitqueue_head(&sq->sync_queue);
- sq->busy = 0;
-}
-
-#if 0 /* blocking open() */
-static inline void sq_wake_up(struct sound_queue *sq, struct file *file,
- fmode_t mode)
-{
- if (file->f_mode & mode) {
- sq->busy = 0; /* CHECK: IS THIS OK??? */
- WAKE_UP(sq->open_queue);
- }
-}
-#endif
-
-static int sq_open2(struct sound_queue *sq, struct file *file, fmode_t mode,
- int numbufs, int bufsize)
-{
- int rc = 0;
-
- if (file->f_mode & mode) {
- if (sq->busy) {
-#if 0 /* blocking open() */
- rc = -EBUSY;
- if (file->f_flags & O_NONBLOCK)
- return rc;
- rc = -EINTR;
- while (sq->busy) {
- SLEEP(sq->open_queue);
- if (signal_pending(current))
- return rc;
- }
- rc = 0;
-#else
- /* OSS manual says we will return EBUSY regardless
- of O_NOBLOCK.
- */
- return -EBUSY ;
-#endif
- }
- sq->busy = 1; /* Let's play spot-the-race-condition */
-
- /* allocate the default number & size of buffers.
- (i.e. specified in _setup() or as module params)
- can't be changed at the moment - but _could_ be perhaps
- in the setfragments ioctl.
- */
- if (( rc = sq_allocate_buffers(sq, numbufs, bufsize))) {
-#if 0 /* blocking open() */
- sq_wake_up(sq, file, mode);
-#else
- sq->busy = 0 ;
-#endif
- return rc;
- }
-
- sq->non_blocking = file->f_flags & O_NONBLOCK;
- }
- return rc;
-}
-
-#define write_sq_init_waitqueue() sq_init_waitqueue(&write_sq)
-#if 0 /* blocking open() */
-#define write_sq_wake_up(file) sq_wake_up(&write_sq, file, FMODE_WRITE)
-#endif
-#define write_sq_release_buffers() sq_release_buffers(&write_sq)
-#define write_sq_open(file) \
- sq_open2(&write_sq, file, FMODE_WRITE, numWriteBufs, writeBufSize )
-
-static int sq_open(struct inode *inode, struct file *file)
-{
- int rc;
-
- mutex_lock(&dmasound_core_mutex);
- if (!try_module_get(dmasound.mach.owner)) {
- mutex_unlock(&dmasound_core_mutex);
- return -ENODEV;
- }
-
- rc = write_sq_open(file); /* checks the f_mode */
- if (rc)
- goto out;
- if (file->f_mode & FMODE_READ) {
- /* TODO: if O_RDWR, release any resources grabbed by write part */
- rc = -ENXIO ; /* I think this is what is required by open(2) */
- goto out;
- }
-
- if (dmasound.mach.sq_open)
- dmasound.mach.sq_open(file->f_mode);
-
- /* CHECK whether this is sensible - in the case that dsp0 could be opened
- O_RDONLY and dsp1 could be opened O_WRONLY
- */
-
- dmasound.minDev = iminor(inode) & 0x0f;
-
- /* OK. - we should make some attempt at consistency. At least the H'ware
- options should be set with a valid mode. We will make it that the LL
- driver must supply defaults for hard & soft params.
- */
-
- if (shared_resource_owner == 0) {
- /* you can make this AFMT_U8/mono/8K if you want to mimic old
- OSS behaviour - while we still have soft translations ;-) */
- dmasound.soft = dmasound.mach.default_soft ;
- dmasound.dsp = dmasound.mach.default_soft ;
- dmasound.hard = dmasound.mach.default_hard ;
- }
-
-#ifndef DMASOUND_STRICT_OSS_COMPLIANCE
- /* none of the current LL drivers can actually do this "native" at the moment
- OSS does not really require us to supply /dev/audio if we can't do it.
- */
- if (dmasound.minDev == SND_DEV_AUDIO) {
- sound_set_speed(8000);
- sound_set_stereo(0);
- sound_set_format(AFMT_MU_LAW);
- }
-#endif
- mutex_unlock(&dmasound_core_mutex);
- return 0;
- out:
- module_put(dmasound.mach.owner);
- mutex_unlock(&dmasound_core_mutex);
- return rc;
-}
-
-static void sq_reset_output(void)
-{
- sound_silence(); /* this _must_ stop DMA, we might be about to lose the buffers */
- write_sq.active = 0;
- write_sq.count = 0;
- write_sq.rear_size = 0;
- /* write_sq.front = (write_sq.rear+1) % write_sq.max_count;*/
- write_sq.front = 0 ;
- write_sq.rear = -1 ; /* same as for set-up */
-
- /* OK - we can unlock the parameters and fragment settings */
- write_sq.locked = 0 ;
- write_sq.user_frags = 0 ;
- write_sq.user_frag_size = 0 ;
-}
-
-static void sq_reset(void)
-{
- sq_reset_output() ;
- /* we could consider resetting the shared_resources_owner here... but I
- think it is probably still rather non-obvious to application writer
- */
-
- /* we release everything else though */
- shared_resources_initialised = 0 ;
-}
-
-static int sq_fsync(struct file *filp, struct dentry *dentry)
-{
- int rc = 0;
- int timeout = 5;
-
- write_sq.syncing |= 1;
- sq_play(); /* there may be an incomplete frame waiting */
-
- while (write_sq.active) {
- SLEEP(write_sq.sync_queue);
- if (signal_pending(current)) {
- /* While waiting for audio output to drain, an
- * interrupt occurred. Stop audio output immediately
- * and clear the queue. */
- sq_reset_output();
- rc = -EINTR;
- break;
- }
- if (!--timeout) {
- printk(KERN_WARNING "dmasound: Timeout draining output\n");
- sq_reset_output();
- rc = -EIO;
- break;
- }
- }
-
- /* flag no sync regardless of whether we had a DSP_POST or not */
- write_sq.syncing = 0 ;
- return rc;
-}
-
-static int sq_release(struct inode *inode, struct file *file)
-{
- int rc = 0;
-
- mutex_lock(&dmasound_core_mutex);
-
- if (file->f_mode & FMODE_WRITE) {
- if (write_sq.busy)
- rc = sq_fsync(file, file->f_path.dentry);
-
- sq_reset_output() ; /* make sure dma is stopped and all is quiet */
- write_sq_release_buffers();
- write_sq.busy = 0;
- }
-
- if (file->f_mode & shared_resource_owner) { /* it's us that has them */
- shared_resource_owner = 0 ;
- shared_resources_initialised = 0 ;
- dmasound.hard = dmasound.mach.default_hard ;
- }
-
- module_put(dmasound.mach.owner);
-
-#if 0 /* blocking open() */
- /* Wake up a process waiting for the queue being released.
- * Note: There may be several processes waiting for a call
- * to open() returning. */
-
- /* Iain: hmm I don't understand this next comment ... */
- /* There is probably a DOS atack here. They change the mode flag. */
- /* XXX add check here,*/
- read_sq_wake_up(file); /* checks f_mode */
- write_sq_wake_up(file); /* checks f_mode */
-#endif /* blocking open() */
-
- mutex_unlock(&dmasound_core_mutex);
-
- return rc;
-}
-
-/* here we see if we have a right to modify format, channels, size and so on
- if no-one else has claimed it already then we do...
-
- TODO: We might change this to mask O_RDWR such that only one or the other channel
- is the owner - if we have problems.
-*/
-
-static int shared_resources_are_mine(fmode_t md)
-{
- if (shared_resource_owner)
- return (shared_resource_owner & md) != 0;
- else {
- shared_resource_owner = md ;
- return 1 ;
- }
-}
-
-/* if either queue is locked we must deny the right to change shared params
-*/
-
-static int queues_are_quiescent(void)
-{
- if (write_sq.locked)
- return 0 ;
- return 1 ;
-}
-
-/* check and set a queue's fragments per user's wishes...
- we will check against the pre-defined literals and the actual sizes.
- This is a bit fraught - because soft translations can mess with our
- buffer requirements *after* this call - OSS says "call setfrags first"
-*/
-
-/* It is possible to replace all the -EINVAL returns with an override that
- just puts the allowable value in. This may be what many OSS apps require
-*/
-
-static int set_queue_frags(struct sound_queue *sq, int bufs, int size)
-{
- if (sq->locked) {
-#ifdef DEBUG_DMASOUND
-printk("dmasound_core: tried to set_queue_frags on a locked queue\n") ;
-#endif
- return -EINVAL ;
- }
-
- if ((size < MIN_FRAG_SIZE) || (size > MAX_FRAG_SIZE))
- return -EINVAL ;
- size = (1<<size) ; /* now in bytes */
- if (size > sq->bufSize)
- return -EINVAL ; /* this might still not work */
-
- if (bufs <= 0)
- return -EINVAL ;
- if (bufs > sq->numBufs) /* the user is allowed say "don't care" with 0x7fff */
- bufs = sq->numBufs ;
-
- /* there is, currently, no way to specify max_active separately
- from max_count. This could be a LL driver issue - I guess
- if there is a requirement for these values to be different then
- we will have to pass that info. up to this level.
- */
- sq->user_frags =
- sq->max_active = bufs ;
- sq->user_frag_size = size ;
-
- return 0 ;
-}
-
-static int sq_ioctl(struct file *file, u_int cmd, u_long arg)
-{
- int val, result;
- u_long fmt;
- int data;
- int size, nbufs;
- audio_buf_info info;
-
- switch (cmd) {
- case SNDCTL_DSP_RESET:
- sq_reset();
- return 0;
- break ;
- case SNDCTL_DSP_GETFMTS:
- fmt = dmasound.mach.hardware_afmts ; /* this is what OSS says.. */
- return IOCTL_OUT(arg, fmt);
- break ;
- case SNDCTL_DSP_GETBLKSIZE:
- /* this should tell the caller about bytes that the app can
- read/write - the app doesn't care about our internal buffers.
- We force sq_setup() here as per OSS 1.1 (which should
- compute the values necessary).
- Since there is no mechanism to specify read/write separately, for
- fds opened O_RDWR, the write_sq values will, arbitrarily, overwrite
- the read_sq ones.
- */
- size = 0 ;
- if (file->f_mode & FMODE_WRITE) {
- if ( !write_sq.locked )
- sq_setup(&write_sq) ;
- size = write_sq.user_frag_size ;
- }
- return IOCTL_OUT(arg, size);
- break ;
- case SNDCTL_DSP_POST:
- /* all we are going to do is to tell the LL that any
- partial frags can be queued for output.
- The LL will have to clear this flag when last output
- is queued.
- */
- write_sq.syncing |= 0x2 ;
- sq_play() ;
- return 0 ;
- case SNDCTL_DSP_SYNC:
- /* This call, effectively, has the same behaviour as SNDCTL_DSP_RESET
- except that it waits for output to finish before resetting
- everything - read, however, is killed immediately.
- */
- result = 0 ;
- if (file->f_mode & FMODE_WRITE) {
- result = sq_fsync(file, file->f_path.dentry);
- sq_reset_output() ;
- }
- /* if we are the shared resource owner then release them */
- if (file->f_mode & shared_resource_owner)
- shared_resources_initialised = 0 ;
- return result ;
- break ;
- case SOUND_PCM_READ_RATE:
- return IOCTL_OUT(arg, dmasound.soft.speed);
- case SNDCTL_DSP_SPEED:
- /* changing this on the fly will have weird effects on the sound.
- Where there are rate conversions implemented in soft form - it
- will cause the _ctx_xxx() functions to be substituted.
- However, there doesn't appear to be any reason to dis-allow it from
- a driver pov.
- */
- if (shared_resources_are_mine(file->f_mode)) {
- IOCTL_IN(arg, data);
- data = sound_set_speed(data) ;
- shared_resources_initialised = 0 ;
- return IOCTL_OUT(arg, data);
- } else
- return -EINVAL ;
- break ;
- /* OSS says these next 4 actions are undefined when the device is
- busy/active - we will just return -EINVAL.
- To be allowed to change one - (a) you have to own the right
- (b) the queue(s) must be quiescent
- */
- case SNDCTL_DSP_STEREO:
- if (shared_resources_are_mine(file->f_mode) &&
- queues_are_quiescent()) {
- IOCTL_IN(arg, data);
- shared_resources_initialised = 0 ;
- return IOCTL_OUT(arg, sound_set_stereo(data));
- } else
- return -EINVAL ;
- break ;
- case SOUND_PCM_WRITE_CHANNELS:
- if (shared_resources_are_mine(file->f_mode) &&
- queues_are_quiescent()) {
- IOCTL_IN(arg, data);
- /* the user might ask for 20 channels, we will return 1 or 2 */
- shared_resources_initialised = 0 ;
- return IOCTL_OUT(arg, sound_set_stereo(data-1)+1);
- } else
- return -EINVAL ;
- break ;
- case SNDCTL_DSP_SETFMT:
- if (shared_resources_are_mine(file->f_mode) &&
- queues_are_quiescent()) {
- int format;
- IOCTL_IN(arg, data);
- shared_resources_initialised = 0 ;
- format = sound_set_format(data);
- result = IOCTL_OUT(arg, format);
- if (result < 0)
- return result;
- if (format != data && data != AFMT_QUERY)
- return -EINVAL;
- return 0;
- } else
- return -EINVAL ;
- case SNDCTL_DSP_SUBDIVIDE:
- return -EINVAL ;
- case SNDCTL_DSP_SETFRAGMENT:
- /* we can do this independently for the two queues - with the
- proviso that for fds opened O_RDWR we cannot separate the
- actions and both queues will be set per the last call.
- NOTE: this does *NOT* actually set the queue up - merely
- registers our intentions.
- */
- IOCTL_IN(arg, data);
- result = 0 ;
- nbufs = (data >> 16) & 0x7fff ; /* 0x7fff is 'use maximum' */
- size = data & 0xffff;
- if (file->f_mode & FMODE_WRITE) {
- result = set_queue_frags(&write_sq, nbufs, size) ;
- if (result)
- return result ;
- }
- /* NOTE: this return value is irrelevant - OSS specifically says that
- the value is 'random' and that the user _must_ check the actual
- frags values using SNDCTL_DSP_GETBLKSIZE or similar */
- return IOCTL_OUT(arg, data);
- break ;
- case SNDCTL_DSP_GETOSPACE:
- /*
- */
- if (file->f_mode & FMODE_WRITE) {
- if ( !write_sq.locked )
- sq_setup(&write_sq) ;
- info.fragments = write_sq.max_active - write_sq.count;
- info.fragstotal = write_sq.max_active;
- info.fragsize = write_sq.user_frag_size;
- info.bytes = info.fragments * info.fragsize;
- if (copy_to_user((void __user *)arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- } else
- return -EINVAL ;
- break ;
- case SNDCTL_DSP_GETCAPS:
- val = dmasound.mach.capabilities & 0xffffff00;
- return IOCTL_OUT(arg,val);
-
- default:
- return mixer_ioctl(file, cmd, arg);
- }
- return -EINVAL;
-}
-
-static long sq_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
-{
- int ret;
-
- mutex_lock(&dmasound_core_mutex);
- ret = sq_ioctl(file, cmd, arg);
- mutex_unlock(&dmasound_core_mutex);
-
- return ret;
-}
-
-static const struct file_operations sq_fops =
-{
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .write = sq_write,
- .poll = sq_poll,
- .unlocked_ioctl = sq_unlocked_ioctl,
- .open = sq_open,
- .release = sq_release,
-};
-
-static int sq_init(void)
-{
- const struct file_operations *fops = &sq_fops;
-#ifndef MODULE
- int sq_unit;
-#endif
-
- sq_unit = register_sound_dsp(fops, -1);
- if (sq_unit < 0) {
- printk(KERN_ERR "dmasound_core: couldn't register fops\n") ;
- return sq_unit ;
- }
-
- write_sq_init_waitqueue();
-
- /* These parameters will be restored for every clean open()
- * in the case of multiple open()s (e.g. dsp0 & dsp1) they
- * will be set so long as the shared resources have no owner.
- */
-
- if (shared_resource_owner == 0) {
- dmasound.soft = dmasound.mach.default_soft ;
- dmasound.hard = dmasound.mach.default_hard ;
- dmasound.dsp = dmasound.mach.default_soft ;
- shared_resources_initialised = 0 ;
- }
- return 0 ;
-}
-
-
- /*
- * /dev/sndstat
- */
-
-/* we allow more space for record-enabled because there are extra output lines.
- the number here must include the amount we are prepared to give to the low-level
- driver.
-*/
-
-#define STAT_BUFF_LEN 768
-
-/* this is how much space we will allow the low-level driver to use
- in the stat buffer. Currently, 2 * (80 character line + <NL>).
- We do not police this (it is up to the ll driver to be honest).
-*/
-
-#define LOW_LEVEL_STAT_ALLOC 162
-
-static struct {
- int busy;
- char buf[STAT_BUFF_LEN]; /* state.buf should not overflow! */
- int len, ptr;
-} state;
-
-/* publish this function for use by low-level code, if required */
-
-static char *get_afmt_string(int afmt)
-{
- switch(afmt) {
- case AFMT_MU_LAW:
- return "mu-law";
- break;
- case AFMT_A_LAW:
- return "A-law";
- break;
- case AFMT_U8:
- return "unsigned 8 bit";
- break;
- case AFMT_S8:
- return "signed 8 bit";
- break;
- case AFMT_S16_BE:
- return "signed 16 bit BE";
- break;
- case AFMT_U16_BE:
- return "unsigned 16 bit BE";
- break;
- case AFMT_S16_LE:
- return "signed 16 bit LE";
- break;
- case AFMT_U16_LE:
- return "unsigned 16 bit LE";
- break;
- case 0:
- return "format not set" ;
- break ;
- default:
- break ;
- }
- return "ERROR: Unsupported AFMT_XXXX code" ;
-}
-
-static int state_open(struct inode *inode, struct file *file)
-{
- char *buffer = state.buf;
- int len = 0;
- int ret;
-
- mutex_lock(&dmasound_core_mutex);
- ret = -EBUSY;
- if (state.busy)
- goto out;
-
- ret = -ENODEV;
- if (!try_module_get(dmasound.mach.owner))
- goto out;
-
- state.ptr = 0;
- state.busy = 1;
-
- len += sprintf(buffer+len, "%sDMA sound driver rev %03d :\n",
- dmasound.mach.name, (DMASOUND_CORE_REVISION<<4) +
- ((dmasound.mach.version>>8) & 0x0f));
- len += sprintf(buffer+len,
- "Core driver edition %02d.%02d : %s driver edition %02d.%02d\n",
- DMASOUND_CORE_REVISION, DMASOUND_CORE_EDITION, dmasound.mach.name2,
- (dmasound.mach.version >> 8), (dmasound.mach.version & 0xff)) ;
-
- /* call the low-level module to fill in any stat info. that it has
- if present. Maximum buffer usage is specified.
- */
-
- if (dmasound.mach.state_info)
- len += dmasound.mach.state_info(buffer+len,
- (size_t) LOW_LEVEL_STAT_ALLOC) ;
-
- /* make usage of the state buffer as deterministic as poss.
- exceptional conditions could cause overrun - and this is flagged as
- a kernel error.
- */
-
- /* formats and settings */
-
- len += sprintf(buffer+len,"\t\t === Formats & settings ===\n") ;
- len += sprintf(buffer+len,"Parameter %20s%20s\n","soft","hard") ;
- len += sprintf(buffer+len,"Format :%20s%20s\n",
- get_afmt_string(dmasound.soft.format),
- get_afmt_string(dmasound.hard.format));
-
- len += sprintf(buffer+len,"Samp Rate:%14d s/sec%14d s/sec\n",
- dmasound.soft.speed, dmasound.hard.speed);
-
- len += sprintf(buffer+len,"Channels :%20s%20s\n",
- dmasound.soft.stereo ? "stereo" : "mono",
- dmasound.hard.stereo ? "stereo" : "mono" );
-
- /* sound queue status */
-
- len += sprintf(buffer+len,"\t\t === Sound Queue status ===\n");
- len += sprintf(buffer+len,"Allocated:%8s%6s\n","Buffers","Size") ;
- len += sprintf(buffer+len,"%9s:%8d%6d\n",
- "write", write_sq.numBufs, write_sq.bufSize) ;
- len += sprintf(buffer+len,
- "Current : MaxFrg FragSiz MaxAct Frnt Rear "
- "Cnt RrSize A B S L xruns\n") ;
- len += sprintf(buffer+len,"%9s:%7d%8d%7d%5d%5d%4d%7d%2d%2d%2d%2d%7d\n",
- "write", write_sq.max_count, write_sq.block_size,
- write_sq.max_active, write_sq.front, write_sq.rear,
- write_sq.count, write_sq.rear_size, write_sq.active,
- write_sq.busy, write_sq.syncing, write_sq.locked, write_sq.xruns) ;
-#ifdef DEBUG_DMASOUND
-printk("dmasound: stat buffer used %d bytes\n", len) ;
-#endif
-
- if (len >= STAT_BUFF_LEN)
- printk(KERN_ERR "dmasound_core: stat buffer overflowed!\n");
-
- state.len = len;
- ret = 0;
-out:
- mutex_unlock(&dmasound_core_mutex);
- return ret;
-}
-
-static int state_release(struct inode *inode, struct file *file)
-{
- mutex_lock(&dmasound_core_mutex);
- state.busy = 0;
- module_put(dmasound.mach.owner);
- mutex_unlock(&dmasound_core_mutex);
- return 0;
-}
-
-static ssize_t state_read(struct file *file, char __user *buf, size_t count,
- loff_t *ppos)
-{
- int n = state.len - state.ptr;
- if (n > count)
- n = count;
- if (n <= 0)
- return 0;
- if (copy_to_user(buf, &state.buf[state.ptr], n))
- return -EFAULT;
- state.ptr += n;
- return n;
-}
-
-static const struct file_operations state_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .read = state_read,
- .open = state_open,
- .release = state_release,
-};
-
-static int state_init(void)
-{
-#ifndef MODULE
- int state_unit;
-#endif
- state_unit = register_sound_special(&state_fops, SND_DEV_STATUS);
- if (state_unit < 0)
- return state_unit ;
- state.busy = 0;
- return 0 ;
-}
-
-
- /*
- * Config & Setup
- *
- * This function is called by _one_ chipset-specific driver
- */
-
-int dmasound_init(void)
-{
- int res ;
-#ifdef MODULE
- if (irq_installed)
- return -EBUSY;
-#endif
-
- /* Set up sound queue, /dev/audio and /dev/dsp. */
-
- /* Set default settings. */
- if ((res = sq_init()) < 0)
- return res ;
-
- /* Set up /dev/sndstat. */
- if ((res = state_init()) < 0)
- return res ;
-
- /* Set up /dev/mixer. */
- mixer_init();
-
- if (!dmasound.mach.irqinit()) {
- printk(KERN_ERR "DMA sound driver: Interrupt initialization failed\n");
- return -ENODEV;
- }
-#ifdef MODULE
- irq_installed = 1;
-#endif
-
- printk(KERN_INFO "%s DMA sound driver rev %03d installed\n",
- dmasound.mach.name, (DMASOUND_CORE_REVISION<<4) +
- ((dmasound.mach.version>>8) & 0x0f));
- printk(KERN_INFO
- "Core driver edition %02d.%02d : %s driver edition %02d.%02d\n",
- DMASOUND_CORE_REVISION, DMASOUND_CORE_EDITION, dmasound.mach.name2,
- (dmasound.mach.version >> 8), (dmasound.mach.version & 0xff)) ;
- printk(KERN_INFO "Write will use %4d fragments of %7d bytes as default\n",
- numWriteBufs, writeBufSize) ;
- return 0;
-}
-
-#ifdef MODULE
-
-void dmasound_deinit(void)
-{
- if (irq_installed) {
- sound_silence();
- dmasound.mach.irqcleanup();
- irq_installed = 0;
- }
-
- write_sq_release_buffers();
-
- if (mixer_unit >= 0)
- unregister_sound_mixer(mixer_unit);
- if (state_unit >= 0)
- unregister_sound_special(state_unit);
- if (sq_unit >= 0)
- unregister_sound_dsp(sq_unit);
-}
-
-#else /* !MODULE */
-
-static int dmasound_setup(char *str)
-{
- int ints[6], size;
-
- str = get_options(str, ARRAY_SIZE(ints), ints);
-
- /* check the bootstrap parameter for "dmasound=" */
-
- /* FIXME: other than in the most naive of cases there is no sense in these
- * buffers being other than powers of two. This is not checked yet.
- */
-
- switch (ints[0]) {
- case 3:
- if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS))
- printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
- else
- catchRadius = ints[3];
- /* fall through */
- case 2:
- if (ints[1] < MIN_BUFFERS)
- printk("dmasound_setup: invalid number of buffers, using default = %d\n", numWriteBufs);
- else
- numWriteBufs = ints[1];
- /* fall through */
- case 1:
- if ((size = ints[2]) < 256) /* check for small buffer specs */
- size <<= 10 ;
- if (size < MIN_BUFSIZE || size > MAX_BUFSIZE)
- printk("dmasound_setup: invalid write buffer size, using default = %d\n", writeBufSize);
- else
- writeBufSize = size;
- case 0:
- break;
- default:
- printk("dmasound_setup: invalid number of arguments\n");
- return 0;
- }
- return 1;
-}
-
-__setup("dmasound=", dmasound_setup);
-
-#endif /* !MODULE */
-
- /*
- * Conversion tables
- */
-
-#ifdef HAS_8BIT_TABLES
-/* 8 bit mu-law */
-
-char dmasound_ulaw2dma8[] = {
- -126, -122, -118, -114, -110, -106, -102, -98,
- -94, -90, -86, -82, -78, -74, -70, -66,
- -63, -61, -59, -57, -55, -53, -51, -49,
- -47, -45, -43, -41, -39, -37, -35, -33,
- -31, -30, -29, -28, -27, -26, -25, -24,
- -23, -22, -21, -20, -19, -18, -17, -16,
- -16, -15, -15, -14, -14, -13, -13, -12,
- -12, -11, -11, -10, -10, -9, -9, -8,
- -8, -8, -7, -7, -7, -7, -6, -6,
- -6, -6, -5, -5, -5, -5, -4, -4,
- -4, -4, -4, -4, -3, -3, -3, -3,
- -3, -3, -3, -3, -2, -2, -2, -2,
- -2, -2, -2, -2, -2, -2, -2, -2,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 0,
- 125, 121, 117, 113, 109, 105, 101, 97,
- 93, 89, 85, 81, 77, 73, 69, 65,
- 62, 60, 58, 56, 54, 52, 50, 48,
- 46, 44, 42, 40, 38, 36, 34, 32,
- 30, 29, 28, 27, 26, 25, 24, 23,
- 22, 21, 20, 19, 18, 17, 16, 15,
- 15, 14, 14, 13, 13, 12, 12, 11,
- 11, 10, 10, 9, 9, 8, 8, 7,
- 7, 7, 6, 6, 6, 6, 5, 5,
- 5, 5, 4, 4, 4, 4, 3, 3,
- 3, 3, 3, 3, 2, 2, 2, 2,
- 2, 2, 2, 2, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/* 8 bit A-law */
-
-char dmasound_alaw2dma8[] = {
- -22, -21, -24, -23, -18, -17, -20, -19,
- -30, -29, -32, -31, -26, -25, -28, -27,
- -11, -11, -12, -12, -9, -9, -10, -10,
- -15, -15, -16, -16, -13, -13, -14, -14,
- -86, -82, -94, -90, -70, -66, -78, -74,
- -118, -114, -126, -122, -102, -98, -110, -106,
- -43, -41, -47, -45, -35, -33, -39, -37,
- -59, -57, -63, -61, -51, -49, -55, -53,
- -2, -2, -2, -2, -2, -2, -2, -2,
- -2, -2, -2, -2, -2, -2, -2, -2,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -6, -6, -6, -6, -5, -5, -5, -5,
- -8, -8, -8, -8, -7, -7, -7, -7,
- -3, -3, -3, -3, -3, -3, -3, -3,
- -4, -4, -4, -4, -4, -4, -4, -4,
- 21, 20, 23, 22, 17, 16, 19, 18,
- 29, 28, 31, 30, 25, 24, 27, 26,
- 10, 10, 11, 11, 8, 8, 9, 9,
- 14, 14, 15, 15, 12, 12, 13, 13,
- 86, 82, 94, 90, 70, 66, 78, 74,
- 118, 114, 126, 122, 102, 98, 110, 106,
- 43, 41, 47, 45, 35, 33, 39, 37,
- 59, 57, 63, 61, 51, 49, 55, 53,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 5, 5, 5, 5, 4, 4, 4, 4,
- 7, 7, 7, 7, 6, 6, 6, 6,
- 2, 2, 2, 2, 2, 2, 2, 2,
- 3, 3, 3, 3, 3, 3, 3, 3
-};
-#endif /* HAS_8BIT_TABLES */
-
- /*
- * Visible symbols for modules
- */
-
-EXPORT_SYMBOL(dmasound);
-EXPORT_SYMBOL(dmasound_init);
-#ifdef MODULE
-EXPORT_SYMBOL(dmasound_deinit);
-#endif
-EXPORT_SYMBOL(dmasound_write_sq);
-EXPORT_SYMBOL(dmasound_catchRadius);
-#ifdef HAS_8BIT_TABLES
-EXPORT_SYMBOL(dmasound_ulaw2dma8);
-EXPORT_SYMBOL(dmasound_alaw2dma8);
-#endif
diff --git a/ANDROID_3.4.5/sound/oss/dmasound/dmasound_paula.c b/ANDROID_3.4.5/sound/oss/dmasound/dmasound_paula.c
deleted file mode 100644
index 87910e99..00000000
--- a/ANDROID_3.4.5/sound/oss/dmasound/dmasound_paula.c
+++ /dev/null
@@ -1,751 +0,0 @@
-/*
- * linux/sound/oss/dmasound/dmasound_paula.c
- *
- * Amiga `Paula' DMA Sound Driver
- *
- * See linux/sound/oss/dmasound/dmasound_core.c for copyright and credits
- * prior to 28/01/2001
- *
- * 28/01/2001 [0.1] Iain Sandoe
- * - added versioning
- * - put in and populated the hardware_afmts field.
- * [0.2] - put in SNDCTL_DSP_GETCAPS value.
- * [0.3] - put in constraint on state buffer usage.
- * [0.4] - put in default hard/soft settings
-*/
-
-
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/soundcard.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-
-#include <asm/uaccess.h>
-#include <asm/setup.h>
-#include <asm/amigahw.h>
-#include <asm/amigaints.h>
-#include <asm/machdep.h>
-
-#include "dmasound.h"
-
-#define DMASOUND_PAULA_REVISION 0
-#define DMASOUND_PAULA_EDITION 4
-
-#define custom amiga_custom
- /*
- * The minimum period for audio depends on htotal (for OCS/ECS/AGA)
- * (Imported from arch/m68k/amiga/amisound.c)
- */
-
-extern volatile u_short amiga_audio_min_period;
-
-
- /*
- * amiga_mksound() should be able to restore the period after beeping
- * (Imported from arch/m68k/amiga/amisound.c)
- */
-
-extern u_short amiga_audio_period;
-
-
- /*
- * Audio DMA masks
- */
-
-#define AMI_AUDIO_OFF (DMAF_AUD0 | DMAF_AUD1 | DMAF_AUD2 | DMAF_AUD3)
-#define AMI_AUDIO_8 (DMAF_SETCLR | DMAF_MASTER | DMAF_AUD0 | DMAF_AUD1)
-#define AMI_AUDIO_14 (AMI_AUDIO_8 | DMAF_AUD2 | DMAF_AUD3)
-
-
- /*
- * Helper pointers for 16(14)-bit sound
- */
-
-static int write_sq_block_size_half, write_sq_block_size_quarter;
-
-
-/*** Low level stuff *********************************************************/
-
-
-static void *AmiAlloc(unsigned int size, gfp_t flags);
-static void AmiFree(void *obj, unsigned int size);
-static int AmiIrqInit(void);
-#ifdef MODULE
-static void AmiIrqCleanUp(void);
-#endif
-static void AmiSilence(void);
-static void AmiInit(void);
-static int AmiSetFormat(int format);
-static int AmiSetVolume(int volume);
-static int AmiSetTreble(int treble);
-static void AmiPlayNextFrame(int index);
-static void AmiPlay(void);
-static irqreturn_t AmiInterrupt(int irq, void *dummy);
-
-#ifdef CONFIG_HEARTBEAT
-
- /*
- * Heartbeat interferes with sound since the 7 kHz low-pass filter and the
- * power LED are controlled by the same line.
- */
-
-static void (*saved_heartbeat)(int) = NULL;
-
-static inline void disable_heartbeat(void)
-{
- if (mach_heartbeat) {
- saved_heartbeat = mach_heartbeat;
- mach_heartbeat = NULL;
- }
- AmiSetTreble(dmasound.treble);
-}
-
-static inline void enable_heartbeat(void)
-{
- if (saved_heartbeat)
- mach_heartbeat = saved_heartbeat;
-}
-#else /* !CONFIG_HEARTBEAT */
-#define disable_heartbeat() do { } while (0)
-#define enable_heartbeat() do { } while (0)
-#endif /* !CONFIG_HEARTBEAT */
-
-
-/*** Mid level stuff *********************************************************/
-
-static void AmiMixerInit(void);
-static int AmiMixerIoctl(u_int cmd, u_long arg);
-static int AmiWriteSqSetup(void);
-static int AmiStateInfo(char *buffer, size_t space);
-
-
-/*** Translations ************************************************************/
-
-/* ++TeSche: radically changed for new expanding purposes...
- *
- * These two routines now deal with copying/expanding/translating the samples
- * from user space into our buffer at the right frequency. They take care about
- * how much data there's actually to read, how much buffer space there is and
- * to convert samples into the right frequency/encoding. They will only work on
- * complete samples so it may happen they leave some bytes in the input stream
- * if the user didn't write a multiple of the current sample size. They both
- * return the number of bytes they've used from both streams so you may detect
- * such a situation. Luckily all programs should be able to cope with that.
- *
- * I think I've optimized anything as far as one can do in plain C, all
- * variables should fit in registers and the loops are really short. There's
- * one loop for every possible situation. Writing a more generalized and thus
- * parameterized loop would only produce slower code. Feel free to optimize
- * this in assembler if you like. :)
- *
- * I think these routines belong here because they're not yet really hardware
- * independent, especially the fact that the Falcon can play 16bit samples
- * only in stereo is hardcoded in both of them!
- *
- * ++geert: split in even more functions (one per format)
- */
-
-
- /*
- * Native format
- */
-
-static ssize_t ami_ct_s8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed, ssize_t frameLeft)
-{
- ssize_t count, used;
-
- if (!dmasound.soft.stereo) {
- void *p = &frame[*frameUsed];
- count = min_t(unsigned long, userCount, frameLeft) & ~1;
- used = count;
- if (copy_from_user(p, userPtr, count))
- return -EFAULT;
- } else {
- u_char *left = &frame[*frameUsed>>1];
- u_char *right = left+write_sq_block_size_half;
- count = min_t(unsigned long, userCount, frameLeft)>>1 & ~1;
- used = count*2;
- while (count > 0) {
- if (get_user(*left++, userPtr++)
- || get_user(*right++, userPtr++))
- return -EFAULT;
- count--;
- }
- }
- *frameUsed += used;
- return used;
-}
-
-
- /*
- * Copy and convert 8 bit data
- */
-
-#define GENERATE_AMI_CT8(funcname, convsample) \
-static ssize_t funcname(const u_char __user *userPtr, size_t userCount, \
- u_char frame[], ssize_t *frameUsed, \
- ssize_t frameLeft) \
-{ \
- ssize_t count, used; \
- \
- if (!dmasound.soft.stereo) { \
- u_char *p = &frame[*frameUsed]; \
- count = min_t(size_t, userCount, frameLeft) & ~1; \
- used = count; \
- while (count > 0) { \
- u_char data; \
- if (get_user(data, userPtr++)) \
- return -EFAULT; \
- *p++ = convsample(data); \
- count--; \
- } \
- } else { \
- u_char *left = &frame[*frameUsed>>1]; \
- u_char *right = left+write_sq_block_size_half; \
- count = min_t(size_t, userCount, frameLeft)>>1 & ~1; \
- used = count*2; \
- while (count > 0) { \
- u_char data; \
- if (get_user(data, userPtr++)) \
- return -EFAULT; \
- *left++ = convsample(data); \
- if (get_user(data, userPtr++)) \
- return -EFAULT; \
- *right++ = convsample(data); \
- count--; \
- } \
- } \
- *frameUsed += used; \
- return used; \
-}
-
-#define AMI_CT_ULAW(x) (dmasound_ulaw2dma8[(x)])
-#define AMI_CT_ALAW(x) (dmasound_alaw2dma8[(x)])
-#define AMI_CT_U8(x) ((x) ^ 0x80)
-
-GENERATE_AMI_CT8(ami_ct_ulaw, AMI_CT_ULAW)
-GENERATE_AMI_CT8(ami_ct_alaw, AMI_CT_ALAW)
-GENERATE_AMI_CT8(ami_ct_u8, AMI_CT_U8)
-
-
- /*
- * Copy and convert 16 bit data
- */
-
-#define GENERATE_AMI_CT_16(funcname, convsample) \
-static ssize_t funcname(const u_char __user *userPtr, size_t userCount, \
- u_char frame[], ssize_t *frameUsed, \
- ssize_t frameLeft) \
-{ \
- const u_short __user *ptr = (const u_short __user *)userPtr; \
- ssize_t count, used; \
- u_short data; \
- \
- if (!dmasound.soft.stereo) { \
- u_char *high = &frame[*frameUsed>>1]; \
- u_char *low = high+write_sq_block_size_half; \
- count = min_t(size_t, userCount, frameLeft)>>1 & ~1; \
- used = count*2; \
- while (count > 0) { \
- if (get_user(data, ptr++)) \
- return -EFAULT; \
- data = convsample(data); \
- *high++ = data>>8; \
- *low++ = (data>>2) & 0x3f; \
- count--; \
- } \
- } else { \
- u_char *lefth = &frame[*frameUsed>>2]; \
- u_char *leftl = lefth+write_sq_block_size_quarter; \
- u_char *righth = lefth+write_sq_block_size_half; \
- u_char *rightl = righth+write_sq_block_size_quarter; \
- count = min_t(size_t, userCount, frameLeft)>>2 & ~1; \
- used = count*4; \
- while (count > 0) { \
- if (get_user(data, ptr++)) \
- return -EFAULT; \
- data = convsample(data); \
- *lefth++ = data>>8; \
- *leftl++ = (data>>2) & 0x3f; \
- if (get_user(data, ptr++)) \
- return -EFAULT; \
- data = convsample(data); \
- *righth++ = data>>8; \
- *rightl++ = (data>>2) & 0x3f; \
- count--; \
- } \
- } \
- *frameUsed += used; \
- return used; \
-}
-
-#define AMI_CT_S16BE(x) (x)
-#define AMI_CT_U16BE(x) ((x) ^ 0x8000)
-#define AMI_CT_S16LE(x) (le2be16((x)))
-#define AMI_CT_U16LE(x) (le2be16((x)) ^ 0x8000)
-
-GENERATE_AMI_CT_16(ami_ct_s16be, AMI_CT_S16BE)
-GENERATE_AMI_CT_16(ami_ct_u16be, AMI_CT_U16BE)
-GENERATE_AMI_CT_16(ami_ct_s16le, AMI_CT_S16LE)
-GENERATE_AMI_CT_16(ami_ct_u16le, AMI_CT_U16LE)
-
-
-static TRANS transAmiga = {
- .ct_ulaw = ami_ct_ulaw,
- .ct_alaw = ami_ct_alaw,
- .ct_s8 = ami_ct_s8,
- .ct_u8 = ami_ct_u8,
- .ct_s16be = ami_ct_s16be,
- .ct_u16be = ami_ct_u16be,
- .ct_s16le = ami_ct_s16le,
- .ct_u16le = ami_ct_u16le,
-};
-
-/*** Low level stuff *********************************************************/
-
-static inline void StopDMA(void)
-{
- custom.aud[0].audvol = custom.aud[1].audvol = 0;
- custom.aud[2].audvol = custom.aud[3].audvol = 0;
- custom.dmacon = AMI_AUDIO_OFF;
- enable_heartbeat();
-}
-
-static void *AmiAlloc(unsigned int size, gfp_t flags)
-{
- return amiga_chip_alloc((long)size, "dmasound [Paula]");
-}
-
-static void AmiFree(void *obj, unsigned int size)
-{
- amiga_chip_free (obj);
-}
-
-static int __init AmiIrqInit(void)
-{
- /* turn off DMA for audio channels */
- StopDMA();
-
- /* Register interrupt handler. */
- if (request_irq(IRQ_AMIGA_AUD0, AmiInterrupt, 0, "DMA sound",
- AmiInterrupt))
- return 0;
- return 1;
-}
-
-#ifdef MODULE
-static void AmiIrqCleanUp(void)
-{
- /* turn off DMA for audio channels */
- StopDMA();
- /* release the interrupt */
- free_irq(IRQ_AMIGA_AUD0, AmiInterrupt);
-}
-#endif /* MODULE */
-
-static void AmiSilence(void)
-{
- /* turn off DMA for audio channels */
- StopDMA();
-}
-
-
-static void AmiInit(void)
-{
- int period, i;
-
- AmiSilence();
-
- if (dmasound.soft.speed)
- period = amiga_colorclock/dmasound.soft.speed-1;
- else
- period = amiga_audio_min_period;
- dmasound.hard = dmasound.soft;
- dmasound.trans_write = &transAmiga;
-
- if (period < amiga_audio_min_period) {
- /* we would need to squeeze the sound, but we won't do that */
- period = amiga_audio_min_period;
- } else if (period > 65535) {
- period = 65535;
- }
- dmasound.hard.speed = amiga_colorclock/(period+1);
-
- for (i = 0; i < 4; i++)
- custom.aud[i].audper = period;
- amiga_audio_period = period;
-}
-
-
-static int AmiSetFormat(int format)
-{
- int size;
-
- /* Amiga sound DMA supports 8bit and 16bit (pseudo 14 bit) modes */
-
- switch (format) {
- case AFMT_QUERY:
- return dmasound.soft.format;
- case AFMT_MU_LAW:
- case AFMT_A_LAW:
- case AFMT_U8:
- case AFMT_S8:
- size = 8;
- break;
- case AFMT_S16_BE:
- case AFMT_U16_BE:
- case AFMT_S16_LE:
- case AFMT_U16_LE:
- size = 16;
- break;
- default: /* :-) */
- size = 8;
- format = AFMT_S8;
- }
-
- dmasound.soft.format = format;
- dmasound.soft.size = size;
- if (dmasound.minDev == SND_DEV_DSP) {
- dmasound.dsp.format = format;
- dmasound.dsp.size = dmasound.soft.size;
- }
- AmiInit();
-
- return format;
-}
-
-
-#define VOLUME_VOXWARE_TO_AMI(v) \
- (((v) < 0) ? 0 : ((v) > 100) ? 64 : ((v) * 64)/100)
-#define VOLUME_AMI_TO_VOXWARE(v) ((v)*100/64)
-
-static int AmiSetVolume(int volume)
-{
- dmasound.volume_left = VOLUME_VOXWARE_TO_AMI(volume & 0xff);
- custom.aud[0].audvol = dmasound.volume_left;
- dmasound.volume_right = VOLUME_VOXWARE_TO_AMI((volume & 0xff00) >> 8);
- custom.aud[1].audvol = dmasound.volume_right;
- if (dmasound.hard.size == 16) {
- if (dmasound.volume_left == 64 && dmasound.volume_right == 64) {
- custom.aud[2].audvol = 1;
- custom.aud[3].audvol = 1;
- } else {
- custom.aud[2].audvol = 0;
- custom.aud[3].audvol = 0;
- }
- }
- return VOLUME_AMI_TO_VOXWARE(dmasound.volume_left) |
- (VOLUME_AMI_TO_VOXWARE(dmasound.volume_right) << 8);
-}
-
-static int AmiSetTreble(int treble)
-{
- dmasound.treble = treble;
- if (treble < 50)
- ciaa.pra &= ~0x02;
- else
- ciaa.pra |= 0x02;
- return treble;
-}
-
-
-#define AMI_PLAY_LOADED 1
-#define AMI_PLAY_PLAYING 2
-#define AMI_PLAY_MASK 3
-
-
-static void AmiPlayNextFrame(int index)
-{
- u_char *start, *ch0, *ch1, *ch2, *ch3;
- u_long size;
-
- /* used by AmiPlay() if all doubts whether there really is something
- * to be played are already wiped out.
- */
- start = write_sq.buffers[write_sq.front];
- size = (write_sq.count == index ? write_sq.rear_size
- : write_sq.block_size)>>1;
-
- if (dmasound.hard.stereo) {
- ch0 = start;
- ch1 = start+write_sq_block_size_half;
- size >>= 1;
- } else {
- ch0 = start;
- ch1 = start;
- }
-
- disable_heartbeat();
- custom.aud[0].audvol = dmasound.volume_left;
- custom.aud[1].audvol = dmasound.volume_right;
- if (dmasound.hard.size == 8) {
- custom.aud[0].audlc = (u_short *)ZTWO_PADDR(ch0);
- custom.aud[0].audlen = size;
- custom.aud[1].audlc = (u_short *)ZTWO_PADDR(ch1);
- custom.aud[1].audlen = size;
- custom.dmacon = AMI_AUDIO_8;
- } else {
- size >>= 1;
- custom.aud[0].audlc = (u_short *)ZTWO_PADDR(ch0);
- custom.aud[0].audlen = size;
- custom.aud[1].audlc = (u_short *)ZTWO_PADDR(ch1);
- custom.aud[1].audlen = size;
- if (dmasound.volume_left == 64 && dmasound.volume_right == 64) {
- /* We can play pseudo 14-bit only with the maximum volume */
- ch3 = ch0+write_sq_block_size_quarter;
- ch2 = ch1+write_sq_block_size_quarter;
- custom.aud[2].audvol = 1; /* we are being affected by the beeps */
- custom.aud[3].audvol = 1; /* restoring volume here helps a bit */
- custom.aud[2].audlc = (u_short *)ZTWO_PADDR(ch2);
- custom.aud[2].audlen = size;
- custom.aud[3].audlc = (u_short *)ZTWO_PADDR(ch3);
- custom.aud[3].audlen = size;
- custom.dmacon = AMI_AUDIO_14;
- } else {
- custom.aud[2].audvol = 0;
- custom.aud[3].audvol = 0;
- custom.dmacon = AMI_AUDIO_8;
- }
- }
- write_sq.front = (write_sq.front+1) % write_sq.max_count;
- write_sq.active |= AMI_PLAY_LOADED;
-}
-
-
-static void AmiPlay(void)
-{
- int minframes = 1;
-
- custom.intena = IF_AUD0;
-
- if (write_sq.active & AMI_PLAY_LOADED) {
- /* There's already a frame loaded */
- custom.intena = IF_SETCLR | IF_AUD0;
- return;
- }
-
- if (write_sq.active & AMI_PLAY_PLAYING)
- /* Increase threshold: frame 1 is already being played */
- minframes = 2;
-
- if (write_sq.count < minframes) {
- /* Nothing to do */
- custom.intena = IF_SETCLR | IF_AUD0;
- return;
- }
-
- if (write_sq.count <= minframes &&
- write_sq.rear_size < write_sq.block_size && !write_sq.syncing) {
- /* hmmm, the only existing frame is not
- * yet filled and we're not syncing?
- */
- custom.intena = IF_SETCLR | IF_AUD0;
- return;
- }
-
- AmiPlayNextFrame(minframes);
-
- custom.intena = IF_SETCLR | IF_AUD0;
-}
-
-
-static irqreturn_t AmiInterrupt(int irq, void *dummy)
-{
- int minframes = 1;
-
- custom.intena = IF_AUD0;
-
- if (!write_sq.active) {
- /* Playing was interrupted and sq_reset() has already cleared
- * the sq variables, so better don't do anything here.
- */
- WAKE_UP(write_sq.sync_queue);
- return IRQ_HANDLED;
- }
-
- if (write_sq.active & AMI_PLAY_PLAYING) {
- /* We've just finished a frame */
- write_sq.count--;
- WAKE_UP(write_sq.action_queue);
- }
-
- if (write_sq.active & AMI_PLAY_LOADED)
- /* Increase threshold: frame 1 is already being played */
- minframes = 2;
-
- /* Shift the flags */
- write_sq.active = (write_sq.active<<1) & AMI_PLAY_MASK;
-
- if (!write_sq.active)
- /* No frame is playing, disable audio DMA */
- StopDMA();
-
- custom.intena = IF_SETCLR | IF_AUD0;
-
- if (write_sq.count >= minframes)
- /* Try to play the next frame */
- AmiPlay();
-
- if (!write_sq.active)
- /* Nothing to play anymore.
- Wake up a process waiting for audio output to drain. */
- WAKE_UP(write_sq.sync_queue);
- return IRQ_HANDLED;
-}
-
-/*** Mid level stuff *********************************************************/
-
-
-/*
- * /dev/mixer abstraction
- */
-
-static void __init AmiMixerInit(void)
-{
- dmasound.volume_left = 64;
- dmasound.volume_right = 64;
- custom.aud[0].audvol = dmasound.volume_left;
- custom.aud[3].audvol = 1; /* For pseudo 14bit */
- custom.aud[1].audvol = dmasound.volume_right;
- custom.aud[2].audvol = 1; /* For pseudo 14bit */
- dmasound.treble = 50;
-}
-
-static int AmiMixerIoctl(u_int cmd, u_long arg)
-{
- int data;
- switch (cmd) {
- case SOUND_MIXER_READ_DEVMASK:
- return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_TREBLE);
- case SOUND_MIXER_READ_RECMASK:
- return IOCTL_OUT(arg, 0);
- case SOUND_MIXER_READ_STEREODEVS:
- return IOCTL_OUT(arg, SOUND_MASK_VOLUME);
- case SOUND_MIXER_READ_VOLUME:
- return IOCTL_OUT(arg,
- VOLUME_AMI_TO_VOXWARE(dmasound.volume_left) |
- VOLUME_AMI_TO_VOXWARE(dmasound.volume_right) << 8);
- case SOUND_MIXER_WRITE_VOLUME:
- IOCTL_IN(arg, data);
- return IOCTL_OUT(arg, dmasound_set_volume(data));
- case SOUND_MIXER_READ_TREBLE:
- return IOCTL_OUT(arg, dmasound.treble);
- case SOUND_MIXER_WRITE_TREBLE:
- IOCTL_IN(arg, data);
- return IOCTL_OUT(arg, dmasound_set_treble(data));
- }
- return -EINVAL;
-}
-
-
-static int AmiWriteSqSetup(void)
-{
- write_sq_block_size_half = write_sq.block_size>>1;
- write_sq_block_size_quarter = write_sq_block_size_half>>1;
- return 0;
-}
-
-
-static int AmiStateInfo(char *buffer, size_t space)
-{
- int len = 0;
- len += sprintf(buffer+len, "\tsound.volume_left = %d [0...64]\n",
- dmasound.volume_left);
- len += sprintf(buffer+len, "\tsound.volume_right = %d [0...64]\n",
- dmasound.volume_right);
- if (len >= space) {
- printk(KERN_ERR "dmasound_paula: overflowed state buffer alloc.\n") ;
- len = space ;
- }
- return len;
-}
-
-
-/*** Machine definitions *****************************************************/
-
-static SETTINGS def_hard = {
- .format = AFMT_S8,
- .stereo = 0,
- .size = 8,
- .speed = 8000
-} ;
-
-static SETTINGS def_soft = {
- .format = AFMT_U8,
- .stereo = 0,
- .size = 8,
- .speed = 8000
-} ;
-
-static MACHINE machAmiga = {
- .name = "Amiga",
- .name2 = "AMIGA",
- .owner = THIS_MODULE,
- .dma_alloc = AmiAlloc,
- .dma_free = AmiFree,
- .irqinit = AmiIrqInit,
-#ifdef MODULE
- .irqcleanup = AmiIrqCleanUp,
-#endif /* MODULE */
- .init = AmiInit,
- .silence = AmiSilence,
- .setFormat = AmiSetFormat,
- .setVolume = AmiSetVolume,
- .setTreble = AmiSetTreble,
- .play = AmiPlay,
- .mixer_init = AmiMixerInit,
- .mixer_ioctl = AmiMixerIoctl,
- .write_sq_setup = AmiWriteSqSetup,
- .state_info = AmiStateInfo,
- .min_dsp_speed = 8000,
- .version = ((DMASOUND_PAULA_REVISION<<8) | DMASOUND_PAULA_EDITION),
- .hardware_afmts = (AFMT_S8 | AFMT_S16_BE), /* h'ware-supported formats *only* here */
- .capabilities = DSP_CAP_BATCH /* As per SNDCTL_DSP_GETCAPS */
-};
-
-
-/*** Config & Setup **********************************************************/
-
-
-static int __init amiga_audio_probe(struct platform_device *pdev)
-{
- dmasound.mach = machAmiga;
- dmasound.mach.default_hard = def_hard ;
- dmasound.mach.default_soft = def_soft ;
- return dmasound_init();
-}
-
-static int __exit amiga_audio_remove(struct platform_device *pdev)
-{
- dmasound_deinit();
- return 0;
-}
-
-static struct platform_driver amiga_audio_driver = {
- .remove = __exit_p(amiga_audio_remove),
- .driver = {
- .name = "amiga-audio",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init amiga_audio_init(void)
-{
- return platform_driver_probe(&amiga_audio_driver, amiga_audio_probe);
-}
-
-module_init(amiga_audio_init);
-
-static void __exit amiga_audio_exit(void)
-{
- platform_driver_unregister(&amiga_audio_driver);
-}
-
-module_exit(amiga_audio_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:amiga-audio");
diff --git a/ANDROID_3.4.5/sound/oss/dmasound/dmasound_q40.c b/ANDROID_3.4.5/sound/oss/dmasound/dmasound_q40.c
deleted file mode 100644
index 99bcb21c..00000000
--- a/ANDROID_3.4.5/sound/oss/dmasound/dmasound_q40.c
+++ /dev/null
@@ -1,638 +0,0 @@
-/*
- * linux/sound/oss/dmasound/dmasound_q40.c
- *
- * Q40 DMA Sound Driver
- *
- * See linux/sound/oss/dmasound/dmasound_core.c for copyright and credits
- * prior to 28/01/2001
- *
- * 28/01/2001 [0.1] Iain Sandoe
- * - added versioning
- * - put in and populated the hardware_afmts field.
- * [0.2] - put in SNDCTL_DSP_GETCAPS value.
- * [0.3] - put in default hard/soft settings.
- */
-
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/interrupt.h>
-
-#include <asm/uaccess.h>
-#include <asm/q40ints.h>
-#include <asm/q40_master.h>
-
-#include "dmasound.h"
-
-#define DMASOUND_Q40_REVISION 0
-#define DMASOUND_Q40_EDITION 3
-
-static int expand_bal; /* Balance factor for expanding (not volume!) */
-static int expand_data; /* Data for expanding */
-
-
-/*** Low level stuff *********************************************************/
-
-
-static void *Q40Alloc(unsigned int size, gfp_t flags);
-static void Q40Free(void *, unsigned int);
-static int Q40IrqInit(void);
-#ifdef MODULE
-static void Q40IrqCleanUp(void);
-#endif
-static void Q40Silence(void);
-static void Q40Init(void);
-static int Q40SetFormat(int format);
-static int Q40SetVolume(int volume);
-static void Q40PlayNextFrame(int index);
-static void Q40Play(void);
-static irqreturn_t Q40StereoInterrupt(int irq, void *dummy);
-static irqreturn_t Q40MonoInterrupt(int irq, void *dummy);
-static void Q40Interrupt(void);
-
-
-/*** Mid level stuff *********************************************************/
-
-
-
-/* userCount, frameUsed, frameLeft == byte counts */
-static ssize_t q40_ct_law(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- char *table = dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma8: dmasound_alaw2dma8;
- ssize_t count, used;
- u_char *p = (u_char *) &frame[*frameUsed];
-
- used = count = min_t(size_t, userCount, frameLeft);
- if (copy_from_user(p,userPtr,count))
- return -EFAULT;
- while (count > 0) {
- *p = table[*p]+128;
- p++;
- count--;
- }
- *frameUsed += used ;
- return used;
-}
-
-
-static ssize_t q40_ct_s8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- ssize_t count, used;
- u_char *p = (u_char *) &frame[*frameUsed];
-
- used = count = min_t(size_t, userCount, frameLeft);
- if (copy_from_user(p,userPtr,count))
- return -EFAULT;
- while (count > 0) {
- *p = *p + 128;
- p++;
- count--;
- }
- *frameUsed += used;
- return used;
-}
-
-static ssize_t q40_ct_u8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- ssize_t count, used;
- u_char *p = (u_char *) &frame[*frameUsed];
-
- used = count = min_t(size_t, userCount, frameLeft);
- if (copy_from_user(p,userPtr,count))
- return -EFAULT;
- *frameUsed += used;
- return used;
-}
-
-
-/* a bit too complicated to optimise right now ..*/
-static ssize_t q40_ctx_law(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- unsigned char *table = (unsigned char *)
- (dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma8: dmasound_alaw2dma8);
- unsigned int data = expand_data;
- u_char *p = (u_char *) &frame[*frameUsed];
- int bal = expand_bal;
- int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- int utotal, ftotal;
-
- ftotal = frameLeft;
- utotal = userCount;
- while (frameLeft) {
- u_char c;
- if (bal < 0) {
- if (userCount == 0)
- break;
- if (get_user(c, userPtr++))
- return -EFAULT;
- data = table[c];
- data += 0x80;
- userCount--;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft--;
- bal -= sSpeed;
- }
- expand_bal = bal;
- expand_data = data;
- *frameUsed += (ftotal - frameLeft);
- utotal -= userCount;
- return utotal;
-}
-
-
-static ssize_t q40_ctx_s8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- u_char *p = (u_char *) &frame[*frameUsed];
- unsigned int data = expand_data;
- int bal = expand_bal;
- int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- int utotal, ftotal;
-
-
- ftotal = frameLeft;
- utotal = userCount;
- while (frameLeft) {
- u_char c;
- if (bal < 0) {
- if (userCount == 0)
- break;
- if (get_user(c, userPtr++))
- return -EFAULT;
- data = c ;
- data += 0x80;
- userCount--;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft--;
- bal -= sSpeed;
- }
- expand_bal = bal;
- expand_data = data;
- *frameUsed += (ftotal - frameLeft);
- utotal -= userCount;
- return utotal;
-}
-
-
-static ssize_t q40_ctx_u8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- u_char *p = (u_char *) &frame[*frameUsed];
- unsigned int data = expand_data;
- int bal = expand_bal;
- int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- int utotal, ftotal;
-
- ftotal = frameLeft;
- utotal = userCount;
- while (frameLeft) {
- u_char c;
- if (bal < 0) {
- if (userCount == 0)
- break;
- if (get_user(c, userPtr++))
- return -EFAULT;
- data = c ;
- userCount--;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft--;
- bal -= sSpeed;
- }
- expand_bal = bal;
- expand_data = data;
- *frameUsed += (ftotal - frameLeft) ;
- utotal -= userCount;
- return utotal;
-}
-
-/* compressing versions */
-static ssize_t q40_ctc_law(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- unsigned char *table = (unsigned char *)
- (dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma8: dmasound_alaw2dma8);
- unsigned int data = expand_data;
- u_char *p = (u_char *) &frame[*frameUsed];
- int bal = expand_bal;
- int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- int utotal, ftotal;
-
- ftotal = frameLeft;
- utotal = userCount;
- while (frameLeft) {
- u_char c;
- while(bal<0) {
- if (userCount == 0)
- goto lout;
- if (!(bal<(-hSpeed))) {
- if (get_user(c, userPtr))
- return -EFAULT;
- data = 0x80 + table[c];
- }
- userPtr++;
- userCount--;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft--;
- bal -= sSpeed;
- }
- lout:
- expand_bal = bal;
- expand_data = data;
- *frameUsed += (ftotal - frameLeft);
- utotal -= userCount;
- return utotal;
-}
-
-
-static ssize_t q40_ctc_s8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- u_char *p = (u_char *) &frame[*frameUsed];
- unsigned int data = expand_data;
- int bal = expand_bal;
- int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- int utotal, ftotal;
-
- ftotal = frameLeft;
- utotal = userCount;
- while (frameLeft) {
- u_char c;
- while (bal < 0) {
- if (userCount == 0)
- goto lout;
- if (!(bal<(-hSpeed))) {
- if (get_user(c, userPtr))
- return -EFAULT;
- data = c + 0x80;
- }
- userPtr++;
- userCount--;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft--;
- bal -= sSpeed;
- }
- lout:
- expand_bal = bal;
- expand_data = data;
- *frameUsed += (ftotal - frameLeft);
- utotal -= userCount;
- return utotal;
-}
-
-
-static ssize_t q40_ctc_u8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- u_char *p = (u_char *) &frame[*frameUsed];
- unsigned int data = expand_data;
- int bal = expand_bal;
- int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- int utotal, ftotal;
-
- ftotal = frameLeft;
- utotal = userCount;
- while (frameLeft) {
- u_char c;
- while (bal < 0) {
- if (userCount == 0)
- goto lout;
- if (!(bal<(-hSpeed))) {
- if (get_user(c, userPtr))
- return -EFAULT;
- data = c ;
- }
- userPtr++;
- userCount--;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft--;
- bal -= sSpeed;
- }
- lout:
- expand_bal = bal;
- expand_data = data;
- *frameUsed += (ftotal - frameLeft) ;
- utotal -= userCount;
- return utotal;
-}
-
-
-static TRANS transQ40Normal = {
- q40_ct_law, q40_ct_law, q40_ct_s8, q40_ct_u8, NULL, NULL, NULL, NULL
-};
-
-static TRANS transQ40Expanding = {
- q40_ctx_law, q40_ctx_law, q40_ctx_s8, q40_ctx_u8, NULL, NULL, NULL, NULL
-};
-
-static TRANS transQ40Compressing = {
- q40_ctc_law, q40_ctc_law, q40_ctc_s8, q40_ctc_u8, NULL, NULL, NULL, NULL
-};
-
-
-/*** Low level stuff *********************************************************/
-
-static void *Q40Alloc(unsigned int size, gfp_t flags)
-{
- return kmalloc(size, flags); /* change to vmalloc */
-}
-
-static void Q40Free(void *ptr, unsigned int size)
-{
- kfree(ptr);
-}
-
-static int __init Q40IrqInit(void)
-{
- /* Register interrupt handler. */
- if (request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0,
- "DMA sound", Q40Interrupt))
- return 0;
-
- return(1);
-}
-
-
-#ifdef MODULE
-static void Q40IrqCleanUp(void)
-{
- master_outb(0,SAMPLE_ENABLE_REG);
- free_irq(Q40_IRQ_SAMPLE, Q40Interrupt);
-}
-#endif /* MODULE */
-
-
-static void Q40Silence(void)
-{
- master_outb(0,SAMPLE_ENABLE_REG);
- *DAC_LEFT=*DAC_RIGHT=127;
-}
-
-static char *q40_pp;
-static unsigned int q40_sc;
-
-static void Q40PlayNextFrame(int index)
-{
- u_char *start;
- u_long size;
- u_char speed;
- int error;
-
- /* used by Q40Play() if all doubts whether there really is something
- * to be played are already wiped out.
- */
- start = write_sq.buffers[write_sq.front];
- size = (write_sq.count == index ? write_sq.rear_size : write_sq.block_size);
-
- q40_pp=start;
- q40_sc=size;
-
- write_sq.front = (write_sq.front+1) % write_sq.max_count;
- write_sq.active++;
-
- speed=(dmasound.hard.speed==10000 ? 0 : 1);
-
- master_outb( 0,SAMPLE_ENABLE_REG);
- free_irq(Q40_IRQ_SAMPLE, Q40Interrupt);
- if (dmasound.soft.stereo)
- error = request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0,
- "Q40 sound", Q40Interrupt);
- else
- error = request_irq(Q40_IRQ_SAMPLE, Q40MonoInterrupt, 0,
- "Q40 sound", Q40Interrupt);
- if (error && printk_ratelimit())
- pr_err("Couldn't register sound interrupt\n");
-
- master_outb( speed, SAMPLE_RATE_REG);
- master_outb( 1,SAMPLE_CLEAR_REG);
- master_outb( 1,SAMPLE_ENABLE_REG);
-}
-
-static void Q40Play(void)
-{
- unsigned long flags;
-
- if (write_sq.active || write_sq.count<=0 ) {
- /* There's already a frame loaded */
- return;
- }
-
- /* nothing in the queue */
- if (write_sq.count <= 1 && write_sq.rear_size < write_sq.block_size && !write_sq.syncing) {
- /* hmmm, the only existing frame is not
- * yet filled and we're not syncing?
- */
- return;
- }
- spin_lock_irqsave(&dmasound.lock, flags);
- Q40PlayNextFrame(1);
- spin_unlock_irqrestore(&dmasound.lock, flags);
-}
-
-static irqreturn_t Q40StereoInterrupt(int irq, void *dummy)
-{
- spin_lock(&dmasound.lock);
- if (q40_sc>1){
- *DAC_LEFT=*q40_pp++;
- *DAC_RIGHT=*q40_pp++;
- q40_sc -=2;
- master_outb(1,SAMPLE_CLEAR_REG);
- }else Q40Interrupt();
- spin_unlock(&dmasound.lock);
- return IRQ_HANDLED;
-}
-static irqreturn_t Q40MonoInterrupt(int irq, void *dummy)
-{
- spin_lock(&dmasound.lock);
- if (q40_sc>0){
- *DAC_LEFT=*q40_pp;
- *DAC_RIGHT=*q40_pp++;
- q40_sc --;
- master_outb(1,SAMPLE_CLEAR_REG);
- }else Q40Interrupt();
- spin_unlock(&dmasound.lock);
- return IRQ_HANDLED;
-}
-static void Q40Interrupt(void)
-{
- if (!write_sq.active) {
- /* playing was interrupted and sq_reset() has already cleared
- * the sq variables, so better don't do anything here.
- */
- WAKE_UP(write_sq.sync_queue);
- master_outb(0,SAMPLE_ENABLE_REG); /* better safe */
- goto exit;
- } else write_sq.active=0;
- write_sq.count--;
- Q40Play();
-
- if (q40_sc<2)
- { /* there was nothing to play, disable irq */
- master_outb(0,SAMPLE_ENABLE_REG);
- *DAC_LEFT=*DAC_RIGHT=127;
- }
- WAKE_UP(write_sq.action_queue);
-
- exit:
- master_outb(1,SAMPLE_CLEAR_REG);
-}
-
-
-static void Q40Init(void)
-{
- int i, idx;
- const int freq[] = {10000, 20000};
-
- /* search a frequency that fits into the allowed error range */
-
- idx = -1;
- for (i = 0; i < 2; i++)
- if ((100 * abs(dmasound.soft.speed - freq[i]) / freq[i]) <= catchRadius)
- idx = i;
-
- dmasound.hard = dmasound.soft;
- /*sound.hard.stereo=1;*/ /* no longer true */
- dmasound.hard.size=8;
-
- if (idx > -1) {
- dmasound.soft.speed = freq[idx];
- dmasound.trans_write = &transQ40Normal;
- } else
- dmasound.trans_write = &transQ40Expanding;
-
- Q40Silence();
-
- if (dmasound.hard.speed > 20200) {
- /* squeeze the sound, we do that */
- dmasound.hard.speed = 20000;
- dmasound.trans_write = &transQ40Compressing;
- } else if (dmasound.hard.speed > 10000) {
- dmasound.hard.speed = 20000;
- } else {
- dmasound.hard.speed = 10000;
- }
- expand_bal = -dmasound.soft.speed;
-}
-
-
-static int Q40SetFormat(int format)
-{
- /* Q40 sound supports only 8bit modes */
-
- switch (format) {
- case AFMT_QUERY:
- return(dmasound.soft.format);
- case AFMT_MU_LAW:
- case AFMT_A_LAW:
- case AFMT_S8:
- case AFMT_U8:
- break;
- default:
- format = AFMT_S8;
- }
-
- dmasound.soft.format = format;
- dmasound.soft.size = 8;
- if (dmasound.minDev == SND_DEV_DSP) {
- dmasound.dsp.format = format;
- dmasound.dsp.size = 8;
- }
- Q40Init();
-
- return(format);
-}
-
-static int Q40SetVolume(int volume)
-{
- return 0;
-}
-
-
-/*** Machine definitions *****************************************************/
-
-static SETTINGS def_hard = {
- .format = AFMT_U8,
- .stereo = 0,
- .size = 8,
- .speed = 10000
-} ;
-
-static SETTINGS def_soft = {
- .format = AFMT_U8,
- .stereo = 0,
- .size = 8,
- .speed = 8000
-} ;
-
-static MACHINE machQ40 = {
- .name = "Q40",
- .name2 = "Q40",
- .owner = THIS_MODULE,
- .dma_alloc = Q40Alloc,
- .dma_free = Q40Free,
- .irqinit = Q40IrqInit,
-#ifdef MODULE
- .irqcleanup = Q40IrqCleanUp,
-#endif /* MODULE */
- .init = Q40Init,
- .silence = Q40Silence,
- .setFormat = Q40SetFormat,
- .setVolume = Q40SetVolume,
- .play = Q40Play,
- .min_dsp_speed = 10000,
- .version = ((DMASOUND_Q40_REVISION<<8) | DMASOUND_Q40_EDITION),
- .hardware_afmts = AFMT_U8, /* h'ware-supported formats *only* here */
- .capabilities = DSP_CAP_BATCH /* As per SNDCTL_DSP_GETCAPS */
-};
-
-
-/*** Config & Setup **********************************************************/
-
-
-static int __init dmasound_q40_init(void)
-{
- if (MACH_IS_Q40) {
- dmasound.mach = machQ40;
- dmasound.mach.default_hard = def_hard ;
- dmasound.mach.default_soft = def_soft ;
- return dmasound_init();
- } else
- return -ENODEV;
-}
-
-static void __exit dmasound_q40_cleanup(void)
-{
- dmasound_deinit();
-}
-
-module_init(dmasound_q40_init);
-module_exit(dmasound_q40_cleanup);
-
-MODULE_DESCRIPTION("Q40/Q60 sound driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/oss/hex2hex.c b/ANDROID_3.4.5/sound/oss/hex2hex.c
deleted file mode 100644
index 041ef5c5..00000000
--- a/ANDROID_3.4.5/sound/oss/hex2hex.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * hex2hex reads stdin in Intel HEX format and produces an
- * (unsigned char) array which contains the bytes and writes it
- * to stdout using C syntax
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#define ABANDON(why) { fprintf(stderr, "%s\n", why); exit(1); }
-#define MAX_SIZE (256*1024)
-unsigned char buf[MAX_SIZE];
-
-static int loadhex(FILE *inf, unsigned char *buf)
-{
- int l=0, c, i;
-
- while ((c=getc(inf))!=EOF)
- {
- if (c == ':') /* Sync with beginning of line */
- {
- int n, check;
- unsigned char sum;
- int addr;
- int linetype;
-
- if (fscanf(inf, "%02x", &n) != 1)
- ABANDON("File format error");
- sum = n;
-
- if (fscanf(inf, "%04x", &addr) != 1)
- ABANDON("File format error");
- sum += addr/256;
- sum += addr%256;
-
- if (fscanf(inf, "%02x", &linetype) != 1)
- ABANDON("File format error");
- sum += linetype;
-
- if (linetype != 0)
- continue;
-
- for (i=0;i<n;i++)
- {
- if (fscanf(inf, "%02x", &c) != 1)
- ABANDON("File format error");
- if (addr >= MAX_SIZE)
- ABANDON("File too large");
- buf[addr++] = c;
- if (addr > l)
- l = addr;
- sum += c;
- }
-
- if (fscanf(inf, "%02x", &check) != 1)
- ABANDON("File format error");
-
- sum = ~sum + 1;
- if (check != sum)
- ABANDON("Line checksum error");
- }
- }
-
- return l;
-}
-
-int main( int argc, const char * argv [] )
-{
- const char * varline;
- int i,l;
- int id=0;
-
- if(argv[1] && strcmp(argv[1], "-i")==0)
- {
- argv++;
- argc--;
- id=1;
- }
- if(argv[1]==NULL)
- {
- fprintf(stderr,"hex2hex: [-i] filename\n");
- exit(1);
- }
- varline = argv[1];
- l = loadhex(stdin, buf);
-
- printf("/*\n *\t Computer generated file. Do not edit.\n */\n");
- printf("static int %s_len = %d;\n", varline, l);
- printf("static unsigned char %s[] %s = {\n", varline, id?"__initdata":"");
-
- for (i=0;i<l;i++)
- {
- if (i) printf(",");
- if (i && !(i % 16)) printf("\n");
- printf("0x%02x", buf[i]);
- }
-
- printf("\n};\n\n");
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/oss/kahlua.c b/ANDROID_3.4.5/sound/oss/kahlua.c
deleted file mode 100644
index 52d06a33..00000000
--- a/ANDROID_3.4.5/sound/oss/kahlua.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Initialisation code for Cyrix/NatSemi VSA1 softaudio
- *
- * (C) Copyright 2003 Red Hat Inc <alan@lxorguk.ukuu.org.uk>
- *
- * XpressAudio(tm) is used on the Cyrix MediaGX (now NatSemi Geode) systems.
- * The older version (VSA1) provides fairly good soundblaster emulation
- * although there are a couple of bugs: large DMA buffers break record,
- * and the MPU event handling seems suspect. VSA2 allows the native driver
- * to control the AC97 audio engine directly and requires a different driver.
- *
- * Thanks to National Semiconductor for providing the needed information
- * on the XpressAudio(tm) internals.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * TO DO:
- * Investigate whether we can portably support Cognac (5520) in the
- * same manner.
- */
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include "sound_config.h"
-
-#include "sb.h"
-
-/*
- * Read a soundblaster compatible mixer register.
- * In this case we are actually reading an SMI trap
- * not real hardware.
- */
-
-static u8 __devinit mixer_read(unsigned long io, u8 reg)
-{
- outb(reg, io + 4);
- udelay(20);
- reg = inb(io + 5);
- udelay(20);
- return reg;
-}
-
-static int __devinit probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
- struct address_info *hw_config;
- unsigned long base;
- void __iomem *mem;
- unsigned long io;
- u16 map;
- u8 irq, dma8, dma16;
- int oldquiet;
- extern int sb_be_quiet;
-
- base = pci_resource_start(pdev, 0);
- if(base == 0UL)
- return 1;
-
- mem = ioremap(base, 128);
- if (!mem)
- return 1;
- map = readw(mem + 0x18); /* Read the SMI enables */
- iounmap(mem);
-
- /* Map bits
- 0:1 * 0x20 + 0x200 = sb base
- 2 sb enable
- 3 adlib enable
- 5 MPU enable 0x330
- 6 MPU enable 0x300
-
- The other bits may be used internally so must be masked */
-
- io = 0x220 + 0x20 * (map & 3);
-
- if(map & (1<<2))
- printk(KERN_INFO "kahlua: XpressAudio at 0x%lx\n", io);
- else
- return 1;
-
- if(map & (1<<5))
- printk(KERN_INFO "kahlua: MPU at 0x300\n");
- else if(map & (1<<6))
- printk(KERN_INFO "kahlua: MPU at 0x330\n");
-
- irq = mixer_read(io, 0x80) & 0x0F;
- dma8 = mixer_read(io, 0x81);
-
- // printk("IRQ=%x MAP=%x DMA=%x\n", irq, map, dma8);
-
- if(dma8 & 0x20)
- dma16 = 5;
- else if(dma8 & 0x40)
- dma16 = 6;
- else if(dma8 & 0x80)
- dma16 = 7;
- else
- {
- printk(KERN_ERR "kahlua: No 16bit DMA enabled.\n");
- return 1;
- }
-
- if(dma8 & 0x01)
- dma8 = 0;
- else if(dma8 & 0x02)
- dma8 = 1;
- else if(dma8 & 0x08)
- dma8 = 3;
- else
- {
- printk(KERN_ERR "kahlua: No 8bit DMA enabled.\n");
- return 1;
- }
-
- if(irq & 1)
- irq = 9;
- else if(irq & 2)
- irq = 5;
- else if(irq & 4)
- irq = 7;
- else if(irq & 8)
- irq = 10;
- else
- {
- printk(KERN_ERR "kahlua: SB IRQ not set.\n");
- return 1;
- }
-
- printk(KERN_INFO "kahlua: XpressAudio on IRQ %d, DMA %d, %d\n",
- irq, dma8, dma16);
-
- hw_config = kzalloc(sizeof(struct address_info), GFP_KERNEL);
- if(hw_config == NULL)
- {
- printk(KERN_ERR "kahlua: out of memory.\n");
- return 1;
- }
-
- pci_set_drvdata(pdev, hw_config);
-
- hw_config->io_base = io;
- hw_config->irq = irq;
- hw_config->dma = dma8;
- hw_config->dma2 = dma16;
- hw_config->name = "Cyrix XpressAudio";
- hw_config->driver_use_1 = SB_NO_MIDI | SB_PCI_IRQ;
-
- if (!request_region(io, 16, "soundblaster"))
- goto err_out_free;
-
- if(sb_dsp_detect(hw_config, 0, 0, NULL)==0)
- {
- printk(KERN_ERR "kahlua: audio not responding.\n");
- release_region(io, 16);
- goto err_out_free;
- }
-
- oldquiet = sb_be_quiet;
- sb_be_quiet = 1;
- if(sb_dsp_init(hw_config, THIS_MODULE))
- {
- sb_be_quiet = oldquiet;
- goto err_out_free;
- }
- sb_be_quiet = oldquiet;
-
- return 0;
-
-err_out_free:
- pci_set_drvdata(pdev, NULL);
- kfree(hw_config);
- return 1;
-}
-
-static void __devexit remove_one(struct pci_dev *pdev)
-{
- struct address_info *hw_config = pci_get_drvdata(pdev);
- sb_dsp_unload(hw_config, 0);
- pci_set_drvdata(pdev, NULL);
- kfree(hw_config);
-}
-
-MODULE_AUTHOR("Alan Cox");
-MODULE_DESCRIPTION("Kahlua VSA1 PCI Audio");
-MODULE_LICENSE("GPL");
-
-/*
- * 5530 only. The 5510/5520 decode is different.
- */
-
-static DEFINE_PCI_DEVICE_TABLE(id_tbl) = {
- { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO), 0 },
- { }
-};
-
-MODULE_DEVICE_TABLE(pci, id_tbl);
-
-static struct pci_driver kahlua_driver = {
- .name = "kahlua",
- .id_table = id_tbl,
- .probe = probe_one,
- .remove = __devexit_p(remove_one),
-};
-
-
-static int __init kahlua_init_module(void)
-{
- printk(KERN_INFO "Cyrix Kahlua VSA1 XpressAudio support (c) Copyright 2003 Red Hat Inc\n");
- return pci_register_driver(&kahlua_driver);
-}
-
-static void __devexit kahlua_cleanup_module(void)
-{
- pci_unregister_driver(&kahlua_driver);
-}
-
-
-module_init(kahlua_init_module);
-module_exit(kahlua_cleanup_module);
-
diff --git a/ANDROID_3.4.5/sound/oss/midi_ctrl.h b/ANDROID_3.4.5/sound/oss/midi_ctrl.h
deleted file mode 100644
index 3353e5a6..00000000
--- a/ANDROID_3.4.5/sound/oss/midi_ctrl.h
+++ /dev/null
@@ -1,22 +0,0 @@
-static unsigned char ctrl_def_values[128] =
-{
- 0x40,0x00,0x40,0x40, 0x40,0x40,0x40,0x7f, /* 0 to 7 */
- 0x40,0x40,0x40,0x7f, 0x40,0x40,0x40,0x40, /* 8 to 15 */
- 0x40,0x40,0x40,0x40, 0x40,0x40,0x40,0x40, /* 16 to 23 */
- 0x40,0x40,0x40,0x40, 0x40,0x40,0x40,0x40, /* 24 to 31 */
-
- 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 32 to 39 */
- 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 40 to 47 */
- 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 48 to 55 */
- 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 56 to 63 */
-
- 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 64 to 71 */
- 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 72 to 79 */
- 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 80 to 87 */
- 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 88 to 95 */
-
- 0x00,0x00,0x7f,0x7f, 0x7f,0x7f,0x00,0x00, /* 96 to 103 */
- 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 104 to 111 */
- 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 112 to 119 */
- 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, /* 120 to 127 */
-};
diff --git a/ANDROID_3.4.5/sound/oss/midi_synth.c b/ANDROID_3.4.5/sound/oss/midi_synth.c
deleted file mode 100644
index 2292c230..00000000
--- a/ANDROID_3.4.5/sound/oss/midi_synth.c
+++ /dev/null
@@ -1,712 +0,0 @@
-/*
- * sound/oss/midi_synth.c
- *
- * High level midi sequencer manager for dumb MIDI interfaces.
- */
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-/*
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
- * Andrew Veliath : fixed running status in MIDI input state machine
- */
-#define USE_SEQ_MACROS
-#define USE_SIMPLE_MACROS
-
-#include "sound_config.h"
-
-#define _MIDI_SYNTH_C_
-
-#include "midi_synth.h"
-
-static int midi2synth[MAX_MIDI_DEV];
-static int sysex_state[MAX_MIDI_DEV] =
-{0};
-static unsigned char prev_out_status[MAX_MIDI_DEV];
-
-#define STORE(cmd) \
-{ \
- int len; \
- unsigned char obuf[8]; \
- cmd; \
- seq_input_event(obuf, len); \
-}
-
-#define _seqbuf obuf
-#define _seqbufptr 0
-#define _SEQ_ADVBUF(x) len=x
-
-void
-do_midi_msg(int synthno, unsigned char *msg, int mlen)
-{
- switch (msg[0] & 0xf0)
- {
- case 0x90:
- if (msg[2] != 0)
- {
- STORE(SEQ_START_NOTE(synthno, msg[0] & 0x0f, msg[1], msg[2]));
- break;
- }
- msg[2] = 64;
-
- case 0x80:
- STORE(SEQ_STOP_NOTE(synthno, msg[0] & 0x0f, msg[1], msg[2]));
- break;
-
- case 0xA0:
- STORE(SEQ_KEY_PRESSURE(synthno, msg[0] & 0x0f, msg[1], msg[2]));
- break;
-
- case 0xB0:
- STORE(SEQ_CONTROL(synthno, msg[0] & 0x0f,
- msg[1], msg[2]));
- break;
-
- case 0xC0:
- STORE(SEQ_SET_PATCH(synthno, msg[0] & 0x0f, msg[1]));
- break;
-
- case 0xD0:
- STORE(SEQ_CHN_PRESSURE(synthno, msg[0] & 0x0f, msg[1]));
- break;
-
- case 0xE0:
- STORE(SEQ_BENDER(synthno, msg[0] & 0x0f,
- (msg[1] & 0x7f) | ((msg[2] & 0x7f) << 7)));
- break;
-
- default:
- /* printk( "MPU: Unknown midi channel message %02x\n", msg[0]); */
- ;
- }
-}
-EXPORT_SYMBOL(do_midi_msg);
-
-static void
-midi_outc(int midi_dev, int data)
-{
- int timeout;
-
- for (timeout = 0; timeout < 3200; timeout++)
- if (midi_devs[midi_dev]->outputc(midi_dev, (unsigned char) (data & 0xff)))
- {
- if (data & 0x80) /*
- * Status byte
- */
- prev_out_status[midi_dev] =
- (unsigned char) (data & 0xff); /*
- * Store for running status
- */
- return; /*
- * Mission complete
- */
- }
- /*
- * Sorry! No space on buffers.
- */
- printk("Midi send timed out\n");
-}
-
-static int
-prefix_cmd(int midi_dev, unsigned char status)
-{
- if ((char *) midi_devs[midi_dev]->prefix_cmd == NULL)
- return 1;
-
- return midi_devs[midi_dev]->prefix_cmd(midi_dev, status);
-}
-
-static void
-midi_synth_input(int orig_dev, unsigned char data)
-{
- int dev;
- struct midi_input_info *inc;
-
- static unsigned char len_tab[] = /* # of data bytes following a status
- */
- {
- 2, /* 8x */
- 2, /* 9x */
- 2, /* Ax */
- 2, /* Bx */
- 1, /* Cx */
- 1, /* Dx */
- 2, /* Ex */
- 0 /* Fx */
- };
-
- if (orig_dev < 0 || orig_dev > num_midis || midi_devs[orig_dev] == NULL)
- return;
-
- if (data == 0xfe) /* Ignore active sensing */
- return;
-
- dev = midi2synth[orig_dev];
- inc = &midi_devs[orig_dev]->in_info;
-
- switch (inc->m_state)
- {
- case MST_INIT:
- if (data & 0x80) /* MIDI status byte */
- {
- if ((data & 0xf0) == 0xf0) /* Common message */
- {
- switch (data)
- {
- case 0xf0: /* Sysex */
- inc->m_state = MST_SYSEX;
- break; /* Sysex */
-
- case 0xf1: /* MTC quarter frame */
- case 0xf3: /* Song select */
- inc->m_state = MST_DATA;
- inc->m_ptr = 1;
- inc->m_left = 1;
- inc->m_buf[0] = data;
- break;
-
- case 0xf2: /* Song position pointer */
- inc->m_state = MST_DATA;
- inc->m_ptr = 1;
- inc->m_left = 2;
- inc->m_buf[0] = data;
- break;
-
- default:
- inc->m_buf[0] = data;
- inc->m_ptr = 1;
- do_midi_msg(dev, inc->m_buf, inc->m_ptr);
- inc->m_ptr = 0;
- inc->m_left = 0;
- }
- } else
- {
- inc->m_state = MST_DATA;
- inc->m_ptr = 1;
- inc->m_left = len_tab[(data >> 4) - 8];
- inc->m_buf[0] = inc->m_prev_status = data;
- }
- } else if (inc->m_prev_status & 0x80) {
- /* Data byte (use running status) */
- inc->m_ptr = 2;
- inc->m_buf[1] = data;
- inc->m_buf[0] = inc->m_prev_status;
- inc->m_left = len_tab[(inc->m_buf[0] >> 4) - 8] - 1;
- if (inc->m_left > 0)
- inc->m_state = MST_DATA; /* Not done yet */
- else {
- inc->m_state = MST_INIT;
- do_midi_msg(dev, inc->m_buf, inc->m_ptr);
- inc->m_ptr = 0;
- }
- }
- break; /* MST_INIT */
-
- case MST_DATA:
- inc->m_buf[inc->m_ptr++] = data;
- if (--inc->m_left <= 0)
- {
- inc->m_state = MST_INIT;
- do_midi_msg(dev, inc->m_buf, inc->m_ptr);
- inc->m_ptr = 0;
- }
- break; /* MST_DATA */
-
- case MST_SYSEX:
- if (data == 0xf7) /* Sysex end */
- {
- inc->m_state = MST_INIT;
- inc->m_left = 0;
- inc->m_ptr = 0;
- }
- break; /* MST_SYSEX */
-
- default:
- printk("MIDI%d: Unexpected state %d (%02x)\n", orig_dev, inc->m_state, (int) data);
- inc->m_state = MST_INIT;
- }
-}
-
-static void
-leave_sysex(int dev)
-{
- int orig_dev = synth_devs[dev]->midi_dev;
- int timeout = 0;
-
- if (!sysex_state[dev])
- return;
-
- sysex_state[dev] = 0;
-
- while (!midi_devs[orig_dev]->outputc(orig_dev, 0xf7) &&
- timeout < 1000)
- timeout++;
-
- sysex_state[dev] = 0;
-}
-
-static void
-midi_synth_output(int dev)
-{
- /*
- * Currently NOP
- */
-}
-
-int midi_synth_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
- /*
- * int orig_dev = synth_devs[dev]->midi_dev;
- */
-
- switch (cmd) {
-
- case SNDCTL_SYNTH_INFO:
- if (__copy_to_user(arg, synth_devs[dev]->info, sizeof(struct synth_info)))
- return -EFAULT;
- return 0;
-
- case SNDCTL_SYNTH_MEMAVL:
- return 0x7fffffff;
-
- default:
- return -EINVAL;
- }
-}
-EXPORT_SYMBOL(midi_synth_ioctl);
-
-int
-midi_synth_kill_note(int dev, int channel, int note, int velocity)
-{
- int orig_dev = synth_devs[dev]->midi_dev;
- int msg, chn;
-
- if (note < 0 || note > 127)
- return 0;
- if (channel < 0 || channel > 15)
- return 0;
- if (velocity < 0)
- velocity = 0;
- if (velocity > 127)
- velocity = 127;
-
- leave_sysex(dev);
-
- msg = prev_out_status[orig_dev] & 0xf0;
- chn = prev_out_status[orig_dev] & 0x0f;
-
- if (chn == channel && ((msg == 0x90 && velocity == 64) || msg == 0x80))
- { /*
- * Use running status
- */
- if (!prefix_cmd(orig_dev, note))
- return 0;
-
- midi_outc(orig_dev, note);
-
- if (msg == 0x90) /*
- * Running status = Note on
- */
- midi_outc(orig_dev, 0); /*
- * Note on with velocity 0 == note
- * off
- */
- else
- midi_outc(orig_dev, velocity);
- } else
- {
- if (velocity == 64)
- {
- if (!prefix_cmd(orig_dev, 0x90 | (channel & 0x0f)))
- return 0;
- midi_outc(orig_dev, 0x90 | (channel & 0x0f)); /*
- * Note on
- */
- midi_outc(orig_dev, note);
- midi_outc(orig_dev, 0); /*
- * Zero G
- */
- } else
- {
- if (!prefix_cmd(orig_dev, 0x80 | (channel & 0x0f)))
- return 0;
- midi_outc(orig_dev, 0x80 | (channel & 0x0f)); /*
- * Note off
- */
- midi_outc(orig_dev, note);
- midi_outc(orig_dev, velocity);
- }
- }
-
- return 0;
-}
-EXPORT_SYMBOL(midi_synth_kill_note);
-
-int
-midi_synth_set_instr(int dev, int channel, int instr_no)
-{
- int orig_dev = synth_devs[dev]->midi_dev;
-
- if (instr_no < 0 || instr_no > 127)
- instr_no = 0;
- if (channel < 0 || channel > 15)
- return 0;
-
- leave_sysex(dev);
-
- if (!prefix_cmd(orig_dev, 0xc0 | (channel & 0x0f)))
- return 0;
- midi_outc(orig_dev, 0xc0 | (channel & 0x0f)); /*
- * Program change
- */
- midi_outc(orig_dev, instr_no);
-
- return 0;
-}
-EXPORT_SYMBOL(midi_synth_set_instr);
-
-int
-midi_synth_start_note(int dev, int channel, int note, int velocity)
-{
- int orig_dev = synth_devs[dev]->midi_dev;
- int msg, chn;
-
- if (note < 0 || note > 127)
- return 0;
- if (channel < 0 || channel > 15)
- return 0;
- if (velocity < 0)
- velocity = 0;
- if (velocity > 127)
- velocity = 127;
-
- leave_sysex(dev);
-
- msg = prev_out_status[orig_dev] & 0xf0;
- chn = prev_out_status[orig_dev] & 0x0f;
-
- if (chn == channel && msg == 0x90)
- { /*
- * Use running status
- */
- if (!prefix_cmd(orig_dev, note))
- return 0;
- midi_outc(orig_dev, note);
- midi_outc(orig_dev, velocity);
- } else
- {
- if (!prefix_cmd(orig_dev, 0x90 | (channel & 0x0f)))
- return 0;
- midi_outc(orig_dev, 0x90 | (channel & 0x0f)); /*
- * Note on
- */
- midi_outc(orig_dev, note);
- midi_outc(orig_dev, velocity);
- }
- return 0;
-}
-EXPORT_SYMBOL(midi_synth_start_note);
-
-void
-midi_synth_reset(int dev)
-{
-
- leave_sysex(dev);
-}
-EXPORT_SYMBOL(midi_synth_reset);
-
-int
-midi_synth_open(int dev, int mode)
-{
- int orig_dev = synth_devs[dev]->midi_dev;
- int err;
- struct midi_input_info *inc;
-
- if (orig_dev < 0 || orig_dev >= num_midis || midi_devs[orig_dev] == NULL)
- return -ENXIO;
-
- midi2synth[orig_dev] = dev;
- sysex_state[dev] = 0;
- prev_out_status[orig_dev] = 0;
-
- if ((err = midi_devs[orig_dev]->open(orig_dev, mode,
- midi_synth_input, midi_synth_output)) < 0)
- return err;
- inc = &midi_devs[orig_dev]->in_info;
-
- /* save_flags(flags);
- cli();
- don't know against what irqhandler to protect*/
- inc->m_busy = 0;
- inc->m_state = MST_INIT;
- inc->m_ptr = 0;
- inc->m_left = 0;
- inc->m_prev_status = 0x00;
- /* restore_flags(flags); */
-
- return 1;
-}
-EXPORT_SYMBOL(midi_synth_open);
-
-void
-midi_synth_close(int dev)
-{
- int orig_dev = synth_devs[dev]->midi_dev;
-
- leave_sysex(dev);
-
- /*
- * Shut up the synths by sending just single active sensing message.
- */
- midi_devs[orig_dev]->outputc(orig_dev, 0xfe);
-
- midi_devs[orig_dev]->close(orig_dev);
-}
-EXPORT_SYMBOL(midi_synth_close);
-
-void
-midi_synth_hw_control(int dev, unsigned char *event)
-{
-}
-EXPORT_SYMBOL(midi_synth_hw_control);
-
-int
-midi_synth_load_patch(int dev, int format, const char __user *addr,
- int count, int pmgr_flag)
-{
- int orig_dev = synth_devs[dev]->midi_dev;
-
- struct sysex_info sysex;
- int i;
- unsigned long left, src_offs, eox_seen = 0;
- int first_byte = 1;
- int hdr_size = (unsigned long) &sysex.data[0] - (unsigned long) &sysex;
-
- leave_sysex(dev);
-
- if (!prefix_cmd(orig_dev, 0xf0))
- return 0;
-
- /* Invalid patch format */
- if (format != SYSEX_PATCH)
- return -EINVAL;
-
- /* Patch header too short */
- if (count < hdr_size)
- return -EINVAL;
-
- count -= hdr_size;
-
- /*
- * Copy the header from user space
- */
-
- if (copy_from_user(&sysex, addr, hdr_size))
- return -EFAULT;
-
- /* Sysex record too short */
- if ((unsigned)count < (unsigned)sysex.len)
- sysex.len = count;
-
- left = sysex.len;
- src_offs = 0;
-
- for (i = 0; i < left && !signal_pending(current); i++)
- {
- unsigned char data;
-
- if (get_user(data,
- (unsigned char __user *)(addr + hdr_size + i)))
- return -EFAULT;
-
- eox_seen = (i > 0 && data & 0x80); /* End of sysex */
-
- if (eox_seen && data != 0xf7)
- data = 0xf7;
-
- if (i == 0)
- {
- if (data != 0xf0)
- {
- printk(KERN_WARNING "midi_synth: Sysex start missing\n");
- return -EINVAL;
- }
- }
- while (!midi_devs[orig_dev]->outputc(orig_dev, (unsigned char) (data & 0xff)) &&
- !signal_pending(current))
- schedule();
-
- if (!first_byte && data & 0x80)
- return 0;
- first_byte = 0;
- }
-
- if (!eox_seen)
- midi_outc(orig_dev, 0xf7);
- return 0;
-}
-EXPORT_SYMBOL(midi_synth_load_patch);
-
-void midi_synth_panning(int dev, int channel, int pressure)
-{
-}
-EXPORT_SYMBOL(midi_synth_panning);
-
-void midi_synth_aftertouch(int dev, int channel, int pressure)
-{
- int orig_dev = synth_devs[dev]->midi_dev;
- int msg, chn;
-
- if (pressure < 0 || pressure > 127)
- return;
- if (channel < 0 || channel > 15)
- return;
-
- leave_sysex(dev);
-
- msg = prev_out_status[orig_dev] & 0xf0;
- chn = prev_out_status[orig_dev] & 0x0f;
-
- if (msg != 0xd0 || chn != channel) /*
- * Test for running status
- */
- {
- if (!prefix_cmd(orig_dev, 0xd0 | (channel & 0x0f)))
- return;
- midi_outc(orig_dev, 0xd0 | (channel & 0x0f)); /*
- * Channel pressure
- */
- } else if (!prefix_cmd(orig_dev, pressure))
- return;
-
- midi_outc(orig_dev, pressure);
-}
-EXPORT_SYMBOL(midi_synth_aftertouch);
-
-void
-midi_synth_controller(int dev, int channel, int ctrl_num, int value)
-{
- int orig_dev = synth_devs[dev]->midi_dev;
- int chn, msg;
-
- if (ctrl_num < 0 || ctrl_num > 127)
- return;
- if (channel < 0 || channel > 15)
- return;
-
- leave_sysex(dev);
-
- msg = prev_out_status[orig_dev] & 0xf0;
- chn = prev_out_status[orig_dev] & 0x0f;
-
- if (msg != 0xb0 || chn != channel)
- {
- if (!prefix_cmd(orig_dev, 0xb0 | (channel & 0x0f)))
- return;
- midi_outc(orig_dev, 0xb0 | (channel & 0x0f));
- } else if (!prefix_cmd(orig_dev, ctrl_num))
- return;
-
- midi_outc(orig_dev, ctrl_num);
- midi_outc(orig_dev, value & 0x7f);
-}
-EXPORT_SYMBOL(midi_synth_controller);
-
-void
-midi_synth_bender(int dev, int channel, int value)
-{
- int orig_dev = synth_devs[dev]->midi_dev;
- int msg, prev_chn;
-
- if (channel < 0 || channel > 15)
- return;
-
- if (value < 0 || value > 16383)
- return;
-
- leave_sysex(dev);
-
- msg = prev_out_status[orig_dev] & 0xf0;
- prev_chn = prev_out_status[orig_dev] & 0x0f;
-
- if (msg != 0xd0 || prev_chn != channel) /*
- * Test for running status
- */
- {
- if (!prefix_cmd(orig_dev, 0xe0 | (channel & 0x0f)))
- return;
- midi_outc(orig_dev, 0xe0 | (channel & 0x0f));
- } else if (!prefix_cmd(orig_dev, value & 0x7f))
- return;
-
- midi_outc(orig_dev, value & 0x7f);
- midi_outc(orig_dev, (value >> 7) & 0x7f);
-}
-EXPORT_SYMBOL(midi_synth_bender);
-
-void
-midi_synth_setup_voice(int dev, int voice, int channel)
-{
-}
-EXPORT_SYMBOL(midi_synth_setup_voice);
-
-int
-midi_synth_send_sysex(int dev, unsigned char *bytes, int len)
-{
- int orig_dev = synth_devs[dev]->midi_dev;
- int i;
-
- for (i = 0; i < len; i++)
- {
- switch (bytes[i])
- {
- case 0xf0: /* Start sysex */
- if (!prefix_cmd(orig_dev, 0xf0))
- return 0;
- sysex_state[dev] = 1;
- break;
-
- case 0xf7: /* End sysex */
- if (!sysex_state[dev]) /* Orphan sysex end */
- return 0;
- sysex_state[dev] = 0;
- break;
-
- default:
- if (!sysex_state[dev])
- return 0;
-
- if (bytes[i] & 0x80) /* Error. Another message before sysex end */
- {
- bytes[i] = 0xf7; /* Sysex end */
- sysex_state[dev] = 0;
- }
- }
-
- if (!midi_devs[orig_dev]->outputc(orig_dev, bytes[i]))
- {
-/*
- * Hardware level buffer is full. Abort the sysex message.
- */
-
- int timeout = 0;
-
- bytes[i] = 0xf7;
- sysex_state[dev] = 0;
-
- while (!midi_devs[orig_dev]->outputc(orig_dev, bytes[i]) &&
- timeout < 1000)
- timeout++;
- }
- if (!sysex_state[dev])
- return 0;
- }
-
- return 0;
-}
-EXPORT_SYMBOL(midi_synth_send_sysex);
-
diff --git a/ANDROID_3.4.5/sound/oss/midi_synth.h b/ANDROID_3.4.5/sound/oss/midi_synth.h
deleted file mode 100644
index b64ddd6c..00000000
--- a/ANDROID_3.4.5/sound/oss/midi_synth.h
+++ /dev/null
@@ -1,47 +0,0 @@
-int midi_synth_ioctl (int dev,
- unsigned int cmd, void __user * arg);
-int midi_synth_kill_note (int dev, int channel, int note, int velocity);
-int midi_synth_set_instr (int dev, int channel, int instr_no);
-int midi_synth_start_note (int dev, int channel, int note, int volume);
-void midi_synth_reset (int dev);
-int midi_synth_open (int dev, int mode);
-void midi_synth_close (int dev);
-void midi_synth_hw_control (int dev, unsigned char *event);
-int midi_synth_load_patch (int dev, int format, const char __user * addr,
- int count, int pmgr_flag);
-void midi_synth_panning (int dev, int channel, int pressure);
-void midi_synth_aftertouch (int dev, int channel, int pressure);
-void midi_synth_controller (int dev, int channel, int ctrl_num, int value);
-void midi_synth_bender (int dev, int chn, int value);
-void midi_synth_setup_voice (int dev, int voice, int chn);
-int midi_synth_send_sysex(int dev, unsigned char *bytes,int len);
-
-#ifndef _MIDI_SYNTH_C_
-static struct synth_info std_synth_info =
-{MIDI_SYNTH_NAME, 0, SYNTH_TYPE_MIDI, 0, 0, 128, 0, 128, MIDI_SYNTH_CAPS};
-
-static struct synth_operations std_midi_synth =
-{
- .owner = THIS_MODULE,
- .id = "MIDI",
- .info = &std_synth_info,
- .midi_dev = 0,
- .synth_type = SYNTH_TYPE_MIDI,
- .synth_subtype = 0,
- .open = midi_synth_open,
- .close = midi_synth_close,
- .ioctl = midi_synth_ioctl,
- .kill_note = midi_synth_kill_note,
- .start_note = midi_synth_start_note,
- .set_instr = midi_synth_set_instr,
- .reset = midi_synth_reset,
- .hw_control = midi_synth_hw_control,
- .load_patch = midi_synth_load_patch,
- .aftertouch = midi_synth_aftertouch,
- .controller = midi_synth_controller,
- .panning = midi_synth_panning,
- .bender = midi_synth_bender,
- .setup_voice = midi_synth_setup_voice,
- .send_sysex = midi_synth_send_sysex
-};
-#endif
diff --git a/ANDROID_3.4.5/sound/oss/midibuf.c b/ANDROID_3.4.5/sound/oss/midibuf.c
deleted file mode 100644
index 8cdb2cfe..00000000
--- a/ANDROID_3.4.5/sound/oss/midibuf.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * sound/oss/midibuf.c
- *
- * Device file manager for /dev/midi#
- */
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-/*
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
- */
-#include <linux/stddef.h>
-#include <linux/kmod.h>
-#include <linux/spinlock.h>
-#define MIDIBUF_C
-
-#include "sound_config.h"
-
-
-/*
- * Don't make MAX_QUEUE_SIZE larger than 4000
- */
-
-#define MAX_QUEUE_SIZE 4000
-
-static wait_queue_head_t midi_sleeper[MAX_MIDI_DEV];
-static wait_queue_head_t input_sleeper[MAX_MIDI_DEV];
-
-struct midi_buf
-{
- int len, head, tail;
- unsigned char queue[MAX_QUEUE_SIZE];
-};
-
-struct midi_parms
-{
- long prech_timeout; /*
- * Timeout before the first ch
- */
-};
-
-static struct midi_buf *midi_out_buf[MAX_MIDI_DEV] = {NULL};
-static struct midi_buf *midi_in_buf[MAX_MIDI_DEV] = {NULL};
-static struct midi_parms parms[MAX_MIDI_DEV];
-
-static void midi_poll(unsigned long dummy);
-
-
-static DEFINE_TIMER(poll_timer, midi_poll, 0, 0);
-
-static volatile int open_devs;
-static DEFINE_SPINLOCK(lock);
-
-#define DATA_AVAIL(q) (q->len)
-#define SPACE_AVAIL(q) (MAX_QUEUE_SIZE - q->len)
-
-#define QUEUE_BYTE(q, data) \
- if (SPACE_AVAIL(q)) \
- { \
- unsigned long flags; \
- spin_lock_irqsave(&lock, flags); \
- q->queue[q->tail] = (data); \
- q->len++; q->tail = (q->tail+1) % MAX_QUEUE_SIZE; \
- spin_unlock_irqrestore(&lock, flags); \
- }
-
-#define REMOVE_BYTE(q, data) \
- if (DATA_AVAIL(q)) \
- { \
- unsigned long flags; \
- spin_lock_irqsave(&lock, flags); \
- data = q->queue[q->head]; \
- q->len--; q->head = (q->head+1) % MAX_QUEUE_SIZE; \
- spin_unlock_irqrestore(&lock, flags); \
- }
-
-static void drain_midi_queue(int dev)
-{
-
- /*
- * Give the Midi driver time to drain its output queues
- */
-
- if (midi_devs[dev]->buffer_status != NULL)
- while (!signal_pending(current) && midi_devs[dev]->buffer_status(dev))
- interruptible_sleep_on_timeout(&midi_sleeper[dev],
- HZ/10);
-}
-
-static void midi_input_intr(int dev, unsigned char data)
-{
- if (midi_in_buf[dev] == NULL)
- return;
-
- if (data == 0xfe) /*
- * Active sensing
- */
- return; /*
- * Ignore
- */
-
- if (SPACE_AVAIL(midi_in_buf[dev])) {
- QUEUE_BYTE(midi_in_buf[dev], data);
- wake_up(&input_sleeper[dev]);
- }
-}
-
-static void midi_output_intr(int dev)
-{
- /*
- * Currently NOP
- */
-}
-
-static void midi_poll(unsigned long dummy)
-{
- unsigned long flags;
- int dev;
-
- spin_lock_irqsave(&lock, flags);
- if (open_devs)
- {
- for (dev = 0; dev < num_midis; dev++)
- if (midi_devs[dev] != NULL && midi_out_buf[dev] != NULL)
- {
- while (DATA_AVAIL(midi_out_buf[dev]))
- {
- int ok;
- int c = midi_out_buf[dev]->queue[midi_out_buf[dev]->head];
-
- spin_unlock_irqrestore(&lock,flags);/* Give some time to others */
- ok = midi_devs[dev]->outputc(dev, c);
- spin_lock_irqsave(&lock, flags);
- if (!ok)
- break;
- midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE;
- midi_out_buf[dev]->len--;
- }
-
- if (DATA_AVAIL(midi_out_buf[dev]) < 100)
- wake_up(&midi_sleeper[dev]);
- }
- poll_timer.expires = (1) + jiffies;
- add_timer(&poll_timer);
- /*
- * Come back later
- */
- }
- spin_unlock_irqrestore(&lock, flags);
-}
-
-int MIDIbuf_open(int dev, struct file *file)
-{
- int mode, err;
-
- dev = dev >> 4;
- mode = translate_mode(file);
-
- if (num_midis > MAX_MIDI_DEV)
- {
- printk(KERN_ERR "midi: Too many midi interfaces\n");
- num_midis = MAX_MIDI_DEV;
- }
- if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
- return -ENXIO;
- /*
- * Interrupts disabled. Be careful
- */
-
- module_put(midi_devs[dev]->owner);
-
- if ((err = midi_devs[dev]->open(dev, mode,
- midi_input_intr, midi_output_intr)) < 0)
- return err;
-
- parms[dev].prech_timeout = MAX_SCHEDULE_TIMEOUT;
- midi_in_buf[dev] = vmalloc(sizeof(struct midi_buf));
-
- if (midi_in_buf[dev] == NULL)
- {
- printk(KERN_WARNING "midi: Can't allocate buffer\n");
- midi_devs[dev]->close(dev);
- return -EIO;
- }
- midi_in_buf[dev]->len = midi_in_buf[dev]->head = midi_in_buf[dev]->tail = 0;
-
- midi_out_buf[dev] = vmalloc(sizeof(struct midi_buf));
-
- if (midi_out_buf[dev] == NULL)
- {
- printk(KERN_WARNING "midi: Can't allocate buffer\n");
- midi_devs[dev]->close(dev);
- vfree(midi_in_buf[dev]);
- midi_in_buf[dev] = NULL;
- return -EIO;
- }
- midi_out_buf[dev]->len = midi_out_buf[dev]->head = midi_out_buf[dev]->tail = 0;
- open_devs++;
-
- init_waitqueue_head(&midi_sleeper[dev]);
- init_waitqueue_head(&input_sleeper[dev]);
-
- if (open_devs < 2) /* This was first open */
- {
- poll_timer.expires = 1 + jiffies;
- add_timer(&poll_timer); /* Start polling */
- }
- return err;
-}
-
-void MIDIbuf_release(int dev, struct file *file)
-{
- int mode;
-
- dev = dev >> 4;
- mode = translate_mode(file);
-
- if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
- return;
-
- /*
- * Wait until the queue is empty
- */
-
- if (mode != OPEN_READ)
- {
- midi_devs[dev]->outputc(dev, 0xfe); /*
- * Active sensing to shut the
- * devices
- */
-
- while (!signal_pending(current) && DATA_AVAIL(midi_out_buf[dev]))
- interruptible_sleep_on(&midi_sleeper[dev]);
- /*
- * Sync
- */
-
- drain_midi_queue(dev); /*
- * Ensure the output queues are empty
- */
- }
-
- midi_devs[dev]->close(dev);
-
- open_devs--;
- if (open_devs == 0)
- del_timer_sync(&poll_timer);
- vfree(midi_in_buf[dev]);
- vfree(midi_out_buf[dev]);
- midi_in_buf[dev] = NULL;
- midi_out_buf[dev] = NULL;
-
- module_put(midi_devs[dev]->owner);
-}
-
-int MIDIbuf_write(int dev, struct file *file, const char __user *buf, int count)
-{
- int c, n, i;
- unsigned char tmp_data;
-
- dev = dev >> 4;
-
- if (!count)
- return 0;
-
- c = 0;
-
- while (c < count)
- {
- n = SPACE_AVAIL(midi_out_buf[dev]);
-
- if (n == 0) { /*
- * No space just now.
- */
-
- if (file->f_flags & O_NONBLOCK) {
- c = -EAGAIN;
- goto out;
- }
-
- interruptible_sleep_on(&midi_sleeper[dev]);
- if (signal_pending(current))
- {
- c = -EINTR;
- goto out;
- }
- n = SPACE_AVAIL(midi_out_buf[dev]);
- }
- if (n > (count - c))
- n = count - c;
-
- for (i = 0; i < n; i++)
- {
- /* BROKE BROKE BROKE - CAN'T DO THIS WITH CLI !! */
- /* yes, think the same, so I removed the cli() brackets
- QUEUE_BYTE is protected against interrupts */
- if (copy_from_user((char *) &tmp_data, &(buf)[c], 1)) {
- c = -EFAULT;
- goto out;
- }
- QUEUE_BYTE(midi_out_buf[dev], tmp_data);
- c++;
- }
- }
-out:
- return c;
-}
-
-
-int MIDIbuf_read(int dev, struct file *file, char __user *buf, int count)
-{
- int n, c = 0;
- unsigned char tmp_data;
-
- dev = dev >> 4;
-
- if (!DATA_AVAIL(midi_in_buf[dev])) { /*
- * No data yet, wait
- */
- if (file->f_flags & O_NONBLOCK) {
- c = -EAGAIN;
- goto out;
- }
- interruptible_sleep_on_timeout(&input_sleeper[dev],
- parms[dev].prech_timeout);
-
- if (signal_pending(current))
- c = -EINTR; /* The user is getting restless */
- }
- if (c == 0 && DATA_AVAIL(midi_in_buf[dev])) /*
- * Got some bytes
- */
- {
- n = DATA_AVAIL(midi_in_buf[dev]);
- if (n > count)
- n = count;
- c = 0;
-
- while (c < n)
- {
- char *fixit;
- REMOVE_BYTE(midi_in_buf[dev], tmp_data);
- fixit = (char *) &tmp_data;
- /* BROKE BROKE BROKE */
- /* yes removed the cli() brackets again
- should q->len,tail&head be atomic_t? */
- if (copy_to_user(&(buf)[c], fixit, 1)) {
- c = -EFAULT;
- goto out;
- }
- c++;
- }
- }
-out:
- return c;
-}
-
-int MIDIbuf_ioctl(int dev, struct file *file,
- unsigned int cmd, void __user *arg)
-{
- int val;
-
- dev = dev >> 4;
-
- if (((cmd >> 8) & 0xff) == 'C')
- {
- if (midi_devs[dev]->coproc) /* Coprocessor ioctl */
- return midi_devs[dev]->coproc->ioctl(midi_devs[dev]->coproc->devc, cmd, arg, 0);
-/* printk("/dev/midi%d: No coprocessor for this device\n", dev);*/
- return -ENXIO;
- }
- else
- {
- switch (cmd)
- {
- case SNDCTL_MIDI_PRETIME:
- if (get_user(val, (int __user *)arg))
- return -EFAULT;
- if (val < 0)
- val = 0;
- val = (HZ * val) / 10;
- parms[dev].prech_timeout = val;
- return put_user(val, (int __user *)arg);
-
- default:
- if (!midi_devs[dev]->ioctl)
- return -EINVAL;
- return midi_devs[dev]->ioctl(dev, cmd, arg);
- }
- }
-}
-
-/* No kernel lock - fine */
-unsigned int MIDIbuf_poll(int dev, struct file *file, poll_table * wait)
-{
- unsigned int mask = 0;
-
- dev = dev >> 4;
-
- /* input */
- poll_wait(file, &input_sleeper[dev], wait);
- if (DATA_AVAIL(midi_in_buf[dev]))
- mask |= POLLIN | POLLRDNORM;
-
- /* output */
- poll_wait(file, &midi_sleeper[dev], wait);
- if (!SPACE_AVAIL(midi_out_buf[dev]))
- mask |= POLLOUT | POLLWRNORM;
-
- return mask;
-}
-
-
-int MIDIbuf_avail(int dev)
-{
- if (midi_in_buf[dev])
- return DATA_AVAIL (midi_in_buf[dev]);
- return 0;
-}
-EXPORT_SYMBOL(MIDIbuf_avail);
-
diff --git a/ANDROID_3.4.5/sound/oss/mpu401.c b/ANDROID_3.4.5/sound/oss/mpu401.c
deleted file mode 100644
index 25e4609f..00000000
--- a/ANDROID_3.4.5/sound/oss/mpu401.c
+++ /dev/null
@@ -1,1806 +0,0 @@
-/*
- * sound/oss/mpu401.c
- *
- * The low level driver for Roland MPU-401 compatible Midi cards.
- */
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- *
- * Thomas Sailer ioctl code reworked (vmalloc/vfree removed)
- * Alan Cox modularisation, use normal request_irq, use dev_id
- * Bartlomiej Zolnierkiewicz removed some __init to allow using many drivers
- * Chris Rankin Update the module-usage counter for the coprocessor
- * Zwane Mwaikambo Changed attach/unload resource freeing
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#define USE_SEQ_MACROS
-#define USE_SIMPLE_MACROS
-
-#include "sound_config.h"
-
-#include "coproc.h"
-#include "mpu401.h"
-
-static int timer_mode = TMR_INTERNAL, timer_caps = TMR_INTERNAL;
-
-struct mpu_config
-{
- int base; /*
- * I/O base
- */
- int irq;
- int opened; /*
- * Open mode
- */
- int devno;
- int synthno;
- int uart_mode;
- int initialized;
- int mode;
-#define MODE_MIDI 1
-#define MODE_SYNTH 2
- unsigned char version, revision;
- unsigned int capabilities;
-#define MPU_CAP_INTLG 0x10000000
-#define MPU_CAP_SYNC 0x00000010
-#define MPU_CAP_FSK 0x00000020
-#define MPU_CAP_CLS 0x00000040
-#define MPU_CAP_SMPTE 0x00000080
-#define MPU_CAP_2PORT 0x00000001
- int timer_flag;
-
-#define MBUF_MAX 10
-#define BUFTEST(dc) if (dc->m_ptr >= MBUF_MAX || dc->m_ptr < 0) \
- {printk( "MPU: Invalid buffer pointer %d/%d, s=%d\n", dc->m_ptr, dc->m_left, dc->m_state);dc->m_ptr--;}
- int m_busy;
- unsigned char m_buf[MBUF_MAX];
- int m_ptr;
- int m_state;
- int m_left;
- unsigned char last_status;
- void (*inputintr) (int dev, unsigned char data);
- int shared_irq;
- int *osp;
- spinlock_t lock;
- };
-
-#define DATAPORT(base) (base)
-#define COMDPORT(base) (base+1)
-#define STATPORT(base) (base+1)
-
-
-static void mpu401_close(int dev);
-
-static inline int mpu401_status(struct mpu_config *devc)
-{
- return inb(STATPORT(devc->base));
-}
-
-#define input_avail(devc) (!(mpu401_status(devc)&INPUT_AVAIL))
-#define output_ready(devc) (!(mpu401_status(devc)&OUTPUT_READY))
-
-static inline void write_command(struct mpu_config *devc, unsigned char cmd)
-{
- outb(cmd, COMDPORT(devc->base));
-}
-
-static inline int read_data(struct mpu_config *devc)
-{
- return inb(DATAPORT(devc->base));
-}
-
-static inline void write_data(struct mpu_config *devc, unsigned char byte)
-{
- outb(byte, DATAPORT(devc->base));
-}
-
-#define OUTPUT_READY 0x40
-#define INPUT_AVAIL 0x80
-#define MPU_ACK 0xFE
-#define MPU_RESET 0xFF
-#define UART_MODE_ON 0x3F
-
-static struct mpu_config dev_conf[MAX_MIDI_DEV];
-
-static int n_mpu_devs;
-
-static int reset_mpu401(struct mpu_config *devc);
-static void set_uart_mode(int dev, struct mpu_config *devc, int arg);
-
-static int mpu_timer_init(int midi_dev);
-static void mpu_timer_interrupt(void);
-static void timer_ext_event(struct mpu_config *devc, int event, int parm);
-
-static struct synth_info mpu_synth_info_proto = {
- "MPU-401 MIDI interface",
- 0,
- SYNTH_TYPE_MIDI,
- MIDI_TYPE_MPU401,
- 0, 128,
- 0, 128,
- SYNTH_CAP_INPUT
-};
-
-static struct synth_info mpu_synth_info[MAX_MIDI_DEV];
-
-/*
- * States for the input scanner
- */
-
-#define ST_INIT 0 /* Ready for timing byte or msg */
-#define ST_TIMED 1 /* Leading timing byte rcvd */
-#define ST_DATABYTE 2 /* Waiting for (nr_left) data bytes */
-
-#define ST_SYSMSG 100 /* System message (sysx etc). */
-#define ST_SYSEX 101 /* System exclusive msg */
-#define ST_MTC 102 /* Midi Time Code (MTC) qframe msg */
-#define ST_SONGSEL 103 /* Song select */
-#define ST_SONGPOS 104 /* Song position pointer */
-
-static unsigned char len_tab[] = /* # of data bytes following a status
- */
-{
- 2, /* 8x */
- 2, /* 9x */
- 2, /* Ax */
- 2, /* Bx */
- 1, /* Cx */
- 1, /* Dx */
- 2, /* Ex */
- 0 /* Fx */
-};
-
-#define STORE(cmd) \
-{ \
- int len; \
- unsigned char obuf[8]; \
- cmd; \
- seq_input_event(obuf, len); \
-}
-
-#define _seqbuf obuf
-#define _seqbufptr 0
-#define _SEQ_ADVBUF(x) len=x
-
-static int mpu_input_scanner(struct mpu_config *devc, unsigned char midic)
-{
-
- switch (devc->m_state)
- {
- case ST_INIT:
- switch (midic)
- {
- case 0xf8:
- /* Timer overflow */
- break;
-
- case 0xfc:
- printk("<all end>");
- break;
-
- case 0xfd:
- if (devc->timer_flag)
- mpu_timer_interrupt();
- break;
-
- case 0xfe:
- return MPU_ACK;
-
- case 0xf0:
- case 0xf1:
- case 0xf2:
- case 0xf3:
- case 0xf4:
- case 0xf5:
- case 0xf6:
- case 0xf7:
- printk("<Trk data rq #%d>", midic & 0x0f);
- break;
-
- case 0xf9:
- printk("<conductor rq>");
- break;
-
- case 0xff:
- devc->m_state = ST_SYSMSG;
- break;
-
- default:
- if (midic <= 0xef)
- {
- /* printk( "mpu time: %d ", midic); */
- devc->m_state = ST_TIMED;
- }
- else
- printk("<MPU: Unknown event %02x> ", midic);
- }
- break;
-
- case ST_TIMED:
- {
- int msg = ((int) (midic & 0xf0) >> 4);
-
- devc->m_state = ST_DATABYTE;
-
- if (msg < 8) /* Data byte */
- {
- /* printk( "midi msg (running status) "); */
- msg = ((int) (devc->last_status & 0xf0) >> 4);
- msg -= 8;
- devc->m_left = len_tab[msg] - 1;
-
- devc->m_ptr = 2;
- devc->m_buf[0] = devc->last_status;
- devc->m_buf[1] = midic;
-
- if (devc->m_left <= 0)
- {
- devc->m_state = ST_INIT;
- do_midi_msg(devc->synthno, devc->m_buf, devc->m_ptr);
- devc->m_ptr = 0;
- }
- }
- else if (msg == 0xf) /* MPU MARK */
- {
- devc->m_state = ST_INIT;
-
- switch (midic)
- {
- case 0xf8:
- /* printk( "NOP "); */
- break;
-
- case 0xf9:
- /* printk( "meas end "); */
- break;
-
- case 0xfc:
- /* printk( "data end "); */
- break;
-
- default:
- printk("Unknown MPU mark %02x\n", midic);
- }
- }
- else
- {
- devc->last_status = midic;
- /* printk( "midi msg "); */
- msg -= 8;
- devc->m_left = len_tab[msg];
-
- devc->m_ptr = 1;
- devc->m_buf[0] = midic;
-
- if (devc->m_left <= 0)
- {
- devc->m_state = ST_INIT;
- do_midi_msg(devc->synthno, devc->m_buf, devc->m_ptr);
- devc->m_ptr = 0;
- }
- }
- }
- break;
-
- case ST_SYSMSG:
- switch (midic)
- {
- case 0xf0:
- printk("<SYX>");
- devc->m_state = ST_SYSEX;
- break;
-
- case 0xf1:
- devc->m_state = ST_MTC;
- break;
-
- case 0xf2:
- devc->m_state = ST_SONGPOS;
- devc->m_ptr = 0;
- break;
-
- case 0xf3:
- devc->m_state = ST_SONGSEL;
- break;
-
- case 0xf6:
- /* printk( "tune_request\n"); */
- devc->m_state = ST_INIT;
-
- /*
- * Real time messages
- */
- case 0xf8:
- /* midi clock */
- devc->m_state = ST_INIT;
- timer_ext_event(devc, TMR_CLOCK, 0);
- break;
-
- case 0xfA:
- devc->m_state = ST_INIT;
- timer_ext_event(devc, TMR_START, 0);
- break;
-
- case 0xFB:
- devc->m_state = ST_INIT;
- timer_ext_event(devc, TMR_CONTINUE, 0);
- break;
-
- case 0xFC:
- devc->m_state = ST_INIT;
- timer_ext_event(devc, TMR_STOP, 0);
- break;
-
- case 0xFE:
- /* active sensing */
- devc->m_state = ST_INIT;
- break;
-
- case 0xff:
- /* printk( "midi hard reset"); */
- devc->m_state = ST_INIT;
- break;
-
- default:
- printk("unknown MIDI sysmsg %0x\n", midic);
- devc->m_state = ST_INIT;
- }
- break;
-
- case ST_MTC:
- devc->m_state = ST_INIT;
- printk("MTC frame %x02\n", midic);
- break;
-
- case ST_SYSEX:
- if (midic == 0xf7)
- {
- printk("<EOX>");
- devc->m_state = ST_INIT;
- }
- else
- printk("%02x ", midic);
- break;
-
- case ST_SONGPOS:
- BUFTEST(devc);
- devc->m_buf[devc->m_ptr++] = midic;
- if (devc->m_ptr == 2)
- {
- devc->m_state = ST_INIT;
- devc->m_ptr = 0;
- timer_ext_event(devc, TMR_SPP,
- ((devc->m_buf[1] & 0x7f) << 7) |
- (devc->m_buf[0] & 0x7f));
- }
- break;
-
- case ST_DATABYTE:
- BUFTEST(devc);
- devc->m_buf[devc->m_ptr++] = midic;
- if ((--devc->m_left) <= 0)
- {
- devc->m_state = ST_INIT;
- do_midi_msg(devc->synthno, devc->m_buf, devc->m_ptr);
- devc->m_ptr = 0;
- }
- break;
-
- default:
- printk("Bad state %d ", devc->m_state);
- devc->m_state = ST_INIT;
- }
- return 1;
-}
-
-static void mpu401_input_loop(struct mpu_config *devc)
-{
- unsigned long flags;
- int busy;
- int n;
-
- spin_lock_irqsave(&devc->lock,flags);
- busy = devc->m_busy;
- devc->m_busy = 1;
- spin_unlock_irqrestore(&devc->lock,flags);
-
- if (busy) /* Already inside the scanner */
- return;
-
- n = 50;
-
- while (input_avail(devc) && n-- > 0)
- {
- unsigned char c = read_data(devc);
-
- if (devc->mode == MODE_SYNTH)
- {
- mpu_input_scanner(devc, c);
- }
- else if (devc->opened & OPEN_READ && devc->inputintr != NULL)
- devc->inputintr(devc->devno, c);
- }
- devc->m_busy = 0;
-}
-
-static irqreturn_t mpuintr(int irq, void *dev_id)
-{
- struct mpu_config *devc;
- int dev = (int)(unsigned long) dev_id;
- int handled = 0;
-
- devc = &dev_conf[dev];
-
- if (input_avail(devc))
- {
- handled = 1;
- if (devc->base != 0 && (devc->opened & OPEN_READ || devc->mode == MODE_SYNTH))
- mpu401_input_loop(devc);
- else
- {
- /* Dummy read (just to acknowledge the interrupt) */
- read_data(devc);
- }
- }
- return IRQ_RETVAL(handled);
-}
-
-static int mpu401_open(int dev, int mode,
- void (*input) (int dev, unsigned char data),
- void (*output) (int dev)
-)
-{
- int err;
- struct mpu_config *devc;
- struct coproc_operations *coprocessor;
-
- if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
- return -ENXIO;
-
- devc = &dev_conf[dev];
-
- if (devc->opened)
- return -EBUSY;
- /*
- * Verify that the device is really running.
- * Some devices (such as Ensoniq SoundScape don't
- * work before the on board processor (OBP) is initialized
- * by downloading its microcode.
- */
-
- if (!devc->initialized)
- {
- if (mpu401_status(devc) == 0xff) /* Bus float */
- {
- printk(KERN_ERR "mpu401: Device not initialized properly\n");
- return -EIO;
- }
- reset_mpu401(devc);
- }
-
- if ( (coprocessor = midi_devs[dev]->coproc) != NULL )
- {
- if (!try_module_get(coprocessor->owner)) {
- mpu401_close(dev);
- return -ENODEV;
- }
-
- if ((err = coprocessor->open(coprocessor->devc, COPR_MIDI)) < 0)
- {
- printk(KERN_WARNING "MPU-401: Can't access coprocessor device\n");
- mpu401_close(dev);
- return err;
- }
- }
-
- set_uart_mode(dev, devc, 1);
- devc->mode = MODE_MIDI;
- devc->synthno = 0;
-
- mpu401_input_loop(devc);
-
- devc->inputintr = input;
- devc->opened = mode;
-
- return 0;
-}
-
-static void mpu401_close(int dev)
-{
- struct mpu_config *devc;
- struct coproc_operations *coprocessor;
-
- devc = &dev_conf[dev];
- if (devc->uart_mode)
- reset_mpu401(devc); /*
- * This disables the UART mode
- */
- devc->mode = 0;
- devc->inputintr = NULL;
-
- coprocessor = midi_devs[dev]->coproc;
- if (coprocessor) {
- coprocessor->close(coprocessor->devc, COPR_MIDI);
- module_put(coprocessor->owner);
- }
- devc->opened = 0;
-}
-
-static int mpu401_out(int dev, unsigned char midi_byte)
-{
- int timeout;
- unsigned long flags;
-
- struct mpu_config *devc;
-
- devc = &dev_conf[dev];
-
- /*
- * Sometimes it takes about 30000 loops before the output becomes ready
- * (After reset). Normally it takes just about 10 loops.
- */
-
- for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
-
- spin_lock_irqsave(&devc->lock,flags);
- if (!output_ready(devc))
- {
- printk(KERN_WARNING "mpu401: Send data timeout\n");
- spin_unlock_irqrestore(&devc->lock,flags);
- return 0;
- }
- write_data(devc, midi_byte);
- spin_unlock_irqrestore(&devc->lock,flags);
- return 1;
-}
-
-static int mpu401_command(int dev, mpu_command_rec * cmd)
-{
- int i, timeout, ok;
- int ret = 0;
- unsigned long flags;
- struct mpu_config *devc;
-
- devc = &dev_conf[dev];
-
- if (devc->uart_mode) /*
- * Not possible in UART mode
- */
- {
- printk(KERN_WARNING "mpu401: commands not possible in the UART mode\n");
- return -EINVAL;
- }
- /*
- * Test for input since pending input seems to block the output.
- */
- if (input_avail(devc))
- mpu401_input_loop(devc);
-
- /*
- * Sometimes it takes about 50000 loops before the output becomes ready
- * (After reset). Normally it takes just about 10 loops.
- */
-
- timeout = 50000;
-retry:
- if (timeout-- <= 0)
- {
- printk(KERN_WARNING "mpu401: Command (0x%x) timeout\n", (int) cmd->cmd);
- return -EIO;
- }
- spin_lock_irqsave(&devc->lock,flags);
-
- if (!output_ready(devc))
- {
- spin_unlock_irqrestore(&devc->lock,flags);
- goto retry;
- }
- write_command(devc, cmd->cmd);
-
- ok = 0;
- for (timeout = 50000; timeout > 0 && !ok; timeout--)
- {
- if (input_avail(devc))
- {
- if (devc->opened && devc->mode == MODE_SYNTH)
- {
- if (mpu_input_scanner(devc, read_data(devc)) == MPU_ACK)
- ok = 1;
- }
- else
- {
- /* Device is not currently open. Use simpler method */
- if (read_data(devc) == MPU_ACK)
- ok = 1;
- }
- }
- }
- if (!ok)
- {
- spin_unlock_irqrestore(&devc->lock,flags);
- return -EIO;
- }
- if (cmd->nr_args)
- {
- for (i = 0; i < cmd->nr_args; i++)
- {
- for (timeout = 3000; timeout > 0 && !output_ready(devc); timeout--);
-
- if (!mpu401_out(dev, cmd->data[i]))
- {
- spin_unlock_irqrestore(&devc->lock,flags);
- printk(KERN_WARNING "mpu401: Command (0x%x), parm send failed.\n", (int) cmd->cmd);
- return -EIO;
- }
- }
- }
- ret = 0;
- cmd->data[0] = 0;
-
- if (cmd->nr_returns)
- {
- for (i = 0; i < cmd->nr_returns; i++)
- {
- ok = 0;
- for (timeout = 5000; timeout > 0 && !ok; timeout--)
- if (input_avail(devc))
- {
- cmd->data[i] = read_data(devc);
- ok = 1;
- }
- if (!ok)
- {
- spin_unlock_irqrestore(&devc->lock,flags);
- return -EIO;
- }
- }
- }
- spin_unlock_irqrestore(&devc->lock,flags);
- return ret;
-}
-
-static int mpu_cmd(int dev, int cmd, int data)
-{
- int ret;
-
- static mpu_command_rec rec;
-
- rec.cmd = cmd & 0xff;
- rec.nr_args = ((cmd & 0xf0) == 0xE0);
- rec.nr_returns = ((cmd & 0xf0) == 0xA0);
- rec.data[0] = data & 0xff;
-
- if ((ret = mpu401_command(dev, &rec)) < 0)
- return ret;
- return (unsigned char) rec.data[0];
-}
-
-static int mpu401_prefix_cmd(int dev, unsigned char status)
-{
- struct mpu_config *devc = &dev_conf[dev];
-
- if (devc->uart_mode)
- return 1;
-
- if (status < 0xf0)
- {
- if (mpu_cmd(dev, 0xD0, 0) < 0)
- return 0;
- return 1;
- }
- switch (status)
- {
- case 0xF0:
- if (mpu_cmd(dev, 0xDF, 0) < 0)
- return 0;
- return 1;
-
- default:
- return 0;
- }
-}
-
-static int mpu401_start_read(int dev)
-{
- return 0;
-}
-
-static int mpu401_end_read(int dev)
-{
- return 0;
-}
-
-static int mpu401_ioctl(int dev, unsigned cmd, void __user *arg)
-{
- struct mpu_config *devc;
- mpu_command_rec rec;
- int val, ret;
-
- devc = &dev_conf[dev];
- switch (cmd)
- {
- case SNDCTL_MIDI_MPUMODE:
- if (!(devc->capabilities & MPU_CAP_INTLG)) { /* No intelligent mode */
- printk(KERN_WARNING "mpu401: Intelligent mode not supported by the HW\n");
- return -EINVAL;
- }
- if (get_user(val, (int __user *)arg))
- return -EFAULT;
- set_uart_mode(dev, devc, !val);
- return 0;
-
- case SNDCTL_MIDI_MPUCMD:
- if (copy_from_user(&rec, arg, sizeof(rec)))
- return -EFAULT;
- if ((ret = mpu401_command(dev, &rec)) < 0)
- return ret;
- if (copy_to_user(arg, &rec, sizeof(rec)))
- return -EFAULT;
- return 0;
-
- default:
- return -EINVAL;
- }
-}
-
-static void mpu401_kick(int dev)
-{
-}
-
-static int mpu401_buffer_status(int dev)
-{
- return 0; /*
- * No data in buffers
- */
-}
-
-static int mpu_synth_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
- int midi_dev;
- struct mpu_config *devc;
-
- midi_dev = synth_devs[dev]->midi_dev;
-
- if (midi_dev < 0 || midi_dev >= num_midis || midi_devs[midi_dev] == NULL)
- return -ENXIO;
-
- devc = &dev_conf[midi_dev];
-
- switch (cmd)
- {
-
- case SNDCTL_SYNTH_INFO:
- if (copy_to_user(arg, &mpu_synth_info[midi_dev],
- sizeof(struct synth_info)))
- return -EFAULT;
- return 0;
-
- case SNDCTL_SYNTH_MEMAVL:
- return 0x7fffffff;
-
- default:
- return -EINVAL;
- }
-}
-
-static int mpu_synth_open(int dev, int mode)
-{
- int midi_dev, err;
- struct mpu_config *devc;
- struct coproc_operations *coprocessor;
-
- midi_dev = synth_devs[dev]->midi_dev;
-
- if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev] == NULL)
- return -ENXIO;
-
- devc = &dev_conf[midi_dev];
-
- /*
- * Verify that the device is really running.
- * Some devices (such as Ensoniq SoundScape don't
- * work before the on board processor (OBP) is initialized
- * by downloading its microcode.
- */
-
- if (!devc->initialized)
- {
- if (mpu401_status(devc) == 0xff) /* Bus float */
- {
- printk(KERN_ERR "mpu401: Device not initialized properly\n");
- return -EIO;
- }
- reset_mpu401(devc);
- }
- if (devc->opened)
- return -EBUSY;
- devc->mode = MODE_SYNTH;
- devc->synthno = dev;
-
- devc->inputintr = NULL;
-
- coprocessor = midi_devs[midi_dev]->coproc;
- if (coprocessor) {
- if (!try_module_get(coprocessor->owner))
- return -ENODEV;
-
- if ((err = coprocessor->open(coprocessor->devc, COPR_MIDI)) < 0)
- {
- printk(KERN_WARNING "mpu401: Can't access coprocessor device\n");
- return err;
- }
- }
- devc->opened = mode;
- reset_mpu401(devc);
-
- if (mode & OPEN_READ)
- {
- mpu_cmd(midi_dev, 0x8B, 0); /* Enable data in stop mode */
- mpu_cmd(midi_dev, 0x34, 0); /* Return timing bytes in stop mode */
- mpu_cmd(midi_dev, 0x87, 0); /* Enable pitch & controller */
- }
- return 0;
-}
-
-static void mpu_synth_close(int dev)
-{
- int midi_dev;
- struct mpu_config *devc;
- struct coproc_operations *coprocessor;
-
- midi_dev = synth_devs[dev]->midi_dev;
-
- devc = &dev_conf[midi_dev];
- mpu_cmd(midi_dev, 0x15, 0); /* Stop recording, playback and MIDI */
- mpu_cmd(midi_dev, 0x8a, 0); /* Disable data in stopped mode */
-
- devc->inputintr = NULL;
-
- coprocessor = midi_devs[midi_dev]->coproc;
- if (coprocessor) {
- coprocessor->close(coprocessor->devc, COPR_MIDI);
- module_put(coprocessor->owner);
- }
- devc->opened = 0;
- devc->mode = 0;
-}
-
-#define MIDI_SYNTH_NAME "MPU-401 UART Midi"
-#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
-#include "midi_synth.h"
-
-static struct synth_operations mpu401_synth_proto =
-{
- .owner = THIS_MODULE,
- .id = "MPU401",
- .info = NULL,
- .midi_dev = 0,
- .synth_type = SYNTH_TYPE_MIDI,
- .synth_subtype = 0,
- .open = mpu_synth_open,
- .close = mpu_synth_close,
- .ioctl = mpu_synth_ioctl,
- .kill_note = midi_synth_kill_note,
- .start_note = midi_synth_start_note,
- .set_instr = midi_synth_set_instr,
- .reset = midi_synth_reset,
- .hw_control = midi_synth_hw_control,
- .load_patch = midi_synth_load_patch,
- .aftertouch = midi_synth_aftertouch,
- .controller = midi_synth_controller,
- .panning = midi_synth_panning,
- .bender = midi_synth_bender,
- .setup_voice = midi_synth_setup_voice,
- .send_sysex = midi_synth_send_sysex
-};
-
-static struct synth_operations *mpu401_synth_operations[MAX_MIDI_DEV];
-
-static struct midi_operations mpu401_midi_proto =
-{
- .owner = THIS_MODULE,
- .info = {"MPU-401 Midi", 0, MIDI_CAP_MPU401, SNDCARD_MPU401},
- .in_info = {0},
- .open = mpu401_open,
- .close = mpu401_close,
- .ioctl = mpu401_ioctl,
- .outputc = mpu401_out,
- .start_read = mpu401_start_read,
- .end_read = mpu401_end_read,
- .kick = mpu401_kick,
- .buffer_status = mpu401_buffer_status,
- .prefix_cmd = mpu401_prefix_cmd
-};
-
-static struct midi_operations mpu401_midi_operations[MAX_MIDI_DEV];
-
-static void mpu401_chk_version(int n, struct mpu_config *devc)
-{
- int tmp;
-
- devc->version = devc->revision = 0;
-
- tmp = mpu_cmd(n, 0xAC, 0);
- if (tmp < 0)
- return;
- if ((tmp & 0xf0) > 0x20) /* Why it's larger than 2.x ??? */
- return;
- devc->version = tmp;
-
- if ((tmp = mpu_cmd(n, 0xAD, 0)) < 0) {
- devc->version = 0;
- return;
- }
- devc->revision = tmp;
-}
-
-int attach_mpu401(struct address_info *hw_config, struct module *owner)
-{
- unsigned long flags;
- char revision_char;
-
- int m, ret;
- struct mpu_config *devc;
-
- hw_config->slots[1] = -1;
- m = sound_alloc_mididev();
- if (m == -1)
- {
- printk(KERN_WARNING "MPU-401: Too many midi devices detected\n");
- ret = -ENOMEM;
- goto out_err;
- }
- devc = &dev_conf[m];
- devc->base = hw_config->io_base;
- devc->osp = hw_config->osp;
- devc->irq = hw_config->irq;
- devc->opened = 0;
- devc->uart_mode = 0;
- devc->initialized = 0;
- devc->version = 0;
- devc->revision = 0;
- devc->capabilities = 0;
- devc->timer_flag = 0;
- devc->m_busy = 0;
- devc->m_state = ST_INIT;
- devc->shared_irq = hw_config->always_detect;
- devc->irq = hw_config->irq;
- spin_lock_init(&devc->lock);
-
- if (devc->irq < 0)
- {
- devc->irq *= -1;
- devc->shared_irq = 1;
- }
-
- if (!hw_config->always_detect)
- {
- /* Verify the hardware again */
- if (!reset_mpu401(devc))
- {
- printk(KERN_WARNING "mpu401: Device didn't respond\n");
- ret = -ENODEV;
- goto out_mididev;
- }
- if (!devc->shared_irq)
- {
- if (request_irq(devc->irq, mpuintr, 0, "mpu401",
- hw_config) < 0)
- {
- printk(KERN_WARNING "mpu401: Failed to allocate IRQ%d\n", devc->irq);
- ret = -ENOMEM;
- goto out_mididev;
- }
- }
- spin_lock_irqsave(&devc->lock,flags);
- mpu401_chk_version(m, devc);
- if (devc->version == 0)
- mpu401_chk_version(m, devc);
- spin_unlock_irqrestore(&devc->lock, flags);
- }
-
- if (devc->version != 0)
- if (mpu_cmd(m, 0xC5, 0) >= 0) /* Set timebase OK */
- if (mpu_cmd(m, 0xE0, 120) >= 0) /* Set tempo OK */
- devc->capabilities |= MPU_CAP_INTLG; /* Supports intelligent mode */
-
-
- mpu401_synth_operations[m] = kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
-
- if (mpu401_synth_operations[m] == NULL)
- {
- printk(KERN_ERR "mpu401: Can't allocate memory\n");
- ret = -ENOMEM;
- goto out_irq;
- }
- if (!(devc->capabilities & MPU_CAP_INTLG)) /* No intelligent mode */
- {
- memcpy((char *) mpu401_synth_operations[m],
- (char *) &std_midi_synth,
- sizeof(struct synth_operations));
- }
- else
- {
- memcpy((char *) mpu401_synth_operations[m],
- (char *) &mpu401_synth_proto,
- sizeof(struct synth_operations));
- }
- if (owner)
- mpu401_synth_operations[m]->owner = owner;
-
- memcpy((char *) &mpu401_midi_operations[m],
- (char *) &mpu401_midi_proto,
- sizeof(struct midi_operations));
-
- mpu401_midi_operations[m].converter = mpu401_synth_operations[m];
-
- memcpy((char *) &mpu_synth_info[m],
- (char *) &mpu_synth_info_proto,
- sizeof(struct synth_info));
-
- n_mpu_devs++;
-
- if (devc->version == 0x20 && devc->revision >= 0x07) /* MusicQuest interface */
- {
- int ports = (devc->revision & 0x08) ? 32 : 16;
-
- devc->capabilities |= MPU_CAP_SYNC | MPU_CAP_SMPTE |
- MPU_CAP_CLS | MPU_CAP_2PORT;
-
- revision_char = (devc->revision == 0x7f) ? 'M' : ' ';
- sprintf(mpu_synth_info[m].name, "MQX-%d%c MIDI Interface #%d",
- ports,
- revision_char,
- n_mpu_devs);
- }
- else
- {
- revision_char = devc->revision ? devc->revision + '@' : ' ';
- if ((int) devc->revision > ('Z' - '@'))
- revision_char = '+';
-
- devc->capabilities |= MPU_CAP_SYNC | MPU_CAP_FSK;
-
- if (hw_config->name)
- sprintf(mpu_synth_info[m].name, "%s (MPU401)", hw_config->name);
- else
- sprintf(mpu_synth_info[m].name,
- "MPU-401 %d.%d%c MIDI #%d",
- (int) (devc->version & 0xf0) >> 4,
- devc->version & 0x0f,
- revision_char,
- n_mpu_devs);
- }
-
- strcpy(mpu401_midi_operations[m].info.name,
- mpu_synth_info[m].name);
-
- conf_printf(mpu_synth_info[m].name, hw_config);
-
- mpu401_synth_operations[m]->midi_dev = devc->devno = m;
- mpu401_synth_operations[devc->devno]->info = &mpu_synth_info[devc->devno];
-
- if (devc->capabilities & MPU_CAP_INTLG) /* Intelligent mode */
- hw_config->slots[2] = mpu_timer_init(m);
-
- midi_devs[m] = &mpu401_midi_operations[devc->devno];
-
- if (owner)
- midi_devs[m]->owner = owner;
-
- hw_config->slots[1] = m;
- sequencer_init();
-
- return 0;
-
-out_irq:
- free_irq(devc->irq, hw_config);
-out_mididev:
- sound_unload_mididev(m);
-out_err:
- release_region(hw_config->io_base, 2);
- return ret;
-}
-
-static int reset_mpu401(struct mpu_config *devc)
-{
- unsigned long flags;
- int ok, timeout, n;
- int timeout_limit;
-
- /*
- * Send the RESET command. Try again if no success at the first time.
- * (If the device is in the UART mode, it will not ack the reset cmd).
- */
-
- ok = 0;
-
- timeout_limit = devc->initialized ? 30000 : 100000;
- devc->initialized = 1;
-
- for (n = 0; n < 2 && !ok; n++)
- {
- for (timeout = timeout_limit; timeout > 0 && !ok; timeout--)
- ok = output_ready(devc);
-
- write_command(devc, MPU_RESET); /*
- * Send MPU-401 RESET Command
- */
-
- /*
- * Wait at least 25 msec. This method is not accurate so let's make the
- * loop bit longer. Cannot sleep since this is called during boot.
- */
-
- for (timeout = timeout_limit * 2; timeout > 0 && !ok; timeout--)
- {
- spin_lock_irqsave(&devc->lock,flags);
- if (input_avail(devc))
- if (read_data(devc) == MPU_ACK)
- ok = 1;
- spin_unlock_irqrestore(&devc->lock,flags);
- }
-
- }
-
- devc->m_state = ST_INIT;
- devc->m_ptr = 0;
- devc->m_left = 0;
- devc->last_status = 0;
- devc->uart_mode = 0;
-
- return ok;
-}
-
-static void set_uart_mode(int dev, struct mpu_config *devc, int arg)
-{
- if (!arg && (devc->capabilities & MPU_CAP_INTLG))
- return;
- if ((devc->uart_mode == 0) == (arg == 0))
- return; /* Already set */
- reset_mpu401(devc); /* This exits the uart mode */
-
- if (arg)
- {
- if (mpu_cmd(dev, UART_MODE_ON, 0) < 0)
- {
- printk(KERN_ERR "mpu401: Can't enter UART mode\n");
- devc->uart_mode = 0;
- return;
- }
- }
- devc->uart_mode = arg;
-
-}
-
-int probe_mpu401(struct address_info *hw_config, struct resource *ports)
-{
- int ok = 0;
- struct mpu_config tmp_devc;
-
- tmp_devc.base = hw_config->io_base;
- tmp_devc.irq = hw_config->irq;
- tmp_devc.initialized = 0;
- tmp_devc.opened = 0;
- tmp_devc.osp = hw_config->osp;
-
- if (hw_config->always_detect)
- return 1;
-
- if (inb(hw_config->io_base + 1) == 0xff)
- {
- DDB(printk("MPU401: Port %x looks dead.\n", hw_config->io_base));
- return 0; /* Just bus float? */
- }
- ok = reset_mpu401(&tmp_devc);
-
- if (!ok)
- {
- DDB(printk("MPU401: Reset failed on port %x\n", hw_config->io_base));
- }
- return ok;
-}
-
-void unload_mpu401(struct address_info *hw_config)
-{
- void *p;
- int n=hw_config->slots[1];
-
- if (n != -1) {
- release_region(hw_config->io_base, 2);
- if (hw_config->always_detect == 0 && hw_config->irq > 0)
- free_irq(hw_config->irq, hw_config);
- p=mpu401_synth_operations[n];
- sound_unload_mididev(n);
- sound_unload_timerdev(hw_config->slots[2]);
- kfree(p);
- }
-}
-
-/*****************************************************
- * Timer stuff
- ****************************************************/
-
-static volatile int timer_initialized = 0, timer_open = 0, tmr_running = 0;
-static volatile int curr_tempo, curr_timebase, hw_timebase;
-static int max_timebase = 8; /* 8*24=192 ppqn */
-static volatile unsigned long next_event_time;
-static volatile unsigned long curr_ticks, curr_clocks;
-static unsigned long prev_event_time;
-static int metronome_mode;
-
-static unsigned long clocks2ticks(unsigned long clocks)
-{
- /*
- * The MPU-401 supports just a limited set of possible timebase values.
- * Since the applications require more choices, the driver has to
- * program the HW to do its best and to convert between the HW and
- * actual timebases.
- */
- return ((clocks * curr_timebase) + (hw_timebase / 2)) / hw_timebase;
-}
-
-static void set_timebase(int midi_dev, int val)
-{
- int hw_val;
-
- if (val < 48)
- val = 48;
- if (val > 1000)
- val = 1000;
-
- hw_val = val;
- hw_val = (hw_val + 12) / 24;
- if (hw_val > max_timebase)
- hw_val = max_timebase;
-
- if (mpu_cmd(midi_dev, 0xC0 | (hw_val & 0x0f), 0) < 0)
- {
- printk(KERN_WARNING "mpu401: Can't set HW timebase to %d\n", hw_val * 24);
- return;
- }
- hw_timebase = hw_val * 24;
- curr_timebase = val;
-
-}
-
-static void tmr_reset(struct mpu_config *devc)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&devc->lock,flags);
- next_event_time = (unsigned long) -1;
- prev_event_time = 0;
- curr_ticks = curr_clocks = 0;
- spin_unlock_irqrestore(&devc->lock,flags);
-}
-
-static void set_timer_mode(int midi_dev)
-{
- if (timer_mode & TMR_MODE_CLS)
- mpu_cmd(midi_dev, 0x3c, 0); /* Use CLS sync */
- else if (timer_mode & TMR_MODE_SMPTE)
- mpu_cmd(midi_dev, 0x3d, 0); /* Use SMPTE sync */
-
- if (timer_mode & TMR_INTERNAL)
- {
- mpu_cmd(midi_dev, 0x80, 0); /* Use MIDI sync */
- }
- else
- {
- if (timer_mode & (TMR_MODE_MIDI | TMR_MODE_CLS))
- {
- mpu_cmd(midi_dev, 0x82, 0); /* Use MIDI sync */
- mpu_cmd(midi_dev, 0x91, 0); /* Enable ext MIDI ctrl */
- }
- else if (timer_mode & TMR_MODE_FSK)
- mpu_cmd(midi_dev, 0x81, 0); /* Use FSK sync */
- }
-}
-
-static void stop_metronome(int midi_dev)
-{
- mpu_cmd(midi_dev, 0x84, 0); /* Disable metronome */
-}
-
-static void setup_metronome(int midi_dev)
-{
- int numerator, denominator;
- int clks_per_click, num_32nds_per_beat;
- int beats_per_measure;
-
- numerator = ((unsigned) metronome_mode >> 24) & 0xff;
- denominator = ((unsigned) metronome_mode >> 16) & 0xff;
- clks_per_click = ((unsigned) metronome_mode >> 8) & 0xff;
- num_32nds_per_beat = (unsigned) metronome_mode & 0xff;
- beats_per_measure = (numerator * 4) >> denominator;
-
- if (!metronome_mode)
- mpu_cmd(midi_dev, 0x84, 0); /* Disable metronome */
- else
- {
- mpu_cmd(midi_dev, 0xE4, clks_per_click);
- mpu_cmd(midi_dev, 0xE6, beats_per_measure);
- mpu_cmd(midi_dev, 0x83, 0); /* Enable metronome without accents */
- }
-}
-
-static int mpu_start_timer(int midi_dev)
-{
- struct mpu_config *devc= &dev_conf[midi_dev];
-
- tmr_reset(devc);
- set_timer_mode(midi_dev);
-
- if (tmr_running)
- return TIMER_NOT_ARMED; /* Already running */
-
- if (timer_mode & TMR_INTERNAL)
- {
- mpu_cmd(midi_dev, 0x02, 0); /* Send MIDI start */
- tmr_running = 1;
- return TIMER_NOT_ARMED;
- }
- else
- {
- mpu_cmd(midi_dev, 0x35, 0); /* Enable mode messages to PC */
- mpu_cmd(midi_dev, 0x38, 0); /* Enable sys common messages to PC */
- mpu_cmd(midi_dev, 0x39, 0); /* Enable real time messages to PC */
- mpu_cmd(midi_dev, 0x97, 0); /* Enable system exclusive messages to PC */
- }
- return TIMER_ARMED;
-}
-
-static int mpu_timer_open(int dev, int mode)
-{
- int midi_dev = sound_timer_devs[dev]->devlink;
- struct mpu_config *devc= &dev_conf[midi_dev];
-
- if (timer_open)
- return -EBUSY;
-
- tmr_reset(devc);
- curr_tempo = 50;
- mpu_cmd(midi_dev, 0xE0, 50);
- curr_timebase = hw_timebase = 120;
- set_timebase(midi_dev, 120);
- timer_open = 1;
- metronome_mode = 0;
- set_timer_mode(midi_dev);
-
- mpu_cmd(midi_dev, 0xe7, 0x04); /* Send all clocks to host */
- mpu_cmd(midi_dev, 0x95, 0); /* Enable clock to host */
-
- return 0;
-}
-
-static void mpu_timer_close(int dev)
-{
- int midi_dev = sound_timer_devs[dev]->devlink;
-
- timer_open = tmr_running = 0;
- mpu_cmd(midi_dev, 0x15, 0); /* Stop all */
- mpu_cmd(midi_dev, 0x94, 0); /* Disable clock to host */
- mpu_cmd(midi_dev, 0x8c, 0); /* Disable measure end messages to host */
- stop_metronome(midi_dev);
-}
-
-static int mpu_timer_event(int dev, unsigned char *event)
-{
- unsigned char command = event[1];
- unsigned long parm = *(unsigned int *) &event[4];
- int midi_dev = sound_timer_devs[dev]->devlink;
-
- switch (command)
- {
- case TMR_WAIT_REL:
- parm += prev_event_time;
- case TMR_WAIT_ABS:
- if (parm > 0)
- {
- long time;
-
- if (parm <= curr_ticks) /* It's the time */
- return TIMER_NOT_ARMED;
- time = parm;
- next_event_time = prev_event_time = time;
-
- return TIMER_ARMED;
- }
- break;
-
- case TMR_START:
- if (tmr_running)
- break;
- return mpu_start_timer(midi_dev);
-
- case TMR_STOP:
- mpu_cmd(midi_dev, 0x01, 0); /* Send MIDI stop */
- stop_metronome(midi_dev);
- tmr_running = 0;
- break;
-
- case TMR_CONTINUE:
- if (tmr_running)
- break;
- mpu_cmd(midi_dev, 0x03, 0); /* Send MIDI continue */
- setup_metronome(midi_dev);
- tmr_running = 1;
- break;
-
- case TMR_TEMPO:
- if (parm)
- {
- if (parm < 8)
- parm = 8;
- if (parm > 250)
- parm = 250;
- if (mpu_cmd(midi_dev, 0xE0, parm) < 0)
- printk(KERN_WARNING "mpu401: Can't set tempo to %d\n", (int) parm);
- curr_tempo = parm;
- }
- break;
-
- case TMR_ECHO:
- seq_copy_to_input(event, 8);
- break;
-
- case TMR_TIMESIG:
- if (metronome_mode) /* Metronome enabled */
- {
- metronome_mode = parm;
- setup_metronome(midi_dev);
- }
- break;
-
- default:;
- }
- return TIMER_NOT_ARMED;
-}
-
-static unsigned long mpu_timer_get_time(int dev)
-{
- if (!timer_open)
- return 0;
-
- return curr_ticks;
-}
-
-static int mpu_timer_ioctl(int dev, unsigned int command, void __user *arg)
-{
- int midi_dev = sound_timer_devs[dev]->devlink;
- int __user *p = (int __user *)arg;
-
- switch (command)
- {
- case SNDCTL_TMR_SOURCE:
- {
- int parm;
-
- if (get_user(parm, p))
- return -EFAULT;
- parm &= timer_caps;
-
- if (parm != 0)
- {
- timer_mode = parm;
-
- if (timer_mode & TMR_MODE_CLS)
- mpu_cmd(midi_dev, 0x3c, 0); /* Use CLS sync */
- else if (timer_mode & TMR_MODE_SMPTE)
- mpu_cmd(midi_dev, 0x3d, 0); /* Use SMPTE sync */
- }
- if (put_user(timer_mode, p))
- return -EFAULT;
- return timer_mode;
- }
- break;
-
- case SNDCTL_TMR_START:
- mpu_start_timer(midi_dev);
- return 0;
-
- case SNDCTL_TMR_STOP:
- tmr_running = 0;
- mpu_cmd(midi_dev, 0x01, 0); /* Send MIDI stop */
- stop_metronome(midi_dev);
- return 0;
-
- case SNDCTL_TMR_CONTINUE:
- if (tmr_running)
- return 0;
- tmr_running = 1;
- mpu_cmd(midi_dev, 0x03, 0); /* Send MIDI continue */
- return 0;
-
- case SNDCTL_TMR_TIMEBASE:
- {
- int val;
- if (get_user(val, p))
- return -EFAULT;
- if (val)
- set_timebase(midi_dev, val);
- if (put_user(curr_timebase, p))
- return -EFAULT;
- return curr_timebase;
- }
- break;
-
- case SNDCTL_TMR_TEMPO:
- {
- int val;
- int ret;
-
- if (get_user(val, p))
- return -EFAULT;
-
- if (val)
- {
- if (val < 8)
- val = 8;
- if (val > 250)
- val = 250;
- if ((ret = mpu_cmd(midi_dev, 0xE0, val)) < 0)
- {
- printk(KERN_WARNING "mpu401: Can't set tempo to %d\n", (int) val);
- return ret;
- }
- curr_tempo = val;
- }
- if (put_user(curr_tempo, p))
- return -EFAULT;
- return curr_tempo;
- }
- break;
-
- case SNDCTL_SEQ_CTRLRATE:
- {
- int val;
- if (get_user(val, p))
- return -EFAULT;
-
- if (val != 0) /* Can't change */
- return -EINVAL;
- val = ((curr_tempo * curr_timebase) + 30)/60;
- if (put_user(val, p))
- return -EFAULT;
- return val;
- }
- break;
-
- case SNDCTL_SEQ_GETTIME:
- if (put_user(curr_ticks, p))
- return -EFAULT;
- return curr_ticks;
-
- case SNDCTL_TMR_METRONOME:
- if (get_user(metronome_mode, p))
- return -EFAULT;
- setup_metronome(midi_dev);
- return 0;
-
- default:;
- }
- return -EINVAL;
-}
-
-static void mpu_timer_arm(int dev, long time)
-{
- if (time < 0)
- time = curr_ticks + 1;
- else if (time <= curr_ticks) /* It's the time */
- return;
- next_event_time = prev_event_time = time;
- return;
-}
-
-static struct sound_timer_operations mpu_timer =
-{
- .owner = THIS_MODULE,
- .info = {"MPU-401 Timer", 0},
- .priority = 10, /* Priority */
- .devlink = 0, /* Local device link */
- .open = mpu_timer_open,
- .close = mpu_timer_close,
- .event = mpu_timer_event,
- .get_time = mpu_timer_get_time,
- .ioctl = mpu_timer_ioctl,
- .arm_timer = mpu_timer_arm
-};
-
-static void mpu_timer_interrupt(void)
-{
- if (!timer_open)
- return;
-
- if (!tmr_running)
- return;
-
- curr_clocks++;
- curr_ticks = clocks2ticks(curr_clocks);
-
- if (curr_ticks >= next_event_time)
- {
- next_event_time = (unsigned long) -1;
- sequencer_timer(0);
- }
-}
-
-static void timer_ext_event(struct mpu_config *devc, int event, int parm)
-{
- int midi_dev = devc->devno;
-
- if (!devc->timer_flag)
- return;
-
- switch (event)
- {
- case TMR_CLOCK:
- printk("<MIDI clk>");
- break;
-
- case TMR_START:
- printk("Ext MIDI start\n");
- if (!tmr_running)
- {
- if (timer_mode & TMR_EXTERNAL)
- {
- tmr_running = 1;
- setup_metronome(midi_dev);
- next_event_time = 0;
- STORE(SEQ_START_TIMER());
- }
- }
- break;
-
- case TMR_STOP:
- printk("Ext MIDI stop\n");
- if (timer_mode & TMR_EXTERNAL)
- {
- tmr_running = 0;
- stop_metronome(midi_dev);
- STORE(SEQ_STOP_TIMER());
- }
- break;
-
- case TMR_CONTINUE:
- printk("Ext MIDI continue\n");
- if (timer_mode & TMR_EXTERNAL)
- {
- tmr_running = 1;
- setup_metronome(midi_dev);
- STORE(SEQ_CONTINUE_TIMER());
- }
- break;
-
- case TMR_SPP:
- printk("Songpos: %d\n", parm);
- if (timer_mode & TMR_EXTERNAL)
- {
- STORE(SEQ_SONGPOS(parm));
- }
- break;
- }
-}
-
-static int mpu_timer_init(int midi_dev)
-{
- struct mpu_config *devc;
- int n;
-
- devc = &dev_conf[midi_dev];
-
- if (timer_initialized)
- return -1; /* There is already a similar timer */
-
- timer_initialized = 1;
-
- mpu_timer.devlink = midi_dev;
- dev_conf[midi_dev].timer_flag = 1;
-
- n = sound_alloc_timerdev();
- if (n == -1)
- n = 0;
- sound_timer_devs[n] = &mpu_timer;
-
- if (devc->version < 0x20) /* Original MPU-401 */
- timer_caps = TMR_INTERNAL | TMR_EXTERNAL | TMR_MODE_FSK | TMR_MODE_MIDI;
- else
- {
- /*
- * The version number 2.0 is used (at least) by the
- * MusicQuest cards and the Roland Super-MPU.
- *
- * MusicQuest has given a special meaning to the bits of the
- * revision number. The Super-MPU returns 0.
- */
-
- if (devc->revision)
- timer_caps |= TMR_EXTERNAL | TMR_MODE_MIDI;
-
- if (devc->revision & 0x02)
- timer_caps |= TMR_MODE_CLS;
-
-
- if (devc->revision & 0x40)
- max_timebase = 10; /* Has the 216 and 240 ppqn modes */
- }
-
- timer_mode = (TMR_INTERNAL | TMR_MODE_MIDI) & timer_caps;
- return n;
-
-}
-
-EXPORT_SYMBOL(probe_mpu401);
-EXPORT_SYMBOL(attach_mpu401);
-EXPORT_SYMBOL(unload_mpu401);
-
-static struct address_info cfg;
-
-static int io = -1;
-static int irq = -1;
-
-module_param(irq, int, 0);
-module_param(io, int, 0);
-
-static int __init init_mpu401(void)
-{
- int ret;
- /* Can be loaded either for module use or to provide functions
- to others */
- if (io != -1 && irq != -1) {
- struct resource *ports;
- cfg.irq = irq;
- cfg.io_base = io;
- ports = request_region(io, 2, "mpu401");
- if (!ports)
- return -EBUSY;
- if (probe_mpu401(&cfg, ports) == 0) {
- release_region(io, 2);
- return -ENODEV;
- }
- if ((ret = attach_mpu401(&cfg, THIS_MODULE)))
- return ret;
- }
-
- return 0;
-}
-
-static void __exit cleanup_mpu401(void)
-{
- if (io != -1 && irq != -1) {
- /* Check for use by, for example, sscape driver */
- unload_mpu401(&cfg);
- }
-}
-
-module_init(init_mpu401);
-module_exit(cleanup_mpu401);
-
-#ifndef MODULE
-static int __init setup_mpu401(char *str)
-{
- /* io, irq */
- int ints[3];
-
- str = get_options(str, ARRAY_SIZE(ints), ints);
-
- io = ints[1];
- irq = ints[2];
-
- return 1;
-}
-
-__setup("mpu401=", setup_mpu401);
-#endif
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/oss/mpu401.h b/ANDROID_3.4.5/sound/oss/mpu401.h
deleted file mode 100644
index 0ad1e9ee..00000000
--- a/ANDROID_3.4.5/sound/oss/mpu401.h
+++ /dev/null
@@ -1,11 +0,0 @@
-
-/* From uart401.c */
-int probe_uart401 (struct address_info *hw_config, struct module *owner);
-void unload_uart401 (struct address_info *hw_config);
-
-irqreturn_t uart401intr (int irq, void *dev_id);
-
-/* From mpu401.c */
-int probe_mpu401(struct address_info *hw_config, struct resource *ports);
-int attach_mpu401(struct address_info * hw_config, struct module *owner);
-void unload_mpu401(struct address_info *hw_info);
diff --git a/ANDROID_3.4.5/sound/oss/msnd.c b/ANDROID_3.4.5/sound/oss/msnd.c
deleted file mode 100644
index c0cc951b..00000000
--- a/ANDROID_3.4.5/sound/oss/msnd.c
+++ /dev/null
@@ -1,413 +0,0 @@
-/*********************************************************************
- *
- * msnd.c - Driver Base
- *
- * Turtle Beach MultiSound Sound Card Driver for Linux
- *
- * Copyright (C) 1998 Andrew Veliath
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ********************************************************************/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/vmalloc.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <linux/spinlock.h>
-#include <asm/irq.h>
-#include "msnd.h"
-
-#define LOGNAME "msnd"
-
-#define MSND_MAX_DEVS 4
-
-static multisound_dev_t *devs[MSND_MAX_DEVS];
-static int num_devs;
-
-int msnd_register(multisound_dev_t *dev)
-{
- int i;
-
- for (i = 0; i < MSND_MAX_DEVS; ++i)
- if (devs[i] == NULL)
- break;
-
- if (i == MSND_MAX_DEVS)
- return -ENOMEM;
-
- devs[i] = dev;
- ++num_devs;
- return 0;
-}
-
-void msnd_unregister(multisound_dev_t *dev)
-{
- int i;
-
- for (i = 0; i < MSND_MAX_DEVS; ++i)
- if (devs[i] == dev)
- break;
-
- if (i == MSND_MAX_DEVS) {
- printk(KERN_WARNING LOGNAME ": Unregistering unknown device\n");
- return;
- }
-
- devs[i] = NULL;
- --num_devs;
-}
-
-void msnd_init_queue(void __iomem *base, int start, int size)
-{
- writew(PCTODSP_BASED(start), base + JQS_wStart);
- writew(PCTODSP_OFFSET(size) - 1, base + JQS_wSize);
- writew(0, base + JQS_wHead);
- writew(0, base + JQS_wTail);
-}
-
-void msnd_fifo_init(msnd_fifo *f)
-{
- f->data = NULL;
-}
-
-void msnd_fifo_free(msnd_fifo *f)
-{
- vfree(f->data);
- f->data = NULL;
-}
-
-int msnd_fifo_alloc(msnd_fifo *f, size_t n)
-{
- msnd_fifo_free(f);
- f->data = vmalloc(n);
- f->n = n;
- f->tail = 0;
- f->head = 0;
- f->len = 0;
-
- if (!f->data)
- return -ENOMEM;
-
- return 0;
-}
-
-void msnd_fifo_make_empty(msnd_fifo *f)
-{
- f->len = f->tail = f->head = 0;
-}
-
-int msnd_fifo_write_io(msnd_fifo *f, char __iomem *buf, size_t len)
-{
- int count = 0;
-
- while ((count < len) && (f->len != f->n)) {
-
- int nwritten;
-
- if (f->head <= f->tail) {
- nwritten = len - count;
- if (nwritten > f->n - f->tail)
- nwritten = f->n - f->tail;
- }
- else {
- nwritten = f->head - f->tail;
- if (nwritten > len - count)
- nwritten = len - count;
- }
-
- memcpy_fromio(f->data + f->tail, buf, nwritten);
-
- count += nwritten;
- buf += nwritten;
- f->len += nwritten;
- f->tail += nwritten;
- f->tail %= f->n;
- }
-
- return count;
-}
-
-int msnd_fifo_write(msnd_fifo *f, const char *buf, size_t len)
-{
- int count = 0;
-
- while ((count < len) && (f->len != f->n)) {
-
- int nwritten;
-
- if (f->head <= f->tail) {
- nwritten = len - count;
- if (nwritten > f->n - f->tail)
- nwritten = f->n - f->tail;
- }
- else {
- nwritten = f->head - f->tail;
- if (nwritten > len - count)
- nwritten = len - count;
- }
-
- memcpy(f->data + f->tail, buf, nwritten);
-
- count += nwritten;
- buf += nwritten;
- f->len += nwritten;
- f->tail += nwritten;
- f->tail %= f->n;
- }
-
- return count;
-}
-
-int msnd_fifo_read_io(msnd_fifo *f, char __iomem *buf, size_t len)
-{
- int count = 0;
-
- while ((count < len) && (f->len > 0)) {
-
- int nread;
-
- if (f->tail <= f->head) {
- nread = len - count;
- if (nread > f->n - f->head)
- nread = f->n - f->head;
- }
- else {
- nread = f->tail - f->head;
- if (nread > len - count)
- nread = len - count;
- }
-
- memcpy_toio(buf, f->data + f->head, nread);
-
- count += nread;
- buf += nread;
- f->len -= nread;
- f->head += nread;
- f->head %= f->n;
- }
-
- return count;
-}
-
-int msnd_fifo_read(msnd_fifo *f, char *buf, size_t len)
-{
- int count = 0;
-
- while ((count < len) && (f->len > 0)) {
-
- int nread;
-
- if (f->tail <= f->head) {
- nread = len - count;
- if (nread > f->n - f->head)
- nread = f->n - f->head;
- }
- else {
- nread = f->tail - f->head;
- if (nread > len - count)
- nread = len - count;
- }
-
- memcpy(buf, f->data + f->head, nread);
-
- count += nread;
- buf += nread;
- f->len -= nread;
- f->head += nread;
- f->head %= f->n;
- }
-
- return count;
-}
-
-static int msnd_wait_TXDE(multisound_dev_t *dev)
-{
- register unsigned int io = dev->io;
- register int timeout = 1000;
-
- while(timeout-- > 0)
- if (msnd_inb(io + HP_ISR) & HPISR_TXDE)
- return 0;
-
- return -EIO;
-}
-
-static int msnd_wait_HC0(multisound_dev_t *dev)
-{
- register unsigned int io = dev->io;
- register int timeout = 1000;
-
- while(timeout-- > 0)
- if (!(msnd_inb(io + HP_CVR) & HPCVR_HC))
- return 0;
-
- return -EIO;
-}
-
-int msnd_send_dsp_cmd(multisound_dev_t *dev, BYTE cmd)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&dev->lock, flags);
- if (msnd_wait_HC0(dev) == 0) {
- msnd_outb(cmd, dev->io + HP_CVR);
- spin_unlock_irqrestore(&dev->lock, flags);
- return 0;
- }
- spin_unlock_irqrestore(&dev->lock, flags);
-
- printk(KERN_DEBUG LOGNAME ": Send DSP command timeout\n");
-
- return -EIO;
-}
-
-int msnd_send_word(multisound_dev_t *dev, unsigned char high,
- unsigned char mid, unsigned char low)
-{
- register unsigned int io = dev->io;
-
- if (msnd_wait_TXDE(dev) == 0) {
- msnd_outb(high, io + HP_TXH);
- msnd_outb(mid, io + HP_TXM);
- msnd_outb(low, io + HP_TXL);
- return 0;
- }
-
- printk(KERN_DEBUG LOGNAME ": Send host word timeout\n");
-
- return -EIO;
-}
-
-int msnd_upload_host(multisound_dev_t *dev, char *bin, int len)
-{
- int i;
-
- if (len % 3 != 0) {
- printk(KERN_WARNING LOGNAME ": Upload host data not multiple of 3!\n");
- return -EINVAL;
- }
-
- for (i = 0; i < len; i += 3)
- if (msnd_send_word(dev, bin[i], bin[i + 1], bin[i + 2]) != 0)
- return -EIO;
-
- msnd_inb(dev->io + HP_RXL);
- msnd_inb(dev->io + HP_CVR);
-
- return 0;
-}
-
-int msnd_enable_irq(multisound_dev_t *dev)
-{
- unsigned long flags;
-
- if (dev->irq_ref++)
- return 0;
-
- printk(KERN_DEBUG LOGNAME ": Enabling IRQ\n");
-
- spin_lock_irqsave(&dev->lock, flags);
- if (msnd_wait_TXDE(dev) == 0) {
- msnd_outb(msnd_inb(dev->io + HP_ICR) | HPICR_TREQ, dev->io + HP_ICR);
- if (dev->type == msndClassic)
- msnd_outb(dev->irqid, dev->io + HP_IRQM);
- msnd_outb(msnd_inb(dev->io + HP_ICR) & ~HPICR_TREQ, dev->io + HP_ICR);
- msnd_outb(msnd_inb(dev->io + HP_ICR) | HPICR_RREQ, dev->io + HP_ICR);
- enable_irq(dev->irq);
- msnd_init_queue(dev->DSPQ, dev->dspq_data_buff, dev->dspq_buff_size);
- spin_unlock_irqrestore(&dev->lock, flags);
- return 0;
- }
- spin_unlock_irqrestore(&dev->lock, flags);
-
- printk(KERN_DEBUG LOGNAME ": Enable IRQ failed\n");
-
- return -EIO;
-}
-
-int msnd_disable_irq(multisound_dev_t *dev)
-{
- unsigned long flags;
-
- if (--dev->irq_ref > 0)
- return 0;
-
- if (dev->irq_ref < 0)
- printk(KERN_DEBUG LOGNAME ": IRQ ref count is %d\n", dev->irq_ref);
-
- printk(KERN_DEBUG LOGNAME ": Disabling IRQ\n");
-
- spin_lock_irqsave(&dev->lock, flags);
- if (msnd_wait_TXDE(dev) == 0) {
- msnd_outb(msnd_inb(dev->io + HP_ICR) & ~HPICR_RREQ, dev->io + HP_ICR);
- if (dev->type == msndClassic)
- msnd_outb(HPIRQ_NONE, dev->io + HP_IRQM);
- disable_irq(dev->irq);
- spin_unlock_irqrestore(&dev->lock, flags);
- return 0;
- }
- spin_unlock_irqrestore(&dev->lock, flags);
-
- printk(KERN_DEBUG LOGNAME ": Disable IRQ failed\n");
-
- return -EIO;
-}
-
-#ifndef LINUX20
-EXPORT_SYMBOL(msnd_register);
-EXPORT_SYMBOL(msnd_unregister);
-
-EXPORT_SYMBOL(msnd_init_queue);
-
-EXPORT_SYMBOL(msnd_fifo_init);
-EXPORT_SYMBOL(msnd_fifo_free);
-EXPORT_SYMBOL(msnd_fifo_alloc);
-EXPORT_SYMBOL(msnd_fifo_make_empty);
-EXPORT_SYMBOL(msnd_fifo_write_io);
-EXPORT_SYMBOL(msnd_fifo_read_io);
-EXPORT_SYMBOL(msnd_fifo_write);
-EXPORT_SYMBOL(msnd_fifo_read);
-
-EXPORT_SYMBOL(msnd_send_dsp_cmd);
-EXPORT_SYMBOL(msnd_send_word);
-EXPORT_SYMBOL(msnd_upload_host);
-
-EXPORT_SYMBOL(msnd_enable_irq);
-EXPORT_SYMBOL(msnd_disable_irq);
-#endif
-
-#ifdef MODULE
-MODULE_AUTHOR ("Andrew Veliath <andrewtv@usa.net>");
-MODULE_DESCRIPTION ("Turtle Beach MultiSound Driver Base");
-MODULE_LICENSE("GPL");
-
-
-int init_module(void)
-{
- return 0;
-}
-
-void cleanup_module(void)
-{
-}
-#endif
diff --git a/ANDROID_3.4.5/sound/oss/msnd.h b/ANDROID_3.4.5/sound/oss/msnd.h
deleted file mode 100644
index c8be47ec..00000000
--- a/ANDROID_3.4.5/sound/oss/msnd.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/*********************************************************************
- *
- * msnd.h
- *
- * Turtle Beach MultiSound Sound Card Driver for Linux
- *
- * Some parts of this header file were derived from the Turtle Beach
- * MultiSound Driver Development Kit.
- *
- * Copyright (C) 1998 Andrew Veliath
- * Copyright (C) 1993 Turtle Beach Systems, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ********************************************************************/
-#ifndef __MSND_H
-#define __MSND_H
-
-#define VERSION "0.8.3.1"
-
-#define DEFSAMPLERATE DSP_DEFAULT_SPEED
-#define DEFSAMPLESIZE AFMT_U8
-#define DEFCHANNELS 1
-
-#define DEFFIFOSIZE 128
-
-#define SNDCARD_MSND 38
-
-#define SRAM_BANK_SIZE 0x8000
-#define SRAM_CNTL_START 0x7F00
-
-#define DSP_BASE_ADDR 0x4000
-#define DSP_BANK_BASE 0x4000
-
-#define HP_ICR 0x00
-#define HP_CVR 0x01
-#define HP_ISR 0x02
-#define HP_IVR 0x03
-#define HP_NU 0x04
-#define HP_INFO 0x04
-#define HP_TXH 0x05
-#define HP_RXH 0x05
-#define HP_TXM 0x06
-#define HP_RXM 0x06
-#define HP_TXL 0x07
-#define HP_RXL 0x07
-
-#define HP_ICR_DEF 0x00
-#define HP_CVR_DEF 0x12
-#define HP_ISR_DEF 0x06
-#define HP_IVR_DEF 0x0f
-#define HP_NU_DEF 0x00
-
-#define HP_IRQM 0x09
-
-#define HPR_BLRC 0x08
-#define HPR_SPR1 0x09
-#define HPR_SPR2 0x0A
-#define HPR_TCL0 0x0B
-#define HPR_TCL1 0x0C
-#define HPR_TCL2 0x0D
-#define HPR_TCL3 0x0E
-#define HPR_TCL4 0x0F
-
-#define HPICR_INIT 0x80
-#define HPICR_HM1 0x40
-#define HPICR_HM0 0x20
-#define HPICR_HF1 0x10
-#define HPICR_HF0 0x08
-#define HPICR_TREQ 0x02
-#define HPICR_RREQ 0x01
-
-#define HPCVR_HC 0x80
-
-#define HPISR_HREQ 0x80
-#define HPISR_DMA 0x40
-#define HPISR_HF3 0x10
-#define HPISR_HF2 0x08
-#define HPISR_TRDY 0x04
-#define HPISR_TXDE 0x02
-#define HPISR_RXDF 0x01
-
-#define HPIO_290 0
-#define HPIO_260 1
-#define HPIO_250 2
-#define HPIO_240 3
-#define HPIO_230 4
-#define HPIO_220 5
-#define HPIO_210 6
-#define HPIO_3E0 7
-
-#define HPMEM_NONE 0
-#define HPMEM_B000 1
-#define HPMEM_C800 2
-#define HPMEM_D000 3
-#define HPMEM_D400 4
-#define HPMEM_D800 5
-#define HPMEM_E000 6
-#define HPMEM_E800 7
-
-#define HPIRQ_NONE 0
-#define HPIRQ_5 1
-#define HPIRQ_7 2
-#define HPIRQ_9 3
-#define HPIRQ_10 4
-#define HPIRQ_11 5
-#define HPIRQ_12 6
-#define HPIRQ_15 7
-
-#define HIMT_PLAY_DONE 0x00
-#define HIMT_RECORD_DONE 0x01
-#define HIMT_MIDI_EOS 0x02
-#define HIMT_MIDI_OUT 0x03
-
-#define HIMT_MIDI_IN_UCHAR 0x0E
-#define HIMT_DSP 0x0F
-
-#define HDEX_BASE 0x92
-#define HDEX_PLAY_START (0 + HDEX_BASE)
-#define HDEX_PLAY_STOP (1 + HDEX_BASE)
-#define HDEX_PLAY_PAUSE (2 + HDEX_BASE)
-#define HDEX_PLAY_RESUME (3 + HDEX_BASE)
-#define HDEX_RECORD_START (4 + HDEX_BASE)
-#define HDEX_RECORD_STOP (5 + HDEX_BASE)
-#define HDEX_MIDI_IN_START (6 + HDEX_BASE)
-#define HDEX_MIDI_IN_STOP (7 + HDEX_BASE)
-#define HDEX_MIDI_OUT_START (8 + HDEX_BASE)
-#define HDEX_MIDI_OUT_STOP (9 + HDEX_BASE)
-#define HDEX_AUX_REQ (10 + HDEX_BASE)
-
-#define HIWORD(l) ((WORD)((((DWORD)(l)) >> 16) & 0xFFFF))
-#define LOWORD(l) ((WORD)(DWORD)(l))
-#define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF))
-#define LOBYTE(w) ((BYTE)(w))
-#define MAKELONG(low,hi) ((long)(((WORD)(low))|(((DWORD)((WORD)(hi)))<<16)))
-#define MAKEWORD(low,hi) ((WORD)(((BYTE)(low))|(((WORD)((BYTE)(hi)))<<8)))
-
-#define PCTODSP_OFFSET(w) (USHORT)((w)/2)
-#define PCTODSP_BASED(w) (USHORT)(((w)/2) + DSP_BASE_ADDR)
-#define DSPTOPC_BASED(w) (((w) - DSP_BASE_ADDR) * 2)
-
-#ifdef SLOWIO
-#define msnd_outb outb_p
-#define msnd_inb inb_p
-#else
-#define msnd_outb outb
-#define msnd_inb inb
-#endif
-
-/* JobQueueStruct */
-#define JQS_wStart 0x00
-#define JQS_wSize 0x02
-#define JQS_wHead 0x04
-#define JQS_wTail 0x06
-#define JQS__size 0x08
-
-/* DAQueueDataStruct */
-#define DAQDS_wStart 0x00
-#define DAQDS_wSize 0x02
-#define DAQDS_wFormat 0x04
-#define DAQDS_wSampleSize 0x06
-#define DAQDS_wChannels 0x08
-#define DAQDS_wSampleRate 0x0A
-#define DAQDS_wIntMsg 0x0C
-#define DAQDS_wFlags 0x0E
-#define DAQDS__size 0x10
-
-typedef u8 BYTE;
-typedef u16 USHORT;
-typedef u16 WORD;
-typedef u32 DWORD;
-typedef void __iomem * LPDAQD;
-
-/* Generic FIFO */
-typedef struct {
- size_t n, len;
- char *data;
- int head, tail;
-} msnd_fifo;
-
-typedef struct multisound_dev {
- /* Linux device info */
- char *name;
- int dsp_minor, mixer_minor;
- int ext_midi_dev, hdr_midi_dev;
-
- /* Hardware resources */
- int io, numio;
- int memid, irqid;
- int irq, irq_ref;
- unsigned char info;
- void __iomem *base;
-
- /* Motorola 56k DSP SMA */
- void __iomem *SMA;
- void __iomem *DAPQ, *DARQ, *MODQ, *MIDQ, *DSPQ;
- void __iomem *pwDSPQData, *pwMIDQData, *pwMODQData;
- int dspq_data_buff, dspq_buff_size;
-
- /* State variables */
- enum { msndClassic, msndPinnacle } type;
- fmode_t mode;
- unsigned long flags;
-#define F_RESETTING 0
-#define F_HAVEDIGITAL 1
-#define F_AUDIO_WRITE_INUSE 2
-#define F_WRITING 3
-#define F_WRITEBLOCK 4
-#define F_WRITEFLUSH 5
-#define F_AUDIO_READ_INUSE 6
-#define F_READING 7
-#define F_READBLOCK 8
-#define F_EXT_MIDI_INUSE 9
-#define F_HDR_MIDI_INUSE 10
-#define F_DISABLE_WRITE_NDELAY 11
- wait_queue_head_t writeblock;
- wait_queue_head_t readblock;
- wait_queue_head_t writeflush;
- spinlock_t lock;
- int nresets;
- unsigned long recsrc;
- int left_levels[32];
- int right_levels[32];
- int mixer_mod_count;
- int calibrate_signal;
- int play_sample_size, play_sample_rate, play_channels;
- int play_ndelay;
- int rec_sample_size, rec_sample_rate, rec_channels;
- int rec_ndelay;
- BYTE bCurrentMidiPatch;
-
- /* Digital audio FIFOs */
- msnd_fifo DAPF, DARF;
- int fifosize;
- int last_playbank, last_recbank;
-
- /* MIDI in callback */
- void (*midi_in_interrupt)(struct multisound_dev *);
-} multisound_dev_t;
-
-#ifndef mdelay
-# define mdelay(a) udelay((a) * 1000)
-#endif
-
-int msnd_register(multisound_dev_t *dev);
-void msnd_unregister(multisound_dev_t *dev);
-
-void msnd_init_queue(void __iomem *, int start, int size);
-
-void msnd_fifo_init(msnd_fifo *f);
-void msnd_fifo_free(msnd_fifo *f);
-int msnd_fifo_alloc(msnd_fifo *f, size_t n);
-void msnd_fifo_make_empty(msnd_fifo *f);
-int msnd_fifo_write_io(msnd_fifo *f, char __iomem *buf, size_t len);
-int msnd_fifo_read_io(msnd_fifo *f, char __iomem *buf, size_t len);
-int msnd_fifo_write(msnd_fifo *f, const char *buf, size_t len);
-int msnd_fifo_read(msnd_fifo *f, char *buf, size_t len);
-
-int msnd_send_dsp_cmd(multisound_dev_t *dev, BYTE cmd);
-int msnd_send_word(multisound_dev_t *dev, unsigned char high,
- unsigned char mid, unsigned char low);
-int msnd_upload_host(multisound_dev_t *dev, char *bin, int len);
-int msnd_enable_irq(multisound_dev_t *dev);
-int msnd_disable_irq(multisound_dev_t *dev);
-
-#endif /* __MSND_H */
diff --git a/ANDROID_3.4.5/sound/oss/msnd_classic.c b/ANDROID_3.4.5/sound/oss/msnd_classic.c
deleted file mode 100644
index 3b23a096..00000000
--- a/ANDROID_3.4.5/sound/oss/msnd_classic.c
+++ /dev/null
@@ -1,3 +0,0 @@
-/* The work is in msnd_pinnacle.c, just define MSND_CLASSIC before it. */
-#define MSND_CLASSIC
-#include "msnd_pinnacle.c"
diff --git a/ANDROID_3.4.5/sound/oss/msnd_classic.h b/ANDROID_3.4.5/sound/oss/msnd_classic.h
deleted file mode 100644
index 1a17dde2..00000000
--- a/ANDROID_3.4.5/sound/oss/msnd_classic.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*********************************************************************
- *
- * msnd_classic.h
- *
- * Turtle Beach MultiSound Sound Card Driver for Linux
- *
- * Some parts of this header file were derived from the Turtle Beach
- * MultiSound Driver Development Kit.
- *
- * Copyright (C) 1998 Andrew Veliath
- * Copyright (C) 1993 Turtle Beach Systems, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ********************************************************************/
-#ifndef __MSND_CLASSIC_H
-#define __MSND_CLASSIC_H
-
-
-#define DSP_NUMIO 0x10
-
-#define HP_MEMM 0x08
-
-#define HP_BITM 0x0E
-#define HP_WAIT 0x0D
-#define HP_DSPR 0x0A
-#define HP_PROR 0x0B
-#define HP_BLKS 0x0C
-
-#define HPPRORESET_OFF 0
-#define HPPRORESET_ON 1
-
-#define HPDSPRESET_OFF 0
-#define HPDSPRESET_ON 1
-
-#define HPBLKSEL_0 0
-#define HPBLKSEL_1 1
-
-#define HPWAITSTATE_0 0
-#define HPWAITSTATE_1 1
-
-#define HPBITMODE_16 0
-#define HPBITMODE_8 1
-
-#define HIDSP_INT_PLAY_UNDER 0x00
-#define HIDSP_INT_RECORD_OVER 0x01
-#define HIDSP_INPUT_CLIPPING 0x02
-#define HIDSP_MIDI_IN_OVER 0x10
-#define HIDSP_MIDI_OVERRUN_ERR 0x13
-
-#define HDEXAR_CLEAR_PEAKS 1
-#define HDEXAR_IN_SET_POTS 2
-#define HDEXAR_AUX_SET_POTS 3
-#define HDEXAR_CAL_A_TO_D 4
-#define HDEXAR_RD_EXT_DSP_BITS 5
-
-#define TIME_PRO_RESET_DONE 0x028A
-#define TIME_PRO_SYSEX 0x0040
-#define TIME_PRO_RESET 0x0032
-
-#define AGND 0x01
-#define SIGNAL 0x02
-
-#define EXT_DSP_BIT_DCAL 0x0001
-#define EXT_DSP_BIT_MIDI_CON 0x0002
-
-#define BUFFSIZE 0x8000
-#define HOSTQ_SIZE 0x40
-
-#define SRAM_CNTL_START 0x7F00
-#define SMA_STRUCT_START 0x7F40
-
-#define DAP_BUFF_SIZE 0x2400
-#define DAR_BUFF_SIZE 0x2000
-
-#define DAPQ_STRUCT_SIZE 0x10
-#define DARQ_STRUCT_SIZE 0x10
-#define DAPQ_BUFF_SIZE (3 * 0x10)
-#define DARQ_BUFF_SIZE (3 * 0x10)
-#define MODQ_BUFF_SIZE 0x400
-#define MIDQ_BUFF_SIZE 0x200
-#define DSPQ_BUFF_SIZE 0x40
-
-#define DAPQ_DATA_BUFF 0x6C00
-#define DARQ_DATA_BUFF 0x6C30
-#define MODQ_DATA_BUFF 0x6C60
-#define MIDQ_DATA_BUFF 0x7060
-#define DSPQ_DATA_BUFF 0x7260
-
-#define DAPQ_OFFSET SRAM_CNTL_START
-#define DARQ_OFFSET (SRAM_CNTL_START + 0x08)
-#define MODQ_OFFSET (SRAM_CNTL_START + 0x10)
-#define MIDQ_OFFSET (SRAM_CNTL_START + 0x18)
-#define DSPQ_OFFSET (SRAM_CNTL_START + 0x20)
-
-#define MOP_SYNTH 0x10
-#define MOP_EXTOUT 0x32
-#define MOP_EXTTHRU 0x02
-#define MOP_OUTMASK 0x01
-
-#define MIP_EXTIN 0x01
-#define MIP_SYNTH 0x00
-#define MIP_INMASK 0x32
-
-/* Classic SMA Common Data */
-#define SMA_wCurrPlayBytes 0x0000
-#define SMA_wCurrRecordBytes 0x0002
-#define SMA_wCurrPlayVolLeft 0x0004
-#define SMA_wCurrPlayVolRight 0x0006
-#define SMA_wCurrInVolLeft 0x0008
-#define SMA_wCurrInVolRight 0x000a
-#define SMA_wUser_3 0x000c
-#define SMA_wUser_4 0x000e
-#define SMA_dwUser_5 0x0010
-#define SMA_dwUser_6 0x0014
-#define SMA_wUser_7 0x0018
-#define SMA_wReserved_A 0x001a
-#define SMA_wReserved_B 0x001c
-#define SMA_wReserved_C 0x001e
-#define SMA_wReserved_D 0x0020
-#define SMA_wReserved_E 0x0022
-#define SMA_wReserved_F 0x0024
-#define SMA_wReserved_G 0x0026
-#define SMA_wReserved_H 0x0028
-#define SMA_wCurrDSPStatusFlags 0x002a
-#define SMA_wCurrHostStatusFlags 0x002c
-#define SMA_wCurrInputTagBits 0x002e
-#define SMA_wCurrLeftPeak 0x0030
-#define SMA_wCurrRightPeak 0x0032
-#define SMA_wExtDSPbits 0x0034
-#define SMA_bExtHostbits 0x0036
-#define SMA_bBoardLevel 0x0037
-#define SMA_bInPotPosRight 0x0038
-#define SMA_bInPotPosLeft 0x0039
-#define SMA_bAuxPotPosRight 0x003a
-#define SMA_bAuxPotPosLeft 0x003b
-#define SMA_wCurrMastVolLeft 0x003c
-#define SMA_wCurrMastVolRight 0x003e
-#define SMA_bUser_12 0x0040
-#define SMA_bUser_13 0x0041
-#define SMA_wUser_14 0x0042
-#define SMA_wUser_15 0x0044
-#define SMA_wCalFreqAtoD 0x0046
-#define SMA_wUser_16 0x0048
-#define SMA_wUser_17 0x004a
-#define SMA__size 0x004c
-
-#ifdef HAVE_DSPCODEH
-# include "msndperm.c"
-# include "msndinit.c"
-# define PERMCODE msndperm
-# define INITCODE msndinit
-# define PERMCODESIZE sizeof(msndperm)
-# define INITCODESIZE sizeof(msndinit)
-#else
-# ifndef CONFIG_MSNDCLAS_INIT_FILE
-# define CONFIG_MSNDCLAS_INIT_FILE \
- "/etc/sound/msndinit.bin"
-# endif
-# ifndef CONFIG_MSNDCLAS_PERM_FILE
-# define CONFIG_MSNDCLAS_PERM_FILE \
- "/etc/sound/msndperm.bin"
-# endif
-# define PERMCODEFILE CONFIG_MSNDCLAS_PERM_FILE
-# define INITCODEFILE CONFIG_MSNDCLAS_INIT_FILE
-# define PERMCODE dspini
-# define INITCODE permini
-# define PERMCODESIZE sizeof_dspini
-# define INITCODESIZE sizeof_permini
-#endif
-#define LONGNAME "MultiSound (Classic/Monterey/Tahiti)"
-
-#endif /* __MSND_CLASSIC_H */
diff --git a/ANDROID_3.4.5/sound/oss/msnd_pinnacle.c b/ANDROID_3.4.5/sound/oss/msnd_pinnacle.c
deleted file mode 100644
index 536c4c05..00000000
--- a/ANDROID_3.4.5/sound/oss/msnd_pinnacle.c
+++ /dev/null
@@ -1,1935 +0,0 @@
-/*********************************************************************
- *
- * Turtle Beach MultiSound Sound Card Driver for Linux
- * Linux 2.0/2.2 Version
- *
- * msnd_pinnacle.c / msnd_classic.c
- *
- * -- If MSND_CLASSIC is defined:
- *
- * -> driver for Turtle Beach Classic/Monterey/Tahiti
- *
- * -- Else
- *
- * -> driver for Turtle Beach Pinnacle/Fiji
- *
- * Copyright (C) 1998 Andrew Veliath
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * 12-3-2000 Modified IO port validation Steve Sycamore
- *
- ********************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <linux/gfp.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-#include "sound_config.h"
-#include "sound_firmware.h"
-#ifdef MSND_CLASSIC
-# ifndef __alpha__
-# define SLOWIO
-# endif
-#endif
-#include "msnd.h"
-#ifdef MSND_CLASSIC
-# ifdef CONFIG_MSNDCLAS_HAVE_BOOT
-# define HAVE_DSPCODEH
-# endif
-# include "msnd_classic.h"
-# define LOGNAME "msnd_classic"
-#else
-# ifdef CONFIG_MSNDPIN_HAVE_BOOT
-# define HAVE_DSPCODEH
-# endif
-# include "msnd_pinnacle.h"
-# define LOGNAME "msnd_pinnacle"
-#endif
-
-#ifndef CONFIG_MSND_WRITE_NDELAY
-# define CONFIG_MSND_WRITE_NDELAY 1
-#endif
-
-#define get_play_delay_jiffies(size) ((size) * HZ * \
- dev.play_sample_size / 8 / \
- dev.play_sample_rate / \
- dev.play_channels)
-
-#define get_rec_delay_jiffies(size) ((size) * HZ * \
- dev.rec_sample_size / 8 / \
- dev.rec_sample_rate / \
- dev.rec_channels)
-
-static DEFINE_MUTEX(msnd_pinnacle_mutex);
-static multisound_dev_t dev;
-
-#ifndef HAVE_DSPCODEH
-static char *dspini, *permini;
-static int sizeof_dspini, sizeof_permini;
-#endif
-
-static int dsp_full_reset(void);
-static void dsp_write_flush(void);
-
-static __inline__ int chk_send_dsp_cmd(multisound_dev_t *dev, register BYTE cmd)
-{
- if (msnd_send_dsp_cmd(dev, cmd) == 0)
- return 0;
- dsp_full_reset();
- return msnd_send_dsp_cmd(dev, cmd);
-}
-
-static void reset_play_queue(void)
-{
- int n;
- LPDAQD lpDAQ;
-
- dev.last_playbank = -1;
- writew(PCTODSP_OFFSET(0 * DAQDS__size), dev.DAPQ + JQS_wHead);
- writew(PCTODSP_OFFSET(0 * DAQDS__size), dev.DAPQ + JQS_wTail);
-
- for (n = 0, lpDAQ = dev.base + DAPQ_DATA_BUFF; n < 3; ++n, lpDAQ += DAQDS__size) {
- writew(PCTODSP_BASED((DWORD)(DAP_BUFF_SIZE * n)), lpDAQ + DAQDS_wStart);
- writew(0, lpDAQ + DAQDS_wSize);
- writew(1, lpDAQ + DAQDS_wFormat);
- writew(dev.play_sample_size, lpDAQ + DAQDS_wSampleSize);
- writew(dev.play_channels, lpDAQ + DAQDS_wChannels);
- writew(dev.play_sample_rate, lpDAQ + DAQDS_wSampleRate);
- writew(HIMT_PLAY_DONE * 0x100 + n, lpDAQ + DAQDS_wIntMsg);
- writew(n, lpDAQ + DAQDS_wFlags);
- }
-}
-
-static void reset_record_queue(void)
-{
- int n;
- LPDAQD lpDAQ;
- unsigned long flags;
-
- dev.last_recbank = 2;
- writew(PCTODSP_OFFSET(0 * DAQDS__size), dev.DARQ + JQS_wHead);
- writew(PCTODSP_OFFSET(dev.last_recbank * DAQDS__size), dev.DARQ + JQS_wTail);
-
- /* Critical section: bank 1 access */
- spin_lock_irqsave(&dev.lock, flags);
- msnd_outb(HPBLKSEL_1, dev.io + HP_BLKS);
- memset_io(dev.base, 0, DAR_BUFF_SIZE * 3);
- msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS);
- spin_unlock_irqrestore(&dev.lock, flags);
-
- for (n = 0, lpDAQ = dev.base + DARQ_DATA_BUFF; n < 3; ++n, lpDAQ += DAQDS__size) {
- writew(PCTODSP_BASED((DWORD)(DAR_BUFF_SIZE * n)) + 0x4000, lpDAQ + DAQDS_wStart);
- writew(DAR_BUFF_SIZE, lpDAQ + DAQDS_wSize);
- writew(1, lpDAQ + DAQDS_wFormat);
- writew(dev.rec_sample_size, lpDAQ + DAQDS_wSampleSize);
- writew(dev.rec_channels, lpDAQ + DAQDS_wChannels);
- writew(dev.rec_sample_rate, lpDAQ + DAQDS_wSampleRate);
- writew(HIMT_RECORD_DONE * 0x100 + n, lpDAQ + DAQDS_wIntMsg);
- writew(n, lpDAQ + DAQDS_wFlags);
- }
-}
-
-static void reset_queues(void)
-{
- if (dev.mode & FMODE_WRITE) {
- msnd_fifo_make_empty(&dev.DAPF);
- reset_play_queue();
- }
- if (dev.mode & FMODE_READ) {
- msnd_fifo_make_empty(&dev.DARF);
- reset_record_queue();
- }
-}
-
-static int dsp_set_format(struct file *file, int val)
-{
- int data, i;
- LPDAQD lpDAQ, lpDARQ;
-
- lpDAQ = dev.base + DAPQ_DATA_BUFF;
- lpDARQ = dev.base + DARQ_DATA_BUFF;
-
- switch (val) {
- case AFMT_U8:
- case AFMT_S16_LE:
- data = val;
- break;
- default:
- data = DEFSAMPLESIZE;
- break;
- }
-
- for (i = 0; i < 3; ++i, lpDAQ += DAQDS__size, lpDARQ += DAQDS__size) {
- if (file->f_mode & FMODE_WRITE)
- writew(data, lpDAQ + DAQDS_wSampleSize);
- if (file->f_mode & FMODE_READ)
- writew(data, lpDARQ + DAQDS_wSampleSize);
- }
- if (file->f_mode & FMODE_WRITE)
- dev.play_sample_size = data;
- if (file->f_mode & FMODE_READ)
- dev.rec_sample_size = data;
-
- return data;
-}
-
-static int dsp_get_frag_size(void)
-{
- int size;
- size = dev.fifosize / 4;
- if (size > 32 * 1024)
- size = 32 * 1024;
- return size;
-}
-
-static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- int val, i, data, tmp;
- LPDAQD lpDAQ, lpDARQ;
- audio_buf_info abinfo;
- unsigned long flags;
- int __user *p = (int __user *)arg;
-
- lpDAQ = dev.base + DAPQ_DATA_BUFF;
- lpDARQ = dev.base + DARQ_DATA_BUFF;
-
- switch (cmd) {
- case SNDCTL_DSP_SUBDIVIDE:
- case SNDCTL_DSP_SETFRAGMENT:
- case SNDCTL_DSP_SETDUPLEX:
- case SNDCTL_DSP_POST:
- return 0;
-
- case SNDCTL_DSP_GETIPTR:
- case SNDCTL_DSP_GETOPTR:
- case SNDCTL_DSP_MAPINBUF:
- case SNDCTL_DSP_MAPOUTBUF:
- return -EINVAL;
-
- case SNDCTL_DSP_GETOSPACE:
- if (!(file->f_mode & FMODE_WRITE))
- return -EINVAL;
- spin_lock_irqsave(&dev.lock, flags);
- abinfo.fragsize = dsp_get_frag_size();
- abinfo.bytes = dev.DAPF.n - dev.DAPF.len;
- abinfo.fragstotal = dev.DAPF.n / abinfo.fragsize;
- abinfo.fragments = abinfo.bytes / abinfo.fragsize;
- spin_unlock_irqrestore(&dev.lock, flags);
- return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
- case SNDCTL_DSP_GETISPACE:
- if (!(file->f_mode & FMODE_READ))
- return -EINVAL;
- spin_lock_irqsave(&dev.lock, flags);
- abinfo.fragsize = dsp_get_frag_size();
- abinfo.bytes = dev.DARF.n - dev.DARF.len;
- abinfo.fragstotal = dev.DARF.n / abinfo.fragsize;
- abinfo.fragments = abinfo.bytes / abinfo.fragsize;
- spin_unlock_irqrestore(&dev.lock, flags);
- return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
- case SNDCTL_DSP_RESET:
- dev.nresets = 0;
- reset_queues();
- return 0;
-
- case SNDCTL_DSP_SYNC:
- dsp_write_flush();
- return 0;
-
- case SNDCTL_DSP_GETBLKSIZE:
- tmp = dsp_get_frag_size();
- if (put_user(tmp, p))
- return -EFAULT;
- return 0;
-
- case SNDCTL_DSP_GETFMTS:
- val = AFMT_S16_LE | AFMT_U8;
- if (put_user(val, p))
- return -EFAULT;
- return 0;
-
- case SNDCTL_DSP_SETFMT:
- if (get_user(val, p))
- return -EFAULT;
-
- if (file->f_mode & FMODE_WRITE)
- data = val == AFMT_QUERY
- ? dev.play_sample_size
- : dsp_set_format(file, val);
- else
- data = val == AFMT_QUERY
- ? dev.rec_sample_size
- : dsp_set_format(file, val);
-
- if (put_user(data, p))
- return -EFAULT;
- return 0;
-
- case SNDCTL_DSP_NONBLOCK:
- if (!test_bit(F_DISABLE_WRITE_NDELAY, &dev.flags) &&
- file->f_mode & FMODE_WRITE)
- dev.play_ndelay = 1;
- if (file->f_mode & FMODE_READ)
- dev.rec_ndelay = 1;
- return 0;
-
- case SNDCTL_DSP_GETCAPS:
- val = DSP_CAP_DUPLEX | DSP_CAP_BATCH;
- if (put_user(val, p))
- return -EFAULT;
- return 0;
-
- case SNDCTL_DSP_SPEED:
- if (get_user(val, p))
- return -EFAULT;
-
- if (val < 8000)
- val = 8000;
-
- if (val > 48000)
- val = 48000;
-
- data = val;
-
- for (i = 0; i < 3; ++i, lpDAQ += DAQDS__size, lpDARQ += DAQDS__size) {
- if (file->f_mode & FMODE_WRITE)
- writew(data, lpDAQ + DAQDS_wSampleRate);
- if (file->f_mode & FMODE_READ)
- writew(data, lpDARQ + DAQDS_wSampleRate);
- }
- if (file->f_mode & FMODE_WRITE)
- dev.play_sample_rate = data;
- if (file->f_mode & FMODE_READ)
- dev.rec_sample_rate = data;
-
- if (put_user(data, p))
- return -EFAULT;
- return 0;
-
- case SNDCTL_DSP_CHANNELS:
- case SNDCTL_DSP_STEREO:
- if (get_user(val, p))
- return -EFAULT;
-
- if (cmd == SNDCTL_DSP_CHANNELS) {
- switch (val) {
- case 1:
- case 2:
- data = val;
- break;
- default:
- val = data = 2;
- break;
- }
- } else {
- switch (val) {
- case 0:
- data = 1;
- break;
- default:
- val = 1;
- case 1:
- data = 2;
- break;
- }
- }
-
- for (i = 0; i < 3; ++i, lpDAQ += DAQDS__size, lpDARQ += DAQDS__size) {
- if (file->f_mode & FMODE_WRITE)
- writew(data, lpDAQ + DAQDS_wChannels);
- if (file->f_mode & FMODE_READ)
- writew(data, lpDARQ + DAQDS_wChannels);
- }
- if (file->f_mode & FMODE_WRITE)
- dev.play_channels = data;
- if (file->f_mode & FMODE_READ)
- dev.rec_channels = data;
-
- if (put_user(val, p))
- return -EFAULT;
- return 0;
- }
-
- return -EINVAL;
-}
-
-static int mixer_get(int d)
-{
- if (d > 31)
- return -EINVAL;
-
- switch (d) {
- case SOUND_MIXER_VOLUME:
- case SOUND_MIXER_PCM:
- case SOUND_MIXER_LINE:
- case SOUND_MIXER_IMIX:
- case SOUND_MIXER_LINE1:
-#ifndef MSND_CLASSIC
- case SOUND_MIXER_MIC:
- case SOUND_MIXER_SYNTH:
-#endif
- return (dev.left_levels[d] >> 8) * 100 / 0xff |
- (((dev.right_levels[d] >> 8) * 100 / 0xff) << 8);
- default:
- return 0;
- }
-}
-
-#define update_volm(a,b) \
- writew((dev.left_levels[a] >> 1) * \
- readw(dev.SMA + SMA_wCurrMastVolLeft) / 0xffff, \
- dev.SMA + SMA_##b##Left); \
- writew((dev.right_levels[a] >> 1) * \
- readw(dev.SMA + SMA_wCurrMastVolRight) / 0xffff, \
- dev.SMA + SMA_##b##Right);
-
-#define update_potm(d,s,ar) \
- writeb((dev.left_levels[d] >> 8) * \
- readw(dev.SMA + SMA_wCurrMastVolLeft) / 0xffff, \
- dev.SMA + SMA_##s##Left); \
- writeb((dev.right_levels[d] >> 8) * \
- readw(dev.SMA + SMA_wCurrMastVolRight) / 0xffff, \
- dev.SMA + SMA_##s##Right); \
- if (msnd_send_word(&dev, 0, 0, ar) == 0) \
- chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
-
-#define update_pot(d,s,ar) \
- writeb(dev.left_levels[d] >> 8, \
- dev.SMA + SMA_##s##Left); \
- writeb(dev.right_levels[d] >> 8, \
- dev.SMA + SMA_##s##Right); \
- if (msnd_send_word(&dev, 0, 0, ar) == 0) \
- chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
-
-static int mixer_set(int d, int value)
-{
- int left = value & 0x000000ff;
- int right = (value & 0x0000ff00) >> 8;
- int bLeft, bRight;
- int wLeft, wRight;
- int updatemaster = 0;
-
- if (d > 31)
- return -EINVAL;
-
- bLeft = left * 0xff / 100;
- wLeft = left * 0xffff / 100;
-
- bRight = right * 0xff / 100;
- wRight = right * 0xffff / 100;
-
- dev.left_levels[d] = wLeft;
- dev.right_levels[d] = wRight;
-
- switch (d) {
- /* master volume unscaled controls */
- case SOUND_MIXER_LINE: /* line pot control */
- /* scaled by IMIX in digital mix */
- writeb(bLeft, dev.SMA + SMA_bInPotPosLeft);
- writeb(bRight, dev.SMA + SMA_bInPotPosRight);
- if (msnd_send_word(&dev, 0, 0, HDEXAR_IN_SET_POTS) == 0)
- chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
- break;
-#ifndef MSND_CLASSIC
- case SOUND_MIXER_MIC: /* mic pot control */
- /* scaled by IMIX in digital mix */
- writeb(bLeft, dev.SMA + SMA_bMicPotPosLeft);
- writeb(bRight, dev.SMA + SMA_bMicPotPosRight);
- if (msnd_send_word(&dev, 0, 0, HDEXAR_MIC_SET_POTS) == 0)
- chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
- break;
-#endif
- case SOUND_MIXER_VOLUME: /* master volume */
- writew(wLeft, dev.SMA + SMA_wCurrMastVolLeft);
- writew(wRight, dev.SMA + SMA_wCurrMastVolRight);
- /* fall through */
-
- case SOUND_MIXER_LINE1: /* aux pot control */
- /* scaled by master volume */
- /* fall through */
-
- /* digital controls */
- case SOUND_MIXER_SYNTH: /* synth vol (dsp mix) */
- case SOUND_MIXER_PCM: /* pcm vol (dsp mix) */
- case SOUND_MIXER_IMIX: /* input monitor (dsp mix) */
- /* scaled by master volume */
- updatemaster = 1;
- break;
-
- default:
- return 0;
- }
-
- if (updatemaster) {
- /* update master volume scaled controls */
- update_volm(SOUND_MIXER_PCM, wCurrPlayVol);
- update_volm(SOUND_MIXER_IMIX, wCurrInVol);
-#ifndef MSND_CLASSIC
- update_volm(SOUND_MIXER_SYNTH, wCurrMHdrVol);
-#endif
- update_potm(SOUND_MIXER_LINE1, bAuxPotPos, HDEXAR_AUX_SET_POTS);
- }
-
- return mixer_get(d);
-}
-
-static void mixer_setup(void)
-{
- update_pot(SOUND_MIXER_LINE, bInPotPos, HDEXAR_IN_SET_POTS);
- update_potm(SOUND_MIXER_LINE1, bAuxPotPos, HDEXAR_AUX_SET_POTS);
- update_volm(SOUND_MIXER_PCM, wCurrPlayVol);
- update_volm(SOUND_MIXER_IMIX, wCurrInVol);
-#ifndef MSND_CLASSIC
- update_pot(SOUND_MIXER_MIC, bMicPotPos, HDEXAR_MIC_SET_POTS);
- update_volm(SOUND_MIXER_SYNTH, wCurrMHdrVol);
-#endif
-}
-
-static unsigned long set_recsrc(unsigned long recsrc)
-{
- if (dev.recsrc == recsrc)
- return dev.recsrc;
-#ifdef HAVE_NORECSRC
- else if (recsrc == 0)
- dev.recsrc = 0;
-#endif
- else
- dev.recsrc ^= recsrc;
-
-#ifndef MSND_CLASSIC
- if (dev.recsrc & SOUND_MASK_IMIX) {
- if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_ANA_IN) == 0)
- chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
- }
- else if (dev.recsrc & SOUND_MASK_SYNTH) {
- if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_SYNTH_IN) == 0)
- chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
- }
- else if ((dev.recsrc & SOUND_MASK_DIGITAL1) && test_bit(F_HAVEDIGITAL, &dev.flags)) {
- if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_DAT_IN) == 0)
- chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
- }
- else {
-#ifdef HAVE_NORECSRC
- /* Select no input (?) */
- dev.recsrc = 0;
-#else
- dev.recsrc = SOUND_MASK_IMIX;
- if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_ANA_IN) == 0)
- chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);
-#endif
- }
-#endif /* MSND_CLASSIC */
-
- return dev.recsrc;
-}
-
-static unsigned long force_recsrc(unsigned long recsrc)
-{
- dev.recsrc = 0;
- return set_recsrc(recsrc);
-}
-
-#define set_mixer_info() \
- memset(&info, 0, sizeof(info)); \
- strlcpy(info.id, "MSNDMIXER", sizeof(info.id)); \
- strlcpy(info.name, "MultiSound Mixer", sizeof(info.name));
-
-static int mixer_ioctl(unsigned int cmd, unsigned long arg)
-{
- if (cmd == SOUND_MIXER_INFO) {
- mixer_info info;
- set_mixer_info();
- info.modify_counter = dev.mixer_mod_count;
- if (copy_to_user((void __user *)arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- } else if (cmd == SOUND_OLD_MIXER_INFO) {
- _old_mixer_info info;
- set_mixer_info();
- if (copy_to_user((void __user *)arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- } else if (cmd == SOUND_MIXER_PRIVATE1) {
- dev.nresets = 0;
- dsp_full_reset();
- return 0;
- } else if (((cmd >> 8) & 0xff) == 'M') {
- int val = 0;
-
- if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
- switch (cmd & 0xff) {
- case SOUND_MIXER_RECSRC:
- if (get_user(val, (int __user *)arg))
- return -EFAULT;
- val = set_recsrc(val);
- break;
-
- default:
- if (get_user(val, (int __user *)arg))
- return -EFAULT;
- val = mixer_set(cmd & 0xff, val);
- break;
- }
- ++dev.mixer_mod_count;
- return put_user(val, (int __user *)arg);
- } else {
- switch (cmd & 0xff) {
- case SOUND_MIXER_RECSRC:
- val = dev.recsrc;
- break;
-
- case SOUND_MIXER_DEVMASK:
- case SOUND_MIXER_STEREODEVS:
- val = SOUND_MASK_PCM |
- SOUND_MASK_LINE |
- SOUND_MASK_IMIX |
- SOUND_MASK_LINE1 |
-#ifndef MSND_CLASSIC
- SOUND_MASK_MIC |
- SOUND_MASK_SYNTH |
-#endif
- SOUND_MASK_VOLUME;
- break;
-
- case SOUND_MIXER_RECMASK:
-#ifdef MSND_CLASSIC
- val = 0;
-#else
- val = SOUND_MASK_IMIX |
- SOUND_MASK_SYNTH;
- if (test_bit(F_HAVEDIGITAL, &dev.flags))
- val |= SOUND_MASK_DIGITAL1;
-#endif
- break;
-
- case SOUND_MIXER_CAPS:
- val = SOUND_CAP_EXCL_INPUT;
- break;
-
- default:
- if ((val = mixer_get(cmd & 0xff)) < 0)
- return -EINVAL;
- break;
- }
- }
-
- return put_user(val, (int __user *)arg);
- }
-
- return -EINVAL;
-}
-
-static long dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- int minor = iminor(file->f_path.dentry->d_inode);
- int ret;
-
- if (cmd == OSS_GETVERSION) {
- int sound_version = SOUND_VERSION;
- return put_user(sound_version, (int __user *)arg);
- }
-
- ret = -EINVAL;
-
- mutex_lock(&msnd_pinnacle_mutex);
- if (minor == dev.dsp_minor)
- ret = dsp_ioctl(file, cmd, arg);
- else if (minor == dev.mixer_minor)
- ret = mixer_ioctl(cmd, arg);
- mutex_unlock(&msnd_pinnacle_mutex);
-
- return ret;
-}
-
-static void dsp_write_flush(void)
-{
- if (!(dev.mode & FMODE_WRITE) || !test_bit(F_WRITING, &dev.flags))
- return;
- set_bit(F_WRITEFLUSH, &dev.flags);
- interruptible_sleep_on_timeout(
- &dev.writeflush,
- get_play_delay_jiffies(dev.DAPF.len));
- clear_bit(F_WRITEFLUSH, &dev.flags);
- if (!signal_pending(current)) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(get_play_delay_jiffies(DAP_BUFF_SIZE));
- }
- clear_bit(F_WRITING, &dev.flags);
-}
-
-static void dsp_halt(struct file *file)
-{
- if ((file ? file->f_mode : dev.mode) & FMODE_READ) {
- clear_bit(F_READING, &dev.flags);
- chk_send_dsp_cmd(&dev, HDEX_RECORD_STOP);
- msnd_disable_irq(&dev);
- if (file) {
- printk(KERN_DEBUG LOGNAME ": Stopping read for %p\n", file);
- dev.mode &= ~FMODE_READ;
- }
- clear_bit(F_AUDIO_READ_INUSE, &dev.flags);
- }
- if ((file ? file->f_mode : dev.mode) & FMODE_WRITE) {
- if (test_bit(F_WRITING, &dev.flags)) {
- dsp_write_flush();
- chk_send_dsp_cmd(&dev, HDEX_PLAY_STOP);
- }
- msnd_disable_irq(&dev);
- if (file) {
- printk(KERN_DEBUG LOGNAME ": Stopping write for %p\n", file);
- dev.mode &= ~FMODE_WRITE;
- }
- clear_bit(F_AUDIO_WRITE_INUSE, &dev.flags);
- }
-}
-
-static int dsp_release(struct file *file)
-{
- dsp_halt(file);
- return 0;
-}
-
-static int dsp_open(struct file *file)
-{
- if ((file ? file->f_mode : dev.mode) & FMODE_WRITE) {
- set_bit(F_AUDIO_WRITE_INUSE, &dev.flags);
- clear_bit(F_WRITING, &dev.flags);
- msnd_fifo_make_empty(&dev.DAPF);
- reset_play_queue();
- if (file) {
- printk(KERN_DEBUG LOGNAME ": Starting write for %p\n", file);
- dev.mode |= FMODE_WRITE;
- }
- msnd_enable_irq(&dev);
- }
- if ((file ? file->f_mode : dev.mode) & FMODE_READ) {
- set_bit(F_AUDIO_READ_INUSE, &dev.flags);
- clear_bit(F_READING, &dev.flags);
- msnd_fifo_make_empty(&dev.DARF);
- reset_record_queue();
- if (file) {
- printk(KERN_DEBUG LOGNAME ": Starting read for %p\n", file);
- dev.mode |= FMODE_READ;
- }
- msnd_enable_irq(&dev);
- }
- return 0;
-}
-
-static void set_default_play_audio_parameters(void)
-{
- dev.play_sample_size = DEFSAMPLESIZE;
- dev.play_sample_rate = DEFSAMPLERATE;
- dev.play_channels = DEFCHANNELS;
-}
-
-static void set_default_rec_audio_parameters(void)
-{
- dev.rec_sample_size = DEFSAMPLESIZE;
- dev.rec_sample_rate = DEFSAMPLERATE;
- dev.rec_channels = DEFCHANNELS;
-}
-
-static void set_default_audio_parameters(void)
-{
- set_default_play_audio_parameters();
- set_default_rec_audio_parameters();
-}
-
-static int dev_open(struct inode *inode, struct file *file)
-{
- int minor = iminor(inode);
- int err = 0;
-
- mutex_lock(&msnd_pinnacle_mutex);
- if (minor == dev.dsp_minor) {
- if ((file->f_mode & FMODE_WRITE &&
- test_bit(F_AUDIO_WRITE_INUSE, &dev.flags)) ||
- (file->f_mode & FMODE_READ &&
- test_bit(F_AUDIO_READ_INUSE, &dev.flags))) {
- err = -EBUSY;
- goto out;
- }
-
- if ((err = dsp_open(file)) >= 0) {
- dev.nresets = 0;
- if (file->f_mode & FMODE_WRITE) {
- set_default_play_audio_parameters();
- if (!test_bit(F_DISABLE_WRITE_NDELAY, &dev.flags))
- dev.play_ndelay = (file->f_flags & O_NDELAY) ? 1 : 0;
- else
- dev.play_ndelay = 0;
- }
- if (file->f_mode & FMODE_READ) {
- set_default_rec_audio_parameters();
- dev.rec_ndelay = (file->f_flags & O_NDELAY) ? 1 : 0;
- }
- }
- }
- else if (minor == dev.mixer_minor) {
- /* nothing */
- } else
- err = -EINVAL;
-out:
- mutex_unlock(&msnd_pinnacle_mutex);
- return err;
-}
-
-static int dev_release(struct inode *inode, struct file *file)
-{
- int minor = iminor(inode);
- int err = 0;
-
- mutex_lock(&msnd_pinnacle_mutex);
- if (minor == dev.dsp_minor)
- err = dsp_release(file);
- else if (minor == dev.mixer_minor) {
- /* nothing */
- } else
- err = -EINVAL;
- mutex_unlock(&msnd_pinnacle_mutex);
- return err;
-}
-
-static __inline__ int pack_DARQ_to_DARF(register int bank)
-{
- register int size, timeout = 3;
- register WORD wTmp;
- LPDAQD DAQD;
-
- /* Increment the tail and check for queue wrap */
- wTmp = readw(dev.DARQ + JQS_wTail) + PCTODSP_OFFSET(DAQDS__size);
- if (wTmp > readw(dev.DARQ + JQS_wSize))
- wTmp = 0;
- while (wTmp == readw(dev.DARQ + JQS_wHead) && timeout--)
- udelay(1);
- writew(wTmp, dev.DARQ + JQS_wTail);
-
- /* Get our digital audio queue struct */
- DAQD = bank * DAQDS__size + dev.base + DARQ_DATA_BUFF;
-
- /* Get length of data */
- size = readw(DAQD + DAQDS_wSize);
-
- /* Read data from the head (unprotected bank 1 access okay
- since this is only called inside an interrupt) */
- msnd_outb(HPBLKSEL_1, dev.io + HP_BLKS);
- msnd_fifo_write_io(
- &dev.DARF,
- dev.base + bank * DAR_BUFF_SIZE,
- size);
- msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS);
-
- return 1;
-}
-
-static __inline__ int pack_DAPF_to_DAPQ(register int start)
-{
- register WORD DAPQ_tail;
- register int protect = start, nbanks = 0;
- LPDAQD DAQD;
-
- DAPQ_tail = readw(dev.DAPQ + JQS_wTail);
- while (DAPQ_tail != readw(dev.DAPQ + JQS_wHead) || start) {
- register int bank_num = DAPQ_tail / PCTODSP_OFFSET(DAQDS__size);
- register int n;
- unsigned long flags;
-
- /* Write the data to the new tail */
- if (protect) {
- /* Critical section: protect fifo in non-interrupt */
- spin_lock_irqsave(&dev.lock, flags);
- n = msnd_fifo_read_io(
- &dev.DAPF,
- dev.base + bank_num * DAP_BUFF_SIZE,
- DAP_BUFF_SIZE);
- spin_unlock_irqrestore(&dev.lock, flags);
- } else {
- n = msnd_fifo_read_io(
- &dev.DAPF,
- dev.base + bank_num * DAP_BUFF_SIZE,
- DAP_BUFF_SIZE);
- }
- if (!n)
- break;
-
- if (start)
- start = 0;
-
- /* Get our digital audio queue struct */
- DAQD = bank_num * DAQDS__size + dev.base + DAPQ_DATA_BUFF;
-
- /* Write size of this bank */
- writew(n, DAQD + DAQDS_wSize);
- ++nbanks;
-
- /* Then advance the tail */
- DAPQ_tail = (++bank_num % 3) * PCTODSP_OFFSET(DAQDS__size);
- writew(DAPQ_tail, dev.DAPQ + JQS_wTail);
- /* Tell the DSP to play the bank */
- msnd_send_dsp_cmd(&dev, HDEX_PLAY_START);
- }
- return nbanks;
-}
-
-static int dsp_read(char __user *buf, size_t len)
-{
- int count = len;
- char *page = (char *)__get_free_page(GFP_KERNEL);
-
- if (!page)
- return -ENOMEM;
-
- while (count > 0) {
- int n, k;
- unsigned long flags;
-
- k = PAGE_SIZE;
- if (k > count)
- k = count;
-
- /* Critical section: protect fifo in non-interrupt */
- spin_lock_irqsave(&dev.lock, flags);
- n = msnd_fifo_read(&dev.DARF, page, k);
- spin_unlock_irqrestore(&dev.lock, flags);
- if (copy_to_user(buf, page, n)) {
- free_page((unsigned long)page);
- return -EFAULT;
- }
- buf += n;
- count -= n;
-
- if (n == k && count)
- continue;
-
- if (!test_bit(F_READING, &dev.flags) && dev.mode & FMODE_READ) {
- dev.last_recbank = -1;
- if (chk_send_dsp_cmd(&dev, HDEX_RECORD_START) == 0)
- set_bit(F_READING, &dev.flags);
- }
-
- if (dev.rec_ndelay) {
- free_page((unsigned long)page);
- return count == len ? -EAGAIN : len - count;
- }
-
- if (count > 0) {
- set_bit(F_READBLOCK, &dev.flags);
- if (!interruptible_sleep_on_timeout(
- &dev.readblock,
- get_rec_delay_jiffies(DAR_BUFF_SIZE)))
- clear_bit(F_READING, &dev.flags);
- clear_bit(F_READBLOCK, &dev.flags);
- if (signal_pending(current)) {
- free_page((unsigned long)page);
- return -EINTR;
- }
- }
- }
- free_page((unsigned long)page);
- return len - count;
-}
-
-static int dsp_write(const char __user *buf, size_t len)
-{
- int count = len;
- char *page = (char *)__get_free_page(GFP_KERNEL);
-
- if (!page)
- return -ENOMEM;
-
- while (count > 0) {
- int n, k;
- unsigned long flags;
-
- k = PAGE_SIZE;
- if (k > count)
- k = count;
-
- if (copy_from_user(page, buf, k)) {
- free_page((unsigned long)page);
- return -EFAULT;
- }
-
- /* Critical section: protect fifo in non-interrupt */
- spin_lock_irqsave(&dev.lock, flags);
- n = msnd_fifo_write(&dev.DAPF, page, k);
- spin_unlock_irqrestore(&dev.lock, flags);
- buf += n;
- count -= n;
-
- if (count && n == k)
- continue;
-
- if (!test_bit(F_WRITING, &dev.flags) && (dev.mode & FMODE_WRITE)) {
- dev.last_playbank = -1;
- if (pack_DAPF_to_DAPQ(1) > 0)
- set_bit(F_WRITING, &dev.flags);
- }
-
- if (dev.play_ndelay) {
- free_page((unsigned long)page);
- return count == len ? -EAGAIN : len - count;
- }
-
- if (count > 0) {
- set_bit(F_WRITEBLOCK, &dev.flags);
- interruptible_sleep_on_timeout(
- &dev.writeblock,
- get_play_delay_jiffies(DAP_BUFF_SIZE));
- clear_bit(F_WRITEBLOCK, &dev.flags);
- if (signal_pending(current)) {
- free_page((unsigned long)page);
- return -EINTR;
- }
- }
- }
-
- free_page((unsigned long)page);
- return len - count;
-}
-
-static ssize_t dev_read(struct file *file, char __user *buf, size_t count, loff_t *off)
-{
- int minor = iminor(file->f_path.dentry->d_inode);
- if (minor == dev.dsp_minor)
- return dsp_read(buf, count);
- else
- return -EINVAL;
-}
-
-static ssize_t dev_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
-{
- int minor = iminor(file->f_path.dentry->d_inode);
- if (minor == dev.dsp_minor)
- return dsp_write(buf, count);
- else
- return -EINVAL;
-}
-
-static __inline__ void eval_dsp_msg(register WORD wMessage)
-{
- switch (HIBYTE(wMessage)) {
- case HIMT_PLAY_DONE:
- if (dev.last_playbank == LOBYTE(wMessage) || !test_bit(F_WRITING, &dev.flags))
- break;
- dev.last_playbank = LOBYTE(wMessage);
-
- if (pack_DAPF_to_DAPQ(0) <= 0) {
- if (!test_bit(F_WRITEBLOCK, &dev.flags)) {
- if (test_and_clear_bit(F_WRITEFLUSH, &dev.flags))
- wake_up_interruptible(&dev.writeflush);
- }
- clear_bit(F_WRITING, &dev.flags);
- }
-
- if (test_bit(F_WRITEBLOCK, &dev.flags))
- wake_up_interruptible(&dev.writeblock);
- break;
-
- case HIMT_RECORD_DONE:
- if (dev.last_recbank == LOBYTE(wMessage))
- break;
- dev.last_recbank = LOBYTE(wMessage);
-
- pack_DARQ_to_DARF(dev.last_recbank);
-
- if (test_bit(F_READBLOCK, &dev.flags))
- wake_up_interruptible(&dev.readblock);
- break;
-
- case HIMT_DSP:
- switch (LOBYTE(wMessage)) {
-#ifndef MSND_CLASSIC
- case HIDSP_PLAY_UNDER:
-#endif
- case HIDSP_INT_PLAY_UNDER:
-/* printk(KERN_DEBUG LOGNAME ": Play underflow\n"); */
- clear_bit(F_WRITING, &dev.flags);
- break;
-
- case HIDSP_INT_RECORD_OVER:
-/* printk(KERN_DEBUG LOGNAME ": Record overflow\n"); */
- clear_bit(F_READING, &dev.flags);
- break;
-
- default:
-/* printk(KERN_DEBUG LOGNAME ": DSP message %d 0x%02x\n",
- LOBYTE(wMessage), LOBYTE(wMessage)); */
- break;
- }
- break;
-
- case HIMT_MIDI_IN_UCHAR:
- if (dev.midi_in_interrupt)
- (*dev.midi_in_interrupt)(&dev);
- break;
-
- default:
-/* printk(KERN_DEBUG LOGNAME ": HIMT message %d 0x%02x\n", HIBYTE(wMessage), HIBYTE(wMessage)); */
- break;
- }
-}
-
-static irqreturn_t intr(int irq, void *dev_id)
-{
- /* Send ack to DSP */
- msnd_inb(dev.io + HP_RXL);
-
- /* Evaluate queued DSP messages */
- while (readw(dev.DSPQ + JQS_wTail) != readw(dev.DSPQ + JQS_wHead)) {
- register WORD wTmp;
-
- eval_dsp_msg(readw(dev.pwDSPQData + 2*readw(dev.DSPQ + JQS_wHead)));
-
- if ((wTmp = readw(dev.DSPQ + JQS_wHead) + 1) > readw(dev.DSPQ + JQS_wSize))
- writew(0, dev.DSPQ + JQS_wHead);
- else
- writew(wTmp, dev.DSPQ + JQS_wHead);
- }
- return IRQ_HANDLED;
-}
-
-static const struct file_operations dev_fileops = {
- .owner = THIS_MODULE,
- .read = dev_read,
- .write = dev_write,
- .unlocked_ioctl = dev_ioctl,
- .open = dev_open,
- .release = dev_release,
- .llseek = noop_llseek,
-};
-
-static int reset_dsp(void)
-{
- int timeout = 100;
-
- msnd_outb(HPDSPRESET_ON, dev.io + HP_DSPR);
- mdelay(1);
-#ifndef MSND_CLASSIC
- dev.info = msnd_inb(dev.io + HP_INFO);
-#endif
- msnd_outb(HPDSPRESET_OFF, dev.io + HP_DSPR);
- mdelay(1);
- while (timeout-- > 0) {
- if (msnd_inb(dev.io + HP_CVR) == HP_CVR_DEF)
- return 0;
- mdelay(1);
- }
- printk(KERN_ERR LOGNAME ": Cannot reset DSP\n");
-
- return -EIO;
-}
-
-static int __init probe_multisound(void)
-{
-#ifndef MSND_CLASSIC
- char *xv, *rev = NULL;
- char *pin = "Pinnacle", *fiji = "Fiji";
- char *pinfiji = "Pinnacle/Fiji";
-#endif
-
- if (!request_region(dev.io, dev.numio, "probing")) {
- printk(KERN_ERR LOGNAME ": I/O port conflict\n");
- return -ENODEV;
- }
-
- if (reset_dsp() < 0) {
- release_region(dev.io, dev.numio);
- return -ENODEV;
- }
-
-#ifdef MSND_CLASSIC
- dev.name = "Classic/Tahiti/Monterey";
- printk(KERN_INFO LOGNAME ": %s, "
-#else
- switch (dev.info >> 4) {
- case 0xf: xv = "<= 1.15"; break;
- case 0x1: xv = "1.18/1.2"; break;
- case 0x2: xv = "1.3"; break;
- case 0x3: xv = "1.4"; break;
- default: xv = "unknown"; break;
- }
-
- switch (dev.info & 0x7) {
- case 0x0: rev = "I"; dev.name = pin; break;
- case 0x1: rev = "F"; dev.name = pin; break;
- case 0x2: rev = "G"; dev.name = pin; break;
- case 0x3: rev = "H"; dev.name = pin; break;
- case 0x4: rev = "E"; dev.name = fiji; break;
- case 0x5: rev = "C"; dev.name = fiji; break;
- case 0x6: rev = "D"; dev.name = fiji; break;
- case 0x7:
- rev = "A-B (Fiji) or A-E (Pinnacle)";
- dev.name = pinfiji;
- break;
- }
- printk(KERN_INFO LOGNAME ": %s revision %s, Xilinx version %s, "
-#endif /* MSND_CLASSIC */
- "I/O 0x%x-0x%x, IRQ %d, memory mapped to %p-%p\n",
- dev.name,
-#ifndef MSND_CLASSIC
- rev, xv,
-#endif
- dev.io, dev.io + dev.numio - 1,
- dev.irq,
- dev.base, dev.base + 0x7fff);
-
- release_region(dev.io, dev.numio);
- return 0;
-}
-
-static int init_sma(void)
-{
- static int initted;
- WORD mastVolLeft, mastVolRight;
- unsigned long flags;
-
-#ifdef MSND_CLASSIC
- msnd_outb(dev.memid, dev.io + HP_MEMM);
-#endif
- msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS);
- if (initted) {
- mastVolLeft = readw(dev.SMA + SMA_wCurrMastVolLeft);
- mastVolRight = readw(dev.SMA + SMA_wCurrMastVolRight);
- } else
- mastVolLeft = mastVolRight = 0;
- memset_io(dev.base, 0, 0x8000);
-
- /* Critical section: bank 1 access */
- spin_lock_irqsave(&dev.lock, flags);
- msnd_outb(HPBLKSEL_1, dev.io + HP_BLKS);
- memset_io(dev.base, 0, 0x8000);
- msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS);
- spin_unlock_irqrestore(&dev.lock, flags);
-
- dev.pwDSPQData = (dev.base + DSPQ_DATA_BUFF);
- dev.pwMODQData = (dev.base + MODQ_DATA_BUFF);
- dev.pwMIDQData = (dev.base + MIDQ_DATA_BUFF);
-
- /* Motorola 56k shared memory base */
- dev.SMA = dev.base + SMA_STRUCT_START;
-
- /* Digital audio play queue */
- dev.DAPQ = dev.base + DAPQ_OFFSET;
- msnd_init_queue(dev.DAPQ, DAPQ_DATA_BUFF, DAPQ_BUFF_SIZE);
-
- /* Digital audio record queue */
- dev.DARQ = dev.base + DARQ_OFFSET;
- msnd_init_queue(dev.DARQ, DARQ_DATA_BUFF, DARQ_BUFF_SIZE);
-
- /* MIDI out queue */
- dev.MODQ = dev.base + MODQ_OFFSET;
- msnd_init_queue(dev.MODQ, MODQ_DATA_BUFF, MODQ_BUFF_SIZE);
-
- /* MIDI in queue */
- dev.MIDQ = dev.base + MIDQ_OFFSET;
- msnd_init_queue(dev.MIDQ, MIDQ_DATA_BUFF, MIDQ_BUFF_SIZE);
-
- /* DSP -> host message queue */
- dev.DSPQ = dev.base + DSPQ_OFFSET;
- msnd_init_queue(dev.DSPQ, DSPQ_DATA_BUFF, DSPQ_BUFF_SIZE);
-
- /* Setup some DSP values */
-#ifndef MSND_CLASSIC
- writew(1, dev.SMA + SMA_wCurrPlayFormat);
- writew(dev.play_sample_size, dev.SMA + SMA_wCurrPlaySampleSize);
- writew(dev.play_channels, dev.SMA + SMA_wCurrPlayChannels);
- writew(dev.play_sample_rate, dev.SMA + SMA_wCurrPlaySampleRate);
-#endif
- writew(dev.play_sample_rate, dev.SMA + SMA_wCalFreqAtoD);
- writew(mastVolLeft, dev.SMA + SMA_wCurrMastVolLeft);
- writew(mastVolRight, dev.SMA + SMA_wCurrMastVolRight);
-#ifndef MSND_CLASSIC
- writel(0x00010000, dev.SMA + SMA_dwCurrPlayPitch);
- writel(0x00000001, dev.SMA + SMA_dwCurrPlayRate);
-#endif
- writew(0x303, dev.SMA + SMA_wCurrInputTagBits);
-
- initted = 1;
-
- return 0;
-}
-
-static int __init calibrate_adc(WORD srate)
-{
- writew(srate, dev.SMA + SMA_wCalFreqAtoD);
- if (dev.calibrate_signal == 0)
- writew(readw(dev.SMA + SMA_wCurrHostStatusFlags)
- | 0x0001, dev.SMA + SMA_wCurrHostStatusFlags);
- else
- writew(readw(dev.SMA + SMA_wCurrHostStatusFlags)
- & ~0x0001, dev.SMA + SMA_wCurrHostStatusFlags);
- if (msnd_send_word(&dev, 0, 0, HDEXAR_CAL_A_TO_D) == 0 &&
- chk_send_dsp_cmd(&dev, HDEX_AUX_REQ) == 0) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HZ / 3);
- return 0;
- }
- printk(KERN_WARNING LOGNAME ": ADC calibration failed\n");
-
- return -EIO;
-}
-
-static int upload_dsp_code(void)
-{
- int ret = 0;
-
- msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS);
-#ifndef HAVE_DSPCODEH
- INITCODESIZE = mod_firmware_load(INITCODEFILE, &INITCODE);
- if (!INITCODE) {
- printk(KERN_ERR LOGNAME ": Error loading " INITCODEFILE);
- return -EBUSY;
- }
-
- PERMCODESIZE = mod_firmware_load(PERMCODEFILE, &PERMCODE);
- if (!PERMCODE) {
- printk(KERN_ERR LOGNAME ": Error loading " PERMCODEFILE);
- vfree(INITCODE);
- return -EBUSY;
- }
-#endif
- memcpy_toio(dev.base, PERMCODE, PERMCODESIZE);
- if (msnd_upload_host(&dev, INITCODE, INITCODESIZE) < 0) {
- printk(KERN_WARNING LOGNAME ": Error uploading to DSP\n");
- ret = -ENODEV;
- goto out;
- }
-#ifdef HAVE_DSPCODEH
- printk(KERN_INFO LOGNAME ": DSP firmware uploaded (resident)\n");
-#else
- printk(KERN_INFO LOGNAME ": DSP firmware uploaded\n");
-#endif
-
-out:
-#ifndef HAVE_DSPCODEH
- vfree(INITCODE);
- vfree(PERMCODE);
-#endif
-
- return ret;
-}
-
-#ifdef MSND_CLASSIC
-static void reset_proteus(void)
-{
- msnd_outb(HPPRORESET_ON, dev.io + HP_PROR);
- mdelay(TIME_PRO_RESET);
- msnd_outb(HPPRORESET_OFF, dev.io + HP_PROR);
- mdelay(TIME_PRO_RESET_DONE);
-}
-#endif
-
-static int initialize(void)
-{
- int err, timeout;
-
-#ifdef MSND_CLASSIC
- msnd_outb(HPWAITSTATE_0, dev.io + HP_WAIT);
- msnd_outb(HPBITMODE_16, dev.io + HP_BITM);
-
- reset_proteus();
-#endif
- if ((err = init_sma()) < 0) {
- printk(KERN_WARNING LOGNAME ": Cannot initialize SMA\n");
- return err;
- }
-
- if ((err = reset_dsp()) < 0)
- return err;
-
- if ((err = upload_dsp_code()) < 0) {
- printk(KERN_WARNING LOGNAME ": Cannot upload DSP code\n");
- return err;
- }
-
- timeout = 200;
- while (readw(dev.base)) {
- mdelay(1);
- if (!timeout--) {
- printk(KERN_DEBUG LOGNAME ": DSP reset timeout\n");
- return -EIO;
- }
- }
-
- mixer_setup();
-
- return 0;
-}
-
-static int dsp_full_reset(void)
-{
- int rv;
-
- if (test_bit(F_RESETTING, &dev.flags) || ++dev.nresets > 10)
- return 0;
-
- set_bit(F_RESETTING, &dev.flags);
- printk(KERN_INFO LOGNAME ": DSP reset\n");
- dsp_halt(NULL); /* Unconditionally halt */
- if ((rv = initialize()))
- printk(KERN_WARNING LOGNAME ": DSP reset failed\n");
- force_recsrc(dev.recsrc);
- dsp_open(NULL);
- clear_bit(F_RESETTING, &dev.flags);
-
- return rv;
-}
-
-static int __init attach_multisound(void)
-{
- int err;
-
- if ((err = request_irq(dev.irq, intr, 0, dev.name, &dev)) < 0) {
- printk(KERN_ERR LOGNAME ": Couldn't grab IRQ %d\n", dev.irq);
- return err;
- }
- if (request_region(dev.io, dev.numio, dev.name) == NULL) {
- free_irq(dev.irq, &dev);
- return -EBUSY;
- }
-
- err = dsp_full_reset();
- if (err < 0) {
- release_region(dev.io, dev.numio);
- free_irq(dev.irq, &dev);
- return err;
- }
-
- if ((err = msnd_register(&dev)) < 0) {
- printk(KERN_ERR LOGNAME ": Unable to register MultiSound\n");
- release_region(dev.io, dev.numio);
- free_irq(dev.irq, &dev);
- return err;
- }
-
- if ((dev.dsp_minor = register_sound_dsp(&dev_fileops, -1)) < 0) {
- printk(KERN_ERR LOGNAME ": Unable to register DSP operations\n");
- msnd_unregister(&dev);
- release_region(dev.io, dev.numio);
- free_irq(dev.irq, &dev);
- return dev.dsp_minor;
- }
-
- if ((dev.mixer_minor = register_sound_mixer(&dev_fileops, -1)) < 0) {
- printk(KERN_ERR LOGNAME ": Unable to register mixer operations\n");
- unregister_sound_mixer(dev.mixer_minor);
- msnd_unregister(&dev);
- release_region(dev.io, dev.numio);
- free_irq(dev.irq, &dev);
- return dev.mixer_minor;
- }
-
- dev.ext_midi_dev = dev.hdr_midi_dev = -1;
-
- disable_irq(dev.irq);
- calibrate_adc(dev.play_sample_rate);
-#ifndef MSND_CLASSIC
- force_recsrc(SOUND_MASK_IMIX);
-#endif
-
- return 0;
-}
-
-static void __exit unload_multisound(void)
-{
- release_region(dev.io, dev.numio);
- free_irq(dev.irq, &dev);
- unregister_sound_mixer(dev.mixer_minor);
- unregister_sound_dsp(dev.dsp_minor);
- msnd_unregister(&dev);
-}
-
-#ifndef MSND_CLASSIC
-
-/* Pinnacle/Fiji Logical Device Configuration */
-
-static int __init msnd_write_cfg(int cfg, int reg, int value)
-{
- msnd_outb(reg, cfg);
- msnd_outb(value, cfg + 1);
- if (value != msnd_inb(cfg + 1)) {
- printk(KERN_ERR LOGNAME ": msnd_write_cfg: I/O error\n");
- return -EIO;
- }
- return 0;
-}
-
-static int __init msnd_write_cfg_io0(int cfg, int num, WORD io)
-{
- if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
- return -EIO;
- if (msnd_write_cfg(cfg, IREG_IO0_BASEHI, HIBYTE(io)))
- return -EIO;
- if (msnd_write_cfg(cfg, IREG_IO0_BASELO, LOBYTE(io)))
- return -EIO;
- return 0;
-}
-
-static int __init msnd_write_cfg_io1(int cfg, int num, WORD io)
-{
- if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
- return -EIO;
- if (msnd_write_cfg(cfg, IREG_IO1_BASEHI, HIBYTE(io)))
- return -EIO;
- if (msnd_write_cfg(cfg, IREG_IO1_BASELO, LOBYTE(io)))
- return -EIO;
- return 0;
-}
-
-static int __init msnd_write_cfg_irq(int cfg, int num, WORD irq)
-{
- if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
- return -EIO;
- if (msnd_write_cfg(cfg, IREG_IRQ_NUMBER, LOBYTE(irq)))
- return -EIO;
- if (msnd_write_cfg(cfg, IREG_IRQ_TYPE, IRQTYPE_EDGE))
- return -EIO;
- return 0;
-}
-
-static int __init msnd_write_cfg_mem(int cfg, int num, int mem)
-{
- WORD wmem;
-
- mem >>= 8;
- mem &= 0xfff;
- wmem = (WORD)mem;
- if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
- return -EIO;
- if (msnd_write_cfg(cfg, IREG_MEMBASEHI, HIBYTE(wmem)))
- return -EIO;
- if (msnd_write_cfg(cfg, IREG_MEMBASELO, LOBYTE(wmem)))
- return -EIO;
- if (wmem && msnd_write_cfg(cfg, IREG_MEMCONTROL, (MEMTYPE_HIADDR | MEMTYPE_16BIT)))
- return -EIO;
- return 0;
-}
-
-static int __init msnd_activate_logical(int cfg, int num)
-{
- if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
- return -EIO;
- if (msnd_write_cfg(cfg, IREG_ACTIVATE, LD_ACTIVATE))
- return -EIO;
- return 0;
-}
-
-static int __init msnd_write_cfg_logical(int cfg, int num, WORD io0, WORD io1, WORD irq, int mem)
-{
- if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
- return -EIO;
- if (msnd_write_cfg_io0(cfg, num, io0))
- return -EIO;
- if (msnd_write_cfg_io1(cfg, num, io1))
- return -EIO;
- if (msnd_write_cfg_irq(cfg, num, irq))
- return -EIO;
- if (msnd_write_cfg_mem(cfg, num, mem))
- return -EIO;
- if (msnd_activate_logical(cfg, num))
- return -EIO;
- return 0;
-}
-
-typedef struct msnd_pinnacle_cfg_device {
- WORD io0, io1, irq;
- int mem;
-} msnd_pinnacle_cfg_t[4];
-
-static int __init msnd_pinnacle_cfg_devices(int cfg, int reset, msnd_pinnacle_cfg_t device)
-{
- int i;
-
- /* Reset devices if told to */
- if (reset) {
- printk(KERN_INFO LOGNAME ": Resetting all devices\n");
- for (i = 0; i < 4; ++i)
- if (msnd_write_cfg_logical(cfg, i, 0, 0, 0, 0))
- return -EIO;
- }
-
- /* Configure specified devices */
- for (i = 0; i < 4; ++i) {
-
- switch (i) {
- case 0: /* DSP */
- if (!(device[i].io0 && device[i].irq && device[i].mem))
- continue;
- break;
- case 1: /* MPU */
- if (!(device[i].io0 && device[i].irq))
- continue;
- printk(KERN_INFO LOGNAME
- ": Configuring MPU to I/O 0x%x IRQ %d\n",
- device[i].io0, device[i].irq);
- break;
- case 2: /* IDE */
- if (!(device[i].io0 && device[i].io1 && device[i].irq))
- continue;
- printk(KERN_INFO LOGNAME
- ": Configuring IDE to I/O 0x%x, 0x%x IRQ %d\n",
- device[i].io0, device[i].io1, device[i].irq);
- break;
- case 3: /* Joystick */
- if (!(device[i].io0))
- continue;
- printk(KERN_INFO LOGNAME
- ": Configuring joystick to I/O 0x%x\n",
- device[i].io0);
- break;
- }
-
- /* Configure the device */
- if (msnd_write_cfg_logical(cfg, i, device[i].io0, device[i].io1, device[i].irq, device[i].mem))
- return -EIO;
- }
-
- return 0;
-}
-#endif
-
-#ifdef MODULE
-MODULE_AUTHOR ("Andrew Veliath <andrewtv@usa.net>");
-MODULE_DESCRIPTION ("Turtle Beach " LONGNAME " Linux Driver");
-MODULE_LICENSE("GPL");
-
-static int io __initdata = -1;
-static int irq __initdata = -1;
-static int mem __initdata = -1;
-static int write_ndelay __initdata = -1;
-
-#ifndef MSND_CLASSIC
-/* Pinnacle/Fiji non-PnP Config Port */
-static int cfg __initdata = -1;
-
-/* Extra Peripheral Configuration */
-static int reset __initdata = 0;
-static int mpu_io __initdata = 0;
-static int mpu_irq __initdata = 0;
-static int ide_io0 __initdata = 0;
-static int ide_io1 __initdata = 0;
-static int ide_irq __initdata = 0;
-static int joystick_io __initdata = 0;
-
-/* If we have the digital daugherboard... */
-static bool digital __initdata = false;
-#endif
-
-static int fifosize __initdata = DEFFIFOSIZE;
-static int calibrate_signal __initdata = 0;
-
-#else /* not a module */
-
-static int write_ndelay __initdata = -1;
-
-#ifdef MSND_CLASSIC
-static int io __initdata = CONFIG_MSNDCLAS_IO;
-static int irq __initdata = CONFIG_MSNDCLAS_IRQ;
-static int mem __initdata = CONFIG_MSNDCLAS_MEM;
-#else /* Pinnacle/Fiji */
-
-static int io __initdata = CONFIG_MSNDPIN_IO;
-static int irq __initdata = CONFIG_MSNDPIN_IRQ;
-static int mem __initdata = CONFIG_MSNDPIN_MEM;
-
-/* Pinnacle/Fiji non-PnP Config Port */
-#ifdef CONFIG_MSNDPIN_NONPNP
-# ifndef CONFIG_MSNDPIN_CFG
-# define CONFIG_MSNDPIN_CFG 0x250
-# endif
-#else
-# ifdef CONFIG_MSNDPIN_CFG
-# undef CONFIG_MSNDPIN_CFG
-# endif
-# define CONFIG_MSNDPIN_CFG -1
-#endif
-static int cfg __initdata = CONFIG_MSNDPIN_CFG;
-/* If not a module, we don't need to bother with reset=1 */
-static int reset;
-
-/* Extra Peripheral Configuration (Default: Disable) */
-#ifndef CONFIG_MSNDPIN_MPU_IO
-# define CONFIG_MSNDPIN_MPU_IO 0
-#endif
-static int mpu_io __initdata = CONFIG_MSNDPIN_MPU_IO;
-
-#ifndef CONFIG_MSNDPIN_MPU_IRQ
-# define CONFIG_MSNDPIN_MPU_IRQ 0
-#endif
-static int mpu_irq __initdata = CONFIG_MSNDPIN_MPU_IRQ;
-
-#ifndef CONFIG_MSNDPIN_IDE_IO0
-# define CONFIG_MSNDPIN_IDE_IO0 0
-#endif
-static int ide_io0 __initdata = CONFIG_MSNDPIN_IDE_IO0;
-
-#ifndef CONFIG_MSNDPIN_IDE_IO1
-# define CONFIG_MSNDPIN_IDE_IO1 0
-#endif
-static int ide_io1 __initdata = CONFIG_MSNDPIN_IDE_IO1;
-
-#ifndef CONFIG_MSNDPIN_IDE_IRQ
-# define CONFIG_MSNDPIN_IDE_IRQ 0
-#endif
-static int ide_irq __initdata = CONFIG_MSNDPIN_IDE_IRQ;
-
-#ifndef CONFIG_MSNDPIN_JOYSTICK_IO
-# define CONFIG_MSNDPIN_JOYSTICK_IO 0
-#endif
-static int joystick_io __initdata = CONFIG_MSNDPIN_JOYSTICK_IO;
-
-/* Have SPDIF (Digital) Daughterboard */
-#ifndef CONFIG_MSNDPIN_DIGITAL
-# define CONFIG_MSNDPIN_DIGITAL 0
-#endif
-static bool digital __initdata = CONFIG_MSNDPIN_DIGITAL;
-
-#endif /* MSND_CLASSIC */
-
-#ifndef CONFIG_MSND_FIFOSIZE
-# define CONFIG_MSND_FIFOSIZE DEFFIFOSIZE
-#endif
-static int fifosize __initdata = CONFIG_MSND_FIFOSIZE;
-
-#ifndef CONFIG_MSND_CALSIGNAL
-# define CONFIG_MSND_CALSIGNAL 0
-#endif
-static int
-calibrate_signal __initdata = CONFIG_MSND_CALSIGNAL;
-#endif /* MODULE */
-
-module_param (io, int, 0);
-module_param (irq, int, 0);
-module_param (mem, int, 0);
-module_param (write_ndelay, int, 0);
-module_param (fifosize, int, 0);
-module_param (calibrate_signal, int, 0);
-#ifndef MSND_CLASSIC
-module_param (digital, bool, 0);
-module_param (cfg, int, 0);
-module_param (reset, int, 0);
-module_param (mpu_io, int, 0);
-module_param (mpu_irq, int, 0);
-module_param (ide_io0, int, 0);
-module_param (ide_io1, int, 0);
-module_param (ide_irq, int, 0);
-module_param (joystick_io, int, 0);
-#endif
-
-static int __init msnd_init(void)
-{
- int err;
-#ifndef MSND_CLASSIC
- static msnd_pinnacle_cfg_t pinnacle_devs;
-#endif /* MSND_CLASSIC */
-
- printk(KERN_INFO LOGNAME ": Turtle Beach " LONGNAME " Linux Driver Version "
- VERSION ", Copyright (C) 1998 Andrew Veliath\n");
-
- if (io == -1 || irq == -1 || mem == -1)
- printk(KERN_WARNING LOGNAME ": io, irq and mem must be set\n");
-
-#ifdef MSND_CLASSIC
- if (io == -1 ||
- !(io == 0x290 ||
- io == 0x260 ||
- io == 0x250 ||
- io == 0x240 ||
- io == 0x230 ||
- io == 0x220 ||
- io == 0x210 ||
- io == 0x3e0)) {
- printk(KERN_ERR LOGNAME ": \"io\" - DSP I/O base must be set to 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x290, or 0x3E0\n");
- return -EINVAL;
- }
-#else
- if (io == -1 ||
- io < 0x100 ||
- io > 0x3e0 ||
- (io % 0x10) != 0) {
- printk(KERN_ERR LOGNAME ": \"io\" - DSP I/O base must within the range 0x100 to 0x3E0 and must be evenly divisible by 0x10\n");
- return -EINVAL;
- }
-#endif /* MSND_CLASSIC */
-
- if (irq == -1 ||
- !(irq == 5 ||
- irq == 7 ||
- irq == 9 ||
- irq == 10 ||
- irq == 11 ||
- irq == 12)) {
- printk(KERN_ERR LOGNAME ": \"irq\" - must be set to 5, 7, 9, 10, 11 or 12\n");
- return -EINVAL;
- }
-
- if (mem == -1 ||
- !(mem == 0xb0000 ||
- mem == 0xc8000 ||
- mem == 0xd0000 ||
- mem == 0xd8000 ||
- mem == 0xe0000 ||
- mem == 0xe8000)) {
- printk(KERN_ERR LOGNAME ": \"mem\" - must be set to "
- "0xb0000, 0xc8000, 0xd0000, 0xd8000, 0xe0000 or 0xe8000\n");
- return -EINVAL;
- }
-
-#ifdef MSND_CLASSIC
- switch (irq) {
- case 5: dev.irqid = HPIRQ_5; break;
- case 7: dev.irqid = HPIRQ_7; break;
- case 9: dev.irqid = HPIRQ_9; break;
- case 10: dev.irqid = HPIRQ_10; break;
- case 11: dev.irqid = HPIRQ_11; break;
- case 12: dev.irqid = HPIRQ_12; break;
- }
-
- switch (mem) {
- case 0xb0000: dev.memid = HPMEM_B000; break;
- case 0xc8000: dev.memid = HPMEM_C800; break;
- case 0xd0000: dev.memid = HPMEM_D000; break;
- case 0xd8000: dev.memid = HPMEM_D800; break;
- case 0xe0000: dev.memid = HPMEM_E000; break;
- case 0xe8000: dev.memid = HPMEM_E800; break;
- }
-#else
- if (cfg == -1) {
- printk(KERN_INFO LOGNAME ": Assuming PnP mode\n");
- } else if (cfg != 0x250 && cfg != 0x260 && cfg != 0x270) {
- printk(KERN_INFO LOGNAME ": Config port must be 0x250, 0x260 or 0x270 (or unspecified for PnP mode)\n");
- return -EINVAL;
- } else {
- printk(KERN_INFO LOGNAME ": Non-PnP mode: configuring at port 0x%x\n", cfg);
-
- /* DSP */
- pinnacle_devs[0].io0 = io;
- pinnacle_devs[0].irq = irq;
- pinnacle_devs[0].mem = mem;
-
- /* The following are Pinnacle specific */
-
- /* MPU */
- pinnacle_devs[1].io0 = mpu_io;
- pinnacle_devs[1].irq = mpu_irq;
-
- /* IDE */
- pinnacle_devs[2].io0 = ide_io0;
- pinnacle_devs[2].io1 = ide_io1;
- pinnacle_devs[2].irq = ide_irq;
-
- /* Joystick */
- pinnacle_devs[3].io0 = joystick_io;
-
- if (!request_region(cfg, 2, "Pinnacle/Fiji Config")) {
- printk(KERN_ERR LOGNAME ": Config port 0x%x conflict\n", cfg);
- return -EIO;
- }
-
- if (msnd_pinnacle_cfg_devices(cfg, reset, pinnacle_devs)) {
- printk(KERN_ERR LOGNAME ": Device configuration error\n");
- release_region(cfg, 2);
- return -EIO;
- }
- release_region(cfg, 2);
- }
-#endif /* MSND_CLASSIC */
-
- if (fifosize < 16)
- fifosize = 16;
-
- if (fifosize > 1024)
- fifosize = 1024;
-
- set_default_audio_parameters();
-#ifdef MSND_CLASSIC
- dev.type = msndClassic;
-#else
- dev.type = msndPinnacle;
-#endif
- dev.io = io;
- dev.numio = DSP_NUMIO;
- dev.irq = irq;
- dev.base = ioremap(mem, 0x8000);
- dev.fifosize = fifosize * 1024;
- dev.calibrate_signal = calibrate_signal ? 1 : 0;
- dev.recsrc = 0;
- dev.dspq_data_buff = DSPQ_DATA_BUFF;
- dev.dspq_buff_size = DSPQ_BUFF_SIZE;
- if (write_ndelay == -1)
- write_ndelay = CONFIG_MSND_WRITE_NDELAY;
- if (write_ndelay)
- clear_bit(F_DISABLE_WRITE_NDELAY, &dev.flags);
- else
- set_bit(F_DISABLE_WRITE_NDELAY, &dev.flags);
-#ifndef MSND_CLASSIC
- if (digital)
- set_bit(F_HAVEDIGITAL, &dev.flags);
-#endif
- init_waitqueue_head(&dev.writeblock);
- init_waitqueue_head(&dev.readblock);
- init_waitqueue_head(&dev.writeflush);
- msnd_fifo_init(&dev.DAPF);
- msnd_fifo_init(&dev.DARF);
- spin_lock_init(&dev.lock);
- printk(KERN_INFO LOGNAME ": %u byte audio FIFOs (x2)\n", dev.fifosize);
- if ((err = msnd_fifo_alloc(&dev.DAPF, dev.fifosize)) < 0) {
- printk(KERN_ERR LOGNAME ": Couldn't allocate write FIFO\n");
- return err;
- }
-
- if ((err = msnd_fifo_alloc(&dev.DARF, dev.fifosize)) < 0) {
- printk(KERN_ERR LOGNAME ": Couldn't allocate read FIFO\n");
- msnd_fifo_free(&dev.DAPF);
- return err;
- }
-
- if ((err = probe_multisound()) < 0) {
- printk(KERN_ERR LOGNAME ": Probe failed\n");
- msnd_fifo_free(&dev.DAPF);
- msnd_fifo_free(&dev.DARF);
- return err;
- }
-
- if ((err = attach_multisound()) < 0) {
- printk(KERN_ERR LOGNAME ": Attach failed\n");
- msnd_fifo_free(&dev.DAPF);
- msnd_fifo_free(&dev.DARF);
- return err;
- }
-
- return 0;
-}
-
-static void __exit msdn_cleanup(void)
-{
- unload_multisound();
- msnd_fifo_free(&dev.DAPF);
- msnd_fifo_free(&dev.DARF);
-}
-
-module_init(msnd_init);
-module_exit(msdn_cleanup);
diff --git a/ANDROID_3.4.5/sound/oss/msnd_pinnacle.h b/ANDROID_3.4.5/sound/oss/msnd_pinnacle.h
deleted file mode 100644
index c18d66cb..00000000
--- a/ANDROID_3.4.5/sound/oss/msnd_pinnacle.h
+++ /dev/null
@@ -1,246 +0,0 @@
-/*********************************************************************
- *
- * msnd_pinnacle.h
- *
- * Turtle Beach MultiSound Sound Card Driver for Linux
- *
- * Some parts of this header file were derived from the Turtle Beach
- * MultiSound Driver Development Kit.
- *
- * Copyright (C) 1998 Andrew Veliath
- * Copyright (C) 1993 Turtle Beach Systems, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ********************************************************************/
-#ifndef __MSND_PINNACLE_H
-#define __MSND_PINNACLE_H
-
-
-#define DSP_NUMIO 0x08
-
-#define IREG_LOGDEVICE 0x07
-#define IREG_ACTIVATE 0x30
-#define LD_ACTIVATE 0x01
-#define LD_DISACTIVATE 0x00
-#define IREG_EECONTROL 0x3F
-#define IREG_MEMBASEHI 0x40
-#define IREG_MEMBASELO 0x41
-#define IREG_MEMCONTROL 0x42
-#define IREG_MEMRANGEHI 0x43
-#define IREG_MEMRANGELO 0x44
-#define MEMTYPE_8BIT 0x00
-#define MEMTYPE_16BIT 0x02
-#define MEMTYPE_RANGE 0x00
-#define MEMTYPE_HIADDR 0x01
-#define IREG_IO0_BASEHI 0x60
-#define IREG_IO0_BASELO 0x61
-#define IREG_IO1_BASEHI 0x62
-#define IREG_IO1_BASELO 0x63
-#define IREG_IRQ_NUMBER 0x70
-#define IREG_IRQ_TYPE 0x71
-#define IRQTYPE_HIGH 0x02
-#define IRQTYPE_LOW 0x00
-#define IRQTYPE_LEVEL 0x01
-#define IRQTYPE_EDGE 0x00
-
-#define HP_DSPR 0x04
-#define HP_BLKS 0x04
-
-#define HPDSPRESET_OFF 2
-#define HPDSPRESET_ON 0
-
-#define HPBLKSEL_0 2
-#define HPBLKSEL_1 3
-
-#define HIMT_DAT_OFF 0x03
-
-#define HIDSP_PLAY_UNDER 0x00
-#define HIDSP_INT_PLAY_UNDER 0x01
-#define HIDSP_SSI_TX_UNDER 0x02
-#define HIDSP_RECQ_OVERFLOW 0x08
-#define HIDSP_INT_RECORD_OVER 0x09
-#define HIDSP_SSI_RX_OVERFLOW 0x0a
-
-#define HIDSP_MIDI_IN_OVER 0x10
-
-#define HIDSP_MIDI_FRAME_ERR 0x11
-#define HIDSP_MIDI_PARITY_ERR 0x12
-#define HIDSP_MIDI_OVERRUN_ERR 0x13
-
-#define HIDSP_INPUT_CLIPPING 0x20
-#define HIDSP_MIX_CLIPPING 0x30
-#define HIDSP_DAT_IN_OFF 0x21
-
-#define HDEXAR_SET_ANA_IN 0
-#define HDEXAR_CLEAR_PEAKS 1
-#define HDEXAR_IN_SET_POTS 2
-#define HDEXAR_AUX_SET_POTS 3
-#define HDEXAR_CAL_A_TO_D 4
-#define HDEXAR_RD_EXT_DSP_BITS 5
-
-#define HDEXAR_SET_SYNTH_IN 4
-#define HDEXAR_READ_DAT_IN 5
-#define HDEXAR_MIC_SET_POTS 6
-#define HDEXAR_SET_DAT_IN 7
-
-#define HDEXAR_SET_SYNTH_48 8
-#define HDEXAR_SET_SYNTH_44 9
-
-#define TIME_PRO_RESET_DONE 0x028A
-#define TIME_PRO_SYSEX 0x001E
-#define TIME_PRO_RESET 0x0032
-
-#define AGND 0x01
-#define SIGNAL 0x02
-
-#define EXT_DSP_BIT_DCAL 0x0001
-#define EXT_DSP_BIT_MIDI_CON 0x0002
-
-#define BUFFSIZE 0x8000
-#define HOSTQ_SIZE 0x40
-
-#define SRAM_CNTL_START 0x7F00
-#define SMA_STRUCT_START 0x7F40
-
-#define DAP_BUFF_SIZE 0x2400
-#define DAR_BUFF_SIZE 0x2000
-
-#define DAPQ_STRUCT_SIZE 0x10
-#define DARQ_STRUCT_SIZE 0x10
-#define DAPQ_BUFF_SIZE (3 * 0x10)
-#define DARQ_BUFF_SIZE (3 * 0x10)
-#define MODQ_BUFF_SIZE 0x400
-#define MIDQ_BUFF_SIZE 0x800
-#define DSPQ_BUFF_SIZE 0x5A0
-
-#define DAPQ_DATA_BUFF 0x6C00
-#define DARQ_DATA_BUFF 0x6C30
-#define MODQ_DATA_BUFF 0x6C60
-#define MIDQ_DATA_BUFF 0x7060
-#define DSPQ_DATA_BUFF 0x7860
-
-#define DAPQ_OFFSET SRAM_CNTL_START
-#define DARQ_OFFSET (SRAM_CNTL_START + 0x08)
-#define MODQ_OFFSET (SRAM_CNTL_START + 0x10)
-#define MIDQ_OFFSET (SRAM_CNTL_START + 0x18)
-#define DSPQ_OFFSET (SRAM_CNTL_START + 0x20)
-
-#define MOP_WAVEHDR 0
-#define MOP_EXTOUT 1
-#define MOP_HWINIT 0xfe
-#define MOP_NONE 0xff
-#define MOP_MAX 1
-
-#define MIP_EXTIN 0
-#define MIP_WAVEHDR 1
-#define MIP_HWINIT 0xfe
-#define MIP_MAX 1
-
-/* Pinnacle/Fiji SMA Common Data */
-#define SMA_wCurrPlayBytes 0x0000
-#define SMA_wCurrRecordBytes 0x0002
-#define SMA_wCurrPlayVolLeft 0x0004
-#define SMA_wCurrPlayVolRight 0x0006
-#define SMA_wCurrInVolLeft 0x0008
-#define SMA_wCurrInVolRight 0x000a
-#define SMA_wCurrMHdrVolLeft 0x000c
-#define SMA_wCurrMHdrVolRight 0x000e
-#define SMA_dwCurrPlayPitch 0x0010
-#define SMA_dwCurrPlayRate 0x0014
-#define SMA_wCurrMIDIIOPatch 0x0018
-#define SMA_wCurrPlayFormat 0x001a
-#define SMA_wCurrPlaySampleSize 0x001c
-#define SMA_wCurrPlayChannels 0x001e
-#define SMA_wCurrPlaySampleRate 0x0020
-#define SMA_wCurrRecordFormat 0x0022
-#define SMA_wCurrRecordSampleSize 0x0024
-#define SMA_wCurrRecordChannels 0x0026
-#define SMA_wCurrRecordSampleRate 0x0028
-#define SMA_wCurrDSPStatusFlags 0x002a
-#define SMA_wCurrHostStatusFlags 0x002c
-#define SMA_wCurrInputTagBits 0x002e
-#define SMA_wCurrLeftPeak 0x0030
-#define SMA_wCurrRightPeak 0x0032
-#define SMA_bMicPotPosLeft 0x0034
-#define SMA_bMicPotPosRight 0x0035
-#define SMA_bMicPotMaxLeft 0x0036
-#define SMA_bMicPotMaxRight 0x0037
-#define SMA_bInPotPosLeft 0x0038
-#define SMA_bInPotPosRight 0x0039
-#define SMA_bAuxPotPosLeft 0x003a
-#define SMA_bAuxPotPosRight 0x003b
-#define SMA_bInPotMaxLeft 0x003c
-#define SMA_bInPotMaxRight 0x003d
-#define SMA_bAuxPotMaxLeft 0x003e
-#define SMA_bAuxPotMaxRight 0x003f
-#define SMA_bInPotMaxMethod 0x0040
-#define SMA_bAuxPotMaxMethod 0x0041
-#define SMA_wCurrMastVolLeft 0x0042
-#define SMA_wCurrMastVolRight 0x0044
-#define SMA_wCalFreqAtoD 0x0046
-#define SMA_wCurrAuxVolLeft 0x0048
-#define SMA_wCurrAuxVolRight 0x004a
-#define SMA_wCurrPlay1VolLeft 0x004c
-#define SMA_wCurrPlay1VolRight 0x004e
-#define SMA_wCurrPlay2VolLeft 0x0050
-#define SMA_wCurrPlay2VolRight 0x0052
-#define SMA_wCurrPlay3VolLeft 0x0054
-#define SMA_wCurrPlay3VolRight 0x0056
-#define SMA_wCurrPlay4VolLeft 0x0058
-#define SMA_wCurrPlay4VolRight 0x005a
-#define SMA_wCurrPlay1PeakLeft 0x005c
-#define SMA_wCurrPlay1PeakRight 0x005e
-#define SMA_wCurrPlay2PeakLeft 0x0060
-#define SMA_wCurrPlay2PeakRight 0x0062
-#define SMA_wCurrPlay3PeakLeft 0x0064
-#define SMA_wCurrPlay3PeakRight 0x0066
-#define SMA_wCurrPlay4PeakLeft 0x0068
-#define SMA_wCurrPlay4PeakRight 0x006a
-#define SMA_wCurrPlayPeakLeft 0x006c
-#define SMA_wCurrPlayPeakRight 0x006e
-#define SMA_wCurrDATSR 0x0070
-#define SMA_wCurrDATRXCHNL 0x0072
-#define SMA_wCurrDATTXCHNL 0x0074
-#define SMA_wCurrDATRXRate 0x0076
-#define SMA_dwDSPPlayCount 0x0078
-#define SMA__size 0x007c
-
-#ifdef HAVE_DSPCODEH
-# include "pndsperm.c"
-# include "pndspini.c"
-# define PERMCODE pndsperm
-# define INITCODE pndspini
-# define PERMCODESIZE sizeof(pndsperm)
-# define INITCODESIZE sizeof(pndspini)
-#else
-# ifndef CONFIG_MSNDPIN_INIT_FILE
-# define CONFIG_MSNDPIN_INIT_FILE \
- "/etc/sound/pndspini.bin"
-# endif
-# ifndef CONFIG_MSNDPIN_PERM_FILE
-# define CONFIG_MSNDPIN_PERM_FILE \
- "/etc/sound/pndsperm.bin"
-# endif
-# define PERMCODEFILE CONFIG_MSNDPIN_PERM_FILE
-# define INITCODEFILE CONFIG_MSNDPIN_INIT_FILE
-# define PERMCODE dspini
-# define INITCODE permini
-# define PERMCODESIZE sizeof_dspini
-# define INITCODESIZE sizeof_permini
-#endif
-#define LONGNAME "MultiSound (Pinnacle/Fiji)"
-
-#endif /* __MSND_PINNACLE_H */
diff --git a/ANDROID_3.4.5/sound/oss/opl3.c b/ANDROID_3.4.5/sound/oss/opl3.c
deleted file mode 100644
index 407cd677..00000000
--- a/ANDROID_3.4.5/sound/oss/opl3.c
+++ /dev/null
@@ -1,1258 +0,0 @@
-/*
- * sound/oss/opl3.c
- *
- * A low level driver for Yamaha YM3812 and OPL-3 -chips
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- *
- * Changes
- * Thomas Sailer ioctl code reworked (vmalloc/vfree removed)
- * Alan Cox modularisation, fixed sound_mem allocs.
- * Christoph Hellwig Adapted to module_init/module_exit
- * Arnaldo C. de Melo get rid of check_region, use request_region for
- * OPL4, release it on exit, some cleanups.
- *
- * Status
- * Believed to work. Badly needs rewriting a bit to support multiple
- * OPL3 devices.
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-
-/*
- * Major improvements to the FM handling 30AUG92 by Rob Hooft,
- * hooft@chem.ruu.nl
- */
-
-#include "sound_config.h"
-
-#include "opl3_hw.h"
-
-#define MAX_VOICE 18
-#define OFFS_4OP 11
-
-struct voice_info
-{
- unsigned char keyon_byte;
- long bender;
- long bender_range;
- unsigned long orig_freq;
- unsigned long current_freq;
- int volume;
- int mode;
- int panning; /* 0xffff means not set */
-};
-
-typedef struct opl_devinfo
-{
- int base;
- int left_io, right_io;
- int nr_voice;
- int lv_map[MAX_VOICE];
-
- struct voice_info voc[MAX_VOICE];
- struct voice_alloc_info *v_alloc;
- struct channel_info *chn_info;
-
- struct sbi_instrument i_map[SBFM_MAXINSTR];
- struct sbi_instrument *act_i[MAX_VOICE];
-
- struct synth_info fm_info;
-
- int busy;
- int model;
- unsigned char cmask;
-
- int is_opl4;
-} opl_devinfo;
-
-static struct opl_devinfo *devc = NULL;
-
-static int detected_model;
-
-static int store_instr(int instr_no, struct sbi_instrument *instr);
-static void freq_to_fnum(int freq, int *block, int *fnum);
-static void opl3_command(int io_addr, unsigned int addr, unsigned int val);
-static int opl3_kill_note(int dev, int voice, int note, int velocity);
-
-static void enter_4op_mode(void)
-{
- int i;
- static int v4op[MAX_VOICE] = {
- 0, 1, 2, 9, 10, 11, 6, 7, 8, 15, 16, 17
- };
-
- devc->cmask = 0x3f; /* Connect all possible 4 OP voice operators */
- opl3_command(devc->right_io, CONNECTION_SELECT_REGISTER, 0x3f);
-
- for (i = 0; i < 3; i++)
- pv_map[i].voice_mode = 4;
- for (i = 3; i < 6; i++)
- pv_map[i].voice_mode = 0;
-
- for (i = 9; i < 12; i++)
- pv_map[i].voice_mode = 4;
- for (i = 12; i < 15; i++)
- pv_map[i].voice_mode = 0;
-
- for (i = 0; i < 12; i++)
- devc->lv_map[i] = v4op[i];
- devc->v_alloc->max_voice = devc->nr_voice = 12;
-}
-
-static int opl3_ioctl(int dev, unsigned int cmd, void __user * arg)
-{
- struct sbi_instrument ins;
-
- switch (cmd) {
- case SNDCTL_FM_LOAD_INSTR:
- printk(KERN_WARNING "Warning: Obsolete ioctl(SNDCTL_FM_LOAD_INSTR) used. Fix the program.\n");
- if (copy_from_user(&ins, arg, sizeof(ins)))
- return -EFAULT;
- if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR) {
- printk(KERN_WARNING "FM Error: Invalid instrument number %d\n", ins.channel);
- return -EINVAL;
- }
- return store_instr(ins.channel, &ins);
-
- case SNDCTL_SYNTH_INFO:
- devc->fm_info.nr_voices = (devc->nr_voice == 12) ? 6 : devc->nr_voice;
- if (copy_to_user(arg, &devc->fm_info, sizeof(devc->fm_info)))
- return -EFAULT;
- return 0;
-
- case SNDCTL_SYNTH_MEMAVL:
- return 0x7fffffff;
-
- case SNDCTL_FM_4OP_ENABLE:
- if (devc->model == 2)
- enter_4op_mode();
- return 0;
-
- default:
- return -EINVAL;
- }
-}
-
-static int opl3_detect(int ioaddr)
-{
- /*
- * This function returns 1 if the FM chip is present at the given I/O port
- * The detection algorithm plays with the timer built in the FM chip and
- * looks for a change in the status register.
- *
- * Note! The timers of the FM chip are not connected to AdLib (and compatible)
- * boards.
- *
- * Note2! The chip is initialized if detected.
- */
-
- unsigned char stat1, signature;
- int i;
-
- if (devc != NULL)
- {
- printk(KERN_ERR "opl3: Only one OPL3 supported.\n");
- return 0;
- }
-
- devc = kzalloc(sizeof(*devc), GFP_KERNEL);
-
- if (devc == NULL)
- {
- printk(KERN_ERR "opl3: Can't allocate memory for the device control "
- "structure \n ");
- return 0;
- }
-
- strcpy(devc->fm_info.name, "OPL2");
-
- if (!request_region(ioaddr, 4, devc->fm_info.name)) {
- printk(KERN_WARNING "opl3: I/O port 0x%x already in use\n", ioaddr);
- goto cleanup_devc;
- }
-
- devc->base = ioaddr;
-
- /* Reset timers 1 and 2 */
- opl3_command(ioaddr, TIMER_CONTROL_REGISTER, TIMER1_MASK | TIMER2_MASK);
-
- /* Reset the IRQ of the FM chip */
- opl3_command(ioaddr, TIMER_CONTROL_REGISTER, IRQ_RESET);
-
- signature = stat1 = inb(ioaddr); /* Status register */
-
- if (signature != 0x00 && signature != 0x06 && signature != 0x02 &&
- signature != 0x0f)
- {
- MDB(printk(KERN_INFO "OPL3 not detected %x\n", signature));
- goto cleanup_region;
- }
-
- if (signature == 0x06) /* OPL2 */
- {
- detected_model = 2;
- }
- else if (signature == 0x00 || signature == 0x0f) /* OPL3 or OPL4 */
- {
- unsigned char tmp;
-
- detected_model = 3;
-
- /*
- * Detect availability of OPL4 (_experimental_). Works probably
- * only after a cold boot. In addition the OPL4 port
- * of the chip may not be connected to the PC bus at all.
- */
-
- opl3_command(ioaddr + 2, OPL3_MODE_REGISTER, 0x00);
- opl3_command(ioaddr + 2, OPL3_MODE_REGISTER, OPL3_ENABLE | OPL4_ENABLE);
-
- if ((tmp = inb(ioaddr)) == 0x02) /* Have a OPL4 */
- {
- detected_model = 4;
- }
-
- if (request_region(ioaddr - 8, 2, "OPL4")) /* OPL4 port was free */
- {
- int tmp;
-
- outb((0x02), ioaddr - 8); /* Select OPL4 ID register */
- udelay(10);
- tmp = inb(ioaddr - 7); /* Read it */
- udelay(10);
-
- if (tmp == 0x20) /* OPL4 should return 0x20 here */
- {
- detected_model = 4;
- outb((0xF8), ioaddr - 8); /* Select OPL4 FM mixer control */
- udelay(10);
- outb((0x1B), ioaddr - 7); /* Write value */
- udelay(10);
- }
- else
- { /* release OPL4 port */
- release_region(ioaddr - 8, 2);
- detected_model = 3;
- }
- }
- opl3_command(ioaddr + 2, OPL3_MODE_REGISTER, 0);
- }
- for (i = 0; i < 9; i++)
- opl3_command(ioaddr, KEYON_BLOCK + i, 0); /*
- * Note off
- */
-
- opl3_command(ioaddr, TEST_REGISTER, ENABLE_WAVE_SELECT);
- opl3_command(ioaddr, PERCOSSION_REGISTER, 0x00); /*
- * Melodic mode.
- */
- return 1;
-cleanup_region:
- release_region(ioaddr, 4);
-cleanup_devc:
- kfree(devc);
- devc = NULL;
- return 0;
-}
-
-static int opl3_kill_note (int devno, int voice, int note, int velocity)
-{
- struct physical_voice_info *map;
-
- if (voice < 0 || voice >= devc->nr_voice)
- return 0;
-
- devc->v_alloc->map[voice] = 0;
-
- map = &pv_map[devc->lv_map[voice]];
- DEB(printk("Kill note %d\n", voice));
-
- if (map->voice_mode == 0)
- return 0;
-
- opl3_command(map->ioaddr, KEYON_BLOCK + map->voice_num, devc->voc[voice].keyon_byte & ~0x20);
- devc->voc[voice].keyon_byte = 0;
- devc->voc[voice].bender = 0;
- devc->voc[voice].volume = 64;
- devc->voc[voice].panning = 0xffff; /* Not set */
- devc->voc[voice].bender_range = 200;
- devc->voc[voice].orig_freq = 0;
- devc->voc[voice].current_freq = 0;
- devc->voc[voice].mode = 0;
- return 0;
-}
-
-#define HIHAT 0
-#define CYMBAL 1
-#define TOMTOM 2
-#define SNARE 3
-#define BDRUM 4
-#define UNDEFINED TOMTOM
-#define DEFAULT TOMTOM
-
-static int store_instr(int instr_no, struct sbi_instrument *instr)
-{
- if (instr->key != FM_PATCH && (instr->key != OPL3_PATCH || devc->model != 2))
- printk(KERN_WARNING "FM warning: Invalid patch format field (key) 0x%x\n", instr->key);
- memcpy((char *) &(devc->i_map[instr_no]), (char *) instr, sizeof(*instr));
- return 0;
-}
-
-static int opl3_set_instr (int dev, int voice, int instr_no)
-{
- if (voice < 0 || voice >= devc->nr_voice)
- return 0;
- if (instr_no < 0 || instr_no >= SBFM_MAXINSTR)
- instr_no = 0; /* Acoustic piano (usually) */
-
- devc->act_i[voice] = &devc->i_map[instr_no];
- return 0;
-}
-
-/*
- * The next table looks magical, but it certainly is not. Its values have
- * been calculated as table[i]=8*log(i/64)/log(2) with an obvious exception
- * for i=0. This log-table converts a linear volume-scaling (0..127) to a
- * logarithmic scaling as present in the FM-synthesizer chips. so : Volume
- * 64 = 0 db = relative volume 0 and: Volume 32 = -6 db = relative
- * volume -8 it was implemented as a table because it is only 128 bytes and
- * it saves a lot of log() calculations. (RH)
- */
-
-static char fm_volume_table[128] =
-{
- -64, -48, -40, -35, -32, -29, -27, -26,
- -24, -23, -21, -20, -19, -18, -18, -17,
- -16, -15, -15, -14, -13, -13, -12, -12,
- -11, -11, -10, -10, -10, -9, -9, -8,
- -8, -8, -7, -7, -7, -6, -6, -6,
- -5, -5, -5, -5, -4, -4, -4, -4,
- -3, -3, -3, -3, -2, -2, -2, -2,
- -2, -1, -1, -1, -1, 0, 0, 0,
- 0, 0, 0, 1, 1, 1, 1, 1,
- 1, 2, 2, 2, 2, 2, 2, 2,
- 3, 3, 3, 3, 3, 3, 3, 4,
- 4, 4, 4, 4, 4, 4, 4, 5,
- 5, 5, 5, 5, 5, 5, 5, 5,
- 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 8, 8, 8, 8, 8
-};
-
-static void calc_vol(unsigned char *regbyte, int volume, int main_vol)
-{
- int level = (~*regbyte & 0x3f);
-
- if (main_vol > 127)
- main_vol = 127;
- volume = (volume * main_vol) / 127;
-
- if (level)
- level += fm_volume_table[volume];
-
- if (level > 0x3f)
- level = 0x3f;
- if (level < 0)
- level = 0;
-
- *regbyte = (*regbyte & 0xc0) | (~level & 0x3f);
-}
-
-static void set_voice_volume(int voice, int volume, int main_vol)
-{
- unsigned char vol1, vol2, vol3, vol4;
- struct sbi_instrument *instr;
- struct physical_voice_info *map;
-
- if (voice < 0 || voice >= devc->nr_voice)
- return;
-
- map = &pv_map[devc->lv_map[voice]];
- instr = devc->act_i[voice];
-
- if (!instr)
- instr = &devc->i_map[0];
-
- if (instr->channel < 0)
- return;
-
- if (devc->voc[voice].mode == 0)
- return;
-
- if (devc->voc[voice].mode == 2)
- {
- vol1 = instr->operators[2];
- vol2 = instr->operators[3];
- if ((instr->operators[10] & 0x01))
- {
- calc_vol(&vol1, volume, main_vol);
- calc_vol(&vol2, volume, main_vol);
- }
- else
- {
- calc_vol(&vol2, volume, main_vol);
- }
- opl3_command(map->ioaddr, KSL_LEVEL + map->op[0], vol1);
- opl3_command(map->ioaddr, KSL_LEVEL + map->op[1], vol2);
- }
- else
- { /*
- * 4 OP voice
- */
- int connection;
-
- vol1 = instr->operators[2];
- vol2 = instr->operators[3];
- vol3 = instr->operators[OFFS_4OP + 2];
- vol4 = instr->operators[OFFS_4OP + 3];
-
- /*
- * The connection method for 4 OP devc->voc is defined by the rightmost
- * bits at the offsets 10 and 10+OFFS_4OP
- */
-
- connection = ((instr->operators[10] & 0x01) << 1) | (instr->operators[10 + OFFS_4OP] & 0x01);
-
- switch (connection)
- {
- case 0:
- calc_vol(&vol4, volume, main_vol);
- break;
-
- case 1:
- calc_vol(&vol2, volume, main_vol);
- calc_vol(&vol4, volume, main_vol);
- break;
-
- case 2:
- calc_vol(&vol1, volume, main_vol);
- calc_vol(&vol4, volume, main_vol);
- break;
-
- case 3:
- calc_vol(&vol1, volume, main_vol);
- calc_vol(&vol3, volume, main_vol);
- calc_vol(&vol4, volume, main_vol);
- break;
-
- default:
- ;
- }
- opl3_command(map->ioaddr, KSL_LEVEL + map->op[0], vol1);
- opl3_command(map->ioaddr, KSL_LEVEL + map->op[1], vol2);
- opl3_command(map->ioaddr, KSL_LEVEL + map->op[2], vol3);
- opl3_command(map->ioaddr, KSL_LEVEL + map->op[3], vol4);
- }
-}
-
-static int opl3_start_note (int dev, int voice, int note, int volume)
-{
- unsigned char data, fpc;
- int block, fnum, freq, voice_mode, pan;
- struct sbi_instrument *instr;
- struct physical_voice_info *map;
-
- if (voice < 0 || voice >= devc->nr_voice)
- return 0;
-
- map = &pv_map[devc->lv_map[voice]];
- pan = devc->voc[voice].panning;
-
- if (map->voice_mode == 0)
- return 0;
-
- if (note == 255) /*
- * Just change the volume
- */
- {
- set_voice_volume(voice, volume, devc->voc[voice].volume);
- return 0;
- }
-
- /*
- * Kill previous note before playing
- */
-
- opl3_command(map->ioaddr, KSL_LEVEL + map->op[1], 0xff); /*
- * Carrier
- * volume to
- * min
- */
- opl3_command(map->ioaddr, KSL_LEVEL + map->op[0], 0xff); /*
- * Modulator
- * volume to
- */
-
- if (map->voice_mode == 4)
- {
- opl3_command(map->ioaddr, KSL_LEVEL + map->op[2], 0xff);
- opl3_command(map->ioaddr, KSL_LEVEL + map->op[3], 0xff);
- }
-
- opl3_command(map->ioaddr, KEYON_BLOCK + map->voice_num, 0x00); /*
- * Note
- * off
- */
-
- instr = devc->act_i[voice];
-
- if (!instr)
- instr = &devc->i_map[0];
-
- if (instr->channel < 0)
- {
- printk(KERN_WARNING "opl3: Initializing voice %d with undefined instrument\n", voice);
- return 0;
- }
-
- if (map->voice_mode == 2 && instr->key == OPL3_PATCH)
- return 0; /*
- * Cannot play
- */
-
- voice_mode = map->voice_mode;
-
- if (voice_mode == 4)
- {
- int voice_shift;
-
- voice_shift = (map->ioaddr == devc->left_io) ? 0 : 3;
- voice_shift += map->voice_num;
-
- if (instr->key != OPL3_PATCH) /*
- * Just 2 OP patch
- */
- {
- voice_mode = 2;
- devc->cmask &= ~(1 << voice_shift);
- }
- else
- {
- devc->cmask |= (1 << voice_shift);
- }
-
- opl3_command(devc->right_io, CONNECTION_SELECT_REGISTER, devc->cmask);
- }
-
- /*
- * Set Sound Characteristics
- */
-
- opl3_command(map->ioaddr, AM_VIB + map->op[0], instr->operators[0]);
- opl3_command(map->ioaddr, AM_VIB + map->op[1], instr->operators[1]);
-
- /*
- * Set Attack/Decay
- */
-
- opl3_command(map->ioaddr, ATTACK_DECAY + map->op[0], instr->operators[4]);
- opl3_command(map->ioaddr, ATTACK_DECAY + map->op[1], instr->operators[5]);
-
- /*
- * Set Sustain/Release
- */
-
- opl3_command(map->ioaddr, SUSTAIN_RELEASE + map->op[0], instr->operators[6]);
- opl3_command(map->ioaddr, SUSTAIN_RELEASE + map->op[1], instr->operators[7]);
-
- /*
- * Set Wave Select
- */
-
- opl3_command(map->ioaddr, WAVE_SELECT + map->op[0], instr->operators[8]);
- opl3_command(map->ioaddr, WAVE_SELECT + map->op[1], instr->operators[9]);
-
- /*
- * Set Feedback/Connection
- */
-
- fpc = instr->operators[10];
-
- if (pan != 0xffff)
- {
- fpc &= ~STEREO_BITS;
- if (pan < -64)
- fpc |= VOICE_TO_LEFT;
- else
- if (pan > 64)
- fpc |= VOICE_TO_RIGHT;
- else
- fpc |= (VOICE_TO_LEFT | VOICE_TO_RIGHT);
- }
-
- if (!(fpc & 0x30))
- fpc |= 0x30; /*
- * Ensure that at least one chn is enabled
- */
- opl3_command(map->ioaddr, FEEDBACK_CONNECTION + map->voice_num, fpc);
-
- /*
- * If the voice is a 4 OP one, initialize the operators 3 and 4 also
- */
-
- if (voice_mode == 4)
- {
- /*
- * Set Sound Characteristics
- */
-
- opl3_command(map->ioaddr, AM_VIB + map->op[2], instr->operators[OFFS_4OP + 0]);
- opl3_command(map->ioaddr, AM_VIB + map->op[3], instr->operators[OFFS_4OP + 1]);
-
- /*
- * Set Attack/Decay
- */
-
- opl3_command(map->ioaddr, ATTACK_DECAY + map->op[2], instr->operators[OFFS_4OP + 4]);
- opl3_command(map->ioaddr, ATTACK_DECAY + map->op[3], instr->operators[OFFS_4OP + 5]);
-
- /*
- * Set Sustain/Release
- */
-
- opl3_command(map->ioaddr, SUSTAIN_RELEASE + map->op[2], instr->operators[OFFS_4OP + 6]);
- opl3_command(map->ioaddr, SUSTAIN_RELEASE + map->op[3], instr->operators[OFFS_4OP + 7]);
-
- /*
- * Set Wave Select
- */
-
- opl3_command(map->ioaddr, WAVE_SELECT + map->op[2], instr->operators[OFFS_4OP + 8]);
- opl3_command(map->ioaddr, WAVE_SELECT + map->op[3], instr->operators[OFFS_4OP + 9]);
-
- /*
- * Set Feedback/Connection
- */
-
- fpc = instr->operators[OFFS_4OP + 10];
- if (!(fpc & 0x30))
- fpc |= 0x30; /*
- * Ensure that at least one chn is enabled
- */
- opl3_command(map->ioaddr, FEEDBACK_CONNECTION + map->voice_num + 3, fpc);
- }
-
- devc->voc[voice].mode = voice_mode;
- set_voice_volume(voice, volume, devc->voc[voice].volume);
-
- freq = devc->voc[voice].orig_freq = note_to_freq(note) / 1000;
-
- /*
- * Since the pitch bender may have been set before playing the note, we
- * have to calculate the bending now.
- */
-
- freq = compute_finetune(devc->voc[voice].orig_freq, devc->voc[voice].bender, devc->voc[voice].bender_range, 0);
- devc->voc[voice].current_freq = freq;
-
- freq_to_fnum(freq, &block, &fnum);
-
- /*
- * Play note
- */
-
- data = fnum & 0xff; /*
- * Least significant bits of fnumber
- */
- opl3_command(map->ioaddr, FNUM_LOW + map->voice_num, data);
-
- data = 0x20 | ((block & 0x7) << 2) | ((fnum >> 8) & 0x3);
- devc->voc[voice].keyon_byte = data;
- opl3_command(map->ioaddr, KEYON_BLOCK + map->voice_num, data);
- if (voice_mode == 4)
- opl3_command(map->ioaddr, KEYON_BLOCK + map->voice_num + 3, data);
-
- return 0;
-}
-
-static void freq_to_fnum (int freq, int *block, int *fnum)
-{
- int f, octave;
-
- /*
- * Converts the note frequency to block and fnum values for the FM chip
- */
- /*
- * First try to compute the block -value (octave) where the note belongs
- */
-
- f = freq;
-
- octave = 5;
-
- if (f == 0)
- octave = 0;
- else if (f < 261)
- {
- while (f < 261)
- {
- octave--;
- f <<= 1;
- }
- }
- else if (f > 493)
- {
- while (f > 493)
- {
- octave++;
- f >>= 1;
- }
- }
-
- if (octave > 7)
- octave = 7;
-
- *fnum = freq * (1 << (20 - octave)) / 49716;
- *block = octave;
-}
-
-static void opl3_command (int io_addr, unsigned int addr, unsigned int val)
-{
- int i;
-
- /*
- * The original 2-OP synth requires a quite long delay after writing to a
- * register. The OPL-3 survives with just two INBs
- */
-
- outb(((unsigned char) (addr & 0xff)), io_addr);
-
- if (devc->model != 2)
- udelay(10);
- else
- for (i = 0; i < 2; i++)
- inb(io_addr);
-
- outb(((unsigned char) (val & 0xff)), io_addr + 1);
-
- if (devc->model != 2)
- udelay(30);
- else
- for (i = 0; i < 2; i++)
- inb(io_addr);
-}
-
-static void opl3_reset(int devno)
-{
- int i;
-
- for (i = 0; i < 18; i++)
- devc->lv_map[i] = i;
-
- for (i = 0; i < devc->nr_voice; i++)
- {
- opl3_command(pv_map[devc->lv_map[i]].ioaddr,
- KSL_LEVEL + pv_map[devc->lv_map[i]].op[0], 0xff);
-
- opl3_command(pv_map[devc->lv_map[i]].ioaddr,
- KSL_LEVEL + pv_map[devc->lv_map[i]].op[1], 0xff);
-
- if (pv_map[devc->lv_map[i]].voice_mode == 4)
- {
- opl3_command(pv_map[devc->lv_map[i]].ioaddr,
- KSL_LEVEL + pv_map[devc->lv_map[i]].op[2], 0xff);
-
- opl3_command(pv_map[devc->lv_map[i]].ioaddr,
- KSL_LEVEL + pv_map[devc->lv_map[i]].op[3], 0xff);
- }
-
- opl3_kill_note(devno, i, 0, 64);
- }
-
- if (devc->model == 2)
- {
- devc->v_alloc->max_voice = devc->nr_voice = 18;
-
- for (i = 0; i < 18; i++)
- pv_map[i].voice_mode = 2;
-
- }
-}
-
-static int opl3_open(int dev, int mode)
-{
- int i;
-
- if (devc->busy)
- return -EBUSY;
- devc->busy = 1;
-
- devc->v_alloc->max_voice = devc->nr_voice = (devc->model == 2) ? 18 : 9;
- devc->v_alloc->timestamp = 0;
-
- for (i = 0; i < 18; i++)
- {
- devc->v_alloc->map[i] = 0;
- devc->v_alloc->alloc_times[i] = 0;
- }
-
- devc->cmask = 0x00; /*
- * Just 2 OP mode
- */
- if (devc->model == 2)
- opl3_command(devc->right_io, CONNECTION_SELECT_REGISTER, devc->cmask);
- return 0;
-}
-
-static void opl3_close(int dev)
-{
- devc->busy = 0;
- devc->v_alloc->max_voice = devc->nr_voice = (devc->model == 2) ? 18 : 9;
-
- devc->fm_info.nr_drums = 0;
- devc->fm_info.perc_mode = 0;
-
- opl3_reset(dev);
-}
-
-static void opl3_hw_control(int dev, unsigned char *event)
-{
-}
-
-static int opl3_load_patch(int dev, int format, const char __user *addr,
- int count, int pmgr_flag)
-{
- struct sbi_instrument ins;
-
- if (count <sizeof(ins))
- {
- printk(KERN_WARNING "FM Error: Patch record too short\n");
- return -EINVAL;
- }
-
- if (copy_from_user(&ins, addr, sizeof(ins)))
- return -EFAULT;
-
- if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR)
- {
- printk(KERN_WARNING "FM Error: Invalid instrument number %d\n", ins.channel);
- return -EINVAL;
- }
- ins.key = format;
-
- return store_instr(ins.channel, &ins);
-}
-
-static void opl3_panning(int dev, int voice, int value)
-{
-
- if (voice < 0 || voice >= devc->nr_voice)
- return;
-
- devc->voc[voice].panning = value;
-}
-
-static void opl3_volume_method(int dev, int mode)
-{
-}
-
-#define SET_VIBRATO(cell) { \
- tmp = instr->operators[(cell-1)+(((cell-1)/2)*OFFS_4OP)]; \
- if (pressure > 110) \
- tmp |= 0x40; /* Vibrato on */ \
- opl3_command (map->ioaddr, AM_VIB + map->op[cell-1], tmp);}
-
-static void opl3_aftertouch(int dev, int voice, int pressure)
-{
- int tmp;
- struct sbi_instrument *instr;
- struct physical_voice_info *map;
-
- if (voice < 0 || voice >= devc->nr_voice)
- return;
-
- map = &pv_map[devc->lv_map[voice]];
-
- DEB(printk("Aftertouch %d\n", voice));
-
- if (map->voice_mode == 0)
- return;
-
- /*
- * Adjust the amount of vibrato depending the pressure
- */
-
- instr = devc->act_i[voice];
-
- if (!instr)
- instr = &devc->i_map[0];
-
- if (devc->voc[voice].mode == 4)
- {
- int connection = ((instr->operators[10] & 0x01) << 1) | (instr->operators[10 + OFFS_4OP] & 0x01);
-
- switch (connection)
- {
- case 0:
- SET_VIBRATO(4);
- break;
-
- case 1:
- SET_VIBRATO(2);
- SET_VIBRATO(4);
- break;
-
- case 2:
- SET_VIBRATO(1);
- SET_VIBRATO(4);
- break;
-
- case 3:
- SET_VIBRATO(1);
- SET_VIBRATO(3);
- SET_VIBRATO(4);
- break;
-
- }
- /*
- * Not implemented yet
- */
- }
- else
- {
- SET_VIBRATO(1);
-
- if ((instr->operators[10] & 0x01)) /*
- * Additive synthesis
- */
- SET_VIBRATO(2);
- }
-}
-
-#undef SET_VIBRATO
-
-static void bend_pitch(int dev, int voice, int value)
-{
- unsigned char data;
- int block, fnum, freq;
- struct physical_voice_info *map;
-
- map = &pv_map[devc->lv_map[voice]];
-
- if (map->voice_mode == 0)
- return;
-
- devc->voc[voice].bender = value;
- if (!value)
- return;
- if (!(devc->voc[voice].keyon_byte & 0x20))
- return; /*
- * Not keyed on
- */
-
- freq = compute_finetune(devc->voc[voice].orig_freq, devc->voc[voice].bender, devc->voc[voice].bender_range, 0);
- devc->voc[voice].current_freq = freq;
-
- freq_to_fnum(freq, &block, &fnum);
-
- data = fnum & 0xff; /*
- * Least significant bits of fnumber
- */
- opl3_command(map->ioaddr, FNUM_LOW + map->voice_num, data);
-
- data = 0x20 | ((block & 0x7) << 2) | ((fnum >> 8) & 0x3);
- devc->voc[voice].keyon_byte = data;
- opl3_command(map->ioaddr, KEYON_BLOCK + map->voice_num, data);
-}
-
-static void opl3_controller (int dev, int voice, int ctrl_num, int value)
-{
- if (voice < 0 || voice >= devc->nr_voice)
- return;
-
- switch (ctrl_num)
- {
- case CTRL_PITCH_BENDER:
- bend_pitch(dev, voice, value);
- break;
-
- case CTRL_PITCH_BENDER_RANGE:
- devc->voc[voice].bender_range = value;
- break;
-
- case CTL_MAIN_VOLUME:
- devc->voc[voice].volume = value / 128;
- break;
-
- case CTL_PAN:
- devc->voc[voice].panning = (value * 2) - 128;
- break;
- }
-}
-
-static void opl3_bender(int dev, int voice, int value)
-{
- if (voice < 0 || voice >= devc->nr_voice)
- return;
-
- bend_pitch(dev, voice, value - 8192);
-}
-
-static int opl3_alloc_voice(int dev, int chn, int note, struct voice_alloc_info *alloc)
-{
- int i, p, best, first, avail, best_time = 0x7fffffff;
- struct sbi_instrument *instr;
- int is4op;
- int instr_no;
-
- if (chn < 0 || chn > 15)
- instr_no = 0;
- else
- instr_no = devc->chn_info[chn].pgm_num;
-
- instr = &devc->i_map[instr_no];
- if (instr->channel < 0 || /* Instrument not loaded */
- devc->nr_voice != 12) /* Not in 4 OP mode */
- is4op = 0;
- else if (devc->nr_voice == 12) /* 4 OP mode */
- is4op = (instr->key == OPL3_PATCH);
- else
- is4op = 0;
-
- if (is4op)
- {
- first = p = 0;
- avail = 6;
- }
- else
- {
- if (devc->nr_voice == 12) /* 4 OP mode. Use the '2 OP only' operators first */
- first = p = 6;
- else
- first = p = 0;
- avail = devc->nr_voice;
- }
-
- /*
- * Now try to find a free voice
- */
- best = first;
-
- for (i = 0; i < avail; i++)
- {
- if (alloc->map[p] == 0)
- {
- return p;
- }
- if (alloc->alloc_times[p] < best_time) /* Find oldest playing note */
- {
- best_time = alloc->alloc_times[p];
- best = p;
- }
- p = (p + 1) % avail;
- }
-
- /*
- * Insert some kind of priority mechanism here.
- */
-
- if (best < 0)
- best = 0;
- if (best > devc->nr_voice)
- best -= devc->nr_voice;
-
- return best; /* All devc->voc in use. Select the first one. */
-}
-
-static void opl3_setup_voice(int dev, int voice, int chn)
-{
- struct channel_info *info;
-
- if (voice < 0 || voice >= devc->nr_voice)
- return;
-
- if (chn < 0 || chn > 15)
- return;
-
- info = &synth_devs[dev]->chn_info[chn];
-
- opl3_set_instr(dev, voice, info->pgm_num);
-
- devc->voc[voice].bender = 0;
- devc->voc[voice].bender_range = info->bender_range;
- devc->voc[voice].volume = info->controllers[CTL_MAIN_VOLUME];
- devc->voc[voice].panning = (info->controllers[CTL_PAN] * 2) - 128;
-}
-
-static struct synth_operations opl3_operations =
-{
- .owner = THIS_MODULE,
- .id = "OPL",
- .info = NULL,
- .midi_dev = 0,
- .synth_type = SYNTH_TYPE_FM,
- .synth_subtype = FM_TYPE_ADLIB,
- .open = opl3_open,
- .close = opl3_close,
- .ioctl = opl3_ioctl,
- .kill_note = opl3_kill_note,
- .start_note = opl3_start_note,
- .set_instr = opl3_set_instr,
- .reset = opl3_reset,
- .hw_control = opl3_hw_control,
- .load_patch = opl3_load_patch,
- .aftertouch = opl3_aftertouch,
- .controller = opl3_controller,
- .panning = opl3_panning,
- .volume_method = opl3_volume_method,
- .bender = opl3_bender,
- .alloc_voice = opl3_alloc_voice,
- .setup_voice = opl3_setup_voice
-};
-
-static int opl3_init(int ioaddr, struct module *owner)
-{
- int i;
- int me;
-
- if (devc == NULL)
- {
- printk(KERN_ERR "opl3: Device control structure not initialized.\n");
- return -1;
- }
-
- if ((me = sound_alloc_synthdev()) == -1)
- {
- printk(KERN_WARNING "opl3: Too many synthesizers\n");
- return -1;
- }
-
- devc->nr_voice = 9;
-
- devc->fm_info.device = 0;
- devc->fm_info.synth_type = SYNTH_TYPE_FM;
- devc->fm_info.synth_subtype = FM_TYPE_ADLIB;
- devc->fm_info.perc_mode = 0;
- devc->fm_info.nr_voices = 9;
- devc->fm_info.nr_drums = 0;
- devc->fm_info.instr_bank_size = SBFM_MAXINSTR;
- devc->fm_info.capabilities = 0;
- devc->left_io = ioaddr;
- devc->right_io = ioaddr + 2;
-
- if (detected_model <= 2)
- devc->model = 1;
- else
- {
- devc->model = 2;
- if (detected_model == 4)
- devc->is_opl4 = 1;
- }
-
- opl3_operations.info = &devc->fm_info;
-
- synth_devs[me] = &opl3_operations;
-
- if (owner)
- synth_devs[me]->owner = owner;
-
- sequencer_init();
- devc->v_alloc = &opl3_operations.alloc;
- devc->chn_info = &opl3_operations.chn_info[0];
-
- if (devc->model == 2)
- {
- if (devc->is_opl4)
- strcpy(devc->fm_info.name, "Yamaha OPL4/OPL3 FM");
- else
- strcpy(devc->fm_info.name, "Yamaha OPL3");
-
- devc->v_alloc->max_voice = devc->nr_voice = 18;
- devc->fm_info.nr_drums = 0;
- devc->fm_info.synth_subtype = FM_TYPE_OPL3;
- devc->fm_info.capabilities |= SYNTH_CAP_OPL3;
-
- for (i = 0; i < 18; i++)
- {
- if (pv_map[i].ioaddr == USE_LEFT)
- pv_map[i].ioaddr = devc->left_io;
- else
- pv_map[i].ioaddr = devc->right_io;
- }
- opl3_command(devc->right_io, OPL3_MODE_REGISTER, OPL3_ENABLE);
- opl3_command(devc->right_io, CONNECTION_SELECT_REGISTER, 0x00);
- }
- else
- {
- strcpy(devc->fm_info.name, "Yamaha OPL2");
- devc->v_alloc->max_voice = devc->nr_voice = 9;
- devc->fm_info.nr_drums = 0;
-
- for (i = 0; i < 18; i++)
- pv_map[i].ioaddr = devc->left_io;
- };
- conf_printf2(devc->fm_info.name, ioaddr, 0, -1, -1);
-
- for (i = 0; i < SBFM_MAXINSTR; i++)
- devc->i_map[i].channel = -1;
-
- return me;
-}
-
-static int me;
-
-static int io = -1;
-
-module_param(io, int, 0);
-
-static int __init init_opl3 (void)
-{
- printk(KERN_INFO "YM3812 and OPL-3 driver Copyright (C) by Hannu Savolainen, Rob Hooft 1993-1996\n");
-
- if (io != -1) /* User loading pure OPL3 module */
- {
- if (!opl3_detect(io))
- {
- return -ENODEV;
- }
-
- me = opl3_init(io, THIS_MODULE);
- }
-
- return 0;
-}
-
-static void __exit cleanup_opl3(void)
-{
- if (devc && io != -1)
- {
- if (devc->base) {
- release_region(devc->base,4);
- if (devc->is_opl4)
- release_region(devc->base - 8, 2);
- }
- kfree(devc);
- devc = NULL;
- sound_unload_synthdev(me);
- }
-}
-
-module_init(init_opl3);
-module_exit(cleanup_opl3);
-
-#ifndef MODULE
-static int __init setup_opl3(char *str)
-{
- /* io */
- int ints[2];
-
- str = get_options(str, ARRAY_SIZE(ints), ints);
-
- io = ints[1];
-
- return 1;
-}
-
-__setup("opl3=", setup_opl3);
-#endif
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/oss/opl3_hw.h b/ANDROID_3.4.5/sound/oss/opl3_hw.h
deleted file mode 100644
index 8b11c893..00000000
--- a/ANDROID_3.4.5/sound/oss/opl3_hw.h
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * opl3_hw.h - Definitions of the OPL-3 registers
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- *
- * The OPL-3 mode is switched on by writing 0x01, to the offset 5
- * of the right side.
- *
- * Another special register at the right side is at offset 4. It contains
- * a bit mask defining which voices are used as 4 OP voices.
- *
- * The percussive mode is implemented in the left side only.
- *
- * With the above exceptions the both sides can be operated independently.
- *
- * A 4 OP voice can be created by setting the corresponding
- * bit at offset 4 of the right side.
- *
- * For example setting the rightmost bit (0x01) changes the
- * first voice on the right side to the 4 OP mode. The fourth
- * voice is made inaccessible.
- *
- * If a voice is set to the 2 OP mode, it works like 2 OP modes
- * of the original YM3812 (AdLib). In addition the voice can
- * be connected the left, right or both stereo channels. It can
- * even be left unconnected. This works with 4 OP voices also.
- *
- * The stereo connection bits are located in the FEEDBACK_CONNECTION
- * register of the voice (0xC0-0xC8). In 4 OP voices these bits are
- * in the second half of the voice.
- */
-
-/*
- * Register numbers for the global registers
- */
-
-#define TEST_REGISTER 0x01
-#define ENABLE_WAVE_SELECT 0x20
-
-#define TIMER1_REGISTER 0x02
-#define TIMER2_REGISTER 0x03
-#define TIMER_CONTROL_REGISTER 0x04 /* Left side */
-#define IRQ_RESET 0x80
-#define TIMER1_MASK 0x40
-#define TIMER2_MASK 0x20
-#define TIMER1_START 0x01
-#define TIMER2_START 0x02
-
-#define CONNECTION_SELECT_REGISTER 0x04 /* Right side */
-#define RIGHT_4OP_0 0x01
-#define RIGHT_4OP_1 0x02
-#define RIGHT_4OP_2 0x04
-#define LEFT_4OP_0 0x08
-#define LEFT_4OP_1 0x10
-#define LEFT_4OP_2 0x20
-
-#define OPL3_MODE_REGISTER 0x05 /* Right side */
-#define OPL3_ENABLE 0x01
-#define OPL4_ENABLE 0x02
-
-#define KBD_SPLIT_REGISTER 0x08 /* Left side */
-#define COMPOSITE_SINE_WAVE_MODE 0x80 /* Don't use with OPL-3? */
-#define KEYBOARD_SPLIT 0x40
-
-#define PERCOSSION_REGISTER 0xbd /* Left side only */
-#define TREMOLO_DEPTH 0x80
-#define VIBRATO_DEPTH 0x40
-#define PERCOSSION_ENABLE 0x20
-#define BASSDRUM_ON 0x10
-#define SNAREDRUM_ON 0x08
-#define TOMTOM_ON 0x04
-#define CYMBAL_ON 0x02
-#define HIHAT_ON 0x01
-
-/*
- * Offsets to the register banks for operators. To get the
- * register number just add the operator offset to the bank offset
- *
- * AM/VIB/EG/KSR/Multiple (0x20 to 0x35)
- */
-#define AM_VIB 0x20
-#define TREMOLO_ON 0x80
-#define VIBRATO_ON 0x40
-#define SUSTAIN_ON 0x20
-#define KSR 0x10 /* Key scaling rate */
-#define MULTIPLE_MASK 0x0f /* Frequency multiplier */
-
- /*
- * KSL/Total level (0x40 to 0x55)
- */
-#define KSL_LEVEL 0x40
-#define KSL_MASK 0xc0 /* Envelope scaling bits */
-#define TOTAL_LEVEL_MASK 0x3f /* Strength (volume) of OP */
-
-/*
- * Attack / Decay rate (0x60 to 0x75)
- */
-#define ATTACK_DECAY 0x60
-#define ATTACK_MASK 0xf0
-#define DECAY_MASK 0x0f
-
-/*
- * Sustain level / Release rate (0x80 to 0x95)
- */
-#define SUSTAIN_RELEASE 0x80
-#define SUSTAIN_MASK 0xf0
-#define RELEASE_MASK 0x0f
-
-/*
- * Wave select (0xE0 to 0xF5)
- */
-#define WAVE_SELECT 0xe0
-
-/*
- * Offsets to the register banks for voices. Just add to the
- * voice number to get the register number.
- *
- * F-Number low bits (0xA0 to 0xA8).
- */
-#define FNUM_LOW 0xa0
-
-/*
- * F-number high bits / Key on / Block (octave) (0xB0 to 0xB8)
- */
-#define KEYON_BLOCK 0xb0
-#define KEYON_BIT 0x20
-#define BLOCKNUM_MASK 0x1c
-#define FNUM_HIGH_MASK 0x03
-
-/*
- * Feedback / Connection (0xc0 to 0xc8)
- *
- * These registers have two new bits when the OPL-3 mode
- * is selected. These bits controls connecting the voice
- * to the stereo channels. For 4 OP voices this bit is
- * defined in the second half of the voice (add 3 to the
- * register offset).
- *
- * For 4 OP voices the connection bit is used in the
- * both halves (gives 4 ways to connect the operators).
- */
-#define FEEDBACK_CONNECTION 0xc0
-#define FEEDBACK_MASK 0x0e /* Valid just for 1st OP of a voice */
-#define CONNECTION_BIT 0x01
-/*
- * In the 4 OP mode there is four possible configurations how the
- * operators can be connected together (in 2 OP modes there is just
- * AM or FM). The 4 OP connection mode is defined by the rightmost
- * bit of the FEEDBACK_CONNECTION (0xC0-0xC8) on the both halves.
- *
- * First half Second half Mode
- *
- * +---+
- * v |
- * 0 0 >+-1-+--2--3--4-->
- *
- *
- *
- * +---+
- * | |
- * 0 1 >+-1-+--2-+
- * |->
- * >--3----4-+
- *
- * +---+
- * | |
- * 1 0 >+-1-+-----+
- * |->
- * >--2--3--4-+
- *
- * +---+
- * | |
- * 1 1 >+-1-+--+
- * |
- * >--2--3-+->
- * |
- * >--4----+
- */
-#define STEREO_BITS 0x30 /* OPL-3 only */
-#define VOICE_TO_LEFT 0x10
-#define VOICE_TO_RIGHT 0x20
-
-/*
- * Definition table for the physical voices
- */
-
-struct physical_voice_info {
- unsigned char voice_num;
- unsigned char voice_mode; /* 0=unavailable, 2=2 OP, 4=4 OP */
- unsigned short ioaddr; /* I/O port (left or right side) */
- unsigned char op[4]; /* Operator offsets */
- };
-
-/*
- * There is 18 possible 2 OP voices
- * (9 in the left and 9 in the right).
- * The first OP is the modulator and 2nd is the carrier.
- *
- * The first three voices in the both sides may be connected
- * with another voice to a 4 OP voice. For example voice 0
- * can be connected with voice 3. The operators of voice 3 are
- * used as operators 3 and 4 of the new 4 OP voice.
- * In this case the 2 OP voice number 0 is the 'first half' and
- * voice 3 is the second.
- */
-
-#define USE_LEFT 0
-#define USE_RIGHT 1
-
-static struct physical_voice_info pv_map[18] =
-{
-/* No Mode Side OP1 OP2 OP3 OP4 */
-/* --------------------------------------------------- */
- { 0, 2, USE_LEFT, {0x00, 0x03, 0x08, 0x0b}},
- { 1, 2, USE_LEFT, {0x01, 0x04, 0x09, 0x0c}},
- { 2, 2, USE_LEFT, {0x02, 0x05, 0x0a, 0x0d}},
-
- { 3, 2, USE_LEFT, {0x08, 0x0b, 0x00, 0x00}},
- { 4, 2, USE_LEFT, {0x09, 0x0c, 0x00, 0x00}},
- { 5, 2, USE_LEFT, {0x0a, 0x0d, 0x00, 0x00}},
-
- { 6, 2, USE_LEFT, {0x10, 0x13, 0x00, 0x00}}, /* Used by percussive voices */
- { 7, 2, USE_LEFT, {0x11, 0x14, 0x00, 0x00}}, /* if the percussive mode */
- { 8, 2, USE_LEFT, {0x12, 0x15, 0x00, 0x00}}, /* is selected */
-
- { 0, 2, USE_RIGHT, {0x00, 0x03, 0x08, 0x0b}},
- { 1, 2, USE_RIGHT, {0x01, 0x04, 0x09, 0x0c}},
- { 2, 2, USE_RIGHT, {0x02, 0x05, 0x0a, 0x0d}},
-
- { 3, 2, USE_RIGHT, {0x08, 0x0b, 0x00, 0x00}},
- { 4, 2, USE_RIGHT, {0x09, 0x0c, 0x00, 0x00}},
- { 5, 2, USE_RIGHT, {0x0a, 0x0d, 0x00, 0x00}},
-
- { 6, 2, USE_RIGHT, {0x10, 0x13, 0x00, 0x00}},
- { 7, 2, USE_RIGHT, {0x11, 0x14, 0x00, 0x00}},
- { 8, 2, USE_RIGHT, {0x12, 0x15, 0x00, 0x00}}
-};
-/*
- * DMA buffer calls
- */
diff --git a/ANDROID_3.4.5/sound/oss/os.h b/ANDROID_3.4.5/sound/oss/os.h
deleted file mode 100644
index 75ad0cd0..00000000
--- a/ANDROID_3.4.5/sound/oss/os.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#define ALLOW_SELECT
-#undef NO_INLINE_ASM
-#define SHORT_BANNERS
-#define MANUAL_PNP
-#undef DO_TIMINGS
-
-#include <linux/module.h>
-
-#ifdef __KERNEL__
-#include <linux/string.h>
-#include <linux/fs.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/param.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <asm/page.h>
-#include <linux/vmalloc.h>
-#include <asm/uaccess.h>
-#include <linux/poll.h>
-#include <linux/pci.h>
-#endif
-
-#include <linux/soundcard.h>
-
-#define FALSE 0
-#define TRUE 1
-
-extern int sound_alloc_dma(int chn, char *deviceID);
-extern int sound_open_dma(int chn, char *deviceID);
-extern void sound_free_dma(int chn);
-extern void sound_close_dma(int chn);
-
-extern void reprogram_timer(void);
-
-#define USE_AUTOINIT_DMA
-
-extern void *sound_mem_blocks[1024];
-extern int sound_nblocks;
-
-#undef PSEUDO_DMA_AUTOINIT
-#define ALLOW_BUFFER_MAPPING
-
-extern const struct file_operations oss_sound_fops;
diff --git a/ANDROID_3.4.5/sound/oss/pas2.h b/ANDROID_3.4.5/sound/oss/pas2.h
deleted file mode 100644
index fa12c55f..00000000
--- a/ANDROID_3.4.5/sound/oss/pas2.h
+++ /dev/null
@@ -1,17 +0,0 @@
-
-/* From pas_card.c */
-int pas_set_intr(int mask);
-int pas_remove_intr(int mask);
-unsigned char pas_read(int ioaddr);
-void pas_write(unsigned char data, int ioaddr);
-
-/* From pas_audio.c */
-void pas_pcm_interrupt(unsigned char status, int cause);
-void pas_pcm_init(struct address_info *hw_config);
-
-/* From pas_mixer.c */
-int pas_init_mixer(void);
-
-/* From pas_midi.c */
-void pas_midi_init(void);
-void pas_midi_interrupt(void);
diff --git a/ANDROID_3.4.5/sound/oss/pas2_card.c b/ANDROID_3.4.5/sound/oss/pas2_card.c
deleted file mode 100644
index dabf8a87..00000000
--- a/ANDROID_3.4.5/sound/oss/pas2_card.c
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * sound/oss/pas2_card.c
- *
- * Detection routine for the Pro Audio Spectrum cards.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include "sound_config.h"
-
-#include "pas2.h"
-#include "sb.h"
-
-static unsigned char dma_bits[] = {
- 4, 1, 2, 3, 0, 5, 6, 7
-};
-
-static unsigned char irq_bits[] = {
- 0, 0, 1, 2, 3, 4, 5, 6, 0, 1, 7, 8, 9, 0, 10, 11
-};
-
-static unsigned char sb_irq_bits[] = {
- 0x00, 0x00, 0x08, 0x10, 0x00, 0x18, 0x00, 0x20,
- 0x00, 0x08, 0x28, 0x30, 0x38, 0, 0
-};
-
-static unsigned char sb_dma_bits[] = {
- 0x00, 0x40, 0x80, 0xC0, 0, 0, 0, 0
-};
-
-/*
- * The Address Translation code is used to convert I/O register addresses to
- * be relative to the given base -register
- */
-
-int pas_translate_code = 0;
-static int pas_intr_mask;
-static int pas_irq;
-static int pas_sb_base;
-DEFINE_SPINLOCK(pas_lock);
-#ifndef CONFIG_PAS_JOYSTICK
-static bool joystick;
-#else
-static bool joystick = 1;
-#endif
-#ifdef SYMPHONY_PAS
-static bool symphony = 1;
-#else
-static bool symphony;
-#endif
-#ifdef BROKEN_BUS_CLOCK
-static bool broken_bus_clock = 1;
-#else
-static bool broken_bus_clock;
-#endif
-
-static struct address_info cfg;
-static struct address_info cfg2;
-
-char pas_model = 0;
-static char *pas_model_names[] = {
- "",
- "Pro AudioSpectrum+",
- "CDPC",
- "Pro AudioSpectrum 16",
- "Pro AudioSpectrum 16D"
-};
-
-/*
- * pas_read() and pas_write() are equivalents of inb and outb
- * These routines perform the I/O address translation required
- * to support other than the default base address
- */
-
-extern void mix_write(unsigned char data, int ioaddr);
-
-unsigned char pas_read(int ioaddr)
-{
- return inb(ioaddr + pas_translate_code);
-}
-
-void pas_write(unsigned char data, int ioaddr)
-{
- outb((data), ioaddr + pas_translate_code);
-}
-
-/******************* Begin of the Interrupt Handler ********************/
-
-static irqreturn_t pasintr(int irq, void *dev_id)
-{
- int status;
-
- status = pas_read(0x0B89);
- pas_write(status, 0x0B89); /* Clear interrupt */
-
- if (status & 0x08)
- {
- pas_pcm_interrupt(status, 1);
- status &= ~0x08;
- }
- if (status & 0x10)
- {
- pas_midi_interrupt();
- status &= ~0x10;
- }
- return IRQ_HANDLED;
-}
-
-int pas_set_intr(int mask)
-{
- if (!mask)
- return 0;
-
- pas_intr_mask |= mask;
-
- pas_write(pas_intr_mask, 0x0B8B);
- return 0;
-}
-
-int pas_remove_intr(int mask)
-{
- if (!mask)
- return 0;
-
- pas_intr_mask &= ~mask;
- pas_write(pas_intr_mask, 0x0B8B);
-
- return 0;
-}
-
-/******************* End of the Interrupt handler **********************/
-
-/******************* Begin of the Initialization Code ******************/
-
-static int __init config_pas_hw(struct address_info *hw_config)
-{
- char ok = 1;
- unsigned int_ptrs; /* scsi/sound interrupt pointers */
-
- pas_irq = hw_config->irq;
-
- pas_write(0x00, 0x0B8B);
- pas_write(0x36, 0x138B);
- pas_write(0x36, 0x1388);
- pas_write(0, 0x1388);
- pas_write(0x74, 0x138B);
- pas_write(0x74, 0x1389);
- pas_write(0, 0x1389);
-
- pas_write(0x80 | 0x40 | 0x20 | 1, 0x0B8A);
- pas_write(0x80 | 0x20 | 0x10 | 0x08 | 0x01, 0xF8A);
- pas_write(0x01 | 0x02 | 0x04 | 0x10 /*
- * |
- * 0x80
- */ , 0xB88);
-
- pas_write(0x80 | (joystick ? 0x40 : 0), 0xF388);
-
- if (pas_irq < 0 || pas_irq > 15)
- {
- printk(KERN_ERR "PAS16: Invalid IRQ %d", pas_irq);
- hw_config->irq=-1;
- ok = 0;
- }
- else
- {
- int_ptrs = pas_read(0xF38A);
- int_ptrs = (int_ptrs & 0xf0) | irq_bits[pas_irq];
- pas_write(int_ptrs, 0xF38A);
- if (!irq_bits[pas_irq])
- {
- printk(KERN_ERR "PAS16: Invalid IRQ %d", pas_irq);
- hw_config->irq=-1;
- ok = 0;
- }
- else
- {
- if (request_irq(pas_irq, pasintr, 0, "PAS16",hw_config) < 0) {
- printk(KERN_ERR "PAS16: Cannot allocate IRQ %d\n",pas_irq);
- hw_config->irq=-1;
- ok = 0;
- }
- }
- }
-
- if (hw_config->dma < 0 || hw_config->dma > 7)
- {
- printk(KERN_ERR "PAS16: Invalid DMA selection %d", hw_config->dma);
- hw_config->dma=-1;
- ok = 0;
- }
- else
- {
- pas_write(dma_bits[hw_config->dma], 0xF389);
- if (!dma_bits[hw_config->dma])
- {
- printk(KERN_ERR "PAS16: Invalid DMA selection %d", hw_config->dma);
- hw_config->dma=-1;
- ok = 0;
- }
- else
- {
- if (sound_alloc_dma(hw_config->dma, "PAS16"))
- {
- printk(KERN_ERR "pas2_card.c: Can't allocate DMA channel\n");
- hw_config->dma=-1;
- ok = 0;
- }
- }
- }
-
- /*
- * This fixes the timing problems of the PAS due to the Symphony chipset
- * as per Media Vision. Only define this if your PAS doesn't work correctly.
- */
-
- if(symphony)
- {
- outb((0x05), 0xa8);
- outb((0x60), 0xa9);
- }
-
- if(broken_bus_clock)
- pas_write(0x01 | 0x10 | 0x20 | 0x04, 0x8388);
- else
- /*
- * pas_write(0x01, 0x8388);
- */
- pas_write(0x01 | 0x10 | 0x20, 0x8388);
-
- pas_write(0x18, 0x838A); /* ??? */
- pas_write(0x20 | 0x01, 0x0B8A); /* Mute off, filter = 17.897 kHz */
- pas_write(8, 0xBF8A);
-
- mix_write(0x80 | 5, 0x078B);
- mix_write(5, 0x078B);
-
- {
- struct address_info *sb_config;
-
- sb_config = &cfg2;
- if (sb_config->io_base)
- {
- unsigned char irq_dma;
-
- /*
- * Turn on Sound Blaster compatibility
- * bit 1 = SB emulation
- * bit 0 = MPU401 emulation (CDPC only :-( )
- */
-
- pas_write(0x02, 0xF788);
-
- /*
- * "Emulation address"
- */
-
- pas_write((sb_config->io_base >> 4) & 0x0f, 0xF789);
- pas_sb_base = sb_config->io_base;
-
- if (!sb_dma_bits[sb_config->dma])
- printk(KERN_ERR "PAS16 Warning: Invalid SB DMA %d\n\n", sb_config->dma);
-
- if (!sb_irq_bits[sb_config->irq])
- printk(KERN_ERR "PAS16 Warning: Invalid SB IRQ %d\n\n", sb_config->irq);
-
- irq_dma = sb_dma_bits[sb_config->dma] |
- sb_irq_bits[sb_config->irq];
-
- pas_write(irq_dma, 0xFB8A);
- }
- else
- pas_write(0x00, 0xF788);
- }
-
- if (!ok)
- printk(KERN_WARNING "PAS16: Driver not enabled\n");
-
- return ok;
-}
-
-static int __init detect_pas_hw(struct address_info *hw_config)
-{
- unsigned char board_id, foo;
-
- /*
- * WARNING: Setting an option like W:1 or so that disables warm boot reset
- * of the card will screw up this detect code something fierce. Adding code
- * to handle this means possibly interfering with other cards on the bus if
- * you have something on base port 0x388. SO be forewarned.
- */
-
- outb((0xBC), 0x9A01); /* Activate first board */
- outb((hw_config->io_base >> 2), 0x9A01); /* Set base address */
- pas_translate_code = hw_config->io_base - 0x388;
- pas_write(1, 0xBF88); /* Select one wait states */
-
- board_id = pas_read(0x0B8B);
-
- if (board_id == 0xff)
- return 0;
-
- /*
- * We probably have a PAS-series board, now check for a PAS16-series board
- * by trying to change the board revision bits. PAS16-series hardware won't
- * let you do this - the bits are read-only.
- */
-
- foo = board_id ^ 0xe0;
-
- pas_write(foo, 0x0B8B);
- foo = pas_read(0x0B8B);
- pas_write(board_id, 0x0B8B);
-
- if (board_id != foo)
- return 0;
-
- pas_model = pas_read(0xFF88);
-
- return pas_model;
-}
-
-static void __init attach_pas_card(struct address_info *hw_config)
-{
- pas_irq = hw_config->irq;
-
- if (detect_pas_hw(hw_config))
- {
-
- if ((pas_model = pas_read(0xFF88)))
- {
- char temp[100];
-
- sprintf(temp,
- "%s rev %d", pas_model_names[(int) pas_model],
- pas_read(0x2789));
- conf_printf(temp, hw_config);
- }
- if (config_pas_hw(hw_config))
- {
- pas_pcm_init(hw_config);
- pas_midi_init();
- pas_init_mixer();
- }
- }
-}
-
-static inline int __init probe_pas(struct address_info *hw_config)
-{
- return detect_pas_hw(hw_config);
-}
-
-static void __exit unload_pas(struct address_info *hw_config)
-{
- extern int pas_audiodev;
- extern int pas2_mididev;
-
- if (hw_config->dma>0)
- sound_free_dma(hw_config->dma);
- if (hw_config->irq>0)
- free_irq(hw_config->irq, hw_config);
-
- if(pas_audiodev!=-1)
- sound_unload_mixerdev(audio_devs[pas_audiodev]->mixer_dev);
- if(pas2_mididev!=-1)
- sound_unload_mididev(pas2_mididev);
- if(pas_audiodev!=-1)
- sound_unload_audiodev(pas_audiodev);
-}
-
-static int __initdata io = -1;
-static int __initdata irq = -1;
-static int __initdata dma = -1;
-static int __initdata dma16 = -1; /* Set this for modules that need it */
-
-static int __initdata sb_io = 0;
-static int __initdata sb_irq = -1;
-static int __initdata sb_dma = -1;
-static int __initdata sb_dma16 = -1;
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-module_param(dma, int, 0);
-module_param(dma16, int, 0);
-
-module_param(sb_io, int, 0);
-module_param(sb_irq, int, 0);
-module_param(sb_dma, int, 0);
-module_param(sb_dma16, int, 0);
-
-module_param(joystick, bool, 0);
-module_param(symphony, bool, 0);
-module_param(broken_bus_clock, bool, 0);
-
-MODULE_LICENSE("GPL");
-
-static int __init init_pas2(void)
-{
- printk(KERN_INFO "Pro Audio Spectrum driver Copyright (C) by Hannu Savolainen 1993-1996\n");
-
- cfg.io_base = io;
- cfg.irq = irq;
- cfg.dma = dma;
- cfg.dma2 = dma16;
-
- cfg2.io_base = sb_io;
- cfg2.irq = sb_irq;
- cfg2.dma = sb_dma;
- cfg2.dma2 = sb_dma16;
-
- if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
- printk(KERN_INFO "I/O, IRQ, DMA and type are mandatory\n");
- return -EINVAL;
- }
-
- if (!probe_pas(&cfg))
- return -ENODEV;
- attach_pas_card(&cfg);
-
- return 0;
-}
-
-static void __exit cleanup_pas2(void)
-{
- unload_pas(&cfg);
-}
-
-module_init(init_pas2);
-module_exit(cleanup_pas2);
-
-#ifndef MODULE
-static int __init setup_pas2(char *str)
-{
- /* io, irq, dma, dma2, sb_io, sb_irq, sb_dma, sb_dma2 */
- int ints[9];
-
- str = get_options(str, ARRAY_SIZE(ints), ints);
-
- io = ints[1];
- irq = ints[2];
- dma = ints[3];
- dma16 = ints[4];
-
- sb_io = ints[5];
- sb_irq = ints[6];
- sb_dma = ints[7];
- sb_dma16 = ints[8];
-
- return 1;
-}
-
-__setup("pas2=", setup_pas2);
-#endif
diff --git a/ANDROID_3.4.5/sound/oss/pas2_midi.c b/ANDROID_3.4.5/sound/oss/pas2_midi.c
deleted file mode 100644
index 1122d10a..00000000
--- a/ANDROID_3.4.5/sound/oss/pas2_midi.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * sound/oss/pas2_midi.c
- *
- * The low level driver for the PAS Midi Interface.
- */
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Bartlomiej Zolnierkiewicz : Added __init to pas_init_mixer()
- */
-
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include "sound_config.h"
-
-#include "pas2.h"
-
-extern spinlock_t pas_lock;
-
-static int midi_busy, input_opened;
-static int my_dev;
-
-int pas2_mididev=-1;
-
-static unsigned char tmp_queue[256];
-static volatile int qlen;
-static volatile unsigned char qhead, qtail;
-
-static void (*midi_input_intr) (int dev, unsigned char data);
-
-static int pas_midi_open(int dev, int mode,
- void (*input) (int dev, unsigned char data),
- void (*output) (int dev)
-)
-{
- int err;
- unsigned long flags;
- unsigned char ctrl;
-
-
- if (midi_busy)
- return -EBUSY;
-
- /*
- * Reset input and output FIFO pointers
- */
- pas_write(0x20 | 0x40,
- 0x178b);
-
- spin_lock_irqsave(&pas_lock, flags);
-
- if ((err = pas_set_intr(0x10)) < 0)
- {
- spin_unlock_irqrestore(&pas_lock, flags);
- return err;
- }
- /*
- * Enable input available and output FIFO empty interrupts
- */
-
- ctrl = 0;
- input_opened = 0;
- midi_input_intr = input;
-
- if (mode == OPEN_READ || mode == OPEN_READWRITE)
- {
- ctrl |= 0x04; /* Enable input */
- input_opened = 1;
- }
- if (mode == OPEN_WRITE || mode == OPEN_READWRITE)
- {
- ctrl |= 0x08 | 0x10; /* Enable output */
- }
- pas_write(ctrl, 0x178b);
-
- /*
- * Acknowledge any pending interrupts
- */
-
- pas_write(0xff, 0x1B88);
-
- spin_unlock_irqrestore(&pas_lock, flags);
-
- midi_busy = 1;
- qlen = qhead = qtail = 0;
- return 0;
-}
-
-static void pas_midi_close(int dev)
-{
-
- /*
- * Reset FIFO pointers, disable intrs
- */
- pas_write(0x20 | 0x40, 0x178b);
-
- pas_remove_intr(0x10);
- midi_busy = 0;
-}
-
-static int dump_to_midi(unsigned char midi_byte)
-{
- int fifo_space, x;
-
- fifo_space = ((x = pas_read(0x1B89)) >> 4) & 0x0f;
-
- /*
- * The MIDI FIFO space register and it's documentation is nonunderstandable.
- * There seem to be no way to differentiate between buffer full and buffer
- * empty situations. For this reason we don't never write the buffer
- * completely full. In this way we can assume that 0 (or is it 15)
- * means that the buffer is empty.
- */
-
- if (fifo_space < 2 && fifo_space != 0) /* Full (almost) */
- return 0; /* Ask upper layers to retry after some time */
-
- pas_write(midi_byte, 0x178A);
-
- return 1;
-}
-
-static int pas_midi_out(int dev, unsigned char midi_byte)
-{
-
- unsigned long flags;
-
- /*
- * Drain the local queue first
- */
-
- spin_lock_irqsave(&pas_lock, flags);
-
- while (qlen && dump_to_midi(tmp_queue[qhead]))
- {
- qlen--;
- qhead++;
- }
-
- spin_unlock_irqrestore(&pas_lock, flags);
-
- /*
- * Output the byte if the local queue is empty.
- */
-
- if (!qlen)
- if (dump_to_midi(midi_byte))
- return 1;
-
- /*
- * Put to the local queue
- */
-
- if (qlen >= 256)
- return 0; /* Local queue full */
-
- spin_lock_irqsave(&pas_lock, flags);
-
- tmp_queue[qtail] = midi_byte;
- qlen++;
- qtail++;
-
- spin_unlock_irqrestore(&pas_lock, flags);
-
- return 1;
-}
-
-static int pas_midi_start_read(int dev)
-{
- return 0;
-}
-
-static int pas_midi_end_read(int dev)
-{
- return 0;
-}
-
-static void pas_midi_kick(int dev)
-{
-}
-
-static int pas_buffer_status(int dev)
-{
- return qlen;
-}
-
-#define MIDI_SYNTH_NAME "Pro Audio Spectrum Midi"
-#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
-#include "midi_synth.h"
-
-static struct midi_operations pas_midi_operations =
-{
- .owner = THIS_MODULE,
- .info = {"Pro Audio Spectrum", 0, 0, SNDCARD_PAS},
- .converter = &std_midi_synth,
- .in_info = {0},
- .open = pas_midi_open,
- .close = pas_midi_close,
- .outputc = pas_midi_out,
- .start_read = pas_midi_start_read,
- .end_read = pas_midi_end_read,
- .kick = pas_midi_kick,
- .buffer_status = pas_buffer_status,
-};
-
-void __init pas_midi_init(void)
-{
- int dev = sound_alloc_mididev();
-
- if (dev == -1)
- {
- printk(KERN_WARNING "pas_midi_init: Too many midi devices detected\n");
- return;
- }
- std_midi_synth.midi_dev = my_dev = dev;
- midi_devs[dev] = &pas_midi_operations;
- pas2_mididev = dev;
- sequencer_init();
-}
-
-void pas_midi_interrupt(void)
-{
- unsigned char stat;
- int i, incount;
-
- stat = pas_read(0x1B88);
-
- if (stat & 0x04) /* Input data available */
- {
- incount = pas_read(0x1B89) & 0x0f; /* Input FIFO size */
- if (!incount)
- incount = 16;
-
- for (i = 0; i < incount; i++)
- if (input_opened)
- {
- midi_input_intr(my_dev, pas_read(0x178A));
- } else
- pas_read(0x178A); /* Flush */
- }
- if (stat & (0x08 | 0x10))
- {
- spin_lock(&pas_lock);/* called in irq context */
-
- while (qlen && dump_to_midi(tmp_queue[qhead]))
- {
- qlen--;
- qhead++;
- }
-
- spin_unlock(&pas_lock);
- }
- if (stat & 0x40)
- {
- printk(KERN_WARNING "MIDI output overrun %x,%x\n", pas_read(0x1B89), stat);
- }
- pas_write(stat, 0x1B88); /* Acknowledge interrupts */
-}
diff --git a/ANDROID_3.4.5/sound/oss/pas2_mixer.c b/ANDROID_3.4.5/sound/oss/pas2_mixer.c
deleted file mode 100644
index a0bcb85c..00000000
--- a/ANDROID_3.4.5/sound/oss/pas2_mixer.c
+++ /dev/null
@@ -1,336 +0,0 @@
-
-/*
- * sound/oss/pas2_mixer.c
- *
- * Mixer routines for the Pro Audio Spectrum cards.
- */
-
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-/*
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
- * Bartlomiej Zolnierkiewicz : added __init to pas_init_mixer()
- */
-#include <linux/init.h>
-#include "sound_config.h"
-
-#include "pas2.h"
-
-#ifndef DEB
-#define DEB(what) /* (what) */
-#endif
-
-extern int pas_translate_code;
-extern char pas_model;
-extern int *pas_osp;
-extern int pas_audiodev;
-
-static int rec_devices = (SOUND_MASK_MIC); /* Default recording source */
-static int mode_control;
-
-#define POSSIBLE_RECORDING_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_SPEAKER | SOUND_MASK_LINE | SOUND_MASK_MIC | \
- SOUND_MASK_CD | SOUND_MASK_ALTPCM)
-
-#define SUPPORTED_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_SPEAKER | SOUND_MASK_LINE | SOUND_MASK_MIC | \
- SOUND_MASK_CD | SOUND_MASK_ALTPCM | SOUND_MASK_IMIX | \
- SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_RECLEV)
-
-static int *levels;
-
-static int default_levels[32] =
-{
- 0x3232, /* Master Volume */
- 0x3232, /* Bass */
- 0x3232, /* Treble */
- 0x5050, /* FM */
- 0x4b4b, /* PCM */
- 0x3232, /* PC Speaker */
- 0x4b4b, /* Ext Line */
- 0x4b4b, /* Mic */
- 0x4b4b, /* CD */
- 0x6464, /* Recording monitor */
- 0x4b4b, /* SB PCM */
- 0x6464 /* Recording level */
-};
-
-void
-mix_write(unsigned char data, int ioaddr)
-{
- /*
- * The Revision D cards have a problem with their MVA508 interface. The
- * kludge-o-rama fix is to make a 16-bit quantity with identical LSB and
- * MSBs out of the output byte and to do a 16-bit out to the mixer port -
- * 1. We need to do this because it isn't timing problem but chip access
- * sequence problem.
- */
-
- if (pas_model == 4)
- {
- outw(data | (data << 8), (ioaddr + pas_translate_code) - 1);
- outb((0x80), 0);
- } else
- pas_write(data, ioaddr);
-}
-
-static int
-mixer_output(int right_vol, int left_vol, int div, int bits,
- int mixer) /* Input or output mixer */
-{
- int left = left_vol * div / 100;
- int right = right_vol * div / 100;
-
-
- if (bits & 0x10)
- {
- left |= mixer;
- right |= mixer;
- }
- if (bits == 0x03 || bits == 0x04)
- {
- mix_write(0x80 | bits, 0x078B);
- mix_write(left, 0x078B);
- right_vol = left_vol;
- } else
- {
- mix_write(0x80 | 0x20 | bits, 0x078B);
- mix_write(left, 0x078B);
- mix_write(0x80 | 0x40 | bits, 0x078B);
- mix_write(right, 0x078B);
- }
-
- return (left_vol | (right_vol << 8));
-}
-
-static void
-set_mode(int new_mode)
-{
- mix_write(0x80 | 0x05, 0x078B);
- mix_write(new_mode, 0x078B);
-
- mode_control = new_mode;
-}
-
-static int
-pas_mixer_set(int whichDev, unsigned int level)
-{
- int left, right, devmask, changed, i, mixer = 0;
-
- DEB(printk("static int pas_mixer_set(int whichDev = %d, unsigned int level = %X)\n", whichDev, level));
-
- left = level & 0x7f;
- right = (level & 0x7f00) >> 8;
-
- if (whichDev < SOUND_MIXER_NRDEVICES) {
- if ((1 << whichDev) & rec_devices)
- mixer = 0x20;
- else
- mixer = 0x00;
- }
-
- switch (whichDev)
- {
- case SOUND_MIXER_VOLUME: /* Master volume (0-63) */
- levels[whichDev] = mixer_output(right, left, 63, 0x01, 0);
- break;
-
- /*
- * Note! Bass and Treble are mono devices. Will use just the left
- * channel.
- */
- case SOUND_MIXER_BASS: /* Bass (0-12) */
- levels[whichDev] = mixer_output(right, left, 12, 0x03, 0);
- break;
- case SOUND_MIXER_TREBLE: /* Treble (0-12) */
- levels[whichDev] = mixer_output(right, left, 12, 0x04, 0);
- break;
-
- case SOUND_MIXER_SYNTH: /* Internal synthesizer (0-31) */
- levels[whichDev] = mixer_output(right, left, 31, 0x10 | 0x00, mixer);
- break;
- case SOUND_MIXER_PCM: /* PAS PCM (0-31) */
- levels[whichDev] = mixer_output(right, left, 31, 0x10 | 0x05, mixer);
- break;
- case SOUND_MIXER_ALTPCM: /* SB PCM (0-31) */
- levels[whichDev] = mixer_output(right, left, 31, 0x10 | 0x07, mixer);
- break;
- case SOUND_MIXER_SPEAKER: /* PC speaker (0-31) */
- levels[whichDev] = mixer_output(right, left, 31, 0x10 | 0x06, mixer);
- break;
- case SOUND_MIXER_LINE: /* External line (0-31) */
- levels[whichDev] = mixer_output(right, left, 31, 0x10 | 0x02, mixer);
- break;
- case SOUND_MIXER_CD: /* CD (0-31) */
- levels[whichDev] = mixer_output(right, left, 31, 0x10 | 0x03, mixer);
- break;
- case SOUND_MIXER_MIC: /* External microphone (0-31) */
- levels[whichDev] = mixer_output(right, left, 31, 0x10 | 0x04, mixer);
- break;
- case SOUND_MIXER_IMIX: /* Recording monitor (0-31) (Output mixer only) */
- levels[whichDev] = mixer_output(right, left, 31, 0x10 | 0x01,
- 0x00);
- break;
- case SOUND_MIXER_RECLEV: /* Recording level (0-15) */
- levels[whichDev] = mixer_output(right, left, 15, 0x02, 0);
- break;
-
-
- case SOUND_MIXER_RECSRC:
- devmask = level & POSSIBLE_RECORDING_DEVICES;
-
- changed = devmask ^ rec_devices;
- rec_devices = devmask;
-
- for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
- if (changed & (1 << i))
- {
- pas_mixer_set(i, levels[i]);
- }
- return rec_devices;
- break;
-
- default:
- return -EINVAL;
- }
-
- return (levels[whichDev]);
-}
-
-/*****/
-
-static void
-pas_mixer_reset(void)
-{
- int foo;
-
- DEB(printk("pas2_mixer.c: void pas_mixer_reset(void)\n"));
-
- for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++)
- pas_mixer_set(foo, levels[foo]);
-
- set_mode(0x04 | 0x01);
-}
-
-static int pas_mixer_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
- int level,v ;
- int __user *p = (int __user *)arg;
-
- DEB(printk("pas2_mixer.c: int pas_mixer_ioctl(unsigned int cmd = %X, unsigned int arg = %X)\n", cmd, arg));
- if (cmd == SOUND_MIXER_PRIVATE1) { /* Set loudness bit */
- if (get_user(level, p))
- return -EFAULT;
- if (level == -1) /* Return current settings */
- level = (mode_control & 0x04);
- else {
- mode_control &= ~0x04;
- if (level)
- mode_control |= 0x04;
- set_mode(mode_control);
- }
- level = !!level;
- return put_user(level, p);
- }
- if (cmd == SOUND_MIXER_PRIVATE2) { /* Set enhance bit */
- if (get_user(level, p))
- return -EFAULT;
- if (level == -1) { /* Return current settings */
- if (!(mode_control & 0x03))
- level = 0;
- else
- level = ((mode_control & 0x03) + 1) * 20;
- } else {
- int i = 0;
-
- level &= 0x7f;
- if (level)
- i = (level / 20) - 1;
- mode_control &= ~0x03;
- mode_control |= i & 0x03;
- set_mode(mode_control);
- if (i)
- i = (i + 1) * 20;
- level = i;
- }
- return put_user(level, p);
- }
- if (cmd == SOUND_MIXER_PRIVATE3) { /* Set mute bit */
- if (get_user(level, p))
- return -EFAULT;
- if (level == -1) /* Return current settings */
- level = !(pas_read(0x0B8A) & 0x20);
- else {
- if (level)
- pas_write(pas_read(0x0B8A) & (~0x20), 0x0B8A);
- else
- pas_write(pas_read(0x0B8A) | 0x20, 0x0B8A);
-
- level = !(pas_read(0x0B8A) & 0x20);
- }
- return put_user(level, p);
- }
- if (((cmd >> 8) & 0xff) == 'M') {
- if (get_user(v, p))
- return -EFAULT;
- if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
- v = pas_mixer_set(cmd & 0xff, v);
- } else {
- switch (cmd & 0xff) {
- case SOUND_MIXER_RECSRC:
- v = rec_devices;
- break;
-
- case SOUND_MIXER_STEREODEVS:
- v = SUPPORTED_MIXER_DEVICES & ~(SOUND_MASK_BASS | SOUND_MASK_TREBLE);
- break;
-
- case SOUND_MIXER_DEVMASK:
- v = SUPPORTED_MIXER_DEVICES;
- break;
-
- case SOUND_MIXER_RECMASK:
- v = POSSIBLE_RECORDING_DEVICES & SUPPORTED_MIXER_DEVICES;
- break;
-
- case SOUND_MIXER_CAPS:
- v = 0; /* No special capabilities */
- break;
-
- default:
- v = levels[cmd & 0xff];
- break;
- }
- }
- return put_user(v, p);
- }
- return -EINVAL;
-}
-
-static struct mixer_operations pas_mixer_operations =
-{
- .owner = THIS_MODULE,
- .id = "PAS16",
- .name = "Pro Audio Spectrum 16",
- .ioctl = pas_mixer_ioctl
-};
-
-int __init
-pas_init_mixer(void)
-{
- int d;
-
- levels = load_mixer_volumes("PAS16_1", default_levels, 1);
-
- pas_mixer_reset();
-
- if ((d = sound_alloc_mixerdev()) != -1)
- {
- audio_devs[pas_audiodev]->mixer_dev = d;
- mixer_devs[d] = &pas_mixer_operations;
- }
- return 1;
-}
diff --git a/ANDROID_3.4.5/sound/oss/pas2_pcm.c b/ANDROID_3.4.5/sound/oss/pas2_pcm.c
deleted file mode 100644
index 6f13ab4a..00000000
--- a/ANDROID_3.4.5/sound/oss/pas2_pcm.c
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * pas2_pcm.c Audio routines for PAS16
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- *
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
- * Alan Cox : Swatted a double allocation of device bug. Made a few
- * more things module options.
- * Bartlomiej Zolnierkiewicz : Added __init to pas_pcm_init()
- */
-
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/timex.h>
-#include "sound_config.h"
-
-#include "pas2.h"
-
-#ifndef DEB
-#define DEB(WHAT)
-#endif
-
-#define PAS_PCM_INTRBITS (0x08)
-/*
- * Sample buffer timer interrupt enable
- */
-
-#define PCM_NON 0
-#define PCM_DAC 1
-#define PCM_ADC 2
-
-static unsigned long pcm_speed; /* sampling rate */
-static unsigned char pcm_channels = 1; /* channels (1 or 2) */
-static unsigned char pcm_bits = 8; /* bits/sample (8 or 16) */
-static unsigned char pcm_filter; /* filter FLAG */
-static unsigned char pcm_mode = PCM_NON;
-static unsigned long pcm_count;
-static unsigned short pcm_bitsok = 8; /* mask of OK bits */
-static int pcm_busy;
-int pas_audiodev = -1;
-static int open_mode;
-
-extern spinlock_t pas_lock;
-
-static int pcm_set_speed(int arg)
-{
- int foo, tmp;
- unsigned long flags;
-
- if (arg == 0)
- return pcm_speed;
-
- if (arg > 44100)
- arg = 44100;
- if (arg < 5000)
- arg = 5000;
-
- if (pcm_channels & 2)
- {
- foo = ((PIT_TICK_RATE / 2) + (arg / 2)) / arg;
- arg = ((PIT_TICK_RATE / 2) + (foo / 2)) / foo;
- }
- else
- {
- foo = (PIT_TICK_RATE + (arg / 2)) / arg;
- arg = (PIT_TICK_RATE + (foo / 2)) / foo;
- }
-
- pcm_speed = arg;
-
- tmp = pas_read(0x0B8A);
-
- /*
- * Set anti-aliasing filters according to sample rate. You really *NEED*
- * to enable this feature for all normal recording unless you want to
- * experiment with aliasing effects.
- * These filters apply to the selected "recording" source.
- * I (pfw) don't know the encoding of these 5 bits. The values shown
- * come from the SDK found on ftp.uwp.edu:/pub/msdos/proaudio/.
- *
- * I cleared bit 5 of these values, since that bit controls the master
- * mute flag. (Olav Wölfelschneider)
- *
- */
-#if !defined NO_AUTO_FILTER_SET
- tmp &= 0xe0;
- if (pcm_speed >= 2 * 17897)
- tmp |= 0x01;
- else if (pcm_speed >= 2 * 15909)
- tmp |= 0x02;
- else if (pcm_speed >= 2 * 11931)
- tmp |= 0x09;
- else if (pcm_speed >= 2 * 8948)
- tmp |= 0x11;
- else if (pcm_speed >= 2 * 5965)
- tmp |= 0x19;
- else if (pcm_speed >= 2 * 2982)
- tmp |= 0x04;
- pcm_filter = tmp;
-#endif
-
- spin_lock_irqsave(&pas_lock, flags);
-
- pas_write(tmp & ~(0x40 | 0x80), 0x0B8A);
- pas_write(0x00 | 0x30 | 0x04, 0x138B);
- pas_write(foo & 0xff, 0x1388);
- pas_write((foo >> 8) & 0xff, 0x1388);
- pas_write(tmp, 0x0B8A);
-
- spin_unlock_irqrestore(&pas_lock, flags);
-
- return pcm_speed;
-}
-
-static int pcm_set_channels(int arg)
-{
-
- if ((arg != 1) && (arg != 2))
- return pcm_channels;
-
- if (arg != pcm_channels)
- {
- pas_write(pas_read(0xF8A) ^ 0x20, 0xF8A);
-
- pcm_channels = arg;
- pcm_set_speed(pcm_speed); /* The speed must be reinitialized */
- }
- return pcm_channels;
-}
-
-static int pcm_set_bits(int arg)
-{
- if (arg == 0)
- return pcm_bits;
-
- if ((arg & pcm_bitsok) != arg)
- return pcm_bits;
-
- if (arg != pcm_bits)
- {
- pas_write(pas_read(0x8389) ^ 0x04, 0x8389);
-
- pcm_bits = arg;
- }
- return pcm_bits;
-}
-
-static int pas_audio_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
- int val, ret;
- int __user *p = arg;
-
- DEB(printk("pas2_pcm.c: static int pas_audio_ioctl(unsigned int cmd = %X, unsigned int arg = %X)\n", cmd, arg));
-
- switch (cmd)
- {
- case SOUND_PCM_WRITE_RATE:
- if (get_user(val, p))
- return -EFAULT;
- ret = pcm_set_speed(val);
- break;
-
- case SOUND_PCM_READ_RATE:
- ret = pcm_speed;
- break;
-
- case SNDCTL_DSP_STEREO:
- if (get_user(val, p))
- return -EFAULT;
- ret = pcm_set_channels(val + 1) - 1;
- break;
-
- case SOUND_PCM_WRITE_CHANNELS:
- if (get_user(val, p))
- return -EFAULT;
- ret = pcm_set_channels(val);
- break;
-
- case SOUND_PCM_READ_CHANNELS:
- ret = pcm_channels;
- break;
-
- case SNDCTL_DSP_SETFMT:
- if (get_user(val, p))
- return -EFAULT;
- ret = pcm_set_bits(val);
- break;
-
- case SOUND_PCM_READ_BITS:
- ret = pcm_bits;
- break;
-
- default:
- return -EINVAL;
- }
- return put_user(ret, p);
-}
-
-static void pas_audio_reset(int dev)
-{
- DEB(printk("pas2_pcm.c: static void pas_audio_reset(void)\n"));
-
- pas_write(pas_read(0xF8A) & ~0x40, 0xF8A); /* Disable PCM */
-}
-
-static int pas_audio_open(int dev, int mode)
-{
- int err;
- unsigned long flags;
-
- DEB(printk("pas2_pcm.c: static int pas_audio_open(int mode = %X)\n", mode));
-
- spin_lock_irqsave(&pas_lock, flags);
- if (pcm_busy)
- {
- spin_unlock_irqrestore(&pas_lock, flags);
- return -EBUSY;
- }
- pcm_busy = 1;
- spin_unlock_irqrestore(&pas_lock, flags);
-
- if ((err = pas_set_intr(PAS_PCM_INTRBITS)) < 0)
- return err;
-
-
- pcm_count = 0;
- open_mode = mode;
-
- return 0;
-}
-
-static void pas_audio_close(int dev)
-{
- unsigned long flags;
-
- DEB(printk("pas2_pcm.c: static void pas_audio_close(void)\n"));
-
- spin_lock_irqsave(&pas_lock, flags);
-
- pas_audio_reset(dev);
- pas_remove_intr(PAS_PCM_INTRBITS);
- pcm_mode = PCM_NON;
-
- pcm_busy = 0;
- spin_unlock_irqrestore(&pas_lock, flags);
-}
-
-static void pas_audio_output_block(int dev, unsigned long buf, int count,
- int intrflag)
-{
- unsigned long flags, cnt;
-
- DEB(printk("pas2_pcm.c: static void pas_audio_output_block(char *buf = %P, int count = %X)\n", buf, count));
-
- cnt = count;
- if (audio_devs[dev]->dmap_out->dma > 3)
- cnt >>= 1;
-
- if (audio_devs[dev]->flags & DMA_AUTOMODE &&
- intrflag &&
- cnt == pcm_count)
- return;
-
- spin_lock_irqsave(&pas_lock, flags);
-
- pas_write(pas_read(0xF8A) & ~0x40,
- 0xF8A);
-
- /* DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE); */
-
- if (audio_devs[dev]->dmap_out->dma > 3)
- count >>= 1;
-
- if (count != pcm_count)
- {
- pas_write(pas_read(0x0B8A) & ~0x80, 0x0B8A);
- pas_write(0x40 | 0x30 | 0x04, 0x138B);
- pas_write(count & 0xff, 0x1389);
- pas_write((count >> 8) & 0xff, 0x1389);
- pas_write(pas_read(0x0B8A) | 0x80, 0x0B8A);
-
- pcm_count = count;
- }
- pas_write(pas_read(0x0B8A) | 0x80 | 0x40, 0x0B8A);
-#ifdef NO_TRIGGER
- pas_write(pas_read(0xF8A) | 0x40 | 0x10, 0xF8A);
-#endif
-
- pcm_mode = PCM_DAC;
-
- spin_unlock_irqrestore(&pas_lock, flags);
-}
-
-static void pas_audio_start_input(int dev, unsigned long buf, int count,
- int intrflag)
-{
- unsigned long flags;
- int cnt;
-
- DEB(printk("pas2_pcm.c: static void pas_audio_start_input(char *buf = %P, int count = %X)\n", buf, count));
-
- cnt = count;
- if (audio_devs[dev]->dmap_out->dma > 3)
- cnt >>= 1;
-
- if (audio_devs[pas_audiodev]->flags & DMA_AUTOMODE &&
- intrflag &&
- cnt == pcm_count)
- return;
-
- spin_lock_irqsave(&pas_lock, flags);
-
- /* DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ); */
-
- if (audio_devs[dev]->dmap_out->dma > 3)
- count >>= 1;
-
- if (count != pcm_count)
- {
- pas_write(pas_read(0x0B8A) & ~0x80, 0x0B8A);
- pas_write(0x40 | 0x30 | 0x04, 0x138B);
- pas_write(count & 0xff, 0x1389);
- pas_write((count >> 8) & 0xff, 0x1389);
- pas_write(pas_read(0x0B8A) | 0x80, 0x0B8A);
-
- pcm_count = count;
- }
- pas_write(pas_read(0x0B8A) | 0x80 | 0x40, 0x0B8A);
-#ifdef NO_TRIGGER
- pas_write((pas_read(0xF8A) | 0x40) & ~0x10, 0xF8A);
-#endif
-
- pcm_mode = PCM_ADC;
-
- spin_unlock_irqrestore(&pas_lock, flags);
-}
-
-#ifndef NO_TRIGGER
-static void pas_audio_trigger(int dev, int state)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&pas_lock, flags);
- state &= open_mode;
-
- if (state & PCM_ENABLE_OUTPUT)
- pas_write(pas_read(0xF8A) | 0x40 | 0x10, 0xF8A);
- else if (state & PCM_ENABLE_INPUT)
- pas_write((pas_read(0xF8A) | 0x40) & ~0x10, 0xF8A);
- else
- pas_write(pas_read(0xF8A) & ~0x40, 0xF8A);
-
- spin_unlock_irqrestore(&pas_lock, flags);
-}
-#endif
-
-static int pas_audio_prepare_for_input(int dev, int bsize, int bcount)
-{
- pas_audio_reset(dev);
- return 0;
-}
-
-static int pas_audio_prepare_for_output(int dev, int bsize, int bcount)
-{
- pas_audio_reset(dev);
- return 0;
-}
-
-static struct audio_driver pas_audio_driver =
-{
- .owner = THIS_MODULE,
- .open = pas_audio_open,
- .close = pas_audio_close,
- .output_block = pas_audio_output_block,
- .start_input = pas_audio_start_input,
- .ioctl = pas_audio_ioctl,
- .prepare_for_input = pas_audio_prepare_for_input,
- .prepare_for_output = pas_audio_prepare_for_output,
- .halt_io = pas_audio_reset,
- .trigger = pas_audio_trigger
-};
-
-void __init pas_pcm_init(struct address_info *hw_config)
-{
- DEB(printk("pas2_pcm.c: long pas_pcm_init()\n"));
-
- pcm_bitsok = 8;
- if (pas_read(0xEF8B) & 0x08)
- pcm_bitsok |= 16;
-
- pcm_set_speed(DSP_DEFAULT_SPEED);
-
- if ((pas_audiodev = sound_install_audiodrv(AUDIO_DRIVER_VERSION,
- "Pro Audio Spectrum",
- &pas_audio_driver,
- sizeof(struct audio_driver),
- DMA_AUTOMODE,
- AFMT_U8 | AFMT_S16_LE,
- NULL,
- hw_config->dma,
- hw_config->dma)) < 0)
- printk(KERN_WARNING "PAS16: Too many PCM devices available\n");
-}
-
-void pas_pcm_interrupt(unsigned char status, int cause)
-{
- if (cause == 1)
- {
- /*
- * Halt the PCM first. Otherwise we don't have time to start a new
- * block before the PCM chip proceeds to the next sample
- */
-
- if (!(audio_devs[pas_audiodev]->flags & DMA_AUTOMODE))
- pas_write(pas_read(0xF8A) & ~0x40, 0xF8A);
-
- switch (pcm_mode)
- {
- case PCM_DAC:
- DMAbuf_outputintr(pas_audiodev, 1);
- break;
-
- case PCM_ADC:
- DMAbuf_inputintr(pas_audiodev);
- break;
-
- default:
- printk(KERN_WARNING "PAS: Unexpected PCM interrupt\n");
- }
- }
-}
diff --git a/ANDROID_3.4.5/sound/oss/pss.c b/ANDROID_3.4.5/sound/oss/pss.c
deleted file mode 100644
index 0f32a561..00000000
--- a/ANDROID_3.4.5/sound/oss/pss.c
+++ /dev/null
@@ -1,1268 +0,0 @@
-/*
- * sound/oss/pss.c
- *
- * The low level driver for the Personal Sound System (ECHO ESC614).
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- *
- * Thomas Sailer ioctl code reworked (vmalloc/vfree removed)
- * Alan Cox modularisation, clean up.
- *
- * 98-02-21: Vladimir Michl <vladimir.michl@upol.cz>
- * Added mixer device for Beethoven ADSP-16 (master volume,
- * bass, treble, synth), only for speakers.
- * Fixed bug in pss_write (exchange parameters)
- * Fixed config port of SB
- * Requested two regions for PSS (PSS mixer, PSS config)
- * Modified pss_download_boot
- * To probe_pss_mss added test for initialize AD1848
- * 98-05-28: Vladimir Michl <vladimir.michl@upol.cz>
- * Fixed computation of mixer volumes
- * 04-05-1999: Anthony Barbachan <barbcode@xmen.cis.fordham.edu>
- * Added code that allows the user to enable his cdrom and/or
- * joystick through the module parameters pss_cdrom_port and
- * pss_enable_joystick. pss_cdrom_port takes a port address as its
- * argument. pss_enable_joystick takes either a 0 or a non-0 as its
- * argument.
- * 04-06-1999: Anthony Barbachan <barbcode@xmen.cis.fordham.edu>
- * Separated some code into new functions for easier reuse.
- * Cleaned up and streamlined new code. Added code to allow a user
- * to only use this driver for enabling non-sound components
- * through the new module parameter pss_no_sound (flag). Added
- * code that would allow a user to decide whether the driver should
- * reset the configured hardware settings for the PSS board through
- * the module parameter pss_keep_settings (flag). This flag will
- * allow a user to free up resources in use by this card if needbe,
- * furthermore it allows him to use this driver to just enable the
- * emulations and then be unloaded as it is no longer needed. Both
- * new settings are only available to this driver if compiled as a
- * module. The default settings of all new parameters are set to
- * load the driver as it did in previous versions.
- * 04-07-1999: Anthony Barbachan <barbcode@xmen.cis.fordham.edu>
- * Added module parameter pss_firmware to allow the user to tell
- * the driver where the firmware file is located. The default
- * setting is the previous hardcoded setting "/etc/sound/pss_synth".
- * 00-03-03: Christoph Hellwig <chhellwig@infradead.org>
- * Adapted to module_init/module_exit
- * 11-10-2000: Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
- * Added __init to probe_pss(), attach_pss() and probe_pss_mpu()
- * 02-Jan-2001: Chris Rankin
- * Specify that this module owns the coprocessor
- */
-
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-
-#include "sound_config.h"
-#include "sound_firmware.h"
-
-#include "ad1848.h"
-#include "mpu401.h"
-
-/*
- * PSS registers.
- */
-#define REG(x) (devc->base+x)
-#define PSS_DATA 0
-#define PSS_STATUS 2
-#define PSS_CONTROL 2
-#define PSS_ID 4
-#define PSS_IRQACK 4
-#define PSS_PIO 0x1a
-
-/*
- * Config registers
- */
-#define CONF_PSS 0x10
-#define CONF_WSS 0x12
-#define CONF_SB 0x14
-#define CONF_CDROM 0x16
-#define CONF_MIDI 0x18
-
-/*
- * Status bits.
- */
-#define PSS_FLAG3 0x0800
-#define PSS_FLAG2 0x0400
-#define PSS_FLAG1 0x1000
-#define PSS_FLAG0 0x0800
-#define PSS_WRITE_EMPTY 0x8000
-#define PSS_READ_FULL 0x4000
-
-/*
- * WSS registers
- */
-#define WSS_INDEX 4
-#define WSS_DATA 5
-
-/*
- * WSS status bits
- */
-#define WSS_INITIALIZING 0x80
-#define WSS_AUTOCALIBRATION 0x20
-
-#define NO_WSS_MIXER -1
-
-#include "coproc.h"
-
-#include "pss_boot.h"
-
-/* If compiled into kernel, it enable or disable pss mixer */
-#ifdef CONFIG_PSS_MIXER
-static bool pss_mixer = 1;
-#else
-static bool pss_mixer;
-#endif
-
-
-typedef struct pss_mixerdata {
- unsigned int volume_l;
- unsigned int volume_r;
- unsigned int bass;
- unsigned int treble;
- unsigned int synth;
-} pss_mixerdata;
-
-typedef struct pss_confdata {
- int base;
- int irq;
- int dma;
- int *osp;
- pss_mixerdata mixer;
- int ad_mixer_dev;
-} pss_confdata;
-
-static pss_confdata pss_data;
-static pss_confdata *devc = &pss_data;
-static DEFINE_SPINLOCK(lock);
-
-static int pss_initialized;
-static int nonstandard_microcode;
-static int pss_cdrom_port = -1; /* Parameter for the PSS cdrom port */
-static bool pss_enable_joystick; /* Parameter for enabling the joystick */
-static coproc_operations pss_coproc_operations;
-
-static void pss_write(pss_confdata *devc, int data)
-{
- unsigned long i, limit;
-
- limit = jiffies + HZ/10; /* The timeout is 0.1 seconds */
- /*
- * Note! the i<5000000 is an emergency exit. The dsp_command() is sometimes
- * called while interrupts are disabled. This means that the timer is
- * disabled also. However the timeout situation is a abnormal condition.
- * Normally the DSP should be ready to accept commands after just couple of
- * loops.
- */
-
- for (i = 0; i < 5000000 && time_before(jiffies, limit); i++)
- {
- if (inw(REG(PSS_STATUS)) & PSS_WRITE_EMPTY)
- {
- outw(data, REG(PSS_DATA));
- return;
- }
- }
- printk(KERN_WARNING "PSS: DSP Command (%04x) Timeout.\n", data);
-}
-
-static int __init probe_pss(struct address_info *hw_config)
-{
- unsigned short id;
- int irq, dma;
-
- devc->base = hw_config->io_base;
- irq = devc->irq = hw_config->irq;
- dma = devc->dma = hw_config->dma;
- devc->osp = hw_config->osp;
-
- if (devc->base != 0x220 && devc->base != 0x240)
- if (devc->base != 0x230 && devc->base != 0x250) /* Some cards use these */
- return 0;
-
- if (!request_region(devc->base, 0x10, "PSS mixer, SB emulation")) {
- printk(KERN_ERR "PSS: I/O port conflict\n");
- return 0;
- }
- id = inw(REG(PSS_ID));
- if ((id >> 8) != 'E') {
- printk(KERN_ERR "No PSS signature detected at 0x%x (0x%x)\n", devc->base, id);
- release_region(devc->base, 0x10);
- return 0;
- }
- if (!request_region(devc->base + 0x10, 0x9, "PSS config")) {
- printk(KERN_ERR "PSS: I/O port conflict\n");
- release_region(devc->base, 0x10);
- return 0;
- }
- return 1;
-}
-
-static int set_irq(pss_confdata * devc, int dev, int irq)
-{
- static unsigned short irq_bits[16] =
- {
- 0x0000, 0x0000, 0x0000, 0x0008,
- 0x0000, 0x0010, 0x0000, 0x0018,
- 0x0000, 0x0020, 0x0028, 0x0030,
- 0x0038, 0x0000, 0x0000, 0x0000
- };
-
- unsigned short tmp, bits;
-
- if (irq < 0 || irq > 15)
- return 0;
-
- tmp = inw(REG(dev)) & ~0x38; /* Load confreg, mask IRQ bits out */
-
- if ((bits = irq_bits[irq]) == 0 && irq != 0)
- {
- printk(KERN_ERR "PSS: Invalid IRQ %d\n", irq);
- return 0;
- }
- outw(tmp | bits, REG(dev));
- return 1;
-}
-
-static void set_io_base(pss_confdata * devc, int dev, int base)
-{
- unsigned short tmp = inw(REG(dev)) & 0x003f;
- unsigned short bits = (base & 0x0ffc) << 4;
-
- outw(bits | tmp, REG(dev));
-}
-
-static int set_dma(pss_confdata * devc, int dev, int dma)
-{
- static unsigned short dma_bits[8] =
- {
- 0x0001, 0x0002, 0x0000, 0x0003,
- 0x0000, 0x0005, 0x0006, 0x0007
- };
-
- unsigned short tmp, bits;
-
- if (dma < 0 || dma > 7)
- return 0;
-
- tmp = inw(REG(dev)) & ~0x07; /* Load confreg, mask DMA bits out */
-
- if ((bits = dma_bits[dma]) == 0 && dma != 4)
- {
- printk(KERN_ERR "PSS: Invalid DMA %d\n", dma);
- return 0;
- }
- outw(tmp | bits, REG(dev));
- return 1;
-}
-
-static int pss_reset_dsp(pss_confdata * devc)
-{
- unsigned long i, limit = jiffies + HZ/10;
-
- outw(0x2000, REG(PSS_CONTROL));
- for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
- inw(REG(PSS_CONTROL));
- outw(0x0000, REG(PSS_CONTROL));
- return 1;
-}
-
-static int pss_put_dspword(pss_confdata * devc, unsigned short word)
-{
- int i, val;
-
- for (i = 0; i < 327680; i++)
- {
- val = inw(REG(PSS_STATUS));
- if (val & PSS_WRITE_EMPTY)
- {
- outw(word, REG(PSS_DATA));
- return 1;
- }
- }
- return 0;
-}
-
-static int pss_get_dspword(pss_confdata * devc, unsigned short *word)
-{
- int i, val;
-
- for (i = 0; i < 327680; i++)
- {
- val = inw(REG(PSS_STATUS));
- if (val & PSS_READ_FULL)
- {
- *word = inw(REG(PSS_DATA));
- return 1;
- }
- }
- return 0;
-}
-
-static int pss_download_boot(pss_confdata * devc, unsigned char *block, int size, int flags)
-{
- int i, val, count;
- unsigned long limit;
-
- if (flags & CPF_FIRST)
- {
-/*_____ Warn DSP software that a boot is coming */
- outw(0x00fe, REG(PSS_DATA));
-
- limit = jiffies + HZ/10;
- for (i = 0; i < 32768 && time_before(jiffies, limit); i++)
- if (inw(REG(PSS_DATA)) == 0x5500)
- break;
-
- outw(*block++, REG(PSS_DATA));
- pss_reset_dsp(devc);
- }
- count = 1;
- while ((flags&CPF_LAST) || count<size )
- {
- int j;
-
- for (j = 0; j < 327670; j++)
- {
-/*_____ Wait for BG to appear */
- if (inw(REG(PSS_STATUS)) & PSS_FLAG3)
- break;
- }
-
- if (j == 327670)
- {
- /* It's ok we timed out when the file was empty */
- if (count >= size && flags & CPF_LAST)
- break;
- else
- {
- printk("\n");
- printk(KERN_ERR "PSS: Download timeout problems, byte %d=%d\n", count, size);
- return 0;
- }
- }
-/*_____ Send the next byte */
- if (count >= size)
- {
- /* If not data in block send 0xffff */
- outw (0xffff, REG (PSS_DATA));
- }
- else
- {
- /*_____ Send the next byte */
- outw (*block++, REG (PSS_DATA));
- };
- count++;
- }
-
- if (flags & CPF_LAST)
- {
-/*_____ Why */
- outw(0, REG(PSS_DATA));
-
- limit = jiffies + HZ/10;
- for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
- val = inw(REG(PSS_STATUS));
-
- limit = jiffies + HZ/10;
- for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
- {
- val = inw(REG(PSS_STATUS));
- if (val & 0x4000)
- break;
- }
-
- /* now read the version */
- for (i = 0; i < 32000; i++)
- {
- val = inw(REG(PSS_STATUS));
- if (val & PSS_READ_FULL)
- break;
- }
- if (i == 32000)
- return 0;
-
- val = inw(REG(PSS_DATA));
- /* printk( "<PSS: microcode version %d.%d loaded>", val/16, val % 16); */
- }
- return 1;
-}
-
-/* Mixer */
-static void set_master_volume(pss_confdata *devc, int left, int right)
-{
- static unsigned char log_scale[101] = {
- 0xdb, 0xe0, 0xe3, 0xe5, 0xe7, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xed, 0xee,
- 0xef, 0xef, 0xf0, 0xf0, 0xf1, 0xf1, 0xf2, 0xf2, 0xf2, 0xf3, 0xf3, 0xf3,
- 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, 0xf7,
- 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9,
- 0xf9, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb,
- 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc,
- 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd,
- 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
- 0xfe, 0xfe, 0xff, 0xff, 0xff
- };
- pss_write(devc, 0x0010);
- pss_write(devc, log_scale[left] | 0x0000);
- pss_write(devc, 0x0010);
- pss_write(devc, log_scale[right] | 0x0100);
-}
-
-static void set_synth_volume(pss_confdata *devc, int volume)
-{
- int vol = ((0x8000*volume)/100L);
- pss_write(devc, 0x0080);
- pss_write(devc, vol);
- pss_write(devc, 0x0081);
- pss_write(devc, vol);
-}
-
-static void set_bass(pss_confdata *devc, int level)
-{
- int vol = (int)(((0xfd - 0xf0) * level)/100L) + 0xf0;
- pss_write(devc, 0x0010);
- pss_write(devc, vol | 0x0200);
-};
-
-static void set_treble(pss_confdata *devc, int level)
-{
- int vol = (((0xfd - 0xf0) * level)/100L) + 0xf0;
- pss_write(devc, 0x0010);
- pss_write(devc, vol | 0x0300);
-};
-
-static void pss_mixer_reset(pss_confdata *devc)
-{
- set_master_volume(devc, 33, 33);
- set_bass(devc, 50);
- set_treble(devc, 50);
- set_synth_volume(devc, 30);
- pss_write (devc, 0x0010);
- pss_write (devc, 0x0800 | 0xce); /* Stereo */
-
- if(pss_mixer)
- {
- devc->mixer.volume_l = devc->mixer.volume_r = 33;
- devc->mixer.bass = 50;
- devc->mixer.treble = 50;
- devc->mixer.synth = 30;
- }
-}
-
-static int set_volume_mono(unsigned __user *p, unsigned int *aleft)
-{
- unsigned int left, volume;
- if (get_user(volume, p))
- return -EFAULT;
-
- left = volume & 0xff;
- if (left > 100)
- left = 100;
- *aleft = left;
- return 0;
-}
-
-static int set_volume_stereo(unsigned __user *p,
- unsigned int *aleft,
- unsigned int *aright)
-{
- unsigned int left, right, volume;
- if (get_user(volume, p))
- return -EFAULT;
-
- left = volume & 0xff;
- if (left > 100)
- left = 100;
- right = (volume >> 8) & 0xff;
- if (right > 100)
- right = 100;
- *aleft = left;
- *aright = right;
- return 0;
-}
-
-static int ret_vol_mono(int left)
-{
- return ((left << 8) | left);
-}
-
-static int ret_vol_stereo(int left, int right)
-{
- return ((right << 8) | left);
-}
-
-static int call_ad_mixer(pss_confdata *devc,unsigned int cmd, void __user *arg)
-{
- if (devc->ad_mixer_dev != NO_WSS_MIXER)
- return mixer_devs[devc->ad_mixer_dev]->ioctl(devc->ad_mixer_dev, cmd, arg);
- else
- return -EINVAL;
-}
-
-static int pss_mixer_ioctl (int dev, unsigned int cmd, void __user *arg)
-{
- pss_confdata *devc = mixer_devs[dev]->devc;
- int cmdf = cmd & 0xff;
-
- if ((cmdf != SOUND_MIXER_VOLUME) && (cmdf != SOUND_MIXER_BASS) &&
- (cmdf != SOUND_MIXER_TREBLE) && (cmdf != SOUND_MIXER_SYNTH) &&
- (cmdf != SOUND_MIXER_DEVMASK) && (cmdf != SOUND_MIXER_STEREODEVS) &&
- (cmdf != SOUND_MIXER_RECMASK) && (cmdf != SOUND_MIXER_CAPS) &&
- (cmdf != SOUND_MIXER_RECSRC))
- {
- return call_ad_mixer(devc, cmd, arg);
- }
-
- if (((cmd >> 8) & 0xff) != 'M')
- return -EINVAL;
-
- if (_SIOC_DIR (cmd) & _SIOC_WRITE)
- {
- switch (cmdf)
- {
- case SOUND_MIXER_RECSRC:
- if (devc->ad_mixer_dev != NO_WSS_MIXER)
- return call_ad_mixer(devc, cmd, arg);
- else
- {
- int v;
- if (get_user(v, (int __user *)arg))
- return -EFAULT;
- if (v != 0)
- return -EINVAL;
- return 0;
- }
- case SOUND_MIXER_VOLUME:
- if (set_volume_stereo(arg,
- &devc->mixer.volume_l,
- &devc->mixer.volume_r))
- return -EFAULT;
- set_master_volume(devc, devc->mixer.volume_l,
- devc->mixer.volume_r);
- return ret_vol_stereo(devc->mixer.volume_l,
- devc->mixer.volume_r);
-
- case SOUND_MIXER_BASS:
- if (set_volume_mono(arg, &devc->mixer.bass))
- return -EFAULT;
- set_bass(devc, devc->mixer.bass);
- return ret_vol_mono(devc->mixer.bass);
-
- case SOUND_MIXER_TREBLE:
- if (set_volume_mono(arg, &devc->mixer.treble))
- return -EFAULT;
- set_treble(devc, devc->mixer.treble);
- return ret_vol_mono(devc->mixer.treble);
-
- case SOUND_MIXER_SYNTH:
- if (set_volume_mono(arg, &devc->mixer.synth))
- return -EFAULT;
- set_synth_volume(devc, devc->mixer.synth);
- return ret_vol_mono(devc->mixer.synth);
-
- default:
- return -EINVAL;
- }
- }
- else
- {
- int val, and_mask = 0, or_mask = 0;
- /*
- * Return parameters
- */
- switch (cmdf)
- {
- case SOUND_MIXER_DEVMASK:
- if (call_ad_mixer(devc, cmd, arg) == -EINVAL)
- break;
- and_mask = ~0;
- or_mask = SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_SYNTH;
- break;
-
- case SOUND_MIXER_STEREODEVS:
- if (call_ad_mixer(devc, cmd, arg) == -EINVAL)
- break;
- and_mask = ~0;
- or_mask = SOUND_MASK_VOLUME;
- break;
-
- case SOUND_MIXER_RECMASK:
- if (devc->ad_mixer_dev != NO_WSS_MIXER)
- return call_ad_mixer(devc, cmd, arg);
- break;
-
- case SOUND_MIXER_CAPS:
- if (devc->ad_mixer_dev != NO_WSS_MIXER)
- return call_ad_mixer(devc, cmd, arg);
- or_mask = SOUND_CAP_EXCL_INPUT;
- break;
-
- case SOUND_MIXER_RECSRC:
- if (devc->ad_mixer_dev != NO_WSS_MIXER)
- return call_ad_mixer(devc, cmd, arg);
- break;
-
- case SOUND_MIXER_VOLUME:
- or_mask = ret_vol_stereo(devc->mixer.volume_l, devc->mixer.volume_r);
- break;
-
- case SOUND_MIXER_BASS:
- or_mask = ret_vol_mono(devc->mixer.bass);
- break;
-
- case SOUND_MIXER_TREBLE:
- or_mask = ret_vol_mono(devc->mixer.treble);
- break;
-
- case SOUND_MIXER_SYNTH:
- or_mask = ret_vol_mono(devc->mixer.synth);
- break;
- default:
- return -EINVAL;
- }
- if (get_user(val, (int __user *)arg))
- return -EFAULT;
- val &= and_mask;
- val |= or_mask;
- if (put_user(val, (int __user *)arg))
- return -EFAULT;
- return val;
- }
-}
-
-static struct mixer_operations pss_mixer_operations =
-{
- .owner = THIS_MODULE,
- .id = "SOUNDPORT",
- .name = "PSS-AD1848",
- .ioctl = pss_mixer_ioctl
-};
-
-static void disable_all_emulations(void)
-{
- outw(0x0000, REG(CONF_PSS)); /* 0x0400 enables joystick */
- outw(0x0000, REG(CONF_WSS));
- outw(0x0000, REG(CONF_SB));
- outw(0x0000, REG(CONF_MIDI));
- outw(0x0000, REG(CONF_CDROM));
-}
-
-static void configure_nonsound_components(void)
-{
- /* Configure Joystick port */
-
- if(pss_enable_joystick)
- {
- outw(0x0400, REG(CONF_PSS)); /* 0x0400 enables joystick */
- printk(KERN_INFO "PSS: joystick enabled.\n");
- }
- else
- {
- printk(KERN_INFO "PSS: joystick port not enabled.\n");
- }
-
- /* Configure CDROM port */
-
- if (pss_cdrom_port == -1) { /* If cdrom port enablation wasn't requested */
- printk(KERN_INFO "PSS: CDROM port not enabled.\n");
- } else if (!request_region(pss_cdrom_port, 2, "PSS CDROM")) {
- pss_cdrom_port = -1;
- printk(KERN_ERR "PSS: CDROM I/O port conflict.\n");
- } else {
- set_io_base(devc, CONF_CDROM, pss_cdrom_port);
- printk(KERN_INFO "PSS: CDROM I/O port set to 0x%x.\n", pss_cdrom_port);
- }
-}
-
-static int __init attach_pss(struct address_info *hw_config)
-{
- unsigned short id;
- char tmp[100];
-
- devc->base = hw_config->io_base;
- devc->irq = hw_config->irq;
- devc->dma = hw_config->dma;
- devc->osp = hw_config->osp;
- devc->ad_mixer_dev = NO_WSS_MIXER;
-
- if (!probe_pss(hw_config))
- return 0;
-
- id = inw(REG(PSS_ID)) & 0x00ff;
-
- /*
- * Disable all emulations. Will be enabled later (if required).
- */
-
- disable_all_emulations();
-
-#ifdef YOU_REALLY_WANT_TO_ALLOCATE_THESE_RESOURCES
- if (sound_alloc_dma(hw_config->dma, "PSS"))
- {
- printk("pss.c: Can't allocate DMA channel.\n");
- release_region(hw_config->io_base, 0x10);
- release_region(hw_config->io_base+0x10, 0x9);
- return 0;
- }
- if (!set_irq(devc, CONF_PSS, devc->irq))
- {
- printk("PSS: IRQ allocation error.\n");
- release_region(hw_config->io_base, 0x10);
- release_region(hw_config->io_base+0x10, 0x9);
- return 0;
- }
- if (!set_dma(devc, CONF_PSS, devc->dma))
- {
- printk(KERN_ERR "PSS: DMA allocation error\n");
- release_region(hw_config->io_base, 0x10);
- release_region(hw_config->io_base+0x10, 0x9);
- return 0;
- }
-#endif
-
- configure_nonsound_components();
- pss_initialized = 1;
- sprintf(tmp, "ECHO-PSS Rev. %d", id);
- conf_printf(tmp, hw_config);
- return 1;
-}
-
-static int __init probe_pss_mpu(struct address_info *hw_config)
-{
- struct resource *ports;
- int timeout;
-
- if (!pss_initialized)
- return 0;
-
- ports = request_region(hw_config->io_base, 2, "mpu401");
-
- if (!ports) {
- printk(KERN_ERR "PSS: MPU I/O port conflict\n");
- return 0;
- }
- set_io_base(devc, CONF_MIDI, hw_config->io_base);
- if (!set_irq(devc, CONF_MIDI, hw_config->irq)) {
- printk(KERN_ERR "PSS: MIDI IRQ allocation error.\n");
- goto fail;
- }
- if (!pss_synthLen) {
- printk(KERN_ERR "PSS: Can't enable MPU. MIDI synth microcode not available.\n");
- goto fail;
- }
- if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST)) {
- printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
- goto fail;
- }
-
- /*
- * Finally wait until the DSP algorithm has initialized itself and
- * deactivates receive interrupt.
- */
-
- for (timeout = 900000; timeout > 0; timeout--)
- {
- if ((inb(hw_config->io_base + 1) & 0x80) == 0) /* Input data avail */
- inb(hw_config->io_base); /* Discard it */
- else
- break; /* No more input */
- }
-
- if (!probe_mpu401(hw_config, ports))
- goto fail;
-
- attach_mpu401(hw_config, THIS_MODULE); /* Slot 1 */
- if (hw_config->slots[1] != -1) /* The MPU driver installed itself */
- midi_devs[hw_config->slots[1]]->coproc = &pss_coproc_operations;
- return 1;
-fail:
- release_region(hw_config->io_base, 2);
- return 0;
-}
-
-static int pss_coproc_open(void *dev_info, int sub_device)
-{
- switch (sub_device)
- {
- case COPR_MIDI:
- if (pss_synthLen == 0)
- {
- printk(KERN_ERR "PSS: MIDI synth microcode not available.\n");
- return -EIO;
- }
- if (nonstandard_microcode)
- if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
- {
- printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
- return -EIO;
- }
- nonstandard_microcode = 0;
- break;
-
- default:
- break;
- }
- return 0;
-}
-
-static void pss_coproc_close(void *dev_info, int sub_device)
-{
- return;
-}
-
-static void pss_coproc_reset(void *dev_info)
-{
- if (pss_synthLen)
- if (!pss_download_boot(devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
- {
- printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
- }
- nonstandard_microcode = 0;
-}
-
-static int download_boot_block(void *dev_info, copr_buffer * buf)
-{
- if (buf->len <= 0 || buf->len > sizeof(buf->data))
- return -EINVAL;
-
- if (!pss_download_boot(devc, buf->data, buf->len, buf->flags))
- {
- printk(KERN_ERR "PSS: Unable to load microcode block to DSP.\n");
- return -EIO;
- }
- nonstandard_microcode = 1; /* The MIDI microcode has been overwritten */
- return 0;
-}
-
-static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg, int local)
-{
- copr_buffer *buf;
- copr_msg *mbuf;
- copr_debug_buf dbuf;
- unsigned short tmp;
- unsigned long flags;
- unsigned short *data;
- int i, err;
- /* printk( "PSS coproc ioctl %x %x %d\n", cmd, arg, local); */
-
- switch (cmd)
- {
- case SNDCTL_COPR_RESET:
- pss_coproc_reset(dev_info);
- return 0;
-
- case SNDCTL_COPR_LOAD:
- buf = vmalloc(sizeof(copr_buffer));
- if (buf == NULL)
- return -ENOSPC;
- if (copy_from_user(buf, arg, sizeof(copr_buffer))) {
- vfree(buf);
- return -EFAULT;
- }
- err = download_boot_block(dev_info, buf);
- vfree(buf);
- return err;
-
- case SNDCTL_COPR_SENDMSG:
- mbuf = vmalloc(sizeof(copr_msg));
- if (mbuf == NULL)
- return -ENOSPC;
- if (copy_from_user(mbuf, arg, sizeof(copr_msg))) {
- vfree(mbuf);
- return -EFAULT;
- }
- data = (unsigned short *)(mbuf->data);
- spin_lock_irqsave(&lock, flags);
- for (i = 0; i < mbuf->len; i++) {
- if (!pss_put_dspword(devc, *data++)) {
- spin_unlock_irqrestore(&lock,flags);
- mbuf->len = i; /* feed back number of WORDs sent */
- err = copy_to_user(arg, mbuf, sizeof(copr_msg));
- vfree(mbuf);
- return err ? -EFAULT : -EIO;
- }
- }
- spin_unlock_irqrestore(&lock,flags);
- vfree(mbuf);
- return 0;
-
- case SNDCTL_COPR_RCVMSG:
- err = 0;
- mbuf = vmalloc(sizeof(copr_msg));
- if (mbuf == NULL)
- return -ENOSPC;
- data = (unsigned short *)mbuf->data;
- spin_lock_irqsave(&lock, flags);
- for (i = 0; i < sizeof(mbuf->data)/sizeof(unsigned short); i++) {
- mbuf->len = i; /* feed back number of WORDs read */
- if (!pss_get_dspword(devc, data++)) {
- if (i == 0)
- err = -EIO;
- break;
- }
- }
- spin_unlock_irqrestore(&lock,flags);
- if (copy_to_user(arg, mbuf, sizeof(copr_msg)))
- err = -EFAULT;
- vfree(mbuf);
- return err;
-
- case SNDCTL_COPR_RDATA:
- if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
- return -EFAULT;
- spin_lock_irqsave(&lock, flags);
- if (!pss_put_dspword(devc, 0x00d0)) {
- spin_unlock_irqrestore(&lock,flags);
- return -EIO;
- }
- if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
- spin_unlock_irqrestore(&lock,flags);
- return -EIO;
- }
- if (!pss_get_dspword(devc, &tmp)) {
- spin_unlock_irqrestore(&lock,flags);
- return -EIO;
- }
- dbuf.parm1 = tmp;
- spin_unlock_irqrestore(&lock,flags);
- if (copy_to_user(arg, &dbuf, sizeof(dbuf)))
- return -EFAULT;
- return 0;
-
- case SNDCTL_COPR_WDATA:
- if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
- return -EFAULT;
- spin_lock_irqsave(&lock, flags);
- if (!pss_put_dspword(devc, 0x00d1)) {
- spin_unlock_irqrestore(&lock,flags);
- return -EIO;
- }
- if (!pss_put_dspword(devc, (unsigned short) (dbuf.parm1 & 0xffff))) {
- spin_unlock_irqrestore(&lock,flags);
- return -EIO;
- }
- tmp = (unsigned int)dbuf.parm2 & 0xffff;
- if (!pss_put_dspword(devc, tmp)) {
- spin_unlock_irqrestore(&lock,flags);
- return -EIO;
- }
- spin_unlock_irqrestore(&lock,flags);
- return 0;
-
- case SNDCTL_COPR_WCODE:
- if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
- return -EFAULT;
- spin_lock_irqsave(&lock, flags);
- if (!pss_put_dspword(devc, 0x00d3)) {
- spin_unlock_irqrestore(&lock,flags);
- return -EIO;
- }
- if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
- spin_unlock_irqrestore(&lock,flags);
- return -EIO;
- }
- tmp = (unsigned int)dbuf.parm2 & 0x00ff;
- if (!pss_put_dspword(devc, tmp)) {
- spin_unlock_irqrestore(&lock,flags);
- return -EIO;
- }
- tmp = ((unsigned int)dbuf.parm2 >> 8) & 0xffff;
- if (!pss_put_dspword(devc, tmp)) {
- spin_unlock_irqrestore(&lock,flags);
- return -EIO;
- }
- spin_unlock_irqrestore(&lock,flags);
- return 0;
-
- case SNDCTL_COPR_RCODE:
- if (copy_from_user(&dbuf, arg, sizeof(dbuf)))
- return -EFAULT;
- spin_lock_irqsave(&lock, flags);
- if (!pss_put_dspword(devc, 0x00d2)) {
- spin_unlock_irqrestore(&lock,flags);
- return -EIO;
- }
- if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
- spin_unlock_irqrestore(&lock,flags);
- return -EIO;
- }
- if (!pss_get_dspword(devc, &tmp)) { /* Read MSB */
- spin_unlock_irqrestore(&lock,flags);
- return -EIO;
- }
- dbuf.parm1 = tmp << 8;
- if (!pss_get_dspword(devc, &tmp)) { /* Read LSB */
- spin_unlock_irqrestore(&lock,flags);
- return -EIO;
- }
- dbuf.parm1 |= tmp & 0x00ff;
- spin_unlock_irqrestore(&lock,flags);
- if (copy_to_user(arg, &dbuf, sizeof(dbuf)))
- return -EFAULT;
- return 0;
-
- default:
- return -EINVAL;
- }
- return -EINVAL;
-}
-
-static coproc_operations pss_coproc_operations =
-{
- "ADSP-2115",
- THIS_MODULE,
- pss_coproc_open,
- pss_coproc_close,
- pss_coproc_ioctl,
- pss_coproc_reset,
- &pss_data
-};
-
-static int __init probe_pss_mss(struct address_info *hw_config)
-{
- volatile int timeout;
- struct resource *ports;
- int my_mix = -999; /* gcc shut up */
-
- if (!pss_initialized)
- return 0;
-
- if (!request_region(hw_config->io_base, 4, "WSS config")) {
- printk(KERN_ERR "PSS: WSS I/O port conflicts.\n");
- return 0;
- }
- ports = request_region(hw_config->io_base + 4, 4, "ad1848");
- if (!ports) {
- printk(KERN_ERR "PSS: WSS I/O port conflicts.\n");
- release_region(hw_config->io_base, 4);
- return 0;
- }
- set_io_base(devc, CONF_WSS, hw_config->io_base);
- if (!set_irq(devc, CONF_WSS, hw_config->irq)) {
- printk("PSS: WSS IRQ allocation error.\n");
- goto fail;
- }
- if (!set_dma(devc, CONF_WSS, hw_config->dma)) {
- printk(KERN_ERR "PSS: WSS DMA allocation error\n");
- goto fail;
- }
- /*
- * For some reason the card returns 0xff in the WSS status register
- * immediately after boot. Probably MIDI+SB emulation algorithm
- * downloaded to the ADSP2115 spends some time initializing the card.
- * Let's try to wait until it finishes this task.
- */
- for (timeout = 0; timeout < 100000 && (inb(hw_config->io_base + WSS_INDEX) &
- WSS_INITIALIZING); timeout++)
- ;
-
- outb((0x0b), hw_config->io_base + WSS_INDEX); /* Required by some cards */
-
- for (timeout = 0; (inb(hw_config->io_base + WSS_DATA) & WSS_AUTOCALIBRATION) &&
- (timeout < 100000); timeout++)
- ;
-
- if (!probe_ms_sound(hw_config, ports))
- goto fail;
-
- devc->ad_mixer_dev = NO_WSS_MIXER;
- if (pss_mixer)
- {
- if ((my_mix = sound_install_mixer (MIXER_DRIVER_VERSION,
- "PSS-SPEAKERS and AD1848 (through MSS audio codec)",
- &pss_mixer_operations,
- sizeof (struct mixer_operations),
- devc)) < 0)
- {
- printk(KERN_ERR "Could not install PSS mixer\n");
- goto fail;
- }
- }
- pss_mixer_reset(devc);
- attach_ms_sound(hw_config, ports, THIS_MODULE); /* Slot 0 */
-
- if (hw_config->slots[0] != -1)
- {
- /* The MSS driver installed itself */
- audio_devs[hw_config->slots[0]]->coproc = &pss_coproc_operations;
- if (pss_mixer && (num_mixers == (my_mix + 2)))
- {
- /* The MSS mixer installed */
- devc->ad_mixer_dev = audio_devs[hw_config->slots[0]]->mixer_dev;
- }
- }
- return 1;
-fail:
- release_region(hw_config->io_base + 4, 4);
- release_region(hw_config->io_base, 4);
- return 0;
-}
-
-static inline void __exit unload_pss(struct address_info *hw_config)
-{
- release_region(hw_config->io_base, 0x10);
- release_region(hw_config->io_base+0x10, 0x9);
-}
-
-static inline void __exit unload_pss_mpu(struct address_info *hw_config)
-{
- unload_mpu401(hw_config);
-}
-
-static inline void __exit unload_pss_mss(struct address_info *hw_config)
-{
- unload_ms_sound(hw_config);
-}
-
-
-static struct address_info cfg;
-static struct address_info cfg2;
-static struct address_info cfg_mpu;
-
-static int pss_io __initdata = -1;
-static int mss_io __initdata = -1;
-static int mss_irq __initdata = -1;
-static int mss_dma __initdata = -1;
-static int mpu_io __initdata = -1;
-static int mpu_irq __initdata = -1;
-static bool pss_no_sound = 0; /* Just configure non-sound components */
-static bool pss_keep_settings = 1; /* Keep hardware settings at module exit */
-static char *pss_firmware = "/etc/sound/pss_synth";
-
-module_param(pss_io, int, 0);
-MODULE_PARM_DESC(pss_io, "Set i/o base of PSS card (probably 0x220 or 0x240)");
-module_param(mss_io, int, 0);
-MODULE_PARM_DESC(mss_io, "Set WSS (audio) i/o base (0x530, 0x604, 0xE80, 0xF40, or other. Address must end in 0 or 4 and must be from 0x100 to 0xFF4)");
-module_param(mss_irq, int, 0);
-MODULE_PARM_DESC(mss_irq, "Set WSS (audio) IRQ (3, 5, 7, 9, 10, 11, 12)");
-module_param(mss_dma, int, 0);
-MODULE_PARM_DESC(mss_dma, "Set WSS (audio) DMA (0, 1, 3)");
-module_param(mpu_io, int, 0);
-MODULE_PARM_DESC(mpu_io, "Set MIDI i/o base (0x330 or other. Address must be on 4 location boundaries and must be from 0x100 to 0xFFC)");
-module_param(mpu_irq, int, 0);
-MODULE_PARM_DESC(mpu_irq, "Set MIDI IRQ (3, 5, 7, 9, 10, 11, 12)");
-module_param(pss_cdrom_port, int, 0);
-MODULE_PARM_DESC(pss_cdrom_port, "Set the PSS CDROM port i/o base (0x340 or other)");
-module_param(pss_enable_joystick, bool, 0);
-MODULE_PARM_DESC(pss_enable_joystick, "Enables the PSS joystick port (1 to enable, 0 to disable)");
-module_param(pss_no_sound, bool, 0);
-MODULE_PARM_DESC(pss_no_sound, "Configure sound compoents (0 - no, 1 - yes)");
-module_param(pss_keep_settings, bool, 0);
-MODULE_PARM_DESC(pss_keep_settings, "Keep hardware setting at driver unloading (0 - no, 1 - yes)");
-module_param(pss_firmware, charp, 0);
-MODULE_PARM_DESC(pss_firmware, "Location of the firmware file (default - /etc/sound/pss_synth)");
-module_param(pss_mixer, bool, 0);
-MODULE_PARM_DESC(pss_mixer, "Enable (1) or disable (0) PSS mixer (controlling of output volume, bass, treble, synth volume). The mixer is not available on all PSS cards.");
-MODULE_AUTHOR("Hannu Savolainen, Vladimir Michl");
-MODULE_DESCRIPTION("Module for PSS sound cards (based on AD1848, ADSP-2115 and ESC614). This module includes control of output amplifier and synth volume of the Beethoven ADSP-16 card (this may work with other PSS cards).");
-MODULE_LICENSE("GPL");
-
-
-static int fw_load = 0;
-static int pssmpu = 0, pssmss = 0;
-
-/*
- * Load a PSS sound card module
- */
-
-static int __init init_pss(void)
-{
-
- if(pss_no_sound) /* If configuring only nonsound components */
- {
- cfg.io_base = pss_io;
- if(!probe_pss(&cfg))
- return -ENODEV;
- printk(KERN_INFO "ECHO-PSS Rev. %d\n", inw(REG(PSS_ID)) & 0x00ff);
- printk(KERN_INFO "PSS: loading in no sound mode.\n");
- disable_all_emulations();
- configure_nonsound_components();
- release_region(pss_io, 0x10);
- release_region(pss_io + 0x10, 0x9);
- return 0;
- }
-
- cfg.io_base = pss_io;
-
- cfg2.io_base = mss_io;
- cfg2.irq = mss_irq;
- cfg2.dma = mss_dma;
-
- cfg_mpu.io_base = mpu_io;
- cfg_mpu.irq = mpu_irq;
-
- if (cfg.io_base == -1 || cfg2.io_base == -1 || cfg2.irq == -1 || cfg.dma == -1) {
- printk(KERN_INFO "pss: mss_io, mss_dma, mss_irq and pss_io must be set.\n");
- return -EINVAL;
- }
-
- if (!pss_synth) {
- fw_load = 1;
- pss_synthLen = mod_firmware_load(pss_firmware, (void *) &pss_synth);
- }
- if (!attach_pss(&cfg))
- return -ENODEV;
- /*
- * Attach stuff
- */
- if (probe_pss_mpu(&cfg_mpu))
- pssmpu = 1;
-
- if (probe_pss_mss(&cfg2))
- pssmss = 1;
-
- return 0;
-}
-
-static void __exit cleanup_pss(void)
-{
- if(!pss_no_sound)
- {
- if(fw_load && pss_synth)
- vfree(pss_synth);
- if(pssmss)
- unload_pss_mss(&cfg2);
- if(pssmpu)
- unload_pss_mpu(&cfg_mpu);
- unload_pss(&cfg);
- } else if (pss_cdrom_port != -1)
- release_region(pss_cdrom_port, 2);
-
- if(!pss_keep_settings) /* Keep hardware settings if asked */
- {
- disable_all_emulations();
- printk(KERN_INFO "Resetting PSS sound card configurations.\n");
- }
-}
-
-module_init(init_pss);
-module_exit(cleanup_pss);
-
-#ifndef MODULE
-static int __init setup_pss(char *str)
-{
- /* io, mss_io, mss_irq, mss_dma, mpu_io, mpu_irq */
- int ints[7];
-
- str = get_options(str, ARRAY_SIZE(ints), ints);
-
- pss_io = ints[1];
- mss_io = ints[2];
- mss_irq = ints[3];
- mss_dma = ints[4];
- mpu_io = ints[5];
- mpu_irq = ints[6];
-
- return 1;
-}
-
-__setup("pss=", setup_pss);
-#endif
diff --git a/ANDROID_3.4.5/sound/oss/sb.h b/ANDROID_3.4.5/sound/oss/sb.h
deleted file mode 100644
index 77e8891c..00000000
--- a/ANDROID_3.4.5/sound/oss/sb.h
+++ /dev/null
@@ -1,185 +0,0 @@
-#define DSP_RESET (devc->base + 0x6)
-#define DSP_READ (devc->base + 0xA)
-#define DSP_WRITE (devc->base + 0xC)
-#define DSP_COMMAND (devc->base + 0xC)
-#define DSP_STATUS (devc->base + 0xC)
-#define DSP_DATA_AVAIL (devc->base + 0xE)
-#define DSP_DATA_AVL16 (devc->base + 0xF)
-#define MIXER_ADDR (devc->base + 0x4)
-#define MIXER_DATA (devc->base + 0x5)
-#define OPL3_LEFT (devc->base + 0x0)
-#define OPL3_RIGHT (devc->base + 0x2)
-#define OPL3_BOTH (devc->base + 0x8)
-/* DSP Commands */
-
-#define DSP_CMD_SPKON 0xD1
-#define DSP_CMD_SPKOFF 0xD3
-#define DSP_CMD_DMAON 0xD0
-#define DSP_CMD_DMAOFF 0xD4
-
-#define IMODE_NONE 0
-#define IMODE_OUTPUT PCM_ENABLE_OUTPUT
-#define IMODE_INPUT PCM_ENABLE_INPUT
-#define IMODE_INIT 3
-#define IMODE_MIDI 4
-
-#define NORMAL_MIDI 0
-#define UART_MIDI 1
-
-
-/*
- * Device models
- */
-#define MDL_NONE 0
-#define MDL_SB1 1 /* SB1.0 or 1.5 */
-#define MDL_SB2 2 /* SB2.0 */
-#define MDL_SB201 3 /* SB2.01 */
-#define MDL_SBPRO 4 /* SB Pro */
-#define MDL_SB16 5 /* SB16/32/AWE */
-#define MDL_SBPNP 6 /* SB16/32/AWE PnP */
-#define MDL_JAZZ 10 /* Media Vision Jazz16 */
-#define MDL_SMW 11 /* Logitech SoundMan Wave (Jazz16) */
-#define MDL_ESS 12 /* ESS ES688 and ES1688 */
-#define MDL_AZTECH 13 /* Aztech Sound Galaxy family */
-#define MDL_ES1868MIDI 14 /* MIDI port of ESS1868 */
-#define MDL_AEDSP 15 /* Audio Excel DSP 16 */
-#define MDL_ESSPCI 16 /* ESS PCI card */
-#define MDL_YMPCI 17 /* Yamaha PCI sb in emulation */
-
-#define SUBMDL_ALS007 42 /* ALS-007 differs from SB16 only in mixer */
- /* register assignment */
-#define SUBMDL_ALS100 43 /* ALS-100 allows sampling rates of up */
- /* to 48kHz */
-
-/*
- * Config flags
- */
-#define SB_NO_MIDI 0x00000001
-#define SB_NO_MIXER 0x00000002
-#define SB_NO_AUDIO 0x00000004
-#define SB_NO_RECORDING 0x00000008 /* No audio recording */
-#define SB_MIDI_ONLY (SB_NO_AUDIO|SB_NO_MIXER)
-#define SB_PCI_IRQ 0x00000010 /* PCI shared IRQ */
-
-struct mixer_def {
- unsigned int regno: 8;
- unsigned int bitoffs:4;
- unsigned int nbits:4;
-};
-
-typedef struct mixer_def mixer_tab[32][2];
-typedef struct mixer_def mixer_ent;
-
-struct sb_module_options
-{
- int esstype; /* ESS chip type */
- int acer; /* Do acer notebook init? */
- int sm_games; /* Logitech soundman games? */
-};
-
-typedef struct sb_devc {
- int dev;
-
- /* Hardware parameters */
- int *osp;
- int minor, major;
- int type;
- int model, submodel;
- int caps;
-# define SBCAP_STEREO 0x00000001
-# define SBCAP_16BITS 0x00000002
-
- /* Hardware resources */
- int base;
- int irq;
- int dma8, dma16;
-
- int pcibase; /* For ESS Maestro etc */
-
- /* State variables */
- int opened;
- /* new audio fields for full duplex support */
- int fullduplex;
- int duplex;
- int speed, bits, channels;
- volatile int irq_ok;
- volatile int intr_active, irq_mode;
- /* duplicate audio fields for full duplex support */
- volatile int intr_active_16, irq_mode_16;
-
- /* Mixer fields */
- int *levels;
- mixer_tab *iomap;
- size_t iomap_sz; /* number or records in the iomap table */
- int mixer_caps, recmask, outmask, supported_devices;
- int supported_rec_devices, supported_out_devices;
- int my_mixerdev;
- int sbmixnum;
-
- /* Audio fields */
- unsigned long trg_buf;
- int trigger_bits;
- int trg_bytes;
- int trg_intrflag;
- int trg_restart;
- /* duplicate audio fields for full duplex support */
- unsigned long trg_buf_16;
- int trigger_bits_16;
- int trg_bytes_16;
- int trg_intrflag_16;
- int trg_restart_16;
-
- unsigned char tconst;
-
- /* MIDI fields */
- int my_mididev;
- int input_opened;
- int midi_broken;
- void (*midi_input_intr) (int dev, unsigned char data);
- void *midi_irq_cookie; /* IRQ cookie for the midi */
-
- spinlock_t lock;
-
- struct sb_module_options sbmo; /* Module options */
-
- } sb_devc;
-
-/*
- * PCI card types
- */
-
-#define SB_PCI_ESSMAESTRO 1 /* ESS Maestro Legacy */
-#define SB_PCI_YAMAHA 2 /* Yamaha Legacy */
-
-/*
- * Functions
- */
-
-int sb_dsp_command (sb_devc *devc, unsigned char val);
-int sb_dsp_get_byte(sb_devc * devc);
-int sb_dsp_reset (sb_devc *devc);
-void sb_setmixer (sb_devc *devc, unsigned int port, unsigned int value);
-unsigned int sb_getmixer (sb_devc *devc, unsigned int port);
-int sb_dsp_detect (struct address_info *hw_config, int pci, int pciio, struct sb_module_options *sbmo);
-int sb_dsp_init (struct address_info *hw_config, struct module *owner);
-void sb_dsp_unload(struct address_info *hw_config, int sbmpu);
-int sb_mixer_init(sb_devc *devc, struct module *owner);
-void sb_mixer_unload(sb_devc *devc);
-void sb_mixer_set_stereo (sb_devc *devc, int mode);
-void smw_mixer_init(sb_devc *devc);
-void sb_dsp_midi_init (sb_devc *devc, struct module *owner);
-void sb_audio_init (sb_devc *devc, char *name, struct module *owner);
-void sb_midi_interrupt (sb_devc *devc);
-void sb_chgmixer (sb_devc * devc, unsigned int reg, unsigned int mask, unsigned int val);
-int sb_common_mixer_set(sb_devc * devc, int dev, int left, int right);
-
-int sb_audio_open(int dev, int mode);
-void sb_audio_close(int dev);
-
-/* From sb_common.c */
-void sb_dsp_disable_midi(int port);
-int probe_sbmpu (struct address_info *hw_config, struct module *owner);
-void unload_sbmpu (struct address_info *hw_config);
-
-void unload_sb16(struct address_info *hw_info);
-void unload_sb16midi(struct address_info *hw_info);
diff --git a/ANDROID_3.4.5/sound/oss/sb_audio.c b/ANDROID_3.4.5/sound/oss/sb_audio.c
deleted file mode 100644
index 733b014e..00000000
--- a/ANDROID_3.4.5/sound/oss/sb_audio.c
+++ /dev/null
@@ -1,1098 +0,0 @@
-/*
- * sound/oss/sb_audio.c
- *
- * Audio routines for Sound Blaster compatible cards.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Changes
- * Alan Cox : Formatting and clean ups
- *
- * Status
- * Mostly working. Weird uart bug causing irq storms
- *
- * Daniel J. Rodriksson: Changes to make sb16 work full duplex.
- * Maybe other 16 bit cards in this code could behave
- * the same.
- * Chris Rankin: Use spinlocks instead of CLI/STI
- */
-
-#include <linux/spinlock.h>
-
-#include "sound_config.h"
-
-#include "sb_mixer.h"
-#include "sb.h"
-
-#include "sb_ess.h"
-
-int sb_audio_open(int dev, int mode)
-{
- sb_devc *devc = audio_devs[dev]->devc;
- unsigned long flags;
-
- if (devc == NULL)
- {
- printk(KERN_ERR "Sound Blaster: incomplete initialization.\n");
- return -ENXIO;
- }
- if (devc->caps & SB_NO_RECORDING && mode & OPEN_READ)
- {
- if (mode == OPEN_READ)
- return -EPERM;
- }
- spin_lock_irqsave(&devc->lock, flags);
- if (devc->opened)
- {
- spin_unlock_irqrestore(&devc->lock, flags);
- return -EBUSY;
- }
- if (devc->dma16 != -1 && devc->dma16 != devc->dma8 && !devc->duplex)
- {
- if (sound_open_dma(devc->dma16, "Sound Blaster 16 bit"))
- {
- spin_unlock_irqrestore(&devc->lock, flags);
- return -EBUSY;
- }
- }
- devc->opened = mode;
- spin_unlock_irqrestore(&devc->lock, flags);
-
- devc->irq_mode = IMODE_NONE;
- devc->irq_mode_16 = IMODE_NONE;
- devc->fullduplex = devc->duplex &&
- ((mode & OPEN_READ) && (mode & OPEN_WRITE));
- sb_dsp_reset(devc);
-
- /* At first glance this check isn't enough, some ESS chips might not
- * have a RECLEV. However if they don't common_mixer_set will refuse
- * cause devc->iomap has no register mapping for RECLEV
- */
- if (devc->model == MDL_ESS) ess_mixer_reload (devc, SOUND_MIXER_RECLEV);
-
- /* The ALS007 seems to require that the DSP be removed from the output */
- /* in order for recording to be activated properly. This is done by */
- /* setting the appropriate bits of the output control register 4ch to */
- /* zero. This code assumes that the output control registers are not */
- /* used anywhere else and therefore the DSP bits are *always* ON for */
- /* output and OFF for sampling. */
-
- if (devc->submodel == SUBMDL_ALS007)
- {
- if (mode & OPEN_READ)
- sb_setmixer(devc,ALS007_OUTPUT_CTRL2,
- sb_getmixer(devc,ALS007_OUTPUT_CTRL2) & 0xf9);
- else
- sb_setmixer(devc,ALS007_OUTPUT_CTRL2,
- sb_getmixer(devc,ALS007_OUTPUT_CTRL2) | 0x06);
- }
- return 0;
-}
-
-void sb_audio_close(int dev)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- /* fix things if mmap turned off fullduplex */
- if(devc->duplex
- && !devc->fullduplex
- && (devc->opened & OPEN_READ) && (devc->opened & OPEN_WRITE))
- {
- struct dma_buffparms *dmap_temp;
- dmap_temp = audio_devs[dev]->dmap_out;
- audio_devs[dev]->dmap_out = audio_devs[dev]->dmap_in;
- audio_devs[dev]->dmap_in = dmap_temp;
- }
- audio_devs[dev]->dmap_out->dma = devc->dma8;
- audio_devs[dev]->dmap_in->dma = ( devc->duplex ) ?
- devc->dma16 : devc->dma8;
-
- if (devc->dma16 != -1 && devc->dma16 != devc->dma8 && !devc->duplex)
- sound_close_dma(devc->dma16);
-
- /* For ALS007, turn DSP output back on if closing the device for read */
-
- if ((devc->submodel == SUBMDL_ALS007) && (devc->opened & OPEN_READ))
- {
- sb_setmixer(devc,ALS007_OUTPUT_CTRL2,
- sb_getmixer(devc,ALS007_OUTPUT_CTRL2) | 0x06);
- }
- devc->opened = 0;
-}
-
-static void sb_set_output_parms(int dev, unsigned long buf, int nr_bytes,
- int intrflag)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- if (!devc->fullduplex || devc->bits == AFMT_S16_LE)
- {
- devc->trg_buf = buf;
- devc->trg_bytes = nr_bytes;
- devc->trg_intrflag = intrflag;
- devc->irq_mode = IMODE_OUTPUT;
- }
- else
- {
- devc->trg_buf_16 = buf;
- devc->trg_bytes_16 = nr_bytes;
- devc->trg_intrflag_16 = intrflag;
- devc->irq_mode_16 = IMODE_OUTPUT;
- }
-}
-
-static void sb_set_input_parms(int dev, unsigned long buf, int count, int intrflag)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- if (!devc->fullduplex || devc->bits != AFMT_S16_LE)
- {
- devc->trg_buf = buf;
- devc->trg_bytes = count;
- devc->trg_intrflag = intrflag;
- devc->irq_mode = IMODE_INPUT;
- }
- else
- {
- devc->trg_buf_16 = buf;
- devc->trg_bytes_16 = count;
- devc->trg_intrflag_16 = intrflag;
- devc->irq_mode_16 = IMODE_INPUT;
- }
-}
-
-/*
- * SB1.x compatible routines
- */
-
-static void sb1_audio_output_block(int dev, unsigned long buf, int nr_bytes, int intrflag)
-{
- unsigned long flags;
- int count = nr_bytes;
- sb_devc *devc = audio_devs[dev]->devc;
-
- /* DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE); */
-
- if (audio_devs[dev]->dmap_out->dma > 3)
- count >>= 1;
- count--;
-
- devc->irq_mode = IMODE_OUTPUT;
-
- spin_lock_irqsave(&devc->lock, flags);
- if (sb_dsp_command(devc, 0x14)) /* 8 bit DAC using DMA */
- {
- sb_dsp_command(devc, (unsigned char) (count & 0xff));
- sb_dsp_command(devc, (unsigned char) ((count >> 8) & 0xff));
- }
- else
- printk(KERN_WARNING "Sound Blaster: unable to start DAC.\n");
- spin_unlock_irqrestore(&devc->lock, flags);
- devc->intr_active = 1;
-}
-
-static void sb1_audio_start_input(int dev, unsigned long buf, int nr_bytes, int intrflag)
-{
- unsigned long flags;
- int count = nr_bytes;
- sb_devc *devc = audio_devs[dev]->devc;
-
- /*
- * Start a DMA input to the buffer pointed by dmaqtail
- */
-
- /* DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ); */
-
- if (audio_devs[dev]->dmap_out->dma > 3)
- count >>= 1;
- count--;
-
- devc->irq_mode = IMODE_INPUT;
-
- spin_lock_irqsave(&devc->lock, flags);
- if (sb_dsp_command(devc, 0x24)) /* 8 bit ADC using DMA */
- {
- sb_dsp_command(devc, (unsigned char) (count & 0xff));
- sb_dsp_command(devc, (unsigned char) ((count >> 8) & 0xff));
- }
- else
- printk(KERN_ERR "Sound Blaster: unable to start ADC.\n");
- spin_unlock_irqrestore(&devc->lock, flags);
-
- devc->intr_active = 1;
-}
-
-static void sb1_audio_trigger(int dev, int bits)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- bits &= devc->irq_mode;
-
- if (!bits)
- sb_dsp_command(devc, 0xd0); /* Halt DMA */
- else
- {
- switch (devc->irq_mode)
- {
- case IMODE_INPUT:
- sb1_audio_start_input(dev, devc->trg_buf, devc->trg_bytes,
- devc->trg_intrflag);
- break;
-
- case IMODE_OUTPUT:
- sb1_audio_output_block(dev, devc->trg_buf, devc->trg_bytes,
- devc->trg_intrflag);
- break;
- }
- }
- devc->trigger_bits = bits;
-}
-
-static int sb1_audio_prepare_for_input(int dev, int bsize, int bcount)
-{
- sb_devc *devc = audio_devs[dev]->devc;
- unsigned long flags;
-
- spin_lock_irqsave(&devc->lock, flags);
- if (sb_dsp_command(devc, 0x40))
- sb_dsp_command(devc, devc->tconst);
- sb_dsp_command(devc, DSP_CMD_SPKOFF);
- spin_unlock_irqrestore(&devc->lock, flags);
-
- devc->trigger_bits = 0;
- return 0;
-}
-
-static int sb1_audio_prepare_for_output(int dev, int bsize, int bcount)
-{
- sb_devc *devc = audio_devs[dev]->devc;
- unsigned long flags;
-
- spin_lock_irqsave(&devc->lock, flags);
- if (sb_dsp_command(devc, 0x40))
- sb_dsp_command(devc, devc->tconst);
- sb_dsp_command(devc, DSP_CMD_SPKON);
- spin_unlock_irqrestore(&devc->lock, flags);
- devc->trigger_bits = 0;
- return 0;
-}
-
-static int sb1_audio_set_speed(int dev, int speed)
-{
- int max_speed = 23000;
- sb_devc *devc = audio_devs[dev]->devc;
- int tmp;
-
- if (devc->opened & OPEN_READ)
- max_speed = 13000;
-
- if (speed > 0)
- {
- if (speed < 4000)
- speed = 4000;
-
- if (speed > max_speed)
- speed = max_speed;
-
- devc->tconst = (256 - ((1000000 + speed / 2) / speed)) & 0xff;
- tmp = 256 - devc->tconst;
- speed = (1000000 + tmp / 2) / tmp;
-
- devc->speed = speed;
- }
- return devc->speed;
-}
-
-static short sb1_audio_set_channels(int dev, short channels)
-{
- sb_devc *devc = audio_devs[dev]->devc;
- return devc->channels = 1;
-}
-
-static unsigned int sb1_audio_set_bits(int dev, unsigned int bits)
-{
- sb_devc *devc = audio_devs[dev]->devc;
- return devc->bits = 8;
-}
-
-static void sb1_audio_halt_xfer(int dev)
-{
- unsigned long flags;
- sb_devc *devc = audio_devs[dev]->devc;
-
- spin_lock_irqsave(&devc->lock, flags);
- sb_dsp_reset(devc);
- spin_unlock_irqrestore(&devc->lock, flags);
-}
-
-/*
- * SB 2.0 and SB 2.01 compatible routines
- */
-
-static void sb20_audio_output_block(int dev, unsigned long buf, int nr_bytes,
- int intrflag)
-{
- unsigned long flags;
- int count = nr_bytes;
- sb_devc *devc = audio_devs[dev]->devc;
- unsigned char cmd;
-
- /* DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE); */
-
- if (audio_devs[dev]->dmap_out->dma > 3)
- count >>= 1;
- count--;
-
- devc->irq_mode = IMODE_OUTPUT;
-
- spin_lock_irqsave(&devc->lock, flags);
- if (sb_dsp_command(devc, 0x48)) /* DSP Block size */
- {
- sb_dsp_command(devc, (unsigned char) (count & 0xff));
- sb_dsp_command(devc, (unsigned char) ((count >> 8) & 0xff));
-
- if (devc->speed * devc->channels <= 23000)
- cmd = 0x1c; /* 8 bit PCM output */
- else
- cmd = 0x90; /* 8 bit high speed PCM output (SB2.01/Pro) */
-
- if (!sb_dsp_command(devc, cmd))
- printk(KERN_ERR "Sound Blaster: unable to start DAC.\n");
- }
- else
- printk(KERN_ERR "Sound Blaster: unable to start DAC.\n");
- spin_unlock_irqrestore(&devc->lock, flags);
- devc->intr_active = 1;
-}
-
-static void sb20_audio_start_input(int dev, unsigned long buf, int nr_bytes, int intrflag)
-{
- unsigned long flags;
- int count = nr_bytes;
- sb_devc *devc = audio_devs[dev]->devc;
- unsigned char cmd;
-
- /*
- * Start a DMA input to the buffer pointed by dmaqtail
- */
-
- /* DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ); */
-
- if (audio_devs[dev]->dmap_out->dma > 3)
- count >>= 1;
- count--;
-
- devc->irq_mode = IMODE_INPUT;
-
- spin_lock_irqsave(&devc->lock, flags);
- if (sb_dsp_command(devc, 0x48)) /* DSP Block size */
- {
- sb_dsp_command(devc, (unsigned char) (count & 0xff));
- sb_dsp_command(devc, (unsigned char) ((count >> 8) & 0xff));
-
- if (devc->speed * devc->channels <= (devc->major == 3 ? 23000 : 13000))
- cmd = 0x2c; /* 8 bit PCM input */
- else
- cmd = 0x98; /* 8 bit high speed PCM input (SB2.01/Pro) */
-
- if (!sb_dsp_command(devc, cmd))
- printk(KERN_ERR "Sound Blaster: unable to start ADC.\n");
- }
- else
- printk(KERN_ERR "Sound Blaster: unable to start ADC.\n");
- spin_unlock_irqrestore(&devc->lock, flags);
- devc->intr_active = 1;
-}
-
-static void sb20_audio_trigger(int dev, int bits)
-{
- sb_devc *devc = audio_devs[dev]->devc;
- bits &= devc->irq_mode;
-
- if (!bits)
- sb_dsp_command(devc, 0xd0); /* Halt DMA */
- else
- {
- switch (devc->irq_mode)
- {
- case IMODE_INPUT:
- sb20_audio_start_input(dev, devc->trg_buf, devc->trg_bytes,
- devc->trg_intrflag);
- break;
-
- case IMODE_OUTPUT:
- sb20_audio_output_block(dev, devc->trg_buf, devc->trg_bytes,
- devc->trg_intrflag);
- break;
- }
- }
- devc->trigger_bits = bits;
-}
-
-/*
- * SB2.01 specific speed setup
- */
-
-static int sb201_audio_set_speed(int dev, int speed)
-{
- sb_devc *devc = audio_devs[dev]->devc;
- int tmp;
- int s = speed * devc->channels;
-
- if (speed > 0)
- {
- if (speed < 4000)
- speed = 4000;
- if (speed > 44100)
- speed = 44100;
- if (devc->opened & OPEN_READ && speed > 15000)
- speed = 15000;
- devc->tconst = (256 - ((1000000 + s / 2) / s)) & 0xff;
- tmp = 256 - devc->tconst;
- speed = ((1000000 + tmp / 2) / tmp) / devc->channels;
-
- devc->speed = speed;
- }
- return devc->speed;
-}
-
-/*
- * SB Pro specific routines
- */
-
-static int sbpro_audio_prepare_for_input(int dev, int bsize, int bcount)
-{ /* For SB Pro and Jazz16 */
- sb_devc *devc = audio_devs[dev]->devc;
- unsigned long flags;
- unsigned char bits = 0;
-
- if (devc->dma16 >= 0 && devc->dma16 != devc->dma8)
- audio_devs[dev]->dmap_out->dma = audio_devs[dev]->dmap_in->dma =
- devc->bits == 16 ? devc->dma16 : devc->dma8;
-
- if (devc->model == MDL_JAZZ || devc->model == MDL_SMW)
- if (devc->bits == AFMT_S16_LE)
- bits = 0x04; /* 16 bit mode */
-
- spin_lock_irqsave(&devc->lock, flags);
- if (sb_dsp_command(devc, 0x40))
- sb_dsp_command(devc, devc->tconst);
- sb_dsp_command(devc, DSP_CMD_SPKOFF);
- if (devc->channels == 1)
- sb_dsp_command(devc, 0xa0 | bits); /* Mono input */
- else
- sb_dsp_command(devc, 0xa8 | bits); /* Stereo input */
- spin_unlock_irqrestore(&devc->lock, flags);
-
- devc->trigger_bits = 0;
- return 0;
-}
-
-static int sbpro_audio_prepare_for_output(int dev, int bsize, int bcount)
-{ /* For SB Pro and Jazz16 */
- sb_devc *devc = audio_devs[dev]->devc;
- unsigned long flags;
- unsigned char tmp;
- unsigned char bits = 0;
-
- if (devc->dma16 >= 0 && devc->dma16 != devc->dma8)
- audio_devs[dev]->dmap_out->dma = audio_devs[dev]->dmap_in->dma = devc->bits == 16 ? devc->dma16 : devc->dma8;
- if (devc->model == MDL_SBPRO)
- sb_mixer_set_stereo(devc, devc->channels == 2);
-
- spin_lock_irqsave(&devc->lock, flags);
- if (sb_dsp_command(devc, 0x40))
- sb_dsp_command(devc, devc->tconst);
- sb_dsp_command(devc, DSP_CMD_SPKON);
-
- if (devc->model == MDL_JAZZ || devc->model == MDL_SMW)
- {
- if (devc->bits == AFMT_S16_LE)
- bits = 0x04; /* 16 bit mode */
-
- if (devc->channels == 1)
- sb_dsp_command(devc, 0xa0 | bits); /* Mono output */
- else
- sb_dsp_command(devc, 0xa8 | bits); /* Stereo output */
- spin_unlock_irqrestore(&devc->lock, flags);
- }
- else
- {
- spin_unlock_irqrestore(&devc->lock, flags);
- tmp = sb_getmixer(devc, 0x0e);
- if (devc->channels == 1)
- tmp &= ~0x02;
- else
- tmp |= 0x02;
- sb_setmixer(devc, 0x0e, tmp);
- }
- devc->trigger_bits = 0;
- return 0;
-}
-
-static int sbpro_audio_set_speed(int dev, int speed)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- if (speed > 0)
- {
- if (speed < 4000)
- speed = 4000;
- if (speed > 44100)
- speed = 44100;
- if (devc->channels > 1 && speed > 22050)
- speed = 22050;
- sb201_audio_set_speed(dev, speed);
- }
- return devc->speed;
-}
-
-static short sbpro_audio_set_channels(int dev, short channels)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- if (channels == 1 || channels == 2)
- {
- if (channels != devc->channels)
- {
- devc->channels = channels;
- if (devc->model == MDL_SBPRO && devc->channels == 2)
- sbpro_audio_set_speed(dev, devc->speed);
- }
- }
- return devc->channels;
-}
-
-static int jazz16_audio_set_speed(int dev, int speed)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- if (speed > 0)
- {
- int tmp;
- int s = speed * devc->channels;
-
- if (speed < 5000)
- speed = 5000;
- if (speed > 44100)
- speed = 44100;
-
- devc->tconst = (256 - ((1000000 + s / 2) / s)) & 0xff;
-
- tmp = 256 - devc->tconst;
- speed = ((1000000 + tmp / 2) / tmp) / devc->channels;
-
- devc->speed = speed;
- }
- return devc->speed;
-}
-
-/*
- * SB16 specific routines
- */
-
-static int sb16_audio_set_speed(int dev, int speed)
-{
- sb_devc *devc = audio_devs[dev]->devc;
- int max_speed = devc->submodel == SUBMDL_ALS100 ? 48000 : 44100;
-
- if (speed > 0)
- {
- if (speed < 5000)
- speed = 5000;
-
- if (speed > max_speed)
- speed = max_speed;
-
- devc->speed = speed;
- }
- return devc->speed;
-}
-
-static unsigned int sb16_audio_set_bits(int dev, unsigned int bits)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- if (bits != 0)
- {
- if (bits == AFMT_U8 || bits == AFMT_S16_LE)
- devc->bits = bits;
- else
- devc->bits = AFMT_U8;
- }
-
- return devc->bits;
-}
-
-static int sb16_audio_prepare_for_input(int dev, int bsize, int bcount)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- if (!devc->fullduplex)
- {
- audio_devs[dev]->dmap_out->dma =
- audio_devs[dev]->dmap_in->dma =
- devc->bits == AFMT_S16_LE ?
- devc->dma16 : devc->dma8;
- }
- else if (devc->bits == AFMT_S16_LE)
- {
- audio_devs[dev]->dmap_out->dma = devc->dma8;
- audio_devs[dev]->dmap_in->dma = devc->dma16;
- }
- else
- {
- audio_devs[dev]->dmap_out->dma = devc->dma16;
- audio_devs[dev]->dmap_in->dma = devc->dma8;
- }
-
- devc->trigger_bits = 0;
- return 0;
-}
-
-static int sb16_audio_prepare_for_output(int dev, int bsize, int bcount)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- if (!devc->fullduplex)
- {
- audio_devs[dev]->dmap_out->dma =
- audio_devs[dev]->dmap_in->dma =
- devc->bits == AFMT_S16_LE ?
- devc->dma16 : devc->dma8;
- }
- else if (devc->bits == AFMT_S16_LE)
- {
- audio_devs[dev]->dmap_out->dma = devc->dma8;
- audio_devs[dev]->dmap_in->dma = devc->dma16;
- }
- else
- {
- audio_devs[dev]->dmap_out->dma = devc->dma16;
- audio_devs[dev]->dmap_in->dma = devc->dma8;
- }
-
- devc->trigger_bits = 0;
- return 0;
-}
-
-static void sb16_audio_output_block(int dev, unsigned long buf, int count,
- int intrflag)
-{
- unsigned long flags, cnt;
- sb_devc *devc = audio_devs[dev]->devc;
- unsigned long bits;
-
- if (!devc->fullduplex || devc->bits == AFMT_S16_LE)
- {
- devc->irq_mode = IMODE_OUTPUT;
- devc->intr_active = 1;
- }
- else
- {
- devc->irq_mode_16 = IMODE_OUTPUT;
- devc->intr_active_16 = 1;
- }
-
- /* save value */
- spin_lock_irqsave(&devc->lock, flags);
- bits = devc->bits;
- if (devc->fullduplex)
- devc->bits = (devc->bits == AFMT_S16_LE) ?
- AFMT_U8 : AFMT_S16_LE;
- spin_unlock_irqrestore(&devc->lock, flags);
-
- cnt = count;
- if (devc->bits == AFMT_S16_LE)
- cnt >>= 1;
- cnt--;
-
- spin_lock_irqsave(&devc->lock, flags);
-
- /* DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE); */
-
- sb_dsp_command(devc, 0x41);
- sb_dsp_command(devc, (unsigned char) ((devc->speed >> 8) & 0xff));
- sb_dsp_command(devc, (unsigned char) (devc->speed & 0xff));
-
- sb_dsp_command(devc, (devc->bits == AFMT_S16_LE ? 0xb6 : 0xc6));
- sb_dsp_command(devc, ((devc->channels == 2 ? 0x20 : 0) +
- (devc->bits == AFMT_S16_LE ? 0x10 : 0)));
- sb_dsp_command(devc, (unsigned char) (cnt & 0xff));
- sb_dsp_command(devc, (unsigned char) (cnt >> 8));
-
- /* restore real value after all programming */
- devc->bits = bits;
- spin_unlock_irqrestore(&devc->lock, flags);
-}
-
-
-/*
- * This fails on the Cyrix MediaGX. If you don't have the DMA enabled
- * before the first sample arrives it locks up. However even if you
- * do enable the DMA in time you just get DMA timeouts and missing
- * interrupts and stuff, so for now I've not bothered fixing this either.
- */
-
-static void sb16_audio_start_input(int dev, unsigned long buf, int count, int intrflag)
-{
- unsigned long flags, cnt;
- sb_devc *devc = audio_devs[dev]->devc;
-
- if (!devc->fullduplex || devc->bits != AFMT_S16_LE)
- {
- devc->irq_mode = IMODE_INPUT;
- devc->intr_active = 1;
- }
- else
- {
- devc->irq_mode_16 = IMODE_INPUT;
- devc->intr_active_16 = 1;
- }
-
- cnt = count;
- if (devc->bits == AFMT_S16_LE)
- cnt >>= 1;
- cnt--;
-
- spin_lock_irqsave(&devc->lock, flags);
-
- /* DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ); */
-
- sb_dsp_command(devc, 0x42);
- sb_dsp_command(devc, (unsigned char) ((devc->speed >> 8) & 0xff));
- sb_dsp_command(devc, (unsigned char) (devc->speed & 0xff));
-
- sb_dsp_command(devc, (devc->bits == AFMT_S16_LE ? 0xbe : 0xce));
- sb_dsp_command(devc, ((devc->channels == 2 ? 0x20 : 0) +
- (devc->bits == AFMT_S16_LE ? 0x10 : 0)));
- sb_dsp_command(devc, (unsigned char) (cnt & 0xff));
- sb_dsp_command(devc, (unsigned char) (cnt >> 8));
-
- spin_unlock_irqrestore(&devc->lock, flags);
-}
-
-static void sb16_audio_trigger(int dev, int bits)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- int bits_16 = bits & devc->irq_mode_16;
- bits &= devc->irq_mode;
-
- if (!bits && !bits_16)
- sb_dsp_command(devc, 0xd0); /* Halt DMA */
- else
- {
- if (bits)
- {
- switch (devc->irq_mode)
- {
- case IMODE_INPUT:
- sb16_audio_start_input(dev,
- devc->trg_buf,
- devc->trg_bytes,
- devc->trg_intrflag);
- break;
-
- case IMODE_OUTPUT:
- sb16_audio_output_block(dev,
- devc->trg_buf,
- devc->trg_bytes,
- devc->trg_intrflag);
- break;
- }
- }
- if (bits_16)
- {
- switch (devc->irq_mode_16)
- {
- case IMODE_INPUT:
- sb16_audio_start_input(dev,
- devc->trg_buf_16,
- devc->trg_bytes_16,
- devc->trg_intrflag_16);
- break;
-
- case IMODE_OUTPUT:
- sb16_audio_output_block(dev,
- devc->trg_buf_16,
- devc->trg_bytes_16,
- devc->trg_intrflag_16);
- break;
- }
- }
- }
-
- devc->trigger_bits = bits | bits_16;
-}
-
-static unsigned char lbuf8[2048];
-static signed short *lbuf16 = (signed short *)lbuf8;
-#define LBUFCOPYSIZE 1024
-static void
-sb16_copy_from_user(int dev,
- char *localbuf, int localoffs,
- const char __user *userbuf, int useroffs,
- int max_in, int max_out,
- int *used, int *returned,
- int len)
-{
- sb_devc *devc = audio_devs[dev]->devc;
- int i, c, p, locallen;
- unsigned char *buf8;
- signed short *buf16;
-
- /* if not duplex no conversion */
- if (!devc->fullduplex)
- {
- if (copy_from_user(localbuf + localoffs,
- userbuf + useroffs, len))
- return;
- *used = len;
- *returned = len;
- }
- else if (devc->bits == AFMT_S16_LE)
- {
- /* 16 -> 8 */
- /* max_in >> 1, max number of samples in ( 16 bits ) */
- /* max_out, max number of samples out ( 8 bits ) */
- /* len, number of samples that will be taken ( 16 bits )*/
- /* c, count of samples remaining in buffer ( 16 bits )*/
- /* p, count of samples already processed ( 16 bits )*/
- len = ( (max_in >> 1) > max_out) ? max_out : (max_in >> 1);
- c = len;
- p = 0;
- buf8 = (unsigned char *)(localbuf + localoffs);
- while (c)
- {
- locallen = (c >= LBUFCOPYSIZE ? LBUFCOPYSIZE : c);
- /* << 1 in order to get 16 bit samples */
- if (copy_from_user(lbuf16,
- userbuf + useroffs + (p << 1),
- locallen << 1))
- return;
- for (i = 0; i < locallen; i++)
- {
- buf8[p+i] = ~((lbuf16[i] >> 8) & 0xff) ^ 0x80;
- }
- c -= locallen; p += locallen;
- }
- /* used = ( samples * 16 bits size ) */
- *used = max_in > ( max_out << 1) ? (max_out << 1) : max_in;
- /* returned = ( samples * 8 bits size ) */
- *returned = len;
- }
- else
- {
- /* 8 -> 16 */
- /* max_in, max number of samples in ( 8 bits ) */
- /* max_out >> 1, max number of samples out ( 16 bits ) */
- /* len, number of samples that will be taken ( 8 bits )*/
- /* c, count of samples remaining in buffer ( 8 bits )*/
- /* p, count of samples already processed ( 8 bits )*/
- len = max_in > (max_out >> 1) ? (max_out >> 1) : max_in;
- c = len;
- p = 0;
- buf16 = (signed short *)(localbuf + localoffs);
- while (c)
- {
- locallen = (c >= LBUFCOPYSIZE ? LBUFCOPYSIZE : c);
- if (copy_from_user(lbuf8,
- userbuf+useroffs + p,
- locallen))
- return;
- for (i = 0; i < locallen; i++)
- {
- buf16[p+i] = (~lbuf8[i] ^ 0x80) << 8;
- }
- c -= locallen; p += locallen;
- }
- /* used = ( samples * 8 bits size ) */
- *used = len;
- /* returned = ( samples * 16 bits size ) */
- *returned = len << 1;
- }
-}
-
-static void
-sb16_audio_mmap(int dev)
-{
- sb_devc *devc = audio_devs[dev]->devc;
- devc->fullduplex = 0;
-}
-
-static struct audio_driver sb1_audio_driver = /* SB1.x */
-{
- .owner = THIS_MODULE,
- .open = sb_audio_open,
- .close = sb_audio_close,
- .output_block = sb_set_output_parms,
- .start_input = sb_set_input_parms,
- .prepare_for_input = sb1_audio_prepare_for_input,
- .prepare_for_output = sb1_audio_prepare_for_output,
- .halt_io = sb1_audio_halt_xfer,
- .trigger = sb1_audio_trigger,
- .set_speed = sb1_audio_set_speed,
- .set_bits = sb1_audio_set_bits,
- .set_channels = sb1_audio_set_channels
-};
-
-static struct audio_driver sb20_audio_driver = /* SB2.0 */
-{
- .owner = THIS_MODULE,
- .open = sb_audio_open,
- .close = sb_audio_close,
- .output_block = sb_set_output_parms,
- .start_input = sb_set_input_parms,
- .prepare_for_input = sb1_audio_prepare_for_input,
- .prepare_for_output = sb1_audio_prepare_for_output,
- .halt_io = sb1_audio_halt_xfer,
- .trigger = sb20_audio_trigger,
- .set_speed = sb1_audio_set_speed,
- .set_bits = sb1_audio_set_bits,
- .set_channels = sb1_audio_set_channels
-};
-
-static struct audio_driver sb201_audio_driver = /* SB2.01 */
-{
- .owner = THIS_MODULE,
- .open = sb_audio_open,
- .close = sb_audio_close,
- .output_block = sb_set_output_parms,
- .start_input = sb_set_input_parms,
- .prepare_for_input = sb1_audio_prepare_for_input,
- .prepare_for_output = sb1_audio_prepare_for_output,
- .halt_io = sb1_audio_halt_xfer,
- .trigger = sb20_audio_trigger,
- .set_speed = sb201_audio_set_speed,
- .set_bits = sb1_audio_set_bits,
- .set_channels = sb1_audio_set_channels
-};
-
-static struct audio_driver sbpro_audio_driver = /* SB Pro */
-{
- .owner = THIS_MODULE,
- .open = sb_audio_open,
- .close = sb_audio_close,
- .output_block = sb_set_output_parms,
- .start_input = sb_set_input_parms,
- .prepare_for_input = sbpro_audio_prepare_for_input,
- .prepare_for_output = sbpro_audio_prepare_for_output,
- .halt_io = sb1_audio_halt_xfer,
- .trigger = sb20_audio_trigger,
- .set_speed = sbpro_audio_set_speed,
- .set_bits = sb1_audio_set_bits,
- .set_channels = sbpro_audio_set_channels
-};
-
-static struct audio_driver jazz16_audio_driver = /* Jazz16 and SM Wave */
-{
- .owner = THIS_MODULE,
- .open = sb_audio_open,
- .close = sb_audio_close,
- .output_block = sb_set_output_parms,
- .start_input = sb_set_input_parms,
- .prepare_for_input = sbpro_audio_prepare_for_input,
- .prepare_for_output = sbpro_audio_prepare_for_output,
- .halt_io = sb1_audio_halt_xfer,
- .trigger = sb20_audio_trigger,
- .set_speed = jazz16_audio_set_speed,
- .set_bits = sb16_audio_set_bits,
- .set_channels = sbpro_audio_set_channels
-};
-
-static struct audio_driver sb16_audio_driver = /* SB16 */
-{
- .owner = THIS_MODULE,
- .open = sb_audio_open,
- .close = sb_audio_close,
- .output_block = sb_set_output_parms,
- .start_input = sb_set_input_parms,
- .prepare_for_input = sb16_audio_prepare_for_input,
- .prepare_for_output = sb16_audio_prepare_for_output,
- .halt_io = sb1_audio_halt_xfer,
- .copy_user = sb16_copy_from_user,
- .trigger = sb16_audio_trigger,
- .set_speed = sb16_audio_set_speed,
- .set_bits = sb16_audio_set_bits,
- .set_channels = sbpro_audio_set_channels,
- .mmap = sb16_audio_mmap
-};
-
-void sb_audio_init(sb_devc * devc, char *name, struct module *owner)
-{
- int audio_flags = 0;
- int format_mask = AFMT_U8;
-
- struct audio_driver *driver = &sb1_audio_driver;
-
- switch (devc->model)
- {
- case MDL_SB1: /* SB1.0 or SB 1.5 */
- DDB(printk("Will use standard SB1.x driver\n"));
- audio_flags = DMA_HARDSTOP;
- break;
-
- case MDL_SB2:
- DDB(printk("Will use SB2.0 driver\n"));
- audio_flags = DMA_AUTOMODE;
- driver = &sb20_audio_driver;
- break;
-
- case MDL_SB201:
- DDB(printk("Will use SB2.01 (high speed) driver\n"));
- audio_flags = DMA_AUTOMODE;
- driver = &sb201_audio_driver;
- break;
-
- case MDL_JAZZ:
- case MDL_SMW:
- DDB(printk("Will use Jazz16 driver\n"));
- audio_flags = DMA_AUTOMODE;
- format_mask |= AFMT_S16_LE;
- driver = &jazz16_audio_driver;
- break;
-
- case MDL_ESS:
- DDB(printk("Will use ESS ES688/1688 driver\n"));
- driver = ess_audio_init (devc, &audio_flags, &format_mask);
- break;
-
- case MDL_SB16:
- DDB(printk("Will use SB16 driver\n"));
- audio_flags = DMA_AUTOMODE;
- format_mask |= AFMT_S16_LE;
- if (devc->dma8 != devc->dma16 && devc->dma16 != -1)
- {
- audio_flags |= DMA_DUPLEX;
- devc->duplex = 1;
- }
- driver = &sb16_audio_driver;
- break;
-
- default:
- DDB(printk("Will use SB Pro driver\n"));
- audio_flags = DMA_AUTOMODE;
- driver = &sbpro_audio_driver;
- }
-
- if (owner)
- driver->owner = owner;
-
- if ((devc->dev = sound_install_audiodrv(AUDIO_DRIVER_VERSION,
- name,driver, sizeof(struct audio_driver),
- audio_flags, format_mask, devc,
- devc->dma8,
- devc->duplex ? devc->dma16 : devc->dma8)) < 0)
- {
- printk(KERN_ERR "Sound Blaster: unable to install audio.\n");
- return;
- }
- audio_devs[devc->dev]->mixer_dev = devc->my_mixerdev;
- audio_devs[devc->dev]->min_fragment = 5;
-}
diff --git a/ANDROID_3.4.5/sound/oss/sb_card.c b/ANDROID_3.4.5/sound/oss/sb_card.c
deleted file mode 100644
index fb5d7250..00000000
--- a/ANDROID_3.4.5/sound/oss/sb_card.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * sound/oss/sb_card.c
- *
- * Detection routine for the ISA Sound Blaster and compatible sound
- * cards.
- *
- * This file is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this
- * software for more info.
- *
- * This is a complete rewrite of the detection routines. This was
- * prompted by the PnP API change during v2.5 and the ugly state the
- * code was in.
- *
- * Copyright (C) by Paul Laufer 2002. Based on code originally by
- * Hannu Savolainen which was modified by many others over the
- * years. Authors specifically mentioned in the previous version were:
- * Daniel Stone, Alessandro Zummo, Jeff Garzik, Arnaldo Carvalho de
- * Melo, Daniel Church, and myself.
- *
- * 02-05-2003 Original Release, Paul Laufer <paul@laufernet.com>
- * 02-07-2003 Bug made it into first release. Take two.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include "sound_config.h"
-#include "sb_mixer.h"
-#include "sb.h"
-#ifdef CONFIG_PNP
-#include <linux/pnp.h>
-#endif /* CONFIG_PNP */
-#include "sb_card.h"
-
-MODULE_DESCRIPTION("OSS Soundblaster ISA PnP and legacy sound driver");
-MODULE_LICENSE("GPL");
-
-extern void *smw_free;
-
-static int __initdata mpu_io = 0;
-static int __initdata io = -1;
-static int __initdata irq = -1;
-static int __initdata dma = -1;
-static int __initdata dma16 = -1;
-static int __initdata type = 0; /* Can set this to a specific card type */
-static int __initdata esstype = 0; /* ESS chip type */
-static int __initdata acer = 0; /* Do acer notebook init? */
-static int __initdata sm_games = 0; /* Logitech soundman games? */
-
-static struct sb_card_config *legacy = NULL;
-
-#ifdef CONFIG_PNP
-static int pnp_registered;
-static int __initdata pnp = 1;
-/*
-static int __initdata uart401 = 0;
-*/
-#else
-static int __initdata pnp = 0;
-#endif
-
-module_param(io, int, 000);
-MODULE_PARM_DESC(io, "Soundblaster i/o base address (0x220,0x240,0x260,0x280)");
-module_param(irq, int, 000);
-MODULE_PARM_DESC(irq, "IRQ (5,7,9,10)");
-module_param(dma, int, 000);
-MODULE_PARM_DESC(dma, "8-bit DMA channel (0,1,3)");
-module_param(dma16, int, 000);
-MODULE_PARM_DESC(dma16, "16-bit DMA channel (5,6,7)");
-module_param(mpu_io, int, 000);
-MODULE_PARM_DESC(mpu_io, "MPU base address");
-module_param(type, int, 000);
-MODULE_PARM_DESC(type, "You can set this to specific card type (doesn't " \
- "work with pnp)");
-module_param(sm_games, int, 000);
-MODULE_PARM_DESC(sm_games, "Enable support for Logitech soundman games " \
- "(doesn't work with pnp)");
-module_param(esstype, int, 000);
-MODULE_PARM_DESC(esstype, "ESS chip type (doesn't work with pnp)");
-module_param(acer, int, 000);
-MODULE_PARM_DESC(acer, "Set this to detect cards in some ACER notebooks "\
- "(doesn't work with pnp)");
-
-#ifdef CONFIG_PNP
-module_param(pnp, int, 000);
-MODULE_PARM_DESC(pnp, "Went set to 0 will disable detection using PnP. "\
- "Default is 1.\n");
-/* Not done yet.... */
-/*
-module_param(uart401, int, 000);
-MODULE_PARM_DESC(uart401, "When set to 1, will attempt to detect and enable"\
- "the mpu on some clones");
-*/
-#endif /* CONFIG_PNP */
-
-/* OSS subsystem card registration shared by PnP and legacy routines */
-static int sb_register_oss(struct sb_card_config *scc, struct sb_module_options *sbmo)
-{
- if (!request_region(scc->conf.io_base, 16, "soundblaster")) {
- printk(KERN_ERR "sb: ports busy.\n");
- kfree(scc);
- return -EBUSY;
- }
-
- if (!sb_dsp_detect(&scc->conf, 0, 0, sbmo)) {
- release_region(scc->conf.io_base, 16);
- printk(KERN_ERR "sb: Failed DSP Detect.\n");
- kfree(scc);
- return -ENODEV;
- }
- if(!sb_dsp_init(&scc->conf, THIS_MODULE)) {
- printk(KERN_ERR "sb: Failed DSP init.\n");
- kfree(scc);
- return -ENODEV;
- }
- if(scc->mpucnf.io_base > 0) {
- scc->mpu = 1;
- printk(KERN_INFO "sb: Turning on MPU\n");
- if(!probe_sbmpu(&scc->mpucnf, THIS_MODULE))
- scc->mpu = 0;
- }
-
- return 1;
-}
-
-static void sb_unload(struct sb_card_config *scc)
-{
- sb_dsp_unload(&scc->conf, 0);
- if(scc->mpu)
- unload_sbmpu(&scc->mpucnf);
- kfree(scc);
-}
-
-/* Register legacy card with OSS subsystem */
-static int __init sb_init_legacy(void)
-{
- struct sb_module_options sbmo = {0};
-
- if((legacy = kzalloc(sizeof(struct sb_card_config), GFP_KERNEL)) == NULL) {
- printk(KERN_ERR "sb: Error: Could not allocate memory\n");
- return -ENOMEM;
- }
-
- legacy->conf.io_base = io;
- legacy->conf.irq = irq;
- legacy->conf.dma = dma;
- legacy->conf.dma2 = dma16;
- legacy->conf.card_subtype = type;
-
- legacy->mpucnf.io_base = mpu_io;
- legacy->mpucnf.irq = -1;
- legacy->mpucnf.dma = -1;
- legacy->mpucnf.dma2 = -1;
-
- sbmo.esstype = esstype;
- sbmo.sm_games = sm_games;
- sbmo.acer = acer;
-
- return sb_register_oss(legacy, &sbmo);
-}
-
-#ifdef CONFIG_PNP
-
-/* Populate the OSS subsystem structures with information from PnP */
-static void sb_dev2cfg(struct pnp_dev *dev, struct sb_card_config *scc)
-{
- scc->conf.io_base = -1;
- scc->conf.irq = -1;
- scc->conf.dma = -1;
- scc->conf.dma2 = -1;
- scc->mpucnf.io_base = -1;
- scc->mpucnf.irq = -1;
- scc->mpucnf.dma = -1;
- scc->mpucnf.dma2 = -1;
-
- /* All clones layout their PnP tables differently and some use
- different logical devices for the MPU */
- if(!strncmp("CTL",scc->card_id,3)) {
- scc->conf.io_base = pnp_port_start(dev,0);
- scc->conf.irq = pnp_irq(dev,0);
- scc->conf.dma = pnp_dma(dev,0);
- scc->conf.dma2 = pnp_dma(dev,1);
- scc->mpucnf.io_base = pnp_port_start(dev,1);
- return;
- }
- if(!strncmp("tBA",scc->card_id,3)) {
- scc->conf.io_base = pnp_port_start(dev,0);
- scc->conf.irq = pnp_irq(dev,0);
- scc->conf.dma = pnp_dma(dev,0);
- scc->conf.dma2 = pnp_dma(dev,1);
- return;
- }
- if(!strncmp("ESS",scc->card_id,3)) {
- scc->conf.io_base = pnp_port_start(dev,0);
- scc->conf.irq = pnp_irq(dev,0);
- scc->conf.dma = pnp_dma(dev,0);
- scc->conf.dma2 = pnp_dma(dev,1);
- scc->mpucnf.io_base = pnp_port_start(dev,2);
- return;
- }
- if(!strncmp("CMI",scc->card_id,3)) {
- scc->conf.io_base = pnp_port_start(dev,0);
- scc->conf.irq = pnp_irq(dev,0);
- scc->conf.dma = pnp_dma(dev,0);
- scc->conf.dma2 = pnp_dma(dev,1);
- return;
- }
- if(!strncmp("RWB",scc->card_id,3)) {
- scc->conf.io_base = pnp_port_start(dev,0);
- scc->conf.irq = pnp_irq(dev,0);
- scc->conf.dma = pnp_dma(dev,0);
- return;
- }
- if(!strncmp("ALS",scc->card_id,3)) {
- if(!strncmp("ALS0007",scc->card_id,7)) {
- scc->conf.io_base = pnp_port_start(dev,0);
- scc->conf.irq = pnp_irq(dev,0);
- scc->conf.dma = pnp_dma(dev,0);
- } else {
- scc->conf.io_base = pnp_port_start(dev,0);
- scc->conf.irq = pnp_irq(dev,0);
- scc->conf.dma = pnp_dma(dev,1);
- scc->conf.dma2 = pnp_dma(dev,0);
- }
- return;
- }
- if(!strncmp("RTL",scc->card_id,3)) {
- scc->conf.io_base = pnp_port_start(dev,0);
- scc->conf.irq = pnp_irq(dev,0);
- scc->conf.dma = pnp_dma(dev,1);
- scc->conf.dma2 = pnp_dma(dev,0);
- }
-}
-
-static unsigned int sb_pnp_devices;
-
-/* Probe callback function for the PnP API */
-static int sb_pnp_probe(struct pnp_card_link *card, const struct pnp_card_device_id *card_id)
-{
- struct sb_card_config *scc;
- struct sb_module_options sbmo = {0}; /* Default to 0 for PnP */
- struct pnp_dev *dev = pnp_request_card_device(card, card_id->devs[0].id, NULL);
-
- if(!dev){
- return -EBUSY;
- }
-
- if((scc = kzalloc(sizeof(struct sb_card_config), GFP_KERNEL)) == NULL) {
- printk(KERN_ERR "sb: Error: Could not allocate memory\n");
- return -ENOMEM;
- }
-
- printk(KERN_INFO "sb: PnP: Found Card Named = \"%s\", Card PnP id = " \
- "%s, Device PnP id = %s\n", card->card->name, card_id->id,
- dev->id->id);
-
- scc->card_id = card_id->id;
- scc->dev_id = dev->id->id;
- sb_dev2cfg(dev, scc);
-
- printk(KERN_INFO "sb: PnP: Detected at: io=0x%x, irq=%d, " \
- "dma=%d, dma16=%d\n", scc->conf.io_base, scc->conf.irq,
- scc->conf.dma, scc->conf.dma2);
-
- pnp_set_card_drvdata(card, scc);
- sb_pnp_devices++;
-
- return sb_register_oss(scc, &sbmo);
-}
-
-static void sb_pnp_remove(struct pnp_card_link *card)
-{
- struct sb_card_config *scc = pnp_get_card_drvdata(card);
-
- if(!scc)
- return;
-
- printk(KERN_INFO "sb: PnP: Removing %s\n", scc->card_id);
-
- sb_unload(scc);
-}
-
-static struct pnp_card_driver sb_pnp_driver = {
- .name = "OSS SndBlstr", /* 16 character limit */
- .id_table = sb_pnp_card_table,
- .probe = sb_pnp_probe,
- .remove = sb_pnp_remove,
-};
-MODULE_DEVICE_TABLE(pnp_card, sb_pnp_card_table);
-#endif /* CONFIG_PNP */
-
-static void sb_unregister_all(void)
-{
-#ifdef CONFIG_PNP
- if (pnp_registered)
- pnp_unregister_card_driver(&sb_pnp_driver);
-#endif
-}
-
-static int __init sb_init(void)
-{
- int lres = 0;
- int pres = 0;
-
- printk(KERN_INFO "sb: Init: Starting Probe...\n");
-
- if(io != -1 && irq != -1 && dma != -1) {
- printk(KERN_INFO "sb: Probing legacy card with io=%x, "\
- "irq=%d, dma=%d, dma16=%d\n",io, irq, dma, dma16);
- lres = sb_init_legacy();
- } else if((io != -1 || irq != -1 || dma != -1) ||
- (!pnp && (io == -1 && irq == -1 && dma == -1)))
- printk(KERN_ERR "sb: Error: At least io, irq, and dma "\
- "must be set for legacy cards.\n");
-
-#ifdef CONFIG_PNP
- if(pnp) {
- int err = pnp_register_card_driver(&sb_pnp_driver);
- if (!err)
- pnp_registered = 1;
- pres = sb_pnp_devices;
- }
-#endif
- printk(KERN_INFO "sb: Init: Done\n");
-
- /* If either PnP or Legacy registered a card then return
- * success */
- if (pres == 0 && lres <= 0) {
- sb_unregister_all();
- return -ENODEV;
- }
- return 0;
-}
-
-static void __exit sb_exit(void)
-{
- printk(KERN_INFO "sb: Unloading...\n");
-
- /* Unload legacy card */
- if (legacy) {
- printk (KERN_INFO "sb: Unloading legacy card\n");
- sb_unload(legacy);
- }
-
- sb_unregister_all();
-
- vfree(smw_free);
- smw_free = NULL;
-}
-
-module_init(sb_init);
-module_exit(sb_exit);
diff --git a/ANDROID_3.4.5/sound/oss/sb_card.h b/ANDROID_3.4.5/sound/oss/sb_card.h
deleted file mode 100644
index 5535cff8..00000000
--- a/ANDROID_3.4.5/sound/oss/sb_card.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * sound/oss/sb_card.h
- *
- * This file is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this
- * software for more info.
- *
- * 02-05-2002 Original Release, Paul Laufer <paul@laufernet.com>
- */
-
-struct sb_card_config {
- struct address_info conf;
- struct address_info mpucnf;
- const char *card_id;
- const char *dev_id;
- int mpu;
-};
-
-#ifdef CONFIG_PNP
-
-/*
- * SoundBlaster PnP tables and structures.
- */
-
-/* Card PnP ID Table */
-static struct pnp_card_device_id sb_pnp_card_table[] = {
- /* Sound Blaster 16 */
- {.id = "CTL0024", .driver_data = 0, .devs = { {.id="CTL0031"}, } },
- /* Sound Blaster 16 */
- {.id = "CTL0025", .driver_data = 0, .devs = { {.id="CTL0031"}, } },
- /* Sound Blaster 16 */
- {.id = "CTL0026", .driver_data = 0, .devs = { {.id="CTL0031"}, } },
- /* Sound Blaster 16 */
- {.id = "CTL0027", .driver_data = 0, .devs = { {.id="CTL0031"}, } },
- /* Sound Blaster 16 */
- {.id = "CTL0028", .driver_data = 0, .devs = { {.id="CTL0031"}, } },
- /* Sound Blaster 16 */
- {.id = "CTL0029", .driver_data = 0, .devs = { {.id="CTL0031"}, } },
- /* Sound Blaster 16 */
- {.id = "CTL002a", .driver_data = 0, .devs = { {.id="CTL0031"}, } },
- /* Sound Blaster 16 */
- {.id = "CTL002b", .driver_data = 0, .devs = { {.id="CTL0031"}, } },
- /* Sound Blaster 16 */
- {.id = "CTL002c", .driver_data = 0, .devs = { {.id="CTL0031"}, } },
- /* Sound Blaster 16 */
- {.id = "CTL00ed", .driver_data = 0, .devs = { {.id="CTL0041"}, } },
- /* Sound Blaster 16 */
- {.id = "CTL0086", .driver_data = 0, .devs = { {.id="CTL0041"}, } },
- /* Sound Blaster Vibra16S */
- {.id = "CTL0051", .driver_data = 0, .devs = { {.id="CTL0001"}, } },
- /* Sound Blaster Vibra16C */
- {.id = "CTL0070", .driver_data = 0, .devs = { {.id="CTL0001"}, } },
- /* Sound Blaster Vibra16CL */
- {.id = "CTL0080", .driver_data = 0, .devs = { {.id="CTL0041"}, } },
- /* Sound Blaster Vibra16CL */
- {.id = "CTL00F0", .driver_data = 0, .devs = { {.id="CTL0043"}, } },
- /* Sound Blaster AWE 32 */
- {.id = "CTL0039", .driver_data = 0, .devs = { {.id="CTL0031"}, } },
- /* Sound Blaster AWE 32 */
- {.id = "CTL0042", .driver_data = 0, .devs = { {.id="CTL0031"}, } },
- /* Sound Blaster AWE 32 */
- {.id = "CTL0043", .driver_data = 0, .devs = { {.id="CTL0031"}, } },
- /* Sound Blaster AWE 32 */
- {.id = "CTL0044", .driver_data = 0, .devs = { {.id="CTL0031"}, } },
- /* Sound Blaster AWE 32 */
- {.id = "CTL0045", .driver_data = 0, .devs = { {.id="CTL0031"}, } },
- /* Sound Blaster AWE 32 */
- {.id = "CTL0046", .driver_data = 0, .devs = { {.id="CTL0031"}, } },
- /* Sound Blaster AWE 32 */
- {.id = "CTL0047", .driver_data = 0, .devs = { {.id="CTL0031"}, } },
- /* Sound Blaster AWE 32 */
- {.id = "CTL0048", .driver_data = 0, .devs = { {.id="CTL0031"}, } },
- /* Sound Blaster AWE 32 */
- {.id = "CTL0054", .driver_data = 0, .devs = { {.id="CTL0031"}, } },
- /* Sound Blaster AWE 32 */
- {.id = "CTL009C", .driver_data = 0, .devs = { {.id="CTL0041"}, } },
- /* Createive SB32 PnP */
- {.id = "CTL009F", .driver_data = 0, .devs = { {.id="CTL0041"}, } },
- /* Sound Blaster AWE 64 */
- {.id = "CTL009D", .driver_data = 0, .devs = { {.id="CTL0042"}, } },
- /* Sound Blaster AWE 64 Gold */
- {.id = "CTL009E", .driver_data = 0, .devs = { {.id="CTL0044"}, } },
- /* Sound Blaster AWE 64 Gold */
- {.id = "CTL00B2", .driver_data = 0, .devs = { {.id="CTL0044"}, } },
- /* Sound Blaster AWE 64 */
- {.id = "CTL00C1", .driver_data = 0, .devs = { {.id="CTL0042"}, } },
- /* Sound Blaster AWE 64 */
- {.id = "CTL00C3", .driver_data = 0, .devs = { {.id="CTL0045"}, } },
- /* Sound Blaster AWE 64 */
- {.id = "CTL00C5", .driver_data = 0, .devs = { {.id="CTL0045"}, } },
- /* Sound Blaster AWE 64 */
- {.id = "CTL00C7", .driver_data = 0, .devs = { {.id="CTL0045"}, } },
- /* Sound Blaster AWE 64 */
- {.id = "CTL00E4", .driver_data = 0, .devs = { {.id="CTL0045"}, } },
- /* Sound Blaster AWE 64 */
- {.id = "CTL00E9", .driver_data = 0, .devs = { {.id="CTL0045"}, } },
- /* ESS 1868 */
- {.id = "ESS0968", .driver_data = 0, .devs = { {.id="ESS0968"}, } },
- /* ESS 1868 */
- {.id = "ESS1868", .driver_data = 0, .devs = { {.id="ESS1868"}, } },
- /* ESS 1868 */
- {.id = "ESS1868", .driver_data = 0, .devs = { {.id="ESS8611"}, } },
- /* ESS 1869 PnP AudioDrive */
- {.id = "ESS0003", .driver_data = 0, .devs = { {.id="ESS1869"}, } },
- /* ESS 1869 */
- {.id = "ESS1869", .driver_data = 0, .devs = { {.id="ESS1869"}, } },
- /* ESS 1878 */
- {.id = "ESS1878", .driver_data = 0, .devs = { {.id="ESS1878"}, } },
- /* ESS 1879 */
- {.id = "ESS1879", .driver_data = 0, .devs = { {.id="ESS1879"}, } },
- /* CMI 8330 SoundPRO */
- {.id = "CMI0001", .driver_data = 0, .devs = { {.id="@X@0001"},
- {.id="@H@0001"},
- {.id="@@@0001"}, } },
- /* Diamond DT0197H */
- {.id = "RWR1688", .driver_data = 0, .devs = { {.id="@@@0001"},
- {.id="@X@0001"},
- {.id="@H@0001"}, } },
- /* ALS007 */
- {.id = "ALS0007", .driver_data = 0, .devs = { {.id="@@@0001"},
- {.id="@X@0001"},
- {.id="@H@0001"}, } },
- /* ALS100 */
- {.id = "ALS0001", .driver_data = 0, .devs = { {.id="@@@0001"},
- {.id="@X@0001"},
- {.id="@H@0001"}, } },
- /* ALS110 */
- {.id = "ALS0110", .driver_data = 0, .devs = { {.id="@@@1001"},
- {.id="@X@1001"},
- {.id="@H@0001"}, } },
- /* ALS120 */
- {.id = "ALS0120", .driver_data = 0, .devs = { {.id="@@@2001"},
- {.id="@X@2001"},
- {.id="@H@0001"}, } },
- /* ALS200 */
- {.id = "ALS0200", .driver_data = 0, .devs = { {.id="@@@0020"},
- {.id="@X@0030"},
- {.id="@H@0001"}, } },
- /* ALS200 */
- {.id = "RTL3000", .driver_data = 0, .devs = { {.id="@@@2001"},
- {.id="@X@2001"},
- {.id="@H@0001"}, } },
- /* Sound Blaster 16 (Virtual PC 2004) */
- {.id = "tBA03b0", .driver_data = 0, .devs = { {.id="PNPb003"}, } },
- /* -end- */
- {.id = "", }
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/oss/sb_common.c b/ANDROID_3.4.5/sound/oss/sb_common.c
deleted file mode 100644
index 7d42c541..00000000
--- a/ANDROID_3.4.5/sound/oss/sb_common.c
+++ /dev/null
@@ -1,1292 +0,0 @@
-/*
- * sound/oss/sb_common.c
- *
- * Common routines for Sound Blaster compatible cards.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- *
- * Daniel J. Rodriksson: Modified sbintr to handle 8 and 16 bit interrupts
- * for full duplex support ( only sb16 by now )
- * Rolf Fokkens: Added (BETA?) support for ES1887 chips.
- * (fokkensr@vertis.nl) Which means: You can adjust the recording levels.
- *
- * 2000/01/18 - separated sb_card and sb_common -
- * Jeff Garzik <jgarzik@pobox.com>
- *
- * 2000/09/18 - got rid of attach_uart401
- * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- *
- * 2001/01/26 - replaced CLI/STI with spinlocks
- * Chris Rankin <rankinc@zipworld.com.au>
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-
-#include "sound_config.h"
-#include "sound_firmware.h"
-
-#include "mpu401.h"
-
-#include "sb_mixer.h"
-#include "sb.h"
-#include "sb_ess.h"
-
-/*
- * global module flag
- */
-
-int sb_be_quiet;
-
-static sb_devc *detected_devc; /* For communication from probe to init */
-static sb_devc *last_devc; /* For MPU401 initialization */
-
-static unsigned char jazz_irq_bits[] = {
- 0, 0, 2, 3, 0, 1, 0, 4, 0, 2, 5, 0, 0, 0, 0, 6
-};
-
-static unsigned char jazz_dma_bits[] = {
- 0, 1, 0, 2, 0, 3, 0, 4
-};
-
-void *smw_free;
-
-/*
- * Jazz16 chipset specific control variables
- */
-
-static int jazz16_base; /* Not detected */
-static unsigned char jazz16_bits; /* I/O relocation bits */
-static DEFINE_SPINLOCK(jazz16_lock);
-
-/*
- * Logitech Soundman Wave specific initialization code
- */
-
-#ifdef SMW_MIDI0001_INCLUDED
-#include "smw-midi0001.h"
-#else
-static unsigned char *smw_ucode;
-static int smw_ucodeLen;
-
-#endif
-
-static sb_devc *last_sb; /* Last sb loaded */
-
-int sb_dsp_command(sb_devc * devc, unsigned char val)
-{
- int i;
- unsigned long limit;
-
- limit = jiffies + HZ / 10; /* Timeout */
-
- /*
- * Note! the i<500000 is an emergency exit. The sb_dsp_command() is sometimes
- * called while interrupts are disabled. This means that the timer is
- * disabled also. However the timeout situation is a abnormal condition.
- * Normally the DSP should be ready to accept commands after just couple of
- * loops.
- */
-
- for (i = 0; i < 500000 && (limit-jiffies)>0; i++)
- {
- if ((inb(DSP_STATUS) & 0x80) == 0)
- {
- outb((val), DSP_COMMAND);
- return 1;
- }
- }
- printk(KERN_WARNING "Sound Blaster: DSP command(%x) timeout.\n", val);
- return 0;
-}
-
-int sb_dsp_get_byte(sb_devc * devc)
-{
- int i;
-
- for (i = 1000; i; i--)
- {
- if (inb(DSP_DATA_AVAIL) & 0x80)
- return inb(DSP_READ);
- }
- return 0xffff;
-}
-
-static void sb_intr (sb_devc *devc)
-{
- int status;
- unsigned char src = 0xff;
-
- if (devc->model == MDL_SB16)
- {
- src = sb_getmixer(devc, IRQ_STAT); /* Interrupt source register */
-
- if (src & 4) /* MPU401 interrupt */
- if(devc->midi_irq_cookie)
- uart401intr(devc->irq, devc->midi_irq_cookie);
-
- if (!(src & 3))
- return; /* Not a DSP interrupt */
- }
- if (devc->intr_active && (!devc->fullduplex || (src & 0x01)))
- {
- switch (devc->irq_mode)
- {
- case IMODE_OUTPUT:
- DMAbuf_outputintr(devc->dev, 1);
- break;
-
- case IMODE_INPUT:
- DMAbuf_inputintr(devc->dev);
- break;
-
- case IMODE_INIT:
- break;
-
- case IMODE_MIDI:
- sb_midi_interrupt(devc);
- break;
-
- default:
- /* printk(KERN_WARNING "Sound Blaster: Unexpected interrupt\n"); */
- ;
- }
- }
- else if (devc->intr_active_16 && (src & 0x02))
- {
- switch (devc->irq_mode_16)
- {
- case IMODE_OUTPUT:
- DMAbuf_outputintr(devc->dev, 1);
- break;
-
- case IMODE_INPUT:
- DMAbuf_inputintr(devc->dev);
- break;
-
- case IMODE_INIT:
- break;
-
- default:
- /* printk(KERN_WARNING "Sound Blaster: Unexpected interrupt\n"); */
- ;
- }
- }
- /*
- * Acknowledge interrupts
- */
-
- if (src & 0x01)
- status = inb(DSP_DATA_AVAIL);
-
- if (devc->model == MDL_SB16 && src & 0x02)
- status = inb(DSP_DATA_AVL16);
-}
-
-static void pci_intr(sb_devc *devc)
-{
- int src = inb(devc->pcibase+0x1A);
- src&=3;
- if(src)
- sb_intr(devc);
-}
-
-static irqreturn_t sbintr(int irq, void *dev_id)
-{
- sb_devc *devc = dev_id;
-
- devc->irq_ok = 1;
-
- switch (devc->model) {
- case MDL_ESSPCI:
- pci_intr (devc);
- break;
-
- case MDL_ESS:
- ess_intr (devc);
- break;
- default:
- sb_intr (devc);
- break;
- }
- return IRQ_HANDLED;
-}
-
-int sb_dsp_reset(sb_devc * devc)
-{
- int loopc;
-
- DEB(printk("Entered sb_dsp_reset()\n"));
-
- if (devc->model == MDL_ESS) return ess_dsp_reset (devc);
-
- /* This is only for non-ESS chips */
-
- outb(1, DSP_RESET);
-
- udelay(10);
- outb(0, DSP_RESET);
- udelay(30);
-
- for (loopc = 0; loopc < 1000 && !(inb(DSP_DATA_AVAIL) & 0x80); loopc++);
-
- if (inb(DSP_READ) != 0xAA)
- {
- DDB(printk("sb: No response to RESET\n"));
- return 0; /* Sorry */
- }
-
- DEB(printk("sb_dsp_reset() OK\n"));
-
- return 1;
-}
-
-static void dsp_get_vers(sb_devc * devc)
-{
- int i;
-
- unsigned long flags;
-
- DDB(printk("Entered dsp_get_vers()\n"));
- spin_lock_irqsave(&devc->lock, flags);
- devc->major = devc->minor = 0;
- sb_dsp_command(devc, 0xe1); /* Get version */
-
- for (i = 100000; i; i--)
- {
- if (inb(DSP_DATA_AVAIL) & 0x80)
- {
- if (devc->major == 0)
- devc->major = inb(DSP_READ);
- else
- {
- devc->minor = inb(DSP_READ);
- break;
- }
- }
- }
- spin_unlock_irqrestore(&devc->lock, flags);
- DDB(printk("DSP version %d.%02d\n", devc->major, devc->minor));
-}
-
-static int sb16_set_dma_hw(sb_devc * devc)
-{
- int bits;
-
- if (devc->dma8 != 0 && devc->dma8 != 1 && devc->dma8 != 3)
- {
- printk(KERN_ERR "SB16: Invalid 8 bit DMA (%d)\n", devc->dma8);
- return 0;
- }
- bits = (1 << devc->dma8);
-
- if (devc->dma16 >= 5 && devc->dma16 <= 7)
- bits |= (1 << devc->dma16);
-
- sb_setmixer(devc, DMA_NR, bits);
- return 1;
-}
-
-static void sb16_set_mpu_port(sb_devc * devc, struct address_info *hw_config)
-{
- /*
- * This routine initializes new MIDI port setup register of SB Vibra (CT2502).
- */
- unsigned char bits = sb_getmixer(devc, 0x84) & ~0x06;
-
- switch (hw_config->io_base)
- {
- case 0x300:
- sb_setmixer(devc, 0x84, bits | 0x04);
- break;
-
- case 0x330:
- sb_setmixer(devc, 0x84, bits | 0x00);
- break;
-
- default:
- sb_setmixer(devc, 0x84, bits | 0x02); /* Disable MPU */
- printk(KERN_ERR "SB16: Invalid MIDI I/O port %x\n", hw_config->io_base);
- }
-}
-
-static int sb16_set_irq_hw(sb_devc * devc, int level)
-{
- int ival;
-
- switch (level)
- {
- case 5:
- ival = 2;
- break;
- case 7:
- ival = 4;
- break;
- case 9:
- ival = 1;
- break;
- case 10:
- ival = 8;
- break;
- default:
- printk(KERN_ERR "SB16: Invalid IRQ%d\n", level);
- return 0;
- }
- sb_setmixer(devc, IRQ_NR, ival);
- return 1;
-}
-
-static void relocate_Jazz16(sb_devc * devc, struct address_info *hw_config)
-{
- unsigned char bits = 0;
- unsigned long flags;
-
- if (jazz16_base != 0 && jazz16_base != hw_config->io_base)
- return;
-
- switch (hw_config->io_base)
- {
- case 0x220:
- bits = 1;
- break;
- case 0x240:
- bits = 2;
- break;
- case 0x260:
- bits = 3;
- break;
- default:
- return;
- }
- bits = jazz16_bits = bits << 5;
- jazz16_base = hw_config->io_base;
-
- /*
- * Magic wake up sequence by writing to 0x201 (aka Joystick port)
- */
- spin_lock_irqsave(&jazz16_lock, flags);
- outb((0xAF), 0x201);
- outb((0x50), 0x201);
- outb((bits), 0x201);
- spin_unlock_irqrestore(&jazz16_lock, flags);
-}
-
-static int init_Jazz16(sb_devc * devc, struct address_info *hw_config)
-{
- char name[100];
- /*
- * First try to check that the card has Jazz16 chip. It identifies itself
- * by returning 0x12 as response to DSP command 0xfa.
- */
-
- if (!sb_dsp_command(devc, 0xfa))
- return 0;
-
- if (sb_dsp_get_byte(devc) != 0x12)
- return 0;
-
- /*
- * OK so far. Now configure the IRQ and DMA channel used by the card.
- */
- if (hw_config->irq < 1 || hw_config->irq > 15 || jazz_irq_bits[hw_config->irq] == 0)
- {
- printk(KERN_ERR "Jazz16: Invalid interrupt (IRQ%d)\n", hw_config->irq);
- return 0;
- }
- if (hw_config->dma < 0 || hw_config->dma > 3 || jazz_dma_bits[hw_config->dma] == 0)
- {
- printk(KERN_ERR "Jazz16: Invalid 8 bit DMA (DMA%d)\n", hw_config->dma);
- return 0;
- }
- if (hw_config->dma2 < 0)
- {
- printk(KERN_ERR "Jazz16: No 16 bit DMA channel defined\n");
- return 0;
- }
- if (hw_config->dma2 < 5 || hw_config->dma2 > 7 || jazz_dma_bits[hw_config->dma2] == 0)
- {
- printk(KERN_ERR "Jazz16: Invalid 16 bit DMA (DMA%d)\n", hw_config->dma2);
- return 0;
- }
- devc->dma16 = hw_config->dma2;
-
- if (!sb_dsp_command(devc, 0xfb))
- return 0;
-
- if (!sb_dsp_command(devc, jazz_dma_bits[hw_config->dma] |
- (jazz_dma_bits[hw_config->dma2] << 4)))
- return 0;
-
- if (!sb_dsp_command(devc, jazz_irq_bits[hw_config->irq]))
- return 0;
-
- /*
- * Now we have configured a standard Jazz16 device.
- */
- devc->model = MDL_JAZZ;
- strcpy(name, "Jazz16");
-
- hw_config->name = "Jazz16";
- devc->caps |= SB_NO_MIDI;
- return 1;
-}
-
-static void relocate_ess1688(sb_devc * devc)
-{
- unsigned char bits;
-
- switch (devc->base)
- {
- case 0x220:
- bits = 0x04;
- break;
- case 0x230:
- bits = 0x05;
- break;
- case 0x240:
- bits = 0x06;
- break;
- case 0x250:
- bits = 0x07;
- break;
- default:
- return; /* Wrong port */
- }
-
- DDB(printk("Doing ESS1688 address selection\n"));
-
- /*
- * ES1688 supports two alternative ways for software address config.
- * First try the so called Read-Sequence-Key method.
- */
-
- /* Reset the sequence logic */
- inb(0x229);
- inb(0x229);
- inb(0x229);
-
- /* Perform the read sequence */
- inb(0x22b);
- inb(0x229);
- inb(0x22b);
- inb(0x229);
- inb(0x229);
- inb(0x22b);
- inb(0x229);
-
- /* Select the base address by reading from it. Then probe using the port. */
- inb(devc->base);
- if (sb_dsp_reset(devc)) /* Bingo */
- return;
-
-#if 0 /* This causes system lockups (Nokia 386/25 at least) */
- /*
- * The last resort is the system control register method.
- */
-
- outb((0x00), 0xfb); /* 0xFB is the unlock register */
- outb((0x00), 0xe0); /* Select index 0 */
- outb((bits), 0xe1); /* Write the config bits */
- outb((0x00), 0xf9); /* 0xFB is the lock register */
-#endif
-}
-
-int sb_dsp_detect(struct address_info *hw_config, int pci, int pciio, struct sb_module_options *sbmo)
-{
- sb_devc sb_info;
- sb_devc *devc = &sb_info;
-
- memset((char *) &sb_info, 0, sizeof(sb_info)); /* Zero everything */
-
- /* Copy module options in place */
- if(sbmo) memcpy(&devc->sbmo, sbmo, sizeof(struct sb_module_options));
-
- sb_info.my_mididev = -1;
- sb_info.my_mixerdev = -1;
- sb_info.dev = -1;
-
- /*
- * Initialize variables
- */
-
- DDB(printk("sb_dsp_detect(%x) entered\n", hw_config->io_base));
-
- spin_lock_init(&devc->lock);
- devc->type = hw_config->card_subtype;
-
- devc->base = hw_config->io_base;
- devc->irq = hw_config->irq;
- devc->dma8 = hw_config->dma;
-
- devc->dma16 = -1;
- devc->pcibase = pciio;
-
- if(pci == SB_PCI_ESSMAESTRO)
- {
- devc->model = MDL_ESSPCI;
- devc->caps |= SB_PCI_IRQ;
- hw_config->driver_use_1 |= SB_PCI_IRQ;
- hw_config->card_subtype = MDL_ESSPCI;
- }
-
- if(pci == SB_PCI_YAMAHA)
- {
- devc->model = MDL_YMPCI;
- devc->caps |= SB_PCI_IRQ;
- hw_config->driver_use_1 |= SB_PCI_IRQ;
- hw_config->card_subtype = MDL_YMPCI;
-
- printk("Yamaha PCI mode.\n");
- }
-
- if (devc->sbmo.acer)
- {
- unsigned long flags;
-
- spin_lock_irqsave(&devc->lock, flags);
- inb(devc->base + 0x09);
- inb(devc->base + 0x09);
- inb(devc->base + 0x09);
- inb(devc->base + 0x0b);
- inb(devc->base + 0x09);
- inb(devc->base + 0x0b);
- inb(devc->base + 0x09);
- inb(devc->base + 0x09);
- inb(devc->base + 0x0b);
- inb(devc->base + 0x09);
- inb(devc->base + 0x00);
- spin_unlock_irqrestore(&devc->lock, flags);
- }
- /*
- * Detect the device
- */
-
- if (sb_dsp_reset(devc))
- dsp_get_vers(devc);
- else
- devc->major = 0;
-
- if (devc->type == 0 || devc->type == MDL_JAZZ || devc->type == MDL_SMW)
- if (devc->major == 0 || (devc->major == 3 && devc->minor == 1))
- relocate_Jazz16(devc, hw_config);
-
- if (devc->major == 0 && (devc->type == MDL_ESS || devc->type == 0))
- relocate_ess1688(devc);
-
- if (!sb_dsp_reset(devc))
- {
- DDB(printk("SB reset failed\n"));
-#ifdef MODULE
- printk(KERN_INFO "sb: dsp reset failed.\n");
-#endif
- return 0;
- }
- if (devc->major == 0)
- dsp_get_vers(devc);
-
- if (devc->major == 3 && devc->minor == 1)
- {
- if (devc->type == MDL_AZTECH) /* SG Washington? */
- {
- if (sb_dsp_command(devc, 0x09))
- if (sb_dsp_command(devc, 0x00)) /* Enter WSS mode */
- {
- int i;
-
- /* Have some delay */
- for (i = 0; i < 10000; i++)
- inb(DSP_DATA_AVAIL);
- devc->caps = SB_NO_AUDIO | SB_NO_MIDI; /* Mixer only */
- devc->model = MDL_AZTECH;
- }
- }
- }
-
- if(devc->type == MDL_ESSPCI)
- devc->model = MDL_ESSPCI;
-
- if(devc->type == MDL_YMPCI)
- {
- printk("YMPCI selected\n");
- devc->model = MDL_YMPCI;
- }
-
- /*
- * Save device information for sb_dsp_init()
- */
-
-
- detected_devc = kmalloc(sizeof(sb_devc), GFP_KERNEL);
- if (detected_devc == NULL)
- {
- printk(KERN_ERR "sb: Can't allocate memory for device information\n");
- return 0;
- }
- memcpy(detected_devc, devc, sizeof(sb_devc));
- MDB(printk(KERN_INFO "SB %d.%02d detected OK (%x)\n", devc->major, devc->minor, hw_config->io_base));
- return 1;
-}
-
-int sb_dsp_init(struct address_info *hw_config, struct module *owner)
-{
- sb_devc *devc;
- char name[100];
- extern int sb_be_quiet;
- int mixer22, mixer30;
-
-/*
- * Check if we had detected a SB device earlier
- */
- DDB(printk("sb_dsp_init(%x) entered\n", hw_config->io_base));
- name[0] = 0;
-
- if (detected_devc == NULL)
- {
- MDB(printk("No detected device\n"));
- return 0;
- }
- devc = detected_devc;
- detected_devc = NULL;
-
- if (devc->base != hw_config->io_base)
- {
- DDB(printk("I/O port mismatch\n"));
- release_region(devc->base, 16);
- return 0;
- }
- /*
- * Now continue initialization of the device
- */
-
- devc->caps = hw_config->driver_use_1;
-
- if (!((devc->caps & SB_NO_AUDIO) && (devc->caps & SB_NO_MIDI)) && hw_config->irq > 0)
- { /* IRQ setup */
-
- /*
- * ESS PCI cards do shared PCI IRQ stuff. Since they
- * will get shared PCI irq lines we must cope.
- */
-
- int i=(devc->caps&SB_PCI_IRQ)?IRQF_SHARED:0;
-
- if (request_irq(hw_config->irq, sbintr, i, "soundblaster", devc) < 0)
- {
- printk(KERN_ERR "SB: Can't allocate IRQ%d\n", hw_config->irq);
- release_region(devc->base, 16);
- return 0;
- }
- devc->irq_ok = 0;
-
- if (devc->major == 4)
- if (!sb16_set_irq_hw(devc, devc->irq)) /* Unsupported IRQ */
- {
- free_irq(devc->irq, devc);
- release_region(devc->base, 16);
- return 0;
- }
- if ((devc->type == 0 || devc->type == MDL_ESS) &&
- devc->major == 3 && devc->minor == 1)
- { /* Handle various chipsets which claim they are SB Pro compatible */
- if ((devc->type != 0 && devc->type != MDL_ESS) ||
- !ess_init(devc, hw_config))
- {
- if ((devc->type != 0 && devc->type != MDL_JAZZ &&
- devc->type != MDL_SMW) || !init_Jazz16(devc, hw_config))
- {
- DDB(printk("This is a genuine SB Pro\n"));
- }
- }
- }
- if (devc->major == 4 && devc->minor <= 11 ) /* Won't work */
- devc->irq_ok = 1;
- else
- {
- int n;
-
- for (n = 0; n < 3 && devc->irq_ok == 0; n++)
- {
- if (sb_dsp_command(devc, 0xf2)) /* Cause interrupt immediately */
- {
- int i;
-
- for (i = 0; !devc->irq_ok && i < 10000; i++);
- }
- }
- if (!devc->irq_ok)
- printk(KERN_WARNING "sb: Interrupt test on IRQ%d failed - Probable IRQ conflict\n", devc->irq);
- else
- {
- DDB(printk("IRQ test OK (IRQ%d)\n", devc->irq));
- }
- }
- } /* IRQ setup */
-
- last_sb = devc;
-
- switch (devc->major)
- {
- case 1: /* SB 1.0 or 1.5 */
- devc->model = hw_config->card_subtype = MDL_SB1;
- break;
-
- case 2: /* SB 2.x */
- if (devc->minor == 0)
- devc->model = hw_config->card_subtype = MDL_SB2;
- else
- devc->model = hw_config->card_subtype = MDL_SB201;
- break;
-
- case 3: /* SB Pro and most clones */
- switch (devc->model) {
- case 0:
- devc->model = hw_config->card_subtype = MDL_SBPRO;
- if (hw_config->name == NULL)
- hw_config->name = "Sound Blaster Pro (8 BIT ONLY)";
- break;
- case MDL_ESS:
- ess_dsp_init(devc, hw_config);
- break;
- }
- break;
-
- case 4:
- devc->model = hw_config->card_subtype = MDL_SB16;
- /*
- * ALS007 and ALS100 return DSP version 4.2 and have 2 post-reset !=0
- * registers at 0x3c and 0x4c (output ctrl registers on ALS007) whereas
- * a "standard" SB16 doesn't have a register at 0x4c. ALS100 actively
- * updates register 0x22 whenever 0x30 changes, as per the SB16 spec.
- * Since ALS007 doesn't, this can be used to differentiate the 2 cards.
- */
- if ((devc->minor == 2) && sb_getmixer(devc,0x3c) && sb_getmixer(devc,0x4c))
- {
- mixer30 = sb_getmixer(devc,0x30);
- sb_setmixer(devc,0x22,(mixer22=sb_getmixer(devc,0x22)) & 0x0f);
- sb_setmixer(devc,0x30,0xff);
- /* ALS100 will force 0x30 to 0xf8 like SB16; ALS007 will allow 0xff. */
- /* Register 0x22 & 0xf0 on ALS100 == 0xf0; on ALS007 it == 0x10. */
- if ((sb_getmixer(devc,0x30) != 0xff) || ((sb_getmixer(devc,0x22) & 0xf0) != 0x10))
- {
- devc->submodel = SUBMDL_ALS100;
- if (hw_config->name == NULL)
- hw_config->name = "Sound Blaster 16 (ALS-100)";
- }
- else
- {
- sb_setmixer(devc,0x3c,0x1f); /* Enable all inputs */
- sb_setmixer(devc,0x4c,0x1f);
- sb_setmixer(devc,0x22,mixer22); /* Restore 0x22 to original value */
- devc->submodel = SUBMDL_ALS007;
- if (hw_config->name == NULL)
- hw_config->name = "Sound Blaster 16 (ALS-007)";
- }
- sb_setmixer(devc,0x30,mixer30);
- }
- else if (hw_config->name == NULL)
- hw_config->name = "Sound Blaster 16";
-
- if (hw_config->dma2 == -1)
- devc->dma16 = devc->dma8;
- else if (hw_config->dma2 < 5 || hw_config->dma2 > 7)
- {
- printk(KERN_WARNING "SB16: Bad or missing 16 bit DMA channel\n");
- devc->dma16 = devc->dma8;
- }
- else
- devc->dma16 = hw_config->dma2;
-
- if(!sb16_set_dma_hw(devc)) {
- free_irq(devc->irq, devc);
- release_region(hw_config->io_base, 16);
- return 0;
- }
-
- devc->caps |= SB_NO_MIDI;
- }
-
- if (!(devc->caps & SB_NO_MIXER))
- if (devc->major == 3 || devc->major == 4)
- sb_mixer_init(devc, owner);
-
- if (!(devc->caps & SB_NO_MIDI))
- sb_dsp_midi_init(devc, owner);
-
- if (hw_config->name == NULL)
- hw_config->name = "Sound Blaster (8 BIT/MONO ONLY)";
-
- sprintf(name, "%s (%d.%02d)", hw_config->name, devc->major, devc->minor);
- conf_printf(name, hw_config);
-
- /*
- * Assuming that a sound card is Sound Blaster (compatible) is the most common
- * configuration error and the mother of all problems. Usually sound cards
- * emulate SB Pro but in addition they have a 16 bit native mode which should be
- * used in Unix. See Readme.cards for more information about configuring OSS/Free
- * properly.
- */
- if (devc->model <= MDL_SBPRO)
- {
- if (devc->major == 3 && devc->minor != 1) /* "True" SB Pro should have v3.1 (rare ones may have 3.2). */
- {
- printk(KERN_INFO "This sound card may not be fully Sound Blaster Pro compatible.\n");
- printk(KERN_INFO "In many cases there is another way to configure OSS so that\n");
- printk(KERN_INFO "it works properly with OSS (for example in 16 bit mode).\n");
- printk(KERN_INFO "Please ignore this message if you _really_ have a SB Pro.\n");
- }
- else if (!sb_be_quiet && devc->model == MDL_SBPRO)
- {
- printk(KERN_INFO "SB DSP version is just %d.%02d which means that your card is\n", devc->major, devc->minor);
- printk(KERN_INFO "several years old (8 bit only device) or alternatively the sound driver\n");
- printk(KERN_INFO "is incorrectly configured.\n");
- }
- }
- hw_config->card_subtype = devc->model;
- hw_config->slots[0]=devc->dev;
- last_devc = devc; /* For SB MPU detection */
-
- if (!(devc->caps & SB_NO_AUDIO) && devc->dma8 >= 0)
- {
- if (sound_alloc_dma(devc->dma8, "SoundBlaster8"))
- {
- printk(KERN_WARNING "Sound Blaster: Can't allocate 8 bit DMA channel %d\n", devc->dma8);
- }
- if (devc->dma16 >= 0 && devc->dma16 != devc->dma8)
- {
- if (sound_alloc_dma(devc->dma16, "SoundBlaster16"))
- printk(KERN_WARNING "Sound Blaster: can't allocate 16 bit DMA channel %d.\n", devc->dma16);
- }
- sb_audio_init(devc, name, owner);
- hw_config->slots[0]=devc->dev;
- }
- else
- {
- MDB(printk("Sound Blaster: no audio devices found.\n"));
- }
- return 1;
-}
-
-/* if (sbmpu) below we allow mpu401 to manage the midi devs
- otherwise we have to unload them. (Andrzej Krzysztofowicz) */
-
-void sb_dsp_unload(struct address_info *hw_config, int sbmpu)
-{
- sb_devc *devc;
-
- devc = audio_devs[hw_config->slots[0]]->devc;
-
- if (devc && devc->base == hw_config->io_base)
- {
- if ((devc->model & MDL_ESS) && devc->pcibase)
- release_region(devc->pcibase, 8);
-
- release_region(devc->base, 16);
-
- if (!(devc->caps & SB_NO_AUDIO))
- {
- sound_free_dma(devc->dma8);
- if (devc->dma16 >= 0)
- sound_free_dma(devc->dma16);
- }
- if (!(devc->caps & SB_NO_AUDIO && devc->caps & SB_NO_MIDI))
- {
- if (devc->irq > 0)
- free_irq(devc->irq, devc);
-
- sb_mixer_unload(devc);
- /* We don't have to do this bit any more the UART401 is its own
- master -- Krzysztof Halasa */
- /* But we have to do it, if UART401 is not detected */
- if (!sbmpu)
- sound_unload_mididev(devc->my_mididev);
- sound_unload_audiodev(devc->dev);
- }
- kfree(devc);
- }
- else
- release_region(hw_config->io_base, 16);
-
- kfree(detected_devc);
-}
-
-/*
- * Mixer access routines
- *
- * ES1887 modifications: some mixer registers reside in the
- * range above 0xa0. These must be accessed in another way.
- */
-
-void sb_setmixer(sb_devc * devc, unsigned int port, unsigned int value)
-{
- unsigned long flags;
-
- if (devc->model == MDL_ESS) {
- ess_setmixer (devc, port, value);
- return;
- }
-
- spin_lock_irqsave(&devc->lock, flags);
-
- outb(((unsigned char) (port & 0xff)), MIXER_ADDR);
- udelay(20);
- outb(((unsigned char) (value & 0xff)), MIXER_DATA);
- udelay(20);
-
- spin_unlock_irqrestore(&devc->lock, flags);
-}
-
-unsigned int sb_getmixer(sb_devc * devc, unsigned int port)
-{
- unsigned int val;
- unsigned long flags;
-
- if (devc->model == MDL_ESS) return ess_getmixer (devc, port);
-
- spin_lock_irqsave(&devc->lock, flags);
-
- outb(((unsigned char) (port & 0xff)), MIXER_ADDR);
- udelay(20);
- val = inb(MIXER_DATA);
- udelay(20);
-
- spin_unlock_irqrestore(&devc->lock, flags);
-
- return val;
-}
-
-void sb_chgmixer
- (sb_devc * devc, unsigned int reg, unsigned int mask, unsigned int val)
-{
- int value;
-
- value = sb_getmixer(devc, reg);
- value = (value & ~mask) | (val & mask);
- sb_setmixer(devc, reg, value);
-}
-
-/*
- * MPU401 MIDI initialization.
- */
-
-static void smw_putmem(sb_devc * devc, int base, int addr, unsigned char val)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&jazz16_lock, flags); /* NOT the SB card? */
-
- outb((addr & 0xff), base + 1); /* Low address bits */
- outb((addr >> 8), base + 2); /* High address bits */
- outb((val), base); /* Data */
-
- spin_unlock_irqrestore(&jazz16_lock, flags);
-}
-
-static unsigned char smw_getmem(sb_devc * devc, int base, int addr)
-{
- unsigned long flags;
- unsigned char val;
-
- spin_lock_irqsave(&jazz16_lock, flags); /* NOT the SB card? */
-
- outb((addr & 0xff), base + 1); /* Low address bits */
- outb((addr >> 8), base + 2); /* High address bits */
- val = inb(base); /* Data */
-
- spin_unlock_irqrestore(&jazz16_lock, flags);
- return val;
-}
-
-static int smw_midi_init(sb_devc * devc, struct address_info *hw_config)
-{
- int mpu_base = hw_config->io_base;
- int mp_base = mpu_base + 4; /* Microcontroller base */
- int i;
- unsigned char control;
-
-
- /*
- * Reset the microcontroller so that the RAM can be accessed
- */
-
- control = inb(mpu_base + 7);
- outb((control | 3), mpu_base + 7); /* Set last two bits to 1 (?) */
- outb(((control & 0xfe) | 2), mpu_base + 7); /* xxxxxxx0 resets the mc */
-
- mdelay(3); /* Wait at least 1ms */
-
- outb((control & 0xfc), mpu_base + 7); /* xxxxxx00 enables RAM */
-
- /*
- * Detect microcontroller by probing the 8k RAM area
- */
- smw_putmem(devc, mp_base, 0, 0x00);
- smw_putmem(devc, mp_base, 1, 0xff);
- udelay(10);
-
- if (smw_getmem(devc, mp_base, 0) != 0x00 || smw_getmem(devc, mp_base, 1) != 0xff)
- {
- DDB(printk("SM Wave: No microcontroller RAM detected (%02x, %02x)\n", smw_getmem(devc, mp_base, 0), smw_getmem(devc, mp_base, 1)));
- return 0; /* No RAM */
- }
- /*
- * There is RAM so assume it's really a SM Wave
- */
-
- devc->model = MDL_SMW;
- smw_mixer_init(devc);
-
-#ifdef MODULE
- if (!smw_ucode)
- {
- smw_ucodeLen = mod_firmware_load("/etc/sound/midi0001.bin", (void *) &smw_ucode);
- smw_free = smw_ucode;
- }
-#endif
- if (smw_ucodeLen > 0)
- {
- if (smw_ucodeLen != 8192)
- {
- printk(KERN_ERR "SM Wave: Invalid microcode (MIDI0001.BIN) length\n");
- return 1;
- }
- /*
- * Download microcode
- */
-
- for (i = 0; i < 8192; i++)
- smw_putmem(devc, mp_base, i, smw_ucode[i]);
-
- /*
- * Verify microcode
- */
-
- for (i = 0; i < 8192; i++)
- if (smw_getmem(devc, mp_base, i) != smw_ucode[i])
- {
- printk(KERN_ERR "SM Wave: Microcode verification failed\n");
- return 0;
- }
- }
- control = 0;
-#ifdef SMW_SCSI_IRQ
- /*
- * Set the SCSI interrupt (IRQ2/9, IRQ3 or IRQ10). The SCSI interrupt
- * is disabled by default.
- *
- * FIXME - make this a module option
- *
- * BTW the Zilog 5380 SCSI controller is located at MPU base + 0x10.
- */
- {
- static unsigned char scsi_irq_bits[] = {
- 0, 0, 3, 1, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0
- };
- control |= scsi_irq_bits[SMW_SCSI_IRQ] << 6;
- }
-#endif
-
-#ifdef SMW_OPL4_ENABLE
- /*
- * Make the OPL4 chip visible on the PC bus at 0x380.
- *
- * There is no need to enable this feature since this driver
- * doesn't support OPL4 yet. Also there is no RAM in SM Wave so
- * enabling OPL4 is pretty useless.
- */
- control |= 0x10; /* Uses IRQ12 if bit 0x20 == 0 */
- /* control |= 0x20; Uncomment this if you want to use IRQ7 */
-#endif
- outb((control | 0x03), mpu_base + 7); /* xxxxxx11 restarts */
- hw_config->name = "SoundMan Wave";
- return 1;
-}
-
-static int init_Jazz16_midi(sb_devc * devc, struct address_info *hw_config)
-{
- int mpu_base = hw_config->io_base;
- int sb_base = devc->base;
- int irq = hw_config->irq;
-
- unsigned char bits = 0;
- unsigned long flags;
-
- if (irq < 0)
- irq *= -1;
-
- if (irq < 1 || irq > 15 ||
- jazz_irq_bits[irq] == 0)
- {
- printk(KERN_ERR "Jazz16: Invalid MIDI interrupt (IRQ%d)\n", irq);
- return 0;
- }
- switch (sb_base)
- {
- case 0x220:
- bits = 1;
- break;
- case 0x240:
- bits = 2;
- break;
- case 0x260:
- bits = 3;
- break;
- default:
- return 0;
- }
- bits = jazz16_bits = bits << 5;
- switch (mpu_base)
- {
- case 0x310:
- bits |= 1;
- break;
- case 0x320:
- bits |= 2;
- break;
- case 0x330:
- bits |= 3;
- break;
- default:
- printk(KERN_ERR "Jazz16: Invalid MIDI I/O port %x\n", mpu_base);
- return 0;
- }
- /*
- * Magic wake up sequence by writing to 0x201 (aka Joystick port)
- */
- spin_lock_irqsave(&jazz16_lock, flags);
- outb(0xAF, 0x201);
- outb(0x50, 0x201);
- outb(bits, 0x201);
- spin_unlock_irqrestore(&jazz16_lock, flags);
-
- hw_config->name = "Jazz16";
- smw_midi_init(devc, hw_config);
-
- if (!sb_dsp_command(devc, 0xfb))
- return 0;
-
- if (!sb_dsp_command(devc, jazz_dma_bits[devc->dma8] |
- (jazz_dma_bits[devc->dma16] << 4)))
- return 0;
-
- if (!sb_dsp_command(devc, jazz_irq_bits[devc->irq] |
- (jazz_irq_bits[irq] << 4)))
- return 0;
-
- return 1;
-}
-
-int probe_sbmpu(struct address_info *hw_config, struct module *owner)
-{
- sb_devc *devc = last_devc;
- int ret;
-
- if (last_devc == NULL)
- return 0;
-
- last_devc = NULL;
-
- if (hw_config->io_base <= 0)
- {
- /* The real vibra16 is fine about this, but we have to go
- wipe up after Cyrix again */
-
- if(devc->model == MDL_SB16 && devc->minor >= 12)
- {
- unsigned char bits = sb_getmixer(devc, 0x84) & ~0x06;
- sb_setmixer(devc, 0x84, bits | 0x02); /* Disable MPU */
- }
- return 0;
- }
-
-#if defined(CONFIG_SOUND_MPU401)
- if (devc->model == MDL_ESS)
- {
- struct resource *ports;
- ports = request_region(hw_config->io_base, 2, "mpu401");
- if (!ports) {
- printk(KERN_ERR "sbmpu: I/O port conflict (%x)\n", hw_config->io_base);
- return 0;
- }
- if (!ess_midi_init(devc, hw_config)) {
- release_region(hw_config->io_base, 2);
- return 0;
- }
- hw_config->name = "ESS1xxx MPU";
- devc->midi_irq_cookie = NULL;
- if (!probe_mpu401(hw_config, ports)) {
- release_region(hw_config->io_base, 2);
- return 0;
- }
- attach_mpu401(hw_config, owner);
- if (last_sb->irq == -hw_config->irq)
- last_sb->midi_irq_cookie =
- (void *)(long) hw_config->slots[1];
- return 1;
- }
-#endif
-
- switch (devc->model)
- {
- case MDL_SB16:
- if (hw_config->io_base != 0x300 && hw_config->io_base != 0x330)
- {
- printk(KERN_ERR "SB16: Invalid MIDI port %x\n", hw_config->io_base);
- return 0;
- }
- hw_config->name = "Sound Blaster 16";
- if (hw_config->irq < 3 || hw_config->irq == devc->irq)
- hw_config->irq = -devc->irq;
- if (devc->minor > 12) /* What is Vibra's version??? */
- sb16_set_mpu_port(devc, hw_config);
- break;
-
- case MDL_JAZZ:
- if (hw_config->irq < 3 || hw_config->irq == devc->irq)
- hw_config->irq = -devc->irq;
- if (!init_Jazz16_midi(devc, hw_config))
- return 0;
- break;
-
- case MDL_YMPCI:
- hw_config->name = "Yamaha PCI Legacy";
- printk("Yamaha PCI legacy UART401 check.\n");
- break;
- default:
- return 0;
- }
-
- ret = probe_uart401(hw_config, owner);
- if (ret)
- last_sb->midi_irq_cookie=midi_devs[hw_config->slots[4]]->devc;
- return ret;
-}
-
-void unload_sbmpu(struct address_info *hw_config)
-{
-#if defined(CONFIG_SOUND_MPU401)
- if (!strcmp (hw_config->name, "ESS1xxx MPU")) {
- unload_mpu401(hw_config);
- return;
- }
-#endif
- unload_uart401(hw_config);
-}
-
-EXPORT_SYMBOL(sb_dsp_init);
-EXPORT_SYMBOL(sb_dsp_detect);
-EXPORT_SYMBOL(sb_dsp_unload);
-EXPORT_SYMBOL(sb_be_quiet);
-EXPORT_SYMBOL(probe_sbmpu);
-EXPORT_SYMBOL(unload_sbmpu);
-EXPORT_SYMBOL(smw_free);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/oss/sb_ess.c b/ANDROID_3.4.5/sound/oss/sb_ess.c
deleted file mode 100644
index 5c773dff..00000000
--- a/ANDROID_3.4.5/sound/oss/sb_ess.c
+++ /dev/null
@@ -1,1831 +0,0 @@
-#undef FKS_LOGGING
-#undef FKS_TEST
-
-/*
- * tabs should be 4 spaces, in vi(m): set tabstop=4
- *
- * TODO: consistency speed calculations!!
- * cleanup!
- * ????: Did I break MIDI support?
- *
- * History:
- *
- * Rolf Fokkens (Dec 20 1998): ES188x recording level support on a per
- * fokkensr@vertis.nl input basis.
- * (Dec 24 1998): Recognition of ES1788, ES1887, ES1888,
- * ES1868, ES1869 and ES1878. Could be used for
- * specific handling in the future. All except
- * ES1887 and ES1888 and ES688 are handled like
- * ES1688.
- * (Dec 27 1998): RECLEV for all (?) ES1688+ chips. ES188x now
- * have the "Dec 20" support + RECLEV
- * (Jan 2 1999): Preparation for Full Duplex. This means
- * Audio 2 is now used for playback when dma16
- * is specified. The next step would be to use
- * Audio 1 and Audio 2 at the same time.
- * (Jan 9 1999): Put all ESS stuff into sb_ess.[ch], this
- * includes both the ESS stuff that has been in
- * sb_*[ch] before I touched it and the ESS support
- * I added later
- * (Jan 23 1999): Full Duplex seems to work. I wrote a small
- * test proggy which works OK. Haven't found
- * any applications to test it though. So why did
- * I bother to create it anyway?? :) Just for
- * fun.
- * (May 2 1999): I tried to be too smart by "introducing"
- * ess_calc_best_speed (). The idea was that two
- * dividers could be used to setup a samplerate,
- * ess_calc_best_speed () would choose the best.
- * This works for playback, but results in
- * recording problems for high samplerates. I
- * fixed this by removing ess_calc_best_speed ()
- * and just doing what the documentation says.
- * Andy Sloane (Jun 4 1999): Stole some code from ALSA to fix the playback
- * andy@guildsoftware.com speed on ES1869, ES1879, ES1887, and ES1888.
- * 1879's were previously ignored by this driver;
- * added (untested) support for those.
- * Cvetan Ivanov (Oct 27 1999): Fixed ess_dsp_init to call ess_set_dma_hw for
- * zezo@inet.bg _ALL_ ESS models, not only ES1887
- *
- * This files contains ESS chip specifics. It's based on the existing ESS
- * handling as it resided in sb_common.c, sb_mixer.c and sb_audio.c. This
- * file adds features like:
- * - Chip Identification (as shown in /proc/sound)
- * - RECLEV support for ES1688 and later
- * - 6 bits playback level support chips later than ES1688
- * - Recording level support on a per-device basis for ES1887
- * - Full-Duplex for ES1887
- *
- * Full duplex is enabled by specifying dma16. While the normal dma must
- * be one of 0, 1 or 3, dma16 can be one of 0, 1, 3 or 5. DMA 5 is a 16 bit
- * DMA channel, while the others are 8 bit..
- *
- * ESS detection isn't full proof (yet). If it fails an additional module
- * parameter esstype can be specified to be one of the following:
- * -1, 0, 688, 1688, 1868, 1869, 1788, 1887, 1888
- * -1 means: mimic 2.0 behaviour,
- * 0 means: auto detect.
- * others: explicitly specify chip
- * -1 is default, cause auto detect still doesn't work.
- */
-
-/*
- * About the documentation
- *
- * I don't know if the chips all are OK, but the documentation is buggy. 'cause
- * I don't have all the cips myself, there's a lot I cannot verify. I'll try to
- * keep track of my latest insights about his here. If you have additional info,
- * please enlighten me (fokkensr@vertis.nl)!
- *
- * I had the impression that ES1688 also has 6 bit master volume control. The
- * documentation about ES1888 (rev C, october '95) claims that ES1888 has
- * the following features ES1688 doesn't have:
- * - 6 bit master volume
- * - Full Duplex
- * So ES1688 apparently doesn't have 6 bit master volume control, but the
- * ES1688 does have RECLEV control. Makes me wonder: does ES688 have it too?
- * Without RECLEV ES688 won't be much fun I guess.
- *
- * From the ES1888 (rev C, october '95) documentation I got the impression
- * that registers 0x68 to 0x6e don't exist which means: no recording volume
- * controls. To my surprise the ES888 documentation (1/14/96) claims that
- * ES888 does have these record mixer registers, but that ES1888 doesn't have
- * 0x69 and 0x6b. So the rest should be there.
- *
- * I'm trying to get ES1887 Full Duplex. Audio 2 is playback only, while Audio 2
- * is both record and playback. I think I should use Audio 2 for all playback.
- *
- * The documentation is an adventure: it's close but not fully accurate. I
- * found out that after a reset some registers are *NOT* reset, though the
- * docs say the would be. Interesting ones are 0x7f, 0x7d and 0x7a. They are
- * related to the Audio 2 channel. I also was surprised about the consequences
- * of writing 0x00 to 0x7f (which should be done by reset): The ES1887 moves
- * into ES1888 mode. This means that it claims IRQ 11, which happens to be my
- * ISDN adapter. Needless to say it no longer worked. I now understand why
- * after rebooting 0x7f already was 0x05, the value of my choice: the BIOS
- * did it.
- *
- * Oh, and this is another trap: in ES1887 docs mixer register 0x70 is
- * described as if it's exactly the same as register 0xa1. This is *NOT* true.
- * The description of 0x70 in ES1869 docs is accurate however.
- * Well, the assumption about ES1869 was wrong: register 0x70 is very much
- * like register 0xa1, except that bit 7 is always 1, whatever you want
- * it to be.
- *
- * When using audio 2 mixer register 0x72 seems te be meaningless. Only 0xa2
- * has effect.
- *
- * Software reset not being able to reset all registers is great! Especially
- * the fact that register 0x78 isn't reset is great when you wanna change back
- * to single dma operation (simplex): audio 2 is still operational, and uses
- * the same dma as audio 1: your ess changes into a funny echo machine.
- *
- * Received the news that ES1688 is detected as a ES1788. Did some thinking:
- * the ES1887 detection scheme suggests in step 2 to try if bit 3 of register
- * 0x64 can be changed. This is inaccurate, first I inverted the * check: "If
- * can be modified, it's a 1688", which lead to a correct detection
- * of my ES1887. It resulted however in bad detection of 1688 (reported by mail)
- * and 1868 (if no PnP detection first): they result in a 1788 being detected.
- * I don't have docs on 1688, but I do have docs on 1868: The documentation is
- * probably inaccurate in the fact that I should check bit 2, not bit 3. This
- * is what I do now.
- */
-
-/*
- * About recognition of ESS chips
- *
- * The distinction of ES688, ES1688, ES1788, ES1887 and ES1888 is described in
- * a (preliminary ??) datasheet on ES1887. Its aim is to identify ES1887, but
- * during detection the text claims that "this chip may be ..." when a step
- * fails. This scheme is used to distinct between the above chips.
- * It appears however that some PnP chips like ES1868 are recognized as ES1788
- * by the ES1887 detection scheme. These PnP chips can be detected in another
- * way however: ES1868, ES1869 and ES1878 can be recognized (full proof I think)
- * by repeatedly reading mixer register 0x40. This is done by ess_identify in
- * sb_common.c.
- * This results in the following detection steps:
- * - distinct between ES688 and ES1688+ (as always done in this driver)
- * if ES688 we're ready
- * - try to detect ES1868, ES1869 or ES1878
- * if successful we're ready
- * - try to detect ES1888, ES1887 or ES1788
- * if successful we're ready
- * - Dunno. Must be 1688. Will do in general
- *
- * About RECLEV support:
- *
- * The existing ES1688 support didn't take care of the ES1688+ recording
- * levels very well. Whenever a device was selected (recmask) for recording
- * its recording level was loud, and it couldn't be changed. The fact that
- * internal register 0xb4 could take care of RECLEV, didn't work meaning until
- * its value was restored every time the chip was reset; this reset the
- * value of 0xb4 too. I guess that's what 4front also had (have?) trouble with.
- *
- * About ES1887 support:
- *
- * The ES1887 has separate registers to control the recording levels, for all
- * inputs. The ES1887 specific software makes these levels the same as their
- * corresponding playback levels, unless recmask says they aren't recorded. In
- * the latter case the recording volumes are 0.
- * Now recording levels of inputs can be controlled, by changing the playback
- * levels. Furthermore several devices can be recorded together (which is not
- * possible with the ES1688).
- * Besides the separate recording level control for each input, the common
- * recording level can also be controlled by RECLEV as described above.
- *
- * Not only ES1887 have this recording mixer. I know the following from the
- * documentation:
- * ES688 no
- * ES1688 no
- * ES1868 no
- * ES1869 yes
- * ES1878 no
- * ES1879 yes
- * ES1888 no/yes Contradicting documentation; most recent: yes
- * ES1946 yes This is a PCI chip; not handled by this driver
- */
-
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-
-#include "sound_config.h"
-#include "sb_mixer.h"
-#include "sb.h"
-
-#include "sb_ess.h"
-
-#define ESSTYPE_LIKE20 -1 /* Mimic 2.0 behaviour */
-#define ESSTYPE_DETECT 0 /* Mimic 2.0 behaviour */
-
-#define SUBMDL_ES1788 0x10 /* Subtype ES1788 for specific handling */
-#define SUBMDL_ES1868 0x11 /* Subtype ES1868 for specific handling */
-#define SUBMDL_ES1869 0x12 /* Subtype ES1869 for specific handling */
-#define SUBMDL_ES1878 0x13 /* Subtype ES1878 for specific handling */
-#define SUBMDL_ES1879 0x16 /* ES1879 was initially forgotten */
-#define SUBMDL_ES1887 0x14 /* Subtype ES1887 for specific handling */
-#define SUBMDL_ES1888 0x15 /* Subtype ES1888 for specific handling */
-
-#define SB_CAP_ES18XX_RATE 0x100
-
-#define ES1688_CLOCK1 795444 /* 128 - div */
-#define ES1688_CLOCK2 397722 /* 256 - div */
-#define ES18XX_CLOCK1 793800 /* 128 - div */
-#define ES18XX_CLOCK2 768000 /* 256 - div */
-
-#ifdef FKS_LOGGING
-static void ess_show_mixerregs (sb_devc *devc);
-#endif
-static int ess_read (sb_devc * devc, unsigned char reg);
-static int ess_write (sb_devc * devc, unsigned char reg, unsigned char data);
-static void ess_chgmixer
- (sb_devc * devc, unsigned int reg, unsigned int mask, unsigned int val);
-
-/****************************************************************************
- * *
- * ESS audio *
- * *
- ****************************************************************************/
-
-struct ess_command {short cmd; short data;};
-
-/*
- * Commands for initializing Audio 1 for input (record)
- */
-static struct ess_command ess_i08m[] = /* input 8 bit mono */
- { {0xb7, 0x51}, {0xb7, 0xd0}, {-1, 0} };
-static struct ess_command ess_i16m[] = /* input 16 bit mono */
- { {0xb7, 0x71}, {0xb7, 0xf4}, {-1, 0} };
-static struct ess_command ess_i08s[] = /* input 8 bit stereo */
- { {0xb7, 0x51}, {0xb7, 0x98}, {-1, 0} };
-static struct ess_command ess_i16s[] = /* input 16 bit stereo */
- { {0xb7, 0x71}, {0xb7, 0xbc}, {-1, 0} };
-
-static struct ess_command *ess_inp_cmds[] =
- { ess_i08m, ess_i16m, ess_i08s, ess_i16s };
-
-
-/*
- * Commands for initializing Audio 1 for output (playback)
- */
-static struct ess_command ess_o08m[] = /* output 8 bit mono */
- { {0xb6, 0x80}, {0xb7, 0x51}, {0xb7, 0xd0}, {-1, 0} };
-static struct ess_command ess_o16m[] = /* output 16 bit mono */
- { {0xb6, 0x00}, {0xb7, 0x71}, {0xb7, 0xf4}, {-1, 0} };
-static struct ess_command ess_o08s[] = /* output 8 bit stereo */
- { {0xb6, 0x80}, {0xb7, 0x51}, {0xb7, 0x98}, {-1, 0} };
-static struct ess_command ess_o16s[] = /* output 16 bit stereo */
- { {0xb6, 0x00}, {0xb7, 0x71}, {0xb7, 0xbc}, {-1, 0} };
-
-static struct ess_command *ess_out_cmds[] =
- { ess_o08m, ess_o16m, ess_o08s, ess_o16s };
-
-static void ess_exec_commands
- (sb_devc *devc, struct ess_command *cmdtab[])
-{
- struct ess_command *cmd;
-
- cmd = cmdtab [ ((devc->channels != 1) << 1) + (devc->bits != AFMT_U8) ];
-
- while (cmd->cmd != -1) {
- ess_write (devc, cmd->cmd, cmd->data);
- cmd++;
- }
-}
-
-static void ess_change
- (sb_devc *devc, unsigned int reg, unsigned int mask, unsigned int val)
-{
- int value;
-
- value = ess_read (devc, reg);
- value = (value & ~mask) | (val & mask);
- ess_write (devc, reg, value);
-}
-
-static void ess_set_output_parms
- (int dev, unsigned long buf, int nr_bytes, int intrflag)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- if (devc->duplex) {
- devc->trg_buf_16 = buf;
- devc->trg_bytes_16 = nr_bytes;
- devc->trg_intrflag_16 = intrflag;
- devc->irq_mode_16 = IMODE_OUTPUT;
- } else {
- devc->trg_buf = buf;
- devc->trg_bytes = nr_bytes;
- devc->trg_intrflag = intrflag;
- devc->irq_mode = IMODE_OUTPUT;
- }
-}
-
-static void ess_set_input_parms
- (int dev, unsigned long buf, int count, int intrflag)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- devc->trg_buf = buf;
- devc->trg_bytes = count;
- devc->trg_intrflag = intrflag;
- devc->irq_mode = IMODE_INPUT;
-}
-
-static int ess_calc_div (int clock, int revert, int *speedp, int *diffp)
-{
- int divider;
- int speed, diff;
- int retval;
-
- speed = *speedp;
- divider = (clock + speed / 2) / speed;
- retval = revert - divider;
- if (retval > revert - 1) {
- retval = revert - 1;
- divider = revert - retval;
- }
- /* This line is suggested. Must be wrong I think
- *speedp = (clock + divider / 2) / divider;
- So I chose the next one */
-
- *speedp = clock / divider;
- diff = speed - *speedp;
- if (diff < 0) diff =-diff;
- *diffp = diff;
-
- return retval;
-}
-
-static int ess_calc_best_speed
- (int clock1, int rev1, int clock2, int rev2, int *divp, int *speedp)
-{
- int speed1 = *speedp, speed2 = *speedp;
- int div1, div2;
- int diff1, diff2;
- int retval;
-
- div1 = ess_calc_div (clock1, rev1, &speed1, &diff1);
- div2 = ess_calc_div (clock2, rev2, &speed2, &diff2);
-
- if (diff1 < diff2) {
- *divp = div1;
- *speedp = speed1;
- retval = 1;
- } else {
- /* *divp = div2; */
- *divp = 0x80 | div2;
- *speedp = speed2;
- retval = 2;
- }
-
- return retval;
-}
-
-/*
- * Depending on the audiochannel ESS devices can
- * have different clock settings. These are made consistent for duplex
- * however.
- * callers of ess_speed only do an audionum suggestion, which means
- * input suggests 1, output suggests 2. This suggestion is only true
- * however when doing duplex.
- */
-static void ess_common_speed (sb_devc *devc, int *speedp, int *divp)
-{
- int diff = 0, div;
-
- if (devc->duplex) {
- /*
- * The 0x80 is important for the first audio channel
- */
- if (devc->submodel == SUBMDL_ES1888) {
- div = 0x80 | ess_calc_div (795500, 256, speedp, &diff);
- } else {
- div = 0x80 | ess_calc_div (795500, 128, speedp, &diff);
- }
- } else if(devc->caps & SB_CAP_ES18XX_RATE) {
- if (devc->submodel == SUBMDL_ES1888) {
- ess_calc_best_speed(397700, 128, 795500, 256,
- &div, speedp);
- } else {
- ess_calc_best_speed(ES18XX_CLOCK1, 128, ES18XX_CLOCK2, 256,
- &div, speedp);
- }
- } else {
- if (*speedp > 22000) {
- div = 0x80 | ess_calc_div (ES1688_CLOCK1, 256, speedp, &diff);
- } else {
- div = 0x00 | ess_calc_div (ES1688_CLOCK2, 128, speedp, &diff);
- }
- }
- *divp = div;
-}
-
-static void ess_speed (sb_devc *devc, int audionum)
-{
- int speed;
- int div, div2;
-
- ess_common_speed (devc, &(devc->speed), &div);
-
-#ifdef FKS_REG_LOGGING
-printk (KERN_INFO "FKS: ess_speed (%d) b speed = %d, div=%x\n", audionum, devc->speed, div);
-#endif
-
- /* Set filter roll-off to 90% of speed/2 */
- speed = (devc->speed * 9) / 20;
-
- div2 = 256 - 7160000 / (speed * 82);
-
- if (!devc->duplex) audionum = 1;
-
- if (audionum == 1) {
- /* Change behaviour of register A1 *
- sb_chg_mixer(devc, 0x71, 0x20, 0x20)
- * For ES1869 only??? */
- ess_write (devc, 0xa1, div);
- ess_write (devc, 0xa2, div2);
- } else {
- ess_setmixer (devc, 0x70, div);
- /*
- * FKS: fascinating: 0x72 doesn't seem to work.
- */
- ess_write (devc, 0xa2, div2);
- ess_setmixer (devc, 0x72, div2);
- }
-}
-
-static int ess_audio_prepare_for_input(int dev, int bsize, int bcount)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- ess_speed(devc, 1);
-
- sb_dsp_command(devc, DSP_CMD_SPKOFF);
-
- ess_write (devc, 0xb8, 0x0e); /* Auto init DMA mode */
- ess_change (devc, 0xa8, 0x03, 3 - devc->channels); /* Mono/stereo */
- ess_write (devc, 0xb9, 2); /* Demand mode (4 bytes/DMA request) */
-
- ess_exec_commands (devc, ess_inp_cmds);
-
- ess_change (devc, 0xb1, 0xf0, 0x50);
- ess_change (devc, 0xb2, 0xf0, 0x50);
-
- devc->trigger_bits = 0;
- return 0;
-}
-
-static int ess_audio_prepare_for_output_audio1 (int dev, int bsize, int bcount)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- sb_dsp_reset(devc);
- ess_speed(devc, 1);
- ess_write (devc, 0xb8, 4); /* Auto init DMA mode */
- ess_change (devc, 0xa8, 0x03, 3 - devc->channels); /* Mono/stereo */
- ess_write (devc, 0xb9, 2); /* Demand mode (4 bytes/request) */
-
- ess_exec_commands (devc, ess_out_cmds);
-
- ess_change (devc, 0xb1, 0xf0, 0x50); /* Enable DMA */
- ess_change (devc, 0xb2, 0xf0, 0x50); /* Enable IRQ */
-
- sb_dsp_command(devc, DSP_CMD_SPKON); /* There be sound! */
-
- devc->trigger_bits = 0;
- return 0;
-}
-
-static int ess_audio_prepare_for_output_audio2 (int dev, int bsize, int bcount)
-{
- sb_devc *devc = audio_devs[dev]->devc;
- unsigned char bits;
-
-/* FKS: qqq
- sb_dsp_reset(devc);
-*/
-
- /*
- * Auto-Initialize:
- * DMA mode + demand mode (8 bytes/request, yes I want it all!)
- * But leave 16-bit DMA bit untouched!
- */
- ess_chgmixer (devc, 0x78, 0xd0, 0xd0);
-
- ess_speed(devc, 2);
-
- /* bits 4:3 on ES1887 represent recording source. Keep them! */
- bits = ess_getmixer (devc, 0x7a) & 0x18;
-
- /* Set stereo/mono */
- if (devc->channels != 1) bits |= 0x02;
-
- /* Init DACs; UNSIGNED mode for 8 bit; SIGNED mode for 16 bit */
- if (devc->bits != AFMT_U8) bits |= 0x05; /* 16 bit */
-
- /* Enable DMA, IRQ will be shared (hopefully)*/
- bits |= 0x60;
-
- ess_setmixer (devc, 0x7a, bits);
-
- ess_mixer_reload (devc, SOUND_MIXER_PCM); /* There be sound! */
-
- devc->trigger_bits = 0;
- return 0;
-}
-
-static int ess_audio_prepare_for_output(int dev, int bsize, int bcount)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
-#ifdef FKS_REG_LOGGING
-printk(KERN_INFO "ess_audio_prepare_for_output: dma_out=%d,dma_in=%d\n"
-, audio_devs[dev]->dmap_out->dma, audio_devs[dev]->dmap_in->dma);
-#endif
-
- if (devc->duplex) {
- return ess_audio_prepare_for_output_audio2 (dev, bsize, bcount);
- } else {
- return ess_audio_prepare_for_output_audio1 (dev, bsize, bcount);
- }
-}
-
-static void ess_audio_halt_xfer(int dev)
-{
- unsigned long flags;
- sb_devc *devc = audio_devs[dev]->devc;
-
- spin_lock_irqsave(&devc->lock, flags);
- sb_dsp_reset(devc);
- spin_unlock_irqrestore(&devc->lock, flags);
-
- /*
- * Audio 2 may still be operational! Creates awful sounds!
- */
- if (devc->duplex) ess_chgmixer(devc, 0x78, 0x03, 0x00);
-}
-
-static void ess_audio_start_input
- (int dev, unsigned long buf, int nr_bytes, int intrflag)
-{
- int count = nr_bytes;
- sb_devc *devc = audio_devs[dev]->devc;
- short c = -nr_bytes;
-
- /*
- * Start a DMA input to the buffer pointed by dmaqtail
- */
-
- if (audio_devs[dev]->dmap_in->dma > 3) count >>= 1;
- count--;
-
- devc->irq_mode = IMODE_INPUT;
-
- ess_write (devc, 0xa4, (unsigned char) ((unsigned short) c & 0xff));
- ess_write (devc, 0xa5, (unsigned char) (((unsigned short) c >> 8) & 0xff));
-
- ess_change (devc, 0xb8, 0x0f, 0x0f); /* Go */
- devc->intr_active = 1;
-}
-
-static void ess_audio_output_block_audio1
- (int dev, unsigned long buf, int nr_bytes, int intrflag)
-{
- int count = nr_bytes;
- sb_devc *devc = audio_devs[dev]->devc;
- short c = -nr_bytes;
-
- if (audio_devs[dev]->dmap_out->dma > 3)
- count >>= 1;
- count--;
-
- devc->irq_mode = IMODE_OUTPUT;
-
- ess_write (devc, 0xa4, (unsigned char) ((unsigned short) c & 0xff));
- ess_write (devc, 0xa5, (unsigned char) (((unsigned short) c >> 8) & 0xff));
-
- ess_change (devc, 0xb8, 0x05, 0x05); /* Go */
- devc->intr_active = 1;
-}
-
-static void ess_audio_output_block_audio2
- (int dev, unsigned long buf, int nr_bytes, int intrflag)
-{
- int count = nr_bytes;
- sb_devc *devc = audio_devs[dev]->devc;
- short c = -nr_bytes;
-
- if (audio_devs[dev]->dmap_out->dma > 3) count >>= 1;
- count--;
-
- ess_setmixer (devc, 0x74, (unsigned char) ((unsigned short) c & 0xff));
- ess_setmixer (devc, 0x76, (unsigned char) (((unsigned short) c >> 8) & 0xff));
- ess_chgmixer (devc, 0x78, 0x03, 0x03); /* Go */
-
- devc->irq_mode_16 = IMODE_OUTPUT;
- devc->intr_active_16 = 1;
-}
-
-static void ess_audio_output_block
- (int dev, unsigned long buf, int nr_bytes, int intrflag)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- if (devc->duplex) {
- ess_audio_output_block_audio2 (dev, buf, nr_bytes, intrflag);
- } else {
- ess_audio_output_block_audio1 (dev, buf, nr_bytes, intrflag);
- }
-}
-
-/*
- * FKS: the if-statements for both bits and bits_16 are quite alike.
- * Combine this...
- */
-static void ess_audio_trigger(int dev, int bits)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- int bits_16 = bits & devc->irq_mode_16;
- bits &= devc->irq_mode;
-
- if (!bits && !bits_16) {
- /* FKS oh oh.... wrong?? for dma 16? */
- sb_dsp_command(devc, 0xd0); /* Halt DMA */
- }
-
- if (bits) {
- switch (devc->irq_mode)
- {
- case IMODE_INPUT:
- ess_audio_start_input(dev, devc->trg_buf, devc->trg_bytes,
- devc->trg_intrflag);
- break;
-
- case IMODE_OUTPUT:
- ess_audio_output_block(dev, devc->trg_buf, devc->trg_bytes,
- devc->trg_intrflag);
- break;
- }
- }
-
- if (bits_16) {
- switch (devc->irq_mode_16) {
- case IMODE_INPUT:
- ess_audio_start_input(dev, devc->trg_buf_16, devc->trg_bytes_16,
- devc->trg_intrflag_16);
- break;
-
- case IMODE_OUTPUT:
- ess_audio_output_block(dev, devc->trg_buf_16, devc->trg_bytes_16,
- devc->trg_intrflag_16);
- break;
- }
- }
-
- devc->trigger_bits = bits | bits_16;
-}
-
-static int ess_audio_set_speed(int dev, int speed)
-{
- sb_devc *devc = audio_devs[dev]->devc;
- int minspeed, maxspeed, dummydiv;
-
- if (speed > 0) {
- minspeed = (devc->duplex ? 6215 : 5000 );
- maxspeed = (devc->duplex ? 44100 : 48000);
- if (speed < minspeed) speed = minspeed;
- if (speed > maxspeed) speed = maxspeed;
-
- ess_common_speed (devc, &speed, &dummydiv);
-
- devc->speed = speed;
- }
- return devc->speed;
-}
-
-/*
- * FKS: This is a one-on-one copy of sb1_audio_set_bits
- */
-static unsigned int ess_audio_set_bits(int dev, unsigned int bits)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- if (bits != 0) {
- if (bits == AFMT_U8 || bits == AFMT_S16_LE) {
- devc->bits = bits;
- } else {
- devc->bits = AFMT_U8;
- }
- }
-
- return devc->bits;
-}
-
-/*
- * FKS: This is a one-on-one copy of sbpro_audio_set_channels
- * (*) Modified it!!
- */
-static short ess_audio_set_channels(int dev, short channels)
-{
- sb_devc *devc = audio_devs[dev]->devc;
-
- if (channels == 1 || channels == 2) devc->channels = channels;
-
- return devc->channels;
-}
-
-static struct audio_driver ess_audio_driver = /* ESS ES688/1688 */
-{
- .owner = THIS_MODULE,
- .open = sb_audio_open,
- .close = sb_audio_close,
- .output_block = ess_set_output_parms,
- .start_input = ess_set_input_parms,
- .prepare_for_input = ess_audio_prepare_for_input,
- .prepare_for_output = ess_audio_prepare_for_output,
- .halt_io = ess_audio_halt_xfer,
- .trigger = ess_audio_trigger,
- .set_speed = ess_audio_set_speed,
- .set_bits = ess_audio_set_bits,
- .set_channels = ess_audio_set_channels
-};
-
-/*
- * ess_audio_init must be called from sb_audio_init
- */
-struct audio_driver *ess_audio_init
- (sb_devc *devc, int *audio_flags, int *format_mask)
-{
- *audio_flags = DMA_AUTOMODE;
- *format_mask |= AFMT_S16_LE;
-
- if (devc->duplex) {
- int tmp_dma;
- /*
- * sb_audio_init thinks dma8 is for playback and
- * dma16 is for record. Not now! So swap them.
- */
- tmp_dma = devc->dma16;
- devc->dma16 = devc->dma8;
- devc->dma8 = tmp_dma;
-
- *audio_flags |= DMA_DUPLEX;
- }
-
- return &ess_audio_driver;
-}
-
-/****************************************************************************
- * *
- * ESS common *
- * *
- ****************************************************************************/
-static void ess_handle_channel
- (char *channel, int dev, int intr_active, unsigned char flag, int irq_mode)
-{
- if (!intr_active || !flag) return;
-#ifdef FKS_REG_LOGGING
-printk(KERN_INFO "FKS: ess_handle_channel %s irq_mode=%d\n", channel, irq_mode);
-#endif
- switch (irq_mode) {
- case IMODE_OUTPUT:
- DMAbuf_outputintr (dev, 1);
- break;
-
- case IMODE_INPUT:
- DMAbuf_inputintr (dev);
- break;
-
- case IMODE_INIT:
- break;
-
- default:;
- /* printk(KERN_WARNING "ESS: Unexpected interrupt\n"); */
- }
-}
-
-/*
- * FKS: TODO!!! Finish this!
- *
- * I think midi stuff uses uart401, without interrupts.
- * So IMODE_MIDI isn't a value for devc->irq_mode.
- */
-void ess_intr (sb_devc *devc)
-{
- int status;
- unsigned char src;
-
- if (devc->submodel == SUBMDL_ES1887) {
- src = ess_getmixer (devc, 0x7f) >> 4;
- } else {
- src = 0xff;
- }
-
-#ifdef FKS_REG_LOGGING
-printk(KERN_INFO "FKS: sbintr src=%x\n",(int)src);
-#endif
- ess_handle_channel
- ( "Audio 1"
- , devc->dev, devc->intr_active , src & 0x01, devc->irq_mode );
- ess_handle_channel
- ( "Audio 2"
- , devc->dev, devc->intr_active_16, src & 0x02, devc->irq_mode_16);
- /*
- * Acknowledge interrupts
- */
- if (devc->submodel == SUBMDL_ES1887 && (src & 0x02)) {
- ess_chgmixer (devc, 0x7a, 0x80, 0x00);
- }
-
- if (src & 0x01) {
- status = inb(DSP_DATA_AVAIL);
- }
-}
-
-static void ess_extended (sb_devc * devc)
-{
- /* Enable extended mode */
-
- sb_dsp_command(devc, 0xc6);
-}
-
-static int ess_write (sb_devc * devc, unsigned char reg, unsigned char data)
-{
-#ifdef FKS_REG_LOGGING
-printk(KERN_INFO "FKS: write reg %x: %x\n", reg, data);
-#endif
- /* Write a byte to an extended mode register of ES1688 */
-
- if (!sb_dsp_command(devc, reg))
- return 0;
-
- return sb_dsp_command(devc, data);
-}
-
-static int ess_read (sb_devc * devc, unsigned char reg)
-{
- /* Read a byte from an extended mode register of ES1688 */
-
- /* Read register command */
- if (!sb_dsp_command(devc, 0xc0)) return -1;
-
- if (!sb_dsp_command(devc, reg )) return -1;
-
- return sb_dsp_get_byte(devc);
-}
-
-int ess_dsp_reset(sb_devc * devc)
-{
- int loopc;
-
-#ifdef FKS_REG_LOGGING
-printk(KERN_INFO "FKS: ess_dsp_reset 1\n");
-ess_show_mixerregs (devc);
-#endif
-
- DEB(printk("Entered ess_dsp_reset()\n"));
-
- outb(3, DSP_RESET); /* Reset FIFO too */
-
- udelay(10);
- outb(0, DSP_RESET);
- udelay(30);
-
- for (loopc = 0; loopc < 1000 && !(inb(DSP_DATA_AVAIL) & 0x80); loopc++);
-
- if (inb(DSP_READ) != 0xAA) {
- DDB(printk("sb: No response to RESET\n"));
- return 0; /* Sorry */
- }
- ess_extended (devc);
-
- DEB(printk("sb_dsp_reset() OK\n"));
-
-#ifdef FKS_LOGGING
-printk(KERN_INFO "FKS: dsp_reset 2\n");
-ess_show_mixerregs (devc);
-#endif
-
- return 1;
-}
-
-static int ess_irq_bits (int irq)
-{
- switch (irq) {
- case 2:
- case 9:
- return 0;
-
- case 5:
- return 1;
-
- case 7:
- return 2;
-
- case 10:
- return 3;
-
- default:
- printk(KERN_ERR "ESS1688: Invalid IRQ %d\n", irq);
- return -1;
- }
-}
-
-/*
- * Set IRQ configuration register for all ESS models
- */
-static int ess_common_set_irq_hw (sb_devc * devc)
-{
- int irq_bits;
-
- if ((irq_bits = ess_irq_bits (devc->irq)) == -1) return 0;
-
- if (!ess_write (devc, 0xb1, 0x50 | (irq_bits << 2))) {
- printk(KERN_ERR "ES1688: Failed to write to IRQ config register\n");
- return 0;
- }
- return 1;
-}
-
-/*
- * I wanna use modern ES1887 mixer irq handling. Funny is the
- * fact that my BIOS wants the same. But suppose someone's BIOS
- * doesn't do this!
- * This is independent of duplex. If there's a 1887 this will
- * prevent it from going into 1888 mode.
- */
-static void ess_es1887_set_irq_hw (sb_devc * devc)
-{
- int irq_bits;
-
- if ((irq_bits = ess_irq_bits (devc->irq)) == -1) return;
-
- ess_chgmixer (devc, 0x7f, 0x0f, 0x01 | ((irq_bits + 1) << 1));
-}
-
-static int ess_set_irq_hw (sb_devc * devc)
-{
- if (devc->submodel == SUBMDL_ES1887) ess_es1887_set_irq_hw (devc);
-
- return ess_common_set_irq_hw (devc);
-}
-
-#ifdef FKS_TEST
-
-/*
- * FKS_test:
- * for ES1887: 00, 18, non wr bits: 0001 1000
- * for ES1868: 00, b8, non wr bits: 1011 1000
- * for ES1888: 00, f8, non wr bits: 1111 1000
- * for ES1688: 00, f8, non wr bits: 1111 1000
- * + ES968
- */
-
-static void FKS_test (sb_devc * devc)
-{
- int val1, val2;
- val1 = ess_getmixer (devc, 0x64);
- ess_setmixer (devc, 0x64, ~val1);
- val2 = ess_getmixer (devc, 0x64) ^ ~val1;
- ess_setmixer (devc, 0x64, val1);
- val1 ^= ess_getmixer (devc, 0x64);
-printk (KERN_INFO "FKS: FKS_test %02x, %02x\n", (val1 & 0x0ff), (val2 & 0x0ff));
-};
-#endif
-
-static unsigned int ess_identify (sb_devc * devc)
-{
- unsigned int val;
- unsigned long flags;
-
- spin_lock_irqsave(&devc->lock, flags);
- outb(((unsigned char) (0x40 & 0xff)), MIXER_ADDR);
-
- udelay(20);
- val = inb(MIXER_DATA) << 8;
- udelay(20);
- val |= inb(MIXER_DATA);
- udelay(20);
- spin_unlock_irqrestore(&devc->lock, flags);
-
- return val;
-}
-
-/*
- * ESS technology describes a detection scheme in their docs. It involves
- * fiddling with the bits in certain mixer registers. ess_probe is supposed
- * to help.
- *
- * FKS: tracing shows ess_probe writes wrong value to 0x64. Bit 3 reads 1, but
- * should be written 0 only. Check this.
- */
-static int ess_probe (sb_devc * devc, int reg, int xorval)
-{
- int val1, val2, val3;
-
- val1 = ess_getmixer (devc, reg);
- val2 = val1 ^ xorval;
- ess_setmixer (devc, reg, val2);
- val3 = ess_getmixer (devc, reg);
- ess_setmixer (devc, reg, val1);
-
- return (val2 == val3);
-}
-
-int ess_init(sb_devc * devc, struct address_info *hw_config)
-{
- unsigned char cfg;
- int ess_major = 0, ess_minor = 0;
- int i;
- static char name[100], modelname[10];
-
- /*
- * Try to detect ESS chips.
- */
-
- sb_dsp_command(devc, 0xe7); /* Return identification */
-
- for (i = 1000; i; i--) {
- if (inb(DSP_DATA_AVAIL) & 0x80) {
- if (ess_major == 0) {
- ess_major = inb(DSP_READ);
- } else {
- ess_minor = inb(DSP_READ);
- break;
- }
- }
- }
-
- if (ess_major == 0) return 0;
-
- if (ess_major == 0x48 && (ess_minor & 0xf0) == 0x80) {
- sprintf(name, "ESS ES488 AudioDrive (rev %d)",
- ess_minor & 0x0f);
- hw_config->name = name;
- devc->model = MDL_SBPRO;
- return 1;
- }
-
- /*
- * This the detection heuristic of ESS technology, though somewhat
- * changed to actually make it work.
- * This results in the following detection steps:
- * - distinct between ES688 and ES1688+ (as always done in this driver)
- * if ES688 we're ready
- * - try to detect ES1868, ES1869 or ES1878 (ess_identify)
- * if successful we're ready
- * - try to detect ES1888, ES1887 or ES1788 (aim: detect ES1887)
- * if successful we're ready
- * - Dunno. Must be 1688. Will do in general
- *
- * This is the most BETA part of the software: Will the detection
- * always work?
- */
- devc->model = MDL_ESS;
- devc->submodel = ess_minor & 0x0f;
-
- if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) {
- char *chip = NULL;
- int submodel = -1;
-
- switch (devc->sbmo.esstype) {
- case ESSTYPE_DETECT:
- case ESSTYPE_LIKE20:
- break;
- case 688:
- submodel = 0x00;
- break;
- case 1688:
- submodel = 0x08;
- break;
- case 1868:
- submodel = SUBMDL_ES1868;
- break;
- case 1869:
- submodel = SUBMDL_ES1869;
- break;
- case 1788:
- submodel = SUBMDL_ES1788;
- break;
- case 1878:
- submodel = SUBMDL_ES1878;
- break;
- case 1879:
- submodel = SUBMDL_ES1879;
- break;
- case 1887:
- submodel = SUBMDL_ES1887;
- break;
- case 1888:
- submodel = SUBMDL_ES1888;
- break;
- default:
- printk (KERN_ERR "Invalid esstype=%d specified\n", devc->sbmo.esstype);
- return 0;
- };
- if (submodel != -1) {
- devc->submodel = submodel;
- sprintf (modelname, "ES%d", devc->sbmo.esstype);
- chip = modelname;
- };
- if (chip == NULL && (ess_minor & 0x0f) < 8) {
- chip = "ES688";
- };
-#ifdef FKS_TEST
-FKS_test (devc);
-#endif
- /*
- * If Nothing detected yet, and we want 2.0 behaviour...
- * Then let's assume it's ES1688.
- */
- if (chip == NULL && devc->sbmo.esstype == ESSTYPE_LIKE20) {
- chip = "ES1688";
- };
-
- if (chip == NULL) {
- int type;
-
- type = ess_identify (devc);
-
- switch (type) {
- case 0x1868:
- chip = "ES1868";
- devc->submodel = SUBMDL_ES1868;
- break;
- case 0x1869:
- chip = "ES1869";
- devc->submodel = SUBMDL_ES1869;
- break;
- case 0x1878:
- chip = "ES1878";
- devc->submodel = SUBMDL_ES1878;
- break;
- case 0x1879:
- chip = "ES1879";
- devc->submodel = SUBMDL_ES1879;
- break;
- default:
- if ((type & 0x00ff) != ((type >> 8) & 0x00ff)) {
- printk ("ess_init: Unrecognized %04x\n", type);
- }
- };
- };
-#if 0
- /*
- * this one failed:
- * the probing of bit 4 is another thought: from ES1788 and up, all
- * chips seem to have hardware volume control. Bit 4 is readonly to
- * check if a hardware volume interrupt has fired.
- * Cause ES688/ES1688 don't have this feature, bit 4 might be writeable
- * for these chips.
- */
- if (chip == NULL && !ess_probe(devc, 0x64, (1 << 4))) {
-#endif
- /*
- * the probing of bit 2 is my idea. The ES1887 docs want me to probe
- * bit 3. This results in ES1688 being detected as ES1788.
- * Bit 2 is for "Enable HWV IRQE", but as ES(1)688 chips don't have
- * HardWare Volume, I think they don't have this IRQE.
- */
- if (chip == NULL && ess_probe(devc, 0x64, (1 << 2))) {
- if (ess_probe (devc, 0x70, 0x7f)) {
- if (ess_probe (devc, 0x64, (1 << 5))) {
- chip = "ES1887";
- devc->submodel = SUBMDL_ES1887;
- } else {
- chip = "ES1888";
- devc->submodel = SUBMDL_ES1888;
- }
- } else {
- chip = "ES1788";
- devc->submodel = SUBMDL_ES1788;
- }
- };
- if (chip == NULL) {
- chip = "ES1688";
- };
-
- printk ( KERN_INFO "ESS chip %s %s%s\n"
- , chip
- , ( devc->sbmo.esstype == ESSTYPE_DETECT || devc->sbmo.esstype == ESSTYPE_LIKE20
- ? "detected"
- : "specified"
- )
- , ( devc->sbmo.esstype == ESSTYPE_LIKE20
- ? " (kernel 2.0 compatible)"
- : ""
- )
- );
-
- sprintf(name,"ESS %s AudioDrive (rev %d)", chip, ess_minor & 0x0f);
- } else {
- strcpy(name, "Jazz16");
- }
-
- /* AAS: info stolen from ALSA: these boards have different clocks */
- switch(devc->submodel) {
-/* APPARENTLY NOT 1869 AND 1887
- case SUBMDL_ES1869:
- case SUBMDL_ES1887:
-*/
- case SUBMDL_ES1888:
- devc->caps |= SB_CAP_ES18XX_RATE;
- break;
- }
-
- hw_config->name = name;
- /* FKS: sb_dsp_reset to enable extended mode???? */
- sb_dsp_reset(devc); /* Turn on extended mode */
-
- /*
- * Enable joystick and OPL3
- */
- cfg = ess_getmixer (devc, 0x40);
- ess_setmixer (devc, 0x40, cfg | 0x03);
- if (devc->submodel >= 8) { /* ES1688 */
- devc->caps |= SB_NO_MIDI; /* ES1688 uses MPU401 MIDI mode */
- }
- sb_dsp_reset (devc);
-
- /*
- * This is important! If it's not done, the IRQ probe in sb_dsp_init
- * may fail.
- */
- return ess_set_irq_hw (devc);
-}
-
-static int ess_set_dma_hw(sb_devc * devc)
-{
- unsigned char cfg, dma_bits = 0, dma16_bits;
- int dma;
-
-#ifdef FKS_LOGGING
-printk(KERN_INFO "ess_set_dma_hw: dma8=%d,dma16=%d,dup=%d\n"
-, devc->dma8, devc->dma16, devc->duplex);
-#endif
-
- /*
- * FKS: It seems as if this duplex flag isn't set yet. Check it.
- */
- dma = devc->dma8;
-
- if (dma > 3 || dma < 0 || dma == 2) {
- dma_bits = 0;
- printk(KERN_ERR "ESS1688: Invalid DMA8 %d\n", dma);
- return 0;
- } else {
- /* Extended mode DMA enable */
- cfg = 0x50;
-
- if (dma == 3) {
- dma_bits = 3;
- } else {
- dma_bits = dma + 1;
- }
- }
-
- if (!ess_write (devc, 0xb2, cfg | (dma_bits << 2))) {
- printk(KERN_ERR "ESS1688: Failed to write to DMA config register\n");
- return 0;
- }
-
- if (devc->duplex) {
- dma = devc->dma16;
- dma16_bits = 0;
-
- if (dma >= 0) {
- switch (dma) {
- case 0:
- dma_bits = 0x04;
- break;
- case 1:
- dma_bits = 0x05;
- break;
- case 3:
- dma_bits = 0x06;
- break;
- case 5:
- dma_bits = 0x07;
- dma16_bits = 0x20;
- break;
- default:
- printk(KERN_ERR "ESS1887: Invalid DMA16 %d\n", dma);
- return 0;
- };
- ess_chgmixer (devc, 0x78, 0x20, dma16_bits);
- ess_chgmixer (devc, 0x7d, 0x07, dma_bits);
- }
- }
- return 1;
-}
-
-/*
- * This one is called from sb_dsp_init.
- *
- * Return values:
- * 0: Failed
- * 1: Succeeded or doesn't apply (not SUBMDL_ES1887)
- */
-int ess_dsp_init (sb_devc *devc, struct address_info *hw_config)
-{
- /*
- * Caller also checks this, but anyway
- */
- if (devc->model != MDL_ESS) {
- printk (KERN_INFO "ess_dsp_init for non ESS chip\n");
- return 1;
- }
- /*
- * This for ES1887 to run Full Duplex. Actually ES1888
- * is allowed to do so too. I have no idea yet if this
- * will work for ES1888 however.
- *
- * For SB16 having both dma8 and dma16 means enable
- * Full Duplex. Let's try this for ES1887 too
- *
- */
- if (devc->submodel == SUBMDL_ES1887) {
- if (hw_config->dma2 != -1) {
- devc->dma16 = hw_config->dma2;
- }
- /*
- * devc->duplex initialization is put here, cause
- * ess_set_dma_hw needs it.
- */
- if (devc->dma8 != devc->dma16 && devc->dma16 != -1) {
- devc->duplex = 1;
- }
- }
- if (!ess_set_dma_hw (devc)) {
- free_irq(devc->irq, devc);
- return 0;
- }
- return 1;
-}
-
-/****************************************************************************
- * *
- * ESS mixer *
- * *
- ****************************************************************************/
-
-#define ES688_RECORDING_DEVICES \
- ( SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD )
-#define ES688_MIXER_DEVICES \
- ( SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_LINE \
- | SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_VOLUME \
- | SOUND_MASK_LINE2 | SOUND_MASK_SPEAKER )
-
-#define ES1688_RECORDING_DEVICES \
- ( ES688_RECORDING_DEVICES )
-#define ES1688_MIXER_DEVICES \
- ( ES688_MIXER_DEVICES | SOUND_MASK_RECLEV )
-
-#define ES1887_RECORDING_DEVICES \
- ( ES1688_RECORDING_DEVICES | SOUND_MASK_LINE2 | SOUND_MASK_SYNTH)
-#define ES1887_MIXER_DEVICES \
- ( ES1688_MIXER_DEVICES )
-
-/*
- * Mixer registers of ES1887
- *
- * These registers specifically take care of recording levels. To make the
- * mapping from playback devices to recording devices every recording
- * devices = playback device + ES_REC_MIXER_RECDIFF
- */
-#define ES_REC_MIXER_RECBASE (SOUND_MIXER_LINE3 + 1)
-#define ES_REC_MIXER_RECDIFF (ES_REC_MIXER_RECBASE - SOUND_MIXER_SYNTH)
-
-#define ES_REC_MIXER_RECSYNTH (SOUND_MIXER_SYNTH + ES_REC_MIXER_RECDIFF)
-#define ES_REC_MIXER_RECPCM (SOUND_MIXER_PCM + ES_REC_MIXER_RECDIFF)
-#define ES_REC_MIXER_RECSPEAKER (SOUND_MIXER_SPEAKER + ES_REC_MIXER_RECDIFF)
-#define ES_REC_MIXER_RECLINE (SOUND_MIXER_LINE + ES_REC_MIXER_RECDIFF)
-#define ES_REC_MIXER_RECMIC (SOUND_MIXER_MIC + ES_REC_MIXER_RECDIFF)
-#define ES_REC_MIXER_RECCD (SOUND_MIXER_CD + ES_REC_MIXER_RECDIFF)
-#define ES_REC_MIXER_RECIMIX (SOUND_MIXER_IMIX + ES_REC_MIXER_RECDIFF)
-#define ES_REC_MIXER_RECALTPCM (SOUND_MIXER_ALTPCM + ES_REC_MIXER_RECDIFF)
-#define ES_REC_MIXER_RECRECLEV (SOUND_MIXER_RECLEV + ES_REC_MIXER_RECDIFF)
-#define ES_REC_MIXER_RECIGAIN (SOUND_MIXER_IGAIN + ES_REC_MIXER_RECDIFF)
-#define ES_REC_MIXER_RECOGAIN (SOUND_MIXER_OGAIN + ES_REC_MIXER_RECDIFF)
-#define ES_REC_MIXER_RECLINE1 (SOUND_MIXER_LINE1 + ES_REC_MIXER_RECDIFF)
-#define ES_REC_MIXER_RECLINE2 (SOUND_MIXER_LINE2 + ES_REC_MIXER_RECDIFF)
-#define ES_REC_MIXER_RECLINE3 (SOUND_MIXER_LINE3 + ES_REC_MIXER_RECDIFF)
-
-static mixer_tab es688_mix = {
-MIX_ENT(SOUND_MIXER_VOLUME, 0x32, 7, 4, 0x32, 3, 4),
-MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4),
-MIX_ENT(SOUND_MIXER_PCM, 0x14, 7, 4, 0x14, 3, 4),
-MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4),
-MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4),
-MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4),
-MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
-MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0)
-};
-
-/*
- * The ES1688 specifics... hopefully correct...
- * - 6 bit master volume
- * I was wrong, ES1888 docs say ES1688 didn't have it.
- * - RECLEV control
- * These may apply to ES688 too. I have no idea.
- */
-static mixer_tab es1688_mix = {
-MIX_ENT(SOUND_MIXER_VOLUME, 0x32, 7, 4, 0x32, 3, 4),
-MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4),
-MIX_ENT(SOUND_MIXER_PCM, 0x14, 7, 4, 0x14, 3, 4),
-MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4),
-MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4),
-MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4),
-MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_RECLEV, 0xb4, 7, 4, 0xb4, 3, 4),
-MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
-MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0)
-};
-
-static mixer_tab es1688later_mix = {
-MIX_ENT(SOUND_MIXER_VOLUME, 0x60, 5, 6, 0x62, 5, 6),
-MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4),
-MIX_ENT(SOUND_MIXER_PCM, 0x14, 7, 4, 0x14, 3, 4),
-MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4),
-MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4),
-MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4),
-MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_RECLEV, 0xb4, 7, 4, 0xb4, 3, 4),
-MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
-MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0)
-};
-
-/*
- * This one is for all ESS chips with a record mixer.
- * It's not used (yet) however
- */
-static mixer_tab es_rec_mix = {
-MIX_ENT(SOUND_MIXER_VOLUME, 0x60, 5, 6, 0x62, 5, 6),
-MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4),
-MIX_ENT(SOUND_MIXER_PCM, 0x14, 7, 4, 0x14, 3, 4),
-MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4),
-MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4),
-MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4),
-MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_RECLEV, 0xb4, 7, 4, 0xb4, 3, 4),
-MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
-MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES_REC_MIXER_RECSYNTH, 0x6b, 7, 4, 0x6b, 3, 4),
-MIX_ENT(ES_REC_MIXER_RECPCM, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES_REC_MIXER_RECSPEAKER, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES_REC_MIXER_RECLINE, 0x6e, 7, 4, 0x6e, 3, 4),
-MIX_ENT(ES_REC_MIXER_RECMIC, 0x68, 7, 4, 0x68, 3, 4),
-MIX_ENT(ES_REC_MIXER_RECCD, 0x6a, 7, 4, 0x6a, 3, 4),
-MIX_ENT(ES_REC_MIXER_RECIMIX, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES_REC_MIXER_RECALTPCM, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES_REC_MIXER_RECRECLEV, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES_REC_MIXER_RECIGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES_REC_MIXER_RECOGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES_REC_MIXER_RECLINE1, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES_REC_MIXER_RECLINE2, 0x6c, 7, 4, 0x6c, 3, 4),
-MIX_ENT(ES_REC_MIXER_RECLINE3, 0x00, 0, 0, 0x00, 0, 0)
-};
-
-/*
- * This one is for ES1887. It's little different from es_rec_mix: it
- * has 0x7c for PCM playback level. This is because ES1887 uses
- * Audio 2 for playback.
- */
-static mixer_tab es1887_mix = {
-MIX_ENT(SOUND_MIXER_VOLUME, 0x60, 5, 6, 0x62, 5, 6),
-MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4),
-MIX_ENT(SOUND_MIXER_PCM, 0x7c, 7, 4, 0x7c, 3, 4),
-MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4),
-MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4),
-MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4),
-MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_RECLEV, 0xb4, 7, 4, 0xb4, 3, 4),
-MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
-MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES_REC_MIXER_RECSYNTH, 0x6b, 7, 4, 0x6b, 3, 4),
-MIX_ENT(ES_REC_MIXER_RECPCM, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES_REC_MIXER_RECSPEAKER, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES_REC_MIXER_RECLINE, 0x6e, 7, 4, 0x6e, 3, 4),
-MIX_ENT(ES_REC_MIXER_RECMIC, 0x68, 7, 4, 0x68, 3, 4),
-MIX_ENT(ES_REC_MIXER_RECCD, 0x6a, 7, 4, 0x6a, 3, 4),
-MIX_ENT(ES_REC_MIXER_RECIMIX, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES_REC_MIXER_RECALTPCM, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES_REC_MIXER_RECRECLEV, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES_REC_MIXER_RECIGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES_REC_MIXER_RECOGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES_REC_MIXER_RECLINE1, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES_REC_MIXER_RECLINE2, 0x6c, 7, 4, 0x6c, 3, 4),
-MIX_ENT(ES_REC_MIXER_RECLINE3, 0x00, 0, 0, 0x00, 0, 0)
-};
-
-static int ess_has_rec_mixer (int submodel)
-{
- switch (submodel) {
- case SUBMDL_ES1887:
- return 1;
- default:
- return 0;
- };
-};
-
-#ifdef FKS_LOGGING
-static int ess_mixer_mon_regs[]
- = { 0x70, 0x71, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7d, 0x7f
- , 0xa1, 0xa2, 0xa4, 0xa5, 0xa8, 0xa9
- , 0xb1, 0xb2, 0xb4, 0xb5, 0xb6, 0xb7, 0xb9
- , 0x00};
-
-static void ess_show_mixerregs (sb_devc *devc)
-{
- int *mp = ess_mixer_mon_regs;
-
-return;
-
- while (*mp != 0) {
- printk (KERN_INFO "res (%x)=%x\n", *mp, (int)(ess_getmixer (devc, *mp)));
- mp++;
- }
-}
-#endif
-
-void ess_setmixer (sb_devc * devc, unsigned int port, unsigned int value)
-{
- unsigned long flags;
-
-#ifdef FKS_LOGGING
-printk(KERN_INFO "FKS: write mixer %x: %x\n", port, value);
-#endif
-
- spin_lock_irqsave(&devc->lock, flags);
- if (port >= 0xa0) {
- ess_write (devc, port, value);
- } else {
- outb(((unsigned char) (port & 0xff)), MIXER_ADDR);
-
- udelay(20);
- outb(((unsigned char) (value & 0xff)), MIXER_DATA);
- udelay(20);
- };
- spin_unlock_irqrestore(&devc->lock, flags);
-}
-
-unsigned int ess_getmixer (sb_devc * devc, unsigned int port)
-{
- unsigned int val;
- unsigned long flags;
-
- spin_lock_irqsave(&devc->lock, flags);
-
- if (port >= 0xa0) {
- val = ess_read (devc, port);
- } else {
- outb(((unsigned char) (port & 0xff)), MIXER_ADDR);
-
- udelay(20);
- val = inb(MIXER_DATA);
- udelay(20);
- }
- spin_unlock_irqrestore(&devc->lock, flags);
-
- return val;
-}
-
-static void ess_chgmixer
- (sb_devc * devc, unsigned int reg, unsigned int mask, unsigned int val)
-{
- int value;
-
- value = ess_getmixer (devc, reg);
- value = (value & ~mask) | (val & mask);
- ess_setmixer (devc, reg, value);
-}
-
-/*
- * ess_mixer_init must be called from sb_mixer_init
- */
-void ess_mixer_init (sb_devc * devc)
-{
- devc->mixer_caps = SOUND_CAP_EXCL_INPUT;
-
- /*
- * Take care of ES1887 specifics...
- */
- switch (devc->submodel) {
- case SUBMDL_ES1887:
- devc->supported_devices = ES1887_MIXER_DEVICES;
- devc->supported_rec_devices = ES1887_RECORDING_DEVICES;
-#ifdef FKS_LOGGING
-printk (KERN_INFO "FKS: ess_mixer_init dup = %d\n", devc->duplex);
-#endif
- if (devc->duplex) {
- devc->iomap = &es1887_mix;
- devc->iomap_sz = ARRAY_SIZE(es1887_mix);
- } else {
- devc->iomap = &es_rec_mix;
- devc->iomap_sz = ARRAY_SIZE(es_rec_mix);
- }
- break;
- default:
- if (devc->submodel < 8) {
- devc->supported_devices = ES688_MIXER_DEVICES;
- devc->supported_rec_devices = ES688_RECORDING_DEVICES;
- devc->iomap = &es688_mix;
- devc->iomap_sz = ARRAY_SIZE(es688_mix);
- } else {
- /*
- * es1688 has 4 bits master vol.
- * later chips have 6 bits (?)
- */
- devc->supported_devices = ES1688_MIXER_DEVICES;
- devc->supported_rec_devices = ES1688_RECORDING_DEVICES;
- if (devc->submodel < 0x10) {
- devc->iomap = &es1688_mix;
- devc->iomap_sz = ARRAY_SIZE(es688_mix);
- } else {
- devc->iomap = &es1688later_mix;
- devc->iomap_sz = ARRAY_SIZE(es1688later_mix);
- }
- }
- }
-}
-
-/*
- * Changing playback levels at an ESS chip with record mixer means having to
- * take care of recording levels of recorded inputs (devc->recmask) too!
- */
-int ess_mixer_set(sb_devc *devc, int dev, int left, int right)
-{
- if (ess_has_rec_mixer (devc->submodel) && (devc->recmask & (1 << dev))) {
- sb_common_mixer_set (devc, dev + ES_REC_MIXER_RECDIFF, left, right);
- }
- return sb_common_mixer_set (devc, dev, left, right);
-}
-
-/*
- * After a sb_dsp_reset extended register 0xb4 (RECLEV) is reset too. After
- * sb_dsp_reset RECLEV has to be restored. This is where ess_mixer_reload
- * helps.
- */
-void ess_mixer_reload (sb_devc *devc, int dev)
-{
- int left, right, value;
-
- value = devc->levels[dev];
- left = value & 0x000000ff;
- right = (value & 0x0000ff00) >> 8;
-
- sb_common_mixer_set(devc, dev, left, right);
-}
-
-static int es_rec_set_recmask(sb_devc * devc, int mask)
-{
- int i, i_mask, cur_mask, diff_mask;
- int value, left, right;
-
-#ifdef FKS_LOGGING
-printk (KERN_INFO "FKS: es_rec_set_recmask mask = %x\n", mask);
-#endif
- /*
- * Changing the recmask on an ESS chip with recording mixer means:
- * (1) Find the differences
- * (2) For "turned-on" inputs: make the recording level the playback level
- * (3) For "turned-off" inputs: make the recording level zero
- */
- cur_mask = devc->recmask;
- diff_mask = (cur_mask ^ mask);
-
- for (i = 0; i < 32; i++) {
- i_mask = (1 << i);
- if (diff_mask & i_mask) { /* Difference? (1) */
- if (mask & i_mask) { /* Turn it on (2) */
- value = devc->levels[i];
- left = value & 0x000000ff;
- right = (value & 0x0000ff00) >> 8;
- } else { /* Turn it off (3) */
- left = 0;
- right = 0;
- }
- sb_common_mixer_set(devc, i + ES_REC_MIXER_RECDIFF, left, right);
- }
- }
- return mask;
-}
-
-int ess_set_recmask(sb_devc * devc, int *mask)
-{
- /* This applies to ESS chips with record mixers only! */
-
- if (ess_has_rec_mixer (devc->submodel)) {
- *mask = es_rec_set_recmask (devc, *mask);
- return 1; /* Applied */
- } else {
- return 0; /* Not applied */
- }
-}
-
-/*
- * ess_mixer_reset must be called from sb_mixer_reset
- */
-int ess_mixer_reset (sb_devc * devc)
-{
- /*
- * Separate actions for ESS chips with a record mixer:
- */
- if (ess_has_rec_mixer (devc->submodel)) {
- switch (devc->submodel) {
- case SUBMDL_ES1887:
- /*
- * Separate actions for ES1887:
- * Change registers 7a and 1c to make the record mixer the
- * actual recording source.
- */
- ess_chgmixer(devc, 0x7a, 0x18, 0x08);
- ess_chgmixer(devc, 0x1c, 0x07, 0x07);
- break;
- };
- /*
- * Call set_recmask for proper initialization
- */
- devc->recmask = devc->supported_rec_devices;
- es_rec_set_recmask(devc, 0);
- devc->recmask = 0;
-
- return 1; /* We took care of recmask. */
- } else {
- return 0; /* We didn't take care; caller do it */
- }
-}
-
-/****************************************************************************
- * *
- * ESS midi *
- * *
- ****************************************************************************/
-
-/*
- * FKS: IRQ may be shared. Hm. And if so? Then What?
- */
-int ess_midi_init(sb_devc * devc, struct address_info *hw_config)
-{
- unsigned char cfg, tmp;
-
- cfg = ess_getmixer (devc, 0x40) & 0x03;
-
- if (devc->submodel < 8) {
- ess_setmixer (devc, 0x40, cfg | 0x03); /* Enable OPL3 & joystick */
- return 0; /* ES688 doesn't support MPU401 mode */
- }
- tmp = (hw_config->io_base & 0x0f0) >> 4;
-
- if (tmp > 3) {
- ess_setmixer (devc, 0x40, cfg);
- return 0;
- }
- cfg |= tmp << 3;
-
- tmp = 1; /* MPU enabled without interrupts */
-
- /* May be shared: if so the value is -ve */
-
- switch (abs(hw_config->irq)) {
- case 9:
- tmp = 0x4;
- break;
- case 5:
- tmp = 0x5;
- break;
- case 7:
- tmp = 0x6;
- break;
- case 10:
- tmp = 0x7;
- break;
- default:
- return 0;
- }
-
- cfg |= tmp << 5;
- ess_setmixer (devc, 0x40, cfg | 0x03);
-
- return 1;
-}
-
diff --git a/ANDROID_3.4.5/sound/oss/sb_ess.h b/ANDROID_3.4.5/sound/oss/sb_ess.h
deleted file mode 100644
index 38aa072e..00000000
--- a/ANDROID_3.4.5/sound/oss/sb_ess.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Created: 9-Jan-1999 Rolf Fokkens
- */
-
-extern void ess_intr
- (sb_devc *devc);
-extern int ess_dsp_init
- (sb_devc *devc, struct address_info *hw_config);
-
-extern struct audio_driver *ess_audio_init
- (sb_devc *devc, int *audio_flags, int *format_mask);
-extern int ess_midi_init
- (sb_devc *devc, struct address_info *hw_config);
-extern void ess_mixer_init
- (sb_devc *devc);
-
-extern int ess_init
- (sb_devc *devc, struct address_info *hw_config);
-extern int ess_dsp_reset
- (sb_devc *devc);
-
-extern void ess_setmixer
- (sb_devc *devc, unsigned int port, unsigned int value);
-extern unsigned int ess_getmixer
- (sb_devc *devc, unsigned int port);
-extern int ess_mixer_set
- (sb_devc *devc, int dev, int left, int right);
-extern int ess_mixer_reset
- (sb_devc *devc);
-extern void ess_mixer_reload
- (sb_devc * devc, int dev);
-extern int ess_set_recmask
- (sb_devc *devc, int *mask);
-
diff --git a/ANDROID_3.4.5/sound/oss/sb_midi.c b/ANDROID_3.4.5/sound/oss/sb_midi.c
deleted file mode 100644
index f139028e..00000000
--- a/ANDROID_3.4.5/sound/oss/sb_midi.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * sound/oss/sb_midi.c
- *
- * The low level driver for the Sound Blaster DS chips.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-
-#include "sound_config.h"
-
-#include "sb.h"
-#undef SB_TEST_IRQ
-
-/*
- * The DSP channel can be used either for input or output. Variable
- * 'sb_irq_mode' will be set when the program calls read or write first time
- * after open. Current version doesn't support mode changes without closing
- * and reopening the device. Support for this feature may be implemented in a
- * future version of this driver.
- */
-
-
-static int sb_midi_open(int dev, int mode,
- void (*input) (int dev, unsigned char data),
- void (*output) (int dev)
-)
-{
- sb_devc *devc = midi_devs[dev]->devc;
- unsigned long flags;
-
- if (devc == NULL)
- return -ENXIO;
-
- spin_lock_irqsave(&devc->lock, flags);
- if (devc->opened)
- {
- spin_unlock_irqrestore(&devc->lock, flags);
- return -EBUSY;
- }
- devc->opened = 1;
- spin_unlock_irqrestore(&devc->lock, flags);
-
- devc->irq_mode = IMODE_MIDI;
- devc->midi_broken = 0;
-
- sb_dsp_reset(devc);
-
- if (!sb_dsp_command(devc, 0x35)) /* Start MIDI UART mode */
- {
- devc->opened = 0;
- return -EIO;
- }
- devc->intr_active = 1;
-
- if (mode & OPEN_READ)
- {
- devc->input_opened = 1;
- devc->midi_input_intr = input;
- }
- return 0;
-}
-
-static void sb_midi_close(int dev)
-{
- sb_devc *devc = midi_devs[dev]->devc;
- unsigned long flags;
-
- if (devc == NULL)
- return;
-
- spin_lock_irqsave(&devc->lock, flags);
- sb_dsp_reset(devc);
- devc->intr_active = 0;
- devc->input_opened = 0;
- devc->opened = 0;
- spin_unlock_irqrestore(&devc->lock, flags);
-}
-
-static int sb_midi_out(int dev, unsigned char midi_byte)
-{
- sb_devc *devc = midi_devs[dev]->devc;
-
- if (devc == NULL)
- return 1;
-
- if (devc->midi_broken)
- return 1;
-
- if (!sb_dsp_command(devc, midi_byte))
- {
- devc->midi_broken = 1;
- return 1;
- }
- return 1;
-}
-
-static int sb_midi_start_read(int dev)
-{
- return 0;
-}
-
-static int sb_midi_end_read(int dev)
-{
- sb_devc *devc = midi_devs[dev]->devc;
-
- if (devc == NULL)
- return -ENXIO;
-
- sb_dsp_reset(devc);
- devc->intr_active = 0;
- return 0;
-}
-
-static int sb_midi_ioctl(int dev, unsigned cmd, void __user *arg)
-{
- return -EINVAL;
-}
-
-void sb_midi_interrupt(sb_devc * devc)
-{
- unsigned long flags;
- unsigned char data;
-
- if (devc == NULL)
- return;
-
- spin_lock_irqsave(&devc->lock, flags);
-
- data = inb(DSP_READ);
- if (devc->input_opened)
- devc->midi_input_intr(devc->my_mididev, data);
-
- spin_unlock_irqrestore(&devc->lock, flags);
-}
-
-#define MIDI_SYNTH_NAME "Sound Blaster Midi"
-#define MIDI_SYNTH_CAPS 0
-#include "midi_synth.h"
-
-static struct midi_operations sb_midi_operations =
-{
- .owner = THIS_MODULE,
- .info = {"Sound Blaster", 0, 0, SNDCARD_SB},
- .converter = &std_midi_synth,
- .in_info = {0},
- .open = sb_midi_open,
- .close = sb_midi_close,
- .ioctl = sb_midi_ioctl,
- .outputc = sb_midi_out,
- .start_read = sb_midi_start_read,
- .end_read = sb_midi_end_read,
-};
-
-void sb_dsp_midi_init(sb_devc * devc, struct module *owner)
-{
- int dev;
-
- if (devc->model < 2) /* No MIDI support for SB 1.x */
- return;
-
- dev = sound_alloc_mididev();
-
- if (dev == -1)
- {
- printk(KERN_ERR "sb_midi: too many MIDI devices detected\n");
- return;
- }
- std_midi_synth.midi_dev = devc->my_mididev = dev;
- midi_devs[dev] = kmalloc(sizeof(struct midi_operations), GFP_KERNEL);
- if (midi_devs[dev] == NULL)
- {
- printk(KERN_WARNING "Sound Blaster: failed to allocate MIDI memory.\n");
- sound_unload_mididev(dev);
- return;
- }
- memcpy((char *) midi_devs[dev], (char *) &sb_midi_operations,
- sizeof(struct midi_operations));
-
- if (owner)
- midi_devs[dev]->owner = owner;
-
- midi_devs[dev]->devc = devc;
-
-
- midi_devs[dev]->converter = kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
- if (midi_devs[dev]->converter == NULL)
- {
- printk(KERN_WARNING "Sound Blaster: failed to allocate MIDI memory.\n");
- kfree(midi_devs[dev]);
- sound_unload_mididev(dev);
- return;
- }
- memcpy((char *) midi_devs[dev]->converter, (char *) &std_midi_synth,
- sizeof(struct synth_operations));
-
- midi_devs[dev]->converter->id = "SBMIDI";
- sequencer_init();
-}
diff --git a/ANDROID_3.4.5/sound/oss/sb_mixer.c b/ANDROID_3.4.5/sound/oss/sb_mixer.c
deleted file mode 100644
index f8f3b7a6..00000000
--- a/ANDROID_3.4.5/sound/oss/sb_mixer.c
+++ /dev/null
@@ -1,770 +0,0 @@
-/*
- * sound/oss/sb_mixer.c
- *
- * The low level mixer driver for the Sound Blaster compatible cards.
- */
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- *
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
- * Rolf Fokkens (Dec 20 1998) : Moved ESS stuff into sb_ess.[ch]
- * Stanislav Voronyi <stas@esc.kharkov.com> : Support for AWE 3DSE device (Jun 7 1999)
- */
-
-#include <linux/slab.h>
-
-#include "sound_config.h"
-
-#define __SB_MIXER_C__
-
-#include "sb.h"
-#include "sb_mixer.h"
-
-#include "sb_ess.h"
-
-#define SBPRO_RECORDING_DEVICES (SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD)
-
-/* Same as SB Pro, unless I find otherwise */
-#define SGNXPRO_RECORDING_DEVICES SBPRO_RECORDING_DEVICES
-
-#define SBPRO_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_LINE | SOUND_MASK_MIC | \
- SOUND_MASK_CD | SOUND_MASK_VOLUME)
-
-/* SG NX Pro has treble and bass settings on the mixer. The 'speaker'
- * channel is the COVOX/DisneySoundSource emulation volume control
- * on the mixer. It does NOT control speaker volume. Should have own
- * mask eventually?
- */
-#define SGNXPRO_MIXER_DEVICES (SBPRO_MIXER_DEVICES|SOUND_MASK_BASS| \
- SOUND_MASK_TREBLE|SOUND_MASK_SPEAKER )
-
-#define SB16_RECORDING_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_LINE | SOUND_MASK_MIC | \
- SOUND_MASK_CD)
-
-#define SB16_OUTFILTER_DEVICES (SOUND_MASK_LINE | SOUND_MASK_MIC | \
- SOUND_MASK_CD)
-
-#define SB16_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_SPEAKER | SOUND_MASK_LINE | SOUND_MASK_MIC | \
- SOUND_MASK_CD | \
- SOUND_MASK_IGAIN | SOUND_MASK_OGAIN | \
- SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | \
- SOUND_MASK_IMIX)
-
-/* These are the only devices that are working at the moment. Others could
- * be added once they are identified and a method is found to control them.
- */
-#define ALS007_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_LINE | \
- SOUND_MASK_PCM | SOUND_MASK_MIC | \
- SOUND_MASK_CD | \
- SOUND_MASK_VOLUME)
-
-static mixer_tab sbpro_mix = {
-MIX_ENT(SOUND_MIXER_VOLUME, 0x22, 7, 4, 0x22, 3, 4),
-MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_SYNTH, 0x26, 7, 4, 0x26, 3, 4),
-MIX_ENT(SOUND_MIXER_PCM, 0x04, 7, 4, 0x04, 3, 4),
-MIX_ENT(SOUND_MIXER_SPEAKER, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE, 0x2e, 7, 4, 0x2e, 3, 4),
-MIX_ENT(SOUND_MIXER_MIC, 0x0a, 2, 3, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_CD, 0x28, 7, 4, 0x28, 3, 4),
-MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0)
-};
-
-static mixer_tab sb16_mix = {
-MIX_ENT(SOUND_MIXER_VOLUME, 0x30, 7, 5, 0x31, 7, 5),
-MIX_ENT(SOUND_MIXER_BASS, 0x46, 7, 4, 0x47, 7, 4),
-MIX_ENT(SOUND_MIXER_TREBLE, 0x44, 7, 4, 0x45, 7, 4),
-MIX_ENT(SOUND_MIXER_SYNTH, 0x34, 7, 5, 0x35, 7, 5),
-MIX_ENT(SOUND_MIXER_PCM, 0x32, 7, 5, 0x33, 7, 5),
-MIX_ENT(SOUND_MIXER_SPEAKER, 0x3b, 7, 2, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE, 0x38, 7, 5, 0x39, 7, 5),
-MIX_ENT(SOUND_MIXER_MIC, 0x3a, 7, 5, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_CD, 0x36, 7, 5, 0x37, 7, 5),
-MIX_ENT(SOUND_MIXER_IMIX, 0x3c, 0, 1, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_RECLEV, 0x3f, 7, 2, 0x40, 7, 2), /* Obsolete. Use IGAIN */
-MIX_ENT(SOUND_MIXER_IGAIN, 0x3f, 7, 2, 0x40, 7, 2),
-MIX_ENT(SOUND_MIXER_OGAIN, 0x41, 7, 2, 0x42, 7, 2)
-};
-
-static mixer_tab als007_mix =
-{
-MIX_ENT(SOUND_MIXER_VOLUME, 0x62, 7, 4, 0x62, 3, 4),
-MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_SYNTH, 0x66, 7, 4, 0x66, 3, 4),
-MIX_ENT(SOUND_MIXER_PCM, 0x64, 7, 4, 0x64, 3, 4),
-MIX_ENT(SOUND_MIXER_SPEAKER, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE, 0x6e, 7, 4, 0x6e, 3, 4),
-MIX_ENT(SOUND_MIXER_MIC, 0x6a, 2, 3, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_CD, 0x68, 7, 4, 0x68, 3, 4),
-MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0), /* Obsolete. Use IGAIN */
-MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0)
-};
-
-
-/* SM_GAMES Master volume is lower and PCM & FM volumes
- higher than with SB Pro. This improves the
- sound quality */
-
-static int smg_default_levels[32] =
-{
- 0x2020, /* Master Volume */
- 0x4b4b, /* Bass */
- 0x4b4b, /* Treble */
- 0x6464, /* FM */
- 0x6464, /* PCM */
- 0x4b4b, /* PC Speaker */
- 0x4b4b, /* Ext Line */
- 0x0000, /* Mic */
- 0x4b4b, /* CD */
- 0x4b4b, /* Recording monitor */
- 0x4b4b, /* SB PCM */
- 0x4b4b, /* Recording level */
- 0x4b4b, /* Input gain */
- 0x4b4b, /* Output gain */
- 0x4040, /* Line1 */
- 0x4040, /* Line2 */
- 0x1515 /* Line3 */
-};
-
-static int sb_default_levels[32] =
-{
- 0x5a5a, /* Master Volume */
- 0x4b4b, /* Bass */
- 0x4b4b, /* Treble */
- 0x4b4b, /* FM */
- 0x4b4b, /* PCM */
- 0x4b4b, /* PC Speaker */
- 0x4b4b, /* Ext Line */
- 0x1010, /* Mic */
- 0x4b4b, /* CD */
- 0x0000, /* Recording monitor */
- 0x4b4b, /* SB PCM */
- 0x4b4b, /* Recording level */
- 0x4b4b, /* Input gain */
- 0x4b4b, /* Output gain */
- 0x4040, /* Line1 */
- 0x4040, /* Line2 */
- 0x1515 /* Line3 */
-};
-
-static unsigned char sb16_recmasks_L[SOUND_MIXER_NRDEVICES] =
-{
- 0x00, /* SOUND_MIXER_VOLUME */
- 0x00, /* SOUND_MIXER_BASS */
- 0x00, /* SOUND_MIXER_TREBLE */
- 0x40, /* SOUND_MIXER_SYNTH */
- 0x00, /* SOUND_MIXER_PCM */
- 0x00, /* SOUND_MIXER_SPEAKER */
- 0x10, /* SOUND_MIXER_LINE */
- 0x01, /* SOUND_MIXER_MIC */
- 0x04, /* SOUND_MIXER_CD */
- 0x00, /* SOUND_MIXER_IMIX */
- 0x00, /* SOUND_MIXER_ALTPCM */
- 0x00, /* SOUND_MIXER_RECLEV */
- 0x00, /* SOUND_MIXER_IGAIN */
- 0x00 /* SOUND_MIXER_OGAIN */
-};
-
-static unsigned char sb16_recmasks_R[SOUND_MIXER_NRDEVICES] =
-{
- 0x00, /* SOUND_MIXER_VOLUME */
- 0x00, /* SOUND_MIXER_BASS */
- 0x00, /* SOUND_MIXER_TREBLE */
- 0x20, /* SOUND_MIXER_SYNTH */
- 0x00, /* SOUND_MIXER_PCM */
- 0x00, /* SOUND_MIXER_SPEAKER */
- 0x08, /* SOUND_MIXER_LINE */
- 0x01, /* SOUND_MIXER_MIC */
- 0x02, /* SOUND_MIXER_CD */
- 0x00, /* SOUND_MIXER_IMIX */
- 0x00, /* SOUND_MIXER_ALTPCM */
- 0x00, /* SOUND_MIXER_RECLEV */
- 0x00, /* SOUND_MIXER_IGAIN */
- 0x00 /* SOUND_MIXER_OGAIN */
-};
-
-static char smw_mix_regs[] = /* Left mixer registers */
-{
- 0x0b, /* SOUND_MIXER_VOLUME */
- 0x0d, /* SOUND_MIXER_BASS */
- 0x0d, /* SOUND_MIXER_TREBLE */
- 0x05, /* SOUND_MIXER_SYNTH */
- 0x09, /* SOUND_MIXER_PCM */
- 0x00, /* SOUND_MIXER_SPEAKER */
- 0x03, /* SOUND_MIXER_LINE */
- 0x01, /* SOUND_MIXER_MIC */
- 0x07, /* SOUND_MIXER_CD */
- 0x00, /* SOUND_MIXER_IMIX */
- 0x00, /* SOUND_MIXER_ALTPCM */
- 0x00, /* SOUND_MIXER_RECLEV */
- 0x00, /* SOUND_MIXER_IGAIN */
- 0x00, /* SOUND_MIXER_OGAIN */
- 0x00, /* SOUND_MIXER_LINE1 */
- 0x00, /* SOUND_MIXER_LINE2 */
- 0x00 /* SOUND_MIXER_LINE3 */
-};
-
-static int sbmixnum = 1;
-
-static void sb_mixer_reset(sb_devc * devc);
-
-void sb_mixer_set_stereo(sb_devc * devc, int mode)
-{
- sb_chgmixer(devc, OUT_FILTER, STEREO_DAC, (mode ? STEREO_DAC : MONO_DAC));
-}
-
-static int detect_mixer(sb_devc * devc)
-{
- /* Just trust the mixer is there */
- return 1;
-}
-
-static void oss_change_bits(sb_devc *devc, unsigned char *regval, int dev, int chn, int newval)
-{
- unsigned char mask;
- int shift;
-
- mask = (1 << (*devc->iomap)[dev][chn].nbits) - 1;
- newval = (int) ((newval * mask) + 50) / 100; /* Scale */
-
- shift = (*devc->iomap)[dev][chn].bitoffs - (*devc->iomap)[dev][LEFT_CHN].nbits + 1;
-
- *regval &= ~(mask << shift); /* Mask out previous value */
- *regval |= (newval & mask) << shift; /* Set the new value */
-}
-
-static int sb_mixer_get(sb_devc * devc, int dev)
-{
- if (!((1 << dev) & devc->supported_devices))
- return -EINVAL;
- return devc->levels[dev];
-}
-
-void smw_mixer_init(sb_devc * devc)
-{
- int i;
-
- sb_setmixer(devc, 0x00, 0x18); /* Mute unused (Telephone) line */
- sb_setmixer(devc, 0x10, 0x38); /* Config register 2 */
-
- devc->supported_devices = 0;
- for (i = 0; i < sizeof(smw_mix_regs); i++)
- if (smw_mix_regs[i] != 0)
- devc->supported_devices |= (1 << i);
-
- devc->supported_rec_devices = devc->supported_devices &
- ~(SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_PCM | SOUND_MASK_VOLUME);
- sb_mixer_reset(devc);
-}
-
-int sb_common_mixer_set(sb_devc * devc, int dev, int left, int right)
-{
- int regoffs;
- unsigned char val;
-
- if ((dev < 0) || (dev >= devc->iomap_sz))
- return -EINVAL;
-
- regoffs = (*devc->iomap)[dev][LEFT_CHN].regno;
-
- if (regoffs == 0)
- return -EINVAL;
-
- val = sb_getmixer(devc, regoffs);
- oss_change_bits(devc, &val, dev, LEFT_CHN, left);
-
- if ((*devc->iomap)[dev][RIGHT_CHN].regno != regoffs) /*
- * Change register
- */
- {
- sb_setmixer(devc, regoffs, val); /*
- * Save the old one
- */
- regoffs = (*devc->iomap)[dev][RIGHT_CHN].regno;
-
- if (regoffs == 0)
- return left | (left << 8); /*
- * Just left channel present
- */
-
- val = sb_getmixer(devc, regoffs); /*
- * Read the new one
- */
- }
- oss_change_bits(devc, &val, dev, RIGHT_CHN, right);
-
- sb_setmixer(devc, regoffs, val);
-
- return left | (right << 8);
-}
-
-static int smw_mixer_set(sb_devc * devc, int dev, int left, int right)
-{
- int reg, val;
-
- switch (dev)
- {
- case SOUND_MIXER_VOLUME:
- sb_setmixer(devc, 0x0b, 96 - (96 * left / 100)); /* 96=mute, 0=max */
- sb_setmixer(devc, 0x0c, 96 - (96 * right / 100));
- break;
-
- case SOUND_MIXER_BASS:
- case SOUND_MIXER_TREBLE:
- devc->levels[dev] = left | (right << 8);
- /* Set left bass and treble values */
- val = ((devc->levels[SOUND_MIXER_TREBLE] & 0xff) * 16 / (unsigned) 100) << 4;
- val |= ((devc->levels[SOUND_MIXER_BASS] & 0xff) * 16 / (unsigned) 100) & 0x0f;
- sb_setmixer(devc, 0x0d, val);
-
- /* Set right bass and treble values */
- val = (((devc->levels[SOUND_MIXER_TREBLE] >> 8) & 0xff) * 16 / (unsigned) 100) << 4;
- val |= (((devc->levels[SOUND_MIXER_BASS] >> 8) & 0xff) * 16 / (unsigned) 100) & 0x0f;
- sb_setmixer(devc, 0x0e, val);
-
- break;
-
- default:
- /* bounds check */
- if (dev < 0 || dev >= ARRAY_SIZE(smw_mix_regs))
- return -EINVAL;
- reg = smw_mix_regs[dev];
- if (reg == 0)
- return -EINVAL;
- sb_setmixer(devc, reg, (24 - (24 * left / 100)) | 0x20); /* 24=mute, 0=max */
- sb_setmixer(devc, reg + 1, (24 - (24 * right / 100)) | 0x40);
- }
-
- devc->levels[dev] = left | (right << 8);
- return left | (right << 8);
-}
-
-static int sb_mixer_set(sb_devc * devc, int dev, int value)
-{
- int left = value & 0x000000ff;
- int right = (value & 0x0000ff00) >> 8;
- int retval;
-
- if (left > 100)
- left = 100;
- if (right > 100)
- right = 100;
-
- if ((dev < 0) || (dev > 31))
- return -EINVAL;
-
- if (!(devc->supported_devices & (1 << dev))) /*
- * Not supported
- */
- return -EINVAL;
-
- /* Differentiate depending on the chipsets */
- switch (devc->model) {
- case MDL_SMW:
- retval = smw_mixer_set(devc, dev, left, right);
- break;
- case MDL_ESS:
- retval = ess_mixer_set(devc, dev, left, right);
- break;
- default:
- retval = sb_common_mixer_set(devc, dev, left, right);
- }
- if (retval >= 0) devc->levels[dev] = retval;
-
- return retval;
-}
-
-/*
- * set_recsrc doesn't apply to ES188x
- */
-static void set_recsrc(sb_devc * devc, int src)
-{
- sb_setmixer(devc, RECORD_SRC, (sb_getmixer(devc, RECORD_SRC) & ~7) | (src & 0x7));
-}
-
-static int set_recmask(sb_devc * devc, int mask)
-{
- int devmask, i;
- unsigned char regimageL, regimageR;
-
- devmask = mask & devc->supported_rec_devices;
-
- switch (devc->model)
- {
- case MDL_SBPRO:
- case MDL_ESS:
- case MDL_JAZZ:
- case MDL_SMW:
- if (devc->model == MDL_ESS && ess_set_recmask (devc, &devmask)) {
- break;
- };
- if (devmask != SOUND_MASK_MIC &&
- devmask != SOUND_MASK_LINE &&
- devmask != SOUND_MASK_CD)
- {
- /*
- * More than one device selected. Drop the
- * previous selection
- */
- devmask &= ~devc->recmask;
- }
- if (devmask != SOUND_MASK_MIC &&
- devmask != SOUND_MASK_LINE &&
- devmask != SOUND_MASK_CD)
- {
- /*
- * More than one device selected. Default to
- * mic
- */
- devmask = SOUND_MASK_MIC;
- }
- if (devmask ^ devc->recmask) /*
- * Input source changed
- */
- {
- switch (devmask)
- {
- case SOUND_MASK_MIC:
- set_recsrc(devc, SRC__MIC);
- break;
-
- case SOUND_MASK_LINE:
- set_recsrc(devc, SRC__LINE);
- break;
-
- case SOUND_MASK_CD:
- set_recsrc(devc, SRC__CD);
- break;
-
- default:
- set_recsrc(devc, SRC__MIC);
- }
- }
- break;
-
- case MDL_SB16:
- if (!devmask)
- devmask = SOUND_MASK_MIC;
-
- if (devc->submodel == SUBMDL_ALS007)
- {
- switch (devmask)
- {
- case SOUND_MASK_LINE:
- sb_setmixer(devc, ALS007_RECORD_SRC, ALS007_LINE);
- break;
- case SOUND_MASK_CD:
- sb_setmixer(devc, ALS007_RECORD_SRC, ALS007_CD);
- break;
- case SOUND_MASK_SYNTH:
- sb_setmixer(devc, ALS007_RECORD_SRC, ALS007_SYNTH);
- break;
- default: /* Also takes care of SOUND_MASK_MIC case */
- sb_setmixer(devc, ALS007_RECORD_SRC, ALS007_MIC);
- break;
- }
- }
- else
- {
- regimageL = regimageR = 0;
- for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
- {
- if ((1 << i) & devmask)
- {
- regimageL |= sb16_recmasks_L[i];
- regimageR |= sb16_recmasks_R[i];
- }
- sb_setmixer (devc, SB16_IMASK_L, regimageL);
- sb_setmixer (devc, SB16_IMASK_R, regimageR);
- }
- }
- break;
- }
- devc->recmask = devmask;
- return devc->recmask;
-}
-
-static int set_outmask(sb_devc * devc, int mask)
-{
- int devmask, i;
- unsigned char regimage;
-
- devmask = mask & devc->supported_out_devices;
-
- switch (devc->model)
- {
- case MDL_SB16:
- if (devc->submodel == SUBMDL_ALS007)
- break;
- else
- {
- regimage = 0;
- for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
- {
- if ((1 << i) & devmask)
- {
- regimage |= (sb16_recmasks_L[i] | sb16_recmasks_R[i]);
- }
- sb_setmixer (devc, SB16_OMASK, regimage);
- }
- }
- break;
- default:
- break;
- }
-
- devc->outmask = devmask;
- return devc->outmask;
-}
-
-static int sb_mixer_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
- sb_devc *devc = mixer_devs[dev]->devc;
- int val, ret;
- int __user *p = arg;
-
- /*
- * Use ioctl(fd, SOUND_MIXER_AGC, &mode) to turn AGC off (0) or on (1).
- * Use ioctl(fd, SOUND_MIXER_3DSE, &mode) to turn 3DSE off (0) or on (1)
- * or mode==2 put 3DSE state to mode.
- */
- if (devc->model == MDL_SB16) {
- if (cmd == SOUND_MIXER_AGC)
- {
- if (get_user(val, p))
- return -EFAULT;
- sb_setmixer(devc, 0x43, (~val) & 0x01);
- return 0;
- }
- if (cmd == SOUND_MIXER_3DSE)
- {
- /* I put here 15, but I don't know the exact version.
- At least my 4.13 havn't 3DSE, 4.16 has it. */
- if (devc->minor < 15)
- return -EINVAL;
- if (get_user(val, p))
- return -EFAULT;
- if (val == 0 || val == 1)
- sb_chgmixer(devc, AWE_3DSE, 0x01, val);
- else if (val == 2)
- {
- ret = sb_getmixer(devc, AWE_3DSE)&0x01;
- return put_user(ret, p);
- }
- else
- return -EINVAL;
- return 0;
- }
- }
- if (((cmd >> 8) & 0xff) == 'M')
- {
- if (_SIOC_DIR(cmd) & _SIOC_WRITE)
- {
- if (get_user(val, p))
- return -EFAULT;
- switch (cmd & 0xff)
- {
- case SOUND_MIXER_RECSRC:
- ret = set_recmask(devc, val);
- break;
-
- case SOUND_MIXER_OUTSRC:
- ret = set_outmask(devc, val);
- break;
-
- default:
- ret = sb_mixer_set(devc, cmd & 0xff, val);
- }
- }
- else switch (cmd & 0xff)
- {
- case SOUND_MIXER_RECSRC:
- ret = devc->recmask;
- break;
-
- case SOUND_MIXER_OUTSRC:
- ret = devc->outmask;
- break;
-
- case SOUND_MIXER_DEVMASK:
- ret = devc->supported_devices;
- break;
-
- case SOUND_MIXER_STEREODEVS:
- ret = devc->supported_devices;
- /* The ESS seems to have stereo mic controls */
- if (devc->model == MDL_ESS)
- ret &= ~(SOUND_MASK_SPEAKER|SOUND_MASK_IMIX);
- else if (devc->model != MDL_JAZZ && devc->model != MDL_SMW)
- ret &= ~(SOUND_MASK_MIC | SOUND_MASK_SPEAKER | SOUND_MASK_IMIX);
- break;
-
- case SOUND_MIXER_RECMASK:
- ret = devc->supported_rec_devices;
- break;
-
- case SOUND_MIXER_OUTMASK:
- ret = devc->supported_out_devices;
- break;
-
- case SOUND_MIXER_CAPS:
- ret = devc->mixer_caps;
- break;
-
- default:
- ret = sb_mixer_get(devc, cmd & 0xff);
- break;
- }
- return put_user(ret, p);
- } else
- return -EINVAL;
-}
-
-static struct mixer_operations sb_mixer_operations =
-{
- .owner = THIS_MODULE,
- .id = "SB",
- .name = "Sound Blaster",
- .ioctl = sb_mixer_ioctl
-};
-
-static struct mixer_operations als007_mixer_operations =
-{
- .owner = THIS_MODULE,
- .id = "ALS007",
- .name = "Avance ALS-007",
- .ioctl = sb_mixer_ioctl
-};
-
-static void sb_mixer_reset(sb_devc * devc)
-{
- char name[32];
- int i;
-
- sprintf(name, "SB_%d", devc->sbmixnum);
-
- if (devc->sbmo.sm_games)
- devc->levels = load_mixer_volumes(name, smg_default_levels, 1);
- else
- devc->levels = load_mixer_volumes(name, sb_default_levels, 1);
-
- for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
- sb_mixer_set(devc, i, devc->levels[i]);
-
- if (devc->model != MDL_ESS || !ess_mixer_reset (devc)) {
- set_recmask(devc, SOUND_MASK_MIC);
- };
-}
-
-int sb_mixer_init(sb_devc * devc, struct module *owner)
-{
- int mixer_type = 0;
- int m;
-
- devc->sbmixnum = sbmixnum++;
- devc->levels = NULL;
-
- sb_setmixer(devc, 0x00, 0); /* Reset mixer */
-
- if (!(mixer_type = detect_mixer(devc)))
- return 0; /* No mixer. Why? */
-
- switch (devc->model)
- {
- case MDL_ESSPCI:
- case MDL_YMPCI:
- case MDL_SBPRO:
- case MDL_AZTECH:
- case MDL_JAZZ:
- devc->mixer_caps = SOUND_CAP_EXCL_INPUT;
- devc->supported_devices = SBPRO_MIXER_DEVICES;
- devc->supported_rec_devices = SBPRO_RECORDING_DEVICES;
- devc->iomap = &sbpro_mix;
- devc->iomap_sz = ARRAY_SIZE(sbpro_mix);
- break;
-
- case MDL_ESS:
- ess_mixer_init (devc);
- break;
-
- case MDL_SMW:
- devc->mixer_caps = SOUND_CAP_EXCL_INPUT;
- devc->supported_devices = 0;
- devc->supported_rec_devices = 0;
- devc->iomap = &sbpro_mix;
- devc->iomap_sz = ARRAY_SIZE(sbpro_mix);
- smw_mixer_init(devc);
- break;
-
- case MDL_SB16:
- devc->mixer_caps = 0;
- devc->supported_rec_devices = SB16_RECORDING_DEVICES;
- devc->supported_out_devices = SB16_OUTFILTER_DEVICES;
- if (devc->submodel != SUBMDL_ALS007)
- {
- devc->supported_devices = SB16_MIXER_DEVICES;
- devc->iomap = &sb16_mix;
- devc->iomap_sz = ARRAY_SIZE(sb16_mix);
- }
- else
- {
- devc->supported_devices = ALS007_MIXER_DEVICES;
- devc->iomap = &als007_mix;
- devc->iomap_sz = ARRAY_SIZE(als007_mix);
- }
- break;
-
- default:
- printk(KERN_WARNING "sb_mixer: Unsupported mixer type %d\n", devc->model);
- return 0;
- }
-
- m = sound_alloc_mixerdev();
- if (m == -1)
- return 0;
-
- mixer_devs[m] = kmalloc(sizeof(struct mixer_operations), GFP_KERNEL);
- if (mixer_devs[m] == NULL)
- {
- printk(KERN_ERR "sb_mixer: Can't allocate memory\n");
- sound_unload_mixerdev(m);
- return 0;
- }
-
- if (devc->submodel != SUBMDL_ALS007)
- memcpy ((char *) mixer_devs[m], (char *) &sb_mixer_operations, sizeof (struct mixer_operations));
- else
- memcpy ((char *) mixer_devs[m], (char *) &als007_mixer_operations, sizeof (struct mixer_operations));
-
- mixer_devs[m]->devc = devc;
-
- if (owner)
- mixer_devs[m]->owner = owner;
-
- devc->my_mixerdev = m;
- sb_mixer_reset(devc);
- return 1;
-}
-
-void sb_mixer_unload(sb_devc *devc)
-{
- if (devc->my_mixerdev == -1)
- return;
-
- kfree(mixer_devs[devc->my_mixerdev]);
- sound_unload_mixerdev(devc->my_mixerdev);
- sbmixnum--;
-}
diff --git a/ANDROID_3.4.5/sound/oss/sb_mixer.h b/ANDROID_3.4.5/sound/oss/sb_mixer.h
deleted file mode 100644
index 4b9425f0..00000000
--- a/ANDROID_3.4.5/sound/oss/sb_mixer.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * sound/oss/sb_mixer.h
- *
- * Definitions for the SB Pro and SB16 mixers
- */
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-
-/*
- * Modified:
- * Hunyue Yau Jan 6 1994
- * Added defines for the Sound Galaxy NX Pro mixer.
- *
- * Rolf Fokkens Dec 20 1998
- * Added defines for some ES188x chips.
- *
- * Rolf Fokkens Dec 27 1998
- * Moved static stuff to sb_mixer.c
- *
- */
-/*
- * Mixer registers
- *
- * NOTE! RECORD_SRC == IN_FILTER
- */
-
-/*
- * Mixer registers of SB Pro
- */
-#define VOC_VOL 0x04
-#define MIC_VOL 0x0A
-#define MIC_MIX 0x0A
-#define RECORD_SRC 0x0C
-#define IN_FILTER 0x0C
-#define OUT_FILTER 0x0E
-#define MASTER_VOL 0x22
-#define FM_VOL 0x26
-#define CD_VOL 0x28
-#define LINE_VOL 0x2E
-#define IRQ_NR 0x80
-#define DMA_NR 0x81
-#define IRQ_STAT 0x82
-#define OPSW 0x3c
-
-/*
- * Additional registers on the SG NX Pro
- */
-#define COVOX_VOL 0x42
-#define TREBLE_LVL 0x44
-#define BASS_LVL 0x46
-
-#define FREQ_HI (1 << 3)/* Use High-frequency ANFI filters */
-#define FREQ_LOW 0 /* Use Low-frequency ANFI filters */
-#define FILT_ON 0 /* Yes, 0 to turn it on, 1 for off */
-#define FILT_OFF (1 << 5)
-
-#define MONO_DAC 0x00
-#define STEREO_DAC 0x02
-
-/*
- * Mixer registers of SB16
- */
-#define SB16_OMASK 0x3c
-#define SB16_IMASK_L 0x3d
-#define SB16_IMASK_R 0x3e
-
-#define LEFT_CHN 0
-#define RIGHT_CHN 1
-
-/*
- * 3DSE register of AWE32/64
- */
-#define AWE_3DSE 0x90
-
-/*
- * Mixer registers of ALS007
- */
-#define ALS007_RECORD_SRC 0x6c
-#define ALS007_OUTPUT_CTRL1 0x3c
-#define ALS007_OUTPUT_CTRL2 0x4c
-
-#define MIX_ENT(name, reg_l, bit_l, len_l, reg_r, bit_r, len_r) \
- {{reg_l, bit_l, len_l}, {reg_r, bit_r, len_r}}
-
-/*
- * Recording sources (SB Pro)
- */
-
-#define SRC__MIC 1 /* Select Microphone recording source */
-#define SRC__CD 3 /* Select CD recording source */
-#define SRC__LINE 7 /* Use Line-in for recording source */
-
-/*
- * Recording sources for ALS-007
- */
-
-#define ALS007_MIC 4
-#define ALS007_LINE 6
-#define ALS007_CD 2
-#define ALS007_SYNTH 7
diff --git a/ANDROID_3.4.5/sound/oss/sequencer.c b/ANDROID_3.4.5/sound/oss/sequencer.c
deleted file mode 100644
index 30bcfe47..00000000
--- a/ANDROID_3.4.5/sound/oss/sequencer.c
+++ /dev/null
@@ -1,1671 +0,0 @@
-/*
- * sound/oss/sequencer.c
- *
- * The sequencer personality manager.
- */
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-/*
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
- * Alan Cox : reformatted and fixed a pair of null pointer bugs
- */
-#include <linux/kmod.h>
-#include <linux/spinlock.h>
-#include "sound_config.h"
-
-#include "midi_ctrl.h"
-
-static int sequencer_ok;
-static struct sound_timer_operations *tmr;
-static int tmr_no = -1; /* Currently selected timer */
-static int pending_timer = -1; /* For timer change operation */
-extern unsigned long seq_time;
-
-static int obsolete_api_used;
-static DEFINE_SPINLOCK(lock);
-
-/*
- * Local counts for number of synth and MIDI devices. These are initialized
- * by the sequencer_open.
- */
-static int max_mididev;
-static int max_synthdev;
-
-/*
- * The seq_mode gives the operating mode of the sequencer:
- * 1 = level1 (the default)
- * 2 = level2 (extended capabilities)
- */
-
-#define SEQ_1 1
-#define SEQ_2 2
-static int seq_mode = SEQ_1;
-
-static DECLARE_WAIT_QUEUE_HEAD(seq_sleeper);
-static DECLARE_WAIT_QUEUE_HEAD(midi_sleeper);
-
-static int midi_opened[MAX_MIDI_DEV];
-
-static int midi_written[MAX_MIDI_DEV];
-
-static unsigned long prev_input_time;
-static int prev_event_time;
-
-#include "tuning.h"
-
-#define EV_SZ 8
-#define IEV_SZ 8
-
-static unsigned char *queue;
-static unsigned char *iqueue;
-
-static volatile int qhead, qtail, qlen;
-static volatile int iqhead, iqtail, iqlen;
-static volatile int seq_playing;
-static volatile int sequencer_busy;
-static int output_threshold;
-static long pre_event_timeout;
-static unsigned synth_open_mask;
-
-static int seq_queue(unsigned char *note, char nonblock);
-static void seq_startplay(void);
-static int seq_sync(void);
-static void seq_reset(void);
-
-#if MAX_SYNTH_DEV > 15
-#error Too many synthesizer devices enabled.
-#endif
-
-int sequencer_read(int dev, struct file *file, char __user *buf, int count)
-{
- int c = count, p = 0;
- int ev_len;
- unsigned long flags;
-
- dev = dev >> 4;
-
- ev_len = seq_mode == SEQ_1 ? 4 : 8;
-
- spin_lock_irqsave(&lock,flags);
-
- if (!iqlen)
- {
- spin_unlock_irqrestore(&lock,flags);
- if (file->f_flags & O_NONBLOCK) {
- return -EAGAIN;
- }
-
- interruptible_sleep_on_timeout(&midi_sleeper,
- pre_event_timeout);
- spin_lock_irqsave(&lock,flags);
- if (!iqlen)
- {
- spin_unlock_irqrestore(&lock,flags);
- return 0;
- }
- }
- while (iqlen && c >= ev_len)
- {
- char *fixit = (char *) &iqueue[iqhead * IEV_SZ];
- spin_unlock_irqrestore(&lock,flags);
- if (copy_to_user(&(buf)[p], fixit, ev_len))
- return count - c;
- p += ev_len;
- c -= ev_len;
-
- spin_lock_irqsave(&lock,flags);
- iqhead = (iqhead + 1) % SEQ_MAX_QUEUE;
- iqlen--;
- }
- spin_unlock_irqrestore(&lock,flags);
- return count - c;
-}
-
-static void sequencer_midi_output(int dev)
-{
- /*
- * Currently NOP
- */
-}
-
-void seq_copy_to_input(unsigned char *event_rec, int len)
-{
- unsigned long flags;
-
- /*
- * Verify that the len is valid for the current mode.
- */
-
- if (len != 4 && len != 8)
- return;
- if ((seq_mode == SEQ_1) != (len == 4))
- return;
-
- if (iqlen >= (SEQ_MAX_QUEUE - 1))
- return; /* Overflow */
-
- spin_lock_irqsave(&lock,flags);
- memcpy(&iqueue[iqtail * IEV_SZ], event_rec, len);
- iqlen++;
- iqtail = (iqtail + 1) % SEQ_MAX_QUEUE;
- wake_up(&midi_sleeper);
- spin_unlock_irqrestore(&lock,flags);
-}
-EXPORT_SYMBOL(seq_copy_to_input);
-
-static void sequencer_midi_input(int dev, unsigned char data)
-{
- unsigned int tstamp;
- unsigned char event_rec[4];
-
- if (data == 0xfe) /* Ignore active sensing */
- return;
-
- tstamp = jiffies - seq_time;
-
- if (tstamp != prev_input_time)
- {
- tstamp = (tstamp << 8) | SEQ_WAIT;
- seq_copy_to_input((unsigned char *) &tstamp, 4);
- prev_input_time = tstamp;
- }
- event_rec[0] = SEQ_MIDIPUTC;
- event_rec[1] = data;
- event_rec[2] = dev;
- event_rec[3] = 0;
-
- seq_copy_to_input(event_rec, 4);
-}
-
-void seq_input_event(unsigned char *event_rec, int len)
-{
- unsigned long this_time;
-
- if (seq_mode == SEQ_2)
- this_time = tmr->get_time(tmr_no);
- else
- this_time = jiffies - seq_time;
-
- if (this_time != prev_input_time)
- {
- unsigned char tmp_event[8];
-
- tmp_event[0] = EV_TIMING;
- tmp_event[1] = TMR_WAIT_ABS;
- tmp_event[2] = 0;
- tmp_event[3] = 0;
- *(unsigned int *) &tmp_event[4] = this_time;
-
- seq_copy_to_input(tmp_event, 8);
- prev_input_time = this_time;
- }
- seq_copy_to_input(event_rec, len);
-}
-EXPORT_SYMBOL(seq_input_event);
-
-int sequencer_write(int dev, struct file *file, const char __user *buf, int count)
-{
- unsigned char event_rec[EV_SZ], ev_code;
- int p = 0, c, ev_size;
- int mode = translate_mode(file);
-
- dev = dev >> 4;
-
- DEB(printk("sequencer_write(dev=%d, count=%d)\n", dev, count));
-
- if (mode == OPEN_READ)
- return -EIO;
-
- c = count;
-
- while (c >= 4)
- {
- if (copy_from_user((char *) event_rec, &(buf)[p], 4))
- goto out;
- ev_code = event_rec[0];
-
- if (ev_code == SEQ_FULLSIZE)
- {
- int err, fmt;
-
- dev = *(unsigned short *) &event_rec[2];
- if (dev < 0 || dev >= max_synthdev || synth_devs[dev] == NULL)
- return -ENXIO;
-
- if (!(synth_open_mask & (1 << dev)))
- return -ENXIO;
-
- fmt = (*(short *) &event_rec[0]) & 0xffff;
- err = synth_devs[dev]->load_patch(dev, fmt, buf + p, c, 0);
- if (err < 0)
- return err;
-
- return err;
- }
- if (ev_code >= 128)
- {
- if (seq_mode == SEQ_2 && ev_code == SEQ_EXTENDED)
- {
- printk(KERN_WARNING "Sequencer: Invalid level 2 event %x\n", ev_code);
- return -EINVAL;
- }
- ev_size = 8;
-
- if (c < ev_size)
- {
- if (!seq_playing)
- seq_startplay();
- return count - c;
- }
- if (copy_from_user((char *)&event_rec[4],
- &(buf)[p + 4], 4))
- goto out;
-
- }
- else
- {
- if (seq_mode == SEQ_2)
- {
- printk(KERN_WARNING "Sequencer: 4 byte event in level 2 mode\n");
- return -EINVAL;
- }
- ev_size = 4;
-
- if (event_rec[0] != SEQ_MIDIPUTC)
- obsolete_api_used = 1;
- }
-
- if (event_rec[0] == SEQ_MIDIPUTC)
- {
- if (!midi_opened[event_rec[2]])
- {
- int err, mode;
- int dev = event_rec[2];
-
- if (dev >= max_mididev || midi_devs[dev]==NULL)
- {
- /*printk("Sequencer Error: Nonexistent MIDI device %d\n", dev);*/
- return -ENXIO;
- }
- mode = translate_mode(file);
-
- if ((err = midi_devs[dev]->open(dev, mode,
- sequencer_midi_input, sequencer_midi_output)) < 0)
- {
- seq_reset();
- printk(KERN_WARNING "Sequencer Error: Unable to open Midi #%d\n", dev);
- return err;
- }
- midi_opened[dev] = 1;
- }
- }
- if (!seq_queue(event_rec, (file->f_flags & (O_NONBLOCK) ? 1 : 0)))
- {
- int processed = count - c;
-
- if (!seq_playing)
- seq_startplay();
-
- if (!processed && (file->f_flags & O_NONBLOCK))
- return -EAGAIN;
- else
- return processed;
- }
- p += ev_size;
- c -= ev_size;
- }
-
- if (!seq_playing)
- seq_startplay();
-out:
- return count;
-}
-
-static int seq_queue(unsigned char *note, char nonblock)
-{
-
- /*
- * Test if there is space in the queue
- */
-
- if (qlen >= SEQ_MAX_QUEUE)
- if (!seq_playing)
- seq_startplay(); /*
- * Give chance to drain the queue
- */
-
- if (!nonblock && qlen >= SEQ_MAX_QUEUE && !waitqueue_active(&seq_sleeper)) {
- /*
- * Sleep until there is enough space on the queue
- */
- interruptible_sleep_on(&seq_sleeper);
- }
- if (qlen >= SEQ_MAX_QUEUE)
- {
- return 0; /*
- * To be sure
- */
- }
- memcpy(&queue[qtail * EV_SZ], note, EV_SZ);
-
- qtail = (qtail + 1) % SEQ_MAX_QUEUE;
- qlen++;
-
- return 1;
-}
-
-static int extended_event(unsigned char *q)
-{
- int dev = q[2];
-
- if (dev < 0 || dev >= max_synthdev)
- return -ENXIO;
-
- if (!(synth_open_mask & (1 << dev)))
- return -ENXIO;
-
- switch (q[1])
- {
- case SEQ_NOTEOFF:
- synth_devs[dev]->kill_note(dev, q[3], q[4], q[5]);
- break;
-
- case SEQ_NOTEON:
- if (q[4] > 127 && q[4] != 255)
- return 0;
-
- if (q[5] == 0)
- {
- synth_devs[dev]->kill_note(dev, q[3], q[4], q[5]);
- break;
- }
- synth_devs[dev]->start_note(dev, q[3], q[4], q[5]);
- break;
-
- case SEQ_PGMCHANGE:
- synth_devs[dev]->set_instr(dev, q[3], q[4]);
- break;
-
- case SEQ_AFTERTOUCH:
- synth_devs[dev]->aftertouch(dev, q[3], q[4]);
- break;
-
- case SEQ_BALANCE:
- synth_devs[dev]->panning(dev, q[3], (char) q[4]);
- break;
-
- case SEQ_CONTROLLER:
- synth_devs[dev]->controller(dev, q[3], q[4], (short) (q[5] | (q[6] << 8)));
- break;
-
- case SEQ_VOLMODE:
- if (synth_devs[dev]->volume_method != NULL)
- synth_devs[dev]->volume_method(dev, q[3]);
- break;
-
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int find_voice(int dev, int chn, int note)
-{
- unsigned short key;
- int i;
-
- key = (chn << 8) | (note + 1);
- for (i = 0; i < synth_devs[dev]->alloc.max_voice; i++)
- if (synth_devs[dev]->alloc.map[i] == key)
- return i;
- return -1;
-}
-
-static int alloc_voice(int dev, int chn, int note)
-{
- unsigned short key;
- int voice;
-
- key = (chn << 8) | (note + 1);
-
- voice = synth_devs[dev]->alloc_voice(dev, chn, note,
- &synth_devs[dev]->alloc);
- synth_devs[dev]->alloc.map[voice] = key;
- synth_devs[dev]->alloc.alloc_times[voice] =
- synth_devs[dev]->alloc.timestamp++;
- return voice;
-}
-
-static void seq_chn_voice_event(unsigned char *event_rec)
-{
-#define dev event_rec[1]
-#define cmd event_rec[2]
-#define chn event_rec[3]
-#define note event_rec[4]
-#define parm event_rec[5]
-
- int voice = -1;
-
- if ((int) dev > max_synthdev || synth_devs[dev] == NULL)
- return;
- if (!(synth_open_mask & (1 << dev)))
- return;
- if (!synth_devs[dev])
- return;
-
- if (seq_mode == SEQ_2)
- {
- if (synth_devs[dev]->alloc_voice)
- voice = find_voice(dev, chn, note);
-
- if (cmd == MIDI_NOTEON && parm == 0)
- {
- cmd = MIDI_NOTEOFF;
- parm = 64;
- }
- }
-
- switch (cmd)
- {
- case MIDI_NOTEON:
- if (note > 127 && note != 255) /* Not a seq2 feature */
- return;
-
- if (voice == -1 && seq_mode == SEQ_2 && synth_devs[dev]->alloc_voice)
- {
- /* Internal synthesizer (FM, GUS, etc) */
- voice = alloc_voice(dev, chn, note);
- }
- if (voice == -1)
- voice = chn;
-
- if (seq_mode == SEQ_2 && (int) dev < num_synths)
- {
- /*
- * The MIDI channel 10 is a percussive channel. Use the note
- * number to select the proper patch (128 to 255) to play.
- */
-
- if (chn == 9)
- {
- synth_devs[dev]->set_instr(dev, voice, 128 + note);
- synth_devs[dev]->chn_info[chn].pgm_num = 128 + note;
- }
- synth_devs[dev]->setup_voice(dev, voice, chn);
- }
- synth_devs[dev]->start_note(dev, voice, note, parm);
- break;
-
- case MIDI_NOTEOFF:
- if (voice == -1)
- voice = chn;
- synth_devs[dev]->kill_note(dev, voice, note, parm);
- break;
-
- case MIDI_KEY_PRESSURE:
- if (voice == -1)
- voice = chn;
- synth_devs[dev]->aftertouch(dev, voice, parm);
- break;
-
- default:;
- }
-#undef dev
-#undef cmd
-#undef chn
-#undef note
-#undef parm
-}
-
-
-static void seq_chn_common_event(unsigned char *event_rec)
-{
- unsigned char dev = event_rec[1];
- unsigned char cmd = event_rec[2];
- unsigned char chn = event_rec[3];
- unsigned char p1 = event_rec[4];
-
- /* unsigned char p2 = event_rec[5]; */
- unsigned short w14 = *(short *) &event_rec[6];
-
- if ((int) dev > max_synthdev || synth_devs[dev] == NULL)
- return;
- if (!(synth_open_mask & (1 << dev)))
- return;
- if (!synth_devs[dev])
- return;
-
- switch (cmd)
- {
- case MIDI_PGM_CHANGE:
- if (seq_mode == SEQ_2)
- {
- synth_devs[dev]->chn_info[chn].pgm_num = p1;
- if ((int) dev >= num_synths)
- synth_devs[dev]->set_instr(dev, chn, p1);
- }
- else
- synth_devs[dev]->set_instr(dev, chn, p1);
-
- break;
-
- case MIDI_CTL_CHANGE:
- if (seq_mode == SEQ_2)
- {
- if (chn > 15 || p1 > 127)
- break;
-
- synth_devs[dev]->chn_info[chn].controllers[p1] = w14 & 0x7f;
-
- if (p1 < 32) /* Setting MSB should clear LSB to 0 */
- synth_devs[dev]->chn_info[chn].controllers[p1 + 32] = 0;
-
- if ((int) dev < num_synths)
- {
- int val = w14 & 0x7f;
- int i, key;
-
- if (p1 < 64) /* Combine MSB and LSB */
- {
- val = ((synth_devs[dev]->
- chn_info[chn].controllers[p1 & ~32] & 0x7f) << 7)
- | (synth_devs[dev]->
- chn_info[chn].controllers[p1 | 32] & 0x7f);
- p1 &= ~32;
- }
- /* Handle all playing notes on this channel */
-
- key = ((int) chn << 8);
-
- for (i = 0; i < synth_devs[dev]->alloc.max_voice; i++)
- if ((synth_devs[dev]->alloc.map[i] & 0xff00) == key)
- synth_devs[dev]->controller(dev, i, p1, val);
- }
- else
- synth_devs[dev]->controller(dev, chn, p1, w14);
- }
- else /* Mode 1 */
- synth_devs[dev]->controller(dev, chn, p1, w14);
- break;
-
- case MIDI_PITCH_BEND:
- if (seq_mode == SEQ_2)
- {
- synth_devs[dev]->chn_info[chn].bender_value = w14;
-
- if ((int) dev < num_synths)
- {
- /* Handle all playing notes on this channel */
- int i, key;
-
- key = (chn << 8);
-
- for (i = 0; i < synth_devs[dev]->alloc.max_voice; i++)
- if ((synth_devs[dev]->alloc.map[i] & 0xff00) == key)
- synth_devs[dev]->bender(dev, i, w14);
- }
- else
- synth_devs[dev]->bender(dev, chn, w14);
- }
- else /* MODE 1 */
- synth_devs[dev]->bender(dev, chn, w14);
- break;
-
- default:;
- }
-}
-
-static int seq_timing_event(unsigned char *event_rec)
-{
- unsigned char cmd = event_rec[1];
- unsigned int parm = *(int *) &event_rec[4];
-
- if (seq_mode == SEQ_2)
- {
- int ret;
-
- if ((ret = tmr->event(tmr_no, event_rec)) == TIMER_ARMED)
- if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
- wake_up(&seq_sleeper);
- return ret;
- }
- switch (cmd)
- {
- case TMR_WAIT_REL:
- parm += prev_event_time;
-
- /*
- * NOTE! No break here. Execution of TMR_WAIT_REL continues in the
- * next case (TMR_WAIT_ABS)
- */
-
- case TMR_WAIT_ABS:
- if (parm > 0)
- {
- long time;
-
- time = parm;
- prev_event_time = time;
-
- seq_playing = 1;
- request_sound_timer(time);
-
- if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
- wake_up(&seq_sleeper);
- return TIMER_ARMED;
- }
- break;
-
- case TMR_START:
- seq_time = jiffies;
- prev_input_time = 0;
- prev_event_time = 0;
- break;
-
- case TMR_STOP:
- break;
-
- case TMR_CONTINUE:
- break;
-
- case TMR_TEMPO:
- break;
-
- case TMR_ECHO:
- if (seq_mode == SEQ_2)
- seq_copy_to_input(event_rec, 8);
- else
- {
- parm = (parm << 8 | SEQ_ECHO);
- seq_copy_to_input((unsigned char *) &parm, 4);
- }
- break;
-
- default:;
- }
-
- return TIMER_NOT_ARMED;
-}
-
-static void seq_local_event(unsigned char *event_rec)
-{
- unsigned char cmd = event_rec[1];
- unsigned int parm = *((unsigned int *) &event_rec[4]);
-
- switch (cmd)
- {
- case LOCL_STARTAUDIO:
- DMAbuf_start_devices(parm);
- break;
-
- default:;
- }
-}
-
-static void seq_sysex_message(unsigned char *event_rec)
-{
- unsigned int dev = event_rec[1];
- int i, l = 0;
- unsigned char *buf = &event_rec[2];
-
- if (dev > max_synthdev)
- return;
- if (!(synth_open_mask & (1 << dev)))
- return;
- if (!synth_devs[dev])
- return;
-
- l = 0;
- for (i = 0; i < 6 && buf[i] != 0xff; i++)
- l = i + 1;
-
- if (!synth_devs[dev]->send_sysex)
- return;
- if (l > 0)
- synth_devs[dev]->send_sysex(dev, buf, l);
-}
-
-static int play_event(unsigned char *q)
-{
- /*
- * NOTE! This routine returns
- * 0 = normal event played.
- * 1 = Timer armed. Suspend playback until timer callback.
- * 2 = MIDI output buffer full. Restore queue and suspend until timer
- */
- unsigned int *delay;
-
- switch (q[0])
- {
- case SEQ_NOTEOFF:
- if (synth_open_mask & (1 << 0))
- if (synth_devs[0])
- synth_devs[0]->kill_note(0, q[1], 255, q[3]);
- break;
-
- case SEQ_NOTEON:
- if (q[4] < 128 || q[4] == 255)
- if (synth_open_mask & (1 << 0))
- if (synth_devs[0])
- synth_devs[0]->start_note(0, q[1], q[2], q[3]);
- break;
-
- case SEQ_WAIT:
- delay = (unsigned int *) q; /*
- * Bytes 1 to 3 are containing the *
- * delay in 'ticks'
- */
- *delay = (*delay >> 8) & 0xffffff;
-
- if (*delay > 0)
- {
- long time;
-
- seq_playing = 1;
- time = *delay;
- prev_event_time = time;
-
- request_sound_timer(time);
-
- if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
- wake_up(&seq_sleeper);
- /*
- * The timer is now active and will reinvoke this function
- * after the timer expires. Return to the caller now.
- */
- return 1;
- }
- break;
-
- case SEQ_PGMCHANGE:
- if (synth_open_mask & (1 << 0))
- if (synth_devs[0])
- synth_devs[0]->set_instr(0, q[1], q[2]);
- break;
-
- case SEQ_SYNCTIMER: /*
- * Reset timer
- */
- seq_time = jiffies;
- prev_input_time = 0;
- prev_event_time = 0;
- break;
-
- case SEQ_MIDIPUTC: /*
- * Put a midi character
- */
- if (midi_opened[q[2]])
- {
- int dev;
-
- dev = q[2];
-
- if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
- break;
-
- if (!midi_devs[dev]->outputc(dev, q[1]))
- {
- /*
- * Output FIFO is full. Wait one timer cycle and try again.
- */
-
- seq_playing = 1;
- request_sound_timer(-1);
- return 2;
- }
- else
- midi_written[dev] = 1;
- }
- break;
-
- case SEQ_ECHO:
- seq_copy_to_input(q, 4); /*
- * Echo back to the process
- */
- break;
-
- case SEQ_PRIVATE:
- if ((int) q[1] < max_synthdev)
- synth_devs[q[1]]->hw_control(q[1], q);
- break;
-
- case SEQ_EXTENDED:
- extended_event(q);
- break;
-
- case EV_CHN_VOICE:
- seq_chn_voice_event(q);
- break;
-
- case EV_CHN_COMMON:
- seq_chn_common_event(q);
- break;
-
- case EV_TIMING:
- if (seq_timing_event(q) == TIMER_ARMED)
- {
- return 1;
- }
- break;
-
- case EV_SEQ_LOCAL:
- seq_local_event(q);
- break;
-
- case EV_SYSEX:
- seq_sysex_message(q);
- break;
-
- default:;
- }
- return 0;
-}
-
-/* called also as timer in irq context */
-static void seq_startplay(void)
-{
- int this_one, action;
- unsigned long flags;
-
- while (qlen > 0)
- {
-
- spin_lock_irqsave(&lock,flags);
- qhead = ((this_one = qhead) + 1) % SEQ_MAX_QUEUE;
- qlen--;
- spin_unlock_irqrestore(&lock,flags);
-
- seq_playing = 1;
-
- if ((action = play_event(&queue[this_one * EV_SZ])))
- { /* Suspend playback. Next timer routine invokes this routine again */
- if (action == 2)
- {
- qlen++;
- qhead = this_one;
- }
- return;
- }
- }
-
- seq_playing = 0;
-
- if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
- wake_up(&seq_sleeper);
-}
-
-static void reset_controllers(int dev, unsigned char *controller, int update_dev)
-{
- int i;
- for (i = 0; i < 128; i++)
- controller[i] = ctrl_def_values[i];
-}
-
-static void setup_mode2(void)
-{
- int dev;
-
- max_synthdev = num_synths;
-
- for (dev = 0; dev < num_midis; dev++)
- {
- if (midi_devs[dev] && midi_devs[dev]->converter != NULL)
- {
- synth_devs[max_synthdev++] = midi_devs[dev]->converter;
- }
- }
-
- for (dev = 0; dev < max_synthdev; dev++)
- {
- int chn;
-
- synth_devs[dev]->sysex_ptr = 0;
- synth_devs[dev]->emulation = 0;
-
- for (chn = 0; chn < 16; chn++)
- {
- synth_devs[dev]->chn_info[chn].pgm_num = 0;
- reset_controllers(dev,
- synth_devs[dev]->chn_info[chn].controllers,0);
- synth_devs[dev]->chn_info[chn].bender_value = (1 << 7); /* Neutral */
- synth_devs[dev]->chn_info[chn].bender_range = 200;
- }
- }
- max_mididev = 0;
- seq_mode = SEQ_2;
-}
-
-int sequencer_open(int dev, struct file *file)
-{
- int retval, mode, i;
- int level, tmp;
-
- if (!sequencer_ok)
- sequencer_init();
-
- level = ((dev & 0x0f) == SND_DEV_SEQ2) ? 2 : 1;
-
- dev = dev >> 4;
- mode = translate_mode(file);
-
- DEB(printk("sequencer_open(dev=%d)\n", dev));
-
- if (!sequencer_ok)
- {
-/* printk("Sound card: sequencer not initialized\n");*/
- return -ENXIO;
- }
- if (dev) /* Patch manager device (obsolete) */
- return -ENXIO;
-
- if(synth_devs[dev] == NULL)
- request_module("synth0");
-
- if (mode == OPEN_READ)
- {
- if (!num_midis)
- {
- /*printk("Sequencer: No MIDI devices. Input not possible\n");*/
- sequencer_busy = 0;
- return -ENXIO;
- }
- }
- if (sequencer_busy)
- {
- return -EBUSY;
- }
- sequencer_busy = 1;
- obsolete_api_used = 0;
-
- max_mididev = num_midis;
- max_synthdev = num_synths;
- pre_event_timeout = MAX_SCHEDULE_TIMEOUT;
- seq_mode = SEQ_1;
-
- if (pending_timer != -1)
- {
- tmr_no = pending_timer;
- pending_timer = -1;
- }
- if (tmr_no == -1) /* Not selected yet */
- {
- int i, best;
-
- best = -1;
- for (i = 0; i < num_sound_timers; i++)
- if (sound_timer_devs[i] && sound_timer_devs[i]->priority > best)
- {
- tmr_no = i;
- best = sound_timer_devs[i]->priority;
- }
- if (tmr_no == -1) /* Should not be */
- tmr_no = 0;
- }
- tmr = sound_timer_devs[tmr_no];
-
- if (level == 2)
- {
- if (tmr == NULL)
- {
- /*printk("sequencer: No timer for level 2\n");*/
- sequencer_busy = 0;
- return -ENXIO;
- }
- setup_mode2();
- }
- if (!max_synthdev && !max_mididev)
- {
- sequencer_busy=0;
- return -ENXIO;
- }
-
- synth_open_mask = 0;
-
- for (i = 0; i < max_mididev; i++)
- {
- midi_opened[i] = 0;
- midi_written[i] = 0;
- }
-
- for (i = 0; i < max_synthdev; i++)
- {
- if (synth_devs[i]==NULL)
- continue;
-
- if (!try_module_get(synth_devs[i]->owner))
- continue;
-
- if ((tmp = synth_devs[i]->open(i, mode)) < 0)
- {
- printk(KERN_WARNING "Sequencer: Warning! Cannot open synth device #%d (%d)\n", i, tmp);
- if (synth_devs[i]->midi_dev)
- printk(KERN_WARNING "(Maps to MIDI dev #%d)\n", synth_devs[i]->midi_dev);
- }
- else
- {
- synth_open_mask |= (1 << i);
- if (synth_devs[i]->midi_dev)
- midi_opened[synth_devs[i]->midi_dev] = 1;
- }
- }
-
- seq_time = jiffies;
-
- prev_input_time = 0;
- prev_event_time = 0;
-
- if (seq_mode == SEQ_1 && (mode == OPEN_READ || mode == OPEN_READWRITE))
- {
- /*
- * Initialize midi input devices
- */
-
- for (i = 0; i < max_mididev; i++)
- if (!midi_opened[i] && midi_devs[i])
- {
- if (!try_module_get(midi_devs[i]->owner))
- continue;
-
- if ((retval = midi_devs[i]->open(i, mode,
- sequencer_midi_input, sequencer_midi_output)) >= 0)
- {
- midi_opened[i] = 1;
- }
- }
- }
-
- if (seq_mode == SEQ_2) {
- if (try_module_get(tmr->owner))
- tmr->open(tmr_no, seq_mode);
- }
-
- init_waitqueue_head(&seq_sleeper);
- init_waitqueue_head(&midi_sleeper);
- output_threshold = SEQ_MAX_QUEUE / 2;
-
- return 0;
-}
-
-static void seq_drain_midi_queues(void)
-{
- int i, n;
-
- /*
- * Give the Midi drivers time to drain their output queues
- */
-
- n = 1;
-
- while (!signal_pending(current) && n)
- {
- n = 0;
-
- for (i = 0; i < max_mididev; i++)
- if (midi_opened[i] && midi_written[i])
- if (midi_devs[i]->buffer_status != NULL)
- if (midi_devs[i]->buffer_status(i))
- n++;
-
- /*
- * Let's have a delay
- */
-
- if (n)
- interruptible_sleep_on_timeout(&seq_sleeper,
- HZ/10);
- }
-}
-
-void sequencer_release(int dev, struct file *file)
-{
- int i;
- int mode = translate_mode(file);
-
- dev = dev >> 4;
-
- DEB(printk("sequencer_release(dev=%d)\n", dev));
-
- /*
- * Wait until the queue is empty (if we don't have nonblock)
- */
-
- if (mode != OPEN_READ && !(file->f_flags & O_NONBLOCK))
- {
- while (!signal_pending(current) && qlen > 0)
- {
- seq_sync();
- interruptible_sleep_on_timeout(&seq_sleeper,
- 3*HZ);
- /* Extra delay */
- }
- }
-
- if (mode != OPEN_READ)
- seq_drain_midi_queues(); /*
- * Ensure the output queues are empty
- */
- seq_reset();
- if (mode != OPEN_READ)
- seq_drain_midi_queues(); /*
- * Flush the all notes off messages
- */
-
- for (i = 0; i < max_synthdev; i++)
- {
- if (synth_open_mask & (1 << i)) /*
- * Actually opened
- */
- if (synth_devs[i])
- {
- synth_devs[i]->close(i);
-
- module_put(synth_devs[i]->owner);
-
- if (synth_devs[i]->midi_dev)
- midi_opened[synth_devs[i]->midi_dev] = 0;
- }
- }
-
- for (i = 0; i < max_mididev; i++)
- {
- if (midi_opened[i]) {
- midi_devs[i]->close(i);
- module_put(midi_devs[i]->owner);
- }
- }
-
- if (seq_mode == SEQ_2) {
- tmr->close(tmr_no);
- module_put(tmr->owner);
- }
-
- if (obsolete_api_used)
- printk(KERN_WARNING "/dev/music: Obsolete (4 byte) API was used by %s\n", current->comm);
- sequencer_busy = 0;
-}
-
-static int seq_sync(void)
-{
- if (qlen && !seq_playing && !signal_pending(current))
- seq_startplay();
-
- if (qlen > 0)
- interruptible_sleep_on_timeout(&seq_sleeper, HZ);
- return qlen;
-}
-
-static void midi_outc(int dev, unsigned char data)
-{
- /*
- * NOTE! Calls sleep(). Don't call this from interrupt.
- */
-
- int n;
- unsigned long flags;
-
- /*
- * This routine sends one byte to the Midi channel.
- * If the output FIFO is full, it waits until there
- * is space in the queue
- */
-
- n = 3 * HZ; /* Timeout */
-
- spin_lock_irqsave(&lock,flags);
- while (n && !midi_devs[dev]->outputc(dev, data)) {
- interruptible_sleep_on_timeout(&seq_sleeper, HZ/25);
- n--;
- }
- spin_unlock_irqrestore(&lock,flags);
-}
-
-static void seq_reset(void)
-{
- /*
- * NOTE! Calls sleep(). Don't call this from interrupt.
- */
-
- int i;
- int chn;
- unsigned long flags;
-
- sound_stop_timer();
-
- seq_time = jiffies;
- prev_input_time = 0;
- prev_event_time = 0;
-
- qlen = qhead = qtail = 0;
- iqlen = iqhead = iqtail = 0;
-
- for (i = 0; i < max_synthdev; i++)
- if (synth_open_mask & (1 << i))
- if (synth_devs[i])
- synth_devs[i]->reset(i);
-
- if (seq_mode == SEQ_2)
- {
- for (chn = 0; chn < 16; chn++)
- for (i = 0; i < max_synthdev; i++)
- if (synth_open_mask & (1 << i))
- if (synth_devs[i])
- {
- synth_devs[i]->controller(i, chn, 123, 0); /* All notes off */
- synth_devs[i]->controller(i, chn, 121, 0); /* Reset all ctl */
- synth_devs[i]->bender(i, chn, 1 << 13); /* Bender off */
- }
- }
- else /* seq_mode == SEQ_1 */
- {
- for (i = 0; i < max_mididev; i++)
- if (midi_written[i]) /*
- * Midi used. Some notes may still be playing
- */
- {
- /*
- * Sending just a ACTIVE SENSING message should be enough to stop all
- * playing notes. Since there are devices not recognizing the
- * active sensing, we have to send some all notes off messages also.
- */
- midi_outc(i, 0xfe);
-
- for (chn = 0; chn < 16; chn++)
- {
- midi_outc(i, (unsigned char) (0xb0 + (chn & 0x0f))); /* control change */
- midi_outc(i, 0x7b); /* All notes off */
- midi_outc(i, 0); /* Dummy parameter */
- }
-
- midi_devs[i]->close(i);
-
- midi_written[i] = 0;
- midi_opened[i] = 0;
- }
- }
-
- seq_playing = 0;
-
- spin_lock_irqsave(&lock,flags);
-
- if (waitqueue_active(&seq_sleeper)) {
- /* printk( "Sequencer Warning: Unexpected sleeping process - Waking up\n"); */
- wake_up(&seq_sleeper);
- }
- spin_unlock_irqrestore(&lock,flags);
-}
-
-static void seq_panic(void)
-{
- /*
- * This routine is called by the application in case the user
- * wants to reset the system to the default state.
- */
-
- seq_reset();
-
- /*
- * Since some of the devices don't recognize the active sensing and
- * all notes off messages, we have to shut all notes manually.
- *
- * TO BE IMPLEMENTED LATER
- */
-
- /*
- * Also return the controllers to their default states
- */
-}
-
-int sequencer_ioctl(int dev, struct file *file, unsigned int cmd, void __user *arg)
-{
- int midi_dev, orig_dev, val, err;
- int mode = translate_mode(file);
- struct synth_info inf;
- struct seq_event_rec event_rec;
- unsigned long flags;
- int __user *p = arg;
-
- orig_dev = dev = dev >> 4;
-
- switch (cmd)
- {
- case SNDCTL_TMR_TIMEBASE:
- case SNDCTL_TMR_TEMPO:
- case SNDCTL_TMR_START:
- case SNDCTL_TMR_STOP:
- case SNDCTL_TMR_CONTINUE:
- case SNDCTL_TMR_METRONOME:
- case SNDCTL_TMR_SOURCE:
- if (seq_mode != SEQ_2)
- return -EINVAL;
- return tmr->ioctl(tmr_no, cmd, arg);
-
- case SNDCTL_TMR_SELECT:
- if (seq_mode != SEQ_2)
- return -EINVAL;
- if (get_user(pending_timer, p))
- return -EFAULT;
- if (pending_timer < 0 || pending_timer >= num_sound_timers || sound_timer_devs[pending_timer] == NULL)
- {
- pending_timer = -1;
- return -EINVAL;
- }
- val = pending_timer;
- break;
-
- case SNDCTL_SEQ_PANIC:
- seq_panic();
- return -EINVAL;
-
- case SNDCTL_SEQ_SYNC:
- if (mode == OPEN_READ)
- return 0;
- while (qlen > 0 && !signal_pending(current))
- seq_sync();
- return qlen ? -EINTR : 0;
-
- case SNDCTL_SEQ_RESET:
- seq_reset();
- return 0;
-
- case SNDCTL_SEQ_TESTMIDI:
- if (__get_user(midi_dev, p))
- return -EFAULT;
- if (midi_dev < 0 || midi_dev >= max_mididev || !midi_devs[midi_dev])
- return -ENXIO;
-
- if (!midi_opened[midi_dev] &&
- (err = midi_devs[midi_dev]->open(midi_dev, mode, sequencer_midi_input,
- sequencer_midi_output)) < 0)
- return err;
- midi_opened[midi_dev] = 1;
- return 0;
-
- case SNDCTL_SEQ_GETINCOUNT:
- if (mode == OPEN_WRITE)
- return 0;
- val = iqlen;
- break;
-
- case SNDCTL_SEQ_GETOUTCOUNT:
- if (mode == OPEN_READ)
- return 0;
- val = SEQ_MAX_QUEUE - qlen;
- break;
-
- case SNDCTL_SEQ_GETTIME:
- if (seq_mode == SEQ_2)
- return tmr->ioctl(tmr_no, cmd, arg);
- val = jiffies - seq_time;
- break;
-
- case SNDCTL_SEQ_CTRLRATE:
- /*
- * If *arg == 0, just return the current rate
- */
- if (seq_mode == SEQ_2)
- return tmr->ioctl(tmr_no, cmd, arg);
-
- if (get_user(val, p))
- return -EFAULT;
- if (val != 0)
- return -EINVAL;
- val = HZ;
- break;
-
- case SNDCTL_SEQ_RESETSAMPLES:
- case SNDCTL_SYNTH_REMOVESAMPLE:
- case SNDCTL_SYNTH_CONTROL:
- if (get_user(dev, p))
- return -EFAULT;
- if (dev < 0 || dev >= num_synths || synth_devs[dev] == NULL)
- return -ENXIO;
- if (!(synth_open_mask & (1 << dev)) && !orig_dev)
- return -EBUSY;
- return synth_devs[dev]->ioctl(dev, cmd, arg);
-
- case SNDCTL_SEQ_NRSYNTHS:
- val = max_synthdev;
- break;
-
- case SNDCTL_SEQ_NRMIDIS:
- val = max_mididev;
- break;
-
- case SNDCTL_SYNTH_MEMAVL:
- if (get_user(dev, p))
- return -EFAULT;
- if (dev < 0 || dev >= num_synths || synth_devs[dev] == NULL)
- return -ENXIO;
- if (!(synth_open_mask & (1 << dev)) && !orig_dev)
- return -EBUSY;
- val = synth_devs[dev]->ioctl(dev, cmd, arg);
- break;
-
- case SNDCTL_FM_4OP_ENABLE:
- if (get_user(dev, p))
- return -EFAULT;
- if (dev < 0 || dev >= num_synths || synth_devs[dev] == NULL)
- return -ENXIO;
- if (!(synth_open_mask & (1 << dev)))
- return -ENXIO;
- synth_devs[dev]->ioctl(dev, cmd, arg);
- return 0;
-
- case SNDCTL_SYNTH_INFO:
- if (get_user(dev, &((struct synth_info __user *)arg)->device))
- return -EFAULT;
- if (dev < 0 || dev >= max_synthdev)
- return -ENXIO;
- if (!(synth_open_mask & (1 << dev)) && !orig_dev)
- return -EBUSY;
- return synth_devs[dev]->ioctl(dev, cmd, arg);
-
- /* Like SYNTH_INFO but returns ID in the name field */
- case SNDCTL_SYNTH_ID:
- if (get_user(dev, &((struct synth_info __user *)arg)->device))
- return -EFAULT;
- if (dev < 0 || dev >= max_synthdev)
- return -ENXIO;
- if (!(synth_open_mask & (1 << dev)) && !orig_dev)
- return -EBUSY;
- memcpy(&inf, synth_devs[dev]->info, sizeof(inf));
- strlcpy(inf.name, synth_devs[dev]->id, sizeof(inf.name));
- inf.device = dev;
- return copy_to_user(arg, &inf, sizeof(inf))?-EFAULT:0;
-
- case SNDCTL_SEQ_OUTOFBAND:
- if (copy_from_user(&event_rec, arg, sizeof(event_rec)))
- return -EFAULT;
- spin_lock_irqsave(&lock,flags);
- play_event(event_rec.arr);
- spin_unlock_irqrestore(&lock,flags);
- return 0;
-
- case SNDCTL_MIDI_INFO:
- if (get_user(dev, &((struct midi_info __user *)arg)->device))
- return -EFAULT;
- if (dev < 0 || dev >= max_mididev || !midi_devs[dev])
- return -ENXIO;
- midi_devs[dev]->info.device = dev;
- return copy_to_user(arg, &midi_devs[dev]->info, sizeof(struct midi_info))?-EFAULT:0;
-
- case SNDCTL_SEQ_THRESHOLD:
- if (get_user(val, p))
- return -EFAULT;
- if (val < 1)
- val = 1;
- if (val >= SEQ_MAX_QUEUE)
- val = SEQ_MAX_QUEUE - 1;
- output_threshold = val;
- return 0;
-
- case SNDCTL_MIDI_PRETIME:
- if (get_user(val, p))
- return -EFAULT;
- if (val < 0)
- val = 0;
- val = (HZ * val) / 10;
- pre_event_timeout = val;
- break;
-
- default:
- if (mode == OPEN_READ)
- return -EIO;
- if (!synth_devs[0])
- return -ENXIO;
- if (!(synth_open_mask & (1 << 0)))
- return -ENXIO;
- if (!synth_devs[0]->ioctl)
- return -EINVAL;
- return synth_devs[0]->ioctl(0, cmd, arg);
- }
- return put_user(val, p);
-}
-
-/* No kernel lock - we're using the global irq lock here */
-unsigned int sequencer_poll(int dev, struct file *file, poll_table * wait)
-{
- unsigned long flags;
- unsigned int mask = 0;
-
- dev = dev >> 4;
-
- spin_lock_irqsave(&lock,flags);
- /* input */
- poll_wait(file, &midi_sleeper, wait);
- if (iqlen)
- mask |= POLLIN | POLLRDNORM;
-
- /* output */
- poll_wait(file, &seq_sleeper, wait);
- if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
- mask |= POLLOUT | POLLWRNORM;
- spin_unlock_irqrestore(&lock,flags);
- return mask;
-}
-
-
-void sequencer_timer(unsigned long dummy)
-{
- seq_startplay();
-}
-EXPORT_SYMBOL(sequencer_timer);
-
-int note_to_freq(int note_num)
-{
-
- /*
- * This routine converts a midi note to a frequency (multiplied by 1000)
- */
-
- int note, octave, note_freq;
- static int notes[] =
- {
- 261632, 277189, 293671, 311132, 329632, 349232,
- 369998, 391998, 415306, 440000, 466162, 493880
- };
-
-#define BASE_OCTAVE 5
-
- octave = note_num / 12;
- note = note_num % 12;
-
- note_freq = notes[note];
-
- if (octave < BASE_OCTAVE)
- note_freq >>= (BASE_OCTAVE - octave);
- else if (octave > BASE_OCTAVE)
- note_freq <<= (octave - BASE_OCTAVE);
-
- /*
- * note_freq >>= 1;
- */
-
- return note_freq;
-}
-EXPORT_SYMBOL(note_to_freq);
-
-unsigned long compute_finetune(unsigned long base_freq, int bend, int range,
- int vibrato_cents)
-{
- unsigned long amount;
- int negative, semitones, cents, multiplier = 1;
-
- if (!bend)
- return base_freq;
- if (!range)
- return base_freq;
-
- if (!base_freq)
- return base_freq;
-
- if (range >= 8192)
- range = 8192;
-
- bend = bend * range / 8192; /* Convert to cents */
- bend += vibrato_cents;
-
- if (!bend)
- return base_freq;
-
- negative = bend < 0 ? 1 : 0;
-
- if (bend < 0)
- bend *= -1;
- if (bend > range)
- bend = range;
-
- /*
- if (bend > 2399)
- bend = 2399;
- */
- while (bend > 2399)
- {
- multiplier *= 4;
- bend -= 2400;
- }
-
- semitones = bend / 100;
- cents = bend % 100;
-
- amount = (int) (semitone_tuning[semitones] * multiplier * cent_tuning[cents]) / 10000;
-
- if (negative)
- return (base_freq * 10000) / amount; /* Bend down */
- else
- return (base_freq * amount) / 10000; /* Bend up */
-}
-EXPORT_SYMBOL(compute_finetune);
-
-void sequencer_init(void)
-{
- if (sequencer_ok)
- return;
- queue = vmalloc(SEQ_MAX_QUEUE * EV_SZ);
- if (queue == NULL)
- {
- printk(KERN_ERR "sequencer: Can't allocate memory for sequencer output queue\n");
- return;
- }
- iqueue = vmalloc(SEQ_MAX_QUEUE * IEV_SZ);
- if (iqueue == NULL)
- {
- printk(KERN_ERR "sequencer: Can't allocate memory for sequencer input queue\n");
- vfree(queue);
- return;
- }
- sequencer_ok = 1;
-}
-EXPORT_SYMBOL(sequencer_init);
-
-void sequencer_unload(void)
-{
- vfree(queue);
- vfree(iqueue);
- queue = iqueue = NULL;
-}
diff --git a/ANDROID_3.4.5/sound/oss/sound_calls.h b/ANDROID_3.4.5/sound/oss/sound_calls.h
deleted file mode 100644
index 87d8ad4a..00000000
--- a/ANDROID_3.4.5/sound/oss/sound_calls.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * DMA buffer calls
- */
-
-int DMAbuf_open(int dev, int mode);
-int DMAbuf_release(int dev, int mode);
-int DMAbuf_getwrbuffer(int dev, char **buf, int *size, int dontblock);
-int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock);
-int DMAbuf_rmchars(int dev, int buff_no, int c);
-int DMAbuf_start_output(int dev, int buff_no, int l);
-int DMAbuf_move_wrpointer(int dev, int l);
-/* int DMAbuf_ioctl(int dev, unsigned int cmd, void __user *arg, int local); */
-void DMAbuf_init(int dev, int dma1, int dma2);
-void DMAbuf_deinit(int dev);
-int DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode);
-void DMAbuf_inputintr(int dev);
-void DMAbuf_outputintr(int dev, int underflow_flag);
-struct dma_buffparms;
-int DMAbuf_space_in_queue (int dev);
-int DMAbuf_activate_recording (int dev, struct dma_buffparms *dmap);
-int DMAbuf_get_buffer_pointer (int dev, struct dma_buffparms *dmap, int direction);
-void DMAbuf_launch_output(int dev, struct dma_buffparms *dmap);
-unsigned int DMAbuf_poll(struct file *file, int dev, poll_table *wait);
-void DMAbuf_start_devices(unsigned int devmask);
-void DMAbuf_reset (int dev);
-int DMAbuf_sync (int dev);
-
-/*
- * System calls for /dev/dsp and /dev/audio (audio.c)
- */
-
-int audio_read (int dev, struct file *file, char __user *buf, int count);
-int audio_write (int dev, struct file *file, const char __user *buf, int count);
-int audio_open (int dev, struct file *file);
-void audio_release (int dev, struct file *file);
-int audio_ioctl (int dev, struct file *file,
- unsigned int cmd, void __user *arg);
-void audio_init_devices (void);
-void reorganize_buffers (int dev, struct dma_buffparms *dmap, int recording);
-
-/*
- * System calls for the /dev/sequencer
- */
-
-int sequencer_read (int dev, struct file *file, char __user *buf, int count);
-int sequencer_write (int dev, struct file *file, const char __user *buf, int count);
-int sequencer_open (int dev, struct file *file);
-void sequencer_release (int dev, struct file *file);
-int sequencer_ioctl (int dev, struct file *file, unsigned int cmd, void __user *arg);
-unsigned int sequencer_poll(int dev, struct file *file, poll_table * wait);
-
-void sequencer_init (void);
-void sequencer_unload (void);
-void sequencer_timer(unsigned long dummy);
-int note_to_freq(int note_num);
-unsigned long compute_finetune(unsigned long base_freq, int bend, int range,
- int vibrato_bend);
-void seq_input_event(unsigned char *event, int len);
-void seq_copy_to_input (unsigned char *event, int len);
-
-/*
- * System calls for the /dev/midi
- */
-
-int MIDIbuf_read (int dev, struct file *file, char __user *buf, int count);
-int MIDIbuf_write (int dev, struct file *file, const char __user *buf, int count);
-int MIDIbuf_open (int dev, struct file *file);
-void MIDIbuf_release (int dev, struct file *file);
-int MIDIbuf_ioctl (int dev, struct file *file, unsigned int cmd, void __user *arg);
-unsigned int MIDIbuf_poll(int dev, struct file *file, poll_table * wait);
-int MIDIbuf_avail(int dev);
-
-void MIDIbuf_bytes_received(int dev, unsigned char *buf, int count);
-
-
-/* From soundcard.c */
-void request_sound_timer (int count);
-void sound_stop_timer(void);
-void conf_printf(char *name, struct address_info *hw_config);
-void conf_printf2(char *name, int base, int irq, int dma, int dma2);
-
-/* From sound_timer.c */
-void sound_timer_interrupt(void);
-void sound_timer_syncinterval(unsigned int new_usecs);
-
-/* From midi_synth.c */
-void do_midi_msg (int synthno, unsigned char *msg, int mlen);
diff --git a/ANDROID_3.4.5/sound/oss/sound_config.h b/ANDROID_3.4.5/sound/oss/sound_config.h
deleted file mode 100644
index 9d35c4c6..00000000
--- a/ANDROID_3.4.5/sound/oss/sound_config.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/* sound_config.h
- *
- * A driver for sound cards, misc. configuration parameters.
- */
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-
-
-#ifndef _SOUND_CONFIG_H_
-#define _SOUND_CONFIG_H_
-
-#include <linux/fs.h>
-#include <linux/sound.h>
-
-#include "os.h"
-#include "soundvers.h"
-
-
-#ifndef SND_DEFAULT_ENABLE
-#define SND_DEFAULT_ENABLE 1
-#endif
-
-#ifndef MAX_REALTIME_FACTOR
-#define MAX_REALTIME_FACTOR 4
-#endif
-
-/*
- * Use always 64k buffer size. There is no reason to use shorter.
- */
-#undef DSP_BUFFSIZE
-#define DSP_BUFFSIZE (64*1024)
-
-#ifndef DSP_BUFFCOUNT
-#define DSP_BUFFCOUNT 1 /* 1 is recommended. */
-#endif
-
-#define FM_MONO 0x388 /* This is the I/O address used by AdLib */
-
-#ifndef CONFIG_PAS_BASE
-#define CONFIG_PAS_BASE 0x388
-#endif
-
-/* SEQ_MAX_QUEUE is the maximum number of sequencer events buffered by the
- driver. (There is no need to alter this) */
-#define SEQ_MAX_QUEUE 1024
-
-#define SBFM_MAXINSTR (256) /* Size of the FM Instrument bank */
-/* 128 instruments for general MIDI setup and 16 unassigned */
-
-#define SND_NDEVS 256 /* Number of supported devices */
-
-#define DSP_DEFAULT_SPEED 8000
-
-#define MAX_AUDIO_DEV 5
-#define MAX_MIXER_DEV 5
-#define MAX_SYNTH_DEV 5
-#define MAX_MIDI_DEV 6
-#define MAX_TIMER_DEV 4
-
-struct address_info {
- int io_base;
- int irq;
- int dma;
- int dma2;
- int always_detect; /* 1=Trust me, it's there */
- char *name;
- int driver_use_1; /* Driver defined field 1 */
- int driver_use_2; /* Driver defined field 2 */
- int *osp; /* OS specific info */
- int card_subtype; /* Driver specific. Usually 0 */
- void *memptr; /* Module memory chainer */
- int slots[6]; /* To remember driver slot ids */
-};
-
-#define SYNTH_MAX_VOICES 32
-
-struct voice_alloc_info {
- int max_voice;
- int used_voices;
- int ptr; /* For device specific use */
- unsigned short map[SYNTH_MAX_VOICES]; /* (ch << 8) | (note+1) */
- int timestamp;
- int alloc_times[SYNTH_MAX_VOICES];
- };
-
-struct channel_info {
- int pgm_num;
- int bender_value;
- int bender_range;
- unsigned char controllers[128];
- };
-
-/*
- * Process wakeup reasons
- */
-#define WK_NONE 0x00
-#define WK_WAKEUP 0x01
-#define WK_TIMEOUT 0x02
-#define WK_SIGNAL 0x04
-#define WK_SLEEP 0x08
-#define WK_SELECT 0x10
-#define WK_ABORT 0x20
-
-#define OPEN_READ PCM_ENABLE_INPUT
-#define OPEN_WRITE PCM_ENABLE_OUTPUT
-#define OPEN_READWRITE (OPEN_READ|OPEN_WRITE)
-
-static inline int translate_mode(struct file *file)
-{
- if (OPEN_READ == (__force int)FMODE_READ &&
- OPEN_WRITE == (__force int)FMODE_WRITE)
- return (__force int)(file->f_mode & (FMODE_READ | FMODE_WRITE));
- else
- return ((file->f_mode & FMODE_READ) ? OPEN_READ : 0) |
- ((file->f_mode & FMODE_WRITE) ? OPEN_WRITE : 0);
-}
-
-#include "sound_calls.h"
-#include "dev_table.h"
-
-#ifndef DEB
-#define DEB(x)
-#endif
-
-#ifndef DDB
-#define DDB(x) do {} while (0)
-#endif
-
-#ifndef MDB
-#ifdef MODULE
-#define MDB(x) x
-#else
-#define MDB(x)
-#endif
-#endif
-
-#define TIMER_ARMED 121234
-#define TIMER_NOT_ARMED 1
-
-#define MAX_MEM_BLOCKS 1024
-
-#endif
diff --git a/ANDROID_3.4.5/sound/oss/sound_firmware.h b/ANDROID_3.4.5/sound/oss/sound_firmware.h
deleted file mode 100644
index 0a0cbfdf..00000000
--- a/ANDROID_3.4.5/sound/oss/sound_firmware.h
+++ /dev/null
@@ -1,2 +0,0 @@
-extern int mod_firmware_load(const char *fn, char **fp);
-
diff --git a/ANDROID_3.4.5/sound/oss/sound_timer.c b/ANDROID_3.4.5/sound/oss/sound_timer.c
deleted file mode 100644
index 8021c85f..00000000
--- a/ANDROID_3.4.5/sound/oss/sound_timer.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * sound/oss/sound_timer.c
- */
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-/*
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
- */
-#include <linux/string.h>
-#include <linux/spinlock.h>
-
-#include "sound_config.h"
-
-static volatile int initialized, opened, tmr_running;
-static volatile time_t tmr_offs, tmr_ctr;
-static volatile unsigned long ticks_offs;
-static volatile int curr_tempo, curr_timebase;
-static volatile unsigned long curr_ticks;
-static volatile unsigned long next_event_time;
-static unsigned long prev_event_time;
-static volatile unsigned long usecs_per_tmr; /* Length of the current interval */
-
-static struct sound_lowlev_timer *tmr;
-static DEFINE_SPINLOCK(lock);
-
-static unsigned long tmr2ticks(int tmr_value)
-{
- /*
- * Convert timer ticks to MIDI ticks
- */
-
- unsigned long tmp;
- unsigned long scale;
-
- tmp = tmr_value * usecs_per_tmr; /* Convert to usecs */
- scale = (60 * 1000000) / (curr_tempo * curr_timebase); /* usecs per MIDI tick */
- return (tmp + (scale / 2)) / scale;
-}
-
-void reprogram_timer(void)
-{
- unsigned long usecs_per_tick;
-
- /*
- * The user is changing the timer rate before setting a timer
- * slap, bad bad not allowed.
- */
-
- if(!tmr)
- return;
-
- usecs_per_tick = (60 * 1000000) / (curr_tempo * curr_timebase);
-
- /*
- * Don't kill the system by setting too high timer rate
- */
- if (usecs_per_tick < 2000)
- usecs_per_tick = 2000;
-
- usecs_per_tmr = tmr->tmr_start(tmr->dev, usecs_per_tick);
-}
-
-void sound_timer_syncinterval(unsigned int new_usecs)
-{
- /*
- * This routine is called by the hardware level if
- * the clock frequency has changed for some reason.
- */
- tmr_offs = tmr_ctr;
- ticks_offs += tmr2ticks(tmr_ctr);
- tmr_ctr = 0;
- usecs_per_tmr = new_usecs;
-}
-EXPORT_SYMBOL(sound_timer_syncinterval);
-
-static void tmr_reset(void)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&lock,flags);
- tmr_offs = 0;
- ticks_offs = 0;
- tmr_ctr = 0;
- next_event_time = (unsigned long) -1;
- prev_event_time = 0;
- curr_ticks = 0;
- spin_unlock_irqrestore(&lock,flags);
-}
-
-static int timer_open(int dev, int mode)
-{
- if (opened)
- return -EBUSY;
- tmr_reset();
- curr_tempo = 60;
- curr_timebase = 100;
- opened = 1;
- reprogram_timer();
- return 0;
-}
-
-static void timer_close(int dev)
-{
- opened = tmr_running = 0;
- tmr->tmr_disable(tmr->dev);
-}
-
-static int timer_event(int dev, unsigned char *event)
-{
- unsigned char cmd = event[1];
- unsigned long parm = *(int *) &event[4];
-
- switch (cmd)
- {
- case TMR_WAIT_REL:
- parm += prev_event_time;
- case TMR_WAIT_ABS:
- if (parm > 0)
- {
- long time;
-
- if (parm <= curr_ticks) /* It's the time */
- return TIMER_NOT_ARMED;
- time = parm;
- next_event_time = prev_event_time = time;
- return TIMER_ARMED;
- }
- break;
-
- case TMR_START:
- tmr_reset();
- tmr_running = 1;
- reprogram_timer();
- break;
-
- case TMR_STOP:
- tmr_running = 0;
- break;
-
- case TMR_CONTINUE:
- tmr_running = 1;
- reprogram_timer();
- break;
-
- case TMR_TEMPO:
- if (parm)
- {
- if (parm < 8)
- parm = 8;
- if (parm > 250)
- parm = 250;
- tmr_offs = tmr_ctr;
- ticks_offs += tmr2ticks(tmr_ctr);
- tmr_ctr = 0;
- curr_tempo = parm;
- reprogram_timer();
- }
- break;
-
- case TMR_ECHO:
- seq_copy_to_input(event, 8);
- break;
-
- default:;
- }
- return TIMER_NOT_ARMED;
-}
-
-static unsigned long timer_get_time(int dev)
-{
- if (!opened)
- return 0;
- return curr_ticks;
-}
-
-static int timer_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
- int __user *p = arg;
- int val;
-
- switch (cmd)
- {
- case SNDCTL_TMR_SOURCE:
- val = TMR_INTERNAL;
- break;
-
- case SNDCTL_TMR_START:
- tmr_reset();
- tmr_running = 1;
- return 0;
-
- case SNDCTL_TMR_STOP:
- tmr_running = 0;
- return 0;
-
- case SNDCTL_TMR_CONTINUE:
- tmr_running = 1;
- return 0;
-
- case SNDCTL_TMR_TIMEBASE:
- if (get_user(val, p))
- return -EFAULT;
- if (val)
- {
- if (val < 1)
- val = 1;
- if (val > 1000)
- val = 1000;
- curr_timebase = val;
- }
- val = curr_timebase;
- break;
-
- case SNDCTL_TMR_TEMPO:
- if (get_user(val, p))
- return -EFAULT;
- if (val)
- {
- if (val < 8)
- val = 8;
- if (val > 250)
- val = 250;
- tmr_offs = tmr_ctr;
- ticks_offs += tmr2ticks(tmr_ctr);
- tmr_ctr = 0;
- curr_tempo = val;
- reprogram_timer();
- }
- val = curr_tempo;
- break;
-
- case SNDCTL_SEQ_CTRLRATE:
- if (get_user(val, p))
- return -EFAULT;
- if (val != 0) /* Can't change */
- return -EINVAL;
- val = ((curr_tempo * curr_timebase) + 30) / 60;
- break;
-
- case SNDCTL_SEQ_GETTIME:
- val = curr_ticks;
- break;
-
- case SNDCTL_TMR_METRONOME:
- default:
- return -EINVAL;
- }
- return put_user(val, p);
-}
-
-static void timer_arm(int dev, long time)
-{
- if (time < 0)
- time = curr_ticks + 1;
- else if (time <= curr_ticks) /* It's the time */
- return;
-
- next_event_time = prev_event_time = time;
- return;
-}
-
-static struct sound_timer_operations sound_timer =
-{
- .owner = THIS_MODULE,
- .info = {"Sound Timer", 0},
- .priority = 1, /* Priority */
- .devlink = 0, /* Local device link */
- .open = timer_open,
- .close = timer_close,
- .event = timer_event,
- .get_time = timer_get_time,
- .ioctl = timer_ioctl,
- .arm_timer = timer_arm
-};
-
-void sound_timer_interrupt(void)
-{
- unsigned long flags;
-
- if (!opened)
- return;
-
- tmr->tmr_restart(tmr->dev);
-
- if (!tmr_running)
- return;
-
- spin_lock_irqsave(&lock,flags);
- tmr_ctr++;
- curr_ticks = ticks_offs + tmr2ticks(tmr_ctr);
-
- if (curr_ticks >= next_event_time)
- {
- next_event_time = (unsigned long) -1;
- sequencer_timer(0);
- }
- spin_unlock_irqrestore(&lock,flags);
-}
-EXPORT_SYMBOL(sound_timer_interrupt);
-
-void sound_timer_init(struct sound_lowlev_timer *t, char *name)
-{
- int n;
-
- if (initialized)
- {
- if (t->priority <= tmr->priority)
- return; /* There is already a similar or better timer */
- tmr = t;
- return;
- }
- initialized = 1;
- tmr = t;
-
- n = sound_alloc_timerdev();
- if (n == -1)
- n = 0; /* Overwrite the system timer */
- strlcpy(sound_timer.info.name, name, sizeof(sound_timer.info.name));
- sound_timer_devs[n] = &sound_timer;
-}
-EXPORT_SYMBOL(sound_timer_init);
-
diff --git a/ANDROID_3.4.5/sound/oss/soundcard.c b/ANDROID_3.4.5/sound/oss/soundcard.c
deleted file mode 100644
index 7c7793a0..00000000
--- a/ANDROID_3.4.5/sound/oss/soundcard.c
+++ /dev/null
@@ -1,739 +0,0 @@
-/*
- * linux/sound/oss/soundcard.c
- *
- * Sound card driver for Linux
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- *
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
- * integrated sound_switch.c
- * Stefan Reinauer : integrated /proc/sound (equals to /dev/sndstat,
- * which should disappear in the near future)
- * Eric Dumas : devfs support (22-Jan-98) <dumas@linux.eu.org> with
- * fixups by C. Scott Ananian <cananian@alumni.princeton.edu>
- * Richard Gooch : moved common (non OSS-specific) devices to sound_core.c
- * Rob Riggs : Added persistent DMA buffers support (1998/10/17)
- * Christoph Hellwig : Some cleanup work (2000/03/01)
- */
-
-
-#include "sound_config.h"
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/fcntl.h>
-#include <linux/ctype.h>
-#include <linux/stddef.h>
-#include <linux/kmod.h>
-#include <linux/kernel.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <linux/wait.h>
-#include <linux/ioport.h>
-#include <linux/major.h>
-#include <linux/delay.h>
-#include <linux/proc_fs.h>
-#include <linux/mutex.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/device.h>
-
-/*
- * This ought to be moved into include/asm/dma.h
- */
-#ifndef valid_dma
-#define valid_dma(n) ((n) >= 0 && (n) < MAX_DMA_CHANNELS && (n) != 4)
-#endif
-
-/*
- * Table for permanently allocated memory (used when unloading the module)
- */
-void * sound_mem_blocks[MAX_MEM_BLOCKS];
-static DEFINE_MUTEX(soundcard_mutex);
-int sound_nblocks = 0;
-
-/* Persistent DMA buffers */
-#ifdef CONFIG_SOUND_DMAP
-int sound_dmap_flag = 1;
-#else
-int sound_dmap_flag = 0;
-#endif
-
-static char dma_alloc_map[MAX_DMA_CHANNELS];
-
-#define DMA_MAP_UNAVAIL 0
-#define DMA_MAP_FREE 1
-#define DMA_MAP_BUSY 2
-
-
-unsigned long seq_time = 0; /* Time for /dev/sequencer */
-extern struct class *sound_class;
-
-/*
- * Table for configurable mixer volume handling
- */
-static mixer_vol_table mixer_vols[MAX_MIXER_DEV];
-static int num_mixer_volumes;
-
-int *load_mixer_volumes(char *name, int *levels, int present)
-{
- int i, n;
-
- for (i = 0; i < num_mixer_volumes; i++) {
- if (strncmp(name, mixer_vols[i].name, 32) == 0) {
- if (present)
- mixer_vols[i].num = i;
- return mixer_vols[i].levels;
- }
- }
- if (num_mixer_volumes >= MAX_MIXER_DEV) {
- printk(KERN_ERR "Sound: Too many mixers (%s)\n", name);
- return levels;
- }
- n = num_mixer_volumes++;
-
- strncpy(mixer_vols[n].name, name, 32);
-
- if (present)
- mixer_vols[n].num = n;
- else
- mixer_vols[n].num = -1;
-
- for (i = 0; i < 32; i++)
- mixer_vols[n].levels[i] = levels[i];
- return mixer_vols[n].levels;
-}
-EXPORT_SYMBOL(load_mixer_volumes);
-
-static int set_mixer_levels(void __user * arg)
-{
- /* mixer_vol_table is 174 bytes, so IMHO no reason to not allocate it on the stack */
- mixer_vol_table buf;
-
- if (__copy_from_user(&buf, arg, sizeof(buf)))
- return -EFAULT;
- load_mixer_volumes(buf.name, buf.levels, 0);
- if (__copy_to_user(arg, &buf, sizeof(buf)))
- return -EFAULT;
- return 0;
-}
-
-static int get_mixer_levels(void __user * arg)
-{
- int n;
-
- if (__get_user(n, (int __user *)(&(((mixer_vol_table __user *)arg)->num))))
- return -EFAULT;
- if (n < 0 || n >= num_mixer_volumes)
- return -EINVAL;
- if (__copy_to_user(arg, &mixer_vols[n], sizeof(mixer_vol_table)))
- return -EFAULT;
- return 0;
-}
-
-/* 4K page size but our output routines use some slack for overruns */
-#define PROC_BLOCK_SIZE (3*1024)
-
-static ssize_t sound_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
-{
- int dev = iminor(file->f_path.dentry->d_inode);
- int ret = -EINVAL;
-
- /*
- * The OSS drivers aren't remotely happy without this locking,
- * and unless someone fixes them when they are about to bite the
- * big one anyway, we might as well bandage here..
- */
-
- mutex_lock(&soundcard_mutex);
-
- DEB(printk("sound_read(dev=%d, count=%d)\n", dev, count));
- switch (dev & 0x0f) {
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- ret = audio_read(dev, file, buf, count);
- break;
-
- case SND_DEV_SEQ:
- case SND_DEV_SEQ2:
- ret = sequencer_read(dev, file, buf, count);
- break;
-
- case SND_DEV_MIDIN:
- ret = MIDIbuf_read(dev, file, buf, count);
- }
- mutex_unlock(&soundcard_mutex);
- return ret;
-}
-
-static ssize_t sound_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
-{
- int dev = iminor(file->f_path.dentry->d_inode);
- int ret = -EINVAL;
-
- mutex_lock(&soundcard_mutex);
- DEB(printk("sound_write(dev=%d, count=%d)\n", dev, count));
- switch (dev & 0x0f) {
- case SND_DEV_SEQ:
- case SND_DEV_SEQ2:
- ret = sequencer_write(dev, file, buf, count);
- break;
-
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- ret = audio_write(dev, file, buf, count);
- break;
-
- case SND_DEV_MIDIN:
- ret = MIDIbuf_write(dev, file, buf, count);
- break;
- }
- mutex_unlock(&soundcard_mutex);
- return ret;
-}
-
-static int sound_open(struct inode *inode, struct file *file)
-{
- int dev = iminor(inode);
- int retval;
-
- DEB(printk("sound_open(dev=%d)\n", dev));
- if ((dev >= SND_NDEVS) || (dev < 0)) {
- printk(KERN_ERR "Invalid minor device %d\n", dev);
- return -ENXIO;
- }
- mutex_lock(&soundcard_mutex);
- switch (dev & 0x0f) {
- case SND_DEV_CTL:
- dev >>= 4;
- if (dev >= 0 && dev < MAX_MIXER_DEV && mixer_devs[dev] == NULL) {
- request_module("mixer%d", dev);
- }
- retval = -ENXIO;
- if (dev && (dev >= num_mixers || mixer_devs[dev] == NULL))
- break;
-
- if (!try_module_get(mixer_devs[dev]->owner))
- break;
-
- retval = 0;
- break;
-
- case SND_DEV_SEQ:
- case SND_DEV_SEQ2:
- retval = sequencer_open(dev, file);
- break;
-
- case SND_DEV_MIDIN:
- retval = MIDIbuf_open(dev, file);
- break;
-
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- retval = audio_open(dev, file);
- break;
-
- default:
- printk(KERN_ERR "Invalid minor device %d\n", dev);
- retval = -ENXIO;
- }
-
- mutex_unlock(&soundcard_mutex);
- return retval;
-}
-
-static int sound_release(struct inode *inode, struct file *file)
-{
- int dev = iminor(inode);
-
- mutex_lock(&soundcard_mutex);
- DEB(printk("sound_release(dev=%d)\n", dev));
- switch (dev & 0x0f) {
- case SND_DEV_CTL:
- module_put(mixer_devs[dev >> 4]->owner);
- break;
-
- case SND_DEV_SEQ:
- case SND_DEV_SEQ2:
- sequencer_release(dev, file);
- break;
-
- case SND_DEV_MIDIN:
- MIDIbuf_release(dev, file);
- break;
-
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- audio_release(dev, file);
- break;
-
- default:
- printk(KERN_ERR "Sound error: Releasing unknown device 0x%02x\n", dev);
- }
- mutex_unlock(&soundcard_mutex);
-
- return 0;
-}
-
-static int get_mixer_info(int dev, void __user *arg)
-{
- mixer_info info;
- memset(&info, 0, sizeof(info));
- strlcpy(info.id, mixer_devs[dev]->id, sizeof(info.id));
- strlcpy(info.name, mixer_devs[dev]->name, sizeof(info.name));
- info.modify_counter = mixer_devs[dev]->modify_counter;
- if (__copy_to_user(arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
-}
-
-static int get_old_mixer_info(int dev, void __user *arg)
-{
- _old_mixer_info info;
- memset(&info, 0, sizeof(info));
- strlcpy(info.id, mixer_devs[dev]->id, sizeof(info.id));
- strlcpy(info.name, mixer_devs[dev]->name, sizeof(info.name));
- if (copy_to_user(arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
-}
-
-static int sound_mixer_ioctl(int mixdev, unsigned int cmd, void __user *arg)
-{
- if (mixdev < 0 || mixdev >= MAX_MIXER_DEV)
- return -ENXIO;
- /* Try to load the mixer... */
- if (mixer_devs[mixdev] == NULL) {
- request_module("mixer%d", mixdev);
- }
- if (mixdev >= num_mixers || !mixer_devs[mixdev])
- return -ENXIO;
- if (cmd == SOUND_MIXER_INFO)
- return get_mixer_info(mixdev, arg);
- if (cmd == SOUND_OLD_MIXER_INFO)
- return get_old_mixer_info(mixdev, arg);
- if (_SIOC_DIR(cmd) & _SIOC_WRITE)
- mixer_devs[mixdev]->modify_counter++;
- if (!mixer_devs[mixdev]->ioctl)
- return -EINVAL;
- return mixer_devs[mixdev]->ioctl(mixdev, cmd, arg);
-}
-
-static long sound_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- int len = 0, dtype;
- int dev = iminor(file->f_dentry->d_inode);
- long ret = -EINVAL;
- void __user *p = (void __user *)arg;
-
- if (_SIOC_DIR(cmd) != _SIOC_NONE && _SIOC_DIR(cmd) != 0) {
- /*
- * Have to validate the address given by the process.
- */
- len = _SIOC_SIZE(cmd);
- if (len < 1 || len > 65536 || !p)
- return -EFAULT;
- if (_SIOC_DIR(cmd) & _SIOC_WRITE)
- if (!access_ok(VERIFY_READ, p, len))
- return -EFAULT;
- if (_SIOC_DIR(cmd) & _SIOC_READ)
- if (!access_ok(VERIFY_WRITE, p, len))
- return -EFAULT;
- }
- DEB(printk("sound_ioctl(dev=%d, cmd=0x%x, arg=0x%x)\n", dev, cmd, arg));
- if (cmd == OSS_GETVERSION)
- return __put_user(SOUND_VERSION, (int __user *)p);
-
- mutex_lock(&soundcard_mutex);
- if (_IOC_TYPE(cmd) == 'M' && num_mixers > 0 && /* Mixer ioctl */
- (dev & 0x0f) != SND_DEV_CTL) {
- dtype = dev & 0x0f;
- switch (dtype) {
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- ret = sound_mixer_ioctl(audio_devs[dev >> 4]->mixer_dev,
- cmd, p);
- break;
- default:
- ret = sound_mixer_ioctl(dev >> 4, cmd, p);
- break;
- }
- mutex_unlock(&soundcard_mutex);
- return ret;
- }
-
- switch (dev & 0x0f) {
- case SND_DEV_CTL:
- if (cmd == SOUND_MIXER_GETLEVELS)
- ret = get_mixer_levels(p);
- else if (cmd == SOUND_MIXER_SETLEVELS)
- ret = set_mixer_levels(p);
- else
- ret = sound_mixer_ioctl(dev >> 4, cmd, p);
- break;
-
- case SND_DEV_SEQ:
- case SND_DEV_SEQ2:
- ret = sequencer_ioctl(dev, file, cmd, p);
- break;
-
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- ret = audio_ioctl(dev, file, cmd, p);
- break;
-
- case SND_DEV_MIDIN:
- ret = MIDIbuf_ioctl(dev, file, cmd, p);
- break;
-
- }
- mutex_unlock(&soundcard_mutex);
- return ret;
-}
-
-static unsigned int sound_poll(struct file *file, poll_table * wait)
-{
- struct inode *inode = file->f_path.dentry->d_inode;
- int dev = iminor(inode);
-
- DEB(printk("sound_poll(dev=%d)\n", dev));
- switch (dev & 0x0f) {
- case SND_DEV_SEQ:
- case SND_DEV_SEQ2:
- return sequencer_poll(dev, file, wait);
-
- case SND_DEV_MIDIN:
- return MIDIbuf_poll(dev, file, wait);
-
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- return DMAbuf_poll(file, dev >> 4, wait);
- }
- return 0;
-}
-
-static int sound_mmap(struct file *file, struct vm_area_struct *vma)
-{
- int dev_class;
- unsigned long size;
- struct dma_buffparms *dmap = NULL;
- int dev = iminor(file->f_path.dentry->d_inode);
-
- dev_class = dev & 0x0f;
- dev >>= 4;
-
- if (dev_class != SND_DEV_DSP && dev_class != SND_DEV_DSP16 && dev_class != SND_DEV_AUDIO) {
- printk(KERN_ERR "Sound: mmap() not supported for other than audio devices\n");
- return -EINVAL;
- }
- mutex_lock(&soundcard_mutex);
- if (vma->vm_flags & VM_WRITE) /* Map write and read/write to the output buf */
- dmap = audio_devs[dev]->dmap_out;
- else if (vma->vm_flags & VM_READ)
- dmap = audio_devs[dev]->dmap_in;
- else {
- printk(KERN_ERR "Sound: Undefined mmap() access\n");
- mutex_unlock(&soundcard_mutex);
- return -EINVAL;
- }
-
- if (dmap == NULL) {
- printk(KERN_ERR "Sound: mmap() error. dmap == NULL\n");
- mutex_unlock(&soundcard_mutex);
- return -EIO;
- }
- if (dmap->raw_buf == NULL) {
- printk(KERN_ERR "Sound: mmap() called when raw_buf == NULL\n");
- mutex_unlock(&soundcard_mutex);
- return -EIO;
- }
- if (dmap->mapping_flags) {
- printk(KERN_ERR "Sound: mmap() called twice for the same DMA buffer\n");
- mutex_unlock(&soundcard_mutex);
- return -EIO;
- }
- if (vma->vm_pgoff != 0) {
- printk(KERN_ERR "Sound: mmap() offset must be 0.\n");
- mutex_unlock(&soundcard_mutex);
- return -EINVAL;
- }
- size = vma->vm_end - vma->vm_start;
-
- if (size != dmap->bytes_in_use) {
- printk(KERN_WARNING "Sound: mmap() size = %ld. Should be %d\n", size, dmap->bytes_in_use);
- }
- if (remap_pfn_range(vma, vma->vm_start,
- virt_to_phys(dmap->raw_buf) >> PAGE_SHIFT,
- vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
- mutex_unlock(&soundcard_mutex);
- return -EAGAIN;
- }
-
- dmap->mapping_flags |= DMA_MAP_MAPPED;
-
- if( audio_devs[dev]->d->mmap)
- audio_devs[dev]->d->mmap(dev);
-
- memset(dmap->raw_buf,
- dmap->neutral_byte,
- dmap->bytes_in_use);
- mutex_unlock(&soundcard_mutex);
- return 0;
-}
-
-const struct file_operations oss_sound_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .read = sound_read,
- .write = sound_write,
- .poll = sound_poll,
- .unlocked_ioctl = sound_ioctl,
- .mmap = sound_mmap,
- .open = sound_open,
- .release = sound_release,
-};
-
-/*
- * Create the required special subdevices
- */
-
-static int create_special_devices(void)
-{
- int seq1,seq2;
- seq1=register_sound_special(&oss_sound_fops, 1);
- if(seq1==-1)
- goto bad;
- seq2=register_sound_special(&oss_sound_fops, 8);
- if(seq2!=-1)
- return 0;
- unregister_sound_special(1);
-bad:
- return -1;
-}
-
-
-static int dmabuf;
-static int dmabug;
-
-module_param(dmabuf, int, 0444);
-module_param(dmabug, int, 0444);
-
-/* additional minors for compatibility */
-struct oss_minor_dev {
- unsigned short minor;
- unsigned int enabled;
-} dev_list[] = {
- { SND_DEV_DSP16 },
- { SND_DEV_AUDIO },
-};
-
-static int __init oss_init(void)
-{
- int err;
- int i, j;
-
-#ifdef CONFIG_PCI
- if(dmabug)
- isa_dma_bridge_buggy = dmabug;
-#endif
-
- err = create_special_devices();
- if (err) {
- printk(KERN_ERR "sound: driver already loaded/included in kernel\n");
- return err;
- }
-
- /* Protecting the innocent */
- sound_dmap_flag = (dmabuf > 0 ? 1 : 0);
-
- for (i = 0; i < ARRAY_SIZE(dev_list); i++) {
- j = 0;
- do {
- unsigned short minor = dev_list[i].minor + j * 0x10;
- if (!register_sound_special(&oss_sound_fops, minor))
- dev_list[i].enabled = (1 << j);
- } while (++j < num_audiodevs);
- }
-
- if (sound_nblocks >= MAX_MEM_BLOCKS - 1)
- printk(KERN_ERR "Sound warning: Deallocation table was too small.\n");
-
- return 0;
-}
-
-static void __exit oss_cleanup(void)
-{
- int i, j;
-
- for (i = 0; i < ARRAY_SIZE(dev_list); i++) {
- j = 0;
- do {
- if (dev_list[i].enabled & (1 << j))
- unregister_sound_special(dev_list[i].minor);
- } while (++j < num_audiodevs);
- }
-
- unregister_sound_special(1);
- unregister_sound_special(8);
-
- sound_stop_timer();
-
- sequencer_unload();
-
- for (i = 0; i < MAX_DMA_CHANNELS; i++)
- if (dma_alloc_map[i] != DMA_MAP_UNAVAIL) {
- printk(KERN_ERR "Sound: Hmm, DMA%d was left allocated - fixed\n", i);
- sound_free_dma(i);
- }
-
- for (i = 0; i < sound_nblocks; i++)
- vfree(sound_mem_blocks[i]);
-
-}
-
-module_init(oss_init);
-module_exit(oss_cleanup);
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("OSS Sound subsystem");
-MODULE_AUTHOR("Hannu Savolainen, et al.");
-
-
-int sound_alloc_dma(int chn, char *deviceID)
-{
- int err;
-
- if ((err = request_dma(chn, deviceID)) != 0)
- return err;
-
- dma_alloc_map[chn] = DMA_MAP_FREE;
-
- return 0;
-}
-EXPORT_SYMBOL(sound_alloc_dma);
-
-int sound_open_dma(int chn, char *deviceID)
-{
- if (!valid_dma(chn)) {
- printk(KERN_ERR "sound_open_dma: Invalid DMA channel %d\n", chn);
- return 1;
- }
-
- if (dma_alloc_map[chn] != DMA_MAP_FREE) {
- printk("sound_open_dma: DMA channel %d busy or not allocated (%d)\n", chn, dma_alloc_map[chn]);
- return 1;
- }
- dma_alloc_map[chn] = DMA_MAP_BUSY;
- return 0;
-}
-EXPORT_SYMBOL(sound_open_dma);
-
-void sound_free_dma(int chn)
-{
- if (dma_alloc_map[chn] == DMA_MAP_UNAVAIL) {
- /* printk( "sound_free_dma: Bad access to DMA channel %d\n", chn); */
- return;
- }
- free_dma(chn);
- dma_alloc_map[chn] = DMA_MAP_UNAVAIL;
-}
-EXPORT_SYMBOL(sound_free_dma);
-
-void sound_close_dma(int chn)
-{
- if (dma_alloc_map[chn] != DMA_MAP_BUSY) {
- printk(KERN_ERR "sound_close_dma: Bad access to DMA channel %d\n", chn);
- return;
- }
- dma_alloc_map[chn] = DMA_MAP_FREE;
-}
-EXPORT_SYMBOL(sound_close_dma);
-
-static void do_sequencer_timer(unsigned long dummy)
-{
- sequencer_timer(0);
-}
-
-
-static DEFINE_TIMER(seq_timer, do_sequencer_timer, 0, 0);
-
-void request_sound_timer(int count)
-{
- extern unsigned long seq_time;
-
- if (count < 0) {
- seq_timer.expires = (-count) + jiffies;
- add_timer(&seq_timer);
- return;
- }
- count += seq_time;
-
- count -= jiffies;
-
- if (count < 1)
- count = 1;
-
- seq_timer.expires = (count) + jiffies;
- add_timer(&seq_timer);
-}
-
-void sound_stop_timer(void)
-{
- del_timer(&seq_timer);
-}
-
-void conf_printf(char *name, struct address_info *hw_config)
-{
-#ifndef CONFIG_SOUND_TRACEINIT
- return;
-#else
- printk("<%s> at 0x%03x", name, hw_config->io_base);
-
- if (hw_config->irq)
- printk(" irq %d", (hw_config->irq > 0) ? hw_config->irq : -hw_config->irq);
-
- if (hw_config->dma != -1 || hw_config->dma2 != -1)
- {
- printk(" dma %d", hw_config->dma);
- if (hw_config->dma2 != -1)
- printk(",%d", hw_config->dma2);
- }
- printk("\n");
-#endif
-}
-EXPORT_SYMBOL(conf_printf);
-
-void conf_printf2(char *name, int base, int irq, int dma, int dma2)
-{
-#ifndef CONFIG_SOUND_TRACEINIT
- return;
-#else
- printk("<%s> at 0x%03x", name, base);
-
- if (irq)
- printk(" irq %d", (irq > 0) ? irq : -irq);
-
- if (dma != -1 || dma2 != -1)
- {
- printk(" dma %d", dma);
- if (dma2 != -1)
- printk(",%d", dma2);
- }
- printk("\n");
-#endif
-}
-EXPORT_SYMBOL(conf_printf2);
-
diff --git a/ANDROID_3.4.5/sound/oss/soundvers.h b/ANDROID_3.4.5/sound/oss/soundvers.h
deleted file mode 100644
index e9084d2f..00000000
--- a/ANDROID_3.4.5/sound/oss/soundvers.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#define SOUND_VERSION_STRING "3.8s2++-971130"
-#define SOUND_INTERNAL_VERSION 0x030804
diff --git a/ANDROID_3.4.5/sound/oss/swarm_cs4297a.c b/ANDROID_3.4.5/sound/oss/swarm_cs4297a.c
deleted file mode 100644
index 09d46484..00000000
--- a/ANDROID_3.4.5/sound/oss/swarm_cs4297a.c
+++ /dev/null
@@ -1,2768 +0,0 @@
-/*******************************************************************************
-*
-* "swarm_cs4297a.c" -- Cirrus Logic-Crystal CS4297a linux audio driver.
-*
-* Copyright (C) 2001 Broadcom Corporation.
-* Copyright (C) 2000,2001 Cirrus Logic Corp.
-* -- adapted from drivers by Thomas Sailer,
-* -- but don't bug him; Problems should go to:
-* -- tom woller (twoller@crystal.cirrus.com) or
-* (audio@crystal.cirrus.com).
-* -- adapted from cs4281 PCI driver for cs4297a on
-* BCM1250 Synchronous Serial interface
-* (Kip Walker, Broadcom Corp.)
-* Copyright (C) 2004 Maciej W. Rozycki
-* Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Module command line parameters:
-* none
-*
-* Supported devices:
-* /dev/dsp standard /dev/dsp device, (mostly) OSS compatible
-* /dev/mixer standard /dev/mixer device, (mostly) OSS compatible
-* /dev/midi simple MIDI UART interface, no ioctl
-*
-* Modification History
-* 08/20/00 trw - silence and no stopping DAC until release
-* 08/23/00 trw - added CS_DBG statements, fix interrupt hang issue on DAC stop.
-* 09/18/00 trw - added 16bit only record with conversion
-* 09/24/00 trw - added Enhanced Full duplex (separate simultaneous
-* capture/playback rates)
-* 10/03/00 trw - fixed mmap (fixed GRECORD and the XMMS mmap test plugin
-* libOSSm.so)
-* 10/11/00 trw - modified for 2.4.0-test9 kernel enhancements (NR_MAP removal)
-* 11/03/00 trw - fixed interrupt loss/stutter, added debug.
-* 11/10/00 bkz - added __devinit to cs4297a_hw_init()
-* 11/10/00 trw - fixed SMP and capture spinlock hang.
-* 12/04/00 trw - cleaned up CSDEBUG flags and added "defaultorder" moduleparm.
-* 12/05/00 trw - fixed polling (myth2), and added underrun swptr fix.
-* 12/08/00 trw - added PM support.
-* 12/14/00 trw - added wrapper code, builds under 2.4.0, 2.2.17-20, 2.2.17-8
-* (RH/Dell base), 2.2.18, 2.2.12. cleaned up code mods by ident.
-* 12/19/00 trw - added PM support for 2.2 base (apm_callback). other PM cleanup.
-* 12/21/00 trw - added fractional "defaultorder" inputs. if >100 then use
-* defaultorder-100 as power of 2 for the buffer size. example:
-* 106 = 2^(106-100) = 2^6 = 64 bytes for the buffer size.
-*
-*******************************************************************************/
-
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/ac97_codec.h>
-#include <linux/pci.h>
-#include <linux/bitops.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/mutex.h>
-#include <linux/kernel.h>
-
-#include <asm/byteorder.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#include <asm/sibyte/sb1250_regs.h>
-#include <asm/sibyte/sb1250_int.h>
-#include <asm/sibyte/sb1250_dma.h>
-#include <asm/sibyte/sb1250_scd.h>
-#include <asm/sibyte/sb1250_syncser.h>
-#include <asm/sibyte/sb1250_mac.h>
-#include <asm/sibyte/sb1250.h>
-
-struct cs4297a_state;
-
-static DEFINE_MUTEX(swarm_cs4297a_mutex);
-static void stop_dac(struct cs4297a_state *s);
-static void stop_adc(struct cs4297a_state *s);
-static void start_dac(struct cs4297a_state *s);
-static void start_adc(struct cs4297a_state *s);
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-
-// ---------------------------------------------------------------------
-
-#define CS4297a_MAGIC 0xf00beef1
-
-// buffer order determines the size of the dma buffer for the driver.
-// under Linux, a smaller buffer allows more responsiveness from many of the
-// applications (e.g. games). A larger buffer allows some of the apps (esound)
-// to not underrun the dma buffer as easily. As default, use 32k (order=3)
-// rather than 64k as some of the games work more responsively.
-// log base 2( buff sz = 32k).
-
-//
-// Turn on/off debugging compilation by commenting out "#define CSDEBUG"
-//
-#define CSDEBUG 0
-#if CSDEBUG
-#define CSDEBUG_INTERFACE 1
-#else
-#undef CSDEBUG_INTERFACE
-#endif
-//
-// cs_debugmask areas
-//
-#define CS_INIT 0x00000001 // initialization and probe functions
-#define CS_ERROR 0x00000002 // tmp debugging bit placeholder
-#define CS_INTERRUPT 0x00000004 // interrupt handler (separate from all other)
-#define CS_FUNCTION 0x00000008 // enter/leave functions
-#define CS_WAVE_WRITE 0x00000010 // write information for wave
-#define CS_WAVE_READ 0x00000020 // read information for wave
-#define CS_AC97 0x00000040 // AC97 register access
-#define CS_DESCR 0x00000080 // descriptor management
-#define CS_OPEN 0x00000400 // all open functions in the driver
-#define CS_RELEASE 0x00000800 // all release functions in the driver
-#define CS_PARMS 0x00001000 // functional and operational parameters
-#define CS_IOCTL 0x00002000 // ioctl (non-mixer)
-#define CS_TMP 0x10000000 // tmp debug mask bit
-
-//
-// CSDEBUG is usual mode is set to 1, then use the
-// cs_debuglevel and cs_debugmask to turn on or off debugging.
-// Debug level of 1 has been defined to be kernel errors and info
-// that should be printed on any released driver.
-//
-#if CSDEBUG
-#define CS_DBGOUT(mask,level,x) if((cs_debuglevel >= (level)) && ((mask) & cs_debugmask) ) {x;}
-#else
-#define CS_DBGOUT(mask,level,x)
-#endif
-
-#if CSDEBUG
-static unsigned long cs_debuglevel = 4; // levels range from 1-9
-static unsigned long cs_debugmask = CS_INIT /*| CS_IOCTL*/;
-module_param(cs_debuglevel, int, 0);
-module_param(cs_debugmask, int, 0);
-#endif
-#define CS_TRUE 1
-#define CS_FALSE 0
-
-#define CS_TYPE_ADC 0
-#define CS_TYPE_DAC 1
-
-#define SER_BASE (A_SER_BASE_1 + KSEG1)
-#define SS_CSR(t) (SER_BASE+t)
-#define SS_TXTBL(t) (SER_BASE+R_SER_TX_TABLE_BASE+(t*8))
-#define SS_RXTBL(t) (SER_BASE+R_SER_RX_TABLE_BASE+(t*8))
-
-#define FRAME_BYTES 32
-#define FRAME_SAMPLE_BYTES 4
-
-/* Should this be variable? */
-#define SAMPLE_BUF_SIZE (16*1024)
-#define SAMPLE_FRAME_COUNT (SAMPLE_BUF_SIZE / FRAME_SAMPLE_BYTES)
-/* The driver can explode/shrink the frames to/from a smaller sample
- buffer */
-#define DMA_BLOAT_FACTOR 1
-#define DMA_DESCR (SAMPLE_FRAME_COUNT / DMA_BLOAT_FACTOR)
-#define DMA_BUF_SIZE (DMA_DESCR * FRAME_BYTES)
-
-/* Use the maxmium count (255 == 5.1 ms between interrupts) */
-#define DMA_INT_CNT ((1 << S_DMA_INT_PKTCNT) - 1)
-
-/* Figure this out: how many TX DMAs ahead to schedule a reg access */
-#define REG_LATENCY 150
-
-#define FRAME_TX_US 20
-
-#define SERDMA_NEXTBUF(d,f) (((d)->f+1) % (d)->ringsz)
-
-static const char invalid_magic[] =
- KERN_CRIT "cs4297a: invalid magic value\n";
-
-#define VALIDATE_STATE(s) \
-({ \
- if (!(s) || (s)->magic != CS4297a_MAGIC) { \
- printk(invalid_magic); \
- return -ENXIO; \
- } \
-})
-
-struct list_head cs4297a_devs = { &cs4297a_devs, &cs4297a_devs };
-
-typedef struct serdma_descr_s {
- u64 descr_a;
- u64 descr_b;
-} serdma_descr_t;
-
-typedef unsigned long paddr_t;
-
-typedef struct serdma_s {
- unsigned ringsz;
- serdma_descr_t *descrtab;
- serdma_descr_t *descrtab_end;
- paddr_t descrtab_phys;
-
- serdma_descr_t *descr_add;
- serdma_descr_t *descr_rem;
-
- u64 *dma_buf; // buffer for DMA contents (frames)
- paddr_t dma_buf_phys;
- u16 *sample_buf; // tmp buffer for sample conversions
- u16 *sb_swptr;
- u16 *sb_hwptr;
- u16 *sb_end;
-
- dma_addr_t dmaaddr;
-// unsigned buforder; // Log base 2 of 'dma_buf' size in bytes..
- unsigned numfrag; // # of 'fragments' in the buffer.
- unsigned fragshift; // Log base 2 of fragment size.
- unsigned hwptr, swptr;
- unsigned total_bytes; // # bytes process since open.
- unsigned blocks; // last returned blocks value GETOPTR
- unsigned wakeup; // interrupt occurred on block
- int count;
- unsigned underrun; // underrun flag
- unsigned error; // over/underrun
- wait_queue_head_t wait;
- wait_queue_head_t reg_wait;
- // redundant, but makes calculations easier
- unsigned fragsize; // 2**fragshift..
- unsigned sbufsz; // 2**buforder.
- unsigned fragsamples;
- // OSS stuff
- unsigned mapped:1; // Buffer mapped in cs4297a_mmap()?
- unsigned ready:1; // prog_dmabuf_dac()/adc() successful?
- unsigned endcleared:1;
- unsigned type:1; // adc or dac buffer (CS_TYPE_XXX)
- unsigned ossfragshift;
- int ossmaxfrags;
- unsigned subdivision;
-} serdma_t;
-
-struct cs4297a_state {
- // magic
- unsigned int magic;
-
- struct list_head list;
-
- // soundcore stuff
- int dev_audio;
- int dev_mixer;
-
- // hardware resources
- unsigned int irq;
-
- struct {
- unsigned int rx_ovrrn; /* FIFO */
- unsigned int rx_overflow; /* staging buffer */
- unsigned int tx_underrun;
- unsigned int rx_bad;
- unsigned int rx_good;
- } stats;
-
- // mixer registers
- struct {
- unsigned short vol[10];
- unsigned int recsrc;
- unsigned int modcnt;
- unsigned short micpreamp;
- } mix;
-
- // wave stuff
- struct properties {
- unsigned fmt;
- unsigned fmt_original; // original requested format
- unsigned channels;
- unsigned rate;
- } prop_dac, prop_adc;
- unsigned conversion:1; // conversion from 16 to 8 bit in progress
- unsigned ena;
- spinlock_t lock;
- struct mutex open_mutex;
- struct mutex open_sem_adc;
- struct mutex open_sem_dac;
- fmode_t open_mode;
- wait_queue_head_t open_wait;
- wait_queue_head_t open_wait_adc;
- wait_queue_head_t open_wait_dac;
-
- dma_addr_t dmaaddr_sample_buf;
- unsigned buforder_sample_buf; // Log base 2 of 'dma_buf' size in bytes..
-
- serdma_t dma_dac, dma_adc;
-
- volatile u16 read_value;
- volatile u16 read_reg;
- volatile u64 reg_request;
-};
-
-#if 1
-#define prog_codec(a,b)
-#define dealloc_dmabuf(a,b);
-#endif
-
-static int prog_dmabuf_adc(struct cs4297a_state *s)
-{
- s->dma_adc.ready = 1;
- return 0;
-}
-
-
-static int prog_dmabuf_dac(struct cs4297a_state *s)
-{
- s->dma_dac.ready = 1;
- return 0;
-}
-
-static void clear_advance(void *buf, unsigned bsize, unsigned bptr,
- unsigned len, unsigned char c)
-{
- if (bptr + len > bsize) {
- unsigned x = bsize - bptr;
- memset(((char *) buf) + bptr, c, x);
- bptr = 0;
- len -= x;
- }
- CS_DBGOUT(CS_WAVE_WRITE, 4, printk(KERN_INFO
- "cs4297a: clear_advance(): memset %d at 0x%.8x for %d size \n",
- (unsigned)c, (unsigned)((char *) buf) + bptr, len));
- memset(((char *) buf) + bptr, c, len);
-}
-
-#if CSDEBUG
-
-// DEBUG ROUTINES
-
-#define SOUND_MIXER_CS_GETDBGLEVEL _SIOWR('M',120, int)
-#define SOUND_MIXER_CS_SETDBGLEVEL _SIOWR('M',121, int)
-#define SOUND_MIXER_CS_GETDBGMASK _SIOWR('M',122, int)
-#define SOUND_MIXER_CS_SETDBGMASK _SIOWR('M',123, int)
-
-static void cs_printioctl(unsigned int x)
-{
- unsigned int i;
- unsigned char vidx;
- // Index of mixtable1[] member is Device ID
- // and must be <= SOUND_MIXER_NRDEVICES.
- // Value of array member is index into s->mix.vol[]
- static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = {
- [SOUND_MIXER_PCM] = 1, // voice
- [SOUND_MIXER_LINE1] = 2, // AUX
- [SOUND_MIXER_CD] = 3, // CD
- [SOUND_MIXER_LINE] = 4, // Line
- [SOUND_MIXER_SYNTH] = 5, // FM
- [SOUND_MIXER_MIC] = 6, // Mic
- [SOUND_MIXER_SPEAKER] = 7, // Speaker
- [SOUND_MIXER_RECLEV] = 8, // Recording level
- [SOUND_MIXER_VOLUME] = 9 // Master Volume
- };
-
- switch (x) {
- case SOUND_MIXER_CS_GETDBGMASK:
- CS_DBGOUT(CS_IOCTL, 4,
- printk("SOUND_MIXER_CS_GETDBGMASK:\n"));
- break;
- case SOUND_MIXER_CS_GETDBGLEVEL:
- CS_DBGOUT(CS_IOCTL, 4,
- printk("SOUND_MIXER_CS_GETDBGLEVEL:\n"));
- break;
- case SOUND_MIXER_CS_SETDBGMASK:
- CS_DBGOUT(CS_IOCTL, 4,
- printk("SOUND_MIXER_CS_SETDBGMASK:\n"));
- break;
- case SOUND_MIXER_CS_SETDBGLEVEL:
- CS_DBGOUT(CS_IOCTL, 4,
- printk("SOUND_MIXER_CS_SETDBGLEVEL:\n"));
- break;
- case OSS_GETVERSION:
- CS_DBGOUT(CS_IOCTL, 4, printk("OSS_GETVERSION:\n"));
- break;
- case SNDCTL_DSP_SYNC:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SYNC:\n"));
- break;
- case SNDCTL_DSP_SETDUPLEX:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETDUPLEX:\n"));
- break;
- case SNDCTL_DSP_GETCAPS:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETCAPS:\n"));
- break;
- case SNDCTL_DSP_RESET:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_RESET:\n"));
- break;
- case SNDCTL_DSP_SPEED:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SPEED:\n"));
- break;
- case SNDCTL_DSP_STEREO:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_STEREO:\n"));
- break;
- case SNDCTL_DSP_CHANNELS:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_CHANNELS:\n"));
- break;
- case SNDCTL_DSP_GETFMTS:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETFMTS:\n"));
- break;
- case SNDCTL_DSP_SETFMT:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETFMT:\n"));
- break;
- case SNDCTL_DSP_POST:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_POST:\n"));
- break;
- case SNDCTL_DSP_GETTRIGGER:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETTRIGGER:\n"));
- break;
- case SNDCTL_DSP_SETTRIGGER:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETTRIGGER:\n"));
- break;
- case SNDCTL_DSP_GETOSPACE:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETOSPACE:\n"));
- break;
- case SNDCTL_DSP_GETISPACE:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETISPACE:\n"));
- break;
- case SNDCTL_DSP_NONBLOCK:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_NONBLOCK:\n"));
- break;
- case SNDCTL_DSP_GETODELAY:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETODELAY:\n"));
- break;
- case SNDCTL_DSP_GETIPTR:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETIPTR:\n"));
- break;
- case SNDCTL_DSP_GETOPTR:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETOPTR:\n"));
- break;
- case SNDCTL_DSP_GETBLKSIZE:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETBLKSIZE:\n"));
- break;
- case SNDCTL_DSP_SETFRAGMENT:
- CS_DBGOUT(CS_IOCTL, 4,
- printk("SNDCTL_DSP_SETFRAGMENT:\n"));
- break;
- case SNDCTL_DSP_SUBDIVIDE:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SUBDIVIDE:\n"));
- break;
- case SOUND_PCM_READ_RATE:
- CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_RATE:\n"));
- break;
- case SOUND_PCM_READ_CHANNELS:
- CS_DBGOUT(CS_IOCTL, 4,
- printk("SOUND_PCM_READ_CHANNELS:\n"));
- break;
- case SOUND_PCM_READ_BITS:
- CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_BITS:\n"));
- break;
- case SOUND_PCM_WRITE_FILTER:
- CS_DBGOUT(CS_IOCTL, 4,
- printk("SOUND_PCM_WRITE_FILTER:\n"));
- break;
- case SNDCTL_DSP_SETSYNCRO:
- CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETSYNCRO:\n"));
- break;
- case SOUND_PCM_READ_FILTER:
- CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_FILTER:\n"));
- break;
- case SOUND_MIXER_PRIVATE1:
- CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE1:\n"));
- break;
- case SOUND_MIXER_PRIVATE2:
- CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE2:\n"));
- break;
- case SOUND_MIXER_PRIVATE3:
- CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE3:\n"));
- break;
- case SOUND_MIXER_PRIVATE4:
- CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE4:\n"));
- break;
- case SOUND_MIXER_PRIVATE5:
- CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE5:\n"));
- break;
- case SOUND_MIXER_INFO:
- CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_INFO:\n"));
- break;
- case SOUND_OLD_MIXER_INFO:
- CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_OLD_MIXER_INFO:\n"));
- break;
-
- default:
- switch (_IOC_NR(x)) {
- case SOUND_MIXER_VOLUME:
- CS_DBGOUT(CS_IOCTL, 4,
- printk("SOUND_MIXER_VOLUME:\n"));
- break;
- case SOUND_MIXER_SPEAKER:
- CS_DBGOUT(CS_IOCTL, 4,
- printk("SOUND_MIXER_SPEAKER:\n"));
- break;
- case SOUND_MIXER_RECLEV:
- CS_DBGOUT(CS_IOCTL, 4,
- printk("SOUND_MIXER_RECLEV:\n"));
- break;
- case SOUND_MIXER_MIC:
- CS_DBGOUT(CS_IOCTL, 4,
- printk("SOUND_MIXER_MIC:\n"));
- break;
- case SOUND_MIXER_SYNTH:
- CS_DBGOUT(CS_IOCTL, 4,
- printk("SOUND_MIXER_SYNTH:\n"));
- break;
- case SOUND_MIXER_RECSRC:
- CS_DBGOUT(CS_IOCTL, 4,
- printk("SOUND_MIXER_RECSRC:\n"));
- break;
- case SOUND_MIXER_DEVMASK:
- CS_DBGOUT(CS_IOCTL, 4,
- printk("SOUND_MIXER_DEVMASK:\n"));
- break;
- case SOUND_MIXER_RECMASK:
- CS_DBGOUT(CS_IOCTL, 4,
- printk("SOUND_MIXER_RECMASK:\n"));
- break;
- case SOUND_MIXER_STEREODEVS:
- CS_DBGOUT(CS_IOCTL, 4,
- printk("SOUND_MIXER_STEREODEVS:\n"));
- break;
- case SOUND_MIXER_CAPS:
- CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_CAPS:\n"));
- break;
- default:
- i = _IOC_NR(x);
- if (i >= SOUND_MIXER_NRDEVICES
- || !(vidx = mixtable1[i])) {
- CS_DBGOUT(CS_IOCTL, 4, printk
- ("UNKNOWN IOCTL: 0x%.8x NR=%d\n",
- x, i));
- } else {
- CS_DBGOUT(CS_IOCTL, 4, printk
- ("SOUND_MIXER_IOCTL AC9x: 0x%.8x NR=%d\n",
- x, i));
- }
- break;
- }
- }
-}
-#endif
-
-
-static int ser_init(struct cs4297a_state *s)
-{
- int i;
-
- CS_DBGOUT(CS_INIT, 2,
- printk(KERN_INFO "cs4297a: Setting up serial parameters\n"));
-
- __raw_writeq(M_SYNCSER_CMD_RX_RESET | M_SYNCSER_CMD_TX_RESET, SS_CSR(R_SER_CMD));
-
- __raw_writeq(M_SYNCSER_MSB_FIRST, SS_CSR(R_SER_MODE));
- __raw_writeq(32, SS_CSR(R_SER_MINFRM_SZ));
- __raw_writeq(32, SS_CSR(R_SER_MAXFRM_SZ));
-
- __raw_writeq(1, SS_CSR(R_SER_TX_RD_THRSH));
- __raw_writeq(4, SS_CSR(R_SER_TX_WR_THRSH));
- __raw_writeq(8, SS_CSR(R_SER_RX_RD_THRSH));
-
- /* This looks good from experimentation */
- __raw_writeq((M_SYNCSER_TXSYNC_INT | V_SYNCSER_TXSYNC_DLY(0) | M_SYNCSER_TXCLK_EXT |
- M_SYNCSER_RXSYNC_INT | V_SYNCSER_RXSYNC_DLY(1) | M_SYNCSER_RXCLK_EXT | M_SYNCSER_RXSYNC_EDGE),
- SS_CSR(R_SER_LINE_MODE));
-
- /* This looks good from experimentation */
- __raw_writeq(V_SYNCSER_SEQ_COUNT(14) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_STROBE,
- SS_TXTBL(0));
- __raw_writeq(V_SYNCSER_SEQ_COUNT(15) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
- SS_TXTBL(1));
- __raw_writeq(V_SYNCSER_SEQ_COUNT(13) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
- SS_TXTBL(2));
- __raw_writeq(V_SYNCSER_SEQ_COUNT( 0) | M_SYNCSER_SEQ_ENABLE |
- M_SYNCSER_SEQ_STROBE | M_SYNCSER_SEQ_LAST, SS_TXTBL(3));
-
- __raw_writeq(V_SYNCSER_SEQ_COUNT(14) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_STROBE,
- SS_RXTBL(0));
- __raw_writeq(V_SYNCSER_SEQ_COUNT(15) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
- SS_RXTBL(1));
- __raw_writeq(V_SYNCSER_SEQ_COUNT(13) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
- SS_RXTBL(2));
- __raw_writeq(V_SYNCSER_SEQ_COUNT( 0) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_STROBE |
- M_SYNCSER_SEQ_LAST, SS_RXTBL(3));
-
- for (i=4; i<16; i++) {
- /* Just in case... */
- __raw_writeq(M_SYNCSER_SEQ_LAST, SS_TXTBL(i));
- __raw_writeq(M_SYNCSER_SEQ_LAST, SS_RXTBL(i));
- }
-
- return 0;
-}
-
-static int init_serdma(serdma_t *dma)
-{
- CS_DBGOUT(CS_INIT, 2,
- printk(KERN_ERR "cs4297a: desc - %d sbufsize - %d dbufsize - %d\n",
- DMA_DESCR, SAMPLE_BUF_SIZE, DMA_BUF_SIZE));
-
- /* Descriptors */
- dma->ringsz = DMA_DESCR;
- dma->descrtab = kzalloc(dma->ringsz * sizeof(serdma_descr_t), GFP_KERNEL);
- if (!dma->descrtab) {
- printk(KERN_ERR "cs4297a: kzalloc descrtab failed\n");
- return -1;
- }
- dma->descrtab_end = dma->descrtab + dma->ringsz;
- /* XXX bloddy mess, use proper DMA API here ... */
- dma->descrtab_phys = CPHYSADDR((long)dma->descrtab);
- dma->descr_add = dma->descr_rem = dma->descrtab;
-
- /* Frame buffer area */
- dma->dma_buf = kzalloc(DMA_BUF_SIZE, GFP_KERNEL);
- if (!dma->dma_buf) {
- printk(KERN_ERR "cs4297a: kzalloc dma_buf failed\n");
- kfree(dma->descrtab);
- return -1;
- }
- dma->dma_buf_phys = CPHYSADDR((long)dma->dma_buf);
-
- /* Samples buffer area */
- dma->sbufsz = SAMPLE_BUF_SIZE;
- dma->sample_buf = kmalloc(dma->sbufsz, GFP_KERNEL);
- if (!dma->sample_buf) {
- printk(KERN_ERR "cs4297a: kmalloc sample_buf failed\n");
- kfree(dma->descrtab);
- kfree(dma->dma_buf);
- return -1;
- }
- dma->sb_swptr = dma->sb_hwptr = dma->sample_buf;
- dma->sb_end = (u16 *)((void *)dma->sample_buf + dma->sbufsz);
- dma->fragsize = dma->sbufsz >> 1;
-
- CS_DBGOUT(CS_INIT, 4,
- printk(KERN_ERR "cs4297a: descrtab - %08x dma_buf - %x sample_buf - %x\n",
- (int)dma->descrtab, (int)dma->dma_buf,
- (int)dma->sample_buf));
-
- return 0;
-}
-
-static int dma_init(struct cs4297a_state *s)
-{
- int i;
-
- CS_DBGOUT(CS_INIT, 2,
- printk(KERN_INFO "cs4297a: Setting up DMA\n"));
-
- if (init_serdma(&s->dma_adc) ||
- init_serdma(&s->dma_dac))
- return -1;
-
- if (__raw_readq(SS_CSR(R_SER_DMA_DSCR_COUNT_RX))||
- __raw_readq(SS_CSR(R_SER_DMA_DSCR_COUNT_TX))) {
- panic("DMA state corrupted?!");
- }
-
- /* Initialize now - the descr/buffer pairings will never
- change... */
- for (i=0; i<DMA_DESCR; i++) {
- s->dma_dac.descrtab[i].descr_a = M_DMA_SERRX_SOP | V_DMA_DSCRA_A_SIZE(1) |
- (s->dma_dac.dma_buf_phys + i*FRAME_BYTES);
- s->dma_dac.descrtab[i].descr_b = V_DMA_DSCRB_PKT_SIZE(FRAME_BYTES);
- s->dma_adc.descrtab[i].descr_a = V_DMA_DSCRA_A_SIZE(1) |
- (s->dma_adc.dma_buf_phys + i*FRAME_BYTES);
- s->dma_adc.descrtab[i].descr_b = 0;
- }
-
- __raw_writeq((M_DMA_EOP_INT_EN | V_DMA_INT_PKTCNT(DMA_INT_CNT) |
- V_DMA_RINGSZ(DMA_DESCR) | M_DMA_TDX_EN),
- SS_CSR(R_SER_DMA_CONFIG0_RX));
- __raw_writeq(M_DMA_L2CA, SS_CSR(R_SER_DMA_CONFIG1_RX));
- __raw_writeq(s->dma_adc.descrtab_phys, SS_CSR(R_SER_DMA_DSCR_BASE_RX));
-
- __raw_writeq(V_DMA_RINGSZ(DMA_DESCR), SS_CSR(R_SER_DMA_CONFIG0_TX));
- __raw_writeq(M_DMA_L2CA | M_DMA_NO_DSCR_UPDT, SS_CSR(R_SER_DMA_CONFIG1_TX));
- __raw_writeq(s->dma_dac.descrtab_phys, SS_CSR(R_SER_DMA_DSCR_BASE_TX));
-
- /* Prep the receive DMA descriptor ring */
- __raw_writeq(DMA_DESCR, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
-
- __raw_writeq(M_SYNCSER_DMA_RX_EN | M_SYNCSER_DMA_TX_EN, SS_CSR(R_SER_DMA_ENABLE));
-
- __raw_writeq((M_SYNCSER_RX_SYNC_ERR | M_SYNCSER_RX_OVERRUN | M_SYNCSER_RX_EOP_COUNT),
- SS_CSR(R_SER_INT_MASK));
-
- /* Enable the rx/tx; let the codec warm up to the sync and
- start sending good frames before the receive FIFO is
- enabled */
- __raw_writeq(M_SYNCSER_CMD_TX_EN, SS_CSR(R_SER_CMD));
- udelay(1000);
- __raw_writeq(M_SYNCSER_CMD_RX_EN | M_SYNCSER_CMD_TX_EN, SS_CSR(R_SER_CMD));
-
- /* XXXKW is this magic? (the "1" part) */
- while ((__raw_readq(SS_CSR(R_SER_STATUS)) & 0xf1) != 1)
- ;
-
- CS_DBGOUT(CS_INIT, 4,
- printk(KERN_INFO "cs4297a: status: %08x\n",
- (unsigned int)(__raw_readq(SS_CSR(R_SER_STATUS)) & 0xffffffff)));
-
- return 0;
-}
-
-static int serdma_reg_access(struct cs4297a_state *s, u64 data)
-{
- serdma_t *d = &s->dma_dac;
- u64 *data_p;
- unsigned swptr;
- unsigned long flags;
- serdma_descr_t *descr;
-
- if (s->reg_request) {
- printk(KERN_ERR "cs4297a: attempt to issue multiple reg_access\n");
- return -1;
- }
-
- if (s->ena & FMODE_WRITE) {
- /* Since a writer has the DSP open, we have to mux the
- request in */
- s->reg_request = data;
- interruptible_sleep_on(&s->dma_dac.reg_wait);
- /* XXXKW how can I deal with the starvation case where
- the opener isn't writing? */
- } else {
- /* Be safe when changing ring pointers */
- spin_lock_irqsave(&s->lock, flags);
- if (d->hwptr != d->swptr) {
- printk(KERN_ERR "cs4297a: reg access found bookkeeping error (hw/sw = %d/%d\n",
- d->hwptr, d->swptr);
- spin_unlock_irqrestore(&s->lock, flags);
- return -1;
- }
- swptr = d->swptr;
- d->hwptr = d->swptr = (d->swptr + 1) % d->ringsz;
- spin_unlock_irqrestore(&s->lock, flags);
-
- descr = &d->descrtab[swptr];
- data_p = &d->dma_buf[swptr * 4];
- *data_p = cpu_to_be64(data);
- __raw_writeq(1, SS_CSR(R_SER_DMA_DSCR_COUNT_TX));
- CS_DBGOUT(CS_DESCR, 4,
- printk(KERN_INFO "cs4297a: add_tx %p (%x -> %x)\n",
- data_p, swptr, d->hwptr));
- }
-
- CS_DBGOUT(CS_FUNCTION, 6,
- printk(KERN_INFO "cs4297a: serdma_reg_access()-\n"));
-
- return 0;
-}
-
-//****************************************************************************
-// "cs4297a_read_ac97" -- Reads an AC97 register
-//****************************************************************************
-static int cs4297a_read_ac97(struct cs4297a_state *s, u32 offset,
- u32 * value)
-{
- CS_DBGOUT(CS_AC97, 1,
- printk(KERN_INFO "cs4297a: read reg %2x\n", offset));
- if (serdma_reg_access(s, (0xCLL << 60) | (1LL << 47) | ((u64)(offset & 0x7F) << 40)))
- return -1;
-
- interruptible_sleep_on(&s->dma_adc.reg_wait);
- *value = s->read_value;
- CS_DBGOUT(CS_AC97, 2,
- printk(KERN_INFO "cs4297a: rdr reg %x -> %x\n", s->read_reg, s->read_value));
-
- return 0;
-}
-
-
-//****************************************************************************
-// "cs4297a_write_ac97()"-- writes an AC97 register
-//****************************************************************************
-static int cs4297a_write_ac97(struct cs4297a_state *s, u32 offset,
- u32 value)
-{
- CS_DBGOUT(CS_AC97, 1,
- printk(KERN_INFO "cs4297a: write reg %2x -> %04x\n", offset, value));
- return (serdma_reg_access(s, (0xELL << 60) | ((u64)(offset & 0x7F) << 40) | ((value & 0xffff) << 12)));
-}
-
-static void stop_dac(struct cs4297a_state *s)
-{
- unsigned long flags;
-
- CS_DBGOUT(CS_WAVE_WRITE, 3, printk(KERN_INFO "cs4297a: stop_dac():\n"));
- spin_lock_irqsave(&s->lock, flags);
- s->ena &= ~FMODE_WRITE;
-#if 0
- /* XXXKW what do I really want here? My theory for now is
- that I just flip the "ena" bit, and the interrupt handler
- will stop processing the xmit channel */
- __raw_writeq((s->ena & FMODE_READ) ? M_SYNCSER_DMA_RX_EN : 0,
- SS_CSR(R_SER_DMA_ENABLE));
-#endif
-
- spin_unlock_irqrestore(&s->lock, flags);
-}
-
-
-static void start_dac(struct cs4297a_state *s)
-{
- unsigned long flags;
-
- CS_DBGOUT(CS_FUNCTION, 3, printk(KERN_INFO "cs4297a: start_dac()+\n"));
- spin_lock_irqsave(&s->lock, flags);
- if (!(s->ena & FMODE_WRITE) && (s->dma_dac.mapped ||
- (s->dma_dac.count > 0
- && s->dma_dac.ready))) {
- s->ena |= FMODE_WRITE;
- /* XXXKW what do I really want here? My theory for
- now is that I just flip the "ena" bit, and the
- interrupt handler will start processing the xmit
- channel */
-
- CS_DBGOUT(CS_WAVE_WRITE | CS_PARMS, 8, printk(KERN_INFO
- "cs4297a: start_dac(): start dma\n"));
-
- }
- spin_unlock_irqrestore(&s->lock, flags);
- CS_DBGOUT(CS_FUNCTION, 3,
- printk(KERN_INFO "cs4297a: start_dac()-\n"));
-}
-
-
-static void stop_adc(struct cs4297a_state *s)
-{
- unsigned long flags;
-
- CS_DBGOUT(CS_FUNCTION, 3,
- printk(KERN_INFO "cs4297a: stop_adc()+\n"));
-
- spin_lock_irqsave(&s->lock, flags);
- s->ena &= ~FMODE_READ;
-
- if (s->conversion == 1) {
- s->conversion = 0;
- s->prop_adc.fmt = s->prop_adc.fmt_original;
- }
- /* Nothing to do really, I need to keep the DMA going
- XXXKW when do I get here, and is there more I should do? */
- spin_unlock_irqrestore(&s->lock, flags);
- CS_DBGOUT(CS_FUNCTION, 3,
- printk(KERN_INFO "cs4297a: stop_adc()-\n"));
-}
-
-
-static void start_adc(struct cs4297a_state *s)
-{
- unsigned long flags;
-
- CS_DBGOUT(CS_FUNCTION, 2,
- printk(KERN_INFO "cs4297a: start_adc()+\n"));
-
- if (!(s->ena & FMODE_READ) &&
- (s->dma_adc.mapped || s->dma_adc.count <=
- (signed) (s->dma_adc.sbufsz - 2 * s->dma_adc.fragsize))
- && s->dma_adc.ready) {
- if (s->prop_adc.fmt & AFMT_S8 || s->prop_adc.fmt & AFMT_U8) {
- //
- // now only use 16 bit capture, due to truncation issue
- // in the chip, noticeable distortion occurs.
- // allocate buffer and then convert from 16 bit to
- // 8 bit for the user buffer.
- //
- s->prop_adc.fmt_original = s->prop_adc.fmt;
- if (s->prop_adc.fmt & AFMT_S8) {
- s->prop_adc.fmt &= ~AFMT_S8;
- s->prop_adc.fmt |= AFMT_S16_LE;
- }
- if (s->prop_adc.fmt & AFMT_U8) {
- s->prop_adc.fmt &= ~AFMT_U8;
- s->prop_adc.fmt |= AFMT_U16_LE;
- }
- //
- // prog_dmabuf_adc performs a stop_adc() but that is
- // ok since we really haven't started the DMA yet.
- //
- prog_codec(s, CS_TYPE_ADC);
-
- prog_dmabuf_adc(s);
- s->conversion = 1;
- }
- spin_lock_irqsave(&s->lock, flags);
- s->ena |= FMODE_READ;
- /* Nothing to do really, I am probably already
- DMAing... XXXKW when do I get here, and is there
- more I should do? */
- spin_unlock_irqrestore(&s->lock, flags);
-
- CS_DBGOUT(CS_PARMS, 6, printk(KERN_INFO
- "cs4297a: start_adc(): start adc\n"));
- }
- CS_DBGOUT(CS_FUNCTION, 2,
- printk(KERN_INFO "cs4297a: start_adc()-\n"));
-
-}
-
-
-// call with spinlock held!
-static void cs4297a_update_ptr(struct cs4297a_state *s, int intflag)
-{
- int good_diff, diff, diff2;
- u64 *data_p, data;
- u32 *s_ptr;
- unsigned hwptr;
- u32 status;
- serdma_t *d;
- serdma_descr_t *descr;
-
- // update ADC pointer
- status = intflag ? __raw_readq(SS_CSR(R_SER_STATUS)) : 0;
-
- if ((s->ena & FMODE_READ) || (status & (M_SYNCSER_RX_EOP_COUNT))) {
- d = &s->dma_adc;
- hwptr = (unsigned) (((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_RX)) & M_DMA_CURDSCR_ADDR) -
- d->descrtab_phys) / sizeof(serdma_descr_t));
-
- if (s->ena & FMODE_READ) {
- CS_DBGOUT(CS_FUNCTION, 2,
- printk(KERN_INFO "cs4297a: upd_rcv sw->hw->hw %x/%x/%x (int-%d)n",
- d->swptr, d->hwptr, hwptr, intflag));
- /* Number of DMA buffers available for software: */
- diff2 = diff = (d->ringsz + hwptr - d->hwptr) % d->ringsz;
- d->hwptr = hwptr;
- good_diff = 0;
- s_ptr = (u32 *)&(d->dma_buf[d->swptr*4]);
- descr = &d->descrtab[d->swptr];
- while (diff2--) {
- u64 data = be64_to_cpu(*(u64 *)s_ptr);
- u64 descr_a;
- u16 left, right;
- descr_a = descr->descr_a;
- descr->descr_a &= ~M_DMA_SERRX_SOP;
- if ((descr_a & M_DMA_DSCRA_A_ADDR) != CPHYSADDR((long)s_ptr)) {
- printk(KERN_ERR "cs4297a: RX Bad address (read)\n");
- }
- if (((data & 0x9800000000000000) != 0x9800000000000000) ||
- (!(descr_a & M_DMA_SERRX_SOP)) ||
- (G_DMA_DSCRB_PKT_SIZE(descr->descr_b) != FRAME_BYTES)) {
- s->stats.rx_bad++;
- printk(KERN_DEBUG "cs4297a: RX Bad attributes (read)\n");
- continue;
- }
- s->stats.rx_good++;
- if ((data >> 61) == 7) {
- s->read_value = (data >> 12) & 0xffff;
- s->read_reg = (data >> 40) & 0x7f;
- wake_up(&d->reg_wait);
- }
- if (d->count && (d->sb_hwptr == d->sb_swptr)) {
- s->stats.rx_overflow++;
- printk(KERN_DEBUG "cs4297a: RX overflow\n");
- continue;
- }
- good_diff++;
- left = ((be32_to_cpu(s_ptr[1]) & 0xff) << 8) |
- ((be32_to_cpu(s_ptr[2]) >> 24) & 0xff);
- right = (be32_to_cpu(s_ptr[2]) >> 4) & 0xffff;
- *d->sb_hwptr++ = cpu_to_be16(left);
- *d->sb_hwptr++ = cpu_to_be16(right);
- if (d->sb_hwptr == d->sb_end)
- d->sb_hwptr = d->sample_buf;
- descr++;
- if (descr == d->descrtab_end) {
- descr = d->descrtab;
- s_ptr = (u32 *)s->dma_adc.dma_buf;
- } else {
- s_ptr += 8;
- }
- }
- d->total_bytes += good_diff * FRAME_SAMPLE_BYTES;
- d->count += good_diff * FRAME_SAMPLE_BYTES;
- if (d->count > d->sbufsz) {
- printk(KERN_ERR "cs4297a: bogus receive overflow!!\n");
- }
- d->swptr = (d->swptr + diff) % d->ringsz;
- __raw_writeq(diff, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
- if (d->mapped) {
- if (d->count >= (signed) d->fragsize)
- wake_up(&d->wait);
- } else {
- if (d->count > 0) {
- CS_DBGOUT(CS_WAVE_READ, 4,
- printk(KERN_INFO
- "cs4297a: update count -> %d\n", d->count));
- wake_up(&d->wait);
- }
- }
- } else {
- /* Receive is going even if no one is
- listening (for register accesses and to
- avoid FIFO overrun) */
- diff2 = diff = (hwptr + d->ringsz - d->hwptr) % d->ringsz;
- if (!diff) {
- printk(KERN_ERR "cs4297a: RX full or empty?\n");
- }
-
- descr = &d->descrtab[d->swptr];
- data_p = &d->dma_buf[d->swptr*4];
-
- /* Force this to happen at least once; I got
- here because of an interrupt, so there must
- be a buffer to process. */
- do {
- data = be64_to_cpu(*data_p);
- if ((descr->descr_a & M_DMA_DSCRA_A_ADDR) != CPHYSADDR((long)data_p)) {
- printk(KERN_ERR "cs4297a: RX Bad address %d (%llx %lx)\n", d->swptr,
- (long long)(descr->descr_a & M_DMA_DSCRA_A_ADDR),
- (long)CPHYSADDR((long)data_p));
- }
- if (!(data & (1LL << 63)) ||
- !(descr->descr_a & M_DMA_SERRX_SOP) ||
- (G_DMA_DSCRB_PKT_SIZE(descr->descr_b) != FRAME_BYTES)) {
- s->stats.rx_bad++;
- printk(KERN_DEBUG "cs4297a: RX Bad attributes\n");
- } else {
- s->stats.rx_good++;
- if ((data >> 61) == 7) {
- s->read_value = (data >> 12) & 0xffff;
- s->read_reg = (data >> 40) & 0x7f;
- wake_up(&d->reg_wait);
- }
- }
- descr->descr_a &= ~M_DMA_SERRX_SOP;
- descr++;
- d->swptr++;
- data_p += 4;
- if (descr == d->descrtab_end) {
- descr = d->descrtab;
- d->swptr = 0;
- data_p = d->dma_buf;
- }
- __raw_writeq(1, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
- } while (--diff);
- d->hwptr = hwptr;
-
- CS_DBGOUT(CS_DESCR, 6,
- printk(KERN_INFO "cs4297a: hw/sw %x/%x\n", d->hwptr, d->swptr));
- }
-
- CS_DBGOUT(CS_PARMS, 8, printk(KERN_INFO
- "cs4297a: cs4297a_update_ptr(): s=0x%.8x hwptr=%d total_bytes=%d count=%d \n",
- (unsigned)s, d->hwptr,
- d->total_bytes, d->count));
- }
-
- /* XXXKW worry about s->reg_request -- there is a starvation
- case if s->ena has FMODE_WRITE on, but the client isn't
- doing writes */
-
- // update DAC pointer
- //
- // check for end of buffer, means that we are going to wait for another interrupt
- // to allow silence to fill the fifos on the part, to keep pops down to a minimum.
- //
- if (s->ena & FMODE_WRITE) {
- serdma_t *d = &s->dma_dac;
- hwptr = (unsigned) (((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
- d->descrtab_phys) / sizeof(serdma_descr_t));
- diff = (d->ringsz + hwptr - d->hwptr) % d->ringsz;
- CS_DBGOUT(CS_WAVE_WRITE, 4, printk(KERN_INFO
- "cs4297a: cs4297a_update_ptr(): hw/hw/sw %x/%x/%x diff %d count %d\n",
- d->hwptr, hwptr, d->swptr, diff, d->count));
- d->hwptr = hwptr;
- /* XXXKW stereo? conversion? Just assume 2 16-bit samples for now */
- d->total_bytes += diff * FRAME_SAMPLE_BYTES;
- if (d->mapped) {
- d->count += diff * FRAME_SAMPLE_BYTES;
- if (d->count >= d->fragsize) {
- d->wakeup = 1;
- wake_up(&d->wait);
- if (d->count > d->sbufsz)
- d->count &= d->sbufsz - 1;
- }
- } else {
- d->count -= diff * FRAME_SAMPLE_BYTES;
- if (d->count <= 0) {
- //
- // fill with silence, and do not shut down the DAC.
- // Continue to play silence until the _release.
- //
- CS_DBGOUT(CS_WAVE_WRITE, 6, printk(KERN_INFO
- "cs4297a: cs4297a_update_ptr(): memset %d at 0x%.8x for %d size \n",
- (unsigned)(s->prop_dac.fmt &
- (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0,
- (unsigned)d->dma_buf,
- d->ringsz));
- memset(d->dma_buf, 0, d->ringsz * FRAME_BYTES);
- if (d->count < 0) {
- d->underrun = 1;
- s->stats.tx_underrun++;
- d->count = 0;
- CS_DBGOUT(CS_ERROR, 9, printk(KERN_INFO
- "cs4297a: cs4297a_update_ptr(): underrun\n"));
- }
- } else if (d->count <=
- (signed) d->fragsize
- && !d->endcleared) {
- /* XXXKW what is this for? */
- clear_advance(d->dma_buf,
- d->sbufsz,
- d->swptr,
- d->fragsize,
- 0);
- d->endcleared = 1;
- }
- if ( (d->count <= (signed) d->sbufsz/2) || intflag)
- {
- CS_DBGOUT(CS_WAVE_WRITE, 4,
- printk(KERN_INFO
- "cs4297a: update count -> %d\n", d->count));
- wake_up(&d->wait);
- }
- }
- CS_DBGOUT(CS_PARMS, 8, printk(KERN_INFO
- "cs4297a: cs4297a_update_ptr(): s=0x%.8x hwptr=%d total_bytes=%d count=%d \n",
- (unsigned) s, d->hwptr,
- d->total_bytes, d->count));
- }
-}
-
-static int mixer_ioctl(struct cs4297a_state *s, unsigned int cmd,
- unsigned long arg)
-{
- // Index to mixer_src[] is value of AC97 Input Mux Select Reg.
- // Value of array member is recording source Device ID Mask.
- static const unsigned int mixer_src[8] = {
- SOUND_MASK_MIC, SOUND_MASK_CD, 0, SOUND_MASK_LINE1,
- SOUND_MASK_LINE, SOUND_MASK_VOLUME, 0, 0
- };
-
- // Index of mixtable1[] member is Device ID
- // and must be <= SOUND_MIXER_NRDEVICES.
- // Value of array member is index into s->mix.vol[]
- static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = {
- [SOUND_MIXER_PCM] = 1, // voice
- [SOUND_MIXER_LINE1] = 2, // AUX
- [SOUND_MIXER_CD] = 3, // CD
- [SOUND_MIXER_LINE] = 4, // Line
- [SOUND_MIXER_SYNTH] = 5, // FM
- [SOUND_MIXER_MIC] = 6, // Mic
- [SOUND_MIXER_SPEAKER] = 7, // Speaker
- [SOUND_MIXER_RECLEV] = 8, // Recording level
- [SOUND_MIXER_VOLUME] = 9 // Master Volume
- };
-
- static const unsigned mixreg[] = {
- AC97_PCMOUT_VOL,
- AC97_AUX_VOL,
- AC97_CD_VOL,
- AC97_LINEIN_VOL
- };
- unsigned char l, r, rl, rr, vidx;
- unsigned char attentbl[11] =
- { 63, 42, 26, 17, 14, 11, 8, 6, 4, 2, 0 };
- unsigned temp1;
- int i, val;
-
- VALIDATE_STATE(s);
- CS_DBGOUT(CS_FUNCTION, 4, printk(KERN_INFO
- "cs4297a: mixer_ioctl(): s=0x%.8x cmd=0x%.8x\n",
- (unsigned) s, cmd));
-#if CSDEBUG
- cs_printioctl(cmd);
-#endif
-#if CSDEBUG_INTERFACE
-
- if ((cmd == SOUND_MIXER_CS_GETDBGMASK) ||
- (cmd == SOUND_MIXER_CS_SETDBGMASK) ||
- (cmd == SOUND_MIXER_CS_GETDBGLEVEL) ||
- (cmd == SOUND_MIXER_CS_SETDBGLEVEL))
- {
- switch (cmd) {
-
- case SOUND_MIXER_CS_GETDBGMASK:
- return put_user(cs_debugmask,
- (unsigned long *) arg);
-
- case SOUND_MIXER_CS_GETDBGLEVEL:
- return put_user(cs_debuglevel,
- (unsigned long *) arg);
-
- case SOUND_MIXER_CS_SETDBGMASK:
- if (get_user(val, (unsigned long *) arg))
- return -EFAULT;
- cs_debugmask = val;
- return 0;
-
- case SOUND_MIXER_CS_SETDBGLEVEL:
- if (get_user(val, (unsigned long *) arg))
- return -EFAULT;
- cs_debuglevel = val;
- return 0;
- default:
- CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO
- "cs4297a: mixer_ioctl(): ERROR unknown debug cmd\n"));
- return 0;
- }
- }
-#endif
-
- if (cmd == SOUND_MIXER_PRIVATE1) {
- return -EINVAL;
- }
- if (cmd == SOUND_MIXER_PRIVATE2) {
- // enable/disable/query spatializer
- if (get_user(val, (int *) arg))
- return -EFAULT;
- if (val != -1) {
- temp1 = (val & 0x3f) >> 2;
- cs4297a_write_ac97(s, AC97_3D_CONTROL, temp1);
- cs4297a_read_ac97(s, AC97_GENERAL_PURPOSE,
- &temp1);
- cs4297a_write_ac97(s, AC97_GENERAL_PURPOSE,
- temp1 | 0x2000);
- }
- cs4297a_read_ac97(s, AC97_3D_CONTROL, &temp1);
- return put_user((temp1 << 2) | 3, (int *) arg);
- }
- if (cmd == SOUND_MIXER_INFO) {
- mixer_info info;
- memset(&info, 0, sizeof(info));
- strlcpy(info.id, "CS4297a", sizeof(info.id));
- strlcpy(info.name, "Crystal CS4297a", sizeof(info.name));
- info.modify_counter = s->mix.modcnt;
- if (copy_to_user((void *) arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- }
- if (cmd == SOUND_OLD_MIXER_INFO) {
- _old_mixer_info info;
- memset(&info, 0, sizeof(info));
- strlcpy(info.id, "CS4297a", sizeof(info.id));
- strlcpy(info.name, "Crystal CS4297a", sizeof(info.name));
- if (copy_to_user((void *) arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- }
- if (cmd == OSS_GETVERSION)
- return put_user(SOUND_VERSION, (int *) arg);
-
- if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
- return -EINVAL;
-
- // If ioctl has only the SIOC_READ bit(bit 31)
- // on, process the only-read commands.
- if (_SIOC_DIR(cmd) == _SIOC_READ) {
- switch (_IOC_NR(cmd)) {
- case SOUND_MIXER_RECSRC: // Arg contains a bit for each recording source
- cs4297a_read_ac97(s, AC97_RECORD_SELECT,
- &temp1);
- return put_user(mixer_src[temp1 & 7], (int *) arg);
-
- case SOUND_MIXER_DEVMASK: // Arg contains a bit for each supported device
- return put_user(SOUND_MASK_PCM | SOUND_MASK_LINE |
- SOUND_MASK_VOLUME | SOUND_MASK_RECLEV,
- (int *) arg);
-
- case SOUND_MIXER_RECMASK: // Arg contains a bit for each supported recording source
- return put_user(SOUND_MASK_LINE | SOUND_MASK_VOLUME,
- (int *) arg);
-
- case SOUND_MIXER_STEREODEVS: // Mixer channels supporting stereo
- return put_user(SOUND_MASK_PCM | SOUND_MASK_LINE |
- SOUND_MASK_VOLUME | SOUND_MASK_RECLEV,
- (int *) arg);
-
- case SOUND_MIXER_CAPS:
- return put_user(SOUND_CAP_EXCL_INPUT, (int *) arg);
-
- default:
- i = _IOC_NR(cmd);
- if (i >= SOUND_MIXER_NRDEVICES
- || !(vidx = mixtable1[i]))
- return -EINVAL;
- return put_user(s->mix.vol[vidx - 1], (int *) arg);
- }
- }
- // If ioctl doesn't have both the SIOC_READ and
- // the SIOC_WRITE bit set, return invalid.
- if (_SIOC_DIR(cmd) != (_SIOC_READ | _SIOC_WRITE))
- return -EINVAL;
-
- // Increment the count of volume writes.
- s->mix.modcnt++;
-
- // Isolate the command; it must be a write.
- switch (_IOC_NR(cmd)) {
-
- case SOUND_MIXER_RECSRC: // Arg contains a bit for each recording source
- if (get_user(val, (int *) arg))
- return -EFAULT;
- i = hweight32(val); // i = # bits on in val.
- if (i != 1) // One & only 1 bit must be on.
- return 0;
- for (i = 0; i < sizeof(mixer_src) / sizeof(int); i++) {
- if (val == mixer_src[i]) {
- temp1 = (i << 8) | i;
- cs4297a_write_ac97(s,
- AC97_RECORD_SELECT,
- temp1);
- return 0;
- }
- }
- return 0;
-
- case SOUND_MIXER_VOLUME:
- if (get_user(val, (int *) arg))
- return -EFAULT;
- l = val & 0xff;
- if (l > 100)
- l = 100; // Max soundcard.h vol is 100.
- if (l < 6) {
- rl = 63;
- l = 0;
- } else
- rl = attentbl[(10 * l) / 100]; // Convert 0-100 vol to 63-0 atten.
-
- r = (val >> 8) & 0xff;
- if (r > 100)
- r = 100; // Max right volume is 100, too
- if (r < 6) {
- rr = 63;
- r = 0;
- } else
- rr = attentbl[(10 * r) / 100]; // Convert volume to attenuation.
-
- if ((rl > 60) && (rr > 60)) // If both l & r are 'low',
- temp1 = 0x8000; // turn on the mute bit.
- else
- temp1 = 0;
-
- temp1 |= (rl << 8) | rr;
-
- cs4297a_write_ac97(s, AC97_MASTER_VOL_STEREO, temp1);
- cs4297a_write_ac97(s, AC97_PHONE_VOL, temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
- s->mix.vol[8] = ((unsigned int) r << 8) | l;
-#else
- s->mix.vol[8] = val;
-#endif
- return put_user(s->mix.vol[8], (int *) arg);
-
- case SOUND_MIXER_SPEAKER:
- if (get_user(val, (int *) arg))
- return -EFAULT;
- l = val & 0xff;
- if (l > 100)
- l = 100;
- if (l < 3) {
- rl = 0;
- l = 0;
- } else {
- rl = (l * 2 - 5) / 13; // Convert 0-100 range to 0-15.
- l = (rl * 13 + 5) / 2;
- }
-
- if (rl < 3) {
- temp1 = 0x8000;
- rl = 0;
- } else
- temp1 = 0;
- rl = 15 - rl; // Convert volume to attenuation.
- temp1 |= rl << 1;
- cs4297a_write_ac97(s, AC97_PCBEEP_VOL, temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
- s->mix.vol[6] = l << 8;
-#else
- s->mix.vol[6] = val;
-#endif
- return put_user(s->mix.vol[6], (int *) arg);
-
- case SOUND_MIXER_RECLEV:
- if (get_user(val, (int *) arg))
- return -EFAULT;
- l = val & 0xff;
- if (l > 100)
- l = 100;
- r = (val >> 8) & 0xff;
- if (r > 100)
- r = 100;
- rl = (l * 2 - 5) / 13; // Convert 0-100 scale to 0-15.
- rr = (r * 2 - 5) / 13;
- if (rl < 3 && rr < 3)
- temp1 = 0x8000;
- else
- temp1 = 0;
-
- temp1 = temp1 | (rl << 8) | rr;
- cs4297a_write_ac97(s, AC97_RECORD_GAIN, temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
- s->mix.vol[7] = ((unsigned int) r << 8) | l;
-#else
- s->mix.vol[7] = val;
-#endif
- return put_user(s->mix.vol[7], (int *) arg);
-
- case SOUND_MIXER_MIC:
- if (get_user(val, (int *) arg))
- return -EFAULT;
- l = val & 0xff;
- if (l > 100)
- l = 100;
- if (l < 1) {
- l = 0;
- rl = 0;
- } else {
- rl = ((unsigned) l * 5 - 4) / 16; // Convert 0-100 range to 0-31.
- l = (rl * 16 + 4) / 5;
- }
- cs4297a_read_ac97(s, AC97_MIC_VOL, &temp1);
- temp1 &= 0x40; // Isolate 20db gain bit.
- if (rl < 3) {
- temp1 |= 0x8000;
- rl = 0;
- }
- rl = 31 - rl; // Convert volume to attenuation.
- temp1 |= rl;
- cs4297a_write_ac97(s, AC97_MIC_VOL, temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
- s->mix.vol[5] = val << 8;
-#else
- s->mix.vol[5] = val;
-#endif
- return put_user(s->mix.vol[5], (int *) arg);
-
-
- case SOUND_MIXER_SYNTH:
- if (get_user(val, (int *) arg))
- return -EFAULT;
- l = val & 0xff;
- if (l > 100)
- l = 100;
- if (get_user(val, (int *) arg))
- return -EFAULT;
- r = (val >> 8) & 0xff;
- if (r > 100)
- r = 100;
- rl = (l * 2 - 11) / 3; // Convert 0-100 range to 0-63.
- rr = (r * 2 - 11) / 3;
- if (rl < 3) // If l is low, turn on
- temp1 = 0x0080; // the mute bit.
- else
- temp1 = 0;
-
- rl = 63 - rl; // Convert vol to attenuation.
-// writel(temp1 | rl, s->pBA0 + FMLVC);
- if (rr < 3) // If rr is low, turn on
- temp1 = 0x0080; // the mute bit.
- else
- temp1 = 0;
- rr = 63 - rr; // Convert vol to attenuation.
-// writel(temp1 | rr, s->pBA0 + FMRVC);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
- s->mix.vol[4] = (r << 8) | l;
-#else
- s->mix.vol[4] = val;
-#endif
- return put_user(s->mix.vol[4], (int *) arg);
-
-
- default:
- CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
- "cs4297a: mixer_ioctl(): default\n"));
-
- i = _IOC_NR(cmd);
- if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
- return -EINVAL;
- if (get_user(val, (int *) arg))
- return -EFAULT;
- l = val & 0xff;
- if (l > 100)
- l = 100;
- if (l < 1) {
- l = 0;
- rl = 31;
- } else
- rl = (attentbl[(l * 10) / 100]) >> 1;
-
- r = (val >> 8) & 0xff;
- if (r > 100)
- r = 100;
- if (r < 1) {
- r = 0;
- rr = 31;
- } else
- rr = (attentbl[(r * 10) / 100]) >> 1;
- if ((rl > 30) && (rr > 30))
- temp1 = 0x8000;
- else
- temp1 = 0;
- temp1 = temp1 | (rl << 8) | rr;
- cs4297a_write_ac97(s, mixreg[vidx - 1], temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
- s->mix.vol[vidx - 1] = ((unsigned int) r << 8) | l;
-#else
- s->mix.vol[vidx - 1] = val;
-#endif
- return put_user(s->mix.vol[vidx - 1], (int *) arg);
- }
-}
-
-
-// ---------------------------------------------------------------------
-
-static int cs4297a_open_mixdev(struct inode *inode, struct file *file)
-{
- int minor = iminor(inode);
- struct cs4297a_state *s=NULL;
- struct list_head *entry;
-
- CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
- printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()+\n"));
-
- mutex_lock(&swarm_cs4297a_mutex);
- list_for_each(entry, &cs4297a_devs)
- {
- s = list_entry(entry, struct cs4297a_state, list);
- if(s->dev_mixer == minor)
- break;
- }
- if (!s)
- {
- CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2,
- printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- -ENODEV\n"));
-
- mutex_unlock(&swarm_cs4297a_mutex);
- return -ENODEV;
- }
- VALIDATE_STATE(s);
- file->private_data = s;
-
- CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
- printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- 0\n"));
- mutex_unlock(&swarm_cs4297a_mutex);
-
- return nonseekable_open(inode, file);
-}
-
-
-static int cs4297a_release_mixdev(struct inode *inode, struct file *file)
-{
- struct cs4297a_state *s =
- (struct cs4297a_state *) file->private_data;
-
- VALIDATE_STATE(s);
- return 0;
-}
-
-
-static int cs4297a_ioctl_mixdev(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- int ret;
- mutex_lock(&swarm_cs4297a_mutex);
- ret = mixer_ioctl((struct cs4297a_state *) file->private_data, cmd,
- arg);
- mutex_unlock(&swarm_cs4297a_mutex);
- return ret;
-}
-
-
-// ******************************************************************************************
-// Mixer file operations struct.
-// ******************************************************************************************
-static const struct file_operations cs4297a_mixer_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .unlocked_ioctl = cs4297a_ioctl_mixdev,
- .open = cs4297a_open_mixdev,
- .release = cs4297a_release_mixdev,
-};
-
-// ---------------------------------------------------------------------
-
-
-static int drain_adc(struct cs4297a_state *s, int nonblock)
-{
- /* This routine serves no purpose currently - any samples
- sitting in the receive queue will just be processed by the
- background consumer. This would be different if DMA
- actually stopped when there were no clients. */
- return 0;
-}
-
-static int drain_dac(struct cs4297a_state *s, int nonblock)
-{
- DECLARE_WAITQUEUE(wait, current);
- unsigned long flags;
- unsigned hwptr;
- unsigned tmo;
- int count;
-
- if (s->dma_dac.mapped)
- return 0;
- if (nonblock)
- return -EBUSY;
- add_wait_queue(&s->dma_dac.wait, &wait);
- while ((count = __raw_readq(SS_CSR(R_SER_DMA_DSCR_COUNT_TX))) ||
- (s->dma_dac.count > 0)) {
- if (!signal_pending(current)) {
- set_current_state(TASK_INTERRUPTIBLE);
- /* XXXKW is this calculation working? */
- tmo = ((count * FRAME_TX_US) * HZ) / 1000000;
- schedule_timeout(tmo + 1);
- } else {
- /* XXXKW do I care if there is a signal pending? */
- }
- }
- spin_lock_irqsave(&s->lock, flags);
- /* Reset the bookkeeping */
- hwptr = (int)(((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
- s->dma_dac.descrtab_phys) / sizeof(serdma_descr_t));
- s->dma_dac.hwptr = s->dma_dac.swptr = hwptr;
- spin_unlock_irqrestore(&s->lock, flags);
- remove_wait_queue(&s->dma_dac.wait, &wait);
- current->state = TASK_RUNNING;
- return 0;
-}
-
-
-// ---------------------------------------------------------------------
-
-static ssize_t cs4297a_read(struct file *file, char *buffer, size_t count,
- loff_t * ppos)
-{
- struct cs4297a_state *s =
- (struct cs4297a_state *) file->private_data;
- ssize_t ret;
- unsigned long flags;
- int cnt, count_fr, cnt_by;
- unsigned copied = 0;
-
- CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2,
- printk(KERN_INFO "cs4297a: cs4297a_read()+ %d \n", count));
-
- VALIDATE_STATE(s);
- if (s->dma_adc.mapped)
- return -ENXIO;
- if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
- return ret;
- if (!access_ok(VERIFY_WRITE, buffer, count))
- return -EFAULT;
- ret = 0;
-//
-// "count" is the amount of bytes to read (from app), is decremented each loop
-// by the amount of bytes that have been returned to the user buffer.
-// "cnt" is the running total of each read from the buffer (changes each loop)
-// "buffer" points to the app's buffer
-// "ret" keeps a running total of the amount of bytes that have been copied
-// to the user buffer.
-// "copied" is the total bytes copied into the user buffer for each loop.
-//
- while (count > 0) {
- CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO
- "_read() count>0 count=%d .count=%d .swptr=%d .hwptr=%d \n",
- count, s->dma_adc.count,
- s->dma_adc.swptr, s->dma_adc.hwptr));
- spin_lock_irqsave(&s->lock, flags);
-
- /* cnt will be the number of available samples (16-bit
- stereo); it starts out as the maxmimum consequetive
- samples */
- cnt = (s->dma_adc.sb_end - s->dma_adc.sb_swptr) / 2;
- count_fr = s->dma_adc.count / FRAME_SAMPLE_BYTES;
-
- // dma_adc.count is the current total bytes that have not been read.
- // if the amount of unread bytes from the current sw pointer to the
- // end of the buffer is greater than the current total bytes that
- // have not been read, then set the "cnt" (unread bytes) to the
- // amount of unread bytes.
-
- if (count_fr < cnt)
- cnt = count_fr;
- cnt_by = cnt * FRAME_SAMPLE_BYTES;
- spin_unlock_irqrestore(&s->lock, flags);
- //
- // if we are converting from 8/16 then we need to copy
- // twice the number of 16 bit bytes then 8 bit bytes.
- //
- if (s->conversion) {
- if (cnt_by > (count * 2)) {
- cnt = (count * 2) / FRAME_SAMPLE_BYTES;
- cnt_by = count * 2;
- }
- } else {
- if (cnt_by > count) {
- cnt = count / FRAME_SAMPLE_BYTES;
- cnt_by = count;
- }
- }
- //
- // "cnt" NOW is the smaller of the amount that will be read,
- // and the amount that is requested in this read (or partial).
- // if there are no bytes in the buffer to read, then start the
- // ADC and wait for the interrupt handler to wake us up.
- //
- if (cnt <= 0) {
-
- // start up the dma engine and then continue back to the top of
- // the loop when wake up occurs.
- start_adc(s);
- if (file->f_flags & O_NONBLOCK)
- return ret ? ret : -EAGAIN;
- interruptible_sleep_on(&s->dma_adc.wait);
- if (signal_pending(current))
- return ret ? ret : -ERESTARTSYS;
- continue;
- }
- // there are bytes in the buffer to read.
- // copy from the hw buffer over to the user buffer.
- // user buffer is designated by "buffer"
- // virtual address to copy from is dma_buf+swptr
- // the "cnt" is the number of bytes to read.
-
- CS_DBGOUT(CS_WAVE_READ, 2, printk(KERN_INFO
- "_read() copy_to cnt=%d count=%d ", cnt_by, count));
- CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO
- " .sbufsz=%d .count=%d buffer=0x%.8x ret=%d\n",
- s->dma_adc.sbufsz, s->dma_adc.count,
- (unsigned) buffer, ret));
-
- if (copy_to_user (buffer, ((void *)s->dma_adc.sb_swptr), cnt_by))
- return ret ? ret : -EFAULT;
- copied = cnt_by;
-
- /* Return the descriptors */
- spin_lock_irqsave(&s->lock, flags);
- CS_DBGOUT(CS_FUNCTION, 2,
- printk(KERN_INFO "cs4297a: upd_rcv sw->hw %x/%x\n", s->dma_adc.swptr, s->dma_adc.hwptr));
- s->dma_adc.count -= cnt_by;
- s->dma_adc.sb_swptr += cnt * 2;
- if (s->dma_adc.sb_swptr == s->dma_adc.sb_end)
- s->dma_adc.sb_swptr = s->dma_adc.sample_buf;
- spin_unlock_irqrestore(&s->lock, flags);
- count -= copied;
- buffer += copied;
- ret += copied;
- start_adc(s);
- }
- CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2,
- printk(KERN_INFO "cs4297a: cs4297a_read()- %d\n", ret));
- return ret;
-}
-
-
-static ssize_t cs4297a_write(struct file *file, const char *buffer,
- size_t count, loff_t * ppos)
-{
- struct cs4297a_state *s =
- (struct cs4297a_state *) file->private_data;
- ssize_t ret;
- unsigned long flags;
- unsigned swptr, hwptr;
- int cnt;
-
- CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2,
- printk(KERN_INFO "cs4297a: cs4297a_write()+ count=%d\n",
- count));
- VALIDATE_STATE(s);
-
- if (s->dma_dac.mapped)
- return -ENXIO;
- if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
- return ret;
- if (!access_ok(VERIFY_READ, buffer, count))
- return -EFAULT;
- ret = 0;
- while (count > 0) {
- serdma_t *d = &s->dma_dac;
- int copy_cnt;
- u32 *s_tmpl;
- u32 *t_tmpl;
- u32 left, right;
- int swap = (s->prop_dac.fmt == AFMT_S16_LE) || (s->prop_dac.fmt == AFMT_U16_LE);
-
- /* XXXXXX this is broken for BLOAT_FACTOR */
- spin_lock_irqsave(&s->lock, flags);
- if (d->count < 0) {
- d->count = 0;
- d->swptr = d->hwptr;
- }
- if (d->underrun) {
- d->underrun = 0;
- hwptr = (unsigned) (((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
- d->descrtab_phys) / sizeof(serdma_descr_t));
- d->swptr = d->hwptr = hwptr;
- }
- swptr = d->swptr;
- cnt = d->sbufsz - (swptr * FRAME_SAMPLE_BYTES);
- /* Will this write fill up the buffer? */
- if (d->count + cnt > d->sbufsz)
- cnt = d->sbufsz - d->count;
- spin_unlock_irqrestore(&s->lock, flags);
- if (cnt > count)
- cnt = count;
- if (cnt <= 0) {
- start_dac(s);
- if (file->f_flags & O_NONBLOCK)
- return ret ? ret : -EAGAIN;
- interruptible_sleep_on(&d->wait);
- if (signal_pending(current))
- return ret ? ret : -ERESTARTSYS;
- continue;
- }
- if (copy_from_user(d->sample_buf, buffer, cnt))
- return ret ? ret : -EFAULT;
-
- copy_cnt = cnt;
- s_tmpl = (u32 *)d->sample_buf;
- t_tmpl = (u32 *)(d->dma_buf + (swptr * 4));
-
- /* XXXKW assuming 16-bit stereo! */
- do {
- u32 tmp;
-
- t_tmpl[0] = cpu_to_be32(0x98000000);
-
- tmp = be32_to_cpu(s_tmpl[0]);
- left = tmp & 0xffff;
- right = tmp >> 16;
- if (swap) {
- left = swab16(left);
- right = swab16(right);
- }
- t_tmpl[1] = cpu_to_be32(left >> 8);
- t_tmpl[2] = cpu_to_be32(((left & 0xff) << 24) |
- (right << 4));
-
- s_tmpl++;
- t_tmpl += 8;
- copy_cnt -= 4;
- } while (copy_cnt);
-
- /* Mux in any pending read/write accesses */
- if (s->reg_request) {
- *(u64 *)(d->dma_buf + (swptr * 4)) |=
- cpu_to_be64(s->reg_request);
- s->reg_request = 0;
- wake_up(&s->dma_dac.reg_wait);
- }
-
- CS_DBGOUT(CS_WAVE_WRITE, 4,
- printk(KERN_INFO
- "cs4297a: copy in %d to swptr %x\n", cnt, swptr));
-
- swptr = (swptr + (cnt/FRAME_SAMPLE_BYTES)) % d->ringsz;
- __raw_writeq(cnt/FRAME_SAMPLE_BYTES, SS_CSR(R_SER_DMA_DSCR_COUNT_TX));
- spin_lock_irqsave(&s->lock, flags);
- d->swptr = swptr;
- d->count += cnt;
- d->endcleared = 0;
- spin_unlock_irqrestore(&s->lock, flags);
- count -= cnt;
- buffer += cnt;
- ret += cnt;
- start_dac(s);
- }
- CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2,
- printk(KERN_INFO "cs4297a: cs4297a_write()- %d\n", ret));
- return ret;
-}
-
-
-static unsigned int cs4297a_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct cs4297a_state *s =
- (struct cs4297a_state *) file->private_data;
- unsigned long flags;
- unsigned int mask = 0;
-
- CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
- printk(KERN_INFO "cs4297a: cs4297a_poll()+\n"));
- VALIDATE_STATE(s);
- if (file->f_mode & FMODE_WRITE) {
- CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
- printk(KERN_INFO
- "cs4297a: cs4297a_poll() wait on FMODE_WRITE\n"));
- if(!s->dma_dac.ready && prog_dmabuf_dac(s))
- return 0;
- poll_wait(file, &s->dma_dac.wait, wait);
- }
- if (file->f_mode & FMODE_READ) {
- CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
- printk(KERN_INFO
- "cs4297a: cs4297a_poll() wait on FMODE_READ\n"));
- if(!s->dma_dac.ready && prog_dmabuf_adc(s))
- return 0;
- poll_wait(file, &s->dma_adc.wait, wait);
- }
- spin_lock_irqsave(&s->lock, flags);
- cs4297a_update_ptr(s,CS_FALSE);
- if (file->f_mode & FMODE_WRITE) {
- if (s->dma_dac.mapped) {
- if (s->dma_dac.count >=
- (signed) s->dma_dac.fragsize) {
- if (s->dma_dac.wakeup)
- mask |= POLLOUT | POLLWRNORM;
- else
- mask = 0;
- s->dma_dac.wakeup = 0;
- }
- } else {
- if ((signed) (s->dma_dac.sbufsz/2) >= s->dma_dac.count)
- mask |= POLLOUT | POLLWRNORM;
- }
- } else if (file->f_mode & FMODE_READ) {
- if (s->dma_adc.mapped) {
- if (s->dma_adc.count >= (signed) s->dma_adc.fragsize)
- mask |= POLLIN | POLLRDNORM;
- } else {
- if (s->dma_adc.count > 0)
- mask |= POLLIN | POLLRDNORM;
- }
- }
- spin_unlock_irqrestore(&s->lock, flags);
- CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
- printk(KERN_INFO "cs4297a: cs4297a_poll()- 0x%.8x\n",
- mask));
- return mask;
-}
-
-
-static int cs4297a_mmap(struct file *file, struct vm_area_struct *vma)
-{
- /* XXXKW currently no mmap support */
- return -EINVAL;
- return 0;
-}
-
-
-static int cs4297a_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct cs4297a_state *s =
- (struct cs4297a_state *) file->private_data;
- unsigned long flags;
- audio_buf_info abinfo;
- count_info cinfo;
- int val, mapped, ret;
-
- CS_DBGOUT(CS_FUNCTION|CS_IOCTL, 4, printk(KERN_INFO
- "cs4297a: cs4297a_ioctl(): file=0x%.8x cmd=0x%.8x\n",
- (unsigned) file, cmd));
-#if CSDEBUG
- cs_printioctl(cmd);
-#endif
- VALIDATE_STATE(s);
- mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
- ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
- switch (cmd) {
- case OSS_GETVERSION:
- CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
- "cs4297a: cs4297a_ioctl(): SOUND_VERSION=0x%.8x\n",
- SOUND_VERSION));
- return put_user(SOUND_VERSION, (int *) arg);
-
- case SNDCTL_DSP_SYNC:
- CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
- "cs4297a: cs4297a_ioctl(): DSP_SYNC\n"));
- if (file->f_mode & FMODE_WRITE)
- return drain_dac(s,
- 0 /*file->f_flags & O_NONBLOCK */
- );
- return 0;
-
- case SNDCTL_DSP_SETDUPLEX:
- return 0;
-
- case SNDCTL_DSP_GETCAPS:
- return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
- DSP_CAP_TRIGGER | DSP_CAP_MMAP,
- (int *) arg);
-
- case SNDCTL_DSP_RESET:
- CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
- "cs4297a: cs4297a_ioctl(): DSP_RESET\n"));
- if (file->f_mode & FMODE_WRITE) {
- stop_dac(s);
- synchronize_irq(s->irq);
- s->dma_dac.count = s->dma_dac.total_bytes =
- s->dma_dac.blocks = s->dma_dac.wakeup = 0;
- s->dma_dac.swptr = s->dma_dac.hwptr =
- (int)(((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
- s->dma_dac.descrtab_phys) / sizeof(serdma_descr_t));
- }
- if (file->f_mode & FMODE_READ) {
- stop_adc(s);
- synchronize_irq(s->irq);
- s->dma_adc.count = s->dma_adc.total_bytes =
- s->dma_adc.blocks = s->dma_dac.wakeup = 0;
- s->dma_adc.swptr = s->dma_adc.hwptr =
- (int)(((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_RX)) & M_DMA_CURDSCR_ADDR) -
- s->dma_adc.descrtab_phys) / sizeof(serdma_descr_t));
- }
- return 0;
-
- case SNDCTL_DSP_SPEED:
- if (get_user(val, (int *) arg))
- return -EFAULT;
- CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
- "cs4297a: cs4297a_ioctl(): DSP_SPEED val=%d -> 48000\n", val));
- val = 48000;
- return put_user(val, (int *) arg);
-
- case SNDCTL_DSP_STEREO:
- if (get_user(val, (int *) arg))
- return -EFAULT;
- CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
- "cs4297a: cs4297a_ioctl(): DSP_STEREO val=%d\n", val));
- if (file->f_mode & FMODE_READ) {
- stop_adc(s);
- s->dma_adc.ready = 0;
- s->prop_adc.channels = val ? 2 : 1;
- }
- if (file->f_mode & FMODE_WRITE) {
- stop_dac(s);
- s->dma_dac.ready = 0;
- s->prop_dac.channels = val ? 2 : 1;
- }
- return 0;
-
- case SNDCTL_DSP_CHANNELS:
- if (get_user(val, (int *) arg))
- return -EFAULT;
- CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
- "cs4297a: cs4297a_ioctl(): DSP_CHANNELS val=%d\n",
- val));
- if (val != 0) {
- if (file->f_mode & FMODE_READ) {
- stop_adc(s);
- s->dma_adc.ready = 0;
- if (val >= 2)
- s->prop_adc.channels = 2;
- else
- s->prop_adc.channels = 1;
- }
- if (file->f_mode & FMODE_WRITE) {
- stop_dac(s);
- s->dma_dac.ready = 0;
- if (val >= 2)
- s->prop_dac.channels = 2;
- else
- s->prop_dac.channels = 1;
- }
- }
-
- if (file->f_mode & FMODE_WRITE)
- val = s->prop_dac.channels;
- else if (file->f_mode & FMODE_READ)
- val = s->prop_adc.channels;
-
- return put_user(val, (int *) arg);
-
- case SNDCTL_DSP_GETFMTS: // Returns a mask
- CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
- "cs4297a: cs4297a_ioctl(): DSP_GETFMT val=0x%.8x\n",
- AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 |
- AFMT_U8));
- return put_user(AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 |
- AFMT_U8, (int *) arg);
-
- case SNDCTL_DSP_SETFMT:
- if (get_user(val, (int *) arg))
- return -EFAULT;
- CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
- "cs4297a: cs4297a_ioctl(): DSP_SETFMT val=0x%.8x\n",
- val));
- if (val != AFMT_QUERY) {
- if (file->f_mode & FMODE_READ) {
- stop_adc(s);
- s->dma_adc.ready = 0;
- if (val != AFMT_S16_LE
- && val != AFMT_U16_LE && val != AFMT_S8
- && val != AFMT_U8)
- val = AFMT_U8;
- s->prop_adc.fmt = val;
- s->prop_adc.fmt_original = s->prop_adc.fmt;
- }
- if (file->f_mode & FMODE_WRITE) {
- stop_dac(s);
- s->dma_dac.ready = 0;
- if (val != AFMT_S16_LE
- && val != AFMT_U16_LE && val != AFMT_S8
- && val != AFMT_U8)
- val = AFMT_U8;
- s->prop_dac.fmt = val;
- s->prop_dac.fmt_original = s->prop_dac.fmt;
- }
- } else {
- if (file->f_mode & FMODE_WRITE)
- val = s->prop_dac.fmt_original;
- else if (file->f_mode & FMODE_READ)
- val = s->prop_adc.fmt_original;
- }
- CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
- "cs4297a: cs4297a_ioctl(): DSP_SETFMT return val=0x%.8x\n",
- val));
- return put_user(val, (int *) arg);
-
- case SNDCTL_DSP_POST:
- CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
- "cs4297a: cs4297a_ioctl(): DSP_POST\n"));
- return 0;
-
- case SNDCTL_DSP_GETTRIGGER:
- val = 0;
- if (file->f_mode & s->ena & FMODE_READ)
- val |= PCM_ENABLE_INPUT;
- if (file->f_mode & s->ena & FMODE_WRITE)
- val |= PCM_ENABLE_OUTPUT;
- return put_user(val, (int *) arg);
-
- case SNDCTL_DSP_SETTRIGGER:
- if (get_user(val, (int *) arg))
- return -EFAULT;
- if (file->f_mode & FMODE_READ) {
- if (val & PCM_ENABLE_INPUT) {
- if (!s->dma_adc.ready
- && (ret = prog_dmabuf_adc(s)))
- return ret;
- start_adc(s);
- } else
- stop_adc(s);
- }
- if (file->f_mode & FMODE_WRITE) {
- if (val & PCM_ENABLE_OUTPUT) {
- if (!s->dma_dac.ready
- && (ret = prog_dmabuf_dac(s)))
- return ret;
- start_dac(s);
- } else
- stop_dac(s);
- }
- return 0;
-
- case SNDCTL_DSP_GETOSPACE:
- if (!(file->f_mode & FMODE_WRITE))
- return -EINVAL;
- if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)))
- return val;
- spin_lock_irqsave(&s->lock, flags);
- cs4297a_update_ptr(s,CS_FALSE);
- abinfo.fragsize = s->dma_dac.fragsize;
- if (s->dma_dac.mapped)
- abinfo.bytes = s->dma_dac.sbufsz;
- else
- abinfo.bytes =
- s->dma_dac.sbufsz - s->dma_dac.count;
- abinfo.fragstotal = s->dma_dac.numfrag;
- abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
- CS_DBGOUT(CS_FUNCTION | CS_PARMS, 4, printk(KERN_INFO
- "cs4297a: cs4297a_ioctl(): GETOSPACE .fragsize=%d .bytes=%d .fragstotal=%d .fragments=%d\n",
- abinfo.fragsize,abinfo.bytes,abinfo.fragstotal,
- abinfo.fragments));
- spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *) arg, &abinfo,
- sizeof(abinfo)) ? -EFAULT : 0;
-
- case SNDCTL_DSP_GETISPACE:
- if (!(file->f_mode & FMODE_READ))
- return -EINVAL;
- if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)))
- return val;
- spin_lock_irqsave(&s->lock, flags);
- cs4297a_update_ptr(s,CS_FALSE);
- if (s->conversion) {
- abinfo.fragsize = s->dma_adc.fragsize / 2;
- abinfo.bytes = s->dma_adc.count / 2;
- abinfo.fragstotal = s->dma_adc.numfrag;
- abinfo.fragments =
- abinfo.bytes >> (s->dma_adc.fragshift - 1);
- } else {
- abinfo.fragsize = s->dma_adc.fragsize;
- abinfo.bytes = s->dma_adc.count;
- abinfo.fragstotal = s->dma_adc.numfrag;
- abinfo.fragments =
- abinfo.bytes >> s->dma_adc.fragshift;
- }
- spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *) arg, &abinfo,
- sizeof(abinfo)) ? -EFAULT : 0;
-
- case SNDCTL_DSP_NONBLOCK:
- spin_lock(&file->f_lock);
- file->f_flags |= O_NONBLOCK;
- spin_unlock(&file->f_lock);
- return 0;
-
- case SNDCTL_DSP_GETODELAY:
- if (!(file->f_mode & FMODE_WRITE))
- return -EINVAL;
- if(!s->dma_dac.ready && prog_dmabuf_dac(s))
- return 0;
- spin_lock_irqsave(&s->lock, flags);
- cs4297a_update_ptr(s,CS_FALSE);
- val = s->dma_dac.count;
- spin_unlock_irqrestore(&s->lock, flags);
- return put_user(val, (int *) arg);
-
- case SNDCTL_DSP_GETIPTR:
- if (!(file->f_mode & FMODE_READ))
- return -EINVAL;
- if(!s->dma_adc.ready && prog_dmabuf_adc(s))
- return 0;
- spin_lock_irqsave(&s->lock, flags);
- cs4297a_update_ptr(s,CS_FALSE);
- cinfo.bytes = s->dma_adc.total_bytes;
- if (s->dma_adc.mapped) {
- cinfo.blocks =
- (cinfo.bytes >> s->dma_adc.fragshift) -
- s->dma_adc.blocks;
- s->dma_adc.blocks =
- cinfo.bytes >> s->dma_adc.fragshift;
- } else {
- if (s->conversion) {
- cinfo.blocks =
- s->dma_adc.count /
- 2 >> (s->dma_adc.fragshift - 1);
- } else
- cinfo.blocks =
- s->dma_adc.count >> s->dma_adc.
- fragshift;
- }
- if (s->conversion)
- cinfo.ptr = s->dma_adc.hwptr / 2;
- else
- cinfo.ptr = s->dma_adc.hwptr;
- if (s->dma_adc.mapped)
- s->dma_adc.count &= s->dma_adc.fragsize - 1;
- spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *) arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
-
- case SNDCTL_DSP_GETOPTR:
- if (!(file->f_mode & FMODE_WRITE))
- return -EINVAL;
- if(!s->dma_dac.ready && prog_dmabuf_dac(s))
- return 0;
- spin_lock_irqsave(&s->lock, flags);
- cs4297a_update_ptr(s,CS_FALSE);
- cinfo.bytes = s->dma_dac.total_bytes;
- if (s->dma_dac.mapped) {
- cinfo.blocks =
- (cinfo.bytes >> s->dma_dac.fragshift) -
- s->dma_dac.blocks;
- s->dma_dac.blocks =
- cinfo.bytes >> s->dma_dac.fragshift;
- } else {
- cinfo.blocks =
- s->dma_dac.count >> s->dma_dac.fragshift;
- }
- cinfo.ptr = s->dma_dac.hwptr;
- if (s->dma_dac.mapped)
- s->dma_dac.count &= s->dma_dac.fragsize - 1;
- spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *) arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
-
- case SNDCTL_DSP_GETBLKSIZE:
- if (file->f_mode & FMODE_WRITE) {
- if ((val = prog_dmabuf_dac(s)))
- return val;
- return put_user(s->dma_dac.fragsize, (int *) arg);
- }
- if ((val = prog_dmabuf_adc(s)))
- return val;
- if (s->conversion)
- return put_user(s->dma_adc.fragsize / 2,
- (int *) arg);
- else
- return put_user(s->dma_adc.fragsize, (int *) arg);
-
- case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(val, (int *) arg))
- return -EFAULT;
- return 0; // Say OK, but do nothing.
-
- case SNDCTL_DSP_SUBDIVIDE:
- if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision)
- || (file->f_mode & FMODE_WRITE
- && s->dma_dac.subdivision)) return -EINVAL;
- if (get_user(val, (int *) arg))
- return -EFAULT;
- if (val != 1 && val != 2 && val != 4)
- return -EINVAL;
- if (file->f_mode & FMODE_READ)
- s->dma_adc.subdivision = val;
- else if (file->f_mode & FMODE_WRITE)
- s->dma_dac.subdivision = val;
- return 0;
-
- case SOUND_PCM_READ_RATE:
- if (file->f_mode & FMODE_READ)
- return put_user(s->prop_adc.rate, (int *) arg);
- else if (file->f_mode & FMODE_WRITE)
- return put_user(s->prop_dac.rate, (int *) arg);
-
- case SOUND_PCM_READ_CHANNELS:
- if (file->f_mode & FMODE_READ)
- return put_user(s->prop_adc.channels, (int *) arg);
- else if (file->f_mode & FMODE_WRITE)
- return put_user(s->prop_dac.channels, (int *) arg);
-
- case SOUND_PCM_READ_BITS:
- if (file->f_mode & FMODE_READ)
- return
- put_user(
- (s->prop_adc.
- fmt & (AFMT_S8 | AFMT_U8)) ? 8 : 16,
- (int *) arg);
- else if (file->f_mode & FMODE_WRITE)
- return
- put_user(
- (s->prop_dac.
- fmt & (AFMT_S8 | AFMT_U8)) ? 8 : 16,
- (int *) arg);
-
- case SOUND_PCM_WRITE_FILTER:
- case SNDCTL_DSP_SETSYNCRO:
- case SOUND_PCM_READ_FILTER:
- return -EINVAL;
- }
- return mixer_ioctl(s, cmd, arg);
-}
-
-static long cs4297a_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
-{
- int ret;
-
- mutex_lock(&swarm_cs4297a_mutex);
- ret = cs4297a_ioctl(file, cmd, arg);
- mutex_unlock(&swarm_cs4297a_mutex);
-
- return ret;
-}
-
-static int cs4297a_release(struct inode *inode, struct file *file)
-{
- struct cs4297a_state *s =
- (struct cs4297a_state *) file->private_data;
-
- CS_DBGOUT(CS_FUNCTION | CS_RELEASE, 2, printk(KERN_INFO
- "cs4297a: cs4297a_release(): inode=0x%.8x file=0x%.8x f_mode=0x%x\n",
- (unsigned) inode, (unsigned) file, file->f_mode));
- VALIDATE_STATE(s);
-
- if (file->f_mode & FMODE_WRITE) {
- drain_dac(s, file->f_flags & O_NONBLOCK);
- mutex_lock(&s->open_sem_dac);
- stop_dac(s);
- dealloc_dmabuf(s, &s->dma_dac);
- s->open_mode &= ~FMODE_WRITE;
- mutex_unlock(&s->open_sem_dac);
- wake_up(&s->open_wait_dac);
- }
- if (file->f_mode & FMODE_READ) {
- drain_adc(s, file->f_flags & O_NONBLOCK);
- mutex_lock(&s->open_sem_adc);
- stop_adc(s);
- dealloc_dmabuf(s, &s->dma_adc);
- s->open_mode &= ~FMODE_READ;
- mutex_unlock(&s->open_sem_adc);
- wake_up(&s->open_wait_adc);
- }
- return 0;
-}
-
-static int cs4297a_locked_open(struct inode *inode, struct file *file)
-{
- int minor = iminor(inode);
- struct cs4297a_state *s=NULL;
- struct list_head *entry;
-
- CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
- "cs4297a: cs4297a_open(): inode=0x%.8x file=0x%.8x f_mode=0x%x\n",
- (unsigned) inode, (unsigned) file, file->f_mode));
- CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
- "cs4297a: status = %08x\n", (int)__raw_readq(SS_CSR(R_SER_STATUS_DEBUG))));
-
- list_for_each(entry, &cs4297a_devs)
- {
- s = list_entry(entry, struct cs4297a_state, list);
-
- if (!((s->dev_audio ^ minor) & ~0xf))
- break;
- }
- if (entry == &cs4297a_devs)
- return -ENODEV;
- if (!s) {
- CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
- "cs4297a: cs4297a_open(): Error - unable to find audio state struct\n"));
- return -ENODEV;
- }
- VALIDATE_STATE(s);
- file->private_data = s;
-
- // wait for device to become free
- if (!(file->f_mode & (FMODE_WRITE | FMODE_READ))) {
- CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2, printk(KERN_INFO
- "cs4297a: cs4297a_open(): Error - must open READ and/or WRITE\n"));
- return -ENODEV;
- }
- if (file->f_mode & FMODE_WRITE) {
- if (__raw_readq(SS_CSR(R_SER_DMA_DSCR_COUNT_TX)) != 0) {
- printk(KERN_ERR "cs4297a: TX pipe needs to drain\n");
- while (__raw_readq(SS_CSR(R_SER_DMA_DSCR_COUNT_TX)))
- ;
- }
-
- mutex_lock(&s->open_sem_dac);
- while (s->open_mode & FMODE_WRITE) {
- if (file->f_flags & O_NONBLOCK) {
- mutex_unlock(&s->open_sem_dac);
- return -EBUSY;
- }
- mutex_unlock(&s->open_sem_dac);
- interruptible_sleep_on(&s->open_wait_dac);
-
- if (signal_pending(current)) {
- printk("open - sig pending\n");
- return -ERESTARTSYS;
- }
- mutex_lock(&s->open_sem_dac);
- }
- }
- if (file->f_mode & FMODE_READ) {
- mutex_lock(&s->open_sem_adc);
- while (s->open_mode & FMODE_READ) {
- if (file->f_flags & O_NONBLOCK) {
- mutex_unlock(&s->open_sem_adc);
- return -EBUSY;
- }
- mutex_unlock(&s->open_sem_adc);
- interruptible_sleep_on(&s->open_wait_adc);
-
- if (signal_pending(current)) {
- printk("open - sig pending\n");
- return -ERESTARTSYS;
- }
- mutex_lock(&s->open_sem_adc);
- }
- }
- s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
- if (file->f_mode & FMODE_READ) {
- s->prop_adc.fmt = AFMT_S16_BE;
- s->prop_adc.fmt_original = s->prop_adc.fmt;
- s->prop_adc.channels = 2;
- s->prop_adc.rate = 48000;
- s->conversion = 0;
- s->ena &= ~FMODE_READ;
- s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
- s->dma_adc.subdivision = 0;
- mutex_unlock(&s->open_sem_adc);
-
- if (prog_dmabuf_adc(s)) {
- CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR
- "cs4297a: adc Program dmabufs failed.\n"));
- cs4297a_release(inode, file);
- return -ENOMEM;
- }
- }
- if (file->f_mode & FMODE_WRITE) {
- s->prop_dac.fmt = AFMT_S16_BE;
- s->prop_dac.fmt_original = s->prop_dac.fmt;
- s->prop_dac.channels = 2;
- s->prop_dac.rate = 48000;
- s->conversion = 0;
- s->ena &= ~FMODE_WRITE;
- s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
- s->dma_dac.subdivision = 0;
- mutex_unlock(&s->open_sem_dac);
-
- if (prog_dmabuf_dac(s)) {
- CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR
- "cs4297a: dac Program dmabufs failed.\n"));
- cs4297a_release(inode, file);
- return -ENOMEM;
- }
- }
- CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2,
- printk(KERN_INFO "cs4297a: cs4297a_open()- 0\n"));
- return nonseekable_open(inode, file);
-}
-
-static int cs4297a_open(struct inode *inode, struct file *file)
-{
- int ret;
-
- mutex_lock(&swarm_cs4297a_mutex);
- ret = cs4297a_open(inode, file);
- mutex_unlock(&swarm_cs4297a_mutex);
-
- return ret;
-}
-
-// ******************************************************************************************
-// Wave (audio) file operations struct.
-// ******************************************************************************************
-static const struct file_operations cs4297a_audio_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .read = cs4297a_read,
- .write = cs4297a_write,
- .poll = cs4297a_poll,
- .unlocked_ioctl = cs4297a_unlocked_ioctl,
- .mmap = cs4297a_mmap,
- .open = cs4297a_open,
- .release = cs4297a_release,
-};
-
-static void cs4297a_interrupt(int irq, void *dev_id)
-{
- struct cs4297a_state *s = (struct cs4297a_state *) dev_id;
- u32 status;
-
- status = __raw_readq(SS_CSR(R_SER_STATUS_DEBUG));
-
- CS_DBGOUT(CS_INTERRUPT, 6, printk(KERN_INFO
- "cs4297a: cs4297a_interrupt() HISR=0x%.8x\n", status));
-
-#if 0
- /* XXXKW what check *should* be done here? */
- if (!(status & (M_SYNCSER_RX_EOP_COUNT | M_SYNCSER_RX_OVERRUN | M_SYNCSER_RX_SYNC_ERR))) {
- status = __raw_readq(SS_CSR(R_SER_STATUS));
- printk(KERN_ERR "cs4297a: unexpected interrupt (status %08x)\n", status);
- return;
- }
-#endif
-
- if (status & M_SYNCSER_RX_SYNC_ERR) {
- status = __raw_readq(SS_CSR(R_SER_STATUS));
- printk(KERN_ERR "cs4297a: rx sync error (status %08x)\n", status);
- return;
- }
-
- if (status & M_SYNCSER_RX_OVERRUN) {
- int newptr, i;
- s->stats.rx_ovrrn++;
- printk(KERN_ERR "cs4297a: receive FIFO overrun\n");
-
- /* Fix things up: get the receive descriptor pool
- clean and give them back to the hardware */
- while (__raw_readq(SS_CSR(R_SER_DMA_DSCR_COUNT_RX)))
- ;
- newptr = (unsigned) (((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_RX)) & M_DMA_CURDSCR_ADDR) -
- s->dma_adc.descrtab_phys) / sizeof(serdma_descr_t));
- for (i=0; i<DMA_DESCR; i++) {
- s->dma_adc.descrtab[i].descr_a &= ~M_DMA_SERRX_SOP;
- }
- s->dma_adc.swptr = s->dma_adc.hwptr = newptr;
- s->dma_adc.count = 0;
- s->dma_adc.sb_swptr = s->dma_adc.sb_hwptr = s->dma_adc.sample_buf;
- __raw_writeq(DMA_DESCR, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
- }
-
- spin_lock(&s->lock);
- cs4297a_update_ptr(s,CS_TRUE);
- spin_unlock(&s->lock);
-
- CS_DBGOUT(CS_INTERRUPT, 6, printk(KERN_INFO
- "cs4297a: cs4297a_interrupt()-\n"));
-}
-
-#if 0
-static struct initvol {
- int mixch;
- int vol;
-} initvol[] __initdata = {
-
- {SOUND_MIXER_WRITE_VOLUME, 0x4040},
- {SOUND_MIXER_WRITE_PCM, 0x4040},
- {SOUND_MIXER_WRITE_SYNTH, 0x4040},
- {SOUND_MIXER_WRITE_CD, 0x4040},
- {SOUND_MIXER_WRITE_LINE, 0x4040},
- {SOUND_MIXER_WRITE_LINE1, 0x4040},
- {SOUND_MIXER_WRITE_RECLEV, 0x0000},
- {SOUND_MIXER_WRITE_SPEAKER, 0x4040},
- {SOUND_MIXER_WRITE_MIC, 0x0000}
-};
-#endif
-
-static int __init cs4297a_init(void)
-{
- struct cs4297a_state *s;
- u32 pwr, id;
- mm_segment_t fs;
- int rval;
-#ifndef CONFIG_BCM_CS4297A_CSWARM
- u64 cfg;
- int mdio_val;
-#endif
-
- CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO
- "cs4297a: cs4297a_init_module()+ \n"));
-
-#ifndef CONFIG_BCM_CS4297A_CSWARM
- mdio_val = __raw_readq(KSEG1 + A_MAC_REGISTER(2, R_MAC_MDIO)) &
- (M_MAC_MDIO_DIR|M_MAC_MDIO_OUT);
-
- /* Check syscfg for synchronous serial on port 1 */
- cfg = __raw_readq(KSEG1 + A_SCD_SYSTEM_CFG);
- if (!(cfg & M_SYS_SER1_ENABLE)) {
- __raw_writeq(cfg | M_SYS_SER1_ENABLE, KSEG1+A_SCD_SYSTEM_CFG);
- cfg = __raw_readq(KSEG1 + A_SCD_SYSTEM_CFG);
- if (!(cfg & M_SYS_SER1_ENABLE)) {
- printk(KERN_INFO "cs4297a: serial port 1 not configured for synchronous operation\n");
- return -1;
- }
-
- printk(KERN_INFO "cs4297a: serial port 1 switching to synchronous operation\n");
-
- /* Force the codec (on SWARM) to reset by clearing
- GENO, preserving MDIO (no effect on CSWARM) */
- __raw_writeq(mdio_val, KSEG1+A_MAC_REGISTER(2, R_MAC_MDIO));
- udelay(10);
- }
-
- /* Now set GENO */
- __raw_writeq(mdio_val | M_MAC_GENC, KSEG1+A_MAC_REGISTER(2, R_MAC_MDIO));
- /* Give the codec some time to finish resetting (start the bit clock) */
- udelay(100);
-#endif
-
- if (!(s = kzalloc(sizeof(struct cs4297a_state), GFP_KERNEL))) {
- CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
- "cs4297a: probe() no memory for state struct.\n"));
- return -1;
- }
- s->magic = CS4297a_MAGIC;
- init_waitqueue_head(&s->dma_adc.wait);
- init_waitqueue_head(&s->dma_dac.wait);
- init_waitqueue_head(&s->dma_adc.reg_wait);
- init_waitqueue_head(&s->dma_dac.reg_wait);
- init_waitqueue_head(&s->open_wait);
- init_waitqueue_head(&s->open_wait_adc);
- init_waitqueue_head(&s->open_wait_dac);
- mutex_init(&s->open_sem_adc);
- mutex_init(&s->open_sem_dac);
- spin_lock_init(&s->lock);
-
- s->irq = K_INT_SER_1;
-
- if (request_irq
- (s->irq, cs4297a_interrupt, 0, "Crystal CS4297a", s)) {
- CS_DBGOUT(CS_INIT | CS_ERROR, 1,
- printk(KERN_ERR "cs4297a: irq %u in use\n", s->irq));
- goto err_irq;
- }
- if ((s->dev_audio = register_sound_dsp(&cs4297a_audio_fops, -1)) <
- 0) {
- CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
- "cs4297a: probe() register_sound_dsp() failed.\n"));
- goto err_dev1;
- }
- if ((s->dev_mixer = register_sound_mixer(&cs4297a_mixer_fops, -1)) <
- 0) {
- CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
- "cs4297a: probe() register_sound_mixer() failed.\n"));
- goto err_dev2;
- }
-
- if (ser_init(s) || dma_init(s)) {
- CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
- "cs4297a: ser_init failed.\n"));
- goto err_dev3;
- }
-
- do {
- udelay(4000);
- rval = cs4297a_read_ac97(s, AC97_POWER_CONTROL, &pwr);
- } while (!rval && (pwr != 0xf));
-
- if (!rval) {
- char *sb1250_duart_present;
-
- fs = get_fs();
- set_fs(KERNEL_DS);
-#if 0
- val = SOUND_MASK_LINE;
- mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long) &val);
- for (i = 0; i < ARRAY_SIZE(initvol); i++) {
- val = initvol[i].vol;
- mixer_ioctl(s, initvol[i].mixch, (unsigned long) &val);
- }
-// cs4297a_write_ac97(s, 0x18, 0x0808);
-#else
- // cs4297a_write_ac97(s, 0x5e, 0x180);
- cs4297a_write_ac97(s, 0x02, 0x0808);
- cs4297a_write_ac97(s, 0x18, 0x0808);
-#endif
- set_fs(fs);
-
- list_add(&s->list, &cs4297a_devs);
-
- cs4297a_read_ac97(s, AC97_VENDOR_ID1, &id);
-
- sb1250_duart_present = symbol_get(sb1250_duart_present);
- if (sb1250_duart_present)
- sb1250_duart_present[1] = 0;
-
- printk(KERN_INFO "cs4297a: initialized (vendor id = %x)\n", id);
-
- CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
- printk(KERN_INFO "cs4297a: cs4297a_init_module()-\n"));
-
- return 0;
- }
-
- err_dev3:
- unregister_sound_mixer(s->dev_mixer);
- err_dev2:
- unregister_sound_dsp(s->dev_audio);
- err_dev1:
- free_irq(s->irq, s);
- err_irq:
- kfree(s);
-
- printk(KERN_INFO "cs4297a: initialization failed\n");
-
- return -1;
-}
-
-static void __exit cs4297a_cleanup(void)
-{
- /*
- XXXKW
- disable_irq, free_irq
- drain DMA queue
- disable DMA
- disable TX/RX
- free memory
- */
- CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
- printk(KERN_INFO "cs4297a: cleanup_cs4297a() finished\n"));
-}
-
-// ---------------------------------------------------------------------
-
-MODULE_AUTHOR("Kip Walker, Broadcom Corp.");
-MODULE_DESCRIPTION("Cirrus Logic CS4297a Driver for Broadcom SWARM board");
-
-// ---------------------------------------------------------------------
-
-module_init(cs4297a_init);
-module_exit(cs4297a_cleanup);
diff --git a/ANDROID_3.4.5/sound/oss/sys_timer.c b/ANDROID_3.4.5/sound/oss/sys_timer.c
deleted file mode 100644
index 8db6aefe..00000000
--- a/ANDROID_3.4.5/sound/oss/sys_timer.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * sound/oss/sys_timer.c
- *
- * The default timer for the Level 2 sequencer interface
- * Uses the (1/HZ sec) timer of kernel.
- */
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-/*
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
- * Andrew Veliath : adapted tmr2ticks from level 1 sequencer (avoid overflow)
- */
-#include <linux/spinlock.h>
-#include "sound_config.h"
-
-static volatile int opened, tmr_running;
-static volatile time_t tmr_offs, tmr_ctr;
-static volatile unsigned long ticks_offs;
-static volatile int curr_tempo, curr_timebase;
-static volatile unsigned long curr_ticks;
-static volatile unsigned long next_event_time;
-static unsigned long prev_event_time;
-
-static void poll_def_tmr(unsigned long dummy);
-static DEFINE_SPINLOCK(lock);
-static DEFINE_TIMER(def_tmr, poll_def_tmr, 0, 0);
-
-static unsigned long
-tmr2ticks(int tmr_value)
-{
- /*
- * Convert timer ticks to MIDI ticks
- */
-
- unsigned long tmp;
- unsigned long scale;
-
- /* tmr_value (ticks per sec) *
- 1000000 (usecs per sec) / HZ (ticks per sec) -=> usecs */
- tmp = tmr_value * (1000000 / HZ);
- scale = (60 * 1000000) / (curr_tempo * curr_timebase); /* usecs per MIDI tick */
- return (tmp + scale / 2) / scale;
-}
-
-static void
-poll_def_tmr(unsigned long dummy)
-{
-
- if (opened)
- {
-
- {
- def_tmr.expires = (1) + jiffies;
- add_timer(&def_tmr);
- };
-
- if (tmr_running)
- {
- spin_lock(&lock);
- tmr_ctr++;
- curr_ticks = ticks_offs + tmr2ticks(tmr_ctr);
-
- if (curr_ticks >= next_event_time)
- {
- next_event_time = (unsigned long) -1;
- sequencer_timer(0);
- }
- spin_unlock(&lock);
- }
- }
-}
-
-static void
-tmr_reset(void)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&lock,flags);
- tmr_offs = 0;
- ticks_offs = 0;
- tmr_ctr = 0;
- next_event_time = (unsigned long) -1;
- prev_event_time = 0;
- curr_ticks = 0;
- spin_unlock_irqrestore(&lock,flags);
-}
-
-static int
-def_tmr_open(int dev, int mode)
-{
- if (opened)
- return -EBUSY;
-
- tmr_reset();
- curr_tempo = 60;
- curr_timebase = 100;
- opened = 1;
- {
- def_tmr.expires = (1) + jiffies;
- add_timer(&def_tmr);
- };
-
- return 0;
-}
-
-static void
-def_tmr_close(int dev)
-{
- opened = tmr_running = 0;
- del_timer(&def_tmr);
-}
-
-static int
-def_tmr_event(int dev, unsigned char *event)
-{
- unsigned char cmd = event[1];
- unsigned long parm = *(int *) &event[4];
-
- switch (cmd)
- {
- case TMR_WAIT_REL:
- parm += prev_event_time;
- case TMR_WAIT_ABS:
- if (parm > 0)
- {
- long time;
-
- if (parm <= curr_ticks) /* It's the time */
- return TIMER_NOT_ARMED;
-
- time = parm;
- next_event_time = prev_event_time = time;
-
- return TIMER_ARMED;
- }
- break;
-
- case TMR_START:
- tmr_reset();
- tmr_running = 1;
- break;
-
- case TMR_STOP:
- tmr_running = 0;
- break;
-
- case TMR_CONTINUE:
- tmr_running = 1;
- break;
-
- case TMR_TEMPO:
- if (parm)
- {
- if (parm < 8)
- parm = 8;
- if (parm > 360)
- parm = 360;
- tmr_offs = tmr_ctr;
- ticks_offs += tmr2ticks(tmr_ctr);
- tmr_ctr = 0;
- curr_tempo = parm;
- }
- break;
-
- case TMR_ECHO:
- seq_copy_to_input(event, 8);
- break;
-
- default:;
- }
-
- return TIMER_NOT_ARMED;
-}
-
-static unsigned long
-def_tmr_get_time(int dev)
-{
- if (!opened)
- return 0;
-
- return curr_ticks;
-}
-
-/* same as sound_timer.c:timer_ioctl!? */
-static int def_tmr_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
- int __user *p = arg;
- int val;
-
- switch (cmd) {
- case SNDCTL_TMR_SOURCE:
- return __put_user(TMR_INTERNAL, p);
-
- case SNDCTL_TMR_START:
- tmr_reset();
- tmr_running = 1;
- return 0;
-
- case SNDCTL_TMR_STOP:
- tmr_running = 0;
- return 0;
-
- case SNDCTL_TMR_CONTINUE:
- tmr_running = 1;
- return 0;
-
- case SNDCTL_TMR_TIMEBASE:
- if (__get_user(val, p))
- return -EFAULT;
- if (val) {
- if (val < 1)
- val = 1;
- if (val > 1000)
- val = 1000;
- curr_timebase = val;
- }
- return __put_user(curr_timebase, p);
-
- case SNDCTL_TMR_TEMPO:
- if (__get_user(val, p))
- return -EFAULT;
- if (val) {
- if (val < 8)
- val = 8;
- if (val > 250)
- val = 250;
- tmr_offs = tmr_ctr;
- ticks_offs += tmr2ticks(tmr_ctr);
- tmr_ctr = 0;
- curr_tempo = val;
- reprogram_timer();
- }
- return __put_user(curr_tempo, p);
-
- case SNDCTL_SEQ_CTRLRATE:
- if (__get_user(val, p))
- return -EFAULT;
- if (val != 0) /* Can't change */
- return -EINVAL;
- val = ((curr_tempo * curr_timebase) + 30) / 60;
- return __put_user(val, p);
-
- case SNDCTL_SEQ_GETTIME:
- return __put_user(curr_ticks, p);
-
- case SNDCTL_TMR_METRONOME:
- /* NOP */
- break;
-
- default:;
- }
- return -EINVAL;
-}
-
-static void
-def_tmr_arm(int dev, long time)
-{
- if (time < 0)
- time = curr_ticks + 1;
- else if (time <= curr_ticks) /* It's the time */
- return;
-
- next_event_time = prev_event_time = time;
-
- return;
-}
-
-struct sound_timer_operations default_sound_timer =
-{
- .owner = THIS_MODULE,
- .info = {"System clock", 0},
- .priority = 0, /* Priority */
- .devlink = 0, /* Local device link */
- .open = def_tmr_open,
- .close = def_tmr_close,
- .event = def_tmr_event,
- .get_time = def_tmr_get_time,
- .ioctl = def_tmr_ioctl,
- .arm_timer = def_tmr_arm
-};
diff --git a/ANDROID_3.4.5/sound/oss/trix.c b/ANDROID_3.4.5/sound/oss/trix.c
deleted file mode 100644
index 944e0c01..00000000
--- a/ANDROID_3.4.5/sound/oss/trix.c
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * sound/oss/trix.c
- *
- * Low level driver for the MediaTrix AudioTrix Pro
- * (MT-0002-PC Control Chip)
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Changes
- * Alan Cox Modularisation, cleanup.
- * Christoph Hellwig Adapted to module_init/module_exit
- * Arnaldo C. de Melo Got rid of attach_uart401
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include "sound_config.h"
-#include "sb.h"
-#include "sound_firmware.h"
-
-#include "ad1848.h"
-#include "mpu401.h"
-
-#include "trix_boot.h"
-
-static int mpu;
-
-static bool joystick;
-
-static unsigned char trix_read(int addr)
-{
- outb(((unsigned char) addr), 0x390); /* MT-0002-PC ASIC address */
- return inb(0x391); /* MT-0002-PC ASIC data */
-}
-
-static void trix_write(int addr, int data)
-{
- outb(((unsigned char) addr), 0x390); /* MT-0002-PC ASIC address */
- outb(((unsigned char) data), 0x391); /* MT-0002-PC ASIC data */
-}
-
-static void download_boot(int base)
-{
- int i = 0, n = trix_boot_len;
-
- if (trix_boot_len == 0)
- return;
-
- trix_write(0xf8, 0x00); /* ??????? */
- outb((0x01), base + 6); /* Clear the internal data pointer */
- outb((0x00), base + 6); /* Restart */
-
- /*
- * Write the boot code to the RAM upload/download register.
- * Each write increments the internal data pointer.
- */
- outb((0x01), base + 6); /* Clear the internal data pointer */
- outb((0x1A), 0x390); /* Select RAM download/upload port */
-
- for (i = 0; i < n; i++)
- outb((trix_boot[i]), 0x391);
- for (i = n; i < 10016; i++) /* Clear up to first 16 bytes of data RAM */
- outb((0x00), 0x391);
- outb((0x00), base + 6); /* Reset */
- outb((0x50), 0x390); /* ?????? */
-
-}
-
-static int trix_set_wss_port(struct address_info *hw_config)
-{
- unsigned char addr_bits;
-
- if (trix_read(0x15) != 0x71) /* No ASIC signature */
- {
- MDB(printk(KERN_ERR "No AudioTrix ASIC signature found\n"));
- return 0;
- }
-
- /*
- * Reset some registers.
- */
-
- trix_write(0x13, 0);
- trix_write(0x14, 0);
-
- /*
- * Configure the ASIC to place the codec to the proper I/O location
- */
-
- switch (hw_config->io_base)
- {
- case 0x530:
- addr_bits = 0;
- break;
- case 0x604:
- addr_bits = 1;
- break;
- case 0xE80:
- addr_bits = 2;
- break;
- case 0xF40:
- addr_bits = 3;
- break;
- default:
- return 0;
- }
-
- trix_write(0x19, (trix_read(0x19) & 0x03) | addr_bits);
- return 1;
-}
-
-/*
- * Probe and attach routines for the Windows Sound System mode of
- * AudioTrix Pro
- */
-
-static int __init init_trix_wss(struct address_info *hw_config)
-{
- static unsigned char dma_bits[4] = {
- 1, 2, 0, 3
- };
- struct resource *ports;
- int config_port = hw_config->io_base + 0;
- int dma1 = hw_config->dma, dma2 = hw_config->dma2;
- int old_num_mixers = num_mixers;
- u8 config, bits;
- int ret;
-
- switch(hw_config->irq) {
- case 7:
- bits = 8;
- break;
- case 9:
- bits = 0x10;
- break;
- case 10:
- bits = 0x18;
- break;
- case 11:
- bits = 0x20;
- break;
- default:
- printk(KERN_ERR "AudioTrix: Bad WSS IRQ %d\n", hw_config->irq);
- return 0;
- }
-
- switch (dma1) {
- case 0:
- case 1:
- case 3:
- break;
- default:
- printk(KERN_ERR "AudioTrix: Bad WSS DMA %d\n", dma1);
- return 0;
- }
-
- switch (dma2) {
- case -1:
- case 0:
- case 1:
- case 3:
- break;
- default:
- printk(KERN_ERR "AudioTrix: Bad capture DMA %d\n", dma2);
- return 0;
- }
-
- /*
- * Check if the IO port returns valid signature. The original MS Sound
- * system returns 0x04 while some cards (AudioTrix Pro for example)
- * return 0x00.
- */
- ports = request_region(hw_config->io_base + 4, 4, "ad1848");
- if (!ports) {
- printk(KERN_ERR "AudioTrix: MSS I/O port conflict (%x)\n", hw_config->io_base);
- return 0;
- }
-
- if (!request_region(hw_config->io_base, 4, "MSS config")) {
- printk(KERN_ERR "AudioTrix: MSS I/O port conflict (%x)\n", hw_config->io_base);
- release_region(hw_config->io_base + 4, 4);
- return 0;
- }
-
- if (!trix_set_wss_port(hw_config))
- goto fail;
-
- config = inb(hw_config->io_base + 3);
-
- if ((config & 0x3f) != 0x00)
- {
- MDB(printk(KERN_ERR "No MSS signature detected on port 0x%x\n", hw_config->io_base));
- goto fail;
- }
-
- /*
- * Check that DMA0 is not in use with a 8 bit board.
- */
-
- if (dma1 == 0 && config & 0x80)
- {
- printk(KERN_ERR "AudioTrix: Can't use DMA0 with a 8 bit card slot\n");
- goto fail;
- }
- if (hw_config->irq > 9 && config & 0x80)
- {
- printk(KERN_ERR "AudioTrix: Can't use IRQ%d with a 8 bit card slot\n", hw_config->irq);
- goto fail;
- }
-
- ret = ad1848_detect(ports, NULL, hw_config->osp);
- if (!ret)
- goto fail;
-
- if (joystick==1)
- trix_write(0x15, 0x80);
-
- /*
- * Set the IRQ and DMA addresses.
- */
-
- outb((bits | 0x40), config_port);
-
- if (dma2 == -1 || dma2 == dma1)
- {
- bits |= dma_bits[dma1];
- dma2 = dma1;
- }
- else
- {
- unsigned char tmp;
-
- tmp = trix_read(0x13) & ~30;
- trix_write(0x13, tmp | 0x80 | (dma1 << 4));
-
- tmp = trix_read(0x14) & ~30;
- trix_write(0x14, tmp | 0x80 | (dma2 << 4));
- }
-
- outb((bits), config_port); /* Write IRQ+DMA setup */
-
- hw_config->slots[0] = ad1848_init("AudioTrix Pro", ports,
- hw_config->irq,
- dma1,
- dma2,
- 0,
- hw_config->osp,
- THIS_MODULE);
-
- if (num_mixers > old_num_mixers) /* Mixer got installed */
- {
- AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE); /* Line in */
- AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_CD);
- AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_SYNTH); /* OPL4 */
- AD1848_REROUTE(SOUND_MIXER_SPEAKER, SOUND_MIXER_ALTPCM); /* SB */
- }
- return 1;
-
-fail:
- release_region(hw_config->io_base, 4);
- release_region(hw_config->io_base + 4, 4);
- return 0;
-}
-
-static int __init probe_trix_sb(struct address_info *hw_config)
-{
-
- int tmp;
- unsigned char conf;
- extern int sb_be_quiet;
- int old_quiet;
- static signed char irq_translate[] = {
- -1, -1, -1, 0, 1, 2, -1, 3
- };
-
- if (trix_boot_len == 0)
- return 0; /* No boot code -> no fun */
-
- if ((hw_config->io_base & 0xffffff8f) != 0x200)
- return 0;
-
- tmp = hw_config->irq;
- if (tmp > 7)
- return 0;
- if (irq_translate[tmp] == -1)
- return 0;
-
- tmp = hw_config->dma;
- if (tmp != 1 && tmp != 3)
- return 0;
-
- if (!request_region(hw_config->io_base, 16, "soundblaster")) {
- printk(KERN_ERR "AudioTrix: SB I/O port conflict (%x)\n", hw_config->io_base);
- return 0;
- }
-
- conf = 0x84; /* DMA and IRQ enable */
- conf |= hw_config->io_base & 0x70; /* I/O address bits */
- conf |= irq_translate[hw_config->irq];
- if (hw_config->dma == 3)
- conf |= 0x08;
- trix_write(0x1b, conf);
-
- download_boot(hw_config->io_base);
-
- hw_config->name = "AudioTrix SB";
- if (!sb_dsp_detect(hw_config, 0, 0, NULL)) {
- release_region(hw_config->io_base, 16);
- return 0;
- }
-
- hw_config->driver_use_1 = SB_NO_MIDI | SB_NO_MIXER | SB_NO_RECORDING;
-
- /* Prevent false alarms */
- old_quiet = sb_be_quiet;
- sb_be_quiet = 1;
-
- sb_dsp_init(hw_config, THIS_MODULE);
-
- sb_be_quiet = old_quiet;
- return 1;
-}
-
-static int __init probe_trix_mpu(struct address_info *hw_config)
-{
- unsigned char conf;
- static int irq_bits[] = {
- -1, -1, -1, 1, 2, 3, -1, 4, -1, 5
- };
-
- if (hw_config->irq > 9)
- {
- printk(KERN_ERR "AudioTrix: Bad MPU IRQ %d\n", hw_config->irq);
- return 0;
- }
- if (irq_bits[hw_config->irq] == -1)
- {
- printk(KERN_ERR "AudioTrix: Bad MPU IRQ %d\n", hw_config->irq);
- return 0;
- }
- switch (hw_config->io_base)
- {
- case 0x330:
- conf = 0x00;
- break;
- case 0x370:
- conf = 0x04;
- break;
- case 0x3b0:
- conf = 0x08;
- break;
- case 0x3f0:
- conf = 0x0c;
- break;
- default:
- return 0; /* Invalid port */
- }
-
- conf |= irq_bits[hw_config->irq] << 4;
- trix_write(0x19, (trix_read(0x19) & 0x83) | conf);
- hw_config->name = "AudioTrix Pro";
- return probe_uart401(hw_config, THIS_MODULE);
-}
-
-static void __exit unload_trix_wss(struct address_info *hw_config)
-{
- int dma2 = hw_config->dma2;
-
- if (dma2 == -1)
- dma2 = hw_config->dma;
-
- release_region(0x390, 2);
- release_region(hw_config->io_base, 4);
-
- ad1848_unload(hw_config->io_base + 4,
- hw_config->irq,
- hw_config->dma,
- dma2,
- 0);
- sound_unload_audiodev(hw_config->slots[0]);
-}
-
-static inline void __exit unload_trix_mpu(struct address_info *hw_config)
-{
- unload_uart401(hw_config);
-}
-
-static inline void __exit unload_trix_sb(struct address_info *hw_config)
-{
- sb_dsp_unload(hw_config, mpu);
-}
-
-static struct address_info cfg;
-static struct address_info cfg2;
-static struct address_info cfg_mpu;
-
-static int sb;
-static int fw_load;
-
-static int __initdata io = -1;
-static int __initdata irq = -1;
-static int __initdata dma = -1;
-static int __initdata dma2 = -1; /* Set this for modules that need it */
-static int __initdata sb_io = -1;
-static int __initdata sb_dma = -1;
-static int __initdata sb_irq = -1;
-static int __initdata mpu_io = -1;
-static int __initdata mpu_irq = -1;
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-module_param(dma, int, 0);
-module_param(dma2, int, 0);
-module_param(sb_io, int, 0);
-module_param(sb_dma, int, 0);
-module_param(sb_irq, int, 0);
-module_param(mpu_io, int, 0);
-module_param(mpu_irq, int, 0);
-module_param(joystick, bool, 0);
-
-static int __init init_trix(void)
-{
- printk(KERN_INFO "MediaTrix audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
-
- cfg.io_base = io;
- cfg.irq = irq;
- cfg.dma = dma;
- cfg.dma2 = dma2;
-
- cfg2.io_base = sb_io;
- cfg2.irq = sb_irq;
- cfg2.dma = sb_dma;
-
- cfg_mpu.io_base = mpu_io;
- cfg_mpu.irq = mpu_irq;
-
- if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
- printk(KERN_INFO "I/O, IRQ, DMA and type are mandatory\n");
- return -EINVAL;
- }
-
- if (cfg2.io_base != -1 && (cfg2.irq == -1 || cfg2.dma == -1)) {
- printk(KERN_INFO "CONFIG_SB_IRQ and CONFIG_SB_DMA must be specified if SB_IO is set.\n");
- return -EINVAL;
- }
- if (cfg_mpu.io_base != -1 && cfg_mpu.irq == -1) {
- printk(KERN_INFO "CONFIG_MPU_IRQ must be specified if MPU_IO is set.\n");
- return -EINVAL;
- }
- if (!trix_boot)
- {
- fw_load = 1;
- trix_boot_len = mod_firmware_load("/etc/sound/trxpro.bin",
- (char **) &trix_boot);
- }
-
- if (!request_region(0x390, 2, "AudioTrix")) {
- printk(KERN_ERR "AudioTrix: Config port I/O conflict\n");
- return -ENODEV;
- }
-
- if (!init_trix_wss(&cfg)) {
- release_region(0x390, 2);
- return -ENODEV;
- }
-
- /*
- * We must attach in the right order to get the firmware
- * loaded up in time.
- */
-
- if (cfg2.io_base != -1) {
- sb = probe_trix_sb(&cfg2);
- }
-
- if (cfg_mpu.io_base != -1)
- mpu = probe_trix_mpu(&cfg_mpu);
-
- return 0;
-}
-
-static void __exit cleanup_trix(void)
-{
- if (fw_load && trix_boot)
- vfree(trix_boot);
- if (sb)
- unload_trix_sb(&cfg2);
- if (mpu)
- unload_trix_mpu(&cfg_mpu);
- unload_trix_wss(&cfg);
-}
-
-module_init(init_trix);
-module_exit(cleanup_trix);
-
-#ifndef MODULE
-static int __init setup_trix (char *str)
-{
- /* io, irq, dma, dma2, sb_io, sb_irq, sb_dma, mpu_io, mpu_irq */
- int ints[9];
-
- str = get_options(str, ARRAY_SIZE(ints), ints);
-
- io = ints[1];
- irq = ints[2];
- dma = ints[3];
- dma2 = ints[4];
- sb_io = ints[5];
- sb_irq = ints[6];
- sb_dma = ints[6];
- mpu_io = ints[7];
- mpu_irq = ints[8];
-
- return 1;
-}
-
-__setup("trix=", setup_trix);
-#endif
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/oss/tuning.h b/ANDROID_3.4.5/sound/oss/tuning.h
deleted file mode 100644
index a73e3dd3..00000000
--- a/ANDROID_3.4.5/sound/oss/tuning.h
+++ /dev/null
@@ -1,23 +0,0 @@
-static unsigned short semitone_tuning[24] =
-{
-/* 0 */ 10000, 10595, 11225, 11892, 12599, 13348, 14142, 14983,
-/* 8 */ 15874, 16818, 17818, 18877, 20000, 21189, 22449, 23784,
-/* 16 */ 25198, 26697, 28284, 29966, 31748, 33636, 35636, 37755
-};
-
-static unsigned short cent_tuning[100] =
-{
-/* 0 */ 10000, 10006, 10012, 10017, 10023, 10029, 10035, 10041,
-/* 8 */ 10046, 10052, 10058, 10064, 10070, 10075, 10081, 10087,
-/* 16 */ 10093, 10099, 10105, 10110, 10116, 10122, 10128, 10134,
-/* 24 */ 10140, 10145, 10151, 10157, 10163, 10169, 10175, 10181,
-/* 32 */ 10187, 10192, 10198, 10204, 10210, 10216, 10222, 10228,
-/* 40 */ 10234, 10240, 10246, 10251, 10257, 10263, 10269, 10275,
-/* 48 */ 10281, 10287, 10293, 10299, 10305, 10311, 10317, 10323,
-/* 56 */ 10329, 10335, 10341, 10347, 10353, 10359, 10365, 10371,
-/* 64 */ 10377, 10383, 10389, 10395, 10401, 10407, 10413, 10419,
-/* 72 */ 10425, 10431, 10437, 10443, 10449, 10455, 10461, 10467,
-/* 80 */ 10473, 10479, 10485, 10491, 10497, 10503, 10509, 10515,
-/* 88 */ 10521, 10528, 10534, 10540, 10546, 10552, 10558, 10564,
-/* 96 */ 10570, 10576, 10582, 10589
-};
diff --git a/ANDROID_3.4.5/sound/oss/uart401.c b/ANDROID_3.4.5/sound/oss/uart401.c
deleted file mode 100644
index 8e514a67..00000000
--- a/ANDROID_3.4.5/sound/oss/uart401.c
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- * sound/oss/uart401.c
- *
- * MPU-401 UART driver (formerly uart401_midi.c)
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Changes:
- * Alan Cox Reformatted, removed sound_mem usage, use normal Linux
- * interrupt allocation. Protect against bogus unload
- * Fixed to allow IRQ > 15
- * Christoph Hellwig Adapted to module_init/module_exit
- * Arnaldo C. de Melo got rid of check_region
- *
- * Status:
- * Untested
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include "sound_config.h"
-
-#include "mpu401.h"
-
-typedef struct uart401_devc
-{
- int base;
- int irq;
- int *osp;
- void (*midi_input_intr) (int dev, unsigned char data);
- int opened, disabled;
- volatile unsigned char input_byte;
- int my_dev;
- int share_irq;
- spinlock_t lock;
-}
-uart401_devc;
-
-#define DATAPORT (devc->base)
-#define COMDPORT (devc->base+1)
-#define STATPORT (devc->base+1)
-
-static int uart401_status(uart401_devc * devc)
-{
- return inb(STATPORT);
-}
-
-#define input_avail(devc) (!(uart401_status(devc)&INPUT_AVAIL))
-#define output_ready(devc) (!(uart401_status(devc)&OUTPUT_READY))
-
-static void uart401_cmd(uart401_devc * devc, unsigned char cmd)
-{
- outb((cmd), COMDPORT);
-}
-
-static int uart401_read(uart401_devc * devc)
-{
- return inb(DATAPORT);
-}
-
-static void uart401_write(uart401_devc * devc, unsigned char byte)
-{
- outb((byte), DATAPORT);
-}
-
-#define OUTPUT_READY 0x40
-#define INPUT_AVAIL 0x80
-#define MPU_ACK 0xFE
-#define MPU_RESET 0xFF
-#define UART_MODE_ON 0x3F
-
-static int reset_uart401(uart401_devc * devc);
-static void enter_uart_mode(uart401_devc * devc);
-
-static void uart401_input_loop(uart401_devc * devc)
-{
- int work_limit=30000;
-
- while (input_avail(devc) && --work_limit)
- {
- unsigned char c = uart401_read(devc);
-
- if (c == MPU_ACK)
- devc->input_byte = c;
- else if (devc->opened & OPEN_READ && devc->midi_input_intr)
- devc->midi_input_intr(devc->my_dev, c);
- }
- if(work_limit==0)
- printk(KERN_WARNING "Too much work in interrupt on uart401 (0x%X). UART jabbering ??\n", devc->base);
-}
-
-irqreturn_t uart401intr(int irq, void *dev_id)
-{
- uart401_devc *devc = dev_id;
-
- if (devc == NULL)
- {
- printk(KERN_ERR "uart401: bad devc\n");
- return IRQ_NONE;
- }
-
- if (input_avail(devc))
- uart401_input_loop(devc);
- return IRQ_HANDLED;
-}
-
-static int
-uart401_open(int dev, int mode,
- void (*input) (int dev, unsigned char data),
- void (*output) (int dev)
-)
-{
- uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
-
- if (devc->opened)
- return -EBUSY;
-
- /* Flush the UART */
-
- while (input_avail(devc))
- uart401_read(devc);
-
- devc->midi_input_intr = input;
- devc->opened = mode;
- enter_uart_mode(devc);
- devc->disabled = 0;
-
- return 0;
-}
-
-static void uart401_close(int dev)
-{
- uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
-
- reset_uart401(devc);
- devc->opened = 0;
-}
-
-static int uart401_out(int dev, unsigned char midi_byte)
-{
- int timeout;
- unsigned long flags;
- uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
-
- if (devc->disabled)
- return 1;
- /*
- * Test for input since pending input seems to block the output.
- */
-
- spin_lock_irqsave(&devc->lock,flags);
- if (input_avail(devc))
- uart401_input_loop(devc);
-
- spin_unlock_irqrestore(&devc->lock,flags);
-
- /*
- * Sometimes it takes about 13000 loops before the output becomes ready
- * (After reset). Normally it takes just about 10 loops.
- */
-
- for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
-
- if (!output_ready(devc))
- {
- printk(KERN_WARNING "uart401: Timeout - Device not responding\n");
- devc->disabled = 1;
- reset_uart401(devc);
- enter_uart_mode(devc);
- return 1;
- }
- uart401_write(devc, midi_byte);
- return 1;
-}
-
-static inline int uart401_start_read(int dev)
-{
- return 0;
-}
-
-static inline int uart401_end_read(int dev)
-{
- return 0;
-}
-
-static inline void uart401_kick(int dev)
-{
-}
-
-static inline int uart401_buffer_status(int dev)
-{
- return 0;
-}
-
-#define MIDI_SYNTH_NAME "MPU-401 UART"
-#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
-#include "midi_synth.h"
-
-static const struct midi_operations uart401_operations =
-{
- .owner = THIS_MODULE,
- .info = {"MPU-401 (UART) MIDI", 0, 0, SNDCARD_MPU401},
- .converter = &std_midi_synth,
- .in_info = {0},
- .open = uart401_open,
- .close = uart401_close,
- .outputc = uart401_out,
- .start_read = uart401_start_read,
- .end_read = uart401_end_read,
- .kick = uart401_kick,
- .buffer_status = uart401_buffer_status,
-};
-
-static void enter_uart_mode(uart401_devc * devc)
-{
- int ok, timeout;
- unsigned long flags;
-
- spin_lock_irqsave(&devc->lock,flags);
- for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
-
- devc->input_byte = 0;
- uart401_cmd(devc, UART_MODE_ON);
-
- ok = 0;
- for (timeout = 50000; timeout > 0 && !ok; timeout--)
- if (devc->input_byte == MPU_ACK)
- ok = 1;
- else if (input_avail(devc))
- if (uart401_read(devc) == MPU_ACK)
- ok = 1;
-
- spin_unlock_irqrestore(&devc->lock,flags);
-}
-
-static int reset_uart401(uart401_devc * devc)
-{
- int ok, timeout, n;
-
- /*
- * Send the RESET command. Try again if no success at the first time.
- */
-
- ok = 0;
-
- for (n = 0; n < 2 && !ok; n++)
- {
- for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
- devc->input_byte = 0;
- uart401_cmd(devc, MPU_RESET);
-
- /*
- * Wait at least 25 msec. This method is not accurate so let's make the
- * loop bit longer. Cannot sleep since this is called during boot.
- */
-
- for (timeout = 50000; timeout > 0 && !ok; timeout--)
- {
- if (devc->input_byte == MPU_ACK) /* Interrupt */
- ok = 1;
- else if (input_avail(devc))
- {
- if (uart401_read(devc) == MPU_ACK)
- ok = 1;
- }
- }
- }
-
-
- if (ok)
- {
- DEB(printk("Reset UART401 OK\n"));
- }
- else
- DDB(printk("Reset UART401 failed - No hardware detected.\n"));
-
- if (ok)
- uart401_input_loop(devc); /*
- * Flush input before enabling interrupts
- */
-
- return ok;
-}
-
-int probe_uart401(struct address_info *hw_config, struct module *owner)
-{
- uart401_devc *devc;
- char *name = "MPU-401 (UART) MIDI";
- int ok = 0;
- unsigned long flags;
-
- DDB(printk("Entered probe_uart401()\n"));
-
- /* Default to "not found" */
- hw_config->slots[4] = -1;
-
- if (!request_region(hw_config->io_base, 4, "MPU-401 UART")) {
- printk(KERN_INFO "uart401: could not request_region(%d, 4)\n", hw_config->io_base);
- return 0;
- }
-
- devc = kmalloc(sizeof(uart401_devc), GFP_KERNEL);
- if (!devc) {
- printk(KERN_WARNING "uart401: Can't allocate memory\n");
- goto cleanup_region;
- }
-
- devc->base = hw_config->io_base;
- devc->irq = hw_config->irq;
- devc->osp = hw_config->osp;
- devc->midi_input_intr = NULL;
- devc->opened = 0;
- devc->input_byte = 0;
- devc->my_dev = 0;
- devc->share_irq = 0;
- spin_lock_init(&devc->lock);
-
- spin_lock_irqsave(&devc->lock,flags);
- ok = reset_uart401(devc);
- spin_unlock_irqrestore(&devc->lock,flags);
-
- if (!ok)
- goto cleanup_devc;
-
- if (hw_config->name)
- name = hw_config->name;
-
- if (devc->irq < 0) {
- devc->share_irq = 1;
- devc->irq *= -1;
- } else
- devc->share_irq = 0;
-
- if (!devc->share_irq)
- if (request_irq(devc->irq, uart401intr, 0, "MPU-401 UART", devc) < 0) {
- printk(KERN_WARNING "uart401: Failed to allocate IRQ%d\n", devc->irq);
- devc->share_irq = 1;
- }
- devc->my_dev = sound_alloc_mididev();
- enter_uart_mode(devc);
-
- if (devc->my_dev == -1) {
- printk(KERN_INFO "uart401: Too many midi devices detected\n");
- goto cleanup_irq;
- }
- conf_printf(name, hw_config);
- midi_devs[devc->my_dev] = kmalloc(sizeof(struct midi_operations), GFP_KERNEL);
- if (!midi_devs[devc->my_dev]) {
- printk(KERN_ERR "uart401: Failed to allocate memory\n");
- goto cleanup_unload_mididev;
- }
- memcpy(midi_devs[devc->my_dev], &uart401_operations, sizeof(struct midi_operations));
-
- if (owner)
- midi_devs[devc->my_dev]->owner = owner;
-
- midi_devs[devc->my_dev]->devc = devc;
- midi_devs[devc->my_dev]->converter = kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
- if (!midi_devs[devc->my_dev]->converter) {
- printk(KERN_WARNING "uart401: Failed to allocate memory\n");
- goto cleanup_midi_devs;
- }
- memcpy(midi_devs[devc->my_dev]->converter, &std_midi_synth, sizeof(struct synth_operations));
- strcpy(midi_devs[devc->my_dev]->info.name, name);
- midi_devs[devc->my_dev]->converter->id = "UART401";
- midi_devs[devc->my_dev]->converter->midi_dev = devc->my_dev;
-
- if (owner)
- midi_devs[devc->my_dev]->converter->owner = owner;
-
- hw_config->slots[4] = devc->my_dev;
- sequencer_init();
- devc->opened = 0;
- return 1;
-cleanup_midi_devs:
- kfree(midi_devs[devc->my_dev]);
-cleanup_unload_mididev:
- sound_unload_mididev(devc->my_dev);
-cleanup_irq:
- if (!devc->share_irq)
- free_irq(devc->irq, devc);
-cleanup_devc:
- kfree(devc);
-cleanup_region:
- release_region(hw_config->io_base, 4);
- return 0;
-}
-
-void unload_uart401(struct address_info *hw_config)
-{
- uart401_devc *devc;
- int n=hw_config->slots[4];
-
- /* Not set up */
- if(n==-1 || midi_devs[n]==NULL)
- return;
-
- /* Not allocated (erm ??) */
-
- devc = midi_devs[hw_config->slots[4]]->devc;
- if (devc == NULL)
- return;
-
- reset_uart401(devc);
- release_region(hw_config->io_base, 4);
-
- if (!devc->share_irq)
- free_irq(devc->irq, devc);
- if (devc)
- {
- kfree(midi_devs[devc->my_dev]->converter);
- kfree(midi_devs[devc->my_dev]);
- kfree(devc);
- devc = NULL;
- }
- /* This kills midi_devs[x] */
- sound_unload_mididev(hw_config->slots[4]);
-}
-
-EXPORT_SYMBOL(probe_uart401);
-EXPORT_SYMBOL(unload_uart401);
-EXPORT_SYMBOL(uart401intr);
-
-static struct address_info cfg_mpu;
-
-static int io = -1;
-static int irq = -1;
-
-module_param(io, int, 0444);
-module_param(irq, int, 0444);
-
-
-static int __init init_uart401(void)
-{
- cfg_mpu.irq = irq;
- cfg_mpu.io_base = io;
-
- /* Can be loaded either for module use or to provide functions
- to others */
- if (cfg_mpu.io_base != -1 && cfg_mpu.irq != -1) {
- printk(KERN_INFO "MPU-401 UART driver Copyright (C) Hannu Savolainen 1993-1997");
- if (!probe_uart401(&cfg_mpu, THIS_MODULE))
- return -ENODEV;
- }
-
- return 0;
-}
-
-static void __exit cleanup_uart401(void)
-{
- if (cfg_mpu.io_base != -1 && cfg_mpu.irq != -1)
- unload_uart401(&cfg_mpu);
-}
-
-module_init(init_uart401);
-module_exit(cleanup_uart401);
-
-#ifndef MODULE
-static int __init setup_uart401(char *str)
-{
- /* io, irq */
- int ints[3];
-
- str = get_options(str, ARRAY_SIZE(ints), ints);
-
- io = ints[1];
- irq = ints[2];
-
- return 1;
-}
-
-__setup("uart401=", setup_uart401);
-#endif
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/oss/uart6850.c b/ANDROID_3.4.5/sound/oss/uart6850.c
deleted file mode 100644
index f3f914aa..00000000
--- a/ANDROID_3.4.5/sound/oss/uart6850.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * sound/oss/uart6850.c
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- * Extended by Alan Cox for Red Hat Software. Now a loadable MIDI driver.
- * 28/4/97 - (C) Copyright Alan Cox. Released under the GPL version 2.
- *
- * Alan Cox: Updated for new modular code. Removed snd_* irq handling. Now
- * uses native linux resources
- * Christoph Hellwig: Adapted to module_init/module_exit
- * Jeff Garzik: Made it work again, in theory
- * FIXME: If the request_irq() succeeds, the probe succeeds. Ug.
- *
- * Status: Testing required (no shit -jgarzik)
- *
- *
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-/* Mon Nov 22 22:38:35 MET 1993 marco@driq.home.usn.nl:
- * added 6850 support, used with COVOX SoundMaster II and custom cards.
- */
-
-#include "sound_config.h"
-
-static int uart6850_base = 0x330;
-
-static int *uart6850_osp;
-
-#define DATAPORT (uart6850_base)
-#define COMDPORT (uart6850_base+1)
-#define STATPORT (uart6850_base+1)
-
-static int uart6850_status(void)
-{
- return inb(STATPORT);
-}
-
-#define input_avail() (uart6850_status()&INPUT_AVAIL)
-#define output_ready() (uart6850_status()&OUTPUT_READY)
-
-static void uart6850_cmd(unsigned char cmd)
-{
- outb(cmd, COMDPORT);
-}
-
-static int uart6850_read(void)
-{
- return inb(DATAPORT);
-}
-
-static void uart6850_write(unsigned char byte)
-{
- outb(byte, DATAPORT);
-}
-
-#define OUTPUT_READY 0x02 /* Mask for data ready Bit */
-#define INPUT_AVAIL 0x01 /* Mask for Data Send Ready Bit */
-
-#define UART_RESET 0x95
-#define UART_MODE_ON 0x03
-
-static int uart6850_opened;
-static int uart6850_irq;
-static int uart6850_detected;
-static int my_dev;
-static DEFINE_SPINLOCK(lock);
-
-static void (*midi_input_intr) (int dev, unsigned char data);
-static void poll_uart6850(unsigned long dummy);
-
-
-static DEFINE_TIMER(uart6850_timer, poll_uart6850, 0, 0);
-
-static void uart6850_input_loop(void)
-{
- int count = 10;
-
- while (count)
- {
- /*
- * Not timed out
- */
- if (input_avail())
- {
- unsigned char c = uart6850_read();
- count = 100;
- if (uart6850_opened & OPEN_READ)
- midi_input_intr(my_dev, c);
- }
- else
- {
- while (!input_avail() && count)
- count--;
- }
- }
-}
-
-static irqreturn_t m6850intr(int irq, void *dev_id)
-{
- if (input_avail())
- uart6850_input_loop();
- return IRQ_HANDLED;
-}
-
-/*
- * It looks like there is no input interrupts in the UART mode. Let's try
- * polling.
- */
-
-static void poll_uart6850(unsigned long dummy)
-{
- unsigned long flags;
-
- if (!(uart6850_opened & OPEN_READ))
- return; /* Device has been closed */
-
- spin_lock_irqsave(&lock,flags);
- if (input_avail())
- uart6850_input_loop();
-
- uart6850_timer.expires = 1 + jiffies;
- add_timer(&uart6850_timer);
-
- /*
- * Come back later
- */
-
- spin_unlock_irqrestore(&lock,flags);
-}
-
-static int uart6850_open(int dev, int mode,
- void (*input) (int dev, unsigned char data),
- void (*output) (int dev)
-)
-{
- if (uart6850_opened)
- {
-/* printk("Midi6850: Midi busy\n");*/
- return -EBUSY;
- };
-
- uart6850_cmd(UART_RESET);
- uart6850_input_loop();
- midi_input_intr = input;
- uart6850_opened = mode;
- poll_uart6850(0); /*
- * Enable input polling
- */
-
- return 0;
-}
-
-static void uart6850_close(int dev)
-{
- uart6850_cmd(UART_MODE_ON);
- del_timer(&uart6850_timer);
- uart6850_opened = 0;
-}
-
-static int uart6850_out(int dev, unsigned char midi_byte)
-{
- int timeout;
- unsigned long flags;
-
- /*
- * Test for input since pending input seems to block the output.
- */
-
- spin_lock_irqsave(&lock,flags);
-
- if (input_avail())
- uart6850_input_loop();
-
- spin_unlock_irqrestore(&lock,flags);
-
- /*
- * Sometimes it takes about 13000 loops before the output becomes ready
- * (After reset). Normally it takes just about 10 loops.
- */
-
- for (timeout = 30000; timeout > 0 && !output_ready(); timeout--); /*
- * Wait
- */
- if (!output_ready())
- {
- printk(KERN_WARNING "Midi6850: Timeout\n");
- return 0;
- }
- uart6850_write(midi_byte);
- return 1;
-}
-
-static inline int uart6850_command(int dev, unsigned char *midi_byte)
-{
- return 1;
-}
-
-static inline int uart6850_start_read(int dev)
-{
- return 0;
-}
-
-static inline int uart6850_end_read(int dev)
-{
- return 0;
-}
-
-static inline void uart6850_kick(int dev)
-{
-}
-
-static inline int uart6850_buffer_status(int dev)
-{
- return 0; /*
- * No data in buffers
- */
-}
-
-#define MIDI_SYNTH_NAME "6850 UART Midi"
-#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
-#include "midi_synth.h"
-
-static struct midi_operations uart6850_operations =
-{
- .owner = THIS_MODULE,
- .info = {"6850 UART", 0, 0, SNDCARD_UART6850},
- .converter = &std_midi_synth,
- .in_info = {0},
- .open = uart6850_open,
- .close = uart6850_close,
- .outputc = uart6850_out,
- .start_read = uart6850_start_read,
- .end_read = uart6850_end_read,
- .kick = uart6850_kick,
- .command = uart6850_command,
- .buffer_status = uart6850_buffer_status
-};
-
-
-static void __init attach_uart6850(struct address_info *hw_config)
-{
- int ok, timeout;
- unsigned long flags;
-
- if (!uart6850_detected)
- return;
-
- if ((my_dev = sound_alloc_mididev()) == -1)
- {
- printk(KERN_INFO "uart6850: Too many midi devices detected\n");
- return;
- }
- uart6850_base = hw_config->io_base;
- uart6850_osp = hw_config->osp;
- uart6850_irq = hw_config->irq;
-
- spin_lock_irqsave(&lock,flags);
-
- for (timeout = 30000; timeout > 0 && !output_ready(); timeout--); /*
- * Wait
- */
- uart6850_cmd(UART_MODE_ON);
- ok = 1;
- spin_unlock_irqrestore(&lock,flags);
-
- conf_printf("6850 Midi Interface", hw_config);
-
- std_midi_synth.midi_dev = my_dev;
- hw_config->slots[4] = my_dev;
- midi_devs[my_dev] = &uart6850_operations;
- sequencer_init();
-}
-
-static inline int reset_uart6850(void)
-{
- uart6850_read();
- return 1; /*
- * OK
- */
-}
-
-static int __init probe_uart6850(struct address_info *hw_config)
-{
- int ok;
-
- uart6850_osp = hw_config->osp;
- uart6850_base = hw_config->io_base;
- uart6850_irq = hw_config->irq;
-
- if (request_irq(uart6850_irq, m6850intr, 0, "MIDI6850", NULL) < 0)
- return 0;
-
- ok = reset_uart6850();
- uart6850_detected = ok;
- return ok;
-}
-
-static void __exit unload_uart6850(struct address_info *hw_config)
-{
- free_irq(hw_config->irq, NULL);
- sound_unload_mididev(hw_config->slots[4]);
-}
-
-static struct address_info cfg_mpu;
-
-static int __initdata io = -1;
-static int __initdata irq = -1;
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-
-static int __init init_uart6850(void)
-{
- cfg_mpu.io_base = io;
- cfg_mpu.irq = irq;
-
- if (cfg_mpu.io_base == -1 || cfg_mpu.irq == -1) {
- printk(KERN_INFO "uart6850: irq and io must be set.\n");
- return -EINVAL;
- }
-
- if (probe_uart6850(&cfg_mpu))
- return -ENODEV;
- attach_uart6850(&cfg_mpu);
-
- return 0;
-}
-
-static void __exit cleanup_uart6850(void)
-{
- unload_uart6850(&cfg_mpu);
-}
-
-module_init(init_uart6850);
-module_exit(cleanup_uart6850);
-
-#ifndef MODULE
-static int __init setup_uart6850(char *str)
-{
- /* io, irq */
- int ints[3];
-
- str = get_options(str, ARRAY_SIZE(ints), ints);
-
- io = ints[1];
- irq = ints[2];
-
- return 1;
-}
-__setup("uart6850=", setup_uart6850);
-#endif
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/oss/ulaw.h b/ANDROID_3.4.5/sound/oss/ulaw.h
deleted file mode 100644
index 0ff8c0a3..00000000
--- a/ANDROID_3.4.5/sound/oss/ulaw.h
+++ /dev/null
@@ -1,69 +0,0 @@
-static unsigned char ulaw_dsp[] = {
- 3, 7, 11, 15, 19, 23, 27, 31,
- 35, 39, 43, 47, 51, 55, 59, 63,
- 66, 68, 70, 72, 74, 76, 78, 80,
- 82, 84, 86, 88, 90, 92, 94, 96,
- 98, 99, 100, 101, 102, 103, 104, 105,
- 106, 107, 108, 109, 110, 111, 112, 113,
- 113, 114, 114, 115, 115, 116, 116, 117,
- 117, 118, 118, 119, 119, 120, 120, 121,
- 121, 121, 122, 122, 122, 122, 123, 123,
- 123, 123, 124, 124, 124, 124, 125, 125,
- 125, 125, 125, 125, 126, 126, 126, 126,
- 126, 126, 126, 126, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127,
- 128, 128, 128, 128, 128, 128, 128, 128,
- 128, 128, 128, 128, 128, 128, 128, 128,
- 128, 128, 128, 128, 128, 128, 128, 128,
- 253, 249, 245, 241, 237, 233, 229, 225,
- 221, 217, 213, 209, 205, 201, 197, 193,
- 190, 188, 186, 184, 182, 180, 178, 176,
- 174, 172, 170, 168, 166, 164, 162, 160,
- 158, 157, 156, 155, 154, 153, 152, 151,
- 150, 149, 148, 147, 146, 145, 144, 143,
- 143, 142, 142, 141, 141, 140, 140, 139,
- 139, 138, 138, 137, 137, 136, 136, 135,
- 135, 135, 134, 134, 134, 134, 133, 133,
- 133, 133, 132, 132, 132, 132, 131, 131,
- 131, 131, 131, 131, 130, 130, 130, 130,
- 130, 130, 130, 130, 129, 129, 129, 129,
- 129, 129, 129, 129, 129, 129, 129, 129,
- 128, 128, 128, 128, 128, 128, 128, 128,
- 128, 128, 128, 128, 128, 128, 128, 128,
- 128, 128, 128, 128, 128, 128, 128, 128,
-};
-
-static unsigned char dsp_ulaw[] = {
- 0, 0, 0, 0, 0, 1, 1, 1,
- 1, 2, 2, 2, 2, 3, 3, 3,
- 3, 4, 4, 4, 4, 5, 5, 5,
- 5, 6, 6, 6, 6, 7, 7, 7,
- 7, 8, 8, 8, 8, 9, 9, 9,
- 9, 10, 10, 10, 10, 11, 11, 11,
- 11, 12, 12, 12, 12, 13, 13, 13,
- 13, 14, 14, 14, 14, 15, 15, 15,
- 15, 16, 16, 17, 17, 18, 18, 19,
- 19, 20, 20, 21, 21, 22, 22, 23,
- 23, 24, 24, 25, 25, 26, 26, 27,
- 27, 28, 28, 29, 29, 30, 30, 31,
- 31, 32, 33, 34, 35, 36, 37, 38,
- 39, 40, 41, 42, 43, 44, 45, 46,
- 47, 49, 51, 53, 55, 57, 59, 61,
- 63, 66, 70, 74, 78, 84, 92, 104,
- 254, 231, 219, 211, 205, 201, 197, 193,
- 190, 188, 186, 184, 182, 180, 178, 176,
- 175, 174, 173, 172, 171, 170, 169, 168,
- 167, 166, 165, 164, 163, 162, 161, 160,
- 159, 159, 158, 158, 157, 157, 156, 156,
- 155, 155, 154, 154, 153, 153, 152, 152,
- 151, 151, 150, 150, 149, 149, 148, 148,
- 147, 147, 146, 146, 145, 145, 144, 144,
- 143, 143, 143, 143, 142, 142, 142, 142,
- 141, 141, 141, 141, 140, 140, 140, 140,
- 139, 139, 139, 139, 138, 138, 138, 138,
- 137, 137, 137, 137, 136, 136, 136, 136,
- 135, 135, 135, 135, 134, 134, 134, 134,
- 133, 133, 133, 133, 132, 132, 132, 132,
- 131, 131, 131, 131, 130, 130, 130, 130,
- 129, 129, 129, 129, 128, 128, 128, 128,
-};
diff --git a/ANDROID_3.4.5/sound/oss/v_midi.c b/ANDROID_3.4.5/sound/oss/v_midi.c
deleted file mode 100644
index f0b4151d..00000000
--- a/ANDROID_3.4.5/sound/oss/v_midi.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * sound/oss/v_midi.c
- *
- * The low level driver for the Sound Blaster DS chips.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1996
- *
- * USS/Lite for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- * ??
- *
- * Changes
- * Alan Cox Modularisation, changed memory allocations
- * Christoph Hellwig Adapted to module_init/module_exit
- *
- * Status
- * Untested
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include "sound_config.h"
-
-#include "v_midi.h"
-
-static vmidi_devc *v_devc[2] = { NULL, NULL};
-static int midi1,midi2;
-static void *midi_mem = NULL;
-
-/*
- * The DSP channel can be used either for input or output. Variable
- * 'sb_irq_mode' will be set when the program calls read or write first time
- * after open. Current version doesn't support mode changes without closing
- * and reopening the device. Support for this feature may be implemented in a
- * future version of this driver.
- */
-
-
-static int v_midi_open (int dev, int mode,
- void (*input) (int dev, unsigned char data),
- void (*output) (int dev)
-)
-{
- vmidi_devc *devc = midi_devs[dev]->devc;
- unsigned long flags;
-
- if (devc == NULL)
- return -(ENXIO);
-
- spin_lock_irqsave(&devc->lock,flags);
- if (devc->opened)
- {
- spin_unlock_irqrestore(&devc->lock,flags);
- return -(EBUSY);
- }
- devc->opened = 1;
- spin_unlock_irqrestore(&devc->lock,flags);
-
- devc->intr_active = 1;
-
- if (mode & OPEN_READ)
- {
- devc->input_opened = 1;
- devc->midi_input_intr = input;
- }
-
- return 0;
-}
-
-static void v_midi_close (int dev)
-{
- vmidi_devc *devc = midi_devs[dev]->devc;
- unsigned long flags;
-
- if (devc == NULL)
- return;
-
- spin_lock_irqsave(&devc->lock,flags);
- devc->intr_active = 0;
- devc->input_opened = 0;
- devc->opened = 0;
- spin_unlock_irqrestore(&devc->lock,flags);
-}
-
-static int v_midi_out (int dev, unsigned char midi_byte)
-{
- vmidi_devc *devc = midi_devs[dev]->devc;
- vmidi_devc *pdevc;
-
- if (devc == NULL)
- return -ENXIO;
-
- pdevc = midi_devs[devc->pair_mididev]->devc;
- if (pdevc->input_opened > 0){
- if (MIDIbuf_avail(pdevc->my_mididev) > 500)
- return 0;
- pdevc->midi_input_intr (pdevc->my_mididev, midi_byte);
- }
- return 1;
-}
-
-static inline int v_midi_start_read (int dev)
-{
- return 0;
-}
-
-static int v_midi_end_read (int dev)
-{
- vmidi_devc *devc = midi_devs[dev]->devc;
- if (devc == NULL)
- return -ENXIO;
-
- devc->intr_active = 0;
- return 0;
-}
-
-/* why -EPERM and not -EINVAL?? */
-
-static inline int v_midi_ioctl (int dev, unsigned cmd, void __user *arg)
-{
- return -EPERM;
-}
-
-
-#define MIDI_SYNTH_NAME "Loopback MIDI"
-#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
-
-#include "midi_synth.h"
-
-static struct midi_operations v_midi_operations =
-{
- .owner = THIS_MODULE,
- .info = {"Loopback MIDI Port 1", 0, 0, SNDCARD_VMIDI},
- .converter = &std_midi_synth,
- .in_info = {0},
- .open = v_midi_open,
- .close = v_midi_close,
- .ioctl = v_midi_ioctl,
- .outputc = v_midi_out,
- .start_read = v_midi_start_read,
- .end_read = v_midi_end_read,
-};
-
-static struct midi_operations v_midi_operations2 =
-{
- .owner = THIS_MODULE,
- .info = {"Loopback MIDI Port 2", 0, 0, SNDCARD_VMIDI},
- .converter = &std_midi_synth,
- .in_info = {0},
- .open = v_midi_open,
- .close = v_midi_close,
- .ioctl = v_midi_ioctl,
- .outputc = v_midi_out,
- .start_read = v_midi_start_read,
- .end_read = v_midi_end_read,
-};
-
-/*
- * We kmalloc just one of these - it makes life simpler and the code
- * cleaner and the memory handling far more efficient
- */
-
-struct vmidi_memory
-{
- /* Must be first */
- struct midi_operations m_ops[2];
- struct synth_operations s_ops[2];
- struct vmidi_devc v_ops[2];
-};
-
-static void __init attach_v_midi (struct address_info *hw_config)
-{
- struct vmidi_memory *m;
- /* printk("Attaching v_midi device.....\n"); */
-
- midi1 = sound_alloc_mididev();
- if (midi1 == -1)
- {
- printk(KERN_ERR "v_midi: Too many midi devices detected\n");
- return;
- }
-
- m = kmalloc(sizeof(struct vmidi_memory), GFP_KERNEL);
- if (m == NULL)
- {
- printk(KERN_WARNING "Loopback MIDI: Failed to allocate memory\n");
- sound_unload_mididev(midi1);
- return;
- }
-
- midi_mem = m;
-
- midi_devs[midi1] = &m->m_ops[0];
-
-
- midi2 = sound_alloc_mididev();
- if (midi2 == -1)
- {
- printk (KERN_ERR "v_midi: Too many midi devices detected\n");
- kfree(m);
- sound_unload_mididev(midi1);
- return;
- }
-
- midi_devs[midi2] = &m->m_ops[1];
-
- /* printk("VMIDI1: %d VMIDI2: %d\n",midi1,midi2); */
-
- /* for MIDI-1 */
- v_devc[0] = &m->v_ops[0];
- memcpy ((char *) midi_devs[midi1], (char *) &v_midi_operations,
- sizeof (struct midi_operations));
-
- v_devc[0]->my_mididev = midi1;
- v_devc[0]->pair_mididev = midi2;
- v_devc[0]->opened = v_devc[0]->input_opened = 0;
- v_devc[0]->intr_active = 0;
- v_devc[0]->midi_input_intr = NULL;
- spin_lock_init(&v_devc[0]->lock);
-
- midi_devs[midi1]->devc = v_devc[0];
-
- midi_devs[midi1]->converter = &m->s_ops[0];
- std_midi_synth.midi_dev = midi1;
- memcpy ((char *) midi_devs[midi1]->converter, (char *) &std_midi_synth,
- sizeof (struct synth_operations));
- midi_devs[midi1]->converter->id = "V_MIDI 1";
-
- /* for MIDI-2 */
- v_devc[1] = &m->v_ops[1];
-
- memcpy ((char *) midi_devs[midi2], (char *) &v_midi_operations2,
- sizeof (struct midi_operations));
-
- v_devc[1]->my_mididev = midi2;
- v_devc[1]->pair_mididev = midi1;
- v_devc[1]->opened = v_devc[1]->input_opened = 0;
- v_devc[1]->intr_active = 0;
- v_devc[1]->midi_input_intr = NULL;
- spin_lock_init(&v_devc[1]->lock);
-
- midi_devs[midi2]->devc = v_devc[1];
- midi_devs[midi2]->converter = &m->s_ops[1];
-
- std_midi_synth.midi_dev = midi2;
- memcpy ((char *) midi_devs[midi2]->converter, (char *) &std_midi_synth,
- sizeof (struct synth_operations));
- midi_devs[midi2]->converter->id = "V_MIDI 2";
-
- sequencer_init();
- /* printk("Attached v_midi device\n"); */
-}
-
-static inline int __init probe_v_midi(struct address_info *hw_config)
-{
- return(1); /* always OK */
-}
-
-
-static void __exit unload_v_midi(struct address_info *hw_config)
-{
- sound_unload_mididev(midi1);
- sound_unload_mididev(midi2);
- kfree(midi_mem);
-}
-
-static struct address_info cfg; /* dummy */
-
-static int __init init_vmidi(void)
-{
- printk("MIDI Loopback device driver\n");
- if (!probe_v_midi(&cfg))
- return -ENODEV;
- attach_v_midi(&cfg);
-
- return 0;
-}
-
-static void __exit cleanup_vmidi(void)
-{
- unload_v_midi(&cfg);
-}
-
-module_init(init_vmidi);
-module_exit(cleanup_vmidi);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/oss/v_midi.h b/ANDROID_3.4.5/sound/oss/v_midi.h
deleted file mode 100644
index 08e2185e..00000000
--- a/ANDROID_3.4.5/sound/oss/v_midi.h
+++ /dev/null
@@ -1,14 +0,0 @@
-typedef struct vmidi_devc {
- int dev;
-
- /* State variables */
- int opened;
- spinlock_t lock;
-
- /* MIDI fields */
- int my_mididev;
- int pair_mididev;
- int input_opened;
- int intr_active;
- void (*midi_input_intr) (int dev, unsigned char data);
- } vmidi_devc;
diff --git a/ANDROID_3.4.5/sound/oss/vidc.c b/ANDROID_3.4.5/sound/oss/vidc.c
deleted file mode 100644
index 92ca5bee..00000000
--- a/ANDROID_3.4.5/sound/oss/vidc.c
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * linux/drivers/sound/vidc.c
- *
- * Copyright (C) 1997-2000 by Russell King <rmk@arm.linux.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * VIDC20 audio driver.
- *
- * The VIDC20 sound hardware consists of the VIDC20 itself, a DAC and a DMA
- * engine. The DMA transfers fixed-format (16-bit little-endian linear)
- * samples to the VIDC20, which then transfers this data serially to the
- * DACs. The samplerate is controlled by the VIDC.
- *
- * We currently support a mixer device, but it is currently non-functional.
- */
-
-#include <linux/gfp.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-
-#include <mach/hardware.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/hardware/iomd.h>
-#include <asm/irq.h>
-
-#include "sound_config.h"
-#include "vidc.h"
-
-#ifndef _SIOC_TYPE
-#define _SIOC_TYPE(x) _IOC_TYPE(x)
-#endif
-#ifndef _SIOC_NR
-#define _SIOC_NR(x) _IOC_NR(x)
-#endif
-
-#define VIDC_SOUND_CLOCK (250000)
-#define VIDC_SOUND_CLOCK_EXT (176400)
-
-/*
- * When using SERIAL SOUND mode (external DAC), the number of physical
- * channels is fixed at 2.
- */
-static int vidc_busy;
-static int vidc_adev;
-static int vidc_audio_rate;
-static char vidc_audio_format;
-static char vidc_audio_channels;
-
-static unsigned char vidc_level_l[SOUND_MIXER_NRDEVICES] = {
- 85, /* master */
- 50, /* bass */
- 50, /* treble */
- 0, /* synth */
- 75, /* pcm */
- 0, /* speaker */
- 100, /* ext line */
- 0, /* mic */
- 100, /* CD */
- 0,
-};
-
-static unsigned char vidc_level_r[SOUND_MIXER_NRDEVICES] = {
- 85, /* master */
- 50, /* bass */
- 50, /* treble */
- 0, /* synth */
- 75, /* pcm */
- 0, /* speaker */
- 100, /* ext line */
- 0, /* mic */
- 100, /* CD */
- 0,
-};
-
-static unsigned int vidc_audio_volume_l; /* left PCM vol, 0 - 65536 */
-static unsigned int vidc_audio_volume_r; /* right PCM vol, 0 - 65536 */
-
-extern void vidc_update_filler(int bits, int channels);
-extern int softoss_dev;
-
-static void
-vidc_mixer_set(int mdev, unsigned int level)
-{
- unsigned int lev_l = level & 0x007f;
- unsigned int lev_r = (level & 0x7f00) >> 8;
- unsigned int mlev_l, mlev_r;
-
- if (lev_l > 100)
- lev_l = 100;
- if (lev_r > 100)
- lev_r = 100;
-
-#define SCALE(lev,master) ((lev) * (master) * 65536 / 10000)
-
- mlev_l = vidc_level_l[SOUND_MIXER_VOLUME];
- mlev_r = vidc_level_r[SOUND_MIXER_VOLUME];
-
- switch (mdev) {
- case SOUND_MIXER_VOLUME:
- case SOUND_MIXER_PCM:
- vidc_level_l[mdev] = lev_l;
- vidc_level_r[mdev] = lev_r;
-
- vidc_audio_volume_l = SCALE(lev_l, mlev_l);
- vidc_audio_volume_r = SCALE(lev_r, mlev_r);
-/*printk("VIDC: PCM vol %05X %05X\n", vidc_audio_volume_l, vidc_audio_volume_r);*/
- break;
- }
-#undef SCALE
-}
-
-static int vidc_mixer_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
- unsigned int val;
- unsigned int mdev;
-
- if (_SIOC_TYPE(cmd) != 'M')
- return -EINVAL;
-
- mdev = _SIOC_NR(cmd);
-
- if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
- if (get_user(val, (unsigned int __user *)arg))
- return -EFAULT;
-
- if (mdev < SOUND_MIXER_NRDEVICES)
- vidc_mixer_set(mdev, val);
- else
- return -EINVAL;
- }
-
- /*
- * Return parameters
- */
- switch (mdev) {
- case SOUND_MIXER_RECSRC:
- val = 0;
- break;
-
- case SOUND_MIXER_DEVMASK:
- val = SOUND_MASK_VOLUME | SOUND_MASK_PCM | SOUND_MASK_SYNTH;
- break;
-
- case SOUND_MIXER_STEREODEVS:
- val = SOUND_MASK_VOLUME | SOUND_MASK_PCM | SOUND_MASK_SYNTH;
- break;
-
- case SOUND_MIXER_RECMASK:
- val = 0;
- break;
-
- case SOUND_MIXER_CAPS:
- val = 0;
- break;
-
- default:
- if (mdev < SOUND_MIXER_NRDEVICES)
- val = vidc_level_l[mdev] | vidc_level_r[mdev] << 8;
- else
- return -EINVAL;
- }
-
- return put_user(val, (unsigned int __user *)arg) ? -EFAULT : 0;
-}
-
-static unsigned int vidc_audio_set_format(int dev, unsigned int fmt)
-{
- switch (fmt) {
- default:
- fmt = AFMT_S16_LE;
- case AFMT_U8:
- case AFMT_S8:
- case AFMT_S16_LE:
- vidc_audio_format = fmt;
- vidc_update_filler(vidc_audio_format, vidc_audio_channels);
- case AFMT_QUERY:
- break;
- }
- return vidc_audio_format;
-}
-
-#define my_abs(i) ((i)<0 ? -(i) : (i))
-
-static int vidc_audio_set_speed(int dev, int rate)
-{
- if (rate) {
- unsigned int hwctrl, hwrate, hwrate_ext, rate_int, rate_ext;
- unsigned int diff_int, diff_ext;
- unsigned int newsize, new2size;
-
- hwctrl = 0x00000003;
-
- /* Using internal clock */
- hwrate = (((VIDC_SOUND_CLOCK * 2) / rate) + 1) >> 1;
- if (hwrate < 3)
- hwrate = 3;
- if (hwrate > 255)
- hwrate = 255;
-
- /* Using exernal clock */
- hwrate_ext = (((VIDC_SOUND_CLOCK_EXT * 2) / rate) + 1) >> 1;
- if (hwrate_ext < 3)
- hwrate_ext = 3;
- if (hwrate_ext > 255)
- hwrate_ext = 255;
-
- rate_int = VIDC_SOUND_CLOCK / hwrate;
- rate_ext = VIDC_SOUND_CLOCK_EXT / hwrate_ext;
-
- /* Chose between external and internal clock */
- diff_int = my_abs(rate_ext-rate);
- diff_ext = my_abs(rate_int-rate);
- if (diff_ext < diff_int) {
- /*printk("VIDC: external %d %d %d\n", rate, rate_ext, hwrate_ext);*/
- hwrate=hwrate_ext;
- hwctrl=0x00000002;
- /* Allow roughly 0.4% tolerance */
- if (diff_ext > (rate/256))
- rate=rate_ext;
- } else {
- /*printk("VIDC: internal %d %d %d\n", rate, rate_int, hwrate);*/
- hwctrl=0x00000003;
- /* Allow roughly 0.4% tolerance */
- if (diff_int > (rate/256))
- rate=rate_int;
- }
-
- vidc_writel(0xb0000000 | (hwrate - 2));
- vidc_writel(0xb1000000 | hwctrl);
-
- newsize = (10000 / hwrate) & ~3;
- if (newsize < 208)
- newsize = 208;
- if (newsize > 4096)
- newsize = 4096;
- for (new2size = 128; new2size < newsize; new2size <<= 1);
- if (new2size - newsize > newsize - (new2size >> 1))
- new2size >>= 1;
- if (new2size > 4096) {
- printk(KERN_ERR "VIDC: error: dma buffer (%d) %d > 4K\n",
- newsize, new2size);
- new2size = 4096;
- }
- /*printk("VIDC: dma size %d\n", new2size);*/
- dma_bufsize = new2size;
- vidc_audio_rate = rate;
- }
- return vidc_audio_rate;
-}
-
-static short vidc_audio_set_channels(int dev, short channels)
-{
- switch (channels) {
- default:
- channels = 2;
- case 1:
- case 2:
- vidc_audio_channels = channels;
- vidc_update_filler(vidc_audio_format, vidc_audio_channels);
- case 0:
- break;
- }
- return vidc_audio_channels;
-}
-
-/*
- * Open the device
- */
-static int vidc_audio_open(int dev, int mode)
-{
- /* This audio device does not have recording capability */
- if (mode == OPEN_READ)
- return -EPERM;
-
- if (vidc_busy)
- return -EBUSY;
-
- vidc_busy = 1;
- return 0;
-}
-
-/*
- * Close the device
- */
-static void vidc_audio_close(int dev)
-{
- vidc_busy = 0;
-}
-
-/*
- * Output a block via DMA to sound device.
- *
- * We just set the DMA start and count; the DMA interrupt routine
- * will take care of formatting the samples (via the appropriate
- * vidc_filler routine), and flag via vidc_audio_dma_interrupt when
- * more data is required.
- */
-static void
-vidc_audio_output_block(int dev, unsigned long buf, int total_count, int one)
-{
- struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
- unsigned long flags;
-
- local_irq_save(flags);
- dma_start = buf - (unsigned long)dmap->raw_buf_phys + (unsigned long)dmap->raw_buf;
- dma_count = total_count;
- local_irq_restore(flags);
-}
-
-static void
-vidc_audio_start_input(int dev, unsigned long buf, int count, int intrflag)
-{
-}
-
-static int vidc_audio_prepare_for_input(int dev, int bsize, int bcount)
-{
- return -EINVAL;
-}
-
-static irqreturn_t vidc_audio_dma_interrupt(void)
-{
- DMAbuf_outputintr(vidc_adev, 1);
- return IRQ_HANDLED;
-}
-
-/*
- * Prepare for outputting samples.
- *
- * Each buffer that will be passed will be `bsize' bytes long,
- * with a total of `bcount' buffers.
- */
-static int vidc_audio_prepare_for_output(int dev, int bsize, int bcount)
-{
- struct audio_operations *adev = audio_devs[dev];
-
- dma_interrupt = NULL;
- adev->dmap_out->flags |= DMA_NODMA;
-
- return 0;
-}
-
-/*
- * Stop our current operation.
- */
-static void vidc_audio_reset(int dev)
-{
- dma_interrupt = NULL;
-}
-
-static int vidc_audio_local_qlen(int dev)
-{
- return /*dma_count !=*/ 0;
-}
-
-static void vidc_audio_trigger(int dev, int enable_bits)
-{
- struct audio_operations *adev = audio_devs[dev];
-
- if (enable_bits & PCM_ENABLE_OUTPUT) {
- if (!(adev->dmap_out->flags & DMA_ACTIVE)) {
- unsigned long flags;
-
- local_irq_save(flags);
-
- /* prevent recusion */
- adev->dmap_out->flags |= DMA_ACTIVE;
-
- dma_interrupt = vidc_audio_dma_interrupt;
- vidc_sound_dma_irq(0, NULL);
- iomd_writeb(DMA_CR_E | 0x10, IOMD_SD0CR);
-
- local_irq_restore(flags);
- }
- }
-}
-
-static struct audio_driver vidc_audio_driver =
-{
- .owner = THIS_MODULE,
- .open = vidc_audio_open,
- .close = vidc_audio_close,
- .output_block = vidc_audio_output_block,
- .start_input = vidc_audio_start_input,
- .prepare_for_input = vidc_audio_prepare_for_input,
- .prepare_for_output = vidc_audio_prepare_for_output,
- .halt_io = vidc_audio_reset,
- .local_qlen = vidc_audio_local_qlen,
- .trigger = vidc_audio_trigger,
- .set_speed = vidc_audio_set_speed,
- .set_bits = vidc_audio_set_format,
- .set_channels = vidc_audio_set_channels
-};
-
-static struct mixer_operations vidc_mixer_operations = {
- .owner = THIS_MODULE,
- .id = "VIDC",
- .name = "VIDCsound",
- .ioctl = vidc_mixer_ioctl
-};
-
-void vidc_update_filler(int format, int channels)
-{
-#define TYPE(fmt,ch) (((fmt)<<2) | ((ch)&3))
-
- switch (TYPE(format, channels)) {
- default:
- case TYPE(AFMT_U8, 1):
- vidc_filler = vidc_fill_1x8_u;
- break;
-
- case TYPE(AFMT_U8, 2):
- vidc_filler = vidc_fill_2x8_u;
- break;
-
- case TYPE(AFMT_S8, 1):
- vidc_filler = vidc_fill_1x8_s;
- break;
-
- case TYPE(AFMT_S8, 2):
- vidc_filler = vidc_fill_2x8_s;
- break;
-
- case TYPE(AFMT_S16_LE, 1):
- vidc_filler = vidc_fill_1x16_s;
- break;
-
- case TYPE(AFMT_S16_LE, 2):
- vidc_filler = vidc_fill_2x16_s;
- break;
- }
-}
-
-static void __init attach_vidc(struct address_info *hw_config)
-{
- char name[32];
- int i, adev;
-
- sprintf(name, "VIDC %d-bit sound", hw_config->card_subtype);
- conf_printf(name, hw_config);
- memset(dma_buf, 0, sizeof(dma_buf));
-
- adev = sound_install_audiodrv(AUDIO_DRIVER_VERSION, name,
- &vidc_audio_driver, sizeof(vidc_audio_driver),
- DMA_AUTOMODE, AFMT_U8 | AFMT_S8 | AFMT_S16_LE,
- NULL, hw_config->dma, hw_config->dma2);
-
- if (adev < 0)
- goto audio_failed;
-
- /*
- * 1024 bytes => 64 buffers
- */
- audio_devs[adev]->min_fragment = 10;
- audio_devs[adev]->mixer_dev = num_mixers;
-
- audio_devs[adev]->mixer_dev =
- sound_install_mixer(MIXER_DRIVER_VERSION,
- name, &vidc_mixer_operations,
- sizeof(vidc_mixer_operations), NULL);
-
- if (audio_devs[adev]->mixer_dev < 0)
- goto mixer_failed;
-
- for (i = 0; i < 2; i++) {
- dma_buf[i] = get_zeroed_page(GFP_KERNEL);
- if (!dma_buf[i]) {
- printk(KERN_ERR "%s: can't allocate required buffers\n",
- name);
- goto mem_failed;
- }
- dma_pbuf[i] = virt_to_phys((void *)dma_buf[i]);
- }
-
- if (sound_alloc_dma(hw_config->dma, hw_config->name)) {
- printk(KERN_ERR "%s: DMA %d is in use\n", name, hw_config->dma);
- goto dma_failed;
- }
-
- if (request_irq(hw_config->irq, vidc_sound_dma_irq, 0,
- hw_config->name, &dma_start)) {
- printk(KERN_ERR "%s: IRQ %d is in use\n", name, hw_config->irq);
- goto irq_failed;
- }
- vidc_adev = adev;
- vidc_mixer_set(SOUND_MIXER_VOLUME, (85 | 85 << 8));
-
- return;
-
-irq_failed:
- sound_free_dma(hw_config->dma);
-dma_failed:
-mem_failed:
- for (i = 0; i < 2; i++)
- free_page(dma_buf[i]);
- sound_unload_mixerdev(audio_devs[adev]->mixer_dev);
-mixer_failed:
- sound_unload_audiodev(adev);
-audio_failed:
- return;
-}
-
-static int __init probe_vidc(struct address_info *hw_config)
-{
- hw_config->irq = IRQ_DMAS0;
- hw_config->dma = DMA_VIRTUAL_SOUND;
- hw_config->dma2 = -1;
- hw_config->card_subtype = 16;
- hw_config->name = "VIDC20";
- return 1;
-}
-
-static void __exit unload_vidc(struct address_info *hw_config)
-{
- int i, adev = vidc_adev;
-
- vidc_adev = -1;
-
- free_irq(hw_config->irq, &dma_start);
- sound_free_dma(hw_config->dma);
-
- if (adev >= 0) {
- sound_unload_mixerdev(audio_devs[adev]->mixer_dev);
- sound_unload_audiodev(adev);
- for (i = 0; i < 2; i++)
- free_page(dma_buf[i]);
- }
-}
-
-static struct address_info cfg;
-
-static int __init init_vidc(void)
-{
- if (probe_vidc(&cfg) == 0)
- return -ENODEV;
-
- attach_vidc(&cfg);
-
- return 0;
-}
-
-static void __exit cleanup_vidc(void)
-{
- unload_vidc(&cfg);
-}
-
-module_init(init_vidc);
-module_exit(cleanup_vidc);
-
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("VIDC20 audio driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/oss/vidc.h b/ANDROID_3.4.5/sound/oss/vidc.h
deleted file mode 100644
index 0d142475..00000000
--- a/ANDROID_3.4.5/sound/oss/vidc.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * linux/drivers/sound/vidc.h
- *
- * Copyright (C) 1997 Russell King <rmk@arm.linux.org.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * VIDC sound function prototypes
- */
-
-/* vidc_fill.S */
-
-/*
- * Filler routines for different channels and sample sizes
- */
-
-extern unsigned long vidc_fill_1x8_u(unsigned long ibuf, unsigned long iend,
- unsigned long obuf, int mask);
-extern unsigned long vidc_fill_2x8_u(unsigned long ibuf, unsigned long iend,
- unsigned long obuf, int mask);
-extern unsigned long vidc_fill_1x8_s(unsigned long ibuf, unsigned long iend,
- unsigned long obuf, int mask);
-extern unsigned long vidc_fill_2x8_s(unsigned long ibuf, unsigned long iend,
- unsigned long obuf, int mask);
-extern unsigned long vidc_fill_1x16_s(unsigned long ibuf, unsigned long iend,
- unsigned long obuf, int mask);
-extern unsigned long vidc_fill_2x16_s(unsigned long ibuf, unsigned long iend,
- unsigned long obuf, int mask);
-
-/*
- * DMA Interrupt handler
- */
-
-extern irqreturn_t vidc_sound_dma_irq(int irqnr, void *ref);
-
-/*
- * Filler routine pointer
- */
-
-extern unsigned long (*vidc_filler) (unsigned long ibuf, unsigned long iend,
- unsigned long obuf, int mask);
-
-/*
- * Virtual DMA buffer exhausted
- */
-
-extern irqreturn_t (*dma_interrupt) (void);
-
-/*
- * Virtual DMA buffer addresses
- */
-
-extern unsigned long dma_start, dma_count, dma_bufsize;
-extern unsigned long dma_buf[2], dma_pbuf[2];
-
-/* vidc_synth.c */
-
-extern void vidc_synth_init(struct address_info *hw_config);
-extern void vidc_synth_exit(struct address_info *hw_config);
-extern int vidc_synth_get_volume(void);
-extern int vidc_synth_set_volume(int vol);
diff --git a/ANDROID_3.4.5/sound/oss/vidc_fill.S b/ANDROID_3.4.5/sound/oss/vidc_fill.S
deleted file mode 100644
index bed34921..00000000
--- a/ANDROID_3.4.5/sound/oss/vidc_fill.S
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * linux/drivers/sound/vidc_fill.S
- *
- * Copyright (C) 1997 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Filler routines for DMA buffers
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <mach/hardware.h>
-#include <asm/hardware/iomd.h>
-
- .text
-
-ENTRY(vidc_fill_1x8_u)
- mov ip, #0xff00
-1: cmp r0, r1
- bge vidc_clear
- ldrb r4, [r0], #1
- eor r4, r4, #0x80
- and r4, ip, r4, lsl #8
- orr r4, r4, r4, lsl #16
- str r4, [r2], #4
- cmp r2, r3
- blt 1b
- mov pc, lr
-
-ENTRY(vidc_fill_2x8_u)
- mov ip, #0xff00
-1: cmp r0, r1
- bge vidc_clear
- ldr r4, [r0], #2
- and r5, r4, ip
- and r4, ip, r4, lsl #8
- orr r4, r4, r5, lsl #16
- orr r4, r4, r4, lsr #8
- str r4, [r2], #4
- cmp r2, r3
- blt 1b
- mov pc, lr
-
-ENTRY(vidc_fill_1x8_s)
- mov ip, #0xff00
-1: cmp r0, r1
- bge vidc_clear
- ldrb r4, [r0], #1
- and r4, ip, r4, lsl #8
- orr r4, r4, r4, lsl #16
- str r4, [r2], #4
- cmp r2, r3
- blt 1b
- mov pc, lr
-
-ENTRY(vidc_fill_2x8_s)
- mov ip, #0xff00
-1: cmp r0, r1
- bge vidc_clear
- ldr r4, [r0], #2
- and r5, r4, ip
- and r4, ip, r4, lsl #8
- orr r4, r4, r5, lsl #16
- orr r4, r4, r4, lsr #8
- str r4, [r2], #4
- cmp r2, r3
- blt 1b
- mov pc, lr
-
-ENTRY(vidc_fill_1x16_s)
- mov ip, #0xff00
- orr ip, ip, ip, lsr #8
-1: cmp r0, r1
- bge vidc_clear
- ldr r5, [r0], #2
- and r4, r5, ip
- orr r4, r4, r4, lsl #16
- str r4, [r2], #4
- cmp r0, r1
- addlt r0, r0, #2
- andlt r4, r5, ip, lsl #16
- orrlt r4, r4, r4, lsr #16
- strlt r4, [r2], #4
- cmp r2, r3
- blt 1b
- mov pc, lr
-
-ENTRY(vidc_fill_2x16_s)
- mov ip, #0xff00
- orr ip, ip, ip, lsr #8
-1: cmp r0, r1
- bge vidc_clear
- ldr r4, [r0], #4
- str r4, [r2], #4
- cmp r0, r1
- ldrlt r4, [r0], #4
- strlt r4, [r2], #4
- cmp r2, r3
- blt 1b
- mov pc, lr
-
-ENTRY(vidc_fill_noaudio)
- mov r0, #0
- mov r1, #0
-2: mov r4, #0
- mov r5, #0
-1: cmp r2, r3
- stmltia r2!, {r0, r1, r4, r5}
- blt 1b
- mov pc, lr
-
-ENTRY(vidc_clear)
- mov r0, #0
- mov r1, #0
- tst r2, #4
- str r0, [r2], #4
- tst r2, #8
- stmia r2!, {r0, r1}
- b 2b
-
-/*
- * Call filler routines with:
- * r0 = phys address
- * r1 = phys end
- * r2 = buffer
- * Returns:
- * r0 = new buffer address
- * r2 = new buffer finish
- * r4 = corrupted
- * r5 = corrupted
- * ip = corrupted
- */
-
-ENTRY(vidc_sound_dma_irq)
- stmfd sp!, {r4 - r8, lr}
- ldr r8, =dma_start
- ldmia r8, {r0, r1, r2, r3, r4, r5}
- teq r1, #0
- adreq r4, vidc_fill_noaudio
- moveq r7, #1 << 31
- movne r7, #0
- mov ip, #IOMD_BASE & 0xff000000
- orr ip, ip, #IOMD_BASE & 0x00ff0000
- ldrb r6, [ip, #IOMD_SD0ST]
- tst r6, #DMA_ST_OFL @ Check for overrun
- eorne r6, r6, #DMA_ST_AB
- tst r6, #DMA_ST_AB
- moveq r2, r3 @ DMAing A, update B
- add r3, r2, r5 @ End of DMA buffer
- add r1, r1, r0 @ End of virtual DMA buffer
- mov lr, pc
- mov pc, r4 @ Call fill routine (uses r4, ip)
- sub r1, r1, r0 @ Remaining length
- stmia r8, {r0, r1}
- mov r0, #0
- tst r2, #4 @ Round buffer up to 4 words
- strne r0, [r2], #4
- tst r2, #8
- strne r0, [r2], #4
- strne r0, [r2], #4
- sub r2, r2, #16
- mov r2, r2, lsl #20
- movs r2, r2, lsr #20
- orreq r2, r2, #1 << 30 @ Set L bit
- orr r2, r2, r7
- ldmdb r8, {r3, r4, r5}
- tst r6, #DMA_ST_AB
- mov ip, #IOMD_BASE & 0xff000000
- orr ip, ip, #IOMD_BASE & 0x00ff0000
- streq r4, [ip, #IOMD_SD0CURB]
- strne r5, [ip, #IOMD_SD0CURA]
- streq r2, [ip, #IOMD_SD0ENDB]
- strne r2, [ip, #IOMD_SD0ENDA]
- ldr lr, [ip, #IOMD_SD0ST]
- tst lr, #DMA_ST_OFL
- bne 1f
- tst r6, #DMA_ST_AB
- strne r4, [ip, #IOMD_SD0CURB]
- streq r5, [ip, #IOMD_SD0CURA]
- strne r2, [ip, #IOMD_SD0ENDB]
- streq r2, [ip, #IOMD_SD0ENDA]
-1: teq r7, #0
- mov r0, #0x10
- strneb r0, [ip, #IOMD_SD0CR]
- ldmfd sp!, {r4 - r8, lr}
- mov r0, #1 @ IRQ_HANDLED
- teq r1, #0 @ If we have no more
- movne pc, lr
- teq r3, #0
- movne pc, r3 @ Call interrupt routine
- mov pc, lr
-
- .data
- .globl dma_interrupt
-dma_interrupt:
- .long 0 @ r3
- .globl dma_pbuf
-dma_pbuf:
- .long 0 @ r4
- .long 0 @ r5
- .globl dma_start
-dma_start:
- .long 0 @ r0
- .globl dma_count
-dma_count:
- .long 0 @ r1
- .globl dma_buf
-dma_buf:
- .long 0 @ r2
- .long 0 @ r3
- .globl vidc_filler
-vidc_filler:
- .long vidc_fill_noaudio @ r4
- .globl dma_bufsize
-dma_bufsize:
- .long 0x1000 @ r5
diff --git a/ANDROID_3.4.5/sound/oss/vwsnd.c b/ANDROID_3.4.5/sound/oss/vwsnd.c
deleted file mode 100644
index 643f1113..00000000
--- a/ANDROID_3.4.5/sound/oss/vwsnd.c
+++ /dev/null
@@ -1,3498 +0,0 @@
-/*
- * Sound driver for Silicon Graphics 320 and 540 Visual Workstations'
- * onboard audio. See notes in Documentation/sound/oss/vwsnd .
- *
- * Copyright 1999 Silicon Graphics, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#undef VWSND_DEBUG /* define for debugging */
-
-/*
- * XXX to do -
- *
- * External sync.
- * Rename swbuf, hwbuf, u&i, hwptr&swptr to something rational.
- * Bug - if select() called before read(), pcm_setup() not called.
- * Bug - output doesn't stop soon enough if process killed.
- */
-
-/*
- * Things to test -
- *
- * Will readv/writev work? Write a test.
- *
- * insmod/rmmod 100 million times.
- *
- * Run I/O until int ptrs wrap around (roughly 6.2 hours @ DAT
- * rate).
- *
- * Concurrent threads banging on mixer simultaneously, both UP
- * and SMP kernels. Especially, watch for thread A changing
- * OUTSRC while thread B changes gain -- both write to the same
- * ad1843 register.
- *
- * What happens if a client opens /dev/audio then forks?
- * Do two procs have /dev/audio open? Test.
- *
- * Pump audio through the CD, MIC and line inputs and verify that
- * they mix/mute into the output.
- *
- * Apps:
- * amp
- * mpg123
- * x11amp
- * mxv
- * kmedia
- * esound
- * need more input apps
- *
- * Run tests while bombarding with signals. setitimer(2) will do it... */
-
-/*
- * This driver is organized in nine sections.
- * The nine sections are:
- *
- * debug stuff
- * low level lithium access
- * high level lithium access
- * AD1843 access
- * PCM I/O
- * audio driver
- * mixer driver
- * probe/attach/unload
- * initialization and loadable kernel module interface
- *
- * That is roughly the order of increasing abstraction, so forward
- * dependencies are minimal.
- */
-
-/*
- * Locking Notes
- *
- * INC_USE_COUNT and DEC_USE_COUNT keep track of the number of
- * open descriptors to this driver. They store it in vwsnd_use_count.
- * The global device list, vwsnd_dev_list, is immutable when the IN_USE
- * is true.
- *
- * devc->open_lock is a semaphore that is used to enforce the
- * single reader/single writer rule for /dev/audio. The rule is
- * that each device may have at most one reader and one writer.
- * Open will block until the previous client has closed the
- * device, unless O_NONBLOCK is specified.
- *
- * The semaphore devc->io_mutex serializes PCM I/O syscalls. This
- * is unnecessary in Linux 2.2, because the kernel lock
- * serializes read, write, and ioctl globally, but it's there,
- * ready for the brave, new post-kernel-lock world.
- *
- * Locking between interrupt and baselevel is handled by the
- * "lock" spinlock in vwsnd_port (one lock each for read and
- * write). Each half holds the lock just long enough to see what
- * area it owns and update its pointers. See pcm_output() and
- * pcm_input() for most of the gory stuff.
- *
- * devc->mix_mutex serializes all mixer ioctls. This is also
- * redundant because of the kernel lock.
- *
- * The lowest level lock is lith->lithium_lock. It is a
- * spinlock which is held during the two-register tango of
- * reading/writing an AD1843 register. See
- * li_{read,write}_ad1843_reg().
- */
-
-/*
- * Sample Format Notes
- *
- * Lithium's DMA engine has two formats: 16-bit 2's complement
- * and 8-bit unsigned . 16-bit transfers the data unmodified, 2
- * bytes per sample. 8-bit unsigned transfers 1 byte per sample
- * and XORs each byte with 0x80. Lithium can input or output
- * either mono or stereo in either format.
- *
- * The AD1843 has four formats: 16-bit 2's complement, 8-bit
- * unsigned, 8-bit mu-Law and 8-bit A-Law.
- *
- * This driver supports five formats: AFMT_S8, AFMT_U8,
- * AFMT_MU_LAW, AFMT_A_LAW, and AFMT_S16_LE.
- *
- * For AFMT_U8 output, we keep the AD1843 in 16-bit mode, and
- * rely on Lithium's XOR to translate between U8 and S8.
- *
- * For AFMT_S8, AFMT_MU_LAW and AFMT_A_LAW output, we have to XOR
- * the 0x80 bit in software to compensate for Lithium's XOR.
- * This happens in pcm_copy_{in,out}().
- *
- * Changes:
- * 11-10-2000 Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
- * Added some __init/__exit
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/spinlock.h>
-#include <linux/wait.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-
-#include <asm/visws/cobalt.h>
-
-#include "sound_config.h"
-
-/*****************************************************************************/
-/* debug stuff */
-
-#ifdef VWSND_DEBUG
-
-static DEFINE_MUTEX(vwsnd_mutex);
-static int shut_up = 1;
-
-/*
- * dbgassert - called when an assertion fails.
- */
-
-static void dbgassert(const char *fcn, int line, const char *expr)
-{
- if (in_interrupt())
- panic("ASSERTION FAILED IN INTERRUPT, %s:%s:%d %s\n",
- __FILE__, fcn, line, expr);
- else {
- int x;
- printk(KERN_ERR "ASSERTION FAILED, %s:%s:%d %s\n",
- __FILE__, fcn, line, expr);
- x = * (volatile int *) 0; /* force proc to exit */
- }
-}
-
-/*
- * Bunch of useful debug macros:
- *
- * ASSERT - print unless e nonzero (panic if in interrupt)
- * DBGDO - include arbitrary code if debugging
- * DBGX - debug print raw (w/o function name)
- * DBGP - debug print w/ function name
- * DBGE - debug print function entry
- * DBGC - debug print function call
- * DBGR - debug print function return
- * DBGXV - debug print raw when verbose
- * DBGPV - debug print when verbose
- * DBGEV - debug print function entry when verbose
- * DBGRV - debug print function return when verbose
- */
-
-#define ASSERT(e) ((e) ? (void) 0 : dbgassert(__func__, __LINE__, #e))
-#define DBGDO(x) x
-#define DBGX(fmt, args...) (in_interrupt() ? 0 : printk(KERN_ERR fmt, ##args))
-#define DBGP(fmt, args...) (DBGX("%s: " fmt, __func__ , ##args))
-#define DBGE(fmt, args...) (DBGX("%s" fmt, __func__ , ##args))
-#define DBGC(rtn) (DBGP("calling %s\n", rtn))
-#define DBGR() (DBGP("returning\n"))
-#define DBGXV(fmt, args...) (shut_up ? 0 : DBGX(fmt, ##args))
-#define DBGPV(fmt, args...) (shut_up ? 0 : DBGP(fmt, ##args))
-#define DBGEV(fmt, args...) (shut_up ? 0 : DBGE(fmt, ##args))
-#define DBGCV(rtn) (shut_up ? 0 : DBGC(rtn))
-#define DBGRV() (shut_up ? 0 : DBGR())
-
-#else /* !VWSND_DEBUG */
-
-#define ASSERT(e) ((void) 0)
-#define DBGDO(x) /* don't */
-#define DBGX(fmt, args...) ((void) 0)
-#define DBGP(fmt, args...) ((void) 0)
-#define DBGE(fmt, args...) ((void) 0)
-#define DBGC(rtn) ((void) 0)
-#define DBGR() ((void) 0)
-#define DBGPV(fmt, args...) ((void) 0)
-#define DBGXV(fmt, args...) ((void) 0)
-#define DBGEV(fmt, args...) ((void) 0)
-#define DBGCV(rtn) ((void) 0)
-#define DBGRV() ((void) 0)
-
-#endif /* !VWSND_DEBUG */
-
-/*****************************************************************************/
-/* low level lithium access */
-
-/*
- * We need to talk to Lithium registers on three pages. Here are
- * the pages' offsets from the base address (0xFF001000).
- */
-
-enum {
- LI_PAGE0_OFFSET = 0x01000 - 0x1000, /* FF001000 */
- LI_PAGE1_OFFSET = 0x0F000 - 0x1000, /* FF00F000 */
- LI_PAGE2_OFFSET = 0x10000 - 0x1000, /* FF010000 */
-};
-
-/* low-level lithium data */
-
-typedef struct lithium {
- void * page0; /* virtual addresses */
- void * page1;
- void * page2;
- spinlock_t lock; /* protects codec and UST/MSC access */
-} lithium_t;
-
-/*
- * li_destroy destroys the lithium_t structure and vm mappings.
- */
-
-static void li_destroy(lithium_t *lith)
-{
- if (lith->page0) {
- iounmap(lith->page0);
- lith->page0 = NULL;
- }
- if (lith->page1) {
- iounmap(lith->page1);
- lith->page1 = NULL;
- }
- if (lith->page2) {
- iounmap(lith->page2);
- lith->page2 = NULL;
- }
-}
-
-/*
- * li_create initializes the lithium_t structure and sets up vm mappings
- * to access the registers.
- * Returns 0 on success, -errno on failure.
- */
-
-static int __init li_create(lithium_t *lith, unsigned long baseaddr)
-{
- spin_lock_init(&lith->lock);
- lith->page0 = ioremap_nocache(baseaddr + LI_PAGE0_OFFSET, PAGE_SIZE);
- lith->page1 = ioremap_nocache(baseaddr + LI_PAGE1_OFFSET, PAGE_SIZE);
- lith->page2 = ioremap_nocache(baseaddr + LI_PAGE2_OFFSET, PAGE_SIZE);
- if (!lith->page0 || !lith->page1 || !lith->page2) {
- li_destroy(lith);
- return -ENOMEM;
- }
- return 0;
-}
-
-/*
- * basic register accessors - read/write long/byte
- */
-
-static __inline__ unsigned long li_readl(lithium_t *lith, int off)
-{
- return * (volatile unsigned long *) (lith->page0 + off);
-}
-
-static __inline__ unsigned char li_readb(lithium_t *lith, int off)
-{
- return * (volatile unsigned char *) (lith->page0 + off);
-}
-
-static __inline__ void li_writel(lithium_t *lith, int off, unsigned long val)
-{
- * (volatile unsigned long *) (lith->page0 + off) = val;
-}
-
-static __inline__ void li_writeb(lithium_t *lith, int off, unsigned char val)
-{
- * (volatile unsigned char *) (lith->page0 + off) = val;
-}
-
-/*****************************************************************************/
-/* High Level Lithium Access */
-
-/*
- * Lithium DMA Notes
- *
- * Lithium has two dedicated DMA channels for audio. They are known
- * as comm1 and comm2 (communication areas 1 and 2). Comm1 is for
- * input, and comm2 is for output. Each is controlled by three
- * registers: BASE (base address), CFG (config) and CCTL
- * (config/control).
- *
- * Each DMA channel points to a physically contiguous ring buffer in
- * main memory of up to 8 Kbytes. (This driver always uses 8 Kb.)
- * There are three pointers into the ring buffer: read, write, and
- * trigger. The pointers are 8 bits each. Each pointer points to
- * 32-byte "chunks" of data. The DMA engine moves 32 bytes at a time,
- * so there is no finer-granularity control.
- *
- * In comm1, the hardware updates the write ptr, and software updates
- * the read ptr. In comm2, it's the opposite: hardware updates the
- * read ptr, and software updates the write ptr. I designate the
- * hardware-updated ptr as the hwptr, and the software-updated ptr as
- * the swptr.
- *
- * The trigger ptr and trigger mask are used to trigger interrupts.
- * From the Lithium spec, section 5.6.8, revision of 12/15/1998:
- *
- * Trigger Mask Value
- *
- * A three bit wide field that represents a power of two mask
- * that is used whenever the trigger pointer is compared to its
- * respective read or write pointer. A value of zero here
- * implies a mask of 0xFF and a value of seven implies a mask
- * 0x01. This value can be used to sub-divide the ring buffer
- * into pie sections so that interrupts monitor the progress of
- * hardware from section to section.
- *
- * My interpretation of that is, whenever the hw ptr is updated, it is
- * compared with the trigger ptr, and the result is masked by the
- * trigger mask. (Actually, by the complement of the trigger mask.)
- * If the result is zero, an interrupt is triggered. I.e., interrupt
- * if ((hwptr & ~mask) == (trptr & ~mask)). The mask is formed from
- * the trigger register value as mask = (1 << (8 - tmreg)) - 1.
- *
- * In yet different words, setting tmreg to 0 causes an interrupt after
- * every 256 DMA chunks (8192 bytes) or once per traversal of the
- * ring buffer. Setting it to 7 caues an interrupt every 2 DMA chunks
- * (64 bytes) or 128 times per traversal of the ring buffer.
- */
-
-/* Lithium register offsets and bit definitions */
-
-#define LI_HOST_CONTROLLER 0x000
-# define LI_HC_RESET 0x00008000
-# define LI_HC_LINK_ENABLE 0x00004000
-# define LI_HC_LINK_FAILURE 0x00000004
-# define LI_HC_LINK_CODEC 0x00000002
-# define LI_HC_LINK_READY 0x00000001
-
-#define LI_INTR_STATUS 0x010
-#define LI_INTR_MASK 0x014
-# define LI_INTR_LINK_ERR 0x00008000
-# define LI_INTR_COMM2_TRIG 0x00000008
-# define LI_INTR_COMM2_UNDERFLOW 0x00000004
-# define LI_INTR_COMM1_TRIG 0x00000002
-# define LI_INTR_COMM1_OVERFLOW 0x00000001
-
-#define LI_CODEC_COMMAND 0x018
-# define LI_CC_BUSY 0x00008000
-# define LI_CC_DIR 0x00000080
-# define LI_CC_DIR_RD LI_CC_DIR
-# define LI_CC_DIR_WR (!LI_CC_DIR)
-# define LI_CC_ADDR_MASK 0x0000007F
-
-#define LI_CODEC_DATA 0x01C
-
-#define LI_COMM1_BASE 0x100
-#define LI_COMM1_CTL 0x104
-# define LI_CCTL_RESET 0x80000000
-# define LI_CCTL_SIZE 0x70000000
-# define LI_CCTL_DMA_ENABLE 0x08000000
-# define LI_CCTL_TMASK 0x07000000 /* trigger mask */
-# define LI_CCTL_TPTR 0x00FF0000 /* trigger pointer */
-# define LI_CCTL_RPTR 0x0000FF00
-# define LI_CCTL_WPTR 0x000000FF
-#define LI_COMM1_CFG 0x108
-# define LI_CCFG_LOCK 0x00008000
-# define LI_CCFG_SLOT 0x00000070
-# define LI_CCFG_DIRECTION 0x00000008
-# define LI_CCFG_DIR_IN (!LI_CCFG_DIRECTION)
-# define LI_CCFG_DIR_OUT LI_CCFG_DIRECTION
-# define LI_CCFG_MODE 0x00000004
-# define LI_CCFG_MODE_MONO (!LI_CCFG_MODE)
-# define LI_CCFG_MODE_STEREO LI_CCFG_MODE
-# define LI_CCFG_FORMAT 0x00000003
-# define LI_CCFG_FMT_8BIT 0x00000000
-# define LI_CCFG_FMT_16BIT 0x00000001
-#define LI_COMM2_BASE 0x10C
-#define LI_COMM2_CTL 0x110
- /* bit definitions are the same as LI_COMM1_CTL */
-#define LI_COMM2_CFG 0x114
- /* bit definitions are the same as LI_COMM1_CFG */
-
-#define LI_UST_LOW 0x200 /* 64-bit Unadjusted System Time is */
-#define LI_UST_HIGH 0x204 /* microseconds since boot */
-
-#define LI_AUDIO1_UST 0x300 /* UST-MSC pairs */
-#define LI_AUDIO1_MSC 0x304 /* MSC (Media Stream Counter) */
-#define LI_AUDIO2_UST 0x308 /* counts samples actually */
-#define LI_AUDIO2_MSC 0x30C /* processed as of time UST */
-
-/*
- * Lithium's DMA engine operates on chunks of 32 bytes. We call that
- * a DMACHUNK.
- */
-
-#define DMACHUNK_SHIFT 5
-#define DMACHUNK_SIZE (1 << DMACHUNK_SHIFT)
-#define BYTES_TO_CHUNKS(bytes) ((bytes) >> DMACHUNK_SHIFT)
-#define CHUNKS_TO_BYTES(chunks) ((chunks) << DMACHUNK_SHIFT)
-
-/*
- * Two convenient macros to shift bitfields into/out of position.
- *
- * Observe that (mask & -mask) is (1 << low_set_bit_of(mask)).
- * As long as mask is constant, we trust the compiler will change the
- * multipy and divide into shifts.
- */
-
-#define SHIFT_FIELD(val, mask) (((val) * ((mask) & -(mask))) & (mask))
-#define UNSHIFT_FIELD(val, mask) (((val) & (mask)) / ((mask) & -(mask)))
-
-/*
- * dma_chan_desc is invariant information about a Lithium
- * DMA channel. There are two instances, li_comm1 and li_comm2.
- *
- * Note that the CCTL register fields are write ptr and read ptr, but what
- * we care about are which pointer is updated by software and which by
- * hardware.
- */
-
-typedef struct dma_chan_desc {
- int basereg;
- int cfgreg;
- int ctlreg;
- int hwptrreg;
- int swptrreg;
- int ustreg;
- int mscreg;
- unsigned long swptrmask;
- int ad1843_slot;
- int direction; /* LI_CCTL_DIR_IN/OUT */
-} dma_chan_desc_t;
-
-static const dma_chan_desc_t li_comm1 = {
- LI_COMM1_BASE, /* base register offset */
- LI_COMM1_CFG, /* config register offset */
- LI_COMM1_CTL, /* control register offset */
- LI_COMM1_CTL + 0, /* hw ptr reg offset (write ptr) */
- LI_COMM1_CTL + 1, /* sw ptr reg offset (read ptr) */
- LI_AUDIO1_UST, /* ust reg offset */
- LI_AUDIO1_MSC, /* msc reg offset */
- LI_CCTL_RPTR, /* sw ptr bitmask in ctlval */
- 2, /* ad1843 serial slot */
- LI_CCFG_DIR_IN /* direction */
-};
-
-static const dma_chan_desc_t li_comm2 = {
- LI_COMM2_BASE, /* base register offset */
- LI_COMM2_CFG, /* config register offset */
- LI_COMM2_CTL, /* control register offset */
- LI_COMM2_CTL + 1, /* hw ptr reg offset (read ptr) */
- LI_COMM2_CTL + 0, /* sw ptr reg offset (writr ptr) */
- LI_AUDIO2_UST, /* ust reg offset */
- LI_AUDIO2_MSC, /* msc reg offset */
- LI_CCTL_WPTR, /* sw ptr bitmask in ctlval */
- 2, /* ad1843 serial slot */
- LI_CCFG_DIR_OUT /* direction */
-};
-
-/*
- * dma_chan is variable information about a Lithium DMA channel.
- *
- * The desc field points to invariant information.
- * The lith field points to a lithium_t which is passed
- * to li_read* and li_write* to access the registers.
- * The *val fields shadow the lithium registers' contents.
- */
-
-typedef struct dma_chan {
- const dma_chan_desc_t *desc;
- lithium_t *lith;
- unsigned long baseval;
- unsigned long cfgval;
- unsigned long ctlval;
-} dma_chan_t;
-
-/*
- * ustmsc is a UST/MSC pair (Unadjusted System Time/Media Stream Counter).
- * UST is time in microseconds since the system booted, and MSC is a
- * counter that increments with every audio sample.
- */
-
-typedef struct ustmsc {
- unsigned long long ust;
- unsigned long msc;
-} ustmsc_t;
-
-/*
- * li_ad1843_wait waits until lithium says the AD1843 register
- * exchange is not busy. Returns 0 on success, -EBUSY on timeout.
- *
- * Locking: must be called with lithium_lock held.
- */
-
-static int li_ad1843_wait(lithium_t *lith)
-{
- unsigned long later = jiffies + 2;
- while (li_readl(lith, LI_CODEC_COMMAND) & LI_CC_BUSY)
- if (time_after_eq(jiffies, later))
- return -EBUSY;
- return 0;
-}
-
-/*
- * li_read_ad1843_reg returns the current contents of a 16 bit AD1843 register.
- *
- * Returns unsigned register value on success, -errno on failure.
- */
-
-static int li_read_ad1843_reg(lithium_t *lith, int reg)
-{
- int val;
-
- ASSERT(!in_interrupt());
- spin_lock(&lith->lock);
- {
- val = li_ad1843_wait(lith);
- if (val == 0) {
- li_writel(lith, LI_CODEC_COMMAND, LI_CC_DIR_RD | reg);
- val = li_ad1843_wait(lith);
- }
- if (val == 0)
- val = li_readl(lith, LI_CODEC_DATA);
- }
- spin_unlock(&lith->lock);
-
- DBGXV("li_read_ad1843_reg(lith=0x%p, reg=%d) returns 0x%04x\n",
- lith, reg, val);
-
- return val;
-}
-
-/*
- * li_write_ad1843_reg writes the specified value to a 16 bit AD1843 register.
- */
-
-static void li_write_ad1843_reg(lithium_t *lith, int reg, int newval)
-{
- spin_lock(&lith->lock);
- {
- if (li_ad1843_wait(lith) == 0) {
- li_writel(lith, LI_CODEC_DATA, newval);
- li_writel(lith, LI_CODEC_COMMAND, LI_CC_DIR_WR | reg);
- }
- }
- spin_unlock(&lith->lock);
-}
-
-/*
- * li_setup_dma calculates all the register settings for DMA in a particular
- * mode. It takes too many arguments.
- */
-
-static void li_setup_dma(dma_chan_t *chan,
- const dma_chan_desc_t *desc,
- lithium_t *lith,
- unsigned long buffer_paddr,
- int bufshift,
- int fragshift,
- int channels,
- int sampsize)
-{
- unsigned long mode, format;
- unsigned long size, tmask;
-
- DBGEV("(chan=0x%p, desc=0x%p, lith=0x%p, buffer_paddr=0x%lx, "
- "bufshift=%d, fragshift=%d, channels=%d, sampsize=%d)\n",
- chan, desc, lith, buffer_paddr,
- bufshift, fragshift, channels, sampsize);
-
- /* Reset the channel first. */
-
- li_writel(lith, desc->ctlreg, LI_CCTL_RESET);
-
- ASSERT(channels == 1 || channels == 2);
- if (channels == 2)
- mode = LI_CCFG_MODE_STEREO;
- else
- mode = LI_CCFG_MODE_MONO;
- ASSERT(sampsize == 1 || sampsize == 2);
- if (sampsize == 2)
- format = LI_CCFG_FMT_16BIT;
- else
- format = LI_CCFG_FMT_8BIT;
- chan->desc = desc;
- chan->lith = lith;
-
- /*
- * Lithium DMA address register takes a 40-bit physical
- * address, right-shifted by 8 so it fits in 32 bits. Bit 37
- * must be set -- it enables cache coherence.
- */
-
- ASSERT(!(buffer_paddr & 0xFF));
- chan->baseval = (buffer_paddr >> 8) | 1 << (37 - 8);
-
- chan->cfgval = ((chan->cfgval & ~LI_CCFG_LOCK) |
- SHIFT_FIELD(desc->ad1843_slot, LI_CCFG_SLOT) |
- desc->direction |
- mode |
- format);
-
- size = bufshift - 6;
- tmask = 13 - fragshift; /* See Lithium DMA Notes above. */
- ASSERT(size >= 2 && size <= 7);
- ASSERT(tmask >= 1 && tmask <= 7);
- chan->ctlval = ((chan->ctlval & ~LI_CCTL_RESET) |
- SHIFT_FIELD(size, LI_CCTL_SIZE) |
- (chan->ctlval & ~LI_CCTL_DMA_ENABLE) |
- SHIFT_FIELD(tmask, LI_CCTL_TMASK) |
- SHIFT_FIELD(0, LI_CCTL_TPTR));
-
- DBGPV("basereg 0x%x = 0x%lx\n", desc->basereg, chan->baseval);
- DBGPV("cfgreg 0x%x = 0x%lx\n", desc->cfgreg, chan->cfgval);
- DBGPV("ctlreg 0x%x = 0x%lx\n", desc->ctlreg, chan->ctlval);
-
- li_writel(lith, desc->basereg, chan->baseval);
- li_writel(lith, desc->cfgreg, chan->cfgval);
- li_writel(lith, desc->ctlreg, chan->ctlval);
-
- DBGRV();
-}
-
-static void li_shutdown_dma(dma_chan_t *chan)
-{
- lithium_t *lith = chan->lith;
- void * lith1 = lith->page1;
-
- DBGEV("(chan=0x%p)\n", chan);
-
- chan->ctlval &= ~LI_CCTL_DMA_ENABLE;
- DBGPV("ctlreg 0x%x = 0x%lx\n", chan->desc->ctlreg, chan->ctlval);
- li_writel(lith, chan->desc->ctlreg, chan->ctlval);
-
- /*
- * Offset 0x500 on Lithium page 1 is an undocumented,
- * unsupported register that holds the zero sample value.
- * Lithium is supposed to output zero samples when DMA is
- * inactive, and repeat the last sample when DMA underflows.
- * But it has a bug, where, after underflow occurs, the zero
- * sample is not reset.
- *
- * I expect this to break in a future rev of Lithium.
- */
-
- if (lith1 && chan->desc->direction == LI_CCFG_DIR_OUT)
- * (volatile unsigned long *) (lith1 + 0x500) = 0;
-}
-
-/*
- * li_activate_dma always starts dma at the beginning of the buffer.
- *
- * N.B., these may be called from interrupt.
- */
-
-static __inline__ void li_activate_dma(dma_chan_t *chan)
-{
- chan->ctlval |= LI_CCTL_DMA_ENABLE;
- DBGPV("ctlval = 0x%lx\n", chan->ctlval);
- li_writel(chan->lith, chan->desc->ctlreg, chan->ctlval);
-}
-
-static void li_deactivate_dma(dma_chan_t *chan)
-{
- lithium_t *lith = chan->lith;
- void * lith2 = lith->page2;
-
- chan->ctlval &= ~(LI_CCTL_DMA_ENABLE | LI_CCTL_RPTR | LI_CCTL_WPTR);
- DBGPV("ctlval = 0x%lx\n", chan->ctlval);
- DBGPV("ctlreg 0x%x = 0x%lx\n", chan->desc->ctlreg, chan->ctlval);
- li_writel(lith, chan->desc->ctlreg, chan->ctlval);
-
- /*
- * Offsets 0x98 and 0x9C on Lithium page 2 are undocumented,
- * unsupported registers that are internal copies of the DMA
- * read and write pointers. Because of a Lithium bug, these
- * registers aren't zeroed correctly when DMA is shut off. So
- * we whack them directly.
- *
- * I expect this to break in a future rev of Lithium.
- */
-
- if (lith2 && chan->desc->direction == LI_CCFG_DIR_OUT) {
- * (volatile unsigned long *) (lith2 + 0x98) = 0;
- * (volatile unsigned long *) (lith2 + 0x9C) = 0;
- }
-}
-
-/*
- * read/write the ring buffer pointers. These routines' arguments and results
- * are byte offsets from the beginning of the ring buffer.
- */
-
-static __inline__ int li_read_swptr(dma_chan_t *chan)
-{
- const unsigned long mask = chan->desc->swptrmask;
-
- return CHUNKS_TO_BYTES(UNSHIFT_FIELD(chan->ctlval, mask));
-}
-
-static __inline__ int li_read_hwptr(dma_chan_t *chan)
-{
- return CHUNKS_TO_BYTES(li_readb(chan->lith, chan->desc->hwptrreg));
-}
-
-static __inline__ void li_write_swptr(dma_chan_t *chan, int val)
-{
- const unsigned long mask = chan->desc->swptrmask;
-
- ASSERT(!(val & ~CHUNKS_TO_BYTES(0xFF)));
- val = BYTES_TO_CHUNKS(val);
- chan->ctlval = (chan->ctlval & ~mask) | SHIFT_FIELD(val, mask);
- li_writeb(chan->lith, chan->desc->swptrreg, val);
-}
-
-/* li_read_USTMSC() returns a UST/MSC pair for the given channel. */
-
-static void li_read_USTMSC(dma_chan_t *chan, ustmsc_t *ustmsc)
-{
- lithium_t *lith = chan->lith;
- const dma_chan_desc_t *desc = chan->desc;
- unsigned long now_low, now_high0, now_high1, chan_ust;
-
- spin_lock(&lith->lock);
- {
- /*
- * retry until we do all five reads without the
- * high word changing. (High word increments
- * every 2^32 microseconds, i.e., not often)
- */
- do {
- now_high0 = li_readl(lith, LI_UST_HIGH);
- now_low = li_readl(lith, LI_UST_LOW);
-
- /*
- * Lithium guarantees these two reads will be
- * atomic -- ust will not increment after msc
- * is read.
- */
-
- ustmsc->msc = li_readl(lith, desc->mscreg);
- chan_ust = li_readl(lith, desc->ustreg);
-
- now_high1 = li_readl(lith, LI_UST_HIGH);
- } while (now_high0 != now_high1);
- }
- spin_unlock(&lith->lock);
- ustmsc->ust = ((unsigned long long) now_high0 << 32 | chan_ust);
-}
-
-static void li_enable_interrupts(lithium_t *lith, unsigned int mask)
-{
- DBGEV("(lith=0x%p, mask=0x%x)\n", lith, mask);
-
- /* clear any already-pending interrupts. */
-
- li_writel(lith, LI_INTR_STATUS, mask);
-
- /* enable the interrupts. */
-
- mask |= li_readl(lith, LI_INTR_MASK);
- li_writel(lith, LI_INTR_MASK, mask);
-}
-
-static void li_disable_interrupts(lithium_t *lith, unsigned int mask)
-{
- unsigned int keepmask;
-
- DBGEV("(lith=0x%p, mask=0x%x)\n", lith, mask);
-
- /* disable the interrupts */
-
- keepmask = li_readl(lith, LI_INTR_MASK) & ~mask;
- li_writel(lith, LI_INTR_MASK, keepmask);
-
- /* clear any pending interrupts. */
-
- li_writel(lith, LI_INTR_STATUS, mask);
-}
-
-/* Get the interrupt status and clear all pending interrupts. */
-
-static unsigned int li_get_clear_intr_status(lithium_t *lith)
-{
- unsigned int status;
-
- status = li_readl(lith, LI_INTR_STATUS);
- li_writel(lith, LI_INTR_STATUS, ~0);
- return status & li_readl(lith, LI_INTR_MASK);
-}
-
-static int li_init(lithium_t *lith)
-{
- /* 1. System power supplies stabilize. */
-
- /* 2. Assert the ~RESET signal. */
-
- li_writel(lith, LI_HOST_CONTROLLER, LI_HC_RESET);
- udelay(1);
-
- /* 3. Deassert the ~RESET signal and enter a wait period to allow
- the AD1843 internal clocks and the external crystal oscillator
- to stabilize. */
-
- li_writel(lith, LI_HOST_CONTROLLER, LI_HC_LINK_ENABLE);
- udelay(1);
-
- return 0;
-}
-
-/*****************************************************************************/
-/* AD1843 access */
-
-/*
- * AD1843 bitfield definitions. All are named as in the AD1843 data
- * sheet, with ad1843_ prepended and individual bit numbers removed.
- *
- * E.g., bits LSS0 through LSS2 become ad1843_LSS.
- *
- * Only the bitfields we need are defined.
- */
-
-typedef struct ad1843_bitfield {
- char reg;
- char lo_bit;
- char nbits;
-} ad1843_bitfield_t;
-
-static const ad1843_bitfield_t
- ad1843_PDNO = { 0, 14, 1 }, /* Converter Power-Down Flag */
- ad1843_INIT = { 0, 15, 1 }, /* Clock Initialization Flag */
- ad1843_RIG = { 2, 0, 4 }, /* Right ADC Input Gain */
- ad1843_RMGE = { 2, 4, 1 }, /* Right ADC Mic Gain Enable */
- ad1843_RSS = { 2, 5, 3 }, /* Right ADC Source Select */
- ad1843_LIG = { 2, 8, 4 }, /* Left ADC Input Gain */
- ad1843_LMGE = { 2, 12, 1 }, /* Left ADC Mic Gain Enable */
- ad1843_LSS = { 2, 13, 3 }, /* Left ADC Source Select */
- ad1843_RX1M = { 4, 0, 5 }, /* Right Aux 1 Mix Gain/Atten */
- ad1843_RX1MM = { 4, 7, 1 }, /* Right Aux 1 Mix Mute */
- ad1843_LX1M = { 4, 8, 5 }, /* Left Aux 1 Mix Gain/Atten */
- ad1843_LX1MM = { 4, 15, 1 }, /* Left Aux 1 Mix Mute */
- ad1843_RX2M = { 5, 0, 5 }, /* Right Aux 2 Mix Gain/Atten */
- ad1843_RX2MM = { 5, 7, 1 }, /* Right Aux 2 Mix Mute */
- ad1843_LX2M = { 5, 8, 5 }, /* Left Aux 2 Mix Gain/Atten */
- ad1843_LX2MM = { 5, 15, 1 }, /* Left Aux 2 Mix Mute */
- ad1843_RMCM = { 7, 0, 5 }, /* Right Mic Mix Gain/Atten */
- ad1843_RMCMM = { 7, 7, 1 }, /* Right Mic Mix Mute */
- ad1843_LMCM = { 7, 8, 5 }, /* Left Mic Mix Gain/Atten */
- ad1843_LMCMM = { 7, 15, 1 }, /* Left Mic Mix Mute */
- ad1843_HPOS = { 8, 4, 1 }, /* Headphone Output Voltage Swing */
- ad1843_HPOM = { 8, 5, 1 }, /* Headphone Output Mute */
- ad1843_RDA1G = { 9, 0, 6 }, /* Right DAC1 Analog/Digital Gain */
- ad1843_RDA1GM = { 9, 7, 1 }, /* Right DAC1 Analog Mute */
- ad1843_LDA1G = { 9, 8, 6 }, /* Left DAC1 Analog/Digital Gain */
- ad1843_LDA1GM = { 9, 15, 1 }, /* Left DAC1 Analog Mute */
- ad1843_RDA1AM = { 11, 7, 1 }, /* Right DAC1 Digital Mute */
- ad1843_LDA1AM = { 11, 15, 1 }, /* Left DAC1 Digital Mute */
- ad1843_ADLC = { 15, 0, 2 }, /* ADC Left Sample Rate Source */
- ad1843_ADRC = { 15, 2, 2 }, /* ADC Right Sample Rate Source */
- ad1843_DA1C = { 15, 8, 2 }, /* DAC1 Sample Rate Source */
- ad1843_C1C = { 17, 0, 16 }, /* Clock 1 Sample Rate Select */
- ad1843_C2C = { 20, 0, 16 }, /* Clock 1 Sample Rate Select */
- ad1843_DAADL = { 25, 4, 2 }, /* Digital ADC Left Source Select */
- ad1843_DAADR = { 25, 6, 2 }, /* Digital ADC Right Source Select */
- ad1843_DRSFLT = { 25, 15, 1 }, /* Digital Reampler Filter Mode */
- ad1843_ADLF = { 26, 0, 2 }, /* ADC Left Channel Data Format */
- ad1843_ADRF = { 26, 2, 2 }, /* ADC Right Channel Data Format */
- ad1843_ADTLK = { 26, 4, 1 }, /* ADC Transmit Lock Mode Select */
- ad1843_SCF = { 26, 7, 1 }, /* SCLK Frequency Select */
- ad1843_DA1F = { 26, 8, 2 }, /* DAC1 Data Format Select */
- ad1843_DA1SM = { 26, 14, 1 }, /* DAC1 Stereo/Mono Mode Select */
- ad1843_ADLEN = { 27, 0, 1 }, /* ADC Left Channel Enable */
- ad1843_ADREN = { 27, 1, 1 }, /* ADC Right Channel Enable */
- ad1843_AAMEN = { 27, 4, 1 }, /* Analog to Analog Mix Enable */
- ad1843_ANAEN = { 27, 7, 1 }, /* Analog Channel Enable */
- ad1843_DA1EN = { 27, 8, 1 }, /* DAC1 Enable */
- ad1843_DA2EN = { 27, 9, 1 }, /* DAC2 Enable */
- ad1843_C1EN = { 28, 11, 1 }, /* Clock Generator 1 Enable */
- ad1843_C2EN = { 28, 12, 1 }, /* Clock Generator 2 Enable */
- ad1843_PDNI = { 28, 15, 1 }; /* Converter Power Down */
-
-/*
- * The various registers of the AD1843 use three different formats for
- * specifying gain. The ad1843_gain structure parameterizes the
- * formats.
- */
-
-typedef struct ad1843_gain {
-
- int negative; /* nonzero if gain is negative. */
- const ad1843_bitfield_t *lfield;
- const ad1843_bitfield_t *rfield;
-
-} ad1843_gain_t;
-
-static const ad1843_gain_t ad1843_gain_RECLEV
- = { 0, &ad1843_LIG, &ad1843_RIG };
-static const ad1843_gain_t ad1843_gain_LINE
- = { 1, &ad1843_LX1M, &ad1843_RX1M };
-static const ad1843_gain_t ad1843_gain_CD
- = { 1, &ad1843_LX2M, &ad1843_RX2M };
-static const ad1843_gain_t ad1843_gain_MIC
- = { 1, &ad1843_LMCM, &ad1843_RMCM };
-static const ad1843_gain_t ad1843_gain_PCM
- = { 1, &ad1843_LDA1G, &ad1843_RDA1G };
-
-/* read the current value of an AD1843 bitfield. */
-
-static int ad1843_read_bits(lithium_t *lith, const ad1843_bitfield_t *field)
-{
- int w = li_read_ad1843_reg(lith, field->reg);
- int val = w >> field->lo_bit & ((1 << field->nbits) - 1);
-
- DBGXV("ad1843_read_bits(lith=0x%p, field->{%d %d %d}) returns 0x%x\n",
- lith, field->reg, field->lo_bit, field->nbits, val);
-
- return val;
-}
-
-/*
- * write a new value to an AD1843 bitfield and return the old value.
- */
-
-static int ad1843_write_bits(lithium_t *lith,
- const ad1843_bitfield_t *field,
- int newval)
-{
- int w = li_read_ad1843_reg(lith, field->reg);
- int mask = ((1 << field->nbits) - 1) << field->lo_bit;
- int oldval = (w & mask) >> field->lo_bit;
- int newbits = (newval << field->lo_bit) & mask;
- w = (w & ~mask) | newbits;
- (void) li_write_ad1843_reg(lith, field->reg, w);
-
- DBGXV("ad1843_write_bits(lith=0x%p, field->{%d %d %d}, val=0x%x) "
- "returns 0x%x\n",
- lith, field->reg, field->lo_bit, field->nbits, newval,
- oldval);
-
- return oldval;
-}
-
-/*
- * ad1843_read_multi reads multiple bitfields from the same AD1843
- * register. It uses a single read cycle to do it. (Reading the
- * ad1843 requires 256 bit times at 12.288 MHz, or nearly 20
- * microseconds.)
- *
- * Called ike this.
- *
- * ad1843_read_multi(lith, nfields,
- * &ad1843_FIELD1, &val1,
- * &ad1843_FIELD2, &val2, ...);
- */
-
-static void ad1843_read_multi(lithium_t *lith, int argcount, ...)
-{
- va_list ap;
- const ad1843_bitfield_t *fp;
- int w = 0, mask, *value, reg = -1;
-
- va_start(ap, argcount);
- while (--argcount >= 0) {
- fp = va_arg(ap, const ad1843_bitfield_t *);
- value = va_arg(ap, int *);
- if (reg == -1) {
- reg = fp->reg;
- w = li_read_ad1843_reg(lith, reg);
- }
- ASSERT(reg == fp->reg);
- mask = (1 << fp->nbits) - 1;
- *value = w >> fp->lo_bit & mask;
- }
- va_end(ap);
-}
-
-/*
- * ad1843_write_multi stores multiple bitfields into the same AD1843
- * register. It uses one read and one write cycle to do it.
- *
- * Called like this.
- *
- * ad1843_write_multi(lith, nfields,
- * &ad1843_FIELD1, val1,
- * &ad1843_FIELF2, val2, ...);
- */
-
-static void ad1843_write_multi(lithium_t *lith, int argcount, ...)
-{
- va_list ap;
- int reg;
- const ad1843_bitfield_t *fp;
- int value;
- int w, m, mask, bits;
-
- mask = 0;
- bits = 0;
- reg = -1;
-
- va_start(ap, argcount);
- while (--argcount >= 0) {
- fp = va_arg(ap, const ad1843_bitfield_t *);
- value = va_arg(ap, int);
- if (reg == -1)
- reg = fp->reg;
- ASSERT(fp->reg == reg);
- m = ((1 << fp->nbits) - 1) << fp->lo_bit;
- mask |= m;
- bits |= (value << fp->lo_bit) & m;
- }
- va_end(ap);
- ASSERT(!(bits & ~mask));
- if (~mask & 0xFFFF)
- w = li_read_ad1843_reg(lith, reg);
- else
- w = 0;
- w = (w & ~mask) | bits;
- (void) li_write_ad1843_reg(lith, reg, w);
-}
-
-/*
- * ad1843_get_gain reads the specified register and extracts the gain value
- * using the supplied gain type. It returns the gain in OSS format.
- */
-
-static int ad1843_get_gain(lithium_t *lith, const ad1843_gain_t *gp)
-{
- int lg, rg;
- unsigned short mask = (1 << gp->lfield->nbits) - 1;
-
- ad1843_read_multi(lith, 2, gp->lfield, &lg, gp->rfield, &rg);
- if (gp->negative) {
- lg = mask - lg;
- rg = mask - rg;
- }
- lg = (lg * 100 + (mask >> 1)) / mask;
- rg = (rg * 100 + (mask >> 1)) / mask;
- return lg << 0 | rg << 8;
-}
-
-/*
- * Set an audio channel's gain. Converts from OSS format to AD1843's
- * format.
- *
- * Returns the new gain, which may be lower than the old gain.
- */
-
-static int ad1843_set_gain(lithium_t *lith,
- const ad1843_gain_t *gp,
- int newval)
-{
- unsigned short mask = (1 << gp->lfield->nbits) - 1;
-
- int lg = newval >> 0 & 0xFF;
- int rg = newval >> 8;
- if (lg < 0 || lg > 100 || rg < 0 || rg > 100)
- return -EINVAL;
- lg = (lg * mask + (mask >> 1)) / 100;
- rg = (rg * mask + (mask >> 1)) / 100;
- if (gp->negative) {
- lg = mask - lg;
- rg = mask - rg;
- }
- ad1843_write_multi(lith, 2, gp->lfield, lg, gp->rfield, rg);
- return ad1843_get_gain(lith, gp);
-}
-
-/* Returns the current recording source, in OSS format. */
-
-static int ad1843_get_recsrc(lithium_t *lith)
-{
- int ls = ad1843_read_bits(lith, &ad1843_LSS);
-
- switch (ls) {
- case 1:
- return SOUND_MASK_MIC;
- case 2:
- return SOUND_MASK_LINE;
- case 3:
- return SOUND_MASK_CD;
- case 6:
- return SOUND_MASK_PCM;
- default:
- ASSERT(0);
- return -1;
- }
-}
-
-/*
- * Enable/disable digital resample mode in the AD1843.
- *
- * The AD1843 requires that ADL, ADR, DA1 and DA2 be powered down
- * while switching modes. So we save DA1's state (DA2's state is not
- * interesting), power them down, switch into/out of resample mode,
- * power them up, and restore state.
- *
- * This will cause audible glitches if D/A or A/D is going on, so the
- * driver disallows that (in mixer_write_ioctl()).
- *
- * The open question is, is this worth doing? I'm leaving it in,
- * because it's written, but...
- */
-
-static void ad1843_set_resample_mode(lithium_t *lith, int onoff)
-{
- /* Save DA1 mute and gain (addr 9 is DA1 analog gain/attenuation) */
- int save_da1 = li_read_ad1843_reg(lith, 9);
-
- /* Power down A/D and D/A. */
- ad1843_write_multi(lith, 4,
- &ad1843_DA1EN, 0,
- &ad1843_DA2EN, 0,
- &ad1843_ADLEN, 0,
- &ad1843_ADREN, 0);
-
- /* Switch mode */
- ASSERT(onoff == 0 || onoff == 1);
- ad1843_write_bits(lith, &ad1843_DRSFLT, onoff);
-
- /* Power up A/D and D/A. */
- ad1843_write_multi(lith, 3,
- &ad1843_DA1EN, 1,
- &ad1843_ADLEN, 1,
- &ad1843_ADREN, 1);
-
- /* Restore DA1 mute and gain. */
- li_write_ad1843_reg(lith, 9, save_da1);
-}
-
-/*
- * Set recording source. Arg newsrc specifies an OSS channel mask.
- *
- * The complication is that when we switch into/out of loopback mode
- * (i.e., src = SOUND_MASK_PCM), we change the AD1843 into/out of
- * digital resampling mode.
- *
- * Returns newsrc on success, -errno on failure.
- */
-
-static int ad1843_set_recsrc(lithium_t *lith, int newsrc)
-{
- int bits;
- int oldbits;
-
- switch (newsrc) {
- case SOUND_MASK_PCM:
- bits = 6;
- break;
-
- case SOUND_MASK_MIC:
- bits = 1;
- break;
-
- case SOUND_MASK_LINE:
- bits = 2;
- break;
-
- case SOUND_MASK_CD:
- bits = 3;
- break;
-
- default:
- return -EINVAL;
- }
- oldbits = ad1843_read_bits(lith, &ad1843_LSS);
- if (newsrc == SOUND_MASK_PCM && oldbits != 6) {
- DBGP("enabling digital resample mode\n");
- ad1843_set_resample_mode(lith, 1);
- ad1843_write_multi(lith, 2,
- &ad1843_DAADL, 2,
- &ad1843_DAADR, 2);
- } else if (newsrc != SOUND_MASK_PCM && oldbits == 6) {
- DBGP("disabling digital resample mode\n");
- ad1843_set_resample_mode(lith, 0);
- ad1843_write_multi(lith, 2,
- &ad1843_DAADL, 0,
- &ad1843_DAADR, 0);
- }
- ad1843_write_multi(lith, 2, &ad1843_LSS, bits, &ad1843_RSS, bits);
- return newsrc;
-}
-
-/*
- * Return current output sources, in OSS format.
- */
-
-static int ad1843_get_outsrc(lithium_t *lith)
-{
- int pcm, line, mic, cd;
-
- pcm = ad1843_read_bits(lith, &ad1843_LDA1GM) ? 0 : SOUND_MASK_PCM;
- line = ad1843_read_bits(lith, &ad1843_LX1MM) ? 0 : SOUND_MASK_LINE;
- cd = ad1843_read_bits(lith, &ad1843_LX2MM) ? 0 : SOUND_MASK_CD;
- mic = ad1843_read_bits(lith, &ad1843_LMCMM) ? 0 : SOUND_MASK_MIC;
-
- return pcm | line | cd | mic;
-}
-
-/*
- * Set output sources. Arg is a mask of active sources in OSS format.
- *
- * Returns source mask on success, -errno on failure.
- */
-
-static int ad1843_set_outsrc(lithium_t *lith, int mask)
-{
- int pcm, line, mic, cd;
-
- if (mask & ~(SOUND_MASK_PCM | SOUND_MASK_LINE |
- SOUND_MASK_CD | SOUND_MASK_MIC))
- return -EINVAL;
- pcm = (mask & SOUND_MASK_PCM) ? 0 : 1;
- line = (mask & SOUND_MASK_LINE) ? 0 : 1;
- mic = (mask & SOUND_MASK_MIC) ? 0 : 1;
- cd = (mask & SOUND_MASK_CD) ? 0 : 1;
-
- ad1843_write_multi(lith, 2, &ad1843_LDA1GM, pcm, &ad1843_RDA1GM, pcm);
- ad1843_write_multi(lith, 2, &ad1843_LX1MM, line, &ad1843_RX1MM, line);
- ad1843_write_multi(lith, 2, &ad1843_LX2MM, cd, &ad1843_RX2MM, cd);
- ad1843_write_multi(lith, 2, &ad1843_LMCMM, mic, &ad1843_RMCMM, mic);
-
- return mask;
-}
-
-/* Setup ad1843 for D/A conversion. */
-
-static void ad1843_setup_dac(lithium_t *lith,
- int framerate,
- int fmt,
- int channels)
-{
- int ad_fmt = 0, ad_mode = 0;
-
- DBGEV("(lith=0x%p, framerate=%d, fmt=%d, channels=%d)\n",
- lith, framerate, fmt, channels);
-
- switch (fmt) {
- case AFMT_S8: ad_fmt = 1; break;
- case AFMT_U8: ad_fmt = 1; break;
- case AFMT_S16_LE: ad_fmt = 1; break;
- case AFMT_MU_LAW: ad_fmt = 2; break;
- case AFMT_A_LAW: ad_fmt = 3; break;
- default: ASSERT(0);
- }
-
- switch (channels) {
- case 2: ad_mode = 0; break;
- case 1: ad_mode = 1; break;
- default: ASSERT(0);
- }
-
- DBGPV("ad_mode = %d, ad_fmt = %d\n", ad_mode, ad_fmt);
- ASSERT(framerate >= 4000 && framerate <= 49000);
- ad1843_write_bits(lith, &ad1843_C1C, framerate);
- ad1843_write_multi(lith, 2,
- &ad1843_DA1SM, ad_mode, &ad1843_DA1F, ad_fmt);
-}
-
-static void ad1843_shutdown_dac(lithium_t *lith)
-{
- ad1843_write_bits(lith, &ad1843_DA1F, 1);
-}
-
-static void ad1843_setup_adc(lithium_t *lith, int framerate, int fmt, int channels)
-{
- int da_fmt = 0;
-
- DBGEV("(lith=0x%p, framerate=%d, fmt=%d, channels=%d)\n",
- lith, framerate, fmt, channels);
-
- switch (fmt) {
- case AFMT_S8: da_fmt = 1; break;
- case AFMT_U8: da_fmt = 1; break;
- case AFMT_S16_LE: da_fmt = 1; break;
- case AFMT_MU_LAW: da_fmt = 2; break;
- case AFMT_A_LAW: da_fmt = 3; break;
- default: ASSERT(0);
- }
-
- DBGPV("da_fmt = %d\n", da_fmt);
- ASSERT(framerate >= 4000 && framerate <= 49000);
- ad1843_write_bits(lith, &ad1843_C2C, framerate);
- ad1843_write_multi(lith, 2,
- &ad1843_ADLF, da_fmt, &ad1843_ADRF, da_fmt);
-}
-
-static void ad1843_shutdown_adc(lithium_t *lith)
-{
- /* nothing to do */
-}
-
-/*
- * Fully initialize the ad1843. As described in the AD1843 data
- * sheet, section "START-UP SEQUENCE". The numbered comments are
- * subsection headings from the data sheet. See the data sheet, pages
- * 52-54, for more info.
- *
- * return 0 on success, -errno on failure. */
-
-static int __init ad1843_init(lithium_t *lith)
-{
- unsigned long later;
- int err;
-
- err = li_init(lith);
- if (err)
- return err;
-
- if (ad1843_read_bits(lith, &ad1843_INIT) != 0) {
- printk(KERN_ERR "vwsnd sound: AD1843 won't initialize\n");
- return -EIO;
- }
-
- ad1843_write_bits(lith, &ad1843_SCF, 1);
-
- /* 4. Put the conversion resources into standby. */
-
- ad1843_write_bits(lith, &ad1843_PDNI, 0);
- later = jiffies + HZ / 2; /* roughly half a second */
- DBGDO(shut_up++);
- while (ad1843_read_bits(lith, &ad1843_PDNO)) {
- if (time_after(jiffies, later)) {
- printk(KERN_ERR
- "vwsnd audio: AD1843 won't power up\n");
- return -EIO;
- }
- schedule();
- }
- DBGDO(shut_up--);
-
- /* 5. Power up the clock generators and enable clock output pins. */
-
- ad1843_write_multi(lith, 2, &ad1843_C1EN, 1, &ad1843_C2EN, 1);
-
- /* 6. Configure conversion resources while they are in standby. */
-
- /* DAC1 uses clock 1 as source, ADC uses clock 2. Always. */
-
- ad1843_write_multi(lith, 3,
- &ad1843_DA1C, 1,
- &ad1843_ADLC, 2,
- &ad1843_ADRC, 2);
-
- /* 7. Enable conversion resources. */
-
- ad1843_write_bits(lith, &ad1843_ADTLK, 1);
- ad1843_write_multi(lith, 5,
- &ad1843_ANAEN, 1,
- &ad1843_AAMEN, 1,
- &ad1843_DA1EN, 1,
- &ad1843_ADLEN, 1,
- &ad1843_ADREN, 1);
-
- /* 8. Configure conversion resources while they are enabled. */
-
- ad1843_write_bits(lith, &ad1843_DA1C, 1);
-
- /* Unmute all channels. */
-
- ad1843_set_outsrc(lith,
- (SOUND_MASK_PCM | SOUND_MASK_LINE |
- SOUND_MASK_MIC | SOUND_MASK_CD));
- ad1843_write_multi(lith, 2, &ad1843_LDA1AM, 0, &ad1843_RDA1AM, 0);
-
- /* Set default recording source to Line In and set
- * mic gain to +20 dB.
- */
-
- ad1843_set_recsrc(lith, SOUND_MASK_LINE);
- ad1843_write_multi(lith, 2, &ad1843_LMGE, 1, &ad1843_RMGE, 1);
-
- /* Set Speaker Out level to +/- 4V and unmute it. */
-
- ad1843_write_multi(lith, 2, &ad1843_HPOS, 1, &ad1843_HPOM, 0);
-
- return 0;
-}
-
-/*****************************************************************************/
-/* PCM I/O */
-
-#define READ_INTR_MASK (LI_INTR_COMM1_TRIG | LI_INTR_COMM1_OVERFLOW)
-#define WRITE_INTR_MASK (LI_INTR_COMM2_TRIG | LI_INTR_COMM2_UNDERFLOW)
-
-typedef enum vwsnd_port_swstate { /* software state */
- SW_OFF,
- SW_INITIAL,
- SW_RUN,
- SW_DRAIN,
-} vwsnd_port_swstate_t;
-
-typedef enum vwsnd_port_hwstate { /* hardware state */
- HW_STOPPED,
- HW_RUNNING,
-} vwsnd_port_hwstate_t;
-
-/*
- * These flags are read by ISR, but only written at baseline.
- */
-
-typedef enum vwsnd_port_flags {
- DISABLED = 1 << 0,
- ERFLOWN = 1 << 1, /* overflown or underflown */
- HW_BUSY = 1 << 2,
-} vwsnd_port_flags_t;
-
-/*
- * vwsnd_port is the per-port data structure. Each device has two
- * ports, one for input and one for output.
- *
- * Locking:
- *
- * port->lock protects: hwstate, flags, swb_[iu]_avail.
- *
- * devc->io_mutex protects: swstate, sw_*, swb_[iu]_idx.
- *
- * everything else is only written by open/release or
- * pcm_{setup,shutdown}(), which are serialized by a
- * combination of devc->open_mutex and devc->io_mutex.
- */
-
-typedef struct vwsnd_port {
-
- spinlock_t lock;
- wait_queue_head_t queue;
- vwsnd_port_swstate_t swstate;
- vwsnd_port_hwstate_t hwstate;
- vwsnd_port_flags_t flags;
-
- int sw_channels;
- int sw_samplefmt;
- int sw_framerate;
- int sample_size;
- int frame_size;
- unsigned int zero_word; /* zero for the sample format */
-
- int sw_fragshift;
- int sw_fragcount;
- int sw_subdivshift;
-
- unsigned int hw_fragshift;
- unsigned int hw_fragsize;
- unsigned int hw_fragcount;
-
- int hwbuf_size;
- unsigned long hwbuf_paddr;
- unsigned long hwbuf_vaddr;
- void * hwbuf; /* hwbuf == hwbuf_vaddr */
- int hwbuf_max; /* max bytes to preload */
-
- void * swbuf;
- unsigned int swbuf_size; /* size in bytes */
- unsigned int swb_u_idx; /* index of next user byte */
- unsigned int swb_i_idx; /* index of next intr byte */
- unsigned int swb_u_avail; /* # bytes avail to user */
- unsigned int swb_i_avail; /* # bytes avail to intr */
-
- dma_chan_t chan;
-
- /* Accounting */
-
- int byte_count;
- int frag_count;
- int MSC_offset;
-
-} vwsnd_port_t;
-
-/* vwsnd_dev is the per-device data structure. */
-
-typedef struct vwsnd_dev {
- struct vwsnd_dev *next_dev;
- int audio_minor; /* minor number of audio device */
- int mixer_minor; /* minor number of mixer device */
-
- struct mutex open_mutex;
- struct mutex io_mutex;
- struct mutex mix_mutex;
- fmode_t open_mode;
- wait_queue_head_t open_wait;
-
- lithium_t lith;
-
- vwsnd_port_t rport;
- vwsnd_port_t wport;
-} vwsnd_dev_t;
-
-static vwsnd_dev_t *vwsnd_dev_list; /* linked list of all devices */
-
-static atomic_t vwsnd_use_count = ATOMIC_INIT(0);
-
-# define INC_USE_COUNT (atomic_inc(&vwsnd_use_count))
-# define DEC_USE_COUNT (atomic_dec(&vwsnd_use_count))
-# define IN_USE (atomic_read(&vwsnd_use_count) != 0)
-
-/*
- * Lithium can only DMA multiples of 32 bytes. Its DMA buffer may
- * be up to 8 Kb. This driver always uses 8 Kb.
- *
- * Memory bug workaround -- I'm not sure what's going on here, but
- * somehow pcm_copy_out() was triggering segv's going on to the next
- * page of the hw buffer. So, I make the hw buffer one size bigger
- * than we actually use. That way, the following page is allocated
- * and mapped, and no error. I suspect that something is broken
- * in Cobalt, but haven't really investigated. HBO is the actual
- * size of the buffer, and HWBUF_ORDER is what we allocate.
- */
-
-#define HWBUF_SHIFT 13
-#define HWBUF_SIZE (1 << HWBUF_SHIFT)
-# define HBO (HWBUF_SHIFT > PAGE_SHIFT ? HWBUF_SHIFT - PAGE_SHIFT : 0)
-# define HWBUF_ORDER (HBO + 1) /* next size bigger */
-#define MIN_SPEED 4000
-#define MAX_SPEED 49000
-
-#define MIN_FRAGSHIFT (DMACHUNK_SHIFT + 1)
-#define MAX_FRAGSHIFT (PAGE_SHIFT)
-#define MIN_FRAGSIZE (1 << MIN_FRAGSHIFT)
-#define MAX_FRAGSIZE (1 << MAX_FRAGSHIFT)
-#define MIN_FRAGCOUNT(fragsize) 3
-#define MAX_FRAGCOUNT(fragsize) (32 * PAGE_SIZE / (fragsize))
-#define DEFAULT_FRAGSHIFT 12
-#define DEFAULT_FRAGCOUNT 16
-#define DEFAULT_SUBDIVSHIFT 0
-
-/*
- * The software buffer (swbuf) is a ring buffer shared between user
- * level and interrupt level. Each level owns some of the bytes in
- * the buffer, and may give bytes away by calling swb_inc_{u,i}().
- * User level calls _u for user, and interrupt level calls _i for
- * interrupt.
- *
- * port->swb_{u,i}_avail is the number of bytes available to that level.
- *
- * port->swb_{u,i}_idx is the index of the first available byte in the
- * buffer.
- *
- * Each level calls swb_inc_{u,i}() to atomically increment its index,
- * recalculate the number of bytes available for both sides, and
- * return the number of bytes available. Since each side can only
- * give away bytes, the other side can only increase the number of
- * bytes available to this side. Each side updates its own index
- * variable, swb_{u,i}_idx, so no lock is needed to read it.
- *
- * To query the number of bytes available, call swb_inc_{u,i} with an
- * increment of zero.
- */
-
-static __inline__ unsigned int __swb_inc_u(vwsnd_port_t *port, int inc)
-{
- if (inc) {
- port->swb_u_idx += inc;
- port->swb_u_idx %= port->swbuf_size;
- port->swb_u_avail -= inc;
- port->swb_i_avail += inc;
- }
- return port->swb_u_avail;
-}
-
-static __inline__ unsigned int swb_inc_u(vwsnd_port_t *port, int inc)
-{
- unsigned long flags;
- unsigned int ret;
-
- spin_lock_irqsave(&port->lock, flags);
- {
- ret = __swb_inc_u(port, inc);
- }
- spin_unlock_irqrestore(&port->lock, flags);
- return ret;
-}
-
-static __inline__ unsigned int __swb_inc_i(vwsnd_port_t *port, int inc)
-{
- if (inc) {
- port->swb_i_idx += inc;
- port->swb_i_idx %= port->swbuf_size;
- port->swb_i_avail -= inc;
- port->swb_u_avail += inc;
- }
- return port->swb_i_avail;
-}
-
-static __inline__ unsigned int swb_inc_i(vwsnd_port_t *port, int inc)
-{
- unsigned long flags;
- unsigned int ret;
-
- spin_lock_irqsave(&port->lock, flags);
- {
- ret = __swb_inc_i(port, inc);
- }
- spin_unlock_irqrestore(&port->lock, flags);
- return ret;
-}
-
-/*
- * pcm_setup - this routine initializes all port state after
- * mode-setting ioctls have been done, but before the first I/O is
- * done.
- *
- * Locking: called with devc->io_mutex held.
- *
- * Returns 0 on success, -errno on failure.
- */
-
-static int pcm_setup(vwsnd_dev_t *devc,
- vwsnd_port_t *rport,
- vwsnd_port_t *wport)
-{
- vwsnd_port_t *aport = rport ? rport : wport;
- int sample_size;
- unsigned int zero_word;
-
- DBGEV("(devc=0x%p, rport=0x%p, wport=0x%p)\n", devc, rport, wport);
-
- ASSERT(aport != NULL);
- if (aport->swbuf != NULL)
- return 0;
- switch (aport->sw_samplefmt) {
- case AFMT_MU_LAW:
- sample_size = 1;
- zero_word = 0xFFFFFFFF ^ 0x80808080;
- break;
-
- case AFMT_A_LAW:
- sample_size = 1;
- zero_word = 0xD5D5D5D5 ^ 0x80808080;
- break;
-
- case AFMT_U8:
- sample_size = 1;
- zero_word = 0x80808080;
- break;
-
- case AFMT_S8:
- sample_size = 1;
- zero_word = 0x00000000;
- break;
-
- case AFMT_S16_LE:
- sample_size = 2;
- zero_word = 0x00000000;
- break;
-
- default:
- sample_size = 0; /* prevent compiler warning */
- zero_word = 0;
- ASSERT(0);
- }
- aport->sample_size = sample_size;
- aport->zero_word = zero_word;
- aport->frame_size = aport->sw_channels * aport->sample_size;
- aport->hw_fragshift = aport->sw_fragshift - aport->sw_subdivshift;
- aport->hw_fragsize = 1 << aport->hw_fragshift;
- aport->hw_fragcount = aport->sw_fragcount << aport->sw_subdivshift;
- ASSERT(aport->hw_fragsize >= MIN_FRAGSIZE);
- ASSERT(aport->hw_fragsize <= MAX_FRAGSIZE);
- ASSERT(aport->hw_fragcount >= MIN_FRAGCOUNT(aport->hw_fragsize));
- ASSERT(aport->hw_fragcount <= MAX_FRAGCOUNT(aport->hw_fragsize));
- if (rport) {
- int hwfrags, swfrags;
- rport->hwbuf_max = aport->hwbuf_size - DMACHUNK_SIZE;
- hwfrags = rport->hwbuf_max >> aport->hw_fragshift;
- swfrags = aport->hw_fragcount - hwfrags;
- if (swfrags < 2)
- swfrags = 2;
- rport->swbuf_size = swfrags * aport->hw_fragsize;
- DBGPV("hwfrags = %d, swfrags = %d\n", hwfrags, swfrags);
- DBGPV("read hwbuf_max = %d, swbuf_size = %d\n",
- rport->hwbuf_max, rport->swbuf_size);
- }
- if (wport) {
- int hwfrags, swfrags;
- int total_bytes = aport->hw_fragcount * aport->hw_fragsize;
- wport->hwbuf_max = aport->hwbuf_size - DMACHUNK_SIZE;
- if (wport->hwbuf_max > total_bytes)
- wport->hwbuf_max = total_bytes;
- hwfrags = wport->hwbuf_max >> aport->hw_fragshift;
- DBGPV("hwfrags = %d\n", hwfrags);
- swfrags = aport->hw_fragcount - hwfrags;
- if (swfrags < 2)
- swfrags = 2;
- wport->swbuf_size = swfrags * aport->hw_fragsize;
- DBGPV("hwfrags = %d, swfrags = %d\n", hwfrags, swfrags);
- DBGPV("write hwbuf_max = %d, swbuf_size = %d\n",
- wport->hwbuf_max, wport->swbuf_size);
- }
-
- aport->swb_u_idx = 0;
- aport->swb_i_idx = 0;
- aport->byte_count = 0;
-
- /*
- * Is this a Cobalt bug? We need to make this buffer extend
- * one page further than we actually use -- somehow memcpy
- * causes an exceptoin otherwise. I suspect there's a bug in
- * Cobalt (or somewhere) where it's generating a fault on a
- * speculative load or something. Obviously, I haven't taken
- * the time to track it down.
- */
-
- aport->swbuf = vmalloc(aport->swbuf_size + PAGE_SIZE);
- if (!aport->swbuf)
- return -ENOMEM;
- if (rport && wport) {
- ASSERT(aport == rport);
- ASSERT(wport->swbuf == NULL);
- /* One extra page - see comment above. */
- wport->swbuf = vmalloc(aport->swbuf_size + PAGE_SIZE);
- if (!wport->swbuf) {
- vfree(aport->swbuf);
- aport->swbuf = NULL;
- return -ENOMEM;
- }
- wport->sample_size = rport->sample_size;
- wport->zero_word = rport->zero_word;
- wport->frame_size = rport->frame_size;
- wport->hw_fragshift = rport->hw_fragshift;
- wport->hw_fragsize = rport->hw_fragsize;
- wport->hw_fragcount = rport->hw_fragcount;
- wport->swbuf_size = rport->swbuf_size;
- wport->hwbuf_max = rport->hwbuf_max;
- wport->swb_u_idx = rport->swb_u_idx;
- wport->swb_i_idx = rport->swb_i_idx;
- wport->byte_count = rport->byte_count;
- }
- if (rport) {
- rport->swb_u_avail = 0;
- rport->swb_i_avail = rport->swbuf_size;
- rport->swstate = SW_RUN;
- li_setup_dma(&rport->chan,
- &li_comm1,
- &devc->lith,
- rport->hwbuf_paddr,
- HWBUF_SHIFT,
- rport->hw_fragshift,
- rport->sw_channels,
- rport->sample_size);
- ad1843_setup_adc(&devc->lith,
- rport->sw_framerate,
- rport->sw_samplefmt,
- rport->sw_channels);
- li_enable_interrupts(&devc->lith, READ_INTR_MASK);
- if (!(rport->flags & DISABLED)) {
- ustmsc_t ustmsc;
- rport->hwstate = HW_RUNNING;
- li_activate_dma(&rport->chan);
- li_read_USTMSC(&rport->chan, &ustmsc);
- rport->MSC_offset = ustmsc.msc;
- }
- }
- if (wport) {
- if (wport->hwbuf_max > wport->swbuf_size)
- wport->hwbuf_max = wport->swbuf_size;
- wport->flags &= ~ERFLOWN;
- wport->swb_u_avail = wport->swbuf_size;
- wport->swb_i_avail = 0;
- wport->swstate = SW_RUN;
- li_setup_dma(&wport->chan,
- &li_comm2,
- &devc->lith,
- wport->hwbuf_paddr,
- HWBUF_SHIFT,
- wport->hw_fragshift,
- wport->sw_channels,
- wport->sample_size);
- ad1843_setup_dac(&devc->lith,
- wport->sw_framerate,
- wport->sw_samplefmt,
- wport->sw_channels);
- li_enable_interrupts(&devc->lith, WRITE_INTR_MASK);
- }
- DBGRV();
- return 0;
-}
-
-/*
- * pcm_shutdown_port - shut down one port (direction) for PCM I/O.
- * Only called from pcm_shutdown.
- */
-
-static void pcm_shutdown_port(vwsnd_dev_t *devc,
- vwsnd_port_t *aport,
- unsigned int mask)
-{
- unsigned long flags;
- vwsnd_port_hwstate_t hwstate;
- DECLARE_WAITQUEUE(wait, current);
-
- aport->swstate = SW_INITIAL;
- add_wait_queue(&aport->queue, &wait);
- while (1) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- spin_lock_irqsave(&aport->lock, flags);
- {
- hwstate = aport->hwstate;
- }
- spin_unlock_irqrestore(&aport->lock, flags);
- if (hwstate == HW_STOPPED)
- break;
- schedule();
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&aport->queue, &wait);
- li_disable_interrupts(&devc->lith, mask);
- if (aport == &devc->rport)
- ad1843_shutdown_adc(&devc->lith);
- else /* aport == &devc->wport) */
- ad1843_shutdown_dac(&devc->lith);
- li_shutdown_dma(&aport->chan);
- vfree(aport->swbuf);
- aport->swbuf = NULL;
- aport->byte_count = 0;
-}
-
-/*
- * pcm_shutdown undoes what pcm_setup did.
- * Also sets the ports' swstate to newstate.
- */
-
-static void pcm_shutdown(vwsnd_dev_t *devc,
- vwsnd_port_t *rport,
- vwsnd_port_t *wport)
-{
- DBGEV("(devc=0x%p, rport=0x%p, wport=0x%p)\n", devc, rport, wport);
-
- if (rport && rport->swbuf) {
- DBGPV("shutting down rport\n");
- pcm_shutdown_port(devc, rport, READ_INTR_MASK);
- }
- if (wport && wport->swbuf) {
- DBGPV("shutting down wport\n");
- pcm_shutdown_port(devc, wport, WRITE_INTR_MASK);
- }
- DBGRV();
-}
-
-static void pcm_copy_in(vwsnd_port_t *rport, int swidx, int hwidx, int nb)
-{
- char *src = rport->hwbuf + hwidx;
- char *dst = rport->swbuf + swidx;
- int fmt = rport->sw_samplefmt;
-
- DBGPV("swidx = %d, hwidx = %d\n", swidx, hwidx);
- ASSERT(rport->hwbuf != NULL);
- ASSERT(rport->swbuf != NULL);
- ASSERT(nb > 0 && (nb % 32) == 0);
- ASSERT(swidx % 32 == 0 && hwidx % 32 == 0);
- ASSERT(swidx >= 0 && swidx + nb <= rport->swbuf_size);
- ASSERT(hwidx >= 0 && hwidx + nb <= rport->hwbuf_size);
-
- if (fmt == AFMT_MU_LAW || fmt == AFMT_A_LAW || fmt == AFMT_S8) {
-
- /* See Sample Format Notes above. */
-
- char *end = src + nb;
- while (src < end)
- *dst++ = *src++ ^ 0x80;
- } else
- memcpy(dst, src, nb);
-}
-
-static void pcm_copy_out(vwsnd_port_t *wport, int swidx, int hwidx, int nb)
-{
- char *src = wport->swbuf + swidx;
- char *dst = wport->hwbuf + hwidx;
- int fmt = wport->sw_samplefmt;
-
- ASSERT(nb > 0 && (nb % 32) == 0);
- ASSERT(wport->hwbuf != NULL);
- ASSERT(wport->swbuf != NULL);
- ASSERT(swidx % 32 == 0 && hwidx % 32 == 0);
- ASSERT(swidx >= 0 && swidx + nb <= wport->swbuf_size);
- ASSERT(hwidx >= 0 && hwidx + nb <= wport->hwbuf_size);
- if (fmt == AFMT_MU_LAW || fmt == AFMT_A_LAW || fmt == AFMT_S8) {
-
- /* See Sample Format Notes above. */
-
- char *end = src + nb;
- while (src < end)
- *dst++ = *src++ ^ 0x80;
- } else
- memcpy(dst, src, nb);
-}
-
-/*
- * pcm_output() is called both from baselevel and from interrupt level.
- * This is where audio frames are copied into the hardware-accessible
- * ring buffer.
- *
- * Locking note: The part of this routine that figures out what to do
- * holds wport->lock. The longer part releases wport->lock, but sets
- * wport->flags & HW_BUSY. Afterward, it reacquires wport->lock, and
- * checks for more work to do.
- *
- * If another thread calls pcm_output() while HW_BUSY is set, it
- * returns immediately, knowing that the thread that set HW_BUSY will
- * look for more work to do before returning.
- *
- * This has the advantage that port->lock is held for several short
- * periods instead of one long period. Also, when pcm_output is
- * called from base level, it reenables interrupts.
- */
-
-static void pcm_output(vwsnd_dev_t *devc, int erflown, int nb)
-{
- vwsnd_port_t *wport = &devc->wport;
- const int hwmax = wport->hwbuf_max;
- const int hwsize = wport->hwbuf_size;
- const int swsize = wport->swbuf_size;
- const int fragsize = wport->hw_fragsize;
- unsigned long iflags;
-
- DBGEV("(devc=0x%p, erflown=%d, nb=%d)\n", devc, erflown, nb);
- spin_lock_irqsave(&wport->lock, iflags);
- if (erflown)
- wport->flags |= ERFLOWN;
- (void) __swb_inc_u(wport, nb);
- if (wport->flags & HW_BUSY) {
- spin_unlock_irqrestore(&wport->lock, iflags);
- DBGPV("returning: HW BUSY\n");
- return;
- }
- if (wport->flags & DISABLED) {
- spin_unlock_irqrestore(&wport->lock, iflags);
- DBGPV("returning: DISABLED\n");
- return;
- }
- wport->flags |= HW_BUSY;
- while (1) {
- int swptr, hwptr, hw_avail, sw_avail, swidx;
- vwsnd_port_hwstate_t hwstate = wport->hwstate;
- vwsnd_port_swstate_t swstate = wport->swstate;
- int hw_unavail;
- ustmsc_t ustmsc;
-
- hwptr = li_read_hwptr(&wport->chan);
- swptr = li_read_swptr(&wport->chan);
- hw_unavail = (swptr - hwptr + hwsize) % hwsize;
- hw_avail = (hwmax - hw_unavail) & -fragsize;
- sw_avail = wport->swb_i_avail & -fragsize;
- if (sw_avail && swstate == SW_RUN) {
- if (wport->flags & ERFLOWN) {
- wport->flags &= ~ERFLOWN;
- }
- } else if (swstate == SW_INITIAL ||
- swstate == SW_OFF ||
- (swstate == SW_DRAIN &&
- !sw_avail &&
- (wport->flags & ERFLOWN))) {
- DBGP("stopping. hwstate = %d\n", hwstate);
- if (hwstate != HW_STOPPED) {
- li_deactivate_dma(&wport->chan);
- wport->hwstate = HW_STOPPED;
- }
- wake_up(&wport->queue);
- break;
- }
- if (!sw_avail || !hw_avail)
- break;
- spin_unlock_irqrestore(&wport->lock, iflags);
-
- /*
- * We gave up the port lock, but we have the HW_BUSY flag.
- * Proceed without accessing any nonlocal state.
- * Do not exit the loop -- must check for more work.
- */
-
- swidx = wport->swb_i_idx;
- nb = hw_avail;
- if (nb > sw_avail)
- nb = sw_avail;
- if (nb > hwsize - swptr)
- nb = hwsize - swptr; /* don't overflow hwbuf */
- if (nb > swsize - swidx)
- nb = swsize - swidx; /* don't overflow swbuf */
- ASSERT(nb > 0);
- if (nb % fragsize) {
- DBGP("nb = %d, fragsize = %d\n", nb, fragsize);
- DBGP("hw_avail = %d\n", hw_avail);
- DBGP("sw_avail = %d\n", sw_avail);
- DBGP("hwsize = %d, swptr = %d\n", hwsize, swptr);
- DBGP("swsize = %d, swidx = %d\n", swsize, swidx);
- }
- ASSERT(!(nb % fragsize));
- DBGPV("copying swb[%d..%d] to hwb[%d..%d]\n",
- swidx, swidx + nb, swptr, swptr + nb);
- pcm_copy_out(wport, swidx, swptr, nb);
- li_write_swptr(&wport->chan, (swptr + nb) % hwsize);
- spin_lock_irqsave(&wport->lock, iflags);
- if (hwstate == HW_STOPPED) {
- DBGPV("starting\n");
- li_activate_dma(&wport->chan);
- wport->hwstate = HW_RUNNING;
- li_read_USTMSC(&wport->chan, &ustmsc);
- ASSERT(wport->byte_count % wport->frame_size == 0);
- wport->MSC_offset = ustmsc.msc - wport->byte_count / wport->frame_size;
- }
- __swb_inc_i(wport, nb);
- wport->byte_count += nb;
- wport->frag_count += nb / fragsize;
- ASSERT(nb % fragsize == 0);
- wake_up(&wport->queue);
- }
- wport->flags &= ~HW_BUSY;
- spin_unlock_irqrestore(&wport->lock, iflags);
- DBGRV();
-}
-
-/*
- * pcm_input() is called both from baselevel and from interrupt level.
- * This is where audio frames are copied out of the hardware-accessible
- * ring buffer.
- *
- * Locking note: The part of this routine that figures out what to do
- * holds rport->lock. The longer part releases rport->lock, but sets
- * rport->flags & HW_BUSY. Afterward, it reacquires rport->lock, and
- * checks for more work to do.
- *
- * If another thread calls pcm_input() while HW_BUSY is set, it
- * returns immediately, knowing that the thread that set HW_BUSY will
- * look for more work to do before returning.
- *
- * This has the advantage that port->lock is held for several short
- * periods instead of one long period. Also, when pcm_input is
- * called from base level, it reenables interrupts.
- */
-
-static void pcm_input(vwsnd_dev_t *devc, int erflown, int nb)
-{
- vwsnd_port_t *rport = &devc->rport;
- const int hwmax = rport->hwbuf_max;
- const int hwsize = rport->hwbuf_size;
- const int swsize = rport->swbuf_size;
- const int fragsize = rport->hw_fragsize;
- unsigned long iflags;
-
- DBGEV("(devc=0x%p, erflown=%d, nb=%d)\n", devc, erflown, nb);
-
- spin_lock_irqsave(&rport->lock, iflags);
- if (erflown)
- rport->flags |= ERFLOWN;
- (void) __swb_inc_u(rport, nb);
- if (rport->flags & HW_BUSY || !rport->swbuf) {
- spin_unlock_irqrestore(&rport->lock, iflags);
- DBGPV("returning: HW BUSY or !swbuf\n");
- return;
- }
- if (rport->flags & DISABLED) {
- spin_unlock_irqrestore(&rport->lock, iflags);
- DBGPV("returning: DISABLED\n");
- return;
- }
- rport->flags |= HW_BUSY;
- while (1) {
- int swptr, hwptr, hw_avail, sw_avail, swidx;
- vwsnd_port_hwstate_t hwstate = rport->hwstate;
- vwsnd_port_swstate_t swstate = rport->swstate;
-
- hwptr = li_read_hwptr(&rport->chan);
- swptr = li_read_swptr(&rport->chan);
- hw_avail = (hwptr - swptr + hwsize) % hwsize & -fragsize;
- if (hw_avail > hwmax)
- hw_avail = hwmax;
- sw_avail = rport->swb_i_avail & -fragsize;
- if (swstate != SW_RUN) {
- DBGP("stopping. hwstate = %d\n", hwstate);
- if (hwstate != HW_STOPPED) {
- li_deactivate_dma(&rport->chan);
- rport->hwstate = HW_STOPPED;
- }
- wake_up(&rport->queue);
- break;
- }
- if (!sw_avail || !hw_avail)
- break;
- spin_unlock_irqrestore(&rport->lock, iflags);
-
- /*
- * We gave up the port lock, but we have the HW_BUSY flag.
- * Proceed without accessing any nonlocal state.
- * Do not exit the loop -- must check for more work.
- */
-
- swidx = rport->swb_i_idx;
- nb = hw_avail;
- if (nb > sw_avail)
- nb = sw_avail;
- if (nb > hwsize - swptr)
- nb = hwsize - swptr; /* don't overflow hwbuf */
- if (nb > swsize - swidx)
- nb = swsize - swidx; /* don't overflow swbuf */
- ASSERT(nb > 0);
- if (nb % fragsize) {
- DBGP("nb = %d, fragsize = %d\n", nb, fragsize);
- DBGP("hw_avail = %d\n", hw_avail);
- DBGP("sw_avail = %d\n", sw_avail);
- DBGP("hwsize = %d, swptr = %d\n", hwsize, swptr);
- DBGP("swsize = %d, swidx = %d\n", swsize, swidx);
- }
- ASSERT(!(nb % fragsize));
- DBGPV("copying hwb[%d..%d] to swb[%d..%d]\n",
- swptr, swptr + nb, swidx, swidx + nb);
- pcm_copy_in(rport, swidx, swptr, nb);
- li_write_swptr(&rport->chan, (swptr + nb) % hwsize);
- spin_lock_irqsave(&rport->lock, iflags);
- __swb_inc_i(rport, nb);
- rport->byte_count += nb;
- rport->frag_count += nb / fragsize;
- ASSERT(nb % fragsize == 0);
- wake_up(&rport->queue);
- }
- rport->flags &= ~HW_BUSY;
- spin_unlock_irqrestore(&rport->lock, iflags);
- DBGRV();
-}
-
-/*
- * pcm_flush_frag() writes zero samples to fill the current fragment,
- * then flushes it to the hardware.
- *
- * It is only meaningful to flush output, not input.
- */
-
-static void pcm_flush_frag(vwsnd_dev_t *devc)
-{
- vwsnd_port_t *wport = &devc->wport;
-
- DBGPV("swstate = %d\n", wport->swstate);
- if (wport->swstate == SW_RUN) {
- int idx = wport->swb_u_idx;
- int end = (idx + wport->hw_fragsize - 1)
- >> wport->hw_fragshift
- << wport->hw_fragshift;
- int nb = end - idx;
- DBGPV("clearing %d bytes\n", nb);
- if (nb)
- memset(wport->swbuf + idx,
- (char) wport->zero_word,
- nb);
- wport->swstate = SW_DRAIN;
- pcm_output(devc, 0, nb);
- }
- DBGRV();
-}
-
-/*
- * Wait for output to drain. This sleeps uninterruptibly because
- * there is nothing intelligent we can do if interrupted. This
- * means the process will be delayed in responding to the signal.
- */
-
-static void pcm_write_sync(vwsnd_dev_t *devc)
-{
- vwsnd_port_t *wport = &devc->wport;
- DECLARE_WAITQUEUE(wait, current);
- unsigned long flags;
- vwsnd_port_hwstate_t hwstate;
-
- DBGEV("(devc=0x%p)\n", devc);
- add_wait_queue(&wport->queue, &wait);
- while (1) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- spin_lock_irqsave(&wport->lock, flags);
- {
- hwstate = wport->hwstate;
- }
- spin_unlock_irqrestore(&wport->lock, flags);
- if (hwstate == HW_STOPPED)
- break;
- schedule();
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&wport->queue, &wait);
- DBGPV("swstate = %d, hwstate = %d\n", wport->swstate, wport->hwstate);
- DBGRV();
-}
-
-/*****************************************************************************/
-/* audio driver */
-
-/*
- * seek on an audio device always fails.
- */
-
-static void vwsnd_audio_read_intr(vwsnd_dev_t *devc, unsigned int status)
-{
- int overflown = status & LI_INTR_COMM1_OVERFLOW;
-
- if (status & READ_INTR_MASK)
- pcm_input(devc, overflown, 0);
-}
-
-static void vwsnd_audio_write_intr(vwsnd_dev_t *devc, unsigned int status)
-{
- int underflown = status & LI_INTR_COMM2_UNDERFLOW;
-
- if (status & WRITE_INTR_MASK)
- pcm_output(devc, underflown, 0);
-}
-
-static irqreturn_t vwsnd_audio_intr(int irq, void *dev_id)
-{
- vwsnd_dev_t *devc = dev_id;
- unsigned int status;
-
- DBGEV("(irq=%d, dev_id=0x%p)\n", irq, dev_id);
-
- status = li_get_clear_intr_status(&devc->lith);
- vwsnd_audio_read_intr(devc, status);
- vwsnd_audio_write_intr(devc, status);
- return IRQ_HANDLED;
-}
-
-static ssize_t vwsnd_audio_do_read(struct file *file,
- char *buffer,
- size_t count,
- loff_t *ppos)
-{
- vwsnd_dev_t *devc = file->private_data;
- vwsnd_port_t *rport = ((file->f_mode & FMODE_READ) ?
- &devc->rport : NULL);
- int ret, nb;
-
- DBGEV("(file=0x%p, buffer=0x%p, count=%d, ppos=0x%p)\n",
- file, buffer, count, ppos);
-
- if (!rport)
- return -EINVAL;
-
- if (rport->swbuf == NULL) {
- vwsnd_port_t *wport = (file->f_mode & FMODE_WRITE) ?
- &devc->wport : NULL;
- ret = pcm_setup(devc, rport, wport);
- if (ret < 0)
- return ret;
- }
-
- if (!access_ok(VERIFY_READ, buffer, count))
- return -EFAULT;
- ret = 0;
- while (count) {
- DECLARE_WAITQUEUE(wait, current);
- add_wait_queue(&rport->queue, &wait);
- while ((nb = swb_inc_u(rport, 0)) == 0) {
- DBGPV("blocking\n");
- set_current_state(TASK_INTERRUPTIBLE);
- if (rport->flags & DISABLED ||
- file->f_flags & O_NONBLOCK) {
- current->state = TASK_RUNNING;
- remove_wait_queue(&rport->queue, &wait);
- return ret ? ret : -EAGAIN;
- }
- schedule();
- if (signal_pending(current)) {
- current->state = TASK_RUNNING;
- remove_wait_queue(&rport->queue, &wait);
- return ret ? ret : -ERESTARTSYS;
- }
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&rport->queue, &wait);
- pcm_input(devc, 0, 0);
- /* nb bytes are available in userbuf. */
- if (nb > count)
- nb = count;
- DBGPV("nb = %d\n", nb);
- if (copy_to_user(buffer, rport->swbuf + rport->swb_u_idx, nb))
- return -EFAULT;
- (void) swb_inc_u(rport, nb);
- buffer += nb;
- count -= nb;
- ret += nb;
- }
- DBGPV("returning %d\n", ret);
- return ret;
-}
-
-static ssize_t vwsnd_audio_read(struct file *file,
- char *buffer,
- size_t count,
- loff_t *ppos)
-{
- vwsnd_dev_t *devc = file->private_data;
- ssize_t ret;
-
- mutex_lock(&devc->io_mutex);
- ret = vwsnd_audio_do_read(file, buffer, count, ppos);
- mutex_unlock(&devc->io_mutex);
- return ret;
-}
-
-static ssize_t vwsnd_audio_do_write(struct file *file,
- const char *buffer,
- size_t count,
- loff_t *ppos)
-{
- vwsnd_dev_t *devc = file->private_data;
- vwsnd_port_t *wport = ((file->f_mode & FMODE_WRITE) ?
- &devc->wport : NULL);
- int ret, nb;
-
- DBGEV("(file=0x%p, buffer=0x%p, count=%d, ppos=0x%p)\n",
- file, buffer, count, ppos);
-
- if (!wport)
- return -EINVAL;
-
- if (wport->swbuf == NULL) {
- vwsnd_port_t *rport = (file->f_mode & FMODE_READ) ?
- &devc->rport : NULL;
- ret = pcm_setup(devc, rport, wport);
- if (ret < 0)
- return ret;
- }
- if (!access_ok(VERIFY_WRITE, buffer, count))
- return -EFAULT;
- ret = 0;
- while (count) {
- DECLARE_WAITQUEUE(wait, current);
- add_wait_queue(&wport->queue, &wait);
- while ((nb = swb_inc_u(wport, 0)) == 0) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (wport->flags & DISABLED ||
- file->f_flags & O_NONBLOCK) {
- current->state = TASK_RUNNING;
- remove_wait_queue(&wport->queue, &wait);
- return ret ? ret : -EAGAIN;
- }
- schedule();
- if (signal_pending(current)) {
- current->state = TASK_RUNNING;
- remove_wait_queue(&wport->queue, &wait);
- return ret ? ret : -ERESTARTSYS;
- }
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&wport->queue, &wait);
- /* nb bytes are available in userbuf. */
- if (nb > count)
- nb = count;
- DBGPV("nb = %d\n", nb);
- if (copy_from_user(wport->swbuf + wport->swb_u_idx, buffer, nb))
- return -EFAULT;
- pcm_output(devc, 0, nb);
- buffer += nb;
- count -= nb;
- ret += nb;
- }
- DBGPV("returning %d\n", ret);
- return ret;
-}
-
-static ssize_t vwsnd_audio_write(struct file *file,
- const char *buffer,
- size_t count,
- loff_t *ppos)
-{
- vwsnd_dev_t *devc = file->private_data;
- ssize_t ret;
-
- mutex_lock(&devc->io_mutex);
- ret = vwsnd_audio_do_write(file, buffer, count, ppos);
- mutex_unlock(&devc->io_mutex);
- return ret;
-}
-
-/* No kernel lock - fine */
-static unsigned int vwsnd_audio_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data;
- vwsnd_port_t *rport = (file->f_mode & FMODE_READ) ?
- &devc->rport : NULL;
- vwsnd_port_t *wport = (file->f_mode & FMODE_WRITE) ?
- &devc->wport : NULL;
- unsigned int mask = 0;
-
- DBGEV("(file=0x%p, wait=0x%p)\n", file, wait);
-
- ASSERT(rport || wport);
- if (rport) {
- poll_wait(file, &rport->queue, wait);
- if (swb_inc_u(rport, 0))
- mask |= (POLLIN | POLLRDNORM);
- }
- if (wport) {
- poll_wait(file, &wport->queue, wait);
- if (wport->swbuf == NULL || swb_inc_u(wport, 0))
- mask |= (POLLOUT | POLLWRNORM);
- }
-
- DBGPV("returning 0x%x\n", mask);
- return mask;
-}
-
-static int vwsnd_audio_do_ioctl(struct file *file,
- unsigned int cmd,
- unsigned long arg)
-{
- vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data;
- vwsnd_port_t *rport = (file->f_mode & FMODE_READ) ?
- &devc->rport : NULL;
- vwsnd_port_t *wport = (file->f_mode & FMODE_WRITE) ?
- &devc->wport : NULL;
- vwsnd_port_t *aport = rport ? rport : wport;
- struct audio_buf_info buf_info;
- struct count_info info;
- unsigned long flags;
- int ival;
-
-
- DBGEV("(file=0x%p, cmd=0x%x, arg=0x%lx)\n",
- file, cmd, arg);
- switch (cmd) {
- case OSS_GETVERSION: /* _SIOR ('M', 118, int) */
- DBGX("OSS_GETVERSION\n");
- ival = SOUND_VERSION;
- return put_user(ival, (int *) arg);
-
- case SNDCTL_DSP_GETCAPS: /* _SIOR ('P',15, int) */
- DBGX("SNDCTL_DSP_GETCAPS\n");
- ival = DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER;
- return put_user(ival, (int *) arg);
-
- case SNDCTL_DSP_GETFMTS: /* _SIOR ('P',11, int) */
- DBGX("SNDCTL_DSP_GETFMTS\n");
- ival = (AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW |
- AFMT_U8 | AFMT_S8);
- return put_user(ival, (int *) arg);
- break;
-
- case SOUND_PCM_READ_RATE: /* _SIOR ('P', 2, int) */
- DBGX("SOUND_PCM_READ_RATE\n");
- ival = aport->sw_framerate;
- return put_user(ival, (int *) arg);
-
- case SOUND_PCM_READ_CHANNELS: /* _SIOR ('P', 6, int) */
- DBGX("SOUND_PCM_READ_CHANNELS\n");
- ival = aport->sw_channels;
- return put_user(ival, (int *) arg);
-
- case SNDCTL_DSP_SPEED: /* _SIOWR('P', 2, int) */
- if (get_user(ival, (int *) arg))
- return -EFAULT;
- DBGX("SNDCTL_DSP_SPEED %d\n", ival);
- if (ival) {
- if (aport->swstate != SW_INITIAL) {
- DBGX("SNDCTL_DSP_SPEED failed: swstate = %d\n",
- aport->swstate);
- return -EINVAL;
- }
- if (ival < MIN_SPEED)
- ival = MIN_SPEED;
- if (ival > MAX_SPEED)
- ival = MAX_SPEED;
- if (rport)
- rport->sw_framerate = ival;
- if (wport)
- wport->sw_framerate = ival;
- } else
- ival = aport->sw_framerate;
- return put_user(ival, (int *) arg);
-
- case SNDCTL_DSP_STEREO: /* _SIOWR('P', 3, int) */
- if (get_user(ival, (int *) arg))
- return -EFAULT;
- DBGX("SNDCTL_DSP_STEREO %d\n", ival);
- if (ival != 0 && ival != 1)
- return -EINVAL;
- if (aport->swstate != SW_INITIAL)
- return -EINVAL;
- if (rport)
- rport->sw_channels = ival + 1;
- if (wport)
- wport->sw_channels = ival + 1;
- return put_user(ival, (int *) arg);
-
- case SNDCTL_DSP_CHANNELS: /* _SIOWR('P', 6, int) */
- if (get_user(ival, (int *) arg))
- return -EFAULT;
- DBGX("SNDCTL_DSP_CHANNELS %d\n", ival);
- if (ival != 1 && ival != 2)
- return -EINVAL;
- if (aport->swstate != SW_INITIAL)
- return -EINVAL;
- if (rport)
- rport->sw_channels = ival;
- if (wport)
- wport->sw_channels = ival;
- return put_user(ival, (int *) arg);
-
- case SNDCTL_DSP_GETBLKSIZE: /* _SIOWR('P', 4, int) */
- ival = pcm_setup(devc, rport, wport);
- if (ival < 0) {
- DBGX("SNDCTL_DSP_GETBLKSIZE failed, errno %d\n", ival);
- return ival;
- }
- ival = 1 << aport->sw_fragshift;
- DBGX("SNDCTL_DSP_GETBLKSIZE returning %d\n", ival);
- return put_user(ival, (int *) arg);
-
- case SNDCTL_DSP_SETFRAGMENT: /* _SIOWR('P',10, int) */
- if (get_user(ival, (int *) arg))
- return -EFAULT;
- DBGX("SNDCTL_DSP_SETFRAGMENT %d:%d\n",
- ival >> 16, ival & 0xFFFF);
- if (aport->swstate != SW_INITIAL)
- return -EINVAL;
- {
- int sw_fragshift = ival & 0xFFFF;
- int sw_subdivshift = aport->sw_subdivshift;
- int hw_fragshift = sw_fragshift - sw_subdivshift;
- int sw_fragcount = (ival >> 16) & 0xFFFF;
- int hw_fragsize;
- if (hw_fragshift < MIN_FRAGSHIFT)
- hw_fragshift = MIN_FRAGSHIFT;
- if (hw_fragshift > MAX_FRAGSHIFT)
- hw_fragshift = MAX_FRAGSHIFT;
- sw_fragshift = hw_fragshift + aport->sw_subdivshift;
- hw_fragsize = 1 << hw_fragshift;
- if (sw_fragcount < MIN_FRAGCOUNT(hw_fragsize))
- sw_fragcount = MIN_FRAGCOUNT(hw_fragsize);
- if (sw_fragcount > MAX_FRAGCOUNT(hw_fragsize))
- sw_fragcount = MAX_FRAGCOUNT(hw_fragsize);
- DBGPV("sw_fragshift = %d\n", sw_fragshift);
- DBGPV("rport = 0x%p, wport = 0x%p\n", rport, wport);
- if (rport) {
- rport->sw_fragshift = sw_fragshift;
- rport->sw_fragcount = sw_fragcount;
- }
- if (wport) {
- wport->sw_fragshift = sw_fragshift;
- wport->sw_fragcount = sw_fragcount;
- }
- ival = sw_fragcount << 16 | sw_fragshift;
- }
- DBGX("SNDCTL_DSP_SETFRAGMENT returns %d:%d\n",
- ival >> 16, ival & 0xFFFF);
- return put_user(ival, (int *) arg);
-
- case SNDCTL_DSP_SUBDIVIDE: /* _SIOWR('P', 9, int) */
- if (get_user(ival, (int *) arg))
- return -EFAULT;
- DBGX("SNDCTL_DSP_SUBDIVIDE %d\n", ival);
- if (aport->swstate != SW_INITIAL)
- return -EINVAL;
- {
- int subdivshift;
- int hw_fragshift, hw_fragsize, hw_fragcount;
- switch (ival) {
- case 1: subdivshift = 0; break;
- case 2: subdivshift = 1; break;
- case 4: subdivshift = 2; break;
- default: return -EINVAL;
- }
- hw_fragshift = aport->sw_fragshift - subdivshift;
- if (hw_fragshift < MIN_FRAGSHIFT ||
- hw_fragshift > MAX_FRAGSHIFT)
- return -EINVAL;
- hw_fragsize = 1 << hw_fragshift;
- hw_fragcount = aport->sw_fragcount >> subdivshift;
- if (hw_fragcount < MIN_FRAGCOUNT(hw_fragsize) ||
- hw_fragcount > MAX_FRAGCOUNT(hw_fragsize))
- return -EINVAL;
- if (rport)
- rport->sw_subdivshift = subdivshift;
- if (wport)
- wport->sw_subdivshift = subdivshift;
- }
- return 0;
-
- case SNDCTL_DSP_SETFMT: /* _SIOWR('P',5, int) */
- if (get_user(ival, (int *) arg))
- return -EFAULT;
- DBGX("SNDCTL_DSP_SETFMT %d\n", ival);
- if (ival != AFMT_QUERY) {
- if (aport->swstate != SW_INITIAL) {
- DBGP("SETFMT failed, swstate = %d\n",
- aport->swstate);
- return -EINVAL;
- }
- switch (ival) {
- case AFMT_MU_LAW:
- case AFMT_A_LAW:
- case AFMT_U8:
- case AFMT_S8:
- case AFMT_S16_LE:
- if (rport)
- rport->sw_samplefmt = ival;
- if (wport)
- wport->sw_samplefmt = ival;
- break;
- default:
- return -EINVAL;
- }
- }
- ival = aport->sw_samplefmt;
- return put_user(ival, (int *) arg);
-
- case SNDCTL_DSP_GETOSPACE: /* _SIOR ('P',12, audio_buf_info) */
- DBGXV("SNDCTL_DSP_GETOSPACE\n");
- if (!wport)
- return -EINVAL;
- ival = pcm_setup(devc, rport, wport);
- if (ival < 0)
- return ival;
- ival = swb_inc_u(wport, 0);
- buf_info.fragments = ival >> wport->sw_fragshift;
- buf_info.fragstotal = wport->sw_fragcount;
- buf_info.fragsize = 1 << wport->sw_fragshift;
- buf_info.bytes = ival;
- DBGXV("SNDCTL_DSP_GETOSPACE returns { %d %d %d %d }\n",
- buf_info.fragments, buf_info.fragstotal,
- buf_info.fragsize, buf_info.bytes);
- if (copy_to_user((void *) arg, &buf_info, sizeof buf_info))
- return -EFAULT;
- return 0;
-
- case SNDCTL_DSP_GETISPACE: /* _SIOR ('P',13, audio_buf_info) */
- DBGX("SNDCTL_DSP_GETISPACE\n");
- if (!rport)
- return -EINVAL;
- ival = pcm_setup(devc, rport, wport);
- if (ival < 0)
- return ival;
- ival = swb_inc_u(rport, 0);
- buf_info.fragments = ival >> rport->sw_fragshift;
- buf_info.fragstotal = rport->sw_fragcount;
- buf_info.fragsize = 1 << rport->sw_fragshift;
- buf_info.bytes = ival;
- DBGX("SNDCTL_DSP_GETISPACE returns { %d %d %d %d }\n",
- buf_info.fragments, buf_info.fragstotal,
- buf_info.fragsize, buf_info.bytes);
- if (copy_to_user((void *) arg, &buf_info, sizeof buf_info))
- return -EFAULT;
- return 0;
-
- case SNDCTL_DSP_NONBLOCK: /* _SIO ('P',14) */
- DBGX("SNDCTL_DSP_NONBLOCK\n");
- spin_lock(&file->f_lock);
- file->f_flags |= O_NONBLOCK;
- spin_unlock(&file->f_lock);
- return 0;
-
- case SNDCTL_DSP_RESET: /* _SIO ('P', 0) */
- DBGX("SNDCTL_DSP_RESET\n");
- /*
- * Nothing special needs to be done for input. Input
- * samples sit in swbuf, but it will be reinitialized
- * to empty when pcm_setup() is called.
- */
- if (wport && wport->swbuf) {
- wport->swstate = SW_INITIAL;
- pcm_output(devc, 0, 0);
- pcm_write_sync(devc);
- }
- pcm_shutdown(devc, rport, wport);
- return 0;
-
- case SNDCTL_DSP_SYNC: /* _SIO ('P', 1) */
- DBGX("SNDCTL_DSP_SYNC\n");
- if (wport) {
- pcm_flush_frag(devc);
- pcm_write_sync(devc);
- }
- pcm_shutdown(devc, rport, wport);
- return 0;
-
- case SNDCTL_DSP_POST: /* _SIO ('P', 8) */
- DBGX("SNDCTL_DSP_POST\n");
- if (!wport)
- return -EINVAL;
- pcm_flush_frag(devc);
- return 0;
-
- case SNDCTL_DSP_GETIPTR: /* _SIOR ('P', 17, count_info) */
- DBGX("SNDCTL_DSP_GETIPTR\n");
- if (!rport)
- return -EINVAL;
- spin_lock_irqsave(&rport->lock, flags);
- {
- ustmsc_t ustmsc;
- if (rport->hwstate == HW_RUNNING) {
- ASSERT(rport->swstate == SW_RUN);
- li_read_USTMSC(&rport->chan, &ustmsc);
- info.bytes = ustmsc.msc - rport->MSC_offset;
- info.bytes *= rport->frame_size;
- } else {
- info.bytes = rport->byte_count;
- }
- info.blocks = rport->frag_count;
- info.ptr = 0; /* not implemented */
- rport->frag_count = 0;
- }
- spin_unlock_irqrestore(&rport->lock, flags);
- if (copy_to_user((void *) arg, &info, sizeof info))
- return -EFAULT;
- return 0;
-
- case SNDCTL_DSP_GETOPTR: /* _SIOR ('P',18, count_info) */
- DBGX("SNDCTL_DSP_GETOPTR\n");
- if (!wport)
- return -EINVAL;
- spin_lock_irqsave(&wport->lock, flags);
- {
- ustmsc_t ustmsc;
- if (wport->hwstate == HW_RUNNING) {
- ASSERT(wport->swstate == SW_RUN);
- li_read_USTMSC(&wport->chan, &ustmsc);
- info.bytes = ustmsc.msc - wport->MSC_offset;
- info.bytes *= wport->frame_size;
- } else {
- info.bytes = wport->byte_count;
- }
- info.blocks = wport->frag_count;
- info.ptr = 0; /* not implemented */
- wport->frag_count = 0;
- }
- spin_unlock_irqrestore(&wport->lock, flags);
- if (copy_to_user((void *) arg, &info, sizeof info))
- return -EFAULT;
- return 0;
-
- case SNDCTL_DSP_GETODELAY: /* _SIOR ('P', 23, int) */
- DBGX("SNDCTL_DSP_GETODELAY\n");
- if (!wport)
- return -EINVAL;
- spin_lock_irqsave(&wport->lock, flags);
- {
- int fsize = wport->frame_size;
- ival = wport->swb_i_avail / fsize;
- if (wport->hwstate == HW_RUNNING) {
- int swptr, hwptr, hwframes, hwbytes, hwsize;
- int totalhwbytes;
- ustmsc_t ustmsc;
-
- hwsize = wport->hwbuf_size;
- swptr = li_read_swptr(&wport->chan);
- li_read_USTMSC(&wport->chan, &ustmsc);
- hwframes = ustmsc.msc - wport->MSC_offset;
- totalhwbytes = hwframes * fsize;
- hwptr = totalhwbytes % hwsize;
- hwbytes = (swptr - hwptr + hwsize) % hwsize;
- ival += hwbytes / fsize;
- }
- }
- spin_unlock_irqrestore(&wport->lock, flags);
- return put_user(ival, (int *) arg);
-
- case SNDCTL_DSP_PROFILE: /* _SIOW ('P', 23, int) */
- DBGX("SNDCTL_DSP_PROFILE\n");
-
- /*
- * Thomas Sailer explains SNDCTL_DSP_PROFILE
- * (private email, March 24, 1999):
- *
- * This gives the sound driver a hint on what it
- * should do with partial fragments
- * (i.e. fragments partially filled with write).
- * This can direct the driver to zero them or
- * leave them alone. But don't ask me what this
- * is good for, my driver just zeroes the last
- * fragment before the receiver stops, no idea
- * what good for any other behaviour could
- * be. Implementing it as NOP seems safe.
- */
-
- break;
-
- case SNDCTL_DSP_GETTRIGGER: /* _SIOR ('P',16, int) */
- DBGX("SNDCTL_DSP_GETTRIGGER\n");
- ival = 0;
- if (rport) {
- spin_lock_irqsave(&rport->lock, flags);
- {
- if (!(rport->flags & DISABLED))
- ival |= PCM_ENABLE_INPUT;
- }
- spin_unlock_irqrestore(&rport->lock, flags);
- }
- if (wport) {
- spin_lock_irqsave(&wport->lock, flags);
- {
- if (!(wport->flags & DISABLED))
- ival |= PCM_ENABLE_OUTPUT;
- }
- spin_unlock_irqrestore(&wport->lock, flags);
- }
- return put_user(ival, (int *) arg);
-
- case SNDCTL_DSP_SETTRIGGER: /* _SIOW ('P',16, int) */
- if (get_user(ival, (int *) arg))
- return -EFAULT;
- DBGX("SNDCTL_DSP_SETTRIGGER %d\n", ival);
-
- /*
- * If user is disabling I/O and port is not in initial
- * state, fail with EINVAL.
- */
-
- if (((rport && !(ival & PCM_ENABLE_INPUT)) ||
- (wport && !(ival & PCM_ENABLE_OUTPUT))) &&
- aport->swstate != SW_INITIAL)
- return -EINVAL;
-
- if (rport) {
- vwsnd_port_hwstate_t hwstate;
- spin_lock_irqsave(&rport->lock, flags);
- {
- hwstate = rport->hwstate;
- if (ival & PCM_ENABLE_INPUT)
- rport->flags &= ~DISABLED;
- else
- rport->flags |= DISABLED;
- }
- spin_unlock_irqrestore(&rport->lock, flags);
- if (hwstate != HW_RUNNING && ival & PCM_ENABLE_INPUT) {
-
- if (rport->swstate == SW_INITIAL)
- pcm_setup(devc, rport, wport);
- else
- li_activate_dma(&rport->chan);
- }
- }
- if (wport) {
- vwsnd_port_flags_t pflags;
- spin_lock_irqsave(&wport->lock, flags);
- {
- pflags = wport->flags;
- if (ival & PCM_ENABLE_OUTPUT)
- wport->flags &= ~DISABLED;
- else
- wport->flags |= DISABLED;
- }
- spin_unlock_irqrestore(&wport->lock, flags);
- if (pflags & DISABLED && ival & PCM_ENABLE_OUTPUT) {
- if (wport->swstate == SW_RUN)
- pcm_output(devc, 0, 0);
- }
- }
- return 0;
-
- default:
- DBGP("unknown ioctl 0x%x\n", cmd);
- return -EINVAL;
- }
- DBGP("unimplemented ioctl 0x%x\n", cmd);
- return -EINVAL;
-}
-
-static long vwsnd_audio_ioctl(struct file *file,
- unsigned int cmd,
- unsigned long arg)
-{
- vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data;
- int ret;
-
- mutex_lock(&vwsnd_mutex);
- mutex_lock(&devc->io_mutex);
- ret = vwsnd_audio_do_ioctl(file, cmd, arg);
- mutex_unlock(&devc->io_mutex);
- mutex_unlock(&vwsnd_mutex);
-
- return ret;
-}
-
-/* No mmap. */
-
-static int vwsnd_audio_mmap(struct file *file, struct vm_area_struct *vma)
-{
- DBGE("(file=0x%p, vma=0x%p)\n", file, vma);
- return -ENODEV;
-}
-
-/*
- * Open the audio device for read and/or write.
- *
- * Returns 0 on success, -errno on failure.
- */
-
-static int vwsnd_audio_open(struct inode *inode, struct file *file)
-{
- vwsnd_dev_t *devc;
- int minor = iminor(inode);
- int sw_samplefmt;
-
- DBGE("(inode=0x%p, file=0x%p)\n", inode, file);
-
- mutex_lock(&vwsnd_mutex);
- INC_USE_COUNT;
- for (devc = vwsnd_dev_list; devc; devc = devc->next_dev)
- if ((devc->audio_minor & ~0x0F) == (minor & ~0x0F))
- break;
-
- if (devc == NULL) {
- DEC_USE_COUNT;
- mutex_unlock(&vwsnd_mutex);
- return -ENODEV;
- }
-
- mutex_lock(&devc->open_mutex);
- while (devc->open_mode & file->f_mode) {
- mutex_unlock(&devc->open_mutex);
- if (file->f_flags & O_NONBLOCK) {
- DEC_USE_COUNT;
- mutex_unlock(&vwsnd_mutex);
- return -EBUSY;
- }
- interruptible_sleep_on(&devc->open_wait);
- if (signal_pending(current)) {
- DEC_USE_COUNT;
- mutex_unlock(&vwsnd_mutex);
- return -ERESTARTSYS;
- }
- mutex_lock(&devc->open_mutex);
- }
- devc->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
- mutex_unlock(&devc->open_mutex);
-
- /* get default sample format from minor number. */
-
- sw_samplefmt = 0;
- if ((minor & 0xF) == SND_DEV_DSP)
- sw_samplefmt = AFMT_U8;
- else if ((minor & 0xF) == SND_DEV_AUDIO)
- sw_samplefmt = AFMT_MU_LAW;
- else if ((minor & 0xF) == SND_DEV_DSP16)
- sw_samplefmt = AFMT_S16_LE;
- else
- ASSERT(0);
-
- /* Initialize vwsnd_ports. */
-
- mutex_lock(&devc->io_mutex);
- {
- if (file->f_mode & FMODE_READ) {
- devc->rport.swstate = SW_INITIAL;
- devc->rport.flags = 0;
- devc->rport.sw_channels = 1;
- devc->rport.sw_samplefmt = sw_samplefmt;
- devc->rport.sw_framerate = 8000;
- devc->rport.sw_fragshift = DEFAULT_FRAGSHIFT;
- devc->rport.sw_fragcount = DEFAULT_FRAGCOUNT;
- devc->rport.sw_subdivshift = DEFAULT_SUBDIVSHIFT;
- devc->rport.byte_count = 0;
- devc->rport.frag_count = 0;
- }
- if (file->f_mode & FMODE_WRITE) {
- devc->wport.swstate = SW_INITIAL;
- devc->wport.flags = 0;
- devc->wport.sw_channels = 1;
- devc->wport.sw_samplefmt = sw_samplefmt;
- devc->wport.sw_framerate = 8000;
- devc->wport.sw_fragshift = DEFAULT_FRAGSHIFT;
- devc->wport.sw_fragcount = DEFAULT_FRAGCOUNT;
- devc->wport.sw_subdivshift = DEFAULT_SUBDIVSHIFT;
- devc->wport.byte_count = 0;
- devc->wport.frag_count = 0;
- }
- }
- mutex_unlock(&devc->io_mutex);
-
- file->private_data = devc;
- DBGRV();
- mutex_unlock(&vwsnd_mutex);
- return 0;
-}
-
-/*
- * Release (close) the audio device.
- */
-
-static int vwsnd_audio_release(struct inode *inode, struct file *file)
-{
- vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data;
- vwsnd_port_t *wport = NULL, *rport = NULL;
- int err = 0;
-
- mutex_lock(&vwsnd_mutex);
- mutex_lock(&devc->io_mutex);
- {
- DBGEV("(inode=0x%p, file=0x%p)\n", inode, file);
-
- if (file->f_mode & FMODE_READ)
- rport = &devc->rport;
- if (file->f_mode & FMODE_WRITE) {
- wport = &devc->wport;
- pcm_flush_frag(devc);
- pcm_write_sync(devc);
- }
- pcm_shutdown(devc, rport, wport);
- if (rport)
- rport->swstate = SW_OFF;
- if (wport)
- wport->swstate = SW_OFF;
- }
- mutex_unlock(&devc->io_mutex);
-
- mutex_lock(&devc->open_mutex);
- {
- devc->open_mode &= ~file->f_mode;
- }
- mutex_unlock(&devc->open_mutex);
- wake_up(&devc->open_wait);
- DEC_USE_COUNT;
- DBGR();
- mutex_unlock(&vwsnd_mutex);
- return err;
-}
-
-static const struct file_operations vwsnd_audio_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .read = vwsnd_audio_read,
- .write = vwsnd_audio_write,
- .poll = vwsnd_audio_poll,
- .unlocked_ioctl = vwsnd_audio_ioctl,
- .mmap = vwsnd_audio_mmap,
- .open = vwsnd_audio_open,
- .release = vwsnd_audio_release,
-};
-
-/*****************************************************************************/
-/* mixer driver */
-
-/* open the mixer device. */
-
-static int vwsnd_mixer_open(struct inode *inode, struct file *file)
-{
- vwsnd_dev_t *devc;
-
- DBGEV("(inode=0x%p, file=0x%p)\n", inode, file);
-
- INC_USE_COUNT;
- mutex_lock(&vwsnd_mutex);
- for (devc = vwsnd_dev_list; devc; devc = devc->next_dev)
- if (devc->mixer_minor == iminor(inode))
- break;
-
- if (devc == NULL) {
- DEC_USE_COUNT;
- mutex_unlock(&vwsnd_mutex);
- return -ENODEV;
- }
- file->private_data = devc;
- mutex_unlock(&vwsnd_mutex);
- return 0;
-}
-
-/* release (close) the mixer device. */
-
-static int vwsnd_mixer_release(struct inode *inode, struct file *file)
-{
- DBGEV("(inode=0x%p, file=0x%p)\n", inode, file);
- DEC_USE_COUNT;
- return 0;
-}
-
-/* mixer_read_ioctl handles all read ioctls on the mixer device. */
-
-static int mixer_read_ioctl(vwsnd_dev_t *devc, unsigned int nr, void __user *arg)
-{
- int val = -1;
-
- DBGEV("(devc=0x%p, nr=0x%x, arg=0x%p)\n", devc, nr, arg);
-
- switch (nr) {
- case SOUND_MIXER_CAPS:
- val = SOUND_CAP_EXCL_INPUT;
- break;
-
- case SOUND_MIXER_DEVMASK:
- val = (SOUND_MASK_PCM | SOUND_MASK_LINE |
- SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_RECLEV);
- break;
-
- case SOUND_MIXER_STEREODEVS:
- val = (SOUND_MASK_PCM | SOUND_MASK_LINE |
- SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_RECLEV);
- break;
-
- case SOUND_MIXER_OUTMASK:
- val = (SOUND_MASK_PCM | SOUND_MASK_LINE |
- SOUND_MASK_MIC | SOUND_MASK_CD);
- break;
-
- case SOUND_MIXER_RECMASK:
- val = (SOUND_MASK_PCM | SOUND_MASK_LINE |
- SOUND_MASK_MIC | SOUND_MASK_CD);
- break;
-
- case SOUND_MIXER_PCM:
- val = ad1843_get_gain(&devc->lith, &ad1843_gain_PCM);
- break;
-
- case SOUND_MIXER_LINE:
- val = ad1843_get_gain(&devc->lith, &ad1843_gain_LINE);
- break;
-
- case SOUND_MIXER_MIC:
- val = ad1843_get_gain(&devc->lith, &ad1843_gain_MIC);
- break;
-
- case SOUND_MIXER_CD:
- val = ad1843_get_gain(&devc->lith, &ad1843_gain_CD);
- break;
-
- case SOUND_MIXER_RECLEV:
- val = ad1843_get_gain(&devc->lith, &ad1843_gain_RECLEV);
- break;
-
- case SOUND_MIXER_RECSRC:
- val = ad1843_get_recsrc(&devc->lith);
- break;
-
- case SOUND_MIXER_OUTSRC:
- val = ad1843_get_outsrc(&devc->lith);
- break;
-
- default:
- return -EINVAL;
- }
- return put_user(val, (int __user *) arg);
-}
-
-/* mixer_write_ioctl handles all write ioctls on the mixer device. */
-
-static int mixer_write_ioctl(vwsnd_dev_t *devc, unsigned int nr, void __user *arg)
-{
- int val;
- int err;
-
- DBGEV("(devc=0x%p, nr=0x%x, arg=0x%p)\n", devc, nr, arg);
-
- err = get_user(val, (int __user *) arg);
- if (err)
- return -EFAULT;
- switch (nr) {
- case SOUND_MIXER_PCM:
- val = ad1843_set_gain(&devc->lith, &ad1843_gain_PCM, val);
- break;
-
- case SOUND_MIXER_LINE:
- val = ad1843_set_gain(&devc->lith, &ad1843_gain_LINE, val);
- break;
-
- case SOUND_MIXER_MIC:
- val = ad1843_set_gain(&devc->lith, &ad1843_gain_MIC, val);
- break;
-
- case SOUND_MIXER_CD:
- val = ad1843_set_gain(&devc->lith, &ad1843_gain_CD, val);
- break;
-
- case SOUND_MIXER_RECLEV:
- val = ad1843_set_gain(&devc->lith, &ad1843_gain_RECLEV, val);
- break;
-
- case SOUND_MIXER_RECSRC:
- if (devc->rport.swbuf || devc->wport.swbuf)
- return -EBUSY; /* can't change recsrc while running */
- val = ad1843_set_recsrc(&devc->lith, val);
- break;
-
- case SOUND_MIXER_OUTSRC:
- val = ad1843_set_outsrc(&devc->lith, val);
- break;
-
- default:
- return -EINVAL;
- }
- if (val < 0)
- return val;
- return put_user(val, (int __user *) arg);
-}
-
-/* This is the ioctl entry to the mixer driver. */
-
-static long vwsnd_mixer_ioctl(struct file *file,
- unsigned int cmd,
- unsigned long arg)
-{
- vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data;
- const unsigned int nrmask = _IOC_NRMASK << _IOC_NRSHIFT;
- const unsigned int nr = (cmd & nrmask) >> _IOC_NRSHIFT;
- int retval;
-
- DBGEV("(devc=0x%p, cmd=0x%x, arg=0x%lx)\n", devc, cmd, arg);
-
- mutex_lock(&vwsnd_mutex);
- mutex_lock(&devc->mix_mutex);
- {
- if ((cmd & ~nrmask) == MIXER_READ(0))
- retval = mixer_read_ioctl(devc, nr, (void __user *) arg);
- else if ((cmd & ~nrmask) == MIXER_WRITE(0))
- retval = mixer_write_ioctl(devc, nr, (void __user *) arg);
- else
- retval = -EINVAL;
- }
- mutex_unlock(&devc->mix_mutex);
- mutex_unlock(&vwsnd_mutex);
- return retval;
-}
-
-static const struct file_operations vwsnd_mixer_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .unlocked_ioctl = vwsnd_mixer_ioctl,
- .open = vwsnd_mixer_open,
- .release = vwsnd_mixer_release,
-};
-
-/*****************************************************************************/
-/* probe/attach/unload */
-
-/* driver probe routine. Return nonzero if hardware is found. */
-
-static int __init probe_vwsnd(struct address_info *hw_config)
-{
- lithium_t lith;
- int w;
- unsigned long later;
-
- DBGEV("(hw_config=0x%p)\n", hw_config);
-
- /* XXX verify lithium present (to prevent crash on non-vw) */
-
- if (li_create(&lith, hw_config->io_base) != 0) {
- printk(KERN_WARNING "probe_vwsnd: can't map lithium\n");
- return 0;
- }
- later = jiffies + 2;
- li_writel(&lith, LI_HOST_CONTROLLER, LI_HC_LINK_ENABLE);
- do {
- w = li_readl(&lith, LI_HOST_CONTROLLER);
- } while (w == LI_HC_LINK_ENABLE && time_before(jiffies, later));
-
- li_destroy(&lith);
-
- DBGPV("HC = 0x%04x\n", w);
-
- if ((w == LI_HC_LINK_ENABLE) || (w & LI_HC_LINK_CODEC)) {
-
- /* This may indicate a beta machine with no audio,
- * or a future machine with different audio.
- * On beta-release 320 w/ no audio, HC == 0x4000 */
-
- printk(KERN_WARNING "probe_vwsnd: audio codec not found\n");
- return 0;
- }
-
- if (w & LI_HC_LINK_FAILURE) {
- printk(KERN_WARNING "probe_vwsnd: can't init audio codec\n");
- return 0;
- }
-
- printk(KERN_INFO "vwsnd: lithium audio at mmio %#x irq %d\n",
- hw_config->io_base, hw_config->irq);
-
- return 1;
-}
-
-/*
- * driver attach routine. Initialize driver data structures and
- * initialize hardware. A new vwsnd_dev_t is allocated and put
- * onto the global list, vwsnd_dev_list.
- *
- * Return +minor_dev on success, -errno on failure.
- */
-
-static int __init attach_vwsnd(struct address_info *hw_config)
-{
- vwsnd_dev_t *devc = NULL;
- int err = -ENOMEM;
-
- DBGEV("(hw_config=0x%p)\n", hw_config);
-
- devc = kmalloc(sizeof (vwsnd_dev_t), GFP_KERNEL);
- if (devc == NULL)
- goto fail0;
-
- err = li_create(&devc->lith, hw_config->io_base);
- if (err)
- goto fail1;
-
- init_waitqueue_head(&devc->open_wait);
-
- devc->rport.hwbuf_size = HWBUF_SIZE;
- devc->rport.hwbuf_vaddr = __get_free_pages(GFP_KERNEL, HWBUF_ORDER);
- if (!devc->rport.hwbuf_vaddr)
- goto fail2;
- devc->rport.hwbuf = (void *) devc->rport.hwbuf_vaddr;
- devc->rport.hwbuf_paddr = virt_to_phys(devc->rport.hwbuf);
-
- /*
- * Quote from the NT driver:
- *
- * // WARNING!!! HACK to setup output dma!!!
- * // This is required because even on output there is some data
- * // trickling into the input DMA channel. This is a bug in the
- * // Lithium microcode.
- * // --sde
- *
- * We set the input side's DMA base address here. It will remain
- * valid until the driver is unloaded.
- */
-
- li_writel(&devc->lith, LI_COMM1_BASE,
- devc->rport.hwbuf_paddr >> 8 | 1 << (37 - 8));
-
- devc->wport.hwbuf_size = HWBUF_SIZE;
- devc->wport.hwbuf_vaddr = __get_free_pages(GFP_KERNEL, HWBUF_ORDER);
- if (!devc->wport.hwbuf_vaddr)
- goto fail3;
- devc->wport.hwbuf = (void *) devc->wport.hwbuf_vaddr;
- devc->wport.hwbuf_paddr = virt_to_phys(devc->wport.hwbuf);
- DBGP("wport hwbuf = 0x%p\n", devc->wport.hwbuf);
-
- DBGDO(shut_up++);
- err = ad1843_init(&devc->lith);
- DBGDO(shut_up--);
- if (err)
- goto fail4;
-
- /* install interrupt handler */
-
- err = request_irq(hw_config->irq, vwsnd_audio_intr, 0, "vwsnd", devc);
- if (err)
- goto fail5;
-
- /* register this device's drivers. */
-
- devc->audio_minor = register_sound_dsp(&vwsnd_audio_fops, -1);
- if ((err = devc->audio_minor) < 0) {
- DBGDO(printk(KERN_WARNING
- "attach_vwsnd: register_sound_dsp error %d\n",
- err));
- goto fail6;
- }
- devc->mixer_minor = register_sound_mixer(&vwsnd_mixer_fops,
- devc->audio_minor >> 4);
- if ((err = devc->mixer_minor) < 0) {
- DBGDO(printk(KERN_WARNING
- "attach_vwsnd: register_sound_mixer error %d\n",
- err));
- goto fail7;
- }
-
- /* Squirrel away device indices for unload routine. */
-
- hw_config->slots[0] = devc->audio_minor;
-
- /* Initialize as much of *devc as possible */
-
- mutex_init(&devc->open_mutex);
- mutex_init(&devc->io_mutex);
- mutex_init(&devc->mix_mutex);
- devc->open_mode = 0;
- spin_lock_init(&devc->rport.lock);
- init_waitqueue_head(&devc->rport.queue);
- devc->rport.swstate = SW_OFF;
- devc->rport.hwstate = HW_STOPPED;
- devc->rport.flags = 0;
- devc->rport.swbuf = NULL;
- spin_lock_init(&devc->wport.lock);
- init_waitqueue_head(&devc->wport.queue);
- devc->wport.swstate = SW_OFF;
- devc->wport.hwstate = HW_STOPPED;
- devc->wport.flags = 0;
- devc->wport.swbuf = NULL;
-
- /* Success. Link us onto the local device list. */
-
- devc->next_dev = vwsnd_dev_list;
- vwsnd_dev_list = devc;
- return devc->audio_minor;
-
- /* So many ways to fail. Undo what we did. */
-
- fail7:
- unregister_sound_dsp(devc->audio_minor);
- fail6:
- free_irq(hw_config->irq, devc);
- fail5:
- fail4:
- free_pages(devc->wport.hwbuf_vaddr, HWBUF_ORDER);
- fail3:
- free_pages(devc->rport.hwbuf_vaddr, HWBUF_ORDER);
- fail2:
- li_destroy(&devc->lith);
- fail1:
- kfree(devc);
- fail0:
- return err;
-}
-
-static int __exit unload_vwsnd(struct address_info *hw_config)
-{
- vwsnd_dev_t *devc, **devcp;
-
- DBGE("()\n");
-
- devcp = &vwsnd_dev_list;
- while ((devc = *devcp)) {
- if (devc->audio_minor == hw_config->slots[0]) {
- *devcp = devc->next_dev;
- break;
- }
- devcp = &devc->next_dev;
- }
-
- if (!devc)
- return -ENODEV;
-
- unregister_sound_mixer(devc->mixer_minor);
- unregister_sound_dsp(devc->audio_minor);
- free_irq(hw_config->irq, devc);
- free_pages(devc->wport.hwbuf_vaddr, HWBUF_ORDER);
- free_pages(devc->rport.hwbuf_vaddr, HWBUF_ORDER);
- li_destroy(&devc->lith);
- kfree(devc);
-
- return 0;
-}
-
-/*****************************************************************************/
-/* initialization and loadable kernel module interface */
-
-static struct address_info the_hw_config = {
- 0xFF001000, /* lithium phys addr */
- CO_IRQ(CO_APIC_LI_AUDIO) /* irq */
-};
-
-MODULE_DESCRIPTION("SGI Visual Workstation sound module");
-MODULE_AUTHOR("Bob Miller <kbob@sgi.com>");
-MODULE_LICENSE("GPL");
-
-static int __init init_vwsnd(void)
-{
- int err;
-
- DBGXV("\n");
- DBGXV("sound::vwsnd::init_module()\n");
-
- if (!probe_vwsnd(&the_hw_config))
- return -ENODEV;
-
- err = attach_vwsnd(&the_hw_config);
- if (err < 0)
- return err;
- return 0;
-}
-
-static void __exit cleanup_vwsnd(void)
-{
- DBGX("sound::vwsnd::cleanup_module()\n");
-
- unload_vwsnd(&the_hw_config);
-}
-
-module_init(init_vwsnd);
-module_exit(cleanup_vwsnd);
diff --git a/ANDROID_3.4.5/sound/oss/waveartist.c b/ANDROID_3.4.5/sound/oss/waveartist.c
deleted file mode 100644
index 24c430f7..00000000
--- a/ANDROID_3.4.5/sound/oss/waveartist.c
+++ /dev/null
@@ -1,2024 +0,0 @@
-/*
- * linux/sound/oss/waveartist.c
- *
- * The low level driver for the RWA010 Rockwell Wave Artist
- * codec chip used in the Rebel.com NetWinder.
- *
- * Cleaned up and integrated into 2.1 by Russell King (rmk@arm.linux.org.uk)
- * and Pat Beirne (patb@corel.ca)
- *
- *
- * Copyright (C) by Rebel.com 1998-1999
- *
- * RWA010 specs received under NDA from Rockwell
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Changes:
- * 11-10-2000 Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
- * Added __init to waveartist_init()
- */
-
-/* Debugging */
-#define DEBUG_CMD 1
-#define DEBUG_OUT 2
-#define DEBUG_IN 4
-#define DEBUG_INTR 8
-#define DEBUG_MIXER 16
-#define DEBUG_TRIGGER 32
-
-#define debug_flg (0)
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/bitops.h>
-
-
-#include "sound_config.h"
-#include "waveartist.h"
-
-#ifdef CONFIG_ARM
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#endif
-
-#ifndef NO_DMA
-#define NO_DMA 255
-#endif
-
-#define SUPPORTED_MIXER_DEVICES (SOUND_MASK_SYNTH |\
- SOUND_MASK_PCM |\
- SOUND_MASK_LINE |\
- SOUND_MASK_MIC |\
- SOUND_MASK_LINE1 |\
- SOUND_MASK_RECLEV |\
- SOUND_MASK_VOLUME |\
- SOUND_MASK_IMIX)
-
-static unsigned short levels[SOUND_MIXER_NRDEVICES] = {
- 0x5555, /* Master Volume */
- 0x0000, /* Bass */
- 0x0000, /* Treble */
- 0x2323, /* Synth (FM) */
- 0x4b4b, /* PCM */
- 0x6464, /* PC Speaker */
- 0x0000, /* Ext Line */
- 0x0000, /* Mic */
- 0x0000, /* CD */
- 0x6464, /* Recording monitor */
- 0x0000, /* SB PCM (ALT PCM) */
- 0x0000, /* Recording level */
- 0x6464, /* Input gain */
- 0x6464, /* Output gain */
- 0x0000, /* Line1 (Aux1) */
- 0x0000, /* Line2 (Aux2) */
- 0x0000, /* Line3 (Aux3) */
- 0x0000, /* Digital1 */
- 0x0000, /* Digital2 */
- 0x0000, /* Digital3 */
- 0x0000, /* Phone In */
- 0x6464, /* Phone Out */
- 0x0000, /* Video */
- 0x0000, /* Radio */
- 0x0000 /* Monitor */
-};
-
-typedef struct {
- struct address_info hw; /* hardware */
- char *chip_name;
-
- int xfer_count;
- int audio_mode;
- int open_mode;
- int audio_flags;
- int record_dev;
- int playback_dev;
- int dev_no;
-
- /* Mixer parameters */
- const struct waveartist_mixer_info *mix;
-
- unsigned short *levels; /* cache of volume settings */
- int recmask; /* currently enabled recording device! */
-
-#ifdef CONFIG_ARCH_NETWINDER
- signed int slider_vol; /* hardware slider volume */
- unsigned int handset_detect :1;
- unsigned int telephone_detect:1;
- unsigned int no_autoselect :1;/* handset/telephone autoselects a path */
- unsigned int spkr_mute_state :1;/* set by ioctl or autoselect */
- unsigned int line_mute_state :1;/* set by ioctl or autoselect */
- unsigned int use_slider :1;/* use slider setting for o/p vol */
-#endif
-} wavnc_info;
-
-/*
- * This is the implementation specific mixer information.
- */
-struct waveartist_mixer_info {
- unsigned int supported_devs; /* Supported devices */
- unsigned int recording_devs; /* Recordable devies */
- unsigned int stereo_devs; /* Stereo devices */
-
- unsigned int (*select_input)(wavnc_info *, unsigned int,
- unsigned char *, unsigned char *);
- int (*decode_mixer)(wavnc_info *, int,
- unsigned char, unsigned char);
- int (*get_mixer)(wavnc_info *, int);
-};
-
-typedef struct wavnc_port_info {
- int open_mode;
- int speed;
- int channels;
- int audio_format;
-} wavnc_port_info;
-
-static int nr_waveartist_devs;
-static wavnc_info adev_info[MAX_AUDIO_DEV];
-static DEFINE_SPINLOCK(waveartist_lock);
-
-#ifndef CONFIG_ARCH_NETWINDER
-#define machine_is_netwinder() 0
-#else
-static struct timer_list vnc_timer;
-static void vnc_configure_mixer(wavnc_info *devc, unsigned int input_mask);
-static int vnc_private_ioctl(int dev, unsigned int cmd, int __user *arg);
-static void vnc_slider_tick(unsigned long data);
-#endif
-
-static inline void
-waveartist_set_ctlr(struct address_info *hw, unsigned char clear, unsigned char set)
-{
- unsigned int ctlr_port = hw->io_base + CTLR;
-
- clear = ~clear & inb(ctlr_port);
-
- outb(clear | set, ctlr_port);
-}
-
-/* Toggle IRQ acknowledge line
- */
-static inline void
-waveartist_iack(wavnc_info *devc)
-{
- unsigned int ctlr_port = devc->hw.io_base + CTLR;
- int old_ctlr;
-
- old_ctlr = inb(ctlr_port) & ~IRQ_ACK;
-
- outb(old_ctlr | IRQ_ACK, ctlr_port);
- outb(old_ctlr, ctlr_port);
-}
-
-static inline int
-waveartist_sleep(int timeout_ms)
-{
- unsigned int timeout = msecs_to_jiffies(timeout_ms*100);
- return schedule_timeout_interruptible(timeout);
-}
-
-static int
-waveartist_reset(wavnc_info *devc)
-{
- struct address_info *hw = &devc->hw;
- unsigned int timeout, res = -1;
-
- waveartist_set_ctlr(hw, -1, RESET);
- waveartist_sleep(2);
- waveartist_set_ctlr(hw, RESET, 0);
-
- timeout = 500;
- do {
- mdelay(2);
-
- if (inb(hw->io_base + STATR) & CMD_RF) {
- res = inw(hw->io_base + CMDR);
- if (res == 0x55aa)
- break;
- }
- } while (--timeout);
-
- if (timeout == 0) {
- printk(KERN_WARNING "WaveArtist: reset timeout ");
- if (res != (unsigned int)-1)
- printk("(res=%04X)", res);
- printk("\n");
- return 1;
- }
- return 0;
-}
-
-/* Helper function to send and receive words
- * from WaveArtist. It handles all the handshaking
- * and can send or receive multiple words.
- */
-static int
-waveartist_cmd(wavnc_info *devc,
- int nr_cmd, unsigned int *cmd,
- int nr_resp, unsigned int *resp)
-{
- unsigned int io_base = devc->hw.io_base;
- unsigned int timed_out = 0;
- unsigned int i;
-
- if (debug_flg & DEBUG_CMD) {
- printk("waveartist_cmd: cmd=");
-
- for (i = 0; i < nr_cmd; i++)
- printk("%04X ", cmd[i]);
-
- printk("\n");
- }
-
- if (inb(io_base + STATR) & CMD_RF) {
- int old_data;
-
- /* flush the port
- */
-
- old_data = inw(io_base + CMDR);
-
- if (debug_flg & DEBUG_CMD)
- printk("flushed %04X...", old_data);
-
- udelay(10);
- }
-
- for (i = 0; !timed_out && i < nr_cmd; i++) {
- int count;
-
- for (count = 5000; count; count--)
- if (inb(io_base + STATR) & CMD_WE)
- break;
-
- if (!count)
- timed_out = 1;
- else
- outw(cmd[i], io_base + CMDR);
- }
-
- for (i = 0; !timed_out && i < nr_resp; i++) {
- int count;
-
- for (count = 5000; count; count--)
- if (inb(io_base + STATR) & CMD_RF)
- break;
-
- if (!count)
- timed_out = 1;
- else
- resp[i] = inw(io_base + CMDR);
- }
-
- if (debug_flg & DEBUG_CMD) {
- if (!timed_out) {
- printk("waveartist_cmd: resp=");
-
- for (i = 0; i < nr_resp; i++)
- printk("%04X ", resp[i]);
-
- printk("\n");
- } else
- printk("waveartist_cmd: timed out\n");
- }
-
- return timed_out ? 1 : 0;
-}
-
-/*
- * Send one command word
- */
-static inline int
-waveartist_cmd1(wavnc_info *devc, unsigned int cmd)
-{
- return waveartist_cmd(devc, 1, &cmd, 0, NULL);
-}
-
-/*
- * Send one command, receive one word
- */
-static inline unsigned int
-waveartist_cmd1_r(wavnc_info *devc, unsigned int cmd)
-{
- unsigned int ret;
-
- waveartist_cmd(devc, 1, &cmd, 1, &ret);
-
- return ret;
-}
-
-/*
- * Send a double command, receive one
- * word (and throw it away)
- */
-static inline int
-waveartist_cmd2(wavnc_info *devc, unsigned int cmd, unsigned int arg)
-{
- unsigned int vals[2];
-
- vals[0] = cmd;
- vals[1] = arg;
-
- return waveartist_cmd(devc, 2, vals, 1, vals);
-}
-
-/*
- * Send a triple command
- */
-static inline int
-waveartist_cmd3(wavnc_info *devc, unsigned int cmd,
- unsigned int arg1, unsigned int arg2)
-{
- unsigned int vals[3];
-
- vals[0] = cmd;
- vals[1] = arg1;
- vals[2] = arg2;
-
- return waveartist_cmd(devc, 3, vals, 0, NULL);
-}
-
-static int
-waveartist_getrev(wavnc_info *devc, char *rev)
-{
- unsigned int temp[2];
- unsigned int cmd = WACMD_GETREV;
-
- waveartist_cmd(devc, 1, &cmd, 2, temp);
-
- rev[0] = temp[0] >> 8;
- rev[1] = temp[0] & 255;
- rev[2] = '\0';
-
- return temp[0];
-}
-
-static void waveartist_halt_output(int dev);
-static void waveartist_halt_input(int dev);
-static void waveartist_halt(int dev);
-static void waveartist_trigger(int dev, int state);
-
-static int
-waveartist_open(int dev, int mode)
-{
- wavnc_info *devc;
- wavnc_port_info *portc;
- unsigned long flags;
-
- if (dev < 0 || dev >= num_audiodevs)
- return -ENXIO;
-
- devc = (wavnc_info *) audio_devs[dev]->devc;
- portc = (wavnc_port_info *) audio_devs[dev]->portc;
-
- spin_lock_irqsave(&waveartist_lock, flags);
- if (portc->open_mode || (devc->open_mode & mode)) {
- spin_unlock_irqrestore(&waveartist_lock, flags);
- return -EBUSY;
- }
-
- devc->audio_mode = 0;
- devc->open_mode |= mode;
- portc->open_mode = mode;
- waveartist_trigger(dev, 0);
-
- if (mode & OPEN_READ)
- devc->record_dev = dev;
- if (mode & OPEN_WRITE)
- devc->playback_dev = dev;
- spin_unlock_irqrestore(&waveartist_lock, flags);
-
- return 0;
-}
-
-static void
-waveartist_close(int dev)
-{
- wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc;
- wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
- unsigned long flags;
-
- spin_lock_irqsave(&waveartist_lock, flags);
-
- waveartist_halt(dev);
-
- devc->audio_mode = 0;
- devc->open_mode &= ~portc->open_mode;
- portc->open_mode = 0;
-
- spin_unlock_irqrestore(&waveartist_lock, flags);
-}
-
-static void
-waveartist_output_block(int dev, unsigned long buf, int __count, int intrflag)
-{
- wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
- wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc;
- unsigned long flags;
- unsigned int count = __count;
-
- if (debug_flg & DEBUG_OUT)
- printk("waveartist: output block, buf=0x%lx, count=0x%x...\n",
- buf, count);
- /*
- * 16 bit data
- */
- if (portc->audio_format & (AFMT_S16_LE | AFMT_S16_BE))
- count >>= 1;
-
- if (portc->channels > 1)
- count >>= 1;
-
- count -= 1;
-
- if (devc->audio_mode & PCM_ENABLE_OUTPUT &&
- audio_devs[dev]->flags & DMA_AUTOMODE &&
- intrflag &&
- count == devc->xfer_count) {
- devc->audio_mode |= PCM_ENABLE_OUTPUT;
- return; /*
- * Auto DMA mode on. No need to react
- */
- }
-
- spin_lock_irqsave(&waveartist_lock, flags);
-
- /*
- * set sample count
- */
- waveartist_cmd2(devc, WACMD_OUTPUTSIZE, count);
-
- devc->xfer_count = count;
- devc->audio_mode |= PCM_ENABLE_OUTPUT;
-
- spin_unlock_irqrestore(&waveartist_lock, flags);
-}
-
-static void
-waveartist_start_input(int dev, unsigned long buf, int __count, int intrflag)
-{
- wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
- wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc;
- unsigned long flags;
- unsigned int count = __count;
-
- if (debug_flg & DEBUG_IN)
- printk("waveartist: start input, buf=0x%lx, count=0x%x...\n",
- buf, count);
-
- if (portc->audio_format & (AFMT_S16_LE | AFMT_S16_BE)) /* 16 bit data */
- count >>= 1;
-
- if (portc->channels > 1)
- count >>= 1;
-
- count -= 1;
-
- if (devc->audio_mode & PCM_ENABLE_INPUT &&
- audio_devs[dev]->flags & DMA_AUTOMODE &&
- intrflag &&
- count == devc->xfer_count) {
- devc->audio_mode |= PCM_ENABLE_INPUT;
- return; /*
- * Auto DMA mode on. No need to react
- */
- }
-
- spin_lock_irqsave(&waveartist_lock, flags);
-
- /*
- * set sample count
- */
- waveartist_cmd2(devc, WACMD_INPUTSIZE, count);
-
- devc->xfer_count = count;
- devc->audio_mode |= PCM_ENABLE_INPUT;
-
- spin_unlock_irqrestore(&waveartist_lock, flags);
-}
-
-static int
-waveartist_ioctl(int dev, unsigned int cmd, void __user * arg)
-{
- return -EINVAL;
-}
-
-static unsigned int
-waveartist_get_speed(wavnc_port_info *portc)
-{
- unsigned int speed;
-
- /*
- * program the speed, channels, bits
- */
- if (portc->speed == 8000)
- speed = 0x2E71;
- else if (portc->speed == 11025)
- speed = 0x4000;
- else if (portc->speed == 22050)
- speed = 0x8000;
- else if (portc->speed == 44100)
- speed = 0x0;
- else {
- /*
- * non-standard - just calculate
- */
- speed = portc->speed << 16;
-
- speed = (speed / 44100) & 65535;
- }
-
- return speed;
-}
-
-static unsigned int
-waveartist_get_bits(wavnc_port_info *portc)
-{
- unsigned int bits;
-
- if (portc->audio_format == AFMT_S16_LE)
- bits = 1;
- else if (portc->audio_format == AFMT_S8)
- bits = 0;
- else
- bits = 2; //default AFMT_U8
-
- return bits;
-}
-
-static int
-waveartist_prepare_for_input(int dev, int bsize, int bcount)
-{
- unsigned long flags;
- wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc;
- wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
- unsigned int speed, bits;
-
- if (devc->audio_mode)
- return 0;
-
- speed = waveartist_get_speed(portc);
- bits = waveartist_get_bits(portc);
-
- spin_lock_irqsave(&waveartist_lock, flags);
-
- if (waveartist_cmd2(devc, WACMD_INPUTFORMAT, bits))
- printk(KERN_WARNING "waveartist: error setting the "
- "record format to %d\n", portc->audio_format);
-
- if (waveartist_cmd2(devc, WACMD_INPUTCHANNELS, portc->channels))
- printk(KERN_WARNING "waveartist: error setting record "
- "to %d channels\n", portc->channels);
-
- /*
- * write cmd SetSampleSpeedTimeConstant
- */
- if (waveartist_cmd2(devc, WACMD_INPUTSPEED, speed))
- printk(KERN_WARNING "waveartist: error setting the record "
- "speed to %dHz.\n", portc->speed);
-
- if (waveartist_cmd2(devc, WACMD_INPUTDMA, 1))
- printk(KERN_WARNING "waveartist: error setting the record "
- "data path to 0x%X\n", 1);
-
- if (waveartist_cmd2(devc, WACMD_INPUTFORMAT, bits))
- printk(KERN_WARNING "waveartist: error setting the record "
- "format to %d\n", portc->audio_format);
-
- devc->xfer_count = 0;
- spin_unlock_irqrestore(&waveartist_lock, flags);
- waveartist_halt_input(dev);
-
- if (debug_flg & DEBUG_INTR) {
- printk("WA CTLR reg: 0x%02X.\n",
- inb(devc->hw.io_base + CTLR));
- printk("WA STAT reg: 0x%02X.\n",
- inb(devc->hw.io_base + STATR));
- printk("WA IRQS reg: 0x%02X.\n",
- inb(devc->hw.io_base + IRQSTAT));
- }
-
- return 0;
-}
-
-static int
-waveartist_prepare_for_output(int dev, int bsize, int bcount)
-{
- unsigned long flags;
- wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc;
- wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
- unsigned int speed, bits;
-
- /*
- * program the speed, channels, bits
- */
- speed = waveartist_get_speed(portc);
- bits = waveartist_get_bits(portc);
-
- spin_lock_irqsave(&waveartist_lock, flags);
-
- if (waveartist_cmd2(devc, WACMD_OUTPUTSPEED, speed) &&
- waveartist_cmd2(devc, WACMD_OUTPUTSPEED, speed))
- printk(KERN_WARNING "waveartist: error setting the playback "
- "speed to %dHz.\n", portc->speed);
-
- if (waveartist_cmd2(devc, WACMD_OUTPUTCHANNELS, portc->channels))
- printk(KERN_WARNING "waveartist: error setting the playback "
- "to %d channels\n", portc->channels);
-
- if (waveartist_cmd2(devc, WACMD_OUTPUTDMA, 0))
- printk(KERN_WARNING "waveartist: error setting the playback "
- "data path to 0x%X\n", 0);
-
- if (waveartist_cmd2(devc, WACMD_OUTPUTFORMAT, bits))
- printk(KERN_WARNING "waveartist: error setting the playback "
- "format to %d\n", portc->audio_format);
-
- devc->xfer_count = 0;
- spin_unlock_irqrestore(&waveartist_lock, flags);
- waveartist_halt_output(dev);
-
- if (debug_flg & DEBUG_INTR) {
- printk("WA CTLR reg: 0x%02X.\n",inb(devc->hw.io_base + CTLR));
- printk("WA STAT reg: 0x%02X.\n",inb(devc->hw.io_base + STATR));
- printk("WA IRQS reg: 0x%02X.\n",inb(devc->hw.io_base + IRQSTAT));
- }
-
- return 0;
-}
-
-static void
-waveartist_halt(int dev)
-{
- wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
- wavnc_info *devc;
-
- if (portc->open_mode & OPEN_WRITE)
- waveartist_halt_output(dev);
-
- if (portc->open_mode & OPEN_READ)
- waveartist_halt_input(dev);
-
- devc = (wavnc_info *) audio_devs[dev]->devc;
- devc->audio_mode = 0;
-}
-
-static void
-waveartist_halt_input(int dev)
-{
- wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc;
- unsigned long flags;
-
- spin_lock_irqsave(&waveartist_lock, flags);
-
- /*
- * Stop capture
- */
- waveartist_cmd1(devc, WACMD_INPUTSTOP);
-
- devc->audio_mode &= ~PCM_ENABLE_INPUT;
-
- /*
- * Clear interrupt by toggling
- * the IRQ_ACK bit in CTRL
- */
- if (inb(devc->hw.io_base + STATR) & IRQ_REQ)
- waveartist_iack(devc);
-
-// devc->audio_mode &= ~PCM_ENABLE_INPUT;
-
- spin_unlock_irqrestore(&waveartist_lock, flags);
-}
-
-static void
-waveartist_halt_output(int dev)
-{
- wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc;
- unsigned long flags;
-
- spin_lock_irqsave(&waveartist_lock, flags);
-
- waveartist_cmd1(devc, WACMD_OUTPUTSTOP);
-
- devc->audio_mode &= ~PCM_ENABLE_OUTPUT;
-
- /*
- * Clear interrupt by toggling
- * the IRQ_ACK bit in CTRL
- */
- if (inb(devc->hw.io_base + STATR) & IRQ_REQ)
- waveartist_iack(devc);
-
-// devc->audio_mode &= ~PCM_ENABLE_OUTPUT;
-
- spin_unlock_irqrestore(&waveartist_lock, flags);
-}
-
-static void
-waveartist_trigger(int dev, int state)
-{
- wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc;
- wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
- unsigned long flags;
-
- if (debug_flg & DEBUG_TRIGGER) {
- printk("wavnc: audio trigger ");
- if (state & PCM_ENABLE_INPUT)
- printk("in ");
- if (state & PCM_ENABLE_OUTPUT)
- printk("out");
- printk("\n");
- }
-
- spin_lock_irqsave(&waveartist_lock, flags);
-
- state &= devc->audio_mode;
-
- if (portc->open_mode & OPEN_READ &&
- state & PCM_ENABLE_INPUT)
- /*
- * enable ADC Data Transfer to PC
- */
- waveartist_cmd1(devc, WACMD_INPUTSTART);
-
- if (portc->open_mode & OPEN_WRITE &&
- state & PCM_ENABLE_OUTPUT)
- /*
- * enable DAC data transfer from PC
- */
- waveartist_cmd1(devc, WACMD_OUTPUTSTART);
-
- spin_unlock_irqrestore(&waveartist_lock, flags);
-}
-
-static int
-waveartist_set_speed(int dev, int arg)
-{
- wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
-
- if (arg <= 0)
- return portc->speed;
-
- if (arg < 5000)
- arg = 5000;
- if (arg > 44100)
- arg = 44100;
-
- portc->speed = arg;
- return portc->speed;
-
-}
-
-static short
-waveartist_set_channels(int dev, short arg)
-{
- wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
-
- if (arg != 1 && arg != 2)
- return portc->channels;
-
- portc->channels = arg;
- return arg;
-}
-
-static unsigned int
-waveartist_set_bits(int dev, unsigned int arg)
-{
- wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
-
- if (arg == 0)
- return portc->audio_format;
-
- if ((arg != AFMT_U8) && (arg != AFMT_S16_LE) && (arg != AFMT_S8))
- arg = AFMT_U8;
-
- portc->audio_format = arg;
-
- return arg;
-}
-
-static struct audio_driver waveartist_audio_driver = {
- .owner = THIS_MODULE,
- .open = waveartist_open,
- .close = waveartist_close,
- .output_block = waveartist_output_block,
- .start_input = waveartist_start_input,
- .ioctl = waveartist_ioctl,
- .prepare_for_input = waveartist_prepare_for_input,
- .prepare_for_output = waveartist_prepare_for_output,
- .halt_io = waveartist_halt,
- .halt_input = waveartist_halt_input,
- .halt_output = waveartist_halt_output,
- .trigger = waveartist_trigger,
- .set_speed = waveartist_set_speed,
- .set_bits = waveartist_set_bits,
- .set_channels = waveartist_set_channels
-};
-
-
-static irqreturn_t
-waveartist_intr(int irq, void *dev_id)
-{
- wavnc_info *devc = dev_id;
- int irqstatus, status;
-
- spin_lock(&waveartist_lock);
- irqstatus = inb(devc->hw.io_base + IRQSTAT);
- status = inb(devc->hw.io_base + STATR);
-
- if (debug_flg & DEBUG_INTR)
- printk("waveartist_intr: stat=%02x, irqstat=%02x\n",
- status, irqstatus);
-
- if (status & IRQ_REQ) /* Clear interrupt */
- waveartist_iack(devc);
- else
- printk(KERN_WARNING "waveartist: unexpected interrupt\n");
-
- if (irqstatus & 0x01) {
- int temp = 1;
-
- /* PCM buffer done
- */
- if ((status & DMA0) && (devc->audio_mode & PCM_ENABLE_OUTPUT)) {
- DMAbuf_outputintr(devc->playback_dev, 1);
- temp = 0;
- }
- if ((status & DMA1) && (devc->audio_mode & PCM_ENABLE_INPUT)) {
- DMAbuf_inputintr(devc->record_dev);
- temp = 0;
- }
- if (temp) //default:
- printk(KERN_WARNING "waveartist: Unknown interrupt\n");
- }
- if (irqstatus & 0x2)
- // We do not use SB mode natively...
- printk(KERN_WARNING "waveartist: Unexpected SB interrupt...\n");
- spin_unlock(&waveartist_lock);
- return IRQ_HANDLED;
-}
-
-/* -------------------------------------------------------------------------
- * Mixer stuff
- */
-struct mix_ent {
- unsigned char reg_l;
- unsigned char reg_r;
- unsigned char shift;
- unsigned char max;
-};
-
-static const struct mix_ent mix_devs[SOUND_MIXER_NRDEVICES] = {
- { 2, 6, 1, 7 }, /* SOUND_MIXER_VOLUME */
- { 0, 0, 0, 0 }, /* SOUND_MIXER_BASS */
- { 0, 0, 0, 0 }, /* SOUND_MIXER_TREBLE */
- { 0, 0, 0, 0 }, /* SOUND_MIXER_SYNTH */
- { 0, 0, 0, 0 }, /* SOUND_MIXER_PCM */
- { 0, 0, 0, 0 }, /* SOUND_MIXER_SPEAKER */
- { 0, 4, 6, 31 }, /* SOUND_MIXER_LINE */
- { 2, 6, 4, 3 }, /* SOUND_MIXER_MIC */
- { 0, 0, 0, 0 }, /* SOUND_MIXER_CD */
- { 0, 0, 0, 0 }, /* SOUND_MIXER_IMIX */
- { 0, 0, 0, 0 }, /* SOUND_MIXER_ALTPCM */
-#if 0
- { 3, 7, 0, 10 }, /* SOUND_MIXER_RECLEV */
- { 0, 0, 0, 0 }, /* SOUND_MIXER_IGAIN */
-#else
- { 0, 0, 0, 0 }, /* SOUND_MIXER_RECLEV */
- { 3, 7, 0, 7 }, /* SOUND_MIXER_IGAIN */
-#endif
- { 0, 0, 0, 0 }, /* SOUND_MIXER_OGAIN */
- { 0, 4, 1, 31 }, /* SOUND_MIXER_LINE1 */
- { 1, 5, 6, 31 }, /* SOUND_MIXER_LINE2 */
- { 0, 0, 0, 0 }, /* SOUND_MIXER_LINE3 */
- { 0, 0, 0, 0 }, /* SOUND_MIXER_DIGITAL1 */
- { 0, 0, 0, 0 }, /* SOUND_MIXER_DIGITAL2 */
- { 0, 0, 0, 0 }, /* SOUND_MIXER_DIGITAL3 */
- { 0, 0, 0, 0 }, /* SOUND_MIXER_PHONEIN */
- { 0, 0, 0, 0 }, /* SOUND_MIXER_PHONEOUT */
- { 0, 0, 0, 0 }, /* SOUND_MIXER_VIDEO */
- { 0, 0, 0, 0 }, /* SOUND_MIXER_RADIO */
- { 0, 0, 0, 0 } /* SOUND_MIXER_MONITOR */
-};
-
-static void
-waveartist_mixer_update(wavnc_info *devc, int whichDev)
-{
- unsigned int lev_left, lev_right;
-
- lev_left = devc->levels[whichDev] & 0xff;
- lev_right = devc->levels[whichDev] >> 8;
-
- if (lev_left > 100)
- lev_left = 100;
- if (lev_right > 100)
- lev_right = 100;
-
-#define SCALE(lev,max) ((lev) * (max) / 100)
-
- if (machine_is_netwinder() && whichDev == SOUND_MIXER_PHONEOUT)
- whichDev = SOUND_MIXER_VOLUME;
-
- if (mix_devs[whichDev].reg_l || mix_devs[whichDev].reg_r) {
- const struct mix_ent *mix = mix_devs + whichDev;
- unsigned int mask, left, right;
-
- mask = mix->max << mix->shift;
- lev_left = SCALE(lev_left, mix->max) << mix->shift;
- lev_right = SCALE(lev_right, mix->max) << mix->shift;
-
- /* read left setting */
- left = waveartist_cmd1_r(devc, WACMD_GET_LEVEL |
- mix->reg_l << 8);
-
- /* read right setting */
- right = waveartist_cmd1_r(devc, WACMD_GET_LEVEL |
- mix->reg_r << 8);
-
- left = (left & ~mask) | (lev_left & mask);
- right = (right & ~mask) | (lev_right & mask);
-
- /* write left,right back */
- waveartist_cmd3(devc, WACMD_SET_MIXER, left, right);
- } else {
- switch(whichDev) {
- case SOUND_MIXER_PCM:
- waveartist_cmd3(devc, WACMD_SET_LEVEL,
- SCALE(lev_left, 32767),
- SCALE(lev_right, 32767));
- break;
-
- case SOUND_MIXER_SYNTH:
- waveartist_cmd3(devc, 0x0100 | WACMD_SET_LEVEL,
- SCALE(lev_left, 32767),
- SCALE(lev_right, 32767));
- break;
- }
- }
-}
-
-/*
- * Set the ADC MUX to the specified values. We do NOT do any
- * checking of the values passed, since we assume that the
- * relevant *_select_input function has done that for us.
- */
-static void
-waveartist_set_adc_mux(wavnc_info *devc, char left_dev, char right_dev)
-{
- unsigned int reg_08, reg_09;
-
- reg_08 = waveartist_cmd1_r(devc, WACMD_GET_LEVEL | 0x0800);
- reg_09 = waveartist_cmd1_r(devc, WACMD_GET_LEVEL | 0x0900);
-
- reg_08 = (reg_08 & ~0x3f) | right_dev << 3 | left_dev;
-
- waveartist_cmd3(devc, WACMD_SET_MIXER, reg_08, reg_09);
-}
-
-/*
- * Decode a recording mask into a mixer selection as follows:
- *
- * OSS Source WA Source Actual source
- * SOUND_MASK_IMIX Mixer Mixer output (same as AD1848)
- * SOUND_MASK_LINE Line Line in
- * SOUND_MASK_LINE1 Aux 1 Aux 1 in
- * SOUND_MASK_LINE2 Aux 2 Aux 2 in
- * SOUND_MASK_MIC Mic Microphone
- */
-static unsigned int
-waveartist_select_input(wavnc_info *devc, unsigned int recmask,
- unsigned char *dev_l, unsigned char *dev_r)
-{
- unsigned int recdev = ADC_MUX_NONE;
-
- if (recmask & SOUND_MASK_IMIX) {
- recmask = SOUND_MASK_IMIX;
- recdev = ADC_MUX_MIXER;
- } else if (recmask & SOUND_MASK_LINE2) {
- recmask = SOUND_MASK_LINE2;
- recdev = ADC_MUX_AUX2;
- } else if (recmask & SOUND_MASK_LINE1) {
- recmask = SOUND_MASK_LINE1;
- recdev = ADC_MUX_AUX1;
- } else if (recmask & SOUND_MASK_LINE) {
- recmask = SOUND_MASK_LINE;
- recdev = ADC_MUX_LINE;
- } else if (recmask & SOUND_MASK_MIC) {
- recmask = SOUND_MASK_MIC;
- recdev = ADC_MUX_MIC;
- }
-
- *dev_l = *dev_r = recdev;
-
- return recmask;
-}
-
-static int
-waveartist_decode_mixer(wavnc_info *devc, int dev, unsigned char lev_l,
- unsigned char lev_r)
-{
- switch (dev) {
- case SOUND_MIXER_VOLUME:
- case SOUND_MIXER_SYNTH:
- case SOUND_MIXER_PCM:
- case SOUND_MIXER_LINE:
- case SOUND_MIXER_MIC:
- case SOUND_MIXER_IGAIN:
- case SOUND_MIXER_LINE1:
- case SOUND_MIXER_LINE2:
- devc->levels[dev] = lev_l | lev_r << 8;
- break;
-
- case SOUND_MIXER_IMIX:
- break;
-
- default:
- dev = -EINVAL;
- break;
- }
-
- return dev;
-}
-
-static int waveartist_get_mixer(wavnc_info *devc, int dev)
-{
- return devc->levels[dev];
-}
-
-static const struct waveartist_mixer_info waveartist_mixer = {
- .supported_devs = SUPPORTED_MIXER_DEVICES | SOUND_MASK_IGAIN,
- .recording_devs = SOUND_MASK_LINE | SOUND_MASK_MIC |
- SOUND_MASK_LINE1 | SOUND_MASK_LINE2 |
- SOUND_MASK_IMIX,
- .stereo_devs = (SUPPORTED_MIXER_DEVICES | SOUND_MASK_IGAIN) & ~
- (SOUND_MASK_SPEAKER | SOUND_MASK_IMIX),
- .select_input = waveartist_select_input,
- .decode_mixer = waveartist_decode_mixer,
- .get_mixer = waveartist_get_mixer,
-};
-
-static void
-waveartist_set_recmask(wavnc_info *devc, unsigned int recmask)
-{
- unsigned char dev_l, dev_r;
-
- recmask &= devc->mix->recording_devs;
-
- /*
- * If more than one recording device selected,
- * disable the device that is currently in use.
- */
- if (hweight32(recmask) > 1)
- recmask &= ~devc->recmask;
-
- /*
- * Translate the recording device mask into
- * the ADC multiplexer settings.
- */
- devc->recmask = devc->mix->select_input(devc, recmask,
- &dev_l, &dev_r);
-
- waveartist_set_adc_mux(devc, dev_l, dev_r);
-}
-
-static int
-waveartist_set_mixer(wavnc_info *devc, int dev, unsigned int level)
-{
- unsigned int lev_left = level & 0x00ff;
- unsigned int lev_right = (level & 0xff00) >> 8;
-
- if (lev_left > 100)
- lev_left = 100;
- if (lev_right > 100)
- lev_right = 100;
-
- /*
- * Mono devices have their right volume forced to their
- * left volume. (from ALSA driver OSS emulation).
- */
- if (!(devc->mix->stereo_devs & (1 << dev)))
- lev_right = lev_left;
-
- dev = devc->mix->decode_mixer(devc, dev, lev_left, lev_right);
-
- if (dev >= 0)
- waveartist_mixer_update(devc, dev);
-
- return dev < 0 ? dev : 0;
-}
-
-static int
-waveartist_mixer_ioctl(int dev, unsigned int cmd, void __user * arg)
-{
- wavnc_info *devc = (wavnc_info *)audio_devs[dev]->devc;
- int ret = 0, val, nr;
-
- /*
- * All SOUND_MIXER_* ioctls use type 'M'
- */
- if (((cmd >> 8) & 255) != 'M')
- return -ENOIOCTLCMD;
-
-#ifdef CONFIG_ARCH_NETWINDER
- if (machine_is_netwinder()) {
- ret = vnc_private_ioctl(dev, cmd, arg);
- if (ret != -ENOIOCTLCMD)
- return ret;
- else
- ret = 0;
- }
-#endif
-
- nr = cmd & 0xff;
-
- if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
- if (get_user(val, (int __user *)arg))
- return -EFAULT;
-
- switch (nr) {
- case SOUND_MIXER_RECSRC:
- waveartist_set_recmask(devc, val);
- break;
-
- default:
- ret = -EINVAL;
- if (nr < SOUND_MIXER_NRDEVICES &&
- devc->mix->supported_devs & (1 << nr))
- ret = waveartist_set_mixer(devc, nr, val);
- }
- }
-
- if (ret == 0 && _SIOC_DIR(cmd) & _SIOC_READ) {
- ret = -EINVAL;
-
- switch (nr) {
- case SOUND_MIXER_RECSRC:
- ret = devc->recmask;
- break;
-
- case SOUND_MIXER_DEVMASK:
- ret = devc->mix->supported_devs;
- break;
-
- case SOUND_MIXER_STEREODEVS:
- ret = devc->mix->stereo_devs;
- break;
-
- case SOUND_MIXER_RECMASK:
- ret = devc->mix->recording_devs;
- break;
-
- case SOUND_MIXER_CAPS:
- ret = SOUND_CAP_EXCL_INPUT;
- break;
-
- default:
- if (nr < SOUND_MIXER_NRDEVICES)
- ret = devc->mix->get_mixer(devc, nr);
- break;
- }
-
- if (ret >= 0)
- ret = put_user(ret, (int __user *)arg) ? -EFAULT : 0;
- }
-
- return ret;
-}
-
-static struct mixer_operations waveartist_mixer_operations =
-{
- .owner = THIS_MODULE,
- .id = "WaveArtist",
- .name = "WaveArtist",
- .ioctl = waveartist_mixer_ioctl
-};
-
-static void
-waveartist_mixer_reset(wavnc_info *devc)
-{
- int i;
-
- if (debug_flg & DEBUG_MIXER)
- printk("%s: mixer_reset\n", devc->hw.name);
-
- /*
- * reset mixer cmd
- */
- waveartist_cmd1(devc, WACMD_RST_MIXER);
-
- /*
- * set input for ADC to come from 'quiet'
- * turn on default modes
- */
- waveartist_cmd3(devc, WACMD_SET_MIXER, 0x9800, 0xa836);
-
- /*
- * set mixer input select to none, RX filter gains 0 dB
- */
- waveartist_cmd3(devc, WACMD_SET_MIXER, 0x4c00, 0x8c00);
-
- /*
- * set bit 0 reg 2 to 1 - unmute MonoOut
- */
- waveartist_cmd3(devc, WACMD_SET_MIXER, 0x2801, 0x6800);
-
- /* set default input device = internal mic
- * current recording device = none
- */
- waveartist_set_recmask(devc, 0);
-
- for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
- waveartist_mixer_update(devc, i);
-}
-
-static int __init waveartist_init(wavnc_info *devc)
-{
- wavnc_port_info *portc;
- char rev[3], dev_name[64];
- int my_dev;
-
- if (waveartist_reset(devc))
- return -ENODEV;
-
- sprintf(dev_name, "%s (%s", devc->hw.name, devc->chip_name);
-
- if (waveartist_getrev(devc, rev)) {
- strcat(dev_name, " rev. ");
- strcat(dev_name, rev);
- }
- strcat(dev_name, ")");
-
- conf_printf2(dev_name, devc->hw.io_base, devc->hw.irq,
- devc->hw.dma, devc->hw.dma2);
-
- portc = kzalloc(sizeof(wavnc_port_info), GFP_KERNEL);
- if (portc == NULL)
- goto nomem;
-
- my_dev = sound_install_audiodrv(AUDIO_DRIVER_VERSION, dev_name,
- &waveartist_audio_driver, sizeof(struct audio_driver),
- devc->audio_flags, AFMT_U8 | AFMT_S16_LE | AFMT_S8,
- devc, devc->hw.dma, devc->hw.dma2);
-
- if (my_dev < 0)
- goto free;
-
- audio_devs[my_dev]->portc = portc;
-
- waveartist_mixer_reset(devc);
-
- /*
- * clear any pending interrupt
- */
- waveartist_iack(devc);
-
- if (request_irq(devc->hw.irq, waveartist_intr, 0, devc->hw.name, devc) < 0) {
- printk(KERN_ERR "%s: IRQ %d in use\n",
- devc->hw.name, devc->hw.irq);
- goto uninstall;
- }
-
- if (sound_alloc_dma(devc->hw.dma, devc->hw.name)) {
- printk(KERN_ERR "%s: Can't allocate DMA%d\n",
- devc->hw.name, devc->hw.dma);
- goto uninstall_irq;
- }
-
- if (devc->hw.dma != devc->hw.dma2 && devc->hw.dma2 != NO_DMA)
- if (sound_alloc_dma(devc->hw.dma2, devc->hw.name)) {
- printk(KERN_ERR "%s: can't allocate DMA%d\n",
- devc->hw.name, devc->hw.dma2);
- goto uninstall_dma;
- }
-
- waveartist_set_ctlr(&devc->hw, 0, DMA1_IE | DMA0_IE);
-
- audio_devs[my_dev]->mixer_dev =
- sound_install_mixer(MIXER_DRIVER_VERSION,
- dev_name,
- &waveartist_mixer_operations,
- sizeof(struct mixer_operations),
- devc);
-
- return my_dev;
-
-uninstall_dma:
- sound_free_dma(devc->hw.dma);
-
-uninstall_irq:
- free_irq(devc->hw.irq, devc);
-
-uninstall:
- sound_unload_audiodev(my_dev);
-
-free:
- kfree(portc);
-
-nomem:
- return -1;
-}
-
-static int __init probe_waveartist(struct address_info *hw_config)
-{
- wavnc_info *devc = &adev_info[nr_waveartist_devs];
-
- if (nr_waveartist_devs >= MAX_AUDIO_DEV) {
- printk(KERN_WARNING "waveartist: too many audio devices\n");
- return 0;
- }
-
- if (!request_region(hw_config->io_base, 15, hw_config->name)) {
- printk(KERN_WARNING "WaveArtist: I/O port conflict\n");
- return 0;
- }
-
- if (hw_config->irq > 15 || hw_config->irq < 0) {
- release_region(hw_config->io_base, 15);
- printk(KERN_WARNING "WaveArtist: Bad IRQ %d\n",
- hw_config->irq);
- return 0;
- }
-
- if (hw_config->dma != 3) {
- release_region(hw_config->io_base, 15);
- printk(KERN_WARNING "WaveArtist: Bad DMA %d\n",
- hw_config->dma);
- return 0;
- }
-
- hw_config->name = "WaveArtist";
- devc->hw = *hw_config;
- devc->open_mode = 0;
- devc->chip_name = "RWA-010";
-
- return 1;
-}
-
-static void __init
-attach_waveartist(struct address_info *hw, const struct waveartist_mixer_info *mix)
-{
- wavnc_info *devc = &adev_info[nr_waveartist_devs];
-
- /*
- * NOTE! If irq < 0, there is another driver which has allocated the
- * IRQ so that this driver doesn't need to allocate/deallocate it.
- * The actually used IRQ is ABS(irq).
- */
- devc->hw = *hw;
- devc->hw.irq = (hw->irq > 0) ? hw->irq : 0;
- devc->open_mode = 0;
- devc->playback_dev = 0;
- devc->record_dev = 0;
- devc->audio_flags = DMA_AUTOMODE;
- devc->levels = levels;
-
- if (hw->dma != hw->dma2 && hw->dma2 != NO_DMA)
- devc->audio_flags |= DMA_DUPLEX;
-
- devc->mix = mix;
- devc->dev_no = waveartist_init(devc);
-
- if (devc->dev_no < 0)
- release_region(hw->io_base, 15);
- else {
-#ifdef CONFIG_ARCH_NETWINDER
- if (machine_is_netwinder()) {
- init_timer(&vnc_timer);
- vnc_timer.function = vnc_slider_tick;
- vnc_timer.expires = jiffies;
- vnc_timer.data = nr_waveartist_devs;
- add_timer(&vnc_timer);
-
- vnc_configure_mixer(devc, 0);
-
- devc->no_autoselect = 1;
- }
-#endif
- nr_waveartist_devs += 1;
- }
-}
-
-static void __exit unload_waveartist(struct address_info *hw)
-{
- wavnc_info *devc = NULL;
- int i;
-
- for (i = 0; i < nr_waveartist_devs; i++)
- if (hw->io_base == adev_info[i].hw.io_base) {
- devc = adev_info + i;
- break;
- }
-
- if (devc != NULL) {
- int mixer;
-
-#ifdef CONFIG_ARCH_NETWINDER
- if (machine_is_netwinder())
- del_timer(&vnc_timer);
-#endif
-
- release_region(devc->hw.io_base, 15);
-
- waveartist_set_ctlr(&devc->hw, DMA1_IE|DMA0_IE, 0);
-
- if (devc->hw.irq >= 0)
- free_irq(devc->hw.irq, devc);
-
- sound_free_dma(devc->hw.dma);
-
- if (devc->hw.dma != devc->hw.dma2 &&
- devc->hw.dma2 != NO_DMA)
- sound_free_dma(devc->hw.dma2);
-
- mixer = audio_devs[devc->dev_no]->mixer_dev;
-
- if (mixer >= 0)
- sound_unload_mixerdev(mixer);
-
- if (devc->dev_no >= 0)
- sound_unload_audiodev(devc->dev_no);
-
- nr_waveartist_devs -= 1;
-
- for (; i < nr_waveartist_devs; i++)
- adev_info[i] = adev_info[i + 1];
- } else
- printk(KERN_WARNING "waveartist: can't find device "
- "to unload\n");
-}
-
-#ifdef CONFIG_ARCH_NETWINDER
-
-/*
- * Rebel.com Netwinder specifics...
- */
-
-#include <asm/hardware/dec21285.h>
-
-#define VNC_TIMER_PERIOD (HZ/4) //check slider 4 times/sec
-
-#define MIXER_PRIVATE3_RESET 0x53570000
-#define MIXER_PRIVATE3_READ 0x53570001
-#define MIXER_PRIVATE3_WRITE 0x53570002
-
-#define VNC_MUTE_INTERNAL_SPKR 0x01 //the sw mute on/off control bit
-#define VNC_MUTE_LINE_OUT 0x10
-#define VNC_PHONE_DETECT 0x20
-#define VNC_HANDSET_DETECT 0x40
-#define VNC_DISABLE_AUTOSWITCH 0x80
-
-static inline void
-vnc_mute_spkr(wavnc_info *devc)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&nw_gpio_lock, flags);
- nw_cpld_modify(CPLD_UNMUTE, devc->spkr_mute_state ? 0 : CPLD_UNMUTE);
- spin_unlock_irqrestore(&nw_gpio_lock, flags);
-}
-
-static void
-vnc_mute_lout(wavnc_info *devc)
-{
- unsigned int left, right;
-
- left = waveartist_cmd1_r(devc, WACMD_GET_LEVEL);
- right = waveartist_cmd1_r(devc, WACMD_GET_LEVEL | 0x400);
-
- if (devc->line_mute_state) {
- left &= ~1;
- right &= ~1;
- } else {
- left |= 1;
- right |= 1;
- }
- waveartist_cmd3(devc, WACMD_SET_MIXER, left, right);
-
-}
-
-static int
-vnc_volume_slider(wavnc_info *devc)
-{
- static signed int old_slider_volume;
- unsigned long flags;
- signed int volume = 255;
-
- *CSR_TIMER1_LOAD = 0x00ffffff;
-
- spin_lock_irqsave(&waveartist_lock, flags);
-
- outb(0xFF, 0x201);
- *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV1;
-
- while (volume && (inb(0x201) & 0x01))
- volume--;
-
- *CSR_TIMER1_CNTL = 0;
-
- spin_unlock_irqrestore(&waveartist_lock,flags);
-
- volume = 0x00ffffff - *CSR_TIMER1_VALUE;
-
-
-#ifndef REVERSE
- volume = 150 - (volume >> 5);
-#else
- volume = (volume >> 6) - 25;
-#endif
-
- if (volume < 0)
- volume = 0;
-
- if (volume > 100)
- volume = 100;
-
- /*
- * slider quite often reads +-8, so debounce this random noise
- */
- if (abs(volume - old_slider_volume) > 7) {
- old_slider_volume = volume;
-
- if (debug_flg & DEBUG_MIXER)
- printk(KERN_DEBUG "Slider volume: %d.\n", volume);
- }
-
- return old_slider_volume;
-}
-
-/*
- * Decode a recording mask into a mixer selection on the NetWinder
- * as follows:
- *
- * OSS Source WA Source Actual source
- * SOUND_MASK_IMIX Mixer Mixer output (same as AD1848)
- * SOUND_MASK_LINE Line Line in
- * SOUND_MASK_LINE1 Left Mic Handset
- * SOUND_MASK_PHONEIN Left Aux Telephone microphone
- * SOUND_MASK_MIC Right Mic Builtin microphone
- */
-static unsigned int
-netwinder_select_input(wavnc_info *devc, unsigned int recmask,
- unsigned char *dev_l, unsigned char *dev_r)
-{
- unsigned int recdev_l = ADC_MUX_NONE, recdev_r = ADC_MUX_NONE;
-
- if (recmask & SOUND_MASK_IMIX) {
- recmask = SOUND_MASK_IMIX;
- recdev_l = ADC_MUX_MIXER;
- recdev_r = ADC_MUX_MIXER;
- } else if (recmask & SOUND_MASK_LINE) {
- recmask = SOUND_MASK_LINE;
- recdev_l = ADC_MUX_LINE;
- recdev_r = ADC_MUX_LINE;
- } else if (recmask & SOUND_MASK_LINE1) {
- recmask = SOUND_MASK_LINE1;
- waveartist_cmd1(devc, WACMD_SET_MONO); /* left */
- recdev_l = ADC_MUX_MIC;
- recdev_r = ADC_MUX_NONE;
- } else if (recmask & SOUND_MASK_PHONEIN) {
- recmask = SOUND_MASK_PHONEIN;
- waveartist_cmd1(devc, WACMD_SET_MONO); /* left */
- recdev_l = ADC_MUX_AUX1;
- recdev_r = ADC_MUX_NONE;
- } else if (recmask & SOUND_MASK_MIC) {
- recmask = SOUND_MASK_MIC;
- waveartist_cmd1(devc, WACMD_SET_MONO | 0x100); /* right */
- recdev_l = ADC_MUX_NONE;
- recdev_r = ADC_MUX_MIC;
- }
-
- *dev_l = recdev_l;
- *dev_r = recdev_r;
-
- return recmask;
-}
-
-static int
-netwinder_decode_mixer(wavnc_info *devc, int dev, unsigned char lev_l,
- unsigned char lev_r)
-{
- switch (dev) {
- case SOUND_MIXER_VOLUME:
- case SOUND_MIXER_SYNTH:
- case SOUND_MIXER_PCM:
- case SOUND_MIXER_LINE:
- case SOUND_MIXER_IGAIN:
- devc->levels[dev] = lev_l | lev_r << 8;
- break;
-
- case SOUND_MIXER_MIC: /* right mic only */
- devc->levels[SOUND_MIXER_MIC] &= 0xff;
- devc->levels[SOUND_MIXER_MIC] |= lev_l << 8;
- break;
-
- case SOUND_MIXER_LINE1: /* left mic only */
- devc->levels[SOUND_MIXER_MIC] &= 0xff00;
- devc->levels[SOUND_MIXER_MIC] |= lev_l;
- dev = SOUND_MIXER_MIC;
- break;
-
- case SOUND_MIXER_PHONEIN: /* left aux only */
- devc->levels[SOUND_MIXER_LINE1] = lev_l;
- dev = SOUND_MIXER_LINE1;
- break;
-
- case SOUND_MIXER_IMIX:
- case SOUND_MIXER_PHONEOUT:
- break;
-
- default:
- dev = -EINVAL;
- break;
- }
- return dev;
-}
-
-static int netwinder_get_mixer(wavnc_info *devc, int dev)
-{
- int levels;
-
- switch (dev) {
- case SOUND_MIXER_VOLUME:
- case SOUND_MIXER_SYNTH:
- case SOUND_MIXER_PCM:
- case SOUND_MIXER_LINE:
- case SOUND_MIXER_IGAIN:
- levels = devc->levels[dev];
- break;
-
- case SOUND_MIXER_MIC: /* builtin mic: right mic only */
- levels = devc->levels[SOUND_MIXER_MIC] >> 8;
- levels |= levels << 8;
- break;
-
- case SOUND_MIXER_LINE1: /* handset mic: left mic only */
- levels = devc->levels[SOUND_MIXER_MIC] & 0xff;
- levels |= levels << 8;
- break;
-
- case SOUND_MIXER_PHONEIN: /* phone mic: left aux1 only */
- levels = devc->levels[SOUND_MIXER_LINE1] & 0xff;
- levels |= levels << 8;
- break;
-
- default:
- levels = 0;
- }
-
- return levels;
-}
-
-/*
- * Waveartist specific mixer information.
- */
-static const struct waveartist_mixer_info netwinder_mixer = {
- .supported_devs = SOUND_MASK_VOLUME | SOUND_MASK_SYNTH |
- SOUND_MASK_PCM | SOUND_MASK_SPEAKER |
- SOUND_MASK_LINE | SOUND_MASK_MIC |
- SOUND_MASK_IMIX | SOUND_MASK_LINE1 |
- SOUND_MASK_PHONEIN | SOUND_MASK_PHONEOUT|
- SOUND_MASK_IGAIN,
-
- .recording_devs = SOUND_MASK_LINE | SOUND_MASK_MIC |
- SOUND_MASK_IMIX | SOUND_MASK_LINE1 |
- SOUND_MASK_PHONEIN,
-
- .stereo_devs = SOUND_MASK_VOLUME | SOUND_MASK_SYNTH |
- SOUND_MASK_PCM | SOUND_MASK_LINE |
- SOUND_MASK_IMIX | SOUND_MASK_IGAIN,
-
- .select_input = netwinder_select_input,
- .decode_mixer = netwinder_decode_mixer,
- .get_mixer = netwinder_get_mixer,
-};
-
-static void
-vnc_configure_mixer(wavnc_info *devc, unsigned int recmask)
-{
- if (!devc->no_autoselect) {
- if (devc->handset_detect) {
- recmask = SOUND_MASK_LINE1;
- devc->spkr_mute_state = devc->line_mute_state = 1;
- } else if (devc->telephone_detect) {
- recmask = SOUND_MASK_PHONEIN;
- devc->spkr_mute_state = devc->line_mute_state = 1;
- } else {
- /* unless someone has asked for LINE-IN,
- * we default to MIC
- */
- if ((devc->recmask & SOUND_MASK_LINE) == 0)
- devc->recmask = SOUND_MASK_MIC;
- devc->spkr_mute_state = devc->line_mute_state = 0;
- }
- vnc_mute_spkr(devc);
- vnc_mute_lout(devc);
-
- if (recmask != devc->recmask)
- waveartist_set_recmask(devc, recmask);
- }
-}
-
-static int
-vnc_slider(wavnc_info *devc)
-{
- signed int slider_volume;
- unsigned int temp, old_hs, old_td;
-
- /*
- * read the "buttons" state.
- * Bit 4 = 0 means handset present
- * Bit 5 = 1 means phone offhook
- */
- temp = inb(0x201);
-
- old_hs = devc->handset_detect;
- old_td = devc->telephone_detect;
-
- devc->handset_detect = !(temp & 0x10);
- devc->telephone_detect = !!(temp & 0x20);
-
- if (!devc->no_autoselect &&
- (old_hs != devc->handset_detect ||
- old_td != devc->telephone_detect))
- vnc_configure_mixer(devc, devc->recmask);
-
- slider_volume = vnc_volume_slider(devc);
-
- /*
- * If we're using software controlled volume, and
- * the slider moves by more than 20%, then we
- * switch back to slider controlled volume.
- */
- if (abs(devc->slider_vol - slider_volume) > 20)
- devc->use_slider = 1;
-
- /*
- * use only left channel
- */
- temp = levels[SOUND_MIXER_VOLUME] & 0xFF;
-
- if (slider_volume != temp && devc->use_slider) {
- devc->slider_vol = slider_volume;
-
- waveartist_set_mixer(devc, SOUND_MIXER_VOLUME,
- slider_volume | slider_volume << 8);
-
- return 1;
- }
-
- return 0;
-}
-
-static void
-vnc_slider_tick(unsigned long data)
-{
- int next_timeout;
-
- if (vnc_slider(adev_info + data))
- next_timeout = 5; // mixer reported change
- else
- next_timeout = VNC_TIMER_PERIOD;
-
- mod_timer(&vnc_timer, jiffies + next_timeout);
-}
-
-static int
-vnc_private_ioctl(int dev, unsigned int cmd, int __user * arg)
-{
- wavnc_info *devc = (wavnc_info *)audio_devs[dev]->devc;
- int val;
-
- switch (cmd) {
- case SOUND_MIXER_PRIVATE1:
- {
- u_int prev_spkr_mute, prev_line_mute, prev_auto_state;
- int val;
-
- if (get_user(val, arg))
- return -EFAULT;
-
- /* check if parameter is logical */
- if (val & ~(VNC_MUTE_INTERNAL_SPKR |
- VNC_MUTE_LINE_OUT |
- VNC_DISABLE_AUTOSWITCH))
- return -EINVAL;
-
- prev_auto_state = devc->no_autoselect;
- prev_spkr_mute = devc->spkr_mute_state;
- prev_line_mute = devc->line_mute_state;
-
- devc->no_autoselect = (val & VNC_DISABLE_AUTOSWITCH) ? 1 : 0;
- devc->spkr_mute_state = (val & VNC_MUTE_INTERNAL_SPKR) ? 1 : 0;
- devc->line_mute_state = (val & VNC_MUTE_LINE_OUT) ? 1 : 0;
-
- if (prev_spkr_mute != devc->spkr_mute_state)
- vnc_mute_spkr(devc);
-
- if (prev_line_mute != devc->line_mute_state)
- vnc_mute_lout(devc);
-
- if (prev_auto_state != devc->no_autoselect)
- vnc_configure_mixer(devc, devc->recmask);
-
- return 0;
- }
-
- case SOUND_MIXER_PRIVATE2:
- if (get_user(val, arg))
- return -EFAULT;
-
- switch (val) {
-#define VNC_SOUND_PAUSE 0x53 //to pause the DSP
-#define VNC_SOUND_RESUME 0x57 //to unpause the DSP
- case VNC_SOUND_PAUSE:
- waveartist_cmd1(devc, 0x16);
- break;
-
- case VNC_SOUND_RESUME:
- waveartist_cmd1(devc, 0x18);
- break;
-
- default:
- return -EINVAL;
- }
- return 0;
-
- /* private ioctl to allow bulk access to waveartist */
- case SOUND_MIXER_PRIVATE3:
- {
- unsigned long flags;
- int mixer_reg[15], i, val;
-
- if (get_user(val, arg))
- return -EFAULT;
- if (copy_from_user(mixer_reg, (void *)val, sizeof(mixer_reg)))
- return -EFAULT;
-
- switch (mixer_reg[14]) {
- case MIXER_PRIVATE3_RESET:
- waveartist_mixer_reset(devc);
- break;
-
- case MIXER_PRIVATE3_WRITE:
- waveartist_cmd3(devc, WACMD_SET_MIXER, mixer_reg[0], mixer_reg[4]);
- waveartist_cmd3(devc, WACMD_SET_MIXER, mixer_reg[1], mixer_reg[5]);
- waveartist_cmd3(devc, WACMD_SET_MIXER, mixer_reg[2], mixer_reg[6]);
- waveartist_cmd3(devc, WACMD_SET_MIXER, mixer_reg[3], mixer_reg[7]);
- waveartist_cmd3(devc, WACMD_SET_MIXER, mixer_reg[8], mixer_reg[9]);
-
- waveartist_cmd3(devc, WACMD_SET_LEVEL, mixer_reg[10], mixer_reg[11]);
- waveartist_cmd3(devc, WACMD_SET_LEVEL, mixer_reg[12], mixer_reg[13]);
- break;
-
- case MIXER_PRIVATE3_READ:
- spin_lock_irqsave(&waveartist_lock, flags);
-
- for (i = 0x30; i < 14 << 8; i += 1 << 8)
- waveartist_cmd(devc, 1, &i, 1, mixer_reg + (i >> 8));
-
- spin_unlock_irqrestore(&waveartist_lock, flags);
-
- if (copy_to_user((void *)val, mixer_reg, sizeof(mixer_reg)))
- return -EFAULT;
- break;
-
- default:
- return -EINVAL;
- }
- return 0;
- }
-
- /* read back the state from PRIVATE1 */
- case SOUND_MIXER_PRIVATE4:
- val = (devc->spkr_mute_state ? VNC_MUTE_INTERNAL_SPKR : 0) |
- (devc->line_mute_state ? VNC_MUTE_LINE_OUT : 0) |
- (devc->handset_detect ? VNC_HANDSET_DETECT : 0) |
- (devc->telephone_detect ? VNC_PHONE_DETECT : 0) |
- (devc->no_autoselect ? VNC_DISABLE_AUTOSWITCH : 0);
-
- return put_user(val, arg) ? -EFAULT : 0;
- }
-
- if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
- /*
- * special case for master volume: if we
- * received this call - switch from hw
- * volume control to a software volume
- * control, till the hw volume is modified
- * to signal that user wants to be back in
- * hardware...
- */
- if ((cmd & 0xff) == SOUND_MIXER_VOLUME)
- devc->use_slider = 0;
-
- /* speaker output */
- if ((cmd & 0xff) == SOUND_MIXER_SPEAKER) {
- unsigned int val, l, r;
-
- if (get_user(val, arg))
- return -EFAULT;
-
- l = val & 0x7f;
- r = (val & 0x7f00) >> 8;
- val = (l + r) / 2;
- devc->levels[SOUND_MIXER_SPEAKER] = val | (val << 8);
- devc->spkr_mute_state = (val <= 50);
- vnc_mute_spkr(devc);
- return 0;
- }
- }
-
- return -ENOIOCTLCMD;
-}
-
-#endif
-
-static struct address_info cfg;
-
-static int attached;
-
-static int __initdata io = 0;
-static int __initdata irq = 0;
-static int __initdata dma = 0;
-static int __initdata dma2 = 0;
-
-
-static int __init init_waveartist(void)
-{
- const struct waveartist_mixer_info *mix;
-
- if (!io && machine_is_netwinder()) {
- /*
- * The NetWinder WaveArtist is at a fixed address.
- * If the user does not supply an address, use the
- * well-known parameters.
- */
- io = 0x250;
- irq = 12;
- dma = 3;
- dma2 = 7;
- }
-
- mix = &waveartist_mixer;
-#ifdef CONFIG_ARCH_NETWINDER
- if (machine_is_netwinder())
- mix = &netwinder_mixer;
-#endif
-
- cfg.io_base = io;
- cfg.irq = irq;
- cfg.dma = dma;
- cfg.dma2 = dma2;
-
- if (!probe_waveartist(&cfg))
- return -ENODEV;
-
- attach_waveartist(&cfg, mix);
- attached = 1;
-
- return 0;
-}
-
-static void __exit cleanup_waveartist(void)
-{
- if (attached)
- unload_waveartist(&cfg);
-}
-
-module_init(init_waveartist);
-module_exit(cleanup_waveartist);
-
-#ifndef MODULE
-static int __init setup_waveartist(char *str)
-{
- /* io, irq, dma, dma2 */
- int ints[5];
-
- str = get_options(str, ARRAY_SIZE(ints), ints);
-
- io = ints[1];
- irq = ints[2];
- dma = ints[3];
- dma2 = ints[4];
-
- return 1;
-}
-__setup("waveartist=", setup_waveartist);
-#endif
-
-MODULE_DESCRIPTION("Rockwell WaveArtist RWA-010 sound driver");
-module_param(io, int, 0); /* IO base */
-module_param(irq, int, 0); /* IRQ */
-module_param(dma, int, 0); /* DMA */
-module_param(dma2, int, 0); /* DMA2 */
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/oss/waveartist.h b/ANDROID_3.4.5/sound/oss/waveartist.h
deleted file mode 100644
index dac4ca91..00000000
--- a/ANDROID_3.4.5/sound/oss/waveartist.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * linux/sound/oss/waveartist.h
- *
- * def file for Rockwell RWA010 chip set, as installed in Rebel.com NetWinder
- */
-
-//registers
-#define CMDR 0
-#define DATR 2
-#define CTLR 4
-#define STATR 5
-#define IRQSTAT 12
-
-//bit defs
-//reg STATR
-#define CMD_WE 0x80
-#define CMD_RF 0x40
-#define DAT_WE 0x20
-#define DAT_RF 0x10
-
-#define IRQ_REQ 0x08
-#define DMA1 0x04
-#define DMA0 0x02
-
-//bit defs
-//reg CTLR
-#define CMD_WEIE 0x80
-#define CMD_RFIE 0x40
-#define DAT_WEIE 0x20
-#define DAT_RFIE 0x10
-
-#define RESET 0x08
-#define DMA1_IE 0x04
-#define DMA0_IE 0x02
-#define IRQ_ACK 0x01
-
-//commands
-
-#define WACMD_SYSTEMID 0x00
-#define WACMD_GETREV 0x00
-#define WACMD_INPUTFORMAT 0x10 //0-8S, 1-16S, 2-8U
-#define WACMD_INPUTCHANNELS 0x11 //1-Mono, 2-Stereo
-#define WACMD_INPUTSPEED 0x12 //sampling rate
-#define WACMD_INPUTDMA 0x13 //0-8bit, 1-16bit, 2-PIO
-#define WACMD_INPUTSIZE 0x14 //samples to interrupt
-#define WACMD_INPUTSTART 0x15 //start ADC
-#define WACMD_INPUTPAUSE 0x16 //pause ADC
-#define WACMD_INPUTSTOP 0x17 //stop ADC
-#define WACMD_INPUTRESUME 0x18 //resume ADC
-#define WACMD_INPUTPIO 0x19 //PIO ADC
-
-#define WACMD_OUTPUTFORMAT 0x20 //0-8S, 1-16S, 2-8U
-#define WACMD_OUTPUTCHANNELS 0x21 //1-Mono, 2-Stereo
-#define WACMD_OUTPUTSPEED 0x22 //sampling rate
-#define WACMD_OUTPUTDMA 0x23 //0-8bit, 1-16bit, 2-PIO
-#define WACMD_OUTPUTSIZE 0x24 //samples to interrupt
-#define WACMD_OUTPUTSTART 0x25 //start ADC
-#define WACMD_OUTPUTPAUSE 0x26 //pause ADC
-#define WACMD_OUTPUTSTOP 0x27 //stop ADC
-#define WACMD_OUTPUTRESUME 0x28 //resume ADC
-#define WACMD_OUTPUTPIO 0x29 //PIO ADC
-
-#define WACMD_GET_LEVEL 0x30
-#define WACMD_SET_LEVEL 0x31
-#define WACMD_SET_MIXER 0x32
-#define WACMD_RST_MIXER 0x33
-#define WACMD_SET_MONO 0x34
-
-/*
- * Definitions for left/right recording input mux
- */
-#define ADC_MUX_NONE 0
-#define ADC_MUX_MIXER 1
-#define ADC_MUX_LINE 2
-#define ADC_MUX_AUX2 3
-#define ADC_MUX_AUX1 4
-#define ADC_MUX_MIC 5
-
-/*
- * Definitions for mixer gain settings
- */
-#define MIX_GAIN_LINE 0 /* line in */
-#define MIX_GAIN_AUX1 1 /* aux1 */
-#define MIX_GAIN_AUX2 2 /* aux2 */
-#define MIX_GAIN_XMIC 3 /* crossover mic */
-#define MIX_GAIN_MIC 4 /* normal mic */
-#define MIX_GAIN_PREMIC 5 /* preamp mic */
-#define MIX_GAIN_OUT 6 /* output */
-#define MIX_GAIN_MONO 7 /* mono in */
-
-int wa_sendcmd(unsigned int cmd);
-int wa_writecmd(unsigned int cmd, unsigned int arg);
diff --git a/ANDROID_3.4.5/sound/parisc/Kconfig b/ANDROID_3.4.5/sound/parisc/Kconfig
deleted file mode 100644
index 9b61d950..00000000
--- a/ANDROID_3.4.5/sound/parisc/Kconfig
+++ /dev/null
@@ -1,20 +0,0 @@
-# ALSA PA-RISC drivers
-
-menuconfig SND_GSC
- bool "GSC sound devices"
- depends on GSC
- default y
- help
- Support for GSC sound devices on PA-RISC architectures.
-
-if SND_GSC
-
-config SND_HARMONY
- tristate "Harmony/Vivace sound chip"
- select SND_PCM
- help
- Say 'Y' or 'M' to include support for the Harmony/Vivace sound
- chip found in most GSC-based PA-RISC workstations. It's frequently
- provided as part of the Lasi multi-function IC.
-
-endif # SND_GSC
diff --git a/ANDROID_3.4.5/sound/parisc/Makefile b/ANDROID_3.4.5/sound/parisc/Makefile
deleted file mode 100644
index b91e750a..00000000
--- a/ANDROID_3.4.5/sound/parisc/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Makefile for ALSA
-#
-
-snd-harmony-objs := harmony.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_HARMONY) += snd-harmony.o
diff --git a/ANDROID_3.4.5/sound/parisc/harmony.c b/ANDROID_3.4.5/sound/parisc/harmony.c
deleted file mode 100644
index f47f9e22..00000000
--- a/ANDROID_3.4.5/sound/parisc/harmony.c
+++ /dev/null
@@ -1,1047 +0,0 @@
-/* Hewlett-Packard Harmony audio driver
- *
- * This is a driver for the Harmony audio chipset found
- * on the LASI ASIC of various early HP PA-RISC workstations.
- *
- * Copyright (C) 2004, Kyle McMartin <kyle@{debian.org,parisc-linux.org}>
- *
- * Based on the previous Harmony incarnations by,
- * Copyright 2000 (c) Linuxcare Canada, Alex deVries
- * Copyright 2000-2003 (c) Helge Deller
- * Copyright 2001 (c) Matthieu Delahaye
- * Copyright 2001 (c) Jean-Christophe Vaugeois
- * Copyright 2003 (c) Laurent Canet
- * Copyright 2004 (c) Stuart Brady
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Notes:
- * - graveyard and silence buffers last for lifetime of
- * the driver. playback and capture buffers are allocated
- * per _open()/_close().
- *
- * TODO:
- *
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/dma-mapping.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/control.h>
-#include <sound/rawmidi.h>
-#include <sound/initval.h>
-#include <sound/info.h>
-
-#include <asm/io.h>
-#include <asm/hardware.h>
-#include <asm/parisc-device.h>
-
-#include "harmony.h"
-
-static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
-static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for Harmony driver.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for Harmony driver.");
-
-
-static struct parisc_device_id snd_harmony_devtable[] = {
- /* bushmaster / flounder */
- { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007A },
- /* 712 / 715 */
- { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007B },
- /* pace */
- { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007E },
- /* outfield / coral II */
- { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007F },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(parisc, snd_harmony_devtable);
-
-#define NAME "harmony"
-#define PFX NAME ": "
-
-static unsigned int snd_harmony_rates[] = {
- 5512, 6615, 8000, 9600,
- 11025, 16000, 18900, 22050,
- 27428, 32000, 33075, 37800,
- 44100, 48000
-};
-
-static unsigned int rate_bits[14] = {
- HARMONY_SR_5KHZ, HARMONY_SR_6KHZ, HARMONY_SR_8KHZ,
- HARMONY_SR_9KHZ, HARMONY_SR_11KHZ, HARMONY_SR_16KHZ,
- HARMONY_SR_18KHZ, HARMONY_SR_22KHZ, HARMONY_SR_27KHZ,
- HARMONY_SR_32KHZ, HARMONY_SR_33KHZ, HARMONY_SR_37KHZ,
- HARMONY_SR_44KHZ, HARMONY_SR_48KHZ
-};
-
-static struct snd_pcm_hw_constraint_list hw_constraint_rates = {
- .count = ARRAY_SIZE(snd_harmony_rates),
- .list = snd_harmony_rates,
- .mask = 0,
-};
-
-static inline unsigned long
-harmony_read(struct snd_harmony *h, unsigned r)
-{
- return __raw_readl(h->iobase + r);
-}
-
-static inline void
-harmony_write(struct snd_harmony *h, unsigned r, unsigned long v)
-{
- __raw_writel(v, h->iobase + r);
-}
-
-static inline void
-harmony_wait_for_control(struct snd_harmony *h)
-{
- while (harmony_read(h, HARMONY_CNTL) & HARMONY_CNTL_C) ;
-}
-
-static inline void
-harmony_reset(struct snd_harmony *h)
-{
- harmony_write(h, HARMONY_RESET, 1);
- mdelay(50);
- harmony_write(h, HARMONY_RESET, 0);
-}
-
-static void
-harmony_disable_interrupts(struct snd_harmony *h)
-{
- u32 dstatus;
- harmony_wait_for_control(h);
- dstatus = harmony_read(h, HARMONY_DSTATUS);
- dstatus &= ~HARMONY_DSTATUS_IE;
- harmony_write(h, HARMONY_DSTATUS, dstatus);
-}
-
-static void
-harmony_enable_interrupts(struct snd_harmony *h)
-{
- u32 dstatus;
- harmony_wait_for_control(h);
- dstatus = harmony_read(h, HARMONY_DSTATUS);
- dstatus |= HARMONY_DSTATUS_IE;
- harmony_write(h, HARMONY_DSTATUS, dstatus);
-}
-
-static void
-harmony_mute(struct snd_harmony *h)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&h->mixer_lock, flags);
- harmony_wait_for_control(h);
- harmony_write(h, HARMONY_GAINCTL, HARMONY_GAIN_SILENCE);
- spin_unlock_irqrestore(&h->mixer_lock, flags);
-}
-
-static void
-harmony_unmute(struct snd_harmony *h)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&h->mixer_lock, flags);
- harmony_wait_for_control(h);
- harmony_write(h, HARMONY_GAINCTL, h->st.gain);
- spin_unlock_irqrestore(&h->mixer_lock, flags);
-}
-
-static void
-harmony_set_control(struct snd_harmony *h)
-{
- u32 ctrl;
- unsigned long flags;
-
- spin_lock_irqsave(&h->lock, flags);
-
- ctrl = (HARMONY_CNTL_C |
- (h->st.format << 6) |
- (h->st.stereo << 5) |
- (h->st.rate));
-
- harmony_wait_for_control(h);
- harmony_write(h, HARMONY_CNTL, ctrl);
-
- spin_unlock_irqrestore(&h->lock, flags);
-}
-
-static irqreturn_t
-snd_harmony_interrupt(int irq, void *dev)
-{
- u32 dstatus;
- struct snd_harmony *h = dev;
-
- spin_lock(&h->lock);
- harmony_disable_interrupts(h);
- harmony_wait_for_control(h);
- dstatus = harmony_read(h, HARMONY_DSTATUS);
- spin_unlock(&h->lock);
-
- if (dstatus & HARMONY_DSTATUS_PN) {
- if (h->psubs && h->st.playing) {
- spin_lock(&h->lock);
- h->pbuf.buf += h->pbuf.count; /* PAGE_SIZE */
- h->pbuf.buf %= h->pbuf.size; /* MAX_BUFS*PAGE_SIZE */
-
- harmony_write(h, HARMONY_PNXTADD,
- h->pbuf.addr + h->pbuf.buf);
- h->stats.play_intr++;
- spin_unlock(&h->lock);
- snd_pcm_period_elapsed(h->psubs);
- } else {
- spin_lock(&h->lock);
- harmony_write(h, HARMONY_PNXTADD, h->sdma.addr);
- h->stats.silence_intr++;
- spin_unlock(&h->lock);
- }
- }
-
- if (dstatus & HARMONY_DSTATUS_RN) {
- if (h->csubs && h->st.capturing) {
- spin_lock(&h->lock);
- h->cbuf.buf += h->cbuf.count;
- h->cbuf.buf %= h->cbuf.size;
-
- harmony_write(h, HARMONY_RNXTADD,
- h->cbuf.addr + h->cbuf.buf);
- h->stats.rec_intr++;
- spin_unlock(&h->lock);
- snd_pcm_period_elapsed(h->csubs);
- } else {
- spin_lock(&h->lock);
- harmony_write(h, HARMONY_RNXTADD, h->gdma.addr);
- h->stats.graveyard_intr++;
- spin_unlock(&h->lock);
- }
- }
-
- spin_lock(&h->lock);
- harmony_enable_interrupts(h);
- spin_unlock(&h->lock);
-
- return IRQ_HANDLED;
-}
-
-static unsigned int
-snd_harmony_rate_bits(int rate)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(snd_harmony_rates); i++)
- if (snd_harmony_rates[i] == rate)
- return rate_bits[i];
-
- return HARMONY_SR_44KHZ;
-}
-
-static struct snd_pcm_hardware snd_harmony_playback =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BLOCK_TRANSFER),
- .formats = (SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_MU_LAW |
- SNDRV_PCM_FMTBIT_A_LAW),
- .rates = (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000 |
- SNDRV_PCM_RATE_KNOT),
- .rate_min = 5512,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = MAX_BUF_SIZE,
- .period_bytes_min = BUF_SIZE,
- .period_bytes_max = BUF_SIZE,
- .periods_min = 1,
- .periods_max = MAX_BUFS,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_harmony_capture =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BLOCK_TRANSFER),
- .formats = (SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_MU_LAW |
- SNDRV_PCM_FMTBIT_A_LAW),
- .rates = (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000 |
- SNDRV_PCM_RATE_KNOT),
- .rate_min = 5512,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = MAX_BUF_SIZE,
- .period_bytes_min = BUF_SIZE,
- .period_bytes_max = BUF_SIZE,
- .periods_min = 1,
- .periods_max = MAX_BUFS,
- .fifo_size = 0,
-};
-
-static int
-snd_harmony_playback_trigger(struct snd_pcm_substream *ss, int cmd)
-{
- struct snd_harmony *h = snd_pcm_substream_chip(ss);
-
- if (h->st.capturing)
- return -EBUSY;
-
- spin_lock(&h->lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- h->st.playing = 1;
- harmony_write(h, HARMONY_PNXTADD, h->pbuf.addr);
- harmony_write(h, HARMONY_RNXTADD, h->gdma.addr);
- harmony_unmute(h);
- harmony_enable_interrupts(h);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- h->st.playing = 0;
- harmony_mute(h);
- harmony_write(h, HARMONY_PNXTADD, h->sdma.addr);
- harmony_disable_interrupts(h);
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- default:
- spin_unlock(&h->lock);
- snd_BUG();
- return -EINVAL;
- }
- spin_unlock(&h->lock);
-
- return 0;
-}
-
-static int
-snd_harmony_capture_trigger(struct snd_pcm_substream *ss, int cmd)
-{
- struct snd_harmony *h = snd_pcm_substream_chip(ss);
-
- if (h->st.playing)
- return -EBUSY;
-
- spin_lock(&h->lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- h->st.capturing = 1;
- harmony_write(h, HARMONY_PNXTADD, h->sdma.addr);
- harmony_write(h, HARMONY_RNXTADD, h->cbuf.addr);
- harmony_unmute(h);
- harmony_enable_interrupts(h);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- h->st.capturing = 0;
- harmony_mute(h);
- harmony_write(h, HARMONY_RNXTADD, h->gdma.addr);
- harmony_disable_interrupts(h);
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- default:
- spin_unlock(&h->lock);
- snd_BUG();
- return -EINVAL;
- }
- spin_unlock(&h->lock);
-
- return 0;
-}
-
-static int
-snd_harmony_set_data_format(struct snd_harmony *h, int fmt, int force)
-{
- int o = h->st.format;
- int n;
-
- switch(fmt) {
- case SNDRV_PCM_FORMAT_S16_BE:
- n = HARMONY_DF_16BIT_LINEAR;
- break;
- case SNDRV_PCM_FORMAT_A_LAW:
- n = HARMONY_DF_8BIT_ALAW;
- break;
- case SNDRV_PCM_FORMAT_MU_LAW:
- n = HARMONY_DF_8BIT_ULAW;
- break;
- default:
- n = HARMONY_DF_16BIT_LINEAR;
- break;
- }
-
- if (force || o != n) {
- snd_pcm_format_set_silence(fmt, h->sdma.area, SILENCE_BUFSZ /
- (snd_pcm_format_physical_width(fmt)
- / 8));
- }
-
- return n;
-}
-
-static int
-snd_harmony_playback_prepare(struct snd_pcm_substream *ss)
-{
- struct snd_harmony *h = snd_pcm_substream_chip(ss);
- struct snd_pcm_runtime *rt = ss->runtime;
-
- if (h->st.capturing)
- return -EBUSY;
-
- h->pbuf.size = snd_pcm_lib_buffer_bytes(ss);
- h->pbuf.count = snd_pcm_lib_period_bytes(ss);
- if (h->pbuf.buf >= h->pbuf.size)
- h->pbuf.buf = 0;
- h->st.playing = 0;
-
- h->st.rate = snd_harmony_rate_bits(rt->rate);
- h->st.format = snd_harmony_set_data_format(h, rt->format, 0);
-
- if (rt->channels == 2)
- h->st.stereo = HARMONY_SS_STEREO;
- else
- h->st.stereo = HARMONY_SS_MONO;
-
- harmony_set_control(h);
-
- h->pbuf.addr = rt->dma_addr;
-
- return 0;
-}
-
-static int
-snd_harmony_capture_prepare(struct snd_pcm_substream *ss)
-{
- struct snd_harmony *h = snd_pcm_substream_chip(ss);
- struct snd_pcm_runtime *rt = ss->runtime;
-
- if (h->st.playing)
- return -EBUSY;
-
- h->cbuf.size = snd_pcm_lib_buffer_bytes(ss);
- h->cbuf.count = snd_pcm_lib_period_bytes(ss);
- if (h->cbuf.buf >= h->cbuf.size)
- h->cbuf.buf = 0;
- h->st.capturing = 0;
-
- h->st.rate = snd_harmony_rate_bits(rt->rate);
- h->st.format = snd_harmony_set_data_format(h, rt->format, 0);
-
- if (rt->channels == 2)
- h->st.stereo = HARMONY_SS_STEREO;
- else
- h->st.stereo = HARMONY_SS_MONO;
-
- harmony_set_control(h);
-
- h->cbuf.addr = rt->dma_addr;
-
- return 0;
-}
-
-static snd_pcm_uframes_t
-snd_harmony_playback_pointer(struct snd_pcm_substream *ss)
-{
- struct snd_pcm_runtime *rt = ss->runtime;
- struct snd_harmony *h = snd_pcm_substream_chip(ss);
- unsigned long pcuradd;
- unsigned long played;
-
- if (!(h->st.playing) || (h->psubs == NULL))
- return 0;
-
- if ((h->pbuf.addr == 0) || (h->pbuf.size == 0))
- return 0;
-
- pcuradd = harmony_read(h, HARMONY_PCURADD);
- played = pcuradd - h->pbuf.addr;
-
-#ifdef HARMONY_DEBUG
- printk(KERN_DEBUG PFX "playback_pointer is 0x%lx-0x%lx = %d bytes\n",
- pcuradd, h->pbuf.addr, played);
-#endif
-
- if (pcuradd > h->pbuf.addr + h->pbuf.size) {
- return 0;
- }
-
- return bytes_to_frames(rt, played);
-}
-
-static snd_pcm_uframes_t
-snd_harmony_capture_pointer(struct snd_pcm_substream *ss)
-{
- struct snd_pcm_runtime *rt = ss->runtime;
- struct snd_harmony *h = snd_pcm_substream_chip(ss);
- unsigned long rcuradd;
- unsigned long caught;
-
- if (!(h->st.capturing) || (h->csubs == NULL))
- return 0;
-
- if ((h->cbuf.addr == 0) || (h->cbuf.size == 0))
- return 0;
-
- rcuradd = harmony_read(h, HARMONY_RCURADD);
- caught = rcuradd - h->cbuf.addr;
-
-#ifdef HARMONY_DEBUG
- printk(KERN_DEBUG PFX "capture_pointer is 0x%lx-0x%lx = %d bytes\n",
- rcuradd, h->cbuf.addr, caught);
-#endif
-
- if (rcuradd > h->cbuf.addr + h->cbuf.size) {
- return 0;
- }
-
- return bytes_to_frames(rt, caught);
-}
-
-static int
-snd_harmony_playback_open(struct snd_pcm_substream *ss)
-{
- struct snd_harmony *h = snd_pcm_substream_chip(ss);
- struct snd_pcm_runtime *rt = ss->runtime;
- int err;
-
- h->psubs = ss;
- rt->hw = snd_harmony_playback;
- snd_pcm_hw_constraint_list(rt, 0, SNDRV_PCM_HW_PARAM_RATE,
- &hw_constraint_rates);
-
- err = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static int
-snd_harmony_capture_open(struct snd_pcm_substream *ss)
-{
- struct snd_harmony *h = snd_pcm_substream_chip(ss);
- struct snd_pcm_runtime *rt = ss->runtime;
- int err;
-
- h->csubs = ss;
- rt->hw = snd_harmony_capture;
- snd_pcm_hw_constraint_list(rt, 0, SNDRV_PCM_HW_PARAM_RATE,
- &hw_constraint_rates);
-
- err = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static int
-snd_harmony_playback_close(struct snd_pcm_substream *ss)
-{
- struct snd_harmony *h = snd_pcm_substream_chip(ss);
- h->psubs = NULL;
- return 0;
-}
-
-static int
-snd_harmony_capture_close(struct snd_pcm_substream *ss)
-{
- struct snd_harmony *h = snd_pcm_substream_chip(ss);
- h->csubs = NULL;
- return 0;
-}
-
-static int
-snd_harmony_hw_params(struct snd_pcm_substream *ss,
- struct snd_pcm_hw_params *hw)
-{
- int err;
- struct snd_harmony *h = snd_pcm_substream_chip(ss);
-
- err = snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw));
- if (err > 0 && h->dma.type == SNDRV_DMA_TYPE_CONTINUOUS)
- ss->runtime->dma_addr = __pa(ss->runtime->dma_area);
-
- return err;
-}
-
-static int
-snd_harmony_hw_free(struct snd_pcm_substream *ss)
-{
- return snd_pcm_lib_free_pages(ss);
-}
-
-static struct snd_pcm_ops snd_harmony_playback_ops = {
- .open = snd_harmony_playback_open,
- .close = snd_harmony_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_harmony_hw_params,
- .hw_free = snd_harmony_hw_free,
- .prepare = snd_harmony_playback_prepare,
- .trigger = snd_harmony_playback_trigger,
- .pointer = snd_harmony_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_harmony_capture_ops = {
- .open = snd_harmony_capture_open,
- .close = snd_harmony_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_harmony_hw_params,
- .hw_free = snd_harmony_hw_free,
- .prepare = snd_harmony_capture_prepare,
- .trigger = snd_harmony_capture_trigger,
- .pointer = snd_harmony_capture_pointer,
-};
-
-static int
-snd_harmony_pcm_init(struct snd_harmony *h)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (snd_BUG_ON(!h))
- return -EINVAL;
-
- harmony_disable_interrupts(h);
-
- err = snd_pcm_new(h->card, "harmony", 0, 1, 1, &pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_harmony_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_harmony_capture_ops);
-
- pcm->private_data = h;
- pcm->info_flags = 0;
- strcpy(pcm->name, "harmony");
- h->pcm = pcm;
-
- h->psubs = NULL;
- h->csubs = NULL;
-
- /* initialize graveyard buffer */
- h->dma.type = SNDRV_DMA_TYPE_DEV;
- h->dma.dev = &h->dev->dev;
- err = snd_dma_alloc_pages(h->dma.type,
- h->dma.dev,
- BUF_SIZE*GRAVEYARD_BUFS,
- &h->gdma);
- if (err < 0) {
- printk(KERN_ERR PFX "cannot allocate graveyard buffer!\n");
- return err;
- }
-
- /* initialize silence buffers */
- err = snd_dma_alloc_pages(h->dma.type,
- h->dma.dev,
- BUF_SIZE*SILENCE_BUFS,
- &h->sdma);
- if (err < 0) {
- printk(KERN_ERR PFX "cannot allocate silence buffer!\n");
- return err;
- }
-
- /* pre-allocate space for DMA */
- err = snd_pcm_lib_preallocate_pages_for_all(pcm, h->dma.type,
- h->dma.dev,
- MAX_BUF_SIZE,
- MAX_BUF_SIZE);
- if (err < 0) {
- printk(KERN_ERR PFX "buffer allocation error: %d\n", err);
- return err;
- }
-
- h->st.format = snd_harmony_set_data_format(h,
- SNDRV_PCM_FORMAT_S16_BE, 1);
-
- return 0;
-}
-
-static void
-snd_harmony_set_new_gain(struct snd_harmony *h)
-{
- harmony_wait_for_control(h);
- harmony_write(h, HARMONY_GAINCTL, h->st.gain);
-}
-
-static int
-snd_harmony_mixercontrol_info(struct snd_kcontrol *kc,
- struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kc->private_value >> 16) & 0xff;
- int left_shift = (kc->private_value) & 0xff;
- int right_shift = (kc->private_value >> 8) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN :
- SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = left_shift == right_shift ? 1 : 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
-
- return 0;
-}
-
-static int
-snd_harmony_volume_get(struct snd_kcontrol *kc,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_harmony *h = snd_kcontrol_chip(kc);
- int shift_left = (kc->private_value) & 0xff;
- int shift_right = (kc->private_value >> 8) & 0xff;
- int mask = (kc->private_value >> 16) & 0xff;
- int invert = (kc->private_value >> 24) & 0xff;
- int left, right;
-
- spin_lock_irq(&h->mixer_lock);
-
- left = (h->st.gain >> shift_left) & mask;
- right = (h->st.gain >> shift_right) & mask;
- if (invert) {
- left = mask - left;
- right = mask - right;
- }
-
- ucontrol->value.integer.value[0] = left;
- if (shift_left != shift_right)
- ucontrol->value.integer.value[1] = right;
-
- spin_unlock_irq(&h->mixer_lock);
-
- return 0;
-}
-
-static int
-snd_harmony_volume_put(struct snd_kcontrol *kc,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_harmony *h = snd_kcontrol_chip(kc);
- int shift_left = (kc->private_value) & 0xff;
- int shift_right = (kc->private_value >> 8) & 0xff;
- int mask = (kc->private_value >> 16) & 0xff;
- int invert = (kc->private_value >> 24) & 0xff;
- int left, right;
- int old_gain = h->st.gain;
-
- spin_lock_irq(&h->mixer_lock);
-
- left = ucontrol->value.integer.value[0] & mask;
- if (invert)
- left = mask - left;
- h->st.gain &= ~( (mask << shift_left ) );
- h->st.gain |= (left << shift_left);
-
- if (shift_left != shift_right) {
- right = ucontrol->value.integer.value[1] & mask;
- if (invert)
- right = mask - right;
- h->st.gain &= ~( (mask << shift_right) );
- h->st.gain |= (right << shift_right);
- }
-
- snd_harmony_set_new_gain(h);
-
- spin_unlock_irq(&h->mixer_lock);
-
- return h->st.gain != old_gain;
-}
-
-static int
-snd_harmony_captureroute_info(struct snd_kcontrol *kc,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[2] = { "Line", "Mic" };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item > 1)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int
-snd_harmony_captureroute_get(struct snd_kcontrol *kc,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_harmony *h = snd_kcontrol_chip(kc);
- int value;
-
- spin_lock_irq(&h->mixer_lock);
-
- value = (h->st.gain >> HARMONY_GAIN_IS_SHIFT) & 1;
- ucontrol->value.enumerated.item[0] = value;
-
- spin_unlock_irq(&h->mixer_lock);
-
- return 0;
-}
-
-static int
-snd_harmony_captureroute_put(struct snd_kcontrol *kc,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_harmony *h = snd_kcontrol_chip(kc);
- int value;
- int old_gain = h->st.gain;
-
- spin_lock_irq(&h->mixer_lock);
-
- value = ucontrol->value.enumerated.item[0] & 1;
- h->st.gain &= ~HARMONY_GAIN_IS_MASK;
- h->st.gain |= value << HARMONY_GAIN_IS_SHIFT;
-
- snd_harmony_set_new_gain(h);
-
- spin_unlock_irq(&h->mixer_lock);
-
- return h->st.gain != old_gain;
-}
-
-#define HARMONY_CONTROLS ARRAY_SIZE(snd_harmony_controls)
-
-#define HARMONY_VOLUME(xname, left_shift, right_shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_harmony_mixercontrol_info, \
- .get = snd_harmony_volume_get, .put = snd_harmony_volume_put, \
- .private_value = ((left_shift) | ((right_shift) << 8) | \
- ((mask) << 16) | ((invert) << 24)) }
-
-static struct snd_kcontrol_new snd_harmony_controls[] = {
- HARMONY_VOLUME("Master Playback Volume", HARMONY_GAIN_LO_SHIFT,
- HARMONY_GAIN_RO_SHIFT, HARMONY_GAIN_OUT, 1),
- HARMONY_VOLUME("Capture Volume", HARMONY_GAIN_LI_SHIFT,
- HARMONY_GAIN_RI_SHIFT, HARMONY_GAIN_IN, 0),
- HARMONY_VOLUME("Monitor Volume", HARMONY_GAIN_MA_SHIFT,
- HARMONY_GAIN_MA_SHIFT, HARMONY_GAIN_MA, 1),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input Route",
- .info = snd_harmony_captureroute_info,
- .get = snd_harmony_captureroute_get,
- .put = snd_harmony_captureroute_put
- },
- HARMONY_VOLUME("Internal Speaker Switch", HARMONY_GAIN_SE_SHIFT,
- HARMONY_GAIN_SE_SHIFT, 1, 0),
- HARMONY_VOLUME("Line-Out Switch", HARMONY_GAIN_LE_SHIFT,
- HARMONY_GAIN_LE_SHIFT, 1, 0),
- HARMONY_VOLUME("Headphones Switch", HARMONY_GAIN_HE_SHIFT,
- HARMONY_GAIN_HE_SHIFT, 1, 0),
-};
-
-static void __devinit
-snd_harmony_mixer_reset(struct snd_harmony *h)
-{
- harmony_mute(h);
- harmony_reset(h);
- h->st.gain = HARMONY_GAIN_DEFAULT;
- harmony_unmute(h);
-}
-
-static int __devinit
-snd_harmony_mixer_init(struct snd_harmony *h)
-{
- struct snd_card *card;
- int idx, err;
-
- if (snd_BUG_ON(!h))
- return -EINVAL;
- card = h->card;
- strcpy(card->mixername, "Harmony Gain control interface");
-
- for (idx = 0; idx < HARMONY_CONTROLS; idx++) {
- err = snd_ctl_add(card,
- snd_ctl_new1(&snd_harmony_controls[idx], h));
- if (err < 0)
- return err;
- }
-
- snd_harmony_mixer_reset(h);
-
- return 0;
-}
-
-static int
-snd_harmony_free(struct snd_harmony *h)
-{
- if (h->gdma.addr)
- snd_dma_free_pages(&h->gdma);
- if (h->sdma.addr)
- snd_dma_free_pages(&h->sdma);
-
- if (h->irq >= 0)
- free_irq(h->irq, h);
-
- if (h->iobase)
- iounmap(h->iobase);
-
- parisc_set_drvdata(h->dev, NULL);
-
- kfree(h);
- return 0;
-}
-
-static int
-snd_harmony_dev_free(struct snd_device *dev)
-{
- struct snd_harmony *h = dev->device_data;
- return snd_harmony_free(h);
-}
-
-static int __devinit
-snd_harmony_create(struct snd_card *card,
- struct parisc_device *padev,
- struct snd_harmony **rchip)
-{
- int err;
- struct snd_harmony *h;
- static struct snd_device_ops ops = {
- .dev_free = snd_harmony_dev_free,
- };
-
- *rchip = NULL;
-
- h = kzalloc(sizeof(*h), GFP_KERNEL);
- if (h == NULL)
- return -ENOMEM;
-
- h->hpa = padev->hpa.start;
- h->card = card;
- h->dev = padev;
- h->irq = -1;
- h->iobase = ioremap_nocache(padev->hpa.start, HARMONY_SIZE);
- if (h->iobase == NULL) {
- printk(KERN_ERR PFX "unable to remap hpa 0x%lx\n",
- (unsigned long)padev->hpa.start);
- err = -EBUSY;
- goto free_and_ret;
- }
-
- err = request_irq(padev->irq, snd_harmony_interrupt, 0,
- "harmony", h);
- if (err) {
- printk(KERN_ERR PFX "could not obtain interrupt %d",
- padev->irq);
- goto free_and_ret;
- }
- h->irq = padev->irq;
-
- spin_lock_init(&h->mixer_lock);
- spin_lock_init(&h->lock);
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
- h, &ops)) < 0) {
- goto free_and_ret;
- }
-
- snd_card_set_dev(card, &padev->dev);
-
- *rchip = h;
-
- return 0;
-
-free_and_ret:
- snd_harmony_free(h);
- return err;
-}
-
-static int __devinit
-snd_harmony_probe(struct parisc_device *padev)
-{
- int err;
- struct snd_card *card;
- struct snd_harmony *h;
-
- err = snd_card_create(index, id, THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- err = snd_harmony_create(card, padev, &h);
- if (err < 0)
- goto free_and_ret;
-
- err = snd_harmony_pcm_init(h);
- if (err < 0)
- goto free_and_ret;
-
- err = snd_harmony_mixer_init(h);
- if (err < 0)
- goto free_and_ret;
-
- strcpy(card->driver, "harmony");
- strcpy(card->shortname, "Harmony");
- sprintf(card->longname, "%s at 0x%lx, irq %i",
- card->shortname, h->hpa, h->irq);
-
- err = snd_card_register(card);
- if (err < 0)
- goto free_and_ret;
-
- parisc_set_drvdata(padev, card);
- return 0;
-
-free_and_ret:
- snd_card_free(card);
- return err;
-}
-
-static int __devexit
-snd_harmony_remove(struct parisc_device *padev)
-{
- snd_card_free(parisc_get_drvdata(padev));
- parisc_set_drvdata(padev, NULL);
- return 0;
-}
-
-static struct parisc_driver snd_harmony_driver = {
- .name = "harmony",
- .id_table = snd_harmony_devtable,
- .probe = snd_harmony_probe,
- .remove = __devexit_p(snd_harmony_remove),
-};
-
-static int __init
-alsa_harmony_init(void)
-{
- return register_parisc_driver(&snd_harmony_driver);
-}
-
-static void __exit
-alsa_harmony_fini(void)
-{
- unregister_parisc_driver(&snd_harmony_driver);
-}
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>");
-MODULE_DESCRIPTION("Harmony sound driver");
-
-module_init(alsa_harmony_init);
-module_exit(alsa_harmony_fini);
diff --git a/ANDROID_3.4.5/sound/parisc/harmony.h b/ANDROID_3.4.5/sound/parisc/harmony.h
deleted file mode 100644
index 2e434523..00000000
--- a/ANDROID_3.4.5/sound/parisc/harmony.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/* Hewlett-Packard Harmony audio driver
- * Copyright (C) 2004, Kyle McMartin <kyle@parisc-linux.org>
- */
-
-#ifndef __HARMONY_H__
-#define __HARMONY_H__
-
-struct harmony_buffer {
- unsigned long addr;
- int buf;
- int count;
- int size;
- int coherent;
-};
-
-struct snd_harmony {
- int irq;
-
- unsigned long hpa; /* hard physical address */
- void __iomem *iobase; /* remapped io address */
-
- struct parisc_device *dev;
-
- struct {
- u32 gain;
- u32 rate;
- u32 format;
- u32 stereo;
- int playing;
- int capturing;
- } st;
-
- struct snd_dma_device dma; /* playback/capture */
- struct harmony_buffer pbuf;
- struct harmony_buffer cbuf;
-
- struct snd_dma_buffer gdma; /* graveyard */
- struct snd_dma_buffer sdma; /* silence */
-
- struct {
- unsigned long play_intr;
- unsigned long rec_intr;
- unsigned long graveyard_intr;
- unsigned long silence_intr;
- } stats;
-
- struct snd_pcm *pcm;
- struct snd_card *card;
- struct snd_pcm_substream *psubs;
- struct snd_pcm_substream *csubs;
- struct snd_info_entry *proc;
-
- spinlock_t lock;
- spinlock_t mixer_lock;
-};
-
-#define MAX_PCM_DEVICES 1
-#define MAX_PCM_SUBSTREAMS 4
-#define MAX_MIDI_DEVICES 0
-
-#define HARMONY_SIZE 64
-
-#define BUF_SIZE PAGE_SIZE
-#define MAX_BUFS 16
-#define MAX_BUF_SIZE (MAX_BUFS * BUF_SIZE)
-
-#define PLAYBACK_BUFS MAX_BUFS
-#define RECORD_BUFS MAX_BUFS
-#define GRAVEYARD_BUFS 1
-#define GRAVEYARD_BUFSZ (GRAVEYARD_BUFS*BUF_SIZE)
-#define SILENCE_BUFS 1
-#define SILENCE_BUFSZ (SILENCE_BUFS*BUF_SIZE)
-
-#define HARMONY_ID 0x000
-#define HARMONY_RESET 0x004
-#define HARMONY_CNTL 0x008
-#define HARMONY_GAINCTL 0x00c
-#define HARMONY_PNXTADD 0x010
-#define HARMONY_PCURADD 0x014
-#define HARMONY_RNXTADD 0x018
-#define HARMONY_RCURADD 0x01c
-#define HARMONY_DSTATUS 0x020
-#define HARMONY_OV 0x024
-#define HARMONY_PIO 0x028
-#define HARMONY_DIAG 0x03c
-
-#define HARMONY_CNTL_C 0x80000000
-#define HARMONY_CNTL_ST 0x00000020
-#define HARMONY_CNTL_44100 0x00000015 /* HARMONY_SR_44KHZ */
-#define HARMONY_CNTL_8000 0x00000008 /* HARMONY_SR_8KHZ */
-
-#define HARMONY_DSTATUS_ID 0x00000000 /* interrupts off */
-#define HARMONY_DSTATUS_PN 0x00000200 /* playback fill */
-#define HARMONY_DSTATUS_RN 0x00000002 /* record fill */
-#define HARMONY_DSTATUS_IE 0x80000000 /* interrupts on */
-
-#define HARMONY_DF_16BIT_LINEAR 0x00000000
-#define HARMONY_DF_8BIT_ULAW 0x00000001
-#define HARMONY_DF_8BIT_ALAW 0x00000002
-
-#define HARMONY_SS_MONO 0x00000000
-#define HARMONY_SS_STEREO 0x00000001
-
-#define HARMONY_GAIN_SILENCE 0x01F00FFF
-#define HARMONY_GAIN_DEFAULT 0x01F00FFF
-
-#define HARMONY_GAIN_HE_SHIFT 27 /* headphones enabled */
-#define HARMONY_GAIN_HE_MASK (1 << HARMONY_GAIN_HE_SHIFT)
-#define HARMONY_GAIN_LE_SHIFT 26 /* line-out enabled */
-#define HARMONY_GAIN_LE_MASK (1 << HARMONY_GAIN_LE_SHIFT)
-#define HARMONY_GAIN_SE_SHIFT 25 /* internal-speaker enabled */
-#define HARMONY_GAIN_SE_MASK (1 << HARMONY_GAIN_SE_SHIFT)
-#define HARMONY_GAIN_IS_SHIFT 24 /* input select - 0 for line, 1 for mic */
-#define HARMONY_GAIN_IS_MASK (1 << HARMONY_GAIN_IS_SHIFT)
-
-/* monitor attenuation */
-#define HARMONY_GAIN_MA 0x0f
-#define HARMONY_GAIN_MA_SHIFT 20
-#define HARMONY_GAIN_MA_MASK (HARMONY_GAIN_MA << HARMONY_GAIN_MA_SHIFT)
-
-/* input gain */
-#define HARMONY_GAIN_IN 0x0f
-#define HARMONY_GAIN_LI_SHIFT 16
-#define HARMONY_GAIN_LI_MASK (HARMONY_GAIN_IN << HARMONY_GAIN_LI_SHIFT)
-#define HARMONY_GAIN_RI_SHIFT 12
-#define HARMONY_GAIN_RI_MASK (HARMONY_GAIN_IN << HARMONY_GAIN_RI_SHIFT)
-
-/* output gain (master volume) */
-#define HARMONY_GAIN_OUT 0x3f
-#define HARMONY_GAIN_LO_SHIFT 6
-#define HARMONY_GAIN_LO_MASK (HARMONY_GAIN_OUT << HARMONY_GAIN_LO_SHIFT)
-#define HARMONY_GAIN_RO_SHIFT 0
-#define HARMONY_GAIN_RO_MASK (HARMONY_GAIN_OUT << HARMONY_GAIN_RO_SHIFT)
-
-#define HARMONY_MAX_OUT (HARMONY_GAIN_RO_MASK >> HARMONY_GAIN_RO_SHIFT)
-#define HARMONY_MAX_IN (HARMONY_GAIN_RI_MASK >> HARMONY_GAIN_RI_SHIFT)
-#define HARMONY_MAX_MON (HARMONY_GAIN_MA_MASK >> HARMONY_GAIN_MA_SHIFT)
-
-#define HARMONY_SR_8KHZ 0x08
-#define HARMONY_SR_16KHZ 0x09
-#define HARMONY_SR_27KHZ 0x0A
-#define HARMONY_SR_32KHZ 0x0B
-#define HARMONY_SR_48KHZ 0x0E
-#define HARMONY_SR_9KHZ 0x0F
-#define HARMONY_SR_5KHZ 0x10
-#define HARMONY_SR_11KHZ 0x11
-#define HARMONY_SR_18KHZ 0x12
-#define HARMONY_SR_22KHZ 0x13
-#define HARMONY_SR_37KHZ 0x14
-#define HARMONY_SR_44KHZ 0x15
-#define HARMONY_SR_33KHZ 0x16
-#define HARMONY_SR_6KHZ 0x17
-
-#endif /* __HARMONY_H__ */
diff --git a/ANDROID_3.4.5/sound/pci/Kconfig b/ANDROID_3.4.5/sound/pci/Kconfig
deleted file mode 100644
index 5ca0939e..00000000
--- a/ANDROID_3.4.5/sound/pci/Kconfig
+++ /dev/null
@@ -1,872 +0,0 @@
-# ALSA PCI drivers
-
-config SND_TEA575X
- tristate
- depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 || RADIO_MAXIRADIO
- default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 || RADIO_MAXIRADIO
-
-menuconfig SND_PCI
- bool "PCI sound devices"
- depends on PCI
- default y
- help
- Support for sound devices connected via the PCI bus.
-
-if SND_PCI
-
-config SND_AD1889
- tristate "Analog Devices AD1889"
- select SND_AC97_CODEC
- help
- Say Y here to include support for the integrated AC97 sound
- device found in particular on the Hewlett-Packard [BCJ]-xxx0
- class PA-RISC workstations, using the AD1819 codec.
-
- To compile this as a module, choose M here: the module
- will be called snd-ad1889.
-
-config SND_ALS300
- tristate "Avance Logic ALS300/ALS300+"
- select SND_PCM
- select SND_AC97_CODEC
- select SND_OPL3_LIB
- help
- Say 'Y' or 'M' to include support for Avance Logic ALS300/ALS300+
-
- To compile this driver as a module, choose M here: the module
- will be called snd-als300
-
-config SND_ALS4000
- tristate "Avance Logic ALS4000"
- depends on ISA_DMA_API
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_PCM
- select SND_SB_COMMON
- help
- Say Y here to include support for soundcards based on Avance Logic
- ALS4000 chips.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-als4000.
-
-config SND_ALI5451
- tristate "ALi M5451 PCI Audio Controller"
- select SND_MPU401_UART
- select SND_AC97_CODEC
- help
- Say Y here to include support for the integrated AC97 sound
- device on motherboards using the ALi M5451 Audio Controller
- (M1535/M1535D/M1535+/M1535D+ south bridges). Newer chipsets
- use the "Intel/SiS/nVidia/AMD/ALi AC97 Controller" driver.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-ali5451.
-
-config SND_ASIHPI
- tristate "AudioScience ASIxxxx"
- depends on X86
- select FW_LOADER
- select SND_PCM
- select SND_HWDEP
- help
- Say Y here to include support for AudioScience ASI sound cards.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-asihpi.
-
-config SND_ATIIXP
- tristate "ATI IXP AC97 Controller"
- select SND_AC97_CODEC
- help
- Say Y here to include support for the integrated AC97 sound
- device on motherboards with ATI chipsets (ATI IXP 150/200/250/
- 300/400).
-
- To compile this driver as a module, choose M here: the module
- will be called snd-atiixp.
-
-config SND_ATIIXP_MODEM
- tristate "ATI IXP Modem"
- select SND_AC97_CODEC
- help
- Say Y here to include support for the integrated MC97 modem on
- motherboards with ATI chipsets (ATI IXP 150/200/250).
-
- To compile this driver as a module, choose M here: the module
- will be called snd-atiixp-modem.
-
-config SND_AU8810
- tristate "Aureal Advantage"
- select SND_MPU401_UART
- select SND_AC97_CODEC
- help
- Say Y here to include support for Aureal Advantage soundcards.
-
- Supported features: Hardware Mixer, SRC, EQ and SPDIF output.
- 3D support code is in place, but not yet useable. For more info,
- email the ALSA developer list, or <mjander@users.sourceforge.net>.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-au8810.
-
-config SND_AU8820
- tristate "Aureal Vortex"
- select SND_MPU401_UART
- select SND_AC97_CODEC
- help
- Say Y here to include support for Aureal Vortex soundcards.
-
- Supported features: Hardware Mixer and SRC. For more info, email
- the ALSA developer list, or <mjander@users.sourceforge.net>.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-au8820.
-
-config SND_AU8830
- tristate "Aureal Vortex 2"
- select SND_MPU401_UART
- select SND_AC97_CODEC
- help
- Say Y here to include support for Aureal Vortex 2 soundcards.
-
- Supported features: Hardware Mixer, SRC, EQ and SPDIF output.
- 3D support code is in place, but not yet useable. For more info,
- email the ALSA developer list, or <mjander@users.sourceforge.net>.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-au8830.
-
-config SND_AW2
- tristate "Emagic Audiowerk 2"
- help
- Say Y here to include support for Emagic Audiowerk 2 soundcards.
-
- Supported features: Analog and SPDIF output. Analog or SPDIF input.
- Note: Switch between analog and digital input does not always work.
- It can produce continuous noise. The workaround is to switch again
- (and again) between digital and analog input until it works.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-aw2.
-
-
-config SND_AZT3328
- tristate "Aztech AZF3328 / PCI168"
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_PCM
- select SND_RAWMIDI
- select SND_AC97_CODEC
- help
- Say Y here to include support for Aztech AZF3328 (PCI168)
- soundcards.
-
- Supported features: AC97-"conformant" mixer, MPU401/OPL3, analog I/O
- (16bit/8bit, many sample rates [<= 66.2kHz], NO hardware mixing),
- Digital Enhanced Game Port, 1.024MHz multimedia sequencer timer,
- ext. codec (I2S port), onboard amp (4W/4Ohms/ch), suspend/resume.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-azt3328.
-
-config SND_BT87X
- tristate "Bt87x Audio Capture"
- select SND_PCM
- help
- If you want to record audio from TV cards based on
- Brooktree Bt878/Bt879 chips, say Y here and read
- <file:Documentation/sound/alsa/Bt87x.txt>.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-bt87x.
-
-config SND_BT87X_OVERCLOCK
- bool "Bt87x Audio overclocking"
- depends on SND_BT87X
- help
- Say Y here if 448000 Hz isn't enough for you and you want to
- record from the analog input with up to 1792000 Hz.
-
- Higher sample rates won't hurt your hardware, but audio
- quality may suffer.
-
-config SND_CA0106
- tristate "SB Audigy LS / Live 24bit"
- select SND_AC97_CODEC
- select SND_RAWMIDI
- select SND_VMASTER
- help
- Say Y here to include support for the Sound Blaster Audigy LS
- and Live 24bit.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-ca0106.
-
-config SND_CMIPCI
- tristate "C-Media 8338, 8738, 8768, 8770"
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_PCM
- help
- If you want to use soundcards based on C-Media CMI8338, CMI8738,
- CMI8768 or CMI8770 chips, say Y here and read
- <file:Documentation/sound/alsa/CMIPCI.txt>.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-cmipci.
-
-config SND_OXYGEN_LIB
- tristate
-
-config SND_OXYGEN
- tristate "C-Media 8786, 8787, 8788 (Oxygen)"
- select SND_OXYGEN_LIB
- select SND_PCM
- select SND_MPU401_UART
- help
- Say Y here to include support for sound cards based on the
- C-Media CMI8788 (Oxygen HD Audio) chip:
- * Asound A-8788
- * Asus Xonar DG
- * AuzenTech X-Meridian
- * AuzenTech X-Meridian 2G
- * Bgears b-Enspirer
- * Club3D Theatron DTS
- * HT-Omega Claro (plus)
- * HT-Omega Claro halo (XT)
- * Kuroutoshikou CMI8787-HG2PCI
- * Razer Barracuda AC-1
- * Sondigo Inferno
- * TempoTec/MediaTek HiFier Fantasia
- * TempoTec/MediaTek HiFier Serenade
-
- To compile this driver as a module, choose M here: the module
- will be called snd-oxygen.
-
-config SND_CS4281
- tristate "Cirrus Logic (Sound Fusion) CS4281"
- select SND_OPL3_LIB
- select SND_RAWMIDI
- select SND_AC97_CODEC
- help
- Say Y here to include support for Cirrus Logic CS4281 chips.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-cs4281.
-
-config SND_CS46XX
- tristate "Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x"
- select SND_RAWMIDI
- select SND_AC97_CODEC
- help
- Say Y here to include support for Cirrus Logic CS4610/CS4612/
- CS4614/CS4615/CS4622/CS4624/CS4630/CS4280 chips.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-cs46xx.
-
-config SND_CS46XX_NEW_DSP
- bool "Cirrus Logic (Sound Fusion) New DSP support"
- depends on SND_CS46XX
- default y
- help
- Say Y here to use a new DSP image for SPDIF and dual codecs.
-
- This works better than the old code, so say Y.
-
-config SND_CS5530
- tristate "CS5530 Audio"
- depends on ISA_DMA_API
- select SND_SB16_DSP
- help
- Say Y here to include support for audio on Cyrix/NatSemi CS5530 chips.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-cs5530.
-
-config SND_CS5535AUDIO
- tristate "CS5535/CS5536 Audio"
- select SND_PCM
- select SND_AC97_CODEC
- help
- Say Y here to include support for audio on CS5535 chips. It is
- referred to as NS CS5535 IO or AMD CS5535 IO companion in
- various literature. This driver also supports the CS5536 audio
- device. However, for both chips, on certain boards, you may
- need to use ac97_quirk=hp_only if your board has physically
- mapped headphone out to master output. If that works for you,
- send lspci -vvv output to the mailing list so that your board
- can be identified in the quirks list.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-cs5535audio.
-
-config SND_CTXFI
- tristate "Creative Sound Blaster X-Fi"
- select SND_PCM
- help
- If you want to use soundcards based on Creative Sound Blastr X-Fi
- boards with 20k1 or 20k2 chips, say Y here.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-ctxfi.
-
-config SND_DARLA20
- tristate "(Echoaudio) Darla20"
- select FW_LOADER
- select SND_PCM
- help
- Say 'Y' or 'M' to include support for Echoaudio Darla.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-darla20
-
-config SND_GINA20
- tristate "(Echoaudio) Gina20"
- select FW_LOADER
- select SND_PCM
- help
- Say 'Y' or 'M' to include support for Echoaudio Gina.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-gina20
-
-config SND_LAYLA20
- tristate "(Echoaudio) Layla20"
- select FW_LOADER
- select SND_RAWMIDI
- select SND_PCM
- help
- Say 'Y' or 'M' to include support for Echoaudio Layla.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-layla20
-
-config SND_DARLA24
- tristate "(Echoaudio) Darla24"
- select FW_LOADER
- select SND_PCM
- help
- Say 'Y' or 'M' to include support for Echoaudio Darla24.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-darla24
-
-config SND_GINA24
- tristate "(Echoaudio) Gina24"
- select FW_LOADER
- select SND_PCM
- help
- Say 'Y' or 'M' to include support for Echoaudio Gina24.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-gina24
-
-config SND_LAYLA24
- tristate "(Echoaudio) Layla24"
- select FW_LOADER
- select SND_RAWMIDI
- select SND_PCM
- help
- Say 'Y' or 'M' to include support for Echoaudio Layla24.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-layla24
-
-config SND_MONA
- tristate "(Echoaudio) Mona"
- select FW_LOADER
- select SND_RAWMIDI
- select SND_PCM
- help
- Say 'Y' or 'M' to include support for Echoaudio Mona.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-mona
-
-config SND_MIA
- tristate "(Echoaudio) Mia"
- select FW_LOADER
- select SND_RAWMIDI
- select SND_PCM
- help
- Say 'Y' or 'M' to include support for Echoaudio Mia and Mia-midi.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-mia
-
-config SND_ECHO3G
- tristate "(Echoaudio) 3G cards"
- select FW_LOADER
- select SND_RAWMIDI
- select SND_PCM
- help
- Say 'Y' or 'M' to include support for Echoaudio Gina3G and Layla3G.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-echo3g
-
-config SND_INDIGO
- tristate "(Echoaudio) Indigo"
- select FW_LOADER
- select SND_PCM
- help
- Say 'Y' or 'M' to include support for Echoaudio Indigo.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-indigo
-
-config SND_INDIGOIO
- tristate "(Echoaudio) Indigo IO"
- select FW_LOADER
- select SND_PCM
- help
- Say 'Y' or 'M' to include support for Echoaudio Indigo IO.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-indigoio
-
-config SND_INDIGODJ
- tristate "(Echoaudio) Indigo DJ"
- select FW_LOADER
- select SND_PCM
- help
- Say 'Y' or 'M' to include support for Echoaudio Indigo DJ.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-indigodj
-
-config SND_INDIGOIOX
- tristate "(Echoaudio) Indigo IOx"
- select FW_LOADER
- select SND_PCM
- help
- Say 'Y' or 'M' to include support for Echoaudio Indigo IOx.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-indigoiox
-
-config SND_INDIGODJX
- tristate "(Echoaudio) Indigo DJx"
- select FW_LOADER
- select SND_PCM
- help
- Say 'Y' or 'M' to include support for Echoaudio Indigo DJx.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-indigodjx
-
-config SND_EMU10K1
- tristate "Emu10k1 (SB Live!, Audigy, E-mu APS)"
- select FW_LOADER
- select SND_HWDEP
- select SND_RAWMIDI
- select SND_AC97_CODEC
- help
- Say Y to include support for Sound Blaster PCI 512, Live!,
- Audigy and E-mu APS (partially supported) soundcards.
-
- The confusing multitude of mixer controls is documented in
- <file:Documentation/sound/alsa/SB-Live-mixer.txt> and
- <file:Documentation/sound/alsa/Audigy-mixer.txt>.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-emu10k1.
-
-config SND_EMU10K1X
- tristate "Emu10k1X (Dell OEM Version)"
- select SND_AC97_CODEC
- select SND_RAWMIDI
- help
- Say Y here to include support for the Dell OEM version of the
- Sound Blaster Live!.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-emu10k1x.
-
-config SND_ENS1370
- tristate "(Creative) Ensoniq AudioPCI 1370"
- select SND_RAWMIDI
- select SND_PCM
- help
- Say Y here to include support for Ensoniq AudioPCI ES1370 chips.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-ens1370.
-
-config SND_ENS1371
- tristate "(Creative) Ensoniq AudioPCI 1371/1373"
- select SND_RAWMIDI
- select SND_AC97_CODEC
- help
- Say Y here to include support for Ensoniq AudioPCI ES1371 chips and
- Sound Blaster PCI 64 or 128 soundcards.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-ens1371.
-
-config SND_ES1938
- tristate "ESS ES1938/1946/1969 (Solo-1)"
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_AC97_CODEC
- help
- Say Y here to include support for soundcards based on ESS Solo-1
- (ES1938, ES1946, ES1969) chips.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-es1938.
-
-config SND_ES1968
- tristate "ESS ES1968/1978 (Maestro-1/2/2E)"
- select SND_MPU401_UART
- select SND_AC97_CODEC
- help
- Say Y here to include support for soundcards based on ESS Maestro
- 1/2/2E chips.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-es1968.
-
-config SND_ES1968_INPUT
- bool "Enable input device for es1968 volume buttons"
- depends on SND_ES1968
- depends on INPUT=y || INPUT=SND_ES1968
- help
- If you say Y here, you will get an input device which reports
- keypresses for the volume buttons connected to the es1968 chip.
- If you say N the buttons will directly control the master volume.
- It is recommended to say Y.
-
-config SND_ES1968_RADIO
- bool "Enable TEA5757 radio tuner support for es1968"
- depends on SND_ES1968
- depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_ES1968
- help
- Say Y here to include support for TEA5757 radio tuner integrated on
- some MediaForte cards (e.g. SF64-PCE2).
-
-config SND_FM801
- tristate "ForteMedia FM801"
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_AC97_CODEC
- help
- Say Y here to include support for soundcards based on the ForteMedia
- FM801 chip.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-fm801.
-
-config SND_FM801_TEA575X_BOOL
- bool "ForteMedia FM801 + TEA5757 tuner"
- depends on SND_FM801
- depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_FM801
- help
- Say Y here to include support for soundcards based on the ForteMedia
- FM801 chip with a TEA5757 tuner (MediaForte SF256-PCS, SF256-PCP and
- SF64-PCR) into the snd-fm801 driver.
-
-source "sound/pci/hda/Kconfig"
-
-config SND_HDSP
- tristate "RME Hammerfall DSP Audio"
- select SND_HWDEP
- select SND_RAWMIDI
- select SND_PCM
- help
- Say Y here to include support for RME Hammerfall DSP Audio
- soundcards.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-hdsp.
-
-comment "Don't forget to add built-in firmwares for HDSP driver"
- depends on SND_HDSP=y
-
-config SND_HDSPM
- tristate "RME Hammerfall DSP MADI/RayDAT/AIO"
- select SND_HWDEP
- select SND_RAWMIDI
- select SND_PCM
- help
- Say Y here to include support for RME Hammerfall DSP MADI,
- RayDAT and AIO soundcards.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-hdspm.
-
-config SND_ICE1712
- tristate "ICEnsemble ICE1712 (Envy24)"
- select SND_MPU401_UART
- select SND_AC97_CODEC
- select BITREVERSE
- help
- Say Y here to include support for soundcards based on the
- ICE1712 (Envy24) chip.
-
- Currently supported hardware is: M-Audio Delta 1010(LT),
- DiO 2496, 66, 44, 410, Audiophile 24/96; Digigram VX442;
- TerraTec EWX 24/96, EWS 88MT/D, DMX 6Fire, Phase 88;
- Hoontech SoundTrack DSP 24/Value/Media7.1; Event EZ8;
- Lionstracs Mediastation, Terrasoniq TS 88.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-ice1712.
-
-config SND_ICE1724
- tristate "ICE/VT1724/1720 (Envy24HT/PT)"
- select SND_RAWMIDI
- select SND_AC97_CODEC
- select SND_VMASTER
- help
- Say Y here to include support for soundcards based on
- ICE/VT1724/1720 (Envy24HT/PT) chips.
-
- Currently supported hardware is: AMP AUDIO2000; M-Audio
- Revolution 5.1, 7.1, Audiophile 192; TerraTec Aureon 5.1 Sky,
- 7.1 Space/Universe, Phase 22/28; Onkyo SE-90PCI, SE-200PCI;
- AudioTrak Prodigy 192, 7.1 (HIFI/LT/XT), HD2; Hercules
- Fortissimo IV; ESI Juli@; Pontis MS300; EGO-SYS WaveTerminal
- 192M; Albatron K8X800 Pro II; Chaintech ZNF3-150/250, 9CJS,
- AV-710; Shuttle SN25P.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-ice1724.
-
-config SND_INTEL8X0
- tristate "Intel/SiS/nVidia/AMD/ALi AC97 Controller"
- select SND_AC97_CODEC
- help
- Say Y here to include support for the integrated AC97 sound
- device on motherboards with Intel/SiS/nVidia/AMD chipsets, or
- ALi chipsets using the M5455 Audio Controller. (There is a
- separate driver for ALi M5451 Audio Controllers.)
-
- To compile this driver as a module, choose M here: the module
- will be called snd-intel8x0.
-
-config SND_INTEL8X0M
- tristate "Intel/SiS/nVidia/AMD MC97 Modem"
- select SND_AC97_CODEC
- help
- Say Y here to include support for the integrated MC97 modem on
- motherboards with Intel/SiS/nVidia/AMD chipsets.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-intel8x0m.
-
-config SND_KORG1212
- tristate "Korg 1212 IO"
- select SND_PCM
- help
- Say Y here to include support for Korg 1212IO soundcards.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-korg1212.
-
-config SND_LOLA
- tristate "Digigram Lola"
- select SND_PCM
- help
- Say Y to include support for Digigram Lola boards.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-lola.
-
-config SND_LX6464ES
- tristate "Digigram LX6464ES"
- select SND_PCM
- help
- Say Y here to include support for Digigram LX6464ES boards.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-lx6464es.
-
-
-config SND_MAESTRO3
- tristate "ESS Allegro/Maestro3"
- select SND_AC97_CODEC
- help
- Say Y here to include support for soundcards based on ESS Maestro 3
- (Allegro) chips.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-maestro3.
-
-config SND_MAESTRO3_INPUT
- bool "Enable input device for maestro3 volume buttons"
- depends on SND_MAESTRO3
- depends on INPUT=y || INPUT=SND_MAESTRO3
- help
- If you say Y here, you will get an input device which reports
- keypresses for the volume buttons connected to the maestro3 chip.
- If you say N the buttons will directly control the master volume.
- It is recommended to say Y.
-
-config SND_MIXART
- tristate "Digigram miXart"
- select SND_HWDEP
- select SND_PCM
- help
- If you want to use Digigram miXart soundcards, say Y here and
- read <file:Documentation/sound/alsa/MIXART.txt>.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-mixart.
-
-config SND_NM256
- tristate "NeoMagic NM256AV/ZX"
- select SND_AC97_CODEC
- help
- Say Y here to include support for NeoMagic NM256AV/ZX chips.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-nm256.
-
-config SND_PCXHR
- tristate "Digigram PCXHR"
- select SND_PCM
- select SND_HWDEP
- help
- Say Y here to include support for Digigram PCXHR boards.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-pcxhr.
-
-config SND_RIPTIDE
- tristate "Conexant Riptide"
- select FW_LOADER
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_AC97_CODEC
- help
- Say 'Y' or 'M' to include support for Conexant Riptide chip.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-riptide
-
-config SND_RME32
- tristate "RME Digi32, 32/8, 32 PRO"
- select SND_PCM
- help
- Say Y to include support for RME Digi32, Digi32 PRO and
- Digi32/8 (Sek'd Prodif32, Prodif96 and Prodif Gold) audio
- devices.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-rme32.
-
-config SND_RME96
- tristate "RME Digi96, 96/8, 96/8 PRO"
- select SND_PCM
- help
- Say Y here to include support for RME Digi96, Digi96/8 and
- Digi96/8 PRO/PAD/PST soundcards.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-rme96.
-
-config SND_RME9652
- tristate "RME Digi9652 (Hammerfall)"
- select SND_PCM
- help
- Say Y here to include support for RME Hammerfall (RME
- Digi9652/Digi9636) soundcards.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-rme9652.
-
-config SND_SIS7019
- tristate "SiS 7019 Audio Accelerator"
- depends on X86 && !X86_64
- select SND_AC97_CODEC
- help
- Say Y here to include support for the SiS 7019 Audio Accelerator.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-sis7019.
-
-config SND_SONICVIBES
- tristate "S3 SonicVibes"
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_AC97_CODEC
- help
- Say Y here to include support for soundcards based on the S3
- SonicVibes chip.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-sonicvibes.
-
-config SND_TRIDENT
- tristate "Trident 4D-Wave DX/NX; SiS 7018"
- select SND_MPU401_UART
- select SND_AC97_CODEC
- help
- Say Y here to include support for soundcards based on Trident
- 4D-Wave DX/NX or SiS 7018 chips.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-trident.
-
-config SND_VIA82XX
- tristate "VIA 82C686A/B, 8233/8235 AC97 Controller"
- select SND_MPU401_UART
- select SND_AC97_CODEC
- help
- Say Y here to include support for the integrated AC97 sound
- device on motherboards with VIA chipsets.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-via82xx.
-
-config SND_VIA82XX_MODEM
- tristate "VIA 82C686A/B, 8233 based Modems"
- select SND_AC97_CODEC
- help
- Say Y here to include support for the integrated MC97 modem on
- motherboards with VIA chipsets.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-via82xx-modem.
-
-config SND_VIRTUOSO
- tristate "Asus Virtuoso 66/100/200 (Xonar)"
- select SND_OXYGEN_LIB
- select SND_PCM
- select SND_MPU401_UART
- select SND_JACK if INPUT=y || INPUT=SND
- help
- Say Y here to include support for sound cards based on the
- Asus AV66/AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, DS,
- Essence ST (Deluxe), and Essence STX.
- Support for the HDAV1.3 (Deluxe) and HDAV1.3 Slim is experimental;
- for the Xense, missing.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-virtuoso.
-
-config SND_VX222
- tristate "Digigram VX222"
- select SND_VX_LIB
- help
- Say Y here to include support for Digigram VX222 soundcards.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-vx222.
-
-config SND_YMFPCI
- tristate "Yamaha YMF724/740/744/754"
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_AC97_CODEC
- help
- Say Y here to include support for Yamaha PCI audio chips -
- YMF724, YMF724F, YMF740, YMF740C, YMF744, YMF754.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-ymfpci.
-
-endif # SND_PCI
diff --git a/ANDROID_3.4.5/sound/pci/Makefile b/ANDROID_3.4.5/sound/pci/Makefile
deleted file mode 100644
index 54fe325e..00000000
--- a/ANDROID_3.4.5/sound/pci/Makefile
+++ /dev/null
@@ -1,82 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-ad1889-objs := ad1889.o
-snd-als300-objs := als300.o
-snd-als4000-objs := als4000.o
-snd-atiixp-objs := atiixp.o
-snd-atiixp-modem-objs := atiixp_modem.o
-snd-azt3328-objs := azt3328.o
-snd-bt87x-objs := bt87x.o
-snd-cmipci-objs := cmipci.o
-snd-cs4281-objs := cs4281.o
-snd-cs5530-objs := cs5530.o
-snd-ens1370-objs := ens1370.o ak4531_codec.o
-snd-ens1371-objs := ens1371.o
-snd-es1938-objs := es1938.o
-snd-es1968-objs := es1968.o
-snd-fm801-objs := fm801.o
-snd-intel8x0-objs := intel8x0.o
-snd-intel8x0m-objs := intel8x0m.o
-snd-maestro3-objs := maestro3.o
-snd-rme32-objs := rme32.o
-snd-rme96-objs := rme96.o
-snd-sis7019-objs := sis7019.o
-snd-sonicvibes-objs := sonicvibes.o
-snd-via82xx-objs := via82xx.o
-snd-via82xx-modem-objs := via82xx_modem.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_AD1889) += snd-ad1889.o
-obj-$(CONFIG_SND_ALS300) += snd-als300.o
-obj-$(CONFIG_SND_ALS4000) += snd-als4000.o
-obj-$(CONFIG_SND_ATIIXP) += snd-atiixp.o
-obj-$(CONFIG_SND_ATIIXP_MODEM) += snd-atiixp-modem.o
-obj-$(CONFIG_SND_AZT3328) += snd-azt3328.o
-obj-$(CONFIG_SND_BT87X) += snd-bt87x.o
-obj-$(CONFIG_SND_CMIPCI) += snd-cmipci.o
-obj-$(CONFIG_SND_CS4281) += snd-cs4281.o
-obj-$(CONFIG_SND_CS5530) += snd-cs5530.o
-obj-$(CONFIG_SND_ENS1370) += snd-ens1370.o
-obj-$(CONFIG_SND_ENS1371) += snd-ens1371.o
-obj-$(CONFIG_SND_ES1938) += snd-es1938.o
-obj-$(CONFIG_SND_ES1968) += snd-es1968.o
-obj-$(CONFIG_SND_FM801) += snd-fm801.o
-obj-$(CONFIG_SND_INTEL8X0) += snd-intel8x0.o
-obj-$(CONFIG_SND_INTEL8X0M) += snd-intel8x0m.o
-obj-$(CONFIG_SND_MAESTRO3) += snd-maestro3.o
-obj-$(CONFIG_SND_RME32) += snd-rme32.o
-obj-$(CONFIG_SND_RME96) += snd-rme96.o
-obj-$(CONFIG_SND_SIS7019) += snd-sis7019.o
-obj-$(CONFIG_SND_SONICVIBES) += snd-sonicvibes.o
-obj-$(CONFIG_SND_VIA82XX) += snd-via82xx.o
-obj-$(CONFIG_SND_VIA82XX_MODEM) += snd-via82xx-modem.o
-
-obj-$(CONFIG_SND) += \
- ac97/ \
- ali5451/ \
- asihpi/ \
- au88x0/ \
- aw2/ \
- ctxfi/ \
- ca0106/ \
- cs46xx/ \
- cs5535audio/ \
- lola/ \
- lx6464es/ \
- echoaudio/ \
- emu10k1/ \
- hda/ \
- ice1712/ \
- korg1212/ \
- mixart/ \
- nm256/ \
- oxygen/ \
- pcxhr/ \
- riptide/ \
- rme9652/ \
- trident/ \
- ymfpci/ \
- vx222/
diff --git a/ANDROID_3.4.5/sound/pci/ac97/Makefile b/ANDROID_3.4.5/sound/pci/ac97/Makefile
deleted file mode 100644
index 41fa322f..00000000
--- a/ANDROID_3.4.5/sound/pci/ac97/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-ac97-codec-y := ac97_codec.o ac97_pcm.o
-snd-ac97-codec-$(CONFIG_PROC_FS) += ac97_proc.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_AC97_CODEC) += snd-ac97-codec.o
diff --git a/ANDROID_3.4.5/sound/pci/ac97/ac97_codec.c b/ANDROID_3.4.5/sound/pci/ac97/ac97_codec.c
deleted file mode 100644
index 9473fca9..00000000
--- a/ANDROID_3.4.5/sound/pci/ac97/ac97_codec.c
+++ /dev/null
@@ -1,2937 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Universal interface for Audio Codec '97
- *
- * For more details look to AC '97 component specification revision 2.2
- * by Intel Corporation (http://developer.intel.com).
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/tlv.h>
-#include <sound/ac97_codec.h>
-#include <sound/asoundef.h>
-#include <sound/initval.h>
-#include "ac97_id.h"
-
-#include "ac97_patch.c"
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Universal interface for Audio Codec '97");
-MODULE_LICENSE("GPL");
-
-static bool enable_loopback;
-
-module_param(enable_loopback, bool, 0444);
-MODULE_PARM_DESC(enable_loopback, "Enable AC97 ADC/DAC Loopback Control");
-
-#ifdef CONFIG_SND_AC97_POWER_SAVE
-static int power_save = CONFIG_SND_AC97_POWER_SAVE_DEFAULT;
-module_param(power_save, int, 0644);
-MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
- "(in second, 0 = disable).");
-#endif
-/*
-
- */
-
-struct ac97_codec_id {
- unsigned int id;
- unsigned int mask;
- const char *name;
- int (*patch)(struct snd_ac97 *ac97);
- int (*mpatch)(struct snd_ac97 *ac97);
- unsigned int flags;
-};
-
-static const struct ac97_codec_id snd_ac97_codec_id_vendors[] = {
-{ 0x41445300, 0xffffff00, "Analog Devices", NULL, NULL },
-{ 0x414b4d00, 0xffffff00, "Asahi Kasei", NULL, NULL },
-{ 0x414c4300, 0xffffff00, "Realtek", NULL, NULL },
-{ 0x414c4700, 0xffffff00, "Realtek", NULL, NULL },
-/*
- * This is an _inofficial_ Aztech Labs entry
- * (value might differ from unknown official Aztech ID),
- * currently used by the AC97 emulation of the almost-AC97 PCI168 card.
- */
-{ 0x415a5400, 0xffffff00, "Aztech Labs (emulated)", NULL, NULL },
-{ 0x434d4900, 0xffffff00, "C-Media Electronics", NULL, NULL },
-{ 0x43525900, 0xffffff00, "Cirrus Logic", NULL, NULL },
-{ 0x43585400, 0xffffff00, "Conexant", NULL, NULL },
-{ 0x44543000, 0xffffff00, "Diamond Technology", NULL, NULL },
-{ 0x454d4300, 0xffffff00, "eMicro", NULL, NULL },
-{ 0x45838300, 0xffffff00, "ESS Technology", NULL, NULL },
-{ 0x48525300, 0xffffff00, "Intersil", NULL, NULL },
-{ 0x49434500, 0xffffff00, "ICEnsemble", NULL, NULL },
-{ 0x49544500, 0xffffff00, "ITE Tech.Inc", NULL, NULL },
-{ 0x4e534300, 0xffffff00, "National Semiconductor", NULL, NULL },
-{ 0x50534300, 0xffffff00, "Philips", NULL, NULL },
-{ 0x53494c00, 0xffffff00, "Silicon Laboratory", NULL, NULL },
-{ 0x53544d00, 0xffffff00, "STMicroelectronics", NULL, NULL },
-{ 0x54524100, 0xffffff00, "TriTech", NULL, NULL },
-{ 0x54584e00, 0xffffff00, "Texas Instruments", NULL, NULL },
-{ 0x56494100, 0xffffff00, "VIA Technologies", NULL, NULL },
-{ 0x57454300, 0xffffff00, "Winbond", NULL, NULL },
-{ 0x574d4c00, 0xffffff00, "Wolfson", NULL, NULL },
-{ 0x594d4800, 0xffffff00, "Yamaha", NULL, NULL },
-{ 0x83847600, 0xffffff00, "SigmaTel", NULL, NULL },
-{ 0, 0, NULL, NULL, NULL }
-};
-
-static const struct ac97_codec_id snd_ac97_codec_ids[] = {
-{ 0x41445303, 0xffffffff, "AD1819", patch_ad1819, NULL },
-{ 0x41445340, 0xffffffff, "AD1881", patch_ad1881, NULL },
-{ 0x41445348, 0xffffffff, "AD1881A", patch_ad1881, NULL },
-{ 0x41445360, 0xffffffff, "AD1885", patch_ad1885, NULL },
-{ 0x41445361, 0xffffffff, "AD1886", patch_ad1886, NULL },
-{ 0x41445362, 0xffffffff, "AD1887", patch_ad1881, NULL },
-{ 0x41445363, 0xffffffff, "AD1886A", patch_ad1881, NULL },
-{ 0x41445368, 0xffffffff, "AD1888", patch_ad1888, NULL },
-{ 0x41445370, 0xffffffff, "AD1980", patch_ad1980, NULL },
-{ 0x41445372, 0xffffffff, "AD1981A", patch_ad1981a, NULL },
-{ 0x41445374, 0xffffffff, "AD1981B", patch_ad1981b, NULL },
-{ 0x41445375, 0xffffffff, "AD1985", patch_ad1985, NULL },
-{ 0x41445378, 0xffffffff, "AD1986", patch_ad1986, NULL },
-{ 0x414b4d00, 0xffffffff, "AK4540", NULL, NULL },
-{ 0x414b4d01, 0xffffffff, "AK4542", NULL, NULL },
-{ 0x414b4d02, 0xffffffff, "AK4543", NULL, NULL },
-{ 0x414b4d06, 0xffffffff, "AK4544A", NULL, NULL },
-{ 0x414b4d07, 0xffffffff, "AK4545", NULL, NULL },
-{ 0x414c4300, 0xffffff00, "ALC100,100P", NULL, NULL },
-{ 0x414c4710, 0xfffffff0, "ALC200,200P", NULL, NULL },
-{ 0x414c4721, 0xffffffff, "ALC650D", NULL, NULL }, /* already patched */
-{ 0x414c4722, 0xffffffff, "ALC650E", NULL, NULL }, /* already patched */
-{ 0x414c4723, 0xffffffff, "ALC650F", NULL, NULL }, /* already patched */
-{ 0x414c4720, 0xfffffff0, "ALC650", patch_alc650, NULL },
-{ 0x414c4730, 0xffffffff, "ALC101", NULL, NULL },
-{ 0x414c4740, 0xfffffff0, "ALC202", NULL, NULL },
-{ 0x414c4750, 0xfffffff0, "ALC250", NULL, NULL },
-{ 0x414c4760, 0xfffffff0, "ALC655", patch_alc655, NULL },
-{ 0x414c4770, 0xfffffff0, "ALC203", patch_alc203, NULL },
-{ 0x414c4781, 0xffffffff, "ALC658D", NULL, NULL }, /* already patched */
-{ 0x414c4780, 0xfffffff0, "ALC658", patch_alc655, NULL },
-{ 0x414c4790, 0xfffffff0, "ALC850", patch_alc850, NULL },
-{ 0x415a5401, 0xffffffff, "AZF3328", patch_aztech_azf3328, NULL },
-{ 0x434d4941, 0xffffffff, "CMI9738", patch_cm9738, NULL },
-{ 0x434d4961, 0xffffffff, "CMI9739", patch_cm9739, NULL },
-{ 0x434d4969, 0xffffffff, "CMI9780", patch_cm9780, NULL },
-{ 0x434d4978, 0xffffffff, "CMI9761A", patch_cm9761, NULL },
-{ 0x434d4982, 0xffffffff, "CMI9761B", patch_cm9761, NULL },
-{ 0x434d4983, 0xffffffff, "CMI9761A+", patch_cm9761, NULL },
-{ 0x43525900, 0xfffffff8, "CS4297", NULL, NULL },
-{ 0x43525910, 0xfffffff8, "CS4297A", patch_cirrus_spdif, NULL },
-{ 0x43525920, 0xfffffff8, "CS4298", patch_cirrus_spdif, NULL },
-{ 0x43525928, 0xfffffff8, "CS4294", NULL, NULL },
-{ 0x43525930, 0xfffffff8, "CS4299", patch_cirrus_cs4299, NULL },
-{ 0x43525948, 0xfffffff8, "CS4201", NULL, NULL },
-{ 0x43525958, 0xfffffff8, "CS4205", patch_cirrus_spdif, NULL },
-{ 0x43525960, 0xfffffff8, "CS4291", NULL, NULL },
-{ 0x43525970, 0xfffffff8, "CS4202", NULL, NULL },
-{ 0x43585421, 0xffffffff, "HSD11246", NULL, NULL }, // SmartMC II
-{ 0x43585428, 0xfffffff8, "Cx20468", patch_conexant, NULL }, // SmartAMC fixme: the mask might be different
-{ 0x43585430, 0xffffffff, "Cx20468-31", patch_conexant, NULL },
-{ 0x43585431, 0xffffffff, "Cx20551", patch_cx20551, NULL },
-{ 0x44543031, 0xfffffff0, "DT0398", NULL, NULL },
-{ 0x454d4328, 0xffffffff, "EM28028", NULL, NULL }, // same as TR28028?
-{ 0x45838308, 0xffffffff, "ESS1988", NULL, NULL },
-{ 0x48525300, 0xffffff00, "HMP9701", NULL, NULL },
-{ 0x49434501, 0xffffffff, "ICE1230", NULL, NULL },
-{ 0x49434511, 0xffffffff, "ICE1232", NULL, NULL }, // alias VIA VT1611A?
-{ 0x49434514, 0xffffffff, "ICE1232A", NULL, NULL },
-{ 0x49434551, 0xffffffff, "VT1616", patch_vt1616, NULL },
-{ 0x49434552, 0xffffffff, "VT1616i", patch_vt1616, NULL }, // VT1616 compatible (chipset integrated)
-{ 0x49544520, 0xffffffff, "IT2226E", NULL, NULL },
-{ 0x49544561, 0xffffffff, "IT2646E", patch_it2646, NULL },
-{ 0x4e534300, 0xffffffff, "LM4540,43,45,46,48", NULL, NULL }, // only guess --jk
-{ 0x4e534331, 0xffffffff, "LM4549", NULL, NULL },
-{ 0x4e534350, 0xffffffff, "LM4550", patch_lm4550, NULL }, // volume wrap fix
-{ 0x50534304, 0xffffffff, "UCB1400", patch_ucb1400, NULL },
-{ 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH },
-{ 0x53544d02, 0xffffffff, "ST7597", NULL, NULL },
-{ 0x54524102, 0xffffffff, "TR28022", NULL, NULL },
-{ 0x54524103, 0xffffffff, "TR28023", NULL, NULL },
-{ 0x54524106, 0xffffffff, "TR28026", NULL, NULL },
-{ 0x54524108, 0xffffffff, "TR28028", patch_tritech_tr28028, NULL }, // added by xin jin [07/09/99]
-{ 0x54524123, 0xffffffff, "TR28602", NULL, NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)]
-{ 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL },
-{ 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF
-{ 0x56494170, 0xffffffff, "VIA1617A", patch_vt1617a, NULL }, // modified VT1616 with S/PDIF
-{ 0x56494182, 0xffffffff, "VIA1618", patch_vt1618, NULL },
-{ 0x57454301, 0xffffffff, "W83971D", NULL, NULL },
-{ 0x574d4c00, 0xffffffff, "WM9701,WM9701A", NULL, NULL },
-{ 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL},
-{ 0x574d4C04, 0xffffffff, "WM9704M,WM9704Q", patch_wolfson04, NULL},
-{ 0x574d4C05, 0xffffffff, "WM9705,WM9710", patch_wolfson05, NULL},
-{ 0x574d4C09, 0xffffffff, "WM9709", NULL, NULL},
-{ 0x574d4C12, 0xffffffff, "WM9711,WM9712,WM9715", patch_wolfson11, NULL},
-{ 0x574d4c13, 0xffffffff, "WM9713,WM9714", patch_wolfson13, NULL, AC97_DEFAULT_POWER_OFF},
-{ 0x594d4800, 0xffffffff, "YMF743", patch_yamaha_ymf743, NULL },
-{ 0x594d4802, 0xffffffff, "YMF752", NULL, NULL },
-{ 0x594d4803, 0xffffffff, "YMF753", patch_yamaha_ymf753, NULL },
-{ 0x83847600, 0xffffffff, "STAC9700,83,84", patch_sigmatel_stac9700, NULL },
-{ 0x83847604, 0xffffffff, "STAC9701,3,4,5", NULL, NULL },
-{ 0x83847605, 0xffffffff, "STAC9704", NULL, NULL },
-{ 0x83847608, 0xffffffff, "STAC9708,11", patch_sigmatel_stac9708, NULL },
-{ 0x83847609, 0xffffffff, "STAC9721,23", patch_sigmatel_stac9721, NULL },
-{ 0x83847644, 0xffffffff, "STAC9744", patch_sigmatel_stac9744, NULL },
-{ 0x83847650, 0xffffffff, "STAC9750,51", NULL, NULL }, // patch?
-{ 0x83847652, 0xffffffff, "STAC9752,53", NULL, NULL }, // patch?
-{ 0x83847656, 0xffffffff, "STAC9756,57", patch_sigmatel_stac9756, NULL },
-{ 0x83847658, 0xffffffff, "STAC9758,59", patch_sigmatel_stac9758, NULL },
-{ 0x83847666, 0xffffffff, "STAC9766,67", NULL, NULL }, // patch?
-{ 0, 0, NULL, NULL, NULL }
-};
-
-
-static void update_power_regs(struct snd_ac97 *ac97);
-#ifdef CONFIG_SND_AC97_POWER_SAVE
-#define ac97_is_power_save_mode(ac97) \
- ((ac97->scaps & AC97_SCAP_POWER_SAVE) && power_save)
-#else
-#define ac97_is_power_save_mode(ac97) 0
-#endif
-
-
-/*
- * I/O routines
- */
-
-static int snd_ac97_valid_reg(struct snd_ac97 *ac97, unsigned short reg)
-{
- /* filter some registers for buggy codecs */
- switch (ac97->id) {
- case AC97_ID_ST_AC97_ID4:
- if (reg == 0x08)
- return 0;
- /* fall through */
- case AC97_ID_ST7597:
- if (reg == 0x22 || reg == 0x7a)
- return 1;
- /* fall through */
- case AC97_ID_AK4540:
- case AC97_ID_AK4542:
- if (reg <= 0x1c || reg == 0x20 || reg == 0x26 || reg >= 0x7c)
- return 1;
- return 0;
- case AC97_ID_AD1819: /* AD1819 */
- case AC97_ID_AD1881: /* AD1881 */
- case AC97_ID_AD1881A: /* AD1881A */
- if (reg >= 0x3a && reg <= 0x6e) /* 0x59 */
- return 0;
- return 1;
- case AC97_ID_AD1885: /* AD1885 */
- case AC97_ID_AD1886: /* AD1886 */
- case AC97_ID_AD1886A: /* AD1886A - !!verify!! --jk */
- case AC97_ID_AD1887: /* AD1887 - !!verify!! --jk */
- if (reg == 0x5a)
- return 1;
- if (reg >= 0x3c && reg <= 0x6e) /* 0x59 */
- return 0;
- return 1;
- case AC97_ID_STAC9700:
- case AC97_ID_STAC9704:
- case AC97_ID_STAC9705:
- case AC97_ID_STAC9708:
- case AC97_ID_STAC9721:
- case AC97_ID_STAC9744:
- case AC97_ID_STAC9756:
- if (reg <= 0x3a || reg >= 0x5a)
- return 1;
- return 0;
- }
- return 1;
-}
-
-/**
- * snd_ac97_write - write a value on the given register
- * @ac97: the ac97 instance
- * @reg: the register to change
- * @value: the value to set
- *
- * Writes a value on the given register. This will invoke the write
- * callback directly after the register check.
- * This function doesn't change the register cache unlike
- * #snd_ca97_write_cache(), so use this only when you don't want to
- * reflect the change to the suspend/resume state.
- */
-void snd_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short value)
-{
- if (!snd_ac97_valid_reg(ac97, reg))
- return;
- if ((ac97->id & 0xffffff00) == AC97_ID_ALC100) {
- /* Fix H/W bug of ALC100/100P */
- if (reg == AC97_MASTER || reg == AC97_HEADPHONE)
- ac97->bus->ops->write(ac97, AC97_RESET, 0); /* reset audio codec */
- }
- ac97->bus->ops->write(ac97, reg, value);
-}
-
-EXPORT_SYMBOL(snd_ac97_write);
-
-/**
- * snd_ac97_read - read a value from the given register
- *
- * @ac97: the ac97 instance
- * @reg: the register to read
- *
- * Reads a value from the given register. This will invoke the read
- * callback directly after the register check.
- *
- * Returns the read value.
- */
-unsigned short snd_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
-{
- if (!snd_ac97_valid_reg(ac97, reg))
- return 0;
- return ac97->bus->ops->read(ac97, reg);
-}
-
-/* read a register - return the cached value if already read */
-static inline unsigned short snd_ac97_read_cache(struct snd_ac97 *ac97, unsigned short reg)
-{
- if (! test_bit(reg, ac97->reg_accessed)) {
- ac97->regs[reg] = ac97->bus->ops->read(ac97, reg);
- // set_bit(reg, ac97->reg_accessed);
- }
- return ac97->regs[reg];
-}
-
-EXPORT_SYMBOL(snd_ac97_read);
-
-/**
- * snd_ac97_write_cache - write a value on the given register and update the cache
- * @ac97: the ac97 instance
- * @reg: the register to change
- * @value: the value to set
- *
- * Writes a value on the given register and updates the register
- * cache. The cached values are used for the cached-read and the
- * suspend/resume.
- */
-void snd_ac97_write_cache(struct snd_ac97 *ac97, unsigned short reg, unsigned short value)
-{
- if (!snd_ac97_valid_reg(ac97, reg))
- return;
- mutex_lock(&ac97->reg_mutex);
- ac97->regs[reg] = value;
- ac97->bus->ops->write(ac97, reg, value);
- set_bit(reg, ac97->reg_accessed);
- mutex_unlock(&ac97->reg_mutex);
-}
-
-EXPORT_SYMBOL(snd_ac97_write_cache);
-
-/**
- * snd_ac97_update - update the value on the given register
- * @ac97: the ac97 instance
- * @reg: the register to change
- * @value: the value to set
- *
- * Compares the value with the register cache and updates the value
- * only when the value is changed.
- *
- * Returns 1 if the value is changed, 0 if no change, or a negative
- * code on failure.
- */
-int snd_ac97_update(struct snd_ac97 *ac97, unsigned short reg, unsigned short value)
-{
- int change;
-
- if (!snd_ac97_valid_reg(ac97, reg))
- return -EINVAL;
- mutex_lock(&ac97->reg_mutex);
- change = ac97->regs[reg] != value;
- if (change) {
- ac97->regs[reg] = value;
- ac97->bus->ops->write(ac97, reg, value);
- }
- set_bit(reg, ac97->reg_accessed);
- mutex_unlock(&ac97->reg_mutex);
- return change;
-}
-
-EXPORT_SYMBOL(snd_ac97_update);
-
-/**
- * snd_ac97_update_bits - update the bits on the given register
- * @ac97: the ac97 instance
- * @reg: the register to change
- * @mask: the bit-mask to change
- * @value: the value to set
- *
- * Updates the masked-bits on the given register only when the value
- * is changed.
- *
- * Returns 1 if the bits are changed, 0 if no change, or a negative
- * code on failure.
- */
-int snd_ac97_update_bits(struct snd_ac97 *ac97, unsigned short reg, unsigned short mask, unsigned short value)
-{
- int change;
-
- if (!snd_ac97_valid_reg(ac97, reg))
- return -EINVAL;
- mutex_lock(&ac97->reg_mutex);
- change = snd_ac97_update_bits_nolock(ac97, reg, mask, value);
- mutex_unlock(&ac97->reg_mutex);
- return change;
-}
-
-EXPORT_SYMBOL(snd_ac97_update_bits);
-
-/* no lock version - see snd_ac97_update_bits() */
-int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short mask, unsigned short value)
-{
- int change;
- unsigned short old, new;
-
- old = snd_ac97_read_cache(ac97, reg);
- new = (old & ~mask) | (value & mask);
- change = old != new;
- if (change) {
- ac97->regs[reg] = new;
- ac97->bus->ops->write(ac97, reg, new);
- }
- set_bit(reg, ac97->reg_accessed);
- return change;
-}
-
-static int snd_ac97_ad18xx_update_pcm_bits(struct snd_ac97 *ac97, int codec, unsigned short mask, unsigned short value)
-{
- int change;
- unsigned short old, new, cfg;
-
- mutex_lock(&ac97->page_mutex);
- old = ac97->spec.ad18xx.pcmreg[codec];
- new = (old & ~mask) | (value & mask);
- change = old != new;
- if (change) {
- mutex_lock(&ac97->reg_mutex);
- cfg = snd_ac97_read_cache(ac97, AC97_AD_SERIAL_CFG);
- ac97->spec.ad18xx.pcmreg[codec] = new;
- /* select single codec */
- ac97->bus->ops->write(ac97, AC97_AD_SERIAL_CFG,
- (cfg & ~0x7000) |
- ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]);
- /* update PCM bits */
- ac97->bus->ops->write(ac97, AC97_PCM, new);
- /* select all codecs */
- ac97->bus->ops->write(ac97, AC97_AD_SERIAL_CFG,
- cfg | 0x7000);
- mutex_unlock(&ac97->reg_mutex);
- }
- mutex_unlock(&ac97->page_mutex);
- return change;
-}
-
-/*
- * Controls
- */
-
-static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = e->shift_l == e->shift_r ? 1 : 2;
- uinfo->value.enumerated.items = e->mask;
-
- if (uinfo->value.enumerated.item > e->mask - 1)
- uinfo->value.enumerated.item = e->mask - 1;
- strcpy(uinfo->value.enumerated.name, e->texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
- unsigned short val, bitmask;
-
- for (bitmask = 1; bitmask < e->mask; bitmask <<= 1)
- ;
- val = snd_ac97_read_cache(ac97, e->reg);
- ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1);
- if (e->shift_l != e->shift_r)
- ucontrol->value.enumerated.item[1] = (val >> e->shift_r) & (bitmask - 1);
-
- return 0;
-}
-
-static int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
- unsigned short val;
- unsigned short mask, bitmask;
-
- for (bitmask = 1; bitmask < e->mask; bitmask <<= 1)
- ;
- if (ucontrol->value.enumerated.item[0] > e->mask - 1)
- return -EINVAL;
- val = ucontrol->value.enumerated.item[0] << e->shift_l;
- mask = (bitmask - 1) << e->shift_l;
- if (e->shift_l != e->shift_r) {
- if (ucontrol->value.enumerated.item[1] > e->mask - 1)
- return -EINVAL;
- val |= ucontrol->value.enumerated.item[1] << e->shift_r;
- mask |= (bitmask - 1) << e->shift_r;
- }
- return snd_ac97_update_bits(ac97, e->reg, mask, val);
-}
-
-/* save/restore ac97 v2.3 paging */
-static int snd_ac97_page_save(struct snd_ac97 *ac97, int reg, struct snd_kcontrol *kcontrol)
-{
- int page_save = -1;
- if ((kcontrol->private_value & (1<<25)) &&
- (ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23 &&
- (reg >= 0x60 && reg < 0x70)) {
- unsigned short page = (kcontrol->private_value >> 26) & 0x0f;
- mutex_lock(&ac97->page_mutex); /* lock paging */
- page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
- snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page);
- }
- return page_save;
-}
-
-static void snd_ac97_page_restore(struct snd_ac97 *ac97, int page_save)
-{
- if (page_save >= 0) {
- snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save);
- mutex_unlock(&ac97->page_mutex); /* unlock paging */
- }
-}
-
-/* volume and switch controls */
-static int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0x0f;
- int rshift = (kcontrol->private_value >> 12) & 0x0f;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = shift == rshift ? 1 : 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0x0f;
- int rshift = (kcontrol->private_value >> 12) & 0x0f;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0x01;
- int page_save;
-
- page_save = snd_ac97_page_save(ac97, reg, kcontrol);
- ucontrol->value.integer.value[0] = (snd_ac97_read_cache(ac97, reg) >> shift) & mask;
- if (shift != rshift)
- ucontrol->value.integer.value[1] = (snd_ac97_read_cache(ac97, reg) >> rshift) & mask;
- if (invert) {
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- if (shift != rshift)
- ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
- }
- snd_ac97_page_restore(ac97, page_save);
- return 0;
-}
-
-static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0x0f;
- int rshift = (kcontrol->private_value >> 12) & 0x0f;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0x01;
- int err, page_save;
- unsigned short val, val2, val_mask;
-
- page_save = snd_ac97_page_save(ac97, reg, kcontrol);
- val = (ucontrol->value.integer.value[0] & mask);
- if (invert)
- val = mask - val;
- val_mask = mask << shift;
- val = val << shift;
- if (shift != rshift) {
- val2 = (ucontrol->value.integer.value[1] & mask);
- if (invert)
- val2 = mask - val2;
- val_mask |= mask << rshift;
- val |= val2 << rshift;
- }
- err = snd_ac97_update_bits(ac97, reg, val_mask, val);
- snd_ac97_page_restore(ac97, page_save);
-#ifdef CONFIG_SND_AC97_POWER_SAVE
- /* check analog mixer power-down */
- if ((val_mask & AC97_PD_EAPD) &&
- (kcontrol->private_value & (1<<30))) {
- if (val & AC97_PD_EAPD)
- ac97->power_up &= ~(1 << (reg>>1));
- else
- ac97->power_up |= 1 << (reg>>1);
- update_power_regs(ac97);
- }
-#endif
- return err;
-}
-
-static const struct snd_kcontrol_new snd_ac97_controls_master_mono[2] = {
-AC97_SINGLE("Master Mono Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
-AC97_SINGLE("Master Mono Playback Volume", AC97_MASTER_MONO, 0, 31, 1)
-};
-
-static const struct snd_kcontrol_new snd_ac97_controls_tone[2] = {
-AC97_SINGLE("Tone Control - Bass", AC97_MASTER_TONE, 8, 15, 1),
-AC97_SINGLE("Tone Control - Treble", AC97_MASTER_TONE, 0, 15, 1)
-};
-
-static const struct snd_kcontrol_new snd_ac97_controls_pc_beep[2] = {
-AC97_SINGLE("Beep Playback Switch", AC97_PC_BEEP, 15, 1, 1),
-AC97_SINGLE("Beep Playback Volume", AC97_PC_BEEP, 1, 15, 1)
-};
-
-static const struct snd_kcontrol_new snd_ac97_controls_mic_boost =
- AC97_SINGLE("Mic Boost (+20dB)", AC97_MIC, 6, 1, 0);
-
-
-static const char* std_rec_sel[] = {"Mic", "CD", "Video", "Aux", "Line", "Mix", "Mix Mono", "Phone"};
-static const char* std_3d_path[] = {"pre 3D", "post 3D"};
-static const char* std_mix[] = {"Mix", "Mic"};
-static const char* std_mic[] = {"Mic1", "Mic2"};
-
-static const struct ac97_enum std_enum[] = {
-AC97_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 8, std_rec_sel),
-AC97_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, std_3d_path),
-AC97_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 9, 2, std_mix),
-AC97_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 8, 2, std_mic),
-};
-
-static const struct snd_kcontrol_new snd_ac97_control_capture_src =
-AC97_ENUM("Capture Source", std_enum[0]);
-
-static const struct snd_kcontrol_new snd_ac97_control_capture_vol =
-AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 15, 0);
-
-static const struct snd_kcontrol_new snd_ac97_controls_mic_capture[2] = {
-AC97_SINGLE("Mic Capture Switch", AC97_REC_GAIN_MIC, 15, 1, 1),
-AC97_SINGLE("Mic Capture Volume", AC97_REC_GAIN_MIC, 0, 15, 0)
-};
-
-enum {
- AC97_GENERAL_PCM_OUT = 0,
- AC97_GENERAL_STEREO_ENHANCEMENT,
- AC97_GENERAL_3D,
- AC97_GENERAL_LOUDNESS,
- AC97_GENERAL_MONO,
- AC97_GENERAL_MIC,
- AC97_GENERAL_LOOPBACK
-};
-
-static const struct snd_kcontrol_new snd_ac97_controls_general[7] = {
-AC97_ENUM("PCM Out Path & Mute", std_enum[1]),
-AC97_SINGLE("Simulated Stereo Enhancement", AC97_GENERAL_PURPOSE, 14, 1, 0),
-AC97_SINGLE("3D Control - Switch", AC97_GENERAL_PURPOSE, 13, 1, 0),
-AC97_SINGLE("Loudness (bass boost)", AC97_GENERAL_PURPOSE, 12, 1, 0),
-AC97_ENUM("Mono Output Select", std_enum[2]),
-AC97_ENUM("Mic Select", std_enum[3]),
-AC97_SINGLE("ADC/DAC Loopback", AC97_GENERAL_PURPOSE, 7, 1, 0)
-};
-
-static const struct snd_kcontrol_new snd_ac97_controls_3d[2] = {
-AC97_SINGLE("3D Control - Center", AC97_3D_CONTROL, 8, 15, 0),
-AC97_SINGLE("3D Control - Depth", AC97_3D_CONTROL, 0, 15, 0)
-};
-
-static const struct snd_kcontrol_new snd_ac97_controls_center[2] = {
-AC97_SINGLE("Center Playback Switch", AC97_CENTER_LFE_MASTER, 7, 1, 1),
-AC97_SINGLE("Center Playback Volume", AC97_CENTER_LFE_MASTER, 0, 31, 1)
-};
-
-static const struct snd_kcontrol_new snd_ac97_controls_lfe[2] = {
-AC97_SINGLE("LFE Playback Switch", AC97_CENTER_LFE_MASTER, 15, 1, 1),
-AC97_SINGLE("LFE Playback Volume", AC97_CENTER_LFE_MASTER, 8, 31, 1)
-};
-
-static const struct snd_kcontrol_new snd_ac97_control_eapd =
-AC97_SINGLE("External Amplifier", AC97_POWERDOWN, 15, 1, 1);
-
-static const struct snd_kcontrol_new snd_ac97_controls_modem_switches[2] = {
-AC97_SINGLE("Off-hook Switch", AC97_GPIO_STATUS, 0, 1, 0),
-AC97_SINGLE("Caller ID Switch", AC97_GPIO_STATUS, 2, 1, 0)
-};
-
-/* change the existing EAPD control as inverted */
-static void set_inv_eapd(struct snd_ac97 *ac97, struct snd_kcontrol *kctl)
-{
- kctl->private_value = AC97_SINGLE_VALUE(AC97_POWERDOWN, 15, 1, 0);
- snd_ac97_update_bits(ac97, AC97_POWERDOWN, (1<<15), (1<<15)); /* EAPD up */
- ac97->scaps |= AC97_SCAP_INV_EAPD;
-}
-
-static int snd_ac97_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_ac97_spdif_cmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
- IEC958_AES0_NONAUDIO |
- IEC958_AES0_CON_EMPHASIS_5015 |
- IEC958_AES0_CON_NOT_COPYRIGHT;
- ucontrol->value.iec958.status[1] = IEC958_AES1_CON_CATEGORY |
- IEC958_AES1_CON_ORIGINAL;
- ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS;
- return 0;
-}
-
-static int snd_ac97_spdif_pmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- /* FIXME: AC'97 spec doesn't say which bits are used for what */
- ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
- IEC958_AES0_NONAUDIO |
- IEC958_AES0_PRO_FS |
- IEC958_AES0_PRO_EMPHASIS_5015;
- return 0;
-}
-
-static int snd_ac97_spdif_default_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&ac97->reg_mutex);
- ucontrol->value.iec958.status[0] = ac97->spdif_status & 0xff;
- ucontrol->value.iec958.status[1] = (ac97->spdif_status >> 8) & 0xff;
- ucontrol->value.iec958.status[2] = (ac97->spdif_status >> 16) & 0xff;
- ucontrol->value.iec958.status[3] = (ac97->spdif_status >> 24) & 0xff;
- mutex_unlock(&ac97->reg_mutex);
- return 0;
-}
-
-static int snd_ac97_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned int new = 0;
- unsigned short val = 0;
- int change;
-
- new = val = ucontrol->value.iec958.status[0] & (IEC958_AES0_PROFESSIONAL|IEC958_AES0_NONAUDIO);
- if (ucontrol->value.iec958.status[0] & IEC958_AES0_PROFESSIONAL) {
- new |= ucontrol->value.iec958.status[0] & (IEC958_AES0_PRO_FS|IEC958_AES0_PRO_EMPHASIS_5015);
- switch (new & IEC958_AES0_PRO_FS) {
- case IEC958_AES0_PRO_FS_44100: val |= 0<<12; break;
- case IEC958_AES0_PRO_FS_48000: val |= 2<<12; break;
- case IEC958_AES0_PRO_FS_32000: val |= 3<<12; break;
- default: val |= 1<<12; break;
- }
- if ((new & IEC958_AES0_PRO_EMPHASIS) == IEC958_AES0_PRO_EMPHASIS_5015)
- val |= 1<<3;
- } else {
- new |= ucontrol->value.iec958.status[0] & (IEC958_AES0_CON_EMPHASIS_5015|IEC958_AES0_CON_NOT_COPYRIGHT);
- new |= ((ucontrol->value.iec958.status[1] & (IEC958_AES1_CON_CATEGORY|IEC958_AES1_CON_ORIGINAL)) << 8);
- new |= ((ucontrol->value.iec958.status[3] & IEC958_AES3_CON_FS) << 24);
- if ((new & IEC958_AES0_CON_EMPHASIS) == IEC958_AES0_CON_EMPHASIS_5015)
- val |= 1<<3;
- if (!(new & IEC958_AES0_CON_NOT_COPYRIGHT))
- val |= 1<<2;
- val |= ((new >> 8) & 0xff) << 4; // category + original
- switch ((new >> 24) & 0xff) {
- case IEC958_AES3_CON_FS_44100: val |= 0<<12; break;
- case IEC958_AES3_CON_FS_48000: val |= 2<<12; break;
- case IEC958_AES3_CON_FS_32000: val |= 3<<12; break;
- default: val |= 1<<12; break;
- }
- }
-
- mutex_lock(&ac97->reg_mutex);
- change = ac97->spdif_status != new;
- ac97->spdif_status = new;
-
- if (ac97->flags & AC97_CS_SPDIF) {
- int x = (val >> 12) & 0x03;
- switch (x) {
- case 0: x = 1; break; // 44.1
- case 2: x = 0; break; // 48.0
- default: x = 0; break; // illegal.
- }
- change |= snd_ac97_update_bits_nolock(ac97, AC97_CSR_SPDIF, 0x3fff, ((val & 0xcfff) | (x << 12)));
- } else if (ac97->flags & AC97_CX_SPDIF) {
- int v;
- v = new & (IEC958_AES0_CON_EMPHASIS_5015|IEC958_AES0_CON_NOT_COPYRIGHT) ? 0 : AC97_CXR_COPYRGT;
- v |= new & IEC958_AES0_NONAUDIO ? AC97_CXR_SPDIF_AC3 : AC97_CXR_SPDIF_PCM;
- change |= snd_ac97_update_bits_nolock(ac97, AC97_CXR_AUDIO_MISC,
- AC97_CXR_SPDIF_MASK | AC97_CXR_COPYRGT,
- v);
- } else if (ac97->id == AC97_ID_YMF743) {
- change |= snd_ac97_update_bits_nolock(ac97,
- AC97_YMF7X3_DIT_CTRL,
- 0xff38,
- ((val << 4) & 0xff00) |
- ((val << 2) & 0x0038));
- } else {
- unsigned short extst = snd_ac97_read_cache(ac97, AC97_EXTENDED_STATUS);
- snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); /* turn off */
-
- change |= snd_ac97_update_bits_nolock(ac97, AC97_SPDIF, 0x3fff, val);
- if (extst & AC97_EA_SPDIF) {
- snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
- }
- }
- mutex_unlock(&ac97->reg_mutex);
-
- return change;
-}
-
-static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- // int invert = (kcontrol->private_value >> 24) & 0xff;
- unsigned short value, old, new;
- int change;
-
- value = (ucontrol->value.integer.value[0] & mask);
-
- mutex_lock(&ac97->reg_mutex);
- mask <<= shift;
- value <<= shift;
- old = snd_ac97_read_cache(ac97, reg);
- new = (old & ~mask) | value;
- change = old != new;
-
- if (change) {
- unsigned short extst = snd_ac97_read_cache(ac97, AC97_EXTENDED_STATUS);
- snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); /* turn off */
- change = snd_ac97_update_bits_nolock(ac97, reg, mask, value);
- if (extst & AC97_EA_SPDIF)
- snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
- }
- mutex_unlock(&ac97->reg_mutex);
- return change;
-}
-
-static const struct snd_kcontrol_new snd_ac97_controls_spdif[5] = {
- {
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
- .info = snd_ac97_spdif_mask_info,
- .get = snd_ac97_spdif_cmask_get,
- },
- {
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
- .info = snd_ac97_spdif_mask_info,
- .get = snd_ac97_spdif_pmask_get,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
- .info = snd_ac97_spdif_mask_info,
- .get = snd_ac97_spdif_default_get,
- .put = snd_ac97_spdif_default_put,
- },
-
- AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),AC97_EXTENDED_STATUS, 2, 1, 0),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "AC97-SPSA",
- .info = snd_ac97_info_volsw,
- .get = snd_ac97_get_volsw,
- .put = snd_ac97_put_spsa,
- .private_value = AC97_SINGLE_VALUE(AC97_EXTENDED_STATUS, 4, 3, 0)
- },
-};
-
-#define AD18XX_PCM_BITS(xname, codec, lshift, rshift, mask) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_ad18xx_pcm_info_bits, \
- .get = snd_ac97_ad18xx_pcm_get_bits, .put = snd_ac97_ad18xx_pcm_put_bits, \
- .private_value = (codec) | ((lshift) << 8) | ((rshift) << 12) | ((mask) << 16) }
-
-static int snd_ac97_ad18xx_pcm_info_bits(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- int mask = (kcontrol->private_value >> 16) & 0x0f;
- int lshift = (kcontrol->private_value >> 8) & 0x0f;
- int rshift = (kcontrol->private_value >> 12) & 0x0f;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- if (lshift != rshift && (ac97->flags & AC97_STEREO_MUTES))
- uinfo->count = 2;
- else
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_ac97_ad18xx_pcm_get_bits(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- int codec = kcontrol->private_value & 3;
- int lshift = (kcontrol->private_value >> 8) & 0x0f;
- int rshift = (kcontrol->private_value >> 12) & 0x0f;
- int mask = (kcontrol->private_value >> 16) & 0xff;
-
- ucontrol->value.integer.value[0] = mask - ((ac97->spec.ad18xx.pcmreg[codec] >> lshift) & mask);
- if (lshift != rshift && (ac97->flags & AC97_STEREO_MUTES))
- ucontrol->value.integer.value[1] = mask - ((ac97->spec.ad18xx.pcmreg[codec] >> rshift) & mask);
- return 0;
-}
-
-static int snd_ac97_ad18xx_pcm_put_bits(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- int codec = kcontrol->private_value & 3;
- int lshift = (kcontrol->private_value >> 8) & 0x0f;
- int rshift = (kcontrol->private_value >> 12) & 0x0f;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- unsigned short val, valmask;
-
- val = (mask - (ucontrol->value.integer.value[0] & mask)) << lshift;
- valmask = mask << lshift;
- if (lshift != rshift && (ac97->flags & AC97_STEREO_MUTES)) {
- val |= (mask - (ucontrol->value.integer.value[1] & mask)) << rshift;
- valmask |= mask << rshift;
- }
- return snd_ac97_ad18xx_update_pcm_bits(ac97, codec, valmask, val);
-}
-
-#define AD18XX_PCM_VOLUME(xname, codec) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_ad18xx_pcm_info_volume, \
- .get = snd_ac97_ad18xx_pcm_get_volume, .put = snd_ac97_ad18xx_pcm_put_volume, \
- .private_value = codec }
-
-static int snd_ac97_ad18xx_pcm_info_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 31;
- return 0;
-}
-
-static int snd_ac97_ad18xx_pcm_get_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- int codec = kcontrol->private_value & 3;
-
- mutex_lock(&ac97->page_mutex);
- ucontrol->value.integer.value[0] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 0) & 31);
- ucontrol->value.integer.value[1] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 8) & 31);
- mutex_unlock(&ac97->page_mutex);
- return 0;
-}
-
-static int snd_ac97_ad18xx_pcm_put_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- int codec = kcontrol->private_value & 3;
- unsigned short val1, val2;
-
- val1 = 31 - (ucontrol->value.integer.value[0] & 31);
- val2 = 31 - (ucontrol->value.integer.value[1] & 31);
- return snd_ac97_ad18xx_update_pcm_bits(ac97, codec, 0x1f1f, (val1 << 8) | val2);
-}
-
-static const struct snd_kcontrol_new snd_ac97_controls_ad18xx_pcm[2] = {
-AD18XX_PCM_BITS("PCM Playback Switch", 0, 15, 7, 1),
-AD18XX_PCM_VOLUME("PCM Playback Volume", 0)
-};
-
-static const struct snd_kcontrol_new snd_ac97_controls_ad18xx_surround[2] = {
-AD18XX_PCM_BITS("Surround Playback Switch", 1, 15, 7, 1),
-AD18XX_PCM_VOLUME("Surround Playback Volume", 1)
-};
-
-static const struct snd_kcontrol_new snd_ac97_controls_ad18xx_center[2] = {
-AD18XX_PCM_BITS("Center Playback Switch", 2, 15, 15, 1),
-AD18XX_PCM_BITS("Center Playback Volume", 2, 8, 8, 31)
-};
-
-static const struct snd_kcontrol_new snd_ac97_controls_ad18xx_lfe[2] = {
-AD18XX_PCM_BITS("LFE Playback Switch", 2, 7, 7, 1),
-AD18XX_PCM_BITS("LFE Playback Volume", 2, 0, 0, 31)
-};
-
-/*
- *
- */
-
-static void snd_ac97_powerdown(struct snd_ac97 *ac97);
-
-static int snd_ac97_bus_free(struct snd_ac97_bus *bus)
-{
- if (bus) {
- snd_ac97_bus_proc_done(bus);
- kfree(bus->pcms);
- if (bus->private_free)
- bus->private_free(bus);
- kfree(bus);
- }
- return 0;
-}
-
-static int snd_ac97_bus_dev_free(struct snd_device *device)
-{
- struct snd_ac97_bus *bus = device->device_data;
- return snd_ac97_bus_free(bus);
-}
-
-static int snd_ac97_free(struct snd_ac97 *ac97)
-{
- if (ac97) {
-#ifdef CONFIG_SND_AC97_POWER_SAVE
- cancel_delayed_work_sync(&ac97->power_work);
-#endif
- snd_ac97_proc_done(ac97);
- if (ac97->bus)
- ac97->bus->codec[ac97->num] = NULL;
- if (ac97->private_free)
- ac97->private_free(ac97);
- kfree(ac97);
- }
- return 0;
-}
-
-static int snd_ac97_dev_free(struct snd_device *device)
-{
- struct snd_ac97 *ac97 = device->device_data;
- snd_ac97_powerdown(ac97); /* for avoiding click noises during shut down */
- return snd_ac97_free(ac97);
-}
-
-static int snd_ac97_try_volume_mix(struct snd_ac97 * ac97, int reg)
-{
- unsigned short val, mask = AC97_MUTE_MASK_MONO;
-
- if (! snd_ac97_valid_reg(ac97, reg))
- return 0;
-
- switch (reg) {
- case AC97_MASTER_TONE:
- return ac97->caps & AC97_BC_BASS_TREBLE ? 1 : 0;
- case AC97_HEADPHONE:
- return ac97->caps & AC97_BC_HEADPHONE ? 1 : 0;
- case AC97_REC_GAIN_MIC:
- return ac97->caps & AC97_BC_DEDICATED_MIC ? 1 : 0;
- case AC97_3D_CONTROL:
- if (ac97->caps & AC97_BC_3D_TECH_ID_MASK) {
- val = snd_ac97_read(ac97, reg);
- /* if nonzero - fixed and we can't set it */
- return val == 0;
- }
- return 0;
- case AC97_CENTER_LFE_MASTER: /* center */
- if ((ac97->ext_id & AC97_EI_CDAC) == 0)
- return 0;
- break;
- case AC97_CENTER_LFE_MASTER+1: /* lfe */
- if ((ac97->ext_id & AC97_EI_LDAC) == 0)
- return 0;
- reg = AC97_CENTER_LFE_MASTER;
- mask = 0x0080;
- break;
- case AC97_SURROUND_MASTER:
- if ((ac97->ext_id & AC97_EI_SDAC) == 0)
- return 0;
- break;
- }
-
- val = snd_ac97_read(ac97, reg);
- if (!(val & mask)) {
- /* nothing seems to be here - mute flag is not set */
- /* try another test */
- snd_ac97_write_cache(ac97, reg, val | mask);
- val = snd_ac97_read(ac97, reg);
- val = snd_ac97_read(ac97, reg);
- if (!(val & mask))
- return 0; /* nothing here */
- }
- return 1; /* success, useable */
-}
-
-static void check_volume_resolution(struct snd_ac97 *ac97, int reg, unsigned char *lo_max, unsigned char *hi_max)
-{
- unsigned short cbit[3] = { 0x20, 0x10, 0x01 };
- unsigned char max[3] = { 63, 31, 15 };
- int i;
-
- /* first look up the static resolution table */
- if (ac97->res_table) {
- const struct snd_ac97_res_table *tbl;
- for (tbl = ac97->res_table; tbl->reg; tbl++) {
- if (tbl->reg == reg) {
- *lo_max = tbl->bits & 0xff;
- *hi_max = (tbl->bits >> 8) & 0xff;
- return;
- }
- }
- }
-
- *lo_max = *hi_max = 0;
- for (i = 0 ; i < ARRAY_SIZE(cbit); i++) {
- unsigned short val;
- snd_ac97_write(
- ac97, reg,
- AC97_MUTE_MASK_STEREO | cbit[i] | (cbit[i] << 8)
- );
- /* Do the read twice due to buffers on some ac97 codecs.
- * e.g. The STAC9704 returns exactly what you wrote to the register
- * if you read it immediately. This causes the detect routine to fail.
- */
- val = snd_ac97_read(ac97, reg);
- val = snd_ac97_read(ac97, reg);
- if (! *lo_max && (val & 0x7f) == cbit[i])
- *lo_max = max[i];
- if (! *hi_max && ((val >> 8) & 0x7f) == cbit[i])
- *hi_max = max[i];
- if (*lo_max && *hi_max)
- break;
- }
-}
-
-static int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit)
-{
- unsigned short mask, val, orig, res;
-
- mask = 1 << bit;
- orig = snd_ac97_read(ac97, reg);
- val = orig ^ mask;
- snd_ac97_write(ac97, reg, val);
- res = snd_ac97_read(ac97, reg);
- snd_ac97_write_cache(ac97, reg, orig);
- return res == val;
-}
-
-/* check the volume resolution of center/lfe */
-static void snd_ac97_change_volume_params2(struct snd_ac97 * ac97, int reg, int shift, unsigned char *max)
-{
- unsigned short val, val1;
-
- *max = 63;
- val = AC97_MUTE_MASK_STEREO | (0x20 << shift);
- snd_ac97_write(ac97, reg, val);
- val1 = snd_ac97_read(ac97, reg);
- if (val != val1) {
- *max = 31;
- }
- /* reset volume to zero */
- snd_ac97_write_cache(ac97, reg, AC97_MUTE_MASK_STEREO);
-}
-
-static inline int printable(unsigned int x)
-{
- x &= 0xff;
- if (x < ' ' || x >= 0x71) {
- if (x <= 0x89)
- return x - 0x71 + 'A';
- return '?';
- }
- return x;
-}
-
-static struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template,
- struct snd_ac97 * ac97)
-{
- struct snd_kcontrol_new template;
- memcpy(&template, _template, sizeof(template));
- template.index = ac97->num;
- return snd_ctl_new1(&template, ac97);
-}
-
-/*
- * create mute switch(es) for normal stereo controls
- */
-static int snd_ac97_cmute_new_stereo(struct snd_card *card, char *name, int reg,
- int check_stereo, int check_amix,
- struct snd_ac97 *ac97)
-{
- struct snd_kcontrol *kctl;
- int err;
- unsigned short val, val1, mute_mask;
-
- if (! snd_ac97_valid_reg(ac97, reg))
- return 0;
-
- mute_mask = AC97_MUTE_MASK_MONO;
- val = snd_ac97_read(ac97, reg);
- if (check_stereo || (ac97->flags & AC97_STEREO_MUTES)) {
- /* check whether both mute bits work */
- val1 = val | AC97_MUTE_MASK_STEREO;
- snd_ac97_write(ac97, reg, val1);
- if (val1 == snd_ac97_read(ac97, reg))
- mute_mask = AC97_MUTE_MASK_STEREO;
- }
- if (mute_mask == AC97_MUTE_MASK_STEREO) {
- struct snd_kcontrol_new tmp = AC97_DOUBLE(name, reg, 15, 7, 1, 1);
- if (check_amix)
- tmp.private_value |= (1 << 30);
- tmp.index = ac97->num;
- kctl = snd_ctl_new1(&tmp, ac97);
- } else {
- struct snd_kcontrol_new tmp = AC97_SINGLE(name, reg, 15, 1, 1);
- if (check_amix)
- tmp.private_value |= (1 << 30);
- tmp.index = ac97->num;
- kctl = snd_ctl_new1(&tmp, ac97);
- }
- err = snd_ctl_add(card, kctl);
- if (err < 0)
- return err;
- /* mute as default */
- snd_ac97_write_cache(ac97, reg, val | mute_mask);
- return 0;
-}
-
-/*
- * set dB information
- */
-static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
-
-static const unsigned int *find_db_scale(unsigned int maxval)
-{
- switch (maxval) {
- case 0x0f: return db_scale_4bit;
- case 0x1f: return db_scale_5bit;
- case 0x3f: return db_scale_6bit;
- }
- return NULL;
-}
-
-static void set_tlv_db_scale(struct snd_kcontrol *kctl, const unsigned int *tlv)
-{
- kctl->tlv.p = tlv;
- if (tlv)
- kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
-}
-
-/*
- * create a volume for normal stereo/mono controls
- */
-static int snd_ac97_cvol_new(struct snd_card *card, char *name, int reg, unsigned int lo_max,
- unsigned int hi_max, struct snd_ac97 *ac97)
-{
- int err;
- struct snd_kcontrol *kctl;
-
- if (! snd_ac97_valid_reg(ac97, reg))
- return 0;
- if (hi_max) {
- /* invert */
- struct snd_kcontrol_new tmp = AC97_DOUBLE(name, reg, 8, 0, lo_max, 1);
- tmp.index = ac97->num;
- kctl = snd_ctl_new1(&tmp, ac97);
- } else {
- /* invert */
- struct snd_kcontrol_new tmp = AC97_SINGLE(name, reg, 0, lo_max, 1);
- tmp.index = ac97->num;
- kctl = snd_ctl_new1(&tmp, ac97);
- }
- if (reg >= AC97_PHONE && reg <= AC97_PCM)
- set_tlv_db_scale(kctl, db_scale_5bit_12db_max);
- else
- set_tlv_db_scale(kctl, find_db_scale(lo_max));
- err = snd_ctl_add(card, kctl);
- if (err < 0)
- return err;
- snd_ac97_write_cache(
- ac97, reg,
- (snd_ac97_read(ac97, reg) & AC97_MUTE_MASK_STEREO)
- | lo_max | (hi_max << 8)
- );
- return 0;
-}
-
-/*
- * create a mute-switch and a volume for normal stereo/mono controls
- */
-static int snd_ac97_cmix_new_stereo(struct snd_card *card, const char *pfx,
- int reg, int check_stereo, int check_amix,
- struct snd_ac97 *ac97)
-{
- int err;
- char name[44];
- unsigned char lo_max, hi_max;
-
- if (! snd_ac97_valid_reg(ac97, reg))
- return 0;
-
- if (snd_ac97_try_bit(ac97, reg, 15)) {
- sprintf(name, "%s Switch", pfx);
- if ((err = snd_ac97_cmute_new_stereo(card, name, reg,
- check_stereo, check_amix,
- ac97)) < 0)
- return err;
- }
- check_volume_resolution(ac97, reg, &lo_max, &hi_max);
- if (lo_max) {
- sprintf(name, "%s Volume", pfx);
- if ((err = snd_ac97_cvol_new(card, name, reg, lo_max, hi_max, ac97)) < 0)
- return err;
- }
- return 0;
-}
-
-#define snd_ac97_cmix_new(card, pfx, reg, acheck, ac97) \
- snd_ac97_cmix_new_stereo(card, pfx, reg, 0, acheck, ac97)
-#define snd_ac97_cmute_new(card, name, reg, acheck, ac97) \
- snd_ac97_cmute_new_stereo(card, name, reg, 0, acheck, ac97)
-
-static unsigned int snd_ac97_determine_spdif_rates(struct snd_ac97 *ac97);
-
-static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
-{
- struct snd_card *card = ac97->bus->card;
- struct snd_kcontrol *kctl;
- int err;
- unsigned int idx;
- unsigned char max;
-
- /* build master controls */
- /* AD claims to remove this control from AD1887, although spec v2.2 does not allow this */
- if (snd_ac97_try_volume_mix(ac97, AC97_MASTER)) {
- if (ac97->flags & AC97_HAS_NO_MASTER_VOL)
- err = snd_ac97_cmute_new(card, "Master Playback Switch",
- AC97_MASTER, 0, ac97);
- else
- err = snd_ac97_cmix_new(card, "Master Playback",
- AC97_MASTER, 0, ac97);
- if (err < 0)
- return err;
- }
-
- ac97->regs[AC97_CENTER_LFE_MASTER] = AC97_MUTE_MASK_STEREO;
-
- /* build center controls */
- if ((snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER))
- && !(ac97->flags & AC97_AD_MULTI)) {
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_center[0], ac97))) < 0)
- return err;
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_center[1], ac97))) < 0)
- return err;
- snd_ac97_change_volume_params2(ac97, AC97_CENTER_LFE_MASTER, 0, &max);
- kctl->private_value &= ~(0xff << 16);
- kctl->private_value |= (int)max << 16;
- set_tlv_db_scale(kctl, find_db_scale(max));
- snd_ac97_write_cache(ac97, AC97_CENTER_LFE_MASTER, ac97->regs[AC97_CENTER_LFE_MASTER] | max);
- }
-
- /* build LFE controls */
- if ((snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER+1))
- && !(ac97->flags & AC97_AD_MULTI)) {
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_lfe[0], ac97))) < 0)
- return err;
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_lfe[1], ac97))) < 0)
- return err;
- snd_ac97_change_volume_params2(ac97, AC97_CENTER_LFE_MASTER, 8, &max);
- kctl->private_value &= ~(0xff << 16);
- kctl->private_value |= (int)max << 16;
- set_tlv_db_scale(kctl, find_db_scale(max));
- snd_ac97_write_cache(ac97, AC97_CENTER_LFE_MASTER, ac97->regs[AC97_CENTER_LFE_MASTER] | max << 8);
- }
-
- /* build surround controls */
- if ((snd_ac97_try_volume_mix(ac97, AC97_SURROUND_MASTER))
- && !(ac97->flags & AC97_AD_MULTI)) {
- /* Surround Master (0x38) is with stereo mutes */
- if ((err = snd_ac97_cmix_new_stereo(card, "Surround Playback",
- AC97_SURROUND_MASTER, 1, 0,
- ac97)) < 0)
- return err;
- }
-
- /* build headphone controls */
- if (snd_ac97_try_volume_mix(ac97, AC97_HEADPHONE)) {
- if ((err = snd_ac97_cmix_new(card, "Headphone Playback",
- AC97_HEADPHONE, 0, ac97)) < 0)
- return err;
- }
-
- /* build master mono controls */
- if (snd_ac97_try_volume_mix(ac97, AC97_MASTER_MONO)) {
- if ((err = snd_ac97_cmix_new(card, "Master Mono Playback",
- AC97_MASTER_MONO, 0, ac97)) < 0)
- return err;
- }
-
- /* build master tone controls */
- if (!(ac97->flags & AC97_HAS_NO_TONE)) {
- if (snd_ac97_try_volume_mix(ac97, AC97_MASTER_TONE)) {
- for (idx = 0; idx < 2; idx++) {
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_tone[idx], ac97))) < 0)
- return err;
- if (ac97->id == AC97_ID_YMF743 ||
- ac97->id == AC97_ID_YMF753) {
- kctl->private_value &= ~(0xff << 16);
- kctl->private_value |= 7 << 16;
- }
- }
- snd_ac97_write_cache(ac97, AC97_MASTER_TONE, 0x0f0f);
- }
- }
-
- /* build Beep controls */
- if (!(ac97->flags & AC97_HAS_NO_PC_BEEP) &&
- ((ac97->flags & AC97_HAS_PC_BEEP) ||
- snd_ac97_try_volume_mix(ac97, AC97_PC_BEEP))) {
- for (idx = 0; idx < 2; idx++)
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_pc_beep[idx], ac97))) < 0)
- return err;
- set_tlv_db_scale(kctl, db_scale_4bit);
- snd_ac97_write_cache(
- ac97,
- AC97_PC_BEEP,
- (snd_ac97_read(ac97, AC97_PC_BEEP)
- | AC97_MUTE_MASK_MONO | 0x001e)
- );
- }
-
- /* build Phone controls */
- if (!(ac97->flags & AC97_HAS_NO_PHONE)) {
- if (snd_ac97_try_volume_mix(ac97, AC97_PHONE)) {
- if ((err = snd_ac97_cmix_new(card, "Phone Playback",
- AC97_PHONE, 1, ac97)) < 0)
- return err;
- }
- }
-
- /* build MIC controls */
- if (!(ac97->flags & AC97_HAS_NO_MIC)) {
- if (snd_ac97_try_volume_mix(ac97, AC97_MIC)) {
- if ((err = snd_ac97_cmix_new(card, "Mic Playback",
- AC97_MIC, 1, ac97)) < 0)
- return err;
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_mic_boost, ac97))) < 0)
- return err;
- }
- }
-
- /* build Line controls */
- if (snd_ac97_try_volume_mix(ac97, AC97_LINE)) {
- if ((err = snd_ac97_cmix_new(card, "Line Playback",
- AC97_LINE, 1, ac97)) < 0)
- return err;
- }
-
- /* build CD controls */
- if (!(ac97->flags & AC97_HAS_NO_CD)) {
- if (snd_ac97_try_volume_mix(ac97, AC97_CD)) {
- if ((err = snd_ac97_cmix_new(card, "CD Playback",
- AC97_CD, 1, ac97)) < 0)
- return err;
- }
- }
-
- /* build Video controls */
- if (!(ac97->flags & AC97_HAS_NO_VIDEO)) {
- if (snd_ac97_try_volume_mix(ac97, AC97_VIDEO)) {
- if ((err = snd_ac97_cmix_new(card, "Video Playback",
- AC97_VIDEO, 1, ac97)) < 0)
- return err;
- }
- }
-
- /* build Aux controls */
- if (!(ac97->flags & AC97_HAS_NO_AUX)) {
- if (snd_ac97_try_volume_mix(ac97, AC97_AUX)) {
- if ((err = snd_ac97_cmix_new(card, "Aux Playback",
- AC97_AUX, 1, ac97)) < 0)
- return err;
- }
- }
-
- /* build PCM controls */
- if (ac97->flags & AC97_AD_MULTI) {
- unsigned short init_val;
- if (ac97->flags & AC97_STEREO_MUTES)
- init_val = 0x9f9f;
- else
- init_val = 0x9f1f;
- for (idx = 0; idx < 2; idx++)
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_ad18xx_pcm[idx], ac97))) < 0)
- return err;
- set_tlv_db_scale(kctl, db_scale_5bit);
- ac97->spec.ad18xx.pcmreg[0] = init_val;
- if (ac97->scaps & AC97_SCAP_SURROUND_DAC) {
- for (idx = 0; idx < 2; idx++)
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_ad18xx_surround[idx], ac97))) < 0)
- return err;
- set_tlv_db_scale(kctl, db_scale_5bit);
- ac97->spec.ad18xx.pcmreg[1] = init_val;
- }
- if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC) {
- for (idx = 0; idx < 2; idx++)
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_ad18xx_center[idx], ac97))) < 0)
- return err;
- set_tlv_db_scale(kctl, db_scale_5bit);
- for (idx = 0; idx < 2; idx++)
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_ad18xx_lfe[idx], ac97))) < 0)
- return err;
- set_tlv_db_scale(kctl, db_scale_5bit);
- ac97->spec.ad18xx.pcmreg[2] = init_val;
- }
- snd_ac97_write_cache(ac97, AC97_PCM, init_val);
- } else {
- if (!(ac97->flags & AC97_HAS_NO_STD_PCM)) {
- if (ac97->flags & AC97_HAS_NO_PCM_VOL)
- err = snd_ac97_cmute_new(card,
- "PCM Playback Switch",
- AC97_PCM, 0, ac97);
- else
- err = snd_ac97_cmix_new(card, "PCM Playback",
- AC97_PCM, 0, ac97);
- if (err < 0)
- return err;
- }
- }
-
- /* build Capture controls */
- if (!(ac97->flags & AC97_HAS_NO_REC_GAIN)) {
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_control_capture_src, ac97))) < 0)
- return err;
- if (snd_ac97_try_bit(ac97, AC97_REC_GAIN, 15)) {
- err = snd_ac97_cmute_new(card, "Capture Switch",
- AC97_REC_GAIN, 0, ac97);
- if (err < 0)
- return err;
- }
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_control_capture_vol, ac97))) < 0)
- return err;
- set_tlv_db_scale(kctl, db_scale_rec_gain);
- snd_ac97_write_cache(ac97, AC97_REC_SEL, 0x0000);
- snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x0000);
- }
- /* build MIC Capture controls */
- if (snd_ac97_try_volume_mix(ac97, AC97_REC_GAIN_MIC)) {
- for (idx = 0; idx < 2; idx++)
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_mic_capture[idx], ac97))) < 0)
- return err;
- set_tlv_db_scale(kctl, db_scale_rec_gain);
- snd_ac97_write_cache(ac97, AC97_REC_GAIN_MIC, 0x0000);
- }
-
- /* build PCM out path & mute control */
- if (snd_ac97_try_bit(ac97, AC97_GENERAL_PURPOSE, 15)) {
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_PCM_OUT], ac97))) < 0)
- return err;
- }
-
- /* build Simulated Stereo Enhancement control */
- if (ac97->caps & AC97_BC_SIM_STEREO) {
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_STEREO_ENHANCEMENT], ac97))) < 0)
- return err;
- }
-
- /* build 3D Stereo Enhancement control */
- if (snd_ac97_try_bit(ac97, AC97_GENERAL_PURPOSE, 13)) {
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_3D], ac97))) < 0)
- return err;
- }
-
- /* build Loudness control */
- if (ac97->caps & AC97_BC_LOUDNESS) {
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_LOUDNESS], ac97))) < 0)
- return err;
- }
-
- /* build Mono output select control */
- if (snd_ac97_try_bit(ac97, AC97_GENERAL_PURPOSE, 9)) {
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_MONO], ac97))) < 0)
- return err;
- }
-
- /* build Mic select control */
- if (snd_ac97_try_bit(ac97, AC97_GENERAL_PURPOSE, 8)) {
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_MIC], ac97))) < 0)
- return err;
- }
-
- /* build ADC/DAC loopback control */
- if (enable_loopback && snd_ac97_try_bit(ac97, AC97_GENERAL_PURPOSE, 7)) {
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_LOOPBACK], ac97))) < 0)
- return err;
- }
-
- snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, ~AC97_GP_DRSS_MASK, 0x0000);
-
- /* build 3D controls */
- if (ac97->build_ops->build_3d) {
- ac97->build_ops->build_3d(ac97);
- } else {
- if (snd_ac97_try_volume_mix(ac97, AC97_3D_CONTROL)) {
- unsigned short val;
- val = 0x0707;
- snd_ac97_write(ac97, AC97_3D_CONTROL, val);
- val = snd_ac97_read(ac97, AC97_3D_CONTROL);
- val = val == 0x0606;
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
- return err;
- if (val)
- kctl->private_value = AC97_3D_CONTROL | (9 << 8) | (7 << 16);
- if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[1], ac97))) < 0)
- return err;
- if (val)
- kctl->private_value = AC97_3D_CONTROL | (1 << 8) | (7 << 16);
- snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
- }
- }
-
- /* build S/PDIF controls */
-
- /* Hack for ASUS P5P800-VM, which does not indicate S/PDIF capability */
- if (ac97->subsystem_vendor == 0x1043 &&
- ac97->subsystem_device == 0x810f)
- ac97->ext_id |= AC97_EI_SPDIF;
-
- if ((ac97->ext_id & AC97_EI_SPDIF) && !(ac97->scaps & AC97_SCAP_NO_SPDIF)) {
- if (ac97->build_ops->build_spdif) {
- if ((err = ac97->build_ops->build_spdif(ac97)) < 0)
- return err;
- } else {
- for (idx = 0; idx < 5; idx++)
- if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_spdif[idx], ac97))) < 0)
- return err;
- if (ac97->build_ops->build_post_spdif) {
- if ((err = ac97->build_ops->build_post_spdif(ac97)) < 0)
- return err;
- }
- /* set default PCM S/PDIF params */
- /* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */
- snd_ac97_write_cache(ac97, AC97_SPDIF, 0x2a20);
- ac97->rates[AC97_RATES_SPDIF] = snd_ac97_determine_spdif_rates(ac97);
- }
- ac97->spdif_status = SNDRV_PCM_DEFAULT_CON_SPDIF;
- }
-
- /* build chip specific controls */
- if (ac97->build_ops->build_specific)
- if ((err = ac97->build_ops->build_specific(ac97)) < 0)
- return err;
-
- if (snd_ac97_try_bit(ac97, AC97_POWERDOWN, 15)) {
- kctl = snd_ac97_cnew(&snd_ac97_control_eapd, ac97);
- if (! kctl)
- return -ENOMEM;
- if (ac97->scaps & AC97_SCAP_INV_EAPD)
- set_inv_eapd(ac97, kctl);
- if ((err = snd_ctl_add(card, kctl)) < 0)
- return err;
- }
-
- return 0;
-}
-
-static int snd_ac97_modem_build(struct snd_card *card, struct snd_ac97 * ac97)
-{
- int err, idx;
-
- /*
- printk(KERN_DEBUG "AC97_GPIO_CFG = %x\n",
- snd_ac97_read(ac97,AC97_GPIO_CFG));
- */
- snd_ac97_write(ac97, AC97_GPIO_CFG, 0xffff & ~(AC97_GPIO_LINE1_OH));
- snd_ac97_write(ac97, AC97_GPIO_POLARITY, 0xffff & ~(AC97_GPIO_LINE1_OH));
- snd_ac97_write(ac97, AC97_GPIO_STICKY, 0xffff);
- snd_ac97_write(ac97, AC97_GPIO_WAKEUP, 0x0);
- snd_ac97_write(ac97, AC97_MISC_AFE, 0x0);
-
- /* build modem switches */
- for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_modem_switches); idx++)
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_ac97_controls_modem_switches[idx], ac97))) < 0)
- return err;
-
- /* build chip specific controls */
- if (ac97->build_ops->build_specific)
- if ((err = ac97->build_ops->build_specific(ac97)) < 0)
- return err;
-
- return 0;
-}
-
-static int snd_ac97_test_rate(struct snd_ac97 *ac97, int reg, int shadow_reg, int rate)
-{
- unsigned short val;
- unsigned int tmp;
-
- tmp = ((unsigned int)rate * ac97->bus->clock) / 48000;
- snd_ac97_write_cache(ac97, reg, tmp & 0xffff);
- if (shadow_reg)
- snd_ac97_write_cache(ac97, shadow_reg, tmp & 0xffff);
- val = snd_ac97_read(ac97, reg);
- return val == (tmp & 0xffff);
-}
-
-static void snd_ac97_determine_rates(struct snd_ac97 *ac97, int reg, int shadow_reg, unsigned int *r_result)
-{
- unsigned int result = 0;
- unsigned short saved;
-
- if (ac97->bus->no_vra) {
- *r_result = SNDRV_PCM_RATE_48000;
- if ((ac97->flags & AC97_DOUBLE_RATE) &&
- reg == AC97_PCM_FRONT_DAC_RATE)
- *r_result |= SNDRV_PCM_RATE_96000;
- return;
- }
-
- saved = snd_ac97_read(ac97, reg);
- if ((ac97->ext_id & AC97_EI_DRA) && reg == AC97_PCM_FRONT_DAC_RATE)
- snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
- AC97_EA_DRA, 0);
- /* test a non-standard rate */
- if (snd_ac97_test_rate(ac97, reg, shadow_reg, 11000))
- result |= SNDRV_PCM_RATE_CONTINUOUS;
- /* let's try to obtain standard rates */
- if (snd_ac97_test_rate(ac97, reg, shadow_reg, 8000))
- result |= SNDRV_PCM_RATE_8000;
- if (snd_ac97_test_rate(ac97, reg, shadow_reg, 11025))
- result |= SNDRV_PCM_RATE_11025;
- if (snd_ac97_test_rate(ac97, reg, shadow_reg, 16000))
- result |= SNDRV_PCM_RATE_16000;
- if (snd_ac97_test_rate(ac97, reg, shadow_reg, 22050))
- result |= SNDRV_PCM_RATE_22050;
- if (snd_ac97_test_rate(ac97, reg, shadow_reg, 32000))
- result |= SNDRV_PCM_RATE_32000;
- if (snd_ac97_test_rate(ac97, reg, shadow_reg, 44100))
- result |= SNDRV_PCM_RATE_44100;
- if (snd_ac97_test_rate(ac97, reg, shadow_reg, 48000))
- result |= SNDRV_PCM_RATE_48000;
- if ((ac97->flags & AC97_DOUBLE_RATE) &&
- reg == AC97_PCM_FRONT_DAC_RATE) {
- /* test standard double rates */
- snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
- AC97_EA_DRA, AC97_EA_DRA);
- if (snd_ac97_test_rate(ac97, reg, shadow_reg, 64000 / 2))
- result |= SNDRV_PCM_RATE_64000;
- if (snd_ac97_test_rate(ac97, reg, shadow_reg, 88200 / 2))
- result |= SNDRV_PCM_RATE_88200;
- if (snd_ac97_test_rate(ac97, reg, shadow_reg, 96000 / 2))
- result |= SNDRV_PCM_RATE_96000;
- /* some codecs don't support variable double rates */
- if (!snd_ac97_test_rate(ac97, reg, shadow_reg, 76100 / 2))
- result &= ~SNDRV_PCM_RATE_CONTINUOUS;
- snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
- AC97_EA_DRA, 0);
- }
- /* restore the default value */
- snd_ac97_write_cache(ac97, reg, saved);
- if (shadow_reg)
- snd_ac97_write_cache(ac97, shadow_reg, saved);
- *r_result = result;
-}
-
-/* check AC97_SPDIF register to accept which sample rates */
-static unsigned int snd_ac97_determine_spdif_rates(struct snd_ac97 *ac97)
-{
- unsigned int result = 0;
- int i;
- static unsigned short ctl_bits[] = {
- AC97_SC_SPSR_44K, AC97_SC_SPSR_32K, AC97_SC_SPSR_48K
- };
- static unsigned int rate_bits[] = {
- SNDRV_PCM_RATE_44100, SNDRV_PCM_RATE_32000, SNDRV_PCM_RATE_48000
- };
-
- for (i = 0; i < (int)ARRAY_SIZE(ctl_bits); i++) {
- snd_ac97_update_bits(ac97, AC97_SPDIF, AC97_SC_SPSR_MASK, ctl_bits[i]);
- if ((snd_ac97_read(ac97, AC97_SPDIF) & AC97_SC_SPSR_MASK) == ctl_bits[i])
- result |= rate_bits[i];
- }
- return result;
-}
-
-/* look for the codec id table matching with the given id */
-static const struct ac97_codec_id *look_for_codec_id(const struct ac97_codec_id *table,
- unsigned int id)
-{
- const struct ac97_codec_id *pid;
-
- for (pid = table; pid->id; pid++)
- if (pid->id == (id & pid->mask))
- return pid;
- return NULL;
-}
-
-void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, int modem)
-{
- const struct ac97_codec_id *pid;
-
- sprintf(name, "0x%x %c%c%c", id,
- printable(id >> 24),
- printable(id >> 16),
- printable(id >> 8));
- pid = look_for_codec_id(snd_ac97_codec_id_vendors, id);
- if (! pid)
- return;
-
- strcpy(name, pid->name);
- if (ac97 && pid->patch) {
- if ((modem && (pid->flags & AC97_MODEM_PATCH)) ||
- (! modem && ! (pid->flags & AC97_MODEM_PATCH)))
- pid->patch(ac97);
- }
-
- pid = look_for_codec_id(snd_ac97_codec_ids, id);
- if (pid) {
- strcat(name, " ");
- strcat(name, pid->name);
- if (pid->mask != 0xffffffff)
- sprintf(name + strlen(name), " rev %d", id & ~pid->mask);
- if (ac97 && pid->patch) {
- if ((modem && (pid->flags & AC97_MODEM_PATCH)) ||
- (! modem && ! (pid->flags & AC97_MODEM_PATCH)))
- pid->patch(ac97);
- }
- } else
- sprintf(name + strlen(name), " id %x", id & 0xff);
-}
-
-/**
- * snd_ac97_get_short_name - retrieve codec name
- * @ac97: the codec instance
- *
- * Returns the short identifying name of the codec.
- */
-const char *snd_ac97_get_short_name(struct snd_ac97 *ac97)
-{
- const struct ac97_codec_id *pid;
-
- for (pid = snd_ac97_codec_ids; pid->id; pid++)
- if (pid->id == (ac97->id & pid->mask))
- return pid->name;
- return "unknown codec";
-}
-
-EXPORT_SYMBOL(snd_ac97_get_short_name);
-
-/* wait for a while until registers are accessible after RESET
- * return 0 if ok, negative not ready
- */
-static int ac97_reset_wait(struct snd_ac97 *ac97, int timeout, int with_modem)
-{
- unsigned long end_time;
- unsigned short val;
-
- end_time = jiffies + timeout;
- do {
-
- /* use preliminary reads to settle the communication */
- snd_ac97_read(ac97, AC97_RESET);
- snd_ac97_read(ac97, AC97_VENDOR_ID1);
- snd_ac97_read(ac97, AC97_VENDOR_ID2);
- /* modem? */
- if (with_modem) {
- val = snd_ac97_read(ac97, AC97_EXTENDED_MID);
- if (val != 0xffff && (val & 1) != 0)
- return 0;
- }
- if (ac97->scaps & AC97_SCAP_DETECT_BY_VENDOR) {
- /* probably only Xbox issue - all registers are read as zero */
- val = snd_ac97_read(ac97, AC97_VENDOR_ID1);
- if (val != 0 && val != 0xffff)
- return 0;
- } else {
- /* because the PCM or MASTER volume registers can be modified,
- * the REC_GAIN register is used for tests
- */
- /* test if we can write to the record gain volume register */
- snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x8a05);
- if ((snd_ac97_read(ac97, AC97_REC_GAIN) & 0x7fff) == 0x0a05)
- return 0;
- }
- schedule_timeout_uninterruptible(1);
- } while (time_after_eq(end_time, jiffies));
- return -ENODEV;
-}
-
-/**
- * snd_ac97_bus - create an AC97 bus component
- * @card: the card instance
- * @num: the bus number
- * @ops: the bus callbacks table
- * @private_data: private data pointer for the new instance
- * @rbus: the pointer to store the new AC97 bus instance.
- *
- * Creates an AC97 bus component. An struct snd_ac97_bus instance is newly
- * allocated and initialized.
- *
- * The ops table must include valid callbacks (at least read and
- * write). The other callbacks, wait and reset, are not mandatory.
- *
- * The clock is set to 48000. If another clock is needed, set
- * (*rbus)->clock manually.
- *
- * The AC97 bus instance is registered as a low-level device, so you don't
- * have to release it manually.
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_ac97_bus(struct snd_card *card, int num, struct snd_ac97_bus_ops *ops,
- void *private_data, struct snd_ac97_bus **rbus)
-{
- int err;
- struct snd_ac97_bus *bus;
- static struct snd_device_ops dev_ops = {
- .dev_free = snd_ac97_bus_dev_free,
- };
-
- if (snd_BUG_ON(!card))
- return -EINVAL;
- bus = kzalloc(sizeof(*bus), GFP_KERNEL);
- if (bus == NULL)
- return -ENOMEM;
- bus->card = card;
- bus->num = num;
- bus->ops = ops;
- bus->private_data = private_data;
- bus->clock = 48000;
- spin_lock_init(&bus->bus_lock);
- snd_ac97_bus_proc_init(bus);
- if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) {
- snd_ac97_bus_free(bus);
- return err;
- }
- if (rbus)
- *rbus = bus;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_ac97_bus);
-
-/* stop no dev release warning */
-static void ac97_device_release(struct device * dev)
-{
-}
-
-/* register ac97 codec to bus */
-static int snd_ac97_dev_register(struct snd_device *device)
-{
- struct snd_ac97 *ac97 = device->device_data;
- int err;
-
- ac97->dev.bus = &ac97_bus_type;
- ac97->dev.parent = ac97->bus->card->dev;
- ac97->dev.release = ac97_device_release;
- dev_set_name(&ac97->dev, "%d-%d:%s",
- ac97->bus->card->number, ac97->num,
- snd_ac97_get_short_name(ac97));
- if ((err = device_register(&ac97->dev)) < 0) {
- snd_printk(KERN_ERR "Can't register ac97 bus\n");
- ac97->dev.bus = NULL;
- return err;
- }
- return 0;
-}
-
-/* disconnect ac97 codec */
-static int snd_ac97_dev_disconnect(struct snd_device *device)
-{
- struct snd_ac97 *ac97 = device->device_data;
- if (ac97->dev.bus)
- device_unregister(&ac97->dev);
- return 0;
-}
-
-/* build_ops to do nothing */
-static const struct snd_ac97_build_ops null_build_ops;
-
-#ifdef CONFIG_SND_AC97_POWER_SAVE
-static void do_update_power(struct work_struct *work)
-{
- update_power_regs(
- container_of(work, struct snd_ac97, power_work.work));
-}
-#endif
-
-/**
- * snd_ac97_mixer - create an Codec97 component
- * @bus: the AC97 bus which codec is attached to
- * @template: the template of ac97, including index, callbacks and
- * the private data.
- * @rac97: the pointer to store the new ac97 instance.
- *
- * Creates an Codec97 component. An struct snd_ac97 instance is newly
- * allocated and initialized from the template. The codec
- * is then initialized by the standard procedure.
- *
- * The template must include the codec number (num) and address (addr),
- * and the private data (private_data).
- *
- * The ac97 instance is registered as a low-level device, so you don't
- * have to release it manually.
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, struct snd_ac97 **rac97)
-{
- int err;
- struct snd_ac97 *ac97;
- struct snd_card *card;
- char name[64];
- unsigned long end_time;
- unsigned int reg;
- const struct ac97_codec_id *pid;
- static struct snd_device_ops ops = {
- .dev_free = snd_ac97_dev_free,
- .dev_register = snd_ac97_dev_register,
- .dev_disconnect = snd_ac97_dev_disconnect,
- };
-
- if (rac97)
- *rac97 = NULL;
- if (snd_BUG_ON(!bus || !template))
- return -EINVAL;
- if (snd_BUG_ON(template->num >= 4))
- return -EINVAL;
- if (bus->codec[template->num])
- return -EBUSY;
-
- card = bus->card;
- ac97 = kzalloc(sizeof(*ac97), GFP_KERNEL);
- if (ac97 == NULL)
- return -ENOMEM;
- ac97->private_data = template->private_data;
- ac97->private_free = template->private_free;
- ac97->bus = bus;
- ac97->pci = template->pci;
- ac97->num = template->num;
- ac97->addr = template->addr;
- ac97->scaps = template->scaps;
- ac97->res_table = template->res_table;
- bus->codec[ac97->num] = ac97;
- mutex_init(&ac97->reg_mutex);
- mutex_init(&ac97->page_mutex);
-#ifdef CONFIG_SND_AC97_POWER_SAVE
- INIT_DELAYED_WORK(&ac97->power_work, do_update_power);
-#endif
-
-#ifdef CONFIG_PCI
- if (ac97->pci) {
- pci_read_config_word(ac97->pci, PCI_SUBSYSTEM_VENDOR_ID, &ac97->subsystem_vendor);
- pci_read_config_word(ac97->pci, PCI_SUBSYSTEM_ID, &ac97->subsystem_device);
- }
-#endif
- if (bus->ops->reset) {
- bus->ops->reset(ac97);
- goto __access_ok;
- }
-
- ac97->id = snd_ac97_read(ac97, AC97_VENDOR_ID1) << 16;
- ac97->id |= snd_ac97_read(ac97, AC97_VENDOR_ID2);
- if (ac97->id && ac97->id != (unsigned int)-1) {
- pid = look_for_codec_id(snd_ac97_codec_ids, ac97->id);
- if (pid && (pid->flags & AC97_DEFAULT_POWER_OFF))
- goto __access_ok;
- }
-
- /* reset to defaults */
- if (!(ac97->scaps & AC97_SCAP_SKIP_AUDIO))
- snd_ac97_write(ac97, AC97_RESET, 0);
- if (!(ac97->scaps & AC97_SCAP_SKIP_MODEM))
- snd_ac97_write(ac97, AC97_EXTENDED_MID, 0);
- if (bus->ops->wait)
- bus->ops->wait(ac97);
- else {
- udelay(50);
- if (ac97->scaps & AC97_SCAP_SKIP_AUDIO)
- err = ac97_reset_wait(ac97, msecs_to_jiffies(500), 1);
- else {
- err = ac97_reset_wait(ac97, msecs_to_jiffies(500), 0);
- if (err < 0)
- err = ac97_reset_wait(ac97,
- msecs_to_jiffies(500), 1);
- }
- if (err < 0) {
- snd_printk(KERN_WARNING "AC'97 %d does not respond - RESET\n", ac97->num);
- /* proceed anyway - it's often non-critical */
- }
- }
- __access_ok:
- ac97->id = snd_ac97_read(ac97, AC97_VENDOR_ID1) << 16;
- ac97->id |= snd_ac97_read(ac97, AC97_VENDOR_ID2);
- if (! (ac97->scaps & AC97_SCAP_DETECT_BY_VENDOR) &&
- (ac97->id == 0x00000000 || ac97->id == 0xffffffff)) {
- snd_printk(KERN_ERR "AC'97 %d access is not valid [0x%x], removing mixer.\n", ac97->num, ac97->id);
- snd_ac97_free(ac97);
- return -EIO;
- }
- pid = look_for_codec_id(snd_ac97_codec_ids, ac97->id);
- if (pid)
- ac97->flags |= pid->flags;
-
- /* test for AC'97 */
- if (!(ac97->scaps & AC97_SCAP_SKIP_AUDIO) && !(ac97->scaps & AC97_SCAP_AUDIO)) {
- /* test if we can write to the record gain volume register */
- snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x8a06);
- if (((err = snd_ac97_read(ac97, AC97_REC_GAIN)) & 0x7fff) == 0x0a06)
- ac97->scaps |= AC97_SCAP_AUDIO;
- }
- if (ac97->scaps & AC97_SCAP_AUDIO) {
- ac97->caps = snd_ac97_read(ac97, AC97_RESET);
- ac97->ext_id = snd_ac97_read(ac97, AC97_EXTENDED_ID);
- if (ac97->ext_id == 0xffff) /* invalid combination */
- ac97->ext_id = 0;
- }
-
- /* test for MC'97 */
- if (!(ac97->scaps & AC97_SCAP_SKIP_MODEM) && !(ac97->scaps & AC97_SCAP_MODEM)) {
- ac97->ext_mid = snd_ac97_read(ac97, AC97_EXTENDED_MID);
- if (ac97->ext_mid == 0xffff) /* invalid combination */
- ac97->ext_mid = 0;
- if (ac97->ext_mid & 1)
- ac97->scaps |= AC97_SCAP_MODEM;
- }
-
- if (!ac97_is_audio(ac97) && !ac97_is_modem(ac97)) {
- if (!(ac97->scaps & (AC97_SCAP_SKIP_AUDIO|AC97_SCAP_SKIP_MODEM)))
- snd_printk(KERN_ERR "AC'97 %d access error (not audio or modem codec)\n", ac97->num);
- snd_ac97_free(ac97);
- return -EACCES;
- }
-
- if (bus->ops->reset) // FIXME: always skipping?
- goto __ready_ok;
-
- /* FIXME: add powerdown control */
- if (ac97_is_audio(ac97)) {
- /* nothing should be in powerdown mode */
- snd_ac97_write_cache(ac97, AC97_POWERDOWN, 0);
- if (! (ac97->flags & AC97_DEFAULT_POWER_OFF)) {
- snd_ac97_write_cache(ac97, AC97_RESET, 0); /* reset to defaults */
- udelay(100);
- snd_ac97_write_cache(ac97, AC97_POWERDOWN, 0);
- }
- /* nothing should be in powerdown mode */
- snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0);
- end_time = jiffies + msecs_to_jiffies(5000);
- do {
- if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f)
- goto __ready_ok;
- schedule_timeout_uninterruptible(1);
- } while (time_after_eq(end_time, jiffies));
- snd_printk(KERN_WARNING "AC'97 %d analog subsections not ready\n", ac97->num);
- }
-
- /* FIXME: add powerdown control */
- if (ac97_is_modem(ac97)) {
- unsigned char tmp;
-
- /* nothing should be in powerdown mode */
- /* note: it's important to set the rate at first */
- tmp = AC97_MEA_GPIO;
- if (ac97->ext_mid & AC97_MEI_LINE1) {
- snd_ac97_write_cache(ac97, AC97_LINE1_RATE, 8000);
- tmp |= AC97_MEA_ADC1 | AC97_MEA_DAC1;
- }
- if (ac97->ext_mid & AC97_MEI_LINE2) {
- snd_ac97_write_cache(ac97, AC97_LINE2_RATE, 8000);
- tmp |= AC97_MEA_ADC2 | AC97_MEA_DAC2;
- }
- if (ac97->ext_mid & AC97_MEI_HANDSET) {
- snd_ac97_write_cache(ac97, AC97_HANDSET_RATE, 8000);
- tmp |= AC97_MEA_HADC | AC97_MEA_HDAC;
- }
- snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0);
- udelay(100);
- /* nothing should be in powerdown mode */
- snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0);
- end_time = jiffies + msecs_to_jiffies(100);
- do {
- if ((snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS) & tmp) == tmp)
- goto __ready_ok;
- schedule_timeout_uninterruptible(1);
- } while (time_after_eq(end_time, jiffies));
- snd_printk(KERN_WARNING "MC'97 %d converters and GPIO not ready (0x%x)\n", ac97->num, snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS));
- }
-
- __ready_ok:
- if (ac97_is_audio(ac97))
- ac97->addr = (ac97->ext_id & AC97_EI_ADDR_MASK) >> AC97_EI_ADDR_SHIFT;
- else
- ac97->addr = (ac97->ext_mid & AC97_MEI_ADDR_MASK) >> AC97_MEI_ADDR_SHIFT;
- if (ac97->ext_id & 0x01c9) { /* L/R, MIC, SDAC, LDAC VRA support */
- reg = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
- reg |= ac97->ext_id & 0x01c0; /* LDAC/SDAC/CDAC */
- if (! bus->no_vra)
- reg |= ac97->ext_id & 0x0009; /* VRA/VRM */
- snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, reg);
- }
- if ((ac97->ext_id & AC97_EI_DRA) && bus->dra) {
- /* Intel controllers require double rate data to be put in
- * slots 7+8, so let's hope the codec supports it. */
- snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, AC97_GP_DRSS_MASK, AC97_GP_DRSS_78);
- if ((snd_ac97_read(ac97, AC97_GENERAL_PURPOSE) & AC97_GP_DRSS_MASK) == AC97_GP_DRSS_78)
- ac97->flags |= AC97_DOUBLE_RATE;
- /* restore to slots 10/11 to avoid the confliction with surrounds */
- snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, AC97_GP_DRSS_MASK, 0);
- }
- if (ac97->ext_id & AC97_EI_VRA) { /* VRA support */
- snd_ac97_determine_rates(ac97, AC97_PCM_FRONT_DAC_RATE, 0, &ac97->rates[AC97_RATES_FRONT_DAC]);
- snd_ac97_determine_rates(ac97, AC97_PCM_LR_ADC_RATE, 0, &ac97->rates[AC97_RATES_ADC]);
- } else {
- ac97->rates[AC97_RATES_FRONT_DAC] = SNDRV_PCM_RATE_48000;
- if (ac97->flags & AC97_DOUBLE_RATE)
- ac97->rates[AC97_RATES_FRONT_DAC] |= SNDRV_PCM_RATE_96000;
- ac97->rates[AC97_RATES_ADC] = SNDRV_PCM_RATE_48000;
- }
- if (ac97->ext_id & AC97_EI_SPDIF) {
- /* codec specific code (patch) should override these values */
- ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_32000;
- }
- if (ac97->ext_id & AC97_EI_VRM) { /* MIC VRA support */
- snd_ac97_determine_rates(ac97, AC97_PCM_MIC_ADC_RATE, 0, &ac97->rates[AC97_RATES_MIC_ADC]);
- } else {
- ac97->rates[AC97_RATES_MIC_ADC] = SNDRV_PCM_RATE_48000;
- }
- if (ac97->ext_id & AC97_EI_SDAC) { /* SDAC support */
- snd_ac97_determine_rates(ac97, AC97_PCM_SURR_DAC_RATE, AC97_PCM_FRONT_DAC_RATE, &ac97->rates[AC97_RATES_SURR_DAC]);
- ac97->scaps |= AC97_SCAP_SURROUND_DAC;
- }
- if (ac97->ext_id & AC97_EI_LDAC) { /* LDAC support */
- snd_ac97_determine_rates(ac97, AC97_PCM_LFE_DAC_RATE, AC97_PCM_FRONT_DAC_RATE, &ac97->rates[AC97_RATES_LFE_DAC]);
- ac97->scaps |= AC97_SCAP_CENTER_LFE_DAC;
- }
- /* additional initializations */
- if (bus->ops->init)
- bus->ops->init(ac97);
- snd_ac97_get_name(ac97, ac97->id, name, !ac97_is_audio(ac97));
- snd_ac97_get_name(NULL, ac97->id, name, !ac97_is_audio(ac97)); // ac97->id might be changed in the special setup code
- if (! ac97->build_ops)
- ac97->build_ops = &null_build_ops;
-
- if (ac97_is_audio(ac97)) {
- char comp[16];
- if (card->mixername[0] == '\0') {
- strcpy(card->mixername, name);
- } else {
- if (strlen(card->mixername) + 1 + strlen(name) + 1 <= sizeof(card->mixername)) {
- strcat(card->mixername, ",");
- strcat(card->mixername, name);
- }
- }
- sprintf(comp, "AC97a:%08x", ac97->id);
- if ((err = snd_component_add(card, comp)) < 0) {
- snd_ac97_free(ac97);
- return err;
- }
- if (snd_ac97_mixer_build(ac97) < 0) {
- snd_ac97_free(ac97);
- return -ENOMEM;
- }
- }
- if (ac97_is_modem(ac97)) {
- char comp[16];
- if (card->mixername[0] == '\0') {
- strcpy(card->mixername, name);
- } else {
- if (strlen(card->mixername) + 1 + strlen(name) + 1 <= sizeof(card->mixername)) {
- strcat(card->mixername, ",");
- strcat(card->mixername, name);
- }
- }
- sprintf(comp, "AC97m:%08x", ac97->id);
- if ((err = snd_component_add(card, comp)) < 0) {
- snd_ac97_free(ac97);
- return err;
- }
- if (snd_ac97_modem_build(card, ac97) < 0) {
- snd_ac97_free(ac97);
- return -ENOMEM;
- }
- }
- if (ac97_is_audio(ac97))
- update_power_regs(ac97);
- snd_ac97_proc_init(ac97);
- if ((err = snd_device_new(card, SNDRV_DEV_CODEC, ac97, &ops)) < 0) {
- snd_ac97_free(ac97);
- return err;
- }
- *rac97 = ac97;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_ac97_mixer);
-
-/*
- * Power down the chip.
- *
- * MASTER and HEADPHONE registers are muted but the register cache values
- * are not changed, so that the values can be restored in snd_ac97_resume().
- */
-static void snd_ac97_powerdown(struct snd_ac97 *ac97)
-{
- unsigned short power;
-
- if (ac97_is_audio(ac97)) {
- /* some codecs have stereo mute bits */
- snd_ac97_write(ac97, AC97_MASTER, 0x9f9f);
- snd_ac97_write(ac97, AC97_HEADPHONE, 0x9f9f);
- }
-
- /* surround, CLFE, mic powerdown */
- power = ac97->regs[AC97_EXTENDED_STATUS];
- if (ac97->scaps & AC97_SCAP_SURROUND_DAC)
- power |= AC97_EA_PRJ;
- if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC)
- power |= AC97_EA_PRI | AC97_EA_PRK;
- power |= AC97_EA_PRL;
- snd_ac97_write(ac97, AC97_EXTENDED_STATUS, power);
-
- /* powerdown external amplifier */
- if (ac97->scaps & AC97_SCAP_INV_EAPD)
- power = ac97->regs[AC97_POWERDOWN] & ~AC97_PD_EAPD;
- else if (! (ac97->scaps & AC97_SCAP_EAPD_LED))
- power = ac97->regs[AC97_POWERDOWN] | AC97_PD_EAPD;
- power |= AC97_PD_PR6; /* Headphone amplifier powerdown */
- power |= AC97_PD_PR0 | AC97_PD_PR1; /* ADC & DAC powerdown */
- snd_ac97_write(ac97, AC97_POWERDOWN, power);
- udelay(100);
- power |= AC97_PD_PR2; /* Analog Mixer powerdown (Vref on) */
- snd_ac97_write(ac97, AC97_POWERDOWN, power);
- if (ac97_is_power_save_mode(ac97)) {
- power |= AC97_PD_PR3; /* Analog Mixer powerdown */
- snd_ac97_write(ac97, AC97_POWERDOWN, power);
- udelay(100);
- /* AC-link powerdown, internal Clk disable */
- /* FIXME: this may cause click noises on some boards */
- power |= AC97_PD_PR4 | AC97_PD_PR5;
- snd_ac97_write(ac97, AC97_POWERDOWN, power);
- }
-}
-
-
-struct ac97_power_reg {
- unsigned short reg;
- unsigned short power_reg;
- unsigned short mask;
-};
-
-enum { PWIDX_ADC, PWIDX_FRONT, PWIDX_CLFE, PWIDX_SURR, PWIDX_MIC, PWIDX_SIZE };
-
-static struct ac97_power_reg power_regs[PWIDX_SIZE] = {
- [PWIDX_ADC] = { AC97_PCM_LR_ADC_RATE, AC97_POWERDOWN, AC97_PD_PR0},
- [PWIDX_FRONT] = { AC97_PCM_FRONT_DAC_RATE, AC97_POWERDOWN, AC97_PD_PR1},
- [PWIDX_CLFE] = { AC97_PCM_LFE_DAC_RATE, AC97_EXTENDED_STATUS,
- AC97_EA_PRI | AC97_EA_PRK},
- [PWIDX_SURR] = { AC97_PCM_SURR_DAC_RATE, AC97_EXTENDED_STATUS,
- AC97_EA_PRJ},
- [PWIDX_MIC] = { AC97_PCM_MIC_ADC_RATE, AC97_EXTENDED_STATUS,
- AC97_EA_PRL},
-};
-
-#ifdef CONFIG_SND_AC97_POWER_SAVE
-/**
- * snd_ac97_update_power - update the powerdown register
- * @ac97: the codec instance
- * @reg: the rate register, e.g. AC97_PCM_FRONT_DAC_RATE
- * @powerup: non-zero when power up the part
- *
- * Update the AC97 powerdown register bits of the given part.
- */
-int snd_ac97_update_power(struct snd_ac97 *ac97, int reg, int powerup)
-{
- int i;
-
- if (! ac97)
- return 0;
-
- if (reg) {
- /* SPDIF requires DAC power, too */
- if (reg == AC97_SPDIF)
- reg = AC97_PCM_FRONT_DAC_RATE;
- for (i = 0; i < PWIDX_SIZE; i++) {
- if (power_regs[i].reg == reg) {
- if (powerup)
- ac97->power_up |= (1 << i);
- else
- ac97->power_up &= ~(1 << i);
- break;
- }
- }
- }
-
- if (ac97_is_power_save_mode(ac97) && !powerup)
- /* adjust power-down bits after two seconds delay
- * (for avoiding loud click noises for many (OSS) apps
- * that open/close frequently)
- */
- schedule_delayed_work(&ac97->power_work,
- msecs_to_jiffies(power_save * 1000));
- else {
- cancel_delayed_work(&ac97->power_work);
- update_power_regs(ac97);
- }
-
- return 0;
-}
-
-EXPORT_SYMBOL(snd_ac97_update_power);
-#endif /* CONFIG_SND_AC97_POWER_SAVE */
-
-static void update_power_regs(struct snd_ac97 *ac97)
-{
- unsigned int power_up, bits;
- int i;
-
- power_up = (1 << PWIDX_FRONT) | (1 << PWIDX_ADC);
- power_up |= (1 << PWIDX_MIC);
- if (ac97->scaps & AC97_SCAP_SURROUND_DAC)
- power_up |= (1 << PWIDX_SURR);
- if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC)
- power_up |= (1 << PWIDX_CLFE);
-#ifdef CONFIG_SND_AC97_POWER_SAVE
- if (ac97_is_power_save_mode(ac97))
- power_up = ac97->power_up;
-#endif
- if (power_up) {
- if (ac97->regs[AC97_POWERDOWN] & AC97_PD_PR2) {
- /* needs power-up analog mix and vref */
- snd_ac97_update_bits(ac97, AC97_POWERDOWN,
- AC97_PD_PR3, 0);
- msleep(1);
- snd_ac97_update_bits(ac97, AC97_POWERDOWN,
- AC97_PD_PR2, 0);
- }
- }
- for (i = 0; i < PWIDX_SIZE; i++) {
- if (power_up & (1 << i))
- bits = 0;
- else
- bits = power_regs[i].mask;
- snd_ac97_update_bits(ac97, power_regs[i].power_reg,
- power_regs[i].mask, bits);
- }
- if (! power_up) {
- if (! (ac97->regs[AC97_POWERDOWN] & AC97_PD_PR2)) {
- /* power down analog mix and vref */
- snd_ac97_update_bits(ac97, AC97_POWERDOWN,
- AC97_PD_PR2, AC97_PD_PR2);
- snd_ac97_update_bits(ac97, AC97_POWERDOWN,
- AC97_PD_PR3, AC97_PD_PR3);
- }
- }
-}
-
-
-#ifdef CONFIG_PM
-/**
- * snd_ac97_suspend - General suspend function for AC97 codec
- * @ac97: the ac97 instance
- *
- * Suspends the codec, power down the chip.
- */
-void snd_ac97_suspend(struct snd_ac97 *ac97)
-{
- if (! ac97)
- return;
- if (ac97->build_ops->suspend)
- ac97->build_ops->suspend(ac97);
-#ifdef CONFIG_SND_AC97_POWER_SAVE
- cancel_delayed_work_sync(&ac97->power_work);
-#endif
- snd_ac97_powerdown(ac97);
-}
-
-EXPORT_SYMBOL(snd_ac97_suspend);
-
-/*
- * restore ac97 status
- */
-static void snd_ac97_restore_status(struct snd_ac97 *ac97)
-{
- int i;
-
- for (i = 2; i < 0x7c ; i += 2) {
- if (i == AC97_POWERDOWN || i == AC97_EXTENDED_ID)
- continue;
- /* restore only accessible registers
- * some chip (e.g. nm256) may hang up when unsupported registers
- * are accessed..!
- */
- if (test_bit(i, ac97->reg_accessed)) {
- snd_ac97_write(ac97, i, ac97->regs[i]);
- snd_ac97_read(ac97, i);
- }
- }
-}
-
-/*
- * restore IEC958 status
- */
-static void snd_ac97_restore_iec958(struct snd_ac97 *ac97)
-{
- if (ac97->ext_id & AC97_EI_SPDIF) {
- if (ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_SPDIF) {
- /* reset spdif status */
- snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
- snd_ac97_write(ac97, AC97_EXTENDED_STATUS, ac97->regs[AC97_EXTENDED_STATUS]);
- if (ac97->flags & AC97_CS_SPDIF)
- snd_ac97_write(ac97, AC97_CSR_SPDIF, ac97->regs[AC97_CSR_SPDIF]);
- else
- snd_ac97_write(ac97, AC97_SPDIF, ac97->regs[AC97_SPDIF]);
- snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
- }
- }
-}
-
-/**
- * snd_ac97_resume - General resume function for AC97 codec
- * @ac97: the ac97 instance
- *
- * Do the standard resume procedure, power up and restoring the
- * old register values.
- */
-void snd_ac97_resume(struct snd_ac97 *ac97)
-{
- unsigned long end_time;
-
- if (! ac97)
- return;
-
- if (ac97->bus->ops->reset) {
- ac97->bus->ops->reset(ac97);
- goto __reset_ready;
- }
-
- snd_ac97_write(ac97, AC97_POWERDOWN, 0);
- if (! (ac97->flags & AC97_DEFAULT_POWER_OFF)) {
- if (!(ac97->scaps & AC97_SCAP_SKIP_AUDIO))
- snd_ac97_write(ac97, AC97_RESET, 0);
- else if (!(ac97->scaps & AC97_SCAP_SKIP_MODEM))
- snd_ac97_write(ac97, AC97_EXTENDED_MID, 0);
- udelay(100);
- snd_ac97_write(ac97, AC97_POWERDOWN, 0);
- }
- snd_ac97_write(ac97, AC97_GENERAL_PURPOSE, 0);
-
- snd_ac97_write(ac97, AC97_POWERDOWN, ac97->regs[AC97_POWERDOWN]);
- if (ac97_is_audio(ac97)) {
- ac97->bus->ops->write(ac97, AC97_MASTER, 0x8101);
- end_time = jiffies + msecs_to_jiffies(100);
- do {
- if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101)
- break;
- schedule_timeout_uninterruptible(1);
- } while (time_after_eq(end_time, jiffies));
- /* FIXME: extra delay */
- ac97->bus->ops->write(ac97, AC97_MASTER, AC97_MUTE_MASK_MONO);
- if (snd_ac97_read(ac97, AC97_MASTER) != AC97_MUTE_MASK_MONO)
- msleep(250);
- } else {
- end_time = jiffies + msecs_to_jiffies(100);
- do {
- unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID);
- if (val != 0xffff && (val & 1) != 0)
- break;
- schedule_timeout_uninterruptible(1);
- } while (time_after_eq(end_time, jiffies));
- }
-__reset_ready:
-
- if (ac97->bus->ops->init)
- ac97->bus->ops->init(ac97);
-
- if (ac97->build_ops->resume)
- ac97->build_ops->resume(ac97);
- else {
- snd_ac97_restore_status(ac97);
- snd_ac97_restore_iec958(ac97);
- }
-}
-
-EXPORT_SYMBOL(snd_ac97_resume);
-#endif
-
-
-/*
- * Hardware tuning
- */
-static void set_ctl_name(char *dst, const char *src, const char *suffix)
-{
- if (suffix)
- sprintf(dst, "%s %s", src, suffix);
- else
- strcpy(dst, src);
-}
-
-/* remove the control with the given name and optional suffix */
-static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name,
- const char *suffix)
-{
- struct snd_ctl_elem_id id;
- memset(&id, 0, sizeof(id));
- set_ctl_name(id.name, name, suffix);
- id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- return snd_ctl_remove_id(ac97->bus->card, &id);
-}
-
-static struct snd_kcontrol *ctl_find(struct snd_ac97 *ac97, const char *name, const char *suffix)
-{
- struct snd_ctl_elem_id sid;
- memset(&sid, 0, sizeof(sid));
- set_ctl_name(sid.name, name, suffix);
- sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- return snd_ctl_find_id(ac97->bus->card, &sid);
-}
-
-/* rename the control with the given name and optional suffix */
-static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src,
- const char *dst, const char *suffix)
-{
- struct snd_kcontrol *kctl = ctl_find(ac97, src, suffix);
- if (kctl) {
- set_ctl_name(kctl->id.name, dst, suffix);
- return 0;
- }
- return -ENOENT;
-}
-
-/* rename both Volume and Switch controls - don't check the return value */
-static void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src,
- const char *dst)
-{
- snd_ac97_rename_ctl(ac97, src, dst, "Switch");
- snd_ac97_rename_ctl(ac97, src, dst, "Volume");
-}
-
-/* swap controls */
-static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1,
- const char *s2, const char *suffix)
-{
- struct snd_kcontrol *kctl1, *kctl2;
- kctl1 = ctl_find(ac97, s1, suffix);
- kctl2 = ctl_find(ac97, s2, suffix);
- if (kctl1 && kctl2) {
- set_ctl_name(kctl1->id.name, s2, suffix);
- set_ctl_name(kctl2->id.name, s1, suffix);
- return 0;
- }
- return -ENOENT;
-}
-
-#if 1
-/* bind hp and master controls instead of using only hp control */
-static int bind_hp_volsw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- int err = snd_ac97_put_volsw(kcontrol, ucontrol);
- if (err > 0) {
- unsigned long priv_saved = kcontrol->private_value;
- kcontrol->private_value = (kcontrol->private_value & ~0xff) | AC97_HEADPHONE;
- snd_ac97_put_volsw(kcontrol, ucontrol);
- kcontrol->private_value = priv_saved;
- }
- return err;
-}
-
-/* ac97 tune: bind Master and Headphone controls */
-static int tune_hp_only(struct snd_ac97 *ac97)
-{
- struct snd_kcontrol *msw = ctl_find(ac97, "Master Playback Switch", NULL);
- struct snd_kcontrol *mvol = ctl_find(ac97, "Master Playback Volume", NULL);
- if (! msw || ! mvol)
- return -ENOENT;
- msw->put = bind_hp_volsw_put;
- mvol->put = bind_hp_volsw_put;
- snd_ac97_remove_ctl(ac97, "Headphone Playback", "Switch");
- snd_ac97_remove_ctl(ac97, "Headphone Playback", "Volume");
- return 0;
-}
-
-#else
-/* ac97 tune: use Headphone control as master */
-static int tune_hp_only(struct snd_ac97 *ac97)
-{
- if (ctl_find(ac97, "Headphone Playback Switch", NULL) == NULL)
- return -ENOENT;
- snd_ac97_remove_ctl(ac97, "Master Playback", "Switch");
- snd_ac97_remove_ctl(ac97, "Master Playback", "Volume");
- snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback");
- return 0;
-}
-#endif
-
-/* ac97 tune: swap Headphone and Master controls */
-static int tune_swap_hp(struct snd_ac97 *ac97)
-{
- if (ctl_find(ac97, "Headphone Playback Switch", NULL) == NULL)
- return -ENOENT;
- snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Line-Out Playback");
- snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback");
- return 0;
-}
-
-/* ac97 tune: swap Surround and Master controls */
-static int tune_swap_surround(struct snd_ac97 *ac97)
-{
- if (snd_ac97_swap_ctl(ac97, "Master Playback", "Surround Playback", "Switch") ||
- snd_ac97_swap_ctl(ac97, "Master Playback", "Surround Playback", "Volume"))
- return -ENOENT;
- return 0;
-}
-
-/* ac97 tune: set up mic sharing for AD codecs */
-static int tune_ad_sharing(struct snd_ac97 *ac97)
-{
- unsigned short scfg;
- if ((ac97->id & 0xffffff00) != 0x41445300) {
- snd_printk(KERN_ERR "ac97_quirk AD_SHARING is only for AD codecs\n");
- return -EINVAL;
- }
- /* Turn on OMS bit to route microphone to back panel */
- scfg = snd_ac97_read(ac97, AC97_AD_SERIAL_CFG);
- snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, scfg | 0x0200);
- return 0;
-}
-
-static const struct snd_kcontrol_new snd_ac97_alc_jack_detect =
-AC97_SINGLE("Jack Detect", AC97_ALC650_CLOCK, 5, 1, 0);
-
-/* ac97 tune: set up ALC jack-select */
-static int tune_alc_jack(struct snd_ac97 *ac97)
-{
- if ((ac97->id & 0xffffff00) != 0x414c4700) {
- snd_printk(KERN_ERR "ac97_quirk ALC_JACK is only for Realtek codecs\n");
- return -EINVAL;
- }
- snd_ac97_update_bits(ac97, 0x7a, 0x20, 0x20); /* select jack detect function */
- snd_ac97_update_bits(ac97, 0x7a, 0x01, 0x01); /* Line-out auto mute */
- if (ac97->id == AC97_ID_ALC658D)
- snd_ac97_update_bits(ac97, 0x74, 0x0800, 0x0800);
- return snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&snd_ac97_alc_jack_detect, ac97));
-}
-
-/* ac97 tune: inversed EAPD bit */
-static int tune_inv_eapd(struct snd_ac97 *ac97)
-{
- struct snd_kcontrol *kctl = ctl_find(ac97, "External Amplifier", NULL);
- if (! kctl)
- return -ENOENT;
- set_inv_eapd(ac97, kctl);
- return 0;
-}
-
-static int master_mute_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- int err = snd_ac97_put_volsw(kcontrol, ucontrol);
- if (err > 0) {
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- int shift = (kcontrol->private_value >> 8) & 0x0f;
- int rshift = (kcontrol->private_value >> 12) & 0x0f;
- unsigned short mask;
- if (shift != rshift)
- mask = AC97_MUTE_MASK_STEREO;
- else
- mask = AC97_MUTE_MASK_MONO;
- snd_ac97_update_bits(ac97, AC97_POWERDOWN, AC97_PD_EAPD,
- (ac97->regs[AC97_MASTER] & mask) == mask ?
- AC97_PD_EAPD : 0);
- }
- return err;
-}
-
-/* ac97 tune: EAPD controls mute LED bound with the master mute */
-static int tune_mute_led(struct snd_ac97 *ac97)
-{
- struct snd_kcontrol *msw = ctl_find(ac97, "Master Playback Switch", NULL);
- if (! msw)
- return -ENOENT;
- msw->put = master_mute_sw_put;
- snd_ac97_remove_ctl(ac97, "External Amplifier", NULL);
- snd_ac97_update_bits(
- ac97, AC97_POWERDOWN,
- AC97_PD_EAPD, AC97_PD_EAPD /* mute LED on */
- );
- ac97->scaps |= AC97_SCAP_EAPD_LED;
- return 0;
-}
-
-static int hp_master_mute_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int err = bind_hp_volsw_put(kcontrol, ucontrol);
- if (err > 0) {
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- int shift = (kcontrol->private_value >> 8) & 0x0f;
- int rshift = (kcontrol->private_value >> 12) & 0x0f;
- unsigned short mask;
- if (shift != rshift)
- mask = AC97_MUTE_MASK_STEREO;
- else
- mask = AC97_MUTE_MASK_MONO;
- snd_ac97_update_bits(ac97, AC97_POWERDOWN, AC97_PD_EAPD,
- (ac97->regs[AC97_MASTER] & mask) == mask ?
- AC97_PD_EAPD : 0);
- }
- return err;
-}
-
-static int tune_hp_mute_led(struct snd_ac97 *ac97)
-{
- struct snd_kcontrol *msw = ctl_find(ac97, "Master Playback Switch", NULL);
- struct snd_kcontrol *mvol = ctl_find(ac97, "Master Playback Volume", NULL);
- if (! msw || ! mvol)
- return -ENOENT;
- msw->put = hp_master_mute_sw_put;
- mvol->put = bind_hp_volsw_put;
- snd_ac97_remove_ctl(ac97, "External Amplifier", NULL);
- snd_ac97_remove_ctl(ac97, "Headphone Playback", "Switch");
- snd_ac97_remove_ctl(ac97, "Headphone Playback", "Volume");
- snd_ac97_update_bits(
- ac97, AC97_POWERDOWN,
- AC97_PD_EAPD, AC97_PD_EAPD /* mute LED on */
- );
- return 0;
-}
-
-struct quirk_table {
- const char *name;
- int (*func)(struct snd_ac97 *);
-};
-
-static struct quirk_table applicable_quirks[] = {
- { "none", NULL },
- { "hp_only", tune_hp_only },
- { "swap_hp", tune_swap_hp },
- { "swap_surround", tune_swap_surround },
- { "ad_sharing", tune_ad_sharing },
- { "alc_jack", tune_alc_jack },
- { "inv_eapd", tune_inv_eapd },
- { "mute_led", tune_mute_led },
- { "hp_mute_led", tune_hp_mute_led },
-};
-
-/* apply the quirk with the given type */
-static int apply_quirk(struct snd_ac97 *ac97, int type)
-{
- if (type <= 0)
- return 0;
- else if (type >= ARRAY_SIZE(applicable_quirks))
- return -EINVAL;
- if (applicable_quirks[type].func)
- return applicable_quirks[type].func(ac97);
- return 0;
-}
-
-/* apply the quirk with the given name */
-static int apply_quirk_str(struct snd_ac97 *ac97, const char *typestr)
-{
- int i;
- struct quirk_table *q;
-
- for (i = 0; i < ARRAY_SIZE(applicable_quirks); i++) {
- q = &applicable_quirks[i];
- if (q->name && ! strcmp(typestr, q->name))
- return apply_quirk(ac97, i);
- }
- /* for compatibility, accept the numbers, too */
- if (*typestr >= '0' && *typestr <= '9')
- return apply_quirk(ac97, (int)simple_strtoul(typestr, NULL, 10));
- return -EINVAL;
-}
-
-/**
- * snd_ac97_tune_hardware - tune up the hardware
- * @ac97: the ac97 instance
- * @quirk: quirk list
- * @override: explicit quirk value (overrides the list if non-NULL)
- *
- * Do some workaround for each pci device, such as renaming of the
- * headphone (true line-out) control as "Master".
- * The quirk-list must be terminated with a zero-filled entry.
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-
-int snd_ac97_tune_hardware(struct snd_ac97 *ac97, struct ac97_quirk *quirk, const char *override)
-{
- int result;
-
- /* quirk overriden? */
- if (override && strcmp(override, "-1") && strcmp(override, "default")) {
- result = apply_quirk_str(ac97, override);
- if (result < 0)
- snd_printk(KERN_ERR "applying quirk type %s failed (%d)\n", override, result);
- return result;
- }
-
- if (! quirk)
- return -EINVAL;
-
- for (; quirk->subvendor; quirk++) {
- if (quirk->subvendor != ac97->subsystem_vendor)
- continue;
- if ((! quirk->mask && quirk->subdevice == ac97->subsystem_device) ||
- quirk->subdevice == (quirk->mask & ac97->subsystem_device)) {
- if (quirk->codec_id && quirk->codec_id != ac97->id)
- continue;
- snd_printdd("ac97 quirk for %s (%04x:%04x)\n", quirk->name, ac97->subsystem_vendor, ac97->subsystem_device);
- result = apply_quirk(ac97, quirk->type);
- if (result < 0)
- snd_printk(KERN_ERR "applying quirk type %d for %s failed (%d)\n", quirk->type, quirk->name, result);
- return result;
- }
- }
- return 0;
-}
-
-EXPORT_SYMBOL(snd_ac97_tune_hardware);
-
-/*
- * INIT part
- */
-
-static int __init alsa_ac97_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_ac97_exit(void)
-{
-}
-
-module_init(alsa_ac97_init)
-module_exit(alsa_ac97_exit)
diff --git a/ANDROID_3.4.5/sound/pci/ac97/ac97_id.h b/ANDROID_3.4.5/sound/pci/ac97/ac97_id.h
deleted file mode 100644
index d603147c..00000000
--- a/ANDROID_3.4.5/sound/pci/ac97/ac97_id.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Universal interface for Audio Codec '97
- *
- * For more details look to AC '97 component specification revision 2.2
- * by Intel Corporation (http://developer.intel.com).
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define AC97_ID_AK4540 0x414b4d00
-#define AC97_ID_AK4542 0x414b4d01
-#define AC97_ID_AD1819 0x41445303
-#define AC97_ID_AD1881 0x41445340
-#define AC97_ID_AD1881A 0x41445348
-#define AC97_ID_AD1885 0x41445360
-#define AC97_ID_AD1886 0x41445361
-#define AC97_ID_AD1887 0x41445362
-#define AC97_ID_AD1886A 0x41445363
-#define AC97_ID_AD1980 0x41445370
-#define AC97_ID_TR28028 0x54524108
-#define AC97_ID_STAC9700 0x83847600
-#define AC97_ID_STAC9704 0x83847604
-#define AC97_ID_STAC9705 0x83847605
-#define AC97_ID_STAC9708 0x83847608
-#define AC97_ID_STAC9721 0x83847609
-#define AC97_ID_STAC9744 0x83847644
-#define AC97_ID_STAC9756 0x83847656
-#define AC97_ID_CS4297A 0x43525910
-#define AC97_ID_CS4299 0x43525930
-#define AC97_ID_CS4201 0x43525948
-#define AC97_ID_CS4205 0x43525958
-#define AC97_ID_CS_MASK 0xfffffff8 /* bit 0-2: rev */
-#define AC97_ID_ALC100 0x414c4300
-#define AC97_ID_ALC650 0x414c4720
-#define AC97_ID_ALC650D 0x414c4721
-#define AC97_ID_ALC650E 0x414c4722
-#define AC97_ID_ALC650F 0x414c4723
-#define AC97_ID_ALC655 0x414c4760
-#define AC97_ID_ALC658 0x414c4780
-#define AC97_ID_ALC658D 0x414c4781
-#define AC97_ID_ALC850 0x414c4790
-#define AC97_ID_YMF743 0x594d4800
-#define AC97_ID_YMF753 0x594d4803
-#define AC97_ID_VT1616 0x49434551
-#define AC97_ID_CM9738 0x434d4941
-#define AC97_ID_CM9739 0x434d4961
-#define AC97_ID_CM9761_78 0x434d4978
-#define AC97_ID_CM9761_82 0x434d4982
-#define AC97_ID_CM9761_83 0x434d4983
-#define AC97_ID_ST7597 0x53544d02
-#define AC97_ID_ST_AC97_ID4 0x53544d04
diff --git a/ANDROID_3.4.5/sound/pci/ac97/ac97_local.h b/ANDROID_3.4.5/sound/pci/ac97/ac97_local.h
deleted file mode 100644
index c276a5e3..00000000
--- a/ANDROID_3.4.5/sound/pci/ac97/ac97_local.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Universal interface for Audio Codec '97
- *
- * For more details look to AC '97 component specification revision 2.2
- * by Intel Corporation (http://developer.intel.com).
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name,
- int modem);
-int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short mask, unsigned short value);
-
-/* ac97_proc.c */
-#ifdef CONFIG_PROC_FS
-void snd_ac97_bus_proc_init(struct snd_ac97_bus * ac97);
-void snd_ac97_bus_proc_done(struct snd_ac97_bus * ac97);
-void snd_ac97_proc_init(struct snd_ac97 * ac97);
-void snd_ac97_proc_done(struct snd_ac97 * ac97);
-#else
-#define snd_ac97_bus_proc_init(ac97_bus_t) do { } while (0)
-#define snd_ac97_bus_proc_done(ac97_bus_t) do { } while (0)
-#define snd_ac97_proc_init(ac97_t) do { } while (0)
-#define snd_ac97_proc_done(ac97_t) do { } while (0)
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/ac97/ac97_patch.c b/ANDROID_3.4.5/sound/pci/ac97/ac97_patch.c
deleted file mode 100644
index a872d0a8..00000000
--- a/ANDROID_3.4.5/sound/pci/ac97/ac97_patch.c
+++ /dev/null
@@ -1,3965 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Universal interface for Audio Codec '97
- *
- * For more details look to AC '97 component specification revision 2.2
- * by Intel Corporation (http://developer.intel.com) and to datasheets
- * for specific codecs.
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "ac97_local.h"
-#include "ac97_patch.h"
-
-/*
- * Forward declarations
- */
-
-static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97,
- const char *name);
-static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name,
- const unsigned int *tlv, const char **slaves);
-
-/*
- * Chip specific initialization
- */
-
-static int patch_build_controls(struct snd_ac97 * ac97, const struct snd_kcontrol_new *controls, int count)
-{
- int idx, err;
-
- for (idx = 0; idx < count; idx++)
- if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&controls[idx], ac97))) < 0)
- return err;
- return 0;
-}
-
-/* replace with a new TLV */
-static void reset_tlv(struct snd_ac97 *ac97, const char *name,
- const unsigned int *tlv)
-{
- struct snd_ctl_elem_id sid;
- struct snd_kcontrol *kctl;
- memset(&sid, 0, sizeof(sid));
- strcpy(sid.name, name);
- sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- kctl = snd_ctl_find_id(ac97->bus->card, &sid);
- if (kctl && kctl->tlv.p)
- kctl->tlv.p = tlv;
-}
-
-/* set to the page, update bits and restore the page */
-static int ac97_update_bits_page(struct snd_ac97 *ac97, unsigned short reg, unsigned short mask, unsigned short value, unsigned short page)
-{
- unsigned short page_save;
- int ret;
-
- mutex_lock(&ac97->page_mutex);
- page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
- snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page);
- ret = snd_ac97_update_bits(ac97, reg, mask, value);
- snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save);
- mutex_unlock(&ac97->page_mutex); /* unlock paging */
- return ret;
-}
-
-/*
- * shared line-in/mic controls
- */
-static int ac97_enum_text_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo,
- const char **texts, unsigned int nums)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = nums;
- if (uinfo->value.enumerated.item > nums - 1)
- uinfo->value.enumerated.item = nums - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int ac97_surround_jack_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static const char *texts[] = { "Shared", "Independent" };
- return ac97_enum_text_info(kcontrol, uinfo, texts, 2);
-}
-
-static int ac97_surround_jack_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = ac97->indep_surround;
- return 0;
-}
-
-static int ac97_surround_jack_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned char indep = !!ucontrol->value.enumerated.item[0];
-
- if (indep != ac97->indep_surround) {
- ac97->indep_surround = indep;
- if (ac97->build_ops->update_jacks)
- ac97->build_ops->update_jacks(ac97);
- return 1;
- }
- return 0;
-}
-
-static int ac97_channel_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static const char *texts[] = { "2ch", "4ch", "6ch", "8ch" };
- return ac97_enum_text_info(kcontrol, uinfo, texts,
- kcontrol->private_value);
-}
-
-static int ac97_channel_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = ac97->channel_mode;
- return 0;
-}
-
-static int ac97_channel_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned char mode = ucontrol->value.enumerated.item[0];
-
- if (mode >= kcontrol->private_value)
- return -EINVAL;
-
- if (mode != ac97->channel_mode) {
- ac97->channel_mode = mode;
- if (ac97->build_ops->update_jacks)
- ac97->build_ops->update_jacks(ac97);
- return 1;
- }
- return 0;
-}
-
-#define AC97_SURROUND_JACK_MODE_CTL \
- { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = "Surround Jack Mode", \
- .info = ac97_surround_jack_mode_info, \
- .get = ac97_surround_jack_mode_get, \
- .put = ac97_surround_jack_mode_put, \
- }
-/* 6ch */
-#define AC97_CHANNEL_MODE_CTL \
- { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = "Channel Mode", \
- .info = ac97_channel_mode_info, \
- .get = ac97_channel_mode_get, \
- .put = ac97_channel_mode_put, \
- .private_value = 3, \
- }
-/* 4ch */
-#define AC97_CHANNEL_MODE_4CH_CTL \
- { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = "Channel Mode", \
- .info = ac97_channel_mode_info, \
- .get = ac97_channel_mode_get, \
- .put = ac97_channel_mode_put, \
- .private_value = 2, \
- }
-/* 8ch */
-#define AC97_CHANNEL_MODE_8CH_CTL \
- { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = "Channel Mode", \
- .info = ac97_channel_mode_info, \
- .get = ac97_channel_mode_get, \
- .put = ac97_channel_mode_put, \
- .private_value = 4, \
- }
-
-static inline int is_surround_on(struct snd_ac97 *ac97)
-{
- return ac97->channel_mode >= 1;
-}
-
-static inline int is_clfe_on(struct snd_ac97 *ac97)
-{
- return ac97->channel_mode >= 2;
-}
-
-/* system has shared jacks with surround out enabled */
-static inline int is_shared_surrout(struct snd_ac97 *ac97)
-{
- return !ac97->indep_surround && is_surround_on(ac97);
-}
-
-/* system has shared jacks with center/lfe out enabled */
-static inline int is_shared_clfeout(struct snd_ac97 *ac97)
-{
- return !ac97->indep_surround && is_clfe_on(ac97);
-}
-
-/* system has shared jacks with line in enabled */
-static inline int is_shared_linein(struct snd_ac97 *ac97)
-{
- return !ac97->indep_surround && !is_surround_on(ac97);
-}
-
-/* system has shared jacks with mic in enabled */
-static inline int is_shared_micin(struct snd_ac97 *ac97)
-{
- return !ac97->indep_surround && !is_clfe_on(ac97);
-}
-
-static inline int alc850_is_aux_back_surround(struct snd_ac97 *ac97)
-{
- return is_surround_on(ac97);
-}
-
-/* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */
-/* Modified for YMF743 by Keita Maehara <maehara@debian.org> */
-
-/* It is possible to indicate to the Yamaha YMF7x3 the type of
- speakers being used. */
-
-static int snd_ac97_ymf7x3_info_speaker(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[3] = {
- "Standard", "Small", "Smaller"
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item > 2)
- uinfo->value.enumerated.item = 2;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ac97_ymf7x3_get_speaker(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- val = ac97->regs[AC97_YMF7X3_3D_MODE_SEL];
- val = (val >> 10) & 3;
- if (val > 0) /* 0 = invalid */
- val--;
- ucontrol->value.enumerated.item[0] = val;
- return 0;
-}
-
-static int snd_ac97_ymf7x3_put_speaker(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- if (ucontrol->value.enumerated.item[0] > 2)
- return -EINVAL;
- val = (ucontrol->value.enumerated.item[0] + 1) << 10;
- return snd_ac97_update(ac97, AC97_YMF7X3_3D_MODE_SEL, val);
-}
-
-static const struct snd_kcontrol_new snd_ac97_ymf7x3_controls_speaker =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "3D Control - Speaker",
- .info = snd_ac97_ymf7x3_info_speaker,
- .get = snd_ac97_ymf7x3_get_speaker,
- .put = snd_ac97_ymf7x3_put_speaker,
-};
-
-/* It is possible to indicate to the Yamaha YMF7x3 the source to
- direct to the S/PDIF output. */
-static int snd_ac97_ymf7x3_spdif_source_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[2] = { "AC-Link", "A/D Converter" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item > 1)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ac97_ymf7x3_spdif_source_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- val = ac97->regs[AC97_YMF7X3_DIT_CTRL];
- ucontrol->value.enumerated.item[0] = (val >> 1) & 1;
- return 0;
-}
-
-static int snd_ac97_ymf7x3_spdif_source_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- if (ucontrol->value.enumerated.item[0] > 1)
- return -EINVAL;
- val = ucontrol->value.enumerated.item[0] << 1;
- return snd_ac97_update_bits(ac97, AC97_YMF7X3_DIT_CTRL, 0x0002, val);
-}
-
-static int patch_yamaha_ymf7x3_3d(struct snd_ac97 *ac97)
-{
- struct snd_kcontrol *kctl;
- int err;
-
- kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97);
- err = snd_ctl_add(ac97->bus->card, kctl);
- if (err < 0)
- return err;
- strcpy(kctl->id.name, "3D Control - Wide");
- kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 9, 7, 0);
- snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
- err = snd_ctl_add(ac97->bus->card,
- snd_ac97_cnew(&snd_ac97_ymf7x3_controls_speaker,
- ac97));
- if (err < 0)
- return err;
- snd_ac97_write_cache(ac97, AC97_YMF7X3_3D_MODE_SEL, 0x0c00);
- return 0;
-}
-
-static const struct snd_kcontrol_new snd_ac97_yamaha_ymf743_controls_spdif[3] =
-{
- AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
- AC97_YMF7X3_DIT_CTRL, 0, 1, 0),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Source",
- .info = snd_ac97_ymf7x3_spdif_source_info,
- .get = snd_ac97_ymf7x3_spdif_source_get,
- .put = snd_ac97_ymf7x3_spdif_source_put,
- },
- AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE, NONE) "Mute",
- AC97_YMF7X3_DIT_CTRL, 2, 1, 1)
-};
-
-static int patch_yamaha_ymf743_build_spdif(struct snd_ac97 *ac97)
-{
- int err;
-
- err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3);
- if (err < 0)
- return err;
- err = patch_build_controls(ac97,
- snd_ac97_yamaha_ymf743_controls_spdif, 3);
- if (err < 0)
- return err;
- /* set default PCM S/PDIF params */
- /* PCM audio,no copyright,no preemphasis,PCM coder,original */
- snd_ac97_write_cache(ac97, AC97_YMF7X3_DIT_CTRL, 0xa201);
- return 0;
-}
-
-static const struct snd_ac97_build_ops patch_yamaha_ymf743_ops = {
- .build_spdif = patch_yamaha_ymf743_build_spdif,
- .build_3d = patch_yamaha_ymf7x3_3d,
-};
-
-static int patch_yamaha_ymf743(struct snd_ac97 *ac97)
-{
- ac97->build_ops = &patch_yamaha_ymf743_ops;
- ac97->caps |= AC97_BC_BASS_TREBLE;
- ac97->caps |= 0x04 << 10; /* Yamaha 3D enhancement */
- ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */
- ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */
- return 0;
-}
-
-/* The AC'97 spec states that the S/PDIF signal is to be output at pin 48.
- The YMF753 will output the S/PDIF signal to pin 43, 47 (EAPD), or 48.
- By default, no output pin is selected, and the S/PDIF signal is not output.
- There is also a bit to mute S/PDIF output in a vendor-specific register. */
-static int snd_ac97_ymf753_spdif_output_pin_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[3] = { "Disabled", "Pin 43", "Pin 48" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item > 2)
- uinfo->value.enumerated.item = 2;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ac97_ymf753_spdif_output_pin_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- val = ac97->regs[AC97_YMF7X3_DIT_CTRL];
- ucontrol->value.enumerated.item[0] = (val & 0x0008) ? 2 : (val & 0x0020) ? 1 : 0;
- return 0;
-}
-
-static int snd_ac97_ymf753_spdif_output_pin_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- if (ucontrol->value.enumerated.item[0] > 2)
- return -EINVAL;
- val = (ucontrol->value.enumerated.item[0] == 2) ? 0x0008 :
- (ucontrol->value.enumerated.item[0] == 1) ? 0x0020 : 0;
- return snd_ac97_update_bits(ac97, AC97_YMF7X3_DIT_CTRL, 0x0028, val);
- /* The following can be used to direct S/PDIF output to pin 47 (EAPD).
- snd_ac97_write_cache(ac97, 0x62, snd_ac97_read(ac97, 0x62) | 0x0008); */
-}
-
-static const struct snd_kcontrol_new snd_ac97_ymf753_controls_spdif[3] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
- .info = snd_ac97_ymf7x3_spdif_source_info,
- .get = snd_ac97_ymf7x3_spdif_source_get,
- .put = snd_ac97_ymf7x3_spdif_source_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Output Pin",
- .info = snd_ac97_ymf753_spdif_output_pin_info,
- .get = snd_ac97_ymf753_spdif_output_pin_get,
- .put = snd_ac97_ymf753_spdif_output_pin_put,
- },
- AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE, NONE) "Mute",
- AC97_YMF7X3_DIT_CTRL, 2, 1, 1)
-};
-
-static int patch_yamaha_ymf753_post_spdif(struct snd_ac97 * ac97)
-{
- int err;
-
- if ((err = patch_build_controls(ac97, snd_ac97_ymf753_controls_spdif, ARRAY_SIZE(snd_ac97_ymf753_controls_spdif))) < 0)
- return err;
- return 0;
-}
-
-static const struct snd_ac97_build_ops patch_yamaha_ymf753_ops = {
- .build_3d = patch_yamaha_ymf7x3_3d,
- .build_post_spdif = patch_yamaha_ymf753_post_spdif
-};
-
-static int patch_yamaha_ymf753(struct snd_ac97 * ac97)
-{
- /* Patch for Yamaha YMF753, Copyright (c) by David Shust, dshust@shustring.com.
- This chip has nonstandard and extended behaviour with regard to its S/PDIF output.
- The AC'97 spec states that the S/PDIF signal is to be output at pin 48.
- The YMF753 will ouput the S/PDIF signal to pin 43, 47 (EAPD), or 48.
- By default, no output pin is selected, and the S/PDIF signal is not output.
- There is also a bit to mute S/PDIF output in a vendor-specific register.
- */
- ac97->build_ops = &patch_yamaha_ymf753_ops;
- ac97->caps |= AC97_BC_BASS_TREBLE;
- ac97->caps |= 0x04 << 10; /* Yamaha 3D enhancement */
- return 0;
-}
-
-/*
- * May 2, 2003 Liam Girdwood <lrg@slimlogic.co.uk>
- * removed broken wolfson00 patch.
- * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717.
- */
-
-static const struct snd_kcontrol_new wm97xx_snd_ac97_controls[] = {
-AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL, 8, 0, 31, 1),
-AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL, 15, 1, 1),
-};
-
-static int patch_wolfson_wm9703_specific(struct snd_ac97 * ac97)
-{
- /* This is known to work for the ViewSonic ViewPad 1000
- * Randolph Bentson <bentson@holmsjoen.com>
- * WM9703/9707/9708/9717
- */
- int err, i;
-
- for (i = 0; i < ARRAY_SIZE(wm97xx_snd_ac97_controls); i++) {
- if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm97xx_snd_ac97_controls[i], ac97))) < 0)
- return err;
- }
- snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808);
- return 0;
-}
-
-static const struct snd_ac97_build_ops patch_wolfson_wm9703_ops = {
- .build_specific = patch_wolfson_wm9703_specific,
-};
-
-static int patch_wolfson03(struct snd_ac97 * ac97)
-{
- ac97->build_ops = &patch_wolfson_wm9703_ops;
- return 0;
-}
-
-static const struct snd_kcontrol_new wm9704_snd_ac97_controls[] = {
-AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL, 8, 0, 31, 1),
-AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL, 15, 1, 1),
-AC97_DOUBLE("Rear Playback Volume", AC97_WM9704_RMIXER_VOL, 8, 0, 31, 1),
-AC97_SINGLE("Rear Playback Switch", AC97_WM9704_RMIXER_VOL, 15, 1, 1),
-AC97_DOUBLE("Rear DAC Volume", AC97_WM9704_RPCM_VOL, 8, 0, 31, 1),
-AC97_DOUBLE("Surround Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1),
-};
-
-static int patch_wolfson_wm9704_specific(struct snd_ac97 * ac97)
-{
- int err, i;
- for (i = 0; i < ARRAY_SIZE(wm9704_snd_ac97_controls); i++) {
- if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm9704_snd_ac97_controls[i], ac97))) < 0)
- return err;
- }
- /* patch for DVD noise */
- snd_ac97_write_cache(ac97, AC97_WM9704_TEST, 0x0200);
- return 0;
-}
-
-static const struct snd_ac97_build_ops patch_wolfson_wm9704_ops = {
- .build_specific = patch_wolfson_wm9704_specific,
-};
-
-static int patch_wolfson04(struct snd_ac97 * ac97)
-{
- /* WM9704M/9704Q */
- ac97->build_ops = &patch_wolfson_wm9704_ops;
- return 0;
-}
-
-static int patch_wolfson05(struct snd_ac97 * ac97)
-{
- /* WM9705, WM9710 */
- ac97->build_ops = &patch_wolfson_wm9703_ops;
-#ifdef CONFIG_TOUCHSCREEN_WM9705
- /* WM9705 touchscreen uses AUX and VIDEO for touch */
- ac97->flags |= AC97_HAS_NO_VIDEO | AC97_HAS_NO_AUX;
-#endif
- return 0;
-}
-
-static const char* wm9711_alc_select[] = {"None", "Left", "Right", "Stereo"};
-static const char* wm9711_alc_mix[] = {"Stereo", "Right", "Left", "None"};
-static const char* wm9711_out3_src[] = {"Left", "VREF", "Left + Right", "Mono"};
-static const char* wm9711_out3_lrsrc[] = {"Master Mix", "Headphone Mix"};
-static const char* wm9711_rec_adc[] = {"Stereo", "Left", "Right", "Mute"};
-static const char* wm9711_base[] = {"Linear Control", "Adaptive Boost"};
-static const char* wm9711_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"};
-static const char* wm9711_mic[] = {"Mic 1", "Differential", "Mic 2", "Stereo"};
-static const char* wm9711_rec_sel[] =
- {"Mic 1", "NC", "NC", "Master Mix", "Line", "Headphone Mix", "Phone Mix", "Phone"};
-static const char* wm9711_ng_type[] = {"Constant Gain", "Mute"};
-
-static const struct ac97_enum wm9711_enum[] = {
-AC97_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9711_alc_select),
-AC97_ENUM_SINGLE(AC97_VIDEO, 10, 4, wm9711_alc_mix),
-AC97_ENUM_SINGLE(AC97_AUX, 9, 4, wm9711_out3_src),
-AC97_ENUM_SINGLE(AC97_AUX, 8, 2, wm9711_out3_lrsrc),
-AC97_ENUM_SINGLE(AC97_REC_SEL, 12, 4, wm9711_rec_adc),
-AC97_ENUM_SINGLE(AC97_MASTER_TONE, 15, 2, wm9711_base),
-AC97_ENUM_DOUBLE(AC97_REC_GAIN, 14, 6, 2, wm9711_rec_gain),
-AC97_ENUM_SINGLE(AC97_MIC, 5, 4, wm9711_mic),
-AC97_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 8, wm9711_rec_sel),
-AC97_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9711_ng_type),
-};
-
-static const struct snd_kcontrol_new wm9711_snd_ac97_controls[] = {
-AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0),
-AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0),
-AC97_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV, 4, 15, 0),
-AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0),
-AC97_ENUM("ALC Function", wm9711_enum[0]),
-AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 1),
-AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 1),
-AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0),
-AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0),
-AC97_ENUM("ALC NG Type", wm9711_enum[9]),
-AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 1),
-
-AC97_SINGLE("Side Tone Switch", AC97_VIDEO, 15, 1, 1),
-AC97_SINGLE("Side Tone Volume", AC97_VIDEO, 12, 7, 1),
-AC97_ENUM("ALC Headphone Mux", wm9711_enum[1]),
-AC97_SINGLE("ALC Headphone Volume", AC97_VIDEO, 7, 7, 1),
-
-AC97_SINGLE("Out3 Switch", AC97_AUX, 15, 1, 1),
-AC97_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 0),
-AC97_ENUM("Out3 Mux", wm9711_enum[2]),
-AC97_ENUM("Out3 LR Mux", wm9711_enum[3]),
-AC97_SINGLE("Out3 Volume", AC97_AUX, 0, 31, 1),
-
-AC97_SINGLE("Beep to Headphone Switch", AC97_PC_BEEP, 15, 1, 1),
-AC97_SINGLE("Beep to Headphone Volume", AC97_PC_BEEP, 12, 7, 1),
-AC97_SINGLE("Beep to Side Tone Switch", AC97_PC_BEEP, 11, 1, 1),
-AC97_SINGLE("Beep to Side Tone Volume", AC97_PC_BEEP, 8, 7, 1),
-AC97_SINGLE("Beep to Phone Switch", AC97_PC_BEEP, 7, 1, 1),
-AC97_SINGLE("Beep to Phone Volume", AC97_PC_BEEP, 4, 7, 1),
-
-AC97_SINGLE("Aux to Headphone Switch", AC97_CD, 15, 1, 1),
-AC97_SINGLE("Aux to Headphone Volume", AC97_CD, 12, 7, 1),
-AC97_SINGLE("Aux to Side Tone Switch", AC97_CD, 11, 1, 1),
-AC97_SINGLE("Aux to Side Tone Volume", AC97_CD, 8, 7, 1),
-AC97_SINGLE("Aux to Phone Switch", AC97_CD, 7, 1, 1),
-AC97_SINGLE("Aux to Phone Volume", AC97_CD, 4, 7, 1),
-
-AC97_SINGLE("Phone to Headphone Switch", AC97_PHONE, 15, 1, 1),
-AC97_SINGLE("Phone to Master Switch", AC97_PHONE, 14, 1, 1),
-
-AC97_SINGLE("Line to Headphone Switch", AC97_LINE, 15, 1, 1),
-AC97_SINGLE("Line to Master Switch", AC97_LINE, 14, 1, 1),
-AC97_SINGLE("Line to Phone Switch", AC97_LINE, 13, 1, 1),
-
-AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PCM, 15, 1, 1),
-AC97_SINGLE("PCM Playback to Master Switch", AC97_PCM, 14, 1, 1),
-AC97_SINGLE("PCM Playback to Phone Switch", AC97_PCM, 13, 1, 1),
-
-AC97_SINGLE("Capture 20dB Boost Switch", AC97_REC_SEL, 14, 1, 0),
-AC97_ENUM("Capture to Phone Mux", wm9711_enum[4]),
-AC97_SINGLE("Capture to Phone 20dB Boost Switch", AC97_REC_SEL, 11, 1, 1),
-AC97_ENUM("Capture Select", wm9711_enum[8]),
-
-AC97_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1),
-AC97_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1),
-
-AC97_ENUM("Bass Control", wm9711_enum[5]),
-AC97_SINGLE("Bass Cut-off Switch", AC97_MASTER_TONE, 12, 1, 1),
-AC97_SINGLE("Tone Cut-off Switch", AC97_MASTER_TONE, 4, 1, 1),
-AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0),
-
-AC97_SINGLE("ADC Switch", AC97_REC_GAIN, 15, 1, 1),
-AC97_ENUM("Capture Volume Steps", wm9711_enum[6]),
-AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1),
-AC97_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0),
-
-AC97_SINGLE("Mic 1 to Phone Switch", AC97_MIC, 14, 1, 1),
-AC97_SINGLE("Mic 2 to Phone Switch", AC97_MIC, 13, 1, 1),
-AC97_ENUM("Mic Select Source", wm9711_enum[7]),
-AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1),
-AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1),
-AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0),
-
-AC97_SINGLE("Master Left Inv Switch", AC97_MASTER, 6, 1, 0),
-AC97_SINGLE("Master ZC Switch", AC97_MASTER, 7, 1, 0),
-AC97_SINGLE("Headphone ZC Switch", AC97_HEADPHONE, 7, 1, 0),
-AC97_SINGLE("Mono ZC Switch", AC97_MASTER_MONO, 7, 1, 0),
-};
-
-static int patch_wolfson_wm9711_specific(struct snd_ac97 * ac97)
-{
- int err, i;
-
- for (i = 0; i < ARRAY_SIZE(wm9711_snd_ac97_controls); i++) {
- if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm9711_snd_ac97_controls[i], ac97))) < 0)
- return err;
- }
- snd_ac97_write_cache(ac97, AC97_CODEC_CLASS_REV, 0x0808);
- snd_ac97_write_cache(ac97, AC97_PCI_SVID, 0x0808);
- snd_ac97_write_cache(ac97, AC97_VIDEO, 0x0808);
- snd_ac97_write_cache(ac97, AC97_AUX, 0x0808);
- snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808);
- snd_ac97_write_cache(ac97, AC97_CD, 0x0000);
- return 0;
-}
-
-static const struct snd_ac97_build_ops patch_wolfson_wm9711_ops = {
- .build_specific = patch_wolfson_wm9711_specific,
-};
-
-static int patch_wolfson11(struct snd_ac97 * ac97)
-{
- /* WM9711, WM9712 */
- ac97->build_ops = &patch_wolfson_wm9711_ops;
-
- ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_MIC |
- AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD;
-
- return 0;
-}
-
-static const char* wm9713_mic_mixer[] = {"Stereo", "Mic 1", "Mic 2", "Mute"};
-static const char* wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"};
-static const char* wm9713_rec_src[] =
- {"Mic 1", "Mic 2", "Line", "Mono In", "Headphone Mix", "Master Mix",
- "Mono Mix", "Zh"};
-static const char* wm9713_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"};
-static const char* wm9713_alc_select[] = {"None", "Left", "Right", "Stereo"};
-static const char* wm9713_mono_pga[] = {"Vmid", "Zh", "Mono Mix", "Inv 1"};
-static const char* wm9713_spk_pga[] =
- {"Vmid", "Zh", "Headphone Mix", "Master Mix", "Inv", "NC", "NC", "NC"};
-static const char* wm9713_hp_pga[] = {"Vmid", "Zh", "Headphone Mix", "NC"};
-static const char* wm9713_out3_pga[] = {"Vmid", "Zh", "Inv 1", "NC"};
-static const char* wm9713_out4_pga[] = {"Vmid", "Zh", "Inv 2", "NC"};
-static const char* wm9713_dac_inv[] =
- {"Off", "Mono Mix", "Master Mix", "Headphone Mix L", "Headphone Mix R",
- "Headphone Mix Mono", "NC", "Vmid"};
-static const char* wm9713_base[] = {"Linear Control", "Adaptive Boost"};
-static const char* wm9713_ng_type[] = {"Constant Gain", "Mute"};
-
-static const struct ac97_enum wm9713_enum[] = {
-AC97_ENUM_SINGLE(AC97_LINE, 3, 4, wm9713_mic_mixer),
-AC97_ENUM_SINGLE(AC97_VIDEO, 14, 4, wm9713_rec_mux),
-AC97_ENUM_SINGLE(AC97_VIDEO, 9, 4, wm9713_rec_mux),
-AC97_ENUM_DOUBLE(AC97_VIDEO, 3, 0, 8, wm9713_rec_src),
-AC97_ENUM_DOUBLE(AC97_CD, 14, 6, 2, wm9713_rec_gain),
-AC97_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9713_alc_select),
-AC97_ENUM_SINGLE(AC97_REC_GAIN, 14, 4, wm9713_mono_pga),
-AC97_ENUM_DOUBLE(AC97_REC_GAIN, 11, 8, 8, wm9713_spk_pga),
-AC97_ENUM_DOUBLE(AC97_REC_GAIN, 6, 4, 4, wm9713_hp_pga),
-AC97_ENUM_SINGLE(AC97_REC_GAIN, 2, 4, wm9713_out3_pga),
-AC97_ENUM_SINGLE(AC97_REC_GAIN, 0, 4, wm9713_out4_pga),
-AC97_ENUM_DOUBLE(AC97_REC_GAIN_MIC, 13, 10, 8, wm9713_dac_inv),
-AC97_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, wm9713_base),
-AC97_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9713_ng_type),
-};
-
-static const struct snd_kcontrol_new wm13_snd_ac97_controls[] = {
-AC97_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1),
-AC97_SINGLE("Line In to Headphone Switch", AC97_PC_BEEP, 15, 1, 1),
-AC97_SINGLE("Line In to Master Switch", AC97_PC_BEEP, 14, 1, 1),
-AC97_SINGLE("Line In to Mono Switch", AC97_PC_BEEP, 13, 1, 1),
-
-AC97_DOUBLE("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1),
-AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PHONE, 15, 1, 1),
-AC97_SINGLE("PCM Playback to Master Switch", AC97_PHONE, 14, 1, 1),
-AC97_SINGLE("PCM Playback to Mono Switch", AC97_PHONE, 13, 1, 1),
-
-AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1),
-AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1),
-AC97_SINGLE("Mic 1 to Mono Switch", AC97_LINE, 7, 1, 1),
-AC97_SINGLE("Mic 2 to Mono Switch", AC97_LINE, 6, 1, 1),
-AC97_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0),
-AC97_ENUM("Mic to Headphone Mux", wm9713_enum[0]),
-AC97_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1),
-
-AC97_SINGLE("Capture Switch", AC97_CD, 15, 1, 1),
-AC97_ENUM("Capture Volume Steps", wm9713_enum[4]),
-AC97_DOUBLE("Capture Volume", AC97_CD, 8, 0, 15, 0),
-AC97_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0),
-
-AC97_ENUM("Capture to Headphone Mux", wm9713_enum[1]),
-AC97_SINGLE("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1),
-AC97_ENUM("Capture to Mono Mux", wm9713_enum[2]),
-AC97_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0),
-AC97_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0),
-AC97_ENUM("Capture Select", wm9713_enum[3]),
-
-AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0),
-AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0),
-AC97_SINGLE("ALC Decay Time ", AC97_CODEC_CLASS_REV, 4, 15, 0),
-AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0),
-AC97_ENUM("ALC Function", wm9713_enum[5]),
-AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0),
-AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 0),
-AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0),
-AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0),
-AC97_ENUM("ALC NG Type", wm9713_enum[13]),
-AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 0),
-
-AC97_DOUBLE("Master ZC Switch", AC97_MASTER, 14, 6, 1, 0),
-AC97_DOUBLE("Headphone ZC Switch", AC97_HEADPHONE, 14, 6, 1, 0),
-AC97_DOUBLE("Out3/4 ZC Switch", AC97_MASTER_MONO, 14, 6, 1, 0),
-AC97_SINGLE("Master Right Switch", AC97_MASTER, 7, 1, 1),
-AC97_SINGLE("Headphone Right Switch", AC97_HEADPHONE, 7, 1, 1),
-AC97_SINGLE("Out3/4 Right Switch", AC97_MASTER_MONO, 7, 1, 1),
-
-AC97_SINGLE("Mono In to Headphone Switch", AC97_MASTER_TONE, 15, 1, 1),
-AC97_SINGLE("Mono In to Master Switch", AC97_MASTER_TONE, 14, 1, 1),
-AC97_SINGLE("Mono In Volume", AC97_MASTER_TONE, 8, 31, 1),
-AC97_SINGLE("Mono Switch", AC97_MASTER_TONE, 7, 1, 1),
-AC97_SINGLE("Mono ZC Switch", AC97_MASTER_TONE, 6, 1, 0),
-AC97_SINGLE("Mono Volume", AC97_MASTER_TONE, 0, 31, 1),
-
-AC97_SINGLE("Beep to Headphone Switch", AC97_AUX, 15, 1, 1),
-AC97_SINGLE("Beep to Headphone Volume", AC97_AUX, 12, 7, 1),
-AC97_SINGLE("Beep to Master Switch", AC97_AUX, 11, 1, 1),
-AC97_SINGLE("Beep to Master Volume", AC97_AUX, 8, 7, 1),
-AC97_SINGLE("Beep to Mono Switch", AC97_AUX, 7, 1, 1),
-AC97_SINGLE("Beep to Mono Volume", AC97_AUX, 4, 7, 1),
-
-AC97_SINGLE("Voice to Headphone Switch", AC97_PCM, 15, 1, 1),
-AC97_SINGLE("Voice to Headphone Volume", AC97_PCM, 12, 7, 1),
-AC97_SINGLE("Voice to Master Switch", AC97_PCM, 11, 1, 1),
-AC97_SINGLE("Voice to Master Volume", AC97_PCM, 8, 7, 1),
-AC97_SINGLE("Voice to Mono Switch", AC97_PCM, 7, 1, 1),
-AC97_SINGLE("Voice to Mono Volume", AC97_PCM, 4, 7, 1),
-
-AC97_SINGLE("Aux to Headphone Switch", AC97_REC_SEL, 15, 1, 1),
-AC97_SINGLE("Aux to Headphone Volume", AC97_REC_SEL, 12, 7, 1),
-AC97_SINGLE("Aux to Master Switch", AC97_REC_SEL, 11, 1, 1),
-AC97_SINGLE("Aux to Master Volume", AC97_REC_SEL, 8, 7, 1),
-AC97_SINGLE("Aux to Mono Switch", AC97_REC_SEL, 7, 1, 1),
-AC97_SINGLE("Aux to Mono Volume", AC97_REC_SEL, 4, 7, 1),
-
-AC97_ENUM("Mono Input Mux", wm9713_enum[6]),
-AC97_ENUM("Master Input Mux", wm9713_enum[7]),
-AC97_ENUM("Headphone Input Mux", wm9713_enum[8]),
-AC97_ENUM("Out 3 Input Mux", wm9713_enum[9]),
-AC97_ENUM("Out 4 Input Mux", wm9713_enum[10]),
-
-AC97_ENUM("Bass Control", wm9713_enum[12]),
-AC97_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1),
-AC97_SINGLE("Tone Cut-off Switch", AC97_GENERAL_PURPOSE, 4, 1, 1),
-AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_GENERAL_PURPOSE, 6, 1, 0),
-AC97_SINGLE("Bass Volume", AC97_GENERAL_PURPOSE, 8, 15, 1),
-AC97_SINGLE("Tone Volume", AC97_GENERAL_PURPOSE, 0, 15, 1),
-};
-
-static const struct snd_kcontrol_new wm13_snd_ac97_controls_3d[] = {
-AC97_ENUM("Inv Input Mux", wm9713_enum[11]),
-AC97_SINGLE("3D Upper Cut-off Switch", AC97_REC_GAIN_MIC, 5, 1, 0),
-AC97_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0),
-AC97_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1),
-};
-
-static int patch_wolfson_wm9713_3d (struct snd_ac97 * ac97)
-{
- int err, i;
-
- for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_3d); i++) {
- if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_3d[i], ac97))) < 0)
- return err;
- }
- return 0;
-}
-
-static int patch_wolfson_wm9713_specific(struct snd_ac97 * ac97)
-{
- int err, i;
-
- for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls); i++) {
- if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls[i], ac97))) < 0)
- return err;
- }
- snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808);
- snd_ac97_write_cache(ac97, AC97_PHONE, 0x0808);
- snd_ac97_write_cache(ac97, AC97_MIC, 0x0808);
- snd_ac97_write_cache(ac97, AC97_LINE, 0x00da);
- snd_ac97_write_cache(ac97, AC97_CD, 0x0808);
- snd_ac97_write_cache(ac97, AC97_VIDEO, 0xd612);
- snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x1ba0);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static void patch_wolfson_wm9713_suspend (struct snd_ac97 * ac97)
-{
- snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xfeff);
- snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0xffff);
-}
-
-static void patch_wolfson_wm9713_resume (struct snd_ac97 * ac97)
-{
- snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xda00);
- snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0x3810);
- snd_ac97_write_cache(ac97, AC97_POWERDOWN, 0x0);
-}
-#endif
-
-static const struct snd_ac97_build_ops patch_wolfson_wm9713_ops = {
- .build_specific = patch_wolfson_wm9713_specific,
- .build_3d = patch_wolfson_wm9713_3d,
-#ifdef CONFIG_PM
- .suspend = patch_wolfson_wm9713_suspend,
- .resume = patch_wolfson_wm9713_resume
-#endif
-};
-
-static int patch_wolfson13(struct snd_ac97 * ac97)
-{
- /* WM9713, WM9714 */
- ac97->build_ops = &patch_wolfson_wm9713_ops;
-
- ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_PHONE |
- AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD | AC97_HAS_NO_TONE |
- AC97_HAS_NO_STD_PCM;
- ac97->scaps &= ~AC97_SCAP_MODEM;
-
- snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xda00);
- snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0x3810);
- snd_ac97_write_cache(ac97, AC97_POWERDOWN, 0x0);
-
- return 0;
-}
-
-/*
- * Tritech codec
- */
-static int patch_tritech_tr28028(struct snd_ac97 * ac97)
-{
- snd_ac97_write_cache(ac97, 0x26, 0x0300);
- snd_ac97_write_cache(ac97, 0x26, 0x0000);
- snd_ac97_write_cache(ac97, AC97_SURROUND_MASTER, 0x0000);
- snd_ac97_write_cache(ac97, AC97_SPDIF, 0x0000);
- return 0;
-}
-
-/*
- * Sigmatel STAC97xx codecs
- */
-static int patch_sigmatel_stac9700_3d(struct snd_ac97 * ac97)
-{
- struct snd_kcontrol *kctl;
- int err;
-
- if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
- return err;
- strcpy(kctl->id.name, "3D Control Sigmatel - Depth");
- kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 2, 3, 0);
- snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
- return 0;
-}
-
-static int patch_sigmatel_stac9708_3d(struct snd_ac97 * ac97)
-{
- struct snd_kcontrol *kctl;
- int err;
-
- if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
- return err;
- strcpy(kctl->id.name, "3D Control Sigmatel - Depth");
- kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 0, 3, 0);
- if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
- return err;
- strcpy(kctl->id.name, "3D Control Sigmatel - Rear Depth");
- kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 2, 3, 0);
- snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
- return 0;
-}
-
-static const struct snd_kcontrol_new snd_ac97_sigmatel_4speaker =
-AC97_SINGLE("Sigmatel 4-Speaker Stereo Playback Switch",
- AC97_SIGMATEL_DAC2INVERT, 2, 1, 0);
-
-/* "Sigmatel " removed due to excessive name length: */
-static const struct snd_kcontrol_new snd_ac97_sigmatel_phaseinvert =
-AC97_SINGLE("Surround Phase Inversion Playback Switch",
- AC97_SIGMATEL_DAC2INVERT, 3, 1, 0);
-
-static const struct snd_kcontrol_new snd_ac97_sigmatel_controls[] = {
-AC97_SINGLE("Sigmatel DAC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 1, 1, 0),
-AC97_SINGLE("Sigmatel ADC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 0, 1, 0)
-};
-
-static int patch_sigmatel_stac97xx_specific(struct snd_ac97 * ac97)
-{
- int err;
-
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_ANALOG, snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) & ~0x0003);
- if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_ANALOG, 1))
- if ((err = patch_build_controls(ac97, &snd_ac97_sigmatel_controls[0], 1)) < 0)
- return err;
- if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_ANALOG, 0))
- if ((err = patch_build_controls(ac97, &snd_ac97_sigmatel_controls[1], 1)) < 0)
- return err;
- if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_DAC2INVERT, 2))
- if ((err = patch_build_controls(ac97, &snd_ac97_sigmatel_4speaker, 1)) < 0)
- return err;
- if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_DAC2INVERT, 3))
- if ((err = patch_build_controls(ac97, &snd_ac97_sigmatel_phaseinvert, 1)) < 0)
- return err;
- return 0;
-}
-
-static const struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = {
- .build_3d = patch_sigmatel_stac9700_3d,
- .build_specific = patch_sigmatel_stac97xx_specific
-};
-
-static int patch_sigmatel_stac9700(struct snd_ac97 * ac97)
-{
- ac97->build_ops = &patch_sigmatel_stac9700_ops;
- return 0;
-}
-
-static int snd_ac97_stac9708_put_bias(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- int err;
-
- mutex_lock(&ac97->page_mutex);
- snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
- err = snd_ac97_update_bits(ac97, AC97_SIGMATEL_BIAS2, 0x0010,
- (ucontrol->value.integer.value[0] & 1) << 4);
- snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0);
- mutex_unlock(&ac97->page_mutex);
- return err;
-}
-
-static const struct snd_kcontrol_new snd_ac97_stac9708_bias_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Sigmatel Output Bias Switch",
- .info = snd_ac97_info_volsw,
- .get = snd_ac97_get_volsw,
- .put = snd_ac97_stac9708_put_bias,
- .private_value = AC97_SINGLE_VALUE(AC97_SIGMATEL_BIAS2, 4, 1, 0),
-};
-
-static int patch_sigmatel_stac9708_specific(struct snd_ac97 *ac97)
-{
- int err;
-
- /* the register bit is writable, but the function is not implemented: */
- snd_ac97_remove_ctl(ac97, "PCM Out Path & Mute", NULL);
-
- snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Sigmatel Surround Playback");
- if ((err = patch_build_controls(ac97, &snd_ac97_stac9708_bias_control, 1)) < 0)
- return err;
- return patch_sigmatel_stac97xx_specific(ac97);
-}
-
-static const struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = {
- .build_3d = patch_sigmatel_stac9708_3d,
- .build_specific = patch_sigmatel_stac9708_specific
-};
-
-static int patch_sigmatel_stac9708(struct snd_ac97 * ac97)
-{
- unsigned int codec72, codec6c;
-
- ac97->build_ops = &patch_sigmatel_stac9708_ops;
- ac97->caps |= 0x10; /* HP (sigmatel surround) support */
-
- codec72 = snd_ac97_read(ac97, AC97_SIGMATEL_BIAS2) & 0x8000;
- codec6c = snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG);
-
- if ((codec72==0) && (codec6c==0)) {
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x1000);
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0007);
- } else if ((codec72==0x8000) && (codec6c==0)) {
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x1001);
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_DAC2INVERT, 0x0008);
- } else if ((codec72==0x8000) && (codec6c==0x0080)) {
- /* nothing */
- }
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000);
- return 0;
-}
-
-static int patch_sigmatel_stac9721(struct snd_ac97 * ac97)
-{
- ac97->build_ops = &patch_sigmatel_stac9700_ops;
- if (snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) == 0) {
- // patch for SigmaTel
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x4000);
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002);
- }
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000);
- return 0;
-}
-
-static int patch_sigmatel_stac9744(struct snd_ac97 * ac97)
-{
- // patch for SigmaTel
- ac97->build_ops = &patch_sigmatel_stac9700_ops;
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x0000); /* is this correct? --jk */
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002);
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000);
- return 0;
-}
-
-static int patch_sigmatel_stac9756(struct snd_ac97 * ac97)
-{
- // patch for SigmaTel
- ac97->build_ops = &patch_sigmatel_stac9700_ops;
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba);
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x0000); /* is this correct? --jk */
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba);
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002);
- snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000);
- return 0;
-}
-
-static int snd_ac97_stac9758_output_jack_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[5] = { "Input/Disabled", "Front Output",
- "Rear Output", "Center/LFE Output", "Mixer Output" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 5;
- if (uinfo->value.enumerated.item > 4)
- uinfo->value.enumerated.item = 4;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ac97_stac9758_output_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- int shift = kcontrol->private_value;
- unsigned short val;
-
- val = ac97->regs[AC97_SIGMATEL_OUTSEL] >> shift;
- if (!(val & 4))
- ucontrol->value.enumerated.item[0] = 0;
- else
- ucontrol->value.enumerated.item[0] = 1 + (val & 3);
- return 0;
-}
-
-static int snd_ac97_stac9758_output_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- int shift = kcontrol->private_value;
- unsigned short val;
-
- if (ucontrol->value.enumerated.item[0] > 4)
- return -EINVAL;
- if (ucontrol->value.enumerated.item[0] == 0)
- val = 0;
- else
- val = 4 | (ucontrol->value.enumerated.item[0] - 1);
- return ac97_update_bits_page(ac97, AC97_SIGMATEL_OUTSEL,
- 7 << shift, val << shift, 0);
-}
-
-static int snd_ac97_stac9758_input_jack_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[7] = { "Mic2 Jack", "Mic1 Jack", "Line In Jack",
- "Front Jack", "Rear Jack", "Center/LFE Jack", "Mute" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 7;
- if (uinfo->value.enumerated.item > 6)
- uinfo->value.enumerated.item = 6;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ac97_stac9758_input_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- int shift = kcontrol->private_value;
- unsigned short val;
-
- val = ac97->regs[AC97_SIGMATEL_INSEL];
- ucontrol->value.enumerated.item[0] = (val >> shift) & 7;
- return 0;
-}
-
-static int snd_ac97_stac9758_input_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- int shift = kcontrol->private_value;
-
- return ac97_update_bits_page(ac97, AC97_SIGMATEL_INSEL, 7 << shift,
- ucontrol->value.enumerated.item[0] << shift, 0);
-}
-
-static int snd_ac97_stac9758_phonesel_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[3] = { "None", "Front Jack", "Rear Jack" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item > 2)
- uinfo->value.enumerated.item = 2;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ac97_stac9758_phonesel_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = ac97->regs[AC97_SIGMATEL_IOMISC] & 3;
- return 0;
-}
-
-static int snd_ac97_stac9758_phonesel_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
-
- return ac97_update_bits_page(ac97, AC97_SIGMATEL_IOMISC, 3,
- ucontrol->value.enumerated.item[0], 0);
-}
-
-#define STAC9758_OUTPUT_JACK(xname, shift) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_ac97_stac9758_output_jack_info, \
- .get = snd_ac97_stac9758_output_jack_get, \
- .put = snd_ac97_stac9758_output_jack_put, \
- .private_value = shift }
-#define STAC9758_INPUT_JACK(xname, shift) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_ac97_stac9758_input_jack_info, \
- .get = snd_ac97_stac9758_input_jack_get, \
- .put = snd_ac97_stac9758_input_jack_put, \
- .private_value = shift }
-static const struct snd_kcontrol_new snd_ac97_sigmatel_stac9758_controls[] = {
- STAC9758_OUTPUT_JACK("Mic1 Jack", 1),
- STAC9758_OUTPUT_JACK("LineIn Jack", 4),
- STAC9758_OUTPUT_JACK("Front Jack", 7),
- STAC9758_OUTPUT_JACK("Rear Jack", 10),
- STAC9758_OUTPUT_JACK("Center/LFE Jack", 13),
- STAC9758_INPUT_JACK("Mic Input Source", 0),
- STAC9758_INPUT_JACK("Line Input Source", 8),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Headphone Amp",
- .info = snd_ac97_stac9758_phonesel_info,
- .get = snd_ac97_stac9758_phonesel_get,
- .put = snd_ac97_stac9758_phonesel_put
- },
- AC97_SINGLE("Exchange Center/LFE", AC97_SIGMATEL_IOMISC, 4, 1, 0),
- AC97_SINGLE("Headphone +3dB Boost", AC97_SIGMATEL_IOMISC, 8, 1, 0)
-};
-
-static int patch_sigmatel_stac9758_specific(struct snd_ac97 *ac97)
-{
- int err;
-
- err = patch_sigmatel_stac97xx_specific(ac97);
- if (err < 0)
- return err;
- err = patch_build_controls(ac97, snd_ac97_sigmatel_stac9758_controls,
- ARRAY_SIZE(snd_ac97_sigmatel_stac9758_controls));
- if (err < 0)
- return err;
- /* DAC-A direct */
- snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Front Playback");
- /* DAC-A to Mix = PCM */
- /* DAC-B direct = Surround */
- /* DAC-B to Mix */
- snd_ac97_rename_vol_ctl(ac97, "Video Playback", "Surround Mix Playback");
- /* DAC-C direct = Center/LFE */
-
- return 0;
-}
-
-static const struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = {
- .build_3d = patch_sigmatel_stac9700_3d,
- .build_specific = patch_sigmatel_stac9758_specific
-};
-
-static int patch_sigmatel_stac9758(struct snd_ac97 * ac97)
-{
- static unsigned short regs[4] = {
- AC97_SIGMATEL_OUTSEL,
- AC97_SIGMATEL_IOMISC,
- AC97_SIGMATEL_INSEL,
- AC97_SIGMATEL_VARIOUS
- };
- static unsigned short def_regs[4] = {
- /* OUTSEL */ 0xd794, /* CL:CL, SR:SR, LO:MX, LI:DS, MI:DS */
- /* IOMISC */ 0x2001,
- /* INSEL */ 0x0201, /* LI:LI, MI:M1 */
- /* VARIOUS */ 0x0040
- };
- static unsigned short m675_regs[4] = {
- /* OUTSEL */ 0xfc70, /* CL:MX, SR:MX, LO:DS, LI:MX, MI:DS */
- /* IOMISC */ 0x2102, /* HP amp on */
- /* INSEL */ 0x0203, /* LI:LI, MI:FR */
- /* VARIOUS */ 0x0041 /* stereo mic */
- };
- unsigned short *pregs = def_regs;
- int i;
-
- /* Gateway M675 notebook */
- if (ac97->pci &&
- ac97->subsystem_vendor == 0x107b &&
- ac97->subsystem_device == 0x0601)
- pregs = m675_regs;
-
- // patch for SigmaTel
- ac97->build_ops = &patch_sigmatel_stac9758_ops;
- /* FIXME: assume only page 0 for writing cache */
- snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR);
- for (i = 0; i < 4; i++)
- snd_ac97_write_cache(ac97, regs[i], pregs[i]);
-
- ac97->flags |= AC97_STEREO_MUTES;
- return 0;
-}
-
-/*
- * Cirrus Logic CS42xx codecs
- */
-static const struct snd_kcontrol_new snd_ac97_cirrus_controls_spdif[2] = {
- AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), AC97_CSR_SPDIF, 15, 1, 0),
- AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "AC97-SPSA", AC97_CSR_ACMODE, 0, 3, 0)
-};
-
-static int patch_cirrus_build_spdif(struct snd_ac97 * ac97)
-{
- int err;
-
- /* con mask, pro mask, default */
- if ((err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3)) < 0)
- return err;
- /* switch, spsa */
- if ((err = patch_build_controls(ac97, &snd_ac97_cirrus_controls_spdif[0], 1)) < 0)
- return err;
- switch (ac97->id & AC97_ID_CS_MASK) {
- case AC97_ID_CS4205:
- if ((err = patch_build_controls(ac97, &snd_ac97_cirrus_controls_spdif[1], 1)) < 0)
- return err;
- break;
- }
- /* set default PCM S/PDIF params */
- /* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */
- snd_ac97_write_cache(ac97, AC97_CSR_SPDIF, 0x0a20);
- return 0;
-}
-
-static const struct snd_ac97_build_ops patch_cirrus_ops = {
- .build_spdif = patch_cirrus_build_spdif
-};
-
-static int patch_cirrus_spdif(struct snd_ac97 * ac97)
-{
- /* Basically, the cs4201/cs4205/cs4297a has non-standard sp/dif registers.
- WHY CAN'T ANYONE FOLLOW THE BLOODY SPEC? *sigh*
- - sp/dif EA ID is not set, but sp/dif is always present.
- - enable/disable is spdif register bit 15.
- - sp/dif control register is 0x68. differs from AC97:
- - valid is bit 14 (vs 15)
- - no DRS
- - only 44.1/48k [00 = 48, 01=44,1] (AC97 is 00=44.1, 10=48)
- - sp/dif ssource select is in 0x5e bits 0,1.
- */
-
- ac97->build_ops = &patch_cirrus_ops;
- ac97->flags |= AC97_CS_SPDIF;
- ac97->rates[AC97_RATES_SPDIF] &= ~SNDRV_PCM_RATE_32000;
- ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */
- snd_ac97_write_cache(ac97, AC97_CSR_ACMODE, 0x0080);
- return 0;
-}
-
-static int patch_cirrus_cs4299(struct snd_ac97 * ac97)
-{
- /* force the detection of PC Beep */
- ac97->flags |= AC97_HAS_PC_BEEP;
-
- return patch_cirrus_spdif(ac97);
-}
-
-/*
- * Conexant codecs
- */
-static const struct snd_kcontrol_new snd_ac97_conexant_controls_spdif[1] = {
- AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), AC97_CXR_AUDIO_MISC, 3, 1, 0),
-};
-
-static int patch_conexant_build_spdif(struct snd_ac97 * ac97)
-{
- int err;
-
- /* con mask, pro mask, default */
- if ((err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3)) < 0)
- return err;
- /* switch */
- if ((err = patch_build_controls(ac97, &snd_ac97_conexant_controls_spdif[0], 1)) < 0)
- return err;
- /* set default PCM S/PDIF params */
- /* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */
- snd_ac97_write_cache(ac97, AC97_CXR_AUDIO_MISC,
- snd_ac97_read(ac97, AC97_CXR_AUDIO_MISC) & ~(AC97_CXR_SPDIFEN|AC97_CXR_COPYRGT|AC97_CXR_SPDIF_MASK));
- return 0;
-}
-
-static const struct snd_ac97_build_ops patch_conexant_ops = {
- .build_spdif = patch_conexant_build_spdif
-};
-
-static int patch_conexant(struct snd_ac97 * ac97)
-{
- ac97->build_ops = &patch_conexant_ops;
- ac97->flags |= AC97_CX_SPDIF;
- ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */
- ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */
- return 0;
-}
-
-static int patch_cx20551(struct snd_ac97 *ac97)
-{
- snd_ac97_update_bits(ac97, 0x5c, 0x01, 0x01);
- return 0;
-}
-
-/*
- * Analog Device AD18xx, AD19xx codecs
- */
-#ifdef CONFIG_PM
-static void ad18xx_resume(struct snd_ac97 *ac97)
-{
- static unsigned short setup_regs[] = {
- AC97_AD_MISC, AC97_AD_SERIAL_CFG, AC97_AD_JACK_SPDIF,
- };
- int i, codec;
-
- for (i = 0; i < (int)ARRAY_SIZE(setup_regs); i++) {
- unsigned short reg = setup_regs[i];
- if (test_bit(reg, ac97->reg_accessed)) {
- snd_ac97_write(ac97, reg, ac97->regs[reg]);
- snd_ac97_read(ac97, reg);
- }
- }
-
- if (! (ac97->flags & AC97_AD_MULTI))
- /* normal restore */
- snd_ac97_restore_status(ac97);
- else {
- /* restore the AD18xx codec configurations */
- for (codec = 0; codec < 3; codec++) {
- if (! ac97->spec.ad18xx.id[codec])
- continue;
- /* select single codec */
- snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
- ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]);
- ac97->bus->ops->write(ac97, AC97_AD_CODEC_CFG, ac97->spec.ad18xx.codec_cfg[codec]);
- }
- /* select all codecs */
- snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
-
- /* restore status */
- for (i = 2; i < 0x7c ; i += 2) {
- if (i == AC97_POWERDOWN || i == AC97_EXTENDED_ID)
- continue;
- if (test_bit(i, ac97->reg_accessed)) {
- /* handle multi codecs for AD18xx */
- if (i == AC97_PCM) {
- for (codec = 0; codec < 3; codec++) {
- if (! ac97->spec.ad18xx.id[codec])
- continue;
- /* select single codec */
- snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
- ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]);
- /* update PCM bits */
- ac97->bus->ops->write(ac97, AC97_PCM, ac97->spec.ad18xx.pcmreg[codec]);
- }
- /* select all codecs */
- snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
- continue;
- } else if (i == AC97_AD_TEST ||
- i == AC97_AD_CODEC_CFG ||
- i == AC97_AD_SERIAL_CFG)
- continue; /* ignore */
- }
- snd_ac97_write(ac97, i, ac97->regs[i]);
- snd_ac97_read(ac97, i);
- }
- }
-
- snd_ac97_restore_iec958(ac97);
-}
-
-static void ad1888_resume(struct snd_ac97 *ac97)
-{
- ad18xx_resume(ac97);
- snd_ac97_write_cache(ac97, AC97_CODEC_CLASS_REV, 0x8080);
-}
-
-#endif
-
-static const struct snd_ac97_res_table ad1819_restbl[] = {
- { AC97_PHONE, 0x9f1f },
- { AC97_MIC, 0x9f1f },
- { AC97_LINE, 0x9f1f },
- { AC97_CD, 0x9f1f },
- { AC97_VIDEO, 0x9f1f },
- { AC97_AUX, 0x9f1f },
- { AC97_PCM, 0x9f1f },
- { } /* terminator */
-};
-
-static int patch_ad1819(struct snd_ac97 * ac97)
-{
- unsigned short scfg;
-
- // patch for Analog Devices
- scfg = snd_ac97_read(ac97, AC97_AD_SERIAL_CFG);
- snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, scfg | 0x7000); /* select all codecs */
- ac97->res_table = ad1819_restbl;
- return 0;
-}
-
-static unsigned short patch_ad1881_unchained(struct snd_ac97 * ac97, int idx, unsigned short mask)
-{
- unsigned short val;
-
- // test for unchained codec
- snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, mask);
- snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0000); /* ID0C, ID1C, SDIE = off */
- val = snd_ac97_read(ac97, AC97_VENDOR_ID2);
- if ((val & 0xff40) != 0x5340)
- return 0;
- ac97->spec.ad18xx.unchained[idx] = mask;
- ac97->spec.ad18xx.id[idx] = val;
- ac97->spec.ad18xx.codec_cfg[idx] = 0x0000;
- return mask;
-}
-
-static int patch_ad1881_chained1(struct snd_ac97 * ac97, int idx, unsigned short codec_bits)
-{
- static int cfg_bits[3] = { 1<<12, 1<<14, 1<<13 };
- unsigned short val;
-
- snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, cfg_bits[idx]);
- snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0004); // SDIE
- val = snd_ac97_read(ac97, AC97_VENDOR_ID2);
- if ((val & 0xff40) != 0x5340)
- return 0;
- if (codec_bits)
- snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, codec_bits);
- ac97->spec.ad18xx.chained[idx] = cfg_bits[idx];
- ac97->spec.ad18xx.id[idx] = val;
- ac97->spec.ad18xx.codec_cfg[idx] = codec_bits ? codec_bits : 0x0004;
- return 1;
-}
-
-static void patch_ad1881_chained(struct snd_ac97 * ac97, int unchained_idx, int cidx1, int cidx2)
-{
- // already detected?
- if (ac97->spec.ad18xx.unchained[cidx1] || ac97->spec.ad18xx.chained[cidx1])
- cidx1 = -1;
- if (ac97->spec.ad18xx.unchained[cidx2] || ac97->spec.ad18xx.chained[cidx2])
- cidx2 = -1;
- if (cidx1 < 0 && cidx2 < 0)
- return;
- // test for chained codecs
- snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
- ac97->spec.ad18xx.unchained[unchained_idx]);
- snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0002); // ID1C
- ac97->spec.ad18xx.codec_cfg[unchained_idx] = 0x0002;
- if (cidx1 >= 0) {
- if (cidx2 < 0)
- patch_ad1881_chained1(ac97, cidx1, 0);
- else if (patch_ad1881_chained1(ac97, cidx1, 0x0006)) // SDIE | ID1C
- patch_ad1881_chained1(ac97, cidx2, 0);
- else if (patch_ad1881_chained1(ac97, cidx2, 0x0006)) // SDIE | ID1C
- patch_ad1881_chained1(ac97, cidx1, 0);
- } else if (cidx2 >= 0) {
- patch_ad1881_chained1(ac97, cidx2, 0);
- }
-}
-
-static const struct snd_ac97_build_ops patch_ad1881_build_ops = {
-#ifdef CONFIG_PM
- .resume = ad18xx_resume
-#endif
-};
-
-static int patch_ad1881(struct snd_ac97 * ac97)
-{
- static const char cfg_idxs[3][2] = {
- {2, 1},
- {0, 2},
- {0, 1}
- };
-
- // patch for Analog Devices
- unsigned short codecs[3];
- unsigned short val;
- int idx, num;
-
- val = snd_ac97_read(ac97, AC97_AD_SERIAL_CFG);
- snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, val);
- codecs[0] = patch_ad1881_unchained(ac97, 0, (1<<12));
- codecs[1] = patch_ad1881_unchained(ac97, 1, (1<<14));
- codecs[2] = patch_ad1881_unchained(ac97, 2, (1<<13));
-
- if (! (codecs[0] || codecs[1] || codecs[2]))
- goto __end;
-
- for (idx = 0; idx < 3; idx++)
- if (ac97->spec.ad18xx.unchained[idx])
- patch_ad1881_chained(ac97, idx, cfg_idxs[idx][0], cfg_idxs[idx][1]);
-
- if (ac97->spec.ad18xx.id[1]) {
- ac97->flags |= AC97_AD_MULTI;
- ac97->scaps |= AC97_SCAP_SURROUND_DAC;
- }
- if (ac97->spec.ad18xx.id[2]) {
- ac97->flags |= AC97_AD_MULTI;
- ac97->scaps |= AC97_SCAP_CENTER_LFE_DAC;
- }
-
- __end:
- /* select all codecs */
- snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
- /* check if only one codec is present */
- for (idx = num = 0; idx < 3; idx++)
- if (ac97->spec.ad18xx.id[idx])
- num++;
- if (num == 1) {
- /* ok, deselect all ID bits */
- snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0000);
- ac97->spec.ad18xx.codec_cfg[0] =
- ac97->spec.ad18xx.codec_cfg[1] =
- ac97->spec.ad18xx.codec_cfg[2] = 0x0000;
- }
- /* required for AD1886/AD1885 combination */
- ac97->ext_id = snd_ac97_read(ac97, AC97_EXTENDED_ID);
- if (ac97->spec.ad18xx.id[0]) {
- ac97->id &= 0xffff0000;
- ac97->id |= ac97->spec.ad18xx.id[0];
- }
- ac97->build_ops = &patch_ad1881_build_ops;
- return 0;
-}
-
-static const struct snd_kcontrol_new snd_ac97_controls_ad1885[] = {
- AC97_SINGLE("Digital Mono Direct", AC97_AD_MISC, 11, 1, 0),
- /* AC97_SINGLE("Digital Audio Mode", AC97_AD_MISC, 12, 1, 0), */ /* seems problematic */
- AC97_SINGLE("Low Power Mixer", AC97_AD_MISC, 14, 1, 0),
- AC97_SINGLE("Zero Fill DAC", AC97_AD_MISC, 15, 1, 0),
- AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 9, 1, 1), /* inverted */
- AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 8, 1, 1), /* inverted */
-};
-
-static const DECLARE_TLV_DB_SCALE(db_scale_6bit_6db_max, -8850, 150, 0);
-
-static int patch_ad1885_specific(struct snd_ac97 * ac97)
-{
- int err;
-
- if ((err = patch_build_controls(ac97, snd_ac97_controls_ad1885, ARRAY_SIZE(snd_ac97_controls_ad1885))) < 0)
- return err;
- reset_tlv(ac97, "Headphone Playback Volume",
- db_scale_6bit_6db_max);
- return 0;
-}
-
-static const struct snd_ac97_build_ops patch_ad1885_build_ops = {
- .build_specific = &patch_ad1885_specific,
-#ifdef CONFIG_PM
- .resume = ad18xx_resume
-#endif
-};
-
-static int patch_ad1885(struct snd_ac97 * ac97)
-{
- patch_ad1881(ac97);
- /* This is required to deal with the Intel D815EEAL2 */
- /* i.e. Line out is actually headphone out from codec */
-
- /* set default */
- snd_ac97_write_cache(ac97, AC97_AD_MISC, 0x0404);
-
- ac97->build_ops = &patch_ad1885_build_ops;
- return 0;
-}
-
-static int patch_ad1886_specific(struct snd_ac97 * ac97)
-{
- reset_tlv(ac97, "Headphone Playback Volume",
- db_scale_6bit_6db_max);
- return 0;
-}
-
-static const struct snd_ac97_build_ops patch_ad1886_build_ops = {
- .build_specific = &patch_ad1886_specific,
-#ifdef CONFIG_PM
- .resume = ad18xx_resume
-#endif
-};
-
-static int patch_ad1886(struct snd_ac97 * ac97)
-{
- patch_ad1881(ac97);
- /* Presario700 workaround */
- /* for Jack Sense/SPDIF Register misetting causing */
- snd_ac97_write_cache(ac97, AC97_AD_JACK_SPDIF, 0x0010);
- ac97->build_ops = &patch_ad1886_build_ops;
- return 0;
-}
-
-/* MISC bits (AD1888/AD1980/AD1985 register 0x76) */
-#define AC97_AD198X_MBC 0x0003 /* mic boost */
-#define AC97_AD198X_MBC_20 0x0000 /* +20dB */
-#define AC97_AD198X_MBC_10 0x0001 /* +10dB */
-#define AC97_AD198X_MBC_30 0x0002 /* +30dB */
-#define AC97_AD198X_VREFD 0x0004 /* VREF high-Z */
-#define AC97_AD198X_VREFH 0x0008 /* 0=2.25V, 1=3.7V */
-#define AC97_AD198X_VREF_0 0x000c /* 0V (AD1985 only) */
-#define AC97_AD198X_VREF_MASK (AC97_AD198X_VREFH | AC97_AD198X_VREFD)
-#define AC97_AD198X_VREF_SHIFT 2
-#define AC97_AD198X_SRU 0x0010 /* sample rate unlock */
-#define AC97_AD198X_LOSEL 0x0020 /* LINE_OUT amplifiers input select */
-#define AC97_AD198X_2MIC 0x0040 /* 2-channel mic select */
-#define AC97_AD198X_SPRD 0x0080 /* SPREAD enable */
-#define AC97_AD198X_DMIX0 0x0100 /* downmix mode: */
- /* 0 = 6-to-4, 1 = 6-to-2 downmix */
-#define AC97_AD198X_DMIX1 0x0200 /* downmix mode: 1 = enabled */
-#define AC97_AD198X_HPSEL 0x0400 /* headphone amplifier input select */
-#define AC97_AD198X_CLDIS 0x0800 /* center/lfe disable */
-#define AC97_AD198X_LODIS 0x1000 /* LINE_OUT disable */
-#define AC97_AD198X_MSPLT 0x2000 /* mute split */
-#define AC97_AD198X_AC97NC 0x4000 /* AC97 no compatible mode */
-#define AC97_AD198X_DACZ 0x8000 /* DAC zero-fill mode */
-
-/* MISC 1 bits (AD1986 register 0x76) */
-#define AC97_AD1986_MBC 0x0003 /* mic boost */
-#define AC97_AD1986_MBC_20 0x0000 /* +20dB */
-#define AC97_AD1986_MBC_10 0x0001 /* +10dB */
-#define AC97_AD1986_MBC_30 0x0002 /* +30dB */
-#define AC97_AD1986_LISEL0 0x0004 /* LINE_IN select bit 0 */
-#define AC97_AD1986_LISEL1 0x0008 /* LINE_IN select bit 1 */
-#define AC97_AD1986_LISEL_MASK (AC97_AD1986_LISEL1 | AC97_AD1986_LISEL0)
-#define AC97_AD1986_LISEL_LI 0x0000 /* LINE_IN pins as LINE_IN source */
-#define AC97_AD1986_LISEL_SURR 0x0004 /* SURROUND pins as LINE_IN source */
-#define AC97_AD1986_LISEL_MIC 0x0008 /* MIC_1/2 pins as LINE_IN source */
-#define AC97_AD1986_SRU 0x0010 /* sample rate unlock */
-#define AC97_AD1986_SOSEL 0x0020 /* SURROUND_OUT amplifiers input sel */
-#define AC97_AD1986_2MIC 0x0040 /* 2-channel mic select */
-#define AC97_AD1986_SPRD 0x0080 /* SPREAD enable */
-#define AC97_AD1986_DMIX0 0x0100 /* downmix mode: */
- /* 0 = 6-to-4, 1 = 6-to-2 downmix */
-#define AC97_AD1986_DMIX1 0x0200 /* downmix mode: 1 = enabled */
-#define AC97_AD1986_CLDIS 0x0800 /* center/lfe disable */
-#define AC97_AD1986_SODIS 0x1000 /* SURROUND_OUT disable */
-#define AC97_AD1986_MSPLT 0x2000 /* mute split (read only 1) */
-#define AC97_AD1986_AC97NC 0x4000 /* AC97 no compatible mode (r/o 1) */
-#define AC97_AD1986_DACZ 0x8000 /* DAC zero-fill mode */
-
-/* MISC 2 bits (AD1986 register 0x70) */
-#define AC97_AD_MISC2 0x70 /* Misc Control Bits 2 (AD1986) */
-
-#define AC97_AD1986_CVREF0 0x0004 /* C/LFE VREF_OUT 2.25V */
-#define AC97_AD1986_CVREF1 0x0008 /* C/LFE VREF_OUT 0V */
-#define AC97_AD1986_CVREF2 0x0010 /* C/LFE VREF_OUT 3.7V */
-#define AC97_AD1986_CVREF_MASK \
- (AC97_AD1986_CVREF2 | AC97_AD1986_CVREF1 | AC97_AD1986_CVREF0)
-#define AC97_AD1986_JSMAP 0x0020 /* Jack Sense Mapping 1 = alternate */
-#define AC97_AD1986_MMDIS 0x0080 /* Mono Mute Disable */
-#define AC97_AD1986_MVREF0 0x0400 /* MIC VREF_OUT 2.25V */
-#define AC97_AD1986_MVREF1 0x0800 /* MIC VREF_OUT 0V */
-#define AC97_AD1986_MVREF2 0x1000 /* MIC VREF_OUT 3.7V */
-#define AC97_AD1986_MVREF_MASK \
- (AC97_AD1986_MVREF2 | AC97_AD1986_MVREF1 | AC97_AD1986_MVREF0)
-
-/* MISC 3 bits (AD1986 register 0x7a) */
-#define AC97_AD_MISC3 0x7a /* Misc Control Bits 3 (AD1986) */
-
-#define AC97_AD1986_MMIX 0x0004 /* Mic Mix, left/right */
-#define AC97_AD1986_GPO 0x0008 /* General Purpose Out */
-#define AC97_AD1986_LOHPEN 0x0010 /* LINE_OUT headphone drive */
-#define AC97_AD1986_LVREF0 0x0100 /* LINE_OUT VREF_OUT 2.25V */
-#define AC97_AD1986_LVREF1 0x0200 /* LINE_OUT VREF_OUT 0V */
-#define AC97_AD1986_LVREF2 0x0400 /* LINE_OUT VREF_OUT 3.7V */
-#define AC97_AD1986_LVREF_MASK \
- (AC97_AD1986_LVREF2 | AC97_AD1986_LVREF1 | AC97_AD1986_LVREF0)
-#define AC97_AD1986_JSINVA 0x0800 /* Jack Sense Invert SENSE_A */
-#define AC97_AD1986_LOSEL 0x1000 /* LINE_OUT amplifiers input select */
-#define AC97_AD1986_HPSEL0 0x2000 /* Headphone amplifiers */
- /* input select Surround DACs */
-#define AC97_AD1986_HPSEL1 0x4000 /* Headphone amplifiers input */
- /* select C/LFE DACs */
-#define AC97_AD1986_JSINVB 0x8000 /* Jack Sense Invert SENSE_B */
-
-/* Serial Config bits (AD1986 register 0x74) (incomplete) */
-#define AC97_AD1986_OMS0 0x0100 /* Optional Mic Selector bit 0 */
-#define AC97_AD1986_OMS1 0x0200 /* Optional Mic Selector bit 1 */
-#define AC97_AD1986_OMS2 0x0400 /* Optional Mic Selector bit 2 */
-#define AC97_AD1986_OMS_MASK \
- (AC97_AD1986_OMS2 | AC97_AD1986_OMS1 | AC97_AD1986_OMS0)
-#define AC97_AD1986_OMS_M 0x0000 /* MIC_1/2 pins are MIC sources */
-#define AC97_AD1986_OMS_L 0x0100 /* LINE_IN pins are MIC sources */
-#define AC97_AD1986_OMS_C 0x0200 /* Center/LFE pins are MCI sources */
-#define AC97_AD1986_OMS_MC 0x0400 /* Mix of MIC and C/LFE pins */
- /* are MIC sources */
-#define AC97_AD1986_OMS_ML 0x0500 /* MIX of MIC and LINE_IN pins */
- /* are MIC sources */
-#define AC97_AD1986_OMS_LC 0x0600 /* MIX of LINE_IN and C/LFE pins */
- /* are MIC sources */
-#define AC97_AD1986_OMS_MLC 0x0700 /* MIX of MIC, LINE_IN, C/LFE pins */
- /* are MIC sources */
-
-
-static int snd_ac97_ad198x_spdif_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[2] = { "AC-Link", "A/D Converter" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item > 1)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ac97_ad198x_spdif_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- val = ac97->regs[AC97_AD_SERIAL_CFG];
- ucontrol->value.enumerated.item[0] = (val >> 2) & 1;
- return 0;
-}
-
-static int snd_ac97_ad198x_spdif_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- if (ucontrol->value.enumerated.item[0] > 1)
- return -EINVAL;
- val = ucontrol->value.enumerated.item[0] << 2;
- return snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x0004, val);
-}
-
-static const struct snd_kcontrol_new snd_ac97_ad198x_spdif_source = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
- .info = snd_ac97_ad198x_spdif_source_info,
- .get = snd_ac97_ad198x_spdif_source_get,
- .put = snd_ac97_ad198x_spdif_source_put,
-};
-
-static int patch_ad198x_post_spdif(struct snd_ac97 * ac97)
-{
- return patch_build_controls(ac97, &snd_ac97_ad198x_spdif_source, 1);
-}
-
-static const struct snd_kcontrol_new snd_ac97_ad1981x_jack_sense[] = {
- AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 11, 1, 0),
- AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),
-};
-
-/* black list to avoid HP/Line jack-sense controls
- * (SS vendor << 16 | device)
- */
-static unsigned int ad1981_jacks_blacklist[] = {
- 0x10140523, /* Thinkpad R40 */
- 0x10140534, /* Thinkpad X31 */
- 0x10140537, /* Thinkpad T41p */
- 0x1014053e, /* Thinkpad R40e */
- 0x10140554, /* Thinkpad T42p/R50p */
- 0x10140567, /* Thinkpad T43p 2668-G7U */
- 0x10140581, /* Thinkpad X41-2527 */
- 0x10280160, /* Dell Dimension 2400 */
- 0x104380b0, /* Asus A7V8X-MX */
- 0x11790241, /* Toshiba Satellite A-15 S127 */
- 0x1179ff10, /* Toshiba P500 */
- 0x144dc01a, /* Samsung NP-X20C004/SEG */
- 0 /* end */
-};
-
-static int check_list(struct snd_ac97 *ac97, const unsigned int *list)
-{
- u32 subid = ((u32)ac97->subsystem_vendor << 16) | ac97->subsystem_device;
- for (; *list; list++)
- if (*list == subid)
- return 1;
- return 0;
-}
-
-static int patch_ad1981a_specific(struct snd_ac97 * ac97)
-{
- if (check_list(ac97, ad1981_jacks_blacklist))
- return 0;
- return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense,
- ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
-}
-
-static const struct snd_ac97_build_ops patch_ad1981a_build_ops = {
- .build_post_spdif = patch_ad198x_post_spdif,
- .build_specific = patch_ad1981a_specific,
-#ifdef CONFIG_PM
- .resume = ad18xx_resume
-#endif
-};
-
-/* white list to enable HP jack-sense bits
- * (SS vendor << 16 | device)
- */
-static unsigned int ad1981_jacks_whitelist[] = {
- 0x0e11005a, /* HP nc4000/4010 */
- 0x103c0890, /* HP nc6000 */
- 0x103c0938, /* HP nc4220 */
- 0x103c099c, /* HP nx6110 */
- 0x103c0944, /* HP nc6220 */
- 0x103c0934, /* HP nc8220 */
- 0x103c006d, /* HP nx9105 */
- 0x103c300d, /* HP Compaq dc5100 SFF(PT003AW) */
- 0x17340088, /* FSC Scenic-W */
- 0 /* end */
-};
-
-static void check_ad1981_hp_jack_sense(struct snd_ac97 *ac97)
-{
- if (check_list(ac97, ad1981_jacks_whitelist))
- /* enable headphone jack sense */
- snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11);
-}
-
-static int patch_ad1981a(struct snd_ac97 *ac97)
-{
- patch_ad1881(ac97);
- ac97->build_ops = &patch_ad1981a_build_ops;
- snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_MSPLT, AC97_AD198X_MSPLT);
- ac97->flags |= AC97_STEREO_MUTES;
- check_ad1981_hp_jack_sense(ac97);
- return 0;
-}
-
-static const struct snd_kcontrol_new snd_ac97_ad198x_2cmic =
-AC97_SINGLE("Stereo Mic", AC97_AD_MISC, 6, 1, 0);
-
-static int patch_ad1981b_specific(struct snd_ac97 *ac97)
-{
- int err;
-
- if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0)
- return err;
- if (check_list(ac97, ad1981_jacks_blacklist))
- return 0;
- return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense,
- ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
-}
-
-static const struct snd_ac97_build_ops patch_ad1981b_build_ops = {
- .build_post_spdif = patch_ad198x_post_spdif,
- .build_specific = patch_ad1981b_specific,
-#ifdef CONFIG_PM
- .resume = ad18xx_resume
-#endif
-};
-
-static int patch_ad1981b(struct snd_ac97 *ac97)
-{
- patch_ad1881(ac97);
- ac97->build_ops = &patch_ad1981b_build_ops;
- snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_MSPLT, AC97_AD198X_MSPLT);
- ac97->flags |= AC97_STEREO_MUTES;
- check_ad1981_hp_jack_sense(ac97);
- return 0;
-}
-
-#define snd_ac97_ad1888_lohpsel_info snd_ctl_boolean_mono_info
-
-static int snd_ac97_ad1888_lohpsel_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- val = ac97->regs[AC97_AD_MISC];
- ucontrol->value.integer.value[0] = !(val & AC97_AD198X_LOSEL);
- if (ac97->spec.ad18xx.lo_as_master)
- ucontrol->value.integer.value[0] =
- !ucontrol->value.integer.value[0];
- return 0;
-}
-
-static int snd_ac97_ad1888_lohpsel_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- val = !ucontrol->value.integer.value[0];
- if (ac97->spec.ad18xx.lo_as_master)
- val = !val;
- val = val ? (AC97_AD198X_LOSEL | AC97_AD198X_HPSEL) : 0;
- return snd_ac97_update_bits(ac97, AC97_AD_MISC,
- AC97_AD198X_LOSEL | AC97_AD198X_HPSEL, val);
-}
-
-static int snd_ac97_ad1888_downmix_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[3] = {"Off", "6 -> 4", "6 -> 2"};
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item > 2)
- uinfo->value.enumerated.item = 2;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ac97_ad1888_downmix_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- val = ac97->regs[AC97_AD_MISC];
- if (!(val & AC97_AD198X_DMIX1))
- ucontrol->value.enumerated.item[0] = 0;
- else
- ucontrol->value.enumerated.item[0] = 1 + ((val >> 8) & 1);
- return 0;
-}
-
-static int snd_ac97_ad1888_downmix_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- if (ucontrol->value.enumerated.item[0] > 2)
- return -EINVAL;
- if (ucontrol->value.enumerated.item[0] == 0)
- val = 0;
- else
- val = AC97_AD198X_DMIX1 |
- ((ucontrol->value.enumerated.item[0] - 1) << 8);
- return snd_ac97_update_bits(ac97, AC97_AD_MISC,
- AC97_AD198X_DMIX0 | AC97_AD198X_DMIX1, val);
-}
-
-static void ad1888_update_jacks(struct snd_ac97 *ac97)
-{
- unsigned short val = 0;
- /* clear LODIS if shared jack is to be used for Surround out */
- if (!ac97->spec.ad18xx.lo_as_master && is_shared_linein(ac97))
- val |= (1 << 12);
- /* clear CLDIS if shared jack is to be used for C/LFE out */
- if (is_shared_micin(ac97))
- val |= (1 << 11);
- /* shared Line-In */
- snd_ac97_update_bits(ac97, AC97_AD_MISC, (1 << 11) | (1 << 12), val);
-}
-
-static const struct snd_kcontrol_new snd_ac97_ad1888_controls[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Exchange Front/Surround",
- .info = snd_ac97_ad1888_lohpsel_info,
- .get = snd_ac97_ad1888_lohpsel_get,
- .put = snd_ac97_ad1888_lohpsel_put
- },
- AC97_SINGLE("V_REFOUT Enable", AC97_AD_MISC, AC97_AD_VREFD_SHIFT, 1, 1),
- AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2,
- AC97_AD_HPFD_SHIFT, 1, 1),
- AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC, 7, 1, 0),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Downmix",
- .info = snd_ac97_ad1888_downmix_info,
- .get = snd_ac97_ad1888_downmix_get,
- .put = snd_ac97_ad1888_downmix_put
- },
- AC97_SURROUND_JACK_MODE_CTL,
- AC97_CHANNEL_MODE_CTL,
-
- AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0),
- AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),
-};
-
-static int patch_ad1888_specific(struct snd_ac97 *ac97)
-{
- if (!ac97->spec.ad18xx.lo_as_master) {
- /* rename 0x04 as "Master" and 0x02 as "Master Surround" */
- snd_ac97_rename_vol_ctl(ac97, "Master Playback",
- "Master Surround Playback");
- snd_ac97_rename_vol_ctl(ac97, "Headphone Playback",
- "Master Playback");
- }
- return patch_build_controls(ac97, snd_ac97_ad1888_controls, ARRAY_SIZE(snd_ac97_ad1888_controls));
-}
-
-static const struct snd_ac97_build_ops patch_ad1888_build_ops = {
- .build_post_spdif = patch_ad198x_post_spdif,
- .build_specific = patch_ad1888_specific,
-#ifdef CONFIG_PM
- .resume = ad1888_resume,
-#endif
- .update_jacks = ad1888_update_jacks,
-};
-
-static int patch_ad1888(struct snd_ac97 * ac97)
-{
- unsigned short misc;
-
- patch_ad1881(ac97);
- ac97->build_ops = &patch_ad1888_build_ops;
-
- /*
- * LO can be used as a real line-out on some devices,
- * and we need to revert the front/surround mixer switches
- */
- if (ac97->subsystem_vendor == 0x1043 &&
- ac97->subsystem_device == 0x1193) /* ASUS A9T laptop */
- ac97->spec.ad18xx.lo_as_master = 1;
-
- misc = snd_ac97_read(ac97, AC97_AD_MISC);
- /* AD-compatible mode */
- /* Stereo mutes enabled */
- misc |= AC97_AD198X_MSPLT | AC97_AD198X_AC97NC;
- if (!ac97->spec.ad18xx.lo_as_master)
- /* Switch FRONT/SURROUND LINE-OUT/HP-OUT default connection */
- /* it seems that most vendors connect line-out connector to
- * headphone out of AC'97
- */
- misc |= AC97_AD198X_LOSEL | AC97_AD198X_HPSEL;
-
- snd_ac97_write_cache(ac97, AC97_AD_MISC, misc);
- ac97->flags |= AC97_STEREO_MUTES;
- return 0;
-}
-
-static int patch_ad1980_specific(struct snd_ac97 *ac97)
-{
- int err;
-
- if ((err = patch_ad1888_specific(ac97)) < 0)
- return err;
- return patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1);
-}
-
-static const struct snd_ac97_build_ops patch_ad1980_build_ops = {
- .build_post_spdif = patch_ad198x_post_spdif,
- .build_specific = patch_ad1980_specific,
-#ifdef CONFIG_PM
- .resume = ad18xx_resume,
-#endif
- .update_jacks = ad1888_update_jacks,
-};
-
-static int patch_ad1980(struct snd_ac97 * ac97)
-{
- patch_ad1888(ac97);
- ac97->build_ops = &patch_ad1980_build_ops;
- return 0;
-}
-
-static int snd_ac97_ad1985_vrefout_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[4] = {"High-Z", "3.7 V", "2.25 V", "0 V"};
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 4;
- if (uinfo->value.enumerated.item > 3)
- uinfo->value.enumerated.item = 3;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ac97_ad1985_vrefout_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- static const int reg2ctrl[4] = {2, 0, 1, 3};
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned short val;
- val = (ac97->regs[AC97_AD_MISC] & AC97_AD198X_VREF_MASK)
- >> AC97_AD198X_VREF_SHIFT;
- ucontrol->value.enumerated.item[0] = reg2ctrl[val];
- return 0;
-}
-
-static int snd_ac97_ad1985_vrefout_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- static const int ctrl2reg[4] = {1, 2, 0, 3};
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- if (ucontrol->value.enumerated.item[0] > 3)
- return -EINVAL;
- val = ctrl2reg[ucontrol->value.enumerated.item[0]]
- << AC97_AD198X_VREF_SHIFT;
- return snd_ac97_update_bits(ac97, AC97_AD_MISC,
- AC97_AD198X_VREF_MASK, val);
-}
-
-static const struct snd_kcontrol_new snd_ac97_ad1985_controls[] = {
- AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Exchange Front/Surround",
- .info = snd_ac97_ad1888_lohpsel_info,
- .get = snd_ac97_ad1888_lohpsel_get,
- .put = snd_ac97_ad1888_lohpsel_put
- },
- AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2, 12, 1, 1),
- AC97_SINGLE("Spread Front to Surround and Center/LFE",
- AC97_AD_MISC, 7, 1, 0),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Downmix",
- .info = snd_ac97_ad1888_downmix_info,
- .get = snd_ac97_ad1888_downmix_get,
- .put = snd_ac97_ad1888_downmix_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "V_REFOUT",
- .info = snd_ac97_ad1985_vrefout_info,
- .get = snd_ac97_ad1985_vrefout_get,
- .put = snd_ac97_ad1985_vrefout_put
- },
- AC97_SURROUND_JACK_MODE_CTL,
- AC97_CHANNEL_MODE_CTL,
-
- AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0),
- AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),
-};
-
-static void ad1985_update_jacks(struct snd_ac97 *ac97)
-{
- ad1888_update_jacks(ac97);
- /* clear OMS if shared jack is to be used for C/LFE out */
- snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 1 << 9,
- is_shared_micin(ac97) ? 1 << 9 : 0);
-}
-
-static int patch_ad1985_specific(struct snd_ac97 *ac97)
-{
- int err;
-
- /* rename 0x04 as "Master" and 0x02 as "Master Surround" */
- snd_ac97_rename_vol_ctl(ac97, "Master Playback",
- "Master Surround Playback");
- snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback");
-
- if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0)
- return err;
-
- return patch_build_controls(ac97, snd_ac97_ad1985_controls,
- ARRAY_SIZE(snd_ac97_ad1985_controls));
-}
-
-static const struct snd_ac97_build_ops patch_ad1985_build_ops = {
- .build_post_spdif = patch_ad198x_post_spdif,
- .build_specific = patch_ad1985_specific,
-#ifdef CONFIG_PM
- .resume = ad18xx_resume,
-#endif
- .update_jacks = ad1985_update_jacks,
-};
-
-static int patch_ad1985(struct snd_ac97 * ac97)
-{
- unsigned short misc;
-
- patch_ad1881(ac97);
- ac97->build_ops = &patch_ad1985_build_ops;
- misc = snd_ac97_read(ac97, AC97_AD_MISC);
- /* switch front/surround line-out/hp-out */
- /* AD-compatible mode */
- /* Stereo mutes enabled */
- snd_ac97_write_cache(ac97, AC97_AD_MISC, misc |
- AC97_AD198X_LOSEL |
- AC97_AD198X_HPSEL |
- AC97_AD198X_MSPLT |
- AC97_AD198X_AC97NC);
- ac97->flags |= AC97_STEREO_MUTES;
-
- /* update current jack configuration */
- ad1985_update_jacks(ac97);
-
- /* on AD1985 rev. 3, AC'97 revision bits are zero */
- ac97->ext_id = (ac97->ext_id & ~AC97_EI_REV_MASK) | AC97_EI_REV_23;
- return 0;
-}
-
-#define snd_ac97_ad1986_bool_info snd_ctl_boolean_mono_info
-
-static int snd_ac97_ad1986_lososel_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- val = ac97->regs[AC97_AD_MISC3];
- ucontrol->value.integer.value[0] = (val & AC97_AD1986_LOSEL) != 0;
- return 0;
-}
-
-static int snd_ac97_ad1986_lososel_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- int ret0;
- int ret1;
- int sprd = (ac97->regs[AC97_AD_MISC] & AC97_AD1986_SPRD) != 0;
-
- ret0 = snd_ac97_update_bits(ac97, AC97_AD_MISC3, AC97_AD1986_LOSEL,
- ucontrol->value.integer.value[0] != 0
- ? AC97_AD1986_LOSEL : 0);
- if (ret0 < 0)
- return ret0;
-
- /* SOSEL is set to values of "Spread" or "Exchange F/S" controls */
- ret1 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SOSEL,
- (ucontrol->value.integer.value[0] != 0
- || sprd)
- ? AC97_AD1986_SOSEL : 0);
- if (ret1 < 0)
- return ret1;
-
- return (ret0 > 0 || ret1 > 0) ? 1 : 0;
-}
-
-static int snd_ac97_ad1986_spread_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- val = ac97->regs[AC97_AD_MISC];
- ucontrol->value.integer.value[0] = (val & AC97_AD1986_SPRD) != 0;
- return 0;
-}
-
-static int snd_ac97_ad1986_spread_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- int ret0;
- int ret1;
- int sprd = (ac97->regs[AC97_AD_MISC3] & AC97_AD1986_LOSEL) != 0;
-
- ret0 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SPRD,
- ucontrol->value.integer.value[0] != 0
- ? AC97_AD1986_SPRD : 0);
- if (ret0 < 0)
- return ret0;
-
- /* SOSEL is set to values of "Spread" or "Exchange F/S" controls */
- ret1 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SOSEL,
- (ucontrol->value.integer.value[0] != 0
- || sprd)
- ? AC97_AD1986_SOSEL : 0);
- if (ret1 < 0)
- return ret1;
-
- return (ret0 > 0 || ret1 > 0) ? 1 : 0;
-}
-
-static int snd_ac97_ad1986_miclisel_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = ac97->spec.ad18xx.swap_mic_linein;
- return 0;
-}
-
-static int snd_ac97_ad1986_miclisel_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned char swap = ucontrol->value.integer.value[0] != 0;
-
- if (swap != ac97->spec.ad18xx.swap_mic_linein) {
- ac97->spec.ad18xx.swap_mic_linein = swap;
- if (ac97->build_ops->update_jacks)
- ac97->build_ops->update_jacks(ac97);
- return 1;
- }
- return 0;
-}
-
-static int snd_ac97_ad1986_vrefout_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- /* Use MIC_1/2 V_REFOUT as the "get" value */
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned short val;
- unsigned short reg = ac97->regs[AC97_AD_MISC2];
- if ((reg & AC97_AD1986_MVREF0) != 0)
- val = 2;
- else if ((reg & AC97_AD1986_MVREF1) != 0)
- val = 3;
- else if ((reg & AC97_AD1986_MVREF2) != 0)
- val = 1;
- else
- val = 0;
- ucontrol->value.enumerated.item[0] = val;
- return 0;
-}
-
-static int snd_ac97_ad1986_vrefout_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned short cval;
- unsigned short lval;
- unsigned short mval;
- int cret;
- int lret;
- int mret;
-
- switch (ucontrol->value.enumerated.item[0])
- {
- case 0: /* High-Z */
- cval = 0;
- lval = 0;
- mval = 0;
- break;
- case 1: /* 3.7 V */
- cval = AC97_AD1986_CVREF2;
- lval = AC97_AD1986_LVREF2;
- mval = AC97_AD1986_MVREF2;
- break;
- case 2: /* 2.25 V */
- cval = AC97_AD1986_CVREF0;
- lval = AC97_AD1986_LVREF0;
- mval = AC97_AD1986_MVREF0;
- break;
- case 3: /* 0 V */
- cval = AC97_AD1986_CVREF1;
- lval = AC97_AD1986_LVREF1;
- mval = AC97_AD1986_MVREF1;
- break;
- default:
- return -EINVAL;
- }
-
- cret = snd_ac97_update_bits(ac97, AC97_AD_MISC2,
- AC97_AD1986_CVREF_MASK, cval);
- if (cret < 0)
- return cret;
- lret = snd_ac97_update_bits(ac97, AC97_AD_MISC3,
- AC97_AD1986_LVREF_MASK, lval);
- if (lret < 0)
- return lret;
- mret = snd_ac97_update_bits(ac97, AC97_AD_MISC2,
- AC97_AD1986_MVREF_MASK, mval);
- if (mret < 0)
- return mret;
-
- return (cret > 0 || lret > 0 || mret > 0) ? 1 : 0;
-}
-
-static const struct snd_kcontrol_new snd_ac97_ad1986_controls[] = {
- AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Exchange Front/Surround",
- .info = snd_ac97_ad1986_bool_info,
- .get = snd_ac97_ad1986_lososel_get,
- .put = snd_ac97_ad1986_lososel_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Exchange Mic/Line In",
- .info = snd_ac97_ad1986_bool_info,
- .get = snd_ac97_ad1986_miclisel_get,
- .put = snd_ac97_ad1986_miclisel_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Spread Front to Surround and Center/LFE",
- .info = snd_ac97_ad1986_bool_info,
- .get = snd_ac97_ad1986_spread_get,
- .put = snd_ac97_ad1986_spread_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Downmix",
- .info = snd_ac97_ad1888_downmix_info,
- .get = snd_ac97_ad1888_downmix_get,
- .put = snd_ac97_ad1888_downmix_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "V_REFOUT",
- .info = snd_ac97_ad1985_vrefout_info,
- .get = snd_ac97_ad1986_vrefout_get,
- .put = snd_ac97_ad1986_vrefout_put
- },
- AC97_SURROUND_JACK_MODE_CTL,
- AC97_CHANNEL_MODE_CTL,
-
- AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0),
- AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0)
-};
-
-static void ad1986_update_jacks(struct snd_ac97 *ac97)
-{
- unsigned short misc_val = 0;
- unsigned short ser_val;
-
- /* disable SURROUND and CENTER/LFE if not surround mode */
- if (!is_surround_on(ac97))
- misc_val |= AC97_AD1986_SODIS;
- if (!is_clfe_on(ac97))
- misc_val |= AC97_AD1986_CLDIS;
-
- /* select line input (default=LINE_IN, SURROUND or MIC_1/2) */
- if (is_shared_linein(ac97))
- misc_val |= AC97_AD1986_LISEL_SURR;
- else if (ac97->spec.ad18xx.swap_mic_linein != 0)
- misc_val |= AC97_AD1986_LISEL_MIC;
- snd_ac97_update_bits(ac97, AC97_AD_MISC,
- AC97_AD1986_SODIS | AC97_AD1986_CLDIS |
- AC97_AD1986_LISEL_MASK,
- misc_val);
-
- /* select microphone input (MIC_1/2, Center/LFE or LINE_IN) */
- if (is_shared_micin(ac97))
- ser_val = AC97_AD1986_OMS_C;
- else if (ac97->spec.ad18xx.swap_mic_linein != 0)
- ser_val = AC97_AD1986_OMS_L;
- else
- ser_val = AC97_AD1986_OMS_M;
- snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG,
- AC97_AD1986_OMS_MASK,
- ser_val);
-}
-
-static int patch_ad1986_specific(struct snd_ac97 *ac97)
-{
- int err;
-
- if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0)
- return err;
-
- return patch_build_controls(ac97, snd_ac97_ad1986_controls,
- ARRAY_SIZE(snd_ac97_ad1985_controls));
-}
-
-static const struct snd_ac97_build_ops patch_ad1986_build_ops = {
- .build_post_spdif = patch_ad198x_post_spdif,
- .build_specific = patch_ad1986_specific,
-#ifdef CONFIG_PM
- .resume = ad18xx_resume,
-#endif
- .update_jacks = ad1986_update_jacks,
-};
-
-static int patch_ad1986(struct snd_ac97 * ac97)
-{
- patch_ad1881(ac97);
- ac97->build_ops = &patch_ad1986_build_ops;
- ac97->flags |= AC97_STEREO_MUTES;
-
- /* update current jack configuration */
- ad1986_update_jacks(ac97);
-
- return 0;
-}
-
-/*
- * realtek ALC203: use mono-out for pin 37
- */
-static int patch_alc203(struct snd_ac97 *ac97)
-{
- snd_ac97_update_bits(ac97, 0x7a, 0x400, 0x400);
- return 0;
-}
-
-/*
- * realtek ALC65x/850 codecs
- */
-static void alc650_update_jacks(struct snd_ac97 *ac97)
-{
- int shared;
-
- /* shared Line-In / Surround Out */
- shared = is_shared_surrout(ac97);
- snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 9,
- shared ? (1 << 9) : 0);
- /* update shared Mic In / Center/LFE Out */
- shared = is_shared_clfeout(ac97);
- /* disable/enable vref */
- snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12,
- shared ? (1 << 12) : 0);
- /* turn on/off center-on-mic */
- snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 10,
- shared ? (1 << 10) : 0);
- /* GPIO0 high for mic */
- snd_ac97_update_bits(ac97, AC97_ALC650_GPIO_STATUS, 0x100,
- shared ? 0 : 0x100);
-}
-
-static const struct snd_kcontrol_new snd_ac97_controls_alc650[] = {
- AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0),
- AC97_SINGLE("Surround Down Mix", AC97_ALC650_MULTICH, 1, 1, 0),
- AC97_SINGLE("Center/LFE Down Mix", AC97_ALC650_MULTICH, 2, 1, 0),
- AC97_SINGLE("Exchange Center/LFE", AC97_ALC650_MULTICH, 3, 1, 0),
- /* 4: Analog Input To Surround */
- /* 5: Analog Input To Center/LFE */
- /* 6: Independent Master Volume Right */
- /* 7: Independent Master Volume Left */
- /* 8: reserved */
- /* 9: Line-In/Surround share */
- /* 10: Mic/CLFE share */
- /* 11-13: in IEC958 controls */
- AC97_SINGLE("Swap Surround Slot", AC97_ALC650_MULTICH, 14, 1, 0),
-#if 0 /* always set in patch_alc650 */
- AC97_SINGLE("IEC958 Input Clock Enable", AC97_ALC650_CLOCK, 0, 1, 0),
- AC97_SINGLE("IEC958 Input Pin Enable", AC97_ALC650_CLOCK, 1, 1, 0),
- AC97_SINGLE("Surround DAC Switch", AC97_ALC650_SURR_DAC_VOL, 15, 1, 1),
- AC97_DOUBLE("Surround DAC Volume", AC97_ALC650_SURR_DAC_VOL, 8, 0, 31, 1),
- AC97_SINGLE("Center/LFE DAC Switch", AC97_ALC650_LFE_DAC_VOL, 15, 1, 1),
- AC97_DOUBLE("Center/LFE DAC Volume", AC97_ALC650_LFE_DAC_VOL, 8, 0, 31, 1),
-#endif
- AC97_SURROUND_JACK_MODE_CTL,
- AC97_CHANNEL_MODE_CTL,
-};
-
-static const struct snd_kcontrol_new snd_ac97_spdif_controls_alc650[] = {
- AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_ALC650_MULTICH, 11, 1, 0),
- AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH, 12, 1, 0),
- /* disable this controls since it doesn't work as expected */
- /* AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0), */
-};
-
-static const DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_max, -4350, 150, 0);
-
-static int patch_alc650_specific(struct snd_ac97 * ac97)
-{
- int err;
-
- if ((err = patch_build_controls(ac97, snd_ac97_controls_alc650, ARRAY_SIZE(snd_ac97_controls_alc650))) < 0)
- return err;
- if (ac97->ext_id & AC97_EI_SPDIF) {
- if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc650, ARRAY_SIZE(snd_ac97_spdif_controls_alc650))) < 0)
- return err;
- }
- if (ac97->id != AC97_ID_ALC650F)
- reset_tlv(ac97, "Master Playback Volume",
- db_scale_5bit_3db_max);
- return 0;
-}
-
-static const struct snd_ac97_build_ops patch_alc650_ops = {
- .build_specific = patch_alc650_specific,
- .update_jacks = alc650_update_jacks
-};
-
-static int patch_alc650(struct snd_ac97 * ac97)
-{
- unsigned short val;
-
- ac97->build_ops = &patch_alc650_ops;
-
- /* determine the revision */
- val = snd_ac97_read(ac97, AC97_ALC650_REVISION) & 0x3f;
- if (val < 3)
- ac97->id = 0x414c4720; /* Old version */
- else if (val < 0x10)
- ac97->id = 0x414c4721; /* D version */
- else if (val < 0x20)
- ac97->id = 0x414c4722; /* E version */
- else if (val < 0x30)
- ac97->id = 0x414c4723; /* F version */
-
- /* revision E or F */
- /* FIXME: what about revision D ? */
- ac97->spec.dev_flags = (ac97->id == 0x414c4722 ||
- ac97->id == 0x414c4723);
-
- /* enable AC97_ALC650_GPIO_SETUP, AC97_ALC650_CLOCK for R/W */
- snd_ac97_write_cache(ac97, AC97_ALC650_GPIO_STATUS,
- snd_ac97_read(ac97, AC97_ALC650_GPIO_STATUS) | 0x8000);
-
- /* Enable SPDIF-IN only on Rev.E and above */
- val = snd_ac97_read(ac97, AC97_ALC650_CLOCK);
- /* SPDIF IN with pin 47 */
- if (ac97->spec.dev_flags &&
- /* ASUS A6KM requires EAPD */
- ! (ac97->subsystem_vendor == 0x1043 &&
- ac97->subsystem_device == 0x1103))
- val |= 0x03; /* enable */
- else
- val &= ~0x03; /* disable */
- snd_ac97_write_cache(ac97, AC97_ALC650_CLOCK, val);
-
- /* set default: slot 3,4,7,8,6,9
- spdif-in monitor off, analog-spdif off, spdif-in off
- center on mic off, surround on line-in off
- downmix off, duplicate front off
- */
- snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 0);
-
- /* set GPIO0 for mic bias */
- /* GPIO0 pin output, no interrupt, high */
- snd_ac97_write_cache(ac97, AC97_ALC650_GPIO_SETUP,
- snd_ac97_read(ac97, AC97_ALC650_GPIO_SETUP) | 0x01);
- snd_ac97_write_cache(ac97, AC97_ALC650_GPIO_STATUS,
- (snd_ac97_read(ac97, AC97_ALC650_GPIO_STATUS) | 0x100) & ~0x10);
-
- /* full DAC volume */
- snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808);
- snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808);
- return 0;
-}
-
-static void alc655_update_jacks(struct snd_ac97 *ac97)
-{
- int shared;
-
- /* shared Line-In / Surround Out */
- shared = is_shared_surrout(ac97);
- ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 9,
- shared ? (1 << 9) : 0, 0);
- /* update shared Mic In / Center/LFE Out */
- shared = is_shared_clfeout(ac97);
- /* misc control; vrefout disable */
- snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12,
- shared ? (1 << 12) : 0);
- ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 10,
- shared ? (1 << 10) : 0, 0);
-}
-
-static const struct snd_kcontrol_new snd_ac97_controls_alc655[] = {
- AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0),
- AC97_SURROUND_JACK_MODE_CTL,
- AC97_CHANNEL_MODE_CTL,
-};
-
-static int alc655_iec958_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts_655[3] = { "PCM", "Analog In", "IEC958 In" };
- static char *texts_658[4] = { "PCM", "Analog1 In", "Analog2 In", "IEC958 In" };
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = ac97->spec.dev_flags ? 4 : 3;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name,
- ac97->spec.dev_flags ?
- texts_658[uinfo->value.enumerated.item] :
- texts_655[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int alc655_iec958_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- val = ac97->regs[AC97_ALC650_MULTICH];
- val = (val >> 12) & 3;
- if (ac97->spec.dev_flags && val == 3)
- val = 0;
- ucontrol->value.enumerated.item[0] = val;
- return 0;
-}
-
-static int alc655_iec958_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
-
- return ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 3 << 12,
- (unsigned short)ucontrol->value.enumerated.item[0] << 12,
- 0);
-}
-
-static const struct snd_kcontrol_new snd_ac97_spdif_controls_alc655[] = {
- AC97_PAGE_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_ALC650_MULTICH, 11, 1, 0, 0),
- /* disable this controls since it doesn't work as expected */
- /* AC97_PAGE_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 14, 1, 0, 0), */
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
- .info = alc655_iec958_route_info,
- .get = alc655_iec958_route_get,
- .put = alc655_iec958_route_put,
- },
-};
-
-static int patch_alc655_specific(struct snd_ac97 * ac97)
-{
- int err;
-
- if ((err = patch_build_controls(ac97, snd_ac97_controls_alc655, ARRAY_SIZE(snd_ac97_controls_alc655))) < 0)
- return err;
- if (ac97->ext_id & AC97_EI_SPDIF) {
- if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc655, ARRAY_SIZE(snd_ac97_spdif_controls_alc655))) < 0)
- return err;
- }
- return 0;
-}
-
-static const struct snd_ac97_build_ops patch_alc655_ops = {
- .build_specific = patch_alc655_specific,
- .update_jacks = alc655_update_jacks
-};
-
-static int patch_alc655(struct snd_ac97 * ac97)
-{
- unsigned int val;
-
- if (ac97->id == AC97_ID_ALC658) {
- ac97->spec.dev_flags = 1; /* ALC658 */
- if ((snd_ac97_read(ac97, AC97_ALC650_REVISION) & 0x3f) == 2) {
- ac97->id = AC97_ID_ALC658D;
- ac97->spec.dev_flags = 2;
- }
- }
-
- ac97->build_ops = &patch_alc655_ops;
-
- /* assume only page 0 for writing cache */
- snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR);
-
- /* adjust default values */
- val = snd_ac97_read(ac97, 0x7a); /* misc control */
- if (ac97->spec.dev_flags) /* ALC658 */
- val &= ~(1 << 1); /* Pin 47 is spdif input pin */
- else { /* ALC655 */
- if (ac97->subsystem_vendor == 0x1462 &&
- (ac97->subsystem_device == 0x0131 || /* MSI S270 laptop */
- ac97->subsystem_device == 0x0161 || /* LG K1 Express */
- ac97->subsystem_device == 0x0351 || /* MSI L725 laptop */
- ac97->subsystem_device == 0x0471 || /* MSI L720 laptop */
- ac97->subsystem_device == 0x0061)) /* MSI S250 laptop */
- val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */
- else
- val |= (1 << 1); /* Pin 47 is spdif input pin */
- /* this seems missing on some hardwares */
- ac97->ext_id |= AC97_EI_SPDIF;
- }
- val &= ~(1 << 12); /* vref enable */
- snd_ac97_write_cache(ac97, 0x7a, val);
- /* set default: spdif-in enabled,
- spdif-in monitor off, spdif-in PCM off
- center on mic off, surround on line-in off
- duplicate front off
- */
- snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 1<<15);
-
- /* full DAC volume */
- snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808);
- snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808);
-
- /* update undocumented bit... */
- if (ac97->id == AC97_ID_ALC658D)
- snd_ac97_update_bits(ac97, 0x74, 0x0800, 0x0800);
-
- return 0;
-}
-
-
-#define AC97_ALC850_JACK_SELECT 0x76
-#define AC97_ALC850_MISC1 0x7a
-#define AC97_ALC850_MULTICH 0x6a
-
-static void alc850_update_jacks(struct snd_ac97 *ac97)
-{
- int shared;
- int aux_is_back_surround;
-
- /* shared Line-In / Surround Out */
- shared = is_shared_surrout(ac97);
- /* SURR 1kOhm (bit4), Amp (bit5) */
- snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<4)|(1<<5),
- shared ? (1<<5) : (1<<4));
- /* LINE-IN = 0, SURROUND = 2 */
- snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 12,
- shared ? (2<<12) : (0<<12));
- /* update shared Mic In / Center/LFE Out */
- shared = is_shared_clfeout(ac97);
- /* Vref disable (bit12), 1kOhm (bit13) */
- snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<12)|(1<<13),
- shared ? (1<<12) : (1<<13));
- /* MIC-IN = 1, CENTER-LFE = 5 */
- snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 4,
- shared ? (5<<4) : (1<<4));
-
- aux_is_back_surround = alc850_is_aux_back_surround(ac97);
- /* Aux is Back Surround */
- snd_ac97_update_bits(ac97, AC97_ALC850_MULTICH, 1 << 10,
- aux_is_back_surround ? (1<<10) : (0<<10));
-}
-
-static const struct snd_kcontrol_new snd_ac97_controls_alc850[] = {
- AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0),
- AC97_SINGLE("Mic Front Input Switch", AC97_ALC850_JACK_SELECT, 15, 1, 1),
- AC97_SURROUND_JACK_MODE_CTL,
- AC97_CHANNEL_MODE_8CH_CTL,
-};
-
-static int patch_alc850_specific(struct snd_ac97 *ac97)
-{
- int err;
-
- if ((err = patch_build_controls(ac97, snd_ac97_controls_alc850, ARRAY_SIZE(snd_ac97_controls_alc850))) < 0)
- return err;
- if (ac97->ext_id & AC97_EI_SPDIF) {
- if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc655, ARRAY_SIZE(snd_ac97_spdif_controls_alc655))) < 0)
- return err;
- }
- return 0;
-}
-
-static const struct snd_ac97_build_ops patch_alc850_ops = {
- .build_specific = patch_alc850_specific,
- .update_jacks = alc850_update_jacks
-};
-
-static int patch_alc850(struct snd_ac97 *ac97)
-{
- ac97->build_ops = &patch_alc850_ops;
-
- ac97->spec.dev_flags = 0; /* for IEC958 playback route - ALC655 compatible */
- ac97->flags |= AC97_HAS_8CH;
-
- /* assume only page 0 for writing cache */
- snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR);
-
- /* adjust default values */
- /* set default: spdif-in enabled,
- spdif-in monitor off, spdif-in PCM off
- center on mic off, surround on line-in off
- duplicate front off
- NB default bit 10=0 = Aux is Capture, not Back Surround
- */
- snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 1<<15);
- /* SURR_OUT: on, Surr 1kOhm: on, Surr Amp: off, Front 1kOhm: off
- * Front Amp: on, Vref: enable, Center 1kOhm: on, Mix: on
- */
- snd_ac97_write_cache(ac97, 0x7a, (1<<1)|(1<<4)|(0<<5)|(1<<6)|
- (1<<7)|(0<<12)|(1<<13)|(0<<14));
- /* detection UIO2,3: all path floating, UIO3: MIC, Vref2: disable,
- * UIO1: FRONT, Vref3: disable, UIO3: LINE, Front-Mic: mute
- */
- snd_ac97_write_cache(ac97, 0x76, (0<<0)|(0<<2)|(1<<4)|(1<<7)|(2<<8)|
- (1<<11)|(0<<12)|(1<<15));
-
- /* full DAC volume */
- snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808);
- snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808);
- return 0;
-}
-
-static int patch_aztech_azf3328_specific(struct snd_ac97 *ac97)
-{
- struct snd_kcontrol *kctl_3d_center =
- snd_ac97_find_mixer_ctl(ac97, "3D Control - Center");
- struct snd_kcontrol *kctl_3d_depth =
- snd_ac97_find_mixer_ctl(ac97, "3D Control - Depth");
-
- /*
- * 3D register is different from AC97 standard layout
- * (also do some renaming, to resemble Windows driver naming)
- */
- if (kctl_3d_center) {
- kctl_3d_center->private_value =
- AC97_SINGLE_VALUE(AC97_3D_CONTROL, 1, 0x07, 0);
- snd_ac97_rename_vol_ctl(ac97,
- "3D Control - Center", "3D Control - Width"
- );
- }
- if (kctl_3d_depth)
- kctl_3d_depth->private_value =
- AC97_SINGLE_VALUE(AC97_3D_CONTROL, 8, 0x03, 0);
-
- /* Aztech Windows driver calls the
- equivalent control "Modem Playback", thus rename it: */
- snd_ac97_rename_vol_ctl(ac97,
- "Master Mono Playback", "Modem Playback"
- );
- snd_ac97_rename_vol_ctl(ac97,
- "Headphone Playback", "FM Synth Playback"
- );
-
- return 0;
-}
-
-static const struct snd_ac97_build_ops patch_aztech_azf3328_ops = {
- .build_specific = patch_aztech_azf3328_specific
-};
-
-static int patch_aztech_azf3328(struct snd_ac97 *ac97)
-{
- ac97->build_ops = &patch_aztech_azf3328_ops;
- return 0;
-}
-
-/*
- * C-Media CM97xx codecs
- */
-static void cm9738_update_jacks(struct snd_ac97 *ac97)
-{
- /* shared Line-In / Surround Out */
- snd_ac97_update_bits(ac97, AC97_CM9738_VENDOR_CTRL, 1 << 10,
- is_shared_surrout(ac97) ? (1 << 10) : 0);
-}
-
-static const struct snd_kcontrol_new snd_ac97_cm9738_controls[] = {
- AC97_SINGLE("Duplicate Front", AC97_CM9738_VENDOR_CTRL, 13, 1, 0),
- AC97_SURROUND_JACK_MODE_CTL,
- AC97_CHANNEL_MODE_4CH_CTL,
-};
-
-static int patch_cm9738_specific(struct snd_ac97 * ac97)
-{
- return patch_build_controls(ac97, snd_ac97_cm9738_controls, ARRAY_SIZE(snd_ac97_cm9738_controls));
-}
-
-static const struct snd_ac97_build_ops patch_cm9738_ops = {
- .build_specific = patch_cm9738_specific,
- .update_jacks = cm9738_update_jacks
-};
-
-static int patch_cm9738(struct snd_ac97 * ac97)
-{
- ac97->build_ops = &patch_cm9738_ops;
- /* FIXME: can anyone confirm below? */
- /* CM9738 has no PCM volume although the register reacts */
- ac97->flags |= AC97_HAS_NO_PCM_VOL;
- snd_ac97_write_cache(ac97, AC97_PCM, 0x8000);
-
- return 0;
-}
-
-static int snd_ac97_cmedia_spdif_playback_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = { "Analog", "Digital" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item > 1)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ac97_cmedia_spdif_playback_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- val = ac97->regs[AC97_CM9739_SPDIF_CTRL];
- ucontrol->value.enumerated.item[0] = (val >> 1) & 0x01;
- return 0;
-}
-
-static int snd_ac97_cmedia_spdif_playback_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
-
- return snd_ac97_update_bits(ac97, AC97_CM9739_SPDIF_CTRL,
- 0x01 << 1,
- (ucontrol->value.enumerated.item[0] & 0x01) << 1);
-}
-
-static const struct snd_kcontrol_new snd_ac97_cm9739_controls_spdif[] = {
- /* BIT 0: SPDI_EN - always true */
- { /* BIT 1: SPDIFS */
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
- .info = snd_ac97_cmedia_spdif_playback_source_info,
- .get = snd_ac97_cmedia_spdif_playback_source_get,
- .put = snd_ac97_cmedia_spdif_playback_source_put,
- },
- /* BIT 2: IG_SPIV */
- AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Valid Switch", AC97_CM9739_SPDIF_CTRL, 2, 1, 0),
- /* BIT 3: SPI2F */
- AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Monitor", AC97_CM9739_SPDIF_CTRL, 3, 1, 0),
- /* BIT 4: SPI2SDI */
- AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_CM9739_SPDIF_CTRL, 4, 1, 0),
- /* BIT 8: SPD32 - 32bit SPDIF - not supported yet */
-};
-
-static void cm9739_update_jacks(struct snd_ac97 *ac97)
-{
- /* shared Line-In / Surround Out */
- snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 1 << 10,
- is_shared_surrout(ac97) ? (1 << 10) : 0);
- /* shared Mic In / Center/LFE Out **/
- snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x3000,
- is_shared_clfeout(ac97) ? 0x1000 : 0x2000);
-}
-
-static const struct snd_kcontrol_new snd_ac97_cm9739_controls[] = {
- AC97_SURROUND_JACK_MODE_CTL,
- AC97_CHANNEL_MODE_CTL,
-};
-
-static int patch_cm9739_specific(struct snd_ac97 * ac97)
-{
- return patch_build_controls(ac97, snd_ac97_cm9739_controls, ARRAY_SIZE(snd_ac97_cm9739_controls));
-}
-
-static int patch_cm9739_post_spdif(struct snd_ac97 * ac97)
-{
- return patch_build_controls(ac97, snd_ac97_cm9739_controls_spdif, ARRAY_SIZE(snd_ac97_cm9739_controls_spdif));
-}
-
-static const struct snd_ac97_build_ops patch_cm9739_ops = {
- .build_specific = patch_cm9739_specific,
- .build_post_spdif = patch_cm9739_post_spdif,
- .update_jacks = cm9739_update_jacks
-};
-
-static int patch_cm9739(struct snd_ac97 * ac97)
-{
- unsigned short val;
-
- ac97->build_ops = &patch_cm9739_ops;
-
- /* CM9739/A has no Master and PCM volume although the register reacts */
- ac97->flags |= AC97_HAS_NO_MASTER_VOL | AC97_HAS_NO_PCM_VOL;
- snd_ac97_write_cache(ac97, AC97_MASTER, 0x8000);
- snd_ac97_write_cache(ac97, AC97_PCM, 0x8000);
-
- /* check spdif */
- val = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
- if (val & AC97_EA_SPCV) {
- /* enable spdif in */
- snd_ac97_write_cache(ac97, AC97_CM9739_SPDIF_CTRL,
- snd_ac97_read(ac97, AC97_CM9739_SPDIF_CTRL) | 0x01);
- ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */
- } else {
- ac97->ext_id &= ~AC97_EI_SPDIF; /* disable extended-id */
- ac97->rates[AC97_RATES_SPDIF] = 0;
- }
-
- /* set-up multi channel */
- /* bit 14: 0 = SPDIF, 1 = EAPD */
- /* bit 13: enable internal vref output for mic */
- /* bit 12: disable center/lfe (swithable) */
- /* bit 10: disable surround/line (switchable) */
- /* bit 9: mix 2 surround off */
- /* bit 4: undocumented; 0 mutes the CM9739A, which defaults to 1 */
- /* bit 3: undocumented; surround? */
- /* bit 0: dB */
- val = snd_ac97_read(ac97, AC97_CM9739_MULTI_CHAN) & (1 << 4);
- val |= (1 << 3);
- val |= (1 << 13);
- if (! (ac97->ext_id & AC97_EI_SPDIF))
- val |= (1 << 14);
- snd_ac97_write_cache(ac97, AC97_CM9739_MULTI_CHAN, val);
-
- /* FIXME: set up GPIO */
- snd_ac97_write_cache(ac97, 0x70, 0x0100);
- snd_ac97_write_cache(ac97, 0x72, 0x0020);
- /* Special exception for ASUS W1000/CMI9739. It does not have an SPDIF in. */
- if (ac97->pci &&
- ac97->subsystem_vendor == 0x1043 &&
- ac97->subsystem_device == 0x1843) {
- snd_ac97_write_cache(ac97, AC97_CM9739_SPDIF_CTRL,
- snd_ac97_read(ac97, AC97_CM9739_SPDIF_CTRL) & ~0x01);
- snd_ac97_write_cache(ac97, AC97_CM9739_MULTI_CHAN,
- snd_ac97_read(ac97, AC97_CM9739_MULTI_CHAN) | (1 << 14));
- }
-
- return 0;
-}
-
-#define AC97_CM9761_MULTI_CHAN 0x64
-#define AC97_CM9761_FUNC 0x66
-#define AC97_CM9761_SPDIF_CTRL 0x6c
-
-static void cm9761_update_jacks(struct snd_ac97 *ac97)
-{
- /* FIXME: check the bits for each model
- * model 83 is confirmed to work
- */
- static unsigned short surr_on[3][2] = {
- { 0x0008, 0x0000 }, /* 9761-78 & 82 */
- { 0x0000, 0x0008 }, /* 9761-82 rev.B */
- { 0x0000, 0x0008 }, /* 9761-83 */
- };
- static unsigned short clfe_on[3][2] = {
- { 0x0000, 0x1000 }, /* 9761-78 & 82 */
- { 0x1000, 0x0000 }, /* 9761-82 rev.B */
- { 0x0000, 0x1000 }, /* 9761-83 */
- };
- static unsigned short surr_shared[3][2] = {
- { 0x0000, 0x0400 }, /* 9761-78 & 82 */
- { 0x0000, 0x0400 }, /* 9761-82 rev.B */
- { 0x0000, 0x0400 }, /* 9761-83 */
- };
- static unsigned short clfe_shared[3][2] = {
- { 0x2000, 0x0880 }, /* 9761-78 & 82 */
- { 0x0000, 0x2880 }, /* 9761-82 rev.B */
- { 0x2000, 0x0800 }, /* 9761-83 */
- };
- unsigned short val = 0;
-
- val |= surr_on[ac97->spec.dev_flags][is_surround_on(ac97)];
- val |= clfe_on[ac97->spec.dev_flags][is_clfe_on(ac97)];
- val |= surr_shared[ac97->spec.dev_flags][is_shared_surrout(ac97)];
- val |= clfe_shared[ac97->spec.dev_flags][is_shared_clfeout(ac97)];
-
- snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3c88, val);
-}
-
-static const struct snd_kcontrol_new snd_ac97_cm9761_controls[] = {
- AC97_SURROUND_JACK_MODE_CTL,
- AC97_CHANNEL_MODE_CTL,
-};
-
-static int cm9761_spdif_out_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = { "AC-Link", "ADC", "SPDIF-In" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item > 2)
- uinfo->value.enumerated.item = 2;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int cm9761_spdif_out_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
-
- if (ac97->regs[AC97_CM9761_FUNC] & 0x1)
- ucontrol->value.enumerated.item[0] = 2; /* SPDIF-loopback */
- else if (ac97->regs[AC97_CM9761_SPDIF_CTRL] & 0x2)
- ucontrol->value.enumerated.item[0] = 1; /* ADC loopback */
- else
- ucontrol->value.enumerated.item[0] = 0; /* AC-link */
- return 0;
-}
-
-static int cm9761_spdif_out_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
-
- if (ucontrol->value.enumerated.item[0] == 2)
- return snd_ac97_update_bits(ac97, AC97_CM9761_FUNC, 0x1, 0x1);
- snd_ac97_update_bits(ac97, AC97_CM9761_FUNC, 0x1, 0);
- return snd_ac97_update_bits(ac97, AC97_CM9761_SPDIF_CTRL, 0x2,
- ucontrol->value.enumerated.item[0] == 1 ? 0x2 : 0);
-}
-
-static const char *cm9761_dac_clock[] = { "AC-Link", "SPDIF-In", "Both" };
-static const struct ac97_enum cm9761_dac_clock_enum =
- AC97_ENUM_SINGLE(AC97_CM9761_SPDIF_CTRL, 9, 3, cm9761_dac_clock);
-
-static const struct snd_kcontrol_new snd_ac97_cm9761_controls_spdif[] = {
- { /* BIT 1: SPDIFS */
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
- .info = cm9761_spdif_out_source_info,
- .get = cm9761_spdif_out_source_get,
- .put = cm9761_spdif_out_source_put,
- },
- /* BIT 2: IG_SPIV */
- AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Valid Switch", AC97_CM9761_SPDIF_CTRL, 2, 1, 0),
- /* BIT 3: SPI2F */
- AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Monitor", AC97_CM9761_SPDIF_CTRL, 3, 1, 0),
- /* BIT 4: SPI2SDI */
- AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_CM9761_SPDIF_CTRL, 4, 1, 0),
- /* BIT 9-10: DAC_CTL */
- AC97_ENUM("DAC Clock Source", cm9761_dac_clock_enum),
-};
-
-static int patch_cm9761_post_spdif(struct snd_ac97 * ac97)
-{
- return patch_build_controls(ac97, snd_ac97_cm9761_controls_spdif, ARRAY_SIZE(snd_ac97_cm9761_controls_spdif));
-}
-
-static int patch_cm9761_specific(struct snd_ac97 * ac97)
-{
- return patch_build_controls(ac97, snd_ac97_cm9761_controls, ARRAY_SIZE(snd_ac97_cm9761_controls));
-}
-
-static const struct snd_ac97_build_ops patch_cm9761_ops = {
- .build_specific = patch_cm9761_specific,
- .build_post_spdif = patch_cm9761_post_spdif,
- .update_jacks = cm9761_update_jacks
-};
-
-static int patch_cm9761(struct snd_ac97 *ac97)
-{
- unsigned short val;
-
- /* CM9761 has no PCM volume although the register reacts */
- /* Master volume seems to have _some_ influence on the analog
- * input sounds
- */
- ac97->flags |= /*AC97_HAS_NO_MASTER_VOL |*/ AC97_HAS_NO_PCM_VOL;
- snd_ac97_write_cache(ac97, AC97_MASTER, 0x8808);
- snd_ac97_write_cache(ac97, AC97_PCM, 0x8808);
-
- ac97->spec.dev_flags = 0; /* 1 = model 82 revision B, 2 = model 83 */
- if (ac97->id == AC97_ID_CM9761_82) {
- unsigned short tmp;
- /* check page 1, reg 0x60 */
- val = snd_ac97_read(ac97, AC97_INT_PAGING);
- snd_ac97_write_cache(ac97, AC97_INT_PAGING, (val & ~0x0f) | 0x01);
- tmp = snd_ac97_read(ac97, 0x60);
- ac97->spec.dev_flags = tmp & 1; /* revision B? */
- snd_ac97_write_cache(ac97, AC97_INT_PAGING, val);
- } else if (ac97->id == AC97_ID_CM9761_83)
- ac97->spec.dev_flags = 2;
-
- ac97->build_ops = &patch_cm9761_ops;
-
- /* enable spdif */
- /* force the SPDIF bit in ext_id - codec doesn't set this bit! */
- ac97->ext_id |= AC97_EI_SPDIF;
- /* to be sure: we overwrite the ext status bits */
- snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, 0x05c0);
- /* Don't set 0x0200 here. This results in the silent analog output */
- snd_ac97_write_cache(ac97, AC97_CM9761_SPDIF_CTRL, 0x0001); /* enable spdif-in */
- ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */
-
- /* set-up multi channel */
- /* bit 15: pc master beep off
- * bit 14: pin47 = EAPD/SPDIF
- * bit 13: vref ctl [= cm9739]
- * bit 12: CLFE control (reverted on rev B)
- * bit 11: Mic/center share (reverted on rev B)
- * bit 10: suddound/line share
- * bit 9: Analog-in mix -> surround
- * bit 8: Analog-in mix -> CLFE
- * bit 7: Mic/LFE share (mic/center/lfe)
- * bit 5: vref select (9761A)
- * bit 4: front control
- * bit 3: surround control (revereted with rev B)
- * bit 2: front mic
- * bit 1: stereo mic
- * bit 0: mic boost level (0=20dB, 1=30dB)
- */
-
-#if 0
- if (ac97->spec.dev_flags)
- val = 0x0214;
- else
- val = 0x321c;
-#endif
- val = snd_ac97_read(ac97, AC97_CM9761_MULTI_CHAN);
- val |= (1 << 4); /* front on */
- snd_ac97_write_cache(ac97, AC97_CM9761_MULTI_CHAN, val);
-
- /* FIXME: set up GPIO */
- snd_ac97_write_cache(ac97, 0x70, 0x0100);
- snd_ac97_write_cache(ac97, 0x72, 0x0020);
-
- return 0;
-}
-
-#define AC97_CM9780_SIDE 0x60
-#define AC97_CM9780_JACK 0x62
-#define AC97_CM9780_MIXER 0x64
-#define AC97_CM9780_MULTI_CHAN 0x66
-#define AC97_CM9780_SPDIF 0x6c
-
-static const char *cm9780_ch_select[] = { "Front", "Side", "Center/LFE", "Rear" };
-static const struct ac97_enum cm9780_ch_select_enum =
- AC97_ENUM_SINGLE(AC97_CM9780_MULTI_CHAN, 6, 4, cm9780_ch_select);
-static const struct snd_kcontrol_new cm9780_controls[] = {
- AC97_DOUBLE("Side Playback Switch", AC97_CM9780_SIDE, 15, 7, 1, 1),
- AC97_DOUBLE("Side Playback Volume", AC97_CM9780_SIDE, 8, 0, 31, 0),
- AC97_ENUM("Side Playback Route", cm9780_ch_select_enum),
-};
-
-static int patch_cm9780_specific(struct snd_ac97 *ac97)
-{
- return patch_build_controls(ac97, cm9780_controls, ARRAY_SIZE(cm9780_controls));
-}
-
-static const struct snd_ac97_build_ops patch_cm9780_ops = {
- .build_specific = patch_cm9780_specific,
- .build_post_spdif = patch_cm9761_post_spdif /* identical with CM9761 */
-};
-
-static int patch_cm9780(struct snd_ac97 *ac97)
-{
- unsigned short val;
-
- ac97->build_ops = &patch_cm9780_ops;
-
- /* enable spdif */
- if (ac97->ext_id & AC97_EI_SPDIF) {
- ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */
- val = snd_ac97_read(ac97, AC97_CM9780_SPDIF);
- val |= 0x1; /* SPDI_EN */
- snd_ac97_write_cache(ac97, AC97_CM9780_SPDIF, val);
- }
-
- return 0;
-}
-
-/*
- * VIA VT1616 codec
- */
-static const struct snd_kcontrol_new snd_ac97_controls_vt1616[] = {
-AC97_SINGLE("DC Offset removal", 0x5a, 10, 1, 0),
-AC97_SINGLE("Alternate Level to Surround Out", 0x5a, 15, 1, 0),
-AC97_SINGLE("Downmix LFE and Center to Front", 0x5a, 12, 1, 0),
-AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0),
-};
-
-static const char *slave_vols_vt1616[] = {
- "Front Playback Volume",
- "Surround Playback Volume",
- "Center Playback Volume",
- "LFE Playback Volume",
- NULL
-};
-
-static const char *slave_sws_vt1616[] = {
- "Front Playback Switch",
- "Surround Playback Switch",
- "Center Playback Switch",
- "LFE Playback Switch",
- NULL
-};
-
-/* find a mixer control element with the given name */
-static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97,
- const char *name)
-{
- struct snd_ctl_elem_id id;
- memset(&id, 0, sizeof(id));
- id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(id.name, name);
- return snd_ctl_find_id(ac97->bus->card, &id);
-}
-
-/* create a virtual master control and add slaves */
-static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name,
- const unsigned int *tlv, const char **slaves)
-{
- struct snd_kcontrol *kctl;
- const char **s;
- int err;
-
- kctl = snd_ctl_make_virtual_master(name, tlv);
- if (!kctl)
- return -ENOMEM;
- err = snd_ctl_add(ac97->bus->card, kctl);
- if (err < 0)
- return err;
-
- for (s = slaves; *s; s++) {
- struct snd_kcontrol *sctl;
-
- sctl = snd_ac97_find_mixer_ctl(ac97, *s);
- if (!sctl) {
- snd_printdd("Cannot find slave %s, skipped\n", *s);
- continue;
- }
- err = snd_ctl_add_slave(kctl, sctl);
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-static int patch_vt1616_specific(struct snd_ac97 * ac97)
-{
- struct snd_kcontrol *kctl;
- int err;
-
- if (snd_ac97_try_bit(ac97, 0x5a, 9))
- if ((err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[0], 1)) < 0)
- return err;
- if ((err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[1], ARRAY_SIZE(snd_ac97_controls_vt1616) - 1)) < 0)
- return err;
-
- /* There is already a misnamed master switch. Rename it. */
- kctl = snd_ac97_find_mixer_ctl(ac97, "Master Playback Volume");
- if (!kctl)
- return -EINVAL;
-
- snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Front Playback");
-
- err = snd_ac97_add_vmaster(ac97, "Master Playback Volume",
- kctl->tlv.p, slave_vols_vt1616);
- if (err < 0)
- return err;
-
- err = snd_ac97_add_vmaster(ac97, "Master Playback Switch",
- NULL, slave_sws_vt1616);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static const struct snd_ac97_build_ops patch_vt1616_ops = {
- .build_specific = patch_vt1616_specific
-};
-
-static int patch_vt1616(struct snd_ac97 * ac97)
-{
- ac97->build_ops = &patch_vt1616_ops;
- return 0;
-}
-
-/*
- * VT1617A codec
- */
-
-/*
- * unfortunately, the vt1617a stashes the twiddlers required for
- * noodling the i/o jacks on 2 different regs. that means that we can't
- * use the easy way provided by AC97_ENUM_DOUBLE() we have to write
- * are own funcs.
- *
- * NB: this is absolutely and utterly different from the vt1618. dunno
- * about the 1616.
- */
-
-/* copied from ac97_surround_jack_mode_info() */
-static int snd_ac97_vt1617a_smart51_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- /* ordering in this list reflects vt1617a docs for Reg 20 and
- * 7a and Table 6 that lays out the matrix NB WRT Table6: SM51
- * is SM51EN *AND* it's Bit14, not Bit15 so the table is very
- * counter-intuitive */
-
- static const char* texts[] = { "LineIn Mic1", "LineIn Mic1 Mic3",
- "Surr LFE/C Mic3", "LineIn LFE/C Mic3",
- "LineIn Mic2", "LineIn Mic2 Mic1",
- "Surr LFE Mic1", "Surr LFE Mic1 Mic2"};
- return ac97_enum_text_info(kcontrol, uinfo, texts, 8);
-}
-
-static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ushort usSM51, usMS;
-
- struct snd_ac97 *pac97;
-
- pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */
-
- /* grab our desired bits, then mash them together in a manner
- * consistent with Table 6 on page 17 in the 1617a docs */
-
- usSM51 = snd_ac97_read(pac97, 0x7a) >> 14;
- usMS = snd_ac97_read(pac97, 0x20) >> 8;
-
- ucontrol->value.enumerated.item[0] = (usSM51 << 1) + usMS;
-
- return 0;
-}
-
-static int snd_ac97_vt1617a_smart51_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ushort usSM51, usMS, usReg;
-
- struct snd_ac97 *pac97;
-
- pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */
-
- usSM51 = ucontrol->value.enumerated.item[0] >> 1;
- usMS = ucontrol->value.enumerated.item[0] & 1;
-
- /* push our values into the register - consider that things will be left
- * in a funky state if the write fails */
-
- usReg = snd_ac97_read(pac97, 0x7a);
- snd_ac97_write_cache(pac97, 0x7a, (usReg & 0x3FFF) + (usSM51 << 14));
- usReg = snd_ac97_read(pac97, 0x20);
- snd_ac97_write_cache(pac97, 0x20, (usReg & 0xFEFF) + (usMS << 8));
-
- return 0;
-}
-
-static const struct snd_kcontrol_new snd_ac97_controls_vt1617a[] = {
-
- AC97_SINGLE("Center/LFE Exchange", 0x5a, 8, 1, 0),
- /*
- * These are used to enable/disable surround sound on motherboards
- * that have 3 bidirectional analog jacks
- */
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Smart 5.1 Select",
- .info = snd_ac97_vt1617a_smart51_info,
- .get = snd_ac97_vt1617a_smart51_get,
- .put = snd_ac97_vt1617a_smart51_put,
- },
-};
-
-static int patch_vt1617a(struct snd_ac97 * ac97)
-{
- int err = 0;
- int val;
-
- /* we choose to not fail out at this point, but we tell the
- caller when we return */
-
- err = patch_build_controls(ac97, &snd_ac97_controls_vt1617a[0],
- ARRAY_SIZE(snd_ac97_controls_vt1617a));
-
- /* bring analog power consumption to normal by turning off the
- * headphone amplifier, like WinXP driver for EPIA SP
- */
- /* We need to check the bit before writing it.
- * On some (many?) hardwares, setting bit actually clears it!
- */
- val = snd_ac97_read(ac97, 0x5c);
- if (!(val & 0x20))
- snd_ac97_write_cache(ac97, 0x5c, 0x20);
-
- ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */
- ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
- ac97->build_ops = &patch_vt1616_ops;
-
- return err;
-}
-
-/* VIA VT1618 8 CHANNEL AC97 CODEC
- *
- * VIA implements 'Smart 5.1' completely differently on the 1618 than
- * it does on the 1617a. awesome! They seem to have sourced this
- * particular revision of the technology from somebody else, it's
- * called Universal Audio Jack and it shows up on some other folk's chips
- * as well.
- *
- * ordering in this list reflects vt1618 docs for Reg 60h and
- * the block diagram, DACs are as follows:
- *
- * OUT_O -> Front,
- * OUT_1 -> Surround,
- * OUT_2 -> C/LFE
- *
- * Unlike the 1617a, each OUT has a consistent set of mappings
- * for all bitpatterns other than 00:
- *
- * 01 Unmixed Output
- * 10 Line In
- * 11 Mic In
- *
- * Special Case of 00:
- *
- * OUT_0 Mixed Output
- * OUT_1 Reserved
- * OUT_2 Reserved
- *
- * I have no idea what the hell Reserved does, but on an MSI
- * CN700T, i have to set it to get 5.1 output - YMMV, bad
- * shit may happen.
- *
- * If other chips use Universal Audio Jack, then this code might be applicable
- * to them.
- */
-
-struct vt1618_uaj_item {
- unsigned short mask;
- unsigned short shift;
- const char *items[4];
-};
-
-/* This list reflects the vt1618 docs for Vendor Defined Register 0x60. */
-
-static struct vt1618_uaj_item vt1618_uaj[3] = {
- {
- /* speaker jack */
- .mask = 0x03,
- .shift = 0,
- .items = {
- "Speaker Out", "DAC Unmixed Out", "Line In", "Mic In"
- }
- },
- {
- /* line jack */
- .mask = 0x0c,
- .shift = 2,
- .items = {
- "Surround Out", "DAC Unmixed Out", "Line In", "Mic In"
- }
- },
- {
- /* mic jack */
- .mask = 0x30,
- .shift = 4,
- .items = {
- "Center LFE Out", "DAC Unmixed Out", "Line In", "Mic In"
- },
- },
-};
-
-static int snd_ac97_vt1618_UAJ_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- return ac97_enum_text_info(kcontrol, uinfo,
- vt1618_uaj[kcontrol->private_value].items,
- 4);
-}
-
-/* All of the vt1618 Universal Audio Jack twiddlers are on
- * Vendor Defined Register 0x60, page 0. The bits, and thus
- * the mask, are the only thing that changes
- */
-static int snd_ac97_vt1618_UAJ_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- unsigned short datpag, uaj;
- struct snd_ac97 *pac97 = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&pac97->page_mutex);
-
- datpag = snd_ac97_read(pac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
- snd_ac97_update_bits(pac97, AC97_INT_PAGING, AC97_PAGE_MASK, 0);
-
- uaj = snd_ac97_read(pac97, 0x60) &
- vt1618_uaj[kcontrol->private_value].mask;
-
- snd_ac97_update_bits(pac97, AC97_INT_PAGING, AC97_PAGE_MASK, datpag);
- mutex_unlock(&pac97->page_mutex);
-
- ucontrol->value.enumerated.item[0] = uaj >>
- vt1618_uaj[kcontrol->private_value].shift;
-
- return 0;
-}
-
-static int snd_ac97_vt1618_UAJ_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- return ac97_update_bits_page(snd_kcontrol_chip(kcontrol), 0x60,
- vt1618_uaj[kcontrol->private_value].mask,
- ucontrol->value.enumerated.item[0]<<
- vt1618_uaj[kcontrol->private_value].shift,
- 0);
-}
-
-/* config aux in jack - not found on 3 jack motherboards or soundcards */
-
-static int snd_ac97_vt1618_aux_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static const char *txt_aux[] = {"Aux In", "Back Surr Out"};
-
- return ac97_enum_text_info(kcontrol, uinfo, txt_aux, 2);
-}
-
-static int snd_ac97_vt1618_aux_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.enumerated.item[0] =
- (snd_ac97_read(snd_kcontrol_chip(kcontrol), 0x5c) & 0x0008)>>3;
- return 0;
-}
-
-static int snd_ac97_vt1618_aux_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- /* toggle surround rear dac power */
-
- snd_ac97_update_bits(snd_kcontrol_chip(kcontrol), 0x5c, 0x0008,
- ucontrol->value.enumerated.item[0] << 3);
-
- /* toggle aux in surround rear out jack */
-
- return snd_ac97_update_bits(snd_kcontrol_chip(kcontrol), 0x76, 0x0008,
- ucontrol->value.enumerated.item[0] << 3);
-}
-
-static const struct snd_kcontrol_new snd_ac97_controls_vt1618[] = {
- AC97_SINGLE("Exchange Center/LFE", 0x5a, 8, 1, 0),
- AC97_SINGLE("DC Offset", 0x5a, 10, 1, 0),
- AC97_SINGLE("Soft Mute", 0x5c, 0, 1, 1),
- AC97_SINGLE("Headphone Amp", 0x5c, 5, 1, 1),
- AC97_DOUBLE("Back Surr Volume", 0x5e, 8, 0, 31, 1),
- AC97_SINGLE("Back Surr Switch", 0x5e, 15, 1, 1),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Speaker Jack Mode",
- .info = snd_ac97_vt1618_UAJ_info,
- .get = snd_ac97_vt1618_UAJ_get,
- .put = snd_ac97_vt1618_UAJ_put,
- .private_value = 0
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Line Jack Mode",
- .info = snd_ac97_vt1618_UAJ_info,
- .get = snd_ac97_vt1618_UAJ_get,
- .put = snd_ac97_vt1618_UAJ_put,
- .private_value = 1
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Mic Jack Mode",
- .info = snd_ac97_vt1618_UAJ_info,
- .get = snd_ac97_vt1618_UAJ_get,
- .put = snd_ac97_vt1618_UAJ_put,
- .private_value = 2
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Aux Jack Mode",
- .info = snd_ac97_vt1618_aux_info,
- .get = snd_ac97_vt1618_aux_get,
- .put = snd_ac97_vt1618_aux_put,
- }
-};
-
-static int patch_vt1618(struct snd_ac97 *ac97)
-{
- return patch_build_controls(ac97, snd_ac97_controls_vt1618,
- ARRAY_SIZE(snd_ac97_controls_vt1618));
-}
-
-/*
- */
-static void it2646_update_jacks(struct snd_ac97 *ac97)
-{
- /* shared Line-In / Surround Out */
- snd_ac97_update_bits(ac97, 0x76, 1 << 9,
- is_shared_surrout(ac97) ? (1<<9) : 0);
- /* shared Mic / Center/LFE Out */
- snd_ac97_update_bits(ac97, 0x76, 1 << 10,
- is_shared_clfeout(ac97) ? (1<<10) : 0);
-}
-
-static const struct snd_kcontrol_new snd_ac97_controls_it2646[] = {
- AC97_SURROUND_JACK_MODE_CTL,
- AC97_CHANNEL_MODE_CTL,
-};
-
-static const struct snd_kcontrol_new snd_ac97_spdif_controls_it2646[] = {
- AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0x76, 11, 1, 0),
- AC97_SINGLE("Analog to IEC958 Output", 0x76, 12, 1, 0),
- AC97_SINGLE("IEC958 Input Monitor", 0x76, 13, 1, 0),
-};
-
-static int patch_it2646_specific(struct snd_ac97 * ac97)
-{
- int err;
- if ((err = patch_build_controls(ac97, snd_ac97_controls_it2646, ARRAY_SIZE(snd_ac97_controls_it2646))) < 0)
- return err;
- if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_it2646, ARRAY_SIZE(snd_ac97_spdif_controls_it2646))) < 0)
- return err;
- return 0;
-}
-
-static const struct snd_ac97_build_ops patch_it2646_ops = {
- .build_specific = patch_it2646_specific,
- .update_jacks = it2646_update_jacks
-};
-
-static int patch_it2646(struct snd_ac97 * ac97)
-{
- ac97->build_ops = &patch_it2646_ops;
- /* full DAC volume */
- snd_ac97_write_cache(ac97, 0x5E, 0x0808);
- snd_ac97_write_cache(ac97, 0x7A, 0x0808);
- return 0;
-}
-
-/*
- * Si3036 codec
- */
-
-#define AC97_SI3036_CHIP_ID 0x5a
-#define AC97_SI3036_LINE_CFG 0x5c
-
-static const struct snd_kcontrol_new snd_ac97_controls_si3036[] = {
-AC97_DOUBLE("Modem Speaker Volume", 0x5c, 14, 12, 3, 1)
-};
-
-static int patch_si3036_specific(struct snd_ac97 * ac97)
-{
- int idx, err;
- for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_si3036); idx++)
- if ((err = snd_ctl_add(ac97->bus->card, snd_ctl_new1(&snd_ac97_controls_si3036[idx], ac97))) < 0)
- return err;
- return 0;
-}
-
-static const struct snd_ac97_build_ops patch_si3036_ops = {
- .build_specific = patch_si3036_specific,
-};
-
-static int mpatch_si3036(struct snd_ac97 * ac97)
-{
- ac97->build_ops = &patch_si3036_ops;
- snd_ac97_write_cache(ac97, 0x5c, 0xf210 );
- snd_ac97_write_cache(ac97, 0x68, 0);
- return 0;
-}
-
-/*
- * LM 4550 Codec
- *
- * We use a static resolution table since LM4550 codec cannot be
- * properly autoprobed to determine the resolution via
- * check_volume_resolution().
- */
-
-static struct snd_ac97_res_table lm4550_restbl[] = {
- { AC97_MASTER, 0x1f1f },
- { AC97_HEADPHONE, 0x1f1f },
- { AC97_MASTER_MONO, 0x001f },
- { AC97_PC_BEEP, 0x001f }, /* LSB is ignored */
- { AC97_PHONE, 0x001f },
- { AC97_MIC, 0x001f },
- { AC97_LINE, 0x1f1f },
- { AC97_CD, 0x1f1f },
- { AC97_VIDEO, 0x1f1f },
- { AC97_AUX, 0x1f1f },
- { AC97_PCM, 0x1f1f },
- { AC97_REC_GAIN, 0x0f0f },
- { } /* terminator */
-};
-
-static int patch_lm4550(struct snd_ac97 *ac97)
-{
- ac97->res_table = lm4550_restbl;
- return 0;
-}
-
-/*
- * UCB1400 codec (http://www.semiconductors.philips.com/acrobat_download/datasheets/UCB1400-02.pdf)
- */
-static const struct snd_kcontrol_new snd_ac97_controls_ucb1400[] = {
-/* enable/disable headphone driver which allows direct connection to
- stereo headphone without the use of external DC blocking
- capacitors */
-AC97_SINGLE("Headphone Driver", 0x6a, 6, 1, 0),
-/* Filter used to compensate the DC offset is added in the ADC to remove idle
- tones from the audio band. */
-AC97_SINGLE("DC Filter", 0x6a, 4, 1, 0),
-/* Control smart-low-power mode feature. Allows automatic power down
- of unused blocks in the ADC analog front end and the PLL. */
-AC97_SINGLE("Smart Low Power Mode", 0x6c, 4, 3, 0),
-};
-
-static int patch_ucb1400_specific(struct snd_ac97 * ac97)
-{
- int idx, err;
- for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_ucb1400); idx++)
- if ((err = snd_ctl_add(ac97->bus->card, snd_ctl_new1(&snd_ac97_controls_ucb1400[idx], ac97))) < 0)
- return err;
- return 0;
-}
-
-static const struct snd_ac97_build_ops patch_ucb1400_ops = {
- .build_specific = patch_ucb1400_specific,
-};
-
-static int patch_ucb1400(struct snd_ac97 * ac97)
-{
- ac97->build_ops = &patch_ucb1400_ops;
- /* enable headphone driver and smart low power mode by default */
- snd_ac97_write_cache(ac97, 0x6a, 0x0050);
- snd_ac97_write_cache(ac97, 0x6c, 0x0030);
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/ac97/ac97_patch.h b/ANDROID_3.4.5/sound/pci/ac97/ac97_patch.h
deleted file mode 100644
index 47bf8dfe..00000000
--- a/ANDROID_3.4.5/sound/pci/ac97/ac97_patch.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Universal interface for Audio Codec '97
- *
- * For more details look to AC '97 component specification revision 2.2
- * by Intel Corporation (http://developer.intel.com).
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define AC97_SINGLE_VALUE(reg,shift,mask,invert) \
- ((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | \
- ((invert) << 24))
-#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) \
- (AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26))
-#define AC97_SINGLE(xname, reg, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_ac97_info_volsw, \
- .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
- .private_value = AC97_SINGLE_VALUE(reg, shift, mask, invert) }
-#define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_ac97_info_volsw, \
- .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
- .private_value = AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) }
-#define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
- .info = snd_ac97_info_volsw, \
- .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
- .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) }
-
-/* enum control */
-struct ac97_enum {
- unsigned char reg;
- unsigned char shift_l;
- unsigned char shift_r;
- unsigned short mask;
- const char **texts;
-};
-
-#define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \
-{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
- .mask = xmask, .texts = xtexts }
-#define AC97_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \
- AC97_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts)
-#define AC97_ENUM(xname, xenum) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_ac97_info_enum_double, \
- .get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \
- .private_value = (unsigned long)&xenum }
-
-/* ac97_codec.c */
-static const struct snd_kcontrol_new snd_ac97_controls_3d[];
-static const struct snd_kcontrol_new snd_ac97_controls_spdif[];
-static struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template,
- struct snd_ac97 * ac97);
-static int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo);
-static int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-static int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit);
-static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name,
- const char *suffix);
-static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src,
- const char *dst, const char *suffix);
-static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1,
- const char *s2, const char *suffix);
-static void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src,
- const char *dst);
-#ifdef CONFIG_PM
-static void snd_ac97_restore_status(struct snd_ac97 *ac97);
-static void snd_ac97_restore_iec958(struct snd_ac97 *ac97);
-#endif
-static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo);
-static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-static int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
diff --git a/ANDROID_3.4.5/sound/pci/ac97/ac97_pcm.c b/ANDROID_3.4.5/sound/pci/ac97/ac97_pcm.c
deleted file mode 100644
index f1488fc1..00000000
--- a/ANDROID_3.4.5/sound/pci/ac97/ac97_pcm.c
+++ /dev/null
@@ -1,737 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Universal interface for Audio Codec '97
- *
- * For more details look to AC '97 component specification revision 2.2
- * by Intel Corporation (http://developer.intel.com) and to datasheets
- * for specific codecs.
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-#include <linux/export.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/control.h>
-#include <sound/ac97_codec.h>
-#include <sound/asoundef.h>
-#include "ac97_id.h"
-#include "ac97_local.h"
-
-/*
- * PCM support
- */
-
-static unsigned char rate_reg_tables[2][4][9] = {
-{
- /* standard rates */
- {
- /* 3&4 front, 7&8 rear, 6&9 center/lfe */
- AC97_PCM_FRONT_DAC_RATE, /* slot 3 */
- AC97_PCM_FRONT_DAC_RATE, /* slot 4 */
- 0xff, /* slot 5 */
- AC97_PCM_LFE_DAC_RATE, /* slot 6 */
- AC97_PCM_SURR_DAC_RATE, /* slot 7 */
- AC97_PCM_SURR_DAC_RATE, /* slot 8 */
- AC97_PCM_LFE_DAC_RATE, /* slot 9 */
- 0xff, /* slot 10 */
- 0xff, /* slot 11 */
- },
- {
- /* 7&8 front, 6&9 rear, 10&11 center/lfe */
- 0xff, /* slot 3 */
- 0xff, /* slot 4 */
- 0xff, /* slot 5 */
- AC97_PCM_SURR_DAC_RATE, /* slot 6 */
- AC97_PCM_FRONT_DAC_RATE, /* slot 7 */
- AC97_PCM_FRONT_DAC_RATE, /* slot 8 */
- AC97_PCM_SURR_DAC_RATE, /* slot 9 */
- AC97_PCM_LFE_DAC_RATE, /* slot 10 */
- AC97_PCM_LFE_DAC_RATE, /* slot 11 */
- },
- {
- /* 6&9 front, 10&11 rear, 3&4 center/lfe */
- AC97_PCM_LFE_DAC_RATE, /* slot 3 */
- AC97_PCM_LFE_DAC_RATE, /* slot 4 */
- 0xff, /* slot 5 */
- AC97_PCM_FRONT_DAC_RATE, /* slot 6 */
- 0xff, /* slot 7 */
- 0xff, /* slot 8 */
- AC97_PCM_FRONT_DAC_RATE, /* slot 9 */
- AC97_PCM_SURR_DAC_RATE, /* slot 10 */
- AC97_PCM_SURR_DAC_RATE, /* slot 11 */
- },
- {
- /* 10&11 front, 3&4 rear, 7&8 center/lfe */
- AC97_PCM_SURR_DAC_RATE, /* slot 3 */
- AC97_PCM_SURR_DAC_RATE, /* slot 4 */
- 0xff, /* slot 5 */
- 0xff, /* slot 6 */
- AC97_PCM_LFE_DAC_RATE, /* slot 7 */
- AC97_PCM_LFE_DAC_RATE, /* slot 8 */
- 0xff, /* slot 9 */
- AC97_PCM_FRONT_DAC_RATE, /* slot 10 */
- AC97_PCM_FRONT_DAC_RATE, /* slot 11 */
- },
-},
-{
- /* double rates */
- {
- /* 3&4 front, 7&8 front (t+1) */
- AC97_PCM_FRONT_DAC_RATE, /* slot 3 */
- AC97_PCM_FRONT_DAC_RATE, /* slot 4 */
- 0xff, /* slot 5 */
- 0xff, /* slot 6 */
- AC97_PCM_FRONT_DAC_RATE, /* slot 7 */
- AC97_PCM_FRONT_DAC_RATE, /* slot 8 */
- 0xff, /* slot 9 */
- 0xff, /* slot 10 */
- 0xff, /* slot 11 */
- },
- {
- /* not specified in the specification */
- 0xff, /* slot 3 */
- 0xff, /* slot 4 */
- 0xff, /* slot 5 */
- 0xff, /* slot 6 */
- 0xff, /* slot 7 */
- 0xff, /* slot 8 */
- 0xff, /* slot 9 */
- 0xff, /* slot 10 */
- 0xff, /* slot 11 */
- },
- {
- 0xff, /* slot 3 */
- 0xff, /* slot 4 */
- 0xff, /* slot 5 */
- 0xff, /* slot 6 */
- 0xff, /* slot 7 */
- 0xff, /* slot 8 */
- 0xff, /* slot 9 */
- 0xff, /* slot 10 */
- 0xff, /* slot 11 */
- },
- {
- 0xff, /* slot 3 */
- 0xff, /* slot 4 */
- 0xff, /* slot 5 */
- 0xff, /* slot 6 */
- 0xff, /* slot 7 */
- 0xff, /* slot 8 */
- 0xff, /* slot 9 */
- 0xff, /* slot 10 */
- 0xff, /* slot 11 */
- }
-}};
-
-/* FIXME: more various mappings for ADC? */
-static unsigned char rate_cregs[9] = {
- AC97_PCM_LR_ADC_RATE, /* 3 */
- AC97_PCM_LR_ADC_RATE, /* 4 */
- 0xff, /* 5 */
- AC97_PCM_MIC_ADC_RATE, /* 6 */
- 0xff, /* 7 */
- 0xff, /* 8 */
- 0xff, /* 9 */
- 0xff, /* 10 */
- 0xff, /* 11 */
-};
-
-static unsigned char get_slot_reg(struct ac97_pcm *pcm, unsigned short cidx,
- unsigned short slot, int dbl)
-{
- if (slot < 3)
- return 0xff;
- if (slot > 11)
- return 0xff;
- if (pcm->spdif)
- return AC97_SPDIF; /* pseudo register */
- if (pcm->stream == SNDRV_PCM_STREAM_PLAYBACK)
- return rate_reg_tables[dbl][pcm->r[dbl].rate_table[cidx]][slot - 3];
- else
- return rate_cregs[slot - 3];
-}
-
-static int set_spdif_rate(struct snd_ac97 *ac97, unsigned short rate)
-{
- unsigned short old, bits, reg, mask;
- unsigned int sbits;
-
- if (! (ac97->ext_id & AC97_EI_SPDIF))
- return -ENODEV;
-
- /* TODO: double rate support */
- if (ac97->flags & AC97_CS_SPDIF) {
- switch (rate) {
- case 48000: bits = 0; break;
- case 44100: bits = 1 << AC97_SC_SPSR_SHIFT; break;
- default: /* invalid - disable output */
- snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
- return -EINVAL;
- }
- reg = AC97_CSR_SPDIF;
- mask = 1 << AC97_SC_SPSR_SHIFT;
- } else {
- if (ac97->id == AC97_ID_CM9739 && rate != 48000) {
- snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
- return -EINVAL;
- }
- switch (rate) {
- case 44100: bits = AC97_SC_SPSR_44K; break;
- case 48000: bits = AC97_SC_SPSR_48K; break;
- case 32000: bits = AC97_SC_SPSR_32K; break;
- default: /* invalid - disable output */
- snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
- return -EINVAL;
- }
- reg = AC97_SPDIF;
- mask = AC97_SC_SPSR_MASK;
- }
-
- mutex_lock(&ac97->reg_mutex);
- old = snd_ac97_read(ac97, reg) & mask;
- if (old != bits) {
- snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
- snd_ac97_update_bits_nolock(ac97, reg, mask, bits);
- /* update the internal spdif bits */
- sbits = ac97->spdif_status;
- if (sbits & IEC958_AES0_PROFESSIONAL) {
- sbits &= ~IEC958_AES0_PRO_FS;
- switch (rate) {
- case 44100: sbits |= IEC958_AES0_PRO_FS_44100; break;
- case 48000: sbits |= IEC958_AES0_PRO_FS_48000; break;
- case 32000: sbits |= IEC958_AES0_PRO_FS_32000; break;
- }
- } else {
- sbits &= ~(IEC958_AES3_CON_FS << 24);
- switch (rate) {
- case 44100: sbits |= IEC958_AES3_CON_FS_44100<<24; break;
- case 48000: sbits |= IEC958_AES3_CON_FS_48000<<24; break;
- case 32000: sbits |= IEC958_AES3_CON_FS_32000<<24; break;
- }
- }
- ac97->spdif_status = sbits;
- }
- snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF);
- mutex_unlock(&ac97->reg_mutex);
- return 0;
-}
-
-/**
- * snd_ac97_set_rate - change the rate of the given input/output.
- * @ac97: the ac97 instance
- * @reg: the register to change
- * @rate: the sample rate to set
- *
- * Changes the rate of the given input/output on the codec.
- * If the codec doesn't support VAR, the rate must be 48000 (except
- * for SPDIF).
- *
- * The valid registers are AC97_PMC_MIC_ADC_RATE,
- * AC97_PCM_FRONT_DAC_RATE, AC97_PCM_LR_ADC_RATE.
- * AC97_PCM_SURR_DAC_RATE and AC97_PCM_LFE_DAC_RATE are accepted
- * if the codec supports them.
- * AC97_SPDIF is accepted as a pseudo register to modify the SPDIF
- * status bits.
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_ac97_set_rate(struct snd_ac97 *ac97, int reg, unsigned int rate)
-{
- int dbl;
- unsigned int tmp;
-
- dbl = rate > 48000;
- if (dbl) {
- if (!(ac97->flags & AC97_DOUBLE_RATE))
- return -EINVAL;
- if (reg != AC97_PCM_FRONT_DAC_RATE)
- return -EINVAL;
- }
-
- snd_ac97_update_power(ac97, reg, 1);
- switch (reg) {
- case AC97_PCM_MIC_ADC_RATE:
- if ((ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_VRM) == 0) /* MIC VRA */
- if (rate != 48000)
- return -EINVAL;
- break;
- case AC97_PCM_FRONT_DAC_RATE:
- case AC97_PCM_LR_ADC_RATE:
- if ((ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_VRA) == 0) /* VRA */
- if (rate != 48000 && rate != 96000)
- return -EINVAL;
- break;
- case AC97_PCM_SURR_DAC_RATE:
- if (! (ac97->scaps & AC97_SCAP_SURROUND_DAC))
- return -EINVAL;
- break;
- case AC97_PCM_LFE_DAC_RATE:
- if (! (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC))
- return -EINVAL;
- break;
- case AC97_SPDIF:
- /* special case */
- return set_spdif_rate(ac97, rate);
- default:
- return -EINVAL;
- }
- if (dbl)
- rate /= 2;
- tmp = (rate * ac97->bus->clock) / 48000;
- if (tmp > 65535)
- return -EINVAL;
- if ((ac97->ext_id & AC97_EI_DRA) && reg == AC97_PCM_FRONT_DAC_RATE)
- snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
- AC97_EA_DRA, dbl ? AC97_EA_DRA : 0);
- snd_ac97_update(ac97, reg, tmp & 0xffff);
- snd_ac97_read(ac97, reg);
- if ((ac97->ext_id & AC97_EI_DRA) && reg == AC97_PCM_FRONT_DAC_RATE) {
- /* Intel controllers require double rate data to be put in
- * slots 7+8
- */
- snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE,
- AC97_GP_DRSS_MASK,
- dbl ? AC97_GP_DRSS_78 : 0);
- snd_ac97_read(ac97, AC97_GENERAL_PURPOSE);
- }
- return 0;
-}
-
-EXPORT_SYMBOL(snd_ac97_set_rate);
-
-static unsigned short get_pslots(struct snd_ac97 *ac97, unsigned char *rate_table, unsigned short *spdif_slots)
-{
- if (!ac97_is_audio(ac97))
- return 0;
- if (ac97_is_rev22(ac97) || ac97_can_amap(ac97)) {
- unsigned short slots = 0;
- if (ac97_is_rev22(ac97)) {
- /* Note: it's simply emulation of AMAP behaviour */
- u16 es;
- es = ac97->regs[AC97_EXTENDED_ID] &= ~AC97_EI_DACS_SLOT_MASK;
- switch (ac97->addr) {
- case 1:
- case 2: es |= (1<<AC97_EI_DACS_SLOT_SHIFT); break;
- case 3: es |= (2<<AC97_EI_DACS_SLOT_SHIFT); break;
- }
- snd_ac97_write_cache(ac97, AC97_EXTENDED_ID, es);
- }
- switch (ac97->addr) {
- case 0:
- slots |= (1<<AC97_SLOT_PCM_LEFT)|(1<<AC97_SLOT_PCM_RIGHT);
- if (ac97->scaps & AC97_SCAP_SURROUND_DAC)
- slots |= (1<<AC97_SLOT_PCM_SLEFT)|(1<<AC97_SLOT_PCM_SRIGHT);
- if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC)
- slots |= (1<<AC97_SLOT_PCM_CENTER)|(1<<AC97_SLOT_LFE);
- if (ac97->ext_id & AC97_EI_SPDIF) {
- if (!(ac97->scaps & AC97_SCAP_SURROUND_DAC))
- *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT)|(1<<AC97_SLOT_SPDIF_RIGHT);
- else if (!(ac97->scaps & AC97_SCAP_CENTER_LFE_DAC))
- *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT1)|(1<<AC97_SLOT_SPDIF_RIGHT1);
- else
- *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT2)|(1<<AC97_SLOT_SPDIF_RIGHT2);
- }
- *rate_table = 0;
- break;
- case 1:
- case 2:
- slots |= (1<<AC97_SLOT_PCM_SLEFT)|(1<<AC97_SLOT_PCM_SRIGHT);
- if (ac97->scaps & AC97_SCAP_SURROUND_DAC)
- slots |= (1<<AC97_SLOT_PCM_CENTER)|(1<<AC97_SLOT_LFE);
- if (ac97->ext_id & AC97_EI_SPDIF) {
- if (!(ac97->scaps & AC97_SCAP_SURROUND_DAC))
- *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT1)|(1<<AC97_SLOT_SPDIF_RIGHT1);
- else
- *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT2)|(1<<AC97_SLOT_SPDIF_RIGHT2);
- }
- *rate_table = 1;
- break;
- case 3:
- slots |= (1<<AC97_SLOT_PCM_CENTER)|(1<<AC97_SLOT_LFE);
- if (ac97->ext_id & AC97_EI_SPDIF)
- *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT2)|(1<<AC97_SLOT_SPDIF_RIGHT2);
- *rate_table = 2;
- break;
- }
- return slots;
- } else {
- unsigned short slots;
- slots = (1<<AC97_SLOT_PCM_LEFT)|(1<<AC97_SLOT_PCM_RIGHT);
- if (ac97->scaps & AC97_SCAP_SURROUND_DAC)
- slots |= (1<<AC97_SLOT_PCM_SLEFT)|(1<<AC97_SLOT_PCM_SRIGHT);
- if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC)
- slots |= (1<<AC97_SLOT_PCM_CENTER)|(1<<AC97_SLOT_LFE);
- if (ac97->ext_id & AC97_EI_SPDIF) {
- if (!(ac97->scaps & AC97_SCAP_SURROUND_DAC))
- *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT)|(1<<AC97_SLOT_SPDIF_RIGHT);
- else if (!(ac97->scaps & AC97_SCAP_CENTER_LFE_DAC))
- *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT1)|(1<<AC97_SLOT_SPDIF_RIGHT1);
- else
- *spdif_slots = (1<<AC97_SLOT_SPDIF_LEFT2)|(1<<AC97_SLOT_SPDIF_RIGHT2);
- }
- *rate_table = 0;
- return slots;
- }
-}
-
-static unsigned short get_cslots(struct snd_ac97 *ac97)
-{
- unsigned short slots;
-
- if (!ac97_is_audio(ac97))
- return 0;
- slots = (1<<AC97_SLOT_PCM_LEFT)|(1<<AC97_SLOT_PCM_RIGHT);
- slots |= (1<<AC97_SLOT_MIC);
- return slots;
-}
-
-static unsigned int get_rates(struct ac97_pcm *pcm, unsigned int cidx, unsigned short slots, int dbl)
-{
- int i, idx;
- unsigned int rates = ~0;
- unsigned char reg;
-
- for (i = 3; i < 12; i++) {
- if (!(slots & (1 << i)))
- continue;
- reg = get_slot_reg(pcm, cidx, i, dbl);
- switch (reg) {
- case AC97_PCM_FRONT_DAC_RATE: idx = AC97_RATES_FRONT_DAC; break;
- case AC97_PCM_SURR_DAC_RATE: idx = AC97_RATES_SURR_DAC; break;
- case AC97_PCM_LFE_DAC_RATE: idx = AC97_RATES_LFE_DAC; break;
- case AC97_PCM_LR_ADC_RATE: idx = AC97_RATES_ADC; break;
- case AC97_PCM_MIC_ADC_RATE: idx = AC97_RATES_MIC_ADC; break;
- default: idx = AC97_RATES_SPDIF; break;
- }
- rates &= pcm->r[dbl].codec[cidx]->rates[idx];
- }
- if (!dbl)
- rates &= ~(SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000);
- return rates;
-}
-
-/**
- * snd_ac97_pcm_assign - assign AC97 slots to given PCM streams
- * @bus: the ac97 bus instance
- * @pcms_count: count of PCMs to be assigned
- * @pcms: PCMs to be assigned
- *
- * It assigns available AC97 slots for given PCMs. If none or only
- * some slots are available, pcm->xxx.slots and pcm->xxx.rslots[] members
- * are reduced and might be zero.
- */
-int snd_ac97_pcm_assign(struct snd_ac97_bus *bus,
- unsigned short pcms_count,
- const struct ac97_pcm *pcms)
-{
- int i, j, k;
- const struct ac97_pcm *pcm;
- struct ac97_pcm *rpcms, *rpcm;
- unsigned short avail_slots[2][4];
- unsigned char rate_table[2][4];
- unsigned short tmp, slots;
- unsigned short spdif_slots[4];
- unsigned int rates;
- struct snd_ac97 *codec;
-
- rpcms = kcalloc(pcms_count, sizeof(struct ac97_pcm), GFP_KERNEL);
- if (rpcms == NULL)
- return -ENOMEM;
- memset(avail_slots, 0, sizeof(avail_slots));
- memset(rate_table, 0, sizeof(rate_table));
- memset(spdif_slots, 0, sizeof(spdif_slots));
- for (i = 0; i < 4; i++) {
- codec = bus->codec[i];
- if (!codec)
- continue;
- avail_slots[0][i] = get_pslots(codec, &rate_table[0][i], &spdif_slots[i]);
- avail_slots[1][i] = get_cslots(codec);
- if (!(codec->scaps & AC97_SCAP_INDEP_SDIN)) {
- for (j = 0; j < i; j++) {
- if (bus->codec[j])
- avail_slots[1][i] &= ~avail_slots[1][j];
- }
- }
- }
- /* first step - exclusive devices */
- for (i = 0; i < pcms_count; i++) {
- pcm = &pcms[i];
- rpcm = &rpcms[i];
- /* low-level driver thinks that it's more clever */
- if (pcm->copy_flag) {
- *rpcm = *pcm;
- continue;
- }
- rpcm->stream = pcm->stream;
- rpcm->exclusive = pcm->exclusive;
- rpcm->spdif = pcm->spdif;
- rpcm->private_value = pcm->private_value;
- rpcm->bus = bus;
- rpcm->rates = ~0;
- slots = pcm->r[0].slots;
- for (j = 0; j < 4 && slots; j++) {
- if (!bus->codec[j])
- continue;
- rates = ~0;
- if (pcm->spdif && pcm->stream == 0)
- tmp = spdif_slots[j];
- else
- tmp = avail_slots[pcm->stream][j];
- if (pcm->exclusive) {
- /* exclusive access */
- tmp &= slots;
- for (k = 0; k < i; k++) {
- if (rpcm->stream == rpcms[k].stream)
- tmp &= ~rpcms[k].r[0].rslots[j];
- }
- } else {
- /* non-exclusive access */
- tmp &= pcm->r[0].slots;
- }
- if (tmp) {
- rpcm->r[0].rslots[j] = tmp;
- rpcm->r[0].codec[j] = bus->codec[j];
- rpcm->r[0].rate_table[j] = rate_table[pcm->stream][j];
- if (bus->no_vra)
- rates = SNDRV_PCM_RATE_48000;
- else
- rates = get_rates(rpcm, j, tmp, 0);
- if (pcm->exclusive)
- avail_slots[pcm->stream][j] &= ~tmp;
- }
- slots &= ~tmp;
- rpcm->r[0].slots |= tmp;
- rpcm->rates &= rates;
- }
- /* for double rate, we check the first codec only */
- if (pcm->stream == SNDRV_PCM_STREAM_PLAYBACK &&
- bus->codec[0] && (bus->codec[0]->flags & AC97_DOUBLE_RATE) &&
- rate_table[pcm->stream][0] == 0) {
- tmp = (1<<AC97_SLOT_PCM_LEFT) | (1<<AC97_SLOT_PCM_RIGHT) |
- (1<<AC97_SLOT_PCM_LEFT_0) | (1<<AC97_SLOT_PCM_RIGHT_0);
- if ((tmp & pcm->r[1].slots) == tmp) {
- rpcm->r[1].slots = tmp;
- rpcm->r[1].rslots[0] = tmp;
- rpcm->r[1].rate_table[0] = 0;
- rpcm->r[1].codec[0] = bus->codec[0];
- if (pcm->exclusive)
- avail_slots[pcm->stream][0] &= ~tmp;
- if (bus->no_vra)
- rates = SNDRV_PCM_RATE_96000;
- else
- rates = get_rates(rpcm, 0, tmp, 1);
- rpcm->rates |= rates;
- }
- }
- if (rpcm->rates == ~0)
- rpcm->rates = 0; /* not used */
- }
- bus->pcms_count = pcms_count;
- bus->pcms = rpcms;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_ac97_pcm_assign);
-
-/**
- * snd_ac97_pcm_open - opens the given AC97 pcm
- * @pcm: the ac97 pcm instance
- * @rate: rate in Hz, if codec does not support VRA, this value must be 48000Hz
- * @cfg: output stream characteristics
- * @slots: a subset of allocated slots (snd_ac97_pcm_assign) for this pcm
- *
- * It locks the specified slots and sets the given rate to AC97 registers.
- */
-int snd_ac97_pcm_open(struct ac97_pcm *pcm, unsigned int rate,
- enum ac97_pcm_cfg cfg, unsigned short slots)
-{
- struct snd_ac97_bus *bus;
- int i, cidx, r, ok_flag;
- unsigned int reg_ok[4] = {0,0,0,0};
- unsigned char reg;
- int err = 0;
-
- r = rate > 48000;
- bus = pcm->bus;
- if (cfg == AC97_PCM_CFG_SPDIF) {
- for (cidx = 0; cidx < 4; cidx++)
- if (bus->codec[cidx] && (bus->codec[cidx]->ext_id & AC97_EI_SPDIF)) {
- err = set_spdif_rate(bus->codec[cidx], rate);
- if (err < 0)
- return err;
- }
- }
- spin_lock_irq(&pcm->bus->bus_lock);
- for (i = 3; i < 12; i++) {
- if (!(slots & (1 << i)))
- continue;
- ok_flag = 0;
- for (cidx = 0; cidx < 4; cidx++) {
- if (bus->used_slots[pcm->stream][cidx] & (1 << i)) {
- spin_unlock_irq(&pcm->bus->bus_lock);
- err = -EBUSY;
- goto error;
- }
- if (pcm->r[r].rslots[cidx] & (1 << i)) {
- bus->used_slots[pcm->stream][cidx] |= (1 << i);
- ok_flag++;
- }
- }
- if (!ok_flag) {
- spin_unlock_irq(&pcm->bus->bus_lock);
- snd_printk(KERN_ERR "cannot find configuration for AC97 slot %i\n", i);
- err = -EAGAIN;
- goto error;
- }
- }
- pcm->cur_dbl = r;
- spin_unlock_irq(&pcm->bus->bus_lock);
- for (i = 3; i < 12; i++) {
- if (!(slots & (1 << i)))
- continue;
- for (cidx = 0; cidx < 4; cidx++) {
- if (pcm->r[r].rslots[cidx] & (1 << i)) {
- reg = get_slot_reg(pcm, cidx, i, r);
- if (reg == 0xff) {
- snd_printk(KERN_ERR "invalid AC97 slot %i?\n", i);
- continue;
- }
- if (reg_ok[cidx] & (1 << (reg - AC97_PCM_FRONT_DAC_RATE)))
- continue;
- //printk(KERN_DEBUG "setting ac97 reg 0x%x to rate %d\n", reg, rate);
- err = snd_ac97_set_rate(pcm->r[r].codec[cidx], reg, rate);
- if (err < 0)
- snd_printk(KERN_ERR "error in snd_ac97_set_rate: cidx=%d, reg=0x%x, rate=%d, err=%d\n", cidx, reg, rate, err);
- else
- reg_ok[cidx] |= (1 << (reg - AC97_PCM_FRONT_DAC_RATE));
- }
- }
- }
- pcm->aslots = slots;
- return 0;
-
- error:
- pcm->aslots = slots;
- snd_ac97_pcm_close(pcm);
- return err;
-}
-
-EXPORT_SYMBOL(snd_ac97_pcm_open);
-
-/**
- * snd_ac97_pcm_close - closes the given AC97 pcm
- * @pcm: the ac97 pcm instance
- *
- * It frees the locked AC97 slots.
- */
-int snd_ac97_pcm_close(struct ac97_pcm *pcm)
-{
- struct snd_ac97_bus *bus;
- unsigned short slots = pcm->aslots;
- int i, cidx;
-
-#ifdef CONFIG_SND_AC97_POWER_SAVE
- int r = pcm->cur_dbl;
- for (i = 3; i < 12; i++) {
- if (!(slots & (1 << i)))
- continue;
- for (cidx = 0; cidx < 4; cidx++) {
- if (pcm->r[r].rslots[cidx] & (1 << i)) {
- int reg = get_slot_reg(pcm, cidx, i, r);
- snd_ac97_update_power(pcm->r[r].codec[cidx],
- reg, 0);
- }
- }
- }
-#endif
-
- bus = pcm->bus;
- spin_lock_irq(&pcm->bus->bus_lock);
- for (i = 3; i < 12; i++) {
- if (!(slots & (1 << i)))
- continue;
- for (cidx = 0; cidx < 4; cidx++)
- bus->used_slots[pcm->stream][cidx] &= ~(1 << i);
- }
- pcm->aslots = 0;
- pcm->cur_dbl = 0;
- spin_unlock_irq(&pcm->bus->bus_lock);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_ac97_pcm_close);
-
-static int double_rate_hw_constraint_rate(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- if (channels->min > 2) {
- static const struct snd_interval single_rates = {
- .min = 1,
- .max = 48000,
- };
- struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
- return snd_interval_refine(rate, &single_rates);
- }
- return 0;
-}
-
-static int double_rate_hw_constraint_channels(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
- if (rate->min > 48000) {
- static const struct snd_interval double_rate_channels = {
- .min = 2,
- .max = 2,
- };
- struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- return snd_interval_refine(channels, &double_rate_channels);
- }
- return 0;
-}
-
-/**
- * snd_ac97_pcm_double_rate_rules - set double rate constraints
- * @runtime: the runtime of the ac97 front playback pcm
- *
- * Installs the hardware constraint rules to prevent using double rates and
- * more than two channels at the same time.
- */
-int snd_ac97_pcm_double_rate_rules(struct snd_pcm_runtime *runtime)
-{
- int err;
-
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- double_rate_hw_constraint_rate, NULL,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- double_rate_hw_constraint_channels, NULL,
- SNDRV_PCM_HW_PARAM_RATE, -1);
- return err;
-}
-
-EXPORT_SYMBOL(snd_ac97_pcm_double_rate_rules);
diff --git a/ANDROID_3.4.5/sound/pci/ac97/ac97_proc.c b/ANDROID_3.4.5/sound/pci/ac97/ac97_proc.c
deleted file mode 100644
index 6320bf08..00000000
--- a/ANDROID_3.4.5/sound/pci/ac97/ac97_proc.c
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Universal interface for Audio Codec '97
- *
- * For more details look to AC '97 component specification revision 2.2
- * by Intel Corporation (http://developer.intel.com).
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/mutex.h>
-
-#include <sound/core.h>
-#include <sound/ac97_codec.h>
-#include <sound/asoundef.h>
-#include "ac97_local.h"
-#include "ac97_id.h"
-
-/*
- * proc interface
- */
-
-static void snd_ac97_proc_read_functions(struct snd_ac97 *ac97, struct snd_info_buffer *buffer)
-{
- int header = 0, function;
- unsigned short info, sense_info;
- static const char *function_names[12] = {
- "Master Out", "AUX Out", "Center/LFE Out", "SPDIF Out",
- "Phone In", "Mic 1", "Mic 2", "Line In", "CD In", "Video In",
- "Aux In", "Mono Out"
- };
- static const char *locations[8] = {
- "Rear I/O Panel", "Front Panel", "Motherboard", "Dock/External",
- "reserved", "reserved", "reserved", "NC/unused"
- };
-
- for (function = 0; function < 12; ++function) {
- snd_ac97_write(ac97, AC97_FUNC_SELECT, function << 1);
- info = snd_ac97_read(ac97, AC97_FUNC_INFO);
- if (!(info & 0x0001))
- continue;
- if (!header) {
- snd_iprintf(buffer, "\n Gain Inverted Buffer delay Location\n");
- header = 1;
- }
- sense_info = snd_ac97_read(ac97, AC97_SENSE_INFO);
- snd_iprintf(buffer, "%-17s: %3d.%d dBV %c %2d/fs %s\n",
- function_names[function],
- (info & 0x8000 ? -1 : 1) * ((info & 0x7000) >> 12) * 3 / 2,
- ((info & 0x0800) >> 11) * 5,
- info & 0x0400 ? 'X' : '-',
- (info & 0x03e0) >> 5,
- locations[sense_info >> 13]);
- }
-}
-
-static const char *snd_ac97_stereo_enhancements[] =
-{
- /* 0 */ "No 3D Stereo Enhancement",
- /* 1 */ "Analog Devices Phat Stereo",
- /* 2 */ "Creative Stereo Enhancement",
- /* 3 */ "National Semi 3D Stereo Enhancement",
- /* 4 */ "YAMAHA Ymersion",
- /* 5 */ "BBE 3D Stereo Enhancement",
- /* 6 */ "Crystal Semi 3D Stereo Enhancement",
- /* 7 */ "Qsound QXpander",
- /* 8 */ "Spatializer 3D Stereo Enhancement",
- /* 9 */ "SRS 3D Stereo Enhancement",
- /* 10 */ "Platform Tech 3D Stereo Enhancement",
- /* 11 */ "AKM 3D Audio",
- /* 12 */ "Aureal Stereo Enhancement",
- /* 13 */ "Aztech 3D Enhancement",
- /* 14 */ "Binaura 3D Audio Enhancement",
- /* 15 */ "ESS Technology Stereo Enhancement",
- /* 16 */ "Harman International VMAx",
- /* 17 */ "Nvidea/IC Ensemble/KS Waves 3D Stereo Enhancement",
- /* 18 */ "Philips Incredible Sound",
- /* 19 */ "Texas Instruments 3D Stereo Enhancement",
- /* 20 */ "VLSI Technology 3D Stereo Enhancement",
- /* 21 */ "TriTech 3D Stereo Enhancement",
- /* 22 */ "Realtek 3D Stereo Enhancement",
- /* 23 */ "Samsung 3D Stereo Enhancement",
- /* 24 */ "Wolfson Microelectronics 3D Enhancement",
- /* 25 */ "Delta Integration 3D Enhancement",
- /* 26 */ "SigmaTel 3D Enhancement",
- /* 27 */ "IC Ensemble/KS Waves",
- /* 28 */ "Rockwell 3D Stereo Enhancement",
- /* 29 */ "Reserved 29",
- /* 30 */ "Reserved 30",
- /* 31 */ "Reserved 31"
-};
-
-static void snd_ac97_proc_read_main(struct snd_ac97 *ac97, struct snd_info_buffer *buffer, int subidx)
-{
- char name[64];
- unsigned short val, tmp, ext, mext;
- static const char *spdif_slots[4] = { " SPDIF=3/4", " SPDIF=7/8", " SPDIF=6/9", " SPDIF=10/11" };
- static const char *spdif_rates[4] = { " Rate=44.1kHz", " Rate=res", " Rate=48kHz", " Rate=32kHz" };
- static const char *spdif_rates_cs4205[4] = { " Rate=48kHz", " Rate=44.1kHz", " Rate=res", " Rate=res" };
- static const char *double_rate_slots[4] = { "10/11", "7/8", "reserved", "reserved" };
-
- snd_ac97_get_name(NULL, ac97->id, name, 0);
- snd_iprintf(buffer, "%d-%d/%d: %s\n\n", ac97->addr, ac97->num, subidx, name);
-
- if ((ac97->scaps & AC97_SCAP_AUDIO) == 0)
- goto __modem;
-
- snd_iprintf(buffer, "PCI Subsys Vendor: 0x%04x\n",
- ac97->subsystem_vendor);
- snd_iprintf(buffer, "PCI Subsys Device: 0x%04x\n\n",
- ac97->subsystem_device);
-
- snd_iprintf(buffer, "Flags: %x\n", ac97->flags);
-
- if ((ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23) {
- val = snd_ac97_read(ac97, AC97_INT_PAGING);
- snd_ac97_update_bits(ac97, AC97_INT_PAGING,
- AC97_PAGE_MASK, AC97_PAGE_1);
- tmp = snd_ac97_read(ac97, AC97_CODEC_CLASS_REV);
- snd_iprintf(buffer, "Revision : 0x%02x\n", tmp & 0xff);
- snd_iprintf(buffer, "Compat. Class : 0x%02x\n", (tmp >> 8) & 0x1f);
- snd_iprintf(buffer, "Subsys. Vendor ID: 0x%04x\n",
- snd_ac97_read(ac97, AC97_PCI_SVID));
- snd_iprintf(buffer, "Subsys. ID : 0x%04x\n\n",
- snd_ac97_read(ac97, AC97_PCI_SID));
- snd_ac97_update_bits(ac97, AC97_INT_PAGING,
- AC97_PAGE_MASK, val & AC97_PAGE_MASK);
- }
-
- // val = snd_ac97_read(ac97, AC97_RESET);
- val = ac97->caps;
- snd_iprintf(buffer, "Capabilities :%s%s%s%s%s%s\n",
- val & AC97_BC_DEDICATED_MIC ? " -dedicated MIC PCM IN channel-" : "",
- val & AC97_BC_RESERVED1 ? " -reserved1-" : "",
- val & AC97_BC_BASS_TREBLE ? " -bass & treble-" : "",
- val & AC97_BC_SIM_STEREO ? " -simulated stereo-" : "",
- val & AC97_BC_HEADPHONE ? " -headphone out-" : "",
- val & AC97_BC_LOUDNESS ? " -loudness-" : "");
- tmp = ac97->caps & AC97_BC_DAC_MASK;
- snd_iprintf(buffer, "DAC resolution : %s%s%s%s\n",
- tmp == AC97_BC_16BIT_DAC ? "16-bit" : "",
- tmp == AC97_BC_18BIT_DAC ? "18-bit" : "",
- tmp == AC97_BC_20BIT_DAC ? "20-bit" : "",
- tmp == AC97_BC_DAC_MASK ? "???" : "");
- tmp = ac97->caps & AC97_BC_ADC_MASK;
- snd_iprintf(buffer, "ADC resolution : %s%s%s%s\n",
- tmp == AC97_BC_16BIT_ADC ? "16-bit" : "",
- tmp == AC97_BC_18BIT_ADC ? "18-bit" : "",
- tmp == AC97_BC_20BIT_ADC ? "20-bit" : "",
- tmp == AC97_BC_ADC_MASK ? "???" : "");
- snd_iprintf(buffer, "3D enhancement : %s\n",
- snd_ac97_stereo_enhancements[(val >> 10) & 0x1f]);
- snd_iprintf(buffer, "\nCurrent setup\n");
- val = snd_ac97_read(ac97, AC97_MIC);
- snd_iprintf(buffer, "Mic gain : %s [%s]\n", val & 0x0040 ? "+20dB" : "+0dB", ac97->regs[AC97_MIC] & 0x0040 ? "+20dB" : "+0dB");
- val = snd_ac97_read(ac97, AC97_GENERAL_PURPOSE);
- snd_iprintf(buffer, "POP path : %s 3D\n"
- "Sim. stereo : %s\n"
- "3D enhancement : %s\n"
- "Loudness : %s\n"
- "Mono output : %s\n"
- "Mic select : %s\n"
- "ADC/DAC loopback : %s\n",
- val & 0x8000 ? "post" : "pre",
- val & 0x4000 ? "on" : "off",
- val & 0x2000 ? "on" : "off",
- val & 0x1000 ? "on" : "off",
- val & 0x0200 ? "Mic" : "MIX",
- val & 0x0100 ? "Mic2" : "Mic1",
- val & 0x0080 ? "on" : "off");
- if (ac97->ext_id & AC97_EI_DRA)
- snd_iprintf(buffer, "Double rate slots: %s\n",
- double_rate_slots[(val >> 10) & 3]);
-
- ext = snd_ac97_read(ac97, AC97_EXTENDED_ID);
- if (ext == 0)
- goto __modem;
-
- snd_iprintf(buffer, "Extended ID : codec=%i rev=%i%s%s%s%s DSA=%i%s%s%s%s\n",
- (ext & AC97_EI_ADDR_MASK) >> AC97_EI_ADDR_SHIFT,
- (ext & AC97_EI_REV_MASK) >> AC97_EI_REV_SHIFT,
- ext & AC97_EI_AMAP ? " AMAP" : "",
- ext & AC97_EI_LDAC ? " LDAC" : "",
- ext & AC97_EI_SDAC ? " SDAC" : "",
- ext & AC97_EI_CDAC ? " CDAC" : "",
- (ext & AC97_EI_DACS_SLOT_MASK) >> AC97_EI_DACS_SLOT_SHIFT,
- ext & AC97_EI_VRM ? " VRM" : "",
- ext & AC97_EI_SPDIF ? " SPDIF" : "",
- ext & AC97_EI_DRA ? " DRA" : "",
- ext & AC97_EI_VRA ? " VRA" : "");
- val = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
- snd_iprintf(buffer, "Extended status :%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
- val & AC97_EA_PRL ? " PRL" : "",
- val & AC97_EA_PRK ? " PRK" : "",
- val & AC97_EA_PRJ ? " PRJ" : "",
- val & AC97_EA_PRI ? " PRI" : "",
- val & AC97_EA_SPCV ? " SPCV" : "",
- val & AC97_EA_MDAC ? " MADC" : "",
- val & AC97_EA_LDAC ? " LDAC" : "",
- val & AC97_EA_SDAC ? " SDAC" : "",
- val & AC97_EA_CDAC ? " CDAC" : "",
- ext & AC97_EI_SPDIF ? spdif_slots[(val & AC97_EA_SPSA_SLOT_MASK) >> AC97_EA_SPSA_SLOT_SHIFT] : "",
- val & AC97_EA_VRM ? " VRM" : "",
- val & AC97_EA_SPDIF ? " SPDIF" : "",
- val & AC97_EA_DRA ? " DRA" : "",
- val & AC97_EA_VRA ? " VRA" : "");
- if (ext & AC97_EI_VRA) { /* VRA */
- val = snd_ac97_read(ac97, AC97_PCM_FRONT_DAC_RATE);
- snd_iprintf(buffer, "PCM front DAC : %iHz\n", val);
- if (ext & AC97_EI_SDAC) {
- val = snd_ac97_read(ac97, AC97_PCM_SURR_DAC_RATE);
- snd_iprintf(buffer, "PCM Surr DAC : %iHz\n", val);
- }
- if (ext & AC97_EI_LDAC) {
- val = snd_ac97_read(ac97, AC97_PCM_LFE_DAC_RATE);
- snd_iprintf(buffer, "PCM LFE DAC : %iHz\n", val);
- }
- val = snd_ac97_read(ac97, AC97_PCM_LR_ADC_RATE);
- snd_iprintf(buffer, "PCM ADC : %iHz\n", val);
- }
- if (ext & AC97_EI_VRM) {
- val = snd_ac97_read(ac97, AC97_PCM_MIC_ADC_RATE);
- snd_iprintf(buffer, "PCM MIC ADC : %iHz\n", val);
- }
- if ((ext & AC97_EI_SPDIF) || (ac97->flags & AC97_CS_SPDIF) ||
- (ac97->id == AC97_ID_YMF743)) {
- if (ac97->flags & AC97_CS_SPDIF)
- val = snd_ac97_read(ac97, AC97_CSR_SPDIF);
- else if (ac97->id == AC97_ID_YMF743) {
- val = snd_ac97_read(ac97, AC97_YMF7X3_DIT_CTRL);
- val = 0x2000 | (val & 0xff00) >> 4 | (val & 0x38) >> 2;
- } else
- val = snd_ac97_read(ac97, AC97_SPDIF);
-
- snd_iprintf(buffer, "SPDIF Control :%s%s%s%s Category=0x%x Generation=%i%s%s%s\n",
- val & AC97_SC_PRO ? " PRO" : " Consumer",
- val & AC97_SC_NAUDIO ? " Non-audio" : " PCM",
- val & AC97_SC_COPY ? "" : " Copyright",
- val & AC97_SC_PRE ? " Preemph50/15" : "",
- (val & AC97_SC_CC_MASK) >> AC97_SC_CC_SHIFT,
- (val & AC97_SC_L) >> 11,
- (ac97->flags & AC97_CS_SPDIF) ?
- spdif_rates_cs4205[(val & AC97_SC_SPSR_MASK) >> AC97_SC_SPSR_SHIFT] :
- spdif_rates[(val & AC97_SC_SPSR_MASK) >> AC97_SC_SPSR_SHIFT],
- (ac97->flags & AC97_CS_SPDIF) ?
- (val & AC97_SC_DRS ? " Validity" : "") :
- (val & AC97_SC_DRS ? " DRS" : ""),
- (ac97->flags & AC97_CS_SPDIF) ?
- (val & AC97_SC_V ? " Enabled" : "") :
- (val & AC97_SC_V ? " Validity" : ""));
- /* ALC650 specific*/
- if ((ac97->id & 0xfffffff0) == 0x414c4720 &&
- (snd_ac97_read(ac97, AC97_ALC650_CLOCK) & 0x01)) {
- val = snd_ac97_read(ac97, AC97_ALC650_SPDIF_INPUT_STATUS2);
- if (val & AC97_ALC650_CLOCK_LOCK) {
- val = snd_ac97_read(ac97, AC97_ALC650_SPDIF_INPUT_STATUS1);
- snd_iprintf(buffer, "SPDIF In Status :%s%s%s%s Category=0x%x Generation=%i",
- val & AC97_ALC650_PRO ? " PRO" : " Consumer",
- val & AC97_ALC650_NAUDIO ? " Non-audio" : " PCM",
- val & AC97_ALC650_COPY ? "" : " Copyright",
- val & AC97_ALC650_PRE ? " Preemph50/15" : "",
- (val & AC97_ALC650_CC_MASK) >> AC97_ALC650_CC_SHIFT,
- (val & AC97_ALC650_L) >> 15);
- val = snd_ac97_read(ac97, AC97_ALC650_SPDIF_INPUT_STATUS2);
- snd_iprintf(buffer, "%s Accuracy=%i%s%s\n",
- spdif_rates[(val & AC97_ALC650_SPSR_MASK) >> AC97_ALC650_SPSR_SHIFT],
- (val & AC97_ALC650_CLOCK_ACCURACY) >> AC97_ALC650_CLOCK_SHIFT,
- (val & AC97_ALC650_CLOCK_LOCK ? " Locked" : " Unlocked"),
- (val & AC97_ALC650_V ? " Validity?" : ""));
- } else {
- snd_iprintf(buffer, "SPDIF In Status : Not Locked\n");
- }
- }
- }
- if ((ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23) {
- val = snd_ac97_read(ac97, AC97_INT_PAGING);
- snd_ac97_update_bits(ac97, AC97_INT_PAGING,
- AC97_PAGE_MASK, AC97_PAGE_1);
- snd_ac97_proc_read_functions(ac97, buffer);
- snd_ac97_update_bits(ac97, AC97_INT_PAGING,
- AC97_PAGE_MASK, val & AC97_PAGE_MASK);
- }
-
-
- __modem:
- mext = snd_ac97_read(ac97, AC97_EXTENDED_MID);
- if (mext == 0)
- return;
-
- snd_iprintf(buffer, "Extended modem ID: codec=%i%s%s%s%s%s\n",
- (mext & AC97_MEI_ADDR_MASK) >> AC97_MEI_ADDR_SHIFT,
- mext & AC97_MEI_CID2 ? " CID2" : "",
- mext & AC97_MEI_CID1 ? " CID1" : "",
- mext & AC97_MEI_HANDSET ? " HSET" : "",
- mext & AC97_MEI_LINE2 ? " LIN2" : "",
- mext & AC97_MEI_LINE1 ? " LIN1" : "");
- val = snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS);
- snd_iprintf(buffer, "Modem status :%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
- val & AC97_MEA_GPIO ? " GPIO" : "",
- val & AC97_MEA_MREF ? " MREF" : "",
- val & AC97_MEA_ADC1 ? " ADC1" : "",
- val & AC97_MEA_DAC1 ? " DAC1" : "",
- val & AC97_MEA_ADC2 ? " ADC2" : "",
- val & AC97_MEA_DAC2 ? " DAC2" : "",
- val & AC97_MEA_HADC ? " HADC" : "",
- val & AC97_MEA_HDAC ? " HDAC" : "",
- val & AC97_MEA_PRA ? " PRA(GPIO)" : "",
- val & AC97_MEA_PRB ? " PRB(res)" : "",
- val & AC97_MEA_PRC ? " PRC(ADC1)" : "",
- val & AC97_MEA_PRD ? " PRD(DAC1)" : "",
- val & AC97_MEA_PRE ? " PRE(ADC2)" : "",
- val & AC97_MEA_PRF ? " PRF(DAC2)" : "",
- val & AC97_MEA_PRG ? " PRG(HADC)" : "",
- val & AC97_MEA_PRH ? " PRH(HDAC)" : "");
- if (mext & AC97_MEI_LINE1) {
- val = snd_ac97_read(ac97, AC97_LINE1_RATE);
- snd_iprintf(buffer, "Line1 rate : %iHz\n", val);
- }
- if (mext & AC97_MEI_LINE2) {
- val = snd_ac97_read(ac97, AC97_LINE2_RATE);
- snd_iprintf(buffer, "Line2 rate : %iHz\n", val);
- }
- if (mext & AC97_MEI_HANDSET) {
- val = snd_ac97_read(ac97, AC97_HANDSET_RATE);
- snd_iprintf(buffer, "Headset rate : %iHz\n", val);
- }
-}
-
-static void snd_ac97_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- struct snd_ac97 *ac97 = entry->private_data;
-
- mutex_lock(&ac97->page_mutex);
- if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) { // Analog Devices AD1881/85/86
- int idx;
- for (idx = 0; idx < 3; idx++)
- if (ac97->spec.ad18xx.id[idx]) {
- /* select single codec */
- snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
- ac97->spec.ad18xx.unchained[idx] | ac97->spec.ad18xx.chained[idx]);
- snd_ac97_proc_read_main(ac97, buffer, idx);
- snd_iprintf(buffer, "\n\n");
- }
- /* select all codecs */
- snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
-
- snd_iprintf(buffer, "\nAD18XX configuration\n");
- snd_iprintf(buffer, "Unchained : 0x%04x,0x%04x,0x%04x\n",
- ac97->spec.ad18xx.unchained[0],
- ac97->spec.ad18xx.unchained[1],
- ac97->spec.ad18xx.unchained[2]);
- snd_iprintf(buffer, "Chained : 0x%04x,0x%04x,0x%04x\n",
- ac97->spec.ad18xx.chained[0],
- ac97->spec.ad18xx.chained[1],
- ac97->spec.ad18xx.chained[2]);
- } else {
- snd_ac97_proc_read_main(ac97, buffer, 0);
- }
- mutex_unlock(&ac97->page_mutex);
-}
-
-#ifdef CONFIG_SND_DEBUG
-/* direct register write for debugging */
-static void snd_ac97_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- struct snd_ac97 *ac97 = entry->private_data;
- char line[64];
- unsigned int reg, val;
- mutex_lock(&ac97->page_mutex);
- while (!snd_info_get_line(buffer, line, sizeof(line))) {
- if (sscanf(line, "%x %x", &reg, &val) != 2)
- continue;
- /* register must be even */
- if (reg < 0x80 && (reg & 1) == 0 && val <= 0xffff)
- snd_ac97_write_cache(ac97, reg, val);
- }
- mutex_unlock(&ac97->page_mutex);
-}
-#endif
-
-static void snd_ac97_proc_regs_read_main(struct snd_ac97 *ac97, struct snd_info_buffer *buffer, int subidx)
-{
- int reg, val;
-
- for (reg = 0; reg < 0x80; reg += 2) {
- val = snd_ac97_read(ac97, reg);
- snd_iprintf(buffer, "%i:%02x = %04x\n", subidx, reg, val);
- }
-}
-
-static void snd_ac97_proc_regs_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_ac97 *ac97 = entry->private_data;
-
- mutex_lock(&ac97->page_mutex);
- if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) { // Analog Devices AD1881/85/86
-
- int idx;
- for (idx = 0; idx < 3; idx++)
- if (ac97->spec.ad18xx.id[idx]) {
- /* select single codec */
- snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
- ac97->spec.ad18xx.unchained[idx] | ac97->spec.ad18xx.chained[idx]);
- snd_ac97_proc_regs_read_main(ac97, buffer, idx);
- }
- /* select all codecs */
- snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
- } else {
- snd_ac97_proc_regs_read_main(ac97, buffer, 0);
- }
- mutex_unlock(&ac97->page_mutex);
-}
-
-void snd_ac97_proc_init(struct snd_ac97 * ac97)
-{
- struct snd_info_entry *entry;
- char name[32];
- const char *prefix;
-
- if (ac97->bus->proc == NULL)
- return;
- prefix = ac97_is_audio(ac97) ? "ac97" : "mc97";
- sprintf(name, "%s#%d-%d", prefix, ac97->addr, ac97->num);
- if ((entry = snd_info_create_card_entry(ac97->bus->card, name, ac97->bus->proc)) != NULL) {
- snd_info_set_text_ops(entry, ac97, snd_ac97_proc_read);
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- ac97->proc = entry;
- sprintf(name, "%s#%d-%d+regs", prefix, ac97->addr, ac97->num);
- if ((entry = snd_info_create_card_entry(ac97->bus->card, name, ac97->bus->proc)) != NULL) {
- snd_info_set_text_ops(entry, ac97, snd_ac97_proc_regs_read);
-#ifdef CONFIG_SND_DEBUG
- entry->mode |= S_IWUSR;
- entry->c.text.write = snd_ac97_proc_regs_write;
-#endif
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- ac97->proc_regs = entry;
-}
-
-void snd_ac97_proc_done(struct snd_ac97 * ac97)
-{
- snd_info_free_entry(ac97->proc_regs);
- ac97->proc_regs = NULL;
- snd_info_free_entry(ac97->proc);
- ac97->proc = NULL;
-}
-
-void snd_ac97_bus_proc_init(struct snd_ac97_bus * bus)
-{
- struct snd_info_entry *entry;
- char name[32];
-
- sprintf(name, "codec97#%d", bus->num);
- if ((entry = snd_info_create_card_entry(bus->card, name, bus->card->proc_root)) != NULL) {
- entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- bus->proc = entry;
-}
-
-void snd_ac97_bus_proc_done(struct snd_ac97_bus * bus)
-{
- snd_info_free_entry(bus->proc);
- bus->proc = NULL;
-}
diff --git a/ANDROID_3.4.5/sound/pci/ad1889.c b/ANDROID_3.4.5/sound/pci/ad1889.c
deleted file mode 100644
index 9d91d619..00000000
--- a/ANDROID_3.4.5/sound/pci/ad1889.c
+++ /dev/null
@@ -1,1078 +0,0 @@
-/* Analog Devices 1889 audio driver
- *
- * This is a driver for the AD1889 PCI audio chipset found
- * on the HP PA-RISC [BCJ]-xxx0 workstations.
- *
- * Copyright (C) 2004-2005, Kyle McMartin <kyle@parisc-linux.org>
- * Copyright (C) 2005, Thibaut Varene <varenet@parisc-linux.org>
- * Based on the OSS AD1889 driver by Randolph Chung <tausq@debian.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * TODO:
- * Do we need to take care of CCS register?
- * Maybe we could use finer grained locking (separate locks for pb/cap)?
- * Wishlist:
- * Control Interface (mixer) support
- * Better AC97 support (VSR...)?
- * PM support
- * MIDI support
- * Game Port support
- * SG DMA support (this will need *a lot* of work)
- */
-
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/compiler.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/initval.h>
-#include <sound/ac97_codec.h>
-
-#include <asm/io.h>
-
-#include "ad1889.h"
-#include "ac97/ac97_id.h"
-
-#define AD1889_DRVVER "Version: 1.7"
-
-MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>, Thibaut Varene <t-bone@parisc-linux.org>");
-MODULE_DESCRIPTION("Analog Devices AD1889 ALSA sound driver");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Analog Devices,AD1889}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for the AD1889 soundcard.");
-
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for the AD1889 soundcard.");
-
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable AD1889 soundcard.");
-
-static char *ac97_quirk[SNDRV_CARDS];
-module_param_array(ac97_quirk, charp, NULL, 0444);
-MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
-
-#define DEVNAME "ad1889"
-#define PFX DEVNAME ": "
-
-/* let's use the global sound debug interfaces */
-#define ad1889_debug(fmt, arg...) snd_printd(KERN_DEBUG fmt, ## arg)
-
-/* keep track of some hw registers */
-struct ad1889_register_state {
- u16 reg; /* reg setup */
- u32 addr; /* dma base address */
- unsigned long size; /* DMA buffer size */
-};
-
-struct snd_ad1889 {
- struct snd_card *card;
- struct pci_dev *pci;
-
- int irq;
- unsigned long bar;
- void __iomem *iobase;
-
- struct snd_ac97 *ac97;
- struct snd_ac97_bus *ac97_bus;
- struct snd_pcm *pcm;
- struct snd_info_entry *proc;
-
- struct snd_pcm_substream *psubs;
- struct snd_pcm_substream *csubs;
-
- /* playback register state */
- struct ad1889_register_state wave;
- struct ad1889_register_state ramc;
-
- spinlock_t lock;
-};
-
-static inline u16
-ad1889_readw(struct snd_ad1889 *chip, unsigned reg)
-{
- return readw(chip->iobase + reg);
-}
-
-static inline void
-ad1889_writew(struct snd_ad1889 *chip, unsigned reg, u16 val)
-{
- writew(val, chip->iobase + reg);
-}
-
-static inline u32
-ad1889_readl(struct snd_ad1889 *chip, unsigned reg)
-{
- return readl(chip->iobase + reg);
-}
-
-static inline void
-ad1889_writel(struct snd_ad1889 *chip, unsigned reg, u32 val)
-{
- writel(val, chip->iobase + reg);
-}
-
-static inline void
-ad1889_unmute(struct snd_ad1889 *chip)
-{
- u16 st;
- st = ad1889_readw(chip, AD_DS_WADA) &
- ~(AD_DS_WADA_RWAM | AD_DS_WADA_LWAM);
- ad1889_writew(chip, AD_DS_WADA, st);
- ad1889_readw(chip, AD_DS_WADA);
-}
-
-static inline void
-ad1889_mute(struct snd_ad1889 *chip)
-{
- u16 st;
- st = ad1889_readw(chip, AD_DS_WADA) | AD_DS_WADA_RWAM | AD_DS_WADA_LWAM;
- ad1889_writew(chip, AD_DS_WADA, st);
- ad1889_readw(chip, AD_DS_WADA);
-}
-
-static inline void
-ad1889_load_adc_buffer_address(struct snd_ad1889 *chip, u32 address)
-{
- ad1889_writel(chip, AD_DMA_ADCBA, address);
- ad1889_writel(chip, AD_DMA_ADCCA, address);
-}
-
-static inline void
-ad1889_load_adc_buffer_count(struct snd_ad1889 *chip, u32 count)
-{
- ad1889_writel(chip, AD_DMA_ADCBC, count);
- ad1889_writel(chip, AD_DMA_ADCCC, count);
-}
-
-static inline void
-ad1889_load_adc_interrupt_count(struct snd_ad1889 *chip, u32 count)
-{
- ad1889_writel(chip, AD_DMA_ADCIB, count);
- ad1889_writel(chip, AD_DMA_ADCIC, count);
-}
-
-static inline void
-ad1889_load_wave_buffer_address(struct snd_ad1889 *chip, u32 address)
-{
- ad1889_writel(chip, AD_DMA_WAVBA, address);
- ad1889_writel(chip, AD_DMA_WAVCA, address);
-}
-
-static inline void
-ad1889_load_wave_buffer_count(struct snd_ad1889 *chip, u32 count)
-{
- ad1889_writel(chip, AD_DMA_WAVBC, count);
- ad1889_writel(chip, AD_DMA_WAVCC, count);
-}
-
-static inline void
-ad1889_load_wave_interrupt_count(struct snd_ad1889 *chip, u32 count)
-{
- ad1889_writel(chip, AD_DMA_WAVIB, count);
- ad1889_writel(chip, AD_DMA_WAVIC, count);
-}
-
-static void
-ad1889_channel_reset(struct snd_ad1889 *chip, unsigned int channel)
-{
- u16 reg;
-
- if (channel & AD_CHAN_WAV) {
- /* Disable wave channel */
- reg = ad1889_readw(chip, AD_DS_WSMC) & ~AD_DS_WSMC_WAEN;
- ad1889_writew(chip, AD_DS_WSMC, reg);
- chip->wave.reg = reg;
-
- /* disable IRQs */
- reg = ad1889_readw(chip, AD_DMA_WAV);
- reg &= AD_DMA_IM_DIS;
- reg &= ~AD_DMA_LOOP;
- ad1889_writew(chip, AD_DMA_WAV, reg);
-
- /* clear IRQ and address counters and pointers */
- ad1889_load_wave_buffer_address(chip, 0x0);
- ad1889_load_wave_buffer_count(chip, 0x0);
- ad1889_load_wave_interrupt_count(chip, 0x0);
-
- /* flush */
- ad1889_readw(chip, AD_DMA_WAV);
- }
-
- if (channel & AD_CHAN_ADC) {
- /* Disable ADC channel */
- reg = ad1889_readw(chip, AD_DS_RAMC) & ~AD_DS_RAMC_ADEN;
- ad1889_writew(chip, AD_DS_RAMC, reg);
- chip->ramc.reg = reg;
-
- reg = ad1889_readw(chip, AD_DMA_ADC);
- reg &= AD_DMA_IM_DIS;
- reg &= ~AD_DMA_LOOP;
- ad1889_writew(chip, AD_DMA_ADC, reg);
-
- ad1889_load_adc_buffer_address(chip, 0x0);
- ad1889_load_adc_buffer_count(chip, 0x0);
- ad1889_load_adc_interrupt_count(chip, 0x0);
-
- /* flush */
- ad1889_readw(chip, AD_DMA_ADC);
- }
-}
-
-static u16
-snd_ad1889_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
-{
- struct snd_ad1889 *chip = ac97->private_data;
- return ad1889_readw(chip, AD_AC97_BASE + reg);
-}
-
-static void
-snd_ad1889_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
-{
- struct snd_ad1889 *chip = ac97->private_data;
- ad1889_writew(chip, AD_AC97_BASE + reg, val);
-}
-
-static int
-snd_ad1889_ac97_ready(struct snd_ad1889 *chip)
-{
- int retry = 400; /* average needs 352 msec */
-
- while (!(ad1889_readw(chip, AD_AC97_ACIC) & AD_AC97_ACIC_ACRDY)
- && --retry)
- mdelay(1);
- if (!retry) {
- snd_printk(KERN_ERR PFX "[%s] Link is not ready.\n",
- __func__);
- return -EIO;
- }
- ad1889_debug("[%s] ready after %d ms\n", __func__, 400 - retry);
-
- return 0;
-}
-
-static int
-snd_ad1889_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-}
-
-static int
-snd_ad1889_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static struct snd_pcm_hardware snd_ad1889_playback_hw = {
- .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 8000, /* docs say 7000, but we're lazy */
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = BUFFER_BYTES_MAX,
- .period_bytes_min = PERIOD_BYTES_MIN,
- .period_bytes_max = PERIOD_BYTES_MAX,
- .periods_min = PERIODS_MIN,
- .periods_max = PERIODS_MAX,
- /*.fifo_size = 0,*/
-};
-
-static struct snd_pcm_hardware snd_ad1889_capture_hw = {
- .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000, /* docs say we could to VSR, but we're lazy */
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = BUFFER_BYTES_MAX,
- .period_bytes_min = PERIOD_BYTES_MIN,
- .period_bytes_max = PERIOD_BYTES_MAX,
- .periods_min = PERIODS_MIN,
- .periods_max = PERIODS_MAX,
- /*.fifo_size = 0,*/
-};
-
-static int
-snd_ad1889_playback_open(struct snd_pcm_substream *ss)
-{
- struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
- struct snd_pcm_runtime *rt = ss->runtime;
-
- chip->psubs = ss;
- rt->hw = snd_ad1889_playback_hw;
-
- return 0;
-}
-
-static int
-snd_ad1889_capture_open(struct snd_pcm_substream *ss)
-{
- struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
- struct snd_pcm_runtime *rt = ss->runtime;
-
- chip->csubs = ss;
- rt->hw = snd_ad1889_capture_hw;
-
- return 0;
-}
-
-static int
-snd_ad1889_playback_close(struct snd_pcm_substream *ss)
-{
- struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
- chip->psubs = NULL;
- return 0;
-}
-
-static int
-snd_ad1889_capture_close(struct snd_pcm_substream *ss)
-{
- struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
- chip->csubs = NULL;
- return 0;
-}
-
-static int
-snd_ad1889_playback_prepare(struct snd_pcm_substream *ss)
-{
- struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
- struct snd_pcm_runtime *rt = ss->runtime;
- unsigned int size = snd_pcm_lib_buffer_bytes(ss);
- unsigned int count = snd_pcm_lib_period_bytes(ss);
- u16 reg;
-
- ad1889_channel_reset(chip, AD_CHAN_WAV);
-
- reg = ad1889_readw(chip, AD_DS_WSMC);
-
- /* Mask out 16-bit / Stereo */
- reg &= ~(AD_DS_WSMC_WA16 | AD_DS_WSMC_WAST);
-
- if (snd_pcm_format_width(rt->format) == 16)
- reg |= AD_DS_WSMC_WA16;
-
- if (rt->channels > 1)
- reg |= AD_DS_WSMC_WAST;
-
- /* let's make sure we don't clobber ourselves */
- spin_lock_irq(&chip->lock);
-
- chip->wave.size = size;
- chip->wave.reg = reg;
- chip->wave.addr = rt->dma_addr;
-
- ad1889_writew(chip, AD_DS_WSMC, chip->wave.reg);
-
- /* Set sample rates on the codec */
- ad1889_writew(chip, AD_DS_WAS, rt->rate);
-
- /* Set up DMA */
- ad1889_load_wave_buffer_address(chip, chip->wave.addr);
- ad1889_load_wave_buffer_count(chip, size);
- ad1889_load_wave_interrupt_count(chip, count);
-
- /* writes flush */
- ad1889_readw(chip, AD_DS_WSMC);
-
- spin_unlock_irq(&chip->lock);
-
- ad1889_debug("prepare playback: addr = 0x%x, count = %u, "
- "size = %u, reg = 0x%x, rate = %u\n", chip->wave.addr,
- count, size, reg, rt->rate);
- return 0;
-}
-
-static int
-snd_ad1889_capture_prepare(struct snd_pcm_substream *ss)
-{
- struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
- struct snd_pcm_runtime *rt = ss->runtime;
- unsigned int size = snd_pcm_lib_buffer_bytes(ss);
- unsigned int count = snd_pcm_lib_period_bytes(ss);
- u16 reg;
-
- ad1889_channel_reset(chip, AD_CHAN_ADC);
-
- reg = ad1889_readw(chip, AD_DS_RAMC);
-
- /* Mask out 16-bit / Stereo */
- reg &= ~(AD_DS_RAMC_AD16 | AD_DS_RAMC_ADST);
-
- if (snd_pcm_format_width(rt->format) == 16)
- reg |= AD_DS_RAMC_AD16;
-
- if (rt->channels > 1)
- reg |= AD_DS_RAMC_ADST;
-
- /* let's make sure we don't clobber ourselves */
- spin_lock_irq(&chip->lock);
-
- chip->ramc.size = size;
- chip->ramc.reg = reg;
- chip->ramc.addr = rt->dma_addr;
-
- ad1889_writew(chip, AD_DS_RAMC, chip->ramc.reg);
-
- /* Set up DMA */
- ad1889_load_adc_buffer_address(chip, chip->ramc.addr);
- ad1889_load_adc_buffer_count(chip, size);
- ad1889_load_adc_interrupt_count(chip, count);
-
- /* writes flush */
- ad1889_readw(chip, AD_DS_RAMC);
-
- spin_unlock_irq(&chip->lock);
-
- ad1889_debug("prepare capture: addr = 0x%x, count = %u, "
- "size = %u, reg = 0x%x, rate = %u\n", chip->ramc.addr,
- count, size, reg, rt->rate);
- return 0;
-}
-
-/* this is called in atomic context with IRQ disabled.
- Must be as fast as possible and not sleep.
- DMA should be *triggered* by this call.
- The WSMC "WAEN" bit triggers DMA Wave On/Off */
-static int
-snd_ad1889_playback_trigger(struct snd_pcm_substream *ss, int cmd)
-{
- u16 wsmc;
- struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
-
- wsmc = ad1889_readw(chip, AD_DS_WSMC);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- /* enable DMA loop & interrupts */
- ad1889_writew(chip, AD_DMA_WAV, AD_DMA_LOOP | AD_DMA_IM_CNT);
- wsmc |= AD_DS_WSMC_WAEN;
- /* 1 to clear CHSS bit */
- ad1889_writel(chip, AD_DMA_CHSS, AD_DMA_CHSS_WAVS);
- ad1889_unmute(chip);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- ad1889_mute(chip);
- wsmc &= ~AD_DS_WSMC_WAEN;
- break;
- default:
- snd_BUG();
- return -EINVAL;
- }
-
- chip->wave.reg = wsmc;
- ad1889_writew(chip, AD_DS_WSMC, wsmc);
- ad1889_readw(chip, AD_DS_WSMC); /* flush */
-
- /* reset the chip when STOP - will disable IRQs */
- if (cmd == SNDRV_PCM_TRIGGER_STOP)
- ad1889_channel_reset(chip, AD_CHAN_WAV);
-
- return 0;
-}
-
-/* this is called in atomic context with IRQ disabled.
- Must be as fast as possible and not sleep.
- DMA should be *triggered* by this call.
- The RAMC "ADEN" bit triggers DMA ADC On/Off */
-static int
-snd_ad1889_capture_trigger(struct snd_pcm_substream *ss, int cmd)
-{
- u16 ramc;
- struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
-
- ramc = ad1889_readw(chip, AD_DS_RAMC);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- /* enable DMA loop & interrupts */
- ad1889_writew(chip, AD_DMA_ADC, AD_DMA_LOOP | AD_DMA_IM_CNT);
- ramc |= AD_DS_RAMC_ADEN;
- /* 1 to clear CHSS bit */
- ad1889_writel(chip, AD_DMA_CHSS, AD_DMA_CHSS_ADCS);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- ramc &= ~AD_DS_RAMC_ADEN;
- break;
- default:
- return -EINVAL;
- }
-
- chip->ramc.reg = ramc;
- ad1889_writew(chip, AD_DS_RAMC, ramc);
- ad1889_readw(chip, AD_DS_RAMC); /* flush */
-
- /* reset the chip when STOP - will disable IRQs */
- if (cmd == SNDRV_PCM_TRIGGER_STOP)
- ad1889_channel_reset(chip, AD_CHAN_ADC);
-
- return 0;
-}
-
-/* Called in atomic context with IRQ disabled */
-static snd_pcm_uframes_t
-snd_ad1889_playback_pointer(struct snd_pcm_substream *ss)
-{
- size_t ptr = 0;
- struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
-
- if (unlikely(!(chip->wave.reg & AD_DS_WSMC_WAEN)))
- return 0;
-
- ptr = ad1889_readl(chip, AD_DMA_WAVCA);
- ptr -= chip->wave.addr;
-
- if (snd_BUG_ON(ptr >= chip->wave.size))
- return 0;
-
- return bytes_to_frames(ss->runtime, ptr);
-}
-
-/* Called in atomic context with IRQ disabled */
-static snd_pcm_uframes_t
-snd_ad1889_capture_pointer(struct snd_pcm_substream *ss)
-{
- size_t ptr = 0;
- struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
-
- if (unlikely(!(chip->ramc.reg & AD_DS_RAMC_ADEN)))
- return 0;
-
- ptr = ad1889_readl(chip, AD_DMA_ADCCA);
- ptr -= chip->ramc.addr;
-
- if (snd_BUG_ON(ptr >= chip->ramc.size))
- return 0;
-
- return bytes_to_frames(ss->runtime, ptr);
-}
-
-static struct snd_pcm_ops snd_ad1889_playback_ops = {
- .open = snd_ad1889_playback_open,
- .close = snd_ad1889_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ad1889_hw_params,
- .hw_free = snd_ad1889_hw_free,
- .prepare = snd_ad1889_playback_prepare,
- .trigger = snd_ad1889_playback_trigger,
- .pointer = snd_ad1889_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_ad1889_capture_ops = {
- .open = snd_ad1889_capture_open,
- .close = snd_ad1889_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ad1889_hw_params,
- .hw_free = snd_ad1889_hw_free,
- .prepare = snd_ad1889_capture_prepare,
- .trigger = snd_ad1889_capture_trigger,
- .pointer = snd_ad1889_capture_pointer,
-};
-
-static irqreturn_t
-snd_ad1889_interrupt(int irq, void *dev_id)
-{
- unsigned long st;
- struct snd_ad1889 *chip = dev_id;
-
- st = ad1889_readl(chip, AD_DMA_DISR);
-
- /* clear ISR */
- ad1889_writel(chip, AD_DMA_DISR, st);
-
- st &= AD_INTR_MASK;
-
- if (unlikely(!st))
- return IRQ_NONE;
-
- if (st & (AD_DMA_DISR_PMAI|AD_DMA_DISR_PTAI))
- ad1889_debug("Unexpected master or target abort interrupt!\n");
-
- if ((st & AD_DMA_DISR_WAVI) && chip->psubs)
- snd_pcm_period_elapsed(chip->psubs);
- if ((st & AD_DMA_DISR_ADCI) && chip->csubs)
- snd_pcm_period_elapsed(chip->csubs);
-
- return IRQ_HANDLED;
-}
-
-static int __devinit
-snd_ad1889_pcm_init(struct snd_ad1889 *chip, int device, struct snd_pcm **rpcm)
-{
- int err;
- struct snd_pcm *pcm;
-
- if (rpcm)
- *rpcm = NULL;
-
- err = snd_pcm_new(chip->card, chip->card->driver, device, 1, 1, &pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_ad1889_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_ad1889_capture_ops);
-
- pcm->private_data = chip;
- pcm->info_flags = 0;
- strcpy(pcm->name, chip->card->shortname);
-
- chip->pcm = pcm;
- chip->psubs = NULL;
- chip->csubs = NULL;
-
- err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- BUFFER_BYTES_MAX / 2,
- BUFFER_BYTES_MAX);
-
- if (err < 0) {
- snd_printk(KERN_ERR PFX "buffer allocation error: %d\n", err);
- return err;
- }
-
- if (rpcm)
- *rpcm = pcm;
-
- return 0;
-}
-
-static void
-snd_ad1889_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- struct snd_ad1889 *chip = entry->private_data;
- u16 reg;
- int tmp;
-
- reg = ad1889_readw(chip, AD_DS_WSMC);
- snd_iprintf(buffer, "Wave output: %s\n",
- (reg & AD_DS_WSMC_WAEN) ? "enabled" : "disabled");
- snd_iprintf(buffer, "Wave Channels: %s\n",
- (reg & AD_DS_WSMC_WAST) ? "stereo" : "mono");
- snd_iprintf(buffer, "Wave Quality: %d-bit linear\n",
- (reg & AD_DS_WSMC_WA16) ? 16 : 8);
-
- /* WARQ is at offset 12 */
- tmp = (reg & AD_DS_WSMC_WARQ) ?
- (((reg & AD_DS_WSMC_WARQ >> 12) & 0x01) ? 12 : 18) : 4;
- tmp /= (reg & AD_DS_WSMC_WAST) ? 2 : 1;
-
- snd_iprintf(buffer, "Wave FIFO: %d %s words\n\n", tmp,
- (reg & AD_DS_WSMC_WAST) ? "stereo" : "mono");
-
-
- snd_iprintf(buffer, "Synthesis output: %s\n",
- reg & AD_DS_WSMC_SYEN ? "enabled" : "disabled");
-
- /* SYRQ is at offset 4 */
- tmp = (reg & AD_DS_WSMC_SYRQ) ?
- (((reg & AD_DS_WSMC_SYRQ >> 4) & 0x01) ? 12 : 18) : 4;
- tmp /= (reg & AD_DS_WSMC_WAST) ? 2 : 1;
-
- snd_iprintf(buffer, "Synthesis FIFO: %d %s words\n\n", tmp,
- (reg & AD_DS_WSMC_WAST) ? "stereo" : "mono");
-
- reg = ad1889_readw(chip, AD_DS_RAMC);
- snd_iprintf(buffer, "ADC input: %s\n",
- (reg & AD_DS_RAMC_ADEN) ? "enabled" : "disabled");
- snd_iprintf(buffer, "ADC Channels: %s\n",
- (reg & AD_DS_RAMC_ADST) ? "stereo" : "mono");
- snd_iprintf(buffer, "ADC Quality: %d-bit linear\n",
- (reg & AD_DS_RAMC_AD16) ? 16 : 8);
-
- /* ACRQ is at offset 4 */
- tmp = (reg & AD_DS_RAMC_ACRQ) ?
- (((reg & AD_DS_RAMC_ACRQ >> 4) & 0x01) ? 12 : 18) : 4;
- tmp /= (reg & AD_DS_RAMC_ADST) ? 2 : 1;
-
- snd_iprintf(buffer, "ADC FIFO: %d %s words\n\n", tmp,
- (reg & AD_DS_RAMC_ADST) ? "stereo" : "mono");
-
- snd_iprintf(buffer, "Resampler input: %s\n",
- reg & AD_DS_RAMC_REEN ? "enabled" : "disabled");
-
- /* RERQ is at offset 12 */
- tmp = (reg & AD_DS_RAMC_RERQ) ?
- (((reg & AD_DS_RAMC_RERQ >> 12) & 0x01) ? 12 : 18) : 4;
- tmp /= (reg & AD_DS_RAMC_ADST) ? 2 : 1;
-
- snd_iprintf(buffer, "Resampler FIFO: %d %s words\n\n", tmp,
- (reg & AD_DS_WSMC_WAST) ? "stereo" : "mono");
-
-
- /* doc says LSB represents -1.5dB, but the max value (-94.5dB)
- suggests that LSB is -3dB, which is more coherent with the logarithmic
- nature of the dB scale */
- reg = ad1889_readw(chip, AD_DS_WADA);
- snd_iprintf(buffer, "Left: %s, -%d dB\n",
- (reg & AD_DS_WADA_LWAM) ? "mute" : "unmute",
- ((reg & AD_DS_WADA_LWAA) >> 8) * 3);
- reg = ad1889_readw(chip, AD_DS_WADA);
- snd_iprintf(buffer, "Right: %s, -%d dB\n",
- (reg & AD_DS_WADA_RWAM) ? "mute" : "unmute",
- ((reg & AD_DS_WADA_RWAA) >> 8) * 3);
-
- reg = ad1889_readw(chip, AD_DS_WAS);
- snd_iprintf(buffer, "Wave samplerate: %u Hz\n", reg);
- reg = ad1889_readw(chip, AD_DS_RES);
- snd_iprintf(buffer, "Resampler samplerate: %u Hz\n", reg);
-}
-
-static void __devinit
-snd_ad1889_proc_init(struct snd_ad1889 *chip)
-{
- struct snd_info_entry *entry;
-
- if (!snd_card_proc_new(chip->card, chip->card->driver, &entry))
- snd_info_set_text_ops(entry, chip, snd_ad1889_proc_read);
-}
-
-static struct ac97_quirk ac97_quirks[] = {
- {
- .subvendor = 0x11d4, /* AD */
- .subdevice = 0x1889, /* AD1889 */
- .codec_id = AC97_ID_AD1819,
- .name = "AD1889",
- .type = AC97_TUNE_HP_ONLY
- },
- { } /* terminator */
-};
-
-static void __devinit
-snd_ad1889_ac97_xinit(struct snd_ad1889 *chip)
-{
- u16 reg;
-
- reg = ad1889_readw(chip, AD_AC97_ACIC);
- reg |= AD_AC97_ACIC_ACRD; /* Reset Disable */
- ad1889_writew(chip, AD_AC97_ACIC, reg);
- ad1889_readw(chip, AD_AC97_ACIC); /* flush posted write */
- udelay(10);
- /* Interface Enable */
- reg |= AD_AC97_ACIC_ACIE;
- ad1889_writew(chip, AD_AC97_ACIC, reg);
-
- snd_ad1889_ac97_ready(chip);
-
- /* Audio Stream Output | Variable Sample Rate Mode */
- reg = ad1889_readw(chip, AD_AC97_ACIC);
- reg |= AD_AC97_ACIC_ASOE | AD_AC97_ACIC_VSRM;
- ad1889_writew(chip, AD_AC97_ACIC, reg);
- ad1889_readw(chip, AD_AC97_ACIC); /* flush posted write */
-
-}
-
-static void
-snd_ad1889_ac97_bus_free(struct snd_ac97_bus *bus)
-{
- struct snd_ad1889 *chip = bus->private_data;
- chip->ac97_bus = NULL;
-}
-
-static void
-snd_ad1889_ac97_free(struct snd_ac97 *ac97)
-{
- struct snd_ad1889 *chip = ac97->private_data;
- chip->ac97 = NULL;
-}
-
-static int __devinit
-snd_ad1889_ac97_init(struct snd_ad1889 *chip, const char *quirk_override)
-{
- int err;
- struct snd_ac97_template ac97;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_ad1889_ac97_write,
- .read = snd_ad1889_ac97_read,
- };
-
- /* doing that here, it works. */
- snd_ad1889_ac97_xinit(chip);
-
- err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus);
- if (err < 0)
- return err;
-
- chip->ac97_bus->private_free = snd_ad1889_ac97_bus_free;
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = chip;
- ac97.private_free = snd_ad1889_ac97_free;
- ac97.pci = chip->pci;
-
- err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97);
- if (err < 0)
- return err;
-
- snd_ac97_tune_hardware(chip->ac97, ac97_quirks, quirk_override);
-
- return 0;
-}
-
-static int
-snd_ad1889_free(struct snd_ad1889 *chip)
-{
- if (chip->irq < 0)
- goto skip_hw;
-
- spin_lock_irq(&chip->lock);
-
- ad1889_mute(chip);
-
- /* Turn off interrupt on count and zero DMA registers */
- ad1889_channel_reset(chip, AD_CHAN_WAV | AD_CHAN_ADC);
-
- /* clear DISR. If we don't, we'd better jump off the Eiffel Tower */
- ad1889_writel(chip, AD_DMA_DISR, AD_DMA_DISR_PTAI | AD_DMA_DISR_PMAI);
- ad1889_readl(chip, AD_DMA_DISR); /* flush, dammit! */
-
- spin_unlock_irq(&chip->lock);
-
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
-
-skip_hw:
- if (chip->iobase)
- iounmap(chip->iobase);
-
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
-
- kfree(chip);
- return 0;
-}
-
-static int
-snd_ad1889_dev_free(struct snd_device *device)
-{
- struct snd_ad1889 *chip = device->device_data;
- return snd_ad1889_free(chip);
-}
-
-static int __devinit
-snd_ad1889_init(struct snd_ad1889 *chip)
-{
- ad1889_writew(chip, AD_DS_CCS, AD_DS_CCS_CLKEN); /* turn on clock */
- ad1889_readw(chip, AD_DS_CCS); /* flush posted write */
-
- mdelay(10);
-
- /* enable Master and Target abort interrupts */
- ad1889_writel(chip, AD_DMA_DISR, AD_DMA_DISR_PMAE | AD_DMA_DISR_PTAE);
-
- return 0;
-}
-
-static int __devinit
-snd_ad1889_create(struct snd_card *card,
- struct pci_dev *pci,
- struct snd_ad1889 **rchip)
-{
- int err;
-
- struct snd_ad1889 *chip;
- static struct snd_device_ops ops = {
- .dev_free = snd_ad1889_dev_free,
- };
-
- *rchip = NULL;
-
- if ((err = pci_enable_device(pci)) < 0)
- return err;
-
- /* check PCI availability (32bit DMA) */
- if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0) {
- printk(KERN_ERR PFX "error setting 32-bit DMA mask.\n");
- pci_disable_device(pci);
- return -ENXIO;
- }
-
- /* allocate chip specific data with zero-filled memory */
- if ((chip = kzalloc(sizeof(*chip), GFP_KERNEL)) == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- chip->card = card;
- card->private_data = chip;
- chip->pci = pci;
- chip->irq = -1;
-
- /* (1) PCI resource allocation */
- if ((err = pci_request_regions(pci, card->driver)) < 0)
- goto free_and_ret;
-
- chip->bar = pci_resource_start(pci, 0);
- chip->iobase = pci_ioremap_bar(pci, 0);
- if (chip->iobase == NULL) {
- printk(KERN_ERR PFX "unable to reserve region.\n");
- err = -EBUSY;
- goto free_and_ret;
- }
-
- pci_set_master(pci);
-
- spin_lock_init(&chip->lock); /* only now can we call ad1889_free */
-
- if (request_irq(pci->irq, snd_ad1889_interrupt,
- IRQF_SHARED, KBUILD_MODNAME, chip)) {
- printk(KERN_ERR PFX "cannot obtain IRQ %d\n", pci->irq);
- snd_ad1889_free(chip);
- return -EBUSY;
- }
-
- chip->irq = pci->irq;
- synchronize_irq(chip->irq);
-
- /* (2) initialization of the chip hardware */
- if ((err = snd_ad1889_init(chip)) < 0) {
- snd_ad1889_free(chip);
- return err;
- }
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_ad1889_free(chip);
- return err;
- }
-
- snd_card_set_dev(card, &pci->dev);
-
- *rchip = chip;
-
- return 0;
-
-free_and_ret:
- kfree(chip);
- pci_disable_device(pci);
-
- return err;
-}
-
-static int __devinit
-snd_ad1889_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- int err;
- static int devno;
- struct snd_card *card;
- struct snd_ad1889 *chip;
-
- /* (1) */
- if (devno >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[devno]) {
- devno++;
- return -ENOENT;
- }
-
- /* (2) */
- err = snd_card_create(index[devno], id[devno], THIS_MODULE, 0, &card);
- /* XXX REVISIT: we can probably allocate chip in this call */
- if (err < 0)
- return err;
-
- strcpy(card->driver, "AD1889");
- strcpy(card->shortname, "Analog Devices AD1889");
-
- /* (3) */
- err = snd_ad1889_create(card, pci, &chip);
- if (err < 0)
- goto free_and_ret;
-
- /* (4) */
- sprintf(card->longname, "%s at 0x%lx irq %i",
- card->shortname, chip->bar, chip->irq);
-
- /* (5) */
- /* register AC97 mixer */
- err = snd_ad1889_ac97_init(chip, ac97_quirk[devno]);
- if (err < 0)
- goto free_and_ret;
-
- err = snd_ad1889_pcm_init(chip, 0, NULL);
- if (err < 0)
- goto free_and_ret;
-
- /* register proc interface */
- snd_ad1889_proc_init(chip);
-
- /* (6) */
- err = snd_card_register(card);
- if (err < 0)
- goto free_and_ret;
-
- /* (7) */
- pci_set_drvdata(pci, card);
-
- devno++;
- return 0;
-
-free_and_ret:
- snd_card_free(card);
- return err;
-}
-
-static void __devexit
-snd_ad1889_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static DEFINE_PCI_DEVICE_TABLE(snd_ad1889_ids) = {
- { PCI_DEVICE(PCI_VENDOR_ID_ANALOG_DEVICES, PCI_DEVICE_ID_AD1889JS) },
- { 0, },
-};
-MODULE_DEVICE_TABLE(pci, snd_ad1889_ids);
-
-static struct pci_driver ad1889_pci_driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_ad1889_ids,
- .probe = snd_ad1889_probe,
- .remove = __devexit_p(snd_ad1889_remove),
-};
-
-static int __init
-alsa_ad1889_init(void)
-{
- return pci_register_driver(&ad1889_pci_driver);
-}
-
-static void __exit
-alsa_ad1889_fini(void)
-{
- pci_unregister_driver(&ad1889_pci_driver);
-}
-
-module_init(alsa_ad1889_init);
-module_exit(alsa_ad1889_fini);
diff --git a/ANDROID_3.4.5/sound/pci/ad1889.h b/ANDROID_3.4.5/sound/pci/ad1889.h
deleted file mode 100644
index 5e6dad53..00000000
--- a/ANDROID_3.4.5/sound/pci/ad1889.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/* Analog Devices 1889 audio driver
- * Copyright (C) 2004, Kyle McMartin <kyle@parisc-linux.org>
- */
-
-#ifndef __AD1889_H__
-#define __AD1889_H__
-
-#define AD_DS_WSMC 0x00 /* wave/synthesis channel mixer control */
-#define AD_DS_WSMC_SYEN 0x0004 /* synthesis channel enable */
-#define AD_DS_WSMC_SYRQ 0x0030 /* synth. fifo request point */
-#define AD_DS_WSMC_WA16 0x0100 /* wave channel 16bit select */
-#define AD_DS_WSMC_WAST 0x0200 /* wave channel stereo select */
-#define AD_DS_WSMC_WAEN 0x0400 /* wave channel enable */
-#define AD_DS_WSMC_WARQ 0x3000 /* wave fifo request point */
-
-#define AD_DS_RAMC 0x02 /* resampler/ADC channel mixer control */
-#define AD_DS_RAMC_AD16 0x0001 /* ADC channel 16bit select */
-#define AD_DS_RAMC_ADST 0x0002 /* ADC channel stereo select */
-#define AD_DS_RAMC_ADEN 0x0004 /* ADC channel enable */
-#define AD_DS_RAMC_ACRQ 0x0030 /* ADC fifo request point */
-#define AD_DS_RAMC_REEN 0x0400 /* resampler channel enable */
-#define AD_DS_RAMC_RERQ 0x3000 /* res. fifo request point */
-
-#define AD_DS_WADA 0x04 /* wave channel mix attenuation */
-#define AD_DS_WADA_RWAM 0x0080 /* right wave mute */
-#define AD_DS_WADA_RWAA 0x001f /* right wave attenuation */
-#define AD_DS_WADA_LWAM 0x8000 /* left wave mute */
-#define AD_DS_WADA_LWAA 0x3e00 /* left wave attenuation */
-
-#define AD_DS_SYDA 0x06 /* synthesis channel mix attenuation */
-#define AD_DS_SYDA_RSYM 0x0080 /* right synthesis mute */
-#define AD_DS_SYDA_RSYA 0x001f /* right synthesis attenuation */
-#define AD_DS_SYDA_LSYM 0x8000 /* left synthesis mute */
-#define AD_DS_SYDA_LSYA 0x3e00 /* left synthesis attenuation */
-
-#define AD_DS_WAS 0x08 /* wave channel sample rate */
-#define AD_DS_WAS_WAS 0xffff /* sample rate mask */
-
-#define AD_DS_RES 0x0a /* resampler channel sample rate */
-#define AD_DS_RES_RES 0xffff /* sample rate mask */
-
-#define AD_DS_CCS 0x0c /* chip control/status */
-#define AD_DS_CCS_ADO 0x0001 /* ADC channel overflow */
-#define AD_DS_CCS_REO 0x0002 /* resampler channel overflow */
-#define AD_DS_CCS_SYU 0x0004 /* synthesis channel underflow */
-#define AD_DS_CCS_WAU 0x0008 /* wave channel underflow */
-/* bits 4 -> 7, 9, 11 -> 14 reserved */
-#define AD_DS_CCS_XTD 0x0100 /* xtd delay control (4096 clock cycles) */
-#define AD_DS_CCS_PDALL 0x0400 /* power */
-#define AD_DS_CCS_CLKEN 0x8000 /* clock */
-
-#define AD_DMA_RESBA 0x40 /* RES base address */
-#define AD_DMA_RESCA 0x44 /* RES current address */
-#define AD_DMA_RESBC 0x48 /* RES base count */
-#define AD_DMA_RESCC 0x4c /* RES current count */
-
-#define AD_DMA_ADCBA 0x50 /* ADC base address */
-#define AD_DMA_ADCCA 0x54 /* ADC current address */
-#define AD_DMA_ADCBC 0x58 /* ADC base count */
-#define AD_DMA_ADCCC 0x5c /* ADC current count */
-
-#define AD_DMA_SYNBA 0x60 /* synth base address */
-#define AD_DMA_SYNCA 0x64 /* synth current address */
-#define AD_DMA_SYNBC 0x68 /* synth base count */
-#define AD_DMA_SYNCC 0x6c /* synth current count */
-
-#define AD_DMA_WAVBA 0x70 /* wave base address */
-#define AD_DMA_WAVCA 0x74 /* wave current address */
-#define AD_DMA_WAVBC 0x78 /* wave base count */
-#define AD_DMA_WAVCC 0x7c /* wave current count */
-
-#define AD_DMA_RESIC 0x80 /* RES dma interrupt current byte count */
-#define AD_DMA_RESIB 0x84 /* RES dma interrupt base byte count */
-
-#define AD_DMA_ADCIC 0x88 /* ADC dma interrupt current byte count */
-#define AD_DMA_ADCIB 0x8c /* ADC dma interrupt base byte count */
-
-#define AD_DMA_SYNIC 0x90 /* synth dma interrupt current byte count */
-#define AD_DMA_SYNIB 0x94 /* synth dma interrupt base byte count */
-
-#define AD_DMA_WAVIC 0x98 /* wave dma interrupt current byte count */
-#define AD_DMA_WAVIB 0x9c /* wave dma interrupt base byte count */
-
-#define AD_DMA_ICC 0xffffff /* current byte count mask */
-#define AD_DMA_IBC 0xffffff /* base byte count mask */
-/* bits 24 -> 31 reserved */
-
-/* 4 bytes pad */
-#define AD_DMA_ADC 0xa8 /* ADC dma control and status */
-#define AD_DMA_SYNTH 0xb0 /* Synth dma control and status */
-#define AD_DMA_WAV 0xb8 /* wave dma control and status */
-#define AD_DMA_RES 0xa0 /* Resample dma control and status */
-
-#define AD_DMA_SGDE 0x0001 /* SGD mode enable */
-#define AD_DMA_LOOP 0x0002 /* loop enable */
-#define AD_DMA_IM 0x000c /* interrupt mode mask */
-#define AD_DMA_IM_DIS (~AD_DMA_IM) /* disable */
-#define AD_DMA_IM_CNT 0x0004 /* interrupt on count */
-#define AD_DMA_IM_SGD 0x0008 /* interrupt on SGD flag */
-#define AD_DMA_IM_EOL 0x000c /* interrupt on End of Linked List */
-#define AD_DMA_SGDS 0x0030 /* SGD status */
-#define AD_DMA_SFLG 0x0040 /* SGD flag */
-#define AD_DMA_EOL 0x0080 /* SGD end of list */
-/* bits 8 -> 15 reserved */
-
-#define AD_DMA_DISR 0xc0 /* dma interrupt status */
-#define AD_DMA_DISR_RESI 0x000001 /* resampler channel interrupt */
-#define AD_DMA_DISR_ADCI 0x000002 /* ADC channel interrupt */
-#define AD_DMA_DISR_SYNI 0x000004 /* synthesis channel interrupt */
-#define AD_DMA_DISR_WAVI 0x000008 /* wave channel interrupt */
-/* bits 4, 5 reserved */
-#define AD_DMA_DISR_SEPS 0x000040 /* serial eeprom status */
-/* bits 7 -> 13 reserved */
-#define AD_DMA_DISR_PMAI 0x004000 /* pci master abort interrupt */
-#define AD_DMA_DISR_PTAI 0x008000 /* pci target abort interrupt */
-#define AD_DMA_DISR_PTAE 0x010000 /* pci target abort interrupt enable */
-#define AD_DMA_DISR_PMAE 0x020000 /* pci master abort interrupt enable */
-/* bits 19 -> 31 reserved */
-
-/* interrupt mask */
-#define AD_INTR_MASK (AD_DMA_DISR_RESI|AD_DMA_DISR_ADCI| \
- AD_DMA_DISR_WAVI|AD_DMA_DISR_SYNI| \
- AD_DMA_DISR_PMAI|AD_DMA_DISR_PTAI)
-
-#define AD_DMA_CHSS 0xc4 /* dma channel stop status */
-#define AD_DMA_CHSS_RESS 0x000001 /* resampler channel stopped */
-#define AD_DMA_CHSS_ADCS 0x000002 /* ADC channel stopped */
-#define AD_DMA_CHSS_SYNS 0x000004 /* synthesis channel stopped */
-#define AD_DMA_CHSS_WAVS 0x000008 /* wave channel stopped */
-
-#define AD_GPIO_IPC 0xc8 /* gpio port control */
-#define AD_GPIO_OP 0xca /* gpio output port status */
-#define AD_GPIO_IP 0xcc /* gpio input port status */
-
-#define AD_AC97_BASE 0x100 /* ac97 base register */
-
-#define AD_AC97_RESET 0x100 /* reset */
-
-#define AD_AC97_PWR_CTL 0x126 /* == AC97_POWERDOWN */
-#define AD_AC97_PWR_ADC 0x0001 /* ADC ready status */
-#define AD_AC97_PWR_DAC 0x0002 /* DAC ready status */
-#define AD_AC97_PWR_PR0 0x0100 /* PR0 (ADC) powerdown */
-#define AD_AC97_PWR_PR1 0x0200 /* PR1 (DAC) powerdown */
-
-#define AD_MISC_CTL 0x176 /* misc control */
-#define AD_MISC_CTL_DACZ 0x8000 /* set for zero fill, unset for repeat */
-#define AD_MISC_CTL_ARSR 0x0001 /* set for SR1, unset for SR0 */
-#define AD_MISC_CTL_ALSR 0x0100
-#define AD_MISC_CTL_DLSR 0x0400
-#define AD_MISC_CTL_DRSR 0x0004
-
-#define AD_AC97_SR0 0x178 /* sample rate 0, 0xbb80 == 48K */
-#define AD_AC97_SR0_48K 0xbb80 /* 48KHz */
-#define AD_AC97_SR1 0x17a /* sample rate 1 */
-
-#define AD_AC97_ACIC 0x180 /* ac97 codec interface control */
-#define AD_AC97_ACIC_ACIE 0x0001 /* analog codec interface enable */
-#define AD_AC97_ACIC_ACRD 0x0002 /* analog codec reset disable */
-#define AD_AC97_ACIC_ASOE 0x0004 /* audio stream output enable */
-#define AD_AC97_ACIC_VSRM 0x0008 /* variable sample rate mode */
-#define AD_AC97_ACIC_FSDH 0x0100 /* force SDATA_OUT high */
-#define AD_AC97_ACIC_FSYH 0x0200 /* force sync high */
-#define AD_AC97_ACIC_ACRDY 0x8000 /* analog codec ready status */
-/* bits 10 -> 14 reserved */
-
-
-#define AD_DS_MEMSIZE 512
-#define AD_OPL_MEMSIZE 16
-#define AD_MIDI_MEMSIZE 16
-
-#define AD_WAV_STATE 0
-#define AD_ADC_STATE 1
-#define AD_MAX_STATES 2
-
-#define AD_CHAN_WAV 0x0001
-#define AD_CHAN_ADC 0x0002
-#define AD_CHAN_RES 0x0004
-#define AD_CHAN_SYN 0x0008
-
-
-/* The chip would support 4 GB buffers and 16 MB periods,
- * but let's not overdo it ... */
-#define BUFFER_BYTES_MAX (256 * 1024)
-#define PERIOD_BYTES_MIN 32
-#define PERIOD_BYTES_MAX (BUFFER_BYTES_MAX / 2)
-#define PERIODS_MIN 2
-#define PERIODS_MAX (BUFFER_BYTES_MAX / PERIOD_BYTES_MIN)
-
-#endif /* __AD1889_H__ */
diff --git a/ANDROID_3.4.5/sound/pci/ak4531_codec.c b/ANDROID_3.4.5/sound/pci/ak4531_codec.c
deleted file mode 100644
index cadf7b96..00000000
--- a/ANDROID_3.4.5/sound/pci/ak4531_codec.c
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Universal routines for AK4531 codec
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-#include <linux/module.h>
-
-#include <sound/core.h>
-#include <sound/ak4531_codec.h>
-#include <sound/tlv.h>
-
-/*
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Universal routines for AK4531 codec");
-MODULE_LICENSE("GPL");
-*/
-
-#ifdef CONFIG_PROC_FS
-static void snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak4531);
-#else
-#define snd_ak4531_proc_init(card,ak)
-#endif
-
-/*
- *
- */
-
-#if 0
-
-static void snd_ak4531_dump(struct snd_ak4531 *ak4531)
-{
- int idx;
-
- for (idx = 0; idx < 0x19; idx++)
- printk(KERN_DEBUG "ak4531 0x%x: 0x%x\n",
- idx, ak4531->regs[idx]);
-}
-
-#endif
-
-/*
- *
- */
-
-#define AK4531_SINGLE(xname, xindex, reg, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_ak4531_info_single, \
- .get = snd_ak4531_get_single, .put = snd_ak4531_put_single, \
- .private_value = reg | (shift << 16) | (mask << 24) | (invert << 22) }
-#define AK4531_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .name = xname, .index = xindex, \
- .info = snd_ak4531_info_single, \
- .get = snd_ak4531_get_single, .put = snd_ak4531_put_single, \
- .private_value = reg | (shift << 16) | (mask << 24) | (invert << 22), \
- .tlv = { .p = (xtlv) } }
-
-static int snd_ak4531_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 24) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_ak4531_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 16) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
- int val;
-
- mutex_lock(&ak4531->reg_mutex);
- val = (ak4531->regs[reg] >> shift) & mask;
- mutex_unlock(&ak4531->reg_mutex);
- if (invert) {
- val = mask - val;
- }
- ucontrol->value.integer.value[0] = val;
- return 0;
-}
-
-static int snd_ak4531_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 16) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
- int change;
- int val;
-
- val = ucontrol->value.integer.value[0] & mask;
- if (invert) {
- val = mask - val;
- }
- val <<= shift;
- mutex_lock(&ak4531->reg_mutex);
- val = (ak4531->regs[reg] & ~(mask << shift)) | val;
- change = val != ak4531->regs[reg];
- ak4531->write(ak4531, reg, ak4531->regs[reg] = val);
- mutex_unlock(&ak4531->reg_mutex);
- return change;
-}
-
-#define AK4531_DOUBLE(xname, xindex, left_reg, right_reg, left_shift, right_shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_ak4531_info_double, \
- .get = snd_ak4531_get_double, .put = snd_ak4531_put_double, \
- .private_value = left_reg | (right_reg << 8) | (left_shift << 16) | (right_shift << 19) | (mask << 24) | (invert << 22) }
-#define AK4531_DOUBLE_TLV(xname, xindex, left_reg, right_reg, left_shift, right_shift, mask, invert, xtlv) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .name = xname, .index = xindex, \
- .info = snd_ak4531_info_double, \
- .get = snd_ak4531_get_double, .put = snd_ak4531_put_double, \
- .private_value = left_reg | (right_reg << 8) | (left_shift << 16) | (right_shift << 19) | (mask << 24) | (invert << 22), \
- .tlv = { .p = (xtlv) } }
-
-static int snd_ak4531_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 24) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_ak4531_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol);
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int left_shift = (kcontrol->private_value >> 16) & 0x07;
- int right_shift = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
- int left, right;
-
- mutex_lock(&ak4531->reg_mutex);
- left = (ak4531->regs[left_reg] >> left_shift) & mask;
- right = (ak4531->regs[right_reg] >> right_shift) & mask;
- mutex_unlock(&ak4531->reg_mutex);
- if (invert) {
- left = mask - left;
- right = mask - right;
- }
- ucontrol->value.integer.value[0] = left;
- ucontrol->value.integer.value[1] = right;
- return 0;
-}
-
-static int snd_ak4531_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol);
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int left_shift = (kcontrol->private_value >> 16) & 0x07;
- int right_shift = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
- int change;
- int left, right;
-
- left = ucontrol->value.integer.value[0] & mask;
- right = ucontrol->value.integer.value[1] & mask;
- if (invert) {
- left = mask - left;
- right = mask - right;
- }
- left <<= left_shift;
- right <<= right_shift;
- mutex_lock(&ak4531->reg_mutex);
- if (left_reg == right_reg) {
- left = (ak4531->regs[left_reg] & ~((mask << left_shift) | (mask << right_shift))) | left | right;
- change = left != ak4531->regs[left_reg];
- ak4531->write(ak4531, left_reg, ak4531->regs[left_reg] = left);
- } else {
- left = (ak4531->regs[left_reg] & ~(mask << left_shift)) | left;
- right = (ak4531->regs[right_reg] & ~(mask << right_shift)) | right;
- change = left != ak4531->regs[left_reg] || right != ak4531->regs[right_reg];
- ak4531->write(ak4531, left_reg, ak4531->regs[left_reg] = left);
- ak4531->write(ak4531, right_reg, ak4531->regs[right_reg] = right);
- }
- mutex_unlock(&ak4531->reg_mutex);
- return change;
-}
-
-#define AK4531_INPUT_SW(xname, xindex, reg1, reg2, left_shift, right_shift) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_ak4531_info_input_sw, \
- .get = snd_ak4531_get_input_sw, .put = snd_ak4531_put_input_sw, \
- .private_value = reg1 | (reg2 << 8) | (left_shift << 16) | (right_shift << 24) }
-
-static int snd_ak4531_info_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 4;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int snd_ak4531_get_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol);
- int reg1 = kcontrol->private_value & 0xff;
- int reg2 = (kcontrol->private_value >> 8) & 0xff;
- int left_shift = (kcontrol->private_value >> 16) & 0x0f;
- int right_shift = (kcontrol->private_value >> 24) & 0x0f;
-
- mutex_lock(&ak4531->reg_mutex);
- ucontrol->value.integer.value[0] = (ak4531->regs[reg1] >> left_shift) & 1;
- ucontrol->value.integer.value[1] = (ak4531->regs[reg2] >> left_shift) & 1;
- ucontrol->value.integer.value[2] = (ak4531->regs[reg1] >> right_shift) & 1;
- ucontrol->value.integer.value[3] = (ak4531->regs[reg2] >> right_shift) & 1;
- mutex_unlock(&ak4531->reg_mutex);
- return 0;
-}
-
-static int snd_ak4531_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol);
- int reg1 = kcontrol->private_value & 0xff;
- int reg2 = (kcontrol->private_value >> 8) & 0xff;
- int left_shift = (kcontrol->private_value >> 16) & 0x0f;
- int right_shift = (kcontrol->private_value >> 24) & 0x0f;
- int change;
- int val1, val2;
-
- mutex_lock(&ak4531->reg_mutex);
- val1 = ak4531->regs[reg1] & ~((1 << left_shift) | (1 << right_shift));
- val2 = ak4531->regs[reg2] & ~((1 << left_shift) | (1 << right_shift));
- val1 |= (ucontrol->value.integer.value[0] & 1) << left_shift;
- val2 |= (ucontrol->value.integer.value[1] & 1) << left_shift;
- val1 |= (ucontrol->value.integer.value[2] & 1) << right_shift;
- val2 |= (ucontrol->value.integer.value[3] & 1) << right_shift;
- change = val1 != ak4531->regs[reg1] || val2 != ak4531->regs[reg2];
- ak4531->write(ak4531, reg1, ak4531->regs[reg1] = val1);
- ak4531->write(ak4531, reg2, ak4531->regs[reg2] = val2);
- mutex_unlock(&ak4531->reg_mutex);
- return change;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_master, -6200, 200, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_mono, -2800, 400, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_input, -5000, 200, 0);
-
-static struct snd_kcontrol_new snd_ak4531_controls[] __devinitdata = {
-
-AK4531_DOUBLE_TLV("Master Playback Switch", 0,
- AK4531_LMASTER, AK4531_RMASTER, 7, 7, 1, 1,
- db_scale_master),
-AK4531_DOUBLE("Master Playback Volume", 0, AK4531_LMASTER, AK4531_RMASTER, 0, 0, 0x1f, 1),
-
-AK4531_SINGLE_TLV("Master Mono Playback Switch", 0, AK4531_MONO_OUT, 7, 1, 1,
- db_scale_mono),
-AK4531_SINGLE("Master Mono Playback Volume", 0, AK4531_MONO_OUT, 0, 0x07, 1),
-
-AK4531_DOUBLE("PCM Switch", 0, AK4531_LVOICE, AK4531_RVOICE, 7, 7, 1, 1),
-AK4531_DOUBLE_TLV("PCM Volume", 0, AK4531_LVOICE, AK4531_RVOICE, 0, 0, 0x1f, 1,
- db_scale_input),
-AK4531_DOUBLE("PCM Playback Switch", 0, AK4531_OUT_SW2, AK4531_OUT_SW2, 3, 2, 1, 0),
-AK4531_DOUBLE("PCM Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 2, 2, 1, 0),
-
-AK4531_DOUBLE("PCM Switch", 1, AK4531_LFM, AK4531_RFM, 7, 7, 1, 1),
-AK4531_DOUBLE_TLV("PCM Volume", 1, AK4531_LFM, AK4531_RFM, 0, 0, 0x1f, 1,
- db_scale_input),
-AK4531_DOUBLE("PCM Playback Switch", 1, AK4531_OUT_SW1, AK4531_OUT_SW1, 6, 5, 1, 0),
-AK4531_INPUT_SW("PCM Capture Route", 1, AK4531_LIN_SW1, AK4531_RIN_SW1, 6, 5),
-
-AK4531_DOUBLE("CD Switch", 0, AK4531_LCD, AK4531_RCD, 7, 7, 1, 1),
-AK4531_DOUBLE_TLV("CD Volume", 0, AK4531_LCD, AK4531_RCD, 0, 0, 0x1f, 1,
- db_scale_input),
-AK4531_DOUBLE("CD Playback Switch", 0, AK4531_OUT_SW1, AK4531_OUT_SW1, 2, 1, 1, 0),
-AK4531_INPUT_SW("CD Capture Route", 0, AK4531_LIN_SW1, AK4531_RIN_SW1, 2, 1),
-
-AK4531_DOUBLE("Line Switch", 0, AK4531_LLINE, AK4531_RLINE, 7, 7, 1, 1),
-AK4531_DOUBLE_TLV("Line Volume", 0, AK4531_LLINE, AK4531_RLINE, 0, 0, 0x1f, 1,
- db_scale_input),
-AK4531_DOUBLE("Line Playback Switch", 0, AK4531_OUT_SW1, AK4531_OUT_SW1, 4, 3, 1, 0),
-AK4531_INPUT_SW("Line Capture Route", 0, AK4531_LIN_SW1, AK4531_RIN_SW1, 4, 3),
-
-AK4531_DOUBLE("Aux Switch", 0, AK4531_LAUXA, AK4531_RAUXA, 7, 7, 1, 1),
-AK4531_DOUBLE_TLV("Aux Volume", 0, AK4531_LAUXA, AK4531_RAUXA, 0, 0, 0x1f, 1,
- db_scale_input),
-AK4531_DOUBLE("Aux Playback Switch", 0, AK4531_OUT_SW2, AK4531_OUT_SW2, 5, 4, 1, 0),
-AK4531_INPUT_SW("Aux Capture Route", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 4, 3),
-
-AK4531_SINGLE("Mono Switch", 0, AK4531_MONO1, 7, 1, 1),
-AK4531_SINGLE_TLV("Mono Volume", 0, AK4531_MONO1, 0, 0x1f, 1, db_scale_input),
-AK4531_SINGLE("Mono Playback Switch", 0, AK4531_OUT_SW2, 0, 1, 0),
-AK4531_DOUBLE("Mono Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 0, 0, 1, 0),
-
-AK4531_SINGLE("Mono Switch", 1, AK4531_MONO2, 7, 1, 1),
-AK4531_SINGLE_TLV("Mono Volume", 1, AK4531_MONO2, 0, 0x1f, 1, db_scale_input),
-AK4531_SINGLE("Mono Playback Switch", 1, AK4531_OUT_SW2, 1, 1, 0),
-AK4531_DOUBLE("Mono Capture Switch", 1, AK4531_LIN_SW2, AK4531_RIN_SW2, 1, 1, 1, 0),
-
-AK4531_SINGLE_TLV("Mic Volume", 0, AK4531_MIC, 0, 0x1f, 1, db_scale_input),
-AK4531_SINGLE("Mic Switch", 0, AK4531_MIC, 7, 1, 1),
-AK4531_SINGLE("Mic Playback Switch", 0, AK4531_OUT_SW1, 0, 1, 0),
-AK4531_DOUBLE("Mic Capture Switch", 0, AK4531_LIN_SW1, AK4531_RIN_SW1, 0, 0, 1, 0),
-
-AK4531_DOUBLE("Mic Bypass Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 7, 7, 1, 0),
-AK4531_DOUBLE("Mono1 Bypass Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 6, 6, 1, 0),
-AK4531_DOUBLE("Mono2 Bypass Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 5, 5, 1, 0),
-
-AK4531_SINGLE("AD Input Select", 0, AK4531_AD_IN, 0, 1, 0),
-AK4531_SINGLE("Mic Boost (+30dB)", 0, AK4531_MIC_GAIN, 0, 1, 0)
-};
-
-static int snd_ak4531_free(struct snd_ak4531 *ak4531)
-{
- if (ak4531) {
- if (ak4531->private_free)
- ak4531->private_free(ak4531);
- kfree(ak4531);
- }
- return 0;
-}
-
-static int snd_ak4531_dev_free(struct snd_device *device)
-{
- struct snd_ak4531 *ak4531 = device->device_data;
- return snd_ak4531_free(ak4531);
-}
-
-static u8 snd_ak4531_initial_map[0x19 + 1] = {
- 0x9f, /* 00: Master Volume Lch */
- 0x9f, /* 01: Master Volume Rch */
- 0x9f, /* 02: Voice Volume Lch */
- 0x9f, /* 03: Voice Volume Rch */
- 0x9f, /* 04: FM Volume Lch */
- 0x9f, /* 05: FM Volume Rch */
- 0x9f, /* 06: CD Audio Volume Lch */
- 0x9f, /* 07: CD Audio Volume Rch */
- 0x9f, /* 08: Line Volume Lch */
- 0x9f, /* 09: Line Volume Rch */
- 0x9f, /* 0a: Aux Volume Lch */
- 0x9f, /* 0b: Aux Volume Rch */
- 0x9f, /* 0c: Mono1 Volume */
- 0x9f, /* 0d: Mono2 Volume */
- 0x9f, /* 0e: Mic Volume */
- 0x87, /* 0f: Mono-out Volume */
- 0x00, /* 10: Output Mixer SW1 */
- 0x00, /* 11: Output Mixer SW2 */
- 0x00, /* 12: Lch Input Mixer SW1 */
- 0x00, /* 13: Rch Input Mixer SW1 */
- 0x00, /* 14: Lch Input Mixer SW2 */
- 0x00, /* 15: Rch Input Mixer SW2 */
- 0x00, /* 16: Reset & Power Down */
- 0x00, /* 17: Clock Select */
- 0x00, /* 18: AD Input Select */
- 0x01 /* 19: Mic Amp Setup */
-};
-
-int __devinit snd_ak4531_mixer(struct snd_card *card,
- struct snd_ak4531 *_ak4531,
- struct snd_ak4531 **rak4531)
-{
- unsigned int idx;
- int err;
- struct snd_ak4531 *ak4531;
- static struct snd_device_ops ops = {
- .dev_free = snd_ak4531_dev_free,
- };
-
- if (snd_BUG_ON(!card || !_ak4531))
- return -EINVAL;
- if (rak4531)
- *rak4531 = NULL;
- ak4531 = kzalloc(sizeof(*ak4531), GFP_KERNEL);
- if (ak4531 == NULL)
- return -ENOMEM;
- *ak4531 = *_ak4531;
- mutex_init(&ak4531->reg_mutex);
- if ((err = snd_component_add(card, "AK4531")) < 0) {
- snd_ak4531_free(ak4531);
- return err;
- }
- strcpy(card->mixername, "Asahi Kasei AK4531");
- ak4531->write(ak4531, AK4531_RESET, 0x03); /* no RST, PD */
- udelay(100);
- ak4531->write(ak4531, AK4531_CLOCK, 0x00); /* CODEC ADC and CODEC DAC use {LR,B}CLK2 and run off LRCLK2 PLL */
- for (idx = 0; idx <= 0x19; idx++) {
- if (idx == AK4531_RESET || idx == AK4531_CLOCK)
- continue;
- ak4531->write(ak4531, idx, ak4531->regs[idx] = snd_ak4531_initial_map[idx]); /* recording source is mixer */
- }
- for (idx = 0; idx < ARRAY_SIZE(snd_ak4531_controls); idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_ak4531_controls[idx], ak4531))) < 0) {
- snd_ak4531_free(ak4531);
- return err;
- }
- }
- snd_ak4531_proc_init(card, ak4531);
- if ((err = snd_device_new(card, SNDRV_DEV_CODEC, ak4531, &ops)) < 0) {
- snd_ak4531_free(ak4531);
- return err;
- }
-
-#if 0
- snd_ak4531_dump(ak4531);
-#endif
- if (rak4531)
- *rak4531 = ak4531;
- return 0;
-}
-
-/*
- * power management
- */
-#ifdef CONFIG_PM
-void snd_ak4531_suspend(struct snd_ak4531 *ak4531)
-{
- /* mute */
- ak4531->write(ak4531, AK4531_LMASTER, 0x9f);
- ak4531->write(ak4531, AK4531_RMASTER, 0x9f);
- /* powerdown */
- ak4531->write(ak4531, AK4531_RESET, 0x01);
-}
-
-void snd_ak4531_resume(struct snd_ak4531 *ak4531)
-{
- int idx;
-
- /* initialize */
- ak4531->write(ak4531, AK4531_RESET, 0x03);
- udelay(100);
- ak4531->write(ak4531, AK4531_CLOCK, 0x00);
- /* restore mixer registers */
- for (idx = 0; idx <= 0x19; idx++) {
- if (idx == AK4531_RESET || idx == AK4531_CLOCK)
- continue;
- ak4531->write(ak4531, idx, ak4531->regs[idx]);
- }
-}
-#endif
-
-#ifdef CONFIG_PROC_FS
-/*
- * /proc interface
- */
-
-static void snd_ak4531_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_ak4531 *ak4531 = entry->private_data;
-
- snd_iprintf(buffer, "Asahi Kasei AK4531\n\n");
- snd_iprintf(buffer, "Recording source : %s\n"
- "MIC gain : %s\n",
- ak4531->regs[AK4531_AD_IN] & 1 ? "external" : "mixer",
- ak4531->regs[AK4531_MIC_GAIN] & 1 ? "+30dB" : "+0dB");
-}
-
-static void __devinit
-snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak4531)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(card, "ak4531", &entry))
- snd_info_set_text_ops(entry, ak4531, snd_ak4531_proc_read);
-}
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/ali5451/Makefile b/ANDROID_3.4.5/sound/pci/ali5451/Makefile
deleted file mode 100644
index 713459c1..00000000
--- a/ANDROID_3.4.5/sound/pci/ali5451/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-ali5451-objs := ali5451.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_ALI5451) += snd-ali5451.o
diff --git a/ANDROID_3.4.5/sound/pci/ali5451/ali5451.c b/ANDROID_3.4.5/sound/pci/ali5451/ali5451.c
deleted file mode 100644
index bdd6164e..00000000
--- a/ANDROID_3.4.5/sound/pci/ali5451/ali5451.c
+++ /dev/null
@@ -1,2319 +0,0 @@
-/*
- * Matt Wu <Matt_Wu@acersoftech.com.cn>
- * Apr 26, 2001
- * Routines for control of ALi pci audio M5451
- *
- * BUGS:
- * --
- *
- * TODO:
- * --
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public Lcodecnse as published by
- * the Free Software Foundation; either version 2 of the Lcodecnse, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public Lcodecnse for more details.
- *
- * You should have received a copy of the GNU General Public Lcodecnse
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/info.h>
-#include <sound/ac97_codec.h>
-#include <sound/mpu401.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Matt Wu <Matt_Wu@acersoftech.com.cn>");
-MODULE_DESCRIPTION("ALI M5451");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ALI,M5451,pci},{ALI,M5451}}");
-
-static int index = SNDRV_DEFAULT_IDX1; /* Index */
-static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-static int pcm_channels = 32;
-static bool spdif;
-
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for ALI M5451 PCI Audio.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for ALI M5451 PCI Audio.");
-module_param(pcm_channels, int, 0444);
-MODULE_PARM_DESC(pcm_channels, "PCM Channels");
-module_param(spdif, bool, 0444);
-MODULE_PARM_DESC(spdif, "Support SPDIF I/O");
-
-/* just for backward compatibility */
-static bool enable;
-module_param(enable, bool, 0444);
-
-
-/*
- * Debug part definitions
- */
-
-/* #define ALI_DEBUG */
-
-#ifdef ALI_DEBUG
-#define snd_ali_printk(format, args...) printk(KERN_DEBUG format, ##args);
-#else
-#define snd_ali_printk(format, args...)
-#endif
-
-/*
- * Constants definition
- */
-
-#define DEVICE_ID_ALI5451 ((PCI_VENDOR_ID_AL<<16)|PCI_DEVICE_ID_AL_M5451)
-
-
-#define ALI_CHANNELS 32
-
-#define ALI_PCM_IN_CHANNEL 31
-#define ALI_SPDIF_IN_CHANNEL 19
-#define ALI_SPDIF_OUT_CHANNEL 15
-#define ALI_CENTER_CHANNEL 24
-#define ALI_LEF_CHANNEL 23
-#define ALI_SURR_LEFT_CHANNEL 26
-#define ALI_SURR_RIGHT_CHANNEL 25
-#define ALI_MODEM_IN_CHANNEL 21
-#define ALI_MODEM_OUT_CHANNEL 20
-
-#define SNDRV_ALI_VOICE_TYPE_PCM 01
-#define SNDRV_ALI_VOICE_TYPE_OTH 02
-
-#define ALI_5451_V02 0x02
-
-/*
- * Direct Registers
- */
-
-#define ALI_LEGACY_DMAR0 0x00 /* ADR0 */
-#define ALI_LEGACY_DMAR4 0x04 /* CNT0 */
-#define ALI_LEGACY_DMAR11 0x0b /* MOD */
-#define ALI_LEGACY_DMAR15 0x0f /* MMR */
-#define ALI_MPUR0 0x20
-#define ALI_MPUR1 0x21
-#define ALI_MPUR2 0x22
-#define ALI_MPUR3 0x23
-
-#define ALI_AC97_WRITE 0x40
-#define ALI_AC97_READ 0x44
-
-#define ALI_SCTRL 0x48
-#define ALI_SPDIF_OUT_ENABLE 0x20
-#define ALI_SCTRL_LINE_IN2 (1 << 9)
-#define ALI_SCTRL_GPIO_IN2 (1 << 13)
-#define ALI_SCTRL_LINE_OUT_EN (1 << 20)
-#define ALI_SCTRL_GPIO_OUT_EN (1 << 23)
-#define ALI_SCTRL_CODEC1_READY (1 << 24)
-#define ALI_SCTRL_CODEC2_READY (1 << 25)
-#define ALI_AC97_GPIO 0x4c
-#define ALI_AC97_GPIO_ENABLE 0x8000
-#define ALI_AC97_GPIO_DATA_SHIFT 16
-#define ALI_SPDIF_CS 0x70
-#define ALI_SPDIF_CTRL 0x74
-#define ALI_SPDIF_IN_FUNC_ENABLE 0x02
-#define ALI_SPDIF_IN_CH_STATUS 0x40
-#define ALI_SPDIF_OUT_CH_STATUS 0xbf
-#define ALI_START 0x80
-#define ALI_STOP 0x84
-#define ALI_CSPF 0x90
-#define ALI_AINT 0x98
-#define ALI_GC_CIR 0xa0
- #define ENDLP_IE 0x00001000
- #define MIDLP_IE 0x00002000
-#define ALI_AINTEN 0xa4
-#define ALI_VOLUME 0xa8
-#define ALI_SBDELTA_DELTA_R 0xac
-#define ALI_MISCINT 0xb0
- #define ADDRESS_IRQ 0x00000020
- #define TARGET_REACHED 0x00008000
- #define MIXER_OVERFLOW 0x00000800
- #define MIXER_UNDERFLOW 0x00000400
- #define GPIO_IRQ 0x01000000
-#define ALI_SBBL_SBCL 0xc0
-#define ALI_SBCTRL_SBE2R_SBDD 0xc4
-#define ALI_STIMER 0xc8
-#define ALI_GLOBAL_CONTROL 0xd4
-#define ALI_SPDIF_OUT_SEL_PCM 0x00000400 /* bit 10 */
-#define ALI_SPDIF_IN_SUPPORT 0x00000800 /* bit 11 */
-#define ALI_SPDIF_OUT_CH_ENABLE 0x00008000 /* bit 15 */
-#define ALI_SPDIF_IN_CH_ENABLE 0x00080000 /* bit 19 */
-#define ALI_PCM_IN_ENABLE 0x80000000 /* bit 31 */
-
-#define ALI_CSO_ALPHA_FMS 0xe0
-#define ALI_LBA 0xe4
-#define ALI_ESO_DELTA 0xe8
-#define ALI_GVSEL_PAN_VOC_CTRL_EC 0xf0
-#define ALI_EBUF1 0xf4
-#define ALI_EBUF2 0xf8
-
-#define ALI_REG(codec, x) ((codec)->port + x)
-
-#define MAX_CODECS 2
-
-
-struct snd_ali;
-struct snd_ali_voice;
-
-struct snd_ali_channel_control {
- /* register data */
- struct REGDATA {
- unsigned int start;
- unsigned int stop;
- unsigned int aint;
- unsigned int ainten;
- } data;
-
- /* register addresses */
- struct REGS {
- unsigned int start;
- unsigned int stop;
- unsigned int aint;
- unsigned int ainten;
- unsigned int ac97read;
- unsigned int ac97write;
- } regs;
-
-};
-
-struct snd_ali_voice {
- unsigned int number;
- unsigned int use :1,
- pcm :1,
- midi :1,
- mode :1,
- synth :1,
- running :1;
-
- /* PCM data */
- struct snd_ali *codec;
- struct snd_pcm_substream *substream;
- struct snd_ali_voice *extra;
-
- int eso; /* final ESO value for channel */
- int count; /* runtime->period_size */
-
- /* --- */
-
- void *private_data;
- void (*private_free)(void *private_data);
-};
-
-
-struct snd_alidev {
-
- struct snd_ali_voice voices[ALI_CHANNELS];
-
- unsigned int chcnt; /* num of opened channels */
- unsigned int chmap; /* bitmap for opened channels */
- unsigned int synthcount;
-
-};
-
-
-#define ALI_GLOBAL_REGS 56
-#define ALI_CHANNEL_REGS 8
-struct snd_ali_image {
- u32 regs[ALI_GLOBAL_REGS];
- u32 channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS];
-};
-
-
-struct snd_ali {
- int irq;
- unsigned long port;
- unsigned char revision;
-
- unsigned int hw_initialized :1;
- unsigned int spdif_support :1;
-
- struct pci_dev *pci;
- struct pci_dev *pci_m1533;
- struct pci_dev *pci_m7101;
-
- struct snd_card *card;
- struct snd_pcm *pcm[MAX_CODECS];
- struct snd_alidev synth;
- struct snd_ali_channel_control chregs;
-
- /* S/PDIF Mask */
- unsigned int spdif_mask;
-
- unsigned int spurious_irq_count;
- unsigned int spurious_irq_max_delta;
-
- unsigned int num_of_codecs;
-
- struct snd_ac97_bus *ac97_bus;
- struct snd_ac97 *ac97[MAX_CODECS];
- unsigned short ac97_ext_id;
- unsigned short ac97_ext_status;
-
- spinlock_t reg_lock;
- spinlock_t voice_alloc;
-
-#ifdef CONFIG_PM
- struct snd_ali_image *image;
-#endif
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_ali_ids) = {
- {PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5451), 0, 0, 0},
- {0, }
-};
-MODULE_DEVICE_TABLE(pci, snd_ali_ids);
-
-static void snd_ali_clear_voices(struct snd_ali *, unsigned int, unsigned int);
-static unsigned short snd_ali_codec_peek(struct snd_ali *, int, unsigned short);
-static void snd_ali_codec_poke(struct snd_ali *, int, unsigned short,
- unsigned short);
-
-/*
- * AC97 ACCESS
- */
-
-static inline unsigned int snd_ali_5451_peek(struct snd_ali *codec,
- unsigned int port)
-{
- return (unsigned int)inl(ALI_REG(codec, port));
-}
-
-static inline void snd_ali_5451_poke(struct snd_ali *codec,
- unsigned int port,
- unsigned int val)
-{
- outl((unsigned int)val, ALI_REG(codec, port));
-}
-
-static int snd_ali_codec_ready(struct snd_ali *codec,
- unsigned int port)
-{
- unsigned long end_time;
- unsigned int res;
-
- end_time = jiffies + msecs_to_jiffies(250);
-
- for (;;) {
- res = snd_ali_5451_peek(codec,port);
- if (!(res & 0x8000))
- return 0;
- if (!time_after_eq(end_time, jiffies))
- break;
- schedule_timeout_uninterruptible(1);
- }
-
- snd_ali_5451_poke(codec, port, res & ~0x8000);
- snd_printdd("ali_codec_ready: codec is not ready.\n ");
- return -EIO;
-}
-
-static int snd_ali_stimer_ready(struct snd_ali *codec)
-{
- unsigned long end_time;
- unsigned long dwChk1,dwChk2;
-
- dwChk1 = snd_ali_5451_peek(codec, ALI_STIMER);
- end_time = jiffies + msecs_to_jiffies(250);
-
- for (;;) {
- dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER);
- if (dwChk2 != dwChk1)
- return 0;
- if (!time_after_eq(end_time, jiffies))
- break;
- schedule_timeout_uninterruptible(1);
- }
-
- snd_printk(KERN_ERR "ali_stimer_read: stimer is not ready.\n");
- return -EIO;
-}
-
-static void snd_ali_codec_poke(struct snd_ali *codec,int secondary,
- unsigned short reg,
- unsigned short val)
-{
- unsigned int dwVal;
- unsigned int port;
-
- if (reg >= 0x80) {
- snd_printk(KERN_ERR "ali_codec_poke: reg(%xh) invalid.\n", reg);
- return;
- }
-
- port = codec->chregs.regs.ac97write;
-
- if (snd_ali_codec_ready(codec, port) < 0)
- return;
- if (snd_ali_stimer_ready(codec) < 0)
- return;
-
- dwVal = (unsigned int) (reg & 0xff);
- dwVal |= 0x8000 | (val << 16);
- if (secondary)
- dwVal |= 0x0080;
- if (codec->revision == ALI_5451_V02)
- dwVal |= 0x0100;
-
- snd_ali_5451_poke(codec, port, dwVal);
-
- return ;
-}
-
-static unsigned short snd_ali_codec_peek(struct snd_ali *codec,
- int secondary,
- unsigned short reg)
-{
- unsigned int dwVal;
- unsigned int port;
-
- if (reg >= 0x80) {
- snd_printk(KERN_ERR "ali_codec_peek: reg(%xh) invalid.\n", reg);
- return ~0;
- }
-
- port = codec->chregs.regs.ac97read;
-
- if (snd_ali_codec_ready(codec, port) < 0)
- return ~0;
- if (snd_ali_stimer_ready(codec) < 0)
- return ~0;
-
- dwVal = (unsigned int) (reg & 0xff);
- dwVal |= 0x8000; /* bit 15*/
- if (secondary)
- dwVal |= 0x0080;
-
- snd_ali_5451_poke(codec, port, dwVal);
-
- if (snd_ali_stimer_ready(codec) < 0)
- return ~0;
- if (snd_ali_codec_ready(codec, port) < 0)
- return ~0;
-
- return (snd_ali_5451_peek(codec, port) & 0xffff0000) >> 16;
-}
-
-static void snd_ali_codec_write(struct snd_ac97 *ac97,
- unsigned short reg,
- unsigned short val )
-{
- struct snd_ali *codec = ac97->private_data;
-
- snd_ali_printk("codec_write: reg=%xh data=%xh.\n", reg, val);
- if (reg == AC97_GPIO_STATUS) {
- outl((val << ALI_AC97_GPIO_DATA_SHIFT) | ALI_AC97_GPIO_ENABLE,
- ALI_REG(codec, ALI_AC97_GPIO));
- return;
- }
- snd_ali_codec_poke(codec, ac97->num, reg, val);
- return ;
-}
-
-
-static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- struct snd_ali *codec = ac97->private_data;
-
- snd_ali_printk("codec_read reg=%xh.\n", reg);
- return snd_ali_codec_peek(codec, ac97->num, reg);
-}
-
-/*
- * AC97 Reset
- */
-
-static int snd_ali_reset_5451(struct snd_ali *codec)
-{
- struct pci_dev *pci_dev;
- unsigned short wCount, wReg;
- unsigned int dwVal;
-
- pci_dev = codec->pci_m1533;
- if (pci_dev) {
- pci_read_config_dword(pci_dev, 0x7c, &dwVal);
- pci_write_config_dword(pci_dev, 0x7c, dwVal | 0x08000000);
- udelay(5000);
- pci_read_config_dword(pci_dev, 0x7c, &dwVal);
- pci_write_config_dword(pci_dev, 0x7c, dwVal & 0xf7ffffff);
- udelay(5000);
- }
-
- pci_dev = codec->pci;
- pci_read_config_dword(pci_dev, 0x44, &dwVal);
- pci_write_config_dword(pci_dev, 0x44, dwVal | 0x000c0000);
- udelay(500);
- pci_read_config_dword(pci_dev, 0x44, &dwVal);
- pci_write_config_dword(pci_dev, 0x44, dwVal & 0xfffbffff);
- udelay(5000);
-
- wCount = 200;
- while(wCount--) {
- wReg = snd_ali_codec_peek(codec, 0, AC97_POWERDOWN);
- if ((wReg & 0x000f) == 0x000f)
- return 0;
- udelay(5000);
- }
-
- /* non-fatal if you have a non PM capable codec */
- /* snd_printk(KERN_WARNING "ali5451: reset time out\n"); */
- return 0;
-}
-
-/*
- * ALI 5451 Controller
- */
-
-static void snd_ali_enable_special_channel(struct snd_ali *codec,
- unsigned int channel)
-{
- unsigned long dwVal;
-
- dwVal = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL));
- dwVal |= 1 << (channel & 0x0000001f);
- outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
-}
-
-static void snd_ali_disable_special_channel(struct snd_ali *codec,
- unsigned int channel)
-{
- unsigned long dwVal;
-
- dwVal = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL));
- dwVal &= ~(1 << (channel & 0x0000001f));
- outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
-}
-
-static void snd_ali_enable_address_interrupt(struct snd_ali *codec)
-{
- unsigned int gc;
-
- gc = inl(ALI_REG(codec, ALI_GC_CIR));
- gc |= ENDLP_IE;
- gc |= MIDLP_IE;
- outl( gc, ALI_REG(codec, ALI_GC_CIR));
-}
-
-static void snd_ali_disable_address_interrupt(struct snd_ali *codec)
-{
- unsigned int gc;
-
- gc = inl(ALI_REG(codec, ALI_GC_CIR));
- gc &= ~ENDLP_IE;
- gc &= ~MIDLP_IE;
- outl(gc, ALI_REG(codec, ALI_GC_CIR));
-}
-
-static void snd_ali_disable_voice_irq(struct snd_ali *codec,
- unsigned int channel)
-{
- unsigned int mask;
- struct snd_ali_channel_control *pchregs = &(codec->chregs);
-
- snd_ali_printk("disable_voice_irq channel=%d\n",channel);
-
- mask = 1 << (channel & 0x1f);
- pchregs->data.ainten = inl(ALI_REG(codec, pchregs->regs.ainten));
- pchregs->data.ainten &= ~mask;
- outl(pchregs->data.ainten, ALI_REG(codec, pchregs->regs.ainten));
-}
-
-static int snd_ali_alloc_pcm_channel(struct snd_ali *codec, int channel)
-{
- unsigned int idx = channel & 0x1f;
-
- if (codec->synth.chcnt >= ALI_CHANNELS){
- snd_printk(KERN_ERR
- "ali_alloc_pcm_channel: no free channels.\n");
- return -1;
- }
-
- if (!(codec->synth.chmap & (1 << idx))) {
- codec->synth.chmap |= 1 << idx;
- codec->synth.chcnt++;
- snd_ali_printk("alloc_pcm_channel no. %d.\n",idx);
- return idx;
- }
- return -1;
-}
-
-static int snd_ali_find_free_channel(struct snd_ali * codec, int rec)
-{
- int idx;
- int result = -1;
-
- snd_ali_printk("find_free_channel: for %s\n",rec ? "rec" : "pcm");
-
- /* recording */
- if (rec) {
- if (codec->spdif_support &&
- (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) &
- ALI_SPDIF_IN_SUPPORT))
- idx = ALI_SPDIF_IN_CHANNEL;
- else
- idx = ALI_PCM_IN_CHANNEL;
-
- result = snd_ali_alloc_pcm_channel(codec, idx);
- if (result >= 0)
- return result;
- else {
- snd_printk(KERN_ERR "ali_find_free_channel: "
- "record channel is busy now.\n");
- return -1;
- }
- }
-
- /* playback... */
- if (codec->spdif_support &&
- (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) &
- ALI_SPDIF_OUT_CH_ENABLE)) {
- idx = ALI_SPDIF_OUT_CHANNEL;
- result = snd_ali_alloc_pcm_channel(codec, idx);
- if (result >= 0)
- return result;
- else
- snd_printk(KERN_ERR "ali_find_free_channel: "
- "S/PDIF out channel is in busy now.\n");
- }
-
- for (idx = 0; idx < ALI_CHANNELS; idx++) {
- result = snd_ali_alloc_pcm_channel(codec, idx);
- if (result >= 0)
- return result;
- }
- snd_printk(KERN_ERR "ali_find_free_channel: no free channels.\n");
- return -1;
-}
-
-static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel)
-{
- unsigned int idx = channel & 0x0000001f;
-
- snd_ali_printk("free_channel_pcm channel=%d\n",channel);
-
- if (channel < 0 || channel >= ALI_CHANNELS)
- return;
-
- if (!(codec->synth.chmap & (1 << idx))) {
- snd_printk(KERN_ERR "ali_free_channel_pcm: "
- "channel %d is not in use.\n", channel);
- return;
- } else {
- codec->synth.chmap &= ~(1 << idx);
- codec->synth.chcnt--;
- }
-}
-
-static void snd_ali_stop_voice(struct snd_ali *codec, unsigned int channel)
-{
- unsigned int mask = 1 << (channel & 0x1f);
-
- snd_ali_printk("stop_voice: channel=%d\n",channel);
- outl(mask, ALI_REG(codec, codec->chregs.regs.stop));
-}
-
-/*
- * S/PDIF Part
- */
-
-static void snd_ali_delay(struct snd_ali *codec,int interval)
-{
- unsigned long begintimer,currenttimer;
-
- begintimer = inl(ALI_REG(codec, ALI_STIMER));
- currenttimer = inl(ALI_REG(codec, ALI_STIMER));
-
- while (currenttimer < begintimer + interval) {
- if (snd_ali_stimer_ready(codec) < 0)
- break;
- currenttimer = inl(ALI_REG(codec, ALI_STIMER));
- cpu_relax();
- }
-}
-
-static void snd_ali_detect_spdif_rate(struct snd_ali *codec)
-{
- u16 wval;
- u16 count = 0;
- u8 bval, R1 = 0, R2;
-
- bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL + 1));
- bval |= 0x1F;
- outb(bval, ALI_REG(codec, ALI_SPDIF_CTRL + 1));
-
- while ((R1 < 0x0b || R1 > 0x0e) && R1 != 0x12 && count <= 50000) {
- count ++;
- snd_ali_delay(codec, 6);
- bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL + 1));
- R1 = bval & 0x1F;
- }
-
- if (count > 50000) {
- snd_printk(KERN_ERR "ali_detect_spdif_rate: timeout!\n");
- return;
- }
-
- for (count = 0; count <= 50000; count++) {
- snd_ali_delay(codec, 6);
- bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1));
- R2 = bval & 0x1F;
- if (R2 != R1)
- R1 = R2;
- else
- break;
- }
-
- if (count > 50000) {
- snd_printk(KERN_ERR "ali_detect_spdif_rate: timeout!\n");
- return;
- }
-
- if (R2 >= 0x0b && R2 <= 0x0e) {
- wval = inw(ALI_REG(codec, ALI_SPDIF_CTRL + 2));
- wval &= 0xe0f0;
- wval |= (0x09 << 8) | 0x05;
- outw(wval, ALI_REG(codec, ALI_SPDIF_CTRL + 2));
-
- bval = inb(ALI_REG(codec, ALI_SPDIF_CS + 3)) & 0xf0;
- outb(bval | 0x02, ALI_REG(codec, ALI_SPDIF_CS + 3));
- } else if (R2 == 0x12) {
- wval = inw(ALI_REG(codec, ALI_SPDIF_CTRL + 2));
- wval &= 0xe0f0;
- wval |= (0x0e << 8) | 0x08;
- outw(wval, ALI_REG(codec, ALI_SPDIF_CTRL + 2));
-
- bval = inb(ALI_REG(codec,ALI_SPDIF_CS + 3)) & 0xf0;
- outb(bval | 0x03, ALI_REG(codec, ALI_SPDIF_CS + 3));
- }
-}
-
-static unsigned int snd_ali_get_spdif_in_rate(struct snd_ali *codec)
-{
- u32 dwRate;
- u8 bval;
-
- bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL));
- bval &= 0x7f;
- bval |= 0x40;
- outb(bval, ALI_REG(codec, ALI_SPDIF_CTRL));
-
- snd_ali_detect_spdif_rate(codec);
-
- bval = inb(ALI_REG(codec, ALI_SPDIF_CS + 3));
- bval &= 0x0f;
-
- switch (bval) {
- case 0: dwRate = 44100; break;
- case 1: dwRate = 48000; break;
- case 2: dwRate = 32000; break;
- default: dwRate = 0; break;
- }
-
- return dwRate;
-}
-
-static void snd_ali_enable_spdif_in(struct snd_ali *codec)
-{
- unsigned int dwVal;
-
- dwVal = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL));
- dwVal |= ALI_SPDIF_IN_SUPPORT;
- outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
-
- dwVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL));
- dwVal |= 0x02;
- outb(dwVal, ALI_REG(codec, ALI_SPDIF_CTRL));
-
- snd_ali_enable_special_channel(codec, ALI_SPDIF_IN_CHANNEL);
-}
-
-static void snd_ali_disable_spdif_in(struct snd_ali *codec)
-{
- unsigned int dwVal;
-
- dwVal = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL));
- dwVal &= ~ALI_SPDIF_IN_SUPPORT;
- outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
-
- snd_ali_disable_special_channel(codec, ALI_SPDIF_IN_CHANNEL);
-}
-
-
-static void snd_ali_set_spdif_out_rate(struct snd_ali *codec, unsigned int rate)
-{
- unsigned char bVal;
- unsigned int dwRate;
-
- switch (rate) {
- case 32000: dwRate = 0x300; break;
- case 48000: dwRate = 0x200; break;
- default: dwRate = 0; break;
- }
-
- bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL));
- bVal &= (unsigned char)(~(1<<6));
-
- bVal |= 0x80; /* select right */
- outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL));
- outb(dwRate | 0x20, ALI_REG(codec, ALI_SPDIF_CS + 2));
-
- bVal &= ~0x80; /* select left */
- outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL));
- outw(rate | 0x10, ALI_REG(codec, ALI_SPDIF_CS + 2));
-}
-
-static void snd_ali_enable_spdif_out(struct snd_ali *codec)
-{
- unsigned short wVal;
- unsigned char bVal;
- struct pci_dev *pci_dev;
-
- pci_dev = codec->pci_m1533;
- if (pci_dev == NULL)
- return;
- pci_read_config_byte(pci_dev, 0x61, &bVal);
- bVal |= 0x40;
- pci_write_config_byte(pci_dev, 0x61, bVal);
- pci_read_config_byte(pci_dev, 0x7d, &bVal);
- bVal |= 0x01;
- pci_write_config_byte(pci_dev, 0x7d, bVal);
-
- pci_read_config_byte(pci_dev, 0x7e, &bVal);
- bVal &= (~0x20);
- bVal |= 0x10;
- pci_write_config_byte(pci_dev, 0x7e, bVal);
-
- bVal = inb(ALI_REG(codec, ALI_SCTRL));
- outb(bVal | ALI_SPDIF_OUT_ENABLE, ALI_REG(codec, ALI_SCTRL));
-
- bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL));
- outb(bVal & ALI_SPDIF_OUT_CH_STATUS, ALI_REG(codec, ALI_SPDIF_CTRL));
-
- wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
- wVal |= ALI_SPDIF_OUT_SEL_PCM;
- outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
- snd_ali_disable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL);
-}
-
-static void snd_ali_enable_spdif_chnout(struct snd_ali *codec)
-{
- unsigned short wVal;
-
- wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
- wVal &= ~ALI_SPDIF_OUT_SEL_PCM;
- outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
-/*
- wVal = inw(ALI_REG(codec, ALI_SPDIF_CS));
- if (flag & ALI_SPDIF_OUT_NON_PCM)
- wVal |= 0x0002;
- else
- wVal &= (~0x0002);
- outw(wVal, ALI_REG(codec, ALI_SPDIF_CS));
-*/
- snd_ali_enable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL);
-}
-
-static void snd_ali_disable_spdif_chnout(struct snd_ali *codec)
-{
- unsigned short wVal;
-
- wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
- wVal |= ALI_SPDIF_OUT_SEL_PCM;
- outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
-
- snd_ali_enable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL);
-}
-
-static void snd_ali_disable_spdif_out(struct snd_ali *codec)
-{
- unsigned char bVal;
-
- bVal = inb(ALI_REG(codec, ALI_SCTRL));
- outb(bVal & ~ALI_SPDIF_OUT_ENABLE, ALI_REG(codec, ALI_SCTRL));
-
- snd_ali_disable_spdif_chnout(codec);
-}
-
-static void snd_ali_update_ptr(struct snd_ali *codec, int channel)
-{
- struct snd_ali_voice *pvoice;
- struct snd_pcm_runtime *runtime;
- struct snd_ali_channel_control *pchregs;
- unsigned int old, mask;
-#ifdef ALI_DEBUG
- unsigned int temp, cspf;
-#endif
-
- pchregs = &(codec->chregs);
-
- /* check if interrupt occurred for channel */
- old = pchregs->data.aint;
- mask = 1U << (channel & 0x1f);
-
- if (!(old & mask))
- return;
-
- pvoice = &codec->synth.voices[channel];
- runtime = pvoice->substream->runtime;
-
- udelay(100);
- spin_lock(&codec->reg_lock);
-
- if (pvoice->pcm && pvoice->substream) {
- /* pcm interrupt */
-#ifdef ALI_DEBUG
- outb((u8)(pvoice->number), ALI_REG(codec, ALI_GC_CIR));
- temp = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2));
- cspf = (inl(ALI_REG(codec, ALI_CSPF)) & mask) == mask;
-#endif
- if (pvoice->running) {
- snd_ali_printk("update_ptr: cso=%4.4x cspf=%d.\n",
- (u16)temp, cspf);
- spin_unlock(&codec->reg_lock);
- snd_pcm_period_elapsed(pvoice->substream);
- spin_lock(&codec->reg_lock);
- } else {
- snd_ali_stop_voice(codec, channel);
- snd_ali_disable_voice_irq(codec, channel);
- }
- } else if (codec->synth.voices[channel].synth) {
- /* synth interrupt */
- } else if (codec->synth.voices[channel].midi) {
- /* midi interrupt */
- } else {
- /* unknown interrupt */
- snd_ali_stop_voice(codec, channel);
- snd_ali_disable_voice_irq(codec, channel);
- }
- spin_unlock(&codec->reg_lock);
- outl(mask,ALI_REG(codec,pchregs->regs.aint));
- pchregs->data.aint = old & (~mask);
-}
-
-static irqreturn_t snd_ali_card_interrupt(int irq, void *dev_id)
-{
- struct snd_ali *codec = dev_id;
- int channel;
- unsigned int audio_int;
- struct snd_ali_channel_control *pchregs;
-
- if (codec == NULL || !codec->hw_initialized)
- return IRQ_NONE;
-
- audio_int = inl(ALI_REG(codec, ALI_MISCINT));
- if (!audio_int)
- return IRQ_NONE;
-
- pchregs = &(codec->chregs);
- if (audio_int & ADDRESS_IRQ) {
- /* get interrupt status for all channels */
- pchregs->data.aint = inl(ALI_REG(codec, pchregs->regs.aint));
- for (channel = 0; channel < ALI_CHANNELS; channel++)
- snd_ali_update_ptr(codec, channel);
- }
- outl((TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW),
- ALI_REG(codec, ALI_MISCINT));
-
- return IRQ_HANDLED;
-}
-
-
-static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec,
- int type, int rec, int channel)
-{
- struct snd_ali_voice *pvoice;
- int idx;
-
- snd_ali_printk("alloc_voice: type=%d rec=%d\n", type, rec);
-
- spin_lock_irq(&codec->voice_alloc);
- if (type == SNDRV_ALI_VOICE_TYPE_PCM) {
- idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) :
- snd_ali_find_free_channel(codec,rec);
- if (idx < 0) {
- snd_printk(KERN_ERR "ali_alloc_voice: err.\n");
- spin_unlock_irq(&codec->voice_alloc);
- return NULL;
- }
- pvoice = &(codec->synth.voices[idx]);
- pvoice->codec = codec;
- pvoice->use = 1;
- pvoice->pcm = 1;
- pvoice->mode = rec;
- spin_unlock_irq(&codec->voice_alloc);
- return pvoice;
- }
- spin_unlock_irq(&codec->voice_alloc);
- return NULL;
-}
-
-
-static void snd_ali_free_voice(struct snd_ali * codec,
- struct snd_ali_voice *pvoice)
-{
- void (*private_free)(void *);
- void *private_data;
-
- snd_ali_printk("free_voice: channel=%d\n",pvoice->number);
- if (!pvoice->use)
- return;
- snd_ali_clear_voices(codec, pvoice->number, pvoice->number);
- spin_lock_irq(&codec->voice_alloc);
- private_free = pvoice->private_free;
- private_data = pvoice->private_data;
- pvoice->private_free = NULL;
- pvoice->private_data = NULL;
- if (pvoice->pcm)
- snd_ali_free_channel_pcm(codec, pvoice->number);
- pvoice->use = pvoice->pcm = pvoice->synth = 0;
- pvoice->substream = NULL;
- spin_unlock_irq(&codec->voice_alloc);
- if (private_free)
- private_free(private_data);
-}
-
-
-static void snd_ali_clear_voices(struct snd_ali *codec,
- unsigned int v_min,
- unsigned int v_max)
-{
- unsigned int i;
-
- for (i = v_min; i <= v_max; i++) {
- snd_ali_stop_voice(codec, i);
- snd_ali_disable_voice_irq(codec, i);
- }
-}
-
-static void snd_ali_write_voice_regs(struct snd_ali *codec,
- unsigned int Channel,
- unsigned int LBA,
- unsigned int CSO,
- unsigned int ESO,
- unsigned int DELTA,
- unsigned int ALPHA_FMS,
- unsigned int GVSEL,
- unsigned int PAN,
- unsigned int VOL,
- unsigned int CTRL,
- unsigned int EC)
-{
- unsigned int ctlcmds[4];
-
- outb((unsigned char)(Channel & 0x001f), ALI_REG(codec, ALI_GC_CIR));
-
- ctlcmds[0] = (CSO << 16) | (ALPHA_FMS & 0x0000ffff);
- ctlcmds[1] = LBA;
- ctlcmds[2] = (ESO << 16) | (DELTA & 0x0ffff);
- ctlcmds[3] = (GVSEL << 31) |
- ((PAN & 0x0000007f) << 24) |
- ((VOL & 0x000000ff) << 16) |
- ((CTRL & 0x0000000f) << 12) |
- (EC & 0x00000fff);
-
- outb(Channel, ALI_REG(codec, ALI_GC_CIR));
-
- outl(ctlcmds[0], ALI_REG(codec, ALI_CSO_ALPHA_FMS));
- outl(ctlcmds[1], ALI_REG(codec, ALI_LBA));
- outl(ctlcmds[2], ALI_REG(codec, ALI_ESO_DELTA));
- outl(ctlcmds[3], ALI_REG(codec, ALI_GVSEL_PAN_VOC_CTRL_EC));
-
- outl(0x30000000, ALI_REG(codec, ALI_EBUF1)); /* Still Mode */
- outl(0x30000000, ALI_REG(codec, ALI_EBUF2)); /* Still Mode */
-}
-
-static unsigned int snd_ali_convert_rate(unsigned int rate, int rec)
-{
- unsigned int delta;
-
- if (rate < 4000)
- rate = 4000;
- if (rate > 48000)
- rate = 48000;
-
- if (rec) {
- if (rate == 44100)
- delta = 0x116a;
- else if (rate == 8000)
- delta = 0x6000;
- else if (rate == 48000)
- delta = 0x1000;
- else
- delta = ((48000 << 12) / rate) & 0x0000ffff;
- } else {
- if (rate == 44100)
- delta = 0xeb3;
- else if (rate == 8000)
- delta = 0x2ab;
- else if (rate == 48000)
- delta = 0x1000;
- else
- delta = (((rate << 12) + rate) / 48000) & 0x0000ffff;
- }
-
- return delta;
-}
-
-static unsigned int snd_ali_control_mode(struct snd_pcm_substream *substream)
-{
- unsigned int CTRL;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- /* set ctrl mode
- CTRL default: 8-bit (unsigned) mono, loop mode enabled
- */
- CTRL = 0x00000001;
- if (snd_pcm_format_width(runtime->format) == 16)
- CTRL |= 0x00000008; /* 16-bit data */
- if (!snd_pcm_format_unsigned(runtime->format))
- CTRL |= 0x00000002; /* signed data */
- if (runtime->channels > 1)
- CTRL |= 0x00000004; /* stereo data */
- return CTRL;
-}
-
-/*
- * PCM part
- */
-
-static int snd_ali_trigger(struct snd_pcm_substream *substream,
- int cmd)
-
-{
- struct snd_ali *codec = snd_pcm_substream_chip(substream);
- struct snd_pcm_substream *s;
- unsigned int what, whati, capture_flag;
- struct snd_ali_voice *pvoice, *evoice;
- unsigned int val;
- int do_start;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- do_start = 1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- do_start = 0;
- break;
- default:
- return -EINVAL;
- }
-
- what = whati = capture_flag = 0;
- snd_pcm_group_for_each_entry(s, substream) {
- if ((struct snd_ali *) snd_pcm_substream_chip(s) == codec) {
- pvoice = s->runtime->private_data;
- evoice = pvoice->extra;
- what |= 1 << (pvoice->number & 0x1f);
- if (evoice == NULL)
- whati |= 1 << (pvoice->number & 0x1f);
- else {
- whati |= 1 << (evoice->number & 0x1f);
- what |= 1 << (evoice->number & 0x1f);
- }
- if (do_start) {
- pvoice->running = 1;
- if (evoice != NULL)
- evoice->running = 1;
- } else {
- pvoice->running = 0;
- if (evoice != NULL)
- evoice->running = 0;
- }
- snd_pcm_trigger_done(s, substream);
- if (pvoice->mode)
- capture_flag = 1;
- }
- }
- spin_lock(&codec->reg_lock);
- if (!do_start)
- outl(what, ALI_REG(codec, ALI_STOP));
- val = inl(ALI_REG(codec, ALI_AINTEN));
- if (do_start)
- val |= whati;
- else
- val &= ~whati;
- outl(val, ALI_REG(codec, ALI_AINTEN));
- if (do_start)
- outl(what, ALI_REG(codec, ALI_START));
- snd_ali_printk("trigger: what=%xh whati=%xh\n", what, whati);
- spin_unlock(&codec->reg_lock);
-
- return 0;
-}
-
-static int snd_ali_playback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_ali *codec = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ali_voice *pvoice = runtime->private_data;
- struct snd_ali_voice *evoice = pvoice->extra;
- int err;
-
- err = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
-
- /* voice management */
-
- if (params_buffer_size(hw_params) / 2 !=
- params_period_size(hw_params)) {
- if (!evoice) {
- evoice = snd_ali_alloc_voice(codec,
- SNDRV_ALI_VOICE_TYPE_PCM,
- 0, -1);
- if (!evoice)
- return -ENOMEM;
- pvoice->extra = evoice;
- evoice->substream = substream;
- }
- } else {
- if (evoice) {
- snd_ali_free_voice(codec, evoice);
- pvoice->extra = evoice = NULL;
- }
- }
-
- return 0;
-}
-
-static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_ali *codec = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ali_voice *pvoice = runtime->private_data;
- struct snd_ali_voice *evoice = pvoice ? pvoice->extra : NULL;
-
- snd_pcm_lib_free_pages(substream);
- if (evoice) {
- snd_ali_free_voice(codec, evoice);
- pvoice->extra = NULL;
- }
- return 0;
-}
-
-static int snd_ali_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-}
-
-static int snd_ali_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_ali_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_ali *codec = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ali_voice *pvoice = runtime->private_data;
- struct snd_ali_voice *evoice = pvoice->extra;
-
- unsigned int LBA;
- unsigned int Delta;
- unsigned int ESO;
- unsigned int CTRL;
- unsigned int GVSEL;
- unsigned int PAN;
- unsigned int VOL;
- unsigned int EC;
-
- snd_ali_printk("playback_prepare ...\n");
-
- spin_lock_irq(&codec->reg_lock);
-
- /* set Delta (rate) value */
- Delta = snd_ali_convert_rate(runtime->rate, 0);
-
- if (pvoice->number == ALI_SPDIF_IN_CHANNEL ||
- pvoice->number == ALI_PCM_IN_CHANNEL)
- snd_ali_disable_special_channel(codec, pvoice->number);
- else if (codec->spdif_support &&
- (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) &
- ALI_SPDIF_OUT_CH_ENABLE)
- && pvoice->number == ALI_SPDIF_OUT_CHANNEL) {
- snd_ali_set_spdif_out_rate(codec, runtime->rate);
- Delta = 0x1000;
- }
-
- /* set Loop Back Address */
- LBA = runtime->dma_addr;
-
- /* set interrupt count size */
- pvoice->count = runtime->period_size;
-
- /* set target ESO for channel */
- pvoice->eso = runtime->buffer_size;
-
- snd_ali_printk("playback_prepare: eso=%xh count=%xh\n",
- pvoice->eso, pvoice->count);
-
- /* set ESO to capture first MIDLP interrupt */
- ESO = pvoice->eso -1;
- /* set ctrl mode */
- CTRL = snd_ali_control_mode(substream);
-
- GVSEL = 1;
- PAN = 0;
- VOL = 0;
- EC = 0;
- snd_ali_printk("playback_prepare:\n");
- snd_ali_printk("ch=%d, Rate=%d Delta=%xh,GVSEL=%xh,PAN=%xh,CTRL=%xh\n",
- pvoice->number,runtime->rate,Delta,GVSEL,PAN,CTRL);
- snd_ali_write_voice_regs(codec,
- pvoice->number,
- LBA,
- 0, /* cso */
- ESO,
- Delta,
- 0, /* alpha */
- GVSEL,
- PAN,
- VOL,
- CTRL,
- EC);
- if (evoice) {
- evoice->count = pvoice->count;
- evoice->eso = pvoice->count << 1;
- ESO = evoice->eso - 1;
- snd_ali_write_voice_regs(codec,
- evoice->number,
- LBA,
- 0, /* cso */
- ESO,
- Delta,
- 0, /* alpha */
- GVSEL,
- 0x7f,
- 0x3ff,
- CTRL,
- EC);
- }
- spin_unlock_irq(&codec->reg_lock);
- return 0;
-}
-
-
-static int snd_ali_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_ali *codec = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ali_voice *pvoice = runtime->private_data;
- unsigned int LBA;
- unsigned int Delta;
- unsigned int ESO;
- unsigned int CTRL;
- unsigned int GVSEL;
- unsigned int PAN;
- unsigned int VOL;
- unsigned int EC;
- u8 bValue;
-
- spin_lock_irq(&codec->reg_lock);
-
- snd_ali_printk("ali_prepare...\n");
-
- snd_ali_enable_special_channel(codec,pvoice->number);
-
- Delta = (pvoice->number == ALI_MODEM_IN_CHANNEL ||
- pvoice->number == ALI_MODEM_OUT_CHANNEL) ?
- 0x1000 : snd_ali_convert_rate(runtime->rate, pvoice->mode);
-
- /* Prepare capture intr channel */
- if (pvoice->number == ALI_SPDIF_IN_CHANNEL) {
-
- unsigned int rate;
-
- spin_unlock_irq(&codec->reg_lock);
- if (codec->revision != ALI_5451_V02)
- return -1;
-
- rate = snd_ali_get_spdif_in_rate(codec);
- if (rate == 0) {
- snd_printk(KERN_WARNING "ali_capture_preapre: "
- "spdif rate detect err!\n");
- rate = 48000;
- }
- spin_lock_irq(&codec->reg_lock);
- bValue = inb(ALI_REG(codec,ALI_SPDIF_CTRL));
- if (bValue & 0x10) {
- outb(bValue,ALI_REG(codec,ALI_SPDIF_CTRL));
- printk(KERN_WARNING "clear SPDIF parity error flag.\n");
- }
-
- if (rate != 48000)
- Delta = ((rate << 12) / runtime->rate) & 0x00ffff;
- }
-
- /* set target ESO for channel */
- pvoice->eso = runtime->buffer_size;
-
- /* set interrupt count size */
- pvoice->count = runtime->period_size;
-
- /* set Loop Back Address */
- LBA = runtime->dma_addr;
-
- /* set ESO to capture first MIDLP interrupt */
- ESO = pvoice->eso - 1;
- CTRL = snd_ali_control_mode(substream);
- GVSEL = 0;
- PAN = 0x00;
- VOL = 0x00;
- EC = 0;
-
- snd_ali_write_voice_regs( codec,
- pvoice->number,
- LBA,
- 0, /* cso */
- ESO,
- Delta,
- 0, /* alpha */
- GVSEL,
- PAN,
- VOL,
- CTRL,
- EC);
-
- spin_unlock_irq(&codec->reg_lock);
-
- return 0;
-}
-
-
-static snd_pcm_uframes_t
-snd_ali_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_ali *codec = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ali_voice *pvoice = runtime->private_data;
- unsigned int cso;
-
- spin_lock(&codec->reg_lock);
- if (!pvoice->running) {
- spin_unlock(&codec->reg_lock);
- return 0;
- }
- outb(pvoice->number, ALI_REG(codec, ALI_GC_CIR));
- cso = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2));
- spin_unlock(&codec->reg_lock);
- snd_ali_printk("playback pointer returned cso=%xh.\n", cso);
-
- return cso;
-}
-
-
-static snd_pcm_uframes_t snd_ali_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_ali *codec = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ali_voice *pvoice = runtime->private_data;
- unsigned int cso;
-
- spin_lock(&codec->reg_lock);
- if (!pvoice->running) {
- spin_unlock_irq(&codec->reg_lock);
- return 0;
- }
- outb(pvoice->number, ALI_REG(codec, ALI_GC_CIR));
- cso = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2));
- spin_unlock(&codec->reg_lock);
-
- return cso;
-}
-
-static struct snd_pcm_hardware snd_ali_playback =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_SYNC_START),
- .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (256*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (256*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-/*
- * Capture support device description
- */
-
-static struct snd_pcm_hardware snd_ali_capture =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_SYNC_START),
- .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static void snd_ali_pcm_free_substream(struct snd_pcm_runtime *runtime)
-{
- struct snd_ali_voice *pvoice = runtime->private_data;
- struct snd_ali *codec;
-
- if (pvoice) {
- codec = pvoice->codec;
- snd_ali_free_voice(pvoice->codec, pvoice);
- }
-}
-
-static int snd_ali_open(struct snd_pcm_substream *substream, int rec,
- int channel, struct snd_pcm_hardware *phw)
-{
- struct snd_ali *codec = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ali_voice *pvoice;
-
- pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, rec,
- channel);
- if (!pvoice)
- return -EAGAIN;
-
- pvoice->substream = substream;
- runtime->private_data = pvoice;
- runtime->private_free = snd_ali_pcm_free_substream;
-
- runtime->hw = *phw;
- snd_pcm_set_sync(substream);
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- 0, 64*1024);
- return 0;
-}
-
-static int snd_ali_playback_open(struct snd_pcm_substream *substream)
-{
- return snd_ali_open(substream, 0, -1, &snd_ali_playback);
-}
-
-static int snd_ali_capture_open(struct snd_pcm_substream *substream)
-{
- return snd_ali_open(substream, 1, -1, &snd_ali_capture);
-}
-
-static int snd_ali_playback_close(struct snd_pcm_substream *substream)
-{
- return 0;
-}
-
-static int snd_ali_close(struct snd_pcm_substream *substream)
-{
- struct snd_ali *codec = snd_pcm_substream_chip(substream);
- struct snd_ali_voice *pvoice = substream->runtime->private_data;
-
- snd_ali_disable_special_channel(codec,pvoice->number);
-
- return 0;
-}
-
-static struct snd_pcm_ops snd_ali_playback_ops = {
- .open = snd_ali_playback_open,
- .close = snd_ali_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ali_playback_hw_params,
- .hw_free = snd_ali_playback_hw_free,
- .prepare = snd_ali_playback_prepare,
- .trigger = snd_ali_trigger,
- .pointer = snd_ali_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_ali_capture_ops = {
- .open = snd_ali_capture_open,
- .close = snd_ali_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ali_hw_params,
- .hw_free = snd_ali_hw_free,
- .prepare = snd_ali_prepare,
- .trigger = snd_ali_trigger,
- .pointer = snd_ali_pointer,
-};
-
-/*
- * Modem PCM
- */
-
-static int snd_ali_modem_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_ali *chip = snd_pcm_substream_chip(substream);
- unsigned int modem_num = chip->num_of_codecs - 1;
- snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE,
- params_rate(hw_params));
- snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_LEVEL, 0);
- return snd_ali_hw_params(substream, hw_params);
-}
-
-static struct snd_pcm_hardware snd_ali_modem =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_SYNC_START),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000 |
- SNDRV_PCM_RATE_16000),
- .rate_min = 8000,
- .rate_max = 16000,
- .channels_min = 1,
- .channels_max = 1,
- .buffer_bytes_max = (256*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (256*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static int snd_ali_modem_open(struct snd_pcm_substream *substream, int rec,
- int channel)
-{
- static unsigned int rates[] = {8000, 9600, 12000, 16000};
- static struct snd_pcm_hw_constraint_list hw_constraint_rates = {
- .count = ARRAY_SIZE(rates),
- .list = rates,
- .mask = 0,
- };
- int err = snd_ali_open(substream, rec, channel, &snd_ali_modem);
-
- if (err)
- return err;
- return snd_pcm_hw_constraint_list(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE, &hw_constraint_rates);
-}
-
-static int snd_ali_modem_playback_open(struct snd_pcm_substream *substream)
-{
- return snd_ali_modem_open(substream, 0, ALI_MODEM_OUT_CHANNEL);
-}
-
-static int snd_ali_modem_capture_open(struct snd_pcm_substream *substream)
-{
- return snd_ali_modem_open(substream, 1, ALI_MODEM_IN_CHANNEL);
-}
-
-static struct snd_pcm_ops snd_ali_modem_playback_ops = {
- .open = snd_ali_modem_playback_open,
- .close = snd_ali_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ali_modem_hw_params,
- .hw_free = snd_ali_hw_free,
- .prepare = snd_ali_prepare,
- .trigger = snd_ali_trigger,
- .pointer = snd_ali_pointer,
-};
-
-static struct snd_pcm_ops snd_ali_modem_capture_ops = {
- .open = snd_ali_modem_capture_open,
- .close = snd_ali_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ali_modem_hw_params,
- .hw_free = snd_ali_hw_free,
- .prepare = snd_ali_prepare,
- .trigger = snd_ali_trigger,
- .pointer = snd_ali_pointer,
-};
-
-
-struct ali_pcm_description {
- char *name;
- unsigned int playback_num;
- unsigned int capture_num;
- struct snd_pcm_ops *playback_ops;
- struct snd_pcm_ops *capture_ops;
- unsigned short class;
-};
-
-
-static void snd_ali_pcm_free(struct snd_pcm *pcm)
-{
- struct snd_ali *codec = pcm->private_data;
- codec->pcm[pcm->device] = NULL;
-}
-
-
-static int __devinit snd_ali_pcm(struct snd_ali * codec, int device,
- struct ali_pcm_description *desc)
-{
- struct snd_pcm *pcm;
- int err;
-
- err = snd_pcm_new(codec->card, desc->name, device,
- desc->playback_num, desc->capture_num, &pcm);
- if (err < 0) {
- snd_printk(KERN_ERR "snd_ali_pcm: err called snd_pcm_new.\n");
- return err;
- }
- pcm->private_data = codec;
- pcm->private_free = snd_ali_pcm_free;
- if (desc->playback_ops)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- desc->playback_ops);
- if (desc->capture_ops)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- desc->capture_ops);
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(codec->pci),
- 64*1024, 128*1024);
-
- pcm->info_flags = 0;
- pcm->dev_class = desc->class;
- pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
- strcpy(pcm->name, desc->name);
- codec->pcm[0] = pcm;
- return 0;
-}
-
-static struct ali_pcm_description ali_pcms[] = {
- { .name = "ALI 5451",
- .playback_num = ALI_CHANNELS,
- .capture_num = 1,
- .playback_ops = &snd_ali_playback_ops,
- .capture_ops = &snd_ali_capture_ops
- },
- { .name = "ALI 5451 modem",
- .playback_num = 1,
- .capture_num = 1,
- .playback_ops = &snd_ali_modem_playback_ops,
- .capture_ops = &snd_ali_modem_capture_ops,
- .class = SNDRV_PCM_CLASS_MODEM
- }
-};
-
-static int __devinit snd_ali_build_pcms(struct snd_ali *codec)
-{
- int i, err;
- for (i = 0; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms); i++) {
- err = snd_ali_pcm(codec, i, &ali_pcms[i]);
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-
-#define ALI5451_SPDIF(xname, xindex, value) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex,\
-.info = snd_ali5451_spdif_info, .get = snd_ali5451_spdif_get, \
-.put = snd_ali5451_spdif_put, .private_value = value}
-
-#define snd_ali5451_spdif_info snd_ctl_boolean_mono_info
-
-static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ali *codec = kcontrol->private_data;
- unsigned int spdif_enable;
-
- spdif_enable = ucontrol->value.integer.value[0] ? 1 : 0;
-
- spin_lock_irq(&codec->reg_lock);
- switch (kcontrol->private_value) {
- case 0:
- spdif_enable = (codec->spdif_mask & 0x02) ? 1 : 0;
- break;
- case 1:
- spdif_enable = ((codec->spdif_mask & 0x02) &&
- (codec->spdif_mask & 0x04)) ? 1 : 0;
- break;
- case 2:
- spdif_enable = (codec->spdif_mask & 0x01) ? 1 : 0;
- break;
- default:
- break;
- }
- ucontrol->value.integer.value[0] = spdif_enable;
- spin_unlock_irq(&codec->reg_lock);
- return 0;
-}
-
-static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ali *codec = kcontrol->private_data;
- unsigned int change = 0, spdif_enable = 0;
-
- spdif_enable = ucontrol->value.integer.value[0] ? 1 : 0;
-
- spin_lock_irq(&codec->reg_lock);
- switch (kcontrol->private_value) {
- case 0:
- change = (codec->spdif_mask & 0x02) ? 1 : 0;
- change = change ^ spdif_enable;
- if (change) {
- if (spdif_enable) {
- codec->spdif_mask |= 0x02;
- snd_ali_enable_spdif_out(codec);
- } else {
- codec->spdif_mask &= ~(0x02);
- codec->spdif_mask &= ~(0x04);
- snd_ali_disable_spdif_out(codec);
- }
- }
- break;
- case 1:
- change = (codec->spdif_mask & 0x04) ? 1 : 0;
- change = change ^ spdif_enable;
- if (change && (codec->spdif_mask & 0x02)) {
- if (spdif_enable) {
- codec->spdif_mask |= 0x04;
- snd_ali_enable_spdif_chnout(codec);
- } else {
- codec->spdif_mask &= ~(0x04);
- snd_ali_disable_spdif_chnout(codec);
- }
- }
- break;
- case 2:
- change = (codec->spdif_mask & 0x01) ? 1 : 0;
- change = change ^ spdif_enable;
- if (change) {
- if (spdif_enable) {
- codec->spdif_mask |= 0x01;
- snd_ali_enable_spdif_in(codec);
- } else {
- codec->spdif_mask &= ~(0x01);
- snd_ali_disable_spdif_in(codec);
- }
- }
- break;
- default:
- break;
- }
- spin_unlock_irq(&codec->reg_lock);
-
- return change;
-}
-
-static struct snd_kcontrol_new snd_ali5451_mixer_spdif[] __devinitdata = {
- /* spdif aplayback switch */
- /* FIXME: "IEC958 Playback Switch" may conflict with one on ac97_codec */
- ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), 0, 0),
- /* spdif out to spdif channel */
- ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("Channel Output ",NONE,SWITCH), 0, 1),
- /* spdif in from spdif channel */
- ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, 2)
-};
-
-static int __devinit snd_ali_mixer(struct snd_ali * codec)
-{
- struct snd_ac97_template ac97;
- unsigned int idx;
- int i, err;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_ali_codec_write,
- .read = snd_ali_codec_read,
- };
-
- err = snd_ac97_bus(codec->card, 0, &ops, codec, &codec->ac97_bus);
- if (err < 0)
- return err;
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = codec;
-
- for (i = 0; i < codec->num_of_codecs; i++) {
- ac97.num = i;
- err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i]);
- if (err < 0) {
- snd_printk(KERN_ERR
- "ali mixer %d creating error.\n", i);
- if (i == 0)
- return err;
- codec->num_of_codecs = 1;
- break;
- }
- }
-
- if (codec->spdif_support) {
- for (idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) {
- err = snd_ctl_add(codec->card,
- snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec));
- if (err < 0)
- return err;
- }
- }
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int ali_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_ali *chip = card->private_data;
- struct snd_ali_image *im;
- int i, j;
-
- im = chip->image;
- if (!im)
- return 0;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- for (i = 0; i < chip->num_of_codecs; i++) {
- snd_pcm_suspend_all(chip->pcm[i]);
- snd_ac97_suspend(chip->ac97[i]);
- }
-
- spin_lock_irq(&chip->reg_lock);
-
- im->regs[ALI_MISCINT >> 2] = inl(ALI_REG(chip, ALI_MISCINT));
- /* im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START)); */
- im->regs[ALI_STOP >> 2] = inl(ALI_REG(chip, ALI_STOP));
-
- /* disable all IRQ bits */
- outl(0, ALI_REG(chip, ALI_MISCINT));
-
- for (i = 0; i < ALI_GLOBAL_REGS; i++) {
- if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP))
- continue;
- im->regs[i] = inl(ALI_REG(chip, i*4));
- }
-
- for (i = 0; i < ALI_CHANNELS; i++) {
- outb(i, ALI_REG(chip, ALI_GC_CIR));
- for (j = 0; j < ALI_CHANNEL_REGS; j++)
- im->channel_regs[i][j] = inl(ALI_REG(chip, j*4 + 0xe0));
- }
-
- /* stop all HW channel */
- outl(0xffffffff, ALI_REG(chip, ALI_STOP));
-
- spin_unlock_irq(&chip->reg_lock);
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int ali_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_ali *chip = card->private_data;
- struct snd_ali_image *im;
- int i, j;
-
- im = chip->image;
- if (!im)
- return 0;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "ali5451: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
-
- spin_lock_irq(&chip->reg_lock);
-
- for (i = 0; i < ALI_CHANNELS; i++) {
- outb(i, ALI_REG(chip, ALI_GC_CIR));
- for (j = 0; j < ALI_CHANNEL_REGS; j++)
- outl(im->channel_regs[i][j], ALI_REG(chip, j*4 + 0xe0));
- }
-
- for (i = 0; i < ALI_GLOBAL_REGS; i++) {
- if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) ||
- (i*4 == ALI_START))
- continue;
- outl(im->regs[i], ALI_REG(chip, i*4));
- }
-
- /* start HW channel */
- outl(im->regs[ALI_START >> 2], ALI_REG(chip, ALI_START));
- /* restore IRQ enable bits */
- outl(im->regs[ALI_MISCINT >> 2], ALI_REG(chip, ALI_MISCINT));
-
- spin_unlock_irq(&chip->reg_lock);
-
- for (i = 0 ; i < chip->num_of_codecs; i++)
- snd_ac97_resume(chip->ac97[i]);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif /* CONFIG_PM */
-
-static int snd_ali_free(struct snd_ali * codec)
-{
- if (codec->hw_initialized)
- snd_ali_disable_address_interrupt(codec);
- if (codec->irq >= 0)
- free_irq(codec->irq, codec);
- if (codec->port)
- pci_release_regions(codec->pci);
- pci_disable_device(codec->pci);
-#ifdef CONFIG_PM
- kfree(codec->image);
-#endif
- pci_dev_put(codec->pci_m1533);
- pci_dev_put(codec->pci_m7101);
- kfree(codec);
- return 0;
-}
-
-static int snd_ali_chip_init(struct snd_ali *codec)
-{
- unsigned int legacy;
- unsigned char temp;
- struct pci_dev *pci_dev;
-
- snd_ali_printk("chip initializing ... \n");
-
- if (snd_ali_reset_5451(codec)) {
- snd_printk(KERN_ERR "ali_chip_init: reset 5451 error.\n");
- return -1;
- }
-
- if (codec->revision == ALI_5451_V02) {
- pci_dev = codec->pci_m1533;
- pci_read_config_byte(pci_dev, 0x59, &temp);
- temp |= 0x80;
- pci_write_config_byte(pci_dev, 0x59, temp);
-
- pci_dev = codec->pci_m7101;
- pci_read_config_byte(pci_dev, 0xb8, &temp);
- temp |= 0x20;
- pci_write_config_byte(pci_dev, 0xB8, temp);
- }
-
- pci_read_config_dword(codec->pci, 0x44, &legacy);
- legacy &= 0xff00ff00;
- legacy |= 0x000800aa;
- pci_write_config_dword(codec->pci, 0x44, legacy);
-
- outl(0x80000001, ALI_REG(codec, ALI_GLOBAL_CONTROL));
- outl(0x00000000, ALI_REG(codec, ALI_AINTEN));
- outl(0xffffffff, ALI_REG(codec, ALI_AINT));
- outl(0x00000000, ALI_REG(codec, ALI_VOLUME));
- outb(0x10, ALI_REG(codec, ALI_MPUR2));
-
- codec->ac97_ext_id = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_ID);
- codec->ac97_ext_status = snd_ali_codec_peek(codec, 0,
- AC97_EXTENDED_STATUS);
- if (codec->spdif_support) {
- snd_ali_enable_spdif_out(codec);
- codec->spdif_mask = 0x00000002;
- }
-
- codec->num_of_codecs = 1;
-
- /* secondary codec - modem */
- if (inl(ALI_REG(codec, ALI_SCTRL)) & ALI_SCTRL_CODEC2_READY) {
- codec->num_of_codecs++;
- outl(inl(ALI_REG(codec, ALI_SCTRL)) |
- (ALI_SCTRL_LINE_IN2 | ALI_SCTRL_GPIO_IN2 |
- ALI_SCTRL_LINE_OUT_EN),
- ALI_REG(codec, ALI_SCTRL));
- }
-
- snd_ali_printk("chip initialize succeed.\n");
- return 0;
-
-}
-
-/* proc for register dump */
-static void snd_ali_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buf)
-{
- struct snd_ali *codec = entry->private_data;
- int i;
- for (i = 0; i < 256 ; i+= 4)
- snd_iprintf(buf, "%02x: %08x\n", i, inl(ALI_REG(codec, i)));
-}
-
-static void __devinit snd_ali_proc_init(struct snd_ali *codec)
-{
- struct snd_info_entry *entry;
- if (!snd_card_proc_new(codec->card, "ali5451", &entry))
- snd_info_set_text_ops(entry, codec, snd_ali_proc_read);
-}
-
-static int __devinit snd_ali_resources(struct snd_ali *codec)
-{
- int err;
-
- snd_ali_printk("resources allocation ...\n");
- err = pci_request_regions(codec->pci, "ALI 5451");
- if (err < 0)
- return err;
- codec->port = pci_resource_start(codec->pci, 0);
-
- if (request_irq(codec->pci->irq, snd_ali_card_interrupt,
- IRQF_SHARED, KBUILD_MODNAME, codec)) {
- snd_printk(KERN_ERR "Unable to request irq.\n");
- return -EBUSY;
- }
- codec->irq = codec->pci->irq;
- snd_ali_printk("resources allocated.\n");
- return 0;
-}
-static int snd_ali_dev_free(struct snd_device *device)
-{
- struct snd_ali *codec = device->device_data;
- snd_ali_free(codec);
- return 0;
-}
-
-static int __devinit snd_ali_create(struct snd_card *card,
- struct pci_dev *pci,
- int pcm_streams,
- int spdif_support,
- struct snd_ali ** r_ali)
-{
- struct snd_ali *codec;
- int i, err;
- unsigned short cmdw;
- static struct snd_device_ops ops = {
- .dev_free = snd_ali_dev_free,
- };
-
- *r_ali = NULL;
-
- snd_ali_printk("creating ...\n");
-
- /* enable PCI device */
- err = pci_enable_device(pci);
- if (err < 0)
- return err;
- /* check, if we can restrict PCI DMA transfers to 31 bits */
- if (pci_set_dma_mask(pci, DMA_BIT_MASK(31)) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(31)) < 0) {
- snd_printk(KERN_ERR "architecture does not support "
- "31bit PCI busmaster DMA\n");
- pci_disable_device(pci);
- return -ENXIO;
- }
-
- codec = kzalloc(sizeof(*codec), GFP_KERNEL);
- if (!codec) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- spin_lock_init(&codec->reg_lock);
- spin_lock_init(&codec->voice_alloc);
-
- codec->card = card;
- codec->pci = pci;
- codec->irq = -1;
- codec->revision = pci->revision;
- codec->spdif_support = spdif_support;
-
- if (pcm_streams < 1)
- pcm_streams = 1;
- if (pcm_streams > 32)
- pcm_streams = 32;
-
- pci_set_master(pci);
- pci_read_config_word(pci, PCI_COMMAND, &cmdw);
- if ((cmdw & PCI_COMMAND_IO) != PCI_COMMAND_IO) {
- cmdw |= PCI_COMMAND_IO;
- pci_write_config_word(pci, PCI_COMMAND, cmdw);
- }
- pci_set_master(pci);
-
- if (snd_ali_resources(codec)) {
- snd_ali_free(codec);
- return -EBUSY;
- }
-
- synchronize_irq(pci->irq);
-
- codec->synth.chmap = 0;
- codec->synth.chcnt = 0;
- codec->spdif_mask = 0;
- codec->synth.synthcount = 0;
-
- if (codec->revision == ALI_5451_V02)
- codec->chregs.regs.ac97read = ALI_AC97_WRITE;
- else
- codec->chregs.regs.ac97read = ALI_AC97_READ;
- codec->chregs.regs.ac97write = ALI_AC97_WRITE;
-
- codec->chregs.regs.start = ALI_START;
- codec->chregs.regs.stop = ALI_STOP;
- codec->chregs.regs.aint = ALI_AINT;
- codec->chregs.regs.ainten = ALI_AINTEN;
-
- codec->chregs.data.start = 0x00;
- codec->chregs.data.stop = 0x00;
- codec->chregs.data.aint = 0x00;
- codec->chregs.data.ainten = 0x00;
-
- /* M1533: southbridge */
- codec->pci_m1533 = pci_get_device(0x10b9, 0x1533, NULL);
- if (!codec->pci_m1533) {
- snd_printk(KERN_ERR "ali5451: cannot find ALi 1533 chip.\n");
- snd_ali_free(codec);
- return -ENODEV;
- }
- /* M7101: power management */
- codec->pci_m7101 = pci_get_device(0x10b9, 0x7101, NULL);
- if (!codec->pci_m7101 && codec->revision == ALI_5451_V02) {
- snd_printk(KERN_ERR "ali5451: cannot find ALi 7101 chip.\n");
- snd_ali_free(codec);
- return -ENODEV;
- }
-
- snd_ali_printk("snd_device_new is called.\n");
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops);
- if (err < 0) {
- snd_ali_free(codec);
- return err;
- }
-
- snd_card_set_dev(card, &pci->dev);
-
- /* initialise synth voices*/
- for (i = 0; i < ALI_CHANNELS; i++)
- codec->synth.voices[i].number = i;
-
- err = snd_ali_chip_init(codec);
- if (err < 0) {
- snd_printk(KERN_ERR "ali create: chip init error.\n");
- return err;
- }
-
-#ifdef CONFIG_PM
- codec->image = kmalloc(sizeof(*codec->image), GFP_KERNEL);
- if (!codec->image)
- snd_printk(KERN_WARNING "can't allocate apm buffer\n");
-#endif
-
- snd_ali_enable_address_interrupt(codec);
- codec->hw_initialized = 1;
-
- *r_ali = codec;
- snd_ali_printk("created.\n");
- return 0;
-}
-
-static int __devinit snd_ali_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- struct snd_card *card;
- struct snd_ali *codec;
- int err;
-
- snd_ali_printk("probe ...\n");
-
- err = snd_card_create(index, id, THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- err = snd_ali_create(card, pci, pcm_channels, spdif, &codec);
- if (err < 0)
- goto error;
- card->private_data = codec;
-
- snd_ali_printk("mixer building ...\n");
- err = snd_ali_mixer(codec);
- if (err < 0)
- goto error;
-
- snd_ali_printk("pcm building ...\n");
- err = snd_ali_build_pcms(codec);
- if (err < 0)
- goto error;
-
- snd_ali_proc_init(codec);
-
- strcpy(card->driver, "ALI5451");
- strcpy(card->shortname, "ALI 5451");
-
- sprintf(card->longname, "%s at 0x%lx, irq %i",
- card->shortname, codec->port, codec->irq);
-
- snd_ali_printk("register card.\n");
- err = snd_card_register(card);
- if (err < 0)
- goto error;
-
- pci_set_drvdata(pci, card);
- return 0;
-
- error:
- snd_card_free(card);
- return err;
-}
-
-static void __devexit snd_ali_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_ali_ids,
- .probe = snd_ali_probe,
- .remove = __devexit_p(snd_ali_remove),
-#ifdef CONFIG_PM
- .suspend = ali_suspend,
- .resume = ali_resume,
-#endif
-};
-
-static int __init alsa_card_ali_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_ali_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_ali_init)
-module_exit(alsa_card_ali_exit)
diff --git a/ANDROID_3.4.5/sound/pci/als300.c b/ANDROID_3.4.5/sound/pci/als300.c
deleted file mode 100644
index 8196e229..00000000
--- a/ANDROID_3.4.5/sound/pci/als300.c
+++ /dev/null
@@ -1,877 +0,0 @@
-/*
- * als300.c - driver for Avance Logic ALS300/ALS300+ soundcards.
- * Copyright (C) 2005 by Ash Willis <ashwillis@programmer.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * TODO
- * 4 channel playback for ALS300+
- * gameport
- * mpu401
- * opl3
- *
- * NOTES
- * The BLOCK_COUNTER registers for the ALS300(+) return a figure related to
- * the position in the current period, NOT the whole buffer. It is important
- * to know which period we are in so we can calculate the correct pointer.
- * This is why we always use 2 periods. We can then use a flip-flop variable
- * to keep track of what period we are in.
- */
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-
-#include <asm/io.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/ac97_codec.h>
-#include <sound/opl3.h>
-
-/* snd_als300_set_irq_flag */
-#define IRQ_DISABLE 0
-#define IRQ_ENABLE 1
-
-/* I/O port layout */
-#define AC97_ACCESS 0x00
-#define AC97_READ 0x04
-#define AC97_STATUS 0x06
-#define AC97_DATA_AVAIL (1<<6)
-#define AC97_BUSY (1<<7)
-#define ALS300_IRQ_STATUS 0x07 /* ALS300 Only */
-#define IRQ_PLAYBACK (1<<3)
-#define IRQ_CAPTURE (1<<2)
-#define GCR_DATA 0x08
-#define GCR_INDEX 0x0C
-#define ALS300P_DRAM_IRQ_STATUS 0x0D /* ALS300+ Only */
-#define MPU_IRQ_STATUS 0x0E /* ALS300 Rev. E+, ALS300+ */
-#define ALS300P_IRQ_STATUS 0x0F /* ALS300+ Only */
-
-/* General Control Registers */
-#define PLAYBACK_START 0x80
-#define PLAYBACK_END 0x81
-#define PLAYBACK_CONTROL 0x82
-#define TRANSFER_START (1<<16)
-#define FIFO_PAUSE (1<<17)
-#define RECORD_START 0x83
-#define RECORD_END 0x84
-#define RECORD_CONTROL 0x85
-#define DRAM_WRITE_CONTROL 0x8B
-#define WRITE_TRANS_START (1<<16)
-#define DRAM_MODE_2 (1<<17)
-#define MISC_CONTROL 0x8C
-#define IRQ_SET_BIT (1<<15)
-#define VMUTE_NORMAL (1<<20)
-#define MMUTE_NORMAL (1<<21)
-#define MUS_VOC_VOL 0x8E
-#define PLAYBACK_BLOCK_COUNTER 0x9A
-#define RECORD_BLOCK_COUNTER 0x9B
-
-#define DEBUG_CALLS 0
-#define DEBUG_PLAY_REC 0
-
-#if DEBUG_CALLS
-#define snd_als300_dbgcalls(format, args...) printk(KERN_DEBUG format, ##args)
-#define snd_als300_dbgcallenter() printk(KERN_ERR "--> %s\n", __func__)
-#define snd_als300_dbgcallleave() printk(KERN_ERR "<-- %s\n", __func__)
-#else
-#define snd_als300_dbgcalls(format, args...)
-#define snd_als300_dbgcallenter()
-#define snd_als300_dbgcallleave()
-#endif
-
-#if DEBUG_PLAY_REC
-#define snd_als300_dbgplay(format, args...) printk(KERN_ERR format, ##args)
-#else
-#define snd_als300_dbgplay(format, args...)
-#endif
-
-enum {DEVICE_ALS300, DEVICE_ALS300_PLUS};
-
-MODULE_AUTHOR("Ash Willis <ashwillis@programmer.net>");
-MODULE_DESCRIPTION("Avance Logic ALS300");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS300},{Avance Logic,ALS300+}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for ALS300 sound card.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for ALS300 sound card.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable ALS300 sound card.");
-
-struct snd_als300 {
- unsigned long port;
- spinlock_t reg_lock;
- struct snd_card *card;
- struct pci_dev *pci;
-
- struct snd_pcm *pcm;
- struct snd_pcm_substream *playback_substream;
- struct snd_pcm_substream *capture_substream;
-
- struct snd_ac97 *ac97;
- struct snd_opl3 *opl3;
-
- struct resource *res_port;
-
- int irq;
-
- int chip_type; /* ALS300 or ALS300+ */
-
- char revision;
-};
-
-struct snd_als300_substream_data {
- int period_flipflop;
- int control_register;
- int block_counter_register;
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_als300_ids) = {
- { 0x4005, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300 },
- { 0x4005, 0x0308, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300_PLUS },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_als300_ids);
-
-static inline u32 snd_als300_gcr_read(unsigned long port, unsigned short reg)
-{
- outb(reg, port+GCR_INDEX);
- return inl(port+GCR_DATA);
-}
-
-static inline void snd_als300_gcr_write(unsigned long port,
- unsigned short reg, u32 val)
-{
- outb(reg, port+GCR_INDEX);
- outl(val, port+GCR_DATA);
-}
-
-/* Enable/Disable Interrupts */
-static void snd_als300_set_irq_flag(struct snd_als300 *chip, int cmd)
-{
- u32 tmp = snd_als300_gcr_read(chip->port, MISC_CONTROL);
- snd_als300_dbgcallenter();
-
- /* boolean XOR check, since old vs. new hardware have
- directly reversed bit setting for ENABLE and DISABLE.
- ALS300+ acts like newer versions of ALS300 */
- if (((chip->revision > 5 || chip->chip_type == DEVICE_ALS300_PLUS) ^
- (cmd == IRQ_ENABLE)) == 0)
- tmp |= IRQ_SET_BIT;
- else
- tmp &= ~IRQ_SET_BIT;
- snd_als300_gcr_write(chip->port, MISC_CONTROL, tmp);
- snd_als300_dbgcallleave();
-}
-
-static int snd_als300_free(struct snd_als300 *chip)
-{
- snd_als300_dbgcallenter();
- snd_als300_set_irq_flag(chip, IRQ_DISABLE);
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
- kfree(chip);
- snd_als300_dbgcallleave();
- return 0;
-}
-
-static int snd_als300_dev_free(struct snd_device *device)
-{
- struct snd_als300 *chip = device->device_data;
- return snd_als300_free(chip);
-}
-
-static irqreturn_t snd_als300_interrupt(int irq, void *dev_id)
-{
- u8 status;
- struct snd_als300 *chip = dev_id;
- struct snd_als300_substream_data *data;
-
- status = inb(chip->port+ALS300_IRQ_STATUS);
- if (!status) /* shared IRQ, for different device?? Exit ASAP! */
- return IRQ_NONE;
-
- /* ACK everything ASAP */
- outb(status, chip->port+ALS300_IRQ_STATUS);
- if (status & IRQ_PLAYBACK) {
- if (chip->pcm && chip->playback_substream) {
- data = chip->playback_substream->runtime->private_data;
- data->period_flipflop ^= 1;
- snd_pcm_period_elapsed(chip->playback_substream);
- snd_als300_dbgplay("IRQ_PLAYBACK\n");
- }
- }
- if (status & IRQ_CAPTURE) {
- if (chip->pcm && chip->capture_substream) {
- data = chip->capture_substream->runtime->private_data;
- data->period_flipflop ^= 1;
- snd_pcm_period_elapsed(chip->capture_substream);
- snd_als300_dbgplay("IRQ_CAPTURE\n");
- }
- }
- return IRQ_HANDLED;
-}
-
-static irqreturn_t snd_als300plus_interrupt(int irq, void *dev_id)
-{
- u8 general, mpu, dram;
- struct snd_als300 *chip = dev_id;
- struct snd_als300_substream_data *data;
-
- general = inb(chip->port+ALS300P_IRQ_STATUS);
- mpu = inb(chip->port+MPU_IRQ_STATUS);
- dram = inb(chip->port+ALS300P_DRAM_IRQ_STATUS);
-
- /* shared IRQ, for different device?? Exit ASAP! */
- if ((general == 0) && ((mpu & 0x80) == 0) && ((dram & 0x01) == 0))
- return IRQ_NONE;
-
- if (general & IRQ_PLAYBACK) {
- if (chip->pcm && chip->playback_substream) {
- outb(IRQ_PLAYBACK, chip->port+ALS300P_IRQ_STATUS);
- data = chip->playback_substream->runtime->private_data;
- data->period_flipflop ^= 1;
- snd_pcm_period_elapsed(chip->playback_substream);
- snd_als300_dbgplay("IRQ_PLAYBACK\n");
- }
- }
- if (general & IRQ_CAPTURE) {
- if (chip->pcm && chip->capture_substream) {
- outb(IRQ_CAPTURE, chip->port+ALS300P_IRQ_STATUS);
- data = chip->capture_substream->runtime->private_data;
- data->period_flipflop ^= 1;
- snd_pcm_period_elapsed(chip->capture_substream);
- snd_als300_dbgplay("IRQ_CAPTURE\n");
- }
- }
- /* FIXME: Ack other interrupt types. Not important right now as
- * those other devices aren't enabled. */
- return IRQ_HANDLED;
-}
-
-static void __devexit snd_als300_remove(struct pci_dev *pci)
-{
- snd_als300_dbgcallenter();
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
- snd_als300_dbgcallleave();
-}
-
-static unsigned short snd_als300_ac97_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- int i;
- struct snd_als300 *chip = ac97->private_data;
-
- for (i = 0; i < 1000; i++) {
- if ((inb(chip->port+AC97_STATUS) & (AC97_BUSY)) == 0)
- break;
- udelay(10);
- }
- outl((reg << 24) | (1 << 31), chip->port+AC97_ACCESS);
-
- for (i = 0; i < 1000; i++) {
- if ((inb(chip->port+AC97_STATUS) & (AC97_DATA_AVAIL)) != 0)
- break;
- udelay(10);
- }
- return inw(chip->port+AC97_READ);
-}
-
-static void snd_als300_ac97_write(struct snd_ac97 *ac97,
- unsigned short reg, unsigned short val)
-{
- int i;
- struct snd_als300 *chip = ac97->private_data;
-
- for (i = 0; i < 1000; i++) {
- if ((inb(chip->port+AC97_STATUS) & (AC97_BUSY)) == 0)
- break;
- udelay(10);
- }
- outl((reg << 24) | val, chip->port+AC97_ACCESS);
-}
-
-static int snd_als300_ac97(struct snd_als300 *chip)
-{
- struct snd_ac97_bus *bus;
- struct snd_ac97_template ac97;
- int err;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_als300_ac97_write,
- .read = snd_als300_ac97_read,
- };
-
- snd_als300_dbgcallenter();
- if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus)) < 0)
- return err;
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = chip;
-
- snd_als300_dbgcallleave();
- return snd_ac97_mixer(bus, &ac97, &chip->ac97);
-}
-
-/* hardware definition
- *
- * In AC97 mode, we always use 48k/16bit/stereo.
- * Any request to change data type is ignored by
- * the card when it is running outside of legacy
- * mode.
- */
-static struct snd_pcm_hardware snd_als300_playback_hw =
-{
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 64 * 1024,
- .period_bytes_min = 64,
- .period_bytes_max = 32 * 1024,
- .periods_min = 2,
- .periods_max = 2,
-};
-
-static struct snd_pcm_hardware snd_als300_capture_hw =
-{
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 64 * 1024,
- .period_bytes_min = 64,
- .period_bytes_max = 32 * 1024,
- .periods_min = 2,
- .periods_max = 2,
-};
-
-static int snd_als300_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_als300 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_als300_substream_data *data = kzalloc(sizeof(*data),
- GFP_KERNEL);
-
- snd_als300_dbgcallenter();
- chip->playback_substream = substream;
- runtime->hw = snd_als300_playback_hw;
- runtime->private_data = data;
- data->control_register = PLAYBACK_CONTROL;
- data->block_counter_register = PLAYBACK_BLOCK_COUNTER;
- snd_als300_dbgcallleave();
- return 0;
-}
-
-static int snd_als300_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_als300 *chip = snd_pcm_substream_chip(substream);
- struct snd_als300_substream_data *data;
-
- data = substream->runtime->private_data;
- snd_als300_dbgcallenter();
- kfree(data);
- chip->playback_substream = NULL;
- snd_pcm_lib_free_pages(substream);
- snd_als300_dbgcallleave();
- return 0;
-}
-
-static int snd_als300_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_als300 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_als300_substream_data *data = kzalloc(sizeof(*data),
- GFP_KERNEL);
-
- snd_als300_dbgcallenter();
- chip->capture_substream = substream;
- runtime->hw = snd_als300_capture_hw;
- runtime->private_data = data;
- data->control_register = RECORD_CONTROL;
- data->block_counter_register = RECORD_BLOCK_COUNTER;
- snd_als300_dbgcallleave();
- return 0;
-}
-
-static int snd_als300_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_als300 *chip = snd_pcm_substream_chip(substream);
- struct snd_als300_substream_data *data;
-
- data = substream->runtime->private_data;
- snd_als300_dbgcallenter();
- kfree(data);
- chip->capture_substream = NULL;
- snd_pcm_lib_free_pages(substream);
- snd_als300_dbgcallleave();
- return 0;
-}
-
-static int snd_als300_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-}
-
-static int snd_als300_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_als300_playback_prepare(struct snd_pcm_substream *substream)
-{
- u32 tmp;
- struct snd_als300 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned short period_bytes = snd_pcm_lib_period_bytes(substream);
- unsigned short buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
-
- snd_als300_dbgcallenter();
- spin_lock_irq(&chip->reg_lock);
- tmp = snd_als300_gcr_read(chip->port, PLAYBACK_CONTROL);
- tmp &= ~TRANSFER_START;
-
- snd_als300_dbgplay("Period bytes: %d Buffer bytes %d\n",
- period_bytes, buffer_bytes);
-
- /* set block size */
- tmp &= 0xffff0000;
- tmp |= period_bytes - 1;
- snd_als300_gcr_write(chip->port, PLAYBACK_CONTROL, tmp);
-
- /* set dma area */
- snd_als300_gcr_write(chip->port, PLAYBACK_START,
- runtime->dma_addr);
- snd_als300_gcr_write(chip->port, PLAYBACK_END,
- runtime->dma_addr + buffer_bytes - 1);
- spin_unlock_irq(&chip->reg_lock);
- snd_als300_dbgcallleave();
- return 0;
-}
-
-static int snd_als300_capture_prepare(struct snd_pcm_substream *substream)
-{
- u32 tmp;
- struct snd_als300 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned short period_bytes = snd_pcm_lib_period_bytes(substream);
- unsigned short buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
-
- snd_als300_dbgcallenter();
- spin_lock_irq(&chip->reg_lock);
- tmp = snd_als300_gcr_read(chip->port, RECORD_CONTROL);
- tmp &= ~TRANSFER_START;
-
- snd_als300_dbgplay("Period bytes: %d Buffer bytes %d\n", period_bytes,
- buffer_bytes);
-
- /* set block size */
- tmp &= 0xffff0000;
- tmp |= period_bytes - 1;
-
- /* set dma area */
- snd_als300_gcr_write(chip->port, RECORD_CONTROL, tmp);
- snd_als300_gcr_write(chip->port, RECORD_START,
- runtime->dma_addr);
- snd_als300_gcr_write(chip->port, RECORD_END,
- runtime->dma_addr + buffer_bytes - 1);
- spin_unlock_irq(&chip->reg_lock);
- snd_als300_dbgcallleave();
- return 0;
-}
-
-static int snd_als300_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_als300 *chip = snd_pcm_substream_chip(substream);
- u32 tmp;
- struct snd_als300_substream_data *data;
- unsigned short reg;
- int ret = 0;
-
- data = substream->runtime->private_data;
- reg = data->control_register;
-
- snd_als300_dbgcallenter();
- spin_lock(&chip->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- tmp = snd_als300_gcr_read(chip->port, reg);
- data->period_flipflop = 1;
- snd_als300_gcr_write(chip->port, reg, tmp | TRANSFER_START);
- snd_als300_dbgplay("TRIGGER START\n");
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- tmp = snd_als300_gcr_read(chip->port, reg);
- snd_als300_gcr_write(chip->port, reg, tmp & ~TRANSFER_START);
- snd_als300_dbgplay("TRIGGER STOP\n");
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- tmp = snd_als300_gcr_read(chip->port, reg);
- snd_als300_gcr_write(chip->port, reg, tmp | FIFO_PAUSE);
- snd_als300_dbgplay("TRIGGER PAUSE\n");
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- tmp = snd_als300_gcr_read(chip->port, reg);
- snd_als300_gcr_write(chip->port, reg, tmp & ~FIFO_PAUSE);
- snd_als300_dbgplay("TRIGGER RELEASE\n");
- break;
- default:
- snd_als300_dbgplay("TRIGGER INVALID\n");
- ret = -EINVAL;
- }
- spin_unlock(&chip->reg_lock);
- snd_als300_dbgcallleave();
- return ret;
-}
-
-static snd_pcm_uframes_t snd_als300_pointer(struct snd_pcm_substream *substream)
-{
- u16 current_ptr;
- struct snd_als300 *chip = snd_pcm_substream_chip(substream);
- struct snd_als300_substream_data *data;
- unsigned short period_bytes;
-
- data = substream->runtime->private_data;
- period_bytes = snd_pcm_lib_period_bytes(substream);
-
- snd_als300_dbgcallenter();
- spin_lock(&chip->reg_lock);
- current_ptr = (u16) snd_als300_gcr_read(chip->port,
- data->block_counter_register) + 4;
- spin_unlock(&chip->reg_lock);
- if (current_ptr > period_bytes)
- current_ptr = 0;
- else
- current_ptr = period_bytes - current_ptr;
-
- if (data->period_flipflop == 0)
- current_ptr += period_bytes;
- snd_als300_dbgplay("Pointer (bytes): %d\n", current_ptr);
- snd_als300_dbgcallleave();
- return bytes_to_frames(substream->runtime, current_ptr);
-}
-
-static struct snd_pcm_ops snd_als300_playback_ops = {
- .open = snd_als300_playback_open,
- .close = snd_als300_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_als300_pcm_hw_params,
- .hw_free = snd_als300_pcm_hw_free,
- .prepare = snd_als300_playback_prepare,
- .trigger = snd_als300_trigger,
- .pointer = snd_als300_pointer,
-};
-
-static struct snd_pcm_ops snd_als300_capture_ops = {
- .open = snd_als300_capture_open,
- .close = snd_als300_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_als300_pcm_hw_params,
- .hw_free = snd_als300_pcm_hw_free,
- .prepare = snd_als300_capture_prepare,
- .trigger = snd_als300_trigger,
- .pointer = snd_als300_pointer,
-};
-
-static int __devinit snd_als300_new_pcm(struct snd_als300 *chip)
-{
- struct snd_pcm *pcm;
- int err;
-
- snd_als300_dbgcallenter();
- err = snd_pcm_new(chip->card, "ALS300", 0, 1, 1, &pcm);
- if (err < 0)
- return err;
- pcm->private_data = chip;
- strcpy(pcm->name, "ALS300");
- chip->pcm = pcm;
-
- /* set operators */
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_als300_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_als300_capture_ops);
-
- /* pre-allocation of buffers */
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci), 64*1024, 64*1024);
- snd_als300_dbgcallleave();
- return 0;
-}
-
-static void snd_als300_init(struct snd_als300 *chip)
-{
- unsigned long flags;
- u32 tmp;
-
- snd_als300_dbgcallenter();
- spin_lock_irqsave(&chip->reg_lock, flags);
- chip->revision = (snd_als300_gcr_read(chip->port, MISC_CONTROL) >> 16)
- & 0x0000000F;
- /* Setup DRAM */
- tmp = snd_als300_gcr_read(chip->port, DRAM_WRITE_CONTROL);
- snd_als300_gcr_write(chip->port, DRAM_WRITE_CONTROL,
- (tmp | DRAM_MODE_2)
- & ~WRITE_TRANS_START);
-
- /* Enable IRQ output */
- snd_als300_set_irq_flag(chip, IRQ_ENABLE);
-
- /* Unmute hardware devices so their outputs get routed to
- * the onboard mixer */
- tmp = snd_als300_gcr_read(chip->port, MISC_CONTROL);
- snd_als300_gcr_write(chip->port, MISC_CONTROL,
- tmp | VMUTE_NORMAL | MMUTE_NORMAL);
-
- /* Reset volumes */
- snd_als300_gcr_write(chip->port, MUS_VOC_VOL, 0);
-
- /* Make sure playback transfer is stopped */
- tmp = snd_als300_gcr_read(chip->port, PLAYBACK_CONTROL);
- snd_als300_gcr_write(chip->port, PLAYBACK_CONTROL,
- tmp & ~TRANSFER_START);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- snd_als300_dbgcallleave();
-}
-
-static int __devinit snd_als300_create(struct snd_card *card,
- struct pci_dev *pci, int chip_type,
- struct snd_als300 **rchip)
-{
- struct snd_als300 *chip;
- void *irq_handler;
- int err;
-
- static struct snd_device_ops ops = {
- .dev_free = snd_als300_dev_free,
- };
- *rchip = NULL;
-
- snd_als300_dbgcallenter();
- if ((err = pci_enable_device(pci)) < 0)
- return err;
-
- if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) {
- printk(KERN_ERR "error setting 28bit DMA mask\n");
- pci_disable_device(pci);
- return -ENXIO;
- }
- pci_set_master(pci);
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
- chip->chip_type = chip_type;
- spin_lock_init(&chip->reg_lock);
-
- if ((err = pci_request_regions(pci, "ALS300")) < 0) {
- kfree(chip);
- pci_disable_device(pci);
- return err;
- }
- chip->port = pci_resource_start(pci, 0);
-
- if (chip->chip_type == DEVICE_ALS300_PLUS)
- irq_handler = snd_als300plus_interrupt;
- else
- irq_handler = snd_als300_interrupt;
-
- if (request_irq(pci->irq, irq_handler, IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_als300_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
-
-
- snd_als300_init(chip);
-
- err = snd_als300_ac97(chip);
- if (err < 0) {
- snd_printk(KERN_WARNING "Could not create ac97\n");
- snd_als300_free(chip);
- return err;
- }
-
- if ((err = snd_als300_new_pcm(chip)) < 0) {
- snd_printk(KERN_WARNING "Could not create PCM\n");
- snd_als300_free(chip);
- return err;
- }
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
- chip, &ops)) < 0) {
- snd_als300_free(chip);
- return err;
- }
-
- snd_card_set_dev(card, &pci->dev);
-
- *rchip = chip;
- snd_als300_dbgcallleave();
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int snd_als300_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_als300 *chip = card->private_data;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(chip->pcm);
- snd_ac97_suspend(chip->ac97);
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int snd_als300_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_als300 *chip = card->private_data;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "als300: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
-
- snd_als300_init(chip);
- snd_ac97_resume(chip->ac97);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif
-
-static int __devinit snd_als300_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct snd_als300 *chip;
- int err, chip_type;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
-
- if (err < 0)
- return err;
-
- chip_type = pci_id->driver_data;
-
- if ((err = snd_als300_create(card, pci, chip_type, &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
- card->private_data = chip;
-
- strcpy(card->driver, "ALS300");
- if (chip->chip_type == DEVICE_ALS300_PLUS)
- /* don't know much about ALS300+ yet
- * print revision number for now */
- sprintf(card->shortname, "ALS300+ (Rev. %d)", chip->revision);
- else
- sprintf(card->shortname, "ALS300 (Rev. %c)", 'A' +
- chip->revision - 1);
- sprintf(card->longname, "%s at 0x%lx irq %i",
- card->shortname, chip->port, chip->irq);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_als300_ids,
- .probe = snd_als300_probe,
- .remove = __devexit_p(snd_als300_remove),
-#ifdef CONFIG_PM
- .suspend = snd_als300_suspend,
- .resume = snd_als300_resume,
-#endif
-};
-
-static int __init alsa_card_als300_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_als300_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_als300_init)
-module_exit(alsa_card_als300_exit)
diff --git a/ANDROID_3.4.5/sound/pci/als4000.c b/ANDROID_3.4.5/sound/pci/als4000.c
deleted file mode 100644
index 3269b801..00000000
--- a/ANDROID_3.4.5/sound/pci/als4000.c
+++ /dev/null
@@ -1,1061 +0,0 @@
-/*
- * card-als4000.c - driver for Avance Logic ALS4000 based soundcards.
- * Copyright (C) 2000 by Bart Hartgers <bart@etpmod.phys.tue.nl>,
- * Jaroslav Kysela <perex@perex.cz>
- * Copyright (C) 2002, 2008 by Andreas Mohr <hw7oshyuv3001@sneakemail.com>
- *
- * Framework borrowed from Massimo Piccioni's card-als100.c.
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * NOTES
- *
- * Since Avance does not provide any meaningful documentation, and I
- * bought an ALS4000 based soundcard, I was forced to base this driver
- * on reverse engineering.
- *
- * Note: this is no longer true (thank you!):
- * pretty verbose chip docu (ALS4000a.PDF) can be found on the ALSA web site.
- * Page numbers stated anywhere below with the "SPECS_PAGE:" tag
- * refer to: ALS4000a.PDF specs Ver 1.0, May 28th, 1998.
- *
- * The ALS4000 seems to be the PCI-cousin of the ALS100. It contains an
- * ALS100-like SB DSP/mixer, an OPL3 synth, a MPU401 and a gameport
- * interface. These subsystems can be mapped into ISA io-port space,
- * using the PCI-interface. In addition, the PCI-bit provides DMA and IRQ
- * services to the subsystems.
- *
- * While ALS4000 is very similar to a SoundBlaster, the differences in
- * DMA and capturing require more changes to the SoundBlaster than
- * desirable, so I made this separate driver.
- *
- * The ALS4000 can do real full duplex playback/capture.
- *
- * FMDAC:
- * - 0x4f -> port 0x14
- * - port 0x15 |= 1
- *
- * Enable/disable 3D sound:
- * - 0x50 -> port 0x14
- * - change bit 6 (0x40) of port 0x15
- *
- * Set QSound:
- * - 0xdb -> port 0x14
- * - set port 0x15:
- * 0x3e (mode 3), 0x3c (mode 2), 0x3a (mode 1), 0x38 (mode 0)
- *
- * Set KSound:
- * - value -> some port 0x0c0d
- *
- * ToDo:
- * - by default, don't enable legacy game and use PCI game I/O
- * - power management? (card can do voice wakeup according to datasheet!!)
- */
-
-#include <asm/io.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/gameport.h>
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/rawmidi.h>
-#include <sound/mpu401.h>
-#include <sound/opl3.h>
-#include <sound/sb.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Bart Hartgers <bart@etpmod.phys.tue.nl>, Andreas Mohr");
-MODULE_DESCRIPTION("Avance Logic ALS4000");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS4000}}");
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK 1
-#endif
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-#ifdef SUPPORT_JOYSTICK
-static int joystick_port[SNDRV_CARDS];
-#endif
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for ALS4000 soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for ALS4000 soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable ALS4000 soundcard.");
-#ifdef SUPPORT_JOYSTICK
-module_param_array(joystick_port, int, NULL, 0444);
-MODULE_PARM_DESC(joystick_port, "Joystick port address for ALS4000 soundcard. (0 = disabled)");
-#endif
-
-struct snd_card_als4000 {
- /* most frequent access first */
- unsigned long iobase;
- struct pci_dev *pci;
- struct snd_sb *chip;
-#ifdef SUPPORT_JOYSTICK
- struct gameport *gameport;
-#endif
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_als4000_ids) = {
- { 0x4005, 0x4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ALS4000 */
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_als4000_ids);
-
-enum als4k_iobase_t {
- /* IOx: B == Byte, W = Word, D = DWord; SPECS_PAGE: 37 */
- ALS4K_IOD_00_AC97_ACCESS = 0x00,
- ALS4K_IOW_04_AC97_READ = 0x04,
- ALS4K_IOB_06_AC97_STATUS = 0x06,
- ALS4K_IOB_07_IRQSTATUS = 0x07,
- ALS4K_IOD_08_GCR_DATA = 0x08,
- ALS4K_IOB_0C_GCR_INDEX = 0x0c,
- ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU = 0x0e,
- ALS4K_IOB_10_ADLIB_ADDR0 = 0x10,
- ALS4K_IOB_11_ADLIB_ADDR1 = 0x11,
- ALS4K_IOB_12_ADLIB_ADDR2 = 0x12,
- ALS4K_IOB_13_ADLIB_ADDR3 = 0x13,
- ALS4K_IOB_14_MIXER_INDEX = 0x14,
- ALS4K_IOB_15_MIXER_DATA = 0x15,
- ALS4K_IOB_16_ESP_RESET = 0x16,
- ALS4K_IOB_16_ACK_FOR_CR1E = 0x16, /* 2nd function */
- ALS4K_IOB_18_OPL_ADDR0 = 0x18,
- ALS4K_IOB_19_OPL_ADDR1 = 0x19,
- ALS4K_IOB_1A_ESP_RD_DATA = 0x1a,
- ALS4K_IOB_1C_ESP_CMD_DATA = 0x1c,
- ALS4K_IOB_1C_ESP_WR_STATUS = 0x1c, /* 2nd function */
- ALS4K_IOB_1E_ESP_RD_STATUS8 = 0x1e,
- ALS4K_IOB_1F_ESP_RD_STATUS16 = 0x1f,
- ALS4K_IOB_20_ESP_GAMEPORT_200 = 0x20,
- ALS4K_IOB_21_ESP_GAMEPORT_201 = 0x21,
- ALS4K_IOB_30_MIDI_DATA = 0x30,
- ALS4K_IOB_31_MIDI_STATUS = 0x31,
- ALS4K_IOB_31_MIDI_COMMAND = 0x31, /* 2nd function */
-};
-
-enum als4k_iobase_0e_t {
- ALS4K_IOB_0E_MPU_IRQ = 0x10,
- ALS4K_IOB_0E_CR1E_IRQ = 0x40,
- ALS4K_IOB_0E_SB_DMA_IRQ = 0x80,
-};
-
-enum als4k_gcr_t { /* all registers 32bit wide; SPECS_PAGE: 38 to 42 */
- ALS4K_GCR8C_MISC_CTRL = 0x8c,
- ALS4K_GCR90_TEST_MODE_REG = 0x90,
- ALS4K_GCR91_DMA0_ADDR = 0x91,
- ALS4K_GCR92_DMA0_MODE_COUNT = 0x92,
- ALS4K_GCR93_DMA1_ADDR = 0x93,
- ALS4K_GCR94_DMA1_MODE_COUNT = 0x94,
- ALS4K_GCR95_DMA3_ADDR = 0x95,
- ALS4K_GCR96_DMA3_MODE_COUNT = 0x96,
- ALS4K_GCR99_DMA_EMULATION_CTRL = 0x99,
- ALS4K_GCRA0_FIFO1_CURRENT_ADDR = 0xa0,
- ALS4K_GCRA1_FIFO1_STATUS_BYTECOUNT = 0xa1,
- ALS4K_GCRA2_FIFO2_PCIADDR = 0xa2,
- ALS4K_GCRA3_FIFO2_COUNT = 0xa3,
- ALS4K_GCRA4_FIFO2_CURRENT_ADDR = 0xa4,
- ALS4K_GCRA5_FIFO1_STATUS_BYTECOUNT = 0xa5,
- ALS4K_GCRA6_PM_CTRL = 0xa6,
- ALS4K_GCRA7_PCI_ACCESS_STORAGE = 0xa7,
- ALS4K_GCRA8_LEGACY_CFG1 = 0xa8,
- ALS4K_GCRA9_LEGACY_CFG2 = 0xa9,
- ALS4K_GCRFF_DUMMY_SCRATCH = 0xff,
-};
-
-enum als4k_gcr8c_t {
- ALS4K_GCR8C_IRQ_MASK_CTRL_ENABLE = 0x8000,
- ALS4K_GCR8C_CHIP_REV_MASK = 0xf0000
-};
-
-static inline void snd_als4k_iobase_writeb(unsigned long iobase,
- enum als4k_iobase_t reg,
- u8 val)
-{
- outb(val, iobase + reg);
-}
-
-static inline void snd_als4k_iobase_writel(unsigned long iobase,
- enum als4k_iobase_t reg,
- u32 val)
-{
- outl(val, iobase + reg);
-}
-
-static inline u8 snd_als4k_iobase_readb(unsigned long iobase,
- enum als4k_iobase_t reg)
-{
- return inb(iobase + reg);
-}
-
-static inline u32 snd_als4k_iobase_readl(unsigned long iobase,
- enum als4k_iobase_t reg)
-{
- return inl(iobase + reg);
-}
-
-static inline void snd_als4k_gcr_write_addr(unsigned long iobase,
- enum als4k_gcr_t reg,
- u32 val)
-{
- snd_als4k_iobase_writeb(iobase, ALS4K_IOB_0C_GCR_INDEX, reg);
- snd_als4k_iobase_writel(iobase, ALS4K_IOD_08_GCR_DATA, val);
-}
-
-static inline void snd_als4k_gcr_write(struct snd_sb *sb,
- enum als4k_gcr_t reg,
- u32 val)
-{
- snd_als4k_gcr_write_addr(sb->alt_port, reg, val);
-}
-
-static inline u32 snd_als4k_gcr_read_addr(unsigned long iobase,
- enum als4k_gcr_t reg)
-{
- /* SPECS_PAGE: 37/38 */
- snd_als4k_iobase_writeb(iobase, ALS4K_IOB_0C_GCR_INDEX, reg);
- return snd_als4k_iobase_readl(iobase, ALS4K_IOD_08_GCR_DATA);
-}
-
-static inline u32 snd_als4k_gcr_read(struct snd_sb *sb, enum als4k_gcr_t reg)
-{
- return snd_als4k_gcr_read_addr(sb->alt_port, reg);
-}
-
-enum als4k_cr_t { /* all registers 8bit wide; SPECS_PAGE: 20 to 23 */
- ALS4K_CR0_SB_CONFIG = 0x00,
- ALS4K_CR2_MISC_CONTROL = 0x02,
- ALS4K_CR3_CONFIGURATION = 0x03,
- ALS4K_CR17_FIFO_STATUS = 0x17,
- ALS4K_CR18_ESP_MAJOR_VERSION = 0x18,
- ALS4K_CR19_ESP_MINOR_VERSION = 0x19,
- ALS4K_CR1A_MPU401_UART_MODE_CONTROL = 0x1a,
- ALS4K_CR1C_FIFO2_BLOCK_LENGTH_LO = 0x1c,
- ALS4K_CR1D_FIFO2_BLOCK_LENGTH_HI = 0x1d,
- ALS4K_CR1E_FIFO2_CONTROL = 0x1e, /* secondary PCM FIFO (recording) */
- ALS4K_CR3A_MISC_CONTROL = 0x3a,
- ALS4K_CR3B_CRC32_BYTE0 = 0x3b, /* for testing, activate via CR3A */
- ALS4K_CR3C_CRC32_BYTE1 = 0x3c,
- ALS4K_CR3D_CRC32_BYTE2 = 0x3d,
- ALS4K_CR3E_CRC32_BYTE3 = 0x3e,
-};
-
-enum als4k_cr0_t {
- ALS4K_CR0_DMA_CONTIN_MODE_CTRL = 0x02, /* IRQ/FIFO controlled for 0/1 */
- ALS4K_CR0_DMA_90H_MODE_CTRL = 0x04, /* IRQ/FIFO controlled for 0/1 */
- ALS4K_CR0_MX80_81_REG_WRITE_ENABLE = 0x80,
-};
-
-static inline void snd_als4_cr_write(struct snd_sb *chip,
- enum als4k_cr_t reg,
- u8 data)
-{
- /* Control Register is reg | 0xc0 (bit 7, 6 set) on sbmixer_index
- * NOTE: assumes chip->mixer_lock to be locked externally already!
- * SPECS_PAGE: 6 */
- snd_sbmixer_write(chip, reg | 0xc0, data);
-}
-
-static inline u8 snd_als4_cr_read(struct snd_sb *chip,
- enum als4k_cr_t reg)
-{
- /* NOTE: assumes chip->mixer_lock to be locked externally already! */
- return snd_sbmixer_read(chip, reg | 0xc0);
-}
-
-
-
-static void snd_als4000_set_rate(struct snd_sb *chip, unsigned int rate)
-{
- if (!(chip->mode & SB_RATE_LOCK)) {
- snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE_OUT);
- snd_sbdsp_command(chip, rate>>8);
- snd_sbdsp_command(chip, rate);
- }
-}
-
-static inline void snd_als4000_set_capture_dma(struct snd_sb *chip,
- dma_addr_t addr, unsigned size)
-{
- /* SPECS_PAGE: 40 */
- snd_als4k_gcr_write(chip, ALS4K_GCRA2_FIFO2_PCIADDR, addr);
- snd_als4k_gcr_write(chip, ALS4K_GCRA3_FIFO2_COUNT, (size-1));
-}
-
-static inline void snd_als4000_set_playback_dma(struct snd_sb *chip,
- dma_addr_t addr,
- unsigned size)
-{
- /* SPECS_PAGE: 38 */
- snd_als4k_gcr_write(chip, ALS4K_GCR91_DMA0_ADDR, addr);
- snd_als4k_gcr_write(chip, ALS4K_GCR92_DMA0_MODE_COUNT,
- (size-1)|0x180000);
-}
-
-#define ALS4000_FORMAT_SIGNED (1<<0)
-#define ALS4000_FORMAT_16BIT (1<<1)
-#define ALS4000_FORMAT_STEREO (1<<2)
-
-static int snd_als4000_get_format(struct snd_pcm_runtime *runtime)
-{
- int result;
-
- result = 0;
- if (snd_pcm_format_signed(runtime->format))
- result |= ALS4000_FORMAT_SIGNED;
- if (snd_pcm_format_physical_width(runtime->format) == 16)
- result |= ALS4000_FORMAT_16BIT;
- if (runtime->channels > 1)
- result |= ALS4000_FORMAT_STEREO;
- return result;
-}
-
-/* structure for setting up playback */
-static const struct {
- unsigned char dsp_cmd, dma_on, dma_off, format;
-} playback_cmd_vals[]={
-/* ALS4000_FORMAT_U8_MONO */
-{ SB_DSP4_OUT8_AI, SB_DSP_DMA8_ON, SB_DSP_DMA8_OFF, SB_DSP4_MODE_UNS_MONO },
-/* ALS4000_FORMAT_S8_MONO */
-{ SB_DSP4_OUT8_AI, SB_DSP_DMA8_ON, SB_DSP_DMA8_OFF, SB_DSP4_MODE_SIGN_MONO },
-/* ALS4000_FORMAT_U16L_MONO */
-{ SB_DSP4_OUT16_AI, SB_DSP_DMA16_ON, SB_DSP_DMA16_OFF, SB_DSP4_MODE_UNS_MONO },
-/* ALS4000_FORMAT_S16L_MONO */
-{ SB_DSP4_OUT16_AI, SB_DSP_DMA16_ON, SB_DSP_DMA16_OFF, SB_DSP4_MODE_SIGN_MONO },
-/* ALS4000_FORMAT_U8_STEREO */
-{ SB_DSP4_OUT8_AI, SB_DSP_DMA8_ON, SB_DSP_DMA8_OFF, SB_DSP4_MODE_UNS_STEREO },
-/* ALS4000_FORMAT_S8_STEREO */
-{ SB_DSP4_OUT8_AI, SB_DSP_DMA8_ON, SB_DSP_DMA8_OFF, SB_DSP4_MODE_SIGN_STEREO },
-/* ALS4000_FORMAT_U16L_STEREO */
-{ SB_DSP4_OUT16_AI, SB_DSP_DMA16_ON, SB_DSP_DMA16_OFF, SB_DSP4_MODE_UNS_STEREO },
-/* ALS4000_FORMAT_S16L_STEREO */
-{ SB_DSP4_OUT16_AI, SB_DSP_DMA16_ON, SB_DSP_DMA16_OFF, SB_DSP4_MODE_SIGN_STEREO },
-};
-#define playback_cmd(chip) (playback_cmd_vals[(chip)->playback_format])
-
-/* structure for setting up capture */
-enum { CMD_WIDTH8=0x04, CMD_SIGNED=0x10, CMD_MONO=0x80, CMD_STEREO=0xA0 };
-static const unsigned char capture_cmd_vals[]=
-{
-CMD_WIDTH8|CMD_MONO, /* ALS4000_FORMAT_U8_MONO */
-CMD_WIDTH8|CMD_SIGNED|CMD_MONO, /* ALS4000_FORMAT_S8_MONO */
-CMD_MONO, /* ALS4000_FORMAT_U16L_MONO */
-CMD_SIGNED|CMD_MONO, /* ALS4000_FORMAT_S16L_MONO */
-CMD_WIDTH8|CMD_STEREO, /* ALS4000_FORMAT_U8_STEREO */
-CMD_WIDTH8|CMD_SIGNED|CMD_STEREO, /* ALS4000_FORMAT_S8_STEREO */
-CMD_STEREO, /* ALS4000_FORMAT_U16L_STEREO */
-CMD_SIGNED|CMD_STEREO, /* ALS4000_FORMAT_S16L_STEREO */
-};
-#define capture_cmd(chip) (capture_cmd_vals[(chip)->capture_format])
-
-static int snd_als4000_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static int snd_als4000_hw_free(struct snd_pcm_substream *substream)
-{
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-static int snd_als4000_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long size;
- unsigned count;
-
- chip->capture_format = snd_als4000_get_format(runtime);
-
- size = snd_pcm_lib_buffer_bytes(substream);
- count = snd_pcm_lib_period_bytes(substream);
-
- if (chip->capture_format & ALS4000_FORMAT_16BIT)
- count >>= 1;
- count--;
-
- spin_lock_irq(&chip->reg_lock);
- snd_als4000_set_rate(chip, runtime->rate);
- snd_als4000_set_capture_dma(chip, runtime->dma_addr, size);
- spin_unlock_irq(&chip->reg_lock);
- spin_lock_irq(&chip->mixer_lock);
- snd_als4_cr_write(chip, ALS4K_CR1C_FIFO2_BLOCK_LENGTH_LO, count & 0xff);
- snd_als4_cr_write(chip, ALS4K_CR1D_FIFO2_BLOCK_LENGTH_HI, count >> 8);
- spin_unlock_irq(&chip->mixer_lock);
- return 0;
-}
-
-static int snd_als4000_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long size;
- unsigned count;
-
- chip->playback_format = snd_als4000_get_format(runtime);
-
- size = snd_pcm_lib_buffer_bytes(substream);
- count = snd_pcm_lib_period_bytes(substream);
-
- if (chip->playback_format & ALS4000_FORMAT_16BIT)
- count >>= 1;
- count--;
-
- /* FIXME: from second playback on, there's a lot more clicks and pops
- * involved here than on first playback. Fiddling with
- * tons of different settings didn't help (DMA, speaker on/off,
- * reordering, ...). Something seems to get enabled on playback
- * that I haven't found out how to disable again, which then causes
- * the switching pops to reach the speakers the next time here. */
- spin_lock_irq(&chip->reg_lock);
- snd_als4000_set_rate(chip, runtime->rate);
- snd_als4000_set_playback_dma(chip, runtime->dma_addr, size);
-
- /* SPEAKER_ON not needed, since dma_on seems to also enable speaker */
- /* snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON); */
- snd_sbdsp_command(chip, playback_cmd(chip).dsp_cmd);
- snd_sbdsp_command(chip, playback_cmd(chip).format);
- snd_sbdsp_command(chip, count & 0xff);
- snd_sbdsp_command(chip, count >> 8);
- snd_sbdsp_command(chip, playback_cmd(chip).dma_off);
- spin_unlock_irq(&chip->reg_lock);
-
- return 0;
-}
-
-static int snd_als4000_capture_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- int result = 0;
-
- /* FIXME race condition in here!!!
- chip->mode non-atomic update gets consistently protected
- by reg_lock always, _except_ for this place!!
- Probably need to take reg_lock as outer (or inner??) lock, too.
- (or serialize both lock operations? probably not, though... - racy?)
- */
- spin_lock(&chip->mixer_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- chip->mode |= SB_RATE_LOCK_CAPTURE;
- snd_als4_cr_write(chip, ALS4K_CR1E_FIFO2_CONTROL,
- capture_cmd(chip));
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- chip->mode &= ~SB_RATE_LOCK_CAPTURE;
- snd_als4_cr_write(chip, ALS4K_CR1E_FIFO2_CONTROL,
- capture_cmd(chip));
- break;
- default:
- result = -EINVAL;
- break;
- }
- spin_unlock(&chip->mixer_lock);
- return result;
-}
-
-static int snd_als4000_playback_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- int result = 0;
-
- spin_lock(&chip->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- chip->mode |= SB_RATE_LOCK_PLAYBACK;
- snd_sbdsp_command(chip, playback_cmd(chip).dma_on);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- snd_sbdsp_command(chip, playback_cmd(chip).dma_off);
- chip->mode &= ~SB_RATE_LOCK_PLAYBACK;
- break;
- default:
- result = -EINVAL;
- break;
- }
- spin_unlock(&chip->reg_lock);
- return result;
-}
-
-static snd_pcm_uframes_t snd_als4000_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- unsigned int result;
-
- spin_lock(&chip->reg_lock);
- result = snd_als4k_gcr_read(chip, ALS4K_GCRA4_FIFO2_CURRENT_ADDR);
- spin_unlock(&chip->reg_lock);
- result &= 0xffff;
- return bytes_to_frames( substream->runtime, result );
-}
-
-static snd_pcm_uframes_t snd_als4000_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- unsigned result;
-
- spin_lock(&chip->reg_lock);
- result = snd_als4k_gcr_read(chip, ALS4K_GCRA0_FIFO1_CURRENT_ADDR);
- spin_unlock(&chip->reg_lock);
- result &= 0xffff;
- return bytes_to_frames( substream->runtime, result );
-}
-
-/* FIXME: this IRQ routine doesn't really support IRQ sharing (we always
- * return IRQ_HANDLED no matter whether we actually had an IRQ flag or not).
- * ALS4000a.PDF writes that while ACKing IRQ in PCI block will *not* ACK
- * the IRQ in the SB core, ACKing IRQ in SB block *will* ACK the PCI IRQ
- * register (alt_port + ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU). Probably something
- * could be optimized here to query/write one register only...
- * And even if both registers need to be queried, then there's still the
- * question of whether it's actually correct to ACK PCI IRQ before reading
- * SB IRQ like we do now, since ALS4000a.PDF mentions that PCI IRQ will *clear*
- * SB IRQ status.
- * (hmm, SPECS_PAGE: 38 mentions it the other way around!)
- * And do we *really* need the lock here for *reading* SB_DSP4_IRQSTATUS??
- * */
-static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id)
-{
- struct snd_sb *chip = dev_id;
- unsigned pci_irqstatus;
- unsigned sb_irqstatus;
-
- /* find out which bit of the ALS4000 PCI block produced the interrupt,
- SPECS_PAGE: 38, 5 */
- pci_irqstatus = snd_als4k_iobase_readb(chip->alt_port,
- ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU);
- if ((pci_irqstatus & ALS4K_IOB_0E_SB_DMA_IRQ)
- && (chip->playback_substream)) /* playback */
- snd_pcm_period_elapsed(chip->playback_substream);
- if ((pci_irqstatus & ALS4K_IOB_0E_CR1E_IRQ)
- && (chip->capture_substream)) /* capturing */
- snd_pcm_period_elapsed(chip->capture_substream);
- if ((pci_irqstatus & ALS4K_IOB_0E_MPU_IRQ)
- && (chip->rmidi)) /* MPU401 interrupt */
- snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
- /* ACK the PCI block IRQ */
- snd_als4k_iobase_writeb(chip->alt_port,
- ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU, pci_irqstatus);
-
- spin_lock(&chip->mixer_lock);
- /* SPECS_PAGE: 20 */
- sb_irqstatus = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS);
- spin_unlock(&chip->mixer_lock);
-
- if (sb_irqstatus & SB_IRQTYPE_8BIT)
- snd_sb_ack_8bit(chip);
- if (sb_irqstatus & SB_IRQTYPE_16BIT)
- snd_sb_ack_16bit(chip);
- if (sb_irqstatus & SB_IRQTYPE_MPUIN)
- inb(chip->mpu_port);
- if (sb_irqstatus & ALS4K_IRQTYPE_CR1E_DMA)
- snd_als4k_iobase_readb(chip->alt_port,
- ALS4K_IOB_16_ACK_FOR_CR1E);
-
- /* printk(KERN_INFO "als4000: irq 0x%04x 0x%04x\n",
- pci_irqstatus, sb_irqstatus); */
-
- /* only ack the things we actually handled above */
- return IRQ_RETVAL(
- (pci_irqstatus & (ALS4K_IOB_0E_SB_DMA_IRQ|ALS4K_IOB_0E_CR1E_IRQ|
- ALS4K_IOB_0E_MPU_IRQ))
- || (sb_irqstatus & (SB_IRQTYPE_8BIT|SB_IRQTYPE_16BIT|
- SB_IRQTYPE_MPUIN|ALS4K_IRQTYPE_CR1E_DMA))
- );
-}
-
-/*****************************************************************/
-
-static struct snd_pcm_hardware snd_als4000_playback =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE, /* formats */
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 65536,
- .period_bytes_min = 64,
- .period_bytes_max = 65536,
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0
-};
-
-static struct snd_pcm_hardware snd_als4000_capture =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE, /* formats */
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 65536,
- .period_bytes_min = 64,
- .period_bytes_max = 65536,
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0
-};
-
-/*****************************************************************/
-
-static int snd_als4000_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- chip->playback_substream = substream;
- runtime->hw = snd_als4000_playback;
- return 0;
-}
-
-static int snd_als4000_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
-
- chip->playback_substream = NULL;
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-static int snd_als4000_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- chip->capture_substream = substream;
- runtime->hw = snd_als4000_capture;
- return 0;
-}
-
-static int snd_als4000_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_sb *chip = snd_pcm_substream_chip(substream);
-
- chip->capture_substream = NULL;
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-/******************************************************************/
-
-static struct snd_pcm_ops snd_als4000_playback_ops = {
- .open = snd_als4000_playback_open,
- .close = snd_als4000_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_als4000_hw_params,
- .hw_free = snd_als4000_hw_free,
- .prepare = snd_als4000_playback_prepare,
- .trigger = snd_als4000_playback_trigger,
- .pointer = snd_als4000_playback_pointer
-};
-
-static struct snd_pcm_ops snd_als4000_capture_ops = {
- .open = snd_als4000_capture_open,
- .close = snd_als4000_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_als4000_hw_params,
- .hw_free = snd_als4000_hw_free,
- .prepare = snd_als4000_capture_prepare,
- .trigger = snd_als4000_capture_trigger,
- .pointer = snd_als4000_capture_pointer
-};
-
-static int __devinit snd_als4000_pcm(struct snd_sb *chip, int device)
-{
- struct snd_pcm *pcm;
- int err;
-
- err = snd_pcm_new(chip->card, "ALS4000 DSP", device, 1, 1, &pcm);
- if (err < 0)
- return err;
- pcm->private_data = chip;
- pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_als4000_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_als4000_capture_ops);
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
- 64*1024, 64*1024);
-
- chip->pcm = pcm;
-
- return 0;
-}
-
-/******************************************************************/
-
-static void snd_als4000_set_addr(unsigned long iobase,
- unsigned int sb_io,
- unsigned int mpu_io,
- unsigned int opl_io,
- unsigned int game_io)
-{
- u32 cfg1 = 0;
- u32 cfg2 = 0;
-
- if (mpu_io > 0)
- cfg2 |= (mpu_io | 1) << 16;
- if (sb_io > 0)
- cfg2 |= (sb_io | 1);
- if (game_io > 0)
- cfg1 |= (game_io | 1) << 16;
- if (opl_io > 0)
- cfg1 |= (opl_io | 1);
- snd_als4k_gcr_write_addr(iobase, ALS4K_GCRA8_LEGACY_CFG1, cfg1);
- snd_als4k_gcr_write_addr(iobase, ALS4K_GCRA9_LEGACY_CFG2, cfg2);
-}
-
-static void snd_als4000_configure(struct snd_sb *chip)
-{
- u8 tmp;
- int i;
-
- /* do some more configuration */
- spin_lock_irq(&chip->mixer_lock);
- tmp = snd_als4_cr_read(chip, ALS4K_CR0_SB_CONFIG);
- snd_als4_cr_write(chip, ALS4K_CR0_SB_CONFIG,
- tmp|ALS4K_CR0_MX80_81_REG_WRITE_ENABLE);
- /* always select DMA channel 0, since we do not actually use DMA
- * SPECS_PAGE: 19/20 */
- snd_sbmixer_write(chip, SB_DSP4_DMASETUP, SB_DMASETUP_DMA0);
- snd_als4_cr_write(chip, ALS4K_CR0_SB_CONFIG,
- tmp & ~ALS4K_CR0_MX80_81_REG_WRITE_ENABLE);
- spin_unlock_irq(&chip->mixer_lock);
-
- spin_lock_irq(&chip->reg_lock);
- /* enable interrupts */
- snd_als4k_gcr_write(chip, ALS4K_GCR8C_MISC_CTRL,
- ALS4K_GCR8C_IRQ_MASK_CTRL_ENABLE);
-
- /* SPECS_PAGE: 39 */
- for (i = ALS4K_GCR91_DMA0_ADDR; i <= ALS4K_GCR96_DMA3_MODE_COUNT; ++i)
- snd_als4k_gcr_write(chip, i, 0);
- /* enable burst mode to prevent dropouts during high PCI bus usage */
- snd_als4k_gcr_write(chip, ALS4K_GCR99_DMA_EMULATION_CTRL,
- (snd_als4k_gcr_read(chip, ALS4K_GCR99_DMA_EMULATION_CTRL) & ~0x07) | 0x04);
- spin_unlock_irq(&chip->reg_lock);
-}
-
-#ifdef SUPPORT_JOYSTICK
-static int __devinit snd_als4000_create_gameport(struct snd_card_als4000 *acard, int dev)
-{
- struct gameport *gp;
- struct resource *r;
- int io_port;
-
- if (joystick_port[dev] == 0)
- return -ENODEV;
-
- if (joystick_port[dev] == 1) { /* auto-detect */
- for (io_port = 0x200; io_port <= 0x218; io_port += 8) {
- r = request_region(io_port, 8, "ALS4000 gameport");
- if (r)
- break;
- }
- } else {
- io_port = joystick_port[dev];
- r = request_region(io_port, 8, "ALS4000 gameport");
- }
-
- if (!r) {
- printk(KERN_WARNING "als4000: cannot reserve joystick ports\n");
- return -EBUSY;
- }
-
- acard->gameport = gp = gameport_allocate_port();
- if (!gp) {
- printk(KERN_ERR "als4000: cannot allocate memory for gameport\n");
- release_and_free_resource(r);
- return -ENOMEM;
- }
-
- gameport_set_name(gp, "ALS4000 Gameport");
- gameport_set_phys(gp, "pci%s/gameport0", pci_name(acard->pci));
- gameport_set_dev_parent(gp, &acard->pci->dev);
- gp->io = io_port;
- gameport_set_port_data(gp, r);
-
- /* Enable legacy joystick port */
- snd_als4000_set_addr(acard->iobase, 0, 0, 0, 1);
-
- gameport_register_port(acard->gameport);
-
- return 0;
-}
-
-static void snd_als4000_free_gameport(struct snd_card_als4000 *acard)
-{
- if (acard->gameport) {
- struct resource *r = gameport_get_port_data(acard->gameport);
-
- gameport_unregister_port(acard->gameport);
- acard->gameport = NULL;
-
- /* disable joystick */
- snd_als4000_set_addr(acard->iobase, 0, 0, 0, 0);
-
- release_and_free_resource(r);
- }
-}
-#else
-static inline int snd_als4000_create_gameport(struct snd_card_als4000 *acard, int dev) { return -ENOSYS; }
-static inline void snd_als4000_free_gameport(struct snd_card_als4000 *acard) { }
-#endif
-
-static void snd_card_als4000_free( struct snd_card *card )
-{
- struct snd_card_als4000 *acard = card->private_data;
-
- /* make sure that interrupts are disabled */
- snd_als4k_gcr_write_addr(acard->iobase, ALS4K_GCR8C_MISC_CTRL, 0);
- /* free resources */
- snd_als4000_free_gameport(acard);
- pci_release_regions(acard->pci);
- pci_disable_device(acard->pci);
-}
-
-static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct snd_card_als4000 *acard;
- unsigned long iobase;
- struct snd_sb *chip;
- struct snd_opl3 *opl3;
- unsigned short word;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- /* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0) {
- return err;
- }
- /* check, if we can restrict PCI DMA transfers to 24 bits */
- if (pci_set_dma_mask(pci, DMA_BIT_MASK(24)) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(24)) < 0) {
- snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
- pci_disable_device(pci);
- return -ENXIO;
- }
-
- if ((err = pci_request_regions(pci, "ALS4000")) < 0) {
- pci_disable_device(pci);
- return err;
- }
- iobase = pci_resource_start(pci, 0);
-
- pci_read_config_word(pci, PCI_COMMAND, &word);
- pci_write_config_word(pci, PCI_COMMAND, word | PCI_COMMAND_IO);
- pci_set_master(pci);
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(*acard) /* private_data: acard */,
- &card);
- if (err < 0) {
- pci_release_regions(pci);
- pci_disable_device(pci);
- return err;
- }
-
- acard = card->private_data;
- acard->pci = pci;
- acard->iobase = iobase;
- card->private_free = snd_card_als4000_free;
-
- /* disable all legacy ISA stuff */
- snd_als4000_set_addr(acard->iobase, 0, 0, 0, 0);
-
- if ((err = snd_sbdsp_create(card,
- iobase + ALS4K_IOB_10_ADLIB_ADDR0,
- pci->irq,
- /* internally registered as IRQF_SHARED in case of ALS4000 SB */
- snd_als4000_interrupt,
- -1,
- -1,
- SB_HW_ALS4000,
- &chip)) < 0) {
- goto out_err;
- }
- acard->chip = chip;
-
- chip->pci = pci;
- chip->alt_port = iobase;
- snd_card_set_dev(card, &pci->dev);
-
- snd_als4000_configure(chip);
-
- strcpy(card->driver, "ALS4000");
- strcpy(card->shortname, "Avance Logic ALS4000");
- sprintf(card->longname, "%s at 0x%lx, irq %i",
- card->shortname, chip->alt_port, chip->irq);
-
- if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000,
- iobase + ALS4K_IOB_30_MIDI_DATA,
- MPU401_INFO_INTEGRATED |
- MPU401_INFO_IRQ_HOOK,
- -1, &chip->rmidi)) < 0) {
- printk(KERN_ERR "als4000: no MPU-401 device at 0x%lx?\n",
- iobase + ALS4K_IOB_30_MIDI_DATA);
- goto out_err;
- }
- /* FIXME: ALS4000 has interesting MPU401 configuration features
- * at ALS4K_CR1A_MPU401_UART_MODE_CONTROL
- * (pass-thru / UART switching, fast MIDI clock, etc.),
- * however there doesn't seem to be an ALSA API for this...
- * SPECS_PAGE: 21 */
-
- if ((err = snd_als4000_pcm(chip, 0)) < 0) {
- goto out_err;
- }
- if ((err = snd_sbmixer_new(chip)) < 0) {
- goto out_err;
- }
-
- if (snd_opl3_create(card,
- iobase + ALS4K_IOB_10_ADLIB_ADDR0,
- iobase + ALS4K_IOB_12_ADLIB_ADDR2,
- OPL3_HW_AUTO, 1, &opl3) < 0) {
- printk(KERN_ERR "als4000: no OPL device at 0x%lx-0x%lx?\n",
- iobase + ALS4K_IOB_10_ADLIB_ADDR0,
- iobase + ALS4K_IOB_12_ADLIB_ADDR2);
- } else {
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
- goto out_err;
- }
- }
-
- snd_als4000_create_gameport(acard, dev);
-
- if ((err = snd_card_register(card)) < 0) {
- goto out_err;
- }
- pci_set_drvdata(pci, card);
- dev++;
- err = 0;
- goto out;
-
-out_err:
- snd_card_free(card);
-
-out:
- return err;
-}
-
-static void __devexit snd_card_als4000_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-#ifdef CONFIG_PM
-static int snd_als4000_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_card_als4000 *acard = card->private_data;
- struct snd_sb *chip = acard->chip;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-
- snd_pcm_suspend_all(chip->pcm);
- snd_sbmixer_suspend(chip);
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int snd_als4000_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_card_als4000 *acard = card->private_data;
- struct snd_sb *chip = acard->chip;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "als4000: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
-
- snd_als4000_configure(chip);
- snd_sbdsp_reset(chip);
- snd_sbmixer_resume(chip);
-
-#ifdef SUPPORT_JOYSTICK
- if (acard->gameport)
- snd_als4000_set_addr(acard->iobase, 0, 0, 0, 1);
-#endif
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif /* CONFIG_PM */
-
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_als4000_ids,
- .probe = snd_card_als4000_probe,
- .remove = __devexit_p(snd_card_als4000_remove),
-#ifdef CONFIG_PM
- .suspend = snd_als4000_suspend,
- .resume = snd_als4000_resume,
-#endif
-};
-
-static int __init alsa_card_als4000_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_als4000_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_als4000_init)
-module_exit(alsa_card_als4000_exit)
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/Makefile b/ANDROID_3.4.5/sound/pci/asihpi/Makefile
deleted file mode 100644
index 391830a4..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-snd-asihpi-objs := asihpi.o hpioctl.o hpimsginit.o\
- hpicmn.o hpifunc.o hpidebug.o hpidspcd.o\
- hpios.o hpi6000.o hpi6205.o hpimsgx.o
-
-obj-$(CONFIG_SND_ASIHPI) += snd-asihpi.o
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/asihpi.c b/ANDROID_3.4.5/sound/pci/asihpi/asihpi.c
deleted file mode 100644
index e8de831f..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/asihpi.c
+++ /dev/null
@@ -1,2992 +0,0 @@
-/*
- * Asihpi soundcard
- * Copyright (c) by AudioScience Inc <alsa@audioscience.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
- * The following is not a condition of use, merely a request:
- * If you modify this program, particularly if you fix errors, AudioScience Inc
- * would appreciate it if you grant us the right to use those modifications
- * for any purpose including commercial applications.
- */
-
-#include "hpi_internal.h"
-#include "hpi_version.h"
-#include "hpimsginit.h"
-#include "hpioctl.h"
-#include "hpicmn.h"
-
-
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/jiffies.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/info.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <sound/hwdep.h>
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
-MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx "
- HPI_VER_STRING);
-
-#if defined CONFIG_SND_DEBUG_VERBOSE
-/**
- * snd_printddd - very verbose debug printk
- * @format: format string
- *
- * Works like snd_printk() for debugging purposes.
- * Ignored when CONFIG_SND_DEBUG_VERBOSE is not set.
- * Must set snd module debug parameter to 3 to enable at runtime.
- */
-#define snd_printddd(format, args...) \
- __snd_printk(3, __FILE__, __LINE__, format, ##args)
-#else
-#define snd_printddd(format, args...) do { } while (0)
-#endif
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static bool enable_hpi_hwdep = 1;
-
-module_param_array(index, int, NULL, S_IRUGO);
-MODULE_PARM_DESC(index, "ALSA index value for AudioScience soundcard.");
-
-module_param_array(id, charp, NULL, S_IRUGO);
-MODULE_PARM_DESC(id, "ALSA ID string for AudioScience soundcard.");
-
-module_param_array(enable, bool, NULL, S_IRUGO);
-MODULE_PARM_DESC(enable, "ALSA enable AudioScience soundcard.");
-
-module_param(enable_hpi_hwdep, bool, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(enable_hpi_hwdep,
- "ALSA enable HPI hwdep for AudioScience soundcard ");
-
-/* identify driver */
-#ifdef KERNEL_ALSA_BUILD
-static char *build_info = "Built using headers from kernel source";
-module_param(build_info, charp, S_IRUGO);
-MODULE_PARM_DESC(build_info, "built using headers from kernel source");
-#else
-static char *build_info = "Built within ALSA source";
-module_param(build_info, charp, S_IRUGO);
-MODULE_PARM_DESC(build_info, "built within ALSA source");
-#endif
-
-/* set to 1 to dump every control from adapter to log */
-static const int mixer_dump;
-
-#define DEFAULT_SAMPLERATE 44100
-static int adapter_fs = DEFAULT_SAMPLERATE;
-
-/* defaults */
-#define PERIODS_MIN 2
-#define PERIOD_BYTES_MIN 2048
-#define BUFFER_BYTES_MAX (512 * 1024)
-
-#define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7)
-
-struct clk_source {
- int source;
- int index;
- char *name;
-};
-
-struct clk_cache {
- int count;
- int has_local;
- struct clk_source s[MAX_CLOCKSOURCES];
-};
-
-/* Per card data */
-struct snd_card_asihpi {
- struct snd_card *card;
- struct pci_dev *pci;
- struct hpi_adapter *hpi;
-
- u32 h_mixer;
- struct clk_cache cc;
-
- u16 can_dma;
- u16 support_grouping;
- u16 support_mrx;
- u16 update_interval_frames;
- u16 in_max_chans;
- u16 out_max_chans;
- u16 in_min_chans;
- u16 out_min_chans;
-};
-
-/* Per stream data */
-struct snd_card_asihpi_pcm {
- struct timer_list timer;
- unsigned int respawn_timer;
- unsigned int hpi_buffer_attached;
- unsigned int buffer_bytes;
- unsigned int period_bytes;
- unsigned int bytes_per_sec;
- unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */
- unsigned int pcm_buf_dma_ofs; /* DMA R/W offset in buffer */
- unsigned int pcm_buf_elapsed_dma_ofs; /* DMA R/W offset in buffer */
- unsigned int drained_count;
- struct snd_pcm_substream *substream;
- u32 h_stream;
- struct hpi_format format;
-};
-
-/* universal stream verbs work with out or in stream handles */
-
-/* Functions to allow driver to give a buffer to HPI for busmastering */
-
-static u16 hpi_stream_host_buffer_attach(
- u32 h_stream, /* handle to outstream. */
- u32 size_in_bytes, /* size in bytes of bus mastering buffer */
- u32 pci_address
-)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- unsigned int obj = hpi_handle_object(h_stream);
-
- if (!h_stream)
- return HPI_ERROR_INVALID_OBJ;
- hpi_init_message_response(&hm, &hr, obj,
- obj == HPI_OBJ_OSTREAM ?
- HPI_OSTREAM_HOSTBUFFER_ALLOC :
- HPI_ISTREAM_HOSTBUFFER_ALLOC);
-
- hpi_handle_to_indexes(h_stream, &hm.adapter_index,
- &hm.obj_index);
-
- hm.u.d.u.buffer.buffer_size = size_in_bytes;
- hm.u.d.u.buffer.pci_address = pci_address;
- hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER;
- hpi_send_recv(&hm, &hr);
- return hr.error;
-}
-
-static u16 hpi_stream_host_buffer_detach(u32 h_stream)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- unsigned int obj = hpi_handle_object(h_stream);
-
- if (!h_stream)
- return HPI_ERROR_INVALID_OBJ;
-
- hpi_init_message_response(&hm, &hr, obj,
- obj == HPI_OBJ_OSTREAM ?
- HPI_OSTREAM_HOSTBUFFER_FREE :
- HPI_ISTREAM_HOSTBUFFER_FREE);
-
- hpi_handle_to_indexes(h_stream, &hm.adapter_index,
- &hm.obj_index);
- hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER;
- hpi_send_recv(&hm, &hr);
- return hr.error;
-}
-
-static inline u16 hpi_stream_start(u32 h_stream)
-{
- if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
- return hpi_outstream_start(h_stream);
- else
- return hpi_instream_start(h_stream);
-}
-
-static inline u16 hpi_stream_stop(u32 h_stream)
-{
- if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
- return hpi_outstream_stop(h_stream);
- else
- return hpi_instream_stop(h_stream);
-}
-
-static inline u16 hpi_stream_get_info_ex(
- u32 h_stream,
- u16 *pw_state,
- u32 *pbuffer_size,
- u32 *pdata_in_buffer,
- u32 *psample_count,
- u32 *pauxiliary_data
-)
-{
- u16 e;
- if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
- e = hpi_outstream_get_info_ex(h_stream, pw_state,
- pbuffer_size, pdata_in_buffer,
- psample_count, pauxiliary_data);
- else
- e = hpi_instream_get_info_ex(h_stream, pw_state,
- pbuffer_size, pdata_in_buffer,
- psample_count, pauxiliary_data);
- return e;
-}
-
-static inline u16 hpi_stream_group_add(
- u32 h_master,
- u32 h_stream)
-{
- if (hpi_handle_object(h_master) == HPI_OBJ_OSTREAM)
- return hpi_outstream_group_add(h_master, h_stream);
- else
- return hpi_instream_group_add(h_master, h_stream);
-}
-
-static inline u16 hpi_stream_group_reset(u32 h_stream)
-{
- if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
- return hpi_outstream_group_reset(h_stream);
- else
- return hpi_instream_group_reset(h_stream);
-}
-
-static inline u16 hpi_stream_group_get_map(
- u32 h_stream, u32 *mo, u32 *mi)
-{
- if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
- return hpi_outstream_group_get_map(h_stream, mo, mi);
- else
- return hpi_instream_group_get_map(h_stream, mo, mi);
-}
-
-static u16 handle_error(u16 err, int line, char *filename)
-{
- if (err)
- printk(KERN_WARNING
- "in file %s, line %d: HPI error %d\n",
- filename, line, err);
- return err;
-}
-
-#define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__)
-
-/***************************** GENERAL PCM ****************/
-
-static void print_hwparams(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *p)
-{
- char name[16];
- snd_pcm_debug_name(substream, name, sizeof(name));
- snd_printd("%s HWPARAMS\n", name);
- snd_printd(" samplerate %d Hz\n", params_rate(p));
- snd_printd(" channels %d\n", params_channels(p));
- snd_printd(" format %d\n", params_format(p));
- snd_printd(" subformat %d\n", params_subformat(p));
- snd_printd(" buffer %d B\n", params_buffer_bytes(p));
- snd_printd(" period %d B\n", params_period_bytes(p));
- snd_printd(" access %d\n", params_access(p));
- snd_printd(" period_size %d\n", params_period_size(p));
- snd_printd(" periods %d\n", params_periods(p));
- snd_printd(" buffer_size %d\n", params_buffer_size(p));
- snd_printd(" %d B/s\n", params_rate(p) *
- params_channels(p) *
- snd_pcm_format_width(params_format(p)) / 8);
-
-}
-
-static snd_pcm_format_t hpi_to_alsa_formats[] = {
- -1, /* INVALID */
- SNDRV_PCM_FORMAT_U8, /* HPI_FORMAT_PCM8_UNSIGNED 1 */
- SNDRV_PCM_FORMAT_S16, /* HPI_FORMAT_PCM16_SIGNED 2 */
- -1, /* HPI_FORMAT_MPEG_L1 3 */
- SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L2 4 */
- SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L3 5 */
- -1, /* HPI_FORMAT_DOLBY_AC2 6 */
- -1, /* HPI_FORMAT_DOLBY_AC3 7 */
- SNDRV_PCM_FORMAT_S16_BE,/* HPI_FORMAT_PCM16_BIGENDIAN 8 */
- -1, /* HPI_FORMAT_AA_TAGIT1_HITS 9 */
- -1, /* HPI_FORMAT_AA_TAGIT1_INSERTS 10 */
- SNDRV_PCM_FORMAT_S32, /* HPI_FORMAT_PCM32_SIGNED 11 */
- -1, /* HPI_FORMAT_RAW_BITSTREAM 12 */
- -1, /* HPI_FORMAT_AA_TAGIT1_HITS_EX1 13 */
- SNDRV_PCM_FORMAT_FLOAT, /* HPI_FORMAT_PCM32_FLOAT 14 */
-#if 1
- /* ALSA can't handle 3 byte sample size together with power-of-2
- * constraint on buffer_bytes, so disable this format
- */
- -1
-#else
- /* SNDRV_PCM_FORMAT_S24_3LE */ /* HPI_FORMAT_PCM24_SIGNED 15 */
-#endif
-};
-
-
-static int snd_card_asihpi_format_alsa2hpi(snd_pcm_format_t alsa_format,
- u16 *hpi_format)
-{
- u16 format;
-
- for (format = HPI_FORMAT_PCM8_UNSIGNED;
- format <= HPI_FORMAT_PCM24_SIGNED; format++) {
- if (hpi_to_alsa_formats[format] == alsa_format) {
- *hpi_format = format;
- return 0;
- }
- }
-
- snd_printd(KERN_WARNING "failed match for alsa format %d\n",
- alsa_format);
- *hpi_format = 0;
- return -EINVAL;
-}
-
-static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi,
- struct snd_pcm_hardware *pcmhw)
-{
- u16 err;
- u32 h_control;
- u32 sample_rate;
- int idx;
- unsigned int rate_min = 200000;
- unsigned int rate_max = 0;
- unsigned int rates = 0;
-
- if (asihpi->support_mrx) {
- rates |= SNDRV_PCM_RATE_CONTINUOUS;
- rates |= SNDRV_PCM_RATE_8000_96000;
- rate_min = 8000;
- rate_max = 100000;
- } else {
- /* on cards without SRC,
- valid rates are determined by sampleclock */
- err = hpi_mixer_get_control(asihpi->h_mixer,
- HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
- HPI_CONTROL_SAMPLECLOCK, &h_control);
- if (err) {
- snd_printk(KERN_ERR
- "No local sampleclock, err %d\n", err);
- }
-
- for (idx = -1; idx < 100; idx++) {
- if (idx == -1) {
- if (hpi_sample_clock_get_sample_rate(h_control,
- &sample_rate))
- continue;
- } else if (hpi_sample_clock_query_local_rate(h_control,
- idx, &sample_rate)) {
- break;
- }
-
- rate_min = min(rate_min, sample_rate);
- rate_max = max(rate_max, sample_rate);
-
- switch (sample_rate) {
- case 5512:
- rates |= SNDRV_PCM_RATE_5512;
- break;
- case 8000:
- rates |= SNDRV_PCM_RATE_8000;
- break;
- case 11025:
- rates |= SNDRV_PCM_RATE_11025;
- break;
- case 16000:
- rates |= SNDRV_PCM_RATE_16000;
- break;
- case 22050:
- rates |= SNDRV_PCM_RATE_22050;
- break;
- case 32000:
- rates |= SNDRV_PCM_RATE_32000;
- break;
- case 44100:
- rates |= SNDRV_PCM_RATE_44100;
- break;
- case 48000:
- rates |= SNDRV_PCM_RATE_48000;
- break;
- case 64000:
- rates |= SNDRV_PCM_RATE_64000;
- break;
- case 88200:
- rates |= SNDRV_PCM_RATE_88200;
- break;
- case 96000:
- rates |= SNDRV_PCM_RATE_96000;
- break;
- case 176400:
- rates |= SNDRV_PCM_RATE_176400;
- break;
- case 192000:
- rates |= SNDRV_PCM_RATE_192000;
- break;
- default: /* some other rate */
- rates |= SNDRV_PCM_RATE_KNOT;
- }
- }
- }
-
- pcmhw->rates = rates;
- pcmhw->rate_min = rate_min;
- pcmhw->rate_max = rate_max;
-}
-
-static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
- struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
- int err;
- u16 format;
- int width;
- unsigned int bytes_per_sec;
-
- print_hwparams(substream, params);
- err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
- if (err < 0)
- return err;
- err = snd_card_asihpi_format_alsa2hpi(params_format(params), &format);
- if (err)
- return err;
-
- hpi_handle_error(hpi_format_create(&dpcm->format,
- params_channels(params),
- format, params_rate(params), 0, 0));
-
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- if (hpi_instream_reset(dpcm->h_stream) != 0)
- return -EINVAL;
-
- if (hpi_instream_set_format(
- dpcm->h_stream, &dpcm->format) != 0)
- return -EINVAL;
- }
-
- dpcm->hpi_buffer_attached = 0;
- if (card->can_dma) {
- err = hpi_stream_host_buffer_attach(dpcm->h_stream,
- params_buffer_bytes(params), runtime->dma_addr);
- if (err == 0) {
- snd_printdd(
- "stream_host_buffer_attach succeeded %u %lu\n",
- params_buffer_bytes(params),
- (unsigned long)runtime->dma_addr);
- } else {
- snd_printd("stream_host_buffer_attach error %d\n",
- err);
- return -ENOMEM;
- }
-
- err = hpi_stream_get_info_ex(dpcm->h_stream, NULL,
- &dpcm->hpi_buffer_attached,
- NULL, NULL, NULL);
-
- snd_printdd("stream_host_buffer_attach status 0x%x\n",
- dpcm->hpi_buffer_attached);
-
- }
- bytes_per_sec = params_rate(params) * params_channels(params);
- width = snd_pcm_format_width(params_format(params));
- bytes_per_sec *= width;
- bytes_per_sec /= 8;
- if (width < 0 || bytes_per_sec == 0)
- return -EINVAL;
-
- dpcm->bytes_per_sec = bytes_per_sec;
- dpcm->buffer_bytes = params_buffer_bytes(params);
- dpcm->period_bytes = params_period_bytes(params);
-
- return 0;
-}
-
-static int
-snd_card_asihpi_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
- if (dpcm->hpi_buffer_attached)
- hpi_stream_host_buffer_detach(dpcm->h_stream);
-
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime)
-{
- struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
- kfree(dpcm);
-}
-
-static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream *
- substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
- int expiry;
-
- expiry = HZ / 200;
- /*? (dpcm->period_bytes * HZ / dpcm->bytes_per_sec); */
- expiry = max(expiry, 1); /* don't let it be zero! */
- dpcm->timer.expires = jiffies + expiry;
- dpcm->respawn_timer = 1;
- add_timer(&dpcm->timer);
-}
-
-static void snd_card_asihpi_pcm_timer_stop(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
-
- dpcm->respawn_timer = 0;
- del_timer(&dpcm->timer);
-}
-
-static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
- struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
- struct snd_pcm_substream *s;
- u16 e;
- char name[16];
-
- snd_pcm_debug_name(substream, name, sizeof(name));
- snd_printdd("%s trigger\n", name);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- snd_pcm_group_for_each_entry(s, substream) {
- struct snd_pcm_runtime *runtime = s->runtime;
- struct snd_card_asihpi_pcm *ds = runtime->private_data;
-
- if (snd_pcm_substream_chip(s) != card)
- continue;
-
- /* don't link Cap and Play */
- if (substream->stream != s->stream)
- continue;
-
- ds->drained_count = 0;
- if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- /* How do I know how much valid data is present
- * in buffer? Must be at least one period!
- * Guessing 2 periods, but if
- * buffer is bigger it may contain even more
- * data??
- */
- unsigned int preload = ds->period_bytes * 1;
- snd_printddd("%d preload x%x\n", s->number, preload);
- hpi_handle_error(hpi_outstream_write_buf(
- ds->h_stream,
- &runtime->dma_area[0],
- preload,
- &ds->format));
- ds->pcm_buf_host_rw_ofs = preload;
- }
-
- if (card->support_grouping) {
- snd_printdd("%d group\n", s->number);
- e = hpi_stream_group_add(
- dpcm->h_stream,
- ds->h_stream);
- if (!e) {
- snd_pcm_trigger_done(s, substream);
- } else {
- hpi_handle_error(e);
- break;
- }
- } else
- break;
- }
- snd_printdd("start\n");
- /* start the master stream */
- snd_card_asihpi_pcm_timer_start(substream);
- if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) ||
- !card->can_dma)
- hpi_handle_error(hpi_stream_start(dpcm->h_stream));
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- snd_card_asihpi_pcm_timer_stop(substream);
- snd_pcm_group_for_each_entry(s, substream) {
- if (snd_pcm_substream_chip(s) != card)
- continue;
- /* don't link Cap and Play */
- if (substream->stream != s->stream)
- continue;
-
- /*? workaround linked streams don't
- transition to SETUP 20070706*/
- s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
-
- if (card->support_grouping) {
- snd_printdd("%d group\n", s->number);
- snd_pcm_trigger_done(s, substream);
- } else
- break;
- }
- snd_printdd("stop\n");
-
- /* _prepare and _hwparams reset the stream */
- hpi_handle_error(hpi_stream_stop(dpcm->h_stream));
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- hpi_handle_error(
- hpi_outstream_reset(dpcm->h_stream));
-
- if (card->support_grouping)
- hpi_handle_error(hpi_stream_group_reset(dpcm->h_stream));
- break;
-
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- snd_printdd("pause release\n");
- hpi_handle_error(hpi_stream_start(dpcm->h_stream));
- snd_card_asihpi_pcm_timer_start(substream);
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- snd_printdd("pause\n");
- snd_card_asihpi_pcm_timer_stop(substream);
- hpi_handle_error(hpi_stream_stop(dpcm->h_stream));
- break;
- default:
- snd_printd(KERN_ERR "\tINVALID\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*algorithm outline
- Without linking degenerates to getting single stream pos etc
- Without mmap 2nd loop degenerates to snd_pcm_period_elapsed
-*/
-/*
-pcm_buf_dma_ofs=get_buf_pos(s);
-for_each_linked_stream(s) {
- pcm_buf_dma_ofs=get_buf_pos(s);
- min_buf_pos = modulo_min(min_buf_pos, pcm_buf_dma_ofs, buffer_bytes)
- new_data = min(new_data, calc_new_data(pcm_buf_dma_ofs,irq_pos)
-}
-timer.expires = jiffies + predict_next_period_ready(min_buf_pos);
-for_each_linked_stream(s) {
- s->pcm_buf_dma_ofs = min_buf_pos;
- if (new_data > period_bytes) {
- if (mmap) {
- irq_pos = (irq_pos + period_bytes) % buffer_bytes;
- if (playback) {
- write(period_bytes);
- } else {
- read(period_bytes);
- }
- }
- snd_pcm_period_elapsed(s);
- }
-}
-*/
-
-/** Minimum of 2 modulo values. Works correctly when the difference between
-* the values is less than half the modulus
-*/
-static inline unsigned int modulo_min(unsigned int a, unsigned int b,
- unsigned long int modulus)
-{
- unsigned int result;
- if (((a-b) % modulus) < (modulus/2))
- result = b;
- else
- result = a;
-
- return result;
-}
-
-/** Timer function, equivalent to interrupt service routine for cards
-*/
-static void snd_card_asihpi_timer_function(unsigned long data)
-{
- struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data;
- struct snd_pcm_substream *substream = dpcm->substream;
- struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime;
- struct snd_pcm_substream *s;
- unsigned int newdata = 0;
- unsigned int pcm_buf_dma_ofs, min_buf_pos = 0;
- unsigned int remdata, xfercount, next_jiffies;
- int first = 1;
- int loops = 0;
- u16 state;
- u32 buffer_size, bytes_avail, samples_played, on_card_bytes;
- char name[16];
-
- snd_pcm_debug_name(substream, name, sizeof(name));
-
- snd_printdd("%s snd_card_asihpi_timer_function\n", name);
-
- /* find minimum newdata and buffer pos in group */
- snd_pcm_group_for_each_entry(s, substream) {
- struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
- runtime = s->runtime;
-
- if (snd_pcm_substream_chip(s) != card)
- continue;
-
- /* don't link Cap and Play */
- if (substream->stream != s->stream)
- continue;
-
- hpi_handle_error(hpi_stream_get_info_ex(
- ds->h_stream, &state,
- &buffer_size, &bytes_avail,
- &samples_played, &on_card_bytes));
-
- /* number of bytes in on-card buffer */
- runtime->delay = on_card_bytes;
-
- if (!card->can_dma)
- on_card_bytes = bytes_avail;
-
- if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail;
- if (state == HPI_STATE_STOPPED) {
- if (bytes_avail == 0) {
- hpi_handle_error(hpi_stream_start(ds->h_stream));
- snd_printdd("P%d start\n", s->number);
- ds->drained_count = 0;
- }
- } else if (state == HPI_STATE_DRAINED) {
- snd_printd(KERN_WARNING "P%d drained\n",
- s->number);
- ds->drained_count++;
- if (ds->drained_count > 20) {
- snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
- continue;
- }
- } else {
- ds->drained_count = 0;
- }
- } else
- pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs;
-
- if (first) {
- /* can't statically init min when wrap is involved */
- min_buf_pos = pcm_buf_dma_ofs;
- newdata = (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->buffer_bytes;
- first = 0;
- } else {
- min_buf_pos =
- modulo_min(min_buf_pos, pcm_buf_dma_ofs, UINT_MAX+1L);
- newdata = min(
- (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->buffer_bytes,
- newdata);
- }
-
- snd_printdd("hw_ptr 0x%04lX, appl_ptr 0x%04lX\n",
- (unsigned long)frames_to_bytes(runtime,
- runtime->status->hw_ptr),
- (unsigned long)frames_to_bytes(runtime,
- runtime->control->appl_ptr));
-
- snd_printdd("%d S=%d, "
- "rw=0x%04X, dma=0x%04X, left=0x%04X, "
- "aux=0x%04X space=0x%04X\n",
- s->number, state,
- ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs,
- (int)bytes_avail,
- (int)on_card_bytes, buffer_size-bytes_avail);
- loops++;
- }
- pcm_buf_dma_ofs = min_buf_pos;
-
- remdata = newdata % dpcm->period_bytes;
- xfercount = newdata - remdata; /* a multiple of period_bytes */
- /* come back when on_card_bytes has decreased enough to allow
- write to happen, or when data has been consumed to make another
- period
- */
- if (xfercount && (on_card_bytes > dpcm->period_bytes))
- next_jiffies = ((on_card_bytes - dpcm->period_bytes) * HZ / dpcm->bytes_per_sec);
- else
- next_jiffies = ((dpcm->period_bytes - remdata) * HZ / dpcm->bytes_per_sec);
-
- next_jiffies = max(next_jiffies, 1U);
- dpcm->timer.expires = jiffies + next_jiffies;
- snd_printdd("jif %d buf pos 0x%04X newdata 0x%04X xfer 0x%04X\n",
- next_jiffies, pcm_buf_dma_ofs, newdata, xfercount);
-
- snd_pcm_group_for_each_entry(s, substream) {
- struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
-
- /* don't link Cap and Play */
- if (substream->stream != s->stream)
- continue;
-
- ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs;
-
- if (xfercount &&
- /* Limit use of on card fifo for playback */
- ((on_card_bytes <= ds->period_bytes) ||
- (s->stream == SNDRV_PCM_STREAM_CAPTURE)))
-
- {
-
- unsigned int buf_ofs = ds->pcm_buf_host_rw_ofs % ds->buffer_bytes;
- unsigned int xfer1, xfer2;
- char *pd = &s->runtime->dma_area[buf_ofs];
-
- if (card->can_dma) { /* buffer wrap is handled at lower level */
- xfer1 = xfercount;
- xfer2 = 0;
- } else {
- xfer1 = min(xfercount, ds->buffer_bytes - buf_ofs);
- xfer2 = xfercount - xfer1;
- }
-
- if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- snd_printddd("P%d write1 0x%04X 0x%04X\n",
- s->number, xfer1, buf_ofs);
- hpi_handle_error(
- hpi_outstream_write_buf(
- ds->h_stream, pd, xfer1,
- &ds->format));
-
- if (xfer2) {
- pd = s->runtime->dma_area;
-
- snd_printddd("P%d write2 0x%04X 0x%04X\n",
- s->number,
- xfercount - xfer1, buf_ofs);
- hpi_handle_error(
- hpi_outstream_write_buf(
- ds->h_stream, pd,
- xfercount - xfer1,
- &ds->format));
- }
- } else {
- snd_printddd("C%d read1 0x%04x\n",
- s->number, xfer1);
- hpi_handle_error(
- hpi_instream_read_buf(
- ds->h_stream,
- pd, xfer1));
- if (xfer2) {
- pd = s->runtime->dma_area;
- snd_printddd("C%d read2 0x%04x\n",
- s->number, xfer2);
- hpi_handle_error(
- hpi_instream_read_buf(
- ds->h_stream,
- pd, xfer2));
- }
- }
- ds->pcm_buf_host_rw_ofs += xfercount;
- ds->pcm_buf_elapsed_dma_ofs += xfercount;
- snd_pcm_period_elapsed(s);
- }
- }
-
- if (dpcm->respawn_timer)
- add_timer(&dpcm->timer);
-}
-
-/***************************** PLAYBACK OPS ****************/
-static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream,
- unsigned int cmd, void *arg)
-{
- char name[16];
- snd_pcm_debug_name(substream, name, sizeof(name));
- snd_printddd(KERN_INFO "%s ioctl %d\n", name, cmd);
- return snd_pcm_lib_ioctl(substream, cmd, arg);
-}
-
-static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
- substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
-
- snd_printdd("P%d prepare\n", substream->number);
-
- hpi_handle_error(hpi_outstream_reset(dpcm->h_stream));
- dpcm->pcm_buf_host_rw_ofs = 0;
- dpcm->pcm_buf_dma_ofs = 0;
- dpcm->pcm_buf_elapsed_dma_ofs = 0;
- return 0;
-}
-
-static snd_pcm_uframes_t
-snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
- snd_pcm_uframes_t ptr;
- char name[16];
- snd_pcm_debug_name(substream, name, sizeof(name));
-
- ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
- snd_printddd("%s pointer = 0x%04lx\n", name, (unsigned long)ptr);
- return ptr;
-}
-
-static u64 snd_card_asihpi_playback_formats(struct snd_card_asihpi *asihpi,
- u32 h_stream)
-{
- struct hpi_format hpi_format;
- u16 format;
- u16 err;
- u32 h_control;
- u32 sample_rate = 48000;
- u64 formats = 0;
-
- /* on cards without SRC, must query at valid rate,
- * maybe set by external sync
- */
- err = hpi_mixer_get_control(asihpi->h_mixer,
- HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
- HPI_CONTROL_SAMPLECLOCK, &h_control);
-
- if (!err)
- err = hpi_sample_clock_get_sample_rate(h_control,
- &sample_rate);
-
- for (format = HPI_FORMAT_PCM8_UNSIGNED;
- format <= HPI_FORMAT_PCM24_SIGNED; format++) {
- err = hpi_format_create(&hpi_format, asihpi->out_max_chans,
- format, sample_rate, 128000, 0);
- if (!err)
- err = hpi_outstream_query_format(h_stream, &hpi_format);
- if (!err && (hpi_to_alsa_formats[format] != -1))
- formats |= (1ULL << hpi_to_alsa_formats[format]);
- }
- return formats;
-}
-
-static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_card_asihpi_pcm *dpcm;
- struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
- struct snd_pcm_hardware snd_card_asihpi_playback;
- int err;
-
- dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
- if (dpcm == NULL)
- return -ENOMEM;
-
- err = hpi_outstream_open(card->hpi->adapter->index,
- substream->number, &dpcm->h_stream);
- hpi_handle_error(err);
- if (err)
- kfree(dpcm);
- if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
- return -EBUSY;
- if (err)
- return -EIO;
-
- /*? also check ASI5000 samplerate source
- If external, only support external rate.
- If internal and other stream playing, can't switch
- */
-
- init_timer(&dpcm->timer);
- dpcm->timer.data = (unsigned long) dpcm;
- dpcm->timer.function = snd_card_asihpi_timer_function;
- dpcm->substream = substream;
- runtime->private_data = dpcm;
- runtime->private_free = snd_card_asihpi_runtime_free;
-
- memset(&snd_card_asihpi_playback, 0, sizeof(snd_card_asihpi_playback));
- snd_card_asihpi_playback.buffer_bytes_max = BUFFER_BYTES_MAX;
- snd_card_asihpi_playback.period_bytes_min = PERIOD_BYTES_MIN;
- /*?snd_card_asihpi_playback.period_bytes_min =
- card->out_max_chans * 4096; */
- snd_card_asihpi_playback.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN;
- snd_card_asihpi_playback.periods_min = PERIODS_MIN;
- snd_card_asihpi_playback.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN;
- /* snd_card_asihpi_playback.fifo_size = 0; */
- snd_card_asihpi_playback.channels_max = card->out_max_chans;
- snd_card_asihpi_playback.channels_min = card->out_min_chans;
- snd_card_asihpi_playback.formats =
- snd_card_asihpi_playback_formats(card, dpcm->h_stream);
-
- snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_playback);
-
- snd_card_asihpi_playback.info = SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_DOUBLE |
- SNDRV_PCM_INFO_BATCH |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID;
-
- if (card->support_grouping) {
- snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START;
- snd_pcm_set_sync(substream);
- }
-
- /* struct is copied, so can create initializer dynamically */
- runtime->hw = snd_card_asihpi_playback;
-
- if (card->can_dma)
- err = snd_pcm_hw_constraint_pow2(runtime, 0,
- SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
- if (err < 0)
- return err;
-
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- card->update_interval_frames);
-
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- card->update_interval_frames * 2, UINT_MAX);
-
- snd_printdd("playback open\n");
-
- return 0;
-}
-
-static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
-
- hpi_handle_error(hpi_outstream_close(dpcm->h_stream));
- snd_printdd("playback close\n");
-
- return 0;
-}
-
-static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = {
- .open = snd_card_asihpi_playback_open,
- .close = snd_card_asihpi_playback_close,
- .ioctl = snd_card_asihpi_playback_ioctl,
- .hw_params = snd_card_asihpi_pcm_hw_params,
- .hw_free = snd_card_asihpi_hw_free,
- .prepare = snd_card_asihpi_playback_prepare,
- .trigger = snd_card_asihpi_trigger,
- .pointer = snd_card_asihpi_playback_pointer,
-};
-
-/***************************** CAPTURE OPS ****************/
-static snd_pcm_uframes_t
-snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
-
- snd_printddd("capture pointer %d=%d\n",
- substream->number, dpcm->pcm_buf_dma_ofs);
- /* NOTE Unlike playback can't use actual samples_played
- for the capture position, because those samples aren't yet in
- the local buffer available for reading.
- */
- return bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
-}
-
-static int snd_card_asihpi_capture_ioctl(struct snd_pcm_substream *substream,
- unsigned int cmd, void *arg)
-{
- return snd_pcm_lib_ioctl(substream, cmd, arg);
-}
-
-static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
-
- hpi_handle_error(hpi_instream_reset(dpcm->h_stream));
- dpcm->pcm_buf_host_rw_ofs = 0;
- dpcm->pcm_buf_dma_ofs = 0;
- dpcm->pcm_buf_elapsed_dma_ofs = 0;
-
- snd_printdd("Capture Prepare %d\n", substream->number);
- return 0;
-}
-
-
-
-static u64 snd_card_asihpi_capture_formats(struct snd_card_asihpi *asihpi,
- u32 h_stream)
-{
- struct hpi_format hpi_format;
- u16 format;
- u16 err;
- u32 h_control;
- u32 sample_rate = 48000;
- u64 formats = 0;
-
- /* on cards without SRC, must query at valid rate,
- maybe set by external sync */
- err = hpi_mixer_get_control(asihpi->h_mixer,
- HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
- HPI_CONTROL_SAMPLECLOCK, &h_control);
-
- if (!err)
- err = hpi_sample_clock_get_sample_rate(h_control,
- &sample_rate);
-
- for (format = HPI_FORMAT_PCM8_UNSIGNED;
- format <= HPI_FORMAT_PCM24_SIGNED; format++) {
-
- err = hpi_format_create(&hpi_format, asihpi->in_max_chans,
- format, sample_rate, 128000, 0);
- if (!err)
- err = hpi_instream_query_format(h_stream, &hpi_format);
- if (!err)
- formats |= (1ULL << hpi_to_alsa_formats[format]);
- }
- return formats;
-}
-
-static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
- struct snd_card_asihpi_pcm *dpcm;
- struct snd_pcm_hardware snd_card_asihpi_capture;
- int err;
-
- dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
- if (dpcm == NULL)
- return -ENOMEM;
-
- snd_printdd("capture open adapter %d stream %d\n",
- card->hpi->adapter->index, substream->number);
-
- err = hpi_handle_error(
- hpi_instream_open(card->hpi->adapter->index,
- substream->number, &dpcm->h_stream));
- if (err)
- kfree(dpcm);
- if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
- return -EBUSY;
- if (err)
- return -EIO;
-
- init_timer(&dpcm->timer);
- dpcm->timer.data = (unsigned long) dpcm;
- dpcm->timer.function = snd_card_asihpi_timer_function;
- dpcm->substream = substream;
- runtime->private_data = dpcm;
- runtime->private_free = snd_card_asihpi_runtime_free;
-
- memset(&snd_card_asihpi_capture, 0, sizeof(snd_card_asihpi_capture));
- snd_card_asihpi_capture.buffer_bytes_max = BUFFER_BYTES_MAX;
- snd_card_asihpi_capture.period_bytes_min = PERIOD_BYTES_MIN;
- snd_card_asihpi_capture.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN;
- snd_card_asihpi_capture.periods_min = PERIODS_MIN;
- snd_card_asihpi_capture.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN;
- /* snd_card_asihpi_capture.fifo_size = 0; */
- snd_card_asihpi_capture.channels_max = card->in_max_chans;
- snd_card_asihpi_capture.channels_min = card->in_min_chans;
- snd_card_asihpi_capture.formats =
- snd_card_asihpi_capture_formats(card, dpcm->h_stream);
- snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture);
- snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID;
-
- if (card->support_grouping)
- snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START;
-
- runtime->hw = snd_card_asihpi_capture;
-
- if (card->can_dma)
- err = snd_pcm_hw_constraint_pow2(runtime, 0,
- SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
- if (err < 0)
- return err;
-
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- card->update_interval_frames);
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- card->update_interval_frames * 2, UINT_MAX);
-
- snd_pcm_set_sync(substream);
-
- return 0;
-}
-
-static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
-
- hpi_handle_error(hpi_instream_close(dpcm->h_stream));
- return 0;
-}
-
-static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
- .open = snd_card_asihpi_capture_open,
- .close = snd_card_asihpi_capture_close,
- .ioctl = snd_card_asihpi_capture_ioctl,
- .hw_params = snd_card_asihpi_pcm_hw_params,
- .hw_free = snd_card_asihpi_hw_free,
- .prepare = snd_card_asihpi_capture_prepare,
- .trigger = snd_card_asihpi_trigger,
- .pointer = snd_card_asihpi_capture_pointer,
-};
-
-static int __devinit snd_card_asihpi_pcm_new(
- struct snd_card_asihpi *asihpi, int device)
-{
- struct snd_pcm *pcm;
- int err;
- u16 num_instreams, num_outstreams, x16;
- u32 x32;
-
- err = hpi_adapter_get_info(asihpi->hpi->adapter->index,
- &num_outstreams, &num_instreams,
- &x16, &x32, &x16);
-
- err = snd_pcm_new(asihpi->card, "Asihpi PCM", device,
- num_outstreams, num_instreams, &pcm);
- if (err < 0)
- return err;
- /* pointer to ops struct is stored, dont change ops afterwards! */
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_card_asihpi_playback_mmap_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_card_asihpi_capture_mmap_ops);
-
- pcm->private_data = asihpi;
- pcm->info_flags = 0;
- strcpy(pcm->name, "Asihpi PCM");
-
- /*? do we want to emulate MMAP for non-BBM cards?
- Jack doesn't work with ALSAs MMAP emulation - WHY NOT? */
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(asihpi->pci),
- 64*1024, BUFFER_BYTES_MAX);
-
- return 0;
-}
-
-/***************************** MIXER CONTROLS ****************/
-struct hpi_control {
- u32 h_control;
- u16 control_type;
- u16 src_node_type;
- u16 src_node_index;
- u16 dst_node_type;
- u16 dst_node_index;
- u16 band;
- char name[44]; /* copied to snd_ctl_elem_id.name[44]; */
-};
-
-static const char * const asihpi_tuner_band_names[] = {
- "invalid",
- "AM",
- "FM mono",
- "TV NTSC-M",
- "FM stereo",
- "AUX",
- "TV PAL BG",
- "TV PAL I",
- "TV PAL DK",
- "TV SECAM",
-};
-
-compile_time_assert(
- (ARRAY_SIZE(asihpi_tuner_band_names) ==
- (HPI_TUNER_BAND_LAST+1)),
- assert_tuner_band_names_size);
-
-static const char * const asihpi_src_names[] = {
- "no source",
- "PCM",
- "Line",
- "Digital",
- "Tuner",
- "RF",
- "Clock",
- "Bitstream",
- "Mic",
- "Net",
- "Analog",
- "Adapter",
- "RTP",
- "Internal"
-};
-
-compile_time_assert(
- (ARRAY_SIZE(asihpi_src_names) ==
- (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)),
- assert_src_names_size);
-
-static const char * const asihpi_dst_names[] = {
- "no destination",
- "PCM",
- "Line",
- "Digital",
- "RF",
- "Speaker",
- "Net",
- "Analog",
- "RTP",
-};
-
-compile_time_assert(
- (ARRAY_SIZE(asihpi_dst_names) ==
- (HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_NONE+1)),
- assert_dst_names_size);
-
-static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl,
- struct snd_card_asihpi *asihpi)
-{
- int err;
-
- err = snd_ctl_add(card, snd_ctl_new1(ctl, asihpi));
- if (err < 0)
- return err;
- else if (mixer_dump)
- snd_printk(KERN_INFO "added %s(%d)\n", ctl->name, ctl->index);
-
- return 0;
-}
-
-/* Convert HPI control name and location into ALSA control name */
-static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
- struct hpi_control *hpi_ctl,
- char *name)
-{
- char *dir;
- memset(snd_control, 0, sizeof(*snd_control));
- snd_control->name = hpi_ctl->name;
- snd_control->private_value = hpi_ctl->h_control;
- snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- snd_control->index = 0;
-
- if (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE == HPI_SOURCENODE_CLOCK_SOURCE)
- dir = ""; /* clock is neither capture nor playback */
- else if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM)
- dir = "Capture "; /* On or towards a PCM capture destination*/
- else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
- (!hpi_ctl->dst_node_type))
- dir = "Capture "; /* On a source node that is not PCM playback */
- else if (hpi_ctl->src_node_type &&
- (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
- (hpi_ctl->dst_node_type))
- dir = "Monitor Playback "; /* Between an input and an output */
- else
- dir = "Playback "; /* PCM Playback source, or output node */
-
- if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
- sprintf(hpi_ctl->name, "%s %d %s %d %s%s",
- asihpi_src_names[hpi_ctl->src_node_type],
- hpi_ctl->src_node_index,
- asihpi_dst_names[hpi_ctl->dst_node_type],
- hpi_ctl->dst_node_index,
- dir, name);
- else if (hpi_ctl->dst_node_type) {
- sprintf(hpi_ctl->name, "%s %d %s%s",
- asihpi_dst_names[hpi_ctl->dst_node_type],
- hpi_ctl->dst_node_index,
- dir, name);
- } else {
- sprintf(hpi_ctl->name, "%s %d %s%s",
- asihpi_src_names[hpi_ctl->src_node_type],
- hpi_ctl->src_node_index,
- dir, name);
- }
- /* printk(KERN_INFO "Adding %s %d to %d ", hpi_ctl->name,
- hpi_ctl->wSrcNodeType, hpi_ctl->wDstNodeType); */
-}
-
-/*------------------------------------------------------------
- Volume controls
- ------------------------------------------------------------*/
-#define VOL_STEP_mB 1
-static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- u32 h_control = kcontrol->private_value;
- u32 count;
- u16 err;
- /* native gains are in millibels */
- short min_gain_mB;
- short max_gain_mB;
- short step_gain_mB;
-
- err = hpi_volume_query_range(h_control,
- &min_gain_mB, &max_gain_mB, &step_gain_mB);
- if (err) {
- max_gain_mB = 0;
- min_gain_mB = -10000;
- step_gain_mB = VOL_STEP_mB;
- }
-
- err = hpi_meter_query_channels(h_control, &count);
- if (err)
- count = HPI_MAX_CHANNELS;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = count;
- uinfo->value.integer.min = min_gain_mB / VOL_STEP_mB;
- uinfo->value.integer.max = max_gain_mB / VOL_STEP_mB;
- uinfo->value.integer.step = step_gain_mB / VOL_STEP_mB;
- return 0;
-}
-
-static int snd_asihpi_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- u32 h_control = kcontrol->private_value;
- short an_gain_mB[HPI_MAX_CHANNELS];
-
- hpi_handle_error(hpi_volume_get_gain(h_control, an_gain_mB));
- ucontrol->value.integer.value[0] = an_gain_mB[0] / VOL_STEP_mB;
- ucontrol->value.integer.value[1] = an_gain_mB[1] / VOL_STEP_mB;
-
- return 0;
-}
-
-static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int change;
- u32 h_control = kcontrol->private_value;
- short an_gain_mB[HPI_MAX_CHANNELS];
-
- an_gain_mB[0] =
- (ucontrol->value.integer.value[0]) * VOL_STEP_mB;
- an_gain_mB[1] =
- (ucontrol->value.integer.value[1]) * VOL_STEP_mB;
- /* change = asihpi->mixer_volume[addr][0] != left ||
- asihpi->mixer_volume[addr][1] != right;
- */
- change = 1;
- hpi_handle_error(hpi_volume_set_gain(h_control, an_gain_mB));
- return change;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
-
-#define snd_asihpi_volume_mute_info snd_ctl_boolean_mono_info
-
-static int snd_asihpi_volume_mute_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- u32 h_control = kcontrol->private_value;
- u32 mute;
-
- hpi_handle_error(hpi_volume_get_mute(h_control, &mute));
- ucontrol->value.integer.value[0] = mute ? 0 : 1;
-
- return 0;
-}
-
-static int snd_asihpi_volume_mute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- u32 h_control = kcontrol->private_value;
- int change = 1;
- /* HPI currently only supports all or none muting of multichannel volume
- ALSA Switch element has opposite sense to HPI mute: on==unmuted, off=muted
- */
- int mute = ucontrol->value.integer.value[0] ? 0 : HPI_BITMASK_ALL_CHANNELS;
- hpi_handle_error(hpi_volume_set_mute(h_control, mute));
- return change;
-}
-
-static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
- struct hpi_control *hpi_ctl)
-{
- struct snd_card *card = asihpi->card;
- struct snd_kcontrol_new snd_control;
- int err;
- u32 mute;
-
- asihpi_ctl_init(&snd_control, hpi_ctl, "Volume");
- snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ;
- snd_control.info = snd_asihpi_volume_info;
- snd_control.get = snd_asihpi_volume_get;
- snd_control.put = snd_asihpi_volume_put;
- snd_control.tlv.p = db_scale_100;
-
- err = ctl_add(card, &snd_control, asihpi);
- if (err)
- return err;
-
- if (hpi_volume_get_mute(hpi_ctl->h_control, &mute) == 0) {
- asihpi_ctl_init(&snd_control, hpi_ctl, "Switch");
- snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
- snd_control.info = snd_asihpi_volume_mute_info;
- snd_control.get = snd_asihpi_volume_mute_get;
- snd_control.put = snd_asihpi_volume_mute_put;
- err = ctl_add(card, &snd_control, asihpi);
- }
- return err;
-}
-
-/*------------------------------------------------------------
- Level controls
- ------------------------------------------------------------*/
-static int snd_asihpi_level_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- u32 h_control = kcontrol->private_value;
- u16 err;
- short min_gain_mB;
- short max_gain_mB;
- short step_gain_mB;
-
- err =
- hpi_level_query_range(h_control, &min_gain_mB,
- &max_gain_mB, &step_gain_mB);
- if (err) {
- max_gain_mB = 2400;
- min_gain_mB = -1000;
- step_gain_mB = 100;
- }
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = min_gain_mB / HPI_UNITS_PER_dB;
- uinfo->value.integer.max = max_gain_mB / HPI_UNITS_PER_dB;
- uinfo->value.integer.step = step_gain_mB / HPI_UNITS_PER_dB;
- return 0;
-}
-
-static int snd_asihpi_level_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- u32 h_control = kcontrol->private_value;
- short an_gain_mB[HPI_MAX_CHANNELS];
-
- hpi_handle_error(hpi_level_get_gain(h_control, an_gain_mB));
- ucontrol->value.integer.value[0] =
- an_gain_mB[0] / HPI_UNITS_PER_dB;
- ucontrol->value.integer.value[1] =
- an_gain_mB[1] / HPI_UNITS_PER_dB;
-
- return 0;
-}
-
-static int snd_asihpi_level_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int change;
- u32 h_control = kcontrol->private_value;
- short an_gain_mB[HPI_MAX_CHANNELS];
-
- an_gain_mB[0] =
- (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
- an_gain_mB[1] =
- (ucontrol->value.integer.value[1]) * HPI_UNITS_PER_dB;
- /* change = asihpi->mixer_level[addr][0] != left ||
- asihpi->mixer_level[addr][1] != right;
- */
- change = 1;
- hpi_handle_error(hpi_level_set_gain(h_control, an_gain_mB));
- return change;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_level, -1000, 100, 0);
-
-static int __devinit snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
- struct hpi_control *hpi_ctl)
-{
- struct snd_card *card = asihpi->card;
- struct snd_kcontrol_new snd_control;
-
- /* can't use 'volume' cos some nodes have volume as well */
- asihpi_ctl_init(&snd_control, hpi_ctl, "Level");
- snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ;
- snd_control.info = snd_asihpi_level_info;
- snd_control.get = snd_asihpi_level_get;
- snd_control.put = snd_asihpi_level_put;
- snd_control.tlv.p = db_scale_level;
-
- return ctl_add(card, &snd_control, asihpi);
-}
-
-/*------------------------------------------------------------
- AESEBU controls
- ------------------------------------------------------------*/
-
-/* AESEBU format */
-static const char * const asihpi_aesebu_format_names[] = {
- "N/A", "S/PDIF", "AES/EBU" };
-
-static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
-
- strcpy(uinfo->value.enumerated.name,
- asihpi_aesebu_format_names[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol,
- u16 (*func)(u32, u16 *))
-{
- u32 h_control = kcontrol->private_value;
- u16 source, err;
-
- err = func(h_control, &source);
-
- /* default to N/A */
- ucontrol->value.enumerated.item[0] = 0;
- /* return success but set the control to N/A */
- if (err)
- return 0;
- if (source == HPI_AESEBU_FORMAT_SPDIF)
- ucontrol->value.enumerated.item[0] = 1;
- if (source == HPI_AESEBU_FORMAT_AESEBU)
- ucontrol->value.enumerated.item[0] = 2;
-
- return 0;
-}
-
-static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol,
- u16 (*func)(u32, u16))
-{
- u32 h_control = kcontrol->private_value;
-
- /* default to S/PDIF */
- u16 source = HPI_AESEBU_FORMAT_SPDIF;
-
- if (ucontrol->value.enumerated.item[0] == 1)
- source = HPI_AESEBU_FORMAT_SPDIF;
- if (ucontrol->value.enumerated.item[0] == 2)
- source = HPI_AESEBU_FORMAT_AESEBU;
-
- if (func(h_control, source) != 0)
- return -EINVAL;
-
- return 1;
-}
-
-static int snd_asihpi_aesebu_rx_format_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol) {
- return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
- hpi_aesebu_receiver_get_format);
-}
-
-static int snd_asihpi_aesebu_rx_format_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol) {
- return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
- hpi_aesebu_receiver_set_format);
-}
-
-static int snd_asihpi_aesebu_rxstatus_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
-
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 0X1F;
- uinfo->value.integer.step = 1;
-
- return 0;
-}
-
-static int snd_asihpi_aesebu_rxstatus_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol) {
-
- u32 h_control = kcontrol->private_value;
- u16 status;
-
- hpi_handle_error(hpi_aesebu_receiver_get_error_status(
- h_control, &status));
- ucontrol->value.integer.value[0] = status;
- return 0;
-}
-
-static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
- struct hpi_control *hpi_ctl)
-{
- struct snd_card *card = asihpi->card;
- struct snd_kcontrol_new snd_control;
-
- asihpi_ctl_init(&snd_control, hpi_ctl, "Format");
- snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
- snd_control.info = snd_asihpi_aesebu_format_info;
- snd_control.get = snd_asihpi_aesebu_rx_format_get;
- snd_control.put = snd_asihpi_aesebu_rx_format_put;
-
-
- if (ctl_add(card, &snd_control, asihpi) < 0)
- return -EINVAL;
-
- asihpi_ctl_init(&snd_control, hpi_ctl, "Status");
- snd_control.access =
- SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
- snd_control.info = snd_asihpi_aesebu_rxstatus_info;
- snd_control.get = snd_asihpi_aesebu_rxstatus_get;
-
- return ctl_add(card, &snd_control, asihpi);
-}
-
-static int snd_asihpi_aesebu_tx_format_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol) {
- return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
- hpi_aesebu_transmitter_get_format);
-}
-
-static int snd_asihpi_aesebu_tx_format_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol) {
- return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
- hpi_aesebu_transmitter_set_format);
-}
-
-
-static int __devinit snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi,
- struct hpi_control *hpi_ctl)
-{
- struct snd_card *card = asihpi->card;
- struct snd_kcontrol_new snd_control;
-
- asihpi_ctl_init(&snd_control, hpi_ctl, "Format");
- snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
- snd_control.info = snd_asihpi_aesebu_format_info;
- snd_control.get = snd_asihpi_aesebu_tx_format_get;
- snd_control.put = snd_asihpi_aesebu_tx_format_put;
-
- return ctl_add(card, &snd_control, asihpi);
-}
-
-/*------------------------------------------------------------
- Tuner controls
- ------------------------------------------------------------*/
-
-/* Gain */
-
-static int snd_asihpi_tuner_gain_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- u32 h_control = kcontrol->private_value;
- u16 err;
- short idx;
- u16 gain_range[3];
-
- for (idx = 0; idx < 3; idx++) {
- err = hpi_tuner_query_gain(h_control,
- idx, &gain_range[idx]);
- if (err != 0)
- return err;
- }
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = ((int)gain_range[0]) / HPI_UNITS_PER_dB;
- uinfo->value.integer.max = ((int)gain_range[1]) / HPI_UNITS_PER_dB;
- uinfo->value.integer.step = ((int) gain_range[2]) / HPI_UNITS_PER_dB;
- return 0;
-}
-
-static int snd_asihpi_tuner_gain_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- /*
- struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
- */
- u32 h_control = kcontrol->private_value;
- short gain;
-
- hpi_handle_error(hpi_tuner_get_gain(h_control, &gain));
- ucontrol->value.integer.value[0] = gain / HPI_UNITS_PER_dB;
-
- return 0;
-}
-
-static int snd_asihpi_tuner_gain_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- /*
- struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
- */
- u32 h_control = kcontrol->private_value;
- short gain;
-
- gain = (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
- hpi_handle_error(hpi_tuner_set_gain(h_control, gain));
-
- return 1;
-}
-
-/* Band */
-
-static int asihpi_tuner_band_query(struct snd_kcontrol *kcontrol,
- u16 *band_list, u32 len) {
- u32 h_control = kcontrol->private_value;
- u16 err = 0;
- u32 i;
-
- for (i = 0; i < len; i++) {
- err = hpi_tuner_query_band(
- h_control, i, &band_list[i]);
- if (err != 0)
- break;
- }
-
- if (err && (err != HPI_ERROR_INVALID_OBJ_INDEX))
- return -EIO;
-
- return i;
-}
-
-static int snd_asihpi_tuner_band_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- u16 tuner_bands[HPI_TUNER_BAND_LAST];
- int num_bands = 0;
-
- num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
- HPI_TUNER_BAND_LAST);
-
- if (num_bands < 0)
- return num_bands;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = num_bands;
-
- if (num_bands > 0) {
- if (uinfo->value.enumerated.item >=
- uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
-
- strcpy(uinfo->value.enumerated.name,
- asihpi_tuner_band_names[
- tuner_bands[uinfo->value.enumerated.item]]);
-
- }
- return 0;
-}
-
-static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- u32 h_control = kcontrol->private_value;
- /*
- struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
- */
- u16 band, idx;
- u16 tuner_bands[HPI_TUNER_BAND_LAST];
- u32 num_bands = 0;
-
- num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
- HPI_TUNER_BAND_LAST);
-
- hpi_handle_error(hpi_tuner_get_band(h_control, &band));
-
- ucontrol->value.enumerated.item[0] = -1;
- for (idx = 0; idx < HPI_TUNER_BAND_LAST; idx++)
- if (tuner_bands[idx] == band) {
- ucontrol->value.enumerated.item[0] = idx;
- break;
- }
-
- return 0;
-}
-
-static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- /*
- struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
- */
- u32 h_control = kcontrol->private_value;
- u16 band;
- u16 tuner_bands[HPI_TUNER_BAND_LAST];
- u32 num_bands = 0;
-
- num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
- HPI_TUNER_BAND_LAST);
-
- band = tuner_bands[ucontrol->value.enumerated.item[0]];
- hpi_handle_error(hpi_tuner_set_band(h_control, band));
-
- return 1;
-}
-
-/* Freq */
-
-static int snd_asihpi_tuner_freq_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- u32 h_control = kcontrol->private_value;
- u16 err;
- u16 tuner_bands[HPI_TUNER_BAND_LAST];
- u16 num_bands = 0, band_iter, idx;
- u32 freq_range[3], temp_freq_range[3];
-
- num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
- HPI_TUNER_BAND_LAST);
-
- freq_range[0] = INT_MAX;
- freq_range[1] = 0;
- freq_range[2] = INT_MAX;
-
- for (band_iter = 0; band_iter < num_bands; band_iter++) {
- for (idx = 0; idx < 3; idx++) {
- err = hpi_tuner_query_frequency(h_control,
- idx, tuner_bands[band_iter],
- &temp_freq_range[idx]);
- if (err != 0)
- return err;
- }
-
- /* skip band with bogus stepping */
- if (temp_freq_range[2] <= 0)
- continue;
-
- if (temp_freq_range[0] < freq_range[0])
- freq_range[0] = temp_freq_range[0];
- if (temp_freq_range[1] > freq_range[1])
- freq_range[1] = temp_freq_range[1];
- if (temp_freq_range[2] < freq_range[2])
- freq_range[2] = temp_freq_range[2];
- }
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = ((int)freq_range[0]);
- uinfo->value.integer.max = ((int)freq_range[1]);
- uinfo->value.integer.step = ((int)freq_range[2]);
- return 0;
-}
-
-static int snd_asihpi_tuner_freq_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- u32 h_control = kcontrol->private_value;
- u32 freq;
-
- hpi_handle_error(hpi_tuner_get_frequency(h_control, &freq));
- ucontrol->value.integer.value[0] = freq;
-
- return 0;
-}
-
-static int snd_asihpi_tuner_freq_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- u32 h_control = kcontrol->private_value;
- u32 freq;
-
- freq = ucontrol->value.integer.value[0];
- hpi_handle_error(hpi_tuner_set_frequency(h_control, freq));
-
- return 1;
-}
-
-/* Tuner control group initializer */
-static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
- struct hpi_control *hpi_ctl)
-{
- struct snd_card *card = asihpi->card;
- struct snd_kcontrol_new snd_control;
-
- snd_control.private_value = hpi_ctl->h_control;
- snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
-
- if (!hpi_tuner_get_gain(hpi_ctl->h_control, NULL)) {
- asihpi_ctl_init(&snd_control, hpi_ctl, "Gain");
- snd_control.info = snd_asihpi_tuner_gain_info;
- snd_control.get = snd_asihpi_tuner_gain_get;
- snd_control.put = snd_asihpi_tuner_gain_put;
-
- if (ctl_add(card, &snd_control, asihpi) < 0)
- return -EINVAL;
- }
-
- asihpi_ctl_init(&snd_control, hpi_ctl, "Band");
- snd_control.info = snd_asihpi_tuner_band_info;
- snd_control.get = snd_asihpi_tuner_band_get;
- snd_control.put = snd_asihpi_tuner_band_put;
-
- if (ctl_add(card, &snd_control, asihpi) < 0)
- return -EINVAL;
-
- asihpi_ctl_init(&snd_control, hpi_ctl, "Freq");
- snd_control.info = snd_asihpi_tuner_freq_info;
- snd_control.get = snd_asihpi_tuner_freq_get;
- snd_control.put = snd_asihpi_tuner_freq_put;
-
- return ctl_add(card, &snd_control, asihpi);
-}
-
-/*------------------------------------------------------------
- Meter controls
- ------------------------------------------------------------*/
-static int snd_asihpi_meter_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- u32 h_control = kcontrol->private_value;
- u32 count;
- u16 err;
- err = hpi_meter_query_channels(h_control, &count);
- if (err)
- count = HPI_MAX_CHANNELS;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = count;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 0x7FFFFFFF;
- return 0;
-}
-
-/* linear values for 10dB steps */
-static int log2lin[] = {
- 0x7FFFFFFF, /* 0dB */
- 679093956,
- 214748365,
- 67909396,
- 21474837,
- 6790940,
- 2147484, /* -60dB */
- 679094,
- 214748, /* -80 */
- 67909,
- 21475, /* -100 */
- 6791,
- 2147,
- 679,
- 214,
- 68,
- 21,
- 7,
- 2
-};
-
-static int snd_asihpi_meter_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- u32 h_control = kcontrol->private_value;
- short an_gain_mB[HPI_MAX_CHANNELS], i;
- u16 err;
-
- err = hpi_meter_get_peak(h_control, an_gain_mB);
-
- for (i = 0; i < HPI_MAX_CHANNELS; i++) {
- if (err) {
- ucontrol->value.integer.value[i] = 0;
- } else if (an_gain_mB[i] >= 0) {
- ucontrol->value.integer.value[i] =
- an_gain_mB[i] << 16;
- } else {
- /* -ve is log value in millibels < -60dB,
- * convert to (roughly!) linear,
- */
- ucontrol->value.integer.value[i] =
- log2lin[an_gain_mB[i] / -1000];
- }
- }
- return 0;
-}
-
-static int __devinit snd_asihpi_meter_add(struct snd_card_asihpi *asihpi,
- struct hpi_control *hpi_ctl, int subidx)
-{
- struct snd_card *card = asihpi->card;
- struct snd_kcontrol_new snd_control;
-
- asihpi_ctl_init(&snd_control, hpi_ctl, "Meter");
- snd_control.access =
- SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
- snd_control.info = snd_asihpi_meter_info;
- snd_control.get = snd_asihpi_meter_get;
-
- snd_control.index = subidx;
-
- return ctl_add(card, &snd_control, asihpi);
-}
-
-/*------------------------------------------------------------
- Multiplexer controls
- ------------------------------------------------------------*/
-static int snd_card_asihpi_mux_count_sources(struct snd_kcontrol *snd_control)
-{
- u32 h_control = snd_control->private_value;
- struct hpi_control hpi_ctl;
- int s, err;
- for (s = 0; s < 32; s++) {
- err = hpi_multiplexer_query_source(h_control, s,
- &hpi_ctl.
- src_node_type,
- &hpi_ctl.
- src_node_index);
- if (err)
- break;
- }
- return s;
-}
-
-static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int err;
- u16 src_node_type, src_node_index;
- u32 h_control = kcontrol->private_value;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items =
- snd_card_asihpi_mux_count_sources(kcontrol);
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
-
- err =
- hpi_multiplexer_query_source(h_control,
- uinfo->value.enumerated.item,
- &src_node_type, &src_node_index);
-
- sprintf(uinfo->value.enumerated.name, "%s %d",
- asihpi_src_names[src_node_type - HPI_SOURCENODE_NONE],
- src_node_index);
- return 0;
-}
-
-static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- u32 h_control = kcontrol->private_value;
- u16 source_type, source_index;
- u16 src_node_type, src_node_index;
- int s;
-
- hpi_handle_error(hpi_multiplexer_get_source(h_control,
- &source_type, &source_index));
- /* Should cache this search result! */
- for (s = 0; s < 256; s++) {
- if (hpi_multiplexer_query_source(h_control, s,
- &src_node_type, &src_node_index))
- break;
-
- if ((source_type == src_node_type)
- && (source_index == src_node_index)) {
- ucontrol->value.enumerated.item[0] = s;
- return 0;
- }
- }
- snd_printd(KERN_WARNING
- "Control %x failed to match mux source %hu %hu\n",
- h_control, source_type, source_index);
- ucontrol->value.enumerated.item[0] = 0;
- return 0;
-}
-
-static int snd_asihpi_mux_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int change;
- u32 h_control = kcontrol->private_value;
- u16 source_type, source_index;
- u16 e;
-
- change = 1;
-
- e = hpi_multiplexer_query_source(h_control,
- ucontrol->value.enumerated.item[0],
- &source_type, &source_index);
- if (!e)
- hpi_handle_error(
- hpi_multiplexer_set_source(h_control,
- source_type, source_index));
- return change;
-}
-
-
-static int __devinit snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
- struct hpi_control *hpi_ctl)
-{
- struct snd_card *card = asihpi->card;
- struct snd_kcontrol_new snd_control;
-
- asihpi_ctl_init(&snd_control, hpi_ctl, "Route");
- snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
- snd_control.info = snd_asihpi_mux_info;
- snd_control.get = snd_asihpi_mux_get;
- snd_control.put = snd_asihpi_mux_put;
-
- return ctl_add(card, &snd_control, asihpi);
-
-}
-
-/*------------------------------------------------------------
- Channel mode controls
- ------------------------------------------------------------*/
-static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static const char * const mode_names[HPI_CHANNEL_MODE_LAST + 1] = {
- "invalid",
- "Normal", "Swap",
- "From Left", "From Right",
- "To Left", "To Right"
- };
-
- u32 h_control = kcontrol->private_value;
- u16 mode;
- int i;
- u16 mode_map[6];
- int valid_modes = 0;
-
- /* HPI channel mode values can be from 1 to 6
- Some adapters only support a contiguous subset
- */
- for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++)
- if (!hpi_channel_mode_query_mode(
- h_control, i, &mode)) {
- mode_map[valid_modes] = mode;
- valid_modes++;
- }
-
- if (!valid_modes)
- return -EINVAL;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = valid_modes;
-
- if (uinfo->value.enumerated.item >= valid_modes)
- uinfo->value.enumerated.item = valid_modes - 1;
-
- strcpy(uinfo->value.enumerated.name,
- mode_names[mode_map[uinfo->value.enumerated.item]]);
-
- return 0;
-}
-
-static int snd_asihpi_cmode_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- u32 h_control = kcontrol->private_value;
- u16 mode;
-
- if (hpi_channel_mode_get(h_control, &mode))
- mode = 1;
-
- ucontrol->value.enumerated.item[0] = mode - 1;
-
- return 0;
-}
-
-static int snd_asihpi_cmode_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int change;
- u32 h_control = kcontrol->private_value;
-
- change = 1;
-
- hpi_handle_error(hpi_channel_mode_set(h_control,
- ucontrol->value.enumerated.item[0] + 1));
- return change;
-}
-
-
-static int __devinit snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
- struct hpi_control *hpi_ctl)
-{
- struct snd_card *card = asihpi->card;
- struct snd_kcontrol_new snd_control;
-
- asihpi_ctl_init(&snd_control, hpi_ctl, "Mode");
- snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
- snd_control.info = snd_asihpi_cmode_info;
- snd_control.get = snd_asihpi_cmode_get;
- snd_control.put = snd_asihpi_cmode_put;
-
- return ctl_add(card, &snd_control, asihpi);
-}
-
-/*------------------------------------------------------------
- Sampleclock source controls
- ------------------------------------------------------------*/
-static char *sampleclock_sources[MAX_CLOCKSOURCES] = {
- "N/A", "Local PLL", "Digital Sync", "Word External", "Word Header",
- "SMPTE", "Digital1", "Auto", "Network", "Invalid",
- "Prev Module",
- "Digital2", "Digital3", "Digital4", "Digital5",
- "Digital6", "Digital7", "Digital8"};
-
-static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct snd_card_asihpi *asihpi =
- (struct snd_card_asihpi *)(kcontrol->private_data);
- struct clk_cache *clkcache = &asihpi->cc;
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = clkcache->count;
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
-
- strcpy(uinfo->value.enumerated.name,
- clkcache->s[uinfo->value.enumerated.item].name);
- return 0;
-}
-
-static int snd_asihpi_clksrc_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_card_asihpi *asihpi =
- (struct snd_card_asihpi *)(kcontrol->private_data);
- struct clk_cache *clkcache = &asihpi->cc;
- u32 h_control = kcontrol->private_value;
- u16 source, srcindex = 0;
- int i;
-
- ucontrol->value.enumerated.item[0] = 0;
- if (hpi_sample_clock_get_source(h_control, &source))
- source = 0;
-
- if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
- if (hpi_sample_clock_get_source_index(h_control, &srcindex))
- srcindex = 0;
-
- for (i = 0; i < clkcache->count; i++)
- if ((clkcache->s[i].source == source) &&
- (clkcache->s[i].index == srcindex))
- break;
-
- ucontrol->value.enumerated.item[0] = i;
-
- return 0;
-}
-
-static int snd_asihpi_clksrc_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_card_asihpi *asihpi =
- (struct snd_card_asihpi *)(kcontrol->private_data);
- struct clk_cache *clkcache = &asihpi->cc;
- int change, item;
- u32 h_control = kcontrol->private_value;
-
- change = 1;
- item = ucontrol->value.enumerated.item[0];
- if (item >= clkcache->count)
- item = clkcache->count-1;
-
- hpi_handle_error(hpi_sample_clock_set_source(
- h_control, clkcache->s[item].source));
-
- if (clkcache->s[item].source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
- hpi_handle_error(hpi_sample_clock_set_source_index(
- h_control, clkcache->s[item].index));
- return change;
-}
-
-/*------------------------------------------------------------
- Clkrate controls
- ------------------------------------------------------------*/
-/* Need to change this to enumerated control with list of rates */
-static int snd_asihpi_clklocal_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 8000;
- uinfo->value.integer.max = 192000;
- uinfo->value.integer.step = 100;
-
- return 0;
-}
-
-static int snd_asihpi_clklocal_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- u32 h_control = kcontrol->private_value;
- u32 rate;
- u16 e;
-
- e = hpi_sample_clock_get_local_rate(h_control, &rate);
- if (!e)
- ucontrol->value.integer.value[0] = rate;
- else
- ucontrol->value.integer.value[0] = 0;
- return 0;
-}
-
-static int snd_asihpi_clklocal_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int change;
- u32 h_control = kcontrol->private_value;
-
- /* change = asihpi->mixer_clkrate[addr][0] != left ||
- asihpi->mixer_clkrate[addr][1] != right;
- */
- change = 1;
- hpi_handle_error(hpi_sample_clock_set_local_rate(h_control,
- ucontrol->value.integer.value[0]));
- return change;
-}
-
-static int snd_asihpi_clkrate_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 8000;
- uinfo->value.integer.max = 192000;
- uinfo->value.integer.step = 100;
-
- return 0;
-}
-
-static int snd_asihpi_clkrate_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- u32 h_control = kcontrol->private_value;
- u32 rate;
- u16 e;
-
- e = hpi_sample_clock_get_sample_rate(h_control, &rate);
- if (!e)
- ucontrol->value.integer.value[0] = rate;
- else
- ucontrol->value.integer.value[0] = 0;
- return 0;
-}
-
-static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
- struct hpi_control *hpi_ctl)
-{
- struct snd_card *card = asihpi->card;
- struct snd_kcontrol_new snd_control;
-
- struct clk_cache *clkcache = &asihpi->cc;
- u32 hSC = hpi_ctl->h_control;
- int has_aes_in = 0;
- int i, j;
- u16 source;
-
- snd_control.private_value = hpi_ctl->h_control;
-
- clkcache->has_local = 0;
-
- for (i = 0; i <= HPI_SAMPLECLOCK_SOURCE_LAST; i++) {
- if (hpi_sample_clock_query_source(hSC,
- i, &source))
- break;
- clkcache->s[i].source = source;
- clkcache->s[i].index = 0;
- clkcache->s[i].name = sampleclock_sources[source];
- if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
- has_aes_in = 1;
- if (source == HPI_SAMPLECLOCK_SOURCE_LOCAL)
- clkcache->has_local = 1;
- }
- if (has_aes_in)
- /* already will have picked up index 0 above */
- for (j = 1; j < 8; j++) {
- if (hpi_sample_clock_query_source_index(hSC,
- j, HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT,
- &source))
- break;
- clkcache->s[i].source =
- HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT;
- clkcache->s[i].index = j;
- clkcache->s[i].name = sampleclock_sources[
- j+HPI_SAMPLECLOCK_SOURCE_LAST];
- i++;
- }
- clkcache->count = i;
-
- asihpi_ctl_init(&snd_control, hpi_ctl, "Source");
- snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
- snd_control.info = snd_asihpi_clksrc_info;
- snd_control.get = snd_asihpi_clksrc_get;
- snd_control.put = snd_asihpi_clksrc_put;
- if (ctl_add(card, &snd_control, asihpi) < 0)
- return -EINVAL;
-
-
- if (clkcache->has_local) {
- asihpi_ctl_init(&snd_control, hpi_ctl, "Localrate");
- snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
- snd_control.info = snd_asihpi_clklocal_info;
- snd_control.get = snd_asihpi_clklocal_get;
- snd_control.put = snd_asihpi_clklocal_put;
-
-
- if (ctl_add(card, &snd_control, asihpi) < 0)
- return -EINVAL;
- }
-
- asihpi_ctl_init(&snd_control, hpi_ctl, "Rate");
- snd_control.access =
- SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
- snd_control.info = snd_asihpi_clkrate_info;
- snd_control.get = snd_asihpi_clkrate_get;
-
- return ctl_add(card, &snd_control, asihpi);
-}
-/*------------------------------------------------------------
- Mixer
- ------------------------------------------------------------*/
-
-static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
-{
- struct snd_card *card = asihpi->card;
- unsigned int idx = 0;
- unsigned int subindex = 0;
- int err;
- struct hpi_control hpi_ctl, prev_ctl;
-
- if (snd_BUG_ON(!asihpi))
- return -EINVAL;
- strcpy(card->mixername, "Asihpi Mixer");
-
- err =
- hpi_mixer_open(asihpi->hpi->adapter->index,
- &asihpi->h_mixer);
- hpi_handle_error(err);
- if (err)
- return -err;
-
- memset(&prev_ctl, 0, sizeof(prev_ctl));
- prev_ctl.control_type = -1;
-
- for (idx = 0; idx < 2000; idx++) {
- err = hpi_mixer_get_control_by_index(
- asihpi->h_mixer,
- idx,
- &hpi_ctl.src_node_type,
- &hpi_ctl.src_node_index,
- &hpi_ctl.dst_node_type,
- &hpi_ctl.dst_node_index,
- &hpi_ctl.control_type,
- &hpi_ctl.h_control);
- if (err) {
- if (err == HPI_ERROR_CONTROL_DISABLED) {
- if (mixer_dump)
- snd_printk(KERN_INFO
- "Disabled HPI Control(%d)\n",
- idx);
- continue;
- } else
- break;
-
- }
-
- hpi_ctl.src_node_type -= HPI_SOURCENODE_NONE;
- hpi_ctl.dst_node_type -= HPI_DESTNODE_NONE;
-
- /* ASI50xx in SSX mode has multiple meters on the same node.
- Use subindex to create distinct ALSA controls
- for any duplicated controls.
- */
- if ((hpi_ctl.control_type == prev_ctl.control_type) &&
- (hpi_ctl.src_node_type == prev_ctl.src_node_type) &&
- (hpi_ctl.src_node_index == prev_ctl.src_node_index) &&
- (hpi_ctl.dst_node_type == prev_ctl.dst_node_type) &&
- (hpi_ctl.dst_node_index == prev_ctl.dst_node_index))
- subindex++;
- else
- subindex = 0;
-
- prev_ctl = hpi_ctl;
-
- switch (hpi_ctl.control_type) {
- case HPI_CONTROL_VOLUME:
- err = snd_asihpi_volume_add(asihpi, &hpi_ctl);
- break;
- case HPI_CONTROL_LEVEL:
- err = snd_asihpi_level_add(asihpi, &hpi_ctl);
- break;
- case HPI_CONTROL_MULTIPLEXER:
- err = snd_asihpi_mux_add(asihpi, &hpi_ctl);
- break;
- case HPI_CONTROL_CHANNEL_MODE:
- err = snd_asihpi_cmode_add(asihpi, &hpi_ctl);
- break;
- case HPI_CONTROL_METER:
- err = snd_asihpi_meter_add(asihpi, &hpi_ctl, subindex);
- break;
- case HPI_CONTROL_SAMPLECLOCK:
- err = snd_asihpi_sampleclock_add(
- asihpi, &hpi_ctl);
- break;
- case HPI_CONTROL_CONNECTION: /* ignore these */
- continue;
- case HPI_CONTROL_TUNER:
- err = snd_asihpi_tuner_add(asihpi, &hpi_ctl);
- break;
- case HPI_CONTROL_AESEBU_TRANSMITTER:
- err = snd_asihpi_aesebu_tx_add(asihpi, &hpi_ctl);
- break;
- case HPI_CONTROL_AESEBU_RECEIVER:
- err = snd_asihpi_aesebu_rx_add(asihpi, &hpi_ctl);
- break;
- case HPI_CONTROL_VOX:
- case HPI_CONTROL_BITSTREAM:
- case HPI_CONTROL_MICROPHONE:
- case HPI_CONTROL_PARAMETRIC_EQ:
- case HPI_CONTROL_COMPANDER:
- default:
- if (mixer_dump)
- snd_printk(KERN_INFO
- "Untranslated HPI Control"
- "(%d) %d %d %d %d %d\n",
- idx,
- hpi_ctl.control_type,
- hpi_ctl.src_node_type,
- hpi_ctl.src_node_index,
- hpi_ctl.dst_node_type,
- hpi_ctl.dst_node_index);
- continue;
- };
- if (err < 0)
- return err;
- }
- if (HPI_ERROR_INVALID_OBJ_INDEX != err)
- hpi_handle_error(err);
-
- snd_printk(KERN_INFO "%d mixer controls found\n", idx);
-
- return 0;
-}
-
-/*------------------------------------------------------------
- /proc interface
- ------------------------------------------------------------*/
-
-static void
-snd_asihpi_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_card_asihpi *asihpi = entry->private_data;
- u32 h_control;
- u32 rate = 0;
- u16 source = 0;
-
- u16 num_outstreams;
- u16 num_instreams;
- u16 version;
- u32 serial_number;
- u16 type;
-
- int err;
-
- snd_iprintf(buffer, "ASIHPI driver proc file\n");
-
- hpi_handle_error(hpi_adapter_get_info(asihpi->hpi->adapter->index,
- &num_outstreams, &num_instreams,
- &version, &serial_number, &type));
-
- snd_iprintf(buffer,
- "Adapter type ASI%4X\nHardware Index %d\n"
- "%d outstreams\n%d instreams\n",
- type, asihpi->hpi->adapter->index,
- num_outstreams, num_instreams);
-
- snd_iprintf(buffer,
- "Serial#%d\nHardware version %c%d\nDSP code version %03d\n",
- serial_number, ((version >> 3) & 0xf) + 'A', version & 0x7,
- ((version >> 13) * 100) + ((version >> 7) & 0x3f));
-
- err = hpi_mixer_get_control(asihpi->h_mixer,
- HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
- HPI_CONTROL_SAMPLECLOCK, &h_control);
-
- if (!err) {
- err = hpi_sample_clock_get_sample_rate(h_control, &rate);
- err += hpi_sample_clock_get_source(h_control, &source);
-
- if (!err)
- snd_iprintf(buffer, "Sample Clock %dHz, source %s\n",
- rate, sampleclock_sources[source]);
- }
-}
-
-static void __devinit snd_asihpi_proc_init(struct snd_card_asihpi *asihpi)
-{
- struct snd_info_entry *entry;
-
- if (!snd_card_proc_new(asihpi->card, "info", &entry))
- snd_info_set_text_ops(entry, asihpi, snd_asihpi_proc_read);
-}
-
-/*------------------------------------------------------------
- HWDEP
- ------------------------------------------------------------*/
-
-static int snd_asihpi_hpi_open(struct snd_hwdep *hw, struct file *file)
-{
- if (enable_hpi_hwdep)
- return 0;
- else
- return -ENODEV;
-
-}
-
-static int snd_asihpi_hpi_release(struct snd_hwdep *hw, struct file *file)
-{
- if (enable_hpi_hwdep)
- return asihpi_hpi_release(file);
- else
- return -ENODEV;
-}
-
-static int snd_asihpi_hpi_ioctl(struct snd_hwdep *hw, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- if (enable_hpi_hwdep)
- return asihpi_hpi_ioctl(file, cmd, arg);
- else
- return -ENODEV;
-}
-
-
-/* results in /dev/snd/hwC#D0 file for each card with index #
- also /proc/asound/hwdep will contain '#-00: asihpi (HPI) for each card'
-*/
-static int __devinit snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi,
- int device, struct snd_hwdep **rhwdep)
-{
- struct snd_hwdep *hw;
- int err;
-
- if (rhwdep)
- *rhwdep = NULL;
- err = snd_hwdep_new(asihpi->card, "HPI", device, &hw);
- if (err < 0)
- return err;
- strcpy(hw->name, "asihpi (HPI)");
- hw->iface = SNDRV_HWDEP_IFACE_LAST;
- hw->ops.open = snd_asihpi_hpi_open;
- hw->ops.ioctl = snd_asihpi_hpi_ioctl;
- hw->ops.release = snd_asihpi_hpi_release;
- hw->private_data = asihpi;
- if (rhwdep)
- *rhwdep = hw;
- return 0;
-}
-
-/*------------------------------------------------------------
- CARD
- ------------------------------------------------------------*/
-static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
-{
- int err;
- struct hpi_adapter *hpi;
- struct snd_card *card;
- struct snd_card_asihpi *asihpi;
-
- u32 h_control;
- u32 h_stream;
- u32 adapter_index;
-
- static int dev;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
-
- /* Should this be enable[hpi->index] ? */
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- /* Initialise low-level HPI driver */
- err = asihpi_adapter_probe(pci_dev, pci_id);
- if (err < 0)
- return err;
-
- hpi = pci_get_drvdata(pci_dev);
- adapter_index = hpi->adapter->index;
- /* first try to give the card the same index as its hardware index */
- err = snd_card_create(adapter_index,
- id[adapter_index], THIS_MODULE,
- sizeof(struct snd_card_asihpi),
- &card);
- if (err < 0) {
- /* if that fails, try the default index==next available */
- err =
- snd_card_create(index[dev], id[dev],
- THIS_MODULE,
- sizeof(struct snd_card_asihpi),
- &card);
- if (err < 0)
- return err;
- snd_printk(KERN_WARNING
- "**** WARNING **** Adapter index %d->ALSA index %d\n",
- adapter_index, card->number);
- }
-
- snd_card_set_dev(card, &pci_dev->dev);
-
- asihpi = card->private_data;
- asihpi->card = card;
- asihpi->pci = pci_dev;
- asihpi->hpi = hpi;
-
- snd_printk(KERN_INFO "adapter ID=%4X index=%d\n",
- asihpi->hpi->adapter->type, adapter_index);
-
- err = hpi_adapter_get_property(adapter_index,
- HPI_ADAPTER_PROPERTY_CAPS1,
- NULL, &asihpi->support_grouping);
- if (err)
- asihpi->support_grouping = 0;
-
- err = hpi_adapter_get_property(adapter_index,
- HPI_ADAPTER_PROPERTY_CAPS2,
- &asihpi->support_mrx, NULL);
- if (err)
- asihpi->support_mrx = 0;
-
- err = hpi_adapter_get_property(adapter_index,
- HPI_ADAPTER_PROPERTY_INTERVAL,
- NULL, &asihpi->update_interval_frames);
- if (err)
- asihpi->update_interval_frames = 512;
-
- if (!asihpi->can_dma)
- asihpi->update_interval_frames *= 2;
-
- hpi_handle_error(hpi_instream_open(adapter_index,
- 0, &h_stream));
-
- err = hpi_instream_host_buffer_free(h_stream);
- asihpi->can_dma = (!err);
-
- hpi_handle_error(hpi_instream_close(h_stream));
-
- err = hpi_adapter_get_property(adapter_index,
- HPI_ADAPTER_PROPERTY_CURCHANNELS,
- &asihpi->in_max_chans, &asihpi->out_max_chans);
- if (err) {
- asihpi->in_max_chans = 2;
- asihpi->out_max_chans = 2;
- }
-
- if (asihpi->out_max_chans > 2) { /* assume LL mode */
- asihpi->out_min_chans = asihpi->out_max_chans;
- asihpi->in_min_chans = asihpi->in_max_chans;
- asihpi->support_grouping = 0;
- } else {
- asihpi->out_min_chans = 1;
- asihpi->in_min_chans = 1;
- }
-
- snd_printk(KERN_INFO "Has dma:%d, grouping:%d, mrx:%d\n",
- asihpi->can_dma,
- asihpi->support_grouping,
- asihpi->support_mrx
- );
-
- err = snd_card_asihpi_pcm_new(asihpi, 0);
- if (err < 0) {
- snd_printk(KERN_ERR "pcm_new failed\n");
- goto __nodev;
- }
- err = snd_card_asihpi_mixer_new(asihpi);
- if (err < 0) {
- snd_printk(KERN_ERR "mixer_new failed\n");
- goto __nodev;
- }
-
- err = hpi_mixer_get_control(asihpi->h_mixer,
- HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
- HPI_CONTROL_SAMPLECLOCK, &h_control);
-
- if (!err)
- err = hpi_sample_clock_set_local_rate(
- h_control, adapter_fs);
-
- snd_asihpi_proc_init(asihpi);
-
- /* always create, can be enabled or disabled dynamically
- by enable_hwdep module param*/
- snd_asihpi_hpi_new(asihpi, 0, NULL);
-
- strcpy(card->driver, "ASIHPI");
-
- sprintf(card->shortname, "AudioScience ASI%4X",
- asihpi->hpi->adapter->type);
- sprintf(card->longname, "%s %i",
- card->shortname, adapter_index);
- err = snd_card_register(card);
-
- if (!err) {
- hpi->snd_card = card;
- dev++;
- return 0;
- }
-__nodev:
- snd_card_free(card);
- snd_printk(KERN_ERR "snd_asihpi_probe error %d\n", err);
- return err;
-
-}
-
-static void __devexit snd_asihpi_remove(struct pci_dev *pci_dev)
-{
- struct hpi_adapter *hpi = pci_get_drvdata(pci_dev);
- snd_card_free(hpi->snd_card);
- hpi->snd_card = NULL;
- asihpi_adapter_remove(pci_dev);
-}
-
-static DEFINE_PCI_DEVICE_TABLE(asihpi_pci_tbl) = {
- {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_DSP6205,
- HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
- (kernel_ulong_t)HPI_6205},
- {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_PCI2040,
- HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
- (kernel_ulong_t)HPI_6000},
- {0,}
-};
-MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = asihpi_pci_tbl,
- .probe = snd_asihpi_probe,
- .remove = __devexit_p(snd_asihpi_remove),
-#ifdef CONFIG_PM
-/* .suspend = snd_asihpi_suspend,
- .resume = snd_asihpi_resume, */
-#endif
-};
-
-static int __init snd_asihpi_init(void)
-{
- asihpi_init();
- return pci_register_driver(&driver);
-}
-
-static void __exit snd_asihpi_exit(void)
-{
-
- pci_unregister_driver(&driver);
- asihpi_exit();
-}
-
-module_init(snd_asihpi_init)
-module_exit(snd_asihpi_exit)
-
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpi.h b/ANDROID_3.4.5/sound/pci/asihpi/hpi.h
deleted file mode 100644
index 20887241..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpi.h
+++ /dev/null
@@ -1,1727 +0,0 @@
-/******************************************************************************
-
- AudioScience HPI driver
- Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-*/
-/** \file hpi.h
-
- AudioScience Hardware Programming Interface (HPI)
- public API definition.
-
- The HPI is a low-level hardware abstraction layer to all
- AudioScience digital audio adapters
-
-(C) Copyright AudioScience Inc. 1998-2010
-*/
-
-#ifndef _HPI_H_
-#define _HPI_H_
-
-#include <linux/types.h>
-#define HPI_BUILD_KERNEL_MODE
-
-/******************************************************************************/
-/******** HPI API DEFINITIONS *****/
-/******************************************************************************/
-
-/*******************************************/
-/** Audio format types
-\ingroup stream
-*/
-enum HPI_FORMATS {
-/** Used internally on adapter. */
- HPI_FORMAT_MIXER_NATIVE = 0,
-/** 8-bit unsigned PCM. Windows equivalent is WAVE_FORMAT_PCM. */
- HPI_FORMAT_PCM8_UNSIGNED = 1,
-/** 16-bit signed PCM. Windows equivalent is WAVE_FORMAT_PCM. */
- HPI_FORMAT_PCM16_SIGNED = 2,
-/** MPEG-1 Layer-1. */
- HPI_FORMAT_MPEG_L1 = 3,
-/** MPEG-1 Layer-2.
-
-Windows equivalent is WAVE_FORMAT_MPEG.
-
-The following table shows what combinations of mode and bitrate are possible:
-
-<table border=1 cellspacing=0 cellpadding=5>
-<tr>
-<td><p><b>Bitrate (kbs)</b></p>
-<td><p><b>Mono</b></p>
-<td><p><b>Stereo,<br>Joint Stereo or<br>Dual Channel</b></p>
-
-<tr><td>32<td>X<td>_
-<tr><td>40<td>_<td>_
-<tr><td>48<td>X<td>_
-<tr><td>56<td>X<td>_
-<tr><td>64<td>X<td>X
-<tr><td>80<td>X<td>_
-<tr><td>96<td>X<td>X
-<tr><td>112<td>X<td>X
-<tr><td>128<td>X<td>X
-<tr><td>160<td>X<td>X
-<tr><td>192<td>X<td>X
-<tr><td>224<td>_<td>X
-<tr><td>256<td>-<td>X
-<tr><td>320<td>-<td>X
-<tr><td>384<td>_<td>X
-</table>
-*/
- HPI_FORMAT_MPEG_L2 = 4,
-/** MPEG-1 Layer-3.
-Windows equivalent is WAVE_FORMAT_MPEG.
-
-The following table shows what combinations of mode and bitrate are possible:
-
-<table border=1 cellspacing=0 cellpadding=5>
-<tr>
-<td><p><b>Bitrate (kbs)</b></p>
-<td><p><b>Mono<br>Stereo @ 8,<br>11.025 and<br>12kHz*</b></p>
-<td><p><b>Mono<br>Stereo @ 16,<br>22.050 and<br>24kHz*</b></p>
-<td><p><b>Mono<br>Stereo @ 32,<br>44.1 and<br>48kHz</b></p>
-
-<tr><td>16<td>X<td>X<td>_
-<tr><td>24<td>X<td>X<td>_
-<tr><td>32<td>X<td>X<td>X
-<tr><td>40<td>X<td>X<td>X
-<tr><td>48<td>X<td>X<td>X
-<tr><td>56<td>X<td>X<td>X
-<tr><td>64<td>X<td>X<td>X
-<tr><td>80<td>_<td>X<td>X
-<tr><td>96<td>_<td>X<td>X
-<tr><td>112<td>_<td>X<td>X
-<tr><td>128<td>_<td>X<td>X
-<tr><td>144<td>_<td>X<td>_
-<tr><td>160<td>_<td>X<td>X
-<tr><td>192<td>_<td>_<td>X
-<tr><td>224<td>_<td>_<td>X
-<tr><td>256<td>-<td>_<td>X
-<tr><td>320<td>-<td>_<td>X
-</table>
-\b * Available on the ASI6000 series only
-*/
- HPI_FORMAT_MPEG_L3 = 5,
-/** Dolby AC-2. */
- HPI_FORMAT_DOLBY_AC2 = 6,
-/** Dolbt AC-3. */
- HPI_FORMAT_DOLBY_AC3 = 7,
-/** 16-bit PCM big-endian. */
- HPI_FORMAT_PCM16_BIGENDIAN = 8,
-/** TAGIT-1 algorithm - hits. */
- HPI_FORMAT_AA_TAGIT1_HITS = 9,
-/** TAGIT-1 algorithm - inserts. */
- HPI_FORMAT_AA_TAGIT1_INSERTS = 10,
-/** 32-bit signed PCM. Windows equivalent is WAVE_FORMAT_PCM.
-Each sample is a 32bit word. The most significant 24 bits contain a 24-bit
-sample and the least significant 8 bits are set to 0.
-*/
- HPI_FORMAT_PCM32_SIGNED = 11,
-/** Raw bitstream - unknown format. */
- HPI_FORMAT_RAW_BITSTREAM = 12,
-/** TAGIT-1 algorithm hits - extended. */
- HPI_FORMAT_AA_TAGIT1_HITS_EX1 = 13,
-/** 32-bit PCM as an IEEE float. Windows equivalent is WAVE_FORMAT_IEEE_FLOAT.
-Each sample is a 32bit word in IEEE754 floating point format.
-The range is +1.0 to -1.0, which corresponds to digital fullscale.
-*/
- HPI_FORMAT_PCM32_FLOAT = 14,
-/** 24-bit PCM signed. Windows equivalent is WAVE_FORMAT_PCM. */
- HPI_FORMAT_PCM24_SIGNED = 15,
-/** OEM format 1 - private. */
- HPI_FORMAT_OEM1 = 16,
-/** OEM format 2 - private. */
- HPI_FORMAT_OEM2 = 17,
-/** Undefined format. */
- HPI_FORMAT_UNDEFINED = 0xffff
-};
-
-/*******************************************/
-/** Stream States
-\ingroup stream
-*/
-enum HPI_STREAM_STATES {
- /** State stopped - stream is stopped. */
- HPI_STATE_STOPPED = 1,
- /** State playing - stream is playing audio. */
- HPI_STATE_PLAYING = 2,
- /** State recording - stream is recording. */
- HPI_STATE_RECORDING = 3,
- /** State drained - playing stream ran out of data to play. */
- HPI_STATE_DRAINED = 4,
- /** State generate sine - to be implemented. */
- HPI_STATE_SINEGEN = 5,
- /** State wait - used for inter-card sync to mean waiting for all
- cards to be ready. */
- HPI_STATE_WAIT = 6
-};
-/*******************************************/
-/** Source node types
-\ingroup mixer
-*/
-enum HPI_SOURCENODES {
- /** This define can be used instead of 0 to indicate
- that there is no valid source node. A control that
- exists on a destination node can be searched for using a source
- node value of either 0, or HPI_SOURCENODE_NONE */
- HPI_SOURCENODE_NONE = 100,
- /** Out Stream (Play) node. */
- HPI_SOURCENODE_OSTREAM = 101,
- /** Line in node - could be analog, AES/EBU or network. */
- HPI_SOURCENODE_LINEIN = 102,
- HPI_SOURCENODE_AESEBU_IN = 103, /**< AES/EBU input node. */
- HPI_SOURCENODE_TUNER = 104, /**< tuner node. */
- HPI_SOURCENODE_RF = 105, /**< RF input node. */
- HPI_SOURCENODE_CLOCK_SOURCE = 106, /**< clock source node. */
- HPI_SOURCENODE_RAW_BITSTREAM = 107, /**< raw bitstream node. */
- HPI_SOURCENODE_MICROPHONE = 108, /**< microphone node. */
- /** Cobranet input node -
- Audio samples come from the Cobranet network and into the device. */
- HPI_SOURCENODE_COBRANET = 109,
- HPI_SOURCENODE_ANALOG = 110, /**< analog input node. */
- HPI_SOURCENODE_ADAPTER = 111, /**< adapter node. */
- /** RTP stream input node - This node is a destination for
- packets of RTP audio samples from other devices. */
- HPI_SOURCENODE_RTP_DESTINATION = 112,
- HPI_SOURCENODE_INTERNAL = 113, /**< node internal to the device. */
- /* !!!Update this AND hpidebug.h if you add a new sourcenode type!!! */
- HPI_SOURCENODE_LAST_INDEX = 113 /**< largest ID */
- /* AX6 max sourcenode types = 15 */
-};
-
-/*******************************************/
-/** Destination node types
-\ingroup mixer
-*/
-enum HPI_DESTNODES {
- /** This define can be used instead of 0 to indicate
- that there is no valid destination node. A control that
- exists on a source node can be searched for using a destination
- node value of either 0, or HPI_DESTNODE_NONE */
- HPI_DESTNODE_NONE = 200,
- /** In Stream (Record) node. */
- HPI_DESTNODE_ISTREAM = 201,
- HPI_DESTNODE_LINEOUT = 202, /**< line out node. */
- HPI_DESTNODE_AESEBU_OUT = 203, /**< AES/EBU output node. */
- HPI_DESTNODE_RF = 204, /**< RF output node. */
- HPI_DESTNODE_SPEAKER = 205, /**< speaker output node. */
- /** Cobranet output node -
- Audio samples from the device are sent out on the Cobranet network.*/
- HPI_DESTNODE_COBRANET = 206,
- HPI_DESTNODE_ANALOG = 207, /**< analog output node. */
- /** RTP stream output node - This node is a source for
- packets of RTP audio samples that are sent to other devices. */
- HPI_DESTNODE_RTP_SOURCE = 208,
- /* !!!Update this AND hpidebug.h if you add a new destnode type!!! */
- HPI_DESTNODE_LAST_INDEX = 208 /**< largest ID */
- /* AX6 max destnode types = 15 */
-};
-
-/*******************************************/
-/** Mixer control types
-\ingroup mixer
-*/
-enum HPI_CONTROLS {
- HPI_CONTROL_GENERIC = 0, /**< generic control. */
- HPI_CONTROL_CONNECTION = 1, /**< A connection between nodes. */
- HPI_CONTROL_VOLUME = 2, /**< volume control - works in dB_fs. */
- HPI_CONTROL_METER = 3, /**< peak meter control. */
- HPI_CONTROL_MUTE = 4, /*mute control - not used at present. */
- HPI_CONTROL_MULTIPLEXER = 5, /**< multiplexer control. */
-
- HPI_CONTROL_AESEBU_TRANSMITTER = 6, /**< AES/EBU transmitter control */
- HPI_CONTROL_AESEBUTX = 6, /* HPI_CONTROL_AESEBU_TRANSMITTER */
-
- HPI_CONTROL_AESEBU_RECEIVER = 7, /**< AES/EBU receiver control. */
- HPI_CONTROL_AESEBURX = 7, /* HPI_CONTROL_AESEBU_RECEIVER */
-
- HPI_CONTROL_LEVEL = 8, /**< level/trim control - works in d_bu. */
- HPI_CONTROL_TUNER = 9, /**< tuner control. */
-/* HPI_CONTROL_ONOFFSWITCH = 10 */
- HPI_CONTROL_VOX = 11, /**< vox control. */
-/* HPI_CONTROL_AES18_TRANSMITTER = 12 */
-/* HPI_CONTROL_AES18_RECEIVER = 13 */
-/* HPI_CONTROL_AES18_BLOCKGENERATOR = 14 */
- HPI_CONTROL_CHANNEL_MODE = 15, /**< channel mode control. */
-
- HPI_CONTROL_BITSTREAM = 16, /**< bitstream control. */
- HPI_CONTROL_SAMPLECLOCK = 17, /**< sample clock control. */
- HPI_CONTROL_MICROPHONE = 18, /**< microphone control. */
- HPI_CONTROL_PARAMETRIC_EQ = 19, /**< parametric EQ control. */
- HPI_CONTROL_EQUALIZER = 19, /*HPI_CONTROL_PARAMETRIC_EQ */
-
- HPI_CONTROL_COMPANDER = 20, /**< compander control. */
- HPI_CONTROL_COBRANET = 21, /**< cobranet control. */
- HPI_CONTROL_TONEDETECTOR = 22, /**< tone detector control. */
- HPI_CONTROL_SILENCEDETECTOR = 23, /**< silence detector control. */
- HPI_CONTROL_PAD = 24, /**< tuner PAD control. */
- HPI_CONTROL_SRC = 25, /**< samplerate converter control. */
- HPI_CONTROL_UNIVERSAL = 26, /**< universal control. */
-
-/* !!! Update this AND hpidebug.h if you add a new control type!!!*/
- HPI_CONTROL_LAST_INDEX = 26 /**<highest control type ID */
-/* WARNING types 256 or greater impact bit packing in all AX6 DSP code */
-};
-
-/*******************************************/
-/** Adapter properties
-These are used in HPI_AdapterSetProperty() and HPI_AdapterGetProperty()
-\ingroup adapter
-*/
-enum HPI_ADAPTER_PROPERTIES {
-/** \internal Used in dwProperty field of HPI_AdapterSetProperty() and
-HPI_AdapterGetProperty(). This errata applies to all ASI6000 cards with both
-analog and digital outputs. The CS4224 A/D+D/A has a one sample delay between
-left and right channels on both its input (ADC) and output (DAC).
-More details are available in Cirrus Logic errata ER284B2.
-PDF available from www.cirrus.com, released by Cirrus in 2001.
-*/
- HPI_ADAPTER_PROPERTY_ERRATA_1 = 1,
-
-/** Adapter grouping property
-Indicates whether the adapter supports the grouping API (for ASIO and SSX2)
-*/
- HPI_ADAPTER_PROPERTY_GROUPING = 2,
-
-/** Driver SSX2 property
-Tells the kernel driver to turn on SSX2 stream mapping.
-This feature is not used by the DSP. In fact the call is completely processed
-by the driver and is not passed on to the DSP at all.
-*/
- HPI_ADAPTER_PROPERTY_ENABLE_SSX2 = 3,
-
-/** Adapter SSX2 property
-Indicates the state of the adapter's SSX2 setting. This setting is stored in
-non-volatile memory on the adapter. A typical call sequence would be to use
-HPI_ADAPTER_PROPERTY_SSX2_SETTING to set SSX2 on the adapter and then to reload
-the driver. The driver would query HPI_ADAPTER_PROPERTY_SSX2_SETTING during
-startup and if SSX2 is set, it would then call HPI_ADAPTER_PROPERTY_ENABLE_SSX2
-to enable SSX2 stream mapping within the kernel level of the driver.
-*/
- HPI_ADAPTER_PROPERTY_SSX2_SETTING = 4,
-
-/** Enables/disables PCI(e) IRQ.
-A setting of 0 indicates that no interrupts are being generated. A DSP boot
-this property is set to 0. Setting to a non-zero value specifies the number
-of frames of audio that should be processed between interrupts. This property
-should be set to multiple of the mixer interval as read back from the
-HPI_ADAPTER_PROPERTY_INTERVAL property.
-*/
- HPI_ADAPTER_PROPERTY_IRQ_RATE = 5,
-
-/** Base number for readonly properties */
- HPI_ADAPTER_PROPERTY_READONLYBASE = 256,
-
-/** Readonly adapter latency property.
-This property returns in the input and output latency in samples.
-Property 1 is the estimated input latency
-in samples, while Property 2 is that output latency in samples.
-*/
- HPI_ADAPTER_PROPERTY_LATENCY = 256,
-
-/** Readonly adapter granularity property.
-The granulariy is the smallest size chunk of stereo samples that is processed by
-the adapter.
-This property returns the record granularity in samples in Property 1.
-Property 2 returns the play granularity.
-*/
- HPI_ADAPTER_PROPERTY_GRANULARITY = 257,
-
-/** Readonly adapter number of current channels property.
-Property 1 is the number of record channels per record device.
-Property 2 is the number of play channels per playback device.*/
- HPI_ADAPTER_PROPERTY_CURCHANNELS = 258,
-
-/** Readonly adapter software version.
-The SOFTWARE_VERSION property returns the version of the software running
-on the adapter as Major.Minor.Release.
-Property 1 contains Major in bits 15..8 and Minor in bits 7..0.
-Property 2 contains Release in bits 7..0. */
- HPI_ADAPTER_PROPERTY_SOFTWARE_VERSION = 259,
-
-/** Readonly adapter MAC address MSBs.
-The MAC_ADDRESS_MSB property returns
-the most significant 32 bits of the MAC address.
-Property 1 contains bits 47..32 of the MAC address.
-Property 2 contains bits 31..16 of the MAC address. */
- HPI_ADAPTER_PROPERTY_MAC_ADDRESS_MSB = 260,
-
-/** Readonly adapter MAC address LSBs
-The MAC_ADDRESS_LSB property returns
-the least significant 16 bits of the MAC address.
-Property 1 contains bits 15..0 of the MAC address. */
- HPI_ADAPTER_PROPERTY_MAC_ADDRESS_LSB = 261,
-
-/** Readonly extended adapter type number
-The EXTENDED_ADAPTER_TYPE property returns the 4 digits of an extended
-adapter type, i.e ASI8920-0022, 0022 is the extended type.
-The digits are returned as ASCII characters rather than the hex digits that
-are returned for the main type
-Property 1 returns the 1st two (left most) digits, i.e "00"
-in the example above, the upper byte being the left most digit.
-Property 2 returns the 2nd two digits, i.e "22" in the example above*/
- HPI_ADAPTER_PROPERTY_EXTENDED_ADAPTER_TYPE = 262,
-
-/** Readonly debug log buffer information */
- HPI_ADAPTER_PROPERTY_LOGTABLEN = 263,
- HPI_ADAPTER_PROPERTY_LOGTABBEG = 264,
-
-/** Readonly adapter IP address
-For 192.168.1.101
-Property 1 returns the 1st two (left most) digits, i.e 192*256 + 168
-in the example above, the upper byte being the left most digit.
-Property 2 returns the 2nd two digits, i.e 1*256 + 101 in the example above, */
- HPI_ADAPTER_PROPERTY_IP_ADDRESS = 265,
-
-/** Readonly adapter buffer processed count. Returns a buffer processed count
-that is incremented every time all buffers for all streams are updated. This
-is useful for checking completion of all stream operations across the adapter
-when using grouped streams.
-*/
- HPI_ADAPTER_PROPERTY_BUFFER_UPDATE_COUNT = 266,
-
-/** Readonly mixer and stream intervals
-
-These intervals are measured in mixer frames.
-To convert to time, divide by the adapter samplerate.
-
-The mixer interval is the number of frames processed in one mixer iteration.
-The stream update interval is the interval at which streams check for and
-process data, and BBM host buffer counters are updated.
-
-Property 1 is the mixer interval in mixer frames.
-Property 2 is the stream update interval in mixer frames.
-*/
- HPI_ADAPTER_PROPERTY_INTERVAL = 267,
-/** Adapter capabilities 1
-Property 1 - adapter can do multichannel (SSX1)
-Property 2 - adapter can do stream grouping (supports SSX2)
-*/
- HPI_ADAPTER_PROPERTY_CAPS1 = 268,
-/** Adapter capabilities 2
-Property 1 - adapter can do samplerate conversion (MRX)
-Property 2 - adapter can do timestretch (TSX)
-*/
- HPI_ADAPTER_PROPERTY_CAPS2 = 269,
-
-/** Readonly adapter sync header connection count.
-*/
- HPI_ADAPTER_PROPERTY_SYNC_HEADER_CONNECTIONS = 270,
-/** Readonly supports SSX2 property.
-Indicates the adapter supports SSX2 in some mode setting. The
-return value is true (1) or false (0). If the current adapter
-mode is MONO SSX2 is disabled, even though this property will
-return true.
-*/
- HPI_ADAPTER_PROPERTY_SUPPORTS_SSX2 = 271,
-/** Readonly supports PCI(e) IRQ.
-Indicates that the adapter in it's current mode supports interrupts
-across the host bus. Note, this does not imply that interrupts are
-enabled. Instead it indicates that they can be enabled.
-*/
- HPI_ADAPTER_PROPERTY_SUPPORTS_IRQ = 272,
-/** Readonly supports firmware updating.
-Indicates that the adapter implements an interface to update firmware
-on the adapter.
-*/
- HPI_ADAPTER_PROPERTY_SUPPORTS_FW_UPDATE = 273,
-/** Readonly Firmware IDs
-Identifiy firmware independent of individual adapter type.
-May be used as a filter for firmware update images.
-Property 1 = Bootloader ID
-Property 2 = Main program ID
-*/
- HPI_ADAPTER_PROPERTY_FIRMWARE_ID = 274
-};
-
-/** Adapter mode commands
-
-Used in wQueryOrSet parameter of HPI_AdapterSetModeEx().
-\ingroup adapter
-*/
-enum HPI_ADAPTER_MODE_CMDS {
- /** Set the mode to the given parameter */
- HPI_ADAPTER_MODE_SET = 0,
- /** Return 0 or error depending whether mode is valid,
- but don't set the mode */
- HPI_ADAPTER_MODE_QUERY = 1
-};
-
-/** Adapter Modes
- These are used by HPI_AdapterSetModeEx()
-
-\warning - more than 16 possible modes breaks
-a bitmask in the Windows WAVE DLL
-\ingroup adapter
-*/
-enum HPI_ADAPTER_MODES {
-/** 4 outstream mode.
-- ASI6114: 1 instream
-- ASI6044: 4 instreams
-- ASI6012: 1 instream
-- ASI6102: no instreams
-- ASI6022, ASI6122: 2 instreams
-- ASI5111, ASI5101: 2 instreams
-- ASI652x, ASI662x: 2 instreams
-- ASI654x, ASI664x: 4 instreams
-*/
- HPI_ADAPTER_MODE_4OSTREAM = 1,
-
-/** 6 outstream mode.
-- ASI6012: 1 instream,
-- ASI6022, ASI6122: 2 instreams
-- ASI652x, ASI662x: 4 instreams
-*/
- HPI_ADAPTER_MODE_6OSTREAM = 2,
-
-/** 8 outstream mode.
-- ASI6114: 8 instreams
-- ASI6118: 8 instreams
-- ASI6585: 8 instreams
-*/
- HPI_ADAPTER_MODE_8OSTREAM = 3,
-
-/** 16 outstream mode.
-- ASI6416 16 instreams
-- ASI6518, ASI6618 16 instreams
-- ASI6118 16 mono out and in streams
-*/
- HPI_ADAPTER_MODE_16OSTREAM = 4,
-
-/** one outstream mode.
-- ASI5111 1 outstream, 1 instream
-*/
- HPI_ADAPTER_MODE_1OSTREAM = 5,
-
-/** ASI504X mode 1. 12 outstream, 4 instream 0 to 48kHz sample rates
- (see ASI504X datasheet for more info).
-*/
- HPI_ADAPTER_MODE_1 = 6,
-
-/** ASI504X mode 2. 4 outstreams, 4 instreams at 0 to 192kHz sample rates
- (see ASI504X datasheet for more info).
-*/
- HPI_ADAPTER_MODE_2 = 7,
-
-/** ASI504X mode 3. 4 outstreams, 4 instreams at 0 to 192kHz sample rates
- (see ASI504X datasheet for more info).
-*/
- HPI_ADAPTER_MODE_3 = 8,
-
-/** ASI504X multichannel mode.
- 2 outstreams -> 4 line outs = 1 to 8 channel streams),
- 4 lineins -> 1 instream (1 to 8 channel streams) at 0-48kHz.
- For more info see the SSX Specification.
-*/
- HPI_ADAPTER_MODE_MULTICHANNEL = 9,
-
-/** 12 outstream mode.
-- ASI6514, ASI6614: 2 instreams
-- ASI6540,ASI6544: 8 instreams
-- ASI6640,ASI6644: 8 instreams
-*/
- HPI_ADAPTER_MODE_12OSTREAM = 10,
-
-/** 9 outstream mode.
-- ASI6044: 8 instreams
-*/
- HPI_ADAPTER_MODE_9OSTREAM = 11,
-
-/** mono mode.
-- ASI6416: 16 outstreams/instreams
-- ASI5402: 2 outstreams/instreams
-*/
- HPI_ADAPTER_MODE_MONO = 12,
-
-/** Low latency mode.
-- ASI6416/ASI6316: 1 16 channel outstream and instream
-*/
- HPI_ADAPTER_MODE_LOW_LATENCY = 13
-};
-
-/* Note, adapters can have more than one capability -
-encoding as bitfield is recommended. */
-#define HPI_CAPABILITY_NONE (0)
-#define HPI_CAPABILITY_MPEG_LAYER3 (1)
-
-/* Set this equal to maximum capability index,
-Must not be greater than 32 - see axnvdef.h */
-#define HPI_CAPABILITY_MAX 1
-/* #define HPI_CAPABILITY_AAC 2 */
-
-/******************************************* STREAM ATTRIBUTES ****/
-
-/** MPEG Ancillary Data modes
-
-The mode for the ancillary data insertion or extraction to operate in.
-\ingroup stream
-*/
-enum HPI_MPEG_ANC_MODES {
- /** the MPEG frames have energy information stored in them (5 bytes per stereo frame, 3 per mono) */
- HPI_MPEG_ANC_HASENERGY = 0,
- /** the entire ancillary data field is taken up by data from the Anc data buffer
- On encode, the encoder will insert the energy bytes before filling the remainder
- of the ancillary data space with data from the ancillary data buffer.
- */
- HPI_MPEG_ANC_RAW = 1
-};
-
-/** Ancillary Data Alignment
-\ingroup instream
-*/
-enum HPI_ISTREAM_MPEG_ANC_ALIGNS {
- /** data is packed against the end of data, then padded to the end of frame */
- HPI_MPEG_ANC_ALIGN_LEFT = 0,
- /** data is packed against the end of the frame */
- HPI_MPEG_ANC_ALIGN_RIGHT = 1
-};
-
-/** MPEG modes
-MPEG modes - can be used optionally for HPI_FormatCreate()
-parameter dwAttributes.
-
-Using any mode setting other than HPI_MPEG_MODE_DEFAULT
-with single channel format will return an error.
-\ingroup stream
-*/
-enum HPI_MPEG_MODES {
-/** Causes the MPEG-1 Layer II bitstream to be recorded
-in single_channel mode when the number of channels is 1 and in stereo when the
-number of channels is 2. */
- HPI_MPEG_MODE_DEFAULT = 0,
- /** Standard stereo without joint-stereo compression */
- HPI_MPEG_MODE_STEREO = 1,
- /** Joint stereo */
- HPI_MPEG_MODE_JOINTSTEREO = 2,
- /** Left and Right channels are completely independent */
- HPI_MPEG_MODE_DUALCHANNEL = 3
-};
-/******************************************* MIXER ATTRIBUTES ****/
-
-/* \defgroup mixer_flags Mixer flags for HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES
-{
-*/
-#define HPI_MIXER_GET_CONTROL_MULTIPLE_CHANGED (0)
-#define HPI_MIXER_GET_CONTROL_MULTIPLE_RESET (1)
-/*}*/
-
-/** Commands used by HPI_MixerStore()
-\ingroup mixer
-*/
-enum HPI_MIXER_STORE_COMMAND {
-/** Save all mixer control settings. */
- HPI_MIXER_STORE_SAVE = 1,
-/** Restore all controls from saved. */
- HPI_MIXER_STORE_RESTORE = 2,
-/** Delete saved control settings. */
- HPI_MIXER_STORE_DELETE = 3,
-/** Enable auto storage of some control settings. */
- HPI_MIXER_STORE_ENABLE = 4,
-/** Disable auto storage of some control settings. */
- HPI_MIXER_STORE_DISABLE = 5,
-/** Unimplemented - save the attributes of a single control. */
- HPI_MIXER_STORE_SAVE_SINGLE = 6
-};
-
-/****************************/
-/* CONTROL ATTRIBUTE VALUES */
-/****************************/
-
-/** Used by mixer plugin enable functions
-
-E.g. HPI_ParametricEq_SetState()
-\ingroup mixer
-*/
-enum HPI_SWITCH_STATES {
- HPI_SWITCH_OFF = 0, /**< turn the mixer plugin on. */
- HPI_SWITCH_ON = 1 /**< turn the mixer plugin off. */
-};
-
-/* Volume control special gain values */
-
-/** volumes units are 100ths of a dB
-\ingroup volume
-*/
-#define HPI_UNITS_PER_dB 100
-/** turns volume control OFF or MUTE
-\ingroup volume
-*/
-#define HPI_GAIN_OFF (-100 * HPI_UNITS_PER_dB)
-
-/** channel mask specifying all channels
-\ingroup volume
-*/
-#define HPI_BITMASK_ALL_CHANNELS (0xFFFFFFFF)
-
-/** value returned for no signal
-\ingroup meter
-*/
-#define HPI_METER_MINIMUM (-150 * HPI_UNITS_PER_dB)
-
-/** autofade profiles
-\ingroup volume
-*/
-enum HPI_VOLUME_AUTOFADES {
-/** log fade - dB attenuation changes linearly over time */
- HPI_VOLUME_AUTOFADE_LOG = 2,
-/** linear fade - amplitude changes linearly */
- HPI_VOLUME_AUTOFADE_LINEAR = 3
-};
-
-/** The physical encoding format of the AESEBU I/O.
-
-Used in HPI_Aesebu_Transmitter_SetFormat(), HPI_Aesebu_Receiver_SetFormat()
-along with related Get and Query functions
-\ingroup aestx
-*/
-enum HPI_AESEBU_FORMATS {
-/** AES/EBU physical format - AES/EBU balanced "professional" */
- HPI_AESEBU_FORMAT_AESEBU = 1,
-/** AES/EBU physical format - S/PDIF unbalanced "consumer" */
- HPI_AESEBU_FORMAT_SPDIF = 2
-};
-
-/** AES/EBU error status bits
-
-Returned by HPI_Aesebu_Receiver_GetErrorStatus()
-\ingroup aesrx
-*/
-enum HPI_AESEBU_ERRORS {
-/** bit0: 1 when PLL is not locked */
- HPI_AESEBU_ERROR_NOT_LOCKED = 0x01,
-/** bit1: 1 when signal quality is poor */
- HPI_AESEBU_ERROR_POOR_QUALITY = 0x02,
-/** bit2: 1 when there is a parity error */
- HPI_AESEBU_ERROR_PARITY_ERROR = 0x04,
-/** bit3: 1 when there is a bi-phase coding violation */
- HPI_AESEBU_ERROR_BIPHASE_VIOLATION = 0x08,
-/** bit4: 1 when the validity bit is high */
- HPI_AESEBU_ERROR_VALIDITY = 0x10,
-/** bit5: 1 when the CRC error bit is high */
- HPI_AESEBU_ERROR_CRC = 0x20
-};
-
-/** \addtogroup pad
-\{
-*/
-/** The text string containing the station/channel combination. */
-#define HPI_PAD_CHANNEL_NAME_LEN 16
-/** The text string containing the artist. */
-#define HPI_PAD_ARTIST_LEN 64
-/** The text string containing the title. */
-#define HPI_PAD_TITLE_LEN 64
-/** The text string containing the comment. */
-#define HPI_PAD_COMMENT_LEN 256
-/** The PTY when the tuner has not received any PTY. */
-#define HPI_PAD_PROGRAM_TYPE_INVALID 0xffff
-/** \} */
-
-/** Data types for PTY string translation.
-\ingroup rds
-*/
-enum eHPI_RDS_type {
- HPI_RDS_DATATYPE_RDS = 0, /**< RDS bitstream.*/
- HPI_RDS_DATATYPE_RBDS = 1 /**< RBDS bitstream.*/
-};
-
-/** Tuner bands
-
-Used for HPI_Tuner_SetBand(),HPI_Tuner_GetBand()
-\ingroup tuner
-*/
-enum HPI_TUNER_BAND {
- HPI_TUNER_BAND_AM = 1, /**< AM band */
- HPI_TUNER_BAND_FM = 2, /**< FM band (mono) */
- HPI_TUNER_BAND_TV_NTSC_M = 3, /**< NTSC-M TV band*/
- HPI_TUNER_BAND_TV = 3, /* use TV_NTSC_M */
- HPI_TUNER_BAND_FM_STEREO = 4, /**< FM band (stereo) */
- HPI_TUNER_BAND_AUX = 5, /**< auxiliary input */
- HPI_TUNER_BAND_TV_PAL_BG = 6, /**< PAL-B/G TV band*/
- HPI_TUNER_BAND_TV_PAL_I = 7, /**< PAL-I TV band*/
- HPI_TUNER_BAND_TV_PAL_DK = 8, /**< PAL-D/K TV band*/
- HPI_TUNER_BAND_TV_SECAM_L = 9, /**< SECAM-L TV band*/
- HPI_TUNER_BAND_LAST = 9 /**< the index of the last tuner band. */
-};
-
-/** Tuner mode attributes
-
-Used by HPI_Tuner_SetMode(), HPI_Tuner_GetMode()
-\ingroup tuner
-
-*/
-enum HPI_TUNER_MODES {
- HPI_TUNER_MODE_RSS = 1, /**< control RSS */
- HPI_TUNER_MODE_RDS = 2 /**< control RBDS/RDS */
-};
-
-/** Tuner mode attribute values
-
-Used by HPI_Tuner_SetMode(), HPI_Tuner_GetMode()
-\ingroup tuner
-*/
-enum HPI_TUNER_MODE_VALUES {
-/* RSS attribute values */
- HPI_TUNER_MODE_RSS_DISABLE = 0, /**< RSS disable */
- HPI_TUNER_MODE_RSS_ENABLE = 1, /**< RSS enable */
-
-/* RDS mode attributes */
- HPI_TUNER_MODE_RDS_DISABLE = 0, /**< RDS - disabled */
- HPI_TUNER_MODE_RDS_RDS = 1, /**< RDS - RDS mode */
- HPI_TUNER_MODE_RDS_RBDS = 2 /**< RDS - RBDS mode */
-};
-
-/** Tuner Status Bits
-
-These bitfield values are returned by a call to HPI_Tuner_GetStatus().
-Multiple fields are returned from a single call.
-\ingroup tuner
-*/
-enum HPI_TUNER_STATUS_BITS {
- HPI_TUNER_VIDEO_COLOR_PRESENT = 0x0001, /**< video color is present. */
- HPI_TUNER_VIDEO_IS_60HZ = 0x0020, /**< 60 hz video detected. */
- HPI_TUNER_VIDEO_HORZ_SYNC_MISSING = 0x0040, /**< video HSYNC is missing. */
- HPI_TUNER_VIDEO_STATUS_VALID = 0x0100, /**< video status is valid. */
- HPI_TUNER_DIGITAL = 0x0200, /**< tuner reports digital programming. */
- HPI_TUNER_MULTIPROGRAM = 0x0400, /**< tuner reports multiple programs. */
- HPI_TUNER_PLL_LOCKED = 0x1000, /**< the tuner's PLL is locked. */
- HPI_TUNER_FM_STEREO = 0x2000 /**< tuner reports back FM stereo. */
-};
-
-/** Channel Modes
-Used for HPI_ChannelModeSet/Get()
-\ingroup channelmode
-*/
-enum HPI_CHANNEL_MODES {
-/** Left channel out = left channel in, Right channel out = right channel in. */
- HPI_CHANNEL_MODE_NORMAL = 1,
-/** Left channel out = right channel in, Right channel out = left channel in. */
- HPI_CHANNEL_MODE_SWAP = 2,
-/** Left channel out = left channel in, Right channel out = left channel in. */
- HPI_CHANNEL_MODE_LEFT_TO_STEREO = 3,
-/** Left channel out = right channel in, Right channel out = right channel in.*/
- HPI_CHANNEL_MODE_RIGHT_TO_STEREO = 4,
-/** Left channel out = (left channel in + right channel in)/2,
- Right channel out = mute. */
- HPI_CHANNEL_MODE_STEREO_TO_LEFT = 5,
-/** Left channel out = mute,
- Right channel out = (right channel in + left channel in)/2. */
- HPI_CHANNEL_MODE_STEREO_TO_RIGHT = 6,
- HPI_CHANNEL_MODE_LAST = 6
-};
-
-/** SampleClock source values
-\ingroup sampleclock
-*/
-enum HPI_SAMPLECLOCK_SOURCES {
-/** The sampleclock output is derived from its local samplerate generator.
- The local samplerate may be set using HPI_SampleClock_SetLocalRate(). */
- HPI_SAMPLECLOCK_SOURCE_LOCAL = 1,
-/** The adapter is clocked from a dedicated AES/EBU SampleClock input.*/
- HPI_SAMPLECLOCK_SOURCE_AESEBU_SYNC = 2,
-/** From external wordclock connector */
- HPI_SAMPLECLOCK_SOURCE_WORD = 3,
-/** Board-to-board header */
- HPI_SAMPLECLOCK_SOURCE_WORD_HEADER = 4,
-/** FUTURE - SMPTE clock. */
- HPI_SAMPLECLOCK_SOURCE_SMPTE = 5,
-/** One of the aesebu inputs */
- HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT = 6,
-/** From a network interface e.g. Cobranet or Livewire at either 48 or 96kHz */
- HPI_SAMPLECLOCK_SOURCE_NETWORK = 8,
-/** From previous adjacent module (ASI2416 only)*/
- HPI_SAMPLECLOCK_SOURCE_PREV_MODULE = 10,
-/*! Update this if you add a new clock source.*/
- HPI_SAMPLECLOCK_SOURCE_LAST = 10
-};
-
-/** Equalizer filter types. Used by HPI_ParametricEq_SetBand()
-\ingroup parmeq
-*/
-enum HPI_FILTER_TYPE {
- HPI_FILTER_TYPE_BYPASS = 0, /**< filter is turned off */
-
- HPI_FILTER_TYPE_LOWSHELF = 1, /**< EQ low shelf */
- HPI_FILTER_TYPE_HIGHSHELF = 2, /**< EQ high shelf */
- HPI_FILTER_TYPE_EQ_BAND = 3, /**< EQ gain */
-
- HPI_FILTER_TYPE_LOWPASS = 4, /**< standard low pass */
- HPI_FILTER_TYPE_HIGHPASS = 5, /**< standard high pass */
- HPI_FILTER_TYPE_BANDPASS = 6, /**< standard band pass */
- HPI_FILTER_TYPE_BANDSTOP = 7 /**< standard band stop/notch */
-};
-
-/** Async Event sources
-\ingroup async
-*/
-enum ASYNC_EVENT_SOURCES {
- HPI_ASYNC_EVENT_GPIO = 1, /**< GPIO event. */
- HPI_ASYNC_EVENT_SILENCE = 2, /**< silence event detected. */
- HPI_ASYNC_EVENT_TONE = 3 /**< tone event detected. */
-};
-/*******************************************/
-/** HPI Error codes
-
-Almost all HPI functions return an error code
-A return value of zero means there was no error.
-Otherwise one of these error codes is returned.
-Error codes can be converted to a descriptive string using HPI_GetErrorText()
-
-\note When a new error code is added HPI_GetErrorText() MUST be updated.
-\note Codes 1-100 are reserved for driver use
-\ingroup utility
-*/
-enum HPI_ERROR_CODES {
- /** Message type does not exist. */
- HPI_ERROR_INVALID_TYPE = 100,
- /** Object type does not exist. */
- HPI_ERROR_INVALID_OBJ = 101,
- /** Function does not exist. */
- HPI_ERROR_INVALID_FUNC = 102,
- /** The specified object does not exist. */
- HPI_ERROR_INVALID_OBJ_INDEX = 103,
- /** Trying to access an object that has not been opened yet. */
- HPI_ERROR_OBJ_NOT_OPEN = 104,
- /** Trying to open an already open object. */
- HPI_ERROR_OBJ_ALREADY_OPEN = 105,
- /** PCI, ISA resource not valid. */
- HPI_ERROR_INVALID_RESOURCE = 106,
- /* HPI_ERROR_SUBSYSFINDADAPTERS_GETINFO= 107 */
- /** Default response was never updated with actual error code. */
- HPI_ERROR_INVALID_RESPONSE = 108,
- /** wSize field of response was not updated,
- indicating that the message was not processed. */
- HPI_ERROR_PROCESSING_MESSAGE = 109,
- /** The network did not respond in a timely manner. */
- HPI_ERROR_NETWORK_TIMEOUT = 110,
- /* An HPI handle is invalid (uninitialised?). */
- HPI_ERROR_INVALID_HANDLE = 111,
- /** A function or attribute has not been implemented yet. */
- HPI_ERROR_UNIMPLEMENTED = 112,
- /** There are too many clients attempting
- to access a network resource. */
- HPI_ERROR_NETWORK_TOO_MANY_CLIENTS = 113,
- /** Response buffer passed to HPI_Message
- was smaller than returned response.
- wSpecificError field of hpi response contains the required size.
- */
- HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL = 114,
- /** The returned response did not match the sent message */
- HPI_ERROR_RESPONSE_MISMATCH = 115,
- /** A control setting that should have been cached was not. */
- HPI_ERROR_CONTROL_CACHING = 116,
- /** A message buffer in the path to the adapter was smaller
- than the message size.
- wSpecificError field of hpi response contains the actual size.
- */
- HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL = 117,
-
- /* HPI_ERROR_TOO_MANY_ADAPTERS= 200 */
- /** Bad adpater. */
- HPI_ERROR_BAD_ADAPTER = 201,
- /** Adapter number out of range or not set properly. */
- HPI_ERROR_BAD_ADAPTER_NUMBER = 202,
- /** 2 adapters with the same adapter number. */
- HPI_ERROR_DUPLICATE_ADAPTER_NUMBER = 203,
- /** DSP code failed to bootload. Usually a DSP memory test failure. */
- HPI_ERROR_DSP_BOOTLOAD = 204,
- /** Couldn't find or open the DSP code file. */
- HPI_ERROR_DSP_FILE_NOT_FOUND = 206,
- /** Internal DSP hardware error. */
- HPI_ERROR_DSP_HARDWARE = 207,
- /** Could not allocate memory */
- HPI_ERROR_MEMORY_ALLOC = 208,
- /** Failed to correctly load/config PLD. (unused) */
- HPI_ERROR_PLD_LOAD = 209,
- /** Unexpected end of file, block length too big etc. */
- HPI_ERROR_DSP_FILE_FORMAT = 210,
-
- /** Found but could not open DSP code file. */
- HPI_ERROR_DSP_FILE_ACCESS_DENIED = 211,
- /** First DSP code section header not found in DSP file. */
- HPI_ERROR_DSP_FILE_NO_HEADER = 212,
- /* HPI_ERROR_DSP_FILE_READ_ERROR= 213, */
- /** DSP code for adapter family not found. */
- HPI_ERROR_DSP_SECTION_NOT_FOUND = 214,
- /** Other OS specific error opening DSP file. */
- HPI_ERROR_DSP_FILE_OTHER_ERROR = 215,
- /** Sharing violation opening DSP code file. */
- HPI_ERROR_DSP_FILE_SHARING_VIOLATION = 216,
- /** DSP code section header had size == 0. */
- HPI_ERROR_DSP_FILE_NULL_HEADER = 217,
-
- /* HPI_ERROR_FLASH = 220, */
-
- /** Flash has bad checksum */
- HPI_ERROR_BAD_CHECKSUM = 221,
- HPI_ERROR_BAD_SEQUENCE = 222,
- HPI_ERROR_FLASH_ERASE = 223,
- HPI_ERROR_FLASH_PROGRAM = 224,
- HPI_ERROR_FLASH_VERIFY = 225,
- HPI_ERROR_FLASH_TYPE = 226,
- HPI_ERROR_FLASH_START = 227,
- HPI_ERROR_FLASH_READ = 228,
- HPI_ERROR_FLASH_READ_NO_FILE = 229,
- HPI_ERROR_FLASH_SIZE = 230,
-
- /** Reserved for OEMs. */
- HPI_ERROR_RESERVED_1 = 290,
-
- /* HPI_ERROR_INVALID_STREAM = 300 use HPI_ERROR_INVALID_OBJ_INDEX */
- /** Invalid compression format. */
- HPI_ERROR_INVALID_FORMAT = 301,
- /** Invalid format samplerate */
- HPI_ERROR_INVALID_SAMPLERATE = 302,
- /** Invalid format number of channels. */
- HPI_ERROR_INVALID_CHANNELS = 303,
- /** Invalid format bitrate. */
- HPI_ERROR_INVALID_BITRATE = 304,
- /** Invalid datasize used for stream read/write. */
- HPI_ERROR_INVALID_DATASIZE = 305,
- /* HPI_ERROR_BUFFER_FULL = 306 use HPI_ERROR_INVALID_DATASIZE */
- /* HPI_ERROR_BUFFER_EMPTY = 307 use HPI_ERROR_INVALID_DATASIZE */
- /** Null data pointer used for stream read/write. */
- HPI_ERROR_INVALID_DATA_POINTER = 308,
- /** Packet ordering error for stream read/write. */
- HPI_ERROR_INVALID_PACKET_ORDER = 309,
-
- /** Object can't do requested operation in its current
- state, eg set format, change rec mux state while recording.*/
- HPI_ERROR_INVALID_OPERATION = 310,
-
- /** Where a SRG is shared amongst streams, an incompatible samplerate
- is one that is different to any currently active stream. */
- HPI_ERROR_INCOMPATIBLE_SAMPLERATE = 311,
- /** Adapter mode is illegal.*/
- HPI_ERROR_BAD_ADAPTER_MODE = 312,
-
- /** There have been too many attempts to set the adapter's
- capabilities (using bad keys), the card should be returned
- to ASI if further capabilities updates are required */
- HPI_ERROR_TOO_MANY_CAPABILITY_CHANGE_ATTEMPTS = 313,
- /** Streams on different adapters cannot be grouped. */
- HPI_ERROR_NO_INTERADAPTER_GROUPS = 314,
- /** Streams on different DSPs cannot be grouped. */
- HPI_ERROR_NO_INTERDSP_GROUPS = 315,
- /** Stream wait cancelled before threshold reached. */
- HPI_ERROR_WAIT_CANCELLED = 316,
- /** A character string is invalid. */
- HPI_ERROR_INVALID_STRING = 317,
-
- /** Invalid mixer node for this adapter. */
- HPI_ERROR_INVALID_NODE = 400,
- /** Invalid control. */
- HPI_ERROR_INVALID_CONTROL = 401,
- /** Invalid control value was passed. */
- HPI_ERROR_INVALID_CONTROL_VALUE = 402,
- /** Control attribute not supported by this control. */
- HPI_ERROR_INVALID_CONTROL_ATTRIBUTE = 403,
- /** Control is disabled. */
- HPI_ERROR_CONTROL_DISABLED = 404,
- /** I2C transaction failed due to a missing ACK. */
- HPI_ERROR_CONTROL_I2C_MISSING_ACK = 405,
- HPI_ERROR_I2C_MISSING_ACK = 405,
- /** Control is busy, or coming out of
- reset and cannot be accessed at this time. */
- HPI_ERROR_CONTROL_NOT_READY = 407,
-
- /** Non volatile memory */
- HPI_ERROR_NVMEM_BUSY = 450,
- HPI_ERROR_NVMEM_FULL = 451,
- HPI_ERROR_NVMEM_FAIL = 452,
-
- /** I2C */
- HPI_ERROR_I2C_BAD_ADR = 460,
-
- /** Entity type did not match requested type */
- HPI_ERROR_ENTITY_TYPE_MISMATCH = 470,
- /** Entity item count did not match requested count */
- HPI_ERROR_ENTITY_ITEM_COUNT = 471,
- /** Entity type is not one of the valid types */
- HPI_ERROR_ENTITY_TYPE_INVALID = 472,
- /** Entity role is not one of the valid roles */
- HPI_ERROR_ENTITY_ROLE_INVALID = 473,
- /** Entity size doesn't match target size */
- HPI_ERROR_ENTITY_SIZE_MISMATCH = 474,
-
- /* AES18 specific errors were 500..507 */
-
- /** custom error to use for debugging */
- HPI_ERROR_CUSTOM = 600,
-
- /** hpioct32.c can't obtain mutex */
- HPI_ERROR_MUTEX_TIMEOUT = 700,
-
- /** Backend errors used to be greater than this.
- \deprecated Now, all backends return only errors defined here in hpi.h
- */
- HPI_ERROR_BACKEND_BASE = 900,
-
- /** Communication with DSP failed */
- HPI_ERROR_DSP_COMMUNICATION = 900
- /* Note that the dsp communication error is set to this value so that
- it remains compatible with any software that expects such errors
- to be backend errors i.e. >= 900.
- Do not define any new error codes with values > 900.
- */
-};
-
-/** \defgroup maximums HPI maximum values
-\{
-*/
-/** Maximum number of PCI HPI adapters */
-#define HPI_MAX_ADAPTERS 20
-/** Maximum number of in or out streams per adapter */
-#define HPI_MAX_STREAMS 16
-#define HPI_MAX_CHANNELS 2 /* per stream */
-#define HPI_MAX_NODES 8 /* per mixer ? */
-#define HPI_MAX_CONTROLS 4 /* per node ? */
-/** maximum number of ancillary bytes per MPEG frame */
-#define HPI_MAX_ANC_BYTES_PER_FRAME (64)
-#define HPI_STRING_LEN 16
-
-/** Networked adapters have index >= 100 */
-#define HPI_MIN_NETWORK_ADAPTER_IDX 100
-
-/** Velocity units */
-#define HPI_OSTREAM_VELOCITY_UNITS 4096
-/** OutStream timescale units */
-#define HPI_OSTREAM_TIMESCALE_UNITS 10000
-/** OutStream timescale passthrough - turns timescaling on in passthough mode */
-#define HPI_OSTREAM_TIMESCALE_PASSTHROUGH 99999
-
-/**\}*/
-
-/**************/
-/* STRUCTURES */
-#ifndef DISABLE_PRAGMA_PACK1
-#pragma pack(push, 1)
-#endif
-
-/** Structure containing sample format information.
- See also HPI_FormatCreate().
- */
-struct hpi_format {
- u32 sample_rate;
- /**< 11025, 32000, 44100 ... */
- u32 bit_rate; /**< for MPEG */
- u32 attributes;
- /**< Stereo/JointStereo/Mono */
- u16 mode_legacy;
- /**< Legacy ancillary mode or idle bit */
- u16 unused; /**< Unused */
- u16 channels; /**< 1,2..., (or ancillary mode or idle bit */
- u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see #HPI_FORMATS. */
-};
-
-struct hpi_anc_frame {
- u32 valid_bits_in_this_frame;
- u8 b_data[HPI_MAX_ANC_BYTES_PER_FRAME];
-};
-
-/** An object for containing a single async event.
-*/
-struct hpi_async_event {
- u16 event_type; /**< type of event. \sa async_event */
- u16 sequence; /**< Sequence number, allows lost event detection */
- u32 state; /**< New state */
- u32 h_object; /**< handle to the object returning the event. */
- union {
- struct {
- u16 index; /**< GPIO bit index. */
- } gpio;
- struct {
- u16 node_index; /**< what node is the control on ? */
- u16 node_type; /**< what type of node is the control on ? */
- } control;
- } u;
-};
-
-#ifndef DISABLE_PRAGMA_PACK1
-#pragma pack(pop)
-#endif
-
-/*****************/
-/* HPI FUNCTIONS */
-/*****************/
-
-/* Stream */
-u16 hpi_stream_estimate_buffer_size(struct hpi_format *pF,
- u32 host_polling_rate_in_milli_seconds, u32 *recommended_buffer_size);
-
-/*************/
-/* SubSystem */
-/*************/
-
-u16 hpi_subsys_get_version_ex(u32 *pversion_ex);
-
-u16 hpi_subsys_get_num_adapters(int *pn_num_adapters);
-
-u16 hpi_subsys_get_adapter(int iterator, u32 *padapter_index,
- u16 *pw_adapter_type);
-
-/***********/
-/* Adapter */
-/***********/
-
-u16 hpi_adapter_open(u16 adapter_index);
-
-u16 hpi_adapter_close(u16 adapter_index);
-
-u16 hpi_adapter_get_info(u16 adapter_index, u16 *pw_num_outstreams,
- u16 *pw_num_instreams, u16 *pw_version, u32 *pserial_number,
- u16 *pw_adapter_type);
-
-u16 hpi_adapter_get_module_by_index(u16 adapter_index, u16 module_index,
- u16 *pw_num_outputs, u16 *pw_num_inputs, u16 *pw_version,
- u32 *pserial_number, u16 *pw_module_type, u32 *ph_module);
-
-u16 hpi_adapter_set_mode(u16 adapter_index, u32 adapter_mode);
-
-u16 hpi_adapter_set_mode_ex(u16 adapter_index, u32 adapter_mode,
- u16 query_or_set);
-
-u16 hpi_adapter_get_mode(u16 adapter_index, u32 *padapter_mode);
-
-u16 hpi_adapter_get_assert2(u16 adapter_index, u16 *p_assert_count,
- char *psz_assert, u32 *p_param1, u32 *p_param2,
- u32 *p_dsp_string_addr, u16 *p_processor_id);
-
-u16 hpi_adapter_test_assert(u16 adapter_index, u16 assert_id);
-
-u16 hpi_adapter_enable_capability(u16 adapter_index, u16 capability, u32 key);
-
-u16 hpi_adapter_self_test(u16 adapter_index);
-
-u16 hpi_adapter_debug_read(u16 adapter_index, u32 dsp_address, char *p_bytes,
- int *count_bytes);
-
-u16 hpi_adapter_set_property(u16 adapter_index, u16 property, u16 paramter1,
- u16 paramter2);
-
-u16 hpi_adapter_get_property(u16 adapter_index, u16 property,
- u16 *pw_paramter1, u16 *pw_paramter2);
-
-u16 hpi_adapter_enumerate_property(u16 adapter_index, u16 index,
- u16 what_to_enumerate, u16 property_index, u32 *psetting);
-/*************/
-/* OutStream */
-/*************/
-u16 hpi_outstream_open(u16 adapter_index, u16 outstream_index,
- u32 *ph_outstream);
-
-u16 hpi_outstream_close(u32 h_outstream);
-
-u16 hpi_outstream_get_info_ex(u32 h_outstream, u16 *pw_state,
- u32 *pbuffer_size, u32 *pdata_to_play, u32 *psamples_played,
- u32 *pauxiliary_data_to_play);
-
-u16 hpi_outstream_write_buf(u32 h_outstream, const u8 *pb_write_buf,
- u32 bytes_to_write, const struct hpi_format *p_format);
-
-u16 hpi_outstream_start(u32 h_outstream);
-
-u16 hpi_outstream_wait_start(u32 h_outstream);
-
-u16 hpi_outstream_stop(u32 h_outstream);
-
-u16 hpi_outstream_sinegen(u32 h_outstream);
-
-u16 hpi_outstream_reset(u32 h_outstream);
-
-u16 hpi_outstream_query_format(u32 h_outstream, struct hpi_format *p_format);
-
-u16 hpi_outstream_set_format(u32 h_outstream, struct hpi_format *p_format);
-
-u16 hpi_outstream_set_punch_in_out(u32 h_outstream, u32 punch_in_sample,
- u32 punch_out_sample);
-
-u16 hpi_outstream_set_velocity(u32 h_outstream, short velocity);
-
-u16 hpi_outstream_ancillary_reset(u32 h_outstream, u16 mode);
-
-u16 hpi_outstream_ancillary_get_info(u32 h_outstream, u32 *pframes_available);
-
-u16 hpi_outstream_ancillary_read(u32 h_outstream,
- struct hpi_anc_frame *p_anc_frame_buffer,
- u32 anc_frame_buffer_size_in_bytes,
- u32 number_of_ancillary_frames_to_read);
-
-u16 hpi_outstream_set_time_scale(u32 h_outstream, u32 time_scaleX10000);
-
-u16 hpi_outstream_host_buffer_allocate(u32 h_outstream, u32 size_in_bytes);
-
-u16 hpi_outstream_host_buffer_free(u32 h_outstream);
-
-u16 hpi_outstream_group_add(u32 h_outstream, u32 h_stream);
-
-u16 hpi_outstream_group_get_map(u32 h_outstream, u32 *poutstream_map,
- u32 *pinstream_map);
-
-u16 hpi_outstream_group_reset(u32 h_outstream);
-
-/************/
-/* InStream */
-/************/
-u16 hpi_instream_open(u16 adapter_index, u16 instream_index,
- u32 *ph_instream);
-
-u16 hpi_instream_close(u32 h_instream);
-
-u16 hpi_instream_query_format(u32 h_instream,
- const struct hpi_format *p_format);
-
-u16 hpi_instream_set_format(u32 h_instream,
- const struct hpi_format *p_format);
-
-u16 hpi_instream_read_buf(u32 h_instream, u8 *pb_read_buf, u32 bytes_to_read);
-
-u16 hpi_instream_start(u32 h_instream);
-
-u16 hpi_instream_wait_start(u32 h_instream);
-
-u16 hpi_instream_stop(u32 h_instream);
-
-u16 hpi_instream_reset(u32 h_instream);
-
-u16 hpi_instream_get_info_ex(u32 h_instream, u16 *pw_state, u32 *pbuffer_size,
- u32 *pdata_recorded, u32 *psamples_recorded,
- u32 *pauxiliary_data_recorded);
-
-u16 hpi_instream_ancillary_reset(u32 h_instream, u16 bytes_per_frame,
- u16 mode, u16 alignment, u16 idle_bit);
-
-u16 hpi_instream_ancillary_get_info(u32 h_instream, u32 *pframe_space);
-
-u16 hpi_instream_ancillary_write(u32 h_instream,
- const struct hpi_anc_frame *p_anc_frame_buffer,
- u32 anc_frame_buffer_size_in_bytes,
- u32 number_of_ancillary_frames_to_write);
-
-u16 hpi_instream_host_buffer_allocate(u32 h_instream, u32 size_in_bytes);
-
-u16 hpi_instream_host_buffer_free(u32 h_instream);
-
-u16 hpi_instream_group_add(u32 h_instream, u32 h_stream);
-
-u16 hpi_instream_group_get_map(u32 h_instream, u32 *poutstream_map,
- u32 *pinstream_map);
-
-u16 hpi_instream_group_reset(u32 h_instream);
-
-/*********/
-/* Mixer */
-/*********/
-u16 hpi_mixer_open(u16 adapter_index, u32 *ph_mixer);
-
-u16 hpi_mixer_close(u32 h_mixer);
-
-u16 hpi_mixer_get_control(u32 h_mixer, u16 src_node_type,
- u16 src_node_type_index, u16 dst_node_type, u16 dst_node_type_index,
- u16 control_type, u32 *ph_control);
-
-u16 hpi_mixer_get_control_by_index(u32 h_mixer, u16 control_index,
- u16 *pw_src_node_type, u16 *pw_src_node_index, u16 *pw_dst_node_type,
- u16 *pw_dst_node_index, u16 *pw_control_type, u32 *ph_control);
-
-u16 hpi_mixer_store(u32 h_mixer, enum HPI_MIXER_STORE_COMMAND command,
- u16 index);
-/************/
-/* Controls */
-/************/
-/******************/
-/* Volume control */
-/******************/
-u16 hpi_volume_set_gain(u32 h_control, short an_gain0_01dB[HPI_MAX_CHANNELS]
- );
-
-u16 hpi_volume_get_gain(u32 h_control,
- short an_gain0_01dB_out[HPI_MAX_CHANNELS]
- );
-
-u16 hpi_volume_set_mute(u32 h_control, u32 mute);
-
-u16 hpi_volume_get_mute(u32 h_control, u32 *mute);
-
-#define hpi_volume_get_range hpi_volume_query_range
-u16 hpi_volume_query_range(u32 h_control, short *min_gain_01dB,
- short *max_gain_01dB, short *step_gain_01dB);
-
-u16 hpi_volume_query_channels(const u32 h_control, u32 *p_channels);
-
-u16 hpi_volume_auto_fade(u32 h_control,
- short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms);
-
-u16 hpi_volume_auto_fade_profile(u32 h_control,
- short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms,
- u16 profile);
-
-u16 hpi_volume_query_auto_fade_profile(const u32 h_control, const u32 i,
- u16 *profile);
-
-/*****************/
-/* Level control */
-/*****************/
-u16 hpi_level_query_range(u32 h_control, short *min_gain_01dB,
- short *max_gain_01dB, short *step_gain_01dB);
-
-u16 hpi_level_set_gain(u32 h_control, short an_gain0_01dB[HPI_MAX_CHANNELS]
- );
-
-u16 hpi_level_get_gain(u32 h_control,
- short an_gain0_01dB_out[HPI_MAX_CHANNELS]
- );
-
-/*****************/
-/* Meter control */
-/*****************/
-u16 hpi_meter_query_channels(const u32 h_meter, u32 *p_channels);
-
-u16 hpi_meter_get_peak(u32 h_control,
- short an_peak0_01dB_out[HPI_MAX_CHANNELS]
- );
-
-u16 hpi_meter_get_rms(u32 h_control, short an_peak0_01dB_out[HPI_MAX_CHANNELS]
- );
-
-u16 hpi_meter_set_peak_ballistics(u32 h_control, u16 attack, u16 decay);
-
-u16 hpi_meter_set_rms_ballistics(u32 h_control, u16 attack, u16 decay);
-
-u16 hpi_meter_get_peak_ballistics(u32 h_control, u16 *attack, u16 *decay);
-
-u16 hpi_meter_get_rms_ballistics(u32 h_control, u16 *attack, u16 *decay);
-
-/************************/
-/* ChannelMode control */
-/************************/
-u16 hpi_channel_mode_query_mode(const u32 h_mode, const u32 index,
- u16 *pw_mode);
-
-u16 hpi_channel_mode_set(u32 h_control, u16 mode);
-
-u16 hpi_channel_mode_get(u32 h_control, u16 *mode);
-
-/*****************/
-/* Tuner control */
-/*****************/
-u16 hpi_tuner_query_band(const u32 h_tuner, const u32 index, u16 *pw_band);
-
-u16 hpi_tuner_set_band(u32 h_control, u16 band);
-
-u16 hpi_tuner_get_band(u32 h_control, u16 *pw_band);
-
-u16 hpi_tuner_query_frequency(const u32 h_tuner, const u32 index,
- const u16 band, u32 *pfreq);
-
-u16 hpi_tuner_set_frequency(u32 h_control, u32 freq_ink_hz);
-
-u16 hpi_tuner_get_frequency(u32 h_control, u32 *pw_freq_ink_hz);
-
-u16 hpi_tuner_get_rf_level(u32 h_control, short *pw_level);
-
-u16 hpi_tuner_get_raw_rf_level(u32 h_control, short *pw_level);
-
-u16 hpi_tuner_query_gain(const u32 h_tuner, const u32 index, u16 *pw_gain);
-
-u16 hpi_tuner_set_gain(u32 h_control, short gain);
-
-u16 hpi_tuner_get_gain(u32 h_control, short *pn_gain);
-
-u16 hpi_tuner_get_status(u32 h_control, u16 *pw_status_mask, u16 *pw_status);
-
-u16 hpi_tuner_set_mode(u32 h_control, u32 mode, u32 value);
-
-u16 hpi_tuner_get_mode(u32 h_control, u32 mode, u32 *pn_value);
-
-u16 hpi_tuner_get_rds(u32 h_control, char *p_rds_data);
-
-u16 hpi_tuner_query_deemphasis(const u32 h_tuner, const u32 index,
- const u16 band, u32 *pdeemphasis);
-
-u16 hpi_tuner_set_deemphasis(u32 h_control, u32 deemphasis);
-u16 hpi_tuner_get_deemphasis(u32 h_control, u32 *pdeemphasis);
-
-u16 hpi_tuner_query_program(const u32 h_tuner, u32 *pbitmap_program);
-
-u16 hpi_tuner_set_program(u32 h_control, u32 program);
-
-u16 hpi_tuner_get_program(u32 h_control, u32 *pprogram);
-
-u16 hpi_tuner_get_hd_radio_dsp_version(u32 h_control, char *psz_dsp_version,
- const u32 string_size);
-
-u16 hpi_tuner_get_hd_radio_sdk_version(u32 h_control, char *psz_sdk_version,
- const u32 string_size);
-
-u16 hpi_tuner_get_hd_radio_signal_quality(u32 h_control, u32 *pquality);
-
-u16 hpi_tuner_get_hd_radio_signal_blend(u32 h_control, u32 *pblend);
-
-u16 hpi_tuner_set_hd_radio_signal_blend(u32 h_control, const u32 blend);
-
-/***************/
-/* PAD control */
-/***************/
-
-u16 hpi_pad_get_channel_name(u32 h_control, char *psz_string,
- const u32 string_length);
-
-u16 hpi_pad_get_artist(u32 h_control, char *psz_string,
- const u32 string_length);
-
-u16 hpi_pad_get_title(u32 h_control, char *psz_string,
- const u32 string_length);
-
-u16 hpi_pad_get_comment(u32 h_control, char *psz_string,
- const u32 string_length);
-
-u16 hpi_pad_get_program_type(u32 h_control, u32 *ppTY);
-
-u16 hpi_pad_get_rdsPI(u32 h_control, u32 *ppI);
-
-u16 hpi_pad_get_program_type_string(u32 h_control, const u32 data_type,
- const u32 pTY, char *psz_string, const u32 string_length);
-
-/****************************/
-/* AES/EBU Receiver control */
-/****************************/
-u16 hpi_aesebu_receiver_query_format(const u32 h_aes_rx, const u32 index,
- u16 *pw_format);
-
-u16 hpi_aesebu_receiver_set_format(u32 h_control, u16 source);
-
-u16 hpi_aesebu_receiver_get_format(u32 h_control, u16 *pw_source);
-
-u16 hpi_aesebu_receiver_get_sample_rate(u32 h_control, u32 *psample_rate);
-
-u16 hpi_aesebu_receiver_get_user_data(u32 h_control, u16 index, u16 *pw_data);
-
-u16 hpi_aesebu_receiver_get_channel_status(u32 h_control, u16 index,
- u16 *pw_data);
-
-u16 hpi_aesebu_receiver_get_error_status(u32 h_control, u16 *pw_error_data);
-
-/*******************************/
-/* AES/EBU Transmitter control */
-/*******************************/
-u16 hpi_aesebu_transmitter_set_sample_rate(u32 h_control, u32 sample_rate);
-
-u16 hpi_aesebu_transmitter_set_user_data(u32 h_control, u16 index, u16 data);
-
-u16 hpi_aesebu_transmitter_set_channel_status(u32 h_control, u16 index,
- u16 data);
-
-u16 hpi_aesebu_transmitter_get_channel_status(u32 h_control, u16 index,
- u16 *pw_data);
-
-u16 hpi_aesebu_transmitter_query_format(const u32 h_aes_tx, const u32 index,
- u16 *pw_format);
-
-u16 hpi_aesebu_transmitter_set_format(u32 h_control, u16 output_format);
-
-u16 hpi_aesebu_transmitter_get_format(u32 h_control, u16 *pw_output_format);
-
-/***********************/
-/* Multiplexer control */
-/***********************/
-u16 hpi_multiplexer_set_source(u32 h_control, u16 source_node_type,
- u16 source_node_index);
-
-u16 hpi_multiplexer_get_source(u32 h_control, u16 *source_node_type,
- u16 *source_node_index);
-
-u16 hpi_multiplexer_query_source(u32 h_control, u16 index,
- u16 *source_node_type, u16 *source_node_index);
-
-/***************/
-/* Vox control */
-/***************/
-u16 hpi_vox_set_threshold(u32 h_control, short an_gain0_01dB);
-
-u16 hpi_vox_get_threshold(u32 h_control, short *an_gain0_01dB);
-
-/*********************/
-/* Bitstream control */
-/*********************/
-u16 hpi_bitstream_set_clock_edge(u32 h_control, u16 edge_type);
-
-u16 hpi_bitstream_set_data_polarity(u32 h_control, u16 polarity);
-
-u16 hpi_bitstream_get_activity(u32 h_control, u16 *pw_clk_activity,
- u16 *pw_data_activity);
-
-/***********************/
-/* SampleClock control */
-/***********************/
-
-u16 hpi_sample_clock_query_source(const u32 h_clock, const u32 index,
- u16 *pw_source);
-
-u16 hpi_sample_clock_set_source(u32 h_control, u16 source);
-
-u16 hpi_sample_clock_get_source(u32 h_control, u16 *pw_source);
-
-u16 hpi_sample_clock_query_source_index(const u32 h_clock, const u32 index,
- const u32 source, u16 *pw_source_index);
-
-u16 hpi_sample_clock_set_source_index(u32 h_control, u16 source_index);
-
-u16 hpi_sample_clock_get_source_index(u32 h_control, u16 *pw_source_index);
-
-u16 hpi_sample_clock_get_sample_rate(u32 h_control, u32 *psample_rate);
-
-u16 hpi_sample_clock_query_local_rate(const u32 h_clock, const u32 index,
- u32 *psource);
-
-u16 hpi_sample_clock_set_local_rate(u32 h_control, u32 sample_rate);
-
-u16 hpi_sample_clock_get_local_rate(u32 h_control, u32 *psample_rate);
-
-u16 hpi_sample_clock_set_auto(u32 h_control, u32 enable);
-
-u16 hpi_sample_clock_get_auto(u32 h_control, u32 *penable);
-
-u16 hpi_sample_clock_set_local_rate_lock(u32 h_control, u32 lock);
-
-u16 hpi_sample_clock_get_local_rate_lock(u32 h_control, u32 *plock);
-
-/***********************/
-/* Microphone control */
-/***********************/
-u16 hpi_microphone_set_phantom_power(u32 h_control, u16 on_off);
-
-u16 hpi_microphone_get_phantom_power(u32 h_control, u16 *pw_on_off);
-
-/********************************/
-/* Parametric Equalizer control */
-/********************************/
-u16 hpi_parametric_eq_get_info(u32 h_control, u16 *pw_number_of_bands,
- u16 *pw_enabled);
-
-u16 hpi_parametric_eq_set_state(u32 h_control, u16 on_off);
-
-u16 hpi_parametric_eq_set_band(u32 h_control, u16 index, u16 type,
- u32 frequency_hz, short q100, short gain0_01dB);
-
-u16 hpi_parametric_eq_get_band(u32 h_control, u16 index, u16 *pn_type,
- u32 *pfrequency_hz, short *pnQ100, short *pn_gain0_01dB);
-
-u16 hpi_parametric_eq_get_coeffs(u32 h_control, u16 index, short coeffs[5]
- );
-
-/*******************************/
-/* Compressor Expander control */
-/*******************************/
-
-u16 hpi_compander_set_enable(u32 h_control, u32 on);
-
-u16 hpi_compander_get_enable(u32 h_control, u32 *pon);
-
-u16 hpi_compander_set_makeup_gain(u32 h_control, short makeup_gain0_01dB);
-
-u16 hpi_compander_get_makeup_gain(u32 h_control, short *pn_makeup_gain0_01dB);
-
-u16 hpi_compander_set_attack_time_constant(u32 h_control, u32 index,
- u32 attack);
-
-u16 hpi_compander_get_attack_time_constant(u32 h_control, u32 index,
- u32 *pw_attack);
-
-u16 hpi_compander_set_decay_time_constant(u32 h_control, u32 index,
- u32 decay);
-
-u16 hpi_compander_get_decay_time_constant(u32 h_control, u32 index,
- u32 *pw_decay);
-
-u16 hpi_compander_set_threshold(u32 h_control, u32 index,
- short threshold0_01dB);
-
-u16 hpi_compander_get_threshold(u32 h_control, u32 index,
- short *pn_threshold0_01dB);
-
-u16 hpi_compander_set_ratio(u32 h_control, u32 index, u32 ratio100);
-
-u16 hpi_compander_get_ratio(u32 h_control, u32 index, u32 *pw_ratio100);
-
-/********************/
-/* Cobranet control */
-/********************/
-u16 hpi_cobranet_hmi_write(u32 h_control, u32 hmi_address, u32 byte_count,
- u8 *pb_data);
-
-u16 hpi_cobranet_hmi_read(u32 h_control, u32 hmi_address, u32 max_byte_count,
- u32 *pbyte_count, u8 *pb_data);
-
-u16 hpi_cobranet_hmi_get_status(u32 h_control, u32 *pstatus,
- u32 *preadable_size, u32 *pwriteable_size);
-
-u16 hpi_cobranet_get_ip_address(u32 h_control, u32 *pdw_ip_address);
-
-u16 hpi_cobranet_set_ip_address(u32 h_control, u32 dw_ip_address);
-
-u16 hpi_cobranet_get_static_ip_address(u32 h_control, u32 *pdw_ip_address);
-
-u16 hpi_cobranet_set_static_ip_address(u32 h_control, u32 dw_ip_address);
-
-u16 hpi_cobranet_get_macaddress(u32 h_control, u32 *p_mac_msbs,
- u32 *p_mac_lsbs);
-
-/*************************/
-/* Tone Detector control */
-/*************************/
-u16 hpi_tone_detector_get_state(u32 hC, u32 *state);
-
-u16 hpi_tone_detector_set_enable(u32 hC, u32 enable);
-
-u16 hpi_tone_detector_get_enable(u32 hC, u32 *enable);
-
-u16 hpi_tone_detector_set_event_enable(u32 hC, u32 event_enable);
-
-u16 hpi_tone_detector_get_event_enable(u32 hC, u32 *event_enable);
-
-u16 hpi_tone_detector_set_threshold(u32 hC, int threshold);
-
-u16 hpi_tone_detector_get_threshold(u32 hC, int *threshold);
-
-u16 hpi_tone_detector_get_frequency(u32 hC, u32 index, u32 *frequency);
-
-/****************************/
-/* Silence Detector control */
-/****************************/
-u16 hpi_silence_detector_get_state(u32 hC, u32 *state);
-
-u16 hpi_silence_detector_set_enable(u32 hC, u32 enable);
-
-u16 hpi_silence_detector_get_enable(u32 hC, u32 *enable);
-
-u16 hpi_silence_detector_set_event_enable(u32 hC, u32 event_enable);
-
-u16 hpi_silence_detector_get_event_enable(u32 hC, u32 *event_enable);
-
-u16 hpi_silence_detector_set_delay(u32 hC, u32 delay);
-
-u16 hpi_silence_detector_get_delay(u32 hC, u32 *delay);
-
-u16 hpi_silence_detector_set_threshold(u32 hC, int threshold);
-
-u16 hpi_silence_detector_get_threshold(u32 hC, int *threshold);
-/*********************/
-/* Utility functions */
-/*********************/
-
-u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format,
- u32 sample_rate, u32 bit_rate, u32 attributes);
-
-#endif /*_HPI_H_ */
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpi6000.c b/ANDROID_3.4.5/sound/pci/asihpi/hpi6000.c
deleted file mode 100644
index 2414d7a2..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpi6000.c
+++ /dev/null
@@ -1,1809 +0,0 @@
-/******************************************************************************
-
- AudioScience HPI driver
- Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- Hardware Programming Interface (HPI) for AudioScience ASI6200 series adapters.
- These PCI bus adapters are based on the TI C6711 DSP.
-
- Exported functions:
- void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
-
- #defines
- HIDE_PCI_ASSERTS to show the PCI asserts
- PROFILE_DSP2 get profile data from DSP2 if present (instead of DSP 1)
-
-(C) Copyright AudioScience Inc. 1998-2003
-*******************************************************************************/
-#define SOURCEFILE_NAME "hpi6000.c"
-
-#include "hpi_internal.h"
-#include "hpimsginit.h"
-#include "hpidebug.h"
-#include "hpi6000.h"
-#include "hpidspcd.h"
-#include "hpicmn.h"
-
-#define HPI_HIF_BASE (0x00000200) /* start of C67xx internal RAM */
-#define HPI_HIF_ADDR(member) \
- (HPI_HIF_BASE + offsetof(struct hpi_hif_6000, member))
-#define HPI_HIF_ERROR_MASK 0x4000
-
-/* HPI6000 specific error codes */
-#define HPI6000_ERROR_BASE 900 /* not actually used anywhere */
-
-/* operational/messaging errors */
-#define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT 901
-
-#define HPI6000_ERROR_MSG_RESP_GET_RESP_ACK 903
-#define HPI6000_ERROR_MSG_GET_ADR 904
-#define HPI6000_ERROR_RESP_GET_ADR 905
-#define HPI6000_ERROR_MSG_RESP_BLOCKWRITE32 906
-#define HPI6000_ERROR_MSG_RESP_BLOCKREAD32 907
-
-#define HPI6000_ERROR_CONTROL_CACHE_PARAMS 909
-
-#define HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT 911
-#define HPI6000_ERROR_SEND_DATA_ACK 912
-#define HPI6000_ERROR_SEND_DATA_ADR 913
-#define HPI6000_ERROR_SEND_DATA_TIMEOUT 914
-#define HPI6000_ERROR_SEND_DATA_CMD 915
-#define HPI6000_ERROR_SEND_DATA_WRITE 916
-#define HPI6000_ERROR_SEND_DATA_IDLECMD 917
-
-#define HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT 921
-#define HPI6000_ERROR_GET_DATA_ACK 922
-#define HPI6000_ERROR_GET_DATA_CMD 923
-#define HPI6000_ERROR_GET_DATA_READ 924
-#define HPI6000_ERROR_GET_DATA_IDLECMD 925
-
-#define HPI6000_ERROR_CONTROL_CACHE_ADDRLEN 951
-#define HPI6000_ERROR_CONTROL_CACHE_READ 952
-#define HPI6000_ERROR_CONTROL_CACHE_FLUSH 953
-
-#define HPI6000_ERROR_MSG_RESP_GETRESPCMD 961
-#define HPI6000_ERROR_MSG_RESP_IDLECMD 962
-
-/* Initialisation/bootload errors */
-#define HPI6000_ERROR_UNHANDLED_SUBSYS_ID 930
-
-/* can't access PCI2040 */
-#define HPI6000_ERROR_INIT_PCI2040 931
-/* can't access DSP HPI i/f */
-#define HPI6000_ERROR_INIT_DSPHPI 932
-/* can't access internal DSP memory */
-#define HPI6000_ERROR_INIT_DSPINTMEM 933
-/* can't access SDRAM - test#1 */
-#define HPI6000_ERROR_INIT_SDRAM1 934
-/* can't access SDRAM - test#2 */
-#define HPI6000_ERROR_INIT_SDRAM2 935
-
-#define HPI6000_ERROR_INIT_VERIFY 938
-
-#define HPI6000_ERROR_INIT_NOACK 939
-
-#define HPI6000_ERROR_INIT_PLDTEST1 941
-#define HPI6000_ERROR_INIT_PLDTEST2 942
-
-/* local defines */
-
-#define HIDE_PCI_ASSERTS
-#define PROFILE_DSP2
-
-/* for PCI2040 i/f chip */
-/* HPI CSR registers */
-/* word offsets from CSR base */
-/* use when io addresses defined as u32 * */
-
-#define INTERRUPT_EVENT_SET 0
-#define INTERRUPT_EVENT_CLEAR 1
-#define INTERRUPT_MASK_SET 2
-#define INTERRUPT_MASK_CLEAR 3
-#define HPI_ERROR_REPORT 4
-#define HPI_RESET 5
-#define HPI_DATA_WIDTH 6
-
-#define MAX_DSPS 2
-/* HPI registers, spaced 8K bytes = 2K words apart */
-#define DSP_SPACING 0x800
-
-#define CONTROL 0x0000
-#define ADDRESS 0x0200
-#define DATA_AUTOINC 0x0400
-#define DATA 0x0600
-
-#define TIMEOUT 500000
-
-struct dsp_obj {
- __iomem u32 *prHPI_control;
- __iomem u32 *prHPI_address;
- __iomem u32 *prHPI_data;
- __iomem u32 *prHPI_data_auto_inc;
- char c_dsp_rev; /*A, B */
- u32 control_cache_address_on_dsp;
- u32 control_cache_length_on_dsp;
- struct hpi_adapter_obj *pa_parent_adapter;
-};
-
-struct hpi_hw_obj {
- __iomem u32 *dw2040_HPICSR;
- __iomem u32 *dw2040_HPIDSP;
-
- u16 num_dsp;
- struct dsp_obj ado[MAX_DSPS];
-
- u32 message_buffer_address_on_dsp;
- u32 response_buffer_address_on_dsp;
- u32 pCI2040HPI_error_count;
-
- struct hpi_control_cache_single control_cache[HPI_NMIXER_CONTROLS];
- struct hpi_control_cache *p_cache;
-};
-
-static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao,
- u16 dsp_index, u32 hpi_address, u32 *source, u32 count);
-static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao,
- u16 dsp_index, u32 hpi_address, u32 *dest, u32 count);
-
-static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
- u32 *pos_error_code);
-static short hpi6000_check_PCI2040_error_flag(struct hpi_adapter_obj *pao,
- u16 read_or_write);
-#define H6READ 1
-#define H6WRITE 0
-
-static short hpi6000_update_control_cache(struct hpi_adapter_obj *pao,
- struct hpi_message *phm);
-static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
- u16 dsp_index, struct hpi_message *phm, struct hpi_response *phr);
-
-static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
- struct hpi_response *phr);
-
-static short hpi6000_wait_dsp_ack(struct hpi_adapter_obj *pao, u16 dsp_index,
- u32 ack_value);
-
-static short hpi6000_send_host_command(struct hpi_adapter_obj *pao,
- u16 dsp_index, u32 host_cmd);
-
-static void hpi6000_send_dsp_interrupt(struct dsp_obj *pdo);
-
-static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index,
- struct hpi_message *phm, struct hpi_response *phr);
-
-static short hpi6000_get_data(struct hpi_adapter_obj *pao, u16 dsp_index,
- struct hpi_message *phm, struct hpi_response *phr);
-
-static void hpi_write_word(struct dsp_obj *pdo, u32 address, u32 data);
-
-static u32 hpi_read_word(struct dsp_obj *pdo, u32 address);
-
-static void hpi_write_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
- u32 length);
-
-static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
- u32 length);
-
-static void subsys_create_adapter(struct hpi_message *phm,
- struct hpi_response *phr);
-
-static void adapter_delete(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr);
-
-static void adapter_get_asserts(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr);
-
-static short create_adapter_obj(struct hpi_adapter_obj *pao,
- u32 *pos_error_code);
-
-static void delete_adapter_obj(struct hpi_adapter_obj *pao);
-
-/* local globals */
-
-static u16 gw_pci_read_asserts; /* used to count PCI2040 errors */
-static u16 gw_pci_write_asserts; /* used to count PCI2040 errors */
-
-static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
-{
- switch (phm->function) {
- case HPI_SUBSYS_CREATE_ADAPTER:
- subsys_create_adapter(phm, phr);
- break;
- default:
- phr->error = HPI_ERROR_INVALID_FUNC;
- break;
- }
-}
-
-static void control_message(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- struct hpi_hw_obj *phw = pao->priv;
-
- switch (phm->function) {
- case HPI_CONTROL_GET_STATE:
- if (pao->has_control_cache) {
- u16 err;
- err = hpi6000_update_control_cache(pao, phm);
-
- if (err) {
- if (err >= HPI_ERROR_BACKEND_BASE) {
- phr->error =
- HPI_ERROR_CONTROL_CACHING;
- phr->specific_error = err;
- } else {
- phr->error = err;
- }
- break;
- }
-
- if (hpi_check_control_cache(phw->p_cache, phm, phr))
- break;
- }
- hw_message(pao, phm, phr);
- break;
- case HPI_CONTROL_SET_STATE:
- hw_message(pao, phm, phr);
- hpi_cmn_control_cache_sync_to_msg(phw->p_cache, phm, phr);
- break;
-
- case HPI_CONTROL_GET_INFO:
- default:
- hw_message(pao, phm, phr);
- break;
- }
-}
-
-static void adapter_message(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- switch (phm->function) {
- case HPI_ADAPTER_GET_ASSERT:
- adapter_get_asserts(pao, phm, phr);
- break;
-
- case HPI_ADAPTER_DELETE:
- adapter_delete(pao, phm, phr);
- break;
-
- default:
- hw_message(pao, phm, phr);
- break;
- }
-}
-
-static void outstream_message(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- switch (phm->function) {
- case HPI_OSTREAM_HOSTBUFFER_ALLOC:
- case HPI_OSTREAM_HOSTBUFFER_FREE:
- /* Don't let these messages go to the HW function because
- * they're called without locking the spinlock.
- * For the HPI6000 adapters the HW would return
- * HPI_ERROR_INVALID_FUNC anyway.
- */
- phr->error = HPI_ERROR_INVALID_FUNC;
- break;
- default:
- hw_message(pao, phm, phr);
- return;
- }
-}
-
-static void instream_message(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
-
- switch (phm->function) {
- case HPI_ISTREAM_HOSTBUFFER_ALLOC:
- case HPI_ISTREAM_HOSTBUFFER_FREE:
- /* Don't let these messages go to the HW function because
- * they're called without locking the spinlock.
- * For the HPI6000 adapters the HW would return
- * HPI_ERROR_INVALID_FUNC anyway.
- */
- phr->error = HPI_ERROR_INVALID_FUNC;
- break;
- default:
- hw_message(pao, phm, phr);
- return;
- }
-}
-
-/************************************************************************/
-/** HPI_6000()
- * Entry point from HPIMAN
- * All calls to the HPI start here
- */
-void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
-{
- struct hpi_adapter_obj *pao = NULL;
-
- if (phm->object != HPI_OBJ_SUBSYSTEM) {
- pao = hpi_find_adapter(phm->adapter_index);
- if (!pao) {
- hpi_init_response(phr, phm->object, phm->function,
- HPI_ERROR_BAD_ADAPTER_NUMBER);
- HPI_DEBUG_LOG(DEBUG, "invalid adapter index: %d \n",
- phm->adapter_index);
- return;
- }
-
- /* Don't even try to communicate with crashed DSP */
- if (pao->dsp_crashed >= 10) {
- hpi_init_response(phr, phm->object, phm->function,
- HPI_ERROR_DSP_HARDWARE);
- HPI_DEBUG_LOG(DEBUG, "adapter %d dsp crashed\n",
- phm->adapter_index);
- return;
- }
- }
- /* Init default response including the size field */
- if (phm->function != HPI_SUBSYS_CREATE_ADAPTER)
- hpi_init_response(phr, phm->object, phm->function,
- HPI_ERROR_PROCESSING_MESSAGE);
-
- switch (phm->type) {
- case HPI_TYPE_REQUEST:
- switch (phm->object) {
- case HPI_OBJ_SUBSYSTEM:
- subsys_message(phm, phr);
- break;
-
- case HPI_OBJ_ADAPTER:
- phr->size =
- sizeof(struct hpi_response_header) +
- sizeof(struct hpi_adapter_res);
- adapter_message(pao, phm, phr);
- break;
-
- case HPI_OBJ_CONTROL:
- control_message(pao, phm, phr);
- break;
-
- case HPI_OBJ_OSTREAM:
- outstream_message(pao, phm, phr);
- break;
-
- case HPI_OBJ_ISTREAM:
- instream_message(pao, phm, phr);
- break;
-
- default:
- hw_message(pao, phm, phr);
- break;
- }
- break;
-
- default:
- phr->error = HPI_ERROR_INVALID_TYPE;
- break;
- }
-}
-
-/************************************************************************/
-/* SUBSYSTEM */
-
-/* create an adapter object and initialise it based on resource information
- * passed in in the message
- * NOTE - you cannot use this function AND the FindAdapters function at the
- * same time, the application must use only one of them to get the adapters
- */
-static void subsys_create_adapter(struct hpi_message *phm,
- struct hpi_response *phr)
-{
- /* create temp adapter obj, because we don't know what index yet */
- struct hpi_adapter_obj ao;
- struct hpi_adapter_obj *pao;
- u32 os_error_code;
- u16 err = 0;
- u32 dsp_index = 0;
-
- HPI_DEBUG_LOG(VERBOSE, "subsys_create_adapter\n");
-
- memset(&ao, 0, sizeof(ao));
-
- ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
- if (!ao.priv) {
- HPI_DEBUG_LOG(ERROR, "can't get mem for adapter object\n");
- phr->error = HPI_ERROR_MEMORY_ALLOC;
- return;
- }
-
- /* create the adapter object based on the resource information */
- ao.pci = *phm->u.s.resource.r.pci;
-
- err = create_adapter_obj(&ao, &os_error_code);
- if (err) {
- delete_adapter_obj(&ao);
- if (err >= HPI_ERROR_BACKEND_BASE) {
- phr->error = HPI_ERROR_DSP_BOOTLOAD;
- phr->specific_error = err;
- } else {
- phr->error = err;
- }
-
- phr->u.s.data = os_error_code;
- return;
- }
- /* need to update paParentAdapter */
- pao = hpi_find_adapter(ao.index);
- if (!pao) {
- /* We just added this adapter, why can't we find it!? */
- HPI_DEBUG_LOG(ERROR, "lost adapter after boot\n");
- phr->error = HPI_ERROR_BAD_ADAPTER;
- return;
- }
-
- for (dsp_index = 0; dsp_index < MAX_DSPS; dsp_index++) {
- struct hpi_hw_obj *phw = pao->priv;
- phw->ado[dsp_index].pa_parent_adapter = pao;
- }
-
- phr->u.s.adapter_type = ao.type;
- phr->u.s.adapter_index = ao.index;
- phr->error = 0;
-}
-
-static void adapter_delete(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- delete_adapter_obj(pao);
- hpi_delete_adapter(pao);
- phr->error = 0;
-}
-
-/* this routine is called from SubSysFindAdapter and SubSysCreateAdapter */
-static short create_adapter_obj(struct hpi_adapter_obj *pao,
- u32 *pos_error_code)
-{
- short boot_error = 0;
- u32 dsp_index = 0;
- u32 control_cache_size = 0;
- u32 control_cache_count = 0;
- struct hpi_hw_obj *phw = pao->priv;
-
- /* The PCI2040 has the following address map */
- /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */
- /* BAR1 - 32K = HPI registers on DSP */
- phw->dw2040_HPICSR = pao->pci.ap_mem_base[0];
- phw->dw2040_HPIDSP = pao->pci.ap_mem_base[1];
- HPI_DEBUG_LOG(VERBOSE, "csr %p, dsp %p\n", phw->dw2040_HPICSR,
- phw->dw2040_HPIDSP);
-
- /* set addresses for the possible DSP HPI interfaces */
- for (dsp_index = 0; dsp_index < MAX_DSPS; dsp_index++) {
- phw->ado[dsp_index].prHPI_control =
- phw->dw2040_HPIDSP + (CONTROL +
- DSP_SPACING * dsp_index);
-
- phw->ado[dsp_index].prHPI_address =
- phw->dw2040_HPIDSP + (ADDRESS +
- DSP_SPACING * dsp_index);
- phw->ado[dsp_index].prHPI_data =
- phw->dw2040_HPIDSP + (DATA + DSP_SPACING * dsp_index);
-
- phw->ado[dsp_index].prHPI_data_auto_inc =
- phw->dw2040_HPIDSP + (DATA_AUTOINC +
- DSP_SPACING * dsp_index);
-
- HPI_DEBUG_LOG(VERBOSE, "ctl %p, adr %p, dat %p, dat++ %p\n",
- phw->ado[dsp_index].prHPI_control,
- phw->ado[dsp_index].prHPI_address,
- phw->ado[dsp_index].prHPI_data,
- phw->ado[dsp_index].prHPI_data_auto_inc);
-
- phw->ado[dsp_index].pa_parent_adapter = pao;
- }
-
- phw->pCI2040HPI_error_count = 0;
- pao->has_control_cache = 0;
-
- /* Set the default number of DSPs on this card */
- /* This is (conditionally) adjusted after bootloading */
- /* of the first DSP in the bootload section. */
- phw->num_dsp = 1;
-
- boot_error = hpi6000_adapter_boot_load_dsp(pao, pos_error_code);
- if (boot_error)
- return boot_error;
-
- HPI_DEBUG_LOG(INFO, "bootload DSP OK\n");
-
- phw->message_buffer_address_on_dsp = 0L;
- phw->response_buffer_address_on_dsp = 0L;
-
- /* get info about the adapter by asking the adapter */
- /* send a HPI_ADAPTER_GET_INFO message */
- {
- struct hpi_message hm;
- struct hpi_response hr0; /* response from DSP 0 */
- struct hpi_response hr1; /* response from DSP 1 */
- u16 error = 0;
-
- HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n");
- memset(&hm, 0, sizeof(hm));
- hm.type = HPI_TYPE_REQUEST;
- hm.size = sizeof(struct hpi_message);
- hm.object = HPI_OBJ_ADAPTER;
- hm.function = HPI_ADAPTER_GET_INFO;
- hm.adapter_index = 0;
- memset(&hr0, 0, sizeof(hr0));
- memset(&hr1, 0, sizeof(hr1));
- hr0.size = sizeof(hr0);
- hr1.size = sizeof(hr1);
-
- error = hpi6000_message_response_sequence(pao, 0, &hm, &hr0);
- if (hr0.error) {
- HPI_DEBUG_LOG(DEBUG, "message error %d\n", hr0.error);
- return hr0.error;
- }
- if (phw->num_dsp == 2) {
- error = hpi6000_message_response_sequence(pao, 1, &hm,
- &hr1);
- if (error)
- return error;
- }
- pao->type = hr0.u.ax.info.adapter_type;
- pao->index = hr0.u.ax.info.adapter_index;
- }
-
- memset(&phw->control_cache[0], 0,
- sizeof(struct hpi_control_cache_single) *
- HPI_NMIXER_CONTROLS);
- /* Read the control cache length to figure out if it is turned on */
- control_cache_size =
- hpi_read_word(&phw->ado[0],
- HPI_HIF_ADDR(control_cache_size_in_bytes));
- if (control_cache_size) {
- control_cache_count =
- hpi_read_word(&phw->ado[0],
- HPI_HIF_ADDR(control_cache_count));
-
- phw->p_cache =
- hpi_alloc_control_cache(control_cache_count,
- control_cache_size, (unsigned char *)
- &phw->control_cache[0]
- );
- if (phw->p_cache)
- pao->has_control_cache = 1;
- }
-
- HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n", pao->type,
- pao->index);
-
- if (phw->p_cache)
- phw->p_cache->adap_idx = pao->index;
-
- return hpi_add_adapter(pao);
-}
-
-static void delete_adapter_obj(struct hpi_adapter_obj *pao)
-{
- struct hpi_hw_obj *phw = pao->priv;
-
- if (pao->has_control_cache)
- hpi_free_control_cache(phw->p_cache);
-
- /* reset DSPs on adapter */
- iowrite32(0x0003000F, phw->dw2040_HPICSR + HPI_RESET);
-
- kfree(phw);
-}
-
-/************************************************************************/
-/* ADAPTER */
-
-static void adapter_get_asserts(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
-#ifndef HIDE_PCI_ASSERTS
- /* if we have PCI2040 asserts then collect them */
- if ((gw_pci_read_asserts > 0) || (gw_pci_write_asserts > 0)) {
- phr->u.ax.assert.p1 =
- gw_pci_read_asserts * 100 + gw_pci_write_asserts;
- phr->u.ax.assert.p2 = 0;
- phr->u.ax.assert.count = 1; /* assert count */
- phr->u.ax.assert.dsp_index = -1; /* "dsp index" */
- strcpy(phr->u.ax.assert.sz_message, "PCI2040 error");
- phr->u.ax.assert.dsp_msg_addr = 0;
- gw_pci_read_asserts = 0;
- gw_pci_write_asserts = 0;
- phr->error = 0;
- } else
-#endif
- hw_message(pao, phm, phr); /*get DSP asserts */
-
- return;
-}
-
-/************************************************************************/
-/* LOW-LEVEL */
-
-static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
- u32 *pos_error_code)
-{
- struct hpi_hw_obj *phw = pao->priv;
- short error;
- u32 timeout;
- u32 read = 0;
- u32 i = 0;
- u32 data = 0;
- u32 j = 0;
- u32 test_addr = 0x80000000;
- u32 test_data = 0x00000001;
- u32 dw2040_reset = 0;
- u32 dsp_index = 0;
- u32 endian = 0;
- u32 adapter_info = 0;
- u32 delay = 0;
-
- struct dsp_code dsp_code;
- u16 boot_load_family = 0;
-
- /* NOTE don't use wAdapterType in this routine. It is not setup yet */
-
- switch (pao->pci.pci_dev->subsystem_device) {
- case 0x5100:
- case 0x5110: /* ASI5100 revB or higher with C6711D */
- case 0x5200: /* ASI5200 PCIe version of ASI5100 */
- case 0x6100:
- case 0x6200:
- boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200);
- break;
- default:
- return HPI6000_ERROR_UNHANDLED_SUBSYS_ID;
- }
-
- /* reset all DSPs, indicate two DSPs are present
- * set RST3-=1 to disconnect HAD8 to set DSP in little endian mode
- */
- endian = 0;
- dw2040_reset = 0x0003000F;
- iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
-
- /* read back register to make sure PCI2040 chip is functioning
- * note that bits 4..15 are read-only and so should always return zero,
- * even though we wrote 1 to them
- */
- hpios_delay_micro_seconds(1000);
- delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
-
- if (delay != dw2040_reset) {
- HPI_DEBUG_LOG(ERROR, "INIT_PCI2040 %x %x\n", dw2040_reset,
- delay);
- return HPI6000_ERROR_INIT_PCI2040;
- }
-
- /* Indicate that DSP#0,1 is a C6X */
- iowrite32(0x00000003, phw->dw2040_HPICSR + HPI_DATA_WIDTH);
- /* set Bit30 and 29 - which will prevent Target aborts from being
- * issued upon HPI or GP error
- */
- iowrite32(0x60000000, phw->dw2040_HPICSR + INTERRUPT_MASK_SET);
-
- /* isolate DSP HAD8 line from PCI2040 so that
- * Little endian can be set by pullup
- */
- dw2040_reset = dw2040_reset & (~(endian << 3));
- iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
-
- phw->ado[0].c_dsp_rev = 'B'; /* revB */
- phw->ado[1].c_dsp_rev = 'B'; /* revB */
-
- /*Take both DSPs out of reset, setting HAD8 to the correct Endian */
- dw2040_reset = dw2040_reset & (~0x00000001); /* start DSP 0 */
- iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
- dw2040_reset = dw2040_reset & (~0x00000002); /* start DSP 1 */
- iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
-
- /* set HAD8 back to PCI2040, now that DSP set to little endian mode */
- dw2040_reset = dw2040_reset & (~0x00000008);
- iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
- /*delay to allow DSP to get going */
- hpios_delay_micro_seconds(100);
-
- /* loop through all DSPs, downloading DSP code */
- for (dsp_index = 0; dsp_index < phw->num_dsp; dsp_index++) {
- struct dsp_obj *pdo = &phw->ado[dsp_index];
-
- /* configure DSP so that we download code into the SRAM */
- /* set control reg for little endian, HWOB=1 */
- iowrite32(0x00010001, pdo->prHPI_control);
-
- /* test access to the HPI address register (HPIA) */
- test_data = 0x00000001;
- for (j = 0; j < 32; j++) {
- iowrite32(test_data, pdo->prHPI_address);
- data = ioread32(pdo->prHPI_address);
- if (data != test_data) {
- HPI_DEBUG_LOG(ERROR, "INIT_DSPHPI %x %x %x\n",
- test_data, data, dsp_index);
- return HPI6000_ERROR_INIT_DSPHPI;
- }
- test_data = test_data << 1;
- }
-
-/* if C6713 the setup PLL to generate 225MHz from 25MHz.
-* Since the PLLDIV1 read is sometimes wrong, even on a C6713,
-* we're going to do this unconditionally
-*/
-/* PLLDIV1 should have a value of 8000 after reset */
-/*
- if (HpiReadWord(pdo,0x01B7C118) == 0x8000)
-*/
- {
- /* C6713 datasheet says we cannot program PLL from HPI,
- * and indeed if we try to set the PLL multiply from the
- * HPI, the PLL does not seem to lock,
- * so we enable the PLL and use the default of x 7
- */
- /* bypass PLL */
- hpi_write_word(pdo, 0x01B7C100, 0x0000);
- hpios_delay_micro_seconds(100);
-
- /* ** use default of PLL x7 ** */
- /* EMIF = 225/3=75MHz */
- hpi_write_word(pdo, 0x01B7C120, 0x8002);
- hpios_delay_micro_seconds(100);
-
- /* peri = 225/2 */
- hpi_write_word(pdo, 0x01B7C11C, 0x8001);
- hpios_delay_micro_seconds(100);
-
- /* cpu = 225/1 */
- hpi_write_word(pdo, 0x01B7C118, 0x8000);
-
- /* ~2ms delay */
- hpios_delay_micro_seconds(2000);
-
- /* PLL not bypassed */
- hpi_write_word(pdo, 0x01B7C100, 0x0001);
- /* ~2ms delay */
- hpios_delay_micro_seconds(2000);
- }
-
- /* test r/w to internal DSP memory
- * C6711 has L2 cache mapped to 0x0 when reset
- *
- * revB - because of bug 3.0.1 last HPI read
- * (before HPI address issued) must be non-autoinc
- */
- /* test each bit in the 32bit word */
- for (i = 0; i < 100; i++) {
- test_addr = 0x00000000;
- test_data = 0x00000001;
- for (j = 0; j < 32; j++) {
- hpi_write_word(pdo, test_addr + i, test_data);
- data = hpi_read_word(pdo, test_addr + i);
- if (data != test_data) {
- HPI_DEBUG_LOG(ERROR,
- "DSP mem %x %x %x %x\n",
- test_addr + i, test_data,
- data, dsp_index);
-
- return HPI6000_ERROR_INIT_DSPINTMEM;
- }
- test_data = test_data << 1;
- }
- }
-
- /* memory map of ASI6200
- 00000000-0000FFFF 16Kx32 internal program
- 01800000-019FFFFF Internal peripheral
- 80000000-807FFFFF CE0 2Mx32 SDRAM running @ 100MHz
- 90000000-9000FFFF CE1 Async peripherals:
-
- EMIF config
- ------------
- Global EMIF control
- 0 -
- 1 -
- 2 -
- 3 CLK2EN = 1 CLKOUT2 enabled
- 4 CLK1EN = 0 CLKOUT1 disabled
- 5 EKEN = 1 <--!! C6713 specific, enables ECLKOUT
- 6 -
- 7 NOHOLD = 1 external HOLD disabled
- 8 HOLDA = 0 HOLDA output is low
- 9 HOLD = 0 HOLD input is low
- 10 ARDY = 1 ARDY input is high
- 11 BUSREQ = 0 BUSREQ output is low
- 12,13 Reserved = 1
- */
- hpi_write_word(pdo, 0x01800000, 0x34A8);
-
- /* EMIF CE0 setup - 2Mx32 Sync DRAM
- 31..28 Wr setup
- 27..22 Wr strobe
- 21..20 Wr hold
- 19..16 Rd setup
- 15..14 -
- 13..8 Rd strobe
- 7..4 MTYPE 0011 Sync DRAM 32bits
- 3 Wr hold MSB
- 2..0 Rd hold
- */
- hpi_write_word(pdo, 0x01800008, 0x00000030);
-
- /* EMIF SDRAM Extension
- 31-21 0
- 20 WR2RD = 0
- 19-18 WR2DEAC = 1
- 17 WR2WR = 0
- 16-15 R2WDQM = 2
- 14-12 RD2WR = 4
- 11-10 RD2DEAC = 1
- 9 RD2RD = 1
- 8-7 THZP = 10b
- 6-5 TWR = 2-1 = 01b (tWR = 10ns)
- 4 TRRD = 0b = 2 ECLK (tRRD = 14ns)
- 3-1 TRAS = 5-1 = 100b (Tras=42ns = 5 ECLK)
- 1 CAS latency = 3 ECLK
- (for Micron 2M32-7 operating at 100Mhz)
- */
-
- /* need to use this else DSP code crashes */
- hpi_write_word(pdo, 0x01800020, 0x001BDF29);
-
- /* EMIF SDRAM control - set up for a 2Mx32 SDRAM (512x32x4 bank)
- 31 - -
- 30 SDBSZ 1 4 bank
- 29..28 SDRSZ 00 11 row address pins
- 27..26 SDCSZ 01 8 column address pins
- 25 RFEN 1 refersh enabled
- 24 INIT 1 init SDRAM
- 23..20 TRCD 0001
- 19..16 TRP 0001
- 15..12 TRC 0110
- 11..0 - -
- */
- /* need to use this else DSP code crashes */
- hpi_write_word(pdo, 0x01800018, 0x47117000);
-
- /* EMIF SDRAM Refresh Timing */
- hpi_write_word(pdo, 0x0180001C, 0x00000410);
-
- /*MIF CE1 setup - Async peripherals
- @100MHz bus speed, each cycle is 10ns,
- 31..28 Wr setup = 1
- 27..22 Wr strobe = 3 30ns
- 21..20 Wr hold = 1
- 19..16 Rd setup =1
- 15..14 Ta = 2
- 13..8 Rd strobe = 3 30ns
- 7..4 MTYPE 0010 Async 32bits
- 3 Wr hold MSB =0
- 2..0 Rd hold = 1
- */
- {
- u32 cE1 =
- (1L << 28) | (3L << 22) | (1L << 20) | (1L <<
- 16) | (2L << 14) | (3L << 8) | (2L << 4) | 1L;
- hpi_write_word(pdo, 0x01800004, cE1);
- }
-
- /* delay a little to allow SDRAM and DSP to "get going" */
- hpios_delay_micro_seconds(1000);
-
- /* test access to SDRAM */
- {
- test_addr = 0x80000000;
- test_data = 0x00000001;
- /* test each bit in the 32bit word */
- for (j = 0; j < 32; j++) {
- hpi_write_word(pdo, test_addr, test_data);
- data = hpi_read_word(pdo, test_addr);
- if (data != test_data) {
- HPI_DEBUG_LOG(ERROR,
- "DSP dram %x %x %x %x\n",
- test_addr, test_data, data,
- dsp_index);
-
- return HPI6000_ERROR_INIT_SDRAM1;
- }
- test_data = test_data << 1;
- }
- /* test every Nth address in the DRAM */
-#define DRAM_SIZE_WORDS 0x200000 /*2_mx32 */
-#define DRAM_INC 1024
- test_addr = 0x80000000;
- test_data = 0x0;
- for (i = 0; i < DRAM_SIZE_WORDS; i = i + DRAM_INC) {
- hpi_write_word(pdo, test_addr + i, test_data);
- test_data++;
- }
- test_addr = 0x80000000;
- test_data = 0x0;
- for (i = 0; i < DRAM_SIZE_WORDS; i = i + DRAM_INC) {
- data = hpi_read_word(pdo, test_addr + i);
- if (data != test_data) {
- HPI_DEBUG_LOG(ERROR,
- "DSP dram %x %x %x %x\n",
- test_addr + i, test_data,
- data, dsp_index);
- return HPI6000_ERROR_INIT_SDRAM2;
- }
- test_data++;
- }
-
- }
-
- /* write the DSP code down into the DSPs memory */
- error = hpi_dsp_code_open(boot_load_family, pao->pci.pci_dev,
- &dsp_code, pos_error_code);
-
- if (error)
- return error;
-
- while (1) {
- u32 length;
- u32 address;
- u32 type;
- u32 *pcode;
-
- error = hpi_dsp_code_read_word(&dsp_code, &length);
- if (error)
- break;
- if (length == 0xFFFFFFFF)
- break; /* end of code */
-
- error = hpi_dsp_code_read_word(&dsp_code, &address);
- if (error)
- break;
- error = hpi_dsp_code_read_word(&dsp_code, &type);
- if (error)
- break;
- error = hpi_dsp_code_read_block(length, &dsp_code,
- &pcode);
- if (error)
- break;
- error = hpi6000_dsp_block_write32(pao, (u16)dsp_index,
- address, pcode, length);
- if (error)
- break;
- }
-
- if (error) {
- hpi_dsp_code_close(&dsp_code);
- return error;
- }
- /* verify that code was written correctly */
- /* this time through, assume no errors in DSP code file/array */
- hpi_dsp_code_rewind(&dsp_code);
- while (1) {
- u32 length;
- u32 address;
- u32 type;
- u32 *pcode;
-
- hpi_dsp_code_read_word(&dsp_code, &length);
- if (length == 0xFFFFFFFF)
- break; /* end of code */
-
- hpi_dsp_code_read_word(&dsp_code, &address);
- hpi_dsp_code_read_word(&dsp_code, &type);
- hpi_dsp_code_read_block(length, &dsp_code, &pcode);
-
- for (i = 0; i < length; i++) {
- data = hpi_read_word(pdo, address);
- if (data != *pcode) {
- error = HPI6000_ERROR_INIT_VERIFY;
- HPI_DEBUG_LOG(ERROR,
- "DSP verify %x %x %x %x\n",
- address, *pcode, data,
- dsp_index);
- break;
- }
- pcode++;
- address += 4;
- }
- if (error)
- break;
- }
- hpi_dsp_code_close(&dsp_code);
- if (error)
- return error;
-
- /* zero out the hostmailbox */
- {
- u32 address = HPI_HIF_ADDR(host_cmd);
- for (i = 0; i < 4; i++) {
- hpi_write_word(pdo, address, 0);
- address += 4;
- }
- }
- /* write the DSP number into the hostmailbox */
- /* structure before starting the DSP */
- hpi_write_word(pdo, HPI_HIF_ADDR(dsp_number), dsp_index);
-
- /* write the DSP adapter Info into the */
- /* hostmailbox before starting the DSP */
- if (dsp_index > 0)
- hpi_write_word(pdo, HPI_HIF_ADDR(adapter_info),
- adapter_info);
-
- /* step 3. Start code by sending interrupt */
- iowrite32(0x00030003, pdo->prHPI_control);
- hpios_delay_micro_seconds(10000);
-
- /* wait for a non-zero value in hostcmd -
- * indicating initialization is complete
- *
- * Init could take a while if DSP checks SDRAM memory
- * Was 200000. Increased to 2000000 for ASI8801 so we
- * don't get 938 errors.
- */
- timeout = 2000000;
- while (timeout) {
- do {
- read = hpi_read_word(pdo,
- HPI_HIF_ADDR(host_cmd));
- } while (--timeout
- && hpi6000_check_PCI2040_error_flag(pao,
- H6READ));
-
- if (read)
- break;
- /* The following is a workaround for bug #94:
- * Bluescreen on install and subsequent boots on a
- * DELL PowerEdge 600SC PC with 1.8GHz P4 and
- * ServerWorks chipset. Without this delay the system
- * locks up with a bluescreen (NOT GPF or pagefault).
- */
- else
- hpios_delay_micro_seconds(10000);
- }
- if (timeout == 0)
- return HPI6000_ERROR_INIT_NOACK;
-
- /* read the DSP adapter Info from the */
- /* hostmailbox structure after starting the DSP */
- if (dsp_index == 0) {
- /*u32 dwTestData=0; */
- u32 mask = 0;
-
- adapter_info =
- hpi_read_word(pdo,
- HPI_HIF_ADDR(adapter_info));
- if (HPI_ADAPTER_FAMILY_ASI
- (HPI_HIF_ADAPTER_INFO_EXTRACT_ADAPTER
- (adapter_info)) ==
- HPI_ADAPTER_FAMILY_ASI(0x6200))
- /* all 6200 cards have this many DSPs */
- phw->num_dsp = 2;
-
- /* test that the PLD is programmed */
- /* and we can read/write 24bits */
-#define PLD_BASE_ADDRESS 0x90000000L /*for ASI6100/6200/8800 */
-
- switch (boot_load_family) {
- case HPI_ADAPTER_FAMILY_ASI(0x6200):
- /* ASI6100/6200 has 24bit path to FPGA */
- mask = 0xFFFFFF00L;
- /* ASI5100 uses AX6 code, */
- /* but has no PLD r/w register to test */
- if (HPI_ADAPTER_FAMILY_ASI(pao->pci.pci_dev->
- subsystem_device) ==
- HPI_ADAPTER_FAMILY_ASI(0x5100))
- mask = 0x00000000L;
- /* ASI5200 uses AX6 code, */
- /* but has no PLD r/w register to test */
- if (HPI_ADAPTER_FAMILY_ASI(pao->pci.pci_dev->
- subsystem_device) ==
- HPI_ADAPTER_FAMILY_ASI(0x5200))
- mask = 0x00000000L;
- break;
- case HPI_ADAPTER_FAMILY_ASI(0x8800):
- /* ASI8800 has 16bit path to FPGA */
- mask = 0xFFFF0000L;
- break;
- }
- test_data = 0xAAAAAA00L & mask;
- /* write to 24 bit Debug register (D31-D8) */
- hpi_write_word(pdo, PLD_BASE_ADDRESS + 4L, test_data);
- read = hpi_read_word(pdo,
- PLD_BASE_ADDRESS + 4L) & mask;
- if (read != test_data) {
- HPI_DEBUG_LOG(ERROR, "PLD %x %x\n", test_data,
- read);
- return HPI6000_ERROR_INIT_PLDTEST1;
- }
- test_data = 0x55555500L & mask;
- hpi_write_word(pdo, PLD_BASE_ADDRESS + 4L, test_data);
- read = hpi_read_word(pdo,
- PLD_BASE_ADDRESS + 4L) & mask;
- if (read != test_data) {
- HPI_DEBUG_LOG(ERROR, "PLD %x %x\n", test_data,
- read);
- return HPI6000_ERROR_INIT_PLDTEST2;
- }
- }
- } /* for numDSP */
- return 0;
-}
-
-#define PCI_TIMEOUT 100
-
-static int hpi_set_address(struct dsp_obj *pdo, u32 address)
-{
- u32 timeout = PCI_TIMEOUT;
-
- do {
- iowrite32(address, pdo->prHPI_address);
- } while (hpi6000_check_PCI2040_error_flag(pdo->pa_parent_adapter,
- H6WRITE)
- && --timeout);
-
- if (timeout)
- return 0;
-
- return 1;
-}
-
-/* write one word to the HPI port */
-static void hpi_write_word(struct dsp_obj *pdo, u32 address, u32 data)
-{
- if (hpi_set_address(pdo, address))
- return;
- iowrite32(data, pdo->prHPI_data);
-}
-
-/* read one word from the HPI port */
-static u32 hpi_read_word(struct dsp_obj *pdo, u32 address)
-{
- u32 data = 0;
-
- if (hpi_set_address(pdo, address))
- return 0; /*? No way to return error */
-
- /* take care of errata in revB DSP (2.0.1) */
- data = ioread32(pdo->prHPI_data);
- return data;
-}
-
-/* write a block of 32bit words to the DSP HPI port using auto-inc mode */
-static void hpi_write_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
- u32 length)
-{
- u16 length16 = length - 1;
-
- if (length == 0)
- return;
-
- if (hpi_set_address(pdo, address))
- return;
-
- iowrite32_rep(pdo->prHPI_data_auto_inc, pdata, length16);
-
- /* take care of errata in revB DSP (2.0.1) */
- /* must end with non auto-inc */
- iowrite32(*(pdata + length - 1), pdo->prHPI_data);
-}
-
-/** read a block of 32bit words from the DSP HPI port using auto-inc mode
- */
-static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
- u32 length)
-{
- u16 length16 = length - 1;
-
- if (length == 0)
- return;
-
- if (hpi_set_address(pdo, address))
- return;
-
- ioread32_rep(pdo->prHPI_data_auto_inc, pdata, length16);
-
- /* take care of errata in revB DSP (2.0.1) */
- /* must end with non auto-inc */
- *(pdata + length - 1) = ioread32(pdo->prHPI_data);
-}
-
-static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao,
- u16 dsp_index, u32 hpi_address, u32 *source, u32 count)
-{
- struct hpi_hw_obj *phw = pao->priv;
- struct dsp_obj *pdo = &phw->ado[dsp_index];
- u32 time_out = PCI_TIMEOUT;
- int c6711_burst_size = 128;
- u32 local_hpi_address = hpi_address;
- int local_count = count;
- int xfer_size;
- u32 *pdata = source;
-
- while (local_count) {
- if (local_count > c6711_burst_size)
- xfer_size = c6711_burst_size;
- else
- xfer_size = local_count;
-
- time_out = PCI_TIMEOUT;
- do {
- hpi_write_block(pdo, local_hpi_address, pdata,
- xfer_size);
- } while (hpi6000_check_PCI2040_error_flag(pao, H6WRITE)
- && --time_out);
-
- if (!time_out)
- break;
- pdata += xfer_size;
- local_hpi_address += sizeof(u32) * xfer_size;
- local_count -= xfer_size;
- }
-
- if (time_out)
- return 0;
- else
- return 1;
-}
-
-static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao,
- u16 dsp_index, u32 hpi_address, u32 *dest, u32 count)
-{
- struct hpi_hw_obj *phw = pao->priv;
- struct dsp_obj *pdo = &phw->ado[dsp_index];
- u32 time_out = PCI_TIMEOUT;
- int c6711_burst_size = 16;
- u32 local_hpi_address = hpi_address;
- int local_count = count;
- int xfer_size;
- u32 *pdata = dest;
- u32 loop_count = 0;
-
- while (local_count) {
- if (local_count > c6711_burst_size)
- xfer_size = c6711_burst_size;
- else
- xfer_size = local_count;
-
- time_out = PCI_TIMEOUT;
- do {
- hpi_read_block(pdo, local_hpi_address, pdata,
- xfer_size);
- } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
- && --time_out);
- if (!time_out)
- break;
-
- pdata += xfer_size;
- local_hpi_address += sizeof(u32) * xfer_size;
- local_count -= xfer_size;
- loop_count++;
- }
-
- if (time_out)
- return 0;
- else
- return 1;
-}
-
-static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
- u16 dsp_index, struct hpi_message *phm, struct hpi_response *phr)
-{
- struct hpi_hw_obj *phw = pao->priv;
- struct dsp_obj *pdo = &phw->ado[dsp_index];
- u32 timeout;
- u16 ack;
- u32 address;
- u32 length;
- u32 *p_data;
- u16 error = 0;
-
- ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
- if (ack & HPI_HIF_ERROR_MASK) {
- pao->dsp_crashed++;
- return HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT;
- }
- pao->dsp_crashed = 0;
-
- /* get the message address and size */
- if (phw->message_buffer_address_on_dsp == 0) {
- timeout = TIMEOUT;
- do {
- address =
- hpi_read_word(pdo,
- HPI_HIF_ADDR(message_buffer_address));
- phw->message_buffer_address_on_dsp = address;
- } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
- && --timeout);
- if (!timeout)
- return HPI6000_ERROR_MSG_GET_ADR;
- } else
- address = phw->message_buffer_address_on_dsp;
-
- length = phm->size;
-
- /* send the message */
- p_data = (u32 *)phm;
- if (hpi6000_dsp_block_write32(pao, dsp_index, address, p_data,
- (u16)length / 4))
- return HPI6000_ERROR_MSG_RESP_BLOCKWRITE32;
-
- if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_GET_RESP))
- return HPI6000_ERROR_MSG_RESP_GETRESPCMD;
- hpi6000_send_dsp_interrupt(pdo);
-
- ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_GET_RESP);
- if (ack & HPI_HIF_ERROR_MASK)
- return HPI6000_ERROR_MSG_RESP_GET_RESP_ACK;
-
- /* get the response address */
- if (phw->response_buffer_address_on_dsp == 0) {
- timeout = TIMEOUT;
- do {
- address =
- hpi_read_word(pdo,
- HPI_HIF_ADDR(response_buffer_address));
- } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
- && --timeout);
- phw->response_buffer_address_on_dsp = address;
-
- if (!timeout)
- return HPI6000_ERROR_RESP_GET_ADR;
- } else
- address = phw->response_buffer_address_on_dsp;
-
- /* read the length of the response back from the DSP */
- timeout = TIMEOUT;
- do {
- length = hpi_read_word(pdo, HPI_HIF_ADDR(length));
- } while (hpi6000_check_PCI2040_error_flag(pao, H6READ) && --timeout);
- if (!timeout)
- length = sizeof(struct hpi_response);
-
- /* get the response */
- p_data = (u32 *)phr;
- if (hpi6000_dsp_block_read32(pao, dsp_index, address, p_data,
- (u16)length / 4))
- return HPI6000_ERROR_MSG_RESP_BLOCKREAD32;
-
- /* set i/f back to idle */
- if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE))
- return HPI6000_ERROR_MSG_RESP_IDLECMD;
- hpi6000_send_dsp_interrupt(pdo);
-
- error = hpi_validate_response(phm, phr);
- return error;
-}
-
-/* have to set up the below defines to match stuff in the MAP file */
-
-#define MSG_ADDRESS (HPI_HIF_BASE+0x18)
-#define MSG_LENGTH 11
-#define RESP_ADDRESS (HPI_HIF_BASE+0x44)
-#define RESP_LENGTH 16
-#define QUEUE_START (HPI_HIF_BASE+0x88)
-#define QUEUE_SIZE 0x8000
-
-static short hpi6000_send_data_check_adr(u32 address, u32 length_in_dwords)
-{
-/*#define CHECKING // comment this line in to enable checking */
-#ifdef CHECKING
- if (address < (u32)MSG_ADDRESS)
- return 0;
- if (address > (u32)(QUEUE_START + QUEUE_SIZE))
- return 0;
- if ((address + (length_in_dwords << 2)) >
- (u32)(QUEUE_START + QUEUE_SIZE))
- return 0;
-#else
- (void)address;
- (void)length_in_dwords;
- return 1;
-#endif
-}
-
-static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- struct hpi_hw_obj *phw = pao->priv;
- struct dsp_obj *pdo = &phw->ado[dsp_index];
- u32 data_sent = 0;
- u16 ack;
- u32 length, address;
- u32 *p_data = (u32 *)phm->u.d.u.data.pb_data;
- u16 time_out = 8;
-
- (void)phr;
-
- /* round dwDataSize down to nearest 4 bytes */
- while ((data_sent < (phm->u.d.u.data.data_size & ~3L))
- && --time_out) {
- ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
- if (ack & HPI_HIF_ERROR_MASK)
- return HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT;
-
- if (hpi6000_send_host_command(pao, dsp_index,
- HPI_HIF_SEND_DATA))
- return HPI6000_ERROR_SEND_DATA_CMD;
-
- hpi6000_send_dsp_interrupt(pdo);
-
- ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_SEND_DATA);
-
- if (ack & HPI_HIF_ERROR_MASK)
- return HPI6000_ERROR_SEND_DATA_ACK;
-
- do {
- /* get the address and size */
- address = hpi_read_word(pdo, HPI_HIF_ADDR(address));
- /* DSP returns number of DWORDS */
- length = hpi_read_word(pdo, HPI_HIF_ADDR(length));
- } while (hpi6000_check_PCI2040_error_flag(pao, H6READ));
-
- if (!hpi6000_send_data_check_adr(address, length))
- return HPI6000_ERROR_SEND_DATA_ADR;
-
- /* send the data. break data into 512 DWORD blocks (2K bytes)
- * and send using block write. 2Kbytes is the max as this is the
- * memory window given to the HPI data register by the PCI2040
- */
-
- {
- u32 len = length;
- u32 blk_len = 512;
- while (len) {
- if (len < blk_len)
- blk_len = len;
- if (hpi6000_dsp_block_write32(pao, dsp_index,
- address, p_data, blk_len))
- return HPI6000_ERROR_SEND_DATA_WRITE;
- address += blk_len * 4;
- p_data += blk_len;
- len -= blk_len;
- }
- }
-
- if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE))
- return HPI6000_ERROR_SEND_DATA_IDLECMD;
-
- hpi6000_send_dsp_interrupt(pdo);
-
- data_sent += length * 4;
- }
- if (!time_out)
- return HPI6000_ERROR_SEND_DATA_TIMEOUT;
- return 0;
-}
-
-static short hpi6000_get_data(struct hpi_adapter_obj *pao, u16 dsp_index,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- struct hpi_hw_obj *phw = pao->priv;
- struct dsp_obj *pdo = &phw->ado[dsp_index];
- u32 data_got = 0;
- u16 ack;
- u32 length, address;
- u32 *p_data = (u32 *)phm->u.d.u.data.pb_data;
-
- (void)phr; /* this parameter not used! */
-
- /* round dwDataSize down to nearest 4 bytes */
- while (data_got < (phm->u.d.u.data.data_size & ~3L)) {
- ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
- if (ack & HPI_HIF_ERROR_MASK)
- return HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT;
-
- if (hpi6000_send_host_command(pao, dsp_index,
- HPI_HIF_GET_DATA))
- return HPI6000_ERROR_GET_DATA_CMD;
- hpi6000_send_dsp_interrupt(pdo);
-
- ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_GET_DATA);
-
- if (ack & HPI_HIF_ERROR_MASK)
- return HPI6000_ERROR_GET_DATA_ACK;
-
- /* get the address and size */
- do {
- address = hpi_read_word(pdo, HPI_HIF_ADDR(address));
- length = hpi_read_word(pdo, HPI_HIF_ADDR(length));
- } while (hpi6000_check_PCI2040_error_flag(pao, H6READ));
-
- /* read the data */
- {
- u32 len = length;
- u32 blk_len = 512;
- while (len) {
- if (len < blk_len)
- blk_len = len;
- if (hpi6000_dsp_block_read32(pao, dsp_index,
- address, p_data, blk_len))
- return HPI6000_ERROR_GET_DATA_READ;
- address += blk_len * 4;
- p_data += blk_len;
- len -= blk_len;
- }
- }
-
- if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE))
- return HPI6000_ERROR_GET_DATA_IDLECMD;
- hpi6000_send_dsp_interrupt(pdo);
-
- data_got += length * 4;
- }
- return 0;
-}
-
-static void hpi6000_send_dsp_interrupt(struct dsp_obj *pdo)
-{
- iowrite32(0x00030003, pdo->prHPI_control); /* DSPINT */
-}
-
-static short hpi6000_send_host_command(struct hpi_adapter_obj *pao,
- u16 dsp_index, u32 host_cmd)
-{
- struct hpi_hw_obj *phw = pao->priv;
- struct dsp_obj *pdo = &phw->ado[dsp_index];
- u32 timeout = TIMEOUT;
-
- /* set command */
- do {
- hpi_write_word(pdo, HPI_HIF_ADDR(host_cmd), host_cmd);
- /* flush the FIFO */
- hpi_set_address(pdo, HPI_HIF_ADDR(host_cmd));
- } while (hpi6000_check_PCI2040_error_flag(pao, H6WRITE) && --timeout);
-
- /* reset the interrupt bit */
- iowrite32(0x00040004, pdo->prHPI_control);
-
- if (timeout)
- return 0;
- else
- return 1;
-}
-
-/* if the PCI2040 has recorded an HPI timeout, reset the error and return 1 */
-static short hpi6000_check_PCI2040_error_flag(struct hpi_adapter_obj *pao,
- u16 read_or_write)
-{
- u32 hPI_error;
-
- struct hpi_hw_obj *phw = pao->priv;
-
- /* read the error bits from the PCI2040 */
- hPI_error = ioread32(phw->dw2040_HPICSR + HPI_ERROR_REPORT);
- if (hPI_error) {
- /* reset the error flag */
- iowrite32(0L, phw->dw2040_HPICSR + HPI_ERROR_REPORT);
- phw->pCI2040HPI_error_count++;
- if (read_or_write == 1)
- gw_pci_read_asserts++; /************* inc global */
- else
- gw_pci_write_asserts++;
- return 1;
- } else
- return 0;
-}
-
-static short hpi6000_wait_dsp_ack(struct hpi_adapter_obj *pao, u16 dsp_index,
- u32 ack_value)
-{
- struct hpi_hw_obj *phw = pao->priv;
- struct dsp_obj *pdo = &phw->ado[dsp_index];
- u32 ack = 0L;
- u32 timeout;
- u32 hPIC = 0L;
-
- /* wait for host interrupt to signal ack is ready */
- timeout = TIMEOUT;
- while (--timeout) {
- hPIC = ioread32(pdo->prHPI_control);
- if (hPIC & 0x04) /* 0x04 = HINT from DSP */
- break;
- }
- if (timeout == 0)
- return HPI_HIF_ERROR_MASK;
-
- /* wait for dwAckValue */
- timeout = TIMEOUT;
- while (--timeout) {
- /* read the ack mailbox */
- ack = hpi_read_word(pdo, HPI_HIF_ADDR(dsp_ack));
- if (ack == ack_value)
- break;
- if ((ack & HPI_HIF_ERROR_MASK)
- && !hpi6000_check_PCI2040_error_flag(pao, H6READ))
- break;
- /*for (i=0;i<1000;i++) */
- /* dwPause=i+1; */
- }
- if (ack & HPI_HIF_ERROR_MASK)
- /* indicates bad read from DSP -
- typically 0xffffff is read for some reason */
- ack = HPI_HIF_ERROR_MASK;
-
- if (timeout == 0)
- ack = HPI_HIF_ERROR_MASK;
- return (short)ack;
-}
-
-static short hpi6000_update_control_cache(struct hpi_adapter_obj *pao,
- struct hpi_message *phm)
-{
- const u16 dsp_index = 0;
- struct hpi_hw_obj *phw = pao->priv;
- struct dsp_obj *pdo = &phw->ado[dsp_index];
- u32 timeout;
- u32 cache_dirty_flag;
- u16 err;
-
- hpios_dsplock_lock(pao);
-
- timeout = TIMEOUT;
- do {
- cache_dirty_flag =
- hpi_read_word((struct dsp_obj *)pdo,
- HPI_HIF_ADDR(control_cache_is_dirty));
- } while (hpi6000_check_PCI2040_error_flag(pao, H6READ) && --timeout);
- if (!timeout) {
- err = HPI6000_ERROR_CONTROL_CACHE_PARAMS;
- goto unlock;
- }
-
- if (cache_dirty_flag) {
- /* read the cached controls */
- u32 address;
- u32 length;
-
- timeout = TIMEOUT;
- if (pdo->control_cache_address_on_dsp == 0) {
- do {
- address =
- hpi_read_word((struct dsp_obj *)pdo,
- HPI_HIF_ADDR(control_cache_address));
-
- length = hpi_read_word((struct dsp_obj *)pdo,
- HPI_HIF_ADDR
- (control_cache_size_in_bytes));
- } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
- && --timeout);
- if (!timeout) {
- err = HPI6000_ERROR_CONTROL_CACHE_ADDRLEN;
- goto unlock;
- }
- pdo->control_cache_address_on_dsp = address;
- pdo->control_cache_length_on_dsp = length;
- } else {
- address = pdo->control_cache_address_on_dsp;
- length = pdo->control_cache_length_on_dsp;
- }
-
- if (hpi6000_dsp_block_read32(pao, dsp_index, address,
- (u32 *)&phw->control_cache[0],
- length / sizeof(u32))) {
- err = HPI6000_ERROR_CONTROL_CACHE_READ;
- goto unlock;
- }
- do {
- hpi_write_word((struct dsp_obj *)pdo,
- HPI_HIF_ADDR(control_cache_is_dirty), 0);
- /* flush the FIFO */
- hpi_set_address(pdo, HPI_HIF_ADDR(host_cmd));
- } while (hpi6000_check_PCI2040_error_flag(pao, H6WRITE)
- && --timeout);
- if (!timeout) {
- err = HPI6000_ERROR_CONTROL_CACHE_FLUSH;
- goto unlock;
- }
-
- }
- err = 0;
-
-unlock:
- hpios_dsplock_unlock(pao);
- return err;
-}
-
-/** Get dsp index for multi DSP adapters only */
-static u16 get_dsp_index(struct hpi_adapter_obj *pao, struct hpi_message *phm)
-{
- u16 ret = 0;
- switch (phm->object) {
- case HPI_OBJ_ISTREAM:
- if (phm->obj_index < 2)
- ret = 1;
- break;
- case HPI_OBJ_PROFILE:
- ret = phm->obj_index;
- break;
- default:
- break;
- }
- return ret;
-}
-
-/** Complete transaction with DSP
-
-Send message, get response, send or get stream data if any.
-*/
-static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
- struct hpi_response *phr)
-{
- u16 error = 0;
- u16 dsp_index = 0;
- struct hpi_hw_obj *phw = pao->priv;
- u16 num_dsp = phw->num_dsp;
-
- if (num_dsp < 2)
- dsp_index = 0;
- else {
- dsp_index = get_dsp_index(pao, phm);
-
- /* is this checked on the DSP anyway? */
- if ((phm->function == HPI_ISTREAM_GROUP_ADD)
- || (phm->function == HPI_OSTREAM_GROUP_ADD)) {
- struct hpi_message hm;
- u16 add_index;
- hm.obj_index = phm->u.d.u.stream.stream_index;
- hm.object = phm->u.d.u.stream.object_type;
- add_index = get_dsp_index(pao, &hm);
- if (add_index != dsp_index) {
- phr->error = HPI_ERROR_NO_INTERDSP_GROUPS;
- return;
- }
- }
- }
-
- hpios_dsplock_lock(pao);
- error = hpi6000_message_response_sequence(pao, dsp_index, phm, phr);
-
- if (error) /* something failed in the HPI/DSP interface */
- goto err;
-
- if (phr->error) /* something failed in the DSP */
- goto out;
-
- switch (phm->function) {
- case HPI_OSTREAM_WRITE:
- case HPI_ISTREAM_ANC_WRITE:
- error = hpi6000_send_data(pao, dsp_index, phm, phr);
- break;
- case HPI_ISTREAM_READ:
- case HPI_OSTREAM_ANC_READ:
- error = hpi6000_get_data(pao, dsp_index, phm, phr);
- break;
- case HPI_ADAPTER_GET_ASSERT:
- phr->u.ax.assert.dsp_index = 0; /* dsp 0 default */
- if (num_dsp == 2) {
- if (!phr->u.ax.assert.count) {
- /* no assert from dsp 0, check dsp 1 */
- error = hpi6000_message_response_sequence(pao,
- 1, phm, phr);
- phr->u.ax.assert.dsp_index = 1;
- }
- }
- }
-
-err:
- if (error) {
- if (error >= HPI_ERROR_BACKEND_BASE) {
- phr->error = HPI_ERROR_DSP_COMMUNICATION;
- phr->specific_error = error;
- } else {
- phr->error = error;
- }
-
- /* just the header of the response is valid */
- phr->size = sizeof(struct hpi_response_header);
- }
-out:
- hpios_dsplock_unlock(pao);
- return;
-}
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpi6000.h b/ANDROID_3.4.5/sound/pci/asihpi/hpi6000.h
deleted file mode 100644
index 7e0deeff..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpi6000.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*****************************************************************************
-
- AudioScience HPI driver
- Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Public declarations for DSP Proramming Interface to TI C6701
-
-Shared between hpi6000.c and DSP code
-
-(C) Copyright AudioScience Inc. 1998-2003
-******************************************************************************/
-
-#ifndef _HPI6000_H_
-#define _HPI6000_H_
-
-#define HPI_NMIXER_CONTROLS 200
-
-/*
- * Control caching is always supported in the HPI code.
- * The DSP should make sure that dwControlCacheSizeInBytes is initialized to 0
- * during boot to make it in-active.
- */
-struct hpi_hif_6000 {
- u32 host_cmd;
- u32 dsp_ack;
- u32 address;
- u32 length;
- u32 message_buffer_address;
- u32 response_buffer_address;
- u32 dsp_number;
- u32 adapter_info;
- u32 control_cache_is_dirty;
- u32 control_cache_address;
- u32 control_cache_size_in_bytes;
- u32 control_cache_count;
-};
-
-#define HPI_HIF_PACK_ADAPTER_INFO(adapter, version_major, version_minor) \
- ((adapter << 16) | (version_major << 8) | version_minor)
-#define HPI_HIF_ADAPTER_INFO_EXTRACT_ADAPTER(adapterinfo) \
- ((adapterinfo >> 16) & 0xffff)
-#define HPI_HIF_ADAPTER_INFO_EXTRACT_HWVERSION_MAJOR(adapterinfo) \
- ((adapterinfo >> 8) & 0xff)
-#define HPI_HIF_ADAPTER_INFO_EXTRACT_HWVERSION_MINOR(adapterinfo) \
- (adapterinfo & 0xff)
-
-/* Command/status exchanged between host and DSP */
-#define HPI_HIF_IDLE 0
-#define HPI_HIF_SEND_MSG 1
-#define HPI_HIF_GET_RESP 2
-#define HPI_HIF_DATA_MASK 0x10
-#define HPI_HIF_SEND_DATA 0x13
-#define HPI_HIF_GET_DATA 0x14
-#define HPI_HIF_SEND_DONE 5
-#define HPI_HIF_RESET 9
-
-#endif /* _HPI6000_H_ */
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpi6205.c b/ANDROID_3.4.5/sound/pci/asihpi/hpi6205.c
deleted file mode 100644
index 4f287388..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpi6205.c
+++ /dev/null
@@ -1,2208 +0,0 @@
-/******************************************************************************
-
- AudioScience HPI driver
- Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- Hardware Programming Interface (HPI) for AudioScience
- ASI50xx, AS51xx, ASI6xxx, ASI87xx ASI89xx series adapters.
- These PCI and PCIe bus adapters are based on a
- TMS320C6205 PCI bus mastering DSP,
- and (except ASI50xx) TI TMS320C6xxx floating point DSP
-
- Exported function:
- void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
-
-(C) Copyright AudioScience Inc. 1998-2010
-*******************************************************************************/
-#define SOURCEFILE_NAME "hpi6205.c"
-
-#include "hpi_internal.h"
-#include "hpimsginit.h"
-#include "hpidebug.h"
-#include "hpi6205.h"
-#include "hpidspcd.h"
-#include "hpicmn.h"
-
-/*****************************************************************************/
-/* HPI6205 specific error codes */
-#define HPI6205_ERROR_BASE 1000 /* not actually used anywhere */
-
-/* operational/messaging errors */
-#define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT 1015
-#define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016
-
-/* initialization/bootload errors */
-#define HPI6205_ERROR_6205_NO_IRQ 1002
-#define HPI6205_ERROR_6205_INIT_FAILED 1003
-#define HPI6205_ERROR_6205_REG 1006
-#define HPI6205_ERROR_6205_DSPPAGE 1007
-#define HPI6205_ERROR_C6713_HPIC 1009
-#define HPI6205_ERROR_C6713_HPIA 1010
-#define HPI6205_ERROR_C6713_PLL 1011
-#define HPI6205_ERROR_DSP_INTMEM 1012
-#define HPI6205_ERROR_DSP_EXTMEM 1013
-#define HPI6205_ERROR_DSP_PLD 1014
-#define HPI6205_ERROR_6205_EEPROM 1017
-#define HPI6205_ERROR_DSP_EMIF1 1018
-#define HPI6205_ERROR_DSP_EMIF2 1019
-#define HPI6205_ERROR_DSP_EMIF3 1020
-#define HPI6205_ERROR_DSP_EMIF4 1021
-
-/*****************************************************************************/
-/* for C6205 PCI i/f */
-/* Host Status Register (HSR) bitfields */
-#define C6205_HSR_INTSRC 0x01
-#define C6205_HSR_INTAVAL 0x02
-#define C6205_HSR_INTAM 0x04
-#define C6205_HSR_CFGERR 0x08
-#define C6205_HSR_EEREAD 0x10
-/* Host-to-DSP Control Register (HDCR) bitfields */
-#define C6205_HDCR_WARMRESET 0x01
-#define C6205_HDCR_DSPINT 0x02
-#define C6205_HDCR_PCIBOOT 0x04
-/* DSP Page Register (DSPP) bitfields, */
-/* defines 4 Mbyte page that BAR0 points to */
-#define C6205_DSPP_MAP1 0x400
-
-/* BAR0 maps to prefetchable 4 Mbyte memory block set by DSPP.
- * BAR1 maps to non-prefetchable 8 Mbyte memory block
- * of DSP memory mapped registers (starting at 0x01800000).
- * 0x01800000 is hardcoded in the PCI i/f, so that only the offset from this
- * needs to be added to the BAR1 base address set in the PCI config reg
- */
-#define C6205_BAR1_PCI_IO_OFFSET (0x027FFF0L)
-#define C6205_BAR1_HSR (C6205_BAR1_PCI_IO_OFFSET)
-#define C6205_BAR1_HDCR (C6205_BAR1_PCI_IO_OFFSET+4)
-#define C6205_BAR1_DSPP (C6205_BAR1_PCI_IO_OFFSET+8)
-
-/* used to control LED (revA) and reset C6713 (revB) */
-#define C6205_BAR0_TIMER1_CTL (0x01980000L)
-
-/* For first 6713 in CE1 space, using DA17,16,2 */
-#define HPICL_ADDR 0x01400000L
-#define HPICH_ADDR 0x01400004L
-#define HPIAL_ADDR 0x01410000L
-#define HPIAH_ADDR 0x01410004L
-#define HPIDIL_ADDR 0x01420000L
-#define HPIDIH_ADDR 0x01420004L
-#define HPIDL_ADDR 0x01430000L
-#define HPIDH_ADDR 0x01430004L
-
-#define C6713_EMIF_GCTL 0x01800000
-#define C6713_EMIF_CE1 0x01800004
-#define C6713_EMIF_CE0 0x01800008
-#define C6713_EMIF_CE2 0x01800010
-#define C6713_EMIF_CE3 0x01800014
-#define C6713_EMIF_SDRAMCTL 0x01800018
-#define C6713_EMIF_SDRAMTIMING 0x0180001C
-#define C6713_EMIF_SDRAMEXT 0x01800020
-
-struct hpi_hw_obj {
- /* PCI registers */
- __iomem u32 *prHSR;
- __iomem u32 *prHDCR;
- __iomem u32 *prDSPP;
-
- u32 dsp_page;
-
- struct consistent_dma_area h_locked_mem;
- struct bus_master_interface *p_interface_buffer;
-
- u16 flag_outstream_just_reset[HPI_MAX_STREAMS];
- /* a non-NULL handle means there is an HPI allocated buffer */
- struct consistent_dma_area instream_host_buffers[HPI_MAX_STREAMS];
- struct consistent_dma_area outstream_host_buffers[HPI_MAX_STREAMS];
- /* non-zero size means a buffer exists, may be external */
- u32 instream_host_buffer_size[HPI_MAX_STREAMS];
- u32 outstream_host_buffer_size[HPI_MAX_STREAMS];
-
- struct consistent_dma_area h_control_cache;
- struct hpi_control_cache *p_cache;
-};
-
-/*****************************************************************************/
-/* local prototypes */
-
-#define check_before_bbm_copy(status, p_bbm_data, l_first_write, l_second_write)
-
-static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us);
-
-static void send_dsp_command(struct hpi_hw_obj *phw, int cmd);
-
-static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
- u32 *pos_error_code);
-
-static u16 message_response_sequence(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr);
-
-static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
- struct hpi_response *phr);
-
-#define HPI6205_TIMEOUT 1000000
-
-static void subsys_create_adapter(struct hpi_message *phm,
- struct hpi_response *phr);
-static void adapter_delete(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr);
-
-static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
- u32 *pos_error_code);
-
-static void delete_adapter_obj(struct hpi_adapter_obj *pao);
-
-static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr);
-
-static void outstream_host_buffer_get_info(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr);
-
-static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr);
-static void outstream_write(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr);
-
-static void outstream_get_info(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr);
-
-static void outstream_start(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr);
-
-static void outstream_open(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr);
-
-static void outstream_reset(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr);
-
-static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr);
-
-static void instream_host_buffer_get_info(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr);
-
-static void instream_host_buffer_free(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr);
-
-static void instream_read(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr);
-
-static void instream_get_info(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr);
-
-static void instream_start(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr);
-
-static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
- u32 address);
-
-static void boot_loader_write_mem32(struct hpi_adapter_obj *pao,
- int dsp_index, u32 address, u32 data);
-
-static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao,
- int dsp_index);
-
-static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
- u32 address, u32 length);
-
-static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
- int dsp_index);
-
-static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
- int dsp_index);
-
-static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index);
-
-/*****************************************************************************/
-
-static void subsys_message(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- switch (phm->function) {
- case HPI_SUBSYS_CREATE_ADAPTER:
- subsys_create_adapter(phm, phr);
- break;
- default:
- phr->error = HPI_ERROR_INVALID_FUNC;
- break;
- }
-}
-
-static void control_message(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
-
- struct hpi_hw_obj *phw = pao->priv;
- u16 pending_cache_error = 0;
-
- switch (phm->function) {
- case HPI_CONTROL_GET_STATE:
- if (pao->has_control_cache) {
- rmb(); /* make sure we see updates DMAed from DSP */
- if (hpi_check_control_cache(phw->p_cache, phm, phr)) {
- break;
- } else if (phm->u.c.attribute == HPI_METER_PEAK) {
- pending_cache_error =
- HPI_ERROR_CONTROL_CACHING;
- }
- }
- hw_message(pao, phm, phr);
- if (pending_cache_error && !phr->error)
- phr->error = pending_cache_error;
- break;
- case HPI_CONTROL_GET_INFO:
- hw_message(pao, phm, phr);
- break;
- case HPI_CONTROL_SET_STATE:
- hw_message(pao, phm, phr);
- if (pao->has_control_cache)
- hpi_cmn_control_cache_sync_to_msg(phw->p_cache, phm,
- phr);
- break;
- default:
- phr->error = HPI_ERROR_INVALID_FUNC;
- break;
- }
-}
-
-static void adapter_message(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- switch (phm->function) {
- case HPI_ADAPTER_DELETE:
- adapter_delete(pao, phm, phr);
- break;
-
- default:
- hw_message(pao, phm, phr);
- break;
- }
-}
-
-static void outstream_message(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
-
- if (phm->obj_index >= HPI_MAX_STREAMS) {
- phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
- HPI_DEBUG_LOG(WARNING,
- "Message referencing invalid stream %d "
- "on adapter index %d\n", phm->obj_index,
- phm->adapter_index);
- return;
- }
-
- switch (phm->function) {
- case HPI_OSTREAM_WRITE:
- outstream_write(pao, phm, phr);
- break;
- case HPI_OSTREAM_GET_INFO:
- outstream_get_info(pao, phm, phr);
- break;
- case HPI_OSTREAM_HOSTBUFFER_ALLOC:
- outstream_host_buffer_allocate(pao, phm, phr);
- break;
- case HPI_OSTREAM_HOSTBUFFER_GET_INFO:
- outstream_host_buffer_get_info(pao, phm, phr);
- break;
- case HPI_OSTREAM_HOSTBUFFER_FREE:
- outstream_host_buffer_free(pao, phm, phr);
- break;
- case HPI_OSTREAM_START:
- outstream_start(pao, phm, phr);
- break;
- case HPI_OSTREAM_OPEN:
- outstream_open(pao, phm, phr);
- break;
- case HPI_OSTREAM_RESET:
- outstream_reset(pao, phm, phr);
- break;
- default:
- hw_message(pao, phm, phr);
- break;
- }
-}
-
-static void instream_message(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
-
- if (phm->obj_index >= HPI_MAX_STREAMS) {
- phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
- HPI_DEBUG_LOG(WARNING,
- "Message referencing invalid stream %d "
- "on adapter index %d\n", phm->obj_index,
- phm->adapter_index);
- return;
- }
-
- switch (phm->function) {
- case HPI_ISTREAM_READ:
- instream_read(pao, phm, phr);
- break;
- case HPI_ISTREAM_GET_INFO:
- instream_get_info(pao, phm, phr);
- break;
- case HPI_ISTREAM_HOSTBUFFER_ALLOC:
- instream_host_buffer_allocate(pao, phm, phr);
- break;
- case HPI_ISTREAM_HOSTBUFFER_GET_INFO:
- instream_host_buffer_get_info(pao, phm, phr);
- break;
- case HPI_ISTREAM_HOSTBUFFER_FREE:
- instream_host_buffer_free(pao, phm, phr);
- break;
- case HPI_ISTREAM_START:
- instream_start(pao, phm, phr);
- break;
- default:
- hw_message(pao, phm, phr);
- break;
- }
-}
-
-/*****************************************************************************/
-/** Entry point to this HPI backend
- * All calls to the HPI start here
- */
-static
-void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
- struct hpi_response *phr)
-{
- if (pao && (pao->dsp_crashed >= 10)
- && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
- /* allow last resort debug read even after crash */
- hpi_init_response(phr, phm->object, phm->function,
- HPI_ERROR_DSP_HARDWARE);
- HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n", phm->object,
- phm->function);
- return;
- }
-
- /* Init default response */
- if (phm->function != HPI_SUBSYS_CREATE_ADAPTER)
- phr->error = HPI_ERROR_PROCESSING_MESSAGE;
-
- HPI_DEBUG_LOG(VERBOSE, "start of switch\n");
- switch (phm->type) {
- case HPI_TYPE_REQUEST:
- switch (phm->object) {
- case HPI_OBJ_SUBSYSTEM:
- subsys_message(pao, phm, phr);
- break;
-
- case HPI_OBJ_ADAPTER:
- adapter_message(pao, phm, phr);
- break;
-
- case HPI_OBJ_CONTROL:
- control_message(pao, phm, phr);
- break;
-
- case HPI_OBJ_OSTREAM:
- outstream_message(pao, phm, phr);
- break;
-
- case HPI_OBJ_ISTREAM:
- instream_message(pao, phm, phr);
- break;
-
- default:
- hw_message(pao, phm, phr);
- break;
- }
- break;
-
- default:
- phr->error = HPI_ERROR_INVALID_TYPE;
- break;
- }
-}
-
-void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
-{
- struct hpi_adapter_obj *pao = NULL;
-
- if (phm->object != HPI_OBJ_SUBSYSTEM) {
- /* normal messages must have valid adapter index */
- pao = hpi_find_adapter(phm->adapter_index);
- } else {
- /* subsys messages don't address an adapter */
- _HPI_6205(NULL, phm, phr);
- return;
- }
-
- if (pao)
- _HPI_6205(pao, phm, phr);
- else
- hpi_init_response(phr, phm->object, phm->function,
- HPI_ERROR_BAD_ADAPTER_NUMBER);
-}
-
-/*****************************************************************************/
-/* SUBSYSTEM */
-
-/** Create an adapter object and initialise it based on resource information
- * passed in in the message
- * *** NOTE - you cannot use this function AND the FindAdapters function at the
- * same time, the application must use only one of them to get the adapters ***
- */
-static void subsys_create_adapter(struct hpi_message *phm,
- struct hpi_response *phr)
-{
- /* create temp adapter obj, because we don't know what index yet */
- struct hpi_adapter_obj ao;
- u32 os_error_code;
- u16 err;
-
- HPI_DEBUG_LOG(DEBUG, " subsys_create_adapter\n");
-
- memset(&ao, 0, sizeof(ao));
-
- ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
- if (!ao.priv) {
- HPI_DEBUG_LOG(ERROR, "can't get mem for adapter object\n");
- phr->error = HPI_ERROR_MEMORY_ALLOC;
- return;
- }
-
- ao.pci = *phm->u.s.resource.r.pci;
- err = create_adapter_obj(&ao, &os_error_code);
- if (err) {
- delete_adapter_obj(&ao);
- if (err >= HPI_ERROR_BACKEND_BASE) {
- phr->error = HPI_ERROR_DSP_BOOTLOAD;
- phr->specific_error = err;
- } else {
- phr->error = err;
- }
- phr->u.s.data = os_error_code;
- return;
- }
-
- phr->u.s.adapter_type = ao.type;
- phr->u.s.adapter_index = ao.index;
- phr->error = 0;
-}
-
-/** delete an adapter - required by WDM driver */
-static void adapter_delete(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- struct hpi_hw_obj *phw;
-
- if (!pao) {
- phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
- return;
- }
- phw = pao->priv;
- /* reset adapter h/w */
- /* Reset C6713 #1 */
- boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0);
- /* reset C6205 */
- iowrite32(C6205_HDCR_WARMRESET, phw->prHDCR);
-
- delete_adapter_obj(pao);
- hpi_delete_adapter(pao);
- phr->error = 0;
-}
-
-/** Create adapter object
- allocate buffers, bootload DSPs, initialise control cache
-*/
-static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
- u32 *pos_error_code)
-{
- struct hpi_hw_obj *phw = pao->priv;
- struct bus_master_interface *interface;
- u32 phys_addr;
- int i;
- u16 err;
-
- /* init error reporting */
- pao->dsp_crashed = 0;
-
- for (i = 0; i < HPI_MAX_STREAMS; i++)
- phw->flag_outstream_just_reset[i] = 1;
-
- /* The C6205 memory area 1 is 8Mbyte window into DSP registers */
- phw->prHSR =
- pao->pci.ap_mem_base[1] +
- C6205_BAR1_HSR / sizeof(*pao->pci.ap_mem_base[1]);
- phw->prHDCR =
- pao->pci.ap_mem_base[1] +
- C6205_BAR1_HDCR / sizeof(*pao->pci.ap_mem_base[1]);
- phw->prDSPP =
- pao->pci.ap_mem_base[1] +
- C6205_BAR1_DSPP / sizeof(*pao->pci.ap_mem_base[1]);
-
- pao->has_control_cache = 0;
-
- if (hpios_locked_mem_alloc(&phw->h_locked_mem,
- sizeof(struct bus_master_interface),
- pao->pci.pci_dev))
- phw->p_interface_buffer = NULL;
- else if (hpios_locked_mem_get_virt_addr(&phw->h_locked_mem,
- (void *)&phw->p_interface_buffer))
- phw->p_interface_buffer = NULL;
-
- HPI_DEBUG_LOG(DEBUG, "interface buffer address %p\n",
- phw->p_interface_buffer);
-
- if (phw->p_interface_buffer) {
- memset((void *)phw->p_interface_buffer, 0,
- sizeof(struct bus_master_interface));
- phw->p_interface_buffer->dsp_ack = H620_HIF_UNKNOWN;
- }
-
- err = adapter_boot_load_dsp(pao, pos_error_code);
- if (err) {
- HPI_DEBUG_LOG(ERROR, "DSP code load failed\n");
- /* no need to clean up as SubSysCreateAdapter */
- /* calls DeleteAdapter on error. */
- return err;
- }
- HPI_DEBUG_LOG(INFO, "load DSP code OK\n");
-
- /* allow boot load even if mem alloc wont work */
- if (!phw->p_interface_buffer)
- return HPI_ERROR_MEMORY_ALLOC;
-
- interface = phw->p_interface_buffer;
-
- /* make sure the DSP has started ok */
- if (!wait_dsp_ack(phw, H620_HIF_RESET, HPI6205_TIMEOUT * 10)) {
- HPI_DEBUG_LOG(ERROR, "timed out waiting reset state \n");
- return HPI6205_ERROR_6205_INIT_FAILED;
- }
- /* Note that *pao, *phw are zeroed after allocation,
- * so pointers and flags are NULL by default.
- * Allocate bus mastering control cache buffer and tell the DSP about it
- */
- if (interface->control_cache.number_of_controls) {
- u8 *p_control_cache_virtual;
-
- err = hpios_locked_mem_alloc(&phw->h_control_cache,
- interface->control_cache.size_in_bytes,
- pao->pci.pci_dev);
- if (!err)
- err = hpios_locked_mem_get_virt_addr(&phw->
- h_control_cache,
- (void *)&p_control_cache_virtual);
- if (!err) {
- memset(p_control_cache_virtual, 0,
- interface->control_cache.size_in_bytes);
-
- phw->p_cache =
- hpi_alloc_control_cache(interface->
- control_cache.number_of_controls,
- interface->control_cache.size_in_bytes,
- p_control_cache_virtual);
-
- if (!phw->p_cache)
- err = HPI_ERROR_MEMORY_ALLOC;
- }
- if (!err) {
- err = hpios_locked_mem_get_phys_addr(&phw->
- h_control_cache, &phys_addr);
- interface->control_cache.physical_address32 =
- phys_addr;
- }
-
- if (!err)
- pao->has_control_cache = 1;
- else {
- if (hpios_locked_mem_valid(&phw->h_control_cache))
- hpios_locked_mem_free(&phw->h_control_cache);
- pao->has_control_cache = 0;
- }
- }
- send_dsp_command(phw, H620_HIF_IDLE);
-
- {
- struct hpi_message hm;
- struct hpi_response hr;
- u32 max_streams;
-
- HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n");
- memset(&hm, 0, sizeof(hm));
- /* wAdapterIndex == version == 0 */
- hm.type = HPI_TYPE_REQUEST;
- hm.size = sizeof(hm);
- hm.object = HPI_OBJ_ADAPTER;
- hm.function = HPI_ADAPTER_GET_INFO;
-
- memset(&hr, 0, sizeof(hr));
- hr.size = sizeof(hr);
-
- err = message_response_sequence(pao, &hm, &hr);
- if (err) {
- HPI_DEBUG_LOG(ERROR, "message transport error %d\n",
- err);
- return err;
- }
- if (hr.error)
- return hr.error;
-
- pao->type = hr.u.ax.info.adapter_type;
- pao->index = hr.u.ax.info.adapter_index;
-
- max_streams =
- hr.u.ax.info.num_outstreams +
- hr.u.ax.info.num_instreams;
-
- HPI_DEBUG_LOG(VERBOSE,
- "got adapter info type %x index %d serial %d\n",
- hr.u.ax.info.adapter_type, hr.u.ax.info.adapter_index,
- hr.u.ax.info.serial_number);
- }
-
- if (phw->p_cache)
- phw->p_cache->adap_idx = pao->index;
-
- HPI_DEBUG_LOG(INFO, "bootload DSP OK\n");
-
- return hpi_add_adapter(pao);
-}
-
-/** Free memory areas allocated by adapter
- * this routine is called from AdapterDelete,
- * and SubSysCreateAdapter if duplicate index
-*/
-static void delete_adapter_obj(struct hpi_adapter_obj *pao)
-{
- struct hpi_hw_obj *phw = pao->priv;
- int i;
-
- if (hpios_locked_mem_valid(&phw->h_control_cache)) {
- hpios_locked_mem_free(&phw->h_control_cache);
- hpi_free_control_cache(phw->p_cache);
- }
-
- if (hpios_locked_mem_valid(&phw->h_locked_mem)) {
- hpios_locked_mem_free(&phw->h_locked_mem);
- phw->p_interface_buffer = NULL;
- }
-
- for (i = 0; i < HPI_MAX_STREAMS; i++)
- if (hpios_locked_mem_valid(&phw->instream_host_buffers[i])) {
- hpios_locked_mem_free(&phw->instream_host_buffers[i]);
- /*?phw->InStreamHostBuffers[i] = NULL; */
- phw->instream_host_buffer_size[i] = 0;
- }
-
- for (i = 0; i < HPI_MAX_STREAMS; i++)
- if (hpios_locked_mem_valid(&phw->outstream_host_buffers[i])) {
- hpios_locked_mem_free(&phw->outstream_host_buffers
- [i]);
- phw->outstream_host_buffer_size[i] = 0;
- }
- kfree(phw);
-}
-
-/*****************************************************************************/
-/* Adapter functions */
-
-/*****************************************************************************/
-/* OutStream Host buffer functions */
-
-/** Allocate or attach buffer for busmastering
-*/
-static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- u16 err = 0;
- u32 command = phm->u.d.u.buffer.command;
- struct hpi_hw_obj *phw = pao->priv;
- struct bus_master_interface *interface = phw->p_interface_buffer;
-
- hpi_init_response(phr, phm->object, phm->function, 0);
-
- if (command == HPI_BUFFER_CMD_EXTERNAL
- || command == HPI_BUFFER_CMD_INTERNAL_ALLOC) {
- /* ALLOC phase, allocate a buffer with power of 2 size,
- get its bus address for PCI bus mastering
- */
- phm->u.d.u.buffer.buffer_size =
- roundup_pow_of_two(phm->u.d.u.buffer.buffer_size);
- /* return old size and allocated size,
- so caller can detect change */
- phr->u.d.u.stream_info.data_available =
- phw->outstream_host_buffer_size[phm->obj_index];
- phr->u.d.u.stream_info.buffer_size =
- phm->u.d.u.buffer.buffer_size;
-
- if (phw->outstream_host_buffer_size[phm->obj_index] ==
- phm->u.d.u.buffer.buffer_size) {
- /* Same size, no action required */
- return;
- }
-
- if (hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
- obj_index]))
- hpios_locked_mem_free(&phw->outstream_host_buffers
- [phm->obj_index]);
-
- err = hpios_locked_mem_alloc(&phw->outstream_host_buffers
- [phm->obj_index], phm->u.d.u.buffer.buffer_size,
- pao->pci.pci_dev);
-
- if (err) {
- phr->error = HPI_ERROR_INVALID_DATASIZE;
- phw->outstream_host_buffer_size[phm->obj_index] = 0;
- return;
- }
-
- err = hpios_locked_mem_get_phys_addr
- (&phw->outstream_host_buffers[phm->obj_index],
- &phm->u.d.u.buffer.pci_address);
- /* get the phys addr into msg for single call alloc caller
- * needs to do this for split alloc (or use the same message)
- * return the phy address for split alloc in the respose too
- */
- phr->u.d.u.stream_info.auxiliary_data_available =
- phm->u.d.u.buffer.pci_address;
-
- if (err) {
- hpios_locked_mem_free(&phw->outstream_host_buffers
- [phm->obj_index]);
- phw->outstream_host_buffer_size[phm->obj_index] = 0;
- phr->error = HPI_ERROR_MEMORY_ALLOC;
- return;
- }
- }
-
- if (command == HPI_BUFFER_CMD_EXTERNAL
- || command == HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER) {
- /* GRANT phase. Set up the BBM status, tell the DSP about
- the buffer so it can start using BBM.
- */
- struct hpi_hostbuffer_status *status;
-
- if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
- buffer_size - 1)) {
- HPI_DEBUG_LOG(ERROR,
- "Buffer size must be 2^N not %d\n",
- phm->u.d.u.buffer.buffer_size);
- phr->error = HPI_ERROR_INVALID_DATASIZE;
- return;
- }
- phw->outstream_host_buffer_size[phm->obj_index] =
- phm->u.d.u.buffer.buffer_size;
- status = &interface->outstream_host_buffer_status[phm->
- obj_index];
- status->samples_processed = 0;
- status->stream_state = HPI_STATE_STOPPED;
- status->dsp_index = 0;
- status->host_index = status->dsp_index;
- status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
- status->auxiliary_data_available = 0;
-
- hw_message(pao, phm, phr);
-
- if (phr->error
- && hpios_locked_mem_valid(&phw->
- outstream_host_buffers[phm->obj_index])) {
- hpios_locked_mem_free(&phw->outstream_host_buffers
- [phm->obj_index]);
- phw->outstream_host_buffer_size[phm->obj_index] = 0;
- }
- }
-}
-
-static void outstream_host_buffer_get_info(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- struct hpi_hw_obj *phw = pao->priv;
- struct bus_master_interface *interface = phw->p_interface_buffer;
- struct hpi_hostbuffer_status *status;
- u8 *p_bbm_data;
-
- if (hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
- obj_index])) {
- if (hpios_locked_mem_get_virt_addr(&phw->
- outstream_host_buffers[phm->obj_index],
- (void *)&p_bbm_data)) {
- phr->error = HPI_ERROR_INVALID_OPERATION;
- return;
- }
- status = &interface->outstream_host_buffer_status[phm->
- obj_index];
- hpi_init_response(phr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_HOSTBUFFER_GET_INFO, 0);
- phr->u.d.u.hostbuffer_info.p_buffer = p_bbm_data;
- phr->u.d.u.hostbuffer_info.p_status = status;
- } else {
- hpi_init_response(phr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_HOSTBUFFER_GET_INFO,
- HPI_ERROR_INVALID_OPERATION);
- }
-}
-
-static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- struct hpi_hw_obj *phw = pao->priv;
- u32 command = phm->u.d.u.buffer.command;
-
- if (phw->outstream_host_buffer_size[phm->obj_index]) {
- if (command == HPI_BUFFER_CMD_EXTERNAL
- || command == HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER) {
- phw->outstream_host_buffer_size[phm->obj_index] = 0;
- hw_message(pao, phm, phr);
- /* Tell adapter to stop using the host buffer. */
- }
- if (command == HPI_BUFFER_CMD_EXTERNAL
- || command == HPI_BUFFER_CMD_INTERNAL_FREE)
- hpios_locked_mem_free(&phw->outstream_host_buffers
- [phm->obj_index]);
- }
- /* Should HPI_ERROR_INVALID_OPERATION be returned
- if no host buffer is allocated? */
- else
- hpi_init_response(phr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_HOSTBUFFER_FREE, 0);
-
-}
-
-static u32 outstream_get_space_available(struct hpi_hostbuffer_status *status)
-{
- return status->size_in_bytes - (status->host_index -
- status->dsp_index);
-}
-
-static void outstream_write(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- struct hpi_hw_obj *phw = pao->priv;
- struct bus_master_interface *interface = phw->p_interface_buffer;
- struct hpi_hostbuffer_status *status;
- u32 space_available;
-
- if (!phw->outstream_host_buffer_size[phm->obj_index]) {
- /* there is no BBM buffer, write via message */
- hw_message(pao, phm, phr);
- return;
- }
-
- hpi_init_response(phr, phm->object, phm->function, 0);
- status = &interface->outstream_host_buffer_status[phm->obj_index];
-
- space_available = outstream_get_space_available(status);
- if (space_available < phm->u.d.u.data.data_size) {
- phr->error = HPI_ERROR_INVALID_DATASIZE;
- return;
- }
-
- /* HostBuffers is used to indicate host buffer is internally allocated.
- otherwise, assumed external, data written externally */
- if (phm->u.d.u.data.pb_data
- && hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
- obj_index])) {
- u8 *p_bbm_data;
- u32 l_first_write;
- u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data;
-
- if (hpios_locked_mem_get_virt_addr(&phw->
- outstream_host_buffers[phm->obj_index],
- (void *)&p_bbm_data)) {
- phr->error = HPI_ERROR_INVALID_OPERATION;
- return;
- }
-
- /* either all data,
- or enough to fit from current to end of BBM buffer */
- l_first_write =
- min(phm->u.d.u.data.data_size,
- status->size_in_bytes -
- (status->host_index & (status->size_in_bytes - 1)));
-
- memcpy(p_bbm_data +
- (status->host_index & (status->size_in_bytes - 1)),
- p_app_data, l_first_write);
- /* remaining data if any */
- memcpy(p_bbm_data, p_app_data + l_first_write,
- phm->u.d.u.data.data_size - l_first_write);
- }
-
- /*
- * This version relies on the DSP code triggering an OStream buffer
- * update immediately following a SET_FORMAT call. The host has
- * already written data into the BBM buffer, but the DSP won't know
- * about it until dwHostIndex is adjusted.
- */
- if (phw->flag_outstream_just_reset[phm->obj_index]) {
- /* Format can only change after reset. Must tell DSP. */
- u16 function = phm->function;
- phw->flag_outstream_just_reset[phm->obj_index] = 0;
- phm->function = HPI_OSTREAM_SET_FORMAT;
- hw_message(pao, phm, phr); /* send the format to the DSP */
- phm->function = function;
- if (phr->error)
- return;
- }
-
- status->host_index += phm->u.d.u.data.data_size;
-}
-
-static void outstream_get_info(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- struct hpi_hw_obj *phw = pao->priv;
- struct bus_master_interface *interface = phw->p_interface_buffer;
- struct hpi_hostbuffer_status *status;
-
- if (!phw->outstream_host_buffer_size[phm->obj_index]) {
- hw_message(pao, phm, phr);
- return;
- }
-
- hpi_init_response(phr, phm->object, phm->function, 0);
-
- status = &interface->outstream_host_buffer_status[phm->obj_index];
-
- phr->u.d.u.stream_info.state = (u16)status->stream_state;
- phr->u.d.u.stream_info.samples_transferred =
- status->samples_processed;
- phr->u.d.u.stream_info.buffer_size = status->size_in_bytes;
- phr->u.d.u.stream_info.data_available =
- status->size_in_bytes - outstream_get_space_available(status);
- phr->u.d.u.stream_info.auxiliary_data_available =
- status->auxiliary_data_available;
-}
-
-static void outstream_start(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- hw_message(pao, phm, phr);
-}
-
-static void outstream_reset(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- struct hpi_hw_obj *phw = pao->priv;
- phw->flag_outstream_just_reset[phm->obj_index] = 1;
- hw_message(pao, phm, phr);
-}
-
-static void outstream_open(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- outstream_reset(pao, phm, phr);
-}
-
-/*****************************************************************************/
-/* InStream Host buffer functions */
-
-static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- u16 err = 0;
- u32 command = phm->u.d.u.buffer.command;
- struct hpi_hw_obj *phw = pao->priv;
- struct bus_master_interface *interface = phw->p_interface_buffer;
-
- hpi_init_response(phr, phm->object, phm->function, 0);
-
- if (command == HPI_BUFFER_CMD_EXTERNAL
- || command == HPI_BUFFER_CMD_INTERNAL_ALLOC) {
-
- phm->u.d.u.buffer.buffer_size =
- roundup_pow_of_two(phm->u.d.u.buffer.buffer_size);
- phr->u.d.u.stream_info.data_available =
- phw->instream_host_buffer_size[phm->obj_index];
- phr->u.d.u.stream_info.buffer_size =
- phm->u.d.u.buffer.buffer_size;
-
- if (phw->instream_host_buffer_size[phm->obj_index] ==
- phm->u.d.u.buffer.buffer_size) {
- /* Same size, no action required */
- return;
- }
-
- if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
- obj_index]))
- hpios_locked_mem_free(&phw->instream_host_buffers
- [phm->obj_index]);
-
- err = hpios_locked_mem_alloc(&phw->instream_host_buffers[phm->
- obj_index], phm->u.d.u.buffer.buffer_size,
- pao->pci.pci_dev);
-
- if (err) {
- phr->error = HPI_ERROR_INVALID_DATASIZE;
- phw->instream_host_buffer_size[phm->obj_index] = 0;
- return;
- }
-
- err = hpios_locked_mem_get_phys_addr
- (&phw->instream_host_buffers[phm->obj_index],
- &phm->u.d.u.buffer.pci_address);
- /* get the phys addr into msg for single call alloc. Caller
- needs to do this for split alloc so return the phy address */
- phr->u.d.u.stream_info.auxiliary_data_available =
- phm->u.d.u.buffer.pci_address;
- if (err) {
- hpios_locked_mem_free(&phw->instream_host_buffers
- [phm->obj_index]);
- phw->instream_host_buffer_size[phm->obj_index] = 0;
- phr->error = HPI_ERROR_MEMORY_ALLOC;
- return;
- }
- }
-
- if (command == HPI_BUFFER_CMD_EXTERNAL
- || command == HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER) {
- struct hpi_hostbuffer_status *status;
-
- if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
- buffer_size - 1)) {
- HPI_DEBUG_LOG(ERROR,
- "Buffer size must be 2^N not %d\n",
- phm->u.d.u.buffer.buffer_size);
- phr->error = HPI_ERROR_INVALID_DATASIZE;
- return;
- }
-
- phw->instream_host_buffer_size[phm->obj_index] =
- phm->u.d.u.buffer.buffer_size;
- status = &interface->instream_host_buffer_status[phm->
- obj_index];
- status->samples_processed = 0;
- status->stream_state = HPI_STATE_STOPPED;
- status->dsp_index = 0;
- status->host_index = status->dsp_index;
- status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
- status->auxiliary_data_available = 0;
-
- hw_message(pao, phm, phr);
-
- if (phr->error
- && hpios_locked_mem_valid(&phw->
- instream_host_buffers[phm->obj_index])) {
- hpios_locked_mem_free(&phw->instream_host_buffers
- [phm->obj_index]);
- phw->instream_host_buffer_size[phm->obj_index] = 0;
- }
- }
-}
-
-static void instream_host_buffer_get_info(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- struct hpi_hw_obj *phw = pao->priv;
- struct bus_master_interface *interface = phw->p_interface_buffer;
- struct hpi_hostbuffer_status *status;
- u8 *p_bbm_data;
-
- if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
- obj_index])) {
- if (hpios_locked_mem_get_virt_addr(&phw->
- instream_host_buffers[phm->obj_index],
- (void *)&p_bbm_data)) {
- phr->error = HPI_ERROR_INVALID_OPERATION;
- return;
- }
- status = &interface->instream_host_buffer_status[phm->
- obj_index];
- hpi_init_response(phr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_HOSTBUFFER_GET_INFO, 0);
- phr->u.d.u.hostbuffer_info.p_buffer = p_bbm_data;
- phr->u.d.u.hostbuffer_info.p_status = status;
- } else {
- hpi_init_response(phr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_HOSTBUFFER_GET_INFO,
- HPI_ERROR_INVALID_OPERATION);
- }
-}
-
-static void instream_host_buffer_free(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- struct hpi_hw_obj *phw = pao->priv;
- u32 command = phm->u.d.u.buffer.command;
-
- if (phw->instream_host_buffer_size[phm->obj_index]) {
- if (command == HPI_BUFFER_CMD_EXTERNAL
- || command == HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER) {
- phw->instream_host_buffer_size[phm->obj_index] = 0;
- hw_message(pao, phm, phr);
- }
-
- if (command == HPI_BUFFER_CMD_EXTERNAL
- || command == HPI_BUFFER_CMD_INTERNAL_FREE)
- hpios_locked_mem_free(&phw->instream_host_buffers
- [phm->obj_index]);
-
- } else {
- /* Should HPI_ERROR_INVALID_OPERATION be returned
- if no host buffer is allocated? */
- hpi_init_response(phr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_HOSTBUFFER_FREE, 0);
-
- }
-
-}
-
-static void instream_start(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- hw_message(pao, phm, phr);
-}
-
-static u32 instream_get_bytes_available(struct hpi_hostbuffer_status *status)
-{
- return status->dsp_index - status->host_index;
-}
-
-static void instream_read(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- struct hpi_hw_obj *phw = pao->priv;
- struct bus_master_interface *interface = phw->p_interface_buffer;
- struct hpi_hostbuffer_status *status;
- u32 data_available;
- u8 *p_bbm_data;
- u32 l_first_read;
- u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data;
-
- if (!phw->instream_host_buffer_size[phm->obj_index]) {
- hw_message(pao, phm, phr);
- return;
- }
- hpi_init_response(phr, phm->object, phm->function, 0);
-
- status = &interface->instream_host_buffer_status[phm->obj_index];
- data_available = instream_get_bytes_available(status);
- if (data_available < phm->u.d.u.data.data_size) {
- phr->error = HPI_ERROR_INVALID_DATASIZE;
- return;
- }
-
- if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
- obj_index])) {
- if (hpios_locked_mem_get_virt_addr(&phw->
- instream_host_buffers[phm->obj_index],
- (void *)&p_bbm_data)) {
- phr->error = HPI_ERROR_INVALID_OPERATION;
- return;
- }
-
- /* either all data,
- or enough to fit from current to end of BBM buffer */
- l_first_read =
- min(phm->u.d.u.data.data_size,
- status->size_in_bytes -
- (status->host_index & (status->size_in_bytes - 1)));
-
- memcpy(p_app_data,
- p_bbm_data +
- (status->host_index & (status->size_in_bytes - 1)),
- l_first_read);
- /* remaining data if any */
- memcpy(p_app_data + l_first_read, p_bbm_data,
- phm->u.d.u.data.data_size - l_first_read);
- }
- status->host_index += phm->u.d.u.data.data_size;
-}
-
-static void instream_get_info(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- struct hpi_hw_obj *phw = pao->priv;
- struct bus_master_interface *interface = phw->p_interface_buffer;
- struct hpi_hostbuffer_status *status;
- if (!phw->instream_host_buffer_size[phm->obj_index]) {
- hw_message(pao, phm, phr);
- return;
- }
-
- status = &interface->instream_host_buffer_status[phm->obj_index];
-
- hpi_init_response(phr, phm->object, phm->function, 0);
-
- phr->u.d.u.stream_info.state = (u16)status->stream_state;
- phr->u.d.u.stream_info.samples_transferred =
- status->samples_processed;
- phr->u.d.u.stream_info.buffer_size = status->size_in_bytes;
- phr->u.d.u.stream_info.data_available =
- instream_get_bytes_available(status);
- phr->u.d.u.stream_info.auxiliary_data_available =
- status->auxiliary_data_available;
-}
-
-/*****************************************************************************/
-/* LOW-LEVEL */
-#define HPI6205_MAX_FILES_TO_LOAD 2
-
-static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
- u32 *pos_error_code)
-{
- struct hpi_hw_obj *phw = pao->priv;
- struct dsp_code dsp_code;
- u16 boot_code_id[HPI6205_MAX_FILES_TO_LOAD];
- u32 temp;
- int dsp = 0, i = 0;
- u16 err = 0;
-
- boot_code_id[0] = HPI_ADAPTER_ASI(0x6205);
-
- boot_code_id[1] = pao->pci.pci_dev->subsystem_device;
- boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(boot_code_id[1]);
-
- /* fix up cases where bootcode id[1] != subsys id */
- switch (boot_code_id[1]) {
- case HPI_ADAPTER_FAMILY_ASI(0x5000):
- boot_code_id[0] = boot_code_id[1];
- boot_code_id[1] = 0;
- break;
- case HPI_ADAPTER_FAMILY_ASI(0x5300):
- case HPI_ADAPTER_FAMILY_ASI(0x5400):
- case HPI_ADAPTER_FAMILY_ASI(0x6300):
- boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6400);
- break;
- case HPI_ADAPTER_FAMILY_ASI(0x5500):
- case HPI_ADAPTER_FAMILY_ASI(0x5600):
- case HPI_ADAPTER_FAMILY_ASI(0x6500):
- boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6600);
- break;
- case HPI_ADAPTER_FAMILY_ASI(0x8800):
- boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x8900);
- break;
- default:
- break;
- }
-
- /* reset DSP by writing a 1 to the WARMRESET bit */
- temp = C6205_HDCR_WARMRESET;
- iowrite32(temp, phw->prHDCR);
- hpios_delay_micro_seconds(1000);
-
- /* check that PCI i/f was configured by EEPROM */
- temp = ioread32(phw->prHSR);
- if ((temp & (C6205_HSR_CFGERR | C6205_HSR_EEREAD)) !=
- C6205_HSR_EEREAD)
- return HPI6205_ERROR_6205_EEPROM;
- temp |= 0x04;
- /* disable PINTA interrupt */
- iowrite32(temp, phw->prHSR);
-
- /* check control register reports PCI boot mode */
- temp = ioread32(phw->prHDCR);
- if (!(temp & C6205_HDCR_PCIBOOT))
- return HPI6205_ERROR_6205_REG;
-
- /* try writing a few numbers to the DSP page register */
- /* and reading them back. */
- temp = 3;
- iowrite32(temp, phw->prDSPP);
- if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
- return HPI6205_ERROR_6205_DSPPAGE;
- temp = 2;
- iowrite32(temp, phw->prDSPP);
- if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
- return HPI6205_ERROR_6205_DSPPAGE;
- temp = 1;
- iowrite32(temp, phw->prDSPP);
- if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
- return HPI6205_ERROR_6205_DSPPAGE;
- /* reset DSP page to the correct number */
- temp = 0;
- iowrite32(temp, phw->prDSPP);
- if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
- return HPI6205_ERROR_6205_DSPPAGE;
- phw->dsp_page = 0;
-
- /* release 6713 from reset before 6205 is bootloaded.
- This ensures that the EMIF is inactive,
- and the 6713 HPI gets the correct bootmode etc
- */
- if (boot_code_id[1] != 0) {
- /* DSP 1 is a C6713 */
- /* CLKX0 <- '1' release the C6205 bootmode pulldowns */
- boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002202);
- hpios_delay_micro_seconds(100);
- /* Reset the 6713 #1 - revB */
- boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0);
-
- /* dummy read every 4 words for 6205 advisory 1.4.4 */
- boot_loader_read_mem32(pao, 0, 0);
-
- hpios_delay_micro_seconds(100);
- /* Release C6713 from reset - revB */
- boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 4);
- hpios_delay_micro_seconds(100);
- }
-
- for (dsp = 0; dsp < HPI6205_MAX_FILES_TO_LOAD; dsp++) {
- /* is there a DSP to load? */
- if (boot_code_id[dsp] == 0)
- continue;
-
- err = boot_loader_config_emif(pao, dsp);
- if (err)
- return err;
-
- err = boot_loader_test_internal_memory(pao, dsp);
- if (err)
- return err;
-
- err = boot_loader_test_external_memory(pao, dsp);
- if (err)
- return err;
-
- err = boot_loader_test_pld(pao, dsp);
- if (err)
- return err;
-
- /* write the DSP code down into the DSPs memory */
- err = hpi_dsp_code_open(boot_code_id[dsp], pao->pci.pci_dev,
- &dsp_code, pos_error_code);
- if (err)
- return err;
-
- while (1) {
- u32 length;
- u32 address;
- u32 type;
- u32 *pcode;
-
- err = hpi_dsp_code_read_word(&dsp_code, &length);
- if (err)
- break;
- if (length == 0xFFFFFFFF)
- break; /* end of code */
-
- err = hpi_dsp_code_read_word(&dsp_code, &address);
- if (err)
- break;
- err = hpi_dsp_code_read_word(&dsp_code, &type);
- if (err)
- break;
- err = hpi_dsp_code_read_block(length, &dsp_code,
- &pcode);
- if (err)
- break;
- for (i = 0; i < (int)length; i++) {
- boot_loader_write_mem32(pao, dsp, address,
- *pcode);
- /* dummy read every 4 words */
- /* for 6205 advisory 1.4.4 */
- if (i % 4 == 0)
- boot_loader_read_mem32(pao, dsp,
- address);
- pcode++;
- address += 4;
- }
-
- }
- if (err) {
- hpi_dsp_code_close(&dsp_code);
- return err;
- }
-
- /* verify code */
- hpi_dsp_code_rewind(&dsp_code);
- while (1) {
- u32 length = 0;
- u32 address = 0;
- u32 type = 0;
- u32 *pcode = NULL;
- u32 data = 0;
-
- hpi_dsp_code_read_word(&dsp_code, &length);
- if (length == 0xFFFFFFFF)
- break; /* end of code */
-
- hpi_dsp_code_read_word(&dsp_code, &address);
- hpi_dsp_code_read_word(&dsp_code, &type);
- hpi_dsp_code_read_block(length, &dsp_code, &pcode);
-
- for (i = 0; i < (int)length; i++) {
- data = boot_loader_read_mem32(pao, dsp,
- address);
- if (data != *pcode) {
- err = 0;
- break;
- }
- pcode++;
- address += 4;
- }
- if (err)
- break;
- }
- hpi_dsp_code_close(&dsp_code);
- if (err)
- return err;
- }
-
- /* After bootloading all DSPs, start DSP0 running
- * The DSP0 code will handle starting and synchronizing with its slaves
- */
- if (phw->p_interface_buffer) {
- /* we need to tell the card the physical PCI address */
- u32 physicalPC_iaddress;
- struct bus_master_interface *interface =
- phw->p_interface_buffer;
- u32 host_mailbox_address_on_dsp;
- u32 physicalPC_iaddress_verify = 0;
- int time_out = 10;
- /* set ack so we know when DSP is ready to go */
- /* (dwDspAck will be changed to HIF_RESET) */
- interface->dsp_ack = H620_HIF_UNKNOWN;
- wmb(); /* ensure ack is written before dsp writes back */
-
- err = hpios_locked_mem_get_phys_addr(&phw->h_locked_mem,
- &physicalPC_iaddress);
-
- /* locate the host mailbox on the DSP. */
- host_mailbox_address_on_dsp = 0x80000000;
- while ((physicalPC_iaddress != physicalPC_iaddress_verify)
- && time_out--) {
- boot_loader_write_mem32(pao, 0,
- host_mailbox_address_on_dsp,
- physicalPC_iaddress);
- physicalPC_iaddress_verify =
- boot_loader_read_mem32(pao, 0,
- host_mailbox_address_on_dsp);
- }
- }
- HPI_DEBUG_LOG(DEBUG, "starting DS_ps running\n");
- /* enable interrupts */
- temp = ioread32(phw->prHSR);
- temp &= ~(u32)C6205_HSR_INTAM;
- iowrite32(temp, phw->prHSR);
-
- /* start code running... */
- temp = ioread32(phw->prHDCR);
- temp |= (u32)C6205_HDCR_DSPINT;
- iowrite32(temp, phw->prHDCR);
-
- /* give the DSP 10ms to start up */
- hpios_delay_micro_seconds(10000);
- return err;
-
-}
-
-/*****************************************************************************/
-/* Bootloader utility functions */
-
-static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
- u32 address)
-{
- struct hpi_hw_obj *phw = pao->priv;
- u32 data = 0;
- __iomem u32 *p_data;
-
- if (dsp_index == 0) {
- /* DSP 0 is always C6205 */
- if ((address >= 0x01800000) & (address < 0x02000000)) {
- /* BAR1 register access */
- p_data = pao->pci.ap_mem_base[1] +
- (address & 0x007fffff) /
- sizeof(*pao->pci.ap_mem_base[1]);
- /* HPI_DEBUG_LOG(WARNING,
- "BAR1 access %08x\n", dwAddress); */
- } else {
- u32 dw4M_page = address >> 22L;
- if (dw4M_page != phw->dsp_page) {
- phw->dsp_page = dw4M_page;
- /* *INDENT OFF* */
- iowrite32(phw->dsp_page, phw->prDSPP);
- /* *INDENT-ON* */
- }
- address &= 0x3fffff; /* address within 4M page */
- /* BAR0 memory access */
- p_data = pao->pci.ap_mem_base[0] +
- address / sizeof(u32);
- }
- data = ioread32(p_data);
- } else if (dsp_index == 1) {
- /* DSP 1 is a C6713 */
- u32 lsb;
- boot_loader_write_mem32(pao, 0, HPIAL_ADDR, address);
- boot_loader_write_mem32(pao, 0, HPIAH_ADDR, address >> 16);
- lsb = boot_loader_read_mem32(pao, 0, HPIDL_ADDR);
- data = boot_loader_read_mem32(pao, 0, HPIDH_ADDR);
- data = (data << 16) | (lsb & 0xFFFF);
- }
- return data;
-}
-
-static void boot_loader_write_mem32(struct hpi_adapter_obj *pao,
- int dsp_index, u32 address, u32 data)
-{
- struct hpi_hw_obj *phw = pao->priv;
- __iomem u32 *p_data;
- /* u32 dwVerifyData=0; */
-
- if (dsp_index == 0) {
- /* DSP 0 is always C6205 */
- if ((address >= 0x01800000) & (address < 0x02000000)) {
- /* BAR1 - DSP register access using */
- /* Non-prefetchable PCI access */
- p_data = pao->pci.ap_mem_base[1] +
- (address & 0x007fffff) /
- sizeof(*pao->pci.ap_mem_base[1]);
- } else {
- /* BAR0 access - all of DSP memory using */
- /* pre-fetchable PCI access */
- u32 dw4M_page = address >> 22L;
- if (dw4M_page != phw->dsp_page) {
- phw->dsp_page = dw4M_page;
- /* *INDENT-OFF* */
- iowrite32(phw->dsp_page, phw->prDSPP);
- /* *INDENT-ON* */
- }
- address &= 0x3fffff; /* address within 4M page */
- p_data = pao->pci.ap_mem_base[0] +
- address / sizeof(u32);
- }
- iowrite32(data, p_data);
- } else if (dsp_index == 1) {
- /* DSP 1 is a C6713 */
- boot_loader_write_mem32(pao, 0, HPIAL_ADDR, address);
- boot_loader_write_mem32(pao, 0, HPIAH_ADDR, address >> 16);
-
- /* dummy read every 4 words for 6205 advisory 1.4.4 */
- boot_loader_read_mem32(pao, 0, 0);
-
- boot_loader_write_mem32(pao, 0, HPIDL_ADDR, data);
- boot_loader_write_mem32(pao, 0, HPIDH_ADDR, data >> 16);
-
- /* dummy read every 4 words for 6205 advisory 1.4.4 */
- boot_loader_read_mem32(pao, 0, 0);
- }
-}
-
-static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
-{
- if (dsp_index == 0) {
- u32 setting;
-
- /* DSP 0 is always C6205 */
-
- /* Set the EMIF */
- /* memory map of C6205 */
- /* 00000000-0000FFFF 16Kx32 internal program */
- /* 00400000-00BFFFFF CE0 2Mx32 SDRAM running @ 100MHz */
-
- /* EMIF config */
- /*------------ */
- /* Global EMIF control */
- boot_loader_write_mem32(pao, dsp_index, 0x01800000, 0x3779);
-#define WS_OFS 28
-#define WST_OFS 22
-#define WH_OFS 20
-#define RS_OFS 16
-#define RST_OFS 8
-#define MTYPE_OFS 4
-#define RH_OFS 0
-
- /* EMIF CE0 setup - 2Mx32 Sync DRAM on ASI5000 cards only */
- setting = 0x00000030;
- boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting);
- if (setting != boot_loader_read_mem32(pao, dsp_index,
- 0x01800008))
- return HPI6205_ERROR_DSP_EMIF1;
-
- /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */
- /* which occupies D15..0. 6713 starts at 27MHz, so need */
- /* plenty of wait states. See dsn8701.rtf, and 6713 errata. */
- /* WST should be 71, but 63 is max possible */
- setting =
- (1L << WS_OFS) | (63L << WST_OFS) | (1L << WH_OFS) |
- (1L << RS_OFS) | (63L << RST_OFS) | (1L << RH_OFS) |
- (2L << MTYPE_OFS);
- boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting);
- if (setting != boot_loader_read_mem32(pao, dsp_index,
- 0x01800004))
- return HPI6205_ERROR_DSP_EMIF2;
-
- /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */
- /* which occupies D15..0. 6713 starts at 27MHz, so need */
- /* plenty of wait states */
- setting =
- (1L << WS_OFS) | (28L << WST_OFS) | (1L << WH_OFS) |
- (1L << RS_OFS) | (63L << RST_OFS) | (1L << RH_OFS) |
- (2L << MTYPE_OFS);
- boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting);
- if (setting != boot_loader_read_mem32(pao, dsp_index,
- 0x01800010))
- return HPI6205_ERROR_DSP_EMIF3;
-
- /* EMIF CE3 setup - 32 bit async. */
- /* This is the PLD on the ASI5000 cards only */
- setting =
- (1L << WS_OFS) | (10L << WST_OFS) | (1L << WH_OFS) |
- (1L << RS_OFS) | (10L << RST_OFS) | (1L << RH_OFS) |
- (2L << MTYPE_OFS);
- boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting);
- if (setting != boot_loader_read_mem32(pao, dsp_index,
- 0x01800014))
- return HPI6205_ERROR_DSP_EMIF4;
-
- /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */
- /* need to use this else DSP code crashes? */
- boot_loader_write_mem32(pao, dsp_index, 0x01800018,
- 0x07117000);
-
- /* EMIF SDRAM Refresh Timing */
- /* EMIF SDRAM timing (orig = 0x410, emulator = 0x61a) */
- boot_loader_write_mem32(pao, dsp_index, 0x0180001C,
- 0x00000410);
-
- } else if (dsp_index == 1) {
- /* test access to the C6713s HPI registers */
- u32 write_data = 0, read_data = 0, i = 0;
-
- /* Set up HPIC for little endian, by setiing HPIC:HWOB=1 */
- write_data = 1;
- boot_loader_write_mem32(pao, 0, HPICL_ADDR, write_data);
- boot_loader_write_mem32(pao, 0, HPICH_ADDR, write_data);
- /* C67 HPI is on lower 16bits of 32bit EMIF */
- read_data =
- 0xFFF7 & boot_loader_read_mem32(pao, 0, HPICL_ADDR);
- if (write_data != read_data) {
- HPI_DEBUG_LOG(ERROR, "HPICL %x %x\n", write_data,
- read_data);
- return HPI6205_ERROR_C6713_HPIC;
- }
- /* HPIA - walking ones test */
- write_data = 1;
- for (i = 0; i < 32; i++) {
- boot_loader_write_mem32(pao, 0, HPIAL_ADDR,
- write_data);
- boot_loader_write_mem32(pao, 0, HPIAH_ADDR,
- (write_data >> 16));
- read_data =
- 0xFFFF & boot_loader_read_mem32(pao, 0,
- HPIAL_ADDR);
- read_data =
- read_data | ((0xFFFF &
- boot_loader_read_mem32(pao, 0,
- HPIAH_ADDR))
- << 16);
- if (read_data != write_data) {
- HPI_DEBUG_LOG(ERROR, "HPIA %x %x\n",
- write_data, read_data);
- return HPI6205_ERROR_C6713_HPIA;
- }
- write_data = write_data << 1;
- }
-
- /* setup C67x PLL
- * ** C6713 datasheet says we cannot program PLL from HPI,
- * and indeed if we try to set the PLL multiply from the HPI,
- * the PLL does not seem to lock, so we enable the PLL and
- * use the default multiply of x 7, which for a 27MHz clock
- * gives a DSP speed of 189MHz
- */
- /* bypass PLL */
- boot_loader_write_mem32(pao, dsp_index, 0x01B7C100, 0x0000);
- hpios_delay_micro_seconds(1000);
- /* EMIF = 189/3=63MHz */
- boot_loader_write_mem32(pao, dsp_index, 0x01B7C120, 0x8002);
- /* peri = 189/2 */
- boot_loader_write_mem32(pao, dsp_index, 0x01B7C11C, 0x8001);
- /* cpu = 189/1 */
- boot_loader_write_mem32(pao, dsp_index, 0x01B7C118, 0x8000);
- hpios_delay_micro_seconds(1000);
- /* ** SGT test to take GPO3 high when we start the PLL */
- /* and low when the delay is completed */
- /* FSX0 <- '1' (GPO3) */
- boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002A0A);
- /* PLL not bypassed */
- boot_loader_write_mem32(pao, dsp_index, 0x01B7C100, 0x0001);
- hpios_delay_micro_seconds(1000);
- /* FSX0 <- '0' (GPO3) */
- boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002A02);
-
- /* 6205 EMIF CE1 resetup - 32 bit async. */
- /* Now 6713 #1 is running at 189MHz can reduce waitstates */
- boot_loader_write_mem32(pao, 0, 0x01800004, /* CE1 */
- (1L << WS_OFS) | (8L << WST_OFS) | (1L << WH_OFS) |
- (1L << RS_OFS) | (12L << RST_OFS) | (1L << RH_OFS) |
- (2L << MTYPE_OFS));
-
- hpios_delay_micro_seconds(1000);
-
- /* check that we can read one of the PLL registers */
- /* PLL should not be bypassed! */
- if ((boot_loader_read_mem32(pao, dsp_index, 0x01B7C100) & 0xF)
- != 0x0001) {
- return HPI6205_ERROR_C6713_PLL;
- }
- /* setup C67x EMIF (note this is the only use of
- BAR1 via BootLoader_WriteMem32) */
- boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_GCTL,
- 0x000034A8);
-
- /* EMIF CE0 setup - 2Mx32 Sync DRAM
- 31..28 Wr setup
- 27..22 Wr strobe
- 21..20 Wr hold
- 19..16 Rd setup
- 15..14 -
- 13..8 Rd strobe
- 7..4 MTYPE 0011 Sync DRAM 32bits
- 3 Wr hold MSB
- 2..0 Rd hold
- */
- boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_CE0,
- 0x00000030);
-
- /* EMIF SDRAM Extension
- 0x00
- 31-21 0000b 0000b 000b
- 20 WR2RD = 2cycles-1 = 1b
-
- 19-18 WR2DEAC = 3cycle-1 = 10b
- 17 WR2WR = 2cycle-1 = 1b
- 16-15 R2WDQM = 4cycle-1 = 11b
- 14-12 RD2WR = 6cycles-1 = 101b
-
- 11-10 RD2DEAC = 4cycle-1 = 11b
- 9 RD2RD = 2cycle-1 = 1b
- 8-7 THZP = 3cycle-1 = 10b
- 6-5 TWR = 2cycle-1 = 01b (tWR = 17ns)
- 4 TRRD = 2cycle = 0b (tRRD = 14ns)
- 3-1 TRAS = 5cycle-1 = 100b (Tras=42ns)
- 1 CAS latency = 3cyc = 1b
- (for Micron 2M32-7 operating at 100MHz)
- */
- boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMEXT,
- 0x001BDF29);
-
- /* EMIF SDRAM control - set up for a 2Mx32 SDRAM (512x32x4 bank)
- 31 - 0b -
- 30 SDBSZ 1b 4 bank
- 29..28 SDRSZ 00b 11 row address pins
-
- 27..26 SDCSZ 01b 8 column address pins
- 25 RFEN 1b refersh enabled
- 24 INIT 1b init SDRAM!
-
- 23..20 TRCD 0001b (Trcd/Tcyc)-1 = (20/10)-1 = 1
-
- 19..16 TRP 0001b (Trp/Tcyc)-1 = (20/10)-1 = 1
-
- 15..12 TRC 0110b (Trc/Tcyc)-1 = (70/10)-1 = 6
-
- 11..0 - 0000b 0000b 0000b
- */
- boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMCTL,
- 0x47116000);
-
- /* SDRAM refresh timing
- Need 4,096 refresh cycles every 64ms = 15.625us = 1562cycles of 100MHz = 0x61A
- */
- boot_loader_write_mem32(pao, dsp_index,
- C6713_EMIF_SDRAMTIMING, 0x00000410);
-
- hpios_delay_micro_seconds(1000);
- } else if (dsp_index == 2) {
- /* DSP 2 is a C6713 */
- }
-
- return 0;
-}
-
-static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
- u32 start_address, u32 length)
-{
- u32 i = 0, j = 0;
- u32 test_addr = 0;
- u32 test_data = 0, data = 0;
-
- length = 1000;
-
- /* for 1st word, test each bit in the 32bit word, */
- /* dwLength specifies number of 32bit words to test */
- /*for(i=0; i<dwLength; i++) */
- i = 0;
- {
- test_addr = start_address + i * 4;
- test_data = 0x00000001;
- for (j = 0; j < 32; j++) {
- boot_loader_write_mem32(pao, dsp_index, test_addr,
- test_data);
- data = boot_loader_read_mem32(pao, dsp_index,
- test_addr);
- if (data != test_data) {
- HPI_DEBUG_LOG(VERBOSE,
- "Memtest error details "
- "%08x %08x %08x %i\n", test_addr,
- test_data, data, dsp_index);
- return 1; /* error */
- }
- test_data = test_data << 1;
- } /* for(j) */
- } /* for(i) */
-
- /* for the next 100 locations test each location, leaving it as zero */
- /* write a zero to the next word in memory before we read */
- /* the previous write to make sure every memory location is unique */
- for (i = 0; i < 100; i++) {
- test_addr = start_address + i * 4;
- test_data = 0xA5A55A5A;
- boot_loader_write_mem32(pao, dsp_index, test_addr, test_data);
- boot_loader_write_mem32(pao, dsp_index, test_addr + 4, 0);
- data = boot_loader_read_mem32(pao, dsp_index, test_addr);
- if (data != test_data) {
- HPI_DEBUG_LOG(VERBOSE,
- "Memtest error details "
- "%08x %08x %08x %i\n", test_addr, test_data,
- data, dsp_index);
- return 1; /* error */
- }
- /* leave location as zero */
- boot_loader_write_mem32(pao, dsp_index, test_addr, 0x0);
- }
-
- /* zero out entire memory block */
- for (i = 0; i < length; i++) {
- test_addr = start_address + i * 4;
- boot_loader_write_mem32(pao, dsp_index, test_addr, 0x0);
- }
- return 0;
-}
-
-static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
- int dsp_index)
-{
- int err = 0;
- if (dsp_index == 0) {
- /* DSP 0 is a C6205 */
- /* 64K prog mem */
- err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
- 0x10000);
- if (!err)
- /* 64K data mem */
- err = boot_loader_test_memory(pao, dsp_index,
- 0x80000000, 0x10000);
- } else if (dsp_index == 1) {
- /* DSP 1 is a C6713 */
- /* 192K internal mem */
- err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
- 0x30000);
- if (!err)
- /* 64K internal mem / L2 cache */
- err = boot_loader_test_memory(pao, dsp_index,
- 0x00030000, 0x10000);
- }
-
- if (err)
- return HPI6205_ERROR_DSP_INTMEM;
- else
- return 0;
-}
-
-static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
- int dsp_index)
-{
- u32 dRAM_start_address = 0;
- u32 dRAM_size = 0;
-
- if (dsp_index == 0) {
- /* only test for SDRAM if an ASI5000 card */
- if (pao->pci.pci_dev->subsystem_device == 0x5000) {
- /* DSP 0 is always C6205 */
- dRAM_start_address = 0x00400000;
- dRAM_size = 0x200000;
- /*dwDRAMinc=1024; */
- } else
- return 0;
- } else if (dsp_index == 1) {
- /* DSP 1 is a C6713 */
- dRAM_start_address = 0x80000000;
- dRAM_size = 0x200000;
- /*dwDRAMinc=1024; */
- }
-
- if (boot_loader_test_memory(pao, dsp_index, dRAM_start_address,
- dRAM_size))
- return HPI6205_ERROR_DSP_EXTMEM;
- return 0;
-}
-
-static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index)
-{
- u32 data = 0;
- if (dsp_index == 0) {
- /* only test for DSP0 PLD on ASI5000 card */
- if (pao->pci.pci_dev->subsystem_device == 0x5000) {
- /* PLD is located at CE3=0x03000000 */
- data = boot_loader_read_mem32(pao, dsp_index,
- 0x03000008);
- if ((data & 0xF) != 0x5)
- return HPI6205_ERROR_DSP_PLD;
- data = boot_loader_read_mem32(pao, dsp_index,
- 0x0300000C);
- if ((data & 0xF) != 0xA)
- return HPI6205_ERROR_DSP_PLD;
- }
- } else if (dsp_index == 1) {
- /* DSP 1 is a C6713 */
- if (pao->pci.pci_dev->subsystem_device == 0x8700) {
- /* PLD is located at CE1=0x90000000 */
- data = boot_loader_read_mem32(pao, dsp_index,
- 0x90000010);
- if ((data & 0xFF) != 0xAA)
- return HPI6205_ERROR_DSP_PLD;
- /* 8713 - LED on */
- boot_loader_write_mem32(pao, dsp_index, 0x90000000,
- 0x02);
- }
- }
- return 0;
-}
-
-/** Transfer data to or from DSP
- nOperation = H620_H620_HIF_SEND_DATA or H620_HIF_GET_DATA
-*/
-static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
- u32 data_size, int operation)
-{
- struct hpi_hw_obj *phw = pao->priv;
- u32 data_transferred = 0;
- u16 err = 0;
- u32 temp2;
- struct bus_master_interface *interface = phw->p_interface_buffer;
-
- if (!p_data)
- return HPI_ERROR_INVALID_DATA_POINTER;
-
- data_size &= ~3L; /* round data_size down to nearest 4 bytes */
-
- /* make sure state is IDLE */
- if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT))
- return HPI_ERROR_DSP_HARDWARE;
-
- while (data_transferred < data_size) {
- u32 this_copy = data_size - data_transferred;
-
- if (this_copy > HPI6205_SIZEOF_DATA)
- this_copy = HPI6205_SIZEOF_DATA;
-
- if (operation == H620_HIF_SEND_DATA)
- memcpy((void *)&interface->u.b_data[0],
- &p_data[data_transferred], this_copy);
-
- interface->transfer_size_in_bytes = this_copy;
-
- /* DSP must change this back to nOperation */
- interface->dsp_ack = H620_HIF_IDLE;
- send_dsp_command(phw, operation);
-
- temp2 = wait_dsp_ack(phw, operation, HPI6205_TIMEOUT);
- HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
- HPI6205_TIMEOUT - temp2, this_copy);
-
- if (!temp2) {
- /* timed out */
- HPI_DEBUG_LOG(ERROR,
- "Timed out waiting for " "state %d got %d\n",
- operation, interface->dsp_ack);
-
- break;
- }
- if (operation == H620_HIF_GET_DATA)
- memcpy(&p_data[data_transferred],
- (void *)&interface->u.b_data[0], this_copy);
-
- data_transferred += this_copy;
- }
- if (interface->dsp_ack != operation)
- HPI_DEBUG_LOG(DEBUG, "interface->dsp_ack=%d, expected %d\n",
- interface->dsp_ack, operation);
- /* err=HPI_ERROR_DSP_HARDWARE; */
-
- send_dsp_command(phw, H620_HIF_IDLE);
-
- return err;
-}
-
-/* wait for up to timeout_us microseconds for the DSP
- to signal state by DMA into dwDspAck
-*/
-static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us)
-{
- struct bus_master_interface *interface = phw->p_interface_buffer;
- int t = timeout_us / 4;
-
- rmb(); /* ensure interface->dsp_ack is up to date */
- while ((interface->dsp_ack != state) && --t) {
- hpios_delay_micro_seconds(4);
- rmb(); /* DSP changes dsp_ack by DMA */
- }
-
- /*HPI_DEBUG_LOG(VERBOSE, "Spun %d for %d\n", timeout_us/4-t, state); */
- return t * 4;
-}
-
-/* set the busmaster interface to cmd, then interrupt the DSP */
-static void send_dsp_command(struct hpi_hw_obj *phw, int cmd)
-{
- struct bus_master_interface *interface = phw->p_interface_buffer;
- u32 r;
-
- interface->host_cmd = cmd;
- wmb(); /* DSP gets state by DMA, make sure it is written to memory */
- /* before we interrupt the DSP */
- r = ioread32(phw->prHDCR);
- r |= (u32)C6205_HDCR_DSPINT;
- iowrite32(r, phw->prHDCR);
- r &= ~(u32)C6205_HDCR_DSPINT;
- iowrite32(r, phw->prHDCR);
-}
-
-static unsigned int message_count;
-
-static u16 message_response_sequence(struct hpi_adapter_obj *pao,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- u32 time_out, time_out2;
- struct hpi_hw_obj *phw = pao->priv;
- struct bus_master_interface *interface = phw->p_interface_buffer;
- u16 err = 0;
-
- message_count++;
- if (phm->size > sizeof(interface->u.message_buffer)) {
- phr->error = HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL;
- phr->specific_error = sizeof(interface->u.message_buffer);
- phr->size = sizeof(struct hpi_response_header);
- HPI_DEBUG_LOG(ERROR,
- "message len %d too big for buffer %zd \n", phm->size,
- sizeof(interface->u.message_buffer));
- return 0;
- }
-
- /* Assume buffer of type struct bus_master_interface
- is allocated "noncacheable" */
-
- if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
- HPI_DEBUG_LOG(DEBUG, "timeout waiting for idle\n");
- return HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT;
- }
-
- memcpy(&interface->u.message_buffer, phm, phm->size);
- /* signal we want a response */
- send_dsp_command(phw, H620_HIF_GET_RESP);
-
- time_out2 = wait_dsp_ack(phw, H620_HIF_GET_RESP, HPI6205_TIMEOUT);
-
- if (!time_out2) {
- HPI_DEBUG_LOG(ERROR,
- "(%u) Timed out waiting for " "GET_RESP state [%x]\n",
- message_count, interface->dsp_ack);
- } else {
- HPI_DEBUG_LOG(VERBOSE,
- "(%u) transition to GET_RESP after %u\n",
- message_count, HPI6205_TIMEOUT - time_out2);
- }
- /* spin waiting on HIF interrupt flag (end of msg process) */
- time_out = HPI6205_TIMEOUT;
-
- /* read the result */
- if (time_out) {
- if (interface->u.response_buffer.response.size <= phr->size)
- memcpy(phr, &interface->u.response_buffer,
- interface->u.response_buffer.response.size);
- else {
- HPI_DEBUG_LOG(ERROR,
- "response len %d too big for buffer %d\n",
- interface->u.response_buffer.response.size,
- phr->size);
- memcpy(phr, &interface->u.response_buffer,
- sizeof(struct hpi_response_header));
- phr->error = HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
- phr->specific_error =
- interface->u.response_buffer.response.size;
- phr->size = sizeof(struct hpi_response_header);
- }
- }
- /* set interface back to idle */
- send_dsp_command(phw, H620_HIF_IDLE);
-
- if (!time_out || !time_out2) {
- HPI_DEBUG_LOG(DEBUG, "something timed out!\n");
- return HPI6205_ERROR_MSG_RESP_TIMEOUT;
- }
- /* special case for adapter close - */
- /* wait for the DSP to indicate it is idle */
- if (phm->function == HPI_ADAPTER_CLOSE) {
- if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
- HPI_DEBUG_LOG(DEBUG,
- "Timeout waiting for idle "
- "(on adapter_close)\n");
- return HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT;
- }
- }
- err = hpi_validate_response(phm, phr);
- return err;
-}
-
-static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
- struct hpi_response *phr)
-{
-
- u16 err = 0;
-
- hpios_dsplock_lock(pao);
-
- err = message_response_sequence(pao, phm, phr);
-
- /* maybe an error response */
- if (err) {
- /* something failed in the HPI/DSP interface */
- if (err >= HPI_ERROR_BACKEND_BASE) {
- phr->error = HPI_ERROR_DSP_COMMUNICATION;
- phr->specific_error = err;
- } else {
- phr->error = err;
- }
-
- pao->dsp_crashed++;
-
- /* just the header of the response is valid */
- phr->size = sizeof(struct hpi_response_header);
- goto err;
- } else
- pao->dsp_crashed = 0;
-
- if (phr->error != 0) /* something failed in the DSP */
- goto err;
-
- switch (phm->function) {
- case HPI_OSTREAM_WRITE:
- case HPI_ISTREAM_ANC_WRITE:
- err = hpi6205_transfer_data(pao, phm->u.d.u.data.pb_data,
- phm->u.d.u.data.data_size, H620_HIF_SEND_DATA);
- break;
-
- case HPI_ISTREAM_READ:
- case HPI_OSTREAM_ANC_READ:
- err = hpi6205_transfer_data(pao, phm->u.d.u.data.pb_data,
- phm->u.d.u.data.data_size, H620_HIF_GET_DATA);
- break;
-
- }
- phr->error = err;
-
-err:
- hpios_dsplock_unlock(pao);
-
- return;
-}
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpi6205.h b/ANDROID_3.4.5/sound/pci/asihpi/hpi6205.h
deleted file mode 100644
index ec0827b6..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpi6205.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*****************************************************************************
-
- AudioScience HPI driver
- Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Host Interface module for an ASI6205 based
-bus mastering PCI adapter.
-
-Copyright AudioScience, Inc., 2003
-******************************************************************************/
-
-#ifndef _HPI6205_H_
-#define _HPI6205_H_
-
-#include "hpi_internal.h"
-
-/***********************************************************
- Defines used for basic messaging
-************************************************************/
-#define H620_HIF_RESET 0
-#define H620_HIF_IDLE 1
-#define H620_HIF_GET_RESP 2
-#define H620_HIF_DATA_DONE 3
-#define H620_HIF_DATA_MASK 0x10
-#define H620_HIF_SEND_DATA 0x14
-#define H620_HIF_GET_DATA 0x15
-#define H620_HIF_UNKNOWN 0x0000ffff
-
-/***********************************************************
- Types used for mixer control caching
-************************************************************/
-
-#define H620_MAX_ISTREAMS 32
-#define H620_MAX_OSTREAMS 32
-#define HPI_NMIXER_CONTROLS 2048
-
-/*********************************************************************
-This is used for dynamic control cache allocation
-**********************************************************************/
-struct controlcache_6205 {
- u32 number_of_controls;
- u32 physical_address32;
- u32 size_in_bytes;
-};
-
-/*********************************************************************
-This is used for dynamic allocation of async event array
-**********************************************************************/
-struct async_event_buffer_6205 {
- u32 physical_address32;
- u32 spare;
- struct hpi_fifo_buffer b;
-};
-
-/***********************************************************
-The Host located memory buffer that the 6205 will bus master
-in and out of.
-************************************************************/
-#define HPI6205_SIZEOF_DATA (16*1024)
-
-struct message_buffer_6205 {
- struct hpi_message message;
- char data[256];
-};
-
-struct response_buffer_6205 {
- struct hpi_response response;
- char data[256];
-};
-
-union buffer_6205 {
- struct message_buffer_6205 message_buffer;
- struct response_buffer_6205 response_buffer;
- u8 b_data[HPI6205_SIZEOF_DATA];
-};
-
-struct bus_master_interface {
- u32 host_cmd;
- u32 dsp_ack;
- u32 transfer_size_in_bytes;
- union buffer_6205 u;
- struct controlcache_6205 control_cache;
- struct async_event_buffer_6205 async_buffer;
- struct hpi_hostbuffer_status
- instream_host_buffer_status[H620_MAX_ISTREAMS];
- struct hpi_hostbuffer_status
- outstream_host_buffer_status[H620_MAX_OSTREAMS];
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpi_internal.h b/ANDROID_3.4.5/sound/pci/asihpi/hpi_internal.h
deleted file mode 100644
index bc86cb72..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpi_internal.h
+++ /dev/null
@@ -1,1431 +0,0 @@
-/******************************************************************************
-
- AudioScience HPI driver
- Copyright (C) 1997-2012 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-HPI internal definitions
-
-(C) Copyright AudioScience Inc. 1996-2009
-******************************************************************************/
-
-#ifndef _HPI_INTERNAL_H_
-#define _HPI_INTERNAL_H_
-
-#include "hpi.h"
-
-/** maximum number of memory regions mapped to an adapter */
-#define HPI_MAX_ADAPTER_MEM_SPACES (2)
-
-/* Each OS needs its own hpios.h */
-#include "hpios.h"
-
-/* physical memory allocation */
-
-/** Allocate and map an area of locked memory for bus master DMA operations.
-
-On success, *pLockedMemeHandle is a valid handle, and 0 is returned
-On error *pLockedMemHandle marked invalid, non-zero returned.
-
-If this function succeeds, then HpiOs_LockedMem_GetVirtAddr() and
-HpiOs_LockedMem_GetPyhsAddr() will always succed on the returned handle.
-*/
-u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_locked_mem_handle,
- /**< memory handle */
- u32 size, /**< Size in bytes to allocate */
- struct pci_dev *p_os_reference
- /**< OS specific data required for memory allocation */
- );
-
-/** Free mapping and memory represented by LockedMemHandle
-
-Frees any resources, then invalidates the handle.
-Returns 0 on success, 1 if handle is invalid.
-
-*/
-u16 hpios_locked_mem_free(struct consistent_dma_area *locked_mem_handle);
-
-/** Get the physical PCI address of memory represented by LockedMemHandle.
-
-If handle is invalid *pPhysicalAddr is set to zero and return 1
-*/
-u16 hpios_locked_mem_get_phys_addr(struct consistent_dma_area
- *locked_mem_handle, u32 *p_physical_addr);
-
-/** Get the CPU address of of memory represented by LockedMemHandle.
-
-If handle is NULL *ppvVirtualAddr is set to NULL and return 1
-*/
-u16 hpios_locked_mem_get_virt_addr(struct consistent_dma_area
- *locked_mem_handle, void **ppv_virtual_addr);
-
-/** Check that handle is valid
-i.e it represents a valid memory area
-*/
-u16 hpios_locked_mem_valid(struct consistent_dma_area *locked_mem_handle);
-
-/* timing/delay */
-void hpios_delay_micro_seconds(u32 num_micro_sec);
-
-struct hpi_message;
-struct hpi_response;
-
-typedef void hpi_handler_func(struct hpi_message *, struct hpi_response *);
-
-/* If the assert fails, compiler complains
- something like size of array `msg' is negative.
- Unlike linux BUILD_BUG_ON, this works outside function scope.
-*/
-#define compile_time_assert(cond, msg) \
- typedef char ASSERT_##msg[(cond) ? 1 : -1]
-
-/******************************************* bus types */
-enum HPI_BUSES {
- HPI_BUS_ISAPNP = 1,
- HPI_BUS_PCI = 2,
- HPI_BUS_USB = 3,
- HPI_BUS_NET = 4
-};
-
-enum HPI_SUBSYS_OPTIONS {
- /* 0, 256 are invalid, 1..255 reserved for global options */
- HPI_SUBSYS_OPT_NET_ENABLE = 257,
- HPI_SUBSYS_OPT_NET_BROADCAST = 258,
- HPI_SUBSYS_OPT_NET_UNICAST = 259,
- HPI_SUBSYS_OPT_NET_ADDR = 260,
- HPI_SUBSYS_OPT_NET_MASK = 261,
- HPI_SUBSYS_OPT_NET_ADAPTER_ADDRESS_ADD = 262
-};
-
-/** Volume flags
-*/
-enum HPI_VOLUME_FLAGS {
- /** Set if the volume control is muted */
- HPI_VOLUME_FLAG_MUTED = (1 << 0),
- /** Set if the volume control has a mute function */
- HPI_VOLUME_FLAG_HAS_MUTE = (1 << 1),
- /** Set if volume control can do autofading */
- HPI_VOLUME_FLAG_HAS_AUTOFADE = (1 << 2)
- /* Note Flags >= (1<<8) are for DSP internal use only */
-};
-
-/******************************************* CONTROL ATTRIBUTES ****/
-/* (in order of control type ID */
-
-/* This allows for 255 control types, 256 unique attributes each */
-#define HPI_CTL_ATTR(ctl, ai) ((HPI_CONTROL_##ctl << 8) + ai)
-
-/* Get the sub-index of the attribute for a control type */
-#define HPI_CTL_ATTR_INDEX(i) (i & 0xff)
-
-/* Extract the control from the control attribute */
-#define HPI_CTL_ATTR_CONTROL(i) (i >> 8)
-
-/** Enable event generation for a control.
-0=disable, 1=enable
-\note generic to all controls that can generate events
-*/
-
-/** Unique identifiers for every control attribute
-*/
-enum HPI_CONTROL_ATTRIBUTES {
- HPI_GENERIC_ENABLE = HPI_CTL_ATTR(GENERIC, 1),
- HPI_GENERIC_EVENT_ENABLE = HPI_CTL_ATTR(GENERIC, 2),
-
- HPI_VOLUME_GAIN = HPI_CTL_ATTR(VOLUME, 1),
- HPI_VOLUME_AUTOFADE = HPI_CTL_ATTR(VOLUME, 2),
- HPI_VOLUME_MUTE = HPI_CTL_ATTR(VOLUME, 3),
- HPI_VOLUME_GAIN_AND_FLAGS = HPI_CTL_ATTR(VOLUME, 4),
- HPI_VOLUME_NUM_CHANNELS = HPI_CTL_ATTR(VOLUME, 6),
- HPI_VOLUME_RANGE = HPI_CTL_ATTR(VOLUME, 10),
-
- HPI_METER_RMS = HPI_CTL_ATTR(METER, 1),
- HPI_METER_PEAK = HPI_CTL_ATTR(METER, 2),
- HPI_METER_RMS_BALLISTICS = HPI_CTL_ATTR(METER, 3),
- HPI_METER_PEAK_BALLISTICS = HPI_CTL_ATTR(METER, 4),
- HPI_METER_NUM_CHANNELS = HPI_CTL_ATTR(METER, 5),
-
- HPI_MULTIPLEXER_SOURCE = HPI_CTL_ATTR(MULTIPLEXER, 1),
- HPI_MULTIPLEXER_QUERYSOURCE = HPI_CTL_ATTR(MULTIPLEXER, 2),
-
- HPI_AESEBUTX_FORMAT = HPI_CTL_ATTR(AESEBUTX, 1),
- HPI_AESEBUTX_SAMPLERATE = HPI_CTL_ATTR(AESEBUTX, 3),
- HPI_AESEBUTX_CHANNELSTATUS = HPI_CTL_ATTR(AESEBUTX, 4),
- HPI_AESEBUTX_USERDATA = HPI_CTL_ATTR(AESEBUTX, 5),
-
- HPI_AESEBURX_FORMAT = HPI_CTL_ATTR(AESEBURX, 1),
- HPI_AESEBURX_ERRORSTATUS = HPI_CTL_ATTR(AESEBURX, 2),
- HPI_AESEBURX_SAMPLERATE = HPI_CTL_ATTR(AESEBURX, 3),
- HPI_AESEBURX_CHANNELSTATUS = HPI_CTL_ATTR(AESEBURX, 4),
- HPI_AESEBURX_USERDATA = HPI_CTL_ATTR(AESEBURX, 5),
-
- HPI_LEVEL_GAIN = HPI_CTL_ATTR(LEVEL, 1),
- HPI_LEVEL_RANGE = HPI_CTL_ATTR(LEVEL, 10),
-
- HPI_TUNER_BAND = HPI_CTL_ATTR(TUNER, 1),
- HPI_TUNER_FREQ = HPI_CTL_ATTR(TUNER, 2),
- HPI_TUNER_LEVEL_AVG = HPI_CTL_ATTR(TUNER, 3),
- HPI_TUNER_LEVEL_RAW = HPI_CTL_ATTR(TUNER, 4),
- HPI_TUNER_SNR = HPI_CTL_ATTR(TUNER, 5),
- HPI_TUNER_GAIN = HPI_CTL_ATTR(TUNER, 6),
- HPI_TUNER_STATUS = HPI_CTL_ATTR(TUNER, 7),
- HPI_TUNER_MODE = HPI_CTL_ATTR(TUNER, 8),
- HPI_TUNER_RDS = HPI_CTL_ATTR(TUNER, 9),
- HPI_TUNER_DEEMPHASIS = HPI_CTL_ATTR(TUNER, 10),
- HPI_TUNER_PROGRAM = HPI_CTL_ATTR(TUNER, 11),
- HPI_TUNER_HDRADIO_SIGNAL_QUALITY = HPI_CTL_ATTR(TUNER, 12),
- HPI_TUNER_HDRADIO_SDK_VERSION = HPI_CTL_ATTR(TUNER, 13),
- HPI_TUNER_HDRADIO_DSP_VERSION = HPI_CTL_ATTR(TUNER, 14),
- HPI_TUNER_HDRADIO_BLEND = HPI_CTL_ATTR(TUNER, 15),
-
- HPI_VOX_THRESHOLD = HPI_CTL_ATTR(VOX, 1),
-
- HPI_CHANNEL_MODE_MODE = HPI_CTL_ATTR(CHANNEL_MODE, 1),
-
- HPI_BITSTREAM_DATA_POLARITY = HPI_CTL_ATTR(BITSTREAM, 1),
- HPI_BITSTREAM_CLOCK_EDGE = HPI_CTL_ATTR(BITSTREAM, 2),
- HPI_BITSTREAM_CLOCK_SOURCE = HPI_CTL_ATTR(BITSTREAM, 3),
- HPI_BITSTREAM_ACTIVITY = HPI_CTL_ATTR(BITSTREAM, 4),
-
- HPI_SAMPLECLOCK_SOURCE = HPI_CTL_ATTR(SAMPLECLOCK, 1),
- HPI_SAMPLECLOCK_SAMPLERATE = HPI_CTL_ATTR(SAMPLECLOCK, 2),
- HPI_SAMPLECLOCK_SOURCE_INDEX = HPI_CTL_ATTR(SAMPLECLOCK, 3),
- HPI_SAMPLECLOCK_LOCAL_SAMPLERATE = HPI_CTL_ATTR(SAMPLECLOCK, 4),
- HPI_SAMPLECLOCK_AUTO = HPI_CTL_ATTR(SAMPLECLOCK, 5),
- HPI_SAMPLECLOCK_LOCAL_LOCK = HPI_CTL_ATTR(SAMPLECLOCK, 6),
-
- HPI_MICROPHONE_PHANTOM_POWER = HPI_CTL_ATTR(MICROPHONE, 1),
-
- HPI_EQUALIZER_NUM_FILTERS = HPI_CTL_ATTR(EQUALIZER, 1),
- HPI_EQUALIZER_FILTER = HPI_CTL_ATTR(EQUALIZER, 2),
- HPI_EQUALIZER_COEFFICIENTS = HPI_CTL_ATTR(EQUALIZER, 3),
-
- HPI_COMPANDER_PARAMS = HPI_CTL_ATTR(COMPANDER, 1),
- HPI_COMPANDER_MAKEUPGAIN = HPI_CTL_ATTR(COMPANDER, 2),
- HPI_COMPANDER_THRESHOLD = HPI_CTL_ATTR(COMPANDER, 3),
- HPI_COMPANDER_RATIO = HPI_CTL_ATTR(COMPANDER, 4),
- HPI_COMPANDER_ATTACK = HPI_CTL_ATTR(COMPANDER, 5),
- HPI_COMPANDER_DECAY = HPI_CTL_ATTR(COMPANDER, 6),
-
- HPI_COBRANET_SET = HPI_CTL_ATTR(COBRANET, 1),
- HPI_COBRANET_GET = HPI_CTL_ATTR(COBRANET, 2),
- HPI_COBRANET_GET_STATUS = HPI_CTL_ATTR(COBRANET, 5),
- HPI_COBRANET_SEND_PACKET = HPI_CTL_ATTR(COBRANET, 6),
- HPI_COBRANET_GET_PACKET = HPI_CTL_ATTR(COBRANET, 7),
-
- HPI_TONEDETECTOR_THRESHOLD = HPI_CTL_ATTR(TONEDETECTOR, 1),
- HPI_TONEDETECTOR_STATE = HPI_CTL_ATTR(TONEDETECTOR, 2),
- HPI_TONEDETECTOR_FREQUENCY = HPI_CTL_ATTR(TONEDETECTOR, 3),
-
- HPI_SILENCEDETECTOR_THRESHOLD = HPI_CTL_ATTR(SILENCEDETECTOR, 1),
- HPI_SILENCEDETECTOR_STATE = HPI_CTL_ATTR(SILENCEDETECTOR, 2),
- HPI_SILENCEDETECTOR_DELAY = HPI_CTL_ATTR(SILENCEDETECTOR, 3),
-
- HPI_PAD_CHANNEL_NAME = HPI_CTL_ATTR(PAD, 1),
- HPI_PAD_ARTIST = HPI_CTL_ATTR(PAD, 2),
- HPI_PAD_TITLE = HPI_CTL_ATTR(PAD, 3),
- HPI_PAD_COMMENT = HPI_CTL_ATTR(PAD, 4),
- HPI_PAD_PROGRAM_TYPE = HPI_CTL_ATTR(PAD, 5),
- HPI_PAD_PROGRAM_ID = HPI_CTL_ATTR(PAD, 6),
- HPI_PAD_TA_SUPPORT = HPI_CTL_ATTR(PAD, 7),
- HPI_PAD_TA_ACTIVE = HPI_CTL_ATTR(PAD, 8),
-
- HPI_UNIVERSAL_ENTITY = HPI_CTL_ATTR(UNIVERSAL, 1)
-};
-
-#define HPI_POLARITY_POSITIVE 0
-#define HPI_POLARITY_NEGATIVE 1
-
-/*------------------------------------------------------------
- Cobranet Chip Bridge - copied from HMI.H
-------------------------------------------------------------*/
-#define HPI_COBRANET_HMI_cobra_bridge 0x20000
-#define HPI_COBRANET_HMI_cobra_bridge_tx_pkt_buf \
- (HPI_COBRANET_HMI_cobra_bridge + 0x1000)
-#define HPI_COBRANET_HMI_cobra_bridge_rx_pkt_buf \
- (HPI_COBRANET_HMI_cobra_bridge + 0x2000)
-#define HPI_COBRANET_HMI_cobra_if_table1 0x110000
-#define HPI_COBRANET_HMI_cobra_if_phy_address \
- (HPI_COBRANET_HMI_cobra_if_table1 + 0xd)
-#define HPI_COBRANET_HMI_cobra_protocolIP 0x72000
-#define HPI_COBRANET_HMI_cobra_ip_mon_currentIP \
- (HPI_COBRANET_HMI_cobra_protocolIP + 0x0)
-#define HPI_COBRANET_HMI_cobra_ip_mon_staticIP \
- (HPI_COBRANET_HMI_cobra_protocolIP + 0x2)
-#define HPI_COBRANET_HMI_cobra_sys 0x100000
-#define HPI_COBRANET_HMI_cobra_sys_desc \
- (HPI_COBRANET_HMI_cobra_sys + 0x0)
-#define HPI_COBRANET_HMI_cobra_sys_objectID \
- (HPI_COBRANET_HMI_cobra_sys + 0x100)
-#define HPI_COBRANET_HMI_cobra_sys_contact \
- (HPI_COBRANET_HMI_cobra_sys + 0x200)
-#define HPI_COBRANET_HMI_cobra_sys_name \
- (HPI_COBRANET_HMI_cobra_sys + 0x300)
-#define HPI_COBRANET_HMI_cobra_sys_location \
- (HPI_COBRANET_HMI_cobra_sys + 0x400)
-
-/*------------------------------------------------------------
- Cobranet Chip Status bits
-------------------------------------------------------------*/
-#define HPI_COBRANET_HMI_STATUS_RXPACKET 2
-#define HPI_COBRANET_HMI_STATUS_TXPACKET 3
-
-/*------------------------------------------------------------
- Ethernet header size
-------------------------------------------------------------*/
-#define HPI_ETHERNET_HEADER_SIZE (16)
-
-/* These defines are used to fill in protocol information for an Ethernet packet
- sent using HMI on CS18102 */
-/** ID supplied by Cirrus for ASI packets. */
-#define HPI_ETHERNET_PACKET_ID 0x85
-/** Simple packet - no special routing required */
-#define HPI_ETHERNET_PACKET_V1 0x01
-/** This packet must make its way to the host across the HPI interface */
-#define HPI_ETHERNET_PACKET_HOSTED_VIA_HMI 0x20
-/** This packet must make its way to the host across the HPI interface */
-#define HPI_ETHERNET_PACKET_HOSTED_VIA_HMI_V1 0x21
-/** This packet must make its way to the host across the HPI interface */
-#define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI 0x40
-/** This packet must make its way to the host across the HPI interface */
-#define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI_V1 0x41
-
-#define HPI_ETHERNET_UDP_PORT 44600 /**< HPI UDP service */
-
-/** Default network timeout in milli-seconds. */
-#define HPI_ETHERNET_TIMEOUT_MS 500
-
-/** Locked memory buffer alloc/free phases */
-enum HPI_BUFFER_CMDS {
- /** use one message to allocate or free physical memory */
- HPI_BUFFER_CMD_EXTERNAL = 0,
- /** alloc physical memory */
- HPI_BUFFER_CMD_INTERNAL_ALLOC = 1,
- /** send physical memory address to adapter */
- HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER = 2,
- /** notify adapter to stop using physical buffer */
- HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER = 3,
- /** free physical buffer */
- HPI_BUFFER_CMD_INTERNAL_FREE = 4
-};
-
-/*****************************************************************************/
-/*****************************************************************************/
-/******** HPI LOW LEVEL MESSAGES *******/
-/*****************************************************************************/
-/*****************************************************************************/
-/** Pnp ids */
-/** "ASI" - actual is "ASX" - need to change */
-#define HPI_ID_ISAPNP_AUDIOSCIENCE 0x0669
-/** PCI vendor ID that AudioScience uses */
-#define HPI_PCI_VENDOR_ID_AUDIOSCIENCE 0x175C
-/** PCI vendor ID that the DSP56301 has */
-#define HPI_PCI_VENDOR_ID_MOTOROLA 0x1057
-/** PCI vendor ID that TI uses */
-#define HPI_PCI_VENDOR_ID_TI 0x104C
-
-#define HPI_PCI_DEV_ID_PCI2040 0xAC60
-/** TI's C6205 PCI interface has this ID */
-#define HPI_PCI_DEV_ID_DSP6205 0xA106
-
-#define HPI_USB_VENDOR_ID_AUDIOSCIENCE 0x1257
-#define HPI_USB_W2K_TAG 0x57495341 /* "ASIW" */
-#define HPI_USB_LINUX_TAG 0x4C495341 /* "ASIL" */
-
-/** Invalid Adapter index
-Used in HPI messages that are not addressed to a specific adapter
-Used in DLL to indicate device not present
-*/
-#define HPI_ADAPTER_INDEX_INVALID 0xFFFF
-
-/** First 2 hex digits define the adapter family */
-#define HPI_ADAPTER_FAMILY_MASK 0xff00
-#define HPI_MODULE_FAMILY_MASK 0xfff0
-
-#define HPI_ADAPTER_FAMILY_ASI(f) (f & HPI_ADAPTER_FAMILY_MASK)
-#define HPI_MODULE_FAMILY_ASI(f) (f & HPI_MODULE_FAMILY_MASK)
-#define HPI_ADAPTER_ASI(f) (f)
-
-enum HPI_MESSAGE_TYPES {
- HPI_TYPE_REQUEST = 1,
- HPI_TYPE_RESPONSE = 2,
- HPI_TYPE_DATA = 3,
- HPI_TYPE_SSX2BYPASS_MESSAGE = 4,
- HPI_TYPE_COMMAND = 5,
- HPI_TYPE_NOTIFICATION = 6
-};
-
-enum HPI_OBJECT_TYPES {
- HPI_OBJ_SUBSYSTEM = 1,
- HPI_OBJ_ADAPTER = 2,
- HPI_OBJ_OSTREAM = 3,
- HPI_OBJ_ISTREAM = 4,
- HPI_OBJ_MIXER = 5,
- HPI_OBJ_NODE = 6,
- HPI_OBJ_CONTROL = 7,
- HPI_OBJ_NVMEMORY = 8,
- HPI_OBJ_GPIO = 9,
- HPI_OBJ_WATCHDOG = 10,
- HPI_OBJ_CLOCK = 11,
- HPI_OBJ_PROFILE = 12,
- /* HPI_ OBJ_ CONTROLEX = 13, */
- HPI_OBJ_ASYNCEVENT = 14
-#define HPI_OBJ_MAXINDEX 14
-};
-
-#define HPI_OBJ_FUNCTION_SPACING 0x100
-#define HPI_FUNC_ID(obj, i) (HPI_OBJ_##obj * HPI_OBJ_FUNCTION_SPACING + i)
-
-#define HPI_EXTRACT_INDEX(fn) (fn & 0xff)
-
-enum HPI_FUNCTION_IDS {
- HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1),
- HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2),
- HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3),
- HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5),
- HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6),
- HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8),
- HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9),
- HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12),
- HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13),
- HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14),
- HPI_SUBSYS_OPTION_INFO = HPI_FUNC_ID(SUBSYSTEM, 15),
- HPI_SUBSYS_OPTION_GET = HPI_FUNC_ID(SUBSYSTEM, 16),
- HPI_SUBSYS_OPTION_SET = HPI_FUNC_ID(SUBSYSTEM, 17),
-#define HPI_SUBSYS_FUNCTION_COUNT 17
-
- HPI_ADAPTER_OPEN = HPI_FUNC_ID(ADAPTER, 1),
- HPI_ADAPTER_CLOSE = HPI_FUNC_ID(ADAPTER, 2),
- HPI_ADAPTER_GET_INFO = HPI_FUNC_ID(ADAPTER, 3),
- HPI_ADAPTER_GET_ASSERT = HPI_FUNC_ID(ADAPTER, 4),
- HPI_ADAPTER_TEST_ASSERT = HPI_FUNC_ID(ADAPTER, 5),
- HPI_ADAPTER_SET_MODE = HPI_FUNC_ID(ADAPTER, 6),
- HPI_ADAPTER_GET_MODE = HPI_FUNC_ID(ADAPTER, 7),
- HPI_ADAPTER_ENABLE_CAPABILITY = HPI_FUNC_ID(ADAPTER, 8),
- HPI_ADAPTER_SELFTEST = HPI_FUNC_ID(ADAPTER, 9),
- HPI_ADAPTER_FIND_OBJECT = HPI_FUNC_ID(ADAPTER, 10),
- HPI_ADAPTER_QUERY_FLASH = HPI_FUNC_ID(ADAPTER, 11),
- HPI_ADAPTER_START_FLASH = HPI_FUNC_ID(ADAPTER, 12),
- HPI_ADAPTER_PROGRAM_FLASH = HPI_FUNC_ID(ADAPTER, 13),
- HPI_ADAPTER_SET_PROPERTY = HPI_FUNC_ID(ADAPTER, 14),
- HPI_ADAPTER_GET_PROPERTY = HPI_FUNC_ID(ADAPTER, 15),
- HPI_ADAPTER_ENUM_PROPERTY = HPI_FUNC_ID(ADAPTER, 16),
- HPI_ADAPTER_MODULE_INFO = HPI_FUNC_ID(ADAPTER, 17),
- HPI_ADAPTER_DEBUG_READ = HPI_FUNC_ID(ADAPTER, 18),
- HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19),
- HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20),
- HPI_ADAPTER_DELETE = HPI_FUNC_ID(ADAPTER, 21),
- HPI_ADAPTER_READ_FLASH = HPI_FUNC_ID(ADAPTER, 22),
- HPI_ADAPTER_END_FLASH = HPI_FUNC_ID(ADAPTER, 23),
- HPI_ADAPTER_FILESTORE_DELETE_ALL = HPI_FUNC_ID(ADAPTER, 24),
-#define HPI_ADAPTER_FUNCTION_COUNT 24
-
- HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1),
- HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2),
- HPI_OSTREAM_WRITE = HPI_FUNC_ID(OSTREAM, 3),
- HPI_OSTREAM_START = HPI_FUNC_ID(OSTREAM, 4),
- HPI_OSTREAM_STOP = HPI_FUNC_ID(OSTREAM, 5),
- HPI_OSTREAM_RESET = HPI_FUNC_ID(OSTREAM, 6),
- HPI_OSTREAM_GET_INFO = HPI_FUNC_ID(OSTREAM, 7),
- HPI_OSTREAM_QUERY_FORMAT = HPI_FUNC_ID(OSTREAM, 8),
- HPI_OSTREAM_DATA = HPI_FUNC_ID(OSTREAM, 9),
- HPI_OSTREAM_SET_VELOCITY = HPI_FUNC_ID(OSTREAM, 10),
- HPI_OSTREAM_SET_PUNCHINOUT = HPI_FUNC_ID(OSTREAM, 11),
- HPI_OSTREAM_SINEGEN = HPI_FUNC_ID(OSTREAM, 12),
- HPI_OSTREAM_ANC_RESET = HPI_FUNC_ID(OSTREAM, 13),
- HPI_OSTREAM_ANC_GET_INFO = HPI_FUNC_ID(OSTREAM, 14),
- HPI_OSTREAM_ANC_READ = HPI_FUNC_ID(OSTREAM, 15),
- HPI_OSTREAM_SET_TIMESCALE = HPI_FUNC_ID(OSTREAM, 16),
- HPI_OSTREAM_SET_FORMAT = HPI_FUNC_ID(OSTREAM, 17),
- HPI_OSTREAM_HOSTBUFFER_ALLOC = HPI_FUNC_ID(OSTREAM, 18),
- HPI_OSTREAM_HOSTBUFFER_FREE = HPI_FUNC_ID(OSTREAM, 19),
- HPI_OSTREAM_GROUP_ADD = HPI_FUNC_ID(OSTREAM, 20),
- HPI_OSTREAM_GROUP_GETMAP = HPI_FUNC_ID(OSTREAM, 21),
- HPI_OSTREAM_GROUP_RESET = HPI_FUNC_ID(OSTREAM, 22),
- HPI_OSTREAM_HOSTBUFFER_GET_INFO = HPI_FUNC_ID(OSTREAM, 23),
- HPI_OSTREAM_WAIT_START = HPI_FUNC_ID(OSTREAM, 24),
- HPI_OSTREAM_WAIT = HPI_FUNC_ID(OSTREAM, 25),
-#define HPI_OSTREAM_FUNCTION_COUNT 25
-
- HPI_ISTREAM_OPEN = HPI_FUNC_ID(ISTREAM, 1),
- HPI_ISTREAM_CLOSE = HPI_FUNC_ID(ISTREAM, 2),
- HPI_ISTREAM_SET_FORMAT = HPI_FUNC_ID(ISTREAM, 3),
- HPI_ISTREAM_READ = HPI_FUNC_ID(ISTREAM, 4),
- HPI_ISTREAM_START = HPI_FUNC_ID(ISTREAM, 5),
- HPI_ISTREAM_STOP = HPI_FUNC_ID(ISTREAM, 6),
- HPI_ISTREAM_RESET = HPI_FUNC_ID(ISTREAM, 7),
- HPI_ISTREAM_GET_INFO = HPI_FUNC_ID(ISTREAM, 8),
- HPI_ISTREAM_QUERY_FORMAT = HPI_FUNC_ID(ISTREAM, 9),
- HPI_ISTREAM_ANC_RESET = HPI_FUNC_ID(ISTREAM, 10),
- HPI_ISTREAM_ANC_GET_INFO = HPI_FUNC_ID(ISTREAM, 11),
- HPI_ISTREAM_ANC_WRITE = HPI_FUNC_ID(ISTREAM, 12),
- HPI_ISTREAM_HOSTBUFFER_ALLOC = HPI_FUNC_ID(ISTREAM, 13),
- HPI_ISTREAM_HOSTBUFFER_FREE = HPI_FUNC_ID(ISTREAM, 14),
- HPI_ISTREAM_GROUP_ADD = HPI_FUNC_ID(ISTREAM, 15),
- HPI_ISTREAM_GROUP_GETMAP = HPI_FUNC_ID(ISTREAM, 16),
- HPI_ISTREAM_GROUP_RESET = HPI_FUNC_ID(ISTREAM, 17),
- HPI_ISTREAM_HOSTBUFFER_GET_INFO = HPI_FUNC_ID(ISTREAM, 18),
- HPI_ISTREAM_WAIT_START = HPI_FUNC_ID(ISTREAM, 19),
- HPI_ISTREAM_WAIT = HPI_FUNC_ID(ISTREAM, 20),
-#define HPI_ISTREAM_FUNCTION_COUNT 20
-
-/* NOTE:
- GET_NODE_INFO, SET_CONNECTION, GET_CONNECTIONS are not currently used */
- HPI_MIXER_OPEN = HPI_FUNC_ID(MIXER, 1),
- HPI_MIXER_CLOSE = HPI_FUNC_ID(MIXER, 2),
- HPI_MIXER_GET_INFO = HPI_FUNC_ID(MIXER, 3),
- HPI_MIXER_GET_NODE_INFO = HPI_FUNC_ID(MIXER, 4),
- HPI_MIXER_GET_CONTROL = HPI_FUNC_ID(MIXER, 5),
- HPI_MIXER_SET_CONNECTION = HPI_FUNC_ID(MIXER, 6),
- HPI_MIXER_GET_CONNECTIONS = HPI_FUNC_ID(MIXER, 7),
- HPI_MIXER_GET_CONTROL_BY_INDEX = HPI_FUNC_ID(MIXER, 8),
- HPI_MIXER_GET_CONTROL_ARRAY_BY_INDEX = HPI_FUNC_ID(MIXER, 9),
- HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES = HPI_FUNC_ID(MIXER, 10),
- HPI_MIXER_STORE = HPI_FUNC_ID(MIXER, 11),
- HPI_MIXER_GET_CACHE_INFO = HPI_FUNC_ID(MIXER, 12),
- HPI_MIXER_GET_BLOCK_HANDLE = HPI_FUNC_ID(MIXER, 13),
- HPI_MIXER_GET_PARAMETER_HANDLE = HPI_FUNC_ID(MIXER, 14),
-#define HPI_MIXER_FUNCTION_COUNT 14
-
- HPI_CONTROL_GET_INFO = HPI_FUNC_ID(CONTROL, 1),
- HPI_CONTROL_GET_STATE = HPI_FUNC_ID(CONTROL, 2),
- HPI_CONTROL_SET_STATE = HPI_FUNC_ID(CONTROL, 3),
-#define HPI_CONTROL_FUNCTION_COUNT 3
-
- HPI_NVMEMORY_OPEN = HPI_FUNC_ID(NVMEMORY, 1),
- HPI_NVMEMORY_READ_BYTE = HPI_FUNC_ID(NVMEMORY, 2),
- HPI_NVMEMORY_WRITE_BYTE = HPI_FUNC_ID(NVMEMORY, 3),
-#define HPI_NVMEMORY_FUNCTION_COUNT 3
-
- HPI_GPIO_OPEN = HPI_FUNC_ID(GPIO, 1),
- HPI_GPIO_READ_BIT = HPI_FUNC_ID(GPIO, 2),
- HPI_GPIO_WRITE_BIT = HPI_FUNC_ID(GPIO, 3),
- HPI_GPIO_READ_ALL = HPI_FUNC_ID(GPIO, 4),
- HPI_GPIO_WRITE_STATUS = HPI_FUNC_ID(GPIO, 5),
-#define HPI_GPIO_FUNCTION_COUNT 5
-
- HPI_ASYNCEVENT_OPEN = HPI_FUNC_ID(ASYNCEVENT, 1),
- HPI_ASYNCEVENT_CLOSE = HPI_FUNC_ID(ASYNCEVENT, 2),
- HPI_ASYNCEVENT_WAIT = HPI_FUNC_ID(ASYNCEVENT, 3),
- HPI_ASYNCEVENT_GETCOUNT = HPI_FUNC_ID(ASYNCEVENT, 4),
- HPI_ASYNCEVENT_GET = HPI_FUNC_ID(ASYNCEVENT, 5),
- HPI_ASYNCEVENT_SENDEVENTS = HPI_FUNC_ID(ASYNCEVENT, 6),
-#define HPI_ASYNCEVENT_FUNCTION_COUNT 6
-
- HPI_WATCHDOG_OPEN = HPI_FUNC_ID(WATCHDOG, 1),
- HPI_WATCHDOG_SET_TIME = HPI_FUNC_ID(WATCHDOG, 2),
- HPI_WATCHDOG_PING = HPI_FUNC_ID(WATCHDOG, 3),
-
- HPI_CLOCK_OPEN = HPI_FUNC_ID(CLOCK, 1),
- HPI_CLOCK_SET_TIME = HPI_FUNC_ID(CLOCK, 2),
- HPI_CLOCK_GET_TIME = HPI_FUNC_ID(CLOCK, 3),
-
- HPI_PROFILE_OPEN_ALL = HPI_FUNC_ID(PROFILE, 1),
- HPI_PROFILE_START_ALL = HPI_FUNC_ID(PROFILE, 2),
- HPI_PROFILE_STOP_ALL = HPI_FUNC_ID(PROFILE, 3),
- HPI_PROFILE_GET = HPI_FUNC_ID(PROFILE, 4),
- HPI_PROFILE_GET_IDLECOUNT = HPI_FUNC_ID(PROFILE, 5),
- HPI_PROFILE_GET_NAME = HPI_FUNC_ID(PROFILE, 6),
- HPI_PROFILE_GET_UTILIZATION = HPI_FUNC_ID(PROFILE, 7)
-#define HPI_PROFILE_FUNCTION_COUNT 7
-};
-
-/* ////////////////////////////////////////////////////////////////////// */
-/* STRUCTURES */
-#ifndef DISABLE_PRAGMA_PACK1
-#pragma pack(push, 1)
-#endif
-
-/** PCI bus resource */
-struct hpi_pci {
- u32 __iomem *ap_mem_base[HPI_MAX_ADAPTER_MEM_SPACES];
- struct pci_dev *pci_dev;
-};
-
-struct hpi_resource {
- union {
- const struct hpi_pci *pci;
- const char *net_if;
- } r;
-#ifndef HPI64BIT /* keep structure size constant */
- u32 pad_to64;
-#endif
- u16 bus_type; /* HPI_BUS_PNPISA, _PCI, _USB etc */
- u16 padding;
-
-};
-
-/** Format info used inside struct hpi_message
- Not the same as public API struct hpi_format */
-struct hpi_msg_format {
- u32 sample_rate; /**< 11025, 32000, 44100 etc. */
- u32 bit_rate; /**< for MPEG */
- u32 attributes; /**< stereo/joint_stereo/mono */
- u16 channels; /**< 1,2..., (or ancillary mode or idle bit */
- u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see \ref HPI_FORMATS. */
-};
-
-/** Buffer+format structure.
- Must be kept 7 * 32 bits to match public struct hpi_datastruct */
-struct hpi_msg_data {
- struct hpi_msg_format format;
- u8 *pb_data;
-#ifndef HPI64BIT
- u32 padding;
-#endif
- u32 data_size;
-};
-
-/** struct hpi_datastructure used up to 3.04 driver */
-struct hpi_data_legacy32 {
- struct hpi_format format;
- u32 pb_data;
- u32 data_size;
-};
-
-#ifdef HPI64BIT
-/* Compatibility version of struct hpi_data*/
-struct hpi_data_compat32 {
- struct hpi_msg_format format;
- u32 pb_data;
- u32 padding;
- u32 data_size;
-};
-#endif
-
-struct hpi_buffer {
- /** placeholder for backward compatibility (see dwBufferSize) */
- struct hpi_msg_format reserved;
- u32 command; /**< HPI_BUFFER_CMD_xxx*/
- u32 pci_address; /**< PCI physical address of buffer for DSP DMA */
- u32 buffer_size; /**< must line up with data_size of HPI_DATA*/
-};
-
-/*/////////////////////////////////////////////////////////////////////////// */
-/* This is used for background buffer bus mastering stream buffers. */
-struct hpi_hostbuffer_status {
- u32 samples_processed;
- u32 auxiliary_data_available;
- u32 stream_state;
- /* DSP index in to the host bus master buffer. */
- u32 dsp_index;
- /* Host index in to the host bus master buffer. */
- u32 host_index;
- u32 size_in_bytes;
-};
-
-struct hpi_streamid {
- u16 object_type;
- /**< Type of object, HPI_OBJ_OSTREAM or HPI_OBJ_ISTREAM. */
- u16 stream_index; /**< outstream or instream index. */
-};
-
-struct hpi_punchinout {
- u32 punch_in_sample;
- u32 punch_out_sample;
-};
-
-struct hpi_subsys_msg {
- struct hpi_resource resource;
-};
-
-struct hpi_subsys_res {
- u32 version;
- u32 data; /* extended version */
- u16 num_adapters;
- u16 adapter_index;
- u16 adapter_type;
- u16 pad16;
-};
-
-union hpi_adapterx_msg {
- struct {
- u32 dsp_address;
- u32 count_bytes;
- } debug_read;
- struct {
- u32 adapter_mode;
- u16 query_or_set;
- } mode;
- struct {
- u16 index;
- } module_info;
- struct {
- u16 index;
- u16 what;
- u16 property_index;
- } property_enum;
- struct {
- u16 property;
- u16 parameter1;
- u16 parameter2;
- } property_set;
- struct {
- u32 pad32;
- u16 key1;
- u16 key2;
- } restart;
- struct {
- u32 pad32;
- u16 value;
- } test_assert;
- struct {
- u32 yes;
- } irq_query;
- u32 pad[3];
-};
-
-struct hpi_adapter_res {
- u32 serial_number;
- u16 adapter_type;
- u16 adapter_index;
- u16 num_instreams;
- u16 num_outstreams;
- u16 num_mixers;
- u16 version;
- u8 sz_adapter_assert[HPI_STRING_LEN];
-};
-
-union hpi_adapterx_res {
- struct hpi_adapter_res info;
- struct {
- u32 p1;
- u16 count;
- u16 dsp_index;
- u32 p2;
- u32 dsp_msg_addr;
- char sz_message[HPI_STRING_LEN];
- } assert;
- struct {
- u32 adapter_mode;
- } mode;
- struct {
- u16 parameter1;
- u16 parameter2;
- } property_get;
- struct {
- u32 yes;
- } irq_query;
-};
-
-struct hpi_stream_msg {
- union {
- struct hpi_msg_data data;
- struct hpi_data_legacy32 data32;
- u16 velocity;
- struct hpi_punchinout pio;
- u32 time_scale;
- struct hpi_buffer buffer;
- struct hpi_streamid stream;
- u32 threshold_bytes;
- } u;
-};
-
-struct hpi_stream_res {
- union {
- struct {
- /* size of hardware buffer */
- u32 buffer_size;
- /* OutStream - data to play,
- InStream - data recorded */
- u32 data_available;
- /* OutStream - samples played,
- InStream - samples recorded */
- u32 samples_transferred;
- /* Adapter - OutStream - data to play,
- InStream - data recorded */
- u32 auxiliary_data_available;
- u16 state; /* HPI_STATE_PLAYING, _STATE_STOPPED */
- u16 padding;
- } stream_info;
- struct {
- u32 buffer_size;
- u32 data_available;
- u32 samples_transfered;
- u16 state;
- u16 outstream_index;
- u16 instream_index;
- u16 padding;
- u32 auxiliary_data_available;
- } legacy_stream_info;
- struct {
- /* bitmap of grouped OutStreams */
- u32 outstream_group_map;
- /* bitmap of grouped InStreams */
- u32 instream_group_map;
- } group_info;
- struct {
- /* pointer to the buffer */
- u8 *p_buffer;
- /* pointer to the hostbuffer status */
- struct hpi_hostbuffer_status *p_status;
- } hostbuffer_info;
- } u;
-};
-
-struct hpi_mixer_msg {
- u16 control_index;
- u16 control_type; /* = HPI_CONTROL_METER _VOLUME etc */
- u16 padding1; /* Maintain alignment of subsequent fields */
- u16 node_type1; /* = HPI_SOURCENODE_LINEIN etc */
- u16 node_index1; /* = 0..N */
- u16 node_type2;
- u16 node_index2;
- u16 padding2; /* round to 4 bytes */
-};
-
-struct hpi_mixer_res {
- u16 src_node_type; /* = HPI_SOURCENODE_LINEIN etc */
- u16 src_node_index; /* = 0..N */
- u16 dst_node_type;
- u16 dst_node_index;
- /* Also controlType for MixerGetControlByIndex */
- u16 control_index;
- /* may indicate which DSP the control is located on */
- u16 dsp_index;
-};
-
-union hpi_mixerx_msg {
- struct {
- u16 starting_index;
- u16 flags;
- u32 length_in_bytes; /* length in bytes of p_data */
- u32 p_data; /* pointer to a data array */
- } gcabi;
- struct {
- u16 command;
- u16 index;
- } store; /* for HPI_MIXER_STORE message */
-};
-
-union hpi_mixerx_res {
- struct {
- u32 bytes_returned; /* size of items returned */
- u32 p_data; /* pointer to data array */
- u16 more_to_do; /* indicates if there is more to do */
- } gcabi;
- struct {
- u32 total_controls; /* count of controls in the mixer */
- u32 cache_controls; /* count of controls in the cac */
- u32 cache_bytes; /* size of cache */
- } cache_info;
-};
-
-struct hpi_control_msg {
- u16 attribute; /* control attribute or property */
- u16 saved_index;
- u32 param1; /* generic parameter 1 */
- u32 param2; /* generic parameter 2 */
- short an_log_value[HPI_MAX_CHANNELS];
-};
-
-struct hpi_control_union_msg {
- u16 attribute; /* control attribute or property */
- u16 saved_index; /* only used in ctrl save/restore */
- union {
- struct {
- u32 param1; /* generic parameter 1 */
- u32 param2; /* generic parameter 2 */
- short an_log_value[HPI_MAX_CHANNELS];
- } old;
- union {
- u32 frequency;
- u32 gain;
- u32 band;
- u32 deemphasis;
- u32 program;
- struct {
- u32 mode;
- u32 value;
- } mode;
- u32 blend;
- } tuner;
- } u;
-};
-
-struct hpi_control_res {
- /* Could make union. dwParam, anLogValue never used in same response */
- u32 param1;
- u32 param2;
- short an_log_value[HPI_MAX_CHANNELS];
-};
-
-union hpi_control_union_res {
- struct {
- u32 param1;
- u32 param2;
- short an_log_value[HPI_MAX_CHANNELS];
- } old;
- union {
- u32 band;
- u32 frequency;
- u32 gain;
- u32 deemphasis;
- struct {
- u32 data[2];
- u32 bLER;
- } rds;
- short s_level;
- struct {
- u16 value;
- u16 mask;
- } status;
- } tuner;
- struct {
- char sz_data[8];
- u32 remaining_chars;
- } chars8;
- char c_data12[12];
- union {
- struct {
- u32 status;
- u32 readable_size;
- u32 writeable_size;
- } status;
- } cobranet;
-};
-
-struct hpi_nvmemory_msg {
- u16 address;
- u16 data;
-};
-
-struct hpi_nvmemory_res {
- u16 size_in_bytes;
- u16 data;
-};
-
-struct hpi_gpio_msg {
- u16 bit_index;
- u16 bit_data;
-};
-
-struct hpi_gpio_res {
- u16 number_input_bits;
- u16 number_output_bits;
- u16 bit_data[4];
-};
-
-struct hpi_async_msg {
- u32 events;
- u16 maximum_events;
- u16 padding;
-};
-
-struct hpi_async_res {
- union {
- struct {
- u16 count;
- } count;
- struct {
- u32 events;
- u16 number_returned;
- u16 padding;
- } get;
- struct hpi_async_event event;
- } u;
-};
-
-struct hpi_watchdog_msg {
- u32 time_ms;
-};
-
-struct hpi_watchdog_res {
- u32 time_ms;
-};
-
-struct hpi_clock_msg {
- u16 hours;
- u16 minutes;
- u16 seconds;
- u16 milli_seconds;
-};
-
-struct hpi_clock_res {
- u16 size_in_bytes;
- u16 hours;
- u16 minutes;
- u16 seconds;
- u16 milli_seconds;
- u16 padding;
-};
-
-struct hpi_profile_msg {
- u16 bin_index;
- u16 padding;
-};
-
-struct hpi_profile_res_open {
- u16 max_profiles;
-};
-
-struct hpi_profile_res_time {
- u32 total_tick_count;
- u32 call_count;
- u32 max_tick_count;
- u32 ticks_per_millisecond;
- u16 profile_interval;
-};
-
-struct hpi_profile_res_name {
- u8 sz_name[32];
-};
-
-struct hpi_profile_res {
- union {
- struct hpi_profile_res_open o;
- struct hpi_profile_res_time t;
- struct hpi_profile_res_name n;
- } u;
-};
-
-struct hpi_message_header {
- u16 size; /* total size in bytes */
- u8 type; /* HPI_TYPE_MESSAGE */
- u8 version; /* message version */
- u16 object; /* HPI_OBJ_* */
- u16 function; /* HPI_SUBSYS_xxx, HPI_ADAPTER_xxx */
- u16 adapter_index; /* the adapter index */
- u16 obj_index; /* */
-};
-
-struct hpi_message {
- /* following fields must match HPI_MESSAGE_HEADER */
- u16 size; /* total size in bytes */
- u8 type; /* HPI_TYPE_MESSAGE */
- u8 version; /* message version */
- u16 object; /* HPI_OBJ_* */
- u16 function; /* HPI_SUBSYS_xxx, HPI_ADAPTER_xxx */
- u16 adapter_index; /* the adapter index */
- u16 obj_index; /* */
- union {
- struct hpi_subsys_msg s;
- union hpi_adapterx_msg ax;
- struct hpi_stream_msg d;
- struct hpi_mixer_msg m;
- union hpi_mixerx_msg mx; /* extended mixer; */
- struct hpi_control_msg c; /* mixer control; */
- /* identical to struct hpi_control_msg,
- but field naming is improved */
- struct hpi_control_union_msg cu;
- struct hpi_nvmemory_msg n;
- struct hpi_gpio_msg l; /* digital i/o */
- struct hpi_watchdog_msg w;
- struct hpi_clock_msg t; /* dsp time */
- struct hpi_profile_msg p;
- struct hpi_async_msg as;
- char fixed_size[32];
- } u;
-};
-
-#define HPI_MESSAGE_SIZE_BY_OBJECT { \
- sizeof(struct hpi_message_header) , /* Default, no object type 0 */ \
- sizeof(struct hpi_message_header) + sizeof(struct hpi_subsys_msg),\
- sizeof(struct hpi_message_header) + sizeof(union hpi_adapterx_msg),\
- sizeof(struct hpi_message_header) + sizeof(struct hpi_stream_msg),\
- sizeof(struct hpi_message_header) + sizeof(struct hpi_stream_msg),\
- sizeof(struct hpi_message_header) + sizeof(struct hpi_mixer_msg),\
- sizeof(struct hpi_message_header) , /* no node message */ \
- sizeof(struct hpi_message_header) + sizeof(struct hpi_control_msg),\
- sizeof(struct hpi_message_header) + sizeof(struct hpi_nvmemory_msg),\
- sizeof(struct hpi_message_header) + sizeof(struct hpi_gpio_msg),\
- sizeof(struct hpi_message_header) + sizeof(struct hpi_watchdog_msg),\
- sizeof(struct hpi_message_header) + sizeof(struct hpi_clock_msg),\
- sizeof(struct hpi_message_header) + sizeof(struct hpi_profile_msg),\
- sizeof(struct hpi_message_header), /* controlx obj removed */ \
- sizeof(struct hpi_message_header) + sizeof(struct hpi_async_msg) \
-}
-
-/*
-Note that the wSpecificError error field should be inspected and potentially
-reported whenever HPI_ERROR_DSP_COMMUNICATION or HPI_ERROR_DSP_BOOTLOAD is
-returned in wError.
-*/
-struct hpi_response_header {
- u16 size;
- u8 type; /* HPI_TYPE_RESPONSE */
- u8 version; /* response version */
- u16 object; /* HPI_OBJ_* */
- u16 function; /* HPI_SUBSYS_xxx, HPI_ADAPTER_xxx */
- u16 error; /* HPI_ERROR_xxx */
- u16 specific_error; /* adapter specific error */
-};
-
-struct hpi_response {
-/* following fields must match HPI_RESPONSE_HEADER */
- u16 size;
- u8 type; /* HPI_TYPE_RESPONSE */
- u8 version; /* response version */
- u16 object; /* HPI_OBJ_* */
- u16 function; /* HPI_SUBSYS_xxx, HPI_ADAPTER_xxx */
- u16 error; /* HPI_ERROR_xxx */
- u16 specific_error; /* adapter specific error */
- union {
- struct hpi_subsys_res s;
- union hpi_adapterx_res ax;
- struct hpi_stream_res d;
- struct hpi_mixer_res m;
- union hpi_mixerx_res mx; /* extended mixer; */
- struct hpi_control_res c; /* mixer control; */
- /* identical to hpi_control_res, but field naming is improved */
- union hpi_control_union_res cu;
- struct hpi_nvmemory_res n;
- struct hpi_gpio_res l; /* digital i/o */
- struct hpi_watchdog_res w;
- struct hpi_clock_res t; /* dsp time */
- struct hpi_profile_res p;
- struct hpi_async_res as;
- u8 bytes[52];
- } u;
-};
-
-#define HPI_RESPONSE_SIZE_BY_OBJECT { \
- sizeof(struct hpi_response_header) ,/* Default, no object type 0 */ \
- sizeof(struct hpi_response_header) + sizeof(struct hpi_subsys_res),\
- sizeof(struct hpi_response_header) + sizeof(union hpi_adapterx_res),\
- sizeof(struct hpi_response_header) + sizeof(struct hpi_stream_res),\
- sizeof(struct hpi_response_header) + sizeof(struct hpi_stream_res),\
- sizeof(struct hpi_response_header) + sizeof(struct hpi_mixer_res),\
- sizeof(struct hpi_response_header) , /* no node response */ \
- sizeof(struct hpi_response_header) + sizeof(struct hpi_control_res),\
- sizeof(struct hpi_response_header) + sizeof(struct hpi_nvmemory_res),\
- sizeof(struct hpi_response_header) + sizeof(struct hpi_gpio_res),\
- sizeof(struct hpi_response_header) + sizeof(struct hpi_watchdog_res),\
- sizeof(struct hpi_response_header) + sizeof(struct hpi_clock_res),\
- sizeof(struct hpi_response_header) + sizeof(struct hpi_profile_res),\
- sizeof(struct hpi_response_header), /* controlx obj removed */ \
- sizeof(struct hpi_response_header) + sizeof(struct hpi_async_res) \
-}
-
-/*********************** version 1 message/response **************************/
-#define HPINET_ETHERNET_DATA_SIZE (1500)
-#define HPINET_IP_HDR_SIZE (20)
-#define HPINET_IP_DATA_SIZE (HPINET_ETHERNET_DATA_SIZE - HPINET_IP_HDR_SIZE)
-#define HPINET_UDP_HDR_SIZE (8)
-#define HPINET_UDP_DATA_SIZE (HPINET_IP_DATA_SIZE - HPINET_UDP_HDR_SIZE)
-#define HPINET_ASI_HDR_SIZE (2)
-#define HPINET_ASI_DATA_SIZE (HPINET_UDP_DATA_SIZE - HPINET_ASI_HDR_SIZE)
-
-#define HPI_MAX_PAYLOAD_SIZE (HPINET_ASI_DATA_SIZE - 2)
-
-/* New style message/response, but still V0 compatible */
-struct hpi_msg_adapter_get_info {
- struct hpi_message_header h;
-};
-
-struct hpi_res_adapter_get_info {
- struct hpi_response_header h; /*v0 */
- struct hpi_adapter_res p;
-};
-
-struct hpi_res_adapter_debug_read {
- struct hpi_response_header h;
- u8 bytes[1024];
-};
-
-struct hpi_msg_cobranet_hmi {
- u16 attribute;
- u16 padding;
- u32 hmi_address;
- u32 byte_count;
-};
-
-struct hpi_msg_cobranet_hmiwrite {
- struct hpi_message_header h;
- struct hpi_msg_cobranet_hmi p;
- u8 bytes[256];
-};
-
-struct hpi_msg_cobranet_hmiread {
- struct hpi_message_header h;
- struct hpi_msg_cobranet_hmi p;
-};
-
-struct hpi_res_cobranet_hmiread {
- struct hpi_response_header h;
- u32 byte_count;
- u8 bytes[256];
-};
-
-#if 1
-#define hpi_message_header_v1 hpi_message_header
-#define hpi_response_header_v1 hpi_response_header
-#else
-/* V1 headers in Addition to v0 headers */
-struct hpi_message_header_v1 {
- struct hpi_message_header h0;
-/* struct {
-} h1; */
-};
-
-struct hpi_response_header_v1 {
- struct hpi_response_header h0;
- struct {
- u16 adapter_index; /* the adapter index */
- u16 obj_index; /* object index */
- } h1;
-};
-#endif
-
-struct hpi_msg_payload_v0 {
- struct hpi_message_header h;
- union {
- struct hpi_subsys_msg s;
- union hpi_adapterx_msg ax;
- struct hpi_stream_msg d;
- struct hpi_mixer_msg m;
- union hpi_mixerx_msg mx;
- struct hpi_control_msg c;
- struct hpi_control_union_msg cu;
- struct hpi_nvmemory_msg n;
- struct hpi_gpio_msg l;
- struct hpi_watchdog_msg w;
- struct hpi_clock_msg t;
- struct hpi_profile_msg p;
- struct hpi_async_msg as;
- } u;
-};
-
-struct hpi_res_payload_v0 {
- struct hpi_response_header h;
- union {
- struct hpi_subsys_res s;
- union hpi_adapterx_res ax;
- struct hpi_stream_res d;
- struct hpi_mixer_res m;
- union hpi_mixerx_res mx;
- struct hpi_control_res c;
- union hpi_control_union_res cu;
- struct hpi_nvmemory_res n;
- struct hpi_gpio_res l;
- struct hpi_watchdog_res w;
- struct hpi_clock_res t;
- struct hpi_profile_res p;
- struct hpi_async_res as;
- } u;
-};
-
-union hpi_message_buffer_v1 {
- struct hpi_message m0; /* version 0 */
- struct hpi_message_header_v1 h;
- u8 buf[HPI_MAX_PAYLOAD_SIZE];
-};
-
-union hpi_response_buffer_v1 {
- struct hpi_response r0; /* version 0 */
- struct hpi_response_header_v1 h;
- u8 buf[HPI_MAX_PAYLOAD_SIZE];
-};
-
-compile_time_assert((sizeof(union hpi_message_buffer_v1) <=
- HPI_MAX_PAYLOAD_SIZE), message_buffer_ok);
-compile_time_assert((sizeof(union hpi_response_buffer_v1) <=
- HPI_MAX_PAYLOAD_SIZE), response_buffer_ok);
-
-/*////////////////////////////////////////////////////////////////////////// */
-/* declarations for compact control calls */
-struct hpi_control_defn {
- u8 type;
- u8 channels;
- u8 src_node_type;
- u8 src_node_index;
- u8 dest_node_type;
- u8 dest_node_index;
-};
-
-/*////////////////////////////////////////////////////////////////////////// */
-/* declarations for control caching (internal to HPI<->DSP interaction) */
-
-/** indicates a cached u16 value is invalid. */
-#define HPI_CACHE_INVALID_UINT16 0xFFFF
-/** indicates a cached short value is invalid. */
-#define HPI_CACHE_INVALID_SHORT -32768
-
-/** A compact representation of (part of) a controls state.
-Used for efficient transfer of the control state
-between DSP and host or across a network
-*/
-struct hpi_control_cache_info {
- /** one of HPI_CONTROL_* */
- u8 control_type;
- /** The total size of cached information in 32-bit words. */
- u8 size_in32bit_words;
- /** The original index of the control on the DSP */
- u16 control_index;
-};
-
-struct hpi_control_cache_vol {
- struct hpi_control_cache_info i;
- short an_log[2];
- unsigned short flags;
- char padding[2];
-};
-
-struct hpi_control_cache_meter {
- struct hpi_control_cache_info i;
- short an_log_peak[2];
- short an_logRMS[2];
-};
-
-struct hpi_control_cache_channelmode {
- struct hpi_control_cache_info i;
- u16 mode;
- char temp_padding[6];
-};
-
-struct hpi_control_cache_mux {
- struct hpi_control_cache_info i;
- u16 source_node_type;
- u16 source_node_index;
- char temp_padding[4];
-};
-
-struct hpi_control_cache_level {
- struct hpi_control_cache_info i;
- short an_log[2];
- char temp_padding[4];
-};
-
-struct hpi_control_cache_tuner {
- struct hpi_control_cache_info i;
- u32 freq_ink_hz;
- u16 band;
- short s_level_avg;
-};
-
-struct hpi_control_cache_aes3rx {
- struct hpi_control_cache_info i;
- u32 error_status;
- u32 format;
-};
-
-struct hpi_control_cache_aes3tx {
- struct hpi_control_cache_info i;
- u32 format;
- char temp_padding[4];
-};
-
-struct hpi_control_cache_tonedetector {
- struct hpi_control_cache_info i;
- u16 state;
- char temp_padding[6];
-};
-
-struct hpi_control_cache_silencedetector {
- struct hpi_control_cache_info i;
- u32 state;
- char temp_padding[4];
-};
-
-struct hpi_control_cache_sampleclock {
- struct hpi_control_cache_info i;
- u16 source;
- u16 source_index;
- u32 sample_rate;
-};
-
-struct hpi_control_cache_microphone {
- struct hpi_control_cache_info i;
- u16 phantom_state;
- char temp_padding[6];
-};
-
-struct hpi_control_cache_single {
- union {
- struct hpi_control_cache_info i;
- struct hpi_control_cache_vol vol;
- struct hpi_control_cache_meter meter;
- struct hpi_control_cache_channelmode mode;
- struct hpi_control_cache_mux mux;
- struct hpi_control_cache_level level;
- struct hpi_control_cache_tuner tuner;
- struct hpi_control_cache_aes3rx aes3rx;
- struct hpi_control_cache_aes3tx aes3tx;
- struct hpi_control_cache_tonedetector tone;
- struct hpi_control_cache_silencedetector silence;
- struct hpi_control_cache_sampleclock clk;
- struct hpi_control_cache_microphone microphone;
- } u;
-};
-
-struct hpi_control_cache_pad {
- struct hpi_control_cache_info i;
- u32 field_valid_flags;
- u8 c_channel[8];
- u8 c_artist[40];
- u8 c_title[40];
- u8 c_comment[200];
- u32 pTY;
- u32 pI;
- u32 traffic_supported;
- u32 traffic_anouncement;
-};
-
-/* 2^N sized FIFO buffer (internal to HPI<->DSP interaction) */
-struct hpi_fifo_buffer {
- u32 size;
- u32 dsp_index;
- u32 host_index;
-};
-
-#ifndef DISABLE_PRAGMA_PACK1
-#pragma pack(pop)
-#endif
-
-/* skip host side function declarations for DSP
- compile and documentation extraction */
-
-char hpi_handle_object(const u32 handle);
-
-void hpi_handle_to_indexes(const u32 handle, u16 *pw_adapter_index,
- u16 *pw_object_index);
-
-u32 hpi_indexes_to_handle(const char c_object, const u16 adapter_index,
- const u16 object_index);
-
-/*////////////////////////////////////////////////////////////////////////// */
-
-/* main HPI entry point */
-void hpi_send_recv(struct hpi_message *phm, struct hpi_response *phr);
-
-/* used in PnP OS/driver */
-u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource,
- u16 *pw_adapter_index);
-
-u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer,
- struct hpi_hostbuffer_status **pp_status);
-
-u16 hpi_instream_host_buffer_get_info(u32 h_instream, u8 **pp_buffer,
- struct hpi_hostbuffer_status **pp_status);
-
-u16 hpi_adapter_restart(u16 adapter_index);
-
-/*
-The following 3 functions were last declared in header files for
-driver 3.10. HPI_ControlQuery() used to be the recommended way
-of getting a volume range. Declared here for binary asihpi32.dll
-compatibility.
-*/
-
-void hpi_format_to_msg(struct hpi_msg_format *pMF,
- const struct hpi_format *pF);
-void hpi_stream_response_to_legacy(struct hpi_stream_res *pSR);
-
-/*////////////////////////////////////////////////////////////////////////// */
-/* declarations for individual HPI entry points */
-hpi_handler_func HPI_6000;
-hpi_handler_func HPI_6205;
-
-#endif /* _HPI_INTERNAL_H_ */
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpi_version.h b/ANDROID_3.4.5/sound/pci/asihpi/hpi_version.h
deleted file mode 100644
index e9146e53..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpi_version.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/** HPI Version Definitions
-Development releases have odd minor version.
-Production releases have even minor version.
-
-\file hpi_version.h
-*/
-
-#ifndef _HPI_VERSION_H
-#define _HPI_VERSION_H
-
-/* Use single digits for versions less that 10 to avoid octal. */
-/* *** HPI_VER is the only edit required to update version *** */
-/** HPI version */
-#define HPI_VER HPI_VERSION_CONSTRUCTOR(4, 10, 1)
-
-/** HPI version string in dotted decimal format */
-#define HPI_VER_STRING "4.10.01"
-
-/** Library version as documented in hpi-api-versions.txt */
-#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(10, 2, 0)
-
-/** Construct hpi version number from major, minor, release numbers */
-#define HPI_VERSION_CONSTRUCTOR(maj, min, r) ((maj << 16) + (min << 8) + r)
-
-/** Extract major version from hpi version number */
-#define HPI_VER_MAJOR(v) ((int)(v >> 16))
-/** Extract minor version from hpi version number */
-#define HPI_VER_MINOR(v) ((int)((v >> 8) & 0xFF))
-/** Extract release from hpi version number */
-#define HPI_VER_RELEASE(v) ((int)(v & 0xFF))
-
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpicmn.c b/ANDROID_3.4.5/sound/pci/asihpi/hpicmn.c
deleted file mode 100644
index 7ed5c26c..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpicmn.c
+++ /dev/null
@@ -1,703 +0,0 @@
-/******************************************************************************
-
- AudioScience HPI driver
- Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-\file hpicmn.c
-
- Common functions used by hpixxxx.c modules
-
-(C) Copyright AudioScience Inc. 1998-2003
-*******************************************************************************/
-#define SOURCEFILE_NAME "hpicmn.c"
-
-#include "hpi_internal.h"
-#include "hpidebug.h"
-#include "hpimsginit.h"
-
-#include "hpicmn.h"
-
-struct hpi_adapters_list {
- struct hpios_spinlock list_lock;
- struct hpi_adapter_obj adapter[HPI_MAX_ADAPTERS];
- u16 gw_num_adapters;
-};
-
-static struct hpi_adapters_list adapters;
-
-/**
-* Given an HPI Message that was sent out and a response that was received,
-* validate that the response has the correct fields filled in,
-* i.e ObjectType, Function etc
-**/
-u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
-{
- if (phr->type != HPI_TYPE_RESPONSE) {
- HPI_DEBUG_LOG(ERROR, "header type %d invalid\n", phr->type);
- return HPI_ERROR_INVALID_RESPONSE;
- }
-
- if (phr->object != phm->object) {
- HPI_DEBUG_LOG(ERROR, "header object %d invalid\n",
- phr->object);
- return HPI_ERROR_INVALID_RESPONSE;
- }
-
- if (phr->function != phm->function) {
- HPI_DEBUG_LOG(ERROR, "header function %d invalid\n",
- phr->function);
- return HPI_ERROR_INVALID_RESPONSE;
- }
-
- return 0;
-}
-
-u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
-{
- u16 retval = 0;
- /*HPI_ASSERT(pao->type); */
-
- hpios_alistlock_lock(&adapters);
-
- if (pao->index >= HPI_MAX_ADAPTERS) {
- retval = HPI_ERROR_BAD_ADAPTER_NUMBER;
- goto unlock;
- }
-
- if (adapters.adapter[pao->index].type) {
- int a;
- for (a = HPI_MAX_ADAPTERS - 1; a >= 0; a--) {
- if (!adapters.adapter[a].type) {
- HPI_DEBUG_LOG(WARNING,
- "ASI%X duplicate index %d moved to %d\n",
- pao->type, pao->index, a);
- pao->index = a;
- break;
- }
- }
- if (a < 0) {
- retval = HPI_ERROR_DUPLICATE_ADAPTER_NUMBER;
- goto unlock;
- }
- }
- adapters.adapter[pao->index] = *pao;
- hpios_dsplock_init(&adapters.adapter[pao->index]);
- adapters.gw_num_adapters++;
-
-unlock:
- hpios_alistlock_unlock(&adapters);
- return retval;
-}
-
-void hpi_delete_adapter(struct hpi_adapter_obj *pao)
-{
- if (!pao->type) {
- HPI_DEBUG_LOG(ERROR, "removing null adapter?\n");
- return;
- }
-
- hpios_alistlock_lock(&adapters);
- if (adapters.adapter[pao->index].type)
- adapters.gw_num_adapters--;
- memset(&adapters.adapter[pao->index], 0, sizeof(adapters.adapter[0]));
- hpios_alistlock_unlock(&adapters);
-}
-
-/**
-* FindAdapter returns a pointer to the struct hpi_adapter_obj with
-* index wAdapterIndex in an HPI_ADAPTERS_LIST structure.
-*
-*/
-struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
-{
- struct hpi_adapter_obj *pao = NULL;
-
- if (adapter_index >= HPI_MAX_ADAPTERS) {
- HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d\n",
- adapter_index);
- return NULL;
- }
-
- pao = &adapters.adapter[adapter_index];
- if (pao->type != 0) {
- /*
- HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n",
- wAdapterIndex);
- */
- return pao;
- } else {
- /*
- HPI_DEBUG_LOG(VERBOSE, "No adapter index %d\n",
- wAdapterIndex);
- */
- return NULL;
- }
-}
-
-/**
-*
-* wipe an HPI_ADAPTERS_LIST structure.
-*
-**/
-static void wipe_adapter_list(void)
-{
- memset(&adapters, 0, sizeof(adapters));
-}
-
-static void subsys_get_adapter(struct hpi_message *phm,
- struct hpi_response *phr)
-{
- int count = phm->obj_index;
- u16 index = 0;
-
- /* find the nCount'th nonzero adapter in array */
- for (index = 0; index < HPI_MAX_ADAPTERS; index++) {
- if (adapters.adapter[index].type) {
- if (!count)
- break;
- count--;
- }
- }
-
- if (index < HPI_MAX_ADAPTERS) {
- phr->u.s.adapter_index = adapters.adapter[index].index;
- phr->u.s.adapter_type = adapters.adapter[index].type;
- } else {
- phr->u.s.adapter_index = 0;
- phr->u.s.adapter_type = 0;
- phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
- }
-}
-
-static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
-{
- unsigned int i;
- int cached = 0;
- if (!pC)
- return 0;
-
- if (pC->init)
- return pC->init;
-
- if (!pC->p_cache)
- return 0;
-
- if (pC->control_count && pC->cache_size_in_bytes) {
- char *p_master_cache;
- unsigned int byte_count = 0;
-
- p_master_cache = (char *)pC->p_cache;
- HPI_DEBUG_LOG(DEBUG, "check %d controls\n",
- pC->control_count);
- for (i = 0; i < pC->control_count; i++) {
- struct hpi_control_cache_info *info =
- (struct hpi_control_cache_info *)
- &p_master_cache[byte_count];
-
- if (!info->size_in32bit_words) {
- if (!i) {
- HPI_DEBUG_LOG(INFO,
- "adap %d cache not ready?\n",
- pC->adap_idx);
- return 0;
- }
- /* The cache is invalid.
- * Minimum valid entry size is
- * sizeof(struct hpi_control_cache_info)
- */
- HPI_DEBUG_LOG(ERROR,
- "adap %d zero size cache entry %d\n",
- pC->adap_idx, i);
- break;
- }
-
- if (info->control_type) {
- pC->p_info[info->control_index] = info;
- cached++;
- } else { /* dummy cache entry */
- pC->p_info[info->control_index] = NULL;
- }
-
- byte_count += info->size_in32bit_words * 4;
-
- HPI_DEBUG_LOG(VERBOSE,
- "cached %d, pinfo %p index %d type %d size %d\n",
- cached, pC->p_info[info->control_index],
- info->control_index, info->control_type,
- info->size_in32bit_words);
-
- /* quit loop early if whole cache has been scanned.
- * dwControlCount is the maximum possible entries
- * but some may be absent from the cache
- */
- if (byte_count >= pC->cache_size_in_bytes)
- break;
- /* have seen last control index */
- if (info->control_index == pC->control_count - 1)
- break;
- }
-
- if (byte_count != pC->cache_size_in_bytes)
- HPI_DEBUG_LOG(WARNING,
- "adap %d bytecount %d != cache size %d\n",
- pC->adap_idx, byte_count,
- pC->cache_size_in_bytes);
- else
- HPI_DEBUG_LOG(DEBUG,
- "adap %d cache good, bytecount == cache size = %d\n",
- pC->adap_idx, byte_count);
-
- pC->init = (u16)cached;
- }
- return pC->init;
-}
-
-/** Find a control.
-*/
-static short find_control(u16 control_index,
- struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI)
-{
- if (!control_cache_alloc_check(p_cache)) {
- HPI_DEBUG_LOG(VERBOSE,
- "control_cache_alloc_check() failed %d\n",
- control_index);
- return 0;
- }
-
- *pI = p_cache->p_info[control_index];
- if (!*pI) {
- HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
- control_index);
- return 0;
- } else {
- HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
- (*pI)->control_type);
- }
- return 1;
-}
-
-/* allow unified treatment of several string fields within struct */
-#define HPICMN_PAD_OFS_AND_SIZE(m) {\
- offsetof(struct hpi_control_cache_pad, m), \
- sizeof(((struct hpi_control_cache_pad *)(NULL))->m) }
-
-struct pad_ofs_size {
- unsigned int offset;
- unsigned int field_size;
-};
-
-static const struct pad_ofs_size pad_desc[] = {
- HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */
- HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */
- HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */
- HPICMN_PAD_OFS_AND_SIZE(c_comment), /* HPI_PAD_COMMENT */
-};
-
-/** CheckControlCache checks the cache and fills the struct hpi_response
- * accordingly. It returns one if a cache hit occurred, zero otherwise.
- */
-short hpi_check_control_cache(struct hpi_control_cache *p_cache,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- short found = 1;
- struct hpi_control_cache_info *pI;
- struct hpi_control_cache_single *pC;
- size_t response_size;
- if (!find_control(phm->obj_index, p_cache, &pI)) {
- HPI_DEBUG_LOG(VERBOSE,
- "HPICMN find_control() failed for adap %d\n",
- phm->adapter_index);
- return 0;
- }
-
- phr->error = 0;
- phr->specific_error = 0;
- phr->version = 0;
-
- /* set the default response size */
- response_size =
- sizeof(struct hpi_response_header) +
- sizeof(struct hpi_control_res);
-
- /* pC is the default cached control strucure. May be cast to
- something else in the following switch statement.
- */
- pC = (struct hpi_control_cache_single *)pI;
-
- switch (pI->control_type) {
-
- case HPI_CONTROL_METER:
- if (phm->u.c.attribute == HPI_METER_PEAK) {
- phr->u.c.an_log_value[0] = pC->u.meter.an_log_peak[0];
- phr->u.c.an_log_value[1] = pC->u.meter.an_log_peak[1];
- } else if (phm->u.c.attribute == HPI_METER_RMS) {
- if (pC->u.meter.an_logRMS[0] ==
- HPI_CACHE_INVALID_SHORT) {
- phr->error =
- HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
- phr->u.c.an_log_value[0] = HPI_METER_MINIMUM;
- phr->u.c.an_log_value[1] = HPI_METER_MINIMUM;
- } else {
- phr->u.c.an_log_value[0] =
- pC->u.meter.an_logRMS[0];
- phr->u.c.an_log_value[1] =
- pC->u.meter.an_logRMS[1];
- }
- } else
- found = 0;
- break;
- case HPI_CONTROL_VOLUME:
- if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
- phr->u.c.an_log_value[0] = pC->u.vol.an_log[0];
- phr->u.c.an_log_value[1] = pC->u.vol.an_log[1];
- } else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
- if (pC->u.vol.flags & HPI_VOLUME_FLAG_HAS_MUTE) {
- if (pC->u.vol.flags & HPI_VOLUME_FLAG_MUTED)
- phr->u.c.param1 =
- HPI_BITMASK_ALL_CHANNELS;
- else
- phr->u.c.param1 = 0;
- } else {
- phr->error =
- HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
- phr->u.c.param1 = 0;
- }
- } else {
- found = 0;
- }
- break;
- case HPI_CONTROL_MULTIPLEXER:
- if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
- phr->u.c.param1 = pC->u.mux.source_node_type;
- phr->u.c.param2 = pC->u.mux.source_node_index;
- } else {
- found = 0;
- }
- break;
- case HPI_CONTROL_CHANNEL_MODE:
- if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
- phr->u.c.param1 = pC->u.mode.mode;
- else
- found = 0;
- break;
- case HPI_CONTROL_LEVEL:
- if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
- phr->u.c.an_log_value[0] = pC->u.level.an_log[0];
- phr->u.c.an_log_value[1] = pC->u.level.an_log[1];
- } else
- found = 0;
- break;
- case HPI_CONTROL_TUNER:
- if (phm->u.c.attribute == HPI_TUNER_FREQ)
- phr->u.c.param1 = pC->u.tuner.freq_ink_hz;
- else if (phm->u.c.attribute == HPI_TUNER_BAND)
- phr->u.c.param1 = pC->u.tuner.band;
- else if (phm->u.c.attribute == HPI_TUNER_LEVEL_AVG)
- if (pC->u.tuner.s_level_avg ==
- HPI_CACHE_INVALID_SHORT) {
- phr->u.cu.tuner.s_level = 0;
- phr->error =
- HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
- } else
- phr->u.cu.tuner.s_level =
- pC->u.tuner.s_level_avg;
- else
- found = 0;
- break;
- case HPI_CONTROL_AESEBU_RECEIVER:
- if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS)
- phr->u.c.param1 = pC->u.aes3rx.error_status;
- else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
- phr->u.c.param1 = pC->u.aes3rx.format;
- else
- found = 0;
- break;
- case HPI_CONTROL_AESEBU_TRANSMITTER:
- if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
- phr->u.c.param1 = pC->u.aes3tx.format;
- else
- found = 0;
- break;
- case HPI_CONTROL_TONEDETECTOR:
- if (phm->u.c.attribute == HPI_TONEDETECTOR_STATE)
- phr->u.c.param1 = pC->u.tone.state;
- else
- found = 0;
- break;
- case HPI_CONTROL_SILENCEDETECTOR:
- if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
- phr->u.c.param1 = pC->u.silence.state;
- } else
- found = 0;
- break;
- case HPI_CONTROL_MICROPHONE:
- if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
- phr->u.c.param1 = pC->u.microphone.phantom_state;
- else
- found = 0;
- break;
- case HPI_CONTROL_SAMPLECLOCK:
- if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
- phr->u.c.param1 = pC->u.clk.source;
- else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) {
- if (pC->u.clk.source_index ==
- HPI_CACHE_INVALID_UINT16) {
- phr->u.c.param1 = 0;
- phr->error =
- HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
- } else
- phr->u.c.param1 = pC->u.clk.source_index;
- } else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
- phr->u.c.param1 = pC->u.clk.sample_rate;
- else
- found = 0;
- break;
- case HPI_CONTROL_PAD:{
- struct hpi_control_cache_pad *p_pad;
- p_pad = (struct hpi_control_cache_pad *)pI;
-
- if (!(p_pad->field_valid_flags & (1 <<
- HPI_CTL_ATTR_INDEX(phm->u.c.
- attribute)))) {
- phr->error =
- HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
- break;
- }
-
- if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
- phr->u.c.param1 = p_pad->pI;
- else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
- phr->u.c.param1 = p_pad->pTY;
- else {
- unsigned int index =
- HPI_CTL_ATTR_INDEX(phm->u.c.
- attribute) - 1;
- unsigned int offset = phm->u.c.param1;
- unsigned int pad_string_len, field_size;
- char *pad_string;
- unsigned int tocopy;
-
- if (index > ARRAY_SIZE(pad_desc) - 1) {
- phr->error =
- HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
- break;
- }
-
- pad_string =
- ((char *)p_pad) +
- pad_desc[index].offset;
- field_size = pad_desc[index].field_size;
- /* Ensure null terminator */
- pad_string[field_size - 1] = 0;
-
- pad_string_len = strlen(pad_string) + 1;
-
- if (offset > pad_string_len) {
- phr->error =
- HPI_ERROR_INVALID_CONTROL_VALUE;
- break;
- }
-
- tocopy = pad_string_len - offset;
- if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
- tocopy = sizeof(phr->u.cu.chars8.
- sz_data);
-
- memcpy(phr->u.cu.chars8.sz_data,
- &pad_string[offset], tocopy);
-
- phr->u.cu.chars8.remaining_chars =
- pad_string_len - offset - tocopy;
- }
- }
- break;
- default:
- found = 0;
- break;
- }
-
- HPI_DEBUG_LOG(VERBOSE, "%s Adap %d, Ctl %d, Type %d, Attr %d\n",
- found ? "Cached" : "Uncached", phm->adapter_index,
- pI->control_index, pI->control_type, phm->u.c.attribute);
-
- if (found) {
- phr->size = (u16)response_size;
- phr->type = HPI_TYPE_RESPONSE;
- phr->object = phm->object;
- phr->function = phm->function;
- }
-
- return found;
-}
-
-/** Updates the cache with Set values.
-
-Only update if no error.
-Volume and Level return the limited values in the response, so use these
-Multiplexer does so use sent values
-*/
-void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache,
- struct hpi_message *phm, struct hpi_response *phr)
-{
- struct hpi_control_cache_single *pC;
- struct hpi_control_cache_info *pI;
-
- if (phr->error)
- return;
-
- if (!find_control(phm->obj_index, p_cache, &pI)) {
- HPI_DEBUG_LOG(VERBOSE,
- "HPICMN find_control() failed for adap %d\n",
- phm->adapter_index);
- return;
- }
-
- /* pC is the default cached control strucure.
- May be cast to something else in the following switch statement.
- */
- pC = (struct hpi_control_cache_single *)pI;
-
- switch (pI->control_type) {
- case HPI_CONTROL_VOLUME:
- if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
- pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
- pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
- } else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
- if (phm->u.c.param1)
- pC->u.vol.flags |= HPI_VOLUME_FLAG_MUTED;
- else
- pC->u.vol.flags &= ~HPI_VOLUME_FLAG_MUTED;
- }
- break;
- case HPI_CONTROL_MULTIPLEXER:
- /* mux does not return its setting on Set command. */
- if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
- pC->u.mux.source_node_type = (u16)phm->u.c.param1;
- pC->u.mux.source_node_index = (u16)phm->u.c.param2;
- }
- break;
- case HPI_CONTROL_CHANNEL_MODE:
- /* mode does not return its setting on Set command. */
- if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
- pC->u.mode.mode = (u16)phm->u.c.param1;
- break;
- case HPI_CONTROL_LEVEL:
- if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
- pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
- pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
- }
- break;
- case HPI_CONTROL_MICROPHONE:
- if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
- pC->u.microphone.phantom_state = (u16)phm->u.c.param1;
- break;
- case HPI_CONTROL_AESEBU_TRANSMITTER:
- if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
- pC->u.aes3tx.format = phm->u.c.param1;
- break;
- case HPI_CONTROL_AESEBU_RECEIVER:
- if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
- pC->u.aes3rx.format = phm->u.c.param1;
- break;
- case HPI_CONTROL_SAMPLECLOCK:
- if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
- pC->u.clk.source = (u16)phm->u.c.param1;
- else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX)
- pC->u.clk.source_index = (u16)phm->u.c.param1;
- else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
- pC->u.clk.sample_rate = phm->u.c.param1;
- break;
- default:
- break;
- }
-}
-
-/** Allocate control cache.
-
-\return Cache pointer, or NULL if allocation fails.
-*/
-struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
- const u32 size_in_bytes, u8 *p_dsp_control_buffer)
-{
- struct hpi_control_cache *p_cache =
- kmalloc(sizeof(*p_cache), GFP_KERNEL);
- if (!p_cache)
- return NULL;
-
- p_cache->p_info = kcalloc(control_count, sizeof(*p_cache->p_info),
- GFP_KERNEL);
- if (!p_cache->p_info) {
- kfree(p_cache);
- return NULL;
- }
- p_cache->cache_size_in_bytes = size_in_bytes;
- p_cache->control_count = control_count;
- p_cache->p_cache = p_dsp_control_buffer;
- p_cache->init = 0;
- return p_cache;
-}
-
-void hpi_free_control_cache(struct hpi_control_cache *p_cache)
-{
- if (p_cache) {
- kfree(p_cache->p_info);
- kfree(p_cache);
- }
-}
-
-static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
-{
- hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 0);
-
- switch (phm->function) {
- case HPI_SUBSYS_OPEN:
- case HPI_SUBSYS_CLOSE:
- case HPI_SUBSYS_DRIVER_UNLOAD:
- break;
- case HPI_SUBSYS_DRIVER_LOAD:
- wipe_adapter_list();
- hpios_alistlock_init(&adapters);
- break;
- case HPI_SUBSYS_GET_ADAPTER:
- subsys_get_adapter(phm, phr);
- break;
- case HPI_SUBSYS_GET_NUM_ADAPTERS:
- phr->u.s.num_adapters = adapters.gw_num_adapters;
- break;
- case HPI_SUBSYS_CREATE_ADAPTER:
- break;
- default:
- phr->error = HPI_ERROR_INVALID_FUNC;
- break;
- }
-}
-
-void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
-{
- switch (phm->type) {
- case HPI_TYPE_REQUEST:
- switch (phm->object) {
- case HPI_OBJ_SUBSYSTEM:
- subsys_message(phm, phr);
- break;
- }
- break;
-
- default:
- phr->error = HPI_ERROR_INVALID_TYPE;
- break;
- }
-}
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpicmn.h b/ANDROID_3.4.5/sound/pci/asihpi/hpicmn.h
deleted file mode 100644
index e4412128..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpicmn.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
-
- AudioScience HPI driver
- Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-*/
-
-struct hpi_adapter_obj;
-
-/* a function that takes an adapter obj and returns an int */
-typedef int adapter_int_func(struct hpi_adapter_obj *pao);
-
-struct hpi_adapter_obj {
- struct hpi_pci pci; /* PCI info - bus#,dev#,address etc */
- u16 type; /* 0x6644 == ASI6644 etc */
- u16 index;
-
- struct hpios_spinlock dsp_lock;
-
- u16 dsp_crashed;
- u16 has_control_cache;
- void *priv;
-};
-
-struct hpi_control_cache {
- /** indicates whether the structures are initialized */
- u16 init;
- u16 adap_idx;
- u32 control_count;
- u32 cache_size_in_bytes;
- /** pointer to allocated memory of lookup pointers. */
- struct hpi_control_cache_info **p_info;
- /** pointer to DSP's control cache. */
- u8 *p_cache;
-};
-
-struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index);
-
-u16 hpi_add_adapter(struct hpi_adapter_obj *pao);
-
-void hpi_delete_adapter(struct hpi_adapter_obj *pao);
-
-short hpi_check_control_cache(struct hpi_control_cache *pC,
- struct hpi_message *phm, struct hpi_response *phr);
-struct hpi_control_cache *hpi_alloc_control_cache(const u32
- number_of_controls, const u32 size_in_bytes, u8 *pDSP_control_buffer);
-void hpi_free_control_cache(struct hpi_control_cache *p_cache);
-
-void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *pC,
- struct hpi_message *phm, struct hpi_response *phr);
-
-u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr);
-
-hpi_handler_func HPI_COMMON;
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpidebug.c b/ANDROID_3.4.5/sound/pci/asihpi/hpidebug.c
deleted file mode 100644
index ac86a1f1..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpidebug.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/************************************************************************
-
- AudioScience HPI driver
- Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Debug macro translation.
-
-************************************************************************/
-
-#include "hpi_internal.h"
-#include "hpidebug.h"
-
-/* Debug level; 0 quiet; 1 informative, 2 debug, 3 verbose debug. */
-int hpi_debug_level = HPI_DEBUG_LEVEL_DEFAULT;
-
-void hpi_debug_init(void)
-{
- printk(KERN_INFO "debug start\n");
-}
-
-int hpi_debug_level_set(int level)
-{
- int old_level;
-
- old_level = hpi_debug_level;
- hpi_debug_level = level;
- return old_level;
-}
-
-int hpi_debug_level_get(void)
-{
- return hpi_debug_level;
-}
-
-void hpi_debug_message(struct hpi_message *phm, char *sz_fileline)
-{
- if (phm) {
- printk(KERN_DEBUG "HPI_MSG%d,%d,%d,%d,%d\n", phm->version,
- phm->adapter_index, phm->obj_index, phm->function,
- phm->u.c.attribute);
- }
-
-}
-
-void hpi_debug_data(u16 *pdata, u32 len)
-{
- u32 i;
- int j;
- int k;
- int lines;
- int cols = 8;
-
- lines = (len + cols - 1) / cols;
- if (lines > 8)
- lines = 8;
-
- for (i = 0, j = 0; j < lines; j++) {
- printk(KERN_DEBUG "%p:", (pdata + i));
-
- for (k = 0; k < cols && i < len; i++, k++)
- printk("%s%04x", k == 0 ? "" : " ", pdata[i]);
-
- printk("\n");
- }
-}
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpidebug.h b/ANDROID_3.4.5/sound/pci/asihpi/hpidebug.h
deleted file mode 100644
index 2c9af232..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpidebug.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*****************************************************************************
-
- AudioScience HPI driver
- Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Debug macros.
-
-*****************************************************************************/
-
-#ifndef _HPIDEBUG_H
-#define _HPIDEBUG_H
-
-#include "hpi_internal.h"
-
-/* Define debugging levels. */
-enum { HPI_DEBUG_LEVEL_ERROR = 0, /* always log errors */
- HPI_DEBUG_LEVEL_WARNING = 1,
- HPI_DEBUG_LEVEL_NOTICE = 2,
- HPI_DEBUG_LEVEL_INFO = 3,
- HPI_DEBUG_LEVEL_DEBUG = 4,
- HPI_DEBUG_LEVEL_VERBOSE = 5 /* same printk level as DEBUG */
-};
-
-#define HPI_DEBUG_LEVEL_DEFAULT HPI_DEBUG_LEVEL_NOTICE
-
-/* an OS can define an extra flag string that is appended to
- the start of each message, eg see linux kernel hpios.h */
-
-#ifdef SOURCEFILE_NAME
-#define FILE_LINE SOURCEFILE_NAME ":" __stringify(__LINE__) " "
-#else
-#define FILE_LINE __FILE__ ":" __stringify(__LINE__) " "
-#endif
-
-#define HPI_DEBUG_ASSERT(expression) \
- do { \
- if (!(expression)) { \
- printk(KERN_ERR FILE_LINE \
- "ASSERT " __stringify(expression)); \
- } \
- } while (0)
-
-#define HPI_DEBUG_LOG(level, ...) \
- do { \
- if (hpi_debug_level >= HPI_DEBUG_LEVEL_##level) { \
- printk(HPI_DEBUG_FLAG_##level \
- FILE_LINE __VA_ARGS__); \
- } \
- } while (0)
-
-void hpi_debug_init(void);
-int hpi_debug_level_set(int level);
-int hpi_debug_level_get(void);
-/* needed by Linux driver for dynamic debug level changes */
-extern int hpi_debug_level;
-
-void hpi_debug_message(struct hpi_message *phm, char *sz_fileline);
-
-void hpi_debug_data(u16 *pdata, u32 len);
-
-#define HPI_DEBUG_DATA(pdata, len) \
- do { \
- if (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE) \
- hpi_debug_data(pdata, len); \
- } while (0)
-
-#define HPI_DEBUG_MESSAGE(level, phm) \
- do { \
- if (hpi_debug_level >= HPI_DEBUG_LEVEL_##level) { \
- hpi_debug_message(phm, HPI_DEBUG_FLAG_##level \
- FILE_LINE __stringify(level)); \
- } \
- } while (0)
-
-#define HPI_DEBUG_RESPONSE(phr) \
- do { \
- if (((hpi_debug_level >= HPI_DEBUG_LEVEL_DEBUG) && \
- (phr->error)) ||\
- (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE)) \
- printk(KERN_DEBUG "HPI_RES%d,%d,%d\n", \
- phr->version, phr->error, phr->specific_error); \
- } while (0)
-
-#ifndef compile_time_assert
-#define compile_time_assert(cond, msg) \
- typedef char msg[(cond) ? 1 : -1]
-#endif
-
-#endif /* _HPIDEBUG_H_ */
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpidspcd.c b/ANDROID_3.4.5/sound/pci/asihpi/hpidspcd.c
deleted file mode 100644
index 456a758f..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpidspcd.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/***********************************************************************/
-/**
-
- AudioScience HPI driver
- Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-\file
-Functions for reading DSP code using
-hotplug firmware loader from individual dsp code files
-*/
-/***********************************************************************/
-#define SOURCEFILE_NAME "hpidspcd.c"
-#include "hpidspcd.h"
-#include "hpidebug.h"
-#include "hpi_version.h"
-
-struct dsp_code_private {
- /** Firmware descriptor */
- const struct firmware *firmware;
- struct pci_dev *dev;
-};
-
-/*-------------------------------------------------------------------*/
-short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code,
- u32 *os_error_code)
-{
- const struct firmware *firmware;
- struct pci_dev *dev = os_data;
- struct code_header header;
- char fw_name[20];
- short err_ret = HPI_ERROR_DSP_FILE_NOT_FOUND;
- int err;
-
- sprintf(fw_name, "asihpi/dsp%04x.bin", adapter);
-
- err = request_firmware(&firmware, fw_name, &dev->dev);
-
- if (err || !firmware) {
- dev_printk(KERN_ERR, &dev->dev,
- "%d, request_firmware failed for %s\n", err,
- fw_name);
- goto error1;
- }
- if (firmware->size < sizeof(header)) {
- dev_printk(KERN_ERR, &dev->dev, "Header size too small %s\n",
- fw_name);
- goto error2;
- }
- memcpy(&header, firmware->data, sizeof(header));
-
- if ((header.type != 0x45444F43) || /* "CODE" */
- (header.adapter != adapter)
- || (header.size != firmware->size)) {
- dev_printk(KERN_ERR, &dev->dev,
- "Invalid firmware header size %d != file %zd\n",
- header.size, firmware->size);
- goto error2;
- }
-
- if ((header.version >> 9) != (HPI_VER >> 9)) {
- /* Consider even and subsequent odd minor versions to be compatible */
- dev_printk(KERN_ERR, &dev->dev,
- "Incompatible firmware version "
- "DSP image %X != Driver %X\n", header.version,
- HPI_VER);
- goto error2;
- }
-
- if (header.version != HPI_VER) {
- dev_printk(KERN_INFO, &dev->dev,
- "Firmware: release version mismatch DSP image %X != Driver %X\n",
- header.version, HPI_VER);
- }
-
- HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name);
- dsp_code->pvt = kmalloc(sizeof(*dsp_code->pvt), GFP_KERNEL);
- if (!dsp_code->pvt) {
- err_ret = HPI_ERROR_MEMORY_ALLOC;
- goto error2;
- }
-
- dsp_code->pvt->dev = dev;
- dsp_code->pvt->firmware = firmware;
- dsp_code->header = header;
- dsp_code->block_length = header.size / sizeof(u32);
- dsp_code->word_count = sizeof(header) / sizeof(u32);
- return 0;
-
-error2:
- release_firmware(firmware);
-error1:
- dsp_code->block_length = 0;
- return err_ret;
-}
-
-/*-------------------------------------------------------------------*/
-void hpi_dsp_code_close(struct dsp_code *dsp_code)
-{
- HPI_DEBUG_LOG(DEBUG, "dsp code closed\n");
- release_firmware(dsp_code->pvt->firmware);
- kfree(dsp_code->pvt);
-}
-
-/*-------------------------------------------------------------------*/
-void hpi_dsp_code_rewind(struct dsp_code *dsp_code)
-{
- /* Go back to start of data, after header */
- dsp_code->word_count = sizeof(struct code_header) / sizeof(u32);
-}
-
-/*-------------------------------------------------------------------*/
-short hpi_dsp_code_read_word(struct dsp_code *dsp_code, u32 *pword)
-{
- if (dsp_code->word_count + 1 > dsp_code->block_length)
- return HPI_ERROR_DSP_FILE_FORMAT;
-
- *pword = ((u32 *)(dsp_code->pvt->firmware->data))[dsp_code->
- word_count];
- dsp_code->word_count++;
- return 0;
-}
-
-/*-------------------------------------------------------------------*/
-short hpi_dsp_code_read_block(size_t words_requested,
- struct dsp_code *dsp_code, u32 **ppblock)
-{
- if (dsp_code->word_count + words_requested > dsp_code->block_length)
- return HPI_ERROR_DSP_FILE_FORMAT;
-
- *ppblock =
- ((u32 *)(dsp_code->pvt->firmware->data)) +
- dsp_code->word_count;
- dsp_code->word_count += words_requested;
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpidspcd.h b/ANDROID_3.4.5/sound/pci/asihpi/hpidspcd.h
deleted file mode 100644
index 659d19ca..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpidspcd.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/***********************************************************************/
-/**
-
- AudioScience HPI driver
- Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-\file
-Functions for reading DSP code to load into DSP
-
-*/
-/***********************************************************************/
-#ifndef _HPIDSPCD_H_
-#define _HPIDSPCD_H_
-
-#include "hpi_internal.h"
-
-/** Header structure for dsp firmware file
- This structure must match that used in s2bin.c for generation of asidsp.bin
- */
-/*#ifndef DISABLE_PRAGMA_PACK1 */
-/*#pragma pack(push, 1) */
-/*#endif */
-struct code_header {
- /** Size in bytes including header */
- u32 size;
- /** File type tag "CODE" == 0x45444F43 */
- u32 type;
- /** Adapter model number */
- u32 adapter;
- /** Firmware version*/
- u32 version;
- /** Data checksum */
- u32 checksum;
-};
-/*#ifndef DISABLE_PRAGMA_PACK1 */
-/*#pragma pack(pop) */
-/*#endif */
-
-/*? Don't need the pragmas? */
-compile_time_assert((sizeof(struct code_header) == 20), code_header_size);
-
-/** Descriptor for dspcode from firmware loader */
-struct dsp_code {
- /** copy of file header */
- struct code_header header;
- /** Expected number of words in the whole dsp code,INCL header */
- u32 block_length;
- /** Number of words read so far */
- u32 word_count;
-
- /** internal state of DSP code reader */
- struct dsp_code_private *pvt;
-};
-
-/** Prepare *psDspCode to refer to the requested adapter's firmware.
-Code file name is obtained from HpiOs_GetDspCodePath
-
-\return 0 for success, or error code if requested code is not available
-*/
-short hpi_dsp_code_open(
- /** Code identifier, usually adapter family */
- u32 adapter, void *pci_dev,
- /** Pointer to DSP code control structure */
- struct dsp_code *ps_dsp_code,
- /** Pointer to dword to receive OS specific error code */
- u32 *pos_error_code);
-
-/** Close the DSP code file */
-void hpi_dsp_code_close(struct dsp_code *ps_dsp_code);
-
-/** Rewind to the beginning of the DSP code file (for verify) */
-void hpi_dsp_code_rewind(struct dsp_code *ps_dsp_code);
-
-/** Read one word from the dsp code file
- \return 0 for success, or error code if eof, or block length exceeded
-*/
-short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code,
- /**< DSP code descriptor */
- u32 *pword /**< Where to store the read word */
- );
-
-/** Get a block of dsp code into an internal buffer, and provide a pointer to
-that buffer. (If dsp code is already an array in memory, it is referenced,
-not copied.)
-
-\return Error if requested number of words are not available
-*/
-short hpi_dsp_code_read_block(size_t words_requested,
- struct dsp_code *ps_dsp_code,
- /* Pointer to store (Pointer to code buffer) */
- u32 **ppblock);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpifunc.c b/ANDROID_3.4.5/sound/pci/asihpi/hpifunc.c
deleted file mode 100644
index 510e56cf..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpifunc.c
+++ /dev/null
@@ -1,2871 +0,0 @@
-
-#include "hpi_internal.h"
-#include "hpimsginit.h"
-
-#include "hpidebug.h"
-
-struct hpi_handle {
- unsigned int obj_index:12;
- unsigned int obj_type:4;
- unsigned int adapter_index:14;
- unsigned int spare:1;
- unsigned int read_only:1;
-};
-
-union handle_word {
- struct hpi_handle h;
- u32 w;
-};
-
-u32 hpi_indexes_to_handle(const char c_object, const u16 adapter_index,
- const u16 object_index)
-{
- union handle_word handle;
-
- handle.h.adapter_index = adapter_index;
- handle.h.spare = 0;
- handle.h.read_only = 0;
- handle.h.obj_type = c_object;
- handle.h.obj_index = object_index;
- return handle.w;
-}
-
-static u16 hpi_handle_indexes(const u32 h, u16 *p1, u16 *p2)
-{
- union handle_word uhandle;
- if (!h)
- return HPI_ERROR_INVALID_HANDLE;
-
- uhandle.w = h;
-
- *p1 = (u16)uhandle.h.adapter_index;
- if (p2)
- *p2 = (u16)uhandle.h.obj_index;
-
- return 0;
-}
-
-void hpi_handle_to_indexes(const u32 handle, u16 *pw_adapter_index,
- u16 *pw_object_index)
-{
- hpi_handle_indexes(handle, pw_adapter_index, pw_object_index);
-}
-
-char hpi_handle_object(const u32 handle)
-{
- union handle_word uhandle;
- uhandle.w = handle;
- return (char)uhandle.h.obj_type;
-}
-
-void hpi_format_to_msg(struct hpi_msg_format *pMF,
- const struct hpi_format *pF)
-{
- pMF->sample_rate = pF->sample_rate;
- pMF->bit_rate = pF->bit_rate;
- pMF->attributes = pF->attributes;
- pMF->channels = pF->channels;
- pMF->format = pF->format;
-}
-
-static void hpi_msg_to_format(struct hpi_format *pF,
- struct hpi_msg_format *pMF)
-{
- pF->sample_rate = pMF->sample_rate;
- pF->bit_rate = pMF->bit_rate;
- pF->attributes = pMF->attributes;
- pF->channels = pMF->channels;
- pF->format = pMF->format;
- pF->mode_legacy = 0;
- pF->unused = 0;
-}
-
-void hpi_stream_response_to_legacy(struct hpi_stream_res *pSR)
-{
- pSR->u.legacy_stream_info.auxiliary_data_available =
- pSR->u.stream_info.auxiliary_data_available;
- pSR->u.legacy_stream_info.state = pSR->u.stream_info.state;
-}
-
-static inline void hpi_send_recvV1(struct hpi_message_header *m,
- struct hpi_response_header *r)
-{
- hpi_send_recv((struct hpi_message *)m, (struct hpi_response *)r);
-}
-
-u16 hpi_subsys_get_version_ex(u32 *pversion_ex)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
- HPI_SUBSYS_GET_VERSION);
- hpi_send_recv(&hm, &hr);
- *pversion_ex = hr.u.s.data;
- return hr.error;
-}
-
-u16 hpi_subsys_get_num_adapters(int *pn_num_adapters)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
- HPI_SUBSYS_GET_NUM_ADAPTERS);
- hpi_send_recv(&hm, &hr);
- *pn_num_adapters = (int)hr.u.s.num_adapters;
- return hr.error;
-}
-
-u16 hpi_subsys_get_adapter(int iterator, u32 *padapter_index,
- u16 *pw_adapter_type)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
- HPI_SUBSYS_GET_ADAPTER);
- hm.obj_index = (u16)iterator;
- hpi_send_recv(&hm, &hr);
- *padapter_index = (int)hr.u.s.adapter_index;
- *pw_adapter_type = hr.u.s.adapter_type;
-
- return hr.error;
-}
-
-u16 hpi_adapter_open(u16 adapter_index)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
- HPI_ADAPTER_OPEN);
- hm.adapter_index = adapter_index;
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-
-}
-
-u16 hpi_adapter_close(u16 adapter_index)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
- HPI_ADAPTER_CLOSE);
- hm.adapter_index = adapter_index;
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_adapter_set_mode(u16 adapter_index, u32 adapter_mode)
-{
- return hpi_adapter_set_mode_ex(adapter_index, adapter_mode,
- HPI_ADAPTER_MODE_SET);
-}
-
-u16 hpi_adapter_set_mode_ex(u16 adapter_index, u32 adapter_mode,
- u16 query_or_set)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
- HPI_ADAPTER_SET_MODE);
- hm.adapter_index = adapter_index;
- hm.u.ax.mode.adapter_mode = adapter_mode;
- hm.u.ax.mode.query_or_set = query_or_set;
- hpi_send_recv(&hm, &hr);
- return hr.error;
-}
-
-u16 hpi_adapter_get_mode(u16 adapter_index, u32 *padapter_mode)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
- HPI_ADAPTER_GET_MODE);
- hm.adapter_index = adapter_index;
- hpi_send_recv(&hm, &hr);
- if (padapter_mode)
- *padapter_mode = hr.u.ax.mode.adapter_mode;
- return hr.error;
-}
-
-u16 hpi_adapter_get_info(u16 adapter_index, u16 *pw_num_outstreams,
- u16 *pw_num_instreams, u16 *pw_version, u32 *pserial_number,
- u16 *pw_adapter_type)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
- HPI_ADAPTER_GET_INFO);
- hm.adapter_index = adapter_index;
-
- hpi_send_recv(&hm, &hr);
-
- *pw_adapter_type = hr.u.ax.info.adapter_type;
- *pw_num_outstreams = hr.u.ax.info.num_outstreams;
- *pw_num_instreams = hr.u.ax.info.num_instreams;
- *pw_version = hr.u.ax.info.version;
- *pserial_number = hr.u.ax.info.serial_number;
- return hr.error;
-}
-
-u16 hpi_adapter_get_module_by_index(u16 adapter_index, u16 module_index,
- u16 *pw_num_outputs, u16 *pw_num_inputs, u16 *pw_version,
- u32 *pserial_number, u16 *pw_module_type, u32 *ph_module)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
- HPI_ADAPTER_MODULE_INFO);
- hm.adapter_index = adapter_index;
- hm.u.ax.module_info.index = module_index;
-
- hpi_send_recv(&hm, &hr);
-
- *pw_module_type = hr.u.ax.info.adapter_type;
- *pw_num_outputs = hr.u.ax.info.num_outstreams;
- *pw_num_inputs = hr.u.ax.info.num_instreams;
- *pw_version = hr.u.ax.info.version;
- *pserial_number = hr.u.ax.info.serial_number;
- *ph_module = 0;
-
- return hr.error;
-}
-
-u16 hpi_adapter_set_property(u16 adapter_index, u16 property, u16 parameter1,
- u16 parameter2)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
- HPI_ADAPTER_SET_PROPERTY);
- hm.adapter_index = adapter_index;
- hm.u.ax.property_set.property = property;
- hm.u.ax.property_set.parameter1 = parameter1;
- hm.u.ax.property_set.parameter2 = parameter2;
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_adapter_get_property(u16 adapter_index, u16 property,
- u16 *pw_parameter1, u16 *pw_parameter2)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
- HPI_ADAPTER_GET_PROPERTY);
- hm.adapter_index = adapter_index;
- hm.u.ax.property_set.property = property;
-
- hpi_send_recv(&hm, &hr);
- if (!hr.error) {
- if (pw_parameter1)
- *pw_parameter1 = hr.u.ax.property_get.parameter1;
- if (pw_parameter2)
- *pw_parameter2 = hr.u.ax.property_get.parameter2;
- }
-
- return hr.error;
-}
-
-u16 hpi_adapter_enumerate_property(u16 adapter_index, u16 index,
- u16 what_to_enumerate, u16 property_index, u32 *psetting)
-{
- return 0;
-}
-
-u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format,
- u32 sample_rate, u32 bit_rate, u32 attributes)
-{
- u16 err = 0;
- struct hpi_msg_format fmt;
-
- switch (channels) {
- case 1:
- case 2:
- case 4:
- case 6:
- case 8:
- case 16:
- break;
- default:
- err = HPI_ERROR_INVALID_CHANNELS;
- return err;
- }
- fmt.channels = channels;
-
- switch (format) {
- case HPI_FORMAT_PCM16_SIGNED:
- case HPI_FORMAT_PCM24_SIGNED:
- case HPI_FORMAT_PCM32_SIGNED:
- case HPI_FORMAT_PCM32_FLOAT:
- case HPI_FORMAT_PCM16_BIGENDIAN:
- case HPI_FORMAT_PCM8_UNSIGNED:
- case HPI_FORMAT_MPEG_L1:
- case HPI_FORMAT_MPEG_L2:
- case HPI_FORMAT_MPEG_L3:
- case HPI_FORMAT_DOLBY_AC2:
- case HPI_FORMAT_AA_TAGIT1_HITS:
- case HPI_FORMAT_AA_TAGIT1_INSERTS:
- case HPI_FORMAT_RAW_BITSTREAM:
- case HPI_FORMAT_AA_TAGIT1_HITS_EX1:
- case HPI_FORMAT_OEM1:
- case HPI_FORMAT_OEM2:
- break;
- default:
- err = HPI_ERROR_INVALID_FORMAT;
- return err;
- }
- fmt.format = format;
-
- if (sample_rate < 8000L) {
- err = HPI_ERROR_INCOMPATIBLE_SAMPLERATE;
- sample_rate = 8000L;
- }
- if (sample_rate > 200000L) {
- err = HPI_ERROR_INCOMPATIBLE_SAMPLERATE;
- sample_rate = 200000L;
- }
- fmt.sample_rate = sample_rate;
-
- switch (format) {
- case HPI_FORMAT_MPEG_L1:
- case HPI_FORMAT_MPEG_L2:
- case HPI_FORMAT_MPEG_L3:
- fmt.bit_rate = bit_rate;
- break;
- case HPI_FORMAT_PCM16_SIGNED:
- case HPI_FORMAT_PCM16_BIGENDIAN:
- fmt.bit_rate = channels * sample_rate * 2;
- break;
- case HPI_FORMAT_PCM32_SIGNED:
- case HPI_FORMAT_PCM32_FLOAT:
- fmt.bit_rate = channels * sample_rate * 4;
- break;
- case HPI_FORMAT_PCM8_UNSIGNED:
- fmt.bit_rate = channels * sample_rate;
- break;
- default:
- fmt.bit_rate = 0;
- }
-
- switch (format) {
- case HPI_FORMAT_MPEG_L2:
- if ((channels == 1)
- && (attributes != HPI_MPEG_MODE_DEFAULT)) {
- attributes = HPI_MPEG_MODE_DEFAULT;
- err = HPI_ERROR_INVALID_FORMAT;
- } else if (attributes > HPI_MPEG_MODE_DUALCHANNEL) {
- attributes = HPI_MPEG_MODE_DEFAULT;
- err = HPI_ERROR_INVALID_FORMAT;
- }
- fmt.attributes = attributes;
- break;
- default:
- fmt.attributes = attributes;
- }
-
- hpi_msg_to_format(p_format, &fmt);
- return err;
-}
-
-u16 hpi_stream_estimate_buffer_size(struct hpi_format *p_format,
- u32 host_polling_rate_in_milli_seconds, u32 *recommended_buffer_size)
-{
-
- u32 bytes_per_second;
- u32 size;
- u16 channels;
- struct hpi_format *pF = p_format;
-
- channels = pF->channels;
-
- switch (pF->format) {
- case HPI_FORMAT_PCM16_BIGENDIAN:
- case HPI_FORMAT_PCM16_SIGNED:
- bytes_per_second = pF->sample_rate * 2L * channels;
- break;
- case HPI_FORMAT_PCM24_SIGNED:
- bytes_per_second = pF->sample_rate * 3L * channels;
- break;
- case HPI_FORMAT_PCM32_SIGNED:
- case HPI_FORMAT_PCM32_FLOAT:
- bytes_per_second = pF->sample_rate * 4L * channels;
- break;
- case HPI_FORMAT_PCM8_UNSIGNED:
- bytes_per_second = pF->sample_rate * 1L * channels;
- break;
- case HPI_FORMAT_MPEG_L1:
- case HPI_FORMAT_MPEG_L2:
- case HPI_FORMAT_MPEG_L3:
- bytes_per_second = pF->bit_rate / 8L;
- break;
- case HPI_FORMAT_DOLBY_AC2:
-
- bytes_per_second = 256000L / 8L;
- break;
- default:
- return HPI_ERROR_INVALID_FORMAT;
- }
- size = (bytes_per_second * host_polling_rate_in_milli_seconds * 2) /
- 1000L;
-
- *recommended_buffer_size =
- roundup_pow_of_two(((size + 4095L) & ~4095L));
- return 0;
-}
-
-u16 hpi_outstream_open(u16 adapter_index, u16 outstream_index,
- u32 *ph_outstream)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_OPEN);
- hm.adapter_index = adapter_index;
- hm.obj_index = outstream_index;
-
- hpi_send_recv(&hm, &hr);
-
- if (hr.error == 0)
- *ph_outstream =
- hpi_indexes_to_handle(HPI_OBJ_OSTREAM, adapter_index,
- outstream_index);
- else
- *ph_outstream = 0;
- return hr.error;
-}
-
-u16 hpi_outstream_close(u32 h_outstream)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_HOSTBUFFER_FREE);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- hpi_send_recv(&hm, &hr);
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_GROUP_RESET);
- hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index);
- hpi_send_recv(&hm, &hr);
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_CLOSE);
- hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index);
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_outstream_get_info_ex(u32 h_outstream, u16 *pw_state,
- u32 *pbuffer_size, u32 *pdata_to_play, u32 *psamples_played,
- u32 *pauxiliary_data_to_play)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_GET_INFO);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- hpi_send_recv(&hm, &hr);
-
- if (pw_state)
- *pw_state = hr.u.d.u.stream_info.state;
- if (pbuffer_size)
- *pbuffer_size = hr.u.d.u.stream_info.buffer_size;
- if (pdata_to_play)
- *pdata_to_play = hr.u.d.u.stream_info.data_available;
- if (psamples_played)
- *psamples_played = hr.u.d.u.stream_info.samples_transferred;
- if (pauxiliary_data_to_play)
- *pauxiliary_data_to_play =
- hr.u.d.u.stream_info.auxiliary_data_available;
- return hr.error;
-}
-
-u16 hpi_outstream_write_buf(u32 h_outstream, const u8 *pb_data,
- u32 bytes_to_write, const struct hpi_format *p_format)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_WRITE);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.d.u.data.pb_data = (u8 *)pb_data;
- hm.u.d.u.data.data_size = bytes_to_write;
-
- hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_outstream_start(u32 h_outstream)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_START);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_outstream_wait_start(u32 h_outstream)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_WAIT_START);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_outstream_stop(u32 h_outstream)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_STOP);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_outstream_sinegen(u32 h_outstream)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_SINEGEN);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_outstream_reset(u32 h_outstream)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_RESET);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_outstream_query_format(u32 h_outstream, struct hpi_format *p_format)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_QUERY_FORMAT);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_outstream_set_format(u32 h_outstream, struct hpi_format *p_format)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_SET_FORMAT);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_outstream_set_velocity(u32 h_outstream, short velocity)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_SET_VELOCITY);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.d.u.velocity = velocity;
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_outstream_set_punch_in_out(u32 h_outstream, u32 punch_in_sample,
- u32 punch_out_sample)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_SET_PUNCHINOUT);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- hm.u.d.u.pio.punch_in_sample = punch_in_sample;
- hm.u.d.u.pio.punch_out_sample = punch_out_sample;
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_outstream_ancillary_reset(u32 h_outstream, u16 mode)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_ANC_RESET);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.d.u.data.format.channels = mode;
- hpi_send_recv(&hm, &hr);
- return hr.error;
-}
-
-u16 hpi_outstream_ancillary_get_info(u32 h_outstream, u32 *pframes_available)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_ANC_GET_INFO);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hpi_send_recv(&hm, &hr);
- if (hr.error == 0) {
- if (pframes_available)
- *pframes_available =
- hr.u.d.u.stream_info.data_available /
- sizeof(struct hpi_anc_frame);
- }
- return hr.error;
-}
-
-u16 hpi_outstream_ancillary_read(u32 h_outstream,
- struct hpi_anc_frame *p_anc_frame_buffer,
- u32 anc_frame_buffer_size_in_bytes,
- u32 number_of_ancillary_frames_to_read)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_ANC_READ);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.d.u.data.pb_data = (u8 *)p_anc_frame_buffer;
- hm.u.d.u.data.data_size =
- number_of_ancillary_frames_to_read *
- sizeof(struct hpi_anc_frame);
- if (hm.u.d.u.data.data_size <= anc_frame_buffer_size_in_bytes)
- hpi_send_recv(&hm, &hr);
- else
- hr.error = HPI_ERROR_INVALID_DATASIZE;
- return hr.error;
-}
-
-u16 hpi_outstream_set_time_scale(u32 h_outstream, u32 time_scale)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_SET_TIMESCALE);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- hm.u.d.u.time_scale = time_scale;
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_outstream_host_buffer_allocate(u32 h_outstream, u32 size_in_bytes)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_HOSTBUFFER_ALLOC);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.d.u.data.data_size = size_in_bytes;
- hpi_send_recv(&hm, &hr);
- return hr.error;
-}
-
-u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer,
- struct hpi_hostbuffer_status **pp_status)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_HOSTBUFFER_GET_INFO);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hpi_send_recv(&hm, &hr);
-
- if (hr.error == 0) {
- if (pp_buffer)
- *pp_buffer = hr.u.d.u.hostbuffer_info.p_buffer;
- if (pp_status)
- *pp_status = hr.u.d.u.hostbuffer_info.p_status;
- }
- return hr.error;
-}
-
-u16 hpi_outstream_host_buffer_free(u32 h_outstream)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_HOSTBUFFER_FREE);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hpi_send_recv(&hm, &hr);
- return hr.error;
-}
-
-u16 hpi_outstream_group_add(u32 h_outstream, u32 h_stream)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- u16 adapter;
- char c_obj_type;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_GROUP_ADD);
-
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- if (hpi_handle_indexes(h_stream, &adapter,
- &hm.u.d.u.stream.stream_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- c_obj_type = hpi_handle_object(h_stream);
- switch (c_obj_type) {
- case HPI_OBJ_OSTREAM:
- case HPI_OBJ_ISTREAM:
- hm.u.d.u.stream.object_type = c_obj_type;
- break;
- default:
- return HPI_ERROR_INVALID_OBJ;
- }
- if (adapter != hm.adapter_index)
- return HPI_ERROR_NO_INTERADAPTER_GROUPS;
-
- hpi_send_recv(&hm, &hr);
- return hr.error;
-}
-
-u16 hpi_outstream_group_get_map(u32 h_outstream, u32 *poutstream_map,
- u32 *pinstream_map)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_GROUP_GETMAP);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hpi_send_recv(&hm, &hr);
-
- if (poutstream_map)
- *poutstream_map = hr.u.d.u.group_info.outstream_group_map;
- if (pinstream_map)
- *pinstream_map = hr.u.d.u.group_info.instream_group_map;
-
- return hr.error;
-}
-
-u16 hpi_outstream_group_reset(u32 h_outstream)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_GROUP_RESET);
- if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hpi_send_recv(&hm, &hr);
- return hr.error;
-}
-
-u16 hpi_instream_open(u16 adapter_index, u16 instream_index, u32 *ph_instream)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_OPEN);
- hm.adapter_index = adapter_index;
- hm.obj_index = instream_index;
-
- hpi_send_recv(&hm, &hr);
-
- if (hr.error == 0)
- *ph_instream =
- hpi_indexes_to_handle(HPI_OBJ_ISTREAM, adapter_index,
- instream_index);
- else
- *ph_instream = 0;
-
- return hr.error;
-}
-
-u16 hpi_instream_close(u32 h_instream)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_HOSTBUFFER_FREE);
- if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hpi_send_recv(&hm, &hr);
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_GROUP_RESET);
- hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index);
- hpi_send_recv(&hm, &hr);
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_CLOSE);
- hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index);
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_instream_query_format(u32 h_instream,
- const struct hpi_format *p_format)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_QUERY_FORMAT);
- if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_instream_set_format(u32 h_instream, const struct hpi_format *p_format)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_SET_FORMAT);
- if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_instream_read_buf(u32 h_instream, u8 *pb_data, u32 bytes_to_read)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_READ);
- if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.d.u.data.data_size = bytes_to_read;
- hm.u.d.u.data.pb_data = pb_data;
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_instream_start(u32 h_instream)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_START);
- if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_instream_wait_start(u32 h_instream)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_WAIT_START);
- if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_instream_stop(u32 h_instream)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_STOP);
- if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_instream_reset(u32 h_instream)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_RESET);
- if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_instream_get_info_ex(u32 h_instream, u16 *pw_state, u32 *pbuffer_size,
- u32 *pdata_recorded, u32 *psamples_recorded,
- u32 *pauxiliary_data_recorded)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_GET_INFO);
- if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- hpi_send_recv(&hm, &hr);
-
- if (pw_state)
- *pw_state = hr.u.d.u.stream_info.state;
- if (pbuffer_size)
- *pbuffer_size = hr.u.d.u.stream_info.buffer_size;
- if (pdata_recorded)
- *pdata_recorded = hr.u.d.u.stream_info.data_available;
- if (psamples_recorded)
- *psamples_recorded = hr.u.d.u.stream_info.samples_transferred;
- if (pauxiliary_data_recorded)
- *pauxiliary_data_recorded =
- hr.u.d.u.stream_info.auxiliary_data_available;
- return hr.error;
-}
-
-u16 hpi_instream_ancillary_reset(u32 h_instream, u16 bytes_per_frame,
- u16 mode, u16 alignment, u16 idle_bit)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_ANC_RESET);
- if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.d.u.data.format.attributes = bytes_per_frame;
- hm.u.d.u.data.format.format = (mode << 8) | (alignment & 0xff);
- hm.u.d.u.data.format.channels = idle_bit;
- hpi_send_recv(&hm, &hr);
- return hr.error;
-}
-
-u16 hpi_instream_ancillary_get_info(u32 h_instream, u32 *pframe_space)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_ANC_GET_INFO);
- if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hpi_send_recv(&hm, &hr);
- if (pframe_space)
- *pframe_space =
- (hr.u.d.u.stream_info.buffer_size -
- hr.u.d.u.stream_info.data_available) /
- sizeof(struct hpi_anc_frame);
- return hr.error;
-}
-
-u16 hpi_instream_ancillary_write(u32 h_instream,
- const struct hpi_anc_frame *p_anc_frame_buffer,
- u32 anc_frame_buffer_size_in_bytes,
- u32 number_of_ancillary_frames_to_write)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_ANC_WRITE);
- if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.d.u.data.pb_data = (u8 *)p_anc_frame_buffer;
- hm.u.d.u.data.data_size =
- number_of_ancillary_frames_to_write *
- sizeof(struct hpi_anc_frame);
- if (hm.u.d.u.data.data_size <= anc_frame_buffer_size_in_bytes)
- hpi_send_recv(&hm, &hr);
- else
- hr.error = HPI_ERROR_INVALID_DATASIZE;
- return hr.error;
-}
-
-u16 hpi_instream_host_buffer_allocate(u32 h_instream, u32 size_in_bytes)
-{
-
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_HOSTBUFFER_ALLOC);
- if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.d.u.data.data_size = size_in_bytes;
- hpi_send_recv(&hm, &hr);
- return hr.error;
-}
-
-u16 hpi_instream_host_buffer_get_info(u32 h_instream, u8 **pp_buffer,
- struct hpi_hostbuffer_status **pp_status)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_HOSTBUFFER_GET_INFO);
- if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hpi_send_recv(&hm, &hr);
-
- if (hr.error == 0) {
- if (pp_buffer)
- *pp_buffer = hr.u.d.u.hostbuffer_info.p_buffer;
- if (pp_status)
- *pp_status = hr.u.d.u.hostbuffer_info.p_status;
- }
- return hr.error;
-}
-
-u16 hpi_instream_host_buffer_free(u32 h_instream)
-{
-
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_HOSTBUFFER_FREE);
- if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hpi_send_recv(&hm, &hr);
- return hr.error;
-}
-
-u16 hpi_instream_group_add(u32 h_instream, u32 h_stream)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- u16 adapter;
- char c_obj_type;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_GROUP_ADD);
- hr.error = 0;
-
- if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- if (hpi_handle_indexes(h_stream, &adapter,
- &hm.u.d.u.stream.stream_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- c_obj_type = hpi_handle_object(h_stream);
-
- switch (c_obj_type) {
- case HPI_OBJ_OSTREAM:
- case HPI_OBJ_ISTREAM:
- hm.u.d.u.stream.object_type = c_obj_type;
- break;
- default:
- return HPI_ERROR_INVALID_OBJ;
- }
-
- if (adapter != hm.adapter_index)
- return HPI_ERROR_NO_INTERADAPTER_GROUPS;
-
- hpi_send_recv(&hm, &hr);
- return hr.error;
-}
-
-u16 hpi_instream_group_get_map(u32 h_instream, u32 *poutstream_map,
- u32 *pinstream_map)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_HOSTBUFFER_FREE);
- if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hpi_send_recv(&hm, &hr);
-
- if (poutstream_map)
- *poutstream_map = hr.u.d.u.group_info.outstream_group_map;
- if (pinstream_map)
- *pinstream_map = hr.u.d.u.group_info.instream_group_map;
-
- return hr.error;
-}
-
-u16 hpi_instream_group_reset(u32 h_instream)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_GROUP_RESET);
- if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hpi_send_recv(&hm, &hr);
- return hr.error;
-}
-
-u16 hpi_mixer_open(u16 adapter_index, u32 *ph_mixer)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN);
- hm.adapter_index = adapter_index;
-
- hpi_send_recv(&hm, &hr);
-
- if (hr.error == 0)
- *ph_mixer =
- hpi_indexes_to_handle(HPI_OBJ_MIXER, adapter_index,
- 0);
- else
- *ph_mixer = 0;
- return hr.error;
-}
-
-u16 hpi_mixer_close(u32 h_mixer)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_CLOSE);
- if (hpi_handle_indexes(h_mixer, &hm.adapter_index, NULL))
- return HPI_ERROR_INVALID_HANDLE;
-
- hpi_send_recv(&hm, &hr);
- return hr.error;
-}
-
-u16 hpi_mixer_get_control(u32 h_mixer, u16 src_node_type,
- u16 src_node_type_index, u16 dst_node_type, u16 dst_node_type_index,
- u16 control_type, u32 *ph_control)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER,
- HPI_MIXER_GET_CONTROL);
- if (hpi_handle_indexes(h_mixer, &hm.adapter_index, NULL))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.m.node_type1 = src_node_type;
- hm.u.m.node_index1 = src_node_type_index;
- hm.u.m.node_type2 = dst_node_type;
- hm.u.m.node_index2 = dst_node_type_index;
- hm.u.m.control_type = control_type;
-
- hpi_send_recv(&hm, &hr);
-
- if (hr.error == 0)
- *ph_control =
- hpi_indexes_to_handle(HPI_OBJ_CONTROL,
- hm.adapter_index, hr.u.m.control_index);
- else
- *ph_control = 0;
- return hr.error;
-}
-
-u16 hpi_mixer_get_control_by_index(u32 h_mixer, u16 control_index,
- u16 *pw_src_node_type, u16 *pw_src_node_index, u16 *pw_dst_node_type,
- u16 *pw_dst_node_index, u16 *pw_control_type, u32 *ph_control)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER,
- HPI_MIXER_GET_CONTROL_BY_INDEX);
- if (hpi_handle_indexes(h_mixer, &hm.adapter_index, NULL))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.m.control_index = control_index;
- hpi_send_recv(&hm, &hr);
-
- if (pw_src_node_type) {
- *pw_src_node_type =
- hr.u.m.src_node_type + HPI_SOURCENODE_NONE;
- *pw_src_node_index = hr.u.m.src_node_index;
- *pw_dst_node_type = hr.u.m.dst_node_type + HPI_DESTNODE_NONE;
- *pw_dst_node_index = hr.u.m.dst_node_index;
- }
- if (pw_control_type)
- *pw_control_type = hr.u.m.control_index;
-
- if (ph_control) {
- if (hr.error == 0)
- *ph_control =
- hpi_indexes_to_handle(HPI_OBJ_CONTROL,
- hm.adapter_index, control_index);
- else
- *ph_control = 0;
- }
- return hr.error;
-}
-
-u16 hpi_mixer_store(u32 h_mixer, enum HPI_MIXER_STORE_COMMAND command,
- u16 index)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_STORE);
- if (hpi_handle_indexes(h_mixer, &hm.adapter_index, NULL))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.mx.store.command = command;
- hm.u.mx.store.index = index;
- hpi_send_recv(&hm, &hr);
- return hr.error;
-}
-
-static
-u16 hpi_control_param_set(const u32 h_control, const u16 attrib,
- const u32 param1, const u32 param2)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_SET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.c.attribute = attrib;
- hm.u.c.param1 = param1;
- hm.u.c.param2 = param2;
- hpi_send_recv(&hm, &hr);
- return hr.error;
-}
-
-static u16 hpi_control_log_set2(u32 h_control, u16 attrib, short sv0,
- short sv1)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_SET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.c.attribute = attrib;
- hm.u.c.an_log_value[0] = sv0;
- hm.u.c.an_log_value[1] = sv1;
- hpi_send_recv(&hm, &hr);
- return hr.error;
-}
-
-static
-u16 hpi_control_param_get(const u32 h_control, const u16 attrib, u32 param1,
- u32 param2, u32 *pparam1, u32 *pparam2)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_GET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.c.attribute = attrib;
- hm.u.c.param1 = param1;
- hm.u.c.param2 = param2;
- hpi_send_recv(&hm, &hr);
-
- *pparam1 = hr.u.c.param1;
- if (pparam2)
- *pparam2 = hr.u.c.param2;
-
- return hr.error;
-}
-
-#define hpi_control_param1_get(h, a, p1) \
- hpi_control_param_get(h, a, 0, 0, p1, NULL)
-#define hpi_control_param2_get(h, a, p1, p2) \
- hpi_control_param_get(h, a, 0, 0, p1, p2)
-
-static u16 hpi_control_log_get2(u32 h_control, u16 attrib, short *sv0,
- short *sv1)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_GET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.c.attribute = attrib;
-
- hpi_send_recv(&hm, &hr);
- *sv0 = hr.u.c.an_log_value[0];
- if (sv1)
- *sv1 = hr.u.c.an_log_value[1];
- return hr.error;
-}
-
-static
-u16 hpi_control_query(const u32 h_control, const u16 attrib, const u32 index,
- const u32 param, u32 *psetting)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_GET_INFO);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- hm.u.c.attribute = attrib;
- hm.u.c.param1 = index;
- hm.u.c.param2 = param;
-
- hpi_send_recv(&hm, &hr);
- *psetting = hr.u.c.param1;
-
- return hr.error;
-}
-
-static u16 hpi_control_get_string(const u32 h_control, const u16 attribute,
- char *psz_string, const u32 string_length)
-{
- unsigned int sub_string_index = 0, j = 0;
- char c = 0;
- unsigned int n = 0;
- u16 err = 0;
-
- if ((string_length < 1) || (string_length > 256))
- return HPI_ERROR_INVALID_CONTROL_VALUE;
- for (sub_string_index = 0; sub_string_index < string_length;
- sub_string_index += 8) {
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_GET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index,
- &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.c.attribute = attribute;
- hm.u.c.param1 = sub_string_index;
- hm.u.c.param2 = 0;
- hpi_send_recv(&hm, &hr);
-
- if (sub_string_index == 0
- && (hr.u.cu.chars8.remaining_chars + 8) >
- string_length)
- return HPI_ERROR_INVALID_CONTROL_VALUE;
-
- if (hr.error) {
- err = hr.error;
- break;
- }
- for (j = 0; j < 8; j++) {
- c = hr.u.cu.chars8.sz_data[j];
- psz_string[sub_string_index + j] = c;
- n++;
- if (n >= string_length) {
- psz_string[string_length - 1] = 0;
- err = HPI_ERROR_INVALID_CONTROL_VALUE;
- break;
- }
- if (c == 0)
- break;
- }
-
- if ((hr.u.cu.chars8.remaining_chars == 0)
- && ((sub_string_index + j) < string_length)
- && (c != 0)) {
- c = 0;
- psz_string[sub_string_index + j] = c;
- }
- if (c == 0)
- break;
- }
- return err;
-}
-
-u16 hpi_aesebu_receiver_query_format(const u32 h_aes_rx, const u32 index,
- u16 *pw_format)
-{
- u32 qr;
- u16 err;
-
- err = hpi_control_query(h_aes_rx, HPI_AESEBURX_FORMAT, index, 0, &qr);
- *pw_format = (u16)qr;
- return err;
-}
-
-u16 hpi_aesebu_receiver_set_format(u32 h_control, u16 format)
-{
- return hpi_control_param_set(h_control, HPI_AESEBURX_FORMAT, format,
- 0);
-}
-
-u16 hpi_aesebu_receiver_get_format(u32 h_control, u16 *pw_format)
-{
- u16 err;
- u32 param;
-
- err = hpi_control_param1_get(h_control, HPI_AESEBURX_FORMAT, &param);
- if (!err && pw_format)
- *pw_format = (u16)param;
-
- return err;
-}
-
-u16 hpi_aesebu_receiver_get_sample_rate(u32 h_control, u32 *psample_rate)
-{
- return hpi_control_param1_get(h_control, HPI_AESEBURX_SAMPLERATE,
- psample_rate);
-}
-
-u16 hpi_aesebu_receiver_get_user_data(u32 h_control, u16 index, u16 *pw_data)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_GET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.c.attribute = HPI_AESEBURX_USERDATA;
- hm.u.c.param1 = index;
-
- hpi_send_recv(&hm, &hr);
-
- if (pw_data)
- *pw_data = (u16)hr.u.c.param2;
- return hr.error;
-}
-
-u16 hpi_aesebu_receiver_get_channel_status(u32 h_control, u16 index,
- u16 *pw_data)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_GET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.c.attribute = HPI_AESEBURX_CHANNELSTATUS;
- hm.u.c.param1 = index;
-
- hpi_send_recv(&hm, &hr);
-
- if (pw_data)
- *pw_data = (u16)hr.u.c.param2;
- return hr.error;
-}
-
-u16 hpi_aesebu_receiver_get_error_status(u32 h_control, u16 *pw_error_data)
-{
- u32 error_data = 0;
- u16 err = 0;
-
- err = hpi_control_param1_get(h_control, HPI_AESEBURX_ERRORSTATUS,
- &error_data);
- if (pw_error_data)
- *pw_error_data = (u16)error_data;
- return err;
-}
-
-u16 hpi_aesebu_transmitter_set_sample_rate(u32 h_control, u32 sample_rate)
-{
- return hpi_control_param_set(h_control, HPI_AESEBUTX_SAMPLERATE,
- sample_rate, 0);
-}
-
-u16 hpi_aesebu_transmitter_set_user_data(u32 h_control, u16 index, u16 data)
-{
- return hpi_control_param_set(h_control, HPI_AESEBUTX_USERDATA, index,
- data);
-}
-
-u16 hpi_aesebu_transmitter_set_channel_status(u32 h_control, u16 index,
- u16 data)
-{
- return hpi_control_param_set(h_control, HPI_AESEBUTX_CHANNELSTATUS,
- index, data);
-}
-
-u16 hpi_aesebu_transmitter_get_channel_status(u32 h_control, u16 index,
- u16 *pw_data)
-{
- return HPI_ERROR_INVALID_OPERATION;
-}
-
-u16 hpi_aesebu_transmitter_query_format(const u32 h_aes_tx, const u32 index,
- u16 *pw_format)
-{
- u32 qr;
- u16 err;
-
- err = hpi_control_query(h_aes_tx, HPI_AESEBUTX_FORMAT, index, 0, &qr);
- *pw_format = (u16)qr;
- return err;
-}
-
-u16 hpi_aesebu_transmitter_set_format(u32 h_control, u16 output_format)
-{
- return hpi_control_param_set(h_control, HPI_AESEBUTX_FORMAT,
- output_format, 0);
-}
-
-u16 hpi_aesebu_transmitter_get_format(u32 h_control, u16 *pw_output_format)
-{
- u16 err;
- u32 param;
-
- err = hpi_control_param1_get(h_control, HPI_AESEBUTX_FORMAT, &param);
- if (!err && pw_output_format)
- *pw_output_format = (u16)param;
-
- return err;
-}
-
-u16 hpi_bitstream_set_clock_edge(u32 h_control, u16 edge_type)
-{
- return hpi_control_param_set(h_control, HPI_BITSTREAM_CLOCK_EDGE,
- edge_type, 0);
-}
-
-u16 hpi_bitstream_set_data_polarity(u32 h_control, u16 polarity)
-{
- return hpi_control_param_set(h_control, HPI_BITSTREAM_DATA_POLARITY,
- polarity, 0);
-}
-
-u16 hpi_bitstream_get_activity(u32 h_control, u16 *pw_clk_activity,
- u16 *pw_data_activity)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_GET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.c.attribute = HPI_BITSTREAM_ACTIVITY;
- hpi_send_recv(&hm, &hr);
- if (pw_clk_activity)
- *pw_clk_activity = (u16)hr.u.c.param1;
- if (pw_data_activity)
- *pw_data_activity = (u16)hr.u.c.param2;
- return hr.error;
-}
-
-u16 hpi_channel_mode_query_mode(const u32 h_mode, const u32 index,
- u16 *pw_mode)
-{
- u32 qr;
- u16 err;
-
- err = hpi_control_query(h_mode, HPI_CHANNEL_MODE_MODE, index, 0, &qr);
- *pw_mode = (u16)qr;
- return err;
-}
-
-u16 hpi_channel_mode_set(u32 h_control, u16 mode)
-{
- return hpi_control_param_set(h_control, HPI_CHANNEL_MODE_MODE, mode,
- 0);
-}
-
-u16 hpi_channel_mode_get(u32 h_control, u16 *mode)
-{
- u32 mode32 = 0;
- u16 err = hpi_control_param1_get(h_control,
- HPI_CHANNEL_MODE_MODE, &mode32);
- if (mode)
- *mode = (u16)mode32;
- return err;
-}
-
-u16 hpi_cobranet_hmi_write(u32 h_control, u32 hmi_address, u32 byte_count,
- u8 *pb_data)
-{
- struct hpi_msg_cobranet_hmiwrite hm;
- struct hpi_response_header hr;
-
- hpi_init_message_responseV1(&hm.h, sizeof(hm), &hr, sizeof(hr),
- HPI_OBJ_CONTROL, HPI_CONTROL_SET_STATE);
-
- if (hpi_handle_indexes(h_control, &hm.h.adapter_index,
- &hm.h.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- if (byte_count > sizeof(hm.bytes))
- return HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL;
-
- hm.p.attribute = HPI_COBRANET_SET;
- hm.p.byte_count = byte_count;
- hm.p.hmi_address = hmi_address;
- memcpy(hm.bytes, pb_data, byte_count);
- hm.h.size = (u16)(sizeof(hm.h) + sizeof(hm.p) + byte_count);
-
- hpi_send_recvV1(&hm.h, &hr);
- return hr.error;
-}
-
-u16 hpi_cobranet_hmi_read(u32 h_control, u32 hmi_address, u32 max_byte_count,
- u32 *pbyte_count, u8 *pb_data)
-{
- struct hpi_msg_cobranet_hmiread hm;
- struct hpi_res_cobranet_hmiread hr;
-
- hpi_init_message_responseV1(&hm.h, sizeof(hm), &hr.h, sizeof(hr),
- HPI_OBJ_CONTROL, HPI_CONTROL_GET_STATE);
-
- if (hpi_handle_indexes(h_control, &hm.h.adapter_index,
- &hm.h.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- if (max_byte_count > sizeof(hr.bytes))
- return HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
-
- hm.p.attribute = HPI_COBRANET_GET;
- hm.p.byte_count = max_byte_count;
- hm.p.hmi_address = hmi_address;
-
- hpi_send_recvV1(&hm.h, &hr.h);
-
- if (!hr.h.error && pb_data) {
- if (hr.byte_count > sizeof(hr.bytes))
-
- return HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
-
- *pbyte_count = hr.byte_count;
-
- if (hr.byte_count < max_byte_count)
- max_byte_count = *pbyte_count;
-
- memcpy(pb_data, hr.bytes, max_byte_count);
- }
- return hr.h.error;
-}
-
-u16 hpi_cobranet_hmi_get_status(u32 h_control, u32 *pstatus,
- u32 *preadable_size, u32 *pwriteable_size)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_GET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- hm.u.c.attribute = HPI_COBRANET_GET_STATUS;
-
- hpi_send_recv(&hm, &hr);
- if (!hr.error) {
- if (pstatus)
- *pstatus = hr.u.cu.cobranet.status.status;
- if (preadable_size)
- *preadable_size =
- hr.u.cu.cobranet.status.readable_size;
- if (pwriteable_size)
- *pwriteable_size =
- hr.u.cu.cobranet.status.writeable_size;
- }
- return hr.error;
-}
-
-u16 hpi_cobranet_get_ip_address(u32 h_control, u32 *pdw_ip_address)
-{
- u32 byte_count;
- u32 iP;
- u16 err;
-
- err = hpi_cobranet_hmi_read(h_control,
- HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, &byte_count,
- (u8 *)&iP);
-
- *pdw_ip_address =
- ((iP & 0xff000000) >> 8) | ((iP & 0x00ff0000) << 8) | ((iP &
- 0x0000ff00) >> 8) | ((iP & 0x000000ff) << 8);
-
- if (err)
- *pdw_ip_address = 0;
-
- return err;
-
-}
-
-u16 hpi_cobranet_set_ip_address(u32 h_control, u32 dw_ip_address)
-{
- u32 iP;
- u16 err;
-
- iP = ((dw_ip_address & 0xff000000) >> 8) | ((dw_ip_address &
- 0x00ff0000) << 8) | ((dw_ip_address & 0x0000ff00) >>
- 8) | ((dw_ip_address & 0x000000ff) << 8);
-
- err = hpi_cobranet_hmi_write(h_control,
- HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, (u8 *)&iP);
-
- return err;
-
-}
-
-u16 hpi_cobranet_get_static_ip_address(u32 h_control, u32 *pdw_ip_address)
-{
- u32 byte_count;
- u32 iP;
- u16 err;
- err = hpi_cobranet_hmi_read(h_control,
- HPI_COBRANET_HMI_cobra_ip_mon_staticIP, 4, &byte_count,
- (u8 *)&iP);
-
- *pdw_ip_address =
- ((iP & 0xff000000) >> 8) | ((iP & 0x00ff0000) << 8) | ((iP &
- 0x0000ff00) >> 8) | ((iP & 0x000000ff) << 8);
-
- if (err)
- *pdw_ip_address = 0;
-
- return err;
-
-}
-
-u16 hpi_cobranet_set_static_ip_address(u32 h_control, u32 dw_ip_address)
-{
- u32 iP;
- u16 err;
-
- iP = ((dw_ip_address & 0xff000000) >> 8) | ((dw_ip_address &
- 0x00ff0000) << 8) | ((dw_ip_address & 0x0000ff00) >>
- 8) | ((dw_ip_address & 0x000000ff) << 8);
-
- err = hpi_cobranet_hmi_write(h_control,
- HPI_COBRANET_HMI_cobra_ip_mon_staticIP, 4, (u8 *)&iP);
-
- return err;
-
-}
-
-u16 hpi_cobranet_get_macaddress(u32 h_control, u32 *p_mac_msbs,
- u32 *p_mac_lsbs)
-{
- u32 byte_count;
- u16 err;
- u32 mac;
-
- err = hpi_cobranet_hmi_read(h_control,
- HPI_COBRANET_HMI_cobra_if_phy_address, 4, &byte_count,
- (u8 *)&mac);
-
- if (!err) {
- *p_mac_msbs =
- ((mac & 0xff000000) >> 8) | ((mac & 0x00ff0000) << 8)
- | ((mac & 0x0000ff00) >> 8) | ((mac & 0x000000ff) <<
- 8);
-
- err = hpi_cobranet_hmi_read(h_control,
- HPI_COBRANET_HMI_cobra_if_phy_address + 1, 4,
- &byte_count, (u8 *)&mac);
- }
-
- if (!err) {
- *p_mac_lsbs =
- ((mac & 0xff000000) >> 8) | ((mac & 0x00ff0000) << 8)
- | ((mac & 0x0000ff00) >> 8) | ((mac & 0x000000ff) <<
- 8);
- } else {
- *p_mac_msbs = 0;
- *p_mac_lsbs = 0;
- }
-
- return err;
-}
-
-u16 hpi_compander_set_enable(u32 h_control, u32 enable)
-{
- return hpi_control_param_set(h_control, HPI_GENERIC_ENABLE, enable,
- 0);
-}
-
-u16 hpi_compander_get_enable(u32 h_control, u32 *enable)
-{
- return hpi_control_param1_get(h_control, HPI_GENERIC_ENABLE, enable);
-}
-
-u16 hpi_compander_set_makeup_gain(u32 h_control, short makeup_gain0_01dB)
-{
- return hpi_control_log_set2(h_control, HPI_COMPANDER_MAKEUPGAIN,
- makeup_gain0_01dB, 0);
-}
-
-u16 hpi_compander_get_makeup_gain(u32 h_control, short *makeup_gain0_01dB)
-{
- return hpi_control_log_get2(h_control, HPI_COMPANDER_MAKEUPGAIN,
- makeup_gain0_01dB, NULL);
-}
-
-u16 hpi_compander_set_attack_time_constant(u32 h_control, unsigned int index,
- u32 attack)
-{
- return hpi_control_param_set(h_control, HPI_COMPANDER_ATTACK, attack,
- index);
-}
-
-u16 hpi_compander_get_attack_time_constant(u32 h_control, unsigned int index,
- u32 *attack)
-{
- return hpi_control_param_get(h_control, HPI_COMPANDER_ATTACK, 0,
- index, attack, NULL);
-}
-
-u16 hpi_compander_set_decay_time_constant(u32 h_control, unsigned int index,
- u32 decay)
-{
- return hpi_control_param_set(h_control, HPI_COMPANDER_DECAY, decay,
- index);
-}
-
-u16 hpi_compander_get_decay_time_constant(u32 h_control, unsigned int index,
- u32 *decay)
-{
- return hpi_control_param_get(h_control, HPI_COMPANDER_DECAY, 0, index,
- decay, NULL);
-
-}
-
-u16 hpi_compander_set_threshold(u32 h_control, unsigned int index,
- short threshold0_01dB)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_SET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.c.attribute = HPI_COMPANDER_THRESHOLD;
- hm.u.c.param2 = index;
- hm.u.c.an_log_value[0] = threshold0_01dB;
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_compander_get_threshold(u32 h_control, unsigned int index,
- short *threshold0_01dB)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_GET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.c.attribute = HPI_COMPANDER_THRESHOLD;
- hm.u.c.param2 = index;
-
- hpi_send_recv(&hm, &hr);
- *threshold0_01dB = hr.u.c.an_log_value[0];
-
- return hr.error;
-}
-
-u16 hpi_compander_set_ratio(u32 h_control, u32 index, u32 ratio100)
-{
- return hpi_control_param_set(h_control, HPI_COMPANDER_RATIO, ratio100,
- index);
-}
-
-u16 hpi_compander_get_ratio(u32 h_control, u32 index, u32 *ratio100)
-{
- return hpi_control_param_get(h_control, HPI_COMPANDER_RATIO, 0, index,
- ratio100, NULL);
-}
-
-u16 hpi_level_query_range(u32 h_control, short *min_gain_01dB,
- short *max_gain_01dB, short *step_gain_01dB)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_GET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.c.attribute = HPI_LEVEL_RANGE;
-
- hpi_send_recv(&hm, &hr);
- if (hr.error) {
- hr.u.c.an_log_value[0] = 0;
- hr.u.c.an_log_value[1] = 0;
- hr.u.c.param1 = 0;
- }
- if (min_gain_01dB)
- *min_gain_01dB = hr.u.c.an_log_value[0];
- if (max_gain_01dB)
- *max_gain_01dB = hr.u.c.an_log_value[1];
- if (step_gain_01dB)
- *step_gain_01dB = (short)hr.u.c.param1;
- return hr.error;
-}
-
-u16 hpi_level_set_gain(u32 h_control, short an_gain0_01dB[HPI_MAX_CHANNELS]
- )
-{
- return hpi_control_log_set2(h_control, HPI_LEVEL_GAIN,
- an_gain0_01dB[0], an_gain0_01dB[1]);
-}
-
-u16 hpi_level_get_gain(u32 h_control, short an_gain0_01dB[HPI_MAX_CHANNELS]
- )
-{
- return hpi_control_log_get2(h_control, HPI_LEVEL_GAIN,
- &an_gain0_01dB[0], &an_gain0_01dB[1]);
-}
-
-u16 hpi_meter_query_channels(const u32 h_meter, u32 *p_channels)
-{
- return hpi_control_query(h_meter, HPI_METER_NUM_CHANNELS, 0, 0,
- p_channels);
-}
-
-u16 hpi_meter_get_peak(u32 h_control, short an_peakdB[HPI_MAX_CHANNELS]
- )
-{
- short i = 0;
-
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_GET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.obj_index = hm.obj_index;
- hm.u.c.attribute = HPI_METER_PEAK;
-
- hpi_send_recv(&hm, &hr);
-
- if (!hr.error)
- memcpy(an_peakdB, hr.u.c.an_log_value,
- sizeof(short) * HPI_MAX_CHANNELS);
- else
- for (i = 0; i < HPI_MAX_CHANNELS; i++)
- an_peakdB[i] = HPI_METER_MINIMUM;
- return hr.error;
-}
-
-u16 hpi_meter_get_rms(u32 h_control, short an_rmsdB[HPI_MAX_CHANNELS]
- )
-{
- short i = 0;
-
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_GET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.c.attribute = HPI_METER_RMS;
-
- hpi_send_recv(&hm, &hr);
-
- if (!hr.error)
- memcpy(an_rmsdB, hr.u.c.an_log_value,
- sizeof(short) * HPI_MAX_CHANNELS);
- else
- for (i = 0; i < HPI_MAX_CHANNELS; i++)
- an_rmsdB[i] = HPI_METER_MINIMUM;
-
- return hr.error;
-}
-
-u16 hpi_meter_set_rms_ballistics(u32 h_control, u16 attack, u16 decay)
-{
- return hpi_control_param_set(h_control, HPI_METER_RMS_BALLISTICS,
- attack, decay);
-}
-
-u16 hpi_meter_get_rms_ballistics(u32 h_control, u16 *pn_attack, u16 *pn_decay)
-{
- u32 attack;
- u32 decay;
- u16 error;
-
- error = hpi_control_param2_get(h_control, HPI_METER_RMS_BALLISTICS,
- &attack, &decay);
-
- if (pn_attack)
- *pn_attack = (unsigned short)attack;
- if (pn_decay)
- *pn_decay = (unsigned short)decay;
-
- return error;
-}
-
-u16 hpi_meter_set_peak_ballistics(u32 h_control, u16 attack, u16 decay)
-{
- return hpi_control_param_set(h_control, HPI_METER_PEAK_BALLISTICS,
- attack, decay);
-}
-
-u16 hpi_meter_get_peak_ballistics(u32 h_control, u16 *pn_attack,
- u16 *pn_decay)
-{
- u32 attack;
- u32 decay;
- u16 error;
-
- error = hpi_control_param2_get(h_control, HPI_METER_PEAK_BALLISTICS,
- &attack, &decay);
-
- if (pn_attack)
- *pn_attack = (short)attack;
- if (pn_decay)
- *pn_decay = (short)decay;
-
- return error;
-}
-
-u16 hpi_microphone_set_phantom_power(u32 h_control, u16 on_off)
-{
- return hpi_control_param_set(h_control, HPI_MICROPHONE_PHANTOM_POWER,
- (u32)on_off, 0);
-}
-
-u16 hpi_microphone_get_phantom_power(u32 h_control, u16 *pw_on_off)
-{
- u16 error = 0;
- u32 on_off = 0;
- error = hpi_control_param1_get(h_control,
- HPI_MICROPHONE_PHANTOM_POWER, &on_off);
- if (pw_on_off)
- *pw_on_off = (u16)on_off;
- return error;
-}
-
-u16 hpi_multiplexer_set_source(u32 h_control, u16 source_node_type,
- u16 source_node_index)
-{
- return hpi_control_param_set(h_control, HPI_MULTIPLEXER_SOURCE,
- source_node_type, source_node_index);
-}
-
-u16 hpi_multiplexer_get_source(u32 h_control, u16 *source_node_type,
- u16 *source_node_index)
-{
- u32 node, index;
- u16 err = hpi_control_param2_get(h_control,
- HPI_MULTIPLEXER_SOURCE, &node,
- &index);
- if (source_node_type)
- *source_node_type = (u16)node;
- if (source_node_index)
- *source_node_index = (u16)index;
- return err;
-}
-
-u16 hpi_multiplexer_query_source(u32 h_control, u16 index,
- u16 *source_node_type, u16 *source_node_index)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_GET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.c.attribute = HPI_MULTIPLEXER_QUERYSOURCE;
- hm.u.c.param1 = index;
-
- hpi_send_recv(&hm, &hr);
-
- if (source_node_type)
- *source_node_type = (u16)hr.u.c.param1;
- if (source_node_index)
- *source_node_index = (u16)hr.u.c.param2;
- return hr.error;
-}
-
-u16 hpi_parametric_eq_get_info(u32 h_control, u16 *pw_number_of_bands,
- u16 *pw_on_off)
-{
- u32 oB = 0;
- u32 oO = 0;
- u16 error = 0;
-
- error = hpi_control_param2_get(h_control, HPI_EQUALIZER_NUM_FILTERS,
- &oO, &oB);
- if (pw_number_of_bands)
- *pw_number_of_bands = (u16)oB;
- if (pw_on_off)
- *pw_on_off = (u16)oO;
- return error;
-}
-
-u16 hpi_parametric_eq_set_state(u32 h_control, u16 on_off)
-{
- return hpi_control_param_set(h_control, HPI_EQUALIZER_NUM_FILTERS,
- on_off, 0);
-}
-
-u16 hpi_parametric_eq_get_band(u32 h_control, u16 index, u16 *pn_type,
- u32 *pfrequency_hz, short *pnQ100, short *pn_gain0_01dB)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_GET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.c.attribute = HPI_EQUALIZER_FILTER;
- hm.u.c.param2 = index;
-
- hpi_send_recv(&hm, &hr);
-
- if (pfrequency_hz)
- *pfrequency_hz = hr.u.c.param1;
- if (pn_type)
- *pn_type = (u16)(hr.u.c.param2 >> 16);
- if (pnQ100)
- *pnQ100 = hr.u.c.an_log_value[1];
- if (pn_gain0_01dB)
- *pn_gain0_01dB = hr.u.c.an_log_value[0];
-
- return hr.error;
-}
-
-u16 hpi_parametric_eq_set_band(u32 h_control, u16 index, u16 type,
- u32 frequency_hz, short q100, short gain0_01dB)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_SET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- hm.u.c.param1 = frequency_hz;
- hm.u.c.param2 = (index & 0xFFFFL) + ((u32)type << 16);
- hm.u.c.an_log_value[0] = gain0_01dB;
- hm.u.c.an_log_value[1] = q100;
- hm.u.c.attribute = HPI_EQUALIZER_FILTER;
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_parametric_eq_get_coeffs(u32 h_control, u16 index, short coeffs[5]
- )
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_GET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.c.attribute = HPI_EQUALIZER_COEFFICIENTS;
- hm.u.c.param2 = index;
-
- hpi_send_recv(&hm, &hr);
-
- coeffs[0] = (short)hr.u.c.an_log_value[0];
- coeffs[1] = (short)hr.u.c.an_log_value[1];
- coeffs[2] = (short)hr.u.c.param1;
- coeffs[3] = (short)(hr.u.c.param1 >> 16);
- coeffs[4] = (short)hr.u.c.param2;
-
- return hr.error;
-}
-
-u16 hpi_sample_clock_query_source(const u32 h_clock, const u32 index,
- u16 *pw_source)
-{
- u32 qr;
- u16 err;
-
- err = hpi_control_query(h_clock, HPI_SAMPLECLOCK_SOURCE, index, 0,
- &qr);
- *pw_source = (u16)qr;
- return err;
-}
-
-u16 hpi_sample_clock_set_source(u32 h_control, u16 source)
-{
- return hpi_control_param_set(h_control, HPI_SAMPLECLOCK_SOURCE,
- source, 0);
-}
-
-u16 hpi_sample_clock_get_source(u32 h_control, u16 *pw_source)
-{
- u16 err = 0;
- u32 source = 0;
- err = hpi_control_param1_get(h_control, HPI_SAMPLECLOCK_SOURCE,
- &source);
- if (!err)
- if (pw_source)
- *pw_source = (u16)source;
- return err;
-}
-
-u16 hpi_sample_clock_query_source_index(const u32 h_clock, const u32 index,
- const u32 source, u16 *pw_source_index)
-{
- u32 qr;
- u16 err;
-
- err = hpi_control_query(h_clock, HPI_SAMPLECLOCK_SOURCE_INDEX, index,
- source, &qr);
- *pw_source_index = (u16)qr;
- return err;
-}
-
-u16 hpi_sample_clock_set_source_index(u32 h_control, u16 source_index)
-{
- return hpi_control_param_set(h_control, HPI_SAMPLECLOCK_SOURCE_INDEX,
- source_index, 0);
-}
-
-u16 hpi_sample_clock_get_source_index(u32 h_control, u16 *pw_source_index)
-{
- u16 err = 0;
- u32 source_index = 0;
- err = hpi_control_param1_get(h_control, HPI_SAMPLECLOCK_SOURCE_INDEX,
- &source_index);
- if (!err)
- if (pw_source_index)
- *pw_source_index = (u16)source_index;
- return err;
-}
-
-u16 hpi_sample_clock_query_local_rate(const u32 h_clock, const u32 index,
- u32 *prate)
-{
- u16 err;
- err = hpi_control_query(h_clock, HPI_SAMPLECLOCK_LOCAL_SAMPLERATE,
- index, 0, prate);
-
- return err;
-}
-
-u16 hpi_sample_clock_set_local_rate(u32 h_control, u32 sample_rate)
-{
- return hpi_control_param_set(h_control,
- HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, sample_rate, 0);
-}
-
-u16 hpi_sample_clock_get_local_rate(u32 h_control, u32 *psample_rate)
-{
- u16 err = 0;
- u32 sample_rate = 0;
- err = hpi_control_param1_get(h_control,
- HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, &sample_rate);
- if (!err)
- if (psample_rate)
- *psample_rate = sample_rate;
- return err;
-}
-
-u16 hpi_sample_clock_get_sample_rate(u32 h_control, u32 *psample_rate)
-{
- u16 err = 0;
- u32 sample_rate = 0;
- err = hpi_control_param1_get(h_control, HPI_SAMPLECLOCK_SAMPLERATE,
- &sample_rate);
- if (!err)
- if (psample_rate)
- *psample_rate = sample_rate;
- return err;
-}
-
-u16 hpi_sample_clock_set_auto(u32 h_control, u32 enable)
-{
- return hpi_control_param_set(h_control, HPI_SAMPLECLOCK_AUTO, enable,
- 0);
-}
-
-u16 hpi_sample_clock_get_auto(u32 h_control, u32 *penable)
-{
- return hpi_control_param1_get(h_control, HPI_SAMPLECLOCK_AUTO,
- penable);
-}
-
-u16 hpi_sample_clock_set_local_rate_lock(u32 h_control, u32 lock)
-{
- return hpi_control_param_set(h_control, HPI_SAMPLECLOCK_LOCAL_LOCK,
- lock, 0);
-}
-
-u16 hpi_sample_clock_get_local_rate_lock(u32 h_control, u32 *plock)
-{
- return hpi_control_param1_get(h_control, HPI_SAMPLECLOCK_LOCAL_LOCK,
- plock);
-}
-
-u16 hpi_tone_detector_get_frequency(u32 h_control, u32 index, u32 *frequency)
-{
- return hpi_control_param_get(h_control, HPI_TONEDETECTOR_FREQUENCY,
- index, 0, frequency, NULL);
-}
-
-u16 hpi_tone_detector_get_state(u32 h_control, u32 *state)
-{
- return hpi_control_param1_get(h_control, HPI_TONEDETECTOR_STATE,
- state);
-}
-
-u16 hpi_tone_detector_set_enable(u32 h_control, u32 enable)
-{
- return hpi_control_param_set(h_control, HPI_GENERIC_ENABLE, enable,
- 0);
-}
-
-u16 hpi_tone_detector_get_enable(u32 h_control, u32 *enable)
-{
- return hpi_control_param1_get(h_control, HPI_GENERIC_ENABLE, enable);
-}
-
-u16 hpi_tone_detector_set_event_enable(u32 h_control, u32 event_enable)
-{
- return hpi_control_param_set(h_control, HPI_GENERIC_EVENT_ENABLE,
- (u32)event_enable, 0);
-}
-
-u16 hpi_tone_detector_get_event_enable(u32 h_control, u32 *event_enable)
-{
- return hpi_control_param1_get(h_control, HPI_GENERIC_EVENT_ENABLE,
- event_enable);
-}
-
-u16 hpi_tone_detector_set_threshold(u32 h_control, int threshold)
-{
- return hpi_control_param_set(h_control, HPI_TONEDETECTOR_THRESHOLD,
- (u32)threshold, 0);
-}
-
-u16 hpi_tone_detector_get_threshold(u32 h_control, int *threshold)
-{
- return hpi_control_param1_get(h_control, HPI_TONEDETECTOR_THRESHOLD,
- (u32 *)threshold);
-}
-
-u16 hpi_silence_detector_get_state(u32 h_control, u32 *state)
-{
- return hpi_control_param1_get(h_control, HPI_SILENCEDETECTOR_STATE,
- state);
-}
-
-u16 hpi_silence_detector_set_enable(u32 h_control, u32 enable)
-{
- return hpi_control_param_set(h_control, HPI_GENERIC_ENABLE, enable,
- 0);
-}
-
-u16 hpi_silence_detector_get_enable(u32 h_control, u32 *enable)
-{
- return hpi_control_param1_get(h_control, HPI_GENERIC_ENABLE, enable);
-}
-
-u16 hpi_silence_detector_set_event_enable(u32 h_control, u32 event_enable)
-{
- return hpi_control_param_set(h_control, HPI_GENERIC_EVENT_ENABLE,
- event_enable, 0);
-}
-
-u16 hpi_silence_detector_get_event_enable(u32 h_control, u32 *event_enable)
-{
- return hpi_control_param1_get(h_control, HPI_GENERIC_EVENT_ENABLE,
- event_enable);
-}
-
-u16 hpi_silence_detector_set_delay(u32 h_control, u32 delay)
-{
- return hpi_control_param_set(h_control, HPI_SILENCEDETECTOR_DELAY,
- delay, 0);
-}
-
-u16 hpi_silence_detector_get_delay(u32 h_control, u32 *delay)
-{
- return hpi_control_param1_get(h_control, HPI_SILENCEDETECTOR_DELAY,
- delay);
-}
-
-u16 hpi_silence_detector_set_threshold(u32 h_control, int threshold)
-{
- return hpi_control_param_set(h_control, HPI_SILENCEDETECTOR_THRESHOLD,
- threshold, 0);
-}
-
-u16 hpi_silence_detector_get_threshold(u32 h_control, int *threshold)
-{
- return hpi_control_param1_get(h_control,
- HPI_SILENCEDETECTOR_THRESHOLD, (u32 *)threshold);
-}
-
-u16 hpi_tuner_query_band(const u32 h_tuner, const u32 index, u16 *pw_band)
-{
- u32 qr;
- u16 err;
-
- err = hpi_control_query(h_tuner, HPI_TUNER_BAND, index, 0, &qr);
- *pw_band = (u16)qr;
- return err;
-}
-
-u16 hpi_tuner_set_band(u32 h_control, u16 band)
-{
- return hpi_control_param_set(h_control, HPI_TUNER_BAND, band, 0);
-}
-
-u16 hpi_tuner_get_band(u32 h_control, u16 *pw_band)
-{
- u32 band = 0;
- u16 error = 0;
-
- error = hpi_control_param1_get(h_control, HPI_TUNER_BAND, &band);
- if (pw_band)
- *pw_band = (u16)band;
- return error;
-}
-
-u16 hpi_tuner_query_frequency(const u32 h_tuner, const u32 index,
- const u16 band, u32 *pfreq)
-{
- return hpi_control_query(h_tuner, HPI_TUNER_FREQ, index, band, pfreq);
-}
-
-u16 hpi_tuner_set_frequency(u32 h_control, u32 freq_ink_hz)
-{
- return hpi_control_param_set(h_control, HPI_TUNER_FREQ, freq_ink_hz,
- 0);
-}
-
-u16 hpi_tuner_get_frequency(u32 h_control, u32 *pw_freq_ink_hz)
-{
- return hpi_control_param1_get(h_control, HPI_TUNER_FREQ,
- pw_freq_ink_hz);
-}
-
-u16 hpi_tuner_query_gain(const u32 h_tuner, const u32 index, u16 *pw_gain)
-{
- u32 qr;
- u16 err;
-
- err = hpi_control_query(h_tuner, HPI_TUNER_BAND, index, 0, &qr);
- *pw_gain = (u16)qr;
- return err;
-}
-
-u16 hpi_tuner_set_gain(u32 h_control, short gain)
-{
- return hpi_control_param_set(h_control, HPI_TUNER_GAIN, gain, 0);
-}
-
-u16 hpi_tuner_get_gain(u32 h_control, short *pn_gain)
-{
- u32 gain = 0;
- u16 error = 0;
-
- error = hpi_control_param1_get(h_control, HPI_TUNER_GAIN, &gain);
- if (pn_gain)
- *pn_gain = (u16)gain;
- return error;
-}
-
-u16 hpi_tuner_get_rf_level(u32 h_control, short *pw_level)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_GET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.cu.attribute = HPI_TUNER_LEVEL_AVG;
- hpi_send_recv(&hm, &hr);
- if (pw_level)
- *pw_level = hr.u.cu.tuner.s_level;
- return hr.error;
-}
-
-u16 hpi_tuner_get_raw_rf_level(u32 h_control, short *pw_level)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_GET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.cu.attribute = HPI_TUNER_LEVEL_RAW;
- hpi_send_recv(&hm, &hr);
- if (pw_level)
- *pw_level = hr.u.cu.tuner.s_level;
- return hr.error;
-}
-
-u16 hpi_tuner_query_deemphasis(const u32 h_tuner, const u32 index,
- const u16 band, u32 *pdeemphasis)
-{
- return hpi_control_query(h_tuner, HPI_TUNER_DEEMPHASIS, index, band,
- pdeemphasis);
-}
-
-u16 hpi_tuner_set_deemphasis(u32 h_control, u32 deemphasis)
-{
- return hpi_control_param_set(h_control, HPI_TUNER_DEEMPHASIS,
- deemphasis, 0);
-}
-
-u16 hpi_tuner_get_deemphasis(u32 h_control, u32 *pdeemphasis)
-{
- return hpi_control_param1_get(h_control, HPI_TUNER_DEEMPHASIS,
- pdeemphasis);
-}
-
-u16 hpi_tuner_query_program(const u32 h_tuner, u32 *pbitmap_program)
-{
- return hpi_control_query(h_tuner, HPI_TUNER_PROGRAM, 0, 0,
- pbitmap_program);
-}
-
-u16 hpi_tuner_set_program(u32 h_control, u32 program)
-{
- return hpi_control_param_set(h_control, HPI_TUNER_PROGRAM, program,
- 0);
-}
-
-u16 hpi_tuner_get_program(u32 h_control, u32 *pprogram)
-{
- return hpi_control_param1_get(h_control, HPI_TUNER_PROGRAM, pprogram);
-}
-
-u16 hpi_tuner_get_hd_radio_dsp_version(u32 h_control, char *psz_dsp_version,
- const u32 string_size)
-{
- return hpi_control_get_string(h_control,
- HPI_TUNER_HDRADIO_DSP_VERSION, psz_dsp_version, string_size);
-}
-
-u16 hpi_tuner_get_hd_radio_sdk_version(u32 h_control, char *psz_sdk_version,
- const u32 string_size)
-{
- return hpi_control_get_string(h_control,
- HPI_TUNER_HDRADIO_SDK_VERSION, psz_sdk_version, string_size);
-}
-
-u16 hpi_tuner_get_status(u32 h_control, u16 *pw_status_mask, u16 *pw_status)
-{
- u32 status = 0;
- u16 error = 0;
-
- error = hpi_control_param1_get(h_control, HPI_TUNER_STATUS, &status);
- if (pw_status) {
- if (!error) {
- *pw_status_mask = (u16)(status >> 16);
- *pw_status = (u16)(status & 0xFFFF);
- } else {
- *pw_status_mask = 0;
- *pw_status = 0;
- }
- }
- return error;
-}
-
-u16 hpi_tuner_set_mode(u32 h_control, u32 mode, u32 value)
-{
- return hpi_control_param_set(h_control, HPI_TUNER_MODE, mode, value);
-}
-
-u16 hpi_tuner_get_mode(u32 h_control, u32 mode, u32 *pn_value)
-{
- return hpi_control_param_get(h_control, HPI_TUNER_MODE, mode, 0,
- pn_value, NULL);
-}
-
-u16 hpi_tuner_get_hd_radio_signal_quality(u32 h_control, u32 *pquality)
-{
- return hpi_control_param1_get(h_control,
- HPI_TUNER_HDRADIO_SIGNAL_QUALITY, pquality);
-}
-
-u16 hpi_tuner_get_hd_radio_signal_blend(u32 h_control, u32 *pblend)
-{
- return hpi_control_param1_get(h_control, HPI_TUNER_HDRADIO_BLEND,
- pblend);
-}
-
-u16 hpi_tuner_set_hd_radio_signal_blend(u32 h_control, const u32 blend)
-{
- return hpi_control_param_set(h_control, HPI_TUNER_HDRADIO_BLEND,
- blend, 0);
-}
-
-u16 hpi_tuner_get_rds(u32 h_control, char *p_data)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_GET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.c.attribute = HPI_TUNER_RDS;
- hpi_send_recv(&hm, &hr);
- if (p_data) {
- *(u32 *)&p_data[0] = hr.u.cu.tuner.rds.data[0];
- *(u32 *)&p_data[4] = hr.u.cu.tuner.rds.data[1];
- *(u32 *)&p_data[8] = hr.u.cu.tuner.rds.bLER;
- }
- return hr.error;
-}
-
-u16 hpi_pad_get_channel_name(u32 h_control, char *psz_string,
- const u32 data_length)
-{
- return hpi_control_get_string(h_control, HPI_PAD_CHANNEL_NAME,
- psz_string, data_length);
-}
-
-u16 hpi_pad_get_artist(u32 h_control, char *psz_string, const u32 data_length)
-{
- return hpi_control_get_string(h_control, HPI_PAD_ARTIST, psz_string,
- data_length);
-}
-
-u16 hpi_pad_get_title(u32 h_control, char *psz_string, const u32 data_length)
-{
- return hpi_control_get_string(h_control, HPI_PAD_TITLE, psz_string,
- data_length);
-}
-
-u16 hpi_pad_get_comment(u32 h_control, char *psz_string,
- const u32 data_length)
-{
- return hpi_control_get_string(h_control, HPI_PAD_COMMENT, psz_string,
- data_length);
-}
-
-u16 hpi_pad_get_program_type(u32 h_control, u32 *ppTY)
-{
- return hpi_control_param1_get(h_control, HPI_PAD_PROGRAM_TYPE, ppTY);
-}
-
-u16 hpi_pad_get_rdsPI(u32 h_control, u32 *ppI)
-{
- return hpi_control_param1_get(h_control, HPI_PAD_PROGRAM_ID, ppI);
-}
-
-u16 hpi_volume_query_channels(const u32 h_volume, u32 *p_channels)
-{
- return hpi_control_query(h_volume, HPI_VOLUME_NUM_CHANNELS, 0, 0,
- p_channels);
-}
-
-u16 hpi_volume_set_gain(u32 h_control, short an_log_gain[HPI_MAX_CHANNELS]
- )
-{
- return hpi_control_log_set2(h_control, HPI_VOLUME_GAIN,
- an_log_gain[0], an_log_gain[1]);
-}
-
-u16 hpi_volume_get_gain(u32 h_control, short an_log_gain[HPI_MAX_CHANNELS]
- )
-{
- return hpi_control_log_get2(h_control, HPI_VOLUME_GAIN,
- &an_log_gain[0], &an_log_gain[1]);
-}
-
-u16 hpi_volume_set_mute(u32 h_control, u32 mute)
-{
- return hpi_control_param_set(h_control, HPI_VOLUME_MUTE, mute, 0);
-}
-
-u16 hpi_volume_get_mute(u32 h_control, u32 *mute)
-{
- return hpi_control_param1_get(h_control, HPI_VOLUME_MUTE, mute);
-}
-
-u16 hpi_volume_query_range(u32 h_control, short *min_gain_01dB,
- short *max_gain_01dB, short *step_gain_01dB)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_GET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.c.attribute = HPI_VOLUME_RANGE;
-
- hpi_send_recv(&hm, &hr);
- if (hr.error) {
- hr.u.c.an_log_value[0] = 0;
- hr.u.c.an_log_value[1] = 0;
- hr.u.c.param1 = 0;
- }
- if (min_gain_01dB)
- *min_gain_01dB = hr.u.c.an_log_value[0];
- if (max_gain_01dB)
- *max_gain_01dB = hr.u.c.an_log_value[1];
- if (step_gain_01dB)
- *step_gain_01dB = (short)hr.u.c.param1;
- return hr.error;
-}
-
-u16 hpi_volume_auto_fade_profile(u32 h_control,
- short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms,
- u16 profile)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_SET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
-
- memcpy(hm.u.c.an_log_value, an_stop_gain0_01dB,
- sizeof(short) * HPI_MAX_CHANNELS);
-
- hm.u.c.attribute = HPI_VOLUME_AUTOFADE;
- hm.u.c.param1 = duration_ms;
- hm.u.c.param2 = profile;
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_volume_auto_fade(u32 h_control,
- short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms)
-{
- return hpi_volume_auto_fade_profile(h_control, an_stop_gain0_01dB,
- duration_ms, HPI_VOLUME_AUTOFADE_LOG);
-}
-
-u16 hpi_volume_query_auto_fade_profile(const u32 h_volume, const u32 i,
- u16 *profile)
-{
- u16 e;
- u32 u;
- e = hpi_control_query(h_volume, HPI_VOLUME_AUTOFADE, i, 0, &u);
- *profile = (u16)u;
- return e;
-}
-
-u16 hpi_vox_set_threshold(u32 h_control, short an_gain0_01dB)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_SET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.c.attribute = HPI_VOX_THRESHOLD;
-
- hm.u.c.an_log_value[0] = an_gain0_01dB;
-
- hpi_send_recv(&hm, &hr);
-
- return hr.error;
-}
-
-u16 hpi_vox_get_threshold(u32 h_control, short *an_gain0_01dB)
-{
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
- HPI_CONTROL_GET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
- hm.u.c.attribute = HPI_VOX_THRESHOLD;
-
- hpi_send_recv(&hm, &hr);
-
- *an_gain0_01dB = hr.u.c.an_log_value[0];
-
- return hr.error;
-}
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpimsginit.c b/ANDROID_3.4.5/sound/pci/asihpi/hpimsginit.c
deleted file mode 100644
index 032d563e..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpimsginit.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/******************************************************************************
-
- AudioScience HPI driver
- Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- Hardware Programming Interface (HPI) Utility functions.
-
- (C) Copyright AudioScience Inc. 2007
-*******************************************************************************/
-
-#include "hpi_internal.h"
-#include "hpimsginit.h"
-
-/* The actual message size for each object type */
-static u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT;
-/* The actual response size for each object type */
-static u16 res_size[HPI_OBJ_MAXINDEX + 1] = HPI_RESPONSE_SIZE_BY_OBJECT;
-/* Flag to enable alternate message type for SSX2 bypass. */
-static u16 gwSSX2_bypass;
-
-/** \internal
- * initialize the HPI message structure
- */
-static void hpi_init_message(struct hpi_message *phm, u16 object,
- u16 function)
-{
- memset(phm, 0, sizeof(*phm));
- if ((object > 0) && (object <= HPI_OBJ_MAXINDEX))
- phm->size = msg_size[object];
- else
- phm->size = sizeof(*phm);
-
- if (gwSSX2_bypass)
- phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE;
- else
- phm->type = HPI_TYPE_REQUEST;
- phm->object = object;
- phm->function = function;
- phm->version = 0;
- phm->adapter_index = HPI_ADAPTER_INDEX_INVALID;
- /* Expect actual adapter index to be set by caller */
-}
-
-/** \internal
- * initialize the HPI response structure
- */
-void hpi_init_response(struct hpi_response *phr, u16 object, u16 function,
- u16 error)
-{
- memset(phr, 0, sizeof(*phr));
- phr->type = HPI_TYPE_RESPONSE;
- if ((object > 0) && (object <= HPI_OBJ_MAXINDEX))
- phr->size = res_size[object];
- else
- phr->size = sizeof(*phr);
- phr->object = object;
- phr->function = function;
- phr->error = error;
- phr->specific_error = 0;
- phr->version = 0;
-}
-
-void hpi_init_message_response(struct hpi_message *phm,
- struct hpi_response *phr, u16 object, u16 function)
-{
- hpi_init_message(phm, object, function);
- /* default error return if the response is
- not filled in by the callee */
- hpi_init_response(phr, object, function,
- HPI_ERROR_PROCESSING_MESSAGE);
-}
-
-static void hpi_init_messageV1(struct hpi_message_header *phm, u16 size,
- u16 object, u16 function)
-{
- memset(phm, 0, sizeof(*phm));
- if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
- phm->size = size;
- phm->type = HPI_TYPE_REQUEST;
- phm->object = object;
- phm->function = function;
- phm->version = 1;
- /* Expect adapter index to be set by caller */
- }
-}
-
-void hpi_init_responseV1(struct hpi_response_header *phr, u16 size,
- u16 object, u16 function)
-{
- memset(phr, 0, sizeof(*phr));
- phr->size = size;
- phr->version = 1;
- phr->type = HPI_TYPE_RESPONSE;
- phr->error = HPI_ERROR_PROCESSING_MESSAGE;
-}
-
-void hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size,
- struct hpi_response_header *phr, u16 res_size, u16 object,
- u16 function)
-{
- hpi_init_messageV1(phm, msg_size, object, function);
- hpi_init_responseV1(phr, res_size, object, function);
-}
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpimsginit.h b/ANDROID_3.4.5/sound/pci/asihpi/hpimsginit.h
deleted file mode 100644
index 5b48708c..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpimsginit.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/******************************************************************************
-
- AudioScience HPI driver
- Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- Hardware Programming Interface (HPI) Utility functions
-
- (C) Copyright AudioScience Inc. 2007
-*******************************************************************************/
-/* Initialise response headers, or msg/response pairs.
-Note that it is valid to just init a response e.g. when a lower level is
-preparing a response to a message.
-However, when sending a message, a matching response buffer must always be
-prepared.
-*/
-
-#ifndef _HPIMSGINIT_H_
-#define _HPIMSGINIT_H_
-
-void hpi_init_response(struct hpi_response *phr, u16 object, u16 function,
- u16 error);
-
-void hpi_init_message_response(struct hpi_message *phm,
- struct hpi_response *phr, u16 object, u16 function);
-
-void hpi_init_responseV1(struct hpi_response_header *phr, u16 size,
- u16 object, u16 function);
-
-void hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size,
- struct hpi_response_header *phr, u16 res_size, u16 object,
- u16 function);
-
-#endif /* _HPIMSGINIT_H_ */
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpimsgx.c b/ANDROID_3.4.5/sound/pci/asihpi/hpimsgx.c
deleted file mode 100644
index d4790ddc..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpimsgx.c
+++ /dev/null
@@ -1,800 +0,0 @@
-/******************************************************************************
-
- AudioScience HPI driver
- Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Extended Message Function With Response Caching
-
-(C) Copyright AudioScience Inc. 2002
-*****************************************************************************/
-#define SOURCEFILE_NAME "hpimsgx.c"
-#include "hpi_internal.h"
-#include "hpi_version.h"
-#include "hpimsginit.h"
-#include "hpicmn.h"
-#include "hpimsgx.h"
-#include "hpidebug.h"
-
-static struct pci_device_id asihpi_pci_tbl[] = {
-#include "hpipcida.h"
-};
-
-static struct hpios_spinlock msgx_lock;
-
-static hpi_handler_func *hpi_entry_points[HPI_MAX_ADAPTERS];
-
-static hpi_handler_func *hpi_lookup_entry_point_function(const struct hpi_pci
- *pci_info)
-{
-
- int i;
-
- for (i = 0; asihpi_pci_tbl[i].vendor != 0; i++) {
- if (asihpi_pci_tbl[i].vendor != PCI_ANY_ID
- && asihpi_pci_tbl[i].vendor !=
- pci_info->pci_dev->vendor)
- continue;
- if (asihpi_pci_tbl[i].device != PCI_ANY_ID
- && asihpi_pci_tbl[i].device !=
- pci_info->pci_dev->device)
- continue;
- if (asihpi_pci_tbl[i].subvendor != PCI_ANY_ID
- && asihpi_pci_tbl[i].subvendor !=
- pci_info->pci_dev->subsystem_vendor)
- continue;
- if (asihpi_pci_tbl[i].subdevice != PCI_ANY_ID
- && asihpi_pci_tbl[i].subdevice !=
- pci_info->pci_dev->subsystem_device)
- continue;
-
- /* HPI_DEBUG_LOG(DEBUG, " %x,%lx\n", i,
- asihpi_pci_tbl[i].driver_data); */
- return (hpi_handler_func *) asihpi_pci_tbl[i].driver_data;
- }
-
- return NULL;
-}
-
-static inline void hw_entry_point(struct hpi_message *phm,
- struct hpi_response *phr)
-{
- if ((phm->adapter_index < HPI_MAX_ADAPTERS)
- && hpi_entry_points[phm->adapter_index])
- hpi_entry_points[phm->adapter_index] (phm, phr);
- else
- hpi_init_response(phr, phm->object, phm->function,
- HPI_ERROR_PROCESSING_MESSAGE);
-}
-
-static void adapter_open(struct hpi_message *phm, struct hpi_response *phr);
-static void adapter_close(struct hpi_message *phm, struct hpi_response *phr);
-
-static void mixer_open(struct hpi_message *phm, struct hpi_response *phr);
-static void mixer_close(struct hpi_message *phm, struct hpi_response *phr);
-
-static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
- void *h_owner);
-static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
- void *h_owner);
-static void instream_open(struct hpi_message *phm, struct hpi_response *phr,
- void *h_owner);
-static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
- void *h_owner);
-
-static void HPIMSGX__reset(u16 adapter_index);
-
-static u16 HPIMSGX__init(struct hpi_message *phm, struct hpi_response *phr);
-static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner);
-
-#ifndef DISABLE_PRAGMA_PACK1
-#pragma pack(push, 1)
-#endif
-
-struct hpi_subsys_response {
- struct hpi_response_header h;
- struct hpi_subsys_res s;
-};
-
-struct hpi_adapter_response {
- struct hpi_response_header h;
- struct hpi_adapter_res a;
-};
-
-struct hpi_mixer_response {
- struct hpi_response_header h;
- struct hpi_mixer_res m;
-};
-
-struct hpi_stream_response {
- struct hpi_response_header h;
- struct hpi_stream_res d;
-};
-
-struct adapter_info {
- u16 type;
- u16 num_instreams;
- u16 num_outstreams;
-};
-
-struct asi_open_state {
- int open_flag;
- void *h_owner;
-};
-
-#ifndef DISABLE_PRAGMA_PACK1
-#pragma pack(pop)
-#endif
-
-/* Globals */
-static struct hpi_adapter_response rESP_HPI_ADAPTER_OPEN[HPI_MAX_ADAPTERS];
-
-static struct hpi_stream_response
- rESP_HPI_OSTREAM_OPEN[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
-
-static struct hpi_stream_response
- rESP_HPI_ISTREAM_OPEN[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
-
-static struct hpi_mixer_response rESP_HPI_MIXER_OPEN[HPI_MAX_ADAPTERS];
-
-static struct adapter_info aDAPTER_INFO[HPI_MAX_ADAPTERS];
-
-/* use these to keep track of opens from user mode apps/DLLs */
-static struct asi_open_state
- outstream_user_open[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
-
-static struct asi_open_state
- instream_user_open[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
-
-static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
- void *h_owner)
-{
- if (phm->adapter_index != HPI_ADAPTER_INDEX_INVALID)
- HPI_DEBUG_LOG(WARNING,
- "suspicious adapter index %d in subsys message 0x%x.\n",
- phm->adapter_index, phm->function);
-
- switch (phm->function) {
- case HPI_SUBSYS_GET_VERSION:
- hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
- HPI_SUBSYS_GET_VERSION, 0);
- phr->u.s.version = HPI_VER >> 8; /* return major.minor */
- phr->u.s.data = HPI_VER; /* return major.minor.release */
- break;
- case HPI_SUBSYS_OPEN:
- /*do not propagate the message down the chain */
- hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_OPEN, 0);
- break;
- case HPI_SUBSYS_CLOSE:
- /*do not propagate the message down the chain */
- hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CLOSE,
- 0);
- HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner);
- break;
- case HPI_SUBSYS_DRIVER_LOAD:
- /* Initialize this module's internal state */
- hpios_msgxlock_init(&msgx_lock);
- memset(&hpi_entry_points, 0, sizeof(hpi_entry_points));
- /* Init subsys_findadapters response to no-adapters */
- HPIMSGX__reset(HPIMSGX_ALLADAPTERS);
- hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
- HPI_SUBSYS_DRIVER_LOAD, 0);
- /* individual HPIs dont implement driver load */
- HPI_COMMON(phm, phr);
- break;
- case HPI_SUBSYS_DRIVER_UNLOAD:
- HPI_COMMON(phm, phr);
- HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner);
- hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
- HPI_SUBSYS_DRIVER_UNLOAD, 0);
- return;
-
- case HPI_SUBSYS_GET_NUM_ADAPTERS:
- case HPI_SUBSYS_GET_ADAPTER:
- HPI_COMMON(phm, phr);
- break;
-
- case HPI_SUBSYS_CREATE_ADAPTER:
- HPIMSGX__init(phm, phr);
- break;
-
- default:
- /* Must explicitly handle every subsys message in this switch */
- hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function,
- HPI_ERROR_INVALID_FUNC);
- break;
- }
-}
-
-static void adapter_message(struct hpi_message *phm, struct hpi_response *phr,
- void *h_owner)
-{
- switch (phm->function) {
- case HPI_ADAPTER_OPEN:
- adapter_open(phm, phr);
- break;
- case HPI_ADAPTER_CLOSE:
- adapter_close(phm, phr);
- break;
- case HPI_ADAPTER_DELETE:
- HPIMSGX__cleanup(phm->adapter_index, h_owner);
- {
- struct hpi_message hm;
- struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
- HPI_ADAPTER_CLOSE);
- hm.adapter_index = phm->adapter_index;
- hw_entry_point(&hm, &hr);
- }
- hw_entry_point(phm, phr);
- break;
-
- default:
- hw_entry_point(phm, phr);
- break;
- }
-}
-
-static void mixer_message(struct hpi_message *phm, struct hpi_response *phr)
-{
- switch (phm->function) {
- case HPI_MIXER_OPEN:
- mixer_open(phm, phr);
- break;
- case HPI_MIXER_CLOSE:
- mixer_close(phm, phr);
- break;
- default:
- hw_entry_point(phm, phr);
- break;
- }
-}
-
-static void outstream_message(struct hpi_message *phm,
- struct hpi_response *phr, void *h_owner)
-{
- if (phm->obj_index >= aDAPTER_INFO[phm->adapter_index].num_outstreams) {
- hpi_init_response(phr, HPI_OBJ_OSTREAM, phm->function,
- HPI_ERROR_INVALID_OBJ_INDEX);
- return;
- }
-
- switch (phm->function) {
- case HPI_OSTREAM_OPEN:
- outstream_open(phm, phr, h_owner);
- break;
- case HPI_OSTREAM_CLOSE:
- outstream_close(phm, phr, h_owner);
- break;
- default:
- hw_entry_point(phm, phr);
- break;
- }
-}
-
-static void instream_message(struct hpi_message *phm,
- struct hpi_response *phr, void *h_owner)
-{
- if (phm->obj_index >= aDAPTER_INFO[phm->adapter_index].num_instreams) {
- hpi_init_response(phr, HPI_OBJ_ISTREAM, phm->function,
- HPI_ERROR_INVALID_OBJ_INDEX);
- return;
- }
-
- switch (phm->function) {
- case HPI_ISTREAM_OPEN:
- instream_open(phm, phr, h_owner);
- break;
- case HPI_ISTREAM_CLOSE:
- instream_close(phm, phr, h_owner);
- break;
- default:
- hw_entry_point(phm, phr);
- break;
- }
-}
-
-/* NOTE: HPI_Message() must be defined in the driver as a wrapper for
- * HPI_MessageEx so that functions in hpifunc.c compile.
- */
-void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr,
- void *h_owner)
-{
- HPI_DEBUG_MESSAGE(DEBUG, phm);
-
- if (phm->type != HPI_TYPE_REQUEST) {
- hpi_init_response(phr, phm->object, phm->function,
- HPI_ERROR_INVALID_TYPE);
- return;
- }
-
- if (phm->adapter_index >= HPI_MAX_ADAPTERS
- && phm->adapter_index != HPIMSGX_ALLADAPTERS) {
- hpi_init_response(phr, phm->object, phm->function,
- HPI_ERROR_BAD_ADAPTER_NUMBER);
- return;
- }
-
- switch (phm->object) {
- case HPI_OBJ_SUBSYSTEM:
- subsys_message(phm, phr, h_owner);
- break;
-
- case HPI_OBJ_ADAPTER:
- adapter_message(phm, phr, h_owner);
- break;
-
- case HPI_OBJ_MIXER:
- mixer_message(phm, phr);
- break;
-
- case HPI_OBJ_OSTREAM:
- outstream_message(phm, phr, h_owner);
- break;
-
- case HPI_OBJ_ISTREAM:
- instream_message(phm, phr, h_owner);
- break;
-
- default:
- hw_entry_point(phm, phr);
- break;
- }
- HPI_DEBUG_RESPONSE(phr);
-
-}
-
-static void adapter_open(struct hpi_message *phm, struct hpi_response *phr)
-{
- HPI_DEBUG_LOG(VERBOSE, "adapter_open\n");
- memcpy(phr, &rESP_HPI_ADAPTER_OPEN[phm->adapter_index],
- sizeof(rESP_HPI_ADAPTER_OPEN[0]));
-}
-
-static void adapter_close(struct hpi_message *phm, struct hpi_response *phr)
-{
- HPI_DEBUG_LOG(VERBOSE, "adapter_close\n");
- hpi_init_response(phr, HPI_OBJ_ADAPTER, HPI_ADAPTER_CLOSE, 0);
-}
-
-static void mixer_open(struct hpi_message *phm, struct hpi_response *phr)
-{
- memcpy(phr, &rESP_HPI_MIXER_OPEN[phm->adapter_index],
- sizeof(rESP_HPI_MIXER_OPEN[0]));
-}
-
-static void mixer_close(struct hpi_message *phm, struct hpi_response *phr)
-{
- hpi_init_response(phr, HPI_OBJ_MIXER, HPI_MIXER_CLOSE, 0);
-}
-
-static void instream_open(struct hpi_message *phm, struct hpi_response *phr,
- void *h_owner)
-{
-
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_response(phr, HPI_OBJ_ISTREAM, HPI_ISTREAM_OPEN, 0);
-
- hpios_msgxlock_lock(&msgx_lock);
-
- if (instream_user_open[phm->adapter_index][phm->obj_index].open_flag)
- phr->error = HPI_ERROR_OBJ_ALREADY_OPEN;
- else if (rESP_HPI_ISTREAM_OPEN[phm->adapter_index]
- [phm->obj_index].h.error)
- memcpy(phr,
- &rESP_HPI_ISTREAM_OPEN[phm->adapter_index][phm->
- obj_index],
- sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
- else {
- instream_user_open[phm->adapter_index][phm->
- obj_index].open_flag = 1;
- hpios_msgxlock_unlock(&msgx_lock);
-
- /* issue a reset */
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_RESET);
- hm.adapter_index = phm->adapter_index;
- hm.obj_index = phm->obj_index;
- hw_entry_point(&hm, &hr);
-
- hpios_msgxlock_lock(&msgx_lock);
- if (hr.error) {
- instream_user_open[phm->adapter_index][phm->
- obj_index].open_flag = 0;
- phr->error = hr.error;
- } else {
- instream_user_open[phm->adapter_index][phm->
- obj_index].open_flag = 1;
- instream_user_open[phm->adapter_index][phm->
- obj_index].h_owner = h_owner;
- memcpy(phr,
- &rESP_HPI_ISTREAM_OPEN[phm->adapter_index]
- [phm->obj_index],
- sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
- }
- }
- hpios_msgxlock_unlock(&msgx_lock);
-}
-
-static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
- void *h_owner)
-{
-
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_response(phr, HPI_OBJ_ISTREAM, HPI_ISTREAM_CLOSE, 0);
-
- hpios_msgxlock_lock(&msgx_lock);
- if (h_owner ==
- instream_user_open[phm->adapter_index][phm->
- obj_index].h_owner) {
- /* HPI_DEBUG_LOG(INFO,"closing adapter %d "
- "instream %d owned by %p\n",
- phm->wAdapterIndex, phm->wObjIndex, hOwner); */
- instream_user_open[phm->adapter_index][phm->
- obj_index].h_owner = NULL;
- hpios_msgxlock_unlock(&msgx_lock);
- /* issue a reset */
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_RESET);
- hm.adapter_index = phm->adapter_index;
- hm.obj_index = phm->obj_index;
- hw_entry_point(&hm, &hr);
- hpios_msgxlock_lock(&msgx_lock);
- if (hr.error) {
- instream_user_open[phm->adapter_index][phm->
- obj_index].h_owner = h_owner;
- phr->error = hr.error;
- } else {
- instream_user_open[phm->adapter_index][phm->
- obj_index].open_flag = 0;
- instream_user_open[phm->adapter_index][phm->
- obj_index].h_owner = NULL;
- }
- } else {
- HPI_DEBUG_LOG(WARNING,
- "%p trying to close %d instream %d owned by %p\n",
- h_owner, phm->adapter_index, phm->obj_index,
- instream_user_open[phm->adapter_index][phm->
- obj_index].h_owner);
- phr->error = HPI_ERROR_OBJ_NOT_OPEN;
- }
- hpios_msgxlock_unlock(&msgx_lock);
-}
-
-static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
- void *h_owner)
-{
-
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_response(phr, HPI_OBJ_OSTREAM, HPI_OSTREAM_OPEN, 0);
-
- hpios_msgxlock_lock(&msgx_lock);
-
- if (outstream_user_open[phm->adapter_index][phm->obj_index].open_flag)
- phr->error = HPI_ERROR_OBJ_ALREADY_OPEN;
- else if (rESP_HPI_OSTREAM_OPEN[phm->adapter_index]
- [phm->obj_index].h.error)
- memcpy(phr,
- &rESP_HPI_OSTREAM_OPEN[phm->adapter_index][phm->
- obj_index],
- sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
- else {
- outstream_user_open[phm->adapter_index][phm->
- obj_index].open_flag = 1;
- hpios_msgxlock_unlock(&msgx_lock);
-
- /* issue a reset */
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_RESET);
- hm.adapter_index = phm->adapter_index;
- hm.obj_index = phm->obj_index;
- hw_entry_point(&hm, &hr);
-
- hpios_msgxlock_lock(&msgx_lock);
- if (hr.error) {
- outstream_user_open[phm->adapter_index][phm->
- obj_index].open_flag = 0;
- phr->error = hr.error;
- } else {
- outstream_user_open[phm->adapter_index][phm->
- obj_index].open_flag = 1;
- outstream_user_open[phm->adapter_index][phm->
- obj_index].h_owner = h_owner;
- memcpy(phr,
- &rESP_HPI_OSTREAM_OPEN[phm->adapter_index]
- [phm->obj_index],
- sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
- }
- }
- hpios_msgxlock_unlock(&msgx_lock);
-}
-
-static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
- void *h_owner)
-{
-
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_response(phr, HPI_OBJ_OSTREAM, HPI_OSTREAM_CLOSE, 0);
-
- hpios_msgxlock_lock(&msgx_lock);
-
- if (h_owner ==
- outstream_user_open[phm->adapter_index][phm->
- obj_index].h_owner) {
- /* HPI_DEBUG_LOG(INFO,"closing adapter %d "
- "outstream %d owned by %p\n",
- phm->wAdapterIndex, phm->wObjIndex, hOwner); */
- outstream_user_open[phm->adapter_index][phm->
- obj_index].h_owner = NULL;
- hpios_msgxlock_unlock(&msgx_lock);
- /* issue a reset */
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_RESET);
- hm.adapter_index = phm->adapter_index;
- hm.obj_index = phm->obj_index;
- hw_entry_point(&hm, &hr);
- hpios_msgxlock_lock(&msgx_lock);
- if (hr.error) {
- outstream_user_open[phm->adapter_index][phm->
- obj_index].h_owner = h_owner;
- phr->error = hr.error;
- } else {
- outstream_user_open[phm->adapter_index][phm->
- obj_index].open_flag = 0;
- outstream_user_open[phm->adapter_index][phm->
- obj_index].h_owner = NULL;
- }
- } else {
- HPI_DEBUG_LOG(WARNING,
- "%p trying to close %d outstream %d owned by %p\n",
- h_owner, phm->adapter_index, phm->obj_index,
- outstream_user_open[phm->adapter_index][phm->
- obj_index].h_owner);
- phr->error = HPI_ERROR_OBJ_NOT_OPEN;
- }
- hpios_msgxlock_unlock(&msgx_lock);
-}
-
-static u16 adapter_prepare(u16 adapter)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- /* Open the adapter and streams */
- u16 i;
-
- /* call to HPI_ADAPTER_OPEN */
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
- HPI_ADAPTER_OPEN);
- hm.adapter_index = adapter;
- hw_entry_point(&hm, &hr);
- memcpy(&rESP_HPI_ADAPTER_OPEN[adapter], &hr,
- sizeof(rESP_HPI_ADAPTER_OPEN[0]));
- if (hr.error)
- return hr.error;
-
- /* call to HPI_ADAPTER_GET_INFO */
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
- HPI_ADAPTER_GET_INFO);
- hm.adapter_index = adapter;
- hw_entry_point(&hm, &hr);
- if (hr.error)
- return hr.error;
-
- aDAPTER_INFO[adapter].num_outstreams = hr.u.ax.info.num_outstreams;
- aDAPTER_INFO[adapter].num_instreams = hr.u.ax.info.num_instreams;
- aDAPTER_INFO[adapter].type = hr.u.ax.info.adapter_type;
-
- /* call to HPI_OSTREAM_OPEN */
- for (i = 0; i < aDAPTER_INFO[adapter].num_outstreams; i++) {
- hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_OPEN);
- hm.adapter_index = adapter;
- hm.obj_index = i;
- hw_entry_point(&hm, &hr);
- memcpy(&rESP_HPI_OSTREAM_OPEN[adapter][i], &hr,
- sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
- outstream_user_open[adapter][i].open_flag = 0;
- outstream_user_open[adapter][i].h_owner = NULL;
- }
-
- /* call to HPI_ISTREAM_OPEN */
- for (i = 0; i < aDAPTER_INFO[adapter].num_instreams; i++) {
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_OPEN);
- hm.adapter_index = adapter;
- hm.obj_index = i;
- hw_entry_point(&hm, &hr);
- memcpy(&rESP_HPI_ISTREAM_OPEN[adapter][i], &hr,
- sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
- instream_user_open[adapter][i].open_flag = 0;
- instream_user_open[adapter][i].h_owner = NULL;
- }
-
- /* call to HPI_MIXER_OPEN */
- hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN);
- hm.adapter_index = adapter;
- hw_entry_point(&hm, &hr);
- memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr,
- sizeof(rESP_HPI_MIXER_OPEN[0]));
-
- return 0;
-}
-
-static void HPIMSGX__reset(u16 adapter_index)
-{
- int i;
- u16 adapter;
- struct hpi_response hr;
-
- if (adapter_index == HPIMSGX_ALLADAPTERS) {
- for (adapter = 0; adapter < HPI_MAX_ADAPTERS; adapter++) {
-
- hpi_init_response(&hr, HPI_OBJ_ADAPTER,
- HPI_ADAPTER_OPEN, HPI_ERROR_BAD_ADAPTER);
- memcpy(&rESP_HPI_ADAPTER_OPEN[adapter], &hr,
- sizeof(rESP_HPI_ADAPTER_OPEN[adapter]));
-
- hpi_init_response(&hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN,
- HPI_ERROR_INVALID_OBJ);
- memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr,
- sizeof(rESP_HPI_MIXER_OPEN[adapter]));
-
- for (i = 0; i < HPI_MAX_STREAMS; i++) {
- hpi_init_response(&hr, HPI_OBJ_OSTREAM,
- HPI_OSTREAM_OPEN,
- HPI_ERROR_INVALID_OBJ);
- memcpy(&rESP_HPI_OSTREAM_OPEN[adapter][i],
- &hr,
- sizeof(rESP_HPI_OSTREAM_OPEN[adapter]
- [i]));
- hpi_init_response(&hr, HPI_OBJ_ISTREAM,
- HPI_ISTREAM_OPEN,
- HPI_ERROR_INVALID_OBJ);
- memcpy(&rESP_HPI_ISTREAM_OPEN[adapter][i],
- &hr,
- sizeof(rESP_HPI_ISTREAM_OPEN[adapter]
- [i]));
- }
- }
- } else if (adapter_index < HPI_MAX_ADAPTERS) {
- rESP_HPI_ADAPTER_OPEN[adapter_index].h.error =
- HPI_ERROR_BAD_ADAPTER;
- rESP_HPI_MIXER_OPEN[adapter_index].h.error =
- HPI_ERROR_INVALID_OBJ;
- for (i = 0; i < HPI_MAX_STREAMS; i++) {
- rESP_HPI_OSTREAM_OPEN[adapter_index][i].h.error =
- HPI_ERROR_INVALID_OBJ;
- rESP_HPI_ISTREAM_OPEN[adapter_index][i].h.error =
- HPI_ERROR_INVALID_OBJ;
- }
- }
-}
-
-static u16 HPIMSGX__init(struct hpi_message *phm,
- /* HPI_SUBSYS_CREATE_ADAPTER structure with */
- /* resource list or NULL=find all */
- struct hpi_response *phr
- /* response from HPI_ADAPTER_GET_INFO */
- )
-{
- hpi_handler_func *entry_point_func;
- struct hpi_response hr;
-
- /* Init response here so we can pass in previous adapter list */
- hpi_init_response(&hr, phm->object, phm->function,
- HPI_ERROR_INVALID_OBJ);
-
- entry_point_func =
- hpi_lookup_entry_point_function(phm->u.s.resource.r.pci);
-
- if (entry_point_func) {
- HPI_DEBUG_MESSAGE(DEBUG, phm);
- entry_point_func(phm, &hr);
- } else {
- phr->error = HPI_ERROR_PROCESSING_MESSAGE;
- return phr->error;
- }
- if (hr.error == 0) {
- /* the adapter was created successfully
- save the mapping for future use */
- hpi_entry_points[hr.u.s.adapter_index] = entry_point_func;
- /* prepare adapter (pre-open streams etc.) */
- HPI_DEBUG_LOG(DEBUG,
- "HPI_SUBSYS_CREATE_ADAPTER successful,"
- " preparing adapter\n");
- adapter_prepare(hr.u.s.adapter_index);
- }
- memcpy(phr, &hr, hr.size);
- return phr->error;
-}
-
-static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner)
-{
- int i, adapter, adapter_limit;
-
- if (!h_owner)
- return;
-
- if (adapter_index == HPIMSGX_ALLADAPTERS) {
- adapter = 0;
- adapter_limit = HPI_MAX_ADAPTERS;
- } else {
- adapter = adapter_index;
- adapter_limit = adapter + 1;
- }
-
- for (; adapter < adapter_limit; adapter++) {
- /* printk(KERN_INFO "Cleanup adapter #%d\n",wAdapter); */
- for (i = 0; i < HPI_MAX_STREAMS; i++) {
- if (h_owner ==
- outstream_user_open[adapter][i].h_owner) {
- struct hpi_message hm;
- struct hpi_response hr;
-
- HPI_DEBUG_LOG(DEBUG,
- "Close adapter %d ostream %d\n",
- adapter, i);
-
- hpi_init_message_response(&hm, &hr,
- HPI_OBJ_OSTREAM, HPI_OSTREAM_RESET);
- hm.adapter_index = (u16)adapter;
- hm.obj_index = (u16)i;
- hw_entry_point(&hm, &hr);
-
- hm.function = HPI_OSTREAM_HOSTBUFFER_FREE;
- hw_entry_point(&hm, &hr);
-
- hm.function = HPI_OSTREAM_GROUP_RESET;
- hw_entry_point(&hm, &hr);
-
- outstream_user_open[adapter][i].open_flag = 0;
- outstream_user_open[adapter][i].h_owner =
- NULL;
- }
- if (h_owner == instream_user_open[adapter][i].h_owner) {
- struct hpi_message hm;
- struct hpi_response hr;
-
- HPI_DEBUG_LOG(DEBUG,
- "Close adapter %d istream %d\n",
- adapter, i);
-
- hpi_init_message_response(&hm, &hr,
- HPI_OBJ_ISTREAM, HPI_ISTREAM_RESET);
- hm.adapter_index = (u16)adapter;
- hm.obj_index = (u16)i;
- hw_entry_point(&hm, &hr);
-
- hm.function = HPI_ISTREAM_HOSTBUFFER_FREE;
- hw_entry_point(&hm, &hr);
-
- hm.function = HPI_ISTREAM_GROUP_RESET;
- hw_entry_point(&hm, &hr);
-
- instream_user_open[adapter][i].open_flag = 0;
- instream_user_open[adapter][i].h_owner = NULL;
- }
- }
- }
-}
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpimsgx.h b/ANDROID_3.4.5/sound/pci/asihpi/hpimsgx.h
deleted file mode 100644
index 37f3efd9..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpimsgx.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/******************************************************************************
-
- AudioScience HPI driver
- Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- HPI Extended Message Handler Functions
-
-(C) Copyright AudioScience Inc. 1997-2003
-******************************************************************************/
-
-#ifndef _HPIMSGX_H_
-#define _HPIMSGX_H_
-
-#include "hpi_internal.h"
-
-#define HPIMSGX_ALLADAPTERS (0xFFFF)
-
-void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr,
- void *h_owner);
-
-#define HPI_MESSAGE_LOWER_LAYER hpi_send_recv_ex
-
-#endif /* _HPIMSGX_H_ */
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpioctl.c b/ANDROID_3.4.5/sound/pci/asihpi/hpioctl.c
deleted file mode 100644
index 60915620..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpioctl.c
+++ /dev/null
@@ -1,482 +0,0 @@
-/*******************************************************************************
-
- AudioScience HPI driver
- Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Common Linux HPI ioctl and module probe/remove functions
-*******************************************************************************/
-#define SOURCEFILE_NAME "hpioctl.c"
-
-#include "hpi_internal.h"
-#include "hpi_version.h"
-#include "hpimsginit.h"
-#include "hpidebug.h"
-#include "hpimsgx.h"
-#include "hpioctl.h"
-#include "hpicmn.h"
-
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/moduleparam.h>
-#include <asm/uaccess.h>
-#include <linux/pci.h>
-#include <linux/stringify.h>
-#include <linux/module.h>
-
-#ifdef MODULE_FIRMWARE
-MODULE_FIRMWARE("asihpi/dsp5000.bin");
-MODULE_FIRMWARE("asihpi/dsp6200.bin");
-MODULE_FIRMWARE("asihpi/dsp6205.bin");
-MODULE_FIRMWARE("asihpi/dsp6400.bin");
-MODULE_FIRMWARE("asihpi/dsp6600.bin");
-MODULE_FIRMWARE("asihpi/dsp8700.bin");
-MODULE_FIRMWARE("asihpi/dsp8900.bin");
-#endif
-
-static int prealloc_stream_buf;
-module_param(prealloc_stream_buf, int, S_IRUGO);
-MODULE_PARM_DESC(prealloc_stream_buf,
- "Preallocate size for per-adapter stream buffer");
-
-/* Allow the debug level to be changed after module load.
- E.g. echo 2 > /sys/module/asihpi/parameters/hpiDebugLevel
-*/
-module_param(hpi_debug_level, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(hpi_debug_level, "debug verbosity 0..5");
-
-/* List of adapters found */
-static struct hpi_adapter adapters[HPI_MAX_ADAPTERS];
-
-/* Wrapper function to HPI_Message to enable dumping of the
- message and response types.
-*/
-static void hpi_send_recv_f(struct hpi_message *phm, struct hpi_response *phr,
- struct file *file)
-{
- if ((phm->adapter_index >= HPI_MAX_ADAPTERS)
- && (phm->object != HPI_OBJ_SUBSYSTEM))
- phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
- else
- hpi_send_recv_ex(phm, phr, file);
-}
-
-/* This is called from hpifunc.c functions, called by ALSA
- * (or other kernel process) In this case there is no file descriptor
- * available for the message cache code
- */
-void hpi_send_recv(struct hpi_message *phm, struct hpi_response *phr)
-{
- hpi_send_recv_f(phm, phr, HOWNER_KERNEL);
-}
-
-EXPORT_SYMBOL(hpi_send_recv);
-/* for radio-asihpi */
-
-int asihpi_hpi_release(struct file *file)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
-/* HPI_DEBUG_LOG(INFO,"hpi_release file %p, pid %d\n", file, current->pid); */
- /* close the subsystem just in case the application forgot to. */
- hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
- HPI_SUBSYS_CLOSE);
- hpi_send_recv_ex(&hm, &hr, file);
- return 0;
-}
-
-long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct hpi_ioctl_linux __user *phpi_ioctl_data;
- void __user *puhm;
- void __user *puhr;
- union hpi_message_buffer_v1 *hm;
- union hpi_response_buffer_v1 *hr;
- u16 res_max_size;
- u32 uncopied_bytes;
- int err = 0;
-
- if (cmd != HPI_IOCTL_LINUX)
- return -EINVAL;
-
- hm = kmalloc(sizeof(*hm), GFP_KERNEL);
- hr = kmalloc(sizeof(*hr), GFP_KERNEL);
- if (!hm || !hr) {
- err = -ENOMEM;
- goto out;
- }
-
- phpi_ioctl_data = (struct hpi_ioctl_linux __user *)arg;
-
- /* Read the message and response pointers from user space. */
- if (get_user(puhm, &phpi_ioctl_data->phm)
- || get_user(puhr, &phpi_ioctl_data->phr)) {
- err = -EFAULT;
- goto out;
- }
-
- /* Now read the message size and data from user space. */
- if (get_user(hm->h.size, (u16 __user *)puhm)) {
- err = -EFAULT;
- goto out;
- }
- if (hm->h.size > sizeof(*hm))
- hm->h.size = sizeof(*hm);
-
- /* printk(KERN_INFO "message size %d\n", hm->h.wSize); */
-
- uncopied_bytes = copy_from_user(hm, puhm, hm->h.size);
- if (uncopied_bytes) {
- HPI_DEBUG_LOG(ERROR, "uncopied bytes %d\n", uncopied_bytes);
- err = -EFAULT;
- goto out;
- }
-
- if (get_user(res_max_size, (u16 __user *)puhr)) {
- err = -EFAULT;
- goto out;
- }
- /* printk(KERN_INFO "user response size %d\n", res_max_size); */
- if (res_max_size < sizeof(struct hpi_response_header)) {
- HPI_DEBUG_LOG(WARNING, "small res size %d\n", res_max_size);
- err = -EFAULT;
- goto out;
- }
-
- switch (hm->h.function) {
- case HPI_SUBSYS_CREATE_ADAPTER:
- case HPI_ADAPTER_DELETE:
- /* Application must not use these functions! */
- hr->h.size = sizeof(hr->h);
- hr->h.error = HPI_ERROR_INVALID_OPERATION;
- hr->h.function = hm->h.function;
- uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
- if (uncopied_bytes)
- err = -EFAULT;
- else
- err = 0;
- goto out;
- }
-
- hr->h.size = res_max_size;
- if (hm->h.object == HPI_OBJ_SUBSYSTEM) {
- hpi_send_recv_f(&hm->m0, &hr->r0, file);
- } else {
- u16 __user *ptr = NULL;
- u32 size = 0;
- /* -1=no data 0=read from user mem, 1=write to user mem */
- int wrflag = -1;
- struct hpi_adapter *pa = NULL;
-
- if (hm->h.adapter_index < ARRAY_SIZE(adapters))
- pa = &adapters[hm->h.adapter_index];
-
- if (!pa || !pa->adapter || !pa->adapter->type) {
- hpi_init_response(&hr->r0, hm->h.object,
- hm->h.function, HPI_ERROR_BAD_ADAPTER_NUMBER);
-
- uncopied_bytes =
- copy_to_user(puhr, hr, sizeof(hr->h));
- if (uncopied_bytes)
- err = -EFAULT;
- else
- err = 0;
- goto out;
- }
-
- if (mutex_lock_interruptible(&pa->mutex)) {
- err = -EINTR;
- goto out;
- }
-
- /* Dig out any pointers embedded in the message. */
- switch (hm->h.function) {
- case HPI_OSTREAM_WRITE:
- case HPI_ISTREAM_READ:{
- /* Yes, sparse, this is correct. */
- ptr = (u16 __user *)hm->m0.u.d.u.data.pb_data;
- size = hm->m0.u.d.u.data.data_size;
-
- /* Allocate buffer according to application request.
- ?Is it better to alloc/free for the duration
- of the transaction?
- */
- if (pa->buffer_size < size) {
- HPI_DEBUG_LOG(DEBUG,
- "Realloc adapter %d stream "
- "buffer from %zd to %d\n",
- hm->h.adapter_index,
- pa->buffer_size, size);
- if (pa->p_buffer) {
- pa->buffer_size = 0;
- vfree(pa->p_buffer);
- }
- pa->p_buffer = vmalloc(size);
- if (pa->p_buffer)
- pa->buffer_size = size;
- else {
- HPI_DEBUG_LOG(ERROR,
- "HPI could not allocate "
- "stream buffer size %d\n",
- size);
-
- mutex_unlock(&pa->mutex);
- err = -EINVAL;
- goto out;
- }
- }
-
- hm->m0.u.d.u.data.pb_data = pa->p_buffer;
- if (hm->h.function == HPI_ISTREAM_READ)
- /* from card, WRITE to user mem */
- wrflag = 1;
- else
- wrflag = 0;
- break;
- }
-
- default:
- size = 0;
- break;
- }
-
- if (size && (wrflag == 0)) {
- uncopied_bytes =
- copy_from_user(pa->p_buffer, ptr, size);
- if (uncopied_bytes)
- HPI_DEBUG_LOG(WARNING,
- "Missed %d of %d "
- "bytes from user\n", uncopied_bytes,
- size);
- }
-
- hpi_send_recv_f(&hm->m0, &hr->r0, file);
-
- if (size && (wrflag == 1)) {
- uncopied_bytes =
- copy_to_user(ptr, pa->p_buffer, size);
- if (uncopied_bytes)
- HPI_DEBUG_LOG(WARNING,
- "Missed %d of %d " "bytes to user\n",
- uncopied_bytes, size);
- }
-
- mutex_unlock(&pa->mutex);
- }
-
- /* on return response size must be set */
- /*printk(KERN_INFO "response size %d\n", hr->h.wSize); */
-
- if (!hr->h.size) {
- HPI_DEBUG_LOG(ERROR, "response zero size\n");
- err = -EFAULT;
- goto out;
- }
-
- if (hr->h.size > res_max_size) {
- HPI_DEBUG_LOG(ERROR, "response too big %d %d\n", hr->h.size,
- res_max_size);
- hr->h.error = HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
- hr->h.specific_error = hr->h.size;
- hr->h.size = sizeof(hr->h);
- }
-
- uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
- if (uncopied_bytes) {
- HPI_DEBUG_LOG(ERROR, "uncopied bytes %d\n", uncopied_bytes);
- err = -EFAULT;
- goto out;
- }
-
-out:
- kfree(hm);
- kfree(hr);
- return err;
-}
-
-int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
-{
- int idx, nm;
- int adapter_index;
- unsigned int memlen;
- struct hpi_message hm;
- struct hpi_response hr;
- struct hpi_adapter adapter;
- struct hpi_pci pci;
-
- memset(&adapter, 0, sizeof(adapter));
-
- dev_printk(KERN_DEBUG, &pci_dev->dev,
- "probe %04x:%04x,%04x:%04x,%04x\n", pci_dev->vendor,
- pci_dev->device, pci_dev->subsystem_vendor,
- pci_dev->subsystem_device, pci_dev->devfn);
-
- if (pci_enable_device(pci_dev) < 0) {
- dev_printk(KERN_ERR, &pci_dev->dev,
- "pci_enable_device failed, disabling device\n");
- return -EIO;
- }
-
- pci_set_master(pci_dev); /* also sets latency timer if < 16 */
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
- HPI_SUBSYS_CREATE_ADAPTER);
- hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CREATE_ADAPTER,
- HPI_ERROR_PROCESSING_MESSAGE);
-
- hm.adapter_index = HPI_ADAPTER_INDEX_INVALID;
-
- nm = HPI_MAX_ADAPTER_MEM_SPACES;
-
- for (idx = 0; idx < nm; idx++) {
- HPI_DEBUG_LOG(INFO, "resource %d %pR\n", idx,
- &pci_dev->resource[idx]);
-
- if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) {
- memlen = pci_resource_len(pci_dev, idx);
- pci.ap_mem_base[idx] =
- ioremap(pci_resource_start(pci_dev, idx),
- memlen);
- if (!pci.ap_mem_base[idx]) {
- HPI_DEBUG_LOG(ERROR,
- "ioremap failed, aborting\n");
- /* unmap previously mapped pci mem space */
- goto err;
- }
- }
- }
-
- pci.pci_dev = pci_dev;
- hm.u.s.resource.bus_type = HPI_BUS_PCI;
- hm.u.s.resource.r.pci = &pci;
-
- /* call CreateAdapterObject on the relevant hpi module */
- hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
- if (hr.error)
- goto err;
-
- adapter_index = hr.u.s.adapter_index;
- adapter.adapter = hpi_find_adapter(adapter_index);
-
- if (prealloc_stream_buf) {
- adapter.p_buffer = vmalloc(prealloc_stream_buf);
- if (!adapter.p_buffer) {
- HPI_DEBUG_LOG(ERROR,
- "HPI could not allocate "
- "kernel buffer size %d\n",
- prealloc_stream_buf);
- goto err;
- }
- }
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
- HPI_ADAPTER_OPEN);
- hm.adapter_index = adapter.adapter->index;
- hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
-
- if (hr.error)
- goto err;
-
- /* WARNING can't init mutex in 'adapter'
- * and then copy it to adapters[] ?!?!
- */
- adapters[adapter_index] = adapter;
- mutex_init(&adapters[adapter_index].mutex);
- pci_set_drvdata(pci_dev, &adapters[adapter_index]);
-
- dev_printk(KERN_INFO, &pci_dev->dev,
- "probe succeeded for ASI%04X HPI index %d\n",
- adapter.adapter->type, adapter_index);
-
- return 0;
-
-err:
- for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) {
- if (pci.ap_mem_base[idx]) {
- iounmap(pci.ap_mem_base[idx]);
- pci.ap_mem_base[idx] = NULL;
- }
- }
-
- if (adapter.p_buffer) {
- adapter.buffer_size = 0;
- vfree(adapter.p_buffer);
- }
-
- HPI_DEBUG_LOG(ERROR, "adapter_probe failed\n");
- return -ENODEV;
-}
-
-void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
-{
- int idx;
- struct hpi_message hm;
- struct hpi_response hr;
- struct hpi_adapter *pa;
- struct hpi_pci pci;
-
- pa = pci_get_drvdata(pci_dev);
- pci = pa->adapter->pci;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
- HPI_ADAPTER_DELETE);
- hm.adapter_index = pa->adapter->index;
- hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
-
- /* unmap PCI memory space, mapped during device init. */
- for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) {
- if (pci.ap_mem_base[idx])
- iounmap(pci.ap_mem_base[idx]);
- }
-
- if (pa->p_buffer)
- vfree(pa->p_buffer);
-
- pci_set_drvdata(pci_dev, NULL);
- if (1)
- dev_printk(KERN_INFO, &pci_dev->dev,
- "remove %04x:%04x,%04x:%04x,%04x," " HPI index %d.\n",
- pci_dev->vendor, pci_dev->device,
- pci_dev->subsystem_vendor, pci_dev->subsystem_device,
- pci_dev->devfn, pa->adapter->index);
-
- memset(pa, 0, sizeof(*pa));
-}
-
-void __init asihpi_init(void)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- memset(adapters, 0, sizeof(adapters));
-
- printk(KERN_INFO "ASIHPI driver " HPI_VER_STRING "\n");
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
- HPI_SUBSYS_DRIVER_LOAD);
- hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
-}
-
-void asihpi_exit(void)
-{
- struct hpi_message hm;
- struct hpi_response hr;
-
- hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
- HPI_SUBSYS_DRIVER_UNLOAD);
- hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
-}
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpioctl.h b/ANDROID_3.4.5/sound/pci/asihpi/hpioctl.h
deleted file mode 100644
index 2614aff6..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpioctl.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*******************************************************************************
-
- AudioScience HPI driver
- Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Linux HPI ioctl, and shared module init functions
-*******************************************************************************/
-
-int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id);
-void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev);
-void __init asihpi_init(void);
-void __exit asihpi_exit(void);
-
-int asihpi_hpi_release(struct file *file);
-
-long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
-
-/* This is called from hpifunc.c functions, called by ALSA
- * (or other kernel process) In this case there is no file descriptor
- * available for the message cache code
- */
-void hpi_send_recv(struct hpi_message *phm, struct hpi_response *phr);
-
-#define HOWNER_KERNEL ((void *)-1)
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpios.c b/ANDROID_3.4.5/sound/pci/asihpi/hpios.c
deleted file mode 100644
index 5ef4fe96..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpios.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/******************************************************************************
-
- AudioScience HPI driver
- Copyright (C) 1997-2012 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-HPI Operating System function implementation for Linux
-
-(C) Copyright AudioScience Inc. 1997-2003
-******************************************************************************/
-#define SOURCEFILE_NAME "hpios.c"
-#include "hpi_internal.h"
-#include "hpidebug.h"
-#include <linux/delay.h>
-#include <linux/sched.h>
-
-void hpios_delay_micro_seconds(u32 num_micro_sec)
-{
- if ((usecs_to_jiffies(num_micro_sec) > 1) && !in_interrupt()) {
- /* MUST NOT SCHEDULE IN INTERRUPT CONTEXT! */
- schedule_timeout_uninterruptible(usecs_to_jiffies
- (num_micro_sec));
- } else if (num_micro_sec <= 2000)
- udelay(num_micro_sec);
- else
- mdelay(num_micro_sec / 1000);
-
-}
-
-/** Allocate an area of locked memory for bus master DMA operations.
-
-If allocation fails, return 1, and *pMemArea.size = 0
-*/
-u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size,
- struct pci_dev *pdev)
-{
- /*?? any benefit in using managed dmam_alloc_coherent? */
- p_mem_area->vaddr =
- dma_alloc_coherent(&pdev->dev, size, &p_mem_area->dma_handle,
- GFP_DMA32 | GFP_KERNEL);
-
- if (p_mem_area->vaddr) {
- HPI_DEBUG_LOG(DEBUG, "allocated %d bytes, dma 0x%x vma %p\n",
- size, (unsigned int)p_mem_area->dma_handle,
- p_mem_area->vaddr);
- p_mem_area->pdev = &pdev->dev;
- p_mem_area->size = size;
- return 0;
- } else {
- HPI_DEBUG_LOG(WARNING,
- "failed to allocate %d bytes locked memory\n", size);
- p_mem_area->size = 0;
- return 1;
- }
-}
-
-u16 hpios_locked_mem_free(struct consistent_dma_area *p_mem_area)
-{
- if (p_mem_area->size) {
- dma_free_coherent(p_mem_area->pdev, p_mem_area->size,
- p_mem_area->vaddr, p_mem_area->dma_handle);
- HPI_DEBUG_LOG(DEBUG, "freed %lu bytes, dma 0x%x vma %p\n",
- (unsigned long)p_mem_area->size,
- (unsigned int)p_mem_area->dma_handle,
- p_mem_area->vaddr);
- p_mem_area->size = 0;
- return 0;
- } else {
- return 1;
- }
-}
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpios.h b/ANDROID_3.4.5/sound/pci/asihpi/hpios.h
deleted file mode 100644
index d3fbd0d7..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpios.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/******************************************************************************
-
- AudioScience HPI driver
- Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-HPI Operating System Specific macros for Linux Kernel driver
-
-(C) Copyright AudioScience Inc. 1997-2003
-******************************************************************************/
-#ifndef _HPIOS_H_
-#define _HPIOS_H_
-
-#undef HPI_OS_LINUX_KERNEL
-#define HPI_OS_LINUX_KERNEL
-
-#define HPI_OS_DEFINED
-#define HPI_BUILD_KERNEL_MODE
-
-#include <linux/io.h>
-#include <linux/ioctl.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/mutex.h>
-
-#define HPI_NO_OS_FILE_OPS
-
-#ifdef CONFIG_64BIT
-#define HPI64BIT
-#endif
-
-/** Details of a memory area allocated with pci_alloc_consistent
-Need all info for parameters to pci_free_consistent
-*/
-struct consistent_dma_area {
- struct device *pdev;
- /* looks like dma-mapping dma_devres ?! */
- size_t size;
- void *vaddr;
- dma_addr_t dma_handle;
-};
-
-static inline u16 hpios_locked_mem_get_phys_addr(struct consistent_dma_area
- *locked_mem_handle, u32 *p_physical_addr)
-{
- *p_physical_addr = locked_mem_handle->dma_handle;
- return 0;
-}
-
-static inline u16 hpios_locked_mem_get_virt_addr(struct consistent_dma_area
- *locked_mem_handle, void **pp_virtual_addr)
-{
- *pp_virtual_addr = locked_mem_handle->vaddr;
- return 0;
-}
-
-static inline u16 hpios_locked_mem_valid(struct consistent_dma_area
- *locked_mem_handle)
-{
- return locked_mem_handle->size != 0;
-}
-
-struct hpi_ioctl_linux {
- void __user *phm;
- void __user *phr;
-};
-
-/* Conflict?: H is already used by a number of drivers hid, bluetooth hci,
- and some sound drivers sb16, hdsp, emu10k. AFAIK 0xFC is ununsed command
-*/
-#define HPI_IOCTL_LINUX _IOWR('H', 0xFC, struct hpi_ioctl_linux)
-
-#define HPI_DEBUG_FLAG_ERROR KERN_ERR
-#define HPI_DEBUG_FLAG_WARNING KERN_WARNING
-#define HPI_DEBUG_FLAG_NOTICE KERN_NOTICE
-#define HPI_DEBUG_FLAG_INFO KERN_INFO
-#define HPI_DEBUG_FLAG_DEBUG KERN_DEBUG
-#define HPI_DEBUG_FLAG_VERBOSE KERN_DEBUG /* kernel has no verbose */
-
-#include <linux/spinlock.h>
-
-#define HPI_LOCKING
-
-struct hpios_spinlock {
- spinlock_t lock; /* SEE hpios_spinlock */
- int lock_context;
-};
-
-/* The reason for all this evilness is that ALSA calls some of a drivers
- * operators in atomic context, and some not. But all our functions channel
- * through the HPI_Message conduit, so we can't handle the different context
- * per function
- */
-#define IN_LOCK_BH 1
-#define IN_LOCK_IRQ 0
-static inline void cond_lock(struct hpios_spinlock *l)
-{
- if (irqs_disabled()) {
- /* NO bh or isr can execute on this processor,
- so ordinary lock will do
- */
- spin_lock(&((l)->lock));
- l->lock_context = IN_LOCK_IRQ;
- } else {
- spin_lock_bh(&((l)->lock));
- l->lock_context = IN_LOCK_BH;
- }
-}
-
-static inline void cond_unlock(struct hpios_spinlock *l)
-{
- if (l->lock_context == IN_LOCK_BH)
- spin_unlock_bh(&((l)->lock));
- else
- spin_unlock(&((l)->lock));
-}
-
-#define hpios_msgxlock_init(obj) spin_lock_init(&(obj)->lock)
-#define hpios_msgxlock_lock(obj) cond_lock(obj)
-#define hpios_msgxlock_unlock(obj) cond_unlock(obj)
-
-#define hpios_dsplock_init(obj) spin_lock_init(&(obj)->dsp_lock.lock)
-#define hpios_dsplock_lock(obj) cond_lock(&(obj)->dsp_lock)
-#define hpios_dsplock_unlock(obj) cond_unlock(&(obj)->dsp_lock)
-
-#ifdef CONFIG_SND_DEBUG
-#define HPI_BUILD_DEBUG
-#endif
-
-#define HPI_ALIST_LOCKING
-#define hpios_alistlock_init(obj) spin_lock_init(&((obj)->list_lock.lock))
-#define hpios_alistlock_lock(obj) spin_lock(&((obj)->list_lock.lock))
-#define hpios_alistlock_unlock(obj) spin_unlock(&((obj)->list_lock.lock))
-
-struct snd_card;
-
-/** pci drvdata points to an instance of this struct */
-struct hpi_adapter {
- struct hpi_adapter_obj *adapter;
- struct snd_card *snd_card;
-
- /* mutex prevents contention for one card
- between multiple user programs (via ioctl) */
- struct mutex mutex;
- char *p_buffer;
- size_t buffer_size;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/asihpi/hpipcida.h b/ANDROID_3.4.5/sound/pci/asihpi/hpipcida.h
deleted file mode 100644
index db570ddf..00000000
--- a/ANDROID_3.4.5/sound/pci/asihpi/hpipcida.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/******************************************************************************
-
- AudioScience HPI driver
- Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation;
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- Array initializer for PCI card IDs
-
-(C) Copyright AudioScience Inc. 1998-2003
-*******************************************************************************/
-
-/*NOTE: when adding new lines to this header file
- they MUST be grouped by HPI entry point.
-*/
-
-{
-HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_DSP6205,
- HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
- (kernel_ulong_t) HPI_6205}
-, {
-HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_PCI2040,
- HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
- (kernel_ulong_t) HPI_6000}
-, {
-0}
diff --git a/ANDROID_3.4.5/sound/pci/atiixp.c b/ANDROID_3.4.5/sound/pci/atiixp.c
deleted file mode 100644
index 590682f1..00000000
--- a/ANDROID_3.4.5/sound/pci/atiixp.c
+++ /dev/null
@@ -1,1726 +0,0 @@
-/*
- * ALSA driver for ATI IXP 150/200/250/300 AC97 controllers
- *
- * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/info.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("ATI IXP AC97 controller");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250/300/400/600}}");
-
-static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
-static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-static int ac97_clock = 48000;
-static char *ac97_quirk;
-static bool spdif_aclink = 1;
-static int ac97_codec = -1;
-
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for ATI IXP controller.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for ATI IXP controller.");
-module_param(ac97_clock, int, 0444);
-MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
-module_param(ac97_quirk, charp, 0444);
-MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
-module_param(ac97_codec, int, 0444);
-MODULE_PARM_DESC(ac97_codec, "Specify codec instead of probing.");
-module_param(spdif_aclink, bool, 0444);
-MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link.");
-
-/* just for backward compatibility */
-static bool enable;
-module_param(enable, bool, 0444);
-
-
-/*
- */
-
-#define ATI_REG_ISR 0x00 /* interrupt source */
-#define ATI_REG_ISR_IN_XRUN (1U<<0)
-#define ATI_REG_ISR_IN_STATUS (1U<<1)
-#define ATI_REG_ISR_OUT_XRUN (1U<<2)
-#define ATI_REG_ISR_OUT_STATUS (1U<<3)
-#define ATI_REG_ISR_SPDF_XRUN (1U<<4)
-#define ATI_REG_ISR_SPDF_STATUS (1U<<5)
-#define ATI_REG_ISR_PHYS_INTR (1U<<8)
-#define ATI_REG_ISR_PHYS_MISMATCH (1U<<9)
-#define ATI_REG_ISR_CODEC0_NOT_READY (1U<<10)
-#define ATI_REG_ISR_CODEC1_NOT_READY (1U<<11)
-#define ATI_REG_ISR_CODEC2_NOT_READY (1U<<12)
-#define ATI_REG_ISR_NEW_FRAME (1U<<13)
-
-#define ATI_REG_IER 0x04 /* interrupt enable */
-#define ATI_REG_IER_IN_XRUN_EN (1U<<0)
-#define ATI_REG_IER_IO_STATUS_EN (1U<<1)
-#define ATI_REG_IER_OUT_XRUN_EN (1U<<2)
-#define ATI_REG_IER_OUT_XRUN_COND (1U<<3)
-#define ATI_REG_IER_SPDF_XRUN_EN (1U<<4)
-#define ATI_REG_IER_SPDF_STATUS_EN (1U<<5)
-#define ATI_REG_IER_PHYS_INTR_EN (1U<<8)
-#define ATI_REG_IER_PHYS_MISMATCH_EN (1U<<9)
-#define ATI_REG_IER_CODEC0_INTR_EN (1U<<10)
-#define ATI_REG_IER_CODEC1_INTR_EN (1U<<11)
-#define ATI_REG_IER_CODEC2_INTR_EN (1U<<12)
-#define ATI_REG_IER_NEW_FRAME_EN (1U<<13) /* (RO */
-#define ATI_REG_IER_SET_BUS_BUSY (1U<<14) /* (WO) audio is running */
-
-#define ATI_REG_CMD 0x08 /* command */
-#define ATI_REG_CMD_POWERDOWN (1U<<0)
-#define ATI_REG_CMD_RECEIVE_EN (1U<<1)
-#define ATI_REG_CMD_SEND_EN (1U<<2)
-#define ATI_REG_CMD_STATUS_MEM (1U<<3)
-#define ATI_REG_CMD_SPDF_OUT_EN (1U<<4)
-#define ATI_REG_CMD_SPDF_STATUS_MEM (1U<<5)
-#define ATI_REG_CMD_SPDF_THRESHOLD (3U<<6)
-#define ATI_REG_CMD_SPDF_THRESHOLD_SHIFT 6
-#define ATI_REG_CMD_IN_DMA_EN (1U<<8)
-#define ATI_REG_CMD_OUT_DMA_EN (1U<<9)
-#define ATI_REG_CMD_SPDF_DMA_EN (1U<<10)
-#define ATI_REG_CMD_SPDF_OUT_STOPPED (1U<<11)
-#define ATI_REG_CMD_SPDF_CONFIG_MASK (7U<<12)
-#define ATI_REG_CMD_SPDF_CONFIG_34 (1U<<12)
-#define ATI_REG_CMD_SPDF_CONFIG_78 (2U<<12)
-#define ATI_REG_CMD_SPDF_CONFIG_69 (3U<<12)
-#define ATI_REG_CMD_SPDF_CONFIG_01 (4U<<12)
-#define ATI_REG_CMD_INTERLEAVE_SPDF (1U<<16)
-#define ATI_REG_CMD_AUDIO_PRESENT (1U<<20)
-#define ATI_REG_CMD_INTERLEAVE_IN (1U<<21)
-#define ATI_REG_CMD_INTERLEAVE_OUT (1U<<22)
-#define ATI_REG_CMD_LOOPBACK_EN (1U<<23)
-#define ATI_REG_CMD_PACKED_DIS (1U<<24)
-#define ATI_REG_CMD_BURST_EN (1U<<25)
-#define ATI_REG_CMD_PANIC_EN (1U<<26)
-#define ATI_REG_CMD_MODEM_PRESENT (1U<<27)
-#define ATI_REG_CMD_ACLINK_ACTIVE (1U<<28)
-#define ATI_REG_CMD_AC_SOFT_RESET (1U<<29)
-#define ATI_REG_CMD_AC_SYNC (1U<<30)
-#define ATI_REG_CMD_AC_RESET (1U<<31)
-
-#define ATI_REG_PHYS_OUT_ADDR 0x0c
-#define ATI_REG_PHYS_OUT_CODEC_MASK (3U<<0)
-#define ATI_REG_PHYS_OUT_RW (1U<<2)
-#define ATI_REG_PHYS_OUT_ADDR_EN (1U<<8)
-#define ATI_REG_PHYS_OUT_ADDR_SHIFT 9
-#define ATI_REG_PHYS_OUT_DATA_SHIFT 16
-
-#define ATI_REG_PHYS_IN_ADDR 0x10
-#define ATI_REG_PHYS_IN_READ_FLAG (1U<<8)
-#define ATI_REG_PHYS_IN_ADDR_SHIFT 9
-#define ATI_REG_PHYS_IN_DATA_SHIFT 16
-
-#define ATI_REG_SLOTREQ 0x14
-
-#define ATI_REG_COUNTER 0x18
-#define ATI_REG_COUNTER_SLOT (3U<<0) /* slot # */
-#define ATI_REG_COUNTER_BITCLOCK (31U<<8)
-
-#define ATI_REG_IN_FIFO_THRESHOLD 0x1c
-
-#define ATI_REG_IN_DMA_LINKPTR 0x20
-#define ATI_REG_IN_DMA_DT_START 0x24 /* RO */
-#define ATI_REG_IN_DMA_DT_NEXT 0x28 /* RO */
-#define ATI_REG_IN_DMA_DT_CUR 0x2c /* RO */
-#define ATI_REG_IN_DMA_DT_SIZE 0x30
-
-#define ATI_REG_OUT_DMA_SLOT 0x34
-#define ATI_REG_OUT_DMA_SLOT_BIT(x) (1U << ((x) - 3))
-#define ATI_REG_OUT_DMA_SLOT_MASK 0x1ff
-#define ATI_REG_OUT_DMA_THRESHOLD_MASK 0xf800
-#define ATI_REG_OUT_DMA_THRESHOLD_SHIFT 11
-
-#define ATI_REG_OUT_DMA_LINKPTR 0x38
-#define ATI_REG_OUT_DMA_DT_START 0x3c /* RO */
-#define ATI_REG_OUT_DMA_DT_NEXT 0x40 /* RO */
-#define ATI_REG_OUT_DMA_DT_CUR 0x44 /* RO */
-#define ATI_REG_OUT_DMA_DT_SIZE 0x48
-
-#define ATI_REG_SPDF_CMD 0x4c
-#define ATI_REG_SPDF_CMD_LFSR (1U<<4)
-#define ATI_REG_SPDF_CMD_SINGLE_CH (1U<<5)
-#define ATI_REG_SPDF_CMD_LFSR_ACC (0xff<<8) /* RO */
-
-#define ATI_REG_SPDF_DMA_LINKPTR 0x50
-#define ATI_REG_SPDF_DMA_DT_START 0x54 /* RO */
-#define ATI_REG_SPDF_DMA_DT_NEXT 0x58 /* RO */
-#define ATI_REG_SPDF_DMA_DT_CUR 0x5c /* RO */
-#define ATI_REG_SPDF_DMA_DT_SIZE 0x60
-
-#define ATI_REG_MODEM_MIRROR 0x7c
-#define ATI_REG_AUDIO_MIRROR 0x80
-
-#define ATI_REG_6CH_REORDER 0x84 /* reorder slots for 6ch */
-#define ATI_REG_6CH_REORDER_EN (1U<<0) /* 3,4,7,8,6,9 -> 3,4,6,9,7,8 */
-
-#define ATI_REG_FIFO_FLUSH 0x88
-#define ATI_REG_FIFO_OUT_FLUSH (1U<<0)
-#define ATI_REG_FIFO_IN_FLUSH (1U<<1)
-
-/* LINKPTR */
-#define ATI_REG_LINKPTR_EN (1U<<0)
-
-/* [INT|OUT|SPDIF]_DMA_DT_SIZE */
-#define ATI_REG_DMA_DT_SIZE (0xffffU<<0)
-#define ATI_REG_DMA_FIFO_USED (0x1fU<<16)
-#define ATI_REG_DMA_FIFO_FREE (0x1fU<<21)
-#define ATI_REG_DMA_STATE (7U<<26)
-
-
-#define ATI_MAX_DESCRIPTORS 256 /* max number of descriptor packets */
-
-
-struct atiixp;
-
-/*
- * DMA packate descriptor
- */
-
-struct atiixp_dma_desc {
- u32 addr; /* DMA buffer address */
- u16 status; /* status bits */
- u16 size; /* size of the packet in dwords */
- u32 next; /* address of the next packet descriptor */
-};
-
-/*
- * stream enum
- */
-enum { ATI_DMA_PLAYBACK, ATI_DMA_CAPTURE, ATI_DMA_SPDIF, NUM_ATI_DMAS }; /* DMAs */
-enum { ATI_PCM_OUT, ATI_PCM_IN, ATI_PCM_SPDIF, NUM_ATI_PCMS }; /* AC97 pcm slots */
-enum { ATI_PCMDEV_ANALOG, ATI_PCMDEV_DIGITAL, NUM_ATI_PCMDEVS }; /* pcm devices */
-
-#define NUM_ATI_CODECS 3
-
-
-/*
- * constants and callbacks for each DMA type
- */
-struct atiixp_dma_ops {
- int type; /* ATI_DMA_XXX */
- unsigned int llp_offset; /* LINKPTR offset */
- unsigned int dt_cur; /* DT_CUR offset */
- /* called from open callback */
- void (*enable_dma)(struct atiixp *chip, int on);
- /* called from trigger (START/STOP) */
- void (*enable_transfer)(struct atiixp *chip, int on);
- /* called from trigger (STOP only) */
- void (*flush_dma)(struct atiixp *chip);
-};
-
-/*
- * DMA stream
- */
-struct atiixp_dma {
- const struct atiixp_dma_ops *ops;
- struct snd_dma_buffer desc_buf;
- struct snd_pcm_substream *substream; /* assigned PCM substream */
- unsigned int buf_addr, buf_bytes; /* DMA buffer address, bytes */
- unsigned int period_bytes, periods;
- int opened;
- int running;
- int suspended;
- int pcm_open_flag;
- int ac97_pcm_type; /* index # of ac97_pcm to access, -1 = not used */
- unsigned int saved_curptr;
-};
-
-/*
- * ATI IXP chip
- */
-struct atiixp {
- struct snd_card *card;
- struct pci_dev *pci;
-
- unsigned long addr;
- void __iomem *remap_addr;
- int irq;
-
- struct snd_ac97_bus *ac97_bus;
- struct snd_ac97 *ac97[NUM_ATI_CODECS];
-
- spinlock_t reg_lock;
-
- struct atiixp_dma dmas[NUM_ATI_DMAS];
- struct ac97_pcm *pcms[NUM_ATI_PCMS];
- struct snd_pcm *pcmdevs[NUM_ATI_PCMDEVS];
-
- int max_channels; /* max. channels for PCM out */
-
- unsigned int codec_not_ready_bits; /* for codec detection */
-
- int spdif_over_aclink; /* passed from the module option */
- struct mutex open_mutex; /* playback open mutex */
-};
-
-
-/*
- */
-static DEFINE_PCI_DEVICE_TABLE(snd_atiixp_ids) = {
- { PCI_VDEVICE(ATI, 0x4341), 0 }, /* SB200 */
- { PCI_VDEVICE(ATI, 0x4361), 0 }, /* SB300 */
- { PCI_VDEVICE(ATI, 0x4370), 0 }, /* SB400 */
- { PCI_VDEVICE(ATI, 0x4382), 0 }, /* SB600 */
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_atiixp_ids);
-
-static struct snd_pci_quirk atiixp_quirks[] __devinitdata = {
- SND_PCI_QUIRK(0x105b, 0x0c81, "Foxconn RC4107MA-RS2", 0),
- SND_PCI_QUIRK(0x15bd, 0x3100, "DFI RS482", 0),
- { } /* terminator */
-};
-
-/*
- * lowlevel functions
- */
-
-/*
- * update the bits of the given register.
- * return 1 if the bits changed.
- */
-static int snd_atiixp_update_bits(struct atiixp *chip, unsigned int reg,
- unsigned int mask, unsigned int value)
-{
- void __iomem *addr = chip->remap_addr + reg;
- unsigned int data, old_data;
- old_data = data = readl(addr);
- data &= ~mask;
- data |= value;
- if (old_data == data)
- return 0;
- writel(data, addr);
- return 1;
-}
-
-/*
- * macros for easy use
- */
-#define atiixp_write(chip,reg,value) \
- writel(value, chip->remap_addr + ATI_REG_##reg)
-#define atiixp_read(chip,reg) \
- readl(chip->remap_addr + ATI_REG_##reg)
-#define atiixp_update(chip,reg,mask,val) \
- snd_atiixp_update_bits(chip, ATI_REG_##reg, mask, val)
-
-/*
- * handling DMA packets
- *
- * we allocate a linear buffer for the DMA, and split it to each packet.
- * in a future version, a scatter-gather buffer should be implemented.
- */
-
-#define ATI_DESC_LIST_SIZE \
- PAGE_ALIGN(ATI_MAX_DESCRIPTORS * sizeof(struct atiixp_dma_desc))
-
-/*
- * build packets ring for the given buffer size.
- *
- * IXP handles the buffer descriptors, which are connected as a linked
- * list. although we can change the list dynamically, in this version,
- * a static RING of buffer descriptors is used.
- *
- * the ring is built in this function, and is set up to the hardware.
- */
-static int atiixp_build_dma_packets(struct atiixp *chip, struct atiixp_dma *dma,
- struct snd_pcm_substream *substream,
- unsigned int periods,
- unsigned int period_bytes)
-{
- unsigned int i;
- u32 addr, desc_addr;
- unsigned long flags;
-
- if (periods > ATI_MAX_DESCRIPTORS)
- return -ENOMEM;
-
- if (dma->desc_buf.area == NULL) {
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- ATI_DESC_LIST_SIZE,
- &dma->desc_buf) < 0)
- return -ENOMEM;
- dma->period_bytes = dma->periods = 0; /* clear */
- }
-
- if (dma->periods == periods && dma->period_bytes == period_bytes)
- return 0;
-
- /* reset DMA before changing the descriptor table */
- spin_lock_irqsave(&chip->reg_lock, flags);
- writel(0, chip->remap_addr + dma->ops->llp_offset);
- dma->ops->enable_dma(chip, 0);
- dma->ops->enable_dma(chip, 1);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- /* fill the entries */
- addr = (u32)substream->runtime->dma_addr;
- desc_addr = (u32)dma->desc_buf.addr;
- for (i = 0; i < periods; i++) {
- struct atiixp_dma_desc *desc;
- desc = &((struct atiixp_dma_desc *)dma->desc_buf.area)[i];
- desc->addr = cpu_to_le32(addr);
- desc->status = 0;
- desc->size = period_bytes >> 2; /* in dwords */
- desc_addr += sizeof(struct atiixp_dma_desc);
- if (i == periods - 1)
- desc->next = cpu_to_le32((u32)dma->desc_buf.addr);
- else
- desc->next = cpu_to_le32(desc_addr);
- addr += period_bytes;
- }
-
- writel((u32)dma->desc_buf.addr | ATI_REG_LINKPTR_EN,
- chip->remap_addr + dma->ops->llp_offset);
-
- dma->period_bytes = period_bytes;
- dma->periods = periods;
-
- return 0;
-}
-
-/*
- * remove the ring buffer and release it if assigned
- */
-static void atiixp_clear_dma_packets(struct atiixp *chip, struct atiixp_dma *dma,
- struct snd_pcm_substream *substream)
-{
- if (dma->desc_buf.area) {
- writel(0, chip->remap_addr + dma->ops->llp_offset);
- snd_dma_free_pages(&dma->desc_buf);
- dma->desc_buf.area = NULL;
- }
-}
-
-/*
- * AC97 interface
- */
-static int snd_atiixp_acquire_codec(struct atiixp *chip)
-{
- int timeout = 1000;
-
- while (atiixp_read(chip, PHYS_OUT_ADDR) & ATI_REG_PHYS_OUT_ADDR_EN) {
- if (! timeout--) {
- snd_printk(KERN_WARNING "atiixp: codec acquire timeout\n");
- return -EBUSY;
- }
- udelay(1);
- }
- return 0;
-}
-
-static unsigned short snd_atiixp_codec_read(struct atiixp *chip, unsigned short codec, unsigned short reg)
-{
- unsigned int data;
- int timeout;
-
- if (snd_atiixp_acquire_codec(chip) < 0)
- return 0xffff;
- data = (reg << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
- ATI_REG_PHYS_OUT_ADDR_EN |
- ATI_REG_PHYS_OUT_RW |
- codec;
- atiixp_write(chip, PHYS_OUT_ADDR, data);
- if (snd_atiixp_acquire_codec(chip) < 0)
- return 0xffff;
- timeout = 1000;
- do {
- data = atiixp_read(chip, PHYS_IN_ADDR);
- if (data & ATI_REG_PHYS_IN_READ_FLAG)
- return data >> ATI_REG_PHYS_IN_DATA_SHIFT;
- udelay(1);
- } while (--timeout);
- /* time out may happen during reset */
- if (reg < 0x7c)
- snd_printk(KERN_WARNING "atiixp: codec read timeout (reg %x)\n", reg);
- return 0xffff;
-}
-
-
-static void snd_atiixp_codec_write(struct atiixp *chip, unsigned short codec,
- unsigned short reg, unsigned short val)
-{
- unsigned int data;
-
- if (snd_atiixp_acquire_codec(chip) < 0)
- return;
- data = ((unsigned int)val << ATI_REG_PHYS_OUT_DATA_SHIFT) |
- ((unsigned int)reg << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
- ATI_REG_PHYS_OUT_ADDR_EN | codec;
- atiixp_write(chip, PHYS_OUT_ADDR, data);
-}
-
-
-static unsigned short snd_atiixp_ac97_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- struct atiixp *chip = ac97->private_data;
- return snd_atiixp_codec_read(chip, ac97->num, reg);
-
-}
-
-static void snd_atiixp_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short val)
-{
- struct atiixp *chip = ac97->private_data;
- snd_atiixp_codec_write(chip, ac97->num, reg, val);
-}
-
-/*
- * reset AC link
- */
-static int snd_atiixp_aclink_reset(struct atiixp *chip)
-{
- int timeout;
-
- /* reset powerdoewn */
- if (atiixp_update(chip, CMD, ATI_REG_CMD_POWERDOWN, 0))
- udelay(10);
-
- /* perform a software reset */
- atiixp_update(chip, CMD, ATI_REG_CMD_AC_SOFT_RESET, ATI_REG_CMD_AC_SOFT_RESET);
- atiixp_read(chip, CMD);
- udelay(10);
- atiixp_update(chip, CMD, ATI_REG_CMD_AC_SOFT_RESET, 0);
-
- timeout = 10;
- while (! (atiixp_read(chip, CMD) & ATI_REG_CMD_ACLINK_ACTIVE)) {
- /* do a hard reset */
- atiixp_update(chip, CMD, ATI_REG_CMD_AC_SYNC|ATI_REG_CMD_AC_RESET,
- ATI_REG_CMD_AC_SYNC);
- atiixp_read(chip, CMD);
- mdelay(1);
- atiixp_update(chip, CMD, ATI_REG_CMD_AC_RESET, ATI_REG_CMD_AC_RESET);
- if (!--timeout) {
- snd_printk(KERN_ERR "atiixp: codec reset timeout\n");
- break;
- }
- }
-
- /* deassert RESET and assert SYNC to make sure */
- atiixp_update(chip, CMD, ATI_REG_CMD_AC_SYNC|ATI_REG_CMD_AC_RESET,
- ATI_REG_CMD_AC_SYNC|ATI_REG_CMD_AC_RESET);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int snd_atiixp_aclink_down(struct atiixp *chip)
-{
- // if (atiixp_read(chip, MODEM_MIRROR) & 0x1) /* modem running, too? */
- // return -EBUSY;
- atiixp_update(chip, CMD,
- ATI_REG_CMD_POWERDOWN | ATI_REG_CMD_AC_RESET,
- ATI_REG_CMD_POWERDOWN);
- return 0;
-}
-#endif
-
-/*
- * auto-detection of codecs
- *
- * the IXP chip can generate interrupts for the non-existing codecs.
- * NEW_FRAME interrupt is used to make sure that the interrupt is generated
- * even if all three codecs are connected.
- */
-
-#define ALL_CODEC_NOT_READY \
- (ATI_REG_ISR_CODEC0_NOT_READY |\
- ATI_REG_ISR_CODEC1_NOT_READY |\
- ATI_REG_ISR_CODEC2_NOT_READY)
-#define CODEC_CHECK_BITS (ALL_CODEC_NOT_READY|ATI_REG_ISR_NEW_FRAME)
-
-static int __devinit ac97_probing_bugs(struct pci_dev *pci)
-{
- const struct snd_pci_quirk *q;
-
- q = snd_pci_quirk_lookup(pci, atiixp_quirks);
- if (q) {
- snd_printdd(KERN_INFO "Atiixp quirk for %s. "
- "Forcing codec %d\n", q->name, q->value);
- return q->value;
- }
- /* this hardware doesn't need workarounds. Probe for codec */
- return -1;
-}
-
-static int __devinit snd_atiixp_codec_detect(struct atiixp *chip)
-{
- int timeout;
-
- chip->codec_not_ready_bits = 0;
- if (ac97_codec == -1)
- ac97_codec = ac97_probing_bugs(chip->pci);
- if (ac97_codec >= 0) {
- chip->codec_not_ready_bits |=
- CODEC_CHECK_BITS ^ (1 << (ac97_codec + 10));
- return 0;
- }
-
- atiixp_write(chip, IER, CODEC_CHECK_BITS);
- /* wait for the interrupts */
- timeout = 50;
- while (timeout-- > 0) {
- mdelay(1);
- if (chip->codec_not_ready_bits)
- break;
- }
- atiixp_write(chip, IER, 0); /* disable irqs */
-
- if ((chip->codec_not_ready_bits & ALL_CODEC_NOT_READY) == ALL_CODEC_NOT_READY) {
- snd_printk(KERN_ERR "atiixp: no codec detected!\n");
- return -ENXIO;
- }
- return 0;
-}
-
-
-/*
- * enable DMA and irqs
- */
-static int snd_atiixp_chip_start(struct atiixp *chip)
-{
- unsigned int reg;
-
- /* set up spdif, enable burst mode */
- reg = atiixp_read(chip, CMD);
- reg |= 0x02 << ATI_REG_CMD_SPDF_THRESHOLD_SHIFT;
- reg |= ATI_REG_CMD_BURST_EN;
- atiixp_write(chip, CMD, reg);
-
- reg = atiixp_read(chip, SPDF_CMD);
- reg &= ~(ATI_REG_SPDF_CMD_LFSR|ATI_REG_SPDF_CMD_SINGLE_CH);
- atiixp_write(chip, SPDF_CMD, reg);
-
- /* clear all interrupt source */
- atiixp_write(chip, ISR, 0xffffffff);
- /* enable irqs */
- atiixp_write(chip, IER,
- ATI_REG_IER_IO_STATUS_EN |
- ATI_REG_IER_IN_XRUN_EN |
- ATI_REG_IER_OUT_XRUN_EN |
- ATI_REG_IER_SPDF_XRUN_EN |
- ATI_REG_IER_SPDF_STATUS_EN);
- return 0;
-}
-
-
-/*
- * disable DMA and IRQs
- */
-static int snd_atiixp_chip_stop(struct atiixp *chip)
-{
- /* clear interrupt source */
- atiixp_write(chip, ISR, atiixp_read(chip, ISR));
- /* disable irqs */
- atiixp_write(chip, IER, 0);
- return 0;
-}
-
-
-/*
- * PCM section
- */
-
-/*
- * pointer callback simplly reads XXX_DMA_DT_CUR register as the current
- * position. when SG-buffer is implemented, the offset must be calculated
- * correctly...
- */
-static snd_pcm_uframes_t snd_atiixp_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct atiixp *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct atiixp_dma *dma = runtime->private_data;
- unsigned int curptr;
- int timeout = 1000;
-
- while (timeout--) {
- curptr = readl(chip->remap_addr + dma->ops->dt_cur);
- if (curptr < dma->buf_addr)
- continue;
- curptr -= dma->buf_addr;
- if (curptr >= dma->buf_bytes)
- continue;
- return bytes_to_frames(runtime, curptr);
- }
- snd_printd("atiixp: invalid DMA pointer read 0x%x (buf=%x)\n",
- readl(chip->remap_addr + dma->ops->dt_cur), dma->buf_addr);
- return 0;
-}
-
-/*
- * XRUN detected, and stop the PCM substream
- */
-static void snd_atiixp_xrun_dma(struct atiixp *chip, struct atiixp_dma *dma)
-{
- if (! dma->substream || ! dma->running)
- return;
- snd_printdd("atiixp: XRUN detected (DMA %d)\n", dma->ops->type);
- snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN);
-}
-
-/*
- * the period ack. update the substream.
- */
-static void snd_atiixp_update_dma(struct atiixp *chip, struct atiixp_dma *dma)
-{
- if (! dma->substream || ! dma->running)
- return;
- snd_pcm_period_elapsed(dma->substream);
-}
-
-/* set BUS_BUSY interrupt bit if any DMA is running */
-/* call with spinlock held */
-static void snd_atiixp_check_bus_busy(struct atiixp *chip)
-{
- unsigned int bus_busy;
- if (atiixp_read(chip, CMD) & (ATI_REG_CMD_SEND_EN |
- ATI_REG_CMD_RECEIVE_EN |
- ATI_REG_CMD_SPDF_OUT_EN))
- bus_busy = ATI_REG_IER_SET_BUS_BUSY;
- else
- bus_busy = 0;
- atiixp_update(chip, IER, ATI_REG_IER_SET_BUS_BUSY, bus_busy);
-}
-
-/* common trigger callback
- * calling the lowlevel callbacks in it
- */
-static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct atiixp *chip = snd_pcm_substream_chip(substream);
- struct atiixp_dma *dma = substream->runtime->private_data;
- int err = 0;
-
- if (snd_BUG_ON(!dma->ops->enable_transfer ||
- !dma->ops->flush_dma))
- return -EINVAL;
-
- spin_lock(&chip->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
- dma->ops->enable_transfer(chip, 1);
- dma->running = 1;
- dma->suspended = 0;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- dma->ops->enable_transfer(chip, 0);
- dma->running = 0;
- dma->suspended = cmd == SNDRV_PCM_TRIGGER_SUSPEND;
- break;
- default:
- err = -EINVAL;
- break;
- }
- if (! err) {
- snd_atiixp_check_bus_busy(chip);
- if (cmd == SNDRV_PCM_TRIGGER_STOP) {
- dma->ops->flush_dma(chip);
- snd_atiixp_check_bus_busy(chip);
- }
- }
- spin_unlock(&chip->reg_lock);
- return err;
-}
-
-
-/*
- * lowlevel callbacks for each DMA type
- *
- * every callback is supposed to be called in chip->reg_lock spinlock
- */
-
-/* flush FIFO of analog OUT DMA */
-static void atiixp_out_flush_dma(struct atiixp *chip)
-{
- atiixp_write(chip, FIFO_FLUSH, ATI_REG_FIFO_OUT_FLUSH);
-}
-
-/* enable/disable analog OUT DMA */
-static void atiixp_out_enable_dma(struct atiixp *chip, int on)
-{
- unsigned int data;
- data = atiixp_read(chip, CMD);
- if (on) {
- if (data & ATI_REG_CMD_OUT_DMA_EN)
- return;
- atiixp_out_flush_dma(chip);
- data |= ATI_REG_CMD_OUT_DMA_EN;
- } else
- data &= ~ATI_REG_CMD_OUT_DMA_EN;
- atiixp_write(chip, CMD, data);
-}
-
-/* start/stop transfer over OUT DMA */
-static void atiixp_out_enable_transfer(struct atiixp *chip, int on)
-{
- atiixp_update(chip, CMD, ATI_REG_CMD_SEND_EN,
- on ? ATI_REG_CMD_SEND_EN : 0);
-}
-
-/* enable/disable analog IN DMA */
-static void atiixp_in_enable_dma(struct atiixp *chip, int on)
-{
- atiixp_update(chip, CMD, ATI_REG_CMD_IN_DMA_EN,
- on ? ATI_REG_CMD_IN_DMA_EN : 0);
-}
-
-/* start/stop analog IN DMA */
-static void atiixp_in_enable_transfer(struct atiixp *chip, int on)
-{
- if (on) {
- unsigned int data = atiixp_read(chip, CMD);
- if (! (data & ATI_REG_CMD_RECEIVE_EN)) {
- data |= ATI_REG_CMD_RECEIVE_EN;
-#if 0 /* FIXME: this causes the endless loop */
- /* wait until slot 3/4 are finished */
- while ((atiixp_read(chip, COUNTER) &
- ATI_REG_COUNTER_SLOT) != 5)
- ;
-#endif
- atiixp_write(chip, CMD, data);
- }
- } else
- atiixp_update(chip, CMD, ATI_REG_CMD_RECEIVE_EN, 0);
-}
-
-/* flush FIFO of analog IN DMA */
-static void atiixp_in_flush_dma(struct atiixp *chip)
-{
- atiixp_write(chip, FIFO_FLUSH, ATI_REG_FIFO_IN_FLUSH);
-}
-
-/* enable/disable SPDIF OUT DMA */
-static void atiixp_spdif_enable_dma(struct atiixp *chip, int on)
-{
- atiixp_update(chip, CMD, ATI_REG_CMD_SPDF_DMA_EN,
- on ? ATI_REG_CMD_SPDF_DMA_EN : 0);
-}
-
-/* start/stop SPDIF OUT DMA */
-static void atiixp_spdif_enable_transfer(struct atiixp *chip, int on)
-{
- unsigned int data;
- data = atiixp_read(chip, CMD);
- if (on)
- data |= ATI_REG_CMD_SPDF_OUT_EN;
- else
- data &= ~ATI_REG_CMD_SPDF_OUT_EN;
- atiixp_write(chip, CMD, data);
-}
-
-/* flush FIFO of SPDIF OUT DMA */
-static void atiixp_spdif_flush_dma(struct atiixp *chip)
-{
- int timeout;
-
- /* DMA off, transfer on */
- atiixp_spdif_enable_dma(chip, 0);
- atiixp_spdif_enable_transfer(chip, 1);
-
- timeout = 100;
- do {
- if (! (atiixp_read(chip, SPDF_DMA_DT_SIZE) & ATI_REG_DMA_FIFO_USED))
- break;
- udelay(1);
- } while (timeout-- > 0);
-
- atiixp_spdif_enable_transfer(chip, 0);
-}
-
-/* set up slots and formats for SPDIF OUT */
-static int snd_atiixp_spdif_prepare(struct snd_pcm_substream *substream)
-{
- struct atiixp *chip = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&chip->reg_lock);
- if (chip->spdif_over_aclink) {
- unsigned int data;
- /* enable slots 10/11 */
- atiixp_update(chip, CMD, ATI_REG_CMD_SPDF_CONFIG_MASK,
- ATI_REG_CMD_SPDF_CONFIG_01);
- data = atiixp_read(chip, OUT_DMA_SLOT) & ~ATI_REG_OUT_DMA_SLOT_MASK;
- data |= ATI_REG_OUT_DMA_SLOT_BIT(10) |
- ATI_REG_OUT_DMA_SLOT_BIT(11);
- data |= 0x04 << ATI_REG_OUT_DMA_THRESHOLD_SHIFT;
- atiixp_write(chip, OUT_DMA_SLOT, data);
- atiixp_update(chip, CMD, ATI_REG_CMD_INTERLEAVE_OUT,
- substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE ?
- ATI_REG_CMD_INTERLEAVE_OUT : 0);
- } else {
- atiixp_update(chip, CMD, ATI_REG_CMD_SPDF_CONFIG_MASK, 0);
- atiixp_update(chip, CMD, ATI_REG_CMD_INTERLEAVE_SPDF, 0);
- }
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-/* set up slots and formats for analog OUT */
-static int snd_atiixp_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct atiixp *chip = snd_pcm_substream_chip(substream);
- unsigned int data;
-
- spin_lock_irq(&chip->reg_lock);
- data = atiixp_read(chip, OUT_DMA_SLOT) & ~ATI_REG_OUT_DMA_SLOT_MASK;
- switch (substream->runtime->channels) {
- case 8:
- data |= ATI_REG_OUT_DMA_SLOT_BIT(10) |
- ATI_REG_OUT_DMA_SLOT_BIT(11);
- /* fallthru */
- case 6:
- data |= ATI_REG_OUT_DMA_SLOT_BIT(7) |
- ATI_REG_OUT_DMA_SLOT_BIT(8);
- /* fallthru */
- case 4:
- data |= ATI_REG_OUT_DMA_SLOT_BIT(6) |
- ATI_REG_OUT_DMA_SLOT_BIT(9);
- /* fallthru */
- default:
- data |= ATI_REG_OUT_DMA_SLOT_BIT(3) |
- ATI_REG_OUT_DMA_SLOT_BIT(4);
- break;
- }
-
- /* set output threshold */
- data |= 0x04 << ATI_REG_OUT_DMA_THRESHOLD_SHIFT;
- atiixp_write(chip, OUT_DMA_SLOT, data);
-
- atiixp_update(chip, CMD, ATI_REG_CMD_INTERLEAVE_OUT,
- substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE ?
- ATI_REG_CMD_INTERLEAVE_OUT : 0);
-
- /*
- * enable 6 channel re-ordering bit if needed
- */
- atiixp_update(chip, 6CH_REORDER, ATI_REG_6CH_REORDER_EN,
- substream->runtime->channels >= 6 ? ATI_REG_6CH_REORDER_EN: 0);
-
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-/* set up slots and formats for analog IN */
-static int snd_atiixp_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct atiixp *chip = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&chip->reg_lock);
- atiixp_update(chip, CMD, ATI_REG_CMD_INTERLEAVE_IN,
- substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE ?
- ATI_REG_CMD_INTERLEAVE_IN : 0);
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-/*
- * hw_params - allocate the buffer and set up buffer descriptors
- */
-static int snd_atiixp_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct atiixp *chip = snd_pcm_substream_chip(substream);
- struct atiixp_dma *dma = substream->runtime->private_data;
- int err;
-
- err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
- dma->buf_addr = substream->runtime->dma_addr;
- dma->buf_bytes = params_buffer_bytes(hw_params);
-
- err = atiixp_build_dma_packets(chip, dma, substream,
- params_periods(hw_params),
- params_period_bytes(hw_params));
- if (err < 0)
- return err;
-
- if (dma->ac97_pcm_type >= 0) {
- struct ac97_pcm *pcm = chip->pcms[dma->ac97_pcm_type];
- /* PCM is bound to AC97 codec(s)
- * set up the AC97 codecs
- */
- if (dma->pcm_open_flag) {
- snd_ac97_pcm_close(pcm);
- dma->pcm_open_flag = 0;
- }
- err = snd_ac97_pcm_open(pcm, params_rate(hw_params),
- params_channels(hw_params),
- pcm->r[0].slots);
- if (err >= 0)
- dma->pcm_open_flag = 1;
- }
-
- return err;
-}
-
-static int snd_atiixp_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct atiixp *chip = snd_pcm_substream_chip(substream);
- struct atiixp_dma *dma = substream->runtime->private_data;
-
- if (dma->pcm_open_flag) {
- struct ac97_pcm *pcm = chip->pcms[dma->ac97_pcm_type];
- snd_ac97_pcm_close(pcm);
- dma->pcm_open_flag = 0;
- }
- atiixp_clear_dma_packets(chip, dma, substream);
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-
-/*
- * pcm hardware definition, identical for all DMA types
- */
-static struct snd_pcm_hardware snd_atiixp_pcm_hw =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 256 * 1024,
- .period_bytes_min = 32,
- .period_bytes_max = 128 * 1024,
- .periods_min = 2,
- .periods_max = ATI_MAX_DESCRIPTORS,
-};
-
-static int snd_atiixp_pcm_open(struct snd_pcm_substream *substream,
- struct atiixp_dma *dma, int pcm_type)
-{
- struct atiixp *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma))
- return -EINVAL;
-
- if (dma->opened)
- return -EBUSY;
- dma->substream = substream;
- runtime->hw = snd_atiixp_pcm_hw;
- dma->ac97_pcm_type = pcm_type;
- if (pcm_type >= 0) {
- runtime->hw.rates = chip->pcms[pcm_type]->rates;
- snd_pcm_limit_hw_rates(runtime);
- } else {
- /* direct SPDIF */
- runtime->hw.formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
- }
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
- return err;
- runtime->private_data = dma;
-
- /* enable DMA bits */
- spin_lock_irq(&chip->reg_lock);
- dma->ops->enable_dma(chip, 1);
- spin_unlock_irq(&chip->reg_lock);
- dma->opened = 1;
-
- return 0;
-}
-
-static int snd_atiixp_pcm_close(struct snd_pcm_substream *substream,
- struct atiixp_dma *dma)
-{
- struct atiixp *chip = snd_pcm_substream_chip(substream);
- /* disable DMA bits */
- if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma))
- return -EINVAL;
- spin_lock_irq(&chip->reg_lock);
- dma->ops->enable_dma(chip, 0);
- spin_unlock_irq(&chip->reg_lock);
- dma->substream = NULL;
- dma->opened = 0;
- return 0;
-}
-
-/*
- */
-static int snd_atiixp_playback_open(struct snd_pcm_substream *substream)
-{
- struct atiixp *chip = snd_pcm_substream_chip(substream);
- int err;
-
- mutex_lock(&chip->open_mutex);
- err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 0);
- mutex_unlock(&chip->open_mutex);
- if (err < 0)
- return err;
- substream->runtime->hw.channels_max = chip->max_channels;
- if (chip->max_channels > 2)
- /* channels must be even */
- snd_pcm_hw_constraint_step(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS, 2);
- return 0;
-}
-
-static int snd_atiixp_playback_close(struct snd_pcm_substream *substream)
-{
- struct atiixp *chip = snd_pcm_substream_chip(substream);
- int err;
- mutex_lock(&chip->open_mutex);
- err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]);
- mutex_unlock(&chip->open_mutex);
- return err;
-}
-
-static int snd_atiixp_capture_open(struct snd_pcm_substream *substream)
-{
- struct atiixp *chip = snd_pcm_substream_chip(substream);
- return snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_CAPTURE], 1);
-}
-
-static int snd_atiixp_capture_close(struct snd_pcm_substream *substream)
-{
- struct atiixp *chip = snd_pcm_substream_chip(substream);
- return snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_CAPTURE]);
-}
-
-static int snd_atiixp_spdif_open(struct snd_pcm_substream *substream)
-{
- struct atiixp *chip = snd_pcm_substream_chip(substream);
- int err;
- mutex_lock(&chip->open_mutex);
- if (chip->spdif_over_aclink) /* share DMA_PLAYBACK */
- err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 2);
- else
- err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_SPDIF], -1);
- mutex_unlock(&chip->open_mutex);
- return err;
-}
-
-static int snd_atiixp_spdif_close(struct snd_pcm_substream *substream)
-{
- struct atiixp *chip = snd_pcm_substream_chip(substream);
- int err;
- mutex_lock(&chip->open_mutex);
- if (chip->spdif_over_aclink)
- err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]);
- else
- err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_SPDIF]);
- mutex_unlock(&chip->open_mutex);
- return err;
-}
-
-/* AC97 playback */
-static struct snd_pcm_ops snd_atiixp_playback_ops = {
- .open = snd_atiixp_playback_open,
- .close = snd_atiixp_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_atiixp_pcm_hw_params,
- .hw_free = snd_atiixp_pcm_hw_free,
- .prepare = snd_atiixp_playback_prepare,
- .trigger = snd_atiixp_pcm_trigger,
- .pointer = snd_atiixp_pcm_pointer,
-};
-
-/* AC97 capture */
-static struct snd_pcm_ops snd_atiixp_capture_ops = {
- .open = snd_atiixp_capture_open,
- .close = snd_atiixp_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_atiixp_pcm_hw_params,
- .hw_free = snd_atiixp_pcm_hw_free,
- .prepare = snd_atiixp_capture_prepare,
- .trigger = snd_atiixp_pcm_trigger,
- .pointer = snd_atiixp_pcm_pointer,
-};
-
-/* SPDIF playback */
-static struct snd_pcm_ops snd_atiixp_spdif_ops = {
- .open = snd_atiixp_spdif_open,
- .close = snd_atiixp_spdif_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_atiixp_pcm_hw_params,
- .hw_free = snd_atiixp_pcm_hw_free,
- .prepare = snd_atiixp_spdif_prepare,
- .trigger = snd_atiixp_pcm_trigger,
- .pointer = snd_atiixp_pcm_pointer,
-};
-
-static struct ac97_pcm atiixp_pcm_defs[] __devinitdata = {
- /* front PCM */
- {
- .exclusive = 1,
- .r = { {
- .slots = (1 << AC97_SLOT_PCM_LEFT) |
- (1 << AC97_SLOT_PCM_RIGHT) |
- (1 << AC97_SLOT_PCM_CENTER) |
- (1 << AC97_SLOT_PCM_SLEFT) |
- (1 << AC97_SLOT_PCM_SRIGHT) |
- (1 << AC97_SLOT_LFE)
- }
- }
- },
- /* PCM IN #1 */
- {
- .stream = 1,
- .exclusive = 1,
- .r = { {
- .slots = (1 << AC97_SLOT_PCM_LEFT) |
- (1 << AC97_SLOT_PCM_RIGHT)
- }
- }
- },
- /* S/PDIF OUT (optional) */
- {
- .exclusive = 1,
- .spdif = 1,
- .r = { {
- .slots = (1 << AC97_SLOT_SPDIF_LEFT2) |
- (1 << AC97_SLOT_SPDIF_RIGHT2)
- }
- }
- },
-};
-
-static struct atiixp_dma_ops snd_atiixp_playback_dma_ops = {
- .type = ATI_DMA_PLAYBACK,
- .llp_offset = ATI_REG_OUT_DMA_LINKPTR,
- .dt_cur = ATI_REG_OUT_DMA_DT_CUR,
- .enable_dma = atiixp_out_enable_dma,
- .enable_transfer = atiixp_out_enable_transfer,
- .flush_dma = atiixp_out_flush_dma,
-};
-
-static struct atiixp_dma_ops snd_atiixp_capture_dma_ops = {
- .type = ATI_DMA_CAPTURE,
- .llp_offset = ATI_REG_IN_DMA_LINKPTR,
- .dt_cur = ATI_REG_IN_DMA_DT_CUR,
- .enable_dma = atiixp_in_enable_dma,
- .enable_transfer = atiixp_in_enable_transfer,
- .flush_dma = atiixp_in_flush_dma,
-};
-
-static struct atiixp_dma_ops snd_atiixp_spdif_dma_ops = {
- .type = ATI_DMA_SPDIF,
- .llp_offset = ATI_REG_SPDF_DMA_LINKPTR,
- .dt_cur = ATI_REG_SPDF_DMA_DT_CUR,
- .enable_dma = atiixp_spdif_enable_dma,
- .enable_transfer = atiixp_spdif_enable_transfer,
- .flush_dma = atiixp_spdif_flush_dma,
-};
-
-
-static int __devinit snd_atiixp_pcm_new(struct atiixp *chip)
-{
- struct snd_pcm *pcm;
- struct snd_ac97_bus *pbus = chip->ac97_bus;
- int err, i, num_pcms;
-
- /* initialize constants */
- chip->dmas[ATI_DMA_PLAYBACK].ops = &snd_atiixp_playback_dma_ops;
- chip->dmas[ATI_DMA_CAPTURE].ops = &snd_atiixp_capture_dma_ops;
- if (! chip->spdif_over_aclink)
- chip->dmas[ATI_DMA_SPDIF].ops = &snd_atiixp_spdif_dma_ops;
-
- /* assign AC97 pcm */
- if (chip->spdif_over_aclink)
- num_pcms = 3;
- else
- num_pcms = 2;
- err = snd_ac97_pcm_assign(pbus, num_pcms, atiixp_pcm_defs);
- if (err < 0)
- return err;
- for (i = 0; i < num_pcms; i++)
- chip->pcms[i] = &pbus->pcms[i];
-
- chip->max_channels = 2;
- if (pbus->pcms[ATI_PCM_OUT].r[0].slots & (1 << AC97_SLOT_PCM_SLEFT)) {
- if (pbus->pcms[ATI_PCM_OUT].r[0].slots & (1 << AC97_SLOT_LFE))
- chip->max_channels = 6;
- else
- chip->max_channels = 4;
- }
-
- /* PCM #0: analog I/O */
- err = snd_pcm_new(chip->card, "ATI IXP AC97",
- ATI_PCMDEV_ANALOG, 1, 1, &pcm);
- if (err < 0)
- return err;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_atiixp_capture_ops);
- pcm->private_data = chip;
- strcpy(pcm->name, "ATI IXP AC97");
- chip->pcmdevs[ATI_PCMDEV_ANALOG] = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- 64*1024, 128*1024);
-
- /* no SPDIF support on codec? */
- if (chip->pcms[ATI_PCM_SPDIF] && ! chip->pcms[ATI_PCM_SPDIF]->rates)
- return 0;
-
- /* FIXME: non-48k sample rate doesn't work on my test machine with AD1888 */
- if (chip->pcms[ATI_PCM_SPDIF])
- chip->pcms[ATI_PCM_SPDIF]->rates = SNDRV_PCM_RATE_48000;
-
- /* PCM #1: spdif playback */
- err = snd_pcm_new(chip->card, "ATI IXP IEC958",
- ATI_PCMDEV_DIGITAL, 1, 0, &pcm);
- if (err < 0)
- return err;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_spdif_ops);
- pcm->private_data = chip;
- if (chip->spdif_over_aclink)
- strcpy(pcm->name, "ATI IXP IEC958 (AC97)");
- else
- strcpy(pcm->name, "ATI IXP IEC958 (Direct)");
- chip->pcmdevs[ATI_PCMDEV_DIGITAL] = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- 64*1024, 128*1024);
-
- /* pre-select AC97 SPDIF slots 10/11 */
- for (i = 0; i < NUM_ATI_CODECS; i++) {
- if (chip->ac97[i])
- snd_ac97_update_bits(chip->ac97[i],
- AC97_EXTENDED_STATUS,
- 0x03 << 4, 0x03 << 4);
- }
-
- return 0;
-}
-
-
-
-/*
- * interrupt handler
- */
-static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id)
-{
- struct atiixp *chip = dev_id;
- unsigned int status;
-
- status = atiixp_read(chip, ISR);
-
- if (! status)
- return IRQ_NONE;
-
- /* process audio DMA */
- if (status & ATI_REG_ISR_OUT_XRUN)
- snd_atiixp_xrun_dma(chip, &chip->dmas[ATI_DMA_PLAYBACK]);
- else if (status & ATI_REG_ISR_OUT_STATUS)
- snd_atiixp_update_dma(chip, &chip->dmas[ATI_DMA_PLAYBACK]);
- if (status & ATI_REG_ISR_IN_XRUN)
- snd_atiixp_xrun_dma(chip, &chip->dmas[ATI_DMA_CAPTURE]);
- else if (status & ATI_REG_ISR_IN_STATUS)
- snd_atiixp_update_dma(chip, &chip->dmas[ATI_DMA_CAPTURE]);
- if (! chip->spdif_over_aclink) {
- if (status & ATI_REG_ISR_SPDF_XRUN)
- snd_atiixp_xrun_dma(chip, &chip->dmas[ATI_DMA_SPDIF]);
- else if (status & ATI_REG_ISR_SPDF_STATUS)
- snd_atiixp_update_dma(chip, &chip->dmas[ATI_DMA_SPDIF]);
- }
-
- /* for codec detection */
- if (status & CODEC_CHECK_BITS) {
- unsigned int detected;
- detected = status & CODEC_CHECK_BITS;
- spin_lock(&chip->reg_lock);
- chip->codec_not_ready_bits |= detected;
- atiixp_update(chip, IER, detected, 0); /* disable the detected irqs */
- spin_unlock(&chip->reg_lock);
- }
-
- /* ack */
- atiixp_write(chip, ISR, status);
-
- return IRQ_HANDLED;
-}
-
-
-/*
- * ac97 mixer section
- */
-
-static struct ac97_quirk ac97_quirks[] __devinitdata = {
- {
- .subvendor = 0x103c,
- .subdevice = 0x006b,
- .name = "HP Pavilion ZV5030US",
- .type = AC97_TUNE_MUTE_LED
- },
- {
- .subvendor = 0x103c,
- .subdevice = 0x308b,
- .name = "HP nx6125",
- .type = AC97_TUNE_MUTE_LED
- },
- {
- .subvendor = 0x103c,
- .subdevice = 0x3091,
- .name = "unknown HP",
- .type = AC97_TUNE_MUTE_LED
- },
- { } /* terminator */
-};
-
-static int __devinit snd_atiixp_mixer_new(struct atiixp *chip, int clock,
- const char *quirk_override)
-{
- struct snd_ac97_bus *pbus;
- struct snd_ac97_template ac97;
- int i, err;
- int codec_count;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_atiixp_ac97_write,
- .read = snd_atiixp_ac97_read,
- };
- static unsigned int codec_skip[NUM_ATI_CODECS] = {
- ATI_REG_ISR_CODEC0_NOT_READY,
- ATI_REG_ISR_CODEC1_NOT_READY,
- ATI_REG_ISR_CODEC2_NOT_READY,
- };
-
- if (snd_atiixp_codec_detect(chip) < 0)
- return -ENXIO;
-
- if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
- return err;
- pbus->clock = clock;
- chip->ac97_bus = pbus;
-
- codec_count = 0;
- for (i = 0; i < NUM_ATI_CODECS; i++) {
- if (chip->codec_not_ready_bits & codec_skip[i])
- continue;
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = chip;
- ac97.pci = chip->pci;
- ac97.num = i;
- ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE;
- if (! chip->spdif_over_aclink)
- ac97.scaps |= AC97_SCAP_NO_SPDIF;
- if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
- chip->ac97[i] = NULL; /* to be sure */
- snd_printdd("atiixp: codec %d not available for audio\n", i);
- continue;
- }
- codec_count++;
- }
-
- if (! codec_count) {
- snd_printk(KERN_ERR "atiixp: no codec available\n");
- return -ENODEV;
- }
-
- snd_ac97_tune_hardware(chip->ac97[0], ac97_quirks, quirk_override);
-
- return 0;
-}
-
-
-#ifdef CONFIG_PM
-/*
- * power management
- */
-static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct atiixp *chip = card->private_data;
- int i;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- for (i = 0; i < NUM_ATI_PCMDEVS; i++)
- if (chip->pcmdevs[i]) {
- struct atiixp_dma *dma = &chip->dmas[i];
- if (dma->substream && dma->running)
- dma->saved_curptr = readl(chip->remap_addr +
- dma->ops->dt_cur);
- snd_pcm_suspend_all(chip->pcmdevs[i]);
- }
- for (i = 0; i < NUM_ATI_CODECS; i++)
- snd_ac97_suspend(chip->ac97[i]);
- snd_atiixp_aclink_down(chip);
- snd_atiixp_chip_stop(chip);
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int snd_atiixp_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct atiixp *chip = card->private_data;
- int i;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "atiixp: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
-
- snd_atiixp_aclink_reset(chip);
- snd_atiixp_chip_start(chip);
-
- for (i = 0; i < NUM_ATI_CODECS; i++)
- snd_ac97_resume(chip->ac97[i]);
-
- for (i = 0; i < NUM_ATI_PCMDEVS; i++)
- if (chip->pcmdevs[i]) {
- struct atiixp_dma *dma = &chip->dmas[i];
- if (dma->substream && dma->suspended) {
- dma->ops->enable_dma(chip, 1);
- dma->substream->ops->prepare(dma->substream);
- writel((u32)dma->desc_buf.addr | ATI_REG_LINKPTR_EN,
- chip->remap_addr + dma->ops->llp_offset);
- writel(dma->saved_curptr, chip->remap_addr +
- dma->ops->dt_cur);
- }
- }
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif /* CONFIG_PM */
-
-
-#ifdef CONFIG_PROC_FS
-/*
- * proc interface for register dump
- */
-
-static void snd_atiixp_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct atiixp *chip = entry->private_data;
- int i;
-
- for (i = 0; i < 256; i += 4)
- snd_iprintf(buffer, "%02x: %08x\n", i, readl(chip->remap_addr + i));
-}
-
-static void __devinit snd_atiixp_proc_init(struct atiixp *chip)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(chip->card, "atiixp", &entry))
- snd_info_set_text_ops(entry, chip, snd_atiixp_proc_read);
-}
-#else /* !CONFIG_PROC_FS */
-#define snd_atiixp_proc_init(chip)
-#endif
-
-
-/*
- * destructor
- */
-
-static int snd_atiixp_free(struct atiixp *chip)
-{
- if (chip->irq < 0)
- goto __hw_end;
- snd_atiixp_chip_stop(chip);
-
- __hw_end:
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
- if (chip->remap_addr)
- iounmap(chip->remap_addr);
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
- kfree(chip);
- return 0;
-}
-
-static int snd_atiixp_dev_free(struct snd_device *device)
-{
- struct atiixp *chip = device->device_data;
- return snd_atiixp_free(chip);
-}
-
-/*
- * constructor for chip instance
- */
-static int __devinit snd_atiixp_create(struct snd_card *card,
- struct pci_dev *pci,
- struct atiixp **r_chip)
-{
- static struct snd_device_ops ops = {
- .dev_free = snd_atiixp_dev_free,
- };
- struct atiixp *chip;
- int err;
-
- if ((err = pci_enable_device(pci)) < 0)
- return err;
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- spin_lock_init(&chip->reg_lock);
- mutex_init(&chip->open_mutex);
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
- if ((err = pci_request_regions(pci, "ATI IXP AC97")) < 0) {
- pci_disable_device(pci);
- kfree(chip);
- return err;
- }
- chip->addr = pci_resource_start(pci, 0);
- chip->remap_addr = pci_ioremap_bar(pci, 0);
- if (chip->remap_addr == NULL) {
- snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
- snd_atiixp_free(chip);
- return -EIO;
- }
-
- if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_atiixp_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
- pci_set_master(pci);
- synchronize_irq(chip->irq);
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_atiixp_free(chip);
- return err;
- }
-
- snd_card_set_dev(card, &pci->dev);
-
- *r_chip = chip;
- return 0;
-}
-
-
-static int __devinit snd_atiixp_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- struct snd_card *card;
- struct atiixp *chip;
- int err;
-
- err = snd_card_create(index, id, THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- strcpy(card->driver, spdif_aclink ? "ATIIXP" : "ATIIXP-SPDMA");
- strcpy(card->shortname, "ATI IXP");
- if ((err = snd_atiixp_create(card, pci, &chip)) < 0)
- goto __error;
- card->private_data = chip;
-
- if ((err = snd_atiixp_aclink_reset(chip)) < 0)
- goto __error;
-
- chip->spdif_over_aclink = spdif_aclink;
-
- if ((err = snd_atiixp_mixer_new(chip, ac97_clock, ac97_quirk)) < 0)
- goto __error;
-
- if ((err = snd_atiixp_pcm_new(chip)) < 0)
- goto __error;
-
- snd_atiixp_proc_init(chip);
-
- snd_atiixp_chip_start(chip);
-
- snprintf(card->longname, sizeof(card->longname),
- "%s rev %x with %s at %#lx, irq %i", card->shortname,
- pci->revision,
- chip->ac97[0] ? snd_ac97_get_short_name(chip->ac97[0]) : "?",
- chip->addr, chip->irq);
-
- if ((err = snd_card_register(card)) < 0)
- goto __error;
-
- pci_set_drvdata(pci, card);
- return 0;
-
- __error:
- snd_card_free(card);
- return err;
-}
-
-static void __devexit snd_atiixp_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_atiixp_ids,
- .probe = snd_atiixp_probe,
- .remove = __devexit_p(snd_atiixp_remove),
-#ifdef CONFIG_PM
- .suspend = snd_atiixp_suspend,
- .resume = snd_atiixp_resume,
-#endif
-};
-
-
-static int __init alsa_card_atiixp_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_atiixp_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_atiixp_init)
-module_exit(alsa_card_atiixp_exit)
diff --git a/ANDROID_3.4.5/sound/pci/atiixp_modem.c b/ANDROID_3.4.5/sound/pci/atiixp_modem.c
deleted file mode 100644
index 524d35f3..00000000
--- a/ANDROID_3.4.5/sound/pci/atiixp_modem.c
+++ /dev/null
@@ -1,1357 +0,0 @@
-/*
- * ALSA driver for ATI IXP 150/200/250 AC97 modem controllers
- *
- * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/info.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("ATI IXP MC97 controller");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250}}");
-
-static int index = -2; /* Exclude the first card */
-static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-static int ac97_clock = 48000;
-
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for ATI IXP controller.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for ATI IXP controller.");
-module_param(ac97_clock, int, 0444);
-MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
-
-/* just for backward compatibility */
-static bool enable;
-module_param(enable, bool, 0444);
-
-
-/*
- */
-
-#define ATI_REG_ISR 0x00 /* interrupt source */
-#define ATI_REG_ISR_MODEM_IN_XRUN (1U<<0)
-#define ATI_REG_ISR_MODEM_IN_STATUS (1U<<1)
-#define ATI_REG_ISR_MODEM_OUT1_XRUN (1U<<2)
-#define ATI_REG_ISR_MODEM_OUT1_STATUS (1U<<3)
-#define ATI_REG_ISR_MODEM_OUT2_XRUN (1U<<4)
-#define ATI_REG_ISR_MODEM_OUT2_STATUS (1U<<5)
-#define ATI_REG_ISR_MODEM_OUT3_XRUN (1U<<6)
-#define ATI_REG_ISR_MODEM_OUT3_STATUS (1U<<7)
-#define ATI_REG_ISR_PHYS_INTR (1U<<8)
-#define ATI_REG_ISR_PHYS_MISMATCH (1U<<9)
-#define ATI_REG_ISR_CODEC0_NOT_READY (1U<<10)
-#define ATI_REG_ISR_CODEC1_NOT_READY (1U<<11)
-#define ATI_REG_ISR_CODEC2_NOT_READY (1U<<12)
-#define ATI_REG_ISR_NEW_FRAME (1U<<13)
-#define ATI_REG_ISR_MODEM_GPIO_DATA (1U<<14)
-
-#define ATI_REG_IER 0x04 /* interrupt enable */
-#define ATI_REG_IER_MODEM_IN_XRUN_EN (1U<<0)
-#define ATI_REG_IER_MODEM_STATUS_EN (1U<<1)
-#define ATI_REG_IER_MODEM_OUT1_XRUN_EN (1U<<2)
-#define ATI_REG_IER_MODEM_OUT2_XRUN_EN (1U<<4)
-#define ATI_REG_IER_MODEM_OUT3_XRUN_EN (1U<<6)
-#define ATI_REG_IER_PHYS_INTR_EN (1U<<8)
-#define ATI_REG_IER_PHYS_MISMATCH_EN (1U<<9)
-#define ATI_REG_IER_CODEC0_INTR_EN (1U<<10)
-#define ATI_REG_IER_CODEC1_INTR_EN (1U<<11)
-#define ATI_REG_IER_CODEC2_INTR_EN (1U<<12)
-#define ATI_REG_IER_NEW_FRAME_EN (1U<<13) /* (RO */
-#define ATI_REG_IER_MODEM_GPIO_DATA_EN (1U<<14) /* (WO) modem is running */
-#define ATI_REG_IER_MODEM_SET_BUS_BUSY (1U<<15)
-
-#define ATI_REG_CMD 0x08 /* command */
-#define ATI_REG_CMD_POWERDOWN (1U<<0)
-#define ATI_REG_CMD_MODEM_RECEIVE_EN (1U<<1) /* modem only */
-#define ATI_REG_CMD_MODEM_SEND1_EN (1U<<2) /* modem only */
-#define ATI_REG_CMD_MODEM_SEND2_EN (1U<<3) /* modem only */
-#define ATI_REG_CMD_MODEM_SEND3_EN (1U<<4) /* modem only */
-#define ATI_REG_CMD_MODEM_STATUS_MEM (1U<<5) /* modem only */
-#define ATI_REG_CMD_MODEM_IN_DMA_EN (1U<<8) /* modem only */
-#define ATI_REG_CMD_MODEM_OUT_DMA1_EN (1U<<9) /* modem only */
-#define ATI_REG_CMD_MODEM_OUT_DMA2_EN (1U<<10) /* modem only */
-#define ATI_REG_CMD_MODEM_OUT_DMA3_EN (1U<<11) /* modem only */
-#define ATI_REG_CMD_AUDIO_PRESENT (1U<<20)
-#define ATI_REG_CMD_MODEM_GPIO_THRU_DMA (1U<<22) /* modem only */
-#define ATI_REG_CMD_LOOPBACK_EN (1U<<23)
-#define ATI_REG_CMD_PACKED_DIS (1U<<24)
-#define ATI_REG_CMD_BURST_EN (1U<<25)
-#define ATI_REG_CMD_PANIC_EN (1U<<26)
-#define ATI_REG_CMD_MODEM_PRESENT (1U<<27)
-#define ATI_REG_CMD_ACLINK_ACTIVE (1U<<28)
-#define ATI_REG_CMD_AC_SOFT_RESET (1U<<29)
-#define ATI_REG_CMD_AC_SYNC (1U<<30)
-#define ATI_REG_CMD_AC_RESET (1U<<31)
-
-#define ATI_REG_PHYS_OUT_ADDR 0x0c
-#define ATI_REG_PHYS_OUT_CODEC_MASK (3U<<0)
-#define ATI_REG_PHYS_OUT_RW (1U<<2)
-#define ATI_REG_PHYS_OUT_ADDR_EN (1U<<8)
-#define ATI_REG_PHYS_OUT_ADDR_SHIFT 9
-#define ATI_REG_PHYS_OUT_DATA_SHIFT 16
-
-#define ATI_REG_PHYS_IN_ADDR 0x10
-#define ATI_REG_PHYS_IN_READ_FLAG (1U<<8)
-#define ATI_REG_PHYS_IN_ADDR_SHIFT 9
-#define ATI_REG_PHYS_IN_DATA_SHIFT 16
-
-#define ATI_REG_SLOTREQ 0x14
-
-#define ATI_REG_COUNTER 0x18
-#define ATI_REG_COUNTER_SLOT (3U<<0) /* slot # */
-#define ATI_REG_COUNTER_BITCLOCK (31U<<8)
-
-#define ATI_REG_IN_FIFO_THRESHOLD 0x1c
-
-#define ATI_REG_MODEM_IN_DMA_LINKPTR 0x20
-#define ATI_REG_MODEM_IN_DMA_DT_START 0x24 /* RO */
-#define ATI_REG_MODEM_IN_DMA_DT_NEXT 0x28 /* RO */
-#define ATI_REG_MODEM_IN_DMA_DT_CUR 0x2c /* RO */
-#define ATI_REG_MODEM_IN_DMA_DT_SIZE 0x30
-#define ATI_REG_MODEM_OUT_FIFO 0x34 /* output threshold */
-#define ATI_REG_MODEM_OUT1_DMA_THRESHOLD_MASK (0xf<<16)
-#define ATI_REG_MODEM_OUT1_DMA_THRESHOLD_SHIFT 16
-#define ATI_REG_MODEM_OUT_DMA1_LINKPTR 0x38
-#define ATI_REG_MODEM_OUT_DMA2_LINKPTR 0x3c
-#define ATI_REG_MODEM_OUT_DMA3_LINKPTR 0x40
-#define ATI_REG_MODEM_OUT_DMA1_DT_START 0x44
-#define ATI_REG_MODEM_OUT_DMA1_DT_NEXT 0x48
-#define ATI_REG_MODEM_OUT_DMA1_DT_CUR 0x4c
-#define ATI_REG_MODEM_OUT_DMA2_DT_START 0x50
-#define ATI_REG_MODEM_OUT_DMA2_DT_NEXT 0x54
-#define ATI_REG_MODEM_OUT_DMA2_DT_CUR 0x58
-#define ATI_REG_MODEM_OUT_DMA3_DT_START 0x5c
-#define ATI_REG_MODEM_OUT_DMA3_DT_NEXT 0x60
-#define ATI_REG_MODEM_OUT_DMA3_DT_CUR 0x64
-#define ATI_REG_MODEM_OUT_DMA12_DT_SIZE 0x68
-#define ATI_REG_MODEM_OUT_DMA3_DT_SIZE 0x6c
-#define ATI_REG_MODEM_OUT_FIFO_USED 0x70
-#define ATI_REG_MODEM_OUT_GPIO 0x74
-#define ATI_REG_MODEM_OUT_GPIO_EN 1
-#define ATI_REG_MODEM_OUT_GPIO_DATA_SHIFT 5
-#define ATI_REG_MODEM_IN_GPIO 0x78
-
-#define ATI_REG_MODEM_MIRROR 0x7c
-#define ATI_REG_AUDIO_MIRROR 0x80
-
-#define ATI_REG_MODEM_FIFO_FLUSH 0x88
-#define ATI_REG_MODEM_FIFO_OUT1_FLUSH (1U<<0)
-#define ATI_REG_MODEM_FIFO_OUT2_FLUSH (1U<<1)
-#define ATI_REG_MODEM_FIFO_OUT3_FLUSH (1U<<2)
-#define ATI_REG_MODEM_FIFO_IN_FLUSH (1U<<3)
-
-/* LINKPTR */
-#define ATI_REG_LINKPTR_EN (1U<<0)
-
-#define ATI_MAX_DESCRIPTORS 256 /* max number of descriptor packets */
-
-
-struct atiixp_modem;
-
-/*
- * DMA packate descriptor
- */
-
-struct atiixp_dma_desc {
- u32 addr; /* DMA buffer address */
- u16 status; /* status bits */
- u16 size; /* size of the packet in dwords */
- u32 next; /* address of the next packet descriptor */
-};
-
-/*
- * stream enum
- */
-enum { ATI_DMA_PLAYBACK, ATI_DMA_CAPTURE, NUM_ATI_DMAS }; /* DMAs */
-enum { ATI_PCM_OUT, ATI_PCM_IN, NUM_ATI_PCMS }; /* AC97 pcm slots */
-enum { ATI_PCMDEV_ANALOG, NUM_ATI_PCMDEVS }; /* pcm devices */
-
-#define NUM_ATI_CODECS 3
-
-
-/*
- * constants and callbacks for each DMA type
- */
-struct atiixp_dma_ops {
- int type; /* ATI_DMA_XXX */
- unsigned int llp_offset; /* LINKPTR offset */
- unsigned int dt_cur; /* DT_CUR offset */
- /* called from open callback */
- void (*enable_dma)(struct atiixp_modem *chip, int on);
- /* called from trigger (START/STOP) */
- void (*enable_transfer)(struct atiixp_modem *chip, int on);
- /* called from trigger (STOP only) */
- void (*flush_dma)(struct atiixp_modem *chip);
-};
-
-/*
- * DMA stream
- */
-struct atiixp_dma {
- const struct atiixp_dma_ops *ops;
- struct snd_dma_buffer desc_buf;
- struct snd_pcm_substream *substream; /* assigned PCM substream */
- unsigned int buf_addr, buf_bytes; /* DMA buffer address, bytes */
- unsigned int period_bytes, periods;
- int opened;
- int running;
- int pcm_open_flag;
- int ac97_pcm_type; /* index # of ac97_pcm to access, -1 = not used */
-};
-
-/*
- * ATI IXP chip
- */
-struct atiixp_modem {
- struct snd_card *card;
- struct pci_dev *pci;
-
- struct resource *res; /* memory i/o */
- unsigned long addr;
- void __iomem *remap_addr;
- int irq;
-
- struct snd_ac97_bus *ac97_bus;
- struct snd_ac97 *ac97[NUM_ATI_CODECS];
-
- spinlock_t reg_lock;
-
- struct atiixp_dma dmas[NUM_ATI_DMAS];
- struct ac97_pcm *pcms[NUM_ATI_PCMS];
- struct snd_pcm *pcmdevs[NUM_ATI_PCMDEVS];
-
- int max_channels; /* max. channels for PCM out */
-
- unsigned int codec_not_ready_bits; /* for codec detection */
-
- int spdif_over_aclink; /* passed from the module option */
- struct mutex open_mutex; /* playback open mutex */
-};
-
-
-/*
- */
-static DEFINE_PCI_DEVICE_TABLE(snd_atiixp_ids) = {
- { PCI_VDEVICE(ATI, 0x434d), 0 }, /* SB200 */
- { PCI_VDEVICE(ATI, 0x4378), 0 }, /* SB400 */
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_atiixp_ids);
-
-
-/*
- * lowlevel functions
- */
-
-/*
- * update the bits of the given register.
- * return 1 if the bits changed.
- */
-static int snd_atiixp_update_bits(struct atiixp_modem *chip, unsigned int reg,
- unsigned int mask, unsigned int value)
-{
- void __iomem *addr = chip->remap_addr + reg;
- unsigned int data, old_data;
- old_data = data = readl(addr);
- data &= ~mask;
- data |= value;
- if (old_data == data)
- return 0;
- writel(data, addr);
- return 1;
-}
-
-/*
- * macros for easy use
- */
-#define atiixp_write(chip,reg,value) \
- writel(value, chip->remap_addr + ATI_REG_##reg)
-#define atiixp_read(chip,reg) \
- readl(chip->remap_addr + ATI_REG_##reg)
-#define atiixp_update(chip,reg,mask,val) \
- snd_atiixp_update_bits(chip, ATI_REG_##reg, mask, val)
-
-/*
- * handling DMA packets
- *
- * we allocate a linear buffer for the DMA, and split it to each packet.
- * in a future version, a scatter-gather buffer should be implemented.
- */
-
-#define ATI_DESC_LIST_SIZE \
- PAGE_ALIGN(ATI_MAX_DESCRIPTORS * sizeof(struct atiixp_dma_desc))
-
-/*
- * build packets ring for the given buffer size.
- *
- * IXP handles the buffer descriptors, which are connected as a linked
- * list. although we can change the list dynamically, in this version,
- * a static RING of buffer descriptors is used.
- *
- * the ring is built in this function, and is set up to the hardware.
- */
-static int atiixp_build_dma_packets(struct atiixp_modem *chip,
- struct atiixp_dma *dma,
- struct snd_pcm_substream *substream,
- unsigned int periods,
- unsigned int period_bytes)
-{
- unsigned int i;
- u32 addr, desc_addr;
- unsigned long flags;
-
- if (periods > ATI_MAX_DESCRIPTORS)
- return -ENOMEM;
-
- if (dma->desc_buf.area == NULL) {
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
- ATI_DESC_LIST_SIZE, &dma->desc_buf) < 0)
- return -ENOMEM;
- dma->period_bytes = dma->periods = 0; /* clear */
- }
-
- if (dma->periods == periods && dma->period_bytes == period_bytes)
- return 0;
-
- /* reset DMA before changing the descriptor table */
- spin_lock_irqsave(&chip->reg_lock, flags);
- writel(0, chip->remap_addr + dma->ops->llp_offset);
- dma->ops->enable_dma(chip, 0);
- dma->ops->enable_dma(chip, 1);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- /* fill the entries */
- addr = (u32)substream->runtime->dma_addr;
- desc_addr = (u32)dma->desc_buf.addr;
- for (i = 0; i < periods; i++) {
- struct atiixp_dma_desc *desc;
- desc = &((struct atiixp_dma_desc *)dma->desc_buf.area)[i];
- desc->addr = cpu_to_le32(addr);
- desc->status = 0;
- desc->size = period_bytes >> 2; /* in dwords */
- desc_addr += sizeof(struct atiixp_dma_desc);
- if (i == periods - 1)
- desc->next = cpu_to_le32((u32)dma->desc_buf.addr);
- else
- desc->next = cpu_to_le32(desc_addr);
- addr += period_bytes;
- }
-
- writel((u32)dma->desc_buf.addr | ATI_REG_LINKPTR_EN,
- chip->remap_addr + dma->ops->llp_offset);
-
- dma->period_bytes = period_bytes;
- dma->periods = periods;
-
- return 0;
-}
-
-/*
- * remove the ring buffer and release it if assigned
- */
-static void atiixp_clear_dma_packets(struct atiixp_modem *chip,
- struct atiixp_dma *dma,
- struct snd_pcm_substream *substream)
-{
- if (dma->desc_buf.area) {
- writel(0, chip->remap_addr + dma->ops->llp_offset);
- snd_dma_free_pages(&dma->desc_buf);
- dma->desc_buf.area = NULL;
- }
-}
-
-/*
- * AC97 interface
- */
-static int snd_atiixp_acquire_codec(struct atiixp_modem *chip)
-{
- int timeout = 1000;
-
- while (atiixp_read(chip, PHYS_OUT_ADDR) & ATI_REG_PHYS_OUT_ADDR_EN) {
- if (! timeout--) {
- snd_printk(KERN_WARNING "atiixp-modem: codec acquire timeout\n");
- return -EBUSY;
- }
- udelay(1);
- }
- return 0;
-}
-
-static unsigned short snd_atiixp_codec_read(struct atiixp_modem *chip,
- unsigned short codec,
- unsigned short reg)
-{
- unsigned int data;
- int timeout;
-
- if (snd_atiixp_acquire_codec(chip) < 0)
- return 0xffff;
- data = (reg << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
- ATI_REG_PHYS_OUT_ADDR_EN |
- ATI_REG_PHYS_OUT_RW |
- codec;
- atiixp_write(chip, PHYS_OUT_ADDR, data);
- if (snd_atiixp_acquire_codec(chip) < 0)
- return 0xffff;
- timeout = 1000;
- do {
- data = atiixp_read(chip, PHYS_IN_ADDR);
- if (data & ATI_REG_PHYS_IN_READ_FLAG)
- return data >> ATI_REG_PHYS_IN_DATA_SHIFT;
- udelay(1);
- } while (--timeout);
- /* time out may happen during reset */
- if (reg < 0x7c)
- snd_printk(KERN_WARNING "atiixp-modem: codec read timeout (reg %x)\n", reg);
- return 0xffff;
-}
-
-
-static void snd_atiixp_codec_write(struct atiixp_modem *chip,
- unsigned short codec,
- unsigned short reg, unsigned short val)
-{
- unsigned int data;
-
- if (snd_atiixp_acquire_codec(chip) < 0)
- return;
- data = ((unsigned int)val << ATI_REG_PHYS_OUT_DATA_SHIFT) |
- ((unsigned int)reg << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
- ATI_REG_PHYS_OUT_ADDR_EN | codec;
- atiixp_write(chip, PHYS_OUT_ADDR, data);
-}
-
-
-static unsigned short snd_atiixp_ac97_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- struct atiixp_modem *chip = ac97->private_data;
- return snd_atiixp_codec_read(chip, ac97->num, reg);
-
-}
-
-static void snd_atiixp_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short val)
-{
- struct atiixp_modem *chip = ac97->private_data;
- if (reg == AC97_GPIO_STATUS) {
- atiixp_write(chip, MODEM_OUT_GPIO,
- (val << ATI_REG_MODEM_OUT_GPIO_DATA_SHIFT) | ATI_REG_MODEM_OUT_GPIO_EN);
- return;
- }
- snd_atiixp_codec_write(chip, ac97->num, reg, val);
-}
-
-/*
- * reset AC link
- */
-static int snd_atiixp_aclink_reset(struct atiixp_modem *chip)
-{
- int timeout;
-
- /* reset powerdoewn */
- if (atiixp_update(chip, CMD, ATI_REG_CMD_POWERDOWN, 0))
- udelay(10);
-
- /* perform a software reset */
- atiixp_update(chip, CMD, ATI_REG_CMD_AC_SOFT_RESET, ATI_REG_CMD_AC_SOFT_RESET);
- atiixp_read(chip, CMD);
- udelay(10);
- atiixp_update(chip, CMD, ATI_REG_CMD_AC_SOFT_RESET, 0);
-
- timeout = 10;
- while (! (atiixp_read(chip, CMD) & ATI_REG_CMD_ACLINK_ACTIVE)) {
- /* do a hard reset */
- atiixp_update(chip, CMD, ATI_REG_CMD_AC_SYNC|ATI_REG_CMD_AC_RESET,
- ATI_REG_CMD_AC_SYNC);
- atiixp_read(chip, CMD);
- msleep(1);
- atiixp_update(chip, CMD, ATI_REG_CMD_AC_RESET, ATI_REG_CMD_AC_RESET);
- if (!--timeout) {
- snd_printk(KERN_ERR "atiixp-modem: codec reset timeout\n");
- break;
- }
- }
-
- /* deassert RESET and assert SYNC to make sure */
- atiixp_update(chip, CMD, ATI_REG_CMD_AC_SYNC|ATI_REG_CMD_AC_RESET,
- ATI_REG_CMD_AC_SYNC|ATI_REG_CMD_AC_RESET);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int snd_atiixp_aclink_down(struct atiixp_modem *chip)
-{
- // if (atiixp_read(chip, MODEM_MIRROR) & 0x1) /* modem running, too? */
- // return -EBUSY;
- atiixp_update(chip, CMD,
- ATI_REG_CMD_POWERDOWN | ATI_REG_CMD_AC_RESET,
- ATI_REG_CMD_POWERDOWN);
- return 0;
-}
-#endif
-
-/*
- * auto-detection of codecs
- *
- * the IXP chip can generate interrupts for the non-existing codecs.
- * NEW_FRAME interrupt is used to make sure that the interrupt is generated
- * even if all three codecs are connected.
- */
-
-#define ALL_CODEC_NOT_READY \
- (ATI_REG_ISR_CODEC0_NOT_READY |\
- ATI_REG_ISR_CODEC1_NOT_READY |\
- ATI_REG_ISR_CODEC2_NOT_READY)
-#define CODEC_CHECK_BITS (ALL_CODEC_NOT_READY|ATI_REG_ISR_NEW_FRAME)
-
-static int snd_atiixp_codec_detect(struct atiixp_modem *chip)
-{
- int timeout;
-
- chip->codec_not_ready_bits = 0;
- atiixp_write(chip, IER, CODEC_CHECK_BITS);
- /* wait for the interrupts */
- timeout = 50;
- while (timeout-- > 0) {
- msleep(1);
- if (chip->codec_not_ready_bits)
- break;
- }
- atiixp_write(chip, IER, 0); /* disable irqs */
-
- if ((chip->codec_not_ready_bits & ALL_CODEC_NOT_READY) == ALL_CODEC_NOT_READY) {
- snd_printk(KERN_ERR "atiixp-modem: no codec detected!\n");
- return -ENXIO;
- }
- return 0;
-}
-
-
-/*
- * enable DMA and irqs
- */
-static int snd_atiixp_chip_start(struct atiixp_modem *chip)
-{
- unsigned int reg;
-
- /* set up spdif, enable burst mode */
- reg = atiixp_read(chip, CMD);
- reg |= ATI_REG_CMD_BURST_EN;
- if(!(reg & ATI_REG_CMD_MODEM_PRESENT))
- reg |= ATI_REG_CMD_MODEM_PRESENT;
- atiixp_write(chip, CMD, reg);
-
- /* clear all interrupt source */
- atiixp_write(chip, ISR, 0xffffffff);
- /* enable irqs */
- atiixp_write(chip, IER,
- ATI_REG_IER_MODEM_STATUS_EN |
- ATI_REG_IER_MODEM_IN_XRUN_EN |
- ATI_REG_IER_MODEM_OUT1_XRUN_EN);
- return 0;
-}
-
-
-/*
- * disable DMA and IRQs
- */
-static int snd_atiixp_chip_stop(struct atiixp_modem *chip)
-{
- /* clear interrupt source */
- atiixp_write(chip, ISR, atiixp_read(chip, ISR));
- /* disable irqs */
- atiixp_write(chip, IER, 0);
- return 0;
-}
-
-
-/*
- * PCM section
- */
-
-/*
- * pointer callback simplly reads XXX_DMA_DT_CUR register as the current
- * position. when SG-buffer is implemented, the offset must be calculated
- * correctly...
- */
-static snd_pcm_uframes_t snd_atiixp_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct atiixp_dma *dma = runtime->private_data;
- unsigned int curptr;
- int timeout = 1000;
-
- while (timeout--) {
- curptr = readl(chip->remap_addr + dma->ops->dt_cur);
- if (curptr < dma->buf_addr)
- continue;
- curptr -= dma->buf_addr;
- if (curptr >= dma->buf_bytes)
- continue;
- return bytes_to_frames(runtime, curptr);
- }
- snd_printd("atiixp-modem: invalid DMA pointer read 0x%x (buf=%x)\n",
- readl(chip->remap_addr + dma->ops->dt_cur), dma->buf_addr);
- return 0;
-}
-
-/*
- * XRUN detected, and stop the PCM substream
- */
-static void snd_atiixp_xrun_dma(struct atiixp_modem *chip,
- struct atiixp_dma *dma)
-{
- if (! dma->substream || ! dma->running)
- return;
- snd_printdd("atiixp-modem: XRUN detected (DMA %d)\n", dma->ops->type);
- snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN);
-}
-
-/*
- * the period ack. update the substream.
- */
-static void snd_atiixp_update_dma(struct atiixp_modem *chip,
- struct atiixp_dma *dma)
-{
- if (! dma->substream || ! dma->running)
- return;
- snd_pcm_period_elapsed(dma->substream);
-}
-
-/* set BUS_BUSY interrupt bit if any DMA is running */
-/* call with spinlock held */
-static void snd_atiixp_check_bus_busy(struct atiixp_modem *chip)
-{
- unsigned int bus_busy;
- if (atiixp_read(chip, CMD) & (ATI_REG_CMD_MODEM_SEND1_EN |
- ATI_REG_CMD_MODEM_RECEIVE_EN))
- bus_busy = ATI_REG_IER_MODEM_SET_BUS_BUSY;
- else
- bus_busy = 0;
- atiixp_update(chip, IER, ATI_REG_IER_MODEM_SET_BUS_BUSY, bus_busy);
-}
-
-/* common trigger callback
- * calling the lowlevel callbacks in it
- */
-static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
- struct atiixp_dma *dma = substream->runtime->private_data;
- int err = 0;
-
- if (snd_BUG_ON(!dma->ops->enable_transfer ||
- !dma->ops->flush_dma))
- return -EINVAL;
-
- spin_lock(&chip->reg_lock);
- switch(cmd) {
- case SNDRV_PCM_TRIGGER_START:
- dma->ops->enable_transfer(chip, 1);
- dma->running = 1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- dma->ops->enable_transfer(chip, 0);
- dma->running = 0;
- break;
- default:
- err = -EINVAL;
- break;
- }
- if (! err) {
- snd_atiixp_check_bus_busy(chip);
- if (cmd == SNDRV_PCM_TRIGGER_STOP) {
- dma->ops->flush_dma(chip);
- snd_atiixp_check_bus_busy(chip);
- }
- }
- spin_unlock(&chip->reg_lock);
- return err;
-}
-
-
-/*
- * lowlevel callbacks for each DMA type
- *
- * every callback is supposed to be called in chip->reg_lock spinlock
- */
-
-/* flush FIFO of analog OUT DMA */
-static void atiixp_out_flush_dma(struct atiixp_modem *chip)
-{
- atiixp_write(chip, MODEM_FIFO_FLUSH, ATI_REG_MODEM_FIFO_OUT1_FLUSH);
-}
-
-/* enable/disable analog OUT DMA */
-static void atiixp_out_enable_dma(struct atiixp_modem *chip, int on)
-{
- unsigned int data;
- data = atiixp_read(chip, CMD);
- if (on) {
- if (data & ATI_REG_CMD_MODEM_OUT_DMA1_EN)
- return;
- atiixp_out_flush_dma(chip);
- data |= ATI_REG_CMD_MODEM_OUT_DMA1_EN;
- } else
- data &= ~ATI_REG_CMD_MODEM_OUT_DMA1_EN;
- atiixp_write(chip, CMD, data);
-}
-
-/* start/stop transfer over OUT DMA */
-static void atiixp_out_enable_transfer(struct atiixp_modem *chip, int on)
-{
- atiixp_update(chip, CMD, ATI_REG_CMD_MODEM_SEND1_EN,
- on ? ATI_REG_CMD_MODEM_SEND1_EN : 0);
-}
-
-/* enable/disable analog IN DMA */
-static void atiixp_in_enable_dma(struct atiixp_modem *chip, int on)
-{
- atiixp_update(chip, CMD, ATI_REG_CMD_MODEM_IN_DMA_EN,
- on ? ATI_REG_CMD_MODEM_IN_DMA_EN : 0);
-}
-
-/* start/stop analog IN DMA */
-static void atiixp_in_enable_transfer(struct atiixp_modem *chip, int on)
-{
- if (on) {
- unsigned int data = atiixp_read(chip, CMD);
- if (! (data & ATI_REG_CMD_MODEM_RECEIVE_EN)) {
- data |= ATI_REG_CMD_MODEM_RECEIVE_EN;
- atiixp_write(chip, CMD, data);
- }
- } else
- atiixp_update(chip, CMD, ATI_REG_CMD_MODEM_RECEIVE_EN, 0);
-}
-
-/* flush FIFO of analog IN DMA */
-static void atiixp_in_flush_dma(struct atiixp_modem *chip)
-{
- atiixp_write(chip, MODEM_FIFO_FLUSH, ATI_REG_MODEM_FIFO_IN_FLUSH);
-}
-
-/* set up slots and formats for analog OUT */
-static int snd_atiixp_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
- unsigned int data;
-
- spin_lock_irq(&chip->reg_lock);
- /* set output threshold */
- data = atiixp_read(chip, MODEM_OUT_FIFO);
- data &= ~ATI_REG_MODEM_OUT1_DMA_THRESHOLD_MASK;
- data |= 0x04 << ATI_REG_MODEM_OUT1_DMA_THRESHOLD_SHIFT;
- atiixp_write(chip, MODEM_OUT_FIFO, data);
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-/* set up slots and formats for analog IN */
-static int snd_atiixp_capture_prepare(struct snd_pcm_substream *substream)
-{
- return 0;
-}
-
-/*
- * hw_params - allocate the buffer and set up buffer descriptors
- */
-static int snd_atiixp_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
- struct atiixp_dma *dma = substream->runtime->private_data;
- int err;
- int i;
-
- err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
- dma->buf_addr = substream->runtime->dma_addr;
- dma->buf_bytes = params_buffer_bytes(hw_params);
-
- err = atiixp_build_dma_packets(chip, dma, substream,
- params_periods(hw_params),
- params_period_bytes(hw_params));
- if (err < 0)
- return err;
-
- /* set up modem rate */
- for (i = 0; i < NUM_ATI_CODECS; i++) {
- if (! chip->ac97[i])
- continue;
- snd_ac97_write(chip->ac97[i], AC97_LINE1_RATE, params_rate(hw_params));
- snd_ac97_write(chip->ac97[i], AC97_LINE1_LEVEL, 0);
- }
-
- return err;
-}
-
-static int snd_atiixp_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
- struct atiixp_dma *dma = substream->runtime->private_data;
-
- atiixp_clear_dma_packets(chip, dma, substream);
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-
-/*
- * pcm hardware definition, identical for all DMA types
- */
-static struct snd_pcm_hardware snd_atiixp_pcm_hw =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = (SNDRV_PCM_RATE_8000 |
- SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_KNOT),
- .rate_min = 8000,
- .rate_max = 16000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 256 * 1024,
- .period_bytes_min = 32,
- .period_bytes_max = 128 * 1024,
- .periods_min = 2,
- .periods_max = ATI_MAX_DESCRIPTORS,
-};
-
-static int snd_atiixp_pcm_open(struct snd_pcm_substream *substream,
- struct atiixp_dma *dma, int pcm_type)
-{
- struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
- static unsigned int rates[] = { 8000, 9600, 12000, 16000 };
- static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
- .count = ARRAY_SIZE(rates),
- .list = rates,
- .mask = 0,
- };
-
- if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma))
- return -EINVAL;
-
- if (dma->opened)
- return -EBUSY;
- dma->substream = substream;
- runtime->hw = snd_atiixp_pcm_hw;
- dma->ac97_pcm_type = pcm_type;
- if ((err = snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- &hw_constraints_rates)) < 0)
- return err;
- if ((err = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
- return err;
- runtime->private_data = dma;
-
- /* enable DMA bits */
- spin_lock_irq(&chip->reg_lock);
- dma->ops->enable_dma(chip, 1);
- spin_unlock_irq(&chip->reg_lock);
- dma->opened = 1;
-
- return 0;
-}
-
-static int snd_atiixp_pcm_close(struct snd_pcm_substream *substream,
- struct atiixp_dma *dma)
-{
- struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
- /* disable DMA bits */
- if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma))
- return -EINVAL;
- spin_lock_irq(&chip->reg_lock);
- dma->ops->enable_dma(chip, 0);
- spin_unlock_irq(&chip->reg_lock);
- dma->substream = NULL;
- dma->opened = 0;
- return 0;
-}
-
-/*
- */
-static int snd_atiixp_playback_open(struct snd_pcm_substream *substream)
-{
- struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
- int err;
-
- mutex_lock(&chip->open_mutex);
- err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 0);
- mutex_unlock(&chip->open_mutex);
- if (err < 0)
- return err;
- return 0;
-}
-
-static int snd_atiixp_playback_close(struct snd_pcm_substream *substream)
-{
- struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
- int err;
- mutex_lock(&chip->open_mutex);
- err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]);
- mutex_unlock(&chip->open_mutex);
- return err;
-}
-
-static int snd_atiixp_capture_open(struct snd_pcm_substream *substream)
-{
- struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
- return snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_CAPTURE], 1);
-}
-
-static int snd_atiixp_capture_close(struct snd_pcm_substream *substream)
-{
- struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
- return snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_CAPTURE]);
-}
-
-
-/* AC97 playback */
-static struct snd_pcm_ops snd_atiixp_playback_ops = {
- .open = snd_atiixp_playback_open,
- .close = snd_atiixp_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_atiixp_pcm_hw_params,
- .hw_free = snd_atiixp_pcm_hw_free,
- .prepare = snd_atiixp_playback_prepare,
- .trigger = snd_atiixp_pcm_trigger,
- .pointer = snd_atiixp_pcm_pointer,
-};
-
-/* AC97 capture */
-static struct snd_pcm_ops snd_atiixp_capture_ops = {
- .open = snd_atiixp_capture_open,
- .close = snd_atiixp_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_atiixp_pcm_hw_params,
- .hw_free = snd_atiixp_pcm_hw_free,
- .prepare = snd_atiixp_capture_prepare,
- .trigger = snd_atiixp_pcm_trigger,
- .pointer = snd_atiixp_pcm_pointer,
-};
-
-static struct atiixp_dma_ops snd_atiixp_playback_dma_ops = {
- .type = ATI_DMA_PLAYBACK,
- .llp_offset = ATI_REG_MODEM_OUT_DMA1_LINKPTR,
- .dt_cur = ATI_REG_MODEM_OUT_DMA1_DT_CUR,
- .enable_dma = atiixp_out_enable_dma,
- .enable_transfer = atiixp_out_enable_transfer,
- .flush_dma = atiixp_out_flush_dma,
-};
-
-static struct atiixp_dma_ops snd_atiixp_capture_dma_ops = {
- .type = ATI_DMA_CAPTURE,
- .llp_offset = ATI_REG_MODEM_IN_DMA_LINKPTR,
- .dt_cur = ATI_REG_MODEM_IN_DMA_DT_CUR,
- .enable_dma = atiixp_in_enable_dma,
- .enable_transfer = atiixp_in_enable_transfer,
- .flush_dma = atiixp_in_flush_dma,
-};
-
-static int __devinit snd_atiixp_pcm_new(struct atiixp_modem *chip)
-{
- struct snd_pcm *pcm;
- int err;
-
- /* initialize constants */
- chip->dmas[ATI_DMA_PLAYBACK].ops = &snd_atiixp_playback_dma_ops;
- chip->dmas[ATI_DMA_CAPTURE].ops = &snd_atiixp_capture_dma_ops;
-
- /* PCM #0: analog I/O */
- err = snd_pcm_new(chip->card, "ATI IXP MC97", ATI_PCMDEV_ANALOG, 1, 1, &pcm);
- if (err < 0)
- return err;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_atiixp_capture_ops);
- pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
- pcm->private_data = chip;
- strcpy(pcm->name, "ATI IXP MC97");
- chip->pcmdevs[ATI_PCMDEV_ANALOG] = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- 64*1024, 128*1024);
-
- return 0;
-}
-
-
-
-/*
- * interrupt handler
- */
-static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id)
-{
- struct atiixp_modem *chip = dev_id;
- unsigned int status;
-
- status = atiixp_read(chip, ISR);
-
- if (! status)
- return IRQ_NONE;
-
- /* process audio DMA */
- if (status & ATI_REG_ISR_MODEM_OUT1_XRUN)
- snd_atiixp_xrun_dma(chip, &chip->dmas[ATI_DMA_PLAYBACK]);
- else if (status & ATI_REG_ISR_MODEM_OUT1_STATUS)
- snd_atiixp_update_dma(chip, &chip->dmas[ATI_DMA_PLAYBACK]);
- if (status & ATI_REG_ISR_MODEM_IN_XRUN)
- snd_atiixp_xrun_dma(chip, &chip->dmas[ATI_DMA_CAPTURE]);
- else if (status & ATI_REG_ISR_MODEM_IN_STATUS)
- snd_atiixp_update_dma(chip, &chip->dmas[ATI_DMA_CAPTURE]);
-
- /* for codec detection */
- if (status & CODEC_CHECK_BITS) {
- unsigned int detected;
- detected = status & CODEC_CHECK_BITS;
- spin_lock(&chip->reg_lock);
- chip->codec_not_ready_bits |= detected;
- atiixp_update(chip, IER, detected, 0); /* disable the detected irqs */
- spin_unlock(&chip->reg_lock);
- }
-
- /* ack */
- atiixp_write(chip, ISR, status);
-
- return IRQ_HANDLED;
-}
-
-
-/*
- * ac97 mixer section
- */
-
-static int __devinit snd_atiixp_mixer_new(struct atiixp_modem *chip, int clock)
-{
- struct snd_ac97_bus *pbus;
- struct snd_ac97_template ac97;
- int i, err;
- int codec_count;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_atiixp_ac97_write,
- .read = snd_atiixp_ac97_read,
- };
- static unsigned int codec_skip[NUM_ATI_CODECS] = {
- ATI_REG_ISR_CODEC0_NOT_READY,
- ATI_REG_ISR_CODEC1_NOT_READY,
- ATI_REG_ISR_CODEC2_NOT_READY,
- };
-
- if (snd_atiixp_codec_detect(chip) < 0)
- return -ENXIO;
-
- if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
- return err;
- pbus->clock = clock;
- chip->ac97_bus = pbus;
-
- codec_count = 0;
- for (i = 0; i < NUM_ATI_CODECS; i++) {
- if (chip->codec_not_ready_bits & codec_skip[i])
- continue;
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = chip;
- ac97.pci = chip->pci;
- ac97.num = i;
- ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
- if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
- chip->ac97[i] = NULL; /* to be sure */
- snd_printdd("atiixp-modem: codec %d not available for modem\n", i);
- continue;
- }
- codec_count++;
- }
-
- if (! codec_count) {
- snd_printk(KERN_ERR "atiixp-modem: no codec available\n");
- return -ENODEV;
- }
-
- /* snd_ac97_tune_hardware(chip->ac97, ac97_quirks); */
-
- return 0;
-}
-
-
-#ifdef CONFIG_PM
-/*
- * power management
- */
-static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct atiixp_modem *chip = card->private_data;
- int i;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- for (i = 0; i < NUM_ATI_PCMDEVS; i++)
- snd_pcm_suspend_all(chip->pcmdevs[i]);
- for (i = 0; i < NUM_ATI_CODECS; i++)
- snd_ac97_suspend(chip->ac97[i]);
- snd_atiixp_aclink_down(chip);
- snd_atiixp_chip_stop(chip);
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int snd_atiixp_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct atiixp_modem *chip = card->private_data;
- int i;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "atiixp-modem: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
-
- snd_atiixp_aclink_reset(chip);
- snd_atiixp_chip_start(chip);
-
- for (i = 0; i < NUM_ATI_CODECS; i++)
- snd_ac97_resume(chip->ac97[i]);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif /* CONFIG_PM */
-
-
-#ifdef CONFIG_PROC_FS
-/*
- * proc interface for register dump
- */
-
-static void snd_atiixp_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct atiixp_modem *chip = entry->private_data;
- int i;
-
- for (i = 0; i < 256; i += 4)
- snd_iprintf(buffer, "%02x: %08x\n", i, readl(chip->remap_addr + i));
-}
-
-static void __devinit snd_atiixp_proc_init(struct atiixp_modem *chip)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(chip->card, "atiixp-modem", &entry))
- snd_info_set_text_ops(entry, chip, snd_atiixp_proc_read);
-}
-#else
-#define snd_atiixp_proc_init(chip)
-#endif
-
-
-/*
- * destructor
- */
-
-static int snd_atiixp_free(struct atiixp_modem *chip)
-{
- if (chip->irq < 0)
- goto __hw_end;
- snd_atiixp_chip_stop(chip);
-
- __hw_end:
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
- if (chip->remap_addr)
- iounmap(chip->remap_addr);
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
- kfree(chip);
- return 0;
-}
-
-static int snd_atiixp_dev_free(struct snd_device *device)
-{
- struct atiixp_modem *chip = device->device_data;
- return snd_atiixp_free(chip);
-}
-
-/*
- * constructor for chip instance
- */
-static int __devinit snd_atiixp_create(struct snd_card *card,
- struct pci_dev *pci,
- struct atiixp_modem **r_chip)
-{
- static struct snd_device_ops ops = {
- .dev_free = snd_atiixp_dev_free,
- };
- struct atiixp_modem *chip;
- int err;
-
- if ((err = pci_enable_device(pci)) < 0)
- return err;
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- spin_lock_init(&chip->reg_lock);
- mutex_init(&chip->open_mutex);
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
- if ((err = pci_request_regions(pci, "ATI IXP MC97")) < 0) {
- kfree(chip);
- pci_disable_device(pci);
- return err;
- }
- chip->addr = pci_resource_start(pci, 0);
- chip->remap_addr = pci_ioremap_bar(pci, 0);
- if (chip->remap_addr == NULL) {
- snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
- snd_atiixp_free(chip);
- return -EIO;
- }
-
- if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_atiixp_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
- pci_set_master(pci);
- synchronize_irq(chip->irq);
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_atiixp_free(chip);
- return err;
- }
-
- snd_card_set_dev(card, &pci->dev);
-
- *r_chip = chip;
- return 0;
-}
-
-
-static int __devinit snd_atiixp_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- struct snd_card *card;
- struct atiixp_modem *chip;
- int err;
-
- err = snd_card_create(index, id, THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- strcpy(card->driver, "ATIIXP-MODEM");
- strcpy(card->shortname, "ATI IXP Modem");
- if ((err = snd_atiixp_create(card, pci, &chip)) < 0)
- goto __error;
- card->private_data = chip;
-
- if ((err = snd_atiixp_aclink_reset(chip)) < 0)
- goto __error;
-
- if ((err = snd_atiixp_mixer_new(chip, ac97_clock)) < 0)
- goto __error;
-
- if ((err = snd_atiixp_pcm_new(chip)) < 0)
- goto __error;
-
- snd_atiixp_proc_init(chip);
-
- snd_atiixp_chip_start(chip);
-
- sprintf(card->longname, "%s rev %x at 0x%lx, irq %i",
- card->shortname, pci->revision, chip->addr, chip->irq);
-
- if ((err = snd_card_register(card)) < 0)
- goto __error;
-
- pci_set_drvdata(pci, card);
- return 0;
-
- __error:
- snd_card_free(card);
- return err;
-}
-
-static void __devexit snd_atiixp_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_atiixp_ids,
- .probe = snd_atiixp_probe,
- .remove = __devexit_p(snd_atiixp_remove),
-#ifdef CONFIG_PM
- .suspend = snd_atiixp_suspend,
- .resume = snd_atiixp_resume,
-#endif
-};
-
-
-static int __init alsa_card_atiixp_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_atiixp_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_atiixp_init)
-module_exit(alsa_card_atiixp_exit)
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/Makefile b/ANDROID_3.4.5/sound/pci/au88x0/Makefile
deleted file mode 100644
index d0a66bc5..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-snd-au8810-objs := au8810.o
-snd-au8820-objs := au8820.o
-snd-au8830-objs := au8830.o
-
-obj-$(CONFIG_SND_AU8810) += snd-au8810.o
-obj-$(CONFIG_SND_AU8820) += snd-au8820.o
-obj-$(CONFIG_SND_AU8830) += snd-au8830.o
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au8810.c b/ANDROID_3.4.5/sound/pci/au88x0/au8810.c
deleted file mode 100644
index aa51cc77..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au8810.c
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "au8810.h"
-#include "au88x0.h"
-static DEFINE_PCI_DEVICE_TABLE(snd_vortex_ids) = {
- {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_ADVANTAGE), 1,},
- {0,}
-};
-
-#include "au88x0_core.c"
-#include "au88x0_pcm.c"
-#include "au88x0_mixer.c"
-#include "au88x0_mpu401.c"
-#include "au88x0_game.c"
-#include "au88x0_eq.c"
-#include "au88x0_a3d.c"
-#include "au88x0_xtalk.c"
-#include "au88x0.c"
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au8810.h b/ANDROID_3.4.5/sound/pci/au88x0/au8810.h
deleted file mode 100644
index 79fbee38..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au8810.h
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- Aureal Advantage Soundcard driver.
- */
-
-#define CHIP_AU8810
-
-#define CARD_NAME "Aureal Advantage"
-#define CARD_NAME_SHORT "au8810"
-
-#define NR_ADB 0x10
-#define NR_WT 0x00
-#define NR_SRC 0x10
-#define NR_A3D 0x10
-#define NR_MIXIN 0x20
-#define NR_MIXOUT 0x10
-
-
-/* ADBDMA */
-#define VORTEX_ADBDMA_STAT 0x27e00 /* read only, subbuffer, DMA pos */
-#define POS_MASK 0x00000fff
-#define POS_SHIFT 0x0
-#define ADB_SUBBUF_MASK 0x00003000 /* ADB only. */
-#define ADB_SUBBUF_SHIFT 0xc /* ADB only. */
-#define VORTEX_ADBDMA_CTRL 0x27180 /* write only; format, flags, DMA pos */
-#define OFFSET_MASK 0x00000fff
-#define OFFSET_SHIFT 0x0
-#define IE_MASK 0x00001000 /* interrupt enable. */
-#define IE_SHIFT 0xc
-#define DIR_MASK 0x00002000 /* Direction */
-#define DIR_SHIFT 0xd
-#define FMT_MASK 0x0003c000
-#define FMT_SHIFT 0xe
-// The ADB masks and shift also are valid for the wtdma, except if specified otherwise.
-#define VORTEX_ADBDMA_BUFCFG0 0x27100
-#define VORTEX_ADBDMA_BUFCFG1 0x27104
-#define VORTEX_ADBDMA_BUFBASE 0x27000
-#define VORTEX_ADBDMA_START 0x27c00 /* Which subbuffer starts */
-
-#define VORTEX_ADBDMA_STATUS 0x27A90 /* stored at AdbDma->this_10 / 2 DWORD in size. */
-
-/* WTDMA */
-#define VORTEX_WTDMA_CTRL 0x27fd8 /* format, DMA pos */
-#define VORTEX_WTDMA_STAT 0x27fe8 /* DMA subbuf, DMA pos */
-#define WT_SUBBUF_MASK 0x3
-#define WT_SUBBUF_SHIFT 0xc
-#define VORTEX_WTDMA_BUFBASE 0x27fc0
-#define VORTEX_WTDMA_BUFCFG0 0x27fd0
-#define VORTEX_WTDMA_BUFCFG1 0x27fd4
-#define VORTEX_WTDMA_START 0x27fe4 /* which subbuffer is first */
-
-/* ADB */
-#define VORTEX_ADB_SR 0x28400 /* Samplerates enable/disable */
-#define VORTEX_ADB_RTBASE 0x28000
-#define VORTEX_ADB_RTBASE_COUNT 173
-#define VORTEX_ADB_CHNBASE 0x282b4
-#define VORTEX_ADB_CHNBASE_COUNT 24
-#define ROUTE_MASK 0xffff
-#define SOURCE_MASK 0xff00
-#define ADB_MASK 0xff
-#define ADB_SHIFT 0x8
-
-/* ADB address */
-#define OFFSET_ADBDMA 0x00
-#define OFFSET_SRCIN 0x40
-#define OFFSET_SRCOUT 0x20
-#define OFFSET_MIXIN 0x50
-#define OFFSET_MIXOUT 0x30
-#define OFFSET_CODECIN 0x70
-#define OFFSET_CODECOUT 0x88
-#define OFFSET_SPORTIN 0x78 /* ch 0x13 */
-#define OFFSET_SPORTOUT 0x90
-#define OFFSET_SPDIFOUT 0x92 /* ch 0x14 check this! */
-#define OFFSET_EQIN 0xa0
-#define OFFSET_EQOUT 0x7e /* 2 routes on ch 0x11 */
-#define OFFSET_XTALKOUT 0x66 /* crosstalk canceller (source) */
-#define OFFSET_XTALKIN 0x96 /* crosstalk canceller (sink) */
-#define OFFSET_A3DIN 0x70 /* ADB sink. */
-#define OFFSET_A3DOUT 0xA6 /* ADB source. 2 routes per slice = 8 */
-#define OFFSET_EFXIN 0x80 /* ADB sink. */
-#define OFFSET_EFXOUT 0x68 /* ADB source. */
-
-/* ADB route translate helper */
-#define ADB_DMA(x) (x)
-#define ADB_SRCOUT(x) (x + OFFSET_SRCOUT)
-#define ADB_SRCIN(x) (x + OFFSET_SRCIN)
-#define ADB_MIXOUT(x) (x + OFFSET_MIXOUT)
-#define ADB_MIXIN(x) (x + OFFSET_MIXIN)
-#define ADB_CODECIN(x) (x + OFFSET_CODECIN)
-#define ADB_CODECOUT(x) (x + OFFSET_CODECOUT)
-#define ADB_SPORTIN(x) (x + OFFSET_SPORTIN)
-#define ADB_SPORTOUT(x) (x + OFFSET_SPORTOUT)
-#define ADB_SPDIFOUT(x) (x + OFFSET_SPDIFOUT)
-#define ADB_EQIN(x) (x + OFFSET_EQIN)
-#define ADB_EQOUT(x) (x + OFFSET_EQOUT)
-#define ADB_A3DOUT(x) (x + OFFSET_A3DOUT) /* 0x10 A3D blocks */
-#define ADB_A3DIN(x) (x + OFFSET_A3DIN)
-#define ADB_XTALKIN(x) (x + OFFSET_XTALKIN)
-#define ADB_XTALKOUT(x) (x + OFFSET_XTALKOUT)
-
-#define MIX_OUTL 0xe
-#define MIX_OUTR 0xf
-#define MIX_INL 0x1e
-#define MIX_INR 0x1f
-#define MIX_DEFIGAIN 0x08 /* 0x8 => 6dB */
-#define MIX_DEFOGAIN 0x08
-
-/* MIXER */
-#define VORTEX_MIXER_SR 0x21f00
-#define VORTEX_MIXER_CLIP 0x21f80
-#define VORTEX_MIXER_CHNBASE 0x21e40
-#define VORTEX_MIXER_RTBASE 0x21e00
-#define MIXER_RTBASE_SIZE 0x38
-#define VORTEX_MIX_ENIN 0x21a00 /* Input enable bits. 4 bits wide. */
-#define VORTEX_MIX_SMP 0x21c00 /* AU8820: 0x9c00 */
-
-/* MIX */
-#define VORTEX_MIX_INVOL_A 0x21000 /* in? */
-#define VORTEX_MIX_INVOL_B 0x20000 /* out? */
-#define VORTEX_MIX_VOL_A 0x21800
-#define VORTEX_MIX_VOL_B 0x20800
-
-#define VOL_MIN 0x80 /* Input volume when muted. */
-#define VOL_MAX 0x7f /* FIXME: Not confirmed! Just guessed. */
-
-/* SRC */
-#define VORTEX_SRC_CHNBASE 0x26c40
-#define VORTEX_SRC_RTBASE 0x26c00
-#define VORTEX_SRCBLOCK_SR 0x26cc0
-#define VORTEX_SRC_SOURCE 0x26cc4
-#define VORTEX_SRC_SOURCESIZE 0x26cc8
-/* Params
- 0x26e00 : 1 U0
- 0x26e40 : 2 CR
- 0x26e80 : 3 U3
- 0x26ec0 : 4 DRIFT1
- 0x26f00 : 5 U1
- 0x26f40 : 6 DRIFT2
- 0x26f80 : 7 U2 : Target rate, direction
-*/
-
-#define VORTEX_SRC_CONVRATIO 0x26e40
-#define VORTEX_SRC_DRIFT0 0x26e80
-#define VORTEX_SRC_DRIFT1 0x26ec0
-#define VORTEX_SRC_DRIFT2 0x26f40
-#define VORTEX_SRC_U0 0x26e00
-#define U0_SLOWLOCK 0x200
-#define VORTEX_SRC_U1 0x26f00
-#define VORTEX_SRC_U2 0x26f80
-#define VORTEX_SRC_DATA 0x26800 /* 0xc800 */
-#define VORTEX_SRC_DATA0 0x26000
-
-/* FIFO */
-#define VORTEX_FIFO_ADBCTRL 0x16100 /* Control bits. */
-#define VORTEX_FIFO_WTCTRL 0x16000
-#define FIFO_RDONLY 0x00000001
-#define FIFO_CTRL 0x00000002 /* Allow ctrl. ? */
-#define FIFO_VALID 0x00000010
-#define FIFO_EMPTY 0x00000020
-#define FIFO_U0 0x00001000 /* Unknown. */
-#define FIFO_U1 0x00010000
-#define FIFO_SIZE_BITS 5
-#define FIFO_SIZE (1<<FIFO_SIZE_BITS) // 0x20
-#define FIFO_MASK (FIFO_SIZE-1) //0x1f /* at shift left 0xc */
-//#define FIFO_MASK 0x1f /* at shift left 0xb */
-//#define FIFO_SIZE 0x20
-#define FIFO_BITS 0x03880000
-#define VORTEX_FIFO_ADBDATA 0x14000
-#define VORTEX_FIFO_WTDATA 0x10000
-
-/* CODEC */
-#define VORTEX_CODEC_CTRL 0x29184
-#define VORTEX_CODEC_EN 0x29190
-#define EN_CODEC0 0x00000300
-#define EN_AC98 0x00000c00 /* Modem AC98 slots. */
-#define EN_CODEC1 0x00003000
-#define EN_CODEC (EN_CODEC0 | EN_CODEC1)
-#define EN_SPORT 0x00030000
-#define EN_SPDIF 0x000c0000
-
-#define VORTEX_CODEC_CHN 0x29080
-#define VORTEX_CODEC_IO 0x29188
-
-/* SPDIF */
-#define VORTEX_SPDIF_FLAGS 0x2205c
-#define VORTEX_SPDIF_CFG0 0x291D0
-#define VORTEX_SPDIF_CFG1 0x291D4
-#define VORTEX_SPDIF_SMPRATE 0x29194
-
-/* Sample timer */
-#define VORTEX_SMP_TIME 0x29198
-
-#define VORTEX_MODEM_CTRL 0x291ac
-
-/* IRQ */
-#define VORTEX_IRQ_SOURCE 0x2a000 /* Interrupt source flags. */
-#define VORTEX_IRQ_CTRL 0x2a004 /* Interrupt source mask. */
-
-#define VORTEX_STAT 0x2a008 /* Status */
-
-#define VORTEX_CTRL 0x2a00c
-#define CTRL_MIDI_EN 0x00000001
-#define CTRL_MIDI_PORT 0x00000060
-#define CTRL_GAME_EN 0x00000008
-#define CTRL_GAME_PORT 0x00000e00
-//#define CTRL_IRQ_ENABLE 0x01004000
-#define CTRL_IRQ_ENABLE 0x00004000
-
-/* write: Timer period config / read: TIMER IRQ ack. */
-#define VORTEX_IRQ_STAT 0x2919c
-
-/* DMA */
-#define VORTEX_ENGINE_CTRL 0x27ae8
-#define ENGINE_INIT 0x1380000
-
-/* MIDI *//* GAME. */
-#define VORTEX_MIDI_DATA 0x28800
-#define VORTEX_MIDI_CMD 0x28804 /* Write command / Read status */
-
-#define VORTEX_CTRL2 0x2880c
-#define CTRL2_GAME_ADCMODE 0x40
-#define VORTEX_GAME_LEGACY 0x28808
-#define VORTEX_GAME_AXIS 0x28810
-#define AXIS_SIZE 4
-#define AXIS_RANGE 0x1fff
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au8820.c b/ANDROID_3.4.5/sound/pci/au88x0/au8820.c
deleted file mode 100644
index 2f321e73..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au8820.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "au8820.h"
-#include "au88x0.h"
-static DEFINE_PCI_DEVICE_TABLE(snd_vortex_ids) = {
- {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_1), 0,},
- {0,}
-};
-
-#include "au88x0_synth.c"
-#include "au88x0_core.c"
-#include "au88x0_pcm.c"
-#include "au88x0_mpu401.c"
-#include "au88x0_game.c"
-#include "au88x0_mixer.c"
-#include "au88x0.c"
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au8820.h b/ANDROID_3.4.5/sound/pci/au88x0/au8820.h
deleted file mode 100644
index cafdb966..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au8820.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- Aureal Vortex Soundcard driver.
-
- IO addr collected from asp4core.vxd:
- function address
- 0005D5A0 13004
- 00080674 14004
- 00080AFF 12818
-
- */
-
-#define CHIP_AU8820
-
-#define CARD_NAME "Aureal Vortex"
-#define CARD_NAME_SHORT "au8820"
-
-/* Number of ADB and WT channels */
-#define NR_ADB 0x10
-#define NR_WT 0x20
-#define NR_SRC 0x10
-#define NR_A3D 0x00
-#define NR_MIXIN 0x10
-#define NR_MIXOUT 0x10
-
-
-/* ADBDMA */
-#define VORTEX_ADBDMA_STAT 0x105c0 /* read only, subbuffer, DMA pos */
-#define POS_MASK 0x00000fff
-#define POS_SHIFT 0x0
-#define ADB_SUBBUF_MASK 0x00003000 /* ADB only. */
-#define ADB_SUBBUF_SHIFT 0xc /* ADB only. */
-#define VORTEX_ADBDMA_CTRL 0x10580 /* write only, format, flags, DMA pos */
-#define OFFSET_MASK 0x00000fff
-#define OFFSET_SHIFT 0x0
-#define IE_MASK 0x00001000 /* interrupt enable. */
-#define IE_SHIFT 0xc
-#define DIR_MASK 0x00002000 /* Direction. */
-#define DIR_SHIFT 0xd
-#define FMT_MASK 0x0003c000
-#define FMT_SHIFT 0xe
-// The masks and shift also work for the wtdma, if not specified otherwise.
-#define VORTEX_ADBDMA_BUFCFG0 0x10400
-#define VORTEX_ADBDMA_BUFCFG1 0x10404
-#define VORTEX_ADBDMA_BUFBASE 0x10200
-#define VORTEX_ADBDMA_START 0x106c0 /* Which subbuffer starts */
-#define VORTEX_ADBDMA_STATUS 0x10600 /* stored at AdbDma->this_10 / 2 DWORD in size. */
-
-/* ADB */
-#define VORTEX_ADB_SR 0x10a00 /* Samplerates enable/disable */
-#define VORTEX_ADB_RTBASE 0x10800
-#define VORTEX_ADB_RTBASE_COUNT 103
-#define VORTEX_ADB_CHNBASE 0x1099c
-#define VORTEX_ADB_CHNBASE_COUNT 22
-#define ROUTE_MASK 0x3fff
-#define ADB_MASK 0x7f
-#define ADB_SHIFT 0x7
-//#define ADB_MIX_MASK 0xf
-/* ADB address */
-#define OFFSET_ADBDMA 0x00
-#define OFFSET_SRCOUT 0x10 /* on channel 0x11 */
-#define OFFSET_SRCIN 0x10 /* on channel < 0x11 */
-#define OFFSET_MIXOUT 0x20 /* source */
-#define OFFSET_MIXIN 0x30 /* sink */
-#define OFFSET_CODECIN 0x48 /* ADB source */
-#define OFFSET_CODECOUT 0x58 /* ADB sink/target */
-#define OFFSET_SPORTOUT 0x60 /* sink */
-#define OFFSET_SPORTIN 0x50 /* source */
-#define OFFSET_EFXOUT 0x50 /* sink */
-#define OFFSET_EFXIN 0x40 /* source */
-#define OFFSET_A3DOUT 0x00 /* This card has no HRTF :( */
-#define OFFSET_A3DIN 0x00
-#define OFFSET_WTOUT 0x58 /* */
-
-/* ADB route translate helper */
-#define ADB_DMA(x) (x + OFFSET_ADBDMA)
-#define ADB_SRCOUT(x) (x + OFFSET_SRCOUT)
-#define ADB_SRCIN(x) (x + OFFSET_SRCIN)
-#define ADB_MIXOUT(x) (x + OFFSET_MIXOUT)
-#define ADB_MIXIN(x) (x + OFFSET_MIXIN)
-#define ADB_CODECIN(x) (x + OFFSET_CODECIN)
-#define ADB_CODECOUT(x) (x + OFFSET_CODECOUT)
-#define ADB_SPORTOUT(x) (x + OFFSET_SPORTOUT)
-#define ADB_SPORTIN(x) (x + OFFSET_SPORTIN) /* */
-#define ADB_A3DOUT(x) (x + OFFSET_A3DOUT) /* 8 A3D blocks */
-#define ADB_A3DIN(x) (x + OFFSET_A3DIN)
-#define ADB_WTOUT(x,y) (y + OFFSET_WTOUT)
-
-/* WTDMA */
-#define VORTEX_WTDMA_CTRL 0x10500 /* format, DMA pos */
-#define VORTEX_WTDMA_STAT 0x10500 /* DMA subbuf, DMA pos */
-#define WT_SUBBUF_MASK (0x3 << WT_SUBBUF_SHIFT)
-#define WT_SUBBUF_SHIFT 0x15
-#define VORTEX_WTDMA_BUFBASE 0x10000
-#define VORTEX_WTDMA_BUFCFG0 0x10300
-#define VORTEX_WTDMA_BUFCFG1 0x10304
-#define VORTEX_WTDMA_START 0x10640 /* which subbuffer is first */
-
-#define VORTEX_WT_BASE 0x9000
-
-/* MIXER */
-#define VORTEX_MIXER_SR 0x9f00
-#define VORTEX_MIXER_CLIP 0x9f80
-#define VORTEX_MIXER_CHNBASE 0x9e40
-#define VORTEX_MIXER_RTBASE 0x9e00
-#define MIXER_RTBASE_SIZE 0x26
-#define VORTEX_MIX_ENIN 0x9a00 /* Input enable bits. 4 bits wide. */
-#define VORTEX_MIX_SMP 0x9c00
-
-/* MIX */
-#define VORTEX_MIX_INVOL_A 0x9000 /* in? */
-#define VORTEX_MIX_INVOL_B 0x8000 /* out? */
-#define VORTEX_MIX_VOL_A 0x9800
-#define VORTEX_MIX_VOL_B 0x8800
-
-#define VOL_MIN 0x80 /* Input volume when muted. */
-#define VOL_MAX 0x7f /* FIXME: Not confirmed! Just guessed. */
-
-//#define MIX_OUTL 0xe
-//#define MIX_OUTR 0xf
-//#define MIX_INL 0xe
-//#define MIX_INR 0xf
-#define MIX_DEFIGAIN 0x08 /* 0x8 => 6dB */
-#define MIX_DEFOGAIN 0x08
-
-/* SRC */
-#define VORTEX_SRCBLOCK_SR 0xccc0
-#define VORTEX_SRC_CHNBASE 0xcc40
-#define VORTEX_SRC_RTBASE 0xcc00
-#define VORTEX_SRC_SOURCE 0xccc4
-#define VORTEX_SRC_SOURCESIZE 0xccc8
-#define VORTEX_SRC_U0 0xce00
-#define VORTEX_SRC_DRIFT0 0xce80
-#define VORTEX_SRC_DRIFT1 0xcec0
-#define VORTEX_SRC_U1 0xcf00
-#define VORTEX_SRC_DRIFT2 0xcf40
-#define VORTEX_SRC_U2 0xcf80
-#define VORTEX_SRC_DATA 0xc800
-#define VORTEX_SRC_DATA0 0xc000
-#define VORTEX_SRC_CONVRATIO 0xce40
-//#define SRC_RATIO(x) ((((x<<15)/48000) + 1)/2) /* Playback */
-//#define SRC_RATIO2(x) ((((48000<<15)/x) + 1)/2) /* Recording */
-
-/* FIFO */
-#define VORTEX_FIFO_ADBCTRL 0xf800 /* Control bits. */
-#define VORTEX_FIFO_WTCTRL 0xf840
-#define FIFO_RDONLY 0x00000001
-#define FIFO_CTRL 0x00000002 /* Allow ctrl. ? */
-#define FIFO_VALID 0x00000010
-#define FIFO_EMPTY 0x00000020
-#define FIFO_U0 0x00001000 /* Unknown. */
-#define FIFO_U1 0x00010000
-#define FIFO_SIZE_BITS 5
-#define FIFO_SIZE (1<<FIFO_SIZE_BITS) // 0x20
-#define FIFO_MASK (FIFO_SIZE-1) //0x1f /* at shift left 0xc */
-#define VORTEX_FIFO_ADBDATA 0xe000
-#define VORTEX_FIFO_WTDATA 0xe800
-
-/* CODEC */
-#define VORTEX_CODEC_CTRL 0x11984
-#define VORTEX_CODEC_EN 0x11990
-#define EN_CODEC 0x00000300
-#define EN_SPORT 0x00030000
-#define EN_SPDIF 0x000c0000
-#define VORTEX_CODEC_CHN 0x11880
-#define VORTEX_CODEC_IO 0x11988
-
-#define VORTEX_SPDIF_FLAGS 0x1005c /* FIXME */
-#define VORTEX_SPDIF_CFG0 0x119D0
-#define VORTEX_SPDIF_CFG1 0x119D4
-#define VORTEX_SPDIF_SMPRATE 0x11994
-
-/* Sample timer */
-#define VORTEX_SMP_TIME 0x11998
-
-/* IRQ */
-#define VORTEX_IRQ_SOURCE 0x12800 /* Interrupt source flags. */
-#define VORTEX_IRQ_CTRL 0x12804 /* Interrupt source mask. */
-
-#define VORTEX_STAT 0x12808 /* ?? */
-
-#define VORTEX_CTRL 0x1280c
-#define CTRL_MIDI_EN 0x00000001
-#define CTRL_MIDI_PORT 0x00000060
-#define CTRL_GAME_EN 0x00000008
-#define CTRL_GAME_PORT 0x00000e00
-#define CTRL_IRQ_ENABLE 0x4000
-
-/* write: Timer period config / read: TIMER IRQ ack. */
-#define VORTEX_IRQ_STAT 0x1199c
-
-/* DMA */
-#define VORTEX_DMA_BUFFER 0x10200
-#define VORTEX_ENGINE_CTRL 0x1060c
-#define ENGINE_INIT 0x0L
-
- /* MIDI *//* GAME. */
-#define VORTEX_MIDI_DATA 0x11000
-#define VORTEX_MIDI_CMD 0x11004 /* Write command / Read status */
-#define VORTEX_GAME_LEGACY 0x11008
-#define VORTEX_CTRL2 0x1100c
-#define CTRL2_GAME_ADCMODE 0x40
-#define VORTEX_GAME_AXIS 0x11010
-#define AXIS_SIZE 4
-#define AXIS_RANGE 0x1fff
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au8830.c b/ANDROID_3.4.5/sound/pci/au88x0/au8830.c
deleted file mode 100644
index 279b78f0..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au8830.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "au8830.h"
-#include "au88x0.h"
-static DEFINE_PCI_DEVICE_TABLE(snd_vortex_ids) = {
- {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_2), 0,},
- {0,}
-};
-
-#include "au88x0_synth.c"
-#include "au88x0_core.c"
-#include "au88x0_pcm.c"
-#include "au88x0_mixer.c"
-#include "au88x0_mpu401.c"
-#include "au88x0_game.c"
-#include "au88x0_eq.c"
-#include "au88x0_a3d.c"
-#include "au88x0_xtalk.c"
-#include "au88x0.c"
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au8830.h b/ANDROID_3.4.5/sound/pci/au88x0/au8830.h
deleted file mode 100644
index 999b29ab..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au8830.h
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- Aureal Vortex Soundcard driver.
-
- IO addr collected from asp4core.vxd:
- function address
- 0005D5A0 13004
- 00080674 14004
- 00080AFF 12818
-
- */
-
-#define CHIP_AU8830
-
-#define CARD_NAME "Aureal Vortex 2"
-#define CARD_NAME_SHORT "au8830"
-
-#define NR_ADB 0x20
-#define NR_SRC 0x10
-#define NR_A3D 0x10
-#define NR_MIXIN 0x20
-#define NR_MIXOUT 0x10
-#define NR_WT 0x40
-
-/* ADBDMA */
-#define VORTEX_ADBDMA_STAT 0x27e00 /* read only, subbuffer, DMA pos */
-#define POS_MASK 0x00000fff
-#define POS_SHIFT 0x0
-#define ADB_SUBBUF_MASK 0x00003000 /* ADB only. */
-#define ADB_SUBBUF_SHIFT 0xc /* ADB only. */
-#define VORTEX_ADBDMA_CTRL 0x27a00 /* write only; format, flags, DMA pos */
-#define OFFSET_MASK 0x00000fff
-#define OFFSET_SHIFT 0x0
-#define IE_MASK 0x00001000 /* interrupt enable. */
-#define IE_SHIFT 0xc
-#define DIR_MASK 0x00002000 /* Direction. */
-#define DIR_SHIFT 0xd
-#define FMT_MASK 0x0003c000
-#define FMT_SHIFT 0xe
-#define ADB_FIFO_EN_SHIFT 0x15
-#define ADB_FIFO_EN (1 << 0x15)
-// The ADB masks and shift also are valid for the wtdma, except if specified otherwise.
-#define VORTEX_ADBDMA_BUFCFG0 0x27800
-#define VORTEX_ADBDMA_BUFCFG1 0x27804
-#define VORTEX_ADBDMA_BUFBASE 0x27400
-#define VORTEX_ADBDMA_START 0x27c00 /* Which subbuffer starts */
-
-#define VORTEX_ADBDMA_STATUS 0x27A90 /* stored at AdbDma->this_10 / 2 DWORD in size. */
-/* Starting at the MSB, each pair of bits seem to be the current DMA page. */
-/* This current page bits are consistent (same value) with VORTEX_ADBDMA_STAT) */
-
-/* DMA */
-#define VORTEX_ENGINE_CTRL 0x27ae8
-#define ENGINE_INIT 0x1380000
-
-/* WTDMA */
-#define VORTEX_WTDMA_CTRL 0x27900 /* format, DMA pos */
-#define VORTEX_WTDMA_STAT 0x27d00 /* DMA subbuf, DMA pos */
-#define WT_SUBBUF_MASK 0x3
-#define WT_SUBBUF_SHIFT 0xc
-#define VORTEX_WTDMA_BUFBASE 0x27000
-#define VORTEX_WTDMA_BUFCFG0 0x27600
-#define VORTEX_WTDMA_BUFCFG1 0x27604
-#define VORTEX_WTDMA_START 0x27b00 /* which subbuffer is first */
-
-/* ADB */
-#define VORTEX_ADB_SR 0x28400 /* Samplerates enable/disable */
-#define VORTEX_ADB_RTBASE 0x28000
-#define VORTEX_ADB_RTBASE_COUNT 173
-#define VORTEX_ADB_CHNBASE 0x282b4
-#define VORTEX_ADB_CHNBASE_COUNT 24
-#define ROUTE_MASK 0xffff
-#define SOURCE_MASK 0xff00
-#define ADB_MASK 0xff
-#define ADB_SHIFT 0x8
-/* ADB address */
-#define OFFSET_ADBDMA 0x00
-#define OFFSET_ADBDMAB 0x20
-#define OFFSET_SRCIN 0x40
-#define OFFSET_SRCOUT 0x20 /* ch 0x11 */
-#define OFFSET_MIXIN 0x50 /* ch 0x11 */
-#define OFFSET_MIXOUT 0x30 /* ch 0x11 */
-#define OFFSET_CODECIN 0x70 /* ch 0x11 */ /* adb source */
-#define OFFSET_CODECOUT 0x88 /* ch 0x11 */ /* adb target */
-#define OFFSET_SPORTIN 0x78 /* ch 0x13 ADB source. 2 routes. */
-#define OFFSET_SPORTOUT 0x90 /* ch 0x13 ADB sink. 2 routes. */
-#define OFFSET_SPDIFIN 0x7A /* ch 0x14 ADB source. */
-#define OFFSET_SPDIFOUT 0x92 /* ch 0x14 ADB sink. */
-#define OFFSET_AC98IN 0x7c /* ch 0x14 ADB source. */
-#define OFFSET_AC98OUT 0x94 /* ch 0x14 ADB sink. */
-#define OFFSET_EQIN 0xa0 /* ch 0x11 */
-#define OFFSET_EQOUT 0x7e /* ch 0x11 */ /* 2 routes on ch 0x11 */
-#define OFFSET_A3DIN 0x70 /* ADB sink. */
-#define OFFSET_A3DOUT 0xA6 /* ADB source. 2 routes per slice = 8 */
-#define OFFSET_WT0 0x40 /* WT bank 0 output. 0x40 - 0x65 */
-#define OFFSET_WT1 0x80 /* WT bank 1 output. 0x80 - 0xA5 */
-/* WT sources offset : 0x00-0x1f Direct stream. */
-/* WT sources offset : 0x20-0x25 Mixed Output. */
-#define OFFSET_XTALKOUT 0x66 /* crosstalk canceller (source) 2 routes */
-#define OFFSET_XTALKIN 0x96 /* crosstalk canceller (sink). 10 routes */
-#define OFFSET_EFXOUT 0x68 /* ADB source. 8 routes. */
-#define OFFSET_EFXIN 0x80 /* ADB sink. 8 routes. */
-
-/* ADB route translate helper */
-#define ADB_DMA(x) (x)
-#define ADB_SRCOUT(x) (x + OFFSET_SRCOUT)
-#define ADB_SRCIN(x) (x + OFFSET_SRCIN)
-#define ADB_MIXOUT(x) (x + OFFSET_MIXOUT)
-#define ADB_MIXIN(x) (x + OFFSET_MIXIN)
-#define ADB_CODECIN(x) (x + OFFSET_CODECIN)
-#define ADB_CODECOUT(x) (x + OFFSET_CODECOUT)
-#define ADB_SPORTIN(x) (x + OFFSET_SPORTIN)
-#define ADB_SPORTOUT(x) (x + OFFSET_SPORTOUT)
-#define ADB_SPDIFIN(x) (x + OFFSET_SPDIFIN)
-#define ADB_SPDIFOUT(x) (x + OFFSET_SPDIFOUT)
-#define ADB_EQIN(x) (x + OFFSET_EQIN)
-#define ADB_EQOUT(x) (x + OFFSET_EQOUT)
-#define ADB_A3DOUT(x) (x + OFFSET_A3DOUT) /* 0x10 A3D blocks */
-#define ADB_A3DIN(x) (x + OFFSET_A3DIN)
-//#define ADB_WTOUT(x) ((x<x20)?(x + OFFSET_WT0):(x + OFFSET_WT1))
-#define ADB_WTOUT(x,y) (((x)==0)?((y) + OFFSET_WT0):((y) + OFFSET_WT1))
-#define ADB_XTALKIN(x) ((x) + OFFSET_XTALKIN)
-#define ADB_XTALKOUT(x) ((x) + OFFSET_XTALKOUT)
-
-#define MIX_DEFIGAIN 0x08
-#define MIX_DEFOGAIN 0x08 /* 0x8->6dB (6dB = x4) 16 to 18 bit conversion? */
-
-/* MIXER */
-#define VORTEX_MIXER_SR 0x21f00
-#define VORTEX_MIXER_CLIP 0x21f80
-#define VORTEX_MIXER_CHNBASE 0x21e40
-#define VORTEX_MIXER_RTBASE 0x21e00
-#define MIXER_RTBASE_SIZE 0x38
-#define VORTEX_MIX_ENIN 0x21a00 /* Input enable bits. 4 bits wide. */
-#define VORTEX_MIX_SMP 0x21c00 /* wave data buffers. AU8820: 0x9c00 */
-
-/* MIX */
-#define VORTEX_MIX_INVOL_B 0x20000 /* Input volume current */
-#define VORTEX_MIX_VOL_B 0x20800 /* Output Volume current */
-#define VORTEX_MIX_INVOL_A 0x21000 /* Input Volume target */
-#define VORTEX_MIX_VOL_A 0x21800 /* Output Volume target */
-
-#define VOL_MIN 0x80 /* Input volume when muted. */
-#define VOL_MAX 0x7f /* FIXME: Not confirmed! Just guessed. */
-
-/* SRC */
-#define VORTEX_SRC_CHNBASE 0x26c40
-#define VORTEX_SRC_RTBASE 0x26c00
-#define VORTEX_SRCBLOCK_SR 0x26cc0
-#define VORTEX_SRC_SOURCE 0x26cc4
-#define VORTEX_SRC_SOURCESIZE 0x26cc8
-/* Params
- 0x26e00 : 1 U0
- 0x26e40 : 2 CR
- 0x26e80 : 3 U3
- 0x26ec0 : 4 DRIFT1
- 0x26f00 : 5 U1
- 0x26f40 : 6 DRIFT2
- 0x26f80 : 7 U2 : Target rate, direction
-*/
-
-#define VORTEX_SRC_CONVRATIO 0x26e40
-#define VORTEX_SRC_DRIFT0 0x26e80
-#define VORTEX_SRC_DRIFT1 0x26ec0
-#define VORTEX_SRC_DRIFT2 0x26f40
-#define VORTEX_SRC_U0 0x26e00
-#define U0_SLOWLOCK 0x200
-#define VORTEX_SRC_U1 0x26f00
-#define VORTEX_SRC_U2 0x26f80
-#define VORTEX_SRC_DATA 0x26800 /* 0xc800 */
-#define VORTEX_SRC_DATA0 0x26000
-
-/* FIFO */
-#define VORTEX_FIFO_ADBCTRL 0x16100 /* Control bits. */
-#define VORTEX_FIFO_WTCTRL 0x16000
-#define FIFO_RDONLY 0x00000001
-#define FIFO_CTRL 0x00000002 /* Allow ctrl. ? */
-#define FIFO_VALID 0x00000010
-#define FIFO_EMPTY 0x00000020
-#define FIFO_U0 0x00002000 /* Unknown. */
-#define FIFO_U1 0x00040000
-#define FIFO_SIZE_BITS 6
-#define FIFO_SIZE (1<<(FIFO_SIZE_BITS)) // 0x40
-#define FIFO_MASK (FIFO_SIZE-1) //0x3f /* at shift left 0xc */
-#define FIFO_BITS 0x1c400000
-#define VORTEX_FIFO_ADBDATA 0x14000
-#define VORTEX_FIFO_WTDATA 0x10000
-
-#define VORTEX_FIFO_GIRT 0x17000 /* wt0, wt1, adb */
-#define GIRT_COUNT 3
-
-/* CODEC */
-
-#define VORTEX_CODEC_CHN 0x29080 /* The name "CHN" is wrong. */
-
-#define VORTEX_CODEC_CTRL 0x29184
-#define VORTEX_CODEC_IO 0x29188
-
-#define VORTEX_CODEC_SPORTCTRL 0x2918c
-
-#define VORTEX_CODEC_EN 0x29190
-#define EN_AUDIO0 0x00000300
-#define EN_MODEM 0x00000c00
-#define EN_AUDIO1 0x00003000
-#define EN_SPORT 0x00030000
-#define EN_SPDIF 0x000c0000
-#define EN_CODEC (EN_AUDIO1 | EN_AUDIO0)
-
-#define VORTEX_SPDIF_SMPRATE 0x29194
-
-#define VORTEX_SPDIF_FLAGS 0x2205c
-#define VORTEX_SPDIF_CFG0 0x291D0 /* status data */
-#define VORTEX_SPDIF_CFG1 0x291D4
-
-#define VORTEX_SMP_TIME 0x29198 /* Sample counter/timer */
-#define VORTEX_SMP_TIMER 0x2919c
-#define VORTEX_CODEC2_CTRL 0x291a0
-
-#define VORTEX_MODEM_CTRL 0x291ac
-
-/* IRQ */
-#define VORTEX_IRQ_SOURCE 0x2a000 /* Interrupt source flags. */
-#define VORTEX_IRQ_CTRL 0x2a004 /* Interrupt source mask. */
-
-//#define VORTEX_IRQ_U0 0x2a008 /* ?? */
-#define VORTEX_STAT 0x2a008 /* Some sort of status */
-#define STAT_IRQ 0x00000001 /* This bitis set if the IRQ is valid. */
-
-#define VORTEX_CTRL 0x2a00c
-#define CTRL_MIDI_EN 0x00000001
-#define CTRL_MIDI_PORT 0x00000060
-#define CTRL_GAME_EN 0x00000008
-#define CTRL_GAME_PORT 0x00000e00
-#define CTRL_IRQ_ENABLE 0x00004000
-#define CTRL_SPDIF 0x00000000 /* unknown. Please find this value */
-#define CTRL_SPORT 0x00200000
-#define CTRL_RST 0x00800000
-#define CTRL_UNKNOWN 0x01000000
-
-/* write: Timer period config / read: TIMER IRQ ack. */
-#define VORTEX_IRQ_STAT 0x2919c
-
- /* MIDI *//* GAME. */
-#define VORTEX_MIDI_DATA 0x28800
-#define VORTEX_MIDI_CMD 0x28804 /* Write command / Read status */
-
-#define VORTEX_GAME_LEGACY 0x28808
-#define VORTEX_CTRL2 0x2880c
-#define CTRL2_GAME_ADCMODE 0x40
-#define VORTEX_GAME_AXIS 0x28810 /* Axis base register. 4 axis's */
-#define AXIS_SIZE 4
-#define AXIS_RANGE 0x1fff
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au88x0.c b/ANDROID_3.4.5/sound/pci/au88x0/au88x0.c
deleted file mode 100644
index f13ad536..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au88x0.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * ALSA driver for the Aureal Vortex family of soundprocessors.
- * Author: Manuel Jander (mjander@embedded.cl)
- *
- * This driver is the result of the OpenVortex Project from Savannah
- * (savannah.nongnu.org/projects/openvortex). I would like to thank
- * the developers of OpenVortex, Jeff Muizelaar and Kester Maddock, from
- * whom i got plenty of help, and their codebase was invaluable.
- * Thanks to the ALSA developers, they helped a lot working out
- * the ALSA part.
- * Thanks also to Sourceforge for maintaining the old binary drivers,
- * and the forum, where developers could comunicate.
- *
- * Now at least i can play Legacy DOOM with MIDI music :-)
- */
-
-#include "au88x0.h"
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <sound/initval.h>
-
-// module parameters (see "Module Parameters")
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static int pcifix[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 255 };
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
-module_param_array(pcifix, int, NULL, 0444);
-MODULE_PARM_DESC(pcifix, "Enable VIA-workaround for " CARD_NAME " soundcard.");
-
-MODULE_DESCRIPTION("Aureal vortex");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Aureal Semiconductor Inc., Aureal Vortex Sound Processor}}");
-
-MODULE_DEVICE_TABLE(pci, snd_vortex_ids);
-
-static void vortex_fix_latency(struct pci_dev *vortex)
-{
- int rc;
- if (!(rc = pci_write_config_byte(vortex, 0x40, 0xff))) {
- printk(KERN_INFO CARD_NAME
- ": vortex latency is 0xff\n");
- } else {
- printk(KERN_WARNING CARD_NAME
- ": could not set vortex latency: pci error 0x%x\n", rc);
- }
-}
-
-static void vortex_fix_agp_bridge(struct pci_dev *via)
-{
- int rc;
- u8 value;
-
- /*
- * only set the bit (Extend PCI#2 Internal Master for
- * Efficient Handling of Dummy Requests) if the can
- * read the config and it is not already set
- */
-
- if (!(rc = pci_read_config_byte(via, 0x42, &value))
- && ((value & 0x10)
- || !(rc = pci_write_config_byte(via, 0x42, value | 0x10)))) {
- printk(KERN_INFO CARD_NAME
- ": bridge config is 0x%x\n", value | 0x10);
- } else {
- printk(KERN_WARNING CARD_NAME
- ": could not set vortex latency: pci error 0x%x\n", rc);
- }
-}
-
-static void __devinit snd_vortex_workaround(struct pci_dev *vortex, int fix)
-{
- struct pci_dev *via = NULL;
-
- /* autodetect if workarounds are required */
- if (fix == 255) {
- /* VIA KT133 */
- via = pci_get_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_8365_1, NULL);
- /* VIA Apollo */
- if (via == NULL) {
- via = pci_get_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_82C598_1, NULL);
- /* AMD Irongate */
- if (via == NULL)
- via = pci_get_device(PCI_VENDOR_ID_AMD,
- PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL);
- }
- if (via) {
- printk(KERN_INFO CARD_NAME ": Activating latency workaround...\n");
- vortex_fix_latency(vortex);
- vortex_fix_agp_bridge(via);
- }
- } else {
- if (fix & 0x1)
- vortex_fix_latency(vortex);
- if ((fix & 0x2) && (via = pci_get_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_8365_1, NULL)))
- vortex_fix_agp_bridge(via);
- if ((fix & 0x4) && (via = pci_get_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_82C598_1, NULL)))
- vortex_fix_agp_bridge(via);
- if ((fix & 0x8) && (via = pci_get_device(PCI_VENDOR_ID_AMD,
- PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL)))
- vortex_fix_agp_bridge(via);
- }
- pci_dev_put(via);
-}
-
-// component-destructor
-// (see "Management of Cards and Components")
-static int snd_vortex_dev_free(struct snd_device *device)
-{
- vortex_t *vortex = device->device_data;
-
- vortex_gameport_unregister(vortex);
- vortex_core_shutdown(vortex);
- // Take down PCI interface.
- free_irq(vortex->irq, vortex);
- iounmap(vortex->mmio);
- pci_release_regions(vortex->pci_dev);
- pci_disable_device(vortex->pci_dev);
- kfree(vortex);
-
- return 0;
-}
-
-// chip-specific constructor
-// (see "Management of Cards and Components")
-static int __devinit
-snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
-{
- vortex_t *chip;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_vortex_dev_free,
- };
-
- *rchip = NULL;
-
- // check PCI availability (DMA).
- if ((err = pci_enable_device(pci)) < 0)
- return err;
- if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0) {
- printk(KERN_ERR "error to set DMA mask\n");
- pci_disable_device(pci);
- return -ENXIO;
- }
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- chip->card = card;
-
- // initialize the stuff
- chip->pci_dev = pci;
- chip->io = pci_resource_start(pci, 0);
- chip->vendor = pci->vendor;
- chip->device = pci->device;
- chip->card = card;
- chip->irq = -1;
-
- // (1) PCI resource allocation
- // Get MMIO area
- //
- if ((err = pci_request_regions(pci, CARD_NAME_SHORT)) != 0)
- goto regions_out;
-
- chip->mmio = pci_ioremap_bar(pci, 0);
- if (!chip->mmio) {
- printk(KERN_ERR "MMIO area remap failed.\n");
- err = -ENOMEM;
- goto ioremap_out;
- }
-
- /* Init audio core.
- * This must be done before we do request_irq otherwise we can get spurious
- * interrupts that we do not handle properly and make a mess of things */
- if ((err = vortex_core_init(chip)) != 0) {
- printk(KERN_ERR "hw core init failed\n");
- goto core_out;
- }
-
- if ((err = request_irq(pci->irq, vortex_interrupt,
- IRQF_SHARED, KBUILD_MODNAME,
- chip)) != 0) {
- printk(KERN_ERR "cannot grab irq\n");
- goto irq_out;
- }
- chip->irq = pci->irq;
-
- pci_set_master(pci);
- // End of PCI setup.
-
- // Register alsa root device.
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- goto alloc_out;
- }
-
- snd_card_set_dev(card, &pci->dev);
-
- *rchip = chip;
-
- return 0;
-
- alloc_out:
- free_irq(chip->irq, chip);
- irq_out:
- vortex_core_shutdown(chip);
- core_out:
- iounmap(chip->mmio);
- ioremap_out:
- pci_release_regions(chip->pci_dev);
- regions_out:
- pci_disable_device(chip->pci_dev);
- //FIXME: this not the right place to unregister the gameport
- vortex_gameport_unregister(chip);
- kfree(chip);
- return err;
-}
-
-// constructor -- see "Constructor" sub-section
-static int __devinit
-snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- vortex_t *chip;
- int err;
-
- // (1)
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
- // (2)
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- // (3)
- if ((err = snd_vortex_create(card, pci, &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
- snd_vortex_workaround(pci, pcifix[dev]);
-
- // Card details needed in snd_vortex_midi
- strcpy(card->driver, CARD_NAME_SHORT);
- sprintf(card->shortname, "Aureal Vortex %s", CARD_NAME_SHORT);
- sprintf(card->longname, "%s at 0x%lx irq %i",
- card->shortname, chip->io, chip->irq);
-
- // (4) Alloc components.
- err = snd_vortex_mixer(chip);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- // ADB pcm.
- err = snd_vortex_new_pcm(chip, VORTEX_PCM_ADB, NR_PCM);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-#ifndef CHIP_AU8820
- // ADB SPDIF
- if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_SPDIF, 1)) < 0) {
- snd_card_free(card);
- return err;
- }
- // A3D
- if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_A3D, NR_A3D)) < 0) {
- snd_card_free(card);
- return err;
- }
-#endif
- /*
- // ADB I2S
- if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_I2S, 1)) < 0) {
- snd_card_free(card);
- return err;
- }
- */
-#ifndef CHIP_AU8810
- // WT pcm.
- if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_WT, NR_WT)) < 0) {
- snd_card_free(card);
- return err;
- }
-#endif
- if ((err = snd_vortex_midi(chip)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- vortex_gameport_register(chip);
-
-#if 0
- if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_VORTEX_SYNTH,
- sizeof(snd_vortex_synth_arg_t), &wave) < 0
- || wave == NULL) {
- snd_printk(KERN_ERR "Can't initialize Aureal wavetable synth\n");
- } else {
- snd_vortex_synth_arg_t *arg;
-
- arg = SNDRV_SEQ_DEVICE_ARGPTR(wave);
- strcpy(wave->name, "Aureal Synth");
- arg->hwptr = vortex;
- arg->index = 1;
- arg->seq_ports = seq_ports[dev];
- arg->max_voices = max_synth_voices[dev];
- }
-#endif
-
- // (5)
- if ((err = pci_read_config_word(pci, PCI_DEVICE_ID,
- &(chip->device))) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = pci_read_config_word(pci, PCI_VENDOR_ID,
- &(chip->vendor))) < 0) {
- snd_card_free(card);
- return err;
- }
- chip->rev = pci->revision;
-#ifdef CHIP_AU8830
- if ((chip->rev) != 0xfe && (chip->rev) != 0xfa) {
- printk(KERN_ALERT
- "vortex: The revision (%x) of your card has not been seen before.\n",
- chip->rev);
- printk(KERN_ALERT
- "vortex: Please email the results of 'lspci -vv' to openvortex-dev@nongnu.org.\n");
- snd_card_free(card);
- err = -ENODEV;
- return err;
- }
-#endif
-
- // (6)
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- // (7)
- pci_set_drvdata(pci, card);
- dev++;
- vortex_connect_default(chip, 1);
- vortex_enable_int(chip);
- return 0;
-}
-
-// destructor -- see "Destructor" sub-section
-static void __devexit snd_vortex_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-// pci_driver definition
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_vortex_ids,
- .probe = snd_vortex_probe,
- .remove = __devexit_p(snd_vortex_remove),
-};
-
-// initialization of the module
-static int __init alsa_card_vortex_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-// clean up the module
-static void __exit alsa_card_vortex_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_vortex_init)
-module_exit(alsa_card_vortex_exit)
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au88x0.h b/ANDROID_3.4.5/sound/pci/au88x0/au88x0.h
deleted file mode 100644
index 466a5c8e..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au88x0.h
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __SOUND_AU88X0_H
-#define __SOUND_AU88X0_H
-
-#ifdef __KERNEL__
-#include <linux/pci.h>
-#include <asm/io.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/rawmidi.h>
-#include <sound/mpu401.h>
-#include <sound/hwdep.h>
-#include <sound/ac97_codec.h>
-#include <sound/tlv.h>
-#endif
-
-#ifndef CHIP_AU8820
-#include "au88x0_eq.h"
-#include "au88x0_a3d.h"
-#endif
-#ifndef CHIP_AU8810
-#include "au88x0_wt.h"
-#endif
-
-#define hwread(x,y) readl((x)+(y))
-#define hwwrite(x,y,z) writel((z),(x)+(y))
-
-/* Vortex MPU401 defines. */
-#define MIDI_CLOCK_DIV 0x61
-/* Standart MPU401 defines. */
-#define MPU401_RESET 0xff
-#define MPU401_ENTER_UART 0x3f
-#define MPU401_ACK 0xfe
-
-// Get src register value to convert from x to y.
-#define SRC_RATIO(x,y) ((((x<<15)/y) + 1)/2)
-
-/* FIFO software state constants. */
-#define FIFO_STOP 0
-#define FIFO_START 1
-#define FIFO_PAUSE 2
-
-/* IRQ flags */
-#define IRQ_ERR_MASK 0x00ff
-#define IRQ_FATAL 0x0001
-#define IRQ_PARITY 0x0002
-#define IRQ_REG 0x0004
-#define IRQ_FIFO 0x0008
-#define IRQ_DMA 0x0010
-#define IRQ_PCMOUT 0x0020 /* PCM OUT page crossing */
-#define IRQ_TIMER 0x1000
-#define IRQ_MIDI 0x2000
-#define IRQ_MODEM 0x4000
-
-/* ADB Resource */
-#define VORTEX_RESOURCE_DMA 0x00000000
-#define VORTEX_RESOURCE_SRC 0x00000001
-#define VORTEX_RESOURCE_MIXIN 0x00000002
-#define VORTEX_RESOURCE_MIXOUT 0x00000003
-#define VORTEX_RESOURCE_A3D 0x00000004
-#define VORTEX_RESOURCE_LAST 0x00000005
-
-/* codec io: VORTEX_CODEC_IO bits */
-#define VORTEX_CODEC_ID_SHIFT 24
-#define VORTEX_CODEC_WRITE 0x00800000
-#define VORTEX_CODEC_ADDSHIFT 16
-#define VORTEX_CODEC_ADDMASK 0x7f0000
-#define VORTEX_CODEC_DATSHIFT 0
-#define VORTEX_CODEC_DATMASK 0xffff
-
-/* Check for SDAC bit in "Extended audio ID" AC97 register */
-//#define VORTEX_IS_QUAD(x) (((x)->codec == NULL) ? 0 : ((x)->codec->ext_id&0x80))
-#define VORTEX_IS_QUAD(x) ((x)->isquad)
-/* Check if chip has bug. */
-#define IS_BAD_CHIP(x) (\
- (x->rev == 0xfe && x->device == PCI_DEVICE_ID_AUREAL_VORTEX_2) || \
- (x->rev == 0xfe && x->device == PCI_DEVICE_ID_AUREAL_ADVANTAGE))
-
-
-/* PCM devices */
-#define VORTEX_PCM_ADB 0
-#define VORTEX_PCM_SPDIF 1
-#define VORTEX_PCM_A3D 2
-#define VORTEX_PCM_WT 3
-#define VORTEX_PCM_I2S 4
-#define VORTEX_PCM_LAST 5
-
-#define MIX_CAPT(x) (vortex->mixcapt[x])
-#define MIX_PLAYB(x) (vortex->mixplayb[x])
-#define MIX_SPDIF(x) (vortex->mixspdif[x])
-
-#define NR_WTPB 0x20 /* WT channels per each bank. */
-#define NR_PCM 0x10
-
-struct pcm_vol {
- struct snd_kcontrol *kctl;
- int active;
- int dma;
- int mixin[4];
- int vol[4];
-};
-
-/* Structs */
-typedef struct {
- //int this_08; /* Still unknown */
- int fifo_enabled; /* this_24 */
- int fifo_status; /* this_1c */
- u32 dma_ctrl; /* this_78 (ADB), this_7c (WT) */
- int dma_unknown; /* this_74 (ADB), this_78 (WT). WDM: +8 */
- int cfg0;
- int cfg1;
-
- int nr_ch; /* Nr of PCM channels in use */
- int type; /* Output type (ac97, a3d, spdif, i2s, dsp) */
- int dma; /* Hardware DMA index. */
- int dir; /* Stream Direction. */
- u32 resources[5];
-
- /* Virtual page extender stuff */
- int nr_periods;
- int period_bytes;
- int period_real;
- int period_virt;
-
- struct snd_pcm_substream *substream;
-} stream_t;
-
-typedef struct snd_vortex vortex_t;
-struct snd_vortex {
- /* ALSA structs. */
- struct snd_card *card;
- struct snd_pcm *pcm[VORTEX_PCM_LAST];
-
- struct snd_rawmidi *rmidi; /* Legacy Midi interface. */
- struct snd_ac97 *codec;
-
- /* Stream structs. */
- stream_t dma_adb[NR_ADB];
- int spdif_sr;
-#ifndef CHIP_AU8810
- stream_t dma_wt[NR_WT];
- wt_voice_t wt_voice[NR_WT]; /* WT register cache. */
- char mixwt[(NR_WT / NR_WTPB) * 6]; /* WT mixin objects */
-#endif
-
- /* Global resources */
- s8 mixcapt[2];
- s8 mixplayb[4];
-#ifndef CHIP_AU8820
- s8 mixspdif[2];
- s8 mixa3d[2]; /* mixers which collect all a3d streams. */
- s8 mixxtlk[2]; /* crosstalk canceler mixer inputs. */
-#endif
- u32 fixed_res[5];
-
-#ifndef CHIP_AU8820
- /* Hardware equalizer structs */
- eqlzr_t eq;
- /* A3D structs */
- a3dsrc_t a3d[NR_A3D];
- /* Xtalk canceler */
- int xt_mode; /* 1: speakers, 0:headphones. */
-#endif
- struct pcm_vol pcm_vol[NR_PCM];
-
- int isquad; /* cache of extended ID codec flag. */
-
- /* Gameport stuff. */
- struct gameport *gameport;
-
- /* PCI hardware resources */
- unsigned long io;
- void __iomem *mmio;
- unsigned int irq;
- spinlock_t lock;
-
- /* PCI device */
- struct pci_dev *pci_dev;
- u16 vendor;
- u16 device;
- u8 rev;
-};
-
-/* Functions. */
-
-/* SRC */
-static void vortex_adb_setsrc(vortex_t * vortex, int adbdma,
- unsigned int cvrt, int dir);
-
-/* DMA Engines. */
-static void vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma,
- int size, int count);
-static void vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie,
- int dir, int fmt, int d,
- u32 offset);
-static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb);
-#ifndef CHIP_AU8810
-static void vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,
- int size, int count);
-static void vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d, /*int e, */
- u32 offset);
-static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb);
-#endif
-
-static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma);
-//static void vortex_adbdma_stopfifo(vortex_t *vortex, int adbdma);
-static void vortex_adbdma_pausefifo(vortex_t * vortex, int adbdma);
-static void vortex_adbdma_resumefifo(vortex_t * vortex, int adbdma);
-static inline int vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma);
-static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma);
-
-#ifndef CHIP_AU8810
-static void vortex_wtdma_startfifo(vortex_t * vortex, int wtdma);
-static void vortex_wtdma_stopfifo(vortex_t * vortex, int wtdma);
-static void vortex_wtdma_pausefifo(vortex_t * vortex, int wtdma);
-static void vortex_wtdma_resumefifo(vortex_t * vortex, int wtdma);
-static inline int vortex_wtdma_getlinearpos(vortex_t * vortex, int wtdma);
-#endif
-
-/* global stuff. */
-static void vortex_codec_init(vortex_t * vortex);
-static void vortex_codec_write(struct snd_ac97 * codec, unsigned short addr,
- unsigned short data);
-static unsigned short vortex_codec_read(struct snd_ac97 * codec, unsigned short addr);
-static void vortex_spdif_init(vortex_t * vortex, int spdif_sr, int spdif_mode);
-
-static int vortex_core_init(vortex_t * card);
-static int vortex_core_shutdown(vortex_t * card);
-static void vortex_enable_int(vortex_t * card);
-static irqreturn_t vortex_interrupt(int irq, void *dev_id);
-static int vortex_alsafmt_aspfmt(int alsafmt);
-
-/* Connection stuff. */
-static void vortex_connect_default(vortex_t * vortex, int en);
-static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch,
- int dir, int type, int subdev);
-static char vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out,
- int restype);
-#ifndef CHIP_AU8810
-static int vortex_wt_allocroute(vortex_t * vortex, int dma, int nr_ch);
-static void vortex_wt_connect(vortex_t * vortex, int en);
-static void vortex_wt_init(vortex_t * vortex);
-#endif
-
-static void vortex_route(vortex_t * vortex, int en, unsigned char channel,
- unsigned char source, unsigned char dest);
-#if 0
-static void vortex_routes(vortex_t * vortex, int en, unsigned char channel,
- unsigned char source, unsigned char dest0,
- unsigned char dest1);
-#endif
-static void vortex_connection_mixin_mix(vortex_t * vortex, int en,
- unsigned char mixin,
- unsigned char mix, int a);
-static void vortex_mix_setinputvolumebyte(vortex_t * vortex,
- unsigned char mix, int mixin,
- unsigned char vol);
-static void vortex_mix_setvolumebyte(vortex_t * vortex, unsigned char mix,
- unsigned char vol);
-
-/* A3D functions. */
-#ifndef CHIP_AU8820
-static void vortex_Vort3D_enable(vortex_t * v);
-static void vortex_Vort3D_disable(vortex_t * v);
-static void vortex_Vort3D_connect(vortex_t * vortex, int en);
-static void vortex_Vort3D_InitializeSource(a3dsrc_t * a, int en);
-#endif
-
-/* Driver stuff. */
-static int vortex_gameport_register(vortex_t * card);
-static void vortex_gameport_unregister(vortex_t * card);
-#ifndef CHIP_AU8820
-static int vortex_eq_init(vortex_t * vortex);
-static int vortex_eq_free(vortex_t * vortex);
-#endif
-/* ALSA stuff. */
-static int snd_vortex_new_pcm(vortex_t * vortex, int idx, int nr);
-static int snd_vortex_mixer(vortex_t * vortex);
-static int snd_vortex_midi(vortex_t * vortex);
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_a3d.c b/ANDROID_3.4.5/sound/pci/au88x0/au88x0_a3d.c
deleted file mode 100644
index 9ae8b3b1..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_a3d.c
+++ /dev/null
@@ -1,914 +0,0 @@
-/***************************************************************************
- * au88x0_a3d.c
- *
- * Fri Jul 18 14:16:22 2003
- * Copyright 2003 mjander
- * mjander@users.sourceforge.net
- *
- * A3D. You may think i'm crazy, but this may work someday. Who knows...
- ****************************************************************************/
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include "au88x0_a3d.h"
-#include "au88x0_a3ddata.c"
-#include "au88x0_xtalk.h"
-#include "au88x0.h"
-
-static void
-a3dsrc_SetTimeConsts(a3dsrc_t * a, short HrtfTrack, short ItdTrack,
- short GTrack, short CTrack)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- hwwrite(vortex->mmio,
- a3d_addrA(a->slice, a->source, A3D_A_HrtfTrackTC), HrtfTrack);
- hwwrite(vortex->mmio,
- a3d_addrA(a->slice, a->source, A3D_A_ITDTrackTC), ItdTrack);
- hwwrite(vortex->mmio,
- a3d_addrA(a->slice, a->source, A3D_A_GainTrackTC), GTrack);
- hwwrite(vortex->mmio,
- a3d_addrA(a->slice, a->source, A3D_A_CoeffTrackTC), CTrack);
-}
-
-#if 0
-static void
-a3dsrc_GetTimeConsts(a3dsrc_t * a, short *HrtfTrack, short *ItdTrack,
- short *GTrack, short *CTrack)
-{
- // stub!
-}
-
-#endif
-/* Atmospheric absorption. */
-
-static void
-a3dsrc_SetAtmosTarget(a3dsrc_t * a, short aa, short b, short c, short d,
- short e)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- hwwrite(vortex->mmio,
- a3d_addrB(a->slice, a->source, A3D_B_A21Target),
- (e << 0x10) | d);
- hwwrite(vortex->mmio,
- a3d_addrB(a->slice, a->source, A3D_B_B10Target),
- (b << 0x10) | aa);
- hwwrite(vortex->mmio,
- a3d_addrB(a->slice, a->source, A3D_B_B2Target), c);
-}
-
-static void
-a3dsrc_SetAtmosCurrent(a3dsrc_t * a, short aa, short b, short c, short d,
- short e)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- hwwrite(vortex->mmio,
- a3d_addrB(a->slice, a->source, A3D_B_A12Current),
- (e << 0x10) | d);
- hwwrite(vortex->mmio,
- a3d_addrB(a->slice, a->source, A3D_B_B01Current),
- (b << 0x10) | aa);
- hwwrite(vortex->mmio,
- a3d_addrB(a->slice, a->source, A3D_B_B2Current), c);
-}
-
-static void
-a3dsrc_SetAtmosState(a3dsrc_t * a, short x1, short x2, short y1, short y2)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- hwwrite(vortex->mmio, a3d_addrA(a->slice, a->source, A3D_A_x1), x1);
- hwwrite(vortex->mmio, a3d_addrA(a->slice, a->source, A3D_A_x2), x2);
- hwwrite(vortex->mmio, a3d_addrA(a->slice, a->source, A3D_A_y1), y1);
- hwwrite(vortex->mmio, a3d_addrA(a->slice, a->source, A3D_A_y2), y2);
-}
-
-#if 0
-static void
-a3dsrc_GetAtmosTarget(a3dsrc_t * a, short *aa, short *b, short *c,
- short *d, short *e)
-{
-}
-static void
-a3dsrc_GetAtmosCurrent(a3dsrc_t * a, short *bb01, short *ab01, short *b2,
- short *aa12, short *ba12)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- *aa12 =
- hwread(vortex->mmio,
- a3d_addrA(a->slice, a->source, A3D_A_A12Current));
- *ba12 =
- hwread(vortex->mmio,
- a3d_addrB(a->slice, a->source, A3D_B_A12Current));
- *ab01 =
- hwread(vortex->mmio,
- a3d_addrA(a->slice, a->source, A3D_A_B01Current));
- *bb01 =
- hwread(vortex->mmio,
- a3d_addrB(a->slice, a->source, A3D_B_B01Current));
- *b2 =
- hwread(vortex->mmio,
- a3d_addrA(a->slice, a->source, A3D_A_B2Current));
-}
-
-static void
-a3dsrc_GetAtmosState(a3dsrc_t * a, short *x1, short *x2, short *y1, short *y2)
-{
-
-}
-
-#endif
-/* HRTF */
-
-static void
-a3dsrc_SetHrtfTarget(a3dsrc_t * a, a3d_Hrtf_t const aa, a3d_Hrtf_t const b)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- int i;
-
- for (i = 0; i < HRTF_SZ; i++)
- hwwrite(vortex->mmio,
- a3d_addrB(a->slice, a->source,
- A3D_B_HrtfTarget) + (i << 2),
- (b[i] << 0x10) | aa[i]);
-}
-
-static void
-a3dsrc_SetHrtfCurrent(a3dsrc_t * a, a3d_Hrtf_t const aa, a3d_Hrtf_t const b)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- int i;
-
- for (i = 0; i < HRTF_SZ; i++)
- hwwrite(vortex->mmio,
- a3d_addrB(a->slice, a->source,
- A3D_B_HrtfCurrent) + (i << 2),
- (b[i] << 0x10) | aa[i]);
-}
-
-static void
-a3dsrc_SetHrtfState(a3dsrc_t * a, a3d_Hrtf_t const aa, a3d_Hrtf_t const b)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- int i;
-
- for (i = 0; i < HRTF_SZ; i++)
- hwwrite(vortex->mmio,
- a3d_addrB(a->slice, a->source,
- A3D_B_HrtfDelayLine) + (i << 2),
- (b[i] << 0x10) | aa[i]);
-}
-
-static void a3dsrc_SetHrtfOutput(a3dsrc_t * a, short left, short right)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- hwwrite(vortex->mmio,
- a3d_addrA(a->slice, a->source, A3D_A_HrtfOutL), left);
- hwwrite(vortex->mmio,
- a3d_addrA(a->slice, a->source, A3D_A_HrtfOutR), right);
-}
-
-#if 0
-static void a3dsrc_GetHrtfTarget(a3dsrc_t * a, a3d_Hrtf_t aa, a3d_Hrtf_t b)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- int i;
-
- for (i = 0; i < HRTF_SZ; i++)
- aa[i] =
- hwread(vortex->mmio,
- a3d_addrA(a->slice, a->source,
- A3D_A_HrtfTarget + (i << 2)));
- for (i = 0; i < HRTF_SZ; i++)
- b[i] =
- hwread(vortex->mmio,
- a3d_addrB(a->slice, a->source,
- A3D_B_HrtfTarget + (i << 2)));
-}
-
-static void a3dsrc_GetHrtfCurrent(a3dsrc_t * a, a3d_Hrtf_t aa, a3d_Hrtf_t b)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- int i;
-
- for (i = 0; i < HRTF_SZ; i++)
- aa[i] =
- hwread(vortex->mmio,
- a3d_addrA(a->slice, a->source,
- A3D_A_HrtfCurrent + (i << 2)));
- for (i = 0; i < HRTF_SZ; i++)
- b[i] =
- hwread(vortex->mmio,
- a3d_addrB(a->slice, a->source,
- A3D_B_HrtfCurrent + (i << 2)));
-}
-
-static void a3dsrc_GetHrtfState(a3dsrc_t * a, a3d_Hrtf_t aa, a3d_Hrtf_t b)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- int i;
- // FIXME: verify this!
- for (i = 0; i < HRTF_SZ; i++)
- aa[i] =
- hwread(vortex->mmio,
- a3d_addrA(a->slice, a->source,
- A3D_A_HrtfDelayLine + (i << 2)));
- for (i = 0; i < HRTF_SZ; i++)
- b[i] =
- hwread(vortex->mmio,
- a3d_addrB(a->slice, a->source,
- A3D_B_HrtfDelayLine + (i << 2)));
-}
-
-static void a3dsrc_GetHrtfOutput(a3dsrc_t * a, short *left, short *right)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- *left =
- hwread(vortex->mmio,
- a3d_addrA(a->slice, a->source, A3D_A_HrtfOutL));
- *right =
- hwread(vortex->mmio,
- a3d_addrA(a->slice, a->source, A3D_A_HrtfOutR));
-}
-
-#endif
-
-/* Interaural Time Difference.
- * "The other main clue that humans use to locate sounds, is called
- * Interaural Time Difference (ITD). The differences in distance from
- * the sound source to a listeners ears means that the sound will
- * reach one ear slightly before the other....", found somewhere with google.*/
-static void a3dsrc_SetItdTarget(a3dsrc_t * a, short litd, short ritd)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
-
- if (litd < 0)
- litd = 0;
- if (litd > 0x57FF)
- litd = 0x57FF;
- if (ritd < 0)
- ritd = 0;
- if (ritd > 0x57FF)
- ritd = 0x57FF;
- hwwrite(vortex->mmio,
- a3d_addrB(a->slice, a->source, A3D_B_ITDTarget),
- (ritd << 0x10) | litd);
- //hwwrite(vortex->mmio, addr(0x191DF+5, this04, this08), (ritd<<0x10)|litd);
-}
-
-static void a3dsrc_SetItdCurrent(a3dsrc_t * a, short litd, short ritd)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
-
- if (litd < 0)
- litd = 0;
- if (litd > 0x57FF)
- litd = 0x57FF;
- if (ritd < 0)
- ritd = 0;
- if (ritd > 0x57FF)
- ritd = 0x57FF;
- hwwrite(vortex->mmio,
- a3d_addrB(a->slice, a->source, A3D_B_ITDCurrent),
- (ritd << 0x10) | litd);
- //hwwrite(vortex->mmio, addr(0x191DF+1, this04, this08), (ritd<<0x10)|litd);
-}
-
-static void a3dsrc_SetItdDline(a3dsrc_t * a, a3d_ItdDline_t const dline)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- int i;
- /* 45 != 40 -> Check this ! */
- for (i = 0; i < DLINE_SZ; i++)
- hwwrite(vortex->mmio,
- a3d_addrA(a->slice, a->source,
- A3D_A_ITDDelayLine) + (i << 2), dline[i]);
-}
-
-#if 0
-static void a3dsrc_GetItdTarget(a3dsrc_t * a, short *litd, short *ritd)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- *ritd =
- hwread(vortex->mmio,
- a3d_addrA(a->slice, a->source, A3D_A_ITDTarget));
- *litd =
- hwread(vortex->mmio,
- a3d_addrB(a->slice, a->source, A3D_B_ITDTarget));
-}
-
-static void a3dsrc_GetItdCurrent(a3dsrc_t * a, short *litd, short *ritd)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
-
- *ritd =
- hwread(vortex->mmio,
- a3d_addrA(a->slice, a->source, A3D_A_ITDCurrent));
- *litd =
- hwread(vortex->mmio,
- a3d_addrB(a->slice, a->source, A3D_B_ITDCurrent));
-}
-
-static void a3dsrc_GetItdDline(a3dsrc_t * a, a3d_ItdDline_t dline)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- int i;
-
- for (i = 0; i < DLINE_SZ; i++)
- dline[i] =
- hwread(vortex->mmio,
- a3d_addrA(a->slice, a->source,
- A3D_A_ITDDelayLine + (i << 2)));
-}
-
-#endif
-/* This is may be used for ILD Interaural Level Difference. */
-
-static void a3dsrc_SetGainTarget(a3dsrc_t * a, short left, short right)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- hwwrite(vortex->mmio,
- a3d_addrB(a->slice, a->source, A3D_B_GainTarget),
- (right << 0x10) | left);
-}
-
-static void a3dsrc_SetGainCurrent(a3dsrc_t * a, short left, short right)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- hwwrite(vortex->mmio,
- a3d_addrB(a->slice, a->source, A3D_B_GainCurrent),
- (right << 0x10) | left);
-}
-
-#if 0
-static void a3dsrc_GetGainTarget(a3dsrc_t * a, short *left, short *right)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- *right =
- hwread(vortex->mmio,
- a3d_addrA(a->slice, a->source, A3D_A_GainTarget));
- *left =
- hwread(vortex->mmio,
- a3d_addrB(a->slice, a->source, A3D_B_GainTarget));
-}
-
-static void a3dsrc_GetGainCurrent(a3dsrc_t * a, short *left, short *right)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- *right =
- hwread(vortex->mmio,
- a3d_addrA(a->slice, a->source, A3D_A_GainCurrent));
- *left =
- hwread(vortex->mmio,
- a3d_addrB(a->slice, a->source, A3D_B_GainCurrent));
-}
-
-/* CA3dIO this func seems to be inlined all over this place. */
-static void CA3dIO_WriteReg(a3dsrc_t * a, unsigned long addr, short aa, short b)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- hwwrite(vortex->mmio, addr, (aa << 0x10) | b);
-}
-
-#endif
-/* Generic A3D stuff */
-
-static void a3dsrc_SetA3DSampleRate(a3dsrc_t * a, int sr)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- int esp0 = 0;
-
- esp0 = (((esp0 & 0x7fffffff) | 0xB8000000) & 0x7) | ((sr & 0x1f) << 3);
- hwwrite(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd), esp0);
- //hwwrite(vortex->mmio, 0x19C38 + (this08<<0xd), esp0);
-}
-
-static void a3dsrc_EnableA3D(a3dsrc_t * a)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- hwwrite(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd),
- 0xF0000001);
- //hwwrite(vortex->mmio, 0x19C38 + (this08<<0xd), 0xF0000001);
-}
-
-static void a3dsrc_DisableA3D(a3dsrc_t * a)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- hwwrite(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd),
- 0xF0000000);
-}
-
-static void a3dsrc_SetA3DControlReg(a3dsrc_t * a, unsigned long ctrl)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- hwwrite(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd), ctrl);
-}
-
-static void a3dsrc_SetA3DPointerReg(a3dsrc_t * a, unsigned long ptr)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- hwwrite(vortex->mmio, A3D_SLICE_Pointers + ((a->slice) << 0xd), ptr);
-}
-
-#if 0
-static void a3dsrc_GetA3DSampleRate(a3dsrc_t * a, int *sr)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- *sr = ((hwread(vortex->mmio, A3D_SLICE_Control + (a->slice << 0xd))
- >> 3) & 0x1f);
- //*sr = ((hwread(vortex->mmio, 0x19C38 + (this08<<0xd))>>3)&0x1f);
-}
-
-static void a3dsrc_GetA3DControlReg(a3dsrc_t * a, unsigned long *ctrl)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- *ctrl = hwread(vortex->mmio, A3D_SLICE_Control + ((a->slice) << 0xd));
-}
-
-static void a3dsrc_GetA3DPointerReg(a3dsrc_t * a, unsigned long *ptr)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- *ptr = hwread(vortex->mmio, A3D_SLICE_Pointers + ((a->slice) << 0xd));
-}
-
-#endif
-static void a3dsrc_ZeroSliceIO(a3dsrc_t * a)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
- int i;
-
- for (i = 0; i < 8; i++)
- hwwrite(vortex->mmio,
- A3D_SLICE_VDBDest +
- ((((a->slice) << 0xb) + i) << 2), 0);
- for (i = 0; i < 4; i++)
- hwwrite(vortex->mmio,
- A3D_SLICE_VDBSource +
- ((((a->slice) << 0xb) + i) << 2), 0);
-}
-
-/* Reset Single A3D source. */
-static void a3dsrc_ZeroState(a3dsrc_t * a)
-{
- /*
- printk(KERN_DEBUG "vortex: ZeroState slice: %d, source %d\n",
- a->slice, a->source);
- */
- a3dsrc_SetAtmosState(a, 0, 0, 0, 0);
- a3dsrc_SetHrtfState(a, A3dHrirZeros, A3dHrirZeros);
- a3dsrc_SetItdDline(a, A3dItdDlineZeros);
- a3dsrc_SetHrtfOutput(a, 0, 0);
- a3dsrc_SetTimeConsts(a, 0, 0, 0, 0);
-
- a3dsrc_SetAtmosCurrent(a, 0, 0, 0, 0, 0);
- a3dsrc_SetAtmosTarget(a, 0, 0, 0, 0, 0);
- a3dsrc_SetItdCurrent(a, 0, 0);
- a3dsrc_SetItdTarget(a, 0, 0);
- a3dsrc_SetGainCurrent(a, 0, 0);
- a3dsrc_SetGainTarget(a, 0, 0);
-
- a3dsrc_SetHrtfCurrent(a, A3dHrirZeros, A3dHrirZeros);
- a3dsrc_SetHrtfTarget(a, A3dHrirZeros, A3dHrirZeros);
-}
-
-/* Reset entire A3D engine */
-static void a3dsrc_ZeroStateA3D(a3dsrc_t * a)
-{
- int i, var, var2;
-
- if ((a->vortex) == NULL) {
- printk(KERN_ERR "vortex: ZeroStateA3D: ERROR: a->vortex is NULL\n");
- return;
- }
-
- a3dsrc_SetA3DControlReg(a, 0);
- a3dsrc_SetA3DPointerReg(a, 0);
-
- var = a->slice;
- var2 = a->source;
- for (i = 0; i < 4; i++) {
- a->slice = i;
- a3dsrc_ZeroSliceIO(a);
- //a3dsrc_ZeroState(a);
- }
- a->source = var2;
- a->slice = var;
-}
-
-/* Program A3D block as pass through */
-static void a3dsrc_ProgramPipe(a3dsrc_t * a)
-{
- a3dsrc_SetTimeConsts(a, 0, 0, 0, 0);
- a3dsrc_SetAtmosCurrent(a, 0, 0x4000, 0, 0, 0);
- a3dsrc_SetAtmosTarget(a, 0x4000, 0, 0, 0, 0);
- a3dsrc_SetItdCurrent(a, 0, 0);
- a3dsrc_SetItdTarget(a, 0, 0);
- a3dsrc_SetGainCurrent(a, 0x7fff, 0x7fff);
- a3dsrc_SetGainTarget(a, 0x7fff, 0x7fff);
-
- /* SET HRTF HERE */
-
- /* Single spike leads to identity transfer function. */
- a3dsrc_SetHrtfCurrent(a, A3dHrirImpulse, A3dHrirImpulse);
- a3dsrc_SetHrtfTarget(a, A3dHrirImpulse, A3dHrirImpulse);
-
- /* Test: Sounds saturated. */
- //a3dsrc_SetHrtfCurrent(a, A3dHrirSatTest, A3dHrirSatTest);
- //a3dsrc_SetHrtfTarget(a, A3dHrirSatTest, A3dHrirSatTest);
-}
-
-/* VDB = Vortex audio Dataflow Bus */
-#if 0
-static void a3dsrc_ClearVDBData(a3dsrc_t * a, unsigned long aa)
-{
- vortex_t *vortex = (vortex_t *) (a->vortex);
-
- // ((aa >> 2) << 8) - (aa >> 2)
- hwwrite(vortex->mmio,
- a3d_addrS(a->slice, A3D_SLICE_VDBDest) + (a->source << 2), 0);
- hwwrite(vortex->mmio,
- a3d_addrS(a->slice,
- A3D_SLICE_VDBDest + 4) + (a->source << 2), 0);
- /*
- hwwrite(vortex->mmio, 0x19c00 + (((aa>>2)*255*4)+aa)*8, 0);
- hwwrite(vortex->mmio, 0x19c04 + (((aa>>2)*255*4)+aa)*8, 0);
- */
-}
-#endif
-
-/* A3D HwSource stuff. */
-
-static void vortex_A3dSourceHw_Initialize(vortex_t * v, int source, int slice)
-{
- a3dsrc_t *a3dsrc = &(v->a3d[source + (slice * 4)]);
- //a3dsrc_t *a3dsrc = &(v->a3d[source + (slice*4)]);
-
- a3dsrc->vortex = (void *)v;
- a3dsrc->source = source; /* source */
- a3dsrc->slice = slice; /* slice */
- a3dsrc_ZeroState(a3dsrc);
- /* Added by me. */
- a3dsrc_SetA3DSampleRate(a3dsrc, 0x11);
-}
-
-static int Vort3DRend_Initialize(vortex_t * v, unsigned short mode)
-{
- v->xt_mode = mode; /* this_14 */
-
- vortex_XtalkHw_init(v);
- vortex_XtalkHw_SetGainsAllChan(v);
- switch (v->xt_mode) {
- case XT_SPEAKER0:
- vortex_XtalkHw_ProgramXtalkNarrow(v);
- break;
- case XT_SPEAKER1:
- vortex_XtalkHw_ProgramXtalkWide(v);
- break;
- default:
- case XT_HEADPHONE:
- vortex_XtalkHw_ProgramPipe(v);
- break;
- case XT_DIAMOND:
- vortex_XtalkHw_ProgramDiamondXtalk(v);
- break;
- }
- vortex_XtalkHw_SetSampleRate(v, 0x11);
- vortex_XtalkHw_Enable(v);
- return 0;
-}
-
-/* 3D Sound entry points. */
-
-static int vortex_a3d_register_controls(vortex_t * vortex);
-static void vortex_a3d_unregister_controls(vortex_t * vortex);
-/* A3D base support init/shudown */
-static void __devinit vortex_Vort3D_enable(vortex_t * v)
-{
- int i;
-
- Vort3DRend_Initialize(v, XT_HEADPHONE);
- for (i = 0; i < NR_A3D; i++) {
- vortex_A3dSourceHw_Initialize(v, i % 4, i >> 2);
- a3dsrc_ZeroStateA3D(&(v->a3d[0]));
- }
- /* Register ALSA controls */
- vortex_a3d_register_controls(v);
-}
-
-static void vortex_Vort3D_disable(vortex_t * v)
-{
- vortex_XtalkHw_Disable(v);
- vortex_a3d_unregister_controls(v);
-}
-
-/* Make A3D subsystem connections. */
-static void vortex_Vort3D_connect(vortex_t * v, int en)
-{
- int i;
-
-// Disable AU8810 routes, since they seem to be wrong (in au8810.h).
-#ifdef CHIP_AU8810
- return;
-#endif
-
-#if 1
- /* Alloc Xtalk mixin resources */
- v->mixxtlk[0] =
- vortex_adb_checkinout(v, v->fixed_res, en, VORTEX_RESOURCE_MIXIN);
- if (v->mixxtlk[0] < 0) {
- printk
- ("vortex: vortex_Vort3D: ERROR: not enough free mixer resources.\n");
- return;
- }
- v->mixxtlk[1] =
- vortex_adb_checkinout(v, v->fixed_res, en, VORTEX_RESOURCE_MIXIN);
- if (v->mixxtlk[1] < 0) {
- printk
- ("vortex: vortex_Vort3D: ERROR: not enough free mixer resources.\n");
- return;
- }
-#endif
-
- /* Connect A3D -> XTALK */
- for (i = 0; i < 4; i++) {
- // 2 outputs per each A3D slice.
- vortex_route(v, en, 0x11, ADB_A3DOUT(i * 2), ADB_XTALKIN(i));
- vortex_route(v, en, 0x11, ADB_A3DOUT(i * 2) + 1, ADB_XTALKIN(5 + i));
- }
-#if 0
- vortex_route(v, en, 0x11, ADB_XTALKOUT(0), ADB_EQIN(2));
- vortex_route(v, en, 0x11, ADB_XTALKOUT(1), ADB_EQIN(3));
-#else
- /* Connect XTalk -> mixer */
- vortex_route(v, en, 0x11, ADB_XTALKOUT(0), ADB_MIXIN(v->mixxtlk[0]));
- vortex_route(v, en, 0x11, ADB_XTALKOUT(1), ADB_MIXIN(v->mixxtlk[1]));
- vortex_connection_mixin_mix(v, en, v->mixxtlk[0], v->mixplayb[0], 0);
- vortex_connection_mixin_mix(v, en, v->mixxtlk[1], v->mixplayb[1], 0);
- vortex_mix_setinputvolumebyte(v, v->mixplayb[0], v->mixxtlk[0],
- en ? MIX_DEFIGAIN : VOL_MIN);
- vortex_mix_setinputvolumebyte(v, v->mixplayb[1], v->mixxtlk[1],
- en ? MIX_DEFIGAIN : VOL_MIN);
- if (VORTEX_IS_QUAD(v)) {
- vortex_connection_mixin_mix(v, en, v->mixxtlk[0],
- v->mixplayb[2], 0);
- vortex_connection_mixin_mix(v, en, v->mixxtlk[1],
- v->mixplayb[3], 0);
- vortex_mix_setinputvolumebyte(v, v->mixplayb[2],
- v->mixxtlk[0],
- en ? MIX_DEFIGAIN : VOL_MIN);
- vortex_mix_setinputvolumebyte(v, v->mixplayb[3],
- v->mixxtlk[1],
- en ? MIX_DEFIGAIN : VOL_MIN);
- }
-#endif
-}
-
-/* Initialize one single A3D source. */
-static void vortex_Vort3D_InitializeSource(a3dsrc_t * a, int en)
-{
- if (a->vortex == NULL) {
- printk
- ("vortex: Vort3D_InitializeSource: A3D source not initialized\n");
- return;
- }
- if (en) {
- a3dsrc_ProgramPipe(a);
- a3dsrc_SetA3DSampleRate(a, 0x11);
- a3dsrc_SetTimeConsts(a, HrtfTCDefault,
- ItdTCDefault, GainTCDefault,
- CoefTCDefault);
- /* Remark: zero gain is muted. */
- //a3dsrc_SetGainTarget(a,0,0);
- //a3dsrc_SetGainCurrent(a,0,0);
- a3dsrc_EnableA3D(a);
- } else {
- a3dsrc_DisableA3D(a);
- a3dsrc_ZeroState(a);
- }
-}
-
-/* Conversion of coordinates into 3D parameters. */
-
-static void vortex_a3d_coord2hrtf(a3d_Hrtf_t hrtf, int *coord)
-{
- /* FIXME: implement this. */
-
-}
-static void vortex_a3d_coord2itd(a3d_Itd_t itd, int *coord)
-{
- /* FIXME: implement this. */
-
-}
-static void vortex_a3d_coord2ild(a3d_LRGains_t ild, int left, int right)
-{
- /* FIXME: implement this. */
-
-}
-static void vortex_a3d_translate_filter(a3d_atmos_t filter, int *params)
-{
- /* FIXME: implement this. */
-
-}
-
-/* ALSA control interface. */
-
-static int
-snd_vortex_a3d_hrtf_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 6;
- uinfo->value.integer.min = 0x00000000;
- uinfo->value.integer.max = 0xffffffff;
- return 0;
-}
-static int
-snd_vortex_a3d_itd_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0x00000000;
- uinfo->value.integer.max = 0xffffffff;
- return 0;
-}
-static int
-snd_vortex_a3d_ild_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0x00000000;
- uinfo->value.integer.max = 0xffffffff;
- return 0;
-}
-static int
-snd_vortex_a3d_filter_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 4;
- uinfo->value.integer.min = 0x00000000;
- uinfo->value.integer.max = 0xffffffff;
- return 0;
-}
-
-static int
-snd_vortex_a3d_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- //a3dsrc_t *a = kcontrol->private_data;
- /* No read yet. Would this be really useable/needed ? */
-
- return 0;
-}
-
-static int
-snd_vortex_a3d_hrtf_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- a3dsrc_t *a = kcontrol->private_data;
- int changed = 1, i;
- int coord[6];
- for (i = 0; i < 6; i++)
- coord[i] = ucontrol->value.integer.value[i];
- /* Translate orientation coordinates to a3d params. */
- vortex_a3d_coord2hrtf(a->hrtf[0], coord);
- vortex_a3d_coord2hrtf(a->hrtf[1], coord);
- a3dsrc_SetHrtfTarget(a, a->hrtf[0], a->hrtf[1]);
- a3dsrc_SetHrtfCurrent(a, a->hrtf[0], a->hrtf[1]);
- return changed;
-}
-
-static int
-snd_vortex_a3d_itd_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- a3dsrc_t *a = kcontrol->private_data;
- int coord[6];
- int i, changed = 1;
- for (i = 0; i < 6; i++)
- coord[i] = ucontrol->value.integer.value[i];
- /* Translate orientation coordinates to a3d params. */
- vortex_a3d_coord2itd(a->hrtf[0], coord);
- vortex_a3d_coord2itd(a->hrtf[1], coord);
- /* Inter aural time difference. */
- a3dsrc_SetItdTarget(a, a->itd[0], a->itd[1]);
- a3dsrc_SetItdCurrent(a, a->itd[0], a->itd[1]);
- a3dsrc_SetItdDline(a, a->dline);
- return changed;
-}
-
-static int
-snd_vortex_a3d_ild_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- a3dsrc_t *a = kcontrol->private_data;
- int changed = 1;
- int l, r;
- /* There may be some scale tranlation needed here. */
- l = ucontrol->value.integer.value[0];
- r = ucontrol->value.integer.value[1];
- vortex_a3d_coord2ild(a->ild, l, r);
- /* Left Right panning. */
- a3dsrc_SetGainTarget(a, l, r);
- a3dsrc_SetGainCurrent(a, l, r);
- return changed;
-}
-
-static int
-snd_vortex_a3d_filter_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- a3dsrc_t *a = kcontrol->private_data;
- int i, changed = 1;
- int params[6];
- for (i = 0; i < 6; i++)
- params[i] = ucontrol->value.integer.value[i];
- /* Translate generic filter params to a3d filter params. */
- vortex_a3d_translate_filter(a->filter, params);
- /* Atmospheric absorption and filtering. */
- a3dsrc_SetAtmosTarget(a, a->filter[0],
- a->filter[1], a->filter[2],
- a->filter[3], a->filter[4]);
- a3dsrc_SetAtmosCurrent(a, a->filter[0],
- a->filter[1], a->filter[2],
- a->filter[3], a->filter[4]);
- return changed;
-}
-
-static struct snd_kcontrol_new vortex_a3d_kcontrol __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "Playback PCM advanced processing",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = snd_vortex_a3d_hrtf_info,
- .get = snd_vortex_a3d_get,
- .put = snd_vortex_a3d_hrtf_put,
-};
-
-/* Control (un)registration. */
-static int __devinit vortex_a3d_register_controls(vortex_t * vortex)
-{
- struct snd_kcontrol *kcontrol;
- int err, i;
- /* HRTF controls. */
- for (i = 0; i < NR_A3D; i++) {
- if ((kcontrol =
- snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL)
- return -ENOMEM;
- kcontrol->id.numid = CTRLID_HRTF;
- kcontrol->info = snd_vortex_a3d_hrtf_info;
- kcontrol->put = snd_vortex_a3d_hrtf_put;
- if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
- return err;
- }
- /* ITD controls. */
- for (i = 0; i < NR_A3D; i++) {
- if ((kcontrol =
- snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL)
- return -ENOMEM;
- kcontrol->id.numid = CTRLID_ITD;
- kcontrol->info = snd_vortex_a3d_itd_info;
- kcontrol->put = snd_vortex_a3d_itd_put;
- if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
- return err;
- }
- /* ILD (gains) controls. */
- for (i = 0; i < NR_A3D; i++) {
- if ((kcontrol =
- snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL)
- return -ENOMEM;
- kcontrol->id.numid = CTRLID_GAINS;
- kcontrol->info = snd_vortex_a3d_ild_info;
- kcontrol->put = snd_vortex_a3d_ild_put;
- if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
- return err;
- }
- /* Filter controls. */
- for (i = 0; i < NR_A3D; i++) {
- if ((kcontrol =
- snd_ctl_new1(&vortex_a3d_kcontrol, &vortex->a3d[i])) == NULL)
- return -ENOMEM;
- kcontrol->id.numid = CTRLID_FILTER;
- kcontrol->info = snd_vortex_a3d_filter_info;
- kcontrol->put = snd_vortex_a3d_filter_put;
- if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
- return err;
- }
- return 0;
-}
-
-static void vortex_a3d_unregister_controls(vortex_t * vortex)
-{
-
-}
-
-/* End of File*/
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_a3d.h b/ANDROID_3.4.5/sound/pci/au88x0/au88x0_a3d.h
deleted file mode 100644
index 0584c65b..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_a3d.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/***************************************************************************
- * au88x0_a3d.h
- *
- * Fri Jul 18 14:16:03 2003
- * Copyright 2003 mjander
- * mjander@users.sourceforge.net
- ****************************************************************************/
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef _AU88X0_A3D_H
-#define _AU88X0_A3D_H
-
-//#include <openal.h>
-
-#define HRTF_SZ 0x38
-#define DLINE_SZ 0x28
-
-#define CTRLID_HRTF 1
-#define CTRLID_ITD 2
-#define CTRLID_ILD 4
-#define CTRLID_FILTER 8
-#define CTRLID_GAINS 16
-
-/* 3D parameter structs */
-typedef unsigned short int a3d_Hrtf_t[HRTF_SZ];
-typedef unsigned short int a3d_ItdDline_t[DLINE_SZ];
-typedef unsigned short int a3d_atmos_t[5];
-typedef unsigned short int a3d_LRGains_t[2];
-typedef unsigned short int a3d_Itd_t[2];
-typedef unsigned short int a3d_Ild_t[2];
-
-typedef struct {
- void *vortex; // Formerly CAsp4HwIO*, now vortex_t*.
- unsigned int source; /* this_04 */
- unsigned int slice; /* this_08 */
- a3d_Hrtf_t hrtf[2];
- a3d_Itd_t itd;
- a3d_Ild_t ild;
- a3d_ItdDline_t dline;
- a3d_atmos_t filter;
-} a3dsrc_t;
-
-/* First Register bank */
-
-#define A3D_A_HrtfCurrent 0x18000 /* 56 ULONG */
-#define A3D_A_GainCurrent 0x180E0
-#define A3D_A_GainTarget 0x180E4
-#define A3D_A_A12Current 0x180E8 /* Atmospheric current. */
-#define A3D_A_A21Target 0x180EC /* Atmospheric target */
-#define A3D_A_B01Current 0x180F0 /* Atmospheric current */
-#define A3D_A_B10Target 0x180F4 /* Atmospheric target */
-#define A3D_A_B2Current 0x180F8 /* Atmospheric current */
-#define A3D_A_B2Target 0x180FC /* Atmospheric target */
-#define A3D_A_HrtfTarget 0x18100 /* 56 ULONG */
-#define A3D_A_ITDCurrent 0x181E0
-#define A3D_A_ITDTarget 0x181E4
-#define A3D_A_HrtfDelayLine 0x181E8 /* 56 ULONG */
-#define A3D_A_ITDDelayLine 0x182C8 /* 40/45 ULONG */
-#define A3D_A_HrtfTrackTC 0x1837C /* Time Constants */
-#define A3D_A_GainTrackTC 0x18380
-#define A3D_A_CoeffTrackTC 0x18384
-#define A3D_A_ITDTrackTC 0x18388
-#define A3D_A_x1 0x1838C
-#define A3D_A_x2 0x18390
-#define A3D_A_y1 0x18394
-#define A3D_A_y2 0x18398
-#define A3D_A_HrtfOutL 0x1839C
-#define A3D_A_HrtfOutR 0x183A0
-#define A3D_A_TAIL 0x183A4
-
-/* Second register bank */
-#define A3D_B_HrtfCurrent 0x19000 /* 56 ULONG */
-#define A3D_B_GainCurrent 0x190E0
-#define A3D_B_GainTarget 0x190E4
-#define A3D_B_A12Current 0x190E8
-#define A3D_B_A21Target 0x190EC
-#define A3D_B_B01Current 0x190F0
-#define A3D_B_B10Target 0x190F4
-#define A3D_B_B2Current 0x190F8
-#define A3D_B_B2Target 0x190FC
-#define A3D_B_HrtfTarget 0x19100 /* 56 ULONG */
-#define A3D_B_ITDCurrent 0x191E0
-#define A3D_B_ITDTarget 0x191E4
-#define A3D_B_HrtfDelayLine 0x191E8 /* 56 ULONG */
-#define A3D_B_TAIL 0x192C8
-
-/* There are 4 slices, 4 a3d each = 16 a3d sources. */
-#define A3D_SLICE_BANK_A 0x18000 /* 4 sources */
-#define A3D_SLICE_BANK_B 0x19000 /* 4 sources */
-#define A3D_SLICE_VDBDest 0x19C00 /* 8 ULONG */
-#define A3D_SLICE_VDBSource 0x19C20 /* 4 ULONG */
-#define A3D_SLICE_ABReg 0x19C30
-#define A3D_SLICE_CReg 0x19C34
-#define A3D_SLICE_Control 0x19C38
-#define A3D_SLICE_DebugReserved 0x19C3c /* Dangerous! */
-#define A3D_SLICE_Pointers 0x19C40
-#define A3D_SLICE_TAIL 0x1A000
-
-// Slice size: 0x2000
-// Source size: 0x3A4, 0x2C8
-
-/* Address generator macro. */
-#define a3d_addrA(slice,source,reg) (((slice)<<0xd)+((source)*0x3A4)+(reg))
-#define a3d_addrB(slice,source,reg) (((slice)<<0xd)+((source)*0x2C8)+(reg))
-#define a3d_addrS(slice,reg) (((slice)<<0xd)+(reg))
-//#define a3d_addr(slice,source,reg) (((reg)>=0x19000) ? a3d_addr2((slice),(source),(reg)) : a3d_addr1((slice),(source),(reg)))
-
-#endif /* _AU88X0_A3D_H */
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_a3ddata.c b/ANDROID_3.4.5/sound/pci/au88x0/au88x0_a3ddata.c
deleted file mode 100644
index 6fab4bba..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_a3ddata.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/***************************************************************************
- * au88x0_a3ddata.c
- *
- * Wed Nov 19 21:11:32 2003
- * Copyright 2003 mjander
- * mjander@users.sourceforge.org
- ****************************************************************************/
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/* Constant initializer values. */
-
-static const a3d_Hrtf_t A3dHrirZeros = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,
- 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,
- 0, 0, 0
-};
-
-static const a3d_Hrtf_t A3dHrirImpulse = {
- 0x7fff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,
- 0, 0, 0
-};
-
-static const a3d_Hrtf_t A3dHrirOnes = {
- 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
- 0x7fff,
- 0x7fff,
- 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
- 0x7fff,
- 0x7fff,
- 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
- 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
- 0x7fff,
- 0x7fff,
- 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
- 0x7fff,
- 0x7fff,
- 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff
-};
-
-static const a3d_Hrtf_t A3dHrirSatTest = {
- 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
- 0x7fff,
- 0x7fff,
- 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001,
- 0x8001,
- 0x8001,
- 0x7fff, 0x0000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-static const a3d_Hrtf_t A3dHrirDImpulse = {
- 0, 0x7fff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,
- 0, 0, 0
-};
-
-static const a3d_ItdDline_t A3dItdDlineZeros = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-static short const GainTCDefault = 0x300;
-static short const ItdTCDefault = 0x0C8;
-static short const HrtfTCDefault = 0x147;
-static short const CoefTCDefault = 0x300;
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_core.c b/ANDROID_3.4.5/sound/pci/au88x0/au88x0_core.c
deleted file mode 100644
index 525f881f..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_core.c
+++ /dev/null
@@ -1,2856 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/*
- Vortex core low level functions.
-
- Author: Manuel Jander (mjander@users.sourceforge.cl)
- These functions are mainly the result of translations made
- from the original disassembly of the au88x0 binary drivers,
- written by Aureal before they went down.
- Many thanks to the Jeff Muizelaar, Kester Maddock, and whoever
- contributed to the OpenVortex project.
- The author of this file, put the few available pieces together
- and translated the rest of the riddle (Mix, Src and connection stuff).
- Some things are still to be discovered, and their meanings are unclear.
-
- Some of these functions aren't intended to be really used, rather
- to help to understand how does the AU88X0 chips work. Keep them in, because
- they could be used somewhere in the future.
-
- This code hasn't been tested or proof read thoroughly. If you wanna help,
- take a look at the AU88X0 assembly and check if this matches.
- Functions tested ok so far are (they show the desired effect
- at least):
- vortex_routes(); (1 bug fixed).
- vortex_adb_addroute();
- vortex_adb_addroutes();
- vortex_connect_codecplay();
- vortex_src_flushbuffers();
- vortex_adbdma_setmode(); note: still some unknown arguments!
- vortex_adbdma_startfifo();
- vortex_adbdma_stopfifo();
- vortex_fifo_setadbctrl(); note: still some unknown arguments!
- vortex_mix_setinputvolumebyte();
- vortex_mix_enableinput();
- vortex_mixer_addWTD(); (fixed)
- vortex_connection_adbdma_src_src();
- vortex_connection_adbdma_src();
- vortex_src_change_convratio();
- vortex_src_addWTD(); (fixed)
-
- History:
-
- 01-03-2003 First revision.
- 01-21-2003 Some bug fixes.
- 17-02-2003 many bugfixes after a big versioning mess.
- 18-02-2003 JAAAAAHHHUUUUUU!!!! The mixer works !! I'm just so happy !
- (2 hours later...) I cant believe it! Im really lucky today.
- Now the SRC is working too! Yeah! XMMS works !
- 20-02-2003 First steps into the ALSA world.
- 28-02-2003 As my birthday present, i discovered how the DMA buffer pages really
- work :-). It was all wrong.
- 12-03-2003 ALSA driver starts working (2 channels).
- 16-03-2003 More srcblock_setupchannel discoveries.
- 12-04-2003 AU8830 playback support. Recording in the works.
- 17-04-2003 vortex_route() and vortex_routes() bug fixes. AU8830 recording
- works now, but chipn' dale effect is still there.
- 16-05-2003 SrcSetupChannel cleanup. Moved the Src setup stuff entirely
- into au88x0_pcm.c .
- 06-06-2003 Buffer shifter bugfix. Mixer volume fix.
- 07-12-2003 A3D routing finally fixed. Believed to be OK.
- 25-03-2004 Many thanks to Claudia, for such valuable bug reports.
-
-*/
-
-#include "au88x0.h"
-#include "au88x0_a3d.h"
-#include <linux/delay.h>
-
-/* MIXER (CAsp4Mix.s and CAsp4Mixer.s) */
-
-// FIXME: get rid of this.
-static int mchannels[NR_MIXIN];
-static int rampchs[NR_MIXIN];
-
-static void vortex_mixer_en_sr(vortex_t * vortex, int channel)
-{
- hwwrite(vortex->mmio, VORTEX_MIXER_SR,
- hwread(vortex->mmio, VORTEX_MIXER_SR) | (0x1 << channel));
-}
-static void vortex_mixer_dis_sr(vortex_t * vortex, int channel)
-{
- hwwrite(vortex->mmio, VORTEX_MIXER_SR,
- hwread(vortex->mmio, VORTEX_MIXER_SR) & ~(0x1 << channel));
-}
-
-#if 0
-static void
-vortex_mix_muteinputgain(vortex_t * vortex, unsigned char mix,
- unsigned char channel)
-{
- hwwrite(vortex->mmio, VORTEX_MIX_INVOL_A + ((mix << 5) + channel),
- 0x80);
- hwwrite(vortex->mmio, VORTEX_MIX_INVOL_B + ((mix << 5) + channel),
- 0x80);
-}
-
-static int vortex_mix_getvolume(vortex_t * vortex, unsigned char mix)
-{
- int a;
- a = hwread(vortex->mmio, VORTEX_MIX_VOL_A + (mix << 2)) & 0xff;
- //FP2LinearFrac(a);
- return (a);
-}
-
-static int
-vortex_mix_getinputvolume(vortex_t * vortex, unsigned char mix,
- int channel, int *vol)
-{
- int a;
- if (!(mchannels[mix] & (1 << channel)))
- return 0;
- a = hwread(vortex->mmio,
- VORTEX_MIX_INVOL_A + (((mix << 5) + channel) << 2));
- /*
- if (rampchs[mix] == 0)
- a = FP2LinearFrac(a);
- else
- a = FP2LinearFracWT(a);
- */
- *vol = a;
- return (0);
-}
-
-static unsigned int vortex_mix_boost6db(unsigned char vol)
-{
- return (vol + 8); /* WOW! what a complex function! */
-}
-
-static void vortex_mix_rampvolume(vortex_t * vortex, int mix)
-{
- int ch;
- char a;
- // This function is intended for ramping down only (see vortex_disableinput()).
- for (ch = 0; ch < 0x20; ch++) {
- if (((1 << ch) & rampchs[mix]) == 0)
- continue;
- a = hwread(vortex->mmio,
- VORTEX_MIX_INVOL_B + (((mix << 5) + ch) << 2));
- if (a > -126) {
- a -= 2;
- hwwrite(vortex->mmio,
- VORTEX_MIX_INVOL_A +
- (((mix << 5) + ch) << 2), a);
- hwwrite(vortex->mmio,
- VORTEX_MIX_INVOL_B +
- (((mix << 5) + ch) << 2), a);
- } else
- vortex_mix_killinput(vortex, mix, ch);
- }
-}
-
-static int
-vortex_mix_getenablebit(vortex_t * vortex, unsigned char mix, int mixin)
-{
- int addr, temp;
- if (mixin >= 0)
- addr = mixin;
- else
- addr = mixin + 3;
- addr = ((mix << 3) + (addr >> 2)) << 2;
- temp = hwread(vortex->mmio, VORTEX_MIX_ENIN + addr);
- return ((temp >> (mixin & 3)) & 1);
-}
-#endif
-static void
-vortex_mix_setvolumebyte(vortex_t * vortex, unsigned char mix,
- unsigned char vol)
-{
- int temp;
- hwwrite(vortex->mmio, VORTEX_MIX_VOL_A + (mix << 2), vol);
- if (1) { /*if (this_10) */
- temp = hwread(vortex->mmio, VORTEX_MIX_VOL_B + (mix << 2));
- if ((temp != 0x80) || (vol == 0x80))
- return;
- }
- hwwrite(vortex->mmio, VORTEX_MIX_VOL_B + (mix << 2), vol);
-}
-
-static void
-vortex_mix_setinputvolumebyte(vortex_t * vortex, unsigned char mix,
- int mixin, unsigned char vol)
-{
- int temp;
-
- hwwrite(vortex->mmio,
- VORTEX_MIX_INVOL_A + (((mix << 5) + mixin) << 2), vol);
- if (1) { /* this_10, initialized to 1. */
- temp =
- hwread(vortex->mmio,
- VORTEX_MIX_INVOL_B + (((mix << 5) + mixin) << 2));
- if ((temp != 0x80) || (vol == 0x80))
- return;
- }
- hwwrite(vortex->mmio,
- VORTEX_MIX_INVOL_B + (((mix << 5) + mixin) << 2), vol);
-}
-
-static void
-vortex_mix_setenablebit(vortex_t * vortex, unsigned char mix, int mixin, int en)
-{
- int temp, addr;
-
- if (mixin < 0)
- addr = (mixin + 3);
- else
- addr = mixin;
- addr = ((mix << 3) + (addr >> 2)) << 2;
- temp = hwread(vortex->mmio, VORTEX_MIX_ENIN + addr);
- if (en)
- temp |= (1 << (mixin & 3));
- else
- temp &= ~(1 << (mixin & 3));
- /* Mute input. Astatic void crackling? */
- hwwrite(vortex->mmio,
- VORTEX_MIX_INVOL_B + (((mix << 5) + mixin) << 2), 0x80);
- /* Looks like clear buffer. */
- hwwrite(vortex->mmio, VORTEX_MIX_SMP + (mixin << 2), 0x0);
- hwwrite(vortex->mmio, VORTEX_MIX_SMP + 4 + (mixin << 2), 0x0);
- /* Write enable bit. */
- hwwrite(vortex->mmio, VORTEX_MIX_ENIN + addr, temp);
-}
-
-static void
-vortex_mix_killinput(vortex_t * vortex, unsigned char mix, int mixin)
-{
- rampchs[mix] &= ~(1 << mixin);
- vortex_mix_setinputvolumebyte(vortex, mix, mixin, 0x80);
- mchannels[mix] &= ~(1 << mixin);
- vortex_mix_setenablebit(vortex, mix, mixin, 0);
-}
-
-static void
-vortex_mix_enableinput(vortex_t * vortex, unsigned char mix, int mixin)
-{
- vortex_mix_killinput(vortex, mix, mixin);
- if ((mchannels[mix] & (1 << mixin)) == 0) {
- vortex_mix_setinputvolumebyte(vortex, mix, mixin, 0x80); /*0x80 : mute */
- mchannels[mix] |= (1 << mixin);
- }
- vortex_mix_setenablebit(vortex, mix, mixin, 1);
-}
-
-static void
-vortex_mix_disableinput(vortex_t * vortex, unsigned char mix, int channel,
- int ramp)
-{
- if (ramp) {
- rampchs[mix] |= (1 << channel);
- // Register callback.
- //vortex_mix_startrampvolume(vortex);
- vortex_mix_killinput(vortex, mix, channel);
- } else
- vortex_mix_killinput(vortex, mix, channel);
-}
-
-static int
-vortex_mixer_addWTD(vortex_t * vortex, unsigned char mix, unsigned char ch)
-{
- int temp, lifeboat = 0, prev;
-
- temp = hwread(vortex->mmio, VORTEX_MIXER_SR);
- if ((temp & (1 << ch)) == 0) {
- hwwrite(vortex->mmio, VORTEX_MIXER_CHNBASE + (ch << 2), mix);
- vortex_mixer_en_sr(vortex, ch);
- return 1;
- }
- prev = VORTEX_MIXER_CHNBASE + (ch << 2);
- temp = hwread(vortex->mmio, prev);
- while (temp & 0x10) {
- prev = VORTEX_MIXER_RTBASE + ((temp & 0xf) << 2);
- temp = hwread(vortex->mmio, prev);
- //printk(KERN_INFO "vortex: mixAddWTD: while addr=%x, val=%x\n", prev, temp);
- if ((++lifeboat) > 0xf) {
- printk(KERN_ERR
- "vortex_mixer_addWTD: lifeboat overflow\n");
- return 0;
- }
- }
- hwwrite(vortex->mmio, VORTEX_MIXER_RTBASE + ((temp & 0xf) << 2), mix);
- hwwrite(vortex->mmio, prev, (temp & 0xf) | 0x10);
- return 1;
-}
-
-static int
-vortex_mixer_delWTD(vortex_t * vortex, unsigned char mix, unsigned char ch)
-{
- int esp14 = -1, esp18, eax, ebx, edx, ebp, esi = 0;
- //int esp1f=edi(while)=src, esp10=ch;
-
- eax = hwread(vortex->mmio, VORTEX_MIXER_SR);
- if (((1 << ch) & eax) == 0) {
- printk(KERN_ERR "mix ALARM %x\n", eax);
- return 0;
- }
- ebp = VORTEX_MIXER_CHNBASE + (ch << 2);
- esp18 = hwread(vortex->mmio, ebp);
- if (esp18 & 0x10) {
- ebx = (esp18 & 0xf);
- if (mix == ebx) {
- ebx = VORTEX_MIXER_RTBASE + (mix << 2);
- edx = hwread(vortex->mmio, ebx);
- //7b60
- hwwrite(vortex->mmio, ebp, edx);
- hwwrite(vortex->mmio, ebx, 0);
- } else {
- //7ad3
- edx =
- hwread(vortex->mmio,
- VORTEX_MIXER_RTBASE + (ebx << 2));
- //printk(KERN_INFO "vortex: mixdelWTD: 1 addr=%x, val=%x, src=%x\n", ebx, edx, src);
- while ((edx & 0xf) != mix) {
- if ((esi) > 0xf) {
- printk(KERN_ERR
- "vortex: mixdelWTD: error lifeboat overflow\n");
- return 0;
- }
- esp14 = ebx;
- ebx = edx & 0xf;
- ebp = ebx << 2;
- edx =
- hwread(vortex->mmio,
- VORTEX_MIXER_RTBASE + ebp);
- //printk(KERN_INFO "vortex: mixdelWTD: while addr=%x, val=%x\n", ebp, edx);
- esi++;
- }
- //7b30
- ebp = ebx << 2;
- if (edx & 0x10) { /* Delete entry in between others */
- ebx = VORTEX_MIXER_RTBASE + ((edx & 0xf) << 2);
- edx = hwread(vortex->mmio, ebx);
- //7b60
- hwwrite(vortex->mmio,
- VORTEX_MIXER_RTBASE + ebp, edx);
- hwwrite(vortex->mmio, ebx, 0);
- //printk(KERN_INFO "vortex mixdelWTD between addr= 0x%x, val= 0x%x\n", ebp, edx);
- } else { /* Delete last entry */
- //7b83
- if (esp14 == -1)
- hwwrite(vortex->mmio,
- VORTEX_MIXER_CHNBASE +
- (ch << 2), esp18 & 0xef);
- else {
- ebx = (0xffffffe0 & edx) | (0xf & ebx);
- hwwrite(vortex->mmio,
- VORTEX_MIXER_RTBASE +
- (esp14 << 2), ebx);
- //printk(KERN_INFO "vortex mixdelWTD last addr= 0x%x, val= 0x%x\n", esp14, ebx);
- }
- hwwrite(vortex->mmio,
- VORTEX_MIXER_RTBASE + ebp, 0);
- return 1;
- }
- }
- } else {
- //printk(KERN_INFO "removed last mix\n");
- //7be0
- vortex_mixer_dis_sr(vortex, ch);
- hwwrite(vortex->mmio, ebp, 0);
- }
- return 1;
-}
-
-static void vortex_mixer_init(vortex_t * vortex)
-{
- u32 addr;
- int x;
-
- // FIXME: get rid of this crap.
- memset(mchannels, 0, NR_MIXOUT * sizeof(int));
- memset(rampchs, 0, NR_MIXOUT * sizeof(int));
-
- addr = VORTEX_MIX_SMP + 0x17c;
- for (x = 0x5f; x >= 0; x--) {
- hwwrite(vortex->mmio, addr, 0);
- addr -= 4;
- }
- addr = VORTEX_MIX_ENIN + 0x1fc;
- for (x = 0x7f; x >= 0; x--) {
- hwwrite(vortex->mmio, addr, 0);
- addr -= 4;
- }
- addr = VORTEX_MIX_SMP + 0x17c;
- for (x = 0x5f; x >= 0; x--) {
- hwwrite(vortex->mmio, addr, 0);
- addr -= 4;
- }
- addr = VORTEX_MIX_INVOL_A + 0x7fc;
- for (x = 0x1ff; x >= 0; x--) {
- hwwrite(vortex->mmio, addr, 0x80);
- addr -= 4;
- }
- addr = VORTEX_MIX_VOL_A + 0x3c;
- for (x = 0xf; x >= 0; x--) {
- hwwrite(vortex->mmio, addr, 0x80);
- addr -= 4;
- }
- addr = VORTEX_MIX_INVOL_B + 0x7fc;
- for (x = 0x1ff; x >= 0; x--) {
- hwwrite(vortex->mmio, addr, 0x80);
- addr -= 4;
- }
- addr = VORTEX_MIX_VOL_B + 0x3c;
- for (x = 0xf; x >= 0; x--) {
- hwwrite(vortex->mmio, addr, 0x80);
- addr -= 4;
- }
- addr = VORTEX_MIXER_RTBASE + (MIXER_RTBASE_SIZE - 1) * 4;
- for (x = (MIXER_RTBASE_SIZE - 1); x >= 0; x--) {
- hwwrite(vortex->mmio, addr, 0x0);
- addr -= 4;
- }
- hwwrite(vortex->mmio, VORTEX_MIXER_SR, 0);
-
- /* Set clipping ceiling (this may be all wrong). */
- /*
- for (x = 0; x < 0x80; x++) {
- hwwrite(vortex->mmio, VORTEX_MIXER_CLIP + (x << 2), 0x3ffff);
- }
- */
- /*
- call CAsp4Mix__Initialize_CAsp4HwIO____CAsp4Mixer____
- Register ISR callback for volume smooth fade out.
- Maybe this avoids clicks when press "stop" ?
- */
-}
-
-/* SRC (CAsp4Src.s and CAsp4SrcBlock) */
-
-static void vortex_src_en_sr(vortex_t * vortex, int channel)
-{
- hwwrite(vortex->mmio, VORTEX_SRCBLOCK_SR,
- hwread(vortex->mmio, VORTEX_SRCBLOCK_SR) | (0x1 << channel));
-}
-
-static void vortex_src_dis_sr(vortex_t * vortex, int channel)
-{
- hwwrite(vortex->mmio, VORTEX_SRCBLOCK_SR,
- hwread(vortex->mmio, VORTEX_SRCBLOCK_SR) & ~(0x1 << channel));
-}
-
-static void vortex_src_flushbuffers(vortex_t * vortex, unsigned char src)
-{
- int i;
-
- for (i = 0x1f; i >= 0; i--)
- hwwrite(vortex->mmio,
- VORTEX_SRC_DATA0 + (src << 7) + (i << 2), 0);
- hwwrite(vortex->mmio, VORTEX_SRC_DATA + (src << 3), 0);
- hwwrite(vortex->mmio, VORTEX_SRC_DATA + (src << 3) + 4, 0);
-}
-
-static void vortex_src_cleardrift(vortex_t * vortex, unsigned char src)
-{
- hwwrite(vortex->mmio, VORTEX_SRC_DRIFT0 + (src << 2), 0);
- hwwrite(vortex->mmio, VORTEX_SRC_DRIFT1 + (src << 2), 0);
- hwwrite(vortex->mmio, VORTEX_SRC_DRIFT2 + (src << 2), 1);
-}
-
-static void
-vortex_src_set_throttlesource(vortex_t * vortex, unsigned char src, int en)
-{
- int temp;
-
- temp = hwread(vortex->mmio, VORTEX_SRC_SOURCE);
- if (en)
- temp |= 1 << src;
- else
- temp &= ~(1 << src);
- hwwrite(vortex->mmio, VORTEX_SRC_SOURCE, temp);
-}
-
-static int
-vortex_src_persist_convratio(vortex_t * vortex, unsigned char src, int ratio)
-{
- int temp, lifeboat = 0;
-
- do {
- hwwrite(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2), ratio);
- temp = hwread(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2));
- if ((++lifeboat) > 0x9) {
- printk(KERN_ERR "Vortex: Src cvr fail\n");
- break;
- }
- }
- while (temp != ratio);
- return temp;
-}
-
-#if 0
-static void vortex_src_slowlock(vortex_t * vortex, unsigned char src)
-{
- int temp;
-
- hwwrite(vortex->mmio, VORTEX_SRC_DRIFT2 + (src << 2), 1);
- hwwrite(vortex->mmio, VORTEX_SRC_DRIFT0 + (src << 2), 0);
- temp = hwread(vortex->mmio, VORTEX_SRC_U0 + (src << 2));
- if (temp & 0x200)
- hwwrite(vortex->mmio, VORTEX_SRC_U0 + (src << 2),
- temp & ~0x200L);
-}
-
-static void
-vortex_src_change_convratio(vortex_t * vortex, unsigned char src, int ratio)
-{
- int temp, a;
-
- if ((ratio & 0x10000) && (ratio != 0x10000)) {
- if (ratio & 0x3fff)
- a = (0x11 - ((ratio >> 0xe) & 0x3)) - 1;
- else
- a = (0x11 - ((ratio >> 0xe) & 0x3)) - 2;
- } else
- a = 0xc;
- temp = hwread(vortex->mmio, VORTEX_SRC_U0 + (src << 2));
- if (((temp >> 4) & 0xf) != a)
- hwwrite(vortex->mmio, VORTEX_SRC_U0 + (src << 2),
- (temp & 0xf) | ((a & 0xf) << 4));
-
- vortex_src_persist_convratio(vortex, src, ratio);
-}
-
-static int
-vortex_src_checkratio(vortex_t * vortex, unsigned char src,
- unsigned int desired_ratio)
-{
- int hw_ratio, lifeboat = 0;
-
- hw_ratio = hwread(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2));
-
- while (hw_ratio != desired_ratio) {
- hwwrite(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2), desired_ratio);
-
- if ((lifeboat++) > 15) {
- printk(KERN_ERR "Vortex: could not set src-%d from %d to %d\n",
- src, hw_ratio, desired_ratio);
- break;
- }
- }
-
- return hw_ratio;
-}
-
-#endif
-/*
- Objective: Set samplerate for given SRC module.
- Arguments:
- card: pointer to vortex_t strcut.
- src: Integer index of the SRC module.
- cr: Current sample rate conversion factor.
- b: unknown 16 bit value.
- sweep: Enable Samplerate fade from cr toward tr flag.
- dirplay: 1: playback, 0: recording.
- sl: Slow Lock flag.
- tr: Target samplerate conversion.
- thsource: Throttle source flag (no idea what that means).
-*/
-static void vortex_src_setupchannel(vortex_t * card, unsigned char src,
- unsigned int cr, unsigned int b, int sweep, int d,
- int dirplay, int sl, unsigned int tr, int thsource)
-{
- // noplayback: d=2,4,7,0xa,0xb when using first 2 src's.
- // c: enables pitch sweep.
- // looks like g is c related. Maybe g is a sweep parameter ?
- // g = cvr
- // dirplay: 0 = recording, 1 = playback
- // d = src hw index.
-
- int esi, ebp = 0, esp10;
-
- vortex_src_flushbuffers(card, src);
-
- if (sweep) {
- if ((tr & 0x10000) && (tr != 0x10000)) {
- tr = 0;
- esi = 0x7;
- } else {
- if ((((short)tr) < 0) && (tr != 0x8000)) {
- tr = 0;
- esi = 0x8;
- } else {
- tr = 1;
- esi = 0xc;
- }
- }
- } else {
- if ((cr & 0x10000) && (cr != 0x10000)) {
- tr = 0; /*ebx = 0 */
- esi = 0x11 - ((cr >> 0xe) & 7);
- if (cr & 0x3fff)
- esi -= 1;
- else
- esi -= 2;
- } else {
- tr = 1;
- esi = 0xc;
- }
- }
- vortex_src_cleardrift(card, src);
- vortex_src_set_throttlesource(card, src, thsource);
-
- if ((dirplay == 0) && (sweep == 0)) {
- if (tr)
- esp10 = 0xf;
- else
- esp10 = 0xc;
- ebp = 0;
- } else {
- if (tr)
- ebp = 0xf;
- else
- ebp = 0xc;
- esp10 = 0;
- }
- hwwrite(card->mmio, VORTEX_SRC_U0 + (src << 2),
- (sl << 0x9) | (sweep << 0x8) | ((esi & 0xf) << 4) | d);
- /* 0xc0 esi=0xc c=f=0 d=0 */
- vortex_src_persist_convratio(card, src, cr);
- hwwrite(card->mmio, VORTEX_SRC_U1 + (src << 2), b & 0xffff);
- /* 0 b=0 */
- hwwrite(card->mmio, VORTEX_SRC_U2 + (src << 2),
- (tr << 0x11) | (dirplay << 0x10) | (ebp << 0x8) | esp10);
- /* 0x30f00 e=g=1 esp10=0 ebp=f */
- //printk(KERN_INFO "vortex: SRC %d, d=0x%x, esi=0x%x, esp10=0x%x, ebp=0x%x\n", src, d, esi, esp10, ebp);
-}
-
-static void vortex_srcblock_init(vortex_t * vortex)
-{
- u32 addr;
- int x;
- hwwrite(vortex->mmio, VORTEX_SRC_SOURCESIZE, 0x1ff);
- /*
- for (x=0; x<0x10; x++) {
- vortex_src_init(&vortex_src[x], x);
- }
- */
- //addr = 0xcc3c;
- //addr = 0x26c3c;
- addr = VORTEX_SRC_RTBASE + 0x3c;
- for (x = 0xf; x >= 0; x--) {
- hwwrite(vortex->mmio, addr, 0);
- addr -= 4;
- }
- //addr = 0xcc94;
- //addr = 0x26c94;
- addr = VORTEX_SRC_CHNBASE + 0x54;
- for (x = 0x15; x >= 0; x--) {
- hwwrite(vortex->mmio, addr, 0);
- addr -= 4;
- }
-}
-
-static int
-vortex_src_addWTD(vortex_t * vortex, unsigned char src, unsigned char ch)
-{
- int temp, lifeboat = 0, prev;
- // esp13 = src
-
- temp = hwread(vortex->mmio, VORTEX_SRCBLOCK_SR);
- if ((temp & (1 << ch)) == 0) {
- hwwrite(vortex->mmio, VORTEX_SRC_CHNBASE + (ch << 2), src);
- vortex_src_en_sr(vortex, ch);
- return 1;
- }
- prev = VORTEX_SRC_CHNBASE + (ch << 2); /*ebp */
- temp = hwread(vortex->mmio, prev);
- //while (temp & NR_SRC) {
- while (temp & 0x10) {
- prev = VORTEX_SRC_RTBASE + ((temp & 0xf) << 2); /*esp12 */
- //prev = VORTEX_SRC_RTBASE + ((temp & (NR_SRC-1)) << 2); /*esp12*/
- temp = hwread(vortex->mmio, prev);
- //printk(KERN_INFO "vortex: srcAddWTD: while addr=%x, val=%x\n", prev, temp);
- if ((++lifeboat) > 0xf) {
- printk(KERN_ERR
- "vortex_src_addWTD: lifeboat overflow\n");
- return 0;
- }
- }
- hwwrite(vortex->mmio, VORTEX_SRC_RTBASE + ((temp & 0xf) << 2), src);
- //hwwrite(vortex->mmio, prev, (temp & (NR_SRC-1)) | NR_SRC);
- hwwrite(vortex->mmio, prev, (temp & 0xf) | 0x10);
- return 1;
-}
-
-static int
-vortex_src_delWTD(vortex_t * vortex, unsigned char src, unsigned char ch)
-{
- int esp14 = -1, esp18, eax, ebx, edx, ebp, esi = 0;
- //int esp1f=edi(while)=src, esp10=ch;
-
- eax = hwread(vortex->mmio, VORTEX_SRCBLOCK_SR);
- if (((1 << ch) & eax) == 0) {
- printk(KERN_ERR "src alarm\n");
- return 0;
- }
- ebp = VORTEX_SRC_CHNBASE + (ch << 2);
- esp18 = hwread(vortex->mmio, ebp);
- if (esp18 & 0x10) {
- ebx = (esp18 & 0xf);
- if (src == ebx) {
- ebx = VORTEX_SRC_RTBASE + (src << 2);
- edx = hwread(vortex->mmio, ebx);
- //7b60
- hwwrite(vortex->mmio, ebp, edx);
- hwwrite(vortex->mmio, ebx, 0);
- } else {
- //7ad3
- edx =
- hwread(vortex->mmio,
- VORTEX_SRC_RTBASE + (ebx << 2));
- //printk(KERN_INFO "vortex: srcdelWTD: 1 addr=%x, val=%x, src=%x\n", ebx, edx, src);
- while ((edx & 0xf) != src) {
- if ((esi) > 0xf) {
- printk
- ("vortex: srcdelWTD: error, lifeboat overflow\n");
- return 0;
- }
- esp14 = ebx;
- ebx = edx & 0xf;
- ebp = ebx << 2;
- edx =
- hwread(vortex->mmio,
- VORTEX_SRC_RTBASE + ebp);
- //printk(KERN_INFO "vortex: srcdelWTD: while addr=%x, val=%x\n", ebp, edx);
- esi++;
- }
- //7b30
- ebp = ebx << 2;
- if (edx & 0x10) { /* Delete entry in between others */
- ebx = VORTEX_SRC_RTBASE + ((edx & 0xf) << 2);
- edx = hwread(vortex->mmio, ebx);
- //7b60
- hwwrite(vortex->mmio,
- VORTEX_SRC_RTBASE + ebp, edx);
- hwwrite(vortex->mmio, ebx, 0);
- //printk(KERN_INFO "vortex srcdelWTD between addr= 0x%x, val= 0x%x\n", ebp, edx);
- } else { /* Delete last entry */
- //7b83
- if (esp14 == -1)
- hwwrite(vortex->mmio,
- VORTEX_SRC_CHNBASE +
- (ch << 2), esp18 & 0xef);
- else {
- ebx = (0xffffffe0 & edx) | (0xf & ebx);
- hwwrite(vortex->mmio,
- VORTEX_SRC_RTBASE +
- (esp14 << 2), ebx);
- //printk(KERN_INFO"vortex srcdelWTD last addr= 0x%x, val= 0x%x\n", esp14, ebx);
- }
- hwwrite(vortex->mmio,
- VORTEX_SRC_RTBASE + ebp, 0);
- return 1;
- }
- }
- } else {
- //7be0
- vortex_src_dis_sr(vortex, ch);
- hwwrite(vortex->mmio, ebp, 0);
- }
- return 1;
-}
-
- /*FIFO*/
-
-static void
-vortex_fifo_clearadbdata(vortex_t * vortex, int fifo, int x)
-{
- for (x--; x >= 0; x--)
- hwwrite(vortex->mmio,
- VORTEX_FIFO_ADBDATA +
- (((fifo << FIFO_SIZE_BITS) + x) << 2), 0);
-}
-
-#if 0
-static void vortex_fifo_adbinitialize(vortex_t * vortex, int fifo, int j)
-{
- vortex_fifo_clearadbdata(vortex, fifo, FIFO_SIZE);
-#ifdef CHIP_AU8820
- hwwrite(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2),
- (FIFO_U1 | ((j & FIFO_MASK) << 0xb)));
-#else
- hwwrite(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2),
- (FIFO_U1 | ((j & FIFO_MASK) << 0xc)));
-#endif
-}
-#endif
-static void vortex_fifo_setadbvalid(vortex_t * vortex, int fifo, int en)
-{
- hwwrite(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2),
- (hwread(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2)) &
- 0xffffffef) | ((1 & en) << 4) | FIFO_U1);
-}
-
-static void
-vortex_fifo_setadbctrl(vortex_t * vortex, int fifo, int stereo, int priority,
- int empty, int valid, int f)
-{
- int temp, lifeboat = 0;
- //int this_8[NR_ADB] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* position */
- int this_4 = 0x2;
- /* f seems priority related.
- * CAsp4AdbDma::SetPriority is the only place that calls SetAdbCtrl with f set to 1
- * every where else it is set to 0. It seems, however, that CAsp4AdbDma::SetPriority
- * is never called, thus the f related bits remain a mystery for now.
- */
- do {
- temp = hwread(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2));
- if (lifeboat++ > 0xbb8) {
- printk(KERN_ERR
- "Vortex: vortex_fifo_setadbctrl fail\n");
- break;
- }
- }
- while (temp & FIFO_RDONLY);
-
- // AU8830 semes to take some special care about fifo content (data).
- // But i'm just to lazy to translate that :)
- if (valid) {
- if ((temp & FIFO_VALID) == 0) {
- //this_8[fifo] = 0;
- vortex_fifo_clearadbdata(vortex, fifo, FIFO_SIZE); // this_4
-#ifdef CHIP_AU8820
- temp = (this_4 & 0x1f) << 0xb;
-#else
- temp = (this_4 & 0x3f) << 0xc;
-#endif
- temp = (temp & 0xfffffffd) | ((stereo & 1) << 1);
- temp = (temp & 0xfffffff3) | ((priority & 3) << 2);
- temp = (temp & 0xffffffef) | ((valid & 1) << 4);
- temp |= FIFO_U1;
- temp = (temp & 0xffffffdf) | ((empty & 1) << 5);
-#ifdef CHIP_AU8820
- temp = (temp & 0xfffbffff) | ((f & 1) << 0x12);
-#endif
-#ifdef CHIP_AU8830
- temp = (temp & 0xf7ffffff) | ((f & 1) << 0x1b);
- temp = (temp & 0xefffffff) | ((f & 1) << 0x1c);
-#endif
-#ifdef CHIP_AU8810
- temp = (temp & 0xfeffffff) | ((f & 1) << 0x18);
- temp = (temp & 0xfdffffff) | ((f & 1) << 0x19);
-#endif
- }
- } else {
- if (temp & FIFO_VALID) {
-#ifdef CHIP_AU8820
- temp = ((f & 1) << 0x12) | (temp & 0xfffbffef);
-#endif
-#ifdef CHIP_AU8830
- temp =
- ((f & 1) << 0x1b) | (temp & 0xe7ffffef) | FIFO_BITS;
-#endif
-#ifdef CHIP_AU8810
- temp =
- ((f & 1) << 0x18) | (temp & 0xfcffffef) | FIFO_BITS;
-#endif
- } else
- /*if (this_8[fifo]) */
- vortex_fifo_clearadbdata(vortex, fifo, FIFO_SIZE);
- }
- hwwrite(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2), temp);
- hwread(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2));
-}
-
-#ifndef CHIP_AU8810
-static void vortex_fifo_clearwtdata(vortex_t * vortex, int fifo, int x)
-{
- if (x < 1)
- return;
- for (x--; x >= 0; x--)
- hwwrite(vortex->mmio,
- VORTEX_FIFO_WTDATA +
- (((fifo << FIFO_SIZE_BITS) + x) << 2), 0);
-}
-
-static void vortex_fifo_wtinitialize(vortex_t * vortex, int fifo, int j)
-{
- vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);
-#ifdef CHIP_AU8820
- hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2),
- (FIFO_U1 | ((j & FIFO_MASK) << 0xb)));
-#else
- hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2),
- (FIFO_U1 | ((j & FIFO_MASK) << 0xc)));
-#endif
-}
-
-static void vortex_fifo_setwtvalid(vortex_t * vortex, int fifo, int en)
-{
- hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2),
- (hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2)) &
- 0xffffffef) | ((en & 1) << 4) | FIFO_U1);
-}
-
-static void
-vortex_fifo_setwtctrl(vortex_t * vortex, int fifo, int ctrl, int priority,
- int empty, int valid, int f)
-{
- int temp = 0, lifeboat = 0;
- int this_4 = 2;
-
- do {
- temp = hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2));
- if (lifeboat++ > 0xbb8) {
- printk(KERN_ERR "Vortex: vortex_fifo_setwtctrl fail\n");
- break;
- }
- }
- while (temp & FIFO_RDONLY);
-
- if (valid) {
- if ((temp & FIFO_VALID) == 0) {
- vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE); // this_4
-#ifdef CHIP_AU8820
- temp = (this_4 & 0x1f) << 0xb;
-#else
- temp = (this_4 & 0x3f) << 0xc;
-#endif
- temp = (temp & 0xfffffffd) | ((ctrl & 1) << 1);
- temp = (temp & 0xfffffff3) | ((priority & 3) << 2);
- temp = (temp & 0xffffffef) | ((valid & 1) << 4);
- temp |= FIFO_U1;
- temp = (temp & 0xffffffdf) | ((empty & 1) << 5);
-#ifdef CHIP_AU8820
- temp = (temp & 0xfffbffff) | ((f & 1) << 0x12);
-#endif
-#ifdef CHIP_AU8830
- temp = (temp & 0xf7ffffff) | ((f & 1) << 0x1b);
- temp = (temp & 0xefffffff) | ((f & 1) << 0x1c);
-#endif
-#ifdef CHIP_AU8810
- temp = (temp & 0xfeffffff) | ((f & 1) << 0x18);
- temp = (temp & 0xfdffffff) | ((f & 1) << 0x19);
-#endif
- }
- } else {
- if (temp & FIFO_VALID) {
-#ifdef CHIP_AU8820
- temp = ((f & 1) << 0x12) | (temp & 0xfffbffef);
-#endif
-#ifdef CHIP_AU8830
- temp =
- ((f & 1) << 0x1b) | (temp & 0xe7ffffef) | FIFO_BITS;
-#endif
-#ifdef CHIP_AU8810
- temp =
- ((f & 1) << 0x18) | (temp & 0xfcffffef) | FIFO_BITS;
-#endif
- } else
- /*if (this_8[fifo]) */
- vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);
- }
- hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);
- hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2));
-
-/*
- do {
- temp = hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2));
- if (lifeboat++ > 0xbb8) {
- printk(KERN_ERR "Vortex: vortex_fifo_setwtctrl fail (hanging)\n");
- break;
- }
- } while ((temp & FIFO_RDONLY)&&(temp & FIFO_VALID)&&(temp != 0xFFFFFFFF));
-
-
- if (valid) {
- if (temp & FIFO_VALID) {
- temp = 0x40000;
- //temp |= 0x08000000;
- //temp |= 0x10000000;
- //temp |= 0x04000000;
- //temp |= 0x00400000;
- temp |= 0x1c400000;
- temp &= 0xFFFFFFF3;
- temp &= 0xFFFFFFEF;
- temp |= (valid & 1) << 4;
- hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);
- return;
- } else {
- vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);
- return;
- }
- } else {
- temp &= 0xffffffef;
- temp |= 0x08000000;
- temp |= 0x10000000;
- temp |= 0x04000000;
- temp |= 0x00400000;
- hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);
- temp = hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2));
- //((temp >> 6) & 0x3f)
-
- priority = 0;
- if (((temp & 0x0fc0) ^ ((temp >> 6) & 0x0fc0)) & 0FFFFFFC0)
- vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);
- valid = 0xfb;
- temp = (temp & 0xfffffffd) | ((ctrl & 1) << 1);
- temp = (temp & 0xfffdffff) | ((f & 1) << 0x11);
- temp = (temp & 0xfffffff3) | ((priority & 3) << 2);
- temp = (temp & 0xffffffef) | ((valid & 1) << 4);
- temp = (temp & 0xffffffdf) | ((empty & 1) << 5);
- hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);
- }
-
- */
-
- /*
- temp = (temp & 0xfffffffd) | ((ctrl & 1) << 1);
- temp = (temp & 0xfffdffff) | ((f & 1) << 0x11);
- temp = (temp & 0xfffffff3) | ((priority & 3) << 2);
- temp = (temp & 0xffffffef) | ((valid & 1) << 4);
- temp = (temp & 0xffffffdf) | ((empty & 1) << 5);
- #ifdef FIFO_BITS
- temp = temp | FIFO_BITS | 40000;
- #endif
- // 0x1c440010, 0x1c400000
- hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);
- */
-}
-
-#endif
-static void vortex_fifo_init(vortex_t * vortex)
-{
- int x;
- u32 addr;
-
- /* ADB DMA channels fifos. */
- addr = VORTEX_FIFO_ADBCTRL + ((NR_ADB - 1) * 4);
- for (x = NR_ADB - 1; x >= 0; x--) {
- hwwrite(vortex->mmio, addr, (FIFO_U0 | FIFO_U1));
- if (hwread(vortex->mmio, addr) != (FIFO_U0 | FIFO_U1))
- printk(KERN_ERR "bad adb fifo reset!");
- vortex_fifo_clearadbdata(vortex, x, FIFO_SIZE);
- addr -= 4;
- }
-
-#ifndef CHIP_AU8810
- /* WT DMA channels fifos. */
- addr = VORTEX_FIFO_WTCTRL + ((NR_WT - 1) * 4);
- for (x = NR_WT - 1; x >= 0; x--) {
- hwwrite(vortex->mmio, addr, FIFO_U0);
- if (hwread(vortex->mmio, addr) != FIFO_U0)
- printk(KERN_ERR
- "bad wt fifo reset (0x%08x, 0x%08x)!\n",
- addr, hwread(vortex->mmio, addr));
- vortex_fifo_clearwtdata(vortex, x, FIFO_SIZE);
- addr -= 4;
- }
-#endif
- /* trigger... */
-#ifdef CHIP_AU8820
- hwwrite(vortex->mmio, 0xf8c0, 0xd03); //0x0843 0xd6b
-#else
-#ifdef CHIP_AU8830
- hwwrite(vortex->mmio, 0x17000, 0x61); /* wt a */
- hwwrite(vortex->mmio, 0x17004, 0x61); /* wt b */
-#endif
- hwwrite(vortex->mmio, 0x17008, 0x61); /* adb */
-#endif
-}
-
-/* ADBDMA */
-
-static void vortex_adbdma_init(vortex_t * vortex)
-{
-}
-
-static void vortex_adbdma_setfirstbuffer(vortex_t * vortex, int adbdma)
-{
- stream_t *dma = &vortex->dma_adb[adbdma];
-
- hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
- dma->dma_ctrl);
-}
-
-static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb)
-{
- stream_t *dma = &vortex->dma_adb[adbdma];
- //hwwrite(vortex->mmio, VORTEX_ADBDMA_START + (adbdma << 2), sb << (((NR_ADB-1)-((adbdma&0xf)*2))));
- hwwrite(vortex->mmio, VORTEX_ADBDMA_START + (adbdma << 2),
- sb << ((0xf - (adbdma & 0xf)) * 2));
- dma->period_real = dma->period_virt = sb;
-}
-
-static void
-vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma,
- int psize, int count)
-{
- stream_t *dma = &vortex->dma_adb[adbdma];
-
- dma->period_bytes = psize;
- dma->nr_periods = count;
-
- dma->cfg0 = 0;
- dma->cfg1 = 0;
- switch (count) {
- /* Four or more pages */
- default:
- case 4:
- dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize - 1);
- hwwrite(vortex->mmio,
- VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0xc,
- snd_pcm_sgbuf_get_addr(dma->substream, psize * 3));
- /* 3 pages */
- case 3:
- dma->cfg0 |= 0x12000000;
- dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize - 1) << 0xc);
- hwwrite(vortex->mmio,
- VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x8,
- snd_pcm_sgbuf_get_addr(dma->substream, psize * 2));
- /* 2 pages */
- case 2:
- dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize - 1);
- hwwrite(vortex->mmio,
- VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x4,
- snd_pcm_sgbuf_get_addr(dma->substream, psize));
- /* 1 page */
- case 1:
- dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize - 1) << 0xc);
- hwwrite(vortex->mmio,
- VORTEX_ADBDMA_BUFBASE + (adbdma << 4),
- snd_pcm_sgbuf_get_addr(dma->substream, 0));
- break;
- }
- /*
- printk(KERN_DEBUG "vortex: cfg0 = 0x%x\nvortex: cfg1=0x%x\n",
- dma->cfg0, dma->cfg1);
- */
- hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFCFG0 + (adbdma << 3), dma->cfg0);
- hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFCFG1 + (adbdma << 3), dma->cfg1);
-
- vortex_adbdma_setfirstbuffer(vortex, adbdma);
- vortex_adbdma_setstartbuffer(vortex, adbdma, 0);
-}
-
-static void
-vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie, int dir,
- int fmt, int stereo, u32 offset)
-{
- stream_t *dma = &vortex->dma_adb[adbdma];
-
- dma->dma_unknown = stereo;
- dma->dma_ctrl =
- ((offset & OFFSET_MASK) | (dma->dma_ctrl & ~OFFSET_MASK));
- /* Enable PCMOUT interrupts. */
- dma->dma_ctrl =
- (dma->dma_ctrl & ~IE_MASK) | ((ie << IE_SHIFT) & IE_MASK);
-
- dma->dma_ctrl =
- (dma->dma_ctrl & ~DIR_MASK) | ((dir << DIR_SHIFT) & DIR_MASK);
- dma->dma_ctrl =
- (dma->dma_ctrl & ~FMT_MASK) | ((fmt << FMT_SHIFT) & FMT_MASK);
-
- hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
- dma->dma_ctrl);
- hwread(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2));
-}
-
-static int vortex_adbdma_bufshift(vortex_t * vortex, int adbdma)
-{
- stream_t *dma = &vortex->dma_adb[adbdma];
- int page, p, pp, delta, i;
-
- page =
- (hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2)) &
- ADB_SUBBUF_MASK) >> ADB_SUBBUF_SHIFT;
- if (dma->nr_periods >= 4)
- delta = (page - dma->period_real) & 3;
- else {
- delta = (page - dma->period_real);
- if (delta < 0)
- delta += dma->nr_periods;
- }
- if (delta == 0)
- return 0;
-
- /* refresh hw page table */
- if (dma->nr_periods > 4) {
- for (i = 0; i < delta; i++) {
- /* p: audio buffer page index */
- p = dma->period_virt + i + 4;
- if (p >= dma->nr_periods)
- p -= dma->nr_periods;
- /* pp: hardware DMA page index. */
- pp = dma->period_real + i;
- if (pp >= 4)
- pp -= 4;
- //hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), dma->table[p].addr);
- hwwrite(vortex->mmio,
- VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2),
- snd_pcm_sgbuf_get_addr(dma->substream,
- dma->period_bytes * p));
- /* Force write thru cache. */
- hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE +
- (((adbdma << 2) + pp) << 2));
- }
- }
- dma->period_virt += delta;
- dma->period_real = page;
- if (dma->period_virt >= dma->nr_periods)
- dma->period_virt -= dma->nr_periods;
- if (delta != 1)
- printk(KERN_INFO "vortex: %d virt=%d, real=%d, delta=%d\n",
- adbdma, dma->period_virt, dma->period_real, delta);
-
- return delta;
-}
-
-
-static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) {
- stream_t *dma = &vortex->dma_adb[adbdma];
- int p, pp, i;
-
- /* refresh hw page table */
- for (i=0 ; i < 4 && i < dma->nr_periods; i++) {
- /* p: audio buffer page index */
- p = dma->period_virt + i;
- if (p >= dma->nr_periods)
- p -= dma->nr_periods;
- /* pp: hardware DMA page index. */
- pp = dma->period_real + i;
- if (dma->nr_periods < 4) {
- if (pp >= dma->nr_periods)
- pp -= dma->nr_periods;
- }
- else {
- if (pp >= 4)
- pp -= 4;
- }
- hwwrite(vortex->mmio,
- VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2),
- snd_pcm_sgbuf_get_addr(dma->substream,
- dma->period_bytes * p));
- /* Force write thru cache. */
- hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (((adbdma << 2)+pp) << 2));
- }
-}
-
-static inline int vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma)
-{
- stream_t *dma = &vortex->dma_adb[adbdma];
- int temp, page, delta;
-
- temp = hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2));
- page = (temp & ADB_SUBBUF_MASK) >> ADB_SUBBUF_SHIFT;
- if (dma->nr_periods >= 4)
- delta = (page - dma->period_real) & 3;
- else {
- delta = (page - dma->period_real);
- if (delta < 0)
- delta += dma->nr_periods;
- }
- return (dma->period_virt + delta) * dma->period_bytes
- + (temp & (dma->period_bytes - 1));
-}
-
-static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma)
-{
- int this_8 = 0 /*empty */ , this_4 = 0 /*priority */ ;
- stream_t *dma = &vortex->dma_adb[adbdma];
-
- switch (dma->fifo_status) {
- case FIFO_START:
- vortex_fifo_setadbvalid(vortex, adbdma,
- dma->fifo_enabled ? 1 : 0);
- break;
- case FIFO_STOP:
- this_8 = 1;
- hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
- dma->dma_ctrl);
- vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
- this_4, this_8,
- dma->fifo_enabled ? 1 : 0, 0);
- break;
- case FIFO_PAUSE:
- vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
- this_4, this_8,
- dma->fifo_enabled ? 1 : 0, 0);
- break;
- }
- dma->fifo_status = FIFO_START;
-}
-
-static void vortex_adbdma_resumefifo(vortex_t * vortex, int adbdma)
-{
- stream_t *dma = &vortex->dma_adb[adbdma];
-
- int this_8 = 1, this_4 = 0;
- switch (dma->fifo_status) {
- case FIFO_STOP:
- hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
- dma->dma_ctrl);
- vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
- this_4, this_8,
- dma->fifo_enabled ? 1 : 0, 0);
- break;
- case FIFO_PAUSE:
- vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
- this_4, this_8,
- dma->fifo_enabled ? 1 : 0, 0);
- break;
- }
- dma->fifo_status = FIFO_START;
-}
-
-static void vortex_adbdma_pausefifo(vortex_t * vortex, int adbdma)
-{
- stream_t *dma = &vortex->dma_adb[adbdma];
-
- int this_8 = 0, this_4 = 0;
- switch (dma->fifo_status) {
- case FIFO_START:
- vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
- this_4, this_8, 0, 0);
- break;
- case FIFO_STOP:
- hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
- dma->dma_ctrl);
- vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
- this_4, this_8, 0, 0);
- break;
- }
- dma->fifo_status = FIFO_PAUSE;
-}
-
-static void vortex_adbdma_stopfifo(vortex_t * vortex, int adbdma)
-{
- stream_t *dma = &vortex->dma_adb[adbdma];
-
- int this_4 = 0, this_8 = 0;
- if (dma->fifo_status == FIFO_START)
- vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
- this_4, this_8, 0, 0);
- else if (dma->fifo_status == FIFO_STOP)
- return;
- dma->fifo_status = FIFO_STOP;
- dma->fifo_enabled = 0;
-}
-
-/* WTDMA */
-
-#ifndef CHIP_AU8810
-static void vortex_wtdma_setfirstbuffer(vortex_t * vortex, int wtdma)
-{
- //int this_7c=dma_ctrl;
- stream_t *dma = &vortex->dma_wt[wtdma];
-
- hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2), dma->dma_ctrl);
-}
-
-static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb)
-{
- stream_t *dma = &vortex->dma_wt[wtdma];
- //hwwrite(vortex->mmio, VORTEX_WTDMA_START + (wtdma << 2), sb << ((0x1f-(wtdma&0xf)*2)));
- hwwrite(vortex->mmio, VORTEX_WTDMA_START + (wtdma << 2),
- sb << ((0xf - (wtdma & 0xf)) * 2));
- dma->period_real = dma->period_virt = sb;
-}
-
-static void
-vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,
- int psize, int count)
-{
- stream_t *dma = &vortex->dma_wt[wtdma];
-
- dma->period_bytes = psize;
- dma->nr_periods = count;
-
- dma->cfg0 = 0;
- dma->cfg1 = 0;
- switch (count) {
- /* Four or more pages */
- default:
- case 4:
- dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize-1);
- hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0xc,
- snd_pcm_sgbuf_get_addr(dma->substream, psize * 3));
- /* 3 pages */
- case 3:
- dma->cfg0 |= 0x12000000;
- dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc);
- hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x8,
- snd_pcm_sgbuf_get_addr(dma->substream, psize * 2));
- /* 2 pages */
- case 2:
- dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize-1);
- hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x4,
- snd_pcm_sgbuf_get_addr(dma->substream, psize));
- /* 1 page */
- case 1:
- dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc);
- hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4),
- snd_pcm_sgbuf_get_addr(dma->substream, 0));
- break;
- }
- hwwrite(vortex->mmio, VORTEX_WTDMA_BUFCFG0 + (wtdma << 3), dma->cfg0);
- hwwrite(vortex->mmio, VORTEX_WTDMA_BUFCFG1 + (wtdma << 3), dma->cfg1);
-
- vortex_wtdma_setfirstbuffer(vortex, wtdma);
- vortex_wtdma_setstartbuffer(vortex, wtdma, 0);
-}
-
-static void
-vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d,
- /*int e, */ u32 offset)
-{
- stream_t *dma = &vortex->dma_wt[wtdma];
-
- //dma->this_08 = e;
- dma->dma_unknown = d;
- dma->dma_ctrl = 0;
- dma->dma_ctrl =
- ((offset & OFFSET_MASK) | (dma->dma_ctrl & ~OFFSET_MASK));
- /* PCMOUT interrupt */
- dma->dma_ctrl =
- (dma->dma_ctrl & ~IE_MASK) | ((ie << IE_SHIFT) & IE_MASK);
- /* Always playback. */
- dma->dma_ctrl |= (1 << DIR_SHIFT);
- /* Audio Format */
- dma->dma_ctrl =
- (dma->dma_ctrl & FMT_MASK) | ((fmt << FMT_SHIFT) & FMT_MASK);
- /* Write into hardware */
- hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2), dma->dma_ctrl);
-}
-
-static int vortex_wtdma_bufshift(vortex_t * vortex, int wtdma)
-{
- stream_t *dma = &vortex->dma_wt[wtdma];
- int page, p, pp, delta, i;
-
- page =
- (hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2)) &
- WT_SUBBUF_MASK)
- >> WT_SUBBUF_SHIFT;
- if (dma->nr_periods >= 4)
- delta = (page - dma->period_real) & 3;
- else {
- delta = (page - dma->period_real);
- if (delta < 0)
- delta += dma->nr_periods;
- }
- if (delta == 0)
- return 0;
-
- /* refresh hw page table */
- if (dma->nr_periods > 4) {
- for (i = 0; i < delta; i++) {
- /* p: audio buffer page index */
- p = dma->period_virt + i + 4;
- if (p >= dma->nr_periods)
- p -= dma->nr_periods;
- /* pp: hardware DMA page index. */
- pp = dma->period_real + i;
- if (pp >= 4)
- pp -= 4;
- hwwrite(vortex->mmio,
- VORTEX_WTDMA_BUFBASE +
- (((wtdma << 2) + pp) << 2),
- snd_pcm_sgbuf_get_addr(dma->substream,
- dma->period_bytes * p));
- /* Force write thru cache. */
- hwread(vortex->mmio, VORTEX_WTDMA_BUFBASE +
- (((wtdma << 2) + pp) << 2));
- }
- }
- dma->period_virt += delta;
- if (dma->period_virt >= dma->nr_periods)
- dma->period_virt -= dma->nr_periods;
- dma->period_real = page;
-
- if (delta != 1)
- printk(KERN_WARNING "vortex: wt virt = %d, delta = %d\n",
- dma->period_virt, delta);
-
- return delta;
-}
-
-#if 0
-static void
-vortex_wtdma_getposition(vortex_t * vortex, int wtdma, int *subbuf, int *pos)
-{
- int temp;
- temp = hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2));
- *subbuf = (temp >> WT_SUBBUF_SHIFT) & WT_SUBBUF_MASK;
- *pos = temp & POS_MASK;
-}
-
-static int vortex_wtdma_getcursubuffer(vortex_t * vortex, int wtdma)
-{
- return ((hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2)) >>
- POS_SHIFT) & POS_MASK);
-}
-#endif
-static inline int vortex_wtdma_getlinearpos(vortex_t * vortex, int wtdma)
-{
- stream_t *dma = &vortex->dma_wt[wtdma];
- int temp;
-
- temp = hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2));
- temp = (dma->period_virt * dma->period_bytes) + (temp & (dma->period_bytes - 1));
- return temp;
-}
-
-static void vortex_wtdma_startfifo(vortex_t * vortex, int wtdma)
-{
- stream_t *dma = &vortex->dma_wt[wtdma];
- int this_8 = 0, this_4 = 0;
-
- switch (dma->fifo_status) {
- case FIFO_START:
- vortex_fifo_setwtvalid(vortex, wtdma,
- dma->fifo_enabled ? 1 : 0);
- break;
- case FIFO_STOP:
- this_8 = 1;
- hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2),
- dma->dma_ctrl);
- vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
- this_4, this_8,
- dma->fifo_enabled ? 1 : 0, 0);
- break;
- case FIFO_PAUSE:
- vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
- this_4, this_8,
- dma->fifo_enabled ? 1 : 0, 0);
- break;
- }
- dma->fifo_status = FIFO_START;
-}
-
-static void vortex_wtdma_resumefifo(vortex_t * vortex, int wtdma)
-{
- stream_t *dma = &vortex->dma_wt[wtdma];
-
- int this_8 = 0, this_4 = 0;
- switch (dma->fifo_status) {
- case FIFO_STOP:
- hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2),
- dma->dma_ctrl);
- vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
- this_4, this_8,
- dma->fifo_enabled ? 1 : 0, 0);
- break;
- case FIFO_PAUSE:
- vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
- this_4, this_8,
- dma->fifo_enabled ? 1 : 0, 0);
- break;
- }
- dma->fifo_status = FIFO_START;
-}
-
-static void vortex_wtdma_pausefifo(vortex_t * vortex, int wtdma)
-{
- stream_t *dma = &vortex->dma_wt[wtdma];
-
- int this_8 = 0, this_4 = 0;
- switch (dma->fifo_status) {
- case FIFO_START:
- vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
- this_4, this_8, 0, 0);
- break;
- case FIFO_STOP:
- hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2),
- dma->dma_ctrl);
- vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
- this_4, this_8, 0, 0);
- break;
- }
- dma->fifo_status = FIFO_PAUSE;
-}
-
-static void vortex_wtdma_stopfifo(vortex_t * vortex, int wtdma)
-{
- stream_t *dma = &vortex->dma_wt[wtdma];
-
- int this_4 = 0, this_8 = 0;
- if (dma->fifo_status == FIFO_START)
- vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
- this_4, this_8, 0, 0);
- else if (dma->fifo_status == FIFO_STOP)
- return;
- dma->fifo_status = FIFO_STOP;
- dma->fifo_enabled = 0;
-}
-
-#endif
-/* ADB Routes */
-
-typedef int ADBRamLink;
-static void vortex_adb_init(vortex_t * vortex)
-{
- int i;
- /* it looks like we are writing more than we need to...
- * if we write what we are supposed to it breaks things... */
- hwwrite(vortex->mmio, VORTEX_ADB_SR, 0);
- for (i = 0; i < VORTEX_ADB_RTBASE_COUNT; i++)
- hwwrite(vortex->mmio, VORTEX_ADB_RTBASE + (i << 2),
- hwread(vortex->mmio,
- VORTEX_ADB_RTBASE + (i << 2)) | ROUTE_MASK);
- for (i = 0; i < VORTEX_ADB_CHNBASE_COUNT; i++) {
- hwwrite(vortex->mmio, VORTEX_ADB_CHNBASE + (i << 2),
- hwread(vortex->mmio,
- VORTEX_ADB_CHNBASE + (i << 2)) | ROUTE_MASK);
- }
-}
-
-static void vortex_adb_en_sr(vortex_t * vortex, int channel)
-{
- hwwrite(vortex->mmio, VORTEX_ADB_SR,
- hwread(vortex->mmio, VORTEX_ADB_SR) | (0x1 << channel));
-}
-
-static void vortex_adb_dis_sr(vortex_t * vortex, int channel)
-{
- hwwrite(vortex->mmio, VORTEX_ADB_SR,
- hwread(vortex->mmio, VORTEX_ADB_SR) & ~(0x1 << channel));
-}
-
-static void
-vortex_adb_addroutes(vortex_t * vortex, unsigned char channel,
- ADBRamLink * route, int rnum)
-{
- int temp, prev, lifeboat = 0;
-
- if ((rnum <= 0) || (route == NULL))
- return;
- /* Write last routes. */
- rnum--;
- hwwrite(vortex->mmio,
- VORTEX_ADB_RTBASE + ((route[rnum] & ADB_MASK) << 2),
- ROUTE_MASK);
- while (rnum > 0) {
- hwwrite(vortex->mmio,
- VORTEX_ADB_RTBASE +
- ((route[rnum - 1] & ADB_MASK) << 2), route[rnum]);
- rnum--;
- }
- /* Write first route. */
- temp =
- hwread(vortex->mmio,
- VORTEX_ADB_CHNBASE + (channel << 2)) & ADB_MASK;
- if (temp == ADB_MASK) {
- /* First entry on this channel. */
- hwwrite(vortex->mmio, VORTEX_ADB_CHNBASE + (channel << 2),
- route[0]);
- vortex_adb_en_sr(vortex, channel);
- return;
- }
- /* Not first entry on this channel. Need to link. */
- do {
- prev = temp;
- temp =
- hwread(vortex->mmio,
- VORTEX_ADB_RTBASE + (temp << 2)) & ADB_MASK;
- if ((lifeboat++) > ADB_MASK) {
- printk(KERN_ERR
- "vortex_adb_addroutes: unending route! 0x%x\n",
- *route);
- return;
- }
- }
- while (temp != ADB_MASK);
- hwwrite(vortex->mmio, VORTEX_ADB_RTBASE + (prev << 2), route[0]);
-}
-
-static void
-vortex_adb_delroutes(vortex_t * vortex, unsigned char channel,
- ADBRamLink route0, ADBRamLink route1)
-{
- int temp, lifeboat = 0, prev;
-
- /* Find route. */
- temp =
- hwread(vortex->mmio,
- VORTEX_ADB_CHNBASE + (channel << 2)) & ADB_MASK;
- if (temp == (route0 & ADB_MASK)) {
- temp =
- hwread(vortex->mmio,
- VORTEX_ADB_RTBASE + ((route1 & ADB_MASK) << 2));
- if ((temp & ADB_MASK) == ADB_MASK)
- vortex_adb_dis_sr(vortex, channel);
- hwwrite(vortex->mmio, VORTEX_ADB_CHNBASE + (channel << 2),
- temp);
- return;
- }
- do {
- prev = temp;
- temp =
- hwread(vortex->mmio,
- VORTEX_ADB_RTBASE + (prev << 2)) & ADB_MASK;
- if (((lifeboat++) > ADB_MASK) || (temp == ADB_MASK)) {
- printk(KERN_ERR
- "vortex_adb_delroutes: route not found! 0x%x\n",
- route0);
- return;
- }
- }
- while (temp != (route0 & ADB_MASK));
- temp = hwread(vortex->mmio, VORTEX_ADB_RTBASE + (temp << 2));
- if ((temp & ADB_MASK) == route1)
- temp = hwread(vortex->mmio, VORTEX_ADB_RTBASE + (temp << 2));
- /* Make bridge over deleted route. */
- hwwrite(vortex->mmio, VORTEX_ADB_RTBASE + (prev << 2), temp);
-}
-
-static void
-vortex_route(vortex_t * vortex, int en, unsigned char channel,
- unsigned char source, unsigned char dest)
-{
- ADBRamLink route;
-
- route = ((source & ADB_MASK) << ADB_SHIFT) | (dest & ADB_MASK);
- if (en) {
- vortex_adb_addroutes(vortex, channel, &route, 1);
- if ((source < (OFFSET_SRCOUT + NR_SRC))
- && (source >= OFFSET_SRCOUT))
- vortex_src_addWTD(vortex, (source - OFFSET_SRCOUT),
- channel);
- else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))
- && (source >= OFFSET_MIXOUT))
- vortex_mixer_addWTD(vortex,
- (source - OFFSET_MIXOUT), channel);
- } else {
- vortex_adb_delroutes(vortex, channel, route, route);
- if ((source < (OFFSET_SRCOUT + NR_SRC))
- && (source >= OFFSET_SRCOUT))
- vortex_src_delWTD(vortex, (source - OFFSET_SRCOUT),
- channel);
- else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))
- && (source >= OFFSET_MIXOUT))
- vortex_mixer_delWTD(vortex,
- (source - OFFSET_MIXOUT), channel);
- }
-}
-
-#if 0
-static void
-vortex_routes(vortex_t * vortex, int en, unsigned char channel,
- unsigned char source, unsigned char dest0, unsigned char dest1)
-{
- ADBRamLink route[2];
-
- route[0] = ((source & ADB_MASK) << ADB_SHIFT) | (dest0 & ADB_MASK);
- route[1] = ((source & ADB_MASK) << ADB_SHIFT) | (dest1 & ADB_MASK);
-
- if (en) {
- vortex_adb_addroutes(vortex, channel, route, 2);
- if ((source < (OFFSET_SRCOUT + NR_SRC))
- && (source >= (OFFSET_SRCOUT)))
- vortex_src_addWTD(vortex, (source - OFFSET_SRCOUT),
- channel);
- else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))
- && (source >= (OFFSET_MIXOUT)))
- vortex_mixer_addWTD(vortex,
- (source - OFFSET_MIXOUT), channel);
- } else {
- vortex_adb_delroutes(vortex, channel, route[0], route[1]);
- if ((source < (OFFSET_SRCOUT + NR_SRC))
- && (source >= (OFFSET_SRCOUT)))
- vortex_src_delWTD(vortex, (source - OFFSET_SRCOUT),
- channel);
- else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))
- && (source >= (OFFSET_MIXOUT)))
- vortex_mixer_delWTD(vortex,
- (source - OFFSET_MIXOUT), channel);
- }
-}
-
-#endif
-/* Route two sources to same target. Sources must be of same class !!! */
-static void
-vortex_routeLRT(vortex_t * vortex, int en, unsigned char ch,
- unsigned char source0, unsigned char source1,
- unsigned char dest)
-{
- ADBRamLink route[2];
-
- route[0] = ((source0 & ADB_MASK) << ADB_SHIFT) | (dest & ADB_MASK);
- route[1] = ((source1 & ADB_MASK) << ADB_SHIFT) | (dest & ADB_MASK);
-
- if (dest < 0x10)
- route[1] = (route[1] & ~ADB_MASK) | (dest + 0x20); /* fifo A */
-
- if (en) {
- vortex_adb_addroutes(vortex, ch, route, 2);
- if ((source0 < (OFFSET_SRCOUT + NR_SRC))
- && (source0 >= OFFSET_SRCOUT)) {
- vortex_src_addWTD(vortex,
- (source0 - OFFSET_SRCOUT), ch);
- vortex_src_addWTD(vortex,
- (source1 - OFFSET_SRCOUT), ch);
- } else if ((source0 < (OFFSET_MIXOUT + NR_MIXOUT))
- && (source0 >= OFFSET_MIXOUT)) {
- vortex_mixer_addWTD(vortex,
- (source0 - OFFSET_MIXOUT), ch);
- vortex_mixer_addWTD(vortex,
- (source1 - OFFSET_MIXOUT), ch);
- }
- } else {
- vortex_adb_delroutes(vortex, ch, route[0], route[1]);
- if ((source0 < (OFFSET_SRCOUT + NR_SRC))
- && (source0 >= OFFSET_SRCOUT)) {
- vortex_src_delWTD(vortex,
- (source0 - OFFSET_SRCOUT), ch);
- vortex_src_delWTD(vortex,
- (source1 - OFFSET_SRCOUT), ch);
- } else if ((source0 < (OFFSET_MIXOUT + NR_MIXOUT))
- && (source0 >= OFFSET_MIXOUT)) {
- vortex_mixer_delWTD(vortex,
- (source0 - OFFSET_MIXOUT), ch);
- vortex_mixer_delWTD(vortex,
- (source1 - OFFSET_MIXOUT), ch);
- }
- }
-}
-
-/* Connection stuff */
-
-// Connect adbdma to src('s).
-static void
-vortex_connection_adbdma_src(vortex_t * vortex, int en, unsigned char ch,
- unsigned char adbdma, unsigned char src)
-{
- vortex_route(vortex, en, ch, ADB_DMA(adbdma), ADB_SRCIN(src));
-}
-
-// Connect SRC to mixin.
-static void
-vortex_connection_src_mixin(vortex_t * vortex, int en,
- unsigned char channel, unsigned char src,
- unsigned char mixin)
-{
- vortex_route(vortex, en, channel, ADB_SRCOUT(src), ADB_MIXIN(mixin));
-}
-
-// Connect mixin with mix output.
-static void
-vortex_connection_mixin_mix(vortex_t * vortex, int en, unsigned char mixin,
- unsigned char mix, int a)
-{
- if (en) {
- vortex_mix_enableinput(vortex, mix, mixin);
- vortex_mix_setinputvolumebyte(vortex, mix, mixin, MIX_DEFIGAIN); // added to original code.
- } else
- vortex_mix_disableinput(vortex, mix, mixin, a);
-}
-
-// Connect absolut address to mixin.
-static void
-vortex_connection_adb_mixin(vortex_t * vortex, int en,
- unsigned char channel, unsigned char source,
- unsigned char mixin)
-{
- vortex_route(vortex, en, channel, source, ADB_MIXIN(mixin));
-}
-
-static void
-vortex_connection_src_adbdma(vortex_t * vortex, int en, unsigned char ch,
- unsigned char src, unsigned char adbdma)
-{
- vortex_route(vortex, en, ch, ADB_SRCOUT(src), ADB_DMA(adbdma));
-}
-
-static void
-vortex_connection_src_src_adbdma(vortex_t * vortex, int en,
- unsigned char ch, unsigned char src0,
- unsigned char src1, unsigned char adbdma)
-{
-
- vortex_routeLRT(vortex, en, ch, ADB_SRCOUT(src0), ADB_SRCOUT(src1),
- ADB_DMA(adbdma));
-}
-
-// mix to absolut address.
-static void
-vortex_connection_mix_adb(vortex_t * vortex, int en, unsigned char ch,
- unsigned char mix, unsigned char dest)
-{
- vortex_route(vortex, en, ch, ADB_MIXOUT(mix), dest);
- vortex_mix_setvolumebyte(vortex, mix, MIX_DEFOGAIN); // added to original code.
-}
-
-// mixer to src.
-static void
-vortex_connection_mix_src(vortex_t * vortex, int en, unsigned char ch,
- unsigned char mix, unsigned char src)
-{
- vortex_route(vortex, en, ch, ADB_MIXOUT(mix), ADB_SRCIN(src));
- vortex_mix_setvolumebyte(vortex, mix, MIX_DEFOGAIN); // added to original code.
-}
-
-#if 0
-static void
-vortex_connection_adbdma_src_src(vortex_t * vortex, int en,
- unsigned char channel,
- unsigned char adbdma, unsigned char src0,
- unsigned char src1)
-{
- vortex_routes(vortex, en, channel, ADB_DMA(adbdma),
- ADB_SRCIN(src0), ADB_SRCIN(src1));
-}
-
-// Connect two mix to AdbDma.
-static void
-vortex_connection_mix_mix_adbdma(vortex_t * vortex, int en,
- unsigned char ch, unsigned char mix0,
- unsigned char mix1, unsigned char adbdma)
-{
-
- ADBRamLink routes[2];
- routes[0] =
- (((mix0 +
- OFFSET_MIXOUT) & ADB_MASK) << ADB_SHIFT) | (adbdma & ADB_MASK);
- routes[1] =
- (((mix1 + OFFSET_MIXOUT) & ADB_MASK) << ADB_SHIFT) | ((adbdma +
- 0x20) &
- ADB_MASK);
- if (en) {
- vortex_adb_addroutes(vortex, ch, routes, 0x2);
- vortex_mixer_addWTD(vortex, mix0, ch);
- vortex_mixer_addWTD(vortex, mix1, ch);
- } else {
- vortex_adb_delroutes(vortex, ch, routes[0], routes[1]);
- vortex_mixer_delWTD(vortex, mix0, ch);
- vortex_mixer_delWTD(vortex, mix1, ch);
- }
-}
-#endif
-
-/* CODEC connect. */
-
-static void
-vortex_connect_codecplay(vortex_t * vortex, int en, unsigned char mixers[])
-{
-#ifdef CHIP_AU8820
- vortex_connection_mix_adb(vortex, en, 0x11, mixers[0], ADB_CODECOUT(0));
- vortex_connection_mix_adb(vortex, en, 0x11, mixers[1], ADB_CODECOUT(1));
-#else
-#if 1
- // Connect front channels through EQ.
- vortex_connection_mix_adb(vortex, en, 0x11, mixers[0], ADB_EQIN(0));
- vortex_connection_mix_adb(vortex, en, 0x11, mixers[1], ADB_EQIN(1));
- /* Lower volume, since EQ has some gain. */
- vortex_mix_setvolumebyte(vortex, mixers[0], 0);
- vortex_mix_setvolumebyte(vortex, mixers[1], 0);
- vortex_route(vortex, en, 0x11, ADB_EQOUT(0), ADB_CODECOUT(0));
- vortex_route(vortex, en, 0x11, ADB_EQOUT(1), ADB_CODECOUT(1));
-
- /* Check if reg 0x28 has SDAC bit set. */
- if (VORTEX_IS_QUAD(vortex)) {
- /* Rear channel. Note: ADB_CODECOUT(0+2) and (1+2) is for AC97 modem */
- vortex_connection_mix_adb(vortex, en, 0x11, mixers[2],
- ADB_CODECOUT(0 + 4));
- vortex_connection_mix_adb(vortex, en, 0x11, mixers[3],
- ADB_CODECOUT(1 + 4));
- /* printk(KERN_DEBUG "SDAC detected "); */
- }
-#else
- // Use plain direct output to codec.
- vortex_connection_mix_adb(vortex, en, 0x11, mixers[0], ADB_CODECOUT(0));
- vortex_connection_mix_adb(vortex, en, 0x11, mixers[1], ADB_CODECOUT(1));
-#endif
-#endif
-}
-
-static void
-vortex_connect_codecrec(vortex_t * vortex, int en, unsigned char mixin0,
- unsigned char mixin1)
-{
- /*
- Enable: 0x1, 0x1
- Channel: 0x11, 0x11
- ADB Source address: 0x48, 0x49
- Destination Asp4Topology_0x9c,0x98
- */
- vortex_connection_adb_mixin(vortex, en, 0x11, ADB_CODECIN(0), mixin0);
- vortex_connection_adb_mixin(vortex, en, 0x11, ADB_CODECIN(1), mixin1);
-}
-
-// Higher level ADB audio path (de)allocator.
-
-/* Resource manager */
-static int resnum[VORTEX_RESOURCE_LAST] =
- { NR_ADB, NR_SRC, NR_MIXIN, NR_MIXOUT, NR_A3D };
-/*
- Checkout/Checkin resource of given type.
- resmap: resource map to be used. If NULL means that we want to allocate
- a DMA resource (root of all other resources of a dma channel).
- out: Mean checkout if != 0. Else mean Checkin resource.
- restype: Indicates type of resource to be checked in or out.
-*/
-static char
-vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype)
-{
- int i, qty = resnum[restype], resinuse = 0;
-
- if (out) {
- /* Gather used resources by all streams. */
- for (i = 0; i < NR_ADB; i++) {
- resinuse |= vortex->dma_adb[i].resources[restype];
- }
- resinuse |= vortex->fixed_res[restype];
- /* Find and take free resource. */
- for (i = 0; i < qty; i++) {
- if ((resinuse & (1 << i)) == 0) {
- if (resmap != NULL)
- resmap[restype] |= (1 << i);
- else
- vortex->dma_adb[i].resources[restype] |= (1 << i);
- /*
- printk(KERN_DEBUG
- "vortex: ResManager: type %d out %d\n",
- restype, i);
- */
- return i;
- }
- }
- } else {
- if (resmap == NULL)
- return -EINVAL;
- /* Checkin first resource of type restype. */
- for (i = 0; i < qty; i++) {
- if (resmap[restype] & (1 << i)) {
- resmap[restype] &= ~(1 << i);
- /*
- printk(KERN_DEBUG
- "vortex: ResManager: type %d in %d\n",
- restype, i);
- */
- return i;
- }
- }
- }
- printk(KERN_ERR "vortex: FATAL: ResManager: resource type %d exhausted.\n", restype);
- return -ENOMEM;
-}
-
-/* Default Connections */
-
-static void vortex_connect_default(vortex_t * vortex, int en)
-{
- // Connect AC97 codec.
- vortex->mixplayb[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
- VORTEX_RESOURCE_MIXOUT);
- vortex->mixplayb[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
- VORTEX_RESOURCE_MIXOUT);
- if (VORTEX_IS_QUAD(vortex)) {
- vortex->mixplayb[2] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
- VORTEX_RESOURCE_MIXOUT);
- vortex->mixplayb[3] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
- VORTEX_RESOURCE_MIXOUT);
- }
- vortex_connect_codecplay(vortex, en, vortex->mixplayb);
-
- vortex->mixcapt[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
- VORTEX_RESOURCE_MIXIN);
- vortex->mixcapt[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
- VORTEX_RESOURCE_MIXIN);
- vortex_connect_codecrec(vortex, en, MIX_CAPT(0), MIX_CAPT(1));
-
- // Connect SPDIF
-#ifndef CHIP_AU8820
- vortex->mixspdif[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
- VORTEX_RESOURCE_MIXOUT);
- vortex->mixspdif[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
- VORTEX_RESOURCE_MIXOUT);
- vortex_connection_mix_adb(vortex, en, 0x14, vortex->mixspdif[0],
- ADB_SPDIFOUT(0));
- vortex_connection_mix_adb(vortex, en, 0x14, vortex->mixspdif[1],
- ADB_SPDIFOUT(1));
-#endif
- // Connect WT
-#ifndef CHIP_AU8810
- vortex_wt_connect(vortex, en);
-#endif
- // A3D (crosstalk canceler and A3D slices). AU8810 disabled for now.
-#ifndef CHIP_AU8820
- vortex_Vort3D_connect(vortex, en);
-#endif
- // Connect I2S
-
- // Connect DSP interface for SQ3500 turbo (not here i think...)
-
- // Connect AC98 modem codec
-
-}
-
-/*
- Allocate nr_ch pcm audio routes if dma < 0. If dma >= 0, existing routes
- are deallocated.
- dma: DMA engine routes to be deallocated when dma >= 0.
- nr_ch: Number of channels to be de/allocated.
- dir: direction of stream. Uses same values as substream->stream.
- type: Type of audio output/source (codec, spdif, i2s, dsp, etc)
- Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0.
-*/
-static int
-vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir,
- int type, int subdev)
-{
- stream_t *stream;
- int i, en;
- struct pcm_vol *p;
-
- if (dma >= 0) {
- en = 0;
- vortex_adb_checkinout(vortex,
- vortex->dma_adb[dma].resources, en,
- VORTEX_RESOURCE_DMA);
- } else {
- en = 1;
- if ((dma =
- vortex_adb_checkinout(vortex, NULL, en,
- VORTEX_RESOURCE_DMA)) < 0)
- return -EBUSY;
- }
-
- stream = &vortex->dma_adb[dma];
- stream->dma = dma;
- stream->dir = dir;
- stream->type = type;
-
- /* PLAYBACK ROUTES. */
- if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
- int src[4], mix[4], ch_top;
-#ifndef CHIP_AU8820
- int a3d = 0;
-#endif
- /* Get SRC and MIXER hardware resources. */
- if (stream->type != VORTEX_PCM_SPDIF) {
- for (i = 0; i < nr_ch; i++) {
- if ((src[i] = vortex_adb_checkinout(vortex,
- stream->resources, en,
- VORTEX_RESOURCE_SRC)) < 0) {
- memset(stream->resources, 0,
- sizeof(unsigned char) *
- VORTEX_RESOURCE_LAST);
- return -EBUSY;
- }
- if (stream->type != VORTEX_PCM_A3D) {
- if ((mix[i] = vortex_adb_checkinout(vortex,
- stream->resources,
- en,
- VORTEX_RESOURCE_MIXIN)) < 0) {
- memset(stream->resources,
- 0,
- sizeof(unsigned char) * VORTEX_RESOURCE_LAST);
- return -EBUSY;
- }
- }
- }
- }
-#ifndef CHIP_AU8820
- if (stream->type == VORTEX_PCM_A3D) {
- if ((a3d =
- vortex_adb_checkinout(vortex,
- stream->resources, en,
- VORTEX_RESOURCE_A3D)) < 0) {
- memset(stream->resources, 0,
- sizeof(unsigned char) *
- VORTEX_RESOURCE_LAST);
- printk(KERN_ERR "vortex: out of A3D sources. Sorry\n");
- return -EBUSY;
- }
- /* (De)Initialize A3D hardware source. */
- vortex_Vort3D_InitializeSource(&(vortex->a3d[a3d]), en);
- }
- /* Make SPDIF out exclusive to "spdif" device when in use. */
- if ((stream->type == VORTEX_PCM_SPDIF) && (en)) {
- vortex_route(vortex, 0, 0x14,
- ADB_MIXOUT(vortex->mixspdif[0]),
- ADB_SPDIFOUT(0));
- vortex_route(vortex, 0, 0x14,
- ADB_MIXOUT(vortex->mixspdif[1]),
- ADB_SPDIFOUT(1));
- }
-#endif
- /* Make playback routes. */
- for (i = 0; i < nr_ch; i++) {
- if (stream->type == VORTEX_PCM_ADB) {
- vortex_connection_adbdma_src(vortex, en,
- src[nr_ch - 1],
- dma,
- src[i]);
- vortex_connection_src_mixin(vortex, en,
- 0x11, src[i],
- mix[i]);
- vortex_connection_mixin_mix(vortex, en,
- mix[i],
- MIX_PLAYB(i), 0);
-#ifndef CHIP_AU8820
- vortex_connection_mixin_mix(vortex, en,
- mix[i],
- MIX_SPDIF(i % 2), 0);
- vortex_mix_setinputvolumebyte(vortex,
- MIX_SPDIF(i % 2),
- mix[i],
- MIX_DEFIGAIN);
-#endif
- }
-#ifndef CHIP_AU8820
- if (stream->type == VORTEX_PCM_A3D) {
- vortex_connection_adbdma_src(vortex, en,
- src[nr_ch - 1],
- dma,
- src[i]);
- vortex_route(vortex, en, 0x11, ADB_SRCOUT(src[i]), ADB_A3DIN(a3d));
- /* XTalk test. */
- //vortex_route(vortex, en, 0x11, dma, ADB_XTALKIN(i?9:4));
- //vortex_route(vortex, en, 0x11, ADB_SRCOUT(src[i]), ADB_XTALKIN(i?4:9));
- }
- if (stream->type == VORTEX_PCM_SPDIF)
- vortex_route(vortex, en, 0x14,
- ADB_DMA(stream->dma),
- ADB_SPDIFOUT(i));
-#endif
- }
- if (stream->type != VORTEX_PCM_SPDIF && stream->type != VORTEX_PCM_A3D) {
- ch_top = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
- for (i = nr_ch; i < ch_top; i++) {
- vortex_connection_mixin_mix(vortex, en,
- mix[i % nr_ch],
- MIX_PLAYB(i), 0);
-#ifndef CHIP_AU8820
- vortex_connection_mixin_mix(vortex, en,
- mix[i % nr_ch],
- MIX_SPDIF(i % 2),
- 0);
- vortex_mix_setinputvolumebyte(vortex,
- MIX_SPDIF(i % 2),
- mix[i % nr_ch],
- MIX_DEFIGAIN);
-#endif
- }
- if (stream->type == VORTEX_PCM_ADB && en) {
- p = &vortex->pcm_vol[subdev];
- p->dma = dma;
- for (i = 0; i < nr_ch; i++)
- p->mixin[i] = mix[i];
- for (i = 0; i < ch_top; i++)
- p->vol[i] = 0;
- }
- }
-#ifndef CHIP_AU8820
- else {
- if (nr_ch == 1 && stream->type == VORTEX_PCM_SPDIF)
- vortex_route(vortex, en, 0x14,
- ADB_DMA(stream->dma),
- ADB_SPDIFOUT(1));
- }
- /* Reconnect SPDIF out when "spdif" device is down. */
- if ((stream->type == VORTEX_PCM_SPDIF) && (!en)) {
- vortex_route(vortex, 1, 0x14,
- ADB_MIXOUT(vortex->mixspdif[0]),
- ADB_SPDIFOUT(0));
- vortex_route(vortex, 1, 0x14,
- ADB_MIXOUT(vortex->mixspdif[1]),
- ADB_SPDIFOUT(1));
- }
-#endif
- /* CAPTURE ROUTES. */
- } else {
- int src[2], mix[2];
-
- /* Get SRC and MIXER hardware resources. */
- for (i = 0; i < nr_ch; i++) {
- if ((mix[i] =
- vortex_adb_checkinout(vortex,
- stream->resources, en,
- VORTEX_RESOURCE_MIXOUT))
- < 0) {
- memset(stream->resources, 0,
- sizeof(unsigned char) *
- VORTEX_RESOURCE_LAST);
- return -EBUSY;
- }
- if ((src[i] =
- vortex_adb_checkinout(vortex,
- stream->resources, en,
- VORTEX_RESOURCE_SRC)) < 0) {
- memset(stream->resources, 0,
- sizeof(unsigned char) *
- VORTEX_RESOURCE_LAST);
- return -EBUSY;
- }
- }
-
- /* Make capture routes. */
- vortex_connection_mixin_mix(vortex, en, MIX_CAPT(0), mix[0], 0);
- vortex_connection_mix_src(vortex, en, 0x11, mix[0], src[0]);
- if (nr_ch == 1) {
- vortex_connection_mixin_mix(vortex, en,
- MIX_CAPT(1), mix[0], 0);
- vortex_connection_src_adbdma(vortex, en,
- src[0],
- src[0], dma);
- } else {
- vortex_connection_mixin_mix(vortex, en,
- MIX_CAPT(1), mix[1], 0);
- vortex_connection_mix_src(vortex, en, 0x11, mix[1],
- src[1]);
- vortex_connection_src_src_adbdma(vortex, en,
- src[1], src[0],
- src[1], dma);
- }
- }
- vortex->dma_adb[dma].nr_ch = nr_ch;
-
-#if 0
- /* AC97 Codec channel setup. FIXME: this has no effect on some cards !! */
- if (nr_ch < 4) {
- /* Copy stereo to rear channel (surround) */
- snd_ac97_write_cache(vortex->codec,
- AC97_SIGMATEL_DAC2INVERT,
- snd_ac97_read(vortex->codec,
- AC97_SIGMATEL_DAC2INVERT)
- | 4);
- } else {
- /* Allow separate front and rear channels. */
- snd_ac97_write_cache(vortex->codec,
- AC97_SIGMATEL_DAC2INVERT,
- snd_ac97_read(vortex->codec,
- AC97_SIGMATEL_DAC2INVERT)
- & ~((u32)
- 4));
- }
-#endif
- return dma;
-}
-
-/*
- Set the SampleRate of the SRC's attached to the given DMA engine.
- */
-static void
-vortex_adb_setsrc(vortex_t * vortex, int adbdma, unsigned int rate, int dir)
-{
- stream_t *stream = &(vortex->dma_adb[adbdma]);
- int i, cvrt;
-
- /* dir=1:play ; dir=0:rec */
- if (dir)
- cvrt = SRC_RATIO(rate, 48000);
- else
- cvrt = SRC_RATIO(48000, rate);
-
- /* Setup SRC's */
- for (i = 0; i < NR_SRC; i++) {
- if (stream->resources[VORTEX_RESOURCE_SRC] & (1 << i))
- vortex_src_setupchannel(vortex, i, cvrt, 0, 0, i, dir, 1, cvrt, dir);
- }
-}
-
-// Timer and ISR functions.
-
-static void vortex_settimer(vortex_t * vortex, int period)
-{
- //set the timer period to <period> 48000ths of a second.
- hwwrite(vortex->mmio, VORTEX_IRQ_STAT, period);
-}
-
-#if 0
-static void vortex_enable_timer_int(vortex_t * card)
-{
- hwwrite(card->mmio, VORTEX_IRQ_CTRL,
- hwread(card->mmio, VORTEX_IRQ_CTRL) | IRQ_TIMER | 0x60);
-}
-
-static void vortex_disable_timer_int(vortex_t * card)
-{
- hwwrite(card->mmio, VORTEX_IRQ_CTRL,
- hwread(card->mmio, VORTEX_IRQ_CTRL) & ~IRQ_TIMER);
-}
-
-#endif
-static void vortex_enable_int(vortex_t * card)
-{
- // CAsp4ISR__EnableVortexInt_void_
- hwwrite(card->mmio, VORTEX_CTRL,
- hwread(card->mmio, VORTEX_CTRL) | CTRL_IRQ_ENABLE);
- hwwrite(card->mmio, VORTEX_IRQ_CTRL,
- (hwread(card->mmio, VORTEX_IRQ_CTRL) & 0xffffefc0) | 0x24);
-}
-
-static void vortex_disable_int(vortex_t * card)
-{
- hwwrite(card->mmio, VORTEX_CTRL,
- hwread(card->mmio, VORTEX_CTRL) & ~CTRL_IRQ_ENABLE);
-}
-
-static irqreturn_t vortex_interrupt(int irq, void *dev_id)
-{
- vortex_t *vortex = dev_id;
- int i, handled;
- u32 source;
-
- //check if the interrupt is ours.
- if (!(hwread(vortex->mmio, VORTEX_STAT) & 0x1))
- return IRQ_NONE;
-
- // This is the Interrupt Enable flag we set before (consistency check).
- if (!(hwread(vortex->mmio, VORTEX_CTRL) & CTRL_IRQ_ENABLE))
- return IRQ_NONE;
-
- source = hwread(vortex->mmio, VORTEX_IRQ_SOURCE);
- // Reset IRQ flags.
- hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, source);
- hwread(vortex->mmio, VORTEX_IRQ_SOURCE);
- // Is at least one IRQ flag set?
- if (source == 0) {
- printk(KERN_ERR "vortex: missing irq source\n");
- return IRQ_NONE;
- }
-
- handled = 0;
- // Attend every interrupt source.
- if (unlikely(source & IRQ_ERR_MASK)) {
- if (source & IRQ_FATAL) {
- printk(KERN_ERR "vortex: IRQ fatal error\n");
- }
- if (source & IRQ_PARITY) {
- printk(KERN_ERR "vortex: IRQ parity error\n");
- }
- if (source & IRQ_REG) {
- printk(KERN_ERR "vortex: IRQ reg error\n");
- }
- if (source & IRQ_FIFO) {
- printk(KERN_ERR "vortex: IRQ fifo error\n");
- }
- if (source & IRQ_DMA) {
- printk(KERN_ERR "vortex: IRQ dma error\n");
- }
- handled = 1;
- }
- if (source & IRQ_PCMOUT) {
- /* ALSA period acknowledge. */
- spin_lock(&vortex->lock);
- for (i = 0; i < NR_ADB; i++) {
- if (vortex->dma_adb[i].fifo_status == FIFO_START) {
- if (!vortex_adbdma_bufshift(vortex, i))
- continue;
- spin_unlock(&vortex->lock);
- snd_pcm_period_elapsed(vortex->dma_adb[i].
- substream);
- spin_lock(&vortex->lock);
- }
- }
-#ifndef CHIP_AU8810
- for (i = 0; i < NR_WT; i++) {
- if (vortex->dma_wt[i].fifo_status == FIFO_START) {
- if (vortex_wtdma_bufshift(vortex, i)) ;
- spin_unlock(&vortex->lock);
- snd_pcm_period_elapsed(vortex->dma_wt[i].
- substream);
- spin_lock(&vortex->lock);
- }
- }
-#endif
- spin_unlock(&vortex->lock);
- handled = 1;
- }
- //Acknowledge the Timer interrupt
- if (source & IRQ_TIMER) {
- hwread(vortex->mmio, VORTEX_IRQ_STAT);
- handled = 1;
- }
- if ((source & IRQ_MIDI) && vortex->rmidi) {
- snd_mpu401_uart_interrupt(vortex->irq,
- vortex->rmidi->private_data);
- handled = 1;
- }
-
- if (!handled) {
- printk(KERN_ERR "vortex: unknown irq source %x\n", source);
- }
- return IRQ_RETVAL(handled);
-}
-
-/* Codec */
-
-#define POLL_COUNT 1000
-static void vortex_codec_init(vortex_t * vortex)
-{
- int i;
-
- for (i = 0; i < 32; i++) {
- /* the windows driver writes -i, so we write -i */
- hwwrite(vortex->mmio, (VORTEX_CODEC_CHN + (i << 2)), -i);
- msleep(2);
- }
- if (0) {
- hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x8068);
- msleep(1);
- hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00e8);
- msleep(1);
- } else {
- hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00a8);
- msleep(2);
- hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80a8);
- msleep(2);
- hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80e8);
- msleep(2);
- hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80a8);
- msleep(2);
- hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00a8);
- msleep(2);
- hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00e8);
- }
- for (i = 0; i < 32; i++) {
- hwwrite(vortex->mmio, (VORTEX_CODEC_CHN + (i << 2)), -i);
- msleep(5);
- }
- hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0xe8);
- msleep(1);
- /* Enable codec channels 0 and 1. */
- hwwrite(vortex->mmio, VORTEX_CODEC_EN,
- hwread(vortex->mmio, VORTEX_CODEC_EN) | EN_CODEC);
-}
-
-static void
-vortex_codec_write(struct snd_ac97 * codec, unsigned short addr, unsigned short data)
-{
-
- vortex_t *card = (vortex_t *) codec->private_data;
- unsigned int lifeboat = 0;
-
- /* wait for transactions to clear */
- while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) {
- udelay(100);
- if (lifeboat++ > POLL_COUNT) {
- printk(KERN_ERR "vortex: ac97 codec stuck busy\n");
- return;
- }
- }
- /* write register */
- hwwrite(card->mmio, VORTEX_CODEC_IO,
- ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
- ((data << VORTEX_CODEC_DATSHIFT) & VORTEX_CODEC_DATMASK) |
- VORTEX_CODEC_WRITE |
- (codec->num << VORTEX_CODEC_ID_SHIFT) );
-
- /* Flush Caches. */
- hwread(card->mmio, VORTEX_CODEC_IO);
-}
-
-static unsigned short vortex_codec_read(struct snd_ac97 * codec, unsigned short addr)
-{
-
- vortex_t *card = (vortex_t *) codec->private_data;
- u32 read_addr, data;
- unsigned lifeboat = 0;
-
- /* wait for transactions to clear */
- while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) {
- udelay(100);
- if (lifeboat++ > POLL_COUNT) {
- printk(KERN_ERR "vortex: ac97 codec stuck busy\n");
- return 0xffff;
- }
- }
- /* set up read address */
- read_addr = ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
- (codec->num << VORTEX_CODEC_ID_SHIFT) ;
- hwwrite(card->mmio, VORTEX_CODEC_IO, read_addr);
-
- /* wait for address */
- do {
- udelay(100);
- data = hwread(card->mmio, VORTEX_CODEC_IO);
- if (lifeboat++ > POLL_COUNT) {
- printk(KERN_ERR "vortex: ac97 address never arrived\n");
- return 0xffff;
- }
- } while ((data & VORTEX_CODEC_ADDMASK) !=
- (addr << VORTEX_CODEC_ADDSHIFT));
-
- /* return data. */
- return (u16) (data & VORTEX_CODEC_DATMASK);
-}
-
-/* SPDIF support */
-
-static void vortex_spdif_init(vortex_t * vortex, int spdif_sr, int spdif_mode)
-{
- int i, this_38 = 0, this_04 = 0, this_08 = 0, this_0c = 0;
-
- /* CAsp4Spdif::InitializeSpdifHardware(void) */
- hwwrite(vortex->mmio, VORTEX_SPDIF_FLAGS,
- hwread(vortex->mmio, VORTEX_SPDIF_FLAGS) & 0xfff3fffd);
- //for (i=0x291D4; i<0x29200; i+=4)
- for (i = 0; i < 11; i++)
- hwwrite(vortex->mmio, VORTEX_SPDIF_CFG1 + (i << 2), 0);
- //hwwrite(vortex->mmio, 0x29190, hwread(vortex->mmio, 0x29190) | 0xc0000);
- hwwrite(vortex->mmio, VORTEX_CODEC_EN,
- hwread(vortex->mmio, VORTEX_CODEC_EN) | EN_SPDIF);
-
- /* CAsp4Spdif::ProgramSRCInHardware(enum SPDIF_SR,enum SPDIFMODE) */
- if (this_04 && this_08) {
- int edi;
-
- i = (((0x5DC00000 / spdif_sr) + 1) >> 1);
- if (i > 0x800) {
- if (i < 0x1ffff)
- edi = (i >> 1);
- else
- edi = 0x1ffff;
- } else {
- i = edi = 0x800;
- }
- /* this_04 and this_08 are the CASp4Src's (samplerate converters) */
- vortex_src_setupchannel(vortex, this_04, edi, 0, 1,
- this_0c, 1, 0, edi, 1);
- vortex_src_setupchannel(vortex, this_08, edi, 0, 1,
- this_0c, 1, 0, edi, 1);
- }
-
- i = spdif_sr;
- spdif_sr |= 0x8c;
- switch (i) {
- case 32000:
- this_38 &= 0xFFFFFFFE;
- this_38 &= 0xFFFFFFFD;
- this_38 &= 0xF3FFFFFF;
- this_38 |= 0x03000000; /* set 32khz samplerate */
- this_38 &= 0xFFFFFF3F;
- spdif_sr &= 0xFFFFFFFD;
- spdif_sr |= 1;
- break;
- case 44100:
- this_38 &= 0xFFFFFFFE;
- this_38 &= 0xFFFFFFFD;
- this_38 &= 0xF0FFFFFF;
- this_38 |= 0x03000000;
- this_38 &= 0xFFFFFF3F;
- spdif_sr &= 0xFFFFFFFC;
- break;
- case 48000:
- if (spdif_mode == 1) {
- this_38 &= 0xFFFFFFFE;
- this_38 &= 0xFFFFFFFD;
- this_38 &= 0xF2FFFFFF;
- this_38 |= 0x02000000; /* set 48khz samplerate */
- this_38 &= 0xFFFFFF3F;
- } else {
- /* J. Gordon Wolfe: I think this stuff is for AC3 */
- this_38 |= 0x00000003;
- this_38 &= 0xFFFFFFBF;
- this_38 |= 0x80;
- }
- spdif_sr |= 2;
- spdif_sr &= 0xFFFFFFFE;
- break;
-
- }
- /* looks like the next 2 lines transfer a 16-bit value into 2 8-bit
- registers. seems to be for the standard IEC/SPDIF initialization
- stuff */
- hwwrite(vortex->mmio, VORTEX_SPDIF_CFG0, this_38 & 0xffff);
- hwwrite(vortex->mmio, VORTEX_SPDIF_CFG1, this_38 >> 0x10);
- hwwrite(vortex->mmio, VORTEX_SPDIF_SMPRATE, spdif_sr);
-}
-
-/* Initialization */
-
-static int __devinit vortex_core_init(vortex_t * vortex)
-{
-
- printk(KERN_INFO "Vortex: init.... ");
- /* Hardware Init. */
- hwwrite(vortex->mmio, VORTEX_CTRL, 0xffffffff);
- msleep(5);
- hwwrite(vortex->mmio, VORTEX_CTRL,
- hwread(vortex->mmio, VORTEX_CTRL) & 0xffdfffff);
- msleep(5);
- /* Reset IRQ flags */
- hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, 0xffffffff);
- hwread(vortex->mmio, VORTEX_IRQ_STAT);
-
- vortex_codec_init(vortex);
-
-#ifdef CHIP_AU8830
- hwwrite(vortex->mmio, VORTEX_CTRL,
- hwread(vortex->mmio, VORTEX_CTRL) | 0x1000000);
-#endif
-
- /* Init audio engine. */
- vortex_adbdma_init(vortex);
- hwwrite(vortex->mmio, VORTEX_ENGINE_CTRL, 0x0); //, 0xc83c7e58, 0xc5f93e58
- vortex_adb_init(vortex);
- /* Init processing blocks. */
- vortex_fifo_init(vortex);
- vortex_mixer_init(vortex);
- vortex_srcblock_init(vortex);
-#ifndef CHIP_AU8820
- vortex_eq_init(vortex);
- vortex_spdif_init(vortex, 48000, 1);
- vortex_Vort3D_enable(vortex);
-#endif
-#ifndef CHIP_AU8810
- vortex_wt_init(vortex);
-#endif
- // Moved to au88x0.c
- //vortex_connect_default(vortex, 1);
-
- vortex_settimer(vortex, 0x90);
- // Enable Interrupts.
- // vortex_enable_int() must be first !!
- // hwwrite(vortex->mmio, VORTEX_IRQ_CTRL, 0);
- // vortex_enable_int(vortex);
- //vortex_enable_timer_int(vortex);
- //vortex_disable_timer_int(vortex);
-
- printk(KERN_INFO "done.\n");
- spin_lock_init(&vortex->lock);
-
- return 0;
-}
-
-static int vortex_core_shutdown(vortex_t * vortex)
-{
-
- printk(KERN_INFO "Vortex: shutdown...");
-#ifndef CHIP_AU8820
- vortex_eq_free(vortex);
- vortex_Vort3D_disable(vortex);
-#endif
- //vortex_disable_timer_int(vortex);
- vortex_disable_int(vortex);
- vortex_connect_default(vortex, 0);
- /* Reset all DMA fifos. */
- vortex_fifo_init(vortex);
- /* Erase all audio routes. */
- vortex_adb_init(vortex);
-
- /* Disable MPU401 */
- //hwwrite(vortex->mmio, VORTEX_IRQ_CTRL, hwread(vortex->mmio, VORTEX_IRQ_CTRL) & ~IRQ_MIDI);
- //hwwrite(vortex->mmio, VORTEX_CTRL, hwread(vortex->mmio, VORTEX_CTRL) & ~CTRL_MIDI_EN);
-
- hwwrite(vortex->mmio, VORTEX_IRQ_CTRL, 0);
- hwwrite(vortex->mmio, VORTEX_CTRL, 0);
- msleep(5);
- hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, 0xffff);
-
- printk(KERN_INFO "done.\n");
- return 0;
-}
-
-/* Alsa support. */
-
-static int vortex_alsafmt_aspfmt(int alsafmt)
-{
- int fmt;
-
- switch (alsafmt) {
- case SNDRV_PCM_FORMAT_U8:
- fmt = 0x1;
- break;
- case SNDRV_PCM_FORMAT_MU_LAW:
- fmt = 0x2;
- break;
- case SNDRV_PCM_FORMAT_A_LAW:
- fmt = 0x3;
- break;
- case SNDRV_PCM_FORMAT_SPECIAL:
- fmt = 0x4; /* guess. */
- break;
- case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
- fmt = 0x5; /* guess. */
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- fmt = 0x8;
- break;
- case SNDRV_PCM_FORMAT_S16_BE:
- fmt = 0x9; /* check this... */
- break;
- default:
- fmt = 0x8;
- printk(KERN_ERR "vortex: format unsupported %d\n", alsafmt);
- break;
- }
- return fmt;
-}
-
-/* Some not yet useful translations. */
-#if 0
-typedef enum {
- ASPFMTLINEAR16 = 0, /* 0x8 */
- ASPFMTLINEAR8, /* 0x1 */
- ASPFMTULAW, /* 0x2 */
- ASPFMTALAW, /* 0x3 */
- ASPFMTSPORT, /* ? */
- ASPFMTSPDIF, /* ? */
-} ASPENCODING;
-
-static int
-vortex_translateformat(vortex_t * vortex, char bits, char nch, int encod)
-{
- int a, this_194;
-
- if ((bits != 8) && (bits != 16))
- return -1;
-
- switch (encod) {
- case 0:
- if (bits == 0x10)
- a = 8; // 16 bit
- break;
- case 1:
- if (bits == 8)
- a = 1; // 8 bit
- break;
- case 2:
- a = 2; // U_LAW
- break;
- case 3:
- a = 3; // A_LAW
- break;
- }
- switch (nch) {
- case 1:
- this_194 = 0;
- break;
- case 2:
- this_194 = 1;
- break;
- case 4:
- this_194 = 1;
- break;
- case 6:
- this_194 = 1;
- break;
- }
- return (a);
-}
-
-static void vortex_cdmacore_setformat(vortex_t * vortex, int bits, int nch)
-{
- short int d, this_148;
-
- d = ((bits >> 3) * nch);
- this_148 = 0xbb80 / d;
-}
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_eq.c b/ANDROID_3.4.5/sound/pci/au88x0/au88x0_eq.c
deleted file mode 100644
index 278ed818..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_eq.c
+++ /dev/null
@@ -1,929 +0,0 @@
-/***************************************************************************
- * au88x0_eq.c
- * Aureal Vortex Hardware EQ control/access.
- *
- * Sun Jun 8 18:19:19 2003
- * 2003 Manuel Jander (mjander@users.sourceforge.net)
- *
- * 02 July 2003: First time something works :)
- * November 2003: A3D Bypass code completed but untested.
- *
- * TODO:
- * - Debug (testing)
- * - Test peak visualization support.
- *
- ****************************************************************************/
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/*
- The Aureal Hardware EQ is found on AU8810 and AU8830 chips only.
- it has 4 inputs (2 for general mix, 2 for A3D) and 2 outputs (supposed
- to be routed to the codec).
-*/
-
-#include "au88x0.h"
-#include "au88x0_eq.h"
-#include "au88x0_eqdata.c"
-
-#define VORTEX_EQ_BASE 0x2b000
-#define VORTEX_EQ_DEST (VORTEX_EQ_BASE + 0x410)
-#define VORTEX_EQ_SOURCE (VORTEX_EQ_BASE + 0x430)
-#define VORTEX_EQ_CTRL (VORTEX_EQ_BASE + 0x440)
-
-#define VORTEX_BAND_COEFF_SIZE 0x30
-
-/* CEqHw.s */
-static void vortex_EqHw_SetTimeConsts(vortex_t * vortex, u16 gain, u16 level)
-{
- hwwrite(vortex->mmio, 0x2b3c4, gain);
- hwwrite(vortex->mmio, 0x2b3c8, level);
-}
-
-static inline u16 sign_invert(u16 a)
-{
- /* -(-32768) -> -32768 so we do -(-32768) -> 32767 to make the result positive */
- if (a == (u16)-32768)
- return 32767;
- else
- return -a;
-}
-
-static void vortex_EqHw_SetLeftCoefs(vortex_t * vortex, u16 coefs[])
-{
- eqhw_t *eqhw = &(vortex->eq.this04);
- int i = 0, n /*esp2c */;
-
- for (n = 0; n < eqhw->this04; n++) {
- hwwrite(vortex->mmio, 0x2b000 + n * 0x30, coefs[i + 0]);
- hwwrite(vortex->mmio, 0x2b004 + n * 0x30, coefs[i + 1]);
-
- if (eqhw->this08 == 0) {
- hwwrite(vortex->mmio, 0x2b008 + n * 0x30, coefs[i + 2]);
- hwwrite(vortex->mmio, 0x2b00c + n * 0x30, coefs[i + 3]);
- hwwrite(vortex->mmio, 0x2b010 + n * 0x30, coefs[i + 4]);
- } else {
- hwwrite(vortex->mmio, 0x2b008 + n * 0x30, sign_invert(coefs[2 + i]));
- hwwrite(vortex->mmio, 0x2b00c + n * 0x30, sign_invert(coefs[3 + i]));
- hwwrite(vortex->mmio, 0x2b010 + n * 0x30, sign_invert(coefs[4 + i]));
- }
- i += 5;
- }
-}
-
-static void vortex_EqHw_SetRightCoefs(vortex_t * vortex, u16 coefs[])
-{
- eqhw_t *eqhw = &(vortex->eq.this04);
- int i = 0, n /*esp2c */;
-
- for (n = 0; n < eqhw->this04; n++) {
- hwwrite(vortex->mmio, 0x2b1e0 + n * 0x30, coefs[0 + i]);
- hwwrite(vortex->mmio, 0x2b1e4 + n * 0x30, coefs[1 + i]);
-
- if (eqhw->this08 == 0) {
- hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, coefs[2 + i]);
- hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, coefs[3 + i]);
- hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, coefs[4 + i]);
- } else {
- hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, sign_invert(coefs[2 + i]));
- hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, sign_invert(coefs[3 + i]));
- hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, sign_invert(coefs[4 + i]));
- }
- i += 5;
- }
-
-}
-
-static void vortex_EqHw_SetLeftStates(vortex_t * vortex, u16 a[], u16 b[])
-{
- eqhw_t *eqhw = &(vortex->eq.this04);
- int i = 0, ebx;
-
- hwwrite(vortex->mmio, 0x2b3fc, a[0]);
- hwwrite(vortex->mmio, 0x2b400, a[1]);
-
- for (ebx = 0; ebx < eqhw->this04; ebx++) {
- hwwrite(vortex->mmio, 0x2b014 + (i * 0xc), b[i]);
- hwwrite(vortex->mmio, 0x2b018 + (i * 0xc), b[1 + i]);
- hwwrite(vortex->mmio, 0x2b01c + (i * 0xc), b[2 + i]);
- hwwrite(vortex->mmio, 0x2b020 + (i * 0xc), b[3 + i]);
- i += 4;
- }
-}
-
-static void vortex_EqHw_SetRightStates(vortex_t * vortex, u16 a[], u16 b[])
-{
- eqhw_t *eqhw = &(vortex->eq.this04);
- int i = 0, ebx;
-
- hwwrite(vortex->mmio, 0x2b404, a[0]);
- hwwrite(vortex->mmio, 0x2b408, a[1]);
-
- for (ebx = 0; ebx < eqhw->this04; ebx++) {
- hwwrite(vortex->mmio, 0x2b1f4 + (i * 0xc), b[i]);
- hwwrite(vortex->mmio, 0x2b1f8 + (i * 0xc), b[1 + i]);
- hwwrite(vortex->mmio, 0x2b1fc + (i * 0xc), b[2 + i]);
- hwwrite(vortex->mmio, 0x2b200 + (i * 0xc), b[3 + i]);
- i += 4;
- }
-}
-
-#if 0
-static void vortex_EqHw_GetTimeConsts(vortex_t * vortex, u16 * a, u16 * b)
-{
- *a = hwread(vortex->mmio, 0x2b3c4);
- *b = hwread(vortex->mmio, 0x2b3c8);
-}
-
-static void vortex_EqHw_GetLeftCoefs(vortex_t * vortex, u16 a[])
-{
-
-}
-
-static void vortex_EqHw_GetRightCoefs(vortex_t * vortex, u16 a[])
-{
-
-}
-
-static void vortex_EqHw_GetLeftStates(vortex_t * vortex, u16 * a, u16 b[])
-{
-
-}
-
-static void vortex_EqHw_GetRightStates(vortex_t * vortex, u16 * a, u16 b[])
-{
-
-}
-
-#endif
-/* Mix Gains */
-static void vortex_EqHw_SetBypassGain(vortex_t * vortex, u16 a, u16 b)
-{
- eqhw_t *eqhw = &(vortex->eq.this04);
- if (eqhw->this08 == 0) {
- hwwrite(vortex->mmio, 0x2b3d4, a);
- hwwrite(vortex->mmio, 0x2b3ec, b);
- } else {
- hwwrite(vortex->mmio, 0x2b3d4, sign_invert(a));
- hwwrite(vortex->mmio, 0x2b3ec, sign_invert(b));
- }
-}
-
-static void vortex_EqHw_SetA3DBypassGain(vortex_t * vortex, u16 a, u16 b)
-{
-
- hwwrite(vortex->mmio, 0x2b3e0, a);
- hwwrite(vortex->mmio, 0x2b3f8, b);
-}
-
-#if 0
-static void vortex_EqHw_SetCurrBypassGain(vortex_t * vortex, u16 a, u16 b)
-{
-
- hwwrite(vortex->mmio, 0x2b3d0, a);
- hwwrite(vortex->mmio, 0x2b3e8, b);
-}
-
-static void vortex_EqHw_SetCurrA3DBypassGain(vortex_t * vortex, u16 a, u16 b)
-{
-
- hwwrite(vortex->mmio, 0x2b3dc, a);
- hwwrite(vortex->mmio, 0x2b3f4, b);
-}
-
-#endif
-static void
-vortex_EqHw_SetLeftGainsSingleTarget(vortex_t * vortex, u16 index, u16 b)
-{
- hwwrite(vortex->mmio, 0x2b02c + (index * 0x30), b);
-}
-
-static void
-vortex_EqHw_SetRightGainsSingleTarget(vortex_t * vortex, u16 index, u16 b)
-{
- hwwrite(vortex->mmio, 0x2b20c + (index * 0x30), b);
-}
-
-static void vortex_EqHw_SetLeftGainsTarget(vortex_t * vortex, u16 a[])
-{
- eqhw_t *eqhw = &(vortex->eq.this04);
- int ebx;
-
- for (ebx = 0; ebx < eqhw->this04; ebx++) {
- hwwrite(vortex->mmio, 0x2b02c + ebx * 0x30, a[ebx]);
- }
-}
-
-static void vortex_EqHw_SetRightGainsTarget(vortex_t * vortex, u16 a[])
-{
- eqhw_t *eqhw = &(vortex->eq.this04);
- int ebx;
-
- for (ebx = 0; ebx < eqhw->this04; ebx++) {
- hwwrite(vortex->mmio, 0x2b20c + ebx * 0x30, a[ebx]);
- }
-}
-
-static void vortex_EqHw_SetLeftGainsCurrent(vortex_t * vortex, u16 a[])
-{
- eqhw_t *eqhw = &(vortex->eq.this04);
- int ebx;
-
- for (ebx = 0; ebx < eqhw->this04; ebx++) {
- hwwrite(vortex->mmio, 0x2b028 + ebx * 0x30, a[ebx]);
- }
-}
-
-static void vortex_EqHw_SetRightGainsCurrent(vortex_t * vortex, u16 a[])
-{
- eqhw_t *eqhw = &(vortex->eq.this04);
- int ebx;
-
- for (ebx = 0; ebx < eqhw->this04; ebx++) {
- hwwrite(vortex->mmio, 0x2b208 + ebx * 0x30, a[ebx]);
- }
-}
-
-#if 0
-static void vortex_EqHw_GetLeftGainsTarget(vortex_t * vortex, u16 a[])
-{
- eqhw_t *eqhw = &(vortex->eq.this04);
- int ebx = 0;
-
- if (eqhw->this04 < 0)
- return;
-
- do {
- a[ebx] = hwread(vortex->mmio, 0x2b02c + ebx * 0x30);
- ebx++;
- }
- while (ebx < eqhw->this04);
-}
-
-static void vortex_EqHw_GetRightGainsTarget(vortex_t * vortex, u16 a[])
-{
- eqhw_t *eqhw = &(vortex->eq.this04);
- int ebx = 0;
-
- if (eqhw->this04 < 0)
- return;
-
- do {
- a[ebx] = hwread(vortex->mmio, 0x2b20c + ebx * 0x30);
- ebx++;
- }
- while (ebx < eqhw->this04);
-}
-
-static void vortex_EqHw_GetLeftGainsCurrent(vortex_t * vortex, u16 a[])
-{
- eqhw_t *eqhw = &(vortex->eq.this04);
- int ebx = 0;
-
- if (eqhw->this04 < 0)
- return;
-
- do {
- a[ebx] = hwread(vortex->mmio, 0x2b028 + ebx * 0x30);
- ebx++;
- }
- while (ebx < eqhw->this04);
-}
-
-static void vortex_EqHw_GetRightGainsCurrent(vortex_t * vortex, u16 a[])
-{
- eqhw_t *eqhw = &(vortex->eq.this04);
- int ebx = 0;
-
- if (eqhw->this04 < 0)
- return;
-
- do {
- a[ebx] = hwread(vortex->mmio, 0x2b208 + ebx * 0x30);
- ebx++;
- }
- while (ebx < eqhw->this04);
-}
-
-#endif
-/* EQ band levels settings */
-static void vortex_EqHw_SetLevels(vortex_t * vortex, u16 peaks[])
-{
- eqhw_t *eqhw = &(vortex->eq.this04);
- int i;
-
- /* set left peaks */
- for (i = 0; i < eqhw->this04; i++) {
- hwwrite(vortex->mmio, 0x2b024 + i * VORTEX_BAND_COEFF_SIZE, peaks[i]);
- }
-
- hwwrite(vortex->mmio, 0x2b3cc, peaks[eqhw->this04]);
- hwwrite(vortex->mmio, 0x2b3d8, peaks[eqhw->this04 + 1]);
-
- /* set right peaks */
- for (i = 0; i < eqhw->this04; i++) {
- hwwrite(vortex->mmio, 0x2b204 + i * VORTEX_BAND_COEFF_SIZE,
- peaks[i + (eqhw->this04 + 2)]);
- }
-
- hwwrite(vortex->mmio, 0x2b3e4, peaks[2 + (eqhw->this04 * 2)]);
- hwwrite(vortex->mmio, 0x2b3f0, peaks[3 + (eqhw->this04 * 2)]);
-}
-
-#if 0
-static void vortex_EqHw_GetLevels(vortex_t * vortex, u16 a[])
-{
- eqhw_t *eqhw = &(vortex->eq.this04);
- int ebx;
-
- if (eqhw->this04 < 0)
- return;
-
- ebx = 0;
- do {
- a[ebx] = hwread(vortex->mmio, 0x2b024 + ebx * 0x30);
- ebx++;
- }
- while (ebx < eqhw->this04);
-
- a[eqhw->this04] = hwread(vortex->mmio, 0x2b3cc);
- a[eqhw->this04 + 1] = hwread(vortex->mmio, 0x2b3d8);
-
- ebx = 0;
- do {
- a[ebx + (eqhw->this04 + 2)] =
- hwread(vortex->mmio, 0x2b204 + ebx * 0x30);
- ebx++;
- }
- while (ebx < eqhw->this04);
-
- a[2 + (eqhw->this04 * 2)] = hwread(vortex->mmio, 0x2b3e4);
- a[3 + (eqhw->this04 * 2)] = hwread(vortex->mmio, 0x2b3f0);
-}
-
-#endif
-/* Global Control */
-static void vortex_EqHw_SetControlReg(vortex_t * vortex, u32 reg)
-{
- hwwrite(vortex->mmio, 0x2b440, reg);
-}
-
-static void vortex_EqHw_SetSampleRate(vortex_t * vortex, u32 sr)
-{
- hwwrite(vortex->mmio, 0x2b440, ((sr & 0x1f) << 3) | 0xb800);
-}
-
-#if 0
-static void vortex_EqHw_GetControlReg(vortex_t * vortex, u32 *reg)
-{
- *reg = hwread(vortex->mmio, 0x2b440);
-}
-
-static void vortex_EqHw_GetSampleRate(vortex_t * vortex, u32 *sr)
-{
- *sr = (hwread(vortex->mmio, 0x2b440) >> 3) & 0x1f;
-}
-
-#endif
-static void vortex_EqHw_Enable(vortex_t * vortex)
-{
- hwwrite(vortex->mmio, VORTEX_EQ_CTRL, 0xf001);
-}
-
-static void vortex_EqHw_Disable(vortex_t * vortex)
-{
- hwwrite(vortex->mmio, VORTEX_EQ_CTRL, 0xf000);
-}
-
-/* Reset (zero) buffers */
-static void vortex_EqHw_ZeroIO(vortex_t * vortex)
-{
- int i;
- for (i = 0; i < 0x8; i++)
- hwwrite(vortex->mmio, VORTEX_EQ_DEST + (i << 2), 0x0);
- for (i = 0; i < 0x4; i++)
- hwwrite(vortex->mmio, VORTEX_EQ_SOURCE + (i << 2), 0x0);
-}
-
-static void vortex_EqHw_ZeroA3DIO(vortex_t * vortex)
-{
- int i;
- for (i = 0; i < 0x4; i++)
- hwwrite(vortex->mmio, VORTEX_EQ_DEST + (i << 2), 0x0);
-}
-
-static void vortex_EqHw_ZeroState(vortex_t * vortex)
-{
-
- vortex_EqHw_SetControlReg(vortex, 0);
- vortex_EqHw_ZeroIO(vortex);
- hwwrite(vortex->mmio, 0x2b3c0, 0);
-
- vortex_EqHw_SetTimeConsts(vortex, 0, 0);
-
- vortex_EqHw_SetLeftCoefs(vortex, asEqCoefsZeros);
- vortex_EqHw_SetRightCoefs(vortex, asEqCoefsZeros);
-
- vortex_EqHw_SetLeftGainsCurrent(vortex, eq_gains_zero);
- vortex_EqHw_SetRightGainsCurrent(vortex, eq_gains_zero);
- vortex_EqHw_SetLeftGainsTarget(vortex, eq_gains_zero);
- vortex_EqHw_SetRightGainsTarget(vortex, eq_gains_zero);
-
- vortex_EqHw_SetBypassGain(vortex, 0, 0);
- //vortex_EqHw_SetCurrBypassGain(vortex, 0, 0);
- vortex_EqHw_SetA3DBypassGain(vortex, 0, 0);
- //vortex_EqHw_SetCurrA3DBypassGain(vortex, 0, 0);
- vortex_EqHw_SetLeftStates(vortex, eq_states_zero, asEqOutStateZeros);
- vortex_EqHw_SetRightStates(vortex, eq_states_zero, asEqOutStateZeros);
- vortex_EqHw_SetLevels(vortex, (u16 *) eq_levels);
-}
-
-/* Program coeficients as pass through */
-static void vortex_EqHw_ProgramPipe(vortex_t * vortex)
-{
- vortex_EqHw_SetTimeConsts(vortex, 0, 0);
-
- vortex_EqHw_SetLeftCoefs(vortex, asEqCoefsPipes);
- vortex_EqHw_SetRightCoefs(vortex, asEqCoefsPipes);
-
- vortex_EqHw_SetLeftGainsCurrent(vortex, eq_gains_current);
- vortex_EqHw_SetRightGainsCurrent(vortex, eq_gains_current);
- vortex_EqHw_SetLeftGainsTarget(vortex, eq_gains_current);
- vortex_EqHw_SetRightGainsTarget(vortex, eq_gains_current);
-}
-
-/* Program EQ block as 10 band Equalizer */
-static void
-vortex_EqHw_Program10Band(vortex_t * vortex, auxxEqCoeffSet_t * coefset)
-{
-
- vortex_EqHw_SetTimeConsts(vortex, 0xc, 0x7fe0);
-
- vortex_EqHw_SetLeftCoefs(vortex, coefset->LeftCoefs);
- vortex_EqHw_SetRightCoefs(vortex, coefset->RightCoefs);
-
- vortex_EqHw_SetLeftGainsCurrent(vortex, coefset->LeftGains);
-
- vortex_EqHw_SetRightGainsTarget(vortex, coefset->RightGains);
- vortex_EqHw_SetLeftGainsTarget(vortex, coefset->LeftGains);
-
- vortex_EqHw_SetRightGainsCurrent(vortex, coefset->RightGains);
-}
-
-/* Read all EQ peaks. (think VU meter) */
-static void vortex_EqHw_GetTenBandLevels(vortex_t * vortex, u16 peaks[])
-{
- eqhw_t *eqhw = &(vortex->eq.this04);
- int i;
-
- if (eqhw->this04 <= 0)
- return;
-
- for (i = 0; i < eqhw->this04; i++)
- peaks[i] = hwread(vortex->mmio, 0x2B024 + i * 0x30);
- for (i = 0; i < eqhw->this04; i++)
- peaks[i + eqhw->this04] =
- hwread(vortex->mmio, 0x2B204 + i * 0x30);
-}
-
-/* CEqlzr.s */
-
-static int vortex_Eqlzr_GetLeftGain(vortex_t * vortex, u16 index, u16 * gain)
-{
- eqlzr_t *eq = &(vortex->eq);
-
- if (eq->this28) {
- *gain = eq->this130[index];
- return 0;
- }
- return 1;
-}
-
-static void vortex_Eqlzr_SetLeftGain(vortex_t * vortex, u16 index, u16 gain)
-{
- eqlzr_t *eq = &(vortex->eq);
-
- if (eq->this28 == 0)
- return;
-
- eq->this130[index] = gain;
- if (eq->this54)
- return;
-
- vortex_EqHw_SetLeftGainsSingleTarget(vortex, index, gain);
-}
-
-static int vortex_Eqlzr_GetRightGain(vortex_t * vortex, u16 index, u16 * gain)
-{
- eqlzr_t *eq = &(vortex->eq);
-
- if (eq->this28) {
- *gain = eq->this130[index + eq->this10];
- return 0;
- }
- return 1;
-}
-
-static void vortex_Eqlzr_SetRightGain(vortex_t * vortex, u16 index, u16 gain)
-{
- eqlzr_t *eq = &(vortex->eq);
-
- if (eq->this28 == 0)
- return;
-
- eq->this130[index + eq->this10] = gain;
- if (eq->this54)
- return;
-
- vortex_EqHw_SetRightGainsSingleTarget(vortex, index, gain);
-}
-
-#if 0
-static int
-vortex_Eqlzr_GetAllBands(vortex_t * vortex, u16 * gains, s32 *cnt)
-{
- eqlzr_t *eq = &(vortex->eq);
- int si = 0;
-
- if (eq->this10 == 0)
- return 1;
-
- {
- if (vortex_Eqlzr_GetLeftGain(vortex, si, &gains[si]))
- return 1;
- if (vortex_Eqlzr_GetRightGain
- (vortex, si, &gains[si + eq->this10]))
- return 1;
- si++;
- }
- while (eq->this10 > si) ;
- *cnt = si * 2;
- return 0;
-}
-#endif
-static int vortex_Eqlzr_SetAllBandsFromActiveCoeffSet(vortex_t * vortex)
-{
- eqlzr_t *eq = &(vortex->eq);
-
- vortex_EqHw_SetLeftGainsTarget(vortex, eq->this130);
- vortex_EqHw_SetRightGainsTarget(vortex, &(eq->this130[eq->this10]));
-
- return 0;
-}
-
-static int
-vortex_Eqlzr_SetAllBands(vortex_t * vortex, u16 gains[], s32 count)
-{
- eqlzr_t *eq = &(vortex->eq);
- int i;
-
- if (((eq->this10) * 2 != count) || (eq->this28 == 0))
- return 1;
-
- for (i = 0; i < count; i++) {
- eq->this130[i] = gains[i];
- }
-
- if (eq->this54)
- return 0;
- return vortex_Eqlzr_SetAllBandsFromActiveCoeffSet(vortex);
-}
-
-static void
-vortex_Eqlzr_SetA3dBypassGain(vortex_t * vortex, u32 a, u32 b)
-{
- eqlzr_t *eq = &(vortex->eq);
- u32 eax, ebx;
-
- eq->this58 = a;
- eq->this5c = b;
- if (eq->this54)
- eax = eq->this0e;
- else
- eax = eq->this0a;
- ebx = (eax * eq->this58) >> 0x10;
- eax = (eax * eq->this5c) >> 0x10;
- vortex_EqHw_SetA3DBypassGain(vortex, ebx, eax);
-}
-
-static void vortex_Eqlzr_ProgramA3dBypassGain(vortex_t * vortex)
-{
- eqlzr_t *eq = &(vortex->eq);
- u32 eax, ebx;
-
- if (eq->this54)
- eax = eq->this0e;
- else
- eax = eq->this0a;
- ebx = (eax * eq->this58) >> 0x10;
- eax = (eax * eq->this5c) >> 0x10;
- vortex_EqHw_SetA3DBypassGain(vortex, ebx, eax);
-}
-
-static void vortex_Eqlzr_ShutDownA3d(vortex_t * vortex)
-{
- if (vortex != NULL)
- vortex_EqHw_ZeroA3DIO(vortex);
-}
-
-static void vortex_Eqlzr_SetBypass(vortex_t * vortex, u32 bp)
-{
- eqlzr_t *eq = &(vortex->eq);
-
- if ((eq->this28) && (bp == 0)) {
- /* EQ enabled */
- vortex_Eqlzr_SetAllBandsFromActiveCoeffSet(vortex);
- vortex_EqHw_SetBypassGain(vortex, eq->this08, eq->this08);
- } else {
- /* EQ disabled. */
- vortex_EqHw_SetLeftGainsTarget(vortex, eq->this14_array);
- vortex_EqHw_SetRightGainsTarget(vortex, eq->this14_array);
- vortex_EqHw_SetBypassGain(vortex, eq->this0c, eq->this0c);
- }
- vortex_Eqlzr_ProgramA3dBypassGain(vortex);
-}
-
-static void vortex_Eqlzr_ReadAndSetActiveCoefSet(vortex_t * vortex)
-{
- eqlzr_t *eq = &(vortex->eq);
-
- /* Set EQ BiQuad filter coeficients */
- memcpy(&(eq->coefset), &asEqCoefsNormal, sizeof(auxxEqCoeffSet_t));
- /* Set EQ Band gain levels and dump into hardware registers. */
- vortex_Eqlzr_SetAllBands(vortex, eq_gains_normal, eq->this10 * 2);
-}
-
-static int vortex_Eqlzr_GetAllPeaks(vortex_t * vortex, u16 * peaks, int *count)
-{
- eqlzr_t *eq = &(vortex->eq);
-
- if (eq->this10 == 0)
- return 1;
- *count = eq->this10 * 2;
- vortex_EqHw_GetTenBandLevels(vortex, peaks);
- return 0;
-}
-
-#if 0
-static auxxEqCoeffSet_t *vortex_Eqlzr_GetActiveCoefSet(vortex_t * vortex)
-{
- eqlzr_t *eq = &(vortex->eq);
-
- return (&(eq->coefset));
-}
-#endif
-static void vortex_Eqlzr_init(vortex_t * vortex)
-{
- eqlzr_t *eq = &(vortex->eq);
-
- /* Object constructor */
- //eq->this04 = 0;
- eq->this08 = 0; /* Bypass gain with EQ in use. */
- eq->this0a = 0x5999;
- eq->this0c = 0x5999; /* Bypass gain with EQ disabled. */
- eq->this0e = 0x5999;
-
- eq->this10 = 0xa; /* 10 eq frequency bands. */
- eq->this04.this04 = eq->this10;
- eq->this28 = 0x1; /* if 1 => Allow read access to this130 (gains) */
- eq->this54 = 0x0; /* if 1 => Dont Allow access to hardware (gains) */
- eq->this58 = 0xffff;
- eq->this5c = 0xffff;
-
- /* Set gains. */
- memset(eq->this14_array, 0, sizeof(eq->this14_array));
-
- /* Actual init. */
- vortex_EqHw_ZeroState(vortex);
- vortex_EqHw_SetSampleRate(vortex, 0x11);
- vortex_Eqlzr_ReadAndSetActiveCoefSet(vortex);
-
- vortex_EqHw_Program10Band(vortex, &(eq->coefset));
- vortex_Eqlzr_SetBypass(vortex, eq->this54);
- vortex_Eqlzr_SetA3dBypassGain(vortex, 0, 0);
- vortex_EqHw_Enable(vortex);
-}
-
-static void vortex_Eqlzr_shutdown(vortex_t * vortex)
-{
- vortex_Eqlzr_ShutDownA3d(vortex);
- vortex_EqHw_ProgramPipe(vortex);
- vortex_EqHw_Disable(vortex);
-}
-
-/* ALSA interface */
-
-/* Control interface */
-#define snd_vortex_eqtoggle_info snd_ctl_boolean_mono_info
-
-static int
-snd_vortex_eqtoggle_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- vortex_t *vortex = snd_kcontrol_chip(kcontrol);
- eqlzr_t *eq = &(vortex->eq);
- //int i = kcontrol->private_value;
-
- ucontrol->value.integer.value[0] = eq->this54 ? 0 : 1;
-
- return 0;
-}
-
-static int
-snd_vortex_eqtoggle_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- vortex_t *vortex = snd_kcontrol_chip(kcontrol);
- eqlzr_t *eq = &(vortex->eq);
- //int i = kcontrol->private_value;
-
- eq->this54 = ucontrol->value.integer.value[0] ? 0 : 1;
- vortex_Eqlzr_SetBypass(vortex, eq->this54);
-
- return 1; /* Allways changes */
-}
-
-static struct snd_kcontrol_new vortex_eqtoggle_kcontrol __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "EQ Enable",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = 0,
- .info = snd_vortex_eqtoggle_info,
- .get = snd_vortex_eqtoggle_get,
- .put = snd_vortex_eqtoggle_put
-};
-
-static int
-snd_vortex_eq_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0x0000;
- uinfo->value.integer.max = 0x7fff;
- return 0;
-}
-
-static int
-snd_vortex_eq_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- vortex_t *vortex = snd_kcontrol_chip(kcontrol);
- int i = kcontrol->private_value;
- u16 gainL = 0, gainR = 0;
-
- vortex_Eqlzr_GetLeftGain(vortex, i, &gainL);
- vortex_Eqlzr_GetRightGain(vortex, i, &gainR);
- ucontrol->value.integer.value[0] = gainL;
- ucontrol->value.integer.value[1] = gainR;
- return 0;
-}
-
-static int
-snd_vortex_eq_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- vortex_t *vortex = snd_kcontrol_chip(kcontrol);
- int changed = 0, i = kcontrol->private_value;
- u16 gainL = 0, gainR = 0;
-
- vortex_Eqlzr_GetLeftGain(vortex, i, &gainL);
- vortex_Eqlzr_GetRightGain(vortex, i, &gainR);
-
- if (gainL != ucontrol->value.integer.value[0]) {
- vortex_Eqlzr_SetLeftGain(vortex, i,
- ucontrol->value.integer.value[0]);
- changed = 1;
- }
- if (gainR != ucontrol->value.integer.value[1]) {
- vortex_Eqlzr_SetRightGain(vortex, i,
- ucontrol->value.integer.value[1]);
- changed = 1;
- }
- return changed;
-}
-
-static struct snd_kcontrol_new vortex_eq_kcontrol __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = " .",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = 0,
- .info = snd_vortex_eq_info,
- .get = snd_vortex_eq_get,
- .put = snd_vortex_eq_put
-};
-
-static int
-snd_vortex_peaks_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 20;
- uinfo->value.integer.min = 0x0000;
- uinfo->value.integer.max = 0x7fff;
- return 0;
-}
-
-static int
-snd_vortex_peaks_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- vortex_t *vortex = snd_kcontrol_chip(kcontrol);
- int i, count = 0;
- u16 peaks[20];
-
- vortex_Eqlzr_GetAllPeaks(vortex, peaks, &count);
- if (count != 20) {
- printk(KERN_ERR "vortex: peak count error 20 != %d \n", count);
- return -1;
- }
- for (i = 0; i < 20; i++)
- ucontrol->value.integer.value[i] = peaks[i];
-
- return 0;
-}
-
-static struct snd_kcontrol_new vortex_levels_kcontrol __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "EQ Peaks",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_vortex_peaks_info,
- .get = snd_vortex_peaks_get,
-};
-
-/* EQ band gain labels. */
-static char *EqBandLabels[10] __devinitdata = {
- "EQ0 31Hz\0",
- "EQ1 63Hz\0",
- "EQ2 125Hz\0",
- "EQ3 250Hz\0",
- "EQ4 500Hz\0",
- "EQ5 1KHz\0",
- "EQ6 2KHz\0",
- "EQ7 4KHz\0",
- "EQ8 8KHz\0",
- "EQ9 16KHz\0",
-};
-
-/* ALSA driver entry points. Init and exit. */
-static int __devinit vortex_eq_init(vortex_t * vortex)
-{
- struct snd_kcontrol *kcontrol;
- int err, i;
-
- vortex_Eqlzr_init(vortex);
-
- if ((kcontrol =
- snd_ctl_new1(&vortex_eqtoggle_kcontrol, vortex)) == NULL)
- return -ENOMEM;
- kcontrol->private_value = 0;
- if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
- return err;
-
- /* EQ gain controls */
- for (i = 0; i < 10; i++) {
- if ((kcontrol =
- snd_ctl_new1(&vortex_eq_kcontrol, vortex)) == NULL)
- return -ENOMEM;
- snprintf(kcontrol->id.name, sizeof(kcontrol->id.name),
- "%s Playback Volume", EqBandLabels[i]);
- kcontrol->private_value = i;
- if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
- return err;
- //vortex->eqctrl[i] = kcontrol;
- }
- /* EQ band levels */
- if ((kcontrol = snd_ctl_new1(&vortex_levels_kcontrol, vortex)) == NULL)
- return -ENOMEM;
- if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
- return err;
-
- return 0;
-}
-
-static int vortex_eq_free(vortex_t * vortex)
-{
- /*
- //FIXME: segfault because vortex->eqctrl[i] == 4
- int i;
- for (i=0; i<10; i++) {
- if (vortex->eqctrl[i])
- snd_ctl_remove(vortex->card, vortex->eqctrl[i]);
- }
- */
- vortex_Eqlzr_shutdown(vortex);
- return 0;
-}
-
-/* End */
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_eq.h b/ANDROID_3.4.5/sound/pci/au88x0/au88x0_eq.h
deleted file mode 100644
index 474cd004..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_eq.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef AU88X0_EQ_H
-#define AU88X0_EQ_H
-
-/***************************************************************************
- * au88x0_eq.h
- *
- * Definitions and constant data for the Aureal Hardware EQ.
- *
- * Sun Jun 8 18:23:38 2003
- * Author: Manuel Jander (mjander@users.sourceforge.net)
- ****************************************************************************/
-
-typedef struct {
- u16 LeftCoefs[50]; //0x4
- u16 RightCoefs[50]; // 0x68
- u16 LeftGains[10]; //0xd0
- u16 RightGains[10]; //0xe4
-} auxxEqCoeffSet_t;
-
-typedef struct {
- s32 this04; /* How many filters for each side (default = 10) */
- s32 this08; /* inited to cero. Stereo flag? */
-} eqhw_t;
-
-typedef struct {
- eqhw_t this04; /* CHwEq */
- u16 this08; /* Bad codec flag ? SetBypassGain: bypass gain */
- u16 this0a;
- u16 this0c; /* SetBypassGain: bypass gain when this28 is not set. */
- u16 this0e;
-
- s32 this10; /* How many gains are used for each side (right or left). */
- u16 this14_array[10]; /* SetLeftGainsTarget: Left (and right?) EQ gains */
- s32 this28; /* flag related to EQ enabled or not. Gang flag ? */
- s32 this54; /* SetBypass */
- s32 this58;
- s32 this5c;
- /*0x60 */ auxxEqCoeffSet_t coefset;
- /* 50 u16 word each channel. */
- u16 this130[20]; /* Left and Right gains */
-} eqlzr_t;
-
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_eqdata.c b/ANDROID_3.4.5/sound/pci/au88x0/au88x0_eqdata.c
deleted file mode 100644
index ce8dca8c..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_eqdata.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Data structs */
-
-static u16 asEqCoefsZeros[50] = {
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-};
-
-static u16 asEqCoefsPipes[64] = {
- 0x0000, 0x0000,
- 0x0000, 0x0666, 0x0000, 0x0000, 0x0666,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0666, 0x0000, 0x0000, 0x0666,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0666, 0x0000, 0x0000, 0x0666,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0666, 0x0000, 0x0000, 0x0666,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0666, 0x0000, 0x0000, 0x066a,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000
-};
-
-/* More coef sets can be found in the win2k "inf" file. */
-static auxxEqCoeffSet_t asEqCoefsNormal = {
- .LeftCoefs = {
- 0x7e60, 0xc19e, 0x0001, 0x0002, 0x0001,
- 0x7fa0, 0xc05f, 0x004f, 0x0000, 0xffb1,
- 0x7f3f, 0xc0bc, 0x00c2, 0x0000, 0xff3e,
- 0x7e78, 0xc177, 0x011f, 0x0000, 0xfee1,
- 0x7cd6, 0xc2e5, 0x025c, 0x0000, 0xfda4,
- 0x7949, 0xc5aa, 0x0467, 0x0000, 0xfb99,
- 0x7120, 0xcadf, 0x0864, 0x0000, 0xf79c,
- 0x5d33, 0xd430, 0x0f7e, 0x0000, 0xf082,
- 0x2beb, 0xe3ca, 0x1bd3, 0x0000, 0xe42d,
- 0xd740, 0xf01d, 0x2ac5, 0x0000, 0xd53b},
-
- .RightCoefs = {
- 0x7e60, 0xc19e, 0x0001, 0x0002, 0x0001,
- 0x7fa0, 0xc05f, 0x004f, 0x0000, 0xffb1,
- 0x7f3f, 0xc0bc, 0x00c2, 0x0000, 0xff3e,
- 0x7e78, 0xc177, 0x011f, 0x0000, 0xfee1,
- 0x7cd6, 0xc2e5, 0x025c, 0x0000, 0xfda4,
- 0x7949, 0xc5aa, 0x0467, 0x0000, 0xfb99,
- 0x7120, 0xcadf, 0x0864, 0x0000, 0xf79c,
- 0x5d33, 0xd430, 0x0f7e, 0x0000, 0xf082,
- 0x2beb, 0xe3ca, 0x1bd3, 0x0000, 0xe42d,
- 0xd740, 0xf01d, 0x2ac5, 0x0000, 0xd53b},
-
- .LeftGains = {
- 0x3e96, 0x3e96, 0x3e96, 0x3e96, 0x3e96,
- 0x3e96, 0x3e96, 0x3e96, 0x3e96, 0x3e96},
- .RightGains = {
- 0x3e96, 0x3e96, 0x3e96, 0x3e96, 0x3e96,
- 0x3e96, 0x3e96, 0x3e96, 0x3e96, 0x3e96}
-};
-
-static u16 eq_gains_normal[20] = {
- 0x3e96, 0x3e96, 0x3e96, 0x3e96, 0x3e96,
- 0x3e96, 0x3e96, 0x3e96, 0x3e96, 0x3e96,
- 0x3e96, 0x3e96, 0x3e96, 0x3e96, 0x3e96,
- 0x3e96, 0x3e96, 0x3e96, 0x3e96, 0x3e96
-};
-
-/* _rodatab60 */
-static u16 eq_gains_zero[10] = {
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
-};
-
-/* _rodatab7c: ProgramPipe */
-static u16 eq_gains_current[12] = {
- 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
- 0x7fff,
- 0x7fff, 0x7fff, 0x7fff
-};
-
-/* _rodatab78 */
-static u16 eq_states_zero[2] = { 0x0000, 0x0000 };
-
-static u16 asEqOutStateZeros[48] = {
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000
-};
-
-/*_rodataba0:*/
-static u16 eq_levels[64] = {
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
-};
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_game.c b/ANDROID_3.4.5/sound/pci/au88x0/au88x0_game.c
deleted file mode 100644
index c07c792b..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_game.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Manuel Jander.
- *
- * Based on the work of:
- * Vojtech Pavlik
- * Raymond Ingles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
- * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
- *
- * Based 90% on Vojtech Pavlik pcigame driver.
- * Merged and modified by Manuel Jander, for the OpenVortex
- * driver. (email: mjander@embedded.cl).
- */
-
-#include <linux/time.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <sound/core.h>
-#include "au88x0.h"
-#include <linux/gameport.h>
-#include <linux/export.h>
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-
-#define VORTEX_GAME_DWAIT 20 /* 20 ms */
-
-static unsigned char vortex_game_read(struct gameport *gameport)
-{
- vortex_t *vortex = gameport_get_port_data(gameport);
- return hwread(vortex->mmio, VORTEX_GAME_LEGACY);
-}
-
-static void vortex_game_trigger(struct gameport *gameport)
-{
- vortex_t *vortex = gameport_get_port_data(gameport);
- hwwrite(vortex->mmio, VORTEX_GAME_LEGACY, 0xff);
-}
-
-static int
-vortex_game_cooked_read(struct gameport *gameport, int *axes, int *buttons)
-{
- vortex_t *vortex = gameport_get_port_data(gameport);
- int i;
-
- *buttons = (~hwread(vortex->mmio, VORTEX_GAME_LEGACY) >> 4) & 0xf;
-
- for (i = 0; i < 4; i++) {
- axes[i] =
- hwread(vortex->mmio, VORTEX_GAME_AXIS + (i * AXIS_SIZE));
- if (axes[i] == AXIS_RANGE)
- axes[i] = -1;
- }
- return 0;
-}
-
-static int vortex_game_open(struct gameport *gameport, int mode)
-{
- vortex_t *vortex = gameport_get_port_data(gameport);
-
- switch (mode) {
- case GAMEPORT_MODE_COOKED:
- hwwrite(vortex->mmio, VORTEX_CTRL2,
- hwread(vortex->mmio,
- VORTEX_CTRL2) | CTRL2_GAME_ADCMODE);
- msleep(VORTEX_GAME_DWAIT);
- return 0;
- case GAMEPORT_MODE_RAW:
- hwwrite(vortex->mmio, VORTEX_CTRL2,
- hwread(vortex->mmio,
- VORTEX_CTRL2) & ~CTRL2_GAME_ADCMODE);
- return 0;
- default:
- return -1;
- }
-
- return 0;
-}
-
-static int __devinit vortex_gameport_register(vortex_t * vortex)
-{
- struct gameport *gp;
-
- vortex->gameport = gp = gameport_allocate_port();
- if (!gp) {
- printk(KERN_ERR "vortex: cannot allocate memory for gameport\n");
- return -ENOMEM;
- };
-
- gameport_set_name(gp, "AU88x0 Gameport");
- gameport_set_phys(gp, "pci%s/gameport0", pci_name(vortex->pci_dev));
- gameport_set_dev_parent(gp, &vortex->pci_dev->dev);
-
- gp->read = vortex_game_read;
- gp->trigger = vortex_game_trigger;
- gp->cooked_read = vortex_game_cooked_read;
- gp->open = vortex_game_open;
-
- gameport_set_port_data(gp, vortex);
- gp->fuzz = 64;
-
- gameport_register_port(gp);
-
- return 0;
-}
-
-static void vortex_gameport_unregister(vortex_t * vortex)
-{
- if (vortex->gameport) {
- gameport_unregister_port(vortex->gameport);
- vortex->gameport = NULL;
- }
-}
-
-#else
-static inline int vortex_gameport_register(vortex_t * vortex) { return -ENOSYS; }
-static inline void vortex_gameport_unregister(vortex_t * vortex) { }
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_mixer.c b/ANDROID_3.4.5/sound/pci/au88x0/au88x0_mixer.c
deleted file mode 100644
index 557c782a..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_mixer.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Vortex Mixer support.
- *
- * There is much more than just the AC97 mixer...
- *
- */
-
-#include <linux/time.h>
-#include <linux/init.h>
-#include <sound/core.h>
-#include "au88x0.h"
-
-static int __devinit snd_vortex_mixer(vortex_t * vortex)
-{
- struct snd_ac97_bus *pbus;
- struct snd_ac97_template ac97;
- int err;
- static struct snd_ac97_bus_ops ops = {
- .write = vortex_codec_write,
- .read = vortex_codec_read,
- };
-
- if ((err = snd_ac97_bus(vortex->card, 0, &ops, NULL, &pbus)) < 0)
- return err;
- memset(&ac97, 0, sizeof(ac97));
- // Initialize AC97 codec stuff.
- ac97.private_data = vortex;
- ac97.scaps = AC97_SCAP_NO_SPDIF;
- err = snd_ac97_mixer(pbus, &ac97, &vortex->codec);
- vortex->isquad = ((vortex->codec == NULL) ? 0 : (vortex->codec->ext_id&0x80));
- return err;
-}
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_mpu401.c b/ANDROID_3.4.5/sound/pci/au88x0/au88x0_mpu401.c
deleted file mode 100644
index e6c6a0fe..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_mpu401.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Routines for control of MPU-401 in UART mode
- *
- * Modified for the Aureal Vortex based Soundcards
- * by Manuel Jander (mjande@embedded.cl).
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <linux/init.h>
-#include <sound/core.h>
-#include <sound/mpu401.h>
-#include "au88x0.h"
-
-/* Check for mpu401 mmio support. */
-/* MPU401 legacy support is only provided as a emergency fallback *
- * for older versions of ALSA. Its usage is strongly discouraged. */
-#ifndef MPU401_HW_AUREAL
-#define VORTEX_MPU401_LEGACY
-#endif
-
-/* Vortex MPU401 defines. */
-#define MIDI_CLOCK_DIV 0x61
-/* Standart MPU401 defines. */
-#define MPU401_RESET 0xff
-#define MPU401_ENTER_UART 0x3f
-#define MPU401_ACK 0xfe
-
-static int __devinit snd_vortex_midi(vortex_t * vortex)
-{
- struct snd_rawmidi *rmidi;
- int temp, mode;
- struct snd_mpu401 *mpu;
- unsigned long port;
-
-#ifdef VORTEX_MPU401_LEGACY
- /* EnableHardCodedMPU401Port() */
- /* Enable Legacy MIDI Interface port. */
- port = (0x03 << 5); /* FIXME: static address. 0x330 */
- temp =
- (hwread(vortex->mmio, VORTEX_CTRL) & ~CTRL_MIDI_PORT) |
- CTRL_MIDI_EN | port;
- hwwrite(vortex->mmio, VORTEX_CTRL, temp);
-#else
- /* Disable Legacy MIDI Interface port. */
- temp =
- (hwread(vortex->mmio, VORTEX_CTRL) & ~CTRL_MIDI_PORT) &
- ~CTRL_MIDI_EN;
- hwwrite(vortex->mmio, VORTEX_CTRL, temp);
-#endif
- /* Mpu401UartInit() */
- mode = 1;
- temp = hwread(vortex->mmio, VORTEX_CTRL2) & 0xffff00cf;
- temp |= (MIDI_CLOCK_DIV << 8) | ((mode >> 24) & 0xff) << 4;
- hwwrite(vortex->mmio, VORTEX_CTRL2, temp);
- hwwrite(vortex->mmio, VORTEX_MIDI_CMD, MPU401_RESET);
-
- /* Check if anything is OK. */
- temp = hwread(vortex->mmio, VORTEX_MIDI_DATA);
- if (temp != MPU401_ACK /*0xfe */ ) {
- printk(KERN_ERR "midi port doesn't acknowledge!\n");
- return -ENODEV;
- }
- /* Enable MPU401 interrupts. */
- hwwrite(vortex->mmio, VORTEX_IRQ_CTRL,
- hwread(vortex->mmio, VORTEX_IRQ_CTRL) | IRQ_MIDI);
-
- /* Create MPU401 instance. */
-#ifdef VORTEX_MPU401_LEGACY
- if ((temp =
- snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_MPU401, 0x330,
- MPU401_INFO_IRQ_HOOK, -1, &rmidi)) != 0) {
- hwwrite(vortex->mmio, VORTEX_CTRL,
- (hwread(vortex->mmio, VORTEX_CTRL) &
- ~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN);
- return temp;
- }
-#else
- port = (unsigned long)(vortex->mmio + VORTEX_MIDI_DATA);
- if ((temp =
- snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_AUREAL, port,
- MPU401_INFO_INTEGRATED | MPU401_INFO_MMIO |
- MPU401_INFO_IRQ_HOOK, -1, &rmidi)) != 0) {
- hwwrite(vortex->mmio, VORTEX_CTRL,
- (hwread(vortex->mmio, VORTEX_CTRL) &
- ~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN);
- return temp;
- }
- mpu = rmidi->private_data;
- mpu->cport = (unsigned long)(vortex->mmio + VORTEX_MIDI_CMD);
-#endif
- /* Overwrite MIDI name */
- snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI %d", CARD_NAME_SHORT , vortex->card->number);
-
- vortex->rmidi = rmidi;
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_pcm.c b/ANDROID_3.4.5/sound/pci/au88x0/au88x0_pcm.c
deleted file mode 100644
index e59f1207..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_pcm.c
+++ /dev/null
@@ -1,678 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/*
- * Vortex PCM ALSA driver.
- *
- * Supports ADB and WT DMA. Unfortunately, WT channels do not run yet.
- * It remains stuck,and DMA transfers do not happen.
- */
-#include <sound/asoundef.h>
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include "au88x0.h"
-
-#define VORTEX_PCM_TYPE(x) (x->name[40])
-
-/* hardware definition */
-static struct snd_pcm_hardware snd_vortex_playback_hw_adb = {
- .info =
- (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats =
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 5000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 0x10000,
- .period_bytes_min = 0x20,
- .period_bytes_max = 0x1000,
- .periods_min = 2,
- .periods_max = 1024,
-};
-
-#ifndef CHIP_AU8820
-static struct snd_pcm_hardware snd_vortex_playback_hw_a3d = {
- .info =
- (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats =
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 5000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 1,
- .buffer_bytes_max = 0x10000,
- .period_bytes_min = 0x100,
- .period_bytes_max = 0x1000,
- .periods_min = 2,
- .periods_max = 64,
-};
-#endif
-static struct snd_pcm_hardware snd_vortex_playback_hw_spdif = {
- .info =
- (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats =
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE | SNDRV_PCM_FMTBIT_MU_LAW |
- SNDRV_PCM_FMTBIT_A_LAW,
- .rates =
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
- .rate_min = 32000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 0x10000,
- .period_bytes_min = 0x100,
- .period_bytes_max = 0x1000,
- .periods_min = 2,
- .periods_max = 64,
-};
-
-#ifndef CHIP_AU8810
-static struct snd_pcm_hardware snd_vortex_playback_hw_wt = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_CONTINUOUS, // SNDRV_PCM_RATE_48000,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 0x10000,
- .period_bytes_min = 0x0400,
- .period_bytes_max = 0x1000,
- .periods_min = 2,
- .periods_max = 64,
-};
-#endif
-#ifdef CHIP_AU8830
-static unsigned int au8830_channels[3] = {
- 1, 2, 4,
-};
-
-static struct snd_pcm_hw_constraint_list hw_constraints_au8830_channels = {
- .count = ARRAY_SIZE(au8830_channels),
- .list = au8830_channels,
- .mask = 0,
-};
-#endif
-
-static void vortex_notify_pcm_vol_change(struct snd_card *card,
- struct snd_kcontrol *kctl, int activate)
-{
- if (activate)
- kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- else
- kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO, &(kctl->id));
-}
-
-/* open callback */
-static int snd_vortex_pcm_open(struct snd_pcm_substream *substream)
-{
- vortex_t *vortex = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- /* Force equal size periods */
- if ((err =
- snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
- return err;
- /* Avoid PAGE_SIZE boundary to fall inside of a period. */
- if ((err =
- snd_pcm_hw_constraint_pow2(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0)
- return err;
-
- snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 64);
-
- if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
-#ifndef CHIP_AU8820
- if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_A3D) {
- runtime->hw = snd_vortex_playback_hw_a3d;
- }
-#endif
- if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_SPDIF) {
- runtime->hw = snd_vortex_playback_hw_spdif;
- switch (vortex->spdif_sr) {
- case 32000:
- runtime->hw.rates = SNDRV_PCM_RATE_32000;
- break;
- case 44100:
- runtime->hw.rates = SNDRV_PCM_RATE_44100;
- break;
- case 48000:
- runtime->hw.rates = SNDRV_PCM_RATE_48000;
- break;
- }
- }
- if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB
- || VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_I2S)
- runtime->hw = snd_vortex_playback_hw_adb;
-#ifdef CHIP_AU8830
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
- VORTEX_IS_QUAD(vortex) &&
- VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
- runtime->hw.channels_max = 4;
- snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- &hw_constraints_au8830_channels);
- }
-#endif
- substream->runtime->private_data = NULL;
- }
-#ifndef CHIP_AU8810
- else {
- runtime->hw = snd_vortex_playback_hw_wt;
- substream->runtime->private_data = NULL;
- }
-#endif
- return 0;
-}
-
-/* close callback */
-static int snd_vortex_pcm_close(struct snd_pcm_substream *substream)
-{
- //vortex_t *chip = snd_pcm_substream_chip(substream);
- stream_t *stream = (stream_t *) substream->runtime->private_data;
-
- // the hardware-specific codes will be here
- if (stream != NULL) {
- stream->substream = NULL;
- stream->nr_ch = 0;
- }
- substream->runtime->private_data = NULL;
- return 0;
-}
-
-/* hw_params callback */
-static int
-snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- vortex_t *chip = snd_pcm_substream_chip(substream);
- stream_t *stream = (stream_t *) (substream->runtime->private_data);
- int err;
-
- // Alloc buffer memory.
- err =
- snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
- if (err < 0) {
- printk(KERN_ERR "Vortex: pcm page alloc failed!\n");
- return err;
- }
- /*
- printk(KERN_INFO "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params),
- params_period_bytes(hw_params), params_channels(hw_params));
- */
- spin_lock_irq(&chip->lock);
- // Make audio routes and config buffer DMA.
- if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
- int dma, type = VORTEX_PCM_TYPE(substream->pcm);
- /* Dealloc any routes. */
- if (stream != NULL)
- vortex_adb_allocroute(chip, stream->dma,
- stream->nr_ch, stream->dir,
- stream->type,
- substream->number);
- /* Alloc routes. */
- dma =
- vortex_adb_allocroute(chip, -1,
- params_channels(hw_params),
- substream->stream, type,
- substream->number);
- if (dma < 0) {
- spin_unlock_irq(&chip->lock);
- return dma;
- }
- stream = substream->runtime->private_data = &chip->dma_adb[dma];
- stream->substream = substream;
- /* Setup Buffers. */
- vortex_adbdma_setbuffers(chip, dma,
- params_period_bytes(hw_params),
- params_periods(hw_params));
- if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
- chip->pcm_vol[substream->number].active = 1;
- vortex_notify_pcm_vol_change(chip->card,
- chip->pcm_vol[substream->number].kctl, 1);
- }
- }
-#ifndef CHIP_AU8810
- else {
- /* if (stream != NULL)
- vortex_wt_allocroute(chip, substream->number, 0); */
- vortex_wt_allocroute(chip, substream->number,
- params_channels(hw_params));
- stream = substream->runtime->private_data =
- &chip->dma_wt[substream->number];
- stream->dma = substream->number;
- stream->substream = substream;
- vortex_wtdma_setbuffers(chip, substream->number,
- params_period_bytes(hw_params),
- params_periods(hw_params));
- }
-#endif
- spin_unlock_irq(&chip->lock);
- return 0;
-}
-
-/* hw_free callback */
-static int snd_vortex_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- vortex_t *chip = snd_pcm_substream_chip(substream);
- stream_t *stream = (stream_t *) (substream->runtime->private_data);
-
- spin_lock_irq(&chip->lock);
- // Delete audio routes.
- if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
- if (stream != NULL) {
- if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
- chip->pcm_vol[substream->number].active = 0;
- vortex_notify_pcm_vol_change(chip->card,
- chip->pcm_vol[substream->number].kctl,
- 0);
- }
- vortex_adb_allocroute(chip, stream->dma,
- stream->nr_ch, stream->dir,
- stream->type,
- substream->number);
- }
- }
-#ifndef CHIP_AU8810
- else {
- if (stream != NULL)
- vortex_wt_allocroute(chip, stream->dma, 0);
- }
-#endif
- substream->runtime->private_data = NULL;
- spin_unlock_irq(&chip->lock);
-
- return snd_pcm_lib_free_pages(substream);
-}
-
-/* prepare callback */
-static int snd_vortex_pcm_prepare(struct snd_pcm_substream *substream)
-{
- vortex_t *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- stream_t *stream = (stream_t *) substream->runtime->private_data;
- int dma = stream->dma, fmt, dir;
-
- // set up the hardware with the current configuration.
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dir = 1;
- else
- dir = 0;
- fmt = vortex_alsafmt_aspfmt(runtime->format);
- spin_lock_irq(&chip->lock);
- if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
- vortex_adbdma_setmode(chip, dma, 1, dir, fmt,
- runtime->channels == 1 ? 0 : 1, 0);
- vortex_adbdma_setstartbuffer(chip, dma, 0);
- if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_SPDIF)
- vortex_adb_setsrc(chip, dma, runtime->rate, dir);
- }
-#ifndef CHIP_AU8810
- else {
- vortex_wtdma_setmode(chip, dma, 1, fmt, 0, 0);
- // FIXME: Set rate (i guess using vortex_wt_writereg() somehow).
- vortex_wtdma_setstartbuffer(chip, dma, 0);
- }
-#endif
- spin_unlock_irq(&chip->lock);
- return 0;
-}
-
-/* trigger callback */
-static int snd_vortex_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- vortex_t *chip = snd_pcm_substream_chip(substream);
- stream_t *stream = (stream_t *) substream->runtime->private_data;
- int dma = stream->dma;
-
- spin_lock(&chip->lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- // do something to start the PCM engine
- //printk(KERN_INFO "vortex: start %d\n", dma);
- stream->fifo_enabled = 1;
- if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
- vortex_adbdma_resetup(chip, dma);
- vortex_adbdma_startfifo(chip, dma);
- }
-#ifndef CHIP_AU8810
- else {
- printk(KERN_INFO "vortex: wt start %d\n", dma);
- vortex_wtdma_startfifo(chip, dma);
- }
-#endif
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- // do something to stop the PCM engine
- //printk(KERN_INFO "vortex: stop %d\n", dma);
- stream->fifo_enabled = 0;
- if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
- vortex_adbdma_stopfifo(chip, dma);
-#ifndef CHIP_AU8810
- else {
- printk(KERN_INFO "vortex: wt stop %d\n", dma);
- vortex_wtdma_stopfifo(chip, dma);
- }
-#endif
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- //printk(KERN_INFO "vortex: pause %d\n", dma);
- if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
- vortex_adbdma_pausefifo(chip, dma);
-#ifndef CHIP_AU8810
- else
- vortex_wtdma_pausefifo(chip, dma);
-#endif
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- //printk(KERN_INFO "vortex: resume %d\n", dma);
- if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
- vortex_adbdma_resumefifo(chip, dma);
-#ifndef CHIP_AU8810
- else
- vortex_wtdma_resumefifo(chip, dma);
-#endif
- break;
- default:
- spin_unlock(&chip->lock);
- return -EINVAL;
- }
- spin_unlock(&chip->lock);
- return 0;
-}
-
-/* pointer callback */
-static snd_pcm_uframes_t snd_vortex_pcm_pointer(struct snd_pcm_substream *substream)
-{
- vortex_t *chip = snd_pcm_substream_chip(substream);
- stream_t *stream = (stream_t *) substream->runtime->private_data;
- int dma = stream->dma;
- snd_pcm_uframes_t current_ptr = 0;
-
- spin_lock(&chip->lock);
- if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
- current_ptr = vortex_adbdma_getlinearpos(chip, dma);
-#ifndef CHIP_AU8810
- else
- current_ptr = vortex_wtdma_getlinearpos(chip, dma);
-#endif
- //printk(KERN_INFO "vortex: pointer = 0x%x\n", current_ptr);
- spin_unlock(&chip->lock);
- return (bytes_to_frames(substream->runtime, current_ptr));
-}
-
-/* operators */
-static struct snd_pcm_ops snd_vortex_playback_ops = {
- .open = snd_vortex_pcm_open,
- .close = snd_vortex_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_vortex_pcm_hw_params,
- .hw_free = snd_vortex_pcm_hw_free,
- .prepare = snd_vortex_pcm_prepare,
- .trigger = snd_vortex_pcm_trigger,
- .pointer = snd_vortex_pcm_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
-/*
-* definitions of capture are omitted here...
-*/
-
-static char *vortex_pcm_prettyname[VORTEX_PCM_LAST] = {
- CARD_NAME " ADB",
- CARD_NAME " SPDIF",
- CARD_NAME " A3D",
- CARD_NAME " WT",
- CARD_NAME " I2S",
-};
-static char *vortex_pcm_name[VORTEX_PCM_LAST] = {
- "adb",
- "spdif",
- "a3d",
- "wt",
- "i2s",
-};
-
-/* SPDIF kcontrol */
-
-static int snd_vortex_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_vortex_spdif_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.iec958.status[0] = 0xff;
- ucontrol->value.iec958.status[1] = 0xff;
- ucontrol->value.iec958.status[2] = 0xff;
- ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS;
- return 0;
-}
-
-static int snd_vortex_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- vortex_t *vortex = snd_kcontrol_chip(kcontrol);
- ucontrol->value.iec958.status[0] = 0x00;
- ucontrol->value.iec958.status[1] = IEC958_AES1_CON_ORIGINAL|IEC958_AES1_CON_DIGDIGCONV_ID;
- ucontrol->value.iec958.status[2] = 0x00;
- switch (vortex->spdif_sr) {
- case 32000: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_32000; break;
- case 44100: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_44100; break;
- case 48000: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_48000; break;
- }
- return 0;
-}
-
-static int snd_vortex_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- vortex_t *vortex = snd_kcontrol_chip(kcontrol);
- int spdif_sr = 48000;
- switch (ucontrol->value.iec958.status[3] & IEC958_AES3_CON_FS) {
- case IEC958_AES3_CON_FS_32000: spdif_sr = 32000; break;
- case IEC958_AES3_CON_FS_44100: spdif_sr = 44100; break;
- case IEC958_AES3_CON_FS_48000: spdif_sr = 48000; break;
- }
- if (spdif_sr == vortex->spdif_sr)
- return 0;
- vortex->spdif_sr = spdif_sr;
- vortex_spdif_init(vortex, vortex->spdif_sr, 1);
- return 1;
-}
-
-/* spdif controls */
-static struct snd_kcontrol_new snd_vortex_mixer_spdif[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
- .info = snd_vortex_spdif_info,
- .get = snd_vortex_spdif_get,
- .put = snd_vortex_spdif_put,
- },
- {
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
- .info = snd_vortex_spdif_info,
- .get = snd_vortex_spdif_mask_get
- },
-};
-
-/* subdevice PCM Volume control */
-
-static int snd_vortex_pcm_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- vortex_t *vortex = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
- uinfo->value.integer.min = -128;
- uinfo->value.integer.max = 32;
- return 0;
-}
-
-static int snd_vortex_pcm_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int i;
- vortex_t *vortex = snd_kcontrol_chip(kcontrol);
- int subdev = kcontrol->id.subdevice;
- struct pcm_vol *p = &vortex->pcm_vol[subdev];
- int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
- for (i = 0; i < max_chn; i++)
- ucontrol->value.integer.value[i] = p->vol[i];
- return 0;
-}
-
-static int snd_vortex_pcm_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int i;
- int changed = 0;
- int mixin;
- unsigned char vol;
- vortex_t *vortex = snd_kcontrol_chip(kcontrol);
- int subdev = kcontrol->id.subdevice;
- struct pcm_vol *p = &vortex->pcm_vol[subdev];
- int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
- for (i = 0; i < max_chn; i++) {
- if (p->vol[i] != ucontrol->value.integer.value[i]) {
- p->vol[i] = ucontrol->value.integer.value[i];
- if (p->active) {
- switch (vortex->dma_adb[p->dma].nr_ch) {
- case 1:
- mixin = p->mixin[0];
- break;
- case 2:
- default:
- mixin = p->mixin[(i < 2) ? i : (i - 2)];
- break;
- case 4:
- mixin = p->mixin[i];
- break;
- };
- vol = p->vol[i];
- vortex_mix_setinputvolumebyte(vortex,
- vortex->mixplayb[i], mixin, vol);
- }
- changed = 1;
- }
- }
- return changed;
-}
-
-static const DECLARE_TLV_DB_MINMAX(vortex_pcm_vol_db_scale, -9600, 2400);
-
-static struct snd_kcontrol_new snd_vortex_pcm_vol __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "PCM Playback Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ |
- SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .info = snd_vortex_pcm_vol_info,
- .get = snd_vortex_pcm_vol_get,
- .put = snd_vortex_pcm_vol_put,
- .tlv = { .p = vortex_pcm_vol_db_scale },
-};
-
-/* create a pcm device */
-static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
-{
- struct snd_pcm *pcm;
- struct snd_kcontrol *kctl;
- int i;
- int err, nr_capt;
-
- if (!chip || idx < 0 || idx >= VORTEX_PCM_LAST)
- return -ENODEV;
-
- /* idx indicates which kind of PCM device. ADB, SPDIF, I2S and A3D share the
- * same dma engine. WT uses it own separate dma engine which can't capture. */
- if (idx == VORTEX_PCM_ADB)
- nr_capt = nr;
- else
- nr_capt = 0;
- err = snd_pcm_new(chip->card, vortex_pcm_prettyname[idx], idx, nr,
- nr_capt, &pcm);
- if (err < 0)
- return err;
- snprintf(pcm->name, sizeof(pcm->name),
- "%s %s", CARD_NAME_SHORT, vortex_pcm_name[idx]);
- chip->pcm[idx] = pcm;
- // This is an evil hack, but it saves a lot of duplicated code.
- VORTEX_PCM_TYPE(pcm) = idx;
- pcm->private_data = chip;
- /* set operators */
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_vortex_playback_ops);
- if (idx == VORTEX_PCM_ADB)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_vortex_playback_ops);
-
- /* pre-allocation of Scatter-Gather buffers */
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(chip->pci_dev),
- 0x10000, 0x10000);
-
- if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_SPDIF) {
- for (i = 0; i < ARRAY_SIZE(snd_vortex_mixer_spdif); i++) {
- kctl = snd_ctl_new1(&snd_vortex_mixer_spdif[i], chip);
- if (!kctl)
- return -ENOMEM;
- if ((err = snd_ctl_add(chip->card, kctl)) < 0)
- return err;
- }
- }
- if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_ADB) {
- for (i = 0; i < NR_PCM; i++) {
- chip->pcm_vol[i].active = 0;
- chip->pcm_vol[i].dma = -1;
- kctl = snd_ctl_new1(&snd_vortex_pcm_vol, chip);
- if (!kctl)
- return -ENOMEM;
- chip->pcm_vol[i].kctl = kctl;
- kctl->id.device = 0;
- kctl->id.subdevice = i;
- err = snd_ctl_add(chip->card, kctl);
- if (err < 0)
- return err;
- }
- }
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_synth.c b/ANDROID_3.4.5/sound/pci/au88x0/au88x0_synth.c
deleted file mode 100644
index 2805e34b..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_synth.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/*
- * Someday its supposed to make use of the WT DMA engine
- * for a Wavetable synthesizer.
- */
-
-#include "au88x0.h"
-#include "au88x0_wt.h"
-
-static void vortex_fifo_setwtvalid(vortex_t * vortex, int fifo, int en);
-static void vortex_connection_adb_mixin(vortex_t * vortex, int en,
- unsigned char channel,
- unsigned char source,
- unsigned char mixin);
-static void vortex_connection_mixin_mix(vortex_t * vortex, int en,
- unsigned char mixin,
- unsigned char mix, int a);
-static void vortex_fifo_wtinitialize(vortex_t * vortex, int fifo, int j);
-static int vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt,
- u32 val);
-
-/* WT */
-
-/* Put 2 WT channels together for one stereo interlaced channel. */
-static void vortex_wt_setstereo(vortex_t * vortex, u32 wt, u32 stereo)
-{
- int temp;
-
- //temp = hwread(vortex->mmio, 0x80 + ((wt >> 0x5)<< 0xf) + (((wt & 0x1f) >> 1) << 2));
- temp = hwread(vortex->mmio, WT_STEREO(wt));
- temp = (temp & 0xfe) | (stereo & 1);
- //hwwrite(vortex->mmio, 0x80 + ((wt >> 0x5)<< 0xf) + (((wt & 0x1f) >> 1) << 2), temp);
- hwwrite(vortex->mmio, WT_STEREO(wt), temp);
-}
-
-/* Join to mixdown route. */
-static void vortex_wt_setdsout(vortex_t * vortex, u32 wt, int en)
-{
- int temp;
-
- /* There is one DSREG register for each bank (32 voices each). */
- temp = hwread(vortex->mmio, WT_DSREG((wt >= 0x20) ? 1 : 0));
- if (en)
- temp |= (1 << (wt & 0x1f));
- else
- temp &= (1 << ~(wt & 0x1f));
- hwwrite(vortex->mmio, WT_DSREG((wt >= 0x20) ? 1 : 0), temp);
-}
-
-/* Setup WT route. */
-static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch)
-{
- wt_voice_t *voice = &(vortex->wt_voice[wt]);
- int temp;
-
- //FIXME: WT audio routing.
- if (nr_ch) {
- vortex_fifo_wtinitialize(vortex, wt, 1);
- vortex_fifo_setwtvalid(vortex, wt, 1);
- vortex_wt_setstereo(vortex, wt, nr_ch - 1);
- } else
- vortex_fifo_setwtvalid(vortex, wt, 0);
-
- /* Set mixdown mode. */
- vortex_wt_setdsout(vortex, wt, 1);
- /* Set other parameter registers. */
- hwwrite(vortex->mmio, WT_SRAMP(0), 0x880000);
- //hwwrite(vortex->mmio, WT_GMODE(0), 0xffffffff);
-#ifdef CHIP_AU8830
- hwwrite(vortex->mmio, WT_SRAMP(1), 0x880000);
- //hwwrite(vortex->mmio, WT_GMODE(1), 0xffffffff);
-#endif
- hwwrite(vortex->mmio, WT_PARM(wt, 0), 0);
- hwwrite(vortex->mmio, WT_PARM(wt, 1), 0);
- hwwrite(vortex->mmio, WT_PARM(wt, 2), 0);
-
- temp = hwread(vortex->mmio, WT_PARM(wt, 3));
- printk(KERN_DEBUG "vortex: WT PARM3: %x\n", temp);
- //hwwrite(vortex->mmio, WT_PARM(wt, 3), temp);
-
- hwwrite(vortex->mmio, WT_DELAY(wt, 0), 0);
- hwwrite(vortex->mmio, WT_DELAY(wt, 1), 0);
- hwwrite(vortex->mmio, WT_DELAY(wt, 2), 0);
- hwwrite(vortex->mmio, WT_DELAY(wt, 3), 0);
-
- printk(KERN_DEBUG "vortex: WT GMODE: %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
-
- hwwrite(vortex->mmio, WT_PARM(wt, 2), 0xffffffff);
- hwwrite(vortex->mmio, WT_PARM(wt, 3), 0xcff1c810);
-
- voice->parm0 = voice->parm1 = 0xcfb23e2f;
- hwwrite(vortex->mmio, WT_PARM(wt, 0), voice->parm0);
- hwwrite(vortex->mmio, WT_PARM(wt, 1), voice->parm1);
- printk(KERN_DEBUG "vortex: WT GMODE 2 : %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
- return 0;
-}
-
-
-static void vortex_wt_connect(vortex_t * vortex, int en)
-{
- int i, ii, mix;
-
-#define NR_WTROUTES 6
-#ifdef CHIP_AU8830
-#define NR_WTBLOCKS 2
-#else
-#define NR_WTBLOCKS 1
-#endif
-
- for (i = 0; i < NR_WTBLOCKS; i++) {
- for (ii = 0; ii < NR_WTROUTES; ii++) {
- mix =
- vortex_adb_checkinout(vortex,
- vortex->fixed_res, en,
- VORTEX_RESOURCE_MIXIN);
- vortex->mixwt[(i * NR_WTROUTES) + ii] = mix;
-
- vortex_route(vortex, en, 0x11,
- ADB_WTOUT(i, ii + 0x20), ADB_MIXIN(mix));
-
- vortex_connection_mixin_mix(vortex, en, mix,
- vortex->mixplayb[ii % 2], 0);
- if (VORTEX_IS_QUAD(vortex))
- vortex_connection_mixin_mix(vortex, en,
- mix,
- vortex->mixplayb[2 +
- (ii % 2)], 0);
- }
- }
- for (i = 0; i < NR_WT; i++) {
- hwwrite(vortex->mmio, WT_RUN(i), 1);
- }
-}
-
-/* Read WT Register */
-#if 0
-static int vortex_wt_GetReg(vortex_t * vortex, char reg, int wt)
-{
- //int eax, esi;
-
- if (reg == 4) {
- return hwread(vortex->mmio, WT_PARM(wt, 3));
- }
- if (reg == 7) {
- return hwread(vortex->mmio, WT_GMODE(wt));
- }
-
- return 0;
-}
-
-/* WT hardware abstraction layer generic register interface. */
-static int
-vortex_wt_SetReg2(vortex_t * vortex, unsigned char reg, int wt,
- u16 val)
-{
- /*
- int eax, edx;
-
- if (wt >= NR_WT) // 0x40 -> NR_WT
- return 0;
-
- if ((reg - 0x20) > 0) {
- if ((reg - 0x21) != 0)
- return 0;
- eax = ((((b & 0xff) << 0xb) + (edx & 0xff)) << 4) + 0x208; // param 2
- } else {
- eax = ((((b & 0xff) << 0xb) + (edx & 0xff)) << 4) + 0x20a; // param 3
- }
- hwwrite(vortex->mmio, eax, c);
- */
- return 1;
-}
-
-/*public: static void __thiscall CWTHal::SetReg(unsigned char,int,unsigned long) */
-#endif
-static int
-vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt,
- u32 val)
-{
- int ecx;
-
- if ((reg == 5) || ((reg >= 7) && (reg <= 10)) || (reg == 0xc)) {
- if (wt >= (NR_WT / NR_WT_PB)) {
- printk
- ("vortex: WT SetReg: bank out of range. reg=0x%x, wt=%d\n",
- reg, wt);
- return 0;
- }
- } else {
- if (wt >= NR_WT) {
- printk(KERN_ERR "vortex: WT SetReg: voice out of range\n");
- return 0;
- }
- }
- if (reg > 0xc)
- return 0;
-
- switch (reg) {
- /* Voice specific parameters */
- case 0: /* running */
- /*
- printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n",
- WT_RUN(wt), (int)val);
- */
- hwwrite(vortex->mmio, WT_RUN(wt), val);
- return 0xc;
- break;
- case 1: /* param 0 */
- /*
- printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n",
- WT_PARM(wt,0), (int)val);
- */
- hwwrite(vortex->mmio, WT_PARM(wt, 0), val);
- return 0xc;
- break;
- case 2: /* param 1 */
- /*
- printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n",
- WT_PARM(wt,1), (int)val);
- */
- hwwrite(vortex->mmio, WT_PARM(wt, 1), val);
- return 0xc;
- break;
- case 3: /* param 2 */
- /*
- printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n",
- WT_PARM(wt,2), (int)val);
- */
- hwwrite(vortex->mmio, WT_PARM(wt, 2), val);
- return 0xc;
- break;
- case 4: /* param 3 */
- /*
- printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n",
- WT_PARM(wt,3), (int)val);
- */
- hwwrite(vortex->mmio, WT_PARM(wt, 3), val);
- return 0xc;
- break;
- case 6: /* mute */
- /*
- printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n",
- WT_MUTE(wt), (int)val);
- */
- hwwrite(vortex->mmio, WT_MUTE(wt), val);
- return 0xc;
- break;
- case 0xb:
- { /* delay */
- /*
- printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n",
- WT_DELAY(wt,0), (int)val);
- */
- hwwrite(vortex->mmio, WT_DELAY(wt, 3), val);
- hwwrite(vortex->mmio, WT_DELAY(wt, 2), val);
- hwwrite(vortex->mmio, WT_DELAY(wt, 1), val);
- hwwrite(vortex->mmio, WT_DELAY(wt, 0), val);
- return 0xc;
- }
- break;
- /* Global WT block parameters */
- case 5: /* sramp */
- ecx = WT_SRAMP(wt);
- break;
- case 8: /* aramp */
- ecx = WT_ARAMP(wt);
- break;
- case 9: /* mramp */
- ecx = WT_MRAMP(wt);
- break;
- case 0xa: /* ctrl */
- ecx = WT_CTRL(wt);
- break;
- case 0xc: /* ds_reg */
- ecx = WT_DSREG(wt);
- break;
- default:
- return 0;
- break;
- }
- /*
- printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", ecx, (int)val);
- */
- hwwrite(vortex->mmio, ecx, val);
- return 1;
-}
-
-static void vortex_wt_init(vortex_t * vortex)
-{
- u32 var4, var8, varc, var10 = 0, edi;
-
- var10 &= 0xFFFFFFE3;
- var10 |= 0x22;
- var10 &= 0xFFFFFEBF;
- var10 |= 0x80;
- var10 |= 0x200;
- var10 &= 0xfffffffe;
- var10 &= 0xfffffbff;
- var10 |= 0x1800;
- // var10 = 0x1AA2
- var4 = 0x10000000;
- varc = 0x00830000;
- var8 = 0x00830000;
-
- /* Init Bank registers. */
- for (edi = 0; edi < (NR_WT / NR_WT_PB); edi++) {
- vortex_wt_SetReg(vortex, 0xc, edi, 0); /* ds_reg */
- vortex_wt_SetReg(vortex, 0xa, edi, var10); /* ctrl */
- vortex_wt_SetReg(vortex, 0x9, edi, var4); /* mramp */
- vortex_wt_SetReg(vortex, 0x8, edi, varc); /* aramp */
- vortex_wt_SetReg(vortex, 0x5, edi, var8); /* sramp */
- }
- /* Init Voice registers. */
- for (edi = 0; edi < NR_WT; edi++) {
- vortex_wt_SetReg(vortex, 0x4, edi, 0); /* param 3 0x20c */
- vortex_wt_SetReg(vortex, 0x3, edi, 0); /* param 2 0x208 */
- vortex_wt_SetReg(vortex, 0x2, edi, 0); /* param 1 0x204 */
- vortex_wt_SetReg(vortex, 0x1, edi, 0); /* param 0 0x200 */
- vortex_wt_SetReg(vortex, 0xb, edi, 0); /* delay 0x400 - 0x40c */
- }
- var10 |= 1;
- for (edi = 0; edi < (NR_WT / NR_WT_PB); edi++)
- vortex_wt_SetReg(vortex, 0xa, edi, var10); /* ctrl */
-}
-
-/* Extract of CAdbTopology::SetVolume(struct _ASPVOLUME *) */
-#if 0
-static void vortex_wt_SetVolume(vortex_t * vortex, int wt, int vol[])
-{
- wt_voice_t *voice = &(vortex->wt_voice[wt]);
- int ecx = vol[1], eax = vol[0];
-
- /* This is pure guess */
- voice->parm0 &= 0xff00ffff;
- voice->parm0 |= (vol[0] & 0xff) << 0x10;
- voice->parm1 &= 0xff00ffff;
- voice->parm1 |= (vol[1] & 0xff) << 0x10;
-
- /* This is real */
- hwwrite(vortex, WT_PARM(wt, 0), voice->parm0);
- hwwrite(vortex, WT_PARM(wt, 1), voice->parm0);
-
- if (voice->this_1D0 & 4) {
- eax >>= 8;
- ecx = eax;
- if (ecx < 0x80)
- ecx = 0x7f;
- voice->parm3 &= 0xFFFFC07F;
- voice->parm3 |= (ecx & 0x7f) << 7;
- voice->parm3 &= 0xFFFFFF80;
- voice->parm3 |= (eax & 0x7f);
- } else {
- voice->parm3 &= 0xFFE03FFF;
- voice->parm3 |= (eax & 0xFE00) << 5;
- }
-
- hwwrite(vortex, WT_PARM(wt, 3), voice->parm3);
-}
-
-/* Extract of CAdbTopology::SetFrequency(unsigned long arg_0) */
-static void vortex_wt_SetFrequency(vortex_t * vortex, int wt, unsigned int sr)
-{
- wt_voice_t *voice = &(vortex->wt_voice[wt]);
- u32 eax, edx;
-
- //FIXME: 64 bit operation.
- eax = ((sr << 0xf) * 0x57619F1) & 0xffffffff;
- edx = (((sr << 0xf) * 0x57619F1)) >> 0x20;
-
- edx >>= 0xa;
- edx <<= 1;
- if (edx) {
- if (edx & 0x0FFF80000)
- eax = 0x7fff;
- else {
- edx <<= 0xd;
- eax = 7;
- while ((edx & 0x80000000) == 0) {
- edx <<= 1;
- eax--;
- if (eax == 0)
- break;
- }
- if (eax)
- edx <<= 1;
- eax <<= 0xc;
- edx >>= 0x14;
- eax |= edx;
- }
- } else
- eax = 0;
- voice->parm0 &= 0xffff0001;
- voice->parm0 |= (eax & 0x7fff) << 1;
- voice->parm1 = voice->parm0 | 1;
- // Wt: this_1D4
- //AuWt::WriteReg((ulong)(this_1DC<<4)+0x200, (ulong)this_1E4);
- //AuWt::WriteReg((ulong)(this_1DC<<4)+0x204, (ulong)this_1E8);
- hwwrite(vortex->mmio, WT_PARM(wt, 0), voice->parm0);
- hwwrite(vortex->mmio, WT_PARM(wt, 1), voice->parm1);
-}
-#endif
-
-/* End of File */
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_wt.h b/ANDROID_3.4.5/sound/pci/au88x0/au88x0_wt.h
deleted file mode 100644
index 38d98f88..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_wt.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/***************************************************************************
- * WT register offsets.
- *
- * Wed Oct 22 13:50:20 2003
- * Copyright 2003 mjander
- * mjander@users.sourceforge.org
- ****************************************************************************/
-#ifndef _AU88X0_WT_H
-#define _AU88X0_WT_H
-
-/* WT channels are grouped in banks. Each bank has 0x20 channels. */
-/* Bank register address boundary is 0x8000 */
-
-#define NR_WT_PB 0x20
-
-/* WT bank base register (as dword address). */
-#define WT_BAR(x) (((x)&0xffe0)<<0x8)
-#define WT_BANK(x) (x>>5)
-/* WT Bank registers */
-#define WT_CTRL(bank) (((((bank)&1)<<0xd) + 0x00)<<2) /* 0x0000 */
-#define WT_SRAMP(bank) (((((bank)&1)<<0xd) + 0x01)<<2) /* 0x0004 */
-#define WT_DSREG(bank) (((((bank)&1)<<0xd) + 0x02)<<2) /* 0x0008 */
-#define WT_MRAMP(bank) (((((bank)&1)<<0xd) + 0x03)<<2) /* 0x000c */
-#define WT_GMODE(bank) (((((bank)&1)<<0xd) + 0x04)<<2) /* 0x0010 */
-#define WT_ARAMP(bank) (((((bank)&1)<<0xd) + 0x05)<<2) /* 0x0014 */
-/* WT Voice registers */
-#define WT_STEREO(voice) ((WT_BAR(voice)+ 0x20 +(((voice)&0x1f)>>1))<<2) /* 0x0080 */
-#define WT_MUTE(voice) ((WT_BAR(voice)+ 0x40 +((voice)&0x1f))<<2) /* 0x0100 */
-#define WT_RUN(voice) ((WT_BAR(voice)+ 0x60 +((voice)&0x1f))<<2) /* 0x0180 */
-/* Some kind of parameters. */
-/* PARM0, PARM1 : Filter (0xFF000000), SampleRate (0x0000FFFF) */
-/* PARM2, PARM3 : Still unknown */
-#define WT_PARM(x,y) (((WT_BAR(x))+ 0x80 +(((x)&0x1f)<<2)+(y))<<2) /* 0x0200 */
-#define WT_DELAY(x,y) (((WT_BAR(x))+ 0x100 +(((x)&0x1f)<<2)+(y))<<2) /* 0x0400 */
-
-/* Numeric indexes used by SetReg() and GetReg() */
-#if 0
-enum {
- run = 0, /* 0 W 1:run 0:stop */
- parm0, /* 1 W filter, samplerate */
- parm1, /* 2 W filter, samplerate */
- parm2, /* 3 W */
- parm3, /* 4 RW volume. This value is calculated using floating point ops. */
- sramp, /* 5 W */
- mute, /* 6 W 1:mute, 0:unmute */
- gmode, /* 7 RO Looks like only bit0 is used. */
- aramp, /* 8 W */
- mramp, /* 9 W */
- ctrl, /* a W */
- delay, /* b W All 4 values are written at once with same value. */
- dsreg, /* c (R)W */
-} wt_reg;
-#endif
-
-typedef struct {
- u32 parm0; /* this_1E4 */
- u32 parm1; /* this_1E8 */
- u32 parm2; /* this_1EC */
- u32 parm3; /* this_1F0 */
- u32 this_1D0;
-} wt_voice_t;
-
-#endif /* _AU88X0_WT_H */
-
-/* End of file */
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_xtalk.c b/ANDROID_3.4.5/sound/pci/au88x0/au88x0_xtalk.c
deleted file mode 100644
index b278e285..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_xtalk.c
+++ /dev/null
@@ -1,795 +0,0 @@
-/***************************************************************************
- * au88x0_cxtalk.c
- *
- * Wed Nov 19 16:29:47 2003
- * Copyright 2003 mjander
- * mjander@users.sourceforge.org
- ****************************************************************************/
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include "au88x0_xtalk.h"
-
-/* Data (a whole lot of data.... ) */
-
-static short const sXtalkWideKLeftEq = 0x269C;
-static short const sXtalkWideKRightEq = 0x269C;
-static short const sXtalkWideKLeftXt = 0xF25E;
-static short const sXtalkWideKRightXt = 0xF25E;
-static short const sXtalkWideShiftLeftEq = 1;
-static short const sXtalkWideShiftRightEq = 1;
-static short const sXtalkWideShiftLeftXt = 0;
-static short const sXtalkWideShiftRightXt = 0;
-static unsigned short const wXtalkWideLeftDelay = 0xd;
-static unsigned short const wXtalkWideRightDelay = 0xd;
-static short const sXtalkNarrowKLeftEq = 0x468D;
-static short const sXtalkNarrowKRightEq = 0x468D;
-static short const sXtalkNarrowKLeftXt = 0xF82E;
-static short const sXtalkNarrowKRightXt = 0xF82E;
-static short const sXtalkNarrowShiftLeftEq = 0x3;
-static short const sXtalkNarrowShiftRightEq = 0x3;
-static short const sXtalkNarrowShiftLeftXt = 0;
-static short const sXtalkNarrowShiftRightXt = 0;
-static unsigned short const wXtalkNarrowLeftDelay = 0x7;
-static unsigned short const wXtalkNarrowRightDelay = 0x7;
-
-static xtalk_gains_t const asXtalkGainsDefault = {
- 0x4000, 0x4000, 0x4000, 0x4000, 0x4000,
- 0x4000, 0x4000, 0x4000, 0x4000, 0x4000
-};
-
-static xtalk_gains_t const asXtalkGainsTest = {
- 0x7fff, 0x8000, 0x0000, 0x0000, 0x0001,
- 0xffff, 0x4000, 0xc000, 0x0002, 0xfffe
-};
-
-static xtalk_gains_t const asXtalkGains1Chan = {
- 0x7FFF, 0, 0, 0, 0,
- 0x7FFF, 0, 0, 0, 0,
-};
-
-// Input gain for 4 A3D slices. One possible input pair is left zero.
-static xtalk_gains_t const asXtalkGainsAllChan = {
- 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0,
- 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0
-};
-
-static xtalk_gains_t const asXtalkGainsZeros = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-static xtalk_dline_t const alXtalkDlineZeros = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-static xtalk_dline_t const alXtalkDlineTest = {
- 0x0000fc18, 0xfff03e8, 0x000186a0, 0xfffe7960, 1, 0xffffffff, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-static xtalk_instate_t const asXtalkInStateZeros = {
- 0, 0, 0, 0
-};
-
-static xtalk_instate_t const asXtalkInStateTest = {
- 0x0080, 0xff80, 0x0001, 0xffff
-};
-
-static xtalk_state_t const asXtalkOutStateZeros = {
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0}
-};
-
-static short const sDiamondKLeftEq = 0x401d;
-static short const sDiamondKRightEq = 0x401d;
-static short const sDiamondKLeftXt = 0xF90E;
-static short const sDiamondKRightXt = 0xF90E;
-static short const sDiamondShiftLeftEq = 1;
-static short const sDiamondShiftRightEq = 1;
-static short const sDiamondShiftLeftXt = 0;
-static short const sDiamondShiftRightXt = 0;
-static unsigned short const wDiamondLeftDelay = 0xb;
-static unsigned short const wDiamondRightDelay = 0xb;
-
-static xtalk_coefs_t const asXtalkWideCoefsLeftEq = {
- {0xEC4C, 0xDCE9, 0xFDC2, 0xFEEC, 0},
- {0x5F60, 0xCBCB, 0xFC26, 0x0305, 0},
- {0x340B, 0xe8f5, 0x236c, 0xe40d, 0},
- {0x76d5, 0xc78d, 0x05ac, 0xfa5b, 0},
- {0x7F04, 0xC0FA, 0x0263, 0xFDA2, 0}
-};
-static xtalk_coefs_t const asXtalkWideCoefsRightEq = {
- {0xEC4C, 0xDCE9, 0xFDC2, 0xFEEC, 0},
- {0x5F60, 0xCBCB, 0xFC26, 0x0305, 0},
- {0x340B, 0xe8f5, 0x236c, 0xe40d, 0},
- {0x76d5, 0xc78d, 0x05ac, 0xfa5b, 0},
- {0x7F04, 0xC0FA, 0x0263, 0xFDA2, 0}
-};
-static xtalk_coefs_t const asXtalkWideCoefsLeftXt = {
- {0x55c6, 0xc97b, 0x005b, 0x0047, 0},
- {0x6a60, 0xca20, 0xffc6, 0x0040, 0},
- {0x6411, 0xd711, 0xfca1, 0x0190, 0},
- {0x77dc, 0xc79e, 0xffb8, 0x000a, 0},
- {0, 0, 0, 0, 0}
-};
-static xtalk_coefs_t const asXtalkWideCoefsRightXt = {
- {0x55c6, 0xc97b, 0x005b, 0x0047, 0},
- {0x6a60, 0xca20, 0xffc6, 0x0040, 0},
- {0x6411, 0xd711, 0xfca1, 0x0190, 0},
- {0x77dc, 0xc79e, 0xffb8, 0x000a, 0},
- {0, 0, 0, 0, 0}
-};
-static xtalk_coefs_t const asXtalkNarrowCoefsLeftEq = {
- {0x50B5, 0xD07C, 0x026D, 0xFD21, 0},
- {0x460F, 0xE44F, 0xF75E, 0xEFA6, 0},
- {0x556D, 0xDCAB, 0x2098, 0xF0F2, 0},
- {0x7E03, 0xC1F0, 0x007D, 0xFF89, 0},
- {0x383E, 0xFD9D, 0xB278, 0x4547, 0}
-};
-
-static xtalk_coefs_t const asXtalkNarrowCoefsRightEq = {
- {0x50B5, 0xD07C, 0x026D, 0xFD21, 0},
- {0x460F, 0xE44F, 0xF75E, 0xEFA6, 0},
- {0x556D, 0xDCAB, 0x2098, 0xF0F2, 0},
- {0x7E03, 0xC1F0, 0x007D, 0xFF89, 0},
- {0x383E, 0xFD9D, 0xB278, 0x4547, 0}
-};
-
-static xtalk_coefs_t const asXtalkNarrowCoefsLeftXt = {
- {0x3CB2, 0xDF49, 0xF6EA, 0x095B, 0},
- {0x6777, 0xC915, 0xFEAF, 0x00B1, 0},
- {0x7762, 0xC7D9, 0x025B, 0xFDA6, 0},
- {0x6B7A, 0xD2AA, 0xF2FB, 0x0B64, 0},
- {0, 0, 0, 0, 0}
-};
-
-static xtalk_coefs_t const asXtalkNarrowCoefsRightXt = {
- {0x3CB2, 0xDF49, 0xF6EA, 0x095B, 0},
- {0x6777, 0xC915, 0xFEAF, 0x00B1, 0},
- {0x7762, 0xC7D9, 0x025B, 0xFDA6, 0},
- {0x6B7A, 0xD2AA, 0xF2FB, 0x0B64, 0},
- {0, 0, 0, 0, 0}
-};
-
-static xtalk_coefs_t const asXtalkCoefsZeros = {
- {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0}
-};
-
-static xtalk_coefs_t const asXtalkCoefsPipe = {
- {0, 0, 0x0FA0, 0, 0},
- {0, 0, 0x0FA0, 0, 0},
- {0, 0, 0x0FA0, 0, 0},
- {0, 0, 0x0FA0, 0, 0},
- {0, 0, 0x1180, 0, 0},
-};
-static xtalk_coefs_t const asXtalkCoefsNegPipe = {
- {0, 0, 0xF380, 0, 0},
- {0, 0, 0xF380, 0, 0},
- {0, 0, 0xF380, 0, 0},
- {0, 0, 0xF380, 0, 0},
- {0, 0, 0xF200, 0, 0}
-};
-
-static xtalk_coefs_t const asXtalkCoefsNumTest = {
- {0, 0, 0xF380, 0x8000, 0x6D60},
- {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0}
-};
-
-static xtalk_coefs_t const asXtalkCoefsDenTest = {
- {0xC000, 0x2000, 0x4000, 0, 0},
- {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0}
-};
-
-static xtalk_state_t const asXtalkOutStateTest = {
- {0x7FFF, 0x0004, 0xFFFC, 0},
- {0xFE00, 0x0008, 0xFFF8, 0x4000},
- {0x0200, 0x0010, 0xFFF0, 0xC000},
- {0x8000, 0x0020, 0xFFE0, 0},
- {0, 0, 0, 0}
-};
-
-static xtalk_coefs_t const asDiamondCoefsLeftEq = {
- {0x0F1E, 0x2D05, 0xF8E3, 0x07C8, 0},
- {0x45E2, 0xCA51, 0x0448, 0xFCE7, 0},
- {0xA93E, 0xDBD5, 0x022C, 0x028A, 0},
- {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0}
-};
-
-static xtalk_coefs_t const asDiamondCoefsRightEq = {
- {0x0F1E, 0x2D05, 0xF8E3, 0x07C8, 0},
- {0x45E2, 0xCA51, 0x0448, 0xFCE7, 0},
- {0xA93E, 0xDBD5, 0x022C, 0x028A, 0},
- {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0}
-};
-
-static xtalk_coefs_t const asDiamondCoefsLeftXt = {
- {0x3B50, 0xFE08, 0xF959, 0x0060, 0},
- {0x9FCB, 0xD8F1, 0x00A2, 0x003A, 0},
- {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0}
-};
-
-static xtalk_coefs_t const asDiamondCoefsRightXt = {
- {0x3B50, 0xFE08, 0xF959, 0x0060, 0},
- {0x9FCB, 0xD8F1, 0x00A2, 0x003A, 0},
- {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0}
-};
-
- /**/
-/* XTalk EQ and XT */
-static void
-vortex_XtalkHw_SetLeftEQ(vortex_t * vortex, short arg_0, short arg_4,
- xtalk_coefs_t const coefs)
-{
- int i;
-
- for (i = 0; i < 5; i++) {
- hwwrite(vortex->mmio, 0x24200 + i * 0x24, coefs[i][0]);
- hwwrite(vortex->mmio, 0x24204 + i * 0x24, coefs[i][1]);
- hwwrite(vortex->mmio, 0x24208 + i * 0x24, coefs[i][2]);
- hwwrite(vortex->mmio, 0x2420c + i * 0x24, coefs[i][3]);
- hwwrite(vortex->mmio, 0x24210 + i * 0x24, coefs[i][4]);
- }
- hwwrite(vortex->mmio, 0x24538, arg_0 & 0xffff);
- hwwrite(vortex->mmio, 0x2453C, arg_4 & 0xffff);
-}
-
-static void
-vortex_XtalkHw_SetRightEQ(vortex_t * vortex, short arg_0, short arg_4,
- xtalk_coefs_t const coefs)
-{
- int i;
-
- for (i = 0; i < 5; i++) {
- hwwrite(vortex->mmio, 0x242b4 + i * 0x24, coefs[i][0]);
- hwwrite(vortex->mmio, 0x242b8 + i * 0x24, coefs[i][1]);
- hwwrite(vortex->mmio, 0x242bc + i * 0x24, coefs[i][2]);
- hwwrite(vortex->mmio, 0x242c0 + i * 0x24, coefs[i][3]);
- hwwrite(vortex->mmio, 0x242c4 + i * 0x24, coefs[i][4]);
- }
- hwwrite(vortex->mmio, 0x24540, arg_0 & 0xffff);
- hwwrite(vortex->mmio, 0x24544, arg_4 & 0xffff);
-}
-
-static void
-vortex_XtalkHw_SetLeftXT(vortex_t * vortex, short arg_0, short arg_4,
- xtalk_coefs_t const coefs)
-{
- int i;
-
- for (i = 0; i < 5; i++) {
- hwwrite(vortex->mmio, 0x24368 + i * 0x24, coefs[i][0]);
- hwwrite(vortex->mmio, 0x2436c + i * 0x24, coefs[i][1]);
- hwwrite(vortex->mmio, 0x24370 + i * 0x24, coefs[i][2]);
- hwwrite(vortex->mmio, 0x24374 + i * 0x24, coefs[i][3]);
- hwwrite(vortex->mmio, 0x24378 + i * 0x24, coefs[i][4]);
- }
- hwwrite(vortex->mmio, 0x24548, arg_0 & 0xffff);
- hwwrite(vortex->mmio, 0x2454C, arg_4 & 0xffff);
-}
-
-static void
-vortex_XtalkHw_SetRightXT(vortex_t * vortex, short arg_0, short arg_4,
- xtalk_coefs_t const coefs)
-{
- int i;
-
- for (i = 0; i < 5; i++) {
- hwwrite(vortex->mmio, 0x2441C + i * 0x24, coefs[i][0]);
- hwwrite(vortex->mmio, 0x24420 + i * 0x24, coefs[i][1]);
- hwwrite(vortex->mmio, 0x24424 + i * 0x24, coefs[i][2]);
- hwwrite(vortex->mmio, 0x24428 + i * 0x24, coefs[i][3]);
- hwwrite(vortex->mmio, 0x2442C + i * 0x24, coefs[i][4]);
- }
- hwwrite(vortex->mmio, 0x24550, arg_0 & 0xffff);
- hwwrite(vortex->mmio, 0x24554, arg_4 & 0xffff);
-}
-
-static void
-vortex_XtalkHw_SetLeftEQStates(vortex_t * vortex,
- xtalk_instate_t const arg_0,
- xtalk_state_t const coefs)
-{
- int i;
-
- for (i = 0; i < 5; i++) {
- hwwrite(vortex->mmio, 0x24214 + i * 0x24, coefs[i][0]);
- hwwrite(vortex->mmio, 0x24218 + i * 0x24, coefs[i][1]);
- hwwrite(vortex->mmio, 0x2421C + i * 0x24, coefs[i][2]);
- hwwrite(vortex->mmio, 0x24220 + i * 0x24, coefs[i][3]);
- }
- hwwrite(vortex->mmio, 0x244F8, arg_0[0]);
- hwwrite(vortex->mmio, 0x244FC, arg_0[1]);
- hwwrite(vortex->mmio, 0x24500, arg_0[2]);
- hwwrite(vortex->mmio, 0x24504, arg_0[3]);
-}
-
-static void
-vortex_XtalkHw_SetRightEQStates(vortex_t * vortex,
- xtalk_instate_t const arg_0,
- xtalk_state_t const coefs)
-{
- int i;
-
- for (i = 0; i < 5; i++) {
- hwwrite(vortex->mmio, 0x242C8 + i * 0x24, coefs[i][0]);
- hwwrite(vortex->mmio, 0x242CC + i * 0x24, coefs[i][1]);
- hwwrite(vortex->mmio, 0x242D0 + i * 0x24, coefs[i][2]);
- hwwrite(vortex->mmio, 0x244D4 + i * 0x24, coefs[i][3]);
- }
- hwwrite(vortex->mmio, 0x24508, arg_0[0]);
- hwwrite(vortex->mmio, 0x2450C, arg_0[1]);
- hwwrite(vortex->mmio, 0x24510, arg_0[2]);
- hwwrite(vortex->mmio, 0x24514, arg_0[3]);
-}
-
-static void
-vortex_XtalkHw_SetLeftXTStates(vortex_t * vortex,
- xtalk_instate_t const arg_0,
- xtalk_state_t const coefs)
-{
- int i;
-
- for (i = 0; i < 5; i++) {
- hwwrite(vortex->mmio, 0x2437C + i * 0x24, coefs[i][0]);
- hwwrite(vortex->mmio, 0x24380 + i * 0x24, coefs[i][1]);
- hwwrite(vortex->mmio, 0x24384 + i * 0x24, coefs[i][2]);
- hwwrite(vortex->mmio, 0x24388 + i * 0x24, coefs[i][3]);
- }
- hwwrite(vortex->mmio, 0x24518, arg_0[0]);
- hwwrite(vortex->mmio, 0x2451C, arg_0[1]);
- hwwrite(vortex->mmio, 0x24520, arg_0[2]);
- hwwrite(vortex->mmio, 0x24524, arg_0[3]);
-}
-
-static void
-vortex_XtalkHw_SetRightXTStates(vortex_t * vortex,
- xtalk_instate_t const arg_0,
- xtalk_state_t const coefs)
-{
- int i;
-
- for (i = 0; i < 5; i++) {
- hwwrite(vortex->mmio, 0x24430 + i * 0x24, coefs[i][0]);
- hwwrite(vortex->mmio, 0x24434 + i * 0x24, coefs[i][1]);
- hwwrite(vortex->mmio, 0x24438 + i * 0x24, coefs[i][2]);
- hwwrite(vortex->mmio, 0x2443C + i * 0x24, coefs[i][3]);
- }
- hwwrite(vortex->mmio, 0x24528, arg_0[0]);
- hwwrite(vortex->mmio, 0x2452C, arg_0[1]);
- hwwrite(vortex->mmio, 0x24530, arg_0[2]);
- hwwrite(vortex->mmio, 0x24534, arg_0[3]);
-}
-
-#if 0
-static void
-vortex_XtalkHw_GetLeftEQ(vortex_t * vortex, short *arg_0, short *arg_4,
- xtalk_coefs_t coefs)
-{
- int i;
-
- for (i = 0; i < 5; i++) {
- coefs[i][0] = hwread(vortex->mmio, 0x24200 + i * 0x24);
- coefs[i][1] = hwread(vortex->mmio, 0x24204 + i * 0x24);
- coefs[i][2] = hwread(vortex->mmio, 0x24208 + i * 0x24);
- coefs[i][3] = hwread(vortex->mmio, 0x2420c + i * 0x24);
- coefs[i][4] = hwread(vortex->mmio, 0x24210 + i * 0x24);
- }
- *arg_0 = hwread(vortex->mmio, 0x24538) & 0xffff;
- *arg_4 = hwread(vortex->mmio, 0x2453c) & 0xffff;
-}
-
-static void
-vortex_XtalkHw_GetRightEQ(vortex_t * vortex, short *arg_0, short *arg_4,
- xtalk_coefs_t coefs)
-{
- int i;
-
- for (i = 0; i < 5; i++) {
- coefs[i][0] = hwread(vortex->mmio, 0x242b4 + i * 0x24);
- coefs[i][1] = hwread(vortex->mmio, 0x242b8 + i * 0x24);
- coefs[i][2] = hwread(vortex->mmio, 0x242bc + i * 0x24);
- coefs[i][3] = hwread(vortex->mmio, 0x242c0 + i * 0x24);
- coefs[i][4] = hwread(vortex->mmio, 0x242c4 + i * 0x24);
- }
- *arg_0 = hwread(vortex->mmio, 0x24540) & 0xffff;
- *arg_4 = hwread(vortex->mmio, 0x24544) & 0xffff;
-}
-
-static void
-vortex_XtalkHw_GetLeftXT(vortex_t * vortex, short *arg_0, short *arg_4,
- xtalk_coefs_t coefs)
-{
- int i;
-
- for (i = 0; i < 5; i++) {
- coefs[i][0] = hwread(vortex->mmio, 0x24368 + i * 0x24);
- coefs[i][1] = hwread(vortex->mmio, 0x2436C + i * 0x24);
- coefs[i][2] = hwread(vortex->mmio, 0x24370 + i * 0x24);
- coefs[i][3] = hwread(vortex->mmio, 0x24374 + i * 0x24);
- coefs[i][4] = hwread(vortex->mmio, 0x24378 + i * 0x24);
- }
- *arg_0 = hwread(vortex->mmio, 0x24548) & 0xffff;
- *arg_4 = hwread(vortex->mmio, 0x2454C) & 0xffff;
-}
-
-static void
-vortex_XtalkHw_GetRightXT(vortex_t * vortex, short *arg_0, short *arg_4,
- xtalk_coefs_t coefs)
-{
- int i;
-
- for (i = 0; i < 5; i++) {
- coefs[i][0] = hwread(vortex->mmio, 0x2441C + i * 0x24);
- coefs[i][1] = hwread(vortex->mmio, 0x24420 + i * 0x24);
- coefs[i][2] = hwread(vortex->mmio, 0x24424 + i * 0x24);
- coefs[i][3] = hwread(vortex->mmio, 0x24428 + i * 0x24);
- coefs[i][4] = hwread(vortex->mmio, 0x2442C + i * 0x24);
- }
- *arg_0 = hwread(vortex->mmio, 0x24550) & 0xffff;
- *arg_4 = hwread(vortex->mmio, 0x24554) & 0xffff;
-}
-
-static void
-vortex_XtalkHw_GetLeftEQStates(vortex_t * vortex, xtalk_instate_t arg_0,
- xtalk_state_t coefs)
-{
- int i;
-
- for (i = 0; i < 5; i++) {
- coefs[i][0] = hwread(vortex->mmio, 0x24214 + i * 0x24);
- coefs[i][1] = hwread(vortex->mmio, 0x24218 + i * 0x24);
- coefs[i][2] = hwread(vortex->mmio, 0x2421C + i * 0x24);
- coefs[i][3] = hwread(vortex->mmio, 0x24220 + i * 0x24);
- }
- arg_0[0] = hwread(vortex->mmio, 0x244F8);
- arg_0[1] = hwread(vortex->mmio, 0x244FC);
- arg_0[2] = hwread(vortex->mmio, 0x24500);
- arg_0[3] = hwread(vortex->mmio, 0x24504);
-}
-
-static void
-vortex_XtalkHw_GetRightEQStates(vortex_t * vortex, xtalk_instate_t arg_0,
- xtalk_state_t coefs)
-{
- int i;
-
- for (i = 0; i < 5; i++) {
- coefs[i][0] = hwread(vortex->mmio, 0x242C8 + i * 0x24);
- coefs[i][1] = hwread(vortex->mmio, 0x242CC + i * 0x24);
- coefs[i][2] = hwread(vortex->mmio, 0x242D0 + i * 0x24);
- coefs[i][3] = hwread(vortex->mmio, 0x242D4 + i * 0x24);
- }
- arg_0[0] = hwread(vortex->mmio, 0x24508);
- arg_0[1] = hwread(vortex->mmio, 0x2450C);
- arg_0[2] = hwread(vortex->mmio, 0x24510);
- arg_0[3] = hwread(vortex->mmio, 0x24514);
-}
-
-static void
-vortex_XtalkHw_GetLeftXTStates(vortex_t * vortex, xtalk_instate_t arg_0,
- xtalk_state_t coefs)
-{
- int i;
-
- for (i = 0; i < 5; i++) {
- coefs[i][0] = hwread(vortex->mmio, 0x2437C + i * 0x24);
- coefs[i][1] = hwread(vortex->mmio, 0x24380 + i * 0x24);
- coefs[i][2] = hwread(vortex->mmio, 0x24384 + i * 0x24);
- coefs[i][3] = hwread(vortex->mmio, 0x24388 + i * 0x24);
- }
- arg_0[0] = hwread(vortex->mmio, 0x24518);
- arg_0[1] = hwread(vortex->mmio, 0x2451C);
- arg_0[2] = hwread(vortex->mmio, 0x24520);
- arg_0[3] = hwread(vortex->mmio, 0x24524);
-}
-
-static void
-vortex_XtalkHw_GetRightXTStates(vortex_t * vortex, xtalk_instate_t arg_0,
- xtalk_state_t coefs)
-{
- int i;
-
- for (i = 0; i < 5; i++) {
- coefs[i][0] = hwread(vortex->mmio, 0x24430 + i * 0x24);
- coefs[i][1] = hwread(vortex->mmio, 0x24434 + i * 0x24);
- coefs[i][2] = hwread(vortex->mmio, 0x24438 + i * 0x24);
- coefs[i][3] = hwread(vortex->mmio, 0x2443C + i * 0x24);
- }
- arg_0[0] = hwread(vortex->mmio, 0x24528);
- arg_0[1] = hwread(vortex->mmio, 0x2452C);
- arg_0[2] = hwread(vortex->mmio, 0x24530);
- arg_0[3] = hwread(vortex->mmio, 0x24534);
-}
-
-#endif
-/* Gains */
-
-static void
-vortex_XtalkHw_SetGains(vortex_t * vortex, xtalk_gains_t const gains)
-{
- int i;
-
- for (i = 0; i < XTGAINS_SZ; i++) {
- hwwrite(vortex->mmio, 0x244D0 + (i * 4), gains[i]);
- }
-}
-
-static void
-vortex_XtalkHw_SetGainsAllChan(vortex_t * vortex)
-{
- vortex_XtalkHw_SetGains(vortex, asXtalkGainsAllChan);
-}
-
-#if 0
-static void vortex_XtalkHw_GetGains(vortex_t * vortex, xtalk_gains_t gains)
-{
- int i;
-
- for (i = 0; i < XTGAINS_SZ; i++)
- gains[i] = hwread(vortex->mmio, 0x244D0 + i * 4);
-}
-
-#endif
-/* Delay parameters */
-
-static void
-vortex_XtalkHw_SetDelay(vortex_t * vortex, unsigned short right,
- unsigned short left)
-{
- u32 esp0 = 0;
-
- esp0 &= 0x1FFFFFFF;
- esp0 |= 0xA0000000;
- esp0 = (esp0 & 0xffffE0ff) | ((right & 0x1F) << 8);
- esp0 = (esp0 & 0xfffc1fff) | ((left & 0x1F) << 0xd);
-
- hwwrite(vortex->mmio, 0x24660, esp0);
-}
-
-static void
-vortex_XtalkHw_SetLeftDline(vortex_t * vortex, xtalk_dline_t const dline)
-{
- int i;
-
- for (i = 0; i < 0x20; i++) {
- hwwrite(vortex->mmio, 0x24000 + (i << 2), dline[i] & 0xffff);
- hwwrite(vortex->mmio, 0x24080 + (i << 2), dline[i] >> 0x10);
- }
-}
-
-static void
-vortex_XtalkHw_SetRightDline(vortex_t * vortex, xtalk_dline_t const dline)
-{
- int i;
-
- for (i = 0; i < 0x20; i++) {
- hwwrite(vortex->mmio, 0x24100 + (i << 2), dline[i] & 0xffff);
- hwwrite(vortex->mmio, 0x24180 + (i << 2), dline[i] >> 0x10);
- }
-}
-
-#if 0
-static void
-vortex_XtalkHw_GetDelay(vortex_t * vortex, unsigned short *right,
- unsigned short *left)
-{
- int esp0;
-
- esp0 = hwread(vortex->mmio, 0x24660);
- *right = (esp0 >> 8) & 0x1f;
- *left = (esp0 >> 0xd) & 0x1f;
-}
-
-static void vortex_XtalkHw_GetLeftDline(vortex_t * vortex, xtalk_dline_t dline)
-{
- int i;
-
- for (i = 0; i < 0x20; i++) {
- dline[i] =
- (hwread(vortex->mmio, 0x24000 + (i << 2)) & 0xffff) |
- (hwread(vortex->mmio, 0x24080 + (i << 2)) << 0x10);
- }
-}
-
-static void vortex_XtalkHw_GetRightDline(vortex_t * vortex, xtalk_dline_t dline)
-{
- int i;
-
- for (i = 0; i < 0x20; i++) {
- dline[i] =
- (hwread(vortex->mmio, 0x24100 + (i << 2)) & 0xffff) |
- (hwread(vortex->mmio, 0x24180 + (i << 2)) << 0x10);
- }
-}
-
-#endif
-/* Control/Global stuff */
-
-#if 0
-static void vortex_XtalkHw_SetControlReg(vortex_t * vortex, u32 ctrl)
-{
- hwwrite(vortex->mmio, 0x24660, ctrl);
-}
-static void vortex_XtalkHw_GetControlReg(vortex_t * vortex, u32 *ctrl)
-{
- *ctrl = hwread(vortex->mmio, 0x24660);
-}
-#endif
-static void vortex_XtalkHw_SetSampleRate(vortex_t * vortex, u32 sr)
-{
- u32 temp;
-
- temp = (hwread(vortex->mmio, 0x24660) & 0x1FFFFFFF) | 0xC0000000;
- temp = (temp & 0xffffff07) | ((sr & 0x1f) << 3);
- hwwrite(vortex->mmio, 0x24660, temp);
-}
-
-#if 0
-static void vortex_XtalkHw_GetSampleRate(vortex_t * vortex, u32 *sr)
-{
- *sr = (hwread(vortex->mmio, 0x24660) >> 3) & 0x1f;
-}
-
-#endif
-static void vortex_XtalkHw_Enable(vortex_t * vortex)
-{
- u32 temp;
-
- temp = (hwread(vortex->mmio, 0x24660) & 0x1FFFFFFF) | 0xC0000000;
- temp |= 1;
- hwwrite(vortex->mmio, 0x24660, temp);
-
-}
-
-static void vortex_XtalkHw_Disable(vortex_t * vortex)
-{
- u32 temp;
-
- temp = (hwread(vortex->mmio, 0x24660) & 0x1FFFFFFF) | 0xC0000000;
- temp &= 0xfffffffe;
- hwwrite(vortex->mmio, 0x24660, temp);
-
-}
-
-static void vortex_XtalkHw_ZeroIO(vortex_t * vortex)
-{
- int i;
-
- for (i = 0; i < 20; i++)
- hwwrite(vortex->mmio, 0x24600 + (i << 2), 0);
- for (i = 0; i < 4; i++)
- hwwrite(vortex->mmio, 0x24650 + (i << 2), 0);
-}
-
-static void vortex_XtalkHw_ZeroState(vortex_t * vortex)
-{
- vortex_XtalkHw_ZeroIO(vortex); // inlined
-
- vortex_XtalkHw_SetLeftEQ(vortex, 0, 0, asXtalkCoefsZeros);
- vortex_XtalkHw_SetRightEQ(vortex, 0, 0, asXtalkCoefsZeros);
-
- vortex_XtalkHw_SetLeftXT(vortex, 0, 0, asXtalkCoefsZeros);
- vortex_XtalkHw_SetRightXT(vortex, 0, 0, asXtalkCoefsZeros);
-
- vortex_XtalkHw_SetGains(vortex, asXtalkGainsZeros); // inlined
-
- vortex_XtalkHw_SetDelay(vortex, 0, 0); // inlined
-
- vortex_XtalkHw_SetLeftDline(vortex, alXtalkDlineZeros); // inlined
- vortex_XtalkHw_SetRightDline(vortex, alXtalkDlineZeros); // inlined
- vortex_XtalkHw_SetLeftDline(vortex, alXtalkDlineZeros); // inlined
- vortex_XtalkHw_SetRightDline(vortex, alXtalkDlineZeros); // inlined
-
- vortex_XtalkHw_SetLeftEQStates(vortex, asXtalkInStateZeros,
- asXtalkOutStateZeros);
- vortex_XtalkHw_SetRightEQStates(vortex, asXtalkInStateZeros,
- asXtalkOutStateZeros);
- vortex_XtalkHw_SetLeftXTStates(vortex, asXtalkInStateZeros,
- asXtalkOutStateZeros);
- vortex_XtalkHw_SetRightXTStates(vortex, asXtalkInStateZeros,
- asXtalkOutStateZeros);
-}
-
-static void vortex_XtalkHw_ProgramPipe(vortex_t * vortex)
-{
-
- vortex_XtalkHw_SetLeftEQ(vortex, 0, 1, asXtalkCoefsPipe);
- vortex_XtalkHw_SetRightEQ(vortex, 0, 1, asXtalkCoefsPipe);
- vortex_XtalkHw_SetLeftXT(vortex, 0, 0, asXtalkCoefsZeros);
- vortex_XtalkHw_SetRightXT(vortex, 0, 0, asXtalkCoefsZeros);
-
- vortex_XtalkHw_SetDelay(vortex, 0, 0); // inlined
-}
-
-static void vortex_XtalkHw_ProgramXtalkWide(vortex_t * vortex)
-{
-
- vortex_XtalkHw_SetLeftEQ(vortex, sXtalkWideKLeftEq,
- sXtalkWideShiftLeftEq, asXtalkWideCoefsLeftEq);
- vortex_XtalkHw_SetRightEQ(vortex, sXtalkWideKRightEq,
- sXtalkWideShiftRightEq,
- asXtalkWideCoefsRightEq);
- vortex_XtalkHw_SetLeftXT(vortex, sXtalkWideKLeftXt,
- sXtalkWideShiftLeftXt, asXtalkWideCoefsLeftXt);
- vortex_XtalkHw_SetRightXT(vortex, sXtalkWideKLeftXt,
- sXtalkWideShiftLeftXt,
- asXtalkWideCoefsLeftXt);
-
- vortex_XtalkHw_SetDelay(vortex, wXtalkWideRightDelay, wXtalkWideLeftDelay); // inlined
-}
-
-static void vortex_XtalkHw_ProgramXtalkNarrow(vortex_t * vortex)
-{
-
- vortex_XtalkHw_SetLeftEQ(vortex, sXtalkNarrowKLeftEq,
- sXtalkNarrowShiftLeftEq,
- asXtalkNarrowCoefsLeftEq);
- vortex_XtalkHw_SetRightEQ(vortex, sXtalkNarrowKRightEq,
- sXtalkNarrowShiftRightEq,
- asXtalkNarrowCoefsRightEq);
- vortex_XtalkHw_SetLeftXT(vortex, sXtalkNarrowKLeftXt,
- sXtalkNarrowShiftLeftXt,
- asXtalkNarrowCoefsLeftXt);
- vortex_XtalkHw_SetRightXT(vortex, sXtalkNarrowKLeftXt,
- sXtalkNarrowShiftLeftXt,
- asXtalkNarrowCoefsLeftXt);
-
- vortex_XtalkHw_SetDelay(vortex, wXtalkNarrowRightDelay, wXtalkNarrowLeftDelay); // inlined
-}
-
-static void vortex_XtalkHw_ProgramDiamondXtalk(vortex_t * vortex)
-{
-
- //sDiamondKLeftEq,sDiamondKRightXt,asDiamondCoefsLeftEq
- vortex_XtalkHw_SetLeftEQ(vortex, sDiamondKLeftEq,
- sDiamondShiftLeftEq, asDiamondCoefsLeftEq);
- vortex_XtalkHw_SetRightEQ(vortex, sDiamondKRightEq,
- sDiamondShiftRightEq, asDiamondCoefsRightEq);
- vortex_XtalkHw_SetLeftXT(vortex, sDiamondKLeftXt,
- sDiamondShiftLeftXt, asDiamondCoefsLeftXt);
- vortex_XtalkHw_SetRightXT(vortex, sDiamondKLeftXt,
- sDiamondShiftLeftXt, asDiamondCoefsLeftXt);
-
- vortex_XtalkHw_SetDelay(vortex, wDiamondRightDelay, wDiamondLeftDelay); // inlined
-}
-
-static void vortex_XtalkHw_init(vortex_t * vortex)
-{
- vortex_XtalkHw_ZeroState(vortex);
-}
-
-/* End of file */
diff --git a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_xtalk.h b/ANDROID_3.4.5/sound/pci/au88x0/au88x0_xtalk.h
deleted file mode 100644
index 7f4534b9..00000000
--- a/ANDROID_3.4.5/sound/pci/au88x0/au88x0_xtalk.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/***************************************************************************
- * au88x0_cxtalk.h
- *
- * Wed Nov 19 19:07:17 2003
- * Copyright 2003 mjander
- * mjander@users.sourceforge.org
- ****************************************************************************/
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/* The crosstalk canceler supports 5 stereo input channels. The result is
- available at one single output route pair (stereo). */
-
-#ifndef _AU88X0_CXTALK_H
-#define _AU88X0_CXTALK_H
-
-#include "au88x0.h"
-
-#define XTDLINE_SZ 32
-#define XTGAINS_SZ 10
-#define XTINST_SZ 4
-
-#define XT_HEADPHONE 1
-#define XT_SPEAKER0 2
-#define XT_SPEAKER1 3
-#define XT_DIAMOND 4
-
-typedef u32 xtalk_dline_t[XTDLINE_SZ];
-typedef u16 xtalk_gains_t[XTGAINS_SZ];
-typedef u16 xtalk_instate_t[XTINST_SZ];
-typedef u16 xtalk_coefs_t[5][5];
-typedef u16 xtalk_state_t[5][4];
-
-static void vortex_XtalkHw_SetGains(vortex_t * vortex,
- xtalk_gains_t const gains);
-static void vortex_XtalkHw_SetGainsAllChan(vortex_t * vortex);
-static void vortex_XtalkHw_SetSampleRate(vortex_t * vortex, u32 sr);
-static void vortex_XtalkHw_ProgramPipe(vortex_t * vortex);
-static void vortex_XtalkHw_ProgramPipe(vortex_t * vortex);
-static void vortex_XtalkHw_ProgramXtalkWide(vortex_t * vortex);
-static void vortex_XtalkHw_ProgramXtalkNarrow(vortex_t * vortex);
-static void vortex_XtalkHw_ProgramDiamondXtalk(vortex_t * vortex);
-static void vortex_XtalkHw_Enable(vortex_t * vortex);
-static void vortex_XtalkHw_Disable(vortex_t * vortex);
-static void vortex_XtalkHw_init(vortex_t * vortex);
-
-#endif /* _AU88X0_CXTALK_H */
diff --git a/ANDROID_3.4.5/sound/pci/aw2/Makefile b/ANDROID_3.4.5/sound/pci/aw2/Makefile
deleted file mode 100644
index 842335d3..00000000
--- a/ANDROID_3.4.5/sound/pci/aw2/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-snd-aw2-objs := aw2-alsa.o aw2-saa7146.o
-
-obj-$(CONFIG_SND_AW2) += snd-aw2.o
diff --git a/ANDROID_3.4.5/sound/pci/aw2/aw2-alsa.c b/ANDROID_3.4.5/sound/pci/aw2/aw2-alsa.c
deleted file mode 100644
index 1c523193..00000000
--- a/ANDROID_3.4.5/sound/pci/aw2/aw2-alsa.c
+++ /dev/null
@@ -1,792 +0,0 @@
-/*****************************************************************************
- *
- * Copyright (C) 2008 Cedric Bregardis <cedric.bregardis@free.fr> and
- * Jean-Christian Hassler <jhassler@free.fr>
- *
- * This file is part of the Audiowerk2 ALSA driver
- *
- * The Audiowerk2 ALSA driver is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2.
- *
- * The Audiowerk2 ALSA driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with the Audiowerk2 ALSA driver; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- *
- *****************************************************************************/
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/control.h>
-
-#include "saa7146.h"
-#include "aw2-saa7146.h"
-
-MODULE_AUTHOR("Cedric Bregardis <cedric.bregardis@free.fr>, "
- "Jean-Christian Hassler <jhassler@free.fr>");
-MODULE_DESCRIPTION("Emagic Audiowerk 2 sound driver");
-MODULE_LICENSE("GPL");
-
-/*********************************
- * DEFINES
- ********************************/
-#define CTL_ROUTE_ANALOG 0
-#define CTL_ROUTE_DIGITAL 1
-
-/*********************************
- * TYPEDEFS
- ********************************/
- /* hardware definition */
-static struct snd_pcm_hardware snd_aw2_playback_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_44100,
- .rate_min = 44100,
- .rate_max = 44100,
- .channels_min = 2,
- .channels_max = 4,
- .buffer_bytes_max = 32768,
- .period_bytes_min = 4096,
- .period_bytes_max = 32768,
- .periods_min = 1,
- .periods_max = 1024,
-};
-
-static struct snd_pcm_hardware snd_aw2_capture_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_44100,
- .rate_min = 44100,
- .rate_max = 44100,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 32768,
- .period_bytes_min = 4096,
- .period_bytes_max = 32768,
- .periods_min = 1,
- .periods_max = 1024,
-};
-
-struct aw2_pcm_device {
- struct snd_pcm *pcm;
- unsigned int stream_number;
- struct aw2 *chip;
-};
-
-struct aw2 {
- struct snd_aw2_saa7146 saa7146;
-
- struct pci_dev *pci;
- int irq;
- spinlock_t reg_lock;
- struct mutex mtx;
-
- unsigned long iobase_phys;
- void __iomem *iobase_virt;
-
- struct snd_card *card;
-
- struct aw2_pcm_device device_playback[NB_STREAM_PLAYBACK];
- struct aw2_pcm_device device_capture[NB_STREAM_CAPTURE];
-};
-
-/*********************************
- * FUNCTION DECLARATIONS
- ********************************/
-static int __init alsa_card_aw2_init(void);
-static void __exit alsa_card_aw2_exit(void);
-static int snd_aw2_dev_free(struct snd_device *device);
-static int __devinit snd_aw2_create(struct snd_card *card,
- struct pci_dev *pci, struct aw2 **rchip);
-static int __devinit snd_aw2_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id);
-static void __devexit snd_aw2_remove(struct pci_dev *pci);
-static int snd_aw2_pcm_playback_open(struct snd_pcm_substream *substream);
-static int snd_aw2_pcm_playback_close(struct snd_pcm_substream *substream);
-static int snd_aw2_pcm_capture_open(struct snd_pcm_substream *substream);
-static int snd_aw2_pcm_capture_close(struct snd_pcm_substream *substream);
-static int snd_aw2_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params);
-static int snd_aw2_pcm_hw_free(struct snd_pcm_substream *substream);
-static int snd_aw2_pcm_prepare_playback(struct snd_pcm_substream *substream);
-static int snd_aw2_pcm_prepare_capture(struct snd_pcm_substream *substream);
-static int snd_aw2_pcm_trigger_playback(struct snd_pcm_substream *substream,
- int cmd);
-static int snd_aw2_pcm_trigger_capture(struct snd_pcm_substream *substream,
- int cmd);
-static snd_pcm_uframes_t snd_aw2_pcm_pointer_playback(struct snd_pcm_substream
- *substream);
-static snd_pcm_uframes_t snd_aw2_pcm_pointer_capture(struct snd_pcm_substream
- *substream);
-static int __devinit snd_aw2_new_pcm(struct aw2 *chip);
-
-static int snd_aw2_control_switch_capture_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo);
-static int snd_aw2_control_switch_capture_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value
- *ucontrol);
-static int snd_aw2_control_switch_capture_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value
- *ucontrol);
-
-/*********************************
- * VARIABLES
- ********************************/
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Audiowerk2 soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for the Audiowerk2 soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard.");
-
-static DEFINE_PCI_DEVICE_TABLE(snd_aw2_ids) = {
- {PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, 0, 0,
- 0, 0, 0},
- {0}
-};
-
-MODULE_DEVICE_TABLE(pci, snd_aw2_ids);
-
-/* pci_driver definition */
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_aw2_ids,
- .probe = snd_aw2_probe,
- .remove = __devexit_p(snd_aw2_remove),
-};
-
-/* operators for playback PCM alsa interface */
-static struct snd_pcm_ops snd_aw2_playback_ops = {
- .open = snd_aw2_pcm_playback_open,
- .close = snd_aw2_pcm_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_aw2_pcm_hw_params,
- .hw_free = snd_aw2_pcm_hw_free,
- .prepare = snd_aw2_pcm_prepare_playback,
- .trigger = snd_aw2_pcm_trigger_playback,
- .pointer = snd_aw2_pcm_pointer_playback,
-};
-
-/* operators for capture PCM alsa interface */
-static struct snd_pcm_ops snd_aw2_capture_ops = {
- .open = snd_aw2_pcm_capture_open,
- .close = snd_aw2_pcm_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_aw2_pcm_hw_params,
- .hw_free = snd_aw2_pcm_hw_free,
- .prepare = snd_aw2_pcm_prepare_capture,
- .trigger = snd_aw2_pcm_trigger_capture,
- .pointer = snd_aw2_pcm_pointer_capture,
-};
-
-static struct snd_kcontrol_new aw2_control __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Capture Route",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = 0xffff,
- .info = snd_aw2_control_switch_capture_info,
- .get = snd_aw2_control_switch_capture_get,
- .put = snd_aw2_control_switch_capture_put
-};
-
-/*********************************
- * FUNCTION IMPLEMENTATIONS
- ********************************/
-
-/* initialization of the module */
-static int __init alsa_card_aw2_init(void)
-{
- snd_printdd(KERN_DEBUG "aw2: Load aw2 module\n");
- return pci_register_driver(&driver);
-}
-
-/* clean up the module */
-static void __exit alsa_card_aw2_exit(void)
-{
- snd_printdd(KERN_DEBUG "aw2: Unload aw2 module\n");
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_aw2_init);
-module_exit(alsa_card_aw2_exit);
-
-/* component-destructor */
-static int snd_aw2_dev_free(struct snd_device *device)
-{
- struct aw2 *chip = device->device_data;
-
- /* Free hardware */
- snd_aw2_saa7146_free(&chip->saa7146);
-
- /* release the irq */
- if (chip->irq >= 0)
- free_irq(chip->irq, (void *)chip);
- /* release the i/o ports & memory */
- if (chip->iobase_virt)
- iounmap(chip->iobase_virt);
-
- pci_release_regions(chip->pci);
- /* disable the PCI entry */
- pci_disable_device(chip->pci);
- /* release the data */
- kfree(chip);
-
- return 0;
-}
-
-/* chip-specific constructor */
-static int __devinit snd_aw2_create(struct snd_card *card,
- struct pci_dev *pci, struct aw2 **rchip)
-{
- struct aw2 *chip;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_aw2_dev_free,
- };
-
- *rchip = NULL;
-
- /* initialize the PCI entry */
- err = pci_enable_device(pci);
- if (err < 0)
- return err;
- pci_set_master(pci);
-
- /* check PCI availability (32bit DMA) */
- if ((pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0) ||
- (pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0)) {
- printk(KERN_ERR "aw2: Impossible to set 32bit mask DMA\n");
- pci_disable_device(pci);
- return -ENXIO;
- }
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- /* initialize the stuff */
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
-
- /* (1) PCI resource allocation */
- err = pci_request_regions(pci, "Audiowerk2");
- if (err < 0) {
- pci_disable_device(pci);
- kfree(chip);
- return err;
- }
- chip->iobase_phys = pci_resource_start(pci, 0);
- chip->iobase_virt =
- ioremap_nocache(chip->iobase_phys,
- pci_resource_len(pci, 0));
-
- if (chip->iobase_virt == NULL) {
- printk(KERN_ERR "aw2: unable to remap memory region");
- pci_release_regions(pci);
- pci_disable_device(pci);
- kfree(chip);
- return -ENOMEM;
- }
-
- /* (2) initialization of the chip hardware */
- snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt);
-
- if (request_irq(pci->irq, snd_aw2_saa7146_interrupt,
- IRQF_SHARED, KBUILD_MODNAME, chip)) {
- printk(KERN_ERR "aw2: Cannot grab irq %d\n", pci->irq);
-
- iounmap(chip->iobase_virt);
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
- kfree(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
- if (err < 0) {
- free_irq(chip->irq, (void *)chip);
- iounmap(chip->iobase_virt);
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
- kfree(chip);
- return err;
- }
-
- snd_card_set_dev(card, &pci->dev);
- *rchip = chip;
-
- printk(KERN_INFO
- "Audiowerk 2 sound card (saa7146 chipset) detected and "
- "managed\n");
- return 0;
-}
-
-/* constructor */
-static int __devinit snd_aw2_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct aw2 *chip;
- int err;
-
- /* (1) Continue if device is not enabled, else inc dev */
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- /* (2) Create card instance */
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- /* (3) Create main component */
- err = snd_aw2_create(card, pci, &chip);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- /* initialize mutex */
- mutex_init(&chip->mtx);
- /* init spinlock */
- spin_lock_init(&chip->reg_lock);
- /* (4) Define driver ID and name string */
- strcpy(card->driver, "aw2");
- strcpy(card->shortname, "Audiowerk2");
-
- sprintf(card->longname, "%s with SAA7146 irq %i",
- card->shortname, chip->irq);
-
- /* (5) Create other components */
- snd_aw2_new_pcm(chip);
-
- /* (6) Register card instance */
- err = snd_card_register(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- /* (7) Set PCI driver data */
- pci_set_drvdata(pci, card);
-
- dev++;
- return 0;
-}
-
-/* destructor */
-static void __devexit snd_aw2_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-/* open callback */
-static int snd_aw2_pcm_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- snd_printdd(KERN_DEBUG "aw2: Playback_open\n");
- runtime->hw = snd_aw2_playback_hw;
- return 0;
-}
-
-/* close callback */
-static int snd_aw2_pcm_playback_close(struct snd_pcm_substream *substream)
-{
- return 0;
-
-}
-
-static int snd_aw2_pcm_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- snd_printdd(KERN_DEBUG "aw2: Capture_open\n");
- runtime->hw = snd_aw2_capture_hw;
- return 0;
-}
-
-/* close callback */
-static int snd_aw2_pcm_capture_close(struct snd_pcm_substream *substream)
-{
- /* TODO: something to do ? */
- return 0;
-}
-
- /* hw_params callback */
-static int snd_aw2_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-}
-
-/* hw_free callback */
-static int snd_aw2_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-/* prepare callback for playback */
-static int snd_aw2_pcm_prepare_playback(struct snd_pcm_substream *substream)
-{
- struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream);
- struct aw2 *chip = pcm_device->chip;
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long period_size, buffer_size;
-
- mutex_lock(&chip->mtx);
-
- period_size = snd_pcm_lib_period_bytes(substream);
- buffer_size = snd_pcm_lib_buffer_bytes(substream);
-
- snd_aw2_saa7146_pcm_init_playback(&chip->saa7146,
- pcm_device->stream_number,
- runtime->dma_addr, period_size,
- buffer_size);
-
- /* Define Interrupt callback */
- snd_aw2_saa7146_define_it_playback_callback(pcm_device->stream_number,
- (snd_aw2_saa7146_it_cb)
- snd_pcm_period_elapsed,
- (void *)substream);
-
- mutex_unlock(&chip->mtx);
-
- return 0;
-}
-
-/* prepare callback for capture */
-static int snd_aw2_pcm_prepare_capture(struct snd_pcm_substream *substream)
-{
- struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream);
- struct aw2 *chip = pcm_device->chip;
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long period_size, buffer_size;
-
- mutex_lock(&chip->mtx);
-
- period_size = snd_pcm_lib_period_bytes(substream);
- buffer_size = snd_pcm_lib_buffer_bytes(substream);
-
- snd_aw2_saa7146_pcm_init_capture(&chip->saa7146,
- pcm_device->stream_number,
- runtime->dma_addr, period_size,
- buffer_size);
-
- /* Define Interrupt callback */
- snd_aw2_saa7146_define_it_capture_callback(pcm_device->stream_number,
- (snd_aw2_saa7146_it_cb)
- snd_pcm_period_elapsed,
- (void *)substream);
-
- mutex_unlock(&chip->mtx);
-
- return 0;
-}
-
-/* playback trigger callback */
-static int snd_aw2_pcm_trigger_playback(struct snd_pcm_substream *substream,
- int cmd)
-{
- int status = 0;
- struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream);
- struct aw2 *chip = pcm_device->chip;
- spin_lock(&chip->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- snd_aw2_saa7146_pcm_trigger_start_playback(&chip->saa7146,
- pcm_device->
- stream_number);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- snd_aw2_saa7146_pcm_trigger_stop_playback(&chip->saa7146,
- pcm_device->
- stream_number);
- break;
- default:
- status = -EINVAL;
- }
- spin_unlock(&chip->reg_lock);
- return status;
-}
-
-/* capture trigger callback */
-static int snd_aw2_pcm_trigger_capture(struct snd_pcm_substream *substream,
- int cmd)
-{
- int status = 0;
- struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream);
- struct aw2 *chip = pcm_device->chip;
- spin_lock(&chip->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- snd_aw2_saa7146_pcm_trigger_start_capture(&chip->saa7146,
- pcm_device->
- stream_number);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- snd_aw2_saa7146_pcm_trigger_stop_capture(&chip->saa7146,
- pcm_device->
- stream_number);
- break;
- default:
- status = -EINVAL;
- }
- spin_unlock(&chip->reg_lock);
- return status;
-}
-
-/* playback pointer callback */
-static snd_pcm_uframes_t snd_aw2_pcm_pointer_playback(struct snd_pcm_substream
- *substream)
-{
- struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream);
- struct aw2 *chip = pcm_device->chip;
- unsigned int current_ptr;
-
- /* get the current hardware pointer */
- struct snd_pcm_runtime *runtime = substream->runtime;
- current_ptr =
- snd_aw2_saa7146_get_hw_ptr_playback(&chip->saa7146,
- pcm_device->stream_number,
- runtime->dma_area,
- runtime->buffer_size);
-
- return bytes_to_frames(substream->runtime, current_ptr);
-}
-
-/* capture pointer callback */
-static snd_pcm_uframes_t snd_aw2_pcm_pointer_capture(struct snd_pcm_substream
- *substream)
-{
- struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream);
- struct aw2 *chip = pcm_device->chip;
- unsigned int current_ptr;
-
- /* get the current hardware pointer */
- struct snd_pcm_runtime *runtime = substream->runtime;
- current_ptr =
- snd_aw2_saa7146_get_hw_ptr_capture(&chip->saa7146,
- pcm_device->stream_number,
- runtime->dma_area,
- runtime->buffer_size);
-
- return bytes_to_frames(substream->runtime, current_ptr);
-}
-
-/* create a pcm device */
-static int __devinit snd_aw2_new_pcm(struct aw2 *chip)
-{
- struct snd_pcm *pcm_playback_ana;
- struct snd_pcm *pcm_playback_num;
- struct snd_pcm *pcm_capture;
- struct aw2_pcm_device *pcm_device;
- int err = 0;
-
- /* Create new Alsa PCM device */
-
- err = snd_pcm_new(chip->card, "Audiowerk2 analog playback", 0, 1, 0,
- &pcm_playback_ana);
- if (err < 0) {
- printk(KERN_ERR "aw2: snd_pcm_new error (0x%X)\n", err);
- return err;
- }
-
- /* Creation ok */
- pcm_device = &chip->device_playback[NUM_STREAM_PLAYBACK_ANA];
-
- /* Set PCM device name */
- strcpy(pcm_playback_ana->name, "Analog playback");
- /* Associate private data to PCM device */
- pcm_playback_ana->private_data = pcm_device;
- /* set operators of PCM device */
- snd_pcm_set_ops(pcm_playback_ana, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_aw2_playback_ops);
- /* store PCM device */
- pcm_device->pcm = pcm_playback_ana;
- /* give base chip pointer to our internal pcm device
- structure */
- pcm_device->chip = chip;
- /* Give stream number to PCM device */
- pcm_device->stream_number = NUM_STREAM_PLAYBACK_ANA;
-
- /* pre-allocation of buffers */
- /* Preallocate continuous pages. */
- err = snd_pcm_lib_preallocate_pages_for_all(pcm_playback_ana,
- SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data
- (chip->pci),
- 64 * 1024, 64 * 1024);
- if (err)
- printk(KERN_ERR "aw2: snd_pcm_lib_preallocate_pages_for_all "
- "error (0x%X)\n", err);
-
- err = snd_pcm_new(chip->card, "Audiowerk2 digital playback", 1, 1, 0,
- &pcm_playback_num);
-
- if (err < 0) {
- printk(KERN_ERR "aw2: snd_pcm_new error (0x%X)\n", err);
- return err;
- }
- /* Creation ok */
- pcm_device = &chip->device_playback[NUM_STREAM_PLAYBACK_DIG];
-
- /* Set PCM device name */
- strcpy(pcm_playback_num->name, "Digital playback");
- /* Associate private data to PCM device */
- pcm_playback_num->private_data = pcm_device;
- /* set operators of PCM device */
- snd_pcm_set_ops(pcm_playback_num, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_aw2_playback_ops);
- /* store PCM device */
- pcm_device->pcm = pcm_playback_num;
- /* give base chip pointer to our internal pcm device
- structure */
- pcm_device->chip = chip;
- /* Give stream number to PCM device */
- pcm_device->stream_number = NUM_STREAM_PLAYBACK_DIG;
-
- /* pre-allocation of buffers */
- /* Preallocate continuous pages. */
- err = snd_pcm_lib_preallocate_pages_for_all(pcm_playback_num,
- SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data
- (chip->pci),
- 64 * 1024, 64 * 1024);
- if (err)
- printk(KERN_ERR
- "aw2: snd_pcm_lib_preallocate_pages_for_all error "
- "(0x%X)\n", err);
-
-
-
- err = snd_pcm_new(chip->card, "Audiowerk2 capture", 2, 0, 1,
- &pcm_capture);
-
- if (err < 0) {
- printk(KERN_ERR "aw2: snd_pcm_new error (0x%X)\n", err);
- return err;
- }
-
- /* Creation ok */
- pcm_device = &chip->device_capture[NUM_STREAM_CAPTURE_ANA];
-
- /* Set PCM device name */
- strcpy(pcm_capture->name, "Capture");
- /* Associate private data to PCM device */
- pcm_capture->private_data = pcm_device;
- /* set operators of PCM device */
- snd_pcm_set_ops(pcm_capture, SNDRV_PCM_STREAM_CAPTURE,
- &snd_aw2_capture_ops);
- /* store PCM device */
- pcm_device->pcm = pcm_capture;
- /* give base chip pointer to our internal pcm device
- structure */
- pcm_device->chip = chip;
- /* Give stream number to PCM device */
- pcm_device->stream_number = NUM_STREAM_CAPTURE_ANA;
-
- /* pre-allocation of buffers */
- /* Preallocate continuous pages. */
- err = snd_pcm_lib_preallocate_pages_for_all(pcm_capture,
- SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data
- (chip->pci),
- 64 * 1024, 64 * 1024);
- if (err)
- printk(KERN_ERR
- "aw2: snd_pcm_lib_preallocate_pages_for_all error "
- "(0x%X)\n", err);
-
-
- /* Create control */
- err = snd_ctl_add(chip->card, snd_ctl_new1(&aw2_control, chip));
- if (err < 0) {
- printk(KERN_ERR "aw2: snd_ctl_add error (0x%X)\n", err);
- return err;
- }
-
- return 0;
-}
-
-static int snd_aw2_control_switch_capture_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[2] = {
- "Analog", "Digital"
- };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) {
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
- }
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_aw2_control_switch_capture_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value
- *ucontrol)
-{
- struct aw2 *chip = snd_kcontrol_chip(kcontrol);
- if (snd_aw2_saa7146_is_using_digital_input(&chip->saa7146))
- ucontrol->value.enumerated.item[0] = CTL_ROUTE_DIGITAL;
- else
- ucontrol->value.enumerated.item[0] = CTL_ROUTE_ANALOG;
- return 0;
-}
-
-static int snd_aw2_control_switch_capture_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value
- *ucontrol)
-{
- struct aw2 *chip = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- int is_disgital =
- snd_aw2_saa7146_is_using_digital_input(&chip->saa7146);
-
- if (((ucontrol->value.integer.value[0] == CTL_ROUTE_DIGITAL)
- && !is_disgital)
- || ((ucontrol->value.integer.value[0] == CTL_ROUTE_ANALOG)
- && is_disgital)) {
- snd_aw2_saa7146_use_digital_input(&chip->saa7146, !is_disgital);
- changed = 1;
- }
- return changed;
-}
diff --git a/ANDROID_3.4.5/sound/pci/aw2/aw2-saa7146.c b/ANDROID_3.4.5/sound/pci/aw2/aw2-saa7146.c
deleted file mode 100644
index 44396369..00000000
--- a/ANDROID_3.4.5/sound/pci/aw2/aw2-saa7146.c
+++ /dev/null
@@ -1,463 +0,0 @@
-/*****************************************************************************
- *
- * Copyright (C) 2008 Cedric Bregardis <cedric.bregardis@free.fr> and
- * Jean-Christian Hassler <jhassler@free.fr>
- *
- * This file is part of the Audiowerk2 ALSA driver
- *
- * The Audiowerk2 ALSA driver is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2.
- *
- * The Audiowerk2 ALSA driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with the Audiowerk2 ALSA driver; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- *
- *****************************************************************************/
-
-#define AW2_SAA7146_M
-
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-
-#include "saa7146.h"
-#include "aw2-saa7146.h"
-
-#include "aw2-tsl.c"
-
-#define WRITEREG(value, addr) writel((value), chip->base_addr + (addr))
-#define READREG(addr) readl(chip->base_addr + (addr))
-
-static struct snd_aw2_saa7146_cb_param
- arr_substream_it_playback_cb[NB_STREAM_PLAYBACK];
-static struct snd_aw2_saa7146_cb_param
- arr_substream_it_capture_cb[NB_STREAM_CAPTURE];
-
-static int snd_aw2_saa7146_get_limit(int size);
-
-/* chip-specific destructor */
-int snd_aw2_saa7146_free(struct snd_aw2_saa7146 *chip)
-{
- /* disable all irqs */
- WRITEREG(0, IER);
-
- /* reset saa7146 */
- WRITEREG((MRST_N << 16), MC1);
-
- /* Unset base addr */
- chip->base_addr = NULL;
-
- return 0;
-}
-
-void snd_aw2_saa7146_setup(struct snd_aw2_saa7146 *chip,
- void __iomem *pci_base_addr)
-{
- /* set PCI burst/threshold
-
- Burst length definition
- VALUE BURST LENGTH
- 000 1 Dword
- 001 2 Dwords
- 010 4 Dwords
- 011 8 Dwords
- 100 16 Dwords
- 101 32 Dwords
- 110 64 Dwords
- 111 128 Dwords
-
- Threshold definition
- VALUE WRITE MODE READ MODE
- 00 1 Dword of valid data 1 empty Dword
- 01 4 Dwords of valid data 4 empty Dwords
- 10 8 Dwords of valid data 8 empty Dwords
- 11 16 Dwords of valid data 16 empty Dwords */
-
- unsigned int acon2;
- unsigned int acon1 = 0;
- int i;
-
- /* Set base addr */
- chip->base_addr = pci_base_addr;
-
- /* disable all irqs */
- WRITEREG(0, IER);
-
- /* reset saa7146 */
- WRITEREG((MRST_N << 16), MC1);
-
- /* enable audio interface */
-#ifdef __BIG_ENDIAN
- acon1 |= A1_SWAP;
- acon1 |= A2_SWAP;
-#endif
- /* WS0_CTRL, WS0_SYNC: input TSL1, I2S */
-
- /* At initialization WS1 and WS2 are disabled (configured as input) */
- acon1 |= 0 * WS1_CTRL;
- acon1 |= 0 * WS2_CTRL;
-
- /* WS4 is not used. So it must not restart A2.
- This is why it is configured as output (force to low) */
- acon1 |= 3 * WS4_CTRL;
-
- /* WS3_CTRL, WS3_SYNC: output TSL2, I2S */
- acon1 |= 2 * WS3_CTRL;
-
- /* A1 and A2 are active and asynchronous */
- acon1 |= 3 * AUDIO_MODE;
- WRITEREG(acon1, ACON1);
-
- /* The following comes from original windows driver.
- It is needed to have a correct behavior of input and output
- simultenously, but I don't know why ! */
- WRITEREG(3 * (BurstA1_in) + 3 * (ThreshA1_in) +
- 3 * (BurstA1_out) + 3 * (ThreshA1_out) +
- 3 * (BurstA2_out) + 3 * (ThreshA2_out), PCI_BT_A);
-
- /* enable audio port pins */
- WRITEREG((EAP << 16) | EAP, MC1);
-
- /* enable I2C */
- WRITEREG((EI2C << 16) | EI2C, MC1);
- /* enable interrupts */
- WRITEREG(A1_out | A2_out | A1_in | IIC_S | IIC_E, IER);
-
- /* audio configuration */
- acon2 = A2_CLKSRC | BCLK1_OEN;
- WRITEREG(acon2, ACON2);
-
- /* By default use analog input */
- snd_aw2_saa7146_use_digital_input(chip, 0);
-
- /* TSL setup */
- for (i = 0; i < 8; ++i) {
- WRITEREG(tsl1[i], TSL1 + (i * 4));
- WRITEREG(tsl2[i], TSL2 + (i * 4));
- }
-
-}
-
-void snd_aw2_saa7146_pcm_init_playback(struct snd_aw2_saa7146 *chip,
- int stream_number,
- unsigned long dma_addr,
- unsigned long period_size,
- unsigned long buffer_size)
-{
- unsigned long dw_page, dw_limit;
-
- /* Configure DMA for substream
- Configuration informations: ALSA has allocated continuous memory
- pages. So we don't need to use MMU of saa7146.
- */
-
- /* No MMU -> nothing to do with PageA1, we only configure the limit of
- PageAx_out register */
- /* Disable MMU */
- dw_page = (0L << 11);
-
- /* Configure Limit for DMA access.
- The limit register defines an address limit, which generates
- an interrupt if passed by the actual PCI address pointer.
- '0001' means an interrupt will be generated if the lower
- 6 bits (64 bytes) of the PCI address are zero. '0010'
- defines a limit of 128 bytes, '0011' one of 256 bytes, and
- so on up to 1 Mbyte defined by '1111'. This interrupt range
- can be calculated as follows:
- Range = 2^(5 + Limit) bytes.
- */
- dw_limit = snd_aw2_saa7146_get_limit(period_size);
- dw_page |= (dw_limit << 4);
-
- if (stream_number == 0) {
- WRITEREG(dw_page, PageA2_out);
-
- /* Base address for DMA transfert. */
- /* This address has been reserved by ALSA. */
- /* This is a physical address */
- WRITEREG(dma_addr, BaseA2_out);
-
- /* Define upper limit for DMA access */
- WRITEREG(dma_addr + buffer_size, ProtA2_out);
-
- } else if (stream_number == 1) {
- WRITEREG(dw_page, PageA1_out);
-
- /* Base address for DMA transfert. */
- /* This address has been reserved by ALSA. */
- /* This is a physical address */
- WRITEREG(dma_addr, BaseA1_out);
-
- /* Define upper limit for DMA access */
- WRITEREG(dma_addr + buffer_size, ProtA1_out);
- } else {
- printk(KERN_ERR
- "aw2: snd_aw2_saa7146_pcm_init_playback: "
- "Substream number is not 0 or 1 -> not managed\n");
- }
-}
-
-void snd_aw2_saa7146_pcm_init_capture(struct snd_aw2_saa7146 *chip,
- int stream_number, unsigned long dma_addr,
- unsigned long period_size,
- unsigned long buffer_size)
-{
- unsigned long dw_page, dw_limit;
-
- /* Configure DMA for substream
- Configuration informations: ALSA has allocated continuous memory
- pages. So we don't need to use MMU of saa7146.
- */
-
- /* No MMU -> nothing to do with PageA1, we only configure the limit of
- PageAx_out register */
- /* Disable MMU */
- dw_page = (0L << 11);
-
- /* Configure Limit for DMA access.
- The limit register defines an address limit, which generates
- an interrupt if passed by the actual PCI address pointer.
- '0001' means an interrupt will be generated if the lower
- 6 bits (64 bytes) of the PCI address are zero. '0010'
- defines a limit of 128 bytes, '0011' one of 256 bytes, and
- so on up to 1 Mbyte defined by '1111'. This interrupt range
- can be calculated as follows:
- Range = 2^(5 + Limit) bytes.
- */
- dw_limit = snd_aw2_saa7146_get_limit(period_size);
- dw_page |= (dw_limit << 4);
-
- if (stream_number == 0) {
- WRITEREG(dw_page, PageA1_in);
-
- /* Base address for DMA transfert. */
- /* This address has been reserved by ALSA. */
- /* This is a physical address */
- WRITEREG(dma_addr, BaseA1_in);
-
- /* Define upper limit for DMA access */
- WRITEREG(dma_addr + buffer_size, ProtA1_in);
- } else {
- printk(KERN_ERR
- "aw2: snd_aw2_saa7146_pcm_init_capture: "
- "Substream number is not 0 -> not managed\n");
- }
-}
-
-void snd_aw2_saa7146_define_it_playback_callback(unsigned int stream_number,
- snd_aw2_saa7146_it_cb
- p_it_callback,
- void *p_callback_param)
-{
- if (stream_number < NB_STREAM_PLAYBACK) {
- arr_substream_it_playback_cb[stream_number].p_it_callback =
- (snd_aw2_saa7146_it_cb) p_it_callback;
- arr_substream_it_playback_cb[stream_number].p_callback_param =
- (void *)p_callback_param;
- }
-}
-
-void snd_aw2_saa7146_define_it_capture_callback(unsigned int stream_number,
- snd_aw2_saa7146_it_cb
- p_it_callback,
- void *p_callback_param)
-{
- if (stream_number < NB_STREAM_CAPTURE) {
- arr_substream_it_capture_cb[stream_number].p_it_callback =
- (snd_aw2_saa7146_it_cb) p_it_callback;
- arr_substream_it_capture_cb[stream_number].p_callback_param =
- (void *)p_callback_param;
- }
-}
-
-void snd_aw2_saa7146_pcm_trigger_start_playback(struct snd_aw2_saa7146 *chip,
- int stream_number)
-{
- unsigned int acon1 = 0;
- /* In aw8 driver, dma transfert is always active. It is
- started and stopped in a larger "space" */
- acon1 = READREG(ACON1);
- if (stream_number == 0) {
- WRITEREG((TR_E_A2_OUT << 16) | TR_E_A2_OUT, MC1);
-
- /* WS2_CTRL, WS2_SYNC: output TSL2, I2S */
- acon1 |= 2 * WS2_CTRL;
- WRITEREG(acon1, ACON1);
-
- } else if (stream_number == 1) {
- WRITEREG((TR_E_A1_OUT << 16) | TR_E_A1_OUT, MC1);
-
- /* WS1_CTRL, WS1_SYNC: output TSL1, I2S */
- acon1 |= 1 * WS1_CTRL;
- WRITEREG(acon1, ACON1);
- }
-}
-
-void snd_aw2_saa7146_pcm_trigger_stop_playback(struct snd_aw2_saa7146 *chip,
- int stream_number)
-{
- unsigned int acon1 = 0;
- acon1 = READREG(ACON1);
- if (stream_number == 0) {
- /* WS2_CTRL, WS2_SYNC: output TSL2, I2S */
- acon1 &= ~(3 * WS2_CTRL);
- WRITEREG(acon1, ACON1);
-
- WRITEREG((TR_E_A2_OUT << 16), MC1);
- } else if (stream_number == 1) {
- /* WS1_CTRL, WS1_SYNC: output TSL1, I2S */
- acon1 &= ~(3 * WS1_CTRL);
- WRITEREG(acon1, ACON1);
-
- WRITEREG((TR_E_A1_OUT << 16), MC1);
- }
-}
-
-void snd_aw2_saa7146_pcm_trigger_start_capture(struct snd_aw2_saa7146 *chip,
- int stream_number)
-{
- /* In aw8 driver, dma transfert is always active. It is
- started and stopped in a larger "space" */
- if (stream_number == 0)
- WRITEREG((TR_E_A1_IN << 16) | TR_E_A1_IN, MC1);
-}
-
-void snd_aw2_saa7146_pcm_trigger_stop_capture(struct snd_aw2_saa7146 *chip,
- int stream_number)
-{
- if (stream_number == 0)
- WRITEREG((TR_E_A1_IN << 16), MC1);
-}
-
-irqreturn_t snd_aw2_saa7146_interrupt(int irq, void *dev_id)
-{
- unsigned int isr;
- unsigned int iicsta;
- struct snd_aw2_saa7146 *chip = dev_id;
-
- isr = READREG(ISR);
- if (!isr)
- return IRQ_NONE;
-
- WRITEREG(isr, ISR);
-
- if (isr & (IIC_S | IIC_E)) {
- iicsta = READREG(IICSTA);
- WRITEREG(0x100, IICSTA);
- }
-
- if (isr & A1_out) {
- if (arr_substream_it_playback_cb[1].p_it_callback != NULL) {
- arr_substream_it_playback_cb[1].
- p_it_callback(arr_substream_it_playback_cb[1].
- p_callback_param);
- }
- }
- if (isr & A2_out) {
- if (arr_substream_it_playback_cb[0].p_it_callback != NULL) {
- arr_substream_it_playback_cb[0].
- p_it_callback(arr_substream_it_playback_cb[0].
- p_callback_param);
- }
-
- }
- if (isr & A1_in) {
- if (arr_substream_it_capture_cb[0].p_it_callback != NULL) {
- arr_substream_it_capture_cb[0].
- p_it_callback(arr_substream_it_capture_cb[0].
- p_callback_param);
- }
- }
- return IRQ_HANDLED;
-}
-
-unsigned int snd_aw2_saa7146_get_hw_ptr_playback(struct snd_aw2_saa7146 *chip,
- int stream_number,
- unsigned char *start_addr,
- unsigned int buffer_size)
-{
- long pci_adp = 0;
- size_t ptr = 0;
-
- if (stream_number == 0) {
- pci_adp = READREG(PCI_ADP3);
- ptr = pci_adp - (long)start_addr;
-
- if (ptr == buffer_size)
- ptr = 0;
- }
- if (stream_number == 1) {
- pci_adp = READREG(PCI_ADP1);
- ptr = pci_adp - (size_t) start_addr;
-
- if (ptr == buffer_size)
- ptr = 0;
- }
- return ptr;
-}
-
-unsigned int snd_aw2_saa7146_get_hw_ptr_capture(struct snd_aw2_saa7146 *chip,
- int stream_number,
- unsigned char *start_addr,
- unsigned int buffer_size)
-{
- size_t pci_adp = 0;
- size_t ptr = 0;
- if (stream_number == 0) {
- pci_adp = READREG(PCI_ADP2);
- ptr = pci_adp - (size_t) start_addr;
-
- if (ptr == buffer_size)
- ptr = 0;
- }
- return ptr;
-}
-
-void snd_aw2_saa7146_use_digital_input(struct snd_aw2_saa7146 *chip,
- int use_digital)
-{
- /* FIXME: switch between analog and digital input does not always work.
- It can produce a kind of white noise. It seams that received data
- are inverted sometime (endian inversion). Why ? I don't know, maybe
- a problem of synchronization... However for the time being I have
- not found the problem. Workaround: switch again (and again) between
- digital and analog input until it works. */
- if (use_digital)
- WRITEREG(0x40, GPIO_CTRL);
- else
- WRITEREG(0x50, GPIO_CTRL);
-}
-
-int snd_aw2_saa7146_is_using_digital_input(struct snd_aw2_saa7146 *chip)
-{
- unsigned int reg_val = READREG(GPIO_CTRL);
- if ((reg_val & 0xFF) == 0x40)
- return 1;
- else
- return 0;
-}
-
-
-static int snd_aw2_saa7146_get_limit(int size)
-{
- int limitsize = 32;
- int limit = 0;
- while (limitsize < size) {
- limitsize *= 2;
- limit++;
- }
- return limit;
-}
diff --git a/ANDROID_3.4.5/sound/pci/aw2/aw2-saa7146.h b/ANDROID_3.4.5/sound/pci/aw2/aw2-saa7146.h
deleted file mode 100644
index 5b35e358..00000000
--- a/ANDROID_3.4.5/sound/pci/aw2/aw2-saa7146.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*****************************************************************************
- *
- * Copyright (C) 2008 Cedric Bregardis <cedric.bregardis@free.fr> and
- * Jean-Christian Hassler <jhassler@free.fr>
- *
- * This file is part of the Audiowerk2 ALSA driver
- *
- * The Audiowerk2 ALSA driver is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2.
- *
- * The Audiowerk2 ALSA driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with the Audiowerk2 ALSA driver; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- *
- *****************************************************************************/
-
-#ifndef AW2_SAA7146_H
-#define AW2_SAA7146_H
-
-#define NB_STREAM_PLAYBACK 2
-#define NB_STREAM_CAPTURE 1
-
-#define NUM_STREAM_PLAYBACK_ANA 0
-#define NUM_STREAM_PLAYBACK_DIG 1
-
-#define NUM_STREAM_CAPTURE_ANA 0
-
-typedef void (*snd_aw2_saa7146_it_cb) (void *);
-
-struct snd_aw2_saa7146_cb_param {
- snd_aw2_saa7146_it_cb p_it_callback;
- void *p_callback_param;
-};
-
-/* definition of the chip-specific record */
-
-struct snd_aw2_saa7146 {
- void __iomem *base_addr;
-};
-
-extern void snd_aw2_saa7146_setup(struct snd_aw2_saa7146 *chip,
- void __iomem *pci_base_addr);
-extern int snd_aw2_saa7146_free(struct snd_aw2_saa7146 *chip);
-
-extern void snd_aw2_saa7146_pcm_init_playback(struct snd_aw2_saa7146 *chip,
- int stream_number,
- unsigned long dma_addr,
- unsigned long period_size,
- unsigned long buffer_size);
-extern void snd_aw2_saa7146_pcm_init_capture(struct snd_aw2_saa7146 *chip,
- int stream_number,
- unsigned long dma_addr,
- unsigned long period_size,
- unsigned long buffer_size);
-extern void snd_aw2_saa7146_define_it_playback_callback(unsigned int
- stream_number,
- snd_aw2_saa7146_it_cb
- p_it_callback,
- void *p_callback_param);
-extern void snd_aw2_saa7146_define_it_capture_callback(unsigned int
- stream_number,
- snd_aw2_saa7146_it_cb
- p_it_callback,
- void *p_callback_param);
-extern void snd_aw2_saa7146_pcm_trigger_start_capture(struct snd_aw2_saa7146
- *chip, int stream_number);
-extern void snd_aw2_saa7146_pcm_trigger_stop_capture(struct snd_aw2_saa7146
- *chip, int stream_number);
-
-extern void snd_aw2_saa7146_pcm_trigger_start_playback(struct snd_aw2_saa7146
- *chip,
- int stream_number);
-extern void snd_aw2_saa7146_pcm_trigger_stop_playback(struct snd_aw2_saa7146
- *chip, int stream_number);
-
-extern irqreturn_t snd_aw2_saa7146_interrupt(int irq, void *dev_id);
-extern unsigned int snd_aw2_saa7146_get_hw_ptr_playback(struct snd_aw2_saa7146
- *chip,
- int stream_number,
- unsigned char
- *start_addr,
- unsigned int
- buffer_size);
-extern unsigned int snd_aw2_saa7146_get_hw_ptr_capture(struct snd_aw2_saa7146
- *chip,
- int stream_number,
- unsigned char
- *start_addr,
- unsigned int
- buffer_size);
-
-extern void snd_aw2_saa7146_use_digital_input(struct snd_aw2_saa7146 *chip,
- int use_digital);
-
-extern int snd_aw2_saa7146_is_using_digital_input(struct snd_aw2_saa7146
- *chip);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/aw2/aw2-tsl.c b/ANDROID_3.4.5/sound/pci/aw2/aw2-tsl.c
deleted file mode 100644
index 459b0311..00000000
--- a/ANDROID_3.4.5/sound/pci/aw2/aw2-tsl.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*****************************************************************************
- *
- * Copyright (C) 2008 Cedric Bregardis <cedric.bregardis@free.fr> and
- * Jean-Christian Hassler <jhassler@free.fr>
- * Copyright 1998 Emagic Soft- und Hardware GmbH
- * Copyright 2002 Martijn Sipkema
- *
- * This file is part of the Audiowerk2 ALSA driver
- *
- * The Audiowerk2 ALSA driver is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2.
- *
- * The Audiowerk2 ALSA driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with the Audiowerk2 ALSA driver; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- *
- *****************************************************************************/
-
-#define TSL_WS0 (1UL << 31)
-#define TSL_WS1 (1UL << 30)
-#define TSL_WS2 (1UL << 29)
-#define TSL_WS3 (1UL << 28)
-#define TSL_WS4 (1UL << 27)
-#define TSL_DIS_A1 (1UL << 24)
-#define TSL_SDW_A1 (1UL << 23)
-#define TSL_SIB_A1 (1UL << 22)
-#define TSL_SF_A1 (1UL << 21)
-#define TSL_LF_A1 (1UL << 20)
-#define TSL_BSEL_A1 (1UL << 17)
-#define TSL_DOD_A1 (1UL << 15)
-#define TSL_LOW_A1 (1UL << 14)
-#define TSL_DIS_A2 (1UL << 11)
-#define TSL_SDW_A2 (1UL << 10)
-#define TSL_SIB_A2 (1UL << 9)
-#define TSL_SF_A2 (1UL << 8)
-#define TSL_LF_A2 (1UL << 7)
-#define TSL_BSEL_A2 (1UL << 4)
-#define TSL_DOD_A2 (1UL << 2)
-#define TSL_LOW_A2 (1UL << 1)
-#define TSL_EOS (1UL << 0)
-
- /* Audiowerk8 hardware setup: */
- /* WS0, SD4, TSL1 - Analog/ digital in */
- /* WS1, SD0, TSL1 - Analog out #1, digital out */
- /* WS2, SD2, TSL1 - Analog out #2 */
- /* WS3, SD1, TSL2 - Analog out #3 */
- /* WS4, SD3, TSL2 - Analog out #4 */
-
- /* Audiowerk8 timing: */
- /* Timeslot: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | ... */
-
- /* A1_INPUT: */
- /* SD4: <_ADC-L_>-------<_ADC-R_>-------< */
- /* WS0: _______________/---------------\_ */
-
- /* A1_OUTPUT: */
- /* SD0: <_1-L___>-------<_1-R___>-------< */
- /* WS1: _______________/---------------\_ */
- /* SD2: >-------<_2-L___>-------<_2-R___> */
- /* WS2: -------\_______________/--------- */
-
- /* A2_OUTPUT: */
- /* SD1: <_3-L___>-------<_3-R___>-------< */
- /* WS3: _______________/---------------\_ */
- /* SD3: >-------<_4-L___>-------<_4-R___> */
- /* WS4: -------\_______________/--------- */
-
-static int tsl1[8] = {
- 1 * TSL_SDW_A1 | 3 * TSL_BSEL_A1 |
- 0 * TSL_DIS_A1 | 0 * TSL_DOD_A1 | TSL_LF_A1,
-
- 1 * TSL_SDW_A1 | 2 * TSL_BSEL_A1 |
- 0 * TSL_DIS_A1 | 0 * TSL_DOD_A1,
-
- 0 * TSL_SDW_A1 | 3 * TSL_BSEL_A1 |
- 0 * TSL_DIS_A1 | 0 * TSL_DOD_A1,
-
- 0 * TSL_SDW_A1 | 2 * TSL_BSEL_A1 |
- 0 * TSL_DIS_A1 | 0 * TSL_DOD_A1,
-
- 1 * TSL_SDW_A1 | 1 * TSL_BSEL_A1 |
- 0 * TSL_DIS_A1 | 0 * TSL_DOD_A1 | TSL_WS1 | TSL_WS0,
-
- 1 * TSL_SDW_A1 | 0 * TSL_BSEL_A1 |
- 0 * TSL_DIS_A1 | 0 * TSL_DOD_A1 | TSL_WS1 | TSL_WS0,
-
- 0 * TSL_SDW_A1 | 1 * TSL_BSEL_A1 |
- 0 * TSL_DIS_A1 | 0 * TSL_DOD_A1 | TSL_WS1 | TSL_WS0,
-
- 0 * TSL_SDW_A1 | 0 * TSL_BSEL_A1 | 0 * TSL_DIS_A1 |
- 0 * TSL_DOD_A1 | TSL_WS1 | TSL_WS0 | TSL_SF_A1 | TSL_EOS,
-};
-
-static int tsl2[8] = {
- 0 * TSL_SDW_A2 | 3 * TSL_BSEL_A2 | 2 * TSL_DOD_A2 | TSL_LF_A2,
- 0 * TSL_SDW_A2 | 2 * TSL_BSEL_A2 | 2 * TSL_DOD_A2,
- 0 * TSL_SDW_A2 | 3 * TSL_BSEL_A2 | 2 * TSL_DOD_A2,
- 0 * TSL_SDW_A2 | 2 * TSL_BSEL_A2 | 2 * TSL_DOD_A2,
- 0 * TSL_SDW_A2 | 1 * TSL_BSEL_A2 | 2 * TSL_DOD_A2 | TSL_WS2,
- 0 * TSL_SDW_A2 | 0 * TSL_BSEL_A2 | 2 * TSL_DOD_A2 | TSL_WS2,
- 0 * TSL_SDW_A2 | 1 * TSL_BSEL_A2 | 2 * TSL_DOD_A2 | TSL_WS2,
- 0 * TSL_SDW_A2 | 0 * TSL_BSEL_A2 | 2 * TSL_DOD_A2 | TSL_WS2 | TSL_EOS
-};
diff --git a/ANDROID_3.4.5/sound/pci/aw2/saa7146.h b/ANDROID_3.4.5/sound/pci/aw2/saa7146.h
deleted file mode 100644
index ce0ab5f9..00000000
--- a/ANDROID_3.4.5/sound/pci/aw2/saa7146.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/*****************************************************************************
- *
- * Copyright (C) 2008 Cedric Bregardis <cedric.bregardis@free.fr> and
- * Jean-Christian Hassler <jhassler@free.fr>
- *
- * This file is part of the Audiowerk2 ALSA driver
- *
- * The Audiowerk2 ALSA driver is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2.
- *
- * The Audiowerk2 ALSA driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with the Audiowerk2 ALSA driver; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- *
- *****************************************************************************/
-
-/* SAA7146 registers */
-#define PCI_BT_A 0x4C
-#define IICTFR 0x8C
-#define IICSTA 0x90
-#define BaseA1_in 0x94
-#define ProtA1_in 0x98
-#define PageA1_in 0x9C
-#define BaseA1_out 0xA0
-#define ProtA1_out 0xA4
-#define PageA1_out 0xA8
-#define BaseA2_in 0xAC
-#define ProtA2_in 0xB0
-#define PageA2_in 0xB4
-#define BaseA2_out 0xB8
-#define ProtA2_out 0xBC
-#define PageA2_out 0xC0
-#define IER 0xDC
-#define GPIO_CTRL 0xE0
-#define ACON1 0xF4
-#define ACON2 0xF8
-#define MC1 0xFC
-#define MC2 0x100
-#define ISR 0x10C
-#define PSR 0x110
-#define SSR 0x114
-#define PCI_ADP1 0x12C
-#define PCI_ADP2 0x130
-#define PCI_ADP3 0x134
-#define PCI_ADP4 0x138
-#define LEVEL_REP 0x140
-#define FB_BUFFER1 0x144
-#define FB_BUFFER2 0x148
-#define TSL1 0x180
-#define TSL2 0x1C0
-
-#define ME (1UL << 11)
-#define LIMIT (1UL << 4)
-#define PV (1UL << 3)
-
-/* PSR/ISR/IER */
-#define PPEF (1UL << 31)
-#define PABO (1UL << 30)
-#define IIC_S (1UL << 17)
-#define IIC_E (1UL << 16)
-#define A2_in (1UL << 15)
-#define A2_out (1UL << 14)
-#define A1_in (1UL << 13)
-#define A1_out (1UL << 12)
-#define AFOU (1UL << 11)
-#define PIN3 (1UL << 6)
-#define PIN2 (1UL << 5)
-#define PIN1 (1UL << 4)
-#define PIN0 (1UL << 3)
-#define ECS (1UL << 2)
-#define EC3S (1UL << 1)
-#define EC0S (1UL << 0)
-
-/* SSR */
-#define PRQ (1UL << 31)
-#define PMA (1UL << 30)
-#define IIC_EA (1UL << 21)
-#define IIC_EW (1UL << 20)
-#define IIC_ER (1UL << 19)
-#define IIC_EL (1UL << 18)
-#define IIC_EF (1UL << 17)
-#define AF2_in (1UL << 10)
-#define AF2_out (1UL << 9)
-#define AF1_in (1UL << 8)
-#define AF1_out (1UL << 7)
-#define EC5S (1UL << 3)
-#define EC4S (1UL << 2)
-#define EC2S (1UL << 1)
-#define EC1S (1UL << 0)
-
-/* PCI_BT_A */
-#define BurstA1_in (1UL << 26)
-#define ThreshA1_in (1UL << 24)
-#define BurstA1_out (1UL << 18)
-#define ThreshA1_out (1UL << 16)
-#define BurstA2_in (1UL << 10)
-#define ThreshA2_in (1UL << 8)
-#define BurstA2_out (1UL << 2)
-#define ThreshA2_out (1UL << 0)
-
-/* MC1 */
-#define MRST_N (1UL << 15)
-#define EAP (1UL << 9)
-#define EI2C (1UL << 8)
-#define TR_E_A2_OUT (1UL << 3)
-#define TR_E_A2_IN (1UL << 2)
-#define TR_E_A1_OUT (1UL << 1)
-#define TR_E_A1_IN (1UL << 0)
-
-/* MC2 */
-#define UPLD_IIC (1UL << 0)
-
-/* ACON1 */
-#define AUDIO_MODE (1UL << 29)
-#define MAXLEVEL (1UL << 22)
-#define A1_SWAP (1UL << 21)
-#define A2_SWAP (1UL << 20)
-#define WS0_CTRL (1UL << 18)
-#define WS0_SYNC (1UL << 16)
-#define WS1_CTRL (1UL << 14)
-#define WS1_SYNC (1UL << 12)
-#define WS2_CTRL (1UL << 10)
-#define WS2_SYNC (1UL << 8)
-#define WS3_CTRL (1UL << 6)
-#define WS3_SYNC (1UL << 4)
-#define WS4_CTRL (1UL << 2)
-#define WS4_SYNC (1UL << 0)
-
-/* ACON2 */
-#define A1_CLKSRC (1UL << 27)
-#define A2_CLKSRC (1UL << 22)
-#define INVERT_BCLK1 (1UL << 21)
-#define INVERT_BCLK2 (1UL << 20)
-#define BCLK1_OEN (1UL << 19)
-#define BCLK2_OEN (1UL << 18)
-
-/* IICSTA */
-#define IICCC (1UL << 8)
-#define ABORT (1UL << 7)
-#define SPERR (1UL << 6)
-#define APERR (1UL << 5)
-#define DTERR (1UL << 4)
-#define DRERR (1UL << 3)
-#define AL (1UL << 2)
-#define ERR (1UL << 1)
-#define BUSY (1UL << 0)
-
-/* IICTFR */
-#define BYTE2 (1UL << 24)
-#define BYTE1 (1UL << 16)
-#define BYTE0 (1UL << 8)
-#define ATRR2 (1UL << 6)
-#define ATRR1 (1UL << 4)
-#define ATRR0 (1UL << 2)
-#define ERR (1UL << 1)
-#define BUSY (1UL << 0)
-
-#define START 3
-#define CONT 2
-#define STOP 1
-#define NOP 0
diff --git a/ANDROID_3.4.5/sound/pci/azt3328.c b/ANDROID_3.4.5/sound/pci/azt3328.c
deleted file mode 100644
index 496f14c1..00000000
--- a/ANDROID_3.4.5/sound/pci/azt3328.c
+++ /dev/null
@@ -1,2895 +0,0 @@
-/* azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
- * Copyright (C) 2002, 2005 - 2011 by Andreas Mohr <andi AT lisas.de>
- *
- * Framework borrowed from Bart Hartgers's als4000.c.
- * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
- * found in a Fujitsu-Siemens PC ("Cordant", aluminum case).
- * Other versions are:
- * PCI168 A(W), sub ID 1800
- * PCI168 A/AP, sub ID 8000
- * Please give me feedback in case you try my driver with one of these!!
- *
- * Keywords: Windows XP Vista 168nt4-125.zip 168win95-125.zip PCI 168 download
- * (XP/Vista do not support this card at all but every Linux distribution
- * has very good support out of the box;
- * just to make sure that the right people hit this and get to know that,
- * despite the high level of Internet ignorance - as usual :-P -
- * about very good support for this card - on Linux!)
- *
- * GPL LICENSE
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * NOTES
- * Since Aztech does not provide any chipset documentation,
- * even on repeated request to various addresses,
- * and the answer that was finally given was negative
- * (and I was stupid enough to manage to get hold of a PCI168 soundcard
- * in the first place >:-P}),
- * I was forced to base this driver on reverse engineering
- * (3 weeks' worth of evenings filled with driver work).
- * (and no, I did NOT go the easy way: to pick up a SB PCI128 for 9 Euros)
- *
- * It is quite likely that the AZF3328 chip is the PCI cousin of the
- * AZF3318 ("azt1020 pnp", "MM Pro 16") ISA chip, given very similar specs.
- *
- * The AZF3328 chip (note: AZF3328, *not* AZT3328, that's just the driver name
- * for compatibility reasons) from Azfin (joint-venture of Aztech and Fincitec,
- * Fincitec acquired by National Semiconductor in 2002, together with the
- * Fincitec-related company ARSmikro) has the following features:
- *
- * - compatibility & compliance:
- * - Microsoft PC 97 ("PC 97 Hardware Design Guide",
- * http://www.microsoft.com/whdc/archive/pcguides.mspx)
- * - Microsoft PC 98 Baseline Audio
- * - MPU401 UART
- * - Sound Blaster Emulation (DOS Box)
- * - builtin AC97 conformant codec (SNR over 80dB)
- * Note that "conformant" != "compliant"!! this chip's mixer register layout
- * *differs* from the standard AC97 layout:
- * they chose to not implement the headphone register (which is not a
- * problem since it's merely optional), yet when doing this, they committed
- * the grave sin of letting other registers follow immediately instead of
- * keeping a headphone dummy register, thereby shifting the mixer register
- * addresses illegally. So far unfortunately it looks like the very flexible
- * ALSA AC97 support is still not enough to easily compensate for such a
- * grave layout violation despite all tweaks and quirks mechanisms it offers.
- * Well, not quite: now ac97 layer is much improved (bus-specific ops!),
- * thus I was able to implement support - it's actually working quite well.
- * An interesting item might be Aztech AMR 2800-W, since it's an AC97
- * modem card which might reveal the Aztech-specific codec ID which
- * we might want to pretend, too. Dito PCI168's brother, PCI368,
- * where the advertising datasheet says it's AC97-based and has a
- * Digital Enhanced Game Port.
- * - builtin genuine OPL3 - verified to work fine, 20080506
- * - full duplex 16bit playback/record at independent sampling rate
- * - MPU401 (+ legacy address support, claimed by one official spec sheet)
- * FIXME: how to enable legacy addr??
- * - game port (legacy address support)
- * - builtin DirectInput support, helps reduce CPU overhead (interrupt-driven
- * features supported). - See common term "Digital Enhanced Game Port"...
- * (probably DirectInput 3.0 spec - confirm)
- * - builtin 3D enhancement (said to be YAMAHA Ymersion)
- * - built-in General DirectX timer having a 20 bits counter
- * with 1us resolution (see below!)
- * - I2S serial output port for external DAC
- * [FIXME: 3.3V or 5V level? maximum rate is 66.2kHz right?]
- * - supports 33MHz PCI spec 2.1, PCI power management 1.0, compliant with ACPI
- * - supports hardware volume control
- * - single chip low cost solution (128 pin QFP)
- * - supports programmable Sub-vendor and Sub-system ID [24C02 SEEPROM chip]
- * required for Microsoft's logo compliance (FIXME: where?)
- * At least the Trident 4D Wave DX has one bit somewhere
- * to enable writes to PCI subsystem VID registers, that should be it.
- * This might easily be in extended PCI reg space, since PCI168 also has
- * some custom data starting at 0x80. What kind of config settings
- * are located in our extended PCI space anyway??
- * - PCI168 AP(W) card: power amplifier with 4 Watts/channel at 4 Ohms
- * [TDA1517P chip]
- *
- * Note that this driver now is actually *better* than the Windows driver,
- * since it additionally supports the card's 1MHz DirectX timer - just try
- * the following snd-seq module parameters etc.:
- * - options snd-seq seq_default_timer_class=2 seq_default_timer_sclass=0
- * seq_default_timer_card=0 seq_client_load=1 seq_default_timer_device=0
- * seq_default_timer_subdevice=0 seq_default_timer_resolution=1000000
- * - "timidity -iAv -B2,8 -Os -EFreverb=0"
- * - "pmidi -p 128:0 jazz.mid"
- *
- * OPL3 hardware playback testing, try something like:
- * cat /proc/asound/hwdep
- * and
- * aconnect -o
- * Then use
- * sbiload -Dhw:x,y --opl3 /usr/share/sounds/opl3/std.o3 ......./drums.o3
- * where x,y is the xx-yy number as given in hwdep.
- * Then try
- * pmidi -p a:b jazz.mid
- * where a:b is the client number plus 0 usually, as given by aconnect above.
- * Oh, and make sure to unmute the FM mixer control (doh!)
- * NOTE: power use during OPL3 playback is _VERY_ high (70W --> 90W!)
- * despite no CPU activity, possibly due to hindering ACPI idling somehow.
- * Shouldn't be a problem of the AZF3328 chip itself, I'd hope.
- * Higher PCM / FM mixer levels seem to conflict (causes crackling),
- * at least sometimes. Maybe even use with hardware sequencer timer above :)
- * adplay/adplug-utils might soon offer hardware-based OPL3 playback, too.
- *
- * Certain PCI versions of this card are susceptible to DMA traffic underruns
- * in some systems (resulting in sound crackling/clicking/popping),
- * probably because they don't have a DMA FIFO buffer or so.
- * Overview (PCI ID/PCI subID/PCI rev.):
- * - no DMA crackling on SiS735: 0x50DC/0x1801/16
- * - unknown performance: 0x50DC/0x1801/10
- * (well, it's not bad on an Athlon 1800 with now very optimized IRQ handler)
- *
- * Crackling happens with VIA chipsets or, in my case, an SiS735, which is
- * supposed to be very fast and supposed to get rid of crackling much
- * better than a VIA, yet ironically I still get crackling, like many other
- * people with the same chipset.
- * Possible remedies:
- * - use speaker (amplifier) output instead of headphone output
- * (in case crackling is due to overloaded output clipping)
- * - plug card into a different PCI slot, preferably one that isn't shared
- * too much (this helps a lot, but not completely!)
- * - get rid of PCI VGA card, use AGP instead
- * - upgrade or downgrade BIOS
- * - fiddle with PCI latency settings (setpci -v -s BUSID latency_timer=XX)
- * Not too helpful.
- * - Disable ACPI/power management/"Auto Detect RAM/PCI Clk" in BIOS
- *
- * BUGS
- * - full-duplex might *still* be problematic, however a recent test was fine
- * - (non-bug) "Bass/Treble or 3D settings don't work" - they do get evaluated
- * if you set PCM output switch to "pre 3D" instead of "post 3D".
- * If this can't be set, then get a mixer application that Isn't Stupid (tm)
- * (e.g. kmix, gamix) - unfortunately several are!!
- * - locking is not entirely clean, especially the audio stream activity
- * ints --> may be racy
- * - an _unconnected_ secondary joystick at the gameport will be reported
- * to be "active" (floating values, not precisely -1) due to the way we need
- * to read the Digital Enhanced Game Port. Not sure whether it is fixable.
- *
- * TODO
- * - use PCI_VDEVICE
- * - verify driver status on x86_64
- * - test multi-card driver operation
- * - (ab)use 1MHz DirectX timer as kernel clocksource
- * - test MPU401 MIDI playback etc.
- * - add more power micro-management (disable various units of the card
- * as long as they're unused, to improve audio quality and save power).
- * However this requires more I/O ports which I haven't figured out yet
- * and which thus might not even exist...
- * The standard suspend/resume functionality could probably make use of
- * some improvement, too...
- * - figure out what all unknown port bits are responsible for
- * - figure out some cleverly evil scheme to possibly make ALSA AC97 code
- * fully accept our quite incompatible ""AC97"" mixer and thus save some
- * code (but I'm not too optimistic that doing this is possible at all)
- * - use MMIO (memory-mapped I/O)? Slightly faster access, e.g. for gameport.
- */
-
-#include <asm/io.h>
-#include <linux/init.h>
-#include <linux/bug.h> /* WARN_ONCE */
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/gameport.h>
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/rawmidi.h>
-#include <sound/mpu401.h>
-#include <sound/opl3.h>
-#include <sound/initval.h>
-/*
- * Config switch, to use ALSA's AC97 layer instead of old custom mixer crap.
- * If the AC97 compatibility parts we needed to implement locally turn out
- * to work nicely, then remove the old implementation eventually.
- */
-#define AZF_USE_AC97_LAYER 1
-
-#ifdef AZF_USE_AC97_LAYER
-#include <sound/ac97_codec.h>
-#endif
-#include "azt3328.h"
-
-MODULE_AUTHOR("Andreas Mohr <andi AT lisas.de>");
-MODULE_DESCRIPTION("Aztech AZF3328 (PCI168)");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_GAMEPORT 1
-#endif
-
-/* === Debug settings ===
- Further diagnostic functionality than the settings below
- does not need to be provided, since one can easily write a POSIX shell script
- to dump the card's I/O ports (those listed in lspci -v -v):
- dump()
- {
- local descr=$1; local addr=$2; local count=$3
-
- echo "${descr}: ${count} @ ${addr}:"
- dd if=/dev/port skip=`printf %d ${addr}` count=${count} bs=1 \
- 2>/dev/null| hexdump -C
- }
- and then use something like
- "dump joy200 0x200 8", "dump mpu388 0x388 4", "dump joy 0xb400 8",
- "dump codec00 0xa800 32", "dump mixer 0xb800 64", "dump synth 0xbc00 8",
- possibly within a "while true; do ... sleep 1; done" loop.
- Tweaking ports could be done using
- VALSTRING="`printf "%02x" $value`"
- printf "\x""$VALSTRING"|dd of=/dev/port seek=`printf %d ${addr}` bs=1 \
- 2>/dev/null
-*/
-
-#define DEBUG_MISC 0
-#define DEBUG_CALLS 0
-#define DEBUG_MIXER 0
-#define DEBUG_CODEC 0
-#define DEBUG_TIMER 0
-#define DEBUG_GAME 0
-#define DEBUG_PM 0
-#define MIXER_TESTING 0
-
-#if DEBUG_MISC
-#define snd_azf3328_dbgmisc(format, args...) printk(KERN_DEBUG format, ##args)
-#else
-#define snd_azf3328_dbgmisc(format, args...)
-#endif
-
-#if DEBUG_CALLS
-#define snd_azf3328_dbgcalls(format, args...) printk(format, ##args)
-#define snd_azf3328_dbgcallenter() printk(KERN_DEBUG "--> %s\n", __func__)
-#define snd_azf3328_dbgcallleave() printk(KERN_DEBUG "<-- %s\n", __func__)
-#else
-#define snd_azf3328_dbgcalls(format, args...)
-#define snd_azf3328_dbgcallenter()
-#define snd_azf3328_dbgcallleave()
-#endif
-
-#if DEBUG_MIXER
-#define snd_azf3328_dbgmixer(format, args...) printk(KERN_DEBUG format, ##args)
-#else
-#define snd_azf3328_dbgmixer(format, args...)
-#endif
-
-#if DEBUG_CODEC
-#define snd_azf3328_dbgcodec(format, args...) printk(KERN_DEBUG format, ##args)
-#else
-#define snd_azf3328_dbgcodec(format, args...)
-#endif
-
-#if DEBUG_MISC
-#define snd_azf3328_dbgtimer(format, args...) printk(KERN_DEBUG format, ##args)
-#else
-#define snd_azf3328_dbgtimer(format, args...)
-#endif
-
-#if DEBUG_GAME
-#define snd_azf3328_dbggame(format, args...) printk(KERN_DEBUG format, ##args)
-#else
-#define snd_azf3328_dbggame(format, args...)
-#endif
-
-#if DEBUG_PM
-#define snd_azf3328_dbgpm(format, args...) printk(KERN_DEBUG format, ##args)
-#else
-#define snd_azf3328_dbgpm(format, args...)
-#endif
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for AZF3328 soundcard.");
-
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for AZF3328 soundcard.");
-
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable AZF3328 soundcard.");
-
-static int seqtimer_scaling = 128;
-module_param(seqtimer_scaling, int, 0444);
-MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
-
-enum snd_azf3328_codec_type {
- /* warning: fixed indices (also used for bitmask checks!) */
- AZF_CODEC_PLAYBACK = 0,
- AZF_CODEC_CAPTURE = 1,
- AZF_CODEC_I2S_OUT = 2,
-};
-
-struct snd_azf3328_codec_data {
- unsigned long io_base; /* keep first! (avoid offset calc) */
- unsigned int dma_base; /* helper to avoid an indirection in hotpath */
- spinlock_t *lock; /* TODO: convert to our own per-codec lock member */
- struct snd_pcm_substream *substream;
- bool running;
- enum snd_azf3328_codec_type type;
- const char *name;
-};
-
-struct snd_azf3328 {
- /* often-used fields towards beginning, then grouped */
-
- unsigned long ctrl_io; /* usually 0xb000, size 128 */
- unsigned long game_io; /* usually 0xb400, size 8 */
- unsigned long mpu_io; /* usually 0xb800, size 4 */
- unsigned long opl3_io; /* usually 0xbc00, size 8 */
- unsigned long mixer_io; /* usually 0xc000, size 64 */
-
- spinlock_t reg_lock;
-
- struct snd_timer *timer;
-
- struct snd_pcm *pcm[3];
-
- /* playback, recording and I2S out codecs */
- struct snd_azf3328_codec_data codecs[3];
-
-#ifdef AZF_USE_AC97_LAYER
- struct snd_ac97 *ac97;
-#endif
-
- struct snd_card *card;
- struct snd_rawmidi *rmidi;
-
-#ifdef SUPPORT_GAMEPORT
- struct gameport *gameport;
- u16 axes[4];
-#endif
-
- struct pci_dev *pci;
- int irq;
-
- /* register 0x6a is write-only, thus need to remember setting.
- * If we need to add more registers here, then we might try to fold this
- * into some transparent combined shadow register handling with
- * CONFIG_PM register storage below, but that's slightly difficult. */
- u16 shadow_reg_ctrl_6AH;
-
-#ifdef CONFIG_PM
- /* register value containers for power management
- * Note: not always full I/O range preserved (similar to Win driver!) */
- u32 saved_regs_ctrl[AZF_ALIGN(AZF_IO_SIZE_CTRL_PM) / 4];
- u32 saved_regs_game[AZF_ALIGN(AZF_IO_SIZE_GAME_PM) / 4];
- u32 saved_regs_mpu[AZF_ALIGN(AZF_IO_SIZE_MPU_PM) / 4];
- u32 saved_regs_opl3[AZF_ALIGN(AZF_IO_SIZE_OPL3_PM) / 4];
- u32 saved_regs_mixer[AZF_ALIGN(AZF_IO_SIZE_MIXER_PM) / 4];
-#endif
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_azf3328_ids) = {
- { 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* PCI168/3328 */
- { 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 3328 */
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
-
-
-static int
-snd_azf3328_io_reg_setb(unsigned reg, u8 mask, bool do_set)
-{
- /* Well, strictly spoken, the inb/outb sequence isn't atomic
- and would need locking. However we currently don't care
- since it potentially complicates matters. */
- u8 prev = inb(reg), new;
-
- new = (do_set) ? (prev|mask) : (prev & ~mask);
- /* we need to always write the new value no matter whether it differs
- * or not, since some register bits don't indicate their setting */
- outb(new, reg);
- if (new != prev)
- return 1;
-
- return 0;
-}
-
-static inline void
-snd_azf3328_codec_outb(const struct snd_azf3328_codec_data *codec,
- unsigned reg,
- u8 value
-)
-{
- outb(value, codec->io_base + reg);
-}
-
-static inline u8
-snd_azf3328_codec_inb(const struct snd_azf3328_codec_data *codec, unsigned reg)
-{
- return inb(codec->io_base + reg);
-}
-
-static inline void
-snd_azf3328_codec_outw(const struct snd_azf3328_codec_data *codec,
- unsigned reg,
- u16 value
-)
-{
- outw(value, codec->io_base + reg);
-}
-
-static inline u16
-snd_azf3328_codec_inw(const struct snd_azf3328_codec_data *codec, unsigned reg)
-{
- return inw(codec->io_base + reg);
-}
-
-static inline void
-snd_azf3328_codec_outl(const struct snd_azf3328_codec_data *codec,
- unsigned reg,
- u32 value
-)
-{
- outl(value, codec->io_base + reg);
-}
-
-static inline void
-snd_azf3328_codec_outl_multi(const struct snd_azf3328_codec_data *codec,
- unsigned reg, const void *buffer, int count
-)
-{
- unsigned long addr = codec->io_base + reg;
- if (count) {
- const u32 *buf = buffer;
- do {
- outl(*buf++, addr);
- addr += 4;
- } while (--count);
- }
-}
-
-static inline u32
-snd_azf3328_codec_inl(const struct snd_azf3328_codec_data *codec, unsigned reg)
-{
- return inl(codec->io_base + reg);
-}
-
-static inline void
-snd_azf3328_ctrl_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value)
-{
- outb(value, chip->ctrl_io + reg);
-}
-
-static inline u8
-snd_azf3328_ctrl_inb(const struct snd_azf3328 *chip, unsigned reg)
-{
- return inb(chip->ctrl_io + reg);
-}
-
-static inline void
-snd_azf3328_ctrl_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
-{
- outw(value, chip->ctrl_io + reg);
-}
-
-static inline void
-snd_azf3328_ctrl_outl(const struct snd_azf3328 *chip, unsigned reg, u32 value)
-{
- outl(value, chip->ctrl_io + reg);
-}
-
-static inline void
-snd_azf3328_game_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value)
-{
- outb(value, chip->game_io + reg);
-}
-
-static inline void
-snd_azf3328_game_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
-{
- outw(value, chip->game_io + reg);
-}
-
-static inline u8
-snd_azf3328_game_inb(const struct snd_azf3328 *chip, unsigned reg)
-{
- return inb(chip->game_io + reg);
-}
-
-static inline u16
-snd_azf3328_game_inw(const struct snd_azf3328 *chip, unsigned reg)
-{
- return inw(chip->game_io + reg);
-}
-
-static inline void
-snd_azf3328_mixer_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
-{
- outw(value, chip->mixer_io + reg);
-}
-
-static inline u16
-snd_azf3328_mixer_inw(const struct snd_azf3328 *chip, unsigned reg)
-{
- return inw(chip->mixer_io + reg);
-}
-
-#define AZF_MUTE_BIT 0x80
-
-static bool
-snd_azf3328_mixer_mute_control(const struct snd_azf3328 *chip,
- unsigned reg, bool do_mute
-)
-{
- unsigned long portbase = chip->mixer_io + reg + 1;
- bool updated;
-
- /* the mute bit is on the *second* (i.e. right) register of a
- * left/right channel setting */
- updated = snd_azf3328_io_reg_setb(portbase, AZF_MUTE_BIT, do_mute);
-
- /* indicate whether it was muted before */
- return (do_mute) ? !updated : updated;
-}
-
-static inline bool
-snd_azf3328_mixer_mute_control_master(const struct snd_azf3328 *chip,
- bool do_mute
-)
-{
- return snd_azf3328_mixer_mute_control(
- chip,
- IDX_MIXER_PLAY_MASTER,
- do_mute
- );
-}
-
-static inline bool
-snd_azf3328_mixer_mute_control_pcm(const struct snd_azf3328 *chip,
- bool do_mute
-)
-{
- return snd_azf3328_mixer_mute_control(
- chip,
- IDX_MIXER_WAVEOUT,
- do_mute
- );
-}
-
-static inline void
-snd_azf3328_mixer_reset(const struct snd_azf3328 *chip)
-{
- /* reset (close) mixer:
- * first mute master volume, then reset
- */
- snd_azf3328_mixer_mute_control_master(chip, 1);
- snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
-}
-
-#ifdef AZF_USE_AC97_LAYER
-
-static inline void
-snd_azf3328_mixer_ac97_map_unsupported(unsigned short reg, const char *mode)
-{
- /* need to add some more or less clever emulation? */
- printk(KERN_WARNING
- "azt3328: missing %s emulation for AC97 register 0x%02x!\n",
- mode, reg);
-}
-
-/*
- * Need to have _special_ AC97 mixer hardware register index mapper,
- * to compensate for the issue of a rather AC97-incompatible hardware layout.
- */
-#define AZF_REG_MASK 0x3f
-#define AZF_AC97_REG_UNSUPPORTED 0x8000
-#define AZF_AC97_REG_REAL_IO_READ 0x4000
-#define AZF_AC97_REG_REAL_IO_WRITE 0x2000
-#define AZF_AC97_REG_REAL_IO_RW \
- (AZF_AC97_REG_REAL_IO_READ | AZF_AC97_REG_REAL_IO_WRITE)
-#define AZF_AC97_REG_EMU_IO_READ 0x0400
-#define AZF_AC97_REG_EMU_IO_WRITE 0x0200
-#define AZF_AC97_REG_EMU_IO_RW \
- (AZF_AC97_REG_EMU_IO_READ | AZF_AC97_REG_EMU_IO_WRITE)
-static unsigned short
-snd_azf3328_mixer_ac97_map_reg_idx(unsigned short reg)
-{
- static const struct {
- unsigned short azf_reg;
- } azf_reg_mapper[] = {
- /* Especially when taking into consideration
- * mono/stereo-based sequence of azf vs. AC97 control series,
- * it's quite obvious that azf simply got rid
- * of the AC97_HEADPHONE control at its intended offset,
- * thus shifted _all_ controls by one,
- * and _then_ simply added it as an FMSYNTH control at the end,
- * to make up for the offset.
- * This means we'll have to translate indices here as
- * needed and then do some tiny AC97 patch action
- * (snd_ac97_rename_vol_ctl() etc.) - that's it.
- */
- { /* AC97_RESET */ IDX_MIXER_RESET
- | AZF_AC97_REG_REAL_IO_WRITE
- | AZF_AC97_REG_EMU_IO_READ },
- { /* AC97_MASTER */ IDX_MIXER_PLAY_MASTER },
- /* note large shift: AC97_HEADPHONE to IDX_MIXER_FMSYNTH! */
- { /* AC97_HEADPHONE */ IDX_MIXER_FMSYNTH },
- { /* AC97_MASTER_MONO */ IDX_MIXER_MODEMOUT },
- { /* AC97_MASTER_TONE */ IDX_MIXER_BASSTREBLE },
- { /* AC97_PC_BEEP */ IDX_MIXER_PCBEEP },
- { /* AC97_PHONE */ IDX_MIXER_MODEMIN },
- { /* AC97_MIC */ IDX_MIXER_MIC },
- { /* AC97_LINE */ IDX_MIXER_LINEIN },
- { /* AC97_CD */ IDX_MIXER_CDAUDIO },
- { /* AC97_VIDEO */ IDX_MIXER_VIDEO },
- { /* AC97_AUX */ IDX_MIXER_AUX },
- { /* AC97_PCM */ IDX_MIXER_WAVEOUT },
- { /* AC97_REC_SEL */ IDX_MIXER_REC_SELECT },
- { /* AC97_REC_GAIN */ IDX_MIXER_REC_VOLUME },
- { /* AC97_REC_GAIN_MIC */ AZF_AC97_REG_EMU_IO_RW },
- { /* AC97_GENERAL_PURPOSE */ IDX_MIXER_ADVCTL2 },
- { /* AC97_3D_CONTROL */ IDX_MIXER_ADVCTL1 },
- };
-
- unsigned short reg_azf = AZF_AC97_REG_UNSUPPORTED;
-
- /* azf3328 supports the low-numbered and low-spec:ed range
- of AC97 regs only */
- if (reg <= AC97_3D_CONTROL) {
- unsigned short reg_idx = reg / 2;
- reg_azf = azf_reg_mapper[reg_idx].azf_reg;
- /* a translation-only entry means it's real read/write: */
- if (!(reg_azf & ~AZF_REG_MASK))
- reg_azf |= AZF_AC97_REG_REAL_IO_RW;
- } else {
- switch (reg) {
- case AC97_POWERDOWN:
- reg_azf = AZF_AC97_REG_EMU_IO_RW;
- break;
- case AC97_EXTENDED_ID:
- reg_azf = AZF_AC97_REG_EMU_IO_READ;
- break;
- case AC97_EXTENDED_STATUS:
- /* I don't know what the h*ll AC97 layer
- * would consult this _extended_ register for
- * given a base-AC97-advertised card,
- * but let's just emulate it anyway :-P
- */
- reg_azf = AZF_AC97_REG_EMU_IO_RW;
- break;
- case AC97_VENDOR_ID1:
- case AC97_VENDOR_ID2:
- reg_azf = AZF_AC97_REG_EMU_IO_READ;
- break;
- }
- }
- return reg_azf;
-}
-
-static const unsigned short
-azf_emulated_ac97_caps =
- AC97_BC_DEDICATED_MIC |
- AC97_BC_BASS_TREBLE |
- /* Headphone is an FM Synth control here */
- AC97_BC_HEADPHONE |
- /* no AC97_BC_LOUDNESS! */
- /* mask 0x7c00 is
- vendor-specific 3D enhancement
- vendor indicator.
- Since there actually _is_ an
- entry for Aztech Labs
- (13), make damn sure
- to indicate it. */
- (13 << 10);
-
-static const unsigned short
-azf_emulated_ac97_powerdown =
- /* pretend everything to be active */
- AC97_PD_ADC_STATUS |
- AC97_PD_DAC_STATUS |
- AC97_PD_MIXER_STATUS |
- AC97_PD_VREF_STATUS;
-
-/*
- * Emulated, _inofficial_ vendor ID
- * (there might be some devices such as the MR 2800-W
- * which could reveal the real Aztech AC97 ID).
- * We choose to use "AZT" prefix, and then use 1 to indicate PCI168
- * (better don't use 0x68 since there's a PCI368 as well).
- */
-static const unsigned int
-azf_emulated_ac97_vendor_id = 0x415a5401;
-
-static unsigned short
-snd_azf3328_mixer_ac97_read(struct snd_ac97 *ac97, unsigned short reg_ac97)
-{
- const struct snd_azf3328 *chip = ac97->private_data;
- unsigned short reg_azf = snd_azf3328_mixer_ac97_map_reg_idx(reg_ac97);
- unsigned short reg_val = 0;
- bool unsupported = 0;
-
- snd_azf3328_dbgmixer(
- "snd_azf3328_mixer_ac97_read reg_ac97 %u\n",
- reg_ac97
- );
- if (reg_azf & AZF_AC97_REG_UNSUPPORTED)
- unsupported = 1;
- else {
- if (reg_azf & AZF_AC97_REG_REAL_IO_READ)
- reg_val = snd_azf3328_mixer_inw(chip,
- reg_azf & AZF_REG_MASK);
- else {
- /*
- * Proceed with dummy I/O read,
- * to ensure compatible timing where this may matter.
- * (ALSA AC97 layer usually doesn't call I/O functions
- * due to intelligent I/O caching anyway)
- * Choose a mixer register that's thoroughly unrelated
- * to common audio (try to minimize distortion).
- */
- snd_azf3328_mixer_inw(chip, IDX_MIXER_SOMETHING30H);
- }
-
- if (reg_azf & AZF_AC97_REG_EMU_IO_READ) {
- switch (reg_ac97) {
- case AC97_RESET:
- reg_val |= azf_emulated_ac97_caps;
- break;
- case AC97_POWERDOWN:
- reg_val |= azf_emulated_ac97_powerdown;
- break;
- case AC97_EXTENDED_ID:
- case AC97_EXTENDED_STATUS:
- /* AFAICS we simply can't support anything: */
- reg_val |= 0;
- break;
- case AC97_VENDOR_ID1:
- reg_val = azf_emulated_ac97_vendor_id >> 16;
- break;
- case AC97_VENDOR_ID2:
- reg_val = azf_emulated_ac97_vendor_id & 0xffff;
- break;
- default:
- unsupported = 1;
- break;
- }
- }
- }
- if (unsupported)
- snd_azf3328_mixer_ac97_map_unsupported(reg_ac97, "read");
-
- return reg_val;
-}
-
-static void
-snd_azf3328_mixer_ac97_write(struct snd_ac97 *ac97,
- unsigned short reg_ac97, unsigned short val)
-{
- const struct snd_azf3328 *chip = ac97->private_data;
- unsigned short reg_azf = snd_azf3328_mixer_ac97_map_reg_idx(reg_ac97);
- bool unsupported = 0;
-
- snd_azf3328_dbgmixer(
- "snd_azf3328_mixer_ac97_write reg_ac97 %u val %u\n",
- reg_ac97, val
- );
- if (reg_azf & AZF_AC97_REG_UNSUPPORTED)
- unsupported = 1;
- else {
- if (reg_azf & AZF_AC97_REG_REAL_IO_WRITE)
- snd_azf3328_mixer_outw(
- chip,
- reg_azf & AZF_REG_MASK,
- val
- );
- else
- if (reg_azf & AZF_AC97_REG_EMU_IO_WRITE) {
- switch (reg_ac97) {
- case AC97_REC_GAIN_MIC:
- case AC97_POWERDOWN:
- case AC97_EXTENDED_STATUS:
- /*
- * Silently swallow these writes.
- * Since for most registers our card doesn't
- * actually support a comparable feature,
- * this is exactly what we should do here.
- * The AC97 layer's I/O caching probably
- * automatically takes care of all the rest...
- * (remembers written values etc.)
- */
- break;
- default:
- unsupported = 1;
- break;
- }
- }
- }
- if (unsupported)
- snd_azf3328_mixer_ac97_map_unsupported(reg_ac97, "write");
-}
-
-static int __devinit
-snd_azf3328_mixer_new(struct snd_azf3328 *chip)
-{
- struct snd_ac97_bus *bus;
- struct snd_ac97_template ac97;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_azf3328_mixer_ac97_write,
- .read = snd_azf3328_mixer_ac97_read,
- };
- int rc;
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.scaps = AC97_SCAP_SKIP_MODEM
- | AC97_SCAP_AUDIO /* we support audio! */
- | AC97_SCAP_NO_SPDIF;
- ac97.private_data = chip;
- ac97.pci = chip->pci;
-
- /*
- * ALSA's AC97 layer has terrible init crackling issues,
- * unfortunately, and since it makes use of AC97_RESET,
- * there's no use trying to mute Master Playback proactively.
- */
-
- rc = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus);
- if (!rc)
- rc = snd_ac97_mixer(bus, &ac97, &chip->ac97);
- /*
- * Make sure to complain loudly in case of AC97 init failure,
- * since failure may happen quite often,
- * due to this card being a very quirky AC97 "lookalike".
- */
- if (rc)
- printk(KERN_ERR "azt3328: AC97 init failed, err %d!\n", rc);
-
- /* If we return an error here, then snd_card_free() should
- * free up any ac97 codecs that got created, as well as the bus.
- */
- return rc;
-}
-#else /* AZF_USE_AC97_LAYER */
-static void
-snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip,
- unsigned reg,
- unsigned char dst_vol_left,
- unsigned char dst_vol_right,
- int chan_sel, int delay
-)
-{
- unsigned long portbase = chip->mixer_io + reg;
- unsigned char curr_vol_left = 0, curr_vol_right = 0;
- int left_change = 0, right_change = 0;
-
- snd_azf3328_dbgcallenter();
-
- if (chan_sel & SET_CHAN_LEFT) {
- curr_vol_left = inb(portbase + 1);
-
- /* take care of muting flag contained in left channel */
- if (curr_vol_left & AZF_MUTE_BIT)
- dst_vol_left |= AZF_MUTE_BIT;
- else
- dst_vol_left &= ~AZF_MUTE_BIT;
-
- left_change = (curr_vol_left > dst_vol_left) ? -1 : 1;
- }
-
- if (chan_sel & SET_CHAN_RIGHT) {
- curr_vol_right = inb(portbase + 0);
-
- right_change = (curr_vol_right > dst_vol_right) ? -1 : 1;
- }
-
- do {
- if (left_change) {
- if (curr_vol_left != dst_vol_left) {
- curr_vol_left += left_change;
- outb(curr_vol_left, portbase + 1);
- } else
- left_change = 0;
- }
- if (right_change) {
- if (curr_vol_right != dst_vol_right) {
- curr_vol_right += right_change;
-
- /* during volume change, the right channel is crackling
- * somewhat more than the left channel, unfortunately.
- * This seems to be a hardware issue. */
- outb(curr_vol_right, portbase + 0);
- } else
- right_change = 0;
- }
- if (delay)
- mdelay(delay);
- } while ((left_change) || (right_change));
- snd_azf3328_dbgcallleave();
-}
-
-/*
- * general mixer element
- */
-struct azf3328_mixer_reg {
- unsigned reg;
- unsigned int lchan_shift, rchan_shift;
- unsigned int mask;
- unsigned int invert: 1;
- unsigned int stereo: 1;
- unsigned int enum_c: 4;
-};
-
-#define COMPOSE_MIXER_REG(reg,lchan_shift,rchan_shift,mask,invert,stereo,enum_c) \
- ((reg) | (lchan_shift << 8) | (rchan_shift << 12) | \
- (mask << 16) | \
- (invert << 24) | \
- (stereo << 25) | \
- (enum_c << 26))
-
-static void snd_azf3328_mixer_reg_decode(struct azf3328_mixer_reg *r, unsigned long val)
-{
- r->reg = val & 0xff;
- r->lchan_shift = (val >> 8) & 0x0f;
- r->rchan_shift = (val >> 12) & 0x0f;
- r->mask = (val >> 16) & 0xff;
- r->invert = (val >> 24) & 1;
- r->stereo = (val >> 25) & 1;
- r->enum_c = (val >> 26) & 0x0f;
-}
-
-/*
- * mixer switches/volumes
- */
-
-#define AZF3328_MIXER_SWITCH(xname, reg, shift, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_azf3328_info_mixer, \
- .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
- .private_value = COMPOSE_MIXER_REG(reg, shift, 0, 0x1, invert, 0, 0), \
-}
-
-#define AZF3328_MIXER_VOL_STEREO(xname, reg, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_azf3328_info_mixer, \
- .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
- .private_value = COMPOSE_MIXER_REG(reg, 8, 0, mask, invert, 1, 0), \
-}
-
-#define AZF3328_MIXER_VOL_MONO(xname, reg, mask, is_right_chan) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_azf3328_info_mixer, \
- .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
- .private_value = COMPOSE_MIXER_REG(reg, is_right_chan ? 0 : 8, 0, mask, 1, 0, 0), \
-}
-
-#define AZF3328_MIXER_VOL_SPECIAL(xname, reg, mask, shift, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_azf3328_info_mixer, \
- .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
- .private_value = COMPOSE_MIXER_REG(reg, shift, 0, mask, invert, 0, 0), \
-}
-
-#define AZF3328_MIXER_ENUM(xname, reg, enum_c, shift) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_azf3328_info_mixer_enum, \
- .get = snd_azf3328_get_mixer_enum, .put = snd_azf3328_put_mixer_enum, \
- .private_value = COMPOSE_MIXER_REG(reg, shift, 0, 0, 0, 0, enum_c), \
-}
-
-static int
-snd_azf3328_info_mixer(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct azf3328_mixer_reg reg;
-
- snd_azf3328_dbgcallenter();
- snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
- uinfo->type = reg.mask == 1 ?
- SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = reg.stereo + 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = reg.mask;
- snd_azf3328_dbgcallleave();
- return 0;
-}
-
-static int
-snd_azf3328_get_mixer(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
- struct azf3328_mixer_reg reg;
- u16 oreg, val;
-
- snd_azf3328_dbgcallenter();
- snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
-
- oreg = snd_azf3328_mixer_inw(chip, reg.reg);
- val = (oreg >> reg.lchan_shift) & reg.mask;
- if (reg.invert)
- val = reg.mask - val;
- ucontrol->value.integer.value[0] = val;
- if (reg.stereo) {
- val = (oreg >> reg.rchan_shift) & reg.mask;
- if (reg.invert)
- val = reg.mask - val;
- ucontrol->value.integer.value[1] = val;
- }
- snd_azf3328_dbgmixer("get: %02x is %04x -> vol %02lx|%02lx "
- "(shift %02d|%02d, mask %02x, inv. %d, stereo %d)\n",
- reg.reg, oreg,
- ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
- reg.lchan_shift, reg.rchan_shift, reg.mask, reg.invert, reg.stereo);
- snd_azf3328_dbgcallleave();
- return 0;
-}
-
-static int
-snd_azf3328_put_mixer(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
- struct azf3328_mixer_reg reg;
- u16 oreg, nreg, val;
-
- snd_azf3328_dbgcallenter();
- snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
- oreg = snd_azf3328_mixer_inw(chip, reg.reg);
- val = ucontrol->value.integer.value[0] & reg.mask;
- if (reg.invert)
- val = reg.mask - val;
- nreg = oreg & ~(reg.mask << reg.lchan_shift);
- nreg |= (val << reg.lchan_shift);
- if (reg.stereo) {
- val = ucontrol->value.integer.value[1] & reg.mask;
- if (reg.invert)
- val = reg.mask - val;
- nreg &= ~(reg.mask << reg.rchan_shift);
- nreg |= (val << reg.rchan_shift);
- }
- if (reg.mask >= 0x07) /* it's a volume control, so better take care */
- snd_azf3328_mixer_write_volume_gradually(
- chip, reg.reg, nreg >> 8, nreg & 0xff,
- /* just set both channels, doesn't matter */
- SET_CHAN_LEFT|SET_CHAN_RIGHT,
- 0);
- else
- snd_azf3328_mixer_outw(chip, reg.reg, nreg);
-
- snd_azf3328_dbgmixer("put: %02x to %02lx|%02lx, "
- "oreg %04x; shift %02d|%02d -> nreg %04x; after: %04x\n",
- reg.reg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
- oreg, reg.lchan_shift, reg.rchan_shift,
- nreg, snd_azf3328_mixer_inw(chip, reg.reg));
- snd_azf3328_dbgcallleave();
- return (nreg != oreg);
-}
-
-static int
-snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static const char * const texts1[] = {
- "Mic1", "Mic2"
- };
- static const char * const texts2[] = {
- "Mix", "Mic"
- };
- static const char * const texts3[] = {
- "Mic", "CD", "Video", "Aux",
- "Line", "Mix", "Mix Mono", "Phone"
- };
- static const char * const texts4[] = {
- "pre 3D", "post 3D"
- };
- struct azf3328_mixer_reg reg;
- const char * const *p = NULL;
-
- snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = (reg.reg == IDX_MIXER_REC_SELECT) ? 2 : 1;
- uinfo->value.enumerated.items = reg.enum_c;
- if (uinfo->value.enumerated.item > reg.enum_c - 1U)
- uinfo->value.enumerated.item = reg.enum_c - 1U;
- if (reg.reg == IDX_MIXER_ADVCTL2) {
- switch(reg.lchan_shift) {
- case 8: /* modem out sel */
- p = texts1;
- break;
- case 9: /* mono sel source */
- p = texts2;
- break;
- case 15: /* PCM Out Path */
- p = texts4;
- break;
- }
- } else
- if (reg.reg == IDX_MIXER_REC_SELECT)
- p = texts3;
-
- strcpy(uinfo->value.enumerated.name, p[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int
-snd_azf3328_get_mixer_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
- struct azf3328_mixer_reg reg;
- unsigned short val;
-
- snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
- val = snd_azf3328_mixer_inw(chip, reg.reg);
- if (reg.reg == IDX_MIXER_REC_SELECT) {
- ucontrol->value.enumerated.item[0] = (val >> 8) & (reg.enum_c - 1);
- ucontrol->value.enumerated.item[1] = (val >> 0) & (reg.enum_c - 1);
- } else
- ucontrol->value.enumerated.item[0] = (val >> reg.lchan_shift) & (reg.enum_c - 1);
-
- snd_azf3328_dbgmixer("get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n",
- reg.reg, val, ucontrol->value.enumerated.item[0], ucontrol->value.enumerated.item[1],
- reg.lchan_shift, reg.enum_c);
- return 0;
-}
-
-static int
-snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
- struct azf3328_mixer_reg reg;
- u16 oreg, nreg, val;
-
- snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
- oreg = snd_azf3328_mixer_inw(chip, reg.reg);
- val = oreg;
- if (reg.reg == IDX_MIXER_REC_SELECT) {
- if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U ||
- ucontrol->value.enumerated.item[1] > reg.enum_c - 1U)
- return -EINVAL;
- val = (ucontrol->value.enumerated.item[0] << 8) |
- (ucontrol->value.enumerated.item[1] << 0);
- } else {
- if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U)
- return -EINVAL;
- val &= ~((reg.enum_c - 1) << reg.lchan_shift);
- val |= (ucontrol->value.enumerated.item[0] << reg.lchan_shift);
- }
- snd_azf3328_mixer_outw(chip, reg.reg, val);
- nreg = val;
-
- snd_azf3328_dbgmixer("put_enum: %02x to %04x, oreg %04x\n", reg.reg, val, oreg);
- return (nreg != oreg);
-}
-
-static struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = {
- AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1),
- AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1),
- AZF3328_MIXER_SWITCH("PCM Playback Switch", IDX_MIXER_WAVEOUT, 15, 1),
- AZF3328_MIXER_VOL_STEREO("PCM Playback Volume",
- IDX_MIXER_WAVEOUT, 0x1f, 1),
- AZF3328_MIXER_SWITCH("PCM 3D Bypass Playback Switch",
- IDX_MIXER_ADVCTL2, 7, 1),
- AZF3328_MIXER_SWITCH("FM Playback Switch", IDX_MIXER_FMSYNTH, 15, 1),
- AZF3328_MIXER_VOL_STEREO("FM Playback Volume", IDX_MIXER_FMSYNTH, 0x1f, 1),
- AZF3328_MIXER_SWITCH("CD Playback Switch", IDX_MIXER_CDAUDIO, 15, 1),
- AZF3328_MIXER_VOL_STEREO("CD Playback Volume", IDX_MIXER_CDAUDIO, 0x1f, 1),
- AZF3328_MIXER_SWITCH("Capture Switch", IDX_MIXER_REC_VOLUME, 15, 1),
- AZF3328_MIXER_VOL_STEREO("Capture Volume", IDX_MIXER_REC_VOLUME, 0x0f, 0),
- AZF3328_MIXER_ENUM("Capture Source", IDX_MIXER_REC_SELECT, 8, 0),
- AZF3328_MIXER_SWITCH("Mic Playback Switch", IDX_MIXER_MIC, 15, 1),
- AZF3328_MIXER_VOL_MONO("Mic Playback Volume", IDX_MIXER_MIC, 0x1f, 1),
- AZF3328_MIXER_SWITCH("Mic Boost (+20dB)", IDX_MIXER_MIC, 6, 0),
- AZF3328_MIXER_SWITCH("Line Playback Switch", IDX_MIXER_LINEIN, 15, 1),
- AZF3328_MIXER_VOL_STEREO("Line Playback Volume", IDX_MIXER_LINEIN, 0x1f, 1),
- AZF3328_MIXER_SWITCH("Beep Playback Switch", IDX_MIXER_PCBEEP, 15, 1),
- AZF3328_MIXER_VOL_SPECIAL("Beep Playback Volume", IDX_MIXER_PCBEEP, 0x0f, 1, 1),
- AZF3328_MIXER_SWITCH("Video Playback Switch", IDX_MIXER_VIDEO, 15, 1),
- AZF3328_MIXER_VOL_STEREO("Video Playback Volume", IDX_MIXER_VIDEO, 0x1f, 1),
- AZF3328_MIXER_SWITCH("Aux Playback Switch", IDX_MIXER_AUX, 15, 1),
- AZF3328_MIXER_VOL_STEREO("Aux Playback Volume", IDX_MIXER_AUX, 0x1f, 1),
- AZF3328_MIXER_SWITCH("Modem Playback Switch", IDX_MIXER_MODEMOUT, 15, 1),
- AZF3328_MIXER_VOL_MONO("Modem Playback Volume", IDX_MIXER_MODEMOUT, 0x1f, 1),
- AZF3328_MIXER_SWITCH("Modem Capture Switch", IDX_MIXER_MODEMIN, 15, 1),
- AZF3328_MIXER_VOL_MONO("Modem Capture Volume", IDX_MIXER_MODEMIN, 0x1f, 1),
- AZF3328_MIXER_ENUM("Mic Select", IDX_MIXER_ADVCTL2, 2, 8),
- AZF3328_MIXER_ENUM("Mono Output Select", IDX_MIXER_ADVCTL2, 2, 9),
- AZF3328_MIXER_ENUM("PCM Output Route", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */
- AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0),
- AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0),
- AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0),
- AZF3328_MIXER_VOL_SPECIAL("3D Control - Width", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */
- AZF3328_MIXER_VOL_SPECIAL("3D Control - Depth", IDX_MIXER_ADVCTL1, 0x03, 8, 0), /* "Hifi 3D" */
-#if MIXER_TESTING
- AZF3328_MIXER_SWITCH("0", IDX_MIXER_ADVCTL2, 0, 0),
- AZF3328_MIXER_SWITCH("1", IDX_MIXER_ADVCTL2, 1, 0),
- AZF3328_MIXER_SWITCH("2", IDX_MIXER_ADVCTL2, 2, 0),
- AZF3328_MIXER_SWITCH("3", IDX_MIXER_ADVCTL2, 3, 0),
- AZF3328_MIXER_SWITCH("4", IDX_MIXER_ADVCTL2, 4, 0),
- AZF3328_MIXER_SWITCH("5", IDX_MIXER_ADVCTL2, 5, 0),
- AZF3328_MIXER_SWITCH("6", IDX_MIXER_ADVCTL2, 6, 0),
- AZF3328_MIXER_SWITCH("7", IDX_MIXER_ADVCTL2, 7, 0),
- AZF3328_MIXER_SWITCH("8", IDX_MIXER_ADVCTL2, 8, 0),
- AZF3328_MIXER_SWITCH("9", IDX_MIXER_ADVCTL2, 9, 0),
- AZF3328_MIXER_SWITCH("10", IDX_MIXER_ADVCTL2, 10, 0),
- AZF3328_MIXER_SWITCH("11", IDX_MIXER_ADVCTL2, 11, 0),
- AZF3328_MIXER_SWITCH("12", IDX_MIXER_ADVCTL2, 12, 0),
- AZF3328_MIXER_SWITCH("13", IDX_MIXER_ADVCTL2, 13, 0),
- AZF3328_MIXER_SWITCH("14", IDX_MIXER_ADVCTL2, 14, 0),
- AZF3328_MIXER_SWITCH("15", IDX_MIXER_ADVCTL2, 15, 0),
-#endif
-};
-
-static u16 __devinitdata snd_azf3328_init_values[][2] = {
- { IDX_MIXER_PLAY_MASTER, MIXER_MUTE_MASK|0x1f1f },
- { IDX_MIXER_MODEMOUT, MIXER_MUTE_MASK|0x1f1f },
- { IDX_MIXER_BASSTREBLE, 0x0000 },
- { IDX_MIXER_PCBEEP, MIXER_MUTE_MASK|0x1f1f },
- { IDX_MIXER_MODEMIN, MIXER_MUTE_MASK|0x1f1f },
- { IDX_MIXER_MIC, MIXER_MUTE_MASK|0x001f },
- { IDX_MIXER_LINEIN, MIXER_MUTE_MASK|0x1f1f },
- { IDX_MIXER_CDAUDIO, MIXER_MUTE_MASK|0x1f1f },
- { IDX_MIXER_VIDEO, MIXER_MUTE_MASK|0x1f1f },
- { IDX_MIXER_AUX, MIXER_MUTE_MASK|0x1f1f },
- { IDX_MIXER_WAVEOUT, MIXER_MUTE_MASK|0x1f1f },
- { IDX_MIXER_FMSYNTH, MIXER_MUTE_MASK|0x1f1f },
- { IDX_MIXER_REC_VOLUME, MIXER_MUTE_MASK|0x0707 },
-};
-
-static int __devinit
-snd_azf3328_mixer_new(struct snd_azf3328 *chip)
-{
- struct snd_card *card;
- const struct snd_kcontrol_new *sw;
- unsigned int idx;
- int err;
-
- snd_azf3328_dbgcallenter();
- if (snd_BUG_ON(!chip || !chip->card))
- return -EINVAL;
-
- card = chip->card;
-
- /* mixer reset */
- snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
-
- /* mute and zero volume channels */
- for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_init_values); ++idx) {
- snd_azf3328_mixer_outw(chip,
- snd_azf3328_init_values[idx][0],
- snd_azf3328_init_values[idx][1]);
- }
-
- /* add mixer controls */
- sw = snd_azf3328_mixer_controls;
- for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_mixer_controls);
- ++idx, ++sw) {
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(sw, chip))) < 0)
- return err;
- }
- snd_component_add(card, "AZF3328 mixer");
- strcpy(card->mixername, "AZF3328 mixer");
-
- snd_azf3328_dbgcallleave();
- return 0;
-}
-#endif /* AZF_USE_AC97_LAYER */
-
-static int
-snd_azf3328_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- int res;
- snd_azf3328_dbgcallenter();
- res = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
- snd_azf3328_dbgcallleave();
- return res;
-}
-
-static int
-snd_azf3328_hw_free(struct snd_pcm_substream *substream)
-{
- snd_azf3328_dbgcallenter();
- snd_pcm_lib_free_pages(substream);
- snd_azf3328_dbgcallleave();
- return 0;
-}
-
-static void
-snd_azf3328_codec_setfmt(struct snd_azf3328_codec_data *codec,
- enum azf_freq_t bitrate,
- unsigned int format_width,
- unsigned int channels
-)
-{
- unsigned long flags;
- u16 val = 0xff00;
- u8 freq = 0;
-
- snd_azf3328_dbgcallenter();
- switch (bitrate) {
- case AZF_FREQ_4000: freq = SOUNDFORMAT_FREQ_SUSPECTED_4000; break;
- case AZF_FREQ_4800: freq = SOUNDFORMAT_FREQ_SUSPECTED_4800; break;
- case AZF_FREQ_5512:
- /* the AZF3328 names it "5510" for some strange reason */
- freq = SOUNDFORMAT_FREQ_5510; break;
- case AZF_FREQ_6620: freq = SOUNDFORMAT_FREQ_6620; break;
- case AZF_FREQ_8000: freq = SOUNDFORMAT_FREQ_8000; break;
- case AZF_FREQ_9600: freq = SOUNDFORMAT_FREQ_9600; break;
- case AZF_FREQ_11025: freq = SOUNDFORMAT_FREQ_11025; break;
- case AZF_FREQ_13240: freq = SOUNDFORMAT_FREQ_SUSPECTED_13240; break;
- case AZF_FREQ_16000: freq = SOUNDFORMAT_FREQ_16000; break;
- case AZF_FREQ_22050: freq = SOUNDFORMAT_FREQ_22050; break;
- case AZF_FREQ_32000: freq = SOUNDFORMAT_FREQ_32000; break;
- default:
- snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
- /* fall-through */
- case AZF_FREQ_44100: freq = SOUNDFORMAT_FREQ_44100; break;
- case AZF_FREQ_48000: freq = SOUNDFORMAT_FREQ_48000; break;
- case AZF_FREQ_66200: freq = SOUNDFORMAT_FREQ_SUSPECTED_66200; break;
- }
- /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */
- /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */
- /* val = 0xff0a; 47m30.599s (4764,891Hz; -> 4800Hz???) yup, 4803Hz */
- /* val = 0xff0c; 57m0.510s (4010,263Hz; -> 4000Hz???) yup, 4003Hz */
- /* val = 0xff05; 5m11.556s (... -> 44100Hz) */
- /* val = 0xff03; 10m21.529s (21872,463Hz; -> 22050Hz???) */
- /* val = 0xff0f; 20m41.883s (10937,993Hz; -> 11025Hz???) */
- /* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */
- /* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */
-
- val |= freq;
-
- if (channels == 2)
- val |= SOUNDFORMAT_FLAG_2CHANNELS;
-
- if (format_width == 16)
- val |= SOUNDFORMAT_FLAG_16BIT;
-
- spin_lock_irqsave(codec->lock, flags);
-
- /* set bitrate/format */
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_SOUNDFORMAT, val);
-
- /* changing the bitrate/format settings switches off the
- * audio output with an annoying click in case of 8/16bit format change
- * (maybe shutting down DAC/ADC?), thus immediately
- * do some tweaking to reenable it and get rid of the clicking
- * (FIXME: yes, it works, but what exactly am I doing here?? :)
- * FIXME: does this have some side effects for full-duplex
- * or other dramatic side effects? */
- /* do it for non-capture codecs only */
- if (codec->type != AZF_CODEC_CAPTURE)
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
- snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS) |
- DMA_RUN_SOMETHING1 |
- DMA_RUN_SOMETHING2 |
- SOMETHING_ALMOST_ALWAYS_SET |
- DMA_EPILOGUE_SOMETHING |
- DMA_SOMETHING_ELSE
- );
-
- spin_unlock_irqrestore(codec->lock, flags);
- snd_azf3328_dbgcallleave();
-}
-
-static inline void
-snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328_codec_data *codec
-)
-{
- /* choose lowest frequency for low power consumption.
- * While this will cause louder noise due to rather coarse frequency,
- * it should never matter since output should always
- * get disabled properly when idle anyway. */
- snd_azf3328_codec_setfmt(codec, AZF_FREQ_4000, 8, 1);
-}
-
-static void
-snd_azf3328_ctrl_reg_6AH_update(struct snd_azf3328 *chip,
- unsigned bitmask,
- bool enable
-)
-{
- bool do_mask = !enable;
- if (do_mask)
- chip->shadow_reg_ctrl_6AH |= bitmask;
- else
- chip->shadow_reg_ctrl_6AH &= ~bitmask;
- snd_azf3328_dbgcodec("6AH_update mask 0x%04x do_mask %d: val 0x%04x\n",
- bitmask, do_mask, chip->shadow_reg_ctrl_6AH);
- snd_azf3328_ctrl_outw(chip, IDX_IO_6AH, chip->shadow_reg_ctrl_6AH);
-}
-
-static inline void
-snd_azf3328_ctrl_enable_codecs(struct snd_azf3328 *chip, bool enable)
-{
- snd_azf3328_dbgcodec("codec_enable %d\n", enable);
- /* no idea what exactly is being done here, but I strongly assume it's
- * PM related */
- snd_azf3328_ctrl_reg_6AH_update(
- chip, IO_6A_PAUSE_PLAYBACK_BIT8, enable
- );
-}
-
-static void
-snd_azf3328_ctrl_codec_activity(struct snd_azf3328 *chip,
- enum snd_azf3328_codec_type codec_type,
- bool enable
-)
-{
- struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
- bool need_change = (codec->running != enable);
-
- snd_azf3328_dbgcodec(
- "codec_activity: %s codec, enable %d, need_change %d\n",
- codec->name, enable, need_change
- );
- if (need_change) {
- static const struct {
- enum snd_azf3328_codec_type other1;
- enum snd_azf3328_codec_type other2;
- } peer_codecs[3] =
- { { AZF_CODEC_CAPTURE, AZF_CODEC_I2S_OUT },
- { AZF_CODEC_PLAYBACK, AZF_CODEC_I2S_OUT },
- { AZF_CODEC_PLAYBACK, AZF_CODEC_CAPTURE } };
- bool call_function;
-
- if (enable)
- /* if enable codec, call enable_codecs func
- to enable codec supply... */
- call_function = 1;
- else {
- /* ...otherwise call enable_codecs func
- (which globally shuts down operation of codecs)
- only in case the other codecs are currently
- not active either! */
- call_function =
- ((!chip->codecs[peer_codecs[codec_type].other1]
- .running)
- && (!chip->codecs[peer_codecs[codec_type].other2]
- .running));
- }
- if (call_function)
- snd_azf3328_ctrl_enable_codecs(chip, enable);
-
- /* ...and adjust clock, too
- * (reduce noise and power consumption) */
- if (!enable)
- snd_azf3328_codec_setfmt_lowpower(codec);
- codec->running = enable;
- }
-}
-
-static void
-snd_azf3328_codec_setdmaa(struct snd_azf3328_codec_data *codec,
- unsigned long addr,
- unsigned int period_bytes,
- unsigned int buffer_bytes
-)
-{
- snd_azf3328_dbgcallenter();
- WARN_ONCE(period_bytes & 1, "odd period length!?\n");
- WARN_ONCE(buffer_bytes != 2 * period_bytes,
- "missed our input expectations! %u vs. %u\n",
- buffer_bytes, period_bytes);
- if (!codec->running) {
- /* AZF3328 uses a two buffer pointer DMA transfer approach */
-
- unsigned long flags;
-
- /* width 32bit (prevent overflow): */
- u32 area_length;
- struct codec_setup_io {
- u32 dma_start_1;
- u32 dma_start_2;
- u32 dma_lengths;
- } __attribute__((packed)) setup_io;
-
- area_length = buffer_bytes/2;
-
- setup_io.dma_start_1 = addr;
- setup_io.dma_start_2 = addr+area_length;
-
- snd_azf3328_dbgcodec(
- "setdma: buffers %08x[%u] / %08x[%u], %u, %u\n",
- setup_io.dma_start_1, area_length,
- setup_io.dma_start_2, area_length,
- period_bytes, buffer_bytes);
-
- /* Hmm, are we really supposed to decrement this by 1??
- Most definitely certainly not: configuring full length does
- work properly (i.e. likely better), and BTW we
- violated possibly differing frame sizes with this...
-
- area_length--; |* max. index *|
- */
-
- /* build combined I/O buffer length word */
- setup_io.dma_lengths = (area_length << 16) | (area_length);
-
- spin_lock_irqsave(codec->lock, flags);
- snd_azf3328_codec_outl_multi(
- codec, IDX_IO_CODEC_DMA_START_1, &setup_io, 3
- );
- spin_unlock_irqrestore(codec->lock, flags);
- }
- snd_azf3328_dbgcallleave();
-}
-
-static int
-snd_azf3328_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_azf3328_codec_data *codec = runtime->private_data;
-#if 0
- unsigned int size = snd_pcm_lib_buffer_bytes(substream);
- unsigned int count = snd_pcm_lib_period_bytes(substream);
-#endif
-
- snd_azf3328_dbgcallenter();
-
- codec->dma_base = runtime->dma_addr;
-
-#if 0
- snd_azf3328_codec_setfmt(codec,
- runtime->rate,
- snd_pcm_format_width(runtime->format),
- runtime->channels);
- snd_azf3328_codec_setdmaa(codec,
- runtime->dma_addr, count, size);
-#endif
- snd_azf3328_dbgcallleave();
- return 0;
-}
-
-static int
-snd_azf3328_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_azf3328_codec_data *codec = runtime->private_data;
- int result = 0;
- u16 flags1;
- bool previously_muted = 0;
- bool is_main_mixer_playback_codec = (AZF_CODEC_PLAYBACK == codec->type);
-
- snd_azf3328_dbgcalls("snd_azf3328_pcm_trigger cmd %d\n", cmd);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- snd_azf3328_dbgcodec("START %s\n", codec->name);
-
- if (is_main_mixer_playback_codec) {
- /* mute WaveOut (avoid clicking during setup) */
- previously_muted =
- snd_azf3328_mixer_mute_control_pcm(
- chip, 1
- );
- }
-
- snd_azf3328_codec_setfmt(codec,
- runtime->rate,
- snd_pcm_format_width(runtime->format),
- runtime->channels);
-
- spin_lock(codec->lock);
- /* first, remember current value: */
- flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
-
- /* stop transfer */
- flags1 &= ~DMA_RESUME;
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
-
- /* FIXME: clear interrupts or what??? */
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_IRQTYPE, 0xffff);
- spin_unlock(codec->lock);
-
- snd_azf3328_codec_setdmaa(codec, runtime->dma_addr,
- snd_pcm_lib_period_bytes(substream),
- snd_pcm_lib_buffer_bytes(substream)
- );
-
- spin_lock(codec->lock);
-#ifdef WIN9X
- /* FIXME: enable playback/recording??? */
- flags1 |= DMA_RUN_SOMETHING1 | DMA_RUN_SOMETHING2;
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
-
- /* start transfer again */
- /* FIXME: what is this value (0x0010)??? */
- flags1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
-#else /* NT4 */
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
- 0x0000);
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
- DMA_RUN_SOMETHING1);
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
- DMA_RUN_SOMETHING1 |
- DMA_RUN_SOMETHING2);
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
- DMA_RESUME |
- SOMETHING_ALMOST_ALWAYS_SET |
- DMA_EPILOGUE_SOMETHING |
- DMA_SOMETHING_ELSE);
-#endif
- spin_unlock(codec->lock);
- snd_azf3328_ctrl_codec_activity(chip, codec->type, 1);
-
- if (is_main_mixer_playback_codec) {
- /* now unmute WaveOut */
- if (!previously_muted)
- snd_azf3328_mixer_mute_control_pcm(
- chip, 0
- );
- }
-
- snd_azf3328_dbgcodec("STARTED %s\n", codec->name);
- break;
- case SNDRV_PCM_TRIGGER_RESUME:
- snd_azf3328_dbgcodec("RESUME %s\n", codec->name);
- /* resume codec if we were active */
- spin_lock(codec->lock);
- if (codec->running)
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
- snd_azf3328_codec_inw(
- codec, IDX_IO_CODEC_DMA_FLAGS
- ) | DMA_RESUME
- );
- spin_unlock(codec->lock);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- snd_azf3328_dbgcodec("STOP %s\n", codec->name);
-
- if (is_main_mixer_playback_codec) {
- /* mute WaveOut (avoid clicking during setup) */
- previously_muted =
- snd_azf3328_mixer_mute_control_pcm(
- chip, 1
- );
- }
-
- spin_lock(codec->lock);
- /* first, remember current value: */
- flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
-
- /* stop transfer */
- flags1 &= ~DMA_RESUME;
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
-
- /* hmm, is this really required? we're resetting the same bit
- * immediately thereafter... */
- flags1 |= DMA_RUN_SOMETHING1;
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
-
- flags1 &= ~DMA_RUN_SOMETHING1;
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
- spin_unlock(codec->lock);
- snd_azf3328_ctrl_codec_activity(chip, codec->type, 0);
-
- if (is_main_mixer_playback_codec) {
- /* now unmute WaveOut */
- if (!previously_muted)
- snd_azf3328_mixer_mute_control_pcm(
- chip, 0
- );
- }
-
- snd_azf3328_dbgcodec("STOPPED %s\n", codec->name);
- break;
- case SNDRV_PCM_TRIGGER_SUSPEND:
- snd_azf3328_dbgcodec("SUSPEND %s\n", codec->name);
- /* make sure codec is stopped */
- snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
- snd_azf3328_codec_inw(
- codec, IDX_IO_CODEC_DMA_FLAGS
- ) & ~DMA_RESUME
- );
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
- break;
- default:
- snd_printk(KERN_ERR "FIXME: unknown trigger mode!\n");
- return -EINVAL;
- }
-
- snd_azf3328_dbgcallleave();
- return result;
-}
-
-static snd_pcm_uframes_t
-snd_azf3328_pcm_pointer(struct snd_pcm_substream *substream
-)
-{
- const struct snd_azf3328_codec_data *codec =
- substream->runtime->private_data;
- unsigned long result;
- snd_pcm_uframes_t frmres;
-
- result = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_CURRPOS);
-
- /* calculate offset */
-#ifdef QUERY_HARDWARE
- result -= snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1);
-#else
- result -= codec->dma_base;
-#endif
- frmres = bytes_to_frames( substream->runtime, result);
- snd_azf3328_dbgcodec("%08li %s @ 0x%8lx, frames %8ld\n",
- jiffies, codec->name, result, frmres);
- return frmres;
-}
-
-/******************************************************************/
-
-#ifdef SUPPORT_GAMEPORT
-static inline void
-snd_azf3328_gameport_irq_enable(struct snd_azf3328 *chip,
- bool enable
-)
-{
- snd_azf3328_io_reg_setb(
- chip->game_io+IDX_GAME_HWCONFIG,
- GAME_HWCFG_IRQ_ENABLE,
- enable
- );
-}
-
-static inline void
-snd_azf3328_gameport_legacy_address_enable(struct snd_azf3328 *chip,
- bool enable
-)
-{
- snd_azf3328_io_reg_setb(
- chip->game_io+IDX_GAME_HWCONFIG,
- GAME_HWCFG_LEGACY_ADDRESS_ENABLE,
- enable
- );
-}
-
-static void
-snd_azf3328_gameport_set_counter_frequency(struct snd_azf3328 *chip,
- unsigned int freq_cfg
-)
-{
- snd_azf3328_io_reg_setb(
- chip->game_io+IDX_GAME_HWCONFIG,
- 0x02,
- (freq_cfg & 1) != 0
- );
- snd_azf3328_io_reg_setb(
- chip->game_io+IDX_GAME_HWCONFIG,
- 0x04,
- (freq_cfg & 2) != 0
- );
-}
-
-static inline void
-snd_azf3328_gameport_axis_circuit_enable(struct snd_azf3328 *chip, bool enable)
-{
- snd_azf3328_ctrl_reg_6AH_update(
- chip, IO_6A_SOMETHING2_GAMEPORT, enable
- );
-}
-
-static inline void
-snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
-{
- /*
- * skeleton handler only
- * (we do not want axis reading in interrupt handler - too much load!)
- */
- snd_azf3328_dbggame("gameport irq\n");
-
- /* this should ACK the gameport IRQ properly, hopefully. */
- snd_azf3328_game_inw(chip, IDX_GAME_AXIS_VALUE);
-}
-
-static int
-snd_azf3328_gameport_open(struct gameport *gameport, int mode)
-{
- struct snd_azf3328 *chip = gameport_get_port_data(gameport);
- int res;
-
- snd_azf3328_dbggame("gameport_open, mode %d\n", mode);
- switch (mode) {
- case GAMEPORT_MODE_COOKED:
- case GAMEPORT_MODE_RAW:
- res = 0;
- break;
- default:
- res = -1;
- break;
- }
-
- snd_azf3328_gameport_set_counter_frequency(chip,
- GAME_HWCFG_ADC_COUNTER_FREQ_STD);
- snd_azf3328_gameport_axis_circuit_enable(chip, (res == 0));
-
- return res;
-}
-
-static void
-snd_azf3328_gameport_close(struct gameport *gameport)
-{
- struct snd_azf3328 *chip = gameport_get_port_data(gameport);
-
- snd_azf3328_dbggame("gameport_close\n");
- snd_azf3328_gameport_set_counter_frequency(chip,
- GAME_HWCFG_ADC_COUNTER_FREQ_1_200);
- snd_azf3328_gameport_axis_circuit_enable(chip, 0);
-}
-
-static int
-snd_azf3328_gameport_cooked_read(struct gameport *gameport,
- int *axes,
- int *buttons
-)
-{
- struct snd_azf3328 *chip = gameport_get_port_data(gameport);
- int i;
- u8 val;
- unsigned long flags;
-
- if (snd_BUG_ON(!chip))
- return 0;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- val = snd_azf3328_game_inb(chip, IDX_GAME_LEGACY_COMPATIBLE);
- *buttons = (~(val) >> 4) & 0xf;
-
- /* ok, this one is a bit dirty: cooked_read is being polled by a timer,
- * thus we're atomic and cannot actively wait in here
- * (which would be useful for us since it probably would be better
- * to trigger a measurement in here, then wait a short amount of
- * time until it's finished, then read values of _this_ measurement).
- *
- * Thus we simply resort to reading values if they're available already
- * and trigger the next measurement.
- */
-
- val = snd_azf3328_game_inb(chip, IDX_GAME_AXES_CONFIG);
- if (val & GAME_AXES_SAMPLING_READY) {
- for (i = 0; i < ARRAY_SIZE(chip->axes); ++i) {
- /* configure the axis to read */
- val = (i << 4) | 0x0f;
- snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
-
- chip->axes[i] = snd_azf3328_game_inw(
- chip, IDX_GAME_AXIS_VALUE
- );
- }
- }
-
- /* trigger next sampling of axes, to be evaluated the next time we
- * enter this function */
-
- /* for some very, very strange reason we cannot enable
- * Measurement Ready monitoring for all axes here,
- * at least not when only one joystick connected */
- val = 0x03; /* we're able to monitor axes 1 and 2 only */
- snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
-
- snd_azf3328_game_outw(chip, IDX_GAME_AXIS_VALUE, 0xffff);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- for (i = 0; i < ARRAY_SIZE(chip->axes); i++) {
- axes[i] = chip->axes[i];
- if (axes[i] == 0xffff)
- axes[i] = -1;
- }
-
- snd_azf3328_dbggame("cooked_read: axes %d %d %d %d buttons %d\n",
- axes[0], axes[1], axes[2], axes[3], *buttons
- );
-
- return 0;
-}
-
-static int __devinit
-snd_azf3328_gameport(struct snd_azf3328 *chip, int dev)
-{
- struct gameport *gp;
-
- chip->gameport = gp = gameport_allocate_port();
- if (!gp) {
- printk(KERN_ERR "azt3328: cannot alloc memory for gameport\n");
- return -ENOMEM;
- }
-
- gameport_set_name(gp, "AZF3328 Gameport");
- gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
- gameport_set_dev_parent(gp, &chip->pci->dev);
- gp->io = chip->game_io;
- gameport_set_port_data(gp, chip);
-
- gp->open = snd_azf3328_gameport_open;
- gp->close = snd_azf3328_gameport_close;
- gp->fuzz = 16; /* seems ok */
- gp->cooked_read = snd_azf3328_gameport_cooked_read;
-
- /* DISABLE legacy address: we don't need it! */
- snd_azf3328_gameport_legacy_address_enable(chip, 0);
-
- snd_azf3328_gameport_set_counter_frequency(chip,
- GAME_HWCFG_ADC_COUNTER_FREQ_1_200);
- snd_azf3328_gameport_axis_circuit_enable(chip, 0);
-
- gameport_register_port(chip->gameport);
-
- return 0;
-}
-
-static void
-snd_azf3328_gameport_free(struct snd_azf3328 *chip)
-{
- if (chip->gameport) {
- gameport_unregister_port(chip->gameport);
- chip->gameport = NULL;
- }
- snd_azf3328_gameport_irq_enable(chip, 0);
-}
-#else
-static inline int
-snd_azf3328_gameport(struct snd_azf3328 *chip, int dev) { return -ENOSYS; }
-static inline void
-snd_azf3328_gameport_free(struct snd_azf3328 *chip) { }
-static inline void
-snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
-{
- printk(KERN_WARNING "huh, game port IRQ occurred!?\n");
-}
-#endif /* SUPPORT_GAMEPORT */
-
-/******************************************************************/
-
-static inline void
-snd_azf3328_irq_log_unknown_type(u8 which)
-{
- snd_azf3328_dbgcodec(
- "azt3328: unknown IRQ type (%x) occurred, please report!\n",
- which
- );
-}
-
-static inline void
-snd_azf3328_pcm_interrupt(const struct snd_azf3328_codec_data *first_codec,
- u8 status
-)
-{
- u8 which;
- enum snd_azf3328_codec_type codec_type;
- const struct snd_azf3328_codec_data *codec = first_codec;
-
- for (codec_type = AZF_CODEC_PLAYBACK;
- codec_type <= AZF_CODEC_I2S_OUT;
- ++codec_type, ++codec) {
-
- /* skip codec if there's no interrupt for it */
- if (!(status & (1 << codec_type)))
- continue;
-
- spin_lock(codec->lock);
- which = snd_azf3328_codec_inb(codec, IDX_IO_CODEC_IRQTYPE);
- /* ack all IRQ types immediately */
- snd_azf3328_codec_outb(codec, IDX_IO_CODEC_IRQTYPE, which);
- spin_unlock(codec->lock);
-
- if (codec->substream) {
- snd_pcm_period_elapsed(codec->substream);
- snd_azf3328_dbgcodec("%s period done (#%x), @ %x\n",
- codec->name,
- which,
- snd_azf3328_codec_inl(
- codec, IDX_IO_CODEC_DMA_CURRPOS
- )
- );
- } else
- printk(KERN_WARNING "azt3328: irq handler problem!\n");
- if (which & IRQ_SOMETHING)
- snd_azf3328_irq_log_unknown_type(which);
- }
-}
-
-static irqreturn_t
-snd_azf3328_interrupt(int irq, void *dev_id)
-{
- struct snd_azf3328 *chip = dev_id;
- u8 status;
-#if DEBUG_CODEC
- static unsigned long irq_count;
-#endif
-
- status = snd_azf3328_ctrl_inb(chip, IDX_IO_IRQSTATUS);
-
- /* fast path out, to ease interrupt sharing */
- if (!(status &
- (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_I2S_OUT
- |IRQ_GAMEPORT|IRQ_MPU401|IRQ_TIMER)
- ))
- return IRQ_NONE; /* must be interrupt for another device */
-
- snd_azf3328_dbgcodec(
- "irq_count %ld! IDX_IO_IRQSTATUS %04x\n",
- irq_count++ /* debug-only */,
- status
- );
-
- if (status & IRQ_TIMER) {
- /* snd_azf3328_dbgcodec("timer %ld\n",
- snd_azf3328_codec_inl(chip, IDX_IO_TIMER_VALUE)
- & TIMER_VALUE_MASK
- ); */
- if (chip->timer)
- snd_timer_interrupt(chip->timer, chip->timer->sticks);
- /* ACK timer */
- spin_lock(&chip->reg_lock);
- snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x07);
- spin_unlock(&chip->reg_lock);
- snd_azf3328_dbgcodec("azt3328: timer IRQ\n");
- }
-
- if (status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_I2S_OUT))
- snd_azf3328_pcm_interrupt(chip->codecs, status);
-
- if (status & IRQ_GAMEPORT)
- snd_azf3328_gameport_interrupt(chip);
-
- /* MPU401 has less critical IRQ requirements
- * than timer and playback/recording, right? */
- if (status & IRQ_MPU401) {
- snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
-
- /* hmm, do we have to ack the IRQ here somehow?
- * If so, then I don't know how yet... */
- snd_azf3328_dbgcodec("azt3328: MPU401 IRQ\n");
- }
- return IRQ_HANDLED;
-}
-
-/*****************************************************************/
-
-/* as long as we think we have identical snd_pcm_hardware parameters
- for playback, capture and i2s out, we can use the same physical struct
- since the struct is simply being copied into a member.
-*/
-static const struct snd_pcm_hardware snd_azf3328_hardware =
-{
- /* FIXME!! Correct? */
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID,
- .formats = SNDRV_PCM_FMTBIT_S8 |
- SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_U16_LE,
- .rates = SNDRV_PCM_RATE_5512 |
- SNDRV_PCM_RATE_8000_48000 |
- SNDRV_PCM_RATE_KNOT,
- .rate_min = AZF_FREQ_4000,
- .rate_max = AZF_FREQ_66200,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (64*1024),
- .period_bytes_min = 1024,
- .period_bytes_max = (32*1024),
- /* We simply have two DMA areas (instead of a list of descriptors
- such as other cards); I believe that this is a fixed hardware
- attribute and there isn't much driver magic to be done to expand it.
- Thus indicate that we have at least and at most 2 periods. */
- .periods_min = 2,
- .periods_max = 2,
- /* FIXME: maybe that card actually has a FIFO?
- * Hmm, it seems newer revisions do have one, but we still don't know
- * its size... */
- .fifo_size = 0,
-};
-
-
-static unsigned int snd_azf3328_fixed_rates[] = {
- AZF_FREQ_4000,
- AZF_FREQ_4800,
- AZF_FREQ_5512,
- AZF_FREQ_6620,
- AZF_FREQ_8000,
- AZF_FREQ_9600,
- AZF_FREQ_11025,
- AZF_FREQ_13240,
- AZF_FREQ_16000,
- AZF_FREQ_22050,
- AZF_FREQ_32000,
- AZF_FREQ_44100,
- AZF_FREQ_48000,
- AZF_FREQ_66200
-};
-
-static struct snd_pcm_hw_constraint_list snd_azf3328_hw_constraints_rates = {
- .count = ARRAY_SIZE(snd_azf3328_fixed_rates),
- .list = snd_azf3328_fixed_rates,
- .mask = 0,
-};
-
-/*****************************************************************/
-
-static int
-snd_azf3328_pcm_open(struct snd_pcm_substream *substream,
- enum snd_azf3328_codec_type codec_type
-)
-{
- struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
-
- snd_azf3328_dbgcallenter();
- codec->substream = substream;
-
- /* same parameters for all our codecs - at least we think so... */
- runtime->hw = snd_azf3328_hardware;
-
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &snd_azf3328_hw_constraints_rates);
- runtime->private_data = codec;
- snd_azf3328_dbgcallleave();
- return 0;
-}
-
-static int
-snd_azf3328_pcm_playback_open(struct snd_pcm_substream *substream)
-{
- return snd_azf3328_pcm_open(substream, AZF_CODEC_PLAYBACK);
-}
-
-static int
-snd_azf3328_pcm_capture_open(struct snd_pcm_substream *substream)
-{
- return snd_azf3328_pcm_open(substream, AZF_CODEC_CAPTURE);
-}
-
-static int
-snd_azf3328_pcm_i2s_out_open(struct snd_pcm_substream *substream)
-{
- return snd_azf3328_pcm_open(substream, AZF_CODEC_I2S_OUT);
-}
-
-static int
-snd_azf3328_pcm_close(struct snd_pcm_substream *substream
-)
-{
- struct snd_azf3328_codec_data *codec =
- substream->runtime->private_data;
-
- snd_azf3328_dbgcallenter();
- codec->substream = NULL;
- snd_azf3328_dbgcallleave();
- return 0;
-}
-
-/******************************************************************/
-
-static struct snd_pcm_ops snd_azf3328_playback_ops = {
- .open = snd_azf3328_pcm_playback_open,
- .close = snd_azf3328_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_azf3328_hw_params,
- .hw_free = snd_azf3328_hw_free,
- .prepare = snd_azf3328_pcm_prepare,
- .trigger = snd_azf3328_pcm_trigger,
- .pointer = snd_azf3328_pcm_pointer
-};
-
-static struct snd_pcm_ops snd_azf3328_capture_ops = {
- .open = snd_azf3328_pcm_capture_open,
- .close = snd_azf3328_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_azf3328_hw_params,
- .hw_free = snd_azf3328_hw_free,
- .prepare = snd_azf3328_pcm_prepare,
- .trigger = snd_azf3328_pcm_trigger,
- .pointer = snd_azf3328_pcm_pointer
-};
-
-static struct snd_pcm_ops snd_azf3328_i2s_out_ops = {
- .open = snd_azf3328_pcm_i2s_out_open,
- .close = snd_azf3328_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_azf3328_hw_params,
- .hw_free = snd_azf3328_hw_free,
- .prepare = snd_azf3328_pcm_prepare,
- .trigger = snd_azf3328_pcm_trigger,
- .pointer = snd_azf3328_pcm_pointer
-};
-
-static int __devinit
-snd_azf3328_pcm(struct snd_azf3328 *chip)
-{
-enum { AZF_PCMDEV_STD, AZF_PCMDEV_I2S_OUT, NUM_AZF_PCMDEVS }; /* pcm devices */
-
- struct snd_pcm *pcm;
- int err;
-
- snd_azf3328_dbgcallenter();
-
- err = snd_pcm_new(chip->card, "AZF3328 DSP", AZF_PCMDEV_STD,
- 1, 1, &pcm);
- if (err < 0)
- return err;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_azf3328_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_azf3328_capture_ops);
-
- pcm->private_data = chip;
- pcm->info_flags = 0;
- strcpy(pcm->name, chip->card->shortname);
- /* same pcm object for playback/capture (see snd_pcm_new() above) */
- chip->pcm[AZF_CODEC_PLAYBACK] = pcm;
- chip->pcm[AZF_CODEC_CAPTURE] = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- 64*1024, 64*1024);
-
- err = snd_pcm_new(chip->card, "AZF3328 I2S OUT", AZF_PCMDEV_I2S_OUT,
- 1, 0, &pcm);
- if (err < 0)
- return err;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_azf3328_i2s_out_ops);
-
- pcm->private_data = chip;
- pcm->info_flags = 0;
- strcpy(pcm->name, chip->card->shortname);
- chip->pcm[AZF_CODEC_I2S_OUT] = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- 64*1024, 64*1024);
-
- snd_azf3328_dbgcallleave();
- return 0;
-}
-
-/******************************************************************/
-
-/*** NOTE: the physical timer resolution actually is 1024000 ticks per second
- *** (probably derived from main crystal via a divider of 24),
- *** but announcing those attributes to user-space would make programs
- *** configure the timer to a 1 tick value, resulting in an absolutely fatal
- *** timer IRQ storm.
- *** Thus I chose to announce a down-scaled virtual timer to the outside and
- *** calculate real timer countdown values internally.
- *** (the scale factor can be set via module parameter "seqtimer_scaling").
- ***/
-
-static int
-snd_azf3328_timer_start(struct snd_timer *timer)
-{
- struct snd_azf3328 *chip;
- unsigned long flags;
- unsigned int delay;
-
- snd_azf3328_dbgcallenter();
- chip = snd_timer_chip(timer);
- delay = ((timer->sticks * seqtimer_scaling) - 1) & TIMER_VALUE_MASK;
- if (delay < 49) {
- /* uhoh, that's not good, since user-space won't know about
- * this timing tweak
- * (we need to do it to avoid a lockup, though) */
-
- snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay);
- delay = 49; /* minimum time is 49 ticks */
- }
- snd_azf3328_dbgtimer("setting timer countdown value %d\n", delay);
- delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE;
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_azf3328_ctrl_outl(chip, IDX_IO_TIMER_VALUE, delay);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- snd_azf3328_dbgcallleave();
- return 0;
-}
-
-static int
-snd_azf3328_timer_stop(struct snd_timer *timer)
-{
- struct snd_azf3328 *chip;
- unsigned long flags;
-
- snd_azf3328_dbgcallenter();
- chip = snd_timer_chip(timer);
- spin_lock_irqsave(&chip->reg_lock, flags);
- /* disable timer countdown and interrupt */
- /* Hmm, should we write TIMER_IRQ_ACK here?
- YES indeed, otherwise a rogue timer operation - which prompts
- ALSA(?) to call repeated stop() in vain, but NOT start() -
- will never end (value 0x03 is kept shown in control byte).
- Simply manually poking 0x04 _once_ immediately successfully stops
- the hardware/ALSA interrupt activity. */
- snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x04);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- snd_azf3328_dbgcallleave();
- return 0;
-}
-
-
-static int
-snd_azf3328_timer_precise_resolution(struct snd_timer *timer,
- unsigned long *num, unsigned long *den)
-{
- snd_azf3328_dbgcallenter();
- *num = 1;
- *den = 1024000 / seqtimer_scaling;
- snd_azf3328_dbgcallleave();
- return 0;
-}
-
-static struct snd_timer_hardware snd_azf3328_timer_hw = {
- .flags = SNDRV_TIMER_HW_AUTO,
- .resolution = 977, /* 1000000/1024000 = 0.9765625us */
- .ticks = 1024000, /* max tick count, defined by the value register; actually it's not 1024000, but 1048576, but we don't care */
- .start = snd_azf3328_timer_start,
- .stop = snd_azf3328_timer_stop,
- .precise_resolution = snd_azf3328_timer_precise_resolution,
-};
-
-static int __devinit
-snd_azf3328_timer(struct snd_azf3328 *chip, int device)
-{
- struct snd_timer *timer = NULL;
- struct snd_timer_id tid;
- int err;
-
- snd_azf3328_dbgcallenter();
- tid.dev_class = SNDRV_TIMER_CLASS_CARD;
- tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
- tid.card = chip->card->number;
- tid.device = device;
- tid.subdevice = 0;
-
- snd_azf3328_timer_hw.resolution *= seqtimer_scaling;
- snd_azf3328_timer_hw.ticks /= seqtimer_scaling;
-
- err = snd_timer_new(chip->card, "AZF3328", &tid, &timer);
- if (err < 0)
- goto out;
-
- strcpy(timer->name, "AZF3328 timer");
- timer->private_data = chip;
- timer->hw = snd_azf3328_timer_hw;
-
- chip->timer = timer;
-
- snd_azf3328_timer_stop(timer);
-
- err = 0;
-
-out:
- snd_azf3328_dbgcallleave();
- return err;
-}
-
-/******************************************************************/
-
-static int
-snd_azf3328_free(struct snd_azf3328 *chip)
-{
- if (chip->irq < 0)
- goto __end_hw;
-
- snd_azf3328_mixer_reset(chip);
-
- snd_azf3328_timer_stop(chip->timer);
- snd_azf3328_gameport_free(chip);
-
- if (chip->irq >= 0)
- synchronize_irq(chip->irq);
-__end_hw:
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
-
- kfree(chip);
- return 0;
-}
-
-static int
-snd_azf3328_dev_free(struct snd_device *device)
-{
- struct snd_azf3328 *chip = device->device_data;
- return snd_azf3328_free(chip);
-}
-
-#if 0
-/* check whether a bit can be modified */
-static void
-snd_azf3328_test_bit(unsigned unsigned reg, int bit)
-{
- unsigned char val, valoff, valon;
-
- val = inb(reg);
-
- outb(val & ~(1 << bit), reg);
- valoff = inb(reg);
-
- outb(val|(1 << bit), reg);
- valon = inb(reg);
-
- outb(val, reg);
-
- printk(KERN_DEBUG "reg %04x bit %d: %02x %02x %02x\n",
- reg, bit, val, valoff, valon
- );
-}
-#endif
-
-static inline void
-snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
-{
-#if DEBUG_MISC
- u16 tmp;
-
- snd_azf3328_dbgmisc(
- "ctrl_io 0x%lx, game_io 0x%lx, mpu_io 0x%lx, "
- "opl3_io 0x%lx, mixer_io 0x%lx, irq %d\n",
- chip->ctrl_io, chip->game_io, chip->mpu_io,
- chip->opl3_io, chip->mixer_io, chip->irq
- );
-
- snd_azf3328_dbgmisc("game %02x %02x %02x %02x %02x %02x\n",
- snd_azf3328_game_inb(chip, 0),
- snd_azf3328_game_inb(chip, 1),
- snd_azf3328_game_inb(chip, 2),
- snd_azf3328_game_inb(chip, 3),
- snd_azf3328_game_inb(chip, 4),
- snd_azf3328_game_inb(chip, 5)
- );
-
- for (tmp = 0; tmp < 0x07; tmp += 1)
- snd_azf3328_dbgmisc("mpu_io 0x%04x\n", inb(chip->mpu_io + tmp));
-
- for (tmp = 0; tmp <= 0x07; tmp += 1)
- snd_azf3328_dbgmisc("0x%02x: game200 0x%04x, game208 0x%04x\n",
- tmp, inb(0x200 + tmp), inb(0x208 + tmp));
-
- for (tmp = 0; tmp <= 0x01; tmp += 1)
- snd_azf3328_dbgmisc(
- "0x%02x: mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, "
- "mpu330 0x%04x opl388 0x%04x opl38c 0x%04x\n",
- tmp,
- inb(0x300 + tmp),
- inb(0x310 + tmp),
- inb(0x320 + tmp),
- inb(0x330 + tmp),
- inb(0x388 + tmp),
- inb(0x38c + tmp)
- );
-
- for (tmp = 0; tmp < AZF_IO_SIZE_CTRL; tmp += 2)
- snd_azf3328_dbgmisc("ctrl 0x%02x: 0x%04x\n",
- tmp, snd_azf3328_ctrl_inw(chip, tmp)
- );
-
- for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2)
- snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n",
- tmp, snd_azf3328_mixer_inw(chip, tmp)
- );
-#endif /* DEBUG_MISC */
-}
-
-static int __devinit
-snd_azf3328_create(struct snd_card *card,
- struct pci_dev *pci,
- unsigned long device_type,
- struct snd_azf3328 **rchip)
-{
- struct snd_azf3328 *chip;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_azf3328_dev_free,
- };
- u8 dma_init;
- enum snd_azf3328_codec_type codec_type;
- struct snd_azf3328_codec_data *codec_setup;
-
- *rchip = NULL;
-
- err = pci_enable_device(pci);
- if (err < 0)
- return err;
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- err = -ENOMEM;
- goto out_err;
- }
- spin_lock_init(&chip->reg_lock);
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
-
- /* check if we can restrict PCI DMA transfers to 24 bits */
- if (pci_set_dma_mask(pci, DMA_BIT_MASK(24)) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(24)) < 0) {
- snd_printk(KERN_ERR "architecture does not support "
- "24bit PCI busmaster DMA\n"
- );
- err = -ENXIO;
- goto out_err;
- }
-
- err = pci_request_regions(pci, "Aztech AZF3328");
- if (err < 0)
- goto out_err;
-
- chip->ctrl_io = pci_resource_start(pci, 0);
- chip->game_io = pci_resource_start(pci, 1);
- chip->mpu_io = pci_resource_start(pci, 2);
- chip->opl3_io = pci_resource_start(pci, 3);
- chip->mixer_io = pci_resource_start(pci, 4);
-
- codec_setup = &chip->codecs[AZF_CODEC_PLAYBACK];
- codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK;
- codec_setup->lock = &chip->reg_lock;
- codec_setup->type = AZF_CODEC_PLAYBACK;
- codec_setup->name = "PLAYBACK";
-
- codec_setup = &chip->codecs[AZF_CODEC_CAPTURE];
- codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE;
- codec_setup->lock = &chip->reg_lock;
- codec_setup->type = AZF_CODEC_CAPTURE;
- codec_setup->name = "CAPTURE";
-
- codec_setup = &chip->codecs[AZF_CODEC_I2S_OUT];
- codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT;
- codec_setup->lock = &chip->reg_lock;
- codec_setup->type = AZF_CODEC_I2S_OUT;
- codec_setup->name = "I2S_OUT";
-
- if (request_irq(pci->irq, snd_azf3328_interrupt,
- IRQF_SHARED, KBUILD_MODNAME, chip)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- err = -EBUSY;
- goto out_err;
- }
- chip->irq = pci->irq;
- pci_set_master(pci);
- synchronize_irq(chip->irq);
-
- snd_azf3328_debug_show_ports(chip);
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
- if (err < 0)
- goto out_err;
-
- /* create mixer interface & switches */
- err = snd_azf3328_mixer_new(chip);
- if (err < 0)
- goto out_err;
-
- /* standard codec init stuff */
- /* default DMA init value */
- dma_init = DMA_RUN_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE;
-
- for (codec_type = AZF_CODEC_PLAYBACK;
- codec_type <= AZF_CODEC_I2S_OUT; ++codec_type) {
- struct snd_azf3328_codec_data *codec =
- &chip->codecs[codec_type];
-
- /* shutdown codecs to reduce power / noise */
- /* have ...ctrl_codec_activity() act properly */
- codec->running = 1;
- snd_azf3328_ctrl_codec_activity(chip, codec_type, 0);
-
- spin_lock_irq(codec->lock);
- snd_azf3328_codec_outb(codec, IDX_IO_CODEC_DMA_FLAGS,
- dma_init);
- spin_unlock_irq(codec->lock);
- }
-
- snd_card_set_dev(card, &pci->dev);
-
- *rchip = chip;
-
- err = 0;
- goto out;
-
-out_err:
- if (chip)
- snd_azf3328_free(chip);
- pci_disable_device(pci);
-
-out:
- return err;
-}
-
-static int __devinit
-snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct snd_azf3328 *chip;
- struct snd_opl3 *opl3;
- int err;
-
- snd_azf3328_dbgcallenter();
- if (dev >= SNDRV_CARDS) {
- err = -ENODEV;
- goto out;
- }
- if (!enable[dev]) {
- dev++;
- err = -ENOENT;
- goto out;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- goto out;
-
- strcpy(card->driver, "AZF3328");
- strcpy(card->shortname, "Aztech AZF3328 (PCI168)");
-
- err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip);
- if (err < 0)
- goto out_err;
-
- card->private_data = chip;
-
- /* chose to use MPU401_HW_AZT2320 ID instead of MPU401_HW_MPU401,
- since our hardware ought to be similar, thus use same ID. */
- err = snd_mpu401_uart_new(
- card, 0,
- MPU401_HW_AZT2320, chip->mpu_io,
- MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK,
- -1, &chip->rmidi
- );
- if (err < 0) {
- snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n",
- chip->mpu_io
- );
- goto out_err;
- }
-
- err = snd_azf3328_timer(chip, 0);
- if (err < 0)
- goto out_err;
-
- err = snd_azf3328_pcm(chip);
- if (err < 0)
- goto out_err;
-
- if (snd_opl3_create(card, chip->opl3_io, chip->opl3_io+2,
- OPL3_HW_AUTO, 1, &opl3) < 0) {
- snd_printk(KERN_ERR "azf3328: no OPL3 device at 0x%lx-0x%lx?\n",
- chip->opl3_io, chip->opl3_io+2
- );
- } else {
- /* need to use IDs 1, 2 since ID 0 is snd_azf3328_timer above */
- err = snd_opl3_timer_new(opl3, 1, 2);
- if (err < 0)
- goto out_err;
- err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
- if (err < 0)
- goto out_err;
- opl3->private_data = chip;
- }
-
- sprintf(card->longname, "%s at 0x%lx, irq %i",
- card->shortname, chip->ctrl_io, chip->irq);
-
- err = snd_card_register(card);
- if (err < 0)
- goto out_err;
-
-#ifdef MODULE
- printk(KERN_INFO
-"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n"
-"azt3328: Hardware was completely undocumented, unfortunately.\n"
-"azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n"
-"azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n",
- 1024000 / seqtimer_scaling, seqtimer_scaling);
-#endif
-
- snd_azf3328_gameport(chip, dev);
-
- pci_set_drvdata(pci, card);
- dev++;
-
- err = 0;
- goto out;
-
-out_err:
- snd_printk(KERN_ERR "azf3328: something failed, exiting\n");
- snd_card_free(card);
-
-out:
- snd_azf3328_dbgcallleave();
- return err;
-}
-
-static void __devexit
-snd_azf3328_remove(struct pci_dev *pci)
-{
- snd_azf3328_dbgcallenter();
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
- snd_azf3328_dbgcallleave();
-}
-
-#ifdef CONFIG_PM
-static inline void
-snd_azf3328_suspend_regs(unsigned long io_addr, unsigned count, u32 *saved_regs)
-{
- unsigned reg;
-
- for (reg = 0; reg < count; ++reg) {
- *saved_regs = inl(io_addr);
- snd_azf3328_dbgpm("suspend: io 0x%04lx: 0x%08x\n",
- io_addr, *saved_regs);
- ++saved_regs;
- io_addr += sizeof(*saved_regs);
- }
-}
-
-static inline void
-snd_azf3328_resume_regs(const u32 *saved_regs,
- unsigned long io_addr,
- unsigned count
-)
-{
- unsigned reg;
-
- for (reg = 0; reg < count; ++reg) {
- outl(*saved_regs, io_addr);
- snd_azf3328_dbgpm("resume: io 0x%04lx: 0x%08x --> 0x%08x\n",
- io_addr, *saved_regs, inl(io_addr));
- ++saved_regs;
- io_addr += sizeof(*saved_regs);
- }
-}
-
-static inline void
-snd_azf3328_suspend_ac97(struct snd_azf3328 *chip)
-{
-#ifdef AZF_USE_AC97_LAYER
- snd_ac97_suspend(chip->ac97);
-#else
- snd_azf3328_suspend_regs(chip->mixer_io,
- ARRAY_SIZE(chip->saved_regs_mixer), chip->saved_regs_mixer);
-
- /* make sure to disable master volume etc. to prevent looping sound */
- snd_azf3328_mixer_mute_control_master(chip, 1);
- snd_azf3328_mixer_mute_control_pcm(chip, 1);
-#endif /* AZF_USE_AC97_LAYER */
-}
-
-static inline void
-snd_azf3328_resume_ac97(const struct snd_azf3328 *chip)
-{
-#ifdef AZF_USE_AC97_LAYER
- snd_ac97_resume(chip->ac97);
-#else
- snd_azf3328_resume_regs(chip->saved_regs_mixer, chip->mixer_io,
- ARRAY_SIZE(chip->saved_regs_mixer));
-
- /* unfortunately with 32bit transfers, IDX_MIXER_PLAY_MASTER (0x02)
- and IDX_MIXER_RESET (offset 0x00) get touched at the same time,
- resulting in a mixer reset condition persisting until _after_
- master vol was restored. Thus master vol needs an extra restore. */
- outw(((u16 *)chip->saved_regs_mixer)[1], chip->mixer_io + 2);
-#endif /* AZF_USE_AC97_LAYER */
-}
-
-static int
-snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_azf3328 *chip = card->private_data;
- u16 *saved_regs_ctrl_u16;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-
- /* same pcm object for playback/capture */
- snd_pcm_suspend_all(chip->pcm[AZF_CODEC_PLAYBACK]);
- snd_pcm_suspend_all(chip->pcm[AZF_CODEC_I2S_OUT]);
-
- snd_azf3328_suspend_ac97(chip);
-
- snd_azf3328_suspend_regs(chip->ctrl_io,
- ARRAY_SIZE(chip->saved_regs_ctrl), chip->saved_regs_ctrl);
-
- /* manually store the one currently relevant write-only reg, too */
- saved_regs_ctrl_u16 = (u16 *)chip->saved_regs_ctrl;
- saved_regs_ctrl_u16[IDX_IO_6AH / 2] = chip->shadow_reg_ctrl_6AH;
-
- snd_azf3328_suspend_regs(chip->game_io,
- ARRAY_SIZE(chip->saved_regs_game), chip->saved_regs_game);
- snd_azf3328_suspend_regs(chip->mpu_io,
- ARRAY_SIZE(chip->saved_regs_mpu), chip->saved_regs_mpu);
- snd_azf3328_suspend_regs(chip->opl3_io,
- ARRAY_SIZE(chip->saved_regs_opl3), chip->saved_regs_opl3);
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int
-snd_azf3328_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- const struct snd_azf3328 *chip = card->private_data;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "azt3328: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
-
- snd_azf3328_resume_regs(chip->saved_regs_game, chip->game_io,
- ARRAY_SIZE(chip->saved_regs_game));
- snd_azf3328_resume_regs(chip->saved_regs_mpu, chip->mpu_io,
- ARRAY_SIZE(chip->saved_regs_mpu));
- snd_azf3328_resume_regs(chip->saved_regs_opl3, chip->opl3_io,
- ARRAY_SIZE(chip->saved_regs_opl3));
-
- snd_azf3328_resume_ac97(chip);
-
- snd_azf3328_resume_regs(chip->saved_regs_ctrl, chip->ctrl_io,
- ARRAY_SIZE(chip->saved_regs_ctrl));
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif /* CONFIG_PM */
-
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_azf3328_ids,
- .probe = snd_azf3328_probe,
- .remove = __devexit_p(snd_azf3328_remove),
-#ifdef CONFIG_PM
- .suspend = snd_azf3328_suspend,
- .resume = snd_azf3328_resume,
-#endif
-};
-
-static int __init
-alsa_card_azf3328_init(void)
-{
- int err;
- snd_azf3328_dbgcallenter();
- err = pci_register_driver(&driver);
- snd_azf3328_dbgcallleave();
- return err;
-}
-
-static void __exit
-alsa_card_azf3328_exit(void)
-{
- snd_azf3328_dbgcallenter();
- pci_unregister_driver(&driver);
- snd_azf3328_dbgcallleave();
-}
-
-module_init(alsa_card_azf3328_init)
-module_exit(alsa_card_azf3328_exit)
diff --git a/ANDROID_3.4.5/sound/pci/azt3328.h b/ANDROID_3.4.5/sound/pci/azt3328.h
deleted file mode 100644
index 6f46b976..00000000
--- a/ANDROID_3.4.5/sound/pci/azt3328.h
+++ /dev/null
@@ -1,342 +0,0 @@
-#ifndef __SOUND_AZT3328_H
-#define __SOUND_AZT3328_H
-
-/* "PU" == "power-up value", as tested on PCI168 PCI rev. 10
- * "WRITE_ONLY" == register does not indicate actual bit values */
-
-/*** main I/O area port indices ***/
-/* (only 0x70 of 0x80 bytes saved/restored by Windows driver) */
-#define AZF_IO_SIZE_CTRL 0x80
-#define AZF_IO_SIZE_CTRL_PM 0x70
-
-/* the driver initialisation suggests a layout of 4 areas
- * within the main card control I/O:
- * from 0x00 (playback codec), from 0x20 (recording codec)
- * and from 0x40 (most certainly I2S out codec).
- * And another area from 0x60 to 0x6f (DirectX timer, IRQ management,
- * power management etc.???). */
-
-#define AZF_IO_OFFS_CODEC_PLAYBACK 0x00
-#define AZF_IO_OFFS_CODEC_CAPTURE 0x20
-#define AZF_IO_OFFS_CODEC_I2S_OUT 0x40
-
-#define IDX_IO_CODEC_DMA_FLAGS 0x00 /* PU:0x0000 */
- /* able to reactivate output after output muting due to 8/16bit
- * output change, just like 0x0002.
- * 0x0001 is the only bit that's able to start the DMA counter */
- #define DMA_RESUME 0x0001 /* paused if cleared? */
- /* 0x0002 *temporarily* set during DMA stopping. hmm
- * both 0x0002 and 0x0004 set in playback setup. */
- /* able to reactivate output after output muting due to 8/16bit
- * output change, just like 0x0001. */
- #define DMA_RUN_SOMETHING1 0x0002 /* \ alternated (toggled) */
- /* 0x0004: NOT able to reactivate output */
- #define DMA_RUN_SOMETHING2 0x0004 /* / bits */
- #define SOMETHING_ALMOST_ALWAYS_SET 0x0008 /* ???; can be modified */
- #define DMA_EPILOGUE_SOMETHING 0x0010
- #define DMA_SOMETHING_ELSE 0x0020 /* ??? */
- #define SOMETHING_UNMODIFIABLE 0xffc0 /* unused? not modifiable */
-#define IDX_IO_CODEC_IRQTYPE 0x02 /* PU:0x0001 */
- /* write back to flags in case flags are set, in order to ACK IRQ in handler
- * (bit 1 of port 0x64 indicates interrupt for one of these three types)
- * sometimes in this case it just writes 0xffff to globally ACK all IRQs
- * settings written are not reflected when reading back, though.
- * seems to be IRQ, too (frequently used: port |= 0x07 !), but who knows? */
- #define IRQ_SOMETHING 0x0001 /* something & ACK */
- #define IRQ_FINISHED_DMABUF_1 0x0002 /* 1st dmabuf finished & ACK */
- #define IRQ_FINISHED_DMABUF_2 0x0004 /* 2nd dmabuf finished & ACK */
- #define IRQMASK_SOME_STATUS_1 0x0008 /* \ related bits */
- #define IRQMASK_SOME_STATUS_2 0x0010 /* / (checked together in loop) */
- #define IRQMASK_UNMODIFIABLE 0xffe0 /* unused? not modifiable */
- /* start address of 1st DMA transfer area, PU:0x00000000 */
-#define IDX_IO_CODEC_DMA_START_1 0x04
- /* start address of 2nd DMA transfer area, PU:0x00000000 */
-#define IDX_IO_CODEC_DMA_START_2 0x08
- /* both lengths of DMA transfer areas, PU:0x00000000
- length1: offset 0x0c, length2: offset 0x0e */
-#define IDX_IO_CODEC_DMA_LENGTHS 0x0c
-#define IDX_IO_CODEC_DMA_CURRPOS 0x10 /* current DMA position, PU:0x00000000 */
- /* offset within current DMA transfer area, PU:0x0000 */
-#define IDX_IO_CODEC_DMA_CURROFS 0x14
-#define IDX_IO_CODEC_SOUNDFORMAT 0x16 /* PU:0x0010 */
- /* all unspecified bits can't be modified */
- #define SOUNDFORMAT_FREQUENCY_MASK 0x000f
- #define SOUNDFORMAT_XTAL1 0x00
- #define SOUNDFORMAT_XTAL2 0x01
- /* all _SUSPECTED_ values are not used by Windows drivers, so we don't
- * have any hard facts, only rough measurements.
- * All we know is that the crystal used on the board has 24.576MHz,
- * like many soundcards (which results in the frequencies below when
- * using certain divider values selected by the values below) */
- #define SOUNDFORMAT_FREQ_SUSPECTED_4000 0x0c | SOUNDFORMAT_XTAL1
- #define SOUNDFORMAT_FREQ_SUSPECTED_4800 0x0a | SOUNDFORMAT_XTAL1
- #define SOUNDFORMAT_FREQ_5510 0x0c | SOUNDFORMAT_XTAL2
- #define SOUNDFORMAT_FREQ_6620 0x0a | SOUNDFORMAT_XTAL2
- #define SOUNDFORMAT_FREQ_8000 0x00 | SOUNDFORMAT_XTAL1 /* also 0x0e | SOUNDFORMAT_XTAL1? */
- #define SOUNDFORMAT_FREQ_9600 0x08 | SOUNDFORMAT_XTAL1
- #define SOUNDFORMAT_FREQ_11025 0x00 | SOUNDFORMAT_XTAL2 /* also 0x0e | SOUNDFORMAT_XTAL2? */
- #define SOUNDFORMAT_FREQ_SUSPECTED_13240 0x08 | SOUNDFORMAT_XTAL2 /* seems to be 6620 *2 */
- #define SOUNDFORMAT_FREQ_16000 0x02 | SOUNDFORMAT_XTAL1
- #define SOUNDFORMAT_FREQ_22050 0x02 | SOUNDFORMAT_XTAL2
- #define SOUNDFORMAT_FREQ_32000 0x04 | SOUNDFORMAT_XTAL1
- #define SOUNDFORMAT_FREQ_44100 0x04 | SOUNDFORMAT_XTAL2
- #define SOUNDFORMAT_FREQ_48000 0x06 | SOUNDFORMAT_XTAL1
- #define SOUNDFORMAT_FREQ_SUSPECTED_66200 0x06 | SOUNDFORMAT_XTAL2 /* 66200 (13240 * 5); 64000 may have been nicer :-\ */
- #define SOUNDFORMAT_FLAG_16BIT 0x0010
- #define SOUNDFORMAT_FLAG_2CHANNELS 0x0020
-
-
-/* define frequency helpers, for maximum value safety */
-enum azf_freq_t {
-#define AZF_FREQ(rate) AZF_FREQ_##rate = rate
- AZF_FREQ(4000),
- AZF_FREQ(4800),
- AZF_FREQ(5512),
- AZF_FREQ(6620),
- AZF_FREQ(8000),
- AZF_FREQ(9600),
- AZF_FREQ(11025),
- AZF_FREQ(13240),
- AZF_FREQ(16000),
- AZF_FREQ(22050),
- AZF_FREQ(32000),
- AZF_FREQ(44100),
- AZF_FREQ(48000),
- AZF_FREQ(66200),
-#undef AZF_FREQ
-};
-
-/** DirectX timer, main interrupt area (FIXME: and something else?) **/
-#define IDX_IO_TIMER_VALUE 0x60 /* found this timer area by pure luck :-) */
- /* timer countdown value; triggers IRQ when timer is finished */
- #define TIMER_VALUE_MASK 0x000fffffUL
- /* activate timer countdown */
- #define TIMER_COUNTDOWN_ENABLE 0x01000000UL
- /* trigger timer IRQ on zero transition */
- #define TIMER_IRQ_ENABLE 0x02000000UL
- /* being set in IRQ handler in case port 0x00 (hmm, not port 0x64!?!?)
- * had 0x0020 set upon IRQ handler */
- #define TIMER_IRQ_ACK 0x04000000UL
-#define IDX_IO_IRQSTATUS 0x64
- /* some IRQ bit in here might also be used to signal a power-management timer
- * timeout, to request shutdown of the chip (e.g. AD1815JS has such a thing).
- * OPL3 hardware contains several timers which confusingly in most cases
- * are NOT routed to an IRQ, but some designs (e.g. LM4560) DO support that,
- * so I wouldn't be surprised at all to discover that AZF3328
- * supports that thing as well... */
-
- #define IRQ_PLAYBACK 0x0001
- #define IRQ_RECORDING 0x0002
- #define IRQ_I2S_OUT 0x0004 /* this IS I2S, right!? (untested) */
- #define IRQ_GAMEPORT 0x0008 /* Interrupt of Digital(ly) Enhanced Game Port */
- #define IRQ_MPU401 0x0010
- #define IRQ_TIMER 0x0020 /* DirectX timer */
- #define IRQ_UNKNOWN2 0x0040 /* probably unused, or possibly OPL3 timer? */
- #define IRQ_UNKNOWN3 0x0080 /* probably unused, or possibly OPL3 timer? */
-#define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */
- /* this is set to e.g. 0x3ff or 0x300, and writable;
- * maybe some buffer limit, but I couldn't find out more, PU:0x00ff: */
-#define IDX_IO_SOME_VALUE 0x68
- #define IO_68_RANDOM_TOGGLE1 0x0100 /* toggles randomly */
- #define IO_68_RANDOM_TOGGLE2 0x0200 /* toggles randomly */
- /* umm, nope, behaviour of these bits changes depending on what we wrote
- * to 0x6b!!
- * And they change upon playback/stop, too:
- * Writing a value to 0x68 will display this exact value during playback,
- * too but when stopped it can fall back to a rather different
- * seemingly random value). Hmm, possibly this is a register which
- * has a remote shadow which needs proper device supply which only exists
- * in case playback is active? Or is this driver-induced?
- */
-
-/* this WORD can be set to have bits 0x0028 activated (FIXME: correct??);
- * actually inhibits PCM playback!!! maybe power management??: */
-#define IDX_IO_6AH 0x6A /* WRITE_ONLY! */
- /* bit 5: enabling this will activate permanent counting of bytes 2/3
- * at gameport I/O (0xb402/3) (equal values each) and cause
- * gameport legacy I/O at 0x0200 to be _DISABLED_!
- * Is this Digital Enhanced Game Port Enable??? Or maybe it's Testmode
- * for Enhanced Digital Gameport (see 4D Wave DX card): */
- #define IO_6A_SOMETHING1_GAMEPORT 0x0020
- /* bit 8; sure, this _pauses_ playback (later resumes at same spot!),
- * but what the heck is this really about??: */
- #define IO_6A_PAUSE_PLAYBACK_BIT8 0x0100
- /* bit 9; sure, this _pauses_ playback (later resumes at same spot!),
- * but what the heck is this really about??: */
- #define IO_6A_PAUSE_PLAYBACK_BIT9 0x0200
- /* BIT8 and BIT9 are _NOT_ able to affect OPL3 MIDI playback,
- * thus it suggests influence on PCM only!!
- * However OTOH there seems to be no bit anywhere around here
- * which is able to disable OPL3... */
- /* bit 10: enabling this actually changes values at legacy gameport
- * I/O address (0x200); is this enabling of the Digital Enhanced Game Port???
- * Or maybe this simply switches off the NE558 circuit, since enabling this
- * still lets us evaluate button states, but not axis states */
- #define IO_6A_SOMETHING2_GAMEPORT 0x0400
- /* writing 0x0300: causes quite some crackling during
- * PC activity such as switching windows (PCI traffic??
- * --> FIFO/timing settings???) */
- /* writing 0x0100 plus/or 0x0200 inhibits playback */
- /* since the Windows .INF file has Flag_Enable_JoyStick and
- * Flag_Enable_SB_DOS_Emulation directly together, it stands to reason
- * that some other bit in this same register might be responsible
- * for SB DOS Emulation activation (note that the file did NOT define
- * a switch for OPL3!) */
-#define IDX_IO_6CH 0x6C /* unknown; fully read-writable */
-#define IDX_IO_6EH 0x6E
- /* writing 0xffff returns 0x83fe (or 0x03fe only).
- * writing 0x83 (and only 0x83!!) to 0x6f will cause 0x6c to switch
- * from 0000 to ffff. */
-
-/* further I/O indices not saved/restored and not readable after writing,
- * so probably not used */
-
-
-/*** Gameport area port indices ***/
-/* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */
-#define AZF_IO_SIZE_GAME 0x08
-#define AZF_IO_SIZE_GAME_PM 0x06
-
-enum {
- AZF_GAME_LEGACY_IO_PORT = 0x200
-};
-
-#define IDX_GAME_LEGACY_COMPATIBLE 0x00
- /* in some operation mode, writing anything to this port
- * triggers an interrupt:
- * yup, that's in case IDX_GAME_01H has one of the
- * axis measurement bits enabled
- * (and of course one needs to have GAME_HWCFG_IRQ_ENABLE, too) */
-
-#define IDX_GAME_AXES_CONFIG 0x01
- /* NOTE: layout of this register awfully similar (read: "identical??")
- * to AD1815JS.pdf (p.29) */
-
- /* enables axis 1 (X axis) measurement: */
- #define GAME_AXES_ENABLE_1 0x01
- /* enables axis 2 (Y axis) measurement: */
- #define GAME_AXES_ENABLE_2 0x02
- /* enables axis 3 (X axis) measurement: */
- #define GAME_AXES_ENABLE_3 0x04
- /* enables axis 4 (Y axis) measurement: */
- #define GAME_AXES_ENABLE_4 0x08
- /* selects the current axis to read the measured value of
- * (at IDX_GAME_AXIS_VALUE):
- * 00 = axis 1, 01 = axis 2, 10 = axis 3, 11 = axis 4: */
- #define GAME_AXES_READ_MASK 0x30
- /* enable to have the latch continuously accept ADC values
- * (and continuously cause interrupts in case interrupts are enabled);
- * AD1815JS.pdf says it's ~16ms interval there: */
- #define GAME_AXES_LATCH_ENABLE 0x40
- /* joystick data (measured axes) ready for reading: */
- #define GAME_AXES_SAMPLING_READY 0x80
-
- /* NOTE: other card specs (SiS960 and others!) state that the
- * game position latches should be frozen when reading and be freed
- * (== reset?) after reading!!!
- * Freezing most likely means disabling 0x40 (GAME_AXES_LATCH_ENABLE),
- * but how to free the value? */
- /* An internet search for "gameport latch ADC" should provide some insight
- * into how to program such a gameport system. */
-
- /* writing 0xf0 to 01H once reset both counters to 0, in some special mode!?
- * yup, in case 6AH 0x20 is not enabled
- * (and 0x40 is sufficient, 0xf0 is not needed) */
-
-#define IDX_GAME_AXIS_VALUE 0x02
- /* R: value of currently configured axis (word value!);
- * W: trigger axis measurement */
-
-#define IDX_GAME_HWCONFIG 0x04
- /* note: bits 4 to 7 are never set (== 0) when reading!
- * --> reserved bits? */
- /* enables IRQ notification upon axes measurement ready: */
- #define GAME_HWCFG_IRQ_ENABLE 0x01
- /* these bits choose a different frequency for the
- * internal ADC counter increment.
- * hmm, seems to be a combo of bits:
- * 00 --> standard frequency
- * 10 --> 1/2
- * 01 --> 1/20
- * 11 --> 1/200: */
- #define GAME_HWCFG_ADC_COUNTER_FREQ_MASK 0x06
-
- /* FIXME: these values might be reversed... */
- #define GAME_HWCFG_ADC_COUNTER_FREQ_STD 0
- #define GAME_HWCFG_ADC_COUNTER_FREQ_1_2 1
- #define GAME_HWCFG_ADC_COUNTER_FREQ_1_20 2
- #define GAME_HWCFG_ADC_COUNTER_FREQ_1_200 3
-
- /* enable gameport legacy I/O address (0x200)
- * I was unable to locate any configurability for a different address: */
- #define GAME_HWCFG_LEGACY_ADDRESS_ENABLE 0x08
-
-/*** MPU401 ***/
-#define AZF_IO_SIZE_MPU 0x04
-#define AZF_IO_SIZE_MPU_PM 0x04
-
-/*** OPL3 synth ***/
-/* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */
-#define AZF_IO_SIZE_OPL3 0x08
-#define AZF_IO_SIZE_OPL3_PM 0x06
-/* hmm, given that a standard OPL3 has 4 registers only,
- * there might be some enhanced functionality lurking at the end
- * (especially since register 0x04 has a "non-empty" value 0xfe) */
-
-/*** mixer I/O area port indices ***/
-/* (only 0x22 of 0x40 bytes saved/restored by Windows driver)
- * UNFORTUNATELY azf3328 is NOT truly AC97 compliant: see main file intro */
-#define AZF_IO_SIZE_MIXER 0x40
-#define AZF_IO_SIZE_MIXER_PM 0x22
-
- #define MIXER_VOLUME_RIGHT_MASK 0x001f
- #define MIXER_VOLUME_LEFT_MASK 0x1f00
- #define MIXER_MUTE_MASK 0x8000
-#define IDX_MIXER_RESET 0x00 /* does NOT seem to have AC97 ID bits */
-#define IDX_MIXER_PLAY_MASTER 0x02
-#define IDX_MIXER_MODEMOUT 0x04
-#define IDX_MIXER_BASSTREBLE 0x06
- #define MIXER_BASSTREBLE_TREBLE_VOLUME_MASK 0x000e
- #define MIXER_BASSTREBLE_BASS_VOLUME_MASK 0x0e00
-#define IDX_MIXER_PCBEEP 0x08
-#define IDX_MIXER_MODEMIN 0x0a
-#define IDX_MIXER_MIC 0x0c
- #define MIXER_MIC_MICGAIN_20DB_ENHANCEMENT_MASK 0x0040
-#define IDX_MIXER_LINEIN 0x0e
-#define IDX_MIXER_CDAUDIO 0x10
-#define IDX_MIXER_VIDEO 0x12
-#define IDX_MIXER_AUX 0x14
-#define IDX_MIXER_WAVEOUT 0x16
-#define IDX_MIXER_FMSYNTH 0x18
-#define IDX_MIXER_REC_SELECT 0x1a
- #define MIXER_REC_SELECT_MIC 0x00
- #define MIXER_REC_SELECT_CD 0x01
- #define MIXER_REC_SELECT_VIDEO 0x02
- #define MIXER_REC_SELECT_AUX 0x03
- #define MIXER_REC_SELECT_LINEIN 0x04
- #define MIXER_REC_SELECT_MIXSTEREO 0x05
- #define MIXER_REC_SELECT_MIXMONO 0x06
- #define MIXER_REC_SELECT_MONOIN 0x07
-#define IDX_MIXER_REC_VOLUME 0x1c
-#define IDX_MIXER_ADVCTL1 0x1e
- /* unlisted bits are unmodifiable */
- #define MIXER_ADVCTL1_3DWIDTH_MASK 0x000e
- #define MIXER_ADVCTL1_HIFI3D_MASK 0x0300 /* yup, this is missing the high bit that official AC97 contains, plus it doesn't have linear bit value range behaviour but instead acts weirdly (possibly we're dealing with two *different* 3D settings here??) */
-#define IDX_MIXER_ADVCTL2 0x20 /* subset of AC97_GENERAL_PURPOSE reg! */
- /* unlisted bits are unmodifiable */
- #define MIXER_ADVCTL2_LPBK 0x0080 /* Loopback mode -- Win driver: "WaveOut3DBypass"? mutes WaveOut at LineOut */
- #define MIXER_ADVCTL2_MS 0x0100 /* Mic Select 0=Mic1, 1=Mic2 -- Win driver: "ModemOutSelect"?? */
- #define MIXER_ADVCTL2_MIX 0x0200 /* Mono output select 0=Mix, 1=Mic; Win driver: "MonoSelectSource"?? */
- #define MIXER_ADVCTL2_3D 0x2000 /* 3D Enhancement 1=on */
- #define MIXER_ADVCTL2_POP 0x8000 /* Pcm Out Path, 0=pre 3D, 1=post 3D */
-
-#define IDX_MIXER_SOMETHING30H 0x30 /* used, but unknown??? */
-
-/* driver internal flags */
-#define SET_CHAN_LEFT 1
-#define SET_CHAN_RIGHT 2
-
-/* helper macro to align I/O port ranges to 32bit I/O width */
-#define AZF_ALIGN(x) (((x) + 3) & (~3))
-
-#endif /* __SOUND_AZT3328_H */
diff --git a/ANDROID_3.4.5/sound/pci/bt87x.c b/ANDROID_3.4.5/sound/pci/bt87x.c
deleted file mode 100644
index 62d6163f..00000000
--- a/ANDROID_3.4.5/sound/pci/bt87x.c
+++ /dev/null
@@ -1,987 +0,0 @@
-/*
- * bt87x.c - Brooktree Bt878/Bt879 driver for ALSA
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- *
- * based on btaudio.c by Gerd Knorr <kraxel@bytesex.org>
- *
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/bitops.h>
-#include <asm/io.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/control.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
-MODULE_DESCRIPTION("Brooktree Bt87x audio driver");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Brooktree,Bt878},"
- "{Brooktree,Bt879}}");
-
-static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int digital_rate[SNDRV_CARDS]; /* digital input rate */
-static bool load_all; /* allow to load the non-whitelisted cards */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Bt87x soundcard");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Bt87x soundcard");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Bt87x soundcard");
-module_param_array(digital_rate, int, NULL, 0444);
-MODULE_PARM_DESC(digital_rate, "Digital input rate for Bt87x soundcard");
-module_param(load_all, bool, 0444);
-MODULE_PARM_DESC(load_all, "Allow to load the non-whitelisted cards");
-
-
-/* register offsets */
-#define REG_INT_STAT 0x100 /* interrupt status */
-#define REG_INT_MASK 0x104 /* interrupt mask */
-#define REG_GPIO_DMA_CTL 0x10c /* audio control */
-#define REG_PACKET_LEN 0x110 /* audio packet lengths */
-#define REG_RISC_STRT_ADD 0x114 /* RISC program start address */
-#define REG_RISC_COUNT 0x120 /* RISC program counter */
-
-/* interrupt bits */
-#define INT_OFLOW (1 << 3) /* audio A/D overflow */
-#define INT_RISCI (1 << 11) /* RISC instruction IRQ bit set */
-#define INT_FBUS (1 << 12) /* FIFO overrun due to bus access latency */
-#define INT_FTRGT (1 << 13) /* FIFO overrun due to target latency */
-#define INT_FDSR (1 << 14) /* FIFO data stream resynchronization */
-#define INT_PPERR (1 << 15) /* PCI parity error */
-#define INT_RIPERR (1 << 16) /* RISC instruction parity error */
-#define INT_PABORT (1 << 17) /* PCI master or target abort */
-#define INT_OCERR (1 << 18) /* invalid opcode */
-#define INT_SCERR (1 << 19) /* sync counter overflow */
-#define INT_RISC_EN (1 << 27) /* DMA controller running */
-#define INT_RISCS_SHIFT 28 /* RISC status bits */
-
-/* audio control bits */
-#define CTL_FIFO_ENABLE (1 << 0) /* enable audio data FIFO */
-#define CTL_RISC_ENABLE (1 << 1) /* enable audio DMA controller */
-#define CTL_PKTP_4 (0 << 2) /* packet mode FIFO trigger point - 4 DWORDs */
-#define CTL_PKTP_8 (1 << 2) /* 8 DWORDs */
-#define CTL_PKTP_16 (2 << 2) /* 16 DWORDs */
-#define CTL_ACAP_EN (1 << 4) /* enable audio capture */
-#define CTL_DA_APP (1 << 5) /* GPIO input */
-#define CTL_DA_IOM_AFE (0 << 6) /* audio A/D input */
-#define CTL_DA_IOM_DA (1 << 6) /* digital audio input */
-#define CTL_DA_SDR_SHIFT 8 /* DDF first stage decimation rate */
-#define CTL_DA_SDR_MASK (0xf<< 8)
-#define CTL_DA_LMT (1 << 12) /* limit audio data values */
-#define CTL_DA_ES2 (1 << 13) /* enable DDF stage 2 */
-#define CTL_DA_SBR (1 << 14) /* samples rounded to 8 bits */
-#define CTL_DA_DPM (1 << 15) /* data packet mode */
-#define CTL_DA_LRD_SHIFT 16 /* ALRCK delay */
-#define CTL_DA_MLB (1 << 21) /* MSB/LSB format */
-#define CTL_DA_LRI (1 << 22) /* left/right indication */
-#define CTL_DA_SCE (1 << 23) /* sample clock edge */
-#define CTL_A_SEL_STV (0 << 24) /* TV tuner audio input */
-#define CTL_A_SEL_SFM (1 << 24) /* FM audio input */
-#define CTL_A_SEL_SML (2 << 24) /* mic/line audio input */
-#define CTL_A_SEL_SMXC (3 << 24) /* MUX bypass */
-#define CTL_A_SEL_SHIFT 24
-#define CTL_A_SEL_MASK (3 << 24)
-#define CTL_A_PWRDN (1 << 26) /* analog audio power-down */
-#define CTL_A_G2X (1 << 27) /* audio gain boost */
-#define CTL_A_GAIN_SHIFT 28 /* audio input gain */
-#define CTL_A_GAIN_MASK (0xf<<28)
-
-/* RISC instruction opcodes */
-#define RISC_WRITE (0x1 << 28) /* write FIFO data to memory at address */
-#define RISC_WRITEC (0x5 << 28) /* write FIFO data to memory at current address */
-#define RISC_SKIP (0x2 << 28) /* skip FIFO data */
-#define RISC_JUMP (0x7 << 28) /* jump to address */
-#define RISC_SYNC (0x8 << 28) /* synchronize with FIFO */
-
-/* RISC instruction bits */
-#define RISC_BYTES_ENABLE (0xf << 12) /* byte enable bits */
-#define RISC_RESYNC ( 1 << 15) /* disable FDSR errors */
-#define RISC_SET_STATUS_SHIFT 16 /* set status bits */
-#define RISC_RESET_STATUS_SHIFT 20 /* clear status bits */
-#define RISC_IRQ ( 1 << 24) /* interrupt */
-#define RISC_EOL ( 1 << 26) /* end of line */
-#define RISC_SOL ( 1 << 27) /* start of line */
-
-/* SYNC status bits values */
-#define RISC_SYNC_FM1 0x6
-#define RISC_SYNC_VRO 0xc
-
-#define ANALOG_CLOCK 1792000
-#ifdef CONFIG_SND_BT87X_OVERCLOCK
-#define CLOCK_DIV_MIN 1
-#else
-#define CLOCK_DIV_MIN 4
-#endif
-#define CLOCK_DIV_MAX 15
-
-#define ERROR_INTERRUPTS (INT_FBUS | INT_FTRGT | INT_PPERR | \
- INT_RIPERR | INT_PABORT | INT_OCERR)
-#define MY_INTERRUPTS (INT_RISCI | ERROR_INTERRUPTS)
-
-/* SYNC, one WRITE per line, one extra WRITE per page boundary, SYNC, JUMP */
-#define MAX_RISC_SIZE ((1 + 255 + (PAGE_ALIGN(255 * 4092) / PAGE_SIZE - 1) + 1 + 1) * 8)
-
-/* Cards with configuration information */
-enum snd_bt87x_boardid {
- SND_BT87X_BOARD_UNKNOWN,
- SND_BT87X_BOARD_GENERIC, /* both an & dig interfaces, 32kHz */
- SND_BT87X_BOARD_ANALOG, /* board with no external A/D */
- SND_BT87X_BOARD_OSPREY2x0,
- SND_BT87X_BOARD_OSPREY440,
- SND_BT87X_BOARD_AVPHONE98,
-};
-
-/* Card configuration */
-struct snd_bt87x_board {
- int dig_rate; /* Digital input sampling rate */
- u32 digital_fmt; /* Register settings for digital input */
- unsigned no_analog:1; /* No analog input */
- unsigned no_digital:1; /* No digital input */
-};
-
-static __devinitdata struct snd_bt87x_board snd_bt87x_boards[] = {
- [SND_BT87X_BOARD_UNKNOWN] = {
- .dig_rate = 32000, /* just a guess */
- },
- [SND_BT87X_BOARD_GENERIC] = {
- .dig_rate = 32000,
- },
- [SND_BT87X_BOARD_ANALOG] = {
- .no_digital = 1,
- },
- [SND_BT87X_BOARD_OSPREY2x0] = {
- .dig_rate = 44100,
- .digital_fmt = CTL_DA_LRI | (1 << CTL_DA_LRD_SHIFT),
- },
- [SND_BT87X_BOARD_OSPREY440] = {
- .dig_rate = 32000,
- .digital_fmt = CTL_DA_LRI | (1 << CTL_DA_LRD_SHIFT),
- .no_analog = 1,
- },
- [SND_BT87X_BOARD_AVPHONE98] = {
- .dig_rate = 48000,
- },
-};
-
-struct snd_bt87x {
- struct snd_card *card;
- struct pci_dev *pci;
- struct snd_bt87x_board board;
-
- void __iomem *mmio;
- int irq;
-
- spinlock_t reg_lock;
- unsigned long opened;
- struct snd_pcm_substream *substream;
-
- struct snd_dma_buffer dma_risc;
- unsigned int line_bytes;
- unsigned int lines;
-
- u32 reg_control;
- u32 interrupt_mask;
-
- int current_line;
-
- int pci_parity_errors;
-};
-
-enum { DEVICE_DIGITAL, DEVICE_ANALOG };
-
-static inline u32 snd_bt87x_readl(struct snd_bt87x *chip, u32 reg)
-{
- return readl(chip->mmio + reg);
-}
-
-static inline void snd_bt87x_writel(struct snd_bt87x *chip, u32 reg, u32 value)
-{
- writel(value, chip->mmio + reg);
-}
-
-static int snd_bt87x_create_risc(struct snd_bt87x *chip, struct snd_pcm_substream *substream,
- unsigned int periods, unsigned int period_bytes)
-{
- unsigned int i, offset;
- u32 *risc;
-
- if (chip->dma_risc.area == NULL) {
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
- PAGE_ALIGN(MAX_RISC_SIZE), &chip->dma_risc) < 0)
- return -ENOMEM;
- }
- risc = (u32 *)chip->dma_risc.area;
- offset = 0;
- *risc++ = cpu_to_le32(RISC_SYNC | RISC_SYNC_FM1);
- *risc++ = cpu_to_le32(0);
- for (i = 0; i < periods; ++i) {
- u32 rest;
-
- rest = period_bytes;
- do {
- u32 cmd, len;
- unsigned int addr;
-
- len = PAGE_SIZE - (offset % PAGE_SIZE);
- if (len > rest)
- len = rest;
- cmd = RISC_WRITE | len;
- if (rest == period_bytes) {
- u32 block = i * 16 / periods;
- cmd |= RISC_SOL;
- cmd |= block << RISC_SET_STATUS_SHIFT;
- cmd |= (~block & 0xf) << RISC_RESET_STATUS_SHIFT;
- }
- if (len == rest)
- cmd |= RISC_EOL | RISC_IRQ;
- *risc++ = cpu_to_le32(cmd);
- addr = snd_pcm_sgbuf_get_addr(substream, offset);
- *risc++ = cpu_to_le32(addr);
- offset += len;
- rest -= len;
- } while (rest > 0);
- }
- *risc++ = cpu_to_le32(RISC_SYNC | RISC_SYNC_VRO);
- *risc++ = cpu_to_le32(0);
- *risc++ = cpu_to_le32(RISC_JUMP);
- *risc++ = cpu_to_le32(chip->dma_risc.addr);
- chip->line_bytes = period_bytes;
- chip->lines = periods;
- return 0;
-}
-
-static void snd_bt87x_free_risc(struct snd_bt87x *chip)
-{
- if (chip->dma_risc.area) {
- snd_dma_free_pages(&chip->dma_risc);
- chip->dma_risc.area = NULL;
- }
-}
-
-static void snd_bt87x_pci_error(struct snd_bt87x *chip, unsigned int status)
-{
- u16 pci_status;
-
- pci_read_config_word(chip->pci, PCI_STATUS, &pci_status);
- pci_status &= PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT |
- PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT |
- PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY;
- pci_write_config_word(chip->pci, PCI_STATUS, pci_status);
- if (pci_status != PCI_STATUS_DETECTED_PARITY)
- snd_printk(KERN_ERR "Aieee - PCI error! status %#08x, PCI status %#04x\n",
- status & ERROR_INTERRUPTS, pci_status);
- else {
- snd_printk(KERN_ERR "Aieee - PCI parity error detected!\n");
- /* error 'handling' similar to aic7xxx_pci.c: */
- chip->pci_parity_errors++;
- if (chip->pci_parity_errors > 20) {
- snd_printk(KERN_ERR "Too many PCI parity errors observed.\n");
- snd_printk(KERN_ERR "Some device on this bus is generating bad parity.\n");
- snd_printk(KERN_ERR "This is an error *observed by*, not *generated by*, this card.\n");
- snd_printk(KERN_ERR "PCI parity error checking has been disabled.\n");
- chip->interrupt_mask &= ~(INT_PPERR | INT_RIPERR);
- snd_bt87x_writel(chip, REG_INT_MASK, chip->interrupt_mask);
- }
- }
-}
-
-static irqreturn_t snd_bt87x_interrupt(int irq, void *dev_id)
-{
- struct snd_bt87x *chip = dev_id;
- unsigned int status, irq_status;
-
- status = snd_bt87x_readl(chip, REG_INT_STAT);
- irq_status = status & chip->interrupt_mask;
- if (!irq_status)
- return IRQ_NONE;
- snd_bt87x_writel(chip, REG_INT_STAT, irq_status);
-
- if (irq_status & ERROR_INTERRUPTS) {
- if (irq_status & (INT_FBUS | INT_FTRGT))
- snd_printk(KERN_WARNING "FIFO overrun, status %#08x\n", status);
- if (irq_status & INT_OCERR)
- snd_printk(KERN_ERR "internal RISC error, status %#08x\n", status);
- if (irq_status & (INT_PPERR | INT_RIPERR | INT_PABORT))
- snd_bt87x_pci_error(chip, irq_status);
- }
- if ((irq_status & INT_RISCI) && (chip->reg_control & CTL_ACAP_EN)) {
- int current_block, irq_block;
-
- /* assume that exactly one line has been recorded */
- chip->current_line = (chip->current_line + 1) % chip->lines;
- /* but check if some interrupts have been skipped */
- current_block = chip->current_line * 16 / chip->lines;
- irq_block = status >> INT_RISCS_SHIFT;
- if (current_block != irq_block)
- chip->current_line = (irq_block * chip->lines + 15) / 16;
-
- snd_pcm_period_elapsed(chip->substream);
- }
- return IRQ_HANDLED;
-}
-
-static struct snd_pcm_hardware snd_bt87x_digital_hw = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BATCH,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = 0, /* set at runtime */
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 255 * 4092,
- .period_bytes_min = 32,
- .period_bytes_max = 4092,
- .periods_min = 2,
- .periods_max = 255,
-};
-
-static struct snd_pcm_hardware snd_bt87x_analog_hw = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BATCH,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8,
- .rates = SNDRV_PCM_RATE_KNOT,
- .rate_min = ANALOG_CLOCK / CLOCK_DIV_MAX,
- .rate_max = ANALOG_CLOCK / CLOCK_DIV_MIN,
- .channels_min = 1,
- .channels_max = 1,
- .buffer_bytes_max = 255 * 4092,
- .period_bytes_min = 32,
- .period_bytes_max = 4092,
- .periods_min = 2,
- .periods_max = 255,
-};
-
-static int snd_bt87x_set_digital_hw(struct snd_bt87x *chip, struct snd_pcm_runtime *runtime)
-{
- chip->reg_control |= CTL_DA_IOM_DA | CTL_A_PWRDN;
- runtime->hw = snd_bt87x_digital_hw;
- runtime->hw.rates = snd_pcm_rate_to_rate_bit(chip->board.dig_rate);
- runtime->hw.rate_min = chip->board.dig_rate;
- runtime->hw.rate_max = chip->board.dig_rate;
- return 0;
-}
-
-static int snd_bt87x_set_analog_hw(struct snd_bt87x *chip, struct snd_pcm_runtime *runtime)
-{
- static struct snd_ratnum analog_clock = {
- .num = ANALOG_CLOCK,
- .den_min = CLOCK_DIV_MIN,
- .den_max = CLOCK_DIV_MAX,
- .den_step = 1
- };
- static struct snd_pcm_hw_constraint_ratnums constraint_rates = {
- .nrats = 1,
- .rats = &analog_clock
- };
-
- chip->reg_control &= ~(CTL_DA_IOM_DA | CTL_A_PWRDN);
- runtime->hw = snd_bt87x_analog_hw;
- return snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &constraint_rates);
-}
-
-static int snd_bt87x_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_bt87x *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- if (test_and_set_bit(0, &chip->opened))
- return -EBUSY;
-
- if (substream->pcm->device == DEVICE_DIGITAL)
- err = snd_bt87x_set_digital_hw(chip, runtime);
- else
- err = snd_bt87x_set_analog_hw(chip, runtime);
- if (err < 0)
- goto _error;
-
- err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0)
- goto _error;
-
- chip->substream = substream;
- return 0;
-
-_error:
- clear_bit(0, &chip->opened);
- smp_mb__after_clear_bit();
- return err;
-}
-
-static int snd_bt87x_close(struct snd_pcm_substream *substream)
-{
- struct snd_bt87x *chip = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&chip->reg_lock);
- chip->reg_control |= CTL_A_PWRDN;
- snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
- spin_unlock_irq(&chip->reg_lock);
-
- chip->substream = NULL;
- clear_bit(0, &chip->opened);
- smp_mb__after_clear_bit();
- return 0;
-}
-
-static int snd_bt87x_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_bt87x *chip = snd_pcm_substream_chip(substream);
- int err;
-
- err = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
- return snd_bt87x_create_risc(chip, substream,
- params_periods(hw_params),
- params_period_bytes(hw_params));
-}
-
-static int snd_bt87x_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_bt87x *chip = snd_pcm_substream_chip(substream);
-
- snd_bt87x_free_risc(chip);
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-static int snd_bt87x_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_bt87x *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int decimation;
-
- spin_lock_irq(&chip->reg_lock);
- chip->reg_control &= ~(CTL_DA_SDR_MASK | CTL_DA_SBR);
- decimation = (ANALOG_CLOCK + runtime->rate / 4) / runtime->rate;
- chip->reg_control |= decimation << CTL_DA_SDR_SHIFT;
- if (runtime->format == SNDRV_PCM_FORMAT_S8)
- chip->reg_control |= CTL_DA_SBR;
- snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static int snd_bt87x_start(struct snd_bt87x *chip)
-{
- spin_lock(&chip->reg_lock);
- chip->current_line = 0;
- chip->reg_control |= CTL_FIFO_ENABLE | CTL_RISC_ENABLE | CTL_ACAP_EN;
- snd_bt87x_writel(chip, REG_RISC_STRT_ADD, chip->dma_risc.addr);
- snd_bt87x_writel(chip, REG_PACKET_LEN,
- chip->line_bytes | (chip->lines << 16));
- snd_bt87x_writel(chip, REG_INT_MASK, chip->interrupt_mask);
- snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
- spin_unlock(&chip->reg_lock);
- return 0;
-}
-
-static int snd_bt87x_stop(struct snd_bt87x *chip)
-{
- spin_lock(&chip->reg_lock);
- chip->reg_control &= ~(CTL_FIFO_ENABLE | CTL_RISC_ENABLE | CTL_ACAP_EN);
- snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
- snd_bt87x_writel(chip, REG_INT_MASK, 0);
- snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
- spin_unlock(&chip->reg_lock);
- return 0;
-}
-
-static int snd_bt87x_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_bt87x *chip = snd_pcm_substream_chip(substream);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- return snd_bt87x_start(chip);
- case SNDRV_PCM_TRIGGER_STOP:
- return snd_bt87x_stop(chip);
- default:
- return -EINVAL;
- }
-}
-
-static snd_pcm_uframes_t snd_bt87x_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_bt87x *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- return (snd_pcm_uframes_t)bytes_to_frames(runtime, chip->current_line * chip->line_bytes);
-}
-
-static struct snd_pcm_ops snd_bt87x_pcm_ops = {
- .open = snd_bt87x_pcm_open,
- .close = snd_bt87x_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_bt87x_hw_params,
- .hw_free = snd_bt87x_hw_free,
- .prepare = snd_bt87x_prepare,
- .trigger = snd_bt87x_trigger,
- .pointer = snd_bt87x_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
-static int snd_bt87x_capture_volume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *info)
-{
- info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- info->count = 1;
- info->value.integer.min = 0;
- info->value.integer.max = 15;
- return 0;
-}
-
-static int snd_bt87x_capture_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- struct snd_bt87x *chip = snd_kcontrol_chip(kcontrol);
-
- value->value.integer.value[0] = (chip->reg_control & CTL_A_GAIN_MASK) >> CTL_A_GAIN_SHIFT;
- return 0;
-}
-
-static int snd_bt87x_capture_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- struct snd_bt87x *chip = snd_kcontrol_chip(kcontrol);
- u32 old_control;
- int changed;
-
- spin_lock_irq(&chip->reg_lock);
- old_control = chip->reg_control;
- chip->reg_control = (chip->reg_control & ~CTL_A_GAIN_MASK)
- | (value->value.integer.value[0] << CTL_A_GAIN_SHIFT);
- snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
- changed = old_control != chip->reg_control;
- spin_unlock_irq(&chip->reg_lock);
- return changed;
-}
-
-static struct snd_kcontrol_new snd_bt87x_capture_volume = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Volume",
- .info = snd_bt87x_capture_volume_info,
- .get = snd_bt87x_capture_volume_get,
- .put = snd_bt87x_capture_volume_put,
-};
-
-#define snd_bt87x_capture_boost_info snd_ctl_boolean_mono_info
-
-static int snd_bt87x_capture_boost_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- struct snd_bt87x *chip = snd_kcontrol_chip(kcontrol);
-
- value->value.integer.value[0] = !! (chip->reg_control & CTL_A_G2X);
- return 0;
-}
-
-static int snd_bt87x_capture_boost_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- struct snd_bt87x *chip = snd_kcontrol_chip(kcontrol);
- u32 old_control;
- int changed;
-
- spin_lock_irq(&chip->reg_lock);
- old_control = chip->reg_control;
- chip->reg_control = (chip->reg_control & ~CTL_A_G2X)
- | (value->value.integer.value[0] ? CTL_A_G2X : 0);
- snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
- changed = chip->reg_control != old_control;
- spin_unlock_irq(&chip->reg_lock);
- return changed;
-}
-
-static struct snd_kcontrol_new snd_bt87x_capture_boost = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Boost",
- .info = snd_bt87x_capture_boost_info,
- .get = snd_bt87x_capture_boost_get,
- .put = snd_bt87x_capture_boost_put,
-};
-
-static int snd_bt87x_capture_source_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *info)
-{
- static const char *const texts[3] = {"TV Tuner", "FM", "Mic/Line"};
-
- return snd_ctl_enum_info(info, 1, 3, texts);
-}
-
-static int snd_bt87x_capture_source_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- struct snd_bt87x *chip = snd_kcontrol_chip(kcontrol);
-
- value->value.enumerated.item[0] = (chip->reg_control & CTL_A_SEL_MASK) >> CTL_A_SEL_SHIFT;
- return 0;
-}
-
-static int snd_bt87x_capture_source_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- struct snd_bt87x *chip = snd_kcontrol_chip(kcontrol);
- u32 old_control;
- int changed;
-
- spin_lock_irq(&chip->reg_lock);
- old_control = chip->reg_control;
- chip->reg_control = (chip->reg_control & ~CTL_A_SEL_MASK)
- | (value->value.enumerated.item[0] << CTL_A_SEL_SHIFT);
- snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
- changed = chip->reg_control != old_control;
- spin_unlock_irq(&chip->reg_lock);
- return changed;
-}
-
-static struct snd_kcontrol_new snd_bt87x_capture_source = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = snd_bt87x_capture_source_info,
- .get = snd_bt87x_capture_source_get,
- .put = snd_bt87x_capture_source_put,
-};
-
-static int snd_bt87x_free(struct snd_bt87x *chip)
-{
- if (chip->mmio)
- snd_bt87x_stop(chip);
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
- if (chip->mmio)
- iounmap(chip->mmio);
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
- kfree(chip);
- return 0;
-}
-
-static int snd_bt87x_dev_free(struct snd_device *device)
-{
- struct snd_bt87x *chip = device->device_data;
- return snd_bt87x_free(chip);
-}
-
-static int __devinit snd_bt87x_pcm(struct snd_bt87x *chip, int device, char *name)
-{
- int err;
- struct snd_pcm *pcm;
-
- err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
- if (err < 0)
- return err;
- pcm->private_data = chip;
- strcpy(pcm->name, name);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_bt87x_pcm_ops);
- return snd_pcm_lib_preallocate_pages_for_all(pcm,
- SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(chip->pci),
- 128 * 1024,
- ALIGN(255 * 4092, 1024));
-}
-
-static int __devinit snd_bt87x_create(struct snd_card *card,
- struct pci_dev *pci,
- struct snd_bt87x **rchip)
-{
- struct snd_bt87x *chip;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_bt87x_dev_free
- };
-
- *rchip = NULL;
-
- err = pci_enable_device(pci);
- if (err < 0)
- return err;
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (!chip) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
- spin_lock_init(&chip->reg_lock);
-
- if ((err = pci_request_regions(pci, "Bt87x audio")) < 0) {
- kfree(chip);
- pci_disable_device(pci);
- return err;
- }
- chip->mmio = pci_ioremap_bar(pci, 0);
- if (!chip->mmio) {
- snd_printk(KERN_ERR "cannot remap io memory\n");
- err = -ENOMEM;
- goto fail;
- }
-
- chip->reg_control = CTL_A_PWRDN | CTL_DA_ES2 |
- CTL_PKTP_16 | (15 << CTL_DA_SDR_SHIFT);
- chip->interrupt_mask = MY_INTERRUPTS;
- snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
- snd_bt87x_writel(chip, REG_INT_MASK, 0);
- snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
-
- err = request_irq(pci->irq, snd_bt87x_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, chip);
- if (err < 0) {
- snd_printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
- goto fail;
- }
- chip->irq = pci->irq;
- pci_set_master(pci);
- synchronize_irq(chip->irq);
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
- if (err < 0)
- goto fail;
-
- snd_card_set_dev(card, &pci->dev);
- *rchip = chip;
- return 0;
-
-fail:
- snd_bt87x_free(chip);
- return err;
-}
-
-#define BT_DEVICE(chip, subvend, subdev, id) \
- { .vendor = PCI_VENDOR_ID_BROOKTREE, \
- .device = chip, \
- .subvendor = subvend, .subdevice = subdev, \
- .driver_data = SND_BT87X_BOARD_ ## id }
-/* driver_data is the card id for that device */
-
-static DEFINE_PCI_DEVICE_TABLE(snd_bt87x_ids) = {
- /* Hauppauge WinTV series */
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, GENERIC),
- /* Hauppauge WinTV series */
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, GENERIC),
- /* Viewcast Osprey 200 */
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, OSPREY2x0),
- /* Viewcast Osprey 440 (rate is configurable via gpio) */
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff07, OSPREY440),
- /* ATI TV-Wonder */
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, GENERIC),
- /* Leadtek Winfast tv 2000xp delux */
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, GENERIC),
- /* Pinnacle PCTV */
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x11bd, 0x0012, GENERIC),
- /* Voodoo TV 200 */
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x121a, 0x3000, GENERIC),
- /* Askey Computer Corp. MagicTView'99 */
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x144f, 0x3000, GENERIC),
- /* AVerMedia Studio No. 103, 203, ...? */
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, AVPHONE98),
- /* Prolink PixelView PV-M4900 */
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1554, 0x4011, GENERIC),
- /* Pinnacle Studio PCTV rave */
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0xbd11, 0x1200, GENERIC),
- { }
-};
-MODULE_DEVICE_TABLE(pci, snd_bt87x_ids);
-
-/* cards known not to have audio
- * (DVB cards use the audio function to transfer MPEG data) */
-static struct {
- unsigned short subvendor, subdevice;
-} blacklist[] __devinitdata = {
- {0x0071, 0x0101}, /* Nebula Electronics DigiTV */
- {0x11bd, 0x001c}, /* Pinnacle PCTV Sat */
- {0x11bd, 0x0026}, /* Pinnacle PCTV SAT CI */
- {0x1461, 0x0761}, /* AVermedia AverTV DVB-T */
- {0x1461, 0x0771}, /* AVermedia DVB-T 771 */
- {0x1822, 0x0001}, /* Twinhan VisionPlus DVB-T */
- {0x18ac, 0xd500}, /* DVICO FusionHDTV 5 Lite */
- {0x18ac, 0xdb10}, /* DVICO FusionHDTV DVB-T Lite */
- {0x18ac, 0xdb11}, /* Ultraview DVB-T Lite */
- {0x270f, 0xfc00}, /* Chaintech Digitop DST-1000 DVB-S */
- {0x7063, 0x2000}, /* pcHDTV HD-2000 TV */
-};
-
-static struct pci_driver driver;
-
-/* return the id of the card, or a negative value if it's blacklisted */
-static int __devinit snd_bt87x_detect_card(struct pci_dev *pci)
-{
- int i;
- const struct pci_device_id *supported;
-
- supported = pci_match_id(snd_bt87x_ids, pci);
- if (supported && supported->driver_data > 0)
- return supported->driver_data;
-
- for (i = 0; i < ARRAY_SIZE(blacklist); ++i)
- if (blacklist[i].subvendor == pci->subsystem_vendor &&
- blacklist[i].subdevice == pci->subsystem_device) {
- snd_printdd(KERN_INFO "card %#04x-%#04x:%#04x has no audio\n",
- pci->device, pci->subsystem_vendor, pci->subsystem_device);
- return -EBUSY;
- }
-
- snd_printk(KERN_INFO "unknown card %#04x-%#04x:%#04x\n",
- pci->device, pci->subsystem_vendor, pci->subsystem_device);
- snd_printk(KERN_DEBUG "please mail id, board name, and, "
- "if it works, the correct digital_rate option to "
- "<alsa-devel@alsa-project.org>\n");
- return SND_BT87X_BOARD_UNKNOWN;
-}
-
-static int __devinit snd_bt87x_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct snd_bt87x *chip;
- int err;
- enum snd_bt87x_boardid boardid;
-
- if (!pci_id->driver_data) {
- err = snd_bt87x_detect_card(pci);
- if (err < 0)
- return -ENODEV;
- boardid = err;
- } else
- boardid = pci_id->driver_data;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- ++dev;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- err = snd_bt87x_create(card, pci, &chip);
- if (err < 0)
- goto _error;
-
- memcpy(&chip->board, &snd_bt87x_boards[boardid], sizeof(chip->board));
-
- if (!chip->board.no_digital) {
- if (digital_rate[dev] > 0)
- chip->board.dig_rate = digital_rate[dev];
-
- chip->reg_control |= chip->board.digital_fmt;
-
- err = snd_bt87x_pcm(chip, DEVICE_DIGITAL, "Bt87x Digital");
- if (err < 0)
- goto _error;
- }
- if (!chip->board.no_analog) {
- err = snd_bt87x_pcm(chip, DEVICE_ANALOG, "Bt87x Analog");
- if (err < 0)
- goto _error;
- err = snd_ctl_add(card, snd_ctl_new1(
- &snd_bt87x_capture_volume, chip));
- if (err < 0)
- goto _error;
- err = snd_ctl_add(card, snd_ctl_new1(
- &snd_bt87x_capture_boost, chip));
- if (err < 0)
- goto _error;
- err = snd_ctl_add(card, snd_ctl_new1(
- &snd_bt87x_capture_source, chip));
- if (err < 0)
- goto _error;
- }
- snd_printk(KERN_INFO "bt87x%d: Using board %d, %sanalog, %sdigital "
- "(rate %d Hz)\n", dev, boardid,
- chip->board.no_analog ? "no " : "",
- chip->board.no_digital ? "no " : "", chip->board.dig_rate);
-
- strcpy(card->driver, "Bt87x");
- sprintf(card->shortname, "Brooktree Bt%x", pci->device);
- sprintf(card->longname, "%s at %#llx, irq %i",
- card->shortname, (unsigned long long)pci_resource_start(pci, 0),
- chip->irq);
- strcpy(card->mixername, "Bt87x");
-
- err = snd_card_register(card);
- if (err < 0)
- goto _error;
-
- pci_set_drvdata(pci, card);
- ++dev;
- return 0;
-
-_error:
- snd_card_free(card);
- return err;
-}
-
-static void __devexit snd_bt87x_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-/* default entries for all Bt87x cards - it's not exported */
-/* driver_data is set to 0 to call detection */
-static DEFINE_PCI_DEVICE_TABLE(snd_bt87x_default_ids) = {
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, UNKNOWN),
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, UNKNOWN),
- { }
-};
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_bt87x_ids,
- .probe = snd_bt87x_probe,
- .remove = __devexit_p(snd_bt87x_remove),
-};
-
-static int __init alsa_card_bt87x_init(void)
-{
- if (load_all)
- driver.id_table = snd_bt87x_default_ids;
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_bt87x_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_bt87x_init)
-module_exit(alsa_card_bt87x_exit)
diff --git a/ANDROID_3.4.5/sound/pci/ca0106/Makefile b/ANDROID_3.4.5/sound/pci/ca0106/Makefile
deleted file mode 100644
index dcbae7b3..00000000
--- a/ANDROID_3.4.5/sound/pci/ca0106/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-snd-ca0106-objs := ca0106_main.o ca0106_proc.o ca0106_mixer.o ca_midi.o
-
-obj-$(CONFIG_SND_CA0106) += snd-ca0106.o
diff --git a/ANDROID_3.4.5/sound/pci/ca0106/ca0106.h b/ANDROID_3.4.5/sound/pci/ca0106/ca0106.h
deleted file mode 100644
index e8e8ccc9..00000000
--- a/ANDROID_3.4.5/sound/pci/ca0106/ca0106.h
+++ /dev/null
@@ -1,742 +0,0 @@
-/*
- * Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
- * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
- * Version: 0.0.22
- *
- * FEATURES currently supported:
- * See ca0106_main.c for features.
- *
- * Changelog:
- * Support interrupts per period.
- * Removed noise from Center/LFE channel when in Analog mode.
- * Rename and remove mixer controls.
- * 0.0.6
- * Use separate card based DMA buffer for periods table list.
- * 0.0.7
- * Change remove and rename ctrls into lists.
- * 0.0.8
- * Try to fix capture sources.
- * 0.0.9
- * Fix AC3 output.
- * Enable S32_LE format support.
- * 0.0.10
- * Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
- * 0.0.11
- * Add Model name recognition.
- * 0.0.12
- * Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
- * Remove redundent "voice" handling.
- * 0.0.13
- * Single trigger call for multi channels.
- * 0.0.14
- * Set limits based on what the sound card hardware can do.
- * playback periods_min=2, periods_max=8
- * capture hw constraints require period_size = n * 64 bytes.
- * playback hw constraints require period_size = n * 64 bytes.
- * 0.0.15
- * Separated ca0106.c into separate functional .c files.
- * 0.0.16
- * Implement 192000 sample rate.
- * 0.0.17
- * Add support for SB0410 and SB0413.
- * 0.0.18
- * Modified Copyright message.
- * 0.0.19
- * Added I2C and SPI registers. Filled in interrupt enable.
- * 0.0.20
- * Added GPIO info for SB Live 24bit.
- * 0.0.21
- * Implement support for Line-in capture on SB Live 24bit.
- * 0.0.22
- * Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
- *
- *
- * This code was initially based on code from ALSA's emu10k1x.c which is:
- * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/************************************************************************************************/
-/* PCI function 0 registers, address = <val> + PCIBASE0 */
-/************************************************************************************************/
-
-#define PTR 0x00 /* Indexed register set pointer register */
- /* NOTE: The CHANNELNUM and ADDRESS words can */
- /* be modified independently of each other. */
- /* CNL[1:0], ADDR[27:16] */
-
-#define DATA 0x04 /* Indexed register set data register */
- /* DATA[31:0] */
-
-#define IPR 0x08 /* Global interrupt pending register */
- /* Clear pending interrupts by writing a 1 to */
- /* the relevant bits and zero to the other bits */
-#define IPR_MIDI_RX_B 0x00020000 /* MIDI UART-B Receive buffer non-empty */
-#define IPR_MIDI_TX_B 0x00010000 /* MIDI UART-B Transmit buffer empty */
-#define IPR_SPDIF_IN_USER 0x00004000 /* SPDIF input user data has 16 more bits */
-#define IPR_SPDIF_OUT_USER 0x00002000 /* SPDIF output user data needs 16 more bits */
-#define IPR_SPDIF_OUT_FRAME 0x00001000 /* SPDIF frame about to start */
-#define IPR_SPI 0x00000800 /* SPI transaction completed */
-#define IPR_I2C_EEPROM 0x00000400 /* I2C EEPROM transaction completed */
-#define IPR_I2C_DAC 0x00000200 /* I2C DAC transaction completed */
-#define IPR_AI 0x00000100 /* Audio pending register changed. See PTR reg 0x76 */
-#define IPR_GPI 0x00000080 /* General Purpose input changed */
-#define IPR_SRC_LOCKED 0x00000040 /* SRC lock status changed */
-#define IPR_SPDIF_STATUS 0x00000020 /* SPDIF status changed */
-#define IPR_TIMER2 0x00000010 /* 192000Hz Timer */
-#define IPR_TIMER1 0x00000008 /* 44100Hz Timer */
-#define IPR_MIDI_RX_A 0x00000004 /* MIDI UART-A Receive buffer non-empty */
-#define IPR_MIDI_TX_A 0x00000002 /* MIDI UART-A Transmit buffer empty */
-#define IPR_PCI 0x00000001 /* PCI Bus error */
-
-#define INTE 0x0c /* Interrupt enable register */
-
-#define INTE_MIDI_RX_B 0x00020000 /* MIDI UART-B Receive buffer non-empty */
-#define INTE_MIDI_TX_B 0x00010000 /* MIDI UART-B Transmit buffer empty */
-#define INTE_SPDIF_IN_USER 0x00004000 /* SPDIF input user data has 16 more bits */
-#define INTE_SPDIF_OUT_USER 0x00002000 /* SPDIF output user data needs 16 more bits */
-#define INTE_SPDIF_OUT_FRAME 0x00001000 /* SPDIF frame about to start */
-#define INTE_SPI 0x00000800 /* SPI transaction completed */
-#define INTE_I2C_EEPROM 0x00000400 /* I2C EEPROM transaction completed */
-#define INTE_I2C_DAC 0x00000200 /* I2C DAC transaction completed */
-#define INTE_AI 0x00000100 /* Audio pending register changed. See PTR reg 0x75 */
-#define INTE_GPI 0x00000080 /* General Purpose input changed */
-#define INTE_SRC_LOCKED 0x00000040 /* SRC lock status changed */
-#define INTE_SPDIF_STATUS 0x00000020 /* SPDIF status changed */
-#define INTE_TIMER2 0x00000010 /* 192000Hz Timer */
-#define INTE_TIMER1 0x00000008 /* 44100Hz Timer */
-#define INTE_MIDI_RX_A 0x00000004 /* MIDI UART-A Receive buffer non-empty */
-#define INTE_MIDI_TX_A 0x00000002 /* MIDI UART-A Transmit buffer empty */
-#define INTE_PCI 0x00000001 /* PCI Bus error */
-
-#define UNKNOWN10 0x10 /* Unknown ??. Defaults to 0 */
-#define HCFG 0x14 /* Hardware config register */
- /* 0x1000 causes AC3 to fails. It adds a dither bit. */
-
-#define HCFG_STAC 0x10000000 /* Special mode for STAC9460 Codec. */
-#define HCFG_CAPTURE_I2S_BYPASS 0x08000000 /* 1 = bypass I2S input async SRC. */
-#define HCFG_CAPTURE_SPDIF_BYPASS 0x04000000 /* 1 = bypass SPDIF input async SRC. */
-#define HCFG_PLAYBACK_I2S_BYPASS 0x02000000 /* 0 = I2S IN mixer output, 1 = I2S IN1. */
-#define HCFG_FORCE_LOCK 0x01000000 /* For test only. Force input SRC tracker to lock. */
-#define HCFG_PLAYBACK_ATTENUATION 0x00006000 /* Playback attenuation mask. 0 = 0dB, 1 = 6dB, 2 = 12dB, 3 = Mute. */
-#define HCFG_PLAYBACK_DITHER 0x00001000 /* 1 = Add dither bit to all playback channels. */
-#define HCFG_PLAYBACK_S32_LE 0x00000800 /* 1 = S32_LE, 0 = S16_LE */
-#define HCFG_CAPTURE_S32_LE 0x00000400 /* 1 = S32_LE, 0 = S16_LE (S32_LE current not working) */
-#define HCFG_8_CHANNEL_PLAY 0x00000200 /* 1 = 8 channels, 0 = 2 channels per substream.*/
-#define HCFG_8_CHANNEL_CAPTURE 0x00000100 /* 1 = 8 channels, 0 = 2 channels per substream.*/
-#define HCFG_MONO 0x00000080 /* 1 = I2S Input mono */
-#define HCFG_I2S_OUTPUT 0x00000010 /* 1 = I2S Output disabled */
-#define HCFG_AC97 0x00000008 /* 0 = AC97 1.0, 1 = AC97 2.0 */
-#define HCFG_LOCK_PLAYBACK_CACHE 0x00000004 /* 1 = Cancel bustmaster accesses to soundcache */
- /* NOTE: This should generally never be used. */
-#define HCFG_LOCK_CAPTURE_CACHE 0x00000002 /* 1 = Cancel bustmaster accesses to soundcache */
- /* NOTE: This should generally never be used. */
-#define HCFG_AUDIOENABLE 0x00000001 /* 0 = CODECs transmit zero-valued samples */
- /* Should be set to 1 when the EMU10K1 is */
- /* completely initialized. */
-#define GPIO 0x18 /* Defaults: 005f03a3-Analog, 005f02a2-SPDIF. */
- /* Here pins 0,1,2,3,4,,6 are output. 5,7 are input */
- /* For the Audigy LS, pin 0 (or bit 8) controls the SPDIF/Analog jack. */
- /* SB Live 24bit:
- * bit 8 0 = SPDIF in and out / 1 = Analog (Mic or Line)-in.
- * bit 9 0 = Mute / 1 = Analog out.
- * bit 10 0 = Line-in / 1 = Mic-in.
- * bit 11 0 = ? / 1 = ?
- * bit 12 0 = 48 Khz / 1 = 96 Khz Analog out on SB Live 24bit.
- * bit 13 0 = ? / 1 = ?
- * bit 14 0 = Mute / 1 = Analog out
- * bit 15 0 = ? / 1 = ?
- * Both bit 9 and bit 14 have to be set for analog sound to work on the SB Live 24bit.
- */
- /* 8 general purpose programmable In/Out pins.
- * GPI [8:0] Read only. Default 0.
- * GPO [15:8] Default 0x9. (Default to SPDIF jack enabled for SPDIF)
- * GPO Enable [23:16] Default 0x0f. Setting a bit to 1, causes the pin to be an output pin.
- */
-#define AC97DATA 0x1c /* AC97 register set data register (16 bit) */
-
-#define AC97ADDRESS 0x1e /* AC97 register set address register (8 bit) */
-
-/********************************************************************************************************/
-/* CA0106 pointer-offset register set, accessed through the PTR and DATA registers */
-/********************************************************************************************************/
-
-/* Initially all registers from 0x00 to 0x3f have zero contents. */
-#define PLAYBACK_LIST_ADDR 0x00 /* Base DMA address of a list of pointers to each period/size */
- /* One list entry: 4 bytes for DMA address,
- * 4 bytes for period_size << 16.
- * One list entry is 8 bytes long.
- * One list entry for each period in the buffer.
- */
- /* ADDR[31:0], Default: 0x0 */
-#define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */
- /* SIZE[21:16], Default: 0x8 */
-#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */
- /* PTR[5:0], Default: 0x0 */
-#define PLAYBACK_UNKNOWN3 0x03 /* Not used ?? */
-#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA address */
- /* DMA[31:0], Default: 0x0 */
-#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size. win2000 uses 0x04000000 */
- /* SIZE[31:16], Default: 0x0 */
-#define PLAYBACK_POINTER 0x06 /* Playback period pointer. Used with PLAYBACK_LIST_PTR to determine buffer position currently in DAC */
- /* POINTER[15:0], Default: 0x0 */
-#define PLAYBACK_PERIOD_END_ADDR 0x07 /* Playback fifo end address */
- /* END_ADDR[15:0], FLAG[16] 0 = don't stop, 1 = stop */
-#define PLAYBACK_FIFO_OFFSET_ADDRESS 0x08 /* Current fifo offset address [21:16] */
- /* Cache size valid [5:0] */
-#define PLAYBACK_UNKNOWN9 0x09 /* 0x9 to 0xf Unused */
-#define CAPTURE_DMA_ADDR 0x10 /* Capture DMA address */
- /* DMA[31:0], Default: 0x0 */
-#define CAPTURE_BUFFER_SIZE 0x11 /* Capture buffer size */
- /* SIZE[31:16], Default: 0x0 */
-#define CAPTURE_POINTER 0x12 /* Capture buffer pointer. Sample currently in ADC */
- /* POINTER[15:0], Default: 0x0 */
-#define CAPTURE_FIFO_OFFSET_ADDRESS 0x13 /* Current fifo offset address [21:16] */
- /* Cache size valid [5:0] */
-#define PLAYBACK_LAST_SAMPLE 0x20 /* The sample currently being played */
-/* 0x21 - 0x3f unused */
-#define BASIC_INTERRUPT 0x40 /* Used by both playback and capture interrupt handler */
- /* Playback (0x1<<channel_id) */
- /* Capture (0x100<<channel_id) */
- /* Playback sample rate 96000 = 0x20000 */
- /* Start Playback [3:0] (one bit per channel)
- * Start Capture [11:8] (one bit per channel)
- * Playback rate [23:16] (2 bits per channel) (0=48kHz, 1=44.1kHz, 2=96kHz, 3=192Khz)
- * Playback mixer in enable [27:24] (one bit per channel)
- * Playback mixer out enable [31:28] (one bit per channel)
- */
-/* The Digital out jack is shared with the Center/LFE Analogue output.
- * The jack has 4 poles. I will call 1 - Tip, 2 - Next to 1, 3 - Next to 2, 4 - Next to 3
- * For Analogue: 1 -> Center Speaker, 2 -> Sub Woofer, 3 -> Ground, 4 -> Ground
- * For Digital: 1 -> Front SPDIF, 2 -> Rear SPDIF, 3 -> Center/Subwoofer SPDIF, 4 -> Ground.
- * Standard 4 pole Video A/V cable with RCA outputs: 1 -> White, 2 -> Yellow, 3 -> Shield on all three, 4 -> Red.
- * So, from this you can see that you cannot use a Standard 4 pole Video A/V cable with the SB Audigy LS card.
- */
-/* The Front SPDIF PCM gets mixed with samples from the AC97 codec, so can only work for Stereo PCM and not AC3/DTS
- * The Rear SPDIF can be used for Stereo PCM and also AC3/DTS
- * The Center/LFE SPDIF cannot be used for AC3/DTS, but can be used for Stereo PCM.
- * Summary: For ALSA we use the Rear channel for SPDIF Digital AC3/DTS output
- */
-/* A standard 2 pole mono mini-jack to RCA plug can be used for SPDIF Stereo PCM output from the Front channel.
- * A standard 3 pole stereo mini-jack to 2 RCA plugs can be used for SPDIF AC3/DTS and Stereo PCM output utilising the Rear channel and just one of the RCA plugs.
- */
-#define SPCS0 0x41 /* SPDIF output Channel Status 0 register. For Rear. default=0x02108004, non-audio=0x02108006 */
-#define SPCS1 0x42 /* SPDIF output Channel Status 1 register. For Front */
-#define SPCS2 0x43 /* SPDIF output Channel Status 2 register. For Center/LFE */
-#define SPCS3 0x44 /* SPDIF output Channel Status 3 register. Unknown */
- /* When Channel set to 0: */
-#define SPCS_CLKACCYMASK 0x30000000 /* Clock accuracy */
-#define SPCS_CLKACCY_1000PPM 0x00000000 /* 1000 parts per million */
-#define SPCS_CLKACCY_50PPM 0x10000000 /* 50 parts per million */
-#define SPCS_CLKACCY_VARIABLE 0x20000000 /* Variable accuracy */
-#define SPCS_SAMPLERATEMASK 0x0f000000 /* Sample rate */
-#define SPCS_SAMPLERATE_44 0x00000000 /* 44.1kHz sample rate */
-#define SPCS_SAMPLERATE_48 0x02000000 /* 48kHz sample rate */
-#define SPCS_SAMPLERATE_32 0x03000000 /* 32kHz sample rate */
-#define SPCS_CHANNELNUMMASK 0x00f00000 /* Channel number */
-#define SPCS_CHANNELNUM_UNSPEC 0x00000000 /* Unspecified channel number */
-#define SPCS_CHANNELNUM_LEFT 0x00100000 /* Left channel */
-#define SPCS_CHANNELNUM_RIGHT 0x00200000 /* Right channel */
-#define SPCS_SOURCENUMMASK 0x000f0000 /* Source number */
-#define SPCS_SOURCENUM_UNSPEC 0x00000000 /* Unspecified source number */
-#define SPCS_GENERATIONSTATUS 0x00008000 /* Originality flag (see IEC-958 spec) */
-#define SPCS_CATEGORYCODEMASK 0x00007f00 /* Category code (see IEC-958 spec) */
-#define SPCS_MODEMASK 0x000000c0 /* Mode (see IEC-958 spec) */
-#define SPCS_EMPHASISMASK 0x00000038 /* Emphasis */
-#define SPCS_EMPHASIS_NONE 0x00000000 /* No emphasis */
-#define SPCS_EMPHASIS_50_15 0x00000008 /* 50/15 usec 2 channel */
-#define SPCS_COPYRIGHT 0x00000004 /* Copyright asserted flag -- do not modify */
-#define SPCS_NOTAUDIODATA 0x00000002 /* 0 = Digital audio, 1 = not audio */
-#define SPCS_PROFESSIONAL 0x00000001 /* 0 = Consumer (IEC-958), 1 = pro (AES3-1992) */
-
- /* When Channel set to 1: */
-#define SPCS_WORD_LENGTH_MASK 0x0000000f /* Word Length Mask */
-#define SPCS_WORD_LENGTH_16 0x00000008 /* Word Length 16 bit */
-#define SPCS_WORD_LENGTH_17 0x00000006 /* Word Length 17 bit */
-#define SPCS_WORD_LENGTH_18 0x00000004 /* Word Length 18 bit */
-#define SPCS_WORD_LENGTH_19 0x00000002 /* Word Length 19 bit */
-#define SPCS_WORD_LENGTH_20A 0x0000000a /* Word Length 20 bit */
-#define SPCS_WORD_LENGTH_20 0x00000009 /* Word Length 20 bit (both 0xa and 0x9 are 20 bit) */
-#define SPCS_WORD_LENGTH_21 0x00000007 /* Word Length 21 bit */
-#define SPCS_WORD_LENGTH_22 0x00000005 /* Word Length 22 bit */
-#define SPCS_WORD_LENGTH_23 0x00000003 /* Word Length 23 bit */
-#define SPCS_WORD_LENGTH_24 0x0000000b /* Word Length 24 bit */
-#define SPCS_ORIGINAL_SAMPLE_RATE_MASK 0x000000f0 /* Original Sample rate */
-#define SPCS_ORIGINAL_SAMPLE_RATE_NONE 0x00000000 /* Original Sample rate not indicated */
-#define SPCS_ORIGINAL_SAMPLE_RATE_16000 0x00000010 /* Original Sample rate */
-#define SPCS_ORIGINAL_SAMPLE_RATE_RES1 0x00000020 /* Original Sample rate */
-#define SPCS_ORIGINAL_SAMPLE_RATE_32000 0x00000030 /* Original Sample rate */
-#define SPCS_ORIGINAL_SAMPLE_RATE_12000 0x00000040 /* Original Sample rate */
-#define SPCS_ORIGINAL_SAMPLE_RATE_11025 0x00000050 /* Original Sample rate */
-#define SPCS_ORIGINAL_SAMPLE_RATE_8000 0x00000060 /* Original Sample rate */
-#define SPCS_ORIGINAL_SAMPLE_RATE_RES2 0x00000070 /* Original Sample rate */
-#define SPCS_ORIGINAL_SAMPLE_RATE_192000 0x00000080 /* Original Sample rate */
-#define SPCS_ORIGINAL_SAMPLE_RATE_24000 0x00000090 /* Original Sample rate */
-#define SPCS_ORIGINAL_SAMPLE_RATE_96000 0x000000a0 /* Original Sample rate */
-#define SPCS_ORIGINAL_SAMPLE_RATE_48000 0x000000b0 /* Original Sample rate */
-#define SPCS_ORIGINAL_SAMPLE_RATE_176400 0x000000c0 /* Original Sample rate */
-#define SPCS_ORIGINAL_SAMPLE_RATE_22050 0x000000d0 /* Original Sample rate */
-#define SPCS_ORIGINAL_SAMPLE_RATE_88200 0x000000e0 /* Original Sample rate */
-#define SPCS_ORIGINAL_SAMPLE_RATE_44100 0x000000f0 /* Original Sample rate */
-
-#define SPDIF_SELECT1 0x45 /* Enables SPDIF or Analogue outputs 0-SPDIF, 0xf00-Analogue */
- /* 0x100 - Front, 0x800 - Rear, 0x200 - Center/LFE.
- * But as the jack is shared, use 0xf00.
- * The Windows2000 driver uses 0x0000000f for both digital and analog.
- * 0xf00 introduces interesting noises onto the Center/LFE.
- * If you turn the volume up, you hear computer noise,
- * e.g. mouse moving, changing between app windows etc.
- * So, I am going to set this to 0x0000000f all the time now,
- * same as the windows driver does.
- * Use register SPDIF_SELECT2(0x72) to switch between SPDIF and Analog.
- */
- /* When Channel = 0:
- * Wide SPDIF format [3:0] (one bit for each channel) (0=20bit, 1=24bit)
- * Tristate SPDIF Output [11:8] (one bit for each channel) (0=Not tristate, 1=Tristate)
- * SPDIF Bypass enable [19:16] (one bit for each channel) (0=Not bypass, 1=Bypass)
- */
- /* When Channel = 1:
- * SPDIF 0 User data [7:0]
- * SPDIF 1 User data [15:8]
- * SPDIF 0 User data [23:16]
- * SPDIF 0 User data [31:24]
- * User data can be sent by using the SPDIF output frame pending and SPDIF output user bit interrupts.
- */
-#define WATERMARK 0x46 /* Test bit to indicate cache usage level */
-#define SPDIF_INPUT_STATUS 0x49 /* SPDIF Input status register. Bits the same as SPCS.
- * When Channel = 0: Bits the same as SPCS channel 0.
- * When Channel = 1: Bits the same as SPCS channel 1.
- * When Channel = 2:
- * SPDIF Input User data [16:0]
- * SPDIF Input Frame count [21:16]
- */
-#define CAPTURE_CACHE_DATA 0x50 /* 0x50-0x5f Recorded samples. */
-#define CAPTURE_SOURCE 0x60 /* Capture Source 0 = MIC */
-#define CAPTURE_SOURCE_CHANNEL0 0xf0000000 /* Mask for selecting the Capture sources */
-#define CAPTURE_SOURCE_CHANNEL1 0x0f000000 /* 0 - SPDIF mixer output. */
-#define CAPTURE_SOURCE_CHANNEL2 0x00f00000 /* 1 - What you hear or . 2 - ?? */
-#define CAPTURE_SOURCE_CHANNEL3 0x000f0000 /* 3 - Mic in, Line in, TAD in, Aux in. */
-#define CAPTURE_SOURCE_RECORD_MAP 0x0000ffff /* Default 0x00e4 */
- /* Record Map [7:0] (2 bits per channel) 0=mapped to channel 0, 1=mapped to channel 1, 2=mapped to channel2, 3=mapped to channel3
- * Record source select for channel 0 [18:16]
- * Record source select for channel 1 [22:20]
- * Record source select for channel 2 [26:24]
- * Record source select for channel 3 [30:28]
- * 0 - SPDIF mixer output.
- * 1 - i2s mixer output.
- * 2 - SPDIF input.
- * 3 - i2s input.
- * 4 - AC97 capture.
- * 5 - SRC output.
- */
-#define CAPTURE_VOLUME1 0x61 /* Capture volume per channel 0-3 */
-#define CAPTURE_VOLUME2 0x62 /* Capture volume per channel 4-7 */
-
-#define PLAYBACK_ROUTING1 0x63 /* Playback routing of channels 0-7. Effects AC3 output. Default 0x32765410 */
-#define ROUTING1_REAR 0x77000000 /* Channel_id 0 sends to 10, Channel_id 1 sends to 32 */
-#define ROUTING1_NULL 0x00770000 /* Channel_id 2 sends to 54, Channel_id 3 sends to 76 */
-#define ROUTING1_CENTER_LFE 0x00007700 /* 0x32765410 means, send Channel_id 0 to FRONT, Channel_id 1 to REAR */
-#define ROUTING1_FRONT 0x00000077 /* Channel_id 2 to CENTER_LFE, Channel_id 3 to NULL. */
- /* Channel_id's handle stereo channels. Channel X is a single mono channel */
- /* Host is input from the PCI bus. */
- /* Host channel 0 [2:0] -> SPDIF Mixer/Router channel 0-7.
- * Host channel 1 [6:4] -> SPDIF Mixer/Router channel 0-7.
- * Host channel 2 [10:8] -> SPDIF Mixer/Router channel 0-7.
- * Host channel 3 [14:12] -> SPDIF Mixer/Router channel 0-7.
- * Host channel 4 [18:16] -> SPDIF Mixer/Router channel 0-7.
- * Host channel 5 [22:20] -> SPDIF Mixer/Router channel 0-7.
- * Host channel 6 [26:24] -> SPDIF Mixer/Router channel 0-7.
- * Host channel 7 [30:28] -> SPDIF Mixer/Router channel 0-7.
- */
-
-#define PLAYBACK_ROUTING2 0x64 /* Playback Routing . Feeding Capture channels back into Playback. Effects AC3 output. Default 0x76767676 */
- /* SRC is input from the capture inputs. */
- /* SRC channel 0 [2:0] -> SPDIF Mixer/Router channel 0-7.
- * SRC channel 1 [6:4] -> SPDIF Mixer/Router channel 0-7.
- * SRC channel 2 [10:8] -> SPDIF Mixer/Router channel 0-7.
- * SRC channel 3 [14:12] -> SPDIF Mixer/Router channel 0-7.
- * SRC channel 4 [18:16] -> SPDIF Mixer/Router channel 0-7.
- * SRC channel 5 [22:20] -> SPDIF Mixer/Router channel 0-7.
- * SRC channel 6 [26:24] -> SPDIF Mixer/Router channel 0-7.
- * SRC channel 7 [30:28] -> SPDIF Mixer/Router channel 0-7.
- */
-
-#define PLAYBACK_MUTE 0x65 /* Unknown. While playing 0x0, while silent 0x00fc0000 */
- /* SPDIF Mixer input control:
- * Invert SRC to SPDIF Mixer [7-0] (One bit per channel)
- * Invert Host to SPDIF Mixer [15:8] (One bit per channel)
- * SRC to SPDIF Mixer disable [23:16] (One bit per channel)
- * Host to SPDIF Mixer disable [31:24] (One bit per channel)
- */
-#define PLAYBACK_VOLUME1 0x66 /* Playback SPDIF volume per channel. Set to the same PLAYBACK_VOLUME(0x6a) */
- /* PLAYBACK_VOLUME1 must be set to 30303030 for SPDIF AC3 Playback */
- /* SPDIF mixer input volume. 0=12dB, 0x30=0dB, 0xFE=-51.5dB, 0xff=Mute */
- /* One register for each of the 4 stereo streams. */
- /* SRC Right volume [7:0]
- * SRC Left volume [15:8]
- * Host Right volume [23:16]
- * Host Left volume [31:24]
- */
-#define CAPTURE_ROUTING1 0x67 /* Capture Routing. Default 0x32765410 */
- /* Similar to register 0x63, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */
-#define CAPTURE_ROUTING2 0x68 /* Unknown Routing. Default 0x76767676 */
- /* Similar to register 0x64, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */
-#define CAPTURE_MUTE 0x69 /* Unknown. While capturing 0x0, while silent 0x00fc0000 */
- /* Similar to register 0x65, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */
-#define PLAYBACK_VOLUME2 0x6a /* Playback Analog volume per channel. Does not effect AC3 output */
- /* Similar to register 0x66, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */
-#define UNKNOWN6b 0x6b /* Unknown. Readonly. Default 00400000 00400000 00400000 00400000 */
-#define MIDI_UART_A_DATA 0x6c /* Midi Uart A Data */
-#define MIDI_UART_A_CMD 0x6d /* Midi Uart A Command/Status */
-#define MIDI_UART_B_DATA 0x6e /* Midi Uart B Data (currently unused) */
-#define MIDI_UART_B_CMD 0x6f /* Midi Uart B Command/Status (currently unused) */
-
-/* unique channel identifier for midi->channel */
-
-#define CA0106_MIDI_CHAN_A 0x1
-#define CA0106_MIDI_CHAN_B 0x2
-
-/* from mpu401 */
-
-#define CA0106_MIDI_INPUT_AVAIL 0x80
-#define CA0106_MIDI_OUTPUT_READY 0x40
-#define CA0106_MPU401_RESET 0xff
-#define CA0106_MPU401_ENTER_UART 0x3f
-#define CA0106_MPU401_ACK 0xfe
-
-#define SAMPLE_RATE_TRACKER_STATUS 0x70 /* Readonly. Default 00108000 00108000 00500000 00500000 */
- /* Estimated sample rate [19:0] Relative to 48kHz. 0x8000 = 1.0
- * Rate Locked [20]
- * SPDIF Locked [21] For SPDIF channel only.
- * Valid Audio [22] For SPDIF channel only.
- */
-#define CAPTURE_CONTROL 0x71 /* Some sort of routing. default = 40c81000 30303030 30300000 00700000 */
- /* Channel_id 0: 0x40c81000 must be changed to 0x40c80000 for SPDIF AC3 input or output. */
- /* Channel_id 1: 0xffffffff(mute) 0x30303030(max) controls CAPTURE feedback into PLAYBACK. */
- /* Sample rate output control register Channel=0
- * Sample output rate [1:0] (0=48kHz, 1=44.1kHz, 2=96kHz, 3=192Khz)
- * Sample input rate [3:2] (0=48kHz, 1=Not available, 2=96kHz, 3=192Khz)
- * SRC input source select [4] 0=Audio from digital mixer, 1=Audio from analog source.
- * Record rate [9:8] (0=48kHz, 1=Not available, 2=96kHz, 3=192Khz)
- * Record mixer output enable [12:10]
- * I2S input rate master mode [15:14] (0=48kHz, 1=44.1kHz, 2=96kHz, 3=192Khz)
- * I2S output rate [17:16] (0=48kHz, 1=44.1kHz, 2=96kHz, 3=192Khz)
- * I2S output source select [18] (0=Audio from host, 1=Audio from SRC)
- * Record mixer I2S enable [20:19] (enable/disable i2sin1 and i2sin0)
- * I2S output master clock select [21] (0=256*I2S output rate, 1=512*I2S output rate.)
- * I2S input master clock select [22] (0=256*I2S input rate, 1=512*I2S input rate.)
- * I2S input mode [23] (0=Slave, 1=Master)
- * SPDIF output rate [25:24] (0=48kHz, 1=44.1kHz, 2=96kHz, 3=192Khz)
- * SPDIF output source select [26] (0=host, 1=SRC)
- * Not used [27]
- * Record Source 0 input [29:28] (0=SPDIF in, 1=I2S in, 2=AC97 Mic, 3=AC97 PCM)
- * Record Source 1 input [31:30] (0=SPDIF in, 1=I2S in, 2=AC97 Mic, 3=AC97 PCM)
- */
- /* Sample rate output control register Channel=1
- * I2S Input 0 volume Right [7:0]
- * I2S Input 0 volume Left [15:8]
- * I2S Input 1 volume Right [23:16]
- * I2S Input 1 volume Left [31:24]
- */
- /* Sample rate output control register Channel=2
- * SPDIF Input volume Right [23:16]
- * SPDIF Input volume Left [31:24]
- */
- /* Sample rate output control register Channel=3
- * No used
- */
-#define SPDIF_SELECT2 0x72 /* Some sort of routing. Channel_id 0 only. default = 0x0f0f003f. Analog 0x000b0000, Digital 0x0b000000 */
-#define ROUTING2_FRONT_MASK 0x00010000 /* Enable for Front speakers. */
-#define ROUTING2_CENTER_LFE_MASK 0x00020000 /* Enable for Center/LFE speakers. */
-#define ROUTING2_REAR_MASK 0x00080000 /* Enable for Rear speakers. */
- /* Audio output control
- * AC97 output enable [5:0]
- * I2S output enable [19:16]
- * SPDIF output enable [27:24]
- */
-#define UNKNOWN73 0x73 /* Unknown. Readonly. Default 0x0 */
-#define CHIP_VERSION 0x74 /* P17 Chip version. Channel_id 0 only. Default 00000071 */
-#define EXTENDED_INT_MASK 0x75 /* Used by both playback and capture interrupt handler */
- /* Sets which Interrupts are enabled. */
- /* 0x00000001 = Half period. Playback.
- * 0x00000010 = Full period. Playback.
- * 0x00000100 = Half buffer. Playback.
- * 0x00001000 = Full buffer. Playback.
- * 0x00010000 = Half buffer. Capture.
- * 0x00100000 = Full buffer. Capture.
- * Capture can only do 2 periods.
- * 0x01000000 = End audio. Playback.
- * 0x40000000 = Half buffer Playback,Caputre xrun.
- * 0x80000000 = Full buffer Playback,Caputre xrun.
- */
-#define EXTENDED_INT 0x76 /* Used by both playback and capture interrupt handler */
- /* Shows which interrupts are active at the moment. */
- /* Same bit layout as EXTENDED_INT_MASK */
-#define COUNTER77 0x77 /* Counter range 0 to 0x3fffff, 192000 counts per second. */
-#define COUNTER78 0x78 /* Counter range 0 to 0x3fffff, 44100 counts per second. */
-#define EXTENDED_INT_TIMER 0x79 /* Channel_id 0 only. Used by both playback and capture interrupt handler */
- /* Causes interrupts based on timer intervals. */
-#define SPI 0x7a /* SPI: Serial Interface Register */
-#define I2C_A 0x7b /* I2C Address. 32 bit */
-#define I2C_D0 0x7c /* I2C Data Port 0. 32 bit */
-#define I2C_D1 0x7d /* I2C Data Port 1. 32 bit */
-//I2C values
-#define I2C_A_ADC_ADD_MASK 0x000000fe //The address is a 7 bit address
-#define I2C_A_ADC_RW_MASK 0x00000001 //bit mask for R/W
-#define I2C_A_ADC_TRANS_MASK 0x00000010 //Bit mask for I2c address DAC value
-#define I2C_A_ADC_ABORT_MASK 0x00000020 //Bit mask for I2C transaction abort flag
-#define I2C_A_ADC_LAST_MASK 0x00000040 //Bit mask for Last word transaction
-#define I2C_A_ADC_BYTE_MASK 0x00000080 //Bit mask for Byte Mode
-
-#define I2C_A_ADC_ADD 0x00000034 //This is the Device address for ADC
-#define I2C_A_ADC_READ 0x00000001 //To perform a read operation
-#define I2C_A_ADC_START 0x00000100 //Start I2C transaction
-#define I2C_A_ADC_ABORT 0x00000200 //I2C transaction abort
-#define I2C_A_ADC_LAST 0x00000400 //I2C last transaction
-#define I2C_A_ADC_BYTE 0x00000800 //I2C one byte mode
-
-#define I2C_D_ADC_REG_MASK 0xfe000000 //ADC address register
-#define I2C_D_ADC_DAT_MASK 0x01ff0000 //ADC data register
-
-#define ADC_TIMEOUT 0x00000007 //ADC Timeout Clock Disable
-#define ADC_IFC_CTRL 0x0000000b //ADC Interface Control
-#define ADC_MASTER 0x0000000c //ADC Master Mode Control
-#define ADC_POWER 0x0000000d //ADC PowerDown Control
-#define ADC_ATTEN_ADCL 0x0000000e //ADC Attenuation ADCL
-#define ADC_ATTEN_ADCR 0x0000000f //ADC Attenuation ADCR
-#define ADC_ALC_CTRL1 0x00000010 //ADC ALC Control 1
-#define ADC_ALC_CTRL2 0x00000011 //ADC ALC Control 2
-#define ADC_ALC_CTRL3 0x00000012 //ADC ALC Control 3
-#define ADC_NOISE_CTRL 0x00000013 //ADC Noise Gate Control
-#define ADC_LIMIT_CTRL 0x00000014 //ADC Limiter Control
-#define ADC_MUX 0x00000015 //ADC Mux offset
-
-#if 0
-/* FIXME: Not tested yet. */
-#define ADC_GAIN_MASK 0x000000ff //Mask for ADC Gain
-#define ADC_ZERODB 0x000000cf //Value to set ADC to 0dB
-#define ADC_MUTE_MASK 0x000000c0 //Mask for ADC mute
-#define ADC_MUTE 0x000000c0 //Value to mute ADC
-#define ADC_OSR 0x00000008 //Mask for ADC oversample rate select
-#define ADC_TIMEOUT_DISABLE 0x00000008 //Value and mask to disable Timeout clock
-#define ADC_HPF_DISABLE 0x00000100 //Value and mask to disable High pass filter
-#define ADC_TRANWIN_MASK 0x00000070 //Mask for Length of Transient Window
-#endif
-
-#define ADC_MUX_MASK 0x0000000f //Mask for ADC Mux
-#define ADC_MUX_PHONE 0x00000001 //Value to select TAD at ADC Mux (Not used)
-#define ADC_MUX_MIC 0x00000002 //Value to select Mic at ADC Mux
-#define ADC_MUX_LINEIN 0x00000004 //Value to select LineIn at ADC Mux
-#define ADC_MUX_AUX 0x00000008 //Value to select Aux at ADC Mux
-
-#define SET_CHANNEL 0 /* Testing channel outputs 0=Front, 1=Center/LFE, 2=Unknown, 3=Rear */
-#define PCM_FRONT_CHANNEL 0
-#define PCM_REAR_CHANNEL 1
-#define PCM_CENTER_LFE_CHANNEL 2
-#define PCM_UNKNOWN_CHANNEL 3
-#define CONTROL_FRONT_CHANNEL 0
-#define CONTROL_REAR_CHANNEL 3
-#define CONTROL_CENTER_LFE_CHANNEL 1
-#define CONTROL_UNKNOWN_CHANNEL 2
-
-
-/* Based on WM8768 Datasheet Rev 4.2 page 32 */
-#define SPI_REG_MASK 0x1ff /* 16-bit SPI writes have a 7-bit address */
-#define SPI_REG_SHIFT 9 /* followed by 9 bits of data */
-
-#define SPI_LDA1_REG 0 /* digital attenuation */
-#define SPI_RDA1_REG 1
-#define SPI_LDA2_REG 4
-#define SPI_RDA2_REG 5
-#define SPI_LDA3_REG 6
-#define SPI_RDA3_REG 7
-#define SPI_LDA4_REG 13
-#define SPI_RDA4_REG 14
-#define SPI_MASTDA_REG 8
-
-#define SPI_DA_BIT_UPDATE (1<<8) /* update attenuation values */
-#define SPI_DA_BIT_0dB 0xff /* 0 dB */
-#define SPI_DA_BIT_infdB 0x00 /* inf dB attenuation (mute) */
-
-#define SPI_PL_REG 2
-#define SPI_PL_BIT_L_M (0<<5) /* left channel = mute */
-#define SPI_PL_BIT_L_L (1<<5) /* left channel = left */
-#define SPI_PL_BIT_L_R (2<<5) /* left channel = right */
-#define SPI_PL_BIT_L_C (3<<5) /* left channel = (L+R)/2 */
-#define SPI_PL_BIT_R_M (0<<7) /* right channel = mute */
-#define SPI_PL_BIT_R_L (1<<7) /* right channel = left */
-#define SPI_PL_BIT_R_R (2<<7) /* right channel = right */
-#define SPI_PL_BIT_R_C (3<<7) /* right channel = (L+R)/2 */
-#define SPI_IZD_REG 2
-#define SPI_IZD_BIT (1<<4) /* infinite zero detect */
-
-#define SPI_FMT_REG 3
-#define SPI_FMT_BIT_RJ (0<<0) /* right justified mode */
-#define SPI_FMT_BIT_LJ (1<<0) /* left justified mode */
-#define SPI_FMT_BIT_I2S (2<<0) /* I2S mode */
-#define SPI_FMT_BIT_DSP (3<<0) /* DSP Modes A or B */
-#define SPI_LRP_REG 3
-#define SPI_LRP_BIT (1<<2) /* invert LRCLK polarity */
-#define SPI_BCP_REG 3
-#define SPI_BCP_BIT (1<<3) /* invert BCLK polarity */
-#define SPI_IWL_REG 3
-#define SPI_IWL_BIT_16 (0<<4) /* 16-bit world length */
-#define SPI_IWL_BIT_20 (1<<4) /* 20-bit world length */
-#define SPI_IWL_BIT_24 (2<<4) /* 24-bit world length */
-#define SPI_IWL_BIT_32 (3<<4) /* 32-bit world length */
-
-#define SPI_MS_REG 10
-#define SPI_MS_BIT (1<<5) /* master mode */
-#define SPI_RATE_REG 10 /* only applies in master mode */
-#define SPI_RATE_BIT_128 (0<<6) /* MCLK = LRCLK * 128 */
-#define SPI_RATE_BIT_192 (1<<6)
-#define SPI_RATE_BIT_256 (2<<6)
-#define SPI_RATE_BIT_384 (3<<6)
-#define SPI_RATE_BIT_512 (4<<6)
-#define SPI_RATE_BIT_768 (5<<6)
-
-/* They really do label the bit for the 4th channel "4" and not "3" */
-#define SPI_DMUTE0_REG 9
-#define SPI_DMUTE1_REG 9
-#define SPI_DMUTE2_REG 9
-#define SPI_DMUTE4_REG 15
-#define SPI_DMUTE0_BIT (1<<3)
-#define SPI_DMUTE1_BIT (1<<4)
-#define SPI_DMUTE2_BIT (1<<5)
-#define SPI_DMUTE4_BIT (1<<2)
-
-#define SPI_PHASE0_REG 3
-#define SPI_PHASE1_REG 3
-#define SPI_PHASE2_REG 3
-#define SPI_PHASE4_REG 15
-#define SPI_PHASE0_BIT (1<<6)
-#define SPI_PHASE1_BIT (1<<7)
-#define SPI_PHASE2_BIT (1<<8)
-#define SPI_PHASE4_BIT (1<<3)
-
-#define SPI_PDWN_REG 2 /* power down all DACs */
-#define SPI_PDWN_BIT (1<<2)
-#define SPI_DACD0_REG 10 /* power down individual DACs */
-#define SPI_DACD1_REG 10
-#define SPI_DACD2_REG 10
-#define SPI_DACD4_REG 15
-#define SPI_DACD0_BIT (1<<1)
-#define SPI_DACD1_BIT (1<<2)
-#define SPI_DACD2_BIT (1<<3)
-#define SPI_DACD4_BIT (1<<0) /* datasheet error says it's 1 */
-
-#define SPI_PWRDNALL_REG 10 /* power down everything */
-#define SPI_PWRDNALL_BIT (1<<4)
-
-#include "ca_midi.h"
-
-struct snd_ca0106;
-
-struct snd_ca0106_channel {
- struct snd_ca0106 *emu;
- int number;
- int use;
- void (*interrupt)(struct snd_ca0106 *emu, struct snd_ca0106_channel *channel);
- struct snd_ca0106_pcm *epcm;
-};
-
-struct snd_ca0106_pcm {
- struct snd_ca0106 *emu;
- struct snd_pcm_substream *substream;
- int channel_id;
- unsigned short running;
-};
-
-struct snd_ca0106_details {
- u32 serial;
- char * name;
- int ac97; /* ac97 = 0 -> Select MIC, Line in, TAD in, AUX in.
- ac97 = 1 -> Default to AC97 in. */
- int gpio_type; /* gpio_type = 1 -> shared mic-in/line-in
- gpio_type = 2 -> shared side-out/line-in. */
- int i2c_adc; /* with i2c_adc=1, the driver adds some capture volume
- controls, phone, mic, line-in and aux. */
- u16 spi_dac; /* spi_dac = 0 -> no spi interface for DACs
- spi_dac = 0x<front><rear><center-lfe><side>
- -> specifies DAC id for each channel pair. */
-};
-
-// definition of the chip-specific record
-struct snd_ca0106 {
- struct snd_card *card;
- struct snd_ca0106_details *details;
- struct pci_dev *pci;
-
- unsigned long port;
- struct resource *res_port;
- int irq;
-
- unsigned int serial; /* serial number */
- unsigned short model; /* subsystem id */
-
- spinlock_t emu_lock;
-
- struct snd_ac97 *ac97;
- struct snd_pcm *pcm[4];
-
- struct snd_ca0106_channel playback_channels[4];
- struct snd_ca0106_channel capture_channels[4];
- u32 spdif_bits[4]; /* s/pdif out default setup */
- u32 spdif_str_bits[4]; /* s/pdif out per-stream setup */
- int spdif_enable;
- int capture_source;
- int i2c_capture_source;
- u8 i2c_capture_volume[4][2];
- int capture_mic_line_in;
-
- struct snd_dma_buffer buffer;
-
- struct snd_ca_midi midi;
- struct snd_ca_midi midi2;
-
- u16 spi_dac_reg[16];
-
-#ifdef CONFIG_PM
-#define NUM_SAVED_VOLUMES 9
- unsigned int saved_vol[NUM_SAVED_VOLUMES];
-#endif
-};
-
-int snd_ca0106_mixer(struct snd_ca0106 *emu);
-int snd_ca0106_proc_init(struct snd_ca0106 * emu);
-
-unsigned int snd_ca0106_ptr_read(struct snd_ca0106 * emu,
- unsigned int reg,
- unsigned int chn);
-
-void snd_ca0106_ptr_write(struct snd_ca0106 *emu,
- unsigned int reg,
- unsigned int chn,
- unsigned int data);
-
-int snd_ca0106_i2c_write(struct snd_ca0106 *emu, u32 reg, u32 value);
-
-int snd_ca0106_spi_write(struct snd_ca0106 * emu,
- unsigned int data);
-
-#ifdef CONFIG_PM
-void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip);
-void snd_ca0106_mixer_resume(struct snd_ca0106 *chip);
-#else
-#define snd_ca0106_mixer_suspend(chip) do { } while (0)
-#define snd_ca0106_mixer_resume(chip) do { } while (0)
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/ca0106/ca0106_main.c b/ANDROID_3.4.5/sound/pci/ca0106/ca0106_main.c
deleted file mode 100644
index 08d6ebfe..00000000
--- a/ANDROID_3.4.5/sound/pci/ca0106/ca0106_main.c
+++ /dev/null
@@ -1,1959 +0,0 @@
-/*
- * Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
- * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
- * Version: 0.0.25
- *
- * FEATURES currently supported:
- * Front, Rear and Center/LFE.
- * Surround40 and Surround51.
- * Capture from MIC an LINE IN input.
- * SPDIF digital playback of PCM stereo and AC3/DTS works.
- * (One can use a standard mono mini-jack to one RCA plugs cable.
- * or one can use a standard stereo mini-jack to two RCA plugs cable.
- * Plug one of the RCA plugs into the Coax input of the external decoder/receiver.)
- * ( In theory one could output 3 different AC3 streams at once, to 3 different SPDIF outputs. )
- * Notes on how to capture sound:
- * The AC97 is used in the PLAYBACK direction.
- * The output from the AC97 chip, instead of reaching the speakers, is fed into the Philips 1361T ADC.
- * So, to record from the MIC, set the MIC Playback volume to max,
- * unmute the MIC and turn up the MASTER Playback volume.
- * So, to prevent feedback when capturing, minimise the "Capture feedback into Playback" volume.
- *
- * The only playback controls that currently do anything are: -
- * Analog Front
- * Analog Rear
- * Analog Center/LFE
- * SPDIF Front
- * SPDIF Rear
- * SPDIF Center/LFE
- *
- * For capture from Mic in or Line in.
- * Digital/Analog ( switch must be in Analog mode for CAPTURE. )
- *
- * CAPTURE feedback into PLAYBACK
- *
- * Changelog:
- * Support interrupts per period.
- * Removed noise from Center/LFE channel when in Analog mode.
- * Rename and remove mixer controls.
- * 0.0.6
- * Use separate card based DMA buffer for periods table list.
- * 0.0.7
- * Change remove and rename ctrls into lists.
- * 0.0.8
- * Try to fix capture sources.
- * 0.0.9
- * Fix AC3 output.
- * Enable S32_LE format support.
- * 0.0.10
- * Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
- * 0.0.11
- * Add Model name recognition.
- * 0.0.12
- * Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
- * Remove redundent "voice" handling.
- * 0.0.13
- * Single trigger call for multi channels.
- * 0.0.14
- * Set limits based on what the sound card hardware can do.
- * playback periods_min=2, periods_max=8
- * capture hw constraints require period_size = n * 64 bytes.
- * playback hw constraints require period_size = n * 64 bytes.
- * 0.0.15
- * Minor updates.
- * 0.0.16
- * Implement 192000 sample rate.
- * 0.0.17
- * Add support for SB0410 and SB0413.
- * 0.0.18
- * Modified Copyright message.
- * 0.0.19
- * Finally fix support for SB Live 24 bit. SB0410 and SB0413.
- * The output codec needs resetting, otherwise all output is muted.
- * 0.0.20
- * Merge "pci_disable_device(pci);" fixes.
- * 0.0.21
- * Add 4 capture channels. (SPDIF only comes in on channel 0. )
- * Add SPDIF capture using optional digital I/O module for SB Live 24bit. (Analog capture does not yet work.)
- * 0.0.22
- * Add support for MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97. From kiksen, bug #901
- * 0.0.23
- * Implement support for Line-in capture on SB Live 24bit.
- * 0.0.24
- * Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
- * 0.0.25
- * Powerdown SPI DAC channels when not in use
- *
- * BUGS:
- * Some stability problems when unloading the snd-ca0106 kernel module.
- * --
- *
- * TODO:
- * 4 Capture channels, only one implemented so far.
- * Other capture rates apart from 48khz not implemented.
- * MIDI
- * --
- * GENERAL INFO:
- * Model: SB0310
- * P17 Chip: CA0106-DAT
- * AC97 Codec: STAC 9721
- * ADC: Philips 1361T (Stereo 24bit)
- * DAC: WM8746EDS (6-channel, 24bit, 192Khz)
- *
- * GENERAL INFO:
- * Model: SB0410
- * P17 Chip: CA0106-DAT
- * AC97 Codec: None
- * ADC: WM8775EDS (4 Channel)
- * DAC: CS4382 (114 dB, 24-Bit, 192 kHz, 8-Channel D/A Converter with DSD Support)
- * SPDIF Out control switches between Mic in and SPDIF out.
- * No sound out or mic input working yet.
- *
- * GENERAL INFO:
- * Model: SB0413
- * P17 Chip: CA0106-DAT
- * AC97 Codec: None.
- * ADC: Unknown
- * DAC: Unknown
- * Trying to handle it like the SB0410.
- *
- * This code was initially based on code from ALSA's emu10k1x.c which is:
- * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/info.h>
-
-MODULE_AUTHOR("James Courtier-Dutton <James@superbug.demon.co.uk>");
-MODULE_DESCRIPTION("CA0106");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Creative,SB CA0106 chip}}");
-
-// module parameters (see "Module Parameters")
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for the CA0106 soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for the CA0106 soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable the CA0106 soundcard.");
-module_param_array(subsystem, uint, NULL, 0444);
-MODULE_PARM_DESC(subsystem, "Force card subsystem model.");
-
-#include "ca0106.h"
-
-static struct snd_ca0106_details ca0106_chip_details[] = {
- /* Sound Blaster X-Fi Extreme Audio. This does not have an AC97. 53SB079000000 */
- /* It is really just a normal SB Live 24bit. */
- /* Tested:
- * See ALSA bug#3251
- */
- { .serial = 0x10131102,
- .name = "X-Fi Extreme Audio [SBxxxx]",
- .gpio_type = 1,
- .i2c_adc = 1 } ,
- /* Sound Blaster X-Fi Extreme Audio. This does not have an AC97. 53SB079000000 */
- /* It is really just a normal SB Live 24bit. */
- /*
- * CTRL:CA0111-WTLF
- * ADC: WM8775SEDS
- * DAC: CS4382-KQZ
- */
- /* Tested:
- * Playback on front, rear, center/lfe speakers
- * Capture from Mic in.
- * Not-Tested:
- * Capture from Line in.
- * Playback to digital out.
- */
- { .serial = 0x10121102,
- .name = "X-Fi Extreme Audio [SB0790]",
- .gpio_type = 1,
- .i2c_adc = 1 } ,
- /* New Dell Sound Blaster Live! 7.1 24bit. This does not have an AC97. */
- /* AudigyLS[SB0310] */
- { .serial = 0x10021102,
- .name = "AudigyLS [SB0310]",
- .ac97 = 1 } ,
- /* Unknown AudigyLS that also says SB0310 on it */
- { .serial = 0x10051102,
- .name = "AudigyLS [SB0310b]",
- .ac97 = 1 } ,
- /* New Sound Blaster Live! 7.1 24bit. This does not have an AC97. 53SB041000001 */
- { .serial = 0x10061102,
- .name = "Live! 7.1 24bit [SB0410]",
- .gpio_type = 1,
- .i2c_adc = 1 } ,
- /* New Dell Sound Blaster Live! 7.1 24bit. This does not have an AC97. */
- { .serial = 0x10071102,
- .name = "Live! 7.1 24bit [SB0413]",
- .gpio_type = 1,
- .i2c_adc = 1 } ,
- /* New Audigy SE. Has a different DAC. */
- /* SB0570:
- * CTRL:CA0106-DAT
- * ADC: WM8775EDS
- * DAC: WM8768GEDS
- */
- { .serial = 0x100a1102,
- .name = "Audigy SE [SB0570]",
- .gpio_type = 1,
- .i2c_adc = 1,
- .spi_dac = 0x4021 } ,
- /* New Audigy LS. Has a different DAC. */
- /* SB0570:
- * CTRL:CA0106-DAT
- * ADC: WM8775EDS
- * DAC: WM8768GEDS
- */
- { .serial = 0x10111102,
- .name = "Audigy SE OEM [SB0570a]",
- .gpio_type = 1,
- .i2c_adc = 1,
- .spi_dac = 0x4021 } ,
- /* Sound Blaster 5.1vx
- * Tested: Playback on front, rear, center/lfe speakers
- * Not-Tested: Capture
- */
- { .serial = 0x10041102,
- .name = "Sound Blaster 5.1vx [SB1070]",
- .gpio_type = 1,
- .i2c_adc = 0,
- .spi_dac = 0x0124
- } ,
- /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */
- /* SB0438
- * CTRL:CA0106-DAT
- * ADC: WM8775SEDS
- * DAC: CS4382-KQZ
- */
- { .serial = 0x10091462,
- .name = "MSI K8N Diamond MB [SB0438]",
- .gpio_type = 2,
- .i2c_adc = 1 } ,
- /* MSI K8N Diamond PLUS MB */
- { .serial = 0x10091102,
- .name = "MSI K8N Diamond MB",
- .gpio_type = 2,
- .i2c_adc = 1,
- .spi_dac = 0x4021 } ,
- /* Giga-byte GA-G1975X mobo
- * Novell bnc#395807
- */
- /* FIXME: the GPIO and I2C setting aren't tested well */
- { .serial = 0x1458a006,
- .name = "Giga-byte GA-G1975X",
- .gpio_type = 1,
- .i2c_adc = 1 },
- /* Shuttle XPC SD31P which has an onboard Creative Labs
- * Sound Blaster Live! 24-bit EAX
- * high-definition 7.1 audio processor".
- * Added using info from andrewvegan in alsa bug #1298
- */
- { .serial = 0x30381297,
- .name = "Shuttle XPC SD31P [SD31P]",
- .gpio_type = 1,
- .i2c_adc = 1 } ,
- /* Shuttle XPC SD11G5 which has an onboard Creative Labs
- * Sound Blaster Live! 24-bit EAX
- * high-definition 7.1 audio processor".
- * Fixes ALSA bug#1600
- */
- { .serial = 0x30411297,
- .name = "Shuttle XPC SD11G5 [SD11G5]",
- .gpio_type = 1,
- .i2c_adc = 1 } ,
- { .serial = 0,
- .name = "AudigyLS [Unknown]" }
-};
-
-/* hardware definition */
-static struct snd_pcm_hardware snd_ca0106_playback_hw = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_SYNC_START,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
- .rates = (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
- SNDRV_PCM_RATE_192000),
- .rate_min = 48000,
- .rate_max = 192000,
- .channels_min = 2, //1,
- .channels_max = 2, //6,
- .buffer_bytes_max = ((65536 - 64) * 8),
- .period_bytes_min = 64,
- .period_bytes_max = (65536 - 64),
- .periods_min = 2,
- .periods_max = 8,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_ca0106_capture_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
-#if 0 /* FIXME: looks like 44.1kHz capture causes noisy output on 48kHz */
- .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000),
- .rate_min = 44100,
-#else
- .rates = (SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000),
- .rate_min = 48000,
-#endif /* FIXME */
- .rate_max = 192000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 65536 - 128,
- .period_bytes_min = 64,
- .period_bytes_max = 32768 - 64,
- .periods_min = 2,
- .periods_max = 2,
- .fifo_size = 0,
-};
-
-unsigned int snd_ca0106_ptr_read(struct snd_ca0106 * emu,
- unsigned int reg,
- unsigned int chn)
-{
- unsigned long flags;
- unsigned int regptr, val;
-
- regptr = (reg << 16) | chn;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(regptr, emu->port + PTR);
- val = inl(emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- return val;
-}
-
-void snd_ca0106_ptr_write(struct snd_ca0106 *emu,
- unsigned int reg,
- unsigned int chn,
- unsigned int data)
-{
- unsigned int regptr;
- unsigned long flags;
-
- regptr = (reg << 16) | chn;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(regptr, emu->port + PTR);
- outl(data, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-int snd_ca0106_spi_write(struct snd_ca0106 * emu,
- unsigned int data)
-{
- unsigned int reset, set;
- unsigned int reg, tmp;
- int n, result;
- reg = SPI;
- if (data > 0xffff) /* Only 16bit values allowed */
- return 1;
- tmp = snd_ca0106_ptr_read(emu, reg, 0);
- reset = (tmp & ~0x3ffff) | 0x20000; /* Set xxx20000 */
- set = reset | 0x10000; /* Set xxx1xxxx */
- snd_ca0106_ptr_write(emu, reg, 0, reset | data);
- tmp = snd_ca0106_ptr_read(emu, reg, 0); /* write post */
- snd_ca0106_ptr_write(emu, reg, 0, set | data);
- result = 1;
- /* Wait for status bit to return to 0 */
- for (n = 0; n < 100; n++) {
- udelay(10);
- tmp = snd_ca0106_ptr_read(emu, reg, 0);
- if (!(tmp & 0x10000)) {
- result = 0;
- break;
- }
- }
- if (result) /* Timed out */
- return 1;
- snd_ca0106_ptr_write(emu, reg, 0, reset | data);
- tmp = snd_ca0106_ptr_read(emu, reg, 0); /* Write post */
- return 0;
-}
-
-/* The ADC does not support i2c read, so only write is implemented */
-int snd_ca0106_i2c_write(struct snd_ca0106 *emu,
- u32 reg,
- u32 value)
-{
- u32 tmp;
- int timeout = 0;
- int status;
- int retry;
- if ((reg > 0x7f) || (value > 0x1ff)) {
- snd_printk(KERN_ERR "i2c_write: invalid values.\n");
- return -EINVAL;
- }
-
- tmp = reg << 25 | value << 16;
- /*
- snd_printk(KERN_DEBUG "I2C-write:reg=0x%x, value=0x%x\n", reg, value);
- */
- /* Not sure what this I2C channel controls. */
- /* snd_ca0106_ptr_write(emu, I2C_D0, 0, tmp); */
-
- /* This controls the I2C connected to the WM8775 ADC Codec */
- snd_ca0106_ptr_write(emu, I2C_D1, 0, tmp);
-
- for (retry = 0; retry < 10; retry++) {
- /* Send the data to i2c */
- //tmp = snd_ca0106_ptr_read(emu, I2C_A, 0);
- //tmp = tmp & ~(I2C_A_ADC_READ|I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD_MASK);
- tmp = 0;
- tmp = tmp | (I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD);
- snd_ca0106_ptr_write(emu, I2C_A, 0, tmp);
-
- /* Wait till the transaction ends */
- while (1) {
- status = snd_ca0106_ptr_read(emu, I2C_A, 0);
- /*snd_printk(KERN_DEBUG "I2C:status=0x%x\n", status);*/
- timeout++;
- if ((status & I2C_A_ADC_START) == 0)
- break;
-
- if (timeout > 1000)
- break;
- }
- //Read back and see if the transaction is successful
- if ((status & I2C_A_ADC_ABORT) == 0)
- break;
- }
-
- if (retry == 10) {
- snd_printk(KERN_ERR "Writing to ADC failed!\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-
-static void snd_ca0106_intr_enable(struct snd_ca0106 *emu, unsigned int intrenb)
-{
- unsigned long flags;
- unsigned int intr_enable;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- intr_enable = inl(emu->port + INTE) | intrenb;
- outl(intr_enable, emu->port + INTE);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-static void snd_ca0106_intr_disable(struct snd_ca0106 *emu, unsigned int intrenb)
-{
- unsigned long flags;
- unsigned int intr_enable;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- intr_enable = inl(emu->port + INTE) & ~intrenb;
- outl(intr_enable, emu->port + INTE);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-
-static void snd_ca0106_pcm_free_substream(struct snd_pcm_runtime *runtime)
-{
- kfree(runtime->private_data);
-}
-
-static const int spi_dacd_reg[] = {
- SPI_DACD0_REG,
- SPI_DACD1_REG,
- SPI_DACD2_REG,
- 0,
- SPI_DACD4_REG,
-};
-static const int spi_dacd_bit[] = {
- SPI_DACD0_BIT,
- SPI_DACD1_BIT,
- SPI_DACD2_BIT,
- 0,
- SPI_DACD4_BIT,
-};
-
-static void restore_spdif_bits(struct snd_ca0106 *chip, int idx)
-{
- if (chip->spdif_str_bits[idx] != chip->spdif_bits[idx]) {
- chip->spdif_str_bits[idx] = chip->spdif_bits[idx];
- snd_ca0106_ptr_write(chip, SPCS0 + idx, 0,
- chip->spdif_str_bits[idx]);
- }
-}
-
-static int snd_ca0106_channel_dac(struct snd_ca0106_details *details,
- int channel_id)
-{
- switch (channel_id) {
- case PCM_FRONT_CHANNEL:
- return (details->spi_dac & 0xf000) >> (4 * 3);
- case PCM_REAR_CHANNEL:
- return (details->spi_dac & 0x0f00) >> (4 * 2);
- case PCM_CENTER_LFE_CHANNEL:
- return (details->spi_dac & 0x00f0) >> (4 * 1);
- case PCM_UNKNOWN_CHANNEL:
- return (details->spi_dac & 0x000f) >> (4 * 0);
- default:
- snd_printk(KERN_DEBUG "ca0106: unknown channel_id %d\n",
- channel_id);
- }
- return 0;
-}
-
-static int snd_ca0106_pcm_power_dac(struct snd_ca0106 *chip, int channel_id,
- int power)
-{
- if (chip->details->spi_dac) {
- const int dac = snd_ca0106_channel_dac(chip->details,
- channel_id);
- const int reg = spi_dacd_reg[dac];
- const int bit = spi_dacd_bit[dac];
-
- if (power)
- /* Power up */
- chip->spi_dac_reg[reg] &= ~bit;
- else
- /* Power down */
- chip->spi_dac_reg[reg] |= bit;
- return snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]);
- }
- return 0;
-}
-
-/* open_playback callback */
-static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream,
- int channel_id)
-{
- struct snd_ca0106 *chip = snd_pcm_substream_chip(substream);
- struct snd_ca0106_channel *channel = &(chip->playback_channels[channel_id]);
- struct snd_ca0106_pcm *epcm;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
-
- if (epcm == NULL)
- return -ENOMEM;
- epcm->emu = chip;
- epcm->substream = substream;
- epcm->channel_id=channel_id;
-
- runtime->private_data = epcm;
- runtime->private_free = snd_ca0106_pcm_free_substream;
-
- runtime->hw = snd_ca0106_playback_hw;
-
- channel->emu = chip;
- channel->number = channel_id;
-
- channel->use = 1;
- /*
- printk(KERN_DEBUG "open:channel_id=%d, chip=%p, channel=%p\n",
- channel_id, chip, channel);
- */
- //channel->interrupt = snd_ca0106_pcm_channel_interrupt;
- channel->epcm = epcm;
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
- return err;
- if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
- return err;
- snd_pcm_set_sync(substream);
-
- /* Front channel dac should already be on */
- if (channel_id != PCM_FRONT_CHANNEL) {
- err = snd_ca0106_pcm_power_dac(chip, channel_id, 1);
- if (err < 0)
- return err;
- }
-
- restore_spdif_bits(chip, channel_id);
-
- return 0;
-}
-
-/* close callback */
-static int snd_ca0106_pcm_close_playback(struct snd_pcm_substream *substream)
-{
- struct snd_ca0106 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ca0106_pcm *epcm = runtime->private_data;
- chip->playback_channels[epcm->channel_id].use = 0;
-
- restore_spdif_bits(chip, epcm->channel_id);
-
- /* Front channel dac should stay on */
- if (epcm->channel_id != PCM_FRONT_CHANNEL) {
- int err;
- err = snd_ca0106_pcm_power_dac(chip, epcm->channel_id, 0);
- if (err < 0)
- return err;
- }
-
- /* FIXME: maybe zero others */
- return 0;
-}
-
-static int snd_ca0106_pcm_open_playback_front(struct snd_pcm_substream *substream)
-{
- return snd_ca0106_pcm_open_playback_channel(substream, PCM_FRONT_CHANNEL);
-}
-
-static int snd_ca0106_pcm_open_playback_center_lfe(struct snd_pcm_substream *substream)
-{
- return snd_ca0106_pcm_open_playback_channel(substream, PCM_CENTER_LFE_CHANNEL);
-}
-
-static int snd_ca0106_pcm_open_playback_unknown(struct snd_pcm_substream *substream)
-{
- return snd_ca0106_pcm_open_playback_channel(substream, PCM_UNKNOWN_CHANNEL);
-}
-
-static int snd_ca0106_pcm_open_playback_rear(struct snd_pcm_substream *substream)
-{
- return snd_ca0106_pcm_open_playback_channel(substream, PCM_REAR_CHANNEL);
-}
-
-/* open_capture callback */
-static int snd_ca0106_pcm_open_capture_channel(struct snd_pcm_substream *substream,
- int channel_id)
-{
- struct snd_ca0106 *chip = snd_pcm_substream_chip(substream);
- struct snd_ca0106_channel *channel = &(chip->capture_channels[channel_id]);
- struct snd_ca0106_pcm *epcm;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
- if (epcm == NULL) {
- snd_printk(KERN_ERR "open_capture_channel: failed epcm alloc\n");
- return -ENOMEM;
- }
- epcm->emu = chip;
- epcm->substream = substream;
- epcm->channel_id=channel_id;
-
- runtime->private_data = epcm;
- runtime->private_free = snd_ca0106_pcm_free_substream;
-
- runtime->hw = snd_ca0106_capture_hw;
-
- channel->emu = chip;
- channel->number = channel_id;
-
- channel->use = 1;
- /*
- printk(KERN_DEBUG "open:channel_id=%d, chip=%p, channel=%p\n",
- channel_id, chip, channel);
- */
- //channel->interrupt = snd_ca0106_pcm_channel_interrupt;
- channel->epcm = epcm;
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
- return err;
- //snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_capture_period_sizes);
- if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
- return err;
- return 0;
-}
-
-/* close callback */
-static int snd_ca0106_pcm_close_capture(struct snd_pcm_substream *substream)
-{
- struct snd_ca0106 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ca0106_pcm *epcm = runtime->private_data;
- chip->capture_channels[epcm->channel_id].use = 0;
- /* FIXME: maybe zero others */
- return 0;
-}
-
-static int snd_ca0106_pcm_open_0_capture(struct snd_pcm_substream *substream)
-{
- return snd_ca0106_pcm_open_capture_channel(substream, 0);
-}
-
-static int snd_ca0106_pcm_open_1_capture(struct snd_pcm_substream *substream)
-{
- return snd_ca0106_pcm_open_capture_channel(substream, 1);
-}
-
-static int snd_ca0106_pcm_open_2_capture(struct snd_pcm_substream *substream)
-{
- return snd_ca0106_pcm_open_capture_channel(substream, 2);
-}
-
-static int snd_ca0106_pcm_open_3_capture(struct snd_pcm_substream *substream)
-{
- return snd_ca0106_pcm_open_capture_channel(substream, 3);
-}
-
-/* hw_params callback */
-static int snd_ca0106_pcm_hw_params_playback(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-}
-
-/* hw_free callback */
-static int snd_ca0106_pcm_hw_free_playback(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-/* hw_params callback */
-static int snd_ca0106_pcm_hw_params_capture(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-}
-
-/* hw_free callback */
-static int snd_ca0106_pcm_hw_free_capture(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-/* prepare playback callback */
-static int snd_ca0106_pcm_prepare_playback(struct snd_pcm_substream *substream)
-{
- struct snd_ca0106 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ca0106_pcm *epcm = runtime->private_data;
- int channel = epcm->channel_id;
- u32 *table_base = (u32 *)(emu->buffer.area+(8*16*channel));
- u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
- u32 hcfg_mask = HCFG_PLAYBACK_S32_LE;
- u32 hcfg_set = 0x00000000;
- u32 hcfg;
- u32 reg40_mask = 0x30000 << (channel<<1);
- u32 reg40_set = 0;
- u32 reg40;
- /* FIXME: Depending on mixer selection of SPDIF out or not, select the spdif rate or the DAC rate. */
- u32 reg71_mask = 0x03030000 ; /* Global. Set SPDIF rate. We only support 44100 to spdif, not to DAC. */
- u32 reg71_set = 0;
- u32 reg71;
- int i;
-
-#if 0 /* debug */
- snd_printk(KERN_DEBUG
- "prepare:channel_number=%d, rate=%d, format=0x%x, "
- "channels=%d, buffer_size=%ld, period_size=%ld, "
- "periods=%u, frames_to_bytes=%d\n",
- channel, runtime->rate, runtime->format,
- runtime->channels, runtime->buffer_size,
- runtime->period_size, runtime->periods,
- frames_to_bytes(runtime, 1));
- snd_printk(KERN_DEBUG "dma_addr=%x, dma_area=%p, table_base=%p\n",
- runtime->dma_addr, runtime->dma_area, table_base);
- snd_printk(KERN_DEBUG "dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n",
- emu->buffer.addr, emu->buffer.area, emu->buffer.bytes);
-#endif /* debug */
- /* Rate can be set per channel. */
- /* reg40 control host to fifo */
- /* reg71 controls DAC rate. */
- switch (runtime->rate) {
- case 44100:
- reg40_set = 0x10000 << (channel<<1);
- reg71_set = 0x01010000;
- break;
- case 48000:
- reg40_set = 0;
- reg71_set = 0;
- break;
- case 96000:
- reg40_set = 0x20000 << (channel<<1);
- reg71_set = 0x02020000;
- break;
- case 192000:
- reg40_set = 0x30000 << (channel<<1);
- reg71_set = 0x03030000;
- break;
- default:
- reg40_set = 0;
- reg71_set = 0;
- break;
- }
- /* Format is a global setting */
- /* FIXME: Only let the first channel accessed set this. */
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_S16_LE:
- hcfg_set = 0;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- hcfg_set = HCFG_PLAYBACK_S32_LE;
- break;
- default:
- hcfg_set = 0;
- break;
- }
- hcfg = inl(emu->port + HCFG) ;
- hcfg = (hcfg & ~hcfg_mask) | hcfg_set;
- outl(hcfg, emu->port + HCFG);
- reg40 = snd_ca0106_ptr_read(emu, 0x40, 0);
- reg40 = (reg40 & ~reg40_mask) | reg40_set;
- snd_ca0106_ptr_write(emu, 0x40, 0, reg40);
- reg71 = snd_ca0106_ptr_read(emu, 0x71, 0);
- reg71 = (reg71 & ~reg71_mask) | reg71_set;
- snd_ca0106_ptr_write(emu, 0x71, 0, reg71);
-
- /* FIXME: Check emu->buffer.size before actually writing to it. */
- for(i=0; i < runtime->periods; i++) {
- table_base[i*2] = runtime->dma_addr + (i * period_size_bytes);
- table_base[i*2+1] = period_size_bytes << 16;
- }
-
- snd_ca0106_ptr_write(emu, PLAYBACK_LIST_ADDR, channel, emu->buffer.addr+(8*16*channel));
- snd_ca0106_ptr_write(emu, PLAYBACK_LIST_SIZE, channel, (runtime->periods - 1) << 19);
- snd_ca0106_ptr_write(emu, PLAYBACK_LIST_PTR, channel, 0);
- snd_ca0106_ptr_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr);
- snd_ca0106_ptr_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes
- /* FIXME test what 0 bytes does. */
- snd_ca0106_ptr_write(emu, PLAYBACK_PERIOD_SIZE, channel, 0); // buffer size in bytes
- snd_ca0106_ptr_write(emu, PLAYBACK_POINTER, channel, 0);
- snd_ca0106_ptr_write(emu, 0x07, channel, 0x0);
- snd_ca0106_ptr_write(emu, 0x08, channel, 0);
- snd_ca0106_ptr_write(emu, PLAYBACK_MUTE, 0x0, 0x0); /* Unmute output */
-#if 0
- snd_ca0106_ptr_write(emu, SPCS0, 0,
- SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
- SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
- SPCS_GENERATIONSTATUS | 0x00001200 |
- 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT );
-#endif
-
- return 0;
-}
-
-/* prepare capture callback */
-static int snd_ca0106_pcm_prepare_capture(struct snd_pcm_substream *substream)
-{
- struct snd_ca0106 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ca0106_pcm *epcm = runtime->private_data;
- int channel = epcm->channel_id;
- u32 hcfg_mask = HCFG_CAPTURE_S32_LE;
- u32 hcfg_set = 0x00000000;
- u32 hcfg;
- u32 over_sampling=0x2;
- u32 reg71_mask = 0x0000c000 ; /* Global. Set ADC rate. */
- u32 reg71_set = 0;
- u32 reg71;
-
-#if 0 /* debug */
- snd_printk(KERN_DEBUG
- "prepare:channel_number=%d, rate=%d, format=0x%x, "
- "channels=%d, buffer_size=%ld, period_size=%ld, "
- "periods=%u, frames_to_bytes=%d\n",
- channel, runtime->rate, runtime->format,
- runtime->channels, runtime->buffer_size,
- runtime->period_size, runtime->periods,
- frames_to_bytes(runtime, 1));
- snd_printk(KERN_DEBUG "dma_addr=%x, dma_area=%p, table_base=%p\n",
- runtime->dma_addr, runtime->dma_area, table_base);
- snd_printk(KERN_DEBUG "dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n",
- emu->buffer.addr, emu->buffer.area, emu->buffer.bytes);
-#endif /* debug */
- /* reg71 controls ADC rate. */
- switch (runtime->rate) {
- case 44100:
- reg71_set = 0x00004000;
- break;
- case 48000:
- reg71_set = 0;
- break;
- case 96000:
- reg71_set = 0x00008000;
- over_sampling=0xa;
- break;
- case 192000:
- reg71_set = 0x0000c000;
- over_sampling=0xa;
- break;
- default:
- reg71_set = 0;
- break;
- }
- /* Format is a global setting */
- /* FIXME: Only let the first channel accessed set this. */
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_S16_LE:
- hcfg_set = 0;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- hcfg_set = HCFG_CAPTURE_S32_LE;
- break;
- default:
- hcfg_set = 0;
- break;
- }
- hcfg = inl(emu->port + HCFG) ;
- hcfg = (hcfg & ~hcfg_mask) | hcfg_set;
- outl(hcfg, emu->port + HCFG);
- reg71 = snd_ca0106_ptr_read(emu, 0x71, 0);
- reg71 = (reg71 & ~reg71_mask) | reg71_set;
- snd_ca0106_ptr_write(emu, 0x71, 0, reg71);
- if (emu->details->i2c_adc == 1) { /* The SB0410 and SB0413 use I2C to control ADC. */
- snd_ca0106_i2c_write(emu, ADC_MASTER, over_sampling); /* Adjust the over sampler to better suit the capture rate. */
- }
-
-
- /*
- printk(KERN_DEBUG
- "prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, "
- "buffer_size=%ld, period_size=%ld, frames_to_bytes=%d\n",
- channel, runtime->rate, runtime->format, runtime->channels,
- runtime->buffer_size, runtime->period_size,
- frames_to_bytes(runtime, 1));
- */
- snd_ca0106_ptr_write(emu, 0x13, channel, 0);
- snd_ca0106_ptr_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr);
- snd_ca0106_ptr_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes
- snd_ca0106_ptr_write(emu, CAPTURE_POINTER, channel, 0);
-
- return 0;
-}
-
-/* trigger_playback callback */
-static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_ca0106 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime;
- struct snd_ca0106_pcm *epcm;
- int channel;
- int result = 0;
- struct snd_pcm_substream *s;
- u32 basic = 0;
- u32 extended = 0;
- u32 bits;
- int running = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- running = 1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- default:
- running = 0;
- break;
- }
- snd_pcm_group_for_each_entry(s, substream) {
- if (snd_pcm_substream_chip(s) != emu ||
- s->stream != SNDRV_PCM_STREAM_PLAYBACK)
- continue;
- runtime = s->runtime;
- epcm = runtime->private_data;
- channel = epcm->channel_id;
- /* snd_printk(KERN_DEBUG "channel=%d\n", channel); */
- epcm->running = running;
- basic |= (0x1 << channel);
- extended |= (0x10 << channel);
- snd_pcm_trigger_done(s, substream);
- }
- /* snd_printk(KERN_DEBUG "basic=0x%x, extended=0x%x\n",basic, extended); */
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- bits = snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0);
- bits |= extended;
- snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, bits);
- bits = snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0);
- bits |= basic;
- snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, bits);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- bits = snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0);
- bits &= ~basic;
- snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, bits);
- bits = snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0);
- bits &= ~extended;
- snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, bits);
- break;
- default:
- result = -EINVAL;
- break;
- }
- return result;
-}
-
-/* trigger_capture callback */
-static int snd_ca0106_pcm_trigger_capture(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_ca0106 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ca0106_pcm *epcm = runtime->private_data;
- int channel = epcm->channel_id;
- int result = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) | (0x110000<<channel));
- snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0)|(0x100<<channel));
- epcm->running = 1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0) & ~(0x100<<channel));
- snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) & ~(0x110000<<channel));
- epcm->running = 0;
- break;
- default:
- result = -EINVAL;
- break;
- }
- return result;
-}
-
-/* pointer_playback callback */
-static snd_pcm_uframes_t
-snd_ca0106_pcm_pointer_playback(struct snd_pcm_substream *substream)
-{
- struct snd_ca0106 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ca0106_pcm *epcm = runtime->private_data;
- unsigned int ptr, prev_ptr;
- int channel = epcm->channel_id;
- int timeout = 10;
-
- if (!epcm->running)
- return 0;
-
- prev_ptr = -1;
- do {
- ptr = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
- ptr = (ptr >> 3) * runtime->period_size;
- ptr += bytes_to_frames(runtime,
- snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel));
- if (ptr >= runtime->buffer_size)
- ptr -= runtime->buffer_size;
- if (prev_ptr == ptr)
- return ptr;
- prev_ptr = ptr;
- } while (--timeout);
- snd_printk(KERN_WARNING "ca0106: unstable DMA pointer!\n");
- return 0;
-}
-
-/* pointer_capture callback */
-static snd_pcm_uframes_t
-snd_ca0106_pcm_pointer_capture(struct snd_pcm_substream *substream)
-{
- struct snd_ca0106 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ca0106_pcm *epcm = runtime->private_data;
- snd_pcm_uframes_t ptr, ptr1, ptr2 = 0;
- int channel = epcm->channel_id;
-
- if (!epcm->running)
- return 0;
-
- ptr1 = snd_ca0106_ptr_read(emu, CAPTURE_POINTER, channel);
- ptr2 = bytes_to_frames(runtime, ptr1);
- ptr=ptr2;
- if (ptr >= runtime->buffer_size)
- ptr -= runtime->buffer_size;
- /*
- printk(KERN_DEBUG "ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, "
- "buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n",
- ptr1, ptr2, ptr, (int)runtime->buffer_size,
- (int)runtime->period_size, (int)runtime->frame_bits,
- (int)runtime->rate);
- */
- return ptr;
-}
-
-/* operators */
-static struct snd_pcm_ops snd_ca0106_playback_front_ops = {
- .open = snd_ca0106_pcm_open_playback_front,
- .close = snd_ca0106_pcm_close_playback,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ca0106_pcm_hw_params_playback,
- .hw_free = snd_ca0106_pcm_hw_free_playback,
- .prepare = snd_ca0106_pcm_prepare_playback,
- .trigger = snd_ca0106_pcm_trigger_playback,
- .pointer = snd_ca0106_pcm_pointer_playback,
-};
-
-static struct snd_pcm_ops snd_ca0106_capture_0_ops = {
- .open = snd_ca0106_pcm_open_0_capture,
- .close = snd_ca0106_pcm_close_capture,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ca0106_pcm_hw_params_capture,
- .hw_free = snd_ca0106_pcm_hw_free_capture,
- .prepare = snd_ca0106_pcm_prepare_capture,
- .trigger = snd_ca0106_pcm_trigger_capture,
- .pointer = snd_ca0106_pcm_pointer_capture,
-};
-
-static struct snd_pcm_ops snd_ca0106_capture_1_ops = {
- .open = snd_ca0106_pcm_open_1_capture,
- .close = snd_ca0106_pcm_close_capture,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ca0106_pcm_hw_params_capture,
- .hw_free = snd_ca0106_pcm_hw_free_capture,
- .prepare = snd_ca0106_pcm_prepare_capture,
- .trigger = snd_ca0106_pcm_trigger_capture,
- .pointer = snd_ca0106_pcm_pointer_capture,
-};
-
-static struct snd_pcm_ops snd_ca0106_capture_2_ops = {
- .open = snd_ca0106_pcm_open_2_capture,
- .close = snd_ca0106_pcm_close_capture,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ca0106_pcm_hw_params_capture,
- .hw_free = snd_ca0106_pcm_hw_free_capture,
- .prepare = snd_ca0106_pcm_prepare_capture,
- .trigger = snd_ca0106_pcm_trigger_capture,
- .pointer = snd_ca0106_pcm_pointer_capture,
-};
-
-static struct snd_pcm_ops snd_ca0106_capture_3_ops = {
- .open = snd_ca0106_pcm_open_3_capture,
- .close = snd_ca0106_pcm_close_capture,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ca0106_pcm_hw_params_capture,
- .hw_free = snd_ca0106_pcm_hw_free_capture,
- .prepare = snd_ca0106_pcm_prepare_capture,
- .trigger = snd_ca0106_pcm_trigger_capture,
- .pointer = snd_ca0106_pcm_pointer_capture,
-};
-
-static struct snd_pcm_ops snd_ca0106_playback_center_lfe_ops = {
- .open = snd_ca0106_pcm_open_playback_center_lfe,
- .close = snd_ca0106_pcm_close_playback,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ca0106_pcm_hw_params_playback,
- .hw_free = snd_ca0106_pcm_hw_free_playback,
- .prepare = snd_ca0106_pcm_prepare_playback,
- .trigger = snd_ca0106_pcm_trigger_playback,
- .pointer = snd_ca0106_pcm_pointer_playback,
-};
-
-static struct snd_pcm_ops snd_ca0106_playback_unknown_ops = {
- .open = snd_ca0106_pcm_open_playback_unknown,
- .close = snd_ca0106_pcm_close_playback,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ca0106_pcm_hw_params_playback,
- .hw_free = snd_ca0106_pcm_hw_free_playback,
- .prepare = snd_ca0106_pcm_prepare_playback,
- .trigger = snd_ca0106_pcm_trigger_playback,
- .pointer = snd_ca0106_pcm_pointer_playback,
-};
-
-static struct snd_pcm_ops snd_ca0106_playback_rear_ops = {
- .open = snd_ca0106_pcm_open_playback_rear,
- .close = snd_ca0106_pcm_close_playback,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ca0106_pcm_hw_params_playback,
- .hw_free = snd_ca0106_pcm_hw_free_playback,
- .prepare = snd_ca0106_pcm_prepare_playback,
- .trigger = snd_ca0106_pcm_trigger_playback,
- .pointer = snd_ca0106_pcm_pointer_playback,
-};
-
-
-static unsigned short snd_ca0106_ac97_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- struct snd_ca0106 *emu = ac97->private_data;
- unsigned long flags;
- unsigned short val;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- outb(reg, emu->port + AC97ADDRESS);
- val = inw(emu->port + AC97DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- return val;
-}
-
-static void snd_ca0106_ac97_write(struct snd_ac97 *ac97,
- unsigned short reg, unsigned short val)
-{
- struct snd_ca0106 *emu = ac97->private_data;
- unsigned long flags;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- outb(reg, emu->port + AC97ADDRESS);
- outw(val, emu->port + AC97DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-static int snd_ca0106_ac97(struct snd_ca0106 *chip)
-{
- struct snd_ac97_bus *pbus;
- struct snd_ac97_template ac97;
- int err;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_ca0106_ac97_write,
- .read = snd_ca0106_ac97_read,
- };
-
- if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
- return err;
- pbus->no_vra = 1; /* we don't need VRA */
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = chip;
- ac97.scaps = AC97_SCAP_NO_SPDIF;
- return snd_ac97_mixer(pbus, &ac97, &chip->ac97);
-}
-
-static void ca0106_stop_chip(struct snd_ca0106 *chip);
-
-static int snd_ca0106_free(struct snd_ca0106 *chip)
-{
- if (chip->res_port != NULL) {
- /* avoid access to already used hardware */
- ca0106_stop_chip(chip);
- }
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
- // release the data
-#if 1
- if (chip->buffer.area)
- snd_dma_free_pages(&chip->buffer);
-#endif
-
- // release the i/o port
- release_and_free_resource(chip->res_port);
-
- pci_disable_device(chip->pci);
- kfree(chip);
- return 0;
-}
-
-static int snd_ca0106_dev_free(struct snd_device *device)
-{
- struct snd_ca0106 *chip = device->device_data;
- return snd_ca0106_free(chip);
-}
-
-static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id)
-{
- unsigned int status;
-
- struct snd_ca0106 *chip = dev_id;
- int i;
- int mask;
- unsigned int stat76;
- struct snd_ca0106_channel *pchannel;
-
- status = inl(chip->port + IPR);
- if (! status)
- return IRQ_NONE;
-
- stat76 = snd_ca0106_ptr_read(chip, EXTENDED_INT, 0);
- /*
- snd_printk(KERN_DEBUG "interrupt status = 0x%08x, stat76=0x%08x\n",
- status, stat76);
- snd_printk(KERN_DEBUG "ptr=0x%08x\n",
- snd_ca0106_ptr_read(chip, PLAYBACK_POINTER, 0));
- */
- mask = 0x11; /* 0x1 for one half, 0x10 for the other half period. */
- for(i = 0; i < 4; i++) {
- pchannel = &(chip->playback_channels[i]);
- if (stat76 & mask) {
-/* FIXME: Select the correct substream for period elapsed */
- if(pchannel->use) {
- snd_pcm_period_elapsed(pchannel->epcm->substream);
- //printk(KERN_INFO "interrupt [%d] used\n", i);
- }
- }
- //printk(KERN_INFO "channel=%p\n",pchannel);
- //printk(KERN_INFO "interrupt stat76[%d] = %08x, use=%d, channel=%d\n", i, stat76, pchannel->use, pchannel->number);
- mask <<= 1;
- }
- mask = 0x110000; /* 0x1 for one half, 0x10 for the other half period. */
- for(i = 0; i < 4; i++) {
- pchannel = &(chip->capture_channels[i]);
- if (stat76 & mask) {
-/* FIXME: Select the correct substream for period elapsed */
- if(pchannel->use) {
- snd_pcm_period_elapsed(pchannel->epcm->substream);
- //printk(KERN_INFO "interrupt [%d] used\n", i);
- }
- }
- //printk(KERN_INFO "channel=%p\n",pchannel);
- //printk(KERN_INFO "interrupt stat76[%d] = %08x, use=%d, channel=%d\n", i, stat76, pchannel->use, pchannel->number);
- mask <<= 1;
- }
-
- snd_ca0106_ptr_write(chip, EXTENDED_INT, 0, stat76);
-
- if (chip->midi.dev_id &&
- (status & (chip->midi.ipr_tx|chip->midi.ipr_rx))) {
- if (chip->midi.interrupt)
- chip->midi.interrupt(&chip->midi, status);
- else
- chip->midi.interrupt_disable(&chip->midi, chip->midi.tx_enable | chip->midi.rx_enable);
- }
-
- // acknowledge the interrupt if necessary
- outl(status, chip->port+IPR);
-
- return IRQ_HANDLED;
-}
-
-static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device)
-{
- struct snd_pcm *pcm;
- struct snd_pcm_substream *substream;
- int err;
-
- err = snd_pcm_new(emu->card, "ca0106", device, 1, 1, &pcm);
- if (err < 0)
- return err;
-
- pcm->private_data = emu;
-
- switch (device) {
- case 0:
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_front_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_0_ops);
- break;
- case 1:
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_rear_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_1_ops);
- break;
- case 2:
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_center_lfe_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_2_ops);
- break;
- case 3:
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_unknown_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_3_ops);
- break;
- }
-
- pcm->info_flags = 0;
- strcpy(pcm->name, "CA0106");
-
- for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
- substream;
- substream = substream->next) {
- if ((err = snd_pcm_lib_preallocate_pages(substream,
- SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(emu->pci),
- 64*1024, 64*1024)) < 0) /* FIXME: 32*1024 for sound buffer, between 32and64 for Periods table. */
- return err;
- }
-
- for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
- substream;
- substream = substream->next) {
- if ((err = snd_pcm_lib_preallocate_pages(substream,
- SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(emu->pci),
- 64*1024, 64*1024)) < 0)
- return err;
- }
-
- emu->pcm[device] = pcm;
-
- return 0;
-}
-
-#define SPI_REG(reg, value) (((reg) << SPI_REG_SHIFT) | (value))
-static unsigned int spi_dac_init[] = {
- SPI_REG(SPI_LDA1_REG, SPI_DA_BIT_0dB), /* 0dB dig. attenuation */
- SPI_REG(SPI_RDA1_REG, SPI_DA_BIT_0dB),
- SPI_REG(SPI_PL_REG, SPI_PL_BIT_L_L | SPI_PL_BIT_R_R | SPI_IZD_BIT),
- SPI_REG(SPI_FMT_REG, SPI_FMT_BIT_I2S | SPI_IWL_BIT_24),
- SPI_REG(SPI_LDA2_REG, SPI_DA_BIT_0dB),
- SPI_REG(SPI_RDA2_REG, SPI_DA_BIT_0dB),
- SPI_REG(SPI_LDA3_REG, SPI_DA_BIT_0dB),
- SPI_REG(SPI_RDA3_REG, SPI_DA_BIT_0dB),
- SPI_REG(SPI_MASTDA_REG, SPI_DA_BIT_0dB),
- SPI_REG(9, 0x00),
- SPI_REG(SPI_MS_REG, SPI_DACD0_BIT | SPI_DACD1_BIT | SPI_DACD2_BIT),
- SPI_REG(12, 0x00),
- SPI_REG(SPI_LDA4_REG, SPI_DA_BIT_0dB),
- SPI_REG(SPI_RDA4_REG, SPI_DA_BIT_0dB | SPI_DA_BIT_UPDATE),
- SPI_REG(SPI_DACD4_REG, SPI_DACD4_BIT),
-};
-
-static unsigned int i2c_adc_init[][2] = {
- { 0x17, 0x00 }, /* Reset */
- { 0x07, 0x00 }, /* Timeout */
- { 0x0b, 0x22 }, /* Interface control */
- { 0x0c, 0x22 }, /* Master mode control */
- { 0x0d, 0x08 }, /* Powerdown control */
- { 0x0e, 0xcf }, /* Attenuation Left 0x01 = -103dB, 0xff = 24dB */
- { 0x0f, 0xcf }, /* Attenuation Right 0.5dB steps */
- { 0x10, 0x7b }, /* ALC Control 1 */
- { 0x11, 0x00 }, /* ALC Control 2 */
- { 0x12, 0x32 }, /* ALC Control 3 */
- { 0x13, 0x00 }, /* Noise gate control */
- { 0x14, 0xa6 }, /* Limiter control */
- { 0x15, ADC_MUX_LINEIN }, /* ADC Mixer control */
-};
-
-static void ca0106_init_chip(struct snd_ca0106 *chip, int resume)
-{
- int ch;
- unsigned int def_bits;
-
- outl(0, chip->port + INTE);
-
- /*
- * Init to 0x02109204 :
- * Clock accuracy = 0 (1000ppm)
- * Sample Rate = 2 (48kHz)
- * Audio Channel = 1 (Left of 2)
- * Source Number = 0 (Unspecified)
- * Generation Status = 1 (Original for Cat Code 12)
- * Cat Code = 12 (Digital Signal Mixer)
- * Mode = 0 (Mode 0)
- * Emphasis = 0 (None)
- * CP = 1 (Copyright unasserted)
- * AN = 0 (Audio data)
- * P = 0 (Consumer)
- */
- def_bits =
- SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
- SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
- SPCS_GENERATIONSTATUS | 0x00001200 |
- 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT;
- if (!resume) {
- chip->spdif_str_bits[0] = chip->spdif_bits[0] = def_bits;
- chip->spdif_str_bits[1] = chip->spdif_bits[1] = def_bits;
- chip->spdif_str_bits[2] = chip->spdif_bits[2] = def_bits;
- chip->spdif_str_bits[3] = chip->spdif_bits[3] = def_bits;
- }
- /* Only SPCS1 has been tested */
- snd_ca0106_ptr_write(chip, SPCS1, 0, chip->spdif_str_bits[1]);
- snd_ca0106_ptr_write(chip, SPCS0, 0, chip->spdif_str_bits[0]);
- snd_ca0106_ptr_write(chip, SPCS2, 0, chip->spdif_str_bits[2]);
- snd_ca0106_ptr_write(chip, SPCS3, 0, chip->spdif_str_bits[3]);
-
- snd_ca0106_ptr_write(chip, PLAYBACK_MUTE, 0, 0x00fc0000);
- snd_ca0106_ptr_write(chip, CAPTURE_MUTE, 0, 0x00fc0000);
-
- /* Write 0x8000 to AC97_REC_GAIN to mute it. */
- outb(AC97_REC_GAIN, chip->port + AC97ADDRESS);
- outw(0x8000, chip->port + AC97DATA);
-#if 0 /* FIXME: what are these? */
- snd_ca0106_ptr_write(chip, SPCS0, 0, 0x2108006);
- snd_ca0106_ptr_write(chip, 0x42, 0, 0x2108006);
- snd_ca0106_ptr_write(chip, 0x43, 0, 0x2108006);
- snd_ca0106_ptr_write(chip, 0x44, 0, 0x2108006);
-#endif
-
- /* OSS drivers set this. */
- /* snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0xf0f003f); */
-
- /* Analog or Digital output */
- snd_ca0106_ptr_write(chip, SPDIF_SELECT1, 0, 0xf);
- /* 0x0b000000 for digital, 0x000b0000 for analog, from win2000 drivers.
- * Use 0x000f0000 for surround71
- */
- snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0x000f0000);
-
- chip->spdif_enable = 0; /* Set digital SPDIF output off */
- /*snd_ca0106_ptr_write(chip, 0x45, 0, 0);*/ /* Analogue out */
- /*snd_ca0106_ptr_write(chip, 0x45, 0, 0xf00);*/ /* Digital out */
-
- /* goes to 0x40c80000 when doing SPDIF IN/OUT */
- snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 0, 0x40c81000);
- /* (Mute) CAPTURE feedback into PLAYBACK volume.
- * Only lower 16 bits matter.
- */
- snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 1, 0xffffffff);
- /* SPDIF IN Volume */
- snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 2, 0x30300000);
- /* SPDIF IN Volume, 0x70 = (vol & 0x3f) | 0x40 */
- snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 3, 0x00700000);
-
- snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING1, 0, 0x32765410);
- snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING2, 0, 0x76767676);
- snd_ca0106_ptr_write(chip, CAPTURE_ROUTING1, 0, 0x32765410);
- snd_ca0106_ptr_write(chip, CAPTURE_ROUTING2, 0, 0x76767676);
-
- for (ch = 0; ch < 4; ch++) {
- /* Only high 16 bits matter */
- snd_ca0106_ptr_write(chip, CAPTURE_VOLUME1, ch, 0x30303030);
- snd_ca0106_ptr_write(chip, CAPTURE_VOLUME2, ch, 0x30303030);
-#if 0 /* Mute */
- snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0x40404040);
- snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0x40404040);
- snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0xffffffff);
- snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0xffffffff);
-#endif
- }
- if (chip->details->i2c_adc == 1) {
- /* Select MIC, Line in, TAD in, AUX in */
- snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4);
- /* Default to CAPTURE_SOURCE to i2s in */
- if (!resume)
- chip->capture_source = 3;
- } else if (chip->details->ac97 == 1) {
- /* Default to AC97 in */
- snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x444400e4);
- /* Default to CAPTURE_SOURCE to AC97 in */
- if (!resume)
- chip->capture_source = 4;
- } else {
- /* Select MIC, Line in, TAD in, AUX in */
- snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4);
- /* Default to Set CAPTURE_SOURCE to i2s in */
- if (!resume)
- chip->capture_source = 3;
- }
-
- if (chip->details->gpio_type == 2) {
- /* The SB0438 use GPIO differently. */
- /* FIXME: Still need to find out what the other GPIO bits do.
- * E.g. For digital spdif out.
- */
- outl(0x0, chip->port+GPIO);
- /* outl(0x00f0e000, chip->port+GPIO); */ /* Analog */
- outl(0x005f5301, chip->port+GPIO); /* Analog */
- } else if (chip->details->gpio_type == 1) {
- /* The SB0410 and SB0413 use GPIO differently. */
- /* FIXME: Still need to find out what the other GPIO bits do.
- * E.g. For digital spdif out.
- */
- outl(0x0, chip->port+GPIO);
- /* outl(0x00f0e000, chip->port+GPIO); */ /* Analog */
- outl(0x005f5301, chip->port+GPIO); /* Analog */
- } else {
- outl(0x0, chip->port+GPIO);
- outl(0x005f03a3, chip->port+GPIO); /* Analog */
- /* outl(0x005f02a2, chip->port+GPIO); */ /* SPDIF */
- }
- snd_ca0106_intr_enable(chip, 0x105); /* Win2000 uses 0x1e0 */
-
- /* outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG); */
- /* 0x1000 causes AC3 to fails. Maybe it effects 24 bit output. */
- /* outl(0x00001409, chip->port+HCFG); */
- /* outl(0x00000009, chip->port+HCFG); */
- /* AC97 2.0, Enable outputs. */
- outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG);
-
- if (chip->details->i2c_adc == 1) {
- /* The SB0410 and SB0413 use I2C to control ADC. */
- int size, n;
-
- size = ARRAY_SIZE(i2c_adc_init);
- /* snd_printk(KERN_DEBUG "I2C:array size=0x%x\n", size); */
- for (n = 0; n < size; n++)
- snd_ca0106_i2c_write(chip, i2c_adc_init[n][0],
- i2c_adc_init[n][1]);
- for (n = 0; n < 4; n++) {
- chip->i2c_capture_volume[n][0] = 0xcf;
- chip->i2c_capture_volume[n][1] = 0xcf;
- }
- chip->i2c_capture_source = 2; /* Line in */
- /* Enable Line-in capture. MIC in currently untested. */
- /* snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); */
- }
-
- if (chip->details->spi_dac) {
- /* The SB0570 use SPI to control DAC. */
- int size, n;
-
- size = ARRAY_SIZE(spi_dac_init);
- for (n = 0; n < size; n++) {
- int reg = spi_dac_init[n] >> SPI_REG_SHIFT;
-
- snd_ca0106_spi_write(chip, spi_dac_init[n]);
- if (reg < ARRAY_SIZE(chip->spi_dac_reg))
- chip->spi_dac_reg[reg] = spi_dac_init[n];
- }
-
- /* Enable front dac only */
- snd_ca0106_pcm_power_dac(chip, PCM_FRONT_CHANNEL, 1);
- }
-}
-
-static void ca0106_stop_chip(struct snd_ca0106 *chip)
-{
- /* disable interrupts */
- snd_ca0106_ptr_write(chip, BASIC_INTERRUPT, 0, 0);
- outl(0, chip->port + INTE);
- snd_ca0106_ptr_write(chip, EXTENDED_INT_MASK, 0, 0);
- udelay(1000);
- /* disable audio */
- /* outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG); */
- outl(0, chip->port + HCFG);
- /* FIXME: We need to stop and DMA transfers here.
- * But as I am not sure how yet, we cannot from the dma pages.
- * So we can fix: snd-malloc: Memory leak? pages not freed = 8
- */
-}
-
-static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
- struct pci_dev *pci,
- struct snd_ca0106 **rchip)
-{
- struct snd_ca0106 *chip;
- struct snd_ca0106_details *c;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_ca0106_dev_free,
- };
-
- *rchip = NULL;
-
- err = pci_enable_device(pci);
- if (err < 0)
- return err;
- if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0) {
- printk(KERN_ERR "error to set 32bit mask DMA\n");
- pci_disable_device(pci);
- return -ENXIO;
- }
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
-
- spin_lock_init(&chip->emu_lock);
-
- chip->port = pci_resource_start(pci, 0);
- chip->res_port = request_region(chip->port, 0x20, "snd_ca0106");
- if (!chip->res_port) {
- snd_ca0106_free(chip);
- printk(KERN_ERR "cannot allocate the port\n");
- return -EBUSY;
- }
-
- if (request_irq(pci->irq, snd_ca0106_interrupt,
- IRQF_SHARED, KBUILD_MODNAME, chip)) {
- snd_ca0106_free(chip);
- printk(KERN_ERR "cannot grab irq\n");
- return -EBUSY;
- }
- chip->irq = pci->irq;
-
- /* This stores the periods table. */
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
- 1024, &chip->buffer) < 0) {
- snd_ca0106_free(chip);
- return -ENOMEM;
- }
-
- pci_set_master(pci);
- /* read serial */
- pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
- pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
- printk(KERN_INFO "snd-ca0106: Model %04x Rev %08x Serial %08x\n",
- chip->model, pci->revision, chip->serial);
- strcpy(card->driver, "CA0106");
- strcpy(card->shortname, "CA0106");
-
- for (c = ca0106_chip_details; c->serial; c++) {
- if (subsystem[dev]) {
- if (c->serial == subsystem[dev])
- break;
- } else if (c->serial == chip->serial)
- break;
- }
- chip->details = c;
- if (subsystem[dev]) {
- printk(KERN_INFO "snd-ca0106: Sound card name=%s, "
- "subsystem=0x%x. Forced to subsystem=0x%x\n",
- c->name, chip->serial, subsystem[dev]);
- }
-
- sprintf(card->longname, "%s at 0x%lx irq %i",
- c->name, chip->port, chip->irq);
-
- ca0106_init_chip(chip, 0);
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
- if (err < 0) {
- snd_ca0106_free(chip);
- return err;
- }
- *rchip = chip;
- return 0;
-}
-
-
-static void ca0106_midi_interrupt_enable(struct snd_ca_midi *midi, int intr)
-{
- snd_ca0106_intr_enable((struct snd_ca0106 *)(midi->dev_id), intr);
-}
-
-static void ca0106_midi_interrupt_disable(struct snd_ca_midi *midi, int intr)
-{
- snd_ca0106_intr_disable((struct snd_ca0106 *)(midi->dev_id), intr);
-}
-
-static unsigned char ca0106_midi_read(struct snd_ca_midi *midi, int idx)
-{
- return (unsigned char)snd_ca0106_ptr_read((struct snd_ca0106 *)(midi->dev_id),
- midi->port + idx, 0);
-}
-
-static void ca0106_midi_write(struct snd_ca_midi *midi, int data, int idx)
-{
- snd_ca0106_ptr_write((struct snd_ca0106 *)(midi->dev_id), midi->port + idx, 0, data);
-}
-
-static struct snd_card *ca0106_dev_id_card(void *dev_id)
-{
- return ((struct snd_ca0106 *)dev_id)->card;
-}
-
-static int ca0106_dev_id_port(void *dev_id)
-{
- return ((struct snd_ca0106 *)dev_id)->port;
-}
-
-static int __devinit snd_ca0106_midi(struct snd_ca0106 *chip, unsigned int channel)
-{
- struct snd_ca_midi *midi;
- char *name;
- int err;
-
- if (channel == CA0106_MIDI_CHAN_B) {
- name = "CA0106 MPU-401 (UART) B";
- midi = &chip->midi2;
- midi->tx_enable = INTE_MIDI_TX_B;
- midi->rx_enable = INTE_MIDI_RX_B;
- midi->ipr_tx = IPR_MIDI_TX_B;
- midi->ipr_rx = IPR_MIDI_RX_B;
- midi->port = MIDI_UART_B_DATA;
- } else {
- name = "CA0106 MPU-401 (UART)";
- midi = &chip->midi;
- midi->tx_enable = INTE_MIDI_TX_A;
- midi->rx_enable = INTE_MIDI_TX_B;
- midi->ipr_tx = IPR_MIDI_TX_A;
- midi->ipr_rx = IPR_MIDI_RX_A;
- midi->port = MIDI_UART_A_DATA;
- }
-
- midi->reset = CA0106_MPU401_RESET;
- midi->enter_uart = CA0106_MPU401_ENTER_UART;
- midi->ack = CA0106_MPU401_ACK;
-
- midi->input_avail = CA0106_MIDI_INPUT_AVAIL;
- midi->output_ready = CA0106_MIDI_OUTPUT_READY;
-
- midi->channel = channel;
-
- midi->interrupt_enable = ca0106_midi_interrupt_enable;
- midi->interrupt_disable = ca0106_midi_interrupt_disable;
-
- midi->read = ca0106_midi_read;
- midi->write = ca0106_midi_write;
-
- midi->get_dev_id_card = ca0106_dev_id_card;
- midi->get_dev_id_port = ca0106_dev_id_port;
-
- midi->dev_id = chip;
-
- if ((err = ca_midi_init(chip, midi, 0, name)) < 0)
- return err;
-
- return 0;
-}
-
-
-static int __devinit snd_ca0106_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct snd_ca0106 *chip;
- int i, err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- err = snd_ca0106_create(dev, card, pci, &chip);
- if (err < 0)
- goto error;
- card->private_data = chip;
-
- for (i = 0; i < 4; i++) {
- err = snd_ca0106_pcm(chip, i);
- if (err < 0)
- goto error;
- }
-
- if (chip->details->ac97 == 1) {
- /* The SB0410 and SB0413 do not have an AC97 chip. */
- err = snd_ca0106_ac97(chip);
- if (err < 0)
- goto error;
- }
- err = snd_ca0106_mixer(chip);
- if (err < 0)
- goto error;
-
- snd_printdd("ca0106: probe for MIDI channel A ...");
- err = snd_ca0106_midi(chip, CA0106_MIDI_CHAN_A);
- if (err < 0)
- goto error;
- snd_printdd(" done.\n");
-
-#ifdef CONFIG_PROC_FS
- snd_ca0106_proc_init(chip);
-#endif
-
- snd_card_set_dev(card, &pci->dev);
-
- err = snd_card_register(card);
- if (err < 0)
- goto error;
-
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-
- error:
- snd_card_free(card);
- return err;
-}
-
-static void __devexit snd_ca0106_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-#ifdef CONFIG_PM
-static int snd_ca0106_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_ca0106 *chip = card->private_data;
- int i;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- for (i = 0; i < 4; i++)
- snd_pcm_suspend_all(chip->pcm[i]);
- if (chip->details->ac97)
- snd_ac97_suspend(chip->ac97);
- snd_ca0106_mixer_suspend(chip);
-
- ca0106_stop_chip(chip);
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int snd_ca0106_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_ca0106 *chip = card->private_data;
- int i;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
-
- if (pci_enable_device(pci) < 0) {
- snd_card_disconnect(card);
- return -EIO;
- }
-
- pci_set_master(pci);
-
- ca0106_init_chip(chip, 1);
-
- if (chip->details->ac97)
- snd_ac97_resume(chip->ac97);
- snd_ca0106_mixer_resume(chip);
- if (chip->details->spi_dac) {
- for (i = 0; i < ARRAY_SIZE(chip->spi_dac_reg); i++)
- snd_ca0106_spi_write(chip, chip->spi_dac_reg[i]);
- }
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif
-
-// PCI IDs
-static DEFINE_PCI_DEVICE_TABLE(snd_ca0106_ids) = {
- { PCI_VDEVICE(CREATIVE, 0x0007), 0 }, /* Audigy LS or Live 24bit */
- { 0, }
-};
-MODULE_DEVICE_TABLE(pci, snd_ca0106_ids);
-
-// pci_driver definition
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_ca0106_ids,
- .probe = snd_ca0106_probe,
- .remove = __devexit_p(snd_ca0106_remove),
-#ifdef CONFIG_PM
- .suspend = snd_ca0106_suspend,
- .resume = snd_ca0106_resume,
-#endif
-};
-
-// initialization of the module
-static int __init alsa_card_ca0106_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-// clean up the module
-static void __exit alsa_card_ca0106_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_ca0106_init)
-module_exit(alsa_card_ca0106_exit)
diff --git a/ANDROID_3.4.5/sound/pci/ca0106/ca0106_mixer.c b/ANDROID_3.4.5/sound/pci/ca0106/ca0106_mixer.c
deleted file mode 100644
index 84f3f924..00000000
--- a/ANDROID_3.4.5/sound/pci/ca0106/ca0106_mixer.c
+++ /dev/null
@@ -1,956 +0,0 @@
-/*
- * Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
- * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
- * Version: 0.0.18
- *
- * FEATURES currently supported:
- * See ca0106_main.c for features.
- *
- * Changelog:
- * Support interrupts per period.
- * Removed noise from Center/LFE channel when in Analog mode.
- * Rename and remove mixer controls.
- * 0.0.6
- * Use separate card based DMA buffer for periods table list.
- * 0.0.7
- * Change remove and rename ctrls into lists.
- * 0.0.8
- * Try to fix capture sources.
- * 0.0.9
- * Fix AC3 output.
- * Enable S32_LE format support.
- * 0.0.10
- * Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
- * 0.0.11
- * Add Model name recognition.
- * 0.0.12
- * Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
- * Remove redundent "voice" handling.
- * 0.0.13
- * Single trigger call for multi channels.
- * 0.0.14
- * Set limits based on what the sound card hardware can do.
- * playback periods_min=2, periods_max=8
- * capture hw constraints require period_size = n * 64 bytes.
- * playback hw constraints require period_size = n * 64 bytes.
- * 0.0.15
- * Separated ca0106.c into separate functional .c files.
- * 0.0.16
- * Modified Copyright message.
- * 0.0.17
- * Implement Mic and Line in Capture.
- * 0.0.18
- * Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
- *
- * This code was initially based on code from ALSA's emu10k1x.c which is:
- * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/moduleparam.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/info.h>
-#include <sound/tlv.h>
-#include <asm/io.h>
-
-#include "ca0106.h"
-
-static void ca0106_spdif_enable(struct snd_ca0106 *emu)
-{
- unsigned int val;
-
- if (emu->spdif_enable) {
- /* Digital */
- snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
- snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
- val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000;
- snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
- val = inl(emu->port + GPIO) & ~0x101;
- outl(val, emu->port + GPIO);
-
- } else {
- /* Analog */
- snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
- snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000);
- val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000;
- snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
- val = inl(emu->port + GPIO) | 0x101;
- outl(val, emu->port + GPIO);
- }
-}
-
-static void ca0106_set_capture_source(struct snd_ca0106 *emu)
-{
- unsigned int val = emu->capture_source;
- unsigned int source, mask;
- source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
- mask = snd_ca0106_ptr_read(emu, CAPTURE_SOURCE, 0) & 0xffff;
- snd_ca0106_ptr_write(emu, CAPTURE_SOURCE, 0, source | mask);
-}
-
-static void ca0106_set_i2c_capture_source(struct snd_ca0106 *emu,
- unsigned int val, int force)
-{
- unsigned int ngain, ogain;
- u32 source;
-
- snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
- ngain = emu->i2c_capture_volume[val][0]; /* Left */
- ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
- if (force || ngain != ogain)
- snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ngain & 0xff);
- ngain = emu->i2c_capture_volume[val][1]; /* Right */
- ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Right */
- if (force || ngain != ogain)
- snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ngain & 0xff);
- source = 1 << val;
- snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */
- emu->i2c_capture_source = val;
-}
-
-static void ca0106_set_capture_mic_line_in(struct snd_ca0106 *emu)
-{
- u32 tmp;
-
- if (emu->capture_mic_line_in) {
- /* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
- tmp = inl(emu->port+GPIO) & ~0x400;
- tmp = tmp | 0x400;
- outl(tmp, emu->port+GPIO);
- /* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); */
- } else {
- /* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
- tmp = inl(emu->port+GPIO) & ~0x400;
- outl(tmp, emu->port+GPIO);
- /* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN); */
- }
-}
-
-static void ca0106_set_spdif_bits(struct snd_ca0106 *emu, int idx)
-{
- snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, emu->spdif_str_bits[idx]);
-}
-
-/*
- */
-static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1);
-static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1);
-
-#define snd_ca0106_shared_spdif_info snd_ctl_boolean_mono_info
-
-static int snd_ca0106_shared_spdif_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = emu->spdif_enable;
- return 0;
-}
-
-static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change = 0;
-
- val = !!ucontrol->value.integer.value[0];
- change = (emu->spdif_enable != val);
- if (change) {
- emu->spdif_enable = val;
- ca0106_spdif_enable(emu);
- }
- return change;
-}
-
-static int snd_ca0106_capture_source_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[6] = {
- "IEC958 out", "i2s mixer out", "IEC958 in", "i2s in", "AC97 in", "SRC out"
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 6;
- if (uinfo->value.enumerated.item > 5)
- uinfo->value.enumerated.item = 5;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ca0106_capture_source_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = emu->capture_source;
- return 0;
-}
-
-static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change = 0;
-
- val = ucontrol->value.enumerated.item[0] ;
- if (val >= 6)
- return -EINVAL;
- change = (emu->capture_source != val);
- if (change) {
- emu->capture_source = val;
- ca0106_set_capture_source(emu);
- }
- return change;
-}
-
-static int snd_ca0106_i2c_capture_source_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[6] = {
- "Phone", "Mic", "Line in", "Aux"
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 4;
- if (uinfo->value.enumerated.item > 3)
- uinfo->value.enumerated.item = 3;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ca0106_i2c_capture_source_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = emu->i2c_capture_source;
- return 0;
-}
-
-static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int source_id;
- int change = 0;
- /* If the capture source has changed,
- * update the capture volume from the cached value
- * for the particular source.
- */
- source_id = ucontrol->value.enumerated.item[0] ;
- if (source_id >= 4)
- return -EINVAL;
- change = (emu->i2c_capture_source != source_id);
- if (change) {
- ca0106_set_i2c_capture_source(emu, source_id, 0);
- }
- return change;
-}
-
-static int snd_ca0106_capture_line_in_side_out_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[2] = { "Side out", "Line in" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item > 1)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[2] = { "Line in", "Mic in" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item > 1)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ca0106_capture_mic_line_in_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = emu->capture_mic_line_in;
- return 0;
-}
-
-static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change = 0;
-
- val = ucontrol->value.enumerated.item[0] ;
- if (val > 1)
- return -EINVAL;
- change = (emu->capture_mic_line_in != val);
- if (change) {
- emu->capture_mic_line_in = val;
- ca0106_set_capture_mic_line_in(emu);
- }
- return change;
-}
-
-static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Shared Mic/Line in Capture Switch",
- .info = snd_ca0106_capture_mic_line_in_info,
- .get = snd_ca0106_capture_mic_line_in_get,
- .put = snd_ca0106_capture_mic_line_in_put
-};
-
-static struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Shared Line in/Side out Capture Switch",
- .info = snd_ca0106_capture_line_in_side_out_info,
- .get = snd_ca0106_capture_mic_line_in_get,
- .put = snd_ca0106_capture_mic_line_in_put
-};
-
-
-static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static void decode_spdif_bits(unsigned char *status, unsigned int bits)
-{
- status[0] = (bits >> 0) & 0xff;
- status[1] = (bits >> 8) & 0xff;
- status[2] = (bits >> 16) & 0xff;
- status[3] = (bits >> 24) & 0xff;
-}
-
-static int snd_ca0106_spdif_get_default(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-
- decode_spdif_bits(ucontrol->value.iec958.status,
- emu->spdif_bits[idx]);
- return 0;
-}
-
-static int snd_ca0106_spdif_get_stream(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-
- decode_spdif_bits(ucontrol->value.iec958.status,
- emu->spdif_str_bits[idx]);
- return 0;
-}
-
-static int snd_ca0106_spdif_get_mask(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.iec958.status[0] = 0xff;
- ucontrol->value.iec958.status[1] = 0xff;
- ucontrol->value.iec958.status[2] = 0xff;
- ucontrol->value.iec958.status[3] = 0xff;
- return 0;
-}
-
-static unsigned int encode_spdif_bits(unsigned char *status)
-{
- return ((unsigned int)status[0] << 0) |
- ((unsigned int)status[1] << 8) |
- ((unsigned int)status[2] << 16) |
- ((unsigned int)status[3] << 24);
-}
-
-static int snd_ca0106_spdif_put_default(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- unsigned int val;
-
- val = encode_spdif_bits(ucontrol->value.iec958.status);
- if (val != emu->spdif_bits[idx]) {
- emu->spdif_bits[idx] = val;
- /* FIXME: this isn't safe, but needed to keep the compatibility
- * with older alsa-lib config
- */
- emu->spdif_str_bits[idx] = val;
- ca0106_set_spdif_bits(emu, idx);
- return 1;
- }
- return 0;
-}
-
-static int snd_ca0106_spdif_put_stream(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- unsigned int val;
-
- val = encode_spdif_bits(ucontrol->value.iec958.status);
- if (val != emu->spdif_str_bits[idx]) {
- emu->spdif_str_bits[idx] = val;
- ca0106_set_spdif_bits(emu, idx);
- return 1;
- }
- return 0;
-}
-
-static int snd_ca0106_volume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 255;
- return 0;
-}
-
-static int snd_ca0106_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int value;
- int channel_id, reg;
-
- channel_id = (kcontrol->private_value >> 8) & 0xff;
- reg = kcontrol->private_value & 0xff;
-
- value = snd_ca0106_ptr_read(emu, reg, channel_id);
- ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
- ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
- return 0;
-}
-
-static int snd_ca0106_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int oval, nval;
- int channel_id, reg;
-
- channel_id = (kcontrol->private_value >> 8) & 0xff;
- reg = kcontrol->private_value & 0xff;
-
- oval = snd_ca0106_ptr_read(emu, reg, channel_id);
- nval = ((0xff - ucontrol->value.integer.value[0]) << 24) |
- ((0xff - ucontrol->value.integer.value[1]) << 16);
- nval |= ((0xff - ucontrol->value.integer.value[0]) << 8) |
- ((0xff - ucontrol->value.integer.value[1]) );
- if (oval == nval)
- return 0;
- snd_ca0106_ptr_write(emu, reg, channel_id, nval);
- return 1;
-}
-
-static int snd_ca0106_i2c_volume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 255;
- return 0;
-}
-
-static int snd_ca0106_i2c_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
- int source_id;
-
- source_id = kcontrol->private_value;
-
- ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0];
- ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1];
- return 0;
-}
-
-static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int ogain;
- unsigned int ngain;
- int source_id;
- int change = 0;
-
- source_id = kcontrol->private_value;
- ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
- ngain = ucontrol->value.integer.value[0];
- if (ngain > 0xff)
- return -EINVAL;
- if (ogain != ngain) {
- if (emu->i2c_capture_source == source_id)
- snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) );
- emu->i2c_capture_volume[source_id][0] = ucontrol->value.integer.value[0];
- change = 1;
- }
- ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
- ngain = ucontrol->value.integer.value[1];
- if (ngain > 0xff)
- return -EINVAL;
- if (ogain != ngain) {
- if (emu->i2c_capture_source == source_id)
- snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
- emu->i2c_capture_volume[source_id][1] = ucontrol->value.integer.value[1];
- change = 1;
- }
-
- return change;
-}
-
-#define spi_mute_info snd_ctl_boolean_mono_info
-
-static int spi_mute_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
- unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
-
- ucontrol->value.integer.value[0] = !(emu->spi_dac_reg[reg] & bit);
- return 0;
-}
-
-static int spi_mute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
- unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
- int ret;
-
- ret = emu->spi_dac_reg[reg] & bit;
- if (ucontrol->value.integer.value[0]) {
- if (!ret) /* bit already cleared, do nothing */
- return 0;
- emu->spi_dac_reg[reg] &= ~bit;
- } else {
- if (ret) /* bit already set, do nothing */
- return 0;
- emu->spi_dac_reg[reg] |= bit;
- }
-
- ret = snd_ca0106_spi_write(emu, emu->spi_dac_reg[reg]);
- return ret ? -EINVAL : 1;
-}
-
-#define CA_VOLUME(xname,chid,reg) \
-{ \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
- SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .info = snd_ca0106_volume_info, \
- .get = snd_ca0106_volume_get, \
- .put = snd_ca0106_volume_put, \
- .tlv = { .p = snd_ca0106_db_scale1 }, \
- .private_value = ((chid) << 8) | (reg) \
-}
-
-static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
- CA_VOLUME("Analog Front Playback Volume",
- CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2),
- CA_VOLUME("Analog Rear Playback Volume",
- CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2),
- CA_VOLUME("Analog Center/LFE Playback Volume",
- CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2),
- CA_VOLUME("Analog Side Playback Volume",
- CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2),
-
- CA_VOLUME("IEC958 Front Playback Volume",
- CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1),
- CA_VOLUME("IEC958 Rear Playback Volume",
- CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1),
- CA_VOLUME("IEC958 Center/LFE Playback Volume",
- CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1),
- CA_VOLUME("IEC958 Unknown Playback Volume",
- CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1),
-
- CA_VOLUME("CAPTURE feedback Playback Volume",
- 1, CAPTURE_CONTROL),
-
- {
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
- .count = 4,
- .info = snd_ca0106_spdif_info,
- .get = snd_ca0106_spdif_get_mask
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "IEC958 Playback Switch",
- .info = snd_ca0106_shared_spdif_info,
- .get = snd_ca0106_shared_spdif_get,
- .put = snd_ca0106_shared_spdif_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Digital Source Capture Enum",
- .info = snd_ca0106_capture_source_info,
- .get = snd_ca0106_capture_source_get,
- .put = snd_ca0106_capture_source_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Source Capture Enum",
- .info = snd_ca0106_i2c_capture_source_info,
- .get = snd_ca0106_i2c_capture_source_get,
- .put = snd_ca0106_i2c_capture_source_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
- .count = 4,
- .info = snd_ca0106_spdif_info,
- .get = snd_ca0106_spdif_get_default,
- .put = snd_ca0106_spdif_put_default
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
- .count = 4,
- .info = snd_ca0106_spdif_info,
- .get = snd_ca0106_spdif_get_stream,
- .put = snd_ca0106_spdif_put_stream
- },
-};
-
-#define I2C_VOLUME(xname,chid) \
-{ \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
- SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .info = snd_ca0106_i2c_volume_info, \
- .get = snd_ca0106_i2c_volume_get, \
- .put = snd_ca0106_i2c_volume_put, \
- .tlv = { .p = snd_ca0106_db_scale2 }, \
- .private_value = chid \
-}
-
-static struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] __devinitdata = {
- I2C_VOLUME("Phone Capture Volume", 0),
- I2C_VOLUME("Mic Capture Volume", 1),
- I2C_VOLUME("Line in Capture Volume", 2),
- I2C_VOLUME("Aux Capture Volume", 3),
-};
-
-static const int spi_dmute_reg[] = {
- SPI_DMUTE0_REG,
- SPI_DMUTE1_REG,
- SPI_DMUTE2_REG,
- 0,
- SPI_DMUTE4_REG,
-};
-static const int spi_dmute_bit[] = {
- SPI_DMUTE0_BIT,
- SPI_DMUTE1_BIT,
- SPI_DMUTE2_BIT,
- 0,
- SPI_DMUTE4_BIT,
-};
-
-static struct snd_kcontrol_new __devinit
-snd_ca0106_volume_spi_dac_ctl(struct snd_ca0106_details *details,
- int channel_id)
-{
- struct snd_kcontrol_new spi_switch = {0};
- int reg, bit;
- int dac_id;
-
- spi_switch.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- spi_switch.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
- spi_switch.info = spi_mute_info;
- spi_switch.get = spi_mute_get;
- spi_switch.put = spi_mute_put;
-
- switch (channel_id) {
- case PCM_FRONT_CHANNEL:
- spi_switch.name = "Analog Front Playback Switch";
- dac_id = (details->spi_dac & 0xf000) >> (4 * 3);
- break;
- case PCM_REAR_CHANNEL:
- spi_switch.name = "Analog Rear Playback Switch";
- dac_id = (details->spi_dac & 0x0f00) >> (4 * 2);
- break;
- case PCM_CENTER_LFE_CHANNEL:
- spi_switch.name = "Analog Center/LFE Playback Switch";
- dac_id = (details->spi_dac & 0x00f0) >> (4 * 1);
- break;
- case PCM_UNKNOWN_CHANNEL:
- spi_switch.name = "Analog Side Playback Switch";
- dac_id = (details->spi_dac & 0x000f) >> (4 * 0);
- break;
- default:
- /* Unused channel */
- spi_switch.name = NULL;
- dac_id = 0;
- }
- reg = spi_dmute_reg[dac_id];
- bit = spi_dmute_bit[dac_id];
-
- spi_switch.private_value = (reg << SPI_REG_SHIFT) | bit;
-
- return spi_switch;
-}
-
-static int __devinit remove_ctl(struct snd_card *card, const char *name)
-{
- struct snd_ctl_elem_id id;
- memset(&id, 0, sizeof(id));
- strcpy(id.name, name);
- id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- return snd_ctl_remove_id(card, &id);
-}
-
-static struct snd_kcontrol __devinit *ctl_find(struct snd_card *card, const char *name)
-{
- struct snd_ctl_elem_id sid;
- memset(&sid, 0, sizeof(sid));
- /* FIXME: strcpy is bad. */
- strcpy(sid.name, name);
- sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- return snd_ctl_find_id(card, &sid);
-}
-
-static int __devinit rename_ctl(struct snd_card *card, const char *src, const char *dst)
-{
- struct snd_kcontrol *kctl = ctl_find(card, src);
- if (kctl) {
- strcpy(kctl->id.name, dst);
- return 0;
- }
- return -ENOENT;
-}
-
-#define ADD_CTLS(emu, ctls) \
- do { \
- int i, _err; \
- for (i = 0; i < ARRAY_SIZE(ctls); i++) { \
- _err = snd_ctl_add(card, snd_ctl_new1(&ctls[i], emu)); \
- if (_err < 0) \
- return _err; \
- } \
- } while (0)
-
-static __devinitdata
-DECLARE_TLV_DB_SCALE(snd_ca0106_master_db_scale, -6375, 25, 1);
-
-static char *slave_vols[] __devinitdata = {
- "Analog Front Playback Volume",
- "Analog Rear Playback Volume",
- "Analog Center/LFE Playback Volume",
- "Analog Side Playback Volume",
- "IEC958 Front Playback Volume",
- "IEC958 Rear Playback Volume",
- "IEC958 Center/LFE Playback Volume",
- "IEC958 Unknown Playback Volume",
- "CAPTURE feedback Playback Volume",
- NULL
-};
-
-static char *slave_sws[] __devinitdata = {
- "Analog Front Playback Switch",
- "Analog Rear Playback Switch",
- "Analog Center/LFE Playback Switch",
- "Analog Side Playback Switch",
- "IEC958 Playback Switch",
- NULL
-};
-
-static void __devinit add_slaves(struct snd_card *card,
- struct snd_kcontrol *master, char **list)
-{
- for (; *list; list++) {
- struct snd_kcontrol *slave = ctl_find(card, *list);
- if (slave)
- snd_ctl_add_slave(master, slave);
- }
-}
-
-int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
-{
- int err;
- struct snd_card *card = emu->card;
- char **c;
- struct snd_kcontrol *vmaster;
- static char *ca0106_remove_ctls[] = {
- "Master Mono Playback Switch",
- "Master Mono Playback Volume",
- "3D Control - Switch",
- "3D Control Sigmatel - Depth",
- "PCM Playback Switch",
- "PCM Playback Volume",
- "CD Playback Switch",
- "CD Playback Volume",
- "Phone Playback Switch",
- "Phone Playback Volume",
- "Video Playback Switch",
- "Video Playback Volume",
- "Beep Playback Switch",
- "Beep Playback Volume",
- "Mono Output Select",
- "Capture Source",
- "Capture Switch",
- "Capture Volume",
- "External Amplifier",
- "Sigmatel 4-Speaker Stereo Playback Switch",
- "Surround Phase Inversion Playback Switch",
- NULL
- };
- static char *ca0106_rename_ctls[] = {
- "Master Playback Switch", "Capture Switch",
- "Master Playback Volume", "Capture Volume",
- "Line Playback Switch", "AC97 Line Capture Switch",
- "Line Playback Volume", "AC97 Line Capture Volume",
- "Aux Playback Switch", "AC97 Aux Capture Switch",
- "Aux Playback Volume", "AC97 Aux Capture Volume",
- "Mic Playback Switch", "AC97 Mic Capture Switch",
- "Mic Playback Volume", "AC97 Mic Capture Volume",
- "Mic Select", "AC97 Mic Select",
- "Mic Boost (+20dB)", "AC97 Mic Boost (+20dB)",
- NULL
- };
-#if 1
- for (c = ca0106_remove_ctls; *c; c++)
- remove_ctl(card, *c);
- for (c = ca0106_rename_ctls; *c; c += 2)
- rename_ctl(card, c[0], c[1]);
-#endif
-
- ADD_CTLS(emu, snd_ca0106_volume_ctls);
- if (emu->details->i2c_adc == 1) {
- ADD_CTLS(emu, snd_ca0106_volume_i2c_adc_ctls);
- if (emu->details->gpio_type == 1)
- err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu));
- else /* gpio_type == 2 */
- err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_line_in_side_out, emu));
- if (err < 0)
- return err;
- }
- if (emu->details->spi_dac) {
- int i;
- for (i = 0;; i++) {
- struct snd_kcontrol_new ctl;
- ctl = snd_ca0106_volume_spi_dac_ctl(emu->details, i);
- if (!ctl.name)
- break;
- err = snd_ctl_add(card, snd_ctl_new1(&ctl, emu));
- if (err < 0)
- return err;
- }
- }
-
- /* Create virtual master controls */
- vmaster = snd_ctl_make_virtual_master("Master Playback Volume",
- snd_ca0106_master_db_scale);
- if (!vmaster)
- return -ENOMEM;
- err = snd_ctl_add(card, vmaster);
- if (err < 0)
- return err;
- add_slaves(card, vmaster, slave_vols);
-
- if (emu->details->spi_dac) {
- vmaster = snd_ctl_make_virtual_master("Master Playback Switch",
- NULL);
- if (!vmaster)
- return -ENOMEM;
- err = snd_ctl_add(card, vmaster);
- if (err < 0)
- return err;
- add_slaves(card, vmaster, slave_sws);
- }
-
- strcpy(card->mixername, "CA0106");
- return 0;
-}
-
-#ifdef CONFIG_PM
-struct ca0106_vol_tbl {
- unsigned int channel_id;
- unsigned int reg;
-};
-
-static struct ca0106_vol_tbl saved_volumes[NUM_SAVED_VOLUMES] = {
- { CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2 },
- { CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2 },
- { CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2 },
- { CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2 },
- { CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1 },
- { CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1 },
- { CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1 },
- { CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1 },
- { 1, CAPTURE_CONTROL },
-};
-
-void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip)
-{
- int i;
-
- /* save volumes */
- for (i = 0; i < NUM_SAVED_VOLUMES; i++)
- chip->saved_vol[i] =
- snd_ca0106_ptr_read(chip, saved_volumes[i].reg,
- saved_volumes[i].channel_id);
-}
-
-void snd_ca0106_mixer_resume(struct snd_ca0106 *chip)
-{
- int i;
-
- for (i = 0; i < NUM_SAVED_VOLUMES; i++)
- snd_ca0106_ptr_write(chip, saved_volumes[i].reg,
- saved_volumes[i].channel_id,
- chip->saved_vol[i]);
-
- ca0106_spdif_enable(chip);
- ca0106_set_capture_source(chip);
- ca0106_set_i2c_capture_source(chip, chip->i2c_capture_source, 1);
- for (i = 0; i < 4; i++)
- ca0106_set_spdif_bits(chip, i);
- if (chip->details->i2c_adc)
- ca0106_set_capture_mic_line_in(chip);
-}
-#endif /* CONFIG_PM */
diff --git a/ANDROID_3.4.5/sound/pci/ca0106/ca0106_proc.c b/ANDROID_3.4.5/sound/pci/ca0106/ca0106_proc.c
deleted file mode 100644
index c694464b..00000000
--- a/ANDROID_3.4.5/sound/pci/ca0106/ca0106_proc.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
- * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
- * Version: 0.0.18
- *
- * FEATURES currently supported:
- * See ca0106_main.c for features.
- *
- * Changelog:
- * Support interrupts per period.
- * Removed noise from Center/LFE channel when in Analog mode.
- * Rename and remove mixer controls.
- * 0.0.6
- * Use separate card based DMA buffer for periods table list.
- * 0.0.7
- * Change remove and rename ctrls into lists.
- * 0.0.8
- * Try to fix capture sources.
- * 0.0.9
- * Fix AC3 output.
- * Enable S32_LE format support.
- * 0.0.10
- * Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".)
- * 0.0.11
- * Add Model name recognition.
- * 0.0.12
- * Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period.
- * Remove redundent "voice" handling.
- * 0.0.13
- * Single trigger call for multi channels.
- * 0.0.14
- * Set limits based on what the sound card hardware can do.
- * playback periods_min=2, periods_max=8
- * capture hw constraints require period_size = n * 64 bytes.
- * playback hw constraints require period_size = n * 64 bytes.
- * 0.0.15
- * Separate ca0106.c into separate functional .c files.
- * 0.0.16
- * Modified Copyright message.
- * 0.0.17
- * Add iec958 file in proc file system to show status of SPDIF in.
- * 0.0.18
- * Implement support for Line-in capture on SB Live 24bit.
- *
- * This code was initially based on code from ALSA's emu10k1x.c which is:
- * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/moduleparam.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/info.h>
-#include <sound/asoundef.h>
-#include <asm/io.h>
-
-#include "ca0106.h"
-
-
-#ifdef CONFIG_PROC_FS
-
-struct snd_ca0106_category_str {
- int val;
- const char *name;
-};
-
-static struct snd_ca0106_category_str snd_ca0106_con_category[] = {
- { IEC958_AES1_CON_DAT, "DAT" },
- { IEC958_AES1_CON_VCR, "VCR" },
- { IEC958_AES1_CON_MICROPHONE, "microphone" },
- { IEC958_AES1_CON_SYNTHESIZER, "synthesizer" },
- { IEC958_AES1_CON_RATE_CONVERTER, "rate converter" },
- { IEC958_AES1_CON_MIXER, "mixer" },
- { IEC958_AES1_CON_SAMPLER, "sampler" },
- { IEC958_AES1_CON_PCM_CODER, "PCM coder" },
- { IEC958_AES1_CON_IEC908_CD, "CD" },
- { IEC958_AES1_CON_NON_IEC908_CD, "non-IEC908 CD" },
- { IEC958_AES1_CON_GENERAL, "general" },
-};
-
-
-static void snd_ca0106_proc_dump_iec958( struct snd_info_buffer *buffer, u32 value)
-{
- int i;
- u32 status[4];
- status[0] = value & 0xff;
- status[1] = (value >> 8) & 0xff;
- status[2] = (value >> 16) & 0xff;
- status[3] = (value >> 24) & 0xff;
-
- if (! (status[0] & IEC958_AES0_PROFESSIONAL)) {
- /* consumer */
- snd_iprintf(buffer, "Mode: consumer\n");
- snd_iprintf(buffer, "Data: ");
- if (!(status[0] & IEC958_AES0_NONAUDIO)) {
- snd_iprintf(buffer, "audio\n");
- } else {
- snd_iprintf(buffer, "non-audio\n");
- }
- snd_iprintf(buffer, "Rate: ");
- switch (status[3] & IEC958_AES3_CON_FS) {
- case IEC958_AES3_CON_FS_44100:
- snd_iprintf(buffer, "44100 Hz\n");
- break;
- case IEC958_AES3_CON_FS_48000:
- snd_iprintf(buffer, "48000 Hz\n");
- break;
- case IEC958_AES3_CON_FS_32000:
- snd_iprintf(buffer, "32000 Hz\n");
- break;
- default:
- snd_iprintf(buffer, "unknown\n");
- break;
- }
- snd_iprintf(buffer, "Copyright: ");
- if (status[0] & IEC958_AES0_CON_NOT_COPYRIGHT) {
- snd_iprintf(buffer, "permitted\n");
- } else {
- snd_iprintf(buffer, "protected\n");
- }
- snd_iprintf(buffer, "Emphasis: ");
- if ((status[0] & IEC958_AES0_CON_EMPHASIS) != IEC958_AES0_CON_EMPHASIS_5015) {
- snd_iprintf(buffer, "none\n");
- } else {
- snd_iprintf(buffer, "50/15us\n");
- }
- snd_iprintf(buffer, "Category: ");
- for (i = 0; i < ARRAY_SIZE(snd_ca0106_con_category); i++) {
- if ((status[1] & IEC958_AES1_CON_CATEGORY) == snd_ca0106_con_category[i].val) {
- snd_iprintf(buffer, "%s\n", snd_ca0106_con_category[i].name);
- break;
- }
- }
- if (i >= ARRAY_SIZE(snd_ca0106_con_category)) {
- snd_iprintf(buffer, "unknown 0x%x\n", status[1] & IEC958_AES1_CON_CATEGORY);
- }
- snd_iprintf(buffer, "Original: ");
- if (status[1] & IEC958_AES1_CON_ORIGINAL) {
- snd_iprintf(buffer, "original\n");
- } else {
- snd_iprintf(buffer, "1st generation\n");
- }
- snd_iprintf(buffer, "Clock: ");
- switch (status[3] & IEC958_AES3_CON_CLOCK) {
- case IEC958_AES3_CON_CLOCK_1000PPM:
- snd_iprintf(buffer, "1000 ppm\n");
- break;
- case IEC958_AES3_CON_CLOCK_50PPM:
- snd_iprintf(buffer, "50 ppm\n");
- break;
- case IEC958_AES3_CON_CLOCK_VARIABLE:
- snd_iprintf(buffer, "variable pitch\n");
- break;
- default:
- snd_iprintf(buffer, "unknown\n");
- break;
- }
- } else {
- snd_iprintf(buffer, "Mode: professional\n");
- snd_iprintf(buffer, "Data: ");
- if (!(status[0] & IEC958_AES0_NONAUDIO)) {
- snd_iprintf(buffer, "audio\n");
- } else {
- snd_iprintf(buffer, "non-audio\n");
- }
- snd_iprintf(buffer, "Rate: ");
- switch (status[0] & IEC958_AES0_PRO_FS) {
- case IEC958_AES0_PRO_FS_44100:
- snd_iprintf(buffer, "44100 Hz\n");
- break;
- case IEC958_AES0_PRO_FS_48000:
- snd_iprintf(buffer, "48000 Hz\n");
- break;
- case IEC958_AES0_PRO_FS_32000:
- snd_iprintf(buffer, "32000 Hz\n");
- break;
- default:
- snd_iprintf(buffer, "unknown\n");
- break;
- }
- snd_iprintf(buffer, "Rate Locked: ");
- if (status[0] & IEC958_AES0_PRO_FREQ_UNLOCKED)
- snd_iprintf(buffer, "no\n");
- else
- snd_iprintf(buffer, "yes\n");
- snd_iprintf(buffer, "Emphasis: ");
- switch (status[0] & IEC958_AES0_PRO_EMPHASIS) {
- case IEC958_AES0_PRO_EMPHASIS_CCITT:
- snd_iprintf(buffer, "CCITT J.17\n");
- break;
- case IEC958_AES0_PRO_EMPHASIS_NONE:
- snd_iprintf(buffer, "none\n");
- break;
- case IEC958_AES0_PRO_EMPHASIS_5015:
- snd_iprintf(buffer, "50/15us\n");
- break;
- case IEC958_AES0_PRO_EMPHASIS_NOTID:
- default:
- snd_iprintf(buffer, "unknown\n");
- break;
- }
- snd_iprintf(buffer, "Stereophonic: ");
- if ((status[1] & IEC958_AES1_PRO_MODE) == IEC958_AES1_PRO_MODE_STEREOPHONIC) {
- snd_iprintf(buffer, "stereo\n");
- } else {
- snd_iprintf(buffer, "not indicated\n");
- }
- snd_iprintf(buffer, "Userbits: ");
- switch (status[1] & IEC958_AES1_PRO_USERBITS) {
- case IEC958_AES1_PRO_USERBITS_192:
- snd_iprintf(buffer, "192bit\n");
- break;
- case IEC958_AES1_PRO_USERBITS_UDEF:
- snd_iprintf(buffer, "user-defined\n");
- break;
- default:
- snd_iprintf(buffer, "unknown\n");
- break;
- }
- snd_iprintf(buffer, "Sample Bits: ");
- switch (status[2] & IEC958_AES2_PRO_SBITS) {
- case IEC958_AES2_PRO_SBITS_20:
- snd_iprintf(buffer, "20 bit\n");
- break;
- case IEC958_AES2_PRO_SBITS_24:
- snd_iprintf(buffer, "24 bit\n");
- break;
- case IEC958_AES2_PRO_SBITS_UDEF:
- snd_iprintf(buffer, "user defined\n");
- break;
- default:
- snd_iprintf(buffer, "unknown\n");
- break;
- }
- snd_iprintf(buffer, "Word Length: ");
- switch (status[2] & IEC958_AES2_PRO_WORDLEN) {
- case IEC958_AES2_PRO_WORDLEN_22_18:
- snd_iprintf(buffer, "22 bit or 18 bit\n");
- break;
- case IEC958_AES2_PRO_WORDLEN_23_19:
- snd_iprintf(buffer, "23 bit or 19 bit\n");
- break;
- case IEC958_AES2_PRO_WORDLEN_24_20:
- snd_iprintf(buffer, "24 bit or 20 bit\n");
- break;
- case IEC958_AES2_PRO_WORDLEN_20_16:
- snd_iprintf(buffer, "20 bit or 16 bit\n");
- break;
- default:
- snd_iprintf(buffer, "unknown\n");
- break;
- }
- }
-}
-
-static void snd_ca0106_proc_iec958(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_ca0106 *emu = entry->private_data;
- u32 value;
-
- value = snd_ca0106_ptr_read(emu, SAMPLE_RATE_TRACKER_STATUS, 0);
- snd_iprintf(buffer, "Status: %s, %s, %s\n",
- (value & 0x100000) ? "Rate Locked" : "Not Rate Locked",
- (value & 0x200000) ? "SPDIF Locked" : "No SPDIF Lock",
- (value & 0x400000) ? "Audio Valid" : "No valid audio" );
- snd_iprintf(buffer, "Estimated sample rate: %u\n",
- ((value & 0xfffff) * 48000) / 0x8000 );
- if (value & 0x200000) {
- snd_iprintf(buffer, "IEC958/SPDIF input status:\n");
- value = snd_ca0106_ptr_read(emu, SPDIF_INPUT_STATUS, 0);
- snd_ca0106_proc_dump_iec958(buffer, value);
- }
-
- snd_iprintf(buffer, "\n");
-}
-
-static void snd_ca0106_proc_reg_write32(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_ca0106 *emu = entry->private_data;
- unsigned long flags;
- char line[64];
- u32 reg, val;
- while (!snd_info_get_line(buffer, line, sizeof(line))) {
- if (sscanf(line, "%x %x", &reg, &val) != 2)
- continue;
- if (reg < 0x40 && val <= 0xffffffff) {
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(val, emu->port + (reg & 0xfffffffc));
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- }
- }
-}
-
-static void snd_ca0106_proc_reg_read32(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_ca0106 *emu = entry->private_data;
- unsigned long value;
- unsigned long flags;
- int i;
- snd_iprintf(buffer, "Registers:\n\n");
- for(i = 0; i < 0x20; i+=4) {
- spin_lock_irqsave(&emu->emu_lock, flags);
- value = inl(emu->port + i);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- snd_iprintf(buffer, "Register %02X: %08lX\n", i, value);
- }
-}
-
-static void snd_ca0106_proc_reg_read16(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_ca0106 *emu = entry->private_data;
- unsigned int value;
- unsigned long flags;
- int i;
- snd_iprintf(buffer, "Registers:\n\n");
- for(i = 0; i < 0x20; i+=2) {
- spin_lock_irqsave(&emu->emu_lock, flags);
- value = inw(emu->port + i);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- snd_iprintf(buffer, "Register %02X: %04X\n", i, value);
- }
-}
-
-static void snd_ca0106_proc_reg_read8(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_ca0106 *emu = entry->private_data;
- unsigned int value;
- unsigned long flags;
- int i;
- snd_iprintf(buffer, "Registers:\n\n");
- for(i = 0; i < 0x20; i+=1) {
- spin_lock_irqsave(&emu->emu_lock, flags);
- value = inb(emu->port + i);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- snd_iprintf(buffer, "Register %02X: %02X\n", i, value);
- }
-}
-
-static void snd_ca0106_proc_reg_read1(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_ca0106 *emu = entry->private_data;
- unsigned long value;
- int i,j;
-
- snd_iprintf(buffer, "Registers\n");
- for(i = 0; i < 0x40; i++) {
- snd_iprintf(buffer, "%02X: ",i);
- for (j = 0; j < 4; j++) {
- value = snd_ca0106_ptr_read(emu, i, j);
- snd_iprintf(buffer, "%08lX ", value);
- }
- snd_iprintf(buffer, "\n");
- }
-}
-
-static void snd_ca0106_proc_reg_read2(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_ca0106 *emu = entry->private_data;
- unsigned long value;
- int i,j;
-
- snd_iprintf(buffer, "Registers\n");
- for(i = 0x40; i < 0x80; i++) {
- snd_iprintf(buffer, "%02X: ",i);
- for (j = 0; j < 4; j++) {
- value = snd_ca0106_ptr_read(emu, i, j);
- snd_iprintf(buffer, "%08lX ", value);
- }
- snd_iprintf(buffer, "\n");
- }
-}
-
-static void snd_ca0106_proc_reg_write(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_ca0106 *emu = entry->private_data;
- char line[64];
- unsigned int reg, channel_id , val;
- while (!snd_info_get_line(buffer, line, sizeof(line))) {
- if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
- continue;
- if (reg < 0x80 && val <= 0xffffffff && channel_id <= 3)
- snd_ca0106_ptr_write(emu, reg, channel_id, val);
- }
-}
-
-static void snd_ca0106_proc_i2c_write(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_ca0106 *emu = entry->private_data;
- char line[64];
- unsigned int reg, val;
- while (!snd_info_get_line(buffer, line, sizeof(line))) {
- if (sscanf(line, "%x %x", &reg, &val) != 2)
- continue;
- if ((reg <= 0x7f) || (val <= 0x1ff)) {
- snd_ca0106_i2c_write(emu, reg, val);
- }
- }
-}
-
-int __devinit snd_ca0106_proc_init(struct snd_ca0106 * emu)
-{
- struct snd_info_entry *entry;
-
- if(! snd_card_proc_new(emu->card, "iec958", &entry))
- snd_info_set_text_ops(entry, emu, snd_ca0106_proc_iec958);
- if(! snd_card_proc_new(emu->card, "ca0106_reg32", &entry)) {
- snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read32);
- entry->c.text.write = snd_ca0106_proc_reg_write32;
- entry->mode |= S_IWUSR;
- }
- if(! snd_card_proc_new(emu->card, "ca0106_reg16", &entry))
- snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read16);
- if(! snd_card_proc_new(emu->card, "ca0106_reg8", &entry))
- snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read8);
- if(! snd_card_proc_new(emu->card, "ca0106_regs1", &entry)) {
- snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read1);
- entry->c.text.write = snd_ca0106_proc_reg_write;
- entry->mode |= S_IWUSR;
- }
- if(! snd_card_proc_new(emu->card, "ca0106_i2c", &entry)) {
- entry->c.text.write = snd_ca0106_proc_i2c_write;
- entry->private_data = emu;
- entry->mode |= S_IWUSR;
- }
- if(! snd_card_proc_new(emu->card, "ca0106_regs2", &entry))
- snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read2);
- return 0;
-}
-
-#endif /* CONFIG_PROC_FS */
diff --git a/ANDROID_3.4.5/sound/pci/ca0106/ca_midi.c b/ANDROID_3.4.5/sound/pci/ca0106/ca_midi.c
deleted file mode 100644
index c7885117..00000000
--- a/ANDROID_3.4.5/sound/pci/ca0106/ca_midi.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Copyright 10/16/2005 Tilman Kranz <tilde@tk-sls.de>
- * Creative Audio MIDI, for the CA0106 Driver
- * Version: 0.0.1
- *
- * Changelog:
- * Implementation is based on mpu401 and emu10k1x and
- * tested with ca0106.
- * mpu401: Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * emu10k1x: Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
- */
-
-#include <linux/spinlock.h>
-#include <sound/core.h>
-#include <sound/rawmidi.h>
-
-#include "ca_midi.h"
-
-#define ca_midi_write_data(midi, data) midi->write(midi, data, 0)
-#define ca_midi_write_cmd(midi, data) midi->write(midi, data, 1)
-#define ca_midi_read_data(midi) midi->read(midi, 0)
-#define ca_midi_read_stat(midi) midi->read(midi, 1)
-#define ca_midi_input_avail(midi) (!(ca_midi_read_stat(midi) & midi->input_avail))
-#define ca_midi_output_ready(midi) (!(ca_midi_read_stat(midi) & midi->output_ready))
-
-static void ca_midi_clear_rx(struct snd_ca_midi *midi)
-{
- int timeout = 100000;
- for (; timeout > 0 && ca_midi_input_avail(midi); timeout--)
- ca_midi_read_data(midi);
-#ifdef CONFIG_SND_DEBUG
- if (timeout <= 0)
- snd_printk(KERN_ERR "ca_midi_clear_rx: timeout (status = 0x%x)\n",
- ca_midi_read_stat(midi));
-#endif
-}
-
-static void ca_midi_interrupt(struct snd_ca_midi *midi, unsigned int status)
-{
- unsigned char byte;
-
- if (midi->rmidi == NULL) {
- midi->interrupt_disable(midi,midi->tx_enable | midi->rx_enable);
- return;
- }
-
- spin_lock(&midi->input_lock);
- if ((status & midi->ipr_rx) && ca_midi_input_avail(midi)) {
- if (!(midi->midi_mode & CA_MIDI_MODE_INPUT)) {
- ca_midi_clear_rx(midi);
- } else {
- byte = ca_midi_read_data(midi);
- if(midi->substream_input)
- snd_rawmidi_receive(midi->substream_input, &byte, 1);
-
-
- }
- }
- spin_unlock(&midi->input_lock);
-
- spin_lock(&midi->output_lock);
- if ((status & midi->ipr_tx) && ca_midi_output_ready(midi)) {
- if (midi->substream_output &&
- snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
- ca_midi_write_data(midi, byte);
- } else {
- midi->interrupt_disable(midi,midi->tx_enable);
- }
- }
- spin_unlock(&midi->output_lock);
-
-}
-
-static void ca_midi_cmd(struct snd_ca_midi *midi, unsigned char cmd, int ack)
-{
- unsigned long flags;
- int timeout, ok;
-
- spin_lock_irqsave(&midi->input_lock, flags);
- ca_midi_write_data(midi, 0x00);
- /* ca_midi_clear_rx(midi); */
-
- ca_midi_write_cmd(midi, cmd);
- if (ack) {
- ok = 0;
- timeout = 10000;
- while (!ok && timeout-- > 0) {
- if (ca_midi_input_avail(midi)) {
- if (ca_midi_read_data(midi) == midi->ack)
- ok = 1;
- }
- }
- if (!ok && ca_midi_read_data(midi) == midi->ack)
- ok = 1;
- } else {
- ok = 1;
- }
- spin_unlock_irqrestore(&midi->input_lock, flags);
- if (!ok)
- snd_printk(KERN_ERR "ca_midi_cmd: 0x%x failed at 0x%x (status = 0x%x, data = 0x%x)!!!\n",
- cmd,
- midi->get_dev_id_port(midi->dev_id),
- ca_midi_read_stat(midi),
- ca_midi_read_data(midi));
-}
-
-static int ca_midi_input_open(struct snd_rawmidi_substream *substream)
-{
- struct snd_ca_midi *midi = substream->rmidi->private_data;
- unsigned long flags;
-
- if (snd_BUG_ON(!midi->dev_id))
- return -ENXIO;
- spin_lock_irqsave(&midi->open_lock, flags);
- midi->midi_mode |= CA_MIDI_MODE_INPUT;
- midi->substream_input = substream;
- if (!(midi->midi_mode & CA_MIDI_MODE_OUTPUT)) {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- ca_midi_cmd(midi, midi->reset, 1);
- ca_midi_cmd(midi, midi->enter_uart, 1);
- } else {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- }
- return 0;
-}
-
-static int ca_midi_output_open(struct snd_rawmidi_substream *substream)
-{
- struct snd_ca_midi *midi = substream->rmidi->private_data;
- unsigned long flags;
-
- if (snd_BUG_ON(!midi->dev_id))
- return -ENXIO;
- spin_lock_irqsave(&midi->open_lock, flags);
- midi->midi_mode |= CA_MIDI_MODE_OUTPUT;
- midi->substream_output = substream;
- if (!(midi->midi_mode & CA_MIDI_MODE_INPUT)) {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- ca_midi_cmd(midi, midi->reset, 1);
- ca_midi_cmd(midi, midi->enter_uart, 1);
- } else {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- }
- return 0;
-}
-
-static int ca_midi_input_close(struct snd_rawmidi_substream *substream)
-{
- struct snd_ca_midi *midi = substream->rmidi->private_data;
- unsigned long flags;
-
- if (snd_BUG_ON(!midi->dev_id))
- return -ENXIO;
- spin_lock_irqsave(&midi->open_lock, flags);
- midi->interrupt_disable(midi,midi->rx_enable);
- midi->midi_mode &= ~CA_MIDI_MODE_INPUT;
- midi->substream_input = NULL;
- if (!(midi->midi_mode & CA_MIDI_MODE_OUTPUT)) {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- ca_midi_cmd(midi, midi->reset, 0);
- } else {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- }
- return 0;
-}
-
-static int ca_midi_output_close(struct snd_rawmidi_substream *substream)
-{
- struct snd_ca_midi *midi = substream->rmidi->private_data;
- unsigned long flags;
-
- if (snd_BUG_ON(!midi->dev_id))
- return -ENXIO;
-
- spin_lock_irqsave(&midi->open_lock, flags);
-
- midi->interrupt_disable(midi,midi->tx_enable);
- midi->midi_mode &= ~CA_MIDI_MODE_OUTPUT;
- midi->substream_output = NULL;
-
- if (!(midi->midi_mode & CA_MIDI_MODE_INPUT)) {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- ca_midi_cmd(midi, midi->reset, 0);
- } else {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- }
- return 0;
-}
-
-static void ca_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct snd_ca_midi *midi = substream->rmidi->private_data;
-
- if (snd_BUG_ON(!midi->dev_id))
- return;
-
- if (up) {
- midi->interrupt_enable(midi,midi->rx_enable);
- } else {
- midi->interrupt_disable(midi, midi->rx_enable);
- }
-}
-
-static void ca_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct snd_ca_midi *midi = substream->rmidi->private_data;
- unsigned long flags;
-
- if (snd_BUG_ON(!midi->dev_id))
- return;
-
- if (up) {
- int max = 4;
- unsigned char byte;
-
- spin_lock_irqsave(&midi->output_lock, flags);
-
- /* try to send some amount of bytes here before interrupts */
- while (max > 0) {
- if (ca_midi_output_ready(midi)) {
- if (!(midi->midi_mode & CA_MIDI_MODE_OUTPUT) ||
- snd_rawmidi_transmit(substream, &byte, 1) != 1) {
- /* no more data */
- spin_unlock_irqrestore(&midi->output_lock, flags);
- return;
- }
- ca_midi_write_data(midi, byte);
- max--;
- } else {
- break;
- }
- }
-
- spin_unlock_irqrestore(&midi->output_lock, flags);
- midi->interrupt_enable(midi,midi->tx_enable);
-
- } else {
- midi->interrupt_disable(midi,midi->tx_enable);
- }
-}
-
-static struct snd_rawmidi_ops ca_midi_output =
-{
- .open = ca_midi_output_open,
- .close = ca_midi_output_close,
- .trigger = ca_midi_output_trigger,
-};
-
-static struct snd_rawmidi_ops ca_midi_input =
-{
- .open = ca_midi_input_open,
- .close = ca_midi_input_close,
- .trigger = ca_midi_input_trigger,
-};
-
-static void ca_midi_free(struct snd_ca_midi *midi)
-{
- midi->interrupt = NULL;
- midi->interrupt_enable = NULL;
- midi->interrupt_disable = NULL;
- midi->read = NULL;
- midi->write = NULL;
- midi->get_dev_id_card = NULL;
- midi->get_dev_id_port = NULL;
- midi->rmidi = NULL;
-}
-
-static void ca_rmidi_free(struct snd_rawmidi *rmidi)
-{
- ca_midi_free(rmidi->private_data);
-}
-
-int __devinit ca_midi_init(void *dev_id, struct snd_ca_midi *midi, int device, char *name)
-{
- struct snd_rawmidi *rmidi;
- int err;
-
- if ((err = snd_rawmidi_new(midi->get_dev_id_card(midi->dev_id), name, device, 1, 1, &rmidi)) < 0)
- return err;
-
- midi->dev_id = dev_id;
- midi->interrupt = ca_midi_interrupt;
-
- spin_lock_init(&midi->open_lock);
- spin_lock_init(&midi->input_lock);
- spin_lock_init(&midi->output_lock);
-
- strcpy(rmidi->name, name);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &ca_midi_output);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &ca_midi_input);
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
- rmidi->private_data = midi;
- rmidi->private_free = ca_rmidi_free;
-
- midi->rmidi = rmidi;
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/pci/ca0106/ca_midi.h b/ANDROID_3.4.5/sound/pci/ca0106/ca_midi.h
deleted file mode 100644
index 922ed3e3..00000000
--- a/ANDROID_3.4.5/sound/pci/ca0106/ca_midi.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 10/16/2005 Tilman Kranz <tilde@tk-sls.de>
- * Creative Audio MIDI, for the CA0106 Driver
- * Version: 0.0.1
- *
- * Changelog:
- * See ca_midi.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/spinlock.h>
-#include <sound/rawmidi.h>
-#include <sound/mpu401.h>
-
-#define CA_MIDI_MODE_INPUT MPU401_MODE_INPUT
-#define CA_MIDI_MODE_OUTPUT MPU401_MODE_OUTPUT
-
-struct snd_ca_midi {
-
- struct snd_rawmidi *rmidi;
- struct snd_rawmidi_substream *substream_input;
- struct snd_rawmidi_substream *substream_output;
-
- void *dev_id;
-
- spinlock_t input_lock;
- spinlock_t output_lock;
- spinlock_t open_lock;
-
- unsigned int channel;
-
- unsigned int midi_mode;
- int port;
- int tx_enable, rx_enable;
- int ipr_tx, ipr_rx;
-
- int input_avail, output_ready;
- int ack, reset, enter_uart;
-
- void (*interrupt)(struct snd_ca_midi *midi, unsigned int status);
- void (*interrupt_enable)(struct snd_ca_midi *midi, int intr);
- void (*interrupt_disable)(struct snd_ca_midi *midi, int intr);
-
- unsigned char (*read)(struct snd_ca_midi *midi, int idx);
- void (*write)(struct snd_ca_midi *midi, int data, int idx);
-
- /* get info from dev_id */
- struct snd_card *(*get_dev_id_card)(void *dev_id);
- int (*get_dev_id_port)(void *dev_id);
-};
-
-int ca_midi_init(void *card, struct snd_ca_midi *midi, int device, char *name);
diff --git a/ANDROID_3.4.5/sound/pci/cmipci.c b/ANDROID_3.4.5/sound/pci/cmipci.c
deleted file mode 100644
index 19b06269..00000000
--- a/ANDROID_3.4.5/sound/pci/cmipci.c
+++ /dev/null
@@ -1,3423 +0,0 @@
-/*
- * Driver for C-Media CMI8338 and 8738 PCI soundcards.
- * Copyright (c) 2000 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* Does not work. Warning may block system in capture mode */
-/* #define USE_VAR48KRATE */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/gameport.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/rawmidi.h>
-#include <sound/mpu401.h>
-#include <sound/opl3.h>
-#include <sound/sb.h>
-#include <sound/asoundef.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("C-Media CMI8x38 PCI");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8738},"
- "{C-Media,CMI8738B},"
- "{C-Media,CMI8338A},"
- "{C-Media,CMI8338B}}");
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK 1
-#endif
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
-static long mpu_port[SNDRV_CARDS];
-static long fm_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)]=1};
-static bool soft_ac3[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)]=1};
-#ifdef SUPPORT_JOYSTICK
-static int joystick_port[SNDRV_CARDS];
-#endif
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for C-Media PCI soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for C-Media PCI soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable C-Media PCI soundcard.");
-module_param_array(mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port.");
-module_param_array(fm_port, long, NULL, 0444);
-MODULE_PARM_DESC(fm_port, "FM port.");
-module_param_array(soft_ac3, bool, NULL, 0444);
-MODULE_PARM_DESC(soft_ac3, "Software-conversion of raw SPDIF packets (model 033 only).");
-#ifdef SUPPORT_JOYSTICK
-module_param_array(joystick_port, int, NULL, 0444);
-MODULE_PARM_DESC(joystick_port, "Joystick port address.");
-#endif
-
-/*
- * CM8x38 registers definition
- */
-
-#define CM_REG_FUNCTRL0 0x00
-#define CM_RST_CH1 0x00080000
-#define CM_RST_CH0 0x00040000
-#define CM_CHEN1 0x00020000 /* ch1: enable */
-#define CM_CHEN0 0x00010000 /* ch0: enable */
-#define CM_PAUSE1 0x00000008 /* ch1: pause */
-#define CM_PAUSE0 0x00000004 /* ch0: pause */
-#define CM_CHADC1 0x00000002 /* ch1, 0:playback, 1:record */
-#define CM_CHADC0 0x00000001 /* ch0, 0:playback, 1:record */
-
-#define CM_REG_FUNCTRL1 0x04
-#define CM_DSFC_MASK 0x0000E000 /* channel 1 (DAC?) sampling frequency */
-#define CM_DSFC_SHIFT 13
-#define CM_ASFC_MASK 0x00001C00 /* channel 0 (ADC?) sampling frequency */
-#define CM_ASFC_SHIFT 10
-#define CM_SPDF_1 0x00000200 /* SPDIF IN/OUT at channel B */
-#define CM_SPDF_0 0x00000100 /* SPDIF OUT only channel A */
-#define CM_SPDFLOOP 0x00000080 /* ext. SPDIIF/IN -> OUT loopback */
-#define CM_SPDO2DAC 0x00000040 /* SPDIF/OUT can be heard from internal DAC */
-#define CM_INTRM 0x00000020 /* master control block (MCB) interrupt enabled */
-#define CM_BREQ 0x00000010 /* bus master enabled */
-#define CM_VOICE_EN 0x00000008 /* legacy voice (SB16,FM) */
-#define CM_UART_EN 0x00000004 /* legacy UART */
-#define CM_JYSTK_EN 0x00000002 /* legacy joystick */
-#define CM_ZVPORT 0x00000001 /* ZVPORT */
-
-#define CM_REG_CHFORMAT 0x08
-
-#define CM_CHB3D5C 0x80000000 /* 5,6 channels */
-#define CM_FMOFFSET2 0x40000000 /* initial FM PCM offset 2 when Fmute=1 */
-#define CM_CHB3D 0x20000000 /* 4 channels */
-
-#define CM_CHIP_MASK1 0x1f000000
-#define CM_CHIP_037 0x01000000
-#define CM_SETLAT48 0x00800000 /* set latency timer 48h */
-#define CM_EDGEIRQ 0x00400000 /* emulated edge trigger legacy IRQ */
-#define CM_SPD24SEL39 0x00200000 /* 24-bit spdif: model 039 */
-#define CM_AC3EN1 0x00100000 /* enable AC3: model 037 */
-#define CM_SPDIF_SELECT1 0x00080000 /* for model <= 037 ? */
-#define CM_SPD24SEL 0x00020000 /* 24bit spdif: model 037 */
-/* #define CM_SPDIF_INVERSE 0x00010000 */ /* ??? */
-
-#define CM_ADCBITLEN_MASK 0x0000C000
-#define CM_ADCBITLEN_16 0x00000000
-#define CM_ADCBITLEN_15 0x00004000
-#define CM_ADCBITLEN_14 0x00008000
-#define CM_ADCBITLEN_13 0x0000C000
-
-#define CM_ADCDACLEN_MASK 0x00003000 /* model 037 */
-#define CM_ADCDACLEN_060 0x00000000
-#define CM_ADCDACLEN_066 0x00001000
-#define CM_ADCDACLEN_130 0x00002000
-#define CM_ADCDACLEN_280 0x00003000
-
-#define CM_ADCDLEN_MASK 0x00003000 /* model 039 */
-#define CM_ADCDLEN_ORIGINAL 0x00000000
-#define CM_ADCDLEN_EXTRA 0x00001000
-#define CM_ADCDLEN_24K 0x00002000
-#define CM_ADCDLEN_WEIGHT 0x00003000
-
-#define CM_CH1_SRATE_176K 0x00000800
-#define CM_CH1_SRATE_96K 0x00000800 /* model 055? */
-#define CM_CH1_SRATE_88K 0x00000400
-#define CM_CH0_SRATE_176K 0x00000200
-#define CM_CH0_SRATE_96K 0x00000200 /* model 055? */
-#define CM_CH0_SRATE_88K 0x00000100
-#define CM_CH0_SRATE_128K 0x00000300
-#define CM_CH0_SRATE_MASK 0x00000300
-
-#define CM_SPDIF_INVERSE2 0x00000080 /* model 055? */
-#define CM_DBLSPDS 0x00000040 /* double SPDIF sample rate 88.2/96 */
-#define CM_POLVALID 0x00000020 /* inverse SPDIF/IN valid bit */
-#define CM_SPDLOCKED 0x00000010
-
-#define CM_CH1FMT_MASK 0x0000000C /* bit 3: 16 bits, bit 2: stereo */
-#define CM_CH1FMT_SHIFT 2
-#define CM_CH0FMT_MASK 0x00000003 /* bit 1: 16 bits, bit 0: stereo */
-#define CM_CH0FMT_SHIFT 0
-
-#define CM_REG_INT_HLDCLR 0x0C
-#define CM_CHIP_MASK2 0xff000000
-#define CM_CHIP_8768 0x20000000
-#define CM_CHIP_055 0x08000000
-#define CM_CHIP_039 0x04000000
-#define CM_CHIP_039_6CH 0x01000000
-#define CM_UNKNOWN_INT_EN 0x00080000 /* ? */
-#define CM_TDMA_INT_EN 0x00040000
-#define CM_CH1_INT_EN 0x00020000
-#define CM_CH0_INT_EN 0x00010000
-
-#define CM_REG_INT_STATUS 0x10
-#define CM_INTR 0x80000000
-#define CM_VCO 0x08000000 /* Voice Control? CMI8738 */
-#define CM_MCBINT 0x04000000 /* Master Control Block abort cond.? */
-#define CM_UARTINT 0x00010000
-#define CM_LTDMAINT 0x00008000
-#define CM_HTDMAINT 0x00004000
-#define CM_XDO46 0x00000080 /* Modell 033? Direct programming EEPROM (read data register) */
-#define CM_LHBTOG 0x00000040 /* High/Low status from DMA ctrl register */
-#define CM_LEG_HDMA 0x00000020 /* Legacy is in High DMA channel */
-#define CM_LEG_STEREO 0x00000010 /* Legacy is in Stereo mode */
-#define CM_CH1BUSY 0x00000008
-#define CM_CH0BUSY 0x00000004
-#define CM_CHINT1 0x00000002
-#define CM_CHINT0 0x00000001
-
-#define CM_REG_LEGACY_CTRL 0x14
-#define CM_NXCHG 0x80000000 /* don't map base reg dword->sample */
-#define CM_VMPU_MASK 0x60000000 /* MPU401 i/o port address */
-#define CM_VMPU_330 0x00000000
-#define CM_VMPU_320 0x20000000
-#define CM_VMPU_310 0x40000000
-#define CM_VMPU_300 0x60000000
-#define CM_ENWR8237 0x10000000 /* enable bus master to write 8237 base reg */
-#define CM_VSBSEL_MASK 0x0C000000 /* SB16 base address */
-#define CM_VSBSEL_220 0x00000000
-#define CM_VSBSEL_240 0x04000000
-#define CM_VSBSEL_260 0x08000000
-#define CM_VSBSEL_280 0x0C000000
-#define CM_FMSEL_MASK 0x03000000 /* FM OPL3 base address */
-#define CM_FMSEL_388 0x00000000
-#define CM_FMSEL_3C8 0x01000000
-#define CM_FMSEL_3E0 0x02000000
-#define CM_FMSEL_3E8 0x03000000
-#define CM_ENSPDOUT 0x00800000 /* enable XSPDIF/OUT to I/O interface */
-#define CM_SPDCOPYRHT 0x00400000 /* spdif in/out copyright bit */
-#define CM_DAC2SPDO 0x00200000 /* enable wave+fm_midi -> SPDIF/OUT */
-#define CM_INVIDWEN 0x00100000 /* internal vendor ID write enable, model 039? */
-#define CM_SETRETRY 0x00100000 /* 0: legacy i/o wait (default), 1: legacy i/o bus retry */
-#define CM_C_EEACCESS 0x00080000 /* direct programming eeprom regs */
-#define CM_C_EECS 0x00040000
-#define CM_C_EEDI46 0x00020000
-#define CM_C_EECK46 0x00010000
-#define CM_CHB3D6C 0x00008000 /* 5.1 channels support */
-#define CM_CENTR2LIN 0x00004000 /* line-in as center out */
-#define CM_BASE2LIN 0x00002000 /* line-in as bass out */
-#define CM_EXBASEN 0x00001000 /* external bass input enable */
-
-#define CM_REG_MISC_CTRL 0x18
-#define CM_PWD 0x80000000 /* power down */
-#define CM_RESET 0x40000000
-#define CM_SFIL_MASK 0x30000000 /* filter control at front end DAC, model 037? */
-#define CM_VMGAIN 0x10000000 /* analog master amp +6dB, model 039? */
-#define CM_TXVX 0x08000000 /* model 037? */
-#define CM_N4SPK3D 0x04000000 /* copy front to rear */
-#define CM_SPDO5V 0x02000000 /* 5V spdif output (1 = 0.5v (coax)) */
-#define CM_SPDIF48K 0x01000000 /* write */
-#define CM_SPATUS48K 0x01000000 /* read */
-#define CM_ENDBDAC 0x00800000 /* enable double dac */
-#define CM_XCHGDAC 0x00400000 /* 0: front=ch0, 1: front=ch1 */
-#define CM_SPD32SEL 0x00200000 /* 0: 16bit SPDIF, 1: 32bit */
-#define CM_SPDFLOOPI 0x00100000 /* int. SPDIF-OUT -> int. IN */
-#define CM_FM_EN 0x00080000 /* enable legacy FM */
-#define CM_AC3EN2 0x00040000 /* enable AC3: model 039 */
-#define CM_ENWRASID 0x00010000 /* choose writable internal SUBID (audio) */
-#define CM_VIDWPDSB 0x00010000 /* model 037? */
-#define CM_SPDF_AC97 0x00008000 /* 0: SPDIF/OUT 44.1K, 1: 48K */
-#define CM_MASK_EN 0x00004000 /* activate channel mask on legacy DMA */
-#define CM_ENWRMSID 0x00002000 /* choose writable internal SUBID (modem) */
-#define CM_VIDWPPRT 0x00002000 /* model 037? */
-#define CM_SFILENB 0x00001000 /* filter stepping at front end DAC, model 037? */
-#define CM_MMODE_MASK 0x00000E00 /* model DAA interface mode */
-#define CM_SPDIF_SELECT2 0x00000100 /* for model > 039 ? */
-#define CM_ENCENTER 0x00000080
-#define CM_FLINKON 0x00000040 /* force modem link detection on, model 037 */
-#define CM_MUTECH1 0x00000040 /* mute PCI ch1 to DAC */
-#define CM_FLINKOFF 0x00000020 /* force modem link detection off, model 037 */
-#define CM_MIDSMP 0x00000010 /* 1/2 interpolation at front end DAC */
-#define CM_UPDDMA_MASK 0x0000000C /* TDMA position update notification */
-#define CM_UPDDMA_2048 0x00000000
-#define CM_UPDDMA_1024 0x00000004
-#define CM_UPDDMA_512 0x00000008
-#define CM_UPDDMA_256 0x0000000C
-#define CM_TWAIT_MASK 0x00000003 /* model 037 */
-#define CM_TWAIT1 0x00000002 /* FM i/o cycle, 0: 48, 1: 64 PCICLKs */
-#define CM_TWAIT0 0x00000001 /* i/o cycle, 0: 4, 1: 6 PCICLKs */
-
-#define CM_REG_TDMA_POSITION 0x1C
-#define CM_TDMA_CNT_MASK 0xFFFF0000 /* current byte/word count */
-#define CM_TDMA_ADR_MASK 0x0000FFFF /* current address */
-
- /* byte */
-#define CM_REG_MIXER0 0x20
-#define CM_REG_SBVR 0x20 /* write: sb16 version */
-#define CM_REG_DEV 0x20 /* read: hardware device version */
-
-#define CM_REG_MIXER21 0x21
-#define CM_UNKNOWN_21_MASK 0x78 /* ? */
-#define CM_X_ADPCM 0x04 /* SB16 ADPCM enable */
-#define CM_PROINV 0x02 /* SBPro left/right channel switching */
-#define CM_X_SB16 0x01 /* SB16 compatible */
-
-#define CM_REG_SB16_DATA 0x22
-#define CM_REG_SB16_ADDR 0x23
-
-#define CM_REFFREQ_XIN (315*1000*1000)/22 /* 14.31818 Mhz reference clock frequency pin XIN */
-#define CM_ADCMULT_XIN 512 /* Guessed (487 best for 44.1kHz, not for 88/176kHz) */
-#define CM_TOLERANCE_RATE 0.001 /* Tolerance sample rate pitch (1000ppm) */
-#define CM_MAXIMUM_RATE 80000000 /* Note more than 80MHz */
-
-#define CM_REG_MIXER1 0x24
-#define CM_FMMUTE 0x80 /* mute FM */
-#define CM_FMMUTE_SHIFT 7
-#define CM_WSMUTE 0x40 /* mute PCM */
-#define CM_WSMUTE_SHIFT 6
-#define CM_REAR2LIN 0x20 /* lin-in -> rear line out */
-#define CM_REAR2LIN_SHIFT 5
-#define CM_REAR2FRONT 0x10 /* exchange rear/front */
-#define CM_REAR2FRONT_SHIFT 4
-#define CM_WAVEINL 0x08 /* digital wave rec. left chan */
-#define CM_WAVEINL_SHIFT 3
-#define CM_WAVEINR 0x04 /* digical wave rec. right */
-#define CM_WAVEINR_SHIFT 2
-#define CM_X3DEN 0x02 /* 3D surround enable */
-#define CM_X3DEN_SHIFT 1
-#define CM_CDPLAY 0x01 /* enable SPDIF/IN PCM -> DAC */
-#define CM_CDPLAY_SHIFT 0
-
-#define CM_REG_MIXER2 0x25
-#define CM_RAUXREN 0x80 /* AUX right capture */
-#define CM_RAUXREN_SHIFT 7
-#define CM_RAUXLEN 0x40 /* AUX left capture */
-#define CM_RAUXLEN_SHIFT 6
-#define CM_VAUXRM 0x20 /* AUX right mute */
-#define CM_VAUXRM_SHIFT 5
-#define CM_VAUXLM 0x10 /* AUX left mute */
-#define CM_VAUXLM_SHIFT 4
-#define CM_VADMIC_MASK 0x0e /* mic gain level (0-3) << 1 */
-#define CM_VADMIC_SHIFT 1
-#define CM_MICGAINZ 0x01 /* mic boost */
-#define CM_MICGAINZ_SHIFT 0
-
-#define CM_REG_MIXER3 0x24
-#define CM_REG_AUX_VOL 0x26
-#define CM_VAUXL_MASK 0xf0
-#define CM_VAUXR_MASK 0x0f
-
-#define CM_REG_MISC 0x27
-#define CM_UNKNOWN_27_MASK 0xd8 /* ? */
-#define CM_XGPO1 0x20
-// #define CM_XGPBIO 0x04
-#define CM_MIC_CENTER_LFE 0x04 /* mic as center/lfe out? (model 039 or later?) */
-#define CM_SPDIF_INVERSE 0x04 /* spdif input phase inverse (model 037) */
-#define CM_SPDVALID 0x02 /* spdif input valid check */
-#define CM_DMAUTO 0x01 /* SB16 DMA auto detect */
-
-#define CM_REG_AC97 0x28 /* hmmm.. do we have ac97 link? */
-/*
- * For CMI-8338 (0x28 - 0x2b) .. is this valid for CMI-8738
- * or identical with AC97 codec?
- */
-#define CM_REG_EXTERN_CODEC CM_REG_AC97
-
-/*
- * MPU401 pci port index address 0x40 - 0x4f (CMI-8738 spec ver. 0.6)
- */
-#define CM_REG_MPU_PCI 0x40
-
-/*
- * FM pci port index address 0x50 - 0x5f (CMI-8738 spec ver. 0.6)
- */
-#define CM_REG_FM_PCI 0x50
-
-/*
- * access from SB-mixer port
- */
-#define CM_REG_EXTENT_IND 0xf0
-#define CM_VPHONE_MASK 0xe0 /* Phone volume control (0-3) << 5 */
-#define CM_VPHONE_SHIFT 5
-#define CM_VPHOM 0x10 /* Phone mute control */
-#define CM_VSPKM 0x08 /* Speaker mute control, default high */
-#define CM_RLOOPREN 0x04 /* Rec. R-channel enable */
-#define CM_RLOOPLEN 0x02 /* Rec. L-channel enable */
-#define CM_VADMIC3 0x01 /* Mic record boost */
-
-/*
- * CMI-8338 spec ver 0.5 (this is not valid for CMI-8738):
- * the 8 registers 0xf8 - 0xff are used for programming m/n counter by the PLL
- * unit (readonly?).
- */
-#define CM_REG_PLL 0xf8
-
-/*
- * extended registers
- */
-#define CM_REG_CH0_FRAME1 0x80 /* write: base address */
-#define CM_REG_CH0_FRAME2 0x84 /* read: current address */
-#define CM_REG_CH1_FRAME1 0x88 /* 0-15: count of samples at bus master; buffer size */
-#define CM_REG_CH1_FRAME2 0x8C /* 16-31: count of samples at codec; fragment size */
-
-#define CM_REG_EXT_MISC 0x90
-#define CM_ADC48K44K 0x10000000 /* ADC parameters group, 0: 44k, 1: 48k */
-#define CM_CHB3D8C 0x00200000 /* 7.1 channels support */
-#define CM_SPD32FMT 0x00100000 /* SPDIF/IN 32k sample rate */
-#define CM_ADC2SPDIF 0x00080000 /* ADC output to SPDIF/OUT */
-#define CM_SHAREADC 0x00040000 /* DAC in ADC as Center/LFE */
-#define CM_REALTCMP 0x00020000 /* monitor the CMPL/CMPR of ADC */
-#define CM_INVLRCK 0x00010000 /* invert ZVPORT's LRCK */
-#define CM_UNKNOWN_90_MASK 0x0000FFFF /* ? */
-
-/*
- * size of i/o region
- */
-#define CM_EXTENT_CODEC 0x100
-#define CM_EXTENT_MIDI 0x2
-#define CM_EXTENT_SYNTH 0x4
-
-
-/*
- * channels for playback / capture
- */
-#define CM_CH_PLAY 0
-#define CM_CH_CAPT 1
-
-/*
- * flags to check device open/close
- */
-#define CM_OPEN_NONE 0
-#define CM_OPEN_CH_MASK 0x01
-#define CM_OPEN_DAC 0x10
-#define CM_OPEN_ADC 0x20
-#define CM_OPEN_SPDIF 0x40
-#define CM_OPEN_MCHAN 0x80
-#define CM_OPEN_PLAYBACK (CM_CH_PLAY | CM_OPEN_DAC)
-#define CM_OPEN_PLAYBACK2 (CM_CH_CAPT | CM_OPEN_DAC)
-#define CM_OPEN_PLAYBACK_MULTI (CM_CH_PLAY | CM_OPEN_DAC | CM_OPEN_MCHAN)
-#define CM_OPEN_CAPTURE (CM_CH_CAPT | CM_OPEN_ADC)
-#define CM_OPEN_SPDIF_PLAYBACK (CM_CH_PLAY | CM_OPEN_DAC | CM_OPEN_SPDIF)
-#define CM_OPEN_SPDIF_CAPTURE (CM_CH_CAPT | CM_OPEN_ADC | CM_OPEN_SPDIF)
-
-
-#if CM_CH_PLAY == 1
-#define CM_PLAYBACK_SRATE_176K CM_CH1_SRATE_176K
-#define CM_PLAYBACK_SPDF CM_SPDF_1
-#define CM_CAPTURE_SPDF CM_SPDF_0
-#else
-#define CM_PLAYBACK_SRATE_176K CM_CH0_SRATE_176K
-#define CM_PLAYBACK_SPDF CM_SPDF_0
-#define CM_CAPTURE_SPDF CM_SPDF_1
-#endif
-
-
-/*
- * driver data
- */
-
-struct cmipci_pcm {
- struct snd_pcm_substream *substream;
- u8 running; /* dac/adc running? */
- u8 fmt; /* format bits */
- u8 is_dac;
- u8 needs_silencing;
- unsigned int dma_size; /* in frames */
- unsigned int shift;
- unsigned int ch; /* channel (0/1) */
- unsigned int offset; /* physical address of the buffer */
-};
-
-/* mixer elements toggled/resumed during ac3 playback */
-struct cmipci_mixer_auto_switches {
- const char *name; /* switch to toggle */
- int toggle_on; /* value to change when ac3 mode */
-};
-static const struct cmipci_mixer_auto_switches cm_saved_mixer[] = {
- {"PCM Playback Switch", 0},
- {"IEC958 Output Switch", 1},
- {"IEC958 Mix Analog", 0},
- // {"IEC958 Out To DAC", 1}, // no longer used
- {"IEC958 Loop", 0},
-};
-#define CM_SAVED_MIXERS ARRAY_SIZE(cm_saved_mixer)
-
-struct cmipci {
- struct snd_card *card;
-
- struct pci_dev *pci;
- unsigned int device; /* device ID */
- int irq;
-
- unsigned long iobase;
- unsigned int ctrl; /* FUNCTRL0 current value */
-
- struct snd_pcm *pcm; /* DAC/ADC PCM */
- struct snd_pcm *pcm2; /* 2nd DAC */
- struct snd_pcm *pcm_spdif; /* SPDIF */
-
- int chip_version;
- int max_channels;
- unsigned int can_ac3_sw: 1;
- unsigned int can_ac3_hw: 1;
- unsigned int can_multi_ch: 1;
- unsigned int can_96k: 1; /* samplerate above 48k */
- unsigned int do_soft_ac3: 1;
-
- unsigned int spdif_playback_avail: 1; /* spdif ready? */
- unsigned int spdif_playback_enabled: 1; /* spdif switch enabled? */
- int spdif_counter; /* for software AC3 */
-
- unsigned int dig_status;
- unsigned int dig_pcm_status;
-
- struct snd_pcm_hardware *hw_info[3]; /* for playbacks */
-
- int opened[2]; /* open mode */
- struct mutex open_mutex;
-
- unsigned int mixer_insensitive: 1;
- struct snd_kcontrol *mixer_res_ctl[CM_SAVED_MIXERS];
- int mixer_res_status[CM_SAVED_MIXERS];
-
- struct cmipci_pcm channel[2]; /* ch0 - DAC, ch1 - ADC or 2nd DAC */
-
- /* external MIDI */
- struct snd_rawmidi *rmidi;
-
-#ifdef SUPPORT_JOYSTICK
- struct gameport *gameport;
-#endif
-
- spinlock_t reg_lock;
-
-#ifdef CONFIG_PM
- unsigned int saved_regs[0x20];
- unsigned char saved_mixers[0x20];
-#endif
-};
-
-
-/* read/write operations for dword register */
-static inline void snd_cmipci_write(struct cmipci *cm, unsigned int cmd, unsigned int data)
-{
- outl(data, cm->iobase + cmd);
-}
-
-static inline unsigned int snd_cmipci_read(struct cmipci *cm, unsigned int cmd)
-{
- return inl(cm->iobase + cmd);
-}
-
-/* read/write operations for word register */
-static inline void snd_cmipci_write_w(struct cmipci *cm, unsigned int cmd, unsigned short data)
-{
- outw(data, cm->iobase + cmd);
-}
-
-static inline unsigned short snd_cmipci_read_w(struct cmipci *cm, unsigned int cmd)
-{
- return inw(cm->iobase + cmd);
-}
-
-/* read/write operations for byte register */
-static inline void snd_cmipci_write_b(struct cmipci *cm, unsigned int cmd, unsigned char data)
-{
- outb(data, cm->iobase + cmd);
-}
-
-static inline unsigned char snd_cmipci_read_b(struct cmipci *cm, unsigned int cmd)
-{
- return inb(cm->iobase + cmd);
-}
-
-/* bit operations for dword register */
-static int snd_cmipci_set_bit(struct cmipci *cm, unsigned int cmd, unsigned int flag)
-{
- unsigned int val, oval;
- val = oval = inl(cm->iobase + cmd);
- val |= flag;
- if (val == oval)
- return 0;
- outl(val, cm->iobase + cmd);
- return 1;
-}
-
-static int snd_cmipci_clear_bit(struct cmipci *cm, unsigned int cmd, unsigned int flag)
-{
- unsigned int val, oval;
- val = oval = inl(cm->iobase + cmd);
- val &= ~flag;
- if (val == oval)
- return 0;
- outl(val, cm->iobase + cmd);
- return 1;
-}
-
-/* bit operations for byte register */
-static int snd_cmipci_set_bit_b(struct cmipci *cm, unsigned int cmd, unsigned char flag)
-{
- unsigned char val, oval;
- val = oval = inb(cm->iobase + cmd);
- val |= flag;
- if (val == oval)
- return 0;
- outb(val, cm->iobase + cmd);
- return 1;
-}
-
-static int snd_cmipci_clear_bit_b(struct cmipci *cm, unsigned int cmd, unsigned char flag)
-{
- unsigned char val, oval;
- val = oval = inb(cm->iobase + cmd);
- val &= ~flag;
- if (val == oval)
- return 0;
- outb(val, cm->iobase + cmd);
- return 1;
-}
-
-
-/*
- * PCM interface
- */
-
-/*
- * calculate frequency
- */
-
-static unsigned int rates[] = { 5512, 11025, 22050, 44100, 8000, 16000, 32000, 48000 };
-
-static unsigned int snd_cmipci_rate_freq(unsigned int rate)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(rates); i++) {
- if (rates[i] == rate)
- return i;
- }
- snd_BUG();
- return 0;
-}
-
-#ifdef USE_VAR48KRATE
-/*
- * Determine PLL values for frequency setup, maybe the CMI8338 (CMI8738???)
- * does it this way .. maybe not. Never get any information from C-Media about
- * that <werner@suse.de>.
- */
-static int snd_cmipci_pll_rmn(unsigned int rate, unsigned int adcmult, int *r, int *m, int *n)
-{
- unsigned int delta, tolerance;
- int xm, xn, xr;
-
- for (*r = 0; rate < CM_MAXIMUM_RATE/adcmult; *r += (1<<5))
- rate <<= 1;
- *n = -1;
- if (*r > 0xff)
- goto out;
- tolerance = rate*CM_TOLERANCE_RATE;
-
- for (xn = (1+2); xn < (0x1f+2); xn++) {
- for (xm = (1+2); xm < (0xff+2); xm++) {
- xr = ((CM_REFFREQ_XIN/adcmult) * xm) / xn;
-
- if (xr < rate)
- delta = rate - xr;
- else
- delta = xr - rate;
-
- /*
- * If we found one, remember this,
- * and try to find a closer one
- */
- if (delta < tolerance) {
- tolerance = delta;
- *m = xm - 2;
- *n = xn - 2;
- }
- }
- }
-out:
- return (*n > -1);
-}
-
-/*
- * Program pll register bits, I assume that the 8 registers 0xf8 up to 0xff
- * are mapped onto the 8 ADC/DAC sampling frequency which can be chosen
- * at the register CM_REG_FUNCTRL1 (0x04).
- * Problem: other ways are also possible (any information about that?)
- */
-static void snd_cmipci_set_pll(struct cmipci *cm, unsigned int rate, unsigned int slot)
-{
- unsigned int reg = CM_REG_PLL + slot;
- /*
- * Guess that this programs at reg. 0x04 the pos 15:13/12:10
- * for DSFC/ASFC (000 up to 111).
- */
-
- /* FIXME: Init (Do we've to set an other register first before programming?) */
-
- /* FIXME: Is this correct? Or shouldn't the m/n/r values be used for that? */
- snd_cmipci_write_b(cm, reg, rate>>8);
- snd_cmipci_write_b(cm, reg, rate&0xff);
-
- /* FIXME: Setup (Do we've to set an other register first to enable this?) */
-}
-#endif /* USE_VAR48KRATE */
-
-static int snd_cmipci_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static int snd_cmipci_playback2_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
- if (params_channels(hw_params) > 2) {
- mutex_lock(&cm->open_mutex);
- if (cm->opened[CM_CH_PLAY]) {
- mutex_unlock(&cm->open_mutex);
- return -EBUSY;
- }
- /* reserve the channel A */
- cm->opened[CM_CH_PLAY] = CM_OPEN_PLAYBACK_MULTI;
- mutex_unlock(&cm->open_mutex);
- }
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static void snd_cmipci_ch_reset(struct cmipci *cm, int ch)
-{
- int reset = CM_RST_CH0 << (cm->channel[ch].ch);
- snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl | reset);
- snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl & ~reset);
- udelay(10);
-}
-
-static int snd_cmipci_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-
-/*
- */
-
-static unsigned int hw_channels[] = {1, 2, 4, 6, 8};
-static struct snd_pcm_hw_constraint_list hw_constraints_channels_4 = {
- .count = 3,
- .list = hw_channels,
- .mask = 0,
-};
-static struct snd_pcm_hw_constraint_list hw_constraints_channels_6 = {
- .count = 4,
- .list = hw_channels,
- .mask = 0,
-};
-static struct snd_pcm_hw_constraint_list hw_constraints_channels_8 = {
- .count = 5,
- .list = hw_channels,
- .mask = 0,
-};
-
-static int set_dac_channels(struct cmipci *cm, struct cmipci_pcm *rec, int channels)
-{
- if (channels > 2) {
- if (!cm->can_multi_ch || !rec->ch)
- return -EINVAL;
- if (rec->fmt != 0x03) /* stereo 16bit only */
- return -EINVAL;
- }
-
- if (cm->can_multi_ch) {
- spin_lock_irq(&cm->reg_lock);
- if (channels > 2) {
- snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG);
- snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
- } else {
- snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG);
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
- }
- if (channels == 8)
- snd_cmipci_set_bit(cm, CM_REG_EXT_MISC, CM_CHB3D8C);
- else
- snd_cmipci_clear_bit(cm, CM_REG_EXT_MISC, CM_CHB3D8C);
- if (channels == 6) {
- snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C);
- snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C);
- } else {
- snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C);
- snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C);
- }
- if (channels == 4)
- snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
- else
- snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
- spin_unlock_irq(&cm->reg_lock);
- }
- return 0;
-}
-
-
-/*
- * prepare playback/capture channel
- * channel to be used must have been set in rec->ch.
- */
-static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec,
- struct snd_pcm_substream *substream)
-{
- unsigned int reg, freq, freq_ext, val;
- unsigned int period_size;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- rec->fmt = 0;
- rec->shift = 0;
- if (snd_pcm_format_width(runtime->format) >= 16) {
- rec->fmt |= 0x02;
- if (snd_pcm_format_width(runtime->format) > 16)
- rec->shift++; /* 24/32bit */
- }
- if (runtime->channels > 1)
- rec->fmt |= 0x01;
- if (rec->is_dac && set_dac_channels(cm, rec, runtime->channels) < 0) {
- snd_printd("cannot set dac channels\n");
- return -EINVAL;
- }
-
- rec->offset = runtime->dma_addr;
- /* buffer and period sizes in frame */
- rec->dma_size = runtime->buffer_size << rec->shift;
- period_size = runtime->period_size << rec->shift;
- if (runtime->channels > 2) {
- /* multi-channels */
- rec->dma_size = (rec->dma_size * runtime->channels) / 2;
- period_size = (period_size * runtime->channels) / 2;
- }
-
- spin_lock_irq(&cm->reg_lock);
-
- /* set buffer address */
- reg = rec->ch ? CM_REG_CH1_FRAME1 : CM_REG_CH0_FRAME1;
- snd_cmipci_write(cm, reg, rec->offset);
- /* program sample counts */
- reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2;
- snd_cmipci_write_w(cm, reg, rec->dma_size - 1);
- snd_cmipci_write_w(cm, reg + 2, period_size - 1);
-
- /* set adc/dac flag */
- val = rec->ch ? CM_CHADC1 : CM_CHADC0;
- if (rec->is_dac)
- cm->ctrl &= ~val;
- else
- cm->ctrl |= val;
- snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl);
- //snd_printd("cmipci: functrl0 = %08x\n", cm->ctrl);
-
- /* set sample rate */
- freq = 0;
- freq_ext = 0;
- if (runtime->rate > 48000)
- switch (runtime->rate) {
- case 88200: freq_ext = CM_CH0_SRATE_88K; break;
- case 96000: freq_ext = CM_CH0_SRATE_96K; break;
- case 128000: freq_ext = CM_CH0_SRATE_128K; break;
- default: snd_BUG(); break;
- }
- else
- freq = snd_cmipci_rate_freq(runtime->rate);
- val = snd_cmipci_read(cm, CM_REG_FUNCTRL1);
- if (rec->ch) {
- val &= ~CM_DSFC_MASK;
- val |= (freq << CM_DSFC_SHIFT) & CM_DSFC_MASK;
- } else {
- val &= ~CM_ASFC_MASK;
- val |= (freq << CM_ASFC_SHIFT) & CM_ASFC_MASK;
- }
- snd_cmipci_write(cm, CM_REG_FUNCTRL1, val);
- //snd_printd("cmipci: functrl1 = %08x\n", val);
-
- /* set format */
- val = snd_cmipci_read(cm, CM_REG_CHFORMAT);
- if (rec->ch) {
- val &= ~CM_CH1FMT_MASK;
- val |= rec->fmt << CM_CH1FMT_SHIFT;
- } else {
- val &= ~CM_CH0FMT_MASK;
- val |= rec->fmt << CM_CH0FMT_SHIFT;
- }
- if (cm->can_96k) {
- val &= ~(CM_CH0_SRATE_MASK << (rec->ch * 2));
- val |= freq_ext << (rec->ch * 2);
- }
- snd_cmipci_write(cm, CM_REG_CHFORMAT, val);
- //snd_printd("cmipci: chformat = %08x\n", val);
-
- if (!rec->is_dac && cm->chip_version) {
- if (runtime->rate > 44100)
- snd_cmipci_set_bit(cm, CM_REG_EXT_MISC, CM_ADC48K44K);
- else
- snd_cmipci_clear_bit(cm, CM_REG_EXT_MISC, CM_ADC48K44K);
- }
-
- rec->running = 0;
- spin_unlock_irq(&cm->reg_lock);
-
- return 0;
-}
-
-/*
- * PCM trigger/stop
- */
-static int snd_cmipci_pcm_trigger(struct cmipci *cm, struct cmipci_pcm *rec,
- int cmd)
-{
- unsigned int inthld, chen, reset, pause;
- int result = 0;
-
- inthld = CM_CH0_INT_EN << rec->ch;
- chen = CM_CHEN0 << rec->ch;
- reset = CM_RST_CH0 << rec->ch;
- pause = CM_PAUSE0 << rec->ch;
-
- spin_lock(&cm->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- rec->running = 1;
- /* set interrupt */
- snd_cmipci_set_bit(cm, CM_REG_INT_HLDCLR, inthld);
- cm->ctrl |= chen;
- /* enable channel */
- snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl);
- //snd_printd("cmipci: functrl0 = %08x\n", cm->ctrl);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- rec->running = 0;
- /* disable interrupt */
- snd_cmipci_clear_bit(cm, CM_REG_INT_HLDCLR, inthld);
- /* reset */
- cm->ctrl &= ~chen;
- snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl | reset);
- snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl & ~reset);
- rec->needs_silencing = rec->is_dac;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- cm->ctrl |= pause;
- snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl);
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
- cm->ctrl &= ~pause;
- snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl);
- break;
- default:
- result = -EINVAL;
- break;
- }
- spin_unlock(&cm->reg_lock);
- return result;
-}
-
-/*
- * return the current pointer
- */
-static snd_pcm_uframes_t snd_cmipci_pcm_pointer(struct cmipci *cm, struct cmipci_pcm *rec,
- struct snd_pcm_substream *substream)
-{
- size_t ptr;
- unsigned int reg, rem, tries;
-
- if (!rec->running)
- return 0;
-#if 1 // this seems better..
- reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2;
- for (tries = 0; tries < 3; tries++) {
- rem = snd_cmipci_read_w(cm, reg);
- if (rem < rec->dma_size)
- goto ok;
- }
- printk(KERN_ERR "cmipci: invalid PCM pointer: %#x\n", rem);
- return SNDRV_PCM_POS_XRUN;
-ok:
- ptr = (rec->dma_size - (rem + 1)) >> rec->shift;
-#else
- reg = rec->ch ? CM_REG_CH1_FRAME1 : CM_REG_CH0_FRAME1;
- ptr = snd_cmipci_read(cm, reg) - rec->offset;
- ptr = bytes_to_frames(substream->runtime, ptr);
-#endif
- if (substream->runtime->channels > 2)
- ptr = (ptr * 2) / substream->runtime->channels;
- return ptr;
-}
-
-/*
- * playback
- */
-
-static int snd_cmipci_playback_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
- return snd_cmipci_pcm_trigger(cm, &cm->channel[CM_CH_PLAY], cmd);
-}
-
-static snd_pcm_uframes_t snd_cmipci_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
- return snd_cmipci_pcm_pointer(cm, &cm->channel[CM_CH_PLAY], substream);
-}
-
-
-
-/*
- * capture
- */
-
-static int snd_cmipci_capture_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
- return snd_cmipci_pcm_trigger(cm, &cm->channel[CM_CH_CAPT], cmd);
-}
-
-static snd_pcm_uframes_t snd_cmipci_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
- return snd_cmipci_pcm_pointer(cm, &cm->channel[CM_CH_CAPT], substream);
-}
-
-
-/*
- * hw preparation for spdif
- */
-
-static int snd_cmipci_spdif_default_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_cmipci_spdif_default_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cmipci *chip = snd_kcontrol_chip(kcontrol);
- int i;
-
- spin_lock_irq(&chip->reg_lock);
- for (i = 0; i < 4; i++)
- ucontrol->value.iec958.status[i] = (chip->dig_status >> (i * 8)) & 0xff;
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static int snd_cmipci_spdif_default_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cmipci *chip = snd_kcontrol_chip(kcontrol);
- int i, change;
- unsigned int val;
-
- val = 0;
- spin_lock_irq(&chip->reg_lock);
- for (i = 0; i < 4; i++)
- val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8);
- change = val != chip->dig_status;
- chip->dig_status = val;
- spin_unlock_irq(&chip->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_cmipci_spdif_default __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
- .info = snd_cmipci_spdif_default_info,
- .get = snd_cmipci_spdif_default_get,
- .put = snd_cmipci_spdif_default_put
-};
-
-static int snd_cmipci_spdif_mask_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_cmipci_spdif_mask_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.iec958.status[0] = 0xff;
- ucontrol->value.iec958.status[1] = 0xff;
- ucontrol->value.iec958.status[2] = 0xff;
- ucontrol->value.iec958.status[3] = 0xff;
- return 0;
-}
-
-static struct snd_kcontrol_new snd_cmipci_spdif_mask __devinitdata =
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
- .info = snd_cmipci_spdif_mask_info,
- .get = snd_cmipci_spdif_mask_get,
-};
-
-static int snd_cmipci_spdif_stream_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_cmipci_spdif_stream_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cmipci *chip = snd_kcontrol_chip(kcontrol);
- int i;
-
- spin_lock_irq(&chip->reg_lock);
- for (i = 0; i < 4; i++)
- ucontrol->value.iec958.status[i] = (chip->dig_pcm_status >> (i * 8)) & 0xff;
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static int snd_cmipci_spdif_stream_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cmipci *chip = snd_kcontrol_chip(kcontrol);
- int i, change;
- unsigned int val;
-
- val = 0;
- spin_lock_irq(&chip->reg_lock);
- for (i = 0; i < 4; i++)
- val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8);
- change = val != chip->dig_pcm_status;
- chip->dig_pcm_status = val;
- spin_unlock_irq(&chip->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_cmipci_spdif_stream __devinitdata =
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
- .info = snd_cmipci_spdif_stream_info,
- .get = snd_cmipci_spdif_stream_get,
- .put = snd_cmipci_spdif_stream_put
-};
-
-/*
- */
-
-/* save mixer setting and mute for AC3 playback */
-static int save_mixer_state(struct cmipci *cm)
-{
- if (! cm->mixer_insensitive) {
- struct snd_ctl_elem_value *val;
- unsigned int i;
-
- val = kmalloc(sizeof(*val), GFP_ATOMIC);
- if (!val)
- return -ENOMEM;
- for (i = 0; i < CM_SAVED_MIXERS; i++) {
- struct snd_kcontrol *ctl = cm->mixer_res_ctl[i];
- if (ctl) {
- int event;
- memset(val, 0, sizeof(*val));
- ctl->get(ctl, val);
- cm->mixer_res_status[i] = val->value.integer.value[0];
- val->value.integer.value[0] = cm_saved_mixer[i].toggle_on;
- event = SNDRV_CTL_EVENT_MASK_INFO;
- if (cm->mixer_res_status[i] != val->value.integer.value[0]) {
- ctl->put(ctl, val); /* toggle */
- event |= SNDRV_CTL_EVENT_MASK_VALUE;
- }
- ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(cm->card, event, &ctl->id);
- }
- }
- kfree(val);
- cm->mixer_insensitive = 1;
- }
- return 0;
-}
-
-
-/* restore the previously saved mixer status */
-static void restore_mixer_state(struct cmipci *cm)
-{
- if (cm->mixer_insensitive) {
- struct snd_ctl_elem_value *val;
- unsigned int i;
-
- val = kmalloc(sizeof(*val), GFP_KERNEL);
- if (!val)
- return;
- cm->mixer_insensitive = 0; /* at first clear this;
- otherwise the changes will be ignored */
- for (i = 0; i < CM_SAVED_MIXERS; i++) {
- struct snd_kcontrol *ctl = cm->mixer_res_ctl[i];
- if (ctl) {
- int event;
-
- memset(val, 0, sizeof(*val));
- ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- ctl->get(ctl, val);
- event = SNDRV_CTL_EVENT_MASK_INFO;
- if (val->value.integer.value[0] != cm->mixer_res_status[i]) {
- val->value.integer.value[0] = cm->mixer_res_status[i];
- ctl->put(ctl, val);
- event |= SNDRV_CTL_EVENT_MASK_VALUE;
- }
- snd_ctl_notify(cm->card, event, &ctl->id);
- }
- }
- kfree(val);
- }
-}
-
-/* spinlock held! */
-static void setup_ac3(struct cmipci *cm, struct snd_pcm_substream *subs, int do_ac3, int rate)
-{
- if (do_ac3) {
- /* AC3EN for 037 */
- snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_AC3EN1);
- /* AC3EN for 039 */
- snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_AC3EN2);
-
- if (cm->can_ac3_hw) {
- /* SPD24SEL for 037, 0x02 */
- /* SPD24SEL for 039, 0x20, but cannot be set */
- snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_SPD24SEL);
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
- } else { /* can_ac3_sw */
- /* SPD32SEL for 037 & 039, 0x20 */
- snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
- /* set 176K sample rate to fix 033 HW bug */
- if (cm->chip_version == 33) {
- if (rate >= 48000) {
- snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_PLAYBACK_SRATE_176K);
- } else {
- snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_PLAYBACK_SRATE_176K);
- }
- }
- }
-
- } else {
- snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_AC3EN1);
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_AC3EN2);
-
- if (cm->can_ac3_hw) {
- /* chip model >= 37 */
- if (snd_pcm_format_width(subs->runtime->format) > 16) {
- snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
- snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_SPD24SEL);
- } else {
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
- snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_SPD24SEL);
- }
- } else {
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
- snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_SPD24SEL);
- snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_PLAYBACK_SRATE_176K);
- }
- }
-}
-
-static int setup_spdif_playback(struct cmipci *cm, struct snd_pcm_substream *subs, int up, int do_ac3)
-{
- int rate, err;
-
- rate = subs->runtime->rate;
-
- if (up && do_ac3)
- if ((err = save_mixer_state(cm)) < 0)
- return err;
-
- spin_lock_irq(&cm->reg_lock);
- cm->spdif_playback_avail = up;
- if (up) {
- /* they are controlled via "IEC958 Output Switch" */
- /* snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_ENSPDOUT); */
- /* snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_SPDO2DAC); */
- if (cm->spdif_playback_enabled)
- snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_PLAYBACK_SPDF);
- setup_ac3(cm, subs, do_ac3, rate);
-
- if (rate == 48000 || rate == 96000)
- snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPDIF48K | CM_SPDF_AC97);
- else
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPDIF48K | CM_SPDF_AC97);
- if (rate > 48000)
- snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS);
- else
- snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS);
- } else {
- /* they are controlled via "IEC958 Output Switch" */
- /* snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_ENSPDOUT); */
- /* snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_SPDO2DAC); */
- snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS);
- snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_PLAYBACK_SPDF);
- setup_ac3(cm, subs, 0, 0);
- }
- spin_unlock_irq(&cm->reg_lock);
- return 0;
-}
-
-
-/*
- * preparation
- */
-
-/* playback - enable spdif only on the certain condition */
-static int snd_cmipci_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
- int rate = substream->runtime->rate;
- int err, do_spdif, do_ac3 = 0;
-
- do_spdif = (rate >= 44100 && rate <= 96000 &&
- substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE &&
- substream->runtime->channels == 2);
- if (do_spdif && cm->can_ac3_hw)
- do_ac3 = cm->dig_pcm_status & IEC958_AES0_NONAUDIO;
- if ((err = setup_spdif_playback(cm, substream, do_spdif, do_ac3)) < 0)
- return err;
- return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_PLAY], substream);
-}
-
-/* playback (via device #2) - enable spdif always */
-static int snd_cmipci_playback_spdif_prepare(struct snd_pcm_substream *substream)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
- int err, do_ac3;
-
- if (cm->can_ac3_hw)
- do_ac3 = cm->dig_pcm_status & IEC958_AES0_NONAUDIO;
- else
- do_ac3 = 1; /* doesn't matter */
- if ((err = setup_spdif_playback(cm, substream, 1, do_ac3)) < 0)
- return err;
- return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_PLAY], substream);
-}
-
-/*
- * Apparently, the samples last played on channel A stay in some buffer, even
- * after the channel is reset, and get added to the data for the rear DACs when
- * playing a multichannel stream on channel B. This is likely to generate
- * wraparounds and thus distortions.
- * To avoid this, we play at least one zero sample after the actual stream has
- * stopped.
- */
-static void snd_cmipci_silence_hack(struct cmipci *cm, struct cmipci_pcm *rec)
-{
- struct snd_pcm_runtime *runtime = rec->substream->runtime;
- unsigned int reg, val;
-
- if (rec->needs_silencing && runtime && runtime->dma_area) {
- /* set up a small silence buffer */
- memset(runtime->dma_area, 0, PAGE_SIZE);
- reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2;
- val = ((PAGE_SIZE / 4) - 1) | (((PAGE_SIZE / 4) / 2 - 1) << 16);
- snd_cmipci_write(cm, reg, val);
-
- /* configure for 16 bits, 2 channels, 8 kHz */
- if (runtime->channels > 2)
- set_dac_channels(cm, rec, 2);
- spin_lock_irq(&cm->reg_lock);
- val = snd_cmipci_read(cm, CM_REG_FUNCTRL1);
- val &= ~(CM_ASFC_MASK << (rec->ch * 3));
- val |= (4 << CM_ASFC_SHIFT) << (rec->ch * 3);
- snd_cmipci_write(cm, CM_REG_FUNCTRL1, val);
- val = snd_cmipci_read(cm, CM_REG_CHFORMAT);
- val &= ~(CM_CH0FMT_MASK << (rec->ch * 2));
- val |= (3 << CM_CH0FMT_SHIFT) << (rec->ch * 2);
- if (cm->can_96k)
- val &= ~(CM_CH0_SRATE_MASK << (rec->ch * 2));
- snd_cmipci_write(cm, CM_REG_CHFORMAT, val);
-
- /* start stream (we don't need interrupts) */
- cm->ctrl |= CM_CHEN0 << rec->ch;
- snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl);
- spin_unlock_irq(&cm->reg_lock);
-
- msleep(1);
-
- /* stop and reset stream */
- spin_lock_irq(&cm->reg_lock);
- cm->ctrl &= ~(CM_CHEN0 << rec->ch);
- val = CM_RST_CH0 << rec->ch;
- snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl | val);
- snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl & ~val);
- spin_unlock_irq(&cm->reg_lock);
-
- rec->needs_silencing = 0;
- }
-}
-
-static int snd_cmipci_playback_hw_free(struct snd_pcm_substream *substream)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
- setup_spdif_playback(cm, substream, 0, 0);
- restore_mixer_state(cm);
- snd_cmipci_silence_hack(cm, &cm->channel[0]);
- return snd_cmipci_hw_free(substream);
-}
-
-static int snd_cmipci_playback2_hw_free(struct snd_pcm_substream *substream)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
- snd_cmipci_silence_hack(cm, &cm->channel[1]);
- return snd_cmipci_hw_free(substream);
-}
-
-/* capture */
-static int snd_cmipci_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
- return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_CAPT], substream);
-}
-
-/* capture with spdif (via device #2) */
-static int snd_cmipci_capture_spdif_prepare(struct snd_pcm_substream *substream)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&cm->reg_lock);
- snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_CAPTURE_SPDF);
- if (cm->can_96k) {
- if (substream->runtime->rate > 48000)
- snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS);
- else
- snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS);
- }
- if (snd_pcm_format_width(substream->runtime->format) > 16)
- snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
- else
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
-
- spin_unlock_irq(&cm->reg_lock);
-
- return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_CAPT], substream);
-}
-
-static int snd_cmipci_capture_spdif_hw_free(struct snd_pcm_substream *subs)
-{
- struct cmipci *cm = snd_pcm_substream_chip(subs);
-
- spin_lock_irq(&cm->reg_lock);
- snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_CAPTURE_SPDF);
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
- spin_unlock_irq(&cm->reg_lock);
-
- return snd_cmipci_hw_free(subs);
-}
-
-
-/*
- * interrupt handler
- */
-static irqreturn_t snd_cmipci_interrupt(int irq, void *dev_id)
-{
- struct cmipci *cm = dev_id;
- unsigned int status, mask = 0;
-
- /* fastpath out, to ease interrupt sharing */
- status = snd_cmipci_read(cm, CM_REG_INT_STATUS);
- if (!(status & CM_INTR))
- return IRQ_NONE;
-
- /* acknowledge interrupt */
- spin_lock(&cm->reg_lock);
- if (status & CM_CHINT0)
- mask |= CM_CH0_INT_EN;
- if (status & CM_CHINT1)
- mask |= CM_CH1_INT_EN;
- snd_cmipci_clear_bit(cm, CM_REG_INT_HLDCLR, mask);
- snd_cmipci_set_bit(cm, CM_REG_INT_HLDCLR, mask);
- spin_unlock(&cm->reg_lock);
-
- if (cm->rmidi && (status & CM_UARTINT))
- snd_mpu401_uart_interrupt(irq, cm->rmidi->private_data);
-
- if (cm->pcm) {
- if ((status & CM_CHINT0) && cm->channel[0].running)
- snd_pcm_period_elapsed(cm->channel[0].substream);
- if ((status & CM_CHINT1) && cm->channel[1].running)
- snd_pcm_period_elapsed(cm->channel[1].substream);
- }
- return IRQ_HANDLED;
-}
-
-/*
- * h/w infos
- */
-
-/* playback on channel A */
-static struct snd_pcm_hardware snd_cmipci_playback =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 5512,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 2,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-/* capture on channel B */
-static struct snd_pcm_hardware snd_cmipci_capture =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 5512,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 2,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-/* playback on channel B - stereo 16bit only? */
-static struct snd_pcm_hardware snd_cmipci_playback2 =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 5512,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 2,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-/* spdif playback on channel A */
-static struct snd_pcm_hardware snd_cmipci_playback_spdif =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
- .rate_min = 44100,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 2,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-/* spdif playback on channel A (32bit, IEC958 subframes) */
-static struct snd_pcm_hardware snd_cmipci_playback_iec958_subframe =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE,
- .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
- .rate_min = 44100,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 2,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-/* spdif capture on channel B */
-static struct snd_pcm_hardware snd_cmipci_capture_spdif =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE,
- .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
- .rate_min = 44100,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 2,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static unsigned int rate_constraints[] = { 5512, 8000, 11025, 16000, 22050,
- 32000, 44100, 48000, 88200, 96000, 128000 };
-static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
- .count = ARRAY_SIZE(rate_constraints),
- .list = rate_constraints,
- .mask = 0,
-};
-
-/*
- * check device open/close
- */
-static int open_device_check(struct cmipci *cm, int mode, struct snd_pcm_substream *subs)
-{
- int ch = mode & CM_OPEN_CH_MASK;
-
- /* FIXME: a file should wait until the device becomes free
- * when it's opened on blocking mode. however, since the current
- * pcm framework doesn't pass file pointer before actually opened,
- * we can't know whether blocking mode or not in open callback..
- */
- mutex_lock(&cm->open_mutex);
- if (cm->opened[ch]) {
- mutex_unlock(&cm->open_mutex);
- return -EBUSY;
- }
- cm->opened[ch] = mode;
- cm->channel[ch].substream = subs;
- if (! (mode & CM_OPEN_DAC)) {
- /* disable dual DAC mode */
- cm->channel[ch].is_dac = 0;
- spin_lock_irq(&cm->reg_lock);
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_ENDBDAC);
- spin_unlock_irq(&cm->reg_lock);
- }
- mutex_unlock(&cm->open_mutex);
- return 0;
-}
-
-static void close_device_check(struct cmipci *cm, int mode)
-{
- int ch = mode & CM_OPEN_CH_MASK;
-
- mutex_lock(&cm->open_mutex);
- if (cm->opened[ch] == mode) {
- if (cm->channel[ch].substream) {
- snd_cmipci_ch_reset(cm, ch);
- cm->channel[ch].running = 0;
- cm->channel[ch].substream = NULL;
- }
- cm->opened[ch] = 0;
- if (! cm->channel[ch].is_dac) {
- /* enable dual DAC mode again */
- cm->channel[ch].is_dac = 1;
- spin_lock_irq(&cm->reg_lock);
- snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_ENDBDAC);
- spin_unlock_irq(&cm->reg_lock);
- }
- }
- mutex_unlock(&cm->open_mutex);
-}
-
-/*
- */
-
-static int snd_cmipci_playback_open(struct snd_pcm_substream *substream)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- if ((err = open_device_check(cm, CM_OPEN_PLAYBACK, substream)) < 0)
- return err;
- runtime->hw = snd_cmipci_playback;
- if (cm->chip_version == 68) {
- runtime->hw.rates |= SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000;
- runtime->hw.rate_max = 96000;
- } else if (cm->chip_version == 55) {
- err = snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
- if (err < 0)
- return err;
- runtime->hw.rates |= SNDRV_PCM_RATE_KNOT;
- runtime->hw.rate_max = 128000;
- }
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000);
- cm->dig_pcm_status = cm->dig_status;
- return 0;
-}
-
-static int snd_cmipci_capture_open(struct snd_pcm_substream *substream)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- if ((err = open_device_check(cm, CM_OPEN_CAPTURE, substream)) < 0)
- return err;
- runtime->hw = snd_cmipci_capture;
- if (cm->chip_version == 68) { // 8768 only supports 44k/48k recording
- runtime->hw.rate_min = 41000;
- runtime->hw.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
- } else if (cm->chip_version == 55) {
- err = snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
- if (err < 0)
- return err;
- runtime->hw.rates |= SNDRV_PCM_RATE_KNOT;
- runtime->hw.rate_max = 128000;
- }
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000);
- return 0;
-}
-
-static int snd_cmipci_playback2_open(struct snd_pcm_substream *substream)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- if ((err = open_device_check(cm, CM_OPEN_PLAYBACK2, substream)) < 0) /* use channel B */
- return err;
- runtime->hw = snd_cmipci_playback2;
- mutex_lock(&cm->open_mutex);
- if (! cm->opened[CM_CH_PLAY]) {
- if (cm->can_multi_ch) {
- runtime->hw.channels_max = cm->max_channels;
- if (cm->max_channels == 4)
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_4);
- else if (cm->max_channels == 6)
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_6);
- else if (cm->max_channels == 8)
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_8);
- }
- }
- mutex_unlock(&cm->open_mutex);
- if (cm->chip_version == 68) {
- runtime->hw.rates |= SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000;
- runtime->hw.rate_max = 96000;
- } else if (cm->chip_version == 55) {
- err = snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
- if (err < 0)
- return err;
- runtime->hw.rates |= SNDRV_PCM_RATE_KNOT;
- runtime->hw.rate_max = 128000;
- }
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000);
- return 0;
-}
-
-static int snd_cmipci_playback_spdif_open(struct snd_pcm_substream *substream)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- if ((err = open_device_check(cm, CM_OPEN_SPDIF_PLAYBACK, substream)) < 0) /* use channel A */
- return err;
- if (cm->can_ac3_hw) {
- runtime->hw = snd_cmipci_playback_spdif;
- if (cm->chip_version >= 37) {
- runtime->hw.formats |= SNDRV_PCM_FMTBIT_S32_LE;
- snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
- }
- if (cm->can_96k) {
- runtime->hw.rates |= SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000;
- runtime->hw.rate_max = 96000;
- }
- } else {
- runtime->hw = snd_cmipci_playback_iec958_subframe;
- }
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x40000);
- cm->dig_pcm_status = cm->dig_status;
- return 0;
-}
-
-static int snd_cmipci_capture_spdif_open(struct snd_pcm_substream *substream)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- if ((err = open_device_check(cm, CM_OPEN_SPDIF_CAPTURE, substream)) < 0) /* use channel B */
- return err;
- runtime->hw = snd_cmipci_capture_spdif;
- if (cm->can_96k && !(cm->chip_version == 68)) {
- runtime->hw.rates |= SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000;
- runtime->hw.rate_max = 96000;
- }
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x40000);
- return 0;
-}
-
-
-/*
- */
-
-static int snd_cmipci_playback_close(struct snd_pcm_substream *substream)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
- close_device_check(cm, CM_OPEN_PLAYBACK);
- return 0;
-}
-
-static int snd_cmipci_capture_close(struct snd_pcm_substream *substream)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
- close_device_check(cm, CM_OPEN_CAPTURE);
- return 0;
-}
-
-static int snd_cmipci_playback2_close(struct snd_pcm_substream *substream)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
- close_device_check(cm, CM_OPEN_PLAYBACK2);
- close_device_check(cm, CM_OPEN_PLAYBACK_MULTI);
- return 0;
-}
-
-static int snd_cmipci_playback_spdif_close(struct snd_pcm_substream *substream)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
- close_device_check(cm, CM_OPEN_SPDIF_PLAYBACK);
- return 0;
-}
-
-static int snd_cmipci_capture_spdif_close(struct snd_pcm_substream *substream)
-{
- struct cmipci *cm = snd_pcm_substream_chip(substream);
- close_device_check(cm, CM_OPEN_SPDIF_CAPTURE);
- return 0;
-}
-
-
-/*
- */
-
-static struct snd_pcm_ops snd_cmipci_playback_ops = {
- .open = snd_cmipci_playback_open,
- .close = snd_cmipci_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cmipci_hw_params,
- .hw_free = snd_cmipci_playback_hw_free,
- .prepare = snd_cmipci_playback_prepare,
- .trigger = snd_cmipci_playback_trigger,
- .pointer = snd_cmipci_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_cmipci_capture_ops = {
- .open = snd_cmipci_capture_open,
- .close = snd_cmipci_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cmipci_hw_params,
- .hw_free = snd_cmipci_hw_free,
- .prepare = snd_cmipci_capture_prepare,
- .trigger = snd_cmipci_capture_trigger,
- .pointer = snd_cmipci_capture_pointer,
-};
-
-static struct snd_pcm_ops snd_cmipci_playback2_ops = {
- .open = snd_cmipci_playback2_open,
- .close = snd_cmipci_playback2_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cmipci_playback2_hw_params,
- .hw_free = snd_cmipci_playback2_hw_free,
- .prepare = snd_cmipci_capture_prepare, /* channel B */
- .trigger = snd_cmipci_capture_trigger, /* channel B */
- .pointer = snd_cmipci_capture_pointer, /* channel B */
-};
-
-static struct snd_pcm_ops snd_cmipci_playback_spdif_ops = {
- .open = snd_cmipci_playback_spdif_open,
- .close = snd_cmipci_playback_spdif_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cmipci_hw_params,
- .hw_free = snd_cmipci_playback_hw_free,
- .prepare = snd_cmipci_playback_spdif_prepare, /* set up rate */
- .trigger = snd_cmipci_playback_trigger,
- .pointer = snd_cmipci_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_cmipci_capture_spdif_ops = {
- .open = snd_cmipci_capture_spdif_open,
- .close = snd_cmipci_capture_spdif_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cmipci_hw_params,
- .hw_free = snd_cmipci_capture_spdif_hw_free,
- .prepare = snd_cmipci_capture_spdif_prepare,
- .trigger = snd_cmipci_capture_trigger,
- .pointer = snd_cmipci_capture_pointer,
-};
-
-
-/*
- */
-
-static int __devinit snd_cmipci_pcm_new(struct cmipci *cm, int device)
-{
- struct snd_pcm *pcm;
- int err;
-
- err = snd_pcm_new(cm->card, cm->card->driver, device, 1, 1, &pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cmipci_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cmipci_capture_ops);
-
- pcm->private_data = cm;
- pcm->info_flags = 0;
- strcpy(pcm->name, "C-Media PCI DAC/ADC");
- cm->pcm = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(cm->pci), 64*1024, 128*1024);
-
- return 0;
-}
-
-static int __devinit snd_cmipci_pcm2_new(struct cmipci *cm, int device)
-{
- struct snd_pcm *pcm;
- int err;
-
- err = snd_pcm_new(cm->card, cm->card->driver, device, 1, 0, &pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cmipci_playback2_ops);
-
- pcm->private_data = cm;
- pcm->info_flags = 0;
- strcpy(pcm->name, "C-Media PCI 2nd DAC");
- cm->pcm2 = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(cm->pci), 64*1024, 128*1024);
-
- return 0;
-}
-
-static int __devinit snd_cmipci_pcm_spdif_new(struct cmipci *cm, int device)
-{
- struct snd_pcm *pcm;
- int err;
-
- err = snd_pcm_new(cm->card, cm->card->driver, device, 1, 1, &pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cmipci_playback_spdif_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cmipci_capture_spdif_ops);
-
- pcm->private_data = cm;
- pcm->info_flags = 0;
- strcpy(pcm->name, "C-Media PCI IEC958");
- cm->pcm_spdif = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(cm->pci), 64*1024, 128*1024);
-
- return 0;
-}
-
-/*
- * mixer interface:
- * - CM8338/8738 has a compatible mixer interface with SB16, but
- * lack of some elements like tone control, i/o gain and AGC.
- * - Access to native registers:
- * - A 3D switch
- * - Output mute switches
- */
-
-static void snd_cmipci_mixer_write(struct cmipci *s, unsigned char idx, unsigned char data)
-{
- outb(idx, s->iobase + CM_REG_SB16_ADDR);
- outb(data, s->iobase + CM_REG_SB16_DATA);
-}
-
-static unsigned char snd_cmipci_mixer_read(struct cmipci *s, unsigned char idx)
-{
- unsigned char v;
-
- outb(idx, s->iobase + CM_REG_SB16_ADDR);
- v = inb(s->iobase + CM_REG_SB16_DATA);
- return v;
-}
-
-/*
- * general mixer element
- */
-struct cmipci_sb_reg {
- unsigned int left_reg, right_reg;
- unsigned int left_shift, right_shift;
- unsigned int mask;
- unsigned int invert: 1;
- unsigned int stereo: 1;
-};
-
-#define COMPOSE_SB_REG(lreg,rreg,lshift,rshift,mask,invert,stereo) \
- ((lreg) | ((rreg) << 8) | (lshift << 16) | (rshift << 19) | (mask << 24) | (invert << 22) | (stereo << 23))
-
-#define CMIPCI_DOUBLE(xname, left_reg, right_reg, left_shift, right_shift, mask, invert, stereo) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_cmipci_info_volume, \
- .get = snd_cmipci_get_volume, .put = snd_cmipci_put_volume, \
- .private_value = COMPOSE_SB_REG(left_reg, right_reg, left_shift, right_shift, mask, invert, stereo), \
-}
-
-#define CMIPCI_SB_VOL_STEREO(xname,reg,shift,mask) CMIPCI_DOUBLE(xname, reg, reg+1, shift, shift, mask, 0, 1)
-#define CMIPCI_SB_VOL_MONO(xname,reg,shift,mask) CMIPCI_DOUBLE(xname, reg, reg, shift, shift, mask, 0, 0)
-#define CMIPCI_SB_SW_STEREO(xname,lshift,rshift) CMIPCI_DOUBLE(xname, SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, lshift, rshift, 1, 0, 1)
-#define CMIPCI_SB_SW_MONO(xname,shift) CMIPCI_DOUBLE(xname, SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, shift, shift, 1, 0, 0)
-
-static void cmipci_sb_reg_decode(struct cmipci_sb_reg *r, unsigned long val)
-{
- r->left_reg = val & 0xff;
- r->right_reg = (val >> 8) & 0xff;
- r->left_shift = (val >> 16) & 0x07;
- r->right_shift = (val >> 19) & 0x07;
- r->invert = (val >> 22) & 1;
- r->stereo = (val >> 23) & 1;
- r->mask = (val >> 24) & 0xff;
-}
-
-static int snd_cmipci_info_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct cmipci_sb_reg reg;
-
- cmipci_sb_reg_decode(&reg, kcontrol->private_value);
- uinfo->type = reg.mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = reg.stereo + 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = reg.mask;
- return 0;
-}
-
-static int snd_cmipci_get_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cmipci *cm = snd_kcontrol_chip(kcontrol);
- struct cmipci_sb_reg reg;
- int val;
-
- cmipci_sb_reg_decode(&reg, kcontrol->private_value);
- spin_lock_irq(&cm->reg_lock);
- val = (snd_cmipci_mixer_read(cm, reg.left_reg) >> reg.left_shift) & reg.mask;
- if (reg.invert)
- val = reg.mask - val;
- ucontrol->value.integer.value[0] = val;
- if (reg.stereo) {
- val = (snd_cmipci_mixer_read(cm, reg.right_reg) >> reg.right_shift) & reg.mask;
- if (reg.invert)
- val = reg.mask - val;
- ucontrol->value.integer.value[1] = val;
- }
- spin_unlock_irq(&cm->reg_lock);
- return 0;
-}
-
-static int snd_cmipci_put_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cmipci *cm = snd_kcontrol_chip(kcontrol);
- struct cmipci_sb_reg reg;
- int change;
- int left, right, oleft, oright;
-
- cmipci_sb_reg_decode(&reg, kcontrol->private_value);
- left = ucontrol->value.integer.value[0] & reg.mask;
- if (reg.invert)
- left = reg.mask - left;
- left <<= reg.left_shift;
- if (reg.stereo) {
- right = ucontrol->value.integer.value[1] & reg.mask;
- if (reg.invert)
- right = reg.mask - right;
- right <<= reg.right_shift;
- } else
- right = 0;
- spin_lock_irq(&cm->reg_lock);
- oleft = snd_cmipci_mixer_read(cm, reg.left_reg);
- left |= oleft & ~(reg.mask << reg.left_shift);
- change = left != oleft;
- if (reg.stereo) {
- if (reg.left_reg != reg.right_reg) {
- snd_cmipci_mixer_write(cm, reg.left_reg, left);
- oright = snd_cmipci_mixer_read(cm, reg.right_reg);
- } else
- oright = left;
- right |= oright & ~(reg.mask << reg.right_shift);
- change |= right != oright;
- snd_cmipci_mixer_write(cm, reg.right_reg, right);
- } else
- snd_cmipci_mixer_write(cm, reg.left_reg, left);
- spin_unlock_irq(&cm->reg_lock);
- return change;
-}
-
-/*
- * input route (left,right) -> (left,right)
- */
-#define CMIPCI_SB_INPUT_SW(xname, left_shift, right_shift) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_cmipci_info_input_sw, \
- .get = snd_cmipci_get_input_sw, .put = snd_cmipci_put_input_sw, \
- .private_value = COMPOSE_SB_REG(SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, left_shift, right_shift, 1, 0, 1), \
-}
-
-static int snd_cmipci_info_input_sw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 4;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int snd_cmipci_get_input_sw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cmipci *cm = snd_kcontrol_chip(kcontrol);
- struct cmipci_sb_reg reg;
- int val1, val2;
-
- cmipci_sb_reg_decode(&reg, kcontrol->private_value);
- spin_lock_irq(&cm->reg_lock);
- val1 = snd_cmipci_mixer_read(cm, reg.left_reg);
- val2 = snd_cmipci_mixer_read(cm, reg.right_reg);
- spin_unlock_irq(&cm->reg_lock);
- ucontrol->value.integer.value[0] = (val1 >> reg.left_shift) & 1;
- ucontrol->value.integer.value[1] = (val2 >> reg.left_shift) & 1;
- ucontrol->value.integer.value[2] = (val1 >> reg.right_shift) & 1;
- ucontrol->value.integer.value[3] = (val2 >> reg.right_shift) & 1;
- return 0;
-}
-
-static int snd_cmipci_put_input_sw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cmipci *cm = snd_kcontrol_chip(kcontrol);
- struct cmipci_sb_reg reg;
- int change;
- int val1, val2, oval1, oval2;
-
- cmipci_sb_reg_decode(&reg, kcontrol->private_value);
- spin_lock_irq(&cm->reg_lock);
- oval1 = snd_cmipci_mixer_read(cm, reg.left_reg);
- oval2 = snd_cmipci_mixer_read(cm, reg.right_reg);
- val1 = oval1 & ~((1 << reg.left_shift) | (1 << reg.right_shift));
- val2 = oval2 & ~((1 << reg.left_shift) | (1 << reg.right_shift));
- val1 |= (ucontrol->value.integer.value[0] & 1) << reg.left_shift;
- val2 |= (ucontrol->value.integer.value[1] & 1) << reg.left_shift;
- val1 |= (ucontrol->value.integer.value[2] & 1) << reg.right_shift;
- val2 |= (ucontrol->value.integer.value[3] & 1) << reg.right_shift;
- change = val1 != oval1 || val2 != oval2;
- snd_cmipci_mixer_write(cm, reg.left_reg, val1);
- snd_cmipci_mixer_write(cm, reg.right_reg, val2);
- spin_unlock_irq(&cm->reg_lock);
- return change;
-}
-
-/*
- * native mixer switches/volumes
- */
-
-#define CMIPCI_MIXER_SW_STEREO(xname, reg, lshift, rshift, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_cmipci_info_native_mixer, \
- .get = snd_cmipci_get_native_mixer, .put = snd_cmipci_put_native_mixer, \
- .private_value = COMPOSE_SB_REG(reg, reg, lshift, rshift, 1, invert, 1), \
-}
-
-#define CMIPCI_MIXER_SW_MONO(xname, reg, shift, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_cmipci_info_native_mixer, \
- .get = snd_cmipci_get_native_mixer, .put = snd_cmipci_put_native_mixer, \
- .private_value = COMPOSE_SB_REG(reg, reg, shift, shift, 1, invert, 0), \
-}
-
-#define CMIPCI_MIXER_VOL_STEREO(xname, reg, lshift, rshift, mask) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_cmipci_info_native_mixer, \
- .get = snd_cmipci_get_native_mixer, .put = snd_cmipci_put_native_mixer, \
- .private_value = COMPOSE_SB_REG(reg, reg, lshift, rshift, mask, 0, 1), \
-}
-
-#define CMIPCI_MIXER_VOL_MONO(xname, reg, shift, mask) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_cmipci_info_native_mixer, \
- .get = snd_cmipci_get_native_mixer, .put = snd_cmipci_put_native_mixer, \
- .private_value = COMPOSE_SB_REG(reg, reg, shift, shift, mask, 0, 0), \
-}
-
-static int snd_cmipci_info_native_mixer(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct cmipci_sb_reg reg;
-
- cmipci_sb_reg_decode(&reg, kcontrol->private_value);
- uinfo->type = reg.mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = reg.stereo + 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = reg.mask;
- return 0;
-
-}
-
-static int snd_cmipci_get_native_mixer(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cmipci *cm = snd_kcontrol_chip(kcontrol);
- struct cmipci_sb_reg reg;
- unsigned char oreg, val;
-
- cmipci_sb_reg_decode(&reg, kcontrol->private_value);
- spin_lock_irq(&cm->reg_lock);
- oreg = inb(cm->iobase + reg.left_reg);
- val = (oreg >> reg.left_shift) & reg.mask;
- if (reg.invert)
- val = reg.mask - val;
- ucontrol->value.integer.value[0] = val;
- if (reg.stereo) {
- val = (oreg >> reg.right_shift) & reg.mask;
- if (reg.invert)
- val = reg.mask - val;
- ucontrol->value.integer.value[1] = val;
- }
- spin_unlock_irq(&cm->reg_lock);
- return 0;
-}
-
-static int snd_cmipci_put_native_mixer(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cmipci *cm = snd_kcontrol_chip(kcontrol);
- struct cmipci_sb_reg reg;
- unsigned char oreg, nreg, val;
-
- cmipci_sb_reg_decode(&reg, kcontrol->private_value);
- spin_lock_irq(&cm->reg_lock);
- oreg = inb(cm->iobase + reg.left_reg);
- val = ucontrol->value.integer.value[0] & reg.mask;
- if (reg.invert)
- val = reg.mask - val;
- nreg = oreg & ~(reg.mask << reg.left_shift);
- nreg |= (val << reg.left_shift);
- if (reg.stereo) {
- val = ucontrol->value.integer.value[1] & reg.mask;
- if (reg.invert)
- val = reg.mask - val;
- nreg &= ~(reg.mask << reg.right_shift);
- nreg |= (val << reg.right_shift);
- }
- outb(nreg, cm->iobase + reg.left_reg);
- spin_unlock_irq(&cm->reg_lock);
- return (nreg != oreg);
-}
-
-/*
- * special case - check mixer sensitivity
- */
-static int snd_cmipci_get_native_mixer_sensitive(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- //struct cmipci *cm = snd_kcontrol_chip(kcontrol);
- return snd_cmipci_get_native_mixer(kcontrol, ucontrol);
-}
-
-static int snd_cmipci_put_native_mixer_sensitive(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cmipci *cm = snd_kcontrol_chip(kcontrol);
- if (cm->mixer_insensitive) {
- /* ignored */
- return 0;
- }
- return snd_cmipci_put_native_mixer(kcontrol, ucontrol);
-}
-
-
-static struct snd_kcontrol_new snd_cmipci_mixers[] __devinitdata = {
- CMIPCI_SB_VOL_STEREO("Master Playback Volume", SB_DSP4_MASTER_DEV, 3, 31),
- CMIPCI_MIXER_SW_MONO("3D Control - Switch", CM_REG_MIXER1, CM_X3DEN_SHIFT, 0),
- CMIPCI_SB_VOL_STEREO("PCM Playback Volume", SB_DSP4_PCM_DEV, 3, 31),
- //CMIPCI_MIXER_SW_MONO("PCM Playback Switch", CM_REG_MIXER1, CM_WSMUTE_SHIFT, 1),
- { /* switch with sensitivity */
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Playback Switch",
- .info = snd_cmipci_info_native_mixer,
- .get = snd_cmipci_get_native_mixer_sensitive,
- .put = snd_cmipci_put_native_mixer_sensitive,
- .private_value = COMPOSE_SB_REG(CM_REG_MIXER1, CM_REG_MIXER1, CM_WSMUTE_SHIFT, CM_WSMUTE_SHIFT, 1, 1, 0),
- },
- CMIPCI_MIXER_SW_STEREO("PCM Capture Switch", CM_REG_MIXER1, CM_WAVEINL_SHIFT, CM_WAVEINR_SHIFT, 0),
- CMIPCI_SB_VOL_STEREO("Synth Playback Volume", SB_DSP4_SYNTH_DEV, 3, 31),
- CMIPCI_MIXER_SW_MONO("Synth Playback Switch", CM_REG_MIXER1, CM_FMMUTE_SHIFT, 1),
- CMIPCI_SB_INPUT_SW("Synth Capture Route", 6, 5),
- CMIPCI_SB_VOL_STEREO("CD Playback Volume", SB_DSP4_CD_DEV, 3, 31),
- CMIPCI_SB_SW_STEREO("CD Playback Switch", 2, 1),
- CMIPCI_SB_INPUT_SW("CD Capture Route", 2, 1),
- CMIPCI_SB_VOL_STEREO("Line Playback Volume", SB_DSP4_LINE_DEV, 3, 31),
- CMIPCI_SB_SW_STEREO("Line Playback Switch", 4, 3),
- CMIPCI_SB_INPUT_SW("Line Capture Route", 4, 3),
- CMIPCI_SB_VOL_MONO("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31),
- CMIPCI_SB_SW_MONO("Mic Playback Switch", 0),
- CMIPCI_DOUBLE("Mic Capture Switch", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0, 1, 0, 0),
- CMIPCI_SB_VOL_MONO("Beep Playback Volume", SB_DSP4_SPEAKER_DEV, 6, 3),
- CMIPCI_MIXER_VOL_STEREO("Aux Playback Volume", CM_REG_AUX_VOL, 4, 0, 15),
- CMIPCI_MIXER_SW_STEREO("Aux Playback Switch", CM_REG_MIXER2, CM_VAUXLM_SHIFT, CM_VAUXRM_SHIFT, 0),
- CMIPCI_MIXER_SW_STEREO("Aux Capture Switch", CM_REG_MIXER2, CM_RAUXLEN_SHIFT, CM_RAUXREN_SHIFT, 0),
- CMIPCI_MIXER_SW_MONO("Mic Boost Playback Switch", CM_REG_MIXER2, CM_MICGAINZ_SHIFT, 1),
- CMIPCI_MIXER_VOL_MONO("Mic Capture Volume", CM_REG_MIXER2, CM_VADMIC_SHIFT, 7),
- CMIPCI_SB_VOL_MONO("Phone Playback Volume", CM_REG_EXTENT_IND, 5, 7),
- CMIPCI_DOUBLE("Phone Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 4, 4, 1, 0, 0),
- CMIPCI_DOUBLE("Beep Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 3, 3, 1, 0, 0),
- CMIPCI_DOUBLE("Mic Boost Capture Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 0, 0, 1, 0, 0),
-};
-
-/*
- * other switches
- */
-
-struct cmipci_switch_args {
- int reg; /* register index */
- unsigned int mask; /* mask bits */
- unsigned int mask_on; /* mask bits to turn on */
- unsigned int is_byte: 1; /* byte access? */
- unsigned int ac3_sensitive: 1; /* access forbidden during
- * non-audio operation?
- */
-};
-
-#define snd_cmipci_uswitch_info snd_ctl_boolean_mono_info
-
-static int _snd_cmipci_uswitch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol,
- struct cmipci_switch_args *args)
-{
- unsigned int val;
- struct cmipci *cm = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&cm->reg_lock);
- if (args->ac3_sensitive && cm->mixer_insensitive) {
- ucontrol->value.integer.value[0] = 0;
- spin_unlock_irq(&cm->reg_lock);
- return 0;
- }
- if (args->is_byte)
- val = inb(cm->iobase + args->reg);
- else
- val = snd_cmipci_read(cm, args->reg);
- ucontrol->value.integer.value[0] = ((val & args->mask) == args->mask_on) ? 1 : 0;
- spin_unlock_irq(&cm->reg_lock);
- return 0;
-}
-
-static int snd_cmipci_uswitch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cmipci_switch_args *args;
- args = (struct cmipci_switch_args *)kcontrol->private_value;
- if (snd_BUG_ON(!args))
- return -EINVAL;
- return _snd_cmipci_uswitch_get(kcontrol, ucontrol, args);
-}
-
-static int _snd_cmipci_uswitch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol,
- struct cmipci_switch_args *args)
-{
- unsigned int val;
- int change;
- struct cmipci *cm = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&cm->reg_lock);
- if (args->ac3_sensitive && cm->mixer_insensitive) {
- /* ignored */
- spin_unlock_irq(&cm->reg_lock);
- return 0;
- }
- if (args->is_byte)
- val = inb(cm->iobase + args->reg);
- else
- val = snd_cmipci_read(cm, args->reg);
- change = (val & args->mask) != (ucontrol->value.integer.value[0] ?
- args->mask_on : (args->mask & ~args->mask_on));
- if (change) {
- val &= ~args->mask;
- if (ucontrol->value.integer.value[0])
- val |= args->mask_on;
- else
- val |= (args->mask & ~args->mask_on);
- if (args->is_byte)
- outb((unsigned char)val, cm->iobase + args->reg);
- else
- snd_cmipci_write(cm, args->reg, val);
- }
- spin_unlock_irq(&cm->reg_lock);
- return change;
-}
-
-static int snd_cmipci_uswitch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cmipci_switch_args *args;
- args = (struct cmipci_switch_args *)kcontrol->private_value;
- if (snd_BUG_ON(!args))
- return -EINVAL;
- return _snd_cmipci_uswitch_put(kcontrol, ucontrol, args);
-}
-
-#define DEFINE_SWITCH_ARG(sname, xreg, xmask, xmask_on, xis_byte, xac3) \
-static struct cmipci_switch_args cmipci_switch_arg_##sname = { \
- .reg = xreg, \
- .mask = xmask, \
- .mask_on = xmask_on, \
- .is_byte = xis_byte, \
- .ac3_sensitive = xac3, \
-}
-
-#define DEFINE_BIT_SWITCH_ARG(sname, xreg, xmask, xis_byte, xac3) \
- DEFINE_SWITCH_ARG(sname, xreg, xmask, xmask, xis_byte, xac3)
-
-#if 0 /* these will be controlled in pcm device */
-DEFINE_BIT_SWITCH_ARG(spdif_in, CM_REG_FUNCTRL1, CM_SPDF_1, 0, 0);
-DEFINE_BIT_SWITCH_ARG(spdif_out, CM_REG_FUNCTRL1, CM_SPDF_0, 0, 0);
-#endif
-DEFINE_BIT_SWITCH_ARG(spdif_in_sel1, CM_REG_CHFORMAT, CM_SPDIF_SELECT1, 0, 0);
-DEFINE_BIT_SWITCH_ARG(spdif_in_sel2, CM_REG_MISC_CTRL, CM_SPDIF_SELECT2, 0, 0);
-DEFINE_BIT_SWITCH_ARG(spdif_enable, CM_REG_LEGACY_CTRL, CM_ENSPDOUT, 0, 0);
-DEFINE_BIT_SWITCH_ARG(spdo2dac, CM_REG_FUNCTRL1, CM_SPDO2DAC, 0, 1);
-DEFINE_BIT_SWITCH_ARG(spdi_valid, CM_REG_MISC, CM_SPDVALID, 1, 0);
-DEFINE_BIT_SWITCH_ARG(spdif_copyright, CM_REG_LEGACY_CTRL, CM_SPDCOPYRHT, 0, 0);
-DEFINE_BIT_SWITCH_ARG(spdif_dac_out, CM_REG_LEGACY_CTRL, CM_DAC2SPDO, 0, 1);
-DEFINE_SWITCH_ARG(spdo_5v, CM_REG_MISC_CTRL, CM_SPDO5V, 0, 0, 0); /* inverse: 0 = 5V */
-// DEFINE_BIT_SWITCH_ARG(spdo_48k, CM_REG_MISC_CTRL, CM_SPDF_AC97|CM_SPDIF48K, 0, 1);
-DEFINE_BIT_SWITCH_ARG(spdif_loop, CM_REG_FUNCTRL1, CM_SPDFLOOP, 0, 1);
-DEFINE_BIT_SWITCH_ARG(spdi_monitor, CM_REG_MIXER1, CM_CDPLAY, 1, 0);
-/* DEFINE_BIT_SWITCH_ARG(spdi_phase, CM_REG_CHFORMAT, CM_SPDIF_INVERSE, 0, 0); */
-DEFINE_BIT_SWITCH_ARG(spdi_phase, CM_REG_MISC, CM_SPDIF_INVERSE, 1, 0);
-DEFINE_BIT_SWITCH_ARG(spdi_phase2, CM_REG_CHFORMAT, CM_SPDIF_INVERSE2, 0, 0);
-#if CM_CH_PLAY == 1
-DEFINE_SWITCH_ARG(exchange_dac, CM_REG_MISC_CTRL, CM_XCHGDAC, 0, 0, 0); /* reversed */
-#else
-DEFINE_SWITCH_ARG(exchange_dac, CM_REG_MISC_CTRL, CM_XCHGDAC, CM_XCHGDAC, 0, 0);
-#endif
-DEFINE_BIT_SWITCH_ARG(fourch, CM_REG_MISC_CTRL, CM_N4SPK3D, 0, 0);
-// DEFINE_BIT_SWITCH_ARG(line_rear, CM_REG_MIXER1, CM_REAR2LIN, 1, 0);
-// DEFINE_BIT_SWITCH_ARG(line_bass, CM_REG_LEGACY_CTRL, CM_CENTR2LIN|CM_BASE2LIN, 0, 0);
-// DEFINE_BIT_SWITCH_ARG(joystick, CM_REG_FUNCTRL1, CM_JYSTK_EN, 0, 0); /* now module option */
-DEFINE_SWITCH_ARG(modem, CM_REG_MISC_CTRL, CM_FLINKON|CM_FLINKOFF, CM_FLINKON, 0, 0);
-
-#define DEFINE_SWITCH(sname, stype, sarg) \
-{ .name = sname, \
- .iface = stype, \
- .info = snd_cmipci_uswitch_info, \
- .get = snd_cmipci_uswitch_get, \
- .put = snd_cmipci_uswitch_put, \
- .private_value = (unsigned long)&cmipci_switch_arg_##sarg,\
-}
-
-#define DEFINE_CARD_SWITCH(sname, sarg) DEFINE_SWITCH(sname, SNDRV_CTL_ELEM_IFACE_CARD, sarg)
-#define DEFINE_MIXER_SWITCH(sname, sarg) DEFINE_SWITCH(sname, SNDRV_CTL_ELEM_IFACE_MIXER, sarg)
-
-
-/*
- * callbacks for spdif output switch
- * needs toggle two registers..
- */
-static int snd_cmipci_spdout_enable_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int changed;
- changed = _snd_cmipci_uswitch_get(kcontrol, ucontrol, &cmipci_switch_arg_spdif_enable);
- changed |= _snd_cmipci_uswitch_get(kcontrol, ucontrol, &cmipci_switch_arg_spdo2dac);
- return changed;
-}
-
-static int snd_cmipci_spdout_enable_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cmipci *chip = snd_kcontrol_chip(kcontrol);
- int changed;
- changed = _snd_cmipci_uswitch_put(kcontrol, ucontrol, &cmipci_switch_arg_spdif_enable);
- changed |= _snd_cmipci_uswitch_put(kcontrol, ucontrol, &cmipci_switch_arg_spdo2dac);
- if (changed) {
- if (ucontrol->value.integer.value[0]) {
- if (chip->spdif_playback_avail)
- snd_cmipci_set_bit(chip, CM_REG_FUNCTRL1, CM_PLAYBACK_SPDF);
- } else {
- if (chip->spdif_playback_avail)
- snd_cmipci_clear_bit(chip, CM_REG_FUNCTRL1, CM_PLAYBACK_SPDF);
- }
- }
- chip->spdif_playback_enabled = ucontrol->value.integer.value[0];
- return changed;
-}
-
-
-static int snd_cmipci_line_in_mode_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct cmipci *cm = snd_kcontrol_chip(kcontrol);
- static const char *const texts[3] = {
- "Line-In", "Rear Output", "Bass Output"
- };
-
- return snd_ctl_enum_info(uinfo, 1,
- cm->chip_version >= 39 ? 3 : 2, texts);
-}
-
-static inline unsigned int get_line_in_mode(struct cmipci *cm)
-{
- unsigned int val;
- if (cm->chip_version >= 39) {
- val = snd_cmipci_read(cm, CM_REG_LEGACY_CTRL);
- if (val & (CM_CENTR2LIN | CM_BASE2LIN))
- return 2;
- }
- val = snd_cmipci_read_b(cm, CM_REG_MIXER1);
- if (val & CM_REAR2LIN)
- return 1;
- return 0;
-}
-
-static int snd_cmipci_line_in_mode_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cmipci *cm = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&cm->reg_lock);
- ucontrol->value.enumerated.item[0] = get_line_in_mode(cm);
- spin_unlock_irq(&cm->reg_lock);
- return 0;
-}
-
-static int snd_cmipci_line_in_mode_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cmipci *cm = snd_kcontrol_chip(kcontrol);
- int change;
-
- spin_lock_irq(&cm->reg_lock);
- if (ucontrol->value.enumerated.item[0] == 2)
- change = snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_CENTR2LIN | CM_BASE2LIN);
- else
- change = snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_CENTR2LIN | CM_BASE2LIN);
- if (ucontrol->value.enumerated.item[0] == 1)
- change |= snd_cmipci_set_bit_b(cm, CM_REG_MIXER1, CM_REAR2LIN);
- else
- change |= snd_cmipci_clear_bit_b(cm, CM_REG_MIXER1, CM_REAR2LIN);
- spin_unlock_irq(&cm->reg_lock);
- return change;
-}
-
-static int snd_cmipci_mic_in_mode_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static const char *const texts[2] = { "Mic-In", "Center/LFE Output" };
-
- return snd_ctl_enum_info(uinfo, 1, 2, texts);
-}
-
-static int snd_cmipci_mic_in_mode_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cmipci *cm = snd_kcontrol_chip(kcontrol);
- /* same bit as spdi_phase */
- spin_lock_irq(&cm->reg_lock);
- ucontrol->value.enumerated.item[0] =
- (snd_cmipci_read_b(cm, CM_REG_MISC) & CM_SPDIF_INVERSE) ? 1 : 0;
- spin_unlock_irq(&cm->reg_lock);
- return 0;
-}
-
-static int snd_cmipci_mic_in_mode_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cmipci *cm = snd_kcontrol_chip(kcontrol);
- int change;
-
- spin_lock_irq(&cm->reg_lock);
- if (ucontrol->value.enumerated.item[0])
- change = snd_cmipci_set_bit_b(cm, CM_REG_MISC, CM_SPDIF_INVERSE);
- else
- change = snd_cmipci_clear_bit_b(cm, CM_REG_MISC, CM_SPDIF_INVERSE);
- spin_unlock_irq(&cm->reg_lock);
- return change;
-}
-
-/* both for CM8338/8738 */
-static struct snd_kcontrol_new snd_cmipci_mixer_switches[] __devinitdata = {
- DEFINE_MIXER_SWITCH("Four Channel Mode", fourch),
- {
- .name = "Line-In Mode",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = snd_cmipci_line_in_mode_info,
- .get = snd_cmipci_line_in_mode_get,
- .put = snd_cmipci_line_in_mode_put,
- },
-};
-
-/* for non-multichannel chips */
-static struct snd_kcontrol_new snd_cmipci_nomulti_switch __devinitdata =
-DEFINE_MIXER_SWITCH("Exchange DAC", exchange_dac);
-
-/* only for CM8738 */
-static struct snd_kcontrol_new snd_cmipci_8738_mixer_switches[] __devinitdata = {
-#if 0 /* controlled in pcm device */
- DEFINE_MIXER_SWITCH("IEC958 In Record", spdif_in),
- DEFINE_MIXER_SWITCH("IEC958 Out", spdif_out),
- DEFINE_MIXER_SWITCH("IEC958 Out To DAC", spdo2dac),
-#endif
- // DEFINE_MIXER_SWITCH("IEC958 Output Switch", spdif_enable),
- { .name = "IEC958 Output Switch",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = snd_cmipci_uswitch_info,
- .get = snd_cmipci_spdout_enable_get,
- .put = snd_cmipci_spdout_enable_put,
- },
- DEFINE_MIXER_SWITCH("IEC958 In Valid", spdi_valid),
- DEFINE_MIXER_SWITCH("IEC958 Copyright", spdif_copyright),
- DEFINE_MIXER_SWITCH("IEC958 5V", spdo_5v),
-// DEFINE_MIXER_SWITCH("IEC958 In/Out 48KHz", spdo_48k),
- DEFINE_MIXER_SWITCH("IEC958 Loop", spdif_loop),
- DEFINE_MIXER_SWITCH("IEC958 In Monitor", spdi_monitor),
-};
-
-/* only for model 033/037 */
-static struct snd_kcontrol_new snd_cmipci_old_mixer_switches[] __devinitdata = {
- DEFINE_MIXER_SWITCH("IEC958 Mix Analog", spdif_dac_out),
- DEFINE_MIXER_SWITCH("IEC958 In Phase Inverse", spdi_phase),
- DEFINE_MIXER_SWITCH("IEC958 In Select", spdif_in_sel1),
-};
-
-/* only for model 039 or later */
-static struct snd_kcontrol_new snd_cmipci_extra_mixer_switches[] __devinitdata = {
- DEFINE_MIXER_SWITCH("IEC958 In Select", spdif_in_sel2),
- DEFINE_MIXER_SWITCH("IEC958 In Phase Inverse", spdi_phase2),
- {
- .name = "Mic-In Mode",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = snd_cmipci_mic_in_mode_info,
- .get = snd_cmipci_mic_in_mode_get,
- .put = snd_cmipci_mic_in_mode_put,
- }
-};
-
-/* card control switches */
-static struct snd_kcontrol_new snd_cmipci_modem_switch __devinitdata =
-DEFINE_CARD_SWITCH("Modem", modem);
-
-
-static int __devinit snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_device)
-{
- struct snd_card *card;
- struct snd_kcontrol_new *sw;
- struct snd_kcontrol *kctl;
- unsigned int idx;
- int err;
-
- if (snd_BUG_ON(!cm || !cm->card))
- return -EINVAL;
-
- card = cm->card;
-
- strcpy(card->mixername, "CMedia PCI");
-
- spin_lock_irq(&cm->reg_lock);
- snd_cmipci_mixer_write(cm, 0x00, 0x00); /* mixer reset */
- spin_unlock_irq(&cm->reg_lock);
-
- for (idx = 0; idx < ARRAY_SIZE(snd_cmipci_mixers); idx++) {
- if (cm->chip_version == 68) { // 8768 has no PCM volume
- if (!strcmp(snd_cmipci_mixers[idx].name,
- "PCM Playback Volume"))
- continue;
- }
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cmipci_mixers[idx], cm))) < 0)
- return err;
- }
-
- /* mixer switches */
- sw = snd_cmipci_mixer_switches;
- for (idx = 0; idx < ARRAY_SIZE(snd_cmipci_mixer_switches); idx++, sw++) {
- err = snd_ctl_add(cm->card, snd_ctl_new1(sw, cm));
- if (err < 0)
- return err;
- }
- if (! cm->can_multi_ch) {
- err = snd_ctl_add(cm->card, snd_ctl_new1(&snd_cmipci_nomulti_switch, cm));
- if (err < 0)
- return err;
- }
- if (cm->device == PCI_DEVICE_ID_CMEDIA_CM8738 ||
- cm->device == PCI_DEVICE_ID_CMEDIA_CM8738B) {
- sw = snd_cmipci_8738_mixer_switches;
- for (idx = 0; idx < ARRAY_SIZE(snd_cmipci_8738_mixer_switches); idx++, sw++) {
- err = snd_ctl_add(cm->card, snd_ctl_new1(sw, cm));
- if (err < 0)
- return err;
- }
- if (cm->can_ac3_hw) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_cmipci_spdif_default, cm))) < 0)
- return err;
- kctl->id.device = pcm_spdif_device;
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_cmipci_spdif_mask, cm))) < 0)
- return err;
- kctl->id.device = pcm_spdif_device;
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_cmipci_spdif_stream, cm))) < 0)
- return err;
- kctl->id.device = pcm_spdif_device;
- }
- if (cm->chip_version <= 37) {
- sw = snd_cmipci_old_mixer_switches;
- for (idx = 0; idx < ARRAY_SIZE(snd_cmipci_old_mixer_switches); idx++, sw++) {
- err = snd_ctl_add(cm->card, snd_ctl_new1(sw, cm));
- if (err < 0)
- return err;
- }
- }
- }
- if (cm->chip_version >= 39) {
- sw = snd_cmipci_extra_mixer_switches;
- for (idx = 0; idx < ARRAY_SIZE(snd_cmipci_extra_mixer_switches); idx++, sw++) {
- err = snd_ctl_add(cm->card, snd_ctl_new1(sw, cm));
- if (err < 0)
- return err;
- }
- }
-
- /* card switches */
- /*
- * newer chips don't have the register bits to force modem link
- * detection; the bit that was FLINKON now mutes CH1
- */
- if (cm->chip_version < 39) {
- err = snd_ctl_add(cm->card,
- snd_ctl_new1(&snd_cmipci_modem_switch, cm));
- if (err < 0)
- return err;
- }
-
- for (idx = 0; idx < CM_SAVED_MIXERS; idx++) {
- struct snd_ctl_elem_id elem_id;
- struct snd_kcontrol *ctl;
- memset(&elem_id, 0, sizeof(elem_id));
- elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(elem_id.name, cm_saved_mixer[idx].name);
- ctl = snd_ctl_find_id(cm->card, &elem_id);
- if (ctl)
- cm->mixer_res_ctl[idx] = ctl;
- }
-
- return 0;
-}
-
-
-/*
- * proc interface
- */
-
-#ifdef CONFIG_PROC_FS
-static void snd_cmipci_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct cmipci *cm = entry->private_data;
- int i, v;
-
- snd_iprintf(buffer, "%s\n", cm->card->longname);
- for (i = 0; i < 0x94; i++) {
- if (i == 0x28)
- i = 0x90;
- v = inb(cm->iobase + i);
- if (i % 4 == 0)
- snd_iprintf(buffer, "\n%02x:", i);
- snd_iprintf(buffer, " %02x", v);
- }
- snd_iprintf(buffer, "\n");
-}
-
-static void __devinit snd_cmipci_proc_init(struct cmipci *cm)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(cm->card, "cmipci", &entry))
- snd_info_set_text_ops(entry, cm, snd_cmipci_proc_read);
-}
-#else /* !CONFIG_PROC_FS */
-static inline void snd_cmipci_proc_init(struct cmipci *cm) {}
-#endif
-
-
-static DEFINE_PCI_DEVICE_TABLE(snd_cmipci_ids) = {
- {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A), 0},
- {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B), 0},
- {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738), 0},
- {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738B), 0},
- {PCI_VDEVICE(AL, PCI_DEVICE_ID_CMEDIA_CM8738), 0},
- {0,},
-};
-
-
-/*
- * check chip version and capabilities
- * driver name is modified according to the chip model
- */
-static void __devinit query_chip(struct cmipci *cm)
-{
- unsigned int detect;
-
- /* check reg 0Ch, bit 24-31 */
- detect = snd_cmipci_read(cm, CM_REG_INT_HLDCLR) & CM_CHIP_MASK2;
- if (! detect) {
- /* check reg 08h, bit 24-28 */
- detect = snd_cmipci_read(cm, CM_REG_CHFORMAT) & CM_CHIP_MASK1;
- switch (detect) {
- case 0:
- cm->chip_version = 33;
- if (cm->do_soft_ac3)
- cm->can_ac3_sw = 1;
- else
- cm->can_ac3_hw = 1;
- break;
- case CM_CHIP_037:
- cm->chip_version = 37;
- cm->can_ac3_hw = 1;
- break;
- default:
- cm->chip_version = 39;
- cm->can_ac3_hw = 1;
- break;
- }
- cm->max_channels = 2;
- } else {
- if (detect & CM_CHIP_039) {
- cm->chip_version = 39;
- if (detect & CM_CHIP_039_6CH) /* 4 or 6 channels */
- cm->max_channels = 6;
- else
- cm->max_channels = 4;
- } else if (detect & CM_CHIP_8768) {
- cm->chip_version = 68;
- cm->max_channels = 8;
- cm->can_96k = 1;
- } else {
- cm->chip_version = 55;
- cm->max_channels = 6;
- cm->can_96k = 1;
- }
- cm->can_ac3_hw = 1;
- cm->can_multi_ch = 1;
- }
-}
-
-#ifdef SUPPORT_JOYSTICK
-static int __devinit snd_cmipci_create_gameport(struct cmipci *cm, int dev)
-{
- static int ports[] = { 0x201, 0x200, 0 }; /* FIXME: majority is 0x201? */
- struct gameport *gp;
- struct resource *r = NULL;
- int i, io_port = 0;
-
- if (joystick_port[dev] == 0)
- return -ENODEV;
-
- if (joystick_port[dev] == 1) { /* auto-detect */
- for (i = 0; ports[i]; i++) {
- io_port = ports[i];
- r = request_region(io_port, 1, "CMIPCI gameport");
- if (r)
- break;
- }
- } else {
- io_port = joystick_port[dev];
- r = request_region(io_port, 1, "CMIPCI gameport");
- }
-
- if (!r) {
- printk(KERN_WARNING "cmipci: cannot reserve joystick ports\n");
- return -EBUSY;
- }
-
- cm->gameport = gp = gameport_allocate_port();
- if (!gp) {
- printk(KERN_ERR "cmipci: cannot allocate memory for gameport\n");
- release_and_free_resource(r);
- return -ENOMEM;
- }
- gameport_set_name(gp, "C-Media Gameport");
- gameport_set_phys(gp, "pci%s/gameport0", pci_name(cm->pci));
- gameport_set_dev_parent(gp, &cm->pci->dev);
- gp->io = io_port;
- gameport_set_port_data(gp, r);
-
- snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN);
-
- gameport_register_port(cm->gameport);
-
- return 0;
-}
-
-static void snd_cmipci_free_gameport(struct cmipci *cm)
-{
- if (cm->gameport) {
- struct resource *r = gameport_get_port_data(cm->gameport);
-
- gameport_unregister_port(cm->gameport);
- cm->gameport = NULL;
-
- snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN);
- release_and_free_resource(r);
- }
-}
-#else
-static inline int snd_cmipci_create_gameport(struct cmipci *cm, int dev) { return -ENOSYS; }
-static inline void snd_cmipci_free_gameport(struct cmipci *cm) { }
-#endif
-
-static int snd_cmipci_free(struct cmipci *cm)
-{
- if (cm->irq >= 0) {
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
- snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_ENSPDOUT);
- snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0); /* disable ints */
- snd_cmipci_ch_reset(cm, CM_CH_PLAY);
- snd_cmipci_ch_reset(cm, CM_CH_CAPT);
- snd_cmipci_write(cm, CM_REG_FUNCTRL0, 0); /* disable channels */
- snd_cmipci_write(cm, CM_REG_FUNCTRL1, 0);
-
- /* reset mixer */
- snd_cmipci_mixer_write(cm, 0, 0);
-
- free_irq(cm->irq, cm);
- }
-
- snd_cmipci_free_gameport(cm);
- pci_release_regions(cm->pci);
- pci_disable_device(cm->pci);
- kfree(cm);
- return 0;
-}
-
-static int snd_cmipci_dev_free(struct snd_device *device)
-{
- struct cmipci *cm = device->device_data;
- return snd_cmipci_free(cm);
-}
-
-static int __devinit snd_cmipci_create_fm(struct cmipci *cm, long fm_port)
-{
- long iosynth;
- unsigned int val;
- struct snd_opl3 *opl3;
- int err;
-
- if (!fm_port)
- goto disable_fm;
-
- if (cm->chip_version >= 39) {
- /* first try FM regs in PCI port range */
- iosynth = cm->iobase + CM_REG_FM_PCI;
- err = snd_opl3_create(cm->card, iosynth, iosynth + 2,
- OPL3_HW_OPL3, 1, &opl3);
- } else {
- err = -EIO;
- }
- if (err < 0) {
- /* then try legacy ports */
- val = snd_cmipci_read(cm, CM_REG_LEGACY_CTRL) & ~CM_FMSEL_MASK;
- iosynth = fm_port;
- switch (iosynth) {
- case 0x3E8: val |= CM_FMSEL_3E8; break;
- case 0x3E0: val |= CM_FMSEL_3E0; break;
- case 0x3C8: val |= CM_FMSEL_3C8; break;
- case 0x388: val |= CM_FMSEL_388; break;
- default:
- goto disable_fm;
- }
- snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
- /* enable FM */
- snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
-
- if (snd_opl3_create(cm->card, iosynth, iosynth + 2,
- OPL3_HW_OPL3, 0, &opl3) < 0) {
- printk(KERN_ERR "cmipci: no OPL device at %#lx, "
- "skipping...\n", iosynth);
- goto disable_fm;
- }
- }
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
- printk(KERN_ERR "cmipci: cannot create OPL3 hwdep\n");
- return err;
- }
- return 0;
-
- disable_fm:
- snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_FMSEL_MASK);
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
- return 0;
-}
-
-static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pci,
- int dev, struct cmipci **rcmipci)
-{
- struct cmipci *cm;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_cmipci_dev_free,
- };
- unsigned int val;
- long iomidi = 0;
- int integrated_midi = 0;
- char modelstr[16];
- int pcm_index, pcm_spdif_index;
- static DEFINE_PCI_DEVICE_TABLE(intel_82437vx) = {
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) },
- { },
- };
-
- *rcmipci = NULL;
-
- if ((err = pci_enable_device(pci)) < 0)
- return err;
-
- cm = kzalloc(sizeof(*cm), GFP_KERNEL);
- if (cm == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- spin_lock_init(&cm->reg_lock);
- mutex_init(&cm->open_mutex);
- cm->device = pci->device;
- cm->card = card;
- cm->pci = pci;
- cm->irq = -1;
- cm->channel[0].ch = 0;
- cm->channel[1].ch = 1;
- cm->channel[0].is_dac = cm->channel[1].is_dac = 1; /* dual DAC mode */
-
- if ((err = pci_request_regions(pci, card->driver)) < 0) {
- kfree(cm);
- pci_disable_device(pci);
- return err;
- }
- cm->iobase = pci_resource_start(pci, 0);
-
- if (request_irq(pci->irq, snd_cmipci_interrupt,
- IRQF_SHARED, KBUILD_MODNAME, cm)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_cmipci_free(cm);
- return -EBUSY;
- }
- cm->irq = pci->irq;
-
- pci_set_master(cm->pci);
-
- /*
- * check chip version, max channels and capabilities
- */
-
- cm->chip_version = 0;
- cm->max_channels = 2;
- cm->do_soft_ac3 = soft_ac3[dev];
-
- if (pci->device != PCI_DEVICE_ID_CMEDIA_CM8338A &&
- pci->device != PCI_DEVICE_ID_CMEDIA_CM8338B)
- query_chip(cm);
- /* added -MCx suffix for chip supporting multi-channels */
- if (cm->can_multi_ch)
- sprintf(cm->card->driver + strlen(cm->card->driver),
- "-MC%d", cm->max_channels);
- else if (cm->can_ac3_sw)
- strcpy(cm->card->driver + strlen(cm->card->driver), "-SWIEC");
-
- cm->dig_status = SNDRV_PCM_DEFAULT_CON_SPDIF;
- cm->dig_pcm_status = SNDRV_PCM_DEFAULT_CON_SPDIF;
-
-#if CM_CH_PLAY == 1
- cm->ctrl = CM_CHADC0; /* default FUNCNTRL0 */
-#else
- cm->ctrl = CM_CHADC1; /* default FUNCNTRL0 */
-#endif
-
- /* initialize codec registers */
- snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_RESET);
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_RESET);
- snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0); /* disable ints */
- snd_cmipci_ch_reset(cm, CM_CH_PLAY);
- snd_cmipci_ch_reset(cm, CM_CH_CAPT);
- snd_cmipci_write(cm, CM_REG_FUNCTRL0, 0); /* disable channels */
- snd_cmipci_write(cm, CM_REG_FUNCTRL1, 0);
-
- snd_cmipci_write(cm, CM_REG_CHFORMAT, 0);
- snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_ENDBDAC|CM_N4SPK3D);
-#if CM_CH_PLAY == 1
- snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
-#else
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
-#endif
- if (cm->chip_version) {
- snd_cmipci_write_b(cm, CM_REG_EXT_MISC, 0x20); /* magic */
- snd_cmipci_write_b(cm, CM_REG_EXT_MISC + 1, 0x09); /* more magic */
- }
- /* Set Bus Master Request */
- snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_BREQ);
-
- /* Assume TX and compatible chip set (Autodetection required for VX chip sets) */
- switch (pci->device) {
- case PCI_DEVICE_ID_CMEDIA_CM8738:
- case PCI_DEVICE_ID_CMEDIA_CM8738B:
- if (!pci_dev_present(intel_82437vx))
- snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_TXVX);
- break;
- default:
- break;
- }
-
- if (cm->chip_version < 68) {
- val = pci->device < 0x110 ? 8338 : 8738;
- } else {
- switch (snd_cmipci_read_b(cm, CM_REG_INT_HLDCLR + 3) & 0x03) {
- case 0:
- val = 8769;
- break;
- case 2:
- val = 8762;
- break;
- default:
- switch ((pci->subsystem_vendor << 16) |
- pci->subsystem_device) {
- case 0x13f69761:
- case 0x584d3741:
- case 0x584d3751:
- case 0x584d3761:
- case 0x584d3771:
- case 0x72848384:
- val = 8770;
- break;
- default:
- val = 8768;
- break;
- }
- }
- }
- sprintf(card->shortname, "C-Media CMI%d", val);
- if (cm->chip_version < 68)
- sprintf(modelstr, " (model %d)", cm->chip_version);
- else
- modelstr[0] = '\0';
- sprintf(card->longname, "%s%s at %#lx, irq %i",
- card->shortname, modelstr, cm->iobase, cm->irq);
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, cm, &ops)) < 0) {
- snd_cmipci_free(cm);
- return err;
- }
-
- if (cm->chip_version >= 39) {
- val = snd_cmipci_read_b(cm, CM_REG_MPU_PCI + 1);
- if (val != 0x00 && val != 0xff) {
- iomidi = cm->iobase + CM_REG_MPU_PCI;
- integrated_midi = 1;
- }
- }
- if (!integrated_midi) {
- val = 0;
- iomidi = mpu_port[dev];
- switch (iomidi) {
- case 0x320: val = CM_VMPU_320; break;
- case 0x310: val = CM_VMPU_310; break;
- case 0x300: val = CM_VMPU_300; break;
- case 0x330: val = CM_VMPU_330; break;
- default:
- iomidi = 0; break;
- }
- if (iomidi > 0) {
- snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
- /* enable UART */
- snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_UART_EN);
- if (inb(iomidi + 1) == 0xff) {
- snd_printk(KERN_ERR "cannot enable MPU-401 port"
- " at %#lx\n", iomidi);
- snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1,
- CM_UART_EN);
- iomidi = 0;
- }
- }
- }
-
- if (cm->chip_version < 68) {
- err = snd_cmipci_create_fm(cm, fm_port[dev]);
- if (err < 0)
- return err;
- }
-
- /* reset mixer */
- snd_cmipci_mixer_write(cm, 0, 0);
-
- snd_cmipci_proc_init(cm);
-
- /* create pcm devices */
- pcm_index = pcm_spdif_index = 0;
- if ((err = snd_cmipci_pcm_new(cm, pcm_index)) < 0)
- return err;
- pcm_index++;
- if ((err = snd_cmipci_pcm2_new(cm, pcm_index)) < 0)
- return err;
- pcm_index++;
- if (cm->can_ac3_hw || cm->can_ac3_sw) {
- pcm_spdif_index = pcm_index;
- if ((err = snd_cmipci_pcm_spdif_new(cm, pcm_index)) < 0)
- return err;
- }
-
- /* create mixer interface & switches */
- if ((err = snd_cmipci_mixer_new(cm, pcm_spdif_index)) < 0)
- return err;
-
- if (iomidi > 0) {
- if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
- iomidi,
- (integrated_midi ?
- MPU401_INFO_INTEGRATED : 0) |
- MPU401_INFO_IRQ_HOOK,
- -1, &cm->rmidi)) < 0) {
- printk(KERN_ERR "cmipci: no UART401 device at 0x%lx\n", iomidi);
- }
- }
-
-#ifdef USE_VAR48KRATE
- for (val = 0; val < ARRAY_SIZE(rates); val++)
- snd_cmipci_set_pll(cm, rates[val], val);
-
- /*
- * (Re-)Enable external switch spdo_48k
- */
- snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPDIF48K|CM_SPDF_AC97);
-#endif /* USE_VAR48KRATE */
-
- if (snd_cmipci_create_gameport(cm, dev) < 0)
- snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN);
-
- snd_card_set_dev(card, &pci->dev);
-
- *rcmipci = cm;
- return 0;
-}
-
-/*
- */
-
-MODULE_DEVICE_TABLE(pci, snd_cmipci_ids);
-
-static int __devinit snd_cmipci_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct cmipci *cm;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (! enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- switch (pci->device) {
- case PCI_DEVICE_ID_CMEDIA_CM8738:
- case PCI_DEVICE_ID_CMEDIA_CM8738B:
- strcpy(card->driver, "CMI8738");
- break;
- case PCI_DEVICE_ID_CMEDIA_CM8338A:
- case PCI_DEVICE_ID_CMEDIA_CM8338B:
- strcpy(card->driver, "CMI8338");
- break;
- default:
- strcpy(card->driver, "CMIPCI");
- break;
- }
-
- if ((err = snd_cmipci_create(card, pci, dev, &cm)) < 0) {
- snd_card_free(card);
- return err;
- }
- card->private_data = cm;
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-
-}
-
-static void __devexit snd_cmipci_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-
-#ifdef CONFIG_PM
-/*
- * power management
- */
-static unsigned char saved_regs[] = {
- CM_REG_FUNCTRL1, CM_REG_CHFORMAT, CM_REG_LEGACY_CTRL, CM_REG_MISC_CTRL,
- CM_REG_MIXER0, CM_REG_MIXER1, CM_REG_MIXER2, CM_REG_MIXER3, CM_REG_PLL,
- CM_REG_CH0_FRAME1, CM_REG_CH0_FRAME2,
- CM_REG_CH1_FRAME1, CM_REG_CH1_FRAME2, CM_REG_EXT_MISC,
- CM_REG_INT_STATUS, CM_REG_INT_HLDCLR, CM_REG_FUNCTRL0,
-};
-
-static unsigned char saved_mixers[] = {
- SB_DSP4_MASTER_DEV, SB_DSP4_MASTER_DEV + 1,
- SB_DSP4_PCM_DEV, SB_DSP4_PCM_DEV + 1,
- SB_DSP4_SYNTH_DEV, SB_DSP4_SYNTH_DEV + 1,
- SB_DSP4_CD_DEV, SB_DSP4_CD_DEV + 1,
- SB_DSP4_LINE_DEV, SB_DSP4_LINE_DEV + 1,
- SB_DSP4_MIC_DEV, SB_DSP4_SPEAKER_DEV,
- CM_REG_EXTENT_IND, SB_DSP4_OUTPUT_SW,
- SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT,
-};
-
-static int snd_cmipci_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct cmipci *cm = card->private_data;
- int i;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-
- snd_pcm_suspend_all(cm->pcm);
- snd_pcm_suspend_all(cm->pcm2);
- snd_pcm_suspend_all(cm->pcm_spdif);
-
- /* save registers */
- for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
- cm->saved_regs[i] = snd_cmipci_read(cm, saved_regs[i]);
- for (i = 0; i < ARRAY_SIZE(saved_mixers); i++)
- cm->saved_mixers[i] = snd_cmipci_mixer_read(cm, saved_mixers[i]);
-
- /* disable ints */
- snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0);
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int snd_cmipci_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct cmipci *cm = card->private_data;
- int i;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "cmipci: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
-
- /* reset / initialize to a sane state */
- snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0);
- snd_cmipci_ch_reset(cm, CM_CH_PLAY);
- snd_cmipci_ch_reset(cm, CM_CH_CAPT);
- snd_cmipci_mixer_write(cm, 0, 0);
-
- /* restore registers */
- for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
- snd_cmipci_write(cm, saved_regs[i], cm->saved_regs[i]);
- for (i = 0; i < ARRAY_SIZE(saved_mixers); i++)
- snd_cmipci_mixer_write(cm, saved_mixers[i], cm->saved_mixers[i]);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif /* CONFIG_PM */
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_cmipci_ids,
- .probe = snd_cmipci_probe,
- .remove = __devexit_p(snd_cmipci_remove),
-#ifdef CONFIG_PM
- .suspend = snd_cmipci_suspend,
- .resume = snd_cmipci_resume,
-#endif
-};
-
-static int __init alsa_card_cmipci_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_cmipci_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_cmipci_init)
-module_exit(alsa_card_cmipci_exit)
diff --git a/ANDROID_3.4.5/sound/pci/cs4281.c b/ANDROID_3.4.5/sound/pci/cs4281.c
deleted file mode 100644
index a9f368f6..00000000
--- a/ANDROID_3.4.5/sound/pci/cs4281.c
+++ /dev/null
@@ -1,2109 +0,0 @@
-/*
- * Driver for Cirrus Logic CS4281 based PCI soundcard
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/gameport.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/rawmidi.h>
-#include <sound/ac97_codec.h>
-#include <sound/tlv.h>
-#include <sound/opl3.h>
-#include <sound/initval.h>
-
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Cirrus Logic CS4281");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Cirrus Logic,CS4281}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
-static bool dual_codec[SNDRV_CARDS]; /* dual codec */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for CS4281 soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for CS4281 soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable CS4281 soundcard.");
-module_param_array(dual_codec, bool, NULL, 0444);
-MODULE_PARM_DESC(dual_codec, "Secondary Codec ID (0 = disabled).");
-
-/*
- * Direct registers
- */
-
-#define CS4281_BA0_SIZE 0x1000
-#define CS4281_BA1_SIZE 0x10000
-
-/*
- * BA0 registers
- */
-#define BA0_HISR 0x0000 /* Host Interrupt Status Register */
-#define BA0_HISR_INTENA (1<<31) /* Internal Interrupt Enable Bit */
-#define BA0_HISR_MIDI (1<<22) /* MIDI port interrupt */
-#define BA0_HISR_FIFOI (1<<20) /* FIFO polled interrupt */
-#define BA0_HISR_DMAI (1<<18) /* DMA interrupt (half or end) */
-#define BA0_HISR_FIFO(c) (1<<(12+(c))) /* FIFO channel interrupt */
-#define BA0_HISR_DMA(c) (1<<(8+(c))) /* DMA channel interrupt */
-#define BA0_HISR_GPPI (1<<5) /* General Purpose Input (Primary chip) */
-#define BA0_HISR_GPSI (1<<4) /* General Purpose Input (Secondary chip) */
-#define BA0_HISR_GP3I (1<<3) /* GPIO3 pin Interrupt */
-#define BA0_HISR_GP1I (1<<2) /* GPIO1 pin Interrupt */
-#define BA0_HISR_VUPI (1<<1) /* VOLUP pin Interrupt */
-#define BA0_HISR_VDNI (1<<0) /* VOLDN pin Interrupt */
-
-#define BA0_HICR 0x0008 /* Host Interrupt Control Register */
-#define BA0_HICR_CHGM (1<<1) /* INTENA Change Mask */
-#define BA0_HICR_IEV (1<<0) /* INTENA Value */
-#define BA0_HICR_EOI (3<<0) /* End of Interrupt command */
-
-#define BA0_HIMR 0x000c /* Host Interrupt Mask Register */
- /* Use same contants as for BA0_HISR */
-
-#define BA0_IIER 0x0010 /* ISA Interrupt Enable Register */
-
-#define BA0_HDSR0 0x00f0 /* Host DMA Engine 0 Status Register */
-#define BA0_HDSR1 0x00f4 /* Host DMA Engine 1 Status Register */
-#define BA0_HDSR2 0x00f8 /* Host DMA Engine 2 Status Register */
-#define BA0_HDSR3 0x00fc /* Host DMA Engine 3 Status Register */
-
-#define BA0_HDSR_CH1P (1<<25) /* Channel 1 Pending */
-#define BA0_HDSR_CH2P (1<<24) /* Channel 2 Pending */
-#define BA0_HDSR_DHTC (1<<17) /* DMA Half Terminal Count */
-#define BA0_HDSR_DTC (1<<16) /* DMA Terminal Count */
-#define BA0_HDSR_DRUN (1<<15) /* DMA Running */
-#define BA0_HDSR_RQ (1<<7) /* Pending Request */
-
-#define BA0_DCA0 0x0110 /* Host DMA Engine 0 Current Address */
-#define BA0_DCC0 0x0114 /* Host DMA Engine 0 Current Count */
-#define BA0_DBA0 0x0118 /* Host DMA Engine 0 Base Address */
-#define BA0_DBC0 0x011c /* Host DMA Engine 0 Base Count */
-#define BA0_DCA1 0x0120 /* Host DMA Engine 1 Current Address */
-#define BA0_DCC1 0x0124 /* Host DMA Engine 1 Current Count */
-#define BA0_DBA1 0x0128 /* Host DMA Engine 1 Base Address */
-#define BA0_DBC1 0x012c /* Host DMA Engine 1 Base Count */
-#define BA0_DCA2 0x0130 /* Host DMA Engine 2 Current Address */
-#define BA0_DCC2 0x0134 /* Host DMA Engine 2 Current Count */
-#define BA0_DBA2 0x0138 /* Host DMA Engine 2 Base Address */
-#define BA0_DBC2 0x013c /* Host DMA Engine 2 Base Count */
-#define BA0_DCA3 0x0140 /* Host DMA Engine 3 Current Address */
-#define BA0_DCC3 0x0144 /* Host DMA Engine 3 Current Count */
-#define BA0_DBA3 0x0148 /* Host DMA Engine 3 Base Address */
-#define BA0_DBC3 0x014c /* Host DMA Engine 3 Base Count */
-#define BA0_DMR0 0x0150 /* Host DMA Engine 0 Mode */
-#define BA0_DCR0 0x0154 /* Host DMA Engine 0 Command */
-#define BA0_DMR1 0x0158 /* Host DMA Engine 1 Mode */
-#define BA0_DCR1 0x015c /* Host DMA Engine 1 Command */
-#define BA0_DMR2 0x0160 /* Host DMA Engine 2 Mode */
-#define BA0_DCR2 0x0164 /* Host DMA Engine 2 Command */
-#define BA0_DMR3 0x0168 /* Host DMA Engine 3 Mode */
-#define BA0_DCR3 0x016c /* Host DMA Engine 3 Command */
-
-#define BA0_DMR_DMA (1<<29) /* Enable DMA mode */
-#define BA0_DMR_POLL (1<<28) /* Enable poll mode */
-#define BA0_DMR_TBC (1<<25) /* Transfer By Channel */
-#define BA0_DMR_CBC (1<<24) /* Count By Channel (0 = frame resolution) */
-#define BA0_DMR_SWAPC (1<<22) /* Swap Left/Right Channels */
-#define BA0_DMR_SIZE20 (1<<20) /* Sample is 20-bit */
-#define BA0_DMR_USIGN (1<<19) /* Unsigned */
-#define BA0_DMR_BEND (1<<18) /* Big Endian */
-#define BA0_DMR_MONO (1<<17) /* Mono */
-#define BA0_DMR_SIZE8 (1<<16) /* Sample is 8-bit */
-#define BA0_DMR_TYPE_DEMAND (0<<6)
-#define BA0_DMR_TYPE_SINGLE (1<<6)
-#define BA0_DMR_TYPE_BLOCK (2<<6)
-#define BA0_DMR_TYPE_CASCADE (3<<6) /* Not supported */
-#define BA0_DMR_DEC (1<<5) /* Access Increment (0) or Decrement (1) */
-#define BA0_DMR_AUTO (1<<4) /* Auto-Initialize */
-#define BA0_DMR_TR_VERIFY (0<<2) /* Verify Transfer */
-#define BA0_DMR_TR_WRITE (1<<2) /* Write Transfer */
-#define BA0_DMR_TR_READ (2<<2) /* Read Transfer */
-
-#define BA0_DCR_HTCIE (1<<17) /* Half Terminal Count Interrupt */
-#define BA0_DCR_TCIE (1<<16) /* Terminal Count Interrupt */
-#define BA0_DCR_MSK (1<<0) /* DMA Mask bit */
-
-#define BA0_FCR0 0x0180 /* FIFO Control 0 */
-#define BA0_FCR1 0x0184 /* FIFO Control 1 */
-#define BA0_FCR2 0x0188 /* FIFO Control 2 */
-#define BA0_FCR3 0x018c /* FIFO Control 3 */
-
-#define BA0_FCR_FEN (1<<31) /* FIFO Enable bit */
-#define BA0_FCR_DACZ (1<<30) /* DAC Zero */
-#define BA0_FCR_PSH (1<<29) /* Previous Sample Hold */
-#define BA0_FCR_RS(x) (((x)&0x1f)<<24) /* Right Slot Mapping */
-#define BA0_FCR_LS(x) (((x)&0x1f)<<16) /* Left Slot Mapping */
-#define BA0_FCR_SZ(x) (((x)&0x7f)<<8) /* FIFO buffer size (in samples) */
-#define BA0_FCR_OF(x) (((x)&0x7f)<<0) /* FIFO starting offset (in samples) */
-
-#define BA0_FPDR0 0x0190 /* FIFO Polled Data 0 */
-#define BA0_FPDR1 0x0194 /* FIFO Polled Data 1 */
-#define BA0_FPDR2 0x0198 /* FIFO Polled Data 2 */
-#define BA0_FPDR3 0x019c /* FIFO Polled Data 3 */
-
-#define BA0_FCHS 0x020c /* FIFO Channel Status */
-#define BA0_FCHS_RCO(x) (1<<(7+(((x)&3)<<3))) /* Right Channel Out */
-#define BA0_FCHS_LCO(x) (1<<(6+(((x)&3)<<3))) /* Left Channel Out */
-#define BA0_FCHS_MRP(x) (1<<(5+(((x)&3)<<3))) /* Move Read Pointer */
-#define BA0_FCHS_FE(x) (1<<(4+(((x)&3)<<3))) /* FIFO Empty */
-#define BA0_FCHS_FF(x) (1<<(3+(((x)&3)<<3))) /* FIFO Full */
-#define BA0_FCHS_IOR(x) (1<<(2+(((x)&3)<<3))) /* Internal Overrun Flag */
-#define BA0_FCHS_RCI(x) (1<<(1+(((x)&3)<<3))) /* Right Channel In */
-#define BA0_FCHS_LCI(x) (1<<(0+(((x)&3)<<3))) /* Left Channel In */
-
-#define BA0_FSIC0 0x0210 /* FIFO Status and Interrupt Control 0 */
-#define BA0_FSIC1 0x0214 /* FIFO Status and Interrupt Control 1 */
-#define BA0_FSIC2 0x0218 /* FIFO Status and Interrupt Control 2 */
-#define BA0_FSIC3 0x021c /* FIFO Status and Interrupt Control 3 */
-
-#define BA0_FSIC_FIC(x) (((x)&0x7f)<<24) /* FIFO Interrupt Count */
-#define BA0_FSIC_FORIE (1<<23) /* FIFO OverRun Interrupt Enable */
-#define BA0_FSIC_FURIE (1<<22) /* FIFO UnderRun Interrupt Enable */
-#define BA0_FSIC_FSCIE (1<<16) /* FIFO Sample Count Interrupt Enable */
-#define BA0_FSIC_FSC(x) (((x)&0x7f)<<8) /* FIFO Sample Count */
-#define BA0_FSIC_FOR (1<<7) /* FIFO OverRun */
-#define BA0_FSIC_FUR (1<<6) /* FIFO UnderRun */
-#define BA0_FSIC_FSCR (1<<0) /* FIFO Sample Count Reached */
-
-#define BA0_PMCS 0x0344 /* Power Management Control/Status */
-#define BA0_CWPR 0x03e0 /* Configuration Write Protect */
-
-#define BA0_EPPMC 0x03e4 /* Extended PCI Power Management Control */
-#define BA0_EPPMC_FPDN (1<<14) /* Full Power DowN */
-
-#define BA0_GPIOR 0x03e8 /* GPIO Pin Interface Register */
-
-#define BA0_SPMC 0x03ec /* Serial Port Power Management Control (& ASDIN2 enable) */
-#define BA0_SPMC_GIPPEN (1<<15) /* GP INT Primary PME# Enable */
-#define BA0_SPMC_GISPEN (1<<14) /* GP INT Secondary PME# Enable */
-#define BA0_SPMC_EESPD (1<<9) /* EEPROM Serial Port Disable */
-#define BA0_SPMC_ASDI2E (1<<8) /* ASDIN2 Enable */
-#define BA0_SPMC_ASDO (1<<7) /* Asynchronous ASDOUT Assertion */
-#define BA0_SPMC_WUP2 (1<<3) /* Wakeup for Secondary Input */
-#define BA0_SPMC_WUP1 (1<<2) /* Wakeup for Primary Input */
-#define BA0_SPMC_ASYNC (1<<1) /* Asynchronous ASYNC Assertion */
-#define BA0_SPMC_RSTN (1<<0) /* Reset Not! */
-
-#define BA0_CFLR 0x03f0 /* Configuration Load Register (EEPROM or BIOS) */
-#define BA0_CFLR_DEFAULT 0x00000001 /* CFLR must be in AC97 link mode */
-#define BA0_IISR 0x03f4 /* ISA Interrupt Select */
-#define BA0_TMS 0x03f8 /* Test Register */
-#define BA0_SSVID 0x03fc /* Subsystem ID register */
-
-#define BA0_CLKCR1 0x0400 /* Clock Control Register 1 */
-#define BA0_CLKCR1_CLKON (1<<25) /* Read Only */
-#define BA0_CLKCR1_DLLRDY (1<<24) /* DLL Ready */
-#define BA0_CLKCR1_DLLOS (1<<6) /* DLL Output Select */
-#define BA0_CLKCR1_SWCE (1<<5) /* Clock Enable */
-#define BA0_CLKCR1_DLLP (1<<4) /* DLL PowerUp */
-#define BA0_CLKCR1_DLLSS (((x)&3)<<3) /* DLL Source Select */
-
-#define BA0_FRR 0x0410 /* Feature Reporting Register */
-#define BA0_SLT12O 0x041c /* Slot 12 GPIO Output Register for AC-Link */
-
-#define BA0_SERMC 0x0420 /* Serial Port Master Control */
-#define BA0_SERMC_FCRN (1<<27) /* Force Codec Ready Not */
-#define BA0_SERMC_ODSEN2 (1<<25) /* On-Demand Support Enable ASDIN2 */
-#define BA0_SERMC_ODSEN1 (1<<24) /* On-Demand Support Enable ASDIN1 */
-#define BA0_SERMC_SXLB (1<<21) /* ASDIN2 to ASDOUT Loopback */
-#define BA0_SERMC_SLB (1<<20) /* ASDOUT to ASDIN2 Loopback */
-#define BA0_SERMC_LOVF (1<<19) /* Loopback Output Valid Frame bit */
-#define BA0_SERMC_TCID(x) (((x)&3)<<16) /* Target Secondary Codec ID */
-#define BA0_SERMC_PXLB (5<<1) /* Primary Port External Loopback */
-#define BA0_SERMC_PLB (4<<1) /* Primary Port Internal Loopback */
-#define BA0_SERMC_PTC (7<<1) /* Port Timing Configuration */
-#define BA0_SERMC_PTC_AC97 (1<<1) /* AC97 mode */
-#define BA0_SERMC_MSPE (1<<0) /* Master Serial Port Enable */
-
-#define BA0_SERC1 0x0428 /* Serial Port Configuration 1 */
-#define BA0_SERC1_SO1F(x) (((x)&7)>>1) /* Primary Output Port Format */
-#define BA0_SERC1_AC97 (1<<1)
-#define BA0_SERC1_SO1EN (1<<0) /* Primary Output Port Enable */
-
-#define BA0_SERC2 0x042c /* Serial Port Configuration 2 */
-#define BA0_SERC2_SI1F(x) (((x)&7)>>1) /* Primary Input Port Format */
-#define BA0_SERC2_AC97 (1<<1)
-#define BA0_SERC2_SI1EN (1<<0) /* Primary Input Port Enable */
-
-#define BA0_SLT12M 0x045c /* Slot 12 Monitor Register for Primary AC-Link */
-
-#define BA0_ACCTL 0x0460 /* AC'97 Control */
-#define BA0_ACCTL_TC (1<<6) /* Target Codec */
-#define BA0_ACCTL_CRW (1<<4) /* 0=Write, 1=Read Command */
-#define BA0_ACCTL_DCV (1<<3) /* Dynamic Command Valid */
-#define BA0_ACCTL_VFRM (1<<2) /* Valid Frame */
-#define BA0_ACCTL_ESYN (1<<1) /* Enable Sync */
-
-#define BA0_ACSTS 0x0464 /* AC'97 Status */
-#define BA0_ACSTS_VSTS (1<<1) /* Valid Status */
-#define BA0_ACSTS_CRDY (1<<0) /* Codec Ready */
-
-#define BA0_ACOSV 0x0468 /* AC'97 Output Slot Valid */
-#define BA0_ACOSV_SLV(x) (1<<((x)-3))
-
-#define BA0_ACCAD 0x046c /* AC'97 Command Address */
-#define BA0_ACCDA 0x0470 /* AC'97 Command Data */
-
-#define BA0_ACISV 0x0474 /* AC'97 Input Slot Valid */
-#define BA0_ACISV_SLV(x) (1<<((x)-3))
-
-#define BA0_ACSAD 0x0478 /* AC'97 Status Address */
-#define BA0_ACSDA 0x047c /* AC'97 Status Data */
-#define BA0_JSPT 0x0480 /* Joystick poll/trigger */
-#define BA0_JSCTL 0x0484 /* Joystick control */
-#define BA0_JSC1 0x0488 /* Joystick control */
-#define BA0_JSC2 0x048c /* Joystick control */
-#define BA0_JSIO 0x04a0
-
-#define BA0_MIDCR 0x0490 /* MIDI Control */
-#define BA0_MIDCR_MRST (1<<5) /* Reset MIDI Interface */
-#define BA0_MIDCR_MLB (1<<4) /* MIDI Loop Back Enable */
-#define BA0_MIDCR_TIE (1<<3) /* MIDI Transmuit Interrupt Enable */
-#define BA0_MIDCR_RIE (1<<2) /* MIDI Receive Interrupt Enable */
-#define BA0_MIDCR_RXE (1<<1) /* MIDI Receive Enable */
-#define BA0_MIDCR_TXE (1<<0) /* MIDI Transmit Enable */
-
-#define BA0_MIDCMD 0x0494 /* MIDI Command (wo) */
-
-#define BA0_MIDSR 0x0494 /* MIDI Status (ro) */
-#define BA0_MIDSR_RDA (1<<15) /* Sticky bit (RBE 1->0) */
-#define BA0_MIDSR_TBE (1<<14) /* Sticky bit (TBF 0->1) */
-#define BA0_MIDSR_RBE (1<<7) /* Receive Buffer Empty */
-#define BA0_MIDSR_TBF (1<<6) /* Transmit Buffer Full */
-
-#define BA0_MIDWP 0x0498 /* MIDI Write */
-#define BA0_MIDRP 0x049c /* MIDI Read (ro) */
-
-#define BA0_AODSD1 0x04a8 /* AC'97 On-Demand Slot Disable for primary link (ro) */
-#define BA0_AODSD1_NDS(x) (1<<((x)-3))
-
-#define BA0_AODSD2 0x04ac /* AC'97 On-Demand Slot Disable for secondary link (ro) */
-#define BA0_AODSD2_NDS(x) (1<<((x)-3))
-
-#define BA0_CFGI 0x04b0 /* Configure Interface (EEPROM interface) */
-#define BA0_SLT12M2 0x04dc /* Slot 12 Monitor Register 2 for secondary AC-link */
-#define BA0_ACSTS2 0x04e4 /* AC'97 Status Register 2 */
-#define BA0_ACISV2 0x04f4 /* AC'97 Input Slot Valid Register 2 */
-#define BA0_ACSAD2 0x04f8 /* AC'97 Status Address Register 2 */
-#define BA0_ACSDA2 0x04fc /* AC'97 Status Data Register 2 */
-#define BA0_FMSR 0x0730 /* FM Synthesis Status (ro) */
-#define BA0_B0AP 0x0730 /* FM Bank 0 Address Port (wo) */
-#define BA0_FMDP 0x0734 /* FM Data Port */
-#define BA0_B1AP 0x0738 /* FM Bank 1 Address Port */
-#define BA0_B1DP 0x073c /* FM Bank 1 Data Port */
-
-#define BA0_SSPM 0x0740 /* Sound System Power Management */
-#define BA0_SSPM_MIXEN (1<<6) /* Playback SRC + FM/Wavetable MIX */
-#define BA0_SSPM_CSRCEN (1<<5) /* Capture Sample Rate Converter Enable */
-#define BA0_SSPM_PSRCEN (1<<4) /* Playback Sample Rate Converter Enable */
-#define BA0_SSPM_JSEN (1<<3) /* Joystick Enable */
-#define BA0_SSPM_ACLEN (1<<2) /* Serial Port Engine and AC-Link Enable */
-#define BA0_SSPM_FMEN (1<<1) /* FM Synthesis Block Enable */
-
-#define BA0_DACSR 0x0744 /* DAC Sample Rate - Playback SRC */
-#define BA0_ADCSR 0x0748 /* ADC Sample Rate - Capture SRC */
-
-#define BA0_SSCR 0x074c /* Sound System Control Register */
-#define BA0_SSCR_HVS1 (1<<23) /* Hardwave Volume Step (0=1,1=2) */
-#define BA0_SSCR_MVCS (1<<19) /* Master Volume Codec Select */
-#define BA0_SSCR_MVLD (1<<18) /* Master Volume Line Out Disable */
-#define BA0_SSCR_MVAD (1<<17) /* Master Volume Alternate Out Disable */
-#define BA0_SSCR_MVMD (1<<16) /* Master Volume Mono Out Disable */
-#define BA0_SSCR_XLPSRC (1<<8) /* External SRC Loopback Mode */
-#define BA0_SSCR_LPSRC (1<<7) /* SRC Loopback Mode */
-#define BA0_SSCR_CDTX (1<<5) /* CD Transfer Data */
-#define BA0_SSCR_HVC (1<<3) /* Harware Volume Control Enable */
-
-#define BA0_FMLVC 0x0754 /* FM Synthesis Left Volume Control */
-#define BA0_FMRVC 0x0758 /* FM Synthesis Right Volume Control */
-#define BA0_SRCSA 0x075c /* SRC Slot Assignments */
-#define BA0_PPLVC 0x0760 /* PCM Playback Left Volume Control */
-#define BA0_PPRVC 0x0764 /* PCM Playback Right Volume Control */
-#define BA0_PASR 0x0768 /* playback sample rate */
-#define BA0_CASR 0x076C /* capture sample rate */
-
-/* Source Slot Numbers - Playback */
-#define SRCSLOT_LEFT_PCM_PLAYBACK 0
-#define SRCSLOT_RIGHT_PCM_PLAYBACK 1
-#define SRCSLOT_PHONE_LINE_1_DAC 2
-#define SRCSLOT_CENTER_PCM_PLAYBACK 3
-#define SRCSLOT_LEFT_SURROUND_PCM_PLAYBACK 4
-#define SRCSLOT_RIGHT_SURROUND_PCM_PLAYBACK 5
-#define SRCSLOT_LFE_PCM_PLAYBACK 6
-#define SRCSLOT_PHONE_LINE_2_DAC 7
-#define SRCSLOT_HEADSET_DAC 8
-#define SRCSLOT_LEFT_WT 29 /* invalid for BA0_SRCSA */
-#define SRCSLOT_RIGHT_WT 30 /* invalid for BA0_SRCSA */
-
-/* Source Slot Numbers - Capture */
-#define SRCSLOT_LEFT_PCM_RECORD 10
-#define SRCSLOT_RIGHT_PCM_RECORD 11
-#define SRCSLOT_PHONE_LINE_1_ADC 12
-#define SRCSLOT_MIC_ADC 13
-#define SRCSLOT_PHONE_LINE_2_ADC 17
-#define SRCSLOT_HEADSET_ADC 18
-#define SRCSLOT_SECONDARY_LEFT_PCM_RECORD 20
-#define SRCSLOT_SECONDARY_RIGHT_PCM_RECORD 21
-#define SRCSLOT_SECONDARY_PHONE_LINE_1_ADC 22
-#define SRCSLOT_SECONDARY_MIC_ADC 23
-#define SRCSLOT_SECONDARY_PHONE_LINE_2_ADC 27
-#define SRCSLOT_SECONDARY_HEADSET_ADC 28
-
-/* Source Slot Numbers - Others */
-#define SRCSLOT_POWER_DOWN 31
-
-/* MIDI modes */
-#define CS4281_MODE_OUTPUT (1<<0)
-#define CS4281_MODE_INPUT (1<<1)
-
-/* joystick bits */
-/* Bits for JSPT */
-#define JSPT_CAX 0x00000001
-#define JSPT_CAY 0x00000002
-#define JSPT_CBX 0x00000004
-#define JSPT_CBY 0x00000008
-#define JSPT_BA1 0x00000010
-#define JSPT_BA2 0x00000020
-#define JSPT_BB1 0x00000040
-#define JSPT_BB2 0x00000080
-
-/* Bits for JSCTL */
-#define JSCTL_SP_MASK 0x00000003
-#define JSCTL_SP_SLOW 0x00000000
-#define JSCTL_SP_MEDIUM_SLOW 0x00000001
-#define JSCTL_SP_MEDIUM_FAST 0x00000002
-#define JSCTL_SP_FAST 0x00000003
-#define JSCTL_ARE 0x00000004
-
-/* Data register pairs masks */
-#define JSC1_Y1V_MASK 0x0000FFFF
-#define JSC1_X1V_MASK 0xFFFF0000
-#define JSC1_Y1V_SHIFT 0
-#define JSC1_X1V_SHIFT 16
-#define JSC2_Y2V_MASK 0x0000FFFF
-#define JSC2_X2V_MASK 0xFFFF0000
-#define JSC2_Y2V_SHIFT 0
-#define JSC2_X2V_SHIFT 16
-
-/* JS GPIO */
-#define JSIO_DAX 0x00000001
-#define JSIO_DAY 0x00000002
-#define JSIO_DBX 0x00000004
-#define JSIO_DBY 0x00000008
-#define JSIO_AXOE 0x00000010
-#define JSIO_AYOE 0x00000020
-#define JSIO_BXOE 0x00000040
-#define JSIO_BYOE 0x00000080
-
-/*
- *
- */
-
-struct cs4281_dma {
- struct snd_pcm_substream *substream;
- unsigned int regDBA; /* offset to DBA register */
- unsigned int regDCA; /* offset to DCA register */
- unsigned int regDBC; /* offset to DBC register */
- unsigned int regDCC; /* offset to DCC register */
- unsigned int regDMR; /* offset to DMR register */
- unsigned int regDCR; /* offset to DCR register */
- unsigned int regHDSR; /* offset to HDSR register */
- unsigned int regFCR; /* offset to FCR register */
- unsigned int regFSIC; /* offset to FSIC register */
- unsigned int valDMR; /* DMA mode */
- unsigned int valDCR; /* DMA command */
- unsigned int valFCR; /* FIFO control */
- unsigned int fifo_offset; /* FIFO offset within BA1 */
- unsigned char left_slot; /* FIFO left slot */
- unsigned char right_slot; /* FIFO right slot */
- int frag; /* period number */
-};
-
-#define SUSPEND_REGISTERS 20
-
-struct cs4281 {
- int irq;
-
- void __iomem *ba0; /* virtual (accessible) address */
- void __iomem *ba1; /* virtual (accessible) address */
- unsigned long ba0_addr;
- unsigned long ba1_addr;
-
- int dual_codec;
-
- struct snd_ac97_bus *ac97_bus;
- struct snd_ac97 *ac97;
- struct snd_ac97 *ac97_secondary;
-
- struct pci_dev *pci;
- struct snd_card *card;
- struct snd_pcm *pcm;
- struct snd_rawmidi *rmidi;
- struct snd_rawmidi_substream *midi_input;
- struct snd_rawmidi_substream *midi_output;
-
- struct cs4281_dma dma[4];
-
- unsigned char src_left_play_slot;
- unsigned char src_right_play_slot;
- unsigned char src_left_rec_slot;
- unsigned char src_right_rec_slot;
-
- unsigned int spurious_dhtc_irq;
- unsigned int spurious_dtc_irq;
-
- spinlock_t reg_lock;
- unsigned int midcr;
- unsigned int uartm;
-
- struct gameport *gameport;
-
-#ifdef CONFIG_PM
- u32 suspend_regs[SUSPEND_REGISTERS];
-#endif
-
-};
-
-static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id);
-
-static DEFINE_PCI_DEVICE_TABLE(snd_cs4281_ids) = {
- { PCI_VDEVICE(CIRRUS, 0x6005), 0, }, /* CS4281 */
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_cs4281_ids);
-
-/*
- * constants
- */
-
-#define CS4281_FIFO_SIZE 32
-
-/*
- * common I/O routines
- */
-
-static inline void snd_cs4281_pokeBA0(struct cs4281 *chip, unsigned long offset,
- unsigned int val)
-{
- writel(val, chip->ba0 + offset);
-}
-
-static inline unsigned int snd_cs4281_peekBA0(struct cs4281 *chip, unsigned long offset)
-{
- return readl(chip->ba0 + offset);
-}
-
-static void snd_cs4281_ac97_write(struct snd_ac97 *ac97,
- unsigned short reg, unsigned short val)
-{
- /*
- * 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
- * 2. Write ACCDA = Command Data Register = 470h for data to write to AC97
- * 3. Write ACCTL = Control Register = 460h for initiating the write
- * 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 07h
- * 5. if DCV not cleared, break and return error
- */
- struct cs4281 *chip = ac97->private_data;
- int count;
-
- /*
- * Setup the AC97 control registers on the CS461x to send the
- * appropriate command to the AC97 to perform the read.
- * ACCAD = Command Address Register = 46Ch
- * ACCDA = Command Data Register = 470h
- * ACCTL = Control Register = 460h
- * set DCV - will clear when process completed
- * reset CRW - Write command
- * set VFRM - valid frame enabled
- * set ESYN - ASYNC generation enabled
- * set RSTN - ARST# inactive, AC97 codec not reset
- */
- snd_cs4281_pokeBA0(chip, BA0_ACCAD, reg);
- snd_cs4281_pokeBA0(chip, BA0_ACCDA, val);
- snd_cs4281_pokeBA0(chip, BA0_ACCTL, BA0_ACCTL_DCV | BA0_ACCTL_VFRM |
- BA0_ACCTL_ESYN | (ac97->num ? BA0_ACCTL_TC : 0));
- for (count = 0; count < 2000; count++) {
- /*
- * First, we want to wait for a short time.
- */
- udelay(10);
- /*
- * Now, check to see if the write has completed.
- * ACCTL = 460h, DCV should be reset by now and 460h = 07h
- */
- if (!(snd_cs4281_peekBA0(chip, BA0_ACCTL) & BA0_ACCTL_DCV)) {
- return;
- }
- }
- snd_printk(KERN_ERR "AC'97 write problem, reg = 0x%x, val = 0x%x\n", reg, val);
-}
-
-static unsigned short snd_cs4281_ac97_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- struct cs4281 *chip = ac97->private_data;
- int count;
- unsigned short result;
- // FIXME: volatile is necessary in the following due to a bug of
- // some gcc versions
- volatile int ac97_num = ((volatile struct snd_ac97 *)ac97)->num;
-
- /*
- * 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
- * 2. Write ACCDA = Command Data Register = 470h for data to write to AC97
- * 3. Write ACCTL = Control Register = 460h for initiating the write
- * 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 17h
- * 5. if DCV not cleared, break and return error
- * 6. Read ACSTS = Status Register = 464h, check VSTS bit
- */
-
- snd_cs4281_peekBA0(chip, ac97_num ? BA0_ACSDA2 : BA0_ACSDA);
-
- /*
- * Setup the AC97 control registers on the CS461x to send the
- * appropriate command to the AC97 to perform the read.
- * ACCAD = Command Address Register = 46Ch
- * ACCDA = Command Data Register = 470h
- * ACCTL = Control Register = 460h
- * set DCV - will clear when process completed
- * set CRW - Read command
- * set VFRM - valid frame enabled
- * set ESYN - ASYNC generation enabled
- * set RSTN - ARST# inactive, AC97 codec not reset
- */
-
- snd_cs4281_pokeBA0(chip, BA0_ACCAD, reg);
- snd_cs4281_pokeBA0(chip, BA0_ACCDA, 0);
- snd_cs4281_pokeBA0(chip, BA0_ACCTL, BA0_ACCTL_DCV | BA0_ACCTL_CRW |
- BA0_ACCTL_VFRM | BA0_ACCTL_ESYN |
- (ac97_num ? BA0_ACCTL_TC : 0));
-
-
- /*
- * Wait for the read to occur.
- */
- for (count = 0; count < 500; count++) {
- /*
- * First, we want to wait for a short time.
- */
- udelay(10);
- /*
- * Now, check to see if the read has completed.
- * ACCTL = 460h, DCV should be reset by now and 460h = 17h
- */
- if (!(snd_cs4281_peekBA0(chip, BA0_ACCTL) & BA0_ACCTL_DCV))
- goto __ok1;
- }
-
- snd_printk(KERN_ERR "AC'97 read problem (ACCTL_DCV), reg = 0x%x\n", reg);
- result = 0xffff;
- goto __end;
-
- __ok1:
- /*
- * Wait for the valid status bit to go active.
- */
- for (count = 0; count < 100; count++) {
- /*
- * Read the AC97 status register.
- * ACSTS = Status Register = 464h
- * VSTS - Valid Status
- */
- if (snd_cs4281_peekBA0(chip, ac97_num ? BA0_ACSTS2 : BA0_ACSTS) & BA0_ACSTS_VSTS)
- goto __ok2;
- udelay(10);
- }
-
- snd_printk(KERN_ERR "AC'97 read problem (ACSTS_VSTS), reg = 0x%x\n", reg);
- result = 0xffff;
- goto __end;
-
- __ok2:
- /*
- * Read the data returned from the AC97 register.
- * ACSDA = Status Data Register = 474h
- */
- result = snd_cs4281_peekBA0(chip, ac97_num ? BA0_ACSDA2 : BA0_ACSDA);
-
- __end:
- return result;
-}
-
-/*
- * PCM part
- */
-
-static int snd_cs4281_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct cs4281_dma *dma = substream->runtime->private_data;
- struct cs4281 *chip = snd_pcm_substream_chip(substream);
-
- spin_lock(&chip->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- dma->valDCR |= BA0_DCR_MSK;
- dma->valFCR |= BA0_FCR_FEN;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- dma->valDCR &= ~BA0_DCR_MSK;
- dma->valFCR &= ~BA0_FCR_FEN;
- break;
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- snd_cs4281_pokeBA0(chip, dma->regDMR, dma->valDMR & ~BA0_DMR_DMA);
- dma->valDMR |= BA0_DMR_DMA;
- dma->valDCR &= ~BA0_DCR_MSK;
- dma->valFCR |= BA0_FCR_FEN;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- dma->valDMR &= ~(BA0_DMR_DMA|BA0_DMR_POLL);
- dma->valDCR |= BA0_DCR_MSK;
- dma->valFCR &= ~BA0_FCR_FEN;
- /* Leave wave playback FIFO enabled for FM */
- if (dma->regFCR != BA0_FCR0)
- dma->valFCR &= ~BA0_FCR_FEN;
- break;
- default:
- spin_unlock(&chip->reg_lock);
- return -EINVAL;
- }
- snd_cs4281_pokeBA0(chip, dma->regDMR, dma->valDMR);
- snd_cs4281_pokeBA0(chip, dma->regFCR, dma->valFCR);
- snd_cs4281_pokeBA0(chip, dma->regDCR, dma->valDCR);
- spin_unlock(&chip->reg_lock);
- return 0;
-}
-
-static unsigned int snd_cs4281_rate(unsigned int rate, unsigned int *real_rate)
-{
- unsigned int val = ~0;
-
- if (real_rate)
- *real_rate = rate;
- /* special "hardcoded" rates */
- switch (rate) {
- case 8000: return 5;
- case 11025: return 4;
- case 16000: return 3;
- case 22050: return 2;
- case 44100: return 1;
- case 48000: return 0;
- default:
- goto __variable;
- }
- __variable:
- val = 1536000 / rate;
- if (real_rate)
- *real_rate = 1536000 / val;
- return val;
-}
-
-static void snd_cs4281_mode(struct cs4281 *chip, struct cs4281_dma *dma,
- struct snd_pcm_runtime *runtime,
- int capture, int src)
-{
- int rec_mono;
-
- dma->valDMR = BA0_DMR_TYPE_SINGLE | BA0_DMR_AUTO |
- (capture ? BA0_DMR_TR_WRITE : BA0_DMR_TR_READ);
- if (runtime->channels == 1)
- dma->valDMR |= BA0_DMR_MONO;
- if (snd_pcm_format_unsigned(runtime->format) > 0)
- dma->valDMR |= BA0_DMR_USIGN;
- if (snd_pcm_format_big_endian(runtime->format) > 0)
- dma->valDMR |= BA0_DMR_BEND;
- switch (snd_pcm_format_width(runtime->format)) {
- case 8: dma->valDMR |= BA0_DMR_SIZE8;
- if (runtime->channels == 1)
- dma->valDMR |= BA0_DMR_SWAPC;
- break;
- case 32: dma->valDMR |= BA0_DMR_SIZE20; break;
- }
- dma->frag = 0; /* for workaround */
- dma->valDCR = BA0_DCR_TCIE | BA0_DCR_MSK;
- if (runtime->buffer_size != runtime->period_size)
- dma->valDCR |= BA0_DCR_HTCIE;
- /* Initialize DMA */
- snd_cs4281_pokeBA0(chip, dma->regDBA, runtime->dma_addr);
- snd_cs4281_pokeBA0(chip, dma->regDBC, runtime->buffer_size - 1);
- rec_mono = (chip->dma[1].valDMR & BA0_DMR_MONO) == BA0_DMR_MONO;
- snd_cs4281_pokeBA0(chip, BA0_SRCSA, (chip->src_left_play_slot << 0) |
- (chip->src_right_play_slot << 8) |
- (chip->src_left_rec_slot << 16) |
- ((rec_mono ? 31 : chip->src_right_rec_slot) << 24));
- if (!src)
- goto __skip_src;
- if (!capture) {
- if (dma->left_slot == chip->src_left_play_slot) {
- unsigned int val = snd_cs4281_rate(runtime->rate, NULL);
- snd_BUG_ON(dma->right_slot != chip->src_right_play_slot);
- snd_cs4281_pokeBA0(chip, BA0_DACSR, val);
- }
- } else {
- if (dma->left_slot == chip->src_left_rec_slot) {
- unsigned int val = snd_cs4281_rate(runtime->rate, NULL);
- snd_BUG_ON(dma->right_slot != chip->src_right_rec_slot);
- snd_cs4281_pokeBA0(chip, BA0_ADCSR, val);
- }
- }
- __skip_src:
- /* Deactivate wave playback FIFO before changing slot assignments */
- if (dma->regFCR == BA0_FCR0)
- snd_cs4281_pokeBA0(chip, dma->regFCR, snd_cs4281_peekBA0(chip, dma->regFCR) & ~BA0_FCR_FEN);
- /* Initialize FIFO */
- dma->valFCR = BA0_FCR_LS(dma->left_slot) |
- BA0_FCR_RS(capture && (dma->valDMR & BA0_DMR_MONO) ? 31 : dma->right_slot) |
- BA0_FCR_SZ(CS4281_FIFO_SIZE) |
- BA0_FCR_OF(dma->fifo_offset);
- snd_cs4281_pokeBA0(chip, dma->regFCR, dma->valFCR | (capture ? BA0_FCR_PSH : 0));
- /* Activate FIFO again for FM playback */
- if (dma->regFCR == BA0_FCR0)
- snd_cs4281_pokeBA0(chip, dma->regFCR, dma->valFCR | BA0_FCR_FEN);
- /* Clear FIFO Status and Interrupt Control Register */
- snd_cs4281_pokeBA0(chip, dma->regFSIC, 0);
-}
-
-static int snd_cs4281_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static int snd_cs4281_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_cs4281_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct cs4281_dma *dma = runtime->private_data;
- struct cs4281 *chip = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&chip->reg_lock);
- snd_cs4281_mode(chip, dma, runtime, 0, 1);
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static int snd_cs4281_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct cs4281_dma *dma = runtime->private_data;
- struct cs4281 *chip = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&chip->reg_lock);
- snd_cs4281_mode(chip, dma, runtime, 1, 1);
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static snd_pcm_uframes_t snd_cs4281_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct cs4281_dma *dma = runtime->private_data;
- struct cs4281 *chip = snd_pcm_substream_chip(substream);
-
- /*
- printk(KERN_DEBUG "DCC = 0x%x, buffer_size = 0x%x, jiffies = %li\n",
- snd_cs4281_peekBA0(chip, dma->regDCC), runtime->buffer_size,
- jiffies);
- */
- return runtime->buffer_size -
- snd_cs4281_peekBA0(chip, dma->regDCC) - 1;
-}
-
-static struct snd_pcm_hardware snd_cs4281_playback =
-{
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME,
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
- SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_U16_BE | SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_U32_BE | SNDRV_PCM_FMTBIT_S32_BE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (512*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (512*1024),
- .periods_min = 1,
- .periods_max = 2,
- .fifo_size = CS4281_FIFO_SIZE,
-};
-
-static struct snd_pcm_hardware snd_cs4281_capture =
-{
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME,
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
- SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_U16_BE | SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_U32_BE | SNDRV_PCM_FMTBIT_S32_BE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (512*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (512*1024),
- .periods_min = 1,
- .periods_max = 2,
- .fifo_size = CS4281_FIFO_SIZE,
-};
-
-static int snd_cs4281_playback_open(struct snd_pcm_substream *substream)
-{
- struct cs4281 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct cs4281_dma *dma;
-
- dma = &chip->dma[0];
- dma->substream = substream;
- dma->left_slot = 0;
- dma->right_slot = 1;
- runtime->private_data = dma;
- runtime->hw = snd_cs4281_playback;
- /* should be detected from the AC'97 layer, but it seems
- that although CS4297A rev B reports 18-bit ADC resolution,
- samples are 20-bit */
- snd_pcm_hw_constraint_msbits(runtime, 0, 32, 20);
- return 0;
-}
-
-static int snd_cs4281_capture_open(struct snd_pcm_substream *substream)
-{
- struct cs4281 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct cs4281_dma *dma;
-
- dma = &chip->dma[1];
- dma->substream = substream;
- dma->left_slot = 10;
- dma->right_slot = 11;
- runtime->private_data = dma;
- runtime->hw = snd_cs4281_capture;
- /* should be detected from the AC'97 layer, but it seems
- that although CS4297A rev B reports 18-bit ADC resolution,
- samples are 20-bit */
- snd_pcm_hw_constraint_msbits(runtime, 0, 32, 20);
- return 0;
-}
-
-static int snd_cs4281_playback_close(struct snd_pcm_substream *substream)
-{
- struct cs4281_dma *dma = substream->runtime->private_data;
-
- dma->substream = NULL;
- return 0;
-}
-
-static int snd_cs4281_capture_close(struct snd_pcm_substream *substream)
-{
- struct cs4281_dma *dma = substream->runtime->private_data;
-
- dma->substream = NULL;
- return 0;
-}
-
-static struct snd_pcm_ops snd_cs4281_playback_ops = {
- .open = snd_cs4281_playback_open,
- .close = snd_cs4281_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cs4281_hw_params,
- .hw_free = snd_cs4281_hw_free,
- .prepare = snd_cs4281_playback_prepare,
- .trigger = snd_cs4281_trigger,
- .pointer = snd_cs4281_pointer,
-};
-
-static struct snd_pcm_ops snd_cs4281_capture_ops = {
- .open = snd_cs4281_capture_open,
- .close = snd_cs4281_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cs4281_hw_params,
- .hw_free = snd_cs4281_hw_free,
- .prepare = snd_cs4281_capture_prepare,
- .trigger = snd_cs4281_trigger,
- .pointer = snd_cs4281_pointer,
-};
-
-static int __devinit snd_cs4281_pcm(struct cs4281 * chip, int device,
- struct snd_pcm ** rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
- err = snd_pcm_new(chip->card, "CS4281", device, 1, 1, &pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs4281_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs4281_capture_ops);
-
- pcm->private_data = chip;
- pcm->info_flags = 0;
- strcpy(pcm->name, "CS4281");
- chip->pcm = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci), 64*1024, 512*1024);
-
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-/*
- * Mixer section
- */
-
-#define CS_VOL_MASK 0x1f
-
-static int snd_cs4281_info_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = CS_VOL_MASK;
- return 0;
-}
-
-static int snd_cs4281_get_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cs4281 *chip = snd_kcontrol_chip(kcontrol);
- int regL = (kcontrol->private_value >> 16) & 0xffff;
- int regR = kcontrol->private_value & 0xffff;
- int volL, volR;
-
- volL = CS_VOL_MASK - (snd_cs4281_peekBA0(chip, regL) & CS_VOL_MASK);
- volR = CS_VOL_MASK - (snd_cs4281_peekBA0(chip, regR) & CS_VOL_MASK);
-
- ucontrol->value.integer.value[0] = volL;
- ucontrol->value.integer.value[1] = volR;
- return 0;
-}
-
-static int snd_cs4281_put_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cs4281 *chip = snd_kcontrol_chip(kcontrol);
- int change = 0;
- int regL = (kcontrol->private_value >> 16) & 0xffff;
- int regR = kcontrol->private_value & 0xffff;
- int volL, volR;
-
- volL = CS_VOL_MASK - (snd_cs4281_peekBA0(chip, regL) & CS_VOL_MASK);
- volR = CS_VOL_MASK - (snd_cs4281_peekBA0(chip, regR) & CS_VOL_MASK);
-
- if (ucontrol->value.integer.value[0] != volL) {
- volL = CS_VOL_MASK - (ucontrol->value.integer.value[0] & CS_VOL_MASK);
- snd_cs4281_pokeBA0(chip, regL, volL);
- change = 1;
- }
- if (ucontrol->value.integer.value[1] != volR) {
- volR = CS_VOL_MASK - (ucontrol->value.integer.value[1] & CS_VOL_MASK);
- snd_cs4281_pokeBA0(chip, regR, volR);
- change = 1;
- }
- return change;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_dsp, -4650, 150, 0);
-
-static struct snd_kcontrol_new snd_cs4281_fm_vol =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Synth Playback Volume",
- .info = snd_cs4281_info_volume,
- .get = snd_cs4281_get_volume,
- .put = snd_cs4281_put_volume,
- .private_value = ((BA0_FMLVC << 16) | BA0_FMRVC),
- .tlv = { .p = db_scale_dsp },
-};
-
-static struct snd_kcontrol_new snd_cs4281_pcm_vol =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Stream Playback Volume",
- .info = snd_cs4281_info_volume,
- .get = snd_cs4281_get_volume,
- .put = snd_cs4281_put_volume,
- .private_value = ((BA0_PPLVC << 16) | BA0_PPRVC),
- .tlv = { .p = db_scale_dsp },
-};
-
-static void snd_cs4281_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
-{
- struct cs4281 *chip = bus->private_data;
- chip->ac97_bus = NULL;
-}
-
-static void snd_cs4281_mixer_free_ac97(struct snd_ac97 *ac97)
-{
- struct cs4281 *chip = ac97->private_data;
- if (ac97->num)
- chip->ac97_secondary = NULL;
- else
- chip->ac97 = NULL;
-}
-
-static int __devinit snd_cs4281_mixer(struct cs4281 * chip)
-{
- struct snd_card *card = chip->card;
- struct snd_ac97_template ac97;
- int err;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_cs4281_ac97_write,
- .read = snd_cs4281_ac97_read,
- };
-
- if ((err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus)) < 0)
- return err;
- chip->ac97_bus->private_free = snd_cs4281_mixer_free_ac97_bus;
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = chip;
- ac97.private_free = snd_cs4281_mixer_free_ac97;
- if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
- return err;
- if (chip->dual_codec) {
- ac97.num = 1;
- if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97_secondary)) < 0)
- return err;
- }
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4281_fm_vol, chip))) < 0)
- return err;
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cs4281_pcm_vol, chip))) < 0)
- return err;
- return 0;
-}
-
-
-/*
- * proc interface
- */
-
-static void snd_cs4281_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct cs4281 *chip = entry->private_data;
-
- snd_iprintf(buffer, "Cirrus Logic CS4281\n\n");
- snd_iprintf(buffer, "Spurious half IRQs : %u\n", chip->spurious_dhtc_irq);
- snd_iprintf(buffer, "Spurious end IRQs : %u\n", chip->spurious_dtc_irq);
-}
-
-static ssize_t snd_cs4281_BA0_read(struct snd_info_entry *entry,
- void *file_private_data,
- struct file *file, char __user *buf,
- size_t count, loff_t pos)
-{
- struct cs4281 *chip = entry->private_data;
-
- if (copy_to_user_fromio(buf, chip->ba0 + pos, count))
- return -EFAULT;
- return count;
-}
-
-static ssize_t snd_cs4281_BA1_read(struct snd_info_entry *entry,
- void *file_private_data,
- struct file *file, char __user *buf,
- size_t count, loff_t pos)
-{
- struct cs4281 *chip = entry->private_data;
-
- if (copy_to_user_fromio(buf, chip->ba1 + pos, count))
- return -EFAULT;
- return count;
-}
-
-static struct snd_info_entry_ops snd_cs4281_proc_ops_BA0 = {
- .read = snd_cs4281_BA0_read,
-};
-
-static struct snd_info_entry_ops snd_cs4281_proc_ops_BA1 = {
- .read = snd_cs4281_BA1_read,
-};
-
-static void __devinit snd_cs4281_proc_init(struct cs4281 * chip)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(chip->card, "cs4281", &entry))
- snd_info_set_text_ops(entry, chip, snd_cs4281_proc_read);
- if (! snd_card_proc_new(chip->card, "cs4281_BA0", &entry)) {
- entry->content = SNDRV_INFO_CONTENT_DATA;
- entry->private_data = chip;
- entry->c.ops = &snd_cs4281_proc_ops_BA0;
- entry->size = CS4281_BA0_SIZE;
- }
- if (! snd_card_proc_new(chip->card, "cs4281_BA1", &entry)) {
- entry->content = SNDRV_INFO_CONTENT_DATA;
- entry->private_data = chip;
- entry->c.ops = &snd_cs4281_proc_ops_BA1;
- entry->size = CS4281_BA1_SIZE;
- }
-}
-
-/*
- * joystick support
- */
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-
-static void snd_cs4281_gameport_trigger(struct gameport *gameport)
-{
- struct cs4281 *chip = gameport_get_port_data(gameport);
-
- if (snd_BUG_ON(!chip))
- return;
- snd_cs4281_pokeBA0(chip, BA0_JSPT, 0xff);
-}
-
-static unsigned char snd_cs4281_gameport_read(struct gameport *gameport)
-{
- struct cs4281 *chip = gameport_get_port_data(gameport);
-
- if (snd_BUG_ON(!chip))
- return 0;
- return snd_cs4281_peekBA0(chip, BA0_JSPT);
-}
-
-#ifdef COOKED_MODE
-static int snd_cs4281_gameport_cooked_read(struct gameport *gameport,
- int *axes, int *buttons)
-{
- struct cs4281 *chip = gameport_get_port_data(gameport);
- unsigned js1, js2, jst;
-
- if (snd_BUG_ON(!chip))
- return 0;
-
- js1 = snd_cs4281_peekBA0(chip, BA0_JSC1);
- js2 = snd_cs4281_peekBA0(chip, BA0_JSC2);
- jst = snd_cs4281_peekBA0(chip, BA0_JSPT);
-
- *buttons = (~jst >> 4) & 0x0F;
-
- axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF;
- axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF;
- axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF;
- axes[3] = ((js2 & JSC2_X2V_MASK) >> JSC2_X2V_SHIFT) & 0xFFFF;
-
- for (jst = 0; jst < 4; ++jst)
- if (axes[jst] == 0xFFFF) axes[jst] = -1;
- return 0;
-}
-#else
-#define snd_cs4281_gameport_cooked_read NULL
-#endif
-
-static int snd_cs4281_gameport_open(struct gameport *gameport, int mode)
-{
- switch (mode) {
-#ifdef COOKED_MODE
- case GAMEPORT_MODE_COOKED:
- return 0;
-#endif
- case GAMEPORT_MODE_RAW:
- return 0;
- default:
- return -1;
- }
- return 0;
-}
-
-static int __devinit snd_cs4281_create_gameport(struct cs4281 *chip)
-{
- struct gameport *gp;
-
- chip->gameport = gp = gameport_allocate_port();
- if (!gp) {
- printk(KERN_ERR "cs4281: cannot allocate memory for gameport\n");
- return -ENOMEM;
- }
-
- gameport_set_name(gp, "CS4281 Gameport");
- gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
- gameport_set_dev_parent(gp, &chip->pci->dev);
- gp->open = snd_cs4281_gameport_open;
- gp->read = snd_cs4281_gameport_read;
- gp->trigger = snd_cs4281_gameport_trigger;
- gp->cooked_read = snd_cs4281_gameport_cooked_read;
- gameport_set_port_data(gp, chip);
-
- snd_cs4281_pokeBA0(chip, BA0_JSIO, 0xFF); // ?
- snd_cs4281_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW);
-
- gameport_register_port(gp);
-
- return 0;
-}
-
-static void snd_cs4281_free_gameport(struct cs4281 *chip)
-{
- if (chip->gameport) {
- gameport_unregister_port(chip->gameport);
- chip->gameport = NULL;
- }
-}
-#else
-static inline int snd_cs4281_create_gameport(struct cs4281 *chip) { return -ENOSYS; }
-static inline void snd_cs4281_free_gameport(struct cs4281 *chip) { }
-#endif /* CONFIG_GAMEPORT || (MODULE && CONFIG_GAMEPORT_MODULE) */
-
-static int snd_cs4281_free(struct cs4281 *chip)
-{
- snd_cs4281_free_gameport(chip);
-
- if (chip->irq >= 0)
- synchronize_irq(chip->irq);
-
- /* Mask interrupts */
- snd_cs4281_pokeBA0(chip, BA0_HIMR, 0x7fffffff);
- /* Stop the DLL Clock logic. */
- snd_cs4281_pokeBA0(chip, BA0_CLKCR1, 0);
- /* Sound System Power Management - Turn Everything OFF */
- snd_cs4281_pokeBA0(chip, BA0_SSPM, 0);
- /* PCI interface - D3 state */
- pci_set_power_state(chip->pci, 3);
-
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
- if (chip->ba0)
- iounmap(chip->ba0);
- if (chip->ba1)
- iounmap(chip->ba1);
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
-
- kfree(chip);
- return 0;
-}
-
-static int snd_cs4281_dev_free(struct snd_device *device)
-{
- struct cs4281 *chip = device->device_data;
- return snd_cs4281_free(chip);
-}
-
-static int snd_cs4281_chip_init(struct cs4281 *chip); /* defined below */
-
-static int __devinit snd_cs4281_create(struct snd_card *card,
- struct pci_dev *pci,
- struct cs4281 ** rchip,
- int dual_codec)
-{
- struct cs4281 *chip;
- unsigned int tmp;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_cs4281_dev_free,
- };
-
- *rchip = NULL;
- if ((err = pci_enable_device(pci)) < 0)
- return err;
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
- spin_lock_init(&chip->reg_lock);
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
- pci_set_master(pci);
- if (dual_codec < 0 || dual_codec > 3) {
- snd_printk(KERN_ERR "invalid dual_codec option %d\n", dual_codec);
- dual_codec = 0;
- }
- chip->dual_codec = dual_codec;
-
- if ((err = pci_request_regions(pci, "CS4281")) < 0) {
- kfree(chip);
- pci_disable_device(pci);
- return err;
- }
- chip->ba0_addr = pci_resource_start(pci, 0);
- chip->ba1_addr = pci_resource_start(pci, 1);
-
- chip->ba0 = pci_ioremap_bar(pci, 0);
- chip->ba1 = pci_ioremap_bar(pci, 1);
- if (!chip->ba0 || !chip->ba1) {
- snd_cs4281_free(chip);
- return -ENOMEM;
- }
-
- if (request_irq(pci->irq, snd_cs4281_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_cs4281_free(chip);
- return -ENOMEM;
- }
- chip->irq = pci->irq;
-
- tmp = snd_cs4281_chip_init(chip);
- if (tmp) {
- snd_cs4281_free(chip);
- return tmp;
- }
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_cs4281_free(chip);
- return err;
- }
-
- snd_cs4281_proc_init(chip);
-
- snd_card_set_dev(card, &pci->dev);
-
- *rchip = chip;
- return 0;
-}
-
-static int snd_cs4281_chip_init(struct cs4281 *chip)
-{
- unsigned int tmp;
- unsigned long end_time;
- int retry_count = 2;
-
- /* Having EPPMC.FPDN=1 prevent proper chip initialisation */
- tmp = snd_cs4281_peekBA0(chip, BA0_EPPMC);
- if (tmp & BA0_EPPMC_FPDN)
- snd_cs4281_pokeBA0(chip, BA0_EPPMC, tmp & ~BA0_EPPMC_FPDN);
-
- __retry:
- tmp = snd_cs4281_peekBA0(chip, BA0_CFLR);
- if (tmp != BA0_CFLR_DEFAULT) {
- snd_cs4281_pokeBA0(chip, BA0_CFLR, BA0_CFLR_DEFAULT);
- tmp = snd_cs4281_peekBA0(chip, BA0_CFLR);
- if (tmp != BA0_CFLR_DEFAULT) {
- snd_printk(KERN_ERR "CFLR setup failed (0x%x)\n", tmp);
- return -EIO;
- }
- }
-
- /* Set the 'Configuration Write Protect' register
- * to 4281h. Allows vendor-defined configuration
- * space between 0e4h and 0ffh to be written. */
- snd_cs4281_pokeBA0(chip, BA0_CWPR, 0x4281);
-
- if ((tmp = snd_cs4281_peekBA0(chip, BA0_SERC1)) != (BA0_SERC1_SO1EN | BA0_SERC1_AC97)) {
- snd_printk(KERN_ERR "SERC1 AC'97 check failed (0x%x)\n", tmp);
- return -EIO;
- }
- if ((tmp = snd_cs4281_peekBA0(chip, BA0_SERC2)) != (BA0_SERC2_SI1EN | BA0_SERC2_AC97)) {
- snd_printk(KERN_ERR "SERC2 AC'97 check failed (0x%x)\n", tmp);
- return -EIO;
- }
-
- /* Sound System Power Management */
- snd_cs4281_pokeBA0(chip, BA0_SSPM, BA0_SSPM_MIXEN | BA0_SSPM_CSRCEN |
- BA0_SSPM_PSRCEN | BA0_SSPM_JSEN |
- BA0_SSPM_ACLEN | BA0_SSPM_FMEN);
-
- /* Serial Port Power Management */
- /* Blast the clock control register to zero so that the
- * PLL starts out in a known state, and blast the master serial
- * port control register to zero so that the serial ports also
- * start out in a known state. */
- snd_cs4281_pokeBA0(chip, BA0_CLKCR1, 0);
- snd_cs4281_pokeBA0(chip, BA0_SERMC, 0);
-
- /* Make ESYN go to zero to turn off
- * the Sync pulse on the AC97 link. */
- snd_cs4281_pokeBA0(chip, BA0_ACCTL, 0);
- udelay(50);
-
- /* Drive the ARST# pin low for a minimum of 1uS (as defined in the AC97
- * spec) and then drive it high. This is done for non AC97 modes since
- * there might be logic external to the CS4281 that uses the ARST# line
- * for a reset. */
- snd_cs4281_pokeBA0(chip, BA0_SPMC, 0);
- udelay(50);
- snd_cs4281_pokeBA0(chip, BA0_SPMC, BA0_SPMC_RSTN);
- msleep(50);
-
- if (chip->dual_codec)
- snd_cs4281_pokeBA0(chip, BA0_SPMC, BA0_SPMC_RSTN | BA0_SPMC_ASDI2E);
-
- /*
- * Set the serial port timing configuration.
- */
- snd_cs4281_pokeBA0(chip, BA0_SERMC,
- (chip->dual_codec ? BA0_SERMC_TCID(chip->dual_codec) : BA0_SERMC_TCID(1)) |
- BA0_SERMC_PTC_AC97 | BA0_SERMC_MSPE);
-
- /*
- * Start the DLL Clock logic.
- */
- snd_cs4281_pokeBA0(chip, BA0_CLKCR1, BA0_CLKCR1_DLLP);
- msleep(50);
- snd_cs4281_pokeBA0(chip, BA0_CLKCR1, BA0_CLKCR1_SWCE | BA0_CLKCR1_DLLP);
-
- /*
- * Wait for the DLL ready signal from the clock logic.
- */
- end_time = jiffies + HZ;
- do {
- /*
- * Read the AC97 status register to see if we've seen a CODEC
- * signal from the AC97 codec.
- */
- if (snd_cs4281_peekBA0(chip, BA0_CLKCR1) & BA0_CLKCR1_DLLRDY)
- goto __ok0;
- schedule_timeout_uninterruptible(1);
- } while (time_after_eq(end_time, jiffies));
-
- snd_printk(KERN_ERR "DLLRDY not seen\n");
- return -EIO;
-
- __ok0:
-
- /*
- * The first thing we do here is to enable sync generation. As soon
- * as we start receiving bit clock, we'll start producing the SYNC
- * signal.
- */
- snd_cs4281_pokeBA0(chip, BA0_ACCTL, BA0_ACCTL_ESYN);
-
- /*
- * Wait for the codec ready signal from the AC97 codec.
- */
- end_time = jiffies + HZ;
- do {
- /*
- * Read the AC97 status register to see if we've seen a CODEC
- * signal from the AC97 codec.
- */
- if (snd_cs4281_peekBA0(chip, BA0_ACSTS) & BA0_ACSTS_CRDY)
- goto __ok1;
- schedule_timeout_uninterruptible(1);
- } while (time_after_eq(end_time, jiffies));
-
- snd_printk(KERN_ERR "never read codec ready from AC'97 (0x%x)\n", snd_cs4281_peekBA0(chip, BA0_ACSTS));
- return -EIO;
-
- __ok1:
- if (chip->dual_codec) {
- end_time = jiffies + HZ;
- do {
- if (snd_cs4281_peekBA0(chip, BA0_ACSTS2) & BA0_ACSTS_CRDY)
- goto __codec2_ok;
- schedule_timeout_uninterruptible(1);
- } while (time_after_eq(end_time, jiffies));
- snd_printk(KERN_INFO "secondary codec doesn't respond. disable it...\n");
- chip->dual_codec = 0;
- __codec2_ok: ;
- }
-
- /*
- * Assert the valid frame signal so that we can start sending commands
- * to the AC97 codec.
- */
-
- snd_cs4281_pokeBA0(chip, BA0_ACCTL, BA0_ACCTL_VFRM | BA0_ACCTL_ESYN);
-
- /*
- * Wait until we've sampled input slots 3 and 4 as valid, meaning that
- * the codec is pumping ADC data across the AC-link.
- */
-
- end_time = jiffies + HZ;
- do {
- /*
- * Read the input slot valid register and see if input slots 3
- * 4 are valid yet.
- */
- if ((snd_cs4281_peekBA0(chip, BA0_ACISV) & (BA0_ACISV_SLV(3) | BA0_ACISV_SLV(4))) == (BA0_ACISV_SLV(3) | BA0_ACISV_SLV(4)))
- goto __ok2;
- schedule_timeout_uninterruptible(1);
- } while (time_after_eq(end_time, jiffies));
-
- if (--retry_count > 0)
- goto __retry;
- snd_printk(KERN_ERR "never read ISV3 and ISV4 from AC'97\n");
- return -EIO;
-
- __ok2:
-
- /*
- * Now, assert valid frame and the slot 3 and 4 valid bits. This will
- * commense the transfer of digital audio data to the AC97 codec.
- */
- snd_cs4281_pokeBA0(chip, BA0_ACOSV, BA0_ACOSV_SLV(3) | BA0_ACOSV_SLV(4));
-
- /*
- * Initialize DMA structures
- */
- for (tmp = 0; tmp < 4; tmp++) {
- struct cs4281_dma *dma = &chip->dma[tmp];
- dma->regDBA = BA0_DBA0 + (tmp * 0x10);
- dma->regDCA = BA0_DCA0 + (tmp * 0x10);
- dma->regDBC = BA0_DBC0 + (tmp * 0x10);
- dma->regDCC = BA0_DCC0 + (tmp * 0x10);
- dma->regDMR = BA0_DMR0 + (tmp * 8);
- dma->regDCR = BA0_DCR0 + (tmp * 8);
- dma->regHDSR = BA0_HDSR0 + (tmp * 4);
- dma->regFCR = BA0_FCR0 + (tmp * 4);
- dma->regFSIC = BA0_FSIC0 + (tmp * 4);
- dma->fifo_offset = tmp * CS4281_FIFO_SIZE;
- snd_cs4281_pokeBA0(chip, dma->regFCR,
- BA0_FCR_LS(31) |
- BA0_FCR_RS(31) |
- BA0_FCR_SZ(CS4281_FIFO_SIZE) |
- BA0_FCR_OF(dma->fifo_offset));
- }
-
- chip->src_left_play_slot = 0; /* AC'97 left PCM playback (3) */
- chip->src_right_play_slot = 1; /* AC'97 right PCM playback (4) */
- chip->src_left_rec_slot = 10; /* AC'97 left PCM record (3) */
- chip->src_right_rec_slot = 11; /* AC'97 right PCM record (4) */
-
- /* Activate wave playback FIFO for FM playback */
- chip->dma[0].valFCR = BA0_FCR_FEN | BA0_FCR_LS(0) |
- BA0_FCR_RS(1) |
- BA0_FCR_SZ(CS4281_FIFO_SIZE) |
- BA0_FCR_OF(chip->dma[0].fifo_offset);
- snd_cs4281_pokeBA0(chip, chip->dma[0].regFCR, chip->dma[0].valFCR);
- snd_cs4281_pokeBA0(chip, BA0_SRCSA, (chip->src_left_play_slot << 0) |
- (chip->src_right_play_slot << 8) |
- (chip->src_left_rec_slot << 16) |
- (chip->src_right_rec_slot << 24));
-
- /* Initialize digital volume */
- snd_cs4281_pokeBA0(chip, BA0_PPLVC, 0);
- snd_cs4281_pokeBA0(chip, BA0_PPRVC, 0);
-
- /* Enable IRQs */
- snd_cs4281_pokeBA0(chip, BA0_HICR, BA0_HICR_EOI);
- /* Unmask interrupts */
- snd_cs4281_pokeBA0(chip, BA0_HIMR, 0x7fffffff & ~(
- BA0_HISR_MIDI |
- BA0_HISR_DMAI |
- BA0_HISR_DMA(0) |
- BA0_HISR_DMA(1) |
- BA0_HISR_DMA(2) |
- BA0_HISR_DMA(3)));
- synchronize_irq(chip->irq);
-
- return 0;
-}
-
-/*
- * MIDI section
- */
-
-static void snd_cs4281_midi_reset(struct cs4281 *chip)
-{
- snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr | BA0_MIDCR_MRST);
- udelay(100);
- snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
-}
-
-static int snd_cs4281_midi_input_open(struct snd_rawmidi_substream *substream)
-{
- struct cs4281 *chip = substream->rmidi->private_data;
-
- spin_lock_irq(&chip->reg_lock);
- chip->midcr |= BA0_MIDCR_RXE;
- chip->midi_input = substream;
- if (!(chip->uartm & CS4281_MODE_OUTPUT)) {
- snd_cs4281_midi_reset(chip);
- } else {
- snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
- }
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static int snd_cs4281_midi_input_close(struct snd_rawmidi_substream *substream)
-{
- struct cs4281 *chip = substream->rmidi->private_data;
-
- spin_lock_irq(&chip->reg_lock);
- chip->midcr &= ~(BA0_MIDCR_RXE | BA0_MIDCR_RIE);
- chip->midi_input = NULL;
- if (!(chip->uartm & CS4281_MODE_OUTPUT)) {
- snd_cs4281_midi_reset(chip);
- } else {
- snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
- }
- chip->uartm &= ~CS4281_MODE_INPUT;
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static int snd_cs4281_midi_output_open(struct snd_rawmidi_substream *substream)
-{
- struct cs4281 *chip = substream->rmidi->private_data;
-
- spin_lock_irq(&chip->reg_lock);
- chip->uartm |= CS4281_MODE_OUTPUT;
- chip->midcr |= BA0_MIDCR_TXE;
- chip->midi_output = substream;
- if (!(chip->uartm & CS4281_MODE_INPUT)) {
- snd_cs4281_midi_reset(chip);
- } else {
- snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
- }
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static int snd_cs4281_midi_output_close(struct snd_rawmidi_substream *substream)
-{
- struct cs4281 *chip = substream->rmidi->private_data;
-
- spin_lock_irq(&chip->reg_lock);
- chip->midcr &= ~(BA0_MIDCR_TXE | BA0_MIDCR_TIE);
- chip->midi_output = NULL;
- if (!(chip->uartm & CS4281_MODE_INPUT)) {
- snd_cs4281_midi_reset(chip);
- } else {
- snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
- }
- chip->uartm &= ~CS4281_MODE_OUTPUT;
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static void snd_cs4281_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- unsigned long flags;
- struct cs4281 *chip = substream->rmidi->private_data;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (up) {
- if ((chip->midcr & BA0_MIDCR_RIE) == 0) {
- chip->midcr |= BA0_MIDCR_RIE;
- snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
- }
- } else {
- if (chip->midcr & BA0_MIDCR_RIE) {
- chip->midcr &= ~BA0_MIDCR_RIE;
- snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
- }
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-
-static void snd_cs4281_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- unsigned long flags;
- struct cs4281 *chip = substream->rmidi->private_data;
- unsigned char byte;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (up) {
- if ((chip->midcr & BA0_MIDCR_TIE) == 0) {
- chip->midcr |= BA0_MIDCR_TIE;
- /* fill UART FIFO buffer at first, and turn Tx interrupts only if necessary */
- while ((chip->midcr & BA0_MIDCR_TIE) &&
- (snd_cs4281_peekBA0(chip, BA0_MIDSR) & BA0_MIDSR_TBF) == 0) {
- if (snd_rawmidi_transmit(substream, &byte, 1) != 1) {
- chip->midcr &= ~BA0_MIDCR_TIE;
- } else {
- snd_cs4281_pokeBA0(chip, BA0_MIDWP, byte);
- }
- }
- snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
- }
- } else {
- if (chip->midcr & BA0_MIDCR_TIE) {
- chip->midcr &= ~BA0_MIDCR_TIE;
- snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
- }
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-
-static struct snd_rawmidi_ops snd_cs4281_midi_output =
-{
- .open = snd_cs4281_midi_output_open,
- .close = snd_cs4281_midi_output_close,
- .trigger = snd_cs4281_midi_output_trigger,
-};
-
-static struct snd_rawmidi_ops snd_cs4281_midi_input =
-{
- .open = snd_cs4281_midi_input_open,
- .close = snd_cs4281_midi_input_close,
- .trigger = snd_cs4281_midi_input_trigger,
-};
-
-static int __devinit snd_cs4281_midi(struct cs4281 * chip, int device,
- struct snd_rawmidi **rrawmidi)
-{
- struct snd_rawmidi *rmidi;
- int err;
-
- if (rrawmidi)
- *rrawmidi = NULL;
- if ((err = snd_rawmidi_new(chip->card, "CS4281", device, 1, 1, &rmidi)) < 0)
- return err;
- strcpy(rmidi->name, "CS4281");
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_cs4281_midi_output);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_cs4281_midi_input);
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
- rmidi->private_data = chip;
- chip->rmidi = rmidi;
- if (rrawmidi)
- *rrawmidi = rmidi;
- return 0;
-}
-
-/*
- * Interrupt handler
- */
-
-static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id)
-{
- struct cs4281 *chip = dev_id;
- unsigned int status, dma, val;
- struct cs4281_dma *cdma;
-
- if (chip == NULL)
- return IRQ_NONE;
- status = snd_cs4281_peekBA0(chip, BA0_HISR);
- if ((status & 0x7fffffff) == 0) {
- snd_cs4281_pokeBA0(chip, BA0_HICR, BA0_HICR_EOI);
- return IRQ_NONE;
- }
-
- if (status & (BA0_HISR_DMA(0)|BA0_HISR_DMA(1)|BA0_HISR_DMA(2)|BA0_HISR_DMA(3))) {
- for (dma = 0; dma < 4; dma++)
- if (status & BA0_HISR_DMA(dma)) {
- cdma = &chip->dma[dma];
- spin_lock(&chip->reg_lock);
- /* ack DMA IRQ */
- val = snd_cs4281_peekBA0(chip, cdma->regHDSR);
- /* workaround, sometimes CS4281 acknowledges */
- /* end or middle transfer position twice */
- cdma->frag++;
- if ((val & BA0_HDSR_DHTC) && !(cdma->frag & 1)) {
- cdma->frag--;
- chip->spurious_dhtc_irq++;
- spin_unlock(&chip->reg_lock);
- continue;
- }
- if ((val & BA0_HDSR_DTC) && (cdma->frag & 1)) {
- cdma->frag--;
- chip->spurious_dtc_irq++;
- spin_unlock(&chip->reg_lock);
- continue;
- }
- spin_unlock(&chip->reg_lock);
- snd_pcm_period_elapsed(cdma->substream);
- }
- }
-
- if ((status & BA0_HISR_MIDI) && chip->rmidi) {
- unsigned char c;
-
- spin_lock(&chip->reg_lock);
- while ((snd_cs4281_peekBA0(chip, BA0_MIDSR) & BA0_MIDSR_RBE) == 0) {
- c = snd_cs4281_peekBA0(chip, BA0_MIDRP);
- if ((chip->midcr & BA0_MIDCR_RIE) == 0)
- continue;
- snd_rawmidi_receive(chip->midi_input, &c, 1);
- }
- while ((snd_cs4281_peekBA0(chip, BA0_MIDSR) & BA0_MIDSR_TBF) == 0) {
- if ((chip->midcr & BA0_MIDCR_TIE) == 0)
- break;
- if (snd_rawmidi_transmit(chip->midi_output, &c, 1) != 1) {
- chip->midcr &= ~BA0_MIDCR_TIE;
- snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
- break;
- }
- snd_cs4281_pokeBA0(chip, BA0_MIDWP, c);
- }
- spin_unlock(&chip->reg_lock);
- }
-
- /* EOI to the PCI part... reenables interrupts */
- snd_cs4281_pokeBA0(chip, BA0_HICR, BA0_HICR_EOI);
-
- return IRQ_HANDLED;
-}
-
-
-/*
- * OPL3 command
- */
-static void snd_cs4281_opl3_command(struct snd_opl3 *opl3, unsigned short cmd,
- unsigned char val)
-{
- unsigned long flags;
- struct cs4281 *chip = opl3->private_data;
- void __iomem *port;
-
- if (cmd & OPL3_RIGHT)
- port = chip->ba0 + BA0_B1AP; /* right port */
- else
- port = chip->ba0 + BA0_B0AP; /* left port */
-
- spin_lock_irqsave(&opl3->reg_lock, flags);
-
- writel((unsigned int)cmd, port);
- udelay(10);
-
- writel((unsigned int)val, port + 4);
- udelay(30);
-
- spin_unlock_irqrestore(&opl3->reg_lock, flags);
-}
-
-static int __devinit snd_cs4281_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct cs4281 *chip;
- struct snd_opl3 *opl3;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- if ((err = snd_cs4281_create(card, pci, &chip, dual_codec[dev])) < 0) {
- snd_card_free(card);
- return err;
- }
- card->private_data = chip;
-
- if ((err = snd_cs4281_mixer(chip)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_cs4281_pcm(chip, 0, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_cs4281_midi(chip, 0, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_opl3_new(card, OPL3_HW_OPL3_CS4281, &opl3)) < 0) {
- snd_card_free(card);
- return err;
- }
- opl3->private_data = chip;
- opl3->command = snd_cs4281_opl3_command;
- snd_opl3_init(opl3);
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- snd_cs4281_create_gameport(chip);
- strcpy(card->driver, "CS4281");
- strcpy(card->shortname, "Cirrus Logic CS4281");
- sprintf(card->longname, "%s at 0x%lx, irq %d",
- card->shortname,
- chip->ba0_addr,
- chip->irq);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_cs4281_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-/*
- * Power Management
- */
-#ifdef CONFIG_PM
-
-static int saved_regs[SUSPEND_REGISTERS] = {
- BA0_JSCTL,
- BA0_GPIOR,
- BA0_SSCR,
- BA0_MIDCR,
- BA0_SRCSA,
- BA0_PASR,
- BA0_CASR,
- BA0_DACSR,
- BA0_ADCSR,
- BA0_FMLVC,
- BA0_FMRVC,
- BA0_PPLVC,
- BA0_PPRVC,
-};
-
-#define CLKCR1_CKRA 0x00010000L
-
-static int cs4281_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct cs4281 *chip = card->private_data;
- u32 ulCLK;
- unsigned int i;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(chip->pcm);
-
- snd_ac97_suspend(chip->ac97);
- snd_ac97_suspend(chip->ac97_secondary);
-
- ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1);
- ulCLK |= CLKCR1_CKRA;
- snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK);
-
- /* Disable interrupts. */
- snd_cs4281_pokeBA0(chip, BA0_HICR, BA0_HICR_CHGM);
-
- /* remember the status registers */
- for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
- if (saved_regs[i])
- chip->suspend_regs[i] = snd_cs4281_peekBA0(chip, saved_regs[i]);
-
- /* Turn off the serial ports. */
- snd_cs4281_pokeBA0(chip, BA0_SERMC, 0);
-
- /* Power off FM, Joystick, AC link, */
- snd_cs4281_pokeBA0(chip, BA0_SSPM, 0);
-
- /* DLL off. */
- snd_cs4281_pokeBA0(chip, BA0_CLKCR1, 0);
-
- /* AC link off. */
- snd_cs4281_pokeBA0(chip, BA0_SPMC, 0);
-
- ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1);
- ulCLK &= ~CLKCR1_CKRA;
- snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK);
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int cs4281_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct cs4281 *chip = card->private_data;
- unsigned int i;
- u32 ulCLK;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "cs4281: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
-
- ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1);
- ulCLK |= CLKCR1_CKRA;
- snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK);
-
- snd_cs4281_chip_init(chip);
-
- /* restore the status registers */
- for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
- if (saved_regs[i])
- snd_cs4281_pokeBA0(chip, saved_regs[i], chip->suspend_regs[i]);
-
- snd_ac97_resume(chip->ac97);
- snd_ac97_resume(chip->ac97_secondary);
-
- ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1);
- ulCLK &= ~CLKCR1_CKRA;
- snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif /* CONFIG_PM */
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_cs4281_ids,
- .probe = snd_cs4281_probe,
- .remove = __devexit_p(snd_cs4281_remove),
-#ifdef CONFIG_PM
- .suspend = cs4281_suspend,
- .resume = cs4281_resume,
-#endif
-};
-
-static int __init alsa_card_cs4281_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_cs4281_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_cs4281_init)
-module_exit(alsa_card_cs4281_exit)
diff --git a/ANDROID_3.4.5/sound/pci/cs46xx/Makefile b/ANDROID_3.4.5/sound/pci/cs46xx/Makefile
deleted file mode 100644
index 67e811ec..00000000
--- a/ANDROID_3.4.5/sound/pci/cs46xx/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-cs46xx-y := cs46xx.o cs46xx_lib.o
-snd-cs46xx-$(CONFIG_SND_CS46XX_NEW_DSP) += dsp_spos.o dsp_spos_scb_lib.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_CS46XX) += snd-cs46xx.o
diff --git a/ANDROID_3.4.5/sound/pci/cs46xx/cs46xx.c b/ANDROID_3.4.5/sound/pci/cs46xx/cs46xx.c
deleted file mode 100644
index 819d79d0..00000000
--- a/ANDROID_3.4.5/sound/pci/cs46xx/cs46xx.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- NOTES:
- - sometimes the sound is metallic and sibilant, unloading and
- reloading the module may solve this.
-*/
-
-#include <linux/pci.h>
-#include <linux/time.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/cs46xx.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Cirrus Logic Sound Fusion CS46XX");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Cirrus Logic,Sound Fusion (CS4280)},"
- "{Cirrus Logic,Sound Fusion (CS4610)},"
- "{Cirrus Logic,Sound Fusion (CS4612)},"
- "{Cirrus Logic,Sound Fusion (CS4615)},"
- "{Cirrus Logic,Sound Fusion (CS4622)},"
- "{Cirrus Logic,Sound Fusion (CS4624)},"
- "{Cirrus Logic,Sound Fusion (CS4630)}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static bool external_amp[SNDRV_CARDS];
-static bool thinkpad[SNDRV_CARDS];
-static bool mmap_valid[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for the CS46xx soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for the CS46xx soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable CS46xx soundcard.");
-module_param_array(external_amp, bool, NULL, 0444);
-MODULE_PARM_DESC(external_amp, "Force to enable external amplifer.");
-module_param_array(thinkpad, bool, NULL, 0444);
-MODULE_PARM_DESC(thinkpad, "Force to enable Thinkpad's CLKRUN control.");
-module_param_array(mmap_valid, bool, NULL, 0444);
-MODULE_PARM_DESC(mmap_valid, "Support OSS mmap.");
-
-static DEFINE_PCI_DEVICE_TABLE(snd_cs46xx_ids) = {
- { PCI_VDEVICE(CIRRUS, 0x6001), 0, }, /* CS4280 */
- { PCI_VDEVICE(CIRRUS, 0x6003), 0, }, /* CS4612 */
- { PCI_VDEVICE(CIRRUS, 0x6004), 0, }, /* CS4615 */
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_cs46xx_ids);
-
-static int __devinit snd_card_cs46xx_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct snd_cs46xx *chip;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
- if ((err = snd_cs46xx_create(card, pci,
- external_amp[dev], thinkpad[dev],
- &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
- card->private_data = chip;
- chip->accept_valid = mmap_valid[dev];
- if ((err = snd_cs46xx_pcm(chip, 0, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- if ((err = snd_cs46xx_pcm_rear(chip,1, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_cs46xx_pcm_iec958(chip,2,NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
-#endif
- if ((err = snd_cs46xx_mixer(chip, 2)) < 0) {
- snd_card_free(card);
- return err;
- }
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- if (chip->nr_ac97_codecs ==2) {
- if ((err = snd_cs46xx_pcm_center_lfe(chip,3,NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- }
-#endif
- if ((err = snd_cs46xx_midi(chip, 0, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_cs46xx_start_dsp(chip)) < 0) {
- snd_card_free(card);
- return err;
- }
-
-
- snd_cs46xx_gameport(chip);
-
- strcpy(card->driver, "CS46xx");
- strcpy(card->shortname, "Sound Fusion CS46xx");
- sprintf(card->longname, "%s at 0x%lx/0x%lx, irq %i",
- card->shortname,
- chip->ba0_addr,
- chip->ba1_addr,
- chip->irq);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_card_cs46xx_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_cs46xx_ids,
- .probe = snd_card_cs46xx_probe,
- .remove = __devexit_p(snd_card_cs46xx_remove),
-#ifdef CONFIG_PM
- .suspend = snd_cs46xx_suspend,
- .resume = snd_cs46xx_resume,
-#endif
-};
-
-static int __init alsa_card_cs46xx_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_cs46xx_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_cs46xx_init)
-module_exit(alsa_card_cs46xx_exit)
diff --git a/ANDROID_3.4.5/sound/pci/cs46xx/cs46xx_image.h b/ANDROID_3.4.5/sound/pci/cs46xx/cs46xx_image.h
deleted file mode 100644
index dc93f62d..00000000
--- a/ANDROID_3.4.5/sound/pci/cs46xx/cs46xx_image.h
+++ /dev/null
@@ -1,3468 +0,0 @@
-struct BA1struct {
- struct {
- unsigned long offset;
- unsigned long size;
- } memory[BA1_MEMORY_COUNT];
- u32 map[BA1_DWORD_SIZE];
-};
-
-
-static struct BA1struct BA1Struct = {
-{{ 0x00000000, 0x00003000 },{ 0x00010000, 0x00003800 },{ 0x00020000, 0x00007000 }},
-{0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000163,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00200040,0x00008010,0x00000000,
-0x00000000,0x80000001,0x00000001,0x00060000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00900080,0x00000173,0x00000000,
-0x00000000,0x00000010,0x00800000,0x00900000,
-0xf2c0000f,0x00000200,0x00000000,0x00010600,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000163,0x330300c2,
-0x06000000,0x00000000,0x80008000,0x80008000,
-0x3fc0000f,0x00000301,0x00010400,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00b00000,0x00d0806d,0x330480c3,
-0x04800000,0x00000001,0x00800001,0x0000ffff,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x066a0600,0x06350070,0x0000929d,0x929d929d,
-0x00000000,0x0000735a,0x00000600,0x00000000,
-0x929d735a,0x8734abfe,0x00010000,0x735a735a,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x0000804f,0x000000c3,
-0x05000000,0x00a00010,0x00000000,0x80008000,
-0x00000000,0x00000000,0x00000700,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000080,0x00a00000,0x0000809a,0x000000c2,
-0x07400000,0x00000000,0x80008000,0xffffffff,
-0x00c80028,0x00005555,0x00000000,0x000107a0,
-0x00c80028,0x000000c2,0x06800000,0x00000000,
-0x06e00080,0x00300000,0x000080bb,0x000000c9,
-0x07a00000,0x04000000,0x80008000,0xffffffff,
-0x00c80028,0x00005555,0x00000000,0x00000780,
-0x00c80028,0x000000c5,0xff800000,0x00000000,
-0x00640080,0x00c00000,0x00008197,0x000000c9,
-0x07800000,0x04000000,0x80008000,0xffffffff,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x0000805e,0x000000c1,
-0x00000000,0x00800000,0x80008000,0x80008000,
-0x00020000,0x0000ffff,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x929d0600,0x929d929d,0x929d929d,0x929d0000,
-0x929d929d,0x929d929d,0x929d929d,0x929d929d,
-0x929d929d,0x00100635,0x060b013f,0x00000004,
-0x00000001,0x007a0002,0x00000000,0x066e0610,
-0x0105929d,0x929d929d,0x929d929d,0x929d929d,
-0x929d929d,0xa431ac75,0x0001735a,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0x735a0051,
-0x00000000,0x929d929d,0x929d929d,0x929d929d,
-0x929d929d,0x929d929d,0x929d929d,0x929d929d,
-0x929d929d,0x929d929d,0x00000000,0x06400136,
-0x0000270f,0x00010000,0x007a0000,0x00000000,
-0x068e0645,0x0105929d,0x929d929d,0x929d929d,
-0x929d929d,0x929d929d,0xa431ac75,0x0001735a,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0x735a0100,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00010004,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00001705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00009705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00011705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00019705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00021705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00029705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00031705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00039705,0x00001400,0x000a411e,0x00001003,
-0x000fe19e,0x00001003,0x0009c730,0x00001003,
-0x0008e19c,0x00001003,0x000083c1,0x00093040,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00009705,0x00001400,0x000a211e,0x00001003,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00011705,0x00001400,0x000a211e,0x00001003,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00019705,0x00001400,0x000a211e,0x00001003,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00021705,0x00001400,0x000a211e,0x00001003,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00029705,0x00001400,0x000a211e,0x00001003,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00031705,0x00001400,0x000a211e,0x00001003,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00039705,0x00001400,0x000a211e,0x00001003,
-0x0000a730,0x00001008,0x000e2730,0x00001002,
-0x0000a731,0x00001002,0x0000a731,0x00001002,
-0x0000a731,0x00001002,0x0000a731,0x00001002,
-0x0000a731,0x00001002,0x0000a731,0x00001002,
-0x00000000,0x00000000,0x000f619c,0x00001003,
-0x0007f801,0x000c0000,0x00000037,0x00001000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x000c0000,0x00000000,0x00000000,
-0x0000373c,0x00001000,0x00000000,0x00000000,
-0x000ee19c,0x00001003,0x0007f801,0x000c0000,
-0x00000037,0x00001000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x0000273c,0x00001000,
-0x00000033,0x00001000,0x000e679e,0x00001003,
-0x00007705,0x00001400,0x000ac71e,0x00001003,
-0x00087fc1,0x000c3be0,0x0007f801,0x000c0000,
-0x00000037,0x00001000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x0000a730,0x00001003,
-0x00000033,0x00001000,0x0007f801,0x000c0000,
-0x00000037,0x00001000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x000c0000,
-0x00000032,0x00001000,0x0000273d,0x00001000,
-0x0004a730,0x00001003,0x00000f41,0x00097140,
-0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
-0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
-0x00000000,0x00000000,0x0001bf05,0x0003fc40,
-0x00002725,0x000aa400,0x00013705,0x00093a00,
-0x0000002e,0x0009d6c0,0x00038630,0x00001004,
-0x0004ef0a,0x000eb785,0x0003fc8a,0x00000000,
-0x00000000,0x000c70e0,0x0007d182,0x0002c640,
-0x00000630,0x00001004,0x000799b8,0x0002c6c0,
-0x00031705,0x00092240,0x00039f05,0x000932c0,
-0x0003520a,0x00000000,0x00040731,0x0000100b,
-0x00010705,0x000b20c0,0x00000000,0x000eba44,
-0x00032108,0x000c60c4,0x00065208,0x000c2917,
-0x000406b0,0x00001007,0x00012f05,0x00036880,
-0x0002818e,0x000c0000,0x0004410a,0x00000000,
-0x00040630,0x00001007,0x00029705,0x000c0000,
-0x00000000,0x00000000,0x00003fc1,0x0003fc40,
-0x000037c1,0x00091b40,0x00003fc1,0x000911c0,
-0x000037c1,0x000957c0,0x00003fc1,0x000951c0,
-0x000037c1,0x00000000,0x00003fc1,0x000991c0,
-0x000037c1,0x00000000,0x00003fc1,0x0009d1c0,
-0x000037c1,0x00000000,0x0001ccc1,0x000915c0,
-0x0001c441,0x0009d800,0x0009cdc1,0x00091240,
-0x0001c541,0x00091d00,0x0009cfc1,0x00095240,
-0x0001c741,0x00095c80,0x000e8ca9,0x00099240,
-0x000e85ad,0x00095640,0x00069ca9,0x00099d80,
-0x000e952d,0x00099640,0x000eaca9,0x0009d6c0,
-0x000ea5ad,0x00091a40,0x0006bca9,0x0009de80,
-0x000eb52d,0x00095a40,0x000ecca9,0x00099ac0,
-0x000ec5ad,0x0009da40,0x000edca9,0x0009d300,
-0x000a6e0a,0x00001000,0x000ed52d,0x00091e40,
-0x000eeca9,0x00095ec0,0x000ee5ad,0x00099e40,
-0x0006fca9,0x00002500,0x000fb208,0x000c59a0,
-0x000ef52d,0x0009de40,0x00068ca9,0x000912c1,
-0x000683ad,0x00095241,0x00020f05,0x000991c1,
-0x00000000,0x00000000,0x00086f88,0x00001000,
-0x0009cf81,0x000b5340,0x0009c701,0x000b92c0,
-0x0009de81,0x000bd300,0x0009d601,0x000b1700,
-0x0001fd81,0x000b9d80,0x0009f501,0x000b57c0,
-0x000a0f81,0x000bd740,0x00020701,0x000b5c80,
-0x000a1681,0x000b97c0,0x00021601,0x00002500,
-0x000a0701,0x000b9b40,0x000a0f81,0x000b1bc0,
-0x00021681,0x00002d00,0x00020f81,0x000bd800,
-0x000a0701,0x000b5bc0,0x00021601,0x00003500,
-0x000a0f81,0x000b5f40,0x000a0701,0x000bdbc0,
-0x00021681,0x00003d00,0x00020f81,0x000b1d00,
-0x000a0701,0x000b1fc0,0x00021601,0x00020500,
-0x00020f81,0x000b1341,0x000a0701,0x000b9fc0,
-0x00021681,0x00020d00,0x00020f81,0x000bde80,
-0x000a0701,0x000bdfc0,0x00021601,0x00021500,
-0x00020f81,0x000b9341,0x00020701,0x000b53c1,
-0x00021681,0x00021d00,0x000a0f81,0x000d0380,
-0x0000b601,0x000b15c0,0x00007b01,0x00000000,
-0x00007b81,0x000bd1c0,0x00007b01,0x00000000,
-0x00007b81,0x000b91c0,0x00007b01,0x000b57c0,
-0x00007b81,0x000b51c0,0x00007b01,0x000b1b40,
-0x00007b81,0x000b11c0,0x00087b01,0x000c3dc0,
-0x0007e488,0x000d7e45,0x00000000,0x000d7a44,
-0x0007e48a,0x00000000,0x00011f05,0x00084080,
-0x00000000,0x00000000,0x00001705,0x000b3540,
-0x00008a01,0x000bf040,0x00007081,0x000bb5c0,
-0x00055488,0x00000000,0x0000d482,0x0003fc40,
-0x0003fc88,0x00000000,0x0001e401,0x000b3a00,
-0x0001ec81,0x000bd6c0,0x0004ef08,0x000eb784,
-0x000c86b0,0x00001007,0x00008281,0x000bb240,
-0x0000b801,0x000b7140,0x00007888,0x00000000,
-0x0000073c,0x00001000,0x0007f188,0x000c0000,
-0x00000000,0x00000000,0x00055288,0x000c555c,
-0x0005528a,0x000c0000,0x0009fa88,0x000c5d00,
-0x0000fa88,0x00000000,0x00000032,0x00001000,
-0x0000073d,0x00001000,0x0007f188,0x000c0000,
-0x00000000,0x00000000,0x0008c01c,0x00001003,
-0x00002705,0x00001008,0x0008b201,0x000c1392,
-0x0000ba01,0x00000000,0x00008731,0x00001400,
-0x0004c108,0x000fe0c4,0x00057488,0x00000000,
-0x000a6388,0x00001001,0x0008b334,0x000bc141,
-0x0003020e,0x00000000,0x000886b0,0x00001008,
-0x00003625,0x000c5dfa,0x000a638a,0x00001001,
-0x0008020e,0x00001002,0x0008a6b0,0x00001008,
-0x0007f301,0x00000000,0x00000000,0x00000000,
-0x00002725,0x000a8c40,0x000000ae,0x00000000,
-0x000d8630,0x00001008,0x00000000,0x000c74e0,
-0x0007d182,0x0002d640,0x000a8630,0x00001008,
-0x000799b8,0x0002d6c0,0x0000748a,0x000c3ec5,
-0x0007420a,0x000c0000,0x00062208,0x000c4117,
-0x00070630,0x00001009,0x00000000,0x000c0000,
-0x0001022e,0x00000000,0x0003a630,0x00001009,
-0x00000000,0x000c0000,0x00000036,0x00001000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x0002a730,0x00001008,0x0007f801,0x000c0000,
-0x00000037,0x00001000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x0002a730,0x00001008,
-0x00000033,0x00001000,0x0002a705,0x00001008,
-0x00007a01,0x000c0000,0x000e6288,0x000d550a,
-0x0006428a,0x00000000,0x00060730,0x0000100a,
-0x00000000,0x000c0000,0x00000000,0x00000000,
-0x0007aab0,0x00034880,0x00078fb0,0x0000100b,
-0x00057488,0x00000000,0x00033b94,0x00081140,
-0x000183ae,0x00000000,0x000786b0,0x0000100b,
-0x00022f05,0x000c3545,0x0000eb8a,0x00000000,
-0x00042731,0x00001003,0x0007aab0,0x00034880,
-0x00048fb0,0x0000100a,0x00057488,0x00000000,
-0x00033b94,0x00081140,0x000183ae,0x00000000,
-0x000806b0,0x0000100b,0x00022f05,0x00000000,
-0x00007401,0x00091140,0x00048f05,0x000951c0,
-0x00042731,0x00001003,0x0000473d,0x00001000,
-0x000f19b0,0x000bbc47,0x00080000,0x000bffc7,
-0x000fe19e,0x00001003,0x00000000,0x00000000,
-0x0008e19c,0x00001003,0x000083c1,0x00093040,
-0x00000f41,0x00097140,0x0000a841,0x0009b240,
-0x0000a0c1,0x0009f040,0x0001c641,0x00093540,
-0x0001cec1,0x0009b5c0,0x00000000,0x000fdc44,
-0x00055208,0x00000000,0x00010705,0x000a2880,
-0x0000a23a,0x00093a00,0x0003fc8a,0x000df6c5,
-0x0004ef0a,0x000c0000,0x00012f05,0x00036880,
-0x00065308,0x000c2997,0x000d86b0,0x0000100a,
-0x0004410a,0x000d40c7,0x00000000,0x00000000,
-0x00080730,0x00001004,0x00056f0a,0x000ea105,
-0x00000000,0x00000000,0x0000473d,0x00001000,
-0x000f19b0,0x000bbc47,0x00080000,0x000bffc7,
-0x0000273d,0x00001000,0x00000000,0x000eba44,
-0x00048f05,0x0000f440,0x00007401,0x0000f7c0,
-0x00000734,0x00001000,0x00010705,0x000a6880,
-0x00006a88,0x000c75c4,0x00000000,0x000e5084,
-0x00000000,0x000eba44,0x00087401,0x000e4782,
-0x00000734,0x00001000,0x00010705,0x000a6880,
-0x00006a88,0x000c75c4,0x0007c108,0x000c0000,
-0x0007e721,0x000bed40,0x00005f25,0x000badc0,
-0x0003ba97,0x000beb80,0x00065590,0x000b2e00,
-0x00033217,0x00003ec0,0x00065590,0x000b8e40,
-0x0003ed80,0x000491c0,0x00073fb0,0x00074c80,
-0x000283a0,0x0000100c,0x000ee388,0x00042970,
-0x00008301,0x00021ef2,0x000b8f14,0x0000000f,
-0x000c4d8d,0x0000001b,0x000d6dc2,0x000e06c6,
-0x000032ac,0x000c3916,0x0004edc2,0x00074c80,
-0x00078898,0x00001000,0x00038894,0x00000032,
-0x000c4d8d,0x00092e1b,0x000d6dc2,0x000e06c6,
-0x0004edc2,0x000c1956,0x0000722c,0x00034a00,
-0x00041705,0x0009ed40,0x00058730,0x00001400,
-0x000d7488,0x000c3a00,0x00048f05,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000}
- };
diff --git a/ANDROID_3.4.5/sound/pci/cs46xx/cs46xx_lib.c b/ANDROID_3.4.5/sound/pci/cs46xx/cs46xx_lib.c
deleted file mode 100644
index 4fa53161..00000000
--- a/ANDROID_3.4.5/sound/pci/cs46xx/cs46xx_lib.c
+++ /dev/null
@@ -1,3882 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Abramo Bagnara <abramo@alsa-project.org>
- * Cirrus Logic, Inc.
- * Routines for control of Cirrus Logic CS461x chips
- *
- * KNOWN BUGS:
- * - Sometimes the SPDIF input DSP tasks get's unsynchronized
- * and the SPDIF get somewhat "distorcionated", or/and left right channel
- * are swapped. To get around this problem when it happens, mute and unmute
- * the SPDIF input mixer control.
- * - On the Hercules Game Theater XP the amplifier are sometimes turned
- * off on inadecuate moments which causes distorcions on sound.
- *
- * TODO:
- * - Secondary CODEC on some soundcards
- * - SPDIF input support for other sample rates then 48khz
- * - Posibility to mix the SPDIF output with analog sources.
- * - PCM channels for Center and LFE on secondary codec
- *
- * NOTE: with CONFIG_SND_CS46XX_NEW_DSP unset uses old DSP image (which
- * is default configuration), no SPDIF, no secondary codec, no
- * multi channel PCM. But known to work.
- *
- * FINALLY: A credit to the developers Tom and Jordan
- * at Cirrus for have helping me out with the DSP, however we
- * still don't have sufficient documentation and technical
- * references to be able to implement all fancy feutures
- * supported by the cs46xx DSP's.
- * Benny <benny@hostmobility.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <linux/pm.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/gameport.h>
-#include <linux/mutex.h>
-#include <linux/export.h>
-
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/info.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/cs46xx.h>
-
-#include <asm/io.h>
-
-#include "cs46xx_lib.h"
-#include "dsp_spos.h"
-
-static void amp_voyetra(struct snd_cs46xx *chip, int change);
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
-static struct snd_pcm_ops snd_cs46xx_playback_rear_ops;
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops;
-static struct snd_pcm_ops snd_cs46xx_playback_clfe_ops;
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops;
-static struct snd_pcm_ops snd_cs46xx_playback_iec958_ops;
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops;
-#endif
-
-static struct snd_pcm_ops snd_cs46xx_playback_ops;
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_ops;
-static struct snd_pcm_ops snd_cs46xx_capture_ops;
-static struct snd_pcm_ops snd_cs46xx_capture_indirect_ops;
-
-static unsigned short snd_cs46xx_codec_read(struct snd_cs46xx *chip,
- unsigned short reg,
- int codec_index)
-{
- int count;
- unsigned short result,tmp;
- u32 offset = 0;
-
- if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
- codec_index != CS46XX_SECONDARY_CODEC_INDEX))
- return -EINVAL;
-
- chip->active_ctrl(chip, 1);
-
- if (codec_index == CS46XX_SECONDARY_CODEC_INDEX)
- offset = CS46XX_SECONDARY_CODEC_OFFSET;
-
- /*
- * 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
- * 2. Write ACCDA = Command Data Register = 470h for data to write to AC97
- * 3. Write ACCTL = Control Register = 460h for initiating the write7---55
- * 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 17h
- * 5. if DCV not cleared, break and return error
- * 6. Read ACSTS = Status Register = 464h, check VSTS bit
- */
-
- snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset);
-
- tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL);
- if ((tmp & ACCTL_VFRM) == 0) {
- snd_printk(KERN_WARNING "cs46xx: ACCTL_VFRM not set 0x%x\n",tmp);
- snd_cs46xx_pokeBA0(chip, BA0_ACCTL, (tmp & (~ACCTL_ESYN)) | ACCTL_VFRM );
- msleep(50);
- tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL + offset);
- snd_cs46xx_pokeBA0(chip, BA0_ACCTL, tmp | ACCTL_ESYN | ACCTL_VFRM );
-
- }
-
- /*
- * Setup the AC97 control registers on the CS461x to send the
- * appropriate command to the AC97 to perform the read.
- * ACCAD = Command Address Register = 46Ch
- * ACCDA = Command Data Register = 470h
- * ACCTL = Control Register = 460h
- * set DCV - will clear when process completed
- * set CRW - Read command
- * set VFRM - valid frame enabled
- * set ESYN - ASYNC generation enabled
- * set RSTN - ARST# inactive, AC97 codec not reset
- */
-
- snd_cs46xx_pokeBA0(chip, BA0_ACCAD, reg);
- snd_cs46xx_pokeBA0(chip, BA0_ACCDA, 0);
- if (codec_index == CS46XX_PRIMARY_CODEC_INDEX) {
- snd_cs46xx_pokeBA0(chip, BA0_ACCTL,/* clear ACCTL_DCV */ ACCTL_CRW |
- ACCTL_VFRM | ACCTL_ESYN |
- ACCTL_RSTN);
- snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_CRW |
- ACCTL_VFRM | ACCTL_ESYN |
- ACCTL_RSTN);
- } else {
- snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_TC |
- ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN |
- ACCTL_RSTN);
- }
-
- /*
- * Wait for the read to occur.
- */
- for (count = 0; count < 1000; count++) {
- /*
- * First, we want to wait for a short time.
- */
- udelay(10);
- /*
- * Now, check to see if the read has completed.
- * ACCTL = 460h, DCV should be reset by now and 460h = 17h
- */
- if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV))
- goto ok1;
- }
-
- snd_printk(KERN_ERR "AC'97 read problem (ACCTL_DCV), reg = 0x%x\n", reg);
- result = 0xffff;
- goto end;
-
- ok1:
- /*
- * Wait for the valid status bit to go active.
- */
- for (count = 0; count < 100; count++) {
- /*
- * Read the AC97 status register.
- * ACSTS = Status Register = 464h
- * VSTS - Valid Status
- */
- if (snd_cs46xx_peekBA0(chip, BA0_ACSTS + offset) & ACSTS_VSTS)
- goto ok2;
- udelay(10);
- }
-
- snd_printk(KERN_ERR "AC'97 read problem (ACSTS_VSTS), codec_index %d, reg = 0x%x\n", codec_index, reg);
- result = 0xffff;
- goto end;
-
- ok2:
- /*
- * Read the data returned from the AC97 register.
- * ACSDA = Status Data Register = 474h
- */
-#if 0
- printk(KERN_DEBUG "e) reg = 0x%x, val = 0x%x, BA0_ACCAD = 0x%x\n", reg,
- snd_cs46xx_peekBA0(chip, BA0_ACSDA),
- snd_cs46xx_peekBA0(chip, BA0_ACCAD));
-#endif
-
- //snd_cs46xx_peekBA0(chip, BA0_ACCAD);
- result = snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset);
- end:
- chip->active_ctrl(chip, -1);
- return result;
-}
-
-static unsigned short snd_cs46xx_ac97_read(struct snd_ac97 * ac97,
- unsigned short reg)
-{
- struct snd_cs46xx *chip = ac97->private_data;
- unsigned short val;
- int codec_index = ac97->num;
-
- if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
- codec_index != CS46XX_SECONDARY_CODEC_INDEX))
- return 0xffff;
-
- val = snd_cs46xx_codec_read(chip, reg, codec_index);
-
- return val;
-}
-
-
-static void snd_cs46xx_codec_write(struct snd_cs46xx *chip,
- unsigned short reg,
- unsigned short val,
- int codec_index)
-{
- int count;
-
- if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
- codec_index != CS46XX_SECONDARY_CODEC_INDEX))
- return;
-
- chip->active_ctrl(chip, 1);
-
- /*
- * 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
- * 2. Write ACCDA = Command Data Register = 470h for data to write to AC97
- * 3. Write ACCTL = Control Register = 460h for initiating the write
- * 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 07h
- * 5. if DCV not cleared, break and return error
- */
-
- /*
- * Setup the AC97 control registers on the CS461x to send the
- * appropriate command to the AC97 to perform the read.
- * ACCAD = Command Address Register = 46Ch
- * ACCDA = Command Data Register = 470h
- * ACCTL = Control Register = 460h
- * set DCV - will clear when process completed
- * reset CRW - Write command
- * set VFRM - valid frame enabled
- * set ESYN - ASYNC generation enabled
- * set RSTN - ARST# inactive, AC97 codec not reset
- */
- snd_cs46xx_pokeBA0(chip, BA0_ACCAD , reg);
- snd_cs46xx_pokeBA0(chip, BA0_ACCDA , val);
- snd_cs46xx_peekBA0(chip, BA0_ACCTL);
-
- if (codec_index == CS46XX_PRIMARY_CODEC_INDEX) {
- snd_cs46xx_pokeBA0(chip, BA0_ACCTL, /* clear ACCTL_DCV */ ACCTL_VFRM |
- ACCTL_ESYN | ACCTL_RSTN);
- snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_VFRM |
- ACCTL_ESYN | ACCTL_RSTN);
- } else {
- snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_TC |
- ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
- }
-
- for (count = 0; count < 4000; count++) {
- /*
- * First, we want to wait for a short time.
- */
- udelay(10);
- /*
- * Now, check to see if the write has completed.
- * ACCTL = 460h, DCV should be reset by now and 460h = 07h
- */
- if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV)) {
- goto end;
- }
- }
- snd_printk(KERN_ERR "AC'97 write problem, codec_index = %d, reg = 0x%x, val = 0x%x\n", codec_index, reg, val);
- end:
- chip->active_ctrl(chip, -1);
-}
-
-static void snd_cs46xx_ac97_write(struct snd_ac97 *ac97,
- unsigned short reg,
- unsigned short val)
-{
- struct snd_cs46xx *chip = ac97->private_data;
- int codec_index = ac97->num;
-
- if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
- codec_index != CS46XX_SECONDARY_CODEC_INDEX))
- return;
-
- snd_cs46xx_codec_write(chip, reg, val, codec_index);
-}
-
-
-/*
- * Chip initialization
- */
-
-int snd_cs46xx_download(struct snd_cs46xx *chip,
- u32 *src,
- unsigned long offset,
- unsigned long len)
-{
- void __iomem *dst;
- unsigned int bank = offset >> 16;
- offset = offset & 0xffff;
-
- if (snd_BUG_ON((offset & 3) || (len & 3)))
- return -EINVAL;
- dst = chip->region.idx[bank+1].remap_addr + offset;
- len /= sizeof(u32);
-
- /* writel already converts 32-bit value to right endianess */
- while (len-- > 0) {
- writel(*src++, dst);
- dst += sizeof(u32);
- }
- return 0;
-}
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
-
-#include "imgs/cwc4630.h"
-#include "imgs/cwcasync.h"
-#include "imgs/cwcsnoop.h"
-#include "imgs/cwcbinhack.h"
-#include "imgs/cwcdma.h"
-
-int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip,
- unsigned long offset,
- unsigned long len)
-{
- void __iomem *dst;
- unsigned int bank = offset >> 16;
- offset = offset & 0xffff;
-
- if (snd_BUG_ON((offset & 3) || (len & 3)))
- return -EINVAL;
- dst = chip->region.idx[bank+1].remap_addr + offset;
- len /= sizeof(u32);
-
- /* writel already converts 32-bit value to right endianess */
- while (len-- > 0) {
- writel(0, dst);
- dst += sizeof(u32);
- }
- return 0;
-}
-
-#else /* old DSP image */
-
-#include "cs46xx_image.h"
-
-int snd_cs46xx_download_image(struct snd_cs46xx *chip)
-{
- int idx, err;
- unsigned long offset = 0;
-
- for (idx = 0; idx < BA1_MEMORY_COUNT; idx++) {
- if ((err = snd_cs46xx_download(chip,
- &BA1Struct.map[offset],
- BA1Struct.memory[idx].offset,
- BA1Struct.memory[idx].size)) < 0)
- return err;
- offset += BA1Struct.memory[idx].size >> 2;
- }
- return 0;
-}
-#endif /* CONFIG_SND_CS46XX_NEW_DSP */
-
-/*
- * Chip reset
- */
-
-static void snd_cs46xx_reset(struct snd_cs46xx *chip)
-{
- int idx;
-
- /*
- * Write the reset bit of the SP control register.
- */
- snd_cs46xx_poke(chip, BA1_SPCR, SPCR_RSTSP);
-
- /*
- * Write the control register.
- */
- snd_cs46xx_poke(chip, BA1_SPCR, SPCR_DRQEN);
-
- /*
- * Clear the trap registers.
- */
- for (idx = 0; idx < 8; idx++) {
- snd_cs46xx_poke(chip, BA1_DREG, DREG_REGID_TRAP_SELECT + idx);
- snd_cs46xx_poke(chip, BA1_TWPR, 0xFFFF);
- }
- snd_cs46xx_poke(chip, BA1_DREG, 0);
-
- /*
- * Set the frame timer to reflect the number of cycles per frame.
- */
- snd_cs46xx_poke(chip, BA1_FRMT, 0xadf);
-}
-
-static int cs46xx_wait_for_fifo(struct snd_cs46xx * chip,int retry_timeout)
-{
- u32 i, status = 0;
- /*
- * Make sure the previous FIFO write operation has completed.
- */
- for(i = 0; i < 50; i++){
- status = snd_cs46xx_peekBA0(chip, BA0_SERBST);
-
- if( !(status & SERBST_WBSY) )
- break;
-
- mdelay(retry_timeout);
- }
-
- if(status & SERBST_WBSY) {
- snd_printk(KERN_ERR "cs46xx: failure waiting for "
- "FIFO command to complete\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void snd_cs46xx_clear_serial_FIFOs(struct snd_cs46xx *chip)
-{
- int idx, powerdown = 0;
- unsigned int tmp;
-
- /*
- * See if the devices are powered down. If so, we must power them up first
- * or they will not respond.
- */
- tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1);
- if (!(tmp & CLKCR1_SWCE)) {
- snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE);
- powerdown = 1;
- }
-
- /*
- * We want to clear out the serial port FIFOs so we don't end up playing
- * whatever random garbage happens to be in them. We fill the sample FIFOS
- * with zero (silence).
- */
- snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0);
-
- /*
- * Fill all 256 sample FIFO locations.
- */
- for (idx = 0; idx < 0xFF; idx++) {
- /*
- * Make sure the previous FIFO write operation has completed.
- */
- if (cs46xx_wait_for_fifo(chip,1)) {
- snd_printdd ("failed waiting for FIFO at addr (%02X)\n",idx);
-
- if (powerdown)
- snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
-
- break;
- }
- /*
- * Write the serial port FIFO index.
- */
- snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx);
- /*
- * Tell the serial port to load the new value into the FIFO location.
- */
- snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC);
- }
- /*
- * Now, if we powered up the devices, then power them back down again.
- * This is kinda ugly, but should never happen.
- */
- if (powerdown)
- snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
-}
-
-static void snd_cs46xx_proc_start(struct snd_cs46xx *chip)
-{
- int cnt;
-
- /*
- * Set the frame timer to reflect the number of cycles per frame.
- */
- snd_cs46xx_poke(chip, BA1_FRMT, 0xadf);
- /*
- * Turn on the run, run at frame, and DMA enable bits in the local copy of
- * the SP control register.
- */
- snd_cs46xx_poke(chip, BA1_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN);
- /*
- * Wait until the run at frame bit resets itself in the SP control
- * register.
- */
- for (cnt = 0; cnt < 25; cnt++) {
- udelay(50);
- if (!(snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR))
- break;
- }
-
- if (snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR)
- snd_printk(KERN_ERR "SPCR_RUNFR never reset\n");
-}
-
-static void snd_cs46xx_proc_stop(struct snd_cs46xx *chip)
-{
- /*
- * Turn off the run, run at frame, and DMA enable bits in the local copy of
- * the SP control register.
- */
- snd_cs46xx_poke(chip, BA1_SPCR, 0);
-}
-
-/*
- * Sample rate routines
- */
-
-#define GOF_PER_SEC 200
-
-static void snd_cs46xx_set_play_sample_rate(struct snd_cs46xx *chip, unsigned int rate)
-{
- unsigned long flags;
- unsigned int tmp1, tmp2;
- unsigned int phiIncr;
- unsigned int correctionPerGOF, correctionPerSec;
-
- /*
- * Compute the values used to drive the actual sample rate conversion.
- * The following formulas are being computed, using inline assembly
- * since we need to use 64 bit arithmetic to compute the values:
- *
- * phiIncr = floor((Fs,in * 2^26) / Fs,out)
- * correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) /
- * GOF_PER_SEC)
- * ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -M
- * GOF_PER_SEC * correctionPerGOF
- *
- * i.e.
- *
- * phiIncr:other = dividend:remainder((Fs,in * 2^26) / Fs,out)
- * correctionPerGOF:correctionPerSec =
- * dividend:remainder(ulOther / GOF_PER_SEC)
- */
- tmp1 = rate << 16;
- phiIncr = tmp1 / 48000;
- tmp1 -= phiIncr * 48000;
- tmp1 <<= 10;
- phiIncr <<= 10;
- tmp2 = tmp1 / 48000;
- phiIncr += tmp2;
- tmp1 -= tmp2 * 48000;
- correctionPerGOF = tmp1 / GOF_PER_SEC;
- tmp1 -= correctionPerGOF * GOF_PER_SEC;
- correctionPerSec = tmp1;
-
- /*
- * Fill in the SampleRateConverter control block.
- */
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_cs46xx_poke(chip, BA1_PSRC,
- ((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
- snd_cs46xx_poke(chip, BA1_PPI, phiIncr);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-
-static void snd_cs46xx_set_capture_sample_rate(struct snd_cs46xx *chip, unsigned int rate)
-{
- unsigned long flags;
- unsigned int phiIncr, coeffIncr, tmp1, tmp2;
- unsigned int correctionPerGOF, correctionPerSec, initialDelay;
- unsigned int frameGroupLength, cnt;
-
- /*
- * We can only decimate by up to a factor of 1/9th the hardware rate.
- * Correct the value if an attempt is made to stray outside that limit.
- */
- if ((rate * 9) < 48000)
- rate = 48000 / 9;
-
- /*
- * We can not capture at at rate greater than the Input Rate (48000).
- * Return an error if an attempt is made to stray outside that limit.
- */
- if (rate > 48000)
- rate = 48000;
-
- /*
- * Compute the values used to drive the actual sample rate conversion.
- * The following formulas are being computed, using inline assembly
- * since we need to use 64 bit arithmetic to compute the values:
- *
- * coeffIncr = -floor((Fs,out * 2^23) / Fs,in)
- * phiIncr = floor((Fs,in * 2^26) / Fs,out)
- * correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) /
- * GOF_PER_SEC)
- * correctionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -
- * GOF_PER_SEC * correctionPerGOF
- * initialDelay = ceil((24 * Fs,in) / Fs,out)
- *
- * i.e.
- *
- * coeffIncr = neg(dividend((Fs,out * 2^23) / Fs,in))
- * phiIncr:ulOther = dividend:remainder((Fs,in * 2^26) / Fs,out)
- * correctionPerGOF:correctionPerSec =
- * dividend:remainder(ulOther / GOF_PER_SEC)
- * initialDelay = dividend(((24 * Fs,in) + Fs,out - 1) / Fs,out)
- */
-
- tmp1 = rate << 16;
- coeffIncr = tmp1 / 48000;
- tmp1 -= coeffIncr * 48000;
- tmp1 <<= 7;
- coeffIncr <<= 7;
- coeffIncr += tmp1 / 48000;
- coeffIncr ^= 0xFFFFFFFF;
- coeffIncr++;
- tmp1 = 48000 << 16;
- phiIncr = tmp1 / rate;
- tmp1 -= phiIncr * rate;
- tmp1 <<= 10;
- phiIncr <<= 10;
- tmp2 = tmp1 / rate;
- phiIncr += tmp2;
- tmp1 -= tmp2 * rate;
- correctionPerGOF = tmp1 / GOF_PER_SEC;
- tmp1 -= correctionPerGOF * GOF_PER_SEC;
- correctionPerSec = tmp1;
- initialDelay = ((48000 * 24) + rate - 1) / rate;
-
- /*
- * Fill in the VariDecimate control block.
- */
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_cs46xx_poke(chip, BA1_CSRC,
- ((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
- snd_cs46xx_poke(chip, BA1_CCI, coeffIncr);
- snd_cs46xx_poke(chip, BA1_CD,
- (((BA1_VARIDEC_BUF_1 + (initialDelay << 2)) << 16) & 0xFFFF0000) | 0x80);
- snd_cs46xx_poke(chip, BA1_CPI, phiIncr);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- /*
- * Figure out the frame group length for the write back task. Basically,
- * this is just the factors of 24000 (2^6*3*5^3) that are not present in
- * the output sample rate.
- */
- frameGroupLength = 1;
- for (cnt = 2; cnt <= 64; cnt *= 2) {
- if (((rate / cnt) * cnt) != rate)
- frameGroupLength *= 2;
- }
- if (((rate / 3) * 3) != rate) {
- frameGroupLength *= 3;
- }
- for (cnt = 5; cnt <= 125; cnt *= 5) {
- if (((rate / cnt) * cnt) != rate)
- frameGroupLength *= 5;
- }
-
- /*
- * Fill in the WriteBack control block.
- */
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_cs46xx_poke(chip, BA1_CFG1, frameGroupLength);
- snd_cs46xx_poke(chip, BA1_CFG2, (0x00800000 | frameGroupLength));
- snd_cs46xx_poke(chip, BA1_CCST, 0x0000FFFF);
- snd_cs46xx_poke(chip, BA1_CSPB, ((65536 * rate) / 24000));
- snd_cs46xx_poke(chip, (BA1_CSPB + 4), 0x0000FFFF);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-
-/*
- * PCM part
- */
-
-static void snd_cs46xx_pb_trans_copy(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect *rec, size_t bytes)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_cs46xx_pcm * cpcm = runtime->private_data;
- memcpy(cpcm->hw_buf.area + rec->hw_data, runtime->dma_area + rec->sw_data, bytes);
-}
-
-static int snd_cs46xx_playback_transfer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_cs46xx_pcm * cpcm = runtime->private_data;
- snd_pcm_indirect_playback_transfer(substream, &cpcm->pcm_rec, snd_cs46xx_pb_trans_copy);
- return 0;
-}
-
-static void snd_cs46xx_cp_trans_copy(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect *rec, size_t bytes)
-{
- struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- memcpy(runtime->dma_area + rec->sw_data,
- chip->capt.hw_buf.area + rec->hw_data, bytes);
-}
-
-static int snd_cs46xx_capture_transfer(struct snd_pcm_substream *substream)
-{
- struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
- snd_pcm_indirect_capture_transfer(substream, &chip->capt.pcm_rec, snd_cs46xx_cp_trans_copy);
- return 0;
-}
-
-static snd_pcm_uframes_t snd_cs46xx_playback_direct_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
- size_t ptr;
- struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data;
-
- if (snd_BUG_ON(!cpcm->pcm_channel))
- return -ENXIO;
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2);
-#else
- ptr = snd_cs46xx_peek(chip, BA1_PBA);
-#endif
- ptr -= cpcm->hw_buf.addr;
- return ptr >> cpcm->shift;
-}
-
-static snd_pcm_uframes_t snd_cs46xx_playback_indirect_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
- size_t ptr;
- struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data;
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- if (snd_BUG_ON(!cpcm->pcm_channel))
- return -ENXIO;
- ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2);
-#else
- ptr = snd_cs46xx_peek(chip, BA1_PBA);
-#endif
- ptr -= cpcm->hw_buf.addr;
- return snd_pcm_indirect_playback_pointer(substream, &cpcm->pcm_rec, ptr);
-}
-
-static snd_pcm_uframes_t snd_cs46xx_capture_direct_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
- size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr;
- return ptr >> chip->capt.shift;
-}
-
-static snd_pcm_uframes_t snd_cs46xx_capture_indirect_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
- size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr;
- return snd_pcm_indirect_capture_pointer(substream, &chip->capt.pcm_rec, ptr);
-}
-
-static int snd_cs46xx_playback_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
- /*struct snd_pcm_runtime *runtime = substream->runtime;*/
- int result = 0;
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data;
- if (! cpcm->pcm_channel) {
- return -ENXIO;
- }
-#endif
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- /* magic value to unmute PCM stream playback volume */
- snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address +
- SCBVolumeCtrl) << 2, 0x80008000);
-
- if (cpcm->pcm_channel->unlinked)
- cs46xx_dsp_pcm_link(chip,cpcm->pcm_channel);
-
- if (substream->runtime->periods != CS46XX_FRAGS)
- snd_cs46xx_playback_transfer(substream);
-#else
- spin_lock(&chip->reg_lock);
- if (substream->runtime->periods != CS46XX_FRAGS)
- snd_cs46xx_playback_transfer(substream);
- { unsigned int tmp;
- tmp = snd_cs46xx_peek(chip, BA1_PCTL);
- tmp &= 0x0000ffff;
- snd_cs46xx_poke(chip, BA1_PCTL, chip->play_ctl | tmp);
- }
- spin_unlock(&chip->reg_lock);
-#endif
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- /* magic mute channel */
- snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address +
- SCBVolumeCtrl) << 2, 0xffffffff);
-
- if (!cpcm->pcm_channel->unlinked)
- cs46xx_dsp_pcm_unlink(chip,cpcm->pcm_channel);
-#else
- spin_lock(&chip->reg_lock);
- { unsigned int tmp;
- tmp = snd_cs46xx_peek(chip, BA1_PCTL);
- tmp &= 0x0000ffff;
- snd_cs46xx_poke(chip, BA1_PCTL, tmp);
- }
- spin_unlock(&chip->reg_lock);
-#endif
- break;
- default:
- result = -EINVAL;
- break;
- }
-
- return result;
-}
-
-static int snd_cs46xx_capture_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
- unsigned int tmp;
- int result = 0;
-
- spin_lock(&chip->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- tmp = snd_cs46xx_peek(chip, BA1_CCTL);
- tmp &= 0xffff0000;
- snd_cs46xx_poke(chip, BA1_CCTL, chip->capt.ctl | tmp);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- tmp = snd_cs46xx_peek(chip, BA1_CCTL);
- tmp &= 0xffff0000;
- snd_cs46xx_poke(chip, BA1_CCTL, tmp);
- break;
- default:
- result = -EINVAL;
- break;
- }
- spin_unlock(&chip->reg_lock);
-
- return result;
-}
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
-static int _cs46xx_adjust_sample_rate (struct snd_cs46xx *chip, struct snd_cs46xx_pcm *cpcm,
- int sample_rate)
-{
-
- /* If PCMReaderSCB and SrcTaskSCB not created yet ... */
- if ( cpcm->pcm_channel == NULL) {
- cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, sample_rate,
- cpcm, cpcm->hw_buf.addr,cpcm->pcm_channel_id);
- if (cpcm->pcm_channel == NULL) {
- snd_printk(KERN_ERR "cs46xx: failed to create virtual PCM channel\n");
- return -ENOMEM;
- }
- cpcm->pcm_channel->sample_rate = sample_rate;
- } else
- /* if sample rate is changed */
- if ((int)cpcm->pcm_channel->sample_rate != sample_rate) {
- int unlinked = cpcm->pcm_channel->unlinked;
- cs46xx_dsp_destroy_pcm_channel (chip,cpcm->pcm_channel);
-
- if ( (cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, sample_rate, cpcm,
- cpcm->hw_buf.addr,
- cpcm->pcm_channel_id)) == NULL) {
- snd_printk(KERN_ERR "cs46xx: failed to re-create virtual PCM channel\n");
- return -ENOMEM;
- }
-
- if (!unlinked) cs46xx_dsp_pcm_link (chip,cpcm->pcm_channel);
- cpcm->pcm_channel->sample_rate = sample_rate;
- }
-
- return 0;
-}
-#endif
-
-
-static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_cs46xx_pcm *cpcm;
- int err;
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
- int sample_rate = params_rate(hw_params);
- int period_size = params_period_bytes(hw_params);
-#endif
- cpcm = runtime->private_data;
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- if (snd_BUG_ON(!sample_rate))
- return -ENXIO;
-
- mutex_lock(&chip->spos_mutex);
-
- if (_cs46xx_adjust_sample_rate (chip,cpcm,sample_rate)) {
- mutex_unlock(&chip->spos_mutex);
- return -ENXIO;
- }
-
- snd_BUG_ON(!cpcm->pcm_channel);
- if (!cpcm->pcm_channel) {
- mutex_unlock(&chip->spos_mutex);
- return -ENXIO;
- }
-
-
- if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size)) {
- mutex_unlock(&chip->spos_mutex);
- return -EINVAL;
- }
-
- snd_printdd ("period_size (%d), periods (%d) buffer_size(%d)\n",
- period_size, params_periods(hw_params),
- params_buffer_bytes(hw_params));
-#endif
-
- if (params_periods(hw_params) == CS46XX_FRAGS) {
- if (runtime->dma_area != cpcm->hw_buf.area)
- snd_pcm_lib_free_pages(substream);
- runtime->dma_area = cpcm->hw_buf.area;
- runtime->dma_addr = cpcm->hw_buf.addr;
- runtime->dma_bytes = cpcm->hw_buf.bytes;
-
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) {
- substream->ops = &snd_cs46xx_playback_ops;
- } else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) {
- substream->ops = &snd_cs46xx_playback_rear_ops;
- } else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) {
- substream->ops = &snd_cs46xx_playback_clfe_ops;
- } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) {
- substream->ops = &snd_cs46xx_playback_iec958_ops;
- } else {
- snd_BUG();
- }
-#else
- substream->ops = &snd_cs46xx_playback_ops;
-#endif
-
- } else {
- if (runtime->dma_area == cpcm->hw_buf.area) {
- runtime->dma_area = NULL;
- runtime->dma_addr = 0;
- runtime->dma_bytes = 0;
- }
- if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) {
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- mutex_unlock(&chip->spos_mutex);
-#endif
- return err;
- }
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) {
- substream->ops = &snd_cs46xx_playback_indirect_ops;
- } else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) {
- substream->ops = &snd_cs46xx_playback_indirect_rear_ops;
- } else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) {
- substream->ops = &snd_cs46xx_playback_indirect_clfe_ops;
- } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) {
- substream->ops = &snd_cs46xx_playback_indirect_iec958_ops;
- } else {
- snd_BUG();
- }
-#else
- substream->ops = &snd_cs46xx_playback_indirect_ops;
-#endif
-
- }
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- mutex_unlock(&chip->spos_mutex);
-#endif
-
- return 0;
-}
-
-static int snd_cs46xx_playback_hw_free(struct snd_pcm_substream *substream)
-{
- /*struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);*/
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_cs46xx_pcm *cpcm;
-
- cpcm = runtime->private_data;
-
- /* if play_back open fails, then this function
- is called and cpcm can actually be NULL here */
- if (!cpcm) return -ENXIO;
-
- if (runtime->dma_area != cpcm->hw_buf.area)
- snd_pcm_lib_free_pages(substream);
-
- runtime->dma_area = NULL;
- runtime->dma_addr = 0;
- runtime->dma_bytes = 0;
-
- return 0;
-}
-
-static int snd_cs46xx_playback_prepare(struct snd_pcm_substream *substream)
-{
- unsigned int tmp;
- unsigned int pfie;
- struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_cs46xx_pcm *cpcm;
-
- cpcm = runtime->private_data;
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- if (snd_BUG_ON(!cpcm->pcm_channel))
- return -ENXIO;
-
- pfie = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2 );
- pfie &= ~0x0000f03f;
-#else
- /* old dsp */
- pfie = snd_cs46xx_peek(chip, BA1_PFIE);
- pfie &= ~0x0000f03f;
-#endif
-
- cpcm->shift = 2;
- /* if to convert from stereo to mono */
- if (runtime->channels == 1) {
- cpcm->shift--;
- pfie |= 0x00002000;
- }
- /* if to convert from 8 bit to 16 bit */
- if (snd_pcm_format_width(runtime->format) == 8) {
- cpcm->shift--;
- pfie |= 0x00001000;
- }
- /* if to convert to unsigned */
- if (snd_pcm_format_unsigned(runtime->format))
- pfie |= 0x00008000;
-
- /* Never convert byte order when sample stream is 8 bit */
- if (snd_pcm_format_width(runtime->format) != 8) {
- /* convert from big endian to little endian */
- if (snd_pcm_format_big_endian(runtime->format))
- pfie |= 0x00004000;
- }
-
- memset(&cpcm->pcm_rec, 0, sizeof(cpcm->pcm_rec));
- cpcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
- cpcm->pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << cpcm->shift;
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
-
- tmp = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2);
- tmp &= ~0x000003ff;
- tmp |= (4 << cpcm->shift) - 1;
- /* playback transaction count register */
- snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2, tmp);
-
- /* playback format && interrupt enable */
- snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2, pfie | cpcm->pcm_channel->pcm_slot);
-#else
- snd_cs46xx_poke(chip, BA1_PBA, cpcm->hw_buf.addr);
- tmp = snd_cs46xx_peek(chip, BA1_PDTC);
- tmp &= ~0x000003ff;
- tmp |= (4 << cpcm->shift) - 1;
- snd_cs46xx_poke(chip, BA1_PDTC, tmp);
- snd_cs46xx_poke(chip, BA1_PFIE, pfie);
- snd_cs46xx_set_play_sample_rate(chip, runtime->rate);
-#endif
-
- return 0;
-}
-
-static int snd_cs46xx_capture_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- cs46xx_dsp_pcm_ostream_set_period (chip, params_period_bytes(hw_params));
-#endif
- if (runtime->periods == CS46XX_FRAGS) {
- if (runtime->dma_area != chip->capt.hw_buf.area)
- snd_pcm_lib_free_pages(substream);
- runtime->dma_area = chip->capt.hw_buf.area;
- runtime->dma_addr = chip->capt.hw_buf.addr;
- runtime->dma_bytes = chip->capt.hw_buf.bytes;
- substream->ops = &snd_cs46xx_capture_ops;
- } else {
- if (runtime->dma_area == chip->capt.hw_buf.area) {
- runtime->dma_area = NULL;
- runtime->dma_addr = 0;
- runtime->dma_bytes = 0;
- }
- if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
- return err;
- substream->ops = &snd_cs46xx_capture_indirect_ops;
- }
-
- return 0;
-}
-
-static int snd_cs46xx_capture_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- if (runtime->dma_area != chip->capt.hw_buf.area)
- snd_pcm_lib_free_pages(substream);
- runtime->dma_area = NULL;
- runtime->dma_addr = 0;
- runtime->dma_bytes = 0;
-
- return 0;
-}
-
-static int snd_cs46xx_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- snd_cs46xx_poke(chip, BA1_CBA, chip->capt.hw_buf.addr);
- chip->capt.shift = 2;
- memset(&chip->capt.pcm_rec, 0, sizeof(chip->capt.pcm_rec));
- chip->capt.pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
- chip->capt.pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << 2;
- snd_cs46xx_set_capture_sample_rate(chip, runtime->rate);
-
- return 0;
-}
-
-static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id)
-{
- struct snd_cs46xx *chip = dev_id;
- u32 status1;
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- u32 status2;
- int i;
- struct snd_cs46xx_pcm *cpcm = NULL;
-#endif
-
- /*
- * Read the Interrupt Status Register to clear the interrupt
- */
- status1 = snd_cs46xx_peekBA0(chip, BA0_HISR);
- if ((status1 & 0x7fffffff) == 0) {
- snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_CHGM | HICR_IEV);
- return IRQ_NONE;
- }
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- status2 = snd_cs46xx_peekBA0(chip, BA0_HSR0);
-
- for (i = 0; i < DSP_MAX_PCM_CHANNELS; ++i) {
- if (i <= 15) {
- if ( status1 & (1 << i) ) {
- if (i == CS46XX_DSP_CAPTURE_CHANNEL) {
- if (chip->capt.substream)
- snd_pcm_period_elapsed(chip->capt.substream);
- } else {
- if (ins->pcm_channels[i].active &&
- ins->pcm_channels[i].private_data &&
- !ins->pcm_channels[i].unlinked) {
- cpcm = ins->pcm_channels[i].private_data;
- snd_pcm_period_elapsed(cpcm->substream);
- }
- }
- }
- } else {
- if ( status2 & (1 << (i - 16))) {
- if (ins->pcm_channels[i].active &&
- ins->pcm_channels[i].private_data &&
- !ins->pcm_channels[i].unlinked) {
- cpcm = ins->pcm_channels[i].private_data;
- snd_pcm_period_elapsed(cpcm->substream);
- }
- }
- }
- }
-
-#else
- /* old dsp */
- if ((status1 & HISR_VC0) && chip->playback_pcm) {
- if (chip->playback_pcm->substream)
- snd_pcm_period_elapsed(chip->playback_pcm->substream);
- }
- if ((status1 & HISR_VC1) && chip->pcm) {
- if (chip->capt.substream)
- snd_pcm_period_elapsed(chip->capt.substream);
- }
-#endif
-
- if ((status1 & HISR_MIDI) && chip->rmidi) {
- unsigned char c;
-
- spin_lock(&chip->reg_lock);
- while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_RBE) == 0) {
- c = snd_cs46xx_peekBA0(chip, BA0_MIDRP);
- if ((chip->midcr & MIDCR_RIE) == 0)
- continue;
- snd_rawmidi_receive(chip->midi_input, &c, 1);
- }
- while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) {
- if ((chip->midcr & MIDCR_TIE) == 0)
- break;
- if (snd_rawmidi_transmit(chip->midi_output, &c, 1) != 1) {
- chip->midcr &= ~MIDCR_TIE;
- snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
- break;
- }
- snd_cs46xx_pokeBA0(chip, BA0_MIDWP, c);
- }
- spin_unlock(&chip->reg_lock);
- }
- /*
- * EOI to the PCI part....reenables interrupts
- */
- snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_CHGM | HICR_IEV);
-
- return IRQ_HANDLED;
-}
-
-static struct snd_pcm_hardware snd_cs46xx_playback =
-{
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER /*|*/
- /*SNDRV_PCM_INFO_RESUME*/),
- .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 5500,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (256 * 1024),
- .period_bytes_min = CS46XX_MIN_PERIOD_SIZE,
- .period_bytes_max = CS46XX_MAX_PERIOD_SIZE,
- .periods_min = CS46XX_FRAGS,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_cs46xx_capture =
-{
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER /*|*/
- /*SNDRV_PCM_INFO_RESUME*/),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 5500,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (256 * 1024),
- .period_bytes_min = CS46XX_MIN_PERIOD_SIZE,
- .period_bytes_max = CS46XX_MAX_PERIOD_SIZE,
- .periods_min = CS46XX_FRAGS,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
-
-static unsigned int period_sizes[] = { 32, 64, 128, 256, 512, 1024, 2048 };
-
-static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes = {
- .count = ARRAY_SIZE(period_sizes),
- .list = period_sizes,
- .mask = 0
-};
-
-#endif
-
-static void snd_cs46xx_pcm_free_substream(struct snd_pcm_runtime *runtime)
-{
- kfree(runtime->private_data);
-}
-
-static int _cs46xx_playback_open_channel (struct snd_pcm_substream *substream,int pcm_channel_id)
-{
- struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
- struct snd_cs46xx_pcm * cpcm;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- cpcm = kzalloc(sizeof(*cpcm), GFP_KERNEL);
- if (cpcm == NULL)
- return -ENOMEM;
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
- PAGE_SIZE, &cpcm->hw_buf) < 0) {
- kfree(cpcm);
- return -ENOMEM;
- }
-
- runtime->hw = snd_cs46xx_playback;
- runtime->private_data = cpcm;
- runtime->private_free = snd_cs46xx_pcm_free_substream;
-
- cpcm->substream = substream;
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- mutex_lock(&chip->spos_mutex);
- cpcm->pcm_channel = NULL;
- cpcm->pcm_channel_id = pcm_channel_id;
-
-
- snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- &hw_constraints_period_sizes);
-
- mutex_unlock(&chip->spos_mutex);
-#else
- chip->playback_pcm = cpcm; /* HACK */
-#endif
-
- if (chip->accept_valid)
- substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID;
- chip->active_ctrl(chip, 1);
-
- return 0;
-}
-
-static int snd_cs46xx_playback_open(struct snd_pcm_substream *substream)
-{
- snd_printdd("open front channel\n");
- return _cs46xx_playback_open_channel(substream,DSP_PCM_MAIN_CHANNEL);
-}
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
-static int snd_cs46xx_playback_open_rear(struct snd_pcm_substream *substream)
-{
- snd_printdd("open rear channel\n");
-
- return _cs46xx_playback_open_channel(substream,DSP_PCM_REAR_CHANNEL);
-}
-
-static int snd_cs46xx_playback_open_clfe(struct snd_pcm_substream *substream)
-{
- snd_printdd("open center - LFE channel\n");
-
- return _cs46xx_playback_open_channel(substream,DSP_PCM_CENTER_LFE_CHANNEL);
-}
-
-static int snd_cs46xx_playback_open_iec958(struct snd_pcm_substream *substream)
-{
- struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
-
- snd_printdd("open raw iec958 channel\n");
-
- mutex_lock(&chip->spos_mutex);
- cs46xx_iec958_pre_open (chip);
- mutex_unlock(&chip->spos_mutex);
-
- return _cs46xx_playback_open_channel(substream,DSP_IEC958_CHANNEL);
-}
-
-static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream);
-
-static int snd_cs46xx_playback_close_iec958(struct snd_pcm_substream *substream)
-{
- int err;
- struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
-
- snd_printdd("close raw iec958 channel\n");
-
- err = snd_cs46xx_playback_close(substream);
-
- mutex_lock(&chip->spos_mutex);
- cs46xx_iec958_post_close (chip);
- mutex_unlock(&chip->spos_mutex);
-
- return err;
-}
-#endif
-
-static int snd_cs46xx_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
-
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
- PAGE_SIZE, &chip->capt.hw_buf) < 0)
- return -ENOMEM;
- chip->capt.substream = substream;
- substream->runtime->hw = snd_cs46xx_capture;
-
- if (chip->accept_valid)
- substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID;
-
- chip->active_ctrl(chip, 1);
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- snd_pcm_hw_constraint_list(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- &hw_constraints_period_sizes);
-#endif
- return 0;
-}
-
-static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_cs46xx_pcm * cpcm;
-
- cpcm = runtime->private_data;
-
- /* when playback_open fails, then cpcm can be NULL */
- if (!cpcm) return -ENXIO;
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- mutex_lock(&chip->spos_mutex);
- if (cpcm->pcm_channel) {
- cs46xx_dsp_destroy_pcm_channel(chip,cpcm->pcm_channel);
- cpcm->pcm_channel = NULL;
- }
- mutex_unlock(&chip->spos_mutex);
-#else
- chip->playback_pcm = NULL;
-#endif
-
- cpcm->substream = NULL;
- snd_dma_free_pages(&cpcm->hw_buf);
- chip->active_ctrl(chip, -1);
-
- return 0;
-}
-
-static int snd_cs46xx_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
-
- chip->capt.substream = NULL;
- snd_dma_free_pages(&chip->capt.hw_buf);
- chip->active_ctrl(chip, -1);
-
- return 0;
-}
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
-static struct snd_pcm_ops snd_cs46xx_playback_rear_ops = {
- .open = snd_cs46xx_playback_open_rear,
- .close = snd_cs46xx_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cs46xx_playback_hw_params,
- .hw_free = snd_cs46xx_playback_hw_free,
- .prepare = snd_cs46xx_playback_prepare,
- .trigger = snd_cs46xx_playback_trigger,
- .pointer = snd_cs46xx_playback_direct_pointer,
-};
-
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops = {
- .open = snd_cs46xx_playback_open_rear,
- .close = snd_cs46xx_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cs46xx_playback_hw_params,
- .hw_free = snd_cs46xx_playback_hw_free,
- .prepare = snd_cs46xx_playback_prepare,
- .trigger = snd_cs46xx_playback_trigger,
- .pointer = snd_cs46xx_playback_indirect_pointer,
- .ack = snd_cs46xx_playback_transfer,
-};
-
-static struct snd_pcm_ops snd_cs46xx_playback_clfe_ops = {
- .open = snd_cs46xx_playback_open_clfe,
- .close = snd_cs46xx_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cs46xx_playback_hw_params,
- .hw_free = snd_cs46xx_playback_hw_free,
- .prepare = snd_cs46xx_playback_prepare,
- .trigger = snd_cs46xx_playback_trigger,
- .pointer = snd_cs46xx_playback_direct_pointer,
-};
-
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops = {
- .open = snd_cs46xx_playback_open_clfe,
- .close = snd_cs46xx_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cs46xx_playback_hw_params,
- .hw_free = snd_cs46xx_playback_hw_free,
- .prepare = snd_cs46xx_playback_prepare,
- .trigger = snd_cs46xx_playback_trigger,
- .pointer = snd_cs46xx_playback_indirect_pointer,
- .ack = snd_cs46xx_playback_transfer,
-};
-
-static struct snd_pcm_ops snd_cs46xx_playback_iec958_ops = {
- .open = snd_cs46xx_playback_open_iec958,
- .close = snd_cs46xx_playback_close_iec958,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cs46xx_playback_hw_params,
- .hw_free = snd_cs46xx_playback_hw_free,
- .prepare = snd_cs46xx_playback_prepare,
- .trigger = snd_cs46xx_playback_trigger,
- .pointer = snd_cs46xx_playback_direct_pointer,
-};
-
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops = {
- .open = snd_cs46xx_playback_open_iec958,
- .close = snd_cs46xx_playback_close_iec958,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cs46xx_playback_hw_params,
- .hw_free = snd_cs46xx_playback_hw_free,
- .prepare = snd_cs46xx_playback_prepare,
- .trigger = snd_cs46xx_playback_trigger,
- .pointer = snd_cs46xx_playback_indirect_pointer,
- .ack = snd_cs46xx_playback_transfer,
-};
-
-#endif
-
-static struct snd_pcm_ops snd_cs46xx_playback_ops = {
- .open = snd_cs46xx_playback_open,
- .close = snd_cs46xx_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cs46xx_playback_hw_params,
- .hw_free = snd_cs46xx_playback_hw_free,
- .prepare = snd_cs46xx_playback_prepare,
- .trigger = snd_cs46xx_playback_trigger,
- .pointer = snd_cs46xx_playback_direct_pointer,
-};
-
-static struct snd_pcm_ops snd_cs46xx_playback_indirect_ops = {
- .open = snd_cs46xx_playback_open,
- .close = snd_cs46xx_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cs46xx_playback_hw_params,
- .hw_free = snd_cs46xx_playback_hw_free,
- .prepare = snd_cs46xx_playback_prepare,
- .trigger = snd_cs46xx_playback_trigger,
- .pointer = snd_cs46xx_playback_indirect_pointer,
- .ack = snd_cs46xx_playback_transfer,
-};
-
-static struct snd_pcm_ops snd_cs46xx_capture_ops = {
- .open = snd_cs46xx_capture_open,
- .close = snd_cs46xx_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cs46xx_capture_hw_params,
- .hw_free = snd_cs46xx_capture_hw_free,
- .prepare = snd_cs46xx_capture_prepare,
- .trigger = snd_cs46xx_capture_trigger,
- .pointer = snd_cs46xx_capture_direct_pointer,
-};
-
-static struct snd_pcm_ops snd_cs46xx_capture_indirect_ops = {
- .open = snd_cs46xx_capture_open,
- .close = snd_cs46xx_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cs46xx_capture_hw_params,
- .hw_free = snd_cs46xx_capture_hw_free,
- .prepare = snd_cs46xx_capture_prepare,
- .trigger = snd_cs46xx_capture_trigger,
- .pointer = snd_cs46xx_capture_indirect_pointer,
- .ack = snd_cs46xx_capture_transfer,
-};
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
-#define MAX_PLAYBACK_CHANNELS (DSP_MAX_PCM_CHANNELS - 1)
-#else
-#define MAX_PLAYBACK_CHANNELS 1
-#endif
-
-int __devinit snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
- if ((err = snd_pcm_new(chip->card, "CS46xx", device, MAX_PLAYBACK_CHANNELS, 1, &pcm)) < 0)
- return err;
-
- pcm->private_data = chip;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs46xx_capture_ops);
-
- /* global setup */
- pcm->info_flags = 0;
- strcpy(pcm->name, "CS46xx");
- chip->pcm = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
-
- if (rpcm)
- *rpcm = pcm;
-
- return 0;
-}
-
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
-int __devinit snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
-
- if ((err = snd_pcm_new(chip->card, "CS46xx - Rear", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0)
- return err;
-
- pcm->private_data = chip;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_rear_ops);
-
- /* global setup */
- pcm->info_flags = 0;
- strcpy(pcm->name, "CS46xx - Rear");
- chip->pcm_rear = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
-
- if (rpcm)
- *rpcm = pcm;
-
- return 0;
-}
-
-int __devinit snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
-
- if ((err = snd_pcm_new(chip->card, "CS46xx - Center LFE", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0)
- return err;
-
- pcm->private_data = chip;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_clfe_ops);
-
- /* global setup */
- pcm->info_flags = 0;
- strcpy(pcm->name, "CS46xx - Center LFE");
- chip->pcm_center_lfe = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
-
- if (rpcm)
- *rpcm = pcm;
-
- return 0;
-}
-
-int __devinit snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
-
- if ((err = snd_pcm_new(chip->card, "CS46xx - IEC958", device, 1, 0, &pcm)) < 0)
- return err;
-
- pcm->private_data = chip;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_iec958_ops);
-
- /* global setup */
- pcm->info_flags = 0;
- strcpy(pcm->name, "CS46xx - IEC958");
- chip->pcm_rear = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
-
- if (rpcm)
- *rpcm = pcm;
-
- return 0;
-}
-#endif
-
-/*
- * Mixer routines
- */
-static void snd_cs46xx_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
-{
- struct snd_cs46xx *chip = bus->private_data;
-
- chip->ac97_bus = NULL;
-}
-
-static void snd_cs46xx_mixer_free_ac97(struct snd_ac97 *ac97)
-{
- struct snd_cs46xx *chip = ac97->private_data;
-
- if (snd_BUG_ON(ac97 != chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] &&
- ac97 != chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]))
- return;
-
- if (ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) {
- chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] = NULL;
- chip->eapd_switch = NULL;
- }
- else
- chip->ac97[CS46XX_SECONDARY_CODEC_INDEX] = NULL;
-}
-
-static int snd_cs46xx_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 0x7fff;
- return 0;
-}
-
-static int snd_cs46xx_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value;
- unsigned int val = snd_cs46xx_peek(chip, reg);
- ucontrol->value.integer.value[0] = 0xffff - (val >> 16);
- ucontrol->value.integer.value[1] = 0xffff - (val & 0xffff);
- return 0;
-}
-
-static int snd_cs46xx_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value;
- unsigned int val = ((0xffff - ucontrol->value.integer.value[0]) << 16 |
- (0xffff - ucontrol->value.integer.value[1]));
- unsigned int old = snd_cs46xx_peek(chip, reg);
- int change = (old != val);
-
- if (change) {
- snd_cs46xx_poke(chip, reg, val);
- }
-
- return change;
-}
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
-
-static int snd_cs46xx_vol_dac_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = chip->dsp_spos_instance->dac_volume_left;
- ucontrol->value.integer.value[1] = chip->dsp_spos_instance->dac_volume_right;
-
- return 0;
-}
-
-static int snd_cs46xx_vol_dac_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
- int change = 0;
-
- if (chip->dsp_spos_instance->dac_volume_right != ucontrol->value.integer.value[0] ||
- chip->dsp_spos_instance->dac_volume_left != ucontrol->value.integer.value[1]) {
- cs46xx_dsp_set_dac_volume(chip,
- ucontrol->value.integer.value[0],
- ucontrol->value.integer.value[1]);
- change = 1;
- }
-
- return change;
-}
-
-#if 0
-static int snd_cs46xx_vol_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_input_volume_left;
- ucontrol->value.integer.value[1] = chip->dsp_spos_instance->spdif_input_volume_right;
- return 0;
-}
-
-static int snd_cs46xx_vol_iec958_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
- int change = 0;
-
- if (chip->dsp_spos_instance->spdif_input_volume_left != ucontrol->value.integer.value[0] ||
- chip->dsp_spos_instance->spdif_input_volume_right!= ucontrol->value.integer.value[1]) {
- cs46xx_dsp_set_iec958_volume (chip,
- ucontrol->value.integer.value[0],
- ucontrol->value.integer.value[1]);
- change = 1;
- }
-
- return change;
-}
-#endif
-
-#define snd_mixer_boolean_info snd_ctl_boolean_mono_info
-
-static int snd_cs46xx_iec958_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value;
-
- if (reg == CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT)
- ucontrol->value.integer.value[0] = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED);
- else
- ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_status_in;
-
- return 0;
-}
-
-static int snd_cs46xx_iec958_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
- int change, res;
-
- switch (kcontrol->private_value) {
- case CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT:
- mutex_lock(&chip->spos_mutex);
- change = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED);
- if (ucontrol->value.integer.value[0] && !change)
- cs46xx_dsp_enable_spdif_out(chip);
- else if (change && !ucontrol->value.integer.value[0])
- cs46xx_dsp_disable_spdif_out(chip);
-
- res = (change != (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED));
- mutex_unlock(&chip->spos_mutex);
- break;
- case CS46XX_MIXER_SPDIF_INPUT_ELEMENT:
- change = chip->dsp_spos_instance->spdif_status_in;
- if (ucontrol->value.integer.value[0] && !change) {
- cs46xx_dsp_enable_spdif_in(chip);
- /* restore volume */
- }
- else if (change && !ucontrol->value.integer.value[0])
- cs46xx_dsp_disable_spdif_in(chip);
-
- res = (change != chip->dsp_spos_instance->spdif_status_in);
- break;
- default:
- res = -EINVAL;
- snd_BUG(); /* should never happen ... */
- }
-
- return res;
-}
-
-static int snd_cs46xx_adc_capture_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- if (ins->adc_input != NULL)
- ucontrol->value.integer.value[0] = 1;
- else
- ucontrol->value.integer.value[0] = 0;
-
- return 0;
-}
-
-static int snd_cs46xx_adc_capture_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- int change = 0;
-
- if (ucontrol->value.integer.value[0] && !ins->adc_input) {
- cs46xx_dsp_enable_adc_capture(chip);
- change = 1;
- } else if (!ucontrol->value.integer.value[0] && ins->adc_input) {
- cs46xx_dsp_disable_adc_capture(chip);
- change = 1;
- }
- return change;
-}
-
-static int snd_cs46xx_pcm_capture_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- if (ins->pcm_input != NULL)
- ucontrol->value.integer.value[0] = 1;
- else
- ucontrol->value.integer.value[0] = 0;
-
- return 0;
-}
-
-
-static int snd_cs46xx_pcm_capture_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- int change = 0;
-
- if (ucontrol->value.integer.value[0] && !ins->pcm_input) {
- cs46xx_dsp_enable_pcm_capture(chip);
- change = 1;
- } else if (!ucontrol->value.integer.value[0] && ins->pcm_input) {
- cs46xx_dsp_disable_pcm_capture(chip);
- change = 1;
- }
-
- return change;
-}
-
-static int snd_herc_spdif_select_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
-
- int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
-
- if (val1 & EGPIODR_GPOE0)
- ucontrol->value.integer.value[0] = 1;
- else
- ucontrol->value.integer.value[0] = 0;
-
- return 0;
-}
-
-/*
- * Game Theatre XP card - EGPIO[0] is used to select SPDIF input optical or coaxial.
- */
-static int snd_herc_spdif_select_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
- int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
- int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR);
-
- if (ucontrol->value.integer.value[0]) {
- /* optical is default */
- snd_cs46xx_pokeBA0(chip, BA0_EGPIODR,
- EGPIODR_GPOE0 | val1); /* enable EGPIO0 output */
- snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR,
- EGPIOPTR_GPPT0 | val2); /* open-drain on output */
- } else {
- /* coaxial */
- snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, val1 & ~EGPIODR_GPOE0); /* disable */
- snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT0); /* disable */
- }
-
- /* checking diff from the EGPIO direction register
- should be enough */
- return (val1 != (int)snd_cs46xx_peekBA0(chip, BA0_EGPIODR));
-}
-
-
-static int snd_cs46xx_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_cs46xx_spdif_default_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- mutex_lock(&chip->spos_mutex);
- ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_default >> 24) & 0xff);
- ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_default >> 16) & 0xff);
- ucontrol->value.iec958.status[2] = 0;
- ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_default) & 0xff);
- mutex_unlock(&chip->spos_mutex);
-
- return 0;
-}
-
-static int snd_cs46xx_spdif_default_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs46xx * chip = snd_kcontrol_chip(kcontrol);
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- unsigned int val;
- int change;
-
- mutex_lock(&chip->spos_mutex);
- val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) |
- ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[2]) << 16) |
- ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) |
- /* left and right validity bit */
- (1 << 13) | (1 << 12);
-
-
- change = (unsigned int)ins->spdif_csuv_default != val;
- ins->spdif_csuv_default = val;
-
- if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) )
- cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val);
-
- mutex_unlock(&chip->spos_mutex);
-
- return change;
-}
-
-static int snd_cs46xx_spdif_mask_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.iec958.status[0] = 0xff;
- ucontrol->value.iec958.status[1] = 0xff;
- ucontrol->value.iec958.status[2] = 0x00;
- ucontrol->value.iec958.status[3] = 0xff;
- return 0;
-}
-
-static int snd_cs46xx_spdif_stream_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- mutex_lock(&chip->spos_mutex);
- ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_stream >> 24) & 0xff);
- ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_stream >> 16) & 0xff);
- ucontrol->value.iec958.status[2] = 0;
- ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_stream) & 0xff);
- mutex_unlock(&chip->spos_mutex);
-
- return 0;
-}
-
-static int snd_cs46xx_spdif_stream_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs46xx * chip = snd_kcontrol_chip(kcontrol);
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- unsigned int val;
- int change;
-
- mutex_lock(&chip->spos_mutex);
- val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) |
- ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[1]) << 16) |
- ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) |
- /* left and right validity bit */
- (1 << 13) | (1 << 12);
-
-
- change = ins->spdif_csuv_stream != val;
- ins->spdif_csuv_stream = val;
-
- if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN )
- cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val);
-
- mutex_unlock(&chip->spos_mutex);
-
- return change;
-}
-
-#endif /* CONFIG_SND_CS46XX_NEW_DSP */
-
-
-static struct snd_kcontrol_new snd_cs46xx_controls[] __devinitdata = {
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "DAC Volume",
- .info = snd_cs46xx_vol_info,
-#ifndef CONFIG_SND_CS46XX_NEW_DSP
- .get = snd_cs46xx_vol_get,
- .put = snd_cs46xx_vol_put,
- .private_value = BA1_PVOL,
-#else
- .get = snd_cs46xx_vol_dac_get,
- .put = snd_cs46xx_vol_dac_put,
-#endif
-},
-
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "ADC Volume",
- .info = snd_cs46xx_vol_info,
- .get = snd_cs46xx_vol_get,
- .put = snd_cs46xx_vol_put,
-#ifndef CONFIG_SND_CS46XX_NEW_DSP
- .private_value = BA1_CVOL,
-#else
- .private_value = (VARIDECIMATE_SCB_ADDR + 0xE) << 2,
-#endif
-},
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "ADC Capture Switch",
- .info = snd_mixer_boolean_info,
- .get = snd_cs46xx_adc_capture_get,
- .put = snd_cs46xx_adc_capture_put
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "DAC Capture Switch",
- .info = snd_mixer_boolean_info,
- .get = snd_cs46xx_pcm_capture_get,
- .put = snd_cs46xx_pcm_capture_put
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH),
- .info = snd_mixer_boolean_info,
- .get = snd_cs46xx_iec958_get,
- .put = snd_cs46xx_iec958_put,
- .private_value = CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("Input ",NONE,SWITCH),
- .info = snd_mixer_boolean_info,
- .get = snd_cs46xx_iec958_get,
- .put = snd_cs46xx_iec958_put,
- .private_value = CS46XX_MIXER_SPDIF_INPUT_ELEMENT,
-},
-#if 0
-/* Input IEC958 volume does not work for the moment. (Benny) */
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("Input ",NONE,VOLUME),
- .info = snd_cs46xx_vol_info,
- .get = snd_cs46xx_vol_iec958_get,
- .put = snd_cs46xx_vol_iec958_put,
- .private_value = (ASYNCRX_SCB_ADDR + 0xE) << 2,
-},
-#endif
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
- .info = snd_cs46xx_spdif_info,
- .get = snd_cs46xx_spdif_default_get,
- .put = snd_cs46xx_spdif_default_put,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
- .info = snd_cs46xx_spdif_info,
- .get = snd_cs46xx_spdif_mask_get,
- .access = SNDRV_CTL_ELEM_ACCESS_READ
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
- .info = snd_cs46xx_spdif_info,
- .get = snd_cs46xx_spdif_stream_get,
- .put = snd_cs46xx_spdif_stream_put
-},
-
-#endif
-};
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
-/* set primary cs4294 codec into Extended Audio Mode */
-static int snd_cs46xx_front_dup_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
- unsigned short val;
- val = snd_ac97_read(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], AC97_CSR_ACMODE);
- ucontrol->value.integer.value[0] = (val & 0x200) ? 0 : 1;
- return 0;
-}
-
-static int snd_cs46xx_front_dup_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
- return snd_ac97_update_bits(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX],
- AC97_CSR_ACMODE, 0x200,
- ucontrol->value.integer.value[0] ? 0 : 0x200);
-}
-
-static struct snd_kcontrol_new snd_cs46xx_front_dup_ctl = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Duplicate Front",
- .info = snd_mixer_boolean_info,
- .get = snd_cs46xx_front_dup_get,
- .put = snd_cs46xx_front_dup_put,
-};
-#endif
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
-/* Only available on the Hercules Game Theater XP soundcard */
-static struct snd_kcontrol_new snd_hercules_controls[] = {
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Optical/Coaxial SPDIF Input Switch",
- .info = snd_mixer_boolean_info,
- .get = snd_herc_spdif_select_get,
- .put = snd_herc_spdif_select_put,
-},
-};
-
-
-static void snd_cs46xx_codec_reset (struct snd_ac97 * ac97)
-{
- unsigned long end_time;
- int err;
-
- /* reset to defaults */
- snd_ac97_write(ac97, AC97_RESET, 0);
-
- /* set the desired CODEC mode */
- if (ac97->num == CS46XX_PRIMARY_CODEC_INDEX) {
- snd_printdd("cs46xx: CODEC1 mode %04x\n", 0x0);
- snd_cs46xx_ac97_write(ac97, AC97_CSR_ACMODE, 0x0);
- } else if (ac97->num == CS46XX_SECONDARY_CODEC_INDEX) {
- snd_printdd("cs46xx: CODEC2 mode %04x\n", 0x3);
- snd_cs46xx_ac97_write(ac97, AC97_CSR_ACMODE, 0x3);
- } else {
- snd_BUG(); /* should never happen ... */
- }
-
- udelay(50);
-
- /* it's necessary to wait awhile until registers are accessible after RESET */
- /* because the PCM or MASTER volume registers can be modified, */
- /* the REC_GAIN register is used for tests */
- end_time = jiffies + HZ;
- do {
- unsigned short ext_mid;
-
- /* use preliminary reads to settle the communication */
- snd_ac97_read(ac97, AC97_RESET);
- snd_ac97_read(ac97, AC97_VENDOR_ID1);
- snd_ac97_read(ac97, AC97_VENDOR_ID2);
- /* modem? */
- ext_mid = snd_ac97_read(ac97, AC97_EXTENDED_MID);
- if (ext_mid != 0xffff && (ext_mid & 1) != 0)
- return;
-
- /* test if we can write to the record gain volume register */
- snd_ac97_write(ac97, AC97_REC_GAIN, 0x8a05);
- if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05)
- return;
-
- msleep(10);
- } while (time_after_eq(end_time, jiffies));
-
- snd_printk(KERN_ERR "CS46xx secondary codec doesn't respond!\n");
-}
-#endif
-
-static int __devinit cs46xx_detect_codec(struct snd_cs46xx *chip, int codec)
-{
- int idx, err;
- struct snd_ac97_template ac97;
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = chip;
- ac97.private_free = snd_cs46xx_mixer_free_ac97;
- ac97.num = codec;
- if (chip->amplifier_ctrl == amp_voyetra)
- ac97.scaps = AC97_SCAP_INV_EAPD;
-
- if (codec == CS46XX_SECONDARY_CODEC_INDEX) {
- snd_cs46xx_codec_write(chip, AC97_RESET, 0, codec);
- udelay(10);
- if (snd_cs46xx_codec_read(chip, AC97_RESET, codec) & 0x8000) {
- snd_printdd("snd_cs46xx: seconadry codec not present\n");
- return -ENXIO;
- }
- }
-
- snd_cs46xx_codec_write(chip, AC97_MASTER, 0x8000, codec);
- for (idx = 0; idx < 100; ++idx) {
- if (snd_cs46xx_codec_read(chip, AC97_MASTER, codec) == 0x8000) {
- err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[codec]);
- return err;
- }
- msleep(10);
- }
- snd_printdd("snd_cs46xx: codec %d detection timeout\n", codec);
- return -ENXIO;
-}
-
-int __devinit snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device)
-{
- struct snd_card *card = chip->card;
- struct snd_ctl_elem_id id;
- int err;
- unsigned int idx;
- static struct snd_ac97_bus_ops ops = {
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- .reset = snd_cs46xx_codec_reset,
-#endif
- .write = snd_cs46xx_ac97_write,
- .read = snd_cs46xx_ac97_read,
- };
-
- /* detect primary codec */
- chip->nr_ac97_codecs = 0;
- snd_printdd("snd_cs46xx: detecting primary codec\n");
- if ((err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus)) < 0)
- return err;
- chip->ac97_bus->private_free = snd_cs46xx_mixer_free_ac97_bus;
-
- if (cs46xx_detect_codec(chip, CS46XX_PRIMARY_CODEC_INDEX) < 0)
- return -ENXIO;
- chip->nr_ac97_codecs = 1;
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- snd_printdd("snd_cs46xx: detecting seconadry codec\n");
- /* try detect a secondary codec */
- if (! cs46xx_detect_codec(chip, CS46XX_SECONDARY_CODEC_INDEX))
- chip->nr_ac97_codecs = 2;
-#endif /* CONFIG_SND_CS46XX_NEW_DSP */
-
- /* add cs4630 mixer controls */
- for (idx = 0; idx < ARRAY_SIZE(snd_cs46xx_controls); idx++) {
- struct snd_kcontrol *kctl;
- kctl = snd_ctl_new1(&snd_cs46xx_controls[idx], chip);
- if (kctl && kctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM)
- kctl->id.device = spdif_device;
- if ((err = snd_ctl_add(card, kctl)) < 0)
- return err;
- }
-
- /* get EAPD mixer switch (for voyetra hack) */
- memset(&id, 0, sizeof(id));
- id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(id.name, "External Amplifier");
- chip->eapd_switch = snd_ctl_find_id(chip->card, &id);
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- if (chip->nr_ac97_codecs == 1) {
- unsigned int id2 = chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]->id & 0xffff;
- if (id2 == 0x592b || id2 == 0x592d) {
- err = snd_ctl_add(card, snd_ctl_new1(&snd_cs46xx_front_dup_ctl, chip));
- if (err < 0)
- return err;
- snd_ac97_write_cache(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX],
- AC97_CSR_ACMODE, 0x200);
- }
- }
- /* do soundcard specific mixer setup */
- if (chip->mixer_init) {
- snd_printdd ("calling chip->mixer_init(chip);\n");
- chip->mixer_init(chip);
- }
-#endif
-
- /* turn on amplifier */
- chip->amplifier_ctrl(chip, 1);
-
- return 0;
-}
-
-/*
- * RawMIDI interface
- */
-
-static void snd_cs46xx_midi_reset(struct snd_cs46xx *chip)
-{
- snd_cs46xx_pokeBA0(chip, BA0_MIDCR, MIDCR_MRST);
- udelay(100);
- snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
-}
-
-static int snd_cs46xx_midi_input_open(struct snd_rawmidi_substream *substream)
-{
- struct snd_cs46xx *chip = substream->rmidi->private_data;
-
- chip->active_ctrl(chip, 1);
- spin_lock_irq(&chip->reg_lock);
- chip->uartm |= CS46XX_MODE_INPUT;
- chip->midcr |= MIDCR_RXE;
- chip->midi_input = substream;
- if (!(chip->uartm & CS46XX_MODE_OUTPUT)) {
- snd_cs46xx_midi_reset(chip);
- } else {
- snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
- }
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static int snd_cs46xx_midi_input_close(struct snd_rawmidi_substream *substream)
-{
- struct snd_cs46xx *chip = substream->rmidi->private_data;
-
- spin_lock_irq(&chip->reg_lock);
- chip->midcr &= ~(MIDCR_RXE | MIDCR_RIE);
- chip->midi_input = NULL;
- if (!(chip->uartm & CS46XX_MODE_OUTPUT)) {
- snd_cs46xx_midi_reset(chip);
- } else {
- snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
- }
- chip->uartm &= ~CS46XX_MODE_INPUT;
- spin_unlock_irq(&chip->reg_lock);
- chip->active_ctrl(chip, -1);
- return 0;
-}
-
-static int snd_cs46xx_midi_output_open(struct snd_rawmidi_substream *substream)
-{
- struct snd_cs46xx *chip = substream->rmidi->private_data;
-
- chip->active_ctrl(chip, 1);
-
- spin_lock_irq(&chip->reg_lock);
- chip->uartm |= CS46XX_MODE_OUTPUT;
- chip->midcr |= MIDCR_TXE;
- chip->midi_output = substream;
- if (!(chip->uartm & CS46XX_MODE_INPUT)) {
- snd_cs46xx_midi_reset(chip);
- } else {
- snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
- }
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static int snd_cs46xx_midi_output_close(struct snd_rawmidi_substream *substream)
-{
- struct snd_cs46xx *chip = substream->rmidi->private_data;
-
- spin_lock_irq(&chip->reg_lock);
- chip->midcr &= ~(MIDCR_TXE | MIDCR_TIE);
- chip->midi_output = NULL;
- if (!(chip->uartm & CS46XX_MODE_INPUT)) {
- snd_cs46xx_midi_reset(chip);
- } else {
- snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
- }
- chip->uartm &= ~CS46XX_MODE_OUTPUT;
- spin_unlock_irq(&chip->reg_lock);
- chip->active_ctrl(chip, -1);
- return 0;
-}
-
-static void snd_cs46xx_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- unsigned long flags;
- struct snd_cs46xx *chip = substream->rmidi->private_data;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (up) {
- if ((chip->midcr & MIDCR_RIE) == 0) {
- chip->midcr |= MIDCR_RIE;
- snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
- }
- } else {
- if (chip->midcr & MIDCR_RIE) {
- chip->midcr &= ~MIDCR_RIE;
- snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
- }
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-
-static void snd_cs46xx_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- unsigned long flags;
- struct snd_cs46xx *chip = substream->rmidi->private_data;
- unsigned char byte;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (up) {
- if ((chip->midcr & MIDCR_TIE) == 0) {
- chip->midcr |= MIDCR_TIE;
- /* fill UART FIFO buffer at first, and turn Tx interrupts only if necessary */
- while ((chip->midcr & MIDCR_TIE) &&
- (snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) {
- if (snd_rawmidi_transmit(substream, &byte, 1) != 1) {
- chip->midcr &= ~MIDCR_TIE;
- } else {
- snd_cs46xx_pokeBA0(chip, BA0_MIDWP, byte);
- }
- }
- snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
- }
- } else {
- if (chip->midcr & MIDCR_TIE) {
- chip->midcr &= ~MIDCR_TIE;
- snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
- }
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-
-static struct snd_rawmidi_ops snd_cs46xx_midi_output =
-{
- .open = snd_cs46xx_midi_output_open,
- .close = snd_cs46xx_midi_output_close,
- .trigger = snd_cs46xx_midi_output_trigger,
-};
-
-static struct snd_rawmidi_ops snd_cs46xx_midi_input =
-{
- .open = snd_cs46xx_midi_input_open,
- .close = snd_cs46xx_midi_input_close,
- .trigger = snd_cs46xx_midi_input_trigger,
-};
-
-int __devinit snd_cs46xx_midi(struct snd_cs46xx *chip, int device, struct snd_rawmidi **rrawmidi)
-{
- struct snd_rawmidi *rmidi;
- int err;
-
- if (rrawmidi)
- *rrawmidi = NULL;
- if ((err = snd_rawmidi_new(chip->card, "CS46XX", device, 1, 1, &rmidi)) < 0)
- return err;
- strcpy(rmidi->name, "CS46XX");
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_cs46xx_midi_output);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_cs46xx_midi_input);
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
- rmidi->private_data = chip;
- chip->rmidi = rmidi;
- if (rrawmidi)
- *rrawmidi = NULL;
- return 0;
-}
-
-
-/*
- * gameport interface
- */
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-
-static void snd_cs46xx_gameport_trigger(struct gameport *gameport)
-{
- struct snd_cs46xx *chip = gameport_get_port_data(gameport);
-
- if (snd_BUG_ON(!chip))
- return;
- snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF); //outb(gameport->io, 0xFF);
-}
-
-static unsigned char snd_cs46xx_gameport_read(struct gameport *gameport)
-{
- struct snd_cs46xx *chip = gameport_get_port_data(gameport);
-
- if (snd_BUG_ON(!chip))
- return 0;
- return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io);
-}
-
-static int snd_cs46xx_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
-{
- struct snd_cs46xx *chip = gameport_get_port_data(gameport);
- unsigned js1, js2, jst;
-
- if (snd_BUG_ON(!chip))
- return 0;
-
- js1 = snd_cs46xx_peekBA0(chip, BA0_JSC1);
- js2 = snd_cs46xx_peekBA0(chip, BA0_JSC2);
- jst = snd_cs46xx_peekBA0(chip, BA0_JSPT);
-
- *buttons = (~jst >> 4) & 0x0F;
-
- axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF;
- axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF;
- axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF;
- axes[3] = ((js2 & JSC2_X2V_MASK) >> JSC2_X2V_SHIFT) & 0xFFFF;
-
- for(jst=0;jst<4;++jst)
- if(axes[jst]==0xFFFF) axes[jst] = -1;
- return 0;
-}
-
-static int snd_cs46xx_gameport_open(struct gameport *gameport, int mode)
-{
- switch (mode) {
- case GAMEPORT_MODE_COOKED:
- return 0;
- case GAMEPORT_MODE_RAW:
- return 0;
- default:
- return -1;
- }
- return 0;
-}
-
-int __devinit snd_cs46xx_gameport(struct snd_cs46xx *chip)
-{
- struct gameport *gp;
-
- chip->gameport = gp = gameport_allocate_port();
- if (!gp) {
- printk(KERN_ERR "cs46xx: cannot allocate memory for gameport\n");
- return -ENOMEM;
- }
-
- gameport_set_name(gp, "CS46xx Gameport");
- gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
- gameport_set_dev_parent(gp, &chip->pci->dev);
- gameport_set_port_data(gp, chip);
-
- gp->open = snd_cs46xx_gameport_open;
- gp->read = snd_cs46xx_gameport_read;
- gp->trigger = snd_cs46xx_gameport_trigger;
- gp->cooked_read = snd_cs46xx_gameport_cooked_read;
-
- snd_cs46xx_pokeBA0(chip, BA0_JSIO, 0xFF); // ?
- snd_cs46xx_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW);
-
- gameport_register_port(gp);
-
- return 0;
-}
-
-static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip)
-{
- if (chip->gameport) {
- gameport_unregister_port(chip->gameport);
- chip->gameport = NULL;
- }
-}
-#else
-int __devinit snd_cs46xx_gameport(struct snd_cs46xx *chip) { return -ENOSYS; }
-static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) { }
-#endif /* CONFIG_GAMEPORT */
-
-#ifdef CONFIG_PROC_FS
-/*
- * proc interface
- */
-
-static ssize_t snd_cs46xx_io_read(struct snd_info_entry *entry,
- void *file_private_data,
- struct file *file, char __user *buf,
- size_t count, loff_t pos)
-{
- struct snd_cs46xx_region *region = entry->private_data;
-
- if (copy_to_user_fromio(buf, region->remap_addr + pos, count))
- return -EFAULT;
- return count;
-}
-
-static struct snd_info_entry_ops snd_cs46xx_proc_io_ops = {
- .read = snd_cs46xx_io_read,
-};
-
-static int __devinit snd_cs46xx_proc_init(struct snd_card *card, struct snd_cs46xx *chip)
-{
- struct snd_info_entry *entry;
- int idx;
-
- for (idx = 0; idx < 5; idx++) {
- struct snd_cs46xx_region *region = &chip->region.idx[idx];
- if (! snd_card_proc_new(card, region->name, &entry)) {
- entry->content = SNDRV_INFO_CONTENT_DATA;
- entry->private_data = chip;
- entry->c.ops = &snd_cs46xx_proc_io_ops;
- entry->size = region->size;
- entry->mode = S_IFREG | S_IRUSR;
- }
- }
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- cs46xx_dsp_proc_init(card, chip);
-#endif
- return 0;
-}
-
-static int snd_cs46xx_proc_done(struct snd_cs46xx *chip)
-{
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- cs46xx_dsp_proc_done(chip);
-#endif
- return 0;
-}
-#else /* !CONFIG_PROC_FS */
-#define snd_cs46xx_proc_init(card, chip)
-#define snd_cs46xx_proc_done(chip)
-#endif
-
-/*
- * stop the h/w
- */
-static void snd_cs46xx_hw_stop(struct snd_cs46xx *chip)
-{
- unsigned int tmp;
-
- tmp = snd_cs46xx_peek(chip, BA1_PFIE);
- tmp &= ~0x0000f03f;
- tmp |= 0x00000010;
- snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt disable */
-
- tmp = snd_cs46xx_peek(chip, BA1_CIE);
- tmp &= ~0x0000003f;
- tmp |= 0x00000011;
- snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt disable */
-
- /*
- * Stop playback DMA.
- */
- tmp = snd_cs46xx_peek(chip, BA1_PCTL);
- snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff);
-
- /*
- * Stop capture DMA.
- */
- tmp = snd_cs46xx_peek(chip, BA1_CCTL);
- snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000);
-
- /*
- * Reset the processor.
- */
- snd_cs46xx_reset(chip);
-
- snd_cs46xx_proc_stop(chip);
-
- /*
- * Power down the PLL.
- */
- snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0);
-
- /*
- * Turn off the Processor by turning off the software clock enable flag in
- * the clock control register.
- */
- tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE;
- snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
-}
-
-
-static int snd_cs46xx_free(struct snd_cs46xx *chip)
-{
- int idx;
-
- if (snd_BUG_ON(!chip))
- return -EINVAL;
-
- if (chip->active_ctrl)
- chip->active_ctrl(chip, 1);
-
- snd_cs46xx_remove_gameport(chip);
-
- if (chip->amplifier_ctrl)
- chip->amplifier_ctrl(chip, -chip->amplifier); /* force to off */
-
- snd_cs46xx_proc_done(chip);
-
- if (chip->region.idx[0].resource)
- snd_cs46xx_hw_stop(chip);
-
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
-
- if (chip->active_ctrl)
- chip->active_ctrl(chip, -chip->amplifier);
-
- for (idx = 0; idx < 5; idx++) {
- struct snd_cs46xx_region *region = &chip->region.idx[idx];
- if (region->remap_addr)
- iounmap(region->remap_addr);
- release_and_free_resource(region->resource);
- }
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- if (chip->dsp_spos_instance) {
- cs46xx_dsp_spos_destroy(chip);
- chip->dsp_spos_instance = NULL;
- }
-#endif
-
-#ifdef CONFIG_PM
- kfree(chip->saved_regs);
-#endif
-
- pci_disable_device(chip->pci);
- kfree(chip);
- return 0;
-}
-
-static int snd_cs46xx_dev_free(struct snd_device *device)
-{
- struct snd_cs46xx *chip = device->device_data;
- return snd_cs46xx_free(chip);
-}
-
-/*
- * initialize chip
- */
-static int snd_cs46xx_chip_init(struct snd_cs46xx *chip)
-{
- int timeout;
-
- /*
- * First, blast the clock control register to zero so that the PLL starts
- * out in a known state, and blast the master serial port control register
- * to zero so that the serial ports also start out in a known state.
- */
- snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0);
- snd_cs46xx_pokeBA0(chip, BA0_SERMC1, 0);
-
- /*
- * If we are in AC97 mode, then we must set the part to a host controlled
- * AC-link. Otherwise, we won't be able to bring up the link.
- */
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0 |
- SERACC_TWO_CODECS); /* 2.00 dual codecs */
- /* snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0); */ /* 2.00 codec */
-#else
- snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_1_03); /* 1.03 codec */
-#endif
-
- /*
- * Drive the ARST# pin low for a minimum of 1uS (as defined in the AC97
- * spec) and then drive it high. This is done for non AC97 modes since
- * there might be logic external to the CS461x that uses the ARST# line
- * for a reset.
- */
- snd_cs46xx_pokeBA0(chip, BA0_ACCTL, 0);
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, 0);
-#endif
- udelay(50);
- snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_RSTN);
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_RSTN);
-#endif
-
- /*
- * The first thing we do here is to enable sync generation. As soon
- * as we start receiving bit clock, we'll start producing the SYNC
- * signal.
- */
- snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_ESYN | ACCTL_RSTN);
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_ESYN | ACCTL_RSTN);
-#endif
-
- /*
- * Now wait for a short while to allow the AC97 part to start
- * generating bit clock (so we don't try to start the PLL without an
- * input clock).
- */
- mdelay(10);
-
- /*
- * Set the serial port timing configuration, so that
- * the clock control circuit gets its clock from the correct place.
- */
- snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97);
-
- /*
- * Write the selected clock control setup to the hardware. Do not turn on
- * SWCE yet (if requested), so that the devices clocked by the output of
- * PLL are not clocked until the PLL is stable.
- */
- snd_cs46xx_pokeBA0(chip, BA0_PLLCC, PLLCC_LPF_1050_2780_KHZ | PLLCC_CDR_73_104_MHZ);
- snd_cs46xx_pokeBA0(chip, BA0_PLLM, 0x3a);
- snd_cs46xx_pokeBA0(chip, BA0_CLKCR2, CLKCR2_PDIVS_8);
-
- /*
- * Power up the PLL.
- */
- snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP);
-
- /*
- * Wait until the PLL has stabilized.
- */
- msleep(100);
-
- /*
- * Turn on clocking of the core so that we can setup the serial ports.
- */
- snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP | CLKCR1_SWCE);
-
- /*
- * Enable FIFO Host Bypass
- */
- snd_cs46xx_pokeBA0(chip, BA0_SERBCF, SERBCF_HBP);
-
- /*
- * Fill the serial port FIFOs with silence.
- */
- snd_cs46xx_clear_serial_FIFOs(chip);
-
- /*
- * Set the serial port FIFO pointer to the first sample in the FIFO.
- */
- /* snd_cs46xx_pokeBA0(chip, BA0_SERBSP, 0); */
-
- /*
- * Write the serial port configuration to the part. The master
- * enable bit is not set until all other values have been written.
- */
- snd_cs46xx_pokeBA0(chip, BA0_SERC1, SERC1_SO1F_AC97 | SERC1_SO1EN);
- snd_cs46xx_pokeBA0(chip, BA0_SERC2, SERC2_SI1F_AC97 | SERC1_SO1EN);
- snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97 | SERMC1_MSPE);
-
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- snd_cs46xx_pokeBA0(chip, BA0_SERC7, SERC7_ASDI2EN);
- snd_cs46xx_pokeBA0(chip, BA0_SERC3, 0);
- snd_cs46xx_pokeBA0(chip, BA0_SERC4, 0);
- snd_cs46xx_pokeBA0(chip, BA0_SERC5, 0);
- snd_cs46xx_pokeBA0(chip, BA0_SERC6, 1);
-#endif
-
- mdelay(5);
-
-
- /*
- * Wait for the codec ready signal from the AC97 codec.
- */
- timeout = 150;
- while (timeout-- > 0) {
- /*
- * Read the AC97 status register to see if we've seen a CODEC READY
- * signal from the AC97 codec.
- */
- if (snd_cs46xx_peekBA0(chip, BA0_ACSTS) & ACSTS_CRDY)
- goto ok1;
- msleep(10);
- }
-
-
- snd_printk(KERN_ERR "create - never read codec ready from AC'97\n");
- snd_printk(KERN_ERR "it is not probably bug, try to use CS4236 driver\n");
- return -EIO;
- ok1:
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- {
- int count;
- for (count = 0; count < 150; count++) {
- /* First, we want to wait for a short time. */
- udelay(25);
-
- if (snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY)
- break;
- }
-
- /*
- * Make sure CODEC is READY.
- */
- if (!(snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY))
- snd_printdd("cs46xx: never read card ready from secondary AC'97\n");
- }
-#endif
-
- /*
- * Assert the vaid frame signal so that we can start sending commands
- * to the AC97 codec.
- */
- snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
-#endif
-
-
- /*
- * Wait until we've sampled input slots 3 and 4 as valid, meaning that
- * the codec is pumping ADC data across the AC-link.
- */
- timeout = 150;
- while (timeout-- > 0) {
- /*
- * Read the input slot valid register and see if input slots 3 and
- * 4 are valid yet.
- */
- if ((snd_cs46xx_peekBA0(chip, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4))
- goto ok2;
- msleep(10);
- }
-
-#ifndef CONFIG_SND_CS46XX_NEW_DSP
- snd_printk(KERN_ERR "create - never read ISV3 & ISV4 from AC'97\n");
- return -EIO;
-#else
- /* This may happen on a cold boot with a Terratec SiXPack 5.1.
- Reloading the driver may help, if there's other soundcards
- with the same problem I would like to know. (Benny) */
-
- snd_printk(KERN_ERR "ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n");
- snd_printk(KERN_ERR " Try reloading the ALSA driver, if you find something\n");
- snd_printk(KERN_ERR " broken or not working on your soundcard upon\n");
- snd_printk(KERN_ERR " this message please report to alsa-devel@alsa-project.org\n");
-
- return -EIO;
-#endif
- ok2:
-
- /*
- * Now, assert valid frame and the slot 3 and 4 valid bits. This will
- * commense the transfer of digital audio data to the AC97 codec.
- */
-
- snd_cs46xx_pokeBA0(chip, BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4);
-
-
- /*
- * Power down the DAC and ADC. We will power them up (if) when we need
- * them.
- */
- /* snd_cs46xx_pokeBA0(chip, BA0_AC97_POWERDOWN, 0x300); */
-
- /*
- * Turn off the Processor by turning off the software clock enable flag in
- * the clock control register.
- */
- /* tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE; */
- /* snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); */
-
- return 0;
-}
-
-/*
- * start and load DSP
- */
-
-static void cs46xx_enable_stream_irqs(struct snd_cs46xx *chip)
-{
- unsigned int tmp;
-
- snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM);
-
- tmp = snd_cs46xx_peek(chip, BA1_PFIE);
- tmp &= ~0x0000f03f;
- snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */
-
- tmp = snd_cs46xx_peek(chip, BA1_CIE);
- tmp &= ~0x0000003f;
- tmp |= 0x00000001;
- snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */
-}
-
-int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip)
-{
- unsigned int tmp;
- /*
- * Reset the processor.
- */
- snd_cs46xx_reset(chip);
- /*
- * Download the image to the processor.
- */
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
-#if 0
- if (cs46xx_dsp_load_module(chip, &cwcemb80_module) < 0) {
- snd_printk(KERN_ERR "image download error\n");
- return -EIO;
- }
-#endif
-
- if (cs46xx_dsp_load_module(chip, &cwc4630_module) < 0) {
- snd_printk(KERN_ERR "image download error [cwc4630]\n");
- return -EIO;
- }
-
- if (cs46xx_dsp_load_module(chip, &cwcasync_module) < 0) {
- snd_printk(KERN_ERR "image download error [cwcasync]\n");
- return -EIO;
- }
-
- if (cs46xx_dsp_load_module(chip, &cwcsnoop_module) < 0) {
- snd_printk(KERN_ERR "image download error [cwcsnoop]\n");
- return -EIO;
- }
-
- if (cs46xx_dsp_load_module(chip, &cwcbinhack_module) < 0) {
- snd_printk(KERN_ERR "image download error [cwcbinhack]\n");
- return -EIO;
- }
-
- if (cs46xx_dsp_load_module(chip, &cwcdma_module) < 0) {
- snd_printk(KERN_ERR "image download error [cwcdma]\n");
- return -EIO;
- }
-
- if (cs46xx_dsp_scb_and_task_init(chip) < 0)
- return -EIO;
-#else
- /* old image */
- if (snd_cs46xx_download_image(chip) < 0) {
- snd_printk(KERN_ERR "image download error\n");
- return -EIO;
- }
-
- /*
- * Stop playback DMA.
- */
- tmp = snd_cs46xx_peek(chip, BA1_PCTL);
- chip->play_ctl = tmp & 0xffff0000;
- snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff);
-#endif
-
- /*
- * Stop capture DMA.
- */
- tmp = snd_cs46xx_peek(chip, BA1_CCTL);
- chip->capt.ctl = tmp & 0x0000ffff;
- snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000);
-
- mdelay(5);
-
- snd_cs46xx_set_play_sample_rate(chip, 8000);
- snd_cs46xx_set_capture_sample_rate(chip, 8000);
-
- snd_cs46xx_proc_start(chip);
-
- cs46xx_enable_stream_irqs(chip);
-
-#ifndef CONFIG_SND_CS46XX_NEW_DSP
- /* set the attenuation to 0dB */
- snd_cs46xx_poke(chip, BA1_PVOL, 0x80008000);
- snd_cs46xx_poke(chip, BA1_CVOL, 0x80008000);
-#endif
-
- return 0;
-}
-
-
-/*
- * AMP control - null AMP
- */
-
-static void amp_none(struct snd_cs46xx *chip, int change)
-{
-}
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
-static int voyetra_setup_eapd_slot(struct snd_cs46xx *chip)
-{
-
- u32 idx, valid_slots,tmp,powerdown = 0;
- u16 modem_power,pin_config,logic_type;
-
- snd_printdd ("cs46xx: cs46xx_setup_eapd_slot()+\n");
-
- /*
- * See if the devices are powered down. If so, we must power them up first
- * or they will not respond.
- */
- tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1);
-
- if (!(tmp & CLKCR1_SWCE)) {
- snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE);
- powerdown = 1;
- }
-
- /*
- * Clear PRA. The Bonzo chip will be used for GPIO not for modem
- * stuff.
- */
- if(chip->nr_ac97_codecs != 2) {
- snd_printk (KERN_ERR "cs46xx: cs46xx_setup_eapd_slot() - no secondary codec configured\n");
- return -EINVAL;
- }
-
- modem_power = snd_cs46xx_codec_read (chip,
- AC97_EXTENDED_MSTATUS,
- CS46XX_SECONDARY_CODEC_INDEX);
- modem_power &=0xFEFF;
-
- snd_cs46xx_codec_write(chip,
- AC97_EXTENDED_MSTATUS, modem_power,
- CS46XX_SECONDARY_CODEC_INDEX);
-
- /*
- * Set GPIO pin's 7 and 8 so that they are configured for output.
- */
- pin_config = snd_cs46xx_codec_read (chip,
- AC97_GPIO_CFG,
- CS46XX_SECONDARY_CODEC_INDEX);
- pin_config &=0x27F;
-
- snd_cs46xx_codec_write(chip,
- AC97_GPIO_CFG, pin_config,
- CS46XX_SECONDARY_CODEC_INDEX);
-
- /*
- * Set GPIO pin's 7 and 8 so that they are compatible with CMOS logic.
- */
-
- logic_type = snd_cs46xx_codec_read(chip, AC97_GPIO_POLARITY,
- CS46XX_SECONDARY_CODEC_INDEX);
- logic_type &=0x27F;
-
- snd_cs46xx_codec_write (chip, AC97_GPIO_POLARITY, logic_type,
- CS46XX_SECONDARY_CODEC_INDEX);
-
- valid_slots = snd_cs46xx_peekBA0(chip, BA0_ACOSV);
- valid_slots |= 0x200;
- snd_cs46xx_pokeBA0(chip, BA0_ACOSV, valid_slots);
-
- if ( cs46xx_wait_for_fifo(chip,1) ) {
- snd_printdd("FIFO is busy\n");
-
- return -EINVAL;
- }
-
- /*
- * Fill slots 12 with the correct value for the GPIO pins.
- */
- for(idx = 0x90; idx <= 0x9F; idx++) {
- /*
- * Initialize the fifo so that bits 7 and 8 are on.
- *
- * Remember that the GPIO pins in bonzo are shifted by 4 bits to
- * the left. 0x1800 corresponds to bits 7 and 8.
- */
- snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0x1800);
-
- /*
- * Wait for command to complete
- */
- if ( cs46xx_wait_for_fifo(chip,200) ) {
- snd_printdd("failed waiting for FIFO at addr (%02X)\n",idx);
-
- return -EINVAL;
- }
-
- /*
- * Write the serial port FIFO index.
- */
- snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx);
-
- /*
- * Tell the serial port to load the new value into the FIFO location.
- */
- snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC);
- }
-
- /* wait for last command to complete */
- cs46xx_wait_for_fifo(chip,200);
-
- /*
- * Now, if we powered up the devices, then power them back down again.
- * This is kinda ugly, but should never happen.
- */
- if (powerdown)
- snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
-
- return 0;
-}
-#endif
-
-/*
- * Crystal EAPD mode
- */
-
-static void amp_voyetra(struct snd_cs46xx *chip, int change)
-{
- /* Manage the EAPD bit on the Crystal 4297
- and the Analog AD1885 */
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- int old = chip->amplifier;
-#endif
- int oval, val;
-
- chip->amplifier += change;
- oval = snd_cs46xx_codec_read(chip, AC97_POWERDOWN,
- CS46XX_PRIMARY_CODEC_INDEX);
- val = oval;
- if (chip->amplifier) {
- /* Turn the EAPD amp on */
- val |= 0x8000;
- } else {
- /* Turn the EAPD amp off */
- val &= ~0x8000;
- }
- if (val != oval) {
- snd_cs46xx_codec_write(chip, AC97_POWERDOWN, val,
- CS46XX_PRIMARY_CODEC_INDEX);
- if (chip->eapd_switch)
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->eapd_switch->id);
- }
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- if (chip->amplifier && !old) {
- voyetra_setup_eapd_slot(chip);
- }
-#endif
-}
-
-static void hercules_init(struct snd_cs46xx *chip)
-{
- /* default: AMP off, and SPDIF input optical */
- snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0);
- snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0);
-}
-
-
-/*
- * Game Theatre XP card - EGPIO[2] is used to enable the external amp.
- */
-static void amp_hercules(struct snd_cs46xx *chip, int change)
-{
- int old = chip->amplifier;
- int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
- int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR);
-
- chip->amplifier += change;
- if (chip->amplifier && !old) {
- snd_printdd ("Hercules amplifier ON\n");
-
- snd_cs46xx_pokeBA0(chip, BA0_EGPIODR,
- EGPIODR_GPOE2 | val1); /* enable EGPIO2 output */
- snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR,
- EGPIOPTR_GPPT2 | val2); /* open-drain on output */
- } else if (old && !chip->amplifier) {
- snd_printdd ("Hercules amplifier OFF\n");
- snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, val1 & ~EGPIODR_GPOE2); /* disable */
- snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT2); /* disable */
- }
-}
-
-static void voyetra_mixer_init (struct snd_cs46xx *chip)
-{
- snd_printdd ("initializing Voyetra mixer\n");
-
- /* Enable SPDIF out */
- snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0);
- snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0);
-}
-
-static void hercules_mixer_init (struct snd_cs46xx *chip)
-{
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- unsigned int idx;
- int err;
- struct snd_card *card = chip->card;
-#endif
-
- /* set EGPIO to default */
- hercules_init(chip);
-
- snd_printdd ("initializing Hercules mixer\n");
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- if (chip->in_suspend)
- return;
-
- for (idx = 0 ; idx < ARRAY_SIZE(snd_hercules_controls); idx++) {
- struct snd_kcontrol *kctl;
-
- kctl = snd_ctl_new1(&snd_hercules_controls[idx], chip);
- if ((err = snd_ctl_add(card, kctl)) < 0) {
- printk (KERN_ERR "cs46xx: failed to initialize Hercules mixer (%d)\n",err);
- break;
- }
- }
-#endif
-}
-
-
-#if 0
-/*
- * Untested
- */
-
-static void amp_voyetra_4294(struct snd_cs46xx *chip, int change)
-{
- chip->amplifier += change;
-
- if (chip->amplifier) {
- /* Switch the GPIO pins 7 and 8 to open drain */
- snd_cs46xx_codec_write(chip, 0x4C,
- snd_cs46xx_codec_read(chip, 0x4C) & 0xFE7F);
- snd_cs46xx_codec_write(chip, 0x4E,
- snd_cs46xx_codec_read(chip, 0x4E) | 0x0180);
- /* Now wake the AMP (this might be backwards) */
- snd_cs46xx_codec_write(chip, 0x54,
- snd_cs46xx_codec_read(chip, 0x54) & ~0x0180);
- } else {
- snd_cs46xx_codec_write(chip, 0x54,
- snd_cs46xx_codec_read(chip, 0x54) | 0x0180);
- }
-}
-#endif
-
-
-/*
- * Handle the CLKRUN on a thinkpad. We must disable CLKRUN support
- * whenever we need to beat on the chip.
- *
- * The original idea and code for this hack comes from David Kaiser at
- * Linuxcare. Perhaps one day Crystal will document their chips well
- * enough to make them useful.
- */
-
-static void clkrun_hack(struct snd_cs46xx *chip, int change)
-{
- u16 control, nval;
-
- if (!chip->acpi_port)
- return;
-
- chip->amplifier += change;
-
- /* Read ACPI port */
- nval = control = inw(chip->acpi_port + 0x10);
-
- /* Flip CLKRUN off while running */
- if (! chip->amplifier)
- nval |= 0x2000;
- else
- nval &= ~0x2000;
- if (nval != control)
- outw(nval, chip->acpi_port + 0x10);
-}
-
-
-/*
- * detect intel piix4
- */
-static void clkrun_init(struct snd_cs46xx *chip)
-{
- struct pci_dev *pdev;
- u8 pp;
-
- chip->acpi_port = 0;
-
- pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
- if (pdev == NULL)
- return; /* Not a thinkpad thats for sure */
-
- /* Find the control port */
- pci_read_config_byte(pdev, 0x41, &pp);
- chip->acpi_port = pp << 8;
- pci_dev_put(pdev);
-}
-
-
-/*
- * Card subid table
- */
-
-struct cs_card_type
-{
- u16 vendor;
- u16 id;
- char *name;
- void (*init)(struct snd_cs46xx *);
- void (*amp)(struct snd_cs46xx *, int);
- void (*active)(struct snd_cs46xx *, int);
- void (*mixer_init)(struct snd_cs46xx *);
-};
-
-static struct cs_card_type __devinitdata cards[] = {
- {
- .vendor = 0x1489,
- .id = 0x7001,
- .name = "Genius Soundmaker 128 value",
- /* nothing special */
- },
- {
- .vendor = 0x5053,
- .id = 0x3357,
- .name = "Voyetra",
- .amp = amp_voyetra,
- .mixer_init = voyetra_mixer_init,
- },
- {
- .vendor = 0x1071,
- .id = 0x6003,
- .name = "Mitac MI6020/21",
- .amp = amp_voyetra,
- },
- /* Hercules Game Theatre XP */
- {
- .vendor = 0x14af, /* Guillemot Corporation */
- .id = 0x0050,
- .name = "Hercules Game Theatre XP",
- .amp = amp_hercules,
- .mixer_init = hercules_mixer_init,
- },
- {
- .vendor = 0x1681,
- .id = 0x0050,
- .name = "Hercules Game Theatre XP",
- .amp = amp_hercules,
- .mixer_init = hercules_mixer_init,
- },
- {
- .vendor = 0x1681,
- .id = 0x0051,
- .name = "Hercules Game Theatre XP",
- .amp = amp_hercules,
- .mixer_init = hercules_mixer_init,
-
- },
- {
- .vendor = 0x1681,
- .id = 0x0052,
- .name = "Hercules Game Theatre XP",
- .amp = amp_hercules,
- .mixer_init = hercules_mixer_init,
- },
- {
- .vendor = 0x1681,
- .id = 0x0053,
- .name = "Hercules Game Theatre XP",
- .amp = amp_hercules,
- .mixer_init = hercules_mixer_init,
- },
- {
- .vendor = 0x1681,
- .id = 0x0054,
- .name = "Hercules Game Theatre XP",
- .amp = amp_hercules,
- .mixer_init = hercules_mixer_init,
- },
- /* Herculess Fortissimo */
- {
- .vendor = 0x1681,
- .id = 0xa010,
- .name = "Hercules Gamesurround Fortissimo II",
- },
- {
- .vendor = 0x1681,
- .id = 0xa011,
- .name = "Hercules Gamesurround Fortissimo III 7.1",
- },
- /* Teratec */
- {
- .vendor = 0x153b,
- .id = 0x112e,
- .name = "Terratec DMX XFire 1024",
- },
- {
- .vendor = 0x153b,
- .id = 0x1136,
- .name = "Terratec SiXPack 5.1",
- },
- /* Not sure if the 570 needs the clkrun hack */
- {
- .vendor = PCI_VENDOR_ID_IBM,
- .id = 0x0132,
- .name = "Thinkpad 570",
- .init = clkrun_init,
- .active = clkrun_hack,
- },
- {
- .vendor = PCI_VENDOR_ID_IBM,
- .id = 0x0153,
- .name = "Thinkpad 600X/A20/T20",
- .init = clkrun_init,
- .active = clkrun_hack,
- },
- {
- .vendor = PCI_VENDOR_ID_IBM,
- .id = 0x1010,
- .name = "Thinkpad 600E (unsupported)",
- },
- {} /* terminator */
-};
-
-
-/*
- * APM support
- */
-#ifdef CONFIG_PM
-static unsigned int saved_regs[] = {
- BA0_ACOSV,
- /*BA0_ASER_FADDR,*/
- BA0_ASER_MASTER,
- BA1_PVOL,
- BA1_CVOL,
-};
-
-int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_cs46xx *chip = card->private_data;
- int i, amp_saved;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- chip->in_suspend = 1;
- snd_pcm_suspend_all(chip->pcm);
- // chip->ac97_powerdown = snd_cs46xx_codec_read(chip, AC97_POWER_CONTROL);
- // chip->ac97_general_purpose = snd_cs46xx_codec_read(chip, BA0_AC97_GENERAL_PURPOSE);
-
- snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
- snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
-
- /* save some registers */
- for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
- chip->saved_regs[i] = snd_cs46xx_peekBA0(chip, saved_regs[i]);
-
- amp_saved = chip->amplifier;
- /* turn off amp */
- chip->amplifier_ctrl(chip, -chip->amplifier);
- snd_cs46xx_hw_stop(chip);
- /* disable CLKRUN */
- chip->active_ctrl(chip, -chip->amplifier);
- chip->amplifier = amp_saved; /* restore the status */
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-int snd_cs46xx_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_cs46xx *chip = card->private_data;
- int amp_saved;
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- int i;
-#endif
- unsigned int tmp;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "cs46xx: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
-
- amp_saved = chip->amplifier;
- chip->amplifier = 0;
- chip->active_ctrl(chip, 1); /* force to on */
-
- snd_cs46xx_chip_init(chip);
-
- snd_cs46xx_reset(chip);
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- cs46xx_dsp_resume(chip);
- /* restore some registers */
- for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
- snd_cs46xx_pokeBA0(chip, saved_regs[i], chip->saved_regs[i]);
-#else
- snd_cs46xx_download_image(chip);
-#endif
-
-#if 0
- snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE,
- chip->ac97_general_purpose);
- snd_cs46xx_codec_write(chip, AC97_POWER_CONTROL,
- chip->ac97_powerdown);
- mdelay(10);
- snd_cs46xx_codec_write(chip, BA0_AC97_POWERDOWN,
- chip->ac97_powerdown);
- mdelay(5);
-#endif
-
- snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
- snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
-
- /*
- * Stop capture DMA.
- */
- tmp = snd_cs46xx_peek(chip, BA1_CCTL);
- chip->capt.ctl = tmp & 0x0000ffff;
- snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000);
-
- mdelay(5);
-
- /* reset playback/capture */
- snd_cs46xx_set_play_sample_rate(chip, 8000);
- snd_cs46xx_set_capture_sample_rate(chip, 8000);
- snd_cs46xx_proc_start(chip);
-
- cs46xx_enable_stream_irqs(chip);
-
- if (amp_saved)
- chip->amplifier_ctrl(chip, 1); /* turn amp on */
- else
- chip->active_ctrl(chip, -1); /* disable CLKRUN */
- chip->amplifier = amp_saved;
- chip->in_suspend = 0;
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif /* CONFIG_PM */
-
-
-/*
- */
-
-int __devinit snd_cs46xx_create(struct snd_card *card,
- struct pci_dev * pci,
- int external_amp, int thinkpad,
- struct snd_cs46xx ** rchip)
-{
- struct snd_cs46xx *chip;
- int err, idx;
- struct snd_cs46xx_region *region;
- struct cs_card_type *cp;
- u16 ss_card, ss_vendor;
- static struct snd_device_ops ops = {
- .dev_free = snd_cs46xx_dev_free,
- };
-
- *rchip = NULL;
-
- /* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
- return err;
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
- spin_lock_init(&chip->reg_lock);
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- mutex_init(&chip->spos_mutex);
-#endif
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
- chip->ba0_addr = pci_resource_start(pci, 0);
- chip->ba1_addr = pci_resource_start(pci, 1);
- if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 ||
- chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) {
- snd_printk(KERN_ERR "wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n",
- chip->ba0_addr, chip->ba1_addr);
- snd_cs46xx_free(chip);
- return -ENOMEM;
- }
-
- region = &chip->region.name.ba0;
- strcpy(region->name, "CS46xx_BA0");
- region->base = chip->ba0_addr;
- region->size = CS46XX_BA0_SIZE;
-
- region = &chip->region.name.data0;
- strcpy(region->name, "CS46xx_BA1_data0");
- region->base = chip->ba1_addr + BA1_SP_DMEM0;
- region->size = CS46XX_BA1_DATA0_SIZE;
-
- region = &chip->region.name.data1;
- strcpy(region->name, "CS46xx_BA1_data1");
- region->base = chip->ba1_addr + BA1_SP_DMEM1;
- region->size = CS46XX_BA1_DATA1_SIZE;
-
- region = &chip->region.name.pmem;
- strcpy(region->name, "CS46xx_BA1_pmem");
- region->base = chip->ba1_addr + BA1_SP_PMEM;
- region->size = CS46XX_BA1_PRG_SIZE;
-
- region = &chip->region.name.reg;
- strcpy(region->name, "CS46xx_BA1_reg");
- region->base = chip->ba1_addr + BA1_SP_REG;
- region->size = CS46XX_BA1_REG_SIZE;
-
- /* set up amp and clkrun hack */
- pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &ss_vendor);
- pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &ss_card);
-
- for (cp = &cards[0]; cp->name; cp++) {
- if (cp->vendor == ss_vendor && cp->id == ss_card) {
- snd_printdd ("hack for %s enabled\n", cp->name);
-
- chip->amplifier_ctrl = cp->amp;
- chip->active_ctrl = cp->active;
- chip->mixer_init = cp->mixer_init;
-
- if (cp->init)
- cp->init(chip);
- break;
- }
- }
-
- if (external_amp) {
- snd_printk(KERN_INFO "Crystal EAPD support forced on.\n");
- chip->amplifier_ctrl = amp_voyetra;
- }
-
- if (thinkpad) {
- snd_printk(KERN_INFO "Activating CLKRUN hack for Thinkpad.\n");
- chip->active_ctrl = clkrun_hack;
- clkrun_init(chip);
- }
-
- if (chip->amplifier_ctrl == NULL)
- chip->amplifier_ctrl = amp_none;
- if (chip->active_ctrl == NULL)
- chip->active_ctrl = amp_none;
-
- chip->active_ctrl(chip, 1); /* enable CLKRUN */
-
- pci_set_master(pci);
-
- for (idx = 0; idx < 5; idx++) {
- region = &chip->region.idx[idx];
- if ((region->resource = request_mem_region(region->base, region->size,
- region->name)) == NULL) {
- snd_printk(KERN_ERR "unable to request memory region 0x%lx-0x%lx\n",
- region->base, region->base + region->size - 1);
- snd_cs46xx_free(chip);
- return -EBUSY;
- }
- region->remap_addr = ioremap_nocache(region->base, region->size);
- if (region->remap_addr == NULL) {
- snd_printk(KERN_ERR "%s ioremap problem\n", region->name);
- snd_cs46xx_free(chip);
- return -ENOMEM;
- }
- }
-
- if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_cs46xx_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
- chip->dsp_spos_instance = cs46xx_dsp_spos_create(chip);
- if (chip->dsp_spos_instance == NULL) {
- snd_cs46xx_free(chip);
- return -ENOMEM;
- }
-#endif
-
- err = snd_cs46xx_chip_init(chip);
- if (err < 0) {
- snd_cs46xx_free(chip);
- return err;
- }
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_cs46xx_free(chip);
- return err;
- }
-
- snd_cs46xx_proc_init(card, chip);
-
-#ifdef CONFIG_PM
- chip->saved_regs = kmalloc(sizeof(*chip->saved_regs) *
- ARRAY_SIZE(saved_regs), GFP_KERNEL);
- if (!chip->saved_regs) {
- snd_cs46xx_free(chip);
- return -ENOMEM;
- }
-#endif
-
- chip->active_ctrl(chip, -1); /* disable CLKRUN */
-
- snd_card_set_dev(card, &pci->dev);
-
- *rchip = chip;
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/cs46xx/cs46xx_lib.h b/ANDROID_3.4.5/sound/pci/cs46xx/cs46xx_lib.h
deleted file mode 100644
index b5189495..00000000
--- a/ANDROID_3.4.5/sound/pci/cs46xx/cs46xx_lib.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifndef __CS46XX_LIB_H__
-#define __CS46XX_LIB_H__
-
-/*
- * constants
- */
-
-#define CS46XX_BA0_SIZE 0x1000
-#define CS46XX_BA1_DATA0_SIZE 0x3000
-#define CS46XX_BA1_DATA1_SIZE 0x3800
-#define CS46XX_BA1_PRG_SIZE 0x7000
-#define CS46XX_BA1_REG_SIZE 0x0100
-
-
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP
-#define CS46XX_MIN_PERIOD_SIZE 64
-#define CS46XX_MAX_PERIOD_SIZE 1024*1024
-#else
-#define CS46XX_MIN_PERIOD_SIZE 2048
-#define CS46XX_MAX_PERIOD_SIZE 2048
-#endif
-
-#define CS46XX_FRAGS 2
-/* #define CS46XX_BUFFER_SIZE CS46XX_MAX_PERIOD_SIZE * CS46XX_FRAGS */
-
-#define SCB_NO_PARENT 0
-#define SCB_ON_PARENT_NEXT_SCB 1
-#define SCB_ON_PARENT_SUBLIST_SCB 2
-
-/* 3*1024 parameter, 3.5*1024 sample, 2*3.5*1024 code */
-#define BA1_DWORD_SIZE (13 * 1024 + 512)
-#define BA1_MEMORY_COUNT 3
-
-/*
- * common I/O routines
- */
-
-static inline void snd_cs46xx_poke(struct snd_cs46xx *chip, unsigned long reg, unsigned int val)
-{
- unsigned int bank = reg >> 16;
- unsigned int offset = reg & 0xffff;
-
- /*
- if (bank == 0)
- printk(KERN_DEBUG "snd_cs46xx_poke: %04X - %08X\n",
- reg >> 2,val);
- */
- writel(val, chip->region.idx[bank+1].remap_addr + offset);
-}
-
-static inline unsigned int snd_cs46xx_peek(struct snd_cs46xx *chip, unsigned long reg)
-{
- unsigned int bank = reg >> 16;
- unsigned int offset = reg & 0xffff;
- return readl(chip->region.idx[bank+1].remap_addr + offset);
-}
-
-static inline void snd_cs46xx_pokeBA0(struct snd_cs46xx *chip, unsigned long offset, unsigned int val)
-{
- writel(val, chip->region.name.ba0.remap_addr + offset);
-}
-
-static inline unsigned int snd_cs46xx_peekBA0(struct snd_cs46xx *chip, unsigned long offset)
-{
- return readl(chip->region.name.ba0.remap_addr + offset);
-}
-
-struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip);
-void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip);
-int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module);
-#ifdef CONFIG_PM
-int cs46xx_dsp_resume(struct snd_cs46xx * chip);
-#endif
-struct dsp_symbol_entry *cs46xx_dsp_lookup_symbol (struct snd_cs46xx * chip, char * symbol_name,
- int symbol_type);
-#ifdef CONFIG_PROC_FS
-int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip);
-int cs46xx_dsp_proc_done (struct snd_cs46xx *chip);
-#else
-#define cs46xx_dsp_proc_init(card, chip)
-#define cs46xx_dsp_proc_done(chip)
-#endif
-int cs46xx_dsp_scb_and_task_init (struct snd_cs46xx *chip);
-int snd_cs46xx_download (struct snd_cs46xx *chip, u32 *src, unsigned long offset,
- unsigned long len);
-int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip, unsigned long offset, unsigned long len);
-int cs46xx_dsp_enable_spdif_out (struct snd_cs46xx *chip);
-int cs46xx_dsp_enable_spdif_hw (struct snd_cs46xx *chip);
-int cs46xx_dsp_disable_spdif_out (struct snd_cs46xx *chip);
-int cs46xx_dsp_enable_spdif_in (struct snd_cs46xx *chip);
-int cs46xx_dsp_disable_spdif_in (struct snd_cs46xx *chip);
-int cs46xx_dsp_enable_pcm_capture (struct snd_cs46xx *chip);
-int cs46xx_dsp_disable_pcm_capture (struct snd_cs46xx *chip);
-int cs46xx_dsp_enable_adc_capture (struct snd_cs46xx *chip);
-int cs46xx_dsp_disable_adc_capture (struct snd_cs46xx *chip);
-int cs46xx_poke_via_dsp (struct snd_cs46xx *chip, u32 address, u32 data);
-struct dsp_scb_descriptor * cs46xx_dsp_create_scb (struct snd_cs46xx *chip, char * name,
- u32 * scb_data, u32 dest);
-#ifdef CONFIG_PROC_FS
-void cs46xx_dsp_proc_free_scb_desc (struct dsp_scb_descriptor * scb);
-void cs46xx_dsp_proc_register_scb_desc (struct snd_cs46xx *chip,
- struct dsp_scb_descriptor * scb);
-#else
-#define cs46xx_dsp_proc_free_scb_desc(scb)
-#define cs46xx_dsp_proc_register_scb_desc(chip, scb)
-#endif
-struct dsp_scb_descriptor * cs46xx_dsp_create_timing_master_scb (struct snd_cs46xx *chip);
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_codec_out_scb(struct snd_cs46xx * chip,
- char * codec_name, u16 channel_disp, u16 fifo_addr,
- u16 child_scb_addr, u32 dest,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type);
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_codec_in_scb(struct snd_cs46xx * chip, char * codec_name,
- u16 channel_disp, u16 fifo_addr,
- u16 sample_buffer_addr, u32 dest,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type);
-void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip,
- struct dsp_scb_descriptor * scb);
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_codec_in_scb(struct snd_cs46xx * chip, char * codec_name,
- u16 channel_disp, u16 fifo_addr,
- u16 sample_buffer_addr, u32 dest,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type);
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_src_task_scb(struct snd_cs46xx * chip, char * scb_name,
- int sample_rate, u16 src_buffer_addr,
- u16 src_delay_buffer_addr, u32 dest,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type, int pass_through);
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_mix_only_scb(struct snd_cs46xx * chip, char * scb_name,
- u16 mix_buffer_addr, u32 dest,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type);
-
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_vari_decimate_scb(struct snd_cs46xx * chip, char * scb_name,
- u16 vari_buffer_addr0, u16 vari_buffer_addr1, u32 dest,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type);
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_asynch_fg_rx_scb(struct snd_cs46xx * chip, char * scb_name,
- u32 dest, u16 hfg_scb_address, u16 asynch_buffer_address,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type);
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_spio_write_scb(struct snd_cs46xx * chip, char * scb_name, u32 dest,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type);
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_mix_to_ostream_scb(struct snd_cs46xx * chip, char * scb_name,
- u16 mix_buffer_addr, u16 writeback_spb, u32 dest,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type);
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_magic_snoop_scb(struct snd_cs46xx * chip, char * scb_name,
- u32 dest, u16 snoop_buffer_address,
- struct dsp_scb_descriptor * snoop_scb,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type);
-struct dsp_pcm_channel_descriptor *
-cs46xx_dsp_create_pcm_channel (struct snd_cs46xx * chip, u32 sample_rate,
- void * private_data, u32 hw_dma_addr,
- int pcm_channel_id);
-void cs46xx_dsp_destroy_pcm_channel (struct snd_cs46xx * chip,
- struct dsp_pcm_channel_descriptor * pcm_channel);
-int cs46xx_dsp_pcm_unlink (struct snd_cs46xx * chip,
- struct dsp_pcm_channel_descriptor * pcm_channel);
-int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip,
- struct dsp_pcm_channel_descriptor * pcm_channel);
-struct dsp_scb_descriptor *
-cs46xx_add_record_source (struct snd_cs46xx *chip, struct dsp_scb_descriptor * source,
- u16 addr, char * scb_name);
-int cs46xx_src_unlink(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src);
-int cs46xx_src_link(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src);
-int cs46xx_iec958_pre_open (struct snd_cs46xx *chip);
-int cs46xx_iec958_post_close (struct snd_cs46xx *chip);
-int cs46xx_dsp_pcm_channel_set_period (struct snd_cs46xx * chip,
- struct dsp_pcm_channel_descriptor * pcm_channel,
- int period_size);
-int cs46xx_dsp_pcm_ostream_set_period (struct snd_cs46xx * chip, int period_size);
-int cs46xx_dsp_set_dac_volume (struct snd_cs46xx * chip, u16 left, u16 right);
-int cs46xx_dsp_set_iec958_volume (struct snd_cs46xx * chip, u16 left, u16 right);
-#endif /* __CS46XX_LIB_H__ */
diff --git a/ANDROID_3.4.5/sound/pci/cs46xx/dsp_spos.c b/ANDROID_3.4.5/sound/pci/cs46xx/dsp_spos.c
deleted file mode 100644
index e3772871..00000000
--- a/ANDROID_3.4.5/sound/pci/cs46xx/dsp_spos.c
+++ /dev/null
@@ -1,2017 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- * 2002-07 Benny Sjostrand benny@hostmobility.com
- */
-
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/mutex.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/info.h>
-#include <sound/asoundef.h>
-#include <sound/cs46xx.h>
-
-#include "cs46xx_lib.h"
-#include "dsp_spos.h"
-
-static int cs46xx_dsp_async_init (struct snd_cs46xx *chip,
- struct dsp_scb_descriptor * fg_entry);
-
-static enum wide_opcode wide_opcodes[] = {
- WIDE_FOR_BEGIN_LOOP,
- WIDE_FOR_BEGIN_LOOP2,
- WIDE_COND_GOTO_ADDR,
- WIDE_COND_GOTO_CALL,
- WIDE_TBEQ_COND_GOTO_ADDR,
- WIDE_TBEQ_COND_CALL_ADDR,
- WIDE_TBEQ_NCOND_GOTO_ADDR,
- WIDE_TBEQ_NCOND_CALL_ADDR,
- WIDE_TBEQ_COND_GOTO1_ADDR,
- WIDE_TBEQ_COND_CALL1_ADDR,
- WIDE_TBEQ_NCOND_GOTOI_ADDR,
- WIDE_TBEQ_NCOND_CALL1_ADDR
-};
-
-static int shadow_and_reallocate_code (struct snd_cs46xx * chip, u32 * data, u32 size,
- u32 overlay_begin_address)
-{
- unsigned int i = 0, j, nreallocated = 0;
- u32 hival,loval,address;
- u32 mop_operands,mop_type,wide_op;
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- if (snd_BUG_ON(size %2))
- return -EINVAL;
-
- while (i < size) {
- loval = data[i++];
- hival = data[i++];
-
- if (ins->code.offset > 0) {
- mop_operands = (hival >> 6) & 0x03fff;
- mop_type = mop_operands >> 10;
-
- /* check for wide type instruction */
- if (mop_type == 0 &&
- (mop_operands & WIDE_LADD_INSTR_MASK) == 0 &&
- (mop_operands & WIDE_INSTR_MASK) != 0) {
- wide_op = loval & 0x7f;
- for (j = 0;j < ARRAY_SIZE(wide_opcodes); ++j) {
- if (wide_opcodes[j] == wide_op) {
- /* need to reallocate instruction */
- address = (hival & 0x00FFF) << 5;
- address |= loval >> 15;
-
- snd_printdd("handle_wideop[1]: %05x:%05x addr %04x\n",hival,loval,address);
-
- if ( !(address & 0x8000) ) {
- address += (ins->code.offset / 2) - overlay_begin_address;
- } else {
- snd_printdd("handle_wideop[1]: ROM symbol not reallocated\n");
- }
-
- hival &= 0xFF000;
- loval &= 0x07FFF;
-
- hival |= ( (address >> 5) & 0x00FFF);
- loval |= ( (address << 15) & 0xF8000);
-
- address = (hival & 0x00FFF) << 5;
- address |= loval >> 15;
-
- snd_printdd("handle_wideop:[2] %05x:%05x addr %04x\n",hival,loval,address);
- nreallocated ++;
- } /* wide_opcodes[j] == wide_op */
- } /* for */
- } /* mod_type == 0 ... */
- } /* ins->code.offset > 0 */
-
- ins->code.data[ins->code.size++] = loval;
- ins->code.data[ins->code.size++] = hival;
- }
-
- snd_printdd("dsp_spos: %d instructions reallocated\n",nreallocated);
- return nreallocated;
-}
-
-static struct dsp_segment_desc * get_segment_desc (struct dsp_module_desc * module, int seg_type)
-{
- int i;
- for (i = 0;i < module->nsegments; ++i) {
- if (module->segments[i].segment_type == seg_type) {
- return (module->segments + i);
- }
- }
-
- return NULL;
-};
-
-static int find_free_symbol_index (struct dsp_spos_instance * ins)
-{
- int index = ins->symbol_table.nsymbols,i;
-
- for (i = ins->symbol_table.highest_frag_index; i < ins->symbol_table.nsymbols; ++i) {
- if (ins->symbol_table.symbols[i].deleted) {
- index = i;
- break;
- }
- }
-
- return index;
-}
-
-static int add_symbols (struct snd_cs46xx * chip, struct dsp_module_desc * module)
-{
- int i;
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- if (module->symbol_table.nsymbols > 0) {
- if (!strcmp(module->symbol_table.symbols[0].symbol_name, "OVERLAYBEGINADDRESS") &&
- module->symbol_table.symbols[0].symbol_type == SYMBOL_CONSTANT ) {
- module->overlay_begin_address = module->symbol_table.symbols[0].address;
- }
- }
-
- for (i = 0;i < module->symbol_table.nsymbols; ++i) {
- if (ins->symbol_table.nsymbols == (DSP_MAX_SYMBOLS - 1)) {
- snd_printk(KERN_ERR "dsp_spos: symbol table is full\n");
- return -ENOMEM;
- }
-
-
- if (cs46xx_dsp_lookup_symbol(chip,
- module->symbol_table.symbols[i].symbol_name,
- module->symbol_table.symbols[i].symbol_type) == NULL) {
-
- ins->symbol_table.symbols[ins->symbol_table.nsymbols] = module->symbol_table.symbols[i];
- ins->symbol_table.symbols[ins->symbol_table.nsymbols].address += ((ins->code.offset / 2) - module->overlay_begin_address);
- ins->symbol_table.symbols[ins->symbol_table.nsymbols].module = module;
- ins->symbol_table.symbols[ins->symbol_table.nsymbols].deleted = 0;
-
- if (ins->symbol_table.nsymbols > ins->symbol_table.highest_frag_index)
- ins->symbol_table.highest_frag_index = ins->symbol_table.nsymbols;
-
- ins->symbol_table.nsymbols++;
- } else {
- /* if (0) printk ("dsp_spos: symbol <%s> duplicated, probably nothing wrong with that (Cirrus?)\n",
- module->symbol_table.symbols[i].symbol_name); */
- }
- }
-
- return 0;
-}
-
-static struct dsp_symbol_entry *
-add_symbol (struct snd_cs46xx * chip, char * symbol_name, u32 address, int type)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- struct dsp_symbol_entry * symbol = NULL;
- int index;
-
- if (ins->symbol_table.nsymbols == (DSP_MAX_SYMBOLS - 1)) {
- snd_printk(KERN_ERR "dsp_spos: symbol table is full\n");
- return NULL;
- }
-
- if (cs46xx_dsp_lookup_symbol(chip,
- symbol_name,
- type) != NULL) {
- snd_printk(KERN_ERR "dsp_spos: symbol <%s> duplicated\n", symbol_name);
- return NULL;
- }
-
- index = find_free_symbol_index (ins);
-
- strcpy (ins->symbol_table.symbols[index].symbol_name, symbol_name);
- ins->symbol_table.symbols[index].address = address;
- ins->symbol_table.symbols[index].symbol_type = type;
- ins->symbol_table.symbols[index].module = NULL;
- ins->symbol_table.symbols[index].deleted = 0;
- symbol = (ins->symbol_table.symbols + index);
-
- if (index > ins->symbol_table.highest_frag_index)
- ins->symbol_table.highest_frag_index = index;
-
- if (index == ins->symbol_table.nsymbols)
- ins->symbol_table.nsymbols++; /* no frag. in list */
-
- return symbol;
-}
-
-struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip)
-{
- struct dsp_spos_instance * ins = kzalloc(sizeof(struct dsp_spos_instance), GFP_KERNEL);
-
- if (ins == NULL)
- return NULL;
-
- /* better to use vmalloc for this big table */
- ins->symbol_table.symbols = vmalloc(sizeof(struct dsp_symbol_entry) *
- DSP_MAX_SYMBOLS);
- ins->code.data = kmalloc(DSP_CODE_BYTE_SIZE, GFP_KERNEL);
- ins->modules = kmalloc(sizeof(struct dsp_module_desc) * DSP_MAX_MODULES, GFP_KERNEL);
- if (!ins->symbol_table.symbols || !ins->code.data || !ins->modules) {
- cs46xx_dsp_spos_destroy(chip);
- goto error;
- }
- ins->symbol_table.nsymbols = 0;
- ins->symbol_table.highest_frag_index = 0;
- ins->code.offset = 0;
- ins->code.size = 0;
- ins->nscb = 0;
- ins->ntask = 0;
- ins->nmodules = 0;
-
- /* default SPDIF input sample rate
- to 48000 khz */
- ins->spdif_in_sample_rate = 48000;
-
- /* maximize volume */
- ins->dac_volume_right = 0x8000;
- ins->dac_volume_left = 0x8000;
- ins->spdif_input_volume_right = 0x8000;
- ins->spdif_input_volume_left = 0x8000;
-
- /* set left and right validity bits and
- default channel status */
- ins->spdif_csuv_default =
- ins->spdif_csuv_stream =
- /* byte 0 */ ((unsigned int)_wrap_all_bits( (SNDRV_PCM_DEFAULT_CON_SPDIF & 0xff)) << 24) |
- /* byte 1 */ ((unsigned int)_wrap_all_bits( ((SNDRV_PCM_DEFAULT_CON_SPDIF >> 8) & 0xff)) << 16) |
- /* byte 3 */ (unsigned int)_wrap_all_bits( (SNDRV_PCM_DEFAULT_CON_SPDIF >> 24) & 0xff) |
- /* left and right validity bits */ (1 << 13) | (1 << 12);
-
- return ins;
-
-error:
- kfree(ins->modules);
- kfree(ins->code.data);
- vfree(ins->symbol_table.symbols);
- kfree(ins);
- return NULL;
-}
-
-void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip)
-{
- int i;
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- if (snd_BUG_ON(!ins))
- return;
-
- mutex_lock(&chip->spos_mutex);
- for (i = 0; i < ins->nscb; ++i) {
- if (ins->scbs[i].deleted) continue;
-
- cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) );
-#ifdef CONFIG_PM
- kfree(ins->scbs[i].data);
-#endif
- }
-
- kfree(ins->code.data);
- vfree(ins->symbol_table.symbols);
- kfree(ins->modules);
- kfree(ins);
- mutex_unlock(&chip->spos_mutex);
-}
-
-static int dsp_load_parameter(struct snd_cs46xx *chip,
- struct dsp_segment_desc *parameter)
-{
- u32 doffset, dsize;
-
- if (!parameter) {
- snd_printdd("dsp_spos: module got no parameter segment\n");
- return 0;
- }
-
- doffset = (parameter->offset * 4 + DSP_PARAMETER_BYTE_OFFSET);
- dsize = parameter->size * 4;
-
- snd_printdd("dsp_spos: "
- "downloading parameter data to chip (%08x-%08x)\n",
- doffset,doffset + dsize);
- if (snd_cs46xx_download (chip, parameter->data, doffset, dsize)) {
- snd_printk(KERN_ERR "dsp_spos: "
- "failed to download parameter data to DSP\n");
- return -EINVAL;
- }
- return 0;
-}
-
-static int dsp_load_sample(struct snd_cs46xx *chip,
- struct dsp_segment_desc *sample)
-{
- u32 doffset, dsize;
-
- if (!sample) {
- snd_printdd("dsp_spos: module got no sample segment\n");
- return 0;
- }
-
- doffset = (sample->offset * 4 + DSP_SAMPLE_BYTE_OFFSET);
- dsize = sample->size * 4;
-
- snd_printdd("dsp_spos: downloading sample data to chip (%08x-%08x)\n",
- doffset,doffset + dsize);
-
- if (snd_cs46xx_download (chip,sample->data,doffset,dsize)) {
- snd_printk(KERN_ERR "dsp_spos: failed to sample data to DSP\n");
- return -EINVAL;
- }
- return 0;
-}
-
-int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- struct dsp_segment_desc * code = get_segment_desc (module,SEGTYPE_SP_PROGRAM);
- u32 doffset, dsize;
- int err;
-
- if (ins->nmodules == DSP_MAX_MODULES - 1) {
- snd_printk(KERN_ERR "dsp_spos: to many modules loaded into DSP\n");
- return -ENOMEM;
- }
-
- snd_printdd("dsp_spos: loading module %s into DSP\n", module->module_name);
-
- if (ins->nmodules == 0) {
- snd_printdd("dsp_spos: clearing parameter area\n");
- snd_cs46xx_clear_BA1(chip, DSP_PARAMETER_BYTE_OFFSET, DSP_PARAMETER_BYTE_SIZE);
- }
-
- err = dsp_load_parameter(chip, get_segment_desc(module,
- SEGTYPE_SP_PARAMETER));
- if (err < 0)
- return err;
-
- if (ins->nmodules == 0) {
- snd_printdd("dsp_spos: clearing sample area\n");
- snd_cs46xx_clear_BA1(chip, DSP_SAMPLE_BYTE_OFFSET, DSP_SAMPLE_BYTE_SIZE);
- }
-
- err = dsp_load_sample(chip, get_segment_desc(module,
- SEGTYPE_SP_SAMPLE));
- if (err < 0)
- return err;
-
- if (ins->nmodules == 0) {
- snd_printdd("dsp_spos: clearing code area\n");
- snd_cs46xx_clear_BA1(chip, DSP_CODE_BYTE_OFFSET, DSP_CODE_BYTE_SIZE);
- }
-
- if (code == NULL) {
- snd_printdd("dsp_spos: module got no code segment\n");
- } else {
- if (ins->code.offset + code->size > DSP_CODE_BYTE_SIZE) {
- snd_printk(KERN_ERR "dsp_spos: no space available in DSP\n");
- return -ENOMEM;
- }
-
- module->load_address = ins->code.offset;
- module->overlay_begin_address = 0x000;
-
- /* if module has a code segment it must have
- symbol table */
- if (snd_BUG_ON(!module->symbol_table.symbols))
- return -ENOMEM;
- if (add_symbols(chip,module)) {
- snd_printk(KERN_ERR "dsp_spos: failed to load symbol table\n");
- return -ENOMEM;
- }
-
- doffset = (code->offset * 4 + ins->code.offset * 4 + DSP_CODE_BYTE_OFFSET);
- dsize = code->size * 4;
- snd_printdd("dsp_spos: downloading code to chip (%08x-%08x)\n",
- doffset,doffset + dsize);
-
- module->nfixups = shadow_and_reallocate_code(chip,code->data,code->size,module->overlay_begin_address);
-
- if (snd_cs46xx_download (chip,(ins->code.data + ins->code.offset),doffset,dsize)) {
- snd_printk(KERN_ERR "dsp_spos: failed to download code to DSP\n");
- return -EINVAL;
- }
-
- ins->code.offset += code->size;
- }
-
- /* NOTE: module segments and symbol table must be
- statically allocated. Case that module data is
- not generated by the ospparser */
- ins->modules[ins->nmodules] = *module;
- ins->nmodules++;
-
- return 0;
-}
-
-struct dsp_symbol_entry *
-cs46xx_dsp_lookup_symbol (struct snd_cs46xx * chip, char * symbol_name, int symbol_type)
-{
- int i;
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- for ( i = 0; i < ins->symbol_table.nsymbols; ++i ) {
-
- if (ins->symbol_table.symbols[i].deleted)
- continue;
-
- if (!strcmp(ins->symbol_table.symbols[i].symbol_name,symbol_name) &&
- ins->symbol_table.symbols[i].symbol_type == symbol_type) {
- return (ins->symbol_table.symbols + i);
- }
- }
-
-#if 0
- printk ("dsp_spos: symbol <%s> type %02x not found\n",
- symbol_name,symbol_type);
-#endif
-
- return NULL;
-}
-
-
-#ifdef CONFIG_PROC_FS
-static struct dsp_symbol_entry *
-cs46xx_dsp_lookup_symbol_addr (struct snd_cs46xx * chip, u32 address, int symbol_type)
-{
- int i;
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- for ( i = 0; i < ins->symbol_table.nsymbols; ++i ) {
-
- if (ins->symbol_table.symbols[i].deleted)
- continue;
-
- if (ins->symbol_table.symbols[i].address == address &&
- ins->symbol_table.symbols[i].symbol_type == symbol_type) {
- return (ins->symbol_table.symbols + i);
- }
- }
-
-
- return NULL;
-}
-
-
-static void cs46xx_dsp_proc_symbol_table_read (struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_cs46xx *chip = entry->private_data;
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- int i;
-
- snd_iprintf(buffer, "SYMBOLS:\n");
- for ( i = 0; i < ins->symbol_table.nsymbols; ++i ) {
- char *module_str = "system";
-
- if (ins->symbol_table.symbols[i].deleted)
- continue;
-
- if (ins->symbol_table.symbols[i].module != NULL) {
- module_str = ins->symbol_table.symbols[i].module->module_name;
- }
-
-
- snd_iprintf(buffer, "%04X <%02X> %s [%s]\n",
- ins->symbol_table.symbols[i].address,
- ins->symbol_table.symbols[i].symbol_type,
- ins->symbol_table.symbols[i].symbol_name,
- module_str);
- }
-}
-
-
-static void cs46xx_dsp_proc_modules_read (struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_cs46xx *chip = entry->private_data;
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- int i,j;
-
- mutex_lock(&chip->spos_mutex);
- snd_iprintf(buffer, "MODULES:\n");
- for ( i = 0; i < ins->nmodules; ++i ) {
- snd_iprintf(buffer, "\n%s:\n", ins->modules[i].module_name);
- snd_iprintf(buffer, " %d symbols\n", ins->modules[i].symbol_table.nsymbols);
- snd_iprintf(buffer, " %d fixups\n", ins->modules[i].nfixups);
-
- for (j = 0; j < ins->modules[i].nsegments; ++ j) {
- struct dsp_segment_desc * desc = (ins->modules[i].segments + j);
- snd_iprintf(buffer, " segment %02x offset %08x size %08x\n",
- desc->segment_type,desc->offset, desc->size);
- }
- }
- mutex_unlock(&chip->spos_mutex);
-}
-
-static void cs46xx_dsp_proc_task_tree_read (struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_cs46xx *chip = entry->private_data;
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- int i, j, col;
- void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
-
- mutex_lock(&chip->spos_mutex);
- snd_iprintf(buffer, "TASK TREES:\n");
- for ( i = 0; i < ins->ntask; ++i) {
- snd_iprintf(buffer,"\n%04x %s:\n",ins->tasks[i].address,ins->tasks[i].task_name);
-
- for (col = 0,j = 0;j < ins->tasks[i].size; j++,col++) {
- u32 val;
- if (col == 4) {
- snd_iprintf(buffer,"\n");
- col = 0;
- }
- val = readl(dst + (ins->tasks[i].address + j) * sizeof(u32));
- snd_iprintf(buffer,"%08x ",val);
- }
- }
-
- snd_iprintf(buffer,"\n");
- mutex_unlock(&chip->spos_mutex);
-}
-
-static void cs46xx_dsp_proc_scb_read (struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_cs46xx *chip = entry->private_data;
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- int i;
-
- mutex_lock(&chip->spos_mutex);
- snd_iprintf(buffer, "SCB's:\n");
- for ( i = 0; i < ins->nscb; ++i) {
- if (ins->scbs[i].deleted)
- continue;
- snd_iprintf(buffer,"\n%04x %s:\n\n",ins->scbs[i].address,ins->scbs[i].scb_name);
-
- if (ins->scbs[i].parent_scb_ptr != NULL) {
- snd_iprintf(buffer,"parent [%s:%04x] ",
- ins->scbs[i].parent_scb_ptr->scb_name,
- ins->scbs[i].parent_scb_ptr->address);
- } else snd_iprintf(buffer,"parent [none] ");
-
- snd_iprintf(buffer,"sub_list_ptr [%s:%04x]\nnext_scb_ptr [%s:%04x] task_entry [%s:%04x]\n",
- ins->scbs[i].sub_list_ptr->scb_name,
- ins->scbs[i].sub_list_ptr->address,
- ins->scbs[i].next_scb_ptr->scb_name,
- ins->scbs[i].next_scb_ptr->address,
- ins->scbs[i].task_entry->symbol_name,
- ins->scbs[i].task_entry->address);
- }
-
- snd_iprintf(buffer,"\n");
- mutex_unlock(&chip->spos_mutex);
-}
-
-static void cs46xx_dsp_proc_parameter_dump_read (struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_cs46xx *chip = entry->private_data;
- /*struct dsp_spos_instance * ins = chip->dsp_spos_instance; */
- unsigned int i, col = 0;
- void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
- struct dsp_symbol_entry * symbol;
-
- for (i = 0;i < DSP_PARAMETER_BYTE_SIZE; i += sizeof(u32),col ++) {
- if (col == 4) {
- snd_iprintf(buffer,"\n");
- col = 0;
- }
-
- if ( (symbol = cs46xx_dsp_lookup_symbol_addr (chip,i / sizeof(u32), SYMBOL_PARAMETER)) != NULL) {
- col = 0;
- snd_iprintf (buffer,"\n%s:\n",symbol->symbol_name);
- }
-
- if (col == 0) {
- snd_iprintf(buffer, "%04X ", i / (unsigned int)sizeof(u32));
- }
-
- snd_iprintf(buffer,"%08X ",readl(dst + i));
- }
-}
-
-static void cs46xx_dsp_proc_sample_dump_read (struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_cs46xx *chip = entry->private_data;
- int i,col = 0;
- void __iomem *dst = chip->region.idx[2].remap_addr;
-
- snd_iprintf(buffer,"PCMREADER:\n");
- for (i = PCM_READER_BUF1;i < PCM_READER_BUF1 + 0x30; i += sizeof(u32),col ++) {
- if (col == 4) {
- snd_iprintf(buffer,"\n");
- col = 0;
- }
-
- if (col == 0) {
- snd_iprintf(buffer, "%04X ",i);
- }
-
- snd_iprintf(buffer,"%08X ",readl(dst + i));
- }
-
- snd_iprintf(buffer,"\nMIX_SAMPLE_BUF1:\n");
-
- col = 0;
- for (i = MIX_SAMPLE_BUF1;i < MIX_SAMPLE_BUF1 + 0x40; i += sizeof(u32),col ++) {
- if (col == 4) {
- snd_iprintf(buffer,"\n");
- col = 0;
- }
-
- if (col == 0) {
- snd_iprintf(buffer, "%04X ",i);
- }
-
- snd_iprintf(buffer,"%08X ",readl(dst + i));
- }
-
- snd_iprintf(buffer,"\nSRC_TASK_SCB1:\n");
- col = 0;
- for (i = 0x2480 ; i < 0x2480 + 0x40 ; i += sizeof(u32),col ++) {
- if (col == 4) {
- snd_iprintf(buffer,"\n");
- col = 0;
- }
-
- if (col == 0) {
- snd_iprintf(buffer, "%04X ",i);
- }
-
- snd_iprintf(buffer,"%08X ",readl(dst + i));
- }
-
-
- snd_iprintf(buffer,"\nSPDIFO_BUFFER:\n");
- col = 0;
- for (i = SPDIFO_IP_OUTPUT_BUFFER1;i < SPDIFO_IP_OUTPUT_BUFFER1 + 0x30; i += sizeof(u32),col ++) {
- if (col == 4) {
- snd_iprintf(buffer,"\n");
- col = 0;
- }
-
- if (col == 0) {
- snd_iprintf(buffer, "%04X ",i);
- }
-
- snd_iprintf(buffer,"%08X ",readl(dst + i));
- }
-
- snd_iprintf(buffer,"\n...\n");
- col = 0;
-
- for (i = SPDIFO_IP_OUTPUT_BUFFER1+0xD0;i < SPDIFO_IP_OUTPUT_BUFFER1 + 0x110; i += sizeof(u32),col ++) {
- if (col == 4) {
- snd_iprintf(buffer,"\n");
- col = 0;
- }
-
- if (col == 0) {
- snd_iprintf(buffer, "%04X ",i);
- }
-
- snd_iprintf(buffer,"%08X ",readl(dst + i));
- }
-
-
- snd_iprintf(buffer,"\nOUTPUT_SNOOP:\n");
- col = 0;
- for (i = OUTPUT_SNOOP_BUFFER;i < OUTPUT_SNOOP_BUFFER + 0x40; i += sizeof(u32),col ++) {
- if (col == 4) {
- snd_iprintf(buffer,"\n");
- col = 0;
- }
-
- if (col == 0) {
- snd_iprintf(buffer, "%04X ",i);
- }
-
- snd_iprintf(buffer,"%08X ",readl(dst + i));
- }
-
- snd_iprintf(buffer,"\nCODEC_INPUT_BUF1: \n");
- col = 0;
- for (i = CODEC_INPUT_BUF1;i < CODEC_INPUT_BUF1 + 0x40; i += sizeof(u32),col ++) {
- if (col == 4) {
- snd_iprintf(buffer,"\n");
- col = 0;
- }
-
- if (col == 0) {
- snd_iprintf(buffer, "%04X ",i);
- }
-
- snd_iprintf(buffer,"%08X ",readl(dst + i));
- }
-#if 0
- snd_iprintf(buffer,"\nWRITE_BACK_BUF1: \n");
- col = 0;
- for (i = WRITE_BACK_BUF1;i < WRITE_BACK_BUF1 + 0x40; i += sizeof(u32),col ++) {
- if (col == 4) {
- snd_iprintf(buffer,"\n");
- col = 0;
- }
-
- if (col == 0) {
- snd_iprintf(buffer, "%04X ",i);
- }
-
- snd_iprintf(buffer,"%08X ",readl(dst + i));
- }
-#endif
-
- snd_iprintf(buffer,"\nSPDIFI_IP_OUTPUT_BUFFER1: \n");
- col = 0;
- for (i = SPDIFI_IP_OUTPUT_BUFFER1;i < SPDIFI_IP_OUTPUT_BUFFER1 + 0x80; i += sizeof(u32),col ++) {
- if (col == 4) {
- snd_iprintf(buffer,"\n");
- col = 0;
- }
-
- if (col == 0) {
- snd_iprintf(buffer, "%04X ",i);
- }
-
- snd_iprintf(buffer,"%08X ",readl(dst + i));
- }
- snd_iprintf(buffer,"\n");
-}
-
-int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip)
-{
- struct snd_info_entry *entry;
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- int i;
-
- ins->snd_card = card;
-
- if ((entry = snd_info_create_card_entry(card, "dsp", card->proc_root)) != NULL) {
- entry->content = SNDRV_INFO_CONTENT_TEXT;
- entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
-
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
-
- ins->proc_dsp_dir = entry;
-
- if (!ins->proc_dsp_dir)
- return -ENOMEM;
-
- if ((entry = snd_info_create_card_entry(card, "spos_symbols", ins->proc_dsp_dir)) != NULL) {
- entry->content = SNDRV_INFO_CONTENT_TEXT;
- entry->private_data = chip;
- entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
- entry->c.text.read = cs46xx_dsp_proc_symbol_table_read;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- ins->proc_sym_info_entry = entry;
-
- if ((entry = snd_info_create_card_entry(card, "spos_modules", ins->proc_dsp_dir)) != NULL) {
- entry->content = SNDRV_INFO_CONTENT_TEXT;
- entry->private_data = chip;
- entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
- entry->c.text.read = cs46xx_dsp_proc_modules_read;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- ins->proc_modules_info_entry = entry;
-
- if ((entry = snd_info_create_card_entry(card, "parameter", ins->proc_dsp_dir)) != NULL) {
- entry->content = SNDRV_INFO_CONTENT_TEXT;
- entry->private_data = chip;
- entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
- entry->c.text.read = cs46xx_dsp_proc_parameter_dump_read;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- ins->proc_parameter_dump_info_entry = entry;
-
- if ((entry = snd_info_create_card_entry(card, "sample", ins->proc_dsp_dir)) != NULL) {
- entry->content = SNDRV_INFO_CONTENT_TEXT;
- entry->private_data = chip;
- entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
- entry->c.text.read = cs46xx_dsp_proc_sample_dump_read;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- ins->proc_sample_dump_info_entry = entry;
-
- if ((entry = snd_info_create_card_entry(card, "task_tree", ins->proc_dsp_dir)) != NULL) {
- entry->content = SNDRV_INFO_CONTENT_TEXT;
- entry->private_data = chip;
- entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
- entry->c.text.read = cs46xx_dsp_proc_task_tree_read;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- ins->proc_task_info_entry = entry;
-
- if ((entry = snd_info_create_card_entry(card, "scb_info", ins->proc_dsp_dir)) != NULL) {
- entry->content = SNDRV_INFO_CONTENT_TEXT;
- entry->private_data = chip;
- entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
- entry->c.text.read = cs46xx_dsp_proc_scb_read;
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- entry = NULL;
- }
- }
- ins->proc_scb_info_entry = entry;
-
- mutex_lock(&chip->spos_mutex);
- /* register/update SCB's entries on proc */
- for (i = 0; i < ins->nscb; ++i) {
- if (ins->scbs[i].deleted) continue;
-
- cs46xx_dsp_proc_register_scb_desc (chip, (ins->scbs + i));
- }
- mutex_unlock(&chip->spos_mutex);
-
- return 0;
-}
-
-int cs46xx_dsp_proc_done (struct snd_cs46xx *chip)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- int i;
-
- snd_info_free_entry(ins->proc_sym_info_entry);
- ins->proc_sym_info_entry = NULL;
-
- snd_info_free_entry(ins->proc_modules_info_entry);
- ins->proc_modules_info_entry = NULL;
-
- snd_info_free_entry(ins->proc_parameter_dump_info_entry);
- ins->proc_parameter_dump_info_entry = NULL;
-
- snd_info_free_entry(ins->proc_sample_dump_info_entry);
- ins->proc_sample_dump_info_entry = NULL;
-
- snd_info_free_entry(ins->proc_scb_info_entry);
- ins->proc_scb_info_entry = NULL;
-
- snd_info_free_entry(ins->proc_task_info_entry);
- ins->proc_task_info_entry = NULL;
-
- mutex_lock(&chip->spos_mutex);
- for (i = 0; i < ins->nscb; ++i) {
- if (ins->scbs[i].deleted) continue;
- cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) );
- }
- mutex_unlock(&chip->spos_mutex);
-
- snd_info_free_entry(ins->proc_dsp_dir);
- ins->proc_dsp_dir = NULL;
-
- return 0;
-}
-#endif /* CONFIG_PROC_FS */
-
-static int debug_tree;
-static void _dsp_create_task_tree (struct snd_cs46xx *chip, u32 * task_data,
- u32 dest, int size)
-{
- void __iomem *spdst = chip->region.idx[1].remap_addr +
- DSP_PARAMETER_BYTE_OFFSET + dest * sizeof(u32);
- int i;
-
- for (i = 0; i < size; ++i) {
- if (debug_tree) printk ("addr %p, val %08x\n",spdst,task_data[i]);
- writel(task_data[i],spdst);
- spdst += sizeof(u32);
- }
-}
-
-static int debug_scb;
-static void _dsp_create_scb (struct snd_cs46xx *chip, u32 * scb_data, u32 dest)
-{
- void __iomem *spdst = chip->region.idx[1].remap_addr +
- DSP_PARAMETER_BYTE_OFFSET + dest * sizeof(u32);
- int i;
-
- for (i = 0; i < 0x10; ++i) {
- if (debug_scb) printk ("addr %p, val %08x\n",spdst,scb_data[i]);
- writel(scb_data[i],spdst);
- spdst += sizeof(u32);
- }
-}
-
-static int find_free_scb_index (struct dsp_spos_instance * ins)
-{
- int index = ins->nscb, i;
-
- for (i = ins->scb_highest_frag_index; i < ins->nscb; ++i) {
- if (ins->scbs[i].deleted) {
- index = i;
- break;
- }
- }
-
- return index;
-}
-
-static struct dsp_scb_descriptor * _map_scb (struct snd_cs46xx *chip, char * name, u32 dest)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- struct dsp_scb_descriptor * desc = NULL;
- int index;
-
- if (ins->nscb == DSP_MAX_SCB_DESC - 1) {
- snd_printk(KERN_ERR "dsp_spos: got no place for other SCB\n");
- return NULL;
- }
-
- index = find_free_scb_index (ins);
-
- memset(&ins->scbs[index], 0, sizeof(ins->scbs[index]));
- strcpy(ins->scbs[index].scb_name, name);
- ins->scbs[index].address = dest;
- ins->scbs[index].index = index;
- ins->scbs[index].ref_count = 1;
-
- desc = (ins->scbs + index);
- ins->scbs[index].scb_symbol = add_symbol (chip, name, dest, SYMBOL_PARAMETER);
-
- if (index > ins->scb_highest_frag_index)
- ins->scb_highest_frag_index = index;
-
- if (index == ins->nscb)
- ins->nscb++;
-
- return desc;
-}
-
-static struct dsp_task_descriptor *
-_map_task_tree (struct snd_cs46xx *chip, char * name, u32 dest, u32 size)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- struct dsp_task_descriptor * desc = NULL;
-
- if (ins->ntask == DSP_MAX_TASK_DESC - 1) {
- snd_printk(KERN_ERR "dsp_spos: got no place for other TASK\n");
- return NULL;
- }
-
- if (name)
- strcpy(ins->tasks[ins->ntask].task_name, name);
- else
- strcpy(ins->tasks[ins->ntask].task_name, "(NULL)");
- ins->tasks[ins->ntask].address = dest;
- ins->tasks[ins->ntask].size = size;
-
- /* quick find in list */
- ins->tasks[ins->ntask].index = ins->ntask;
- desc = (ins->tasks + ins->ntask);
- ins->ntask++;
-
- if (name)
- add_symbol (chip,name,dest,SYMBOL_PARAMETER);
- return desc;
-}
-
-#define SCB_BYTES (0x10 * 4)
-
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u32 dest)
-{
- struct dsp_scb_descriptor * desc;
-
-#ifdef CONFIG_PM
- /* copy the data for resume */
- scb_data = kmemdup(scb_data, SCB_BYTES, GFP_KERNEL);
- if (!scb_data)
- return NULL;
-#endif
-
- desc = _map_scb (chip,name,dest);
- if (desc) {
- desc->data = scb_data;
- _dsp_create_scb(chip,scb_data,dest);
- } else {
- snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n");
-#ifdef CONFIG_PM
- kfree(scb_data);
-#endif
- }
-
- return desc;
-}
-
-
-static struct dsp_task_descriptor *
-cs46xx_dsp_create_task_tree (struct snd_cs46xx *chip, char * name, u32 * task_data,
- u32 dest, int size)
-{
- struct dsp_task_descriptor * desc;
-
- desc = _map_task_tree (chip,name,dest,size);
- if (desc) {
- desc->data = task_data;
- _dsp_create_task_tree(chip,task_data,dest,size);
- } else {
- snd_printk(KERN_ERR "dsp_spos: failed to map TASK\n");
- }
-
- return desc;
-}
-
-int cs46xx_dsp_scb_and_task_init (struct snd_cs46xx *chip)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- struct dsp_symbol_entry * fg_task_tree_header_code;
- struct dsp_symbol_entry * task_tree_header_code;
- struct dsp_symbol_entry * task_tree_thread;
- struct dsp_symbol_entry * null_algorithm;
- struct dsp_symbol_entry * magic_snoop_task;
-
- struct dsp_scb_descriptor * timing_master_scb;
- struct dsp_scb_descriptor * codec_out_scb;
- struct dsp_scb_descriptor * codec_in_scb;
- struct dsp_scb_descriptor * src_task_scb;
- struct dsp_scb_descriptor * master_mix_scb;
- struct dsp_scb_descriptor * rear_mix_scb;
- struct dsp_scb_descriptor * record_mix_scb;
- struct dsp_scb_descriptor * write_back_scb;
- struct dsp_scb_descriptor * vari_decimate_scb;
- struct dsp_scb_descriptor * rear_codec_out_scb;
- struct dsp_scb_descriptor * clfe_codec_out_scb;
- struct dsp_scb_descriptor * magic_snoop_scb;
-
- int fifo_addr, fifo_span, valid_slots;
-
- static struct dsp_spos_control_block sposcb = {
- /* 0 */ HFG_TREE_SCB,HFG_STACK,
- /* 1 */ SPOSCB_ADDR,BG_TREE_SCB_ADDR,
- /* 2 */ DSP_SPOS_DC,0,
- /* 3 */ DSP_SPOS_DC,DSP_SPOS_DC,
- /* 4 */ 0,0,
- /* 5 */ DSP_SPOS_UU,0,
- /* 6 */ FG_TASK_HEADER_ADDR,0,
- /* 7 */ 0,0,
- /* 8 */ DSP_SPOS_UU,DSP_SPOS_DC,
- /* 9 */ 0,
- /* A */ 0,HFG_FIRST_EXECUTE_MODE,
- /* B */ DSP_SPOS_UU,DSP_SPOS_UU,
- /* C */ DSP_SPOS_DC_DC,
- /* D */ DSP_SPOS_DC_DC,
- /* E */ DSP_SPOS_DC_DC,
- /* F */ DSP_SPOS_DC_DC
- };
-
- cs46xx_dsp_create_task_tree(chip, "sposCB", (u32 *)&sposcb, SPOSCB_ADDR, 0x10);
-
- null_algorithm = cs46xx_dsp_lookup_symbol(chip, "NULLALGORITHM", SYMBOL_CODE);
- if (null_algorithm == NULL) {
- snd_printk(KERN_ERR "dsp_spos: symbol NULLALGORITHM not found\n");
- return -EIO;
- }
-
- fg_task_tree_header_code = cs46xx_dsp_lookup_symbol(chip, "FGTASKTREEHEADERCODE", SYMBOL_CODE);
- if (fg_task_tree_header_code == NULL) {
- snd_printk(KERN_ERR "dsp_spos: symbol FGTASKTREEHEADERCODE not found\n");
- return -EIO;
- }
-
- task_tree_header_code = cs46xx_dsp_lookup_symbol(chip, "TASKTREEHEADERCODE", SYMBOL_CODE);
- if (task_tree_header_code == NULL) {
- snd_printk(KERN_ERR "dsp_spos: symbol TASKTREEHEADERCODE not found\n");
- return -EIO;
- }
-
- task_tree_thread = cs46xx_dsp_lookup_symbol(chip, "TASKTREETHREAD", SYMBOL_CODE);
- if (task_tree_thread == NULL) {
- snd_printk(KERN_ERR "dsp_spos: symbol TASKTREETHREAD not found\n");
- return -EIO;
- }
-
- magic_snoop_task = cs46xx_dsp_lookup_symbol(chip, "MAGICSNOOPTASK", SYMBOL_CODE);
- if (magic_snoop_task == NULL) {
- snd_printk(KERN_ERR "dsp_spos: symbol MAGICSNOOPTASK not found\n");
- return -EIO;
- }
-
- {
- /* create the null SCB */
- static struct dsp_generic_scb null_scb = {
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0 },
- NULL_SCB_ADDR, NULL_SCB_ADDR,
- 0, 0, 0, 0, 0,
- {
- 0,0,
- 0,0,
- }
- };
-
- null_scb.entry_point = null_algorithm->address;
- ins->the_null_scb = cs46xx_dsp_create_scb(chip, "nullSCB", (u32 *)&null_scb, NULL_SCB_ADDR);
- ins->the_null_scb->task_entry = null_algorithm;
- ins->the_null_scb->sub_list_ptr = ins->the_null_scb;
- ins->the_null_scb->next_scb_ptr = ins->the_null_scb;
- ins->the_null_scb->parent_scb_ptr = NULL;
- cs46xx_dsp_proc_register_scb_desc (chip,ins->the_null_scb);
- }
-
- {
- /* setup foreground task tree */
- static struct dsp_task_tree_control_block fg_task_tree_hdr = {
- { FG_TASK_HEADER_ADDR | (DSP_SPOS_DC << 0x10),
- DSP_SPOS_DC_DC,
- DSP_SPOS_DC_DC,
- 0x0000,DSP_SPOS_DC,
- DSP_SPOS_DC, DSP_SPOS_DC,
- DSP_SPOS_DC_DC,
- DSP_SPOS_DC_DC,
- DSP_SPOS_DC_DC,
- DSP_SPOS_DC,DSP_SPOS_DC },
-
- {
- BG_TREE_SCB_ADDR,TIMINGMASTER_SCB_ADDR,
- 0,
- FG_TASK_HEADER_ADDR + TCBData,
- },
-
- {
- 4,0,
- 1,0,
- 2,SPOSCB_ADDR + HFGFlags,
- 0,0,
- FG_TASK_HEADER_ADDR + TCBContextBlk,FG_STACK
- },
-
- {
- DSP_SPOS_DC,0,
- DSP_SPOS_DC,DSP_SPOS_DC,
- DSP_SPOS_DC,DSP_SPOS_DC,
- DSP_SPOS_DC,DSP_SPOS_DC,
- DSP_SPOS_DC,DSP_SPOS_DC,
- DSP_SPOS_DCDC,
- DSP_SPOS_UU,1,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC
- },
- {
- FG_INTERVAL_TIMER_PERIOD,DSP_SPOS_UU,
- 0,0
- }
- };
-
- fg_task_tree_hdr.links.entry_point = fg_task_tree_header_code->address;
- fg_task_tree_hdr.context_blk.stack0 = task_tree_thread->address;
- cs46xx_dsp_create_task_tree(chip,"FGtaskTreeHdr",(u32 *)&fg_task_tree_hdr,FG_TASK_HEADER_ADDR,0x35);
- }
-
-
- {
- /* setup foreground task tree */
- static struct dsp_task_tree_control_block bg_task_tree_hdr = {
- { DSP_SPOS_DC_DC,
- DSP_SPOS_DC_DC,
- DSP_SPOS_DC_DC,
- DSP_SPOS_DC, DSP_SPOS_DC,
- DSP_SPOS_DC, DSP_SPOS_DC,
- DSP_SPOS_DC_DC,
- DSP_SPOS_DC_DC,
- DSP_SPOS_DC_DC,
- DSP_SPOS_DC,DSP_SPOS_DC },
-
- {
- NULL_SCB_ADDR,NULL_SCB_ADDR, /* Set up the background to do nothing */
- 0,
- BG_TREE_SCB_ADDR + TCBData,
- },
-
- {
- 9999,0,
- 0,1,
- 0,SPOSCB_ADDR + HFGFlags,
- 0,0,
- BG_TREE_SCB_ADDR + TCBContextBlk,BG_STACK
- },
-
- {
- DSP_SPOS_DC,0,
- DSP_SPOS_DC,DSP_SPOS_DC,
- DSP_SPOS_DC,DSP_SPOS_DC,
- DSP_SPOS_DC,DSP_SPOS_DC,
- DSP_SPOS_DC,DSP_SPOS_DC,
- DSP_SPOS_DCDC,
- DSP_SPOS_UU,1,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC,
- DSP_SPOS_DCDC
- },
- {
- BG_INTERVAL_TIMER_PERIOD,DSP_SPOS_UU,
- 0,0
- }
- };
-
- bg_task_tree_hdr.links.entry_point = task_tree_header_code->address;
- bg_task_tree_hdr.context_blk.stack0 = task_tree_thread->address;
- cs46xx_dsp_create_task_tree(chip,"BGtaskTreeHdr",(u32 *)&bg_task_tree_hdr,BG_TREE_SCB_ADDR,0x35);
- }
-
- /* create timing master SCB */
- timing_master_scb = cs46xx_dsp_create_timing_master_scb(chip);
-
- /* create the CODEC output task */
- codec_out_scb = cs46xx_dsp_create_codec_out_scb(chip,"CodecOutSCB_I",0x0010,0x0000,
- MASTERMIX_SCB_ADDR,
- CODECOUT_SCB_ADDR,timing_master_scb,
- SCB_ON_PARENT_SUBLIST_SCB);
-
- if (!codec_out_scb) goto _fail_end;
- /* create the master mix SCB */
- master_mix_scb = cs46xx_dsp_create_mix_only_scb(chip,"MasterMixSCB",
- MIX_SAMPLE_BUF1,MASTERMIX_SCB_ADDR,
- codec_out_scb,
- SCB_ON_PARENT_SUBLIST_SCB);
- ins->master_mix_scb = master_mix_scb;
-
- if (!master_mix_scb) goto _fail_end;
-
- /* create codec in */
- codec_in_scb = cs46xx_dsp_create_codec_in_scb(chip,"CodecInSCB",0x0010,0x00A0,
- CODEC_INPUT_BUF1,
- CODECIN_SCB_ADDR,codec_out_scb,
- SCB_ON_PARENT_NEXT_SCB);
- if (!codec_in_scb) goto _fail_end;
- ins->codec_in_scb = codec_in_scb;
-
- /* create write back scb */
- write_back_scb = cs46xx_dsp_create_mix_to_ostream_scb(chip,"WriteBackSCB",
- WRITE_BACK_BUF1,WRITE_BACK_SPB,
- WRITEBACK_SCB_ADDR,
- timing_master_scb,
- SCB_ON_PARENT_NEXT_SCB);
- if (!write_back_scb) goto _fail_end;
-
- {
- static struct dsp_mix2_ostream_spb mix2_ostream_spb = {
- 0x00020000,
- 0x0000ffff
- };
-
- if (!cs46xx_dsp_create_task_tree(chip, NULL,
- (u32 *)&mix2_ostream_spb,
- WRITE_BACK_SPB, 2))
- goto _fail_end;
- }
-
- /* input sample converter */
- vari_decimate_scb = cs46xx_dsp_create_vari_decimate_scb(chip,"VariDecimateSCB",
- VARI_DECIMATE_BUF0,
- VARI_DECIMATE_BUF1,
- VARIDECIMATE_SCB_ADDR,
- write_back_scb,
- SCB_ON_PARENT_SUBLIST_SCB);
- if (!vari_decimate_scb) goto _fail_end;
-
- /* create the record mixer SCB */
- record_mix_scb = cs46xx_dsp_create_mix_only_scb(chip,"RecordMixerSCB",
- MIX_SAMPLE_BUF2,
- RECORD_MIXER_SCB_ADDR,
- vari_decimate_scb,
- SCB_ON_PARENT_SUBLIST_SCB);
- ins->record_mixer_scb = record_mix_scb;
-
- if (!record_mix_scb) goto _fail_end;
-
- valid_slots = snd_cs46xx_peekBA0(chip, BA0_ACOSV);
-
- if (snd_BUG_ON(chip->nr_ac97_codecs != 1 && chip->nr_ac97_codecs != 2))
- goto _fail_end;
-
- if (chip->nr_ac97_codecs == 1) {
- /* output on slot 5 and 11
- on primary CODEC */
- fifo_addr = 0x20;
- fifo_span = 0x60;
-
- /* enable slot 5 and 11 */
- valid_slots |= ACOSV_SLV5 | ACOSV_SLV11;
- } else {
- /* output on slot 7 and 8
- on secondary CODEC */
- fifo_addr = 0x40;
- fifo_span = 0x10;
-
- /* enable slot 7 and 8 */
- valid_slots |= ACOSV_SLV7 | ACOSV_SLV8;
- }
- /* create CODEC tasklet for rear speakers output*/
- rear_codec_out_scb = cs46xx_dsp_create_codec_out_scb(chip,"CodecOutSCB_Rear",fifo_span,fifo_addr,
- REAR_MIXER_SCB_ADDR,
- REAR_CODECOUT_SCB_ADDR,codec_in_scb,
- SCB_ON_PARENT_NEXT_SCB);
- if (!rear_codec_out_scb) goto _fail_end;
-
-
- /* create the rear PCM channel mixer SCB */
- rear_mix_scb = cs46xx_dsp_create_mix_only_scb(chip,"RearMixerSCB",
- MIX_SAMPLE_BUF3,
- REAR_MIXER_SCB_ADDR,
- rear_codec_out_scb,
- SCB_ON_PARENT_SUBLIST_SCB);
- ins->rear_mix_scb = rear_mix_scb;
- if (!rear_mix_scb) goto _fail_end;
-
- if (chip->nr_ac97_codecs == 2) {
- /* create CODEC tasklet for rear Center/LFE output
- slot 6 and 9 on seconadry CODEC */
- clfe_codec_out_scb = cs46xx_dsp_create_codec_out_scb(chip,"CodecOutSCB_CLFE",0x0030,0x0030,
- CLFE_MIXER_SCB_ADDR,
- CLFE_CODEC_SCB_ADDR,
- rear_codec_out_scb,
- SCB_ON_PARENT_NEXT_SCB);
- if (!clfe_codec_out_scb) goto _fail_end;
-
-
- /* create the rear PCM channel mixer SCB */
- ins->center_lfe_mix_scb = cs46xx_dsp_create_mix_only_scb(chip,"CLFEMixerSCB",
- MIX_SAMPLE_BUF4,
- CLFE_MIXER_SCB_ADDR,
- clfe_codec_out_scb,
- SCB_ON_PARENT_SUBLIST_SCB);
- if (!ins->center_lfe_mix_scb) goto _fail_end;
-
- /* enable slot 6 and 9 */
- valid_slots |= ACOSV_SLV6 | ACOSV_SLV9;
- } else {
- clfe_codec_out_scb = rear_codec_out_scb;
- ins->center_lfe_mix_scb = rear_mix_scb;
- }
-
- /* enable slots depending on CODEC configuration */
- snd_cs46xx_pokeBA0(chip, BA0_ACOSV, valid_slots);
-
- /* the magic snooper */
- magic_snoop_scb = cs46xx_dsp_create_magic_snoop_scb (chip,"MagicSnoopSCB_I",OUTPUTSNOOP_SCB_ADDR,
- OUTPUT_SNOOP_BUFFER,
- codec_out_scb,
- clfe_codec_out_scb,
- SCB_ON_PARENT_NEXT_SCB);
-
-
- if (!magic_snoop_scb) goto _fail_end;
- ins->ref_snoop_scb = magic_snoop_scb;
-
- /* SP IO access */
- if (!cs46xx_dsp_create_spio_write_scb(chip,"SPIOWriteSCB",SPIOWRITE_SCB_ADDR,
- magic_snoop_scb,
- SCB_ON_PARENT_NEXT_SCB))
- goto _fail_end;
-
- /* SPDIF input sampel rate converter */
- src_task_scb = cs46xx_dsp_create_src_task_scb(chip,"SrcTaskSCB_SPDIFI",
- ins->spdif_in_sample_rate,
- SRC_OUTPUT_BUF1,
- SRC_DELAY_BUF1,SRCTASK_SCB_ADDR,
- master_mix_scb,
- SCB_ON_PARENT_SUBLIST_SCB,1);
-
- if (!src_task_scb) goto _fail_end;
- cs46xx_src_unlink(chip,src_task_scb);
-
- /* NOTE: when we now how to detect the SPDIF input
- sample rate we will use this SRC to adjust it */
- ins->spdif_in_src = src_task_scb;
-
- cs46xx_dsp_async_init(chip,timing_master_scb);
- return 0;
-
- _fail_end:
- snd_printk(KERN_ERR "dsp_spos: failed to setup SCB's in DSP\n");
- return -EINVAL;
-}
-
-static int cs46xx_dsp_async_init (struct snd_cs46xx *chip,
- struct dsp_scb_descriptor * fg_entry)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- struct dsp_symbol_entry * s16_async_codec_input_task;
- struct dsp_symbol_entry * spdifo_task;
- struct dsp_symbol_entry * spdifi_task;
- struct dsp_scb_descriptor * spdifi_scb_desc, * spdifo_scb_desc, * async_codec_scb_desc;
-
- s16_async_codec_input_task = cs46xx_dsp_lookup_symbol(chip, "S16_ASYNCCODECINPUTTASK", SYMBOL_CODE);
- if (s16_async_codec_input_task == NULL) {
- snd_printk(KERN_ERR "dsp_spos: symbol S16_ASYNCCODECINPUTTASK not found\n");
- return -EIO;
- }
- spdifo_task = cs46xx_dsp_lookup_symbol(chip, "SPDIFOTASK", SYMBOL_CODE);
- if (spdifo_task == NULL) {
- snd_printk(KERN_ERR "dsp_spos: symbol SPDIFOTASK not found\n");
- return -EIO;
- }
-
- spdifi_task = cs46xx_dsp_lookup_symbol(chip, "SPDIFITASK", SYMBOL_CODE);
- if (spdifi_task == NULL) {
- snd_printk(KERN_ERR "dsp_spos: symbol SPDIFITASK not found\n");
- return -EIO;
- }
-
- {
- /* 0xBC0 */
- struct dsp_spdifoscb spdifo_scb = {
- /* 0 */ DSP_SPOS_UUUU,
- {
- /* 1 */ 0xb0,
- /* 2 */ 0,
- /* 3 */ 0,
- /* 4 */ 0,
- },
- /* NOTE: the SPDIF output task read samples in mono
- format, the AsynchFGTxSCB task writes to buffer
- in stereo format
- */
- /* 5 */ RSCONFIG_SAMPLE_16MONO + RSCONFIG_MODULO_256,
- /* 6 */ ( SPDIFO_IP_OUTPUT_BUFFER1 << 0x10 ) | 0xFFFC,
- /* 7 */ 0,0,
- /* 8 */ 0,
- /* 9 */ FG_TASK_HEADER_ADDR, NULL_SCB_ADDR,
- /* A */ spdifo_task->address,
- SPDIFO_SCB_INST + SPDIFOFIFOPointer,
- {
- /* B */ 0x0040, /*DSP_SPOS_UUUU,*/
- /* C */ 0x20ff, /*DSP_SPOS_UUUU,*/
- },
- /* D */ 0x804c,0, /* SPDIFOFIFOPointer:SPDIFOStatRegAddr; */
- /* E */ 0x0108,0x0001, /* SPDIFOStMoFormat:SPDIFOFIFOBaseAddr; */
- /* F */ DSP_SPOS_UUUU /* SPDIFOFree; */
- };
-
- /* 0xBB0 */
- struct dsp_spdifiscb spdifi_scb = {
- /* 0 */ DSP_SPOS_UULO,DSP_SPOS_UUHI,
- /* 1 */ 0,
- /* 2 */ 0,
- /* 3 */ 1,4000, /* SPDIFICountLimit SPDIFICount */
- /* 4 */ DSP_SPOS_UUUU, /* SPDIFIStatusData */
- /* 5 */ 0,DSP_SPOS_UUHI, /* StatusData, Free4 */
- /* 6 */ DSP_SPOS_UUUU, /* Free3 */
- /* 7 */ DSP_SPOS_UU,DSP_SPOS_DC, /* Free2 BitCount*/
- /* 8 */ DSP_SPOS_UUUU, /* TempStatus */
- /* 9 */ SPDIFO_SCB_INST, NULL_SCB_ADDR,
- /* A */ spdifi_task->address,
- SPDIFI_SCB_INST + SPDIFIFIFOPointer,
- /* NOTE: The SPDIF input task write the sample in mono
- format from the HW FIFO, the AsynchFGRxSCB task reads
- them in stereo
- */
- /* B */ RSCONFIG_SAMPLE_16MONO + RSCONFIG_MODULO_128,
- /* C */ (SPDIFI_IP_OUTPUT_BUFFER1 << 0x10) | 0xFFFC,
- /* D */ 0x8048,0,
- /* E */ 0x01f0,0x0001,
- /* F */ DSP_SPOS_UUUU /* SPDIN_STATUS monitor */
- };
-
- /* 0xBA0 */
- struct dsp_async_codec_input_scb async_codec_input_scb = {
- /* 0 */ DSP_SPOS_UUUU,
- /* 1 */ 0,
- /* 2 */ 0,
- /* 3 */ 1,4000,
- /* 4 */ 0x0118,0x0001,
- /* 5 */ RSCONFIG_SAMPLE_16MONO + RSCONFIG_MODULO_64,
- /* 6 */ (ASYNC_IP_OUTPUT_BUFFER1 << 0x10) | 0xFFFC,
- /* 7 */ DSP_SPOS_UU,0x3,
- /* 8 */ DSP_SPOS_UUUU,
- /* 9 */ SPDIFI_SCB_INST,NULL_SCB_ADDR,
- /* A */ s16_async_codec_input_task->address,
- HFG_TREE_SCB + AsyncCIOFIFOPointer,
-
- /* B */ RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_64,
- /* C */ (ASYNC_IP_OUTPUT_BUFFER1 << 0x10), /*(ASYNC_IP_OUTPUT_BUFFER1 << 0x10) | 0xFFFC,*/
-
-#ifdef UseASER1Input
- /* short AsyncCIFIFOPointer:AsyncCIStatRegAddr;
- Init. 0000:8042: for ASER1
- 0000:8044: for ASER2 */
- /* D */ 0x8042,0,
-
- /* short AsyncCIStMoFormat:AsyncCIFIFOBaseAddr;
- Init 1 stero:8050 ASER1
- Init 0 mono:8070 ASER2
- Init 1 Stereo : 0100 ASER1 (Set by script) */
- /* E */ 0x0100,0x0001,
-
-#endif
-
-#ifdef UseASER2Input
- /* short AsyncCIFIFOPointer:AsyncCIStatRegAddr;
- Init. 0000:8042: for ASER1
- 0000:8044: for ASER2 */
- /* D */ 0x8044,0,
-
- /* short AsyncCIStMoFormat:AsyncCIFIFOBaseAddr;
- Init 1 stero:8050 ASER1
- Init 0 mono:8070 ASER2
- Init 1 Stereo : 0100 ASER1 (Set by script) */
- /* E */ 0x0110,0x0001,
-
-#endif
-
- /* short AsyncCIOutputBufModulo:AsyncCIFree;
- AsyncCIOutputBufModulo: The modulo size for
- the output buffer of this task */
- /* F */ 0, /* DSP_SPOS_UUUU */
- };
-
- spdifo_scb_desc = cs46xx_dsp_create_scb(chip,"SPDIFOSCB",(u32 *)&spdifo_scb,SPDIFO_SCB_INST);
-
- if (snd_BUG_ON(!spdifo_scb_desc))
- return -EIO;
- spdifi_scb_desc = cs46xx_dsp_create_scb(chip,"SPDIFISCB",(u32 *)&spdifi_scb,SPDIFI_SCB_INST);
- if (snd_BUG_ON(!spdifi_scb_desc))
- return -EIO;
- async_codec_scb_desc = cs46xx_dsp_create_scb(chip,"AsynCodecInputSCB",(u32 *)&async_codec_input_scb, HFG_TREE_SCB);
- if (snd_BUG_ON(!async_codec_scb_desc))
- return -EIO;
-
- async_codec_scb_desc->parent_scb_ptr = NULL;
- async_codec_scb_desc->next_scb_ptr = spdifi_scb_desc;
- async_codec_scb_desc->sub_list_ptr = ins->the_null_scb;
- async_codec_scb_desc->task_entry = s16_async_codec_input_task;
-
- spdifi_scb_desc->parent_scb_ptr = async_codec_scb_desc;
- spdifi_scb_desc->next_scb_ptr = spdifo_scb_desc;
- spdifi_scb_desc->sub_list_ptr = ins->the_null_scb;
- spdifi_scb_desc->task_entry = spdifi_task;
-
- spdifo_scb_desc->parent_scb_ptr = spdifi_scb_desc;
- spdifo_scb_desc->next_scb_ptr = fg_entry;
- spdifo_scb_desc->sub_list_ptr = ins->the_null_scb;
- spdifo_scb_desc->task_entry = spdifo_task;
-
- /* this one is faked, as the parnet of SPDIFO task
- is the FG task tree */
- fg_entry->parent_scb_ptr = spdifo_scb_desc;
-
- /* for proc fs */
- cs46xx_dsp_proc_register_scb_desc (chip,spdifo_scb_desc);
- cs46xx_dsp_proc_register_scb_desc (chip,spdifi_scb_desc);
- cs46xx_dsp_proc_register_scb_desc (chip,async_codec_scb_desc);
-
- /* Async MASTER ENABLE, affects both SPDIF input and output */
- snd_cs46xx_pokeBA0(chip, BA0_ASER_MASTER, 0x1 );
- }
-
- return 0;
-}
-
-static void cs46xx_dsp_disable_spdif_hw (struct snd_cs46xx *chip)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- /* set SPDIF output FIFO slot */
- snd_cs46xx_pokeBA0(chip, BA0_ASER_FADDR, 0);
-
- /* SPDIF output MASTER ENABLE */
- cs46xx_poke_via_dsp (chip,SP_SPDOUT_CONTROL, 0);
-
- /* right and left validate bit */
- /*cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, ins->spdif_csuv_default);*/
- cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, 0x0);
-
- /* clear fifo pointer */
- cs46xx_poke_via_dsp (chip,SP_SPDIN_FIFOPTR, 0x0);
-
- /* monitor state */
- ins->spdif_status_out &= ~DSP_SPDIF_STATUS_HW_ENABLED;
-}
-
-int cs46xx_dsp_enable_spdif_hw (struct snd_cs46xx *chip)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- /* if hw-ctrl already enabled, turn off to reset logic ... */
- cs46xx_dsp_disable_spdif_hw (chip);
- udelay(50);
-
- /* set SPDIF output FIFO slot */
- snd_cs46xx_pokeBA0(chip, BA0_ASER_FADDR, ( 0x8000 | ((SP_SPDOUT_FIFO >> 4) << 4) ));
-
- /* SPDIF output MASTER ENABLE */
- cs46xx_poke_via_dsp (chip,SP_SPDOUT_CONTROL, 0x80000000);
-
- /* right and left validate bit */
- cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, ins->spdif_csuv_default);
-
- /* monitor state */
- ins->spdif_status_out |= DSP_SPDIF_STATUS_HW_ENABLED;
-
- return 0;
-}
-
-int cs46xx_dsp_enable_spdif_in (struct snd_cs46xx *chip)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- /* turn on amplifier */
- chip->active_ctrl(chip, 1);
- chip->amplifier_ctrl(chip, 1);
-
- if (snd_BUG_ON(ins->asynch_rx_scb))
- return -EINVAL;
- if (snd_BUG_ON(!ins->spdif_in_src))
- return -EINVAL;
-
- mutex_lock(&chip->spos_mutex);
-
- if ( ! (ins->spdif_status_out & DSP_SPDIF_STATUS_INPUT_CTRL_ENABLED) ) {
- /* time countdown enable */
- cs46xx_poke_via_dsp (chip,SP_ASER_COUNTDOWN, 0x80000005);
- /* NOTE: 80000005 value is just magic. With all values
- that I've tested this one seem to give the best result.
- Got no explication why. (Benny) */
-
- /* SPDIF input MASTER ENABLE */
- cs46xx_poke_via_dsp (chip,SP_SPDIN_CONTROL, 0x800003ff);
-
- ins->spdif_status_out |= DSP_SPDIF_STATUS_INPUT_CTRL_ENABLED;
- }
-
- /* create and start the asynchronous receiver SCB */
- ins->asynch_rx_scb = cs46xx_dsp_create_asynch_fg_rx_scb(chip,"AsynchFGRxSCB",
- ASYNCRX_SCB_ADDR,
- SPDIFI_SCB_INST,
- SPDIFI_IP_OUTPUT_BUFFER1,
- ins->spdif_in_src,
- SCB_ON_PARENT_SUBLIST_SCB);
-
- spin_lock_irq(&chip->reg_lock);
-
- /* reset SPDIF input sample buffer pointer */
- /*snd_cs46xx_poke (chip, (SPDIFI_SCB_INST + 0x0c) << 2,
- (SPDIFI_IP_OUTPUT_BUFFER1 << 0x10) | 0xFFFC);*/
-
- /* reset FIFO ptr */
- /*cs46xx_poke_via_dsp (chip,SP_SPDIN_FIFOPTR, 0x0);*/
- cs46xx_src_link(chip,ins->spdif_in_src);
-
- /* unmute SRC volume */
- cs46xx_dsp_scb_set_volume (chip,ins->spdif_in_src,0x7fff,0x7fff);
-
- spin_unlock_irq(&chip->reg_lock);
-
- /* set SPDIF input sample rate and unmute
- NOTE: only 48khz support for SPDIF input this time */
- /* cs46xx_dsp_set_src_sample_rate(chip,ins->spdif_in_src,48000); */
-
- /* monitor state */
- ins->spdif_status_in = 1;
- mutex_unlock(&chip->spos_mutex);
-
- return 0;
-}
-
-int cs46xx_dsp_disable_spdif_in (struct snd_cs46xx *chip)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- if (snd_BUG_ON(!ins->asynch_rx_scb))
- return -EINVAL;
- if (snd_BUG_ON(!ins->spdif_in_src))
- return -EINVAL;
-
- mutex_lock(&chip->spos_mutex);
-
- /* Remove the asynchronous receiver SCB */
- cs46xx_dsp_remove_scb (chip,ins->asynch_rx_scb);
- ins->asynch_rx_scb = NULL;
-
- cs46xx_src_unlink(chip,ins->spdif_in_src);
-
- /* monitor state */
- ins->spdif_status_in = 0;
- mutex_unlock(&chip->spos_mutex);
-
- /* restore amplifier */
- chip->active_ctrl(chip, -1);
- chip->amplifier_ctrl(chip, -1);
-
- return 0;
-}
-
-int cs46xx_dsp_enable_pcm_capture (struct snd_cs46xx *chip)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- if (snd_BUG_ON(ins->pcm_input))
- return -EINVAL;
- if (snd_BUG_ON(!ins->ref_snoop_scb))
- return -EINVAL;
-
- mutex_lock(&chip->spos_mutex);
- ins->pcm_input = cs46xx_add_record_source(chip,ins->ref_snoop_scb,PCMSERIALIN_PCM_SCB_ADDR,
- "PCMSerialInput_Wave");
- mutex_unlock(&chip->spos_mutex);
-
- return 0;
-}
-
-int cs46xx_dsp_disable_pcm_capture (struct snd_cs46xx *chip)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- if (snd_BUG_ON(!ins->pcm_input))
- return -EINVAL;
-
- mutex_lock(&chip->spos_mutex);
- cs46xx_dsp_remove_scb (chip,ins->pcm_input);
- ins->pcm_input = NULL;
- mutex_unlock(&chip->spos_mutex);
-
- return 0;
-}
-
-int cs46xx_dsp_enable_adc_capture (struct snd_cs46xx *chip)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- if (snd_BUG_ON(ins->adc_input))
- return -EINVAL;
- if (snd_BUG_ON(!ins->codec_in_scb))
- return -EINVAL;
-
- mutex_lock(&chip->spos_mutex);
- ins->adc_input = cs46xx_add_record_source(chip,ins->codec_in_scb,PCMSERIALIN_SCB_ADDR,
- "PCMSerialInput_ADC");
- mutex_unlock(&chip->spos_mutex);
-
- return 0;
-}
-
-int cs46xx_dsp_disable_adc_capture (struct snd_cs46xx *chip)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- if (snd_BUG_ON(!ins->adc_input))
- return -EINVAL;
-
- mutex_lock(&chip->spos_mutex);
- cs46xx_dsp_remove_scb (chip,ins->adc_input);
- ins->adc_input = NULL;
- mutex_unlock(&chip->spos_mutex);
-
- return 0;
-}
-
-int cs46xx_poke_via_dsp (struct snd_cs46xx *chip, u32 address, u32 data)
-{
- u32 temp;
- int i;
-
- /* santiy check the parameters. (These numbers are not 100% correct. They are
- a rough guess from looking at the controller spec.) */
- if (address < 0x8000 || address >= 0x9000)
- return -EINVAL;
-
- /* initialize the SP_IO_WRITE SCB with the data. */
- temp = ( address << 16 ) | ( address & 0x0000FFFF); /* offset 0 <-- address2 : address1 */
-
- snd_cs46xx_poke(chip,( SPIOWRITE_SCB_ADDR << 2), temp);
- snd_cs46xx_poke(chip,((SPIOWRITE_SCB_ADDR + 1) << 2), data); /* offset 1 <-- data1 */
- snd_cs46xx_poke(chip,((SPIOWRITE_SCB_ADDR + 2) << 2), data); /* offset 1 <-- data2 */
-
- /* Poke this location to tell the task to start */
- snd_cs46xx_poke(chip,((SPIOWRITE_SCB_ADDR + 6) << 2), SPIOWRITE_SCB_ADDR << 0x10);
-
- /* Verify that the task ran */
- for (i=0; i<25; i++) {
- udelay(125);
-
- temp = snd_cs46xx_peek(chip,((SPIOWRITE_SCB_ADDR + 6) << 2));
- if (temp == 0x00000000)
- break;
- }
-
- if (i == 25) {
- snd_printk(KERN_ERR "dsp_spos: SPIOWriteTask not responding\n");
- return -EBUSY;
- }
-
- return 0;
-}
-
-int cs46xx_dsp_set_dac_volume (struct snd_cs46xx * chip, u16 left, u16 right)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- struct dsp_scb_descriptor * scb;
-
- mutex_lock(&chip->spos_mutex);
-
- /* main output */
- scb = ins->master_mix_scb->sub_list_ptr;
- while (scb != ins->the_null_scb) {
- cs46xx_dsp_scb_set_volume (chip,scb,left,right);
- scb = scb->next_scb_ptr;
- }
-
- /* rear output */
- scb = ins->rear_mix_scb->sub_list_ptr;
- while (scb != ins->the_null_scb) {
- cs46xx_dsp_scb_set_volume (chip,scb,left,right);
- scb = scb->next_scb_ptr;
- }
-
- ins->dac_volume_left = left;
- ins->dac_volume_right = right;
-
- mutex_unlock(&chip->spos_mutex);
-
- return 0;
-}
-
-int cs46xx_dsp_set_iec958_volume (struct snd_cs46xx * chip, u16 left, u16 right)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- mutex_lock(&chip->spos_mutex);
-
- if (ins->asynch_rx_scb != NULL)
- cs46xx_dsp_scb_set_volume (chip,ins->asynch_rx_scb,
- left,right);
-
- ins->spdif_input_volume_left = left;
- ins->spdif_input_volume_right = right;
-
- mutex_unlock(&chip->spos_mutex);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-int cs46xx_dsp_resume(struct snd_cs46xx * chip)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- int i, err;
-
- /* clear parameter, sample and code areas */
- snd_cs46xx_clear_BA1(chip, DSP_PARAMETER_BYTE_OFFSET,
- DSP_PARAMETER_BYTE_SIZE);
- snd_cs46xx_clear_BA1(chip, DSP_SAMPLE_BYTE_OFFSET,
- DSP_SAMPLE_BYTE_SIZE);
- snd_cs46xx_clear_BA1(chip, DSP_CODE_BYTE_OFFSET, DSP_CODE_BYTE_SIZE);
-
- for (i = 0; i < ins->nmodules; i++) {
- struct dsp_module_desc *module = &ins->modules[i];
- struct dsp_segment_desc *seg;
- u32 doffset, dsize;
-
- seg = get_segment_desc(module, SEGTYPE_SP_PARAMETER);
- err = dsp_load_parameter(chip, seg);
- if (err < 0)
- return err;
-
- seg = get_segment_desc(module, SEGTYPE_SP_SAMPLE);
- err = dsp_load_sample(chip, seg);
- if (err < 0)
- return err;
-
- seg = get_segment_desc(module, SEGTYPE_SP_PROGRAM);
- if (!seg)
- continue;
-
- doffset = seg->offset * 4 + module->load_address * 4
- + DSP_CODE_BYTE_OFFSET;
- dsize = seg->size * 4;
- err = snd_cs46xx_download(chip,
- ins->code.data + module->load_address,
- doffset, dsize);
- if (err < 0)
- return err;
- }
-
- for (i = 0; i < ins->ntask; i++) {
- struct dsp_task_descriptor *t = &ins->tasks[i];
- _dsp_create_task_tree(chip, t->data, t->address, t->size);
- }
-
- for (i = 0; i < ins->nscb; i++) {
- struct dsp_scb_descriptor *s = &ins->scbs[i];
- if (s->deleted)
- continue;
- _dsp_create_scb(chip, s->data, s->address);
- }
- for (i = 0; i < ins->nscb; i++) {
- struct dsp_scb_descriptor *s = &ins->scbs[i];
- if (s->deleted)
- continue;
- if (s->updated)
- cs46xx_dsp_spos_update_scb(chip, s);
- if (s->volume_set)
- cs46xx_dsp_scb_set_volume(chip, s,
- s->volume[0], s->volume[1]);
- }
- if (ins->spdif_status_out & DSP_SPDIF_STATUS_HW_ENABLED) {
- cs46xx_dsp_enable_spdif_hw(chip);
- snd_cs46xx_poke(chip, (ins->ref_snoop_scb->address + 2) << 2,
- (OUTPUT_SNOOP_BUFFER + 0x10) << 0x10);
- if (ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN)
- cs46xx_poke_via_dsp(chip, SP_SPDOUT_CSUV,
- ins->spdif_csuv_stream);
- }
- if (chip->dsp_spos_instance->spdif_status_in) {
- cs46xx_poke_via_dsp(chip, SP_ASER_COUNTDOWN, 0x80000005);
- cs46xx_poke_via_dsp(chip, SP_SPDIN_CONTROL, 0x800003ff);
- }
- return 0;
-}
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/cs46xx/dsp_spos.h b/ANDROID_3.4.5/sound/pci/cs46xx/dsp_spos.h
deleted file mode 100644
index ca47a811..00000000
--- a/ANDROID_3.4.5/sound/pci/cs46xx/dsp_spos.h
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- * 2002-07 Benny Sjostrand benny@hostmobility.com
- */
-
-#ifdef CONFIG_SND_CS46XX_NEW_DSP /* hack ... */
-#ifndef __DSP_SPOS_H__
-#define __DSP_SPOS_H__
-
-#define DSP_MAX_SYMBOLS 1024
-#define DSP_MAX_MODULES 64
-
-#define DSP_CODE_BYTE_SIZE 0x00007000UL
-#define DSP_PARAMETER_BYTE_SIZE 0x00003000UL
-#define DSP_SAMPLE_BYTE_SIZE 0x00003800UL
-#define DSP_PARAMETER_BYTE_OFFSET 0x00000000UL
-#define DSP_SAMPLE_BYTE_OFFSET 0x00010000UL
-#define DSP_CODE_BYTE_OFFSET 0x00020000UL
-
-#define WIDE_INSTR_MASK 0x0040
-#define WIDE_LADD_INSTR_MASK 0x0380
-
-/* this instruction types
- needs to be reallocated when load
- code into DSP */
-enum wide_opcode {
- WIDE_FOR_BEGIN_LOOP = 0x20,
- WIDE_FOR_BEGIN_LOOP2,
-
- WIDE_COND_GOTO_ADDR = 0x30,
- WIDE_COND_GOTO_CALL,
-
- WIDE_TBEQ_COND_GOTO_ADDR = 0x70,
- WIDE_TBEQ_COND_CALL_ADDR,
- WIDE_TBEQ_NCOND_GOTO_ADDR,
- WIDE_TBEQ_NCOND_CALL_ADDR,
- WIDE_TBEQ_COND_GOTO1_ADDR,
- WIDE_TBEQ_COND_CALL1_ADDR,
- WIDE_TBEQ_NCOND_GOTOI_ADDR,
- WIDE_TBEQ_NCOND_CALL1_ADDR,
-};
-
-/* SAMPLE segment */
-#define VARI_DECIMATE_BUF1 0x0000
-#define WRITE_BACK_BUF1 0x0400
-#define CODEC_INPUT_BUF1 0x0500
-#define PCM_READER_BUF1 0x0600
-#define SRC_DELAY_BUF1 0x0680
-#define VARI_DECIMATE_BUF0 0x0780
-#define SRC_OUTPUT_BUF1 0x07A0
-#define ASYNC_IP_OUTPUT_BUFFER1 0x0A00
-#define OUTPUT_SNOOP_BUFFER 0x0B00
-#define SPDIFI_IP_OUTPUT_BUFFER1 0x0E00
-#define SPDIFO_IP_OUTPUT_BUFFER1 0x1000
-#define MIX_SAMPLE_BUF1 0x1400
-#define MIX_SAMPLE_BUF2 0x2E80
-#define MIX_SAMPLE_BUF3 0x2F00
-#define MIX_SAMPLE_BUF4 0x2F80
-#define MIX_SAMPLE_BUF5 0x3000
-
-/* Task stack address */
-#define HFG_STACK 0x066A
-#define FG_STACK 0x066E
-#define BG_STACK 0x068E
-
-/* SCB's addresses */
-#define SPOSCB_ADDR 0x070
-#define BG_TREE_SCB_ADDR 0x635
-#define NULL_SCB_ADDR 0x000
-#define TIMINGMASTER_SCB_ADDR 0x010
-#define CODECOUT_SCB_ADDR 0x020
-#define PCMREADER_SCB_ADDR 0x030
-#define WRITEBACK_SCB_ADDR 0x040
-#define CODECIN_SCB_ADDR 0x080
-#define MASTERMIX_SCB_ADDR 0x090
-#define SRCTASK_SCB_ADDR 0x0A0
-#define VARIDECIMATE_SCB_ADDR 0x0B0
-#define PCMSERIALIN_SCB_ADDR 0x0C0
-#define FG_TASK_HEADER_ADDR 0x600
-#define ASYNCTX_SCB_ADDR 0x0E0
-#define ASYNCRX_SCB_ADDR 0x0F0
-#define SRCTASKII_SCB_ADDR 0x100
-#define OUTPUTSNOOP_SCB_ADDR 0x110
-#define PCMSERIALINII_SCB_ADDR 0x120
-#define SPIOWRITE_SCB_ADDR 0x130
-#define REAR_CODECOUT_SCB_ADDR 0x140
-#define OUTPUTSNOOPII_SCB_ADDR 0x150
-#define PCMSERIALIN_PCM_SCB_ADDR 0x160
-#define RECORD_MIXER_SCB_ADDR 0x170
-#define REAR_MIXER_SCB_ADDR 0x180
-#define CLFE_MIXER_SCB_ADDR 0x190
-#define CLFE_CODEC_SCB_ADDR 0x1A0
-
-/* hyperforground SCB's*/
-#define HFG_TREE_SCB 0xBA0
-#define SPDIFI_SCB_INST 0xBB0
-#define SPDIFO_SCB_INST 0xBC0
-#define WRITE_BACK_SPB 0x0D0
-
-/* offsets */
-#define AsyncCIOFIFOPointer 0xd
-#define SPDIFOFIFOPointer 0xd
-#define SPDIFIFIFOPointer 0xd
-#define TCBData 0xb
-#define HFGFlags 0xa
-#define TCBContextBlk 0x10
-#define AFGTxAccumPhi 0x4
-#define SCBsubListPtr 0x9
-#define SCBfuncEntryPtr 0xA
-#define SRCCorPerGof 0x2
-#define SRCPhiIncr6Int26Frac 0xd
-#define SCBVolumeCtrl 0xe
-
-/* conf */
-#define UseASER1Input 1
-
-
-
-/*
- * The following defines are for the flags in the rsConfig01/23 registers of
- * the SP.
- */
-
-#define RSCONFIG_MODULO_SIZE_MASK 0x0000000FL
-#define RSCONFIG_MODULO_16 0x00000001L
-#define RSCONFIG_MODULO_32 0x00000002L
-#define RSCONFIG_MODULO_64 0x00000003L
-#define RSCONFIG_MODULO_128 0x00000004L
-#define RSCONFIG_MODULO_256 0x00000005L
-#define RSCONFIG_MODULO_512 0x00000006L
-#define RSCONFIG_MODULO_1024 0x00000007L
-#define RSCONFIG_MODULO_4 0x00000008L
-#define RSCONFIG_MODULO_8 0x00000009L
-#define RSCONFIG_SAMPLE_SIZE_MASK 0x000000C0L
-#define RSCONFIG_SAMPLE_8MONO 0x00000000L
-#define RSCONFIG_SAMPLE_8STEREO 0x00000040L
-#define RSCONFIG_SAMPLE_16MONO 0x00000080L
-#define RSCONFIG_SAMPLE_16STEREO 0x000000C0L
-#define RSCONFIG_UNDERRUN_ZERO 0x00004000L
-#define RSCONFIG_DMA_TO_HOST 0x00008000L
-#define RSCONFIG_STREAM_NUM_MASK 0x00FF0000L
-#define RSCONFIG_MAX_DMA_SIZE_MASK 0x1F000000L
-#define RSCONFIG_DMA_ENABLE 0x20000000L
-#define RSCONFIG_PRIORITY_MASK 0xC0000000L
-#define RSCONFIG_PRIORITY_HIGH 0x00000000L
-#define RSCONFIG_PRIORITY_MEDIUM_HIGH 0x40000000L
-#define RSCONFIG_PRIORITY_MEDIUM_LOW 0x80000000L
-#define RSCONFIG_PRIORITY_LOW 0xC0000000L
-#define RSCONFIG_STREAM_NUM_SHIFT 16L
-#define RSCONFIG_MAX_DMA_SIZE_SHIFT 24L
-
-/* SP constants */
-#define FG_INTERVAL_TIMER_PERIOD 0x0051
-#define BG_INTERVAL_TIMER_PERIOD 0x0100
-
-
-/* Only SP accessible registers */
-#define SP_ASER_COUNTDOWN 0x8040
-#define SP_SPDOUT_FIFO 0x0108
-#define SP_SPDIN_MI_FIFO 0x01E0
-#define SP_SPDIN_D_FIFO 0x01F0
-#define SP_SPDIN_STATUS 0x8048
-#define SP_SPDIN_CONTROL 0x8049
-#define SP_SPDIN_FIFOPTR 0x804A
-#define SP_SPDOUT_STATUS 0x804C
-#define SP_SPDOUT_CONTROL 0x804D
-#define SP_SPDOUT_CSUV 0x808E
-
-static inline u8 _wrap_all_bits (u8 val)
-{
- u8 wrapped;
-
- /* wrap all 8 bits */
- wrapped =
- ((val & 0x1 ) << 7) |
- ((val & 0x2 ) << 5) |
- ((val & 0x4 ) << 3) |
- ((val & 0x8 ) << 1) |
- ((val & 0x10) >> 1) |
- ((val & 0x20) >> 3) |
- ((val & 0x40) >> 5) |
- ((val & 0x80) >> 7);
-
- return wrapped;
-}
-
-static inline void cs46xx_dsp_spos_update_scb (struct snd_cs46xx * chip,
- struct dsp_scb_descriptor * scb)
-{
- /* update nextSCB and subListPtr in SCB */
- snd_cs46xx_poke(chip,
- (scb->address + SCBsubListPtr) << 2,
- (scb->sub_list_ptr->address << 0x10) |
- (scb->next_scb_ptr->address));
- scb->updated = 1;
-}
-
-static inline void cs46xx_dsp_scb_set_volume (struct snd_cs46xx * chip,
- struct dsp_scb_descriptor * scb,
- u16 left, u16 right)
-{
- unsigned int val = ((0xffff - left) << 16 | (0xffff - right));
-
- snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val);
- snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl + 1) << 2, val);
- scb->volume_set = 1;
- scb->volume[0] = left;
- scb->volume[1] = right;
-}
-#endif /* __DSP_SPOS_H__ */
-#endif /* CONFIG_SND_CS46XX_NEW_DSP */
diff --git a/ANDROID_3.4.5/sound/pci/cs46xx/dsp_spos_scb_lib.c b/ANDROID_3.4.5/sound/pci/cs46xx/dsp_spos_scb_lib.c
deleted file mode 100644
index 00b148a1..00000000
--- a/ANDROID_3.4.5/sound/pci/cs46xx/dsp_spos_scb_lib.c
+++ /dev/null
@@ -1,1784 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- * 2002-07 Benny Sjostrand benny@hostmobility.com
- */
-
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/info.h>
-#include <sound/cs46xx.h>
-
-#include "cs46xx_lib.h"
-#include "dsp_spos.h"
-
-struct proc_scb_info {
- struct dsp_scb_descriptor * scb_desc;
- struct snd_cs46xx *chip;
-};
-
-static void remove_symbol (struct snd_cs46xx * chip, struct dsp_symbol_entry * symbol)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- int symbol_index = (int)(symbol - ins->symbol_table.symbols);
-
- if (snd_BUG_ON(ins->symbol_table.nsymbols <= 0))
- return;
- if (snd_BUG_ON(symbol_index < 0 ||
- symbol_index >= ins->symbol_table.nsymbols))
- return;
-
- ins->symbol_table.symbols[symbol_index].deleted = 1;
-
- if (symbol_index < ins->symbol_table.highest_frag_index) {
- ins->symbol_table.highest_frag_index = symbol_index;
- }
-
- if (symbol_index == ins->symbol_table.nsymbols - 1)
- ins->symbol_table.nsymbols --;
-
- if (ins->symbol_table.highest_frag_index > ins->symbol_table.nsymbols) {
- ins->symbol_table.highest_frag_index = ins->symbol_table.nsymbols;
- }
-
-}
-
-#ifdef CONFIG_PROC_FS
-static void cs46xx_dsp_proc_scb_info_read (struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct proc_scb_info * scb_info = entry->private_data;
- struct dsp_scb_descriptor * scb = scb_info->scb_desc;
- struct dsp_spos_instance * ins;
- struct snd_cs46xx *chip = scb_info->chip;
- int j,col;
- void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
-
- ins = chip->dsp_spos_instance;
-
- mutex_lock(&chip->spos_mutex);
- snd_iprintf(buffer,"%04x %s:\n",scb->address,scb->scb_name);
-
- for (col = 0,j = 0;j < 0x10; j++,col++) {
- if (col == 4) {
- snd_iprintf(buffer,"\n");
- col = 0;
- }
- snd_iprintf(buffer,"%08x ",readl(dst + (scb->address + j) * sizeof(u32)));
- }
-
- snd_iprintf(buffer,"\n");
-
- if (scb->parent_scb_ptr != NULL) {
- snd_iprintf(buffer,"parent [%s:%04x] ",
- scb->parent_scb_ptr->scb_name,
- scb->parent_scb_ptr->address);
- } else snd_iprintf(buffer,"parent [none] ");
-
- snd_iprintf(buffer,"sub_list_ptr [%s:%04x]\nnext_scb_ptr [%s:%04x] task_entry [%s:%04x]\n",
- scb->sub_list_ptr->scb_name,
- scb->sub_list_ptr->address,
- scb->next_scb_ptr->scb_name,
- scb->next_scb_ptr->address,
- scb->task_entry->symbol_name,
- scb->task_entry->address);
-
- snd_iprintf(buffer,"index [%d] ref_count [%d]\n",scb->index,scb->ref_count);
- mutex_unlock(&chip->spos_mutex);
-}
-#endif
-
-static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * scb)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- if ( scb->parent_scb_ptr ) {
- /* unlink parent SCB */
- if (snd_BUG_ON(scb->parent_scb_ptr->sub_list_ptr != scb &&
- scb->parent_scb_ptr->next_scb_ptr != scb))
- return;
-
- if (scb->parent_scb_ptr->sub_list_ptr == scb) {
-
- if (scb->next_scb_ptr == ins->the_null_scb) {
- /* last and only node in parent sublist */
- scb->parent_scb_ptr->sub_list_ptr = scb->sub_list_ptr;
-
- if (scb->sub_list_ptr != ins->the_null_scb) {
- scb->sub_list_ptr->parent_scb_ptr = scb->parent_scb_ptr;
- }
- scb->sub_list_ptr = ins->the_null_scb;
- } else {
- /* first node in parent sublist */
- scb->parent_scb_ptr->sub_list_ptr = scb->next_scb_ptr;
-
- if (scb->next_scb_ptr != ins->the_null_scb) {
- /* update next node parent ptr. */
- scb->next_scb_ptr->parent_scb_ptr = scb->parent_scb_ptr;
- }
- scb->next_scb_ptr = ins->the_null_scb;
- }
- } else {
- scb->parent_scb_ptr->next_scb_ptr = scb->next_scb_ptr;
-
- if (scb->next_scb_ptr != ins->the_null_scb) {
- /* update next node parent ptr. */
- scb->next_scb_ptr->parent_scb_ptr = scb->parent_scb_ptr;
- }
- scb->next_scb_ptr = ins->the_null_scb;
- }
-
- /* update parent first entry in DSP RAM */
- cs46xx_dsp_spos_update_scb(chip,scb->parent_scb_ptr);
-
- /* then update entry in DSP RAM */
- cs46xx_dsp_spos_update_scb(chip,scb);
-
- scb->parent_scb_ptr = NULL;
- }
-}
-
-static void _dsp_clear_sample_buffer (struct snd_cs46xx *chip, u32 sample_buffer_addr,
- int dword_count)
-{
- void __iomem *dst = chip->region.idx[2].remap_addr + sample_buffer_addr;
- int i;
-
- for (i = 0; i < dword_count ; ++i ) {
- writel(0, dst);
- dst += 4;
- }
-}
-
-void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * scb)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- unsigned long flags;
-
- /* check integrety */
- if (snd_BUG_ON(scb->index < 0 ||
- scb->index >= ins->nscb ||
- (ins->scbs + scb->index) != scb))
- return;
-
-#if 0
- /* can't remove a SCB with childs before
- removing childs first */
- if (snd_BUG_ON(scb->sub_list_ptr != ins->the_null_scb ||
- scb->next_scb_ptr != ins->the_null_scb))
- goto _end;
-#endif
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- _dsp_unlink_scb (chip,scb);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- cs46xx_dsp_proc_free_scb_desc(scb);
- if (snd_BUG_ON(!scb->scb_symbol))
- return;
- remove_symbol (chip,scb->scb_symbol);
-
- ins->scbs[scb->index].deleted = 1;
-#ifdef CONFIG_PM
- kfree(ins->scbs[scb->index].data);
- ins->scbs[scb->index].data = NULL;
-#endif
-
- if (scb->index < ins->scb_highest_frag_index)
- ins->scb_highest_frag_index = scb->index;
-
- if (scb->index == ins->nscb - 1) {
- ins->nscb --;
- }
-
- if (ins->scb_highest_frag_index > ins->nscb) {
- ins->scb_highest_frag_index = ins->nscb;
- }
-
-#if 0
- /* !!!! THIS IS A PIECE OF SHIT MADE BY ME !!! */
- for(i = scb->index + 1;i < ins->nscb; ++i) {
- ins->scbs[i - 1].index = i - 1;
- }
-#endif
-}
-
-
-#ifdef CONFIG_PROC_FS
-void cs46xx_dsp_proc_free_scb_desc (struct dsp_scb_descriptor * scb)
-{
- if (scb->proc_info) {
- struct proc_scb_info * scb_info = scb->proc_info->private_data;
-
- snd_printdd("cs46xx_dsp_proc_free_scb_desc: freeing %s\n",scb->scb_name);
-
- snd_info_free_entry(scb->proc_info);
- scb->proc_info = NULL;
-
- kfree (scb_info);
- }
-}
-
-void cs46xx_dsp_proc_register_scb_desc (struct snd_cs46xx *chip,
- struct dsp_scb_descriptor * scb)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- struct snd_info_entry * entry;
- struct proc_scb_info * scb_info;
-
- /* register to proc */
- if (ins->snd_card != NULL && ins->proc_dsp_dir != NULL &&
- scb->proc_info == NULL) {
-
- if ((entry = snd_info_create_card_entry(ins->snd_card, scb->scb_name,
- ins->proc_dsp_dir)) != NULL) {
- scb_info = kmalloc(sizeof(struct proc_scb_info), GFP_KERNEL);
- if (!scb_info) {
- snd_info_free_entry(entry);
- entry = NULL;
- goto out;
- }
-
- scb_info->chip = chip;
- scb_info->scb_desc = scb;
-
- entry->content = SNDRV_INFO_CONTENT_TEXT;
- entry->private_data = scb_info;
- entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-
- entry->c.text.read = cs46xx_dsp_proc_scb_info_read;
-
- if (snd_info_register(entry) < 0) {
- snd_info_free_entry(entry);
- kfree (scb_info);
- entry = NULL;
- }
- }
-out:
- scb->proc_info = entry;
- }
-}
-#endif /* CONFIG_PROC_FS */
-
-static struct dsp_scb_descriptor *
-_dsp_create_generic_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u32 dest,
- struct dsp_symbol_entry * task_entry,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- struct dsp_scb_descriptor * scb;
-
- unsigned long flags;
-
- if (snd_BUG_ON(!ins->the_null_scb))
- return NULL;
-
- /* fill the data that will be wroten to DSP */
- scb_data[SCBsubListPtr] =
- (ins->the_null_scb->address << 0x10) | ins->the_null_scb->address;
-
- scb_data[SCBfuncEntryPtr] &= 0xFFFF0000;
- scb_data[SCBfuncEntryPtr] |= task_entry->address;
-
- snd_printdd("dsp_spos: creating SCB <%s>\n",name);
-
- scb = cs46xx_dsp_create_scb(chip,name,scb_data,dest);
-
-
- scb->sub_list_ptr = ins->the_null_scb;
- scb->next_scb_ptr = ins->the_null_scb;
-
- scb->parent_scb_ptr = parent_scb;
- scb->task_entry = task_entry;
-
-
- /* update parent SCB */
- if (scb->parent_scb_ptr) {
-#if 0
- printk ("scb->parent_scb_ptr = %s\n",scb->parent_scb_ptr->scb_name);
- printk ("scb->parent_scb_ptr->next_scb_ptr = %s\n",scb->parent_scb_ptr->next_scb_ptr->scb_name);
- printk ("scb->parent_scb_ptr->sub_list_ptr = %s\n",scb->parent_scb_ptr->sub_list_ptr->scb_name);
-#endif
- /* link to parent SCB */
- if (scb_child_type == SCB_ON_PARENT_NEXT_SCB) {
- if (snd_BUG_ON(scb->parent_scb_ptr->next_scb_ptr !=
- ins->the_null_scb))
- return NULL;
-
- scb->parent_scb_ptr->next_scb_ptr = scb;
-
- } else if (scb_child_type == SCB_ON_PARENT_SUBLIST_SCB) {
- if (snd_BUG_ON(scb->parent_scb_ptr->sub_list_ptr !=
- ins->the_null_scb))
- return NULL;
-
- scb->parent_scb_ptr->sub_list_ptr = scb;
- } else {
- snd_BUG();
- }
-
- spin_lock_irqsave(&chip->reg_lock, flags);
-
- /* update entry in DSP RAM */
- cs46xx_dsp_spos_update_scb(chip,scb->parent_scb_ptr);
-
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- }
-
-
- cs46xx_dsp_proc_register_scb_desc (chip,scb);
-
- return scb;
-}
-
-static struct dsp_scb_descriptor *
-cs46xx_dsp_create_generic_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data,
- u32 dest, char * task_entry_name,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type)
-{
- struct dsp_symbol_entry * task_entry;
-
- task_entry = cs46xx_dsp_lookup_symbol (chip,task_entry_name,
- SYMBOL_CODE);
-
- if (task_entry == NULL) {
- snd_printk (KERN_ERR "dsp_spos: symbol %s not found\n",task_entry_name);
- return NULL;
- }
-
- return _dsp_create_generic_scb (chip,name,scb_data,dest,task_entry,
- parent_scb,scb_child_type);
-}
-
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_timing_master_scb (struct snd_cs46xx *chip)
-{
- struct dsp_scb_descriptor * scb;
-
- struct dsp_timing_master_scb timing_master_scb = {
- { 0,
- 0,
- 0,
- 0
- },
- { 0,
- 0,
- 0,
- 0,
- 0
- },
- 0,0,
- 0,NULL_SCB_ADDR,
- 0,0, /* extraSampleAccum:TMreserved */
- 0,0, /* codecFIFOptr:codecFIFOsyncd */
- 0x0001,0x8000, /* fracSampAccumQm1:TMfrmsLeftInGroup */
- 0x0001,0x0000, /* fracSampCorrectionQm1:TMfrmGroupLength */
- 0x00060000 /* nSampPerFrmQ15 */
- };
-
- scb = cs46xx_dsp_create_generic_scb(chip,"TimingMasterSCBInst",(u32 *)&timing_master_scb,
- TIMINGMASTER_SCB_ADDR,
- "TIMINGMASTER",NULL,SCB_NO_PARENT);
-
- return scb;
-}
-
-
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_codec_out_scb(struct snd_cs46xx * chip, char * codec_name,
- u16 channel_disp, u16 fifo_addr, u16 child_scb_addr,
- u32 dest, struct dsp_scb_descriptor * parent_scb,
- int scb_child_type)
-{
- struct dsp_scb_descriptor * scb;
-
- struct dsp_codec_output_scb codec_out_scb = {
- { 0,
- 0,
- 0,
- 0
- },
- {
- 0,
- 0,
- 0,
- 0,
- 0
- },
- 0,0,
- 0,NULL_SCB_ADDR,
- 0, /* COstrmRsConfig */
- 0, /* COstrmBufPtr */
- channel_disp,fifo_addr, /* leftChanBaseIOaddr:rightChanIOdisp */
- 0x0000,0x0080, /* (!AC97!) COexpVolChangeRate:COscaleShiftCount */
- 0,child_scb_addr /* COreserved - need child scb to work with rom code */
- };
-
-
- scb = cs46xx_dsp_create_generic_scb(chip,codec_name,(u32 *)&codec_out_scb,
- dest,"S16_CODECOUTPUTTASK",parent_scb,
- scb_child_type);
-
- return scb;
-}
-
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_codec_in_scb(struct snd_cs46xx * chip, char * codec_name,
- u16 channel_disp, u16 fifo_addr, u16 sample_buffer_addr,
- u32 dest, struct dsp_scb_descriptor * parent_scb,
- int scb_child_type)
-{
-
- struct dsp_scb_descriptor * scb;
- struct dsp_codec_input_scb codec_input_scb = {
- { 0,
- 0,
- 0,
- 0
- },
- {
- 0,
- 0,
- 0,
- 0,
- 0
- },
-
-#if 0 /* cs4620 */
- SyncIOSCB,NULL_SCB_ADDR
-#else
- 0 , 0,
-#endif
- 0,0,
-
- RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_64, /* strmRsConfig */
- sample_buffer_addr << 0x10, /* strmBufPtr; defined as a dword ptr, used as a byte ptr */
- channel_disp,fifo_addr, /* (!AC97!) leftChanBaseINaddr=AC97primary
- link input slot 3 :rightChanINdisp=""slot 4 */
- 0x0000,0x0000, /* (!AC97!) ????:scaleShiftCount; no shift needed
- because AC97 is already 20 bits */
- 0x80008000 /* ??clw cwcgame.scb has 0 */
- };
-
- scb = cs46xx_dsp_create_generic_scb(chip,codec_name,(u32 *)&codec_input_scb,
- dest,"S16_CODECINPUTTASK",parent_scb,
- scb_child_type);
- return scb;
-}
-
-
-static struct dsp_scb_descriptor *
-cs46xx_dsp_create_pcm_reader_scb(struct snd_cs46xx * chip, char * scb_name,
- u16 sample_buffer_addr, u32 dest,
- int virtual_channel, u32 playback_hw_addr,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- struct dsp_scb_descriptor * scb;
-
- struct dsp_generic_scb pcm_reader_scb = {
-
- /*
- Play DMA Task xfers data from host buffer to SP buffer
- init/runtime variables:
- PlayAC: Play Audio Data Conversion - SCB loc: 2nd dword, mask: 0x0000F000L
- DATA_FMT_16BIT_ST_LTLEND(0x00000000L) from 16-bit stereo, little-endian
- DATA_FMT_8_BIT_ST_SIGNED(0x00001000L) from 8-bit stereo, signed
- DATA_FMT_16BIT_MN_LTLEND(0x00002000L) from 16-bit mono, little-endian
- DATA_FMT_8_BIT_MN_SIGNED(0x00003000L) from 8-bit mono, signed
- DATA_FMT_16BIT_ST_BIGEND(0x00004000L) from 16-bit stereo, big-endian
- DATA_FMT_16BIT_MN_BIGEND(0x00006000L) from 16-bit mono, big-endian
- DATA_FMT_8_BIT_ST_UNSIGNED(0x00009000L) from 8-bit stereo, unsigned
- DATA_FMT_8_BIT_MN_UNSIGNED(0x0000b000L) from 8-bit mono, unsigned
- ? Other combinations possible from:
- DMA_RQ_C2_AUDIO_CONVERT_MASK 0x0000F000L
- DMA_RQ_C2_AC_NONE 0x00000000L
- DMA_RQ_C2_AC_8_TO_16_BIT 0x00001000L
- DMA_RQ_C2_AC_MONO_TO_STEREO 0x00002000L
- DMA_RQ_C2_AC_ENDIAN_CONVERT 0x00004000L
- DMA_RQ_C2_AC_SIGNED_CONVERT 0x00008000L
-
- HostBuffAddr: Host Buffer Physical Byte Address - SCB loc:3rd dword, Mask: 0xFFFFFFFFL
- aligned to dword boundary
- */
- /* Basic (non scatter/gather) DMA requestor (4 ints) */
- { DMA_RQ_C1_SOURCE_ON_HOST + /* source buffer is on the host */
- DMA_RQ_C1_SOURCE_MOD1024 + /* source buffer is 1024 dwords (4096 bytes) */
- DMA_RQ_C1_DEST_MOD32 + /* dest buffer(PCMreaderBuf) is 32 dwords*/
- DMA_RQ_C1_WRITEBACK_SRC_FLAG + /* ?? */
- DMA_RQ_C1_WRITEBACK_DEST_FLAG + /* ?? */
- 15, /* DwordCount-1: picked 16 for DwordCount because Jim */
- /* Barnette said that is what we should use since */
- /* we are not running in optimized mode? */
- DMA_RQ_C2_AC_NONE +
- DMA_RQ_C2_SIGNAL_SOURCE_PINGPONG + /* set play interrupt (bit0) in HISR when source */
- /* buffer (on host) crosses half-way point */
- virtual_channel, /* Play DMA channel arbitrarily set to 0 */
- playback_hw_addr, /* HostBuffAddr (source) */
- DMA_RQ_SD_SP_SAMPLE_ADDR + /* destination buffer is in SP Sample Memory */
- sample_buffer_addr /* SP Buffer Address (destination) */
- },
- /* Scatter/gather DMA requestor extension (5 ints) */
- {
- 0,
- 0,
- 0,
- 0,
- 0
- },
- /* Sublist pointer & next stream control block (SCB) link. */
- NULL_SCB_ADDR,NULL_SCB_ADDR,
- /* Pointer to this tasks parameter block & stream function pointer */
- 0,NULL_SCB_ADDR,
- /* rsConfig register for stream buffer (rsDMA reg. is loaded from basicReq.daw */
- /* for incoming streams, or basicReq.saw, for outgoing streams) */
- RSCONFIG_DMA_ENABLE + /* enable DMA */
- (19 << RSCONFIG_MAX_DMA_SIZE_SHIFT) + /* MAX_DMA_SIZE picked to be 19 since SPUD */
- /* uses it for some reason */
- ((dest >> 4) << RSCONFIG_STREAM_NUM_SHIFT) + /* stream number = SCBaddr/16 */
- RSCONFIG_SAMPLE_16STEREO +
- RSCONFIG_MODULO_32, /* dest buffer(PCMreaderBuf) is 32 dwords (256 bytes) */
- /* Stream sample pointer & MAC-unit mode for this stream */
- (sample_buffer_addr << 0x10),
- /* Fractional increment per output sample in the input sample buffer */
- 0,
- {
- /* Standard stereo volume control
- default muted */
- 0xffff,0xffff,
- 0xffff,0xffff
- }
- };
-
- if (ins->null_algorithm == NULL) {
- ins->null_algorithm = cs46xx_dsp_lookup_symbol (chip,"NULLALGORITHM",
- SYMBOL_CODE);
-
- if (ins->null_algorithm == NULL) {
- snd_printk (KERN_ERR "dsp_spos: symbol NULLALGORITHM not found\n");
- return NULL;
- }
- }
-
- scb = _dsp_create_generic_scb(chip,scb_name,(u32 *)&pcm_reader_scb,
- dest,ins->null_algorithm,parent_scb,
- scb_child_type);
-
- return scb;
-}
-
-#define GOF_PER_SEC 200
-
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_src_task_scb(struct snd_cs46xx * chip, char * scb_name,
- int rate,
- u16 src_buffer_addr,
- u16 src_delay_buffer_addr, u32 dest,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type,
- int pass_through)
-{
-
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- struct dsp_scb_descriptor * scb;
- unsigned int tmp1, tmp2;
- unsigned int phiIncr;
- unsigned int correctionPerGOF, correctionPerSec;
-
- snd_printdd( "dsp_spos: setting %s rate to %u\n",scb_name,rate);
-
- /*
- * Compute the values used to drive the actual sample rate conversion.
- * The following formulas are being computed, using inline assembly
- * since we need to use 64 bit arithmetic to compute the values:
- *
- * phiIncr = floor((Fs,in * 2^26) / Fs,out)
- * correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) /
- * GOF_PER_SEC)
- * ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -M
- * GOF_PER_SEC * correctionPerGOF
- *
- * i.e.
- *
- * phiIncr:other = dividend:remainder((Fs,in * 2^26) / Fs,out)
- * correctionPerGOF:correctionPerSec =
- * dividend:remainder(ulOther / GOF_PER_SEC)
- */
- tmp1 = rate << 16;
- phiIncr = tmp1 / 48000;
- tmp1 -= phiIncr * 48000;
- tmp1 <<= 10;
- phiIncr <<= 10;
- tmp2 = tmp1 / 48000;
- phiIncr += tmp2;
- tmp1 -= tmp2 * 48000;
- correctionPerGOF = tmp1 / GOF_PER_SEC;
- tmp1 -= correctionPerGOF * GOF_PER_SEC;
- correctionPerSec = tmp1;
-
- {
- struct dsp_src_task_scb src_task_scb = {
- 0x0028,0x00c8,
- 0x5555,0x0000,
- 0x0000,0x0000,
- src_buffer_addr,1,
- correctionPerGOF,correctionPerSec,
- RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_32,
- 0x0000,src_delay_buffer_addr,
- 0x0,
- 0x080,(src_delay_buffer_addr + (24 * 4)),
- 0,0, /* next_scb, sub_list_ptr */
- 0,0, /* entry, this_spb */
- RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_8,
- src_buffer_addr << 0x10,
- phiIncr,
- {
- 0xffff - ins->dac_volume_right,0xffff - ins->dac_volume_left,
- 0xffff - ins->dac_volume_right,0xffff - ins->dac_volume_left
- }
- };
-
- if (ins->s16_up == NULL) {
- ins->s16_up = cs46xx_dsp_lookup_symbol (chip,"S16_UPSRC",
- SYMBOL_CODE);
-
- if (ins->s16_up == NULL) {
- snd_printk (KERN_ERR "dsp_spos: symbol S16_UPSRC not found\n");
- return NULL;
- }
- }
-
- /* clear buffers */
- _dsp_clear_sample_buffer (chip,src_buffer_addr,8);
- _dsp_clear_sample_buffer (chip,src_delay_buffer_addr,32);
-
- if (pass_through) {
- /* wont work with any other rate than
- the native DSP rate */
- snd_BUG_ON(rate != 48000);
-
- scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&src_task_scb,
- dest,"DMAREADER",parent_scb,
- scb_child_type);
- } else {
- scb = _dsp_create_generic_scb(chip,scb_name,(u32 *)&src_task_scb,
- dest,ins->s16_up,parent_scb,
- scb_child_type);
- }
-
-
- }
-
- return scb;
-}
-
-#if 0 /* not used */
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_filter_scb(struct snd_cs46xx * chip, char * scb_name,
- u16 buffer_addr, u32 dest,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type) {
- struct dsp_scb_descriptor * scb;
-
- struct dsp_filter_scb filter_scb = {
- .a0_right = 0x41a9,
- .a0_left = 0x41a9,
- .a1_right = 0xb8e4,
- .a1_left = 0xb8e4,
- .a2_right = 0x3e55,
- .a2_left = 0x3e55,
-
- .filter_unused3 = 0x0000,
- .filter_unused2 = 0x0000,
-
- .output_buf_ptr = buffer_addr,
- .init = 0x000,
-
- .prev_sample_output1 = 0x00000000,
- .prev_sample_output2 = 0x00000000,
-
- .prev_sample_input1 = 0x00000000,
- .prev_sample_input2 = 0x00000000,
-
- .next_scb_ptr = 0x0000,
- .sub_list_ptr = 0x0000,
-
- .entry_point = 0x0000,
- .spb_ptr = 0x0000,
-
- .b0_right = 0x0e38,
- .b0_left = 0x0e38,
- .b1_right = 0x1c71,
- .b1_left = 0x1c71,
- .b2_right = 0x0e38,
- .b2_left = 0x0e38,
- };
-
-
- scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&filter_scb,
- dest,"FILTERTASK",parent_scb,
- scb_child_type);
-
- return scb;
-}
-#endif /* not used */
-
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_mix_only_scb(struct snd_cs46xx * chip, char * scb_name,
- u16 mix_buffer_addr, u32 dest,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type)
-{
- struct dsp_scb_descriptor * scb;
-
- struct dsp_mix_only_scb master_mix_scb = {
- /* 0 */ { 0,
- /* 1 */ 0,
- /* 2 */ mix_buffer_addr,
- /* 3 */ 0
- /* */ },
- {
- /* 4 */ 0,
- /* 5 */ 0,
- /* 6 */ 0,
- /* 7 */ 0,
- /* 8 */ 0x00000080
- },
- /* 9 */ 0,0,
- /* A */ 0,0,
- /* B */ RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_32,
- /* C */ (mix_buffer_addr + (16 * 4)) << 0x10,
- /* D */ 0,
- {
- /* E */ 0x8000,0x8000,
- /* F */ 0x8000,0x8000
- }
- };
-
-
- scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&master_mix_scb,
- dest,"S16_MIX",parent_scb,
- scb_child_type);
- return scb;
-}
-
-
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_mix_to_ostream_scb(struct snd_cs46xx * chip, char * scb_name,
- u16 mix_buffer_addr, u16 writeback_spb, u32 dest,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type)
-{
- struct dsp_scb_descriptor * scb;
-
- struct dsp_mix2_ostream_scb mix2_ostream_scb = {
- /* Basic (non scatter/gather) DMA requestor (4 ints) */
- {
- DMA_RQ_C1_SOURCE_MOD64 +
- DMA_RQ_C1_DEST_ON_HOST +
- DMA_RQ_C1_DEST_MOD1024 +
- DMA_RQ_C1_WRITEBACK_SRC_FLAG +
- DMA_RQ_C1_WRITEBACK_DEST_FLAG +
- 15,
-
- DMA_RQ_C2_AC_NONE +
- DMA_RQ_C2_SIGNAL_DEST_PINGPONG +
-
- CS46XX_DSP_CAPTURE_CHANNEL,
- DMA_RQ_SD_SP_SAMPLE_ADDR +
- mix_buffer_addr,
- 0x0
- },
-
- { 0, 0, 0, 0, 0, },
- 0,0,
- 0,writeback_spb,
-
- RSCONFIG_DMA_ENABLE +
- (19 << RSCONFIG_MAX_DMA_SIZE_SHIFT) +
-
- ((dest >> 4) << RSCONFIG_STREAM_NUM_SHIFT) +
- RSCONFIG_DMA_TO_HOST +
- RSCONFIG_SAMPLE_16STEREO +
- RSCONFIG_MODULO_64,
- (mix_buffer_addr + (32 * 4)) << 0x10,
- 1,0,
- 0x0001,0x0080,
- 0xFFFF,0
- };
-
-
- scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&mix2_ostream_scb,
-
- dest,"S16_MIX_TO_OSTREAM",parent_scb,
- scb_child_type);
-
- return scb;
-}
-
-
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_vari_decimate_scb(struct snd_cs46xx * chip,char * scb_name,
- u16 vari_buffer_addr0,
- u16 vari_buffer_addr1,
- u32 dest,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type)
-{
-
- struct dsp_scb_descriptor * scb;
-
- struct dsp_vari_decimate_scb vari_decimate_scb = {
- 0x0028,0x00c8,
- 0x5555,0x0000,
- 0x0000,0x0000,
- vari_buffer_addr0,vari_buffer_addr1,
-
- 0x0028,0x00c8,
- RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_256,
-
- 0xFF800000,
- 0,
- 0x0080,vari_buffer_addr1 + (25 * 4),
-
- 0,0,
- 0,0,
-
- RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_8,
- vari_buffer_addr0 << 0x10,
- 0x04000000,
- {
- 0x8000,0x8000,
- 0xFFFF,0xFFFF
- }
- };
-
- scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&vari_decimate_scb,
- dest,"VARIDECIMATE",parent_scb,
- scb_child_type);
-
- return scb;
-}
-
-
-static struct dsp_scb_descriptor *
-cs46xx_dsp_create_pcm_serial_input_scb(struct snd_cs46xx * chip, char * scb_name, u32 dest,
- struct dsp_scb_descriptor * input_scb,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type)
-{
-
- struct dsp_scb_descriptor * scb;
-
-
- struct dsp_pcm_serial_input_scb pcm_serial_input_scb = {
- { 0,
- 0,
- 0,
- 0
- },
- {
- 0,
- 0,
- 0,
- 0,
- 0
- },
-
- 0,0,
- 0,0,
-
- RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_16,
- 0,
- /* 0xD */ 0,input_scb->address,
- {
- /* 0xE */ 0x8000,0x8000,
- /* 0xF */ 0x8000,0x8000
- }
- };
-
- scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&pcm_serial_input_scb,
- dest,"PCMSERIALINPUTTASK",parent_scb,
- scb_child_type);
- return scb;
-}
-
-
-static struct dsp_scb_descriptor *
-cs46xx_dsp_create_asynch_fg_tx_scb(struct snd_cs46xx * chip, char * scb_name, u32 dest,
- u16 hfg_scb_address,
- u16 asynch_buffer_address,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type)
-{
-
- struct dsp_scb_descriptor * scb;
-
- struct dsp_asynch_fg_tx_scb asynch_fg_tx_scb = {
- 0xfc00,0x03ff, /* Prototype sample buffer size of 256 dwords */
- 0x0058,0x0028, /* Min Delta 7 dwords == 28 bytes */
- /* : Max delta 25 dwords == 100 bytes */
- 0,hfg_scb_address, /* Point to HFG task SCB */
- 0,0, /* Initialize current Delta and Consumer ptr adjustment count */
- 0, /* Initialize accumulated Phi to 0 */
- 0,0x2aab, /* Const 1/3 */
-
- {
- 0, /* Define the unused elements */
- 0,
- 0
- },
-
- 0,0,
- 0,dest + AFGTxAccumPhi,
-
- RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_256, /* Stereo, 256 dword */
- (asynch_buffer_address) << 0x10, /* This should be automagically synchronized
- to the producer pointer */
-
- /* There is no correct initial value, it will depend upon the detected
- rate etc */
- 0x18000000, /* Phi increment for approx 32k operation */
- 0x8000,0x8000, /* Volume controls are unused at this time */
- 0x8000,0x8000
- };
-
- scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&asynch_fg_tx_scb,
- dest,"ASYNCHFGTXCODE",parent_scb,
- scb_child_type);
-
- return scb;
-}
-
-
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_asynch_fg_rx_scb(struct snd_cs46xx * chip, char * scb_name, u32 dest,
- u16 hfg_scb_address,
- u16 asynch_buffer_address,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- struct dsp_scb_descriptor * scb;
-
- struct dsp_asynch_fg_rx_scb asynch_fg_rx_scb = {
- 0xfe00,0x01ff, /* Prototype sample buffer size of 128 dwords */
- 0x0064,0x001c, /* Min Delta 7 dwords == 28 bytes */
- /* : Max delta 25 dwords == 100 bytes */
- 0,hfg_scb_address, /* Point to HFG task SCB */
- 0,0, /* Initialize current Delta and Consumer ptr adjustment count */
- {
- 0, /* Define the unused elements */
- 0,
- 0,
- 0,
- 0
- },
-
- 0,0,
- 0,dest,
-
- RSCONFIG_MODULO_128 |
- RSCONFIG_SAMPLE_16STEREO, /* Stereo, 128 dword */
- ( (asynch_buffer_address + (16 * 4)) << 0x10), /* This should be automagically
- synchrinized to the producer pointer */
-
- /* There is no correct initial value, it will depend upon the detected
- rate etc */
- 0x18000000,
-
- /* Set IEC958 input volume */
- 0xffff - ins->spdif_input_volume_right,0xffff - ins->spdif_input_volume_left,
- 0xffff - ins->spdif_input_volume_right,0xffff - ins->spdif_input_volume_left,
- };
-
- scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&asynch_fg_rx_scb,
- dest,"ASYNCHFGRXCODE",parent_scb,
- scb_child_type);
-
- return scb;
-}
-
-
-#if 0 /* not used */
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_output_snoop_scb(struct snd_cs46xx * chip, char * scb_name, u32 dest,
- u16 snoop_buffer_address,
- struct dsp_scb_descriptor * snoop_scb,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type)
-{
-
- struct dsp_scb_descriptor * scb;
-
- struct dsp_output_snoop_scb output_snoop_scb = {
- { 0, /* not used. Zero */
- 0,
- 0,
- 0,
- },
- {
- 0, /* not used. Zero */
- 0,
- 0,
- 0,
- 0
- },
-
- 0,0,
- 0,0,
-
- RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_64,
- snoop_buffer_address << 0x10,
- 0,0,
- 0,
- 0,snoop_scb->address
- };
-
- scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&output_snoop_scb,
- dest,"OUTPUTSNOOP",parent_scb,
- scb_child_type);
- return scb;
-}
-#endif /* not used */
-
-
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_spio_write_scb(struct snd_cs46xx * chip, char * scb_name, u32 dest,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type)
-{
- struct dsp_scb_descriptor * scb;
-
- struct dsp_spio_write_scb spio_write_scb = {
- 0,0, /* SPIOWAddress2:SPIOWAddress1; */
- 0, /* SPIOWData1; */
- 0, /* SPIOWData2; */
- 0,0, /* SPIOWAddress4:SPIOWAddress3; */
- 0, /* SPIOWData3; */
- 0, /* SPIOWData4; */
- 0,0, /* SPIOWDataPtr:Unused1; */
- { 0,0 }, /* Unused2[2]; */
-
- 0,0, /* SPIOWChildPtr:SPIOWSiblingPtr; */
- 0,0, /* SPIOWThisPtr:SPIOWEntryPoint; */
-
- {
- 0,
- 0,
- 0,
- 0,
- 0 /* Unused3[5]; */
- }
- };
-
- scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&spio_write_scb,
- dest,"SPIOWRITE",parent_scb,
- scb_child_type);
-
- return scb;
-}
-
-struct dsp_scb_descriptor *
-cs46xx_dsp_create_magic_snoop_scb(struct snd_cs46xx * chip, char * scb_name, u32 dest,
- u16 snoop_buffer_address,
- struct dsp_scb_descriptor * snoop_scb,
- struct dsp_scb_descriptor * parent_scb,
- int scb_child_type)
-{
- struct dsp_scb_descriptor * scb;
-
- struct dsp_magic_snoop_task magic_snoop_scb = {
- /* 0 */ 0, /* i0 */
- /* 1 */ 0, /* i1 */
- /* 2 */ snoop_buffer_address << 0x10,
- /* 3 */ 0,snoop_scb->address,
- /* 4 */ 0, /* i3 */
- /* 5 */ 0, /* i4 */
- /* 6 */ 0, /* i5 */
- /* 7 */ 0, /* i6 */
- /* 8 */ 0, /* i7 */
- /* 9 */ 0,0, /* next_scb, sub_list_ptr */
- /* A */ 0,0, /* entry_point, this_ptr */
- /* B */ RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_64,
- /* C */ snoop_buffer_address << 0x10,
- /* D */ 0,
- /* E */ { 0x8000,0x8000,
- /* F */ 0xffff,0xffff
- }
- };
-
- scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&magic_snoop_scb,
- dest,"MAGICSNOOPTASK",parent_scb,
- scb_child_type);
-
- return scb;
-}
-
-static struct dsp_scb_descriptor *
-find_next_free_scb (struct snd_cs46xx * chip, struct dsp_scb_descriptor * from)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- struct dsp_scb_descriptor * scb = from;
-
- while (scb->next_scb_ptr != ins->the_null_scb) {
- if (snd_BUG_ON(!scb->next_scb_ptr))
- return NULL;
-
- scb = scb->next_scb_ptr;
- }
-
- return scb;
-}
-
-static u32 pcm_reader_buffer_addr[DSP_MAX_PCM_CHANNELS] = {
- 0x0600, /* 1 */
- 0x1500, /* 2 */
- 0x1580, /* 3 */
- 0x1600, /* 4 */
- 0x1680, /* 5 */
- 0x1700, /* 6 */
- 0x1780, /* 7 */
- 0x1800, /* 8 */
- 0x1880, /* 9 */
- 0x1900, /* 10 */
- 0x1980, /* 11 */
- 0x1A00, /* 12 */
- 0x1A80, /* 13 */
- 0x1B00, /* 14 */
- 0x1B80, /* 15 */
- 0x1C00, /* 16 */
- 0x1C80, /* 17 */
- 0x1D00, /* 18 */
- 0x1D80, /* 19 */
- 0x1E00, /* 20 */
- 0x1E80, /* 21 */
- 0x1F00, /* 22 */
- 0x1F80, /* 23 */
- 0x2000, /* 24 */
- 0x2080, /* 25 */
- 0x2100, /* 26 */
- 0x2180, /* 27 */
- 0x2200, /* 28 */
- 0x2280, /* 29 */
- 0x2300, /* 30 */
- 0x2380, /* 31 */
- 0x2400, /* 32 */
-};
-
-static u32 src_output_buffer_addr[DSP_MAX_SRC_NR] = {
- 0x2B80,
- 0x2BA0,
- 0x2BC0,
- 0x2BE0,
- 0x2D00,
- 0x2D20,
- 0x2D40,
- 0x2D60,
- 0x2D80,
- 0x2DA0,
- 0x2DC0,
- 0x2DE0,
- 0x2E00,
- 0x2E20
-};
-
-static u32 src_delay_buffer_addr[DSP_MAX_SRC_NR] = {
- 0x2480,
- 0x2500,
- 0x2580,
- 0x2600,
- 0x2680,
- 0x2700,
- 0x2780,
- 0x2800,
- 0x2880,
- 0x2900,
- 0x2980,
- 0x2A00,
- 0x2A80,
- 0x2B00
-};
-
-struct dsp_pcm_channel_descriptor *
-cs46xx_dsp_create_pcm_channel (struct snd_cs46xx * chip,
- u32 sample_rate, void * private_data,
- u32 hw_dma_addr,
- int pcm_channel_id)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- struct dsp_scb_descriptor * src_scb = NULL, * pcm_scb, * mixer_scb = NULL;
- struct dsp_scb_descriptor * src_parent_scb = NULL;
-
- /* struct dsp_scb_descriptor * pcm_parent_scb; */
- char scb_name[DSP_MAX_SCB_NAME];
- int i, pcm_index = -1, insert_point, src_index = -1, pass_through = 0;
- unsigned long flags;
-
- switch (pcm_channel_id) {
- case DSP_PCM_MAIN_CHANNEL:
- mixer_scb = ins->master_mix_scb;
- break;
- case DSP_PCM_REAR_CHANNEL:
- mixer_scb = ins->rear_mix_scb;
- break;
- case DSP_PCM_CENTER_LFE_CHANNEL:
- mixer_scb = ins->center_lfe_mix_scb;
- break;
- case DSP_PCM_S71_CHANNEL:
- /* TODO */
- snd_BUG();
- break;
- case DSP_IEC958_CHANNEL:
- if (snd_BUG_ON(!ins->asynch_tx_scb))
- return NULL;
- mixer_scb = ins->asynch_tx_scb;
-
- /* if sample rate is set to 48khz we pass
- the Sample Rate Converted (which could
- alter the raw data stream ...) */
- if (sample_rate == 48000) {
- snd_printdd ("IEC958 pass through\n");
- /* Hack to bypass creating a new SRC */
- pass_through = 1;
- }
- break;
- default:
- snd_BUG();
- return NULL;
- }
- /* default sample rate is 44100 */
- if (!sample_rate) sample_rate = 44100;
-
- /* search for a already created SRC SCB with the same sample rate */
- for (i = 0; i < DSP_MAX_PCM_CHANNELS &&
- (pcm_index == -1 || src_scb == NULL); ++i) {
-
- /* virtual channel reserved
- for capture */
- if (i == CS46XX_DSP_CAPTURE_CHANNEL) continue;
-
- if (ins->pcm_channels[i].active) {
- if (!src_scb &&
- ins->pcm_channels[i].sample_rate == sample_rate &&
- ins->pcm_channels[i].mixer_scb == mixer_scb) {
- src_scb = ins->pcm_channels[i].src_scb;
- ins->pcm_channels[i].src_scb->ref_count ++;
- src_index = ins->pcm_channels[i].src_slot;
- }
- } else if (pcm_index == -1) {
- pcm_index = i;
- }
- }
-
- if (pcm_index == -1) {
- snd_printk (KERN_ERR "dsp_spos: no free PCM channel\n");
- return NULL;
- }
-
- if (src_scb == NULL) {
- if (ins->nsrc_scb >= DSP_MAX_SRC_NR) {
- snd_printk(KERN_ERR "dsp_spos: to many SRC instances\n!");
- return NULL;
- }
-
- /* find a free slot */
- for (i = 0; i < DSP_MAX_SRC_NR; ++i) {
- if (ins->src_scb_slots[i] == 0) {
- src_index = i;
- ins->src_scb_slots[i] = 1;
- break;
- }
- }
- if (snd_BUG_ON(src_index == -1))
- return NULL;
-
- /* we need to create a new SRC SCB */
- if (mixer_scb->sub_list_ptr == ins->the_null_scb) {
- src_parent_scb = mixer_scb;
- insert_point = SCB_ON_PARENT_SUBLIST_SCB;
- } else {
- src_parent_scb = find_next_free_scb(chip,mixer_scb->sub_list_ptr);
- insert_point = SCB_ON_PARENT_NEXT_SCB;
- }
-
- snprintf (scb_name,DSP_MAX_SCB_NAME,"SrcTask_SCB%d",src_index);
-
- snd_printdd( "dsp_spos: creating SRC \"%s\"\n",scb_name);
- src_scb = cs46xx_dsp_create_src_task_scb(chip,scb_name,
- sample_rate,
- src_output_buffer_addr[src_index],
- src_delay_buffer_addr[src_index],
- /* 0x400 - 0x600 source SCBs */
- 0x400 + (src_index * 0x10) ,
- src_parent_scb,
- insert_point,
- pass_through);
-
- if (!src_scb) {
- snd_printk (KERN_ERR "dsp_spos: failed to create SRCtaskSCB\n");
- return NULL;
- }
-
- /* cs46xx_dsp_set_src_sample_rate(chip,src_scb,sample_rate); */
-
- ins->nsrc_scb ++;
- }
-
-
- snprintf (scb_name,DSP_MAX_SCB_NAME,"PCMReader_SCB%d",pcm_index);
-
- snd_printdd( "dsp_spos: creating PCM \"%s\" (%d)\n",scb_name,
- pcm_channel_id);
-
- pcm_scb = cs46xx_dsp_create_pcm_reader_scb(chip,scb_name,
- pcm_reader_buffer_addr[pcm_index],
- /* 0x200 - 400 PCMreader SCBs */
- (pcm_index * 0x10) + 0x200,
- pcm_index, /* virtual channel 0-31 */
- hw_dma_addr, /* pcm hw addr */
- NULL, /* parent SCB ptr */
- 0 /* insert point */
- );
-
- if (!pcm_scb) {
- snd_printk (KERN_ERR "dsp_spos: failed to create PCMreaderSCB\n");
- return NULL;
- }
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- ins->pcm_channels[pcm_index].sample_rate = sample_rate;
- ins->pcm_channels[pcm_index].pcm_reader_scb = pcm_scb;
- ins->pcm_channels[pcm_index].src_scb = src_scb;
- ins->pcm_channels[pcm_index].unlinked = 1;
- ins->pcm_channels[pcm_index].private_data = private_data;
- ins->pcm_channels[pcm_index].src_slot = src_index;
- ins->pcm_channels[pcm_index].active = 1;
- ins->pcm_channels[pcm_index].pcm_slot = pcm_index;
- ins->pcm_channels[pcm_index].mixer_scb = mixer_scb;
- ins->npcm_channels ++;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- return (ins->pcm_channels + pcm_index);
-}
-
-int cs46xx_dsp_pcm_channel_set_period (struct snd_cs46xx * chip,
- struct dsp_pcm_channel_descriptor * pcm_channel,
- int period_size)
-{
- u32 temp = snd_cs46xx_peek (chip,pcm_channel->pcm_reader_scb->address << 2);
- temp &= ~DMA_RQ_C1_SOURCE_SIZE_MASK;
-
- switch (period_size) {
- case 2048:
- temp |= DMA_RQ_C1_SOURCE_MOD1024;
- break;
- case 1024:
- temp |= DMA_RQ_C1_SOURCE_MOD512;
- break;
- case 512:
- temp |= DMA_RQ_C1_SOURCE_MOD256;
- break;
- case 256:
- temp |= DMA_RQ_C1_SOURCE_MOD128;
- break;
- case 128:
- temp |= DMA_RQ_C1_SOURCE_MOD64;
- break;
- case 64:
- temp |= DMA_RQ_C1_SOURCE_MOD32;
- break;
- case 32:
- temp |= DMA_RQ_C1_SOURCE_MOD16;
- break;
- default:
- snd_printdd ("period size (%d) not supported by HW\n", period_size);
- return -EINVAL;
- }
-
- snd_cs46xx_poke (chip,pcm_channel->pcm_reader_scb->address << 2,temp);
-
- return 0;
-}
-
-int cs46xx_dsp_pcm_ostream_set_period (struct snd_cs46xx * chip,
- int period_size)
-{
- u32 temp = snd_cs46xx_peek (chip,WRITEBACK_SCB_ADDR << 2);
- temp &= ~DMA_RQ_C1_DEST_SIZE_MASK;
-
- switch (period_size) {
- case 2048:
- temp |= DMA_RQ_C1_DEST_MOD1024;
- break;
- case 1024:
- temp |= DMA_RQ_C1_DEST_MOD512;
- break;
- case 512:
- temp |= DMA_RQ_C1_DEST_MOD256;
- break;
- case 256:
- temp |= DMA_RQ_C1_DEST_MOD128;
- break;
- case 128:
- temp |= DMA_RQ_C1_DEST_MOD64;
- break;
- case 64:
- temp |= DMA_RQ_C1_DEST_MOD32;
- break;
- case 32:
- temp |= DMA_RQ_C1_DEST_MOD16;
- break;
- default:
- snd_printdd ("period size (%d) not supported by HW\n", period_size);
- return -EINVAL;
- }
-
- snd_cs46xx_poke (chip,WRITEBACK_SCB_ADDR << 2,temp);
-
- return 0;
-}
-
-void cs46xx_dsp_destroy_pcm_channel (struct snd_cs46xx * chip,
- struct dsp_pcm_channel_descriptor * pcm_channel)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- unsigned long flags;
-
- if (snd_BUG_ON(!pcm_channel->active ||
- ins->npcm_channels <= 0 ||
- pcm_channel->src_scb->ref_count <= 0))
- return;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- pcm_channel->unlinked = 1;
- pcm_channel->active = 0;
- pcm_channel->private_data = NULL;
- pcm_channel->src_scb->ref_count --;
- ins->npcm_channels --;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- cs46xx_dsp_remove_scb(chip,pcm_channel->pcm_reader_scb);
-
- if (!pcm_channel->src_scb->ref_count) {
- cs46xx_dsp_remove_scb(chip,pcm_channel->src_scb);
-
- if (snd_BUG_ON(pcm_channel->src_slot < 0 ||
- pcm_channel->src_slot >= DSP_MAX_SRC_NR))
- return;
-
- ins->src_scb_slots[pcm_channel->src_slot] = 0;
- ins->nsrc_scb --;
- }
-}
-
-int cs46xx_dsp_pcm_unlink (struct snd_cs46xx * chip,
- struct dsp_pcm_channel_descriptor * pcm_channel)
-{
- unsigned long flags;
-
- if (snd_BUG_ON(!pcm_channel->active ||
- chip->dsp_spos_instance->npcm_channels <= 0))
- return -EIO;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (pcm_channel->unlinked) {
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return -EIO;
- }
-
- pcm_channel->unlinked = 1;
-
- _dsp_unlink_scb (chip,pcm_channel->pcm_reader_scb);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- return 0;
-}
-
-int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip,
- struct dsp_pcm_channel_descriptor * pcm_channel)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- struct dsp_scb_descriptor * parent_scb;
- struct dsp_scb_descriptor * src_scb = pcm_channel->src_scb;
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
-
- if (pcm_channel->unlinked == 0) {
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return -EIO;
- }
-
- parent_scb = src_scb;
-
- if (src_scb->sub_list_ptr != ins->the_null_scb) {
- src_scb->sub_list_ptr->parent_scb_ptr = pcm_channel->pcm_reader_scb;
- pcm_channel->pcm_reader_scb->next_scb_ptr = src_scb->sub_list_ptr;
- }
-
- src_scb->sub_list_ptr = pcm_channel->pcm_reader_scb;
-
- snd_BUG_ON(pcm_channel->pcm_reader_scb->parent_scb_ptr);
- pcm_channel->pcm_reader_scb->parent_scb_ptr = parent_scb;
-
- /* update SCB entry in DSP RAM */
- cs46xx_dsp_spos_update_scb(chip,pcm_channel->pcm_reader_scb);
-
- /* update parent SCB entry */
- cs46xx_dsp_spos_update_scb(chip,parent_scb);
-
- pcm_channel->unlinked = 0;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
-}
-
-struct dsp_scb_descriptor *
-cs46xx_add_record_source (struct snd_cs46xx *chip, struct dsp_scb_descriptor * source,
- u16 addr, char * scb_name)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- struct dsp_scb_descriptor * parent;
- struct dsp_scb_descriptor * pcm_input;
- int insert_point;
-
- if (snd_BUG_ON(!ins->record_mixer_scb))
- return NULL;
-
- if (ins->record_mixer_scb->sub_list_ptr != ins->the_null_scb) {
- parent = find_next_free_scb (chip,ins->record_mixer_scb->sub_list_ptr);
- insert_point = SCB_ON_PARENT_NEXT_SCB;
- } else {
- parent = ins->record_mixer_scb;
- insert_point = SCB_ON_PARENT_SUBLIST_SCB;
- }
-
- pcm_input = cs46xx_dsp_create_pcm_serial_input_scb(chip,scb_name,addr,
- source, parent,
- insert_point);
-
- return pcm_input;
-}
-
-int cs46xx_src_unlink(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src)
-{
- unsigned long flags;
-
- if (snd_BUG_ON(!src->parent_scb_ptr))
- return -EINVAL;
-
- /* mute SCB */
- cs46xx_dsp_scb_set_volume (chip,src,0,0);
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- _dsp_unlink_scb (chip,src);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- return 0;
-}
-
-int cs46xx_src_link(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- struct dsp_scb_descriptor * parent_scb;
-
- if (snd_BUG_ON(src->parent_scb_ptr))
- return -EINVAL;
- if (snd_BUG_ON(!ins->master_mix_scb))
- return -EINVAL;
-
- if (ins->master_mix_scb->sub_list_ptr != ins->the_null_scb) {
- parent_scb = find_next_free_scb (chip,ins->master_mix_scb->sub_list_ptr);
- parent_scb->next_scb_ptr = src;
- } else {
- parent_scb = ins->master_mix_scb;
- parent_scb->sub_list_ptr = src;
- }
-
- src->parent_scb_ptr = parent_scb;
-
- /* update entry in DSP RAM */
- cs46xx_dsp_spos_update_scb(chip,parent_scb);
-
- return 0;
-}
-
-int cs46xx_dsp_enable_spdif_out (struct snd_cs46xx *chip)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- if ( ! (ins->spdif_status_out & DSP_SPDIF_STATUS_HW_ENABLED) ) {
- cs46xx_dsp_enable_spdif_hw (chip);
- }
-
- /* dont touch anything if SPDIF is open */
- if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) {
- /* when cs46xx_iec958_post_close(...) is called it
- will call this function if necessary depending on
- this bit */
- ins->spdif_status_out |= DSP_SPDIF_STATUS_OUTPUT_ENABLED;
-
- return -EBUSY;
- }
-
- if (snd_BUG_ON(ins->asynch_tx_scb))
- return -EINVAL;
- if (snd_BUG_ON(ins->master_mix_scb->next_scb_ptr !=
- ins->the_null_scb))
- return -EINVAL;
-
- /* reset output snooper sample buffer pointer */
- snd_cs46xx_poke (chip, (ins->ref_snoop_scb->address + 2) << 2,
- (OUTPUT_SNOOP_BUFFER + 0x10) << 0x10 );
-
- /* The asynch. transfer task */
- ins->asynch_tx_scb = cs46xx_dsp_create_asynch_fg_tx_scb(chip,"AsynchFGTxSCB",ASYNCTX_SCB_ADDR,
- SPDIFO_SCB_INST,
- SPDIFO_IP_OUTPUT_BUFFER1,
- ins->master_mix_scb,
- SCB_ON_PARENT_NEXT_SCB);
- if (!ins->asynch_tx_scb) return -ENOMEM;
-
- ins->spdif_pcm_input_scb = cs46xx_dsp_create_pcm_serial_input_scb(chip,"PCMSerialInput_II",
- PCMSERIALINII_SCB_ADDR,
- ins->ref_snoop_scb,
- ins->asynch_tx_scb,
- SCB_ON_PARENT_SUBLIST_SCB);
-
-
- if (!ins->spdif_pcm_input_scb) return -ENOMEM;
-
- /* monitor state */
- ins->spdif_status_out |= DSP_SPDIF_STATUS_OUTPUT_ENABLED;
-
- return 0;
-}
-
-int cs46xx_dsp_disable_spdif_out (struct snd_cs46xx *chip)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- /* dont touch anything if SPDIF is open */
- if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) {
- ins->spdif_status_out &= ~DSP_SPDIF_STATUS_OUTPUT_ENABLED;
- return -EBUSY;
- }
-
- /* check integrety */
- if (snd_BUG_ON(!ins->asynch_tx_scb))
- return -EINVAL;
- if (snd_BUG_ON(!ins->spdif_pcm_input_scb))
- return -EINVAL;
- if (snd_BUG_ON(ins->master_mix_scb->next_scb_ptr != ins->asynch_tx_scb))
- return -EINVAL;
- if (snd_BUG_ON(ins->asynch_tx_scb->parent_scb_ptr !=
- ins->master_mix_scb))
- return -EINVAL;
-
- cs46xx_dsp_remove_scb (chip,ins->spdif_pcm_input_scb);
- cs46xx_dsp_remove_scb (chip,ins->asynch_tx_scb);
-
- ins->spdif_pcm_input_scb = NULL;
- ins->asynch_tx_scb = NULL;
-
- /* clear buffer to prevent any undesired noise */
- _dsp_clear_sample_buffer(chip,SPDIFO_IP_OUTPUT_BUFFER1,256);
-
- /* monitor state */
- ins->spdif_status_out &= ~DSP_SPDIF_STATUS_OUTPUT_ENABLED;
-
-
- return 0;
-}
-
-int cs46xx_iec958_pre_open (struct snd_cs46xx *chip)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- if ( ins->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED ) {
- /* remove AsynchFGTxSCB and and PCMSerialInput_II */
- cs46xx_dsp_disable_spdif_out (chip);
-
- /* save state */
- ins->spdif_status_out |= DSP_SPDIF_STATUS_OUTPUT_ENABLED;
- }
-
- /* if not enabled already */
- if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_HW_ENABLED) ) {
- cs46xx_dsp_enable_spdif_hw (chip);
- }
-
- /* Create the asynch. transfer task for playback */
- ins->asynch_tx_scb = cs46xx_dsp_create_asynch_fg_tx_scb(chip,"AsynchFGTxSCB",ASYNCTX_SCB_ADDR,
- SPDIFO_SCB_INST,
- SPDIFO_IP_OUTPUT_BUFFER1,
- ins->master_mix_scb,
- SCB_ON_PARENT_NEXT_SCB);
-
-
- /* set spdif channel status value for streaming */
- cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, ins->spdif_csuv_stream);
-
- ins->spdif_status_out |= DSP_SPDIF_STATUS_PLAYBACK_OPEN;
-
- return 0;
-}
-
-int cs46xx_iec958_post_close (struct snd_cs46xx *chip)
-{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
-
- if (snd_BUG_ON(!ins->asynch_tx_scb))
- return -EINVAL;
-
- ins->spdif_status_out &= ~DSP_SPDIF_STATUS_PLAYBACK_OPEN;
-
- /* restore settings */
- cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, ins->spdif_csuv_default);
-
- /* deallocate stuff */
- if (ins->spdif_pcm_input_scb != NULL) {
- cs46xx_dsp_remove_scb (chip,ins->spdif_pcm_input_scb);
- ins->spdif_pcm_input_scb = NULL;
- }
-
- cs46xx_dsp_remove_scb (chip,ins->asynch_tx_scb);
- ins->asynch_tx_scb = NULL;
-
- /* clear buffer to prevent any undesired noise */
- _dsp_clear_sample_buffer(chip,SPDIFO_IP_OUTPUT_BUFFER1,256);
-
- /* restore state */
- if ( ins->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED ) {
- cs46xx_dsp_enable_spdif_out (chip);
- }
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwc4630.h b/ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwc4630.h
deleted file mode 100644
index 37c4f131..00000000
--- a/ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwc4630.h
+++ /dev/null
@@ -1,320 +0,0 @@
-/* generated from cwc4630.osp DO NOT MODIFY */
-
-#ifndef __HEADER_cwc4630_H__
-#define __HEADER_cwc4630_H__
-
-static struct dsp_symbol_entry cwc4630_symbols[] = {
- { 0x0000, "BEGINADDRESS",0x00 },
- { 0x8000, "EXECCHILD",0x03 },
- { 0x8001, "EXECCHILD_98",0x03 },
- { 0x8003, "EXECCHILD_PUSH1IND",0x03 },
- { 0x8008, "EXECSIBLING",0x03 },
- { 0x800a, "EXECSIBLING_298",0x03 },
- { 0x800b, "EXECSIBLING_2IND1",0x03 },
- { 0x8010, "TIMINGMASTER",0x03 },
- { 0x804f, "S16_CODECINPUTTASK",0x03 },
- { 0x805e, "PCMSERIALINPUTTASK",0x03 },
- { 0x806d, "S16_MIX_TO_OSTREAM",0x03 },
- { 0x809a, "S16_MIX",0x03 },
- { 0x80bb, "S16_UPSRC",0x03 },
- { 0x813b, "MIX3_EXP",0x03 },
- { 0x8164, "DECIMATEBYPOW2",0x03 },
- { 0x8197, "VARIDECIMATE",0x03 },
- { 0x81f2, "_3DINPUTTASK",0x03 },
- { 0x820a, "_3DPRLGCINPTASK",0x03 },
- { 0x8227, "_3DSTEREOINPUTTASK",0x03 },
- { 0x8242, "_3DOUTPUTTASK",0x03 },
- { 0x82c4, "HRTF_MORPH_TASK",0x03 },
- { 0x82c6, "WAIT4DATA",0x03 },
- { 0x82fa, "PROLOGIC",0x03 },
- { 0x8496, "DECORRELATOR",0x03 },
- { 0x84a4, "STEREO2MONO",0x03 },
- { 0x0070, "SPOSCB",0x02 },
- { 0x0107, "TASKTREETHREAD",0x03 },
- { 0x013c, "TASKTREEHEADERCODE",0x03 },
- { 0x0145, "FGTASKTREEHEADERCODE",0x03 },
- { 0x0169, "NULLALGORITHM",0x03 },
- { 0x016d, "HFGEXECCHILD",0x03 },
- { 0x016e, "HFGEXECCHILD_98",0x03 },
- { 0x0170, "HFGEXECCHILD_PUSH1IND",0x03 },
- { 0x0173, "HFGEXECSIBLING",0x03 },
- { 0x0175, "HFGEXECSIBLING_298",0x03 },
- { 0x0176, "HFGEXECSIBLING_2IND1",0x03 },
- { 0x0179, "S16_CODECOUTPUTTASK",0x03 },
- { 0x0194, "#CODE_END",0x00 },
-}; /* cwc4630 symbols */
-
-static u32 cwc4630_code[] = {
-/* BEGINADDRESS */
-/* 0000 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 0002 */ 0x00001705,0x00001400,0x000a411e,0x00001003,
-/* 0004 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 0006 */ 0x00009705,0x00001400,0x000a411e,0x00001003,
-/* 0008 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 000A */ 0x00011705,0x00001400,0x000a411e,0x00001003,
-/* 000C */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 000E */ 0x00019705,0x00001400,0x000a411e,0x00001003,
-/* 0010 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 0012 */ 0x00021705,0x00001400,0x000a411e,0x00001003,
-/* 0014 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 0016 */ 0x00029705,0x00001400,0x000a411e,0x00001003,
-/* 0018 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 001A */ 0x00031705,0x00001400,0x000a411e,0x00001003,
-/* 001C */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 001E */ 0x00039705,0x00001400,0x000a411e,0x00001003,
-/* 0020 */ 0x000fe19e,0x00001003,0x0009c730,0x00001003,
-/* 0022 */ 0x0008e19c,0x00001003,0x000083c1,0x00093040,
-/* 0024 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 0026 */ 0x00009705,0x00001400,0x000a211e,0x00001003,
-/* 0028 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 002A */ 0x00011705,0x00001400,0x000a211e,0x00001003,
-/* 002C */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 002E */ 0x00019705,0x00001400,0x000a211e,0x00001003,
-/* 0030 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 0032 */ 0x00021705,0x00001400,0x000a211e,0x00001003,
-/* 0034 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 0036 */ 0x00029705,0x00001400,0x000a211e,0x00001003,
-/* 0038 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 003A */ 0x00031705,0x00001400,0x000a211e,0x00001003,
-/* 003C */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 003E */ 0x00039705,0x00001400,0x000a211e,0x00001003,
-/* 0040 */ 0x0001a730,0x00001008,0x000e2730,0x00001002,
-/* 0042 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
-/* 0044 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
-/* 0046 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
-/* 0048 */ 0x00000000,0x00000000,0x000f619c,0x00001003,
-/* 004A */ 0x0007f801,0x000c0000,0x00000037,0x00001000,
-/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 004E */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0050 */ 0x00000000,0x000c0000,0x00000000,0x00000000,
-/* 0052 */ 0x0000373c,0x00001000,0x00000000,0x00000000,
-/* 0054 */ 0x000ee19c,0x00001003,0x0007f801,0x000c0000,
-/* 0056 */ 0x00000037,0x00001000,0x00000000,0x00000000,
-/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 005A */ 0x00000000,0x00000000,0x0000273c,0x00001000,
-/* 005C */ 0x00000033,0x00001000,0x000e679e,0x00001003,
-/* 005E */ 0x00007705,0x00001400,0x000ac71e,0x00001003,
-/* 0060 */ 0x00087fc1,0x000c3be0,0x0007f801,0x000c0000,
-/* 0062 */ 0x00000037,0x00001000,0x00000000,0x00000000,
-/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0066 */ 0x00000000,0x00000000,0x0000a730,0x00001003,
-/* 0068 */ 0x00000033,0x00001000,0x0007f801,0x000c0000,
-/* 006A */ 0x00000037,0x00001000,0x00000000,0x00000000,
-/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 006E */ 0x00000000,0x00000000,0x00000000,0x000c0000,
-/* 0070 */ 0x00000032,0x00001000,0x0000273d,0x00001000,
-/* 0072 */ 0x0004a730,0x00001003,0x00000f41,0x00097140,
-/* 0074 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
-/* 0076 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
-/* 0078 */ 0x00000000,0x00000000,0x0001bf05,0x0003fc40,
-/* 007A */ 0x00002725,0x000aa400,0x00013705,0x00093a00,
-/* 007C */ 0x0000002e,0x0009d6c0,0x0002ef8a,0x00000000,
-/* 007E */ 0x00040630,0x00001004,0x0004ef0a,0x000eb785,
-/* 0080 */ 0x0003fc8a,0x00000000,0x00000000,0x000c70e0,
-/* 0082 */ 0x0007d182,0x0002c640,0x00008630,0x00001004,
-/* 0084 */ 0x000799b8,0x0002c6c0,0x00031705,0x00092240,
-/* 0086 */ 0x00039f05,0x000932c0,0x0003520a,0x00000000,
-/* 0088 */ 0x00070731,0x0000100b,0x00010705,0x000b20c0,
-/* 008A */ 0x00000000,0x000eba44,0x00032108,0x000c60c4,
-/* 008C */ 0x00065208,0x000c2917,0x000486b0,0x00001007,
-/* 008E */ 0x00012f05,0x00036880,0x0002818e,0x000c0000,
-/* 0090 */ 0x0004410a,0x00000000,0x00048630,0x00001007,
-/* 0092 */ 0x00029705,0x000c0000,0x00000000,0x00000000,
-/* 0094 */ 0x00003fc1,0x0003fc40,0x000037c1,0x00091b40,
-/* 0096 */ 0x00003fc1,0x000911c0,0x000037c1,0x000957c0,
-/* 0098 */ 0x00003fc1,0x000951c0,0x000037c1,0x00000000,
-/* 009A */ 0x00003fc1,0x000991c0,0x000037c1,0x00000000,
-/* 009C */ 0x00003fc1,0x0009d1c0,0x000037c1,0x00000000,
-/* 009E */ 0x0001ccc1,0x000915c0,0x0001c441,0x0009d800,
-/* 00A0 */ 0x0009cdc1,0x00091240,0x0001c541,0x00091d00,
-/* 00A2 */ 0x0009cfc1,0x00095240,0x0001c741,0x00095c80,
-/* 00A4 */ 0x000e8ca9,0x00099240,0x000e85ad,0x00095640,
-/* 00A6 */ 0x00069ca9,0x00099d80,0x000e952d,0x00099640,
-/* 00A8 */ 0x000eaca9,0x0009d6c0,0x000ea5ad,0x00091a40,
-/* 00AA */ 0x0006bca9,0x0009de80,0x000eb52d,0x00095a40,
-/* 00AC */ 0x000ecca9,0x00099ac0,0x000ec5ad,0x0009da40,
-/* 00AE */ 0x000edca9,0x0009d300,0x000a6e0a,0x00001000,
-/* 00B0 */ 0x000ed52d,0x00091e40,0x000eeca9,0x00095ec0,
-/* 00B2 */ 0x000ee5ad,0x00099e40,0x0006fca9,0x00002500,
-/* 00B4 */ 0x000fb208,0x000c59a0,0x000ef52d,0x0009de40,
-/* 00B6 */ 0x00068ca9,0x000912c1,0x000683ad,0x00095241,
-/* 00B8 */ 0x00020f05,0x000991c1,0x00000000,0x00000000,
-/* 00BA */ 0x00086f88,0x00001000,0x0009cf81,0x000b5340,
-/* 00BC */ 0x0009c701,0x000b92c0,0x0009de81,0x000bd300,
-/* 00BE */ 0x0009d601,0x000b1700,0x0001fd81,0x000b9d80,
-/* 00C0 */ 0x0009f501,0x000b57c0,0x000a0f81,0x000bd740,
-/* 00C2 */ 0x00020701,0x000b5c80,0x000a1681,0x000b97c0,
-/* 00C4 */ 0x00021601,0x00002500,0x000a0701,0x000b9b40,
-/* 00C6 */ 0x000a0f81,0x000b1bc0,0x00021681,0x00002d00,
-/* 00C8 */ 0x00020f81,0x000bd800,0x000a0701,0x000b5bc0,
-/* 00CA */ 0x00021601,0x00003500,0x000a0f81,0x000b5f40,
-/* 00CC */ 0x000a0701,0x000bdbc0,0x00021681,0x00003d00,
-/* 00CE */ 0x00020f81,0x000b1d00,0x000a0701,0x000b1fc0,
-/* 00D0 */ 0x00021601,0x00020500,0x00020f81,0x000b1341,
-/* 00D2 */ 0x000a0701,0x000b9fc0,0x00021681,0x00020d00,
-/* 00D4 */ 0x00020f81,0x000bde80,0x000a0701,0x000bdfc0,
-/* 00D6 */ 0x00021601,0x00021500,0x00020f81,0x000b9341,
-/* 00D8 */ 0x00020701,0x000b53c1,0x00021681,0x00021d00,
-/* 00DA */ 0x000a0f81,0x000d0380,0x0000b601,0x000b15c0,
-/* 00DC */ 0x00007b01,0x00000000,0x00007b81,0x000bd1c0,
-/* 00DE */ 0x00007b01,0x00000000,0x00007b81,0x000b91c0,
-/* 00E0 */ 0x00007b01,0x000b57c0,0x00007b81,0x000b51c0,
-/* 00E2 */ 0x00007b01,0x000b1b40,0x00007b81,0x000b11c0,
-/* 00E4 */ 0x00087b01,0x000c3dc0,0x0007e488,0x000d7e45,
-/* 00E6 */ 0x00000000,0x000d7a44,0x0007e48a,0x00000000,
-/* 00E8 */ 0x00011f05,0x00084080,0x00000000,0x00000000,
-/* 00EA */ 0x00001705,0x000b3540,0x00008a01,0x000bf040,
-/* 00EC */ 0x00007081,0x000bb5c0,0x00055488,0x00000000,
-/* 00EE */ 0x0000d482,0x0003fc40,0x0003fc88,0x00000000,
-/* 00F0 */ 0x0001e401,0x000b3a00,0x0001ec81,0x000bd6c0,
-/* 00F2 */ 0x0002ef88,0x000e7784,0x00056f08,0x00000000,
-/* 00F4 */ 0x000d86b0,0x00001007,0x00008281,0x000bb240,
-/* 00F6 */ 0x0000b801,0x000b7140,0x00007888,0x00000000,
-/* 00F8 */ 0x0000073c,0x00001000,0x0007f188,0x000c0000,
-/* 00FA */ 0x00000000,0x00000000,0x00055288,0x000c555c,
-/* 00FC */ 0x0005528a,0x000c0000,0x0009fa88,0x000c5d00,
-/* 00FE */ 0x0000fa88,0x00000000,0x00000032,0x00001000,
-/* 0100 */ 0x0000073d,0x00001000,0x0007f188,0x000c0000,
-/* 0102 */ 0x00000000,0x00000000,0x0008c01c,0x00001003,
-/* 0104 */ 0x00002705,0x00001008,0x0008b201,0x000c1392,
-/* 0106 */ 0x0000ba01,0x00000000,
-/* TASKTREETHREAD */
-/* 0107 */ 0x00008731,0x00001400,0x0004c108,0x000fe0c4,
-/* 0109 */ 0x00057488,0x00000000,0x000a6388,0x00001001,
-/* 010B */ 0x0008b334,0x000bc141,0x0003020e,0x00000000,
-/* 010D */ 0x000986b0,0x00001008,0x00003625,0x000c5dfa,
-/* 010F */ 0x000a638a,0x00001001,0x0008020e,0x00001002,
-/* 0111 */ 0x0009a6b0,0x00001008,0x0007f301,0x00000000,
-/* 0113 */ 0x00000000,0x00000000,0x00002725,0x000a8c40,
-/* 0115 */ 0x000000ae,0x00000000,0x000e8630,0x00001008,
-/* 0117 */ 0x00000000,0x000c74e0,0x0007d182,0x0002d640,
-/* 0119 */ 0x000b8630,0x00001008,0x000799b8,0x0002d6c0,
-/* 011B */ 0x0000748a,0x000c3ec5,0x0007420a,0x000c0000,
-/* 011D */ 0x00062208,0x000c4117,0x000a0630,0x00001009,
-/* 011F */ 0x00000000,0x000c0000,0x0001022e,0x00000000,
-/* 0121 */ 0x0006a630,0x00001009,0x00000032,0x00001000,
-/* 0123 */ 0x000ca21c,0x00001003,0x00005a02,0x00000000,
-/* 0125 */ 0x0001a630,0x00001009,0x00000000,0x000c0000,
-/* 0127 */ 0x00000036,0x00001000,0x00000000,0x00000000,
-/* 0129 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 012B */ 0x00000000,0x00000000,0x0003a730,0x00001008,
-/* 012D */ 0x0007f801,0x000c0000,0x00000037,0x00001000,
-/* 012F */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0131 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0133 */ 0x0003a730,0x00001008,0x00000033,0x00001000,
-/* 0135 */ 0x0003a705,0x00001008,0x00007a01,0x000c0000,
-/* 0137 */ 0x000e6288,0x000d550a,0x0006428a,0x00000000,
-/* 0139 */ 0x00090730,0x0000100a,0x00000000,0x000c0000,
-/* 013B */ 0x00000000,0x00000000,
-/* TASKTREEHEADERCODE */
-/* 013C */ 0x0007aab0,0x00034880,0x000a8fb0,0x0000100b,
-/* 013E */ 0x00057488,0x00000000,0x00033b94,0x00081140,
-/* 0140 */ 0x000183ae,0x00000000,0x000a86b0,0x0000100b,
-/* 0142 */ 0x00022f05,0x000c3545,0x0000eb8a,0x00000000,
-/* 0144 */ 0x00042731,0x00001003,
-/* FGTASKTREEHEADERCODE */
-/* 0145 */ 0x0007aab0,0x00034880,0x00078fb0,0x0000100a,
-/* 0147 */ 0x00057488,0x00000000,0x00033b94,0x00081140,
-/* 0149 */ 0x000183ae,0x00000000,0x000b06b0,0x0000100b,
-/* 014B */ 0x00022f05,0x00000000,0x00007401,0x00091140,
-/* 014D */ 0x00048f05,0x000951c0,0x00042731,0x00001003,
-/* 014F */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47,
-/* 0151 */ 0x00080000,0x000bffc7,0x000fe19e,0x00001003,
-/* 0153 */ 0x00000000,0x00000000,0x0008e19c,0x00001003,
-/* 0155 */ 0x000083c1,0x00093040,0x00000f41,0x00097140,
-/* 0157 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
-/* 0159 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
-/* 015B */ 0x00000000,0x000fdc44,0x00055208,0x00000000,
-/* 015D */ 0x00010705,0x000a2880,0x0000a23a,0x00093a00,
-/* 015F */ 0x0003fc8a,0x000df6c5,0x0004ef0a,0x000c0000,
-/* 0161 */ 0x00012f05,0x00036880,0x00065308,0x000c2997,
-/* 0163 */ 0x000086b0,0x0000100b,0x0004410a,0x000d40c7,
-/* 0165 */ 0x00000000,0x00000000,0x00088730,0x00001004,
-/* 0167 */ 0x00056f0a,0x000ea105,0x00000000,0x00000000,
-/* NULLALGORITHM */
-/* 0169 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47,
-/* 016B */ 0x00080000,0x000bffc7,0x0000273d,0x00001000,
-/* HFGEXECCHILD */
-/* 016D */ 0x00000000,0x000eba44,
-/* HFGEXECCHILD_98 */
-/* 016E */ 0x00048f05,0x0000f440,0x00007401,0x0000f7c0,
-/* HFGEXECCHILD_PUSH1IND */
-/* 0170 */ 0x00000734,0x00001000,0x00010705,0x000a6880,
-/* 0172 */ 0x00006a88,0x000c75c4,
-/* HFGEXECSIBLING */
-/* 0173 */ 0x00000000,0x000e5084,0x00000000,0x000eba44,
-/* HFGEXECSIBLING_298 */
-/* 0175 */ 0x00087401,0x000e4782,
-/* HFGEXECSIBLING_2IND1 */
-/* 0176 */ 0x00000734,0x00001000,0x00010705,0x000a6880,
-/* 0178 */ 0x00006a88,0x000c75c4,
-/* S16_CODECOUTPUTTASK */
-/* 0179 */ 0x0007c108,0x000c0000,0x0007e721,0x000bed40,
-/* 017B */ 0x00005f25,0x000badc0,0x0003ba97,0x000beb80,
-/* 017D */ 0x00065590,0x000b2e00,0x00033217,0x00003ec0,
-/* 017F */ 0x00065590,0x000b8e40,0x0003ed80,0x000491c0,
-/* 0181 */ 0x00073fb0,0x00074c80,0x000583a0,0x0000100c,
-/* 0183 */ 0x000ee388,0x00042970,0x00008301,0x00021ef2,
-/* 0185 */ 0x000b8f14,0x0000000f,0x000c4d8d,0x0000001b,
-/* 0187 */ 0x000d6dc2,0x000e06c6,0x000032ac,0x000c3916,
-/* 0189 */ 0x0004edc2,0x00074c80,0x00078898,0x00001000,
-/* 018B */ 0x00038894,0x00000032,0x000c4d8d,0x00092e1b,
-/* 018D */ 0x000d6dc2,0x000e06c6,0x0004edc2,0x000c1956,
-/* 018F */ 0x0000722c,0x00034a00,0x00041705,0x0009ed40,
-/* 0191 */ 0x00058730,0x00001400,0x000d7488,0x000c3a00,
-/* 0193 */ 0x00048f05,0x00000000
-};
-/* #CODE_END */
-
-static u32 cwc4630_parameter[] = {
-/* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0008 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0018 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 001C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0028 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 002C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0030 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0038 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 003C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0040 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0048 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0070 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0074 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0078 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 007C */ 0x00000000,0x00000000,0x00000000,0x00000000
-}; /* #PARAMETER_END */
-
-
-static struct dsp_segment_desc cwc4630_segments[] = {
- { SEGTYPE_SP_PROGRAM, 0x00000000, 0x00000328, cwc4630_code },
- { SEGTYPE_SP_PARAMETER, 0x00000000, 0x00000080, cwc4630_parameter },
-};
-
-static struct dsp_module_desc cwc4630_module = {
- "cwc4630",
- {
- 38,
- cwc4630_symbols
- },
- 2,
- cwc4630_segments,
-};
-
-#endif /* __HEADER_cwc4630_H__ */
diff --git a/ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwcasync.h b/ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwcasync.h
deleted file mode 100644
index 70e63e13..00000000
--- a/ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwcasync.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/* generated from cwcasync.osp DO NOT MODIFY */
-
-#ifndef __HEADER_cwcasync_H__
-#define __HEADER_cwcasync_H__
-
-static struct dsp_symbol_entry cwcasync_symbols[] = {
- { 0x8000, "EXECCHILD",0x03 },
- { 0x8001, "EXECCHILD_98",0x03 },
- { 0x8003, "EXECCHILD_PUSH1IND",0x03 },
- { 0x8008, "EXECSIBLING",0x03 },
- { 0x800a, "EXECSIBLING_298",0x03 },
- { 0x800b, "EXECSIBLING_2IND1",0x03 },
- { 0x8010, "TIMINGMASTER",0x03 },
- { 0x804f, "S16_CODECINPUTTASK",0x03 },
- { 0x805e, "PCMSERIALINPUTTASK",0x03 },
- { 0x806d, "S16_MIX_TO_OSTREAM",0x03 },
- { 0x809a, "S16_MIX",0x03 },
- { 0x80bb, "S16_UPSRC",0x03 },
- { 0x813b, "MIX3_EXP",0x03 },
- { 0x8164, "DECIMATEBYPOW2",0x03 },
- { 0x8197, "VARIDECIMATE",0x03 },
- { 0x81f2, "_3DINPUTTASK",0x03 },
- { 0x820a, "_3DPRLGCINPTASK",0x03 },
- { 0x8227, "_3DSTEREOINPUTTASK",0x03 },
- { 0x8242, "_3DOUTPUTTASK",0x03 },
- { 0x82c4, "HRTF_MORPH_TASK",0x03 },
- { 0x82c6, "WAIT4DATA",0x03 },
- { 0x82fa, "PROLOGIC",0x03 },
- { 0x8496, "DECORRELATOR",0x03 },
- { 0x84a4, "STEREO2MONO",0x03 },
- { 0x0000, "OVERLAYBEGINADDRESS",0x00 },
- { 0x0000, "SPIOWRITE",0x03 },
- { 0x000d, "S16_ASYNCCODECINPUTTASK",0x03 },
- { 0x0043, "SPDIFITASK",0x03 },
- { 0x007b, "SPDIFOTASK",0x03 },
- { 0x0097, "ASYNCHFGTXCODE",0x03 },
- { 0x00be, "ASYNCHFGRXCODE",0x03 },
- { 0x00db, "#CODE_END",0x00 },
-}; /* cwcasync symbols */
-
-static u32 cwcasync_code[] = {
-/* OVERLAYBEGINADDRESS */
-/* 0000 */ 0x00002731,0x00001400,0x00003725,0x000a8440,
-/* 0002 */ 0x000000ae,0x00000000,0x00060630,0x00001000,
-/* 0004 */ 0x00000000,0x000c7560,0x00075282,0x0002d640,
-/* 0006 */ 0x00021705,0x00000000,0x00072ab8,0x0002d6c0,
-/* 0008 */ 0x00020630,0x00001000,0x000c74c2,0x000d4b82,
-/* 000A */ 0x000475c2,0x00000000,0x0003430a,0x000c0000,
-/* 000C */ 0x00042730,0x00001400,
-/* S16_ASYNCCODECINPUTTASK */
-/* 000D */ 0x0006a108,0x000cf2c4,0x0004f4c0,0x00000000,
-/* 000F */ 0x000fa418,0x0000101f,0x0005d402,0x0001c500,
-/* 0011 */ 0x000f0630,0x00001000,0x00004418,0x00001380,
-/* 0013 */ 0x000e243d,0x000d394a,0x00049705,0x00000000,
-/* 0015 */ 0x0007d530,0x000b4240,0x000e00f2,0x00001000,
-/* 0017 */ 0x00009134,0x000ca20a,0x00004c90,0x00001000,
-/* 0019 */ 0x0005d705,0x00000000,0x00004f25,0x00098240,
-/* 001B */ 0x00004725,0x00000000,0x0000e48a,0x00000000,
-/* 001D */ 0x00027295,0x0009c2c0,0x0003df25,0x00000000,
-/* 001F */ 0x000e8030,0x00001001,0x0005f718,0x000ac600,
-/* 0021 */ 0x0007cf30,0x000c2a01,0x00082630,0x00001001,
-/* 0023 */ 0x000504a0,0x00001001,0x00029314,0x000bcb80,
-/* 0025 */ 0x0003cf25,0x000b0e00,0x0004f5c0,0x00000000,
-/* 0027 */ 0x00049118,0x000d888a,0x0007dd02,0x000c6efa,
-/* 0029 */ 0x00000000,0x00000000,0x0004f5c0,0x00069c80,
-/* 002B */ 0x0000d402,0x00000000,0x000e8630,0x00001001,
-/* 002D */ 0x00079130,0x00000000,0x00049118,0x00090e00,
-/* 002F */ 0x0006c10a,0x00000000,0x00000000,0x000c0000,
-/* 0031 */ 0x0007cf30,0x00030580,0x00005725,0x00000000,
-/* 0033 */ 0x000d84a0,0x00001001,0x00029314,0x000b4780,
-/* 0035 */ 0x0003cf25,0x000b8600,0x00000000,0x00000000,
-/* 0037 */ 0x00000000,0x000c0000,0x00000000,0x00042c80,
-/* 0039 */ 0x0001dec1,0x000e488c,0x00031114,0x00000000,
-/* 003B */ 0x0004f5c2,0x00000000,0x0003640a,0x00000000,
-/* 003D */ 0x00000000,0x000e5084,0x00000000,0x000eb844,
-/* 003F */ 0x00007001,0x00000000,0x00000734,0x00001000,
-/* 0041 */ 0x00010705,0x000a6880,0x00006a88,0x000c75c4,
-/* SPDIFITASK */
-/* 0043 */ 0x0006a108,0x000cf2c4,0x0004f4c0,0x000d5384,
-/* 0045 */ 0x0007e48a,0x00000000,0x00067718,0x00001000,
-/* 0047 */ 0x0007a418,0x00001000,0x0007221a,0x00000000,
-/* 0049 */ 0x0005d402,0x00014500,0x000b8630,0x00001002,
-/* 004B */ 0x00004418,0x00001780,0x000e243d,0x000d394a,
-/* 004D */ 0x00049705,0x00000000,0x0007d530,0x000b4240,
-/* 004F */ 0x000ac0f2,0x00001002,0x00014414,0x00000000,
-/* 0051 */ 0x00004c90,0x00001000,0x0005d705,0x00000000,
-/* 0053 */ 0x00004f25,0x00098240,0x00004725,0x00000000,
-/* 0055 */ 0x0000e48a,0x00000000,0x00027295,0x0009c2c0,
-/* 0057 */ 0x0007df25,0x00000000,0x000ac030,0x00001003,
-/* 0059 */ 0x0005f718,0x000fe798,0x00029314,0x000bcb80,
-/* 005B */ 0x00000930,0x000b0e00,0x0004f5c0,0x000de204,
-/* 005D */ 0x000884a0,0x00001003,0x0007cf25,0x000e3560,
-/* 005F */ 0x00049118,0x00000000,0x00049118,0x000d888a,
-/* 0061 */ 0x0007dd02,0x000c6efa,0x0000c434,0x00030040,
-/* 0063 */ 0x000fda82,0x000c2312,0x000fdc0e,0x00001001,
-/* 0065 */ 0x00083402,0x000c2b92,0x000706b0,0x00001003,
-/* 0067 */ 0x00075a82,0x00000000,0x0000d625,0x000b0940,
-/* 0069 */ 0x0000840e,0x00001002,0x0000aabc,0x000c511e,
-/* 006B */ 0x00078730,0x00001003,0x0000aaf4,0x000e910a,
-/* 006D */ 0x0004628a,0x00000000,0x00006aca,0x00000000,
-/* 006F */ 0x00000930,0x00000000,0x0004f5c0,0x00069c80,
-/* 0071 */ 0x00046ac0,0x00000000,0x0003c40a,0x000fc898,
-/* 0073 */ 0x00049118,0x00090e00,0x0006c10a,0x00000000,
-/* 0075 */ 0x00000000,0x000e5084,0x00000000,0x000eb844,
-/* 0077 */ 0x00007001,0x00000000,0x00000734,0x00001000,
-/* 0079 */ 0x00010705,0x000a6880,0x00006a88,0x000c75c4,
-/* SPDIFOTASK */
-/* 007B */ 0x0006a108,0x000c0000,0x0004f4c0,0x000c3245,
-/* 007D */ 0x0000a418,0x00001000,0x0003a20a,0x00000000,
-/* 007F */ 0x00004418,0x00001380,0x000e243d,0x000d394a,
-/* 0081 */ 0x000c9705,0x000def92,0x0008c030,0x00001004,
-/* 0083 */ 0x0005f718,0x000fe798,0x00000000,0x000c0000,
-/* 0085 */ 0x00005725,0x00000000,0x000704a0,0x00001004,
-/* 0087 */ 0x00029314,0x000b4780,0x0003cf25,0x000b8600,
-/* 0089 */ 0x00000000,0x00000000,0x00000000,0x000c0000,
-/* 008B */ 0x00000000,0x00042c80,0x0001dec1,0x000e488c,
-/* 008D */ 0x00031114,0x00000000,0x0004f5c2,0x00000000,
-/* 008F */ 0x0004a918,0x00098600,0x0006c28a,0x00000000,
-/* 0091 */ 0x00000000,0x000e5084,0x00000000,0x000eb844,
-/* 0093 */ 0x00007001,0x00000000,0x00000734,0x00001000,
-/* 0095 */ 0x00010705,0x000a6880,0x00006a88,0x000c75c4,
-/* ASYNCHFGTXCODE */
-/* 0097 */ 0x0002a880,0x000b4e40,0x00042214,0x000e5548,
-/* 0099 */ 0x000542bf,0x00000000,0x00000000,0x000481c0,
-/* 009B */ 0x00000000,0x00000000,0x00000000,0x00000030,
-/* 009D */ 0x0000072d,0x000fbf8a,0x00077f94,0x000ea7df,
-/* 009F */ 0x0002ac95,0x000d3145,0x00002731,0x00001400,
-/* 00A1 */ 0x00006288,0x000c71c4,0x00014108,0x000e6044,
-/* 00A3 */ 0x00035408,0x00000000,0x00025418,0x000a0ec0,
-/* 00A5 */ 0x0001443d,0x000ca21e,0x00046595,0x000d730c,
-/* 00A7 */ 0x0006538e,0x00000000,0x00064630,0x00001005,
-/* 00A9 */ 0x000e7b0e,0x000df782,0x000746b0,0x00001005,
-/* 00AB */ 0x00036f05,0x000c0000,0x00043695,0x000d598c,
-/* 00AD */ 0x0005331a,0x000f2185,0x00000000,0x00000000,
-/* 00AF */ 0x000007ae,0x000bdb00,0x00040630,0x00001400,
-/* 00B1 */ 0x0005e708,0x000c0000,0x0007ef30,0x000b1c00,
-/* 00B3 */ 0x000d86a0,0x00001005,0x00066408,0x000c0000,
-/* 00B5 */ 0x00000000,0x00000000,0x00021843,0x00000000,
-/* 00B7 */ 0x00000cac,0x00062c00,0x00001dac,0x00063400,
-/* 00B9 */ 0x00002cac,0x0006cc80,0x000db943,0x000e5ca1,
-/* 00BB */ 0x00000000,0x00000000,0x0006680a,0x000f3205,
-/* 00BD */ 0x00042730,0x00001400,
-/* ASYNCHFGRXCODE */
-/* 00BE */ 0x00014108,0x000f2204,0x00025418,0x000a2ec0,
-/* 00C0 */ 0x00015dbd,0x00038100,0x00015dbc,0x00000000,
-/* 00C2 */ 0x0005e415,0x00034880,0x0001258a,0x000d730c,
-/* 00C4 */ 0x0006538e,0x000baa40,0x00060630,0x00001006,
-/* 00C6 */ 0x00067b0e,0x000ac380,0x0003ef05,0x00000000,
-/* 00C8 */ 0x0000f734,0x0001c300,0x000586b0,0x00001400,
-/* 00CA */ 0x000b6f05,0x000c3a00,0x00048f05,0x00000000,
-/* 00CC */ 0x0005b695,0x0008c380,0x0002058e,0x00000000,
-/* 00CE */ 0x000500b0,0x00001400,0x0002b318,0x000e998d,
-/* 00D0 */ 0x0006430a,0x00000000,0x00000000,0x000ef384,
-/* 00D2 */ 0x00004725,0x000c0000,0x00000000,0x000f3204,
-/* 00D4 */ 0x00004f25,0x000c0000,0x00080000,0x000e5ca1,
-/* 00D6 */ 0x000cb943,0x000e5ca1,0x0004b943,0x00000000,
-/* 00D8 */ 0x00040730,0x00001400,0x000cb943,0x000e5ca1,
-/* 00DA */ 0x0004b943,0x00000000
-};
-/* #CODE_END */
-
-static struct dsp_segment_desc cwcasync_segments[] = {
- { SEGTYPE_SP_PROGRAM, 0x00000000, 0x000001b6, cwcasync_code },
-};
-
-static struct dsp_module_desc cwcasync_module = {
- "cwcasync",
- {
- 32,
- cwcasync_symbols
- },
- 1,
- cwcasync_segments,
-};
-
-#endif /* __HEADER_cwcasync_H__ */
diff --git a/ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwcbinhack.h b/ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwcbinhack.h
deleted file mode 100644
index f4d93689..00000000
--- a/ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwcbinhack.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* generated by Benny
- MODIFY ON YOUR OWN RISK */
-
-#ifndef __HEADER_cwcbinhack_H__
-#define __HEADER_cwcbinhack_H__
-
-static struct dsp_symbol_entry cwcbinhack_symbols[] = {
- { 0x02c8, "OVERLAYBEGINADDRESS",0x00 },
- { 0x02c8, "MAGICSNOOPTASK",0x03 },
- { 0x0308, "#CODE_END",0x00 },
-}; /* cwcbinhack symbols */
-
-static u32 cwcbinhack_code[] = {
- /* 0x02c8 */
- 0x0007bfb0,0x000bc240,0x00000c2e,0x000c6084, /* 1 */
- 0x000b8630,0x00001016,0x00006408,0x000efb84, /* 2 */
- 0x00016008,0x00000000,0x0001c088,0x000c0000, /* 3 */
- 0x000fc908,0x000e3392,0x0005f488,0x000efb84, /* 4 */
- 0x0001d402,0x000b2e00,0x0003d418,0x00001000, /* 5 */
- 0x0008d574,0x000c4293,0x00065625,0x000ea30e, /* 6 */
- 0x00096c01,0x000c6f92,0x0001a58a,0x000c6085, /* 7 */
- 0x00002f43,0x00000000,0x000e03a0,0x00001016, /* 8 */
- 0x0005e608,0x000c0000,0x00000000,0x00000000, /* 9 */
- 0x000ca108,0x000dcca1,0x00003bac,0x000c3205, /* 10 */
- 0x00073843,0x00000000,0x00010730,0x00001017, /* 11 */
- 0x0001600a,0x000c0000,0x00057488,0x00000000, /* 12 */
- 0x00000000,0x000e5084,0x00000000,0x000eba44, /* 13 */
- 0x00087401,0x000e4782,0x00000734,0x00001000, /* 14 */
- 0x00010705,0x000a6880,0x00006a88,0x000c75c4, /* 15 */
- 0x00000000,0x00000000,0x00000000,0x00000000, /* 16 */
-};
-/* #CODE_END */
-
-static struct dsp_segment_desc cwcbinhack_segments[] = {
- { SEGTYPE_SP_PROGRAM, 0x00000000, 64, cwcbinhack_code },
-};
-
-static struct dsp_module_desc cwcbinhack_module = {
- "cwcbinhack",
- {
- 3,
- cwcbinhack_symbols
- },
- 1,
- cwcbinhack_segments,
-};
-
-#endif /* __HEADER_cwcbinhack_H__ */
diff --git a/ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwcdma.asp b/ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwcdma.asp
deleted file mode 100644
index a65e1193..00000000
--- a/ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwcdma.asp
+++ /dev/null
@@ -1,170 +0,0 @@
-//
-// Copyright(c) by Benny Sjostrand (benny@hostmobility.com)
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-
-
-//
-// This code runs inside the DSP (cs4610, cs4612, cs4624, or cs4630),
-// to compile it you need a tool named SPASM 3.0 and DSP code owned by
-// Cirrus Logic(R). The SPASM program will generate a object file (cwcdma.osp),
-// the "ospparser" tool will genereate the cwcdma.h file it's included from
-// the cs46xx_lib.c file.
-//
-//
-// The purpose of this code is very simple: make it possible to tranfser
-// the samples 'as they are' with no alteration from a PCMreader
-// SCB (DMA from host) to any other SCB. This is useful for AC3 through SPDIF.
-// SRC (source rate converters) task always alters the samples in somehow,
-// however it's from 48khz -> 48khz.
-// The alterations are not audible, but AC3 wont work.
-//
-// ...
-// |
-// +---------------+
-// | AsynchFGTxSCB |
-// +---------------+
-// |
-// subListPtr
-// |
-// +--------------+
-// | DMAReader |
-// +--------------+
-// |
-// subListPtr
-// |
-// +-------------+
-// | PCMReader |
-// +-------------+
-// (DMA from host)
-//
-
-struct dmaSCB
- {
- long dma_reserved1[3];
-
- short dma_reserved2:dma_outBufPtr;
-
- short dma_unused1:dma_unused2;
-
- long dma_reserved3[4];
-
- short dma_subListPtr:dma_nextSCB;
- short dma_SPBptr:dma_entryPoint;
-
- long dma_strmRsConfig;
- long dma_strmBufPtr;
-
- long dma_reserved4;
-
- VolumeControl s2m_volume;
- };
-
-#export DMAReader
-void DMAReader()
-{
- execChild();
- r2 = r0->dma_subListPtr;
- r1 = r0->nextSCB;
-
- rsConfig01 = r2->strmRsConfig;
- // Load rsConfig for input buffer
-
- rsDMA01 = r2->basicReq.daw, , tb = Z(0 - rf);
- // Load rsDMA in case input buffer is a DMA buffer Test to see if there is any data to transfer
-
- if (tb) goto execSibling_2ind1 after {
- r5 = rf + (-1);
- r6 = r1->dma_entryPoint; // r6 = entry point of sibling task
- r1 = r1->dma_SPBptr, // r1 = pointer to sibling task's SPB
- , ind = r6; // Load entry point of sibling task
- }
-
- rsConfig23 = r0->dma_strmRsConfig;
- // Load rsConfig for output buffer (never a DMA buffer)
-
- r4 = r0->dma_outBufPtr;
-
- rsa0 = r2->strmBufPtr;
- // rsa0 = input buffer pointer
-
- for (i = r5; i >= 0; --i)
- after {
- rsa2 = r4;
- // rsa2 = output buffer pointer
-
- nop;
- nop;
- }
- //*****************************
- // TODO: cycles to this point *
- //*****************************
- {
- acc0 = (rsd0 = *rsa0++1);
- // get sample
-
- nop; // Those "nop"'s are really uggly, but there's
- nop; // something with DSP's pipelines which I don't
- nop; // understand, resulting this code to fail without
- // having those "nop"'s (Benny)
-
- rsa0?reqDMA = r2;
- // Trigger DMA transfer on input stream,
- // if needed to replenish input buffer
-
- nop;
- // Yet another magic "nop" to make stuff work
-
- ,,r98 = acc0 $+>> 0;
- // store sample in ALU
-
- nop;
- // latency on load register.
- // (this one is understandable)
-
- *rsa2++1 = r98;
- // store sample in output buffer
-
- nop; // The same story
- nop; // as above again ...
- nop;
- }
- // TODO: cycles per loop iteration
-
- r2->strmBufPtr = rsa0,, ;
- // Update the modified buffer pointers
-
- r4 = rsa2;
- // Load output pointer position into r4
-
- r2 = r0->nextSCB;
- // Sibling task
-
- goto execSibling_2ind1 // takes 6 cycles
- after {
- r98 = r2->thisSPB:entryPoint;
- // Load child routine entry and data address
-
- r1 = r9;
- // r9 is r2->thisSPB
-
- r0->dma_outBufPtr = r4,,
- // Store updated output buffer pointer
-
- ind = r8;
- // r8 is r2->entryPoint
- }
-}
diff --git a/ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwcdma.h b/ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwcdma.h
deleted file mode 100644
index 7ff0d458..00000000
--- a/ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwcdma.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* generated from cwcdma.osp DO NOT MODIFY */
-
-#ifndef __HEADER_cwcdma_H__
-#define __HEADER_cwcdma_H__
-
-static struct dsp_symbol_entry cwcdma_symbols[] = {
- { 0x8000, "EXECCHILD",0x03 },
- { 0x8001, "EXECCHILD_98",0x03 },
- { 0x8003, "EXECCHILD_PUSH1IND",0x03 },
- { 0x8008, "EXECSIBLING",0x03 },
- { 0x800a, "EXECSIBLING_298",0x03 },
- { 0x800b, "EXECSIBLING_2IND1",0x03 },
- { 0x8010, "TIMINGMASTER",0x03 },
- { 0x804f, "S16_CODECINPUTTASK",0x03 },
- { 0x805e, "PCMSERIALINPUTTASK",0x03 },
- { 0x806d, "S16_MIX_TO_OSTREAM",0x03 },
- { 0x809a, "S16_MIX",0x03 },
- { 0x80bb, "S16_UPSRC",0x03 },
- { 0x813b, "MIX3_EXP",0x03 },
- { 0x8164, "DECIMATEBYPOW2",0x03 },
- { 0x8197, "VARIDECIMATE",0x03 },
- { 0x81f2, "_3DINPUTTASK",0x03 },
- { 0x820a, "_3DPRLGCINPTASK",0x03 },
- { 0x8227, "_3DSTEREOINPUTTASK",0x03 },
- { 0x8242, "_3DOUTPUTTASK",0x03 },
- { 0x82c4, "HRTF_MORPH_TASK",0x03 },
- { 0x82c6, "WAIT4DATA",0x03 },
- { 0x82fa, "PROLOGIC",0x03 },
- { 0x8496, "DECORRELATOR",0x03 },
- { 0x84a4, "STEREO2MONO",0x03 },
- { 0x0000, "OVERLAYBEGINADDRESS",0x00 },
- { 0x0000, "DMAREADER",0x03 },
- { 0x0018, "#CODE_END",0x00 },
-}; /* cwcdma symbols */
-
-static u32 cwcdma_code[] = {
-/* OVERLAYBEGINADDRESS */
-/* 0000 */ 0x00002731,0x00001400,0x0004c108,0x000e5044,
-/* 0002 */ 0x0005f608,0x00000000,0x000007ae,0x000be300,
-/* 0004 */ 0x00058630,0x00001400,0x0007afb0,0x000e9584,
-/* 0006 */ 0x00007301,0x000a9840,0x0005e708,0x000cd104,
-/* 0008 */ 0x00067008,0x00000000,0x000902a0,0x00001000,
-/* 000A */ 0x00012a01,0x000c0000,0x00000000,0x00000000,
-/* 000C */ 0x00021843,0x000c0000,0x00000000,0x000c0000,
-/* 000E */ 0x0000e101,0x000c0000,0x00000cac,0x00000000,
-/* 0010 */ 0x00080000,0x000e5ca1,0x00000000,0x000c0000,
-/* 0012 */ 0x00000000,0x00000000,0x00000000,0x00092c00,
-/* 0014 */ 0x000122c1,0x000e5084,0x00058730,0x00001400,
-/* 0016 */ 0x000d7488,0x000e4782,0x00007401,0x0001c100
-};
-
-/* #CODE_END */
-
-static struct dsp_segment_desc cwcdma_segments[] = {
- { SEGTYPE_SP_PROGRAM, 0x00000000, 0x00000030, cwcdma_code },
-};
-
-static struct dsp_module_desc cwcdma_module = {
- "cwcdma",
- {
- 27,
- cwcdma_symbols
- },
- 1,
- cwcdma_segments,
-};
-
-#endif /* __HEADER_cwcdma_H__ */
diff --git a/ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwcsnoop.h b/ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwcsnoop.h
deleted file mode 100644
index 6929d0a5..00000000
--- a/ANDROID_3.4.5/sound/pci/cs46xx/imgs/cwcsnoop.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* generated from cwcsnoop.osp DO NOT MODIFY */
-
-#ifndef __HEADER_cwcsnoop_H__
-#define __HEADER_cwcsnoop_H__
-
-static struct dsp_symbol_entry cwcsnoop_symbols[] = {
- { 0x0500, "OVERLAYBEGINADDRESS",0x00 },
- { 0x0500, "OUTPUTSNOOP",0x03 },
- { 0x051f, "#CODE_END",0x00 },
-}; /* cwcsnoop symbols */
-
-static u32 cwcsnoop_code[] = {
-/* 0000 */ 0x0007bfb0,0x000b4e40,0x0007c088,0x000c0617,
-/* 0002 */ 0x00049705,0x00000000,0x00080630,0x00001028,
-/* 0004 */ 0x00076408,0x000efb84,0x00066008,0x00000000,
-/* 0006 */ 0x0007c908,0x000c0000,0x00046725,0x000efa44,
-/* 0008 */ 0x0005f708,0x00000000,0x0001d402,0x000b2e00,
-/* 000A */ 0x0003d418,0x00001000,0x0008d574,0x000c4293,
-/* 000C */ 0x00065625,0x000ea30e,0x00096c01,0x000c6f92,
-/* 000E */ 0x0006a58a,0x000f6085,0x00002f43,0x00000000,
-/* 0010 */ 0x000a83a0,0x00001028,0x0005e608,0x000c0000,
-/* 0012 */ 0x00000000,0x00000000,0x000ca108,0x000dcca1,
-/* 0014 */ 0x00003bac,0x000fb205,0x00073843,0x00000000,
-/* 0016 */ 0x000d8730,0x00001028,0x0006600a,0x000c0000,
-/* 0018 */ 0x00057488,0x00000000,0x00000000,0x000e5084,
-/* 001A */ 0x00000000,0x000eba44,0x00087401,0x000e4782,
-/* 001C */ 0x00000734,0x00001000,0x00010705,0x000a6880,
-/* 001E */ 0x00006a88,0x000c75c4
-};
-/* #CODE_END */
-
-static struct dsp_segment_desc cwcsnoop_segments[] = {
- { SEGTYPE_SP_PROGRAM, 0x00000000, 0x0000003e, cwcsnoop_code },
-};
-
-static struct dsp_module_desc cwcsnoop_module = {
- "cwcsnoop",
- {
- 3,
- cwcsnoop_symbols
- },
- 1,
- cwcsnoop_segments,
-};
-
-#endif /* __HEADER_cwcsnoop_H__ */
diff --git a/ANDROID_3.4.5/sound/pci/cs5530.c b/ANDROID_3.4.5/sound/pci/cs5530.c
deleted file mode 100644
index c47cabff..00000000
--- a/ANDROID_3.4.5/sound/pci/cs5530.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * cs5530.c - Initialisation code for Cyrix/NatSemi VSA1 softaudio
- *
- * (C) Copyright 2007 Ash Willis <ashwillis@programmer.net>
- * (C) Copyright 2003 Red Hat Inc <alan@lxorguk.ukuu.org.uk>
- *
- * This driver was ported (shamelessly ripped ;) from oss/kahlua.c but I did
- * mess with it a bit. The chip seems to have to have trouble with full duplex
- * mode. If we're recording in 8bit 8000kHz, say, and we then attempt to
- * simultaneously play back audio at 16bit 44100kHz, the device actually plays
- * back in the same format in which it is capturing. By forcing the chip to
- * always play/capture in 16/44100, we can let alsa-lib convert the samples and
- * that way we can hack up some full duplex audio.
- *
- * XpressAudio(tm) is used on the Cyrix MediaGX (now NatSemi Geode) systems.
- * The older version (VSA1) provides fairly good soundblaster emulation
- * although there are a couple of bugs: large DMA buffers break record,
- * and the MPU event handling seems suspect. VSA2 allows the native driver
- * to control the AC97 audio engine directly and requires a different driver.
- *
- * Thanks to National Semiconductor for providing the needed information
- * on the XpressAudio(tm) internals.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * TO DO:
- * Investigate whether we can portably support Cognac (5520) in the
- * same manner.
- */
-
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/sb.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Ash Willis");
-MODULE_DESCRIPTION("CS5530 Audio");
-MODULE_LICENSE("GPL");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for CS5530 Audio driver.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for CS5530 Audio driver.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable CS5530 Audio driver.");
-
-struct snd_cs5530 {
- struct snd_card *card;
- struct pci_dev *pci;
- struct snd_sb *sb;
- unsigned long pci_base;
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_cs5530_ids) = {
- {PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO, PCI_ANY_ID,
- PCI_ANY_ID, 0, 0},
- {0,}
-};
-
-MODULE_DEVICE_TABLE(pci, snd_cs5530_ids);
-
-static int snd_cs5530_free(struct snd_cs5530 *chip)
-{
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
- kfree(chip);
- return 0;
-}
-
-static int snd_cs5530_dev_free(struct snd_device *device)
-{
- struct snd_cs5530 *chip = device->device_data;
- return snd_cs5530_free(chip);
-}
-
-static void __devexit snd_cs5530_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static u8 __devinit snd_cs5530_mixer_read(unsigned long io, u8 reg)
-{
- outb(reg, io + 4);
- udelay(20);
- reg = inb(io + 5);
- udelay(20);
- return reg;
-}
-
-static int __devinit snd_cs5530_create(struct snd_card *card,
- struct pci_dev *pci,
- struct snd_cs5530 **rchip)
-{
- struct snd_cs5530 *chip;
- unsigned long sb_base;
- u8 irq, dma8, dma16 = 0;
- u16 map;
- void __iomem *mem;
- int err;
-
- static struct snd_device_ops ops = {
- .dev_free = snd_cs5530_dev_free,
- };
- *rchip = NULL;
-
- err = pci_enable_device(pci);
- if (err < 0)
- return err;
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- chip->card = card;
- chip->pci = pci;
-
- err = pci_request_regions(pci, "CS5530");
- if (err < 0) {
- kfree(chip);
- pci_disable_device(pci);
- return err;
- }
- chip->pci_base = pci_resource_start(pci, 0);
-
- mem = pci_ioremap_bar(pci, 0);
- if (mem == NULL) {
- kfree(chip);
- pci_disable_device(pci);
- return -EBUSY;
- }
-
- map = readw(mem + 0x18);
- iounmap(mem);
-
- /* Map bits
- 0:1 * 0x20 + 0x200 = sb base
- 2 sb enable
- 3 adlib enable
- 5 MPU enable 0x330
- 6 MPU enable 0x300
-
- The other bits may be used internally so must be masked */
-
- sb_base = 0x220 + 0x20 * (map & 3);
-
- if (map & (1<<2))
- printk(KERN_INFO "CS5530: XpressAudio at 0x%lx\n", sb_base);
- else {
- printk(KERN_ERR "Could not find XpressAudio!\n");
- snd_cs5530_free(chip);
- return -ENODEV;
- }
-
- if (map & (1<<5))
- printk(KERN_INFO "CS5530: MPU at 0x300\n");
- else if (map & (1<<6))
- printk(KERN_INFO "CS5530: MPU at 0x330\n");
-
- irq = snd_cs5530_mixer_read(sb_base, 0x80) & 0x0F;
- dma8 = snd_cs5530_mixer_read(sb_base, 0x81);
-
- if (dma8 & 0x20)
- dma16 = 5;
- else if (dma8 & 0x40)
- dma16 = 6;
- else if (dma8 & 0x80)
- dma16 = 7;
- else {
- printk(KERN_ERR "CS5530: No 16bit DMA enabled\n");
- snd_cs5530_free(chip);
- return -ENODEV;
- }
-
- if (dma8 & 0x01)
- dma8 = 0;
- else if (dma8 & 02)
- dma8 = 1;
- else if (dma8 & 0x08)
- dma8 = 3;
- else {
- printk(KERN_ERR "CS5530: No 8bit DMA enabled\n");
- snd_cs5530_free(chip);
- return -ENODEV;
- }
-
- if (irq & 1)
- irq = 9;
- else if (irq & 2)
- irq = 5;
- else if (irq & 4)
- irq = 7;
- else if (irq & 8)
- irq = 10;
- else {
- printk(KERN_ERR "CS5530: SoundBlaster IRQ not set\n");
- snd_cs5530_free(chip);
- return -ENODEV;
- }
-
- printk(KERN_INFO "CS5530: IRQ: %d DMA8: %d DMA16: %d\n", irq, dma8,
- dma16);
-
- err = snd_sbdsp_create(card, sb_base, irq, snd_sb16dsp_interrupt, dma8,
- dma16, SB_HW_CS5530, &chip->sb);
- if (err < 0) {
- printk(KERN_ERR "CS5530: Could not create SoundBlaster\n");
- snd_cs5530_free(chip);
- return err;
- }
-
- err = snd_sb16dsp_pcm(chip->sb, 0, &chip->sb->pcm);
- if (err < 0) {
- printk(KERN_ERR "CS5530: Could not create PCM\n");
- snd_cs5530_free(chip);
- return err;
- }
-
- err = snd_sbmixer_new(chip->sb);
- if (err < 0) {
- printk(KERN_ERR "CS5530: Could not create Mixer\n");
- snd_cs5530_free(chip);
- return err;
- }
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
- if (err < 0) {
- snd_cs5530_free(chip);
- return err;
- }
-
- snd_card_set_dev(card, &pci->dev);
- *rchip = chip;
- return 0;
-}
-
-static int __devinit snd_cs5530_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct snd_cs5530 *chip = NULL;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
-
- if (err < 0)
- return err;
-
- err = snd_cs5530_create(card, pci, &chip);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- strcpy(card->driver, "CS5530");
- strcpy(card->shortname, "CS5530 Audio");
- sprintf(card->longname, "%s at 0x%lx", card->shortname, chip->pci_base);
-
- err = snd_card_register(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_cs5530_ids,
- .probe = snd_cs5530_probe,
- .remove = __devexit_p(snd_cs5530_remove),
-};
-
-static int __init alsa_card_cs5530_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_cs5530_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_cs5530_init)
-module_exit(alsa_card_cs5530_exit)
-
diff --git a/ANDROID_3.4.5/sound/pci/cs5535audio/Makefile b/ANDROID_3.4.5/sound/pci/cs5535audio/Makefile
deleted file mode 100644
index ccc64226..00000000
--- a/ANDROID_3.4.5/sound/pci/cs5535audio/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile for cs5535audio
-#
-
-snd-cs5535audio-y := cs5535audio.o cs5535audio_pcm.o
-snd-cs5535audio-$(CONFIG_PM) += cs5535audio_pm.o
-snd-cs5535audio-$(CONFIG_OLPC) += cs5535audio_olpc.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o
diff --git a/ANDROID_3.4.5/sound/pci/cs5535audio/cs5535audio.c b/ANDROID_3.4.5/sound/pci/cs5535audio/cs5535audio.c
deleted file mode 100644
index a2fb2173..00000000
--- a/ANDROID_3.4.5/sound/pci/cs5535audio/cs5535audio.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Driver for audio on multifunction CS5535/6 companion device
- * Copyright (C) Jaya Kumar
- *
- * Based on Jaroslav Kysela and Takashi Iwai's examples.
- * This work was sponsored by CIS(M) Sdn Bhd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <asm/io.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/rawmidi.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-#include <sound/asoundef.h>
-#include "cs5535audio.h"
-
-#define DRIVER_NAME "cs5535audio"
-
-static char *ac97_quirk;
-module_param(ac97_quirk, charp, 0444);
-MODULE_PARM_DESC(ac97_quirk, "AC'97 board specific workarounds.");
-
-static struct ac97_quirk ac97_quirks[] __devinitdata = {
-#if 0 /* Not yet confirmed if all 5536 boards are HP only */
- {
- .subvendor = PCI_VENDOR_ID_AMD,
- .subdevice = PCI_DEVICE_ID_AMD_CS5536_AUDIO,
- .name = "AMD RDK",
- .type = AC97_TUNE_HP_ONLY
- },
-#endif
- {}
-};
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for " DRIVER_NAME);
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for " DRIVER_NAME);
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable " DRIVER_NAME);
-
-static DEFINE_PCI_DEVICE_TABLE(snd_cs5535audio_ids) = {
- { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO) },
- { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO) },
- {}
-};
-
-MODULE_DEVICE_TABLE(pci, snd_cs5535audio_ids);
-
-static void wait_till_cmd_acked(struct cs5535audio *cs5535au, unsigned long timeout)
-{
- unsigned int tmp;
- do {
- tmp = cs_readl(cs5535au, ACC_CODEC_CNTL);
- if (!(tmp & CMD_NEW))
- break;
- udelay(1);
- } while (--timeout);
- if (!timeout)
- snd_printk(KERN_ERR "Failure writing to cs5535 codec\n");
-}
-
-static unsigned short snd_cs5535audio_codec_read(struct cs5535audio *cs5535au,
- unsigned short reg)
-{
- unsigned int regdata;
- unsigned int timeout;
- unsigned int val;
-
- regdata = ((unsigned int) reg) << 24;
- regdata |= ACC_CODEC_CNTL_RD_CMD;
- regdata |= CMD_NEW;
-
- cs_writel(cs5535au, ACC_CODEC_CNTL, regdata);
- wait_till_cmd_acked(cs5535au, 50);
-
- timeout = 50;
- do {
- val = cs_readl(cs5535au, ACC_CODEC_STATUS);
- if ((val & STS_NEW) && reg == (val >> 24))
- break;
- udelay(1);
- } while (--timeout);
- if (!timeout)
- snd_printk(KERN_ERR "Failure reading codec reg 0x%x,"
- "Last value=0x%x\n", reg, val);
-
- return (unsigned short) val;
-}
-
-static void snd_cs5535audio_codec_write(struct cs5535audio *cs5535au,
- unsigned short reg, unsigned short val)
-{
- unsigned int regdata;
-
- regdata = ((unsigned int) reg) << 24;
- regdata |= val;
- regdata &= CMD_MASK;
- regdata |= CMD_NEW;
- regdata &= ACC_CODEC_CNTL_WR_CMD;
-
- cs_writel(cs5535au, ACC_CODEC_CNTL, regdata);
- wait_till_cmd_acked(cs5535au, 50);
-}
-
-static void snd_cs5535audio_ac97_codec_write(struct snd_ac97 *ac97,
- unsigned short reg, unsigned short val)
-{
- struct cs5535audio *cs5535au = ac97->private_data;
- snd_cs5535audio_codec_write(cs5535au, reg, val);
-}
-
-static unsigned short snd_cs5535audio_ac97_codec_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- struct cs5535audio *cs5535au = ac97->private_data;
- return snd_cs5535audio_codec_read(cs5535au, reg);
-}
-
-static int __devinit snd_cs5535audio_mixer(struct cs5535audio *cs5535au)
-{
- struct snd_card *card = cs5535au->card;
- struct snd_ac97_bus *pbus;
- struct snd_ac97_template ac97;
- int err;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_cs5535audio_ac97_codec_write,
- .read = snd_cs5535audio_ac97_codec_read,
- };
-
- if ((err = snd_ac97_bus(card, 0, &ops, NULL, &pbus)) < 0)
- return err;
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.scaps = AC97_SCAP_AUDIO | AC97_SCAP_SKIP_MODEM
- | AC97_SCAP_POWER_SAVE;
- ac97.private_data = cs5535au;
- ac97.pci = cs5535au->pci;
-
- /* set any OLPC-specific scaps */
- olpc_prequirks(card, &ac97);
-
- if ((err = snd_ac97_mixer(pbus, &ac97, &cs5535au->ac97)) < 0) {
- snd_printk(KERN_ERR "mixer failed\n");
- return err;
- }
-
- snd_ac97_tune_hardware(cs5535au->ac97, ac97_quirks, ac97_quirk);
-
- err = olpc_quirks(card, cs5535au->ac97);
- if (err < 0) {
- snd_printk(KERN_ERR "olpc quirks failed\n");
- return err;
- }
-
- return 0;
-}
-
-static void process_bm0_irq(struct cs5535audio *cs5535au)
-{
- u8 bm_stat;
- spin_lock(&cs5535au->reg_lock);
- bm_stat = cs_readb(cs5535au, ACC_BM0_STATUS);
- spin_unlock(&cs5535au->reg_lock);
- if (bm_stat & EOP) {
- struct cs5535audio_dma *dma;
- dma = cs5535au->playback_substream->runtime->private_data;
- snd_pcm_period_elapsed(cs5535au->playback_substream);
- } else {
- snd_printk(KERN_ERR "unexpected bm0 irq src, bm_stat=%x\n",
- bm_stat);
- }
-}
-
-static void process_bm1_irq(struct cs5535audio *cs5535au)
-{
- u8 bm_stat;
- spin_lock(&cs5535au->reg_lock);
- bm_stat = cs_readb(cs5535au, ACC_BM1_STATUS);
- spin_unlock(&cs5535au->reg_lock);
- if (bm_stat & EOP) {
- struct cs5535audio_dma *dma;
- dma = cs5535au->capture_substream->runtime->private_data;
- snd_pcm_period_elapsed(cs5535au->capture_substream);
- }
-}
-
-static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id)
-{
- u16 acc_irq_stat;
- unsigned char count;
- struct cs5535audio *cs5535au = dev_id;
-
- if (cs5535au == NULL)
- return IRQ_NONE;
-
- acc_irq_stat = cs_readw(cs5535au, ACC_IRQ_STATUS);
-
- if (!acc_irq_stat)
- return IRQ_NONE;
- for (count = 0; count < 4; count++) {
- if (acc_irq_stat & (1 << count)) {
- switch (count) {
- case IRQ_STS:
- cs_readl(cs5535au, ACC_GPIO_STATUS);
- break;
- case WU_IRQ_STS:
- cs_readl(cs5535au, ACC_GPIO_STATUS);
- break;
- case BM0_IRQ_STS:
- process_bm0_irq(cs5535au);
- break;
- case BM1_IRQ_STS:
- process_bm1_irq(cs5535au);
- break;
- default:
- snd_printk(KERN_ERR "Unexpected irq src: "
- "0x%x\n", acc_irq_stat);
- break;
- }
- }
- }
- return IRQ_HANDLED;
-}
-
-static int snd_cs5535audio_free(struct cs5535audio *cs5535au)
-{
- synchronize_irq(cs5535au->irq);
- pci_set_power_state(cs5535au->pci, 3);
-
- if (cs5535au->irq >= 0)
- free_irq(cs5535au->irq, cs5535au);
-
- pci_release_regions(cs5535au->pci);
- pci_disable_device(cs5535au->pci);
- kfree(cs5535au);
- return 0;
-}
-
-static int snd_cs5535audio_dev_free(struct snd_device *device)
-{
- struct cs5535audio *cs5535au = device->device_data;
- return snd_cs5535audio_free(cs5535au);
-}
-
-static int __devinit snd_cs5535audio_create(struct snd_card *card,
- struct pci_dev *pci,
- struct cs5535audio **rcs5535au)
-{
- struct cs5535audio *cs5535au;
-
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_cs5535audio_dev_free,
- };
-
- *rcs5535au = NULL;
- if ((err = pci_enable_device(pci)) < 0)
- return err;
-
- if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0) {
- printk(KERN_WARNING "unable to get 32bit dma\n");
- err = -ENXIO;
- goto pcifail;
- }
-
- cs5535au = kzalloc(sizeof(*cs5535au), GFP_KERNEL);
- if (cs5535au == NULL) {
- err = -ENOMEM;
- goto pcifail;
- }
-
- spin_lock_init(&cs5535au->reg_lock);
- cs5535au->card = card;
- cs5535au->pci = pci;
- cs5535au->irq = -1;
-
- if ((err = pci_request_regions(pci, "CS5535 Audio")) < 0) {
- kfree(cs5535au);
- goto pcifail;
- }
-
- cs5535au->port = pci_resource_start(pci, 0);
-
- if (request_irq(pci->irq, snd_cs5535audio_interrupt,
- IRQF_SHARED, KBUILD_MODNAME, cs5535au)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- err = -EBUSY;
- goto sndfail;
- }
-
- cs5535au->irq = pci->irq;
- pci_set_master(pci);
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
- cs5535au, &ops)) < 0)
- goto sndfail;
-
- snd_card_set_dev(card, &pci->dev);
-
- *rcs5535au = cs5535au;
- return 0;
-
-sndfail: /* leave the device alive, just kill the snd */
- snd_cs5535audio_free(cs5535au);
- return err;
-
-pcifail:
- pci_disable_device(pci);
- return err;
-}
-
-static int __devinit snd_cs5535audio_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct cs5535audio *cs5535au;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- if ((err = snd_cs5535audio_create(card, pci, &cs5535au)) < 0)
- goto probefail_out;
-
- card->private_data = cs5535au;
-
- if ((err = snd_cs5535audio_mixer(cs5535au)) < 0)
- goto probefail_out;
-
- if ((err = snd_cs5535audio_pcm(cs5535au)) < 0)
- goto probefail_out;
-
- strcpy(card->driver, DRIVER_NAME);
-
- strcpy(card->shortname, "CS5535 Audio");
- sprintf(card->longname, "%s %s at 0x%lx, irq %i",
- card->shortname, card->driver,
- cs5535au->port, cs5535au->irq);
-
- if ((err = snd_card_register(card)) < 0)
- goto probefail_out;
-
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-
-probefail_out:
- snd_card_free(card);
- return err;
-}
-
-static void __devexit snd_cs5535audio_remove(struct pci_dev *pci)
-{
- olpc_quirks_cleanup();
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_cs5535audio_ids,
- .probe = snd_cs5535audio_probe,
- .remove = __devexit_p(snd_cs5535audio_remove),
-#ifdef CONFIG_PM
- .suspend = snd_cs5535audio_suspend,
- .resume = snd_cs5535audio_resume,
-#endif
-};
-
-static int __init alsa_card_cs5535audio_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_cs5535audio_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_cs5535audio_init)
-module_exit(alsa_card_cs5535audio_exit)
-
-MODULE_AUTHOR("Jaya Kumar");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("CS5535 Audio");
-MODULE_SUPPORTED_DEVICE("CS5535 Audio");
diff --git a/ANDROID_3.4.5/sound/pci/cs5535audio/cs5535audio.h b/ANDROID_3.4.5/sound/pci/cs5535audio/cs5535audio.h
deleted file mode 100644
index 51966d78..00000000
--- a/ANDROID_3.4.5/sound/pci/cs5535audio/cs5535audio.h
+++ /dev/null
@@ -1,142 +0,0 @@
-#ifndef __SOUND_CS5535AUDIO_H
-#define __SOUND_CS5535AUDIO_H
-
-#define cs_writel(cs5535au, reg, val) outl(val, (cs5535au)->port + reg)
-#define cs_writeb(cs5535au, reg, val) outb(val, (cs5535au)->port + reg)
-#define cs_readl(cs5535au, reg) inl((cs5535au)->port + reg)
-#define cs_readw(cs5535au, reg) inw((cs5535au)->port + reg)
-#define cs_readb(cs5535au, reg) inb((cs5535au)->port + reg)
-
-#define CS5535AUDIO_MAX_DESCRIPTORS 128
-
-/* acc_codec bar0 reg addrs */
-#define ACC_GPIO_STATUS 0x00
-#define ACC_CODEC_STATUS 0x08
-#define ACC_CODEC_CNTL 0x0C
-#define ACC_IRQ_STATUS 0x12
-#define ACC_BM0_CMD 0x20
-#define ACC_BM1_CMD 0x28
-#define ACC_BM0_PRD 0x24
-#define ACC_BM1_PRD 0x2C
-#define ACC_BM0_STATUS 0x21
-#define ACC_BM1_STATUS 0x29
-#define ACC_BM0_PNTR 0x60
-#define ACC_BM1_PNTR 0x64
-
-/* acc_codec bar0 reg bits */
-/* ACC_IRQ_STATUS */
-#define IRQ_STS 0
-#define WU_IRQ_STS 1
-#define BM0_IRQ_STS 2
-#define BM1_IRQ_STS 3
-/* ACC_BMX_STATUS */
-#define EOP (1<<0)
-#define BM_EOP_ERR (1<<1)
-/* ACC_BMX_CTL */
-#define BM_CTL_EN 0x01
-#define BM_CTL_PAUSE 0x03
-#define BM_CTL_DIS 0x00
-#define BM_CTL_BYTE_ORD_LE 0x00
-#define BM_CTL_BYTE_ORD_BE 0x04
-/* cs5535 specific ac97 codec register defines */
-#define CMD_MASK 0xFF00FFFF
-#define CMD_NEW 0x00010000
-#define STS_NEW 0x00020000
-#define PRM_RDY_STS 0x00800000
-#define ACC_CODEC_CNTL_WR_CMD (~0x80000000)
-#define ACC_CODEC_CNTL_RD_CMD 0x80000000
-#define ACC_CODEC_CNTL_LNK_SHUTDOWN 0x00040000
-#define ACC_CODEC_CNTL_LNK_WRM_RST 0x00020000
-#define PRD_JMP 0x2000
-#define PRD_EOP 0x4000
-#define PRD_EOT 0x8000
-
-enum { CS5535AUDIO_DMA_PLAYBACK, CS5535AUDIO_DMA_CAPTURE, NUM_CS5535AUDIO_DMAS };
-
-struct cs5535audio;
-
-struct cs5535audio_dma_ops {
- int type;
- void (*enable_dma)(struct cs5535audio *cs5535au);
- void (*disable_dma)(struct cs5535audio *cs5535au);
- void (*pause_dma)(struct cs5535audio *cs5535au);
- void (*setup_prd)(struct cs5535audio *cs5535au, u32 prd_addr);
- u32 (*read_prd)(struct cs5535audio *cs5535au);
- u32 (*read_dma_pntr)(struct cs5535audio *cs5535au);
-};
-
-struct cs5535audio_dma_desc {
- u32 addr;
- u16 size;
- u16 ctlreserved;
-};
-
-struct cs5535audio_dma {
- const struct cs5535audio_dma_ops *ops;
- struct snd_dma_buffer desc_buf;
- struct snd_pcm_substream *substream;
- unsigned int buf_addr, buf_bytes;
- unsigned int period_bytes, periods;
- u32 saved_prd;
- int pcm_open_flag;
-};
-
-struct cs5535audio {
- struct snd_card *card;
- struct snd_ac97 *ac97;
- struct snd_pcm *pcm;
- int irq;
- struct pci_dev *pci;
- unsigned long port;
- spinlock_t reg_lock;
- struct snd_pcm_substream *playback_substream;
- struct snd_pcm_substream *capture_substream;
- struct cs5535audio_dma dmas[NUM_CS5535AUDIO_DMAS];
-};
-
-#ifdef CONFIG_PM
-int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state);
-int snd_cs5535audio_resume(struct pci_dev *pci);
-#endif
-
-#ifdef CONFIG_OLPC
-void __devinit olpc_prequirks(struct snd_card *card,
- struct snd_ac97_template *ac97);
-int __devinit olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97);
-void __devexit olpc_quirks_cleanup(void);
-void olpc_analog_input(struct snd_ac97 *ac97, int on);
-void olpc_mic_bias(struct snd_ac97 *ac97, int on);
-
-static inline void olpc_capture_open(struct snd_ac97 *ac97)
-{
- /* default to Analog Input off */
- olpc_analog_input(ac97, 0);
- /* enable MIC Bias for recording */
- olpc_mic_bias(ac97, 1);
-}
-
-static inline void olpc_capture_close(struct snd_ac97 *ac97)
-{
- /* disable Analog Input */
- olpc_analog_input(ac97, 0);
- /* disable the MIC Bias (so the recording LED turns off) */
- olpc_mic_bias(ac97, 0);
-}
-#else
-static inline void olpc_prequirks(struct snd_card *card,
- struct snd_ac97_template *ac97) { }
-static inline int olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97)
-{
- return 0;
-}
-static inline void olpc_quirks_cleanup(void) { }
-static inline void olpc_analog_input(struct snd_ac97 *ac97, int on) { }
-static inline void olpc_mic_bias(struct snd_ac97 *ac97, int on) { }
-static inline void olpc_capture_open(struct snd_ac97 *ac97) { }
-static inline void olpc_capture_close(struct snd_ac97 *ac97) { }
-#endif
-
-int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535audio);
-
-#endif /* __SOUND_CS5535AUDIO_H */
-
diff --git a/ANDROID_3.4.5/sound/pci/cs5535audio/cs5535audio_olpc.c b/ANDROID_3.4.5/sound/pci/cs5535audio/cs5535audio_olpc.c
deleted file mode 100644
index 50da49be..00000000
--- a/ANDROID_3.4.5/sound/pci/cs5535audio/cs5535audio_olpc.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * OLPC XO-1 additional sound features
- *
- * Copyright © 2006 Jaya Kumar <jayakumar.lkml@gmail.com>
- * Copyright © 2007-2008 Andres Salomon <dilinger@debian.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/ac97_codec.h>
-#include <linux/gpio.h>
-
-#include <asm/olpc.h>
-#include "cs5535audio.h"
-
-#define DRV_NAME "cs5535audio-olpc"
-
-/*
- * OLPC has an additional feature on top of the regular AD1888 codec features.
- * It has an Analog Input mode that is switched into (after disabling the
- * High Pass Filter) via GPIO. It is supported on B2 and later models.
- */
-void olpc_analog_input(struct snd_ac97 *ac97, int on)
-{
- int err;
-
- if (!machine_is_olpc())
- return;
-
- /* update the High Pass Filter (via AC97_AD_TEST2) */
- err = snd_ac97_update_bits(ac97, AC97_AD_TEST2,
- 1 << AC97_AD_HPFD_SHIFT, on << AC97_AD_HPFD_SHIFT);
- if (err < 0) {
- snd_printk(KERN_ERR "setting High Pass Filter - %d\n", err);
- return;
- }
-
- /* set Analog Input through GPIO */
- gpio_set_value(OLPC_GPIO_MIC_AC, on);
-}
-
-/*
- * OLPC XO-1's V_REFOUT is a mic bias enable.
- */
-void olpc_mic_bias(struct snd_ac97 *ac97, int on)
-{
- int err;
-
- if (!machine_is_olpc())
- return;
-
- on = on ? 0 : 1;
- err = snd_ac97_update_bits(ac97, AC97_AD_MISC,
- 1 << AC97_AD_VREFD_SHIFT, on << AC97_AD_VREFD_SHIFT);
- if (err < 0)
- snd_printk(KERN_ERR "setting MIC Bias - %d\n", err);
-}
-
-static int olpc_dc_info(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int olpc_dc_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v)
-{
- v->value.integer.value[0] = gpio_get_value(OLPC_GPIO_MIC_AC);
- return 0;
-}
-
-static int olpc_dc_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v)
-{
- struct cs5535audio *cs5535au = snd_kcontrol_chip(kctl);
-
- olpc_analog_input(cs5535au->ac97, v->value.integer.value[0]);
- return 1;
-}
-
-static int olpc_mic_info(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int olpc_mic_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v)
-{
- struct cs5535audio *cs5535au = snd_kcontrol_chip(kctl);
- struct snd_ac97 *ac97 = cs5535au->ac97;
- int i;
-
- i = (snd_ac97_read(ac97, AC97_AD_MISC) >> AC97_AD_VREFD_SHIFT) & 0x1;
- v->value.integer.value[0] = i ? 0 : 1;
- return 0;
-}
-
-static int olpc_mic_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v)
-{
- struct cs5535audio *cs5535au = snd_kcontrol_chip(kctl);
-
- olpc_mic_bias(cs5535au->ac97, v->value.integer.value[0]);
- return 1;
-}
-
-static struct snd_kcontrol_new olpc_cs5535audio_ctls[] __devinitdata = {
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "DC Mode Enable",
- .info = olpc_dc_info,
- .get = olpc_dc_get,
- .put = olpc_dc_put,
- .private_value = 0,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "MIC Bias Enable",
- .info = olpc_mic_info,
- .get = olpc_mic_get,
- .put = olpc_mic_put,
- .private_value = 0,
-},
-};
-
-void __devinit olpc_prequirks(struct snd_card *card,
- struct snd_ac97_template *ac97)
-{
- if (!machine_is_olpc())
- return;
-
- /* invert EAPD if on an OLPC B3 or higher */
- if (olpc_board_at_least(olpc_board_pre(0xb3)))
- ac97->scaps |= AC97_SCAP_INV_EAPD;
-}
-
-int __devinit olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97)
-{
- struct snd_ctl_elem_id elem;
- int i, err;
-
- if (!machine_is_olpc())
- return 0;
-
- if (gpio_request(OLPC_GPIO_MIC_AC, DRV_NAME)) {
- printk(KERN_ERR DRV_NAME ": unable to allocate MIC GPIO\n");
- return -EIO;
- }
- gpio_direction_output(OLPC_GPIO_MIC_AC, 0);
-
- /* drop the original AD1888 HPF control */
- memset(&elem, 0, sizeof(elem));
- elem.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strncpy(elem.name, "High Pass Filter Enable", sizeof(elem.name));
- snd_ctl_remove_id(card, &elem);
-
- /* drop the original V_REFOUT control */
- memset(&elem, 0, sizeof(elem));
- elem.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strncpy(elem.name, "V_REFOUT Enable", sizeof(elem.name));
- snd_ctl_remove_id(card, &elem);
-
- /* add the OLPC-specific controls */
- for (i = 0; i < ARRAY_SIZE(olpc_cs5535audio_ctls); i++) {
- err = snd_ctl_add(card, snd_ctl_new1(&olpc_cs5535audio_ctls[i],
- ac97->private_data));
- if (err < 0) {
- gpio_free(OLPC_GPIO_MIC_AC);
- return err;
- }
- }
-
- /* turn off the mic by default */
- olpc_mic_bias(ac97, 0);
- return 0;
-}
-
-void __devexit olpc_quirks_cleanup(void)
-{
- gpio_free(OLPC_GPIO_MIC_AC);
-}
diff --git a/ANDROID_3.4.5/sound/pci/cs5535audio/cs5535audio_pcm.c b/ANDROID_3.4.5/sound/pci/cs5535audio/cs5535audio_pcm.c
deleted file mode 100644
index dbf94b18..00000000
--- a/ANDROID_3.4.5/sound/pci/cs5535audio/cs5535audio_pcm.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * Driver for audio on multifunction CS5535 companion device
- * Copyright (C) Jaya Kumar
- *
- * Based on Jaroslav Kysela and Takashi Iwai's examples.
- * This work was sponsored by CIS(M) Sdn Bhd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * todo: add be fmt support, spdif, pm
- */
-
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/initval.h>
-#include <sound/asoundef.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/ac97_codec.h>
-#include "cs5535audio.h"
-
-static struct snd_pcm_hardware snd_cs5535audio_playback =
-{
- .info = (
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME
- ),
- .formats = (
- SNDRV_PCM_FMTBIT_S16_LE
- ),
- .rates = (
- SNDRV_PCM_RATE_CONTINUOUS |
- SNDRV_PCM_RATE_8000_48000
- ),
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (64*1024 - 16),
- .periods_min = 1,
- .periods_max = CS5535AUDIO_MAX_DESCRIPTORS,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_cs5535audio_capture =
-{
- .info = (
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID
- ),
- .formats = (
- SNDRV_PCM_FMTBIT_S16_LE
- ),
- .rates = (
- SNDRV_PCM_RATE_CONTINUOUS |
- SNDRV_PCM_RATE_8000_48000
- ),
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (64*1024 - 16),
- .periods_min = 1,
- .periods_max = CS5535AUDIO_MAX_DESCRIPTORS,
- .fifo_size = 0,
-};
-
-static int snd_cs5535audio_playback_open(struct snd_pcm_substream *substream)
-{
- int err;
- struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- runtime->hw = snd_cs5535audio_playback;
- runtime->hw.rates = cs5535au->ac97->rates[AC97_RATES_FRONT_DAC];
- snd_pcm_limit_hw_rates(runtime);
- cs5535au->playback_substream = substream;
- runtime->private_data = &(cs5535au->dmas[CS5535AUDIO_DMA_PLAYBACK]);
- if ((err = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
- return err;
-
- return 0;
-}
-
-static int snd_cs5535audio_playback_close(struct snd_pcm_substream *substream)
-{
- return 0;
-}
-
-#define CS5535AUDIO_DESC_LIST_SIZE \
- PAGE_ALIGN(CS5535AUDIO_MAX_DESCRIPTORS * sizeof(struct cs5535audio_dma_desc))
-
-static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au,
- struct cs5535audio_dma *dma,
- struct snd_pcm_substream *substream,
- unsigned int periods,
- unsigned int period_bytes)
-{
- unsigned int i;
- u32 addr, desc_addr, jmpprd_addr;
- struct cs5535audio_dma_desc *lastdesc;
-
- if (periods > CS5535AUDIO_MAX_DESCRIPTORS)
- return -ENOMEM;
-
- if (dma->desc_buf.area == NULL) {
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(cs5535au->pci),
- CS5535AUDIO_DESC_LIST_SIZE+1,
- &dma->desc_buf) < 0)
- return -ENOMEM;
- dma->period_bytes = dma->periods = 0;
- }
-
- if (dma->periods == periods && dma->period_bytes == period_bytes)
- return 0;
-
- /* the u32 cast is okay because in snd*create we successfully told
- pci alloc that we're only 32 bit capable so the uppper will be 0 */
- addr = (u32) substream->runtime->dma_addr;
- desc_addr = (u32) dma->desc_buf.addr;
- for (i = 0; i < periods; i++) {
- struct cs5535audio_dma_desc *desc =
- &((struct cs5535audio_dma_desc *) dma->desc_buf.area)[i];
- desc->addr = cpu_to_le32(addr);
- desc->size = cpu_to_le16(period_bytes);
- desc->ctlreserved = cpu_to_le16(PRD_EOP);
- desc_addr += sizeof(struct cs5535audio_dma_desc);
- addr += period_bytes;
- }
- /* we reserved one dummy descriptor at the end to do the PRD jump */
- lastdesc = &((struct cs5535audio_dma_desc *) dma->desc_buf.area)[periods];
- lastdesc->addr = cpu_to_le32((u32) dma->desc_buf.addr);
- lastdesc->size = 0;
- lastdesc->ctlreserved = cpu_to_le16(PRD_JMP);
- jmpprd_addr = cpu_to_le32(lastdesc->addr +
- (sizeof(struct cs5535audio_dma_desc)*periods));
-
- dma->substream = substream;
- dma->period_bytes = period_bytes;
- dma->periods = periods;
- spin_lock_irq(&cs5535au->reg_lock);
- dma->ops->disable_dma(cs5535au);
- dma->ops->setup_prd(cs5535au, jmpprd_addr);
- spin_unlock_irq(&cs5535au->reg_lock);
- return 0;
-}
-
-static void cs5535audio_playback_enable_dma(struct cs5535audio *cs5535au)
-{
- cs_writeb(cs5535au, ACC_BM0_CMD, BM_CTL_EN);
-}
-
-static void cs5535audio_playback_disable_dma(struct cs5535audio *cs5535au)
-{
- cs_writeb(cs5535au, ACC_BM0_CMD, 0);
-}
-
-static void cs5535audio_playback_pause_dma(struct cs5535audio *cs5535au)
-{
- cs_writeb(cs5535au, ACC_BM0_CMD, BM_CTL_PAUSE);
-}
-
-static void cs5535audio_playback_setup_prd(struct cs5535audio *cs5535au,
- u32 prd_addr)
-{
- cs_writel(cs5535au, ACC_BM0_PRD, prd_addr);
-}
-
-static u32 cs5535audio_playback_read_prd(struct cs5535audio *cs5535au)
-{
- return cs_readl(cs5535au, ACC_BM0_PRD);
-}
-
-static u32 cs5535audio_playback_read_dma_pntr(struct cs5535audio *cs5535au)
-{
- return cs_readl(cs5535au, ACC_BM0_PNTR);
-}
-
-static void cs5535audio_capture_enable_dma(struct cs5535audio *cs5535au)
-{
- cs_writeb(cs5535au, ACC_BM1_CMD, BM_CTL_EN);
-}
-
-static void cs5535audio_capture_disable_dma(struct cs5535audio *cs5535au)
-{
- cs_writeb(cs5535au, ACC_BM1_CMD, 0);
-}
-
-static void cs5535audio_capture_pause_dma(struct cs5535audio *cs5535au)
-{
- cs_writeb(cs5535au, ACC_BM1_CMD, BM_CTL_PAUSE);
-}
-
-static void cs5535audio_capture_setup_prd(struct cs5535audio *cs5535au,
- u32 prd_addr)
-{
- cs_writel(cs5535au, ACC_BM1_PRD, prd_addr);
-}
-
-static u32 cs5535audio_capture_read_prd(struct cs5535audio *cs5535au)
-{
- return cs_readl(cs5535au, ACC_BM1_PRD);
-}
-
-static u32 cs5535audio_capture_read_dma_pntr(struct cs5535audio *cs5535au)
-{
- return cs_readl(cs5535au, ACC_BM1_PNTR);
-}
-
-static void cs5535audio_clear_dma_packets(struct cs5535audio *cs5535au,
- struct cs5535audio_dma *dma,
- struct snd_pcm_substream *substream)
-{
- snd_dma_free_pages(&dma->desc_buf);
- dma->desc_buf.area = NULL;
- dma->substream = NULL;
-}
-
-static int snd_cs5535audio_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
- struct cs5535audio_dma *dma = substream->runtime->private_data;
- int err;
-
- err = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
- dma->buf_addr = substream->runtime->dma_addr;
- dma->buf_bytes = params_buffer_bytes(hw_params);
-
- err = cs5535audio_build_dma_packets(cs5535au, dma, substream,
- params_periods(hw_params),
- params_period_bytes(hw_params));
- if (!err)
- dma->pcm_open_flag = 1;
-
- return err;
-}
-
-static int snd_cs5535audio_hw_free(struct snd_pcm_substream *substream)
-{
- struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
- struct cs5535audio_dma *dma = substream->runtime->private_data;
-
- if (dma->pcm_open_flag) {
- if (substream == cs5535au->playback_substream)
- snd_ac97_update_power(cs5535au->ac97,
- AC97_PCM_FRONT_DAC_RATE, 0);
- else
- snd_ac97_update_power(cs5535au->ac97,
- AC97_PCM_LR_ADC_RATE, 0);
- dma->pcm_open_flag = 0;
- }
- cs5535audio_clear_dma_packets(cs5535au, dma, substream);
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_cs5535audio_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
- return snd_ac97_set_rate(cs5535au->ac97, AC97_PCM_FRONT_DAC_RATE,
- substream->runtime->rate);
-}
-
-static int snd_cs5535audio_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
- struct cs5535audio_dma *dma = substream->runtime->private_data;
- int err = 0;
-
- spin_lock(&cs5535au->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- dma->ops->pause_dma(cs5535au);
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- dma->ops->enable_dma(cs5535au);
- break;
- case SNDRV_PCM_TRIGGER_START:
- dma->ops->enable_dma(cs5535au);
- break;
- case SNDRV_PCM_TRIGGER_RESUME:
- dma->ops->enable_dma(cs5535au);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- dma->ops->disable_dma(cs5535au);
- break;
- case SNDRV_PCM_TRIGGER_SUSPEND:
- dma->ops->disable_dma(cs5535au);
- break;
- default:
- snd_printk(KERN_ERR "unhandled trigger\n");
- err = -EINVAL;
- break;
- }
- spin_unlock(&cs5535au->reg_lock);
- return err;
-}
-
-static snd_pcm_uframes_t snd_cs5535audio_pcm_pointer(struct snd_pcm_substream
- *substream)
-{
- struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
- u32 curdma;
- struct cs5535audio_dma *dma;
-
- dma = substream->runtime->private_data;
- curdma = dma->ops->read_dma_pntr(cs5535au);
- if (curdma < dma->buf_addr) {
- snd_printk(KERN_ERR "curdma=%x < %x bufaddr.\n",
- curdma, dma->buf_addr);
- return 0;
- }
- curdma -= dma->buf_addr;
- if (curdma >= dma->buf_bytes) {
- snd_printk(KERN_ERR "diff=%x >= %x buf_bytes.\n",
- curdma, dma->buf_bytes);
- return 0;
- }
- return bytes_to_frames(substream->runtime, curdma);
-}
-
-static int snd_cs5535audio_capture_open(struct snd_pcm_substream *substream)
-{
- int err;
- struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- runtime->hw = snd_cs5535audio_capture;
- runtime->hw.rates = cs5535au->ac97->rates[AC97_RATES_ADC];
- snd_pcm_limit_hw_rates(runtime);
- cs5535au->capture_substream = substream;
- runtime->private_data = &(cs5535au->dmas[CS5535AUDIO_DMA_CAPTURE]);
- if ((err = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
- return err;
- olpc_capture_open(cs5535au->ac97);
- return 0;
-}
-
-static int snd_cs5535audio_capture_close(struct snd_pcm_substream *substream)
-{
- struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
- olpc_capture_close(cs5535au->ac97);
- return 0;
-}
-
-static int snd_cs5535audio_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
- return snd_ac97_set_rate(cs5535au->ac97, AC97_PCM_LR_ADC_RATE,
- substream->runtime->rate);
-}
-
-static struct snd_pcm_ops snd_cs5535audio_playback_ops = {
- .open = snd_cs5535audio_playback_open,
- .close = snd_cs5535audio_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cs5535audio_hw_params,
- .hw_free = snd_cs5535audio_hw_free,
- .prepare = snd_cs5535audio_playback_prepare,
- .trigger = snd_cs5535audio_trigger,
- .pointer = snd_cs5535audio_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_cs5535audio_capture_ops = {
- .open = snd_cs5535audio_capture_open,
- .close = snd_cs5535audio_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cs5535audio_hw_params,
- .hw_free = snd_cs5535audio_hw_free,
- .prepare = snd_cs5535audio_capture_prepare,
- .trigger = snd_cs5535audio_trigger,
- .pointer = snd_cs5535audio_pcm_pointer,
-};
-
-static struct cs5535audio_dma_ops snd_cs5535audio_playback_dma_ops = {
- .type = CS5535AUDIO_DMA_PLAYBACK,
- .enable_dma = cs5535audio_playback_enable_dma,
- .disable_dma = cs5535audio_playback_disable_dma,
- .setup_prd = cs5535audio_playback_setup_prd,
- .read_prd = cs5535audio_playback_read_prd,
- .pause_dma = cs5535audio_playback_pause_dma,
- .read_dma_pntr = cs5535audio_playback_read_dma_pntr,
-};
-
-static struct cs5535audio_dma_ops snd_cs5535audio_capture_dma_ops = {
- .type = CS5535AUDIO_DMA_CAPTURE,
- .enable_dma = cs5535audio_capture_enable_dma,
- .disable_dma = cs5535audio_capture_disable_dma,
- .setup_prd = cs5535audio_capture_setup_prd,
- .read_prd = cs5535audio_capture_read_prd,
- .pause_dma = cs5535audio_capture_pause_dma,
- .read_dma_pntr = cs5535audio_capture_read_dma_pntr,
-};
-
-int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535au)
-{
- struct snd_pcm *pcm;
- int err;
-
- err = snd_pcm_new(cs5535au->card, "CS5535 Audio", 0, 1, 1, &pcm);
- if (err < 0)
- return err;
-
- cs5535au->dmas[CS5535AUDIO_DMA_PLAYBACK].ops =
- &snd_cs5535audio_playback_dma_ops;
- cs5535au->dmas[CS5535AUDIO_DMA_CAPTURE].ops =
- &snd_cs5535audio_capture_dma_ops;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_cs5535audio_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_cs5535audio_capture_ops);
-
- pcm->private_data = cs5535au;
- pcm->info_flags = 0;
- strcpy(pcm->name, "CS5535 Audio");
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(cs5535au->pci),
- 64*1024, 128*1024);
- cs5535au->pcm = pcm;
-
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/pci/cs5535audio/cs5535audio_pm.c b/ANDROID_3.4.5/sound/pci/cs5535audio/cs5535audio_pm.c
deleted file mode 100644
index 185b0008..00000000
--- a/ANDROID_3.4.5/sound/pci/cs5535audio/cs5535audio_pm.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Power management for audio on multifunction CS5535 companion device
- * Copyright (C) Jaya Kumar
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/initval.h>
-#include <sound/asoundef.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include "cs5535audio.h"
-
-static void snd_cs5535audio_stop_hardware(struct cs5535audio *cs5535au)
-{
- /*
- we depend on snd_ac97_suspend to tell the
- AC97 codec to shutdown. the amd spec suggests
- that the LNK_SHUTDOWN be done at the same time
- that the codec power-down is issued. instead,
- we do it just after rather than at the same
- time. excluding codec specific build_ops->suspend
- ac97 powerdown hits:
- 0x8000 EAPD
- 0x4000 Headphone amplifier
- 0x0300 ADC & DAC
- 0x0400 Analog Mixer powerdown (Vref on)
- I am not sure if this is the best that we can do.
- The remainder to be investigated are:
- - analog mixer (vref off) 0x0800
- - AC-link powerdown 0x1000
- - codec internal clock 0x2000
- */
-
- /* set LNK_SHUTDOWN to shutdown AC link */
- cs_writel(cs5535au, ACC_CODEC_CNTL, ACC_CODEC_CNTL_LNK_SHUTDOWN);
-
-}
-
-int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct cs5535audio *cs5535au = card->private_data;
- int i;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(cs5535au->pcm);
- snd_ac97_suspend(cs5535au->ac97);
- for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) {
- struct cs5535audio_dma *dma = &cs5535au->dmas[i];
- if (dma && dma->substream)
- dma->saved_prd = dma->ops->read_prd(cs5535au);
- }
- /* save important regs, then disable aclink in hw */
- snd_cs5535audio_stop_hardware(cs5535au);
-
- if (pci_save_state(pci)) {
- printk(KERN_ERR "cs5535audio: pci_save_state failed!\n");
- return -EIO;
- }
- pci_disable_device(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-int snd_cs5535audio_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct cs5535audio *cs5535au = card->private_data;
- u32 tmp;
- int timeout;
- int i;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "cs5535audio: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
-
- /* set LNK_WRM_RST to reset AC link */
- cs_writel(cs5535au, ACC_CODEC_CNTL, ACC_CODEC_CNTL_LNK_WRM_RST);
-
- timeout = 50;
- do {
- tmp = cs_readl(cs5535au, ACC_CODEC_STATUS);
- if (tmp & PRM_RDY_STS)
- break;
- udelay(1);
- } while (--timeout);
-
- if (!timeout)
- snd_printk(KERN_ERR "Failure getting AC Link ready\n");
-
- /* set up rate regs, dma. actual initiation is done in trig */
- for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) {
- struct cs5535audio_dma *dma = &cs5535au->dmas[i];
- if (dma && dma->substream) {
- dma->substream->ops->prepare(dma->substream);
- dma->ops->setup_prd(cs5535au, dma->saved_prd);
- }
- }
-
- /* we depend on ac97 to perform the codec power up */
- snd_ac97_resume(cs5535au->ac97);
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
-
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/Makefile b/ANDROID_3.4.5/sound/pci/ctxfi/Makefile
deleted file mode 100644
index 15075f89..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-snd-ctxfi-objs := xfi.o ctatc.o ctvmem.o ctpcm.o ctmixer.o ctresource.o \
- ctsrc.o ctamixer.o ctdaio.o ctimap.o cthardware.o cttimer.o \
- cthw20k2.o cthw20k1.o
-
-obj-$(CONFIG_SND_CTXFI) += snd-ctxfi.o
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ct20k1reg.h b/ANDROID_3.4.5/sound/pci/ctxfi/ct20k1reg.h
deleted file mode 100644
index f2e34e3f..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/ct20k1reg.h
+++ /dev/null
@@ -1,636 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- */
-
-#ifndef CT20K1REG_H
-#define CT20k1REG_H
-
-/* 20k1 registers */
-#define DSPXRAM_START 0x000000
-#define DSPXRAM_END 0x013FFC
-#define DSPAXRAM_START 0x020000
-#define DSPAXRAM_END 0x023FFC
-#define DSPYRAM_START 0x040000
-#define DSPYRAM_END 0x04FFFC
-#define DSPAYRAM_START 0x020000
-#define DSPAYRAM_END 0x063FFC
-#define DSPMICRO_START 0x080000
-#define DSPMICRO_END 0x0B3FFC
-#define DSP0IO_START 0x100000
-#define DSP0IO_END 0x101FFC
-#define AUDIORINGIPDSP0_START 0x100000
-#define AUDIORINGIPDSP0_END 0x1003FC
-#define AUDIORINGOPDSP0_START 0x100400
-#define AUDIORINGOPDSP0_END 0x1007FC
-#define AUDPARARINGIODSP0_START 0x100800
-#define AUDPARARINGIODSP0_END 0x100BFC
-#define DSP0LOCALHWREG_START 0x100C00
-#define DSP0LOCALHWREG_END 0x100C3C
-#define DSP0XYRAMAGINDEX_START 0x100C40
-#define DSP0XYRAMAGINDEX_END 0x100C5C
-#define DSP0XYRAMAGMDFR_START 0x100C60
-#define DSP0XYRAMAGMDFR_END 0x100C7C
-#define DSP0INTCONTLVEC_START 0x100C80
-#define DSP0INTCONTLVEC_END 0x100CD8
-#define INTCONTLGLOBALREG_START 0x100D1C
-#define INTCONTLGLOBALREG_END 0x100D3C
-#define HOSTINTFPORTADDRCONTDSP0 0x100D40
-#define HOSTINTFPORTDATADSP0 0x100D44
-#define TIME0PERENBDSP0 0x100D60
-#define TIME0COUNTERDSP0 0x100D64
-#define TIME1PERENBDSP0 0x100D68
-#define TIME1COUNTERDSP0 0x100D6C
-#define TIME2PERENBDSP0 0x100D70
-#define TIME2COUNTERDSP0 0x100D74
-#define TIME3PERENBDSP0 0x100D78
-#define TIME3COUNTERDSP0 0x100D7C
-#define XRAMINDOPERREFNOUP_STARTDSP0 0x100D80
-#define XRAMINDOPERREFNOUP_ENDDSP0 0x100D9C
-#define XRAMINDOPERREFUP_STARTDSP0 0x100DA0
-#define XRAMINDOPERREFUP_ENDDSP0 0x100DBC
-#define YRAMINDOPERREFNOUP_STARTDSP0 0x100DC0
-#define YRAMINDOPERREFNOUP_ENDDSP0 0x100DDC
-#define YRAMINDOPERREFUP_STARTDSP0 0x100DE0
-#define YRAMINDOPERREFUP_ENDDSP0 0x100DFC
-#define DSP0CONDCODE 0x100E00
-#define DSP0STACKFLAG 0x100E04
-#define DSP0PROGCOUNTSTACKPTREG 0x100E08
-#define DSP0PROGCOUNTSTACKDATAREG 0x100E0C
-#define DSP0CURLOOPADDRREG 0x100E10
-#define DSP0CURLOOPCOUNT 0x100E14
-#define DSP0TOPLOOPCOUNTSTACK 0x100E18
-#define DSP0TOPLOOPADDRSTACK 0x100E1C
-#define DSP0LOOPSTACKPTR 0x100E20
-#define DSP0STASSTACKDATAREG 0x100E24
-#define DSP0STASSTACKPTR 0x100E28
-#define DSP0PROGCOUNT 0x100E2C
-#define GLOBDSPDEBGREG 0x100E30
-#define GLOBDSPBREPTRREG 0x100E30
-#define DSP0XYRAMBASE_START 0x100EA0
-#define DSP0XYRAMBASE_END 0x100EBC
-#define DSP0XYRAMLENG_START 0x100EC0
-#define DSP0XYRAMLENG_END 0x100EDC
-#define SEMAPHOREREGDSP0 0x100EE0
-#define DSP0INTCONTMASKREG 0x100EE4
-#define DSP0INTCONTPENDREG 0x100EE8
-#define DSP0INTCONTSERVINT 0x100EEC
-#define DSPINTCONTEXTINTMODREG 0x100EEC
-#define GPIODSP0 0x100EFC
-#define DMADSPBASEADDRREG_STARTDSP0 0x100F00
-#define DMADSPBASEADDRREG_ENDDSP0 0x100F1C
-#define DMAHOSTBASEADDRREG_STARTDSP0 0x100F20
-#define DMAHOSTBASEADDRREG_ENDDSP0 0x100F3C
-#define DMADSPCURADDRREG_STARTDSP0 0x100F40
-#define DMADSPCURADDRREG_ENDDSP0 0x100F5C
-#define DMAHOSTCURADDRREG_STARTDSP0 0x100F60
-#define DMAHOSTCURADDRREG_ENDDSP0 0x100F7C
-#define DMATANXCOUNTREG_STARTDSP0 0x100F80
-#define DMATANXCOUNTREG_ENDDSP0 0x100F9C
-#define DMATIMEBUGREG_STARTDSP0 0x100FA0
-#define DMATIMEBUGREG_ENDDSP0 0x100FAC
-#define DMACNTLMODFREG_STARTDSP0 0x100FA0
-#define DMACNTLMODFREG_ENDDSP0 0x100FAC
-
-#define DMAGLOBSTATSREGDSP0 0x100FEC
-#define DSP0XGPRAM_START 0x101000
-#define DSP0XGPRAM_END 0x1017FC
-#define DSP0YGPRAM_START 0x101800
-#define DSP0YGPRAM_END 0x101FFC
-
-
-
-
-#define AUDIORINGIPDSP1_START 0x102000
-#define AUDIORINGIPDSP1_END 0x1023FC
-#define AUDIORINGOPDSP1_START 0x102400
-#define AUDIORINGOPDSP1_END 0x1027FC
-#define AUDPARARINGIODSP1_START 0x102800
-#define AUDPARARINGIODSP1_END 0x102BFC
-#define DSP1LOCALHWREG_START 0x102C00
-#define DSP1LOCALHWREG_END 0x102C3C
-#define DSP1XYRAMAGINDEX_START 0x102C40
-#define DSP1XYRAMAGINDEX_END 0x102C5C
-#define DSP1XYRAMAGMDFR_START 0x102C60
-#define DSP1XYRAMAGMDFR_END 0x102C7C
-#define DSP1INTCONTLVEC_START 0x102C80
-#define DSP1INTCONTLVEC_END 0x102CD8
-#define HOSTINTFPORTADDRCONTDSP1 0x102D40
-#define HOSTINTFPORTDATADSP1 0x102D44
-#define TIME0PERENBDSP1 0x102D60
-#define TIME0COUNTERDSP1 0x102D64
-#define TIME1PERENBDSP1 0x102D68
-#define TIME1COUNTERDSP1 0x102D6C
-#define TIME2PERENBDSP1 0x102D70
-#define TIME2COUNTERDSP1 0x102D74
-#define TIME3PERENBDSP1 0x102D78
-#define TIME3COUNTERDSP1 0x102D7C
-#define XRAMINDOPERREFNOUP_STARTDSP1 0x102D80
-#define XRAMINDOPERREFNOUP_ENDDSP1 0x102D9C
-#define XRAMINDOPERREFUP_STARTDSP1 0x102DA0
-#define XRAMINDOPERREFUP_ENDDSP1 0x102DBC
-#define YRAMINDOPERREFNOUP_STARTDSP1 0x102DC0
-#define YRAMINDOPERREFNOUP_ENDDSP1 0x102DDC
-#define YRAMINDOPERREFUP_STARTDSP1 0x102DE0
-#define YRAMINDOPERREFUP_ENDDSP1 0x102DFC
-
-#define DSP1CONDCODE 0x102E00
-#define DSP1STACKFLAG 0x102E04
-#define DSP1PROGCOUNTSTACKPTREG 0x102E08
-#define DSP1PROGCOUNTSTACKDATAREG 0x102E0C
-#define DSP1CURLOOPADDRREG 0x102E10
-#define DSP1CURLOOPCOUNT 0x102E14
-#define DSP1TOPLOOPCOUNTSTACK 0x102E18
-#define DSP1TOPLOOPADDRSTACK 0x102E1C
-#define DSP1LOOPSTACKPTR 0x102E20
-#define DSP1STASSTACKDATAREG 0x102E24
-#define DSP1STASSTACKPTR 0x102E28
-#define DSP1PROGCOUNT 0x102E2C
-#define DSP1XYRAMBASE_START 0x102EA0
-#define DSP1XYRAMBASE_END 0x102EBC
-#define DSP1XYRAMLENG_START 0x102EC0
-#define DSP1XYRAMLENG_END 0x102EDC
-#define SEMAPHOREREGDSP1 0x102EE0
-#define DSP1INTCONTMASKREG 0x102EE4
-#define DSP1INTCONTPENDREG 0x102EE8
-#define DSP1INTCONTSERVINT 0x102EEC
-#define GPIODSP1 0x102EFC
-#define DMADSPBASEADDRREG_STARTDSP1 0x102F00
-#define DMADSPBASEADDRREG_ENDDSP1 0x102F1C
-#define DMAHOSTBASEADDRREG_STARTDSP1 0x102F20
-#define DMAHOSTBASEADDRREG_ENDDSP1 0x102F3C
-#define DMADSPCURADDRREG_STARTDSP1 0x102F40
-#define DMADSPCURADDRREG_ENDDSP1 0x102F5C
-#define DMAHOSTCURADDRREG_STARTDSP1 0x102F60
-#define DMAHOSTCURADDRREG_ENDDSP1 0x102F7C
-#define DMATANXCOUNTREG_STARTDSP1 0x102F80
-#define DMATANXCOUNTREG_ENDDSP1 0x102F9C
-#define DMATIMEBUGREG_STARTDSP1 0x102FA0
-#define DMATIMEBUGREG_ENDDSP1 0x102FAC
-#define DMACNTLMODFREG_STARTDSP1 0x102FA0
-#define DMACNTLMODFREG_ENDDSP1 0x102FAC
-
-#define DMAGLOBSTATSREGDSP1 0x102FEC
-#define DSP1XGPRAM_START 0x103000
-#define DSP1XGPRAM_END 0x1033FC
-#define DSP1YGPRAM_START 0x103400
-#define DSP1YGPRAM_END 0x1037FC
-
-
-
-#define AUDIORINGIPDSP2_START 0x104000
-#define AUDIORINGIPDSP2_END 0x1043FC
-#define AUDIORINGOPDSP2_START 0x104400
-#define AUDIORINGOPDSP2_END 0x1047FC
-#define AUDPARARINGIODSP2_START 0x104800
-#define AUDPARARINGIODSP2_END 0x104BFC
-#define DSP2LOCALHWREG_START 0x104C00
-#define DSP2LOCALHWREG_END 0x104C3C
-#define DSP2XYRAMAGINDEX_START 0x104C40
-#define DSP2XYRAMAGINDEX_END 0x104C5C
-#define DSP2XYRAMAGMDFR_START 0x104C60
-#define DSP2XYRAMAGMDFR_END 0x104C7C
-#define DSP2INTCONTLVEC_START 0x104C80
-#define DSP2INTCONTLVEC_END 0x104CD8
-#define HOSTINTFPORTADDRCONTDSP2 0x104D40
-#define HOSTINTFPORTDATADSP2 0x104D44
-#define TIME0PERENBDSP2 0x104D60
-#define TIME0COUNTERDSP2 0x104D64
-#define TIME1PERENBDSP2 0x104D68
-#define TIME1COUNTERDSP2 0x104D6C
-#define TIME2PERENBDSP2 0x104D70
-#define TIME2COUNTERDSP2 0x104D74
-#define TIME3PERENBDSP2 0x104D78
-#define TIME3COUNTERDSP2 0x104D7C
-#define XRAMINDOPERREFNOUP_STARTDSP2 0x104D80
-#define XRAMINDOPERREFNOUP_ENDDSP2 0x104D9C
-#define XRAMINDOPERREFUP_STARTDSP2 0x104DA0
-#define XRAMINDOPERREFUP_ENDDSP2 0x104DBC
-#define YRAMINDOPERREFNOUP_STARTDSP2 0x104DC0
-#define YRAMINDOPERREFNOUP_ENDDSP2 0x104DDC
-#define YRAMINDOPERREFUP_STARTDSP2 0x104DE0
-#define YRAMINDOPERREFUP_ENDDSP2 0x104DFC
-#define DSP2CONDCODE 0x104E00
-#define DSP2STACKFLAG 0x104E04
-#define DSP2PROGCOUNTSTACKPTREG 0x104E08
-#define DSP2PROGCOUNTSTACKDATAREG 0x104E0C
-#define DSP2CURLOOPADDRREG 0x104E10
-#define DSP2CURLOOPCOUNT 0x104E14
-#define DSP2TOPLOOPCOUNTSTACK 0x104E18
-#define DSP2TOPLOOPADDRSTACK 0x104E1C
-#define DSP2LOOPSTACKPTR 0x104E20
-#define DSP2STASSTACKDATAREG 0x104E24
-#define DSP2STASSTACKPTR 0x104E28
-#define DSP2PROGCOUNT 0x104E2C
-#define DSP2XYRAMBASE_START 0x104EA0
-#define DSP2XYRAMBASE_END 0x104EBC
-#define DSP2XYRAMLENG_START 0x104EC0
-#define DSP2XYRAMLENG_END 0x104EDC
-#define SEMAPHOREREGDSP2 0x104EE0
-#define DSP2INTCONTMASKREG 0x104EE4
-#define DSP2INTCONTPENDREG 0x104EE8
-#define DSP2INTCONTSERVINT 0x104EEC
-#define GPIODSP2 0x104EFC
-#define DMADSPBASEADDRREG_STARTDSP2 0x104F00
-#define DMADSPBASEADDRREG_ENDDSP2 0x104F1C
-#define DMAHOSTBASEADDRREG_STARTDSP2 0x104F20
-#define DMAHOSTBASEADDRREG_ENDDSP2 0x104F3C
-#define DMADSPCURADDRREG_STARTDSP2 0x104F40
-#define DMADSPCURADDRREG_ENDDSP2 0x104F5C
-#define DMAHOSTCURADDRREG_STARTDSP2 0x104F60
-#define DMAHOSTCURADDRREG_ENDDSP2 0x104F7C
-#define DMATANXCOUNTREG_STARTDSP2 0x104F80
-#define DMATANXCOUNTREG_ENDDSP2 0x104F9C
-#define DMATIMEBUGREG_STARTDSP2 0x104FA0
-#define DMATIMEBUGREG_ENDDSP2 0x104FAC
-#define DMACNTLMODFREG_STARTDSP2 0x104FA0
-#define DMACNTLMODFREG_ENDDSP2 0x104FAC
-
-#define DMAGLOBSTATSREGDSP2 0x104FEC
-#define DSP2XGPRAM_START 0x105000
-#define DSP2XGPRAM_END 0x1051FC
-#define DSP2YGPRAM_START 0x105800
-#define DSP2YGPRAM_END 0x1059FC
-
-
-
-#define AUDIORINGIPDSP3_START 0x106000
-#define AUDIORINGIPDSP3_END 0x1063FC
-#define AUDIORINGOPDSP3_START 0x106400
-#define AUDIORINGOPDSP3_END 0x1067FC
-#define AUDPARARINGIODSP3_START 0x106800
-#define AUDPARARINGIODSP3_END 0x106BFC
-#define DSP3LOCALHWREG_START 0x106C00
-#define DSP3LOCALHWREG_END 0x106C3C
-#define DSP3XYRAMAGINDEX_START 0x106C40
-#define DSP3XYRAMAGINDEX_END 0x106C5C
-#define DSP3XYRAMAGMDFR_START 0x106C60
-#define DSP3XYRAMAGMDFR_END 0x106C7C
-#define DSP3INTCONTLVEC_START 0x106C80
-#define DSP3INTCONTLVEC_END 0x106CD8
-#define HOSTINTFPORTADDRCONTDSP3 0x106D40
-#define HOSTINTFPORTDATADSP3 0x106D44
-#define TIME0PERENBDSP3 0x106D60
-#define TIME0COUNTERDSP3 0x106D64
-#define TIME1PERENBDSP3 0x106D68
-#define TIME1COUNTERDSP3 0x106D6C
-#define TIME2PERENBDSP3 0x106D70
-#define TIME2COUNTERDSP3 0x106D74
-#define TIME3PERENBDSP3 0x106D78
-#define TIME3COUNTERDSP3 0x106D7C
-#define XRAMINDOPERREFNOUP_STARTDSP3 0x106D80
-#define XRAMINDOPERREFNOUP_ENDDSP3 0x106D9C
-#define XRAMINDOPERREFUP_STARTDSP3 0x106DA0
-#define XRAMINDOPERREFUP_ENDDSP3 0x106DBC
-#define YRAMINDOPERREFNOUP_STARTDSP3 0x106DC0
-#define YRAMINDOPERREFNOUP_ENDDSP3 0x106DDC
-#define YRAMINDOPERREFUP_STARTDSP3 0x106DE0
-#define YRAMINDOPERREFUP_ENDDSP3 0x100DFC
-
-#define DSP3CONDCODE 0x106E00
-#define DSP3STACKFLAG 0x106E04
-#define DSP3PROGCOUNTSTACKPTREG 0x106E08
-#define DSP3PROGCOUNTSTACKDATAREG 0x106E0C
-#define DSP3CURLOOPADDRREG 0x106E10
-#define DSP3CURLOOPCOUNT 0x106E14
-#define DSP3TOPLOOPCOUNTSTACK 0x106E18
-#define DSP3TOPLOOPADDRSTACK 0x106E1C
-#define DSP3LOOPSTACKPTR 0x106E20
-#define DSP3STASSTACKDATAREG 0x106E24
-#define DSP3STASSTACKPTR 0x106E28
-#define DSP3PROGCOUNT 0x106E2C
-#define DSP3XYRAMBASE_START 0x106EA0
-#define DSP3XYRAMBASE_END 0x106EBC
-#define DSP3XYRAMLENG_START 0x106EC0
-#define DSP3XYRAMLENG_END 0x106EDC
-#define SEMAPHOREREGDSP3 0x106EE0
-#define DSP3INTCONTMASKREG 0x106EE4
-#define DSP3INTCONTPENDREG 0x106EE8
-#define DSP3INTCONTSERVINT 0x106EEC
-#define GPIODSP3 0x106EFC
-#define DMADSPBASEADDRREG_STARTDSP3 0x106F00
-#define DMADSPBASEADDRREG_ENDDSP3 0x106F1C
-#define DMAHOSTBASEADDRREG_STARTDSP3 0x106F20
-#define DMAHOSTBASEADDRREG_ENDDSP3 0x106F3C
-#define DMADSPCURADDRREG_STARTDSP3 0x106F40
-#define DMADSPCURADDRREG_ENDDSP3 0x106F5C
-#define DMAHOSTCURADDRREG_STARTDSP3 0x106F60
-#define DMAHOSTCURADDRREG_ENDDSP3 0x106F7C
-#define DMATANXCOUNTREG_STARTDSP3 0x106F80
-#define DMATANXCOUNTREG_ENDDSP3 0x106F9C
-#define DMATIMEBUGREG_STARTDSP3 0x106FA0
-#define DMATIMEBUGREG_ENDDSP3 0x106FAC
-#define DMACNTLMODFREG_STARTDSP3 0x106FA0
-#define DMACNTLMODFREG_ENDDSP3 0x106FAC
-
-#define DMAGLOBSTATSREGDSP3 0x106FEC
-#define DSP3XGPRAM_START 0x107000
-#define DSP3XGPRAM_END 0x1071FC
-#define DSP3YGPRAM_START 0x107800
-#define DSP3YGPRAM_END 0x1079FC
-
-/* end of DSP reg definitions */
-
-#define DSPAIMAP_START 0x108000
-#define DSPAIMAP_END 0x1083FC
-#define DSPPIMAP_START 0x108400
-#define DSPPIMAP_END 0x1087FC
-#define DSPPOMAP_START 0x108800
-#define DSPPOMAP_END 0x108BFC
-#define DSPPOCTL 0x108C00
-#define TKCTL_START 0x110000
-#define TKCTL_END 0x110FFC
-#define TKCC_START 0x111000
-#define TKCC_END 0x111FFC
-#define TKIMAP_START 0x112000
-#define TKIMAP_END 0x112FFC
-#define TKDCTR16 0x113000
-#define TKPB16 0x113004
-#define TKBS16 0x113008
-#define TKDCTR32 0x11300C
-#define TKPB32 0x113010
-#define TKBS32 0x113014
-#define ICDCTR16 0x113018
-#define ITBS16 0x11301C
-#define ICDCTR32 0x113020
-#define ITBS32 0x113024
-#define ITSTART 0x113028
-#define TKSQ 0x11302C
-
-#define TKSCCTL_START 0x114000
-#define TKSCCTL_END 0x11403C
-#define TKSCADR_START 0x114100
-#define TKSCADR_END 0x11413C
-#define TKSCDATAX_START 0x114800
-#define TKSCDATAX_END 0x1149FC
-#define TKPCDATAX_START 0x120000
-#define TKPCDATAX_END 0x12FFFC
-
-#define MALSA 0x130000
-#define MAPPHA 0x130004
-#define MAPPLA 0x130008
-#define MALSB 0x130010
-#define MAPPHB 0x130014
-#define MAPPLB 0x130018
-
-#define TANSPORTMAPABREGS_START 0x130020
-#define TANSPORTMAPABREGS_END 0x13A2FC
-
-#define PTPAHX 0x13B000
-#define PTPALX 0x13B004
-
-#define TANSPPAGETABLEPHYADDR015_START 0x13B008
-#define TANSPPAGETABLEPHYADDR015_END 0x13B07C
-#define TRNQADRX_START 0x13B100
-#define TRNQADRX_END 0x13B13C
-#define TRNQTIMX_START 0x13B200
-#define TRNQTIMX_END 0x13B23C
-#define TRNQAPARMX_START 0x13B300
-#define TRNQAPARMX_END 0x13B33C
-
-#define TRNQCNT 0x13B400
-#define TRNCTL 0x13B404
-#define TRNIS 0x13B408
-#define TRNCURTS 0x13B40C
-
-#define AMOP_START 0x140000
-#define AMOPLO 0x140000
-#define AMOPHI 0x140004
-#define AMOP_END 0x147FFC
-#define PMOP_START 0x148000
-#define PMOPLO 0x148000
-#define PMOPHI 0x148004
-#define PMOP_END 0x14FFFC
-#define PCURR_START 0x150000
-#define PCURR_END 0x153FFC
-#define PTRAG_START 0x154000
-#define PTRAG_END 0x157FFC
-#define PSR_START 0x158000
-#define PSR_END 0x15BFFC
-
-#define PFSTAT4SEG_START 0x160000
-#define PFSTAT4SEG_END 0x160BFC
-#define PFSTAT2SEG_START 0x160C00
-#define PFSTAT2SEG_END 0x1617FC
-#define PFTARG4SEG_START 0x164000
-#define PFTARG4SEG_END 0x164BFC
-#define PFTARG2SEG_START 0x164C00
-#define PFTARG2SEG_END 0x1657FC
-#define PFSR4SEG_START 0x168000
-#define PFSR4SEG_END 0x168BFC
-#define PFSR2SEG_START 0x168C00
-#define PFSR2SEG_END 0x1697FC
-#define PCURRMS4SEG_START 0x16C000
-#define PCURRMS4SEG_END 0x16CCFC
-#define PCURRMS2SEG_START 0x16CC00
-#define PCURRMS2SEG_END 0x16D7FC
-#define PTARGMS4SEG_START 0x170000
-#define PTARGMS4SEG_END 0x172FFC
-#define PTARGMS2SEG_START 0x173000
-#define PTARGMS2SEG_END 0x1747FC
-#define PSRMS4SEG_START 0x170000
-#define PSRMS4SEG_END 0x172FFC
-#define PSRMS2SEG_START 0x173000
-#define PSRMS2SEG_END 0x1747FC
-
-#define PRING_LO_START 0x190000
-#define PRING_LO_END 0x193FFC
-#define PRING_HI_START 0x194000
-#define PRING_HI_END 0x197FFC
-#define PRING_LO_HI_START 0x198000
-#define PRING_LO_HI 0x198000
-#define PRING_LO_HI_END 0x19BFFC
-
-#define PINTFIFO 0x1A0000
-#define SRCCTL 0x1B0000
-#define SRCCCR 0x1B0004
-#define SRCIMAP 0x1B0008
-#define SRCODDC 0x1B000C
-#define SRCCA 0x1B0010
-#define SRCCF 0x1B0014
-#define SRCSA 0x1B0018
-#define SRCLA 0x1B001C
-#define SRCCTLSWR 0x1B0020
-
-/* SRC HERE */
-#define SRCALBA 0x1B002C
-#define SRCMCTL 0x1B012C
-#define SRCCERR 0x1B022C
-#define SRCITB 0x1B032C
-#define SRCIPM 0x1B082C
-#define SRCIP 0x1B102C
-#define SRCENBSTAT 0x1B202C
-#define SRCENBLO 0x1B212C
-#define SRCENBHI 0x1B222C
-#define SRCENBS 0x1B232C
-#define SRCENB 0x1B282C
-#define SRCENB07 0x1B282C
-#define SRCENBS07 0x1B302C
-
-#define SRCDN0Z 0x1B0030
-#define SRCDN0Z0 0x1B0030
-#define SRCDN0Z1 0x1B0034
-#define SRCDN0Z2 0x1B0038
-#define SRCDN0Z3 0x1B003C
-#define SRCDN1Z 0x1B0040
-#define SRCDN1Z0 0x1B0040
-#define SRCDN1Z1 0x1B0044
-#define SRCDN1Z2 0x1B0048
-#define SRCDN1Z3 0x1B004C
-#define SRCDN1Z4 0x1B0050
-#define SRCDN1Z5 0x1B0054
-#define SRCDN1Z6 0x1B0058
-#define SRCDN1Z7 0x1B005C
-#define SRCUPZ 0x1B0060
-#define SRCUPZ0 0x1B0060
-#define SRCUPZ1 0x1B0064
-#define SRCUPZ2 0x1B0068
-#define SRCUPZ3 0x1B006C
-#define SRCUPZ4 0x1B0070
-#define SRCUPZ5 0x1B0074
-#define SRCUPZ6 0x1B0078
-#define SRCUPZ7 0x1B007C
-#define SRCCD0 0x1B0080
-#define SRCCD1 0x1B0084
-#define SRCCD2 0x1B0088
-#define SRCCD3 0x1B008C
-#define SRCCD4 0x1B0090
-#define SRCCD5 0x1B0094
-#define SRCCD6 0x1B0098
-#define SRCCD7 0x1B009C
-#define SRCCD8 0x1B00A0
-#define SRCCD9 0x1B00A4
-#define SRCCDA 0x1B00A8
-#define SRCCDB 0x1B00AC
-#define SRCCDC 0x1B00B0
-#define SRCCDD 0x1B00B4
-#define SRCCDE 0x1B00B8
-#define SRCCDF 0x1B00BC
-#define SRCCD10 0x1B00C0
-#define SRCCD11 0x1B00C4
-#define SRCCD12 0x1B00C8
-#define SRCCD13 0x1B00CC
-#define SRCCD14 0x1B00D0
-#define SRCCD15 0x1B00D4
-#define SRCCD16 0x1B00D8
-#define SRCCD17 0x1B00DC
-#define SRCCD18 0x1B00E0
-#define SRCCD19 0x1B00E4
-#define SRCCD1A 0x1B00E8
-#define SRCCD1B 0x1B00EC
-#define SRCCD1C 0x1B00F0
-#define SRCCD1D 0x1B00F4
-#define SRCCD1E 0x1B00F8
-#define SRCCD1F 0x1B00FC
-
-#define SRCCONTRBLOCK_START 0x1B0100
-#define SRCCONTRBLOCK_END 0x1BFFFC
-#define FILTOP_START 0x1C0000
-#define FILTOP_END 0x1C05FC
-#define FILTIMAP_START 0x1C0800
-#define FILTIMAP_END 0x1C0DFC
-#define FILTZ1_START 0x1C1000
-#define FILTZ1_END 0x1C15FC
-#define FILTZ2_START 0x1C1800
-#define FILTZ2_END 0x1C1DFC
-#define DAOIMAP_START 0x1C5000
-#define DAOIMAP 0x1C5000
-#define DAOIMAP_END 0x1C5124
-
-#define AC97D 0x1C5400
-#define AC97A 0x1C5404
-#define AC97CTL 0x1C5408
-#define I2SCTL 0x1C5420
-
-#define SPOS 0x1C5440
-#define SPOSA 0x1C5440
-#define SPOSB 0x1C5444
-#define SPOSC 0x1C5448
-#define SPOSD 0x1C544C
-
-#define SPISA 0x1C5450
-#define SPISB 0x1C5454
-#define SPISC 0x1C5458
-#define SPISD 0x1C545C
-
-#define SPFSCTL 0x1C5460
-
-#define SPFS0 0x1C5468
-#define SPFS1 0x1C546C
-#define SPFS2 0x1C5470
-#define SPFS3 0x1C5474
-#define SPFS4 0x1C5478
-#define SPFS5 0x1C547C
-
-#define SPOCTL 0x1C5480
-#define SPICTL 0x1C5484
-#define SPISTS 0x1C5488
-#define SPINTP 0x1C548C
-#define SPINTE 0x1C5490
-#define SPUTCTLAB 0x1C5494
-#define SPUTCTLCD 0x1C5498
-
-#define SRTSPA 0x1C54C0
-#define SRTSPB 0x1C54C4
-#define SRTSPC 0x1C54C8
-#define SRTSPD 0x1C54CC
-
-#define SRTSCTL 0x1C54D0
-#define SRTSCTLA 0x1C54D0
-#define SRTSCTLB 0x1C54D4
-#define SRTSCTLC 0x1C54D8
-#define SRTSCTLD 0x1C54DC
-
-#define SRTI2S 0x1C54E0
-#define SRTICTL 0x1C54F0
-
-#define WC 0x1C6000
-#define TIMR 0x1C6004
-# define TIMR_IE (1<<15)
-# define TIMR_IP (1<<14)
-
-#define GIP 0x1C6010
-#define GIE 0x1C6014
-#define DIE 0x1C6018
-#define DIC 0x1C601C
-#define GPIO 0x1C6020
-#define GPIOCTL 0x1C6024
-#define GPIP 0x1C6028
-#define GPIE 0x1C602C
-#define DSPINT0 0x1C6030
-#define DSPEIOC 0x1C6034
-#define MUADAT 0x1C6040
-#define MUACMD 0x1C6044
-#define MUASTAT 0x1C6044
-#define MUBDAT 0x1C6048
-#define MUBCMD 0x1C604C
-#define MUBSTAT 0x1C604C
-#define UARTCMA 0x1C6050
-#define UARTCMB 0x1C6054
-#define UARTIP 0x1C6058
-#define UARTIE 0x1C605C
-#define PLLCTL 0x1C6060
-#define PLLDCD 0x1C6064
-#define GCTL 0x1C6070
-#define ID0 0x1C6080
-#define ID1 0x1C6084
-#define ID2 0x1C6088
-#define ID3 0x1C608C
-#define SDRCTL 0x1C7000
-
-
-#define I2SA_L 0x0L
-#define I2SA_R 0x1L
-#define I2SB_L 0x8L
-#define I2SB_R 0x9L
-#define I2SC_L 0x10L
-#define I2SC_R 0x11L
-#define I2SD_L 0x18L
-#define I2SD_R 0x19L
-
-#endif /* CT20K1REG_H */
-
-
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ct20k2reg.h b/ANDROID_3.4.5/sound/pci/ctxfi/ct20k2reg.h
deleted file mode 100644
index ca501ba0..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/ct20k2reg.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- */
-
-#ifndef _20K2REGISTERS_H_
-#define _20K2REGISTERS_H_
-
-
-/* Timer Registers */
-#define WC 0x1b7000
-#define TIMR 0x1b7004
-# define TIMR_IE (1<<15)
-# define TIMR_IP (1<<14)
-#define GIP 0x1b7010
-#define GIE 0x1b7014
-
-/* I2C Registers */
-#define I2C_IF_ADDRESS 0x1B9000
-#define I2C_IF_WDATA 0x1B9004
-#define I2C_IF_RDATA 0x1B9008
-#define I2C_IF_STATUS 0x1B900C
-#define I2C_IF_WLOCK 0x1B9010
-
-/* Global Control Registers */
-#define GLOBAL_CNTL_GCTL 0x1B7090
-
-/* PLL Registers */
-#define PLL_CTL 0x1B7080
-#define PLL_STAT 0x1B7084
-#define PLL_ENB 0x1B7088
-
-/* SRC Registers */
-#define SRC_CTL 0x1A0000 /* 0x1A0000 + (256 * Chn) */
-#define SRC_CCR 0x1A0004 /* 0x1A0004 + (256 * Chn) */
-#define SRC_IMAP 0x1A0008 /* 0x1A0008 + (256 * Chn) */
-#define SRC_CA 0x1A0010 /* 0x1A0010 + (256 * Chn) */
-#define SRC_CF 0x1A0014 /* 0x1A0014 + (256 * Chn) */
-#define SRC_SA 0x1A0018 /* 0x1A0018 + (256 * Chn) */
-#define SRC_LA 0x1A001C /* 0x1A001C + (256 * Chn) */
-#define SRC_CTLSWR 0x1A0020 /* 0x1A0020 + (256 * Chn) */
-#define SRC_CD 0x1A0080 /* 0x1A0080 + (256 * Chn) + (4 * Regn) */
-#define SRC_MCTL 0x1A012C
-#define SRC_IP 0x1A102C /* 0x1A102C + (256 * Regn) */
-#define SRC_ENB 0x1A282C /* 0x1A282C + (256 * Regn) */
-#define SRC_ENBSTAT 0x1A202C
-#define SRC_ENBSA 0x1A232C
-#define SRC_DN0Z 0x1A0030
-#define SRC_DN1Z 0x1A0040
-#define SRC_UPZ 0x1A0060
-
-/* GPIO Registers */
-#define GPIO_DATA 0x1B7020
-#define GPIO_CTRL 0x1B7024
-#define GPIO_EXT_DATA 0x1B70A0
-
-/* Virtual memory registers */
-#define VMEM_PTPAL 0x1C6300 /* 0x1C6300 + (16 * Chn) */
-#define VMEM_PTPAH 0x1C6304 /* 0x1C6304 + (16 * Chn) */
-#define VMEM_CTL 0x1C7000
-
-/* Transport Registers */
-#define TRANSPORT_ENB 0x1B6000
-#define TRANSPORT_CTL 0x1B6004
-#define TRANSPORT_INT 0x1B6008
-
-/* Audio IO */
-#define AUDIO_IO_AIM 0x1B5000 /* 0x1B5000 + (0x04 * Chn) */
-#define AUDIO_IO_TX_CTL 0x1B5400 /* 0x1B5400 + (0x40 * Chn) */
-#define AUDIO_IO_TX_CSTAT_L 0x1B5408 /* 0x1B5408 + (0x40 * Chn) */
-#define AUDIO_IO_TX_CSTAT_H 0x1B540C /* 0x1B540C + (0x40 * Chn) */
-#define AUDIO_IO_RX_CTL 0x1B5410 /* 0x1B5410 + (0x40 * Chn) */
-#define AUDIO_IO_RX_SRT_CTL 0x1B5420 /* 0x1B5420 + (0x40 * Chn) */
-#define AUDIO_IO_MCLK 0x1B5600
-#define AUDIO_IO_TX_BLRCLK 0x1B5604
-#define AUDIO_IO_RX_BLRCLK 0x1B5608
-
-/* Mixer */
-#define MIXER_AMOPLO 0x130000 /* 0x130000 + (8 * Chn) [4095 : 0] */
-#define MIXER_AMOPHI 0x130004 /* 0x130004 + (8 * Chn) [4095 : 0] */
-#define MIXER_PRING_LO_HI 0x188000 /* 0x188000 + (4 * Chn) [4095 : 0] */
-#define MIXER_PMOPLO 0x138000 /* 0x138000 + (8 * Chn) [4095 : 0] */
-#define MIXER_PMOPHI 0x138004 /* 0x138004 + (8 * Chn) [4095 : 0] */
-#define MIXER_AR_ENABLE 0x19000C
-
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctamixer.c b/ANDROID_3.4.5/sound/pci/ctxfi/ctamixer.c
deleted file mode 100644
index fee35cfc..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/ctamixer.c
+++ /dev/null
@@ -1,486 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File ctamixer.c
- *
- * @Brief
- * This file contains the implementation of the Audio Mixer
- * resource management object.
- *
- * @Author Liu Chun
- * @Date May 21 2008
- *
- */
-
-#include "ctamixer.h"
-#include "cthardware.h"
-#include <linux/slab.h>
-
-#define AMIXER_RESOURCE_NUM 256
-#define SUM_RESOURCE_NUM 256
-
-#define AMIXER_Y_IMMEDIATE 1
-
-#define BLANK_SLOT 4094
-
-static int amixer_master(struct rsc *rsc)
-{
- rsc->conj = 0;
- return rsc->idx = container_of(rsc, struct amixer, rsc)->idx[0];
-}
-
-static int amixer_next_conj(struct rsc *rsc)
-{
- rsc->conj++;
- return container_of(rsc, struct amixer, rsc)->idx[rsc->conj];
-}
-
-static int amixer_index(const struct rsc *rsc)
-{
- return container_of(rsc, struct amixer, rsc)->idx[rsc->conj];
-}
-
-static int amixer_output_slot(const struct rsc *rsc)
-{
- return (amixer_index(rsc) << 4) + 0x4;
-}
-
-static struct rsc_ops amixer_basic_rsc_ops = {
- .master = amixer_master,
- .next_conj = amixer_next_conj,
- .index = amixer_index,
- .output_slot = amixer_output_slot,
-};
-
-static int amixer_set_input(struct amixer *amixer, struct rsc *rsc)
-{
- struct hw *hw;
-
- hw = amixer->rsc.hw;
- hw->amixer_set_mode(amixer->rsc.ctrl_blk, AMIXER_Y_IMMEDIATE);
- amixer->input = rsc;
- if (!rsc)
- hw->amixer_set_x(amixer->rsc.ctrl_blk, BLANK_SLOT);
- else
- hw->amixer_set_x(amixer->rsc.ctrl_blk,
- rsc->ops->output_slot(rsc));
-
- return 0;
-}
-
-/* y is a 14-bit immediate constant */
-static int amixer_set_y(struct amixer *amixer, unsigned int y)
-{
- struct hw *hw;
-
- hw = amixer->rsc.hw;
- hw->amixer_set_y(amixer->rsc.ctrl_blk, y);
-
- return 0;
-}
-
-static int amixer_set_invalid_squash(struct amixer *amixer, unsigned int iv)
-{
- struct hw *hw;
-
- hw = amixer->rsc.hw;
- hw->amixer_set_iv(amixer->rsc.ctrl_blk, iv);
-
- return 0;
-}
-
-static int amixer_set_sum(struct amixer *amixer, struct sum *sum)
-{
- struct hw *hw;
-
- hw = amixer->rsc.hw;
- amixer->sum = sum;
- if (!sum) {
- hw->amixer_set_se(amixer->rsc.ctrl_blk, 0);
- } else {
- hw->amixer_set_se(amixer->rsc.ctrl_blk, 1);
- hw->amixer_set_sadr(amixer->rsc.ctrl_blk,
- sum->rsc.ops->index(&sum->rsc));
- }
-
- return 0;
-}
-
-static int amixer_commit_write(struct amixer *amixer)
-{
- struct hw *hw;
- unsigned int index;
- int i;
- struct rsc *input;
- struct sum *sum;
-
- hw = amixer->rsc.hw;
- input = amixer->input;
- sum = amixer->sum;
-
- /* Program master and conjugate resources */
- amixer->rsc.ops->master(&amixer->rsc);
- if (input)
- input->ops->master(input);
-
- if (sum)
- sum->rsc.ops->master(&sum->rsc);
-
- for (i = 0; i < amixer->rsc.msr; i++) {
- hw->amixer_set_dirty_all(amixer->rsc.ctrl_blk);
- if (input) {
- hw->amixer_set_x(amixer->rsc.ctrl_blk,
- input->ops->output_slot(input));
- input->ops->next_conj(input);
- }
- if (sum) {
- hw->amixer_set_sadr(amixer->rsc.ctrl_blk,
- sum->rsc.ops->index(&sum->rsc));
- sum->rsc.ops->next_conj(&sum->rsc);
- }
- index = amixer->rsc.ops->output_slot(&amixer->rsc);
- hw->amixer_commit_write(hw, index, amixer->rsc.ctrl_blk);
- amixer->rsc.ops->next_conj(&amixer->rsc);
- }
- amixer->rsc.ops->master(&amixer->rsc);
- if (input)
- input->ops->master(input);
-
- if (sum)
- sum->rsc.ops->master(&sum->rsc);
-
- return 0;
-}
-
-static int amixer_commit_raw_write(struct amixer *amixer)
-{
- struct hw *hw;
- unsigned int index;
-
- hw = amixer->rsc.hw;
- index = amixer->rsc.ops->output_slot(&amixer->rsc);
- hw->amixer_commit_write(hw, index, amixer->rsc.ctrl_blk);
-
- return 0;
-}
-
-static int amixer_get_y(struct amixer *amixer)
-{
- struct hw *hw;
-
- hw = amixer->rsc.hw;
- return hw->amixer_get_y(amixer->rsc.ctrl_blk);
-}
-
-static int amixer_setup(struct amixer *amixer, struct rsc *input,
- unsigned int scale, struct sum *sum)
-{
- amixer_set_input(amixer, input);
- amixer_set_y(amixer, scale);
- amixer_set_sum(amixer, sum);
- amixer_commit_write(amixer);
- return 0;
-}
-
-static struct amixer_rsc_ops amixer_ops = {
- .set_input = amixer_set_input,
- .set_invalid_squash = amixer_set_invalid_squash,
- .set_scale = amixer_set_y,
- .set_sum = amixer_set_sum,
- .commit_write = amixer_commit_write,
- .commit_raw_write = amixer_commit_raw_write,
- .setup = amixer_setup,
- .get_scale = amixer_get_y,
-};
-
-static int amixer_rsc_init(struct amixer *amixer,
- const struct amixer_desc *desc,
- struct amixer_mgr *mgr)
-{
- int err;
-
- err = rsc_init(&amixer->rsc, amixer->idx[0],
- AMIXER, desc->msr, mgr->mgr.hw);
- if (err)
- return err;
-
- /* Set amixer specific operations */
- amixer->rsc.ops = &amixer_basic_rsc_ops;
- amixer->ops = &amixer_ops;
- amixer->input = NULL;
- amixer->sum = NULL;
-
- amixer_setup(amixer, NULL, 0, NULL);
-
- return 0;
-}
-
-static int amixer_rsc_uninit(struct amixer *amixer)
-{
- amixer_setup(amixer, NULL, 0, NULL);
- rsc_uninit(&amixer->rsc);
- amixer->ops = NULL;
- amixer->input = NULL;
- amixer->sum = NULL;
- return 0;
-}
-
-static int get_amixer_rsc(struct amixer_mgr *mgr,
- const struct amixer_desc *desc,
- struct amixer **ramixer)
-{
- int err, i;
- unsigned int idx;
- struct amixer *amixer;
- unsigned long flags;
-
- *ramixer = NULL;
-
- /* Allocate mem for amixer resource */
- amixer = kzalloc(sizeof(*amixer), GFP_KERNEL);
- if (!amixer)
- return -ENOMEM;
-
- /* Check whether there are sufficient
- * amixer resources to meet request. */
- err = 0;
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- for (i = 0; i < desc->msr; i++) {
- err = mgr_get_resource(&mgr->mgr, 1, &idx);
- if (err)
- break;
-
- amixer->idx[i] = idx;
- }
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
- if (err) {
- printk(KERN_ERR "ctxfi: Can't meet AMIXER resource request!\n");
- goto error;
- }
-
- err = amixer_rsc_init(amixer, desc, mgr);
- if (err)
- goto error;
-
- *ramixer = amixer;
-
- return 0;
-
-error:
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- for (i--; i >= 0; i--)
- mgr_put_resource(&mgr->mgr, 1, amixer->idx[i]);
-
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
- kfree(amixer);
- return err;
-}
-
-static int put_amixer_rsc(struct amixer_mgr *mgr, struct amixer *amixer)
-{
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- for (i = 0; i < amixer->rsc.msr; i++)
- mgr_put_resource(&mgr->mgr, 1, amixer->idx[i]);
-
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
- amixer_rsc_uninit(amixer);
- kfree(amixer);
-
- return 0;
-}
-
-int amixer_mgr_create(void *hw, struct amixer_mgr **ramixer_mgr)
-{
- int err;
- struct amixer_mgr *amixer_mgr;
-
- *ramixer_mgr = NULL;
- amixer_mgr = kzalloc(sizeof(*amixer_mgr), GFP_KERNEL);
- if (!amixer_mgr)
- return -ENOMEM;
-
- err = rsc_mgr_init(&amixer_mgr->mgr, AMIXER, AMIXER_RESOURCE_NUM, hw);
- if (err)
- goto error;
-
- spin_lock_init(&amixer_mgr->mgr_lock);
-
- amixer_mgr->get_amixer = get_amixer_rsc;
- amixer_mgr->put_amixer = put_amixer_rsc;
-
- *ramixer_mgr = amixer_mgr;
-
- return 0;
-
-error:
- kfree(amixer_mgr);
- return err;
-}
-
-int amixer_mgr_destroy(struct amixer_mgr *amixer_mgr)
-{
- rsc_mgr_uninit(&amixer_mgr->mgr);
- kfree(amixer_mgr);
- return 0;
-}
-
-/* SUM resource management */
-
-static int sum_master(struct rsc *rsc)
-{
- rsc->conj = 0;
- return rsc->idx = container_of(rsc, struct sum, rsc)->idx[0];
-}
-
-static int sum_next_conj(struct rsc *rsc)
-{
- rsc->conj++;
- return container_of(rsc, struct sum, rsc)->idx[rsc->conj];
-}
-
-static int sum_index(const struct rsc *rsc)
-{
- return container_of(rsc, struct sum, rsc)->idx[rsc->conj];
-}
-
-static int sum_output_slot(const struct rsc *rsc)
-{
- return (sum_index(rsc) << 4) + 0xc;
-}
-
-static struct rsc_ops sum_basic_rsc_ops = {
- .master = sum_master,
- .next_conj = sum_next_conj,
- .index = sum_index,
- .output_slot = sum_output_slot,
-};
-
-static int sum_rsc_init(struct sum *sum,
- const struct sum_desc *desc,
- struct sum_mgr *mgr)
-{
- int err;
-
- err = rsc_init(&sum->rsc, sum->idx[0], SUM, desc->msr, mgr->mgr.hw);
- if (err)
- return err;
-
- sum->rsc.ops = &sum_basic_rsc_ops;
-
- return 0;
-}
-
-static int sum_rsc_uninit(struct sum *sum)
-{
- rsc_uninit(&sum->rsc);
- return 0;
-}
-
-static int get_sum_rsc(struct sum_mgr *mgr,
- const struct sum_desc *desc,
- struct sum **rsum)
-{
- int err, i;
- unsigned int idx;
- struct sum *sum;
- unsigned long flags;
-
- *rsum = NULL;
-
- /* Allocate mem for sum resource */
- sum = kzalloc(sizeof(*sum), GFP_KERNEL);
- if (!sum)
- return -ENOMEM;
-
- /* Check whether there are sufficient sum resources to meet request. */
- err = 0;
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- for (i = 0; i < desc->msr; i++) {
- err = mgr_get_resource(&mgr->mgr, 1, &idx);
- if (err)
- break;
-
- sum->idx[i] = idx;
- }
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
- if (err) {
- printk(KERN_ERR "ctxfi: Can't meet SUM resource request!\n");
- goto error;
- }
-
- err = sum_rsc_init(sum, desc, mgr);
- if (err)
- goto error;
-
- *rsum = sum;
-
- return 0;
-
-error:
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- for (i--; i >= 0; i--)
- mgr_put_resource(&mgr->mgr, 1, sum->idx[i]);
-
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
- kfree(sum);
- return err;
-}
-
-static int put_sum_rsc(struct sum_mgr *mgr, struct sum *sum)
-{
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- for (i = 0; i < sum->rsc.msr; i++)
- mgr_put_resource(&mgr->mgr, 1, sum->idx[i]);
-
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
- sum_rsc_uninit(sum);
- kfree(sum);
-
- return 0;
-}
-
-int sum_mgr_create(void *hw, struct sum_mgr **rsum_mgr)
-{
- int err;
- struct sum_mgr *sum_mgr;
-
- *rsum_mgr = NULL;
- sum_mgr = kzalloc(sizeof(*sum_mgr), GFP_KERNEL);
- if (!sum_mgr)
- return -ENOMEM;
-
- err = rsc_mgr_init(&sum_mgr->mgr, SUM, SUM_RESOURCE_NUM, hw);
- if (err)
- goto error;
-
- spin_lock_init(&sum_mgr->mgr_lock);
-
- sum_mgr->get_sum = get_sum_rsc;
- sum_mgr->put_sum = put_sum_rsc;
-
- *rsum_mgr = sum_mgr;
-
- return 0;
-
-error:
- kfree(sum_mgr);
- return err;
-}
-
-int sum_mgr_destroy(struct sum_mgr *sum_mgr)
-{
- rsc_mgr_uninit(&sum_mgr->mgr);
- kfree(sum_mgr);
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctamixer.h b/ANDROID_3.4.5/sound/pci/ctxfi/ctamixer.h
deleted file mode 100644
index cc49e5ab..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/ctamixer.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File ctamixer.h
- *
- * @Brief
- * This file contains the definition of the Audio Mixer
- * resource management object.
- *
- * @Author Liu Chun
- * @Date May 21 2008
- *
- */
-
-#ifndef CTAMIXER_H
-#define CTAMIXER_H
-
-#include "ctresource.h"
-#include <linux/spinlock.h>
-
-/* Define the descriptor of a summation node resource */
-struct sum {
- struct rsc rsc; /* Basic resource info */
- unsigned char idx[8];
-};
-
-/* Define sum resource request description info */
-struct sum_desc {
- unsigned int msr;
-};
-
-struct sum_mgr {
- struct rsc_mgr mgr; /* Basic resource manager info */
- spinlock_t mgr_lock;
-
- /* request one sum resource */
- int (*get_sum)(struct sum_mgr *mgr,
- const struct sum_desc *desc, struct sum **rsum);
- /* return one sum resource */
- int (*put_sum)(struct sum_mgr *mgr, struct sum *sum);
-};
-
-/* Constructor and destructor of daio resource manager */
-int sum_mgr_create(void *hw, struct sum_mgr **rsum_mgr);
-int sum_mgr_destroy(struct sum_mgr *sum_mgr);
-
-/* Define the descriptor of a amixer resource */
-struct amixer_rsc_ops;
-
-struct amixer {
- struct rsc rsc; /* Basic resource info */
- unsigned char idx[8];
- struct rsc *input; /* pointer to a resource acting as source */
- struct sum *sum; /* Put amixer output to this summation node */
- struct amixer_rsc_ops *ops; /* AMixer specific operations */
-};
-
-struct amixer_rsc_ops {
- int (*set_input)(struct amixer *amixer, struct rsc *rsc);
- int (*set_scale)(struct amixer *amixer, unsigned int scale);
- int (*set_invalid_squash)(struct amixer *amixer, unsigned int iv);
- int (*set_sum)(struct amixer *amixer, struct sum *sum);
- int (*commit_write)(struct amixer *amixer);
- /* Only for interleaved recording */
- int (*commit_raw_write)(struct amixer *amixer);
- int (*setup)(struct amixer *amixer, struct rsc *input,
- unsigned int scale, struct sum *sum);
- int (*get_scale)(struct amixer *amixer);
-};
-
-/* Define amixer resource request description info */
-struct amixer_desc {
- unsigned int msr;
-};
-
-struct amixer_mgr {
- struct rsc_mgr mgr; /* Basic resource manager info */
- spinlock_t mgr_lock;
-
- /* request one amixer resource */
- int (*get_amixer)(struct amixer_mgr *mgr,
- const struct amixer_desc *desc,
- struct amixer **ramixer);
- /* return one amixer resource */
- int (*put_amixer)(struct amixer_mgr *mgr, struct amixer *amixer);
-};
-
-/* Constructor and destructor of amixer resource manager */
-int amixer_mgr_create(void *hw, struct amixer_mgr **ramixer_mgr);
-int amixer_mgr_destroy(struct amixer_mgr *amixer_mgr);
-
-#endif /* CTAMIXER_H */
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctatc.c b/ANDROID_3.4.5/sound/pci/ctxfi/ctatc.c
deleted file mode 100644
index d8a44235..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/ctatc.c
+++ /dev/null
@@ -1,1744 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File ctatc.c
- *
- * @Brief
- * This file contains the implementation of the device resource management
- * object.
- *
- * @Author Liu Chun
- * @Date Mar 28 2008
- */
-
-#include "ctatc.h"
-#include "ctpcm.h"
-#include "ctmixer.h"
-#include "ctsrc.h"
-#include "ctamixer.h"
-#include "ctdaio.h"
-#include "cttimer.h"
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <sound/pcm.h>
-#include <sound/control.h>
-#include <sound/asoundef.h>
-
-#define MONO_SUM_SCALE 0x19a8 /* 2^(-0.5) in 14-bit floating format */
-#define MAX_MULTI_CHN 8
-
-#define IEC958_DEFAULT_CON ((IEC958_AES0_NONAUDIO \
- | IEC958_AES0_CON_NOT_COPYRIGHT) \
- | ((IEC958_AES1_CON_MIXER \
- | IEC958_AES1_CON_ORIGINAL) << 8) \
- | (0x10 << 16) \
- | ((IEC958_AES3_CON_FS_48000) << 24))
-
-static struct snd_pci_quirk __devinitdata subsys_20k1_list[] = {
- SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0022, "SB055x", CTSB055X),
- SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x002f, "SB055x", CTSB055X),
- SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0029, "SB073x", CTSB073X),
- SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0031, "SB073x", CTSB073X),
- SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0xf000, 0x6000,
- "UAA", CTUAA),
- { } /* terminator */
-};
-
-static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = {
- SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB0760,
- "SB0760", CTSB0760),
- SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB1270,
- "SB1270", CTSB1270),
- SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08801,
- "SB0880", CTSB0880),
- SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08802,
- "SB0880", CTSB0880),
- SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08803,
- "SB0880", CTSB0880),
- SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0xf000,
- PCI_SUBDEVICE_ID_CREATIVE_HENDRIX, "HENDRIX",
- CTHENDRIX),
- { } /* terminator */
-};
-
-static const char *ct_subsys_name[NUM_CTCARDS] = {
- /* 20k1 models */
- [CTSB055X] = "SB055x",
- [CTSB073X] = "SB073x",
- [CTUAA] = "UAA",
- [CT20K1_UNKNOWN] = "Unknown",
- /* 20k2 models */
- [CTSB0760] = "SB076x",
- [CTHENDRIX] = "Hendrix",
- [CTSB0880] = "SB0880",
- [CTSB1270] = "SB1270",
- [CT20K2_UNKNOWN] = "Unknown",
-};
-
-static struct {
- int (*create)(struct ct_atc *atc,
- enum CTALSADEVS device, const char *device_name);
- int (*destroy)(void *alsa_dev);
- const char *public_name;
-} alsa_dev_funcs[NUM_CTALSADEVS] = {
- [FRONT] = { .create = ct_alsa_pcm_create,
- .destroy = NULL,
- .public_name = "Front/WaveIn"},
- [SURROUND] = { .create = ct_alsa_pcm_create,
- .destroy = NULL,
- .public_name = "Surround"},
- [CLFE] = { .create = ct_alsa_pcm_create,
- .destroy = NULL,
- .public_name = "Center/LFE"},
- [SIDE] = { .create = ct_alsa_pcm_create,
- .destroy = NULL,
- .public_name = "Side"},
- [IEC958] = { .create = ct_alsa_pcm_create,
- .destroy = NULL,
- .public_name = "IEC958 Non-audio"},
-
- [MIXER] = { .create = ct_alsa_mix_create,
- .destroy = NULL,
- .public_name = "Mixer"}
-};
-
-typedef int (*create_t)(void *, void **);
-typedef int (*destroy_t)(void *);
-
-static struct {
- int (*create)(void *hw, void **rmgr);
- int (*destroy)(void *mgr);
-} rsc_mgr_funcs[NUM_RSCTYP] = {
- [SRC] = { .create = (create_t)src_mgr_create,
- .destroy = (destroy_t)src_mgr_destroy },
- [SRCIMP] = { .create = (create_t)srcimp_mgr_create,
- .destroy = (destroy_t)srcimp_mgr_destroy },
- [AMIXER] = { .create = (create_t)amixer_mgr_create,
- .destroy = (destroy_t)amixer_mgr_destroy },
- [SUM] = { .create = (create_t)sum_mgr_create,
- .destroy = (destroy_t)sum_mgr_destroy },
- [DAIO] = { .create = (create_t)daio_mgr_create,
- .destroy = (destroy_t)daio_mgr_destroy }
-};
-
-static int
-atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm);
-
-/* *
- * Only mono and interleaved modes are supported now.
- * Always allocates a contiguous channel block.
- * */
-
-static int ct_map_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
-{
- struct snd_pcm_runtime *runtime;
- struct ct_vm *vm;
-
- if (!apcm->substream)
- return 0;
-
- runtime = apcm->substream->runtime;
- vm = atc->vm;
-
- apcm->vm_block = vm->map(vm, apcm->substream, runtime->dma_bytes);
-
- if (!apcm->vm_block)
- return -ENOENT;
-
- return 0;
-}
-
-static void ct_unmap_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
-{
- struct ct_vm *vm;
-
- if (!apcm->vm_block)
- return;
-
- vm = atc->vm;
-
- vm->unmap(vm, apcm->vm_block);
-
- apcm->vm_block = NULL;
-}
-
-static unsigned long atc_get_ptp_phys(struct ct_atc *atc, int index)
-{
- return atc->vm->get_ptp_phys(atc->vm, index);
-}
-
-static unsigned int convert_format(snd_pcm_format_t snd_format)
-{
- switch (snd_format) {
- case SNDRV_PCM_FORMAT_U8:
- return SRC_SF_U8;
- case SNDRV_PCM_FORMAT_S16_LE:
- return SRC_SF_S16;
- case SNDRV_PCM_FORMAT_S24_3LE:
- return SRC_SF_S24;
- case SNDRV_PCM_FORMAT_S32_LE:
- return SRC_SF_S32;
- case SNDRV_PCM_FORMAT_FLOAT_LE:
- return SRC_SF_F32;
- default:
- printk(KERN_ERR "ctxfi: not recognized snd format is %d \n",
- snd_format);
- return SRC_SF_S16;
- }
-}
-
-static unsigned int
-atc_get_pitch(unsigned int input_rate, unsigned int output_rate)
-{
- unsigned int pitch;
- int b;
-
- /* get pitch and convert to fixed-point 8.24 format. */
- pitch = (input_rate / output_rate) << 24;
- input_rate %= output_rate;
- input_rate /= 100;
- output_rate /= 100;
- for (b = 31; ((b >= 0) && !(input_rate >> b)); )
- b--;
-
- if (b >= 0) {
- input_rate <<= (31 - b);
- input_rate /= output_rate;
- b = 24 - (31 - b);
- if (b >= 0)
- input_rate <<= b;
- else
- input_rate >>= -b;
-
- pitch |= input_rate;
- }
-
- return pitch;
-}
-
-static int select_rom(unsigned int pitch)
-{
- if (pitch > 0x00428f5c && pitch < 0x01b851ec) {
- /* 0.26 <= pitch <= 1.72 */
- return 1;
- } else if (pitch == 0x01d66666 || pitch == 0x01d66667) {
- /* pitch == 1.8375 */
- return 2;
- } else if (pitch == 0x02000000) {
- /* pitch == 2 */
- return 3;
- } else if (pitch <= 0x08000000) {
- /* 0 <= pitch <= 8 */
- return 0;
- } else {
- return -ENOENT;
- }
-}
-
-static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
-{
- struct src_mgr *src_mgr = atc->rsc_mgrs[SRC];
- struct amixer_mgr *amixer_mgr = atc->rsc_mgrs[AMIXER];
- struct src_desc desc = {0};
- struct amixer_desc mix_dsc = {0};
- struct src *src;
- struct amixer *amixer;
- int err;
- int n_amixer = apcm->substream->runtime->channels, i = 0;
- int device = apcm->substream->pcm->device;
- unsigned int pitch;
-
- /* first release old resources */
- atc_pcm_release_resources(atc, apcm);
-
- /* Get SRC resource */
- desc.multi = apcm->substream->runtime->channels;
- desc.msr = atc->msr;
- desc.mode = MEMRD;
- err = src_mgr->get_src(src_mgr, &desc, (struct src **)&apcm->src);
- if (err)
- goto error1;
-
- pitch = atc_get_pitch(apcm->substream->runtime->rate,
- (atc->rsr * atc->msr));
- src = apcm->src;
- src->ops->set_pitch(src, pitch);
- src->ops->set_rom(src, select_rom(pitch));
- src->ops->set_sf(src, convert_format(apcm->substream->runtime->format));
- src->ops->set_pm(src, (src->ops->next_interleave(src) != NULL));
-
- /* Get AMIXER resource */
- n_amixer = (n_amixer < 2) ? 2 : n_amixer;
- apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL);
- if (!apcm->amixers) {
- err = -ENOMEM;
- goto error1;
- }
- mix_dsc.msr = atc->msr;
- for (i = 0, apcm->n_amixer = 0; i < n_amixer; i++) {
- err = amixer_mgr->get_amixer(amixer_mgr, &mix_dsc,
- (struct amixer **)&apcm->amixers[i]);
- if (err)
- goto error1;
-
- apcm->n_amixer++;
- }
-
- /* Set up device virtual mem map */
- err = ct_map_audio_buffer(atc, apcm);
- if (err < 0)
- goto error1;
-
- /* Connect resources */
- src = apcm->src;
- for (i = 0; i < n_amixer; i++) {
- amixer = apcm->amixers[i];
- mutex_lock(&atc->atc_mutex);
- amixer->ops->setup(amixer, &src->rsc,
- INIT_VOL, atc->pcm[i+device*2]);
- mutex_unlock(&atc->atc_mutex);
- src = src->ops->next_interleave(src);
- if (!src)
- src = apcm->src;
- }
-
- ct_timer_prepare(apcm->timer);
-
- return 0;
-
-error1:
- atc_pcm_release_resources(atc, apcm);
- return err;
-}
-
-static int
-atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm)
-{
- struct src_mgr *src_mgr = atc->rsc_mgrs[SRC];
- struct srcimp_mgr *srcimp_mgr = atc->rsc_mgrs[SRCIMP];
- struct amixer_mgr *amixer_mgr = atc->rsc_mgrs[AMIXER];
- struct sum_mgr *sum_mgr = atc->rsc_mgrs[SUM];
- struct srcimp *srcimp;
- int i;
-
- if (apcm->srcimps) {
- for (i = 0; i < apcm->n_srcimp; i++) {
- srcimp = apcm->srcimps[i];
- srcimp->ops->unmap(srcimp);
- srcimp_mgr->put_srcimp(srcimp_mgr, srcimp);
- apcm->srcimps[i] = NULL;
- }
- kfree(apcm->srcimps);
- apcm->srcimps = NULL;
- }
-
- if (apcm->srccs) {
- for (i = 0; i < apcm->n_srcc; i++) {
- src_mgr->put_src(src_mgr, apcm->srccs[i]);
- apcm->srccs[i] = NULL;
- }
- kfree(apcm->srccs);
- apcm->srccs = NULL;
- }
-
- if (apcm->amixers) {
- for (i = 0; i < apcm->n_amixer; i++) {
- amixer_mgr->put_amixer(amixer_mgr, apcm->amixers[i]);
- apcm->amixers[i] = NULL;
- }
- kfree(apcm->amixers);
- apcm->amixers = NULL;
- }
-
- if (apcm->mono) {
- sum_mgr->put_sum(sum_mgr, apcm->mono);
- apcm->mono = NULL;
- }
-
- if (apcm->src) {
- src_mgr->put_src(src_mgr, apcm->src);
- apcm->src = NULL;
- }
-
- if (apcm->vm_block) {
- /* Undo device virtual mem map */
- ct_unmap_audio_buffer(atc, apcm);
- apcm->vm_block = NULL;
- }
-
- return 0;
-}
-
-static int atc_pcm_playback_start(struct ct_atc *atc, struct ct_atc_pcm *apcm)
-{
- unsigned int max_cisz;
- struct src *src = apcm->src;
-
- if (apcm->started)
- return 0;
- apcm->started = 1;
-
- max_cisz = src->multi * src->rsc.msr;
- max_cisz = 0x80 * (max_cisz < 8 ? max_cisz : 8);
-
- src->ops->set_sa(src, apcm->vm_block->addr);
- src->ops->set_la(src, apcm->vm_block->addr + apcm->vm_block->size);
- src->ops->set_ca(src, apcm->vm_block->addr + max_cisz);
- src->ops->set_cisz(src, max_cisz);
-
- src->ops->set_bm(src, 1);
- src->ops->set_state(src, SRC_STATE_INIT);
- src->ops->commit_write(src);
-
- ct_timer_start(apcm->timer);
- return 0;
-}
-
-static int atc_pcm_stop(struct ct_atc *atc, struct ct_atc_pcm *apcm)
-{
- struct src *src;
- int i;
-
- ct_timer_stop(apcm->timer);
-
- src = apcm->src;
- src->ops->set_bm(src, 0);
- src->ops->set_state(src, SRC_STATE_OFF);
- src->ops->commit_write(src);
-
- if (apcm->srccs) {
- for (i = 0; i < apcm->n_srcc; i++) {
- src = apcm->srccs[i];
- src->ops->set_bm(src, 0);
- src->ops->set_state(src, SRC_STATE_OFF);
- src->ops->commit_write(src);
- }
- }
-
- apcm->started = 0;
-
- return 0;
-}
-
-static int
-atc_pcm_playback_position(struct ct_atc *atc, struct ct_atc_pcm *apcm)
-{
- struct src *src = apcm->src;
- u32 size, max_cisz;
- int position;
-
- if (!src)
- return 0;
- position = src->ops->get_ca(src);
-
- size = apcm->vm_block->size;
- max_cisz = src->multi * src->rsc.msr;
- max_cisz = 128 * (max_cisz < 8 ? max_cisz : 8);
-
- return (position + size - max_cisz - apcm->vm_block->addr) % size;
-}
-
-struct src_node_conf_t {
- unsigned int pitch;
- unsigned int msr:8;
- unsigned int mix_msr:8;
- unsigned int imp_msr:8;
- unsigned int vo:1;
-};
-
-static void setup_src_node_conf(struct ct_atc *atc, struct ct_atc_pcm *apcm,
- struct src_node_conf_t *conf, int *n_srcc)
-{
- unsigned int pitch;
-
- /* get pitch and convert to fixed-point 8.24 format. */
- pitch = atc_get_pitch((atc->rsr * atc->msr),
- apcm->substream->runtime->rate);
- *n_srcc = 0;
-
- if (1 == atc->msr) { /* FIXME: do we really need SRC here if pitch==1 */
- *n_srcc = apcm->substream->runtime->channels;
- conf[0].pitch = pitch;
- conf[0].mix_msr = conf[0].imp_msr = conf[0].msr = 1;
- conf[0].vo = 1;
- } else if (2 <= atc->msr) {
- if (0x8000000 < pitch) {
- /* Need two-stage SRCs, SRCIMPs and
- * AMIXERs for converting format */
- conf[0].pitch = (atc->msr << 24);
- conf[0].msr = conf[0].mix_msr = 1;
- conf[0].imp_msr = atc->msr;
- conf[0].vo = 0;
- conf[1].pitch = atc_get_pitch(atc->rsr,
- apcm->substream->runtime->rate);
- conf[1].msr = conf[1].mix_msr = conf[1].imp_msr = 1;
- conf[1].vo = 1;
- *n_srcc = apcm->substream->runtime->channels * 2;
- } else if (0x1000000 < pitch) {
- /* Need one-stage SRCs, SRCIMPs and
- * AMIXERs for converting format */
- conf[0].pitch = pitch;
- conf[0].msr = conf[0].mix_msr
- = conf[0].imp_msr = atc->msr;
- conf[0].vo = 1;
- *n_srcc = apcm->substream->runtime->channels;
- }
- }
-}
-
-static int
-atc_pcm_capture_get_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm)
-{
- struct src_mgr *src_mgr = atc->rsc_mgrs[SRC];
- struct srcimp_mgr *srcimp_mgr = atc->rsc_mgrs[SRCIMP];
- struct amixer_mgr *amixer_mgr = atc->rsc_mgrs[AMIXER];
- struct sum_mgr *sum_mgr = atc->rsc_mgrs[SUM];
- struct src_desc src_dsc = {0};
- struct src *src;
- struct srcimp_desc srcimp_dsc = {0};
- struct srcimp *srcimp;
- struct amixer_desc mix_dsc = {0};
- struct sum_desc sum_dsc = {0};
- unsigned int pitch;
- int multi, err, i;
- int n_srcimp, n_amixer, n_srcc, n_sum;
- struct src_node_conf_t src_node_conf[2] = {{0} };
-
- /* first release old resources */
- atc_pcm_release_resources(atc, apcm);
-
- /* The numbers of converting SRCs and SRCIMPs should be determined
- * by pitch value. */
-
- multi = apcm->substream->runtime->channels;
-
- /* get pitch and convert to fixed-point 8.24 format. */
- pitch = atc_get_pitch((atc->rsr * atc->msr),
- apcm->substream->runtime->rate);
-
- setup_src_node_conf(atc, apcm, src_node_conf, &n_srcc);
- n_sum = (1 == multi) ? 1 : 0;
- n_amixer = n_sum * 2 + n_srcc;
- n_srcimp = n_srcc;
- if ((multi > 1) && (0x8000000 >= pitch)) {
- /* Need extra AMIXERs and SRCIMPs for special treatment
- * of interleaved recording of conjugate channels */
- n_amixer += multi * atc->msr;
- n_srcimp += multi * atc->msr;
- } else {
- n_srcimp += multi;
- }
-
- if (n_srcc) {
- apcm->srccs = kzalloc(sizeof(void *)*n_srcc, GFP_KERNEL);
- if (!apcm->srccs)
- return -ENOMEM;
- }
- if (n_amixer) {
- apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL);
- if (!apcm->amixers) {
- err = -ENOMEM;
- goto error1;
- }
- }
- apcm->srcimps = kzalloc(sizeof(void *)*n_srcimp, GFP_KERNEL);
- if (!apcm->srcimps) {
- err = -ENOMEM;
- goto error1;
- }
-
- /* Allocate SRCs for sample rate conversion if needed */
- src_dsc.multi = 1;
- src_dsc.mode = ARCRW;
- for (i = 0, apcm->n_srcc = 0; i < n_srcc; i++) {
- src_dsc.msr = src_node_conf[i/multi].msr;
- err = src_mgr->get_src(src_mgr, &src_dsc,
- (struct src **)&apcm->srccs[i]);
- if (err)
- goto error1;
-
- src = apcm->srccs[i];
- pitch = src_node_conf[i/multi].pitch;
- src->ops->set_pitch(src, pitch);
- src->ops->set_rom(src, select_rom(pitch));
- src->ops->set_vo(src, src_node_conf[i/multi].vo);
-
- apcm->n_srcc++;
- }
-
- /* Allocate AMIXERs for routing SRCs of conversion if needed */
- for (i = 0, apcm->n_amixer = 0; i < n_amixer; i++) {
- if (i < (n_sum*2))
- mix_dsc.msr = atc->msr;
- else if (i < (n_sum*2+n_srcc))
- mix_dsc.msr = src_node_conf[(i-n_sum*2)/multi].mix_msr;
- else
- mix_dsc.msr = 1;
-
- err = amixer_mgr->get_amixer(amixer_mgr, &mix_dsc,
- (struct amixer **)&apcm->amixers[i]);
- if (err)
- goto error1;
-
- apcm->n_amixer++;
- }
-
- /* Allocate a SUM resource to mix all input channels together */
- sum_dsc.msr = atc->msr;
- err = sum_mgr->get_sum(sum_mgr, &sum_dsc, (struct sum **)&apcm->mono);
- if (err)
- goto error1;
-
- pitch = atc_get_pitch((atc->rsr * atc->msr),
- apcm->substream->runtime->rate);
- /* Allocate SRCIMP resources */
- for (i = 0, apcm->n_srcimp = 0; i < n_srcimp; i++) {
- if (i < (n_srcc))
- srcimp_dsc.msr = src_node_conf[i/multi].imp_msr;
- else if (1 == multi)
- srcimp_dsc.msr = (pitch <= 0x8000000) ? atc->msr : 1;
- else
- srcimp_dsc.msr = 1;
-
- err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc, &srcimp);
- if (err)
- goto error1;
-
- apcm->srcimps[i] = srcimp;
- apcm->n_srcimp++;
- }
-
- /* Allocate a SRC for writing data to host memory */
- src_dsc.multi = apcm->substream->runtime->channels;
- src_dsc.msr = 1;
- src_dsc.mode = MEMWR;
- err = src_mgr->get_src(src_mgr, &src_dsc, (struct src **)&apcm->src);
- if (err)
- goto error1;
-
- src = apcm->src;
- src->ops->set_pitch(src, pitch);
-
- /* Set up device virtual mem map */
- err = ct_map_audio_buffer(atc, apcm);
- if (err < 0)
- goto error1;
-
- return 0;
-
-error1:
- atc_pcm_release_resources(atc, apcm);
- return err;
-}
-
-static int atc_pcm_capture_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
-{
- struct src *src;
- struct amixer *amixer;
- struct srcimp *srcimp;
- struct ct_mixer *mixer = atc->mixer;
- struct sum *mono;
- struct rsc *out_ports[8] = {NULL};
- int err, i, j, n_sum, multi;
- unsigned int pitch;
- int mix_base = 0, imp_base = 0;
-
- atc_pcm_release_resources(atc, apcm);
-
- /* Get needed resources. */
- err = atc_pcm_capture_get_resources(atc, apcm);
- if (err)
- return err;
-
- /* Connect resources */
- mixer->get_output_ports(mixer, MIX_PCMO_FRONT,
- &out_ports[0], &out_ports[1]);
-
- multi = apcm->substream->runtime->channels;
- if (1 == multi) {
- mono = apcm->mono;
- for (i = 0; i < 2; i++) {
- amixer = apcm->amixers[i];
- amixer->ops->setup(amixer, out_ports[i],
- MONO_SUM_SCALE, mono);
- }
- out_ports[0] = &mono->rsc;
- n_sum = 1;
- mix_base = n_sum * 2;
- }
-
- for (i = 0; i < apcm->n_srcc; i++) {
- src = apcm->srccs[i];
- srcimp = apcm->srcimps[imp_base+i];
- amixer = apcm->amixers[mix_base+i];
- srcimp->ops->map(srcimp, src, out_ports[i%multi]);
- amixer->ops->setup(amixer, &src->rsc, INIT_VOL, NULL);
- out_ports[i%multi] = &amixer->rsc;
- }
-
- pitch = atc_get_pitch((atc->rsr * atc->msr),
- apcm->substream->runtime->rate);
-
- if ((multi > 1) && (pitch <= 0x8000000)) {
- /* Special connection for interleaved
- * recording with conjugate channels */
- for (i = 0; i < multi; i++) {
- out_ports[i]->ops->master(out_ports[i]);
- for (j = 0; j < atc->msr; j++) {
- amixer = apcm->amixers[apcm->n_srcc+j*multi+i];
- amixer->ops->set_input(amixer, out_ports[i]);
- amixer->ops->set_scale(amixer, INIT_VOL);
- amixer->ops->set_sum(amixer, NULL);
- amixer->ops->commit_raw_write(amixer);
- out_ports[i]->ops->next_conj(out_ports[i]);
-
- srcimp = apcm->srcimps[apcm->n_srcc+j*multi+i];
- srcimp->ops->map(srcimp, apcm->src,
- &amixer->rsc);
- }
- }
- } else {
- for (i = 0; i < multi; i++) {
- srcimp = apcm->srcimps[apcm->n_srcc+i];
- srcimp->ops->map(srcimp, apcm->src, out_ports[i]);
- }
- }
-
- ct_timer_prepare(apcm->timer);
-
- return 0;
-}
-
-static int atc_pcm_capture_start(struct ct_atc *atc, struct ct_atc_pcm *apcm)
-{
- struct src *src;
- struct src_mgr *src_mgr = atc->rsc_mgrs[SRC];
- int i, multi;
-
- if (apcm->started)
- return 0;
-
- apcm->started = 1;
- multi = apcm->substream->runtime->channels;
- /* Set up converting SRCs */
- for (i = 0; i < apcm->n_srcc; i++) {
- src = apcm->srccs[i];
- src->ops->set_pm(src, ((i%multi) != (multi-1)));
- src_mgr->src_disable(src_mgr, src);
- }
-
- /* Set up recording SRC */
- src = apcm->src;
- src->ops->set_sf(src, convert_format(apcm->substream->runtime->format));
- src->ops->set_sa(src, apcm->vm_block->addr);
- src->ops->set_la(src, apcm->vm_block->addr + apcm->vm_block->size);
- src->ops->set_ca(src, apcm->vm_block->addr);
- src_mgr->src_disable(src_mgr, src);
-
- /* Disable relevant SRCs firstly */
- src_mgr->commit_write(src_mgr);
-
- /* Enable SRCs respectively */
- for (i = 0; i < apcm->n_srcc; i++) {
- src = apcm->srccs[i];
- src->ops->set_state(src, SRC_STATE_RUN);
- src->ops->commit_write(src);
- src_mgr->src_enable_s(src_mgr, src);
- }
- src = apcm->src;
- src->ops->set_bm(src, 1);
- src->ops->set_state(src, SRC_STATE_RUN);
- src->ops->commit_write(src);
- src_mgr->src_enable_s(src_mgr, src);
-
- /* Enable relevant SRCs synchronously */
- src_mgr->commit_write(src_mgr);
-
- ct_timer_start(apcm->timer);
- return 0;
-}
-
-static int
-atc_pcm_capture_position(struct ct_atc *atc, struct ct_atc_pcm *apcm)
-{
- struct src *src = apcm->src;
-
- if (!src)
- return 0;
- return src->ops->get_ca(src) - apcm->vm_block->addr;
-}
-
-static int spdif_passthru_playback_get_resources(struct ct_atc *atc,
- struct ct_atc_pcm *apcm)
-{
- struct src_mgr *src_mgr = atc->rsc_mgrs[SRC];
- struct amixer_mgr *amixer_mgr = atc->rsc_mgrs[AMIXER];
- struct src_desc desc = {0};
- struct amixer_desc mix_dsc = {0};
- struct src *src;
- int err;
- int n_amixer = apcm->substream->runtime->channels, i;
- unsigned int pitch, rsr = atc->pll_rate;
-
- /* first release old resources */
- atc_pcm_release_resources(atc, apcm);
-
- /* Get SRC resource */
- desc.multi = apcm->substream->runtime->channels;
- desc.msr = 1;
- while (apcm->substream->runtime->rate > (rsr * desc.msr))
- desc.msr <<= 1;
-
- desc.mode = MEMRD;
- err = src_mgr->get_src(src_mgr, &desc, (struct src **)&apcm->src);
- if (err)
- goto error1;
-
- pitch = atc_get_pitch(apcm->substream->runtime->rate, (rsr * desc.msr));
- src = apcm->src;
- src->ops->set_pitch(src, pitch);
- src->ops->set_rom(src, select_rom(pitch));
- src->ops->set_sf(src, convert_format(apcm->substream->runtime->format));
- src->ops->set_pm(src, (src->ops->next_interleave(src) != NULL));
- src->ops->set_bp(src, 1);
-
- /* Get AMIXER resource */
- n_amixer = (n_amixer < 2) ? 2 : n_amixer;
- apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL);
- if (!apcm->amixers) {
- err = -ENOMEM;
- goto error1;
- }
- mix_dsc.msr = desc.msr;
- for (i = 0, apcm->n_amixer = 0; i < n_amixer; i++) {
- err = amixer_mgr->get_amixer(amixer_mgr, &mix_dsc,
- (struct amixer **)&apcm->amixers[i]);
- if (err)
- goto error1;
-
- apcm->n_amixer++;
- }
-
- /* Set up device virtual mem map */
- err = ct_map_audio_buffer(atc, apcm);
- if (err < 0)
- goto error1;
-
- return 0;
-
-error1:
- atc_pcm_release_resources(atc, apcm);
- return err;
-}
-
-static int atc_pll_init(struct ct_atc *atc, int rate)
-{
- struct hw *hw = atc->hw;
- int err;
- err = hw->pll_init(hw, rate);
- atc->pll_rate = err ? 0 : rate;
- return err;
-}
-
-static int
-spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm)
-{
- struct dao *dao = container_of(atc->daios[SPDIFOO], struct dao, daio);
- unsigned int rate = apcm->substream->runtime->rate;
- unsigned int status;
- int err = 0;
- unsigned char iec958_con_fs;
-
- switch (rate) {
- case 48000:
- iec958_con_fs = IEC958_AES3_CON_FS_48000;
- break;
- case 44100:
- iec958_con_fs = IEC958_AES3_CON_FS_44100;
- break;
- case 32000:
- iec958_con_fs = IEC958_AES3_CON_FS_32000;
- break;
- default:
- return -ENOENT;
- }
-
- mutex_lock(&atc->atc_mutex);
- dao->ops->get_spos(dao, &status);
- if (((status >> 24) & IEC958_AES3_CON_FS) != iec958_con_fs) {
- status &= ~(IEC958_AES3_CON_FS << 24);
- status |= (iec958_con_fs << 24);
- dao->ops->set_spos(dao, status);
- dao->ops->commit_write(dao);
- }
- if ((rate != atc->pll_rate) && (32000 != rate))
- err = atc_pll_init(atc, rate);
- mutex_unlock(&atc->atc_mutex);
-
- return err;
-}
-
-static int
-spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
-{
- struct src *src;
- struct amixer *amixer;
- struct dao *dao;
- int err;
- int i;
-
- atc_pcm_release_resources(atc, apcm);
-
- /* Configure SPDIFOO and PLL to passthrough mode;
- * determine pll_rate. */
- err = spdif_passthru_playback_setup(atc, apcm);
- if (err)
- return err;
-
- /* Get needed resources. */
- err = spdif_passthru_playback_get_resources(atc, apcm);
- if (err)
- return err;
-
- /* Connect resources */
- src = apcm->src;
- for (i = 0; i < apcm->n_amixer; i++) {
- amixer = apcm->amixers[i];
- amixer->ops->setup(amixer, &src->rsc, INIT_VOL, NULL);
- src = src->ops->next_interleave(src);
- if (!src)
- src = apcm->src;
- }
- /* Connect to SPDIFOO */
- mutex_lock(&atc->atc_mutex);
- dao = container_of(atc->daios[SPDIFOO], struct dao, daio);
- amixer = apcm->amixers[0];
- dao->ops->set_left_input(dao, &amixer->rsc);
- amixer = apcm->amixers[1];
- dao->ops->set_right_input(dao, &amixer->rsc);
- mutex_unlock(&atc->atc_mutex);
-
- ct_timer_prepare(apcm->timer);
-
- return 0;
-}
-
-static int atc_select_line_in(struct ct_atc *atc)
-{
- struct hw *hw = atc->hw;
- struct ct_mixer *mixer = atc->mixer;
- struct src *src;
-
- if (hw->is_adc_source_selected(hw, ADC_LINEIN))
- return 0;
-
- mixer->set_input_left(mixer, MIX_MIC_IN, NULL);
- mixer->set_input_right(mixer, MIX_MIC_IN, NULL);
-
- hw->select_adc_source(hw, ADC_LINEIN);
-
- src = atc->srcs[2];
- mixer->set_input_left(mixer, MIX_LINE_IN, &src->rsc);
- src = atc->srcs[3];
- mixer->set_input_right(mixer, MIX_LINE_IN, &src->rsc);
-
- return 0;
-}
-
-static int atc_select_mic_in(struct ct_atc *atc)
-{
- struct hw *hw = atc->hw;
- struct ct_mixer *mixer = atc->mixer;
- struct src *src;
-
- if (hw->is_adc_source_selected(hw, ADC_MICIN))
- return 0;
-
- mixer->set_input_left(mixer, MIX_LINE_IN, NULL);
- mixer->set_input_right(mixer, MIX_LINE_IN, NULL);
-
- hw->select_adc_source(hw, ADC_MICIN);
-
- src = atc->srcs[2];
- mixer->set_input_left(mixer, MIX_MIC_IN, &src->rsc);
- src = atc->srcs[3];
- mixer->set_input_right(mixer, MIX_MIC_IN, &src->rsc);
-
- return 0;
-}
-
-static struct capabilities atc_capabilities(struct ct_atc *atc)
-{
- struct hw *hw = atc->hw;
-
- return hw->capabilities(hw);
-}
-
-static int atc_output_switch_get(struct ct_atc *atc)
-{
- struct hw *hw = atc->hw;
-
- return hw->output_switch_get(hw);
-}
-
-static int atc_output_switch_put(struct ct_atc *atc, int position)
-{
- struct hw *hw = atc->hw;
-
- return hw->output_switch_put(hw, position);
-}
-
-static int atc_mic_source_switch_get(struct ct_atc *atc)
-{
- struct hw *hw = atc->hw;
-
- return hw->mic_source_switch_get(hw);
-}
-
-static int atc_mic_source_switch_put(struct ct_atc *atc, int position)
-{
- struct hw *hw = atc->hw;
-
- return hw->mic_source_switch_put(hw, position);
-}
-
-static int atc_select_digit_io(struct ct_atc *atc)
-{
- struct hw *hw = atc->hw;
-
- if (hw->is_adc_source_selected(hw, ADC_NONE))
- return 0;
-
- hw->select_adc_source(hw, ADC_NONE);
-
- return 0;
-}
-
-static int atc_daio_unmute(struct ct_atc *atc, unsigned char state, int type)
-{
- struct daio_mgr *daio_mgr = atc->rsc_mgrs[DAIO];
-
- if (state)
- daio_mgr->daio_enable(daio_mgr, atc->daios[type]);
- else
- daio_mgr->daio_disable(daio_mgr, atc->daios[type]);
-
- daio_mgr->commit_write(daio_mgr);
-
- return 0;
-}
-
-static int
-atc_dao_get_status(struct ct_atc *atc, unsigned int *status, int type)
-{
- struct dao *dao = container_of(atc->daios[type], struct dao, daio);
- return dao->ops->get_spos(dao, status);
-}
-
-static int
-atc_dao_set_status(struct ct_atc *atc, unsigned int status, int type)
-{
- struct dao *dao = container_of(atc->daios[type], struct dao, daio);
-
- dao->ops->set_spos(dao, status);
- dao->ops->commit_write(dao);
- return 0;
-}
-
-static int atc_line_front_unmute(struct ct_atc *atc, unsigned char state)
-{
- return atc_daio_unmute(atc, state, LINEO1);
-}
-
-static int atc_line_surround_unmute(struct ct_atc *atc, unsigned char state)
-{
- return atc_daio_unmute(atc, state, LINEO2);
-}
-
-static int atc_line_clfe_unmute(struct ct_atc *atc, unsigned char state)
-{
- return atc_daio_unmute(atc, state, LINEO3);
-}
-
-static int atc_line_rear_unmute(struct ct_atc *atc, unsigned char state)
-{
- return atc_daio_unmute(atc, state, LINEO4);
-}
-
-static int atc_line_in_unmute(struct ct_atc *atc, unsigned char state)
-{
- return atc_daio_unmute(atc, state, LINEIM);
-}
-
-static int atc_mic_unmute(struct ct_atc *atc, unsigned char state)
-{
- return atc_daio_unmute(atc, state, MIC);
-}
-
-static int atc_spdif_out_unmute(struct ct_atc *atc, unsigned char state)
-{
- return atc_daio_unmute(atc, state, SPDIFOO);
-}
-
-static int atc_spdif_in_unmute(struct ct_atc *atc, unsigned char state)
-{
- return atc_daio_unmute(atc, state, SPDIFIO);
-}
-
-static int atc_spdif_out_get_status(struct ct_atc *atc, unsigned int *status)
-{
- return atc_dao_get_status(atc, status, SPDIFOO);
-}
-
-static int atc_spdif_out_set_status(struct ct_atc *atc, unsigned int status)
-{
- return atc_dao_set_status(atc, status, SPDIFOO);
-}
-
-static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state)
-{
- struct dao_desc da_dsc = {0};
- struct dao *dao;
- int err;
- struct ct_mixer *mixer = atc->mixer;
- struct rsc *rscs[2] = {NULL};
- unsigned int spos = 0;
-
- mutex_lock(&atc->atc_mutex);
- dao = container_of(atc->daios[SPDIFOO], struct dao, daio);
- da_dsc.msr = state ? 1 : atc->msr;
- da_dsc.passthru = state ? 1 : 0;
- err = dao->ops->reinit(dao, &da_dsc);
- if (state) {
- spos = IEC958_DEFAULT_CON;
- } else {
- mixer->get_output_ports(mixer, MIX_SPDIF_OUT,
- &rscs[0], &rscs[1]);
- dao->ops->set_left_input(dao, rscs[0]);
- dao->ops->set_right_input(dao, rscs[1]);
- /* Restore PLL to atc->rsr if needed. */
- if (atc->pll_rate != atc->rsr)
- err = atc_pll_init(atc, atc->rsr);
- }
- dao->ops->set_spos(dao, spos);
- dao->ops->commit_write(dao);
- mutex_unlock(&atc->atc_mutex);
-
- return err;
-}
-
-static int atc_release_resources(struct ct_atc *atc)
-{
- int i;
- struct daio_mgr *daio_mgr = NULL;
- struct dao *dao = NULL;
- struct dai *dai = NULL;
- struct daio *daio = NULL;
- struct sum_mgr *sum_mgr = NULL;
- struct src_mgr *src_mgr = NULL;
- struct srcimp_mgr *srcimp_mgr = NULL;
- struct srcimp *srcimp = NULL;
- struct ct_mixer *mixer = NULL;
-
- /* disconnect internal mixer objects */
- if (atc->mixer) {
- mixer = atc->mixer;
- mixer->set_input_left(mixer, MIX_LINE_IN, NULL);
- mixer->set_input_right(mixer, MIX_LINE_IN, NULL);
- mixer->set_input_left(mixer, MIX_MIC_IN, NULL);
- mixer->set_input_right(mixer, MIX_MIC_IN, NULL);
- mixer->set_input_left(mixer, MIX_SPDIF_IN, NULL);
- mixer->set_input_right(mixer, MIX_SPDIF_IN, NULL);
- }
-
- if (atc->daios) {
- daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO];
- for (i = 0; i < atc->n_daio; i++) {
- daio = atc->daios[i];
- if (daio->type < LINEIM) {
- dao = container_of(daio, struct dao, daio);
- dao->ops->clear_left_input(dao);
- dao->ops->clear_right_input(dao);
- } else {
- dai = container_of(daio, struct dai, daio);
- /* some thing to do for dai ... */
- }
- daio_mgr->put_daio(daio_mgr, daio);
- }
- kfree(atc->daios);
- atc->daios = NULL;
- }
-
- if (atc->pcm) {
- sum_mgr = atc->rsc_mgrs[SUM];
- for (i = 0; i < atc->n_pcm; i++)
- sum_mgr->put_sum(sum_mgr, atc->pcm[i]);
-
- kfree(atc->pcm);
- atc->pcm = NULL;
- }
-
- if (atc->srcs) {
- src_mgr = atc->rsc_mgrs[SRC];
- for (i = 0; i < atc->n_src; i++)
- src_mgr->put_src(src_mgr, atc->srcs[i]);
-
- kfree(atc->srcs);
- atc->srcs = NULL;
- }
-
- if (atc->srcimps) {
- srcimp_mgr = atc->rsc_mgrs[SRCIMP];
- for (i = 0; i < atc->n_srcimp; i++) {
- srcimp = atc->srcimps[i];
- srcimp->ops->unmap(srcimp);
- srcimp_mgr->put_srcimp(srcimp_mgr, atc->srcimps[i]);
- }
- kfree(atc->srcimps);
- atc->srcimps = NULL;
- }
-
- return 0;
-}
-
-static int ct_atc_destroy(struct ct_atc *atc)
-{
- int i = 0;
-
- if (!atc)
- return 0;
-
- if (atc->timer) {
- ct_timer_free(atc->timer);
- atc->timer = NULL;
- }
-
- atc_release_resources(atc);
-
- /* Destroy internal mixer objects */
- if (atc->mixer)
- ct_mixer_destroy(atc->mixer);
-
- for (i = 0; i < NUM_RSCTYP; i++) {
- if (rsc_mgr_funcs[i].destroy && atc->rsc_mgrs[i])
- rsc_mgr_funcs[i].destroy(atc->rsc_mgrs[i]);
-
- }
-
- if (atc->hw)
- destroy_hw_obj((struct hw *)atc->hw);
-
- /* Destroy device virtual memory manager object */
- if (atc->vm) {
- ct_vm_destroy(atc->vm);
- atc->vm = NULL;
- }
-
- kfree(atc);
-
- return 0;
-}
-
-static int atc_dev_free(struct snd_device *dev)
-{
- struct ct_atc *atc = dev->device_data;
- return ct_atc_destroy(atc);
-}
-
-static int __devinit atc_identify_card(struct ct_atc *atc, unsigned int ssid)
-{
- const struct snd_pci_quirk *p;
- const struct snd_pci_quirk *list;
- u16 vendor_id, device_id;
-
- switch (atc->chip_type) {
- case ATC20K1:
- atc->chip_name = "20K1";
- list = subsys_20k1_list;
- break;
- case ATC20K2:
- atc->chip_name = "20K2";
- list = subsys_20k2_list;
- break;
- default:
- return -ENOENT;
- }
- if (ssid) {
- vendor_id = ssid >> 16;
- device_id = ssid & 0xffff;
- } else {
- vendor_id = atc->pci->subsystem_vendor;
- device_id = atc->pci->subsystem_device;
- }
- p = snd_pci_quirk_lookup_id(vendor_id, device_id, list);
- if (p) {
- if (p->value < 0) {
- printk(KERN_ERR "ctxfi: "
- "Device %04x:%04x is black-listed\n",
- vendor_id, device_id);
- return -ENOENT;
- }
- atc->model = p->value;
- } else {
- if (atc->chip_type == ATC20K1)
- atc->model = CT20K1_UNKNOWN;
- else
- atc->model = CT20K2_UNKNOWN;
- }
- atc->model_name = ct_subsys_name[atc->model];
- snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n",
- atc->chip_name, atc->model_name,
- vendor_id, device_id);
- return 0;
-}
-
-int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc)
-{
- enum CTALSADEVS i;
- int err;
-
- alsa_dev_funcs[MIXER].public_name = atc->chip_name;
-
- for (i = 0; i < NUM_CTALSADEVS; i++) {
- if (!alsa_dev_funcs[i].create)
- continue;
-
- err = alsa_dev_funcs[i].create(atc, i,
- alsa_dev_funcs[i].public_name);
- if (err) {
- printk(KERN_ERR "ctxfi: "
- "Creating alsa device %d failed!\n", i);
- return err;
- }
- }
-
- return 0;
-}
-
-static int __devinit atc_create_hw_devs(struct ct_atc *atc)
-{
- struct hw *hw;
- struct card_conf info = {0};
- int i, err;
-
- err = create_hw_obj(atc->pci, atc->chip_type, atc->model, &hw);
- if (err) {
- printk(KERN_ERR "Failed to create hw obj!!!\n");
- return err;
- }
- atc->hw = hw;
-
- /* Initialize card hardware. */
- info.rsr = atc->rsr;
- info.msr = atc->msr;
- info.vm_pgt_phys = atc_get_ptp_phys(atc, 0);
- err = hw->card_init(hw, &info);
- if (err < 0)
- return err;
-
- for (i = 0; i < NUM_RSCTYP; i++) {
- if (!rsc_mgr_funcs[i].create)
- continue;
-
- err = rsc_mgr_funcs[i].create(atc->hw, &atc->rsc_mgrs[i]);
- if (err) {
- printk(KERN_ERR "ctxfi: "
- "Failed to create rsc_mgr %d!!!\n", i);
- return err;
- }
- }
-
- return 0;
-}
-
-static int atc_get_resources(struct ct_atc *atc)
-{
- struct daio_desc da_desc = {0};
- struct daio_mgr *daio_mgr;
- struct src_desc src_dsc = {0};
- struct src_mgr *src_mgr;
- struct srcimp_desc srcimp_dsc = {0};
- struct srcimp_mgr *srcimp_mgr;
- struct sum_desc sum_dsc = {0};
- struct sum_mgr *sum_mgr;
- int err, i, num_srcs, num_daios;
-
- num_daios = ((atc->model == CTSB1270) ? 8 : 7);
- num_srcs = ((atc->model == CTSB1270) ? 6 : 4);
-
- atc->daios = kzalloc(sizeof(void *)*num_daios, GFP_KERNEL);
- if (!atc->daios)
- return -ENOMEM;
-
- atc->srcs = kzalloc(sizeof(void *)*num_srcs, GFP_KERNEL);
- if (!atc->srcs)
- return -ENOMEM;
-
- atc->srcimps = kzalloc(sizeof(void *)*num_srcs, GFP_KERNEL);
- if (!atc->srcimps)
- return -ENOMEM;
-
- atc->pcm = kzalloc(sizeof(void *)*(2*4), GFP_KERNEL);
- if (!atc->pcm)
- return -ENOMEM;
-
- daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO];
- da_desc.msr = atc->msr;
- for (i = 0, atc->n_daio = 0; i < num_daios; i++) {
- da_desc.type = (atc->model != CTSB073X) ? i :
- ((i == SPDIFIO) ? SPDIFI1 : i);
- err = daio_mgr->get_daio(daio_mgr, &da_desc,
- (struct daio **)&atc->daios[i]);
- if (err) {
- printk(KERN_ERR "ctxfi: Failed to get DAIO "
- "resource %d!!!\n", i);
- return err;
- }
- atc->n_daio++;
- }
-
- src_mgr = atc->rsc_mgrs[SRC];
- src_dsc.multi = 1;
- src_dsc.msr = atc->msr;
- src_dsc.mode = ARCRW;
- for (i = 0, atc->n_src = 0; i < num_srcs; i++) {
- err = src_mgr->get_src(src_mgr, &src_dsc,
- (struct src **)&atc->srcs[i]);
- if (err)
- return err;
-
- atc->n_src++;
- }
-
- srcimp_mgr = atc->rsc_mgrs[SRCIMP];
- srcimp_dsc.msr = 8;
- for (i = 0, atc->n_srcimp = 0; i < num_srcs; i++) {
- err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc,
- (struct srcimp **)&atc->srcimps[i]);
- if (err)
- return err;
-
- atc->n_srcimp++;
- }
-
- sum_mgr = atc->rsc_mgrs[SUM];
- sum_dsc.msr = atc->msr;
- for (i = 0, atc->n_pcm = 0; i < (2*4); i++) {
- err = sum_mgr->get_sum(sum_mgr, &sum_dsc,
- (struct sum **)&atc->pcm[i]);
- if (err)
- return err;
-
- atc->n_pcm++;
- }
-
- return 0;
-}
-
-static void
-atc_connect_dai(struct src_mgr *src_mgr, struct dai *dai,
- struct src **srcs, struct srcimp **srcimps)
-{
- struct rsc *rscs[2] = {NULL};
- struct src *src;
- struct srcimp *srcimp;
- int i = 0;
-
- rscs[0] = &dai->daio.rscl;
- rscs[1] = &dai->daio.rscr;
- for (i = 0; i < 2; i++) {
- src = srcs[i];
- srcimp = srcimps[i];
- srcimp->ops->map(srcimp, src, rscs[i]);
- src_mgr->src_disable(src_mgr, src);
- }
-
- src_mgr->commit_write(src_mgr); /* Actually disable SRCs */
-
- src = srcs[0];
- src->ops->set_pm(src, 1);
- for (i = 0; i < 2; i++) {
- src = srcs[i];
- src->ops->set_state(src, SRC_STATE_RUN);
- src->ops->commit_write(src);
- src_mgr->src_enable_s(src_mgr, src);
- }
-
- dai->ops->set_srt_srcl(dai, &(srcs[0]->rsc));
- dai->ops->set_srt_srcr(dai, &(srcs[1]->rsc));
-
- dai->ops->set_enb_src(dai, 1);
- dai->ops->set_enb_srt(dai, 1);
- dai->ops->commit_write(dai);
-
- src_mgr->commit_write(src_mgr); /* Synchronously enable SRCs */
-}
-
-static void atc_connect_resources(struct ct_atc *atc)
-{
- struct dai *dai;
- struct dao *dao;
- struct src *src;
- struct sum *sum;
- struct ct_mixer *mixer;
- struct rsc *rscs[2] = {NULL};
- int i, j;
-
- mixer = atc->mixer;
-
- for (i = MIX_WAVE_FRONT, j = LINEO1; i <= MIX_SPDIF_OUT; i++, j++) {
- mixer->get_output_ports(mixer, i, &rscs[0], &rscs[1]);
- dao = container_of(atc->daios[j], struct dao, daio);
- dao->ops->set_left_input(dao, rscs[0]);
- dao->ops->set_right_input(dao, rscs[1]);
- }
-
- dai = container_of(atc->daios[LINEIM], struct dai, daio);
- atc_connect_dai(atc->rsc_mgrs[SRC], dai,
- (struct src **)&atc->srcs[2],
- (struct srcimp **)&atc->srcimps[2]);
- src = atc->srcs[2];
- mixer->set_input_left(mixer, MIX_LINE_IN, &src->rsc);
- src = atc->srcs[3];
- mixer->set_input_right(mixer, MIX_LINE_IN, &src->rsc);
-
- if (atc->model == CTSB1270) {
- /* Titanium HD has a dedicated ADC for the Mic. */
- dai = container_of(atc->daios[MIC], struct dai, daio);
- atc_connect_dai(atc->rsc_mgrs[SRC], dai,
- (struct src **)&atc->srcs[4],
- (struct srcimp **)&atc->srcimps[4]);
- src = atc->srcs[4];
- mixer->set_input_left(mixer, MIX_MIC_IN, &src->rsc);
- src = atc->srcs[5];
- mixer->set_input_right(mixer, MIX_MIC_IN, &src->rsc);
- }
-
- dai = container_of(atc->daios[SPDIFIO], struct dai, daio);
- atc_connect_dai(atc->rsc_mgrs[SRC], dai,
- (struct src **)&atc->srcs[0],
- (struct srcimp **)&atc->srcimps[0]);
-
- src = atc->srcs[0];
- mixer->set_input_left(mixer, MIX_SPDIF_IN, &src->rsc);
- src = atc->srcs[1];
- mixer->set_input_right(mixer, MIX_SPDIF_IN, &src->rsc);
-
- for (i = MIX_PCMI_FRONT, j = 0; i <= MIX_PCMI_SURROUND; i++, j += 2) {
- sum = atc->pcm[j];
- mixer->set_input_left(mixer, i, &sum->rsc);
- sum = atc->pcm[j+1];
- mixer->set_input_right(mixer, i, &sum->rsc);
- }
-}
-
-#ifdef CONFIG_PM
-static int atc_suspend(struct ct_atc *atc, pm_message_t state)
-{
- int i;
- struct hw *hw = atc->hw;
-
- snd_power_change_state(atc->card, SNDRV_CTL_POWER_D3hot);
-
- for (i = FRONT; i < NUM_PCMS; i++) {
- if (!atc->pcms[i])
- continue;
-
- snd_pcm_suspend_all(atc->pcms[i]);
- }
-
- atc_release_resources(atc);
-
- hw->suspend(hw, state);
-
- return 0;
-}
-
-static int atc_hw_resume(struct ct_atc *atc)
-{
- struct hw *hw = atc->hw;
- struct card_conf info = {0};
-
- /* Re-initialize card hardware. */
- info.rsr = atc->rsr;
- info.msr = atc->msr;
- info.vm_pgt_phys = atc_get_ptp_phys(atc, 0);
- return hw->resume(hw, &info);
-}
-
-static int atc_resources_resume(struct ct_atc *atc)
-{
- struct ct_mixer *mixer;
- int err = 0;
-
- /* Get resources */
- err = atc_get_resources(atc);
- if (err < 0) {
- atc_release_resources(atc);
- return err;
- }
-
- /* Build topology */
- atc_connect_resources(atc);
-
- mixer = atc->mixer;
- mixer->resume(mixer);
-
- return 0;
-}
-
-static int atc_resume(struct ct_atc *atc)
-{
- int err = 0;
-
- /* Do hardware resume. */
- err = atc_hw_resume(atc);
- if (err < 0) {
- printk(KERN_ERR "ctxfi: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(atc->card);
- return err;
- }
-
- err = atc_resources_resume(atc);
- if (err < 0)
- return err;
-
- snd_power_change_state(atc->card, SNDRV_CTL_POWER_D0);
-
- return 0;
-}
-#endif
-
-static struct ct_atc atc_preset __devinitdata = {
- .map_audio_buffer = ct_map_audio_buffer,
- .unmap_audio_buffer = ct_unmap_audio_buffer,
- .pcm_playback_prepare = atc_pcm_playback_prepare,
- .pcm_release_resources = atc_pcm_release_resources,
- .pcm_playback_start = atc_pcm_playback_start,
- .pcm_playback_stop = atc_pcm_stop,
- .pcm_playback_position = atc_pcm_playback_position,
- .pcm_capture_prepare = atc_pcm_capture_prepare,
- .pcm_capture_start = atc_pcm_capture_start,
- .pcm_capture_stop = atc_pcm_stop,
- .pcm_capture_position = atc_pcm_capture_position,
- .spdif_passthru_playback_prepare = spdif_passthru_playback_prepare,
- .get_ptp_phys = atc_get_ptp_phys,
- .select_line_in = atc_select_line_in,
- .select_mic_in = atc_select_mic_in,
- .select_digit_io = atc_select_digit_io,
- .line_front_unmute = atc_line_front_unmute,
- .line_surround_unmute = atc_line_surround_unmute,
- .line_clfe_unmute = atc_line_clfe_unmute,
- .line_rear_unmute = atc_line_rear_unmute,
- .line_in_unmute = atc_line_in_unmute,
- .mic_unmute = atc_mic_unmute,
- .spdif_out_unmute = atc_spdif_out_unmute,
- .spdif_in_unmute = atc_spdif_in_unmute,
- .spdif_out_get_status = atc_spdif_out_get_status,
- .spdif_out_set_status = atc_spdif_out_set_status,
- .spdif_out_passthru = atc_spdif_out_passthru,
- .capabilities = atc_capabilities,
- .output_switch_get = atc_output_switch_get,
- .output_switch_put = atc_output_switch_put,
- .mic_source_switch_get = atc_mic_source_switch_get,
- .mic_source_switch_put = atc_mic_source_switch_put,
-#ifdef CONFIG_PM
- .suspend = atc_suspend,
- .resume = atc_resume,
-#endif
-};
-
-/**
- * ct_atc_create - create and initialize a hardware manager
- * @card: corresponding alsa card object
- * @pci: corresponding kernel pci device object
- * @ratc: return created object address in it
- *
- * Creates and initializes a hardware manager.
- *
- * Creates kmallocated ct_atc structure. Initializes hardware.
- * Returns 0 if succeeds, or negative error code if fails.
- */
-
-int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
- unsigned int rsr, unsigned int msr,
- int chip_type, unsigned int ssid,
- struct ct_atc **ratc)
-{
- struct ct_atc *atc;
- static struct snd_device_ops ops = {
- .dev_free = atc_dev_free,
- };
- int err;
-
- *ratc = NULL;
-
- atc = kzalloc(sizeof(*atc), GFP_KERNEL);
- if (!atc)
- return -ENOMEM;
-
- /* Set operations */
- *atc = atc_preset;
-
- atc->card = card;
- atc->pci = pci;
- atc->rsr = rsr;
- atc->msr = msr;
- atc->chip_type = chip_type;
-
- mutex_init(&atc->atc_mutex);
-
- /* Find card model */
- err = atc_identify_card(atc, ssid);
- if (err < 0) {
- printk(KERN_ERR "ctatc: Card not recognised\n");
- goto error1;
- }
-
- /* Set up device virtual memory management object */
- err = ct_vm_create(&atc->vm, pci);
- if (err < 0)
- goto error1;
-
- /* Create all atc hw devices */
- err = atc_create_hw_devs(atc);
- if (err < 0)
- goto error1;
-
- err = ct_mixer_create(atc, (struct ct_mixer **)&atc->mixer);
- if (err) {
- printk(KERN_ERR "ctxfi: Failed to create mixer obj!!!\n");
- goto error1;
- }
-
- /* Get resources */
- err = atc_get_resources(atc);
- if (err < 0)
- goto error1;
-
- /* Build topology */
- atc_connect_resources(atc);
-
- atc->timer = ct_timer_new(atc);
- if (!atc->timer)
- goto error1;
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, atc, &ops);
- if (err < 0)
- goto error1;
-
- snd_card_set_dev(card, &pci->dev);
-
- *ratc = atc;
- return 0;
-
-error1:
- ct_atc_destroy(atc);
- printk(KERN_ERR "ctxfi: Something wrong!!!\n");
- return err;
-}
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctatc.h b/ANDROID_3.4.5/sound/pci/ctxfi/ctatc.h
deleted file mode 100644
index 3a0def65..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/ctatc.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File ctatc.h
- *
- * @Brief
- * This file contains the definition of the device resource management object.
- *
- * @Author Liu Chun
- * @Date Mar 28 2008
- *
- */
-
-#ifndef CTATC_H
-#define CTATC_H
-
-#include <linux/types.h>
-#include <linux/mutex.h>
-#include <linux/pci.h>
-#include <linux/timer.h>
-#include <sound/core.h>
-
-#include "ctvmem.h"
-#include "cthardware.h"
-#include "ctresource.h"
-
-enum CTALSADEVS { /* Types of alsa devices */
- FRONT,
- SURROUND,
- CLFE,
- SIDE,
- IEC958,
- MIXER,
- NUM_CTALSADEVS /* This should always be the last */
-};
-
-struct ct_atc_chip_sub_details {
- u16 subsys;
- const char *nm_model;
-};
-
-struct ct_atc_chip_details {
- u16 vendor;
- u16 device;
- const struct ct_atc_chip_sub_details *sub_details;
- const char *nm_card;
-};
-
-struct ct_atc;
-struct ct_timer;
-struct ct_timer_instance;
-
-/* alsa pcm stream descriptor */
-struct ct_atc_pcm {
- struct snd_pcm_substream *substream;
- void (*interrupt)(struct ct_atc_pcm *apcm);
- struct ct_timer_instance *timer;
- unsigned int started:1;
-
- /* Only mono and interleaved modes are supported now. */
- struct ct_vm_block *vm_block;
- void *src; /* SRC for interacting with host memory */
- void **srccs; /* SRCs for sample rate conversion */
- void **srcimps; /* SRC Input Mappers */
- void **amixers; /* AMIXERs for routing converted data */
- void *mono; /* A SUM resource for mixing chs to one */
- unsigned char n_srcc; /* Number of converting SRCs */
- unsigned char n_srcimp; /* Number of SRC Input Mappers */
- unsigned char n_amixer; /* Number of AMIXERs */
-};
-
-/* Chip resource management object */
-struct ct_atc {
- struct pci_dev *pci;
- struct snd_card *card;
- unsigned int rsr; /* reference sample rate in Hz */
- unsigned int msr; /* master sample rate in rsr */
- unsigned int pll_rate; /* current rate of Phase Lock Loop */
-
- int chip_type;
- int model;
- const char *chip_name;
- const char *model_name;
-
- struct ct_vm *vm; /* device virtual memory manager for this card */
- int (*map_audio_buffer)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
- void (*unmap_audio_buffer)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
- unsigned long (*get_ptp_phys)(struct ct_atc *atc, int index);
-
- struct mutex atc_mutex;
-
- int (*pcm_playback_prepare)(struct ct_atc *atc,
- struct ct_atc_pcm *apcm);
- int (*pcm_playback_start)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
- int (*pcm_playback_stop)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
- int (*pcm_playback_position)(struct ct_atc *atc,
- struct ct_atc_pcm *apcm);
- int (*spdif_passthru_playback_prepare)(struct ct_atc *atc,
- struct ct_atc_pcm *apcm);
- int (*pcm_capture_prepare)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
- int (*pcm_capture_start)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
- int (*pcm_capture_stop)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
- int (*pcm_capture_position)(struct ct_atc *atc,
- struct ct_atc_pcm *apcm);
- int (*pcm_release_resources)(struct ct_atc *atc,
- struct ct_atc_pcm *apcm);
- int (*select_line_in)(struct ct_atc *atc);
- int (*select_mic_in)(struct ct_atc *atc);
- int (*select_digit_io)(struct ct_atc *atc);
- int (*line_front_unmute)(struct ct_atc *atc, unsigned char state);
- int (*line_surround_unmute)(struct ct_atc *atc, unsigned char state);
- int (*line_clfe_unmute)(struct ct_atc *atc, unsigned char state);
- int (*line_rear_unmute)(struct ct_atc *atc, unsigned char state);
- int (*line_in_unmute)(struct ct_atc *atc, unsigned char state);
- int (*mic_unmute)(struct ct_atc *atc, unsigned char state);
- int (*spdif_out_unmute)(struct ct_atc *atc, unsigned char state);
- int (*spdif_in_unmute)(struct ct_atc *atc, unsigned char state);
- int (*spdif_out_get_status)(struct ct_atc *atc, unsigned int *status);
- int (*spdif_out_set_status)(struct ct_atc *atc, unsigned int status);
- int (*spdif_out_passthru)(struct ct_atc *atc, unsigned char state);
- struct capabilities (*capabilities)(struct ct_atc *atc);
- int (*output_switch_get)(struct ct_atc *atc);
- int (*output_switch_put)(struct ct_atc *atc, int position);
- int (*mic_source_switch_get)(struct ct_atc *atc);
- int (*mic_source_switch_put)(struct ct_atc *atc, int position);
-
- /* Don't touch! Used for internal object. */
- void *rsc_mgrs[NUM_RSCTYP]; /* chip resource managers */
- void *mixer; /* internal mixer object */
- void *hw; /* chip specific hardware access object */
- void **daios; /* digital audio io resources */
- void **pcm; /* SUMs for collecting all pcm stream */
- void **srcs; /* Sample Rate Converters for input signal */
- void **srcimps; /* input mappers for SRCs */
- unsigned char n_daio;
- unsigned char n_src;
- unsigned char n_srcimp;
- unsigned char n_pcm;
-
- struct ct_timer *timer;
-
-#ifdef CONFIG_PM
- int (*suspend)(struct ct_atc *atc, pm_message_t state);
- int (*resume)(struct ct_atc *atc);
-#define NUM_PCMS (NUM_CTALSADEVS - 1)
- struct snd_pcm *pcms[NUM_PCMS];
-#endif
-};
-
-
-int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
- unsigned int rsr, unsigned int msr, int chip_type,
- unsigned int subsysid, struct ct_atc **ratc);
-int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc);
-
-#endif /* CTATC_H */
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctdaio.c b/ANDROID_3.4.5/sound/pci/ctxfi/ctdaio.c
deleted file mode 100644
index 0c00eb40..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/ctdaio.c
+++ /dev/null
@@ -1,762 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File ctdaio.c
- *
- * @Brief
- * This file contains the implementation of Digital Audio Input Output
- * resource management object.
- *
- * @Author Liu Chun
- * @Date May 23 2008
- *
- */
-
-#include "ctdaio.h"
-#include "cthardware.h"
-#include "ctimap.h"
-#include <linux/slab.h>
-#include <linux/kernel.h>
-
-#define DAIO_OUT_MAX SPDIFOO
-
-struct daio_usage {
- unsigned short data;
-};
-
-struct daio_rsc_idx {
- unsigned short left;
- unsigned short right;
-};
-
-struct daio_rsc_idx idx_20k1[NUM_DAIOTYP] = {
- [LINEO1] = {.left = 0x00, .right = 0x01},
- [LINEO2] = {.left = 0x18, .right = 0x19},
- [LINEO3] = {.left = 0x08, .right = 0x09},
- [LINEO4] = {.left = 0x10, .right = 0x11},
- [LINEIM] = {.left = 0x1b5, .right = 0x1bd},
- [SPDIFOO] = {.left = 0x20, .right = 0x21},
- [SPDIFIO] = {.left = 0x15, .right = 0x1d},
- [SPDIFI1] = {.left = 0x95, .right = 0x9d},
-};
-
-struct daio_rsc_idx idx_20k2[NUM_DAIOTYP] = {
- [LINEO1] = {.left = 0x40, .right = 0x41},
- [LINEO2] = {.left = 0x60, .right = 0x61},
- [LINEO3] = {.left = 0x50, .right = 0x51},
- [LINEO4] = {.left = 0x70, .right = 0x71},
- [LINEIM] = {.left = 0x45, .right = 0xc5},
- [MIC] = {.left = 0x55, .right = 0xd5},
- [SPDIFOO] = {.left = 0x00, .right = 0x01},
- [SPDIFIO] = {.left = 0x05, .right = 0x85},
-};
-
-static int daio_master(struct rsc *rsc)
-{
- /* Actually, this is not the resource index of DAIO.
- * For DAO, it is the input mapper index. And, for DAI,
- * it is the output time-slot index. */
- return rsc->conj = rsc->idx;
-}
-
-static int daio_index(const struct rsc *rsc)
-{
- return rsc->conj;
-}
-
-static int daio_out_next_conj(struct rsc *rsc)
-{
- return rsc->conj += 2;
-}
-
-static int daio_in_next_conj_20k1(struct rsc *rsc)
-{
- return rsc->conj += 0x200;
-}
-
-static int daio_in_next_conj_20k2(struct rsc *rsc)
-{
- return rsc->conj += 0x100;
-}
-
-static struct rsc_ops daio_out_rsc_ops = {
- .master = daio_master,
- .next_conj = daio_out_next_conj,
- .index = daio_index,
- .output_slot = NULL,
-};
-
-static struct rsc_ops daio_in_rsc_ops_20k1 = {
- .master = daio_master,
- .next_conj = daio_in_next_conj_20k1,
- .index = NULL,
- .output_slot = daio_index,
-};
-
-static struct rsc_ops daio_in_rsc_ops_20k2 = {
- .master = daio_master,
- .next_conj = daio_in_next_conj_20k2,
- .index = NULL,
- .output_slot = daio_index,
-};
-
-static unsigned int daio_device_index(enum DAIOTYP type, struct hw *hw)
-{
- switch (hw->chip_type) {
- case ATC20K1:
- switch (type) {
- case SPDIFOO: return 0;
- case SPDIFIO: return 0;
- case SPDIFI1: return 1;
- case LINEO1: return 4;
- case LINEO2: return 7;
- case LINEO3: return 5;
- case LINEO4: return 6;
- case LINEIM: return 7;
- default: return -EINVAL;
- }
- case ATC20K2:
- switch (type) {
- case SPDIFOO: return 0;
- case SPDIFIO: return 0;
- case LINEO1: return 4;
- case LINEO2: return 7;
- case LINEO3: return 5;
- case LINEO4: return 6;
- case LINEIM: return 4;
- case MIC: return 5;
- default: return -EINVAL;
- }
- default:
- return -EINVAL;
- }
-}
-
-static int dao_rsc_reinit(struct dao *dao, const struct dao_desc *desc);
-
-static int dao_spdif_get_spos(struct dao *dao, unsigned int *spos)
-{
- ((struct hw *)dao->hw)->dao_get_spos(dao->ctrl_blk, spos);
- return 0;
-}
-
-static int dao_spdif_set_spos(struct dao *dao, unsigned int spos)
-{
- ((struct hw *)dao->hw)->dao_set_spos(dao->ctrl_blk, spos);
- return 0;
-}
-
-static int dao_commit_write(struct dao *dao)
-{
- ((struct hw *)dao->hw)->dao_commit_write(dao->hw,
- daio_device_index(dao->daio.type, dao->hw), dao->ctrl_blk);
- return 0;
-}
-
-static int dao_set_left_input(struct dao *dao, struct rsc *input)
-{
- struct imapper *entry;
- struct daio *daio = &dao->daio;
- int i;
-
- entry = kzalloc((sizeof(*entry) * daio->rscl.msr), GFP_KERNEL);
- if (!entry)
- return -ENOMEM;
-
- dao->ops->clear_left_input(dao);
- /* Program master and conjugate resources */
- input->ops->master(input);
- daio->rscl.ops->master(&daio->rscl);
- for (i = 0; i < daio->rscl.msr; i++, entry++) {
- entry->slot = input->ops->output_slot(input);
- entry->user = entry->addr = daio->rscl.ops->index(&daio->rscl);
- dao->mgr->imap_add(dao->mgr, entry);
- dao->imappers[i] = entry;
-
- input->ops->next_conj(input);
- daio->rscl.ops->next_conj(&daio->rscl);
- }
- input->ops->master(input);
- daio->rscl.ops->master(&daio->rscl);
-
- return 0;
-}
-
-static int dao_set_right_input(struct dao *dao, struct rsc *input)
-{
- struct imapper *entry;
- struct daio *daio = &dao->daio;
- int i;
-
- entry = kzalloc((sizeof(*entry) * daio->rscr.msr), GFP_KERNEL);
- if (!entry)
- return -ENOMEM;
-
- dao->ops->clear_right_input(dao);
- /* Program master and conjugate resources */
- input->ops->master(input);
- daio->rscr.ops->master(&daio->rscr);
- for (i = 0; i < daio->rscr.msr; i++, entry++) {
- entry->slot = input->ops->output_slot(input);
- entry->user = entry->addr = daio->rscr.ops->index(&daio->rscr);
- dao->mgr->imap_add(dao->mgr, entry);
- dao->imappers[daio->rscl.msr + i] = entry;
-
- input->ops->next_conj(input);
- daio->rscr.ops->next_conj(&daio->rscr);
- }
- input->ops->master(input);
- daio->rscr.ops->master(&daio->rscr);
-
- return 0;
-}
-
-static int dao_clear_left_input(struct dao *dao)
-{
- struct imapper *entry;
- struct daio *daio = &dao->daio;
- int i;
-
- if (!dao->imappers[0])
- return 0;
-
- entry = dao->imappers[0];
- dao->mgr->imap_delete(dao->mgr, entry);
- /* Program conjugate resources */
- for (i = 1; i < daio->rscl.msr; i++) {
- entry = dao->imappers[i];
- dao->mgr->imap_delete(dao->mgr, entry);
- dao->imappers[i] = NULL;
- }
-
- kfree(dao->imappers[0]);
- dao->imappers[0] = NULL;
-
- return 0;
-}
-
-static int dao_clear_right_input(struct dao *dao)
-{
- struct imapper *entry;
- struct daio *daio = &dao->daio;
- int i;
-
- if (!dao->imappers[daio->rscl.msr])
- return 0;
-
- entry = dao->imappers[daio->rscl.msr];
- dao->mgr->imap_delete(dao->mgr, entry);
- /* Program conjugate resources */
- for (i = 1; i < daio->rscr.msr; i++) {
- entry = dao->imappers[daio->rscl.msr + i];
- dao->mgr->imap_delete(dao->mgr, entry);
- dao->imappers[daio->rscl.msr + i] = NULL;
- }
-
- kfree(dao->imappers[daio->rscl.msr]);
- dao->imappers[daio->rscl.msr] = NULL;
-
- return 0;
-}
-
-static struct dao_rsc_ops dao_ops = {
- .set_spos = dao_spdif_set_spos,
- .commit_write = dao_commit_write,
- .get_spos = dao_spdif_get_spos,
- .reinit = dao_rsc_reinit,
- .set_left_input = dao_set_left_input,
- .set_right_input = dao_set_right_input,
- .clear_left_input = dao_clear_left_input,
- .clear_right_input = dao_clear_right_input,
-};
-
-static int dai_set_srt_srcl(struct dai *dai, struct rsc *src)
-{
- src->ops->master(src);
- ((struct hw *)dai->hw)->dai_srt_set_srcm(dai->ctrl_blk,
- src->ops->index(src));
- return 0;
-}
-
-static int dai_set_srt_srcr(struct dai *dai, struct rsc *src)
-{
- src->ops->master(src);
- ((struct hw *)dai->hw)->dai_srt_set_srco(dai->ctrl_blk,
- src->ops->index(src));
- return 0;
-}
-
-static int dai_set_srt_msr(struct dai *dai, unsigned int msr)
-{
- unsigned int rsr;
-
- for (rsr = 0; msr > 1; msr >>= 1)
- rsr++;
-
- ((struct hw *)dai->hw)->dai_srt_set_rsr(dai->ctrl_blk, rsr);
- return 0;
-}
-
-static int dai_set_enb_src(struct dai *dai, unsigned int enb)
-{
- ((struct hw *)dai->hw)->dai_srt_set_ec(dai->ctrl_blk, enb);
- return 0;
-}
-
-static int dai_set_enb_srt(struct dai *dai, unsigned int enb)
-{
- ((struct hw *)dai->hw)->dai_srt_set_et(dai->ctrl_blk, enb);
- return 0;
-}
-
-static int dai_commit_write(struct dai *dai)
-{
- ((struct hw *)dai->hw)->dai_commit_write(dai->hw,
- daio_device_index(dai->daio.type, dai->hw), dai->ctrl_blk);
- return 0;
-}
-
-static struct dai_rsc_ops dai_ops = {
- .set_srt_srcl = dai_set_srt_srcl,
- .set_srt_srcr = dai_set_srt_srcr,
- .set_srt_msr = dai_set_srt_msr,
- .set_enb_src = dai_set_enb_src,
- .set_enb_srt = dai_set_enb_srt,
- .commit_write = dai_commit_write,
-};
-
-static int daio_rsc_init(struct daio *daio,
- const struct daio_desc *desc,
- void *hw)
-{
- int err;
- unsigned int idx_l, idx_r;
-
- switch (((struct hw *)hw)->chip_type) {
- case ATC20K1:
- idx_l = idx_20k1[desc->type].left;
- idx_r = idx_20k1[desc->type].right;
- break;
- case ATC20K2:
- idx_l = idx_20k2[desc->type].left;
- idx_r = idx_20k2[desc->type].right;
- break;
- default:
- return -EINVAL;
- }
- err = rsc_init(&daio->rscl, idx_l, DAIO, desc->msr, hw);
- if (err)
- return err;
-
- err = rsc_init(&daio->rscr, idx_r, DAIO, desc->msr, hw);
- if (err)
- goto error1;
-
- /* Set daio->rscl/r->ops to daio specific ones */
- if (desc->type <= DAIO_OUT_MAX) {
- daio->rscl.ops = daio->rscr.ops = &daio_out_rsc_ops;
- } else {
- switch (((struct hw *)hw)->chip_type) {
- case ATC20K1:
- daio->rscl.ops = daio->rscr.ops = &daio_in_rsc_ops_20k1;
- break;
- case ATC20K2:
- daio->rscl.ops = daio->rscr.ops = &daio_in_rsc_ops_20k2;
- break;
- default:
- break;
- }
- }
- daio->type = desc->type;
-
- return 0;
-
-error1:
- rsc_uninit(&daio->rscl);
- return err;
-}
-
-static int daio_rsc_uninit(struct daio *daio)
-{
- rsc_uninit(&daio->rscl);
- rsc_uninit(&daio->rscr);
-
- return 0;
-}
-
-static int dao_rsc_init(struct dao *dao,
- const struct daio_desc *desc,
- struct daio_mgr *mgr)
-{
- struct hw *hw = mgr->mgr.hw;
- unsigned int conf;
- int err;
-
- err = daio_rsc_init(&dao->daio, desc, mgr->mgr.hw);
- if (err)
- return err;
-
- dao->imappers = kzalloc(sizeof(void *)*desc->msr*2, GFP_KERNEL);
- if (!dao->imappers) {
- err = -ENOMEM;
- goto error1;
- }
- dao->ops = &dao_ops;
- dao->mgr = mgr;
- dao->hw = hw;
- err = hw->dao_get_ctrl_blk(&dao->ctrl_blk);
- if (err)
- goto error2;
-
- hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk,
- daio_device_index(dao->daio.type, hw));
- hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
-
- conf = (desc->msr & 0x7) | (desc->passthru << 3);
- hw->daio_mgr_dao_init(mgr->mgr.ctrl_blk,
- daio_device_index(dao->daio.type, hw), conf);
- hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk,
- daio_device_index(dao->daio.type, hw));
- hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
-
- return 0;
-
-error2:
- kfree(dao->imappers);
- dao->imappers = NULL;
-error1:
- daio_rsc_uninit(&dao->daio);
- return err;
-}
-
-static int dao_rsc_uninit(struct dao *dao)
-{
- if (dao->imappers) {
- if (dao->imappers[0])
- dao_clear_left_input(dao);
-
- if (dao->imappers[dao->daio.rscl.msr])
- dao_clear_right_input(dao);
-
- kfree(dao->imappers);
- dao->imappers = NULL;
- }
- ((struct hw *)dao->hw)->dao_put_ctrl_blk(dao->ctrl_blk);
- dao->hw = dao->ctrl_blk = NULL;
- daio_rsc_uninit(&dao->daio);
-
- return 0;
-}
-
-static int dao_rsc_reinit(struct dao *dao, const struct dao_desc *desc)
-{
- struct daio_mgr *mgr = dao->mgr;
- struct daio_desc dsc = {0};
-
- dsc.type = dao->daio.type;
- dsc.msr = desc->msr;
- dsc.passthru = desc->passthru;
- dao_rsc_uninit(dao);
- return dao_rsc_init(dao, &dsc, mgr);
-}
-
-static int dai_rsc_init(struct dai *dai,
- const struct daio_desc *desc,
- struct daio_mgr *mgr)
-{
- int err;
- struct hw *hw = mgr->mgr.hw;
- unsigned int rsr, msr;
-
- err = daio_rsc_init(&dai->daio, desc, mgr->mgr.hw);
- if (err)
- return err;
-
- dai->ops = &dai_ops;
- dai->hw = mgr->mgr.hw;
- err = hw->dai_get_ctrl_blk(&dai->ctrl_blk);
- if (err)
- goto error1;
-
- for (rsr = 0, msr = desc->msr; msr > 1; msr >>= 1)
- rsr++;
-
- hw->dai_srt_set_rsr(dai->ctrl_blk, rsr);
- hw->dai_srt_set_drat(dai->ctrl_blk, 0);
- /* default to disabling control of a SRC */
- hw->dai_srt_set_ec(dai->ctrl_blk, 0);
- hw->dai_srt_set_et(dai->ctrl_blk, 0); /* default to disabling SRT */
- hw->dai_commit_write(hw,
- daio_device_index(dai->daio.type, dai->hw), dai->ctrl_blk);
-
- return 0;
-
-error1:
- daio_rsc_uninit(&dai->daio);
- return err;
-}
-
-static int dai_rsc_uninit(struct dai *dai)
-{
- ((struct hw *)dai->hw)->dai_put_ctrl_blk(dai->ctrl_blk);
- dai->hw = dai->ctrl_blk = NULL;
- daio_rsc_uninit(&dai->daio);
- return 0;
-}
-
-static int daio_mgr_get_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
-{
- if (((struct daio_usage *)mgr->rscs)->data & (0x1 << type))
- return -ENOENT;
-
- ((struct daio_usage *)mgr->rscs)->data |= (0x1 << type);
-
- return 0;
-}
-
-static int daio_mgr_put_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
-{
- ((struct daio_usage *)mgr->rscs)->data &= ~(0x1 << type);
-
- return 0;
-}
-
-static int get_daio_rsc(struct daio_mgr *mgr,
- const struct daio_desc *desc,
- struct daio **rdaio)
-{
- int err;
- struct dai *dai = NULL;
- struct dao *dao = NULL;
- unsigned long flags;
-
- *rdaio = NULL;
-
- /* Check whether there are sufficient daio resources to meet request. */
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- err = daio_mgr_get_rsc(&mgr->mgr, desc->type);
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
- if (err) {
- printk(KERN_ERR "Can't meet DAIO resource request!\n");
- return err;
- }
-
- /* Allocate mem for daio resource */
- if (desc->type <= DAIO_OUT_MAX) {
- dao = kzalloc(sizeof(*dao), GFP_KERNEL);
- if (!dao) {
- err = -ENOMEM;
- goto error;
- }
- err = dao_rsc_init(dao, desc, mgr);
- if (err)
- goto error;
-
- *rdaio = &dao->daio;
- } else {
- dai = kzalloc(sizeof(*dai), GFP_KERNEL);
- if (!dai) {
- err = -ENOMEM;
- goto error;
- }
- err = dai_rsc_init(dai, desc, mgr);
- if (err)
- goto error;
-
- *rdaio = &dai->daio;
- }
-
- mgr->daio_enable(mgr, *rdaio);
- mgr->commit_write(mgr);
-
- return 0;
-
-error:
- if (dao)
- kfree(dao);
- else if (dai)
- kfree(dai);
-
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- daio_mgr_put_rsc(&mgr->mgr, desc->type);
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
- return err;
-}
-
-static int put_daio_rsc(struct daio_mgr *mgr, struct daio *daio)
-{
- unsigned long flags;
-
- mgr->daio_disable(mgr, daio);
- mgr->commit_write(mgr);
-
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- daio_mgr_put_rsc(&mgr->mgr, daio->type);
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
-
- if (daio->type <= DAIO_OUT_MAX) {
- dao_rsc_uninit(container_of(daio, struct dao, daio));
- kfree(container_of(daio, struct dao, daio));
- } else {
- dai_rsc_uninit(container_of(daio, struct dai, daio));
- kfree(container_of(daio, struct dai, daio));
- }
-
- return 0;
-}
-
-static int daio_mgr_enb_daio(struct daio_mgr *mgr, struct daio *daio)
-{
- struct hw *hw = mgr->mgr.hw;
-
- if (DAIO_OUT_MAX >= daio->type) {
- hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk,
- daio_device_index(daio->type, hw));
- } else {
- hw->daio_mgr_enb_dai(mgr->mgr.ctrl_blk,
- daio_device_index(daio->type, hw));
- }
- return 0;
-}
-
-static int daio_mgr_dsb_daio(struct daio_mgr *mgr, struct daio *daio)
-{
- struct hw *hw = mgr->mgr.hw;
-
- if (DAIO_OUT_MAX >= daio->type) {
- hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk,
- daio_device_index(daio->type, hw));
- } else {
- hw->daio_mgr_dsb_dai(mgr->mgr.ctrl_blk,
- daio_device_index(daio->type, hw));
- }
- return 0;
-}
-
-static int daio_map_op(void *data, struct imapper *entry)
-{
- struct rsc_mgr *mgr = &((struct daio_mgr *)data)->mgr;
- struct hw *hw = mgr->hw;
-
- hw->daio_mgr_set_imaparc(mgr->ctrl_blk, entry->slot);
- hw->daio_mgr_set_imapnxt(mgr->ctrl_blk, entry->next);
- hw->daio_mgr_set_imapaddr(mgr->ctrl_blk, entry->addr);
- hw->daio_mgr_commit_write(mgr->hw, mgr->ctrl_blk);
-
- return 0;
-}
-
-static int daio_imap_add(struct daio_mgr *mgr, struct imapper *entry)
-{
- unsigned long flags;
- int err;
-
- spin_lock_irqsave(&mgr->imap_lock, flags);
- if (!entry->addr && mgr->init_imap_added) {
- input_mapper_delete(&mgr->imappers, mgr->init_imap,
- daio_map_op, mgr);
- mgr->init_imap_added = 0;
- }
- err = input_mapper_add(&mgr->imappers, entry, daio_map_op, mgr);
- spin_unlock_irqrestore(&mgr->imap_lock, flags);
-
- return err;
-}
-
-static int daio_imap_delete(struct daio_mgr *mgr, struct imapper *entry)
-{
- unsigned long flags;
- int err;
-
- spin_lock_irqsave(&mgr->imap_lock, flags);
- err = input_mapper_delete(&mgr->imappers, entry, daio_map_op, mgr);
- if (list_empty(&mgr->imappers)) {
- input_mapper_add(&mgr->imappers, mgr->init_imap,
- daio_map_op, mgr);
- mgr->init_imap_added = 1;
- }
- spin_unlock_irqrestore(&mgr->imap_lock, flags);
-
- return err;
-}
-
-static int daio_mgr_commit_write(struct daio_mgr *mgr)
-{
- struct hw *hw = mgr->mgr.hw;
-
- hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
- return 0;
-}
-
-int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr)
-{
- int err, i;
- struct daio_mgr *daio_mgr;
- struct imapper *entry;
-
- *rdaio_mgr = NULL;
- daio_mgr = kzalloc(sizeof(*daio_mgr), GFP_KERNEL);
- if (!daio_mgr)
- return -ENOMEM;
-
- err = rsc_mgr_init(&daio_mgr->mgr, DAIO, NUM_DAIOTYP, hw);
- if (err)
- goto error1;
-
- spin_lock_init(&daio_mgr->mgr_lock);
- spin_lock_init(&daio_mgr->imap_lock);
- INIT_LIST_HEAD(&daio_mgr->imappers);
- entry = kzalloc(sizeof(*entry), GFP_KERNEL);
- if (!entry) {
- err = -ENOMEM;
- goto error2;
- }
- entry->slot = entry->addr = entry->next = entry->user = 0;
- list_add(&entry->list, &daio_mgr->imappers);
- daio_mgr->init_imap = entry;
- daio_mgr->init_imap_added = 1;
-
- daio_mgr->get_daio = get_daio_rsc;
- daio_mgr->put_daio = put_daio_rsc;
- daio_mgr->daio_enable = daio_mgr_enb_daio;
- daio_mgr->daio_disable = daio_mgr_dsb_daio;
- daio_mgr->imap_add = daio_imap_add;
- daio_mgr->imap_delete = daio_imap_delete;
- daio_mgr->commit_write = daio_mgr_commit_write;
-
- for (i = 0; i < 8; i++) {
- ((struct hw *)hw)->daio_mgr_dsb_dao(daio_mgr->mgr.ctrl_blk, i);
- ((struct hw *)hw)->daio_mgr_dsb_dai(daio_mgr->mgr.ctrl_blk, i);
- }
- ((struct hw *)hw)->daio_mgr_commit_write(hw, daio_mgr->mgr.ctrl_blk);
-
- *rdaio_mgr = daio_mgr;
-
- return 0;
-
-error2:
- rsc_mgr_uninit(&daio_mgr->mgr);
-error1:
- kfree(daio_mgr);
- return err;
-}
-
-int daio_mgr_destroy(struct daio_mgr *daio_mgr)
-{
- unsigned long flags;
-
- /* free daio input mapper list */
- spin_lock_irqsave(&daio_mgr->imap_lock, flags);
- free_input_mapper_list(&daio_mgr->imappers);
- spin_unlock_irqrestore(&daio_mgr->imap_lock, flags);
-
- rsc_mgr_uninit(&daio_mgr->mgr);
- kfree(daio_mgr);
-
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctdaio.h b/ANDROID_3.4.5/sound/pci/ctxfi/ctdaio.h
deleted file mode 100644
index 85ccb6ee..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/ctdaio.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File ctdaio.h
- *
- * @Brief
- * This file contains the definition of Digital Audio Input Output
- * resource management object.
- *
- * @Author Liu Chun
- * @Date May 23 2008
- *
- */
-
-#ifndef CTDAIO_H
-#define CTDAIO_H
-
-#include "ctresource.h"
-#include "ctimap.h"
-#include <linux/spinlock.h>
-#include <linux/list.h>
-
-/* Define the descriptor of a daio resource */
-enum DAIOTYP {
- LINEO1,
- LINEO2,
- LINEO3,
- LINEO4,
- SPDIFOO, /* S/PDIF Out (Flexijack/Optical) */
- LINEIM,
- SPDIFIO, /* S/PDIF In (Flexijack/Optical) on the card */
- MIC, /* Dedicated mic on Titanium HD */
- SPDIFI1, /* S/PDIF In on internal Drive Bay */
- NUM_DAIOTYP
-};
-
-struct dao_rsc_ops;
-struct dai_rsc_ops;
-struct daio_mgr;
-
-struct daio {
- struct rsc rscl; /* Basic resource info for left TX/RX */
- struct rsc rscr; /* Basic resource info for right TX/RX */
- enum DAIOTYP type;
-};
-
-struct dao {
- struct daio daio;
- struct dao_rsc_ops *ops; /* DAO specific operations */
- struct imapper **imappers;
- struct daio_mgr *mgr;
- void *hw;
- void *ctrl_blk;
-};
-
-struct dai {
- struct daio daio;
- struct dai_rsc_ops *ops; /* DAI specific operations */
- void *hw;
- void *ctrl_blk;
-};
-
-struct dao_desc {
- unsigned int msr:4;
- unsigned int passthru:1;
-};
-
-struct dao_rsc_ops {
- int (*set_spos)(struct dao *dao, unsigned int spos);
- int (*commit_write)(struct dao *dao);
- int (*get_spos)(struct dao *dao, unsigned int *spos);
- int (*reinit)(struct dao *dao, const struct dao_desc *desc);
- int (*set_left_input)(struct dao *dao, struct rsc *input);
- int (*set_right_input)(struct dao *dao, struct rsc *input);
- int (*clear_left_input)(struct dao *dao);
- int (*clear_right_input)(struct dao *dao);
-};
-
-struct dai_rsc_ops {
- int (*set_srt_srcl)(struct dai *dai, struct rsc *src);
- int (*set_srt_srcr)(struct dai *dai, struct rsc *src);
- int (*set_srt_msr)(struct dai *dai, unsigned int msr);
- int (*set_enb_src)(struct dai *dai, unsigned int enb);
- int (*set_enb_srt)(struct dai *dai, unsigned int enb);
- int (*commit_write)(struct dai *dai);
-};
-
-/* Define daio resource request description info */
-struct daio_desc {
- unsigned int type:4;
- unsigned int msr:4;
- unsigned int passthru:1;
-};
-
-struct daio_mgr {
- struct rsc_mgr mgr; /* Basic resource manager info */
- spinlock_t mgr_lock;
- spinlock_t imap_lock;
- struct list_head imappers;
- struct imapper *init_imap;
- unsigned int init_imap_added;
-
- /* request one daio resource */
- int (*get_daio)(struct daio_mgr *mgr,
- const struct daio_desc *desc, struct daio **rdaio);
- /* return one daio resource */
- int (*put_daio)(struct daio_mgr *mgr, struct daio *daio);
- int (*daio_enable)(struct daio_mgr *mgr, struct daio *daio);
- int (*daio_disable)(struct daio_mgr *mgr, struct daio *daio);
- int (*imap_add)(struct daio_mgr *mgr, struct imapper *entry);
- int (*imap_delete)(struct daio_mgr *mgr, struct imapper *entry);
- int (*commit_write)(struct daio_mgr *mgr);
-};
-
-/* Constructor and destructor of daio resource manager */
-int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr);
-int daio_mgr_destroy(struct daio_mgr *daio_mgr);
-
-#endif /* CTDAIO_H */
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/cthardware.c b/ANDROID_3.4.5/sound/pci/ctxfi/cthardware.c
deleted file mode 100644
index 8e64f486..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/cthardware.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File cthardware.c
- *
- * @Brief
- * This file contains the implementation of hardware access methord.
- *
- * @Author Liu Chun
- * @Date Jun 26 2008
- *
- */
-
-#include "cthardware.h"
-#include "cthw20k1.h"
-#include "cthw20k2.h"
-#include <linux/bug.h>
-
-int __devinit create_hw_obj(struct pci_dev *pci, enum CHIPTYP chip_type,
- enum CTCARDS model, struct hw **rhw)
-{
- int err;
-
- switch (chip_type) {
- case ATC20K1:
- err = create_20k1_hw_obj(rhw);
- break;
- case ATC20K2:
- err = create_20k2_hw_obj(rhw);
- break;
- default:
- err = -ENODEV;
- break;
- }
- if (err)
- return err;
-
- (*rhw)->pci = pci;
- (*rhw)->chip_type = chip_type;
- (*rhw)->model = model;
-
- return 0;
-}
-
-int destroy_hw_obj(struct hw *hw)
-{
- int err;
-
- switch (hw->pci->device) {
- case 0x0005: /* 20k1 device */
- err = destroy_20k1_hw_obj(hw);
- break;
- case 0x000B: /* 20k2 device */
- err = destroy_20k2_hw_obj(hw);
- break;
- default:
- err = -ENODEV;
- break;
- }
-
- return err;
-}
-
-unsigned int get_field(unsigned int data, unsigned int field)
-{
- int i;
-
- BUG_ON(!field);
- /* @field should always be greater than 0 */
- for (i = 0; !(field & (1 << i)); )
- i++;
-
- return (data & field) >> i;
-}
-
-void set_field(unsigned int *data, unsigned int field, unsigned int value)
-{
- int i;
-
- BUG_ON(!field);
- /* @field should always be greater than 0 */
- for (i = 0; !(field & (1 << i)); )
- i++;
-
- *data = (*data & (~field)) | ((value << i) & field);
-}
-
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/cthardware.h b/ANDROID_3.4.5/sound/pci/ctxfi/cthardware.h
deleted file mode 100644
index 908315be..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/cthardware.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File cthardware.h
- *
- * @Brief
- * This file contains the definition of hardware access methord.
- *
- * @Author Liu Chun
- * @Date May 13 2008
- *
- */
-
-#ifndef CTHARDWARE_H
-#define CTHARDWARE_H
-
-#include <linux/types.h>
-#include <linux/pci.h>
-
-enum CHIPTYP {
- ATC20K1,
- ATC20K2,
- ATCNONE
-};
-
-enum CTCARDS {
- /* 20k1 models */
- CTSB055X,
- CT20K1_MODEL_FIRST = CTSB055X,
- CTSB073X,
- CTUAA,
- CT20K1_UNKNOWN,
- /* 20k2 models */
- CTSB0760,
- CT20K2_MODEL_FIRST = CTSB0760,
- CTHENDRIX,
- CTSB0880,
- CTSB1270,
- CT20K2_UNKNOWN,
- NUM_CTCARDS /* This should always be the last */
-};
-
-/* Type of input source for ADC */
-enum ADCSRC{
- ADC_MICIN,
- ADC_LINEIN,
- ADC_VIDEO,
- ADC_AUX,
- ADC_NONE /* Switch to digital input */
-};
-
-struct card_conf {
- /* device virtual mem page table page physical addr
- * (supporting one page table page now) */
- unsigned long vm_pgt_phys;
- unsigned int rsr; /* reference sample rate in Hzs*/
- unsigned int msr; /* master sample rate in rsrs */
-};
-
-struct capabilities {
- unsigned int digit_io_switch:1;
- unsigned int dedicated_mic:1;
- unsigned int output_switch:1;
- unsigned int mic_source_switch:1;
-};
-
-struct hw {
- int (*card_init)(struct hw *hw, struct card_conf *info);
- int (*card_stop)(struct hw *hw);
- int (*pll_init)(struct hw *hw, unsigned int rsr);
-#ifdef CONFIG_PM
- int (*suspend)(struct hw *hw, pm_message_t state);
- int (*resume)(struct hw *hw, struct card_conf *info);
-#endif
- int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source);
- int (*select_adc_source)(struct hw *hw, enum ADCSRC source);
- struct capabilities (*capabilities)(struct hw *hw);
- int (*output_switch_get)(struct hw *hw);
- int (*output_switch_put)(struct hw *hw, int position);
- int (*mic_source_switch_get)(struct hw *hw);
- int (*mic_source_switch_put)(struct hw *hw, int position);
-
- /* SRC operations */
- int (*src_rsc_get_ctrl_blk)(void **rblk);
- int (*src_rsc_put_ctrl_blk)(void *blk);
- int (*src_set_state)(void *blk, unsigned int state);
- int (*src_set_bm)(void *blk, unsigned int bm);
- int (*src_set_rsr)(void *blk, unsigned int rsr);
- int (*src_set_sf)(void *blk, unsigned int sf);
- int (*src_set_wr)(void *blk, unsigned int wr);
- int (*src_set_pm)(void *blk, unsigned int pm);
- int (*src_set_rom)(void *blk, unsigned int rom);
- int (*src_set_vo)(void *blk, unsigned int vo);
- int (*src_set_st)(void *blk, unsigned int st);
- int (*src_set_ie)(void *blk, unsigned int ie);
- int (*src_set_ilsz)(void *blk, unsigned int ilsz);
- int (*src_set_bp)(void *blk, unsigned int bp);
- int (*src_set_cisz)(void *blk, unsigned int cisz);
- int (*src_set_ca)(void *blk, unsigned int ca);
- int (*src_set_sa)(void *blk, unsigned int sa);
- int (*src_set_la)(void *blk, unsigned int la);
- int (*src_set_pitch)(void *blk, unsigned int pitch);
- int (*src_set_clear_zbufs)(void *blk, unsigned int clear);
- int (*src_set_dirty)(void *blk, unsigned int flags);
- int (*src_set_dirty_all)(void *blk);
- int (*src_commit_write)(struct hw *hw, unsigned int idx, void *blk);
- int (*src_get_ca)(struct hw *hw, unsigned int idx, void *blk);
- unsigned int (*src_get_dirty)(void *blk);
- unsigned int (*src_dirty_conj_mask)(void);
- int (*src_mgr_get_ctrl_blk)(void **rblk);
- int (*src_mgr_put_ctrl_blk)(void *blk);
- /* syncly enable src @idx */
- int (*src_mgr_enbs_src)(void *blk, unsigned int idx);
- /* enable src @idx */
- int (*src_mgr_enb_src)(void *blk, unsigned int idx);
- /* disable src @idx */
- int (*src_mgr_dsb_src)(void *blk, unsigned int idx);
- int (*src_mgr_commit_write)(struct hw *hw, void *blk);
-
- /* SRC Input Mapper operations */
- int (*srcimp_mgr_get_ctrl_blk)(void **rblk);
- int (*srcimp_mgr_put_ctrl_blk)(void *blk);
- int (*srcimp_mgr_set_imaparc)(void *blk, unsigned int slot);
- int (*srcimp_mgr_set_imapuser)(void *blk, unsigned int user);
- int (*srcimp_mgr_set_imapnxt)(void *blk, unsigned int next);
- int (*srcimp_mgr_set_imapaddr)(void *blk, unsigned int addr);
- int (*srcimp_mgr_commit_write)(struct hw *hw, void *blk);
-
- /* AMIXER operations */
- int (*amixer_rsc_get_ctrl_blk)(void **rblk);
- int (*amixer_rsc_put_ctrl_blk)(void *blk);
- int (*amixer_mgr_get_ctrl_blk)(void **rblk);
- int (*amixer_mgr_put_ctrl_blk)(void *blk);
- int (*amixer_set_mode)(void *blk, unsigned int mode);
- int (*amixer_set_iv)(void *blk, unsigned int iv);
- int (*amixer_set_x)(void *blk, unsigned int x);
- int (*amixer_set_y)(void *blk, unsigned int y);
- int (*amixer_set_sadr)(void *blk, unsigned int sadr);
- int (*amixer_set_se)(void *blk, unsigned int se);
- int (*amixer_set_dirty)(void *blk, unsigned int flags);
- int (*amixer_set_dirty_all)(void *blk);
- int (*amixer_commit_write)(struct hw *hw, unsigned int idx, void *blk);
- int (*amixer_get_y)(void *blk);
- unsigned int (*amixer_get_dirty)(void *blk);
-
- /* DAIO operations */
- int (*dai_get_ctrl_blk)(void **rblk);
- int (*dai_put_ctrl_blk)(void *blk);
- int (*dai_srt_set_srco)(void *blk, unsigned int src);
- int (*dai_srt_set_srcm)(void *blk, unsigned int src);
- int (*dai_srt_set_rsr)(void *blk, unsigned int rsr);
- int (*dai_srt_set_drat)(void *blk, unsigned int drat);
- int (*dai_srt_set_ec)(void *blk, unsigned int ec);
- int (*dai_srt_set_et)(void *blk, unsigned int et);
- int (*dai_commit_write)(struct hw *hw, unsigned int idx, void *blk);
- int (*dao_get_ctrl_blk)(void **rblk);
- int (*dao_put_ctrl_blk)(void *blk);
- int (*dao_set_spos)(void *blk, unsigned int spos);
- int (*dao_commit_write)(struct hw *hw, unsigned int idx, void *blk);
- int (*dao_get_spos)(void *blk, unsigned int *spos);
-
- int (*daio_mgr_get_ctrl_blk)(struct hw *hw, void **rblk);
- int (*daio_mgr_put_ctrl_blk)(void *blk);
- int (*daio_mgr_enb_dai)(void *blk, unsigned int idx);
- int (*daio_mgr_dsb_dai)(void *blk, unsigned int idx);
- int (*daio_mgr_enb_dao)(void *blk, unsigned int idx);
- int (*daio_mgr_dsb_dao)(void *blk, unsigned int idx);
- int (*daio_mgr_dao_init)(void *blk, unsigned int idx,
- unsigned int conf);
- int (*daio_mgr_set_imaparc)(void *blk, unsigned int slot);
- int (*daio_mgr_set_imapnxt)(void *blk, unsigned int next);
- int (*daio_mgr_set_imapaddr)(void *blk, unsigned int addr);
- int (*daio_mgr_commit_write)(struct hw *hw, void *blk);
-
- int (*set_timer_irq)(struct hw *hw, int enable);
- int (*set_timer_tick)(struct hw *hw, unsigned int tick);
- unsigned int (*get_wc)(struct hw *hw);
-
- void (*irq_callback)(void *data, unsigned int bit);
- void *irq_callback_data;
-
- struct pci_dev *pci; /* the pci kernel structure of this card */
- int irq;
- unsigned long io_base;
- unsigned long mem_base;
-
- enum CHIPTYP chip_type;
- enum CTCARDS model;
-};
-
-int create_hw_obj(struct pci_dev *pci, enum CHIPTYP chip_type,
- enum CTCARDS model, struct hw **rhw);
-int destroy_hw_obj(struct hw *hw);
-
-unsigned int get_field(unsigned int data, unsigned int field);
-void set_field(unsigned int *data, unsigned int field, unsigned int value);
-
-/* IRQ bits */
-#define PLL_INT (1 << 10) /* PLL input-clock out-of-range */
-#define FI_INT (1 << 9) /* forced interrupt */
-#define IT_INT (1 << 8) /* timer interrupt */
-#define PCI_INT (1 << 7) /* PCI bus error pending */
-#define URT_INT (1 << 6) /* UART Tx/Rx */
-#define GPI_INT (1 << 5) /* GPI pin */
-#define MIX_INT (1 << 4) /* mixer parameter segment FIFO channels */
-#define DAI_INT (1 << 3) /* DAI (SR-tracker or SPDIF-receiver) */
-#define TP_INT (1 << 2) /* transport priority queue */
-#define DSP_INT (1 << 1) /* DSP */
-#define SRC_INT (1 << 0) /* SRC channels */
-
-#endif /* CTHARDWARE_H */
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k1.c b/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k1.c
deleted file mode 100644
index a7df1979..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k1.c
+++ /dev/null
@@ -1,2304 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File cthw20k1.c
- *
- * @Brief
- * This file contains the implementation of hardware access methord for 20k1.
- *
- * @Author Liu Chun
- * @Date Jun 24 2008
- *
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/io.h>
-#include <linux/string.h>
-#include <linux/spinlock.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include "cthw20k1.h"
-#include "ct20k1reg.h"
-
-#if BITS_PER_LONG == 32
-#define CT_XFI_DMA_MASK DMA_BIT_MASK(32) /* 32 bit PTE */
-#else
-#define CT_XFI_DMA_MASK DMA_BIT_MASK(64) /* 64 bit PTE */
-#endif
-
-struct hw20k1 {
- struct hw hw;
- spinlock_t reg_20k1_lock;
- spinlock_t reg_pci_lock;
-};
-
-static u32 hw_read_20kx(struct hw *hw, u32 reg);
-static void hw_write_20kx(struct hw *hw, u32 reg, u32 data);
-static u32 hw_read_pci(struct hw *hw, u32 reg);
-static void hw_write_pci(struct hw *hw, u32 reg, u32 data);
-
-/*
- * Type definition block.
- * The layout of control structures can be directly applied on 20k2 chip.
- */
-
-/*
- * SRC control block definitions.
- */
-
-/* SRC resource control block */
-#define SRCCTL_STATE 0x00000007
-#define SRCCTL_BM 0x00000008
-#define SRCCTL_RSR 0x00000030
-#define SRCCTL_SF 0x000001C0
-#define SRCCTL_WR 0x00000200
-#define SRCCTL_PM 0x00000400
-#define SRCCTL_ROM 0x00001800
-#define SRCCTL_VO 0x00002000
-#define SRCCTL_ST 0x00004000
-#define SRCCTL_IE 0x00008000
-#define SRCCTL_ILSZ 0x000F0000
-#define SRCCTL_BP 0x00100000
-
-#define SRCCCR_CISZ 0x000007FF
-#define SRCCCR_CWA 0x001FF800
-#define SRCCCR_D 0x00200000
-#define SRCCCR_RS 0x01C00000
-#define SRCCCR_NAL 0x3E000000
-#define SRCCCR_RA 0xC0000000
-
-#define SRCCA_CA 0x03FFFFFF
-#define SRCCA_RS 0x1C000000
-#define SRCCA_NAL 0xE0000000
-
-#define SRCSA_SA 0x03FFFFFF
-
-#define SRCLA_LA 0x03FFFFFF
-
-/* Mixer Parameter Ring ram Low and Hight register.
- * Fixed-point value in 8.24 format for parameter channel */
-#define MPRLH_PITCH 0xFFFFFFFF
-
-/* SRC resource register dirty flags */
-union src_dirty {
- struct {
- u16 ctl:1;
- u16 ccr:1;
- u16 sa:1;
- u16 la:1;
- u16 ca:1;
- u16 mpr:1;
- u16 czbfs:1; /* Clear Z-Buffers */
- u16 rsv:9;
- } bf;
- u16 data;
-};
-
-struct src_rsc_ctrl_blk {
- unsigned int ctl;
- unsigned int ccr;
- unsigned int ca;
- unsigned int sa;
- unsigned int la;
- unsigned int mpr;
- union src_dirty dirty;
-};
-
-/* SRC manager control block */
-union src_mgr_dirty {
- struct {
- u16 enb0:1;
- u16 enb1:1;
- u16 enb2:1;
- u16 enb3:1;
- u16 enb4:1;
- u16 enb5:1;
- u16 enb6:1;
- u16 enb7:1;
- u16 enbsa:1;
- u16 rsv:7;
- } bf;
- u16 data;
-};
-
-struct src_mgr_ctrl_blk {
- unsigned int enbsa;
- unsigned int enb[8];
- union src_mgr_dirty dirty;
-};
-
-/* SRCIMP manager control block */
-#define SRCAIM_ARC 0x00000FFF
-#define SRCAIM_NXT 0x00FF0000
-#define SRCAIM_SRC 0xFF000000
-
-struct srcimap {
- unsigned int srcaim;
- unsigned int idx;
-};
-
-/* SRCIMP manager register dirty flags */
-union srcimp_mgr_dirty {
- struct {
- u16 srcimap:1;
- u16 rsv:15;
- } bf;
- u16 data;
-};
-
-struct srcimp_mgr_ctrl_blk {
- struct srcimap srcimap;
- union srcimp_mgr_dirty dirty;
-};
-
-/*
- * Function implementation block.
- */
-
-static int src_get_rsc_ctrl_blk(void **rblk)
-{
- struct src_rsc_ctrl_blk *blk;
-
- *rblk = NULL;
- blk = kzalloc(sizeof(*blk), GFP_KERNEL);
- if (!blk)
- return -ENOMEM;
-
- *rblk = blk;
-
- return 0;
-}
-
-static int src_put_rsc_ctrl_blk(void *blk)
-{
- kfree((struct src_rsc_ctrl_blk *)blk);
-
- return 0;
-}
-
-static int src_set_state(void *blk, unsigned int state)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_STATE, state);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_bm(void *blk, unsigned int bm)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_BM, bm);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_rsr(void *blk, unsigned int rsr)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_RSR, rsr);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_sf(void *blk, unsigned int sf)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_SF, sf);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_wr(void *blk, unsigned int wr)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_WR, wr);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_pm(void *blk, unsigned int pm)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_PM, pm);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_rom(void *blk, unsigned int rom)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_ROM, rom);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_vo(void *blk, unsigned int vo)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_VO, vo);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_st(void *blk, unsigned int st)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_ST, st);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_ie(void *blk, unsigned int ie)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_IE, ie);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_ilsz(void *blk, unsigned int ilsz)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_ILSZ, ilsz);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_bp(void *blk, unsigned int bp)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_BP, bp);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_cisz(void *blk, unsigned int cisz)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ccr, SRCCCR_CISZ, cisz);
- ctl->dirty.bf.ccr = 1;
- return 0;
-}
-
-static int src_set_ca(void *blk, unsigned int ca)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ca, SRCCA_CA, ca);
- ctl->dirty.bf.ca = 1;
- return 0;
-}
-
-static int src_set_sa(void *blk, unsigned int sa)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->sa, SRCSA_SA, sa);
- ctl->dirty.bf.sa = 1;
- return 0;
-}
-
-static int src_set_la(void *blk, unsigned int la)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->la, SRCLA_LA, la);
- ctl->dirty.bf.la = 1;
- return 0;
-}
-
-static int src_set_pitch(void *blk, unsigned int pitch)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->mpr, MPRLH_PITCH, pitch);
- ctl->dirty.bf.mpr = 1;
- return 0;
-}
-
-static int src_set_clear_zbufs(void *blk, unsigned int clear)
-{
- ((struct src_rsc_ctrl_blk *)blk)->dirty.bf.czbfs = (clear ? 1 : 0);
- return 0;
-}
-
-static int src_set_dirty(void *blk, unsigned int flags)
-{
- ((struct src_rsc_ctrl_blk *)blk)->dirty.data = (flags & 0xffff);
- return 0;
-}
-
-static int src_set_dirty_all(void *blk)
-{
- ((struct src_rsc_ctrl_blk *)blk)->dirty.data = ~(0x0);
- return 0;
-}
-
-#define AR_SLOT_SIZE 4096
-#define AR_SLOT_BLOCK_SIZE 16
-#define AR_PTS_PITCH 6
-#define AR_PARAM_SRC_OFFSET 0x60
-
-static unsigned int src_param_pitch_mixer(unsigned int src_idx)
-{
- return ((src_idx << 4) + AR_PTS_PITCH + AR_SLOT_SIZE
- - AR_PARAM_SRC_OFFSET) % AR_SLOT_SIZE;
-
-}
-
-static int src_commit_write(struct hw *hw, unsigned int idx, void *blk)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
- int i;
-
- if (ctl->dirty.bf.czbfs) {
- /* Clear Z-Buffer registers */
- for (i = 0; i < 8; i++)
- hw_write_20kx(hw, SRCUPZ+idx*0x100+i*0x4, 0);
-
- for (i = 0; i < 4; i++)
- hw_write_20kx(hw, SRCDN0Z+idx*0x100+i*0x4, 0);
-
- for (i = 0; i < 8; i++)
- hw_write_20kx(hw, SRCDN1Z+idx*0x100+i*0x4, 0);
-
- ctl->dirty.bf.czbfs = 0;
- }
- if (ctl->dirty.bf.mpr) {
- /* Take the parameter mixer resource in the same group as that
- * the idx src is in for simplicity. Unlike src, all conjugate
- * parameter mixer resources must be programmed for
- * corresponding conjugate src resources. */
- unsigned int pm_idx = src_param_pitch_mixer(idx);
- hw_write_20kx(hw, PRING_LO_HI+4*pm_idx, ctl->mpr);
- hw_write_20kx(hw, PMOPLO+8*pm_idx, 0x3);
- hw_write_20kx(hw, PMOPHI+8*pm_idx, 0x0);
- ctl->dirty.bf.mpr = 0;
- }
- if (ctl->dirty.bf.sa) {
- hw_write_20kx(hw, SRCSA+idx*0x100, ctl->sa);
- ctl->dirty.bf.sa = 0;
- }
- if (ctl->dirty.bf.la) {
- hw_write_20kx(hw, SRCLA+idx*0x100, ctl->la);
- ctl->dirty.bf.la = 0;
- }
- if (ctl->dirty.bf.ca) {
- hw_write_20kx(hw, SRCCA+idx*0x100, ctl->ca);
- ctl->dirty.bf.ca = 0;
- }
-
- /* Write srccf register */
- hw_write_20kx(hw, SRCCF+idx*0x100, 0x0);
-
- if (ctl->dirty.bf.ccr) {
- hw_write_20kx(hw, SRCCCR+idx*0x100, ctl->ccr);
- ctl->dirty.bf.ccr = 0;
- }
- if (ctl->dirty.bf.ctl) {
- hw_write_20kx(hw, SRCCTL+idx*0x100, ctl->ctl);
- ctl->dirty.bf.ctl = 0;
- }
-
- return 0;
-}
-
-static int src_get_ca(struct hw *hw, unsigned int idx, void *blk)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- ctl->ca = hw_read_20kx(hw, SRCCA+idx*0x100);
- ctl->dirty.bf.ca = 0;
-
- return get_field(ctl->ca, SRCCA_CA);
-}
-
-static unsigned int src_get_dirty(void *blk)
-{
- return ((struct src_rsc_ctrl_blk *)blk)->dirty.data;
-}
-
-static unsigned int src_dirty_conj_mask(void)
-{
- return 0x20;
-}
-
-static int src_mgr_enbs_src(void *blk, unsigned int idx)
-{
- ((struct src_mgr_ctrl_blk *)blk)->enbsa = ~(0x0);
- ((struct src_mgr_ctrl_blk *)blk)->dirty.bf.enbsa = 1;
- ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] |= (0x1 << (idx%32));
- return 0;
-}
-
-static int src_mgr_enb_src(void *blk, unsigned int idx)
-{
- ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] |= (0x1 << (idx%32));
- ((struct src_mgr_ctrl_blk *)blk)->dirty.data |= (0x1 << (idx/32));
- return 0;
-}
-
-static int src_mgr_dsb_src(void *blk, unsigned int idx)
-{
- ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] &= ~(0x1 << (idx%32));
- ((struct src_mgr_ctrl_blk *)blk)->dirty.data |= (0x1 << (idx/32));
- return 0;
-}
-
-static int src_mgr_commit_write(struct hw *hw, void *blk)
-{
- struct src_mgr_ctrl_blk *ctl = blk;
- int i;
- unsigned int ret;
-
- if (ctl->dirty.bf.enbsa) {
- do {
- ret = hw_read_20kx(hw, SRCENBSTAT);
- } while (ret & 0x1);
- hw_write_20kx(hw, SRCENBS, ctl->enbsa);
- ctl->dirty.bf.enbsa = 0;
- }
- for (i = 0; i < 8; i++) {
- if ((ctl->dirty.data & (0x1 << i))) {
- hw_write_20kx(hw, SRCENB+(i*0x100), ctl->enb[i]);
- ctl->dirty.data &= ~(0x1 << i);
- }
- }
-
- return 0;
-}
-
-static int src_mgr_get_ctrl_blk(void **rblk)
-{
- struct src_mgr_ctrl_blk *blk;
-
- *rblk = NULL;
- blk = kzalloc(sizeof(*blk), GFP_KERNEL);
- if (!blk)
- return -ENOMEM;
-
- *rblk = blk;
-
- return 0;
-}
-
-static int src_mgr_put_ctrl_blk(void *blk)
-{
- kfree((struct src_mgr_ctrl_blk *)blk);
-
- return 0;
-}
-
-static int srcimp_mgr_get_ctrl_blk(void **rblk)
-{
- struct srcimp_mgr_ctrl_blk *blk;
-
- *rblk = NULL;
- blk = kzalloc(sizeof(*blk), GFP_KERNEL);
- if (!blk)
- return -ENOMEM;
-
- *rblk = blk;
-
- return 0;
-}
-
-static int srcimp_mgr_put_ctrl_blk(void *blk)
-{
- kfree((struct srcimp_mgr_ctrl_blk *)blk);
-
- return 0;
-}
-
-static int srcimp_mgr_set_imaparc(void *blk, unsigned int slot)
-{
- struct srcimp_mgr_ctrl_blk *ctl = blk;
-
- set_field(&ctl->srcimap.srcaim, SRCAIM_ARC, slot);
- ctl->dirty.bf.srcimap = 1;
- return 0;
-}
-
-static int srcimp_mgr_set_imapuser(void *blk, unsigned int user)
-{
- struct srcimp_mgr_ctrl_blk *ctl = blk;
-
- set_field(&ctl->srcimap.srcaim, SRCAIM_SRC, user);
- ctl->dirty.bf.srcimap = 1;
- return 0;
-}
-
-static int srcimp_mgr_set_imapnxt(void *blk, unsigned int next)
-{
- struct srcimp_mgr_ctrl_blk *ctl = blk;
-
- set_field(&ctl->srcimap.srcaim, SRCAIM_NXT, next);
- ctl->dirty.bf.srcimap = 1;
- return 0;
-}
-
-static int srcimp_mgr_set_imapaddr(void *blk, unsigned int addr)
-{
- struct srcimp_mgr_ctrl_blk *ctl = blk;
-
- ctl->srcimap.idx = addr;
- ctl->dirty.bf.srcimap = 1;
- return 0;
-}
-
-static int srcimp_mgr_commit_write(struct hw *hw, void *blk)
-{
- struct srcimp_mgr_ctrl_blk *ctl = blk;
-
- if (ctl->dirty.bf.srcimap) {
- hw_write_20kx(hw, SRCIMAP+ctl->srcimap.idx*0x100,
- ctl->srcimap.srcaim);
- ctl->dirty.bf.srcimap = 0;
- }
-
- return 0;
-}
-
-/*
- * AMIXER control block definitions.
- */
-
-#define AMOPLO_M 0x00000003
-#define AMOPLO_X 0x0003FFF0
-#define AMOPLO_Y 0xFFFC0000
-
-#define AMOPHI_SADR 0x000000FF
-#define AMOPHI_SE 0x80000000
-
-/* AMIXER resource register dirty flags */
-union amixer_dirty {
- struct {
- u16 amoplo:1;
- u16 amophi:1;
- u16 rsv:14;
- } bf;
- u16 data;
-};
-
-/* AMIXER resource control block */
-struct amixer_rsc_ctrl_blk {
- unsigned int amoplo;
- unsigned int amophi;
- union amixer_dirty dirty;
-};
-
-static int amixer_set_mode(void *blk, unsigned int mode)
-{
- struct amixer_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->amoplo, AMOPLO_M, mode);
- ctl->dirty.bf.amoplo = 1;
- return 0;
-}
-
-static int amixer_set_iv(void *blk, unsigned int iv)
-{
- /* 20k1 amixer does not have this field */
- return 0;
-}
-
-static int amixer_set_x(void *blk, unsigned int x)
-{
- struct amixer_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->amoplo, AMOPLO_X, x);
- ctl->dirty.bf.amoplo = 1;
- return 0;
-}
-
-static int amixer_set_y(void *blk, unsigned int y)
-{
- struct amixer_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->amoplo, AMOPLO_Y, y);
- ctl->dirty.bf.amoplo = 1;
- return 0;
-}
-
-static int amixer_set_sadr(void *blk, unsigned int sadr)
-{
- struct amixer_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->amophi, AMOPHI_SADR, sadr);
- ctl->dirty.bf.amophi = 1;
- return 0;
-}
-
-static int amixer_set_se(void *blk, unsigned int se)
-{
- struct amixer_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->amophi, AMOPHI_SE, se);
- ctl->dirty.bf.amophi = 1;
- return 0;
-}
-
-static int amixer_set_dirty(void *blk, unsigned int flags)
-{
- ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data = (flags & 0xffff);
- return 0;
-}
-
-static int amixer_set_dirty_all(void *blk)
-{
- ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data = ~(0x0);
- return 0;
-}
-
-static int amixer_commit_write(struct hw *hw, unsigned int idx, void *blk)
-{
- struct amixer_rsc_ctrl_blk *ctl = blk;
-
- if (ctl->dirty.bf.amoplo || ctl->dirty.bf.amophi) {
- hw_write_20kx(hw, AMOPLO+idx*8, ctl->amoplo);
- ctl->dirty.bf.amoplo = 0;
- hw_write_20kx(hw, AMOPHI+idx*8, ctl->amophi);
- ctl->dirty.bf.amophi = 0;
- }
-
- return 0;
-}
-
-static int amixer_get_y(void *blk)
-{
- struct amixer_rsc_ctrl_blk *ctl = blk;
-
- return get_field(ctl->amoplo, AMOPLO_Y);
-}
-
-static unsigned int amixer_get_dirty(void *blk)
-{
- return ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data;
-}
-
-static int amixer_rsc_get_ctrl_blk(void **rblk)
-{
- struct amixer_rsc_ctrl_blk *blk;
-
- *rblk = NULL;
- blk = kzalloc(sizeof(*blk), GFP_KERNEL);
- if (!blk)
- return -ENOMEM;
-
- *rblk = blk;
-
- return 0;
-}
-
-static int amixer_rsc_put_ctrl_blk(void *blk)
-{
- kfree((struct amixer_rsc_ctrl_blk *)blk);
-
- return 0;
-}
-
-static int amixer_mgr_get_ctrl_blk(void **rblk)
-{
- /*amixer_mgr_ctrl_blk_t *blk;*/
-
- *rblk = NULL;
- /*blk = kzalloc(sizeof(*blk), GFP_KERNEL);
- if (!blk)
- return -ENOMEM;
-
- *rblk = blk;*/
-
- return 0;
-}
-
-static int amixer_mgr_put_ctrl_blk(void *blk)
-{
- /*kfree((amixer_mgr_ctrl_blk_t *)blk);*/
-
- return 0;
-}
-
-/*
- * DAIO control block definitions.
- */
-
-/* Receiver Sample Rate Tracker Control register */
-#define SRTCTL_SRCR 0x000000FF
-#define SRTCTL_SRCL 0x0000FF00
-#define SRTCTL_RSR 0x00030000
-#define SRTCTL_DRAT 0x000C0000
-#define SRTCTL_RLE 0x10000000
-#define SRTCTL_RLP 0x20000000
-#define SRTCTL_EC 0x40000000
-#define SRTCTL_ET 0x80000000
-
-/* DAIO Receiver register dirty flags */
-union dai_dirty {
- struct {
- u16 srtctl:1;
- u16 rsv:15;
- } bf;
- u16 data;
-};
-
-/* DAIO Receiver control block */
-struct dai_ctrl_blk {
- unsigned int srtctl;
- union dai_dirty dirty;
-};
-
-/* S/PDIF Transmitter register dirty flags */
-union dao_dirty {
- struct {
- u16 spos:1;
- u16 rsv:15;
- } bf;
- u16 data;
-};
-
-/* S/PDIF Transmitter control block */
-struct dao_ctrl_blk {
- unsigned int spos; /* S/PDIF Output Channel Status Register */
- union dao_dirty dirty;
-};
-
-/* Audio Input Mapper RAM */
-#define AIM_ARC 0x00000FFF
-#define AIM_NXT 0x007F0000
-
-struct daoimap {
- unsigned int aim;
- unsigned int idx;
-};
-
-/* I2S Transmitter/Receiver Control register */
-#define I2SCTL_EA 0x00000004
-#define I2SCTL_EI 0x00000010
-
-/* S/PDIF Transmitter Control register */
-#define SPOCTL_OE 0x00000001
-#define SPOCTL_OS 0x0000000E
-#define SPOCTL_RIV 0x00000010
-#define SPOCTL_LIV 0x00000020
-#define SPOCTL_SR 0x000000C0
-
-/* S/PDIF Receiver Control register */
-#define SPICTL_EN 0x00000001
-#define SPICTL_I24 0x00000002
-#define SPICTL_IB 0x00000004
-#define SPICTL_SM 0x00000008
-#define SPICTL_VM 0x00000010
-
-/* DAIO manager register dirty flags */
-union daio_mgr_dirty {
- struct {
- u32 i2soctl:4;
- u32 i2sictl:4;
- u32 spoctl:4;
- u32 spictl:4;
- u32 daoimap:1;
- u32 rsv:15;
- } bf;
- u32 data;
-};
-
-/* DAIO manager control block */
-struct daio_mgr_ctrl_blk {
- unsigned int i2sctl;
- unsigned int spoctl;
- unsigned int spictl;
- struct daoimap daoimap;
- union daio_mgr_dirty dirty;
-};
-
-static int dai_srt_set_srcr(void *blk, unsigned int src)
-{
- struct dai_ctrl_blk *ctl = blk;
-
- set_field(&ctl->srtctl, SRTCTL_SRCR, src);
- ctl->dirty.bf.srtctl = 1;
- return 0;
-}
-
-static int dai_srt_set_srcl(void *blk, unsigned int src)
-{
- struct dai_ctrl_blk *ctl = blk;
-
- set_field(&ctl->srtctl, SRTCTL_SRCL, src);
- ctl->dirty.bf.srtctl = 1;
- return 0;
-}
-
-static int dai_srt_set_rsr(void *blk, unsigned int rsr)
-{
- struct dai_ctrl_blk *ctl = blk;
-
- set_field(&ctl->srtctl, SRTCTL_RSR, rsr);
- ctl->dirty.bf.srtctl = 1;
- return 0;
-}
-
-static int dai_srt_set_drat(void *blk, unsigned int drat)
-{
- struct dai_ctrl_blk *ctl = blk;
-
- set_field(&ctl->srtctl, SRTCTL_DRAT, drat);
- ctl->dirty.bf.srtctl = 1;
- return 0;
-}
-
-static int dai_srt_set_ec(void *blk, unsigned int ec)
-{
- struct dai_ctrl_blk *ctl = blk;
-
- set_field(&ctl->srtctl, SRTCTL_EC, ec ? 1 : 0);
- ctl->dirty.bf.srtctl = 1;
- return 0;
-}
-
-static int dai_srt_set_et(void *blk, unsigned int et)
-{
- struct dai_ctrl_blk *ctl = blk;
-
- set_field(&ctl->srtctl, SRTCTL_ET, et ? 1 : 0);
- ctl->dirty.bf.srtctl = 1;
- return 0;
-}
-
-static int dai_commit_write(struct hw *hw, unsigned int idx, void *blk)
-{
- struct dai_ctrl_blk *ctl = blk;
-
- if (ctl->dirty.bf.srtctl) {
- if (idx < 4) {
- /* S/PDIF SRTs */
- hw_write_20kx(hw, SRTSCTL+0x4*idx, ctl->srtctl);
- } else {
- /* I2S SRT */
- hw_write_20kx(hw, SRTICTL, ctl->srtctl);
- }
- ctl->dirty.bf.srtctl = 0;
- }
-
- return 0;
-}
-
-static int dai_get_ctrl_blk(void **rblk)
-{
- struct dai_ctrl_blk *blk;
-
- *rblk = NULL;
- blk = kzalloc(sizeof(*blk), GFP_KERNEL);
- if (!blk)
- return -ENOMEM;
-
- *rblk = blk;
-
- return 0;
-}
-
-static int dai_put_ctrl_blk(void *blk)
-{
- kfree((struct dai_ctrl_blk *)blk);
-
- return 0;
-}
-
-static int dao_set_spos(void *blk, unsigned int spos)
-{
- ((struct dao_ctrl_blk *)blk)->spos = spos;
- ((struct dao_ctrl_blk *)blk)->dirty.bf.spos = 1;
- return 0;
-}
-
-static int dao_commit_write(struct hw *hw, unsigned int idx, void *blk)
-{
- struct dao_ctrl_blk *ctl = blk;
-
- if (ctl->dirty.bf.spos) {
- if (idx < 4) {
- /* S/PDIF SPOSx */
- hw_write_20kx(hw, SPOS+0x4*idx, ctl->spos);
- }
- ctl->dirty.bf.spos = 0;
- }
-
- return 0;
-}
-
-static int dao_get_spos(void *blk, unsigned int *spos)
-{
- *spos = ((struct dao_ctrl_blk *)blk)->spos;
- return 0;
-}
-
-static int dao_get_ctrl_blk(void **rblk)
-{
- struct dao_ctrl_blk *blk;
-
- *rblk = NULL;
- blk = kzalloc(sizeof(*blk), GFP_KERNEL);
- if (!blk)
- return -ENOMEM;
-
- *rblk = blk;
-
- return 0;
-}
-
-static int dao_put_ctrl_blk(void *blk)
-{
- kfree((struct dao_ctrl_blk *)blk);
-
- return 0;
-}
-
-static int daio_mgr_enb_dai(void *blk, unsigned int idx)
-{
- struct daio_mgr_ctrl_blk *ctl = blk;
-
- if (idx < 4) {
- /* S/PDIF input */
- set_field(&ctl->spictl, SPICTL_EN << (idx*8), 1);
- ctl->dirty.bf.spictl |= (0x1 << idx);
- } else {
- /* I2S input */
- idx %= 4;
- set_field(&ctl->i2sctl, I2SCTL_EI << (idx*8), 1);
- ctl->dirty.bf.i2sictl |= (0x1 << idx);
- }
- return 0;
-}
-
-static int daio_mgr_dsb_dai(void *blk, unsigned int idx)
-{
- struct daio_mgr_ctrl_blk *ctl = blk;
-
- if (idx < 4) {
- /* S/PDIF input */
- set_field(&ctl->spictl, SPICTL_EN << (idx*8), 0);
- ctl->dirty.bf.spictl |= (0x1 << idx);
- } else {
- /* I2S input */
- idx %= 4;
- set_field(&ctl->i2sctl, I2SCTL_EI << (idx*8), 0);
- ctl->dirty.bf.i2sictl |= (0x1 << idx);
- }
- return 0;
-}
-
-static int daio_mgr_enb_dao(void *blk, unsigned int idx)
-{
- struct daio_mgr_ctrl_blk *ctl = blk;
-
- if (idx < 4) {
- /* S/PDIF output */
- set_field(&ctl->spoctl, SPOCTL_OE << (idx*8), 1);
- ctl->dirty.bf.spoctl |= (0x1 << idx);
- } else {
- /* I2S output */
- idx %= 4;
- set_field(&ctl->i2sctl, I2SCTL_EA << (idx*8), 1);
- ctl->dirty.bf.i2soctl |= (0x1 << idx);
- }
- return 0;
-}
-
-static int daio_mgr_dsb_dao(void *blk, unsigned int idx)
-{
- struct daio_mgr_ctrl_blk *ctl = blk;
-
- if (idx < 4) {
- /* S/PDIF output */
- set_field(&ctl->spoctl, SPOCTL_OE << (idx*8), 0);
- ctl->dirty.bf.spoctl |= (0x1 << idx);
- } else {
- /* I2S output */
- idx %= 4;
- set_field(&ctl->i2sctl, I2SCTL_EA << (idx*8), 0);
- ctl->dirty.bf.i2soctl |= (0x1 << idx);
- }
- return 0;
-}
-
-static int daio_mgr_dao_init(void *blk, unsigned int idx, unsigned int conf)
-{
- struct daio_mgr_ctrl_blk *ctl = blk;
-
- if (idx < 4) {
- /* S/PDIF output */
- switch ((conf & 0x7)) {
- case 0:
- set_field(&ctl->spoctl, SPOCTL_SR << (idx*8), 3);
- break; /* CDIF */
- case 1:
- set_field(&ctl->spoctl, SPOCTL_SR << (idx*8), 0);
- break;
- case 2:
- set_field(&ctl->spoctl, SPOCTL_SR << (idx*8), 1);
- break;
- case 4:
- set_field(&ctl->spoctl, SPOCTL_SR << (idx*8), 2);
- break;
- default:
- break;
- }
- set_field(&ctl->spoctl, SPOCTL_LIV << (idx*8),
- (conf >> 4) & 0x1); /* Non-audio */
- set_field(&ctl->spoctl, SPOCTL_RIV << (idx*8),
- (conf >> 4) & 0x1); /* Non-audio */
- set_field(&ctl->spoctl, SPOCTL_OS << (idx*8),
- ((conf >> 3) & 0x1) ? 2 : 2); /* Raw */
-
- ctl->dirty.bf.spoctl |= (0x1 << idx);
- } else {
- /* I2S output */
- /*idx %= 4; */
- }
- return 0;
-}
-
-static int daio_mgr_set_imaparc(void *blk, unsigned int slot)
-{
- struct daio_mgr_ctrl_blk *ctl = blk;
-
- set_field(&ctl->daoimap.aim, AIM_ARC, slot);
- ctl->dirty.bf.daoimap = 1;
- return 0;
-}
-
-static int daio_mgr_set_imapnxt(void *blk, unsigned int next)
-{
- struct daio_mgr_ctrl_blk *ctl = blk;
-
- set_field(&ctl->daoimap.aim, AIM_NXT, next);
- ctl->dirty.bf.daoimap = 1;
- return 0;
-}
-
-static int daio_mgr_set_imapaddr(void *blk, unsigned int addr)
-{
- struct daio_mgr_ctrl_blk *ctl = blk;
-
- ctl->daoimap.idx = addr;
- ctl->dirty.bf.daoimap = 1;
- return 0;
-}
-
-static int daio_mgr_commit_write(struct hw *hw, void *blk)
-{
- struct daio_mgr_ctrl_blk *ctl = blk;
- int i;
-
- if (ctl->dirty.bf.i2sictl || ctl->dirty.bf.i2soctl) {
- for (i = 0; i < 4; i++) {
- if ((ctl->dirty.bf.i2sictl & (0x1 << i)))
- ctl->dirty.bf.i2sictl &= ~(0x1 << i);
-
- if ((ctl->dirty.bf.i2soctl & (0x1 << i)))
- ctl->dirty.bf.i2soctl &= ~(0x1 << i);
- }
- hw_write_20kx(hw, I2SCTL, ctl->i2sctl);
- mdelay(1);
- }
- if (ctl->dirty.bf.spoctl) {
- for (i = 0; i < 4; i++) {
- if ((ctl->dirty.bf.spoctl & (0x1 << i)))
- ctl->dirty.bf.spoctl &= ~(0x1 << i);
- }
- hw_write_20kx(hw, SPOCTL, ctl->spoctl);
- mdelay(1);
- }
- if (ctl->dirty.bf.spictl) {
- for (i = 0; i < 4; i++) {
- if ((ctl->dirty.bf.spictl & (0x1 << i)))
- ctl->dirty.bf.spictl &= ~(0x1 << i);
- }
- hw_write_20kx(hw, SPICTL, ctl->spictl);
- mdelay(1);
- }
- if (ctl->dirty.bf.daoimap) {
- hw_write_20kx(hw, DAOIMAP+ctl->daoimap.idx*4,
- ctl->daoimap.aim);
- ctl->dirty.bf.daoimap = 0;
- }
-
- return 0;
-}
-
-static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk)
-{
- struct daio_mgr_ctrl_blk *blk;
-
- *rblk = NULL;
- blk = kzalloc(sizeof(*blk), GFP_KERNEL);
- if (!blk)
- return -ENOMEM;
-
- blk->i2sctl = hw_read_20kx(hw, I2SCTL);
- blk->spoctl = hw_read_20kx(hw, SPOCTL);
- blk->spictl = hw_read_20kx(hw, SPICTL);
-
- *rblk = blk;
-
- return 0;
-}
-
-static int daio_mgr_put_ctrl_blk(void *blk)
-{
- kfree((struct daio_mgr_ctrl_blk *)blk);
-
- return 0;
-}
-
-/* Timer interrupt */
-static int set_timer_irq(struct hw *hw, int enable)
-{
- hw_write_20kx(hw, GIE, enable ? IT_INT : 0);
- return 0;
-}
-
-static int set_timer_tick(struct hw *hw, unsigned int ticks)
-{
- if (ticks)
- ticks |= TIMR_IE | TIMR_IP;
- hw_write_20kx(hw, TIMR, ticks);
- return 0;
-}
-
-static unsigned int get_wc(struct hw *hw)
-{
- return hw_read_20kx(hw, WC);
-}
-
-/* Card hardware initialization block */
-struct dac_conf {
- unsigned int msr; /* master sample rate in rsrs */
-};
-
-struct adc_conf {
- unsigned int msr; /* master sample rate in rsrs */
- unsigned char input; /* the input source of ADC */
- unsigned char mic20db; /* boost mic by 20db if input is microphone */
-};
-
-struct daio_conf {
- unsigned int msr; /* master sample rate in rsrs */
-};
-
-struct trn_conf {
- unsigned long vm_pgt_phys;
-};
-
-static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
-{
- u32 i2sorg;
- u32 spdorg;
-
- /* Read I2S CTL. Keep original value. */
- /*i2sorg = hw_read_20kx(hw, I2SCTL);*/
- i2sorg = 0x94040404; /* enable all audio out and I2S-D input */
- /* Program I2S with proper master sample rate and enable
- * the correct I2S channel. */
- i2sorg &= 0xfffffffc;
-
- /* Enable S/PDIF-out-A in fixed 24-bit data
- * format and default to 48kHz. */
- /* Disable all before doing any changes. */
- hw_write_20kx(hw, SPOCTL, 0x0);
- spdorg = 0x05;
-
- switch (info->msr) {
- case 1:
- i2sorg |= 1;
- spdorg |= (0x0 << 6);
- break;
- case 2:
- i2sorg |= 2;
- spdorg |= (0x1 << 6);
- break;
- case 4:
- i2sorg |= 3;
- spdorg |= (0x2 << 6);
- break;
- default:
- i2sorg |= 1;
- break;
- }
-
- hw_write_20kx(hw, I2SCTL, i2sorg);
- hw_write_20kx(hw, SPOCTL, spdorg);
-
- /* Enable S/PDIF-in-A in fixed 24-bit data format. */
- /* Disable all before doing any changes. */
- hw_write_20kx(hw, SPICTL, 0x0);
- mdelay(1);
- spdorg = 0x0a0a0a0a;
- hw_write_20kx(hw, SPICTL, spdorg);
- mdelay(1);
-
- return 0;
-}
-
-/* TRANSPORT operations */
-static int hw_trn_init(struct hw *hw, const struct trn_conf *info)
-{
- u32 trnctl;
- u32 ptp_phys_low, ptp_phys_high;
-
- /* Set up device page table */
- if ((~0UL) == info->vm_pgt_phys) {
- printk(KERN_ERR "Wrong device page table page address!\n");
- return -1;
- }
-
- trnctl = 0x13; /* 32-bit, 4k-size page */
- ptp_phys_low = (u32)info->vm_pgt_phys;
- ptp_phys_high = upper_32_bits(info->vm_pgt_phys);
- if (sizeof(void *) == 8) /* 64bit address */
- trnctl |= (1 << 2);
-#if 0 /* Only 4k h/w pages for simplicitiy */
-#if PAGE_SIZE == 8192
- trnctl |= (1<<5);
-#endif
-#endif
- hw_write_20kx(hw, PTPALX, ptp_phys_low);
- hw_write_20kx(hw, PTPAHX, ptp_phys_high);
- hw_write_20kx(hw, TRNCTL, trnctl);
- hw_write_20kx(hw, TRNIS, 0x200c01); /* really needed? */
-
- return 0;
-}
-
-/* Card initialization */
-#define GCTL_EAC 0x00000001
-#define GCTL_EAI 0x00000002
-#define GCTL_BEP 0x00000004
-#define GCTL_BES 0x00000008
-#define GCTL_DSP 0x00000010
-#define GCTL_DBP 0x00000020
-#define GCTL_ABP 0x00000040
-#define GCTL_TBP 0x00000080
-#define GCTL_SBP 0x00000100
-#define GCTL_FBP 0x00000200
-#define GCTL_XA 0x00000400
-#define GCTL_ET 0x00000800
-#define GCTL_PR 0x00001000
-#define GCTL_MRL 0x00002000
-#define GCTL_SDE 0x00004000
-#define GCTL_SDI 0x00008000
-#define GCTL_SM 0x00010000
-#define GCTL_SR 0x00020000
-#define GCTL_SD 0x00040000
-#define GCTL_SE 0x00080000
-#define GCTL_AID 0x00100000
-
-static int hw_pll_init(struct hw *hw, unsigned int rsr)
-{
- unsigned int pllctl;
- int i;
-
- pllctl = (48000 == rsr) ? 0x1480a001 : 0x1480a731;
- for (i = 0; i < 3; i++) {
- if (hw_read_20kx(hw, PLLCTL) == pllctl)
- break;
-
- hw_write_20kx(hw, PLLCTL, pllctl);
- mdelay(40);
- }
- if (i >= 3) {
- printk(KERN_ALERT "PLL initialization failed!!!\n");
- return -EBUSY;
- }
-
- return 0;
-}
-
-static int hw_auto_init(struct hw *hw)
-{
- unsigned int gctl;
- int i;
-
- gctl = hw_read_20kx(hw, GCTL);
- set_field(&gctl, GCTL_EAI, 0);
- hw_write_20kx(hw, GCTL, gctl);
- set_field(&gctl, GCTL_EAI, 1);
- hw_write_20kx(hw, GCTL, gctl);
- mdelay(10);
- for (i = 0; i < 400000; i++) {
- gctl = hw_read_20kx(hw, GCTL);
- if (get_field(gctl, GCTL_AID))
- break;
- }
- if (!get_field(gctl, GCTL_AID)) {
- printk(KERN_ALERT "Card Auto-init failed!!!\n");
- return -EBUSY;
- }
-
- return 0;
-}
-
-static int i2c_unlock(struct hw *hw)
-{
- if ((hw_read_pci(hw, 0xcc) & 0xff) == 0xaa)
- return 0;
-
- hw_write_pci(hw, 0xcc, 0x8c);
- hw_write_pci(hw, 0xcc, 0x0e);
- if ((hw_read_pci(hw, 0xcc) & 0xff) == 0xaa)
- return 0;
-
- hw_write_pci(hw, 0xcc, 0xee);
- hw_write_pci(hw, 0xcc, 0xaa);
- if ((hw_read_pci(hw, 0xcc) & 0xff) == 0xaa)
- return 0;
-
- return -1;
-}
-
-static void i2c_lock(struct hw *hw)
-{
- if ((hw_read_pci(hw, 0xcc) & 0xff) == 0xaa)
- hw_write_pci(hw, 0xcc, 0x00);
-}
-
-static void i2c_write(struct hw *hw, u32 device, u32 addr, u32 data)
-{
- unsigned int ret;
-
- do {
- ret = hw_read_pci(hw, 0xEC);
- } while (!(ret & 0x800000));
- hw_write_pci(hw, 0xE0, device);
- hw_write_pci(hw, 0xE4, (data << 8) | (addr & 0xff));
-}
-
-/* DAC operations */
-
-static int hw_reset_dac(struct hw *hw)
-{
- u32 i;
- u16 gpioorg;
- unsigned int ret;
-
- if (i2c_unlock(hw))
- return -1;
-
- do {
- ret = hw_read_pci(hw, 0xEC);
- } while (!(ret & 0x800000));
- hw_write_pci(hw, 0xEC, 0x05); /* write to i2c status control */
-
- /* To be effective, need to reset the DAC twice. */
- for (i = 0; i < 2; i++) {
- /* set gpio */
- mdelay(100);
- gpioorg = (u16)hw_read_20kx(hw, GPIO);
- gpioorg &= 0xfffd;
- hw_write_20kx(hw, GPIO, gpioorg);
- mdelay(1);
- hw_write_20kx(hw, GPIO, gpioorg | 0x2);
- }
-
- i2c_write(hw, 0x00180080, 0x01, 0x80);
- i2c_write(hw, 0x00180080, 0x02, 0x10);
-
- i2c_lock(hw);
-
- return 0;
-}
-
-static int hw_dac_init(struct hw *hw, const struct dac_conf *info)
-{
- u32 data;
- u16 gpioorg;
- unsigned int ret;
-
- if (hw->model == CTSB055X) {
- /* SB055x, unmute outputs */
- gpioorg = (u16)hw_read_20kx(hw, GPIO);
- gpioorg &= 0xffbf; /* set GPIO6 to low */
- gpioorg |= 2; /* set GPIO1 to high */
- hw_write_20kx(hw, GPIO, gpioorg);
- return 0;
- }
-
- /* mute outputs */
- gpioorg = (u16)hw_read_20kx(hw, GPIO);
- gpioorg &= 0xffbf;
- hw_write_20kx(hw, GPIO, gpioorg);
-
- hw_reset_dac(hw);
-
- if (i2c_unlock(hw))
- return -1;
-
- hw_write_pci(hw, 0xEC, 0x05); /* write to i2c status control */
- do {
- ret = hw_read_pci(hw, 0xEC);
- } while (!(ret & 0x800000));
-
- switch (info->msr) {
- case 1:
- data = 0x24;
- break;
- case 2:
- data = 0x25;
- break;
- case 4:
- data = 0x26;
- break;
- default:
- data = 0x24;
- break;
- }
-
- i2c_write(hw, 0x00180080, 0x06, data);
- i2c_write(hw, 0x00180080, 0x09, data);
- i2c_write(hw, 0x00180080, 0x0c, data);
- i2c_write(hw, 0x00180080, 0x0f, data);
-
- i2c_lock(hw);
-
- /* unmute outputs */
- gpioorg = (u16)hw_read_20kx(hw, GPIO);
- gpioorg = gpioorg | 0x40;
- hw_write_20kx(hw, GPIO, gpioorg);
-
- return 0;
-}
-
-/* ADC operations */
-
-static int is_adc_input_selected_SB055x(struct hw *hw, enum ADCSRC type)
-{
- return 0;
-}
-
-static int is_adc_input_selected_SBx(struct hw *hw, enum ADCSRC type)
-{
- u32 data;
-
- data = hw_read_20kx(hw, GPIO);
- switch (type) {
- case ADC_MICIN:
- data = ((data & (0x1<<7)) && (data & (0x1<<8)));
- break;
- case ADC_LINEIN:
- data = (!(data & (0x1<<7)) && (data & (0x1<<8)));
- break;
- case ADC_NONE: /* Digital I/O */
- data = (!(data & (0x1<<8)));
- break;
- default:
- data = 0;
- }
- return data;
-}
-
-static int is_adc_input_selected_hendrix(struct hw *hw, enum ADCSRC type)
-{
- u32 data;
-
- data = hw_read_20kx(hw, GPIO);
- switch (type) {
- case ADC_MICIN:
- data = (data & (0x1 << 7)) ? 1 : 0;
- break;
- case ADC_LINEIN:
- data = (data & (0x1 << 7)) ? 0 : 1;
- break;
- default:
- data = 0;
- }
- return data;
-}
-
-static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type)
-{
- switch (hw->model) {
- case CTSB055X:
- return is_adc_input_selected_SB055x(hw, type);
- case CTSB073X:
- return is_adc_input_selected_hendrix(hw, type);
- case CTUAA:
- return is_adc_input_selected_hendrix(hw, type);
- default:
- return is_adc_input_selected_SBx(hw, type);
- }
-}
-
-static int
-adc_input_select_SB055x(struct hw *hw, enum ADCSRC type, unsigned char boost)
-{
- u32 data;
-
- /*
- * check and set the following GPIO bits accordingly
- * ADC_Gain = GPIO2
- * DRM_off = GPIO3
- * Mic_Pwr_on = GPIO7
- * Digital_IO_Sel = GPIO8
- * Mic_Sw = GPIO9
- * Aux/MicLine_Sw = GPIO12
- */
- data = hw_read_20kx(hw, GPIO);
- data &= 0xec73;
- switch (type) {
- case ADC_MICIN:
- data |= (0x1<<7) | (0x1<<8) | (0x1<<9) ;
- data |= boost ? (0x1<<2) : 0;
- break;
- case ADC_LINEIN:
- data |= (0x1<<8);
- break;
- case ADC_AUX:
- data |= (0x1<<8) | (0x1<<12);
- break;
- case ADC_NONE:
- data |= (0x1<<12); /* set to digital */
- break;
- default:
- return -1;
- }
-
- hw_write_20kx(hw, GPIO, data);
-
- return 0;
-}
-
-
-static int
-adc_input_select_SBx(struct hw *hw, enum ADCSRC type, unsigned char boost)
-{
- u32 data;
- u32 i2c_data;
- unsigned int ret;
-
- if (i2c_unlock(hw))
- return -1;
-
- do {
- ret = hw_read_pci(hw, 0xEC);
- } while (!(ret & 0x800000)); /* i2c ready poll */
- /* set i2c access mode as Direct Control */
- hw_write_pci(hw, 0xEC, 0x05);
-
- data = hw_read_20kx(hw, GPIO);
- switch (type) {
- case ADC_MICIN:
- data |= ((0x1 << 7) | (0x1 << 8));
- i2c_data = 0x1; /* Mic-in */
- break;
- case ADC_LINEIN:
- data &= ~(0x1 << 7);
- data |= (0x1 << 8);
- i2c_data = 0x2; /* Line-in */
- break;
- case ADC_NONE:
- data &= ~(0x1 << 8);
- i2c_data = 0x0; /* set to Digital */
- break;
- default:
- i2c_lock(hw);
- return -1;
- }
- hw_write_20kx(hw, GPIO, data);
- i2c_write(hw, 0x001a0080, 0x2a, i2c_data);
- if (boost) {
- i2c_write(hw, 0x001a0080, 0x1c, 0xe7); /* +12dB boost */
- i2c_write(hw, 0x001a0080, 0x1e, 0xe7); /* +12dB boost */
- } else {
- i2c_write(hw, 0x001a0080, 0x1c, 0xcf); /* No boost */
- i2c_write(hw, 0x001a0080, 0x1e, 0xcf); /* No boost */
- }
-
- i2c_lock(hw);
-
- return 0;
-}
-
-static int
-adc_input_select_hendrix(struct hw *hw, enum ADCSRC type, unsigned char boost)
-{
- u32 data;
- u32 i2c_data;
- unsigned int ret;
-
- if (i2c_unlock(hw))
- return -1;
-
- do {
- ret = hw_read_pci(hw, 0xEC);
- } while (!(ret & 0x800000)); /* i2c ready poll */
- /* set i2c access mode as Direct Control */
- hw_write_pci(hw, 0xEC, 0x05);
-
- data = hw_read_20kx(hw, GPIO);
- switch (type) {
- case ADC_MICIN:
- data |= (0x1 << 7);
- i2c_data = 0x1; /* Mic-in */
- break;
- case ADC_LINEIN:
- data &= ~(0x1 << 7);
- i2c_data = 0x2; /* Line-in */
- break;
- default:
- i2c_lock(hw);
- return -1;
- }
- hw_write_20kx(hw, GPIO, data);
- i2c_write(hw, 0x001a0080, 0x2a, i2c_data);
- if (boost) {
- i2c_write(hw, 0x001a0080, 0x1c, 0xe7); /* +12dB boost */
- i2c_write(hw, 0x001a0080, 0x1e, 0xe7); /* +12dB boost */
- } else {
- i2c_write(hw, 0x001a0080, 0x1c, 0xcf); /* No boost */
- i2c_write(hw, 0x001a0080, 0x1e, 0xcf); /* No boost */
- }
-
- i2c_lock(hw);
-
- return 0;
-}
-
-static int hw_adc_input_select(struct hw *hw, enum ADCSRC type)
-{
- int state = type == ADC_MICIN;
-
- switch (hw->model) {
- case CTSB055X:
- return adc_input_select_SB055x(hw, type, state);
- case CTSB073X:
- return adc_input_select_hendrix(hw, type, state);
- case CTUAA:
- return adc_input_select_hendrix(hw, type, state);
- default:
- return adc_input_select_SBx(hw, type, state);
- }
-}
-
-static int adc_init_SB055x(struct hw *hw, int input, int mic20db)
-{
- return adc_input_select_SB055x(hw, input, mic20db);
-}
-
-static int adc_init_SBx(struct hw *hw, int input, int mic20db)
-{
- u16 gpioorg;
- u16 input_source;
- u32 adcdata;
- unsigned int ret;
-
- input_source = 0x100; /* default to analog */
- switch (input) {
- case ADC_MICIN:
- adcdata = 0x1;
- input_source = 0x180; /* set GPIO7 to select Mic */
- break;
- case ADC_LINEIN:
- adcdata = 0x2;
- break;
- case ADC_VIDEO:
- adcdata = 0x4;
- break;
- case ADC_AUX:
- adcdata = 0x8;
- break;
- case ADC_NONE:
- adcdata = 0x0;
- input_source = 0x0; /* set to Digital */
- break;
- default:
- adcdata = 0x0;
- break;
- }
-
- if (i2c_unlock(hw))
- return -1;
-
- do {
- ret = hw_read_pci(hw, 0xEC);
- } while (!(ret & 0x800000)); /* i2c ready poll */
- hw_write_pci(hw, 0xEC, 0x05); /* write to i2c status control */
-
- i2c_write(hw, 0x001a0080, 0x0e, 0x08);
- i2c_write(hw, 0x001a0080, 0x18, 0x0a);
- i2c_write(hw, 0x001a0080, 0x28, 0x86);
- i2c_write(hw, 0x001a0080, 0x2a, adcdata);
-
- if (mic20db) {
- i2c_write(hw, 0x001a0080, 0x1c, 0xf7);
- i2c_write(hw, 0x001a0080, 0x1e, 0xf7);
- } else {
- i2c_write(hw, 0x001a0080, 0x1c, 0xcf);
- i2c_write(hw, 0x001a0080, 0x1e, 0xcf);
- }
-
- if (!(hw_read_20kx(hw, ID0) & 0x100))
- i2c_write(hw, 0x001a0080, 0x16, 0x26);
-
- i2c_lock(hw);
-
- gpioorg = (u16)hw_read_20kx(hw, GPIO);
- gpioorg &= 0xfe7f;
- gpioorg |= input_source;
- hw_write_20kx(hw, GPIO, gpioorg);
-
- return 0;
-}
-
-static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
-{
- if (hw->model == CTSB055X)
- return adc_init_SB055x(hw, info->input, info->mic20db);
- else
- return adc_init_SBx(hw, info->input, info->mic20db);
-}
-
-static struct capabilities hw_capabilities(struct hw *hw)
-{
- struct capabilities cap;
-
- /* SB073x and Vista compatible cards have no digit IO switch */
- cap.digit_io_switch = !(hw->model == CTSB073X || hw->model == CTUAA);
- cap.dedicated_mic = 0;
- cap.output_switch = 0;
- cap.mic_source_switch = 0;
-
- return cap;
-}
-
-#define CTLBITS(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
-
-#define UAA_CFG_PWRSTATUS 0x44
-#define UAA_CFG_SPACE_FLAG 0xA0
-#define UAA_CORE_CHANGE 0x3FFC
-static int uaa_to_xfi(struct pci_dev *pci)
-{
- unsigned int bar0, bar1, bar2, bar3, bar4, bar5;
- unsigned int cmd, irq, cl_size, l_timer, pwr;
- unsigned int is_uaa;
- unsigned int data[4] = {0};
- unsigned int io_base;
- void *mem_base;
- int i;
- const u32 CTLX = CTLBITS('C', 'T', 'L', 'X');
- const u32 CTL_ = CTLBITS('C', 'T', 'L', '-');
- const u32 CTLF = CTLBITS('C', 'T', 'L', 'F');
- const u32 CTLi = CTLBITS('C', 'T', 'L', 'i');
- const u32 CTLA = CTLBITS('C', 'T', 'L', 'A');
- const u32 CTLZ = CTLBITS('C', 'T', 'L', 'Z');
- const u32 CTLL = CTLBITS('C', 'T', 'L', 'L');
-
- /* By default, Hendrix card UAA Bar0 should be using memory... */
- io_base = pci_resource_start(pci, 0);
- mem_base = ioremap(io_base, pci_resource_len(pci, 0));
- if (!mem_base)
- return -ENOENT;
-
- /* Read current mode from Mode Change Register */
- for (i = 0; i < 4; i++)
- data[i] = readl(mem_base + UAA_CORE_CHANGE);
-
- /* Determine current mode... */
- if (data[0] == CTLA) {
- is_uaa = ((data[1] == CTLZ && data[2] == CTLL
- && data[3] == CTLA) || (data[1] == CTLA
- && data[2] == CTLZ && data[3] == CTLL));
- } else if (data[0] == CTLZ) {
- is_uaa = (data[1] == CTLL
- && data[2] == CTLA && data[3] == CTLA);
- } else if (data[0] == CTLL) {
- is_uaa = (data[1] == CTLA
- && data[2] == CTLA && data[3] == CTLZ);
- } else {
- is_uaa = 0;
- }
-
- if (!is_uaa) {
- /* Not in UAA mode currently. Return directly. */
- iounmap(mem_base);
- return 0;
- }
-
- pci_read_config_dword(pci, PCI_BASE_ADDRESS_0, &bar0);
- pci_read_config_dword(pci, PCI_BASE_ADDRESS_1, &bar1);
- pci_read_config_dword(pci, PCI_BASE_ADDRESS_2, &bar2);
- pci_read_config_dword(pci, PCI_BASE_ADDRESS_3, &bar3);
- pci_read_config_dword(pci, PCI_BASE_ADDRESS_4, &bar4);
- pci_read_config_dword(pci, PCI_BASE_ADDRESS_5, &bar5);
- pci_read_config_dword(pci, PCI_INTERRUPT_LINE, &irq);
- pci_read_config_dword(pci, PCI_CACHE_LINE_SIZE, &cl_size);
- pci_read_config_dword(pci, PCI_LATENCY_TIMER, &l_timer);
- pci_read_config_dword(pci, UAA_CFG_PWRSTATUS, &pwr);
- pci_read_config_dword(pci, PCI_COMMAND, &cmd);
-
- /* Set up X-Fi core PCI configuration space. */
- /* Switch to X-Fi config space with BAR0 exposed. */
- pci_write_config_dword(pci, UAA_CFG_SPACE_FLAG, 0x87654321);
- /* Copy UAA's BAR5 into X-Fi BAR0 */
- pci_write_config_dword(pci, PCI_BASE_ADDRESS_0, bar5);
- /* Switch to X-Fi config space without BAR0 exposed. */
- pci_write_config_dword(pci, UAA_CFG_SPACE_FLAG, 0x12345678);
- pci_write_config_dword(pci, PCI_BASE_ADDRESS_1, bar1);
- pci_write_config_dword(pci, PCI_BASE_ADDRESS_2, bar2);
- pci_write_config_dword(pci, PCI_BASE_ADDRESS_3, bar3);
- pci_write_config_dword(pci, PCI_BASE_ADDRESS_4, bar4);
- pci_write_config_dword(pci, PCI_INTERRUPT_LINE, irq);
- pci_write_config_dword(pci, PCI_CACHE_LINE_SIZE, cl_size);
- pci_write_config_dword(pci, PCI_LATENCY_TIMER, l_timer);
- pci_write_config_dword(pci, UAA_CFG_PWRSTATUS, pwr);
- pci_write_config_dword(pci, PCI_COMMAND, cmd);
-
- /* Switch to X-Fi mode */
- writel(CTLX, (mem_base + UAA_CORE_CHANGE));
- writel(CTL_, (mem_base + UAA_CORE_CHANGE));
- writel(CTLF, (mem_base + UAA_CORE_CHANGE));
- writel(CTLi, (mem_base + UAA_CORE_CHANGE));
-
- iounmap(mem_base);
-
- return 0;
-}
-
-static irqreturn_t ct_20k1_interrupt(int irq, void *dev_id)
-{
- struct hw *hw = dev_id;
- unsigned int status;
-
- status = hw_read_20kx(hw, GIP);
- if (!status)
- return IRQ_NONE;
-
- if (hw->irq_callback)
- hw->irq_callback(hw->irq_callback_data, status);
-
- hw_write_20kx(hw, GIP, status);
- return IRQ_HANDLED;
-}
-
-static int hw_card_start(struct hw *hw)
-{
- int err;
- struct pci_dev *pci = hw->pci;
-
- err = pci_enable_device(pci);
- if (err < 0)
- return err;
-
- /* Set DMA transfer mask */
- if (pci_set_dma_mask(pci, CT_XFI_DMA_MASK) < 0 ||
- pci_set_consistent_dma_mask(pci, CT_XFI_DMA_MASK) < 0) {
- printk(KERN_ERR "architecture does not support PCI "
- "busmaster DMA with mask 0x%llx\n",
- CT_XFI_DMA_MASK);
- err = -ENXIO;
- goto error1;
- }
-
- if (!hw->io_base) {
- err = pci_request_regions(pci, "XFi");
- if (err < 0)
- goto error1;
-
- if (hw->model == CTUAA)
- hw->io_base = pci_resource_start(pci, 5);
- else
- hw->io_base = pci_resource_start(pci, 0);
-
- }
-
- /* Switch to X-Fi mode from UAA mode if neeeded */
- if (hw->model == CTUAA) {
- err = uaa_to_xfi(pci);
- if (err)
- goto error2;
-
- }
-
- if (hw->irq < 0) {
- err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, hw);
- if (err < 0) {
- printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
- goto error2;
- }
- hw->irq = pci->irq;
- }
-
- pci_set_master(pci);
-
- return 0;
-
-error2:
- pci_release_regions(pci);
- hw->io_base = 0;
-error1:
- pci_disable_device(pci);
- return err;
-}
-
-static int hw_card_stop(struct hw *hw)
-{
- unsigned int data;
-
- /* disable transport bus master and queueing of request */
- hw_write_20kx(hw, TRNCTL, 0x00);
-
- /* disable pll */
- data = hw_read_20kx(hw, PLLCTL);
- hw_write_20kx(hw, PLLCTL, (data & (~(0x0F<<12))));
-
- /* TODO: Disable interrupt and so on... */
- if (hw->irq >= 0)
- synchronize_irq(hw->irq);
- return 0;
-}
-
-static int hw_card_shutdown(struct hw *hw)
-{
- if (hw->irq >= 0)
- free_irq(hw->irq, hw);
-
- hw->irq = -1;
-
- if (hw->mem_base)
- iounmap((void *)hw->mem_base);
-
- hw->mem_base = (unsigned long)NULL;
-
- if (hw->io_base)
- pci_release_regions(hw->pci);
-
- hw->io_base = 0;
-
- pci_disable_device(hw->pci);
-
- return 0;
-}
-
-static int hw_card_init(struct hw *hw, struct card_conf *info)
-{
- int err;
- unsigned int gctl;
- u32 data;
- struct dac_conf dac_info = {0};
- struct adc_conf adc_info = {0};
- struct daio_conf daio_info = {0};
- struct trn_conf trn_info = {0};
-
- /* Get PCI io port base address and do Hendrix switch if needed. */
- err = hw_card_start(hw);
- if (err)
- return err;
-
- /* PLL init */
- err = hw_pll_init(hw, info->rsr);
- if (err < 0)
- return err;
-
- /* kick off auto-init */
- err = hw_auto_init(hw);
- if (err < 0)
- return err;
-
- /* Enable audio ring */
- gctl = hw_read_20kx(hw, GCTL);
- set_field(&gctl, GCTL_EAC, 1);
- set_field(&gctl, GCTL_DBP, 1);
- set_field(&gctl, GCTL_TBP, 1);
- set_field(&gctl, GCTL_FBP, 1);
- set_field(&gctl, GCTL_ET, 1);
- hw_write_20kx(hw, GCTL, gctl);
- mdelay(10);
-
- /* Reset all global pending interrupts */
- hw_write_20kx(hw, GIE, 0);
- /* Reset all SRC pending interrupts */
- hw_write_20kx(hw, SRCIP, 0);
- mdelay(30);
-
- /* Detect the card ID and configure GPIO accordingly. */
- switch (hw->model) {
- case CTSB055X:
- hw_write_20kx(hw, GPIOCTL, 0x13fe);
- break;
- case CTSB073X:
- hw_write_20kx(hw, GPIOCTL, 0x00e6);
- break;
- case CTUAA:
- hw_write_20kx(hw, GPIOCTL, 0x00c2);
- break;
- default:
- hw_write_20kx(hw, GPIOCTL, 0x01e6);
- break;
- }
-
- trn_info.vm_pgt_phys = info->vm_pgt_phys;
- err = hw_trn_init(hw, &trn_info);
- if (err < 0)
- return err;
-
- daio_info.msr = info->msr;
- err = hw_daio_init(hw, &daio_info);
- if (err < 0)
- return err;
-
- dac_info.msr = info->msr;
- err = hw_dac_init(hw, &dac_info);
- if (err < 0)
- return err;
-
- adc_info.msr = info->msr;
- adc_info.input = ADC_LINEIN;
- adc_info.mic20db = 0;
- err = hw_adc_init(hw, &adc_info);
- if (err < 0)
- return err;
-
- data = hw_read_20kx(hw, SRCMCTL);
- data |= 0x1; /* Enables input from the audio ring */
- hw_write_20kx(hw, SRCMCTL, data);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int hw_suspend(struct hw *hw, pm_message_t state)
-{
- struct pci_dev *pci = hw->pci;
-
- hw_card_stop(hw);
-
- if (hw->model == CTUAA) {
- /* Switch to UAA config space. */
- pci_write_config_dword(pci, UAA_CFG_SPACE_FLAG, 0x0);
- }
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
-
- return 0;
-}
-
-static int hw_resume(struct hw *hw, struct card_conf *info)
-{
- struct pci_dev *pci = hw->pci;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
-
- /* Re-initialize card hardware. */
- return hw_card_init(hw, info);
-}
-#endif
-
-static u32 hw_read_20kx(struct hw *hw, u32 reg)
-{
- u32 value;
- unsigned long flags;
-
- spin_lock_irqsave(
- &container_of(hw, struct hw20k1, hw)->reg_20k1_lock, flags);
- outl(reg, hw->io_base + 0x0);
- value = inl(hw->io_base + 0x4);
- spin_unlock_irqrestore(
- &container_of(hw, struct hw20k1, hw)->reg_20k1_lock, flags);
-
- return value;
-}
-
-static void hw_write_20kx(struct hw *hw, u32 reg, u32 data)
-{
- unsigned long flags;
-
- spin_lock_irqsave(
- &container_of(hw, struct hw20k1, hw)->reg_20k1_lock, flags);
- outl(reg, hw->io_base + 0x0);
- outl(data, hw->io_base + 0x4);
- spin_unlock_irqrestore(
- &container_of(hw, struct hw20k1, hw)->reg_20k1_lock, flags);
-
-}
-
-static u32 hw_read_pci(struct hw *hw, u32 reg)
-{
- u32 value;
- unsigned long flags;
-
- spin_lock_irqsave(
- &container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags);
- outl(reg, hw->io_base + 0x10);
- value = inl(hw->io_base + 0x14);
- spin_unlock_irqrestore(
- &container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags);
-
- return value;
-}
-
-static void hw_write_pci(struct hw *hw, u32 reg, u32 data)
-{
- unsigned long flags;
-
- spin_lock_irqsave(
- &container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags);
- outl(reg, hw->io_base + 0x10);
- outl(data, hw->io_base + 0x14);
- spin_unlock_irqrestore(
- &container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags);
-}
-
-static struct hw ct20k1_preset __devinitdata = {
- .irq = -1,
-
- .card_init = hw_card_init,
- .card_stop = hw_card_stop,
- .pll_init = hw_pll_init,
- .is_adc_source_selected = hw_is_adc_input_selected,
- .select_adc_source = hw_adc_input_select,
- .capabilities = hw_capabilities,
-#ifdef CONFIG_PM
- .suspend = hw_suspend,
- .resume = hw_resume,
-#endif
-
- .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk,
- .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk,
- .src_mgr_get_ctrl_blk = src_mgr_get_ctrl_blk,
- .src_mgr_put_ctrl_blk = src_mgr_put_ctrl_blk,
- .src_set_state = src_set_state,
- .src_set_bm = src_set_bm,
- .src_set_rsr = src_set_rsr,
- .src_set_sf = src_set_sf,
- .src_set_wr = src_set_wr,
- .src_set_pm = src_set_pm,
- .src_set_rom = src_set_rom,
- .src_set_vo = src_set_vo,
- .src_set_st = src_set_st,
- .src_set_ie = src_set_ie,
- .src_set_ilsz = src_set_ilsz,
- .src_set_bp = src_set_bp,
- .src_set_cisz = src_set_cisz,
- .src_set_ca = src_set_ca,
- .src_set_sa = src_set_sa,
- .src_set_la = src_set_la,
- .src_set_pitch = src_set_pitch,
- .src_set_dirty = src_set_dirty,
- .src_set_clear_zbufs = src_set_clear_zbufs,
- .src_set_dirty_all = src_set_dirty_all,
- .src_commit_write = src_commit_write,
- .src_get_ca = src_get_ca,
- .src_get_dirty = src_get_dirty,
- .src_dirty_conj_mask = src_dirty_conj_mask,
- .src_mgr_enbs_src = src_mgr_enbs_src,
- .src_mgr_enb_src = src_mgr_enb_src,
- .src_mgr_dsb_src = src_mgr_dsb_src,
- .src_mgr_commit_write = src_mgr_commit_write,
-
- .srcimp_mgr_get_ctrl_blk = srcimp_mgr_get_ctrl_blk,
- .srcimp_mgr_put_ctrl_blk = srcimp_mgr_put_ctrl_blk,
- .srcimp_mgr_set_imaparc = srcimp_mgr_set_imaparc,
- .srcimp_mgr_set_imapuser = srcimp_mgr_set_imapuser,
- .srcimp_mgr_set_imapnxt = srcimp_mgr_set_imapnxt,
- .srcimp_mgr_set_imapaddr = srcimp_mgr_set_imapaddr,
- .srcimp_mgr_commit_write = srcimp_mgr_commit_write,
-
- .amixer_rsc_get_ctrl_blk = amixer_rsc_get_ctrl_blk,
- .amixer_rsc_put_ctrl_blk = amixer_rsc_put_ctrl_blk,
- .amixer_mgr_get_ctrl_blk = amixer_mgr_get_ctrl_blk,
- .amixer_mgr_put_ctrl_blk = amixer_mgr_put_ctrl_blk,
- .amixer_set_mode = amixer_set_mode,
- .amixer_set_iv = amixer_set_iv,
- .amixer_set_x = amixer_set_x,
- .amixer_set_y = amixer_set_y,
- .amixer_set_sadr = amixer_set_sadr,
- .amixer_set_se = amixer_set_se,
- .amixer_set_dirty = amixer_set_dirty,
- .amixer_set_dirty_all = amixer_set_dirty_all,
- .amixer_commit_write = amixer_commit_write,
- .amixer_get_y = amixer_get_y,
- .amixer_get_dirty = amixer_get_dirty,
-
- .dai_get_ctrl_blk = dai_get_ctrl_blk,
- .dai_put_ctrl_blk = dai_put_ctrl_blk,
- .dai_srt_set_srco = dai_srt_set_srcr,
- .dai_srt_set_srcm = dai_srt_set_srcl,
- .dai_srt_set_rsr = dai_srt_set_rsr,
- .dai_srt_set_drat = dai_srt_set_drat,
- .dai_srt_set_ec = dai_srt_set_ec,
- .dai_srt_set_et = dai_srt_set_et,
- .dai_commit_write = dai_commit_write,
-
- .dao_get_ctrl_blk = dao_get_ctrl_blk,
- .dao_put_ctrl_blk = dao_put_ctrl_blk,
- .dao_set_spos = dao_set_spos,
- .dao_commit_write = dao_commit_write,
- .dao_get_spos = dao_get_spos,
-
- .daio_mgr_get_ctrl_blk = daio_mgr_get_ctrl_blk,
- .daio_mgr_put_ctrl_blk = daio_mgr_put_ctrl_blk,
- .daio_mgr_enb_dai = daio_mgr_enb_dai,
- .daio_mgr_dsb_dai = daio_mgr_dsb_dai,
- .daio_mgr_enb_dao = daio_mgr_enb_dao,
- .daio_mgr_dsb_dao = daio_mgr_dsb_dao,
- .daio_mgr_dao_init = daio_mgr_dao_init,
- .daio_mgr_set_imaparc = daio_mgr_set_imaparc,
- .daio_mgr_set_imapnxt = daio_mgr_set_imapnxt,
- .daio_mgr_set_imapaddr = daio_mgr_set_imapaddr,
- .daio_mgr_commit_write = daio_mgr_commit_write,
-
- .set_timer_irq = set_timer_irq,
- .set_timer_tick = set_timer_tick,
- .get_wc = get_wc,
-};
-
-int __devinit create_20k1_hw_obj(struct hw **rhw)
-{
- struct hw20k1 *hw20k1;
-
- *rhw = NULL;
- hw20k1 = kzalloc(sizeof(*hw20k1), GFP_KERNEL);
- if (!hw20k1)
- return -ENOMEM;
-
- spin_lock_init(&hw20k1->reg_20k1_lock);
- spin_lock_init(&hw20k1->reg_pci_lock);
-
- hw20k1->hw = ct20k1_preset;
-
- *rhw = &hw20k1->hw;
-
- return 0;
-}
-
-int destroy_20k1_hw_obj(struct hw *hw)
-{
- if (hw->io_base)
- hw_card_shutdown(hw);
-
- kfree(container_of(hw, struct hw20k1, hw));
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k1.h b/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k1.h
deleted file mode 100644
index 02f72fb4..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k1.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File cthw20k1.h
- *
- * @Brief
- * This file contains the definition of hardware access methord.
- *
- * @Author Liu Chun
- * @Date May 13 2008
- *
- */
-
-#ifndef CTHW20K1_H
-#define CTHW20K1_H
-
-#include "cthardware.h"
-
-int create_20k1_hw_obj(struct hw **rhw);
-int destroy_20k1_hw_obj(struct hw *hw);
-
-#endif /* CTHW20K1_H */
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k2.c b/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k2.c
deleted file mode 100644
index d6c54b52..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k2.c
+++ /dev/null
@@ -1,2370 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File cthw20k2.c
- *
- * @Brief
- * This file contains the implementation of hardware access method for 20k2.
- *
- * @Author Liu Chun
- * @Date May 14 2008
- *
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/io.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include "cthw20k2.h"
-#include "ct20k2reg.h"
-
-#if BITS_PER_LONG == 32
-#define CT_XFI_DMA_MASK DMA_BIT_MASK(32) /* 32 bit PTE */
-#else
-#define CT_XFI_DMA_MASK DMA_BIT_MASK(64) /* 64 bit PTE */
-#endif
-
-struct hw20k2 {
- struct hw hw;
- /* for i2c */
- unsigned char dev_id;
- unsigned char addr_size;
- unsigned char data_size;
-
- int mic_source;
-};
-
-static u32 hw_read_20kx(struct hw *hw, u32 reg);
-static void hw_write_20kx(struct hw *hw, u32 reg, u32 data);
-
-/*
- * Type definition block.
- * The layout of control structures can be directly applied on 20k2 chip.
- */
-
-/*
- * SRC control block definitions.
- */
-
-/* SRC resource control block */
-#define SRCCTL_STATE 0x00000007
-#define SRCCTL_BM 0x00000008
-#define SRCCTL_RSR 0x00000030
-#define SRCCTL_SF 0x000001C0
-#define SRCCTL_WR 0x00000200
-#define SRCCTL_PM 0x00000400
-#define SRCCTL_ROM 0x00001800
-#define SRCCTL_VO 0x00002000
-#define SRCCTL_ST 0x00004000
-#define SRCCTL_IE 0x00008000
-#define SRCCTL_ILSZ 0x000F0000
-#define SRCCTL_BP 0x00100000
-
-#define SRCCCR_CISZ 0x000007FF
-#define SRCCCR_CWA 0x001FF800
-#define SRCCCR_D 0x00200000
-#define SRCCCR_RS 0x01C00000
-#define SRCCCR_NAL 0x3E000000
-#define SRCCCR_RA 0xC0000000
-
-#define SRCCA_CA 0x0FFFFFFF
-#define SRCCA_RS 0xE0000000
-
-#define SRCSA_SA 0x0FFFFFFF
-
-#define SRCLA_LA 0x0FFFFFFF
-
-/* Mixer Parameter Ring ram Low and Hight register.
- * Fixed-point value in 8.24 format for parameter channel */
-#define MPRLH_PITCH 0xFFFFFFFF
-
-/* SRC resource register dirty flags */
-union src_dirty {
- struct {
- u16 ctl:1;
- u16 ccr:1;
- u16 sa:1;
- u16 la:1;
- u16 ca:1;
- u16 mpr:1;
- u16 czbfs:1; /* Clear Z-Buffers */
- u16 rsv:9;
- } bf;
- u16 data;
-};
-
-struct src_rsc_ctrl_blk {
- unsigned int ctl;
- unsigned int ccr;
- unsigned int ca;
- unsigned int sa;
- unsigned int la;
- unsigned int mpr;
- union src_dirty dirty;
-};
-
-/* SRC manager control block */
-union src_mgr_dirty {
- struct {
- u16 enb0:1;
- u16 enb1:1;
- u16 enb2:1;
- u16 enb3:1;
- u16 enb4:1;
- u16 enb5:1;
- u16 enb6:1;
- u16 enb7:1;
- u16 enbsa:1;
- u16 rsv:7;
- } bf;
- u16 data;
-};
-
-struct src_mgr_ctrl_blk {
- unsigned int enbsa;
- unsigned int enb[8];
- union src_mgr_dirty dirty;
-};
-
-/* SRCIMP manager control block */
-#define SRCAIM_ARC 0x00000FFF
-#define SRCAIM_NXT 0x00FF0000
-#define SRCAIM_SRC 0xFF000000
-
-struct srcimap {
- unsigned int srcaim;
- unsigned int idx;
-};
-
-/* SRCIMP manager register dirty flags */
-union srcimp_mgr_dirty {
- struct {
- u16 srcimap:1;
- u16 rsv:15;
- } bf;
- u16 data;
-};
-
-struct srcimp_mgr_ctrl_blk {
- struct srcimap srcimap;
- union srcimp_mgr_dirty dirty;
-};
-
-/*
- * Function implementation block.
- */
-
-static int src_get_rsc_ctrl_blk(void **rblk)
-{
- struct src_rsc_ctrl_blk *blk;
-
- *rblk = NULL;
- blk = kzalloc(sizeof(*blk), GFP_KERNEL);
- if (!blk)
- return -ENOMEM;
-
- *rblk = blk;
-
- return 0;
-}
-
-static int src_put_rsc_ctrl_blk(void *blk)
-{
- kfree(blk);
-
- return 0;
-}
-
-static int src_set_state(void *blk, unsigned int state)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_STATE, state);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_bm(void *blk, unsigned int bm)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_BM, bm);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_rsr(void *blk, unsigned int rsr)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_RSR, rsr);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_sf(void *blk, unsigned int sf)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_SF, sf);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_wr(void *blk, unsigned int wr)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_WR, wr);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_pm(void *blk, unsigned int pm)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_PM, pm);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_rom(void *blk, unsigned int rom)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_ROM, rom);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_vo(void *blk, unsigned int vo)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_VO, vo);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_st(void *blk, unsigned int st)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_ST, st);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_ie(void *blk, unsigned int ie)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_IE, ie);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_ilsz(void *blk, unsigned int ilsz)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_ILSZ, ilsz);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_bp(void *blk, unsigned int bp)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ctl, SRCCTL_BP, bp);
- ctl->dirty.bf.ctl = 1;
- return 0;
-}
-
-static int src_set_cisz(void *blk, unsigned int cisz)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ccr, SRCCCR_CISZ, cisz);
- ctl->dirty.bf.ccr = 1;
- return 0;
-}
-
-static int src_set_ca(void *blk, unsigned int ca)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->ca, SRCCA_CA, ca);
- ctl->dirty.bf.ca = 1;
- return 0;
-}
-
-static int src_set_sa(void *blk, unsigned int sa)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->sa, SRCSA_SA, sa);
- ctl->dirty.bf.sa = 1;
- return 0;
-}
-
-static int src_set_la(void *blk, unsigned int la)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->la, SRCLA_LA, la);
- ctl->dirty.bf.la = 1;
- return 0;
-}
-
-static int src_set_pitch(void *blk, unsigned int pitch)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->mpr, MPRLH_PITCH, pitch);
- ctl->dirty.bf.mpr = 1;
- return 0;
-}
-
-static int src_set_clear_zbufs(void *blk, unsigned int clear)
-{
- ((struct src_rsc_ctrl_blk *)blk)->dirty.bf.czbfs = (clear ? 1 : 0);
- return 0;
-}
-
-static int src_set_dirty(void *blk, unsigned int flags)
-{
- ((struct src_rsc_ctrl_blk *)blk)->dirty.data = (flags & 0xffff);
- return 0;
-}
-
-static int src_set_dirty_all(void *blk)
-{
- ((struct src_rsc_ctrl_blk *)blk)->dirty.data = ~(0x0);
- return 0;
-}
-
-#define AR_SLOT_SIZE 4096
-#define AR_SLOT_BLOCK_SIZE 16
-#define AR_PTS_PITCH 6
-#define AR_PARAM_SRC_OFFSET 0x60
-
-static unsigned int src_param_pitch_mixer(unsigned int src_idx)
-{
- return ((src_idx << 4) + AR_PTS_PITCH + AR_SLOT_SIZE
- - AR_PARAM_SRC_OFFSET) % AR_SLOT_SIZE;
-
-}
-
-static int src_commit_write(struct hw *hw, unsigned int idx, void *blk)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
- int i;
-
- if (ctl->dirty.bf.czbfs) {
- /* Clear Z-Buffer registers */
- for (i = 0; i < 8; i++)
- hw_write_20kx(hw, SRC_UPZ+idx*0x100+i*0x4, 0);
-
- for (i = 0; i < 4; i++)
- hw_write_20kx(hw, SRC_DN0Z+idx*0x100+i*0x4, 0);
-
- for (i = 0; i < 8; i++)
- hw_write_20kx(hw, SRC_DN1Z+idx*0x100+i*0x4, 0);
-
- ctl->dirty.bf.czbfs = 0;
- }
- if (ctl->dirty.bf.mpr) {
- /* Take the parameter mixer resource in the same group as that
- * the idx src is in for simplicity. Unlike src, all conjugate
- * parameter mixer resources must be programmed for
- * corresponding conjugate src resources. */
- unsigned int pm_idx = src_param_pitch_mixer(idx);
- hw_write_20kx(hw, MIXER_PRING_LO_HI+4*pm_idx, ctl->mpr);
- hw_write_20kx(hw, MIXER_PMOPLO+8*pm_idx, 0x3);
- hw_write_20kx(hw, MIXER_PMOPHI+8*pm_idx, 0x0);
- ctl->dirty.bf.mpr = 0;
- }
- if (ctl->dirty.bf.sa) {
- hw_write_20kx(hw, SRC_SA+idx*0x100, ctl->sa);
- ctl->dirty.bf.sa = 0;
- }
- if (ctl->dirty.bf.la) {
- hw_write_20kx(hw, SRC_LA+idx*0x100, ctl->la);
- ctl->dirty.bf.la = 0;
- }
- if (ctl->dirty.bf.ca) {
- hw_write_20kx(hw, SRC_CA+idx*0x100, ctl->ca);
- ctl->dirty.bf.ca = 0;
- }
-
- /* Write srccf register */
- hw_write_20kx(hw, SRC_CF+idx*0x100, 0x0);
-
- if (ctl->dirty.bf.ccr) {
- hw_write_20kx(hw, SRC_CCR+idx*0x100, ctl->ccr);
- ctl->dirty.bf.ccr = 0;
- }
- if (ctl->dirty.bf.ctl) {
- hw_write_20kx(hw, SRC_CTL+idx*0x100, ctl->ctl);
- ctl->dirty.bf.ctl = 0;
- }
-
- return 0;
-}
-
-static int src_get_ca(struct hw *hw, unsigned int idx, void *blk)
-{
- struct src_rsc_ctrl_blk *ctl = blk;
-
- ctl->ca = hw_read_20kx(hw, SRC_CA+idx*0x100);
- ctl->dirty.bf.ca = 0;
-
- return get_field(ctl->ca, SRCCA_CA);
-}
-
-static unsigned int src_get_dirty(void *blk)
-{
- return ((struct src_rsc_ctrl_blk *)blk)->dirty.data;
-}
-
-static unsigned int src_dirty_conj_mask(void)
-{
- return 0x20;
-}
-
-static int src_mgr_enbs_src(void *blk, unsigned int idx)
-{
- ((struct src_mgr_ctrl_blk *)blk)->enbsa |= (0x1 << ((idx%128)/4));
- ((struct src_mgr_ctrl_blk *)blk)->dirty.bf.enbsa = 1;
- ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] |= (0x1 << (idx%32));
- return 0;
-}
-
-static int src_mgr_enb_src(void *blk, unsigned int idx)
-{
- ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] |= (0x1 << (idx%32));
- ((struct src_mgr_ctrl_blk *)blk)->dirty.data |= (0x1 << (idx/32));
- return 0;
-}
-
-static int src_mgr_dsb_src(void *blk, unsigned int idx)
-{
- ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] &= ~(0x1 << (idx%32));
- ((struct src_mgr_ctrl_blk *)blk)->dirty.data |= (0x1 << (idx/32));
- return 0;
-}
-
-static int src_mgr_commit_write(struct hw *hw, void *blk)
-{
- struct src_mgr_ctrl_blk *ctl = blk;
- int i;
- unsigned int ret;
-
- if (ctl->dirty.bf.enbsa) {
- do {
- ret = hw_read_20kx(hw, SRC_ENBSTAT);
- } while (ret & 0x1);
- hw_write_20kx(hw, SRC_ENBSA, ctl->enbsa);
- ctl->dirty.bf.enbsa = 0;
- }
- for (i = 0; i < 8; i++) {
- if ((ctl->dirty.data & (0x1 << i))) {
- hw_write_20kx(hw, SRC_ENB+(i*0x100), ctl->enb[i]);
- ctl->dirty.data &= ~(0x1 << i);
- }
- }
-
- return 0;
-}
-
-static int src_mgr_get_ctrl_blk(void **rblk)
-{
- struct src_mgr_ctrl_blk *blk;
-
- *rblk = NULL;
- blk = kzalloc(sizeof(*blk), GFP_KERNEL);
- if (!blk)
- return -ENOMEM;
-
- *rblk = blk;
-
- return 0;
-}
-
-static int src_mgr_put_ctrl_blk(void *blk)
-{
- kfree(blk);
-
- return 0;
-}
-
-static int srcimp_mgr_get_ctrl_blk(void **rblk)
-{
- struct srcimp_mgr_ctrl_blk *blk;
-
- *rblk = NULL;
- blk = kzalloc(sizeof(*blk), GFP_KERNEL);
- if (!blk)
- return -ENOMEM;
-
- *rblk = blk;
-
- return 0;
-}
-
-static int srcimp_mgr_put_ctrl_blk(void *blk)
-{
- kfree(blk);
-
- return 0;
-}
-
-static int srcimp_mgr_set_imaparc(void *blk, unsigned int slot)
-{
- struct srcimp_mgr_ctrl_blk *ctl = blk;
-
- set_field(&ctl->srcimap.srcaim, SRCAIM_ARC, slot);
- ctl->dirty.bf.srcimap = 1;
- return 0;
-}
-
-static int srcimp_mgr_set_imapuser(void *blk, unsigned int user)
-{
- struct srcimp_mgr_ctrl_blk *ctl = blk;
-
- set_field(&ctl->srcimap.srcaim, SRCAIM_SRC, user);
- ctl->dirty.bf.srcimap = 1;
- return 0;
-}
-
-static int srcimp_mgr_set_imapnxt(void *blk, unsigned int next)
-{
- struct srcimp_mgr_ctrl_blk *ctl = blk;
-
- set_field(&ctl->srcimap.srcaim, SRCAIM_NXT, next);
- ctl->dirty.bf.srcimap = 1;
- return 0;
-}
-
-static int srcimp_mgr_set_imapaddr(void *blk, unsigned int addr)
-{
- ((struct srcimp_mgr_ctrl_blk *)blk)->srcimap.idx = addr;
- ((struct srcimp_mgr_ctrl_blk *)blk)->dirty.bf.srcimap = 1;
- return 0;
-}
-
-static int srcimp_mgr_commit_write(struct hw *hw, void *blk)
-{
- struct srcimp_mgr_ctrl_blk *ctl = blk;
-
- if (ctl->dirty.bf.srcimap) {
- hw_write_20kx(hw, SRC_IMAP+ctl->srcimap.idx*0x100,
- ctl->srcimap.srcaim);
- ctl->dirty.bf.srcimap = 0;
- }
-
- return 0;
-}
-
-/*
- * AMIXER control block definitions.
- */
-
-#define AMOPLO_M 0x00000003
-#define AMOPLO_IV 0x00000004
-#define AMOPLO_X 0x0003FFF0
-#define AMOPLO_Y 0xFFFC0000
-
-#define AMOPHI_SADR 0x000000FF
-#define AMOPHI_SE 0x80000000
-
-/* AMIXER resource register dirty flags */
-union amixer_dirty {
- struct {
- u16 amoplo:1;
- u16 amophi:1;
- u16 rsv:14;
- } bf;
- u16 data;
-};
-
-/* AMIXER resource control block */
-struct amixer_rsc_ctrl_blk {
- unsigned int amoplo;
- unsigned int amophi;
- union amixer_dirty dirty;
-};
-
-static int amixer_set_mode(void *blk, unsigned int mode)
-{
- struct amixer_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->amoplo, AMOPLO_M, mode);
- ctl->dirty.bf.amoplo = 1;
- return 0;
-}
-
-static int amixer_set_iv(void *blk, unsigned int iv)
-{
- struct amixer_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->amoplo, AMOPLO_IV, iv);
- ctl->dirty.bf.amoplo = 1;
- return 0;
-}
-
-static int amixer_set_x(void *blk, unsigned int x)
-{
- struct amixer_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->amoplo, AMOPLO_X, x);
- ctl->dirty.bf.amoplo = 1;
- return 0;
-}
-
-static int amixer_set_y(void *blk, unsigned int y)
-{
- struct amixer_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->amoplo, AMOPLO_Y, y);
- ctl->dirty.bf.amoplo = 1;
- return 0;
-}
-
-static int amixer_set_sadr(void *blk, unsigned int sadr)
-{
- struct amixer_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->amophi, AMOPHI_SADR, sadr);
- ctl->dirty.bf.amophi = 1;
- return 0;
-}
-
-static int amixer_set_se(void *blk, unsigned int se)
-{
- struct amixer_rsc_ctrl_blk *ctl = blk;
-
- set_field(&ctl->amophi, AMOPHI_SE, se);
- ctl->dirty.bf.amophi = 1;
- return 0;
-}
-
-static int amixer_set_dirty(void *blk, unsigned int flags)
-{
- ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data = (flags & 0xffff);
- return 0;
-}
-
-static int amixer_set_dirty_all(void *blk)
-{
- ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data = ~(0x0);
- return 0;
-}
-
-static int amixer_commit_write(struct hw *hw, unsigned int idx, void *blk)
-{
- struct amixer_rsc_ctrl_blk *ctl = blk;
-
- if (ctl->dirty.bf.amoplo || ctl->dirty.bf.amophi) {
- hw_write_20kx(hw, MIXER_AMOPLO+idx*8, ctl->amoplo);
- ctl->dirty.bf.amoplo = 0;
- hw_write_20kx(hw, MIXER_AMOPHI+idx*8, ctl->amophi);
- ctl->dirty.bf.amophi = 0;
- }
-
- return 0;
-}
-
-static int amixer_get_y(void *blk)
-{
- struct amixer_rsc_ctrl_blk *ctl = blk;
-
- return get_field(ctl->amoplo, AMOPLO_Y);
-}
-
-static unsigned int amixer_get_dirty(void *blk)
-{
- return ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data;
-}
-
-static int amixer_rsc_get_ctrl_blk(void **rblk)
-{
- struct amixer_rsc_ctrl_blk *blk;
-
- *rblk = NULL;
- blk = kzalloc(sizeof(*blk), GFP_KERNEL);
- if (!blk)
- return -ENOMEM;
-
- *rblk = blk;
-
- return 0;
-}
-
-static int amixer_rsc_put_ctrl_blk(void *blk)
-{
- kfree(blk);
-
- return 0;
-}
-
-static int amixer_mgr_get_ctrl_blk(void **rblk)
-{
- *rblk = NULL;
-
- return 0;
-}
-
-static int amixer_mgr_put_ctrl_blk(void *blk)
-{
- return 0;
-}
-
-/*
- * DAIO control block definitions.
- */
-
-/* Receiver Sample Rate Tracker Control register */
-#define SRTCTL_SRCO 0x000000FF
-#define SRTCTL_SRCM 0x0000FF00
-#define SRTCTL_RSR 0x00030000
-#define SRTCTL_DRAT 0x00300000
-#define SRTCTL_EC 0x01000000
-#define SRTCTL_ET 0x10000000
-
-/* DAIO Receiver register dirty flags */
-union dai_dirty {
- struct {
- u16 srt:1;
- u16 rsv:15;
- } bf;
- u16 data;
-};
-
-/* DAIO Receiver control block */
-struct dai_ctrl_blk {
- unsigned int srt;
- union dai_dirty dirty;
-};
-
-/* Audio Input Mapper RAM */
-#define AIM_ARC 0x00000FFF
-#define AIM_NXT 0x007F0000
-
-struct daoimap {
- unsigned int aim;
- unsigned int idx;
-};
-
-/* Audio Transmitter Control and Status register */
-#define ATXCTL_EN 0x00000001
-#define ATXCTL_MODE 0x00000010
-#define ATXCTL_CD 0x00000020
-#define ATXCTL_RAW 0x00000100
-#define ATXCTL_MT 0x00000200
-#define ATXCTL_NUC 0x00003000
-#define ATXCTL_BEN 0x00010000
-#define ATXCTL_BMUX 0x00700000
-#define ATXCTL_B24 0x01000000
-#define ATXCTL_CPF 0x02000000
-#define ATXCTL_RIV 0x10000000
-#define ATXCTL_LIV 0x20000000
-#define ATXCTL_RSAT 0x40000000
-#define ATXCTL_LSAT 0x80000000
-
-/* XDIF Transmitter register dirty flags */
-union dao_dirty {
- struct {
- u16 atxcsl:1;
- u16 rsv:15;
- } bf;
- u16 data;
-};
-
-/* XDIF Transmitter control block */
-struct dao_ctrl_blk {
- /* XDIF Transmitter Channel Status Low Register */
- unsigned int atxcsl;
- union dao_dirty dirty;
-};
-
-/* Audio Receiver Control register */
-#define ARXCTL_EN 0x00000001
-
-/* DAIO manager register dirty flags */
-union daio_mgr_dirty {
- struct {
- u32 atxctl:8;
- u32 arxctl:8;
- u32 daoimap:1;
- u32 rsv:15;
- } bf;
- u32 data;
-};
-
-/* DAIO manager control block */
-struct daio_mgr_ctrl_blk {
- struct daoimap daoimap;
- unsigned int txctl[8];
- unsigned int rxctl[8];
- union daio_mgr_dirty dirty;
-};
-
-static int dai_srt_set_srco(void *blk, unsigned int src)
-{
- struct dai_ctrl_blk *ctl = blk;
-
- set_field(&ctl->srt, SRTCTL_SRCO, src);
- ctl->dirty.bf.srt = 1;
- return 0;
-}
-
-static int dai_srt_set_srcm(void *blk, unsigned int src)
-{
- struct dai_ctrl_blk *ctl = blk;
-
- set_field(&ctl->srt, SRTCTL_SRCM, src);
- ctl->dirty.bf.srt = 1;
- return 0;
-}
-
-static int dai_srt_set_rsr(void *blk, unsigned int rsr)
-{
- struct dai_ctrl_blk *ctl = blk;
-
- set_field(&ctl->srt, SRTCTL_RSR, rsr);
- ctl->dirty.bf.srt = 1;
- return 0;
-}
-
-static int dai_srt_set_drat(void *blk, unsigned int drat)
-{
- struct dai_ctrl_blk *ctl = blk;
-
- set_field(&ctl->srt, SRTCTL_DRAT, drat);
- ctl->dirty.bf.srt = 1;
- return 0;
-}
-
-static int dai_srt_set_ec(void *blk, unsigned int ec)
-{
- struct dai_ctrl_blk *ctl = blk;
-
- set_field(&ctl->srt, SRTCTL_EC, ec ? 1 : 0);
- ctl->dirty.bf.srt = 1;
- return 0;
-}
-
-static int dai_srt_set_et(void *blk, unsigned int et)
-{
- struct dai_ctrl_blk *ctl = blk;
-
- set_field(&ctl->srt, SRTCTL_ET, et ? 1 : 0);
- ctl->dirty.bf.srt = 1;
- return 0;
-}
-
-static int dai_commit_write(struct hw *hw, unsigned int idx, void *blk)
-{
- struct dai_ctrl_blk *ctl = blk;
-
- if (ctl->dirty.bf.srt) {
- hw_write_20kx(hw, AUDIO_IO_RX_SRT_CTL+0x40*idx, ctl->srt);
- ctl->dirty.bf.srt = 0;
- }
-
- return 0;
-}
-
-static int dai_get_ctrl_blk(void **rblk)
-{
- struct dai_ctrl_blk *blk;
-
- *rblk = NULL;
- blk = kzalloc(sizeof(*blk), GFP_KERNEL);
- if (!blk)
- return -ENOMEM;
-
- *rblk = blk;
-
- return 0;
-}
-
-static int dai_put_ctrl_blk(void *blk)
-{
- kfree(blk);
-
- return 0;
-}
-
-static int dao_set_spos(void *blk, unsigned int spos)
-{
- ((struct dao_ctrl_blk *)blk)->atxcsl = spos;
- ((struct dao_ctrl_blk *)blk)->dirty.bf.atxcsl = 1;
- return 0;
-}
-
-static int dao_commit_write(struct hw *hw, unsigned int idx, void *blk)
-{
- struct dao_ctrl_blk *ctl = blk;
-
- if (ctl->dirty.bf.atxcsl) {
- if (idx < 4) {
- /* S/PDIF SPOSx */
- hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_L+0x40*idx,
- ctl->atxcsl);
- }
- ctl->dirty.bf.atxcsl = 0;
- }
-
- return 0;
-}
-
-static int dao_get_spos(void *blk, unsigned int *spos)
-{
- *spos = ((struct dao_ctrl_blk *)blk)->atxcsl;
- return 0;
-}
-
-static int dao_get_ctrl_blk(void **rblk)
-{
- struct dao_ctrl_blk *blk;
-
- *rblk = NULL;
- blk = kzalloc(sizeof(*blk), GFP_KERNEL);
- if (!blk)
- return -ENOMEM;
-
- *rblk = blk;
-
- return 0;
-}
-
-static int dao_put_ctrl_blk(void *blk)
-{
- kfree(blk);
-
- return 0;
-}
-
-static int daio_mgr_enb_dai(void *blk, unsigned int idx)
-{
- struct daio_mgr_ctrl_blk *ctl = blk;
-
- set_field(&ctl->rxctl[idx], ARXCTL_EN, 1);
- ctl->dirty.bf.arxctl |= (0x1 << idx);
- return 0;
-}
-
-static int daio_mgr_dsb_dai(void *blk, unsigned int idx)
-{
- struct daio_mgr_ctrl_blk *ctl = blk;
-
- set_field(&ctl->rxctl[idx], ARXCTL_EN, 0);
-
- ctl->dirty.bf.arxctl |= (0x1 << idx);
- return 0;
-}
-
-static int daio_mgr_enb_dao(void *blk, unsigned int idx)
-{
- struct daio_mgr_ctrl_blk *ctl = blk;
-
- set_field(&ctl->txctl[idx], ATXCTL_EN, 1);
- ctl->dirty.bf.atxctl |= (0x1 << idx);
- return 0;
-}
-
-static int daio_mgr_dsb_dao(void *blk, unsigned int idx)
-{
- struct daio_mgr_ctrl_blk *ctl = blk;
-
- set_field(&ctl->txctl[idx], ATXCTL_EN, 0);
- ctl->dirty.bf.atxctl |= (0x1 << idx);
- return 0;
-}
-
-static int daio_mgr_dao_init(void *blk, unsigned int idx, unsigned int conf)
-{
- struct daio_mgr_ctrl_blk *ctl = blk;
-
- if (idx < 4) {
- /* S/PDIF output */
- switch ((conf & 0x7)) {
- case 1:
- set_field(&ctl->txctl[idx], ATXCTL_NUC, 0);
- break;
- case 2:
- set_field(&ctl->txctl[idx], ATXCTL_NUC, 1);
- break;
- case 4:
- set_field(&ctl->txctl[idx], ATXCTL_NUC, 2);
- break;
- case 8:
- set_field(&ctl->txctl[idx], ATXCTL_NUC, 3);
- break;
- default:
- break;
- }
- /* CDIF */
- set_field(&ctl->txctl[idx], ATXCTL_CD, (!(conf & 0x7)));
- /* Non-audio */
- set_field(&ctl->txctl[idx], ATXCTL_LIV, (conf >> 4) & 0x1);
- /* Non-audio */
- set_field(&ctl->txctl[idx], ATXCTL_RIV, (conf >> 4) & 0x1);
- set_field(&ctl->txctl[idx], ATXCTL_RAW,
- ((conf >> 3) & 0x1) ? 0 : 0);
- ctl->dirty.bf.atxctl |= (0x1 << idx);
- } else {
- /* I2S output */
- /*idx %= 4; */
- }
- return 0;
-}
-
-static int daio_mgr_set_imaparc(void *blk, unsigned int slot)
-{
- struct daio_mgr_ctrl_blk *ctl = blk;
-
- set_field(&ctl->daoimap.aim, AIM_ARC, slot);
- ctl->dirty.bf.daoimap = 1;
- return 0;
-}
-
-static int daio_mgr_set_imapnxt(void *blk, unsigned int next)
-{
- struct daio_mgr_ctrl_blk *ctl = blk;
-
- set_field(&ctl->daoimap.aim, AIM_NXT, next);
- ctl->dirty.bf.daoimap = 1;
- return 0;
-}
-
-static int daio_mgr_set_imapaddr(void *blk, unsigned int addr)
-{
- ((struct daio_mgr_ctrl_blk *)blk)->daoimap.idx = addr;
- ((struct daio_mgr_ctrl_blk *)blk)->dirty.bf.daoimap = 1;
- return 0;
-}
-
-static int daio_mgr_commit_write(struct hw *hw, void *blk)
-{
- struct daio_mgr_ctrl_blk *ctl = blk;
- unsigned int data;
- int i;
-
- for (i = 0; i < 8; i++) {
- if ((ctl->dirty.bf.atxctl & (0x1 << i))) {
- data = ctl->txctl[i];
- hw_write_20kx(hw, (AUDIO_IO_TX_CTL+(0x40*i)), data);
- ctl->dirty.bf.atxctl &= ~(0x1 << i);
- mdelay(1);
- }
- if ((ctl->dirty.bf.arxctl & (0x1 << i))) {
- data = ctl->rxctl[i];
- hw_write_20kx(hw, (AUDIO_IO_RX_CTL+(0x40*i)), data);
- ctl->dirty.bf.arxctl &= ~(0x1 << i);
- mdelay(1);
- }
- }
- if (ctl->dirty.bf.daoimap) {
- hw_write_20kx(hw, AUDIO_IO_AIM+ctl->daoimap.idx*4,
- ctl->daoimap.aim);
- ctl->dirty.bf.daoimap = 0;
- }
-
- return 0;
-}
-
-static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk)
-{
- struct daio_mgr_ctrl_blk *blk;
- int i;
-
- *rblk = NULL;
- blk = kzalloc(sizeof(*blk), GFP_KERNEL);
- if (!blk)
- return -ENOMEM;
-
- for (i = 0; i < 8; i++) {
- blk->txctl[i] = hw_read_20kx(hw, AUDIO_IO_TX_CTL+(0x40*i));
- blk->rxctl[i] = hw_read_20kx(hw, AUDIO_IO_RX_CTL+(0x40*i));
- }
-
- *rblk = blk;
-
- return 0;
-}
-
-static int daio_mgr_put_ctrl_blk(void *blk)
-{
- kfree(blk);
-
- return 0;
-}
-
-/* Timer interrupt */
-static int set_timer_irq(struct hw *hw, int enable)
-{
- hw_write_20kx(hw, GIE, enable ? IT_INT : 0);
- return 0;
-}
-
-static int set_timer_tick(struct hw *hw, unsigned int ticks)
-{
- if (ticks)
- ticks |= TIMR_IE | TIMR_IP;
- hw_write_20kx(hw, TIMR, ticks);
- return 0;
-}
-
-static unsigned int get_wc(struct hw *hw)
-{
- return hw_read_20kx(hw, WC);
-}
-
-/* Card hardware initialization block */
-struct dac_conf {
- unsigned int msr; /* master sample rate in rsrs */
-};
-
-struct adc_conf {
- unsigned int msr; /* master sample rate in rsrs */
- unsigned char input; /* the input source of ADC */
- unsigned char mic20db; /* boost mic by 20db if input is microphone */
-};
-
-struct daio_conf {
- unsigned int msr; /* master sample rate in rsrs */
-};
-
-struct trn_conf {
- unsigned long vm_pgt_phys;
-};
-
-static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
-{
- u32 data;
- int i;
-
- /* Program I2S with proper sample rate and enable the correct I2S
- * channel. ED(0/8/16/24): Enable all I2S/I2X master clock output */
- if (1 == info->msr) {
- hw_write_20kx(hw, AUDIO_IO_MCLK, 0x01010101);
- hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x01010101);
- hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
- } else if (2 == info->msr) {
- if (hw->model != CTSB1270) {
- hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11111111);
- } else {
- /* PCM4220 on Titanium HD is different. */
- hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11011111);
- }
- /* Specify all playing 96khz
- * EA [0] - Enabled
- * RTA [4:5] - 96kHz
- * EB [8] - Enabled
- * RTB [12:13] - 96kHz
- * EC [16] - Enabled
- * RTC [20:21] - 96kHz
- * ED [24] - Enabled
- * RTD [28:29] - 96kHz */
- hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x11111111);
- hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
- } else if ((4 == info->msr) && (hw->model == CTSB1270)) {
- hw_write_20kx(hw, AUDIO_IO_MCLK, 0x21011111);
- hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x21212121);
- hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
- } else {
- printk(KERN_ALERT "ctxfi: ERROR!!! Invalid sampling rate!!!\n");
- return -EINVAL;
- }
-
- for (i = 0; i < 8; i++) {
- if (i <= 3) {
- /* This comment looks wrong since loop is over 4 */
- /* channels and emu20k2 supports 4 spdif IOs. */
- /* 1st 3 channels are SPDIFs (SB0960) */
- if (i == 3)
- data = 0x1001001;
- else
- data = 0x1000001;
-
- hw_write_20kx(hw, (AUDIO_IO_TX_CTL+(0x40*i)), data);
- hw_write_20kx(hw, (AUDIO_IO_RX_CTL+(0x40*i)), data);
-
- /* Initialize the SPDIF Out Channel status registers.
- * The value specified here is based on the typical
- * values provided in the specification, namely: Clock
- * Accuracy of 1000ppm, Sample Rate of 48KHz,
- * unspecified source number, Generation status = 1,
- * Category code = 0x12 (Digital Signal Mixer),
- * Mode = 0, Emph = 0, Copy Permitted, AN = 0
- * (indicating that we're transmitting digital audio,
- * and the Professional Use bit is 0. */
-
- hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_L+(0x40*i),
- 0x02109204); /* Default to 48kHz */
-
- hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_H+(0x40*i), 0x0B);
- } else {
- /* Again, loop is over 4 channels not 5. */
- /* Next 5 channels are I2S (SB0960) */
- data = 0x11;
- hw_write_20kx(hw, AUDIO_IO_RX_CTL+(0x40*i), data);
- if (2 == info->msr) {
- /* Four channels per sample period */
- data |= 0x1000;
- } else if (4 == info->msr) {
- /* FIXME: check this against the chip spec */
- data |= 0x2000;
- }
- hw_write_20kx(hw, AUDIO_IO_TX_CTL+(0x40*i), data);
- }
- }
-
- return 0;
-}
-
-/* TRANSPORT operations */
-static int hw_trn_init(struct hw *hw, const struct trn_conf *info)
-{
- u32 vmctl, data;
- u32 ptp_phys_low, ptp_phys_high;
- int i;
-
- /* Set up device page table */
- if ((~0UL) == info->vm_pgt_phys) {
- printk(KERN_ALERT "ctxfi: "
- "Wrong device page table page address!!!\n");
- return -1;
- }
-
- vmctl = 0x80000C0F; /* 32-bit, 4k-size page */
- ptp_phys_low = (u32)info->vm_pgt_phys;
- ptp_phys_high = upper_32_bits(info->vm_pgt_phys);
- if (sizeof(void *) == 8) /* 64bit address */
- vmctl |= (3 << 8);
- /* Write page table physical address to all PTPAL registers */
- for (i = 0; i < 64; i++) {
- hw_write_20kx(hw, VMEM_PTPAL+(16*i), ptp_phys_low);
- hw_write_20kx(hw, VMEM_PTPAH+(16*i), ptp_phys_high);
- }
- /* Enable virtual memory transfer */
- hw_write_20kx(hw, VMEM_CTL, vmctl);
- /* Enable transport bus master and queueing of request */
- hw_write_20kx(hw, TRANSPORT_CTL, 0x03);
- hw_write_20kx(hw, TRANSPORT_INT, 0x200c01);
- /* Enable transport ring */
- data = hw_read_20kx(hw, TRANSPORT_ENB);
- hw_write_20kx(hw, TRANSPORT_ENB, (data | 0x03));
-
- return 0;
-}
-
-/* Card initialization */
-#define GCTL_AIE 0x00000001
-#define GCTL_UAA 0x00000002
-#define GCTL_DPC 0x00000004
-#define GCTL_DBP 0x00000008
-#define GCTL_ABP 0x00000010
-#define GCTL_TBP 0x00000020
-#define GCTL_SBP 0x00000040
-#define GCTL_FBP 0x00000080
-#define GCTL_ME 0x00000100
-#define GCTL_AID 0x00001000
-
-#define PLLCTL_SRC 0x00000007
-#define PLLCTL_SPE 0x00000008
-#define PLLCTL_RD 0x000000F0
-#define PLLCTL_FD 0x0001FF00
-#define PLLCTL_OD 0x00060000
-#define PLLCTL_B 0x00080000
-#define PLLCTL_AS 0x00100000
-#define PLLCTL_LF 0x03E00000
-#define PLLCTL_SPS 0x1C000000
-#define PLLCTL_AD 0x60000000
-
-#define PLLSTAT_CCS 0x00000007
-#define PLLSTAT_SPL 0x00000008
-#define PLLSTAT_CRD 0x000000F0
-#define PLLSTAT_CFD 0x0001FF00
-#define PLLSTAT_SL 0x00020000
-#define PLLSTAT_FAS 0x00040000
-#define PLLSTAT_B 0x00080000
-#define PLLSTAT_PD 0x00100000
-#define PLLSTAT_OCA 0x00200000
-#define PLLSTAT_NCA 0x00400000
-
-static int hw_pll_init(struct hw *hw, unsigned int rsr)
-{
- unsigned int pllenb;
- unsigned int pllctl;
- unsigned int pllstat;
- int i;
-
- pllenb = 0xB;
- hw_write_20kx(hw, PLL_ENB, pllenb);
- pllctl = 0x20C00000;
- set_field(&pllctl, PLLCTL_B, 0);
- set_field(&pllctl, PLLCTL_FD, 48000 == rsr ? 16 - 4 : 147 - 4);
- set_field(&pllctl, PLLCTL_RD, 48000 == rsr ? 1 - 1 : 10 - 1);
- hw_write_20kx(hw, PLL_CTL, pllctl);
- mdelay(40);
-
- pllctl = hw_read_20kx(hw, PLL_CTL);
- set_field(&pllctl, PLLCTL_FD, 48000 == rsr ? 16 - 2 : 147 - 2);
- hw_write_20kx(hw, PLL_CTL, pllctl);
- mdelay(40);
-
- for (i = 0; i < 1000; i++) {
- pllstat = hw_read_20kx(hw, PLL_STAT);
- if (get_field(pllstat, PLLSTAT_PD))
- continue;
-
- if (get_field(pllstat, PLLSTAT_B) !=
- get_field(pllctl, PLLCTL_B))
- continue;
-
- if (get_field(pllstat, PLLSTAT_CCS) !=
- get_field(pllctl, PLLCTL_SRC))
- continue;
-
- if (get_field(pllstat, PLLSTAT_CRD) !=
- get_field(pllctl, PLLCTL_RD))
- continue;
-
- if (get_field(pllstat, PLLSTAT_CFD) !=
- get_field(pllctl, PLLCTL_FD))
- continue;
-
- break;
- }
- if (i >= 1000) {
- printk(KERN_ALERT "ctxfi: PLL initialization failed!!!\n");
- return -EBUSY;
- }
-
- return 0;
-}
-
-static int hw_auto_init(struct hw *hw)
-{
- unsigned int gctl;
- int i;
-
- gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL);
- set_field(&gctl, GCTL_AIE, 0);
- hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);
- set_field(&gctl, GCTL_AIE, 1);
- hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);
- mdelay(10);
- for (i = 0; i < 400000; i++) {
- gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL);
- if (get_field(gctl, GCTL_AID))
- break;
- }
- if (!get_field(gctl, GCTL_AID)) {
- printk(KERN_ALERT "ctxfi: Card Auto-init failed!!!\n");
- return -EBUSY;
- }
-
- return 0;
-}
-
-/* DAC operations */
-
-#define CS4382_MC1 0x1
-#define CS4382_MC2 0x2
-#define CS4382_MC3 0x3
-#define CS4382_FC 0x4
-#define CS4382_IC 0x5
-#define CS4382_XC1 0x6
-#define CS4382_VCA1 0x7
-#define CS4382_VCB1 0x8
-#define CS4382_XC2 0x9
-#define CS4382_VCA2 0xA
-#define CS4382_VCB2 0xB
-#define CS4382_XC3 0xC
-#define CS4382_VCA3 0xD
-#define CS4382_VCB3 0xE
-#define CS4382_XC4 0xF
-#define CS4382_VCA4 0x10
-#define CS4382_VCB4 0x11
-#define CS4382_CREV 0x12
-
-/* I2C status */
-#define STATE_LOCKED 0x00
-#define STATE_UNLOCKED 0xAA
-#define DATA_READY 0x800000 /* Used with I2C_IF_STATUS */
-#define DATA_ABORT 0x10000 /* Used with I2C_IF_STATUS */
-
-#define I2C_STATUS_DCM 0x00000001
-#define I2C_STATUS_BC 0x00000006
-#define I2C_STATUS_APD 0x00000008
-#define I2C_STATUS_AB 0x00010000
-#define I2C_STATUS_DR 0x00800000
-
-#define I2C_ADDRESS_PTAD 0x0000FFFF
-#define I2C_ADDRESS_SLAD 0x007F0000
-
-struct regs_cs4382 {
- u32 mode_control_1;
- u32 mode_control_2;
- u32 mode_control_3;
-
- u32 filter_control;
- u32 invert_control;
-
- u32 mix_control_P1;
- u32 vol_control_A1;
- u32 vol_control_B1;
-
- u32 mix_control_P2;
- u32 vol_control_A2;
- u32 vol_control_B2;
-
- u32 mix_control_P3;
- u32 vol_control_A3;
- u32 vol_control_B3;
-
- u32 mix_control_P4;
- u32 vol_control_A4;
- u32 vol_control_B4;
-};
-
-static int hw20k2_i2c_unlock_full_access(struct hw *hw)
-{
- u8 UnlockKeySequence_FLASH_FULLACCESS_MODE[2] = {0xB3, 0xD4};
-
- /* Send keys for forced BIOS mode */
- hw_write_20kx(hw, I2C_IF_WLOCK,
- UnlockKeySequence_FLASH_FULLACCESS_MODE[0]);
- hw_write_20kx(hw, I2C_IF_WLOCK,
- UnlockKeySequence_FLASH_FULLACCESS_MODE[1]);
- /* Check whether the chip is unlocked */
- if (hw_read_20kx(hw, I2C_IF_WLOCK) == STATE_UNLOCKED)
- return 0;
-
- return -1;
-}
-
-static int hw20k2_i2c_lock_chip(struct hw *hw)
-{
- /* Write twice */
- hw_write_20kx(hw, I2C_IF_WLOCK, STATE_LOCKED);
- hw_write_20kx(hw, I2C_IF_WLOCK, STATE_LOCKED);
- if (hw_read_20kx(hw, I2C_IF_WLOCK) == STATE_LOCKED)
- return 0;
-
- return -1;
-}
-
-static int hw20k2_i2c_init(struct hw *hw, u8 dev_id, u8 addr_size, u8 data_size)
-{
- struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;
- int err;
- unsigned int i2c_status;
- unsigned int i2c_addr;
-
- err = hw20k2_i2c_unlock_full_access(hw);
- if (err < 0)
- return err;
-
- hw20k2->addr_size = addr_size;
- hw20k2->data_size = data_size;
- hw20k2->dev_id = dev_id;
-
- i2c_addr = 0;
- set_field(&i2c_addr, I2C_ADDRESS_SLAD, dev_id);
-
- hw_write_20kx(hw, I2C_IF_ADDRESS, i2c_addr);
-
- i2c_status = hw_read_20kx(hw, I2C_IF_STATUS);
-
- set_field(&i2c_status, I2C_STATUS_DCM, 1); /* Direct control mode */
-
- hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);
-
- return 0;
-}
-
-static int hw20k2_i2c_uninit(struct hw *hw)
-{
- unsigned int i2c_status;
- unsigned int i2c_addr;
-
- i2c_addr = 0;
- set_field(&i2c_addr, I2C_ADDRESS_SLAD, 0x57); /* I2C id */
-
- hw_write_20kx(hw, I2C_IF_ADDRESS, i2c_addr);
-
- i2c_status = hw_read_20kx(hw, I2C_IF_STATUS);
-
- set_field(&i2c_status, I2C_STATUS_DCM, 0); /* I2C mode */
-
- hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);
-
- return hw20k2_i2c_lock_chip(hw);
-}
-
-static int hw20k2_i2c_wait_data_ready(struct hw *hw)
-{
- int i = 0x400000;
- unsigned int ret;
-
- do {
- ret = hw_read_20kx(hw, I2C_IF_STATUS);
- } while ((!(ret & DATA_READY)) && --i);
-
- return i;
-}
-
-static int hw20k2_i2c_read(struct hw *hw, u16 addr, u32 *datap)
-{
- struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;
- unsigned int i2c_status;
-
- i2c_status = hw_read_20kx(hw, I2C_IF_STATUS);
- set_field(&i2c_status, I2C_STATUS_BC,
- (4 == hw20k2->addr_size) ? 0 : hw20k2->addr_size);
- hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);
- if (!hw20k2_i2c_wait_data_ready(hw))
- return -1;
-
- hw_write_20kx(hw, I2C_IF_WDATA, addr);
- if (!hw20k2_i2c_wait_data_ready(hw))
- return -1;
-
- /* Force a read operation */
- hw_write_20kx(hw, I2C_IF_RDATA, 0);
- if (!hw20k2_i2c_wait_data_ready(hw))
- return -1;
-
- *datap = hw_read_20kx(hw, I2C_IF_RDATA);
-
- return 0;
-}
-
-static int hw20k2_i2c_write(struct hw *hw, u16 addr, u32 data)
-{
- struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;
- unsigned int i2c_data = (data << (hw20k2->addr_size * 8)) | addr;
- unsigned int i2c_status;
-
- i2c_status = hw_read_20kx(hw, I2C_IF_STATUS);
-
- set_field(&i2c_status, I2C_STATUS_BC,
- (4 == (hw20k2->addr_size + hw20k2->data_size)) ?
- 0 : (hw20k2->addr_size + hw20k2->data_size));
-
- hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);
- hw20k2_i2c_wait_data_ready(hw);
- /* Dummy write to trigger the write operation */
- hw_write_20kx(hw, I2C_IF_WDATA, 0);
- hw20k2_i2c_wait_data_ready(hw);
-
- /* This is the real data */
- hw_write_20kx(hw, I2C_IF_WDATA, i2c_data);
- hw20k2_i2c_wait_data_ready(hw);
-
- return 0;
-}
-
-static void hw_dac_stop(struct hw *hw)
-{
- u32 data;
- data = hw_read_20kx(hw, GPIO_DATA);
- data &= 0xFFFFFFFD;
- hw_write_20kx(hw, GPIO_DATA, data);
- mdelay(10);
-}
-
-static void hw_dac_start(struct hw *hw)
-{
- u32 data;
- data = hw_read_20kx(hw, GPIO_DATA);
- data |= 0x2;
- hw_write_20kx(hw, GPIO_DATA, data);
- mdelay(50);
-}
-
-static void hw_dac_reset(struct hw *hw)
-{
- hw_dac_stop(hw);
- hw_dac_start(hw);
-}
-
-static int hw_dac_init(struct hw *hw, const struct dac_conf *info)
-{
- int err;
- u32 data;
- int i;
- struct regs_cs4382 cs_read = {0};
- struct regs_cs4382 cs_def = {
- 0x00000001, /* Mode Control 1 */
- 0x00000000, /* Mode Control 2 */
- 0x00000084, /* Mode Control 3 */
- 0x00000000, /* Filter Control */
- 0x00000000, /* Invert Control */
- 0x00000024, /* Mixing Control Pair 1 */
- 0x00000000, /* Vol Control A1 */
- 0x00000000, /* Vol Control B1 */
- 0x00000024, /* Mixing Control Pair 2 */
- 0x00000000, /* Vol Control A2 */
- 0x00000000, /* Vol Control B2 */
- 0x00000024, /* Mixing Control Pair 3 */
- 0x00000000, /* Vol Control A3 */
- 0x00000000, /* Vol Control B3 */
- 0x00000024, /* Mixing Control Pair 4 */
- 0x00000000, /* Vol Control A4 */
- 0x00000000 /* Vol Control B4 */
- };
-
- if (hw->model == CTSB1270) {
- hw_dac_stop(hw);
- data = hw_read_20kx(hw, GPIO_DATA);
- data &= ~0x0600;
- if (1 == info->msr)
- data |= 0x0000; /* Single Speed Mode 0-50kHz */
- else if (2 == info->msr)
- data |= 0x0200; /* Double Speed Mode 50-100kHz */
- else
- data |= 0x0600; /* Quad Speed Mode 100-200kHz */
- hw_write_20kx(hw, GPIO_DATA, data);
- hw_dac_start(hw);
- return 0;
- }
-
- /* Set DAC reset bit as output */
- data = hw_read_20kx(hw, GPIO_CTRL);
- data |= 0x02;
- hw_write_20kx(hw, GPIO_CTRL, data);
-
- err = hw20k2_i2c_init(hw, 0x18, 1, 1);
- if (err < 0)
- goto End;
-
- for (i = 0; i < 2; i++) {
- /* Reset DAC twice just in-case the chip
- * didn't initialized properly */
- hw_dac_reset(hw);
- hw_dac_reset(hw);
-
- if (hw20k2_i2c_read(hw, CS4382_MC1, &cs_read.mode_control_1))
- continue;
-
- if (hw20k2_i2c_read(hw, CS4382_MC2, &cs_read.mode_control_2))
- continue;
-
- if (hw20k2_i2c_read(hw, CS4382_MC3, &cs_read.mode_control_3))
- continue;
-
- if (hw20k2_i2c_read(hw, CS4382_FC, &cs_read.filter_control))
- continue;
-
- if (hw20k2_i2c_read(hw, CS4382_IC, &cs_read.invert_control))
- continue;
-
- if (hw20k2_i2c_read(hw, CS4382_XC1, &cs_read.mix_control_P1))
- continue;
-
- if (hw20k2_i2c_read(hw, CS4382_VCA1, &cs_read.vol_control_A1))
- continue;
-
- if (hw20k2_i2c_read(hw, CS4382_VCB1, &cs_read.vol_control_B1))
- continue;
-
- if (hw20k2_i2c_read(hw, CS4382_XC2, &cs_read.mix_control_P2))
- continue;
-
- if (hw20k2_i2c_read(hw, CS4382_VCA2, &cs_read.vol_control_A2))
- continue;
-
- if (hw20k2_i2c_read(hw, CS4382_VCB2, &cs_read.vol_control_B2))
- continue;
-
- if (hw20k2_i2c_read(hw, CS4382_XC3, &cs_read.mix_control_P3))
- continue;
-
- if (hw20k2_i2c_read(hw, CS4382_VCA3, &cs_read.vol_control_A3))
- continue;
-
- if (hw20k2_i2c_read(hw, CS4382_VCB3, &cs_read.vol_control_B3))
- continue;
-
- if (hw20k2_i2c_read(hw, CS4382_XC4, &cs_read.mix_control_P4))
- continue;
-
- if (hw20k2_i2c_read(hw, CS4382_VCA4, &cs_read.vol_control_A4))
- continue;
-
- if (hw20k2_i2c_read(hw, CS4382_VCB4, &cs_read.vol_control_B4))
- continue;
-
- if (memcmp(&cs_read, &cs_def, sizeof(cs_read)))
- continue;
- else
- break;
- }
-
- if (i >= 2)
- goto End;
-
- /* Note: Every I2C write must have some delay.
- * This is not a requirement but the delay works here... */
- hw20k2_i2c_write(hw, CS4382_MC1, 0x80);
- hw20k2_i2c_write(hw, CS4382_MC2, 0x10);
- if (1 == info->msr) {
- hw20k2_i2c_write(hw, CS4382_XC1, 0x24);
- hw20k2_i2c_write(hw, CS4382_XC2, 0x24);
- hw20k2_i2c_write(hw, CS4382_XC3, 0x24);
- hw20k2_i2c_write(hw, CS4382_XC4, 0x24);
- } else if (2 == info->msr) {
- hw20k2_i2c_write(hw, CS4382_XC1, 0x25);
- hw20k2_i2c_write(hw, CS4382_XC2, 0x25);
- hw20k2_i2c_write(hw, CS4382_XC3, 0x25);
- hw20k2_i2c_write(hw, CS4382_XC4, 0x25);
- } else {
- hw20k2_i2c_write(hw, CS4382_XC1, 0x26);
- hw20k2_i2c_write(hw, CS4382_XC2, 0x26);
- hw20k2_i2c_write(hw, CS4382_XC3, 0x26);
- hw20k2_i2c_write(hw, CS4382_XC4, 0x26);
- }
-
- return 0;
-End:
-
- hw20k2_i2c_uninit(hw);
- return -1;
-}
-
-/* ADC operations */
-#define MAKE_WM8775_ADDR(addr, data) (u32)(((addr<<1)&0xFE)|((data>>8)&0x1))
-#define MAKE_WM8775_DATA(data) (u32)(data&0xFF)
-
-#define WM8775_IC 0x0B
-#define WM8775_MMC 0x0C
-#define WM8775_AADCL 0x0E
-#define WM8775_AADCR 0x0F
-#define WM8775_ADCMC 0x15
-#define WM8775_RESET 0x17
-
-static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type)
-{
- u32 data;
- if (hw->model == CTSB1270) {
- /* Titanium HD has two ADC chips, one for line in and one */
- /* for MIC. We don't need to switch the ADC input. */
- return 1;
- }
- data = hw_read_20kx(hw, GPIO_DATA);
- switch (type) {
- case ADC_MICIN:
- data = (data & (0x1 << 14)) ? 1 : 0;
- break;
- case ADC_LINEIN:
- data = (data & (0x1 << 14)) ? 0 : 1;
- break;
- default:
- data = 0;
- }
- return data;
-}
-
-#define MIC_BOOST_0DB 0xCF
-#define MIC_BOOST_STEPS_PER_DB 2
-
-static void hw_wm8775_input_select(struct hw *hw, u8 input, s8 gain_in_db)
-{
- u32 adcmc, gain;
-
- if (input > 3)
- input = 3;
-
- adcmc = ((u32)1 << input) | 0x100; /* Link L+R gain... */
-
- hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, adcmc),
- MAKE_WM8775_DATA(adcmc));
-
- if (gain_in_db < -103)
- gain_in_db = -103;
- if (gain_in_db > 24)
- gain_in_db = 24;
-
- gain = gain_in_db * MIC_BOOST_STEPS_PER_DB + MIC_BOOST_0DB;
-
- hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, gain),
- MAKE_WM8775_DATA(gain));
- /* ...so there should be no need for the following. */
- hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, gain),
- MAKE_WM8775_DATA(gain));
-}
-
-static int hw_adc_input_select(struct hw *hw, enum ADCSRC type)
-{
- u32 data;
- data = hw_read_20kx(hw, GPIO_DATA);
- switch (type) {
- case ADC_MICIN:
- data |= (0x1 << 14);
- hw_write_20kx(hw, GPIO_DATA, data);
- hw_wm8775_input_select(hw, 0, 20); /* Mic, 20dB */
- break;
- case ADC_LINEIN:
- data &= ~(0x1 << 14);
- hw_write_20kx(hw, GPIO_DATA, data);
- hw_wm8775_input_select(hw, 1, 0); /* Line-in, 0dB */
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
-{
- int err;
- u32 data, ctl;
-
- /* Set ADC reset bit as output */
- data = hw_read_20kx(hw, GPIO_CTRL);
- data |= (0x1 << 15);
- hw_write_20kx(hw, GPIO_CTRL, data);
-
- /* Initialize I2C */
- err = hw20k2_i2c_init(hw, 0x1A, 1, 1);
- if (err < 0) {
- printk(KERN_ALERT "ctxfi: Failure to acquire I2C!!!\n");
- goto error;
- }
-
- /* Reset the ADC (reset is active low). */
- data = hw_read_20kx(hw, GPIO_DATA);
- data &= ~(0x1 << 15);
- hw_write_20kx(hw, GPIO_DATA, data);
-
- if (hw->model == CTSB1270) {
- /* Set up the PCM4220 ADC on Titanium HD */
- data &= ~0x0C;
- if (1 == info->msr)
- data |= 0x00; /* Single Speed Mode 32-50kHz */
- else if (2 == info->msr)
- data |= 0x08; /* Double Speed Mode 50-108kHz */
- else
- data |= 0x04; /* Quad Speed Mode 108kHz-216kHz */
- hw_write_20kx(hw, GPIO_DATA, data);
- }
-
- mdelay(10);
- /* Return the ADC to normal operation. */
- data |= (0x1 << 15);
- hw_write_20kx(hw, GPIO_DATA, data);
- mdelay(50);
-
- /* I2C write to register offset 0x0B to set ADC LRCLK polarity */
- /* invert bit, interface format to I2S, word length to 24-bit, */
- /* enable ADC high pass filter. Fixes bug 5323? */
- hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_IC, 0x26),
- MAKE_WM8775_DATA(0x26));
-
- /* Set the master mode (256fs) */
- if (1 == info->msr) {
- /* slave mode, 128x oversampling 256fs */
- hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x02),
- MAKE_WM8775_DATA(0x02));
- } else if ((2 == info->msr) || (4 == info->msr)) {
- /* slave mode, 64x oversampling, 256fs */
- hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x0A),
- MAKE_WM8775_DATA(0x0A));
- } else {
- printk(KERN_ALERT "ctxfi: Invalid master sampling "
- "rate (msr %d)!!!\n", info->msr);
- err = -EINVAL;
- goto error;
- }
-
- if (hw->model != CTSB1270) {
- /* Configure GPIO bit 14 change to line-in/mic-in */
- ctl = hw_read_20kx(hw, GPIO_CTRL);
- ctl |= 0x1 << 14;
- hw_write_20kx(hw, GPIO_CTRL, ctl);
- hw_adc_input_select(hw, ADC_LINEIN);
- } else {
- hw_wm8775_input_select(hw, 0, 0);
- }
-
- return 0;
-error:
- hw20k2_i2c_uninit(hw);
- return err;
-}
-
-static struct capabilities hw_capabilities(struct hw *hw)
-{
- struct capabilities cap;
-
- cap.digit_io_switch = 0;
- cap.dedicated_mic = hw->model == CTSB1270;
- cap.output_switch = hw->model == CTSB1270;
- cap.mic_source_switch = hw->model == CTSB1270;
-
- return cap;
-}
-
-static int hw_output_switch_get(struct hw *hw)
-{
- u32 data = hw_read_20kx(hw, GPIO_EXT_DATA);
-
- switch (data & 0x30) {
- case 0x00:
- return 0;
- case 0x10:
- return 1;
- case 0x20:
- return 2;
- default:
- return 3;
- }
-}
-
-static int hw_output_switch_put(struct hw *hw, int position)
-{
- u32 data;
-
- if (position == hw_output_switch_get(hw))
- return 0;
-
- /* Mute line and headphones (intended for anti-pop). */
- data = hw_read_20kx(hw, GPIO_DATA);
- data |= (0x03 << 11);
- hw_write_20kx(hw, GPIO_DATA, data);
-
- data = hw_read_20kx(hw, GPIO_EXT_DATA) & ~0x30;
- switch (position) {
- case 0:
- break;
- case 1:
- data |= 0x10;
- break;
- default:
- data |= 0x20;
- }
- hw_write_20kx(hw, GPIO_EXT_DATA, data);
-
- /* Unmute line and headphones. */
- data = hw_read_20kx(hw, GPIO_DATA);
- data &= ~(0x03 << 11);
- hw_write_20kx(hw, GPIO_DATA, data);
-
- return 1;
-}
-
-static int hw_mic_source_switch_get(struct hw *hw)
-{
- struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;
-
- return hw20k2->mic_source;
-}
-
-static int hw_mic_source_switch_put(struct hw *hw, int position)
-{
- struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;
-
- if (position == hw20k2->mic_source)
- return 0;
-
- switch (position) {
- case 0:
- hw_wm8775_input_select(hw, 0, 0); /* Mic, 0dB */
- break;
- case 1:
- hw_wm8775_input_select(hw, 1, 0); /* FP Mic, 0dB */
- break;
- case 2:
- hw_wm8775_input_select(hw, 3, 0); /* Aux Ext, 0dB */
- break;
- default:
- return 0;
- }
-
- hw20k2->mic_source = position;
-
- return 1;
-}
-
-static irqreturn_t ct_20k2_interrupt(int irq, void *dev_id)
-{
- struct hw *hw = dev_id;
- unsigned int status;
-
- status = hw_read_20kx(hw, GIP);
- if (!status)
- return IRQ_NONE;
-
- if (hw->irq_callback)
- hw->irq_callback(hw->irq_callback_data, status);
-
- hw_write_20kx(hw, GIP, status);
- return IRQ_HANDLED;
-}
-
-static int hw_card_start(struct hw *hw)
-{
- int err = 0;
- struct pci_dev *pci = hw->pci;
- unsigned int gctl;
-
- err = pci_enable_device(pci);
- if (err < 0)
- return err;
-
- /* Set DMA transfer mask */
- if (pci_set_dma_mask(pci, CT_XFI_DMA_MASK) < 0 ||
- pci_set_consistent_dma_mask(pci, CT_XFI_DMA_MASK) < 0) {
- printk(KERN_ERR "ctxfi: architecture does not support PCI "
- "busmaster DMA with mask 0x%llx\n", CT_XFI_DMA_MASK);
- err = -ENXIO;
- goto error1;
- }
-
- if (!hw->io_base) {
- err = pci_request_regions(pci, "XFi");
- if (err < 0)
- goto error1;
-
- hw->io_base = pci_resource_start(hw->pci, 2);
- hw->mem_base = (unsigned long)ioremap(hw->io_base,
- pci_resource_len(hw->pci, 2));
- if (!hw->mem_base) {
- err = -ENOENT;
- goto error2;
- }
- }
-
- /* Switch to 20k2 mode from UAA mode. */
- gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL);
- set_field(&gctl, GCTL_UAA, 0);
- hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);
-
- if (hw->irq < 0) {
- err = request_irq(pci->irq, ct_20k2_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, hw);
- if (err < 0) {
- printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
- goto error2;
- }
- hw->irq = pci->irq;
- }
-
- pci_set_master(pci);
-
- return 0;
-
-/*error3:
- iounmap((void *)hw->mem_base);
- hw->mem_base = (unsigned long)NULL;*/
-error2:
- pci_release_regions(pci);
- hw->io_base = 0;
-error1:
- pci_disable_device(pci);
- return err;
-}
-
-static int hw_card_stop(struct hw *hw)
-{
- unsigned int data;
-
- /* disable transport bus master and queueing of request */
- hw_write_20kx(hw, TRANSPORT_CTL, 0x00);
-
- /* disable pll */
- data = hw_read_20kx(hw, PLL_ENB);
- hw_write_20kx(hw, PLL_ENB, (data & (~0x07)));
-
- /* TODO: Disable interrupt and so on... */
- return 0;
-}
-
-static int hw_card_shutdown(struct hw *hw)
-{
- if (hw->irq >= 0)
- free_irq(hw->irq, hw);
-
- hw->irq = -1;
-
- if (hw->mem_base)
- iounmap((void *)hw->mem_base);
-
- hw->mem_base = (unsigned long)NULL;
-
- if (hw->io_base)
- pci_release_regions(hw->pci);
-
- hw->io_base = 0;
-
- pci_disable_device(hw->pci);
-
- return 0;
-}
-
-static int hw_card_init(struct hw *hw, struct card_conf *info)
-{
- int err;
- unsigned int gctl;
- u32 data = 0;
- struct dac_conf dac_info = {0};
- struct adc_conf adc_info = {0};
- struct daio_conf daio_info = {0};
- struct trn_conf trn_info = {0};
-
- /* Get PCI io port/memory base address and
- * do 20kx core switch if needed. */
- err = hw_card_start(hw);
- if (err)
- return err;
-
- /* PLL init */
- err = hw_pll_init(hw, info->rsr);
- if (err < 0)
- return err;
-
- /* kick off auto-init */
- err = hw_auto_init(hw);
- if (err < 0)
- return err;
-
- gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL);
- set_field(&gctl, GCTL_DBP, 1);
- set_field(&gctl, GCTL_TBP, 1);
- set_field(&gctl, GCTL_FBP, 1);
- set_field(&gctl, GCTL_DPC, 0);
- hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);
-
- /* Reset all global pending interrupts */
- hw_write_20kx(hw, GIE, 0);
- /* Reset all SRC pending interrupts */
- hw_write_20kx(hw, SRC_IP, 0);
-
- if (hw->model != CTSB1270) {
- /* TODO: detect the card ID and configure GPIO accordingly. */
- /* Configures GPIO (0xD802 0x98028) */
- /*hw_write_20kx(hw, GPIO_CTRL, 0x7F07);*/
- /* Configures GPIO (SB0880) */
- /*hw_write_20kx(hw, GPIO_CTRL, 0xFF07);*/
- hw_write_20kx(hw, GPIO_CTRL, 0xD802);
- } else {
- hw_write_20kx(hw, GPIO_CTRL, 0x9E5F);
- }
- /* Enable audio ring */
- hw_write_20kx(hw, MIXER_AR_ENABLE, 0x01);
-
- trn_info.vm_pgt_phys = info->vm_pgt_phys;
- err = hw_trn_init(hw, &trn_info);
- if (err < 0)
- return err;
-
- daio_info.msr = info->msr;
- err = hw_daio_init(hw, &daio_info);
- if (err < 0)
- return err;
-
- dac_info.msr = info->msr;
- err = hw_dac_init(hw, &dac_info);
- if (err < 0)
- return err;
-
- adc_info.msr = info->msr;
- adc_info.input = ADC_LINEIN;
- adc_info.mic20db = 0;
- err = hw_adc_init(hw, &adc_info);
- if (err < 0)
- return err;
-
- data = hw_read_20kx(hw, SRC_MCTL);
- data |= 0x1; /* Enables input from the audio ring */
- hw_write_20kx(hw, SRC_MCTL, data);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int hw_suspend(struct hw *hw, pm_message_t state)
-{
- struct pci_dev *pci = hw->pci;
-
- hw_card_stop(hw);
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
-
- return 0;
-}
-
-static int hw_resume(struct hw *hw, struct card_conf *info)
-{
- struct pci_dev *pci = hw->pci;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
-
- /* Re-initialize card hardware. */
- return hw_card_init(hw, info);
-}
-#endif
-
-static u32 hw_read_20kx(struct hw *hw, u32 reg)
-{
- return readl((void *)(hw->mem_base + reg));
-}
-
-static void hw_write_20kx(struct hw *hw, u32 reg, u32 data)
-{
- writel(data, (void *)(hw->mem_base + reg));
-}
-
-static struct hw ct20k2_preset __devinitdata = {
- .irq = -1,
-
- .card_init = hw_card_init,
- .card_stop = hw_card_stop,
- .pll_init = hw_pll_init,
- .is_adc_source_selected = hw_is_adc_input_selected,
- .select_adc_source = hw_adc_input_select,
- .capabilities = hw_capabilities,
- .output_switch_get = hw_output_switch_get,
- .output_switch_put = hw_output_switch_put,
- .mic_source_switch_get = hw_mic_source_switch_get,
- .mic_source_switch_put = hw_mic_source_switch_put,
-#ifdef CONFIG_PM
- .suspend = hw_suspend,
- .resume = hw_resume,
-#endif
-
- .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk,
- .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk,
- .src_mgr_get_ctrl_blk = src_mgr_get_ctrl_blk,
- .src_mgr_put_ctrl_blk = src_mgr_put_ctrl_blk,
- .src_set_state = src_set_state,
- .src_set_bm = src_set_bm,
- .src_set_rsr = src_set_rsr,
- .src_set_sf = src_set_sf,
- .src_set_wr = src_set_wr,
- .src_set_pm = src_set_pm,
- .src_set_rom = src_set_rom,
- .src_set_vo = src_set_vo,
- .src_set_st = src_set_st,
- .src_set_ie = src_set_ie,
- .src_set_ilsz = src_set_ilsz,
- .src_set_bp = src_set_bp,
- .src_set_cisz = src_set_cisz,
- .src_set_ca = src_set_ca,
- .src_set_sa = src_set_sa,
- .src_set_la = src_set_la,
- .src_set_pitch = src_set_pitch,
- .src_set_dirty = src_set_dirty,
- .src_set_clear_zbufs = src_set_clear_zbufs,
- .src_set_dirty_all = src_set_dirty_all,
- .src_commit_write = src_commit_write,
- .src_get_ca = src_get_ca,
- .src_get_dirty = src_get_dirty,
- .src_dirty_conj_mask = src_dirty_conj_mask,
- .src_mgr_enbs_src = src_mgr_enbs_src,
- .src_mgr_enb_src = src_mgr_enb_src,
- .src_mgr_dsb_src = src_mgr_dsb_src,
- .src_mgr_commit_write = src_mgr_commit_write,
-
- .srcimp_mgr_get_ctrl_blk = srcimp_mgr_get_ctrl_blk,
- .srcimp_mgr_put_ctrl_blk = srcimp_mgr_put_ctrl_blk,
- .srcimp_mgr_set_imaparc = srcimp_mgr_set_imaparc,
- .srcimp_mgr_set_imapuser = srcimp_mgr_set_imapuser,
- .srcimp_mgr_set_imapnxt = srcimp_mgr_set_imapnxt,
- .srcimp_mgr_set_imapaddr = srcimp_mgr_set_imapaddr,
- .srcimp_mgr_commit_write = srcimp_mgr_commit_write,
-
- .amixer_rsc_get_ctrl_blk = amixer_rsc_get_ctrl_blk,
- .amixer_rsc_put_ctrl_blk = amixer_rsc_put_ctrl_blk,
- .amixer_mgr_get_ctrl_blk = amixer_mgr_get_ctrl_blk,
- .amixer_mgr_put_ctrl_blk = amixer_mgr_put_ctrl_blk,
- .amixer_set_mode = amixer_set_mode,
- .amixer_set_iv = amixer_set_iv,
- .amixer_set_x = amixer_set_x,
- .amixer_set_y = amixer_set_y,
- .amixer_set_sadr = amixer_set_sadr,
- .amixer_set_se = amixer_set_se,
- .amixer_set_dirty = amixer_set_dirty,
- .amixer_set_dirty_all = amixer_set_dirty_all,
- .amixer_commit_write = amixer_commit_write,
- .amixer_get_y = amixer_get_y,
- .amixer_get_dirty = amixer_get_dirty,
-
- .dai_get_ctrl_blk = dai_get_ctrl_blk,
- .dai_put_ctrl_blk = dai_put_ctrl_blk,
- .dai_srt_set_srco = dai_srt_set_srco,
- .dai_srt_set_srcm = dai_srt_set_srcm,
- .dai_srt_set_rsr = dai_srt_set_rsr,
- .dai_srt_set_drat = dai_srt_set_drat,
- .dai_srt_set_ec = dai_srt_set_ec,
- .dai_srt_set_et = dai_srt_set_et,
- .dai_commit_write = dai_commit_write,
-
- .dao_get_ctrl_blk = dao_get_ctrl_blk,
- .dao_put_ctrl_blk = dao_put_ctrl_blk,
- .dao_set_spos = dao_set_spos,
- .dao_commit_write = dao_commit_write,
- .dao_get_spos = dao_get_spos,
-
- .daio_mgr_get_ctrl_blk = daio_mgr_get_ctrl_blk,
- .daio_mgr_put_ctrl_blk = daio_mgr_put_ctrl_blk,
- .daio_mgr_enb_dai = daio_mgr_enb_dai,
- .daio_mgr_dsb_dai = daio_mgr_dsb_dai,
- .daio_mgr_enb_dao = daio_mgr_enb_dao,
- .daio_mgr_dsb_dao = daio_mgr_dsb_dao,
- .daio_mgr_dao_init = daio_mgr_dao_init,
- .daio_mgr_set_imaparc = daio_mgr_set_imaparc,
- .daio_mgr_set_imapnxt = daio_mgr_set_imapnxt,
- .daio_mgr_set_imapaddr = daio_mgr_set_imapaddr,
- .daio_mgr_commit_write = daio_mgr_commit_write,
-
- .set_timer_irq = set_timer_irq,
- .set_timer_tick = set_timer_tick,
- .get_wc = get_wc,
-};
-
-int __devinit create_20k2_hw_obj(struct hw **rhw)
-{
- struct hw20k2 *hw20k2;
-
- *rhw = NULL;
- hw20k2 = kzalloc(sizeof(*hw20k2), GFP_KERNEL);
- if (!hw20k2)
- return -ENOMEM;
-
- hw20k2->hw = ct20k2_preset;
- *rhw = &hw20k2->hw;
-
- return 0;
-}
-
-int destroy_20k2_hw_obj(struct hw *hw)
-{
- if (hw->io_base)
- hw_card_shutdown(hw);
-
- kfree(hw);
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k2.h b/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k2.h
deleted file mode 100644
index d2b7daab..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/cthw20k2.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File cthw20k2.h
- *
- * @Brief
- * This file contains the definition of hardware access methord.
- *
- * @Author Liu Chun
- * @Date May 13 2008
- *
- */
-
-#ifndef CTHW20K2_H
-#define CTHW20K2_H
-
-#include "cthardware.h"
-
-int create_20k2_hw_obj(struct hw **rhw);
-int destroy_20k2_hw_obj(struct hw *hw);
-
-#endif /* CTHW20K2_H */
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctimap.c b/ANDROID_3.4.5/sound/pci/ctxfi/ctimap.c
deleted file mode 100644
index 0b73368a..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/ctimap.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File ctimap.c
- *
- * @Brief
- * This file contains the implementation of generic input mapper operations
- * for input mapper management.
- *
- * @Author Liu Chun
- * @Date May 23 2008
- *
- */
-
-#include "ctimap.h"
-#include <linux/slab.h>
-
-int input_mapper_add(struct list_head *mappers, struct imapper *entry,
- int (*map_op)(void *, struct imapper *), void *data)
-{
- struct list_head *pos, *pre, *head;
- struct imapper *pre_ent, *pos_ent;
-
- head = mappers;
-
- if (list_empty(head)) {
- entry->next = entry->addr;
- map_op(data, entry);
- list_add(&entry->list, head);
- return 0;
- }
-
- list_for_each(pos, head) {
- pos_ent = list_entry(pos, struct imapper, list);
- if (pos_ent->slot > entry->slot) {
- /* found a position in list */
- break;
- }
- }
-
- if (pos != head) {
- pre = pos->prev;
- if (pre == head)
- pre = head->prev;
-
- __list_add(&entry->list, pos->prev, pos);
- } else {
- pre = head->prev;
- pos = head->next;
- list_add_tail(&entry->list, head);
- }
-
- pre_ent = list_entry(pre, struct imapper, list);
- pos_ent = list_entry(pos, struct imapper, list);
-
- entry->next = pos_ent->addr;
- map_op(data, entry);
- pre_ent->next = entry->addr;
- map_op(data, pre_ent);
-
- return 0;
-}
-
-int input_mapper_delete(struct list_head *mappers, struct imapper *entry,
- int (*map_op)(void *, struct imapper *), void *data)
-{
- struct list_head *next, *pre, *head;
- struct imapper *pre_ent, *next_ent;
-
- head = mappers;
-
- if (list_empty(head))
- return 0;
-
- pre = (entry->list.prev == head) ? head->prev : entry->list.prev;
- next = (entry->list.next == head) ? head->next : entry->list.next;
-
- if (pre == &entry->list) {
- /* entry is the only one node in mappers list */
- entry->next = entry->addr = entry->user = entry->slot = 0;
- map_op(data, entry);
- list_del(&entry->list);
- return 0;
- }
-
- pre_ent = list_entry(pre, struct imapper, list);
- next_ent = list_entry(next, struct imapper, list);
-
- pre_ent->next = next_ent->addr;
- map_op(data, pre_ent);
- list_del(&entry->list);
-
- return 0;
-}
-
-void free_input_mapper_list(struct list_head *head)
-{
- struct imapper *entry;
- struct list_head *pos;
-
- while (!list_empty(head)) {
- pos = head->next;
- list_del(pos);
- entry = list_entry(pos, struct imapper, list);
- kfree(entry);
- }
-}
-
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctimap.h b/ANDROID_3.4.5/sound/pci/ctxfi/ctimap.h
deleted file mode 100644
index 53ccf9be..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/ctimap.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File ctimap.h
- *
- * @Brief
- * This file contains the definition of generic input mapper operations
- * for input mapper management.
- *
- * @Author Liu Chun
- * @Date May 23 2008
- *
- */
-
-#ifndef CTIMAP_H
-#define CTIMAP_H
-
-#include <linux/list.h>
-
-struct imapper {
- unsigned short slot; /* the id of the slot containing input data */
- unsigned short user; /* the id of the user resource consuming data */
- unsigned short addr; /* the input mapper ram id */
- unsigned short next; /* the next input mapper ram id */
- struct list_head list;
-};
-
-int input_mapper_add(struct list_head *mappers, struct imapper *entry,
- int (*map_op)(void *, struct imapper *), void *data);
-
-int input_mapper_delete(struct list_head *mappers, struct imapper *entry,
- int (*map_op)(void *, struct imapper *), void *data);
-
-void free_input_mapper_list(struct list_head *mappers);
-
-#endif /* CTIMAP_H */
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctmixer.c b/ANDROID_3.4.5/sound/pci/ctxfi/ctmixer.c
deleted file mode 100644
index 0cc13eee..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/ctmixer.c
+++ /dev/null
@@ -1,1227 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File ctmixer.c
- *
- * @Brief
- * This file contains the implementation of alsa mixer device functions.
- *
- * @Author Liu Chun
- * @Date May 28 2008
- *
- */
-
-
-#include "ctmixer.h"
-#include "ctamixer.h"
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/asoundef.h>
-#include <sound/pcm.h>
-#include <sound/tlv.h>
-
-enum CT_SUM_CTL {
- SUM_IN_F,
- SUM_IN_R,
- SUM_IN_C,
- SUM_IN_S,
- SUM_IN_F_C,
-
- NUM_CT_SUMS
-};
-
-enum CT_AMIXER_CTL {
- /* volume control mixers */
- AMIXER_MASTER_F,
- AMIXER_MASTER_R,
- AMIXER_MASTER_C,
- AMIXER_MASTER_S,
- AMIXER_PCM_F,
- AMIXER_PCM_R,
- AMIXER_PCM_C,
- AMIXER_PCM_S,
- AMIXER_SPDIFI,
- AMIXER_LINEIN,
- AMIXER_MIC,
- AMIXER_SPDIFO,
- AMIXER_WAVE_F,
- AMIXER_WAVE_R,
- AMIXER_WAVE_C,
- AMIXER_WAVE_S,
- AMIXER_MASTER_F_C,
- AMIXER_PCM_F_C,
- AMIXER_SPDIFI_C,
- AMIXER_LINEIN_C,
- AMIXER_MIC_C,
-
- /* this should always be the last one */
- NUM_CT_AMIXERS
-};
-
-enum CTALSA_MIXER_CTL {
- /* volume control mixers */
- MIXER_MASTER_P,
- MIXER_PCM_P,
- MIXER_LINEIN_P,
- MIXER_MIC_P,
- MIXER_SPDIFI_P,
- MIXER_SPDIFO_P,
- MIXER_WAVEF_P,
- MIXER_WAVER_P,
- MIXER_WAVEC_P,
- MIXER_WAVES_P,
- MIXER_MASTER_C,
- MIXER_PCM_C,
- MIXER_LINEIN_C,
- MIXER_MIC_C,
- MIXER_SPDIFI_C,
-
- /* switch control mixers */
- MIXER_PCM_C_S,
- MIXER_LINEIN_C_S,
- MIXER_MIC_C_S,
- MIXER_SPDIFI_C_S,
- MIXER_SPDIFO_P_S,
- MIXER_WAVEF_P_S,
- MIXER_WAVER_P_S,
- MIXER_WAVEC_P_S,
- MIXER_WAVES_P_S,
- MIXER_DIGITAL_IO_S,
- MIXER_IEC958_MASK,
- MIXER_IEC958_DEFAULT,
- MIXER_IEC958_STREAM,
-
- /* this should always be the last one */
- NUM_CTALSA_MIXERS
-};
-
-#define VOL_MIXER_START MIXER_MASTER_P
-#define VOL_MIXER_END MIXER_SPDIFI_C
-#define VOL_MIXER_NUM (VOL_MIXER_END - VOL_MIXER_START + 1)
-#define SWH_MIXER_START MIXER_PCM_C_S
-#define SWH_MIXER_END MIXER_DIGITAL_IO_S
-#define SWH_CAPTURE_START MIXER_PCM_C_S
-#define SWH_CAPTURE_END MIXER_SPDIFI_C_S
-
-#define CHN_NUM 2
-
-struct ct_kcontrol_init {
- unsigned char ctl;
- char *name;
-};
-
-static struct ct_kcontrol_init
-ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
- [MIXER_MASTER_P] = {
- .ctl = 1,
- .name = "Master Playback Volume",
- },
- [MIXER_MASTER_C] = {
- .ctl = 1,
- .name = "Master Capture Volume",
- },
- [MIXER_PCM_P] = {
- .ctl = 1,
- .name = "PCM Playback Volume",
- },
- [MIXER_PCM_C] = {
- .ctl = 1,
- .name = "PCM Capture Volume",
- },
- [MIXER_LINEIN_P] = {
- .ctl = 1,
- .name = "Line Playback Volume",
- },
- [MIXER_LINEIN_C] = {
- .ctl = 1,
- .name = "Line Capture Volume",
- },
- [MIXER_MIC_P] = {
- .ctl = 1,
- .name = "Mic Playback Volume",
- },
- [MIXER_MIC_C] = {
- .ctl = 1,
- .name = "Mic Capture Volume",
- },
- [MIXER_SPDIFI_P] = {
- .ctl = 1,
- .name = "IEC958 Playback Volume",
- },
- [MIXER_SPDIFI_C] = {
- .ctl = 1,
- .name = "IEC958 Capture Volume",
- },
- [MIXER_SPDIFO_P] = {
- .ctl = 1,
- .name = "Digital Playback Volume",
- },
- [MIXER_WAVEF_P] = {
- .ctl = 1,
- .name = "Front Playback Volume",
- },
- [MIXER_WAVES_P] = {
- .ctl = 1,
- .name = "Side Playback Volume",
- },
- [MIXER_WAVEC_P] = {
- .ctl = 1,
- .name = "Center/LFE Playback Volume",
- },
- [MIXER_WAVER_P] = {
- .ctl = 1,
- .name = "Surround Playback Volume",
- },
- [MIXER_PCM_C_S] = {
- .ctl = 1,
- .name = "PCM Capture Switch",
- },
- [MIXER_LINEIN_C_S] = {
- .ctl = 1,
- .name = "Line Capture Switch",
- },
- [MIXER_MIC_C_S] = {
- .ctl = 1,
- .name = "Mic Capture Switch",
- },
- [MIXER_SPDIFI_C_S] = {
- .ctl = 1,
- .name = "IEC958 Capture Switch",
- },
- [MIXER_SPDIFO_P_S] = {
- .ctl = 1,
- .name = "Digital Playback Switch",
- },
- [MIXER_WAVEF_P_S] = {
- .ctl = 1,
- .name = "Front Playback Switch",
- },
- [MIXER_WAVES_P_S] = {
- .ctl = 1,
- .name = "Side Playback Switch",
- },
- [MIXER_WAVEC_P_S] = {
- .ctl = 1,
- .name = "Center/LFE Playback Switch",
- },
- [MIXER_WAVER_P_S] = {
- .ctl = 1,
- .name = "Surround Playback Switch",
- },
- [MIXER_DIGITAL_IO_S] = {
- .ctl = 0,
- .name = "Digit-IO Playback Switch",
- },
-};
-
-static void
-ct_mixer_recording_select(struct ct_mixer *mixer, enum CT_AMIXER_CTL type);
-
-static void
-ct_mixer_recording_unselect(struct ct_mixer *mixer, enum CT_AMIXER_CTL type);
-
-/* FIXME: this static looks like it would fail if more than one card was */
-/* installed. */
-static struct snd_kcontrol *kctls[2] = {NULL};
-
-static enum CT_AMIXER_CTL get_amixer_index(enum CTALSA_MIXER_CTL alsa_index)
-{
- switch (alsa_index) {
- case MIXER_MASTER_P: return AMIXER_MASTER_F;
- case MIXER_MASTER_C: return AMIXER_MASTER_F_C;
- case MIXER_PCM_P: return AMIXER_PCM_F;
- case MIXER_PCM_C:
- case MIXER_PCM_C_S: return AMIXER_PCM_F_C;
- case MIXER_LINEIN_P: return AMIXER_LINEIN;
- case MIXER_LINEIN_C:
- case MIXER_LINEIN_C_S: return AMIXER_LINEIN_C;
- case MIXER_MIC_P: return AMIXER_MIC;
- case MIXER_MIC_C:
- case MIXER_MIC_C_S: return AMIXER_MIC_C;
- case MIXER_SPDIFI_P: return AMIXER_SPDIFI;
- case MIXER_SPDIFI_C:
- case MIXER_SPDIFI_C_S: return AMIXER_SPDIFI_C;
- case MIXER_SPDIFO_P: return AMIXER_SPDIFO;
- case MIXER_WAVEF_P: return AMIXER_WAVE_F;
- case MIXER_WAVES_P: return AMIXER_WAVE_S;
- case MIXER_WAVEC_P: return AMIXER_WAVE_C;
- case MIXER_WAVER_P: return AMIXER_WAVE_R;
- default: return NUM_CT_AMIXERS;
- }
-}
-
-static enum CT_AMIXER_CTL get_recording_amixer(enum CT_AMIXER_CTL index)
-{
- switch (index) {
- case AMIXER_MASTER_F: return AMIXER_MASTER_F_C;
- case AMIXER_PCM_F: return AMIXER_PCM_F_C;
- case AMIXER_SPDIFI: return AMIXER_SPDIFI_C;
- case AMIXER_LINEIN: return AMIXER_LINEIN_C;
- case AMIXER_MIC: return AMIXER_MIC_C;
- default: return NUM_CT_AMIXERS;
- }
-}
-
-static unsigned char
-get_switch_state(struct ct_mixer *mixer, enum CTALSA_MIXER_CTL type)
-{
- return (mixer->switch_state & (0x1 << (type - SWH_MIXER_START)))
- ? 1 : 0;
-}
-
-static void
-set_switch_state(struct ct_mixer *mixer,
- enum CTALSA_MIXER_CTL type, unsigned char state)
-{
- if (state)
- mixer->switch_state |= (0x1 << (type - SWH_MIXER_START));
- else
- mixer->switch_state &= ~(0x1 << (type - SWH_MIXER_START));
-}
-
-#if 0 /* not used */
-/* Map integer value ranging from 0 to 65535 to 14-bit float value ranging
- * from 2^-6 to (1+1023/1024) */
-static unsigned int uint16_to_float14(unsigned int x)
-{
- unsigned int i;
-
- if (x < 17)
- return 0;
-
- x *= 2031;
- x /= 65535;
- x += 16;
-
- /* i <= 6 */
- for (i = 0; !(x & 0x400); i++)
- x <<= 1;
-
- x = (((7 - i) & 0x7) << 10) | (x & 0x3ff);
-
- return x;
-}
-
-static unsigned int float14_to_uint16(unsigned int x)
-{
- unsigned int e;
-
- if (!x)
- return x;
-
- e = (x >> 10) & 0x7;
- x &= 0x3ff;
- x += 1024;
- x >>= (7 - e);
- x -= 16;
- x *= 65535;
- x /= 2031;
-
- return x;
-}
-#endif /* not used */
-
-#define VOL_SCALE 0x1c
-#define VOL_MAX 0x100
-
-static const DECLARE_TLV_DB_SCALE(ct_vol_db_scale, -6400, 25, 1);
-
-static int ct_alsa_mix_volume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = VOL_MAX;
-
- return 0;
-}
-
-static int ct_alsa_mix_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
- enum CT_AMIXER_CTL type = get_amixer_index(kcontrol->private_value);
- struct amixer *amixer;
- int i, val;
-
- for (i = 0; i < 2; i++) {
- amixer = ((struct ct_mixer *)atc->mixer)->
- amixers[type*CHN_NUM+i];
- val = amixer->ops->get_scale(amixer) / VOL_SCALE;
- if (val < 0)
- val = 0;
- else if (val > VOL_MAX)
- val = VOL_MAX;
- ucontrol->value.integer.value[i] = val;
- }
-
- return 0;
-}
-
-static int ct_alsa_mix_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
- struct ct_mixer *mixer = atc->mixer;
- enum CT_AMIXER_CTL type = get_amixer_index(kcontrol->private_value);
- struct amixer *amixer;
- int i, j, val, oval, change = 0;
-
- for (i = 0; i < 2; i++) {
- val = ucontrol->value.integer.value[i];
- if (val < 0)
- val = 0;
- else if (val > VOL_MAX)
- val = VOL_MAX;
- val *= VOL_SCALE;
- amixer = mixer->amixers[type*CHN_NUM+i];
- oval = amixer->ops->get_scale(amixer);
- if (val != oval) {
- amixer->ops->set_scale(amixer, val);
- amixer->ops->commit_write(amixer);
- change = 1;
- /* Synchronize Master/PCM playback AMIXERs. */
- if (AMIXER_MASTER_F == type || AMIXER_PCM_F == type) {
- for (j = 1; j < 4; j++) {
- amixer = mixer->
- amixers[(type+j)*CHN_NUM+i];
- amixer->ops->set_scale(amixer, val);
- amixer->ops->commit_write(amixer);
- }
- }
- }
- }
-
- return change;
-}
-
-static struct snd_kcontrol_new vol_ctl = {
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = ct_alsa_mix_volume_info,
- .get = ct_alsa_mix_volume_get,
- .put = ct_alsa_mix_volume_put,
- .tlv = { .p = ct_vol_db_scale },
-};
-
-static int output_switch_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *info)
-{
- static const char *const names[3] = {
- "FP Headphones", "Headphones", "Speakers"
- };
-
- return snd_ctl_enum_info(info, 1, 3, names);
-}
-
-static int output_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = atc->output_switch_get(atc);
- return 0;
-}
-
-static int output_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
- if (ucontrol->value.enumerated.item[0] > 2)
- return -EINVAL;
- return atc->output_switch_put(atc, ucontrol->value.enumerated.item[0]);
-}
-
-static struct snd_kcontrol_new output_ctl = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Output Playback Enum",
- .info = output_switch_info,
- .get = output_switch_get,
- .put = output_switch_put,
-};
-
-static int mic_source_switch_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *info)
-{
- static const char *const names[3] = {
- "Mic", "FP Mic", "Aux"
- };
-
- return snd_ctl_enum_info(info, 1, 3, names);
-}
-
-static int mic_source_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = atc->mic_source_switch_get(atc);
- return 0;
-}
-
-static int mic_source_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
- if (ucontrol->value.enumerated.item[0] > 2)
- return -EINVAL;
- return atc->mic_source_switch_put(atc,
- ucontrol->value.enumerated.item[0]);
-}
-
-static struct snd_kcontrol_new mic_source_ctl = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Mic Source Capture Enum",
- .info = mic_source_switch_info,
- .get = mic_source_switch_get,
- .put = mic_source_switch_put,
-};
-
-static void
-do_line_mic_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type)
-{
-
- if (MIXER_LINEIN_C_S == type) {
- atc->select_line_in(atc);
- set_switch_state(atc->mixer, MIXER_MIC_C_S, 0);
- snd_ctl_notify(atc->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &kctls[1]->id);
- } else if (MIXER_MIC_C_S == type) {
- atc->select_mic_in(atc);
- set_switch_state(atc->mixer, MIXER_LINEIN_C_S, 0);
- snd_ctl_notify(atc->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &kctls[0]->id);
- }
-}
-
-static void
-do_digit_io_switch(struct ct_atc *atc, int state)
-{
- struct ct_mixer *mixer = atc->mixer;
-
- if (state) {
- atc->select_digit_io(atc);
- atc->spdif_out_unmute(atc,
- get_switch_state(mixer, MIXER_SPDIFO_P_S));
- atc->spdif_in_unmute(atc, 1);
- atc->line_in_unmute(atc, 0);
- return;
- }
-
- if (get_switch_state(mixer, MIXER_LINEIN_C_S))
- atc->select_line_in(atc);
- else if (get_switch_state(mixer, MIXER_MIC_C_S))
- atc->select_mic_in(atc);
-
- atc->spdif_out_unmute(atc, 0);
- atc->spdif_in_unmute(atc, 0);
- atc->line_in_unmute(atc, 1);
- return;
-}
-
-static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state)
-{
- struct ct_mixer *mixer = atc->mixer;
- struct capabilities cap = atc->capabilities(atc);
-
- /* Do changes in mixer. */
- if ((SWH_CAPTURE_START <= type) && (SWH_CAPTURE_END >= type)) {
- if (state) {
- ct_mixer_recording_select(mixer,
- get_amixer_index(type));
- } else {
- ct_mixer_recording_unselect(mixer,
- get_amixer_index(type));
- }
- }
- /* Do changes out of mixer. */
- if (!cap.dedicated_mic &&
- (MIXER_LINEIN_C_S == type || MIXER_MIC_C_S == type)) {
- if (state)
- do_line_mic_switch(atc, type);
- atc->line_in_unmute(atc, state);
- } else if (cap.dedicated_mic && (MIXER_LINEIN_C_S == type))
- atc->line_in_unmute(atc, state);
- else if (cap.dedicated_mic && (MIXER_MIC_C_S == type))
- atc->mic_unmute(atc, state);
- else if (MIXER_SPDIFI_C_S == type)
- atc->spdif_in_unmute(atc, state);
- else if (MIXER_WAVEF_P_S == type)
- atc->line_front_unmute(atc, state);
- else if (MIXER_WAVES_P_S == type)
- atc->line_surround_unmute(atc, state);
- else if (MIXER_WAVEC_P_S == type)
- atc->line_clfe_unmute(atc, state);
- else if (MIXER_WAVER_P_S == type)
- atc->line_rear_unmute(atc, state);
- else if (MIXER_SPDIFO_P_S == type)
- atc->spdif_out_unmute(atc, state);
- else if (MIXER_DIGITAL_IO_S == type)
- do_digit_io_switch(atc, state);
-
- return;
-}
-
-static int ct_alsa_mix_switch_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- uinfo->value.integer.step = 1;
-
- return 0;
-}
-
-static int ct_alsa_mix_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ct_mixer *mixer =
- ((struct ct_atc *)snd_kcontrol_chip(kcontrol))->mixer;
- enum CTALSA_MIXER_CTL type = kcontrol->private_value;
-
- ucontrol->value.integer.value[0] = get_switch_state(mixer, type);
- return 0;
-}
-
-static int ct_alsa_mix_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
- struct ct_mixer *mixer = atc->mixer;
- enum CTALSA_MIXER_CTL type = kcontrol->private_value;
- int state;
-
- state = ucontrol->value.integer.value[0];
- if (get_switch_state(mixer, type) == state)
- return 0;
-
- set_switch_state(mixer, type, state);
- do_switch(atc, type, state);
-
- return 1;
-}
-
-static struct snd_kcontrol_new swh_ctl = {
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = ct_alsa_mix_switch_info,
- .get = ct_alsa_mix_switch_get,
- .put = ct_alsa_mix_switch_put
-};
-
-static int ct_spdif_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int ct_spdif_get_mask(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.iec958.status[0] = 0xff;
- ucontrol->value.iec958.status[1] = 0xff;
- ucontrol->value.iec958.status[2] = 0xff;
- ucontrol->value.iec958.status[3] = 0xff;
- return 0;
-}
-
-static int ct_spdif_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
- unsigned int status;
-
- atc->spdif_out_get_status(atc, &status);
-
- if (status == 0)
- status = SNDRV_PCM_DEFAULT_CON_SPDIF;
-
- ucontrol->value.iec958.status[0] = (status >> 0) & 0xff;
- ucontrol->value.iec958.status[1] = (status >> 8) & 0xff;
- ucontrol->value.iec958.status[2] = (status >> 16) & 0xff;
- ucontrol->value.iec958.status[3] = (status >> 24) & 0xff;
-
- return 0;
-}
-
-static int ct_spdif_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int status, old_status;
-
- status = (ucontrol->value.iec958.status[0] << 0) |
- (ucontrol->value.iec958.status[1] << 8) |
- (ucontrol->value.iec958.status[2] << 16) |
- (ucontrol->value.iec958.status[3] << 24);
-
- atc->spdif_out_get_status(atc, &old_status);
- change = (old_status != status);
- if (change)
- atc->spdif_out_set_status(atc, status);
-
- return change;
-}
-
-static struct snd_kcontrol_new iec958_mask_ctl = {
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
- .count = 1,
- .info = ct_spdif_info,
- .get = ct_spdif_get_mask,
- .private_value = MIXER_IEC958_MASK
-};
-
-static struct snd_kcontrol_new iec958_default_ctl = {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
- .count = 1,
- .info = ct_spdif_info,
- .get = ct_spdif_get,
- .put = ct_spdif_put,
- .private_value = MIXER_IEC958_DEFAULT
-};
-
-static struct snd_kcontrol_new iec958_ctl = {
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM),
- .count = 1,
- .info = ct_spdif_info,
- .get = ct_spdif_get,
- .put = ct_spdif_put,
- .private_value = MIXER_IEC958_STREAM
-};
-
-#define NUM_IEC958_CTL 3
-
-static int
-ct_mixer_kcontrol_new(struct ct_mixer *mixer, struct snd_kcontrol_new *new)
-{
- struct snd_kcontrol *kctl;
- int err;
-
- kctl = snd_ctl_new1(new, mixer->atc);
- if (!kctl)
- return -ENOMEM;
-
- if (SNDRV_CTL_ELEM_IFACE_PCM == kctl->id.iface)
- kctl->id.device = IEC958;
-
- err = snd_ctl_add(mixer->atc->card, kctl);
- if (err)
- return err;
-
- switch (new->private_value) {
- case MIXER_LINEIN_C_S:
- kctls[0] = kctl; break;
- case MIXER_MIC_C_S:
- kctls[1] = kctl; break;
- default:
- break;
- }
-
- return 0;
-}
-
-static int ct_mixer_kcontrols_create(struct ct_mixer *mixer)
-{
- enum CTALSA_MIXER_CTL type;
- struct ct_atc *atc = mixer->atc;
- struct capabilities cap = atc->capabilities(atc);
- int err;
-
- /* Create snd kcontrol instances on demand */
- for (type = VOL_MIXER_START; type <= VOL_MIXER_END; type++) {
- if (ct_kcontrol_init_table[type].ctl) {
- vol_ctl.name = ct_kcontrol_init_table[type].name;
- vol_ctl.private_value = (unsigned long)type;
- err = ct_mixer_kcontrol_new(mixer, &vol_ctl);
- if (err)
- return err;
- }
- }
-
- ct_kcontrol_init_table[MIXER_DIGITAL_IO_S].ctl = cap.digit_io_switch;
-
- for (type = SWH_MIXER_START; type <= SWH_MIXER_END; type++) {
- if (ct_kcontrol_init_table[type].ctl) {
- swh_ctl.name = ct_kcontrol_init_table[type].name;
- swh_ctl.private_value = (unsigned long)type;
- err = ct_mixer_kcontrol_new(mixer, &swh_ctl);
- if (err)
- return err;
- }
- }
-
- err = ct_mixer_kcontrol_new(mixer, &iec958_mask_ctl);
- if (err)
- return err;
-
- err = ct_mixer_kcontrol_new(mixer, &iec958_default_ctl);
- if (err)
- return err;
-
- err = ct_mixer_kcontrol_new(mixer, &iec958_ctl);
- if (err)
- return err;
-
- if (cap.output_switch) {
- err = ct_mixer_kcontrol_new(mixer, &output_ctl);
- if (err)
- return err;
- }
-
- if (cap.mic_source_switch) {
- err = ct_mixer_kcontrol_new(mixer, &mic_source_ctl);
- if (err)
- return err;
- }
- atc->line_front_unmute(atc, 1);
- set_switch_state(mixer, MIXER_WAVEF_P_S, 1);
- atc->line_surround_unmute(atc, 0);
- set_switch_state(mixer, MIXER_WAVES_P_S, 0);
- atc->line_clfe_unmute(atc, 0);
- set_switch_state(mixer, MIXER_WAVEC_P_S, 0);
- atc->line_rear_unmute(atc, 0);
- set_switch_state(mixer, MIXER_WAVER_P_S, 0);
- atc->spdif_out_unmute(atc, 0);
- set_switch_state(mixer, MIXER_SPDIFO_P_S, 0);
- atc->line_in_unmute(atc, 0);
- if (cap.dedicated_mic)
- atc->mic_unmute(atc, 0);
- atc->spdif_in_unmute(atc, 0);
- set_switch_state(mixer, MIXER_PCM_C_S, 0);
- set_switch_state(mixer, MIXER_LINEIN_C_S, 0);
- set_switch_state(mixer, MIXER_SPDIFI_C_S, 0);
-
- return 0;
-}
-
-static void
-ct_mixer_recording_select(struct ct_mixer *mixer, enum CT_AMIXER_CTL type)
-{
- struct amixer *amix_d;
- struct sum *sum_c;
- int i;
-
- for (i = 0; i < 2; i++) {
- amix_d = mixer->amixers[type*CHN_NUM+i];
- sum_c = mixer->sums[SUM_IN_F_C*CHN_NUM+i];
- amix_d->ops->set_sum(amix_d, sum_c);
- amix_d->ops->commit_write(amix_d);
- }
-}
-
-static void
-ct_mixer_recording_unselect(struct ct_mixer *mixer, enum CT_AMIXER_CTL type)
-{
- struct amixer *amix_d;
- int i;
-
- for (i = 0; i < 2; i++) {
- amix_d = mixer->amixers[type*CHN_NUM+i];
- amix_d->ops->set_sum(amix_d, NULL);
- amix_d->ops->commit_write(amix_d);
- }
-}
-
-static int ct_mixer_get_resources(struct ct_mixer *mixer)
-{
- struct sum_mgr *sum_mgr;
- struct sum *sum;
- struct sum_desc sum_desc = {0};
- struct amixer_mgr *amixer_mgr;
- struct amixer *amixer;
- struct amixer_desc am_desc = {0};
- int err;
- int i;
-
- /* Allocate sum resources for mixer obj */
- sum_mgr = (struct sum_mgr *)mixer->atc->rsc_mgrs[SUM];
- sum_desc.msr = mixer->atc->msr;
- for (i = 0; i < (NUM_CT_SUMS * CHN_NUM); i++) {
- err = sum_mgr->get_sum(sum_mgr, &sum_desc, &sum);
- if (err) {
- printk(KERN_ERR "ctxfi:Failed to get sum resources for "
- "front output!\n");
- break;
- }
- mixer->sums[i] = sum;
- }
- if (err)
- goto error1;
-
- /* Allocate amixer resources for mixer obj */
- amixer_mgr = (struct amixer_mgr *)mixer->atc->rsc_mgrs[AMIXER];
- am_desc.msr = mixer->atc->msr;
- for (i = 0; i < (NUM_CT_AMIXERS * CHN_NUM); i++) {
- err = amixer_mgr->get_amixer(amixer_mgr, &am_desc, &amixer);
- if (err) {
- printk(KERN_ERR "ctxfi:Failed to get amixer resources "
- "for mixer obj!\n");
- break;
- }
- mixer->amixers[i] = amixer;
- }
- if (err)
- goto error2;
-
- return 0;
-
-error2:
- for (i = 0; i < (NUM_CT_AMIXERS * CHN_NUM); i++) {
- if (NULL != mixer->amixers[i]) {
- amixer = mixer->amixers[i];
- amixer_mgr->put_amixer(amixer_mgr, amixer);
- mixer->amixers[i] = NULL;
- }
- }
-error1:
- for (i = 0; i < (NUM_CT_SUMS * CHN_NUM); i++) {
- if (NULL != mixer->sums[i]) {
- sum_mgr->put_sum(sum_mgr, (struct sum *)mixer->sums[i]);
- mixer->sums[i] = NULL;
- }
- }
-
- return err;
-}
-
-static int ct_mixer_get_mem(struct ct_mixer **rmixer)
-{
- struct ct_mixer *mixer;
- int err;
-
- *rmixer = NULL;
- /* Allocate mem for mixer obj */
- mixer = kzalloc(sizeof(*mixer), GFP_KERNEL);
- if (!mixer)
- return -ENOMEM;
-
- mixer->amixers = kzalloc(sizeof(void *)*(NUM_CT_AMIXERS*CHN_NUM),
- GFP_KERNEL);
- if (!mixer->amixers) {
- err = -ENOMEM;
- goto error1;
- }
- mixer->sums = kzalloc(sizeof(void *)*(NUM_CT_SUMS*CHN_NUM), GFP_KERNEL);
- if (!mixer->sums) {
- err = -ENOMEM;
- goto error2;
- }
-
- *rmixer = mixer;
- return 0;
-
-error2:
- kfree(mixer->amixers);
-error1:
- kfree(mixer);
- return err;
-}
-
-static int ct_mixer_topology_build(struct ct_mixer *mixer)
-{
- struct sum *sum;
- struct amixer *amix_d, *amix_s;
- enum CT_AMIXER_CTL i, j;
-
- /* Build topology from destination to source */
-
- /* Set up Master mixer */
- for (i = AMIXER_MASTER_F, j = SUM_IN_F;
- i <= AMIXER_MASTER_S; i++, j++) {
- amix_d = mixer->amixers[i*CHN_NUM];
- sum = mixer->sums[j*CHN_NUM];
- amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL);
- amix_d = mixer->amixers[i*CHN_NUM+1];
- sum = mixer->sums[j*CHN_NUM+1];
- amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL);
- }
-
- /* Set up Wave-out mixer */
- for (i = AMIXER_WAVE_F, j = AMIXER_MASTER_F;
- i <= AMIXER_WAVE_S; i++, j++) {
- amix_d = mixer->amixers[i*CHN_NUM];
- amix_s = mixer->amixers[j*CHN_NUM];
- amix_d->ops->setup(amix_d, &amix_s->rsc, INIT_VOL, NULL);
- amix_d = mixer->amixers[i*CHN_NUM+1];
- amix_s = mixer->amixers[j*CHN_NUM+1];
- amix_d->ops->setup(amix_d, &amix_s->rsc, INIT_VOL, NULL);
- }
-
- /* Set up S/PDIF-out mixer */
- amix_d = mixer->amixers[AMIXER_SPDIFO*CHN_NUM];
- amix_s = mixer->amixers[AMIXER_MASTER_F*CHN_NUM];
- amix_d->ops->setup(amix_d, &amix_s->rsc, INIT_VOL, NULL);
- amix_d = mixer->amixers[AMIXER_SPDIFO*CHN_NUM+1];
- amix_s = mixer->amixers[AMIXER_MASTER_F*CHN_NUM+1];
- amix_d->ops->setup(amix_d, &amix_s->rsc, INIT_VOL, NULL);
-
- /* Set up PCM-in mixer */
- for (i = AMIXER_PCM_F, j = SUM_IN_F; i <= AMIXER_PCM_S; i++, j++) {
- amix_d = mixer->amixers[i*CHN_NUM];
- sum = mixer->sums[j*CHN_NUM];
- amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
- amix_d = mixer->amixers[i*CHN_NUM+1];
- sum = mixer->sums[j*CHN_NUM+1];
- amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
- }
-
- /* Set up Line-in mixer */
- amix_d = mixer->amixers[AMIXER_LINEIN*CHN_NUM];
- sum = mixer->sums[SUM_IN_F*CHN_NUM];
- amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
- amix_d = mixer->amixers[AMIXER_LINEIN*CHN_NUM+1];
- sum = mixer->sums[SUM_IN_F*CHN_NUM+1];
- amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
-
- /* Set up Mic-in mixer */
- amix_d = mixer->amixers[AMIXER_MIC*CHN_NUM];
- sum = mixer->sums[SUM_IN_F*CHN_NUM];
- amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
- amix_d = mixer->amixers[AMIXER_MIC*CHN_NUM+1];
- sum = mixer->sums[SUM_IN_F*CHN_NUM+1];
- amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
-
- /* Set up S/PDIF-in mixer */
- amix_d = mixer->amixers[AMIXER_SPDIFI*CHN_NUM];
- sum = mixer->sums[SUM_IN_F*CHN_NUM];
- amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
- amix_d = mixer->amixers[AMIXER_SPDIFI*CHN_NUM+1];
- sum = mixer->sums[SUM_IN_F*CHN_NUM+1];
- amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
-
- /* Set up Master recording mixer */
- amix_d = mixer->amixers[AMIXER_MASTER_F_C*CHN_NUM];
- sum = mixer->sums[SUM_IN_F_C*CHN_NUM];
- amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL);
- amix_d = mixer->amixers[AMIXER_MASTER_F_C*CHN_NUM+1];
- sum = mixer->sums[SUM_IN_F_C*CHN_NUM+1];
- amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL);
-
- /* Set up PCM-in recording mixer */
- amix_d = mixer->amixers[AMIXER_PCM_F_C*CHN_NUM];
- sum = mixer->sums[SUM_IN_F_C*CHN_NUM];
- amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
- amix_d = mixer->amixers[AMIXER_PCM_F_C*CHN_NUM+1];
- sum = mixer->sums[SUM_IN_F_C*CHN_NUM+1];
- amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
-
- /* Set up Line-in recording mixer */
- amix_d = mixer->amixers[AMIXER_LINEIN_C*CHN_NUM];
- sum = mixer->sums[SUM_IN_F_C*CHN_NUM];
- amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
- amix_d = mixer->amixers[AMIXER_LINEIN_C*CHN_NUM+1];
- sum = mixer->sums[SUM_IN_F_C*CHN_NUM+1];
- amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
-
- /* Set up Mic-in recording mixer */
- amix_d = mixer->amixers[AMIXER_MIC_C*CHN_NUM];
- sum = mixer->sums[SUM_IN_F_C*CHN_NUM];
- amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
- amix_d = mixer->amixers[AMIXER_MIC_C*CHN_NUM+1];
- sum = mixer->sums[SUM_IN_F_C*CHN_NUM+1];
- amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
-
- /* Set up S/PDIF-in recording mixer */
- amix_d = mixer->amixers[AMIXER_SPDIFI_C*CHN_NUM];
- sum = mixer->sums[SUM_IN_F_C*CHN_NUM];
- amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
- amix_d = mixer->amixers[AMIXER_SPDIFI_C*CHN_NUM+1];
- sum = mixer->sums[SUM_IN_F_C*CHN_NUM+1];
- amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
-
- return 0;
-}
-
-static int mixer_set_input_port(struct amixer *amixer, struct rsc *rsc)
-{
- amixer->ops->set_input(amixer, rsc);
- amixer->ops->commit_write(amixer);
-
- return 0;
-}
-
-static enum CT_AMIXER_CTL port_to_amixer(enum MIXER_PORT_T type)
-{
- switch (type) {
- case MIX_WAVE_FRONT: return AMIXER_WAVE_F;
- case MIX_WAVE_SURROUND: return AMIXER_WAVE_S;
- case MIX_WAVE_CENTLFE: return AMIXER_WAVE_C;
- case MIX_WAVE_REAR: return AMIXER_WAVE_R;
- case MIX_PCMO_FRONT: return AMIXER_MASTER_F_C;
- case MIX_SPDIF_OUT: return AMIXER_SPDIFO;
- case MIX_LINE_IN: return AMIXER_LINEIN;
- case MIX_MIC_IN: return AMIXER_MIC;
- case MIX_SPDIF_IN: return AMIXER_SPDIFI;
- case MIX_PCMI_FRONT: return AMIXER_PCM_F;
- case MIX_PCMI_SURROUND: return AMIXER_PCM_S;
- case MIX_PCMI_CENTLFE: return AMIXER_PCM_C;
- case MIX_PCMI_REAR: return AMIXER_PCM_R;
- default: return 0;
- }
-}
-
-static int mixer_get_output_ports(struct ct_mixer *mixer,
- enum MIXER_PORT_T type,
- struct rsc **rleft, struct rsc **rright)
-{
- enum CT_AMIXER_CTL amix = port_to_amixer(type);
-
- if (NULL != rleft)
- *rleft = &((struct amixer *)mixer->amixers[amix*CHN_NUM])->rsc;
-
- if (NULL != rright)
- *rright =
- &((struct amixer *)mixer->amixers[amix*CHN_NUM+1])->rsc;
-
- return 0;
-}
-
-static int mixer_set_input_left(struct ct_mixer *mixer,
- enum MIXER_PORT_T type, struct rsc *rsc)
-{
- enum CT_AMIXER_CTL amix = port_to_amixer(type);
-
- mixer_set_input_port(mixer->amixers[amix*CHN_NUM], rsc);
- amix = get_recording_amixer(amix);
- if (amix < NUM_CT_AMIXERS)
- mixer_set_input_port(mixer->amixers[amix*CHN_NUM], rsc);
-
- return 0;
-}
-
-static int
-mixer_set_input_right(struct ct_mixer *mixer,
- enum MIXER_PORT_T type, struct rsc *rsc)
-{
- enum CT_AMIXER_CTL amix = port_to_amixer(type);
-
- mixer_set_input_port(mixer->amixers[amix*CHN_NUM+1], rsc);
- amix = get_recording_amixer(amix);
- if (amix < NUM_CT_AMIXERS)
- mixer_set_input_port(mixer->amixers[amix*CHN_NUM+1], rsc);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int mixer_resume(struct ct_mixer *mixer)
-{
- int i, state;
- struct amixer *amixer;
-
- /* resume topology and volume gain. */
- for (i = 0; i < NUM_CT_AMIXERS*CHN_NUM; i++) {
- amixer = mixer->amixers[i];
- amixer->ops->commit_write(amixer);
- }
-
- /* resume switch state. */
- for (i = SWH_MIXER_START; i <= SWH_MIXER_END; i++) {
- state = get_switch_state(mixer, i);
- do_switch(mixer->atc, i, state);
- }
-
- return 0;
-}
-#endif
-
-int ct_mixer_destroy(struct ct_mixer *mixer)
-{
- struct sum_mgr *sum_mgr = (struct sum_mgr *)mixer->atc->rsc_mgrs[SUM];
- struct amixer_mgr *amixer_mgr =
- (struct amixer_mgr *)mixer->atc->rsc_mgrs[AMIXER];
- struct amixer *amixer;
- int i = 0;
-
- /* Release amixer resources */
- for (i = 0; i < (NUM_CT_AMIXERS * CHN_NUM); i++) {
- if (NULL != mixer->amixers[i]) {
- amixer = mixer->amixers[i];
- amixer_mgr->put_amixer(amixer_mgr, amixer);
- }
- }
-
- /* Release sum resources */
- for (i = 0; i < (NUM_CT_SUMS * CHN_NUM); i++) {
- if (NULL != mixer->sums[i])
- sum_mgr->put_sum(sum_mgr, (struct sum *)mixer->sums[i]);
- }
-
- /* Release mem assigned to mixer object */
- kfree(mixer->sums);
- kfree(mixer->amixers);
- kfree(mixer);
-
- return 0;
-}
-
-int ct_mixer_create(struct ct_atc *atc, struct ct_mixer **rmixer)
-{
- struct ct_mixer *mixer;
- int err;
-
- *rmixer = NULL;
-
- /* Allocate mem for mixer obj */
- err = ct_mixer_get_mem(&mixer);
- if (err)
- return err;
-
- mixer->switch_state = 0;
- mixer->atc = atc;
- /* Set operations */
- mixer->get_output_ports = mixer_get_output_ports;
- mixer->set_input_left = mixer_set_input_left;
- mixer->set_input_right = mixer_set_input_right;
-#ifdef CONFIG_PM
- mixer->resume = mixer_resume;
-#endif
-
- /* Allocate chip resources for mixer obj */
- err = ct_mixer_get_resources(mixer);
- if (err)
- goto error;
-
- /* Build internal mixer topology */
- ct_mixer_topology_build(mixer);
-
- *rmixer = mixer;
-
- return 0;
-
-error:
- ct_mixer_destroy(mixer);
- return err;
-}
-
-int ct_alsa_mix_create(struct ct_atc *atc,
- enum CTALSADEVS device,
- const char *device_name)
-{
- int err;
-
- /* Create snd kcontrol instances on demand */
- /* vol_ctl.device = swh_ctl.device = device; */ /* better w/ device 0 */
- err = ct_mixer_kcontrols_create((struct ct_mixer *)atc->mixer);
- if (err)
- return err;
-
- strcpy(atc->card->mixername, device_name);
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctmixer.h b/ANDROID_3.4.5/sound/pci/ctxfi/ctmixer.h
deleted file mode 100644
index b009e989..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/ctmixer.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File ctmixer.h
- *
- * @Brief
- * This file contains the definition of the mixer device functions.
- *
- * @Author Liu Chun
- * @Date Mar 28 2008
- *
- */
-
-#ifndef CTMIXER_H
-#define CTMIXER_H
-
-#include "ctatc.h"
-#include "ctresource.h"
-
-#define INIT_VOL 0x1c00
-
-enum MIXER_PORT_T {
- MIX_WAVE_FRONT,
- MIX_WAVE_REAR,
- MIX_WAVE_CENTLFE,
- MIX_WAVE_SURROUND,
- MIX_SPDIF_OUT,
- MIX_PCMO_FRONT,
- MIX_MIC_IN,
- MIX_LINE_IN,
- MIX_SPDIF_IN,
- MIX_PCMI_FRONT,
- MIX_PCMI_REAR,
- MIX_PCMI_CENTLFE,
- MIX_PCMI_SURROUND,
-
- NUM_MIX_PORTS
-};
-
-/* alsa mixer descriptor */
-struct ct_mixer {
- struct ct_atc *atc;
-
- void **amixers; /* amixer resources for volume control */
- void **sums; /* sum resources for signal collection */
- unsigned int switch_state; /* A bit-map to indicate state of switches */
-
- int (*get_output_ports)(struct ct_mixer *mixer, enum MIXER_PORT_T type,
- struct rsc **rleft, struct rsc **rright);
-
- int (*set_input_left)(struct ct_mixer *mixer,
- enum MIXER_PORT_T type, struct rsc *rsc);
- int (*set_input_right)(struct ct_mixer *mixer,
- enum MIXER_PORT_T type, struct rsc *rsc);
-#ifdef CONFIG_PM
- int (*resume)(struct ct_mixer *mixer);
-#endif
-};
-
-int ct_alsa_mix_create(struct ct_atc *atc,
- enum CTALSADEVS device,
- const char *device_name);
-int ct_mixer_create(struct ct_atc *atc, struct ct_mixer **rmixer);
-int ct_mixer_destroy(struct ct_mixer *mixer);
-
-#endif /* CTMIXER_H */
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctpcm.c b/ANDROID_3.4.5/sound/pci/ctxfi/ctpcm.c
deleted file mode 100644
index 2c862261..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/ctpcm.c
+++ /dev/null
@@ -1,435 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File ctpcm.c
- *
- * @Brief
- * This file contains the definition of the pcm device functions.
- *
- * @Author Liu Chun
- * @Date Apr 2 2008
- *
- */
-
-#include "ctpcm.h"
-#include "cttimer.h"
-#include <linux/slab.h>
-#include <sound/pcm.h>
-
-/* Hardware descriptions for playback */
-static struct snd_pcm_hardware ct_pcm_playback_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE),
- .formats = (SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_FLOAT_LE),
- .rates = (SNDRV_PCM_RATE_CONTINUOUS |
- SNDRV_PCM_RATE_8000_192000),
- .rate_min = 8000,
- .rate_max = 192000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = (64),
- .period_bytes_max = (128*1024),
- .periods_min = 2,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware ct_spdif_passthru_playback_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = (SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_32000),
- .rate_min = 32000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = (64),
- .period_bytes_max = (128*1024),
- .periods_min = 2,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-/* Hardware descriptions for capture */
-static struct snd_pcm_hardware ct_pcm_capture_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = (SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_FLOAT_LE),
- .rates = (SNDRV_PCM_RATE_CONTINUOUS |
- SNDRV_PCM_RATE_8000_96000),
- .rate_min = 8000,
- .rate_max = 96000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = (384),
- .period_bytes_max = (64*1024),
- .periods_min = 2,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static void ct_atc_pcm_interrupt(struct ct_atc_pcm *atc_pcm)
-{
- struct ct_atc_pcm *apcm = atc_pcm;
-
- if (!apcm->substream)
- return;
-
- snd_pcm_period_elapsed(apcm->substream);
-}
-
-static void ct_atc_pcm_free_substream(struct snd_pcm_runtime *runtime)
-{
- struct ct_atc_pcm *apcm = runtime->private_data;
- struct ct_atc *atc = snd_pcm_substream_chip(apcm->substream);
-
- atc->pcm_release_resources(atc, apcm);
- ct_timer_instance_free(apcm->timer);
- kfree(apcm);
- runtime->private_data = NULL;
-}
-
-/* pcm playback operations */
-static int ct_pcm_playback_open(struct snd_pcm_substream *substream)
-{
- struct ct_atc *atc = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct ct_atc_pcm *apcm;
- int err;
-
- apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
- if (!apcm)
- return -ENOMEM;
-
- apcm->substream = substream;
- apcm->interrupt = ct_atc_pcm_interrupt;
- if (IEC958 == substream->pcm->device) {
- runtime->hw = ct_spdif_passthru_playback_hw;
- atc->spdif_out_passthru(atc, 1);
- } else {
- runtime->hw = ct_pcm_playback_hw;
- if (FRONT == substream->pcm->device)
- runtime->hw.channels_max = 8;
- }
-
- err = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0) {
- kfree(apcm);
- return err;
- }
- err = snd_pcm_hw_constraint_minmax(runtime,
- SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
- 1024, UINT_MAX);
- if (err < 0) {
- kfree(apcm);
- return err;
- }
-
- apcm->timer = ct_timer_instance_new(atc->timer, apcm);
- if (!apcm->timer) {
- kfree(apcm);
- return -ENOMEM;
- }
- runtime->private_data = apcm;
- runtime->private_free = ct_atc_pcm_free_substream;
-
- return 0;
-}
-
-static int ct_pcm_playback_close(struct snd_pcm_substream *substream)
-{
- struct ct_atc *atc = snd_pcm_substream_chip(substream);
-
- /* TODO: Notify mixer inactive. */
- if (IEC958 == substream->pcm->device)
- atc->spdif_out_passthru(atc, 0);
-
- /* The ct_atc_pcm object will be freed by runtime->private_free */
-
- return 0;
-}
-
-static int ct_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct ct_atc *atc = snd_pcm_substream_chip(substream);
- struct ct_atc_pcm *apcm = substream->runtime->private_data;
- int err;
-
- err = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
- /* clear previous resources */
- atc->pcm_release_resources(atc, apcm);
- return err;
-}
-
-static int ct_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct ct_atc *atc = snd_pcm_substream_chip(substream);
- struct ct_atc_pcm *apcm = substream->runtime->private_data;
-
- /* clear previous resources */
- atc->pcm_release_resources(atc, apcm);
- /* Free snd-allocated pages */
- return snd_pcm_lib_free_pages(substream);
-}
-
-
-static int ct_pcm_playback_prepare(struct snd_pcm_substream *substream)
-{
- int err;
- struct ct_atc *atc = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct ct_atc_pcm *apcm = runtime->private_data;
-
- if (IEC958 == substream->pcm->device)
- err = atc->spdif_passthru_playback_prepare(atc, apcm);
- else
- err = atc->pcm_playback_prepare(atc, apcm);
-
- if (err < 0) {
- printk(KERN_ERR "ctxfi: Preparing pcm playback failed!!!\n");
- return err;
- }
-
- return 0;
-}
-
-static int
-ct_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct ct_atc *atc = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct ct_atc_pcm *apcm = runtime->private_data;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- atc->pcm_playback_start(atc, apcm);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- atc->pcm_playback_stop(atc, apcm);
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-static snd_pcm_uframes_t
-ct_pcm_playback_pointer(struct snd_pcm_substream *substream)
-{
- unsigned long position;
- struct ct_atc *atc = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct ct_atc_pcm *apcm = runtime->private_data;
-
- /* Read out playback position */
- position = atc->pcm_playback_position(atc, apcm);
- position = bytes_to_frames(runtime, position);
- if (position >= runtime->buffer_size)
- position = 0;
- return position;
-}
-
-/* pcm capture operations */
-static int ct_pcm_capture_open(struct snd_pcm_substream *substream)
-{
- struct ct_atc *atc = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct ct_atc_pcm *apcm;
- int err;
-
- apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
- if (!apcm)
- return -ENOMEM;
-
- apcm->started = 0;
- apcm->substream = substream;
- apcm->interrupt = ct_atc_pcm_interrupt;
- runtime->hw = ct_pcm_capture_hw;
- runtime->hw.rate_max = atc->rsr * atc->msr;
-
- err = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0) {
- kfree(apcm);
- return err;
- }
- err = snd_pcm_hw_constraint_minmax(runtime,
- SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
- 1024, UINT_MAX);
- if (err < 0) {
- kfree(apcm);
- return err;
- }
-
- apcm->timer = ct_timer_instance_new(atc->timer, apcm);
- if (!apcm->timer) {
- kfree(apcm);
- return -ENOMEM;
- }
- runtime->private_data = apcm;
- runtime->private_free = ct_atc_pcm_free_substream;
-
- return 0;
-}
-
-static int ct_pcm_capture_close(struct snd_pcm_substream *substream)
-{
- /* The ct_atc_pcm object will be freed by runtime->private_free */
- /* TODO: Notify mixer inactive. */
- return 0;
-}
-
-static int ct_pcm_capture_prepare(struct snd_pcm_substream *substream)
-{
- int err;
- struct ct_atc *atc = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct ct_atc_pcm *apcm = runtime->private_data;
-
- err = atc->pcm_capture_prepare(atc, apcm);
- if (err < 0) {
- printk(KERN_ERR "ctxfi: Preparing pcm capture failed!!!\n");
- return err;
- }
-
- return 0;
-}
-
-static int
-ct_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct ct_atc *atc = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct ct_atc_pcm *apcm = runtime->private_data;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- atc->pcm_capture_start(atc, apcm);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- atc->pcm_capture_stop(atc, apcm);
- break;
- default:
- atc->pcm_capture_stop(atc, apcm);
- break;
- }
-
- return 0;
-}
-
-static snd_pcm_uframes_t
-ct_pcm_capture_pointer(struct snd_pcm_substream *substream)
-{
- unsigned long position;
- struct ct_atc *atc = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct ct_atc_pcm *apcm = runtime->private_data;
-
- /* Read out playback position */
- position = atc->pcm_capture_position(atc, apcm);
- position = bytes_to_frames(runtime, position);
- if (position >= runtime->buffer_size)
- position = 0;
- return position;
-}
-
-/* PCM operators for playback */
-static struct snd_pcm_ops ct_pcm_playback_ops = {
- .open = ct_pcm_playback_open,
- .close = ct_pcm_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = ct_pcm_hw_params,
- .hw_free = ct_pcm_hw_free,
- .prepare = ct_pcm_playback_prepare,
- .trigger = ct_pcm_playback_trigger,
- .pointer = ct_pcm_playback_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
-/* PCM operators for capture */
-static struct snd_pcm_ops ct_pcm_capture_ops = {
- .open = ct_pcm_capture_open,
- .close = ct_pcm_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = ct_pcm_hw_params,
- .hw_free = ct_pcm_hw_free,
- .prepare = ct_pcm_capture_prepare,
- .trigger = ct_pcm_capture_trigger,
- .pointer = ct_pcm_capture_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
-/* Create ALSA pcm device */
-int ct_alsa_pcm_create(struct ct_atc *atc,
- enum CTALSADEVS device,
- const char *device_name)
-{
- struct snd_pcm *pcm;
- int err;
- int playback_count, capture_count;
-
- playback_count = (IEC958 == device) ? 1 : 256;
- capture_count = (FRONT == device) ? 1 : 0;
- err = snd_pcm_new(atc->card, "ctxfi", device,
- playback_count, capture_count, &pcm);
- if (err < 0) {
- printk(KERN_ERR "ctxfi: snd_pcm_new failed!! Err=%d\n", err);
- return err;
- }
-
- pcm->private_data = atc;
- pcm->info_flags = 0;
- pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
- strlcpy(pcm->name, device_name, sizeof(pcm->name));
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ct_pcm_playback_ops);
-
- if (FRONT == device)
- snd_pcm_set_ops(pcm,
- SNDRV_PCM_STREAM_CAPTURE, &ct_pcm_capture_ops);
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(atc->pci), 128*1024, 128*1024);
-
-#ifdef CONFIG_PM
- atc->pcms[device] = pcm;
-#endif
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctpcm.h b/ANDROID_3.4.5/sound/pci/ctxfi/ctpcm.h
deleted file mode 100644
index 178da0dc..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/ctpcm.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File ctpcm.h
- *
- * @Brief
- * This file contains the definition of the pcm device functions.
- *
- * @Author Liu Chun
- * @Date Mar 28 2008
- *
- */
-
-#ifndef CTPCM_H
-#define CTPCM_H
-
-#include "ctatc.h"
-
-int ct_alsa_pcm_create(struct ct_atc *atc,
- enum CTALSADEVS device,
- const char *device_name);
-
-#endif /* CTPCM_H */
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctresource.c b/ANDROID_3.4.5/sound/pci/ctxfi/ctresource.c
deleted file mode 100644
index 7dfaf673..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/ctresource.c
+++ /dev/null
@@ -1,301 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File ctresource.c
- *
- * @Brief
- * This file contains the implementation of some generic helper functions.
- *
- * @Author Liu Chun
- * @Date May 15 2008
- *
- */
-
-#include "ctresource.h"
-#include "cthardware.h"
-#include <linux/err.h>
-#include <linux/slab.h>
-
-#define AUDIO_SLOT_BLOCK_NUM 256
-
-/* Resource allocation based on bit-map management mechanism */
-static int
-get_resource(u8 *rscs, unsigned int amount,
- unsigned int multi, unsigned int *ridx)
-{
- int i, j, k, n;
-
- /* Check whether there are sufficient resources to meet request. */
- for (i = 0, n = multi; i < amount; i++) {
- j = i / 8;
- k = i % 8;
- if (rscs[j] & ((u8)1 << k)) {
- n = multi;
- continue;
- }
- if (!(--n))
- break; /* found sufficient contiguous resources */
- }
-
- if (i >= amount) {
- /* Can not find sufficient contiguous resources */
- return -ENOENT;
- }
-
- /* Mark the contiguous bits in resource bit-map as used */
- for (n = multi; n > 0; n--) {
- j = i / 8;
- k = i % 8;
- rscs[j] |= ((u8)1 << k);
- i--;
- }
-
- *ridx = i + 1;
-
- return 0;
-}
-
-static int put_resource(u8 *rscs, unsigned int multi, unsigned int idx)
-{
- unsigned int i, j, k, n;
-
- /* Mark the contiguous bits in resource bit-map as used */
- for (n = multi, i = idx; n > 0; n--) {
- j = i / 8;
- k = i % 8;
- rscs[j] &= ~((u8)1 << k);
- i++;
- }
-
- return 0;
-}
-
-int mgr_get_resource(struct rsc_mgr *mgr, unsigned int n, unsigned int *ridx)
-{
- int err;
-
- if (n > mgr->avail)
- return -ENOENT;
-
- err = get_resource(mgr->rscs, mgr->amount, n, ridx);
- if (!err)
- mgr->avail -= n;
-
- return err;
-}
-
-int mgr_put_resource(struct rsc_mgr *mgr, unsigned int n, unsigned int idx)
-{
- put_resource(mgr->rscs, n, idx);
- mgr->avail += n;
-
- return 0;
-}
-
-static unsigned char offset_in_audio_slot_block[NUM_RSCTYP] = {
- /* SRC channel is at Audio Ring slot 1 every 16 slots. */
- [SRC] = 0x1,
- [AMIXER] = 0x4,
- [SUM] = 0xc,
-};
-
-static int rsc_index(const struct rsc *rsc)
-{
- return rsc->conj;
-}
-
-static int audio_ring_slot(const struct rsc *rsc)
-{
- return (rsc->conj << 4) + offset_in_audio_slot_block[rsc->type];
-}
-
-static int rsc_next_conj(struct rsc *rsc)
-{
- unsigned int i;
- for (i = 0; (i < 8) && (!(rsc->msr & (0x1 << i))); )
- i++;
- rsc->conj += (AUDIO_SLOT_BLOCK_NUM >> i);
- return rsc->conj;
-}
-
-static int rsc_master(struct rsc *rsc)
-{
- return rsc->conj = rsc->idx;
-}
-
-static struct rsc_ops rsc_generic_ops = {
- .index = rsc_index,
- .output_slot = audio_ring_slot,
- .master = rsc_master,
- .next_conj = rsc_next_conj,
-};
-
-int rsc_init(struct rsc *rsc, u32 idx, enum RSCTYP type, u32 msr, void *hw)
-{
- int err = 0;
-
- rsc->idx = idx;
- rsc->conj = idx;
- rsc->type = type;
- rsc->msr = msr;
- rsc->hw = hw;
- rsc->ops = &rsc_generic_ops;
- if (!hw) {
- rsc->ctrl_blk = NULL;
- return 0;
- }
-
- switch (type) {
- case SRC:
- err = ((struct hw *)hw)->src_rsc_get_ctrl_blk(&rsc->ctrl_blk);
- break;
- case AMIXER:
- err = ((struct hw *)hw)->
- amixer_rsc_get_ctrl_blk(&rsc->ctrl_blk);
- break;
- case SRCIMP:
- case SUM:
- case DAIO:
- break;
- default:
- printk(KERN_ERR
- "ctxfi: Invalid resource type value %d!\n", type);
- return -EINVAL;
- }
-
- if (err) {
- printk(KERN_ERR
- "ctxfi: Failed to get resource control block!\n");
- return err;
- }
-
- return 0;
-}
-
-int rsc_uninit(struct rsc *rsc)
-{
- if ((NULL != rsc->hw) && (NULL != rsc->ctrl_blk)) {
- switch (rsc->type) {
- case SRC:
- ((struct hw *)rsc->hw)->
- src_rsc_put_ctrl_blk(rsc->ctrl_blk);
- break;
- case AMIXER:
- ((struct hw *)rsc->hw)->
- amixer_rsc_put_ctrl_blk(rsc->ctrl_blk);
- break;
- case SUM:
- case DAIO:
- break;
- default:
- printk(KERN_ERR "ctxfi: "
- "Invalid resource type value %d!\n", rsc->type);
- break;
- }
-
- rsc->hw = rsc->ctrl_blk = NULL;
- }
-
- rsc->idx = rsc->conj = 0;
- rsc->type = NUM_RSCTYP;
- rsc->msr = 0;
-
- return 0;
-}
-
-int rsc_mgr_init(struct rsc_mgr *mgr, enum RSCTYP type,
- unsigned int amount, void *hw_obj)
-{
- int err = 0;
- struct hw *hw = hw_obj;
-
- mgr->type = NUM_RSCTYP;
-
- mgr->rscs = kzalloc(((amount + 8 - 1) / 8), GFP_KERNEL);
- if (!mgr->rscs)
- return -ENOMEM;
-
- switch (type) {
- case SRC:
- err = hw->src_mgr_get_ctrl_blk(&mgr->ctrl_blk);
- break;
- case SRCIMP:
- err = hw->srcimp_mgr_get_ctrl_blk(&mgr->ctrl_blk);
- break;
- case AMIXER:
- err = hw->amixer_mgr_get_ctrl_blk(&mgr->ctrl_blk);
- break;
- case DAIO:
- err = hw->daio_mgr_get_ctrl_blk(hw, &mgr->ctrl_blk);
- break;
- case SUM:
- break;
- default:
- printk(KERN_ERR
- "ctxfi: Invalid resource type value %d!\n", type);
- err = -EINVAL;
- goto error;
- }
-
- if (err) {
- printk(KERN_ERR
- "ctxfi: Failed to get manager control block!\n");
- goto error;
- }
-
- mgr->type = type;
- mgr->avail = mgr->amount = amount;
- mgr->hw = hw;
-
- return 0;
-
-error:
- kfree(mgr->rscs);
- return err;
-}
-
-int rsc_mgr_uninit(struct rsc_mgr *mgr)
-{
- if (NULL != mgr->rscs) {
- kfree(mgr->rscs);
- mgr->rscs = NULL;
- }
-
- if ((NULL != mgr->hw) && (NULL != mgr->ctrl_blk)) {
- switch (mgr->type) {
- case SRC:
- ((struct hw *)mgr->hw)->
- src_mgr_put_ctrl_blk(mgr->ctrl_blk);
- break;
- case SRCIMP:
- ((struct hw *)mgr->hw)->
- srcimp_mgr_put_ctrl_blk(mgr->ctrl_blk);
- break;
- case AMIXER:
- ((struct hw *)mgr->hw)->
- amixer_mgr_put_ctrl_blk(mgr->ctrl_blk);
- break;
- case DAIO:
- ((struct hw *)mgr->hw)->
- daio_mgr_put_ctrl_blk(mgr->ctrl_blk);
- break;
- case SUM:
- break;
- default:
- printk(KERN_ERR "ctxfi: "
- "Invalid resource type value %d!\n", mgr->type);
- break;
- }
-
- mgr->hw = mgr->ctrl_blk = NULL;
- }
-
- mgr->type = NUM_RSCTYP;
- mgr->avail = mgr->amount = 0;
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctresource.h b/ANDROID_3.4.5/sound/pci/ctxfi/ctresource.h
deleted file mode 100644
index 0838c2e8..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/ctresource.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File ctresource.h
- *
- * @Brief
- * This file contains the definition of generic hardware resources for
- * resource management.
- *
- * @Author Liu Chun
- * @Date May 13 2008
- *
- */
-
-#ifndef CTRESOURCE_H
-#define CTRESOURCE_H
-
-#include <linux/types.h>
-
-enum RSCTYP {
- SRC,
- SRCIMP,
- AMIXER,
- SUM,
- DAIO,
- NUM_RSCTYP /* This must be the last one and less than 16 */
-};
-
-struct rsc_ops;
-
-struct rsc {
- u32 idx:12; /* The index of a resource */
- u32 type:4; /* The type (RSCTYP) of a resource */
- u32 conj:12; /* Current conjugate index */
- u32 msr:4; /* The Master Sample Rate a resource working on */
- void *ctrl_blk; /* Chip specific control info block for a resource */
- void *hw; /* Chip specific object for hardware access means */
- struct rsc_ops *ops; /* Generic resource operations */
-};
-
-struct rsc_ops {
- int (*master)(struct rsc *rsc); /* Move to master resource */
- int (*next_conj)(struct rsc *rsc); /* Move to next conjugate resource */
- int (*index)(const struct rsc *rsc); /* Return the index of resource */
- /* Return the output slot number */
- int (*output_slot)(const struct rsc *rsc);
-};
-
-int rsc_init(struct rsc *rsc, u32 idx, enum RSCTYP type, u32 msr, void *hw);
-int rsc_uninit(struct rsc *rsc);
-
-struct rsc_mgr {
- enum RSCTYP type; /* The type (RSCTYP) of resource to manage */
- unsigned int amount; /* The total amount of a kind of resource */
- unsigned int avail; /* The amount of currently available resources */
- unsigned char *rscs; /* The bit-map for resource allocation */
- void *ctrl_blk; /* Chip specific control info block */
- void *hw; /* Chip specific object for hardware access */
-};
-
-/* Resource management is based on bit-map mechanism */
-int rsc_mgr_init(struct rsc_mgr *mgr, enum RSCTYP type,
- unsigned int amount, void *hw);
-int rsc_mgr_uninit(struct rsc_mgr *mgr);
-int mgr_get_resource(struct rsc_mgr *mgr, unsigned int n, unsigned int *ridx);
-int mgr_put_resource(struct rsc_mgr *mgr, unsigned int n, unsigned int idx);
-
-#endif /* CTRESOURCE_H */
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctsrc.c b/ANDROID_3.4.5/sound/pci/ctxfi/ctsrc.c
deleted file mode 100644
index 6e77e863..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/ctsrc.c
+++ /dev/null
@@ -1,885 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File ctsrc.c
- *
- * @Brief
- * This file contains the implementation of the Sample Rate Convertor
- * resource management object.
- *
- * @Author Liu Chun
- * @Date May 13 2008
- *
- */
-
-#include "ctsrc.h"
-#include "cthardware.h"
-#include <linux/slab.h>
-
-#define SRC_RESOURCE_NUM 256
-#define SRCIMP_RESOURCE_NUM 256
-
-static unsigned int conj_mask;
-
-static int src_default_config_memrd(struct src *src);
-static int src_default_config_memwr(struct src *src);
-static int src_default_config_arcrw(struct src *src);
-
-static int (*src_default_config[3])(struct src *) = {
- [MEMRD] = src_default_config_memrd,
- [MEMWR] = src_default_config_memwr,
- [ARCRW] = src_default_config_arcrw
-};
-
-static int src_set_state(struct src *src, unsigned int state)
-{
- struct hw *hw;
-
- hw = src->rsc.hw;
- hw->src_set_state(src->rsc.ctrl_blk, state);
-
- return 0;
-}
-
-static int src_set_bm(struct src *src, unsigned int bm)
-{
- struct hw *hw;
-
- hw = src->rsc.hw;
- hw->src_set_bm(src->rsc.ctrl_blk, bm);
-
- return 0;
-}
-
-static int src_set_sf(struct src *src, unsigned int sf)
-{
- struct hw *hw;
-
- hw = src->rsc.hw;
- hw->src_set_sf(src->rsc.ctrl_blk, sf);
-
- return 0;
-}
-
-static int src_set_pm(struct src *src, unsigned int pm)
-{
- struct hw *hw;
-
- hw = src->rsc.hw;
- hw->src_set_pm(src->rsc.ctrl_blk, pm);
-
- return 0;
-}
-
-static int src_set_rom(struct src *src, unsigned int rom)
-{
- struct hw *hw;
-
- hw = src->rsc.hw;
- hw->src_set_rom(src->rsc.ctrl_blk, rom);
-
- return 0;
-}
-
-static int src_set_vo(struct src *src, unsigned int vo)
-{
- struct hw *hw;
-
- hw = src->rsc.hw;
- hw->src_set_vo(src->rsc.ctrl_blk, vo);
-
- return 0;
-}
-
-static int src_set_st(struct src *src, unsigned int st)
-{
- struct hw *hw;
-
- hw = src->rsc.hw;
- hw->src_set_st(src->rsc.ctrl_blk, st);
-
- return 0;
-}
-
-static int src_set_bp(struct src *src, unsigned int bp)
-{
- struct hw *hw;
-
- hw = src->rsc.hw;
- hw->src_set_bp(src->rsc.ctrl_blk, bp);
-
- return 0;
-}
-
-static int src_set_cisz(struct src *src, unsigned int cisz)
-{
- struct hw *hw;
-
- hw = src->rsc.hw;
- hw->src_set_cisz(src->rsc.ctrl_blk, cisz);
-
- return 0;
-}
-
-static int src_set_ca(struct src *src, unsigned int ca)
-{
- struct hw *hw;
-
- hw = src->rsc.hw;
- hw->src_set_ca(src->rsc.ctrl_blk, ca);
-
- return 0;
-}
-
-static int src_set_sa(struct src *src, unsigned int sa)
-{
- struct hw *hw;
-
- hw = src->rsc.hw;
- hw->src_set_sa(src->rsc.ctrl_blk, sa);
-
- return 0;
-}
-
-static int src_set_la(struct src *src, unsigned int la)
-{
- struct hw *hw;
-
- hw = src->rsc.hw;
- hw->src_set_la(src->rsc.ctrl_blk, la);
-
- return 0;
-}
-
-static int src_set_pitch(struct src *src, unsigned int pitch)
-{
- struct hw *hw;
-
- hw = src->rsc.hw;
- hw->src_set_pitch(src->rsc.ctrl_blk, pitch);
-
- return 0;
-}
-
-static int src_set_clear_zbufs(struct src *src)
-{
- struct hw *hw;
-
- hw = src->rsc.hw;
- hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1);
-
- return 0;
-}
-
-static int src_commit_write(struct src *src)
-{
- struct hw *hw;
- int i;
- unsigned int dirty = 0;
-
- hw = src->rsc.hw;
- src->rsc.ops->master(&src->rsc);
- if (src->rsc.msr > 1) {
- /* Save dirty flags for conjugate resource programming */
- dirty = hw->src_get_dirty(src->rsc.ctrl_blk) & conj_mask;
- }
- hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
- src->rsc.ctrl_blk);
-
- /* Program conjugate parameter mixer resources */
- if (MEMWR == src->mode)
- return 0;
-
- for (i = 1; i < src->rsc.msr; i++) {
- src->rsc.ops->next_conj(&src->rsc);
- hw->src_set_dirty(src->rsc.ctrl_blk, dirty);
- hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
- src->rsc.ctrl_blk);
- }
- src->rsc.ops->master(&src->rsc);
-
- return 0;
-}
-
-static int src_get_ca(struct src *src)
-{
- struct hw *hw;
-
- hw = src->rsc.hw;
- return hw->src_get_ca(hw, src->rsc.ops->index(&src->rsc),
- src->rsc.ctrl_blk);
-}
-
-static int src_init(struct src *src)
-{
- src_default_config[src->mode](src);
-
- return 0;
-}
-
-static struct src *src_next_interleave(struct src *src)
-{
- return src->intlv;
-}
-
-static int src_default_config_memrd(struct src *src)
-{
- struct hw *hw = src->rsc.hw;
- unsigned int rsr, msr;
-
- hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF);
- hw->src_set_bm(src->rsc.ctrl_blk, 1);
- for (rsr = 0, msr = src->rsc.msr; msr > 1; msr >>= 1)
- rsr++;
-
- hw->src_set_rsr(src->rsc.ctrl_blk, rsr);
- hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_S16);
- hw->src_set_wr(src->rsc.ctrl_blk, 0);
- hw->src_set_pm(src->rsc.ctrl_blk, 0);
- hw->src_set_rom(src->rsc.ctrl_blk, 0);
- hw->src_set_vo(src->rsc.ctrl_blk, 0);
- hw->src_set_st(src->rsc.ctrl_blk, 0);
- hw->src_set_ilsz(src->rsc.ctrl_blk, src->multi - 1);
- hw->src_set_cisz(src->rsc.ctrl_blk, 0x80);
- hw->src_set_sa(src->rsc.ctrl_blk, 0x0);
- hw->src_set_la(src->rsc.ctrl_blk, 0x1000);
- hw->src_set_ca(src->rsc.ctrl_blk, 0x80);
- hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000);
- hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1);
-
- src->rsc.ops->master(&src->rsc);
- hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
- src->rsc.ctrl_blk);
-
- for (msr = 1; msr < src->rsc.msr; msr++) {
- src->rsc.ops->next_conj(&src->rsc);
- hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000);
- hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
- src->rsc.ctrl_blk);
- }
- src->rsc.ops->master(&src->rsc);
-
- return 0;
-}
-
-static int src_default_config_memwr(struct src *src)
-{
- struct hw *hw = src->rsc.hw;
-
- hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF);
- hw->src_set_bm(src->rsc.ctrl_blk, 1);
- hw->src_set_rsr(src->rsc.ctrl_blk, 0);
- hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_S16);
- hw->src_set_wr(src->rsc.ctrl_blk, 1);
- hw->src_set_pm(src->rsc.ctrl_blk, 0);
- hw->src_set_rom(src->rsc.ctrl_blk, 0);
- hw->src_set_vo(src->rsc.ctrl_blk, 0);
- hw->src_set_st(src->rsc.ctrl_blk, 0);
- hw->src_set_ilsz(src->rsc.ctrl_blk, 0);
- hw->src_set_cisz(src->rsc.ctrl_blk, 0x80);
- hw->src_set_sa(src->rsc.ctrl_blk, 0x0);
- hw->src_set_la(src->rsc.ctrl_blk, 0x1000);
- hw->src_set_ca(src->rsc.ctrl_blk, 0x80);
- hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000);
- hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1);
-
- src->rsc.ops->master(&src->rsc);
- hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
- src->rsc.ctrl_blk);
-
- return 0;
-}
-
-static int src_default_config_arcrw(struct src *src)
-{
- struct hw *hw = src->rsc.hw;
- unsigned int rsr, msr;
- unsigned int dirty;
-
- hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF);
- hw->src_set_bm(src->rsc.ctrl_blk, 0);
- for (rsr = 0, msr = src->rsc.msr; msr > 1; msr >>= 1)
- rsr++;
-
- hw->src_set_rsr(src->rsc.ctrl_blk, rsr);
- hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_F32);
- hw->src_set_wr(src->rsc.ctrl_blk, 0);
- hw->src_set_pm(src->rsc.ctrl_blk, 0);
- hw->src_set_rom(src->rsc.ctrl_blk, 0);
- hw->src_set_vo(src->rsc.ctrl_blk, 0);
- hw->src_set_st(src->rsc.ctrl_blk, 0);
- hw->src_set_ilsz(src->rsc.ctrl_blk, 0);
- hw->src_set_cisz(src->rsc.ctrl_blk, 0x80);
- hw->src_set_sa(src->rsc.ctrl_blk, 0x0);
- /*hw->src_set_sa(src->rsc.ctrl_blk, 0x100);*/
- hw->src_set_la(src->rsc.ctrl_blk, 0x1000);
- /*hw->src_set_la(src->rsc.ctrl_blk, 0x03ffffe0);*/
- hw->src_set_ca(src->rsc.ctrl_blk, 0x80);
- hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000);
- hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1);
-
- dirty = hw->src_get_dirty(src->rsc.ctrl_blk);
- src->rsc.ops->master(&src->rsc);
- for (msr = 0; msr < src->rsc.msr; msr++) {
- hw->src_set_dirty(src->rsc.ctrl_blk, dirty);
- hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
- src->rsc.ctrl_blk);
- src->rsc.ops->next_conj(&src->rsc);
- }
- src->rsc.ops->master(&src->rsc);
-
- return 0;
-}
-
-static struct src_rsc_ops src_rsc_ops = {
- .set_state = src_set_state,
- .set_bm = src_set_bm,
- .set_sf = src_set_sf,
- .set_pm = src_set_pm,
- .set_rom = src_set_rom,
- .set_vo = src_set_vo,
- .set_st = src_set_st,
- .set_bp = src_set_bp,
- .set_cisz = src_set_cisz,
- .set_ca = src_set_ca,
- .set_sa = src_set_sa,
- .set_la = src_set_la,
- .set_pitch = src_set_pitch,
- .set_clr_zbufs = src_set_clear_zbufs,
- .commit_write = src_commit_write,
- .get_ca = src_get_ca,
- .init = src_init,
- .next_interleave = src_next_interleave,
-};
-
-static int
-src_rsc_init(struct src *src, u32 idx,
- const struct src_desc *desc, struct src_mgr *mgr)
-{
- int err;
- int i, n;
- struct src *p;
-
- n = (MEMRD == desc->mode) ? desc->multi : 1;
- for (i = 0, p = src; i < n; i++, p++) {
- err = rsc_init(&p->rsc, idx + i, SRC, desc->msr, mgr->mgr.hw);
- if (err)
- goto error1;
-
- /* Initialize src specific rsc operations */
- p->ops = &src_rsc_ops;
- p->multi = (0 == i) ? desc->multi : 1;
- p->mode = desc->mode;
- src_default_config[desc->mode](p);
- mgr->src_enable(mgr, p);
- p->intlv = p + 1;
- }
- (--p)->intlv = NULL; /* Set @intlv of the last SRC to NULL */
-
- mgr->commit_write(mgr);
-
- return 0;
-
-error1:
- for (i--, p--; i >= 0; i--, p--) {
- mgr->src_disable(mgr, p);
- rsc_uninit(&p->rsc);
- }
- mgr->commit_write(mgr);
- return err;
-}
-
-static int src_rsc_uninit(struct src *src, struct src_mgr *mgr)
-{
- int i, n;
- struct src *p;
-
- n = (MEMRD == src->mode) ? src->multi : 1;
- for (i = 0, p = src; i < n; i++, p++) {
- mgr->src_disable(mgr, p);
- rsc_uninit(&p->rsc);
- p->multi = 0;
- p->ops = NULL;
- p->mode = NUM_SRCMODES;
- p->intlv = NULL;
- }
- mgr->commit_write(mgr);
-
- return 0;
-}
-
-static int
-get_src_rsc(struct src_mgr *mgr, const struct src_desc *desc, struct src **rsrc)
-{
- unsigned int idx = SRC_RESOURCE_NUM;
- int err;
- struct src *src;
- unsigned long flags;
-
- *rsrc = NULL;
-
- /* Check whether there are sufficient src resources to meet request. */
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- if (MEMRD == desc->mode)
- err = mgr_get_resource(&mgr->mgr, desc->multi, &idx);
- else
- err = mgr_get_resource(&mgr->mgr, 1, &idx);
-
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
- if (err) {
- printk(KERN_ERR "ctxfi: Can't meet SRC resource request!\n");
- return err;
- }
-
- /* Allocate mem for master src resource */
- if (MEMRD == desc->mode)
- src = kcalloc(desc->multi, sizeof(*src), GFP_KERNEL);
- else
- src = kzalloc(sizeof(*src), GFP_KERNEL);
-
- if (!src) {
- err = -ENOMEM;
- goto error1;
- }
-
- err = src_rsc_init(src, idx, desc, mgr);
- if (err)
- goto error2;
-
- *rsrc = src;
-
- return 0;
-
-error2:
- kfree(src);
-error1:
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- if (MEMRD == desc->mode)
- mgr_put_resource(&mgr->mgr, desc->multi, idx);
- else
- mgr_put_resource(&mgr->mgr, 1, idx);
-
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
- return err;
-}
-
-static int put_src_rsc(struct src_mgr *mgr, struct src *src)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- src->rsc.ops->master(&src->rsc);
- if (MEMRD == src->mode)
- mgr_put_resource(&mgr->mgr, src->multi,
- src->rsc.ops->index(&src->rsc));
- else
- mgr_put_resource(&mgr->mgr, 1, src->rsc.ops->index(&src->rsc));
-
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
- src_rsc_uninit(src, mgr);
- kfree(src);
-
- return 0;
-}
-
-static int src_enable_s(struct src_mgr *mgr, struct src *src)
-{
- struct hw *hw = mgr->mgr.hw;
- int i;
-
- src->rsc.ops->master(&src->rsc);
- for (i = 0; i < src->rsc.msr; i++) {
- hw->src_mgr_enbs_src(mgr->mgr.ctrl_blk,
- src->rsc.ops->index(&src->rsc));
- src->rsc.ops->next_conj(&src->rsc);
- }
- src->rsc.ops->master(&src->rsc);
-
- return 0;
-}
-
-static int src_enable(struct src_mgr *mgr, struct src *src)
-{
- struct hw *hw = mgr->mgr.hw;
- int i;
-
- src->rsc.ops->master(&src->rsc);
- for (i = 0; i < src->rsc.msr; i++) {
- hw->src_mgr_enb_src(mgr->mgr.ctrl_blk,
- src->rsc.ops->index(&src->rsc));
- src->rsc.ops->next_conj(&src->rsc);
- }
- src->rsc.ops->master(&src->rsc);
-
- return 0;
-}
-
-static int src_disable(struct src_mgr *mgr, struct src *src)
-{
- struct hw *hw = mgr->mgr.hw;
- int i;
-
- src->rsc.ops->master(&src->rsc);
- for (i = 0; i < src->rsc.msr; i++) {
- hw->src_mgr_dsb_src(mgr->mgr.ctrl_blk,
- src->rsc.ops->index(&src->rsc));
- src->rsc.ops->next_conj(&src->rsc);
- }
- src->rsc.ops->master(&src->rsc);
-
- return 0;
-}
-
-static int src_mgr_commit_write(struct src_mgr *mgr)
-{
- struct hw *hw = mgr->mgr.hw;
-
- hw->src_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
-
- return 0;
-}
-
-int src_mgr_create(void *hw, struct src_mgr **rsrc_mgr)
-{
- int err, i;
- struct src_mgr *src_mgr;
-
- *rsrc_mgr = NULL;
- src_mgr = kzalloc(sizeof(*src_mgr), GFP_KERNEL);
- if (!src_mgr)
- return -ENOMEM;
-
- err = rsc_mgr_init(&src_mgr->mgr, SRC, SRC_RESOURCE_NUM, hw);
- if (err)
- goto error1;
-
- spin_lock_init(&src_mgr->mgr_lock);
- conj_mask = ((struct hw *)hw)->src_dirty_conj_mask();
-
- src_mgr->get_src = get_src_rsc;
- src_mgr->put_src = put_src_rsc;
- src_mgr->src_enable_s = src_enable_s;
- src_mgr->src_enable = src_enable;
- src_mgr->src_disable = src_disable;
- src_mgr->commit_write = src_mgr_commit_write;
-
- /* Disable all SRC resources. */
- for (i = 0; i < 256; i++)
- ((struct hw *)hw)->src_mgr_dsb_src(src_mgr->mgr.ctrl_blk, i);
-
- ((struct hw *)hw)->src_mgr_commit_write(hw, src_mgr->mgr.ctrl_blk);
-
- *rsrc_mgr = src_mgr;
-
- return 0;
-
-error1:
- kfree(src_mgr);
- return err;
-}
-
-int src_mgr_destroy(struct src_mgr *src_mgr)
-{
- rsc_mgr_uninit(&src_mgr->mgr);
- kfree(src_mgr);
-
- return 0;
-}
-
-/* SRCIMP resource manager operations */
-
-static int srcimp_master(struct rsc *rsc)
-{
- rsc->conj = 0;
- return rsc->idx = container_of(rsc, struct srcimp, rsc)->idx[0];
-}
-
-static int srcimp_next_conj(struct rsc *rsc)
-{
- rsc->conj++;
- return container_of(rsc, struct srcimp, rsc)->idx[rsc->conj];
-}
-
-static int srcimp_index(const struct rsc *rsc)
-{
- return container_of(rsc, struct srcimp, rsc)->idx[rsc->conj];
-}
-
-static struct rsc_ops srcimp_basic_rsc_ops = {
- .master = srcimp_master,
- .next_conj = srcimp_next_conj,
- .index = srcimp_index,
- .output_slot = NULL,
-};
-
-static int srcimp_map(struct srcimp *srcimp, struct src *src, struct rsc *input)
-{
- struct imapper *entry;
- int i;
-
- srcimp->rsc.ops->master(&srcimp->rsc);
- src->rsc.ops->master(&src->rsc);
- input->ops->master(input);
-
- /* Program master and conjugate resources */
- for (i = 0; i < srcimp->rsc.msr; i++) {
- entry = &srcimp->imappers[i];
- entry->slot = input->ops->output_slot(input);
- entry->user = src->rsc.ops->index(&src->rsc);
- entry->addr = srcimp->rsc.ops->index(&srcimp->rsc);
- srcimp->mgr->imap_add(srcimp->mgr, entry);
- srcimp->mapped |= (0x1 << i);
-
- srcimp->rsc.ops->next_conj(&srcimp->rsc);
- input->ops->next_conj(input);
- }
-
- srcimp->rsc.ops->master(&srcimp->rsc);
- input->ops->master(input);
-
- return 0;
-}
-
-static int srcimp_unmap(struct srcimp *srcimp)
-{
- int i;
-
- /* Program master and conjugate resources */
- for (i = 0; i < srcimp->rsc.msr; i++) {
- if (srcimp->mapped & (0x1 << i)) {
- srcimp->mgr->imap_delete(srcimp->mgr,
- &srcimp->imappers[i]);
- srcimp->mapped &= ~(0x1 << i);
- }
- }
-
- return 0;
-}
-
-static struct srcimp_rsc_ops srcimp_ops = {
- .map = srcimp_map,
- .unmap = srcimp_unmap
-};
-
-static int srcimp_rsc_init(struct srcimp *srcimp,
- const struct srcimp_desc *desc,
- struct srcimp_mgr *mgr)
-{
- int err;
-
- err = rsc_init(&srcimp->rsc, srcimp->idx[0],
- SRCIMP, desc->msr, mgr->mgr.hw);
- if (err)
- return err;
-
- /* Reserve memory for imapper nodes */
- srcimp->imappers = kzalloc(sizeof(struct imapper)*desc->msr,
- GFP_KERNEL);
- if (!srcimp->imappers) {
- err = -ENOMEM;
- goto error1;
- }
-
- /* Set srcimp specific operations */
- srcimp->rsc.ops = &srcimp_basic_rsc_ops;
- srcimp->ops = &srcimp_ops;
- srcimp->mgr = mgr;
-
- srcimp->rsc.ops->master(&srcimp->rsc);
-
- return 0;
-
-error1:
- rsc_uninit(&srcimp->rsc);
- return err;
-}
-
-static int srcimp_rsc_uninit(struct srcimp *srcimp)
-{
- if (NULL != srcimp->imappers) {
- kfree(srcimp->imappers);
- srcimp->imappers = NULL;
- }
- srcimp->ops = NULL;
- srcimp->mgr = NULL;
- rsc_uninit(&srcimp->rsc);
-
- return 0;
-}
-
-static int get_srcimp_rsc(struct srcimp_mgr *mgr,
- const struct srcimp_desc *desc,
- struct srcimp **rsrcimp)
-{
- int err, i;
- unsigned int idx;
- struct srcimp *srcimp;
- unsigned long flags;
-
- *rsrcimp = NULL;
-
- /* Allocate mem for SRCIMP resource */
- srcimp = kzalloc(sizeof(*srcimp), GFP_KERNEL);
- if (!srcimp)
- return -ENOMEM;
-
- /* Check whether there are sufficient SRCIMP resources. */
- err = 0;
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- for (i = 0; i < desc->msr; i++) {
- err = mgr_get_resource(&mgr->mgr, 1, &idx);
- if (err)
- break;
-
- srcimp->idx[i] = idx;
- }
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
- if (err) {
- printk(KERN_ERR "ctxfi: Can't meet SRCIMP resource request!\n");
- goto error1;
- }
-
- err = srcimp_rsc_init(srcimp, desc, mgr);
- if (err)
- goto error1;
-
- *rsrcimp = srcimp;
-
- return 0;
-
-error1:
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- for (i--; i >= 0; i--)
- mgr_put_resource(&mgr->mgr, 1, srcimp->idx[i]);
-
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
- kfree(srcimp);
- return err;
-}
-
-static int put_srcimp_rsc(struct srcimp_mgr *mgr, struct srcimp *srcimp)
-{
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&mgr->mgr_lock, flags);
- for (i = 0; i < srcimp->rsc.msr; i++)
- mgr_put_resource(&mgr->mgr, 1, srcimp->idx[i]);
-
- spin_unlock_irqrestore(&mgr->mgr_lock, flags);
- srcimp_rsc_uninit(srcimp);
- kfree(srcimp);
-
- return 0;
-}
-
-static int srcimp_map_op(void *data, struct imapper *entry)
-{
- struct rsc_mgr *mgr = &((struct srcimp_mgr *)data)->mgr;
- struct hw *hw = mgr->hw;
-
- hw->srcimp_mgr_set_imaparc(mgr->ctrl_blk, entry->slot);
- hw->srcimp_mgr_set_imapuser(mgr->ctrl_blk, entry->user);
- hw->srcimp_mgr_set_imapnxt(mgr->ctrl_blk, entry->next);
- hw->srcimp_mgr_set_imapaddr(mgr->ctrl_blk, entry->addr);
- hw->srcimp_mgr_commit_write(mgr->hw, mgr->ctrl_blk);
-
- return 0;
-}
-
-static int srcimp_imap_add(struct srcimp_mgr *mgr, struct imapper *entry)
-{
- unsigned long flags;
- int err;
-
- spin_lock_irqsave(&mgr->imap_lock, flags);
- if ((0 == entry->addr) && (mgr->init_imap_added)) {
- input_mapper_delete(&mgr->imappers,
- mgr->init_imap, srcimp_map_op, mgr);
- mgr->init_imap_added = 0;
- }
- err = input_mapper_add(&mgr->imappers, entry, srcimp_map_op, mgr);
- spin_unlock_irqrestore(&mgr->imap_lock, flags);
-
- return err;
-}
-
-static int srcimp_imap_delete(struct srcimp_mgr *mgr, struct imapper *entry)
-{
- unsigned long flags;
- int err;
-
- spin_lock_irqsave(&mgr->imap_lock, flags);
- err = input_mapper_delete(&mgr->imappers, entry, srcimp_map_op, mgr);
- if (list_empty(&mgr->imappers)) {
- input_mapper_add(&mgr->imappers, mgr->init_imap,
- srcimp_map_op, mgr);
- mgr->init_imap_added = 1;
- }
- spin_unlock_irqrestore(&mgr->imap_lock, flags);
-
- return err;
-}
-
-int srcimp_mgr_create(void *hw, struct srcimp_mgr **rsrcimp_mgr)
-{
- int err;
- struct srcimp_mgr *srcimp_mgr;
- struct imapper *entry;
-
- *rsrcimp_mgr = NULL;
- srcimp_mgr = kzalloc(sizeof(*srcimp_mgr), GFP_KERNEL);
- if (!srcimp_mgr)
- return -ENOMEM;
-
- err = rsc_mgr_init(&srcimp_mgr->mgr, SRCIMP, SRCIMP_RESOURCE_NUM, hw);
- if (err)
- goto error1;
-
- spin_lock_init(&srcimp_mgr->mgr_lock);
- spin_lock_init(&srcimp_mgr->imap_lock);
- INIT_LIST_HEAD(&srcimp_mgr->imappers);
- entry = kzalloc(sizeof(*entry), GFP_KERNEL);
- if (!entry) {
- err = -ENOMEM;
- goto error2;
- }
- entry->slot = entry->addr = entry->next = entry->user = 0;
- list_add(&entry->list, &srcimp_mgr->imappers);
- srcimp_mgr->init_imap = entry;
- srcimp_mgr->init_imap_added = 1;
-
- srcimp_mgr->get_srcimp = get_srcimp_rsc;
- srcimp_mgr->put_srcimp = put_srcimp_rsc;
- srcimp_mgr->imap_add = srcimp_imap_add;
- srcimp_mgr->imap_delete = srcimp_imap_delete;
-
- *rsrcimp_mgr = srcimp_mgr;
-
- return 0;
-
-error2:
- rsc_mgr_uninit(&srcimp_mgr->mgr);
-error1:
- kfree(srcimp_mgr);
- return err;
-}
-
-int srcimp_mgr_destroy(struct srcimp_mgr *srcimp_mgr)
-{
- unsigned long flags;
-
- /* free src input mapper list */
- spin_lock_irqsave(&srcimp_mgr->imap_lock, flags);
- free_input_mapper_list(&srcimp_mgr->imappers);
- spin_unlock_irqrestore(&srcimp_mgr->imap_lock, flags);
-
- rsc_mgr_uninit(&srcimp_mgr->mgr);
- kfree(srcimp_mgr);
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctsrc.h b/ANDROID_3.4.5/sound/pci/ctxfi/ctsrc.h
deleted file mode 100644
index 259366aa..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/ctsrc.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File ctsrc.h
- *
- * @Brief
- * This file contains the definition of the Sample Rate Convertor
- * resource management object.
- *
- * @Author Liu Chun
- * @Date May 13 2008
- *
- */
-
-#ifndef CTSRC_H
-#define CTSRC_H
-
-#include "ctresource.h"
-#include "ctimap.h"
-#include <linux/spinlock.h>
-#include <linux/list.h>
-
-#define SRC_STATE_OFF 0x0
-#define SRC_STATE_INIT 0x4
-#define SRC_STATE_RUN 0x5
-
-#define SRC_SF_U8 0x0
-#define SRC_SF_S16 0x1
-#define SRC_SF_S24 0x2
-#define SRC_SF_S32 0x3
-#define SRC_SF_F32 0x4
-
-/* Define the descriptor of a src resource */
-enum SRCMODE {
- MEMRD, /* Read data from host memory */
- MEMWR, /* Write data to host memory */
- ARCRW, /* Read from and write to audio ring channel */
- NUM_SRCMODES
-};
-
-struct src_rsc_ops;
-
-struct src {
- struct rsc rsc; /* Basic resource info */
- struct src *intlv; /* Pointer to next interleaved SRC in a series */
- struct src_rsc_ops *ops; /* SRC specific operations */
- /* Number of contiguous srcs for interleaved usage */
- unsigned char multi;
- unsigned char mode; /* Working mode of this SRC resource */
-};
-
-struct src_rsc_ops {
- int (*set_state)(struct src *src, unsigned int state);
- int (*set_bm)(struct src *src, unsigned int bm);
- int (*set_sf)(struct src *src, unsigned int sf);
- int (*set_pm)(struct src *src, unsigned int pm);
- int (*set_rom)(struct src *src, unsigned int rom);
- int (*set_vo)(struct src *src, unsigned int vo);
- int (*set_st)(struct src *src, unsigned int st);
- int (*set_bp)(struct src *src, unsigned int bp);
- int (*set_cisz)(struct src *src, unsigned int cisz);
- int (*set_ca)(struct src *src, unsigned int ca);
- int (*set_sa)(struct src *src, unsigned int sa);
- int (*set_la)(struct src *src, unsigned int la);
- int (*set_pitch)(struct src *src, unsigned int pitch);
- int (*set_clr_zbufs)(struct src *src);
- int (*commit_write)(struct src *src);
- int (*get_ca)(struct src *src);
- int (*init)(struct src *src);
- struct src* (*next_interleave)(struct src *src);
-};
-
-/* Define src resource request description info */
-struct src_desc {
- /* Number of contiguous master srcs for interleaved usage */
- unsigned char multi;
- unsigned char msr;
- unsigned char mode; /* Working mode of the requested srcs */
-};
-
-/* Define src manager object */
-struct src_mgr {
- struct rsc_mgr mgr; /* Basic resource manager info */
- spinlock_t mgr_lock;
-
- /* request src resource */
- int (*get_src)(struct src_mgr *mgr,
- const struct src_desc *desc, struct src **rsrc);
- /* return src resource */
- int (*put_src)(struct src_mgr *mgr, struct src *src);
- int (*src_enable_s)(struct src_mgr *mgr, struct src *src);
- int (*src_enable)(struct src_mgr *mgr, struct src *src);
- int (*src_disable)(struct src_mgr *mgr, struct src *src);
- int (*commit_write)(struct src_mgr *mgr);
-};
-
-/* Define the descriptor of a SRC Input Mapper resource */
-struct srcimp_mgr;
-struct srcimp_rsc_ops;
-
-struct srcimp {
- struct rsc rsc;
- unsigned char idx[8];
- struct imapper *imappers;
- unsigned int mapped; /* A bit-map indicating which conj rsc is mapped */
- struct srcimp_mgr *mgr;
- struct srcimp_rsc_ops *ops;
-};
-
-struct srcimp_rsc_ops {
- int (*map)(struct srcimp *srcimp, struct src *user, struct rsc *input);
- int (*unmap)(struct srcimp *srcimp);
-};
-
-/* Define SRCIMP resource request description info */
-struct srcimp_desc {
- unsigned int msr;
-};
-
-struct srcimp_mgr {
- struct rsc_mgr mgr; /* Basic resource manager info */
- spinlock_t mgr_lock;
- spinlock_t imap_lock;
- struct list_head imappers;
- struct imapper *init_imap;
- unsigned int init_imap_added;
-
- /* request srcimp resource */
- int (*get_srcimp)(struct srcimp_mgr *mgr,
- const struct srcimp_desc *desc,
- struct srcimp **rsrcimp);
- /* return srcimp resource */
- int (*put_srcimp)(struct srcimp_mgr *mgr, struct srcimp *srcimp);
- int (*imap_add)(struct srcimp_mgr *mgr, struct imapper *entry);
- int (*imap_delete)(struct srcimp_mgr *mgr, struct imapper *entry);
-};
-
-/* Constructor and destructor of SRC resource manager */
-int src_mgr_create(void *hw, struct src_mgr **rsrc_mgr);
-int src_mgr_destroy(struct src_mgr *src_mgr);
-/* Constructor and destructor of SRCIMP resource manager */
-int srcimp_mgr_create(void *hw, struct srcimp_mgr **rsrc_mgr);
-int srcimp_mgr_destroy(struct srcimp_mgr *srcimp_mgr);
-
-#endif /* CTSRC_H */
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/cttimer.c b/ANDROID_3.4.5/sound/pci/ctxfi/cttimer.c
deleted file mode 100644
index 03fb9090..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/cttimer.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * PCM timer handling on ctxfi
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- */
-
-#include <linux/slab.h>
-#include <linux/math64.h>
-#include <linux/moduleparam.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include "ctatc.h"
-#include "cthardware.h"
-#include "cttimer.h"
-
-static bool use_system_timer;
-MODULE_PARM_DESC(use_system_timer, "Force to use system-timer");
-module_param(use_system_timer, bool, S_IRUGO);
-
-struct ct_timer_ops {
- void (*init)(struct ct_timer_instance *);
- void (*prepare)(struct ct_timer_instance *);
- void (*start)(struct ct_timer_instance *);
- void (*stop)(struct ct_timer_instance *);
- void (*free_instance)(struct ct_timer_instance *);
- void (*interrupt)(struct ct_timer *);
- void (*free_global)(struct ct_timer *);
-};
-
-/* timer instance -- assigned to each PCM stream */
-struct ct_timer_instance {
- spinlock_t lock;
- struct ct_timer *timer_base;
- struct ct_atc_pcm *apcm;
- struct snd_pcm_substream *substream;
- struct timer_list timer;
- struct list_head instance_list;
- struct list_head running_list;
- unsigned int position;
- unsigned int frag_count;
- unsigned int running:1;
- unsigned int need_update:1;
-};
-
-/* timer instance manager */
-struct ct_timer {
- spinlock_t lock; /* global timer lock (for xfitimer) */
- spinlock_t list_lock; /* lock for instance list */
- struct ct_atc *atc;
- struct ct_timer_ops *ops;
- struct list_head instance_head;
- struct list_head running_head;
- unsigned int wc; /* current wallclock */
- unsigned int irq_handling:1; /* in IRQ handling */
- unsigned int reprogram:1; /* need to reprogram the internval */
- unsigned int running:1; /* global timer running */
-};
-
-
-/*
- * system-timer-based updates
- */
-
-static void ct_systimer_callback(unsigned long data)
-{
- struct ct_timer_instance *ti = (struct ct_timer_instance *)data;
- struct snd_pcm_substream *substream = ti->substream;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct ct_atc_pcm *apcm = ti->apcm;
- unsigned int period_size = runtime->period_size;
- unsigned int buffer_size = runtime->buffer_size;
- unsigned long flags;
- unsigned int position, dist, interval;
-
- position = substream->ops->pointer(substream);
- dist = (position + buffer_size - ti->position) % buffer_size;
- if (dist >= period_size ||
- position / period_size != ti->position / period_size) {
- apcm->interrupt(apcm);
- ti->position = position;
- }
- /* Add extra HZ*5/1000 to avoid overrun issue when recording
- * at 8kHz in 8-bit format or at 88kHz in 24-bit format. */
- interval = ((period_size - (position % period_size))
- * HZ + (runtime->rate - 1)) / runtime->rate + HZ * 5 / 1000;
- spin_lock_irqsave(&ti->lock, flags);
- if (ti->running)
- mod_timer(&ti->timer, jiffies + interval);
- spin_unlock_irqrestore(&ti->lock, flags);
-}
-
-static void ct_systimer_init(struct ct_timer_instance *ti)
-{
- setup_timer(&ti->timer, ct_systimer_callback,
- (unsigned long)ti);
-}
-
-static void ct_systimer_start(struct ct_timer_instance *ti)
-{
- struct snd_pcm_runtime *runtime = ti->substream->runtime;
- unsigned long flags;
-
- spin_lock_irqsave(&ti->lock, flags);
- ti->running = 1;
- mod_timer(&ti->timer,
- jiffies + (runtime->period_size * HZ +
- (runtime->rate - 1)) / runtime->rate);
- spin_unlock_irqrestore(&ti->lock, flags);
-}
-
-static void ct_systimer_stop(struct ct_timer_instance *ti)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ti->lock, flags);
- ti->running = 0;
- del_timer(&ti->timer);
- spin_unlock_irqrestore(&ti->lock, flags);
-}
-
-static void ct_systimer_prepare(struct ct_timer_instance *ti)
-{
- ct_systimer_stop(ti);
- try_to_del_timer_sync(&ti->timer);
-}
-
-#define ct_systimer_free ct_systimer_prepare
-
-static struct ct_timer_ops ct_systimer_ops = {
- .init = ct_systimer_init,
- .free_instance = ct_systimer_free,
- .prepare = ct_systimer_prepare,
- .start = ct_systimer_start,
- .stop = ct_systimer_stop,
-};
-
-
-/*
- * Handling multiple streams using a global emu20k1 timer irq
- */
-
-#define CT_TIMER_FREQ 48000
-#define MIN_TICKS 1
-#define MAX_TICKS ((1 << 13) - 1)
-
-static void ct_xfitimer_irq_rearm(struct ct_timer *atimer, int ticks)
-{
- struct hw *hw = atimer->atc->hw;
- if (ticks > MAX_TICKS)
- ticks = MAX_TICKS;
- hw->set_timer_tick(hw, ticks);
- if (!atimer->running)
- hw->set_timer_irq(hw, 1);
- atimer->running = 1;
-}
-
-static void ct_xfitimer_irq_stop(struct ct_timer *atimer)
-{
- if (atimer->running) {
- struct hw *hw = atimer->atc->hw;
- hw->set_timer_irq(hw, 0);
- hw->set_timer_tick(hw, 0);
- atimer->running = 0;
- }
-}
-
-static inline unsigned int ct_xfitimer_get_wc(struct ct_timer *atimer)
-{
- struct hw *hw = atimer->atc->hw;
- return hw->get_wc(hw);
-}
-
-/*
- * reprogram the timer interval;
- * checks the running instance list and determines the next timer interval.
- * also updates the each stream position, returns the number of streams
- * to call snd_pcm_period_elapsed() appropriately
- *
- * call this inside the lock and irq disabled
- */
-static int ct_xfitimer_reprogram(struct ct_timer *atimer, int can_update)
-{
- struct ct_timer_instance *ti;
- unsigned int min_intr = (unsigned int)-1;
- int updates = 0;
- unsigned int wc, diff;
-
- if (list_empty(&atimer->running_head)) {
- ct_xfitimer_irq_stop(atimer);
- atimer->reprogram = 0; /* clear flag */
- return 0;
- }
-
- wc = ct_xfitimer_get_wc(atimer);
- diff = wc - atimer->wc;
- atimer->wc = wc;
- list_for_each_entry(ti, &atimer->running_head, running_list) {
- if (ti->frag_count > diff)
- ti->frag_count -= diff;
- else {
- unsigned int pos;
- unsigned int period_size, rate;
-
- period_size = ti->substream->runtime->period_size;
- rate = ti->substream->runtime->rate;
- pos = ti->substream->ops->pointer(ti->substream);
- if (pos / period_size != ti->position / period_size) {
- ti->need_update = 1;
- ti->position = pos;
- updates++;
- }
- pos %= period_size;
- pos = period_size - pos;
- ti->frag_count = div_u64((u64)pos * CT_TIMER_FREQ +
- rate - 1, rate);
- }
- if (ti->need_update && !can_update)
- min_intr = 0; /* pending to the next irq */
- if (ti->frag_count < min_intr)
- min_intr = ti->frag_count;
- }
-
- if (min_intr < MIN_TICKS)
- min_intr = MIN_TICKS;
- ct_xfitimer_irq_rearm(atimer, min_intr);
- atimer->reprogram = 0; /* clear flag */
- return updates;
-}
-
-/* look through the instance list and call period_elapsed if needed */
-static void ct_xfitimer_check_period(struct ct_timer *atimer)
-{
- struct ct_timer_instance *ti;
- unsigned long flags;
-
- spin_lock_irqsave(&atimer->list_lock, flags);
- list_for_each_entry(ti, &atimer->instance_head, instance_list) {
- if (ti->running && ti->need_update) {
- ti->need_update = 0;
- ti->apcm->interrupt(ti->apcm);
- }
- }
- spin_unlock_irqrestore(&atimer->list_lock, flags);
-}
-
-/* Handle timer-interrupt */
-static void ct_xfitimer_callback(struct ct_timer *atimer)
-{
- int update;
- unsigned long flags;
-
- spin_lock_irqsave(&atimer->lock, flags);
- atimer->irq_handling = 1;
- do {
- update = ct_xfitimer_reprogram(atimer, 1);
- spin_unlock(&atimer->lock);
- if (update)
- ct_xfitimer_check_period(atimer);
- spin_lock(&atimer->lock);
- } while (atimer->reprogram);
- atimer->irq_handling = 0;
- spin_unlock_irqrestore(&atimer->lock, flags);
-}
-
-static void ct_xfitimer_prepare(struct ct_timer_instance *ti)
-{
- ti->frag_count = ti->substream->runtime->period_size;
- ti->running = 0;
- ti->need_update = 0;
-}
-
-
-/* start/stop the timer */
-static void ct_xfitimer_update(struct ct_timer *atimer)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&atimer->lock, flags);
- if (atimer->irq_handling) {
- /* reached from IRQ handler; let it handle later */
- atimer->reprogram = 1;
- spin_unlock_irqrestore(&atimer->lock, flags);
- return;
- }
-
- ct_xfitimer_irq_stop(atimer);
- ct_xfitimer_reprogram(atimer, 0);
- spin_unlock_irqrestore(&atimer->lock, flags);
-}
-
-static void ct_xfitimer_start(struct ct_timer_instance *ti)
-{
- struct ct_timer *atimer = ti->timer_base;
- unsigned long flags;
-
- spin_lock_irqsave(&atimer->lock, flags);
- if (list_empty(&ti->running_list))
- atimer->wc = ct_xfitimer_get_wc(atimer);
- ti->running = 1;
- ti->need_update = 0;
- list_add(&ti->running_list, &atimer->running_head);
- spin_unlock_irqrestore(&atimer->lock, flags);
- ct_xfitimer_update(atimer);
-}
-
-static void ct_xfitimer_stop(struct ct_timer_instance *ti)
-{
- struct ct_timer *atimer = ti->timer_base;
- unsigned long flags;
-
- spin_lock_irqsave(&atimer->lock, flags);
- list_del_init(&ti->running_list);
- ti->running = 0;
- spin_unlock_irqrestore(&atimer->lock, flags);
- ct_xfitimer_update(atimer);
-}
-
-static void ct_xfitimer_free_global(struct ct_timer *atimer)
-{
- ct_xfitimer_irq_stop(atimer);
-}
-
-static struct ct_timer_ops ct_xfitimer_ops = {
- .prepare = ct_xfitimer_prepare,
- .start = ct_xfitimer_start,
- .stop = ct_xfitimer_stop,
- .interrupt = ct_xfitimer_callback,
- .free_global = ct_xfitimer_free_global,
-};
-
-/*
- * timer instance
- */
-
-struct ct_timer_instance *
-ct_timer_instance_new(struct ct_timer *atimer, struct ct_atc_pcm *apcm)
-{
- struct ct_timer_instance *ti;
-
- ti = kzalloc(sizeof(*ti), GFP_KERNEL);
- if (!ti)
- return NULL;
- spin_lock_init(&ti->lock);
- INIT_LIST_HEAD(&ti->instance_list);
- INIT_LIST_HEAD(&ti->running_list);
- ti->timer_base = atimer;
- ti->apcm = apcm;
- ti->substream = apcm->substream;
- if (atimer->ops->init)
- atimer->ops->init(ti);
-
- spin_lock_irq(&atimer->list_lock);
- list_add(&ti->instance_list, &atimer->instance_head);
- spin_unlock_irq(&atimer->list_lock);
-
- return ti;
-}
-
-void ct_timer_prepare(struct ct_timer_instance *ti)
-{
- if (ti->timer_base->ops->prepare)
- ti->timer_base->ops->prepare(ti);
- ti->position = 0;
- ti->running = 0;
-}
-
-void ct_timer_start(struct ct_timer_instance *ti)
-{
- struct ct_timer *atimer = ti->timer_base;
- atimer->ops->start(ti);
-}
-
-void ct_timer_stop(struct ct_timer_instance *ti)
-{
- struct ct_timer *atimer = ti->timer_base;
- atimer->ops->stop(ti);
-}
-
-void ct_timer_instance_free(struct ct_timer_instance *ti)
-{
- struct ct_timer *atimer = ti->timer_base;
-
- atimer->ops->stop(ti); /* to be sure */
- if (atimer->ops->free_instance)
- atimer->ops->free_instance(ti);
-
- spin_lock_irq(&atimer->list_lock);
- list_del(&ti->instance_list);
- spin_unlock_irq(&atimer->list_lock);
-
- kfree(ti);
-}
-
-/*
- * timer manager
- */
-
-static void ct_timer_interrupt(void *data, unsigned int status)
-{
- struct ct_timer *timer = data;
-
- /* Interval timer interrupt */
- if ((status & IT_INT) && timer->ops->interrupt)
- timer->ops->interrupt(timer);
-}
-
-struct ct_timer *ct_timer_new(struct ct_atc *atc)
-{
- struct ct_timer *atimer;
- struct hw *hw;
-
- atimer = kzalloc(sizeof(*atimer), GFP_KERNEL);
- if (!atimer)
- return NULL;
- spin_lock_init(&atimer->lock);
- spin_lock_init(&atimer->list_lock);
- INIT_LIST_HEAD(&atimer->instance_head);
- INIT_LIST_HEAD(&atimer->running_head);
- atimer->atc = atc;
- hw = atc->hw;
- if (!use_system_timer && hw->set_timer_irq) {
- snd_printd(KERN_INFO "ctxfi: Use xfi-native timer\n");
- atimer->ops = &ct_xfitimer_ops;
- hw->irq_callback_data = atimer;
- hw->irq_callback = ct_timer_interrupt;
- } else {
- snd_printd(KERN_INFO "ctxfi: Use system timer\n");
- atimer->ops = &ct_systimer_ops;
- }
- return atimer;
-}
-
-void ct_timer_free(struct ct_timer *atimer)
-{
- struct hw *hw = atimer->atc->hw;
- hw->irq_callback = NULL;
- if (atimer->ops->free_global)
- atimer->ops->free_global(atimer);
- kfree(atimer);
-}
-
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/cttimer.h b/ANDROID_3.4.5/sound/pci/ctxfi/cttimer.h
deleted file mode 100644
index 97934822..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/cttimer.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Timer handling
- */
-
-#ifndef __CTTIMER_H
-#define __CTTIMER_H
-
-#include <linux/spinlock.h>
-#include <linux/timer.h>
-#include <linux/list.h>
-
-struct snd_pcm_substream;
-struct ct_atc;
-struct ct_atc_pcm;
-
-struct ct_timer;
-struct ct_timer_instance;
-
-struct ct_timer *ct_timer_new(struct ct_atc *atc);
-void ct_timer_free(struct ct_timer *atimer);
-
-struct ct_timer_instance *
-ct_timer_instance_new(struct ct_timer *atimer, struct ct_atc_pcm *apcm);
-void ct_timer_instance_free(struct ct_timer_instance *ti);
-void ct_timer_start(struct ct_timer_instance *ti);
-void ct_timer_stop(struct ct_timer_instance *ti);
-void ct_timer_prepare(struct ct_timer_instance *ti);
-
-#endif /* __CTTIMER_H */
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctvmem.c b/ANDROID_3.4.5/sound/pci/ctxfi/ctvmem.c
deleted file mode 100644
index 6109490b..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/ctvmem.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File ctvmem.c
- *
- * @Brief
- * This file contains the implementation of virtual memory management object
- * for card device.
- *
- * @Author Liu Chun
- * @Date Apr 1 2008
- */
-
-#include "ctvmem.h"
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/io.h>
-#include <sound/pcm.h>
-
-#define CT_PTES_PER_PAGE (CT_PAGE_SIZE / sizeof(void *))
-#define CT_ADDRS_PER_PAGE (CT_PTES_PER_PAGE * CT_PAGE_SIZE)
-
-/* *
- * Find or create vm block based on requested @size.
- * @size must be page aligned.
- * */
-static struct ct_vm_block *
-get_vm_block(struct ct_vm *vm, unsigned int size)
-{
- struct ct_vm_block *block = NULL, *entry;
- struct list_head *pos;
-
- size = CT_PAGE_ALIGN(size);
- if (size > vm->size) {
- printk(KERN_ERR "ctxfi: Fail! No sufficient device virtual "
- "memory space available!\n");
- return NULL;
- }
-
- mutex_lock(&vm->lock);
- list_for_each(pos, &vm->unused) {
- entry = list_entry(pos, struct ct_vm_block, list);
- if (entry->size >= size)
- break; /* found a block that is big enough */
- }
- if (pos == &vm->unused)
- goto out;
-
- if (entry->size == size) {
- /* Move the vm node from unused list to used list directly */
- list_move(&entry->list, &vm->used);
- vm->size -= size;
- block = entry;
- goto out;
- }
-
- block = kzalloc(sizeof(*block), GFP_KERNEL);
- if (!block)
- goto out;
-
- block->addr = entry->addr;
- block->size = size;
- list_add(&block->list, &vm->used);
- entry->addr += size;
- entry->size -= size;
- vm->size -= size;
-
- out:
- mutex_unlock(&vm->lock);
- return block;
-}
-
-static void put_vm_block(struct ct_vm *vm, struct ct_vm_block *block)
-{
- struct ct_vm_block *entry, *pre_ent;
- struct list_head *pos, *pre;
-
- block->size = CT_PAGE_ALIGN(block->size);
-
- mutex_lock(&vm->lock);
- list_del(&block->list);
- vm->size += block->size;
-
- list_for_each(pos, &vm->unused) {
- entry = list_entry(pos, struct ct_vm_block, list);
- if (entry->addr >= (block->addr + block->size))
- break; /* found a position */
- }
- if (pos == &vm->unused) {
- list_add_tail(&block->list, &vm->unused);
- entry = block;
- } else {
- if ((block->addr + block->size) == entry->addr) {
- entry->addr = block->addr;
- entry->size += block->size;
- kfree(block);
- } else {
- __list_add(&block->list, pos->prev, pos);
- entry = block;
- }
- }
-
- pos = &entry->list;
- pre = pos->prev;
- while (pre != &vm->unused) {
- entry = list_entry(pos, struct ct_vm_block, list);
- pre_ent = list_entry(pre, struct ct_vm_block, list);
- if ((pre_ent->addr + pre_ent->size) > entry->addr)
- break;
-
- pre_ent->size += entry->size;
- list_del(pos);
- kfree(entry);
- pos = pre;
- pre = pos->prev;
- }
- mutex_unlock(&vm->lock);
-}
-
-/* Map host addr (kmalloced/vmalloced) to device logical addr. */
-static struct ct_vm_block *
-ct_vm_map(struct ct_vm *vm, struct snd_pcm_substream *substream, int size)
-{
- struct ct_vm_block *block;
- unsigned int pte_start;
- unsigned i, pages;
- unsigned long *ptp;
-
- block = get_vm_block(vm, size);
- if (block == NULL) {
- printk(KERN_ERR "ctxfi: No virtual memory block that is big "
- "enough to allocate!\n");
- return NULL;
- }
-
- ptp = (unsigned long *)vm->ptp[0].area;
- pte_start = (block->addr >> CT_PAGE_SHIFT);
- pages = block->size >> CT_PAGE_SHIFT;
- for (i = 0; i < pages; i++) {
- unsigned long addr;
- addr = snd_pcm_sgbuf_get_addr(substream, i << CT_PAGE_SHIFT);
- ptp[pte_start + i] = addr;
- }
-
- block->size = size;
- return block;
-}
-
-static void ct_vm_unmap(struct ct_vm *vm, struct ct_vm_block *block)
-{
- /* do unmapping */
- put_vm_block(vm, block);
-}
-
-/* *
- * return the host physical addr of the @index-th device
- * page table page on success, or ~0UL on failure.
- * The first returned ~0UL indicates the termination.
- * */
-static dma_addr_t
-ct_get_ptp_phys(struct ct_vm *vm, int index)
-{
- dma_addr_t addr;
-
- addr = (index >= CT_PTP_NUM) ? ~0UL : vm->ptp[index].addr;
-
- return addr;
-}
-
-int ct_vm_create(struct ct_vm **rvm, struct pci_dev *pci)
-{
- struct ct_vm *vm;
- struct ct_vm_block *block;
- int i, err = 0;
-
- *rvm = NULL;
-
- vm = kzalloc(sizeof(*vm), GFP_KERNEL);
- if (!vm)
- return -ENOMEM;
-
- mutex_init(&vm->lock);
-
- /* Allocate page table pages */
- for (i = 0; i < CT_PTP_NUM; i++) {
- err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(pci),
- PAGE_SIZE, &vm->ptp[i]);
- if (err < 0)
- break;
- }
- if (err < 0) {
- /* no page table pages are allocated */
- ct_vm_destroy(vm);
- return -ENOMEM;
- }
- vm->size = CT_ADDRS_PER_PAGE * i;
- vm->map = ct_vm_map;
- vm->unmap = ct_vm_unmap;
- vm->get_ptp_phys = ct_get_ptp_phys;
- INIT_LIST_HEAD(&vm->unused);
- INIT_LIST_HEAD(&vm->used);
- block = kzalloc(sizeof(*block), GFP_KERNEL);
- if (NULL != block) {
- block->addr = 0;
- block->size = vm->size;
- list_add(&block->list, &vm->unused);
- }
-
- *rvm = vm;
- return 0;
-}
-
-/* The caller must ensure no mapping pages are being used
- * by hardware before calling this function */
-void ct_vm_destroy(struct ct_vm *vm)
-{
- int i;
- struct list_head *pos;
- struct ct_vm_block *entry;
-
- /* free used and unused list nodes */
- while (!list_empty(&vm->used)) {
- pos = vm->used.next;
- list_del(pos);
- entry = list_entry(pos, struct ct_vm_block, list);
- kfree(entry);
- }
- while (!list_empty(&vm->unused)) {
- pos = vm->unused.next;
- list_del(pos);
- entry = list_entry(pos, struct ct_vm_block, list);
- kfree(entry);
- }
-
- /* free allocated page table pages */
- for (i = 0; i < CT_PTP_NUM; i++)
- snd_dma_free_pages(&vm->ptp[i]);
-
- vm->size = 0;
-
- kfree(vm);
-}
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/ctvmem.h b/ANDROID_3.4.5/sound/pci/ctxfi/ctvmem.h
deleted file mode 100644
index e6da60eb..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/ctvmem.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- *
- * @File ctvmem.h
- *
- * @Brief
- * This file contains the definition of virtual memory management object
- * for card device.
- *
- * @Author Liu Chun
- * @Date Mar 28 2008
- */
-
-#ifndef CTVMEM_H
-#define CTVMEM_H
-
-#define CT_PTP_NUM 4 /* num of device page table pages */
-
-#include <linux/mutex.h>
-#include <linux/list.h>
-#include <linux/pci.h>
-#include <sound/memalloc.h>
-
-/* The chip can handle the page table of 4k pages
- * (emu20k1 can handle even 8k pages, but we don't use it right now)
- */
-#define CT_PAGE_SIZE 4096
-#define CT_PAGE_SHIFT 12
-#define CT_PAGE_MASK (~(PAGE_SIZE - 1))
-#define CT_PAGE_ALIGN(addr) ALIGN(addr, CT_PAGE_SIZE)
-
-struct ct_vm_block {
- unsigned int addr; /* starting logical addr of this block */
- unsigned int size; /* size of this device virtual mem block */
- struct list_head list;
-};
-
-struct snd_pcm_substream;
-
-/* Virtual memory management object for card device */
-struct ct_vm {
- struct snd_dma_buffer ptp[CT_PTP_NUM]; /* Device page table pages */
- unsigned int size; /* Available addr space in bytes */
- struct list_head unused; /* List of unused blocks */
- struct list_head used; /* List of used blocks */
- struct mutex lock;
-
- /* Map host addr (kmalloced/vmalloced) to device logical addr. */
- struct ct_vm_block *(*map)(struct ct_vm *, struct snd_pcm_substream *,
- int size);
- /* Unmap device logical addr area. */
- void (*unmap)(struct ct_vm *, struct ct_vm_block *block);
- dma_addr_t (*get_ptp_phys)(struct ct_vm *vm, int index);
-};
-
-int ct_vm_create(struct ct_vm **rvm, struct pci_dev *pci);
-void ct_vm_destroy(struct ct_vm *vm);
-
-#endif /* CTVMEM_H */
diff --git a/ANDROID_3.4.5/sound/pci/ctxfi/xfi.c b/ANDROID_3.4.5/sound/pci/ctxfi/xfi.c
deleted file mode 100644
index 15d95d2b..00000000
--- a/ANDROID_3.4.5/sound/pci/ctxfi/xfi.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * xfi linux driver.
- *
- * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
- *
- * This source file is released under GPL v2 license (no other versions).
- * See the COPYING file included in the main directory of this source
- * distribution for the license terms and conditions.
- */
-
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/moduleparam.h>
-#include <linux/pci_ids.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include "ctatc.h"
-#include "cthardware.h"
-
-MODULE_AUTHOR("Creative Technology Ltd");
-MODULE_DESCRIPTION("X-Fi driver version 1.03");
-MODULE_LICENSE("GPL v2");
-MODULE_SUPPORTED_DEVICE("{{Creative Labs, Sound Blaster X-Fi}");
-
-static unsigned int reference_rate = 48000;
-static unsigned int multiple = 2;
-MODULE_PARM_DESC(reference_rate, "Reference rate (default=48000)");
-module_param(reference_rate, uint, S_IRUGO);
-MODULE_PARM_DESC(multiple, "Rate multiplier (default=2)");
-module_param(multiple, uint, S_IRUGO);
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static unsigned int subsystem[SNDRV_CARDS];
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Creative X-Fi driver");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Creative X-Fi driver");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Creative X-Fi driver");
-module_param_array(subsystem, int, NULL, 0444);
-MODULE_PARM_DESC(subsystem, "Override subsystem ID for Creative X-Fi driver");
-
-static DEFINE_PCI_DEVICE_TABLE(ct_pci_dev_ids) = {
- /* only X-Fi is supported, so... */
- { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K1),
- .driver_data = ATC20K1,
- },
- { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K2),
- .driver_data = ATC20K2,
- },
- { 0, }
-};
-MODULE_DEVICE_TABLE(pci, ct_pci_dev_ids);
-
-static int __devinit
-ct_card_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct ct_atc *atc;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
-
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err)
- return err;
- if ((reference_rate != 48000) && (reference_rate != 44100)) {
- printk(KERN_ERR "ctxfi: Invalid reference_rate value %u!!!\n",
- reference_rate);
- printk(KERN_ERR "ctxfi: The valid values for reference_rate "
- "are 48000 and 44100, Value 48000 is assumed.\n");
- reference_rate = 48000;
- }
- if ((multiple != 1) && (multiple != 2) && (multiple != 4)) {
- printk(KERN_ERR "ctxfi: Invalid multiple value %u!!!\n",
- multiple);
- printk(KERN_ERR "ctxfi: The valid values for multiple are "
- "1, 2 and 4, Value 2 is assumed.\n");
- multiple = 2;
- }
- err = ct_atc_create(card, pci, reference_rate, multiple,
- pci_id->driver_data, subsystem[dev], &atc);
- if (err < 0)
- goto error;
-
- card->private_data = atc;
-
- /* Create alsa devices supported by this card */
- err = ct_atc_create_alsa_devs(atc);
- if (err < 0)
- goto error;
-
- strcpy(card->driver, "SB-XFi");
- strcpy(card->shortname, "Creative X-Fi");
- snprintf(card->longname, sizeof(card->longname), "%s %s %s",
- card->shortname, atc->chip_name, atc->model_name);
-
- err = snd_card_register(card);
- if (err < 0)
- goto error;
-
- pci_set_drvdata(pci, card);
- dev++;
-
- return 0;
-
-error:
- snd_card_free(card);
- return err;
-}
-
-static void __devexit ct_card_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-#ifdef CONFIG_PM
-static int ct_card_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct ct_atc *atc = card->private_data;
-
- return atc->suspend(atc, state);
-}
-
-static int ct_card_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct ct_atc *atc = card->private_data;
-
- return atc->resume(atc);
-}
-#endif
-
-static struct pci_driver ct_driver = {
- .name = KBUILD_MODNAME,
- .id_table = ct_pci_dev_ids,
- .probe = ct_card_probe,
- .remove = __devexit_p(ct_card_remove),
-#ifdef CONFIG_PM
- .suspend = ct_card_suspend,
- .resume = ct_card_resume,
-#endif
-};
-
-static int __init ct_card_init(void)
-{
- return pci_register_driver(&ct_driver);
-}
-
-static void __exit ct_card_exit(void)
-{
- pci_unregister_driver(&ct_driver);
-}
-
-module_init(ct_card_init)
-module_exit(ct_card_exit)
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/Makefile b/ANDROID_3.4.5/sound/pci/echoaudio/Makefile
deleted file mode 100644
index 1361de77..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-#
-# Makefile for ALSA Echoaudio soundcard drivers
-# Copyright (c) 2003 by Giuliano Pochini <pochini@shiny.it>
-#
-
-snd-darla20-objs := darla20.o
-snd-gina20-objs := gina20.o
-snd-layla20-objs := layla20.o
-snd-darla24-objs := darla24.o
-snd-gina24-objs := gina24.o
-snd-layla24-objs := layla24.o
-snd-mona-objs := mona.o
-snd-mia-objs := mia.o
-snd-echo3g-objs := echo3g.o
-snd-indigo-objs := indigo.o
-snd-indigoio-objs := indigoio.o
-snd-indigodj-objs := indigodj.o
-snd-indigoiox-objs := indigoiox.o
-snd-indigodjx-objs := indigodjx.o
-
-obj-$(CONFIG_SND_DARLA20) += snd-darla20.o
-obj-$(CONFIG_SND_GINA20) += snd-gina20.o
-obj-$(CONFIG_SND_LAYLA20) += snd-layla20.o
-obj-$(CONFIG_SND_DARLA24) += snd-darla24.o
-obj-$(CONFIG_SND_GINA24) += snd-gina24.o
-obj-$(CONFIG_SND_LAYLA24) += snd-layla24.o
-obj-$(CONFIG_SND_MONA) += snd-mona.o
-obj-$(CONFIG_SND_MIA) += snd-mia.o
-obj-$(CONFIG_SND_ECHO3G) += snd-echo3g.o
-obj-$(CONFIG_SND_INDIGO) += snd-indigo.o
-obj-$(CONFIG_SND_INDIGOIO) += snd-indigoio.o
-obj-$(CONFIG_SND_INDIGODJ) += snd-indigodj.o
-obj-$(CONFIG_SND_INDIGOIOX) += snd-indigoiox.o
-obj-$(CONFIG_SND_INDIGODJX) += snd-indigodjx.o
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/darla20.c b/ANDROID_3.4.5/sound/pci/echoaudio/darla20.c
deleted file mode 100644
index d47e72ae..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/darla20.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * ALSA driver for Echoaudio soundcards.
- * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#define ECHOGALS_FAMILY
-#define ECHOCARD_DARLA20
-#define ECHOCARD_NAME "Darla20"
-#define ECHOCARD_HAS_MONITOR
-
-/* Pipe indexes */
-#define PX_ANALOG_OUT 0 /* 8 */
-#define PX_DIGITAL_OUT 8 /* 0 */
-#define PX_ANALOG_IN 8 /* 2 */
-#define PX_DIGITAL_IN 10 /* 0 */
-#define PX_NUM 10
-
-/* Bus indexes */
-#define BX_ANALOG_OUT 0 /* 8 */
-#define BX_DIGITAL_OUT 8 /* 0 */
-#define BX_ANALOG_IN 8 /* 2 */
-#define BX_DIGITAL_IN 10 /* 0 */
-#define BX_NUM 10
-
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/asoundef.h>
-#include <sound/initval.h>
-#include <asm/io.h>
-#include <linux/atomic.h>
-#include "echoaudio.h"
-
-MODULE_FIRMWARE("ea/darla20_dsp.fw");
-
-#define FW_DARLA20_DSP 0
-
-static const struct firmware card_fw[] = {
- {0, "darla20_dsp.fw"}
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
- {0x1057, 0x1801, 0xECC0, 0x0010, 0, 0, 0}, /* DSP 56301 Darla20 rev.0 */
- {0,}
-};
-
-static struct snd_pcm_hardware pcm_hardware_skel = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START,
- .formats = SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_S32_BE,
- .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
- .rate_min = 44100,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 262144,
- .period_bytes_min = 32,
- .period_bytes_max = 131072,
- .periods_min = 2,
- .periods_max = 220,
- /* One page (4k) contains 512 instructions. I don't know if the hw
- supports lists longer than this. In this case periods_max=220 is a
- safe limit to make sure the list never exceeds 512 instructions. */
-};
-
-
-#include "darla20_dsp.c"
-#include "echoaudio_dsp.c"
-#include "echoaudio.c"
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/darla20_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/darla20_dsp.c
deleted file mode 100644
index 20c7cbc8..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/darla20_dsp.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/***************************************************************************
-
- Copyright Echo Digital Audio Corporation (c) 1998 - 2004
- All rights reserved
- www.echoaudio.com
-
- This file is part of Echo Digital Audio's generic driver library.
-
- Echo Digital Audio's generic driver library is free software;
- you can redistribute it and/or modify it under the terms of
- the GNU General Public License as published by the Free Software
- Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- *************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
-****************************************************************************/
-
-
-static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
-{
- int err;
-
- DE_INIT(("init_hw() - Darla20\n"));
- if (snd_BUG_ON((subdevice_id & 0xfff0) != DARLA20))
- return -ENODEV;
-
- if ((err = init_dsp_comm_page(chip))) {
- DE_INIT(("init_hw - could not initialize DSP comm page\n"));
- return err;
- }
-
- chip->device_id = device_id;
- chip->subdevice_id = subdevice_id;
- chip->bad_board = TRUE;
- chip->dsp_code_to_load = FW_DARLA20_DSP;
- chip->spdif_status = GD_SPDIF_STATUS_UNDEF;
- chip->clock_state = GD_CLOCK_UNDEF;
- /* Since this card has no ASIC, mark it as loaded so everything
- works OK */
- chip->asic_loaded = TRUE;
- chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
-
- if ((err = load_firmware(chip)) < 0)
- return err;
- chip->bad_board = FALSE;
-
- DE_INIT(("init_hw done\n"));
- return err;
-}
-
-
-
-static int set_mixer_defaults(struct echoaudio *chip)
-{
- return init_line_levels(chip);
-}
-
-
-
-/* The Darla20 has no external clock sources */
-static u32 detect_input_clocks(const struct echoaudio *chip)
-{
- return ECHO_CLOCK_BIT_INTERNAL;
-}
-
-
-
-/* The Darla20 has no ASIC. Just do nothing */
-static int load_asic(struct echoaudio *chip)
-{
- return 0;
-}
-
-
-
-static int set_sample_rate(struct echoaudio *chip, u32 rate)
-{
- u8 clock_state, spdif_status;
-
- if (wait_handshake(chip))
- return -EIO;
-
- switch (rate) {
- case 44100:
- clock_state = GD_CLOCK_44;
- spdif_status = GD_SPDIF_STATUS_44;
- break;
- case 48000:
- clock_state = GD_CLOCK_48;
- spdif_status = GD_SPDIF_STATUS_48;
- break;
- default:
- clock_state = GD_CLOCK_NOCHANGE;
- spdif_status = GD_SPDIF_STATUS_NOCHANGE;
- break;
- }
-
- if (chip->clock_state == clock_state)
- clock_state = GD_CLOCK_NOCHANGE;
- if (spdif_status == chip->spdif_status)
- spdif_status = GD_SPDIF_STATUS_NOCHANGE;
-
- chip->comm_page->sample_rate = cpu_to_le32(rate);
- chip->comm_page->gd_clock_state = clock_state;
- chip->comm_page->gd_spdif_status = spdif_status;
- chip->comm_page->gd_resampler_state = 3; /* magic number - should always be 3 */
-
- /* Save the new audio state if it changed */
- if (clock_state != GD_CLOCK_NOCHANGE)
- chip->clock_state = clock_state;
- if (spdif_status != GD_SPDIF_STATUS_NOCHANGE)
- chip->spdif_status = spdif_status;
- chip->sample_rate = rate;
-
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE);
-}
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/darla24.c b/ANDROID_3.4.5/sound/pci/echoaudio/darla24.c
deleted file mode 100644
index 413acf70..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/darla24.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * ALSA driver for Echoaudio soundcards.
- * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#define ECHOGALS_FAMILY
-#define ECHOCARD_DARLA24
-#define ECHOCARD_NAME "Darla24"
-#define ECHOCARD_HAS_MONITOR
-#define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL
-#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL
-#define ECHOCARD_HAS_EXTERNAL_CLOCK
-#define ECHOCARD_HAS_SUPER_INTERLEAVE
-
-/* Pipe indexes */
-#define PX_ANALOG_OUT 0 /* 8 */
-#define PX_DIGITAL_OUT 8 /* 0 */
-#define PX_ANALOG_IN 8 /* 2 */
-#define PX_DIGITAL_IN 10 /* 0 */
-#define PX_NUM 10
-
-/* Bus indexes */
-#define BX_ANALOG_OUT 0 /* 8 */
-#define BX_DIGITAL_OUT 8 /* 0 */
-#define BX_ANALOG_IN 8 /* 2 */
-#define BX_DIGITAL_IN 10 /* 0 */
-#define BX_NUM 10
-
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/asoundef.h>
-#include <sound/initval.h>
-#include <asm/io.h>
-#include <linux/atomic.h>
-#include "echoaudio.h"
-
-MODULE_FIRMWARE("ea/darla24_dsp.fw");
-
-#define FW_DARLA24_DSP 0
-
-static const struct firmware card_fw[] = {
- {0, "darla24_dsp.fw"}
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
- {0x1057, 0x1801, 0xECC0, 0x0040, 0, 0, 0}, /* DSP 56301 Darla24 rev.0 */
- {0x1057, 0x1801, 0xECC0, 0x0041, 0, 0, 0}, /* DSP 56301 Darla24 rev.1 */
- {0,}
-};
-
-static struct snd_pcm_hardware pcm_hardware_skel = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START,
- .formats = SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_S32_BE,
- .rates = SNDRV_PCM_RATE_8000_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000,
- .rate_min = 8000,
- .rate_max = 96000,
- .channels_min = 1,
- .channels_max = 8,
- .buffer_bytes_max = 262144,
- .period_bytes_min = 32,
- .period_bytes_max = 131072,
- .periods_min = 2,
- .periods_max = 220,
- /* One page (4k) contains 512 instructions. I don't know if the hw
- supports lists longer than this. In this case periods_max=220 is a
- safe limit to make sure the list never exceeds 512 instructions. */
-};
-
-
-#include "darla24_dsp.c"
-#include "echoaudio_dsp.c"
-#include "echoaudio.c"
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/darla24_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/darla24_dsp.c
deleted file mode 100644
index 6da6663e..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/darla24_dsp.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/***************************************************************************
-
- Copyright Echo Digital Audio Corporation (c) 1998 - 2004
- All rights reserved
- www.echoaudio.com
-
- This file is part of Echo Digital Audio's generic driver library.
-
- Echo Digital Audio's generic driver library is free software;
- you can redistribute it and/or modify it under the terms of
- the GNU General Public License as published by the Free Software
- Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- *************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
-****************************************************************************/
-
-
-static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
-{
- int err;
-
- DE_INIT(("init_hw() - Darla24\n"));
- if (snd_BUG_ON((subdevice_id & 0xfff0) != DARLA24))
- return -ENODEV;
-
- if ((err = init_dsp_comm_page(chip))) {
- DE_INIT(("init_hw - could not initialize DSP comm page\n"));
- return err;
- }
-
- chip->device_id = device_id;
- chip->subdevice_id = subdevice_id;
- chip->bad_board = TRUE;
- chip->dsp_code_to_load = FW_DARLA24_DSP;
- /* Since this card has no ASIC, mark it as loaded so everything
- works OK */
- chip->asic_loaded = TRUE;
- chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL |
- ECHO_CLOCK_BIT_ESYNC;
-
- if ((err = load_firmware(chip)) < 0)
- return err;
- chip->bad_board = FALSE;
-
- DE_INIT(("init_hw done\n"));
- return err;
-}
-
-
-
-static int set_mixer_defaults(struct echoaudio *chip)
-{
- return init_line_levels(chip);
-}
-
-
-
-static u32 detect_input_clocks(const struct echoaudio *chip)
-{
- u32 clocks_from_dsp, clock_bits;
-
- /* Map the DSP clock detect bits to the generic driver clock
- detect bits */
- clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
-
- clock_bits = ECHO_CLOCK_BIT_INTERNAL;
-
- if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_ESYNC)
- clock_bits |= ECHO_CLOCK_BIT_ESYNC;
-
- return clock_bits;
-}
-
-
-
-/* The Darla24 has no ASIC. Just do nothing */
-static int load_asic(struct echoaudio *chip)
-{
- return 0;
-}
-
-
-
-static int set_sample_rate(struct echoaudio *chip, u32 rate)
-{
- u8 clock;
-
- switch (rate) {
- case 96000:
- clock = GD24_96000;
- break;
- case 88200:
- clock = GD24_88200;
- break;
- case 48000:
- clock = GD24_48000;
- break;
- case 44100:
- clock = GD24_44100;
- break;
- case 32000:
- clock = GD24_32000;
- break;
- case 22050:
- clock = GD24_22050;
- break;
- case 16000:
- clock = GD24_16000;
- break;
- case 11025:
- clock = GD24_11025;
- break;
- case 8000:
- clock = GD24_8000;
- break;
- default:
- DE_ACT(("set_sample_rate: Error, invalid sample rate %d\n",
- rate));
- return -EINVAL;
- }
-
- if (wait_handshake(chip))
- return -EIO;
-
- DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock));
- chip->sample_rate = rate;
-
- /* Override the sample rate if this card is set to Echo sync. */
- if (chip->input_clock == ECHO_CLOCK_ESYNC)
- clock = GD24_EXT_SYNC;
-
- chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP ? */
- chip->comm_page->gd_clock_state = clock;
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE);
-}
-
-
-
-static int set_input_clock(struct echoaudio *chip, u16 clock)
-{
- if (snd_BUG_ON(clock != ECHO_CLOCK_INTERNAL &&
- clock != ECHO_CLOCK_ESYNC))
- return -EINVAL;
- chip->input_clock = clock;
- return set_sample_rate(chip, chip->sample_rate);
-}
-
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/echo3g.c b/ANDROID_3.4.5/sound/pci/echoaudio/echo3g.c
deleted file mode 100644
index 1ec4edca..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/echo3g.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * ALSA driver for Echoaudio soundcards.
- * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#define ECHO3G_FAMILY
-#define ECHOCARD_ECHO3G
-#define ECHOCARD_NAME "Echo3G"
-#define ECHOCARD_HAS_MONITOR
-#define ECHOCARD_HAS_ASIC
-#define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL
-#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL
-#define ECHOCARD_HAS_SUPER_INTERLEAVE
-#define ECHOCARD_HAS_DIGITAL_IO
-#define ECHOCARD_HAS_DIGITAL_MODE_SWITCH
-#define ECHOCARD_HAS_ADAT 6
-#define ECHOCARD_HAS_EXTERNAL_CLOCK
-#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
-#define ECHOCARD_HAS_MIDI
-#define ECHOCARD_HAS_PHANTOM_POWER
-
-/* Pipe indexes */
-#define PX_ANALOG_OUT 0
-#define PX_DIGITAL_OUT chip->px_digital_out
-#define PX_ANALOG_IN chip->px_analog_in
-#define PX_DIGITAL_IN chip->px_digital_in
-#define PX_NUM chip->px_num
-
-/* Bus indexes */
-#define BX_ANALOG_OUT 0
-#define BX_DIGITAL_OUT chip->bx_digital_out
-#define BX_ANALOG_IN chip->bx_analog_in
-#define BX_DIGITAL_IN chip->bx_digital_in
-#define BX_NUM chip->bx_num
-
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/asoundef.h>
-#include <sound/initval.h>
-#include <sound/rawmidi.h>
-#include <asm/io.h>
-#include <linux/atomic.h>
-#include "echoaudio.h"
-
-MODULE_FIRMWARE("ea/loader_dsp.fw");
-MODULE_FIRMWARE("ea/echo3g_dsp.fw");
-MODULE_FIRMWARE("ea/3g_asic.fw");
-
-#define FW_361_LOADER 0
-#define FW_ECHO3G_DSP 1
-#define FW_3G_ASIC 2
-
-static const struct firmware card_fw[] = {
- {0, "loader_dsp.fw"},
- {0, "echo3g_dsp.fw"},
- {0, "3g_asic.fw"}
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
- {0x1057, 0x3410, 0xECC0, 0x0100, 0, 0, 0}, /* Echo 3G */
- {0,}
-};
-
-static struct snd_pcm_hardware pcm_hardware_skel = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START,
- .formats = SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_S32_BE,
- .rates = SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000 |
- SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 32000,
- .rate_max = 100000,
- .channels_min = 1,
- .channels_max = 8,
- .buffer_bytes_max = 262144,
- .period_bytes_min = 32,
- .period_bytes_max = 131072,
- .periods_min = 2,
- .periods_max = 220,
-};
-
-#include "echo3g_dsp.c"
-#include "echoaudio_dsp.c"
-#include "echoaudio_3g.c"
-#include "echoaudio.c"
-#include "midi.c"
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/echo3g_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/echo3g_dsp.c
deleted file mode 100644
index 3cdc2ee2..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/echo3g_dsp.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/****************************************************************************
-
- Copyright Echo Digital Audio Corporation (c) 1998 - 2004
- All rights reserved
- www.echoaudio.com
-
- This file is part of Echo Digital Audio's generic driver library.
-
- Echo Digital Audio's generic driver library is free software;
- you can redistribute it and/or modify it under the terms of
- the GNU General Public License as published by the Free Software
- Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- *************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
-****************************************************************************/
-
-static int load_asic(struct echoaudio *chip);
-static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode);
-static int set_digital_mode(struct echoaudio *chip, u8 mode);
-static int check_asic_status(struct echoaudio *chip);
-static int set_sample_rate(struct echoaudio *chip, u32 rate);
-static int set_input_clock(struct echoaudio *chip, u16 clock);
-static int set_professional_spdif(struct echoaudio *chip, char prof);
-static int set_phantom_power(struct echoaudio *chip, char on);
-static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq,
- char force);
-
-#include <linux/interrupt.h>
-
-static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
-{
- int err;
-
- local_irq_enable();
- DE_INIT(("init_hw() - Echo3G\n"));
- if (snd_BUG_ON((subdevice_id & 0xfff0) != ECHO3G))
- return -ENODEV;
-
- if ((err = init_dsp_comm_page(chip))) {
- DE_INIT(("init_hw - could not initialize DSP comm page\n"));
- return err;
- }
-
- chip->comm_page->e3g_frq_register =
- cpu_to_le32((E3G_MAGIC_NUMBER / 48000) - 2);
- chip->device_id = device_id;
- chip->subdevice_id = subdevice_id;
- chip->bad_board = TRUE;
- chip->has_midi = TRUE;
- chip->dsp_code_to_load = FW_ECHO3G_DSP;
-
- /* Load the DSP code and the ASIC on the PCI card and get
- what type of external box is attached */
- err = load_firmware(chip);
-
- if (err < 0) {
- return err;
- } else if (err == E3G_GINA3G_BOX_TYPE) {
- chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL |
- ECHO_CLOCK_BIT_SPDIF |
- ECHO_CLOCK_BIT_ADAT;
- chip->card_name = "Gina3G";
- chip->px_digital_out = chip->bx_digital_out = 6;
- chip->px_analog_in = chip->bx_analog_in = 14;
- chip->px_digital_in = chip->bx_digital_in = 16;
- chip->px_num = chip->bx_num = 24;
- chip->has_phantom_power = TRUE;
- chip->hasnt_input_nominal_level = TRUE;
- } else if (err == E3G_LAYLA3G_BOX_TYPE) {
- chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL |
- ECHO_CLOCK_BIT_SPDIF |
- ECHO_CLOCK_BIT_ADAT |
- ECHO_CLOCK_BIT_WORD;
- chip->card_name = "Layla3G";
- chip->px_digital_out = chip->bx_digital_out = 8;
- chip->px_analog_in = chip->bx_analog_in = 16;
- chip->px_digital_in = chip->bx_digital_in = 24;
- chip->px_num = chip->bx_num = 32;
- } else {
- return -ENODEV;
- }
-
- chip->digital_modes = ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
- ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
- ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
-
- DE_INIT(("init_hw done\n"));
- return err;
-}
-
-
-
-static int set_mixer_defaults(struct echoaudio *chip)
-{
- chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
- chip->professional_spdif = FALSE;
- chip->non_audio_spdif = FALSE;
- chip->bad_board = FALSE;
- chip->phantom_power = FALSE;
- return init_line_levels(chip);
-}
-
-
-
-static int set_phantom_power(struct echoaudio *chip, char on)
-{
- u32 control_reg = le32_to_cpu(chip->comm_page->control_register);
-
- if (on)
- control_reg |= E3G_PHANTOM_POWER;
- else
- control_reg &= ~E3G_PHANTOM_POWER;
-
- chip->phantom_power = on;
- return write_control_reg(chip, control_reg,
- le32_to_cpu(chip->comm_page->e3g_frq_register),
- 0);
-}
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio.c b/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio.c
deleted file mode 100644
index 595c11f9..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio.c
+++ /dev/null
@@ -1,2360 +0,0 @@
-/*
- * ALSA driver for Echoaudio soundcards.
- * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <linux/module.h>
-
-MODULE_AUTHOR("Giuliano Pochini <pochini@shiny.it>");
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Echoaudio " ECHOCARD_NAME " soundcards driver");
-MODULE_SUPPORTED_DEVICE("{{Echoaudio," ECHOCARD_NAME "}}");
-MODULE_DEVICE_TABLE(pci, snd_echo_ids);
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for " ECHOCARD_NAME " soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for " ECHOCARD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable " ECHOCARD_NAME " soundcard.");
-
-static unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999};
-static const DECLARE_TLV_DB_SCALE(db_scale_output_gain, -12800, 100, 1);
-
-
-
-static int get_firmware(const struct firmware **fw_entry,
- struct echoaudio *chip, const short fw_index)
-{
- int err;
- char name[30];
-
-#ifdef CONFIG_PM
- if (chip->fw_cache[fw_index]) {
- DE_ACT(("firmware requested: %s is cached\n", card_fw[fw_index].data));
- *fw_entry = chip->fw_cache[fw_index];
- return 0;
- }
-#endif
-
- DE_ACT(("firmware requested: %s\n", card_fw[fw_index].data));
- snprintf(name, sizeof(name), "ea/%s", card_fw[fw_index].data);
- err = request_firmware(fw_entry, name, pci_device(chip));
- if (err < 0)
- snd_printk(KERN_ERR "get_firmware(): Firmware not available (%d)\n", err);
-#ifdef CONFIG_PM
- else
- chip->fw_cache[fw_index] = *fw_entry;
-#endif
- return err;
-}
-
-
-
-static void free_firmware(const struct firmware *fw_entry)
-{
-#ifdef CONFIG_PM
- DE_ACT(("firmware not released (kept in cache)\n"));
-#else
- release_firmware(fw_entry);
- DE_ACT(("firmware released\n"));
-#endif
-}
-
-
-
-static void free_firmware_cache(struct echoaudio *chip)
-{
-#ifdef CONFIG_PM
- int i;
-
- for (i = 0; i < 8 ; i++)
- if (chip->fw_cache[i]) {
- release_firmware(chip->fw_cache[i]);
- DE_ACT(("release_firmware(%d)\n", i));
- }
-
- DE_ACT(("firmware_cache released\n"));
-#endif
-}
-
-
-
-/******************************************************************************
- PCM interface
-******************************************************************************/
-
-static void audiopipe_free(struct snd_pcm_runtime *runtime)
-{
- struct audiopipe *pipe = runtime->private_data;
-
- if (pipe->sgpage.area)
- snd_dma_free_pages(&pipe->sgpage);
- kfree(pipe);
-}
-
-
-
-static int hw_rule_capture_format_by_channels(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_interval *c = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
- struct snd_mask fmt;
-
- snd_mask_any(&fmt);
-
-#ifndef ECHOCARD_HAS_STEREO_BIG_ENDIAN32
- /* >=2 channels cannot be S32_BE */
- if (c->min == 2) {
- fmt.bits[0] &= ~SNDRV_PCM_FMTBIT_S32_BE;
- return snd_mask_refine(f, &fmt);
- }
-#endif
- /* > 2 channels cannot be U8 and S32_BE */
- if (c->min > 2) {
- fmt.bits[0] &= ~(SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_BE);
- return snd_mask_refine(f, &fmt);
- }
- /* Mono is ok with any format */
- return 0;
-}
-
-
-
-static int hw_rule_capture_channels_by_format(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_interval *c = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
- struct snd_interval ch;
-
- snd_interval_any(&ch);
-
- /* S32_BE is mono (and stereo) only */
- if (f->bits[0] == SNDRV_PCM_FMTBIT_S32_BE) {
- ch.min = 1;
-#ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32
- ch.max = 2;
-#else
- ch.max = 1;
-#endif
- ch.integer = 1;
- return snd_interval_refine(c, &ch);
- }
- /* U8 can be only mono or stereo */
- if (f->bits[0] == SNDRV_PCM_FMTBIT_U8) {
- ch.min = 1;
- ch.max = 2;
- ch.integer = 1;
- return snd_interval_refine(c, &ch);
- }
- /* S16_LE, S24_3LE and S32_LE support any number of channels. */
- return 0;
-}
-
-
-
-static int hw_rule_playback_format_by_channels(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_interval *c = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
- struct snd_mask fmt;
- u64 fmask;
- snd_mask_any(&fmt);
-
- fmask = fmt.bits[0] + ((u64)fmt.bits[1] << 32);
-
- /* >2 channels must be S16_LE, S24_3LE or S32_LE */
- if (c->min > 2) {
- fmask &= SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S32_LE;
- /* 1 channel must be S32_BE or S32_LE */
- } else if (c->max == 1)
- fmask &= SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE;
-#ifndef ECHOCARD_HAS_STEREO_BIG_ENDIAN32
- /* 2 channels cannot be S32_BE */
- else if (c->min == 2 && c->max == 2)
- fmask &= ~SNDRV_PCM_FMTBIT_S32_BE;
-#endif
- else
- return 0;
-
- fmt.bits[0] &= (u32)fmask;
- fmt.bits[1] &= (u32)(fmask >> 32);
- return snd_mask_refine(f, &fmt);
-}
-
-
-
-static int hw_rule_playback_channels_by_format(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_interval *c = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
- struct snd_interval ch;
- u64 fmask;
-
- snd_interval_any(&ch);
- ch.integer = 1;
- fmask = f->bits[0] + ((u64)f->bits[1] << 32);
-
- /* S32_BE is mono (and stereo) only */
- if (fmask == SNDRV_PCM_FMTBIT_S32_BE) {
- ch.min = 1;
-#ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32
- ch.max = 2;
-#else
- ch.max = 1;
-#endif
- /* U8 is stereo only */
- } else if (fmask == SNDRV_PCM_FMTBIT_U8)
- ch.min = ch.max = 2;
- /* S16_LE and S24_3LE must be at least stereo */
- else if (!(fmask & ~(SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_3LE)))
- ch.min = 2;
- else
- return 0;
-
- return snd_interval_refine(c, &ch);
-}
-
-
-
-/* Since the sample rate is a global setting, do allow the user to change the
-sample rate only if there is only one pcm device open. */
-static int hw_rule_sample_rate(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_interval *rate = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_RATE);
- struct echoaudio *chip = rule->private;
- struct snd_interval fixed;
-
- if (!chip->can_set_rate) {
- snd_interval_any(&fixed);
- fixed.min = fixed.max = chip->sample_rate;
- return snd_interval_refine(rate, &fixed);
- }
- return 0;
-}
-
-
-static int pcm_open(struct snd_pcm_substream *substream,
- signed char max_channels)
-{
- struct echoaudio *chip;
- struct snd_pcm_runtime *runtime;
- struct audiopipe *pipe;
- int err, i;
-
- if (max_channels <= 0)
- return -EAGAIN;
-
- chip = snd_pcm_substream_chip(substream);
- runtime = substream->runtime;
-
- pipe = kzalloc(sizeof(struct audiopipe), GFP_KERNEL);
- if (!pipe)
- return -ENOMEM;
- pipe->index = -1; /* Not configured yet */
-
- /* Set up hw capabilities and contraints */
- memcpy(&pipe->hw, &pcm_hardware_skel, sizeof(struct snd_pcm_hardware));
- DE_HWP(("max_channels=%d\n", max_channels));
- pipe->constr.list = channels_list;
- pipe->constr.mask = 0;
- for (i = 0; channels_list[i] <= max_channels; i++);
- pipe->constr.count = i;
- if (pipe->hw.channels_max > max_channels)
- pipe->hw.channels_max = max_channels;
- if (chip->digital_mode == DIGITAL_MODE_ADAT) {
- pipe->hw.rate_max = 48000;
- pipe->hw.rates &= SNDRV_PCM_RATE_8000_48000;
- }
-
- runtime->hw = pipe->hw;
- runtime->private_data = pipe;
- runtime->private_free = audiopipe_free;
- snd_pcm_set_sync(substream);
-
- /* Only mono and any even number of channels are allowed */
- if ((err = snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- &pipe->constr)) < 0)
- return err;
-
- /* All periods should have the same size */
- if ((err = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
- return err;
-
- /* The hw accesses memory in chunks 32 frames long and they should be
- 32-bytes-aligned. It's not a requirement, but it seems that IRQs are
- generated with a resolution of 32 frames. Thus we need the following */
- if ((err = snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- 32)) < 0)
- return err;
- if ((err = snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- 32)) < 0)
- return err;
-
- if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- hw_rule_sample_rate, chip,
- SNDRV_PCM_HW_PARAM_RATE, -1)) < 0)
- return err;
-
- /* Finally allocate a page for the scatter-gather list */
- if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- PAGE_SIZE, &pipe->sgpage)) < 0) {
- DE_HWP(("s-g list allocation failed\n"));
- return err;
- }
-
- return 0;
-}
-
-
-
-static int pcm_analog_in_open(struct snd_pcm_substream *substream)
-{
- struct echoaudio *chip = snd_pcm_substream_chip(substream);
- int err;
-
- DE_ACT(("pcm_analog_in_open\n"));
- if ((err = pcm_open(substream, num_analog_busses_in(chip) -
- substream->number)) < 0)
- return err;
- if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- hw_rule_capture_channels_by_format, NULL,
- SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0)
- return err;
- if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_FORMAT,
- hw_rule_capture_format_by_channels, NULL,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0)
- return err;
- atomic_inc(&chip->opencount);
- if (atomic_read(&chip->opencount) > 1 && chip->rate_set)
- chip->can_set_rate=0;
- DE_HWP(("pcm_analog_in_open cs=%d oc=%d r=%d\n",
- chip->can_set_rate, atomic_read(&chip->opencount),
- chip->sample_rate));
- return 0;
-}
-
-
-
-static int pcm_analog_out_open(struct snd_pcm_substream *substream)
-{
- struct echoaudio *chip = snd_pcm_substream_chip(substream);
- int max_channels, err;
-
-#ifdef ECHOCARD_HAS_VMIXER
- max_channels = num_pipes_out(chip);
-#else
- max_channels = num_analog_busses_out(chip);
-#endif
- DE_ACT(("pcm_analog_out_open\n"));
- if ((err = pcm_open(substream, max_channels - substream->number)) < 0)
- return err;
- if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- hw_rule_playback_channels_by_format,
- NULL,
- SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0)
- return err;
- if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_FORMAT,
- hw_rule_playback_format_by_channels,
- NULL,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0)
- return err;
- atomic_inc(&chip->opencount);
- if (atomic_read(&chip->opencount) > 1 && chip->rate_set)
- chip->can_set_rate=0;
- DE_HWP(("pcm_analog_out_open cs=%d oc=%d r=%d\n",
- chip->can_set_rate, atomic_read(&chip->opencount),
- chip->sample_rate));
- return 0;
-}
-
-
-
-#ifdef ECHOCARD_HAS_DIGITAL_IO
-
-static int pcm_digital_in_open(struct snd_pcm_substream *substream)
-{
- struct echoaudio *chip = snd_pcm_substream_chip(substream);
- int err, max_channels;
-
- DE_ACT(("pcm_digital_in_open\n"));
- max_channels = num_digital_busses_in(chip) - substream->number;
- mutex_lock(&chip->mode_mutex);
- if (chip->digital_mode == DIGITAL_MODE_ADAT)
- err = pcm_open(substream, max_channels);
- else /* If the card has ADAT, subtract the 6 channels
- * that S/PDIF doesn't have
- */
- err = pcm_open(substream, max_channels - ECHOCARD_HAS_ADAT);
-
- if (err < 0)
- goto din_exit;
-
- if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- hw_rule_capture_channels_by_format, NULL,
- SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0)
- goto din_exit;
- if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_FORMAT,
- hw_rule_capture_format_by_channels, NULL,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0)
- goto din_exit;
-
- atomic_inc(&chip->opencount);
- if (atomic_read(&chip->opencount) > 1 && chip->rate_set)
- chip->can_set_rate=0;
-
-din_exit:
- mutex_unlock(&chip->mode_mutex);
- return err;
-}
-
-
-
-#ifndef ECHOCARD_HAS_VMIXER /* See the note in snd_echo_new_pcm() */
-
-static int pcm_digital_out_open(struct snd_pcm_substream *substream)
-{
- struct echoaudio *chip = snd_pcm_substream_chip(substream);
- int err, max_channels;
-
- DE_ACT(("pcm_digital_out_open\n"));
- max_channels = num_digital_busses_out(chip) - substream->number;
- mutex_lock(&chip->mode_mutex);
- if (chip->digital_mode == DIGITAL_MODE_ADAT)
- err = pcm_open(substream, max_channels);
- else /* If the card has ADAT, subtract the 6 channels
- * that S/PDIF doesn't have
- */
- err = pcm_open(substream, max_channels - ECHOCARD_HAS_ADAT);
-
- if (err < 0)
- goto dout_exit;
-
- if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- hw_rule_playback_channels_by_format,
- NULL, SNDRV_PCM_HW_PARAM_FORMAT,
- -1)) < 0)
- goto dout_exit;
- if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_FORMAT,
- hw_rule_playback_format_by_channels,
- NULL, SNDRV_PCM_HW_PARAM_CHANNELS,
- -1)) < 0)
- goto dout_exit;
- atomic_inc(&chip->opencount);
- if (atomic_read(&chip->opencount) > 1 && chip->rate_set)
- chip->can_set_rate=0;
-dout_exit:
- mutex_unlock(&chip->mode_mutex);
- return err;
-}
-
-#endif /* !ECHOCARD_HAS_VMIXER */
-
-#endif /* ECHOCARD_HAS_DIGITAL_IO */
-
-
-
-static int pcm_close(struct snd_pcm_substream *substream)
-{
- struct echoaudio *chip = snd_pcm_substream_chip(substream);
- int oc;
-
- /* Nothing to do here. Audio is already off and pipe will be
- * freed by its callback
- */
- DE_ACT(("pcm_close\n"));
-
- atomic_dec(&chip->opencount);
- oc = atomic_read(&chip->opencount);
- DE_ACT(("pcm_close oc=%d cs=%d rs=%d\n", oc,
- chip->can_set_rate, chip->rate_set));
- if (oc < 2)
- chip->can_set_rate = 1;
- if (oc == 0)
- chip->rate_set = 0;
- DE_ACT(("pcm_close2 oc=%d cs=%d rs=%d\n", oc,
- chip->can_set_rate,chip->rate_set));
-
- return 0;
-}
-
-
-
-/* Channel allocation and scatter-gather list setup */
-static int init_engine(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params,
- int pipe_index, int interleave)
-{
- struct echoaudio *chip;
- int err, per, rest, page, edge, offs;
- struct audiopipe *pipe;
-
- chip = snd_pcm_substream_chip(substream);
- pipe = (struct audiopipe *) substream->runtime->private_data;
-
- /* Sets up che hardware. If it's already initialized, reset and
- * redo with the new parameters
- */
- spin_lock_irq(&chip->lock);
- if (pipe->index >= 0) {
- DE_HWP(("hwp_ie free(%d)\n", pipe->index));
- err = free_pipes(chip, pipe);
- snd_BUG_ON(err);
- chip->substream[pipe->index] = NULL;
- }
-
- err = allocate_pipes(chip, pipe, pipe_index, interleave);
- if (err < 0) {
- spin_unlock_irq(&chip->lock);
- DE_ACT((KERN_NOTICE "allocate_pipes(%d) err=%d\n",
- pipe_index, err));
- return err;
- }
- spin_unlock_irq(&chip->lock);
- DE_ACT((KERN_NOTICE "allocate_pipes()=%d\n", pipe_index));
-
- DE_HWP(("pcm_hw_params (bufsize=%dB periods=%d persize=%dB)\n",
- params_buffer_bytes(hw_params), params_periods(hw_params),
- params_period_bytes(hw_params)));
- err = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- if (err < 0) {
- snd_printk(KERN_ERR "malloc_pages err=%d\n", err);
- spin_lock_irq(&chip->lock);
- free_pipes(chip, pipe);
- spin_unlock_irq(&chip->lock);
- pipe->index = -1;
- return err;
- }
-
- sglist_init(chip, pipe);
- edge = PAGE_SIZE;
- for (offs = page = per = 0; offs < params_buffer_bytes(hw_params);
- per++) {
- rest = params_period_bytes(hw_params);
- if (offs + rest > params_buffer_bytes(hw_params))
- rest = params_buffer_bytes(hw_params) - offs;
- while (rest) {
- dma_addr_t addr;
- addr = snd_pcm_sgbuf_get_addr(substream, offs);
- if (rest <= edge - offs) {
- sglist_add_mapping(chip, pipe, addr, rest);
- sglist_add_irq(chip, pipe);
- offs += rest;
- rest = 0;
- } else {
- sglist_add_mapping(chip, pipe, addr,
- edge - offs);
- rest -= edge - offs;
- offs = edge;
- }
- if (offs == edge) {
- edge += PAGE_SIZE;
- page++;
- }
- }
- }
-
- /* Close the ring buffer */
- sglist_wrap(chip, pipe);
-
- /* This stuff is used by the irq handler, so it must be
- * initialized before chip->substream
- */
- chip->last_period[pipe_index] = 0;
- pipe->last_counter = 0;
- pipe->position = 0;
- smp_wmb();
- chip->substream[pipe_index] = substream;
- chip->rate_set = 1;
- spin_lock_irq(&chip->lock);
- set_sample_rate(chip, hw_params->rate_num / hw_params->rate_den);
- spin_unlock_irq(&chip->lock);
- DE_HWP(("pcm_hw_params ok\n"));
- return 0;
-}
-
-
-
-static int pcm_analog_in_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct echoaudio *chip = snd_pcm_substream_chip(substream);
-
- return init_engine(substream, hw_params, px_analog_in(chip) +
- substream->number, params_channels(hw_params));
-}
-
-
-
-static int pcm_analog_out_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return init_engine(substream, hw_params, substream->number,
- params_channels(hw_params));
-}
-
-
-
-#ifdef ECHOCARD_HAS_DIGITAL_IO
-
-static int pcm_digital_in_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct echoaudio *chip = snd_pcm_substream_chip(substream);
-
- return init_engine(substream, hw_params, px_digital_in(chip) +
- substream->number, params_channels(hw_params));
-}
-
-
-
-#ifndef ECHOCARD_HAS_VMIXER /* See the note in snd_echo_new_pcm() */
-static int pcm_digital_out_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct echoaudio *chip = snd_pcm_substream_chip(substream);
-
- return init_engine(substream, hw_params, px_digital_out(chip) +
- substream->number, params_channels(hw_params));
-}
-#endif /* !ECHOCARD_HAS_VMIXER */
-
-#endif /* ECHOCARD_HAS_DIGITAL_IO */
-
-
-
-static int pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct echoaudio *chip;
- struct audiopipe *pipe;
-
- chip = snd_pcm_substream_chip(substream);
- pipe = (struct audiopipe *) substream->runtime->private_data;
-
- spin_lock_irq(&chip->lock);
- if (pipe->index >= 0) {
- DE_HWP(("pcm_hw_free(%d)\n", pipe->index));
- free_pipes(chip, pipe);
- chip->substream[pipe->index] = NULL;
- pipe->index = -1;
- }
- spin_unlock_irq(&chip->lock);
-
- DE_HWP(("pcm_hw_freed\n"));
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-
-
-static int pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct echoaudio *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct audioformat format;
- int pipe_index = ((struct audiopipe *)runtime->private_data)->index;
-
- DE_HWP(("Prepare rate=%d format=%d channels=%d\n",
- runtime->rate, runtime->format, runtime->channels));
- format.interleave = runtime->channels;
- format.data_are_bigendian = 0;
- format.mono_to_stereo = 0;
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_U8:
- format.bits_per_sample = 8;
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- format.bits_per_sample = 16;
- break;
- case SNDRV_PCM_FORMAT_S24_3LE:
- format.bits_per_sample = 24;
- break;
- case SNDRV_PCM_FORMAT_S32_BE:
- format.data_are_bigendian = 1;
- case SNDRV_PCM_FORMAT_S32_LE:
- format.bits_per_sample = 32;
- break;
- default:
- DE_HWP(("Prepare error: unsupported format %d\n",
- runtime->format));
- return -EINVAL;
- }
-
- if (snd_BUG_ON(pipe_index >= px_num(chip)))
- return -EINVAL;
- if (snd_BUG_ON(!is_pipe_allocated(chip, pipe_index)))
- return -EINVAL;
- set_audio_format(chip, pipe_index, &format);
- return 0;
-}
-
-
-
-static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct echoaudio *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct audiopipe *pipe = runtime->private_data;
- int i, err;
- u32 channelmask = 0;
- struct snd_pcm_substream *s;
-
- snd_pcm_group_for_each_entry(s, substream) {
- for (i = 0; i < DSP_MAXPIPES; i++) {
- if (s == chip->substream[i]) {
- channelmask |= 1 << i;
- snd_pcm_trigger_done(s, substream);
- }
- }
- }
-
- spin_lock(&chip->lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_RESUME:
- DE_ACT(("pcm_trigger resume\n"));
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- DE_ACT(("pcm_trigger start\n"));
- for (i = 0; i < DSP_MAXPIPES; i++) {
- if (channelmask & (1 << i)) {
- pipe = chip->substream[i]->runtime->private_data;
- switch (pipe->state) {
- case PIPE_STATE_STOPPED:
- chip->last_period[i] = 0;
- pipe->last_counter = 0;
- pipe->position = 0;
- *pipe->dma_counter = 0;
- case PIPE_STATE_PAUSED:
- pipe->state = PIPE_STATE_STARTED;
- break;
- case PIPE_STATE_STARTED:
- break;
- }
- }
- }
- err = start_transport(chip, channelmask,
- chip->pipe_cyclic_mask);
- break;
- case SNDRV_PCM_TRIGGER_SUSPEND:
- DE_ACT(("pcm_trigger suspend\n"));
- case SNDRV_PCM_TRIGGER_STOP:
- DE_ACT(("pcm_trigger stop\n"));
- for (i = 0; i < DSP_MAXPIPES; i++) {
- if (channelmask & (1 << i)) {
- pipe = chip->substream[i]->runtime->private_data;
- pipe->state = PIPE_STATE_STOPPED;
- }
- }
- err = stop_transport(chip, channelmask);
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- DE_ACT(("pcm_trigger pause\n"));
- for (i = 0; i < DSP_MAXPIPES; i++) {
- if (channelmask & (1 << i)) {
- pipe = chip->substream[i]->runtime->private_data;
- pipe->state = PIPE_STATE_PAUSED;
- }
- }
- err = pause_transport(chip, channelmask);
- break;
- default:
- err = -EINVAL;
- }
- spin_unlock(&chip->lock);
- return err;
-}
-
-
-
-static snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct audiopipe *pipe = runtime->private_data;
- size_t cnt, bufsize, pos;
-
- cnt = le32_to_cpu(*pipe->dma_counter);
- pipe->position += cnt - pipe->last_counter;
- pipe->last_counter = cnt;
- bufsize = substream->runtime->buffer_size;
- pos = bytes_to_frames(substream->runtime, pipe->position);
-
- while (pos >= bufsize) {
- pipe->position -= frames_to_bytes(substream->runtime, bufsize);
- pos -= bufsize;
- }
- return pos;
-}
-
-
-
-/* pcm *_ops structures */
-static struct snd_pcm_ops analog_playback_ops = {
- .open = pcm_analog_out_open,
- .close = pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = pcm_analog_out_hw_params,
- .hw_free = pcm_hw_free,
- .prepare = pcm_prepare,
- .trigger = pcm_trigger,
- .pointer = pcm_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-static struct snd_pcm_ops analog_capture_ops = {
- .open = pcm_analog_in_open,
- .close = pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = pcm_analog_in_hw_params,
- .hw_free = pcm_hw_free,
- .prepare = pcm_prepare,
- .trigger = pcm_trigger,
- .pointer = pcm_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-#ifdef ECHOCARD_HAS_DIGITAL_IO
-#ifndef ECHOCARD_HAS_VMIXER
-static struct snd_pcm_ops digital_playback_ops = {
- .open = pcm_digital_out_open,
- .close = pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = pcm_digital_out_hw_params,
- .hw_free = pcm_hw_free,
- .prepare = pcm_prepare,
- .trigger = pcm_trigger,
- .pointer = pcm_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-#endif /* !ECHOCARD_HAS_VMIXER */
-static struct snd_pcm_ops digital_capture_ops = {
- .open = pcm_digital_in_open,
- .close = pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = pcm_digital_in_hw_params,
- .hw_free = pcm_hw_free,
- .prepare = pcm_prepare,
- .trigger = pcm_trigger,
- .pointer = pcm_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-#endif /* ECHOCARD_HAS_DIGITAL_IO */
-
-
-
-/* Preallocate memory only for the first substream because it's the most
- * used one
- */
-static int snd_echo_preallocate_pages(struct snd_pcm *pcm, struct device *dev)
-{
- struct snd_pcm_substream *ss;
- int stream, err;
-
- for (stream = 0; stream < 2; stream++)
- for (ss = pcm->streams[stream].substream; ss; ss = ss->next) {
- err = snd_pcm_lib_preallocate_pages(ss, SNDRV_DMA_TYPE_DEV_SG,
- dev,
- ss->number ? 0 : 128<<10,
- 256<<10);
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-
-
-/*<--snd_echo_probe() */
-static int __devinit snd_echo_new_pcm(struct echoaudio *chip)
-{
- struct snd_pcm *pcm;
- int err;
-
-#ifdef ECHOCARD_HAS_VMIXER
- /* This card has a Vmixer, that is there is no direct mapping from PCM
- streams to physical outputs. The user can mix the streams as he wishes
- via control interface and it's possible to send any stream to any
- output, thus it makes no sense to keep analog and digital outputs
- separated */
-
- /* PCM#0 Virtual outputs and analog inputs */
- if ((err = snd_pcm_new(chip->card, "PCM", 0, num_pipes_out(chip),
- num_analog_busses_in(chip), &pcm)) < 0)
- return err;
- pcm->private_data = chip;
- chip->analog_pcm = pcm;
- strcpy(pcm->name, chip->card->shortname);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &analog_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops);
- if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0)
- return err;
- DE_INIT(("Analog PCM ok\n"));
-
-#ifdef ECHOCARD_HAS_DIGITAL_IO
- /* PCM#1 Digital inputs, no outputs */
- if ((err = snd_pcm_new(chip->card, "Digital PCM", 1, 0,
- num_digital_busses_in(chip), &pcm)) < 0)
- return err;
- pcm->private_data = chip;
- chip->digital_pcm = pcm;
- strcpy(pcm->name, chip->card->shortname);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops);
- if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0)
- return err;
- DE_INIT(("Digital PCM ok\n"));
-#endif /* ECHOCARD_HAS_DIGITAL_IO */
-
-#else /* ECHOCARD_HAS_VMIXER */
-
- /* The card can manage substreams formed by analog and digital channels
- at the same time, but I prefer to keep analog and digital channels
- separated, because that mixed thing is confusing and useless. So we
- register two PCM devices: */
-
- /* PCM#0 Analog i/o */
- if ((err = snd_pcm_new(chip->card, "Analog PCM", 0,
- num_analog_busses_out(chip),
- num_analog_busses_in(chip), &pcm)) < 0)
- return err;
- pcm->private_data = chip;
- chip->analog_pcm = pcm;
- strcpy(pcm->name, chip->card->shortname);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &analog_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops);
- if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0)
- return err;
- DE_INIT(("Analog PCM ok\n"));
-
-#ifdef ECHOCARD_HAS_DIGITAL_IO
- /* PCM#1 Digital i/o */
- if ((err = snd_pcm_new(chip->card, "Digital PCM", 1,
- num_digital_busses_out(chip),
- num_digital_busses_in(chip), &pcm)) < 0)
- return err;
- pcm->private_data = chip;
- chip->digital_pcm = pcm;
- strcpy(pcm->name, chip->card->shortname);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &digital_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops);
- if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0)
- return err;
- DE_INIT(("Digital PCM ok\n"));
-#endif /* ECHOCARD_HAS_DIGITAL_IO */
-
-#endif /* ECHOCARD_HAS_VMIXER */
-
- return 0;
-}
-
-
-
-
-/******************************************************************************
- Control interface
-******************************************************************************/
-
-#if !defined(ECHOCARD_HAS_VMIXER) || defined(ECHOCARD_HAS_LINE_OUT_GAIN)
-
-/******************* PCM output volume *******************/
-static int snd_echo_output_gain_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct echoaudio *chip;
-
- chip = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = num_busses_out(chip);
- uinfo->value.integer.min = ECHOGAIN_MINOUT;
- uinfo->value.integer.max = ECHOGAIN_MAXOUT;
- return 0;
-}
-
-static int snd_echo_output_gain_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
- int c;
-
- chip = snd_kcontrol_chip(kcontrol);
- for (c = 0; c < num_busses_out(chip); c++)
- ucontrol->value.integer.value[c] = chip->output_gain[c];
- return 0;
-}
-
-static int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
- int c, changed, gain;
-
- changed = 0;
- chip = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&chip->lock);
- for (c = 0; c < num_busses_out(chip); c++) {
- gain = ucontrol->value.integer.value[c];
- /* Ignore out of range values */
- if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT)
- continue;
- if (chip->output_gain[c] != gain) {
- set_output_gain(chip, c, gain);
- changed = 1;
- }
- }
- if (changed)
- update_output_line_level(chip);
- spin_unlock_irq(&chip->lock);
- return changed;
-}
-
-#ifdef ECHOCARD_HAS_LINE_OUT_GAIN
-/* On the Mia this one controls the line-out volume */
-static struct snd_kcontrol_new snd_echo_line_output_gain __devinitdata = {
- .name = "Line Playback Volume",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = snd_echo_output_gain_info,
- .get = snd_echo_output_gain_get,
- .put = snd_echo_output_gain_put,
- .tlv = {.p = db_scale_output_gain},
-};
-#else
-static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = {
- .name = "PCM Playback Volume",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = snd_echo_output_gain_info,
- .get = snd_echo_output_gain_get,
- .put = snd_echo_output_gain_put,
- .tlv = {.p = db_scale_output_gain},
-};
-#endif
-
-#endif /* !ECHOCARD_HAS_VMIXER || ECHOCARD_HAS_LINE_OUT_GAIN */
-
-
-
-#ifdef ECHOCARD_HAS_INPUT_GAIN
-
-/******************* Analog input volume *******************/
-static int snd_echo_input_gain_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct echoaudio *chip;
-
- chip = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = num_analog_busses_in(chip);
- uinfo->value.integer.min = ECHOGAIN_MININP;
- uinfo->value.integer.max = ECHOGAIN_MAXINP;
- return 0;
-}
-
-static int snd_echo_input_gain_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
- int c;
-
- chip = snd_kcontrol_chip(kcontrol);
- for (c = 0; c < num_analog_busses_in(chip); c++)
- ucontrol->value.integer.value[c] = chip->input_gain[c];
- return 0;
-}
-
-static int snd_echo_input_gain_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
- int c, gain, changed;
-
- changed = 0;
- chip = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&chip->lock);
- for (c = 0; c < num_analog_busses_in(chip); c++) {
- gain = ucontrol->value.integer.value[c];
- /* Ignore out of range values */
- if (gain < ECHOGAIN_MININP || gain > ECHOGAIN_MAXINP)
- continue;
- if (chip->input_gain[c] != gain) {
- set_input_gain(chip, c, gain);
- changed = 1;
- }
- }
- if (changed)
- update_input_line_level(chip);
- spin_unlock_irq(&chip->lock);
- return changed;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_input_gain, -2500, 50, 0);
-
-static struct snd_kcontrol_new snd_echo_line_input_gain __devinitdata = {
- .name = "Line Capture Volume",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = snd_echo_input_gain_info,
- .get = snd_echo_input_gain_get,
- .put = snd_echo_input_gain_put,
- .tlv = {.p = db_scale_input_gain},
-};
-
-#endif /* ECHOCARD_HAS_INPUT_GAIN */
-
-
-
-#ifdef ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL
-
-/************ Analog output nominal level (+4dBu / -10dBV) ***************/
-static int snd_echo_output_nominal_info (struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct echoaudio *chip;
-
- chip = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = num_analog_busses_out(chip);
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int snd_echo_output_nominal_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
- int c;
-
- chip = snd_kcontrol_chip(kcontrol);
- for (c = 0; c < num_analog_busses_out(chip); c++)
- ucontrol->value.integer.value[c] = chip->nominal_level[c];
- return 0;
-}
-
-static int snd_echo_output_nominal_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
- int c, changed;
-
- changed = 0;
- chip = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&chip->lock);
- for (c = 0; c < num_analog_busses_out(chip); c++) {
- if (chip->nominal_level[c] != ucontrol->value.integer.value[c]) {
- set_nominal_level(chip, c,
- ucontrol->value.integer.value[c]);
- changed = 1;
- }
- }
- if (changed)
- update_output_line_level(chip);
- spin_unlock_irq(&chip->lock);
- return changed;
-}
-
-static struct snd_kcontrol_new snd_echo_output_nominal_level __devinitdata = {
- .name = "Line Playback Switch (-10dBV)",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = snd_echo_output_nominal_info,
- .get = snd_echo_output_nominal_get,
- .put = snd_echo_output_nominal_put,
-};
-
-#endif /* ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL */
-
-
-
-#ifdef ECHOCARD_HAS_INPUT_NOMINAL_LEVEL
-
-/*************** Analog input nominal level (+4dBu / -10dBV) ***************/
-static int snd_echo_input_nominal_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct echoaudio *chip;
-
- chip = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = num_analog_busses_in(chip);
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int snd_echo_input_nominal_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
- int c;
-
- chip = snd_kcontrol_chip(kcontrol);
- for (c = 0; c < num_analog_busses_in(chip); c++)
- ucontrol->value.integer.value[c] =
- chip->nominal_level[bx_analog_in(chip) + c];
- return 0;
-}
-
-static int snd_echo_input_nominal_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
- int c, changed;
-
- changed = 0;
- chip = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&chip->lock);
- for (c = 0; c < num_analog_busses_in(chip); c++) {
- if (chip->nominal_level[bx_analog_in(chip) + c] !=
- ucontrol->value.integer.value[c]) {
- set_nominal_level(chip, bx_analog_in(chip) + c,
- ucontrol->value.integer.value[c]);
- changed = 1;
- }
- }
- if (changed)
- update_output_line_level(chip); /* "Output" is not a mistake
- * here.
- */
- spin_unlock_irq(&chip->lock);
- return changed;
-}
-
-static struct snd_kcontrol_new snd_echo_intput_nominal_level __devinitdata = {
- .name = "Line Capture Switch (-10dBV)",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = snd_echo_input_nominal_info,
- .get = snd_echo_input_nominal_get,
- .put = snd_echo_input_nominal_put,
-};
-
-#endif /* ECHOCARD_HAS_INPUT_NOMINAL_LEVEL */
-
-
-
-#ifdef ECHOCARD_HAS_MONITOR
-
-/******************* Monitor mixer *******************/
-static int snd_echo_mixer_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct echoaudio *chip;
-
- chip = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = ECHOGAIN_MINOUT;
- uinfo->value.integer.max = ECHOGAIN_MAXOUT;
- uinfo->dimen.d[0] = num_busses_out(chip);
- uinfo->dimen.d[1] = num_busses_in(chip);
- return 0;
-}
-
-static int snd_echo_mixer_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
-
- chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] =
- chip->monitor_gain[ucontrol->id.index / num_busses_in(chip)]
- [ucontrol->id.index % num_busses_in(chip)];
- return 0;
-}
-
-static int snd_echo_mixer_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
- int changed, gain;
- short out, in;
-
- changed = 0;
- chip = snd_kcontrol_chip(kcontrol);
- out = ucontrol->id.index / num_busses_in(chip);
- in = ucontrol->id.index % num_busses_in(chip);
- gain = ucontrol->value.integer.value[0];
- if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT)
- return -EINVAL;
- if (chip->monitor_gain[out][in] != gain) {
- spin_lock_irq(&chip->lock);
- set_monitor_gain(chip, out, in, gain);
- update_output_line_level(chip);
- spin_unlock_irq(&chip->lock);
- changed = 1;
- }
- return changed;
-}
-
-static struct snd_kcontrol_new snd_echo_monitor_mixer __devinitdata = {
- .name = "Monitor Mixer Volume",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = snd_echo_mixer_info,
- .get = snd_echo_mixer_get,
- .put = snd_echo_mixer_put,
- .tlv = {.p = db_scale_output_gain},
-};
-
-#endif /* ECHOCARD_HAS_MONITOR */
-
-
-
-#ifdef ECHOCARD_HAS_VMIXER
-
-/******************* Vmixer *******************/
-static int snd_echo_vmixer_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct echoaudio *chip;
-
- chip = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = ECHOGAIN_MINOUT;
- uinfo->value.integer.max = ECHOGAIN_MAXOUT;
- uinfo->dimen.d[0] = num_busses_out(chip);
- uinfo->dimen.d[1] = num_pipes_out(chip);
- return 0;
-}
-
-static int snd_echo_vmixer_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
-
- chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] =
- chip->vmixer_gain[ucontrol->id.index / num_pipes_out(chip)]
- [ucontrol->id.index % num_pipes_out(chip)];
- return 0;
-}
-
-static int snd_echo_vmixer_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
- int gain, changed;
- short vch, out;
-
- changed = 0;
- chip = snd_kcontrol_chip(kcontrol);
- out = ucontrol->id.index / num_pipes_out(chip);
- vch = ucontrol->id.index % num_pipes_out(chip);
- gain = ucontrol->value.integer.value[0];
- if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT)
- return -EINVAL;
- if (chip->vmixer_gain[out][vch] != ucontrol->value.integer.value[0]) {
- spin_lock_irq(&chip->lock);
- set_vmixer_gain(chip, out, vch, ucontrol->value.integer.value[0]);
- update_vmixer_level(chip);
- spin_unlock_irq(&chip->lock);
- changed = 1;
- }
- return changed;
-}
-
-static struct snd_kcontrol_new snd_echo_vmixer __devinitdata = {
- .name = "VMixer Volume",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = snd_echo_vmixer_info,
- .get = snd_echo_vmixer_get,
- .put = snd_echo_vmixer_put,
- .tlv = {.p = db_scale_output_gain},
-};
-
-#endif /* ECHOCARD_HAS_VMIXER */
-
-
-
-#ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH
-
-/******************* Digital mode switch *******************/
-static int snd_echo_digital_mode_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *names[4] = {
- "S/PDIF Coaxial", "S/PDIF Optical", "ADAT Optical",
- "S/PDIF Cdrom"
- };
- struct echoaudio *chip;
-
- chip = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->value.enumerated.items = chip->num_digital_modes;
- uinfo->count = 1;
- if (uinfo->value.enumerated.item >= chip->num_digital_modes)
- uinfo->value.enumerated.item = chip->num_digital_modes - 1;
- strcpy(uinfo->value.enumerated.name, names[
- chip->digital_mode_list[uinfo->value.enumerated.item]]);
- return 0;
-}
-
-static int snd_echo_digital_mode_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
- int i, mode;
-
- chip = snd_kcontrol_chip(kcontrol);
- mode = chip->digital_mode;
- for (i = chip->num_digital_modes - 1; i >= 0; i--)
- if (mode == chip->digital_mode_list[i]) {
- ucontrol->value.enumerated.item[0] = i;
- break;
- }
- return 0;
-}
-
-static int snd_echo_digital_mode_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
- int changed;
- unsigned short emode, dmode;
-
- changed = 0;
- chip = snd_kcontrol_chip(kcontrol);
-
- emode = ucontrol->value.enumerated.item[0];
- if (emode >= chip->num_digital_modes)
- return -EINVAL;
- dmode = chip->digital_mode_list[emode];
-
- if (dmode != chip->digital_mode) {
- /* mode_mutex is required to make this operation atomic wrt
- pcm_digital_*_open() and set_input_clock() functions. */
- mutex_lock(&chip->mode_mutex);
-
- /* Do not allow the user to change the digital mode when a pcm
- device is open because it also changes the number of channels
- and the allowed sample rates */
- if (atomic_read(&chip->opencount)) {
- changed = -EAGAIN;
- } else {
- changed = set_digital_mode(chip, dmode);
- /* If we had to change the clock source, report it */
- if (changed > 0 && chip->clock_src_ctl) {
- snd_ctl_notify(chip->card,
- SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->clock_src_ctl->id);
- DE_ACT(("SDM() =%d\n", changed));
- }
- if (changed >= 0)
- changed = 1; /* No errors */
- }
- mutex_unlock(&chip->mode_mutex);
- }
- return changed;
-}
-
-static struct snd_kcontrol_new snd_echo_digital_mode_switch __devinitdata = {
- .name = "Digital mode Switch",
- .iface = SNDRV_CTL_ELEM_IFACE_CARD,
- .info = snd_echo_digital_mode_info,
- .get = snd_echo_digital_mode_get,
- .put = snd_echo_digital_mode_put,
-};
-
-#endif /* ECHOCARD_HAS_DIGITAL_MODE_SWITCH */
-
-
-
-#ifdef ECHOCARD_HAS_DIGITAL_IO
-
-/******************* S/PDIF mode switch *******************/
-static int snd_echo_spdif_mode_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *names[2] = {"Consumer", "Professional"};
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->value.enumerated.items = 2;
- uinfo->count = 1;
- if (uinfo->value.enumerated.item)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name,
- names[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_echo_spdif_mode_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
-
- chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = !!chip->professional_spdif;
- return 0;
-}
-
-static int snd_echo_spdif_mode_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
- int mode;
-
- chip = snd_kcontrol_chip(kcontrol);
- mode = !!ucontrol->value.enumerated.item[0];
- if (mode != chip->professional_spdif) {
- spin_lock_irq(&chip->lock);
- set_professional_spdif(chip, mode);
- spin_unlock_irq(&chip->lock);
- return 1;
- }
- return 0;
-}
-
-static struct snd_kcontrol_new snd_echo_spdif_mode_switch __devinitdata = {
- .name = "S/PDIF mode Switch",
- .iface = SNDRV_CTL_ELEM_IFACE_CARD,
- .info = snd_echo_spdif_mode_info,
- .get = snd_echo_spdif_mode_get,
- .put = snd_echo_spdif_mode_put,
-};
-
-#endif /* ECHOCARD_HAS_DIGITAL_IO */
-
-
-
-#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK
-
-/******************* Select input clock source *******************/
-static int snd_echo_clock_source_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *names[8] = {
- "Internal", "Word", "Super", "S/PDIF", "ADAT", "ESync",
- "ESync96", "MTC"
- };
- struct echoaudio *chip;
-
- chip = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->value.enumerated.items = chip->num_clock_sources;
- uinfo->count = 1;
- if (uinfo->value.enumerated.item >= chip->num_clock_sources)
- uinfo->value.enumerated.item = chip->num_clock_sources - 1;
- strcpy(uinfo->value.enumerated.name, names[
- chip->clock_source_list[uinfo->value.enumerated.item]]);
- return 0;
-}
-
-static int snd_echo_clock_source_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
- int i, clock;
-
- chip = snd_kcontrol_chip(kcontrol);
- clock = chip->input_clock;
-
- for (i = 0; i < chip->num_clock_sources; i++)
- if (clock == chip->clock_source_list[i])
- ucontrol->value.enumerated.item[0] = i;
-
- return 0;
-}
-
-static int snd_echo_clock_source_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
- int changed;
- unsigned int eclock, dclock;
-
- changed = 0;
- chip = snd_kcontrol_chip(kcontrol);
- eclock = ucontrol->value.enumerated.item[0];
- if (eclock >= chip->input_clock_types)
- return -EINVAL;
- dclock = chip->clock_source_list[eclock];
- if (chip->input_clock != dclock) {
- mutex_lock(&chip->mode_mutex);
- spin_lock_irq(&chip->lock);
- if ((changed = set_input_clock(chip, dclock)) == 0)
- changed = 1; /* no errors */
- spin_unlock_irq(&chip->lock);
- mutex_unlock(&chip->mode_mutex);
- }
-
- if (changed < 0)
- DE_ACT(("seticlk val%d err 0x%x\n", dclock, changed));
-
- return changed;
-}
-
-static struct snd_kcontrol_new snd_echo_clock_source_switch __devinitdata = {
- .name = "Sample Clock Source",
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .info = snd_echo_clock_source_info,
- .get = snd_echo_clock_source_get,
- .put = snd_echo_clock_source_put,
-};
-
-#endif /* ECHOCARD_HAS_EXTERNAL_CLOCK */
-
-
-
-#ifdef ECHOCARD_HAS_PHANTOM_POWER
-
-/******************* Phantom power switch *******************/
-#define snd_echo_phantom_power_info snd_ctl_boolean_mono_info
-
-static int snd_echo_phantom_power_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = chip->phantom_power;
- return 0;
-}
-
-static int snd_echo_phantom_power_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip = snd_kcontrol_chip(kcontrol);
- int power, changed = 0;
-
- power = !!ucontrol->value.integer.value[0];
- if (chip->phantom_power != power) {
- spin_lock_irq(&chip->lock);
- changed = set_phantom_power(chip, power);
- spin_unlock_irq(&chip->lock);
- if (changed == 0)
- changed = 1; /* no errors */
- }
- return changed;
-}
-
-static struct snd_kcontrol_new snd_echo_phantom_power_switch __devinitdata = {
- .name = "Phantom power Switch",
- .iface = SNDRV_CTL_ELEM_IFACE_CARD,
- .info = snd_echo_phantom_power_info,
- .get = snd_echo_phantom_power_get,
- .put = snd_echo_phantom_power_put,
-};
-
-#endif /* ECHOCARD_HAS_PHANTOM_POWER */
-
-
-
-#ifdef ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE
-
-/******************* Digital input automute switch *******************/
-#define snd_echo_automute_info snd_ctl_boolean_mono_info
-
-static int snd_echo_automute_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = chip->digital_in_automute;
- return 0;
-}
-
-static int snd_echo_automute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip = snd_kcontrol_chip(kcontrol);
- int automute, changed = 0;
-
- automute = !!ucontrol->value.integer.value[0];
- if (chip->digital_in_automute != automute) {
- spin_lock_irq(&chip->lock);
- changed = set_input_auto_mute(chip, automute);
- spin_unlock_irq(&chip->lock);
- if (changed == 0)
- changed = 1; /* no errors */
- }
- return changed;
-}
-
-static struct snd_kcontrol_new snd_echo_automute_switch __devinitdata = {
- .name = "Digital Capture Switch (automute)",
- .iface = SNDRV_CTL_ELEM_IFACE_CARD,
- .info = snd_echo_automute_info,
- .get = snd_echo_automute_get,
- .put = snd_echo_automute_put,
-};
-
-#endif /* ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE */
-
-
-
-/******************* VU-meters switch *******************/
-#define snd_echo_vumeters_switch_info snd_ctl_boolean_mono_info
-
-static int snd_echo_vumeters_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
-
- chip = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&chip->lock);
- set_meters_on(chip, ucontrol->value.integer.value[0]);
- spin_unlock_irq(&chip->lock);
- return 1;
-}
-
-static struct snd_kcontrol_new snd_echo_vumeters_switch __devinitdata = {
- .name = "VU-meters Switch",
- .iface = SNDRV_CTL_ELEM_IFACE_CARD,
- .access = SNDRV_CTL_ELEM_ACCESS_WRITE,
- .info = snd_echo_vumeters_switch_info,
- .put = snd_echo_vumeters_switch_put,
-};
-
-
-
-/***** Read VU-meters (input, output, analog and digital together) *****/
-static int snd_echo_vumeters_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct echoaudio *chip;
-
- chip = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 96;
- uinfo->value.integer.min = ECHOGAIN_MINOUT;
- uinfo->value.integer.max = 0;
-#ifdef ECHOCARD_HAS_VMIXER
- uinfo->dimen.d[0] = 3; /* Out, In, Virt */
-#else
- uinfo->dimen.d[0] = 2; /* Out, In */
-#endif
- uinfo->dimen.d[1] = 16; /* 16 channels */
- uinfo->dimen.d[2] = 2; /* 0=level, 1=peak */
- return 0;
-}
-
-static int snd_echo_vumeters_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
-
- chip = snd_kcontrol_chip(kcontrol);
- get_audio_meters(chip, ucontrol->value.integer.value);
- return 0;
-}
-
-static struct snd_kcontrol_new snd_echo_vumeters __devinitdata = {
- .name = "VU-meters",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = SNDRV_CTL_ELEM_ACCESS_READ |
- SNDRV_CTL_ELEM_ACCESS_VOLATILE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = snd_echo_vumeters_info,
- .get = snd_echo_vumeters_get,
- .tlv = {.p = db_scale_output_gain},
-};
-
-
-
-/*** Channels info - it exports informations about the number of channels ***/
-static int snd_echo_channels_info_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct echoaudio *chip;
-
- chip = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 6;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1 << ECHO_CLOCK_NUMBER;
- return 0;
-}
-
-static int snd_echo_channels_info_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct echoaudio *chip;
- int detected, clocks, bit, src;
-
- chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = num_busses_in(chip);
- ucontrol->value.integer.value[1] = num_analog_busses_in(chip);
- ucontrol->value.integer.value[2] = num_busses_out(chip);
- ucontrol->value.integer.value[3] = num_analog_busses_out(chip);
- ucontrol->value.integer.value[4] = num_pipes_out(chip);
-
- /* Compute the bitmask of the currently valid input clocks */
- detected = detect_input_clocks(chip);
- clocks = 0;
- src = chip->num_clock_sources - 1;
- for (bit = ECHO_CLOCK_NUMBER - 1; bit >= 0; bit--)
- if (detected & (1 << bit))
- for (; src >= 0; src--)
- if (bit == chip->clock_source_list[src]) {
- clocks |= 1 << src;
- break;
- }
- ucontrol->value.integer.value[5] = clocks;
-
- return 0;
-}
-
-static struct snd_kcontrol_new snd_echo_channels_info __devinitdata = {
- .name = "Channels info",
- .iface = SNDRV_CTL_ELEM_IFACE_HWDEP,
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_echo_channels_info_info,
- .get = snd_echo_channels_info_get,
-};
-
-
-
-
-/******************************************************************************
- IRQ Handler
-******************************************************************************/
-
-static irqreturn_t snd_echo_interrupt(int irq, void *dev_id)
-{
- struct echoaudio *chip = dev_id;
- struct snd_pcm_substream *substream;
- int period, ss, st;
-
- spin_lock(&chip->lock);
- st = service_irq(chip);
- if (st < 0) {
- spin_unlock(&chip->lock);
- return IRQ_NONE;
- }
- /* The hardware doesn't tell us which substream caused the irq,
- thus we have to check all running substreams. */
- for (ss = 0; ss < DSP_MAXPIPES; ss++) {
- substream = chip->substream[ss];
- if (substream && ((struct audiopipe *)substream->runtime->
- private_data)->state == PIPE_STATE_STARTED) {
- period = pcm_pointer(substream) /
- substream->runtime->period_size;
- if (period != chip->last_period[ss]) {
- chip->last_period[ss] = period;
- spin_unlock(&chip->lock);
- snd_pcm_period_elapsed(substream);
- spin_lock(&chip->lock);
- }
- }
- }
- spin_unlock(&chip->lock);
-
-#ifdef ECHOCARD_HAS_MIDI
- if (st > 0 && chip->midi_in) {
- snd_rawmidi_receive(chip->midi_in, chip->midi_buffer, st);
- DE_MID(("rawmidi_iread=%d\n", st));
- }
-#endif
- return IRQ_HANDLED;
-}
-
-
-
-
-/******************************************************************************
- Module construction / destruction
-******************************************************************************/
-
-static int snd_echo_free(struct echoaudio *chip)
-{
- DE_INIT(("Stop DSP...\n"));
- if (chip->comm_page)
- rest_in_peace(chip);
- DE_INIT(("Stopped.\n"));
-
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
-
- if (chip->comm_page)
- snd_dma_free_pages(&chip->commpage_dma_buf);
-
- if (chip->dsp_registers)
- iounmap(chip->dsp_registers);
-
- if (chip->iores)
- release_and_free_resource(chip->iores);
-
- DE_INIT(("MMIO freed.\n"));
-
- pci_disable_device(chip->pci);
-
- /* release chip data */
- free_firmware_cache(chip);
- kfree(chip);
- DE_INIT(("Chip freed.\n"));
- return 0;
-}
-
-
-
-static int snd_echo_dev_free(struct snd_device *device)
-{
- struct echoaudio *chip = device->device_data;
-
- DE_INIT(("snd_echo_dev_free()...\n"));
- return snd_echo_free(chip);
-}
-
-
-
-/* <--snd_echo_probe() */
-static __devinit int snd_echo_create(struct snd_card *card,
- struct pci_dev *pci,
- struct echoaudio **rchip)
-{
- struct echoaudio *chip;
- int err;
- size_t sz;
- static struct snd_device_ops ops = {
- .dev_free = snd_echo_dev_free,
- };
-
- *rchip = NULL;
-
- pci_write_config_byte(pci, PCI_LATENCY_TIMER, 0xC0);
-
- if ((err = pci_enable_device(pci)) < 0)
- return err;
- pci_set_master(pci);
-
- /* Allocate chip if needed */
- if (!*rchip) {
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (!chip) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
- DE_INIT(("chip=%p\n", chip));
- spin_lock_init(&chip->lock);
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
- atomic_set(&chip->opencount, 0);
- mutex_init(&chip->mode_mutex);
- chip->can_set_rate = 1;
- } else {
- /* If this was called from the resume function, chip is
- * already allocated and it contains current card settings.
- */
- chip = *rchip;
- }
-
- /* PCI resource allocation */
- chip->dsp_registers_phys = pci_resource_start(pci, 0);
- sz = pci_resource_len(pci, 0);
- if (sz > PAGE_SIZE)
- sz = PAGE_SIZE; /* We map only the required part */
-
- if ((chip->iores = request_mem_region(chip->dsp_registers_phys, sz,
- ECHOCARD_NAME)) == NULL) {
- snd_echo_free(chip);
- snd_printk(KERN_ERR "cannot get memory region\n");
- return -EBUSY;
- }
- chip->dsp_registers = (volatile u32 __iomem *)
- ioremap_nocache(chip->dsp_registers_phys, sz);
-
- if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
- snd_echo_free(chip);
- snd_printk(KERN_ERR "cannot grab irq\n");
- return -EBUSY;
- }
- chip->irq = pci->irq;
- DE_INIT(("pci=%p irq=%d subdev=%04x Init hardware...\n",
- chip->pci, chip->irq, chip->pci->subsystem_device));
-
- /* Create the DSP comm page - this is the area of memory used for most
- of the communication with the DSP, which accesses it via bus mastering */
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
- sizeof(struct comm_page),
- &chip->commpage_dma_buf) < 0) {
- snd_echo_free(chip);
- snd_printk(KERN_ERR "cannot allocate the comm page\n");
- return -ENOMEM;
- }
- chip->comm_page_phys = chip->commpage_dma_buf.addr;
- chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area;
-
- err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device);
- if (err >= 0)
- err = set_mixer_defaults(chip);
- if (err < 0) {
- DE_INIT(("init_hw err=%d\n", err));
- snd_echo_free(chip);
- return err;
- }
- DE_INIT(("Card init OK\n"));
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_echo_free(chip);
- return err;
- }
- *rchip = chip;
- /* Init done ! */
- return 0;
-}
-
-
-
-/* constructor */
-static int __devinit snd_echo_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct echoaudio *chip;
- char *dsp;
- int i, err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- DE_INIT(("Echoaudio driver starting...\n"));
- i = 0;
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- snd_card_set_dev(card, &pci->dev);
-
- chip = NULL; /* Tells snd_echo_create to allocate chip */
- if ((err = snd_echo_create(card, pci, &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- strcpy(card->driver, "Echo_" ECHOCARD_NAME);
- strcpy(card->shortname, chip->card_name);
-
- dsp = "56301";
- if (pci_id->device == 0x3410)
- dsp = "56361";
-
- sprintf(card->longname, "%s rev.%d (DSP%s) at 0x%lx irq %i",
- card->shortname, pci_id->subdevice & 0x000f, dsp,
- chip->dsp_registers_phys, chip->irq);
-
- if ((err = snd_echo_new_pcm(chip)) < 0) {
- snd_printk(KERN_ERR "new pcm error %d\n", err);
- snd_card_free(card);
- return err;
- }
-
-#ifdef ECHOCARD_HAS_MIDI
- if (chip->has_midi) { /* Some Mia's do not have midi */
- if ((err = snd_echo_midi_create(card, chip)) < 0) {
- snd_printk(KERN_ERR "new midi error %d\n", err);
- snd_card_free(card);
- return err;
- }
- }
-#endif
-
-#ifdef ECHOCARD_HAS_VMIXER
- snd_echo_vmixer.count = num_pipes_out(chip) * num_busses_out(chip);
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vmixer, chip))) < 0)
- goto ctl_error;
-#ifdef ECHOCARD_HAS_LINE_OUT_GAIN
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&snd_echo_line_output_gain, chip));
- if (err < 0)
- goto ctl_error;
-#endif
-#else /* ECHOCARD_HAS_VMIXER */
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&snd_echo_pcm_output_gain, chip));
- if (err < 0)
- goto ctl_error;
-#endif /* ECHOCARD_HAS_VMIXER */
-
-#ifdef ECHOCARD_HAS_INPUT_GAIN
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_input_gain, chip))) < 0)
- goto ctl_error;
-#endif
-
-#ifdef ECHOCARD_HAS_INPUT_NOMINAL_LEVEL
- if (!chip->hasnt_input_nominal_level)
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_intput_nominal_level, chip))) < 0)
- goto ctl_error;
-#endif
-
-#ifdef ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_output_nominal_level, chip))) < 0)
- goto ctl_error;
-#endif
-
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters_switch, chip))) < 0)
- goto ctl_error;
-
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters, chip))) < 0)
- goto ctl_error;
-
-#ifdef ECHOCARD_HAS_MONITOR
- snd_echo_monitor_mixer.count = num_busses_in(chip) * num_busses_out(chip);
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_monitor_mixer, chip))) < 0)
- goto ctl_error;
-#endif
-
-#ifdef ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_automute_switch, chip))) < 0)
- goto ctl_error;
-#endif
-
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_channels_info, chip))) < 0)
- goto ctl_error;
-
-#ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH
- /* Creates a list of available digital modes */
- chip->num_digital_modes = 0;
- for (i = 0; i < 6; i++)
- if (chip->digital_modes & (1 << i))
- chip->digital_mode_list[chip->num_digital_modes++] = i;
-
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_digital_mode_switch, chip))) < 0)
- goto ctl_error;
-#endif /* ECHOCARD_HAS_DIGITAL_MODE_SWITCH */
-
-#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK
- /* Creates a list of available clock sources */
- chip->num_clock_sources = 0;
- for (i = 0; i < 10; i++)
- if (chip->input_clock_types & (1 << i))
- chip->clock_source_list[chip->num_clock_sources++] = i;
-
- if (chip->num_clock_sources > 1) {
- chip->clock_src_ctl = snd_ctl_new1(&snd_echo_clock_source_switch, chip);
- if ((err = snd_ctl_add(chip->card, chip->clock_src_ctl)) < 0)
- goto ctl_error;
- }
-#endif /* ECHOCARD_HAS_EXTERNAL_CLOCK */
-
-#ifdef ECHOCARD_HAS_DIGITAL_IO
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_spdif_mode_switch, chip))) < 0)
- goto ctl_error;
-#endif
-
-#ifdef ECHOCARD_HAS_PHANTOM_POWER
- if (chip->has_phantom_power)
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_phantom_power_switch, chip))) < 0)
- goto ctl_error;
-#endif
-
- err = snd_card_register(card);
- if (err < 0)
- goto ctl_error;
- snd_printk(KERN_INFO "Card registered: %s\n", card->longname);
-
- pci_set_drvdata(pci, chip);
- dev++;
- return 0;
-
-ctl_error:
- snd_printk(KERN_ERR "new control error %d\n", err);
- snd_card_free(card);
- return err;
-}
-
-
-
-#if defined(CONFIG_PM)
-
-static int snd_echo_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct echoaudio *chip = pci_get_drvdata(pci);
-
- DE_INIT(("suspend start\n"));
- snd_pcm_suspend_all(chip->analog_pcm);
- snd_pcm_suspend_all(chip->digital_pcm);
-
-#ifdef ECHOCARD_HAS_MIDI
- /* This call can sleep */
- if (chip->midi_out)
- snd_echo_midi_output_trigger(chip->midi_out, 0);
-#endif
- spin_lock_irq(&chip->lock);
- if (wait_handshake(chip)) {
- spin_unlock_irq(&chip->lock);
- return -EIO;
- }
- clear_handshake(chip);
- if (send_vector(chip, DSP_VC_GO_COMATOSE) < 0) {
- spin_unlock_irq(&chip->lock);
- return -EIO;
- }
- spin_unlock_irq(&chip->lock);
-
- chip->dsp_code = NULL;
- free_irq(chip->irq, chip);
- chip->irq = -1;
- pci_save_state(pci);
- pci_disable_device(pci);
-
- DE_INIT(("suspend done\n"));
- return 0;
-}
-
-
-
-static int snd_echo_resume(struct pci_dev *pci)
-{
- struct echoaudio *chip = pci_get_drvdata(pci);
- struct comm_page *commpage, *commpage_bak;
- u32 pipe_alloc_mask;
- int err;
-
- DE_INIT(("resume start\n"));
- pci_restore_state(pci);
- commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL);
- if (commpage_bak == NULL)
- return -ENOMEM;
- commpage = chip->comm_page;
- memcpy(commpage_bak, commpage, sizeof(struct comm_page));
-
- err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device);
- if (err < 0) {
- kfree(commpage_bak);
- DE_INIT(("resume init_hw err=%d\n", err));
- snd_echo_free(chip);
- return err;
- }
- DE_INIT(("resume init OK\n"));
-
- /* Temporarily set chip->pipe_alloc_mask=0 otherwise
- * restore_dsp_settings() fails.
- */
- pipe_alloc_mask = chip->pipe_alloc_mask;
- chip->pipe_alloc_mask = 0;
- err = restore_dsp_rettings(chip);
- chip->pipe_alloc_mask = pipe_alloc_mask;
- if (err < 0) {
- kfree(commpage_bak);
- return err;
- }
- DE_INIT(("resume restore OK\n"));
-
- memcpy(&commpage->audio_format, &commpage_bak->audio_format,
- sizeof(commpage->audio_format));
- memcpy(&commpage->sglist_addr, &commpage_bak->sglist_addr,
- sizeof(commpage->sglist_addr));
- memcpy(&commpage->midi_output, &commpage_bak->midi_output,
- sizeof(commpage->midi_output));
- kfree(commpage_bak);
-
- if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
- snd_echo_free(chip);
- snd_printk(KERN_ERR "cannot grab irq\n");
- return -EBUSY;
- }
- chip->irq = pci->irq;
- DE_INIT(("resume irq=%d\n", chip->irq));
-
-#ifdef ECHOCARD_HAS_MIDI
- if (chip->midi_input_enabled)
- enable_midi_input(chip, TRUE);
- if (chip->midi_out)
- snd_echo_midi_output_trigger(chip->midi_out, 1);
-#endif
-
- DE_INIT(("resume done\n"));
- return 0;
-}
-
-#endif /* CONFIG_PM */
-
-
-
-static void __devexit snd_echo_remove(struct pci_dev *pci)
-{
- struct echoaudio *chip;
-
- chip = pci_get_drvdata(pci);
- if (chip)
- snd_card_free(chip->card);
- pci_set_drvdata(pci, NULL);
-}
-
-
-
-/******************************************************************************
- Everything starts and ends here
-******************************************************************************/
-
-/* pci_driver definition */
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_echo_ids,
- .probe = snd_echo_probe,
- .remove = __devexit_p(snd_echo_remove),
-#ifdef CONFIG_PM
- .suspend = snd_echo_suspend,
- .resume = snd_echo_resume,
-#endif /* CONFIG_PM */
-};
-
-
-
-/* initialization of the module */
-static int __init alsa_card_echo_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-
-
-/* clean up the module */
-static void __exit alsa_card_echo_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-
-module_init(alsa_card_echo_init)
-module_exit(alsa_card_echo_exit)
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio.h b/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio.h
deleted file mode 100644
index 1df974dc..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio.h
+++ /dev/null
@@ -1,598 +0,0 @@
-/****************************************************************************
-
- Copyright Echo Digital Audio Corporation (c) 1998 - 2004
- All rights reserved
- www.echoaudio.com
-
- This file is part of Echo Digital Audio's generic driver library.
-
- Echo Digital Audio's generic driver library is free software;
- you can redistribute it and/or modify it under the terms of
- the GNU General Public License as published by the Free Software
- Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- ****************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
- ****************************************************************************
-
-
- Here's a block diagram of how most of the cards work:
-
- +-----------+
- record | |<-------------------- Inputs
- <-------| | |
- PCI | Transport | |
- bus | engine | \|/
- ------->| | +-------+
- play | |--->|monitor|-------> Outputs
- +-----------+ | mixer |
- +-------+
-
- The lines going to and from the PCI bus represent "pipes". A pipe performs
- audio transport - moving audio data to and from buffers on the host via
- bus mastering.
-
- The inputs and outputs on the right represent input and output "busses."
- A bus is a physical, real connection to the outside world. An example
- of a bus would be the 1/4" analog connectors on the back of Layla or
- an RCA S/PDIF connector.
-
- For most cards, there is a one-to-one correspondence between outputs
- and busses; that is, each individual pipe is hard-wired to a single bus.
-
- Cards that work this way are Darla20, Gina20, Layla20, Darla24, Gina24,
- Layla24, Mona, and Indigo.
-
-
- Mia has a feature called "virtual outputs."
-
-
- +-----------+
- record | |<----------------------------- Inputs
- <-------| | |
- PCI | Transport | |
- bus | engine | \|/
- ------->| | +------+ +-------+
- play | |-->|vmixer|-->|monitor|-------> Outputs
- +-----------+ +------+ | mixer |
- +-------+
-
-
- Obviously, the difference here is the box labeled "vmixer." Vmixer is
- short for "virtual output mixer." For Mia, pipes are *not* hard-wired
- to a single bus; the vmixer lets you mix any pipe to any bus in any
- combination.
-
- Note, however, that the left-hand side of the diagram is unchanged.
- Transport works exactly the same way - the difference is in the mixer stage.
-
-
- Pipes and busses are numbered starting at zero.
-
-
-
- Pipe index
- ==========
-
- A number of calls in CEchoGals refer to a "pipe index". A pipe index is
- a unique number for a pipe that unambiguously refers to a playback or record
- pipe. Pipe indices are numbered starting with analog outputs, followed by
- digital outputs, then analog inputs, then digital inputs.
-
- Take Gina24 as an example:
-
- Pipe index
-
- 0-7 Analog outputs (0 .. FirstDigitalBusOut-1)
- 8-15 Digital outputs (FirstDigitalBusOut .. NumBussesOut-1)
- 16-17 Analog inputs
- 18-25 Digital inputs
-
-
- You get the pipe index by calling CEchoGals::OpenAudio; the other transport
- functions take the pipe index as a parameter. If you need a pipe index for
- some other reason, use the handy Makepipe_index method.
-
-
- Some calls take a CChannelMask parameter; CChannelMask is a handy way to
- group pipe indices.
-
-
-
- Digital mode switch
- ===================
-
- Some cards (right now, Gina24, Layla24, and Mona) have a Digital Mode Switch
- or DMS. Cards with a DMS can be set to one of three mutually exclusive
- digital modes: S/PDIF RCA, S/PDIF optical, or ADAT optical.
-
- This may create some confusion since ADAT optical is 8 channels wide and
- S/PDIF is only two channels wide. Gina24, Layla24, and Mona handle this
- by acting as if they always have 8 digital outs and ins. If you are in
- either S/PDIF mode, the last 6 channels don't do anything - data sent
- out these channels is thrown away and you will always record zeros.
-
- Note that with Gina24, Layla24, and Mona, sample rates above 50 kHz are
- only available if you have the card configured for S/PDIF optical or S/PDIF
- RCA.
-
-
-
- Double speed mode
- =================
-
- Some of the cards support 88.2 kHz and 96 kHz sampling (Darla24, Gina24,
- Layla24, Mona, Mia, and Indigo). For these cards, the driver sometimes has
- to worry about "double speed mode"; double speed mode applies whenever the
- sampling rate is above 50 kHz.
-
- For instance, Mona and Layla24 support word clock sync. However, they
- actually support two different word clock modes - single speed (below
- 50 kHz) and double speed (above 50 kHz). The hardware detects if a single
- or double speed word clock signal is present; the generic code uses that
- information to determine which mode to use.
-
- The generic code takes care of all this for you.
-*/
-
-
-#ifndef _ECHOAUDIO_H_
-#define _ECHOAUDIO_H_
-
-
-#define TRUE 1
-#define FALSE 0
-
-#include "echoaudio_dsp.h"
-
-
-
-/***********************************************************************
-
- PCI configuration space
-
-***********************************************************************/
-
-/*
- * PCI vendor ID and device IDs for the hardware
- */
-#define VENDOR_ID 0x1057
-#define DEVICE_ID_56301 0x1801
-#define DEVICE_ID_56361 0x3410
-#define SUBVENDOR_ID 0xECC0
-
-
-/*
- * Valid Echo PCI subsystem card IDs
- */
-#define DARLA20 0x0010
-#define GINA20 0x0020
-#define LAYLA20 0x0030
-#define DARLA24 0x0040
-#define GINA24 0x0050
-#define LAYLA24 0x0060
-#define MONA 0x0070
-#define MIA 0x0080
-#define INDIGO 0x0090
-#define INDIGO_IO 0x00a0
-#define INDIGO_DJ 0x00b0
-#define DC8 0x00c0
-#define INDIGO_IOX 0x00d0
-#define INDIGO_DJX 0x00e0
-#define ECHO3G 0x0100
-
-
-/************************************************************************
-
- Array sizes and so forth
-
-***********************************************************************/
-
-/*
- * Sizes
- */
-#define ECHO_MAXAUDIOINPUTS 32 /* Max audio input channels */
-#define ECHO_MAXAUDIOOUTPUTS 32 /* Max audio output channels */
-#define ECHO_MAXAUDIOPIPES 32 /* Max number of input and output
- * pipes */
-#define E3G_MAX_OUTPUTS 16
-#define ECHO_MAXMIDIJACKS 1 /* Max MIDI ports */
-#define ECHO_MIDI_QUEUE_SZ 512 /* Max MIDI input queue entries */
-#define ECHO_MTC_QUEUE_SZ 32 /* Max MIDI time code input queue
- * entries */
-
-/*
- * MIDI activity indicator timeout
- */
-#define MIDI_ACTIVITY_TIMEOUT_USEC 200000
-
-
-/****************************************************************************
-
- Clocks
-
-*****************************************************************************/
-
-/*
- * Clock numbers
- */
-#define ECHO_CLOCK_INTERNAL 0
-#define ECHO_CLOCK_WORD 1
-#define ECHO_CLOCK_SUPER 2
-#define ECHO_CLOCK_SPDIF 3
-#define ECHO_CLOCK_ADAT 4
-#define ECHO_CLOCK_ESYNC 5
-#define ECHO_CLOCK_ESYNC96 6
-#define ECHO_CLOCK_MTC 7
-#define ECHO_CLOCK_NUMBER 8
-#define ECHO_CLOCKS 0xffff
-
-/*
- * Clock bit numbers - used to report capabilities and whatever clocks
- * are being detected dynamically.
- */
-#define ECHO_CLOCK_BIT_INTERNAL (1 << ECHO_CLOCK_INTERNAL)
-#define ECHO_CLOCK_BIT_WORD (1 << ECHO_CLOCK_WORD)
-#define ECHO_CLOCK_BIT_SUPER (1 << ECHO_CLOCK_SUPER)
-#define ECHO_CLOCK_BIT_SPDIF (1 << ECHO_CLOCK_SPDIF)
-#define ECHO_CLOCK_BIT_ADAT (1 << ECHO_CLOCK_ADAT)
-#define ECHO_CLOCK_BIT_ESYNC (1 << ECHO_CLOCK_ESYNC)
-#define ECHO_CLOCK_BIT_ESYNC96 (1 << ECHO_CLOCK_ESYNC96)
-#define ECHO_CLOCK_BIT_MTC (1<<ECHO_CLOCK_MTC)
-
-
-/***************************************************************************
-
- Digital modes
-
-****************************************************************************/
-
-/*
- * Digital modes for Mona, Layla24, and Gina24
- */
-#define DIGITAL_MODE_NONE 0xFF
-#define DIGITAL_MODE_SPDIF_RCA 0
-#define DIGITAL_MODE_SPDIF_OPTICAL 1
-#define DIGITAL_MODE_ADAT 2
-#define DIGITAL_MODE_SPDIF_CDROM 3
-#define DIGITAL_MODES 4
-
-/*
- * Digital mode capability masks
- */
-#define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA (1 << DIGITAL_MODE_SPDIF_RCA)
-#define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL (1 << DIGITAL_MODE_SPDIF_OPTICAL)
-#define ECHOCAPS_HAS_DIGITAL_MODE_ADAT (1 << DIGITAL_MODE_ADAT)
-#define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_CDROM (1 << DIGITAL_MODE_SPDIF_CDROM)
-
-
-#define EXT_3GBOX_NC 0x01 /* 3G box not connected */
-#define EXT_3GBOX_NOT_SET 0x02 /* 3G box not detected yet */
-
-
-#define ECHOGAIN_MUTED (-128) /* Minimum possible gain */
-#define ECHOGAIN_MINOUT (-128) /* Min output gain (dB) */
-#define ECHOGAIN_MAXOUT (6) /* Max output gain (dB) */
-#define ECHOGAIN_MININP (-50) /* Min input gain (0.5 dB) */
-#define ECHOGAIN_MAXINP (50) /* Max input gain (0.5 dB) */
-
-#define PIPE_STATE_STOPPED 0 /* Pipe has been reset */
-#define PIPE_STATE_PAUSED 1 /* Pipe has been stopped */
-#define PIPE_STATE_STARTED 2 /* Pipe has been started */
-#define PIPE_STATE_PENDING 3 /* Pipe has pending start */
-
-
-/* Debug initialization */
-#ifdef CONFIG_SND_DEBUG
-#define DE_INIT(x) snd_printk x
-#else
-#define DE_INIT(x)
-#endif
-
-/* Debug hw_params callbacks */
-#ifdef CONFIG_SND_DEBUG
-#define DE_HWP(x) snd_printk x
-#else
-#define DE_HWP(x)
-#endif
-
-/* Debug normal activity (open, start, stop...) */
-#ifdef CONFIG_SND_DEBUG
-#define DE_ACT(x) snd_printk x
-#else
-#define DE_ACT(x)
-#endif
-
-/* Debug midi activity */
-#ifdef CONFIG_SND_DEBUG
-#define DE_MID(x) snd_printk x
-#else
-#define DE_MID(x)
-#endif
-
-
-struct audiopipe {
- volatile u32 *dma_counter; /* Commpage register that contains
- * the current dma position
- * (lower 32 bits only)
- */
- u32 last_counter; /* The last position, which is used
- * to compute...
- */
- u32 position; /* ...the number of bytes tranferred
- * by the DMA engine, modulo the
- * buffer size
- */
- short index; /* Index of the first channel or <0
- * if hw is not configured yet
- */
- short interleave;
- struct snd_dma_buffer sgpage; /* Room for the scatter-gather list */
- struct snd_pcm_hardware hw;
- struct snd_pcm_hw_constraint_list constr;
- short sglist_head;
- char state; /* pipe state */
-};
-
-
-struct audioformat {
- u8 interleave; /* How the data is arranged in memory:
- * mono = 1, stereo = 2, ...
- */
- u8 bits_per_sample; /* 8, 16, 24, 32 (24 bits left aligned) */
- char mono_to_stereo; /* Only used if interleave is 1 and
- * if this is an output pipe.
- */
- char data_are_bigendian; /* 1 = big endian, 0 = little endian */
-};
-
-
-struct echoaudio {
- spinlock_t lock;
- struct snd_pcm_substream *substream[DSP_MAXPIPES];
- int last_period[DSP_MAXPIPES];
- struct mutex mode_mutex;
- u16 num_digital_modes, digital_mode_list[6];
- u16 num_clock_sources, clock_source_list[10];
- atomic_t opencount;
- struct snd_kcontrol *clock_src_ctl;
- struct snd_pcm *analog_pcm, *digital_pcm;
- struct snd_card *card;
- const char *card_name;
- struct pci_dev *pci;
- unsigned long dsp_registers_phys;
- struct resource *iores;
- struct snd_dma_buffer commpage_dma_buf;
- int irq;
-#ifdef ECHOCARD_HAS_MIDI
- struct snd_rawmidi *rmidi;
- struct snd_rawmidi_substream *midi_in, *midi_out;
-#endif
- struct timer_list timer;
- char tinuse; /* Timer in use */
- char midi_full; /* MIDI output buffer is full */
- char can_set_rate;
- char rate_set;
-
- /* This stuff is used mainly by the lowlevel code */
- struct comm_page *comm_page; /* Virtual address of the memory
- * seen by DSP
- */
- u32 pipe_alloc_mask; /* Bitmask of allocated pipes */
- u32 pipe_cyclic_mask; /* Bitmask of pipes with cyclic
- * buffers
- */
- u32 sample_rate; /* Card sample rate in Hz */
- u8 digital_mode; /* Current digital mode
- * (see DIGITAL_MODE_*)
- */
- u8 spdif_status; /* Gina20, Darla20, Darla24 - only */
- u8 clock_state; /* Gina20, Darla20, Darla24 - only */
- u8 input_clock; /* Currently selected sample clock
- * source
- */
- u8 output_clock; /* Layla20 only */
- char meters_enabled; /* VU-meters status */
- char asic_loaded; /* Set TRUE when ASIC loaded */
- char bad_board; /* Set TRUE if DSP won't load */
- char professional_spdif; /* 0 = consumer; 1 = professional */
- char non_audio_spdif; /* 3G - only */
- char digital_in_automute; /* Gina24, Layla24, Mona - only */
- char has_phantom_power;
- char hasnt_input_nominal_level; /* Gina3G */
- char phantom_power; /* Gina3G - only */
- char has_midi;
- char midi_input_enabled;
-
-#ifdef ECHOCARD_ECHO3G
- /* External module -dependent pipe and bus indexes */
- char px_digital_out, px_analog_in, px_digital_in, px_num;
- char bx_digital_out, bx_analog_in, bx_digital_in, bx_num;
-#endif
-
- char nominal_level[ECHO_MAXAUDIOPIPES]; /* True == -10dBV
- * False == +4dBu */
- s8 input_gain[ECHO_MAXAUDIOINPUTS]; /* Input level -50..+50
- * unit is 0.5dB */
- s8 output_gain[ECHO_MAXAUDIOOUTPUTS]; /* Output level -128..+6 dB
- * (-128=muted) */
- s8 monitor_gain[ECHO_MAXAUDIOOUTPUTS][ECHO_MAXAUDIOINPUTS];
- /* -128..+6 dB */
- s8 vmixer_gain[ECHO_MAXAUDIOOUTPUTS][ECHO_MAXAUDIOOUTPUTS];
- /* -128..+6 dB */
-
- u16 digital_modes; /* Bitmask of supported modes
- * (see ECHOCAPS_HAS_DIGITAL_MODE_*) */
- u16 input_clock_types; /* Suppoted input clock types */
- u16 output_clock_types; /* Suppoted output clock types -
- * Layla20 only */
- u16 device_id, subdevice_id;
- u16 *dsp_code; /* Current DSP code loaded,
- * NULL if nothing loaded */
- short dsp_code_to_load; /* DSP code to load */
- short asic_code; /* Current ASIC code */
- u32 comm_page_phys; /* Physical address of the
- * memory seen by DSP */
- volatile u32 __iomem *dsp_registers; /* DSP's register base */
- u32 active_mask; /* Chs. active mask or
- * punks out */
-#ifdef CONFIG_PM
- const struct firmware *fw_cache[8]; /* Cached firmwares */
-#endif
-
-#ifdef ECHOCARD_HAS_MIDI
- u16 mtc_state; /* State for MIDI input parsing state machine */
- u8 midi_buffer[MIDI_IN_BUFFER_SIZE];
-#endif
-};
-
-
-static int init_dsp_comm_page(struct echoaudio *chip);
-static int init_line_levels(struct echoaudio *chip);
-static int free_pipes(struct echoaudio *chip, struct audiopipe *pipe);
-static int load_firmware(struct echoaudio *chip);
-static int wait_handshake(struct echoaudio *chip);
-static int send_vector(struct echoaudio *chip, u32 command);
-static int get_firmware(const struct firmware **fw_entry,
- struct echoaudio *chip, const short fw_index);
-static void free_firmware(const struct firmware *fw_entry);
-
-#ifdef ECHOCARD_HAS_MIDI
-static int enable_midi_input(struct echoaudio *chip, char enable);
-static void snd_echo_midi_output_trigger(
- struct snd_rawmidi_substream *substream, int up);
-static int midi_service_irq(struct echoaudio *chip);
-static int __devinit snd_echo_midi_create(struct snd_card *card,
- struct echoaudio *chip);
-#endif
-
-
-static inline void clear_handshake(struct echoaudio *chip)
-{
- chip->comm_page->handshake = 0;
-}
-
-static inline u32 get_dsp_register(struct echoaudio *chip, u32 index)
-{
- return readl(&chip->dsp_registers[index]);
-}
-
-static inline void set_dsp_register(struct echoaudio *chip, u32 index,
- u32 value)
-{
- writel(value, &chip->dsp_registers[index]);
-}
-
-
-/* Pipe and bus indexes. PX_* and BX_* are defined as chip->px_* and chip->bx_*
-for 3G cards because they depend on the external box. They are integer
-constants for all other cards.
-Never use those defines directly, use the following functions instead. */
-
-static inline int px_digital_out(const struct echoaudio *chip)
-{
- return PX_DIGITAL_OUT;
-}
-
-static inline int px_analog_in(const struct echoaudio *chip)
-{
- return PX_ANALOG_IN;
-}
-
-static inline int px_digital_in(const struct echoaudio *chip)
-{
- return PX_DIGITAL_IN;
-}
-
-static inline int px_num(const struct echoaudio *chip)
-{
- return PX_NUM;
-}
-
-static inline int bx_digital_out(const struct echoaudio *chip)
-{
- return BX_DIGITAL_OUT;
-}
-
-static inline int bx_analog_in(const struct echoaudio *chip)
-{
- return BX_ANALOG_IN;
-}
-
-static inline int bx_digital_in(const struct echoaudio *chip)
-{
- return BX_DIGITAL_IN;
-}
-
-static inline int bx_num(const struct echoaudio *chip)
-{
- return BX_NUM;
-}
-
-static inline int num_pipes_out(const struct echoaudio *chip)
-{
- return px_analog_in(chip);
-}
-
-static inline int num_pipes_in(const struct echoaudio *chip)
-{
- return px_num(chip) - px_analog_in(chip);
-}
-
-static inline int num_busses_out(const struct echoaudio *chip)
-{
- return bx_analog_in(chip);
-}
-
-static inline int num_busses_in(const struct echoaudio *chip)
-{
- return bx_num(chip) - bx_analog_in(chip);
-}
-
-static inline int num_analog_busses_out(const struct echoaudio *chip)
-{
- return bx_digital_out(chip);
-}
-
-static inline int num_analog_busses_in(const struct echoaudio *chip)
-{
- return bx_digital_in(chip) - bx_analog_in(chip);
-}
-
-static inline int num_digital_busses_out(const struct echoaudio *chip)
-{
- return num_busses_out(chip) - num_analog_busses_out(chip);
-}
-
-static inline int num_digital_busses_in(const struct echoaudio *chip)
-{
- return num_busses_in(chip) - num_analog_busses_in(chip);
-}
-
-/* The monitor array is a one-dimensional array; compute the offset
- * into the array */
-static inline int monitor_index(const struct echoaudio *chip, int out, int in)
-{
- return out * num_busses_in(chip) + in;
-}
-
-
-#ifndef pci_device
-#define pci_device(chip) (&chip->pci->dev)
-#endif
-
-
-#endif /* _ECHOAUDIO_H_ */
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_3g.c b/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_3g.c
deleted file mode 100644
index 658db44e..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_3g.c
+++ /dev/null
@@ -1,432 +0,0 @@
-/****************************************************************************
-
- Copyright Echo Digital Audio Corporation (c) 1998 - 2004
- All rights reserved
- www.echoaudio.com
-
- This file is part of Echo Digital Audio's generic driver library.
-
- Echo Digital Audio's generic driver library is free software;
- you can redistribute it and/or modify it under the terms of
- the GNU General Public License as published by the Free Software
- Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- *************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
-****************************************************************************/
-
-
-
-/* These functions are common for all "3G" cards */
-
-
-static int check_asic_status(struct echoaudio *chip)
-{
- u32 box_status;
-
- if (wait_handshake(chip))
- return -EIO;
-
- chip->comm_page->ext_box_status = cpu_to_le32(E3G_ASIC_NOT_LOADED);
- chip->asic_loaded = FALSE;
- clear_handshake(chip);
- send_vector(chip, DSP_VC_TEST_ASIC);
-
- if (wait_handshake(chip)) {
- chip->dsp_code = NULL;
- return -EIO;
- }
-
- box_status = le32_to_cpu(chip->comm_page->ext_box_status);
- DE_INIT(("box_status=%x\n", box_status));
- if (box_status == E3G_ASIC_NOT_LOADED)
- return -ENODEV;
-
- chip->asic_loaded = TRUE;
- return box_status & E3G_BOX_TYPE_MASK;
-}
-
-
-
-static inline u32 get_frq_reg(struct echoaudio *chip)
-{
- return le32_to_cpu(chip->comm_page->e3g_frq_register);
-}
-
-
-
-/* Most configuration of 3G cards is accomplished by writing the control
-register. write_control_reg sends the new control register value to the DSP. */
-static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq,
- char force)
-{
- if (wait_handshake(chip))
- return -EIO;
-
- DE_ACT(("WriteControlReg: Setting 0x%x, 0x%x\n", ctl, frq));
-
- ctl = cpu_to_le32(ctl);
- frq = cpu_to_le32(frq);
-
- if (ctl != chip->comm_page->control_register ||
- frq != chip->comm_page->e3g_frq_register || force) {
- chip->comm_page->e3g_frq_register = frq;
- chip->comm_page->control_register = ctl;
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_WRITE_CONTROL_REG);
- }
-
- DE_ACT(("WriteControlReg: not written, no change\n"));
- return 0;
-}
-
-
-
-/* Set the digital mode - currently for Gina24, Layla24, Mona, 3G */
-static int set_digital_mode(struct echoaudio *chip, u8 mode)
-{
- u8 previous_mode;
- int err, i, o;
-
- /* All audio channels must be closed before changing the digital mode */
- if (snd_BUG_ON(chip->pipe_alloc_mask))
- return -EAGAIN;
-
- if (snd_BUG_ON(!(chip->digital_modes & (1 << mode))))
- return -EINVAL;
-
- previous_mode = chip->digital_mode;
- err = dsp_set_digital_mode(chip, mode);
-
- /* If we successfully changed the digital mode from or to ADAT,
- * then make sure all output, input and monitor levels are
- * updated by the DSP comm object. */
- if (err >= 0 && previous_mode != mode &&
- (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) {
- spin_lock_irq(&chip->lock);
- for (o = 0; o < num_busses_out(chip); o++)
- for (i = 0; i < num_busses_in(chip); i++)
- set_monitor_gain(chip, o, i,
- chip->monitor_gain[o][i]);
-
-#ifdef ECHOCARD_HAS_INPUT_GAIN
- for (i = 0; i < num_busses_in(chip); i++)
- set_input_gain(chip, i, chip->input_gain[i]);
- update_input_line_level(chip);
-#endif
-
- for (o = 0; o < num_busses_out(chip); o++)
- set_output_gain(chip, o, chip->output_gain[o]);
- update_output_line_level(chip);
- spin_unlock_irq(&chip->lock);
- }
-
- return err;
-}
-
-
-
-static u32 set_spdif_bits(struct echoaudio *chip, u32 control_reg, u32 rate)
-{
- control_reg &= E3G_SPDIF_FORMAT_CLEAR_MASK;
-
- switch (rate) {
- case 32000 :
- control_reg |= E3G_SPDIF_SAMPLE_RATE0 | E3G_SPDIF_SAMPLE_RATE1;
- break;
- case 44100 :
- if (chip->professional_spdif)
- control_reg |= E3G_SPDIF_SAMPLE_RATE0;
- break;
- case 48000 :
- control_reg |= E3G_SPDIF_SAMPLE_RATE1;
- break;
- }
-
- if (chip->professional_spdif)
- control_reg |= E3G_SPDIF_PRO_MODE;
-
- if (chip->non_audio_spdif)
- control_reg |= E3G_SPDIF_NOT_AUDIO;
-
- control_reg |= E3G_SPDIF_24_BIT | E3G_SPDIF_TWO_CHANNEL |
- E3G_SPDIF_COPY_PERMIT;
-
- return control_reg;
-}
-
-
-
-/* Set the S/PDIF output format */
-static int set_professional_spdif(struct echoaudio *chip, char prof)
-{
- u32 control_reg;
-
- control_reg = le32_to_cpu(chip->comm_page->control_register);
- chip->professional_spdif = prof;
- control_reg = set_spdif_bits(chip, control_reg, chip->sample_rate);
- return write_control_reg(chip, control_reg, get_frq_reg(chip), 0);
-}
-
-
-
-/* detect_input_clocks() returns a bitmask consisting of all the input clocks
-currently connected to the hardware; this changes as the user connects and
-disconnects clock inputs. You should use this information to determine which
-clocks the user is allowed to select. */
-static u32 detect_input_clocks(const struct echoaudio *chip)
-{
- u32 clocks_from_dsp, clock_bits;
-
- /* Map the DSP clock detect bits to the generic driver clock
- * detect bits */
- clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
-
- clock_bits = ECHO_CLOCK_BIT_INTERNAL;
-
- if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD)
- clock_bits |= ECHO_CLOCK_BIT_WORD;
-
- switch(chip->digital_mode) {
- case DIGITAL_MODE_SPDIF_RCA:
- case DIGITAL_MODE_SPDIF_OPTICAL:
- if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF)
- clock_bits |= ECHO_CLOCK_BIT_SPDIF;
- break;
- case DIGITAL_MODE_ADAT:
- if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_ADAT)
- clock_bits |= ECHO_CLOCK_BIT_ADAT;
- break;
- }
-
- return clock_bits;
-}
-
-
-
-static int load_asic(struct echoaudio *chip)
-{
- int box_type, err;
-
- if (chip->asic_loaded)
- return 0;
-
- /* Give the DSP a few milliseconds to settle down */
- mdelay(2);
-
- err = load_asic_generic(chip, DSP_FNC_LOAD_3G_ASIC, FW_3G_ASIC);
- if (err < 0)
- return err;
-
- chip->asic_code = FW_3G_ASIC;
-
- /* Now give the new ASIC some time to set up */
- msleep(1000);
- /* See if it worked */
- box_type = check_asic_status(chip);
-
- /* Set up the control register if the load succeeded -
- * 48 kHz, internal clock, S/PDIF RCA mode */
- if (box_type >= 0) {
- err = write_control_reg(chip, E3G_48KHZ,
- E3G_FREQ_REG_DEFAULT, TRUE);
- if (err < 0)
- return err;
- }
-
- return box_type;
-}
-
-
-
-static int set_sample_rate(struct echoaudio *chip, u32 rate)
-{
- u32 control_reg, clock, base_rate, frq_reg;
-
- /* Only set the clock for internal mode. */
- if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
- DE_ACT(("set_sample_rate: Cannot set sample rate - "
- "clock not set to CLK_CLOCKININTERNAL\n"));
- /* Save the rate anyhow */
- chip->comm_page->sample_rate = cpu_to_le32(rate);
- chip->sample_rate = rate;
- set_input_clock(chip, chip->input_clock);
- return 0;
- }
-
- if (snd_BUG_ON(rate >= 50000 &&
- chip->digital_mode == DIGITAL_MODE_ADAT))
- return -EINVAL;
-
- clock = 0;
- control_reg = le32_to_cpu(chip->comm_page->control_register);
- control_reg &= E3G_CLOCK_CLEAR_MASK;
-
- switch (rate) {
- case 96000:
- clock = E3G_96KHZ;
- break;
- case 88200:
- clock = E3G_88KHZ;
- break;
- case 48000:
- clock = E3G_48KHZ;
- break;
- case 44100:
- clock = E3G_44KHZ;
- break;
- case 32000:
- clock = E3G_32KHZ;
- break;
- default:
- clock = E3G_CONTINUOUS_CLOCK;
- if (rate > 50000)
- clock |= E3G_DOUBLE_SPEED_MODE;
- break;
- }
-
- control_reg |= clock;
- control_reg = set_spdif_bits(chip, control_reg, rate);
-
- base_rate = rate;
- if (base_rate > 50000)
- base_rate /= 2;
- if (base_rate < 32000)
- base_rate = 32000;
-
- frq_reg = E3G_MAGIC_NUMBER / base_rate - 2;
- if (frq_reg > E3G_FREQ_REG_MAX)
- frq_reg = E3G_FREQ_REG_MAX;
-
- chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */
- chip->sample_rate = rate;
- DE_ACT(("SetSampleRate: %d clock %x\n", rate, control_reg));
-
- /* Tell the DSP about it - DSP reads both control reg & freq reg */
- return write_control_reg(chip, control_reg, frq_reg, 0);
-}
-
-
-
-/* Set the sample clock source to internal, S/PDIF, ADAT */
-static int set_input_clock(struct echoaudio *chip, u16 clock)
-{
- u32 control_reg, clocks_from_dsp;
-
- DE_ACT(("set_input_clock:\n"));
-
- /* Mask off the clock select bits */
- control_reg = le32_to_cpu(chip->comm_page->control_register) &
- E3G_CLOCK_CLEAR_MASK;
- clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
-
- switch (clock) {
- case ECHO_CLOCK_INTERNAL:
- DE_ACT(("Set Echo3G clock to INTERNAL\n"));
- chip->input_clock = ECHO_CLOCK_INTERNAL;
- return set_sample_rate(chip, chip->sample_rate);
- case ECHO_CLOCK_SPDIF:
- if (chip->digital_mode == DIGITAL_MODE_ADAT)
- return -EAGAIN;
- DE_ACT(("Set Echo3G clock to SPDIF\n"));
- control_reg |= E3G_SPDIF_CLOCK;
- if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF96)
- control_reg |= E3G_DOUBLE_SPEED_MODE;
- else
- control_reg &= ~E3G_DOUBLE_SPEED_MODE;
- break;
- case ECHO_CLOCK_ADAT:
- if (chip->digital_mode != DIGITAL_MODE_ADAT)
- return -EAGAIN;
- DE_ACT(("Set Echo3G clock to ADAT\n"));
- control_reg |= E3G_ADAT_CLOCK;
- control_reg &= ~E3G_DOUBLE_SPEED_MODE;
- break;
- case ECHO_CLOCK_WORD:
- DE_ACT(("Set Echo3G clock to WORD\n"));
- control_reg |= E3G_WORD_CLOCK;
- if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD96)
- control_reg |= E3G_DOUBLE_SPEED_MODE;
- else
- control_reg &= ~E3G_DOUBLE_SPEED_MODE;
- break;
- default:
- DE_ACT(("Input clock 0x%x not supported for Echo3G\n", clock));
- return -EINVAL;
- }
-
- chip->input_clock = clock;
- return write_control_reg(chip, control_reg, get_frq_reg(chip), 1);
-}
-
-
-
-static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
-{
- u32 control_reg;
- int err, incompatible_clock;
-
- /* Set clock to "internal" if it's not compatible with the new mode */
- incompatible_clock = FALSE;
- switch (mode) {
- case DIGITAL_MODE_SPDIF_OPTICAL:
- case DIGITAL_MODE_SPDIF_RCA:
- if (chip->input_clock == ECHO_CLOCK_ADAT)
- incompatible_clock = TRUE;
- break;
- case DIGITAL_MODE_ADAT:
- if (chip->input_clock == ECHO_CLOCK_SPDIF)
- incompatible_clock = TRUE;
- break;
- default:
- DE_ACT(("Digital mode not supported: %d\n", mode));
- return -EINVAL;
- }
-
- spin_lock_irq(&chip->lock);
-
- if (incompatible_clock) {
- chip->sample_rate = 48000;
- set_input_clock(chip, ECHO_CLOCK_INTERNAL);
- }
-
- /* Clear the current digital mode */
- control_reg = le32_to_cpu(chip->comm_page->control_register);
- control_reg &= E3G_DIGITAL_MODE_CLEAR_MASK;
-
- /* Tweak the control reg */
- switch (mode) {
- case DIGITAL_MODE_SPDIF_OPTICAL:
- control_reg |= E3G_SPDIF_OPTICAL_MODE;
- break;
- case DIGITAL_MODE_SPDIF_RCA:
- /* E3G_SPDIF_OPTICAL_MODE bit cleared */
- break;
- case DIGITAL_MODE_ADAT:
- control_reg |= E3G_ADAT_MODE;
- control_reg &= ~E3G_DOUBLE_SPEED_MODE; /* @@ useless */
- break;
- }
-
- err = write_control_reg(chip, control_reg, get_frq_reg(chip), 1);
- spin_unlock_irq(&chip->lock);
- if (err < 0)
- return err;
- chip->digital_mode = mode;
-
- DE_ACT(("set_digital_mode(%d)\n", chip->digital_mode));
- return incompatible_clock;
-}
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_dsp.c
deleted file mode 100644
index d8c670c9..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_dsp.c
+++ /dev/null
@@ -1,1151 +0,0 @@
-/****************************************************************************
-
- Copyright Echo Digital Audio Corporation (c) 1998 - 2004
- All rights reserved
- www.echoaudio.com
-
- This file is part of Echo Digital Audio's generic driver library.
-
- Echo Digital Audio's generic driver library is free software;
- you can redistribute it and/or modify it under the terms of
- the GNU General Public License as published by the Free Software
- Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- *************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
-****************************************************************************/
-
-#if PAGE_SIZE < 4096
-#error PAGE_SIZE is < 4k
-#endif
-
-static int restore_dsp_rettings(struct echoaudio *chip);
-
-
-/* Some vector commands involve the DSP reading or writing data to and from the
-comm page; if you send one of these commands to the DSP, it will complete the
-command and then write a non-zero value to the Handshake field in the
-comm page. This function waits for the handshake to show up. */
-static int wait_handshake(struct echoaudio *chip)
-{
- int i;
-
- /* Wait up to 20ms for the handshake from the DSP */
- for (i = 0; i < HANDSHAKE_TIMEOUT; i++) {
- /* Look for the handshake value */
- barrier();
- if (chip->comm_page->handshake) {
- return 0;
- }
- udelay(1);
- }
-
- snd_printk(KERN_ERR "wait_handshake(): Timeout waiting for DSP\n");
- return -EBUSY;
-}
-
-
-
-/* Much of the interaction between the DSP and the driver is done via vector
-commands; send_vector writes a vector command to the DSP. Typically, this
-causes the DSP to read or write fields in the comm page.
-PCI posting is not required thanks to the handshake logic. */
-static int send_vector(struct echoaudio *chip, u32 command)
-{
- int i;
-
- wmb(); /* Flush all pending writes before sending the command */
-
- /* Wait up to 100ms for the "vector busy" bit to be off */
- for (i = 0; i < VECTOR_BUSY_TIMEOUT; i++) {
- if (!(get_dsp_register(chip, CHI32_VECTOR_REG) &
- CHI32_VECTOR_BUSY)) {
- set_dsp_register(chip, CHI32_VECTOR_REG, command);
- /*if (i) DE_ACT(("send_vector time: %d\n", i));*/
- return 0;
- }
- udelay(1);
- }
-
- DE_ACT((KERN_ERR "timeout on send_vector\n"));
- return -EBUSY;
-}
-
-
-
-/* write_dsp writes a 32-bit value to the DSP; this is used almost
-exclusively for loading the DSP. */
-static int write_dsp(struct echoaudio *chip, u32 data)
-{
- u32 status, i;
-
- for (i = 0; i < 10000000; i++) { /* timeout = 10s */
- status = get_dsp_register(chip, CHI32_STATUS_REG);
- if ((status & CHI32_STATUS_HOST_WRITE_EMPTY) != 0) {
- set_dsp_register(chip, CHI32_DATA_REG, data);
- wmb(); /* write it immediately */
- return 0;
- }
- udelay(1);
- cond_resched();
- }
-
- chip->bad_board = TRUE; /* Set TRUE until DSP re-loaded */
- DE_ACT((KERN_ERR "write_dsp: Set bad_board to TRUE\n"));
- return -EIO;
-}
-
-
-
-/* read_dsp reads a 32-bit value from the DSP; this is used almost
-exclusively for loading the DSP and checking the status of the ASIC. */
-static int read_dsp(struct echoaudio *chip, u32 *data)
-{
- u32 status, i;
-
- for (i = 0; i < READ_DSP_TIMEOUT; i++) {
- status = get_dsp_register(chip, CHI32_STATUS_REG);
- if ((status & CHI32_STATUS_HOST_READ_FULL) != 0) {
- *data = get_dsp_register(chip, CHI32_DATA_REG);
- return 0;
- }
- udelay(1);
- cond_resched();
- }
-
- chip->bad_board = TRUE; /* Set TRUE until DSP re-loaded */
- DE_INIT((KERN_ERR "read_dsp: Set bad_board to TRUE\n"));
- return -EIO;
-}
-
-
-
-/****************************************************************************
- Firmware loading functions
- ****************************************************************************/
-
-/* This function is used to read back the serial number from the DSP;
-this is triggered by the SET_COMMPAGE_ADDR command.
-Only some early Echogals products have serial numbers in the ROM;
-the serial number is not used, but you still need to do this as
-part of the DSP load process. */
-static int read_sn(struct echoaudio *chip)
-{
- int i;
- u32 sn[6];
-
- for (i = 0; i < 5; i++) {
- if (read_dsp(chip, &sn[i])) {
- snd_printk(KERN_ERR "Failed to read serial number\n");
- return -EIO;
- }
- }
- DE_INIT(("Read serial number %08x %08x %08x %08x %08x\n",
- sn[0], sn[1], sn[2], sn[3], sn[4]));
- return 0;
-}
-
-
-
-#ifndef ECHOCARD_HAS_ASIC
-/* This card has no ASIC, just return ok */
-static inline int check_asic_status(struct echoaudio *chip)
-{
- chip->asic_loaded = TRUE;
- return 0;
-}
-
-#endif /* !ECHOCARD_HAS_ASIC */
-
-
-
-#ifdef ECHOCARD_HAS_ASIC
-
-/* Load ASIC code - done after the DSP is loaded */
-static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic)
-{
- const struct firmware *fw;
- int err;
- u32 i, size;
- u8 *code;
-
- err = get_firmware(&fw, chip, asic);
- if (err < 0) {
- snd_printk(KERN_WARNING "Firmware not found !\n");
- return err;
- }
-
- code = (u8 *)fw->data;
- size = fw->size;
-
- /* Send the "Here comes the ASIC" command */
- if (write_dsp(chip, cmd) < 0)
- goto la_error;
-
- /* Write length of ASIC file in bytes */
- if (write_dsp(chip, size) < 0)
- goto la_error;
-
- for (i = 0; i < size; i++) {
- if (write_dsp(chip, code[i]) < 0)
- goto la_error;
- }
-
- DE_INIT(("ASIC loaded\n"));
- free_firmware(fw);
- return 0;
-
-la_error:
- DE_INIT(("failed on write_dsp\n"));
- free_firmware(fw);
- return -EIO;
-}
-
-#endif /* ECHOCARD_HAS_ASIC */
-
-
-
-#ifdef DSP_56361
-
-/* Install the resident loader for 56361 DSPs; The resident loader is on
-the EPROM on the board for 56301 DSP. The resident loader is a tiny little
-program that is used to load the real DSP code. */
-static int install_resident_loader(struct echoaudio *chip)
-{
- u32 address;
- int index, words, i;
- u16 *code;
- u32 status;
- const struct firmware *fw;
-
- /* 56361 cards only! This check is required by the old 56301-based
- Mona and Gina24 */
- if (chip->device_id != DEVICE_ID_56361)
- return 0;
-
- /* Look to see if the resident loader is present. If the resident
- loader is already installed, host flag 5 will be on. */
- status = get_dsp_register(chip, CHI32_STATUS_REG);
- if (status & CHI32_STATUS_REG_HF5) {
- DE_INIT(("Resident loader already installed; status is 0x%x\n",
- status));
- return 0;
- }
-
- i = get_firmware(&fw, chip, FW_361_LOADER);
- if (i < 0) {
- snd_printk(KERN_WARNING "Firmware not found !\n");
- return i;
- }
-
- /* The DSP code is an array of 16 bit words. The array is divided up
- into sections. The first word of each section is the size in words,
- followed by the section type.
- Since DSP addresses and data are 24 bits wide, they each take up two
- 16 bit words in the array.
- This is a lot like the other loader loop, but it's not a loop, you
- don't write the memory type, and you don't write a zero at the end. */
-
- /* Set DSP format bits for 24 bit mode */
- set_dsp_register(chip, CHI32_CONTROL_REG,
- get_dsp_register(chip, CHI32_CONTROL_REG) | 0x900);
-
- code = (u16 *)fw->data;
-
- /* Skip the header section; the first word in the array is the size
- of the first section, so the first real section of code is pointed
- to by Code[0]. */
- index = code[0];
-
- /* Skip the section size, LRS block type, and DSP memory type */
- index += 3;
-
- /* Get the number of DSP words to write */
- words = code[index++];
-
- /* Get the DSP address for this block; 24 bits, so build from two words */
- address = ((u32)code[index] << 16) + code[index + 1];
- index += 2;
-
- /* Write the count to the DSP */
- if (write_dsp(chip, words)) {
- DE_INIT(("install_resident_loader: Failed to write word count!\n"));
- goto irl_error;
- }
- /* Write the DSP address */
- if (write_dsp(chip, address)) {
- DE_INIT(("install_resident_loader: Failed to write DSP address!\n"));
- goto irl_error;
- }
- /* Write out this block of code to the DSP */
- for (i = 0; i < words; i++) {
- u32 data;
-
- data = ((u32)code[index] << 16) + code[index + 1];
- if (write_dsp(chip, data)) {
- DE_INIT(("install_resident_loader: Failed to write DSP code\n"));
- goto irl_error;
- }
- index += 2;
- }
-
- /* Wait for flag 5 to come up */
- for (i = 0; i < 200; i++) { /* Timeout is 50us * 200 = 10ms */
- udelay(50);
- status = get_dsp_register(chip, CHI32_STATUS_REG);
- if (status & CHI32_STATUS_REG_HF5)
- break;
- }
-
- if (i == 200) {
- DE_INIT(("Resident loader failed to set HF5\n"));
- goto irl_error;
- }
-
- DE_INIT(("Resident loader successfully installed\n"));
- free_firmware(fw);
- return 0;
-
-irl_error:
- free_firmware(fw);
- return -EIO;
-}
-
-#endif /* DSP_56361 */
-
-
-static int load_dsp(struct echoaudio *chip, u16 *code)
-{
- u32 address, data;
- int index, words, i;
-
- if (chip->dsp_code == code) {
- DE_INIT(("DSP is already loaded!\n"));
- return 0;
- }
- chip->bad_board = TRUE; /* Set TRUE until DSP loaded */
- chip->dsp_code = NULL; /* Current DSP code not loaded */
- chip->asic_loaded = FALSE; /* Loading the DSP code will reset the ASIC */
-
- DE_INIT(("load_dsp: Set bad_board to TRUE\n"));
-
- /* If this board requires a resident loader, install it. */
-#ifdef DSP_56361
- if ((i = install_resident_loader(chip)) < 0)
- return i;
-#endif
-
- /* Send software reset command */
- if (send_vector(chip, DSP_VC_RESET) < 0) {
- DE_INIT(("LoadDsp: send_vector DSP_VC_RESET failed, Critical Failure\n"));
- return -EIO;
- }
- /* Delay 10us */
- udelay(10);
-
- /* Wait 10ms for HF3 to indicate that software reset is complete */
- for (i = 0; i < 1000; i++) { /* Timeout is 10us * 1000 = 10ms */
- if (get_dsp_register(chip, CHI32_STATUS_REG) &
- CHI32_STATUS_REG_HF3)
- break;
- udelay(10);
- }
-
- if (i == 1000) {
- DE_INIT(("load_dsp: Timeout waiting for CHI32_STATUS_REG_HF3\n"));
- return -EIO;
- }
-
- /* Set DSP format bits for 24 bit mode now that soft reset is done */
- set_dsp_register(chip, CHI32_CONTROL_REG,
- get_dsp_register(chip, CHI32_CONTROL_REG) | 0x900);
-
- /* Main loader loop */
-
- index = code[0];
- for (;;) {
- int block_type, mem_type;
-
- /* Total Block Size */
- index++;
-
- /* Block Type */
- block_type = code[index];
- if (block_type == 4) /* We're finished */
- break;
-
- index++;
-
- /* Memory Type P=0,X=1,Y=2 */
- mem_type = code[index++];
-
- /* Block Code Size */
- words = code[index++];
- if (words == 0) /* We're finished */
- break;
-
- /* Start Address */
- address = ((u32)code[index] << 16) + code[index + 1];
- index += 2;
-
- if (write_dsp(chip, words) < 0) {
- DE_INIT(("load_dsp: failed to write number of DSP words\n"));
- return -EIO;
- }
- if (write_dsp(chip, address) < 0) {
- DE_INIT(("load_dsp: failed to write DSP address\n"));
- return -EIO;
- }
- if (write_dsp(chip, mem_type) < 0) {
- DE_INIT(("load_dsp: failed to write DSP memory type\n"));
- return -EIO;
- }
- /* Code */
- for (i = 0; i < words; i++, index+=2) {
- data = ((u32)code[index] << 16) + code[index + 1];
- if (write_dsp(chip, data) < 0) {
- DE_INIT(("load_dsp: failed to write DSP data\n"));
- return -EIO;
- }
- }
- }
-
- if (write_dsp(chip, 0) < 0) { /* We're done!!! */
- DE_INIT(("load_dsp: Failed to write final zero\n"));
- return -EIO;
- }
- udelay(10);
-
- for (i = 0; i < 5000; i++) { /* Timeout is 100us * 5000 = 500ms */
- /* Wait for flag 4 - indicates that the DSP loaded OK */
- if (get_dsp_register(chip, CHI32_STATUS_REG) &
- CHI32_STATUS_REG_HF4) {
- set_dsp_register(chip, CHI32_CONTROL_REG,
- get_dsp_register(chip, CHI32_CONTROL_REG) & ~0x1b00);
-
- if (write_dsp(chip, DSP_FNC_SET_COMMPAGE_ADDR) < 0) {
- DE_INIT(("load_dsp: Failed to write DSP_FNC_SET_COMMPAGE_ADDR\n"));
- return -EIO;
- }
-
- if (write_dsp(chip, chip->comm_page_phys) < 0) {
- DE_INIT(("load_dsp: Failed to write comm page address\n"));
- return -EIO;
- }
-
- /* Get the serial number via slave mode.
- This is triggered by the SET_COMMPAGE_ADDR command.
- We don't actually use the serial number but we have to
- get it as part of the DSP init voodoo. */
- if (read_sn(chip) < 0) {
- DE_INIT(("load_dsp: Failed to read serial number\n"));
- return -EIO;
- }
-
- chip->dsp_code = code; /* Show which DSP code loaded */
- chip->bad_board = FALSE; /* DSP OK */
- DE_INIT(("load_dsp: OK!\n"));
- return 0;
- }
- udelay(100);
- }
-
- DE_INIT(("load_dsp: DSP load timed out waiting for HF4\n"));
- return -EIO;
-}
-
-
-
-/* load_firmware takes care of loading the DSP and any ASIC code. */
-static int load_firmware(struct echoaudio *chip)
-{
- const struct firmware *fw;
- int box_type, err;
-
- if (snd_BUG_ON(!chip->comm_page))
- return -EPERM;
-
- /* See if the ASIC is present and working - only if the DSP is already loaded */
- if (chip->dsp_code) {
- if ((box_type = check_asic_status(chip)) >= 0)
- return box_type;
- /* ASIC check failed; force the DSP to reload */
- chip->dsp_code = NULL;
- }
-
- err = get_firmware(&fw, chip, chip->dsp_code_to_load);
- if (err < 0)
- return err;
- err = load_dsp(chip, (u16 *)fw->data);
- free_firmware(fw);
- if (err < 0)
- return err;
-
- if ((box_type = load_asic(chip)) < 0)
- return box_type; /* error */
-
- return box_type;
-}
-
-
-
-/****************************************************************************
- Mixer functions
- ****************************************************************************/
-
-#if defined(ECHOCARD_HAS_INPUT_NOMINAL_LEVEL) || \
- defined(ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL)
-
-/* Set the nominal level for an input or output bus (true = -10dBV, false = +4dBu) */
-static int set_nominal_level(struct echoaudio *chip, u16 index, char consumer)
-{
- if (snd_BUG_ON(index >= num_busses_out(chip) + num_busses_in(chip)))
- return -EINVAL;
-
- /* Wait for the handshake (OK even if ASIC is not loaded) */
- if (wait_handshake(chip))
- return -EIO;
-
- chip->nominal_level[index] = consumer;
-
- if (consumer)
- chip->comm_page->nominal_level_mask |= cpu_to_le32(1 << index);
- else
- chip->comm_page->nominal_level_mask &= ~cpu_to_le32(1 << index);
-
- return 0;
-}
-
-#endif /* ECHOCARD_HAS_*_NOMINAL_LEVEL */
-
-
-
-/* Set the gain for a single physical output channel (dB). */
-static int set_output_gain(struct echoaudio *chip, u16 channel, s8 gain)
-{
- if (snd_BUG_ON(channel >= num_busses_out(chip)))
- return -EINVAL;
-
- if (wait_handshake(chip))
- return -EIO;
-
- /* Save the new value */
- chip->output_gain[channel] = gain;
- chip->comm_page->line_out_level[channel] = gain;
- return 0;
-}
-
-
-
-#ifdef ECHOCARD_HAS_MONITOR
-/* Set the monitor level from an input bus to an output bus. */
-static int set_monitor_gain(struct echoaudio *chip, u16 output, u16 input,
- s8 gain)
-{
- if (snd_BUG_ON(output >= num_busses_out(chip) ||
- input >= num_busses_in(chip)))
- return -EINVAL;
-
- if (wait_handshake(chip))
- return -EIO;
-
- chip->monitor_gain[output][input] = gain;
- chip->comm_page->monitors[monitor_index(chip, output, input)] = gain;
- return 0;
-}
-#endif /* ECHOCARD_HAS_MONITOR */
-
-
-/* Tell the DSP to read and update output, nominal & monitor levels in comm page. */
-static int update_output_line_level(struct echoaudio *chip)
-{
- if (wait_handshake(chip))
- return -EIO;
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_UPDATE_OUTVOL);
-}
-
-
-
-/* Tell the DSP to read and update input levels in comm page */
-static int update_input_line_level(struct echoaudio *chip)
-{
- if (wait_handshake(chip))
- return -EIO;
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_UPDATE_INGAIN);
-}
-
-
-
-/* set_meters_on turns the meters on or off. If meters are turned on, the DSP
-will write the meter and clock detect values to the comm page at about 30Hz */
-static void set_meters_on(struct echoaudio *chip, char on)
-{
- if (on && !chip->meters_enabled) {
- send_vector(chip, DSP_VC_METERS_ON);
- chip->meters_enabled = 1;
- } else if (!on && chip->meters_enabled) {
- send_vector(chip, DSP_VC_METERS_OFF);
- chip->meters_enabled = 0;
- memset((s8 *)chip->comm_page->vu_meter, ECHOGAIN_MUTED,
- DSP_MAXPIPES);
- memset((s8 *)chip->comm_page->peak_meter, ECHOGAIN_MUTED,
- DSP_MAXPIPES);
- }
-}
-
-
-
-/* Fill out an the given array using the current values in the comm page.
-Meters are written in the comm page by the DSP in this order:
- Output busses
- Input busses
- Output pipes (vmixer cards only)
-
-This function assumes there are no more than 16 in/out busses or pipes
-Meters is an array [3][16][2] of long. */
-static void get_audio_meters(struct echoaudio *chip, long *meters)
-{
- int i, m, n;
-
- m = 0;
- n = 0;
- for (i = 0; i < num_busses_out(chip); i++, m++) {
- meters[n++] = chip->comm_page->vu_meter[m];
- meters[n++] = chip->comm_page->peak_meter[m];
- }
- for (; n < 32; n++)
- meters[n] = 0;
-
-#ifdef ECHOCARD_ECHO3G
- m = E3G_MAX_OUTPUTS; /* Skip unused meters */
-#endif
-
- for (i = 0; i < num_busses_in(chip); i++, m++) {
- meters[n++] = chip->comm_page->vu_meter[m];
- meters[n++] = chip->comm_page->peak_meter[m];
- }
- for (; n < 64; n++)
- meters[n] = 0;
-
-#ifdef ECHOCARD_HAS_VMIXER
- for (i = 0; i < num_pipes_out(chip); i++, m++) {
- meters[n++] = chip->comm_page->vu_meter[m];
- meters[n++] = chip->comm_page->peak_meter[m];
- }
-#endif
- for (; n < 96; n++)
- meters[n] = 0;
-}
-
-
-
-static int restore_dsp_rettings(struct echoaudio *chip)
-{
- int i, o, err;
- DE_INIT(("restore_dsp_settings\n"));
-
- if ((err = check_asic_status(chip)) < 0)
- return err;
-
- /* Gina20/Darla20 only. Should be harmless for other cards. */
- chip->comm_page->gd_clock_state = GD_CLOCK_UNDEF;
- chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_UNDEF;
- chip->comm_page->handshake = 0xffffffff;
-
- /* Restore output busses */
- for (i = 0; i < num_busses_out(chip); i++) {
- err = set_output_gain(chip, i, chip->output_gain[i]);
- if (err < 0)
- return err;
- }
-
-#ifdef ECHOCARD_HAS_VMIXER
- for (i = 0; i < num_pipes_out(chip); i++)
- for (o = 0; o < num_busses_out(chip); o++) {
- err = set_vmixer_gain(chip, o, i,
- chip->vmixer_gain[o][i]);
- if (err < 0)
- return err;
- }
- if (update_vmixer_level(chip) < 0)
- return -EIO;
-#endif /* ECHOCARD_HAS_VMIXER */
-
-#ifdef ECHOCARD_HAS_MONITOR
- for (o = 0; o < num_busses_out(chip); o++)
- for (i = 0; i < num_busses_in(chip); i++) {
- err = set_monitor_gain(chip, o, i,
- chip->monitor_gain[o][i]);
- if (err < 0)
- return err;
- }
-#endif /* ECHOCARD_HAS_MONITOR */
-
-#ifdef ECHOCARD_HAS_INPUT_GAIN
- for (i = 0; i < num_busses_in(chip); i++) {
- err = set_input_gain(chip, i, chip->input_gain[i]);
- if (err < 0)
- return err;
- }
-#endif /* ECHOCARD_HAS_INPUT_GAIN */
-
- err = update_output_line_level(chip);
- if (err < 0)
- return err;
-
- err = update_input_line_level(chip);
- if (err < 0)
- return err;
-
- err = set_sample_rate(chip, chip->sample_rate);
- if (err < 0)
- return err;
-
- if (chip->meters_enabled) {
- err = send_vector(chip, DSP_VC_METERS_ON);
- if (err < 0)
- return err;
- }
-
-#ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH
- if (set_digital_mode(chip, chip->digital_mode) < 0)
- return -EIO;
-#endif
-
-#ifdef ECHOCARD_HAS_DIGITAL_IO
- if (set_professional_spdif(chip, chip->professional_spdif) < 0)
- return -EIO;
-#endif
-
-#ifdef ECHOCARD_HAS_PHANTOM_POWER
- if (set_phantom_power(chip, chip->phantom_power) < 0)
- return -EIO;
-#endif
-
-#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK
- /* set_input_clock() also restores automute setting */
- if (set_input_clock(chip, chip->input_clock) < 0)
- return -EIO;
-#endif
-
-#ifdef ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH
- if (set_output_clock(chip, chip->output_clock) < 0)
- return -EIO;
-#endif
-
- if (wait_handshake(chip) < 0)
- return -EIO;
- clear_handshake(chip);
- if (send_vector(chip, DSP_VC_UPDATE_FLAGS) < 0)
- return -EIO;
-
- DE_INIT(("restore_dsp_rettings done\n"));
- return 0;
-}
-
-
-
-/****************************************************************************
- Transport functions
- ****************************************************************************/
-
-/* set_audio_format() sets the format of the audio data in host memory for
-this pipe. Note that _MS_ (mono-to-stereo) playback modes are not used by ALSA
-but they are here because they are just mono while capturing */
-static void set_audio_format(struct echoaudio *chip, u16 pipe_index,
- const struct audioformat *format)
-{
- u16 dsp_format;
-
- dsp_format = DSP_AUDIOFORM_SS_16LE;
-
- /* Look for super-interleave (no big-endian and 8 bits) */
- if (format->interleave > 2) {
- switch (format->bits_per_sample) {
- case 16:
- dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_16LE;
- break;
- case 24:
- dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_24LE;
- break;
- case 32:
- dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_32LE;
- break;
- }
- dsp_format |= format->interleave;
- } else if (format->data_are_bigendian) {
- /* For big-endian data, only 32 bit samples are supported */
- switch (format->interleave) {
- case 1:
- dsp_format = DSP_AUDIOFORM_MM_32BE;
- break;
-#ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32
- case 2:
- dsp_format = DSP_AUDIOFORM_SS_32BE;
- break;
-#endif
- }
- } else if (format->interleave == 1 &&
- format->bits_per_sample == 32 && !format->mono_to_stereo) {
- /* 32 bit little-endian mono->mono case */
- dsp_format = DSP_AUDIOFORM_MM_32LE;
- } else {
- /* Handle the other little-endian formats */
- switch (format->bits_per_sample) {
- case 8:
- if (format->interleave == 2)
- dsp_format = DSP_AUDIOFORM_SS_8;
- else
- dsp_format = DSP_AUDIOFORM_MS_8;
- break;
- default:
- case 16:
- if (format->interleave == 2)
- dsp_format = DSP_AUDIOFORM_SS_16LE;
- else
- dsp_format = DSP_AUDIOFORM_MS_16LE;
- break;
- case 24:
- if (format->interleave == 2)
- dsp_format = DSP_AUDIOFORM_SS_24LE;
- else
- dsp_format = DSP_AUDIOFORM_MS_24LE;
- break;
- case 32:
- if (format->interleave == 2)
- dsp_format = DSP_AUDIOFORM_SS_32LE;
- else
- dsp_format = DSP_AUDIOFORM_MS_32LE;
- break;
- }
- }
- DE_ACT(("set_audio_format[%d] = %x\n", pipe_index, dsp_format));
- chip->comm_page->audio_format[pipe_index] = cpu_to_le16(dsp_format);
-}
-
-
-
-/* start_transport starts transport for a set of pipes.
-The bits 1 in channel_mask specify what pipes to start. Only the bit of the
-first channel must be set, regardless its interleave.
-Same thing for pause_ and stop_ -trasport below. */
-static int start_transport(struct echoaudio *chip, u32 channel_mask,
- u32 cyclic_mask)
-{
- DE_ACT(("start_transport %x\n", channel_mask));
-
- if (wait_handshake(chip))
- return -EIO;
-
- chip->comm_page->cmd_start |= cpu_to_le32(channel_mask);
-
- if (chip->comm_page->cmd_start) {
- clear_handshake(chip);
- send_vector(chip, DSP_VC_START_TRANSFER);
- if (wait_handshake(chip))
- return -EIO;
- /* Keep track of which pipes are transporting */
- chip->active_mask |= channel_mask;
- chip->comm_page->cmd_start = 0;
- return 0;
- }
-
- DE_ACT(("start_transport: No pipes to start!\n"));
- return -EINVAL;
-}
-
-
-
-static int pause_transport(struct echoaudio *chip, u32 channel_mask)
-{
- DE_ACT(("pause_transport %x\n", channel_mask));
-
- if (wait_handshake(chip))
- return -EIO;
-
- chip->comm_page->cmd_stop |= cpu_to_le32(channel_mask);
- chip->comm_page->cmd_reset = 0;
- if (chip->comm_page->cmd_stop) {
- clear_handshake(chip);
- send_vector(chip, DSP_VC_STOP_TRANSFER);
- if (wait_handshake(chip))
- return -EIO;
- /* Keep track of which pipes are transporting */
- chip->active_mask &= ~channel_mask;
- chip->comm_page->cmd_stop = 0;
- chip->comm_page->cmd_reset = 0;
- return 0;
- }
-
- DE_ACT(("pause_transport: No pipes to stop!\n"));
- return 0;
-}
-
-
-
-static int stop_transport(struct echoaudio *chip, u32 channel_mask)
-{
- DE_ACT(("stop_transport %x\n", channel_mask));
-
- if (wait_handshake(chip))
- return -EIO;
-
- chip->comm_page->cmd_stop |= cpu_to_le32(channel_mask);
- chip->comm_page->cmd_reset |= cpu_to_le32(channel_mask);
- if (chip->comm_page->cmd_reset) {
- clear_handshake(chip);
- send_vector(chip, DSP_VC_STOP_TRANSFER);
- if (wait_handshake(chip))
- return -EIO;
- /* Keep track of which pipes are transporting */
- chip->active_mask &= ~channel_mask;
- chip->comm_page->cmd_stop = 0;
- chip->comm_page->cmd_reset = 0;
- return 0;
- }
-
- DE_ACT(("stop_transport: No pipes to stop!\n"));
- return 0;
-}
-
-
-
-static inline int is_pipe_allocated(struct echoaudio *chip, u16 pipe_index)
-{
- return (chip->pipe_alloc_mask & (1 << pipe_index));
-}
-
-
-
-/* Stops everything and turns off the DSP. All pipes should be already
-stopped and unallocated. */
-static int rest_in_peace(struct echoaudio *chip)
-{
- DE_ACT(("rest_in_peace() open=%x\n", chip->pipe_alloc_mask));
-
- /* Stops all active pipes (just to be sure) */
- stop_transport(chip, chip->active_mask);
-
- set_meters_on(chip, FALSE);
-
-#ifdef ECHOCARD_HAS_MIDI
- enable_midi_input(chip, FALSE);
-#endif
-
- /* Go to sleep */
- if (chip->dsp_code) {
- /* Make load_firmware do a complete reload */
- chip->dsp_code = NULL;
- /* Put the DSP to sleep */
- return send_vector(chip, DSP_VC_GO_COMATOSE);
- }
- return 0;
-}
-
-
-
-/* Fills the comm page with default values */
-static int init_dsp_comm_page(struct echoaudio *chip)
-{
- /* Check if the compiler added extra padding inside the structure */
- if (offsetof(struct comm_page, midi_output) != 0xbe0) {
- DE_INIT(("init_dsp_comm_page() - Invalid struct comm_page structure\n"));
- return -EPERM;
- }
-
- /* Init all the basic stuff */
- chip->card_name = ECHOCARD_NAME;
- chip->bad_board = TRUE; /* Set TRUE until DSP loaded */
- chip->dsp_code = NULL; /* Current DSP code not loaded */
- chip->asic_loaded = FALSE;
- memset(chip->comm_page, 0, sizeof(struct comm_page));
-
- /* Init the comm page */
- chip->comm_page->comm_size =
- cpu_to_le32(sizeof(struct comm_page));
- chip->comm_page->handshake = 0xffffffff;
- chip->comm_page->midi_out_free_count =
- cpu_to_le32(DSP_MIDI_OUT_FIFO_SIZE);
- chip->comm_page->sample_rate = cpu_to_le32(44100);
-
- /* Set line levels so we don't blast any inputs on startup */
- memset(chip->comm_page->monitors, ECHOGAIN_MUTED, MONITOR_ARRAY_SIZE);
- memset(chip->comm_page->vmixer, ECHOGAIN_MUTED, VMIXER_ARRAY_SIZE);
-
- return 0;
-}
-
-
-
-/* This function initializes the chip structure with default values, ie. all
- * muted and internal clock source. Then it copies the settings to the DSP.
- * This MUST be called after the DSP is up and running !
- */
-static int init_line_levels(struct echoaudio *chip)
-{
- DE_INIT(("init_line_levels\n"));
- memset(chip->output_gain, ECHOGAIN_MUTED, sizeof(chip->output_gain));
- memset(chip->input_gain, ECHOGAIN_MUTED, sizeof(chip->input_gain));
- memset(chip->monitor_gain, ECHOGAIN_MUTED, sizeof(chip->monitor_gain));
- memset(chip->vmixer_gain, ECHOGAIN_MUTED, sizeof(chip->vmixer_gain));
- chip->input_clock = ECHO_CLOCK_INTERNAL;
- chip->output_clock = ECHO_CLOCK_WORD;
- chip->sample_rate = 44100;
- return restore_dsp_rettings(chip);
-}
-
-
-
-/* This is low level part of the interrupt handler.
-It returns -1 if the IRQ is not ours, or N>=0 if it is, where N is the number
-of midi data in the input queue. */
-static int service_irq(struct echoaudio *chip)
-{
- int st;
-
- /* Read the DSP status register and see if this DSP generated this interrupt */
- if (get_dsp_register(chip, CHI32_STATUS_REG) & CHI32_STATUS_IRQ) {
- st = 0;
-#ifdef ECHOCARD_HAS_MIDI
- /* Get and parse midi data if present */
- if (chip->comm_page->midi_input[0]) /* The count is at index 0 */
- st = midi_service_irq(chip); /* Returns how many midi bytes we received */
-#endif
- /* Clear the hardware interrupt */
- chip->comm_page->midi_input[0] = 0;
- send_vector(chip, DSP_VC_ACK_INT);
- return st;
- }
- return -1;
-}
-
-
-
-
-/******************************************************************************
- Functions for opening and closing pipes
- ******************************************************************************/
-
-/* allocate_pipes is used to reserve audio pipes for your exclusive use.
-The call will fail if some pipes are already allocated. */
-static int allocate_pipes(struct echoaudio *chip, struct audiopipe *pipe,
- int pipe_index, int interleave)
-{
- int i;
- u32 channel_mask;
- char is_cyclic;
-
- DE_ACT(("allocate_pipes: ch=%d int=%d\n", pipe_index, interleave));
-
- if (chip->bad_board)
- return -EIO;
-
- is_cyclic = 1; /* This driver uses cyclic buffers only */
-
- for (channel_mask = i = 0; i < interleave; i++)
- channel_mask |= 1 << (pipe_index + i);
- if (chip->pipe_alloc_mask & channel_mask) {
- DE_ACT(("allocate_pipes: channel already open\n"));
- return -EAGAIN;
- }
-
- chip->comm_page->position[pipe_index] = 0;
- chip->pipe_alloc_mask |= channel_mask;
- if (is_cyclic)
- chip->pipe_cyclic_mask |= channel_mask;
- pipe->index = pipe_index;
- pipe->interleave = interleave;
- pipe->state = PIPE_STATE_STOPPED;
-
- /* The counter register is where the DSP writes the 32 bit DMA
- position for a pipe. The DSP is constantly updating this value as
- it moves data. The DMA counter is in units of bytes, not samples. */
- pipe->dma_counter = &chip->comm_page->position[pipe_index];
- *pipe->dma_counter = 0;
- DE_ACT(("allocate_pipes: ok\n"));
- return pipe_index;
-}
-
-
-
-static int free_pipes(struct echoaudio *chip, struct audiopipe *pipe)
-{
- u32 channel_mask;
- int i;
-
- DE_ACT(("free_pipes: Pipe %d\n", pipe->index));
- if (snd_BUG_ON(!is_pipe_allocated(chip, pipe->index)))
- return -EINVAL;
- if (snd_BUG_ON(pipe->state != PIPE_STATE_STOPPED))
- return -EINVAL;
-
- for (channel_mask = i = 0; i < pipe->interleave; i++)
- channel_mask |= 1 << (pipe->index + i);
-
- chip->pipe_alloc_mask &= ~channel_mask;
- chip->pipe_cyclic_mask &= ~channel_mask;
- return 0;
-}
-
-
-
-/******************************************************************************
- Functions for managing the scatter-gather list
-******************************************************************************/
-
-static int sglist_init(struct echoaudio *chip, struct audiopipe *pipe)
-{
- pipe->sglist_head = 0;
- memset(pipe->sgpage.area, 0, PAGE_SIZE);
- chip->comm_page->sglist_addr[pipe->index].addr =
- cpu_to_le32(pipe->sgpage.addr);
- return 0;
-}
-
-
-
-static int sglist_add_mapping(struct echoaudio *chip, struct audiopipe *pipe,
- dma_addr_t address, size_t length)
-{
- int head = pipe->sglist_head;
- struct sg_entry *list = (struct sg_entry *)pipe->sgpage.area;
-
- if (head < MAX_SGLIST_ENTRIES - 1) {
- list[head].addr = cpu_to_le32(address);
- list[head].size = cpu_to_le32(length);
- pipe->sglist_head++;
- } else {
- DE_ACT(("SGlist: too many fragments\n"));
- return -ENOMEM;
- }
- return 0;
-}
-
-
-
-static inline int sglist_add_irq(struct echoaudio *chip, struct audiopipe *pipe)
-{
- return sglist_add_mapping(chip, pipe, 0, 0);
-}
-
-
-
-static inline int sglist_wrap(struct echoaudio *chip, struct audiopipe *pipe)
-{
- return sglist_add_mapping(chip, pipe, pipe->sgpage.addr, 0);
-}
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_dsp.h b/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_dsp.h
deleted file mode 100644
index cb7d75a0..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_dsp.h
+++ /dev/null
@@ -1,698 +0,0 @@
-/****************************************************************************
-
- Copyright Echo Digital Audio Corporation (c) 1998 - 2004
- All rights reserved
- www.echoaudio.com
-
- This file is part of Echo Digital Audio's generic driver library.
-
- Echo Digital Audio's generic driver library is free software;
- you can redistribute it and/or modify it under the terms of
- the GNU General Public License as published by the Free Software
- Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- *************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
-****************************************************************************/
-
-#ifndef _ECHO_DSP_
-#define _ECHO_DSP_
-
-
-/**** Echogals: Darla20, Gina20, Layla20, and Darla24 ****/
-#if defined(ECHOGALS_FAMILY)
-
-#define NUM_ASIC_TESTS 5
-#define READ_DSP_TIMEOUT 1000000L /* one second */
-
-/**** Echo24: Gina24, Layla24, Mona, Mia, Mia-midi ****/
-#elif defined(ECHO24_FAMILY)
-
-#define DSP_56361 /* Some Echo24 cards use the 56361 DSP */
-#define READ_DSP_TIMEOUT 100000L /* .1 second */
-
-/**** 3G: Gina3G, Layla3G ****/
-#elif defined(ECHO3G_FAMILY)
-
-#define DSP_56361
-#define READ_DSP_TIMEOUT 100000L /* .1 second */
-#define MIN_MTC_1X_RATE 32000
-
-/**** Indigo: Indigo, Indigo IO, Indigo DJ ****/
-#elif defined(INDIGO_FAMILY)
-
-#define DSP_56361
-#define READ_DSP_TIMEOUT 100000L /* .1 second */
-
-#else
-
-#error No family is defined
-
-#endif
-
-
-
-/*
- *
- * Max inputs and outputs
- *
- */
-
-#define DSP_MAXAUDIOINPUTS 16 /* Max audio input channels */
-#define DSP_MAXAUDIOOUTPUTS 16 /* Max audio output channels */
-#define DSP_MAXPIPES 32 /* Max total pipes (input + output) */
-
-
-/*
- *
- * These are the offsets for the memory-mapped DSP registers; the DSP base
- * address is treated as the start of a u32 array.
- */
-
-#define CHI32_CONTROL_REG 4
-#define CHI32_STATUS_REG 5
-#define CHI32_VECTOR_REG 6
-#define CHI32_DATA_REG 7
-
-
-/*
- *
- * Interesting bits within the DSP registers
- *
- */
-
-#define CHI32_VECTOR_BUSY 0x00000001
-#define CHI32_STATUS_REG_HF3 0x00000008
-#define CHI32_STATUS_REG_HF4 0x00000010
-#define CHI32_STATUS_REG_HF5 0x00000020
-#define CHI32_STATUS_HOST_READ_FULL 0x00000004
-#define CHI32_STATUS_HOST_WRITE_EMPTY 0x00000002
-#define CHI32_STATUS_IRQ 0x00000040
-
-
-/*
- *
- * DSP commands sent via slave mode; these are sent to the DSP by write_dsp()
- *
- */
-
-#define DSP_FNC_SET_COMMPAGE_ADDR 0x02
-#define DSP_FNC_LOAD_LAYLA_ASIC 0xa0
-#define DSP_FNC_LOAD_GINA24_ASIC 0xa0
-#define DSP_FNC_LOAD_MONA_PCI_CARD_ASIC 0xa0
-#define DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC 0xa0
-#define DSP_FNC_LOAD_MONA_EXTERNAL_ASIC 0xa1
-#define DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC 0xa1
-#define DSP_FNC_LOAD_3G_ASIC 0xa0
-
-
-/*
- *
- * Defines to handle the MIDI input state engine; these are used to properly
- * extract MIDI time code bytes and their timestamps from the MIDI input stream.
- *
- */
-
-#define MIDI_IN_STATE_NORMAL 0
-#define MIDI_IN_STATE_TS_HIGH 1
-#define MIDI_IN_STATE_TS_LOW 2
-#define MIDI_IN_STATE_F1_DATA 3
-#define MIDI_IN_SKIP_DATA (-1)
-
-
-/*----------------------------------------------------------------------------
-
-Setting the sample rates on Layla24 is somewhat schizophrenic.
-
-For standard rates, it works exactly like Mona and Gina24. That is, for
-8, 11.025, 16, 22.05, 32, 44.1, 48, 88.2, and 96 kHz, you just set the
-appropriate bits in the control register and write the control register.
-
-In order to support MIDI time code sync (and possibly SMPTE LTC sync in
-the future), Layla24 also has "continuous sample rate mode". In this mode,
-Layla24 can generate any sample rate between 25 and 50 kHz inclusive, or
-50 to 100 kHz inclusive for double speed mode.
-
-To use continuous mode:
-
--Set the clock select bits in the control register to 0xe (see the #define
- below)
-
--Set double-speed mode if you want to use sample rates above 50 kHz
-
--Write the control register as you would normally
-
--Now, you need to set the frequency register. First, you need to determine the
- value for the frequency register. This is given by the following formula:
-
-frequency_reg = (LAYLA24_MAGIC_NUMBER / sample_rate) - 2
-
-Note the #define below for the magic number
-
--Wait for the DSP handshake
--Write the frequency_reg value to the .SampleRate field of the comm page
--Send the vector command SET_LAYLA24_FREQUENCY_REG (see vmonkey.h)
-
-Once you have set the control register up for continuous mode, you can just
-write the frequency register to change the sample rate. This could be
-used for MIDI time code sync. For MTC sync, the control register is set for
-continuous mode. The driver then just keeps writing the
-SET_LAYLA24_FREQUENCY_REG command.
-
------------------------------------------------------------------------------*/
-
-#define LAYLA24_MAGIC_NUMBER 677376000
-#define LAYLA24_CONTINUOUS_CLOCK 0x000e
-
-
-/*
- *
- * DSP vector commands
- *
- */
-
-#define DSP_VC_RESET 0x80ff
-
-#ifndef DSP_56361
-
-#define DSP_VC_ACK_INT 0x8073
-#define DSP_VC_SET_VMIXER_GAIN 0x0000 /* Not used, only for compile */
-#define DSP_VC_START_TRANSFER 0x0075 /* Handshke rqd. */
-#define DSP_VC_METERS_ON 0x0079
-#define DSP_VC_METERS_OFF 0x007b
-#define DSP_VC_UPDATE_OUTVOL 0x007d /* Handshke rqd. */
-#define DSP_VC_UPDATE_INGAIN 0x007f /* Handshke rqd. */
-#define DSP_VC_ADD_AUDIO_BUFFER 0x0081 /* Handshke rqd. */
-#define DSP_VC_TEST_ASIC 0x00eb
-#define DSP_VC_UPDATE_CLOCKS 0x00ef /* Handshke rqd. */
-#define DSP_VC_SET_LAYLA_SAMPLE_RATE 0x00f1 /* Handshke rqd. */
-#define DSP_VC_SET_GD_AUDIO_STATE 0x00f1 /* Handshke rqd. */
-#define DSP_VC_WRITE_CONTROL_REG 0x00f1 /* Handshke rqd. */
-#define DSP_VC_MIDI_WRITE 0x00f5 /* Handshke rqd. */
-#define DSP_VC_STOP_TRANSFER 0x00f7 /* Handshke rqd. */
-#define DSP_VC_UPDATE_FLAGS 0x00fd /* Handshke rqd. */
-#define DSP_VC_GO_COMATOSE 0x00f9
-
-#else /* !DSP_56361 */
-
-/* Vector commands for families that use either the 56301 or 56361 */
-#define DSP_VC_ACK_INT 0x80F5
-#define DSP_VC_SET_VMIXER_GAIN 0x00DB /* Handshke rqd. */
-#define DSP_VC_START_TRANSFER 0x00DD /* Handshke rqd. */
-#define DSP_VC_METERS_ON 0x00EF
-#define DSP_VC_METERS_OFF 0x00F1
-#define DSP_VC_UPDATE_OUTVOL 0x00E3 /* Handshke rqd. */
-#define DSP_VC_UPDATE_INGAIN 0x00E5 /* Handshke rqd. */
-#define DSP_VC_ADD_AUDIO_BUFFER 0x00E1 /* Handshke rqd. */
-#define DSP_VC_TEST_ASIC 0x00ED
-#define DSP_VC_UPDATE_CLOCKS 0x00E9 /* Handshke rqd. */
-#define DSP_VC_SET_LAYLA24_FREQUENCY_REG 0x00E9 /* Handshke rqd. */
-#define DSP_VC_SET_LAYLA_SAMPLE_RATE 0x00EB /* Handshke rqd. */
-#define DSP_VC_SET_GD_AUDIO_STATE 0x00EB /* Handshke rqd. */
-#define DSP_VC_WRITE_CONTROL_REG 0x00EB /* Handshke rqd. */
-#define DSP_VC_MIDI_WRITE 0x00E7 /* Handshke rqd. */
-#define DSP_VC_STOP_TRANSFER 0x00DF /* Handshke rqd. */
-#define DSP_VC_UPDATE_FLAGS 0x00FB /* Handshke rqd. */
-#define DSP_VC_GO_COMATOSE 0x00d9
-
-#endif /* !DSP_56361 */
-
-
-/*
- *
- * Timeouts
- *
- */
-
-#define HANDSHAKE_TIMEOUT 20000 /* send_vector command timeout (20ms) */
-#define VECTOR_BUSY_TIMEOUT 100000 /* 100ms */
-#define MIDI_OUT_DELAY_USEC 2000 /* How long to wait after MIDI fills up */
-
-
-/*
- *
- * Flags for .Flags field in the comm page
- *
- */
-
-#define DSP_FLAG_MIDI_INPUT 0x0001 /* Enable MIDI input */
-#define DSP_FLAG_SPDIF_NONAUDIO 0x0002 /* Sets the "non-audio" bit
- * in the S/PDIF out status
- * bits. Clear this flag for
- * audio data;
- * set it for AC3 or WMA or
- * some such */
-#define DSP_FLAG_PROFESSIONAL_SPDIF 0x0008 /* 1 Professional, 0 Consumer */
-
-
-/*
- *
- * Clock detect bits reported by the DSP for Gina20, Layla20, Darla24, and Mia
- *
- */
-
-#define GLDM_CLOCK_DETECT_BIT_WORD 0x0002
-#define GLDM_CLOCK_DETECT_BIT_SUPER 0x0004
-#define GLDM_CLOCK_DETECT_BIT_SPDIF 0x0008
-#define GLDM_CLOCK_DETECT_BIT_ESYNC 0x0010
-
-
-/*
- *
- * Clock detect bits reported by the DSP for Gina24, Mona, and Layla24
- *
- */
-
-#define GML_CLOCK_DETECT_BIT_WORD96 0x0002
-#define GML_CLOCK_DETECT_BIT_WORD48 0x0004
-#define GML_CLOCK_DETECT_BIT_SPDIF48 0x0008
-#define GML_CLOCK_DETECT_BIT_SPDIF96 0x0010
-#define GML_CLOCK_DETECT_BIT_WORD (GML_CLOCK_DETECT_BIT_WORD96 | GML_CLOCK_DETECT_BIT_WORD48)
-#define GML_CLOCK_DETECT_BIT_SPDIF (GML_CLOCK_DETECT_BIT_SPDIF48 | GML_CLOCK_DETECT_BIT_SPDIF96)
-#define GML_CLOCK_DETECT_BIT_ESYNC 0x0020
-#define GML_CLOCK_DETECT_BIT_ADAT 0x0040
-
-
-/*
- *
- * Layla clock numbers to send to DSP
- *
- */
-
-#define LAYLA20_CLOCK_INTERNAL 0
-#define LAYLA20_CLOCK_SPDIF 1
-#define LAYLA20_CLOCK_WORD 2
-#define LAYLA20_CLOCK_SUPER 3
-
-
-/*
- *
- * Gina/Darla clock states
- *
- */
-
-#define GD_CLOCK_NOCHANGE 0
-#define GD_CLOCK_44 1
-#define GD_CLOCK_48 2
-#define GD_CLOCK_SPDIFIN 3
-#define GD_CLOCK_UNDEF 0xff
-
-
-/*
- *
- * Gina/Darla S/PDIF status bits
- *
- */
-
-#define GD_SPDIF_STATUS_NOCHANGE 0
-#define GD_SPDIF_STATUS_44 1
-#define GD_SPDIF_STATUS_48 2
-#define GD_SPDIF_STATUS_UNDEF 0xff
-
-
-/*
- *
- * Layla20 output clocks
- *
- */
-
-#define LAYLA20_OUTPUT_CLOCK_SUPER 0
-#define LAYLA20_OUTPUT_CLOCK_WORD 1
-
-
-/****************************************************************************
-
- Magic constants for the Darla24 hardware
-
- ****************************************************************************/
-
-#define GD24_96000 0x0
-#define GD24_48000 0x1
-#define GD24_44100 0x2
-#define GD24_32000 0x3
-#define GD24_22050 0x4
-#define GD24_16000 0x5
-#define GD24_11025 0x6
-#define GD24_8000 0x7
-#define GD24_88200 0x8
-#define GD24_EXT_SYNC 0x9
-
-
-/*
- *
- * Return values from the DSP when ASIC is loaded
- *
- */
-
-#define ASIC_ALREADY_LOADED 0x1
-#define ASIC_NOT_LOADED 0x0
-
-
-/*
- *
- * DSP Audio formats
- *
- * These are the audio formats that the DSP can transfer
- * via input and output pipes. LE means little-endian,
- * BE means big-endian.
- *
- * DSP_AUDIOFORM_MS_8
- *
- * 8-bit mono unsigned samples. For playback,
- * mono data is duplicated out the left and right channels
- * of the output bus. The "MS" part of the name
- * means mono->stereo.
- *
- * DSP_AUDIOFORM_MS_16LE
- *
- * 16-bit signed little-endian mono samples. Playback works
- * like the previous code.
- *
- * DSP_AUDIOFORM_MS_24LE
- *
- * 24-bit signed little-endian mono samples. Data is packed
- * three bytes per sample; if you had two samples 0x112233 and 0x445566
- * they would be stored in memory like this: 33 22 11 66 55 44.
- *
- * DSP_AUDIOFORM_MS_32LE
- *
- * 24-bit signed little-endian mono samples in a 32-bit
- * container. In other words, each sample is a 32-bit signed
- * integer, where the actual audio data is left-justified
- * in the 32 bits and only the 24 most significant bits are valid.
- *
- * DSP_AUDIOFORM_SS_8
- * DSP_AUDIOFORM_SS_16LE
- * DSP_AUDIOFORM_SS_24LE
- * DSP_AUDIOFORM_SS_32LE
- *
- * Like the previous ones, except now with stereo interleaved
- * data. "SS" means stereo->stereo.
- *
- * DSP_AUDIOFORM_MM_32LE
- *
- * Similar to DSP_AUDIOFORM_MS_32LE, except that the mono
- * data is not duplicated out both the left and right outputs.
- * This mode is used by the ASIO driver. Here, "MM" means
- * mono->mono.
- *
- * DSP_AUDIOFORM_MM_32BE
- *
- * Just like DSP_AUDIOFORM_MM_32LE, but now the data is
- * in big-endian format.
- *
- */
-
-#define DSP_AUDIOFORM_MS_8 0 /* 8 bit mono */
-#define DSP_AUDIOFORM_MS_16LE 1 /* 16 bit mono */
-#define DSP_AUDIOFORM_MS_24LE 2 /* 24 bit mono */
-#define DSP_AUDIOFORM_MS_32LE 3 /* 32 bit mono */
-#define DSP_AUDIOFORM_SS_8 4 /* 8 bit stereo */
-#define DSP_AUDIOFORM_SS_16LE 5 /* 16 bit stereo */
-#define DSP_AUDIOFORM_SS_24LE 6 /* 24 bit stereo */
-#define DSP_AUDIOFORM_SS_32LE 7 /* 32 bit stereo */
-#define DSP_AUDIOFORM_MM_32LE 8 /* 32 bit mono->mono little-endian */
-#define DSP_AUDIOFORM_MM_32BE 9 /* 32 bit mono->mono big-endian */
-#define DSP_AUDIOFORM_SS_32BE 10 /* 32 bit stereo big endian */
-#define DSP_AUDIOFORM_INVALID 0xFF /* Invalid audio format */
-
-
-/*
- *
- * Super-interleave is defined as interleaving by 4 or more. Darla20 and Gina20
- * do not support super interleave.
- *
- * 16 bit, 24 bit, and 32 bit little endian samples are supported for super
- * interleave. The interleave factor must be even. 16 - way interleave is the
- * current maximum, so you can interleave by 4, 6, 8, 10, 12, 14, and 16.
- *
- * The actual format code is derived by taking the define below and or-ing with
- * the interleave factor. So, 32 bit interleave by 6 is 0x86 and
- * 16 bit interleave by 16 is (0x40 | 0x10) = 0x50.
- *
- */
-
-#define DSP_AUDIOFORM_SUPER_INTERLEAVE_16LE 0x40
-#define DSP_AUDIOFORM_SUPER_INTERLEAVE_24LE 0xc0
-#define DSP_AUDIOFORM_SUPER_INTERLEAVE_32LE 0x80
-
-
-/*
- *
- * Gina24, Mona, and Layla24 control register defines
- *
- */
-
-#define GML_CONVERTER_ENABLE 0x0010
-#define GML_SPDIF_PRO_MODE 0x0020 /* Professional S/PDIF == 1,
- consumer == 0 */
-#define GML_SPDIF_SAMPLE_RATE0 0x0040
-#define GML_SPDIF_SAMPLE_RATE1 0x0080
-#define GML_SPDIF_TWO_CHANNEL 0x0100 /* 1 == two channels,
- 0 == one channel */
-#define GML_SPDIF_NOT_AUDIO 0x0200
-#define GML_SPDIF_COPY_PERMIT 0x0400
-#define GML_SPDIF_24_BIT 0x0800 /* 1 == 24 bit, 0 == 20 bit */
-#define GML_ADAT_MODE 0x1000 /* 1 == ADAT mode, 0 == S/PDIF mode */
-#define GML_SPDIF_OPTICAL_MODE 0x2000 /* 1 == optical mode, 0 == RCA mode */
-#define GML_SPDIF_CDROM_MODE 0x3000 /* 1 == CDROM mode,
- * 0 == RCA or optical mode */
-#define GML_DOUBLE_SPEED_MODE 0x4000 /* 1 == double speed,
- 0 == single speed */
-
-#define GML_DIGITAL_IN_AUTO_MUTE 0x800000
-
-#define GML_96KHZ (0x0 | GML_DOUBLE_SPEED_MODE)
-#define GML_88KHZ (0x1 | GML_DOUBLE_SPEED_MODE)
-#define GML_48KHZ 0x2
-#define GML_44KHZ 0x3
-#define GML_32KHZ 0x4
-#define GML_22KHZ 0x5
-#define GML_16KHZ 0x6
-#define GML_11KHZ 0x7
-#define GML_8KHZ 0x8
-#define GML_SPDIF_CLOCK 0x9
-#define GML_ADAT_CLOCK 0xA
-#define GML_WORD_CLOCK 0xB
-#define GML_ESYNC_CLOCK 0xC
-#define GML_ESYNCx2_CLOCK 0xD
-
-#define GML_CLOCK_CLEAR_MASK 0xffffbff0
-#define GML_SPDIF_RATE_CLEAR_MASK (~(GML_SPDIF_SAMPLE_RATE0|GML_SPDIF_SAMPLE_RATE1))
-#define GML_DIGITAL_MODE_CLEAR_MASK 0xffffcfff
-#define GML_SPDIF_FORMAT_CLEAR_MASK 0xfffff01f
-
-
-/*
- *
- * Mia sample rate and clock setting constants
- *
- */
-
-#define MIA_32000 0x0040
-#define MIA_44100 0x0042
-#define MIA_48000 0x0041
-#define MIA_88200 0x0142
-#define MIA_96000 0x0141
-
-#define MIA_SPDIF 0x00000044
-#define MIA_SPDIF96 0x00000144
-
-#define MIA_MIDI_REV 1 /* Must be Mia rev 1 for MIDI support */
-
-
-/*
- *
- * 3G register bits
- *
- */
-
-#define E3G_CONVERTER_ENABLE 0x0010
-#define E3G_SPDIF_PRO_MODE 0x0020 /* Professional S/PDIF == 1,
- consumer == 0 */
-#define E3G_SPDIF_SAMPLE_RATE0 0x0040
-#define E3G_SPDIF_SAMPLE_RATE1 0x0080
-#define E3G_SPDIF_TWO_CHANNEL 0x0100 /* 1 == two channels,
- 0 == one channel */
-#define E3G_SPDIF_NOT_AUDIO 0x0200
-#define E3G_SPDIF_COPY_PERMIT 0x0400
-#define E3G_SPDIF_24_BIT 0x0800 /* 1 == 24 bit, 0 == 20 bit */
-#define E3G_DOUBLE_SPEED_MODE 0x4000 /* 1 == double speed,
- 0 == single speed */
-#define E3G_PHANTOM_POWER 0x8000 /* 1 == phantom power on,
- 0 == phantom power off */
-
-#define E3G_96KHZ (0x0 | E3G_DOUBLE_SPEED_MODE)
-#define E3G_88KHZ (0x1 | E3G_DOUBLE_SPEED_MODE)
-#define E3G_48KHZ 0x2
-#define E3G_44KHZ 0x3
-#define E3G_32KHZ 0x4
-#define E3G_22KHZ 0x5
-#define E3G_16KHZ 0x6
-#define E3G_11KHZ 0x7
-#define E3G_8KHZ 0x8
-#define E3G_SPDIF_CLOCK 0x9
-#define E3G_ADAT_CLOCK 0xA
-#define E3G_WORD_CLOCK 0xB
-#define E3G_CONTINUOUS_CLOCK 0xE
-
-#define E3G_ADAT_MODE 0x1000
-#define E3G_SPDIF_OPTICAL_MODE 0x2000
-
-#define E3G_CLOCK_CLEAR_MASK 0xbfffbff0
-#define E3G_DIGITAL_MODE_CLEAR_MASK 0xffffcfff
-#define E3G_SPDIF_FORMAT_CLEAR_MASK 0xfffff01f
-
-/* Clock detect bits reported by the DSP */
-#define E3G_CLOCK_DETECT_BIT_WORD96 0x0001
-#define E3G_CLOCK_DETECT_BIT_WORD48 0x0002
-#define E3G_CLOCK_DETECT_BIT_SPDIF48 0x0004
-#define E3G_CLOCK_DETECT_BIT_ADAT 0x0004
-#define E3G_CLOCK_DETECT_BIT_SPDIF96 0x0008
-#define E3G_CLOCK_DETECT_BIT_WORD (E3G_CLOCK_DETECT_BIT_WORD96|E3G_CLOCK_DETECT_BIT_WORD48)
-#define E3G_CLOCK_DETECT_BIT_SPDIF (E3G_CLOCK_DETECT_BIT_SPDIF48|E3G_CLOCK_DETECT_BIT_SPDIF96)
-
-/* Frequency control register */
-#define E3G_MAGIC_NUMBER 677376000
-#define E3G_FREQ_REG_DEFAULT (E3G_MAGIC_NUMBER / 48000 - 2)
-#define E3G_FREQ_REG_MAX 0xffff
-
-/* 3G external box types */
-#define E3G_GINA3G_BOX_TYPE 0x00
-#define E3G_LAYLA3G_BOX_TYPE 0x10
-#define E3G_ASIC_NOT_LOADED 0xffff
-#define E3G_BOX_TYPE_MASK 0xf0
-
-/* Indigo express control register values */
-#define INDIGO_EXPRESS_32000 0x02
-#define INDIGO_EXPRESS_44100 0x01
-#define INDIGO_EXPRESS_48000 0x00
-#define INDIGO_EXPRESS_DOUBLE_SPEED 0x10
-#define INDIGO_EXPRESS_QUAD_SPEED 0x04
-#define INDIGO_EXPRESS_CLOCK_MASK 0x17
-
-
-/*
- *
- * Gina20 & Layla20 have input gain controls for the analog inputs;
- * this is the magic number for the hardware that gives you 0 dB at -10.
- *
- */
-
-#define GL20_INPUT_GAIN_MAGIC_NUMBER 0xC8
-
-
-/*
- *
- * Defines how much time must pass between DSP load attempts
- *
- */
-
-#define DSP_LOAD_ATTEMPT_PERIOD 1000000L /* One second */
-
-
-/*
- *
- * Size of arrays for the comm page. MAX_PLAY_TAPS and MAX_REC_TAPS are
- * no longer used, but the sizes must still be right for the DSP to see
- * the comm page correctly.
- *
- */
-
-#define MONITOR_ARRAY_SIZE 0x180
-#define VMIXER_ARRAY_SIZE 0x40
-#define MIDI_OUT_BUFFER_SIZE 32
-#define MIDI_IN_BUFFER_SIZE 256
-#define MAX_PLAY_TAPS 168
-#define MAX_REC_TAPS 192
-#define DSP_MIDI_OUT_FIFO_SIZE 64
-
-
-/* sg_entry is a single entry for the scatter-gather list. The array of struct
-sg_entry struct is read by the DSP, so all values must be little-endian. */
-
-#define MAX_SGLIST_ENTRIES 512
-
-struct sg_entry {
- u32 addr;
- u32 size;
-};
-
-
-/****************************************************************************
-
- The comm page. This structure is read and written by the DSP; the
- DSP code is a firm believer in the byte offsets written in the comments
- at the end of each line. This structure should not be changed.
-
- Any reads from or writes to this structure should be in little-endian format.
-
- ****************************************************************************/
-
-struct comm_page { /* Base Length*/
- u32 comm_size; /* size of this object 0x000 4 */
- u32 flags; /* See Appendix A below 0x004 4 */
- u32 unused; /* Unused entry 0x008 4 */
- u32 sample_rate; /* Card sample rate in Hz 0x00c 4 */
- u32 handshake; /* DSP command handshake 0x010 4 */
- u32 cmd_start; /* Chs. to start mask 0x014 4 */
- u32 cmd_stop; /* Chs. to stop mask 0x018 4 */
- u32 cmd_reset; /* Chs. to reset mask 0x01c 4 */
- u16 audio_format[DSP_MAXPIPES]; /* Chs. audio format 0x020 32*2 */
- struct sg_entry sglist_addr[DSP_MAXPIPES];
- /* Chs. Physical sglist addrs 0x060 32*8 */
- u32 position[DSP_MAXPIPES];
- /* Positions for ea. ch. 0x160 32*4 */
- s8 vu_meter[DSP_MAXPIPES];
- /* VU meters 0x1e0 32*1 */
- s8 peak_meter[DSP_MAXPIPES];
- /* Peak meters 0x200 32*1 */
- s8 line_out_level[DSP_MAXAUDIOOUTPUTS];
- /* Output gain 0x220 16*1 */
- s8 line_in_level[DSP_MAXAUDIOINPUTS];
- /* Input gain 0x230 16*1 */
- s8 monitors[MONITOR_ARRAY_SIZE];
- /* Monitor map 0x240 0x180 */
- u32 play_coeff[MAX_PLAY_TAPS];
- /* Gina/Darla play filters - obsolete 0x3c0 168*4 */
- u32 rec_coeff[MAX_REC_TAPS];
- /* Gina/Darla record filters - obsolete 0x660 192*4 */
- u16 midi_input[MIDI_IN_BUFFER_SIZE];
- /* MIDI input data transfer buffer 0x960 256*2 */
- u8 gd_clock_state; /* Chg Gina/Darla clock state 0xb60 1 */
- u8 gd_spdif_status; /* Chg. Gina/Darla S/PDIF state 0xb61 1 */
- u8 gd_resampler_state; /* Should always be 3 0xb62 1 */
- u8 filler2; /* 0xb63 1 */
- u32 nominal_level_mask; /* -10 level enable mask 0xb64 4 */
- u16 input_clock; /* Chg. Input clock state 0xb68 2 */
- u16 output_clock; /* Chg. Output clock state 0xb6a 2 */
- u32 status_clocks; /* Current Input clock state 0xb6c 4 */
- u32 ext_box_status; /* External box status 0xb70 4 */
- u32 cmd_add_buffer; /* Pipes to add (obsolete) 0xb74 4 */
- u32 midi_out_free_count;
- /* # of bytes free in MIDI output FIFO 0xb78 4 */
- u32 unused2; /* Cyclic pipes 0xb7c 4 */
- u32 control_register;
- /* Mona, Gina24, Layla24, 3G ctrl reg 0xb80 4 */
- u32 e3g_frq_register; /* 3G frequency register 0xb84 4 */
- u8 filler[24]; /* filler 0xb88 24*1 */
- s8 vmixer[VMIXER_ARRAY_SIZE];
- /* Vmixer levels 0xba0 64*1 */
- u8 midi_output[MIDI_OUT_BUFFER_SIZE];
- /* MIDI output data 0xbe0 32*1 */
-};
-
-#endif /* _ECHO_DSP_ */
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_gml.c b/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_gml.c
deleted file mode 100644
index afa27333..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_gml.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/****************************************************************************
-
- Copyright Echo Digital Audio Corporation (c) 1998 - 2004
- All rights reserved
- www.echoaudio.com
-
- This file is part of Echo Digital Audio's generic driver library.
-
- Echo Digital Audio's generic driver library is free software;
- you can redistribute it and/or modify it under the terms of
- the GNU General Public License as published by the Free Software
- Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- *************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
-****************************************************************************/
-
-
-/* These functions are common for Gina24, Layla24 and Mona cards */
-
-
-/* ASIC status check - some cards have one or two ASICs that need to be
-loaded. Once that load is complete, this function is called to see if
-the load was successful.
-If this load fails, it does not necessarily mean that the hardware is
-defective - the external box may be disconnected or turned off. */
-static int check_asic_status(struct echoaudio *chip)
-{
- u32 asic_status;
-
- send_vector(chip, DSP_VC_TEST_ASIC);
-
- /* The DSP will return a value to indicate whether or not the
- ASIC is currently loaded */
- if (read_dsp(chip, &asic_status) < 0) {
- DE_INIT(("check_asic_status: failed on read_dsp\n"));
- chip->asic_loaded = FALSE;
- return -EIO;
- }
-
- chip->asic_loaded = (asic_status == ASIC_ALREADY_LOADED);
- return chip->asic_loaded ? 0 : -EIO;
-}
-
-
-
-/* Most configuration of Gina24, Layla24, or Mona is accomplished by writing
-the control register. write_control_reg sends the new control register
-value to the DSP. */
-static int write_control_reg(struct echoaudio *chip, u32 value, char force)
-{
- /* Handle the digital input auto-mute */
- if (chip->digital_in_automute)
- value |= GML_DIGITAL_IN_AUTO_MUTE;
- else
- value &= ~GML_DIGITAL_IN_AUTO_MUTE;
-
- DE_ACT(("write_control_reg: 0x%x\n", value));
-
- /* Write the control register */
- value = cpu_to_le32(value);
- if (value != chip->comm_page->control_register || force) {
- if (wait_handshake(chip))
- return -EIO;
- chip->comm_page->control_register = value;
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_WRITE_CONTROL_REG);
- }
- return 0;
-}
-
-
-
-/* Gina24, Layla24, and Mona support digital input auto-mute. If the digital
-input auto-mute is enabled, the DSP will only enable the digital inputs if
-the card is syncing to a valid clock on the ADAT or S/PDIF inputs.
-If the auto-mute is disabled, the digital inputs are enabled regardless of
-what the input clock is set or what is connected. */
-static int set_input_auto_mute(struct echoaudio *chip, int automute)
-{
- DE_ACT(("set_input_auto_mute %d\n", automute));
-
- chip->digital_in_automute = automute;
-
- /* Re-set the input clock to the current value - indirectly causes
- the auto-mute flag to be sent to the DSP */
- return set_input_clock(chip, chip->input_clock);
-}
-
-
-
-/* S/PDIF coax / S/PDIF optical / ADAT - switch */
-static int set_digital_mode(struct echoaudio *chip, u8 mode)
-{
- u8 previous_mode;
- int err, i, o;
-
- if (chip->bad_board)
- return -EIO;
-
- /* All audio channels must be closed before changing the digital mode */
- if (snd_BUG_ON(chip->pipe_alloc_mask))
- return -EAGAIN;
-
- if (snd_BUG_ON(!(chip->digital_modes & (1 << mode))))
- return -EINVAL;
-
- previous_mode = chip->digital_mode;
- err = dsp_set_digital_mode(chip, mode);
-
- /* If we successfully changed the digital mode from or to ADAT,
- then make sure all output, input and monitor levels are
- updated by the DSP comm object. */
- if (err >= 0 && previous_mode != mode &&
- (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) {
- spin_lock_irq(&chip->lock);
- for (o = 0; o < num_busses_out(chip); o++)
- for (i = 0; i < num_busses_in(chip); i++)
- set_monitor_gain(chip, o, i,
- chip->monitor_gain[o][i]);
-
-#ifdef ECHOCARD_HAS_INPUT_GAIN
- for (i = 0; i < num_busses_in(chip); i++)
- set_input_gain(chip, i, chip->input_gain[i]);
- update_input_line_level(chip);
-#endif
-
- for (o = 0; o < num_busses_out(chip); o++)
- set_output_gain(chip, o, chip->output_gain[o]);
- update_output_line_level(chip);
- spin_unlock_irq(&chip->lock);
- }
-
- return err;
-}
-
-
-
-/* Set the S/PDIF output format */
-static int set_professional_spdif(struct echoaudio *chip, char prof)
-{
- u32 control_reg;
- int err;
-
- /* Clear the current S/PDIF flags */
- control_reg = le32_to_cpu(chip->comm_page->control_register);
- control_reg &= GML_SPDIF_FORMAT_CLEAR_MASK;
-
- /* Set the new S/PDIF flags depending on the mode */
- control_reg |= GML_SPDIF_TWO_CHANNEL | GML_SPDIF_24_BIT |
- GML_SPDIF_COPY_PERMIT;
- if (prof) {
- /* Professional mode */
- control_reg |= GML_SPDIF_PRO_MODE;
-
- switch (chip->sample_rate) {
- case 32000:
- control_reg |= GML_SPDIF_SAMPLE_RATE0 |
- GML_SPDIF_SAMPLE_RATE1;
- break;
- case 44100:
- control_reg |= GML_SPDIF_SAMPLE_RATE0;
- break;
- case 48000:
- control_reg |= GML_SPDIF_SAMPLE_RATE1;
- break;
- }
- } else {
- /* Consumer mode */
- switch (chip->sample_rate) {
- case 32000:
- control_reg |= GML_SPDIF_SAMPLE_RATE0 |
- GML_SPDIF_SAMPLE_RATE1;
- break;
- case 48000:
- control_reg |= GML_SPDIF_SAMPLE_RATE1;
- break;
- }
- }
-
- if ((err = write_control_reg(chip, control_reg, FALSE)))
- return err;
- chip->professional_spdif = prof;
- DE_ACT(("set_professional_spdif to %s\n",
- prof ? "Professional" : "Consumer"));
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/gina20.c b/ANDROID_3.4.5/sound/pci/echoaudio/gina20.c
deleted file mode 100644
index 039125b7..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/gina20.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * ALSA driver for Echoaudio soundcards.
- * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#define ECHOGALS_FAMILY
-#define ECHOCARD_GINA20
-#define ECHOCARD_NAME "Gina20"
-#define ECHOCARD_HAS_MONITOR
-#define ECHOCARD_HAS_INPUT_GAIN
-#define ECHOCARD_HAS_DIGITAL_IO
-#define ECHOCARD_HAS_EXTERNAL_CLOCK
-#define ECHOCARD_HAS_ADAT FALSE
-
-/* Pipe indexes */
-#define PX_ANALOG_OUT 0 /* 8 */
-#define PX_DIGITAL_OUT 8 /* 2 */
-#define PX_ANALOG_IN 10 /* 2 */
-#define PX_DIGITAL_IN 12 /* 2 */
-#define PX_NUM 14
-
-/* Bus indexes */
-#define BX_ANALOG_OUT 0 /* 8 */
-#define BX_DIGITAL_OUT 8 /* 2 */
-#define BX_ANALOG_IN 10 /* 2 */
-#define BX_DIGITAL_IN 12 /* 2 */
-#define BX_NUM 14
-
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/asoundef.h>
-#include <sound/initval.h>
-#include <asm/io.h>
-#include <linux/atomic.h>
-#include "echoaudio.h"
-
-MODULE_FIRMWARE("ea/gina20_dsp.fw");
-
-#define FW_GINA20_DSP 0
-
-static const struct firmware card_fw[] = {
- {0, "gina20_dsp.fw"}
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
- {0x1057, 0x1801, 0xECC0, 0x0020, 0, 0, 0}, /* DSP 56301 Gina20 rev.0 */
- {0,}
-};
-
-static struct snd_pcm_hardware pcm_hardware_skel = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START,
- .formats = SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_S32_BE,
- .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
- .rate_min = 44100,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 262144,
- .period_bytes_min = 32,
- .period_bytes_max = 131072,
- .periods_min = 2,
- .periods_max = 220,
- /* One page (4k) contains 512 instructions. I don't know if the hw
- supports lists longer than this. In this case periods_max=220 is a
- safe limit to make sure the list never exceeds 512 instructions. */
-};
-
-
-#include "gina20_dsp.c"
-#include "echoaudio_dsp.c"
-#include "echoaudio.c"
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/gina20_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/gina20_dsp.c
deleted file mode 100644
index d1615a05..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/gina20_dsp.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/****************************************************************************
-
- Copyright Echo Digital Audio Corporation (c) 1998 - 2004
- All rights reserved
- www.echoaudio.com
-
- This file is part of Echo Digital Audio's generic driver library.
-
- Echo Digital Audio's generic driver library is free software;
- you can redistribute it and/or modify it under the terms of
- the GNU General Public License as published by the Free Software
- Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- *************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
-****************************************************************************/
-
-
-static int set_professional_spdif(struct echoaudio *chip, char prof);
-static int update_flags(struct echoaudio *chip);
-
-
-static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
-{
- int err;
-
- DE_INIT(("init_hw() - Gina20\n"));
- if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA20))
- return -ENODEV;
-
- if ((err = init_dsp_comm_page(chip))) {
- DE_INIT(("init_hw - could not initialize DSP comm page\n"));
- return err;
- }
-
- chip->device_id = device_id;
- chip->subdevice_id = subdevice_id;
- chip->bad_board = TRUE;
- chip->dsp_code_to_load = FW_GINA20_DSP;
- chip->spdif_status = GD_SPDIF_STATUS_UNDEF;
- chip->clock_state = GD_CLOCK_UNDEF;
- /* Since this card has no ASIC, mark it as loaded so everything
- works OK */
- chip->asic_loaded = TRUE;
- chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL |
- ECHO_CLOCK_BIT_SPDIF;
-
- if ((err = load_firmware(chip)) < 0)
- return err;
- chip->bad_board = FALSE;
-
- DE_INIT(("init_hw done\n"));
- return err;
-}
-
-
-
-static int set_mixer_defaults(struct echoaudio *chip)
-{
- chip->professional_spdif = FALSE;
- return init_line_levels(chip);
-}
-
-
-
-static u32 detect_input_clocks(const struct echoaudio *chip)
-{
- u32 clocks_from_dsp, clock_bits;
-
- /* Map the DSP clock detect bits to the generic driver clock
- detect bits */
- clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
-
- clock_bits = ECHO_CLOCK_BIT_INTERNAL;
-
- if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF)
- clock_bits |= ECHO_CLOCK_BIT_SPDIF;
-
- return clock_bits;
-}
-
-
-
-/* The Gina20 has no ASIC. Just do nothing */
-static int load_asic(struct echoaudio *chip)
-{
- return 0;
-}
-
-
-
-static int set_sample_rate(struct echoaudio *chip, u32 rate)
-{
- u8 clock_state, spdif_status;
-
- if (wait_handshake(chip))
- return -EIO;
-
- switch (rate) {
- case 44100:
- clock_state = GD_CLOCK_44;
- spdif_status = GD_SPDIF_STATUS_44;
- break;
- case 48000:
- clock_state = GD_CLOCK_48;
- spdif_status = GD_SPDIF_STATUS_48;
- break;
- default:
- clock_state = GD_CLOCK_NOCHANGE;
- spdif_status = GD_SPDIF_STATUS_NOCHANGE;
- break;
- }
-
- if (chip->clock_state == clock_state)
- clock_state = GD_CLOCK_NOCHANGE;
- if (spdif_status == chip->spdif_status)
- spdif_status = GD_SPDIF_STATUS_NOCHANGE;
-
- chip->comm_page->sample_rate = cpu_to_le32(rate);
- chip->comm_page->gd_clock_state = clock_state;
- chip->comm_page->gd_spdif_status = spdif_status;
- chip->comm_page->gd_resampler_state = 3; /* magic number - should always be 3 */
-
- /* Save the new audio state if it changed */
- if (clock_state != GD_CLOCK_NOCHANGE)
- chip->clock_state = clock_state;
- if (spdif_status != GD_SPDIF_STATUS_NOCHANGE)
- chip->spdif_status = spdif_status;
- chip->sample_rate = rate;
-
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE);
-}
-
-
-
-static int set_input_clock(struct echoaudio *chip, u16 clock)
-{
- DE_ACT(("set_input_clock:\n"));
-
- switch (clock) {
- case ECHO_CLOCK_INTERNAL:
- /* Reset the audio state to unknown (just in case) */
- chip->clock_state = GD_CLOCK_UNDEF;
- chip->spdif_status = GD_SPDIF_STATUS_UNDEF;
- set_sample_rate(chip, chip->sample_rate);
- chip->input_clock = clock;
- DE_ACT(("Set Gina clock to INTERNAL\n"));
- break;
- case ECHO_CLOCK_SPDIF:
- chip->comm_page->gd_clock_state = GD_CLOCK_SPDIFIN;
- chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_NOCHANGE;
- clear_handshake(chip);
- send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE);
- chip->clock_state = GD_CLOCK_SPDIFIN;
- DE_ACT(("Set Gina20 clock to SPDIF\n"));
- chip->input_clock = clock;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-
-
-/* Set input bus gain (one unit is 0.5dB !) */
-static int set_input_gain(struct echoaudio *chip, u16 input, int gain)
-{
- if (snd_BUG_ON(input >= num_busses_in(chip)))
- return -EINVAL;
-
- if (wait_handshake(chip))
- return -EIO;
-
- chip->input_gain[input] = gain;
- gain += GL20_INPUT_GAIN_MAGIC_NUMBER;
- chip->comm_page->line_in_level[input] = gain;
- return 0;
-}
-
-
-
-/* Tell the DSP to reread the flags from the comm page */
-static int update_flags(struct echoaudio *chip)
-{
- if (wait_handshake(chip))
- return -EIO;
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_UPDATE_FLAGS);
-}
-
-
-
-static int set_professional_spdif(struct echoaudio *chip, char prof)
-{
- DE_ACT(("set_professional_spdif %d\n", prof));
- if (prof)
- chip->comm_page->flags |=
- cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
- else
- chip->comm_page->flags &=
- ~cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
- chip->professional_spdif = prof;
- return update_flags(chip);
-}
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/gina24.c b/ANDROID_3.4.5/sound/pci/echoaudio/gina24.c
deleted file mode 100644
index 5e966f6f..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/gina24.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * ALSA driver for Echoaudio soundcards.
- * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#define ECHO24_FAMILY
-#define ECHOCARD_GINA24
-#define ECHOCARD_NAME "Gina24"
-#define ECHOCARD_HAS_MONITOR
-#define ECHOCARD_HAS_ASIC
-#define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL
-#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL
-#define ECHOCARD_HAS_SUPER_INTERLEAVE
-#define ECHOCARD_HAS_DIGITAL_IO
-#define ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE
-#define ECHOCARD_HAS_DIGITAL_MODE_SWITCH
-#define ECHOCARD_HAS_EXTERNAL_CLOCK
-#define ECHOCARD_HAS_ADAT 6
-#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
-
-/* Pipe indexes */
-#define PX_ANALOG_OUT 0 /* 8 */
-#define PX_DIGITAL_OUT 8 /* 8 */
-#define PX_ANALOG_IN 16 /* 2 */
-#define PX_DIGITAL_IN 18 /* 8 */
-#define PX_NUM 26
-
-/* Bus indexes */
-#define BX_ANALOG_OUT 0 /* 8 */
-#define BX_DIGITAL_OUT 8 /* 8 */
-#define BX_ANALOG_IN 16 /* 2 */
-#define BX_DIGITAL_IN 18 /* 8 */
-#define BX_NUM 26
-
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/asoundef.h>
-#include <sound/initval.h>
-#include <asm/io.h>
-#include <linux/atomic.h>
-#include "echoaudio.h"
-
-MODULE_FIRMWARE("ea/loader_dsp.fw");
-MODULE_FIRMWARE("ea/gina24_301_dsp.fw");
-MODULE_FIRMWARE("ea/gina24_361_dsp.fw");
-MODULE_FIRMWARE("ea/gina24_301_asic.fw");
-MODULE_FIRMWARE("ea/gina24_361_asic.fw");
-
-#define FW_361_LOADER 0
-#define FW_GINA24_301_DSP 1
-#define FW_GINA24_361_DSP 2
-#define FW_GINA24_301_ASIC 3
-#define FW_GINA24_361_ASIC 4
-
-static const struct firmware card_fw[] = {
- {0, "loader_dsp.fw"},
- {0, "gina24_301_dsp.fw"},
- {0, "gina24_361_dsp.fw"},
- {0, "gina24_301_asic.fw"},
- {0, "gina24_361_asic.fw"}
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
- {0x1057, 0x1801, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56301 Gina24 rev.0 */
- {0x1057, 0x1801, 0xECC0, 0x0051, 0, 0, 0}, /* DSP 56301 Gina24 rev.1 */
- {0x1057, 0x3410, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56361 Gina24 rev.0 */
- {0x1057, 0x3410, 0xECC0, 0x0051, 0, 0, 0}, /* DSP 56361 Gina24 rev.1 */
- {0,}
-};
-
-static struct snd_pcm_hardware pcm_hardware_skel = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START,
- .formats = SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_S32_BE,
- .rates = SNDRV_PCM_RATE_8000_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000,
- .rate_min = 8000,
- .rate_max = 96000,
- .channels_min = 1,
- .channels_max = 8,
- .buffer_bytes_max = 262144,
- .period_bytes_min = 32,
- .period_bytes_max = 131072,
- .periods_min = 2,
- .periods_max = 220,
- /* One page (4k) contains 512 instructions. I don't know if the hw
- supports lists longer than this. In this case periods_max=220 is a
- safe limit to make sure the list never exceeds 512 instructions.
- 220 ~= (512 - 1 - (BUFFER_BYTES_MAX / PAGE_SIZE)) / 2 */
-};
-
-#include "gina24_dsp.c"
-#include "echoaudio_dsp.c"
-#include "echoaudio_gml.c"
-#include "echoaudio.c"
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/gina24_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/gina24_dsp.c
deleted file mode 100644
index 98f7cfa8..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/gina24_dsp.c
+++ /dev/null
@@ -1,349 +0,0 @@
-/****************************************************************************
-
- Copyright Echo Digital Audio Corporation (c) 1998 - 2004
- All rights reserved
- www.echoaudio.com
-
- This file is part of Echo Digital Audio's generic driver library.
-
- Echo Digital Audio's generic driver library is free software;
- you can redistribute it and/or modify it under the terms of
- the GNU General Public License as published by the Free Software
- Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- *************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
-****************************************************************************/
-
-
-static int write_control_reg(struct echoaudio *chip, u32 value, char force);
-static int set_input_clock(struct echoaudio *chip, u16 clock);
-static int set_professional_spdif(struct echoaudio *chip, char prof);
-static int set_digital_mode(struct echoaudio *chip, u8 mode);
-static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
-static int check_asic_status(struct echoaudio *chip);
-
-
-static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
-{
- int err;
-
- DE_INIT(("init_hw() - Gina24\n"));
- if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA24))
- return -ENODEV;
-
- if ((err = init_dsp_comm_page(chip))) {
- DE_INIT(("init_hw - could not initialize DSP comm page\n"));
- return err;
- }
-
- chip->device_id = device_id;
- chip->subdevice_id = subdevice_id;
- chip->bad_board = TRUE;
- chip->input_clock_types =
- ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
- ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96 |
- ECHO_CLOCK_BIT_ADAT;
-
- /* Gina24 comes in both '301 and '361 flavors */
- if (chip->device_id == DEVICE_ID_56361) {
- chip->dsp_code_to_load = FW_GINA24_361_DSP;
- chip->digital_modes =
- ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
- ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
- ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
- } else {
- chip->dsp_code_to_load = FW_GINA24_301_DSP;
- chip->digital_modes =
- ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
- ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
- ECHOCAPS_HAS_DIGITAL_MODE_ADAT |
- ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_CDROM;
- }
-
- if ((err = load_firmware(chip)) < 0)
- return err;
- chip->bad_board = FALSE;
-
- DE_INIT(("init_hw done\n"));
- return err;
-}
-
-
-
-static int set_mixer_defaults(struct echoaudio *chip)
-{
- chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
- chip->professional_spdif = FALSE;
- chip->digital_in_automute = TRUE;
- return init_line_levels(chip);
-}
-
-
-
-static u32 detect_input_clocks(const struct echoaudio *chip)
-{
- u32 clocks_from_dsp, clock_bits;
-
- /* Map the DSP clock detect bits to the generic driver clock
- detect bits */
- clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
-
- clock_bits = ECHO_CLOCK_BIT_INTERNAL;
-
- if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF)
- clock_bits |= ECHO_CLOCK_BIT_SPDIF;
-
- if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT)
- clock_bits |= ECHO_CLOCK_BIT_ADAT;
-
- if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ESYNC)
- clock_bits |= ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96;
-
- return clock_bits;
-}
-
-
-
-/* Gina24 has an ASIC on the PCI card which must be loaded for anything
-interesting to happen. */
-static int load_asic(struct echoaudio *chip)
-{
- u32 control_reg;
- int err;
- short asic;
-
- if (chip->asic_loaded)
- return 1;
-
- /* Give the DSP a few milliseconds to settle down */
- mdelay(10);
-
- /* Pick the correct ASIC for '301 or '361 Gina24 */
- if (chip->device_id == DEVICE_ID_56361)
- asic = FW_GINA24_361_ASIC;
- else
- asic = FW_GINA24_301_ASIC;
-
- err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, asic);
- if (err < 0)
- return err;
-
- chip->asic_code = asic;
-
- /* Now give the new ASIC a little time to set up */
- mdelay(10);
- /* See if it worked */
- err = check_asic_status(chip);
-
- /* Set up the control register if the load succeeded -
- 48 kHz, internal clock, S/PDIF RCA mode */
- if (!err) {
- control_reg = GML_CONVERTER_ENABLE | GML_48KHZ;
- err = write_control_reg(chip, control_reg, TRUE);
- }
- DE_INIT(("load_asic() done\n"));
- return err;
-}
-
-
-
-static int set_sample_rate(struct echoaudio *chip, u32 rate)
-{
- u32 control_reg, clock;
-
- if (snd_BUG_ON(rate >= 50000 &&
- chip->digital_mode == DIGITAL_MODE_ADAT))
- return -EINVAL;
-
- /* Only set the clock for internal mode. */
- if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
- DE_ACT(("set_sample_rate: Cannot set sample rate - "
- "clock not set to CLK_CLOCKININTERNAL\n"));
- /* Save the rate anyhow */
- chip->comm_page->sample_rate = cpu_to_le32(rate);
- chip->sample_rate = rate;
- return 0;
- }
-
- clock = 0;
-
- control_reg = le32_to_cpu(chip->comm_page->control_register);
- control_reg &= GML_CLOCK_CLEAR_MASK & GML_SPDIF_RATE_CLEAR_MASK;
-
- switch (rate) {
- case 96000:
- clock = GML_96KHZ;
- break;
- case 88200:
- clock = GML_88KHZ;
- break;
- case 48000:
- clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1;
- break;
- case 44100:
- clock = GML_44KHZ;
- /* Professional mode ? */
- if (control_reg & GML_SPDIF_PRO_MODE)
- clock |= GML_SPDIF_SAMPLE_RATE0;
- break;
- case 32000:
- clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 |
- GML_SPDIF_SAMPLE_RATE1;
- break;
- case 22050:
- clock = GML_22KHZ;
- break;
- case 16000:
- clock = GML_16KHZ;
- break;
- case 11025:
- clock = GML_11KHZ;
- break;
- case 8000:
- clock = GML_8KHZ;
- break;
- default:
- DE_ACT(("set_sample_rate: %d invalid!\n", rate));
- return -EINVAL;
- }
-
- control_reg |= clock;
-
- chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */
- chip->sample_rate = rate;
- DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock));
-
- return write_control_reg(chip, control_reg, FALSE);
-}
-
-
-
-static int set_input_clock(struct echoaudio *chip, u16 clock)
-{
- u32 control_reg, clocks_from_dsp;
-
- DE_ACT(("set_input_clock:\n"));
-
- /* Mask off the clock select bits */
- control_reg = le32_to_cpu(chip->comm_page->control_register) &
- GML_CLOCK_CLEAR_MASK;
- clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
-
- switch (clock) {
- case ECHO_CLOCK_INTERNAL:
- DE_ACT(("Set Gina24 clock to INTERNAL\n"));
- chip->input_clock = ECHO_CLOCK_INTERNAL;
- return set_sample_rate(chip, chip->sample_rate);
- case ECHO_CLOCK_SPDIF:
- if (chip->digital_mode == DIGITAL_MODE_ADAT)
- return -EAGAIN;
- DE_ACT(("Set Gina24 clock to SPDIF\n"));
- control_reg |= GML_SPDIF_CLOCK;
- if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96)
- control_reg |= GML_DOUBLE_SPEED_MODE;
- else
- control_reg &= ~GML_DOUBLE_SPEED_MODE;
- break;
- case ECHO_CLOCK_ADAT:
- if (chip->digital_mode != DIGITAL_MODE_ADAT)
- return -EAGAIN;
- DE_ACT(("Set Gina24 clock to ADAT\n"));
- control_reg |= GML_ADAT_CLOCK;
- control_reg &= ~GML_DOUBLE_SPEED_MODE;
- break;
- case ECHO_CLOCK_ESYNC:
- DE_ACT(("Set Gina24 clock to ESYNC\n"));
- control_reg |= GML_ESYNC_CLOCK;
- control_reg &= ~GML_DOUBLE_SPEED_MODE;
- break;
- case ECHO_CLOCK_ESYNC96:
- DE_ACT(("Set Gina24 clock to ESYNC96\n"));
- control_reg |= GML_ESYNC_CLOCK | GML_DOUBLE_SPEED_MODE;
- break;
- default:
- DE_ACT(("Input clock 0x%x not supported for Gina24\n", clock));
- return -EINVAL;
- }
-
- chip->input_clock = clock;
- return write_control_reg(chip, control_reg, TRUE);
-}
-
-
-
-static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
-{
- u32 control_reg;
- int err, incompatible_clock;
-
- /* Set clock to "internal" if it's not compatible with the new mode */
- incompatible_clock = FALSE;
- switch (mode) {
- case DIGITAL_MODE_SPDIF_OPTICAL:
- case DIGITAL_MODE_SPDIF_CDROM:
- case DIGITAL_MODE_SPDIF_RCA:
- if (chip->input_clock == ECHO_CLOCK_ADAT)
- incompatible_clock = TRUE;
- break;
- case DIGITAL_MODE_ADAT:
- if (chip->input_clock == ECHO_CLOCK_SPDIF)
- incompatible_clock = TRUE;
- break;
- default:
- DE_ACT(("Digital mode not supported: %d\n", mode));
- return -EINVAL;
- }
-
- spin_lock_irq(&chip->lock);
-
- if (incompatible_clock) { /* Switch to 48KHz, internal */
- chip->sample_rate = 48000;
- set_input_clock(chip, ECHO_CLOCK_INTERNAL);
- }
-
- /* Clear the current digital mode */
- control_reg = le32_to_cpu(chip->comm_page->control_register);
- control_reg &= GML_DIGITAL_MODE_CLEAR_MASK;
-
- /* Tweak the control reg */
- switch (mode) {
- case DIGITAL_MODE_SPDIF_OPTICAL:
- control_reg |= GML_SPDIF_OPTICAL_MODE;
- break;
- case DIGITAL_MODE_SPDIF_CDROM:
- /* '361 Gina24 cards do not have the S/PDIF CD-ROM mode */
- if (chip->device_id == DEVICE_ID_56301)
- control_reg |= GML_SPDIF_CDROM_MODE;
- break;
- case DIGITAL_MODE_SPDIF_RCA:
- /* GML_SPDIF_OPTICAL_MODE bit cleared */
- break;
- case DIGITAL_MODE_ADAT:
- control_reg |= GML_ADAT_MODE;
- control_reg &= ~GML_DOUBLE_SPEED_MODE;
- break;
- }
-
- err = write_control_reg(chip, control_reg, TRUE);
- spin_unlock_irq(&chip->lock);
- if (err < 0)
- return err;
- chip->digital_mode = mode;
-
- DE_ACT(("set_digital_mode to %d\n", chip->digital_mode));
- return incompatible_clock;
-}
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigo.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigo.c
deleted file mode 100644
index c166b7ee..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/indigo.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * ALSA driver for Echoaudio soundcards.
- * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#define INDIGO_FAMILY
-#define ECHOCARD_INDIGO
-#define ECHOCARD_NAME "Indigo"
-#define ECHOCARD_HAS_SUPER_INTERLEAVE
-#define ECHOCARD_HAS_VMIXER
-#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
-
-/* Pipe indexes */
-#define PX_ANALOG_OUT 0 /* 8 */
-#define PX_DIGITAL_OUT 8 /* 0 */
-#define PX_ANALOG_IN 8 /* 0 */
-#define PX_DIGITAL_IN 8 /* 0 */
-#define PX_NUM 8
-
-/* Bus indexes */
-#define BX_ANALOG_OUT 0 /* 2 */
-#define BX_DIGITAL_OUT 2 /* 0 */
-#define BX_ANALOG_IN 2 /* 0 */
-#define BX_DIGITAL_IN 2 /* 0 */
-#define BX_NUM 2
-
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/asoundef.h>
-#include <sound/initval.h>
-#include <asm/io.h>
-#include <linux/atomic.h>
-#include "echoaudio.h"
-
-MODULE_FIRMWARE("ea/loader_dsp.fw");
-MODULE_FIRMWARE("ea/indigo_dsp.fw");
-
-#define FW_361_LOADER 0
-#define FW_INDIGO_DSP 1
-
-static const struct firmware card_fw[] = {
- {0, "loader_dsp.fw"},
- {0, "indigo_dsp.fw"}
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
- {0x1057, 0x3410, 0xECC0, 0x0090, 0, 0, 0}, /* Indigo */
- {0,}
-};
-
-static struct snd_pcm_hardware pcm_hardware_skel = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START,
- .formats = SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_S32_BE,
- .rates = SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000,
- .rate_min = 32000,
- .rate_max = 96000,
- .channels_min = 1,
- .channels_max = 8,
- .buffer_bytes_max = 262144,
- .period_bytes_min = 32,
- .period_bytes_max = 131072,
- .periods_min = 2,
- .periods_max = 220,
-};
-
-#include "indigo_dsp.c"
-#include "echoaudio_dsp.c"
-#include "echoaudio.c"
-
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigo_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigo_dsp.c
deleted file mode 100644
index 5e85f14f..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/indigo_dsp.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/****************************************************************************
-
- Copyright Echo Digital Audio Corporation (c) 1998 - 2004
- All rights reserved
- www.echoaudio.com
-
- This file is part of Echo Digital Audio's generic driver library.
-
- Echo Digital Audio's generic driver library is free software;
- you can redistribute it and/or modify it under the terms of
- the GNU General Public License as published by the Free Software
- Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- *************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
-****************************************************************************/
-
-
-static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
- int gain);
-static int update_vmixer_level(struct echoaudio *chip);
-
-
-static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
-{
- int err;
-
- DE_INIT(("init_hw() - Indigo\n"));
- if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO))
- return -ENODEV;
-
- if ((err = init_dsp_comm_page(chip))) {
- DE_INIT(("init_hw - could not initialize DSP comm page\n"));
- return err;
- }
-
- chip->device_id = device_id;
- chip->subdevice_id = subdevice_id;
- chip->bad_board = TRUE;
- chip->dsp_code_to_load = FW_INDIGO_DSP;
- /* Since this card has no ASIC, mark it as loaded so everything
- works OK */
- chip->asic_loaded = TRUE;
- chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
-
- if ((err = load_firmware(chip)) < 0)
- return err;
- chip->bad_board = FALSE;
-
- DE_INIT(("init_hw done\n"));
- return err;
-}
-
-
-
-static int set_mixer_defaults(struct echoaudio *chip)
-{
- return init_line_levels(chip);
-}
-
-
-
-static u32 detect_input_clocks(const struct echoaudio *chip)
-{
- return ECHO_CLOCK_BIT_INTERNAL;
-}
-
-
-
-/* The Indigo has no ASIC. Just do nothing */
-static int load_asic(struct echoaudio *chip)
-{
- return 0;
-}
-
-
-
-static int set_sample_rate(struct echoaudio *chip, u32 rate)
-{
- u32 control_reg;
-
- switch (rate) {
- case 96000:
- control_reg = MIA_96000;
- break;
- case 88200:
- control_reg = MIA_88200;
- break;
- case 48000:
- control_reg = MIA_48000;
- break;
- case 44100:
- control_reg = MIA_44100;
- break;
- case 32000:
- control_reg = MIA_32000;
- break;
- default:
- DE_ACT(("set_sample_rate: %d invalid!\n", rate));
- return -EINVAL;
- }
-
- /* Set the control register if it has changed */
- if (control_reg != le32_to_cpu(chip->comm_page->control_register)) {
- if (wait_handshake(chip))
- return -EIO;
-
- chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */
- chip->comm_page->control_register = cpu_to_le32(control_reg);
- chip->sample_rate = rate;
-
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
- }
- return 0;
-}
-
-
-
-/* This function routes the sound from a virtual channel to a real output */
-static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
- int gain)
-{
- int index;
-
- if (snd_BUG_ON(pipe >= num_pipes_out(chip) ||
- output >= num_busses_out(chip)))
- return -EINVAL;
-
- if (wait_handshake(chip))
- return -EIO;
-
- chip->vmixer_gain[output][pipe] = gain;
- index = output * num_pipes_out(chip) + pipe;
- chip->comm_page->vmixer[index] = gain;
-
- DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain));
- return 0;
-}
-
-
-
-/* Tell the DSP to read and update virtual mixer levels in comm page. */
-static int update_vmixer_level(struct echoaudio *chip)
-{
- if (wait_handshake(chip))
- return -EIO;
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_SET_VMIXER_GAIN);
-}
-
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigo_express_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigo_express_dsp.c
deleted file mode 100644
index 2e4ab3e3..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/indigo_express_dsp.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/************************************************************************
-
-This file is part of Echo Digital Audio's generic driver library.
-Copyright Echo Digital Audio Corporation (c) 1998 - 2005
-All rights reserved
-www.echoaudio.com
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-*************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
-*************************************************************************/
-
-static int set_sample_rate(struct echoaudio *chip, u32 rate)
-{
- u32 clock, control_reg, old_control_reg;
-
- if (wait_handshake(chip))
- return -EIO;
-
- old_control_reg = le32_to_cpu(chip->comm_page->control_register);
- control_reg = old_control_reg & ~INDIGO_EXPRESS_CLOCK_MASK;
-
- switch (rate) {
- case 32000:
- clock = INDIGO_EXPRESS_32000;
- break;
- case 44100:
- clock = INDIGO_EXPRESS_44100;
- break;
- case 48000:
- clock = INDIGO_EXPRESS_48000;
- break;
- case 64000:
- clock = INDIGO_EXPRESS_32000|INDIGO_EXPRESS_DOUBLE_SPEED;
- break;
- case 88200:
- clock = INDIGO_EXPRESS_44100|INDIGO_EXPRESS_DOUBLE_SPEED;
- break;
- case 96000:
- clock = INDIGO_EXPRESS_48000|INDIGO_EXPRESS_DOUBLE_SPEED;
- break;
- default:
- return -EINVAL;
- }
-
- control_reg |= clock;
- if (control_reg != old_control_reg) {
- DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock));
- chip->comm_page->control_register = cpu_to_le32(control_reg);
- chip->sample_rate = rate;
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
- }
- return 0;
-}
-
-
-
-/* This function routes the sound from a virtual channel to a real output */
-static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
- int gain)
-{
- int index;
-
- if (snd_BUG_ON(pipe >= num_pipes_out(chip) ||
- output >= num_busses_out(chip)))
- return -EINVAL;
-
- if (wait_handshake(chip))
- return -EIO;
-
- chip->vmixer_gain[output][pipe] = gain;
- index = output * num_pipes_out(chip) + pipe;
- chip->comm_page->vmixer[index] = gain;
-
- DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain));
- return 0;
-}
-
-
-
-/* Tell the DSP to read and update virtual mixer levels in comm page. */
-static int update_vmixer_level(struct echoaudio *chip)
-{
- if (wait_handshake(chip))
- return -EIO;
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_SET_VMIXER_GAIN);
-}
-
-
-
-static u32 detect_input_clocks(const struct echoaudio *chip)
-{
- return ECHO_CLOCK_BIT_INTERNAL;
-}
-
-
-
-/* The IndigoIO has no ASIC. Just do nothing */
-static int load_asic(struct echoaudio *chip)
-{
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigodj.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigodj.c
deleted file mode 100644
index a3ef3b99..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/indigodj.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * ALSA driver for Echoaudio soundcards.
- * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#define INDIGO_FAMILY
-#define ECHOCARD_INDIGO_DJ
-#define ECHOCARD_NAME "Indigo DJ"
-#define ECHOCARD_HAS_SUPER_INTERLEAVE
-#define ECHOCARD_HAS_VMIXER
-#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
-
-/* Pipe indexes */
-#define PX_ANALOG_OUT 0 /* 8 */
-#define PX_DIGITAL_OUT 8 /* 0 */
-#define PX_ANALOG_IN 8 /* 0 */
-#define PX_DIGITAL_IN 8 /* 0 */
-#define PX_NUM 8
-
-/* Bus indexes */
-#define BX_ANALOG_OUT 0 /* 4 */
-#define BX_DIGITAL_OUT 4 /* 0 */
-#define BX_ANALOG_IN 4 /* 0 */
-#define BX_DIGITAL_IN 4 /* 0 */
-#define BX_NUM 4
-
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/asoundef.h>
-#include <sound/initval.h>
-#include <asm/io.h>
-#include <linux/atomic.h>
-#include "echoaudio.h"
-
-MODULE_FIRMWARE("ea/loader_dsp.fw");
-MODULE_FIRMWARE("ea/indigo_dj_dsp.fw");
-
-#define FW_361_LOADER 0
-#define FW_INDIGO_DJ_DSP 1
-
-static const struct firmware card_fw[] = {
- {0, "loader_dsp.fw"},
- {0, "indigo_dj_dsp.fw"}
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
- {0x1057, 0x3410, 0xECC0, 0x00B0, 0, 0, 0}, /* Indigo DJ*/
- {0,}
-};
-
-static struct snd_pcm_hardware pcm_hardware_skel = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START,
- .formats = SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_S32_BE,
- .rates = SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000,
- .rate_min = 32000,
- .rate_max = 96000,
- .channels_min = 1,
- .channels_max = 4,
- .buffer_bytes_max = 262144,
- .period_bytes_min = 32,
- .period_bytes_max = 131072,
- .periods_min = 2,
- .periods_max = 220,
-};
-
-#include "indigodj_dsp.c"
-#include "echoaudio_dsp.c"
-#include "echoaudio.c"
-
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigodj_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigodj_dsp.c
deleted file mode 100644
index 68f3c8cc..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/indigodj_dsp.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/****************************************************************************
-
- Copyright Echo Digital Audio Corporation (c) 1998 - 2004
- All rights reserved
- www.echoaudio.com
-
- This file is part of Echo Digital Audio's generic driver library.
-
- Echo Digital Audio's generic driver library is free software;
- you can redistribute it and/or modify it under the terms of
- the GNU General Public License as published by the Free Software
- Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- *************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
-****************************************************************************/
-
-
-static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
- int gain);
-static int update_vmixer_level(struct echoaudio *chip);
-
-
-static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
-{
- int err;
-
- DE_INIT(("init_hw() - Indigo DJ\n"));
- if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_DJ))
- return -ENODEV;
-
- if ((err = init_dsp_comm_page(chip))) {
- DE_INIT(("init_hw - could not initialize DSP comm page\n"));
- return err;
- }
-
- chip->device_id = device_id;
- chip->subdevice_id = subdevice_id;
- chip->bad_board = TRUE;
- chip->dsp_code_to_load = FW_INDIGO_DJ_DSP;
- /* Since this card has no ASIC, mark it as loaded so everything
- works OK */
- chip->asic_loaded = TRUE;
- chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
-
- if ((err = load_firmware(chip)) < 0)
- return err;
- chip->bad_board = FALSE;
-
- DE_INIT(("init_hw done\n"));
- return err;
-}
-
-
-
-static int set_mixer_defaults(struct echoaudio *chip)
-{
- return init_line_levels(chip);
-}
-
-
-
-static u32 detect_input_clocks(const struct echoaudio *chip)
-{
- return ECHO_CLOCK_BIT_INTERNAL;
-}
-
-
-
-/* The IndigoDJ has no ASIC. Just do nothing */
-static int load_asic(struct echoaudio *chip)
-{
- return 0;
-}
-
-
-
-static int set_sample_rate(struct echoaudio *chip, u32 rate)
-{
- u32 control_reg;
-
- switch (rate) {
- case 96000:
- control_reg = MIA_96000;
- break;
- case 88200:
- control_reg = MIA_88200;
- break;
- case 48000:
- control_reg = MIA_48000;
- break;
- case 44100:
- control_reg = MIA_44100;
- break;
- case 32000:
- control_reg = MIA_32000;
- break;
- default:
- DE_ACT(("set_sample_rate: %d invalid!\n", rate));
- return -EINVAL;
- }
-
- /* Set the control register if it has changed */
- if (control_reg != le32_to_cpu(chip->comm_page->control_register)) {
- if (wait_handshake(chip))
- return -EIO;
-
- chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */
- chip->comm_page->control_register = cpu_to_le32(control_reg);
- chip->sample_rate = rate;
-
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
- }
- return 0;
-}
-
-
-
-/* This function routes the sound from a virtual channel to a real output */
-static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
- int gain)
-{
- int index;
-
- if (snd_BUG_ON(pipe >= num_pipes_out(chip) ||
- output >= num_busses_out(chip)))
- return -EINVAL;
-
- if (wait_handshake(chip))
- return -EIO;
-
- chip->vmixer_gain[output][pipe] = gain;
- index = output * num_pipes_out(chip) + pipe;
- chip->comm_page->vmixer[index] = gain;
-
- DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain));
- return 0;
-}
-
-
-
-/* Tell the DSP to read and update virtual mixer levels in comm page. */
-static int update_vmixer_level(struct echoaudio *chip)
-{
- if (wait_handshake(chip))
- return -EIO;
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_SET_VMIXER_GAIN);
-}
-
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigodjx.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigodjx.c
deleted file mode 100644
index f516444f..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/indigodjx.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * ALSA driver for Echoaudio soundcards.
- * Copyright (C) 2009 Giuliano Pochini <pochini@shiny.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#define INDIGO_FAMILY
-#define ECHOCARD_INDIGO_DJX
-#define ECHOCARD_NAME "Indigo DJx"
-#define ECHOCARD_HAS_SUPER_INTERLEAVE
-#define ECHOCARD_HAS_VMIXER
-#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
-
-/* Pipe indexes */
-#define PX_ANALOG_OUT 0 /* 8 */
-#define PX_DIGITAL_OUT 8 /* 0 */
-#define PX_ANALOG_IN 8 /* 0 */
-#define PX_DIGITAL_IN 8 /* 0 */
-#define PX_NUM 8
-
-/* Bus indexes */
-#define BX_ANALOG_OUT 0 /* 4 */
-#define BX_DIGITAL_OUT 4 /* 0 */
-#define BX_ANALOG_IN 4 /* 0 */
-#define BX_DIGITAL_IN 4 /* 0 */
-#define BX_NUM 4
-
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/asoundef.h>
-#include <sound/initval.h>
-#include <linux/atomic.h>
-#include "echoaudio.h"
-
-MODULE_FIRMWARE("ea/loader_dsp.fw");
-MODULE_FIRMWARE("ea/indigo_djx_dsp.fw");
-
-#define FW_361_LOADER 0
-#define FW_INDIGO_DJX_DSP 1
-
-static const struct firmware card_fw[] = {
- {0, "loader_dsp.fw"},
- {0, "indigo_djx_dsp.fw"}
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
- {0x1057, 0x3410, 0xECC0, 0x00E0, 0, 0, 0}, /* Indigo DJx*/
- {0,}
-};
-
-static struct snd_pcm_hardware pcm_hardware_skel = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START,
- .formats = SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_S32_BE,
- .rates = SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_64000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000,
- .rate_min = 32000,
- .rate_max = 96000,
- .channels_min = 1,
- .channels_max = 4,
- .buffer_bytes_max = 262144,
- .period_bytes_min = 32,
- .period_bytes_max = 131072,
- .periods_min = 2,
- .periods_max = 220,
-};
-
-#include "indigodjx_dsp.c"
-#include "indigo_express_dsp.c"
-#include "echoaudio_dsp.c"
-#include "echoaudio.c"
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigodjx_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigodjx_dsp.c
deleted file mode 100644
index bb9632c7..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/indigodjx_dsp.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/************************************************************************
-
-This file is part of Echo Digital Audio's generic driver library.
-Copyright Echo Digital Audio Corporation (c) 1998 - 2005
-All rights reserved
-www.echoaudio.com
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-*************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
-*************************************************************************/
-
-static int update_vmixer_level(struct echoaudio *chip);
-static int set_vmixer_gain(struct echoaudio *chip, u16 output,
- u16 pipe, int gain);
-
-
-static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
-{
- int err;
-
- DE_INIT(("init_hw() - Indigo DJx\n"));
- if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_DJX))
- return -ENODEV;
-
- err = init_dsp_comm_page(chip);
- if (err < 0) {
- DE_INIT(("init_hw - could not initialize DSP comm page\n"));
- return err;
- }
-
- chip->device_id = device_id;
- chip->subdevice_id = subdevice_id;
- chip->bad_board = TRUE;
- chip->dsp_code_to_load = FW_INDIGO_DJX_DSP;
- /* Since this card has no ASIC, mark it as loaded so everything
- works OK */
- chip->asic_loaded = TRUE;
- chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
-
- err = load_firmware(chip);
- if (err < 0)
- return err;
- chip->bad_board = FALSE;
-
- DE_INIT(("init_hw done\n"));
- return err;
-}
-
-
-
-static int set_mixer_defaults(struct echoaudio *chip)
-{
- return init_line_levels(chip);
-}
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigoio.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigoio.c
deleted file mode 100644
index c22c82fd..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/indigoio.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * ALSA driver for Echoaudio soundcards.
- * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#define INDIGO_FAMILY
-#define ECHOCARD_INDIGO_IO
-#define ECHOCARD_NAME "Indigo IO"
-#define ECHOCARD_HAS_MONITOR
-#define ECHOCARD_HAS_SUPER_INTERLEAVE
-#define ECHOCARD_HAS_VMIXER
-#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
-
-/* Pipe indexes */
-#define PX_ANALOG_OUT 0 /* 8 */
-#define PX_DIGITAL_OUT 8 /* 0 */
-#define PX_ANALOG_IN 8 /* 2 */
-#define PX_DIGITAL_IN 10 /* 0 */
-#define PX_NUM 10
-
-/* Bus indexes */
-#define BX_ANALOG_OUT 0 /* 2 */
-#define BX_DIGITAL_OUT 2 /* 0 */
-#define BX_ANALOG_IN 2 /* 2 */
-#define BX_DIGITAL_IN 4 /* 0 */
-#define BX_NUM 4
-
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/asoundef.h>
-#include <sound/initval.h>
-#include <asm/io.h>
-#include <linux/atomic.h>
-#include "echoaudio.h"
-
-MODULE_FIRMWARE("ea/loader_dsp.fw");
-MODULE_FIRMWARE("ea/indigo_io_dsp.fw");
-
-#define FW_361_LOADER 0
-#define FW_INDIGO_IO_DSP 1
-
-static const struct firmware card_fw[] = {
- {0, "loader_dsp.fw"},
- {0, "indigo_io_dsp.fw"}
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
- {0x1057, 0x3410, 0xECC0, 0x00A0, 0, 0, 0}, /* Indigo IO*/
- {0,}
-};
-
-static struct snd_pcm_hardware pcm_hardware_skel = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START,
- .formats = SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_S32_BE,
- .rates = SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000,
- .rate_min = 32000,
- .rate_max = 96000,
- .channels_min = 1,
- .channels_max = 8,
- .buffer_bytes_max = 262144,
- .period_bytes_min = 32,
- .period_bytes_max = 131072,
- .periods_min = 2,
- .periods_max = 220,
-};
-
-#include "indigoio_dsp.c"
-#include "echoaudio_dsp.c"
-#include "echoaudio.c"
-
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigoio_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigoio_dsp.c
deleted file mode 100644
index beb9a5b6..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/indigoio_dsp.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/****************************************************************************
-
- Copyright Echo Digital Audio Corporation (c) 1998 - 2004
- All rights reserved
- www.echoaudio.com
-
- This file is part of Echo Digital Audio's generic driver library.
-
- Echo Digital Audio's generic driver library is free software;
- you can redistribute it and/or modify it under the terms of
- the GNU General Public License as published by the Free Software
- Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- *************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
-****************************************************************************/
-
-
-static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
- int gain);
-static int update_vmixer_level(struct echoaudio *chip);
-
-
-static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
-{
- int err;
-
- DE_INIT(("init_hw() - Indigo IO\n"));
- if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_IO))
- return -ENODEV;
-
- if ((err = init_dsp_comm_page(chip))) {
- DE_INIT(("init_hw - could not initialize DSP comm page\n"));
- return err;
- }
-
- chip->device_id = device_id;
- chip->subdevice_id = subdevice_id;
- chip->bad_board = TRUE;
- chip->dsp_code_to_load = FW_INDIGO_IO_DSP;
- /* Since this card has no ASIC, mark it as loaded so everything
- works OK */
- chip->asic_loaded = TRUE;
- chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
-
- if ((err = load_firmware(chip)) < 0)
- return err;
- chip->bad_board = FALSE;
-
- DE_INIT(("init_hw done\n"));
- return err;
-}
-
-
-
-static int set_mixer_defaults(struct echoaudio *chip)
-{
- return init_line_levels(chip);
-}
-
-
-
-static u32 detect_input_clocks(const struct echoaudio *chip)
-{
- return ECHO_CLOCK_BIT_INTERNAL;
-}
-
-
-
-/* The IndigoIO has no ASIC. Just do nothing */
-static int load_asic(struct echoaudio *chip)
-{
- return 0;
-}
-
-
-
-static int set_sample_rate(struct echoaudio *chip, u32 rate)
-{
- if (wait_handshake(chip))
- return -EIO;
-
- chip->sample_rate = rate;
- chip->comm_page->sample_rate = cpu_to_le32(rate);
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
-}
-
-
-
-/* This function routes the sound from a virtual channel to a real output */
-static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
- int gain)
-{
- int index;
-
- if (snd_BUG_ON(pipe >= num_pipes_out(chip) ||
- output >= num_busses_out(chip)))
- return -EINVAL;
-
- if (wait_handshake(chip))
- return -EIO;
-
- chip->vmixer_gain[output][pipe] = gain;
- index = output * num_pipes_out(chip) + pipe;
- chip->comm_page->vmixer[index] = gain;
-
- DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain));
- return 0;
-}
-
-
-
-/* Tell the DSP to read and update virtual mixer levels in comm page. */
-static int update_vmixer_level(struct echoaudio *chip)
-{
- if (wait_handshake(chip))
- return -EIO;
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_SET_VMIXER_GAIN);
-}
-
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigoiox.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigoiox.c
deleted file mode 100644
index 86cf2d07..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/indigoiox.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * ALSA driver for Echoaudio soundcards.
- * Copyright (C) 2009 Giuliano Pochini <pochini@shiny.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#define INDIGO_FAMILY
-#define ECHOCARD_INDIGO_IOX
-#define ECHOCARD_NAME "Indigo IOx"
-#define ECHOCARD_HAS_MONITOR
-#define ECHOCARD_HAS_SUPER_INTERLEAVE
-#define ECHOCARD_HAS_VMIXER
-#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
-
-/* Pipe indexes */
-#define PX_ANALOG_OUT 0 /* 8 */
-#define PX_DIGITAL_OUT 8 /* 0 */
-#define PX_ANALOG_IN 8 /* 2 */
-#define PX_DIGITAL_IN 10 /* 0 */
-#define PX_NUM 10
-
-/* Bus indexes */
-#define BX_ANALOG_OUT 0 /* 2 */
-#define BX_DIGITAL_OUT 2 /* 0 */
-#define BX_ANALOG_IN 2 /* 2 */
-#define BX_DIGITAL_IN 4 /* 0 */
-#define BX_NUM 4
-
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/asoundef.h>
-#include <sound/initval.h>
-#include <linux/atomic.h>
-#include "echoaudio.h"
-
-MODULE_FIRMWARE("ea/loader_dsp.fw");
-MODULE_FIRMWARE("ea/indigo_iox_dsp.fw");
-
-#define FW_361_LOADER 0
-#define FW_INDIGO_IOX_DSP 1
-
-static const struct firmware card_fw[] = {
- {0, "loader_dsp.fw"},
- {0, "indigo_iox_dsp.fw"}
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
- {0x1057, 0x3410, 0xECC0, 0x00D0, 0, 0, 0}, /* Indigo IOx */
- {0,}
-};
-
-static struct snd_pcm_hardware pcm_hardware_skel = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START,
- .formats = SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_S32_BE,
- .rates = SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_64000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000,
- .rate_min = 32000,
- .rate_max = 96000,
- .channels_min = 1,
- .channels_max = 8,
- .buffer_bytes_max = 262144,
- .period_bytes_min = 32,
- .period_bytes_max = 131072,
- .periods_min = 2,
- .periods_max = 220,
-};
-
-#include "indigoiox_dsp.c"
-#include "indigo_express_dsp.c"
-#include "echoaudio_dsp.c"
-#include "echoaudio.c"
-
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigoiox_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigoiox_dsp.c
deleted file mode 100644
index 394c6e76..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/indigoiox_dsp.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/************************************************************************
-
-This file is part of Echo Digital Audio's generic driver library.
-Copyright Echo Digital Audio Corporation (c) 1998 - 2005
-All rights reserved
-www.echoaudio.com
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-*************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
-*************************************************************************/
-
-static int update_vmixer_level(struct echoaudio *chip);
-static int set_vmixer_gain(struct echoaudio *chip, u16 output,
- u16 pipe, int gain);
-
-
-static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
-{
- int err;
-
- DE_INIT(("init_hw() - Indigo IOx\n"));
- if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_IOX))
- return -ENODEV;
-
- err = init_dsp_comm_page(chip);
- if (err < 0) {
- DE_INIT(("init_hw - could not initialize DSP comm page\n"));
- return err;
- }
-
- chip->device_id = device_id;
- chip->subdevice_id = subdevice_id;
- chip->bad_board = TRUE;
- chip->dsp_code_to_load = FW_INDIGO_IOX_DSP;
- /* Since this card has no ASIC, mark it as loaded so everything
- works OK */
- chip->asic_loaded = TRUE;
- chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
-
- err = load_firmware(chip);
- if (err < 0)
- return err;
- chip->bad_board = FALSE;
-
- DE_INIT(("init_hw done\n"));
- return err;
-}
-
-
-
-static int set_mixer_defaults(struct echoaudio *chip)
-{
- return init_line_levels(chip);
-}
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/layla20.c b/ANDROID_3.4.5/sound/pci/echoaudio/layla20.c
deleted file mode 100644
index 6a027f39..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/layla20.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * ALSA driver for Echoaudio soundcards.
- * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#define ECHOGALS_FAMILY
-#define ECHOCARD_LAYLA20
-#define ECHOCARD_NAME "Layla20"
-#define ECHOCARD_HAS_MONITOR
-#define ECHOCARD_HAS_ASIC
-#define ECHOCARD_HAS_INPUT_GAIN
-#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL
-#define ECHOCARD_HAS_SUPER_INTERLEAVE
-#define ECHOCARD_HAS_DIGITAL_IO
-#define ECHOCARD_HAS_EXTERNAL_CLOCK
-#define ECHOCARD_HAS_ADAT FALSE
-#define ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH
-#define ECHOCARD_HAS_MIDI
-
-/* Pipe indexes */
-#define PX_ANALOG_OUT 0 /* 10 */
-#define PX_DIGITAL_OUT 10 /* 2 */
-#define PX_ANALOG_IN 12 /* 8 */
-#define PX_DIGITAL_IN 20 /* 2 */
-#define PX_NUM 22
-
-/* Bus indexes */
-#define BX_ANALOG_OUT 0 /* 10 */
-#define BX_DIGITAL_OUT 10 /* 2 */
-#define BX_ANALOG_IN 12 /* 8 */
-#define BX_DIGITAL_IN 20 /* 2 */
-#define BX_NUM 22
-
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/asoundef.h>
-#include <sound/initval.h>
-#include <sound/rawmidi.h>
-#include <asm/io.h>
-#include <linux/atomic.h>
-#include "echoaudio.h"
-
-MODULE_FIRMWARE("ea/layla20_dsp.fw");
-MODULE_FIRMWARE("ea/layla20_asic.fw");
-
-#define FW_LAYLA20_DSP 0
-#define FW_LAYLA20_ASIC 1
-
-static const struct firmware card_fw[] = {
- {0, "layla20_dsp.fw"},
- {0, "layla20_asic.fw"}
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
- {0x1057, 0x1801, 0xECC0, 0x0030, 0, 0, 0}, /* DSP 56301 Layla20 rev.0 */
- {0x1057, 0x1801, 0xECC0, 0x0031, 0, 0, 0}, /* DSP 56301 Layla20 rev.1 */
- {0,}
-};
-
-static struct snd_pcm_hardware pcm_hardware_skel = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START,
- .formats = SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_S32_BE,
- .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 8000,
- .rate_max = 50000,
- .channels_min = 1,
- .channels_max = 10,
- .buffer_bytes_max = 262144,
- .period_bytes_min = 32,
- .period_bytes_max = 131072,
- .periods_min = 2,
- .periods_max = 220,
- /* One page (4k) contains 512 instructions. I don't know if the hw
- supports lists longer than this. In this case periods_max=220 is a
- safe limit to make sure the list never exceeds 512 instructions. */
-};
-
-#include "layla20_dsp.c"
-#include "echoaudio_dsp.c"
-#include "echoaudio.c"
-#include "midi.c"
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/layla20_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/layla20_dsp.c
deleted file mode 100644
index 53ce9460..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/layla20_dsp.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/****************************************************************************
-
- Copyright Echo Digital Audio Corporation (c) 1998 - 2004
- All rights reserved
- www.echoaudio.com
-
- This file is part of Echo Digital Audio's generic driver library.
-
- Echo Digital Audio's generic driver library is free software;
- you can redistribute it and/or modify it under the terms of
- the GNU General Public License as published by the Free Software
- Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- *************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
-****************************************************************************/
-
-
-static int read_dsp(struct echoaudio *chip, u32 *data);
-static int set_professional_spdif(struct echoaudio *chip, char prof);
-static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
-static int check_asic_status(struct echoaudio *chip);
-static int update_flags(struct echoaudio *chip);
-
-
-static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
-{
- int err;
-
- DE_INIT(("init_hw() - Layla20\n"));
- if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA20))
- return -ENODEV;
-
- if ((err = init_dsp_comm_page(chip))) {
- DE_INIT(("init_hw - could not initialize DSP comm page\n"));
- return err;
- }
-
- chip->device_id = device_id;
- chip->subdevice_id = subdevice_id;
- chip->bad_board = TRUE;
- chip->has_midi = TRUE;
- chip->dsp_code_to_load = FW_LAYLA20_DSP;
- chip->input_clock_types =
- ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
- ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
- chip->output_clock_types =
- ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
-
- if ((err = load_firmware(chip)) < 0)
- return err;
- chip->bad_board = FALSE;
-
- DE_INIT(("init_hw done\n"));
- return err;
-}
-
-
-
-static int set_mixer_defaults(struct echoaudio *chip)
-{
- chip->professional_spdif = FALSE;
- return init_line_levels(chip);
-}
-
-
-
-static u32 detect_input_clocks(const struct echoaudio *chip)
-{
- u32 clocks_from_dsp, clock_bits;
-
- /* Map the DSP clock detect bits to the generic driver clock detect bits */
- clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
-
- clock_bits = ECHO_CLOCK_BIT_INTERNAL;
-
- if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF)
- clock_bits |= ECHO_CLOCK_BIT_SPDIF;
-
- if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_WORD) {
- if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SUPER)
- clock_bits |= ECHO_CLOCK_BIT_SUPER;
- else
- clock_bits |= ECHO_CLOCK_BIT_WORD;
- }
-
- return clock_bits;
-}
-
-
-
-/* ASIC status check - some cards have one or two ASICs that need to be
-loaded. Once that load is complete, this function is called to see if
-the load was successful.
-If this load fails, it does not necessarily mean that the hardware is
-defective - the external box may be disconnected or turned off.
-This routine sometimes fails for Layla20; for Layla20, the loop runs
-5 times and succeeds if it wins on three of the loops. */
-static int check_asic_status(struct echoaudio *chip)
-{
- u32 asic_status;
- int goodcnt, i;
-
- chip->asic_loaded = FALSE;
- for (i = goodcnt = 0; i < 5; i++) {
- send_vector(chip, DSP_VC_TEST_ASIC);
-
- /* The DSP will return a value to indicate whether or not
- the ASIC is currently loaded */
- if (read_dsp(chip, &asic_status) < 0) {
- DE_ACT(("check_asic_status: failed on read_dsp\n"));
- return -EIO;
- }
-
- if (asic_status == ASIC_ALREADY_LOADED) {
- if (++goodcnt == 3) {
- chip->asic_loaded = TRUE;
- return 0;
- }
- }
- }
- return -EIO;
-}
-
-
-
-/* Layla20 has an ASIC in the external box */
-static int load_asic(struct echoaudio *chip)
-{
- int err;
-
- if (chip->asic_loaded)
- return 0;
-
- err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC,
- FW_LAYLA20_ASIC);
- if (err < 0)
- return err;
-
- /* Check if ASIC is alive and well. */
- return check_asic_status(chip);
-}
-
-
-
-static int set_sample_rate(struct echoaudio *chip, u32 rate)
-{
- if (snd_BUG_ON(rate < 8000 || rate > 50000))
- return -EINVAL;
-
- /* Only set the clock for internal mode. Do not return failure,
- simply treat it as a non-event. */
- if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
- DE_ACT(("set_sample_rate: Cannot set sample rate - "
- "clock not set to CLK_CLOCKININTERNAL\n"));
- chip->comm_page->sample_rate = cpu_to_le32(rate);
- chip->sample_rate = rate;
- return 0;
- }
-
- if (wait_handshake(chip))
- return -EIO;
-
- DE_ACT(("set_sample_rate(%d)\n", rate));
- chip->sample_rate = rate;
- chip->comm_page->sample_rate = cpu_to_le32(rate);
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_SET_LAYLA_SAMPLE_RATE);
-}
-
-
-
-static int set_input_clock(struct echoaudio *chip, u16 clock_source)
-{
- u16 clock;
- u32 rate;
-
- DE_ACT(("set_input_clock:\n"));
- rate = 0;
- switch (clock_source) {
- case ECHO_CLOCK_INTERNAL:
- DE_ACT(("Set Layla20 clock to INTERNAL\n"));
- rate = chip->sample_rate;
- clock = LAYLA20_CLOCK_INTERNAL;
- break;
- case ECHO_CLOCK_SPDIF:
- DE_ACT(("Set Layla20 clock to SPDIF\n"));
- clock = LAYLA20_CLOCK_SPDIF;
- break;
- case ECHO_CLOCK_WORD:
- DE_ACT(("Set Layla20 clock to WORD\n"));
- clock = LAYLA20_CLOCK_WORD;
- break;
- case ECHO_CLOCK_SUPER:
- DE_ACT(("Set Layla20 clock to SUPER\n"));
- clock = LAYLA20_CLOCK_SUPER;
- break;
- default:
- DE_ACT(("Input clock 0x%x not supported for Layla24\n",
- clock_source));
- return -EINVAL;
- }
- chip->input_clock = clock_source;
-
- chip->comm_page->input_clock = cpu_to_le16(clock);
- clear_handshake(chip);
- send_vector(chip, DSP_VC_UPDATE_CLOCKS);
-
- if (rate)
- set_sample_rate(chip, rate);
-
- return 0;
-}
-
-
-
-static int set_output_clock(struct echoaudio *chip, u16 clock)
-{
- DE_ACT(("set_output_clock: %d\n", clock));
- switch (clock) {
- case ECHO_CLOCK_SUPER:
- clock = LAYLA20_OUTPUT_CLOCK_SUPER;
- break;
- case ECHO_CLOCK_WORD:
- clock = LAYLA20_OUTPUT_CLOCK_WORD;
- break;
- default:
- DE_ACT(("set_output_clock wrong clock\n"));
- return -EINVAL;
- }
-
- if (wait_handshake(chip))
- return -EIO;
-
- chip->comm_page->output_clock = cpu_to_le16(clock);
- chip->output_clock = clock;
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
-}
-
-
-
-/* Set input bus gain (one unit is 0.5dB !) */
-static int set_input_gain(struct echoaudio *chip, u16 input, int gain)
-{
- if (snd_BUG_ON(input >= num_busses_in(chip)))
- return -EINVAL;
-
- if (wait_handshake(chip))
- return -EIO;
-
- chip->input_gain[input] = gain;
- gain += GL20_INPUT_GAIN_MAGIC_NUMBER;
- chip->comm_page->line_in_level[input] = gain;
- return 0;
-}
-
-
-
-/* Tell the DSP to reread the flags from the comm page */
-static int update_flags(struct echoaudio *chip)
-{
- if (wait_handshake(chip))
- return -EIO;
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_UPDATE_FLAGS);
-}
-
-
-
-static int set_professional_spdif(struct echoaudio *chip, char prof)
-{
- DE_ACT(("set_professional_spdif %d\n", prof));
- if (prof)
- chip->comm_page->flags |=
- cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
- else
- chip->comm_page->flags &=
- ~cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
- chip->professional_spdif = prof;
- return update_flags(chip);
-}
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/layla24.c b/ANDROID_3.4.5/sound/pci/echoaudio/layla24.c
deleted file mode 100644
index 96a5991a..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/layla24.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * ALSA driver for Echoaudio soundcards.
- * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#define ECHO24_FAMILY
-#define ECHOCARD_LAYLA24
-#define ECHOCARD_NAME "Layla24"
-#define ECHOCARD_HAS_MONITOR
-#define ECHOCARD_HAS_ASIC
-#define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL
-#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL
-#define ECHOCARD_HAS_SUPER_INTERLEAVE
-#define ECHOCARD_HAS_DIGITAL_IO
-#define ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE
-#define ECHOCARD_HAS_DIGITAL_MODE_SWITCH
-#define ECHOCARD_HAS_EXTERNAL_CLOCK
-#define ECHOCARD_HAS_ADAT 6
-#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
-#define ECHOCARD_HAS_MIDI
-
-/* Pipe indexes */
-#define PX_ANALOG_OUT 0 /* 8 */
-#define PX_DIGITAL_OUT 8 /* 8 */
-#define PX_ANALOG_IN 16 /* 8 */
-#define PX_DIGITAL_IN 24 /* 8 */
-#define PX_NUM 32
-
-/* Bus indexes */
-#define BX_ANALOG_OUT 0 /* 8 */
-#define BX_DIGITAL_OUT 8 /* 8 */
-#define BX_ANALOG_IN 16 /* 8 */
-#define BX_DIGITAL_IN 24 /* 8 */
-#define BX_NUM 32
-
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/asoundef.h>
-#include <sound/initval.h>
-#include <sound/rawmidi.h>
-#include <asm/io.h>
-#include <linux/atomic.h>
-#include "echoaudio.h"
-
-MODULE_FIRMWARE("ea/loader_dsp.fw");
-MODULE_FIRMWARE("ea/layla24_dsp.fw");
-MODULE_FIRMWARE("ea/layla24_1_asic.fw");
-MODULE_FIRMWARE("ea/layla24_2A_asic.fw");
-MODULE_FIRMWARE("ea/layla24_2S_asic.fw");
-
-#define FW_361_LOADER 0
-#define FW_LAYLA24_DSP 1
-#define FW_LAYLA24_1_ASIC 2
-#define FW_LAYLA24_2A_ASIC 3
-#define FW_LAYLA24_2S_ASIC 4
-
-static const struct firmware card_fw[] = {
- {0, "loader_dsp.fw"},
- {0, "layla24_dsp.fw"},
- {0, "layla24_1_asic.fw"},
- {0, "layla24_2A_asic.fw"},
- {0, "layla24_2S_asic.fw"}
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
- {0x1057, 0x3410, 0xECC0, 0x0060, 0, 0, 0}, /* DSP 56361 Layla24 rev.0 */
- {0,}
-};
-
-static struct snd_pcm_hardware pcm_hardware_skel = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START,
- .formats = SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_S32_BE,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .rate_min = 8000,
- .rate_max = 100000,
- .channels_min = 1,
- .channels_max = 8,
- .buffer_bytes_max = 262144,
- .period_bytes_min = 32,
- .period_bytes_max = 131072,
- .periods_min = 2,
- .periods_max = 220,
- /* One page (4k) contains 512 instructions. I don't know if the hw
- supports lists longer than this. In this case periods_max=220 is a
- safe limit to make sure the list never exceeds 512 instructions. */
-};
-
-
-#include "layla24_dsp.c"
-#include "echoaudio_dsp.c"
-#include "echoaudio_gml.c"
-#include "echoaudio.c"
-#include "midi.c"
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/layla24_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/layla24_dsp.c
deleted file mode 100644
index 8c041647..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/layla24_dsp.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/****************************************************************************
-
- Copyright Echo Digital Audio Corporation (c) 1998 - 2004
- All rights reserved
- www.echoaudio.com
-
- This file is part of Echo Digital Audio's generic driver library.
-
- Echo Digital Audio's generic driver library is free software;
- you can redistribute it and/or modify it under the terms of
- the GNU General Public License as published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- *************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
-****************************************************************************/
-
-
-static int write_control_reg(struct echoaudio *chip, u32 value, char force);
-static int set_input_clock(struct echoaudio *chip, u16 clock);
-static int set_professional_spdif(struct echoaudio *chip, char prof);
-static int set_digital_mode(struct echoaudio *chip, u8 mode);
-static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
-static int check_asic_status(struct echoaudio *chip);
-
-
-static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
-{
- int err;
-
- DE_INIT(("init_hw() - Layla24\n"));
- if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA24))
- return -ENODEV;
-
- if ((err = init_dsp_comm_page(chip))) {
- DE_INIT(("init_hw - could not initialize DSP comm page\n"));
- return err;
- }
-
- chip->device_id = device_id;
- chip->subdevice_id = subdevice_id;
- chip->bad_board = TRUE;
- chip->has_midi = TRUE;
- chip->dsp_code_to_load = FW_LAYLA24_DSP;
- chip->input_clock_types =
- ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
- ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT;
- chip->digital_modes =
- ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
- ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
- ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
-
- if ((err = load_firmware(chip)) < 0)
- return err;
- chip->bad_board = FALSE;
-
- if ((err = init_line_levels(chip)) < 0)
- return err;
-
- DE_INIT(("init_hw done\n"));
- return err;
-}
-
-
-
-static int set_mixer_defaults(struct echoaudio *chip)
-{
- chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
- chip->professional_spdif = FALSE;
- chip->digital_in_automute = TRUE;
- return init_line_levels(chip);
-}
-
-
-
-static u32 detect_input_clocks(const struct echoaudio *chip)
-{
- u32 clocks_from_dsp, clock_bits;
-
- /* Map the DSP clock detect bits to the generic driver clock detect bits */
- clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
-
- clock_bits = ECHO_CLOCK_BIT_INTERNAL;
-
- if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF)
- clock_bits |= ECHO_CLOCK_BIT_SPDIF;
-
- if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT)
- clock_bits |= ECHO_CLOCK_BIT_ADAT;
-
- if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD)
- clock_bits |= ECHO_CLOCK_BIT_WORD;
-
- return clock_bits;
-}
-
-
-
-/* Layla24 has an ASIC on the PCI card and another ASIC in the external box;
-both need to be loaded. */
-static int load_asic(struct echoaudio *chip)
-{
- int err;
-
- if (chip->asic_loaded)
- return 1;
-
- DE_INIT(("load_asic\n"));
-
- /* Give the DSP a few milliseconds to settle down */
- mdelay(10);
-
- /* Load the ASIC for the PCI card */
- err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC,
- FW_LAYLA24_1_ASIC);
- if (err < 0)
- return err;
-
- chip->asic_code = FW_LAYLA24_2S_ASIC;
-
- /* Now give the new ASIC a little time to set up */
- mdelay(10);
-
- /* Do the external one */
- err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC,
- FW_LAYLA24_2S_ASIC);
- if (err < 0)
- return FALSE;
-
- /* Now give the external ASIC a little time to set up */
- mdelay(10);
-
- /* See if it worked */
- err = check_asic_status(chip);
-
- /* Set up the control register if the load succeeded -
- 48 kHz, internal clock, S/PDIF RCA mode */
- if (!err)
- err = write_control_reg(chip, GML_CONVERTER_ENABLE | GML_48KHZ,
- TRUE);
-
- DE_INIT(("load_asic() done\n"));
- return err;
-}
-
-
-
-static int set_sample_rate(struct echoaudio *chip, u32 rate)
-{
- u32 control_reg, clock, base_rate;
-
- if (snd_BUG_ON(rate >= 50000 &&
- chip->digital_mode == DIGITAL_MODE_ADAT))
- return -EINVAL;
-
- /* Only set the clock for internal mode. */
- if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
- DE_ACT(("set_sample_rate: Cannot set sample rate - "
- "clock not set to CLK_CLOCKININTERNAL\n"));
- /* Save the rate anyhow */
- chip->comm_page->sample_rate = cpu_to_le32(rate);
- chip->sample_rate = rate;
- return 0;
- }
-
- /* Get the control register & clear the appropriate bits */
- control_reg = le32_to_cpu(chip->comm_page->control_register);
- control_reg &= GML_CLOCK_CLEAR_MASK & GML_SPDIF_RATE_CLEAR_MASK;
-
- clock = 0;
-
- switch (rate) {
- case 96000:
- clock = GML_96KHZ;
- break;
- case 88200:
- clock = GML_88KHZ;
- break;
- case 48000:
- clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1;
- break;
- case 44100:
- clock = GML_44KHZ;
- /* Professional mode */
- if (control_reg & GML_SPDIF_PRO_MODE)
- clock |= GML_SPDIF_SAMPLE_RATE0;
- break;
- case 32000:
- clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 |
- GML_SPDIF_SAMPLE_RATE1;
- break;
- case 22050:
- clock = GML_22KHZ;
- break;
- case 16000:
- clock = GML_16KHZ;
- break;
- case 11025:
- clock = GML_11KHZ;
- break;
- case 8000:
- clock = GML_8KHZ;
- break;
- default:
- /* If this is a non-standard rate, then the driver needs to
- use Layla24's special "continuous frequency" mode */
- clock = LAYLA24_CONTINUOUS_CLOCK;
- if (rate > 50000) {
- base_rate = rate >> 1;
- control_reg |= GML_DOUBLE_SPEED_MODE;
- } else {
- base_rate = rate;
- }
-
- if (base_rate < 25000)
- base_rate = 25000;
-
- if (wait_handshake(chip))
- return -EIO;
-
- chip->comm_page->sample_rate =
- cpu_to_le32(LAYLA24_MAGIC_NUMBER / base_rate - 2);
-
- clear_handshake(chip);
- send_vector(chip, DSP_VC_SET_LAYLA24_FREQUENCY_REG);
- }
-
- control_reg |= clock;
-
- chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP ? */
- chip->sample_rate = rate;
- DE_ACT(("set_sample_rate: %d clock %d\n", rate, control_reg));
-
- return write_control_reg(chip, control_reg, FALSE);
-}
-
-
-
-static int set_input_clock(struct echoaudio *chip, u16 clock)
-{
- u32 control_reg, clocks_from_dsp;
-
- /* Mask off the clock select bits */
- control_reg = le32_to_cpu(chip->comm_page->control_register) &
- GML_CLOCK_CLEAR_MASK;
- clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
-
- /* Pick the new clock */
- switch (clock) {
- case ECHO_CLOCK_INTERNAL:
- DE_ACT(("Set Layla24 clock to INTERNAL\n"));
- chip->input_clock = ECHO_CLOCK_INTERNAL;
- return set_sample_rate(chip, chip->sample_rate);
- case ECHO_CLOCK_SPDIF:
- if (chip->digital_mode == DIGITAL_MODE_ADAT)
- return -EAGAIN;
- control_reg |= GML_SPDIF_CLOCK;
- /* Layla24 doesn't support 96KHz S/PDIF */
- control_reg &= ~GML_DOUBLE_SPEED_MODE;
- DE_ACT(("Set Layla24 clock to SPDIF\n"));
- break;
- case ECHO_CLOCK_WORD:
- control_reg |= GML_WORD_CLOCK;
- if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96)
- control_reg |= GML_DOUBLE_SPEED_MODE;
- else
- control_reg &= ~GML_DOUBLE_SPEED_MODE;
- DE_ACT(("Set Layla24 clock to WORD\n"));
- break;
- case ECHO_CLOCK_ADAT:
- if (chip->digital_mode != DIGITAL_MODE_ADAT)
- return -EAGAIN;
- control_reg |= GML_ADAT_CLOCK;
- control_reg &= ~GML_DOUBLE_SPEED_MODE;
- DE_ACT(("Set Layla24 clock to ADAT\n"));
- break;
- default:
- DE_ACT(("Input clock 0x%x not supported for Layla24\n", clock));
- return -EINVAL;
- }
-
- chip->input_clock = clock;
- return write_control_reg(chip, control_reg, TRUE);
-}
-
-
-
-/* Depending on what digital mode you want, Layla24 needs different ASICs
-loaded. This function checks the ASIC needed for the new mode and sees
-if it matches the one already loaded. */
-static int switch_asic(struct echoaudio *chip, short asic)
-{
- s8 *monitors;
-
- /* Check to see if this is already loaded */
- if (asic != chip->asic_code) {
- monitors = kmemdup(chip->comm_page->monitors,
- MONITOR_ARRAY_SIZE, GFP_KERNEL);
- if (! monitors)
- return -ENOMEM;
-
- memset(chip->comm_page->monitors, ECHOGAIN_MUTED,
- MONITOR_ARRAY_SIZE);
-
- /* Load the desired ASIC */
- if (load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC,
- asic) < 0) {
- memcpy(chip->comm_page->monitors, monitors,
- MONITOR_ARRAY_SIZE);
- kfree(monitors);
- return -EIO;
- }
- chip->asic_code = asic;
- memcpy(chip->comm_page->monitors, monitors, MONITOR_ARRAY_SIZE);
- kfree(monitors);
- }
-
- return 0;
-}
-
-
-
-static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
-{
- u32 control_reg;
- int err, incompatible_clock;
- short asic;
-
- /* Set clock to "internal" if it's not compatible with the new mode */
- incompatible_clock = FALSE;
- switch (mode) {
- case DIGITAL_MODE_SPDIF_OPTICAL:
- case DIGITAL_MODE_SPDIF_RCA:
- if (chip->input_clock == ECHO_CLOCK_ADAT)
- incompatible_clock = TRUE;
- asic = FW_LAYLA24_2S_ASIC;
- break;
- case DIGITAL_MODE_ADAT:
- if (chip->input_clock == ECHO_CLOCK_SPDIF)
- incompatible_clock = TRUE;
- asic = FW_LAYLA24_2A_ASIC;
- break;
- default:
- DE_ACT(("Digital mode not supported: %d\n", mode));
- return -EINVAL;
- }
-
- if (incompatible_clock) { /* Switch to 48KHz, internal */
- chip->sample_rate = 48000;
- spin_lock_irq(&chip->lock);
- set_input_clock(chip, ECHO_CLOCK_INTERNAL);
- spin_unlock_irq(&chip->lock);
- }
-
- /* switch_asic() can sleep */
- if (switch_asic(chip, asic) < 0)
- return -EIO;
-
- spin_lock_irq(&chip->lock);
-
- /* Tweak the control register */
- control_reg = le32_to_cpu(chip->comm_page->control_register);
- control_reg &= GML_DIGITAL_MODE_CLEAR_MASK;
-
- switch (mode) {
- case DIGITAL_MODE_SPDIF_OPTICAL:
- control_reg |= GML_SPDIF_OPTICAL_MODE;
- break;
- case DIGITAL_MODE_SPDIF_RCA:
- /* GML_SPDIF_OPTICAL_MODE bit cleared */
- break;
- case DIGITAL_MODE_ADAT:
- control_reg |= GML_ADAT_MODE;
- control_reg &= ~GML_DOUBLE_SPEED_MODE;
- break;
- }
-
- err = write_control_reg(chip, control_reg, TRUE);
- spin_unlock_irq(&chip->lock);
- if (err < 0)
- return err;
- chip->digital_mode = mode;
-
- DE_ACT(("set_digital_mode to %d\n", mode));
- return incompatible_clock;
-}
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/mia.c b/ANDROID_3.4.5/sound/pci/echoaudio/mia.c
deleted file mode 100644
index b8ce27e6..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/mia.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * ALSA driver for Echoaudio soundcards.
- * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#define ECHO24_FAMILY
-#define ECHOCARD_MIA
-#define ECHOCARD_NAME "Mia"
-#define ECHOCARD_HAS_MONITOR
-#define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL
-#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL
-#define ECHOCARD_HAS_SUPER_INTERLEAVE
-#define ECHOCARD_HAS_VMIXER
-#define ECHOCARD_HAS_DIGITAL_IO
-#define ECHOCARD_HAS_EXTERNAL_CLOCK
-#define ECHOCARD_HAS_ADAT FALSE
-#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
-#define ECHOCARD_HAS_MIDI
-#define ECHOCARD_HAS_LINE_OUT_GAIN
-
-/* Pipe indexes */
-#define PX_ANALOG_OUT 0 /* 8 */
-#define PX_DIGITAL_OUT 8 /* 0 */
-#define PX_ANALOG_IN 8 /* 2 */
-#define PX_DIGITAL_IN 10 /* 2 */
-#define PX_NUM 12
-
-/* Bus indexes */
-#define BX_ANALOG_OUT 0 /* 2 */
-#define BX_DIGITAL_OUT 2 /* 2 */
-#define BX_ANALOG_IN 4 /* 2 */
-#define BX_DIGITAL_IN 6 /* 2 */
-#define BX_NUM 8
-
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/asoundef.h>
-#include <sound/initval.h>
-#include <sound/rawmidi.h>
-#include <asm/io.h>
-#include <linux/atomic.h>
-#include "echoaudio.h"
-
-MODULE_FIRMWARE("ea/loader_dsp.fw");
-MODULE_FIRMWARE("ea/mia_dsp.fw");
-
-#define FW_361_LOADER 0
-#define FW_MIA_DSP 1
-
-static const struct firmware card_fw[] = {
- {0, "loader_dsp.fw"},
- {0, "mia_dsp.fw"}
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
- {0x1057, 0x3410, 0xECC0, 0x0080, 0, 0, 0}, /* DSP 56361 Mia rev.0 */
- {0x1057, 0x3410, 0xECC0, 0x0081, 0, 0, 0}, /* DSP 56361 Mia rev.1 */
- {0,}
-};
-
-static struct snd_pcm_hardware pcm_hardware_skel = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START,
- .formats = SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_S32_BE,
- .rates = SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000,
- .rate_min = 8000,
- .rate_max = 96000,
- .channels_min = 1,
- .channels_max = 8,
- .buffer_bytes_max = 262144,
- .period_bytes_min = 32,
- .period_bytes_max = 131072,
- .periods_min = 2,
- .periods_max = 220,
- /* One page (4k) contains 512 instructions. I don't know if the hw
- supports lists longer than this. In this case periods_max=220 is a
- safe limit to make sure the list never exceeds 512 instructions. */
-};
-
-
-#include "mia_dsp.c"
-#include "echoaudio_dsp.c"
-#include "echoaudio.c"
-#include "midi.c"
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/mia_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/mia_dsp.c
deleted file mode 100644
index 6ebfa6e7..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/mia_dsp.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/****************************************************************************
-
- Copyright Echo Digital Audio Corporation (c) 1998 - 2004
- All rights reserved
- www.echoaudio.com
-
- This file is part of Echo Digital Audio's generic driver library.
-
- Echo Digital Audio's generic driver library is free software;
- you can redistribute it and/or modify it under the terms of
- the GNU General Public License as published by the Free Software
- Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- *************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
-****************************************************************************/
-
-
-static int set_input_clock(struct echoaudio *chip, u16 clock);
-static int set_professional_spdif(struct echoaudio *chip, char prof);
-static int update_flags(struct echoaudio *chip);
-static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
- int gain);
-static int update_vmixer_level(struct echoaudio *chip);
-
-
-static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
-{
- int err;
-
- DE_INIT(("init_hw() - Mia\n"));
- if (snd_BUG_ON((subdevice_id & 0xfff0) != MIA))
- return -ENODEV;
-
- if ((err = init_dsp_comm_page(chip))) {
- DE_INIT(("init_hw - could not initialize DSP comm page\n"));
- return err;
- }
-
- chip->device_id = device_id;
- chip->subdevice_id = subdevice_id;
- chip->bad_board = TRUE;
- chip->dsp_code_to_load = FW_MIA_DSP;
- /* Since this card has no ASIC, mark it as loaded so everything
- works OK */
- chip->asic_loaded = TRUE;
- if ((subdevice_id & 0x0000f) == MIA_MIDI_REV)
- chip->has_midi = TRUE;
- chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL |
- ECHO_CLOCK_BIT_SPDIF;
-
- if ((err = load_firmware(chip)) < 0)
- return err;
- chip->bad_board = FALSE;
-
- DE_INIT(("init_hw done\n"));
- return err;
-}
-
-
-
-static int set_mixer_defaults(struct echoaudio *chip)
-{
- return init_line_levels(chip);
-}
-
-
-
-static u32 detect_input_clocks(const struct echoaudio *chip)
-{
- u32 clocks_from_dsp, clock_bits;
-
- /* Map the DSP clock detect bits to the generic driver clock
- detect bits */
- clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
-
- clock_bits = ECHO_CLOCK_BIT_INTERNAL;
-
- if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF)
- clock_bits |= ECHO_CLOCK_BIT_SPDIF;
-
- return clock_bits;
-}
-
-
-
-/* The Mia has no ASIC. Just do nothing */
-static int load_asic(struct echoaudio *chip)
-{
- return 0;
-}
-
-
-
-static int set_sample_rate(struct echoaudio *chip, u32 rate)
-{
- u32 control_reg;
-
- switch (rate) {
- case 96000:
- control_reg = MIA_96000;
- break;
- case 88200:
- control_reg = MIA_88200;
- break;
- case 48000:
- control_reg = MIA_48000;
- break;
- case 44100:
- control_reg = MIA_44100;
- break;
- case 32000:
- control_reg = MIA_32000;
- break;
- default:
- DE_ACT(("set_sample_rate: %d invalid!\n", rate));
- return -EINVAL;
- }
-
- /* Override the clock setting if this Mia is set to S/PDIF clock */
- if (chip->input_clock == ECHO_CLOCK_SPDIF)
- control_reg |= MIA_SPDIF;
-
- /* Set the control register if it has changed */
- if (control_reg != le32_to_cpu(chip->comm_page->control_register)) {
- if (wait_handshake(chip))
- return -EIO;
-
- chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */
- chip->comm_page->control_register = cpu_to_le32(control_reg);
- chip->sample_rate = rate;
-
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
- }
- return 0;
-}
-
-
-
-static int set_input_clock(struct echoaudio *chip, u16 clock)
-{
- DE_ACT(("set_input_clock(%d)\n", clock));
- if (snd_BUG_ON(clock != ECHO_CLOCK_INTERNAL &&
- clock != ECHO_CLOCK_SPDIF))
- return -EINVAL;
-
- chip->input_clock = clock;
- return set_sample_rate(chip, chip->sample_rate);
-}
-
-
-
-/* This function routes the sound from a virtual channel to a real output */
-static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
- int gain)
-{
- int index;
-
- if (snd_BUG_ON(pipe >= num_pipes_out(chip) ||
- output >= num_busses_out(chip)))
- return -EINVAL;
-
- if (wait_handshake(chip))
- return -EIO;
-
- chip->vmixer_gain[output][pipe] = gain;
- index = output * num_pipes_out(chip) + pipe;
- chip->comm_page->vmixer[index] = gain;
-
- DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain));
- return 0;
-}
-
-
-
-/* Tell the DSP to read and update virtual mixer levels in comm page. */
-static int update_vmixer_level(struct echoaudio *chip)
-{
- if (wait_handshake(chip))
- return -EIO;
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_SET_VMIXER_GAIN);
-}
-
-
-
-/* Tell the DSP to reread the flags from the comm page */
-static int update_flags(struct echoaudio *chip)
-{
- if (wait_handshake(chip))
- return -EIO;
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_UPDATE_FLAGS);
-}
-
-
-
-static int set_professional_spdif(struct echoaudio *chip, char prof)
-{
- DE_ACT(("set_professional_spdif %d\n", prof));
- if (prof)
- chip->comm_page->flags |=
- cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
- else
- chip->comm_page->flags &=
- ~cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
- chip->professional_spdif = prof;
- return update_flags(chip);
-}
-
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/midi.c b/ANDROID_3.4.5/sound/pci/echoaudio/midi.c
deleted file mode 100644
index a953d142..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/midi.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/****************************************************************************
-
- Copyright Echo Digital Audio Corporation (c) 1998 - 2004
- All rights reserved
- www.echoaudio.com
-
- This file is part of Echo Digital Audio's generic driver library.
-
- Echo Digital Audio's generic driver library is free software;
- you can redistribute it and/or modify it under the terms of
- the GNU General Public License as published by the Free Software
- Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- *************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
-****************************************************************************/
-
-
-/******************************************************************************
- MIDI lowlevel code
-******************************************************************************/
-
-/* Start and stop Midi input */
-static int enable_midi_input(struct echoaudio *chip, char enable)
-{
- DE_MID(("enable_midi_input(%d)\n", enable));
-
- if (wait_handshake(chip))
- return -EIO;
-
- if (enable) {
- chip->mtc_state = MIDI_IN_STATE_NORMAL;
- chip->comm_page->flags |=
- cpu_to_le32(DSP_FLAG_MIDI_INPUT);
- } else
- chip->comm_page->flags &=
- ~cpu_to_le32(DSP_FLAG_MIDI_INPUT);
-
- clear_handshake(chip);
- return send_vector(chip, DSP_VC_UPDATE_FLAGS);
-}
-
-
-
-/* Send a buffer full of MIDI data to the DSP
-Returns how many actually written or < 0 on error */
-static int write_midi(struct echoaudio *chip, u8 *data, int bytes)
-{
- if (snd_BUG_ON(bytes <= 0 || bytes >= MIDI_OUT_BUFFER_SIZE))
- return -EINVAL;
-
- if (wait_handshake(chip))
- return -EIO;
-
- /* HF4 indicates that it is safe to write MIDI output data */
- if (! (get_dsp_register(chip, CHI32_STATUS_REG) & CHI32_STATUS_REG_HF4))
- return 0;
-
- chip->comm_page->midi_output[0] = bytes;
- memcpy(&chip->comm_page->midi_output[1], data, bytes);
- chip->comm_page->midi_out_free_count = 0;
- clear_handshake(chip);
- send_vector(chip, DSP_VC_MIDI_WRITE);
- DE_MID(("write_midi: %d\n", bytes));
- return bytes;
-}
-
-
-
-/* Run the state machine for MIDI input data
-MIDI time code sync isn't supported by this code right now, but you still need
-this state machine to parse the incoming MIDI data stream. Every time the DSP
-sees a 0xF1 byte come in, it adds the DSP sample position to the MIDI data
-stream. The DSP sample position is represented as a 32 bit unsigned value,
-with the high 16 bits first, followed by the low 16 bits. Since these aren't
-real MIDI bytes, the following logic is needed to skip them. */
-static inline int mtc_process_data(struct echoaudio *chip, short midi_byte)
-{
- switch (chip->mtc_state) {
- case MIDI_IN_STATE_NORMAL:
- if (midi_byte == 0xF1)
- chip->mtc_state = MIDI_IN_STATE_TS_HIGH;
- break;
- case MIDI_IN_STATE_TS_HIGH:
- chip->mtc_state = MIDI_IN_STATE_TS_LOW;
- return MIDI_IN_SKIP_DATA;
- break;
- case MIDI_IN_STATE_TS_LOW:
- chip->mtc_state = MIDI_IN_STATE_F1_DATA;
- return MIDI_IN_SKIP_DATA;
- break;
- case MIDI_IN_STATE_F1_DATA:
- chip->mtc_state = MIDI_IN_STATE_NORMAL;
- break;
- }
- return 0;
-}
-
-
-
-/* This function is called from the IRQ handler and it reads the midi data
-from the DSP's buffer. It returns the number of bytes received. */
-static int midi_service_irq(struct echoaudio *chip)
-{
- short int count, midi_byte, i, received;
-
- /* The count is at index 0, followed by actual data */
- count = le16_to_cpu(chip->comm_page->midi_input[0]);
-
- if (snd_BUG_ON(count >= MIDI_IN_BUFFER_SIZE))
- return 0;
-
- /* Get the MIDI data from the comm page */
- i = 1;
- received = 0;
- for (i = 1; i <= count; i++) {
- /* Get the MIDI byte */
- midi_byte = le16_to_cpu(chip->comm_page->midi_input[i]);
-
- /* Parse the incoming MIDI stream. The incoming MIDI data
- consists of MIDI bytes and timestamps for the MIDI time code
- 0xF1 bytes. mtc_process_data() is a little state machine that
- parses the stream. If you get MIDI_IN_SKIP_DATA back, then
- this is a timestamp byte, not a MIDI byte, so don't store it
- in the MIDI input buffer. */
- if (mtc_process_data(chip, midi_byte) == MIDI_IN_SKIP_DATA)
- continue;
-
- chip->midi_buffer[received++] = (u8)midi_byte;
- }
-
- return received;
-}
-
-
-
-
-/******************************************************************************
- MIDI interface
-******************************************************************************/
-
-static int snd_echo_midi_input_open(struct snd_rawmidi_substream *substream)
-{
- struct echoaudio *chip = substream->rmidi->private_data;
-
- chip->midi_in = substream;
- DE_MID(("rawmidi_iopen\n"));
- return 0;
-}
-
-
-
-static void snd_echo_midi_input_trigger(struct snd_rawmidi_substream *substream,
- int up)
-{
- struct echoaudio *chip = substream->rmidi->private_data;
-
- if (up != chip->midi_input_enabled) {
- spin_lock_irq(&chip->lock);
- enable_midi_input(chip, up);
- spin_unlock_irq(&chip->lock);
- chip->midi_input_enabled = up;
- }
-}
-
-
-
-static int snd_echo_midi_input_close(struct snd_rawmidi_substream *substream)
-{
- struct echoaudio *chip = substream->rmidi->private_data;
-
- chip->midi_in = NULL;
- DE_MID(("rawmidi_iclose\n"));
- return 0;
-}
-
-
-
-static int snd_echo_midi_output_open(struct snd_rawmidi_substream *substream)
-{
- struct echoaudio *chip = substream->rmidi->private_data;
-
- chip->tinuse = 0;
- chip->midi_full = 0;
- chip->midi_out = substream;
- DE_MID(("rawmidi_oopen\n"));
- return 0;
-}
-
-
-
-static void snd_echo_midi_output_write(unsigned long data)
-{
- struct echoaudio *chip = (struct echoaudio *)data;
- unsigned long flags;
- int bytes, sent, time;
- unsigned char buf[MIDI_OUT_BUFFER_SIZE - 1];
-
- DE_MID(("snd_echo_midi_output_write\n"));
- /* No interrupts are involved: we have to check at regular intervals
- if the card's output buffer has room for new data. */
- sent = bytes = 0;
- spin_lock_irqsave(&chip->lock, flags);
- chip->midi_full = 0;
- if (!snd_rawmidi_transmit_empty(chip->midi_out)) {
- bytes = snd_rawmidi_transmit_peek(chip->midi_out, buf,
- MIDI_OUT_BUFFER_SIZE - 1);
- DE_MID(("Try to send %d bytes...\n", bytes));
- sent = write_midi(chip, buf, bytes);
- if (sent < 0) {
- snd_printk(KERN_ERR "write_midi() error %d\n", sent);
- /* retry later */
- sent = 9000;
- chip->midi_full = 1;
- } else if (sent > 0) {
- DE_MID(("%d bytes sent\n", sent));
- snd_rawmidi_transmit_ack(chip->midi_out, sent);
- } else {
- /* Buffer is full. DSP's internal buffer is 64 (128 ?)
- bytes long. Let's wait until half of them are sent */
- DE_MID(("Full\n"));
- sent = 32;
- chip->midi_full = 1;
- }
- }
-
- /* We restart the timer only if there is some data left to send */
- if (!snd_rawmidi_transmit_empty(chip->midi_out) && chip->tinuse) {
- /* The timer will expire slightly after the data has been
- sent */
- time = (sent << 3) / 25 + 1; /* 8/25=0.32ms to send a byte */
- mod_timer(&chip->timer, jiffies + (time * HZ + 999) / 1000);
- DE_MID(("Timer armed(%d)\n", ((time * HZ + 999) / 1000)));
- }
- spin_unlock_irqrestore(&chip->lock, flags);
-}
-
-
-
-static void snd_echo_midi_output_trigger(struct snd_rawmidi_substream *substream,
- int up)
-{
- struct echoaudio *chip = substream->rmidi->private_data;
-
- DE_MID(("snd_echo_midi_output_trigger(%d)\n", up));
- spin_lock_irq(&chip->lock);
- if (up) {
- if (!chip->tinuse) {
- init_timer(&chip->timer);
- chip->timer.function = snd_echo_midi_output_write;
- chip->timer.data = (unsigned long)chip;
- chip->tinuse = 1;
- }
- } else {
- if (chip->tinuse) {
- chip->tinuse = 0;
- spin_unlock_irq(&chip->lock);
- del_timer_sync(&chip->timer);
- DE_MID(("Timer removed\n"));
- return;
- }
- }
- spin_unlock_irq(&chip->lock);
-
- if (up && !chip->midi_full)
- snd_echo_midi_output_write((unsigned long)chip);
-}
-
-
-
-static int snd_echo_midi_output_close(struct snd_rawmidi_substream *substream)
-{
- struct echoaudio *chip = substream->rmidi->private_data;
-
- chip->midi_out = NULL;
- DE_MID(("rawmidi_oclose\n"));
- return 0;
-}
-
-
-
-static struct snd_rawmidi_ops snd_echo_midi_input = {
- .open = snd_echo_midi_input_open,
- .close = snd_echo_midi_input_close,
- .trigger = snd_echo_midi_input_trigger,
-};
-
-static struct snd_rawmidi_ops snd_echo_midi_output = {
- .open = snd_echo_midi_output_open,
- .close = snd_echo_midi_output_close,
- .trigger = snd_echo_midi_output_trigger,
-};
-
-
-
-/* <--snd_echo_probe() */
-static int __devinit snd_echo_midi_create(struct snd_card *card,
- struct echoaudio *chip)
-{
- int err;
-
- if ((err = snd_rawmidi_new(card, card->shortname, 0, 1, 1,
- &chip->rmidi)) < 0)
- return err;
-
- strcpy(chip->rmidi->name, card->shortname);
- chip->rmidi->private_data = chip;
-
- snd_rawmidi_set_ops(chip->rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
- &snd_echo_midi_input);
- snd_rawmidi_set_ops(chip->rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
- &snd_echo_midi_output);
-
- chip->rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
- DE_INIT(("MIDI ok\n"));
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/mona.c b/ANDROID_3.4.5/sound/pci/echoaudio/mona.c
deleted file mode 100644
index 1283bfb2..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/mona.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * ALSA driver for Echoaudio soundcards.
- * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#define ECHO24_FAMILY
-#define ECHOCARD_MONA
-#define ECHOCARD_NAME "Mona"
-#define ECHOCARD_HAS_MONITOR
-#define ECHOCARD_HAS_ASIC
-#define ECHOCARD_HAS_SUPER_INTERLEAVE
-#define ECHOCARD_HAS_DIGITAL_IO
-#define ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE
-#define ECHOCARD_HAS_DIGITAL_MODE_SWITCH
-#define ECHOCARD_HAS_EXTERNAL_CLOCK
-#define ECHOCARD_HAS_ADAT 6
-#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
-
-/* Pipe indexes */
-#define PX_ANALOG_OUT 0 /* 6 */
-#define PX_DIGITAL_OUT 6 /* 8 */
-#define PX_ANALOG_IN 14 /* 4 */
-#define PX_DIGITAL_IN 18 /* 8 */
-#define PX_NUM 26
-
-/* Bus indexes */
-#define BX_ANALOG_OUT 0 /* 6 */
-#define BX_DIGITAL_OUT 6 /* 8 */
-#define BX_ANALOG_IN 14 /* 4 */
-#define BX_DIGITAL_IN 18 /* 8 */
-#define BX_NUM 26
-
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/asoundef.h>
-#include <sound/initval.h>
-#include <asm/io.h>
-#include <linux/atomic.h>
-#include "echoaudio.h"
-
-MODULE_FIRMWARE("ea/loader_dsp.fw");
-MODULE_FIRMWARE("ea/mona_301_dsp.fw");
-MODULE_FIRMWARE("ea/mona_361_dsp.fw");
-MODULE_FIRMWARE("ea/mona_301_1_asic_48.fw");
-MODULE_FIRMWARE("ea/mona_301_1_asic_96.fw");
-MODULE_FIRMWARE("ea/mona_361_1_asic_48.fw");
-MODULE_FIRMWARE("ea/mona_361_1_asic_96.fw");
-MODULE_FIRMWARE("ea/mona_2_asic.fw");
-
-#define FW_361_LOADER 0
-#define FW_MONA_301_DSP 1
-#define FW_MONA_361_DSP 2
-#define FW_MONA_301_1_ASIC48 3
-#define FW_MONA_301_1_ASIC96 4
-#define FW_MONA_361_1_ASIC48 5
-#define FW_MONA_361_1_ASIC96 6
-#define FW_MONA_2_ASIC 7
-
-static const struct firmware card_fw[] = {
- {0, "loader_dsp.fw"},
- {0, "mona_301_dsp.fw"},
- {0, "mona_361_dsp.fw"},
- {0, "mona_301_1_asic_48.fw"},
- {0, "mona_301_1_asic_96.fw"},
- {0, "mona_361_1_asic_48.fw"},
- {0, "mona_361_1_asic_96.fw"},
- {0, "mona_2_asic.fw"}
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
- {0x1057, 0x1801, 0xECC0, 0x0070, 0, 0, 0}, /* DSP 56301 Mona rev.0 */
- {0x1057, 0x1801, 0xECC0, 0x0071, 0, 0, 0}, /* DSP 56301 Mona rev.1 */
- {0x1057, 0x1801, 0xECC0, 0x0072, 0, 0, 0}, /* DSP 56301 Mona rev.2 */
- {0x1057, 0x3410, 0xECC0, 0x0070, 0, 0, 0}, /* DSP 56361 Mona rev.0 */
- {0x1057, 0x3410, 0xECC0, 0x0071, 0, 0, 0}, /* DSP 56361 Mona rev.1 */
- {0x1057, 0x3410, 0xECC0, 0x0072, 0, 0, 0}, /* DSP 56361 Mona rev.2 */
- {0,}
-};
-
-static struct snd_pcm_hardware pcm_hardware_skel = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START,
- .formats = SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_S32_BE,
- .rates = SNDRV_PCM_RATE_8000_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000,
- .rate_min = 8000,
- .rate_max = 96000,
- .channels_min = 1,
- .channels_max = 8,
- .buffer_bytes_max = 262144,
- .period_bytes_min = 32,
- .period_bytes_max = 131072,
- .periods_min = 2,
- .periods_max = 220,
- /* One page (4k) contains 512 instructions. I don't know if the hw
- supports lists longer than this. In this case periods_max=220 is a
- safe limit to make sure the list never exceeds 512 instructions. */
-};
-
-
-#include "mona_dsp.c"
-#include "echoaudio_dsp.c"
-#include "echoaudio_gml.c"
-#include "echoaudio.c"
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/mona_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/mona_dsp.c
deleted file mode 100644
index 6e6a7eb5..00000000
--- a/ANDROID_3.4.5/sound/pci/echoaudio/mona_dsp.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/****************************************************************************
-
- Copyright Echo Digital Audio Corporation (c) 1998 - 2004
- All rights reserved
- www.echoaudio.com
-
- This file is part of Echo Digital Audio's generic driver library.
-
- Echo Digital Audio's generic driver library is free software;
- you can redistribute it and/or modify it under the terms of
- the GNU General Public License as published by the Free Software
- Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- *************************************************************************
-
- Translation from C++ and adaptation for use in ALSA-Driver
- were made by Giuliano Pochini <pochini@shiny.it>
-
-****************************************************************************/
-
-
-static int write_control_reg(struct echoaudio *chip, u32 value, char force);
-static int set_input_clock(struct echoaudio *chip, u16 clock);
-static int set_professional_spdif(struct echoaudio *chip, char prof);
-static int set_digital_mode(struct echoaudio *chip, u8 mode);
-static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
-static int check_asic_status(struct echoaudio *chip);
-
-
-static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
-{
- int err;
-
- DE_INIT(("init_hw() - Mona\n"));
- if (snd_BUG_ON((subdevice_id & 0xfff0) != MONA))
- return -ENODEV;
-
- if ((err = init_dsp_comm_page(chip))) {
- DE_INIT(("init_hw - could not initialize DSP comm page\n"));
- return err;
- }
-
- chip->device_id = device_id;
- chip->subdevice_id = subdevice_id;
- chip->bad_board = TRUE;
- chip->input_clock_types =
- ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
- ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT;
- chip->digital_modes =
- ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
- ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
- ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
-
- /* Mona comes in both '301 and '361 flavors */
- if (chip->device_id == DEVICE_ID_56361)
- chip->dsp_code_to_load = FW_MONA_361_DSP;
- else
- chip->dsp_code_to_load = FW_MONA_301_DSP;
-
- if ((err = load_firmware(chip)) < 0)
- return err;
- chip->bad_board = FALSE;
-
- DE_INIT(("init_hw done\n"));
- return err;
-}
-
-
-
-static int set_mixer_defaults(struct echoaudio *chip)
-{
- chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
- chip->professional_spdif = FALSE;
- chip->digital_in_automute = TRUE;
- return init_line_levels(chip);
-}
-
-
-
-static u32 detect_input_clocks(const struct echoaudio *chip)
-{
- u32 clocks_from_dsp, clock_bits;
-
- /* Map the DSP clock detect bits to the generic driver clock
- detect bits */
- clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
-
- clock_bits = ECHO_CLOCK_BIT_INTERNAL;
-
- if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF)
- clock_bits |= ECHO_CLOCK_BIT_SPDIF;
-
- if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT)
- clock_bits |= ECHO_CLOCK_BIT_ADAT;
-
- if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD)
- clock_bits |= ECHO_CLOCK_BIT_WORD;
-
- return clock_bits;
-}
-
-
-
-/* Mona has an ASIC on the PCI card and another ASIC in the external box;
-both need to be loaded. */
-static int load_asic(struct echoaudio *chip)
-{
- u32 control_reg;
- int err;
- short asic;
-
- if (chip->asic_loaded)
- return 0;
-
- mdelay(10);
-
- if (chip->device_id == DEVICE_ID_56361)
- asic = FW_MONA_361_1_ASIC48;
- else
- asic = FW_MONA_301_1_ASIC48;
-
- err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, asic);
- if (err < 0)
- return err;
-
- chip->asic_code = asic;
- mdelay(10);
-
- /* Do the external one */
- err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_EXTERNAL_ASIC,
- FW_MONA_2_ASIC);
- if (err < 0)
- return err;
-
- mdelay(10);
- err = check_asic_status(chip);
-
- /* Set up the control register if the load succeeded -
- 48 kHz, internal clock, S/PDIF RCA mode */
- if (!err) {
- control_reg = GML_CONVERTER_ENABLE | GML_48KHZ;
- err = write_control_reg(chip, control_reg, TRUE);
- }
-
- return err;
-}
-
-
-
-/* Depending on what digital mode you want, Mona needs different ASICs
-loaded. This function checks the ASIC needed for the new mode and sees
-if it matches the one already loaded. */
-static int switch_asic(struct echoaudio *chip, char double_speed)
-{
- int err;
- short asic;
-
- /* Check the clock detect bits to see if this is
- a single-speed clock or a double-speed clock; load
- a new ASIC if necessary. */
- if (chip->device_id == DEVICE_ID_56361) {
- if (double_speed)
- asic = FW_MONA_361_1_ASIC96;
- else
- asic = FW_MONA_361_1_ASIC48;
- } else {
- if (double_speed)
- asic = FW_MONA_301_1_ASIC96;
- else
- asic = FW_MONA_301_1_ASIC48;
- }
-
- if (asic != chip->asic_code) {
- /* Load the desired ASIC */
- err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC,
- asic);
- if (err < 0)
- return err;
- chip->asic_code = asic;
- }
-
- return 0;
-}
-
-
-
-static int set_sample_rate(struct echoaudio *chip, u32 rate)
-{
- u32 control_reg, clock;
- short asic;
- char force_write;
-
- /* Only set the clock for internal mode. */
- if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
- DE_ACT(("set_sample_rate: Cannot set sample rate - "
- "clock not set to CLK_CLOCKININTERNAL\n"));
- /* Save the rate anyhow */
- chip->comm_page->sample_rate = cpu_to_le32(rate);
- chip->sample_rate = rate;
- return 0;
- }
-
- /* Now, check to see if the required ASIC is loaded */
- if (rate >= 88200) {
- if (chip->digital_mode == DIGITAL_MODE_ADAT)
- return -EINVAL;
- if (chip->device_id == DEVICE_ID_56361)
- asic = FW_MONA_361_1_ASIC96;
- else
- asic = FW_MONA_301_1_ASIC96;
- } else {
- if (chip->device_id == DEVICE_ID_56361)
- asic = FW_MONA_361_1_ASIC48;
- else
- asic = FW_MONA_301_1_ASIC48;
- }
-
- force_write = 0;
- if (asic != chip->asic_code) {
- int err;
- /* Load the desired ASIC (load_asic_generic() can sleep) */
- spin_unlock_irq(&chip->lock);
- err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC,
- asic);
- spin_lock_irq(&chip->lock);
-
- if (err < 0)
- return err;
- chip->asic_code = asic;
- force_write = 1;
- }
-
- /* Compute the new control register value */
- clock = 0;
- control_reg = le32_to_cpu(chip->comm_page->control_register);
- control_reg &= GML_CLOCK_CLEAR_MASK;
- control_reg &= GML_SPDIF_RATE_CLEAR_MASK;
-
- switch (rate) {
- case 96000:
- clock = GML_96KHZ;
- break;
- case 88200:
- clock = GML_88KHZ;
- break;
- case 48000:
- clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1;
- break;
- case 44100:
- clock = GML_44KHZ;
- /* Professional mode */
- if (control_reg & GML_SPDIF_PRO_MODE)
- clock |= GML_SPDIF_SAMPLE_RATE0;
- break;
- case 32000:
- clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 |
- GML_SPDIF_SAMPLE_RATE1;
- break;
- case 22050:
- clock = GML_22KHZ;
- break;
- case 16000:
- clock = GML_16KHZ;
- break;
- case 11025:
- clock = GML_11KHZ;
- break;
- case 8000:
- clock = GML_8KHZ;
- break;
- default:
- DE_ACT(("set_sample_rate: %d invalid!\n", rate));
- return -EINVAL;
- }
-
- control_reg |= clock;
-
- chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */
- chip->sample_rate = rate;
- DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock));
-
- return write_control_reg(chip, control_reg, force_write);
-}
-
-
-
-static int set_input_clock(struct echoaudio *chip, u16 clock)
-{
- u32 control_reg, clocks_from_dsp;
- int err;
-
- DE_ACT(("set_input_clock:\n"));
-
- /* Prevent two simultaneous calls to switch_asic() */
- if (atomic_read(&chip->opencount))
- return -EAGAIN;
-
- /* Mask off the clock select bits */
- control_reg = le32_to_cpu(chip->comm_page->control_register) &
- GML_CLOCK_CLEAR_MASK;
- clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
-
- switch (clock) {
- case ECHO_CLOCK_INTERNAL:
- DE_ACT(("Set Mona clock to INTERNAL\n"));
- chip->input_clock = ECHO_CLOCK_INTERNAL;
- return set_sample_rate(chip, chip->sample_rate);
- case ECHO_CLOCK_SPDIF:
- if (chip->digital_mode == DIGITAL_MODE_ADAT)
- return -EAGAIN;
- spin_unlock_irq(&chip->lock);
- err = switch_asic(chip, clocks_from_dsp &
- GML_CLOCK_DETECT_BIT_SPDIF96);
- spin_lock_irq(&chip->lock);
- if (err < 0)
- return err;
- DE_ACT(("Set Mona clock to SPDIF\n"));
- control_reg |= GML_SPDIF_CLOCK;
- if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96)
- control_reg |= GML_DOUBLE_SPEED_MODE;
- else
- control_reg &= ~GML_DOUBLE_SPEED_MODE;
- break;
- case ECHO_CLOCK_WORD:
- DE_ACT(("Set Mona clock to WORD\n"));
- spin_unlock_irq(&chip->lock);
- err = switch_asic(chip, clocks_from_dsp &
- GML_CLOCK_DETECT_BIT_WORD96);
- spin_lock_irq(&chip->lock);
- if (err < 0)
- return err;
- control_reg |= GML_WORD_CLOCK;
- if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96)
- control_reg |= GML_DOUBLE_SPEED_MODE;
- else
- control_reg &= ~GML_DOUBLE_SPEED_MODE;
- break;
- case ECHO_CLOCK_ADAT:
- DE_ACT(("Set Mona clock to ADAT\n"));
- if (chip->digital_mode != DIGITAL_MODE_ADAT)
- return -EAGAIN;
- control_reg |= GML_ADAT_CLOCK;
- control_reg &= ~GML_DOUBLE_SPEED_MODE;
- break;
- default:
- DE_ACT(("Input clock 0x%x not supported for Mona\n", clock));
- return -EINVAL;
- }
-
- chip->input_clock = clock;
- return write_control_reg(chip, control_reg, TRUE);
-}
-
-
-
-static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
-{
- u32 control_reg;
- int err, incompatible_clock;
-
- /* Set clock to "internal" if it's not compatible with the new mode */
- incompatible_clock = FALSE;
- switch (mode) {
- case DIGITAL_MODE_SPDIF_OPTICAL:
- case DIGITAL_MODE_SPDIF_RCA:
- if (chip->input_clock == ECHO_CLOCK_ADAT)
- incompatible_clock = TRUE;
- break;
- case DIGITAL_MODE_ADAT:
- if (chip->input_clock == ECHO_CLOCK_SPDIF)
- incompatible_clock = TRUE;
- break;
- default:
- DE_ACT(("Digital mode not supported: %d\n", mode));
- return -EINVAL;
- }
-
- spin_lock_irq(&chip->lock);
-
- if (incompatible_clock) { /* Switch to 48KHz, internal */
- chip->sample_rate = 48000;
- set_input_clock(chip, ECHO_CLOCK_INTERNAL);
- }
-
- /* Clear the current digital mode */
- control_reg = le32_to_cpu(chip->comm_page->control_register);
- control_reg &= GML_DIGITAL_MODE_CLEAR_MASK;
-
- /* Tweak the control reg */
- switch (mode) {
- case DIGITAL_MODE_SPDIF_OPTICAL:
- control_reg |= GML_SPDIF_OPTICAL_MODE;
- break;
- case DIGITAL_MODE_SPDIF_RCA:
- /* GML_SPDIF_OPTICAL_MODE bit cleared */
- break;
- case DIGITAL_MODE_ADAT:
- /* If the current ASIC is the 96KHz ASIC, switch the ASIC
- and set to 48 KHz */
- if (chip->asic_code == FW_MONA_361_1_ASIC96 ||
- chip->asic_code == FW_MONA_301_1_ASIC96) {
- set_sample_rate(chip, 48000);
- }
- control_reg |= GML_ADAT_MODE;
- control_reg &= ~GML_DOUBLE_SPEED_MODE;
- break;
- }
-
- err = write_control_reg(chip, control_reg, FALSE);
- spin_unlock_irq(&chip->lock);
- if (err < 0)
- return err;
- chip->digital_mode = mode;
-
- DE_ACT(("set_digital_mode to %d\n", mode));
- return incompatible_clock;
-}
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/Makefile b/ANDROID_3.4.5/sound/pci/emu10k1/Makefile
deleted file mode 100644
index fc5591e7..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-emu10k1-objs := emu10k1.o emu10k1_main.o \
- irq.o memory.o voice.o emumpu401.o emupcm.o io.o \
- emuproc.o emumixer.o emufx.o timer.o p16v.o
-snd-emu10k1-synth-objs := emu10k1_synth.o emu10k1_callback.o emu10k1_patch.o
-snd-emu10k1x-objs := emu10k1x.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_EMU10K1) += snd-emu10k1.o
-obj-$(CONFIG_SND_EMU10K1_SEQ) += snd-emu10k1-synth.o
-obj-$(CONFIG_SND_EMU10K1X) += snd-emu10k1x.o
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1.c b/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1.c
deleted file mode 100644
index 790c65d9..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * The driver for the EMU10K1 (SB Live!) based soundcards
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
- * Added support for Audigy 2 Value.
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
- */
-
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/time.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/emu10k1.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("EMU10K1");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB Live!/PCI512/E-mu APS},"
- "{Creative Labs,SB Audigy}}");
-
-#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
-#define ENABLE_SYNTH
-#include <sound/emu10k1_synth.h>
-#endif
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int extin[SNDRV_CARDS];
-static int extout[SNDRV_CARDS];
-static int seq_ports[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4};
-static int max_synth_voices[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 64};
-static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128};
-static bool enable_ir[SNDRV_CARDS];
-static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */
-static uint delay_pcm_irq[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for the EMU10K1 soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable the EMU10K1 soundcard.");
-module_param_array(extin, int, NULL, 0444);
-MODULE_PARM_DESC(extin, "Available external inputs for FX8010. Zero=default.");
-module_param_array(extout, int, NULL, 0444);
-MODULE_PARM_DESC(extout, "Available external outputs for FX8010. Zero=default.");
-module_param_array(seq_ports, int, NULL, 0444);
-MODULE_PARM_DESC(seq_ports, "Allocated sequencer ports for internal synthesizer.");
-module_param_array(max_synth_voices, int, NULL, 0444);
-MODULE_PARM_DESC(max_synth_voices, "Maximum number of voices for WaveTable.");
-module_param_array(max_buffer_size, int, NULL, 0444);
-MODULE_PARM_DESC(max_buffer_size, "Maximum sample buffer size in MB.");
-module_param_array(enable_ir, bool, NULL, 0444);
-MODULE_PARM_DESC(enable_ir, "Enable IR.");
-module_param_array(subsystem, uint, NULL, 0444);
-MODULE_PARM_DESC(subsystem, "Force card subsystem model.");
-module_param_array(delay_pcm_irq, uint, NULL, 0444);
-MODULE_PARM_DESC(delay_pcm_irq, "Delay PCM interrupt by specified number of samples (default 0).");
-/*
- * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400
- */
-static DEFINE_PCI_DEVICE_TABLE(snd_emu10k1_ids) = {
- { PCI_VDEVICE(CREATIVE, 0x0002), 0 }, /* EMU10K1 */
- { PCI_VDEVICE(CREATIVE, 0x0004), 1 }, /* Audigy */
- { PCI_VDEVICE(CREATIVE, 0x0008), 1 }, /* Audigy 2 Value SB0400 */
- { 0, }
-};
-
-/*
- * Audigy 2 Value notes:
- * A_IOCFG Input (GPIO)
- * 0x400 = Front analog jack plugged in. (Green socket)
- * 0x1000 = Read analog jack plugged in. (Black socket)
- * 0x2000 = Center/LFE analog jack plugged in. (Orange socket)
- * A_IOCFG Output (GPIO)
- * 0x60 = Sound out of front Left.
- * Win sets it to 0xXX61
- */
-
-MODULE_DEVICE_TABLE(pci, snd_emu10k1_ids);
-
-static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct snd_emu10k1 *emu;
-#ifdef ENABLE_SYNTH
- struct snd_seq_device *wave = NULL;
-#endif
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
- if (max_buffer_size[dev] < 32)
- max_buffer_size[dev] = 32;
- else if (max_buffer_size[dev] > 1024)
- max_buffer_size[dev] = 1024;
- if ((err = snd_emu10k1_create(card, pci, extin[dev], extout[dev],
- (long)max_buffer_size[dev] * 1024 * 1024,
- enable_ir[dev], subsystem[dev],
- &emu)) < 0)
- goto error;
- card->private_data = emu;
- emu->delay_pcm_irq = delay_pcm_irq[dev] & 0x1f;
- if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0)
- goto error;
- if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0)
- goto error;
- if ((err = snd_emu10k1_pcm_efx(emu, 2, NULL)) < 0)
- goto error;
- /* This stores the periods table. */
- if (emu->card_capabilities->ca0151_chip) { /* P16V */
- if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
- 1024, &emu->p16v_buffer)) < 0)
- goto error;
- }
-
- if ((err = snd_emu10k1_mixer(emu, 0, 3)) < 0)
- goto error;
-
- if ((err = snd_emu10k1_timer(emu, 0)) < 0)
- goto error;
-
- if ((err = snd_emu10k1_pcm_multi(emu, 3, NULL)) < 0)
- goto error;
- if (emu->card_capabilities->ca0151_chip) { /* P16V */
- if ((err = snd_p16v_pcm(emu, 4, NULL)) < 0)
- goto error;
- }
- if (emu->audigy) {
- if ((err = snd_emu10k1_audigy_midi(emu)) < 0)
- goto error;
- } else {
- if ((err = snd_emu10k1_midi(emu)) < 0)
- goto error;
- }
- if ((err = snd_emu10k1_fx8010_new(emu, 0, NULL)) < 0)
- goto error;
-#ifdef ENABLE_SYNTH
- if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH,
- sizeof(struct snd_emu10k1_synth_arg), &wave) < 0 ||
- wave == NULL) {
- snd_printk(KERN_WARNING "can't initialize Emu10k1 wavetable synth\n");
- } else {
- struct snd_emu10k1_synth_arg *arg;
- arg = SNDRV_SEQ_DEVICE_ARGPTR(wave);
- strcpy(wave->name, "Emu-10k1 Synth");
- arg->hwptr = emu;
- arg->index = 1;
- arg->seq_ports = seq_ports[dev];
- arg->max_voices = max_synth_voices[dev];
- }
-#endif
-
- strcpy(card->driver, emu->card_capabilities->driver);
- strcpy(card->shortname, emu->card_capabilities->name);
- snprintf(card->longname, sizeof(card->longname),
- "%s (rev.%d, serial:0x%x) at 0x%lx, irq %i",
- card->shortname, emu->revision, emu->serial, emu->port, emu->irq);
-
- if ((err = snd_card_register(card)) < 0)
- goto error;
-
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-
- error:
- snd_card_free(card);
- return err;
-}
-
-static void __devexit snd_card_emu10k1_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-
-#ifdef CONFIG_PM
-static int snd_emu10k1_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_emu10k1 *emu = card->private_data;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-
- snd_pcm_suspend_all(emu->pcm);
- snd_pcm_suspend_all(emu->pcm_mic);
- snd_pcm_suspend_all(emu->pcm_efx);
- snd_pcm_suspend_all(emu->pcm_multi);
- snd_pcm_suspend_all(emu->pcm_p16v);
-
- snd_ac97_suspend(emu->ac97);
-
- snd_emu10k1_efx_suspend(emu);
- snd_emu10k1_suspend_regs(emu);
- if (emu->card_capabilities->ca0151_chip)
- snd_p16v_suspend(emu);
-
- snd_emu10k1_done(emu);
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int snd_emu10k1_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_emu10k1 *emu = card->private_data;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "emu10k1: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
-
- snd_emu10k1_resume_init(emu);
- snd_emu10k1_efx_resume(emu);
- snd_ac97_resume(emu->ac97);
- snd_emu10k1_resume_regs(emu);
-
- if (emu->card_capabilities->ca0151_chip)
- snd_p16v_resume(emu);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_emu10k1_ids,
- .probe = snd_card_emu10k1_probe,
- .remove = __devexit_p(snd_card_emu10k1_remove),
-#ifdef CONFIG_PM
- .suspend = snd_emu10k1_suspend,
- .resume = snd_emu10k1_resume,
-#endif
-};
-
-static int __init alsa_card_emu10k1_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_emu10k1_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_emu10k1_init)
-module_exit(alsa_card_emu10k1_exit)
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1_callback.c b/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1_callback.c
deleted file mode 100644
index a0afa505..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1_callback.c
+++ /dev/null
@@ -1,552 +0,0 @@
-/*
- * synth callback routines for Emu10k1
- *
- * Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/export.h>
-#include "emu10k1_synth_local.h"
-#include <sound/asoundef.h>
-
-/* voice status */
-enum {
- V_FREE=0, V_OFF, V_RELEASED, V_PLAYING, V_END
-};
-
-/* Keeps track of what we are finding */
-struct best_voice {
- unsigned int time;
- int voice;
-};
-
-/*
- * prototypes
- */
-static void lookup_voices(struct snd_emux *emux, struct snd_emu10k1 *hw,
- struct best_voice *best, int active_only);
-static struct snd_emux_voice *get_voice(struct snd_emux *emux,
- struct snd_emux_port *port);
-static int start_voice(struct snd_emux_voice *vp);
-static void trigger_voice(struct snd_emux_voice *vp);
-static void release_voice(struct snd_emux_voice *vp);
-static void update_voice(struct snd_emux_voice *vp, int update);
-static void terminate_voice(struct snd_emux_voice *vp);
-static void free_voice(struct snd_emux_voice *vp);
-static void set_fmmod(struct snd_emu10k1 *hw, struct snd_emux_voice *vp);
-static void set_fm2frq2(struct snd_emu10k1 *hw, struct snd_emux_voice *vp);
-static void set_filterQ(struct snd_emu10k1 *hw, struct snd_emux_voice *vp);
-
-/*
- * Ensure a value is between two points
- * macro evaluates its args more than once, so changed to upper-case.
- */
-#define LIMITVALUE(x, a, b) do { if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b); } while (0)
-#define LIMITMAX(x, a) do {if ((x) > (a)) (x) = (a); } while (0)
-
-
-/*
- * set up operators
- */
-static struct snd_emux_operators emu10k1_ops = {
- .owner = THIS_MODULE,
- .get_voice = get_voice,
- .prepare = start_voice,
- .trigger = trigger_voice,
- .release = release_voice,
- .update = update_voice,
- .terminate = terminate_voice,
- .free_voice = free_voice,
- .sample_new = snd_emu10k1_sample_new,
- .sample_free = snd_emu10k1_sample_free,
-};
-
-void
-snd_emu10k1_ops_setup(struct snd_emux *emux)
-{
- emux->ops = emu10k1_ops;
-}
-
-
-/*
- * get more voice for pcm
- *
- * terminate most inactive voice and give it as a pcm voice.
- */
-int
-snd_emu10k1_synth_get_voice(struct snd_emu10k1 *hw)
-{
- struct snd_emux *emu;
- struct snd_emux_voice *vp;
- struct best_voice best[V_END];
- unsigned long flags;
- int i;
-
- emu = hw->synth;
-
- spin_lock_irqsave(&emu->voice_lock, flags);
- lookup_voices(emu, hw, best, 1); /* no OFF voices */
- for (i = 0; i < V_END; i++) {
- if (best[i].voice >= 0) {
- int ch;
- vp = &emu->voices[best[i].voice];
- if ((ch = vp->ch) < 0) {
- /*
- printk(KERN_WARNING
- "synth_get_voice: ch < 0 (%d) ??", i);
- */
- continue;
- }
- vp->emu->num_voices--;
- vp->ch = -1;
- vp->state = SNDRV_EMUX_ST_OFF;
- spin_unlock_irqrestore(&emu->voice_lock, flags);
- return ch;
- }
- }
- spin_unlock_irqrestore(&emu->voice_lock, flags);
-
- /* not found */
- return -ENOMEM;
-}
-
-
-/*
- * turn off the voice (not terminated)
- */
-static void
-release_voice(struct snd_emux_voice *vp)
-{
- int dcysusv;
- struct snd_emu10k1 *hw;
-
- hw = vp->hw;
- dcysusv = 0x8000 | (unsigned char)vp->reg.parm.modrelease;
- snd_emu10k1_ptr_write(hw, DCYSUSM, vp->ch, dcysusv);
- dcysusv = 0x8000 | (unsigned char)vp->reg.parm.volrelease | DCYSUSV_CHANNELENABLE_MASK;
- snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, dcysusv);
-}
-
-
-/*
- * terminate the voice
- */
-static void
-terminate_voice(struct snd_emux_voice *vp)
-{
- struct snd_emu10k1 *hw;
-
- if (snd_BUG_ON(!vp))
- return;
- hw = vp->hw;
- snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0x807f | DCYSUSV_CHANNELENABLE_MASK);
- if (vp->block) {
- struct snd_emu10k1_memblk *emem;
- emem = (struct snd_emu10k1_memblk *)vp->block;
- if (emem->map_locked > 0)
- emem->map_locked--;
- }
-}
-
-/*
- * release the voice to system
- */
-static void
-free_voice(struct snd_emux_voice *vp)
-{
- struct snd_emu10k1 *hw;
-
- hw = vp->hw;
- /* FIXME: emu10k1_synth is broken. */
- /* This can get called with hw == 0 */
- /* Problem apparent on plug, unplug then plug */
- /* on the Audigy 2 ZS Notebook. */
- if (hw && (vp->ch >= 0)) {
- snd_emu10k1_ptr_write(hw, IFATN, vp->ch, 0xff00);
- snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0x807f | DCYSUSV_CHANNELENABLE_MASK);
- // snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0);
- snd_emu10k1_ptr_write(hw, VTFT, vp->ch, 0xffff);
- snd_emu10k1_ptr_write(hw, CVCF, vp->ch, 0xffff);
- snd_emu10k1_voice_free(hw, &hw->voices[vp->ch]);
- vp->emu->num_voices--;
- vp->ch = -1;
- }
-}
-
-
-/*
- * update registers
- */
-static void
-update_voice(struct snd_emux_voice *vp, int update)
-{
- struct snd_emu10k1 *hw;
-
- hw = vp->hw;
- if (update & SNDRV_EMUX_UPDATE_VOLUME)
- snd_emu10k1_ptr_write(hw, IFATN_ATTENUATION, vp->ch, vp->avol);
- if (update & SNDRV_EMUX_UPDATE_PITCH)
- snd_emu10k1_ptr_write(hw, IP, vp->ch, vp->apitch);
- if (update & SNDRV_EMUX_UPDATE_PAN) {
- snd_emu10k1_ptr_write(hw, PTRX_FXSENDAMOUNT_A, vp->ch, vp->apan);
- snd_emu10k1_ptr_write(hw, PTRX_FXSENDAMOUNT_B, vp->ch, vp->aaux);
- }
- if (update & SNDRV_EMUX_UPDATE_FMMOD)
- set_fmmod(hw, vp);
- if (update & SNDRV_EMUX_UPDATE_TREMFREQ)
- snd_emu10k1_ptr_write(hw, TREMFRQ, vp->ch, vp->reg.parm.tremfrq);
- if (update & SNDRV_EMUX_UPDATE_FM2FRQ2)
- set_fm2frq2(hw, vp);
- if (update & SNDRV_EMUX_UPDATE_Q)
- set_filterQ(hw, vp);
-}
-
-
-/*
- * look up voice table - get the best voice in order of preference
- */
-/* spinlock held! */
-static void
-lookup_voices(struct snd_emux *emu, struct snd_emu10k1 *hw,
- struct best_voice *best, int active_only)
-{
- struct snd_emux_voice *vp;
- struct best_voice *bp;
- int i;
-
- for (i = 0; i < V_END; i++) {
- best[i].time = (unsigned int)-1; /* XXX MAX_?INT really */;
- best[i].voice = -1;
- }
-
- /*
- * Go through them all and get a best one to use.
- * NOTE: could also look at volume and pick the quietest one.
- */
- for (i = 0; i < emu->max_voices; i++) {
- int state, val;
-
- vp = &emu->voices[i];
- state = vp->state;
- if (state == SNDRV_EMUX_ST_OFF) {
- if (vp->ch < 0) {
- if (active_only)
- continue;
- bp = best + V_FREE;
- } else
- bp = best + V_OFF;
- }
- else if (state == SNDRV_EMUX_ST_RELEASED ||
- state == SNDRV_EMUX_ST_PENDING) {
- bp = best + V_RELEASED;
-#if 1
- val = snd_emu10k1_ptr_read(hw, CVCF_CURRENTVOL, vp->ch);
- if (! val)
- bp = best + V_OFF;
-#endif
- }
- else if (state == SNDRV_EMUX_ST_STANDBY)
- continue;
- else if (state & SNDRV_EMUX_ST_ON)
- bp = best + V_PLAYING;
- else
- continue;
-
- /* check if sample is finished playing (non-looping only) */
- if (bp != best + V_OFF && bp != best + V_FREE &&
- (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_SINGLESHOT)) {
- val = snd_emu10k1_ptr_read(hw, CCCA_CURRADDR, vp->ch);
- if (val >= vp->reg.loopstart)
- bp = best + V_OFF;
- }
-
- if (vp->time < bp->time) {
- bp->time = vp->time;
- bp->voice = i;
- }
- }
-}
-
-/*
- * get an empty voice
- *
- * emu->voice_lock is already held.
- */
-static struct snd_emux_voice *
-get_voice(struct snd_emux *emu, struct snd_emux_port *port)
-{
- struct snd_emu10k1 *hw;
- struct snd_emux_voice *vp;
- struct best_voice best[V_END];
- int i;
-
- hw = emu->hw;
-
- lookup_voices(emu, hw, best, 0);
- for (i = 0; i < V_END; i++) {
- if (best[i].voice >= 0) {
- vp = &emu->voices[best[i].voice];
- if (vp->ch < 0) {
- /* allocate a voice */
- struct snd_emu10k1_voice *hwvoice;
- if (snd_emu10k1_voice_alloc(hw, EMU10K1_SYNTH, 1, &hwvoice) < 0 || hwvoice == NULL)
- continue;
- vp->ch = hwvoice->number;
- emu->num_voices++;
- }
- return vp;
- }
- }
-
- /* not found */
- return NULL;
-}
-
-/*
- * prepare envelopes and LFOs
- */
-static int
-start_voice(struct snd_emux_voice *vp)
-{
- unsigned int temp;
- int ch;
- unsigned int addr, mapped_offset;
- struct snd_midi_channel *chan;
- struct snd_emu10k1 *hw;
- struct snd_emu10k1_memblk *emem;
-
- hw = vp->hw;
- ch = vp->ch;
- if (snd_BUG_ON(ch < 0))
- return -EINVAL;
- chan = vp->chan;
-
- emem = (struct snd_emu10k1_memblk *)vp->block;
- if (emem == NULL)
- return -EINVAL;
- emem->map_locked++;
- if (snd_emu10k1_memblk_map(hw, emem) < 0) {
- /* printk(KERN_ERR "emu: cannot map!\n"); */
- return -ENOMEM;
- }
- mapped_offset = snd_emu10k1_memblk_offset(emem) >> 1;
- vp->reg.start += mapped_offset;
- vp->reg.end += mapped_offset;
- vp->reg.loopstart += mapped_offset;
- vp->reg.loopend += mapped_offset;
-
- /* set channel routing */
- /* A = left(0), B = right(1), C = reverb(c), D = chorus(d) */
- if (hw->audigy) {
- temp = FXBUS_MIDI_LEFT | (FXBUS_MIDI_RIGHT << 8) |
- (FXBUS_MIDI_REVERB << 16) | (FXBUS_MIDI_CHORUS << 24);
- snd_emu10k1_ptr_write(hw, A_FXRT1, ch, temp);
- } else {
- temp = (FXBUS_MIDI_LEFT << 16) | (FXBUS_MIDI_RIGHT << 20) |
- (FXBUS_MIDI_REVERB << 24) | (FXBUS_MIDI_CHORUS << 28);
- snd_emu10k1_ptr_write(hw, FXRT, ch, temp);
- }
-
- /* channel to be silent and idle */
- snd_emu10k1_ptr_write(hw, DCYSUSV, ch, 0x0000);
- snd_emu10k1_ptr_write(hw, VTFT, ch, 0x0000FFFF);
- snd_emu10k1_ptr_write(hw, CVCF, ch, 0x0000FFFF);
- snd_emu10k1_ptr_write(hw, PTRX, ch, 0);
- snd_emu10k1_ptr_write(hw, CPF, ch, 0);
-
- /* set pitch offset */
- snd_emu10k1_ptr_write(hw, IP, vp->ch, vp->apitch);
-
- /* set envelope parameters */
- snd_emu10k1_ptr_write(hw, ENVVAL, ch, vp->reg.parm.moddelay);
- snd_emu10k1_ptr_write(hw, ATKHLDM, ch, vp->reg.parm.modatkhld);
- snd_emu10k1_ptr_write(hw, DCYSUSM, ch, vp->reg.parm.moddcysus);
- snd_emu10k1_ptr_write(hw, ENVVOL, ch, vp->reg.parm.voldelay);
- snd_emu10k1_ptr_write(hw, ATKHLDV, ch, vp->reg.parm.volatkhld);
- /* decay/sustain parameter for volume envelope is used
- for triggerg the voice */
-
- /* cutoff and volume */
- temp = (unsigned int)vp->acutoff << 8 | (unsigned char)vp->avol;
- snd_emu10k1_ptr_write(hw, IFATN, vp->ch, temp);
-
- /* modulation envelope heights */
- snd_emu10k1_ptr_write(hw, PEFE, ch, vp->reg.parm.pefe);
-
- /* lfo1/2 delay */
- snd_emu10k1_ptr_write(hw, LFOVAL1, ch, vp->reg.parm.lfo1delay);
- snd_emu10k1_ptr_write(hw, LFOVAL2, ch, vp->reg.parm.lfo2delay);
-
- /* lfo1 pitch & cutoff shift */
- set_fmmod(hw, vp);
- /* lfo1 volume & freq */
- snd_emu10k1_ptr_write(hw, TREMFRQ, vp->ch, vp->reg.parm.tremfrq);
- /* lfo2 pitch & freq */
- set_fm2frq2(hw, vp);
-
- /* reverb and loop start (reverb 8bit, MSB) */
- temp = vp->reg.parm.reverb;
- temp += (int)vp->chan->control[MIDI_CTL_E1_REVERB_DEPTH] * 9 / 10;
- LIMITMAX(temp, 255);
- addr = vp->reg.loopstart;
- snd_emu10k1_ptr_write(hw, PSST, vp->ch, (temp << 24) | addr);
-
- /* chorus & loop end (chorus 8bit, MSB) */
- addr = vp->reg.loopend;
- temp = vp->reg.parm.chorus;
- temp += (int)chan->control[MIDI_CTL_E3_CHORUS_DEPTH] * 9 / 10;
- LIMITMAX(temp, 255);
- temp = (temp <<24) | addr;
- snd_emu10k1_ptr_write(hw, DSL, ch, temp);
-
- /* clear filter delay memory */
- snd_emu10k1_ptr_write(hw, Z1, ch, 0);
- snd_emu10k1_ptr_write(hw, Z2, ch, 0);
-
- /* invalidate maps */
- temp = (hw->silent_page.addr << 1) | MAP_PTI_MASK;
- snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
- snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
-#if 0
- /* cache */
- {
- unsigned int val, sample;
- val = 32;
- if (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_8BITS)
- sample = 0x80808080;
- else {
- sample = 0;
- val *= 2;
- }
-
- /* cache */
- snd_emu10k1_ptr_write(hw, CCR, ch, 0x1c << 16);
- snd_emu10k1_ptr_write(hw, CDE, ch, sample);
- snd_emu10k1_ptr_write(hw, CDF, ch, sample);
-
- /* invalidate maps */
- temp = ((unsigned int)hw->silent_page.addr << 1) | MAP_PTI_MASK;
- snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
- snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
-
- /* fill cache */
- val -= 4;
- val <<= 25;
- val |= 0x1c << 16;
- snd_emu10k1_ptr_write(hw, CCR, ch, val);
- }
-#endif
-
- /* Q & current address (Q 4bit value, MSB) */
- addr = vp->reg.start;
- temp = vp->reg.parm.filterQ;
- temp = (temp<<28) | addr;
- if (vp->apitch < 0xe400)
- temp |= CCCA_INTERPROM_0;
- else {
- unsigned int shift = (vp->apitch - 0xe000) >> 10;
- temp |= shift << 25;
- }
- if (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_8BITS)
- temp |= CCCA_8BITSELECT;
- snd_emu10k1_ptr_write(hw, CCCA, ch, temp);
-
- /* reset volume */
- temp = (unsigned int)vp->vtarget << 16;
- snd_emu10k1_ptr_write(hw, VTFT, ch, temp | vp->ftarget);
- snd_emu10k1_ptr_write(hw, CVCF, ch, temp | 0xff00);
- return 0;
-}
-
-/*
- * Start envelope
- */
-static void
-trigger_voice(struct snd_emux_voice *vp)
-{
- unsigned int temp, ptarget;
- struct snd_emu10k1 *hw;
- struct snd_emu10k1_memblk *emem;
-
- hw = vp->hw;
-
- emem = (struct snd_emu10k1_memblk *)vp->block;
- if (! emem || emem->mapped_page < 0)
- return; /* not mapped */
-
-#if 0
- ptarget = (unsigned int)vp->ptarget << 16;
-#else
- ptarget = IP_TO_CP(vp->apitch);
-#endif
- /* set pitch target and pan (volume) */
- temp = ptarget | (vp->apan << 8) | vp->aaux;
- snd_emu10k1_ptr_write(hw, PTRX, vp->ch, temp);
-
- /* pitch target */
- snd_emu10k1_ptr_write(hw, CPF, vp->ch, ptarget);
-
- /* trigger voice */
- snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, vp->reg.parm.voldcysus|DCYSUSV_CHANNELENABLE_MASK);
-}
-
-#define MOD_SENSE 18
-
-/* set lfo1 modulation height and cutoff */
-static void
-set_fmmod(struct snd_emu10k1 *hw, struct snd_emux_voice *vp)
-{
- unsigned short fmmod;
- short pitch;
- unsigned char cutoff;
- int modulation;
-
- pitch = (char)(vp->reg.parm.fmmod>>8);
- cutoff = (vp->reg.parm.fmmod & 0xff);
- modulation = vp->chan->gm_modulation + vp->chan->midi_pressure;
- pitch += (MOD_SENSE * modulation) / 1200;
- LIMITVALUE(pitch, -128, 127);
- fmmod = ((unsigned char)pitch<<8) | cutoff;
- snd_emu10k1_ptr_write(hw, FMMOD, vp->ch, fmmod);
-}
-
-/* set lfo2 pitch & frequency */
-static void
-set_fm2frq2(struct snd_emu10k1 *hw, struct snd_emux_voice *vp)
-{
- unsigned short fm2frq2;
- short pitch;
- unsigned char freq;
- int modulation;
-
- pitch = (char)(vp->reg.parm.fm2frq2>>8);
- freq = vp->reg.parm.fm2frq2 & 0xff;
- modulation = vp->chan->gm_modulation + vp->chan->midi_pressure;
- pitch += (MOD_SENSE * modulation) / 1200;
- LIMITVALUE(pitch, -128, 127);
- fm2frq2 = ((unsigned char)pitch<<8) | freq;
- snd_emu10k1_ptr_write(hw, FM2FRQ2, vp->ch, fm2frq2);
-}
-
-/* set filterQ */
-static void
-set_filterQ(struct snd_emu10k1 *hw, struct snd_emux_voice *vp)
-{
- unsigned int val;
- val = snd_emu10k1_ptr_read(hw, CCCA, vp->ch) & ~CCCA_RESONANCE;
- val |= (vp->reg.parm.filterQ << 28);
- snd_emu10k1_ptr_write(hw, CCCA, vp->ch, val);
-}
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1_main.c b/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1_main.c
deleted file mode 100644
index 75492408..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1_main.c
+++ /dev/null
@@ -1,2101 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Creative Labs, Inc.
- * Routines for control of EMU10K1 chips
- *
- * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk>
- * Added support for Audigy 2 Value.
- * Added EMU 1010 support.
- * General bug fixes and enhancements.
- *
- *
- * BUGS:
- * --
- *
- * TODO:
- * --
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/sched.h>
-#include <linux/kthread.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/mutex.h>
-
-
-#include <sound/core.h>
-#include <sound/emu10k1.h>
-#include <linux/firmware.h>
-#include "p16v.h"
-#include "tina2.h"
-#include "p17v.h"
-
-
-#define HANA_FILENAME "emu/hana.fw"
-#define DOCK_FILENAME "emu/audio_dock.fw"
-#define EMU1010B_FILENAME "emu/emu1010b.fw"
-#define MICRO_DOCK_FILENAME "emu/micro_dock.fw"
-#define EMU0404_FILENAME "emu/emu0404.fw"
-#define EMU1010_NOTEBOOK_FILENAME "emu/emu1010_notebook.fw"
-
-MODULE_FIRMWARE(HANA_FILENAME);
-MODULE_FIRMWARE(DOCK_FILENAME);
-MODULE_FIRMWARE(EMU1010B_FILENAME);
-MODULE_FIRMWARE(MICRO_DOCK_FILENAME);
-MODULE_FIRMWARE(EMU0404_FILENAME);
-MODULE_FIRMWARE(EMU1010_NOTEBOOK_FILENAME);
-
-
-/*************************************************************************
- * EMU10K1 init / done
- *************************************************************************/
-
-void snd_emu10k1_voice_init(struct snd_emu10k1 *emu, int ch)
-{
- snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);
- snd_emu10k1_ptr_write(emu, IP, ch, 0);
- snd_emu10k1_ptr_write(emu, VTFT, ch, 0xffff);
- snd_emu10k1_ptr_write(emu, CVCF, ch, 0xffff);
- snd_emu10k1_ptr_write(emu, PTRX, ch, 0);
- snd_emu10k1_ptr_write(emu, CPF, ch, 0);
- snd_emu10k1_ptr_write(emu, CCR, ch, 0);
-
- snd_emu10k1_ptr_write(emu, PSST, ch, 0);
- snd_emu10k1_ptr_write(emu, DSL, ch, 0x10);
- snd_emu10k1_ptr_write(emu, CCCA, ch, 0);
- snd_emu10k1_ptr_write(emu, Z1, ch, 0);
- snd_emu10k1_ptr_write(emu, Z2, ch, 0);
- snd_emu10k1_ptr_write(emu, FXRT, ch, 0x32100000);
-
- snd_emu10k1_ptr_write(emu, ATKHLDM, ch, 0);
- snd_emu10k1_ptr_write(emu, DCYSUSM, ch, 0);
- snd_emu10k1_ptr_write(emu, IFATN, ch, 0xffff);
- snd_emu10k1_ptr_write(emu, PEFE, ch, 0);
- snd_emu10k1_ptr_write(emu, FMMOD, ch, 0);
- snd_emu10k1_ptr_write(emu, TREMFRQ, ch, 24); /* 1 Hz */
- snd_emu10k1_ptr_write(emu, FM2FRQ2, ch, 24); /* 1 Hz */
- snd_emu10k1_ptr_write(emu, TEMPENV, ch, 0);
-
- /*** these are last so OFF prevents writing ***/
- snd_emu10k1_ptr_write(emu, LFOVAL2, ch, 0);
- snd_emu10k1_ptr_write(emu, LFOVAL1, ch, 0);
- snd_emu10k1_ptr_write(emu, ATKHLDV, ch, 0);
- snd_emu10k1_ptr_write(emu, ENVVOL, ch, 0);
- snd_emu10k1_ptr_write(emu, ENVVAL, ch, 0);
-
- /* Audigy extra stuffs */
- if (emu->audigy) {
- snd_emu10k1_ptr_write(emu, 0x4c, ch, 0); /* ?? */
- snd_emu10k1_ptr_write(emu, 0x4d, ch, 0); /* ?? */
- snd_emu10k1_ptr_write(emu, 0x4e, ch, 0); /* ?? */
- snd_emu10k1_ptr_write(emu, 0x4f, ch, 0); /* ?? */
- snd_emu10k1_ptr_write(emu, A_FXRT1, ch, 0x03020100);
- snd_emu10k1_ptr_write(emu, A_FXRT2, ch, 0x3f3f3f3f);
- snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, ch, 0);
- }
-}
-
-static unsigned int spi_dac_init[] = {
- 0x00ff,
- 0x02ff,
- 0x0400,
- 0x0520,
- 0x0600,
- 0x08ff,
- 0x0aff,
- 0x0cff,
- 0x0eff,
- 0x10ff,
- 0x1200,
- 0x1400,
- 0x1480,
- 0x1800,
- 0x1aff,
- 0x1cff,
- 0x1e00,
- 0x0530,
- 0x0602,
- 0x0622,
- 0x1400,
-};
-
-static unsigned int i2c_adc_init[][2] = {
- { 0x17, 0x00 }, /* Reset */
- { 0x07, 0x00 }, /* Timeout */
- { 0x0b, 0x22 }, /* Interface control */
- { 0x0c, 0x22 }, /* Master mode control */
- { 0x0d, 0x08 }, /* Powerdown control */
- { 0x0e, 0xcf }, /* Attenuation Left 0x01 = -103dB, 0xff = 24dB */
- { 0x0f, 0xcf }, /* Attenuation Right 0.5dB steps */
- { 0x10, 0x7b }, /* ALC Control 1 */
- { 0x11, 0x00 }, /* ALC Control 2 */
- { 0x12, 0x32 }, /* ALC Control 3 */
- { 0x13, 0x00 }, /* Noise gate control */
- { 0x14, 0xa6 }, /* Limiter control */
- { 0x15, ADC_MUX_2 }, /* ADC Mixer control. Mic for A2ZS Notebook */
-};
-
-static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
-{
- unsigned int silent_page;
- int ch;
- u32 tmp;
-
- /* disable audio and lock cache */
- outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK |
- HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
-
- /* reset recording buffers */
- snd_emu10k1_ptr_write(emu, MICBS, 0, ADCBS_BUFSIZE_NONE);
- snd_emu10k1_ptr_write(emu, MICBA, 0, 0);
- snd_emu10k1_ptr_write(emu, FXBS, 0, ADCBS_BUFSIZE_NONE);
- snd_emu10k1_ptr_write(emu, FXBA, 0, 0);
- snd_emu10k1_ptr_write(emu, ADCBS, 0, ADCBS_BUFSIZE_NONE);
- snd_emu10k1_ptr_write(emu, ADCBA, 0, 0);
-
- /* disable channel interrupt */
- outl(0, emu->port + INTE);
- snd_emu10k1_ptr_write(emu, CLIEL, 0, 0);
- snd_emu10k1_ptr_write(emu, CLIEH, 0, 0);
- snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
- snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
-
- if (emu->audigy) {
- /* set SPDIF bypass mode */
- snd_emu10k1_ptr_write(emu, SPBYPASS, 0, SPBYPASS_FORMAT);
- /* enable rear left + rear right AC97 slots */
- snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_REAR_RIGHT |
- AC97SLOT_REAR_LEFT);
- }
-
- /* init envelope engine */
- for (ch = 0; ch < NUM_G; ch++)
- snd_emu10k1_voice_init(emu, ch);
-
- snd_emu10k1_ptr_write(emu, SPCS0, 0, emu->spdif_bits[0]);
- snd_emu10k1_ptr_write(emu, SPCS1, 0, emu->spdif_bits[1]);
- snd_emu10k1_ptr_write(emu, SPCS2, 0, emu->spdif_bits[2]);
-
- if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
- /* Hacks for Alice3 to work independent of haP16V driver */
- /* Setup SRCMulti_I2S SamplingRate */
- tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
- tmp &= 0xfffff1ff;
- tmp |= (0x2<<9);
- snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
-
- /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
- snd_emu10k1_ptr20_write(emu, SRCSel, 0, 0x14);
- /* Setup SRCMulti Input Audio Enable */
- /* Use 0xFFFFFFFF to enable P16V sounds. */
- snd_emu10k1_ptr20_write(emu, SRCMULTI_ENABLE, 0, 0xFFFFFFFF);
-
- /* Enabled Phased (8-channel) P16V playback */
- outl(0x0201, emu->port + HCFG2);
- /* Set playback routing. */
- snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, 0x78e4);
- }
- if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */
- /* Hacks for Alice3 to work independent of haP16V driver */
- snd_printk(KERN_INFO "Audigy2 value: Special config.\n");
- /* Setup SRCMulti_I2S SamplingRate */
- tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
- tmp &= 0xfffff1ff;
- tmp |= (0x2<<9);
- snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
-
- /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
- outl(0x600000, emu->port + 0x20);
- outl(0x14, emu->port + 0x24);
-
- /* Setup SRCMulti Input Audio Enable */
- outl(0x7b0000, emu->port + 0x20);
- outl(0xFF000000, emu->port + 0x24);
-
- /* Setup SPDIF Out Audio Enable */
- /* The Audigy 2 Value has a separate SPDIF out,
- * so no need for a mixer switch
- */
- outl(0x7a0000, emu->port + 0x20);
- outl(0xFF000000, emu->port + 0x24);
- tmp = inl(emu->port + A_IOCFG) & ~0x8; /* Clear bit 3 */
- outl(tmp, emu->port + A_IOCFG);
- }
- if (emu->card_capabilities->spi_dac) { /* Audigy 2 ZS Notebook with DAC Wolfson WM8768/WM8568 */
- int size, n;
-
- size = ARRAY_SIZE(spi_dac_init);
- for (n = 0; n < size; n++)
- snd_emu10k1_spi_write(emu, spi_dac_init[n]);
-
- snd_emu10k1_ptr20_write(emu, 0x60, 0, 0x10);
- /* Enable GPIOs
- * GPIO0: Unknown
- * GPIO1: Speakers-enabled.
- * GPIO2: Unknown
- * GPIO3: Unknown
- * GPIO4: IEC958 Output on.
- * GPIO5: Unknown
- * GPIO6: Unknown
- * GPIO7: Unknown
- */
- outl(0x76, emu->port + A_IOCFG); /* Windows uses 0x3f76 */
- }
- if (emu->card_capabilities->i2c_adc) { /* Audigy 2 ZS Notebook with ADC Wolfson WM8775 */
- int size, n;
-
- snd_emu10k1_ptr20_write(emu, P17V_I2S_SRC_SEL, 0, 0x2020205f);
- tmp = inl(emu->port + A_IOCFG);
- outl(tmp | 0x4, emu->port + A_IOCFG); /* Set bit 2 for mic input */
- tmp = inl(emu->port + A_IOCFG);
- size = ARRAY_SIZE(i2c_adc_init);
- for (n = 0; n < size; n++)
- snd_emu10k1_i2c_write(emu, i2c_adc_init[n][0], i2c_adc_init[n][1]);
- for (n = 0; n < 4; n++) {
- emu->i2c_capture_volume[n][0] = 0xcf;
- emu->i2c_capture_volume[n][1] = 0xcf;
- }
- }
-
-
- snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr);
- snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */
- snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */
-
- silent_page = (emu->silent_page.addr << 1) | MAP_PTI_MASK;
- for (ch = 0; ch < NUM_G; ch++) {
- snd_emu10k1_ptr_write(emu, MAPA, ch, silent_page);
- snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page);
- }
-
- if (emu->card_capabilities->emu_model) {
- outl(HCFG_AUTOMUTE_ASYNC |
- HCFG_EMU32_SLAVE |
- HCFG_AUDIOENABLE, emu->port + HCFG);
- /*
- * Hokay, setup HCFG
- * Mute Disable Audio = 0
- * Lock Tank Memory = 1
- * Lock Sound Memory = 0
- * Auto Mute = 1
- */
- } else if (emu->audigy) {
- if (emu->revision == 4) /* audigy2 */
- outl(HCFG_AUDIOENABLE |
- HCFG_AC3ENABLE_CDSPDIF |
- HCFG_AC3ENABLE_GPSPDIF |
- HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
- else
- outl(HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
- /* FIXME: Remove all these emu->model and replace it with a card recognition parameter,
- * e.g. card_capabilities->joystick */
- } else if (emu->model == 0x20 ||
- emu->model == 0xc400 ||
- (emu->model == 0x21 && emu->revision < 6))
- outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE, emu->port + HCFG);
- else
- /* With on-chip joystick */
- outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
-
- if (enable_ir) { /* enable IR for SB Live */
- if (emu->card_capabilities->emu_model) {
- ; /* Disable all access to A_IOCFG for the emu1010 */
- } else if (emu->card_capabilities->i2c_adc) {
- ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */
- } else if (emu->audigy) {
- unsigned int reg = inl(emu->port + A_IOCFG);
- outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
- udelay(500);
- outl(reg | A_IOCFG_GPOUT1 | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
- udelay(100);
- outl(reg, emu->port + A_IOCFG);
- } else {
- unsigned int reg = inl(emu->port + HCFG);
- outl(reg | HCFG_GPOUT2, emu->port + HCFG);
- udelay(500);
- outl(reg | HCFG_GPOUT1 | HCFG_GPOUT2, emu->port + HCFG);
- udelay(100);
- outl(reg, emu->port + HCFG);
- }
- }
-
- if (emu->card_capabilities->emu_model) {
- ; /* Disable all access to A_IOCFG for the emu1010 */
- } else if (emu->card_capabilities->i2c_adc) {
- ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */
- } else if (emu->audigy) { /* enable analog output */
- unsigned int reg = inl(emu->port + A_IOCFG);
- outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
- }
-
- return 0;
-}
-
-static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
-{
- /*
- * Enable the audio bit
- */
- outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG);
-
- /* Enable analog/digital outs on audigy */
- if (emu->card_capabilities->emu_model) {
- ; /* Disable all access to A_IOCFG for the emu1010 */
- } else if (emu->card_capabilities->i2c_adc) {
- ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */
- } else if (emu->audigy) {
- outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG);
-
- if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
- /* Unmute Analog now. Set GPO6 to 1 for Apollo.
- * This has to be done after init ALice3 I2SOut beyond 48KHz.
- * So, sequence is important. */
- outl(inl(emu->port + A_IOCFG) | 0x0040, emu->port + A_IOCFG);
- } else if (emu->card_capabilities->ca0108_chip) { /* audigy2 value */
- /* Unmute Analog now. */
- outl(inl(emu->port + A_IOCFG) | 0x0060, emu->port + A_IOCFG);
- } else {
- /* Disable routing from AC97 line out to Front speakers */
- outl(inl(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG);
- }
- }
-
-#if 0
- {
- unsigned int tmp;
- /* FIXME: the following routine disables LiveDrive-II !! */
- /* TOSLink detection */
- emu->tos_link = 0;
- tmp = inl(emu->port + HCFG);
- if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {
- outl(tmp|0x800, emu->port + HCFG);
- udelay(50);
- if (tmp != (inl(emu->port + HCFG) & ~0x800)) {
- emu->tos_link = 1;
- outl(tmp, emu->port + HCFG);
- }
- }
- }
-#endif
-
- snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE);
-}
-
-int snd_emu10k1_done(struct snd_emu10k1 *emu)
-{
- int ch;
-
- outl(0, emu->port + INTE);
-
- /*
- * Shutdown the chip
- */
- for (ch = 0; ch < NUM_G; ch++)
- snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);
- for (ch = 0; ch < NUM_G; ch++) {
- snd_emu10k1_ptr_write(emu, VTFT, ch, 0);
- snd_emu10k1_ptr_write(emu, CVCF, ch, 0);
- snd_emu10k1_ptr_write(emu, PTRX, ch, 0);
- snd_emu10k1_ptr_write(emu, CPF, ch, 0);
- }
-
- /* reset recording buffers */
- snd_emu10k1_ptr_write(emu, MICBS, 0, 0);
- snd_emu10k1_ptr_write(emu, MICBA, 0, 0);
- snd_emu10k1_ptr_write(emu, FXBS, 0, 0);
- snd_emu10k1_ptr_write(emu, FXBA, 0, 0);
- snd_emu10k1_ptr_write(emu, FXWC, 0, 0);
- snd_emu10k1_ptr_write(emu, ADCBS, 0, ADCBS_BUFSIZE_NONE);
- snd_emu10k1_ptr_write(emu, ADCBA, 0, 0);
- snd_emu10k1_ptr_write(emu, TCBS, 0, TCBS_BUFFSIZE_16K);
- snd_emu10k1_ptr_write(emu, TCB, 0, 0);
- if (emu->audigy)
- snd_emu10k1_ptr_write(emu, A_DBG, 0, A_DBG_SINGLE_STEP);
- else
- snd_emu10k1_ptr_write(emu, DBG, 0, EMU10K1_DBG_SINGLE_STEP);
-
- /* disable channel interrupt */
- snd_emu10k1_ptr_write(emu, CLIEL, 0, 0);
- snd_emu10k1_ptr_write(emu, CLIEH, 0, 0);
- snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
- snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
-
- /* disable audio and lock cache */
- outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
- snd_emu10k1_ptr_write(emu, PTB, 0, 0);
-
- return 0;
-}
-
-/*************************************************************************
- * ECARD functional implementation
- *************************************************************************/
-
-/* In A1 Silicon, these bits are in the HC register */
-#define HOOKN_BIT (1L << 12)
-#define HANDN_BIT (1L << 11)
-#define PULSEN_BIT (1L << 10)
-
-#define EC_GDI1 (1 << 13)
-#define EC_GDI0 (1 << 14)
-
-#define EC_NUM_CONTROL_BITS 20
-
-#define EC_AC3_DATA_SELN 0x0001L
-#define EC_EE_DATA_SEL 0x0002L
-#define EC_EE_CNTRL_SELN 0x0004L
-#define EC_EECLK 0x0008L
-#define EC_EECS 0x0010L
-#define EC_EESDO 0x0020L
-#define EC_TRIM_CSN 0x0040L
-#define EC_TRIM_SCLK 0x0080L
-#define EC_TRIM_SDATA 0x0100L
-#define EC_TRIM_MUTEN 0x0200L
-#define EC_ADCCAL 0x0400L
-#define EC_ADCRSTN 0x0800L
-#define EC_DACCAL 0x1000L
-#define EC_DACMUTEN 0x2000L
-#define EC_LEDN 0x4000L
-
-#define EC_SPDIF0_SEL_SHIFT 15
-#define EC_SPDIF1_SEL_SHIFT 17
-#define EC_SPDIF0_SEL_MASK (0x3L << EC_SPDIF0_SEL_SHIFT)
-#define EC_SPDIF1_SEL_MASK (0x7L << EC_SPDIF1_SEL_SHIFT)
-#define EC_SPDIF0_SELECT(_x) (((_x) << EC_SPDIF0_SEL_SHIFT) & EC_SPDIF0_SEL_MASK)
-#define EC_SPDIF1_SELECT(_x) (((_x) << EC_SPDIF1_SEL_SHIFT) & EC_SPDIF1_SEL_MASK)
-#define EC_CURRENT_PROM_VERSION 0x01 /* Self-explanatory. This should
- * be incremented any time the EEPROM's
- * format is changed. */
-
-#define EC_EEPROM_SIZE 0x40 /* ECARD EEPROM has 64 16-bit words */
-
-/* Addresses for special values stored in to EEPROM */
-#define EC_PROM_VERSION_ADDR 0x20 /* Address of the current prom version */
-#define EC_BOARDREV0_ADDR 0x21 /* LSW of board rev */
-#define EC_BOARDREV1_ADDR 0x22 /* MSW of board rev */
-
-#define EC_LAST_PROMFILE_ADDR 0x2f
-
-#define EC_SERIALNUM_ADDR 0x30 /* First word of serial number. The
- * can be up to 30 characters in length
- * and is stored as a NULL-terminated
- * ASCII string. Any unused bytes must be
- * filled with zeros */
-#define EC_CHECKSUM_ADDR 0x3f /* Location at which checksum is stored */
-
-
-/* Most of this stuff is pretty self-evident. According to the hardware
- * dudes, we need to leave the ADCCAL bit low in order to avoid a DC
- * offset problem. Weird.
- */
-#define EC_RAW_RUN_MODE (EC_DACMUTEN | EC_ADCRSTN | EC_TRIM_MUTEN | \
- EC_TRIM_CSN)
-
-
-#define EC_DEFAULT_ADC_GAIN 0xC4C4
-#define EC_DEFAULT_SPDIF0_SEL 0x0
-#define EC_DEFAULT_SPDIF1_SEL 0x4
-
-/**************************************************************************
- * @func Clock bits into the Ecard's control latch. The Ecard uses a
- * control latch will is loaded bit-serially by toggling the Modem control
- * lines from function 2 on the E8010. This function hides these details
- * and presents the illusion that we are actually writing to a distinct
- * register.
- */
-
-static void snd_emu10k1_ecard_write(struct snd_emu10k1 *emu, unsigned int value)
-{
- unsigned short count;
- unsigned int data;
- unsigned long hc_port;
- unsigned int hc_value;
-
- hc_port = emu->port + HCFG;
- hc_value = inl(hc_port) & ~(HOOKN_BIT | HANDN_BIT | PULSEN_BIT);
- outl(hc_value, hc_port);
-
- for (count = 0; count < EC_NUM_CONTROL_BITS; count++) {
-
- /* Set up the value */
- data = ((value & 0x1) ? PULSEN_BIT : 0);
- value >>= 1;
-
- outl(hc_value | data, hc_port);
-
- /* Clock the shift register */
- outl(hc_value | data | HANDN_BIT, hc_port);
- outl(hc_value | data, hc_port);
- }
-
- /* Latch the bits */
- outl(hc_value | HOOKN_BIT, hc_port);
- outl(hc_value, hc_port);
-}
-
-/**************************************************************************
- * @func Set the gain of the ECARD's CS3310 Trim/gain controller. The
- * trim value consists of a 16bit value which is composed of two
- * 8 bit gain/trim values, one for the left channel and one for the
- * right channel. The following table maps from the Gain/Attenuation
- * value in decibels into the corresponding bit pattern for a single
- * channel.
- */
-
-static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 *emu,
- unsigned short gain)
-{
- unsigned int bit;
-
- /* Enable writing to the TRIM registers */
- snd_emu10k1_ecard_write(emu, emu->ecard_ctrl & ~EC_TRIM_CSN);
-
- /* Do it again to insure that we meet hold time requirements */
- snd_emu10k1_ecard_write(emu, emu->ecard_ctrl & ~EC_TRIM_CSN);
-
- for (bit = (1 << 15); bit; bit >>= 1) {
- unsigned int value;
-
- value = emu->ecard_ctrl & ~(EC_TRIM_CSN | EC_TRIM_SDATA);
-
- if (gain & bit)
- value |= EC_TRIM_SDATA;
-
- /* Clock the bit */
- snd_emu10k1_ecard_write(emu, value);
- snd_emu10k1_ecard_write(emu, value | EC_TRIM_SCLK);
- snd_emu10k1_ecard_write(emu, value);
- }
-
- snd_emu10k1_ecard_write(emu, emu->ecard_ctrl);
-}
-
-static int snd_emu10k1_ecard_init(struct snd_emu10k1 *emu)
-{
- unsigned int hc_value;
-
- /* Set up the initial settings */
- emu->ecard_ctrl = EC_RAW_RUN_MODE |
- EC_SPDIF0_SELECT(EC_DEFAULT_SPDIF0_SEL) |
- EC_SPDIF1_SELECT(EC_DEFAULT_SPDIF1_SEL);
-
- /* Step 0: Set the codec type in the hardware control register
- * and enable audio output */
- hc_value = inl(emu->port + HCFG);
- outl(hc_value | HCFG_AUDIOENABLE | HCFG_CODECFORMAT_I2S, emu->port + HCFG);
- inl(emu->port + HCFG);
-
- /* Step 1: Turn off the led and deassert TRIM_CS */
- snd_emu10k1_ecard_write(emu, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN);
-
- /* Step 2: Calibrate the ADC and DAC */
- snd_emu10k1_ecard_write(emu, EC_DACCAL | EC_LEDN | EC_TRIM_CSN);
-
- /* Step 3: Wait for awhile; XXX We can't get away with this
- * under a real operating system; we'll need to block and wait that
- * way. */
- snd_emu10k1_wait(emu, 48000);
-
- /* Step 4: Switch off the DAC and ADC calibration. Note
- * That ADC_CAL is actually an inverted signal, so we assert
- * it here to stop calibration. */
- snd_emu10k1_ecard_write(emu, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN);
-
- /* Step 4: Switch into run mode */
- snd_emu10k1_ecard_write(emu, emu->ecard_ctrl);
-
- /* Step 5: Set the analog input gain */
- snd_emu10k1_ecard_setadcgain(emu, EC_DEFAULT_ADC_GAIN);
-
- return 0;
-}
-
-static int snd_emu10k1_cardbus_init(struct snd_emu10k1 *emu)
-{
- unsigned long special_port;
- unsigned int value;
-
- /* Special initialisation routine
- * before the rest of the IO-Ports become active.
- */
- special_port = emu->port + 0x38;
- value = inl(special_port);
- outl(0x00d00000, special_port);
- value = inl(special_port);
- outl(0x00d00001, special_port);
- value = inl(special_port);
- outl(0x00d0005f, special_port);
- value = inl(special_port);
- outl(0x00d0007f, special_port);
- value = inl(special_port);
- outl(0x0090007f, special_port);
- value = inl(special_port);
-
- snd_emu10k1_ptr20_write(emu, TINA2_VOLUME, 0, 0xfefefefe); /* Defaults to 0x30303030 */
- /* Delay to give time for ADC chip to switch on. It needs 113ms */
- msleep(200);
- return 0;
-}
-
-static int snd_emu1010_load_firmware(struct snd_emu10k1 *emu, const char *filename)
-{
- int err;
- int n, i;
- int reg;
- int value;
- unsigned int write_post;
- unsigned long flags;
- const struct firmware *fw_entry;
-
- err = request_firmware(&fw_entry, filename, &emu->pci->dev);
- if (err != 0) {
- snd_printk(KERN_ERR "firmware: %s not found. Err = %d\n", filename, err);
- return err;
- }
- snd_printk(KERN_INFO "firmware size = 0x%zx\n", fw_entry->size);
-
- /* The FPGA is a Xilinx Spartan IIE XC2S50E */
- /* GPIO7 -> FPGA PGMN
- * GPIO6 -> FPGA CCLK
- * GPIO5 -> FPGA DIN
- * FPGA CONFIG OFF -> FPGA PGMN
- */
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(0x00, emu->port + A_IOCFG); /* Set PGMN low for 1uS. */
- write_post = inl(emu->port + A_IOCFG);
- udelay(100);
- outl(0x80, emu->port + A_IOCFG); /* Leave bit 7 set during netlist setup. */
- write_post = inl(emu->port + A_IOCFG);
- udelay(100); /* Allow FPGA memory to clean */
- for (n = 0; n < fw_entry->size; n++) {
- value = fw_entry->data[n];
- for (i = 0; i < 8; i++) {
- reg = 0x80;
- if (value & 0x1)
- reg = reg | 0x20;
- value = value >> 1;
- outl(reg, emu->port + A_IOCFG);
- write_post = inl(emu->port + A_IOCFG);
- outl(reg | 0x40, emu->port + A_IOCFG);
- write_post = inl(emu->port + A_IOCFG);
- }
- }
- /* After programming, set GPIO bit 4 high again. */
- outl(0x10, emu->port + A_IOCFG);
- write_post = inl(emu->port + A_IOCFG);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-
- release_firmware(fw_entry);
- return 0;
-}
-
-static int emu1010_firmware_thread(void *data)
-{
- struct snd_emu10k1 *emu = data;
- u32 tmp, tmp2, reg;
- int err;
-
- for (;;) {
- /* Delay to allow Audio Dock to settle */
- msleep_interruptible(1000);
- if (kthread_should_stop())
- break;
- snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp); /* IRQ Status */
- snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg); /* OPTIONS: Which cards are attached to the EMU */
- if (reg & EMU_HANA_OPTION_DOCK_OFFLINE) {
- /* Audio Dock attached */
- /* Return to Audio Dock programming mode */
- snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n");
- snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK);
- if (emu->card_capabilities->emu_model ==
- EMU_MODEL_EMU1010) {
- err = snd_emu1010_load_firmware(emu, DOCK_FILENAME);
- if (err != 0)
- continue;
- } else if (emu->card_capabilities->emu_model ==
- EMU_MODEL_EMU1010B) {
- err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME);
- if (err != 0)
- continue;
- } else if (emu->card_capabilities->emu_model ==
- EMU_MODEL_EMU1616) {
- err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME);
- if (err != 0)
- continue;
- }
-
- snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0);
- snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &reg);
- snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS = 0x%x\n", reg);
- /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
- snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
- snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID = 0x%x\n", reg);
- if ((reg & 0x1f) != 0x15) {
- /* FPGA failed to be programmed */
- snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg = 0x%x\n", reg);
- continue;
- }
- snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n");
- snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp);
- snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2);
- snd_printk(KERN_INFO "Audio Dock ver: %u.%u\n",
- tmp, tmp2);
- /* Sync clocking between 1010 and Dock */
- /* Allow DLL to settle */
- msleep(10);
- /* Unmute all. Default is muted after a firmware load */
- snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);
- }
- }
- snd_printk(KERN_INFO "emu1010: firmware thread stopping\n");
- return 0;
-}
-
-/*
- * EMU-1010 - details found out from this driver, official MS Win drivers,
- * testing the card:
- *
- * Audigy2 (aka Alice2):
- * ---------------------
- * * communication over PCI
- * * conversion of 32-bit data coming over EMU32 links from HANA FPGA
- * to 2 x 16-bit, using internal DSP instructions
- * * slave mode, clock supplied by HANA
- * * linked to HANA using:
- * 32 x 32-bit serial EMU32 output channels
- * 16 x EMU32 input channels
- * (?) x I2S I/O channels (?)
- *
- * FPGA (aka HANA):
- * ---------------
- * * provides all (?) physical inputs and outputs of the card
- * (ADC, DAC, SPDIF I/O, ADAT I/O, etc.)
- * * provides clock signal for the card and Alice2
- * * two crystals - for 44.1kHz and 48kHz multiples
- * * provides internal routing of signal sources to signal destinations
- * * inputs/outputs to Alice2 - see above
- *
- * Current status of the driver:
- * ----------------------------
- * * only 44.1/48kHz supported (the MS Win driver supports up to 192 kHz)
- * * PCM device nb. 2:
- * 16 x 16-bit playback - snd_emu10k1_fx8010_playback_ops
- * 16 x 32-bit capture - snd_emu10k1_capture_efx_ops
- */
-static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
-{
- unsigned int i;
- u32 tmp, tmp2, reg;
- int err;
- const char *filename = NULL;
-
- snd_printk(KERN_INFO "emu1010: Special config.\n");
- /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
- * Lock Sound Memory Cache, Lock Tank Memory Cache,
- * Mute all codecs.
- */
- outl(0x0005a00c, emu->port + HCFG);
- /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
- * Lock Tank Memory Cache,
- * Mute all codecs.
- */
- outl(0x0005a004, emu->port + HCFG);
- /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
- * Mute all codecs.
- */
- outl(0x0005a000, emu->port + HCFG);
- /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
- * Mute all codecs.
- */
- outl(0x0005a000, emu->port + HCFG);
-
- /* Disable 48Volt power to Audio Dock */
- snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0);
-
- /* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */
- snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
- snd_printdd("reg1 = 0x%x\n", reg);
- if ((reg & 0x3f) == 0x15) {
- /* FPGA netlist already present so clear it */
- /* Return to programming mode */
-
- snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0x02);
- }
- snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
- snd_printdd("reg2 = 0x%x\n", reg);
- if ((reg & 0x3f) == 0x15) {
- /* FPGA failed to return to programming mode */
- snd_printk(KERN_INFO "emu1010: FPGA failed to return to programming mode\n");
- return -ENODEV;
- }
- snd_printk(KERN_INFO "emu1010: EMU_HANA_ID = 0x%x\n", reg);
- switch (emu->card_capabilities->emu_model) {
- case EMU_MODEL_EMU1010:
- filename = HANA_FILENAME;
- break;
- case EMU_MODEL_EMU1010B:
- filename = EMU1010B_FILENAME;
- break;
- case EMU_MODEL_EMU1616:
- filename = EMU1010_NOTEBOOK_FILENAME;
- break;
- case EMU_MODEL_EMU0404:
- filename = EMU0404_FILENAME;
- break;
- default:
- filename = NULL;
- return -ENODEV;
- break;
- }
- snd_printk(KERN_INFO "emu1010: filename %s testing\n", filename);
- err = snd_emu1010_load_firmware(emu, filename);
- if (err != 0) {
- snd_printk(
- KERN_INFO "emu1010: Loading Firmware file %s failed\n",
- filename);
- return err;
- }
-
- /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
- snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
- if ((reg & 0x3f) != 0x15) {
- /* FPGA failed to be programmed */
- snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file failed, reg = 0x%x\n", reg);
- return -ENODEV;
- }
-
- snd_printk(KERN_INFO "emu1010: Hana Firmware loaded\n");
- snd_emu1010_fpga_read(emu, EMU_HANA_MAJOR_REV, &tmp);
- snd_emu1010_fpga_read(emu, EMU_HANA_MINOR_REV, &tmp2);
- snd_printk(KERN_INFO "emu1010: Hana version: %u.%u\n", tmp, tmp2);
- /* Enable 48Volt power to Audio Dock */
- snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, EMU_HANA_DOCK_PWR_ON);
-
- snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);
- snd_printk(KERN_INFO "emu1010: Card options = 0x%x\n", reg);
- snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);
- snd_printk(KERN_INFO "emu1010: Card options = 0x%x\n", reg);
- snd_emu1010_fpga_read(emu, EMU_HANA_OPTICAL_TYPE, &tmp);
- /* Optical -> ADAT I/O */
- /* 0 : SPDIF
- * 1 : ADAT
- */
- emu->emu1010.optical_in = 1; /* IN_ADAT */
- emu->emu1010.optical_out = 1; /* IN_ADAT */
- tmp = 0;
- tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) |
- (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0);
- snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp);
- snd_emu1010_fpga_read(emu, EMU_HANA_ADC_PADS, &tmp);
- /* Set no attenuation on Audio Dock pads. */
- snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, 0x00);
- emu->emu1010.adc_pads = 0x00;
- snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp);
- /* Unmute Audio dock DACs, Headphone source DAC-4. */
- snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30);
- snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12);
- snd_emu1010_fpga_read(emu, EMU_HANA_DAC_PADS, &tmp);
- /* DAC PADs. */
- snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, 0x0f);
- emu->emu1010.dac_pads = 0x0f;
- snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp);
- snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30);
- snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp);
- /* SPDIF Format. Set Consumer mode, 24bit, copy enable */
- snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10);
- /* MIDI routing */
- snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19);
- /* Unknown. */
- snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c);
- /* IRQ Enable: All on */
- /* snd_emu1010_fpga_write(emu, 0x09, 0x0f ); */
- /* IRQ Enable: All off */
- snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00);
-
- snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);
- snd_printk(KERN_INFO "emu1010: Card options3 = 0x%x\n", reg);
- /* Default WCLK set to 48kHz. */
- snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x00);
- /* Word Clock source, Internal 48kHz x1 */
- snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K);
- /* snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X); */
- /* Audio Dock LEDs. */
- snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12);
-
-#if 0
- /* For 96kHz */
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_0, EMU_SRC_HAMOA_ADC_LEFT1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_1, EMU_SRC_HAMOA_ADC_RIGHT1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_4, EMU_SRC_HAMOA_ADC_LEFT2);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_5, EMU_SRC_HAMOA_ADC_RIGHT2);
-#endif
-#if 0
- /* For 192kHz */
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_0, EMU_SRC_HAMOA_ADC_LEFT1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_1, EMU_SRC_HAMOA_ADC_RIGHT1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_2, EMU_SRC_HAMOA_ADC_LEFT2);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_3, EMU_SRC_HAMOA_ADC_RIGHT2);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_4, EMU_SRC_HAMOA_ADC_LEFT3);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_5, EMU_SRC_HAMOA_ADC_RIGHT3);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_6, EMU_SRC_HAMOA_ADC_LEFT4);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_7, EMU_SRC_HAMOA_ADC_RIGHT4);
-#endif
-#if 1
- /* For 48kHz */
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_0, EMU_SRC_DOCK_MIC_A1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_1, EMU_SRC_DOCK_MIC_B1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_2, EMU_SRC_HAMOA_ADC_LEFT2);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_3, EMU_SRC_HAMOA_ADC_LEFT2);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_4, EMU_SRC_DOCK_ADC1_LEFT1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_5, EMU_SRC_DOCK_ADC1_RIGHT1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_6, EMU_SRC_DOCK_ADC2_LEFT1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_7, EMU_SRC_DOCK_ADC2_RIGHT1);
- /* Pavel Hofman - setting defaults for 8 more capture channels
- * Defaults only, users will set their own values anyways, let's
- * just copy/paste.
- */
-
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_8, EMU_SRC_DOCK_MIC_A1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_9, EMU_SRC_DOCK_MIC_B1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_A, EMU_SRC_HAMOA_ADC_LEFT2);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_B, EMU_SRC_HAMOA_ADC_LEFT2);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_C, EMU_SRC_DOCK_ADC1_LEFT1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_D, EMU_SRC_DOCK_ADC1_RIGHT1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_E, EMU_SRC_DOCK_ADC2_LEFT1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_F, EMU_SRC_DOCK_ADC2_RIGHT1);
-#endif
-#if 0
- /* Original */
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_4, EMU_SRC_HANA_ADAT);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_5, EMU_SRC_HANA_ADAT + 1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_6, EMU_SRC_HANA_ADAT + 2);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_7, EMU_SRC_HANA_ADAT + 3);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_8, EMU_SRC_HANA_ADAT + 4);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_9, EMU_SRC_HANA_ADAT + 5);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_A, EMU_SRC_HANA_ADAT + 6);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_B, EMU_SRC_HANA_ADAT + 7);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_C, EMU_SRC_DOCK_MIC_A1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_D, EMU_SRC_DOCK_MIC_B1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_E, EMU_SRC_HAMOA_ADC_LEFT2);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE2_EMU32_F, EMU_SRC_HAMOA_ADC_LEFT2);
-#endif
- for (i = 0; i < 0x20; i++) {
- /* AudioDock Elink <- Silence */
- snd_emu1010_fpga_link_dst_src_write(emu, 0x0100 + i, EMU_SRC_SILENCE);
- }
- for (i = 0; i < 4; i++) {
- /* Hana SPDIF Out <- Silence */
- snd_emu1010_fpga_link_dst_src_write(emu, 0x0200 + i, EMU_SRC_SILENCE);
- }
- for (i = 0; i < 7; i++) {
- /* Hamoa DAC <- Silence */
- snd_emu1010_fpga_link_dst_src_write(emu, 0x0300 + i, EMU_SRC_SILENCE);
- }
- for (i = 0; i < 7; i++) {
- /* Hana ADAT Out <- Silence */
- snd_emu1010_fpga_link_dst_src_write(emu, EMU_DST_HANA_ADAT + i, EMU_SRC_SILENCE);
- }
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE_I2S0_LEFT, EMU_SRC_DOCK_ADC1_LEFT1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE_I2S0_RIGHT, EMU_SRC_DOCK_ADC1_RIGHT1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE_I2S1_LEFT, EMU_SRC_DOCK_ADC2_LEFT1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE_I2S1_RIGHT, EMU_SRC_DOCK_ADC2_RIGHT1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE_I2S2_LEFT, EMU_SRC_DOCK_ADC3_LEFT1);
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_ALICE_I2S2_RIGHT, EMU_SRC_DOCK_ADC3_RIGHT1);
- snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x01); /* Unmute all */
-
- snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp);
-
- /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave,
- * Lock Sound Memory Cache, Lock Tank Memory Cache,
- * Mute all codecs.
- */
- outl(0x0000a000, emu->port + HCFG);
- /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave,
- * Lock Sound Memory Cache, Lock Tank Memory Cache,
- * Un-Mute all codecs.
- */
- outl(0x0000a001, emu->port + HCFG);
-
- /* Initial boot complete. Now patches */
-
- snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp);
- snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); /* MIDI Route */
- snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); /* Unknown */
- snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); /* MIDI Route */
- snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); /* Unknown */
- snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp);
- snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10); /* SPDIF Format spdif (or 0x11 for aes/ebu) */
-
- /* Start Micro/Audio Dock firmware loader thread */
- if (!emu->emu1010.firmware_thread) {
- emu->emu1010.firmware_thread =
- kthread_create(emu1010_firmware_thread, emu,
- "emu1010_firmware");
- wake_up_process(emu->emu1010.firmware_thread);
- }
-
-#if 0
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32B + 2); /* ALICE2 bus 0xa2 */
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_HAMOA_DAC_RIGHT1, EMU_SRC_ALICE_EMU32B + 3); /* ALICE2 bus 0xa3 */
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_HANA_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 2); /* ALICE2 bus 0xb2 */
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_HANA_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 3); /* ALICE2 bus 0xb3 */
-#endif
- /* Default outputs */
- if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1616) {
- /* 1616(M) cardbus default outputs */
- /* ALICE2 bus 0xa0 */
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_DOCK_DAC1_LEFT1, EMU_SRC_ALICE_EMU32A + 0);
- emu->emu1010.output_source[0] = 17;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_DOCK_DAC1_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
- emu->emu1010.output_source[1] = 18;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_DOCK_DAC2_LEFT1, EMU_SRC_ALICE_EMU32A + 2);
- emu->emu1010.output_source[2] = 19;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_DOCK_DAC2_RIGHT1, EMU_SRC_ALICE_EMU32A + 3);
- emu->emu1010.output_source[3] = 20;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_DOCK_DAC3_LEFT1, EMU_SRC_ALICE_EMU32A + 4);
- emu->emu1010.output_source[4] = 21;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_DOCK_DAC3_RIGHT1, EMU_SRC_ALICE_EMU32A + 5);
- emu->emu1010.output_source[5] = 22;
- /* ALICE2 bus 0xa0 */
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_MANA_DAC_LEFT, EMU_SRC_ALICE_EMU32A + 0);
- emu->emu1010.output_source[16] = 17;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_MANA_DAC_RIGHT, EMU_SRC_ALICE_EMU32A + 1);
- emu->emu1010.output_source[17] = 18;
- } else {
- /* ALICE2 bus 0xa0 */
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_DOCK_DAC1_LEFT1, EMU_SRC_ALICE_EMU32A + 0);
- emu->emu1010.output_source[0] = 21;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_DOCK_DAC1_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
- emu->emu1010.output_source[1] = 22;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_DOCK_DAC2_LEFT1, EMU_SRC_ALICE_EMU32A + 2);
- emu->emu1010.output_source[2] = 23;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_DOCK_DAC2_RIGHT1, EMU_SRC_ALICE_EMU32A + 3);
- emu->emu1010.output_source[3] = 24;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_DOCK_DAC3_LEFT1, EMU_SRC_ALICE_EMU32A + 4);
- emu->emu1010.output_source[4] = 25;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_DOCK_DAC3_RIGHT1, EMU_SRC_ALICE_EMU32A + 5);
- emu->emu1010.output_source[5] = 26;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_DOCK_DAC4_LEFT1, EMU_SRC_ALICE_EMU32A + 6);
- emu->emu1010.output_source[6] = 27;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_DOCK_DAC4_RIGHT1, EMU_SRC_ALICE_EMU32A + 7);
- emu->emu1010.output_source[7] = 28;
- /* ALICE2 bus 0xa0 */
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_DOCK_PHONES_LEFT1, EMU_SRC_ALICE_EMU32A + 0);
- emu->emu1010.output_source[8] = 21;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_DOCK_PHONES_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
- emu->emu1010.output_source[9] = 22;
- /* ALICE2 bus 0xa0 */
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_DOCK_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 0);
- emu->emu1010.output_source[10] = 21;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_DOCK_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
- emu->emu1010.output_source[11] = 22;
- /* ALICE2 bus 0xa0 */
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_HANA_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 0);
- emu->emu1010.output_source[12] = 21;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_HANA_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
- emu->emu1010.output_source[13] = 22;
- /* ALICE2 bus 0xa0 */
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32A + 0);
- emu->emu1010.output_source[14] = 21;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_HAMOA_DAC_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
- emu->emu1010.output_source[15] = 22;
- /* ALICE2 bus 0xa0 */
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_HANA_ADAT, EMU_SRC_ALICE_EMU32A + 0);
- emu->emu1010.output_source[16] = 21;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_HANA_ADAT + 1, EMU_SRC_ALICE_EMU32A + 1);
- emu->emu1010.output_source[17] = 22;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_HANA_ADAT + 2, EMU_SRC_ALICE_EMU32A + 2);
- emu->emu1010.output_source[18] = 23;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_HANA_ADAT + 3, EMU_SRC_ALICE_EMU32A + 3);
- emu->emu1010.output_source[19] = 24;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_HANA_ADAT + 4, EMU_SRC_ALICE_EMU32A + 4);
- emu->emu1010.output_source[20] = 25;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_HANA_ADAT + 5, EMU_SRC_ALICE_EMU32A + 5);
- emu->emu1010.output_source[21] = 26;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_HANA_ADAT + 6, EMU_SRC_ALICE_EMU32A + 6);
- emu->emu1010.output_source[22] = 27;
- snd_emu1010_fpga_link_dst_src_write(emu,
- EMU_DST_HANA_ADAT + 7, EMU_SRC_ALICE_EMU32A + 7);
- emu->emu1010.output_source[23] = 28;
- }
- /* TEMP: Select SPDIF in/out */
- /* snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); */ /* Output spdif */
-
- /* TEMP: Select 48kHz SPDIF out */
- snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x0); /* Mute all */
- snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x0); /* Default fallback clock 48kHz */
- /* Word Clock source, Internal 48kHz x1 */
- snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K);
- /* snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X); */
- emu->emu1010.internal_clock = 1; /* 48000 */
- snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12); /* Set LEDs on Audio Dock */
- snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x1); /* Unmute all */
- /* snd_emu1010_fpga_write(emu, 0x7, 0x0); */ /* Mute all */
- /* snd_emu1010_fpga_write(emu, 0x7, 0x1); */ /* Unmute all */
- /* snd_emu1010_fpga_write(emu, 0xe, 0x12); */ /* Set LEDs on Audio Dock */
-
- return 0;
-}
-/*
- * Create the EMU10K1 instance
- */
-
-#ifdef CONFIG_PM
-static int alloc_pm_buffer(struct snd_emu10k1 *emu);
-static void free_pm_buffer(struct snd_emu10k1 *emu);
-#endif
-
-static int snd_emu10k1_free(struct snd_emu10k1 *emu)
-{
- if (emu->port) { /* avoid access to already used hardware */
- snd_emu10k1_fx8010_tram_setup(emu, 0);
- snd_emu10k1_done(emu);
- snd_emu10k1_free_efx(emu);
- }
- if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1010) {
- /* Disable 48Volt power to Audio Dock */
- snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0);
- }
- if (emu->emu1010.firmware_thread)
- kthread_stop(emu->emu1010.firmware_thread);
- if (emu->irq >= 0)
- free_irq(emu->irq, emu);
- /* remove reserved page */
- if (emu->reserved_page) {
- snd_emu10k1_synth_free(emu,
- (struct snd_util_memblk *)emu->reserved_page);
- emu->reserved_page = NULL;
- }
- if (emu->memhdr)
- snd_util_memhdr_free(emu->memhdr);
- if (emu->silent_page.area)
- snd_dma_free_pages(&emu->silent_page);
- if (emu->ptb_pages.area)
- snd_dma_free_pages(&emu->ptb_pages);
- vfree(emu->page_ptr_table);
- vfree(emu->page_addr_table);
-#ifdef CONFIG_PM
- free_pm_buffer(emu);
-#endif
- if (emu->port)
- pci_release_regions(emu->pci);
- if (emu->card_capabilities->ca0151_chip) /* P16V */
- snd_p16v_free(emu);
- pci_disable_device(emu->pci);
- kfree(emu);
- return 0;
-}
-
-static int snd_emu10k1_dev_free(struct snd_device *device)
-{
- struct snd_emu10k1 *emu = device->device_data;
- return snd_emu10k1_free(emu);
-}
-
-static struct snd_emu_chip_details emu_chip_details[] = {
- /* Audigy4 (Not PRO) SB0610 */
- /* Tested by James@superbug.co.uk 4th April 2006 */
- /* A_IOCFG bits
- * Output
- * 0: ?
- * 1: ?
- * 2: ?
- * 3: 0 - Digital Out, 1 - Line in
- * 4: ?
- * 5: ?
- * 6: ?
- * 7: ?
- * Input
- * 8: ?
- * 9: ?
- * A: Green jack sense (Front)
- * B: ?
- * C: Black jack sense (Rear/Side Right)
- * D: Yellow jack sense (Center/LFE/Side Left)
- * E: ?
- * F: ?
- *
- * Digital Out/Line in switch using A_IOCFG bit 3 (0x08)
- * 0 - Digital Out
- * 1 - Line in
- */
- /* Mic input not tested.
- * Analog CD input not tested
- * Digital Out not tested.
- * Line in working.
- * Audio output 5.1 working. Side outputs not working.
- */
- /* DSP: CA10300-IAT LF
- * DAC: Cirrus Logic CS4382-KQZ
- * ADC: Philips 1361T
- * AC97: Sigmatel STAC9750
- * CA0151: None
- */
- {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10211102,
- .driver = "Audigy2", .name = "SB Audigy 4 [SB0610]",
- .id = "Audigy2",
- .emu10k2_chip = 1,
- .ca0108_chip = 1,
- .spk71 = 1,
- .adc_1361t = 1, /* 24 bit capture instead of 16bit */
- .ac97_chip = 1} ,
- /* Audigy 2 Value AC3 out does not work yet.
- * Need to find out how to turn off interpolators.
- */
- /* Tested by James@superbug.co.uk 3rd July 2005 */
- /* DSP: CA0108-IAT
- * DAC: CS4382-KQ
- * ADC: Philips 1361T
- * AC97: STAC9750
- * CA0151: None
- */
- {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102,
- .driver = "Audigy2", .name = "SB Audigy 2 Value [SB0400]",
- .id = "Audigy2",
- .emu10k2_chip = 1,
- .ca0108_chip = 1,
- .spk71 = 1,
- .ac97_chip = 1} ,
- /* Audigy 2 ZS Notebook Cardbus card.*/
- /* Tested by James@superbug.co.uk 6th November 2006 */
- /* Audio output 7.1/Headphones working.
- * Digital output working. (AC3 not checked, only PCM)
- * Audio Mic/Line inputs working.
- * Digital input not tested.
- */
- /* DSP: Tina2
- * DAC: Wolfson WM8768/WM8568
- * ADC: Wolfson WM8775
- * AC97: None
- * CA0151: None
- */
- /* Tested by James@superbug.co.uk 4th April 2006 */
- /* A_IOCFG bits
- * Output
- * 0: Not Used
- * 1: 0 = Mute all the 7.1 channel out. 1 = unmute.
- * 2: Analog input 0 = line in, 1 = mic in
- * 3: Not Used
- * 4: Digital output 0 = off, 1 = on.
- * 5: Not Used
- * 6: Not Used
- * 7: Not Used
- * Input
- * All bits 1 (0x3fxx) means nothing plugged in.
- * 8-9: 0 = Line in/Mic, 2 = Optical in, 3 = Nothing.
- * A-B: 0 = Headphones, 2 = Optical out, 3 = Nothing.
- * C-D: 2 = Front/Rear/etc, 3 = nothing.
- * E-F: Always 0
- *
- */
- {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102,
- .driver = "Audigy2", .name = "SB Audigy 2 ZS Notebook [SB0530]",
- .id = "Audigy2",
- .emu10k2_chip = 1,
- .ca0108_chip = 1,
- .ca_cardbus_chip = 1,
- .spi_dac = 1,
- .i2c_adc = 1,
- .spk71 = 1} ,
- /* Tested by James@superbug.co.uk 4th Nov 2007. */
- {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102,
- .driver = "Audigy2", .name = "E-mu 1010 Notebook [MAEM8950]",
- .id = "EMU1010",
- .emu10k2_chip = 1,
- .ca0108_chip = 1,
- .ca_cardbus_chip = 1,
- .spk71 = 1 ,
- .emu_model = EMU_MODEL_EMU1616},
- /* Tested by James@superbug.co.uk 4th Nov 2007. */
- /* This is MAEM8960, 0202 is MAEM 8980 */
- {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40041102,
- .driver = "Audigy2", .name = "E-mu 1010b PCI [MAEM8960]",
- .id = "EMU1010",
- .emu10k2_chip = 1,
- .ca0108_chip = 1,
- .spk71 = 1,
- .emu_model = EMU_MODEL_EMU1010B}, /* EMU 1010 new revision */
- /* Tested by James@superbug.co.uk 8th July 2005. */
- /* This is MAEM8810, 0202 is MAEM8820 */
- {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102,
- .driver = "Audigy2", .name = "E-mu 1010 [MAEM8810]",
- .id = "EMU1010",
- .emu10k2_chip = 1,
- .ca0102_chip = 1,
- .spk71 = 1,
- .emu_model = EMU_MODEL_EMU1010}, /* EMU 1010 old revision */
- /* EMU0404b */
- {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40021102,
- .driver = "Audigy2", .name = "E-mu 0404b PCI [MAEM8852]",
- .id = "EMU0404",
- .emu10k2_chip = 1,
- .ca0108_chip = 1,
- .spk71 = 1,
- .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 new revision */
- /* Tested by James@superbug.co.uk 20-3-2007. */
- {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40021102,
- .driver = "Audigy2", .name = "E-mu 0404 [MAEM8850]",
- .id = "EMU0404",
- .emu10k2_chip = 1,
- .ca0102_chip = 1,
- .spk71 = 1,
- .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 */
- /* EMU0404 PCIe */
- {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40051102,
- .driver = "Audigy2", .name = "E-mu 0404 PCIe [MAEM8984]",
- .id = "EMU0404",
- .emu10k2_chip = 1,
- .ca0108_chip = 1,
- .spk71 = 1,
- .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 PCIe ver_03 */
- /* Note that all E-mu cards require kernel 2.6 or newer. */
- {.vendor = 0x1102, .device = 0x0008,
- .driver = "Audigy2", .name = "SB Audigy 2 Value [Unknown]",
- .id = "Audigy2",
- .emu10k2_chip = 1,
- .ca0108_chip = 1,
- .ac97_chip = 1} ,
- /* Tested by James@superbug.co.uk 3rd July 2005 */
- {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102,
- .driver = "Audigy2", .name = "SB Audigy 4 PRO [SB0380]",
- .id = "Audigy2",
- .emu10k2_chip = 1,
- .ca0102_chip = 1,
- .ca0151_chip = 1,
- .spk71 = 1,
- .spdif_bug = 1,
- .ac97_chip = 1} ,
- /* Tested by shane-alsa@cm.nu 5th Nov 2005 */
- /* The 0x20061102 does have SB0350 written on it
- * Just like 0x20021102
- */
- {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20061102,
- .driver = "Audigy2", .name = "SB Audigy 2 [SB0350b]",
- .id = "Audigy2",
- .emu10k2_chip = 1,
- .ca0102_chip = 1,
- .ca0151_chip = 1,
- .spk71 = 1,
- .spdif_bug = 1,
- .invert_shared_spdif = 1, /* digital/analog switch swapped */
- .ac97_chip = 1} ,
- /* 0x20051102 also has SB0350 written on it, treated as Audigy 2 ZS by
- Creative's Windows driver */
- {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20051102,
- .driver = "Audigy2", .name = "SB Audigy 2 ZS [SB0350a]",
- .id = "Audigy2",
- .emu10k2_chip = 1,
- .ca0102_chip = 1,
- .ca0151_chip = 1,
- .spk71 = 1,
- .spdif_bug = 1,
- .invert_shared_spdif = 1, /* digital/analog switch swapped */
- .ac97_chip = 1} ,
- {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102,
- .driver = "Audigy2", .name = "SB Audigy 2 ZS [SB0350]",
- .id = "Audigy2",
- .emu10k2_chip = 1,
- .ca0102_chip = 1,
- .ca0151_chip = 1,
- .spk71 = 1,
- .spdif_bug = 1,
- .invert_shared_spdif = 1, /* digital/analog switch swapped */
- .ac97_chip = 1} ,
- {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20011102,
- .driver = "Audigy2", .name = "SB Audigy 2 ZS [SB0360]",
- .id = "Audigy2",
- .emu10k2_chip = 1,
- .ca0102_chip = 1,
- .ca0151_chip = 1,
- .spk71 = 1,
- .spdif_bug = 1,
- .invert_shared_spdif = 1, /* digital/analog switch swapped */
- .ac97_chip = 1} ,
- /* Audigy 2 */
- /* Tested by James@superbug.co.uk 3rd July 2005 */
- /* DSP: CA0102-IAT
- * DAC: CS4382-KQ
- * ADC: Philips 1361T
- * AC97: STAC9721
- * CA0151: Yes
- */
- {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102,
- .driver = "Audigy2", .name = "SB Audigy 2 [SB0240]",
- .id = "Audigy2",
- .emu10k2_chip = 1,
- .ca0102_chip = 1,
- .ca0151_chip = 1,
- .spk71 = 1,
- .spdif_bug = 1,
- .adc_1361t = 1, /* 24 bit capture instead of 16bit */
- .ac97_chip = 1} ,
- {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102,
- .driver = "Audigy2", .name = "SB Audigy 2 Platinum EX [SB0280]",
- .id = "Audigy2",
- .emu10k2_chip = 1,
- .ca0102_chip = 1,
- .ca0151_chip = 1,
- .spk71 = 1,
- .spdif_bug = 1} ,
- /* Dell OEM/Creative Labs Audigy 2 ZS */
- /* See ALSA bug#1365 */
- {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10031102,
- .driver = "Audigy2", .name = "SB Audigy 2 ZS [SB0353]",
- .id = "Audigy2",
- .emu10k2_chip = 1,
- .ca0102_chip = 1,
- .ca0151_chip = 1,
- .spk71 = 1,
- .spdif_bug = 1,
- .invert_shared_spdif = 1, /* digital/analog switch swapped */
- .ac97_chip = 1} ,
- {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102,
- .driver = "Audigy2", .name = "SB Audigy 2 Platinum [SB0240P]",
- .id = "Audigy2",
- .emu10k2_chip = 1,
- .ca0102_chip = 1,
- .ca0151_chip = 1,
- .spk71 = 1,
- .spdif_bug = 1,
- .invert_shared_spdif = 1, /* digital/analog switch swapped */
- .adc_1361t = 1, /* 24 bit capture instead of 16bit. Fixes ALSA bug#324 */
- .ac97_chip = 1} ,
- {.vendor = 0x1102, .device = 0x0004, .revision = 0x04,
- .driver = "Audigy2", .name = "SB Audigy 2 [Unknown]",
- .id = "Audigy2",
- .emu10k2_chip = 1,
- .ca0102_chip = 1,
- .ca0151_chip = 1,
- .spdif_bug = 1,
- .ac97_chip = 1} ,
- {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00531102,
- .driver = "Audigy", .name = "SB Audigy 1 [SB0092]",
- .id = "Audigy",
- .emu10k2_chip = 1,
- .ca0102_chip = 1,
- .ac97_chip = 1} ,
- {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00521102,
- .driver = "Audigy", .name = "SB Audigy 1 ES [SB0160]",
- .id = "Audigy",
- .emu10k2_chip = 1,
- .ca0102_chip = 1,
- .spdif_bug = 1,
- .ac97_chip = 1} ,
- {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00511102,
- .driver = "Audigy", .name = "SB Audigy 1 [SB0090]",
- .id = "Audigy",
- .emu10k2_chip = 1,
- .ca0102_chip = 1,
- .ac97_chip = 1} ,
- {.vendor = 0x1102, .device = 0x0004,
- .driver = "Audigy", .name = "Audigy 1 [Unknown]",
- .id = "Audigy",
- .emu10k2_chip = 1,
- .ca0102_chip = 1,
- .ac97_chip = 1} ,
- {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x100a1102,
- .driver = "EMU10K1", .name = "SB Live! 5.1 [SB0220]",
- .id = "Live",
- .emu10k1_chip = 1,
- .ac97_chip = 1,
- .sblive51 = 1} ,
- {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806b1102,
- .driver = "EMU10K1", .name = "SB Live! [SB0105]",
- .id = "Live",
- .emu10k1_chip = 1,
- .ac97_chip = 1,
- .sblive51 = 1} ,
- {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806a1102,
- .driver = "EMU10K1", .name = "SB Live! Value [SB0103]",
- .id = "Live",
- .emu10k1_chip = 1,
- .ac97_chip = 1,
- .sblive51 = 1} ,
- {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80691102,
- .driver = "EMU10K1", .name = "SB Live! Value [SB0101]",
- .id = "Live",
- .emu10k1_chip = 1,
- .ac97_chip = 1,
- .sblive51 = 1} ,
- /* Tested by ALSA bug#1680 26th December 2005 */
- /* note: It really has SB0220 written on the card, */
- /* but it's SB0228 according to kx.inf */
- {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80661102,
- .driver = "EMU10K1", .name = "SB Live! 5.1 Dell OEM [SB0228]",
- .id = "Live",
- .emu10k1_chip = 1,
- .ac97_chip = 1,
- .sblive51 = 1} ,
- /* Tested by Thomas Zehetbauer 27th Aug 2005 */
- {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80651102,
- .driver = "EMU10K1", .name = "SB Live! 5.1 [SB0220]",
- .id = "Live",
- .emu10k1_chip = 1,
- .ac97_chip = 1,
- .sblive51 = 1} ,
- {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102,
- .driver = "EMU10K1", .name = "SB Live! 5.1",
- .id = "Live",
- .emu10k1_chip = 1,
- .ac97_chip = 1,
- .sblive51 = 1} ,
- /* Tested by alsa bugtrack user "hus" bug #1297 12th Aug 2005 */
- {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102,
- .driver = "EMU10K1", .name = "SB Live! 5.1 [SB0060]",
- .id = "Live",
- .emu10k1_chip = 1,
- .ac97_chip = 2, /* ac97 is optional; both SBLive 5.1 and platinum
- * share the same IDs!
- */
- .sblive51 = 1} ,
- {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102,
- .driver = "EMU10K1", .name = "SB Live! Value [CT4850]",
- .id = "Live",
- .emu10k1_chip = 1,
- .ac97_chip = 1,
- .sblive51 = 1} ,
- {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102,
- .driver = "EMU10K1", .name = "SB Live! Platinum [CT4760P]",
- .id = "Live",
- .emu10k1_chip = 1,
- .ac97_chip = 1} ,
- {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80321102,
- .driver = "EMU10K1", .name = "SB Live! Value [CT4871]",
- .id = "Live",
- .emu10k1_chip = 1,
- .ac97_chip = 1,
- .sblive51 = 1} ,
- {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80311102,
- .driver = "EMU10K1", .name = "SB Live! Value [CT4831]",
- .id = "Live",
- .emu10k1_chip = 1,
- .ac97_chip = 1,
- .sblive51 = 1} ,
- {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80281102,
- .driver = "EMU10K1", .name = "SB Live! Value [CT4870]",
- .id = "Live",
- .emu10k1_chip = 1,
- .ac97_chip = 1,
- .sblive51 = 1} ,
- /* Tested by James@superbug.co.uk 3rd July 2005 */
- {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80271102,
- .driver = "EMU10K1", .name = "SB Live! Value [CT4832]",
- .id = "Live",
- .emu10k1_chip = 1,
- .ac97_chip = 1,
- .sblive51 = 1} ,
- {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80261102,
- .driver = "EMU10K1", .name = "SB Live! Value [CT4830]",
- .id = "Live",
- .emu10k1_chip = 1,
- .ac97_chip = 1,
- .sblive51 = 1} ,
- {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80231102,
- .driver = "EMU10K1", .name = "SB PCI512 [CT4790]",
- .id = "Live",
- .emu10k1_chip = 1,
- .ac97_chip = 1,
- .sblive51 = 1} ,
- {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80221102,
- .driver = "EMU10K1", .name = "SB Live! Value [CT4780]",
- .id = "Live",
- .emu10k1_chip = 1,
- .ac97_chip = 1,
- .sblive51 = 1} ,
- {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102,
- .driver = "EMU10K1", .name = "E-mu APS [PC545]",
- .id = "APS",
- .emu10k1_chip = 1,
- .ecard = 1} ,
- {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00211102,
- .driver = "EMU10K1", .name = "SB Live! [CT4620]",
- .id = "Live",
- .emu10k1_chip = 1,
- .ac97_chip = 1,
- .sblive51 = 1} ,
- {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00201102,
- .driver = "EMU10K1", .name = "SB Live! Value [CT4670]",
- .id = "Live",
- .emu10k1_chip = 1,
- .ac97_chip = 1,
- .sblive51 = 1} ,
- {.vendor = 0x1102, .device = 0x0002,
- .driver = "EMU10K1", .name = "SB Live! [Unknown]",
- .id = "Live",
- .emu10k1_chip = 1,
- .ac97_chip = 1,
- .sblive51 = 1} ,
- { } /* terminator */
-};
-
-int __devinit snd_emu10k1_create(struct snd_card *card,
- struct pci_dev *pci,
- unsigned short extin_mask,
- unsigned short extout_mask,
- long max_cache_bytes,
- int enable_ir,
- uint subsystem,
- struct snd_emu10k1 **remu)
-{
- struct snd_emu10k1 *emu;
- int idx, err;
- int is_audigy;
- unsigned int silent_page;
- const struct snd_emu_chip_details *c;
- static struct snd_device_ops ops = {
- .dev_free = snd_emu10k1_dev_free,
- };
-
- *remu = NULL;
-
- /* enable PCI device */
- err = pci_enable_device(pci);
- if (err < 0)
- return err;
-
- emu = kzalloc(sizeof(*emu), GFP_KERNEL);
- if (emu == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
- emu->card = card;
- spin_lock_init(&emu->reg_lock);
- spin_lock_init(&emu->emu_lock);
- spin_lock_init(&emu->spi_lock);
- spin_lock_init(&emu->i2c_lock);
- spin_lock_init(&emu->voice_lock);
- spin_lock_init(&emu->synth_lock);
- spin_lock_init(&emu->memblk_lock);
- mutex_init(&emu->fx8010.lock);
- INIT_LIST_HEAD(&emu->mapped_link_head);
- INIT_LIST_HEAD(&emu->mapped_order_link_head);
- emu->pci = pci;
- emu->irq = -1;
- emu->synth = NULL;
- emu->get_synth_voice = NULL;
- /* read revision & serial */
- emu->revision = pci->revision;
- pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial);
- pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model);
- snd_printdd("vendor = 0x%x, device = 0x%x, subsystem_vendor_id = 0x%x, subsystem_id = 0x%x\n", pci->vendor, pci->device, emu->serial, emu->model);
-
- for (c = emu_chip_details; c->vendor; c++) {
- if (c->vendor == pci->vendor && c->device == pci->device) {
- if (subsystem) {
- if (c->subsystem && (c->subsystem == subsystem))
- break;
- else
- continue;
- } else {
- if (c->subsystem && (c->subsystem != emu->serial))
- continue;
- if (c->revision && c->revision != emu->revision)
- continue;
- }
- break;
- }
- }
- if (c->vendor == 0) {
- snd_printk(KERN_ERR "emu10k1: Card not recognised\n");
- kfree(emu);
- pci_disable_device(pci);
- return -ENOENT;
- }
- emu->card_capabilities = c;
- if (c->subsystem && !subsystem)
- snd_printdd("Sound card name = %s\n", c->name);
- else if (subsystem)
- snd_printdd("Sound card name = %s, "
- "vendor = 0x%x, device = 0x%x, subsystem = 0x%x. "
- "Forced to subsystem = 0x%x\n", c->name,
- pci->vendor, pci->device, emu->serial, c->subsystem);
- else
- snd_printdd("Sound card name = %s, "
- "vendor = 0x%x, device = 0x%x, subsystem = 0x%x.\n",
- c->name, pci->vendor, pci->device,
- emu->serial);
-
- if (!*card->id && c->id) {
- int i, n = 0;
- strlcpy(card->id, c->id, sizeof(card->id));
- for (;;) {
- for (i = 0; i < snd_ecards_limit; i++) {
- if (snd_cards[i] && !strcmp(snd_cards[i]->id, card->id))
- break;
- }
- if (i >= snd_ecards_limit)
- break;
- n++;
- if (n >= SNDRV_CARDS)
- break;
- snprintf(card->id, sizeof(card->id), "%s_%d", c->id, n);
- }
- }
-
- is_audigy = emu->audigy = c->emu10k2_chip;
-
- /* set the DMA transfer mask */
- emu->dma_mask = is_audigy ? AUDIGY_DMA_MASK : EMU10K1_DMA_MASK;
- if (pci_set_dma_mask(pci, emu->dma_mask) < 0 ||
- pci_set_consistent_dma_mask(pci, emu->dma_mask) < 0) {
- snd_printk(KERN_ERR "architecture does not support PCI busmaster DMA with mask 0x%lx\n", emu->dma_mask);
- kfree(emu);
- pci_disable_device(pci);
- return -ENXIO;
- }
- if (is_audigy)
- emu->gpr_base = A_FXGPREGBASE;
- else
- emu->gpr_base = FXGPREGBASE;
-
- err = pci_request_regions(pci, "EMU10K1");
- if (err < 0) {
- kfree(emu);
- pci_disable_device(pci);
- return err;
- }
- emu->port = pci_resource_start(pci, 0);
-
- emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT;
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
- 32 * 1024, &emu->ptb_pages) < 0) {
- err = -ENOMEM;
- goto error;
- }
-
- emu->page_ptr_table = vmalloc(emu->max_cache_pages * sizeof(void *));
- emu->page_addr_table = vmalloc(emu->max_cache_pages *
- sizeof(unsigned long));
- if (emu->page_ptr_table == NULL || emu->page_addr_table == NULL) {
- err = -ENOMEM;
- goto error;
- }
-
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
- EMUPAGESIZE, &emu->silent_page) < 0) {
- err = -ENOMEM;
- goto error;
- }
- emu->memhdr = snd_util_memhdr_new(emu->max_cache_pages * PAGE_SIZE);
- if (emu->memhdr == NULL) {
- err = -ENOMEM;
- goto error;
- }
- emu->memhdr->block_extra_size = sizeof(struct snd_emu10k1_memblk) -
- sizeof(struct snd_util_memblk);
-
- pci_set_master(pci);
-
- emu->fx8010.fxbus_mask = 0x303f;
- if (extin_mask == 0)
- extin_mask = 0x3fcf;
- if (extout_mask == 0)
- extout_mask = 0x7fff;
- emu->fx8010.extin_mask = extin_mask;
- emu->fx8010.extout_mask = extout_mask;
- emu->enable_ir = enable_ir;
-
- if (emu->card_capabilities->ca_cardbus_chip) {
- err = snd_emu10k1_cardbus_init(emu);
- if (err < 0)
- goto error;
- }
- if (emu->card_capabilities->ecard) {
- err = snd_emu10k1_ecard_init(emu);
- if (err < 0)
- goto error;
- } else if (emu->card_capabilities->emu_model) {
- err = snd_emu10k1_emu1010_init(emu);
- if (err < 0) {
- snd_emu10k1_free(emu);
- return err;
- }
- } else {
- /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
- does not support this, it shouldn't do any harm */
- snd_emu10k1_ptr_write(emu, AC97SLOT, 0,
- AC97SLOT_CNTR|AC97SLOT_LFE);
- }
-
- /* initialize TRAM setup */
- emu->fx8010.itram_size = (16 * 1024)/2;
- emu->fx8010.etram_pages.area = NULL;
- emu->fx8010.etram_pages.bytes = 0;
-
- /* irq handler must be registered after I/O ports are activated */
- if (request_irq(pci->irq, snd_emu10k1_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, emu)) {
- err = -EBUSY;
- goto error;
- }
- emu->irq = pci->irq;
-
- /*
- * Init to 0x02109204 :
- * Clock accuracy = 0 (1000ppm)
- * Sample Rate = 2 (48kHz)
- * Audio Channel = 1 (Left of 2)
- * Source Number = 0 (Unspecified)
- * Generation Status = 1 (Original for Cat Code 12)
- * Cat Code = 12 (Digital Signal Mixer)
- * Mode = 0 (Mode 0)
- * Emphasis = 0 (None)
- * CP = 1 (Copyright unasserted)
- * AN = 0 (Audio data)
- * P = 0 (Consumer)
- */
- emu->spdif_bits[0] = emu->spdif_bits[1] =
- emu->spdif_bits[2] = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
- SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
- SPCS_GENERATIONSTATUS | 0x00001200 |
- 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT;
-
- emu->reserved_page = (struct snd_emu10k1_memblk *)
- snd_emu10k1_synth_alloc(emu, 4096);
- if (emu->reserved_page)
- emu->reserved_page->map_locked = 1;
-
- /* Clear silent pages and set up pointers */
- memset(emu->silent_page.area, 0, PAGE_SIZE);
- silent_page = emu->silent_page.addr << 1;
- for (idx = 0; idx < MAXPAGES; idx++)
- ((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx);
-
- /* set up voice indices */
- for (idx = 0; idx < NUM_G; idx++) {
- emu->voices[idx].emu = emu;
- emu->voices[idx].number = idx;
- }
-
- err = snd_emu10k1_init(emu, enable_ir, 0);
- if (err < 0)
- goto error;
-#ifdef CONFIG_PM
- err = alloc_pm_buffer(emu);
- if (err < 0)
- goto error;
-#endif
-
- /* Initialize the effect engine */
- err = snd_emu10k1_init_efx(emu);
- if (err < 0)
- goto error;
- snd_emu10k1_audio_enable(emu);
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, emu, &ops);
- if (err < 0)
- goto error;
-
-#ifdef CONFIG_PROC_FS
- snd_emu10k1_proc_init(emu);
-#endif
-
- snd_card_set_dev(card, &pci->dev);
- *remu = emu;
- return 0;
-
- error:
- snd_emu10k1_free(emu);
- return err;
-}
-
-#ifdef CONFIG_PM
-static unsigned char saved_regs[] = {
- CPF, PTRX, CVCF, VTFT, Z1, Z2, PSST, DSL, CCCA, CCR, CLP,
- FXRT, MAPA, MAPB, ENVVOL, ATKHLDV, DCYSUSV, LFOVAL1, ENVVAL,
- ATKHLDM, DCYSUSM, LFOVAL2, IP, IFATN, PEFE, FMMOD, TREMFRQ, FM2FRQ2,
- TEMPENV, ADCCR, FXWC, MICBA, ADCBA, FXBA,
- MICBS, ADCBS, FXBS, CDCS, GPSCS, SPCS0, SPCS1, SPCS2,
- SPBYPASS, AC97SLOT, CDSRCS, GPSRCS, ZVSRCS, MICIDX, ADCIDX, FXIDX,
- 0xff /* end */
-};
-static unsigned char saved_regs_audigy[] = {
- A_ADCIDX, A_MICIDX, A_FXWC1, A_FXWC2, A_SAMPLE_RATE,
- A_FXRT2, A_SENDAMOUNTS, A_FXRT1,
- 0xff /* end */
-};
-
-static int __devinit alloc_pm_buffer(struct snd_emu10k1 *emu)
-{
- int size;
-
- size = ARRAY_SIZE(saved_regs);
- if (emu->audigy)
- size += ARRAY_SIZE(saved_regs_audigy);
- emu->saved_ptr = vmalloc(4 * NUM_G * size);
- if (!emu->saved_ptr)
- return -ENOMEM;
- if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0)
- return -ENOMEM;
- if (emu->card_capabilities->ca0151_chip &&
- snd_p16v_alloc_pm_buffer(emu) < 0)
- return -ENOMEM;
- return 0;
-}
-
-static void free_pm_buffer(struct snd_emu10k1 *emu)
-{
- vfree(emu->saved_ptr);
- snd_emu10k1_efx_free_pm_buffer(emu);
- if (emu->card_capabilities->ca0151_chip)
- snd_p16v_free_pm_buffer(emu);
-}
-
-void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu)
-{
- int i;
- unsigned char *reg;
- unsigned int *val;
-
- val = emu->saved_ptr;
- for (reg = saved_regs; *reg != 0xff; reg++)
- for (i = 0; i < NUM_G; i++, val++)
- *val = snd_emu10k1_ptr_read(emu, *reg, i);
- if (emu->audigy) {
- for (reg = saved_regs_audigy; *reg != 0xff; reg++)
- for (i = 0; i < NUM_G; i++, val++)
- *val = snd_emu10k1_ptr_read(emu, *reg, i);
- }
- if (emu->audigy)
- emu->saved_a_iocfg = inl(emu->port + A_IOCFG);
- emu->saved_hcfg = inl(emu->port + HCFG);
-}
-
-void snd_emu10k1_resume_init(struct snd_emu10k1 *emu)
-{
- if (emu->card_capabilities->ca_cardbus_chip)
- snd_emu10k1_cardbus_init(emu);
- if (emu->card_capabilities->ecard)
- snd_emu10k1_ecard_init(emu);
- else if (emu->card_capabilities->emu_model)
- snd_emu10k1_emu1010_init(emu);
- else
- snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
- snd_emu10k1_init(emu, emu->enable_ir, 1);
-}
-
-void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu)
-{
- int i;
- unsigned char *reg;
- unsigned int *val;
-
- snd_emu10k1_audio_enable(emu);
-
- /* resore for spdif */
- if (emu->audigy)
- outl(emu->saved_a_iocfg, emu->port + A_IOCFG);
- outl(emu->saved_hcfg, emu->port + HCFG);
-
- val = emu->saved_ptr;
- for (reg = saved_regs; *reg != 0xff; reg++)
- for (i = 0; i < NUM_G; i++, val++)
- snd_emu10k1_ptr_write(emu, *reg, i, *val);
- if (emu->audigy) {
- for (reg = saved_regs_audigy; *reg != 0xff; reg++)
- for (i = 0; i < NUM_G; i++, val++)
- snd_emu10k1_ptr_write(emu, *reg, i, *val);
- }
-}
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1_patch.c b/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1_patch.c
deleted file mode 100644
index e10f027b..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1_patch.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Patch transfer callback for Emu10k1
- *
- * Copyright (C) 2000 Takashi iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-/*
- * All the code for loading in a patch. There is very little that is
- * chip specific here. Just the actual writing to the board.
- */
-
-#include "emu10k1_synth_local.h"
-
-/*
- */
-#define BLANK_LOOP_START 4
-#define BLANK_LOOP_END 8
-#define BLANK_LOOP_SIZE 12
-#define BLANK_HEAD_SIZE 32
-
-/*
- * allocate a sample block and copy data from userspace
- */
-int
-snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
- struct snd_util_memhdr *hdr,
- const void __user *data, long count)
-{
- int offset;
- int truesize, size, loopsize, blocksize;
- int loopend, sampleend;
- unsigned int start_addr;
- struct snd_emu10k1 *emu;
-
- emu = rec->hw;
- if (snd_BUG_ON(!sp || !hdr))
- return -EINVAL;
-
- if (sp->v.size == 0) {
- snd_printd("emu: rom font for sample %d\n", sp->v.sample);
- return 0;
- }
-
- /* recalculate address offset */
- sp->v.end -= sp->v.start;
- sp->v.loopstart -= sp->v.start;
- sp->v.loopend -= sp->v.start;
- sp->v.start = 0;
-
- /* some samples have invalid data. the addresses are corrected in voice info */
- sampleend = sp->v.end;
- if (sampleend > sp->v.size)
- sampleend = sp->v.size;
- loopend = sp->v.loopend;
- if (loopend > sampleend)
- loopend = sampleend;
-
- /* be sure loop points start < end */
- if (sp->v.loopstart >= sp->v.loopend) {
- int tmp = sp->v.loopstart;
- sp->v.loopstart = sp->v.loopend;
- sp->v.loopend = tmp;
- }
-
- /* compute true data size to be loaded */
- truesize = sp->v.size + BLANK_HEAD_SIZE;
- loopsize = 0;
-#if 0 /* not supported */
- if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP|SNDRV_SFNT_SAMPLE_REVERSE_LOOP))
- loopsize = sp->v.loopend - sp->v.loopstart;
- truesize += loopsize;
-#endif
- if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK)
- truesize += BLANK_LOOP_SIZE;
-
- /* try to allocate a memory block */
- blocksize = truesize;
- if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
- blocksize *= 2;
- sp->block = snd_emu10k1_synth_alloc(emu, blocksize);
- if (sp->block == NULL) {
- snd_printd("emu10k1: synth malloc failed (size=%d)\n", blocksize);
- /* not ENOMEM (for compatibility with OSS) */
- return -ENOSPC;
- }
- /* set the total size */
- sp->v.truesize = blocksize;
-
- /* write blank samples at head */
- offset = 0;
- size = BLANK_HEAD_SIZE;
- if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
- size *= 2;
- if (offset + size > blocksize)
- return -EINVAL;
- snd_emu10k1_synth_bzero(emu, sp->block, offset, size);
- offset += size;
-
- /* copy start->loopend */
- size = loopend;
- if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
- size *= 2;
- if (offset + size > blocksize)
- return -EINVAL;
- if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) {
- snd_emu10k1_synth_free(emu, sp->block);
- sp->block = NULL;
- return -EFAULT;
- }
- offset += size;
- data += size;
-
-#if 0 /* not suppported yet */
- /* handle reverse (or bidirectional) loop */
- if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP|SNDRV_SFNT_SAMPLE_REVERSE_LOOP)) {
- /* copy loop in reverse */
- if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) {
- int woffset;
- unsigned short *wblock = (unsigned short*)block;
- woffset = offset / 2;
- if (offset + loopsize * 2 > blocksize)
- return -EINVAL;
- for (i = 0; i < loopsize; i++)
- wblock[woffset + i] = wblock[woffset - i -1];
- offset += loopsize * 2;
- } else {
- if (offset + loopsize > blocksize)
- return -EINVAL;
- for (i = 0; i < loopsize; i++)
- block[offset + i] = block[offset - i -1];
- offset += loopsize;
- }
-
- /* modify loop pointers */
- if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_BIDIR_LOOP) {
- sp->v.loopend += loopsize;
- } else {
- sp->v.loopstart += loopsize;
- sp->v.loopend += loopsize;
- }
- /* add sample pointer */
- sp->v.end += loopsize;
- }
-#endif
-
- /* loopend -> sample end */
- size = sp->v.size - loopend;
- if (size < 0)
- return -EINVAL;
- if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
- size *= 2;
- if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) {
- snd_emu10k1_synth_free(emu, sp->block);
- sp->block = NULL;
- return -EFAULT;
- }
- offset += size;
-
- /* clear rest of samples (if any) */
- if (offset < blocksize)
- snd_emu10k1_synth_bzero(emu, sp->block, offset, blocksize - offset);
-
- if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK) {
- /* if no blank loop is attached in the sample, add it */
- if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT) {
- sp->v.loopstart = sp->v.end + BLANK_LOOP_START;
- sp->v.loopend = sp->v.end + BLANK_LOOP_END;
- }
- }
-
-#if 0 /* not supported yet */
- if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_UNSIGNED) {
- /* unsigned -> signed */
- if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) {
- unsigned short *wblock = (unsigned short*)block;
- for (i = 0; i < truesize; i++)
- wblock[i] ^= 0x8000;
- } else {
- for (i = 0; i < truesize; i++)
- block[i] ^= 0x80;
- }
- }
-#endif
-
- /* recalculate offset */
- start_addr = BLANK_HEAD_SIZE * 2;
- if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
- start_addr >>= 1;
- sp->v.start += start_addr;
- sp->v.end += start_addr;
- sp->v.loopstart += start_addr;
- sp->v.loopend += start_addr;
-
- return 0;
-}
-
-/*
- * free a sample block
- */
-int
-snd_emu10k1_sample_free(struct snd_emux *rec, struct snd_sf_sample *sp,
- struct snd_util_memhdr *hdr)
-{
- struct snd_emu10k1 *emu;
-
- emu = rec->hw;
- if (snd_BUG_ON(!sp || !hdr))
- return -EINVAL;
-
- if (sp->block) {
- snd_emu10k1_synth_free(emu, sp->block);
- sp->block = NULL;
- }
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1_synth.c b/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1_synth.c
deleted file mode 100644
index 4c41c903..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1_synth.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
- *
- * Routines for control of EMU10K1 WaveTable synth
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "emu10k1_synth_local.h"
-#include <linux/init.h>
-#include <linux/module.h>
-
-MODULE_AUTHOR("Takashi Iwai");
-MODULE_DESCRIPTION("Routines for control of EMU10K1 WaveTable synth");
-MODULE_LICENSE("GPL");
-
-/*
- * create a new hardware dependent device for Emu10k1
- */
-static int snd_emu10k1_synth_new_device(struct snd_seq_device *dev)
-{
- struct snd_emux *emux;
- struct snd_emu10k1 *hw;
- struct snd_emu10k1_synth_arg *arg;
- unsigned long flags;
-
- arg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
- if (arg == NULL)
- return -EINVAL;
-
- if (arg->seq_ports <= 0)
- return 0; /* nothing */
- if (arg->max_voices < 1)
- arg->max_voices = 1;
- else if (arg->max_voices > 64)
- arg->max_voices = 64;
-
- if (snd_emux_new(&emux) < 0)
- return -ENOMEM;
-
- snd_emu10k1_ops_setup(emux);
- hw = arg->hwptr;
- emux->hw = hw;
- emux->max_voices = arg->max_voices;
- emux->num_ports = arg->seq_ports;
- emux->pitch_shift = -501;
- emux->memhdr = hw->memhdr;
- /* maximum two ports */
- emux->midi_ports = arg->seq_ports < 2 ? arg->seq_ports : 2;
- /* audigy has two external midis */
- emux->midi_devidx = hw->audigy ? 2 : 1;
- emux->linear_panning = 0;
- emux->hwdep_idx = 2; /* FIXED */
-
- if (snd_emux_register(emux, dev->card, arg->index, "Emu10k1") < 0) {
- snd_emux_free(emux);
- return -ENOMEM;
- }
-
- spin_lock_irqsave(&hw->voice_lock, flags);
- hw->synth = emux;
- hw->get_synth_voice = snd_emu10k1_synth_get_voice;
- spin_unlock_irqrestore(&hw->voice_lock, flags);
-
- dev->driver_data = emux;
-
- return 0;
-}
-
-static int snd_emu10k1_synth_delete_device(struct snd_seq_device *dev)
-{
- struct snd_emux *emux;
- struct snd_emu10k1 *hw;
- unsigned long flags;
-
- if (dev->driver_data == NULL)
- return 0; /* not registered actually */
-
- emux = dev->driver_data;
-
- hw = emux->hw;
- spin_lock_irqsave(&hw->voice_lock, flags);
- hw->synth = NULL;
- hw->get_synth_voice = NULL;
- spin_unlock_irqrestore(&hw->voice_lock, flags);
-
- snd_emux_free(emux);
- return 0;
-}
-
-/*
- * INIT part
- */
-
-static int __init alsa_emu10k1_synth_init(void)
-{
-
- static struct snd_seq_dev_ops ops = {
- snd_emu10k1_synth_new_device,
- snd_emu10k1_synth_delete_device,
- };
- return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH, &ops,
- sizeof(struct snd_emu10k1_synth_arg));
-}
-
-static void __exit alsa_emu10k1_synth_exit(void)
-{
- snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH);
-}
-
-module_init(alsa_emu10k1_synth_init)
-module_exit(alsa_emu10k1_synth_exit)
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1_synth_local.h b/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1_synth_local.h
deleted file mode 100644
index 25f328ff..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1_synth_local.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef __EMU10K1_SYNTH_LOCAL_H
-#define __EMU10K1_SYNTH_LOCAL_H
-/*
- * Local defininitons for Emu10k1 wavetable
- *
- * Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/emu10k1_synth.h>
-
-/* emu10k1_patch.c */
-int snd_emu10k1_sample_new(struct snd_emux *private_data,
- struct snd_sf_sample *sp,
- struct snd_util_memhdr *hdr,
- const void __user *_data, long count);
-int snd_emu10k1_sample_free(struct snd_emux *private_data,
- struct snd_sf_sample *sp,
- struct snd_util_memhdr *hdr);
-int snd_emu10k1_memhdr_init(struct snd_emux *emu);
-
-/* emu10k1_callback.c */
-void snd_emu10k1_ops_setup(struct snd_emux *emu);
-int snd_emu10k1_synth_get_voice(struct snd_emu10k1 *hw);
-
-
-#endif /* __EMU10K1_SYNTH_LOCAL_H */
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1x.c b/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1x.c
deleted file mode 100644
index 47a651cb..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/emu10k1x.c
+++ /dev/null
@@ -1,1635 +0,0 @@
-/*
- * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
- * Driver EMU10K1X chips
- *
- * Parts of this code were adapted from audigyls.c driver which is
- * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
- *
- * BUGS:
- * --
- *
- * TODO:
- *
- * Chips (SB0200 model):
- * - EMU10K1X-DBQ
- * - STAC 9708T
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/info.h>
-#include <sound/rawmidi.h>
-
-MODULE_AUTHOR("Francisco Moraes <fmoraes@nc.rr.com>");
-MODULE_DESCRIPTION("EMU10K1X");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Dell Creative Labs,SB Live!}");
-
-// module parameters (see "Module Parameters")
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for the EMU10K1X soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for the EMU10K1X soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable the EMU10K1X soundcard.");
-
-
-// some definitions were borrowed from emu10k1 driver as they seem to be the same
-/************************************************************************************************/
-/* PCI function 0 registers, address = <val> + PCIBASE0 */
-/************************************************************************************************/
-
-#define PTR 0x00 /* Indexed register set pointer register */
- /* NOTE: The CHANNELNUM and ADDRESS words can */
- /* be modified independently of each other. */
-
-#define DATA 0x04 /* Indexed register set data register */
-
-#define IPR 0x08 /* Global interrupt pending register */
- /* Clear pending interrupts by writing a 1 to */
- /* the relevant bits and zero to the other bits */
-#define IPR_MIDITRANSBUFEMPTY 0x00000001 /* MIDI UART transmit buffer empty */
-#define IPR_MIDIRECVBUFEMPTY 0x00000002 /* MIDI UART receive buffer empty */
-#define IPR_CH_0_LOOP 0x00000800 /* Channel 0 loop */
-#define IPR_CH_0_HALF_LOOP 0x00000100 /* Channel 0 half loop */
-#define IPR_CAP_0_LOOP 0x00080000 /* Channel capture loop */
-#define IPR_CAP_0_HALF_LOOP 0x00010000 /* Channel capture half loop */
-
-#define INTE 0x0c /* Interrupt enable register */
-#define INTE_MIDITXENABLE 0x00000001 /* Enable MIDI transmit-buffer-empty interrupts */
-#define INTE_MIDIRXENABLE 0x00000002 /* Enable MIDI receive-buffer-empty interrupts */
-#define INTE_CH_0_LOOP 0x00000800 /* Channel 0 loop */
-#define INTE_CH_0_HALF_LOOP 0x00000100 /* Channel 0 half loop */
-#define INTE_CAP_0_LOOP 0x00080000 /* Channel capture loop */
-#define INTE_CAP_0_HALF_LOOP 0x00010000 /* Channel capture half loop */
-
-#define HCFG 0x14 /* Hardware config register */
-
-#define HCFG_LOCKSOUNDCACHE 0x00000008 /* 1 = Cancel bustmaster accesses to soundcache */
- /* NOTE: This should generally never be used. */
-#define HCFG_AUDIOENABLE 0x00000001 /* 0 = CODECs transmit zero-valued samples */
- /* Should be set to 1 when the EMU10K1 is */
- /* completely initialized. */
-#define GPIO 0x18 /* Defaults: 00001080-Analog, 00001000-SPDIF. */
-
-
-#define AC97DATA 0x1c /* AC97 register set data register (16 bit) */
-
-#define AC97ADDRESS 0x1e /* AC97 register set address register (8 bit) */
-
-/********************************************************************************************************/
-/* Emu10k1x pointer-offset register set, accessed through the PTR and DATA registers */
-/********************************************************************************************************/
-#define PLAYBACK_LIST_ADDR 0x00 /* Base DMA address of a list of pointers to each period/size */
- /* One list entry: 4 bytes for DMA address,
- * 4 bytes for period_size << 16.
- * One list entry is 8 bytes long.
- * One list entry for each period in the buffer.
- */
-#define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */
-#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */
-#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA address */
-#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size */
-#define PLAYBACK_POINTER 0x06 /* Playback period pointer. Sample currently in DAC */
-#define PLAYBACK_UNKNOWN1 0x07
-#define PLAYBACK_UNKNOWN2 0x08
-
-/* Only one capture channel supported */
-#define CAPTURE_DMA_ADDR 0x10 /* Capture DMA address */
-#define CAPTURE_BUFFER_SIZE 0x11 /* Capture buffer size */
-#define CAPTURE_POINTER 0x12 /* Capture buffer pointer. Sample currently in ADC */
-#define CAPTURE_UNKNOWN 0x13
-
-/* From 0x20 - 0x3f, last samples played on each channel */
-
-#define TRIGGER_CHANNEL 0x40 /* Trigger channel playback */
-#define TRIGGER_CHANNEL_0 0x00000001 /* Trigger channel 0 */
-#define TRIGGER_CHANNEL_1 0x00000002 /* Trigger channel 1 */
-#define TRIGGER_CHANNEL_2 0x00000004 /* Trigger channel 2 */
-#define TRIGGER_CAPTURE 0x00000100 /* Trigger capture channel */
-
-#define ROUTING 0x41 /* Setup sound routing ? */
-#define ROUTING_FRONT_LEFT 0x00000001
-#define ROUTING_FRONT_RIGHT 0x00000002
-#define ROUTING_REAR_LEFT 0x00000004
-#define ROUTING_REAR_RIGHT 0x00000008
-#define ROUTING_CENTER_LFE 0x00010000
-
-#define SPCS0 0x42 /* SPDIF output Channel Status 0 register */
-
-#define SPCS1 0x43 /* SPDIF output Channel Status 1 register */
-
-#define SPCS2 0x44 /* SPDIF output Channel Status 2 register */
-
-#define SPCS_CLKACCYMASK 0x30000000 /* Clock accuracy */
-#define SPCS_CLKACCY_1000PPM 0x00000000 /* 1000 parts per million */
-#define SPCS_CLKACCY_50PPM 0x10000000 /* 50 parts per million */
-#define SPCS_CLKACCY_VARIABLE 0x20000000 /* Variable accuracy */
-#define SPCS_SAMPLERATEMASK 0x0f000000 /* Sample rate */
-#define SPCS_SAMPLERATE_44 0x00000000 /* 44.1kHz sample rate */
-#define SPCS_SAMPLERATE_48 0x02000000 /* 48kHz sample rate */
-#define SPCS_SAMPLERATE_32 0x03000000 /* 32kHz sample rate */
-#define SPCS_CHANNELNUMMASK 0x00f00000 /* Channel number */
-#define SPCS_CHANNELNUM_UNSPEC 0x00000000 /* Unspecified channel number */
-#define SPCS_CHANNELNUM_LEFT 0x00100000 /* Left channel */
-#define SPCS_CHANNELNUM_RIGHT 0x00200000 /* Right channel */
-#define SPCS_SOURCENUMMASK 0x000f0000 /* Source number */
-#define SPCS_SOURCENUM_UNSPEC 0x00000000 /* Unspecified source number */
-#define SPCS_GENERATIONSTATUS 0x00008000 /* Originality flag (see IEC-958 spec) */
-#define SPCS_CATEGORYCODEMASK 0x00007f00 /* Category code (see IEC-958 spec) */
-#define SPCS_MODEMASK 0x000000c0 /* Mode (see IEC-958 spec) */
-#define SPCS_EMPHASISMASK 0x00000038 /* Emphasis */
-#define SPCS_EMPHASIS_NONE 0x00000000 /* No emphasis */
-#define SPCS_EMPHASIS_50_15 0x00000008 /* 50/15 usec 2 channel */
-#define SPCS_COPYRIGHT 0x00000004 /* Copyright asserted flag -- do not modify */
-#define SPCS_NOTAUDIODATA 0x00000002 /* 0 = Digital audio, 1 = not audio */
-#define SPCS_PROFESSIONAL 0x00000001 /* 0 = Consumer (IEC-958), 1 = pro (AES3-1992) */
-
-#define SPDIF_SELECT 0x45 /* Enables SPDIF or Analogue outputs 0-Analogue, 0x700-SPDIF */
-
-/* This is the MPU port on the card */
-#define MUDATA 0x47
-#define MUCMD 0x48
-#define MUSTAT MUCMD
-
-/* From 0x50 - 0x5f, last samples captured */
-
-/**
- * The hardware has 3 channels for playback and 1 for capture.
- * - channel 0 is the front channel
- * - channel 1 is the rear channel
- * - channel 2 is the center/lfe channel
- * Volume is controlled by the AC97 for the front and rear channels by
- * the PCM Playback Volume, Sigmatel Surround Playback Volume and
- * Surround Playback Volume. The Sigmatel 4-Speaker Stereo switch affects
- * the front/rear channel mixing in the REAR OUT jack. When using the
- * 4-Speaker Stereo, both front and rear channels will be mixed in the
- * REAR OUT.
- * The center/lfe channel has no volume control and cannot be muted during
- * playback.
- */
-
-struct emu10k1x_voice {
- struct emu10k1x *emu;
- int number;
- int use;
-
- struct emu10k1x_pcm *epcm;
-};
-
-struct emu10k1x_pcm {
- struct emu10k1x *emu;
- struct snd_pcm_substream *substream;
- struct emu10k1x_voice *voice;
- unsigned short running;
-};
-
-struct emu10k1x_midi {
- struct emu10k1x *emu;
- struct snd_rawmidi *rmidi;
- struct snd_rawmidi_substream *substream_input;
- struct snd_rawmidi_substream *substream_output;
- unsigned int midi_mode;
- spinlock_t input_lock;
- spinlock_t output_lock;
- spinlock_t open_lock;
- int tx_enable, rx_enable;
- int port;
- int ipr_tx, ipr_rx;
- void (*interrupt)(struct emu10k1x *emu, unsigned int status);
-};
-
-// definition of the chip-specific record
-struct emu10k1x {
- struct snd_card *card;
- struct pci_dev *pci;
-
- unsigned long port;
- struct resource *res_port;
- int irq;
-
- unsigned char revision; /* chip revision */
- unsigned int serial; /* serial number */
- unsigned short model; /* subsystem id */
-
- spinlock_t emu_lock;
- spinlock_t voice_lock;
-
- struct snd_ac97 *ac97;
- struct snd_pcm *pcm;
-
- struct emu10k1x_voice voices[3];
- struct emu10k1x_voice capture_voice;
- u32 spdif_bits[3]; // SPDIF out setup
-
- struct snd_dma_buffer dma_buffer;
-
- struct emu10k1x_midi midi;
-};
-
-/* hardware definition */
-static struct snd_pcm_hardware snd_emu10k1x_playback_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (32*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (16*1024),
- .periods_min = 2,
- .periods_max = 8,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_emu10k1x_capture_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (32*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (16*1024),
- .periods_min = 2,
- .periods_max = 2,
- .fifo_size = 0,
-};
-
-static unsigned int snd_emu10k1x_ptr_read(struct emu10k1x * emu,
- unsigned int reg,
- unsigned int chn)
-{
- unsigned long flags;
- unsigned int regptr, val;
-
- regptr = (reg << 16) | chn;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(regptr, emu->port + PTR);
- val = inl(emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- return val;
-}
-
-static void snd_emu10k1x_ptr_write(struct emu10k1x *emu,
- unsigned int reg,
- unsigned int chn,
- unsigned int data)
-{
- unsigned int regptr;
- unsigned long flags;
-
- regptr = (reg << 16) | chn;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(regptr, emu->port + PTR);
- outl(data, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-static void snd_emu10k1x_intr_enable(struct emu10k1x *emu, unsigned int intrenb)
-{
- unsigned long flags;
- unsigned int intr_enable;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- intr_enable = inl(emu->port + INTE) | intrenb;
- outl(intr_enable, emu->port + INTE);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-static void snd_emu10k1x_intr_disable(struct emu10k1x *emu, unsigned int intrenb)
-{
- unsigned long flags;
- unsigned int intr_enable;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- intr_enable = inl(emu->port + INTE) & ~intrenb;
- outl(intr_enable, emu->port + INTE);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-static void snd_emu10k1x_gpio_write(struct emu10k1x *emu, unsigned int value)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(value, emu->port + GPIO);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-static void snd_emu10k1x_pcm_free_substream(struct snd_pcm_runtime *runtime)
-{
- kfree(runtime->private_data);
-}
-
-static void snd_emu10k1x_pcm_interrupt(struct emu10k1x *emu, struct emu10k1x_voice *voice)
-{
- struct emu10k1x_pcm *epcm;
-
- if ((epcm = voice->epcm) == NULL)
- return;
- if (epcm->substream == NULL)
- return;
-#if 0
- snd_printk(KERN_INFO "IRQ: position = 0x%x, period = 0x%x, size = 0x%x\n",
- epcm->substream->ops->pointer(epcm->substream),
- snd_pcm_lib_period_bytes(epcm->substream),
- snd_pcm_lib_buffer_bytes(epcm->substream));
-#endif
- snd_pcm_period_elapsed(epcm->substream);
-}
-
-/* open callback */
-static int snd_emu10k1x_playback_open(struct snd_pcm_substream *substream)
-{
- struct emu10k1x *chip = snd_pcm_substream_chip(substream);
- struct emu10k1x_pcm *epcm;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) {
- return err;
- }
- if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
- return err;
-
- epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
- if (epcm == NULL)
- return -ENOMEM;
- epcm->emu = chip;
- epcm->substream = substream;
-
- runtime->private_data = epcm;
- runtime->private_free = snd_emu10k1x_pcm_free_substream;
-
- runtime->hw = snd_emu10k1x_playback_hw;
-
- return 0;
-}
-
-/* close callback */
-static int snd_emu10k1x_playback_close(struct snd_pcm_substream *substream)
-{
- return 0;
-}
-
-/* hw_params callback */
-static int snd_emu10k1x_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct emu10k1x_pcm *epcm = runtime->private_data;
-
- if (! epcm->voice) {
- epcm->voice = &epcm->emu->voices[substream->pcm->device];
- epcm->voice->use = 1;
- epcm->voice->epcm = epcm;
- }
-
- return snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-}
-
-/* hw_free callback */
-static int snd_emu10k1x_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct emu10k1x_pcm *epcm;
-
- if (runtime->private_data == NULL)
- return 0;
-
- epcm = runtime->private_data;
-
- if (epcm->voice) {
- epcm->voice->use = 0;
- epcm->voice->epcm = NULL;
- epcm->voice = NULL;
- }
-
- return snd_pcm_lib_free_pages(substream);
-}
-
-/* prepare callback */
-static int snd_emu10k1x_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct emu10k1x *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct emu10k1x_pcm *epcm = runtime->private_data;
- int voice = epcm->voice->number;
- u32 *table_base = (u32 *)(emu->dma_buffer.area+1024*voice);
- u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
- int i;
-
- for(i = 0; i < runtime->periods; i++) {
- *table_base++=runtime->dma_addr+(i*period_size_bytes);
- *table_base++=period_size_bytes<<16;
- }
-
- snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_ADDR, voice, emu->dma_buffer.addr+1024*voice);
- snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_SIZE, voice, (runtime->periods - 1) << 19);
- snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_PTR, voice, 0);
- snd_emu10k1x_ptr_write(emu, PLAYBACK_POINTER, voice, 0);
- snd_emu10k1x_ptr_write(emu, PLAYBACK_UNKNOWN1, voice, 0);
- snd_emu10k1x_ptr_write(emu, PLAYBACK_UNKNOWN2, voice, 0);
- snd_emu10k1x_ptr_write(emu, PLAYBACK_DMA_ADDR, voice, runtime->dma_addr);
-
- snd_emu10k1x_ptr_write(emu, PLAYBACK_PERIOD_SIZE, voice, frames_to_bytes(runtime, runtime->period_size)<<16);
-
- return 0;
-}
-
-/* trigger callback */
-static int snd_emu10k1x_pcm_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct emu10k1x *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct emu10k1x_pcm *epcm = runtime->private_data;
- int channel = epcm->voice->number;
- int result = 0;
-
-// snd_printk(KERN_INFO "trigger - emu10k1x = 0x%x, cmd = %i, pointer = %d\n", (int)emu, cmd, (int)substream->ops->pointer(substream));
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- if(runtime->periods == 2)
- snd_emu10k1x_intr_enable(emu, (INTE_CH_0_LOOP | INTE_CH_0_HALF_LOOP) << channel);
- else
- snd_emu10k1x_intr_enable(emu, INTE_CH_0_LOOP << channel);
- epcm->running = 1;
- snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0)|(TRIGGER_CHANNEL_0<<channel));
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- epcm->running = 0;
- snd_emu10k1x_intr_disable(emu, (INTE_CH_0_LOOP | INTE_CH_0_HALF_LOOP) << channel);
- snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0) & ~(TRIGGER_CHANNEL_0<<channel));
- break;
- default:
- result = -EINVAL;
- break;
- }
- return result;
-}
-
-/* pointer callback */
-static snd_pcm_uframes_t
-snd_emu10k1x_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct emu10k1x *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct emu10k1x_pcm *epcm = runtime->private_data;
- int channel = epcm->voice->number;
- snd_pcm_uframes_t ptr = 0, ptr1 = 0, ptr2= 0,ptr3 = 0,ptr4 = 0;
-
- if (!epcm->running)
- return 0;
-
- ptr3 = snd_emu10k1x_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
- ptr1 = snd_emu10k1x_ptr_read(emu, PLAYBACK_POINTER, channel);
- ptr4 = snd_emu10k1x_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
-
- if(ptr4 == 0 && ptr1 == frames_to_bytes(runtime, runtime->buffer_size))
- return 0;
-
- if (ptr3 != ptr4)
- ptr1 = snd_emu10k1x_ptr_read(emu, PLAYBACK_POINTER, channel);
- ptr2 = bytes_to_frames(runtime, ptr1);
- ptr2 += (ptr4 >> 3) * runtime->period_size;
- ptr = ptr2;
-
- if (ptr >= runtime->buffer_size)
- ptr -= runtime->buffer_size;
-
- return ptr;
-}
-
-/* operators */
-static struct snd_pcm_ops snd_emu10k1x_playback_ops = {
- .open = snd_emu10k1x_playback_open,
- .close = snd_emu10k1x_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_emu10k1x_pcm_hw_params,
- .hw_free = snd_emu10k1x_pcm_hw_free,
- .prepare = snd_emu10k1x_pcm_prepare,
- .trigger = snd_emu10k1x_pcm_trigger,
- .pointer = snd_emu10k1x_pcm_pointer,
-};
-
-/* open_capture callback */
-static int snd_emu10k1x_pcm_open_capture(struct snd_pcm_substream *substream)
-{
- struct emu10k1x *chip = snd_pcm_substream_chip(substream);
- struct emu10k1x_pcm *epcm;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
- return err;
- if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
- return err;
-
- epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
- if (epcm == NULL)
- return -ENOMEM;
-
- epcm->emu = chip;
- epcm->substream = substream;
-
- runtime->private_data = epcm;
- runtime->private_free = snd_emu10k1x_pcm_free_substream;
-
- runtime->hw = snd_emu10k1x_capture_hw;
-
- return 0;
-}
-
-/* close callback */
-static int snd_emu10k1x_pcm_close_capture(struct snd_pcm_substream *substream)
-{
- return 0;
-}
-
-/* hw_params callback */
-static int snd_emu10k1x_pcm_hw_params_capture(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct emu10k1x_pcm *epcm = runtime->private_data;
-
- if (! epcm->voice) {
- if (epcm->emu->capture_voice.use)
- return -EBUSY;
- epcm->voice = &epcm->emu->capture_voice;
- epcm->voice->epcm = epcm;
- epcm->voice->use = 1;
- }
-
- return snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-}
-
-/* hw_free callback */
-static int snd_emu10k1x_pcm_hw_free_capture(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- struct emu10k1x_pcm *epcm;
-
- if (runtime->private_data == NULL)
- return 0;
- epcm = runtime->private_data;
-
- if (epcm->voice) {
- epcm->voice->use = 0;
- epcm->voice->epcm = NULL;
- epcm->voice = NULL;
- }
-
- return snd_pcm_lib_free_pages(substream);
-}
-
-/* prepare capture callback */
-static int snd_emu10k1x_pcm_prepare_capture(struct snd_pcm_substream *substream)
-{
- struct emu10k1x *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- snd_emu10k1x_ptr_write(emu, CAPTURE_DMA_ADDR, 0, runtime->dma_addr);
- snd_emu10k1x_ptr_write(emu, CAPTURE_BUFFER_SIZE, 0, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes
- snd_emu10k1x_ptr_write(emu, CAPTURE_POINTER, 0, 0);
- snd_emu10k1x_ptr_write(emu, CAPTURE_UNKNOWN, 0, 0);
-
- return 0;
-}
-
-/* trigger_capture callback */
-static int snd_emu10k1x_pcm_trigger_capture(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct emu10k1x *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct emu10k1x_pcm *epcm = runtime->private_data;
- int result = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- snd_emu10k1x_intr_enable(emu, INTE_CAP_0_LOOP |
- INTE_CAP_0_HALF_LOOP);
- snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0)|TRIGGER_CAPTURE);
- epcm->running = 1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- epcm->running = 0;
- snd_emu10k1x_intr_disable(emu, INTE_CAP_0_LOOP |
- INTE_CAP_0_HALF_LOOP);
- snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0) & ~(TRIGGER_CAPTURE));
- break;
- default:
- result = -EINVAL;
- break;
- }
- return result;
-}
-
-/* pointer_capture callback */
-static snd_pcm_uframes_t
-snd_emu10k1x_pcm_pointer_capture(struct snd_pcm_substream *substream)
-{
- struct emu10k1x *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct emu10k1x_pcm *epcm = runtime->private_data;
- snd_pcm_uframes_t ptr;
-
- if (!epcm->running)
- return 0;
-
- ptr = bytes_to_frames(runtime, snd_emu10k1x_ptr_read(emu, CAPTURE_POINTER, 0));
- if (ptr >= runtime->buffer_size)
- ptr -= runtime->buffer_size;
-
- return ptr;
-}
-
-static struct snd_pcm_ops snd_emu10k1x_capture_ops = {
- .open = snd_emu10k1x_pcm_open_capture,
- .close = snd_emu10k1x_pcm_close_capture,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_emu10k1x_pcm_hw_params_capture,
- .hw_free = snd_emu10k1x_pcm_hw_free_capture,
- .prepare = snd_emu10k1x_pcm_prepare_capture,
- .trigger = snd_emu10k1x_pcm_trigger_capture,
- .pointer = snd_emu10k1x_pcm_pointer_capture,
-};
-
-static unsigned short snd_emu10k1x_ac97_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- struct emu10k1x *emu = ac97->private_data;
- unsigned long flags;
- unsigned short val;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- outb(reg, emu->port + AC97ADDRESS);
- val = inw(emu->port + AC97DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- return val;
-}
-
-static void snd_emu10k1x_ac97_write(struct snd_ac97 *ac97,
- unsigned short reg, unsigned short val)
-{
- struct emu10k1x *emu = ac97->private_data;
- unsigned long flags;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- outb(reg, emu->port + AC97ADDRESS);
- outw(val, emu->port + AC97DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-static int snd_emu10k1x_ac97(struct emu10k1x *chip)
-{
- struct snd_ac97_bus *pbus;
- struct snd_ac97_template ac97;
- int err;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_emu10k1x_ac97_write,
- .read = snd_emu10k1x_ac97_read,
- };
-
- if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
- return err;
- pbus->no_vra = 1; /* we don't need VRA */
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = chip;
- ac97.scaps = AC97_SCAP_NO_SPDIF;
- return snd_ac97_mixer(pbus, &ac97, &chip->ac97);
-}
-
-static int snd_emu10k1x_free(struct emu10k1x *chip)
-{
- snd_emu10k1x_ptr_write(chip, TRIGGER_CHANNEL, 0, 0);
- // disable interrupts
- outl(0, chip->port + INTE);
- // disable audio
- outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG);
-
- /* release the irq */
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
-
- // release the i/o port
- release_and_free_resource(chip->res_port);
-
- // release the DMA
- if (chip->dma_buffer.area) {
- snd_dma_free_pages(&chip->dma_buffer);
- }
-
- pci_disable_device(chip->pci);
-
- // release the data
- kfree(chip);
- return 0;
-}
-
-static int snd_emu10k1x_dev_free(struct snd_device *device)
-{
- struct emu10k1x *chip = device->device_data;
- return snd_emu10k1x_free(chip);
-}
-
-static irqreturn_t snd_emu10k1x_interrupt(int irq, void *dev_id)
-{
- unsigned int status;
-
- struct emu10k1x *chip = dev_id;
- struct emu10k1x_voice *pvoice = chip->voices;
- int i;
- int mask;
-
- status = inl(chip->port + IPR);
-
- if (! status)
- return IRQ_NONE;
-
- // capture interrupt
- if (status & (IPR_CAP_0_LOOP | IPR_CAP_0_HALF_LOOP)) {
- struct emu10k1x_voice *cap_voice = &chip->capture_voice;
- if (cap_voice->use)
- snd_emu10k1x_pcm_interrupt(chip, cap_voice);
- else
- snd_emu10k1x_intr_disable(chip,
- INTE_CAP_0_LOOP |
- INTE_CAP_0_HALF_LOOP);
- }
-
- mask = IPR_CH_0_LOOP|IPR_CH_0_HALF_LOOP;
- for (i = 0; i < 3; i++) {
- if (status & mask) {
- if (pvoice->use)
- snd_emu10k1x_pcm_interrupt(chip, pvoice);
- else
- snd_emu10k1x_intr_disable(chip, mask);
- }
- pvoice++;
- mask <<= 1;
- }
-
- if (status & (IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY)) {
- if (chip->midi.interrupt)
- chip->midi.interrupt(chip, status);
- else
- snd_emu10k1x_intr_disable(chip, INTE_MIDITXENABLE|INTE_MIDIRXENABLE);
- }
-
- // acknowledge the interrupt if necessary
- outl(status, chip->port + IPR);
-
- // snd_printk(KERN_INFO "interrupt %08x\n", status);
- return IRQ_HANDLED;
-}
-
-static int __devinit snd_emu10k1x_pcm(struct emu10k1x *emu, int device, struct snd_pcm **rpcm)
-{
- struct snd_pcm *pcm;
- int err;
- int capture = 0;
-
- if (rpcm)
- *rpcm = NULL;
- if (device == 0)
- capture = 1;
-
- if ((err = snd_pcm_new(emu->card, "emu10k1x", device, 1, capture, &pcm)) < 0)
- return err;
-
- pcm->private_data = emu;
-
- switch(device) {
- case 0:
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1x_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1x_capture_ops);
- break;
- case 1:
- case 2:
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1x_playback_ops);
- break;
- }
-
- pcm->info_flags = 0;
- switch(device) {
- case 0:
- strcpy(pcm->name, "EMU10K1X Front");
- break;
- case 1:
- strcpy(pcm->name, "EMU10K1X Rear");
- break;
- case 2:
- strcpy(pcm->name, "EMU10K1X Center/LFE");
- break;
- }
- emu->pcm = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(emu->pci),
- 32*1024, 32*1024);
-
- if (rpcm)
- *rpcm = pcm;
-
- return 0;
-}
-
-static int __devinit snd_emu10k1x_create(struct snd_card *card,
- struct pci_dev *pci,
- struct emu10k1x **rchip)
-{
- struct emu10k1x *chip;
- int err;
- int ch;
- static struct snd_device_ops ops = {
- .dev_free = snd_emu10k1x_dev_free,
- };
-
- *rchip = NULL;
-
- if ((err = pci_enable_device(pci)) < 0)
- return err;
- if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) {
- snd_printk(KERN_ERR "error to set 28bit mask DMA\n");
- pci_disable_device(pci);
- return -ENXIO;
- }
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
-
- spin_lock_init(&chip->emu_lock);
- spin_lock_init(&chip->voice_lock);
-
- chip->port = pci_resource_start(pci, 0);
- if ((chip->res_port = request_region(chip->port, 8,
- "EMU10K1X")) == NULL) {
- snd_printk(KERN_ERR "emu10k1x: cannot allocate the port 0x%lx\n", chip->port);
- snd_emu10k1x_free(chip);
- return -EBUSY;
- }
-
- if (request_irq(pci->irq, snd_emu10k1x_interrupt,
- IRQF_SHARED, KBUILD_MODNAME, chip)) {
- snd_printk(KERN_ERR "emu10k1x: cannot grab irq %d\n", pci->irq);
- snd_emu10k1x_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
-
- if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
- 4 * 1024, &chip->dma_buffer) < 0) {
- snd_emu10k1x_free(chip);
- return -ENOMEM;
- }
-
- pci_set_master(pci);
- /* read revision & serial */
- chip->revision = pci->revision;
- pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
- pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
- snd_printk(KERN_INFO "Model %04x Rev %08x Serial %08x\n", chip->model,
- chip->revision, chip->serial);
-
- outl(0, chip->port + INTE);
-
- for(ch = 0; ch < 3; ch++) {
- chip->voices[ch].emu = chip;
- chip->voices[ch].number = ch;
- }
-
- /*
- * Init to 0x02109204 :
- * Clock accuracy = 0 (1000ppm)
- * Sample Rate = 2 (48kHz)
- * Audio Channel = 1 (Left of 2)
- * Source Number = 0 (Unspecified)
- * Generation Status = 1 (Original for Cat Code 12)
- * Cat Code = 12 (Digital Signal Mixer)
- * Mode = 0 (Mode 0)
- * Emphasis = 0 (None)
- * CP = 1 (Copyright unasserted)
- * AN = 0 (Audio data)
- * P = 0 (Consumer)
- */
- snd_emu10k1x_ptr_write(chip, SPCS0, 0,
- chip->spdif_bits[0] =
- SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
- SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
- SPCS_GENERATIONSTATUS | 0x00001200 |
- 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
- snd_emu10k1x_ptr_write(chip, SPCS1, 0,
- chip->spdif_bits[1] =
- SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
- SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
- SPCS_GENERATIONSTATUS | 0x00001200 |
- 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
- snd_emu10k1x_ptr_write(chip, SPCS2, 0,
- chip->spdif_bits[2] =
- SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
- SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
- SPCS_GENERATIONSTATUS | 0x00001200 |
- 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
-
- snd_emu10k1x_ptr_write(chip, SPDIF_SELECT, 0, 0x700); // disable SPDIF
- snd_emu10k1x_ptr_write(chip, ROUTING, 0, 0x1003F); // routing
- snd_emu10k1x_gpio_write(chip, 0x1080); // analog mode
-
- outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG);
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
- chip, &ops)) < 0) {
- snd_emu10k1x_free(chip);
- return err;
- }
- *rchip = chip;
- return 0;
-}
-
-static void snd_emu10k1x_proc_reg_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct emu10k1x *emu = entry->private_data;
- unsigned long value,value1,value2;
- unsigned long flags;
- int i;
-
- snd_iprintf(buffer, "Registers:\n\n");
- for(i = 0; i < 0x20; i+=4) {
- spin_lock_irqsave(&emu->emu_lock, flags);
- value = inl(emu->port + i);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- snd_iprintf(buffer, "Register %02X: %08lX\n", i, value);
- }
- snd_iprintf(buffer, "\nRegisters\n\n");
- for(i = 0; i <= 0x48; i++) {
- value = snd_emu10k1x_ptr_read(emu, i, 0);
- if(i < 0x10 || (i >= 0x20 && i < 0x40)) {
- value1 = snd_emu10k1x_ptr_read(emu, i, 1);
- value2 = snd_emu10k1x_ptr_read(emu, i, 2);
- snd_iprintf(buffer, "%02X: %08lX %08lX %08lX\n", i, value, value1, value2);
- } else {
- snd_iprintf(buffer, "%02X: %08lX\n", i, value);
- }
- }
-}
-
-static void snd_emu10k1x_proc_reg_write(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct emu10k1x *emu = entry->private_data;
- char line[64];
- unsigned int reg, channel_id , val;
-
- while (!snd_info_get_line(buffer, line, sizeof(line))) {
- if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
- continue;
-
- if (reg < 0x49 && val <= 0xffffffff && channel_id <= 2)
- snd_emu10k1x_ptr_write(emu, reg, channel_id, val);
- }
-}
-
-static int __devinit snd_emu10k1x_proc_init(struct emu10k1x * emu)
-{
- struct snd_info_entry *entry;
-
- if(! snd_card_proc_new(emu->card, "emu10k1x_regs", &entry)) {
- snd_info_set_text_ops(entry, emu, snd_emu10k1x_proc_reg_read);
- entry->c.text.write = snd_emu10k1x_proc_reg_write;
- entry->mode |= S_IWUSR;
- entry->private_data = emu;
- }
-
- return 0;
-}
-
-#define snd_emu10k1x_shared_spdif_info snd_ctl_boolean_mono_info
-
-static int snd_emu10k1x_shared_spdif_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct emu10k1x *emu = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = (snd_emu10k1x_ptr_read(emu, SPDIF_SELECT, 0) == 0x700) ? 0 : 1;
-
- return 0;
-}
-
-static int snd_emu10k1x_shared_spdif_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct emu10k1x *emu = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change = 0;
-
- val = ucontrol->value.integer.value[0] ;
-
- if (val) {
- // enable spdif output
- snd_emu10k1x_ptr_write(emu, SPDIF_SELECT, 0, 0x000);
- snd_emu10k1x_ptr_write(emu, ROUTING, 0, 0x700);
- snd_emu10k1x_gpio_write(emu, 0x1000);
- } else {
- // disable spdif output
- snd_emu10k1x_ptr_write(emu, SPDIF_SELECT, 0, 0x700);
- snd_emu10k1x_ptr_write(emu, ROUTING, 0, 0x1003F);
- snd_emu10k1x_gpio_write(emu, 0x1080);
- }
- return change;
-}
-
-static struct snd_kcontrol_new snd_emu10k1x_shared_spdif __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog/Digital Output Jack",
- .info = snd_emu10k1x_shared_spdif_info,
- .get = snd_emu10k1x_shared_spdif_get,
- .put = snd_emu10k1x_shared_spdif_put
-};
-
-static int snd_emu10k1x_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_emu10k1x_spdif_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct emu10k1x *emu = snd_kcontrol_chip(kcontrol);
- unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-
- ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff;
- ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff;
- ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff;
- ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff;
- return 0;
-}
-
-static int snd_emu10k1x_spdif_get_mask(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.iec958.status[0] = 0xff;
- ucontrol->value.iec958.status[1] = 0xff;
- ucontrol->value.iec958.status[2] = 0xff;
- ucontrol->value.iec958.status[3] = 0xff;
- return 0;
-}
-
-static int snd_emu10k1x_spdif_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct emu10k1x *emu = snd_kcontrol_chip(kcontrol);
- unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- int change;
- unsigned int val;
-
- val = (ucontrol->value.iec958.status[0] << 0) |
- (ucontrol->value.iec958.status[1] << 8) |
- (ucontrol->value.iec958.status[2] << 16) |
- (ucontrol->value.iec958.status[3] << 24);
- change = val != emu->spdif_bits[idx];
- if (change) {
- snd_emu10k1x_ptr_write(emu, SPCS0 + idx, 0, val);
- emu->spdif_bits[idx] = val;
- }
- return change;
-}
-
-static struct snd_kcontrol_new snd_emu10k1x_spdif_mask_control =
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
- .count = 3,
- .info = snd_emu10k1x_spdif_info,
- .get = snd_emu10k1x_spdif_get_mask
-};
-
-static struct snd_kcontrol_new snd_emu10k1x_spdif_control =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
- .count = 3,
- .info = snd_emu10k1x_spdif_info,
- .get = snd_emu10k1x_spdif_get,
- .put = snd_emu10k1x_spdif_put
-};
-
-static int __devinit snd_emu10k1x_mixer(struct emu10k1x *emu)
-{
- int err;
- struct snd_kcontrol *kctl;
- struct snd_card *card = emu->card;
-
- if ((kctl = snd_ctl_new1(&snd_emu10k1x_spdif_mask_control, emu)) == NULL)
- return -ENOMEM;
- if ((err = snd_ctl_add(card, kctl)))
- return err;
- if ((kctl = snd_ctl_new1(&snd_emu10k1x_shared_spdif, emu)) == NULL)
- return -ENOMEM;
- if ((err = snd_ctl_add(card, kctl)))
- return err;
- if ((kctl = snd_ctl_new1(&snd_emu10k1x_spdif_control, emu)) == NULL)
- return -ENOMEM;
- if ((err = snd_ctl_add(card, kctl)))
- return err;
-
- return 0;
-}
-
-#define EMU10K1X_MIDI_MODE_INPUT (1<<0)
-#define EMU10K1X_MIDI_MODE_OUTPUT (1<<1)
-
-static inline unsigned char mpu401_read(struct emu10k1x *emu, struct emu10k1x_midi *mpu, int idx)
-{
- return (unsigned char)snd_emu10k1x_ptr_read(emu, mpu->port + idx, 0);
-}
-
-static inline void mpu401_write(struct emu10k1x *emu, struct emu10k1x_midi *mpu, int data, int idx)
-{
- snd_emu10k1x_ptr_write(emu, mpu->port + idx, 0, data);
-}
-
-#define mpu401_write_data(emu, mpu, data) mpu401_write(emu, mpu, data, 0)
-#define mpu401_write_cmd(emu, mpu, data) mpu401_write(emu, mpu, data, 1)
-#define mpu401_read_data(emu, mpu) mpu401_read(emu, mpu, 0)
-#define mpu401_read_stat(emu, mpu) mpu401_read(emu, mpu, 1)
-
-#define mpu401_input_avail(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x80))
-#define mpu401_output_ready(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x40))
-
-#define MPU401_RESET 0xff
-#define MPU401_ENTER_UART 0x3f
-#define MPU401_ACK 0xfe
-
-static void mpu401_clear_rx(struct emu10k1x *emu, struct emu10k1x_midi *mpu)
-{
- int timeout = 100000;
- for (; timeout > 0 && mpu401_input_avail(emu, mpu); timeout--)
- mpu401_read_data(emu, mpu);
-#ifdef CONFIG_SND_DEBUG
- if (timeout <= 0)
- snd_printk(KERN_ERR "cmd: clear rx timeout (status = 0x%x)\n", mpu401_read_stat(emu, mpu));
-#endif
-}
-
-/*
-
- */
-
-static void do_emu10k1x_midi_interrupt(struct emu10k1x *emu,
- struct emu10k1x_midi *midi, unsigned int status)
-{
- unsigned char byte;
-
- if (midi->rmidi == NULL) {
- snd_emu10k1x_intr_disable(emu, midi->tx_enable | midi->rx_enable);
- return;
- }
-
- spin_lock(&midi->input_lock);
- if ((status & midi->ipr_rx) && mpu401_input_avail(emu, midi)) {
- if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
- mpu401_clear_rx(emu, midi);
- } else {
- byte = mpu401_read_data(emu, midi);
- if (midi->substream_input)
- snd_rawmidi_receive(midi->substream_input, &byte, 1);
- }
- }
- spin_unlock(&midi->input_lock);
-
- spin_lock(&midi->output_lock);
- if ((status & midi->ipr_tx) && mpu401_output_ready(emu, midi)) {
- if (midi->substream_output &&
- snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
- mpu401_write_data(emu, midi, byte);
- } else {
- snd_emu10k1x_intr_disable(emu, midi->tx_enable);
- }
- }
- spin_unlock(&midi->output_lock);
-}
-
-static void snd_emu10k1x_midi_interrupt(struct emu10k1x *emu, unsigned int status)
-{
- do_emu10k1x_midi_interrupt(emu, &emu->midi, status);
-}
-
-static int snd_emu10k1x_midi_cmd(struct emu10k1x * emu,
- struct emu10k1x_midi *midi, unsigned char cmd, int ack)
-{
- unsigned long flags;
- int timeout, ok;
-
- spin_lock_irqsave(&midi->input_lock, flags);
- mpu401_write_data(emu, midi, 0x00);
- /* mpu401_clear_rx(emu, midi); */
-
- mpu401_write_cmd(emu, midi, cmd);
- if (ack) {
- ok = 0;
- timeout = 10000;
- while (!ok && timeout-- > 0) {
- if (mpu401_input_avail(emu, midi)) {
- if (mpu401_read_data(emu, midi) == MPU401_ACK)
- ok = 1;
- }
- }
- if (!ok && mpu401_read_data(emu, midi) == MPU401_ACK)
- ok = 1;
- } else {
- ok = 1;
- }
- spin_unlock_irqrestore(&midi->input_lock, flags);
- if (!ok) {
- snd_printk(KERN_ERR "midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n",
- cmd, emu->port,
- mpu401_read_stat(emu, midi),
- mpu401_read_data(emu, midi));
- return 1;
- }
- return 0;
-}
-
-static int snd_emu10k1x_midi_input_open(struct snd_rawmidi_substream *substream)
-{
- struct emu10k1x *emu;
- struct emu10k1x_midi *midi = substream->rmidi->private_data;
- unsigned long flags;
-
- emu = midi->emu;
- if (snd_BUG_ON(!emu))
- return -ENXIO;
- spin_lock_irqsave(&midi->open_lock, flags);
- midi->midi_mode |= EMU10K1X_MIDI_MODE_INPUT;
- midi->substream_input = substream;
- if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1))
- goto error_out;
- if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
- goto error_out;
- } else {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- }
- return 0;
-
-error_out:
- return -EIO;
-}
-
-static int snd_emu10k1x_midi_output_open(struct snd_rawmidi_substream *substream)
-{
- struct emu10k1x *emu;
- struct emu10k1x_midi *midi = substream->rmidi->private_data;
- unsigned long flags;
-
- emu = midi->emu;
- if (snd_BUG_ON(!emu))
- return -ENXIO;
- spin_lock_irqsave(&midi->open_lock, flags);
- midi->midi_mode |= EMU10K1X_MIDI_MODE_OUTPUT;
- midi->substream_output = substream;
- if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1))
- goto error_out;
- if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
- goto error_out;
- } else {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- }
- return 0;
-
-error_out:
- return -EIO;
-}
-
-static int snd_emu10k1x_midi_input_close(struct snd_rawmidi_substream *substream)
-{
- struct emu10k1x *emu;
- struct emu10k1x_midi *midi = substream->rmidi->private_data;
- unsigned long flags;
- int err = 0;
-
- emu = midi->emu;
- if (snd_BUG_ON(!emu))
- return -ENXIO;
- spin_lock_irqsave(&midi->open_lock, flags);
- snd_emu10k1x_intr_disable(emu, midi->rx_enable);
- midi->midi_mode &= ~EMU10K1X_MIDI_MODE_INPUT;
- midi->substream_input = NULL;
- if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- err = snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0);
- } else {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- }
- return err;
-}
-
-static int snd_emu10k1x_midi_output_close(struct snd_rawmidi_substream *substream)
-{
- struct emu10k1x *emu;
- struct emu10k1x_midi *midi = substream->rmidi->private_data;
- unsigned long flags;
- int err = 0;
-
- emu = midi->emu;
- if (snd_BUG_ON(!emu))
- return -ENXIO;
- spin_lock_irqsave(&midi->open_lock, flags);
- snd_emu10k1x_intr_disable(emu, midi->tx_enable);
- midi->midi_mode &= ~EMU10K1X_MIDI_MODE_OUTPUT;
- midi->substream_output = NULL;
- if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- err = snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0);
- } else {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- }
- return err;
-}
-
-static void snd_emu10k1x_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct emu10k1x *emu;
- struct emu10k1x_midi *midi = substream->rmidi->private_data;
- emu = midi->emu;
- if (snd_BUG_ON(!emu))
- return;
-
- if (up)
- snd_emu10k1x_intr_enable(emu, midi->rx_enable);
- else
- snd_emu10k1x_intr_disable(emu, midi->rx_enable);
-}
-
-static void snd_emu10k1x_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct emu10k1x *emu;
- struct emu10k1x_midi *midi = substream->rmidi->private_data;
- unsigned long flags;
-
- emu = midi->emu;
- if (snd_BUG_ON(!emu))
- return;
-
- if (up) {
- int max = 4;
- unsigned char byte;
-
- /* try to send some amount of bytes here before interrupts */
- spin_lock_irqsave(&midi->output_lock, flags);
- while (max > 0) {
- if (mpu401_output_ready(emu, midi)) {
- if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT) ||
- snd_rawmidi_transmit(substream, &byte, 1) != 1) {
- /* no more data */
- spin_unlock_irqrestore(&midi->output_lock, flags);
- return;
- }
- mpu401_write_data(emu, midi, byte);
- max--;
- } else {
- break;
- }
- }
- spin_unlock_irqrestore(&midi->output_lock, flags);
- snd_emu10k1x_intr_enable(emu, midi->tx_enable);
- } else {
- snd_emu10k1x_intr_disable(emu, midi->tx_enable);
- }
-}
-
-/*
-
- */
-
-static struct snd_rawmidi_ops snd_emu10k1x_midi_output =
-{
- .open = snd_emu10k1x_midi_output_open,
- .close = snd_emu10k1x_midi_output_close,
- .trigger = snd_emu10k1x_midi_output_trigger,
-};
-
-static struct snd_rawmidi_ops snd_emu10k1x_midi_input =
-{
- .open = snd_emu10k1x_midi_input_open,
- .close = snd_emu10k1x_midi_input_close,
- .trigger = snd_emu10k1x_midi_input_trigger,
-};
-
-static void snd_emu10k1x_midi_free(struct snd_rawmidi *rmidi)
-{
- struct emu10k1x_midi *midi = rmidi->private_data;
- midi->interrupt = NULL;
- midi->rmidi = NULL;
-}
-
-static int __devinit emu10k1x_midi_init(struct emu10k1x *emu,
- struct emu10k1x_midi *midi, int device, char *name)
-{
- struct snd_rawmidi *rmidi;
- int err;
-
- if ((err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi)) < 0)
- return err;
- midi->emu = emu;
- spin_lock_init(&midi->open_lock);
- spin_lock_init(&midi->input_lock);
- spin_lock_init(&midi->output_lock);
- strcpy(rmidi->name, name);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_emu10k1x_midi_output);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_emu10k1x_midi_input);
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
- rmidi->private_data = midi;
- rmidi->private_free = snd_emu10k1x_midi_free;
- midi->rmidi = rmidi;
- return 0;
-}
-
-static int __devinit snd_emu10k1x_midi(struct emu10k1x *emu)
-{
- struct emu10k1x_midi *midi = &emu->midi;
- int err;
-
- if ((err = emu10k1x_midi_init(emu, midi, 0, "EMU10K1X MPU-401 (UART)")) < 0)
- return err;
-
- midi->tx_enable = INTE_MIDITXENABLE;
- midi->rx_enable = INTE_MIDIRXENABLE;
- midi->port = MUDATA;
- midi->ipr_tx = IPR_MIDITRANSBUFEMPTY;
- midi->ipr_rx = IPR_MIDIRECVBUFEMPTY;
- midi->interrupt = snd_emu10k1x_midi_interrupt;
- return 0;
-}
-
-static int __devinit snd_emu10k1x_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct emu10k1x *chip;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- if ((err = snd_emu10k1x_create(card, pci, &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- if ((err = snd_emu10k1x_pcm(chip, 0, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_emu10k1x_pcm(chip, 1, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_emu10k1x_pcm(chip, 2, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- if ((err = snd_emu10k1x_ac97(chip)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- if ((err = snd_emu10k1x_mixer(chip)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- if ((err = snd_emu10k1x_midi(chip)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- snd_emu10k1x_proc_init(chip);
-
- strcpy(card->driver, "EMU10K1X");
- strcpy(card->shortname, "Dell Sound Blaster Live!");
- sprintf(card->longname, "%s at 0x%lx irq %i",
- card->shortname, chip->port, chip->irq);
-
- snd_card_set_dev(card, &pci->dev);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_emu10k1x_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-// PCI IDs
-static DEFINE_PCI_DEVICE_TABLE(snd_emu10k1x_ids) = {
- { PCI_VDEVICE(CREATIVE, 0x0006), 0 }, /* Dell OEM version (EMU10K1) */
- { 0, }
-};
-MODULE_DEVICE_TABLE(pci, snd_emu10k1x_ids);
-
-// pci_driver definition
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_emu10k1x_ids,
- .probe = snd_emu10k1x_probe,
- .remove = __devexit_p(snd_emu10k1x_remove),
-};
-
-// initialization of the module
-static int __init alsa_card_emu10k1x_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-// clean up the module
-static void __exit alsa_card_emu10k1x_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_emu10k1x_init)
-module_exit(alsa_card_emu10k1x_exit)
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/emufx.c b/ANDROID_3.4.5/sound/pci/emu10k1/emufx.c
deleted file mode 100644
index dae4050e..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/emufx.c
+++ /dev/null
@@ -1,2758 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Creative Labs, Inc.
- * Routines for effect processor FX8010
- *
- * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk>
- * Added EMU 1010 support.
- *
- * BUGS:
- * --
- *
- * TODO:
- * --
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/pci.h>
-#include <linux/capability.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/init.h>
-#include <linux/mutex.h>
-#include <linux/moduleparam.h>
-
-#include <sound/core.h>
-#include <sound/tlv.h>
-#include <sound/emu10k1.h>
-
-#if 0 /* for testing purposes - digital out -> capture */
-#define EMU10K1_CAPTURE_DIGITAL_OUT
-#endif
-#if 0 /* for testing purposes - set S/PDIF to AC3 output */
-#define EMU10K1_SET_AC3_IEC958
-#endif
-#if 0 /* for testing purposes - feed the front signal to Center/LFE outputs */
-#define EMU10K1_CENTER_LFE_FROM_FRONT
-#endif
-
-static bool high_res_gpr_volume;
-module_param(high_res_gpr_volume, bool, 0444);
-MODULE_PARM_DESC(high_res_gpr_volume, "GPR mixer controls use 31-bit range.");
-
-/*
- * Tables
- */
-
-static char *fxbuses[16] = {
- /* 0x00 */ "PCM Left",
- /* 0x01 */ "PCM Right",
- /* 0x02 */ "PCM Surround Left",
- /* 0x03 */ "PCM Surround Right",
- /* 0x04 */ "MIDI Left",
- /* 0x05 */ "MIDI Right",
- /* 0x06 */ "Center",
- /* 0x07 */ "LFE",
- /* 0x08 */ NULL,
- /* 0x09 */ NULL,
- /* 0x0a */ NULL,
- /* 0x0b */ NULL,
- /* 0x0c */ "MIDI Reverb",
- /* 0x0d */ "MIDI Chorus",
- /* 0x0e */ NULL,
- /* 0x0f */ NULL
-};
-
-static char *creative_ins[16] = {
- /* 0x00 */ "AC97 Left",
- /* 0x01 */ "AC97 Right",
- /* 0x02 */ "TTL IEC958 Left",
- /* 0x03 */ "TTL IEC958 Right",
- /* 0x04 */ "Zoom Video Left",
- /* 0x05 */ "Zoom Video Right",
- /* 0x06 */ "Optical IEC958 Left",
- /* 0x07 */ "Optical IEC958 Right",
- /* 0x08 */ "Line/Mic 1 Left",
- /* 0x09 */ "Line/Mic 1 Right",
- /* 0x0a */ "Coaxial IEC958 Left",
- /* 0x0b */ "Coaxial IEC958 Right",
- /* 0x0c */ "Line/Mic 2 Left",
- /* 0x0d */ "Line/Mic 2 Right",
- /* 0x0e */ NULL,
- /* 0x0f */ NULL
-};
-
-static char *audigy_ins[16] = {
- /* 0x00 */ "AC97 Left",
- /* 0x01 */ "AC97 Right",
- /* 0x02 */ "Audigy CD Left",
- /* 0x03 */ "Audigy CD Right",
- /* 0x04 */ "Optical IEC958 Left",
- /* 0x05 */ "Optical IEC958 Right",
- /* 0x06 */ NULL,
- /* 0x07 */ NULL,
- /* 0x08 */ "Line/Mic 2 Left",
- /* 0x09 */ "Line/Mic 2 Right",
- /* 0x0a */ "SPDIF Left",
- /* 0x0b */ "SPDIF Right",
- /* 0x0c */ "Aux2 Left",
- /* 0x0d */ "Aux2 Right",
- /* 0x0e */ NULL,
- /* 0x0f */ NULL
-};
-
-static char *creative_outs[32] = {
- /* 0x00 */ "AC97 Left",
- /* 0x01 */ "AC97 Right",
- /* 0x02 */ "Optical IEC958 Left",
- /* 0x03 */ "Optical IEC958 Right",
- /* 0x04 */ "Center",
- /* 0x05 */ "LFE",
- /* 0x06 */ "Headphone Left",
- /* 0x07 */ "Headphone Right",
- /* 0x08 */ "Surround Left",
- /* 0x09 */ "Surround Right",
- /* 0x0a */ "PCM Capture Left",
- /* 0x0b */ "PCM Capture Right",
- /* 0x0c */ "MIC Capture",
- /* 0x0d */ "AC97 Surround Left",
- /* 0x0e */ "AC97 Surround Right",
- /* 0x0f */ NULL,
- /* 0x10 */ NULL,
- /* 0x11 */ "Analog Center",
- /* 0x12 */ "Analog LFE",
- /* 0x13 */ NULL,
- /* 0x14 */ NULL,
- /* 0x15 */ NULL,
- /* 0x16 */ NULL,
- /* 0x17 */ NULL,
- /* 0x18 */ NULL,
- /* 0x19 */ NULL,
- /* 0x1a */ NULL,
- /* 0x1b */ NULL,
- /* 0x1c */ NULL,
- /* 0x1d */ NULL,
- /* 0x1e */ NULL,
- /* 0x1f */ NULL,
-};
-
-static char *audigy_outs[32] = {
- /* 0x00 */ "Digital Front Left",
- /* 0x01 */ "Digital Front Right",
- /* 0x02 */ "Digital Center",
- /* 0x03 */ "Digital LEF",
- /* 0x04 */ "Headphone Left",
- /* 0x05 */ "Headphone Right",
- /* 0x06 */ "Digital Rear Left",
- /* 0x07 */ "Digital Rear Right",
- /* 0x08 */ "Front Left",
- /* 0x09 */ "Front Right",
- /* 0x0a */ "Center",
- /* 0x0b */ "LFE",
- /* 0x0c */ NULL,
- /* 0x0d */ NULL,
- /* 0x0e */ "Rear Left",
- /* 0x0f */ "Rear Right",
- /* 0x10 */ "AC97 Front Left",
- /* 0x11 */ "AC97 Front Right",
- /* 0x12 */ "ADC Caputre Left",
- /* 0x13 */ "ADC Capture Right",
- /* 0x14 */ NULL,
- /* 0x15 */ NULL,
- /* 0x16 */ NULL,
- /* 0x17 */ NULL,
- /* 0x18 */ NULL,
- /* 0x19 */ NULL,
- /* 0x1a */ NULL,
- /* 0x1b */ NULL,
- /* 0x1c */ NULL,
- /* 0x1d */ NULL,
- /* 0x1e */ NULL,
- /* 0x1f */ NULL,
-};
-
-static const u32 bass_table[41][5] = {
- { 0x3e4f844f, 0x84ed4cc3, 0x3cc69927, 0x7b03553a, 0xc4da8486 },
- { 0x3e69a17a, 0x84c280fb, 0x3cd77cd4, 0x7b2f2a6f, 0xc4b08d1d },
- { 0x3e82ff42, 0x849991d5, 0x3ce7466b, 0x7b5917c6, 0xc48863ee },
- { 0x3e9bab3c, 0x847267f0, 0x3cf5ffe8, 0x7b813560, 0xc461f22c },
- { 0x3eb3b275, 0x844ced29, 0x3d03b295, 0x7ba79a1c, 0xc43d223b },
- { 0x3ecb2174, 0x84290c8b, 0x3d106714, 0x7bcc5ba3, 0xc419dfa5 },
- { 0x3ee2044b, 0x8406b244, 0x3d1c2561, 0x7bef8e77, 0xc3f8170f },
- { 0x3ef86698, 0x83e5cb96, 0x3d26f4d8, 0x7c114600, 0xc3d7b625 },
- { 0x3f0e5390, 0x83c646c9, 0x3d30dc39, 0x7c319498, 0xc3b8ab97 },
- { 0x3f23d60b, 0x83a81321, 0x3d39e1af, 0x7c508b9c, 0xc39ae704 },
- { 0x3f38f884, 0x838b20d2, 0x3d420ad2, 0x7c6e3b75, 0xc37e58f1 },
- { 0x3f4dc52c, 0x836f60ef, 0x3d495cab, 0x7c8ab3a6, 0xc362f2be },
- { 0x3f6245e8, 0x8354c565, 0x3d4fdbb8, 0x7ca602d6, 0xc348a69b },
- { 0x3f76845f, 0x833b40ec, 0x3d558bf0, 0x7cc036df, 0xc32f677c },
- { 0x3f8a8a03, 0x8322c6fb, 0x3d5a70c4, 0x7cd95cd7, 0xc317290b },
- { 0x3f9e6014, 0x830b4bc3, 0x3d5e8d25, 0x7cf1811a, 0xc2ffdfa5 },
- { 0x3fb20fae, 0x82f4c420, 0x3d61e37f, 0x7d08af56, 0xc2e9804a },
- { 0x3fc5a1cc, 0x82df2592, 0x3d6475c3, 0x7d1ef294, 0xc2d40096 },
- { 0x3fd91f55, 0x82ca6632, 0x3d664564, 0x7d345541, 0xc2bf56b9 },
- { 0x3fec9120, 0x82b67cac, 0x3d675356, 0x7d48e138, 0xc2ab796e },
- { 0x40000000, 0x82a36037, 0x3d67a012, 0x7d5c9fc9, 0xc2985fee },
- { 0x401374c7, 0x8291088a, 0x3d672b93, 0x7d6f99c3, 0xc28601f2 },
- { 0x4026f857, 0x827f6dd7, 0x3d65f559, 0x7d81d77c, 0xc27457a3 },
- { 0x403a939f, 0x826e88c5, 0x3d63fc63, 0x7d9360d4, 0xc2635996 },
- { 0x404e4faf, 0x825e5266, 0x3d613f32, 0x7da43d42, 0xc25300c6 },
- { 0x406235ba, 0x824ec434, 0x3d5dbbc3, 0x7db473d7, 0xc243468e },
- { 0x40764f1f, 0x823fd80c, 0x3d596f8f, 0x7dc40b44, 0xc23424a2 },
- { 0x408aa576, 0x82318824, 0x3d545787, 0x7dd309e2, 0xc2259509 },
- { 0x409f4296, 0x8223cf0b, 0x3d4e7012, 0x7de175b5, 0xc2179218 },
- { 0x40b430a0, 0x8216a7a1, 0x3d47b505, 0x7def5475, 0xc20a1670 },
- { 0x40c97a0a, 0x820a0d12, 0x3d4021a1, 0x7dfcab8d, 0xc1fd1cf5 },
- { 0x40df29a6, 0x81fdfad6, 0x3d37b08d, 0x7e098028, 0xc1f0a0ca },
- { 0x40f54ab1, 0x81f26ca9, 0x3d2e5bd1, 0x7e15d72b, 0xc1e49d52 },
- { 0x410be8da, 0x81e75e89, 0x3d241cce, 0x7e21b544, 0xc1d90e24 },
- { 0x41231051, 0x81dcccb3, 0x3d18ec37, 0x7e2d1ee6, 0xc1cdef10 },
- { 0x413acdd0, 0x81d2b39e, 0x3d0cc20a, 0x7e38184e, 0xc1c33c13 },
- { 0x41532ea7, 0x81c90ffb, 0x3cff9585, 0x7e42a58b, 0xc1b8f15a },
- { 0x416c40cd, 0x81bfdeb2, 0x3cf15d21, 0x7e4cca7c, 0xc1af0b3f },
- { 0x418612ea, 0x81b71cdc, 0x3ce20e85, 0x7e568ad3, 0xc1a58640 },
- { 0x41a0b465, 0x81aec7c5, 0x3cd19e7c, 0x7e5fea1e, 0xc19c5f03 },
- { 0x41bc3573, 0x81a6dcea, 0x3cc000e9, 0x7e68ebc2, 0xc1939250 }
-};
-
-static const u32 treble_table[41][5] = {
- { 0x0125cba9, 0xfed5debd, 0x00599b6c, 0x0d2506da, 0xfa85b354 },
- { 0x0142f67e, 0xfeb03163, 0x0066cd0f, 0x0d14c69d, 0xfa914473 },
- { 0x016328bd, 0xfe860158, 0x0075b7f2, 0x0d03eb27, 0xfa9d32d2 },
- { 0x0186b438, 0xfe56c982, 0x00869234, 0x0cf27048, 0xfaa97fca },
- { 0x01adf358, 0xfe21f5fe, 0x00999842, 0x0ce051c2, 0xfab62ca5 },
- { 0x01d949fa, 0xfde6e287, 0x00af0d8d, 0x0ccd8b4a, 0xfac33aa7 },
- { 0x02092669, 0xfda4d8bf, 0x00c73d4c, 0x0cba1884, 0xfad0ab07 },
- { 0x023e0268, 0xfd5b0e4a, 0x00e27b54, 0x0ca5f509, 0xfade7ef2 },
- { 0x0278645c, 0xfd08a2b0, 0x01012509, 0x0c911c63, 0xfaecb788 },
- { 0x02b8e091, 0xfcac9d1a, 0x0123a262, 0x0c7b8a14, 0xfafb55df },
- { 0x03001a9a, 0xfc45e9ce, 0x014a6709, 0x0c65398f, 0xfb0a5aff },
- { 0x034ec6d7, 0xfbd3576b, 0x0175f397, 0x0c4e2643, 0xfb19c7e4 },
- { 0x03a5ac15, 0xfb5393ee, 0x01a6d6ed, 0x0c364b94, 0xfb299d7c },
- { 0x0405a562, 0xfac52968, 0x01ddafae, 0x0c1da4e2, 0xfb39dca5 },
- { 0x046fa3fe, 0xfa267a66, 0x021b2ddd, 0x0c042d8d, 0xfb4a8631 },
- { 0x04e4b17f, 0xf975be0f, 0x0260149f, 0x0be9e0f2, 0xfb5b9ae0 },
- { 0x0565f220, 0xf8b0fbe5, 0x02ad3c29, 0x0bceba73, 0xfb6d1b60 },
- { 0x05f4a745, 0xf7d60722, 0x030393d4, 0x0bb2b578, 0xfb7f084d },
- { 0x06923236, 0xf6e279bd, 0x03642465, 0x0b95cd75, 0xfb916233 },
- { 0x07401713, 0xf5d3aef9, 0x03d01283, 0x0b77fded, 0xfba42984 },
- { 0x08000000, 0xf4a6bd88, 0x0448a161, 0x0b594278, 0xfbb75e9f },
- { 0x08d3c097, 0xf3587131, 0x04cf35a4, 0x0b3996c9, 0xfbcb01cb },
- { 0x09bd59a2, 0xf1e543f9, 0x05655880, 0x0b18f6b2, 0xfbdf1333 },
- { 0x0abefd0f, 0xf04956ca, 0x060cbb12, 0x0af75e2c, 0xfbf392e8 },
- { 0x0bdb123e, 0xee806984, 0x06c739fe, 0x0ad4c962, 0xfc0880dd },
- { 0x0d143a94, 0xec85d287, 0x0796e150, 0x0ab134b0, 0xfc1ddce5 },
- { 0x0e6d5664, 0xea547598, 0x087df0a0, 0x0a8c9cb6, 0xfc33a6ad },
- { 0x0fe98a2a, 0xe7e6ba35, 0x097edf83, 0x0a66fe5b, 0xfc49ddc2 },
- { 0x118c4421, 0xe536813a, 0x0a9c6248, 0x0a4056d7, 0xfc608185 },
- { 0x1359422e, 0xe23d19eb, 0x0bd96efb, 0x0a18a3bf, 0xfc77912c },
- { 0x1554982b, 0xdef33645, 0x0d3942bd, 0x09efe312, 0xfc8f0bc1 },
- { 0x1782b68a, 0xdb50deb1, 0x0ebf676d, 0x09c6133f, 0xfca6f019 },
- { 0x19e8715d, 0xd74d64fd, 0x106fb999, 0x099b3337, 0xfcbf3cd6 },
- { 0x1c8b07b8, 0xd2df56ab, 0x124e6ec8, 0x096f4274, 0xfcd7f060 },
- { 0x1f702b6d, 0xcdfc6e92, 0x14601c10, 0x0942410b, 0xfcf108e5 },
- { 0x229e0933, 0xc89985cd, 0x16a9bcfa, 0x09142fb5, 0xfd0a8451 },
- { 0x261b5118, 0xc2aa8409, 0x1930bab6, 0x08e50fdc, 0xfd24604d },
- { 0x29ef3f5d, 0xbc224f28, 0x1bfaf396, 0x08b4e3aa, 0xfd3e9a3b },
- { 0x2e21a59b, 0xb4f2ba46, 0x1f0ec2d6, 0x0883ae15, 0xfd592f33 },
- { 0x32baf44b, 0xad0c7429, 0x227308a3, 0x085172eb, 0xfd741bfd },
- { 0x37c4448b, 0xa45ef51d, 0x262f3267, 0x081e36dc, 0xfd8f5d14 }
-};
-
-/* dB gain = (float) 20 * log10( float(db_table_value) / 0x8000000 ) */
-static const u32 db_table[101] = {
- 0x00000000, 0x01571f82, 0x01674b41, 0x01783a1b, 0x0189f540,
- 0x019c8651, 0x01aff763, 0x01c45306, 0x01d9a446, 0x01eff6b8,
- 0x0207567a, 0x021fd03d, 0x0239714c, 0x02544792, 0x027061a1,
- 0x028dcebb, 0x02ac9edc, 0x02cce2bf, 0x02eeabe8, 0x03120cb0,
- 0x0337184e, 0x035de2df, 0x03868173, 0x03b10a18, 0x03dd93e9,
- 0x040c3713, 0x043d0cea, 0x04702ff3, 0x04a5bbf2, 0x04ddcdfb,
- 0x0518847f, 0x0555ff62, 0x05966005, 0x05d9c95d, 0x06206005,
- 0x066a4a52, 0x06b7b067, 0x0708bc4c, 0x075d9a01, 0x07b6779d,
- 0x08138561, 0x0874f5d5, 0x08dafde1, 0x0945d4ed, 0x09b5b4fd,
- 0x0a2adad1, 0x0aa58605, 0x0b25f936, 0x0bac7a24, 0x0c3951d8,
- 0x0ccccccc, 0x0d673b17, 0x0e08f093, 0x0eb24510, 0x0f639481,
- 0x101d3f2d, 0x10dfa9e6, 0x11ab3e3f, 0x12806ac3, 0x135fa333,
- 0x144960c5, 0x153e2266, 0x163e6cfe, 0x174acbb7, 0x1863d04d,
- 0x198a1357, 0x1abe349f, 0x1c00db77, 0x1d52b712, 0x1eb47ee6,
- 0x2026f30f, 0x21aadcb6, 0x23410e7e, 0x24ea64f9, 0x26a7c71d,
- 0x287a26c4, 0x2a62812c, 0x2c61df84, 0x2e795779, 0x30aa0bcf,
- 0x32f52cfe, 0x355bf9d8, 0x37dfc033, 0x3a81dda4, 0x3d43c038,
- 0x4026e73c, 0x432ce40f, 0x46575af8, 0x49a8040f, 0x4d20ac2a,
- 0x50c335d3, 0x54919a57, 0x588dead1, 0x5cba514a, 0x611911ea,
- 0x65ac8c2f, 0x6a773c39, 0x6f7bbc23, 0x74bcc56c, 0x7a3d3272,
- 0x7fffffff,
-};
-
-/* EMU10k1/EMU10k2 DSP control db gain */
-static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1);
-static const DECLARE_TLV_DB_LINEAR(snd_emu10k1_db_linear, TLV_DB_GAIN_MUTE, 0);
-
-/* EMU10K1 bass/treble db gain */
-static const DECLARE_TLV_DB_SCALE(snd_emu10k1_bass_treble_db_scale, -1200, 60, 0);
-
-static const u32 onoff_table[2] = {
- 0x00000000, 0x00000001
-};
-
-/*
- */
-
-static inline mm_segment_t snd_enter_user(void)
-{
- mm_segment_t fs = get_fs();
- set_fs(get_ds());
- return fs;
-}
-
-static inline void snd_leave_user(mm_segment_t fs)
-{
- set_fs(fs);
-}
-
-/*
- * controls
- */
-
-static int snd_emu10k1_gpr_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct snd_emu10k1_fx8010_ctl *ctl =
- (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
-
- if (ctl->min == 0 && ctl->max == 1)
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- else
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = ctl->vcount;
- uinfo->value.integer.min = ctl->min;
- uinfo->value.integer.max = ctl->max;
- return 0;
-}
-
-static int snd_emu10k1_gpr_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- struct snd_emu10k1_fx8010_ctl *ctl =
- (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
- unsigned long flags;
- unsigned int i;
-
- spin_lock_irqsave(&emu->reg_lock, flags);
- for (i = 0; i < ctl->vcount; i++)
- ucontrol->value.integer.value[i] = ctl->value[i];
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return 0;
-}
-
-static int snd_emu10k1_gpr_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- struct snd_emu10k1_fx8010_ctl *ctl =
- (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
- unsigned long flags;
- unsigned int nval, val;
- unsigned int i, j;
- int change = 0;
-
- spin_lock_irqsave(&emu->reg_lock, flags);
- for (i = 0; i < ctl->vcount; i++) {
- nval = ucontrol->value.integer.value[i];
- if (nval < ctl->min)
- nval = ctl->min;
- if (nval > ctl->max)
- nval = ctl->max;
- if (nval != ctl->value[i])
- change = 1;
- val = ctl->value[i] = nval;
- switch (ctl->translation) {
- case EMU10K1_GPR_TRANSLATION_NONE:
- snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, val);
- break;
- case EMU10K1_GPR_TRANSLATION_TABLE100:
- snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]);
- break;
- case EMU10K1_GPR_TRANSLATION_BASS:
- if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
- change = -EIO;
- goto __error;
- }
- for (j = 0; j < 5; j++)
- snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]);
- break;
- case EMU10K1_GPR_TRANSLATION_TREBLE:
- if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
- change = -EIO;
- goto __error;
- }
- for (j = 0; j < 5; j++)
- snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]);
- break;
- case EMU10K1_GPR_TRANSLATION_ONOFF:
- snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, onoff_table[val]);
- break;
- }
- }
- __error:
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return change;
-}
-
-/*
- * Interrupt handler
- */
-
-static void snd_emu10k1_fx8010_interrupt(struct snd_emu10k1 *emu)
-{
- struct snd_emu10k1_fx8010_irq *irq, *nirq;
-
- irq = emu->fx8010.irq_handlers;
- while (irq) {
- nirq = irq->next; /* irq ptr can be removed from list */
- if (snd_emu10k1_ptr_read(emu, emu->gpr_base + irq->gpr_running, 0) & 0xffff0000) {
- if (irq->handler)
- irq->handler(emu, irq->private_data);
- snd_emu10k1_ptr_write(emu, emu->gpr_base + irq->gpr_running, 0, 1);
- }
- irq = nirq;
- }
-}
-
-int snd_emu10k1_fx8010_register_irq_handler(struct snd_emu10k1 *emu,
- snd_fx8010_irq_handler_t *handler,
- unsigned char gpr_running,
- void *private_data,
- struct snd_emu10k1_fx8010_irq **r_irq)
-{
- struct snd_emu10k1_fx8010_irq *irq;
- unsigned long flags;
-
- irq = kmalloc(sizeof(*irq), GFP_ATOMIC);
- if (irq == NULL)
- return -ENOMEM;
- irq->handler = handler;
- irq->gpr_running = gpr_running;
- irq->private_data = private_data;
- irq->next = NULL;
- spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
- if (emu->fx8010.irq_handlers == NULL) {
- emu->fx8010.irq_handlers = irq;
- emu->dsp_interrupt = snd_emu10k1_fx8010_interrupt;
- snd_emu10k1_intr_enable(emu, INTE_FXDSPENABLE);
- } else {
- irq->next = emu->fx8010.irq_handlers;
- emu->fx8010.irq_handlers = irq;
- }
- spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
- if (r_irq)
- *r_irq = irq;
- return 0;
-}
-
-int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
- struct snd_emu10k1_fx8010_irq *irq)
-{
- struct snd_emu10k1_fx8010_irq *tmp;
- unsigned long flags;
-
- spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
- if ((tmp = emu->fx8010.irq_handlers) == irq) {
- emu->fx8010.irq_handlers = tmp->next;
- if (emu->fx8010.irq_handlers == NULL) {
- snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
- emu->dsp_interrupt = NULL;
- }
- } else {
- while (tmp && tmp->next != irq)
- tmp = tmp->next;
- if (tmp)
- tmp->next = tmp->next->next;
- }
- spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
- kfree(irq);
- return 0;
-}
-
-/*************************************************************************
- * EMU10K1 effect manager
- *************************************************************************/
-
-static void snd_emu10k1_write_op(struct snd_emu10k1_fx8010_code *icode,
- unsigned int *ptr,
- u32 op, u32 r, u32 a, u32 x, u32 y)
-{
- u_int32_t *code;
- if (snd_BUG_ON(*ptr >= 512))
- return;
- code = (u_int32_t __force *)icode->code + (*ptr) * 2;
- set_bit(*ptr, icode->code_valid);
- code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
- code[1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
- (*ptr)++;
-}
-
-#define OP(icode, ptr, op, r, a, x, y) \
- snd_emu10k1_write_op(icode, ptr, op, r, a, x, y)
-
-static void snd_emu10k1_audigy_write_op(struct snd_emu10k1_fx8010_code *icode,
- unsigned int *ptr,
- u32 op, u32 r, u32 a, u32 x, u32 y)
-{
- u_int32_t *code;
- if (snd_BUG_ON(*ptr >= 1024))
- return;
- code = (u_int32_t __force *)icode->code + (*ptr) * 2;
- set_bit(*ptr, icode->code_valid);
- code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
- code[1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
- (*ptr)++;
-}
-
-#define A_OP(icode, ptr, op, r, a, x, y) \
- snd_emu10k1_audigy_write_op(icode, ptr, op, r, a, x, y)
-
-static void snd_emu10k1_efx_write(struct snd_emu10k1 *emu, unsigned int pc, unsigned int data)
-{
- pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
- snd_emu10k1_ptr_write(emu, pc, 0, data);
-}
-
-unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc)
-{
- pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
- return snd_emu10k1_ptr_read(emu, pc, 0);
-}
-
-static int snd_emu10k1_gpr_poke(struct snd_emu10k1 *emu,
- struct snd_emu10k1_fx8010_code *icode)
-{
- int gpr;
- u32 val;
-
- for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
- if (!test_bit(gpr, icode->gpr_valid))
- continue;
- if (get_user(val, &icode->gpr_map[gpr]))
- return -EFAULT;
- snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val);
- }
- return 0;
-}
-
-static int snd_emu10k1_gpr_peek(struct snd_emu10k1 *emu,
- struct snd_emu10k1_fx8010_code *icode)
-{
- int gpr;
- u32 val;
-
- for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
- set_bit(gpr, icode->gpr_valid);
- val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
- if (put_user(val, &icode->gpr_map[gpr]))
- return -EFAULT;
- }
- return 0;
-}
-
-static int snd_emu10k1_tram_poke(struct snd_emu10k1 *emu,
- struct snd_emu10k1_fx8010_code *icode)
-{
- int tram;
- u32 addr, val;
-
- for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
- if (!test_bit(tram, icode->tram_valid))
- continue;
- if (get_user(val, &icode->tram_data_map[tram]) ||
- get_user(addr, &icode->tram_addr_map[tram]))
- return -EFAULT;
- snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val);
- if (!emu->audigy) {
- snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr);
- } else {
- snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr << 12);
- snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, addr >> 20);
- }
- }
- return 0;
-}
-
-static int snd_emu10k1_tram_peek(struct snd_emu10k1 *emu,
- struct snd_emu10k1_fx8010_code *icode)
-{
- int tram;
- u32 val, addr;
-
- memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
- for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
- set_bit(tram, icode->tram_valid);
- val = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
- if (!emu->audigy) {
- addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
- } else {
- addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
- addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
- }
- if (put_user(val, &icode->tram_data_map[tram]) ||
- put_user(addr, &icode->tram_addr_map[tram]))
- return -EFAULT;
- }
- return 0;
-}
-
-static int snd_emu10k1_code_poke(struct snd_emu10k1 *emu,
- struct snd_emu10k1_fx8010_code *icode)
-{
- u32 pc, lo, hi;
-
- for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
- if (!test_bit(pc / 2, icode->code_valid))
- continue;
- if (get_user(lo, &icode->code[pc + 0]) ||
- get_user(hi, &icode->code[pc + 1]))
- return -EFAULT;
- snd_emu10k1_efx_write(emu, pc + 0, lo);
- snd_emu10k1_efx_write(emu, pc + 1, hi);
- }
- return 0;
-}
-
-static int snd_emu10k1_code_peek(struct snd_emu10k1 *emu,
- struct snd_emu10k1_fx8010_code *icode)
-{
- u32 pc;
-
- memset(icode->code_valid, 0, sizeof(icode->code_valid));
- for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
- set_bit(pc / 2, icode->code_valid);
- if (put_user(snd_emu10k1_efx_read(emu, pc + 0), &icode->code[pc + 0]))
- return -EFAULT;
- if (put_user(snd_emu10k1_efx_read(emu, pc + 1), &icode->code[pc + 1]))
- return -EFAULT;
- }
- return 0;
-}
-
-static struct snd_emu10k1_fx8010_ctl *
-snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu, struct snd_ctl_elem_id *id)
-{
- struct snd_emu10k1_fx8010_ctl *ctl;
- struct snd_kcontrol *kcontrol;
-
- list_for_each_entry(ctl, &emu->fx8010.gpr_ctl, list) {
- kcontrol = ctl->kcontrol;
- if (kcontrol->id.iface == id->iface &&
- !strcmp(kcontrol->id.name, id->name) &&
- kcontrol->id.index == id->index)
- return ctl;
- }
- return NULL;
-}
-
-#define MAX_TLV_SIZE 256
-
-static unsigned int *copy_tlv(const unsigned int __user *_tlv)
-{
- unsigned int data[2];
- unsigned int *tlv;
-
- if (!_tlv)
- return NULL;
- if (copy_from_user(data, _tlv, sizeof(data)))
- return NULL;
- if (data[1] >= MAX_TLV_SIZE)
- return NULL;
- tlv = kmalloc(data[1] + sizeof(data), GFP_KERNEL);
- if (!tlv)
- return NULL;
- memcpy(tlv, data, sizeof(data));
- if (copy_from_user(tlv + 2, _tlv + 2, data[1])) {
- kfree(tlv);
- return NULL;
- }
- return tlv;
-}
-
-static int copy_gctl(struct snd_emu10k1 *emu,
- struct snd_emu10k1_fx8010_control_gpr *gctl,
- struct snd_emu10k1_fx8010_control_gpr __user *_gctl,
- int idx)
-{
- struct snd_emu10k1_fx8010_control_old_gpr __user *octl;
-
- if (emu->support_tlv)
- return copy_from_user(gctl, &_gctl[idx], sizeof(*gctl));
- octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl;
- if (copy_from_user(gctl, &octl[idx], sizeof(*octl)))
- return -EFAULT;
- gctl->tlv = NULL;
- return 0;
-}
-
-static int copy_gctl_to_user(struct snd_emu10k1 *emu,
- struct snd_emu10k1_fx8010_control_gpr __user *_gctl,
- struct snd_emu10k1_fx8010_control_gpr *gctl,
- int idx)
-{
- struct snd_emu10k1_fx8010_control_old_gpr __user *octl;
-
- if (emu->support_tlv)
- return copy_to_user(&_gctl[idx], gctl, sizeof(*gctl));
-
- octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl;
- return copy_to_user(&octl[idx], gctl, sizeof(*octl));
-}
-
-static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
- struct snd_emu10k1_fx8010_code *icode)
-{
- unsigned int i;
- struct snd_ctl_elem_id __user *_id;
- struct snd_ctl_elem_id id;
- struct snd_emu10k1_fx8010_control_gpr *gctl;
- int err;
-
- for (i = 0, _id = icode->gpr_del_controls;
- i < icode->gpr_del_control_count; i++, _id++) {
- if (copy_from_user(&id, _id, sizeof(id)))
- return -EFAULT;
- if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
- return -ENOENT;
- }
- gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
- if (! gctl)
- return -ENOMEM;
- err = 0;
- for (i = 0; i < icode->gpr_add_control_count; i++) {
- if (copy_gctl(emu, gctl, icode->gpr_add_controls, i)) {
- err = -EFAULT;
- goto __error;
- }
- if (snd_emu10k1_look_for_ctl(emu, &gctl->id))
- continue;
- down_read(&emu->card->controls_rwsem);
- if (snd_ctl_find_id(emu->card, &gctl->id) != NULL) {
- up_read(&emu->card->controls_rwsem);
- err = -EEXIST;
- goto __error;
- }
- up_read(&emu->card->controls_rwsem);
- if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
- gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
- err = -EINVAL;
- goto __error;
- }
- }
- for (i = 0; i < icode->gpr_list_control_count; i++) {
- /* FIXME: we need to check the WRITE access */
- if (copy_gctl(emu, gctl, icode->gpr_list_controls, i)) {
- err = -EFAULT;
- goto __error;
- }
- }
- __error:
- kfree(gctl);
- return err;
-}
-
-static void snd_emu10k1_ctl_private_free(struct snd_kcontrol *kctl)
-{
- struct snd_emu10k1_fx8010_ctl *ctl;
-
- ctl = (struct snd_emu10k1_fx8010_ctl *) kctl->private_value;
- kctl->private_value = 0;
- list_del(&ctl->list);
- kfree(ctl);
- if (kctl->tlv.p)
- kfree(kctl->tlv.p);
-}
-
-static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
- struct snd_emu10k1_fx8010_code *icode)
-{
- unsigned int i, j;
- struct snd_emu10k1_fx8010_control_gpr *gctl;
- struct snd_emu10k1_fx8010_ctl *ctl, *nctl;
- struct snd_kcontrol_new knew;
- struct snd_kcontrol *kctl;
- struct snd_ctl_elem_value *val;
- int err = 0;
-
- val = kmalloc(sizeof(*val), GFP_KERNEL);
- gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
- nctl = kmalloc(sizeof(*nctl), GFP_KERNEL);
- if (!val || !gctl || !nctl) {
- err = -ENOMEM;
- goto __error;
- }
-
- for (i = 0; i < icode->gpr_add_control_count; i++) {
- if (copy_gctl(emu, gctl, icode->gpr_add_controls, i)) {
- err = -EFAULT;
- goto __error;
- }
- if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
- gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
- err = -EINVAL;
- goto __error;
- }
- if (! gctl->id.name[0]) {
- err = -EINVAL;
- goto __error;
- }
- ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id);
- memset(&knew, 0, sizeof(knew));
- knew.iface = gctl->id.iface;
- knew.name = gctl->id.name;
- knew.index = gctl->id.index;
- knew.device = gctl->id.device;
- knew.subdevice = gctl->id.subdevice;
- knew.info = snd_emu10k1_gpr_ctl_info;
- knew.tlv.p = copy_tlv(gctl->tlv);
- if (knew.tlv.p)
- knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ;
- knew.get = snd_emu10k1_gpr_ctl_get;
- knew.put = snd_emu10k1_gpr_ctl_put;
- memset(nctl, 0, sizeof(*nctl));
- nctl->vcount = gctl->vcount;
- nctl->count = gctl->count;
- for (j = 0; j < 32; j++) {
- nctl->gpr[j] = gctl->gpr[j];
- nctl->value[j] = ~gctl->value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
- val->value.integer.value[j] = gctl->value[j];
- }
- nctl->min = gctl->min;
- nctl->max = gctl->max;
- nctl->translation = gctl->translation;
- if (ctl == NULL) {
- ctl = kmalloc(sizeof(*ctl), GFP_KERNEL);
- if (ctl == NULL) {
- err = -ENOMEM;
- kfree(knew.tlv.p);
- goto __error;
- }
- knew.private_value = (unsigned long)ctl;
- *ctl = *nctl;
- if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) {
- kfree(ctl);
- kfree(knew.tlv.p);
- goto __error;
- }
- kctl->private_free = snd_emu10k1_ctl_private_free;
- ctl->kcontrol = kctl;
- list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
- } else {
- /* overwrite */
- nctl->list = ctl->list;
- nctl->kcontrol = ctl->kcontrol;
- *ctl = *nctl;
- snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
- }
- snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
- }
- __error:
- kfree(nctl);
- kfree(gctl);
- kfree(val);
- return err;
-}
-
-static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu,
- struct snd_emu10k1_fx8010_code *icode)
-{
- unsigned int i;
- struct snd_ctl_elem_id id;
- struct snd_ctl_elem_id __user *_id;
- struct snd_emu10k1_fx8010_ctl *ctl;
- struct snd_card *card = emu->card;
-
- for (i = 0, _id = icode->gpr_del_controls;
- i < icode->gpr_del_control_count; i++, _id++) {
- if (copy_from_user(&id, _id, sizeof(id)))
- return -EFAULT;
- down_write(&card->controls_rwsem);
- ctl = snd_emu10k1_look_for_ctl(emu, &id);
- if (ctl)
- snd_ctl_remove(card, ctl->kcontrol);
- up_write(&card->controls_rwsem);
- }
- return 0;
-}
-
-static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu,
- struct snd_emu10k1_fx8010_code *icode)
-{
- unsigned int i = 0, j;
- unsigned int total = 0;
- struct snd_emu10k1_fx8010_control_gpr *gctl;
- struct snd_emu10k1_fx8010_ctl *ctl;
- struct snd_ctl_elem_id *id;
-
- gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
- if (! gctl)
- return -ENOMEM;
-
- list_for_each_entry(ctl, &emu->fx8010.gpr_ctl, list) {
- total++;
- if (icode->gpr_list_controls &&
- i < icode->gpr_list_control_count) {
- memset(gctl, 0, sizeof(*gctl));
- id = &ctl->kcontrol->id;
- gctl->id.iface = id->iface;
- strlcpy(gctl->id.name, id->name, sizeof(gctl->id.name));
- gctl->id.index = id->index;
- gctl->id.device = id->device;
- gctl->id.subdevice = id->subdevice;
- gctl->vcount = ctl->vcount;
- gctl->count = ctl->count;
- for (j = 0; j < 32; j++) {
- gctl->gpr[j] = ctl->gpr[j];
- gctl->value[j] = ctl->value[j];
- }
- gctl->min = ctl->min;
- gctl->max = ctl->max;
- gctl->translation = ctl->translation;
- if (copy_gctl_to_user(emu, icode->gpr_list_controls,
- gctl, i)) {
- kfree(gctl);
- return -EFAULT;
- }
- i++;
- }
- }
- icode->gpr_list_control_total = total;
- kfree(gctl);
- return 0;
-}
-
-static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu,
- struct snd_emu10k1_fx8010_code *icode)
-{
- int err = 0;
-
- mutex_lock(&emu->fx8010.lock);
- if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0)
- goto __error;
- strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
- /* stop FX processor - this may be dangerous, but it's better to miss
- some samples than generate wrong ones - [jk] */
- if (emu->audigy)
- snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
- else
- snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
- /* ok, do the main job */
- if ((err = snd_emu10k1_del_controls(emu, icode)) < 0 ||
- (err = snd_emu10k1_gpr_poke(emu, icode)) < 0 ||
- (err = snd_emu10k1_tram_poke(emu, icode)) < 0 ||
- (err = snd_emu10k1_code_poke(emu, icode)) < 0 ||
- (err = snd_emu10k1_add_controls(emu, icode)) < 0)
- goto __error;
- /* start FX processor when the DSP code is updated */
- if (emu->audigy)
- snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
- else
- snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
- __error:
- mutex_unlock(&emu->fx8010.lock);
- return err;
-}
-
-static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu,
- struct snd_emu10k1_fx8010_code *icode)
-{
- int err;
-
- mutex_lock(&emu->fx8010.lock);
- strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
- /* ok, do the main job */
- err = snd_emu10k1_gpr_peek(emu, icode);
- if (err >= 0)
- err = snd_emu10k1_tram_peek(emu, icode);
- if (err >= 0)
- err = snd_emu10k1_code_peek(emu, icode);
- if (err >= 0)
- err = snd_emu10k1_list_controls(emu, icode);
- mutex_unlock(&emu->fx8010.lock);
- return err;
-}
-
-static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu,
- struct snd_emu10k1_fx8010_pcm_rec *ipcm)
-{
- unsigned int i;
- int err = 0;
- struct snd_emu10k1_fx8010_pcm *pcm;
-
- if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
- return -EINVAL;
- if (ipcm->channels > 32)
- return -EINVAL;
- pcm = &emu->fx8010.pcm[ipcm->substream];
- mutex_lock(&emu->fx8010.lock);
- spin_lock_irq(&emu->reg_lock);
- if (pcm->opened) {
- err = -EBUSY;
- goto __error;
- }
- if (ipcm->channels == 0) { /* remove */
- pcm->valid = 0;
- } else {
- /* FIXME: we need to add universal code to the PCM transfer routine */
- if (ipcm->channels != 2) {
- err = -EINVAL;
- goto __error;
- }
- pcm->valid = 1;
- pcm->opened = 0;
- pcm->channels = ipcm->channels;
- pcm->tram_start = ipcm->tram_start;
- pcm->buffer_size = ipcm->buffer_size;
- pcm->gpr_size = ipcm->gpr_size;
- pcm->gpr_count = ipcm->gpr_count;
- pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
- pcm->gpr_ptr = ipcm->gpr_ptr;
- pcm->gpr_trigger = ipcm->gpr_trigger;
- pcm->gpr_running = ipcm->gpr_running;
- for (i = 0; i < pcm->channels; i++)
- pcm->etram[i] = ipcm->etram[i];
- }
- __error:
- spin_unlock_irq(&emu->reg_lock);
- mutex_unlock(&emu->fx8010.lock);
- return err;
-}
-
-static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu,
- struct snd_emu10k1_fx8010_pcm_rec *ipcm)
-{
- unsigned int i;
- int err = 0;
- struct snd_emu10k1_fx8010_pcm *pcm;
-
- if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
- return -EINVAL;
- pcm = &emu->fx8010.pcm[ipcm->substream];
- mutex_lock(&emu->fx8010.lock);
- spin_lock_irq(&emu->reg_lock);
- ipcm->channels = pcm->channels;
- ipcm->tram_start = pcm->tram_start;
- ipcm->buffer_size = pcm->buffer_size;
- ipcm->gpr_size = pcm->gpr_size;
- ipcm->gpr_ptr = pcm->gpr_ptr;
- ipcm->gpr_count = pcm->gpr_count;
- ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
- ipcm->gpr_trigger = pcm->gpr_trigger;
- ipcm->gpr_running = pcm->gpr_running;
- for (i = 0; i < pcm->channels; i++)
- ipcm->etram[i] = pcm->etram[i];
- ipcm->res1 = ipcm->res2 = 0;
- ipcm->pad = 0;
- spin_unlock_irq(&emu->reg_lock);
- mutex_unlock(&emu->fx8010.lock);
- return err;
-}
-
-#define SND_EMU10K1_GPR_CONTROLS 44
-#define SND_EMU10K1_INPUTS 12
-#define SND_EMU10K1_PLAYBACK_CHANNELS 8
-#define SND_EMU10K1_CAPTURE_CHANNELS 4
-
-static void __devinit
-snd_emu10k1_init_mono_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
- const char *name, int gpr, int defval)
-{
- ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(ctl->id.name, name);
- ctl->vcount = ctl->count = 1;
- ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
- if (high_res_gpr_volume) {
- ctl->min = 0;
- ctl->max = 0x7fffffff;
- ctl->tlv = snd_emu10k1_db_linear;
- ctl->translation = EMU10K1_GPR_TRANSLATION_NONE;
- } else {
- ctl->min = 0;
- ctl->max = 100;
- ctl->tlv = snd_emu10k1_db_scale1;
- ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
- }
-}
-
-static void __devinit
-snd_emu10k1_init_stereo_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
- const char *name, int gpr, int defval)
-{
- ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(ctl->id.name, name);
- ctl->vcount = ctl->count = 2;
- ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
- ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
- if (high_res_gpr_volume) {
- ctl->min = 0;
- ctl->max = 0x7fffffff;
- ctl->tlv = snd_emu10k1_db_linear;
- ctl->translation = EMU10K1_GPR_TRANSLATION_NONE;
- } else {
- ctl->min = 0;
- ctl->max = 100;
- ctl->tlv = snd_emu10k1_db_scale1;
- ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
- }
-}
-
-static void __devinit
-snd_emu10k1_init_mono_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
- const char *name, int gpr, int defval)
-{
- ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(ctl->id.name, name);
- ctl->vcount = ctl->count = 1;
- ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
- ctl->min = 0;
- ctl->max = 1;
- ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
-}
-
-static void __devinit
-snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
- const char *name, int gpr, int defval)
-{
- ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(ctl->id.name, name);
- ctl->vcount = ctl->count = 2;
- ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
- ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
- ctl->min = 0;
- ctl->max = 1;
- ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
-}
-
-/*
- * Used for emu1010 - conversion from 32-bit capture inputs from HANA
- * to 2 x 16-bit registers in audigy - their values are read via DMA.
- * Conversion is performed by Audigy DSP instructions of FX8010.
- */
-static int snd_emu10k1_audigy_dsp_convert_32_to_2x16(
- struct snd_emu10k1_fx8010_code *icode,
- u32 *ptr, int tmp, int bit_shifter16,
- int reg_in, int reg_out)
-{
- A_OP(icode, ptr, iACC3, A_GPR(tmp + 1), reg_in, A_C_00000000, A_C_00000000);
- A_OP(icode, ptr, iANDXOR, A_GPR(tmp), A_GPR(tmp + 1), A_GPR(bit_shifter16 - 1), A_C_00000000);
- A_OP(icode, ptr, iTSTNEG, A_GPR(tmp + 2), A_GPR(tmp), A_C_80000000, A_GPR(bit_shifter16 - 2));
- A_OP(icode, ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_C_80000000, A_C_00000000);
- A_OP(icode, ptr, iANDXOR, A_GPR(tmp), A_GPR(tmp), A_GPR(bit_shifter16 - 3), A_C_00000000);
- A_OP(icode, ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A_GPR(tmp), A_C_00010000);
- A_OP(icode, ptr, iANDXOR, reg_out, A_GPR(tmp), A_C_ffffffff, A_GPR(tmp + 2));
- A_OP(icode, ptr, iACC3, reg_out + 1, A_GPR(tmp + 1), A_C_00000000, A_C_00000000);
- return 1;
-}
-
-/*
- * initial DSP configuration for Audigy
- */
-
-static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
-{
- int err, i, z, gpr, nctl;
- int bit_shifter16;
- const int playback = 10;
- const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
- const int stereo_mix = capture + 2;
- const int tmp = 0x88;
- u32 ptr;
- struct snd_emu10k1_fx8010_code *icode = NULL;
- struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
- u32 *gpr_map;
- mm_segment_t seg;
-
- if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL ||
- (icode->gpr_map = (u_int32_t __user *)
- kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t),
- GFP_KERNEL)) == NULL ||
- (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
- sizeof(*controls), GFP_KERNEL)) == NULL) {
- err = -ENOMEM;
- goto __err;
- }
- gpr_map = (u32 __force *)icode->gpr_map;
-
- icode->tram_data_map = icode->gpr_map + 512;
- icode->tram_addr_map = icode->tram_data_map + 256;
- icode->code = icode->tram_addr_map + 256;
-
- /* clear free GPRs */
- for (i = 0; i < 512; i++)
- set_bit(i, icode->gpr_valid);
-
- /* clear TRAM data & address lines */
- for (i = 0; i < 256; i++)
- set_bit(i, icode->tram_valid);
-
- strcpy(icode->name, "Audigy DSP code for ALSA");
- ptr = 0;
- nctl = 0;
- gpr = stereo_mix + 10;
- gpr_map[gpr++] = 0x00007fff;
- gpr_map[gpr++] = 0x00008000;
- gpr_map[gpr++] = 0x0000ffff;
- bit_shifter16 = gpr;
-
- /* stop FX processor */
- snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
-
-#if 1
- /* PCM front Playback Volume (independent from stereo mix)
- * playback = 0 + ( gpr * FXBUS_PCM_LEFT_FRONT >> 31)
- * where gpr contains attenuation from corresponding mixer control
- * (snd_emu10k1_init_stereo_control)
- */
- A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
- snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
- gpr += 2;
-
- /* PCM Surround Playback (independent from stereo mix) */
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
- snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
- gpr += 2;
-
- /* PCM Side Playback (independent from stereo mix) */
- if (emu->card_capabilities->spk71) {
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
- snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
- gpr += 2;
- }
-
- /* PCM Center Playback (independent from stereo mix) */
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
- snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
- gpr++;
-
- /* PCM LFE Playback (independent from stereo mix) */
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
- snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
- gpr++;
-
- /*
- * Stereo Mix
- */
- /* Wave (PCM) Playback Volume (will be renamed later) */
- A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
- A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
- snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
- gpr += 2;
-
- /* Synth Playback */
- A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
- A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
- snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Playback Volume", gpr, 100);
- gpr += 2;
-
- /* Wave (PCM) Capture */
- A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
- A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
- snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
- gpr += 2;
-
- /* Synth Capture */
- A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
- A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
- snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0);
- gpr += 2;
-
- /*
- * inputs
- */
-#define A_ADD_VOLUME_IN(var,vol,input) \
-A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
-
- /* emu1212 DSP 0 and DSP 1 Capture */
- if (emu->card_capabilities->emu_model) {
- if (emu->card_capabilities->ca0108_chip) {
- /* Note:JCD:No longer bit shift lower 16bits to upper 16bits of 32bit value. */
- A_OP(icode, &ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A3_EMU32IN(0x0), A_C_00000001);
- A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_GPR(tmp));
- A_OP(icode, &ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A3_EMU32IN(0x1), A_C_00000001);
- A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr), A_GPR(tmp));
- } else {
- A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_P16VIN(0x0));
- A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_P16VIN(0x1));
- }
- snd_emu10k1_init_stereo_control(&controls[nctl++], "EMU Capture Volume", gpr, 0);
- gpr += 2;
- }
- /* AC'97 Playback Volume - used only for mic (renamed later) */
- A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
- A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
- snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
- gpr += 2;
- /* AC'97 Capture Volume - used only for mic */
- A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
- A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
- snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
- gpr += 2;
-
- /* mic capture buffer */
- A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
-
- /* Audigy CD Playback Volume */
- A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
- A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
- snd_emu10k1_init_stereo_control(&controls[nctl++],
- emu->card_capabilities->ac97_chip ? "Audigy CD Playback Volume" : "CD Playback Volume",
- gpr, 0);
- gpr += 2;
- /* Audigy CD Capture Volume */
- A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
- A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
- snd_emu10k1_init_stereo_control(&controls[nctl++],
- emu->card_capabilities->ac97_chip ? "Audigy CD Capture Volume" : "CD Capture Volume",
- gpr, 0);
- gpr += 2;
-
- /* Optical SPDIF Playback Volume */
- A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
- A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
- snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",PLAYBACK,VOLUME), gpr, 0);
- gpr += 2;
- /* Optical SPDIF Capture Volume */
- A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
- A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
- snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",CAPTURE,VOLUME), gpr, 0);
- gpr += 2;
-
- /* Line2 Playback Volume */
- A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
- A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
- snd_emu10k1_init_stereo_control(&controls[nctl++],
- emu->card_capabilities->ac97_chip ? "Line2 Playback Volume" : "Line Playback Volume",
- gpr, 0);
- gpr += 2;
- /* Line2 Capture Volume */
- A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
- A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
- snd_emu10k1_init_stereo_control(&controls[nctl++],
- emu->card_capabilities->ac97_chip ? "Line2 Capture Volume" : "Line Capture Volume",
- gpr, 0);
- gpr += 2;
-
- /* Philips ADC Playback Volume */
- A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
- A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
- snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
- gpr += 2;
- /* Philips ADC Capture Volume */
- A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
- A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
- snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
- gpr += 2;
-
- /* Aux2 Playback Volume */
- A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
- A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
- snd_emu10k1_init_stereo_control(&controls[nctl++],
- emu->card_capabilities->ac97_chip ? "Aux2 Playback Volume" : "Aux Playback Volume",
- gpr, 0);
- gpr += 2;
- /* Aux2 Capture Volume */
- A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
- A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
- snd_emu10k1_init_stereo_control(&controls[nctl++],
- emu->card_capabilities->ac97_chip ? "Aux2 Capture Volume" : "Aux Capture Volume",
- gpr, 0);
- gpr += 2;
-
- /* Stereo Mix Front Playback Volume */
- A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
- snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
- gpr += 2;
-
- /* Stereo Mix Surround Playback */
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
- snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
- gpr += 2;
-
- /* Stereo Mix Center Playback */
- /* Center = sub = Left/2 + Right/2 */
- A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
- snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
- gpr++;
-
- /* Stereo Mix LFE Playback */
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
- snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
- gpr++;
-
- if (emu->card_capabilities->spk71) {
- /* Stereo Mix Side Playback */
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
- snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0);
- gpr += 2;
- }
-
- /*
- * outputs
- */
-#define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
-#define A_PUT_STEREO_OUTPUT(out1,out2,src) \
- {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
-
-#define _A_SWITCH(icode, ptr, dst, src, sw) \
- A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
-#define A_SWITCH(icode, ptr, dst, src, sw) \
- _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
-#define _A_SWITCH_NEG(icode, ptr, dst, src) \
- A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
-#define A_SWITCH_NEG(icode, ptr, dst, src) \
- _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
-
-
- /*
- * Process tone control
- */
- A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
- A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
- A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), A_GPR(playback + 2), A_C_00000000, A_C_00000000); /* rear left */
- A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), A_GPR(playback + 3), A_C_00000000, A_C_00000000); /* rear right */
- A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
- A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
- if (emu->card_capabilities->spk71) {
- A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 6), A_GPR(playback + 6), A_C_00000000, A_C_00000000); /* side left */
- A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 7), A_GPR(playback + 7), A_C_00000000, A_C_00000000); /* side right */
- }
-
-
- ctl = &controls[nctl + 0];
- ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(ctl->id.name, "Tone Control - Bass");
- ctl->vcount = 2;
- ctl->count = 10;
- ctl->min = 0;
- ctl->max = 40;
- ctl->value[0] = ctl->value[1] = 20;
- ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
- ctl = &controls[nctl + 1];
- ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(ctl->id.name, "Tone Control - Treble");
- ctl->vcount = 2;
- ctl->count = 10;
- ctl->min = 0;
- ctl->max = 40;
- ctl->value[0] = ctl->value[1] = 20;
- ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
-
-#define BASS_GPR 0x8c
-#define TREBLE_GPR 0x96
-
- for (z = 0; z < 5; z++) {
- int j;
- for (j = 0; j < 2; j++) {
- controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
- controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
- }
- }
- for (z = 0; z < 4; z++) { /* front/rear/center-lfe/side */
- int j, k, l, d;
- for (j = 0; j < 2; j++) { /* left/right */
- k = 0xb0 + (z * 8) + (j * 4);
- l = 0xe0 + (z * 8) + (j * 4);
- d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
-
- A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
- A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
- A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
- A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
- A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
- A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
-
- A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
- A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
- A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
- A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
- A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
- A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
-
- A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
-
- if (z == 2) /* center */
- break;
- }
- }
- nctl += 2;
-
-#undef BASS_GPR
-#undef TREBLE_GPR
-
- for (z = 0; z < 8; z++) {
- A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
- A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
- A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
- A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
- }
- snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
- gpr += 2;
-
- /* Master volume (will be renamed later) */
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+0+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+0+SND_EMU10K1_PLAYBACK_CHANNELS));
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS));
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+2+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+2+SND_EMU10K1_PLAYBACK_CHANNELS));
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+3+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+3+SND_EMU10K1_PLAYBACK_CHANNELS));
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+4+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+4+SND_EMU10K1_PLAYBACK_CHANNELS));
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+5+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+5+SND_EMU10K1_PLAYBACK_CHANNELS));
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+6+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+6+SND_EMU10K1_PLAYBACK_CHANNELS));
- A_OP(icode, &ptr, iMAC0, A_GPR(playback+7+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+7+SND_EMU10K1_PLAYBACK_CHANNELS));
- snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
- gpr += 2;
-
- /* analog speakers */
- A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
- A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
- A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
- A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
- if (emu->card_capabilities->spk71)
- A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
-
- /* headphone */
- A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
-
- /* digital outputs */
- /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
- if (emu->card_capabilities->emu_model) {
- /* EMU1010 Outputs from PCM Front, Rear, Center, LFE, Side */
- snd_printk(KERN_INFO "EMU outputs on\n");
- for (z = 0; z < 8; z++) {
- if (emu->card_capabilities->ca0108_chip) {
- A_OP(icode, &ptr, iACC3, A3_EMU32OUT(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000);
- } else {
- A_OP(icode, &ptr, iACC3, A_EMU32OUTL(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000);
- }
- }
- }
-
- /* IEC958 Optical Raw Playback Switch */
- gpr_map[gpr++] = 0;
- gpr_map[gpr++] = 0x1008;
- gpr_map[gpr++] = 0xffff0000;
- for (z = 0; z < 2; z++) {
- A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
- A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
- A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
- A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
- A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
- A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
- A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
- if ((z==1) && (emu->card_capabilities->spdif_bug)) {
- /* Due to a SPDIF output bug on some Audigy cards, this code delays the Right channel by 1 sample */
- snd_printk(KERN_INFO "Installing spdif_bug patch: %s\n", emu->card_capabilities->name);
- A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
- } else {
- A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
- }
- }
- snd_emu10k1_init_stereo_onoff_control(controls + nctl++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
- gpr += 2;
-
- A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
- A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
- A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
-
- /* ADC buffer */
-#ifdef EMU10K1_CAPTURE_DIGITAL_OUT
- A_PUT_STEREO_OUTPUT(A_EXTOUT_ADC_CAP_L, A_EXTOUT_ADC_CAP_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
-#else
- A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
- A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
-#endif
-
- if (emu->card_capabilities->emu_model) {
- if (emu->card_capabilities->ca0108_chip) {
- snd_printk(KERN_INFO "EMU2 inputs on\n");
- for (z = 0; z < 0x10; z++) {
- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp,
- bit_shifter16,
- A3_EMU32IN(z),
- A_FXBUS2(z*2) );
- }
- } else {
- snd_printk(KERN_INFO "EMU inputs on\n");
- /* Capture 16 (originally 8) channels of S32_LE sound */
-
- /*
- printk(KERN_DEBUG "emufx.c: gpr=0x%x, tmp=0x%x\n",
- gpr, tmp);
- */
- /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */
- /* A_P16VIN(0) is delayed by one sample,
- * so all other A_P16VIN channels will need to also be delayed
- */
- /* Left ADC in. 1 of 2 */
- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) );
- /* Right ADC in 1 of 2 */
- gpr_map[gpr++] = 0x00000000;
- /* Delaying by one sample: instead of copying the input
- * value A_P16VIN to output A_FXBUS2 as in the first channel,
- * we use an auxiliary register, delaying the value by one
- * sample
- */
- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) );
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(4) );
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x2), A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(6) );
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x3), A_C_00000000, A_C_00000000);
- /* For 96kHz mode */
- /* Left ADC in. 2 of 2 */
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0x8) );
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x4), A_C_00000000, A_C_00000000);
- /* Right ADC in 2 of 2 */
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xa) );
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x5), A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xc) );
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x6), A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) );
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000);
- /* Pavel Hofman - we still have voices, A_FXBUS2s, and
- * A_P16VINs available -
- * let's add 8 more capture channels - total of 16
- */
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
- bit_shifter16,
- A_GPR(gpr - 1),
- A_FXBUS2(0x10));
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x8),
- A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
- bit_shifter16,
- A_GPR(gpr - 1),
- A_FXBUS2(0x12));
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x9),
- A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
- bit_shifter16,
- A_GPR(gpr - 1),
- A_FXBUS2(0x14));
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xa),
- A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
- bit_shifter16,
- A_GPR(gpr - 1),
- A_FXBUS2(0x16));
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xb),
- A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
- bit_shifter16,
- A_GPR(gpr - 1),
- A_FXBUS2(0x18));
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xc),
- A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
- bit_shifter16,
- A_GPR(gpr - 1),
- A_FXBUS2(0x1a));
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xd),
- A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
- bit_shifter16,
- A_GPR(gpr - 1),
- A_FXBUS2(0x1c));
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xe),
- A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
- bit_shifter16,
- A_GPR(gpr - 1),
- A_FXBUS2(0x1e));
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xf),
- A_C_00000000, A_C_00000000);
- }
-
-#if 0
- for (z = 4; z < 8; z++) {
- A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000);
- }
- for (z = 0xc; z < 0x10; z++) {
- A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000);
- }
-#endif
- } else {
- /* EFX capture - capture the 16 EXTINs */
- /* Capture 16 channels of S16_LE sound */
- for (z = 0; z < 16; z++) {
- A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z));
- }
- }
-
-#endif /* JCD test */
- /*
- * ok, set up done..
- */
-
- if (gpr > tmp) {
- snd_BUG();
- err = -EIO;
- goto __err;
- }
- /* clear remaining instruction memory */
- while (ptr < 0x400)
- A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
-
- seg = snd_enter_user();
- icode->gpr_add_control_count = nctl;
- icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
- emu->support_tlv = 1; /* support TLV */
- err = snd_emu10k1_icode_poke(emu, icode);
- emu->support_tlv = 0; /* clear again */
- snd_leave_user(seg);
-
- __err:
- kfree(controls);
- if (icode != NULL) {
- kfree((void __force *)icode->gpr_map);
- kfree(icode);
- }
- return err;
-}
-
-
-/*
- * initial DSP configuration for Emu10k1
- */
-
-/* when volume = max, then copy only to avoid volume modification */
-/* with iMAC0 (negative values) */
-static void __devinit _volume(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
-{
- OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
- OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
- OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
- OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
-}
-static void __devinit _volume_add(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
-{
- OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
- OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
- OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
- OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
- OP(icode, ptr, iMAC0, dst, dst, src, vol);
-}
-static void __devinit _volume_out(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
-{
- OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
- OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
- OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
- OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
- OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
-}
-
-#define VOLUME(icode, ptr, dst, src, vol) \
- _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
-#define VOLUME_IN(icode, ptr, dst, src, vol) \
- _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
-#define VOLUME_ADD(icode, ptr, dst, src, vol) \
- _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
-#define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
- _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
-#define VOLUME_OUT(icode, ptr, dst, src, vol) \
- _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
-#define _SWITCH(icode, ptr, dst, src, sw) \
- OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
-#define SWITCH(icode, ptr, dst, src, sw) \
- _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
-#define SWITCH_IN(icode, ptr, dst, src, sw) \
- _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
-#define _SWITCH_NEG(icode, ptr, dst, src) \
- OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
-#define SWITCH_NEG(icode, ptr, dst, src) \
- _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
-
-
-static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
-{
- int err, i, z, gpr, tmp, playback, capture;
- u32 ptr;
- struct snd_emu10k1_fx8010_code *icode;
- struct snd_emu10k1_fx8010_pcm_rec *ipcm = NULL;
- struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
- u32 *gpr_map;
- mm_segment_t seg;
-
- if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL)
- return -ENOMEM;
- if ((icode->gpr_map = (u_int32_t __user *)
- kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t),
- GFP_KERNEL)) == NULL ||
- (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
- sizeof(struct snd_emu10k1_fx8010_control_gpr),
- GFP_KERNEL)) == NULL ||
- (ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL)) == NULL) {
- err = -ENOMEM;
- goto __err;
- }
- gpr_map = (u32 __force *)icode->gpr_map;
-
- icode->tram_data_map = icode->gpr_map + 256;
- icode->tram_addr_map = icode->tram_data_map + 160;
- icode->code = icode->tram_addr_map + 160;
-
- /* clear free GPRs */
- for (i = 0; i < 256; i++)
- set_bit(i, icode->gpr_valid);
-
- /* clear TRAM data & address lines */
- for (i = 0; i < 160; i++)
- set_bit(i, icode->tram_valid);
-
- strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
- ptr = 0; i = 0;
- /* we have 12 inputs */
- playback = SND_EMU10K1_INPUTS;
- /* we have 6 playback channels and tone control doubles */
- capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
- gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
- tmp = 0x88; /* we need 4 temporary GPR */
- /* from 0x8c to 0xff is the area for tone control */
-
- /* stop FX processor */
- snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
-
- /*
- * Process FX Buses
- */
- OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
- OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
- OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
- OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
- OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
- OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
- OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
- OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
- OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
- OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
- OP(icode, &ptr, iMACINT0, GPR(10), C_00000000, FXBUS(FXBUS_PCM_LEFT_FRONT), C_00000004);
- OP(icode, &ptr, iMACINT0, GPR(11), C_00000000, FXBUS(FXBUS_PCM_RIGHT_FRONT), C_00000004);
-
- /* Raw S/PDIF PCM */
- ipcm->substream = 0;
- ipcm->channels = 2;
- ipcm->tram_start = 0;
- ipcm->buffer_size = (64 * 1024) / 2;
- ipcm->gpr_size = gpr++;
- ipcm->gpr_ptr = gpr++;
- ipcm->gpr_count = gpr++;
- ipcm->gpr_tmpcount = gpr++;
- ipcm->gpr_trigger = gpr++;
- ipcm->gpr_running = gpr++;
- ipcm->etram[0] = 0;
- ipcm->etram[1] = 1;
-
- gpr_map[gpr + 0] = 0xfffff000;
- gpr_map[gpr + 1] = 0xffff0000;
- gpr_map[gpr + 2] = 0x70000000;
- gpr_map[gpr + 3] = 0x00000007;
- gpr_map[gpr + 4] = 0x001f << 11;
- gpr_map[gpr + 5] = 0x001c << 11;
- gpr_map[gpr + 6] = (0x22 - 0x01) - 1; /* skip at 01 to 22 */
- gpr_map[gpr + 7] = (0x22 - 0x06) - 1; /* skip at 06 to 22 */
- gpr_map[gpr + 8] = 0x2000000 + (2<<11);
- gpr_map[gpr + 9] = 0x4000000 + (2<<11);
- gpr_map[gpr + 10] = 1<<11;
- gpr_map[gpr + 11] = (0x24 - 0x0a) - 1; /* skip at 0a to 24 */
- gpr_map[gpr + 12] = 0;
-
- /* if the trigger flag is not set, skip */
- /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
- /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
- /* if the running flag is set, we're running */
- /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
- /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
- /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
- /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
- /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
- /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
- /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
-
- /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
- /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
- /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
- /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
-
- /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
- /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
- /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
- /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
- /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
-
- /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
- /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
- /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
- /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
- /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
-
- /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
- /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
- /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
- /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
- /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
-
- /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
- /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
- /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
- /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
- /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
-
- /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
- /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
-
- /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
- /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
-
- /* 24: */
- gpr += 13;
-
- /* Wave Playback Volume */
- for (z = 0; z < 2; z++)
- VOLUME(icode, &ptr, playback + z, z, gpr + z);
- snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
- gpr += 2;
-
- /* Wave Surround Playback Volume */
- for (z = 0; z < 2; z++)
- VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
- snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
- gpr += 2;
-
- /* Wave Center/LFE Playback Volume */
- OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
- OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
- VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
- snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
- VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
- snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
-
- /* Wave Capture Volume + Switch */
- for (z = 0; z < 2; z++) {
- SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
- VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
- }
- snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
- snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
- gpr += 4;
-
- /* Synth Playback Volume */
- for (z = 0; z < 2; z++)
- VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
- snd_emu10k1_init_stereo_control(controls + i++, "Synth Playback Volume", gpr, 100);
- gpr += 2;
-
- /* Synth Capture Volume + Switch */
- for (z = 0; z < 2; z++) {
- SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
- VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
- }
- snd_emu10k1_init_stereo_control(controls + i++, "Synth Capture Volume", gpr, 0);
- snd_emu10k1_init_stereo_onoff_control(controls + i++, "Synth Capture Switch", gpr + 2, 0);
- gpr += 4;
-
- /* Surround Digital Playback Volume (renamed later without Digital) */
- for (z = 0; z < 2; z++)
- VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
- snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
- gpr += 2;
-
- /* Surround Capture Volume + Switch */
- for (z = 0; z < 2; z++) {
- SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
- VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
- }
- snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
- snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
- gpr += 4;
-
- /* Center Playback Volume (renamed later without Digital) */
- VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
- snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
-
- /* LFE Playback Volume + Switch (renamed later without Digital) */
- VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
- snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
-
- /* Front Playback Volume */
- for (z = 0; z < 2; z++)
- VOLUME_ADD(icode, &ptr, playback + z, 10 + z, gpr + z);
- snd_emu10k1_init_stereo_control(controls + i++, "Front Playback Volume", gpr, 100);
- gpr += 2;
-
- /* Front Capture Volume + Switch */
- for (z = 0; z < 2; z++) {
- SWITCH(icode, &ptr, tmp + 0, 10 + z, gpr + 2);
- VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
- }
- snd_emu10k1_init_stereo_control(controls + i++, "Front Capture Volume", gpr, 0);
- snd_emu10k1_init_mono_onoff_control(controls + i++, "Front Capture Switch", gpr + 2, 0);
- gpr += 3;
-
- /*
- * Process inputs
- */
-
- if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
- /* AC'97 Playback Volume */
- VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
- VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
- snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
- /* AC'97 Capture Volume */
- VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
- VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
- snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
- }
-
- if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
- /* IEC958 TTL Playback Volume */
- for (z = 0; z < 2; z++)
- VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
- snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",PLAYBACK,VOLUME), gpr, 0);
- gpr += 2;
-
- /* IEC958 TTL Capture Volume + Switch */
- for (z = 0; z < 2; z++) {
- SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
- VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
- }
- snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,VOLUME), gpr, 0);
- snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,SWITCH), gpr + 2, 0);
- gpr += 4;
- }
-
- if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
- /* Zoom Video Playback Volume */
- for (z = 0; z < 2; z++)
- VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
- snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
- gpr += 2;
-
- /* Zoom Video Capture Volume + Switch */
- for (z = 0; z < 2; z++) {
- SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
- VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
- }
- snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
- snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
- gpr += 4;
- }
-
- if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
- /* IEC958 Optical Playback Volume */
- for (z = 0; z < 2; z++)
- VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
- snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",PLAYBACK,VOLUME), gpr, 0);
- gpr += 2;
-
- /* IEC958 Optical Capture Volume */
- for (z = 0; z < 2; z++) {
- SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
- VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
- }
- snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,VOLUME), gpr, 0);
- snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,SWITCH), gpr + 2, 0);
- gpr += 4;
- }
-
- if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
- /* Line LiveDrive Playback Volume */
- for (z = 0; z < 2; z++)
- VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
- snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
- gpr += 2;
-
- /* Line LiveDrive Capture Volume + Switch */
- for (z = 0; z < 2; z++) {
- SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
- VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
- }
- snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
- snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
- gpr += 4;
- }
-
- if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
- /* IEC958 Coax Playback Volume */
- for (z = 0; z < 2; z++)
- VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
- snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",PLAYBACK,VOLUME), gpr, 0);
- gpr += 2;
-
- /* IEC958 Coax Capture Volume + Switch */
- for (z = 0; z < 2; z++) {
- SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
- VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
- }
- snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,VOLUME), gpr, 0);
- snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,SWITCH), gpr + 2, 0);
- gpr += 4;
- }
-
- if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
- /* Line LiveDrive Playback Volume */
- for (z = 0; z < 2; z++)
- VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
- snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
- controls[i-1].id.index = 1;
- gpr += 2;
-
- /* Line LiveDrive Capture Volume */
- for (z = 0; z < 2; z++) {
- SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
- VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
- }
- snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
- controls[i-1].id.index = 1;
- snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
- controls[i-1].id.index = 1;
- gpr += 4;
- }
-
- /*
- * Process tone control
- */
- OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
- OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
- OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
- OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
- OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
- OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
-
- ctl = &controls[i + 0];
- ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(ctl->id.name, "Tone Control - Bass");
- ctl->vcount = 2;
- ctl->count = 10;
- ctl->min = 0;
- ctl->max = 40;
- ctl->value[0] = ctl->value[1] = 20;
- ctl->tlv = snd_emu10k1_bass_treble_db_scale;
- ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
- ctl = &controls[i + 1];
- ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(ctl->id.name, "Tone Control - Treble");
- ctl->vcount = 2;
- ctl->count = 10;
- ctl->min = 0;
- ctl->max = 40;
- ctl->value[0] = ctl->value[1] = 20;
- ctl->tlv = snd_emu10k1_bass_treble_db_scale;
- ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
-
-#define BASS_GPR 0x8c
-#define TREBLE_GPR 0x96
-
- for (z = 0; z < 5; z++) {
- int j;
- for (j = 0; j < 2; j++) {
- controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
- controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
- }
- }
- for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
- int j, k, l, d;
- for (j = 0; j < 2; j++) { /* left/right */
- k = 0xa0 + (z * 8) + (j * 4);
- l = 0xd0 + (z * 8) + (j * 4);
- d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
-
- OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
- OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
- OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
- OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
- OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
- OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
-
- OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
- OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
- OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
- OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
- OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
- OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
-
- OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
-
- if (z == 2) /* center */
- break;
- }
- }
- i += 2;
-
-#undef BASS_GPR
-#undef TREBLE_GPR
-
- for (z = 0; z < 6; z++) {
- SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
- SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
- SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
- OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
- }
- snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
- gpr += 2;
-
- /*
- * Process outputs
- */
- if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
- /* AC'97 Playback Volume */
-
- for (z = 0; z < 2; z++)
- OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
- }
-
- if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
- /* IEC958 Optical Raw Playback Switch */
-
- for (z = 0; z < 2; z++) {
- SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
- SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
- SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
- OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
-#ifdef EMU10K1_CAPTURE_DIGITAL_OUT
- OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
-#endif
- }
-
- snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0);
- gpr += 2;
- }
-
- if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
- /* Headphone Playback Volume */
-
- for (z = 0; z < 2; z++) {
- SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
- SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
- SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
- OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
- VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
- }
-
- snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
- controls[i-1].id.index = 1; /* AC'97 can have also Headphone control */
- snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
- controls[i-1].id.index = 1;
- snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
- controls[i-1].id.index = 1;
-
- gpr += 4;
- }
-
- if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
- for (z = 0; z < 2; z++)
- OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
-
- if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
- for (z = 0; z < 2; z++)
- OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
-
- if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
-#ifndef EMU10K1_CENTER_LFE_FROM_FRONT
- OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
- OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
-#else
- OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
- OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
-#endif
- }
-
- if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
-#ifndef EMU10K1_CENTER_LFE_FROM_FRONT
- OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
- OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
-#else
- OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
- OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
-#endif
- }
-
-#ifndef EMU10K1_CAPTURE_DIGITAL_OUT
- for (z = 0; z < 2; z++)
- OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
-#endif
-
- if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
- OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
-
- /* EFX capture - capture the 16 EXTINS */
- if (emu->card_capabilities->sblive51) {
- /* On the Live! 5.1, FXBUS2(1) and FXBUS(2) are shared with EXTOUT_ACENTER
- * and EXTOUT_ALFE, so we can't connect inputs to them for multitrack recording.
- *
- * Since only 14 of the 16 EXTINs are used, this is not a big problem.
- * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture
- * 0 and 3, then the rest of the EXTINs to the corresponding FX capture
- * channel. Multitrack recorders will still see the center/lfe output signal
- * on the second and third channels.
- */
- OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0));
- OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1));
- OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2));
- OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3));
- for (z = 4; z < 14; z++)
- OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
- } else {
- for (z = 0; z < 16; z++)
- OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
- }
-
-
- if (gpr > tmp) {
- snd_BUG();
- err = -EIO;
- goto __err;
- }
- if (i > SND_EMU10K1_GPR_CONTROLS) {
- snd_BUG();
- err = -EIO;
- goto __err;
- }
-
- /* clear remaining instruction memory */
- while (ptr < 0x200)
- OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
-
- if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
- goto __err;
- seg = snd_enter_user();
- icode->gpr_add_control_count = i;
- icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
- emu->support_tlv = 1; /* support TLV */
- err = snd_emu10k1_icode_poke(emu, icode);
- emu->support_tlv = 0; /* clear again */
- snd_leave_user(seg);
- if (err >= 0)
- err = snd_emu10k1_ipcm_poke(emu, ipcm);
- __err:
- kfree(ipcm);
- kfree(controls);
- if (icode != NULL) {
- kfree((void __force *)icode->gpr_map);
- kfree(icode);
- }
- return err;
-}
-
-int __devinit snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
-{
- spin_lock_init(&emu->fx8010.irq_lock);
- INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
- if (emu->audigy)
- return _snd_emu10k1_audigy_init_efx(emu);
- else
- return _snd_emu10k1_init_efx(emu);
-}
-
-void snd_emu10k1_free_efx(struct snd_emu10k1 *emu)
-{
- /* stop processor */
- if (emu->audigy)
- snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
- else
- snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
-}
-
-#if 0 /* FIXME: who use them? */
-int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output)
-{
- if (output < 0 || output >= 6)
- return -EINVAL;
- snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
- return 0;
-}
-
-int snd_emu10k1_fx8010_tone_control_deactivate(struct snd_emu10k1 *emu, int output)
-{
- if (output < 0 || output >= 6)
- return -EINVAL;
- snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
- return 0;
-}
-#endif
-
-int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size)
-{
- u8 size_reg = 0;
-
- /* size is in samples */
- if (size != 0) {
- size = (size - 1) >> 13;
-
- while (size) {
- size >>= 1;
- size_reg++;
- }
- size = 0x2000 << size_reg;
- }
- if ((emu->fx8010.etram_pages.bytes / 2) == size)
- return 0;
- spin_lock_irq(&emu->emu_lock);
- outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
- spin_unlock_irq(&emu->emu_lock);
- snd_emu10k1_ptr_write(emu, TCB, 0, 0);
- snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
- if (emu->fx8010.etram_pages.area != NULL) {
- snd_dma_free_pages(&emu->fx8010.etram_pages);
- emu->fx8010.etram_pages.area = NULL;
- emu->fx8010.etram_pages.bytes = 0;
- }
-
- if (size > 0) {
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
- size * 2, &emu->fx8010.etram_pages) < 0)
- return -ENOMEM;
- memset(emu->fx8010.etram_pages.area, 0, size * 2);
- snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
- snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
- spin_lock_irq(&emu->emu_lock);
- outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
- spin_unlock_irq(&emu->emu_lock);
- }
-
- return 0;
-}
-
-static int snd_emu10k1_fx8010_open(struct snd_hwdep * hw, struct file *file)
-{
- return 0;
-}
-
-static void copy_string(char *dst, char *src, char *null, int idx)
-{
- if (src == NULL)
- sprintf(dst, "%s %02X", null, idx);
- else
- strcpy(dst, src);
-}
-
-static void snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
- struct snd_emu10k1_fx8010_info *info)
-{
- char **fxbus, **extin, **extout;
- unsigned short fxbus_mask, extin_mask, extout_mask;
- int res;
-
- info->internal_tram_size = emu->fx8010.itram_size;
- info->external_tram_size = emu->fx8010.etram_pages.bytes / 2;
- fxbus = fxbuses;
- extin = emu->audigy ? audigy_ins : creative_ins;
- extout = emu->audigy ? audigy_outs : creative_outs;
- fxbus_mask = emu->fx8010.fxbus_mask;
- extin_mask = emu->fx8010.extin_mask;
- extout_mask = emu->fx8010.extout_mask;
- for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
- copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
- copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
- copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
- }
- for (res = 16; res < 32; res++, extout++)
- copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
- info->gpr_controls = emu->fx8010.gpr_count;
-}
-
-static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct snd_emu10k1 *emu = hw->private_data;
- struct snd_emu10k1_fx8010_info *info;
- struct snd_emu10k1_fx8010_code *icode;
- struct snd_emu10k1_fx8010_pcm_rec *ipcm;
- unsigned int addr;
- void __user *argp = (void __user *)arg;
- int res;
-
- switch (cmd) {
- case SNDRV_EMU10K1_IOCTL_PVERSION:
- emu->support_tlv = 1;
- return put_user(SNDRV_EMU10K1_VERSION, (int __user *)argp);
- case SNDRV_EMU10K1_IOCTL_INFO:
- info = kmalloc(sizeof(*info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
- snd_emu10k1_fx8010_info(emu, info);
- if (copy_to_user(argp, info, sizeof(*info))) {
- kfree(info);
- return -EFAULT;
- }
- kfree(info);
- return 0;
- case SNDRV_EMU10K1_IOCTL_CODE_POKE:
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- icode = memdup_user(argp, sizeof(*icode));
- if (IS_ERR(icode))
- return PTR_ERR(icode);
- res = snd_emu10k1_icode_poke(emu, icode);
- kfree(icode);
- return res;
- case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
- icode = memdup_user(argp, sizeof(*icode));
- if (IS_ERR(icode))
- return PTR_ERR(icode);
- res = snd_emu10k1_icode_peek(emu, icode);
- if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
- kfree(icode);
- return -EFAULT;
- }
- kfree(icode);
- return res;
- case SNDRV_EMU10K1_IOCTL_PCM_POKE:
- ipcm = memdup_user(argp, sizeof(*ipcm));
- if (IS_ERR(ipcm))
- return PTR_ERR(ipcm);
- res = snd_emu10k1_ipcm_poke(emu, ipcm);
- kfree(ipcm);
- return res;
- case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
- ipcm = memdup_user(argp, sizeof(*ipcm));
- if (IS_ERR(ipcm))
- return PTR_ERR(ipcm);
- res = snd_emu10k1_ipcm_peek(emu, ipcm);
- if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
- kfree(ipcm);
- return -EFAULT;
- }
- kfree(ipcm);
- return res;
- case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (get_user(addr, (unsigned int __user *)argp))
- return -EFAULT;
- mutex_lock(&emu->fx8010.lock);
- res = snd_emu10k1_fx8010_tram_setup(emu, addr);
- mutex_unlock(&emu->fx8010.lock);
- return res;
- case SNDRV_EMU10K1_IOCTL_STOP:
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (emu->audigy)
- snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
- else
- snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
- return 0;
- case SNDRV_EMU10K1_IOCTL_CONTINUE:
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (emu->audigy)
- snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
- else
- snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
- return 0;
- case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (emu->audigy)
- snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
- else
- snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
- udelay(10);
- if (emu->audigy)
- snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
- else
- snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
- return 0;
- case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (get_user(addr, (unsigned int __user *)argp))
- return -EFAULT;
- if (addr > 0x1ff)
- return -EINVAL;
- if (emu->audigy)
- snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
- else
- snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
- udelay(10);
- if (emu->audigy)
- snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
- else
- snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
- return 0;
- case SNDRV_EMU10K1_IOCTL_DBG_READ:
- if (emu->audigy)
- addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
- else
- addr = snd_emu10k1_ptr_read(emu, DBG, 0);
- if (put_user(addr, (unsigned int __user *)argp))
- return -EFAULT;
- return 0;
- }
- return -ENOTTY;
-}
-
-static int snd_emu10k1_fx8010_release(struct snd_hwdep * hw, struct file *file)
-{
- return 0;
-}
-
-int __devinit snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, struct snd_hwdep ** rhwdep)
-{
- struct snd_hwdep *hw;
- int err;
-
- if (rhwdep)
- *rhwdep = NULL;
- if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
- return err;
- strcpy(hw->name, "EMU10K1 (FX8010)");
- hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
- hw->ops.open = snd_emu10k1_fx8010_open;
- hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
- hw->ops.release = snd_emu10k1_fx8010_release;
- hw->private_data = emu;
- if (rhwdep)
- *rhwdep = hw;
- return 0;
-}
-
-#ifdef CONFIG_PM
-int __devinit snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu)
-{
- int len;
-
- len = emu->audigy ? 0x200 : 0x100;
- emu->saved_gpr = kmalloc(len * 4, GFP_KERNEL);
- if (! emu->saved_gpr)
- return -ENOMEM;
- len = emu->audigy ? 0x100 : 0xa0;
- emu->tram_val_saved = kmalloc(len * 4, GFP_KERNEL);
- emu->tram_addr_saved = kmalloc(len * 4, GFP_KERNEL);
- if (! emu->tram_val_saved || ! emu->tram_addr_saved)
- return -ENOMEM;
- len = emu->audigy ? 2 * 1024 : 2 * 512;
- emu->saved_icode = vmalloc(len * 4);
- if (! emu->saved_icode)
- return -ENOMEM;
- return 0;
-}
-
-void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu)
-{
- kfree(emu->saved_gpr);
- kfree(emu->tram_val_saved);
- kfree(emu->tram_addr_saved);
- vfree(emu->saved_icode);
-}
-
-/*
- * save/restore GPR, TRAM and codes
- */
-void snd_emu10k1_efx_suspend(struct snd_emu10k1 *emu)
-{
- int i, len;
-
- len = emu->audigy ? 0x200 : 0x100;
- for (i = 0; i < len; i++)
- emu->saved_gpr[i] = snd_emu10k1_ptr_read(emu, emu->gpr_base + i, 0);
-
- len = emu->audigy ? 0x100 : 0xa0;
- for (i = 0; i < len; i++) {
- emu->tram_val_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + i, 0);
- emu->tram_addr_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + i, 0);
- if (emu->audigy) {
- emu->tram_addr_saved[i] >>= 12;
- emu->tram_addr_saved[i] |=
- snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + i, 0) << 20;
- }
- }
-
- len = emu->audigy ? 2 * 1024 : 2 * 512;
- for (i = 0; i < len; i++)
- emu->saved_icode[i] = snd_emu10k1_efx_read(emu, i);
-}
-
-void snd_emu10k1_efx_resume(struct snd_emu10k1 *emu)
-{
- int i, len;
-
- /* set up TRAM */
- if (emu->fx8010.etram_pages.bytes > 0) {
- unsigned size, size_reg = 0;
- size = emu->fx8010.etram_pages.bytes / 2;
- size = (size - 1) >> 13;
- while (size) {
- size >>= 1;
- size_reg++;
- }
- outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
- snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
- snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
- outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
- }
-
- if (emu->audigy)
- snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
- else
- snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
-
- len = emu->audigy ? 0x200 : 0x100;
- for (i = 0; i < len; i++)
- snd_emu10k1_ptr_write(emu, emu->gpr_base + i, 0, emu->saved_gpr[i]);
-
- len = emu->audigy ? 0x100 : 0xa0;
- for (i = 0; i < len; i++) {
- snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + i, 0,
- emu->tram_val_saved[i]);
- if (! emu->audigy)
- snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
- emu->tram_addr_saved[i]);
- else {
- snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
- emu->tram_addr_saved[i] << 12);
- snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
- emu->tram_addr_saved[i] >> 20);
- }
- }
-
- len = emu->audigy ? 2 * 1024 : 2 * 512;
- for (i = 0; i < len; i++)
- snd_emu10k1_efx_write(emu, i, emu->saved_icode[i]);
-
- /* start FX processor when the DSP code is updated */
- if (emu->audigy)
- snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
- else
- snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
-}
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/emumixer.c b/ANDROID_3.4.5/sound/pci/emu10k1/emumixer.c
deleted file mode 100644
index 9d890a5a..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/emumixer.c
+++ /dev/null
@@ -1,2143 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
- * Takashi Iwai <tiwai@suse.de>
- * Creative Labs, Inc.
- * Routines for control of EMU10K1 chips / mixer routines
- * Multichannel PCM support Copyright (c) Lee Revell <rlrevell@joe-job.com>
- *
- * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk>
- * Added EMU 1010 support.
- *
- * BUGS:
- * --
- *
- * TODO:
- * --
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <linux/init.h>
-#include <sound/core.h>
-#include <sound/emu10k1.h>
-#include <linux/delay.h>
-#include <sound/tlv.h>
-
-#include "p17v.h"
-
-#define AC97_ID_STAC9758 0x83847658
-
-static const DECLARE_TLV_DB_SCALE(snd_audigy_db_scale2, -10350, 50, 1); /* WM8775 gain scale */
-
-static int snd_emu10k1_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_emu10k1_spdif_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- unsigned long flags;
-
- /* Limit: emu->spdif_bits */
- if (idx >= 3)
- return -EINVAL;
- spin_lock_irqsave(&emu->reg_lock, flags);
- ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff;
- ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff;
- ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff;
- ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff;
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return 0;
-}
-
-static int snd_emu10k1_spdif_get_mask(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.iec958.status[0] = 0xff;
- ucontrol->value.iec958.status[1] = 0xff;
- ucontrol->value.iec958.status[2] = 0xff;
- ucontrol->value.iec958.status[3] = 0xff;
- return 0;
-}
-
-/*
- * Items labels in enum mixer controls assigning source data to
- * each destination
- */
-static char *emu1010_src_texts[] = {
- "Silence",
- "Dock Mic A",
- "Dock Mic B",
- "Dock ADC1 Left",
- "Dock ADC1 Right",
- "Dock ADC2 Left",
- "Dock ADC2 Right",
- "Dock ADC3 Left",
- "Dock ADC3 Right",
- "0202 ADC Left",
- "0202 ADC Right",
- "0202 SPDIF Left",
- "0202 SPDIF Right",
- "ADAT 0",
- "ADAT 1",
- "ADAT 2",
- "ADAT 3",
- "ADAT 4",
- "ADAT 5",
- "ADAT 6",
- "ADAT 7",
- "DSP 0",
- "DSP 1",
- "DSP 2",
- "DSP 3",
- "DSP 4",
- "DSP 5",
- "DSP 6",
- "DSP 7",
- "DSP 8",
- "DSP 9",
- "DSP 10",
- "DSP 11",
- "DSP 12",
- "DSP 13",
- "DSP 14",
- "DSP 15",
- "DSP 16",
- "DSP 17",
- "DSP 18",
- "DSP 19",
- "DSP 20",
- "DSP 21",
- "DSP 22",
- "DSP 23",
- "DSP 24",
- "DSP 25",
- "DSP 26",
- "DSP 27",
- "DSP 28",
- "DSP 29",
- "DSP 30",
- "DSP 31",
-};
-
-/* 1616(m) cardbus */
-
-static char *emu1616_src_texts[] = {
- "Silence",
- "Dock Mic A",
- "Dock Mic B",
- "Dock ADC1 Left",
- "Dock ADC1 Right",
- "Dock ADC2 Left",
- "Dock ADC2 Right",
- "Dock SPDIF Left",
- "Dock SPDIF Right",
- "ADAT 0",
- "ADAT 1",
- "ADAT 2",
- "ADAT 3",
- "ADAT 4",
- "ADAT 5",
- "ADAT 6",
- "ADAT 7",
- "DSP 0",
- "DSP 1",
- "DSP 2",
- "DSP 3",
- "DSP 4",
- "DSP 5",
- "DSP 6",
- "DSP 7",
- "DSP 8",
- "DSP 9",
- "DSP 10",
- "DSP 11",
- "DSP 12",
- "DSP 13",
- "DSP 14",
- "DSP 15",
- "DSP 16",
- "DSP 17",
- "DSP 18",
- "DSP 19",
- "DSP 20",
- "DSP 21",
- "DSP 22",
- "DSP 23",
- "DSP 24",
- "DSP 25",
- "DSP 26",
- "DSP 27",
- "DSP 28",
- "DSP 29",
- "DSP 30",
- "DSP 31",
-};
-
-
-/*
- * List of data sources available for each destination
- */
-static unsigned int emu1010_src_regs[] = {
- EMU_SRC_SILENCE,/* 0 */
- EMU_SRC_DOCK_MIC_A1, /* 1 */
- EMU_SRC_DOCK_MIC_B1, /* 2 */
- EMU_SRC_DOCK_ADC1_LEFT1, /* 3 */
- EMU_SRC_DOCK_ADC1_RIGHT1, /* 4 */
- EMU_SRC_DOCK_ADC2_LEFT1, /* 5 */
- EMU_SRC_DOCK_ADC2_RIGHT1, /* 6 */
- EMU_SRC_DOCK_ADC3_LEFT1, /* 7 */
- EMU_SRC_DOCK_ADC3_RIGHT1, /* 8 */
- EMU_SRC_HAMOA_ADC_LEFT1, /* 9 */
- EMU_SRC_HAMOA_ADC_RIGHT1, /* 10 */
- EMU_SRC_HANA_SPDIF_LEFT1, /* 11 */
- EMU_SRC_HANA_SPDIF_RIGHT1, /* 12 */
- EMU_SRC_HANA_ADAT, /* 13 */
- EMU_SRC_HANA_ADAT+1, /* 14 */
- EMU_SRC_HANA_ADAT+2, /* 15 */
- EMU_SRC_HANA_ADAT+3, /* 16 */
- EMU_SRC_HANA_ADAT+4, /* 17 */
- EMU_SRC_HANA_ADAT+5, /* 18 */
- EMU_SRC_HANA_ADAT+6, /* 19 */
- EMU_SRC_HANA_ADAT+7, /* 20 */
- EMU_SRC_ALICE_EMU32A, /* 21 */
- EMU_SRC_ALICE_EMU32A+1, /* 22 */
- EMU_SRC_ALICE_EMU32A+2, /* 23 */
- EMU_SRC_ALICE_EMU32A+3, /* 24 */
- EMU_SRC_ALICE_EMU32A+4, /* 25 */
- EMU_SRC_ALICE_EMU32A+5, /* 26 */
- EMU_SRC_ALICE_EMU32A+6, /* 27 */
- EMU_SRC_ALICE_EMU32A+7, /* 28 */
- EMU_SRC_ALICE_EMU32A+8, /* 29 */
- EMU_SRC_ALICE_EMU32A+9, /* 30 */
- EMU_SRC_ALICE_EMU32A+0xa, /* 31 */
- EMU_SRC_ALICE_EMU32A+0xb, /* 32 */
- EMU_SRC_ALICE_EMU32A+0xc, /* 33 */
- EMU_SRC_ALICE_EMU32A+0xd, /* 34 */
- EMU_SRC_ALICE_EMU32A+0xe, /* 35 */
- EMU_SRC_ALICE_EMU32A+0xf, /* 36 */
- EMU_SRC_ALICE_EMU32B, /* 37 */
- EMU_SRC_ALICE_EMU32B+1, /* 38 */
- EMU_SRC_ALICE_EMU32B+2, /* 39 */
- EMU_SRC_ALICE_EMU32B+3, /* 40 */
- EMU_SRC_ALICE_EMU32B+4, /* 41 */
- EMU_SRC_ALICE_EMU32B+5, /* 42 */
- EMU_SRC_ALICE_EMU32B+6, /* 43 */
- EMU_SRC_ALICE_EMU32B+7, /* 44 */
- EMU_SRC_ALICE_EMU32B+8, /* 45 */
- EMU_SRC_ALICE_EMU32B+9, /* 46 */
- EMU_SRC_ALICE_EMU32B+0xa, /* 47 */
- EMU_SRC_ALICE_EMU32B+0xb, /* 48 */
- EMU_SRC_ALICE_EMU32B+0xc, /* 49 */
- EMU_SRC_ALICE_EMU32B+0xd, /* 50 */
- EMU_SRC_ALICE_EMU32B+0xe, /* 51 */
- EMU_SRC_ALICE_EMU32B+0xf, /* 52 */
-};
-
-/* 1616(m) cardbus */
-static unsigned int emu1616_src_regs[] = {
- EMU_SRC_SILENCE,
- EMU_SRC_DOCK_MIC_A1,
- EMU_SRC_DOCK_MIC_B1,
- EMU_SRC_DOCK_ADC1_LEFT1,
- EMU_SRC_DOCK_ADC1_RIGHT1,
- EMU_SRC_DOCK_ADC2_LEFT1,
- EMU_SRC_DOCK_ADC2_RIGHT1,
- EMU_SRC_MDOCK_SPDIF_LEFT1,
- EMU_SRC_MDOCK_SPDIF_RIGHT1,
- EMU_SRC_MDOCK_ADAT,
- EMU_SRC_MDOCK_ADAT+1,
- EMU_SRC_MDOCK_ADAT+2,
- EMU_SRC_MDOCK_ADAT+3,
- EMU_SRC_MDOCK_ADAT+4,
- EMU_SRC_MDOCK_ADAT+5,
- EMU_SRC_MDOCK_ADAT+6,
- EMU_SRC_MDOCK_ADAT+7,
- EMU_SRC_ALICE_EMU32A,
- EMU_SRC_ALICE_EMU32A+1,
- EMU_SRC_ALICE_EMU32A+2,
- EMU_SRC_ALICE_EMU32A+3,
- EMU_SRC_ALICE_EMU32A+4,
- EMU_SRC_ALICE_EMU32A+5,
- EMU_SRC_ALICE_EMU32A+6,
- EMU_SRC_ALICE_EMU32A+7,
- EMU_SRC_ALICE_EMU32A+8,
- EMU_SRC_ALICE_EMU32A+9,
- EMU_SRC_ALICE_EMU32A+0xa,
- EMU_SRC_ALICE_EMU32A+0xb,
- EMU_SRC_ALICE_EMU32A+0xc,
- EMU_SRC_ALICE_EMU32A+0xd,
- EMU_SRC_ALICE_EMU32A+0xe,
- EMU_SRC_ALICE_EMU32A+0xf,
- EMU_SRC_ALICE_EMU32B,
- EMU_SRC_ALICE_EMU32B+1,
- EMU_SRC_ALICE_EMU32B+2,
- EMU_SRC_ALICE_EMU32B+3,
- EMU_SRC_ALICE_EMU32B+4,
- EMU_SRC_ALICE_EMU32B+5,
- EMU_SRC_ALICE_EMU32B+6,
- EMU_SRC_ALICE_EMU32B+7,
- EMU_SRC_ALICE_EMU32B+8,
- EMU_SRC_ALICE_EMU32B+9,
- EMU_SRC_ALICE_EMU32B+0xa,
- EMU_SRC_ALICE_EMU32B+0xb,
- EMU_SRC_ALICE_EMU32B+0xc,
- EMU_SRC_ALICE_EMU32B+0xd,
- EMU_SRC_ALICE_EMU32B+0xe,
- EMU_SRC_ALICE_EMU32B+0xf,
-};
-
-/*
- * Data destinations - physical EMU outputs.
- * Each destination has an enum mixer control to choose a data source
- */
-static unsigned int emu1010_output_dst[] = {
- EMU_DST_DOCK_DAC1_LEFT1, /* 0 */
- EMU_DST_DOCK_DAC1_RIGHT1, /* 1 */
- EMU_DST_DOCK_DAC2_LEFT1, /* 2 */
- EMU_DST_DOCK_DAC2_RIGHT1, /* 3 */
- EMU_DST_DOCK_DAC3_LEFT1, /* 4 */
- EMU_DST_DOCK_DAC3_RIGHT1, /* 5 */
- EMU_DST_DOCK_DAC4_LEFT1, /* 6 */
- EMU_DST_DOCK_DAC4_RIGHT1, /* 7 */
- EMU_DST_DOCK_PHONES_LEFT1, /* 8 */
- EMU_DST_DOCK_PHONES_RIGHT1, /* 9 */
- EMU_DST_DOCK_SPDIF_LEFT1, /* 10 */
- EMU_DST_DOCK_SPDIF_RIGHT1, /* 11 */
- EMU_DST_HANA_SPDIF_LEFT1, /* 12 */
- EMU_DST_HANA_SPDIF_RIGHT1, /* 13 */
- EMU_DST_HAMOA_DAC_LEFT1, /* 14 */
- EMU_DST_HAMOA_DAC_RIGHT1, /* 15 */
- EMU_DST_HANA_ADAT, /* 16 */
- EMU_DST_HANA_ADAT+1, /* 17 */
- EMU_DST_HANA_ADAT+2, /* 18 */
- EMU_DST_HANA_ADAT+3, /* 19 */
- EMU_DST_HANA_ADAT+4, /* 20 */
- EMU_DST_HANA_ADAT+5, /* 21 */
- EMU_DST_HANA_ADAT+6, /* 22 */
- EMU_DST_HANA_ADAT+7, /* 23 */
-};
-
-/* 1616(m) cardbus */
-static unsigned int emu1616_output_dst[] = {
- EMU_DST_DOCK_DAC1_LEFT1,
- EMU_DST_DOCK_DAC1_RIGHT1,
- EMU_DST_DOCK_DAC2_LEFT1,
- EMU_DST_DOCK_DAC2_RIGHT1,
- EMU_DST_DOCK_DAC3_LEFT1,
- EMU_DST_DOCK_DAC3_RIGHT1,
- EMU_DST_MDOCK_SPDIF_LEFT1,
- EMU_DST_MDOCK_SPDIF_RIGHT1,
- EMU_DST_MDOCK_ADAT,
- EMU_DST_MDOCK_ADAT+1,
- EMU_DST_MDOCK_ADAT+2,
- EMU_DST_MDOCK_ADAT+3,
- EMU_DST_MDOCK_ADAT+4,
- EMU_DST_MDOCK_ADAT+5,
- EMU_DST_MDOCK_ADAT+6,
- EMU_DST_MDOCK_ADAT+7,
- EMU_DST_MANA_DAC_LEFT,
- EMU_DST_MANA_DAC_RIGHT,
-};
-
-/*
- * Data destinations - HANA outputs going to Alice2 (audigy) for
- * capture (EMU32 + I2S links)
- * Each destination has an enum mixer control to choose a data source
- */
-static unsigned int emu1010_input_dst[] = {
- EMU_DST_ALICE2_EMU32_0,
- EMU_DST_ALICE2_EMU32_1,
- EMU_DST_ALICE2_EMU32_2,
- EMU_DST_ALICE2_EMU32_3,
- EMU_DST_ALICE2_EMU32_4,
- EMU_DST_ALICE2_EMU32_5,
- EMU_DST_ALICE2_EMU32_6,
- EMU_DST_ALICE2_EMU32_7,
- EMU_DST_ALICE2_EMU32_8,
- EMU_DST_ALICE2_EMU32_9,
- EMU_DST_ALICE2_EMU32_A,
- EMU_DST_ALICE2_EMU32_B,
- EMU_DST_ALICE2_EMU32_C,
- EMU_DST_ALICE2_EMU32_D,
- EMU_DST_ALICE2_EMU32_E,
- EMU_DST_ALICE2_EMU32_F,
- EMU_DST_ALICE_I2S0_LEFT,
- EMU_DST_ALICE_I2S0_RIGHT,
- EMU_DST_ALICE_I2S1_LEFT,
- EMU_DST_ALICE_I2S1_RIGHT,
- EMU_DST_ALICE_I2S2_LEFT,
- EMU_DST_ALICE_I2S2_RIGHT,
-};
-
-static int snd_emu1010_input_output_source_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- char **items;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1616) {
- uinfo->value.enumerated.items = 49;
- items = emu1616_src_texts;
- } else {
- uinfo->value.enumerated.items = 53;
- items = emu1010_src_texts;
- }
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name,
- items[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_emu1010_output_source_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int channel;
-
- channel = (kcontrol->private_value) & 0xff;
- /* Limit: emu1010_output_dst, emu->emu1010.output_source */
- if (channel >= 24 ||
- (emu->card_capabilities->emu_model == EMU_MODEL_EMU1616 &&
- channel >= 18))
- return -EINVAL;
- ucontrol->value.enumerated.item[0] = emu->emu1010.output_source[channel];
- return 0;
-}
-
-static int snd_emu1010_output_source_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- unsigned int channel;
-
- val = ucontrol->value.enumerated.item[0];
- if (val >= 53 ||
- (emu->card_capabilities->emu_model == EMU_MODEL_EMU1616 &&
- val >= 49))
- return -EINVAL;
- channel = (kcontrol->private_value) & 0xff;
- /* Limit: emu1010_output_dst, emu->emu1010.output_source */
- if (channel >= 24 ||
- (emu->card_capabilities->emu_model == EMU_MODEL_EMU1616 &&
- channel >= 18))
- return -EINVAL;
- if (emu->emu1010.output_source[channel] == val)
- return 0;
- emu->emu1010.output_source[channel] = val;
- if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1616)
- snd_emu1010_fpga_link_dst_src_write(emu,
- emu1616_output_dst[channel], emu1616_src_regs[val]);
- else
- snd_emu1010_fpga_link_dst_src_write(emu,
- emu1010_output_dst[channel], emu1010_src_regs[val]);
- return 1;
-}
-
-static int snd_emu1010_input_source_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int channel;
-
- channel = (kcontrol->private_value) & 0xff;
- /* Limit: emu1010_input_dst, emu->emu1010.input_source */
- if (channel >= 22)
- return -EINVAL;
- ucontrol->value.enumerated.item[0] = emu->emu1010.input_source[channel];
- return 0;
-}
-
-static int snd_emu1010_input_source_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- unsigned int channel;
-
- val = ucontrol->value.enumerated.item[0];
- if (val >= 53 ||
- (emu->card_capabilities->emu_model == EMU_MODEL_EMU1616 &&
- val >= 49))
- return -EINVAL;
- channel = (kcontrol->private_value) & 0xff;
- /* Limit: emu1010_input_dst, emu->emu1010.input_source */
- if (channel >= 22)
- return -EINVAL;
- if (emu->emu1010.input_source[channel] == val)
- return 0;
- emu->emu1010.input_source[channel] = val;
- if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1616)
- snd_emu1010_fpga_link_dst_src_write(emu,
- emu1010_input_dst[channel], emu1616_src_regs[val]);
- else
- snd_emu1010_fpga_link_dst_src_write(emu,
- emu1010_input_dst[channel], emu1010_src_regs[val]);
- return 1;
-}
-
-#define EMU1010_SOURCE_OUTPUT(xname,chid) \
-{ \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
- .info = snd_emu1010_input_output_source_info, \
- .get = snd_emu1010_output_source_get, \
- .put = snd_emu1010_output_source_put, \
- .private_value = chid \
-}
-
-static struct snd_kcontrol_new snd_emu1010_output_enum_ctls[] __devinitdata = {
- EMU1010_SOURCE_OUTPUT("Dock DAC1 Left Playback Enum", 0),
- EMU1010_SOURCE_OUTPUT("Dock DAC1 Right Playback Enum", 1),
- EMU1010_SOURCE_OUTPUT("Dock DAC2 Left Playback Enum", 2),
- EMU1010_SOURCE_OUTPUT("Dock DAC2 Right Playback Enum", 3),
- EMU1010_SOURCE_OUTPUT("Dock DAC3 Left Playback Enum", 4),
- EMU1010_SOURCE_OUTPUT("Dock DAC3 Right Playback Enum", 5),
- EMU1010_SOURCE_OUTPUT("Dock DAC4 Left Playback Enum", 6),
- EMU1010_SOURCE_OUTPUT("Dock DAC4 Right Playback Enum", 7),
- EMU1010_SOURCE_OUTPUT("Dock Phones Left Playback Enum", 8),
- EMU1010_SOURCE_OUTPUT("Dock Phones Right Playback Enum", 9),
- EMU1010_SOURCE_OUTPUT("Dock SPDIF Left Playback Enum", 0xa),
- EMU1010_SOURCE_OUTPUT("Dock SPDIF Right Playback Enum", 0xb),
- EMU1010_SOURCE_OUTPUT("1010 SPDIF Left Playback Enum", 0xc),
- EMU1010_SOURCE_OUTPUT("1010 SPDIF Right Playback Enum", 0xd),
- EMU1010_SOURCE_OUTPUT("0202 DAC Left Playback Enum", 0xe),
- EMU1010_SOURCE_OUTPUT("0202 DAC Right Playback Enum", 0xf),
- EMU1010_SOURCE_OUTPUT("1010 ADAT 0 Playback Enum", 0x10),
- EMU1010_SOURCE_OUTPUT("1010 ADAT 1 Playback Enum", 0x11),
- EMU1010_SOURCE_OUTPUT("1010 ADAT 2 Playback Enum", 0x12),
- EMU1010_SOURCE_OUTPUT("1010 ADAT 3 Playback Enum", 0x13),
- EMU1010_SOURCE_OUTPUT("1010 ADAT 4 Playback Enum", 0x14),
- EMU1010_SOURCE_OUTPUT("1010 ADAT 5 Playback Enum", 0x15),
- EMU1010_SOURCE_OUTPUT("1010 ADAT 6 Playback Enum", 0x16),
- EMU1010_SOURCE_OUTPUT("1010 ADAT 7 Playback Enum", 0x17),
-};
-
-
-/* 1616(m) cardbus */
-static struct snd_kcontrol_new snd_emu1616_output_enum_ctls[] __devinitdata = {
- EMU1010_SOURCE_OUTPUT("Dock DAC1 Left Playback Enum", 0),
- EMU1010_SOURCE_OUTPUT("Dock DAC1 Right Playback Enum", 1),
- EMU1010_SOURCE_OUTPUT("Dock DAC2 Left Playback Enum", 2),
- EMU1010_SOURCE_OUTPUT("Dock DAC2 Right Playback Enum", 3),
- EMU1010_SOURCE_OUTPUT("Dock DAC3 Left Playback Enum", 4),
- EMU1010_SOURCE_OUTPUT("Dock DAC3 Right Playback Enum", 5),
- EMU1010_SOURCE_OUTPUT("Dock SPDIF Left Playback Enum", 6),
- EMU1010_SOURCE_OUTPUT("Dock SPDIF Right Playback Enum", 7),
- EMU1010_SOURCE_OUTPUT("Dock ADAT 0 Playback Enum", 8),
- EMU1010_SOURCE_OUTPUT("Dock ADAT 1 Playback Enum", 9),
- EMU1010_SOURCE_OUTPUT("Dock ADAT 2 Playback Enum", 0xa),
- EMU1010_SOURCE_OUTPUT("Dock ADAT 3 Playback Enum", 0xb),
- EMU1010_SOURCE_OUTPUT("Dock ADAT 4 Playback Enum", 0xc),
- EMU1010_SOURCE_OUTPUT("Dock ADAT 5 Playback Enum", 0xd),
- EMU1010_SOURCE_OUTPUT("Dock ADAT 6 Playback Enum", 0xe),
- EMU1010_SOURCE_OUTPUT("Dock ADAT 7 Playback Enum", 0xf),
- EMU1010_SOURCE_OUTPUT("Mana DAC Left Playback Enum", 0x10),
- EMU1010_SOURCE_OUTPUT("Mana DAC Right Playback Enum", 0x11),
-};
-
-
-#define EMU1010_SOURCE_INPUT(xname,chid) \
-{ \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
- .info = snd_emu1010_input_output_source_info, \
- .get = snd_emu1010_input_source_get, \
- .put = snd_emu1010_input_source_put, \
- .private_value = chid \
-}
-
-static struct snd_kcontrol_new snd_emu1010_input_enum_ctls[] __devinitdata = {
- EMU1010_SOURCE_INPUT("DSP 0 Capture Enum", 0),
- EMU1010_SOURCE_INPUT("DSP 1 Capture Enum", 1),
- EMU1010_SOURCE_INPUT("DSP 2 Capture Enum", 2),
- EMU1010_SOURCE_INPUT("DSP 3 Capture Enum", 3),
- EMU1010_SOURCE_INPUT("DSP 4 Capture Enum", 4),
- EMU1010_SOURCE_INPUT("DSP 5 Capture Enum", 5),
- EMU1010_SOURCE_INPUT("DSP 6 Capture Enum", 6),
- EMU1010_SOURCE_INPUT("DSP 7 Capture Enum", 7),
- EMU1010_SOURCE_INPUT("DSP 8 Capture Enum", 8),
- EMU1010_SOURCE_INPUT("DSP 9 Capture Enum", 9),
- EMU1010_SOURCE_INPUT("DSP A Capture Enum", 0xa),
- EMU1010_SOURCE_INPUT("DSP B Capture Enum", 0xb),
- EMU1010_SOURCE_INPUT("DSP C Capture Enum", 0xc),
- EMU1010_SOURCE_INPUT("DSP D Capture Enum", 0xd),
- EMU1010_SOURCE_INPUT("DSP E Capture Enum", 0xe),
- EMU1010_SOURCE_INPUT("DSP F Capture Enum", 0xf),
- EMU1010_SOURCE_INPUT("DSP 10 Capture Enum", 0x10),
- EMU1010_SOURCE_INPUT("DSP 11 Capture Enum", 0x11),
- EMU1010_SOURCE_INPUT("DSP 12 Capture Enum", 0x12),
- EMU1010_SOURCE_INPUT("DSP 13 Capture Enum", 0x13),
- EMU1010_SOURCE_INPUT("DSP 14 Capture Enum", 0x14),
- EMU1010_SOURCE_INPUT("DSP 15 Capture Enum", 0x15),
-};
-
-
-
-#define snd_emu1010_adc_pads_info snd_ctl_boolean_mono_info
-
-static int snd_emu1010_adc_pads_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int mask = kcontrol->private_value & 0xff;
- ucontrol->value.integer.value[0] = (emu->emu1010.adc_pads & mask) ? 1 : 0;
- return 0;
-}
-
-static int snd_emu1010_adc_pads_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int mask = kcontrol->private_value & 0xff;
- unsigned int val, cache;
- val = ucontrol->value.integer.value[0];
- cache = emu->emu1010.adc_pads;
- if (val == 1)
- cache = cache | mask;
- else
- cache = cache & ~mask;
- if (cache != emu->emu1010.adc_pads) {
- snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, cache );
- emu->emu1010.adc_pads = cache;
- }
-
- return 0;
-}
-
-
-
-#define EMU1010_ADC_PADS(xname,chid) \
-{ \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
- .info = snd_emu1010_adc_pads_info, \
- .get = snd_emu1010_adc_pads_get, \
- .put = snd_emu1010_adc_pads_put, \
- .private_value = chid \
-}
-
-static struct snd_kcontrol_new snd_emu1010_adc_pads[] __devinitdata = {
- EMU1010_ADC_PADS("ADC1 14dB PAD Audio Dock Capture Switch", EMU_HANA_DOCK_ADC_PAD1),
- EMU1010_ADC_PADS("ADC2 14dB PAD Audio Dock Capture Switch", EMU_HANA_DOCK_ADC_PAD2),
- EMU1010_ADC_PADS("ADC3 14dB PAD Audio Dock Capture Switch", EMU_HANA_DOCK_ADC_PAD3),
- EMU1010_ADC_PADS("ADC1 14dB PAD 0202 Capture Switch", EMU_HANA_0202_ADC_PAD1),
-};
-
-#define snd_emu1010_dac_pads_info snd_ctl_boolean_mono_info
-
-static int snd_emu1010_dac_pads_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int mask = kcontrol->private_value & 0xff;
- ucontrol->value.integer.value[0] = (emu->emu1010.dac_pads & mask) ? 1 : 0;
- return 0;
-}
-
-static int snd_emu1010_dac_pads_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int mask = kcontrol->private_value & 0xff;
- unsigned int val, cache;
- val = ucontrol->value.integer.value[0];
- cache = emu->emu1010.dac_pads;
- if (val == 1)
- cache = cache | mask;
- else
- cache = cache & ~mask;
- if (cache != emu->emu1010.dac_pads) {
- snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, cache );
- emu->emu1010.dac_pads = cache;
- }
-
- return 0;
-}
-
-
-
-#define EMU1010_DAC_PADS(xname,chid) \
-{ \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
- .info = snd_emu1010_dac_pads_info, \
- .get = snd_emu1010_dac_pads_get, \
- .put = snd_emu1010_dac_pads_put, \
- .private_value = chid \
-}
-
-static struct snd_kcontrol_new snd_emu1010_dac_pads[] __devinitdata = {
- EMU1010_DAC_PADS("DAC1 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD1),
- EMU1010_DAC_PADS("DAC2 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD2),
- EMU1010_DAC_PADS("DAC3 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD3),
- EMU1010_DAC_PADS("DAC4 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD4),
- EMU1010_DAC_PADS("DAC1 0202 14dB PAD Playback Switch", EMU_HANA_0202_DAC_PAD1),
-};
-
-
-static int snd_emu1010_internal_clock_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[4] = {
- "44100", "48000", "SPDIF", "ADAT"
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 4;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-
-
-}
-
-static int snd_emu1010_internal_clock_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = emu->emu1010.internal_clock;
- return 0;
-}
-
-static int snd_emu1010_internal_clock_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change = 0;
-
- val = ucontrol->value.enumerated.item[0] ;
- /* Limit: uinfo->value.enumerated.items = 4; */
- if (val >= 4)
- return -EINVAL;
- change = (emu->emu1010.internal_clock != val);
- if (change) {
- emu->emu1010.internal_clock = val;
- switch (val) {
- case 0:
- /* 44100 */
- /* Mute all */
- snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );
- /* Default fallback clock 48kHz */
- snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_44_1K );
- /* Word Clock source, Internal 44.1kHz x1 */
- snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,
- EMU_HANA_WCLOCK_INT_44_1K | EMU_HANA_WCLOCK_1X );
- /* Set LEDs on Audio Dock */
- snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2,
- EMU_HANA_DOCK_LEDS_2_44K | EMU_HANA_DOCK_LEDS_2_LOCK );
- /* Allow DLL to settle */
- msleep(10);
- /* Unmute all */
- snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );
- break;
- case 1:
- /* 48000 */
- /* Mute all */
- snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );
- /* Default fallback clock 48kHz */
- snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_48K );
- /* Word Clock source, Internal 48kHz x1 */
- snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,
- EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_1X );
- /* Set LEDs on Audio Dock */
- snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2,
- EMU_HANA_DOCK_LEDS_2_48K | EMU_HANA_DOCK_LEDS_2_LOCK );
- /* Allow DLL to settle */
- msleep(10);
- /* Unmute all */
- snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );
- break;
-
- case 2: /* Take clock from S/PDIF IN */
- /* Mute all */
- snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );
- /* Default fallback clock 48kHz */
- snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_48K );
- /* Word Clock source, sync to S/PDIF input */
- snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,
- EMU_HANA_WCLOCK_HANA_SPDIF_IN | EMU_HANA_WCLOCK_1X );
- /* Set LEDs on Audio Dock */
- snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2,
- EMU_HANA_DOCK_LEDS_2_EXT | EMU_HANA_DOCK_LEDS_2_LOCK );
- /* FIXME: We should set EMU_HANA_DOCK_LEDS_2_LOCK only when clock signal is present and valid */
- /* Allow DLL to settle */
- msleep(10);
- /* Unmute all */
- snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );
- break;
-
- case 3:
- /* Take clock from ADAT IN */
- /* Mute all */
- snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );
- /* Default fallback clock 48kHz */
- snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_48K );
- /* Word Clock source, sync to ADAT input */
- snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,
- EMU_HANA_WCLOCK_HANA_ADAT_IN | EMU_HANA_WCLOCK_1X );
- /* Set LEDs on Audio Dock */
- snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, EMU_HANA_DOCK_LEDS_2_EXT | EMU_HANA_DOCK_LEDS_2_LOCK );
- /* FIXME: We should set EMU_HANA_DOCK_LEDS_2_LOCK only when clock signal is present and valid */
- /* Allow DLL to settle */
- msleep(10);
- /* Unmute all */
- snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );
-
-
- break;
- }
- }
- return change;
-}
-
-static struct snd_kcontrol_new snd_emu1010_internal_clock =
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Clock Internal Rate",
- .count = 1,
- .info = snd_emu1010_internal_clock_info,
- .get = snd_emu1010_internal_clock_get,
- .put = snd_emu1010_internal_clock_put
-};
-
-static int snd_audigy_i2c_capture_source_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
-#if 0
- static char *texts[4] = {
- "Unknown1", "Unknown2", "Mic", "Line"
- };
-#endif
- static char *texts[2] = {
- "Mic", "Line"
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item > 1)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_audigy_i2c_capture_source_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = emu->i2c_capture_source;
- return 0;
-}
-
-static int snd_audigy_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int source_id;
- unsigned int ngain, ogain;
- u32 gpio;
- int change = 0;
- unsigned long flags;
- u32 source;
- /* If the capture source has changed,
- * update the capture volume from the cached value
- * for the particular source.
- */
- source_id = ucontrol->value.enumerated.item[0];
- /* Limit: uinfo->value.enumerated.items = 2; */
- /* emu->i2c_capture_volume */
- if (source_id >= 2)
- return -EINVAL;
- change = (emu->i2c_capture_source != source_id);
- if (change) {
- snd_emu10k1_i2c_write(emu, ADC_MUX, 0); /* Mute input */
- spin_lock_irqsave(&emu->emu_lock, flags);
- gpio = inl(emu->port + A_IOCFG);
- if (source_id==0)
- outl(gpio | 0x4, emu->port + A_IOCFG);
- else
- outl(gpio & ~0x4, emu->port + A_IOCFG);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-
- ngain = emu->i2c_capture_volume[source_id][0]; /* Left */
- ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
- if (ngain != ogain)
- snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff));
- ngain = emu->i2c_capture_volume[source_id][1]; /* Right */
- ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Right */
- if (ngain != ogain)
- snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
-
- source = 1 << (source_id + 2);
- snd_emu10k1_i2c_write(emu, ADC_MUX, source); /* Set source */
- emu->i2c_capture_source = source_id;
- }
- return change;
-}
-
-static struct snd_kcontrol_new snd_audigy_i2c_capture_source =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = snd_audigy_i2c_capture_source_info,
- .get = snd_audigy_i2c_capture_source_get,
- .put = snd_audigy_i2c_capture_source_put
-};
-
-static int snd_audigy_i2c_volume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 255;
- return 0;
-}
-
-static int snd_audigy_i2c_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int source_id;
-
- source_id = kcontrol->private_value;
- /* Limit: emu->i2c_capture_volume */
- /* capture_source: uinfo->value.enumerated.items = 2 */
- if (source_id >= 2)
- return -EINVAL;
-
- ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0];
- ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1];
- return 0;
-}
-
-static int snd_audigy_i2c_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int ogain;
- unsigned int ngain;
- unsigned int source_id;
- int change = 0;
-
- source_id = kcontrol->private_value;
- /* Limit: emu->i2c_capture_volume */
- /* capture_source: uinfo->value.enumerated.items = 2 */
- if (source_id >= 2)
- return -EINVAL;
- ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
- ngain = ucontrol->value.integer.value[0];
- if (ngain > 0xff)
- return 0;
- if (ogain != ngain) {
- if (emu->i2c_capture_source == source_id)
- snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) );
- emu->i2c_capture_volume[source_id][0] = ngain;
- change = 1;
- }
- ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
- ngain = ucontrol->value.integer.value[1];
- if (ngain > 0xff)
- return 0;
- if (ogain != ngain) {
- if (emu->i2c_capture_source == source_id)
- snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
- emu->i2c_capture_volume[source_id][1] = ngain;
- change = 1;
- }
-
- return change;
-}
-
-#define I2C_VOLUME(xname,chid) \
-{ \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
- SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .info = snd_audigy_i2c_volume_info, \
- .get = snd_audigy_i2c_volume_get, \
- .put = snd_audigy_i2c_volume_put, \
- .tlv = { .p = snd_audigy_db_scale2 }, \
- .private_value = chid \
-}
-
-
-static struct snd_kcontrol_new snd_audigy_i2c_volume_ctls[] __devinitdata = {
- I2C_VOLUME("Mic Capture Volume", 0),
- I2C_VOLUME("Line Capture Volume", 0)
-};
-
-#if 0
-static int snd_audigy_spdif_output_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = {"44100", "48000", "96000"};
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_audigy_spdif_output_rate_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int tmp;
- unsigned long flags;
-
-
- spin_lock_irqsave(&emu->reg_lock, flags);
- tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
- switch (tmp & A_SPDIF_RATE_MASK) {
- case A_SPDIF_44100:
- ucontrol->value.enumerated.item[0] = 0;
- break;
- case A_SPDIF_48000:
- ucontrol->value.enumerated.item[0] = 1;
- break;
- case A_SPDIF_96000:
- ucontrol->value.enumerated.item[0] = 2;
- break;
- default:
- ucontrol->value.enumerated.item[0] = 1;
- }
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return 0;
-}
-
-static int snd_audigy_spdif_output_rate_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int reg, val, tmp;
- unsigned long flags;
-
- switch(ucontrol->value.enumerated.item[0]) {
- case 0:
- val = A_SPDIF_44100;
- break;
- case 1:
- val = A_SPDIF_48000;
- break;
- case 2:
- val = A_SPDIF_96000;
- break;
- default:
- val = A_SPDIF_48000;
- break;
- }
-
-
- spin_lock_irqsave(&emu->reg_lock, flags);
- reg = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
- tmp = reg & ~A_SPDIF_RATE_MASK;
- tmp |= val;
- if ((change = (tmp != reg)))
- snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return change;
-}
-
-static struct snd_kcontrol_new snd_audigy_spdif_output_rate =
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Audigy SPDIF Output Sample Rate",
- .count = 1,
- .info = snd_audigy_spdif_output_rate_info,
- .get = snd_audigy_spdif_output_rate_get,
- .put = snd_audigy_spdif_output_rate_put
-};
-#endif
-
-static int snd_emu10k1_spdif_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- int change;
- unsigned int val;
- unsigned long flags;
-
- /* Limit: emu->spdif_bits */
- if (idx >= 3)
- return -EINVAL;
- val = (ucontrol->value.iec958.status[0] << 0) |
- (ucontrol->value.iec958.status[1] << 8) |
- (ucontrol->value.iec958.status[2] << 16) |
- (ucontrol->value.iec958.status[3] << 24);
- spin_lock_irqsave(&emu->reg_lock, flags);
- change = val != emu->spdif_bits[idx];
- if (change) {
- snd_emu10k1_ptr_write(emu, SPCS0 + idx, 0, val);
- emu->spdif_bits[idx] = val;
- }
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return change;
-}
-
-static struct snd_kcontrol_new snd_emu10k1_spdif_mask_control =
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
- .count = 3,
- .info = snd_emu10k1_spdif_info,
- .get = snd_emu10k1_spdif_get_mask
-};
-
-static struct snd_kcontrol_new snd_emu10k1_spdif_control =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
- .count = 3,
- .info = snd_emu10k1_spdif_info,
- .get = snd_emu10k1_spdif_get,
- .put = snd_emu10k1_spdif_put
-};
-
-
-static void update_emu10k1_fxrt(struct snd_emu10k1 *emu, int voice, unsigned char *route)
-{
- if (emu->audigy) {
- snd_emu10k1_ptr_write(emu, A_FXRT1, voice,
- snd_emu10k1_compose_audigy_fxrt1(route));
- snd_emu10k1_ptr_write(emu, A_FXRT2, voice,
- snd_emu10k1_compose_audigy_fxrt2(route));
- } else {
- snd_emu10k1_ptr_write(emu, FXRT, voice,
- snd_emu10k1_compose_send_routing(route));
- }
-}
-
-static void update_emu10k1_send_volume(struct snd_emu10k1 *emu, int voice, unsigned char *volume)
-{
- snd_emu10k1_ptr_write(emu, PTRX_FXSENDAMOUNT_A, voice, volume[0]);
- snd_emu10k1_ptr_write(emu, PTRX_FXSENDAMOUNT_B, voice, volume[1]);
- snd_emu10k1_ptr_write(emu, PSST_FXSENDAMOUNT_C, voice, volume[2]);
- snd_emu10k1_ptr_write(emu, DSL_FXSENDAMOUNT_D, voice, volume[3]);
- if (emu->audigy) {
- unsigned int val = ((unsigned int)volume[4] << 24) |
- ((unsigned int)volume[5] << 16) |
- ((unsigned int)volume[6] << 8) |
- (unsigned int)volume[7];
- snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, voice, val);
- }
-}
-
-/* PCM stream controls */
-
-static int snd_emu10k1_send_routing_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = emu->audigy ? 3*8 : 3*4;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = emu->audigy ? 0x3f : 0x0f;
- return 0;
-}
-
-static int snd_emu10k1_send_routing_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- unsigned long flags;
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- struct snd_emu10k1_pcm_mixer *mix =
- &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
- int voice, idx;
- int num_efx = emu->audigy ? 8 : 4;
- int mask = emu->audigy ? 0x3f : 0x0f;
-
- spin_lock_irqsave(&emu->reg_lock, flags);
- for (voice = 0; voice < 3; voice++)
- for (idx = 0; idx < num_efx; idx++)
- ucontrol->value.integer.value[(voice * num_efx) + idx] =
- mix->send_routing[voice][idx] & mask;
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return 0;
-}
-
-static int snd_emu10k1_send_routing_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- unsigned long flags;
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- struct snd_emu10k1_pcm_mixer *mix =
- &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
- int change = 0, voice, idx, val;
- int num_efx = emu->audigy ? 8 : 4;
- int mask = emu->audigy ? 0x3f : 0x0f;
-
- spin_lock_irqsave(&emu->reg_lock, flags);
- for (voice = 0; voice < 3; voice++)
- for (idx = 0; idx < num_efx; idx++) {
- val = ucontrol->value.integer.value[(voice * num_efx) + idx] & mask;
- if (mix->send_routing[voice][idx] != val) {
- mix->send_routing[voice][idx] = val;
- change = 1;
- }
- }
- if (change && mix->epcm) {
- if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
- update_emu10k1_fxrt(emu, mix->epcm->voices[0]->number,
- &mix->send_routing[1][0]);
- update_emu10k1_fxrt(emu, mix->epcm->voices[1]->number,
- &mix->send_routing[2][0]);
- } else if (mix->epcm->voices[0]) {
- update_emu10k1_fxrt(emu, mix->epcm->voices[0]->number,
- &mix->send_routing[0][0]);
- }
- }
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return change;
-}
-
-static struct snd_kcontrol_new snd_emu10k1_send_routing_control =
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "EMU10K1 PCM Send Routing",
- .count = 32,
- .info = snd_emu10k1_send_routing_info,
- .get = snd_emu10k1_send_routing_get,
- .put = snd_emu10k1_send_routing_put
-};
-
-static int snd_emu10k1_send_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = emu->audigy ? 3*8 : 3*4;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 255;
- return 0;
-}
-
-static int snd_emu10k1_send_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- unsigned long flags;
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- struct snd_emu10k1_pcm_mixer *mix =
- &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
- int idx;
- int num_efx = emu->audigy ? 8 : 4;
-
- spin_lock_irqsave(&emu->reg_lock, flags);
- for (idx = 0; idx < 3*num_efx; idx++)
- ucontrol->value.integer.value[idx] = mix->send_volume[idx/num_efx][idx%num_efx];
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return 0;
-}
-
-static int snd_emu10k1_send_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- unsigned long flags;
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- struct snd_emu10k1_pcm_mixer *mix =
- &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
- int change = 0, idx, val;
- int num_efx = emu->audigy ? 8 : 4;
-
- spin_lock_irqsave(&emu->reg_lock, flags);
- for (idx = 0; idx < 3*num_efx; idx++) {
- val = ucontrol->value.integer.value[idx] & 255;
- if (mix->send_volume[idx/num_efx][idx%num_efx] != val) {
- mix->send_volume[idx/num_efx][idx%num_efx] = val;
- change = 1;
- }
- }
- if (change && mix->epcm) {
- if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
- update_emu10k1_send_volume(emu, mix->epcm->voices[0]->number,
- &mix->send_volume[1][0]);
- update_emu10k1_send_volume(emu, mix->epcm->voices[1]->number,
- &mix->send_volume[2][0]);
- } else if (mix->epcm->voices[0]) {
- update_emu10k1_send_volume(emu, mix->epcm->voices[0]->number,
- &mix->send_volume[0][0]);
- }
- }
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return change;
-}
-
-static struct snd_kcontrol_new snd_emu10k1_send_volume_control =
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "EMU10K1 PCM Send Volume",
- .count = 32,
- .info = snd_emu10k1_send_volume_info,
- .get = snd_emu10k1_send_volume_get,
- .put = snd_emu10k1_send_volume_put
-};
-
-static int snd_emu10k1_attn_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 3;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 0xffff;
- return 0;
-}
-
-static int snd_emu10k1_attn_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- struct snd_emu10k1_pcm_mixer *mix =
- &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
- unsigned long flags;
- int idx;
-
- spin_lock_irqsave(&emu->reg_lock, flags);
- for (idx = 0; idx < 3; idx++)
- ucontrol->value.integer.value[idx] = mix->attn[idx];
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return 0;
-}
-
-static int snd_emu10k1_attn_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- unsigned long flags;
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- struct snd_emu10k1_pcm_mixer *mix =
- &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
- int change = 0, idx, val;
-
- spin_lock_irqsave(&emu->reg_lock, flags);
- for (idx = 0; idx < 3; idx++) {
- val = ucontrol->value.integer.value[idx] & 0xffff;
- if (mix->attn[idx] != val) {
- mix->attn[idx] = val;
- change = 1;
- }
- }
- if (change && mix->epcm) {
- if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
- snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[1]);
- snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[1]->number, mix->attn[2]);
- } else if (mix->epcm->voices[0]) {
- snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[0]);
- }
- }
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return change;
-}
-
-static struct snd_kcontrol_new snd_emu10k1_attn_control =
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "EMU10K1 PCM Volume",
- .count = 32,
- .info = snd_emu10k1_attn_info,
- .get = snd_emu10k1_attn_get,
- .put = snd_emu10k1_attn_put
-};
-
-/* Mutichannel PCM stream controls */
-
-static int snd_emu10k1_efx_send_routing_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = emu->audigy ? 8 : 4;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = emu->audigy ? 0x3f : 0x0f;
- return 0;
-}
-
-static int snd_emu10k1_efx_send_routing_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- unsigned long flags;
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- struct snd_emu10k1_pcm_mixer *mix =
- &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
- int idx;
- int num_efx = emu->audigy ? 8 : 4;
- int mask = emu->audigy ? 0x3f : 0x0f;
-
- spin_lock_irqsave(&emu->reg_lock, flags);
- for (idx = 0; idx < num_efx; idx++)
- ucontrol->value.integer.value[idx] =
- mix->send_routing[0][idx] & mask;
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return 0;
-}
-
-static int snd_emu10k1_efx_send_routing_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- unsigned long flags;
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];
- int change = 0, idx, val;
- int num_efx = emu->audigy ? 8 : 4;
- int mask = emu->audigy ? 0x3f : 0x0f;
-
- spin_lock_irqsave(&emu->reg_lock, flags);
- for (idx = 0; idx < num_efx; idx++) {
- val = ucontrol->value.integer.value[idx] & mask;
- if (mix->send_routing[0][idx] != val) {
- mix->send_routing[0][idx] = val;
- change = 1;
- }
- }
-
- if (change && mix->epcm) {
- if (mix->epcm->voices[ch]) {
- update_emu10k1_fxrt(emu, mix->epcm->voices[ch]->number,
- &mix->send_routing[0][0]);
- }
- }
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return change;
-}
-
-static struct snd_kcontrol_new snd_emu10k1_efx_send_routing_control =
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "Multichannel PCM Send Routing",
- .count = 16,
- .info = snd_emu10k1_efx_send_routing_info,
- .get = snd_emu10k1_efx_send_routing_get,
- .put = snd_emu10k1_efx_send_routing_put
-};
-
-static int snd_emu10k1_efx_send_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = emu->audigy ? 8 : 4;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 255;
- return 0;
-}
-
-static int snd_emu10k1_efx_send_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- unsigned long flags;
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- struct snd_emu10k1_pcm_mixer *mix =
- &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
- int idx;
- int num_efx = emu->audigy ? 8 : 4;
-
- spin_lock_irqsave(&emu->reg_lock, flags);
- for (idx = 0; idx < num_efx; idx++)
- ucontrol->value.integer.value[idx] = mix->send_volume[0][idx];
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return 0;
-}
-
-static int snd_emu10k1_efx_send_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- unsigned long flags;
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];
- int change = 0, idx, val;
- int num_efx = emu->audigy ? 8 : 4;
-
- spin_lock_irqsave(&emu->reg_lock, flags);
- for (idx = 0; idx < num_efx; idx++) {
- val = ucontrol->value.integer.value[idx] & 255;
- if (mix->send_volume[0][idx] != val) {
- mix->send_volume[0][idx] = val;
- change = 1;
- }
- }
- if (change && mix->epcm) {
- if (mix->epcm->voices[ch]) {
- update_emu10k1_send_volume(emu, mix->epcm->voices[ch]->number,
- &mix->send_volume[0][0]);
- }
- }
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return change;
-}
-
-
-static struct snd_kcontrol_new snd_emu10k1_efx_send_volume_control =
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "Multichannel PCM Send Volume",
- .count = 16,
- .info = snd_emu10k1_efx_send_volume_info,
- .get = snd_emu10k1_efx_send_volume_get,
- .put = snd_emu10k1_efx_send_volume_put
-};
-
-static int snd_emu10k1_efx_attn_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 0xffff;
- return 0;
-}
-
-static int snd_emu10k1_efx_attn_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- struct snd_emu10k1_pcm_mixer *mix =
- &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
- unsigned long flags;
-
- spin_lock_irqsave(&emu->reg_lock, flags);
- ucontrol->value.integer.value[0] = mix->attn[0];
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return 0;
-}
-
-static int snd_emu10k1_efx_attn_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- unsigned long flags;
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];
- int change = 0, val;
-
- spin_lock_irqsave(&emu->reg_lock, flags);
- val = ucontrol->value.integer.value[0] & 0xffff;
- if (mix->attn[0] != val) {
- mix->attn[0] = val;
- change = 1;
- }
- if (change && mix->epcm) {
- if (mix->epcm->voices[ch]) {
- snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[ch]->number, mix->attn[0]);
- }
- }
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return change;
-}
-
-static struct snd_kcontrol_new snd_emu10k1_efx_attn_control =
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "Multichannel PCM Volume",
- .count = 16,
- .info = snd_emu10k1_efx_attn_info,
- .get = snd_emu10k1_efx_attn_get,
- .put = snd_emu10k1_efx_attn_put
-};
-
-#define snd_emu10k1_shared_spdif_info snd_ctl_boolean_mono_info
-
-static int snd_emu10k1_shared_spdif_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
-
- if (emu->audigy)
- ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0;
- else
- ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0;
- if (emu->card_capabilities->invert_shared_spdif)
- ucontrol->value.integer.value[0] =
- !ucontrol->value.integer.value[0];
-
- return 0;
-}
-
-static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- unsigned long flags;
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int reg, val, sw;
- int change = 0;
-
- sw = ucontrol->value.integer.value[0];
- if (emu->card_capabilities->invert_shared_spdif)
- sw = !sw;
- spin_lock_irqsave(&emu->reg_lock, flags);
- if ( emu->card_capabilities->i2c_adc) {
- /* Do nothing for Audigy 2 ZS Notebook */
- } else if (emu->audigy) {
- reg = inl(emu->port + A_IOCFG);
- val = sw ? A_IOCFG_GPOUT0 : 0;
- change = (reg & A_IOCFG_GPOUT0) != val;
- if (change) {
- reg &= ~A_IOCFG_GPOUT0;
- reg |= val;
- outl(reg | val, emu->port + A_IOCFG);
- }
- }
- reg = inl(emu->port + HCFG);
- val = sw ? HCFG_GPOUT0 : 0;
- change |= (reg & HCFG_GPOUT0) != val;
- if (change) {
- reg &= ~HCFG_GPOUT0;
- reg |= val;
- outl(reg | val, emu->port + HCFG);
- }
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return change;
-}
-
-static struct snd_kcontrol_new snd_emu10k1_shared_spdif __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "SB Live Analog/Digital Output Jack",
- .info = snd_emu10k1_shared_spdif_info,
- .get = snd_emu10k1_shared_spdif_get,
- .put = snd_emu10k1_shared_spdif_put
-};
-
-static struct snd_kcontrol_new snd_audigy_shared_spdif __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Audigy Analog/Digital Output Jack",
- .info = snd_emu10k1_shared_spdif_info,
- .get = snd_emu10k1_shared_spdif_get,
- .put = snd_emu10k1_shared_spdif_put
-};
-
-/* workaround for too low volume on Audigy due to 16bit/24bit conversion */
-
-#define snd_audigy_capture_boost_info snd_ctl_boolean_mono_info
-
-static int snd_audigy_capture_boost_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int val;
-
- /* FIXME: better to use a cached version */
- val = snd_ac97_read(emu->ac97, AC97_REC_GAIN);
- ucontrol->value.integer.value[0] = !!val;
- return 0;
-}
-
-static int snd_audigy_capture_boost_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int val;
-
- if (ucontrol->value.integer.value[0])
- val = 0x0f0f;
- else
- val = 0;
- return snd_ac97_update(emu->ac97, AC97_REC_GAIN, val);
-}
-
-static struct snd_kcontrol_new snd_audigy_capture_boost __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Capture Boost",
- .info = snd_audigy_capture_boost_info,
- .get = snd_audigy_capture_boost_get,
- .put = snd_audigy_capture_boost_put
-};
-
-
-/*
- */
-static void snd_emu10k1_mixer_free_ac97(struct snd_ac97 *ac97)
-{
- struct snd_emu10k1 *emu = ac97->private_data;
- emu->ac97 = NULL;
-}
-
-/*
- */
-static int remove_ctl(struct snd_card *card, const char *name)
-{
- struct snd_ctl_elem_id id;
- memset(&id, 0, sizeof(id));
- strcpy(id.name, name);
- id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- return snd_ctl_remove_id(card, &id);
-}
-
-static struct snd_kcontrol *ctl_find(struct snd_card *card, const char *name)
-{
- struct snd_ctl_elem_id sid;
- memset(&sid, 0, sizeof(sid));
- strcpy(sid.name, name);
- sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- return snd_ctl_find_id(card, &sid);
-}
-
-static int rename_ctl(struct snd_card *card, const char *src, const char *dst)
-{
- struct snd_kcontrol *kctl = ctl_find(card, src);
- if (kctl) {
- strcpy(kctl->id.name, dst);
- return 0;
- }
- return -ENOENT;
-}
-
-int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
- int pcm_device, int multi_device)
-{
- int err, pcm;
- struct snd_kcontrol *kctl;
- struct snd_card *card = emu->card;
- char **c;
- static char *emu10k1_remove_ctls[] = {
- /* no AC97 mono, surround, center/lfe */
- "Master Mono Playback Switch",
- "Master Mono Playback Volume",
- "PCM Out Path & Mute",
- "Mono Output Select",
- "Surround Playback Switch",
- "Surround Playback Volume",
- "Center Playback Switch",
- "Center Playback Volume",
- "LFE Playback Switch",
- "LFE Playback Volume",
- NULL
- };
- static char *emu10k1_rename_ctls[] = {
- "Surround Digital Playback Volume", "Surround Playback Volume",
- "Center Digital Playback Volume", "Center Playback Volume",
- "LFE Digital Playback Volume", "LFE Playback Volume",
- NULL
- };
- static char *audigy_remove_ctls[] = {
- /* Master/PCM controls on ac97 of Audigy has no effect */
- /* On the Audigy2 the AC97 playback is piped into
- * the Philips ADC for 24bit capture */
- "PCM Playback Switch",
- "PCM Playback Volume",
- "Master Mono Playback Switch",
- "Master Mono Playback Volume",
- "Master Playback Switch",
- "Master Playback Volume",
- "PCM Out Path & Mute",
- "Mono Output Select",
- /* remove unused AC97 capture controls */
- "Capture Source",
- "Capture Switch",
- "Capture Volume",
- "Mic Select",
- "Video Playback Switch",
- "Video Playback Volume",
- "Mic Playback Switch",
- "Mic Playback Volume",
- NULL
- };
- static char *audigy_rename_ctls[] = {
- /* use conventional names */
- "Wave Playback Volume", "PCM Playback Volume",
- /* "Wave Capture Volume", "PCM Capture Volume", */
- "Wave Master Playback Volume", "Master Playback Volume",
- "AMic Playback Volume", "Mic Playback Volume",
- NULL
- };
- static char *audigy_rename_ctls_i2c_adc[] = {
- //"Analog Mix Capture Volume","OLD Analog Mix Capture Volume",
- "Line Capture Volume", "Analog Mix Capture Volume",
- "Wave Playback Volume", "OLD PCM Playback Volume",
- "Wave Master Playback Volume", "Master Playback Volume",
- "AMic Playback Volume", "Old Mic Playback Volume",
- "CD Capture Volume", "IEC958 Optical Capture Volume",
- NULL
- };
- static char *audigy_remove_ctls_i2c_adc[] = {
- /* On the Audigy2 ZS Notebook
- * Capture via WM8775 */
- "Mic Capture Volume",
- "Analog Mix Capture Volume",
- "Aux Capture Volume",
- "IEC958 Optical Capture Volume",
- NULL
- };
- static char *audigy_remove_ctls_1361t_adc[] = {
- /* On the Audigy2 the AC97 playback is piped into
- * the Philips ADC for 24bit capture */
- "PCM Playback Switch",
- "PCM Playback Volume",
- "Master Mono Playback Switch",
- "Master Mono Playback Volume",
- "Capture Source",
- "Capture Switch",
- "Capture Volume",
- "Mic Capture Volume",
- "Headphone Playback Switch",
- "Headphone Playback Volume",
- "3D Control - Center",
- "3D Control - Depth",
- "3D Control - Switch",
- "Line2 Playback Volume",
- "Line2 Capture Volume",
- NULL
- };
- static char *audigy_rename_ctls_1361t_adc[] = {
- "Master Playback Switch", "Master Capture Switch",
- "Master Playback Volume", "Master Capture Volume",
- "Wave Master Playback Volume", "Master Playback Volume",
- "Beep Playback Switch", "Beep Capture Switch",
- "Beep Playback Volume", "Beep Capture Volume",
- "Phone Playback Switch", "Phone Capture Switch",
- "Phone Playback Volume", "Phone Capture Volume",
- "Mic Playback Switch", "Mic Capture Switch",
- "Mic Playback Volume", "Mic Capture Volume",
- "Line Playback Switch", "Line Capture Switch",
- "Line Playback Volume", "Line Capture Volume",
- "CD Playback Switch", "CD Capture Switch",
- "CD Playback Volume", "CD Capture Volume",
- "Aux Playback Switch", "Aux Capture Switch",
- "Aux Playback Volume", "Aux Capture Volume",
- "Video Playback Switch", "Video Capture Switch",
- "Video Playback Volume", "Video Capture Volume",
-
- NULL
- };
-
- if (emu->card_capabilities->ac97_chip) {
- struct snd_ac97_bus *pbus;
- struct snd_ac97_template ac97;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_emu10k1_ac97_write,
- .read = snd_emu10k1_ac97_read,
- };
-
- if ((err = snd_ac97_bus(emu->card, 0, &ops, NULL, &pbus)) < 0)
- return err;
- pbus->no_vra = 1; /* we don't need VRA */
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = emu;
- ac97.private_free = snd_emu10k1_mixer_free_ac97;
- ac97.scaps = AC97_SCAP_NO_SPDIF;
- if ((err = snd_ac97_mixer(pbus, &ac97, &emu->ac97)) < 0) {
- if (emu->card_capabilities->ac97_chip == 1)
- return err;
- snd_printd(KERN_INFO "emu10k1: AC97 is optional on this board\n");
- snd_printd(KERN_INFO" Proceeding without ac97 mixers...\n");
- snd_device_free(emu->card, pbus);
- goto no_ac97; /* FIXME: get rid of ugly gotos.. */
- }
- if (emu->audigy) {
- /* set master volume to 0 dB */
- snd_ac97_write_cache(emu->ac97, AC97_MASTER, 0x0000);
- /* set capture source to mic */
- snd_ac97_write_cache(emu->ac97, AC97_REC_SEL, 0x0000);
- if (emu->card_capabilities->adc_1361t)
- c = audigy_remove_ctls_1361t_adc;
- else
- c = audigy_remove_ctls;
- } else {
- /*
- * Credits for cards based on STAC9758:
- * James Courtier-Dutton <James@superbug.demon.co.uk>
- * Voluspa <voluspa@comhem.se>
- */
- if (emu->ac97->id == AC97_ID_STAC9758) {
- emu->rear_ac97 = 1;
- snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT);
- snd_ac97_write_cache(emu->ac97, AC97_HEADPHONE, 0x0202);
- remove_ctl(card,"Front Playback Volume");
- remove_ctl(card,"Front Playback Switch");
- }
- /* remove unused AC97 controls */
- snd_ac97_write_cache(emu->ac97, AC97_SURROUND_MASTER, 0x0202);
- snd_ac97_write_cache(emu->ac97, AC97_CENTER_LFE_MASTER, 0x0202);
- c = emu10k1_remove_ctls;
- }
- for (; *c; c++)
- remove_ctl(card, *c);
- } else if (emu->card_capabilities->i2c_adc) {
- c = audigy_remove_ctls_i2c_adc;
- for (; *c; c++)
- remove_ctl(card, *c);
- } else {
- no_ac97:
- if (emu->card_capabilities->ecard)
- strcpy(emu->card->mixername, "EMU APS");
- else if (emu->audigy)
- strcpy(emu->card->mixername, "SB Audigy");
- else
- strcpy(emu->card->mixername, "Emu10k1");
- }
-
- if (emu->audigy)
- if (emu->card_capabilities->adc_1361t)
- c = audigy_rename_ctls_1361t_adc;
- else if (emu->card_capabilities->i2c_adc)
- c = audigy_rename_ctls_i2c_adc;
- else
- c = audigy_rename_ctls;
- else
- c = emu10k1_rename_ctls;
- for (; *c; c += 2)
- rename_ctl(card, c[0], c[1]);
-
- if (emu->card_capabilities->subsystem == 0x80401102) { /* SB Live! Platinum CT4760P */
- remove_ctl(card, "Center Playback Volume");
- remove_ctl(card, "LFE Playback Volume");
- remove_ctl(card, "Wave Center Playback Volume");
- remove_ctl(card, "Wave LFE Playback Volume");
- }
- if (emu->card_capabilities->subsystem == 0x20071102) { /* Audigy 4 Pro */
- rename_ctl(card, "Line2 Capture Volume", "Line1/Mic Capture Volume");
- rename_ctl(card, "Analog Mix Capture Volume", "Line2 Capture Volume");
- rename_ctl(card, "Aux2 Capture Volume", "Line3 Capture Volume");
- rename_ctl(card, "Mic Capture Volume", "Unknown1 Capture Volume");
- remove_ctl(card, "Headphone Playback Switch");
- remove_ctl(card, "Headphone Playback Volume");
- remove_ctl(card, "3D Control - Center");
- remove_ctl(card, "3D Control - Depth");
- remove_ctl(card, "3D Control - Switch");
- }
- if ((kctl = emu->ctl_send_routing = snd_ctl_new1(&snd_emu10k1_send_routing_control, emu)) == NULL)
- return -ENOMEM;
- kctl->id.device = pcm_device;
- if ((err = snd_ctl_add(card, kctl)))
- return err;
- if ((kctl = emu->ctl_send_volume = snd_ctl_new1(&snd_emu10k1_send_volume_control, emu)) == NULL)
- return -ENOMEM;
- kctl->id.device = pcm_device;
- if ((err = snd_ctl_add(card, kctl)))
- return err;
- if ((kctl = emu->ctl_attn = snd_ctl_new1(&snd_emu10k1_attn_control, emu)) == NULL)
- return -ENOMEM;
- kctl->id.device = pcm_device;
- if ((err = snd_ctl_add(card, kctl)))
- return err;
-
- if ((kctl = emu->ctl_efx_send_routing = snd_ctl_new1(&snd_emu10k1_efx_send_routing_control, emu)) == NULL)
- return -ENOMEM;
- kctl->id.device = multi_device;
- if ((err = snd_ctl_add(card, kctl)))
- return err;
-
- if ((kctl = emu->ctl_efx_send_volume = snd_ctl_new1(&snd_emu10k1_efx_send_volume_control, emu)) == NULL)
- return -ENOMEM;
- kctl->id.device = multi_device;
- if ((err = snd_ctl_add(card, kctl)))
- return err;
-
- if ((kctl = emu->ctl_efx_attn = snd_ctl_new1(&snd_emu10k1_efx_attn_control, emu)) == NULL)
- return -ENOMEM;
- kctl->id.device = multi_device;
- if ((err = snd_ctl_add(card, kctl)))
- return err;
-
- /* initialize the routing and volume table for each pcm playback stream */
- for (pcm = 0; pcm < 32; pcm++) {
- struct snd_emu10k1_pcm_mixer *mix;
- int v;
-
- mix = &emu->pcm_mixer[pcm];
- mix->epcm = NULL;
-
- for (v = 0; v < 4; v++)
- mix->send_routing[0][v] =
- mix->send_routing[1][v] =
- mix->send_routing[2][v] = v;
-
- memset(&mix->send_volume, 0, sizeof(mix->send_volume));
- mix->send_volume[0][0] = mix->send_volume[0][1] =
- mix->send_volume[1][0] = mix->send_volume[2][1] = 255;
-
- mix->attn[0] = mix->attn[1] = mix->attn[2] = 0xffff;
- }
-
- /* initialize the routing and volume table for the multichannel playback stream */
- for (pcm = 0; pcm < NUM_EFX_PLAYBACK; pcm++) {
- struct snd_emu10k1_pcm_mixer *mix;
- int v;
-
- mix = &emu->efx_pcm_mixer[pcm];
- mix->epcm = NULL;
-
- mix->send_routing[0][0] = pcm;
- mix->send_routing[0][1] = (pcm == 0) ? 1 : 0;
- for (v = 0; v < 2; v++)
- mix->send_routing[0][2+v] = 13+v;
- if (emu->audigy)
- for (v = 0; v < 4; v++)
- mix->send_routing[0][4+v] = 60+v;
-
- memset(&mix->send_volume, 0, sizeof(mix->send_volume));
- mix->send_volume[0][0] = 255;
-
- mix->attn[0] = 0xffff;
- }
-
- if (! emu->card_capabilities->ecard) { /* FIXME: APS has these controls? */
- /* sb live! and audigy */
- if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_mask_control, emu)) == NULL)
- return -ENOMEM;
- if (!emu->audigy)
- kctl->id.device = emu->pcm_efx->device;
- if ((err = snd_ctl_add(card, kctl)))
- return err;
- if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_control, emu)) == NULL)
- return -ENOMEM;
- if (!emu->audigy)
- kctl->id.device = emu->pcm_efx->device;
- if ((err = snd_ctl_add(card, kctl)))
- return err;
- }
-
- if (emu->card_capabilities->emu_model) {
- ; /* Disable the snd_audigy_spdif_shared_spdif */
- } else if (emu->audigy) {
- if ((kctl = snd_ctl_new1(&snd_audigy_shared_spdif, emu)) == NULL)
- return -ENOMEM;
- if ((err = snd_ctl_add(card, kctl)))
- return err;
-#if 0
- if ((kctl = snd_ctl_new1(&snd_audigy_spdif_output_rate, emu)) == NULL)
- return -ENOMEM;
- if ((err = snd_ctl_add(card, kctl)))
- return err;
-#endif
- } else if (! emu->card_capabilities->ecard) {
- /* sb live! */
- if ((kctl = snd_ctl_new1(&snd_emu10k1_shared_spdif, emu)) == NULL)
- return -ENOMEM;
- if ((err = snd_ctl_add(card, kctl)))
- return err;
- }
- if (emu->card_capabilities->ca0151_chip) { /* P16V */
- if ((err = snd_p16v_mixer(emu)))
- return err;
- }
-
- if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1616) {
- /* 1616(m) cardbus */
- int i;
-
- for (i = 0; i < ARRAY_SIZE(snd_emu1616_output_enum_ctls); i++) {
- err = snd_ctl_add(card,
- snd_ctl_new1(&snd_emu1616_output_enum_ctls[i],
- emu));
- if (err < 0)
- return err;
- }
- for (i = 0; i < ARRAY_SIZE(snd_emu1010_input_enum_ctls); i++) {
- err = snd_ctl_add(card,
- snd_ctl_new1(&snd_emu1010_input_enum_ctls[i],
- emu));
- if (err < 0)
- return err;
- }
- for (i = 0; i < ARRAY_SIZE(snd_emu1010_adc_pads) - 2; i++) {
- err = snd_ctl_add(card,
- snd_ctl_new1(&snd_emu1010_adc_pads[i], emu));
- if (err < 0)
- return err;
- }
- for (i = 0; i < ARRAY_SIZE(snd_emu1010_dac_pads) - 2; i++) {
- err = snd_ctl_add(card,
- snd_ctl_new1(&snd_emu1010_dac_pads[i], emu));
- if (err < 0)
- return err;
- }
- err = snd_ctl_add(card,
- snd_ctl_new1(&snd_emu1010_internal_clock, emu));
- if (err < 0)
- return err;
-
- } else if (emu->card_capabilities->emu_model) {
- /* all other e-mu cards for now */
- int i;
-
- for (i = 0; i < ARRAY_SIZE(snd_emu1010_output_enum_ctls); i++) {
- err = snd_ctl_add(card,
- snd_ctl_new1(&snd_emu1010_output_enum_ctls[i],
- emu));
- if (err < 0)
- return err;
- }
- for (i = 0; i < ARRAY_SIZE(snd_emu1010_input_enum_ctls); i++) {
- err = snd_ctl_add(card,
- snd_ctl_new1(&snd_emu1010_input_enum_ctls[i],
- emu));
- if (err < 0)
- return err;
- }
- for (i = 0; i < ARRAY_SIZE(snd_emu1010_adc_pads); i++) {
- err = snd_ctl_add(card,
- snd_ctl_new1(&snd_emu1010_adc_pads[i], emu));
- if (err < 0)
- return err;
- }
- for (i = 0; i < ARRAY_SIZE(snd_emu1010_dac_pads); i++) {
- err = snd_ctl_add(card,
- snd_ctl_new1(&snd_emu1010_dac_pads[i], emu));
- if (err < 0)
- return err;
- }
- err = snd_ctl_add(card,
- snd_ctl_new1(&snd_emu1010_internal_clock, emu));
- if (err < 0)
- return err;
- }
-
- if ( emu->card_capabilities->i2c_adc) {
- int i;
-
- err = snd_ctl_add(card, snd_ctl_new1(&snd_audigy_i2c_capture_source, emu));
- if (err < 0)
- return err;
-
- for (i = 0; i < ARRAY_SIZE(snd_audigy_i2c_volume_ctls); i++) {
- err = snd_ctl_add(card, snd_ctl_new1(&snd_audigy_i2c_volume_ctls[i], emu));
- if (err < 0)
- return err;
- }
- }
-
- if (emu->card_capabilities->ac97_chip && emu->audigy) {
- err = snd_ctl_add(card, snd_ctl_new1(&snd_audigy_capture_boost,
- emu));
- if (err < 0)
- return err;
- }
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/emumpu401.c b/ANDROID_3.4.5/sound/pci/emu10k1/emumpu401.c
deleted file mode 100644
index bab56482..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/emumpu401.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Routines for control of EMU10K1 MPU-401 in UART mode
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <linux/init.h>
-#include <sound/core.h>
-#include <sound/emu10k1.h>
-
-#define EMU10K1_MIDI_MODE_INPUT (1<<0)
-#define EMU10K1_MIDI_MODE_OUTPUT (1<<1)
-
-static inline unsigned char mpu401_read(struct snd_emu10k1 *emu,
- struct snd_emu10k1_midi *mpu, int idx)
-{
- if (emu->audigy)
- return (unsigned char)snd_emu10k1_ptr_read(emu, mpu->port + idx, 0);
- else
- return inb(emu->port + mpu->port + idx);
-}
-
-static inline void mpu401_write(struct snd_emu10k1 *emu,
- struct snd_emu10k1_midi *mpu, int data, int idx)
-{
- if (emu->audigy)
- snd_emu10k1_ptr_write(emu, mpu->port + idx, 0, data);
- else
- outb(data, emu->port + mpu->port + idx);
-}
-
-#define mpu401_write_data(emu, mpu, data) mpu401_write(emu, mpu, data, 0)
-#define mpu401_write_cmd(emu, mpu, data) mpu401_write(emu, mpu, data, 1)
-#define mpu401_read_data(emu, mpu) mpu401_read(emu, mpu, 0)
-#define mpu401_read_stat(emu, mpu) mpu401_read(emu, mpu, 1)
-
-#define mpu401_input_avail(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x80))
-#define mpu401_output_ready(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x40))
-
-#define MPU401_RESET 0xff
-#define MPU401_ENTER_UART 0x3f
-#define MPU401_ACK 0xfe
-
-static void mpu401_clear_rx(struct snd_emu10k1 *emu, struct snd_emu10k1_midi *mpu)
-{
- int timeout = 100000;
- for (; timeout > 0 && mpu401_input_avail(emu, mpu); timeout--)
- mpu401_read_data(emu, mpu);
-#ifdef CONFIG_SND_DEBUG
- if (timeout <= 0)
- snd_printk(KERN_ERR "cmd: clear rx timeout (status = 0x%x)\n", mpu401_read_stat(emu, mpu));
-#endif
-}
-
-/*
-
- */
-
-static void do_emu10k1_midi_interrupt(struct snd_emu10k1 *emu, struct snd_emu10k1_midi *midi, unsigned int status)
-{
- unsigned char byte;
-
- if (midi->rmidi == NULL) {
- snd_emu10k1_intr_disable(emu, midi->tx_enable | midi->rx_enable);
- return;
- }
-
- spin_lock(&midi->input_lock);
- if ((status & midi->ipr_rx) && mpu401_input_avail(emu, midi)) {
- if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
- mpu401_clear_rx(emu, midi);
- } else {
- byte = mpu401_read_data(emu, midi);
- if (midi->substream_input)
- snd_rawmidi_receive(midi->substream_input, &byte, 1);
- }
- }
- spin_unlock(&midi->input_lock);
-
- spin_lock(&midi->output_lock);
- if ((status & midi->ipr_tx) && mpu401_output_ready(emu, midi)) {
- if (midi->substream_output &&
- snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
- mpu401_write_data(emu, midi, byte);
- } else {
- snd_emu10k1_intr_disable(emu, midi->tx_enable);
- }
- }
- spin_unlock(&midi->output_lock);
-}
-
-static void snd_emu10k1_midi_interrupt(struct snd_emu10k1 *emu, unsigned int status)
-{
- do_emu10k1_midi_interrupt(emu, &emu->midi, status);
-}
-
-static void snd_emu10k1_midi_interrupt2(struct snd_emu10k1 *emu, unsigned int status)
-{
- do_emu10k1_midi_interrupt(emu, &emu->midi2, status);
-}
-
-static int snd_emu10k1_midi_cmd(struct snd_emu10k1 * emu, struct snd_emu10k1_midi *midi, unsigned char cmd, int ack)
-{
- unsigned long flags;
- int timeout, ok;
-
- spin_lock_irqsave(&midi->input_lock, flags);
- mpu401_write_data(emu, midi, 0x00);
- /* mpu401_clear_rx(emu, midi); */
-
- mpu401_write_cmd(emu, midi, cmd);
- if (ack) {
- ok = 0;
- timeout = 10000;
- while (!ok && timeout-- > 0) {
- if (mpu401_input_avail(emu, midi)) {
- if (mpu401_read_data(emu, midi) == MPU401_ACK)
- ok = 1;
- }
- }
- if (!ok && mpu401_read_data(emu, midi) == MPU401_ACK)
- ok = 1;
- } else {
- ok = 1;
- }
- spin_unlock_irqrestore(&midi->input_lock, flags);
- if (!ok) {
- snd_printk(KERN_ERR "midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n",
- cmd, emu->port,
- mpu401_read_stat(emu, midi),
- mpu401_read_data(emu, midi));
- return 1;
- }
- return 0;
-}
-
-static int snd_emu10k1_midi_input_open(struct snd_rawmidi_substream *substream)
-{
- struct snd_emu10k1 *emu;
- struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
- unsigned long flags;
-
- emu = midi->emu;
- if (snd_BUG_ON(!emu))
- return -ENXIO;
- spin_lock_irqsave(&midi->open_lock, flags);
- midi->midi_mode |= EMU10K1_MIDI_MODE_INPUT;
- midi->substream_input = substream;
- if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1))
- goto error_out;
- if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
- goto error_out;
- } else {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- }
- return 0;
-
-error_out:
- return -EIO;
-}
-
-static int snd_emu10k1_midi_output_open(struct snd_rawmidi_substream *substream)
-{
- struct snd_emu10k1 *emu;
- struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
- unsigned long flags;
-
- emu = midi->emu;
- if (snd_BUG_ON(!emu))
- return -ENXIO;
- spin_lock_irqsave(&midi->open_lock, flags);
- midi->midi_mode |= EMU10K1_MIDI_MODE_OUTPUT;
- midi->substream_output = substream;
- if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1))
- goto error_out;
- if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
- goto error_out;
- } else {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- }
- return 0;
-
-error_out:
- return -EIO;
-}
-
-static int snd_emu10k1_midi_input_close(struct snd_rawmidi_substream *substream)
-{
- struct snd_emu10k1 *emu;
- struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
- unsigned long flags;
- int err = 0;
-
- emu = midi->emu;
- if (snd_BUG_ON(!emu))
- return -ENXIO;
- spin_lock_irqsave(&midi->open_lock, flags);
- snd_emu10k1_intr_disable(emu, midi->rx_enable);
- midi->midi_mode &= ~EMU10K1_MIDI_MODE_INPUT;
- midi->substream_input = NULL;
- if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- err = snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);
- } else {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- }
- return err;
-}
-
-static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream)
-{
- struct snd_emu10k1 *emu;
- struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
- unsigned long flags;
- int err = 0;
-
- emu = midi->emu;
- if (snd_BUG_ON(!emu))
- return -ENXIO;
- spin_lock_irqsave(&midi->open_lock, flags);
- snd_emu10k1_intr_disable(emu, midi->tx_enable);
- midi->midi_mode &= ~EMU10K1_MIDI_MODE_OUTPUT;
- midi->substream_output = NULL;
- if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- err = snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);
- } else {
- spin_unlock_irqrestore(&midi->open_lock, flags);
- }
- return err;
-}
-
-static void snd_emu10k1_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct snd_emu10k1 *emu;
- struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
- emu = midi->emu;
- if (snd_BUG_ON(!emu))
- return;
-
- if (up)
- snd_emu10k1_intr_enable(emu, midi->rx_enable);
- else
- snd_emu10k1_intr_disable(emu, midi->rx_enable);
-}
-
-static void snd_emu10k1_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct snd_emu10k1 *emu;
- struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
- unsigned long flags;
-
- emu = midi->emu;
- if (snd_BUG_ON(!emu))
- return;
-
- if (up) {
- int max = 4;
- unsigned char byte;
-
- /* try to send some amount of bytes here before interrupts */
- spin_lock_irqsave(&midi->output_lock, flags);
- while (max > 0) {
- if (mpu401_output_ready(emu, midi)) {
- if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT) ||
- snd_rawmidi_transmit(substream, &byte, 1) != 1) {
- /* no more data */
- spin_unlock_irqrestore(&midi->output_lock, flags);
- return;
- }
- mpu401_write_data(emu, midi, byte);
- max--;
- } else {
- break;
- }
- }
- spin_unlock_irqrestore(&midi->output_lock, flags);
- snd_emu10k1_intr_enable(emu, midi->tx_enable);
- } else {
- snd_emu10k1_intr_disable(emu, midi->tx_enable);
- }
-}
-
-/*
-
- */
-
-static struct snd_rawmidi_ops snd_emu10k1_midi_output =
-{
- .open = snd_emu10k1_midi_output_open,
- .close = snd_emu10k1_midi_output_close,
- .trigger = snd_emu10k1_midi_output_trigger,
-};
-
-static struct snd_rawmidi_ops snd_emu10k1_midi_input =
-{
- .open = snd_emu10k1_midi_input_open,
- .close = snd_emu10k1_midi_input_close,
- .trigger = snd_emu10k1_midi_input_trigger,
-};
-
-static void snd_emu10k1_midi_free(struct snd_rawmidi *rmidi)
-{
- struct snd_emu10k1_midi *midi = rmidi->private_data;
- midi->interrupt = NULL;
- midi->rmidi = NULL;
-}
-
-static int __devinit emu10k1_midi_init(struct snd_emu10k1 *emu, struct snd_emu10k1_midi *midi, int device, char *name)
-{
- struct snd_rawmidi *rmidi;
- int err;
-
- if ((err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi)) < 0)
- return err;
- midi->emu = emu;
- spin_lock_init(&midi->open_lock);
- spin_lock_init(&midi->input_lock);
- spin_lock_init(&midi->output_lock);
- strcpy(rmidi->name, name);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_emu10k1_midi_output);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_emu10k1_midi_input);
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
- rmidi->private_data = midi;
- rmidi->private_free = snd_emu10k1_midi_free;
- midi->rmidi = rmidi;
- return 0;
-}
-
-int __devinit snd_emu10k1_midi(struct snd_emu10k1 *emu)
-{
- struct snd_emu10k1_midi *midi = &emu->midi;
- int err;
-
- if ((err = emu10k1_midi_init(emu, midi, 0, "EMU10K1 MPU-401 (UART)")) < 0)
- return err;
-
- midi->tx_enable = INTE_MIDITXENABLE;
- midi->rx_enable = INTE_MIDIRXENABLE;
- midi->port = MUDATA;
- midi->ipr_tx = IPR_MIDITRANSBUFEMPTY;
- midi->ipr_rx = IPR_MIDIRECVBUFEMPTY;
- midi->interrupt = snd_emu10k1_midi_interrupt;
- return 0;
-}
-
-int __devinit snd_emu10k1_audigy_midi(struct snd_emu10k1 *emu)
-{
- struct snd_emu10k1_midi *midi;
- int err;
-
- midi = &emu->midi;
- if ((err = emu10k1_midi_init(emu, midi, 0, "Audigy MPU-401 (UART)")) < 0)
- return err;
-
- midi->tx_enable = INTE_MIDITXENABLE;
- midi->rx_enable = INTE_MIDIRXENABLE;
- midi->port = A_MUDATA1;
- midi->ipr_tx = IPR_MIDITRANSBUFEMPTY;
- midi->ipr_rx = IPR_MIDIRECVBUFEMPTY;
- midi->interrupt = snd_emu10k1_midi_interrupt;
-
- midi = &emu->midi2;
- if ((err = emu10k1_midi_init(emu, midi, 1, "Audigy MPU-401 #2")) < 0)
- return err;
-
- midi->tx_enable = INTE_A_MIDITXENABLE2;
- midi->rx_enable = INTE_A_MIDIRXENABLE2;
- midi->port = A_MUDATA2;
- midi->ipr_tx = IPR_A_MIDITRANSBUFEMPTY2;
- midi->ipr_rx = IPR_A_MIDIRECVBUFEMPTY2;
- midi->interrupt = snd_emu10k1_midi_interrupt2;
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/emupcm.c b/ANDROID_3.4.5/sound/pci/emu10k1/emupcm.c
deleted file mode 100644
index e22b8e2b..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/emupcm.c
+++ /dev/null
@@ -1,1870 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Creative Labs, Inc.
- * Routines for control of EMU10K1 chips / PCM routines
- * Multichannel PCM support Copyright (c) Lee Revell <rlrevell@joe-job.com>
- *
- * BUGS:
- * --
- *
- * TODO:
- * --
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/init.h>
-#include <sound/core.h>
-#include <sound/emu10k1.h>
-
-static void snd_emu10k1_pcm_interrupt(struct snd_emu10k1 *emu,
- struct snd_emu10k1_voice *voice)
-{
- struct snd_emu10k1_pcm *epcm;
-
- if ((epcm = voice->epcm) == NULL)
- return;
- if (epcm->substream == NULL)
- return;
-#if 0
- printk(KERN_DEBUG "IRQ: position = 0x%x, period = 0x%x, size = 0x%x\n",
- epcm->substream->runtime->hw->pointer(emu, epcm->substream),
- snd_pcm_lib_period_bytes(epcm->substream),
- snd_pcm_lib_buffer_bytes(epcm->substream));
-#endif
- snd_pcm_period_elapsed(epcm->substream);
-}
-
-static void snd_emu10k1_pcm_ac97adc_interrupt(struct snd_emu10k1 *emu,
- unsigned int status)
-{
-#if 0
- if (status & IPR_ADCBUFHALFFULL) {
- if (emu->pcm_capture_substream->runtime->mode == SNDRV_PCM_MODE_FRAME)
- return;
- }
-#endif
- snd_pcm_period_elapsed(emu->pcm_capture_substream);
-}
-
-static void snd_emu10k1_pcm_ac97mic_interrupt(struct snd_emu10k1 *emu,
- unsigned int status)
-{
-#if 0
- if (status & IPR_MICBUFHALFFULL) {
- if (emu->pcm_capture_mic_substream->runtime->mode == SNDRV_PCM_MODE_FRAME)
- return;
- }
-#endif
- snd_pcm_period_elapsed(emu->pcm_capture_mic_substream);
-}
-
-static void snd_emu10k1_pcm_efx_interrupt(struct snd_emu10k1 *emu,
- unsigned int status)
-{
-#if 0
- if (status & IPR_EFXBUFHALFFULL) {
- if (emu->pcm_capture_efx_substream->runtime->mode == SNDRV_PCM_MODE_FRAME)
- return;
- }
-#endif
- snd_pcm_period_elapsed(emu->pcm_capture_efx_substream);
-}
-
-static snd_pcm_uframes_t snd_emu10k1_efx_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_emu10k1_pcm *epcm = runtime->private_data;
- unsigned int ptr;
-
- if (!epcm->running)
- return 0;
- ptr = snd_emu10k1_ptr_read(emu, CCCA, epcm->voices[0]->number) & 0x00ffffff;
- ptr += runtime->buffer_size;
- ptr -= epcm->ccca_start_addr;
- ptr %= runtime->buffer_size;
-
- return ptr;
-}
-
-static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm * epcm, int voices)
-{
- int err, i;
-
- if (epcm->voices[1] != NULL && voices < 2) {
- snd_emu10k1_voice_free(epcm->emu, epcm->voices[1]);
- epcm->voices[1] = NULL;
- }
- for (i = 0; i < voices; i++) {
- if (epcm->voices[i] == NULL)
- break;
- }
- if (i == voices)
- return 0; /* already allocated */
-
- for (i = 0; i < ARRAY_SIZE(epcm->voices); i++) {
- if (epcm->voices[i]) {
- snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]);
- epcm->voices[i] = NULL;
- }
- }
- err = snd_emu10k1_voice_alloc(epcm->emu,
- epcm->type == PLAYBACK_EMUVOICE ? EMU10K1_PCM : EMU10K1_EFX,
- voices,
- &epcm->voices[0]);
-
- if (err < 0)
- return err;
- epcm->voices[0]->epcm = epcm;
- if (voices > 1) {
- for (i = 1; i < voices; i++) {
- epcm->voices[i] = &epcm->emu->voices[epcm->voices[0]->number + i];
- epcm->voices[i]->epcm = epcm;
- }
- }
- if (epcm->extra == NULL) {
- err = snd_emu10k1_voice_alloc(epcm->emu,
- epcm->type == PLAYBACK_EMUVOICE ? EMU10K1_PCM : EMU10K1_EFX,
- 1,
- &epcm->extra);
- if (err < 0) {
- /*
- printk(KERN_DEBUG "pcm_channel_alloc: "
- "failed extra: voices=%d, frame=%d\n",
- voices, frame);
- */
- for (i = 0; i < voices; i++) {
- snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]);
- epcm->voices[i] = NULL;
- }
- return err;
- }
- epcm->extra->epcm = epcm;
- epcm->extra->interrupt = snd_emu10k1_pcm_interrupt;
- }
- return 0;
-}
-
-static unsigned int capture_period_sizes[31] = {
- 384, 448, 512, 640,
- 384*2, 448*2, 512*2, 640*2,
- 384*4, 448*4, 512*4, 640*4,
- 384*8, 448*8, 512*8, 640*8,
- 384*16, 448*16, 512*16, 640*16,
- 384*32, 448*32, 512*32, 640*32,
- 384*64, 448*64, 512*64, 640*64,
- 384*128,448*128,512*128
-};
-
-static struct snd_pcm_hw_constraint_list hw_constraints_capture_period_sizes = {
- .count = 31,
- .list = capture_period_sizes,
- .mask = 0
-};
-
-static unsigned int capture_rates[8] = {
- 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000
-};
-
-static struct snd_pcm_hw_constraint_list hw_constraints_capture_rates = {
- .count = 8,
- .list = capture_rates,
- .mask = 0
-};
-
-static unsigned int snd_emu10k1_capture_rate_reg(unsigned int rate)
-{
- switch (rate) {
- case 8000: return ADCCR_SAMPLERATE_8;
- case 11025: return ADCCR_SAMPLERATE_11;
- case 16000: return ADCCR_SAMPLERATE_16;
- case 22050: return ADCCR_SAMPLERATE_22;
- case 24000: return ADCCR_SAMPLERATE_24;
- case 32000: return ADCCR_SAMPLERATE_32;
- case 44100: return ADCCR_SAMPLERATE_44;
- case 48000: return ADCCR_SAMPLERATE_48;
- default:
- snd_BUG();
- return ADCCR_SAMPLERATE_8;
- }
-}
-
-static unsigned int snd_emu10k1_audigy_capture_rate_reg(unsigned int rate)
-{
- switch (rate) {
- case 8000: return A_ADCCR_SAMPLERATE_8;
- case 11025: return A_ADCCR_SAMPLERATE_11;
- case 12000: return A_ADCCR_SAMPLERATE_12; /* really supported? */
- case 16000: return ADCCR_SAMPLERATE_16;
- case 22050: return ADCCR_SAMPLERATE_22;
- case 24000: return ADCCR_SAMPLERATE_24;
- case 32000: return ADCCR_SAMPLERATE_32;
- case 44100: return ADCCR_SAMPLERATE_44;
- case 48000: return ADCCR_SAMPLERATE_48;
- default:
- snd_BUG();
- return A_ADCCR_SAMPLERATE_8;
- }
-}
-
-static unsigned int emu10k1_calc_pitch_target(unsigned int rate)
-{
- unsigned int pitch_target;
-
- pitch_target = (rate << 8) / 375;
- pitch_target = (pitch_target >> 1) + (pitch_target & 1);
- return pitch_target;
-}
-
-#define PITCH_48000 0x00004000
-#define PITCH_96000 0x00008000
-#define PITCH_85000 0x00007155
-#define PITCH_80726 0x00006ba2
-#define PITCH_67882 0x00005a82
-#define PITCH_57081 0x00004c1c
-
-static unsigned int emu10k1_select_interprom(unsigned int pitch_target)
-{
- if (pitch_target == PITCH_48000)
- return CCCA_INTERPROM_0;
- else if (pitch_target < PITCH_48000)
- return CCCA_INTERPROM_1;
- else if (pitch_target >= PITCH_96000)
- return CCCA_INTERPROM_0;
- else if (pitch_target >= PITCH_85000)
- return CCCA_INTERPROM_6;
- else if (pitch_target >= PITCH_80726)
- return CCCA_INTERPROM_5;
- else if (pitch_target >= PITCH_67882)
- return CCCA_INTERPROM_4;
- else if (pitch_target >= PITCH_57081)
- return CCCA_INTERPROM_3;
- else
- return CCCA_INTERPROM_2;
-}
-
-/*
- * calculate cache invalidate size
- *
- * stereo: channel is stereo
- * w_16: using 16bit samples
- *
- * returns: cache invalidate size in samples
- */
-static inline int emu10k1_ccis(int stereo, int w_16)
-{
- if (w_16) {
- return stereo ? 24 : 26;
- } else {
- return stereo ? 24*2 : 26*2;
- }
-}
-
-static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
- int master, int extra,
- struct snd_emu10k1_voice *evoice,
- unsigned int start_addr,
- unsigned int end_addr,
- struct snd_emu10k1_pcm_mixer *mix)
-{
- struct snd_pcm_substream *substream = evoice->epcm->substream;
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int silent_page, tmp;
- int voice, stereo, w_16;
- unsigned char attn, send_amount[8];
- unsigned char send_routing[8];
- unsigned long flags;
- unsigned int pitch_target;
- unsigned int ccis;
-
- voice = evoice->number;
- stereo = runtime->channels == 2;
- w_16 = snd_pcm_format_width(runtime->format) == 16;
-
- if (!extra && stereo) {
- start_addr >>= 1;
- end_addr >>= 1;
- }
- if (w_16) {
- start_addr >>= 1;
- end_addr >>= 1;
- }
-
- spin_lock_irqsave(&emu->reg_lock, flags);
-
- /* volume parameters */
- if (extra) {
- attn = 0;
- memset(send_routing, 0, sizeof(send_routing));
- send_routing[0] = 0;
- send_routing[1] = 1;
- send_routing[2] = 2;
- send_routing[3] = 3;
- memset(send_amount, 0, sizeof(send_amount));
- } else {
- /* mono, left, right (master voice = left) */
- tmp = stereo ? (master ? 1 : 2) : 0;
- memcpy(send_routing, &mix->send_routing[tmp][0], 8);
- memcpy(send_amount, &mix->send_volume[tmp][0], 8);
- }
-
- ccis = emu10k1_ccis(stereo, w_16);
-
- if (master) {
- evoice->epcm->ccca_start_addr = start_addr + ccis;
- if (extra) {
- start_addr += ccis;
- end_addr += ccis + emu->delay_pcm_irq;
- }
- if (stereo && !extra) {
- snd_emu10k1_ptr_write(emu, CPF, voice, CPF_STEREO_MASK);
- snd_emu10k1_ptr_write(emu, CPF, (voice + 1), CPF_STEREO_MASK);
- } else {
- snd_emu10k1_ptr_write(emu, CPF, voice, 0);
- }
- }
-
- /* setup routing */
- if (emu->audigy) {
- snd_emu10k1_ptr_write(emu, A_FXRT1, voice,
- snd_emu10k1_compose_audigy_fxrt1(send_routing));
- snd_emu10k1_ptr_write(emu, A_FXRT2, voice,
- snd_emu10k1_compose_audigy_fxrt2(send_routing));
- snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, voice,
- ((unsigned int)send_amount[4] << 24) |
- ((unsigned int)send_amount[5] << 16) |
- ((unsigned int)send_amount[6] << 8) |
- (unsigned int)send_amount[7]);
- } else
- snd_emu10k1_ptr_write(emu, FXRT, voice,
- snd_emu10k1_compose_send_routing(send_routing));
- /* Stop CA */
- /* Assumption that PT is already 0 so no harm overwriting */
- snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]);
- snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24));
- snd_emu10k1_ptr_write(emu, PSST, voice,
- (start_addr + (extra ? emu->delay_pcm_irq : 0)) |
- (send_amount[2] << 24));
- if (emu->card_capabilities->emu_model)
- pitch_target = PITCH_48000; /* Disable interpolators on emu1010 card */
- else
- pitch_target = emu10k1_calc_pitch_target(runtime->rate);
- if (extra)
- snd_emu10k1_ptr_write(emu, CCCA, voice, start_addr |
- emu10k1_select_interprom(pitch_target) |
- (w_16 ? 0 : CCCA_8BITSELECT));
- else
- snd_emu10k1_ptr_write(emu, CCCA, voice, (start_addr + ccis) |
- emu10k1_select_interprom(pitch_target) |
- (w_16 ? 0 : CCCA_8BITSELECT));
- /* Clear filter delay memory */
- snd_emu10k1_ptr_write(emu, Z1, voice, 0);
- snd_emu10k1_ptr_write(emu, Z2, voice, 0);
- /* invalidate maps */
- silent_page = ((unsigned int)emu->silent_page.addr << 1) | MAP_PTI_MASK;
- snd_emu10k1_ptr_write(emu, MAPA, voice, silent_page);
- snd_emu10k1_ptr_write(emu, MAPB, voice, silent_page);
- /* modulation envelope */
- snd_emu10k1_ptr_write(emu, CVCF, voice, 0xffff);
- snd_emu10k1_ptr_write(emu, VTFT, voice, 0xffff);
- snd_emu10k1_ptr_write(emu, ATKHLDM, voice, 0);
- snd_emu10k1_ptr_write(emu, DCYSUSM, voice, 0x007f);
- snd_emu10k1_ptr_write(emu, LFOVAL1, voice, 0x8000);
- snd_emu10k1_ptr_write(emu, LFOVAL2, voice, 0x8000);
- snd_emu10k1_ptr_write(emu, FMMOD, voice, 0);
- snd_emu10k1_ptr_write(emu, TREMFRQ, voice, 0);
- snd_emu10k1_ptr_write(emu, FM2FRQ2, voice, 0);
- snd_emu10k1_ptr_write(emu, ENVVAL, voice, 0x8000);
- /* volume envelope */
- snd_emu10k1_ptr_write(emu, ATKHLDV, voice, 0x7f7f);
- snd_emu10k1_ptr_write(emu, ENVVOL, voice, 0x0000);
- /* filter envelope */
- snd_emu10k1_ptr_write(emu, PEFE_FILTERAMOUNT, voice, 0x7f);
- /* pitch envelope */
- snd_emu10k1_ptr_write(emu, PEFE_PITCHAMOUNT, voice, 0);
-
- spin_unlock_irqrestore(&emu->reg_lock, flags);
-}
-
-static int snd_emu10k1_playback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_emu10k1_pcm *epcm = runtime->private_data;
- int err;
-
- if ((err = snd_emu10k1_pcm_channel_alloc(epcm, params_channels(hw_params))) < 0)
- return err;
- if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
- return err;
- if (err > 0) { /* change */
- int mapped;
- if (epcm->memblk != NULL)
- snd_emu10k1_free_pages(emu, epcm->memblk);
- epcm->memblk = snd_emu10k1_alloc_pages(emu, substream);
- epcm->start_addr = 0;
- if (! epcm->memblk)
- return -ENOMEM;
- mapped = ((struct snd_emu10k1_memblk *)epcm->memblk)->mapped_page;
- if (mapped < 0)
- return -ENOMEM;
- epcm->start_addr = mapped << PAGE_SHIFT;
- }
- return 0;
-}
-
-static int snd_emu10k1_playback_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_emu10k1_pcm *epcm;
-
- if (runtime->private_data == NULL)
- return 0;
- epcm = runtime->private_data;
- if (epcm->extra) {
- snd_emu10k1_voice_free(epcm->emu, epcm->extra);
- epcm->extra = NULL;
- }
- if (epcm->voices[1]) {
- snd_emu10k1_voice_free(epcm->emu, epcm->voices[1]);
- epcm->voices[1] = NULL;
- }
- if (epcm->voices[0]) {
- snd_emu10k1_voice_free(epcm->emu, epcm->voices[0]);
- epcm->voices[0] = NULL;
- }
- if (epcm->memblk) {
- snd_emu10k1_free_pages(emu, epcm->memblk);
- epcm->memblk = NULL;
- epcm->start_addr = 0;
- }
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-static int snd_emu10k1_efx_playback_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_emu10k1_pcm *epcm;
- int i;
-
- if (runtime->private_data == NULL)
- return 0;
- epcm = runtime->private_data;
- if (epcm->extra) {
- snd_emu10k1_voice_free(epcm->emu, epcm->extra);
- epcm->extra = NULL;
- }
- for (i = 0; i < NUM_EFX_PLAYBACK; i++) {
- if (epcm->voices[i]) {
- snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]);
- epcm->voices[i] = NULL;
- }
- }
- if (epcm->memblk) {
- snd_emu10k1_free_pages(emu, epcm->memblk);
- epcm->memblk = NULL;
- epcm->start_addr = 0;
- }
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-static int snd_emu10k1_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_emu10k1_pcm *epcm = runtime->private_data;
- unsigned int start_addr, end_addr;
-
- start_addr = epcm->start_addr;
- end_addr = snd_pcm_lib_period_bytes(substream);
- if (runtime->channels == 2) {
- start_addr >>= 1;
- end_addr >>= 1;
- }
- end_addr += start_addr;
- snd_emu10k1_pcm_init_voice(emu, 1, 1, epcm->extra,
- start_addr, end_addr, NULL);
- start_addr = epcm->start_addr;
- end_addr = epcm->start_addr + snd_pcm_lib_buffer_bytes(substream);
- snd_emu10k1_pcm_init_voice(emu, 1, 0, epcm->voices[0],
- start_addr, end_addr,
- &emu->pcm_mixer[substream->number]);
- if (epcm->voices[1])
- snd_emu10k1_pcm_init_voice(emu, 0, 0, epcm->voices[1],
- start_addr, end_addr,
- &emu->pcm_mixer[substream->number]);
- return 0;
-}
-
-static int snd_emu10k1_efx_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_emu10k1_pcm *epcm = runtime->private_data;
- unsigned int start_addr, end_addr;
- unsigned int channel_size;
- int i;
-
- start_addr = epcm->start_addr;
- end_addr = epcm->start_addr + snd_pcm_lib_buffer_bytes(substream);
-
- /*
- * the kX driver leaves some space between voices
- */
- channel_size = ( end_addr - start_addr ) / NUM_EFX_PLAYBACK;
-
- snd_emu10k1_pcm_init_voice(emu, 1, 1, epcm->extra,
- start_addr, start_addr + (channel_size / 2), NULL);
-
- /* only difference with the master voice is we use it for the pointer */
- snd_emu10k1_pcm_init_voice(emu, 1, 0, epcm->voices[0],
- start_addr, start_addr + channel_size,
- &emu->efx_pcm_mixer[0]);
-
- start_addr += channel_size;
- for (i = 1; i < NUM_EFX_PLAYBACK; i++) {
- snd_emu10k1_pcm_init_voice(emu, 0, 0, epcm->voices[i],
- start_addr, start_addr + channel_size,
- &emu->efx_pcm_mixer[i]);
- start_addr += channel_size;
- }
-
- return 0;
-}
-
-static struct snd_pcm_hardware snd_emu10k1_efx_playback =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_NONINTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = NUM_EFX_PLAYBACK,
- .channels_max = NUM_EFX_PLAYBACK,
- .buffer_bytes_max = (64*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (64*1024),
- .periods_min = 2,
- .periods_max = 2,
- .fifo_size = 0,
-};
-
-static int snd_emu10k1_capture_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static int snd_emu10k1_capture_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_emu10k1_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_emu10k1_pcm *epcm = runtime->private_data;
- int idx;
-
- /* zeroing the buffer size will stop capture */
- snd_emu10k1_ptr_write(emu, epcm->capture_bs_reg, 0, 0);
- switch (epcm->type) {
- case CAPTURE_AC97ADC:
- snd_emu10k1_ptr_write(emu, ADCCR, 0, 0);
- break;
- case CAPTURE_EFX:
- if (emu->audigy) {
- snd_emu10k1_ptr_write(emu, A_FXWC1, 0, 0);
- snd_emu10k1_ptr_write(emu, A_FXWC2, 0, 0);
- } else
- snd_emu10k1_ptr_write(emu, FXWC, 0, 0);
- break;
- default:
- break;
- }
- snd_emu10k1_ptr_write(emu, epcm->capture_ba_reg, 0, runtime->dma_addr);
- epcm->capture_bufsize = snd_pcm_lib_buffer_bytes(substream);
- epcm->capture_bs_val = 0;
- for (idx = 0; idx < 31; idx++) {
- if (capture_period_sizes[idx] == epcm->capture_bufsize) {
- epcm->capture_bs_val = idx + 1;
- break;
- }
- }
- if (epcm->capture_bs_val == 0) {
- snd_BUG();
- epcm->capture_bs_val++;
- }
- if (epcm->type == CAPTURE_AC97ADC) {
- epcm->capture_cr_val = emu->audigy ? A_ADCCR_LCHANENABLE : ADCCR_LCHANENABLE;
- if (runtime->channels > 1)
- epcm->capture_cr_val |= emu->audigy ? A_ADCCR_RCHANENABLE : ADCCR_RCHANENABLE;
- epcm->capture_cr_val |= emu->audigy ?
- snd_emu10k1_audigy_capture_rate_reg(runtime->rate) :
- snd_emu10k1_capture_rate_reg(runtime->rate);
- }
- return 0;
-}
-
-static void snd_emu10k1_playback_invalidate_cache(struct snd_emu10k1 *emu, int extra, struct snd_emu10k1_voice *evoice)
-{
- struct snd_pcm_runtime *runtime;
- unsigned int voice, stereo, i, ccis, cra = 64, cs, sample;
-
- if (evoice == NULL)
- return;
- runtime = evoice->epcm->substream->runtime;
- voice = evoice->number;
- stereo = (!extra && runtime->channels == 2);
- sample = snd_pcm_format_width(runtime->format) == 16 ? 0 : 0x80808080;
- ccis = emu10k1_ccis(stereo, sample == 0);
- /* set cs to 2 * number of cache registers beside the invalidated */
- cs = (sample == 0) ? (32-ccis) : (64-ccis+1) >> 1;
- if (cs > 16) cs = 16;
- for (i = 0; i < cs; i++) {
- snd_emu10k1_ptr_write(emu, CD0 + i, voice, sample);
- if (stereo) {
- snd_emu10k1_ptr_write(emu, CD0 + i, voice + 1, sample);
- }
- }
- /* reset cache */
- snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, 0);
- snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice, cra);
- if (stereo) {
- snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice + 1, 0);
- snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice + 1, cra);
- }
- /* fill cache */
- snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, ccis);
- if (stereo) {
- snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice+1, ccis);
- }
-}
-
-static void snd_emu10k1_playback_prepare_voice(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *evoice,
- int master, int extra,
- struct snd_emu10k1_pcm_mixer *mix)
-{
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
- unsigned int attn, vattn;
- unsigned int voice, tmp;
-
- if (evoice == NULL) /* skip second voice for mono */
- return;
- substream = evoice->epcm->substream;
- runtime = substream->runtime;
- voice = evoice->number;
-
- attn = extra ? 0 : 0x00ff;
- tmp = runtime->channels == 2 ? (master ? 1 : 2) : 0;
- vattn = mix != NULL ? (mix->attn[tmp] << 16) : 0;
- snd_emu10k1_ptr_write(emu, IFATN, voice, attn);
- snd_emu10k1_ptr_write(emu, VTFT, voice, vattn | 0xffff);
- snd_emu10k1_ptr_write(emu, CVCF, voice, vattn | 0xffff);
- snd_emu10k1_ptr_write(emu, DCYSUSV, voice, 0x7f7f);
- snd_emu10k1_voice_clear_loop_stop(emu, voice);
-}
-
-static void snd_emu10k1_playback_trigger_voice(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *evoice, int master, int extra)
-{
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
- unsigned int voice, pitch, pitch_target;
-
- if (evoice == NULL) /* skip second voice for mono */
- return;
- substream = evoice->epcm->substream;
- runtime = substream->runtime;
- voice = evoice->number;
-
- pitch = snd_emu10k1_rate_to_pitch(runtime->rate) >> 8;
- if (emu->card_capabilities->emu_model)
- pitch_target = PITCH_48000; /* Disable interpolators on emu1010 card */
- else
- pitch_target = emu10k1_calc_pitch_target(runtime->rate);
- snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, pitch_target);
- if (master || evoice->epcm->type == PLAYBACK_EFX)
- snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, pitch_target);
- snd_emu10k1_ptr_write(emu, IP, voice, pitch);
- if (extra)
- snd_emu10k1_voice_intr_enable(emu, voice);
-}
-
-static void snd_emu10k1_playback_stop_voice(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *evoice)
-{
- unsigned int voice;
-
- if (evoice == NULL)
- return;
- voice = evoice->number;
- snd_emu10k1_voice_intr_disable(emu, voice);
- snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, 0);
- snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, 0);
- snd_emu10k1_ptr_write(emu, IFATN, voice, 0xffff);
- snd_emu10k1_ptr_write(emu, VTFT, voice, 0xffff);
- snd_emu10k1_ptr_write(emu, CVCF, voice, 0xffff);
- snd_emu10k1_ptr_write(emu, IP, voice, 0);
-}
-
-static inline void snd_emu10k1_playback_mangle_extra(struct snd_emu10k1 *emu,
- struct snd_emu10k1_pcm *epcm,
- struct snd_pcm_substream *substream,
- struct snd_pcm_runtime *runtime)
-{
- unsigned int ptr, period_pos;
-
- /* try to sychronize the current position for the interrupt
- source voice */
- period_pos = runtime->status->hw_ptr - runtime->hw_ptr_interrupt;
- period_pos %= runtime->period_size;
- ptr = snd_emu10k1_ptr_read(emu, CCCA, epcm->extra->number);
- ptr &= ~0x00ffffff;
- ptr |= epcm->ccca_start_addr + period_pos;
- snd_emu10k1_ptr_write(emu, CCCA, epcm->extra->number, ptr);
-}
-
-static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_emu10k1_pcm *epcm = runtime->private_data;
- struct snd_emu10k1_pcm_mixer *mix;
- int result = 0;
-
- /*
- printk(KERN_DEBUG "trigger - emu10k1 = 0x%x, cmd = %i, pointer = %i\n",
- (int)emu, cmd, substream->ops->pointer(substream))
- */
- spin_lock(&emu->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- snd_emu10k1_playback_invalidate_cache(emu, 1, epcm->extra); /* do we need this? */
- snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[0]);
- /* follow thru */
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
- if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE)
- snd_emu10k1_playback_mangle_extra(emu, epcm, substream, runtime);
- mix = &emu->pcm_mixer[substream->number];
- snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, 0, mix);
- snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, 0, mix);
- snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1, NULL);
- snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0], 1, 0);
- snd_emu10k1_playback_trigger_voice(emu, epcm->voices[1], 0, 0);
- snd_emu10k1_playback_trigger_voice(emu, epcm->extra, 1, 1);
- epcm->running = 1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- epcm->running = 0;
- snd_emu10k1_playback_stop_voice(emu, epcm->voices[0]);
- snd_emu10k1_playback_stop_voice(emu, epcm->voices[1]);
- snd_emu10k1_playback_stop_voice(emu, epcm->extra);
- break;
- default:
- result = -EINVAL;
- break;
- }
- spin_unlock(&emu->reg_lock);
- return result;
-}
-
-static int snd_emu10k1_capture_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_emu10k1_pcm *epcm = runtime->private_data;
- int result = 0;
-
- spin_lock(&emu->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- /* hmm this should cause full and half full interrupt to be raised? */
- outl(epcm->capture_ipr, emu->port + IPR);
- snd_emu10k1_intr_enable(emu, epcm->capture_inte);
- /*
- printk(KERN_DEBUG "adccr = 0x%x, adcbs = 0x%x\n",
- epcm->adccr, epcm->adcbs);
- */
- switch (epcm->type) {
- case CAPTURE_AC97ADC:
- snd_emu10k1_ptr_write(emu, ADCCR, 0, epcm->capture_cr_val);
- break;
- case CAPTURE_EFX:
- if (emu->audigy) {
- snd_emu10k1_ptr_write(emu, A_FXWC1, 0, epcm->capture_cr_val);
- snd_emu10k1_ptr_write(emu, A_FXWC2, 0, epcm->capture_cr_val2);
- snd_printdd("cr_val=0x%x, cr_val2=0x%x\n", epcm->capture_cr_val, epcm->capture_cr_val2);
- } else
- snd_emu10k1_ptr_write(emu, FXWC, 0, epcm->capture_cr_val);
- break;
- default:
- break;
- }
- snd_emu10k1_ptr_write(emu, epcm->capture_bs_reg, 0, epcm->capture_bs_val);
- epcm->running = 1;
- epcm->first_ptr = 1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- epcm->running = 0;
- snd_emu10k1_intr_disable(emu, epcm->capture_inte);
- outl(epcm->capture_ipr, emu->port + IPR);
- snd_emu10k1_ptr_write(emu, epcm->capture_bs_reg, 0, 0);
- switch (epcm->type) {
- case CAPTURE_AC97ADC:
- snd_emu10k1_ptr_write(emu, ADCCR, 0, 0);
- break;
- case CAPTURE_EFX:
- if (emu->audigy) {
- snd_emu10k1_ptr_write(emu, A_FXWC1, 0, 0);
- snd_emu10k1_ptr_write(emu, A_FXWC2, 0, 0);
- } else
- snd_emu10k1_ptr_write(emu, FXWC, 0, 0);
- break;
- default:
- break;
- }
- break;
- default:
- result = -EINVAL;
- }
- spin_unlock(&emu->reg_lock);
- return result;
-}
-
-static snd_pcm_uframes_t snd_emu10k1_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_emu10k1_pcm *epcm = runtime->private_data;
- unsigned int ptr;
-
- if (!epcm->running)
- return 0;
- ptr = snd_emu10k1_ptr_read(emu, CCCA, epcm->voices[0]->number) & 0x00ffffff;
-#if 0 /* Perex's code */
- ptr += runtime->buffer_size;
- ptr -= epcm->ccca_start_addr;
- ptr %= runtime->buffer_size;
-#else /* EMU10K1 Open Source code from Creative */
- if (ptr < epcm->ccca_start_addr)
- ptr += runtime->buffer_size - epcm->ccca_start_addr;
- else {
- ptr -= epcm->ccca_start_addr;
- if (ptr >= runtime->buffer_size)
- ptr -= runtime->buffer_size;
- }
-#endif
- /*
- printk(KERN_DEBUG
- "ptr = 0x%lx, buffer_size = 0x%lx, period_size = 0x%lx\n",
- (long)ptr, (long)runtime->buffer_size,
- (long)runtime->period_size);
- */
- return ptr;
-}
-
-
-static int snd_emu10k1_efx_playback_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_emu10k1_pcm *epcm = runtime->private_data;
- int i;
- int result = 0;
-
- spin_lock(&emu->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- /* prepare voices */
- for (i = 0; i < NUM_EFX_PLAYBACK; i++) {
- snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[i]);
- }
- snd_emu10k1_playback_invalidate_cache(emu, 1, epcm->extra);
-
- /* follow thru */
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
- snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1, NULL);
- snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 0, 0,
- &emu->efx_pcm_mixer[0]);
- for (i = 1; i < NUM_EFX_PLAYBACK; i++)
- snd_emu10k1_playback_prepare_voice(emu, epcm->voices[i], 0, 0,
- &emu->efx_pcm_mixer[i]);
- snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0], 0, 0);
- snd_emu10k1_playback_trigger_voice(emu, epcm->extra, 1, 1);
- for (i = 1; i < NUM_EFX_PLAYBACK; i++)
- snd_emu10k1_playback_trigger_voice(emu, epcm->voices[i], 0, 0);
- epcm->running = 1;
- break;
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- epcm->running = 0;
- for (i = 0; i < NUM_EFX_PLAYBACK; i++) {
- snd_emu10k1_playback_stop_voice(emu, epcm->voices[i]);
- }
- snd_emu10k1_playback_stop_voice(emu, epcm->extra);
- break;
- default:
- result = -EINVAL;
- break;
- }
- spin_unlock(&emu->reg_lock);
- return result;
-}
-
-
-static snd_pcm_uframes_t snd_emu10k1_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_emu10k1_pcm *epcm = runtime->private_data;
- unsigned int ptr;
-
- if (!epcm->running)
- return 0;
- if (epcm->first_ptr) {
- udelay(50); /* hack, it takes awhile until capture is started */
- epcm->first_ptr = 0;
- }
- ptr = snd_emu10k1_ptr_read(emu, epcm->capture_idx_reg, 0) & 0x0000ffff;
- return bytes_to_frames(runtime, ptr);
-}
-
-/*
- * Playback support device description
- */
-
-static struct snd_pcm_hardware snd_emu10k1_playback =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_96000,
- .rate_min = 4000,
- .rate_max = 96000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-/*
- * Capture support device description
- */
-
-static struct snd_pcm_hardware snd_emu10k1_capture =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (64*1024),
- .period_bytes_min = 384,
- .period_bytes_max = (64*1024),
- .periods_min = 2,
- .periods_max = 2,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_emu10k1_capture_efx =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
- SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
- .rate_min = 44100,
- .rate_max = 192000,
- .channels_min = 8,
- .channels_max = 8,
- .buffer_bytes_max = (64*1024),
- .period_bytes_min = 384,
- .period_bytes_max = (64*1024),
- .periods_min = 2,
- .periods_max = 2,
- .fifo_size = 0,
-};
-
-/*
- *
- */
-
-static void snd_emu10k1_pcm_mixer_notify1(struct snd_emu10k1 *emu, struct snd_kcontrol *kctl, int idx, int activate)
-{
- struct snd_ctl_elem_id id;
-
- if (! kctl)
- return;
- if (activate)
- kctl->vd[idx].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- else
- kctl->vd[idx].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO,
- snd_ctl_build_ioff(&id, kctl, idx));
-}
-
-static void snd_emu10k1_pcm_mixer_notify(struct snd_emu10k1 *emu, int idx, int activate)
-{
- snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_send_routing, idx, activate);
- snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_send_volume, idx, activate);
- snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_attn, idx, activate);
-}
-
-static void snd_emu10k1_pcm_efx_mixer_notify(struct snd_emu10k1 *emu, int idx, int activate)
-{
- snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_efx_send_routing, idx, activate);
- snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_efx_send_volume, idx, activate);
- snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_efx_attn, idx, activate);
-}
-
-static void snd_emu10k1_pcm_free_substream(struct snd_pcm_runtime *runtime)
-{
- kfree(runtime->private_data);
-}
-
-static int snd_emu10k1_efx_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_emu10k1_pcm_mixer *mix;
- int i;
-
- for (i = 0; i < NUM_EFX_PLAYBACK; i++) {
- mix = &emu->efx_pcm_mixer[i];
- mix->epcm = NULL;
- snd_emu10k1_pcm_efx_mixer_notify(emu, i, 0);
- }
- return 0;
-}
-
-static int snd_emu10k1_efx_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_emu10k1_pcm *epcm;
- struct snd_emu10k1_pcm_mixer *mix;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int i;
-
- epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
- if (epcm == NULL)
- return -ENOMEM;
- epcm->emu = emu;
- epcm->type = PLAYBACK_EFX;
- epcm->substream = substream;
-
- emu->pcm_playback_efx_substream = substream;
-
- runtime->private_data = epcm;
- runtime->private_free = snd_emu10k1_pcm_free_substream;
- runtime->hw = snd_emu10k1_efx_playback;
-
- for (i = 0; i < NUM_EFX_PLAYBACK; i++) {
- mix = &emu->efx_pcm_mixer[i];
- mix->send_routing[0][0] = i;
- memset(&mix->send_volume, 0, sizeof(mix->send_volume));
- mix->send_volume[0][0] = 255;
- mix->attn[0] = 0xffff;
- mix->epcm = epcm;
- snd_emu10k1_pcm_efx_mixer_notify(emu, i, 1);
- }
- return 0;
-}
-
-static int snd_emu10k1_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_emu10k1_pcm *epcm;
- struct snd_emu10k1_pcm_mixer *mix;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int i, err;
-
- epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
- if (epcm == NULL)
- return -ENOMEM;
- epcm->emu = emu;
- epcm->type = PLAYBACK_EMUVOICE;
- epcm->substream = substream;
- runtime->private_data = epcm;
- runtime->private_free = snd_emu10k1_pcm_free_substream;
- runtime->hw = snd_emu10k1_playback;
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) {
- kfree(epcm);
- return err;
- }
- if ((err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX)) < 0) {
- kfree(epcm);
- return err;
- }
- err = snd_pcm_hw_rule_noresample(runtime, 48000);
- if (err < 0) {
- kfree(epcm);
- return err;
- }
- mix = &emu->pcm_mixer[substream->number];
- for (i = 0; i < 4; i++)
- mix->send_routing[0][i] = mix->send_routing[1][i] = mix->send_routing[2][i] = i;
- memset(&mix->send_volume, 0, sizeof(mix->send_volume));
- mix->send_volume[0][0] = mix->send_volume[0][1] =
- mix->send_volume[1][0] = mix->send_volume[2][1] = 255;
- mix->attn[0] = mix->attn[1] = mix->attn[2] = 0xffff;
- mix->epcm = epcm;
- snd_emu10k1_pcm_mixer_notify(emu, substream->number, 1);
- return 0;
-}
-
-static int snd_emu10k1_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_emu10k1_pcm_mixer *mix = &emu->pcm_mixer[substream->number];
-
- mix->epcm = NULL;
- snd_emu10k1_pcm_mixer_notify(emu, substream->number, 0);
- return 0;
-}
-
-static int snd_emu10k1_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_emu10k1_pcm *epcm;
-
- epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
- if (epcm == NULL)
- return -ENOMEM;
- epcm->emu = emu;
- epcm->type = CAPTURE_AC97ADC;
- epcm->substream = substream;
- epcm->capture_ipr = IPR_ADCBUFFULL|IPR_ADCBUFHALFFULL;
- epcm->capture_inte = INTE_ADCBUFENABLE;
- epcm->capture_ba_reg = ADCBA;
- epcm->capture_bs_reg = ADCBS;
- epcm->capture_idx_reg = emu->audigy ? A_ADCIDX : ADCIDX;
- runtime->private_data = epcm;
- runtime->private_free = snd_emu10k1_pcm_free_substream;
- runtime->hw = snd_emu10k1_capture;
- emu->capture_interrupt = snd_emu10k1_pcm_ac97adc_interrupt;
- emu->pcm_capture_substream = substream;
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_capture_period_sizes);
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_capture_rates);
- return 0;
-}
-
-static int snd_emu10k1_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
-
- emu->capture_interrupt = NULL;
- emu->pcm_capture_substream = NULL;
- return 0;
-}
-
-static int snd_emu10k1_capture_mic_open(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_emu10k1_pcm *epcm;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
- if (epcm == NULL)
- return -ENOMEM;
- epcm->emu = emu;
- epcm->type = CAPTURE_AC97MIC;
- epcm->substream = substream;
- epcm->capture_ipr = IPR_MICBUFFULL|IPR_MICBUFHALFFULL;
- epcm->capture_inte = INTE_MICBUFENABLE;
- epcm->capture_ba_reg = MICBA;
- epcm->capture_bs_reg = MICBS;
- epcm->capture_idx_reg = emu->audigy ? A_MICIDX : MICIDX;
- substream->runtime->private_data = epcm;
- substream->runtime->private_free = snd_emu10k1_pcm_free_substream;
- runtime->hw = snd_emu10k1_capture;
- runtime->hw.rates = SNDRV_PCM_RATE_8000;
- runtime->hw.rate_min = runtime->hw.rate_max = 8000;
- runtime->hw.channels_min = 1;
- emu->capture_mic_interrupt = snd_emu10k1_pcm_ac97mic_interrupt;
- emu->pcm_capture_mic_substream = substream;
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_capture_period_sizes);
- return 0;
-}
-
-static int snd_emu10k1_capture_mic_close(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
-
- emu->capture_interrupt = NULL;
- emu->pcm_capture_mic_substream = NULL;
- return 0;
-}
-
-static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_emu10k1_pcm *epcm;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int nefx = emu->audigy ? 64 : 32;
- int idx;
-
- epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
- if (epcm == NULL)
- return -ENOMEM;
- epcm->emu = emu;
- epcm->type = CAPTURE_EFX;
- epcm->substream = substream;
- epcm->capture_ipr = IPR_EFXBUFFULL|IPR_EFXBUFHALFFULL;
- epcm->capture_inte = INTE_EFXBUFENABLE;
- epcm->capture_ba_reg = FXBA;
- epcm->capture_bs_reg = FXBS;
- epcm->capture_idx_reg = FXIDX;
- substream->runtime->private_data = epcm;
- substream->runtime->private_free = snd_emu10k1_pcm_free_substream;
- runtime->hw = snd_emu10k1_capture_efx;
- runtime->hw.rates = SNDRV_PCM_RATE_48000;
- runtime->hw.rate_min = runtime->hw.rate_max = 48000;
- spin_lock_irq(&emu->reg_lock);
- if (emu->card_capabilities->emu_model) {
- /* Nb. of channels has been increased to 16 */
- /* TODO
- * SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE
- * SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
- * SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
- * SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000
- * rate_min = 44100,
- * rate_max = 192000,
- * channels_min = 16,
- * channels_max = 16,
- * Need to add mixer control to fix sample rate
- *
- * There are 32 mono channels of 16bits each.
- * 24bit Audio uses 2x channels over 16bit
- * 96kHz uses 2x channels over 48kHz
- * 192kHz uses 4x channels over 48kHz
- * So, for 48kHz 24bit, one has 16 channels
- * for 96kHz 24bit, one has 8 channels
- * for 192kHz 24bit, one has 4 channels
- *
- */
-#if 1
- switch (emu->emu1010.internal_clock) {
- case 0:
- /* For 44.1kHz */
- runtime->hw.rates = SNDRV_PCM_RATE_44100;
- runtime->hw.rate_min = runtime->hw.rate_max = 44100;
- runtime->hw.channels_min =
- runtime->hw.channels_max = 16;
- break;
- case 1:
- /* For 48kHz */
- runtime->hw.rates = SNDRV_PCM_RATE_48000;
- runtime->hw.rate_min = runtime->hw.rate_max = 48000;
- runtime->hw.channels_min =
- runtime->hw.channels_max = 16;
- break;
- };
-#endif
-#if 0
- /* For 96kHz */
- runtime->hw.rates = SNDRV_PCM_RATE_96000;
- runtime->hw.rate_min = runtime->hw.rate_max = 96000;
- runtime->hw.channels_min = runtime->hw.channels_max = 4;
-#endif
-#if 0
- /* For 192kHz */
- runtime->hw.rates = SNDRV_PCM_RATE_192000;
- runtime->hw.rate_min = runtime->hw.rate_max = 192000;
- runtime->hw.channels_min = runtime->hw.channels_max = 2;
-#endif
- runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE;
- /* efx_voices_mask[0] is expected to be zero
- * efx_voices_mask[1] is expected to have 32bits set
- */
- } else {
- runtime->hw.channels_min = runtime->hw.channels_max = 0;
- for (idx = 0; idx < nefx; idx++) {
- if (emu->efx_voices_mask[idx/32] & (1 << (idx%32))) {
- runtime->hw.channels_min++;
- runtime->hw.channels_max++;
- }
- }
- }
- epcm->capture_cr_val = emu->efx_voices_mask[0];
- epcm->capture_cr_val2 = emu->efx_voices_mask[1];
- spin_unlock_irq(&emu->reg_lock);
- emu->capture_efx_interrupt = snd_emu10k1_pcm_efx_interrupt;
- emu->pcm_capture_efx_substream = substream;
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_capture_period_sizes);
- return 0;
-}
-
-static int snd_emu10k1_capture_efx_close(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
-
- emu->capture_interrupt = NULL;
- emu->pcm_capture_efx_substream = NULL;
- return 0;
-}
-
-static struct snd_pcm_ops snd_emu10k1_playback_ops = {
- .open = snd_emu10k1_playback_open,
- .close = snd_emu10k1_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_emu10k1_playback_hw_params,
- .hw_free = snd_emu10k1_playback_hw_free,
- .prepare = snd_emu10k1_playback_prepare,
- .trigger = snd_emu10k1_playback_trigger,
- .pointer = snd_emu10k1_playback_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
-static struct snd_pcm_ops snd_emu10k1_capture_ops = {
- .open = snd_emu10k1_capture_open,
- .close = snd_emu10k1_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_emu10k1_capture_hw_params,
- .hw_free = snd_emu10k1_capture_hw_free,
- .prepare = snd_emu10k1_capture_prepare,
- .trigger = snd_emu10k1_capture_trigger,
- .pointer = snd_emu10k1_capture_pointer,
-};
-
-/* EFX playback */
-static struct snd_pcm_ops snd_emu10k1_efx_playback_ops = {
- .open = snd_emu10k1_efx_playback_open,
- .close = snd_emu10k1_efx_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_emu10k1_playback_hw_params,
- .hw_free = snd_emu10k1_efx_playback_hw_free,
- .prepare = snd_emu10k1_efx_playback_prepare,
- .trigger = snd_emu10k1_efx_playback_trigger,
- .pointer = snd_emu10k1_efx_playback_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
-int __devinit snd_emu10k1_pcm(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm)
-{
- struct snd_pcm *pcm;
- struct snd_pcm_substream *substream;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
-
- if ((err = snd_pcm_new(emu->card, "emu10k1", device, 32, 1, &pcm)) < 0)
- return err;
-
- pcm->private_data = emu;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_ops);
-
- pcm->info_flags = 0;
- pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
- strcpy(pcm->name, "ADC Capture/Standard PCM Playback");
- emu->pcm = pcm;
-
- for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)
- if ((err = snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(emu->pci), 64*1024, 64*1024)) < 0)
- return err;
-
- for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; substream; substream = substream->next)
- snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024);
-
- if (rpcm)
- *rpcm = pcm;
-
- return 0;
-}
-
-int __devinit snd_emu10k1_pcm_multi(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm)
-{
- struct snd_pcm *pcm;
- struct snd_pcm_substream *substream;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
-
- if ((err = snd_pcm_new(emu->card, "emu10k1", device, 1, 0, &pcm)) < 0)
- return err;
-
- pcm->private_data = emu;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_efx_playback_ops);
-
- pcm->info_flags = 0;
- pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
- strcpy(pcm->name, "Multichannel Playback");
- emu->pcm_multi = pcm;
-
- for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)
- if ((err = snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(emu->pci), 64*1024, 64*1024)) < 0)
- return err;
-
- if (rpcm)
- *rpcm = pcm;
-
- return 0;
-}
-
-
-static struct snd_pcm_ops snd_emu10k1_capture_mic_ops = {
- .open = snd_emu10k1_capture_mic_open,
- .close = snd_emu10k1_capture_mic_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_emu10k1_capture_hw_params,
- .hw_free = snd_emu10k1_capture_hw_free,
- .prepare = snd_emu10k1_capture_prepare,
- .trigger = snd_emu10k1_capture_trigger,
- .pointer = snd_emu10k1_capture_pointer,
-};
-
-int __devinit snd_emu10k1_pcm_mic(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
-
- if ((err = snd_pcm_new(emu->card, "emu10k1 mic", device, 0, 1, &pcm)) < 0)
- return err;
-
- pcm->private_data = emu;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_mic_ops);
-
- pcm->info_flags = 0;
- strcpy(pcm->name, "Mic Capture");
- emu->pcm_mic = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024);
-
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-static int snd_emu10k1_pcm_efx_voices_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- int nefx = emu->audigy ? 64 : 32;
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = nefx;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int snd_emu10k1_pcm_efx_voices_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- int nefx = emu->audigy ? 64 : 32;
- int idx;
-
- spin_lock_irq(&emu->reg_lock);
- for (idx = 0; idx < nefx; idx++)
- ucontrol->value.integer.value[idx] = (emu->efx_voices_mask[idx / 32] & (1 << (idx % 32))) ? 1 : 0;
- spin_unlock_irq(&emu->reg_lock);
- return 0;
-}
-
-static int snd_emu10k1_pcm_efx_voices_mask_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int nval[2], bits;
- int nefx = emu->audigy ? 64 : 32;
- int nefxb = emu->audigy ? 7 : 6;
- int change, idx;
-
- nval[0] = nval[1] = 0;
- for (idx = 0, bits = 0; idx < nefx; idx++)
- if (ucontrol->value.integer.value[idx]) {
- nval[idx / 32] |= 1 << (idx % 32);
- bits++;
- }
-
- for (idx = 0; idx < nefxb; idx++)
- if (1 << idx == bits)
- break;
-
- if (idx >= nefxb)
- return -EINVAL;
-
- spin_lock_irq(&emu->reg_lock);
- change = (nval[0] != emu->efx_voices_mask[0]) ||
- (nval[1] != emu->efx_voices_mask[1]);
- emu->efx_voices_mask[0] = nval[0];
- emu->efx_voices_mask[1] = nval[1];
- spin_unlock_irq(&emu->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_emu10k1_pcm_efx_voices_mask = {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "Captured FX8010 Outputs",
- .info = snd_emu10k1_pcm_efx_voices_mask_info,
- .get = snd_emu10k1_pcm_efx_voices_mask_get,
- .put = snd_emu10k1_pcm_efx_voices_mask_put
-};
-
-static struct snd_pcm_ops snd_emu10k1_capture_efx_ops = {
- .open = snd_emu10k1_capture_efx_open,
- .close = snd_emu10k1_capture_efx_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_emu10k1_capture_hw_params,
- .hw_free = snd_emu10k1_capture_hw_free,
- .prepare = snd_emu10k1_capture_prepare,
- .trigger = snd_emu10k1_capture_trigger,
- .pointer = snd_emu10k1_capture_pointer,
-};
-
-
-/* EFX playback */
-
-#define INITIAL_TRAM_SHIFT 14
-#define INITIAL_TRAM_POS(size) ((((size) / 2) - INITIAL_TRAM_SHIFT) - 1)
-
-static void snd_emu10k1_fx8010_playback_irq(struct snd_emu10k1 *emu, void *private_data)
-{
- struct snd_pcm_substream *substream = private_data;
- snd_pcm_period_elapsed(substream);
-}
-
-static void snd_emu10k1_fx8010_playback_tram_poke1(unsigned short *dst_left,
- unsigned short *dst_right,
- unsigned short *src,
- unsigned int count,
- unsigned int tram_shift)
-{
- /*
- printk(KERN_DEBUG "tram_poke1: dst_left = 0x%p, dst_right = 0x%p, "
- "src = 0x%p, count = 0x%x\n",
- dst_left, dst_right, src, count);
- */
- if ((tram_shift & 1) == 0) {
- while (count--) {
- *dst_left-- = *src++;
- *dst_right-- = *src++;
- }
- } else {
- while (count--) {
- *dst_right-- = *src++;
- *dst_left-- = *src++;
- }
- }
-}
-
-static void fx8010_pb_trans_copy(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect *rec, size_t bytes)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number];
- unsigned int tram_size = pcm->buffer_size;
- unsigned short *src = (unsigned short *)(substream->runtime->dma_area + rec->sw_data);
- unsigned int frames = bytes >> 2, count;
- unsigned int tram_pos = pcm->tram_pos;
- unsigned int tram_shift = pcm->tram_shift;
-
- while (frames > tram_pos) {
- count = tram_pos + 1;
- snd_emu10k1_fx8010_playback_tram_poke1((unsigned short *)emu->fx8010.etram_pages.area + tram_pos,
- (unsigned short *)emu->fx8010.etram_pages.area + tram_pos + tram_size / 2,
- src, count, tram_shift);
- src += count * 2;
- frames -= count;
- tram_pos = (tram_size / 2) - 1;
- tram_shift++;
- }
- snd_emu10k1_fx8010_playback_tram_poke1((unsigned short *)emu->fx8010.etram_pages.area + tram_pos,
- (unsigned short *)emu->fx8010.etram_pages.area + tram_pos + tram_size / 2,
- src, frames, tram_shift);
- tram_pos -= frames;
- pcm->tram_pos = tram_pos;
- pcm->tram_shift = tram_shift;
-}
-
-static int snd_emu10k1_fx8010_playback_transfer(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number];
-
- snd_pcm_indirect_playback_transfer(substream, &pcm->pcm_rec, fx8010_pb_trans_copy);
- return 0;
-}
-
-static int snd_emu10k1_fx8010_playback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static int snd_emu10k1_fx8010_playback_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number];
- unsigned int i;
-
- for (i = 0; i < pcm->channels; i++)
- snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + 0x80 + pcm->etram[i], 0, 0);
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-static int snd_emu10k1_fx8010_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number];
- unsigned int i;
-
- /*
- printk(KERN_DEBUG "prepare: etram_pages = 0x%p, dma_area = 0x%x, "
- "buffer_size = 0x%x (0x%x)\n",
- emu->fx8010.etram_pages, runtime->dma_area,
- runtime->buffer_size, runtime->buffer_size << 2);
- */
- memset(&pcm->pcm_rec, 0, sizeof(pcm->pcm_rec));
- pcm->pcm_rec.hw_buffer_size = pcm->buffer_size * 2; /* byte size */
- pcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
- pcm->tram_pos = INITIAL_TRAM_POS(pcm->buffer_size);
- pcm->tram_shift = 0;
- snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_running, 0, 0); /* reset */
- snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 0); /* reset */
- snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_size, 0, runtime->buffer_size);
- snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_ptr, 0, 0); /* reset ptr number */
- snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_count, 0, runtime->period_size);
- snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_tmpcount, 0, runtime->period_size);
- for (i = 0; i < pcm->channels; i++)
- snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + 0x80 + pcm->etram[i], 0, (TANKMEMADDRREG_READ|TANKMEMADDRREG_ALIGN) + i * (runtime->buffer_size / pcm->channels));
- return 0;
-}
-
-static int snd_emu10k1_fx8010_playback_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number];
- int result = 0;
-
- spin_lock(&emu->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- /* follow thru */
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
-#ifdef EMU10K1_SET_AC3_IEC958
- {
- int i;
- for (i = 0; i < 3; i++) {
- unsigned int bits;
- bits = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
- SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS |
- 0x00001200 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT | SPCS_NOTAUDIODATA;
- snd_emu10k1_ptr_write(emu, SPCS0 + i, 0, bits);
- }
- }
-#endif
- result = snd_emu10k1_fx8010_register_irq_handler(emu, snd_emu10k1_fx8010_playback_irq, pcm->gpr_running, substream, &pcm->irq);
- if (result < 0)
- goto __err;
- snd_emu10k1_fx8010_playback_transfer(substream); /* roll the ball */
- snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 1);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- snd_emu10k1_fx8010_unregister_irq_handler(emu, pcm->irq); pcm->irq = NULL;
- snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 0);
- pcm->tram_pos = INITIAL_TRAM_POS(pcm->buffer_size);
- pcm->tram_shift = 0;
- break;
- default:
- result = -EINVAL;
- break;
- }
- __err:
- spin_unlock(&emu->reg_lock);
- return result;
-}
-
-static snd_pcm_uframes_t snd_emu10k1_fx8010_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number];
- size_t ptr; /* byte pointer */
-
- if (!snd_emu10k1_ptr_read(emu, emu->gpr_base + pcm->gpr_trigger, 0))
- return 0;
- ptr = snd_emu10k1_ptr_read(emu, emu->gpr_base + pcm->gpr_ptr, 0) << 2;
- return snd_pcm_indirect_playback_pointer(substream, &pcm->pcm_rec, ptr);
-}
-
-static struct snd_pcm_hardware snd_emu10k1_fx8010_playback =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_RESUME |
- /* SNDRV_PCM_INFO_MMAP_VALID | */ SNDRV_PCM_INFO_PAUSE),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 1,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 1024,
- .period_bytes_max = (128*1024),
- .periods_min = 2,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static int snd_emu10k1_fx8010_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number];
-
- runtime->hw = snd_emu10k1_fx8010_playback;
- runtime->hw.channels_min = runtime->hw.channels_max = pcm->channels;
- runtime->hw.period_bytes_max = (pcm->buffer_size * 2) / 2;
- spin_lock_irq(&emu->reg_lock);
- if (pcm->valid == 0) {
- spin_unlock_irq(&emu->reg_lock);
- return -ENODEV;
- }
- pcm->opened = 1;
- spin_unlock_irq(&emu->reg_lock);
- return 0;
-}
-
-static int snd_emu10k1_fx8010_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number];
-
- spin_lock_irq(&emu->reg_lock);
- pcm->opened = 0;
- spin_unlock_irq(&emu->reg_lock);
- return 0;
-}
-
-static struct snd_pcm_ops snd_emu10k1_fx8010_playback_ops = {
- .open = snd_emu10k1_fx8010_playback_open,
- .close = snd_emu10k1_fx8010_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_emu10k1_fx8010_playback_hw_params,
- .hw_free = snd_emu10k1_fx8010_playback_hw_free,
- .prepare = snd_emu10k1_fx8010_playback_prepare,
- .trigger = snd_emu10k1_fx8010_playback_trigger,
- .pointer = snd_emu10k1_fx8010_playback_pointer,
- .ack = snd_emu10k1_fx8010_playback_transfer,
-};
-
-int __devinit snd_emu10k1_pcm_efx(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm)
-{
- struct snd_pcm *pcm;
- struct snd_kcontrol *kctl;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
-
- if ((err = snd_pcm_new(emu->card, "emu10k1 efx", device, 8, 1, &pcm)) < 0)
- return err;
-
- pcm->private_data = emu;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_fx8010_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_efx_ops);
-
- pcm->info_flags = 0;
- strcpy(pcm->name, "Multichannel Capture/PT Playback");
- emu->pcm_efx = pcm;
- if (rpcm)
- *rpcm = pcm;
-
- /* EFX capture - record the "FXBUS2" channels, by default we connect the EXTINs
- * to these
- */
-
- /* emu->efx_voices_mask[0] = FXWC_DEFAULTROUTE_C | FXWC_DEFAULTROUTE_A; */
- if (emu->audigy) {
- emu->efx_voices_mask[0] = 0;
- if (emu->card_capabilities->emu_model)
- /* Pavel Hofman - 32 voices will be used for
- * capture (write mode) -
- * each bit = corresponding voice
- */
- emu->efx_voices_mask[1] = 0xffffffff;
- else
- emu->efx_voices_mask[1] = 0xffff;
- } else {
- emu->efx_voices_mask[0] = 0xffff0000;
- emu->efx_voices_mask[1] = 0;
- }
- /* For emu1010, the control has to set 32 upper bits (voices)
- * out of the 64 bits (voices) to true for the 16-channels capture
- * to work correctly. Correct A_FXWC2 initial value (0xffffffff)
- * is already defined but the snd_emu10k1_pcm_efx_voices_mask
- * control can override this register's value.
- */
- kctl = snd_ctl_new1(&snd_emu10k1_pcm_efx_voices_mask, emu);
- if (!kctl)
- return -ENOMEM;
- kctl->id.device = device;
- snd_ctl_add(emu->card, kctl);
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024);
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/emuproc.c b/ANDROID_3.4.5/sound/pci/emu10k1/emuproc.c
deleted file mode 100644
index bc38dd4d..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/emuproc.c
+++ /dev/null
@@ -1,671 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Creative Labs, Inc.
- * Routines for control of EMU10K1 chips / proc interface routines
- *
- * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk>
- * Added EMU 1010 support.
- *
- * BUGS:
- * --
- *
- * TODO:
- * --
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <sound/core.h>
-#include <sound/emu10k1.h>
-#include "p16v.h"
-
-#ifdef CONFIG_PROC_FS
-static void snd_emu10k1_proc_spdif_status(struct snd_emu10k1 * emu,
- struct snd_info_buffer *buffer,
- char *title,
- int status_reg,
- int rate_reg)
-{
- static char *clkaccy[4] = { "1000ppm", "50ppm", "variable", "unknown" };
- static int samplerate[16] = { 44100, 1, 48000, 32000, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
- static char *channel[16] = { "unspec", "left", "right", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15" };
- static char *emphasis[8] = { "none", "50/15 usec 2 channel", "2", "3", "4", "5", "6", "7" };
- unsigned int status, rate = 0;
-
- status = snd_emu10k1_ptr_read(emu, status_reg, 0);
-
- snd_iprintf(buffer, "\n%s\n", title);
-
- if (status != 0xffffffff) {
- snd_iprintf(buffer, "Professional Mode : %s\n", (status & SPCS_PROFESSIONAL) ? "yes" : "no");
- snd_iprintf(buffer, "Not Audio Data : %s\n", (status & SPCS_NOTAUDIODATA) ? "yes" : "no");
- snd_iprintf(buffer, "Copyright : %s\n", (status & SPCS_COPYRIGHT) ? "yes" : "no");
- snd_iprintf(buffer, "Emphasis : %s\n", emphasis[(status & SPCS_EMPHASISMASK) >> 3]);
- snd_iprintf(buffer, "Mode : %i\n", (status & SPCS_MODEMASK) >> 6);
- snd_iprintf(buffer, "Category Code : 0x%x\n", (status & SPCS_CATEGORYCODEMASK) >> 8);
- snd_iprintf(buffer, "Generation Status : %s\n", status & SPCS_GENERATIONSTATUS ? "original" : "copy");
- snd_iprintf(buffer, "Source Mask : %i\n", (status & SPCS_SOURCENUMMASK) >> 16);
- snd_iprintf(buffer, "Channel Number : %s\n", channel[(status & SPCS_CHANNELNUMMASK) >> 20]);
- snd_iprintf(buffer, "Sample Rate : %iHz\n", samplerate[(status & SPCS_SAMPLERATEMASK) >> 24]);
- snd_iprintf(buffer, "Clock Accuracy : %s\n", clkaccy[(status & SPCS_CLKACCYMASK) >> 28]);
-
- if (rate_reg > 0) {
- rate = snd_emu10k1_ptr_read(emu, rate_reg, 0);
- snd_iprintf(buffer, "S/PDIF Valid : %s\n", rate & SRCS_SPDIFVALID ? "on" : "off");
- snd_iprintf(buffer, "S/PDIF Locked : %s\n", rate & SRCS_SPDIFLOCKED ? "on" : "off");
- snd_iprintf(buffer, "Rate Locked : %s\n", rate & SRCS_RATELOCKED ? "on" : "off");
- /* From ((Rate * 48000 ) / 262144); */
- snd_iprintf(buffer, "Estimated Sample Rate : %d\n", ((rate & 0xFFFFF ) * 375) >> 11);
- }
- } else {
- snd_iprintf(buffer, "No signal detected.\n");
- }
-
-}
-
-static void snd_emu10k1_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- /* FIXME - output names are in emufx.c too */
- static char *creative_outs[32] = {
- /* 00 */ "AC97 Left",
- /* 01 */ "AC97 Right",
- /* 02 */ "Optical IEC958 Left",
- /* 03 */ "Optical IEC958 Right",
- /* 04 */ "Center",
- /* 05 */ "LFE",
- /* 06 */ "Headphone Left",
- /* 07 */ "Headphone Right",
- /* 08 */ "Surround Left",
- /* 09 */ "Surround Right",
- /* 10 */ "PCM Capture Left",
- /* 11 */ "PCM Capture Right",
- /* 12 */ "MIC Capture",
- /* 13 */ "AC97 Surround Left",
- /* 14 */ "AC97 Surround Right",
- /* 15 */ "???",
- /* 16 */ "???",
- /* 17 */ "Analog Center",
- /* 18 */ "Analog LFE",
- /* 19 */ "???",
- /* 20 */ "???",
- /* 21 */ "???",
- /* 22 */ "???",
- /* 23 */ "???",
- /* 24 */ "???",
- /* 25 */ "???",
- /* 26 */ "???",
- /* 27 */ "???",
- /* 28 */ "???",
- /* 29 */ "???",
- /* 30 */ "???",
- /* 31 */ "???"
- };
-
- static char *audigy_outs[64] = {
- /* 00 */ "Digital Front Left",
- /* 01 */ "Digital Front Right",
- /* 02 */ "Digital Center",
- /* 03 */ "Digital LEF",
- /* 04 */ "Headphone Left",
- /* 05 */ "Headphone Right",
- /* 06 */ "Digital Rear Left",
- /* 07 */ "Digital Rear Right",
- /* 08 */ "Front Left",
- /* 09 */ "Front Right",
- /* 10 */ "Center",
- /* 11 */ "LFE",
- /* 12 */ "???",
- /* 13 */ "???",
- /* 14 */ "Rear Left",
- /* 15 */ "Rear Right",
- /* 16 */ "AC97 Front Left",
- /* 17 */ "AC97 Front Right",
- /* 18 */ "ADC Caputre Left",
- /* 19 */ "ADC Capture Right",
- /* 20 */ "???",
- /* 21 */ "???",
- /* 22 */ "???",
- /* 23 */ "???",
- /* 24 */ "???",
- /* 25 */ "???",
- /* 26 */ "???",
- /* 27 */ "???",
- /* 28 */ "???",
- /* 29 */ "???",
- /* 30 */ "???",
- /* 31 */ "???",
- /* 32 */ "FXBUS2_0",
- /* 33 */ "FXBUS2_1",
- /* 34 */ "FXBUS2_2",
- /* 35 */ "FXBUS2_3",
- /* 36 */ "FXBUS2_4",
- /* 37 */ "FXBUS2_5",
- /* 38 */ "FXBUS2_6",
- /* 39 */ "FXBUS2_7",
- /* 40 */ "FXBUS2_8",
- /* 41 */ "FXBUS2_9",
- /* 42 */ "FXBUS2_10",
- /* 43 */ "FXBUS2_11",
- /* 44 */ "FXBUS2_12",
- /* 45 */ "FXBUS2_13",
- /* 46 */ "FXBUS2_14",
- /* 47 */ "FXBUS2_15",
- /* 48 */ "FXBUS2_16",
- /* 49 */ "FXBUS2_17",
- /* 50 */ "FXBUS2_18",
- /* 51 */ "FXBUS2_19",
- /* 52 */ "FXBUS2_20",
- /* 53 */ "FXBUS2_21",
- /* 54 */ "FXBUS2_22",
- /* 55 */ "FXBUS2_23",
- /* 56 */ "FXBUS2_24",
- /* 57 */ "FXBUS2_25",
- /* 58 */ "FXBUS2_26",
- /* 59 */ "FXBUS2_27",
- /* 60 */ "FXBUS2_28",
- /* 61 */ "FXBUS2_29",
- /* 62 */ "FXBUS2_30",
- /* 63 */ "FXBUS2_31"
- };
-
- struct snd_emu10k1 *emu = entry->private_data;
- unsigned int val, val1;
- int nefx = emu->audigy ? 64 : 32;
- char **outputs = emu->audigy ? audigy_outs : creative_outs;
- int idx;
-
- snd_iprintf(buffer, "EMU10K1\n\n");
- snd_iprintf(buffer, "Card : %s\n",
- emu->audigy ? "Audigy" : (emu->card_capabilities->ecard ? "EMU APS" : "Creative"));
- snd_iprintf(buffer, "Internal TRAM (words) : 0x%x\n", emu->fx8010.itram_size);
- snd_iprintf(buffer, "External TRAM (words) : 0x%x\n", (int)emu->fx8010.etram_pages.bytes / 2);
- snd_iprintf(buffer, "\n");
- snd_iprintf(buffer, "Effect Send Routing :\n");
- for (idx = 0; idx < NUM_G; idx++) {
- val = emu->audigy ?
- snd_emu10k1_ptr_read(emu, A_FXRT1, idx) :
- snd_emu10k1_ptr_read(emu, FXRT, idx);
- val1 = emu->audigy ?
- snd_emu10k1_ptr_read(emu, A_FXRT2, idx) :
- 0;
- if (emu->audigy) {
- snd_iprintf(buffer, "Ch%i: A=%i, B=%i, C=%i, D=%i, ",
- idx,
- val & 0x3f,
- (val >> 8) & 0x3f,
- (val >> 16) & 0x3f,
- (val >> 24) & 0x3f);
- snd_iprintf(buffer, "E=%i, F=%i, G=%i, H=%i\n",
- val1 & 0x3f,
- (val1 >> 8) & 0x3f,
- (val1 >> 16) & 0x3f,
- (val1 >> 24) & 0x3f);
- } else {
- snd_iprintf(buffer, "Ch%i: A=%i, B=%i, C=%i, D=%i\n",
- idx,
- (val >> 16) & 0x0f,
- (val >> 20) & 0x0f,
- (val >> 24) & 0x0f,
- (val >> 28) & 0x0f);
- }
- }
- snd_iprintf(buffer, "\nCaptured FX Outputs :\n");
- for (idx = 0; idx < nefx; idx++) {
- if (emu->efx_voices_mask[idx/32] & (1 << (idx%32)))
- snd_iprintf(buffer, " Output %02i [%s]\n", idx, outputs[idx]);
- }
- snd_iprintf(buffer, "\nAll FX Outputs :\n");
- for (idx = 0; idx < (emu->audigy ? 64 : 32); idx++)
- snd_iprintf(buffer, " Output %02i [%s]\n", idx, outputs[idx]);
-}
-
-static void snd_emu10k1_proc_spdif_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_emu10k1 *emu = entry->private_data;
- u32 value;
- u32 value2;
- unsigned long flags;
- u32 rate;
-
- if (emu->card_capabilities->emu_model) {
- spin_lock_irqsave(&emu->emu_lock, flags);
- snd_emu1010_fpga_read(emu, 0x38, &value);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- if ((value & 0x1) == 0) {
- spin_lock_irqsave(&emu->emu_lock, flags);
- snd_emu1010_fpga_read(emu, 0x2a, &value);
- snd_emu1010_fpga_read(emu, 0x2b, &value2);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- rate = 0x1770000 / (((value << 5) | value2)+1);
- snd_iprintf(buffer, "ADAT Locked : %u\n", rate);
- } else {
- snd_iprintf(buffer, "ADAT Unlocked\n");
- }
- spin_lock_irqsave(&emu->emu_lock, flags);
- snd_emu1010_fpga_read(emu, 0x20, &value);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- if ((value & 0x4) == 0) {
- spin_lock_irqsave(&emu->emu_lock, flags);
- snd_emu1010_fpga_read(emu, 0x28, &value);
- snd_emu1010_fpga_read(emu, 0x29, &value2);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- rate = 0x1770000 / (((value << 5) | value2)+1);
- snd_iprintf(buffer, "SPDIF Locked : %d\n", rate);
- } else {
- snd_iprintf(buffer, "SPDIF Unlocked\n");
- }
- } else {
- snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF In", CDCS, CDSRCS);
- snd_emu10k1_proc_spdif_status(emu, buffer, "Optical or Coax S/PDIF In", GPSCS, GPSRCS);
- }
-#if 0
- val = snd_emu10k1_ptr_read(emu, ZVSRCS, 0);
- snd_iprintf(buffer, "\nZoomed Video\n");
- snd_iprintf(buffer, "Rate Locked : %s\n", val & SRCS_RATELOCKED ? "on" : "off");
- snd_iprintf(buffer, "Estimated Sample Rate : 0x%x\n", val & SRCS_ESTSAMPLERATE);
-#endif
-}
-
-static void snd_emu10k1_proc_rates_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- static int samplerate[8] = { 44100, 48000, 96000, 192000, 4, 5, 6, 7 };
- struct snd_emu10k1 *emu = entry->private_data;
- unsigned int val, tmp, n;
- val = snd_emu10k1_ptr20_read(emu, CAPTURE_RATE_STATUS, 0);
- tmp = (val >> 16) & 0x8;
- for (n = 0; n < 4; n++) {
- tmp = val >> (16 + (n*4));
- if (tmp & 0x8) snd_iprintf(buffer, "Channel %d: Rate=%d\n", n, samplerate[tmp & 0x7]);
- else snd_iprintf(buffer, "Channel %d: No input\n", n);
- }
-}
-
-static void snd_emu10k1_proc_acode_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- u32 pc;
- struct snd_emu10k1 *emu = entry->private_data;
-
- snd_iprintf(buffer, "FX8010 Instruction List '%s'\n", emu->fx8010.name);
- snd_iprintf(buffer, " Code dump :\n");
- for (pc = 0; pc < (emu->audigy ? 1024 : 512); pc++) {
- u32 low, high;
-
- low = snd_emu10k1_efx_read(emu, pc * 2);
- high = snd_emu10k1_efx_read(emu, pc * 2 + 1);
- if (emu->audigy)
- snd_iprintf(buffer, " OP(0x%02x, 0x%03x, 0x%03x, 0x%03x, 0x%03x) /* 0x%04x: 0x%08x%08x */\n",
- (high >> 24) & 0x0f,
- (high >> 12) & 0x7ff,
- (high >> 0) & 0x7ff,
- (low >> 12) & 0x7ff,
- (low >> 0) & 0x7ff,
- pc,
- high, low);
- else
- snd_iprintf(buffer, " OP(0x%02x, 0x%03x, 0x%03x, 0x%03x, 0x%03x) /* 0x%04x: 0x%08x%08x */\n",
- (high >> 20) & 0x0f,
- (high >> 10) & 0x3ff,
- (high >> 0) & 0x3ff,
- (low >> 10) & 0x3ff,
- (low >> 0) & 0x3ff,
- pc,
- high, low);
- }
-}
-
-#define TOTAL_SIZE_GPR (0x100*4)
-#define A_TOTAL_SIZE_GPR (0x200*4)
-#define TOTAL_SIZE_TANKMEM_DATA (0xa0*4)
-#define TOTAL_SIZE_TANKMEM_ADDR (0xa0*4)
-#define A_TOTAL_SIZE_TANKMEM_DATA (0x100*4)
-#define A_TOTAL_SIZE_TANKMEM_ADDR (0x100*4)
-#define TOTAL_SIZE_CODE (0x200*8)
-#define A_TOTAL_SIZE_CODE (0x400*8)
-
-static ssize_t snd_emu10k1_fx8010_read(struct snd_info_entry *entry,
- void *file_private_data,
- struct file *file, char __user *buf,
- size_t count, loff_t pos)
-{
- struct snd_emu10k1 *emu = entry->private_data;
- unsigned int offset;
- int tram_addr = 0;
- unsigned int *tmp;
- long res;
- unsigned int idx;
-
- if (!strcmp(entry->name, "fx8010_tram_addr")) {
- offset = TANKMEMADDRREGBASE;
- tram_addr = 1;
- } else if (!strcmp(entry->name, "fx8010_tram_data")) {
- offset = TANKMEMDATAREGBASE;
- } else if (!strcmp(entry->name, "fx8010_code")) {
- offset = emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
- } else {
- offset = emu->audigy ? A_FXGPREGBASE : FXGPREGBASE;
- }
-
- tmp = kmalloc(count + 8, GFP_KERNEL);
- if (!tmp)
- return -ENOMEM;
- for (idx = 0; idx < ((pos & 3) + count + 3) >> 2; idx++) {
- unsigned int val;
- val = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0);
- if (tram_addr && emu->audigy) {
- val >>= 11;
- val |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20;
- }
- tmp[idx] = val;
- }
- if (copy_to_user(buf, ((char *)tmp) + (pos & 3), count))
- res = -EFAULT;
- else
- res = count;
- kfree(tmp);
- return res;
-}
-
-static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_emu10k1 *emu = entry->private_data;
- struct snd_emu10k1_voice *voice;
- int idx;
-
- snd_iprintf(buffer, "ch\tuse\tpcm\tefx\tsynth\tmidi\n");
- for (idx = 0; idx < NUM_G; idx++) {
- voice = &emu->voices[idx];
- snd_iprintf(buffer, "%i\t%i\t%i\t%i\t%i\t%i\n",
- idx,
- voice->use,
- voice->pcm,
- voice->efx,
- voice->synth,
- voice->midi);
- }
-}
-
-#ifdef CONFIG_SND_DEBUG
-static void snd_emu_proc_emu1010_reg_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_emu10k1 *emu = entry->private_data;
- u32 value;
- unsigned long flags;
- int i;
- snd_iprintf(buffer, "EMU1010 Registers:\n\n");
-
- for(i = 0; i < 0x40; i+=1) {
- spin_lock_irqsave(&emu->emu_lock, flags);
- snd_emu1010_fpga_read(emu, i, &value);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- snd_iprintf(buffer, "%02X: %08X, %02X\n", i, value, (value >> 8) & 0x7f);
- }
-}
-
-static void snd_emu_proc_io_reg_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_emu10k1 *emu = entry->private_data;
- unsigned long value;
- unsigned long flags;
- int i;
- snd_iprintf(buffer, "IO Registers:\n\n");
- for(i = 0; i < 0x40; i+=4) {
- spin_lock_irqsave(&emu->emu_lock, flags);
- value = inl(emu->port + i);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- snd_iprintf(buffer, "%02X: %08lX\n", i, value);
- }
-}
-
-static void snd_emu_proc_io_reg_write(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_emu10k1 *emu = entry->private_data;
- unsigned long flags;
- char line[64];
- u32 reg, val;
- while (!snd_info_get_line(buffer, line, sizeof(line))) {
- if (sscanf(line, "%x %x", &reg, &val) != 2)
- continue;
- if (reg < 0x40 && val <= 0xffffffff) {
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(val, emu->port + (reg & 0xfffffffc));
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- }
- }
-}
-
-static unsigned int snd_ptr_read(struct snd_emu10k1 * emu,
- unsigned int iobase,
- unsigned int reg,
- unsigned int chn)
-{
- unsigned long flags;
- unsigned int regptr, val;
-
- regptr = (reg << 16) | chn;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(regptr, emu->port + iobase + PTR);
- val = inl(emu->port + iobase + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- return val;
-}
-
-static void snd_ptr_write(struct snd_emu10k1 *emu,
- unsigned int iobase,
- unsigned int reg,
- unsigned int chn,
- unsigned int data)
-{
- unsigned int regptr;
- unsigned long flags;
-
- regptr = (reg << 16) | chn;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(regptr, emu->port + iobase + PTR);
- outl(data, emu->port + iobase + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-
-static void snd_emu_proc_ptr_reg_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer, int iobase, int offset, int length, int voices)
-{
- struct snd_emu10k1 *emu = entry->private_data;
- unsigned long value;
- int i,j;
- if (offset+length > 0xa0) {
- snd_iprintf(buffer, "Input values out of range\n");
- return;
- }
- snd_iprintf(buffer, "Registers 0x%x\n", iobase);
- for(i = offset; i < offset+length; i++) {
- snd_iprintf(buffer, "%02X: ",i);
- for (j = 0; j < voices; j++) {
- if(iobase == 0)
- value = snd_ptr_read(emu, 0, i, j);
- else
- value = snd_ptr_read(emu, 0x20, i, j);
- snd_iprintf(buffer, "%08lX ", value);
- }
- snd_iprintf(buffer, "\n");
- }
-}
-
-static void snd_emu_proc_ptr_reg_write(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer, int iobase)
-{
- struct snd_emu10k1 *emu = entry->private_data;
- char line[64];
- unsigned int reg, channel_id , val;
- while (!snd_info_get_line(buffer, line, sizeof(line))) {
- if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
- continue;
- if (reg < 0xa0 && val <= 0xffffffff && channel_id <= 3)
- snd_ptr_write(emu, iobase, reg, channel_id, val);
- }
-}
-
-static void snd_emu_proc_ptr_reg_write00(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- snd_emu_proc_ptr_reg_write(entry, buffer, 0);
-}
-
-static void snd_emu_proc_ptr_reg_write20(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- snd_emu_proc_ptr_reg_write(entry, buffer, 0x20);
-}
-
-
-static void snd_emu_proc_ptr_reg_read00a(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- snd_emu_proc_ptr_reg_read(entry, buffer, 0, 0, 0x40, 64);
-}
-
-static void snd_emu_proc_ptr_reg_read00b(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- snd_emu_proc_ptr_reg_read(entry, buffer, 0, 0x40, 0x40, 64);
-}
-
-static void snd_emu_proc_ptr_reg_read20a(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0, 0x40, 4);
-}
-
-static void snd_emu_proc_ptr_reg_read20b(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0x40, 0x40, 4);
-}
-
-static void snd_emu_proc_ptr_reg_read20c(struct snd_info_entry *entry,
- struct snd_info_buffer * buffer)
-{
- snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0x80, 0x20, 4);
-}
-#endif
-
-static struct snd_info_entry_ops snd_emu10k1_proc_ops_fx8010 = {
- .read = snd_emu10k1_fx8010_read,
-};
-
-int __devinit snd_emu10k1_proc_init(struct snd_emu10k1 * emu)
-{
- struct snd_info_entry *entry;
-#ifdef CONFIG_SND_DEBUG
- if (emu->card_capabilities->emu_model) {
- if (! snd_card_proc_new(emu->card, "emu1010_regs", &entry))
- snd_info_set_text_ops(entry, emu, snd_emu_proc_emu1010_reg_read);
- }
- if (! snd_card_proc_new(emu->card, "io_regs", &entry)) {
- snd_info_set_text_ops(entry, emu, snd_emu_proc_io_reg_read);
- entry->c.text.write = snd_emu_proc_io_reg_write;
- entry->mode |= S_IWUSR;
- }
- if (! snd_card_proc_new(emu->card, "ptr_regs00a", &entry)) {
- snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read00a);
- entry->c.text.write = snd_emu_proc_ptr_reg_write00;
- entry->mode |= S_IWUSR;
- }
- if (! snd_card_proc_new(emu->card, "ptr_regs00b", &entry)) {
- snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read00b);
- entry->c.text.write = snd_emu_proc_ptr_reg_write00;
- entry->mode |= S_IWUSR;
- }
- if (! snd_card_proc_new(emu->card, "ptr_regs20a", &entry)) {
- snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read20a);
- entry->c.text.write = snd_emu_proc_ptr_reg_write20;
- entry->mode |= S_IWUSR;
- }
- if (! snd_card_proc_new(emu->card, "ptr_regs20b", &entry)) {
- snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read20b);
- entry->c.text.write = snd_emu_proc_ptr_reg_write20;
- entry->mode |= S_IWUSR;
- }
- if (! snd_card_proc_new(emu->card, "ptr_regs20c", &entry)) {
- snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read20c);
- entry->c.text.write = snd_emu_proc_ptr_reg_write20;
- entry->mode |= S_IWUSR;
- }
-#endif
-
- if (! snd_card_proc_new(emu->card, "emu10k1", &entry))
- snd_info_set_text_ops(entry, emu, snd_emu10k1_proc_read);
-
- if (emu->card_capabilities->emu10k2_chip) {
- if (! snd_card_proc_new(emu->card, "spdif-in", &entry))
- snd_info_set_text_ops(entry, emu, snd_emu10k1_proc_spdif_read);
- }
- if (emu->card_capabilities->ca0151_chip) {
- if (! snd_card_proc_new(emu->card, "capture-rates", &entry))
- snd_info_set_text_ops(entry, emu, snd_emu10k1_proc_rates_read);
- }
-
- if (! snd_card_proc_new(emu->card, "voices", &entry))
- snd_info_set_text_ops(entry, emu, snd_emu10k1_proc_voices_read);
-
- if (! snd_card_proc_new(emu->card, "fx8010_gpr", &entry)) {
- entry->content = SNDRV_INFO_CONTENT_DATA;
- entry->private_data = emu;
- entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
- entry->size = emu->audigy ? A_TOTAL_SIZE_GPR : TOTAL_SIZE_GPR;
- entry->c.ops = &snd_emu10k1_proc_ops_fx8010;
- }
- if (! snd_card_proc_new(emu->card, "fx8010_tram_data", &entry)) {
- entry->content = SNDRV_INFO_CONTENT_DATA;
- entry->private_data = emu;
- entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
- entry->size = emu->audigy ? A_TOTAL_SIZE_TANKMEM_DATA : TOTAL_SIZE_TANKMEM_DATA ;
- entry->c.ops = &snd_emu10k1_proc_ops_fx8010;
- }
- if (! snd_card_proc_new(emu->card, "fx8010_tram_addr", &entry)) {
- entry->content = SNDRV_INFO_CONTENT_DATA;
- entry->private_data = emu;
- entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
- entry->size = emu->audigy ? A_TOTAL_SIZE_TANKMEM_ADDR : TOTAL_SIZE_TANKMEM_ADDR ;
- entry->c.ops = &snd_emu10k1_proc_ops_fx8010;
- }
- if (! snd_card_proc_new(emu->card, "fx8010_code", &entry)) {
- entry->content = SNDRV_INFO_CONTENT_DATA;
- entry->private_data = emu;
- entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
- entry->size = emu->audigy ? A_TOTAL_SIZE_CODE : TOTAL_SIZE_CODE;
- entry->c.ops = &snd_emu10k1_proc_ops_fx8010;
- }
- if (! snd_card_proc_new(emu->card, "fx8010_acode", &entry)) {
- entry->content = SNDRV_INFO_CONTENT_TEXT;
- entry->private_data = emu;
- entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
- entry->c.text.read = snd_emu10k1_proc_acode_read;
- }
- return 0;
-}
-#endif /* CONFIG_PROC_FS */
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/io.c b/ANDROID_3.4.5/sound/pci/emu10k1/io.c
deleted file mode 100644
index e4fba49f..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/io.c
+++ /dev/null
@@ -1,583 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Creative Labs, Inc.
- * Routines for control of EMU10K1 chips
- *
- * BUGS:
- * --
- *
- * TODO:
- * --
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/emu10k1.h>
-#include <linux/delay.h>
-#include <linux/export.h>
-#include "p17v.h"
-
-unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn)
-{
- unsigned long flags;
- unsigned int regptr, val;
- unsigned int mask;
-
- mask = emu->audigy ? A_PTR_ADDRESS_MASK : PTR_ADDRESS_MASK;
- regptr = ((reg << 16) & mask) | (chn & PTR_CHANNELNUM_MASK);
-
- if (reg & 0xff000000) {
- unsigned char size, offset;
-
- size = (reg >> 24) & 0x3f;
- offset = (reg >> 16) & 0x1f;
- mask = ((1 << size) - 1) << offset;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(regptr, emu->port + PTR);
- val = inl(emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-
- return (val & mask) >> offset;
- } else {
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(regptr, emu->port + PTR);
- val = inl(emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- return val;
- }
-}
-
-EXPORT_SYMBOL(snd_emu10k1_ptr_read);
-
-void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data)
-{
- unsigned int regptr;
- unsigned long flags;
- unsigned int mask;
-
- if (!emu) {
- snd_printk(KERN_ERR "ptr_write: emu is null!\n");
- dump_stack();
- return;
- }
- mask = emu->audigy ? A_PTR_ADDRESS_MASK : PTR_ADDRESS_MASK;
- regptr = ((reg << 16) & mask) | (chn & PTR_CHANNELNUM_MASK);
-
- if (reg & 0xff000000) {
- unsigned char size, offset;
-
- size = (reg >> 24) & 0x3f;
- offset = (reg >> 16) & 0x1f;
- mask = ((1 << size) - 1) << offset;
- data = (data << offset) & mask;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(regptr, emu->port + PTR);
- data |= inl(emu->port + DATA) & ~mask;
- outl(data, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- } else {
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(regptr, emu->port + PTR);
- outl(data, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- }
-}
-
-EXPORT_SYMBOL(snd_emu10k1_ptr_write);
-
-unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu,
- unsigned int reg,
- unsigned int chn)
-{
- unsigned long flags;
- unsigned int regptr, val;
-
- regptr = (reg << 16) | chn;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(regptr, emu->port + 0x20 + PTR);
- val = inl(emu->port + 0x20 + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- return val;
-}
-
-void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu,
- unsigned int reg,
- unsigned int chn,
- unsigned int data)
-{
- unsigned int regptr;
- unsigned long flags;
-
- regptr = (reg << 16) | chn;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(regptr, emu->port + 0x20 + PTR);
- outl(data, emu->port + 0x20 + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-int snd_emu10k1_spi_write(struct snd_emu10k1 * emu,
- unsigned int data)
-{
- unsigned int reset, set;
- unsigned int reg, tmp;
- int n, result;
- int err = 0;
-
- /* This function is not re-entrant, so protect against it. */
- spin_lock(&emu->spi_lock);
- if (emu->card_capabilities->ca0108_chip)
- reg = 0x3c; /* PTR20, reg 0x3c */
- else {
- /* For other chip types the SPI register
- * is currently unknown. */
- err = 1;
- goto spi_write_exit;
- }
- if (data > 0xffff) {
- /* Only 16bit values allowed */
- err = 1;
- goto spi_write_exit;
- }
-
- tmp = snd_emu10k1_ptr20_read(emu, reg, 0);
- reset = (tmp & ~0x3ffff) | 0x20000; /* Set xxx20000 */
- set = reset | 0x10000; /* Set xxx1xxxx */
- snd_emu10k1_ptr20_write(emu, reg, 0, reset | data);
- tmp = snd_emu10k1_ptr20_read(emu, reg, 0); /* write post */
- snd_emu10k1_ptr20_write(emu, reg, 0, set | data);
- result = 1;
- /* Wait for status bit to return to 0 */
- for (n = 0; n < 100; n++) {
- udelay(10);
- tmp = snd_emu10k1_ptr20_read(emu, reg, 0);
- if (!(tmp & 0x10000)) {
- result = 0;
- break;
- }
- }
- if (result) {
- /* Timed out */
- err = 1;
- goto spi_write_exit;
- }
- snd_emu10k1_ptr20_write(emu, reg, 0, reset | data);
- tmp = snd_emu10k1_ptr20_read(emu, reg, 0); /* Write post */
- err = 0;
-spi_write_exit:
- spin_unlock(&emu->spi_lock);
- return err;
-}
-
-/* The ADC does not support i2c read, so only write is implemented */
-int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu,
- u32 reg,
- u32 value)
-{
- u32 tmp;
- int timeout = 0;
- int status;
- int retry;
- int err = 0;
-
- if ((reg > 0x7f) || (value > 0x1ff)) {
- snd_printk(KERN_ERR "i2c_write: invalid values.\n");
- return -EINVAL;
- }
-
- /* This function is not re-entrant, so protect against it. */
- spin_lock(&emu->i2c_lock);
-
- tmp = reg << 25 | value << 16;
-
- /* This controls the I2C connected to the WM8775 ADC Codec */
- snd_emu10k1_ptr20_write(emu, P17V_I2C_1, 0, tmp);
- tmp = snd_emu10k1_ptr20_read(emu, P17V_I2C_1, 0); /* write post */
-
- for (retry = 0; retry < 10; retry++) {
- /* Send the data to i2c */
- tmp = 0;
- tmp = tmp | (I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD);
- snd_emu10k1_ptr20_write(emu, P17V_I2C_ADDR, 0, tmp);
-
- /* Wait till the transaction ends */
- while (1) {
- mdelay(1);
- status = snd_emu10k1_ptr20_read(emu, P17V_I2C_ADDR, 0);
- timeout++;
- if ((status & I2C_A_ADC_START) == 0)
- break;
-
- if (timeout > 1000) {
- snd_printk(KERN_WARNING
- "emu10k1:I2C:timeout status=0x%x\n",
- status);
- break;
- }
- }
- //Read back and see if the transaction is successful
- if ((status & I2C_A_ADC_ABORT) == 0)
- break;
- }
-
- if (retry == 10) {
- snd_printk(KERN_ERR "Writing to ADC failed!\n");
- snd_printk(KERN_ERR "status=0x%x, reg=%d, value=%d\n",
- status, reg, value);
- /* dump_stack(); */
- err = -EINVAL;
- }
-
- spin_unlock(&emu->i2c_lock);
- return err;
-}
-
-int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, u32 reg, u32 value)
-{
- unsigned long flags;
-
- if (reg > 0x3f)
- return 1;
- reg += 0x40; /* 0x40 upwards are registers. */
- if (value > 0x3f) /* 0 to 0x3f are values */
- return 1;
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(reg, emu->port + A_IOCFG);
- udelay(10);
- outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
- udelay(10);
- outl(value, emu->port + A_IOCFG);
- udelay(10);
- outl(value | 0x80 , emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-
- return 0;
-}
-
-int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, u32 reg, u32 *value)
-{
- unsigned long flags;
- if (reg > 0x3f)
- return 1;
- reg += 0x40; /* 0x40 upwards are registers. */
- spin_lock_irqsave(&emu->emu_lock, flags);
- outl(reg, emu->port + A_IOCFG);
- udelay(10);
- outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
- udelay(10);
- *value = ((inl(emu->port + A_IOCFG) >> 8) & 0x7f);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-
- return 0;
-}
-
-/* Each Destination has one and only one Source,
- * but one Source can feed any number of Destinations simultaneously.
- */
-int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, u32 dst, u32 src)
-{
- snd_emu1010_fpga_write(emu, 0x00, ((dst >> 8) & 0x3f) );
- snd_emu1010_fpga_write(emu, 0x01, (dst & 0x3f) );
- snd_emu1010_fpga_write(emu, 0x02, ((src >> 8) & 0x3f) );
- snd_emu1010_fpga_write(emu, 0x03, (src & 0x3f) );
-
- return 0;
-}
-
-void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
-{
- unsigned long flags;
- unsigned int enable;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- enable = inl(emu->port + INTE) | intrenb;
- outl(enable, emu->port + INTE);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb)
-{
- unsigned long flags;
- unsigned int enable;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- enable = inl(emu->port + INTE) & ~intrenb;
- outl(enable, emu->port + INTE);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-void snd_emu10k1_voice_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum)
-{
- unsigned long flags;
- unsigned int val;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- /* voice interrupt */
- if (voicenum >= 32) {
- outl(CLIEH << 16, emu->port + PTR);
- val = inl(emu->port + DATA);
- val |= 1 << (voicenum - 32);
- } else {
- outl(CLIEL << 16, emu->port + PTR);
- val = inl(emu->port + DATA);
- val |= 1 << voicenum;
- }
- outl(val, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-void snd_emu10k1_voice_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum)
-{
- unsigned long flags;
- unsigned int val;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- /* voice interrupt */
- if (voicenum >= 32) {
- outl(CLIEH << 16, emu->port + PTR);
- val = inl(emu->port + DATA);
- val &= ~(1 << (voicenum - 32));
- } else {
- outl(CLIEL << 16, emu->port + PTR);
- val = inl(emu->port + DATA);
- val &= ~(1 << voicenum);
- }
- outl(val, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-void snd_emu10k1_voice_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- /* voice interrupt */
- if (voicenum >= 32) {
- outl(CLIPH << 16, emu->port + PTR);
- voicenum = 1 << (voicenum - 32);
- } else {
- outl(CLIPL << 16, emu->port + PTR);
- voicenum = 1 << voicenum;
- }
- outl(voicenum, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-void snd_emu10k1_voice_half_loop_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum)
-{
- unsigned long flags;
- unsigned int val;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- /* voice interrupt */
- if (voicenum >= 32) {
- outl(HLIEH << 16, emu->port + PTR);
- val = inl(emu->port + DATA);
- val |= 1 << (voicenum - 32);
- } else {
- outl(HLIEL << 16, emu->port + PTR);
- val = inl(emu->port + DATA);
- val |= 1 << voicenum;
- }
- outl(val, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-void snd_emu10k1_voice_half_loop_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum)
-{
- unsigned long flags;
- unsigned int val;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- /* voice interrupt */
- if (voicenum >= 32) {
- outl(HLIEH << 16, emu->port + PTR);
- val = inl(emu->port + DATA);
- val &= ~(1 << (voicenum - 32));
- } else {
- outl(HLIEL << 16, emu->port + PTR);
- val = inl(emu->port + DATA);
- val &= ~(1 << voicenum);
- }
- outl(val, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-void snd_emu10k1_voice_half_loop_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- /* voice interrupt */
- if (voicenum >= 32) {
- outl(HLIPH << 16, emu->port + PTR);
- voicenum = 1 << (voicenum - 32);
- } else {
- outl(HLIPL << 16, emu->port + PTR);
- voicenum = 1 << voicenum;
- }
- outl(voicenum, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-void snd_emu10k1_voice_set_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum)
-{
- unsigned long flags;
- unsigned int sol;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- /* voice interrupt */
- if (voicenum >= 32) {
- outl(SOLEH << 16, emu->port + PTR);
- sol = inl(emu->port + DATA);
- sol |= 1 << (voicenum - 32);
- } else {
- outl(SOLEL << 16, emu->port + PTR);
- sol = inl(emu->port + DATA);
- sol |= 1 << voicenum;
- }
- outl(sol, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-void snd_emu10k1_voice_clear_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum)
-{
- unsigned long flags;
- unsigned int sol;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- /* voice interrupt */
- if (voicenum >= 32) {
- outl(SOLEH << 16, emu->port + PTR);
- sol = inl(emu->port + DATA);
- sol &= ~(1 << (voicenum - 32));
- } else {
- outl(SOLEL << 16, emu->port + PTR);
- sol = inl(emu->port + DATA);
- sol &= ~(1 << voicenum);
- }
- outl(sol, emu->port + DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-void snd_emu10k1_wait(struct snd_emu10k1 *emu, unsigned int wait)
-{
- volatile unsigned count;
- unsigned int newtime = 0, curtime;
-
- curtime = inl(emu->port + WC) >> 6;
- while (wait-- > 0) {
- count = 0;
- while (count++ < 16384) {
- newtime = inl(emu->port + WC) >> 6;
- if (newtime != curtime)
- break;
- }
- if (count > 16384)
- break;
- curtime = newtime;
- }
-}
-
-unsigned short snd_emu10k1_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
-{
- struct snd_emu10k1 *emu = ac97->private_data;
- unsigned long flags;
- unsigned short val;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- outb(reg, emu->port + AC97ADDRESS);
- val = inw(emu->port + AC97DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
- return val;
-}
-
-void snd_emu10k1_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short data)
-{
- struct snd_emu10k1 *emu = ac97->private_data;
- unsigned long flags;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- outb(reg, emu->port + AC97ADDRESS);
- outw(data, emu->port + AC97DATA);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-/*
- * convert rate to pitch
- */
-
-unsigned int snd_emu10k1_rate_to_pitch(unsigned int rate)
-{
- static u32 logMagTable[128] = {
- 0x00000, 0x02dfc, 0x05b9e, 0x088e6, 0x0b5d6, 0x0e26f, 0x10eb3, 0x13aa2,
- 0x1663f, 0x1918a, 0x1bc84, 0x1e72e, 0x2118b, 0x23b9a, 0x2655d, 0x28ed5,
- 0x2b803, 0x2e0e8, 0x30985, 0x331db, 0x359eb, 0x381b6, 0x3a93d, 0x3d081,
- 0x3f782, 0x41e42, 0x444c1, 0x46b01, 0x49101, 0x4b6c4, 0x4dc49, 0x50191,
- 0x5269e, 0x54b6f, 0x57006, 0x59463, 0x5b888, 0x5dc74, 0x60029, 0x623a7,
- 0x646ee, 0x66a00, 0x68cdd, 0x6af86, 0x6d1fa, 0x6f43c, 0x7164b, 0x73829,
- 0x759d4, 0x77b4f, 0x79c9a, 0x7bdb5, 0x7dea1, 0x7ff5e, 0x81fed, 0x8404e,
- 0x86082, 0x88089, 0x8a064, 0x8c014, 0x8df98, 0x8fef1, 0x91e20, 0x93d26,
- 0x95c01, 0x97ab4, 0x9993e, 0x9b79f, 0x9d5d9, 0x9f3ec, 0xa11d8, 0xa2f9d,
- 0xa4d3c, 0xa6ab5, 0xa8808, 0xaa537, 0xac241, 0xadf26, 0xafbe7, 0xb1885,
- 0xb3500, 0xb5157, 0xb6d8c, 0xb899f, 0xba58f, 0xbc15e, 0xbdd0c, 0xbf899,
- 0xc1404, 0xc2f50, 0xc4a7b, 0xc6587, 0xc8073, 0xc9b3f, 0xcb5ed, 0xcd07c,
- 0xceaec, 0xd053f, 0xd1f73, 0xd398a, 0xd5384, 0xd6d60, 0xd8720, 0xda0c3,
- 0xdba4a, 0xdd3b4, 0xded03, 0xe0636, 0xe1f4e, 0xe384a, 0xe512c, 0xe69f3,
- 0xe829f, 0xe9b31, 0xeb3a9, 0xecc08, 0xee44c, 0xefc78, 0xf148a, 0xf2c83,
- 0xf4463, 0xf5c2a, 0xf73da, 0xf8b71, 0xfa2f0, 0xfba57, 0xfd1a7, 0xfe8df
- };
- static char logSlopeTable[128] = {
- 0x5c, 0x5c, 0x5b, 0x5a, 0x5a, 0x59, 0x58, 0x58,
- 0x57, 0x56, 0x56, 0x55, 0x55, 0x54, 0x53, 0x53,
- 0x52, 0x52, 0x51, 0x51, 0x50, 0x50, 0x4f, 0x4f,
- 0x4e, 0x4d, 0x4d, 0x4d, 0x4c, 0x4c, 0x4b, 0x4b,
- 0x4a, 0x4a, 0x49, 0x49, 0x48, 0x48, 0x47, 0x47,
- 0x47, 0x46, 0x46, 0x45, 0x45, 0x45, 0x44, 0x44,
- 0x43, 0x43, 0x43, 0x42, 0x42, 0x42, 0x41, 0x41,
- 0x41, 0x40, 0x40, 0x40, 0x3f, 0x3f, 0x3f, 0x3e,
- 0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 0x3c,
- 0x3b, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39,
- 0x39, 0x39, 0x39, 0x38, 0x38, 0x38, 0x38, 0x37,
- 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x35,
- 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x34, 0x34,
- 0x33, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x32,
- 0x32, 0x31, 0x31, 0x31, 0x31, 0x31, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f
- };
- int i;
-
- if (rate == 0)
- return 0; /* Bail out if no leading "1" */
- rate *= 11185; /* Scale 48000 to 0x20002380 */
- for (i = 31; i > 0; i--) {
- if (rate & 0x80000000) { /* Detect leading "1" */
- return (((unsigned int) (i - 15) << 20) +
- logMagTable[0x7f & (rate >> 24)] +
- (0x7f & (rate >> 17)) *
- logSlopeTable[0x7f & (rate >> 24)]);
- }
- rate <<= 1;
- }
-
- return 0; /* Should never reach this point */
-}
-
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/irq.c b/ANDROID_3.4.5/sound/pci/emu10k1/irq.c
deleted file mode 100644
index 30bfed6f..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/irq.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Creative Labs, Inc.
- * Routines for IRQ control of EMU10K1 chips
- *
- * BUGS:
- * --
- *
- * TODO:
- * --
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/emu10k1.h>
-
-irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id)
-{
- struct snd_emu10k1 *emu = dev_id;
- unsigned int status, status2, orig_status, orig_status2;
- int handled = 0;
- int timeout = 0;
-
- while (((status = inl(emu->port + IPR)) != 0) && (timeout < 1000)) {
- timeout++;
- orig_status = status;
- handled = 1;
- if ((status & 0xffffffff) == 0xffffffff) {
- snd_printk(KERN_INFO "snd-emu10k1: Suspected sound card removal\n");
- break;
- }
- if (status & IPR_PCIERROR) {
- snd_printk(KERN_ERR "interrupt: PCI error\n");
- snd_emu10k1_intr_disable(emu, INTE_PCIERRORENABLE);
- status &= ~IPR_PCIERROR;
- }
- if (status & (IPR_VOLINCR|IPR_VOLDECR|IPR_MUTE)) {
- if (emu->hwvol_interrupt)
- emu->hwvol_interrupt(emu, status);
- else
- snd_emu10k1_intr_disable(emu, INTE_VOLINCRENABLE|INTE_VOLDECRENABLE|INTE_MUTEENABLE);
- status &= ~(IPR_VOLINCR|IPR_VOLDECR|IPR_MUTE);
- }
- if (status & IPR_CHANNELLOOP) {
- int voice;
- int voice_max = status & IPR_CHANNELNUMBERMASK;
- u32 val;
- struct snd_emu10k1_voice *pvoice = emu->voices;
-
- val = snd_emu10k1_ptr_read(emu, CLIPL, 0);
- for (voice = 0; voice <= voice_max; voice++) {
- if (voice == 0x20)
- val = snd_emu10k1_ptr_read(emu, CLIPH, 0);
- if (val & 1) {
- if (pvoice->use && pvoice->interrupt != NULL) {
- pvoice->interrupt(emu, pvoice);
- snd_emu10k1_voice_intr_ack(emu, voice);
- } else {
- snd_emu10k1_voice_intr_disable(emu, voice);
- }
- }
- val >>= 1;
- pvoice++;
- }
- val = snd_emu10k1_ptr_read(emu, HLIPL, 0);
- for (voice = 0; voice <= voice_max; voice++) {
- if (voice == 0x20)
- val = snd_emu10k1_ptr_read(emu, HLIPH, 0);
- if (val & 1) {
- if (pvoice->use && pvoice->interrupt != NULL) {
- pvoice->interrupt(emu, pvoice);
- snd_emu10k1_voice_half_loop_intr_ack(emu, voice);
- } else {
- snd_emu10k1_voice_half_loop_intr_disable(emu, voice);
- }
- }
- val >>= 1;
- pvoice++;
- }
- status &= ~IPR_CHANNELLOOP;
- }
- status &= ~IPR_CHANNELNUMBERMASK;
- if (status & (IPR_ADCBUFFULL|IPR_ADCBUFHALFFULL)) {
- if (emu->capture_interrupt)
- emu->capture_interrupt(emu, status);
- else
- snd_emu10k1_intr_disable(emu, INTE_ADCBUFENABLE);
- status &= ~(IPR_ADCBUFFULL|IPR_ADCBUFHALFFULL);
- }
- if (status & (IPR_MICBUFFULL|IPR_MICBUFHALFFULL)) {
- if (emu->capture_mic_interrupt)
- emu->capture_mic_interrupt(emu, status);
- else
- snd_emu10k1_intr_disable(emu, INTE_MICBUFENABLE);
- status &= ~(IPR_MICBUFFULL|IPR_MICBUFHALFFULL);
- }
- if (status & (IPR_EFXBUFFULL|IPR_EFXBUFHALFFULL)) {
- if (emu->capture_efx_interrupt)
- emu->capture_efx_interrupt(emu, status);
- else
- snd_emu10k1_intr_disable(emu, INTE_EFXBUFENABLE);
- status &= ~(IPR_EFXBUFFULL|IPR_EFXBUFHALFFULL);
- }
- if (status & (IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY)) {
- if (emu->midi.interrupt)
- emu->midi.interrupt(emu, status);
- else
- snd_emu10k1_intr_disable(emu, INTE_MIDITXENABLE|INTE_MIDIRXENABLE);
- status &= ~(IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY);
- }
- if (status & (IPR_A_MIDITRANSBUFEMPTY2|IPR_A_MIDIRECVBUFEMPTY2)) {
- if (emu->midi2.interrupt)
- emu->midi2.interrupt(emu, status);
- else
- snd_emu10k1_intr_disable(emu, INTE_A_MIDITXENABLE2|INTE_A_MIDIRXENABLE2);
- status &= ~(IPR_A_MIDITRANSBUFEMPTY2|IPR_A_MIDIRECVBUFEMPTY2);
- }
- if (status & IPR_INTERVALTIMER) {
- if (emu->timer)
- snd_timer_interrupt(emu->timer, emu->timer->sticks);
- else
- snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB);
- status &= ~IPR_INTERVALTIMER;
- }
- if (status & (IPR_GPSPDIFSTATUSCHANGE|IPR_CDROMSTATUSCHANGE)) {
- if (emu->spdif_interrupt)
- emu->spdif_interrupt(emu, status);
- else
- snd_emu10k1_intr_disable(emu, INTE_GPSPDIFENABLE|INTE_CDSPDIFENABLE);
- status &= ~(IPR_GPSPDIFSTATUSCHANGE|IPR_CDROMSTATUSCHANGE);
- }
- if (status & IPR_FXDSP) {
- if (emu->dsp_interrupt)
- emu->dsp_interrupt(emu);
- else
- snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
- status &= ~IPR_FXDSP;
- }
- if (status & IPR_P16V) {
- while ((status2 = inl(emu->port + IPR2)) != 0) {
- u32 mask = INTE2_PLAYBACK_CH_0_LOOP; /* Full Loop */
- struct snd_emu10k1_voice *pvoice = &(emu->p16v_voices[0]);
- struct snd_emu10k1_voice *cvoice = &(emu->p16v_capture_voice);
-
- //printk(KERN_INFO "status2=0x%x\n", status2);
- orig_status2 = status2;
- if(status2 & mask) {
- if(pvoice->use) {
- snd_pcm_period_elapsed(pvoice->epcm->substream);
- } else {
- snd_printk(KERN_ERR "p16v: status: 0x%08x, mask=0x%08x, pvoice=%p, use=%d\n", status2, mask, pvoice, pvoice->use);
- }
- }
- if(status2 & 0x110000) {
- //printk(KERN_INFO "capture int found\n");
- if(cvoice->use) {
- //printk(KERN_INFO "capture period_elapsed\n");
- snd_pcm_period_elapsed(cvoice->epcm->substream);
- }
- }
- outl(orig_status2, emu->port + IPR2); /* ack all */
- }
- status &= ~IPR_P16V;
- }
-
- if (status) {
- unsigned int bits;
- snd_printk(KERN_ERR "emu10k1: unhandled interrupt: 0x%08x\n", status);
- //make sure any interrupts we don't handle are disabled:
- bits = INTE_FXDSPENABLE |
- INTE_PCIERRORENABLE |
- INTE_VOLINCRENABLE |
- INTE_VOLDECRENABLE |
- INTE_MUTEENABLE |
- INTE_MICBUFENABLE |
- INTE_ADCBUFENABLE |
- INTE_EFXBUFENABLE |
- INTE_GPSPDIFENABLE |
- INTE_CDSPDIFENABLE |
- INTE_INTERVALTIMERENB |
- INTE_MIDITXENABLE |
- INTE_MIDIRXENABLE;
- if (emu->audigy)
- bits |= INTE_A_MIDITXENABLE2 | INTE_A_MIDIRXENABLE2;
- snd_emu10k1_intr_disable(emu, bits);
- }
- outl(orig_status, emu->port + IPR); /* ack all */
- }
- if (timeout == 1000)
- snd_printk(KERN_INFO "emu10k1 irq routine failure\n");
-
- return IRQ_RETVAL(handled);
-}
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/memory.c b/ANDROID_3.4.5/sound/pci/emu10k1/memory.c
deleted file mode 100644
index 4f502a2b..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/memory.c
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- *
- * EMU10K1 memory page allocation (PTB area)
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/pci.h>
-#include <linux/gfp.h>
-#include <linux/time.h>
-#include <linux/mutex.h>
-#include <linux/export.h>
-
-#include <sound/core.h>
-#include <sound/emu10k1.h>
-
-/* page arguments of these two macros are Emu page (4096 bytes), not like
- * aligned pages in others
- */
-#define __set_ptb_entry(emu,page,addr) \
- (((u32 *)(emu)->ptb_pages.area)[page] = cpu_to_le32(((addr) << 1) | (page)))
-
-#define UNIT_PAGES (PAGE_SIZE / EMUPAGESIZE)
-#define MAX_ALIGN_PAGES (MAXPAGES / UNIT_PAGES)
-/* get aligned page from offset address */
-#define get_aligned_page(offset) ((offset) >> PAGE_SHIFT)
-/* get offset address from aligned page */
-#define aligned_page_offset(page) ((page) << PAGE_SHIFT)
-
-#if PAGE_SIZE == 4096
-/* page size == EMUPAGESIZE */
-/* fill PTB entrie(s) corresponding to page with addr */
-#define set_ptb_entry(emu,page,addr) __set_ptb_entry(emu,page,addr)
-/* fill PTB entrie(s) corresponding to page with silence pointer */
-#define set_silent_ptb(emu,page) __set_ptb_entry(emu,page,emu->silent_page.addr)
-#else
-/* fill PTB entries -- we need to fill UNIT_PAGES entries */
-static inline void set_ptb_entry(struct snd_emu10k1 *emu, int page, dma_addr_t addr)
-{
- int i;
- page *= UNIT_PAGES;
- for (i = 0; i < UNIT_PAGES; i++, page++) {
- __set_ptb_entry(emu, page, addr);
- addr += EMUPAGESIZE;
- }
-}
-static inline void set_silent_ptb(struct snd_emu10k1 *emu, int page)
-{
- int i;
- page *= UNIT_PAGES;
- for (i = 0; i < UNIT_PAGES; i++, page++)
- /* do not increment ptr */
- __set_ptb_entry(emu, page, emu->silent_page.addr);
-}
-#endif /* PAGE_SIZE */
-
-
-/*
- */
-static int synth_alloc_pages(struct snd_emu10k1 *hw, struct snd_emu10k1_memblk *blk);
-static int synth_free_pages(struct snd_emu10k1 *hw, struct snd_emu10k1_memblk *blk);
-
-#define get_emu10k1_memblk(l,member) list_entry(l, struct snd_emu10k1_memblk, member)
-
-
-/* initialize emu10k1 part */
-static void emu10k1_memblk_init(struct snd_emu10k1_memblk *blk)
-{
- blk->mapped_page = -1;
- INIT_LIST_HEAD(&blk->mapped_link);
- INIT_LIST_HEAD(&blk->mapped_order_link);
- blk->map_locked = 0;
-
- blk->first_page = get_aligned_page(blk->mem.offset);
- blk->last_page = get_aligned_page(blk->mem.offset + blk->mem.size - 1);
- blk->pages = blk->last_page - blk->first_page + 1;
-}
-
-/*
- * search empty region on PTB with the given size
- *
- * if an empty region is found, return the page and store the next mapped block
- * in nextp
- * if not found, return a negative error code.
- */
-static int search_empty_map_area(struct snd_emu10k1 *emu, int npages, struct list_head **nextp)
-{
- int page = 0, found_page = -ENOMEM;
- int max_size = npages;
- int size;
- struct list_head *candidate = &emu->mapped_link_head;
- struct list_head *pos;
-
- list_for_each (pos, &emu->mapped_link_head) {
- struct snd_emu10k1_memblk *blk = get_emu10k1_memblk(pos, mapped_link);
- if (blk->mapped_page < 0)
- continue;
- size = blk->mapped_page - page;
- if (size == npages) {
- *nextp = pos;
- return page;
- }
- else if (size > max_size) {
- /* we look for the maximum empty hole */
- max_size = size;
- candidate = pos;
- found_page = page;
- }
- page = blk->mapped_page + blk->pages;
- }
- size = MAX_ALIGN_PAGES - page;
- if (size >= max_size) {
- *nextp = pos;
- return page;
- }
- *nextp = candidate;
- return found_page;
-}
-
-/*
- * map a memory block onto emu10k1's PTB
- *
- * call with memblk_lock held
- */
-static int map_memblk(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
-{
- int page, pg;
- struct list_head *next;
-
- page = search_empty_map_area(emu, blk->pages, &next);
- if (page < 0) /* not found */
- return page;
- /* insert this block in the proper position of mapped list */
- list_add_tail(&blk->mapped_link, next);
- /* append this as a newest block in order list */
- list_add_tail(&blk->mapped_order_link, &emu->mapped_order_link_head);
- blk->mapped_page = page;
- /* fill PTB */
- for (pg = blk->first_page; pg <= blk->last_page; pg++) {
- set_ptb_entry(emu, page, emu->page_addr_table[pg]);
- page++;
- }
- return 0;
-}
-
-/*
- * unmap the block
- * return the size of resultant empty pages
- *
- * call with memblk_lock held
- */
-static int unmap_memblk(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
-{
- int start_page, end_page, mpage, pg;
- struct list_head *p;
- struct snd_emu10k1_memblk *q;
-
- /* calculate the expected size of empty region */
- if ((p = blk->mapped_link.prev) != &emu->mapped_link_head) {
- q = get_emu10k1_memblk(p, mapped_link);
- start_page = q->mapped_page + q->pages;
- } else
- start_page = 0;
- if ((p = blk->mapped_link.next) != &emu->mapped_link_head) {
- q = get_emu10k1_memblk(p, mapped_link);
- end_page = q->mapped_page;
- } else
- end_page = MAX_ALIGN_PAGES;
-
- /* remove links */
- list_del(&blk->mapped_link);
- list_del(&blk->mapped_order_link);
- /* clear PTB */
- mpage = blk->mapped_page;
- for (pg = blk->first_page; pg <= blk->last_page; pg++) {
- set_silent_ptb(emu, mpage);
- mpage++;
- }
- blk->mapped_page = -1;
- return end_page - start_page; /* return the new empty size */
-}
-
-/*
- * search empty pages with the given size, and create a memory block
- *
- * unlike synth_alloc the memory block is aligned to the page start
- */
-static struct snd_emu10k1_memblk *
-search_empty(struct snd_emu10k1 *emu, int size)
-{
- struct list_head *p;
- struct snd_emu10k1_memblk *blk;
- int page, psize;
-
- psize = get_aligned_page(size + PAGE_SIZE -1);
- page = 0;
- list_for_each(p, &emu->memhdr->block) {
- blk = get_emu10k1_memblk(p, mem.list);
- if (page + psize <= blk->first_page)
- goto __found_pages;
- page = blk->last_page + 1;
- }
- if (page + psize > emu->max_cache_pages)
- return NULL;
-
-__found_pages:
- /* create a new memory block */
- blk = (struct snd_emu10k1_memblk *)__snd_util_memblk_new(emu->memhdr, psize << PAGE_SHIFT, p->prev);
- if (blk == NULL)
- return NULL;
- blk->mem.offset = aligned_page_offset(page); /* set aligned offset */
- emu10k1_memblk_init(blk);
- return blk;
-}
-
-
-/*
- * check if the given pointer is valid for pages
- */
-static int is_valid_page(struct snd_emu10k1 *emu, dma_addr_t addr)
-{
- if (addr & ~emu->dma_mask) {
- snd_printk(KERN_ERR "max memory size is 0x%lx (addr = 0x%lx)!!\n", emu->dma_mask, (unsigned long)addr);
- return 0;
- }
- if (addr & (EMUPAGESIZE-1)) {
- snd_printk(KERN_ERR "page is not aligned\n");
- return 0;
- }
- return 1;
-}
-
-/*
- * map the given memory block on PTB.
- * if the block is already mapped, update the link order.
- * if no empty pages are found, tries to release unused memory blocks
- * and retry the mapping.
- */
-int snd_emu10k1_memblk_map(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
-{
- int err;
- int size;
- struct list_head *p, *nextp;
- struct snd_emu10k1_memblk *deleted;
- unsigned long flags;
-
- spin_lock_irqsave(&emu->memblk_lock, flags);
- if (blk->mapped_page >= 0) {
- /* update order link */
- list_del(&blk->mapped_order_link);
- list_add_tail(&blk->mapped_order_link, &emu->mapped_order_link_head);
- spin_unlock_irqrestore(&emu->memblk_lock, flags);
- return 0;
- }
- if ((err = map_memblk(emu, blk)) < 0) {
- /* no enough page - try to unmap some blocks */
- /* starting from the oldest block */
- p = emu->mapped_order_link_head.next;
- for (; p != &emu->mapped_order_link_head; p = nextp) {
- nextp = p->next;
- deleted = get_emu10k1_memblk(p, mapped_order_link);
- if (deleted->map_locked)
- continue;
- size = unmap_memblk(emu, deleted);
- if (size >= blk->pages) {
- /* ok the empty region is enough large */
- err = map_memblk(emu, blk);
- break;
- }
- }
- }
- spin_unlock_irqrestore(&emu->memblk_lock, flags);
- return err;
-}
-
-EXPORT_SYMBOL(snd_emu10k1_memblk_map);
-
-/*
- * page allocation for DMA
- */
-struct snd_util_memblk *
-snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_util_memhdr *hdr;
- struct snd_emu10k1_memblk *blk;
- int page, err, idx;
-
- if (snd_BUG_ON(!emu))
- return NULL;
- if (snd_BUG_ON(runtime->dma_bytes <= 0 ||
- runtime->dma_bytes >= MAXPAGES * EMUPAGESIZE))
- return NULL;
- hdr = emu->memhdr;
- if (snd_BUG_ON(!hdr))
- return NULL;
-
- idx = runtime->period_size >= runtime->buffer_size ?
- (emu->delay_pcm_irq * 2) : 0;
- mutex_lock(&hdr->block_mutex);
- blk = search_empty(emu, runtime->dma_bytes + idx);
- if (blk == NULL) {
- mutex_unlock(&hdr->block_mutex);
- return NULL;
- }
- /* fill buffer addresses but pointers are not stored so that
- * snd_free_pci_page() is not called in in synth_free()
- */
- idx = 0;
- for (page = blk->first_page; page <= blk->last_page; page++, idx++) {
- unsigned long ofs = idx << PAGE_SHIFT;
- dma_addr_t addr;
- addr = snd_pcm_sgbuf_get_addr(substream, ofs);
- if (! is_valid_page(emu, addr)) {
- printk(KERN_ERR "emu: failure page = %d\n", idx);
- mutex_unlock(&hdr->block_mutex);
- return NULL;
- }
- emu->page_addr_table[page] = addr;
- emu->page_ptr_table[page] = NULL;
- }
-
- /* set PTB entries */
- blk->map_locked = 1; /* do not unmap this block! */
- err = snd_emu10k1_memblk_map(emu, blk);
- if (err < 0) {
- __snd_util_mem_free(hdr, (struct snd_util_memblk *)blk);
- mutex_unlock(&hdr->block_mutex);
- return NULL;
- }
- mutex_unlock(&hdr->block_mutex);
- return (struct snd_util_memblk *)blk;
-}
-
-
-/*
- * release DMA buffer from page table
- */
-int snd_emu10k1_free_pages(struct snd_emu10k1 *emu, struct snd_util_memblk *blk)
-{
- if (snd_BUG_ON(!emu || !blk))
- return -EINVAL;
- return snd_emu10k1_synth_free(emu, blk);
-}
-
-
-/*
- * memory allocation using multiple pages (for synth)
- * Unlike the DMA allocation above, non-contiguous pages are assined.
- */
-
-/*
- * allocate a synth sample area
- */
-struct snd_util_memblk *
-snd_emu10k1_synth_alloc(struct snd_emu10k1 *hw, unsigned int size)
-{
- struct snd_emu10k1_memblk *blk;
- struct snd_util_memhdr *hdr = hw->memhdr;
-
- mutex_lock(&hdr->block_mutex);
- blk = (struct snd_emu10k1_memblk *)__snd_util_mem_alloc(hdr, size);
- if (blk == NULL) {
- mutex_unlock(&hdr->block_mutex);
- return NULL;
- }
- if (synth_alloc_pages(hw, blk)) {
- __snd_util_mem_free(hdr, (struct snd_util_memblk *)blk);
- mutex_unlock(&hdr->block_mutex);
- return NULL;
- }
- snd_emu10k1_memblk_map(hw, blk);
- mutex_unlock(&hdr->block_mutex);
- return (struct snd_util_memblk *)blk;
-}
-
-EXPORT_SYMBOL(snd_emu10k1_synth_alloc);
-
-/*
- * free a synth sample area
- */
-int
-snd_emu10k1_synth_free(struct snd_emu10k1 *emu, struct snd_util_memblk *memblk)
-{
- struct snd_util_memhdr *hdr = emu->memhdr;
- struct snd_emu10k1_memblk *blk = (struct snd_emu10k1_memblk *)memblk;
- unsigned long flags;
-
- mutex_lock(&hdr->block_mutex);
- spin_lock_irqsave(&emu->memblk_lock, flags);
- if (blk->mapped_page >= 0)
- unmap_memblk(emu, blk);
- spin_unlock_irqrestore(&emu->memblk_lock, flags);
- synth_free_pages(emu, blk);
- __snd_util_mem_free(hdr, memblk);
- mutex_unlock(&hdr->block_mutex);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_emu10k1_synth_free);
-
-/* check new allocation range */
-static void get_single_page_range(struct snd_util_memhdr *hdr,
- struct snd_emu10k1_memblk *blk,
- int *first_page_ret, int *last_page_ret)
-{
- struct list_head *p;
- struct snd_emu10k1_memblk *q;
- int first_page, last_page;
- first_page = blk->first_page;
- if ((p = blk->mem.list.prev) != &hdr->block) {
- q = get_emu10k1_memblk(p, mem.list);
- if (q->last_page == first_page)
- first_page++; /* first page was already allocated */
- }
- last_page = blk->last_page;
- if ((p = blk->mem.list.next) != &hdr->block) {
- q = get_emu10k1_memblk(p, mem.list);
- if (q->first_page == last_page)
- last_page--; /* last page was already allocated */
- }
- *first_page_ret = first_page;
- *last_page_ret = last_page;
-}
-
-/* release allocated pages */
-static void __synth_free_pages(struct snd_emu10k1 *emu, int first_page,
- int last_page)
-{
- int page;
-
- for (page = first_page; page <= last_page; page++) {
- free_page((unsigned long)emu->page_ptr_table[page]);
- emu->page_addr_table[page] = 0;
- emu->page_ptr_table[page] = NULL;
- }
-}
-
-/*
- * allocate kernel pages
- */
-static int synth_alloc_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
-{
- int page, first_page, last_page;
-
- emu10k1_memblk_init(blk);
- get_single_page_range(emu->memhdr, blk, &first_page, &last_page);
- /* allocate kernel pages */
- for (page = first_page; page <= last_page; page++) {
- /* first try to allocate from <4GB zone */
- struct page *p = alloc_page(GFP_KERNEL | GFP_DMA32 |
- __GFP_NOWARN);
- if (!p || (page_to_pfn(p) & ~(emu->dma_mask >> PAGE_SHIFT))) {
- if (p)
- __free_page(p);
- /* try to allocate from <16MB zone */
- p = alloc_page(GFP_ATOMIC | GFP_DMA |
- __GFP_NORETRY | /* no OOM-killer */
- __GFP_NOWARN);
- }
- if (!p) {
- __synth_free_pages(emu, first_page, page - 1);
- return -ENOMEM;
- }
- emu->page_addr_table[page] = page_to_phys(p);
- emu->page_ptr_table[page] = page_address(p);
- }
- return 0;
-}
-
-/*
- * free pages
- */
-static int synth_free_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
-{
- int first_page, last_page;
-
- get_single_page_range(emu->memhdr, blk, &first_page, &last_page);
- __synth_free_pages(emu, first_page, last_page);
- return 0;
-}
-
-/* calculate buffer pointer from offset address */
-static inline void *offset_ptr(struct snd_emu10k1 *emu, int page, int offset)
-{
- char *ptr;
- if (snd_BUG_ON(page < 0 || page >= emu->max_cache_pages))
- return NULL;
- ptr = emu->page_ptr_table[page];
- if (! ptr) {
- printk(KERN_ERR "emu10k1: access to NULL ptr: page = %d\n", page);
- return NULL;
- }
- ptr += offset & (PAGE_SIZE - 1);
- return (void*)ptr;
-}
-
-/*
- * bzero(blk + offset, size)
- */
-int snd_emu10k1_synth_bzero(struct snd_emu10k1 *emu, struct snd_util_memblk *blk,
- int offset, int size)
-{
- int page, nextofs, end_offset, temp, temp1;
- void *ptr;
- struct snd_emu10k1_memblk *p = (struct snd_emu10k1_memblk *)blk;
-
- offset += blk->offset & (PAGE_SIZE - 1);
- end_offset = offset + size;
- page = get_aligned_page(offset);
- do {
- nextofs = aligned_page_offset(page + 1);
- temp = nextofs - offset;
- temp1 = end_offset - offset;
- if (temp1 < temp)
- temp = temp1;
- ptr = offset_ptr(emu, page + p->first_page, offset);
- if (ptr)
- memset(ptr, 0, temp);
- offset = nextofs;
- page++;
- } while (offset < end_offset);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_emu10k1_synth_bzero);
-
-/*
- * copy_from_user(blk + offset, data, size)
- */
-int snd_emu10k1_synth_copy_from_user(struct snd_emu10k1 *emu, struct snd_util_memblk *blk,
- int offset, const char __user *data, int size)
-{
- int page, nextofs, end_offset, temp, temp1;
- void *ptr;
- struct snd_emu10k1_memblk *p = (struct snd_emu10k1_memblk *)blk;
-
- offset += blk->offset & (PAGE_SIZE - 1);
- end_offset = offset + size;
- page = get_aligned_page(offset);
- do {
- nextofs = aligned_page_offset(page + 1);
- temp = nextofs - offset;
- temp1 = end_offset - offset;
- if (temp1 < temp)
- temp = temp1;
- ptr = offset_ptr(emu, page + p->first_page, offset);
- if (ptr && copy_from_user(ptr, data, temp))
- return -EFAULT;
- offset = nextofs;
- data += temp;
- page++;
- } while (offset < end_offset);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_emu10k1_synth_copy_from_user);
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/p16v.c b/ANDROID_3.4.5/sound/pci/emu10k1/p16v.c
deleted file mode 100644
index a81dc442..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/p16v.c
+++ /dev/null
@@ -1,934 +0,0 @@
-/*
- * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
- * Driver p16v chips
- * Version: 0.25
- *
- * FEATURES currently supported:
- * Output fixed at S32_LE, 2 channel to hw:0,0
- * Rates: 44.1, 48, 96, 192.
- *
- * Changelog:
- * 0.8
- * Use separate card based buffer for periods table.
- * 0.9
- * Use 2 channel output streams instead of 8 channel.
- * (8 channel output streams might be good for ASIO type output)
- * Corrected speaker output, so Front -> Front etc.
- * 0.10
- * Fixed missed interrupts.
- * 0.11
- * Add Sound card model number and names.
- * Add Analog volume controls.
- * 0.12
- * Corrected playback interrupts. Now interrupt per period, instead of half period.
- * 0.13
- * Use single trigger for multichannel.
- * 0.14
- * Mic capture now works at fixed: S32_LE, 96000Hz, Stereo.
- * 0.15
- * Force buffer_size / period_size == INTEGER.
- * 0.16
- * Update p16v.c to work with changed alsa api.
- * 0.17
- * Update p16v.c to work with changed alsa api. Removed boot_devs.
- * 0.18
- * Merging with snd-emu10k1 driver.
- * 0.19
- * One stereo channel at 24bit now works.
- * 0.20
- * Added better register defines.
- * 0.21
- * Integrated with snd-emu10k1 driver.
- * 0.22
- * Removed #if 0 ... #endif
- * 0.23
- * Implement different capture rates.
- * 0.24
- * Implement different capture source channels.
- * e.g. When HD Capture source is set to SPDIF,
- * setting HD Capture channel to 0 captures from CDROM digital input.
- * setting HD Capture channel to 1 captures from SPDIF in.
- * 0.25
- * Include capture buffer sizes.
- *
- * BUGS:
- * Some stability problems when unloading the snd-p16v kernel module.
- * --
- *
- * TODO:
- * SPDIF out.
- * Find out how to change capture sample rates. E.g. To record SPDIF at 48000Hz.
- * Currently capture fixed at 48000Hz.
- *
- * --
- * GENERAL INFO:
- * Model: SB0240
- * P16V Chip: CA0151-DBS
- * Audigy 2 Chip: CA0102-IAT
- * AC97 Codec: STAC 9721
- * ADC: Philips 1361T (Stereo 24bit)
- * DAC: CS4382-K (8-channel, 24bit, 192Khz)
- *
- * This code was initially based on code from ALSA's emu10k1x.c which is:
- * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/moduleparam.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/info.h>
-#include <sound/tlv.h>
-#include <sound/emu10k1.h>
-#include "p16v.h"
-
-#define SET_CHANNEL 0 /* Testing channel outputs 0=Front, 1=Center/LFE, 2=Unknown, 3=Rear */
-#define PCM_FRONT_CHANNEL 0
-#define PCM_REAR_CHANNEL 1
-#define PCM_CENTER_LFE_CHANNEL 2
-#define PCM_SIDE_CHANNEL 3
-#define CONTROL_FRONT_CHANNEL 0
-#define CONTROL_REAR_CHANNEL 3
-#define CONTROL_CENTER_LFE_CHANNEL 1
-#define CONTROL_SIDE_CHANNEL 2
-
-/* Card IDs:
- * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:2002 -> Audigy2 ZS 7.1 Model:SB0350
- * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:1007 -> Audigy2 6.1 Model:SB0240
- * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:1002 -> Audigy2 Platinum Model:SB msb0240230009266
- * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:2007 -> Audigy4 Pro Model:SB0380 M1SB0380472001901E
- *
- */
-
- /* hardware definition */
-static struct snd_pcm_hardware snd_p16v_playback_hw = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_SYNC_START,
- .formats = SNDRV_PCM_FMTBIT_S32_LE, /* Only supports 24-bit samples padded to 32 bits. */
- .rates = SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100,
- .rate_min = 44100,
- .rate_max = 192000,
- .channels_min = 8,
- .channels_max = 8,
- .buffer_bytes_max = ((65536 - 64) * 8),
- .period_bytes_min = 64,
- .period_bytes_max = (65536 - 64),
- .periods_min = 2,
- .periods_max = 8,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_p16v_capture_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .rates = SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100,
- .rate_min = 44100,
- .rate_max = 192000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (65536 - 64),
- .period_bytes_min = 64,
- .period_bytes_max = (65536 - 128) >> 1, /* size has to be N*64 bytes */
- .periods_min = 2,
- .periods_max = 2,
- .fifo_size = 0,
-};
-
-static void snd_p16v_pcm_free_substream(struct snd_pcm_runtime *runtime)
-{
- struct snd_emu10k1_pcm *epcm = runtime->private_data;
-
- if (epcm) {
- /* snd_printk(KERN_DEBUG "epcm free: %p\n", epcm); */
- kfree(epcm);
- }
-}
-
-/* open_playback callback */
-static int snd_p16v_pcm_open_playback_channel(struct snd_pcm_substream *substream, int channel_id)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_emu10k1_voice *channel = &(emu->p16v_voices[channel_id]);
- struct snd_emu10k1_pcm *epcm;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
- /* snd_printk(KERN_DEBUG "epcm kcalloc: %p\n", epcm); */
-
- if (epcm == NULL)
- return -ENOMEM;
- epcm->emu = emu;
- epcm->substream = substream;
- /*
- snd_printk(KERN_DEBUG "epcm device=%d, channel_id=%d\n",
- substream->pcm->device, channel_id);
- */
- runtime->private_data = epcm;
- runtime->private_free = snd_p16v_pcm_free_substream;
-
- runtime->hw = snd_p16v_playback_hw;
-
- channel->emu = emu;
- channel->number = channel_id;
-
- channel->use=1;
-#if 0 /* debug */
- snd_printk(KERN_DEBUG
- "p16v: open channel_id=%d, channel=%p, use=0x%x\n",
- channel_id, channel, channel->use);
- printk(KERN_DEBUG "open:channel_id=%d, chip=%p, channel=%p\n",
- channel_id, chip, channel);
-#endif /* debug */
- /* channel->interrupt = snd_p16v_pcm_channel_interrupt; */
- channel->epcm = epcm;
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
- return err;
-
- runtime->sync.id32[0] = substream->pcm->card->number;
- runtime->sync.id32[1] = 'P';
- runtime->sync.id32[2] = 16;
- runtime->sync.id32[3] = 'V';
-
- return 0;
-}
-/* open_capture callback */
-static int snd_p16v_pcm_open_capture_channel(struct snd_pcm_substream *substream, int channel_id)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_emu10k1_voice *channel = &(emu->p16v_capture_voice);
- struct snd_emu10k1_pcm *epcm;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
- /* snd_printk(KERN_DEBUG "epcm kcalloc: %p\n", epcm); */
-
- if (epcm == NULL)
- return -ENOMEM;
- epcm->emu = emu;
- epcm->substream = substream;
- /*
- snd_printk(KERN_DEBUG "epcm device=%d, channel_id=%d\n",
- substream->pcm->device, channel_id);
- */
- runtime->private_data = epcm;
- runtime->private_free = snd_p16v_pcm_free_substream;
-
- runtime->hw = snd_p16v_capture_hw;
-
- channel->emu = emu;
- channel->number = channel_id;
-
- channel->use=1;
-#if 0 /* debug */
- snd_printk(KERN_DEBUG
- "p16v: open channel_id=%d, channel=%p, use=0x%x\n",
- channel_id, channel, channel->use);
- printk(KERN_DEBUG "open:channel_id=%d, chip=%p, channel=%p\n",
- channel_id, chip, channel);
-#endif /* debug */
- /* channel->interrupt = snd_p16v_pcm_channel_interrupt; */
- channel->epcm = epcm;
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
- return err;
-
- return 0;
-}
-
-
-/* close callback */
-static int snd_p16v_pcm_close_playback(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- //struct snd_pcm_runtime *runtime = substream->runtime;
- //struct snd_emu10k1_pcm *epcm = runtime->private_data;
- emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use = 0;
- /* FIXME: maybe zero others */
- return 0;
-}
-
-/* close callback */
-static int snd_p16v_pcm_close_capture(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- //struct snd_pcm_runtime *runtime = substream->runtime;
- //struct snd_emu10k1_pcm *epcm = runtime->private_data;
- emu->p16v_capture_voice.use = 0;
- /* FIXME: maybe zero others */
- return 0;
-}
-
-static int snd_p16v_pcm_open_playback_front(struct snd_pcm_substream *substream)
-{
- return snd_p16v_pcm_open_playback_channel(substream, PCM_FRONT_CHANNEL);
-}
-
-static int snd_p16v_pcm_open_capture(struct snd_pcm_substream *substream)
-{
- // Only using channel 0 for now, but the card has 2 channels.
- return snd_p16v_pcm_open_capture_channel(substream, 0);
-}
-
-/* hw_params callback */
-static int snd_p16v_pcm_hw_params_playback(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- int result;
- result = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- return result;
-}
-
-/* hw_params callback */
-static int snd_p16v_pcm_hw_params_capture(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- int result;
- result = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- return result;
-}
-
-
-/* hw_free callback */
-static int snd_p16v_pcm_hw_free_playback(struct snd_pcm_substream *substream)
-{
- int result;
- result = snd_pcm_lib_free_pages(substream);
- return result;
-}
-
-/* hw_free callback */
-static int snd_p16v_pcm_hw_free_capture(struct snd_pcm_substream *substream)
-{
- int result;
- result = snd_pcm_lib_free_pages(substream);
- return result;
-}
-
-
-/* prepare playback callback */
-static int snd_p16v_pcm_prepare_playback(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int channel = substream->pcm->device - emu->p16v_device_offset;
- u32 *table_base = (u32 *)(emu->p16v_buffer.area+(8*16*channel));
- u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
- int i;
- u32 tmp;
-
-#if 0 /* debug */
- snd_printk(KERN_DEBUG "prepare:channel_number=%d, rate=%d, "
- "format=0x%x, channels=%d, buffer_size=%ld, "
- "period_size=%ld, periods=%u, frames_to_bytes=%d\n",
- channel, runtime->rate, runtime->format, runtime->channels,
- runtime->buffer_size, runtime->period_size,
- runtime->periods, frames_to_bytes(runtime, 1));
- snd_printk(KERN_DEBUG "dma_addr=%x, dma_area=%p, table_base=%p\n",
- runtime->dma_addr, runtime->dma_area, table_base);
- snd_printk(KERN_DEBUG "dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n",
- emu->p16v_buffer.addr, emu->p16v_buffer.area,
- emu->p16v_buffer.bytes);
-#endif /* debug */
- tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel);
- switch (runtime->rate) {
- case 44100:
- snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x8080);
- break;
- case 96000:
- snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x4040);
- break;
- case 192000:
- snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x2020);
- break;
- case 48000:
- default:
- snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x0000);
- break;
- }
- /* FIXME: Check emu->buffer.size before actually writing to it. */
- for(i = 0; i < runtime->periods; i++) {
- table_base[i*2]=runtime->dma_addr+(i*period_size_bytes);
- table_base[(i*2)+1]=period_size_bytes<<16;
- }
-
- snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_ADDR, channel, emu->p16v_buffer.addr+(8*16*channel));
- snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_SIZE, channel, (runtime->periods - 1) << 19);
- snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_PTR, channel, 0);
- snd_emu10k1_ptr20_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr);
- //snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes
- snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, 0); // buffer size in bytes
- snd_emu10k1_ptr20_write(emu, PLAYBACK_POINTER, channel, 0);
- snd_emu10k1_ptr20_write(emu, 0x07, channel, 0x0);
- snd_emu10k1_ptr20_write(emu, 0x08, channel, 0);
-
- return 0;
-}
-
-/* prepare capture callback */
-static int snd_p16v_pcm_prepare_capture(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int channel = substream->pcm->device - emu->p16v_device_offset;
- u32 tmp;
-
- /*
- printk(KERN_DEBUG "prepare capture:channel_number=%d, rate=%d, "
- "format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, "
- "frames_to_bytes=%d\n",
- channel, runtime->rate, runtime->format, runtime->channels,
- runtime->buffer_size, runtime->period_size,
- frames_to_bytes(runtime, 1));
- */
- tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel);
- switch (runtime->rate) {
- case 44100:
- snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0800);
- break;
- case 96000:
- snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0400);
- break;
- case 192000:
- snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0200);
- break;
- case 48000:
- default:
- snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0000);
- break;
- }
- /* FIXME: Check emu->buffer.size before actually writing to it. */
- snd_emu10k1_ptr20_write(emu, 0x13, channel, 0);
- snd_emu10k1_ptr20_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr);
- snd_emu10k1_ptr20_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size) << 16); // buffer size in bytes
- snd_emu10k1_ptr20_write(emu, CAPTURE_POINTER, channel, 0);
- //snd_emu10k1_ptr20_write(emu, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC or Line in */
- //snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) | (0x110000<<channel));
-
- return 0;
-}
-
-static void snd_p16v_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
-{
- unsigned long flags;
- unsigned int enable;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- enable = inl(emu->port + INTE2) | intrenb;
- outl(enable, emu->port + INTE2);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-static void snd_p16v_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb)
-{
- unsigned long flags;
- unsigned int disable;
-
- spin_lock_irqsave(&emu->emu_lock, flags);
- disable = inl(emu->port + INTE2) & (~intrenb);
- outl(disable, emu->port + INTE2);
- spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
-/* trigger_playback callback */
-static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime;
- struct snd_emu10k1_pcm *epcm;
- int channel;
- int result = 0;
- struct snd_pcm_substream *s;
- u32 basic = 0;
- u32 inte = 0;
- int running = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- running=1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- default:
- running = 0;
- break;
- }
- snd_pcm_group_for_each_entry(s, substream) {
- if (snd_pcm_substream_chip(s) != emu ||
- s->stream != SNDRV_PCM_STREAM_PLAYBACK)
- continue;
- runtime = s->runtime;
- epcm = runtime->private_data;
- channel = substream->pcm->device-emu->p16v_device_offset;
- /* snd_printk(KERN_DEBUG "p16v channel=%d\n", channel); */
- epcm->running = running;
- basic |= (0x1<<channel);
- inte |= (INTE2_PLAYBACK_CH_0_LOOP<<channel);
- snd_pcm_trigger_done(s, substream);
- }
- /* snd_printk(KERN_DEBUG "basic=0x%x, inte=0x%x\n", basic, inte); */
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- snd_p16v_intr_enable(emu, inte);
- snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)| (basic));
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(basic));
- snd_p16v_intr_disable(emu, inte);
- break;
- default:
- result = -EINVAL;
- break;
- }
- return result;
-}
-
-/* trigger_capture callback */
-static int snd_p16v_pcm_trigger_capture(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_emu10k1_pcm *epcm = runtime->private_data;
- int channel = 0;
- int result = 0;
- u32 inte = INTE2_CAPTURE_CH_0_LOOP | INTE2_CAPTURE_CH_0_HALF_LOOP;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- snd_p16v_intr_enable(emu, inte);
- snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)|(0x100<<channel));
- epcm->running = 1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(0x100<<channel));
- snd_p16v_intr_disable(emu, inte);
- //snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) & ~(0x110000<<channel));
- epcm->running = 0;
- break;
- default:
- result = -EINVAL;
- break;
- }
- return result;
-}
-
-/* pointer_playback callback */
-static snd_pcm_uframes_t
-snd_p16v_pcm_pointer_playback(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_emu10k1_pcm *epcm = runtime->private_data;
- snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0;
- int channel = substream->pcm->device - emu->p16v_device_offset;
- if (!epcm->running)
- return 0;
-
- ptr3 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel);
- ptr1 = snd_emu10k1_ptr20_read(emu, PLAYBACK_POINTER, channel);
- ptr4 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel);
- if (ptr3 != ptr4) ptr1 = snd_emu10k1_ptr20_read(emu, PLAYBACK_POINTER, channel);
- ptr2 = bytes_to_frames(runtime, ptr1);
- ptr2+= (ptr4 >> 3) * runtime->period_size;
- ptr=ptr2;
- if (ptr >= runtime->buffer_size)
- ptr -= runtime->buffer_size;
-
- return ptr;
-}
-
-/* pointer_capture callback */
-static snd_pcm_uframes_t
-snd_p16v_pcm_pointer_capture(struct snd_pcm_substream *substream)
-{
- struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_emu10k1_pcm *epcm = runtime->private_data;
- snd_pcm_uframes_t ptr, ptr1, ptr2 = 0;
- int channel = 0;
-
- if (!epcm->running)
- return 0;
-
- ptr1 = snd_emu10k1_ptr20_read(emu, CAPTURE_POINTER, channel);
- ptr2 = bytes_to_frames(runtime, ptr1);
- ptr=ptr2;
- if (ptr >= runtime->buffer_size) {
- ptr -= runtime->buffer_size;
- printk(KERN_WARNING "buffer capture limited!\n");
- }
- /*
- printk(KERN_DEBUG "ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, "
- "buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n",
- ptr1, ptr2, ptr, (int)runtime->buffer_size,
- (int)runtime->period_size, (int)runtime->frame_bits,
- (int)runtime->rate);
- */
- return ptr;
-}
-
-/* operators */
-static struct snd_pcm_ops snd_p16v_playback_front_ops = {
- .open = snd_p16v_pcm_open_playback_front,
- .close = snd_p16v_pcm_close_playback,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_p16v_pcm_hw_params_playback,
- .hw_free = snd_p16v_pcm_hw_free_playback,
- .prepare = snd_p16v_pcm_prepare_playback,
- .trigger = snd_p16v_pcm_trigger_playback,
- .pointer = snd_p16v_pcm_pointer_playback,
-};
-
-static struct snd_pcm_ops snd_p16v_capture_ops = {
- .open = snd_p16v_pcm_open_capture,
- .close = snd_p16v_pcm_close_capture,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_p16v_pcm_hw_params_capture,
- .hw_free = snd_p16v_pcm_hw_free_capture,
- .prepare = snd_p16v_pcm_prepare_capture,
- .trigger = snd_p16v_pcm_trigger_capture,
- .pointer = snd_p16v_pcm_pointer_capture,
-};
-
-
-int snd_p16v_free(struct snd_emu10k1 *chip)
-{
- // release the data
- if (chip->p16v_buffer.area) {
- snd_dma_free_pages(&chip->p16v_buffer);
- /*
- snd_printk(KERN_DEBUG "period lables free: %p\n",
- &chip->p16v_buffer);
- */
- }
- return 0;
-}
-
-int __devinit snd_p16v_pcm(struct snd_emu10k1 *emu, int device, struct snd_pcm **rpcm)
-{
- struct snd_pcm *pcm;
- struct snd_pcm_substream *substream;
- int err;
- int capture=1;
-
- /* snd_printk(KERN_DEBUG "snd_p16v_pcm called. device=%d\n", device); */
- emu->p16v_device_offset = device;
- if (rpcm)
- *rpcm = NULL;
-
- if ((err = snd_pcm_new(emu->card, "p16v", device, 1, capture, &pcm)) < 0)
- return err;
-
- pcm->private_data = emu;
- // Single playback 8 channel device.
- // Single capture 2 channel device.
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_p16v_playback_front_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_p16v_capture_ops);
-
- pcm->info_flags = 0;
- pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
- strcpy(pcm->name, "p16v");
- emu->pcm_p16v = pcm;
-
- for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
- substream;
- substream = substream->next) {
- if ((err = snd_pcm_lib_preallocate_pages(substream,
- SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(emu->pci),
- ((65536 - 64) * 8), ((65536 - 64) * 8))) < 0)
- return err;
- /*
- snd_printk(KERN_DEBUG
- "preallocate playback substream: err=%d\n", err);
- */
- }
-
- for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
- substream;
- substream = substream->next) {
- if ((err = snd_pcm_lib_preallocate_pages(substream,
- SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(emu->pci),
- 65536 - 64, 65536 - 64)) < 0)
- return err;
- /*
- snd_printk(KERN_DEBUG
- "preallocate capture substream: err=%d\n", err);
- */
- }
-
- if (rpcm)
- *rpcm = pcm;
-
- return 0;
-}
-
-static int snd_p16v_volume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 255;
- return 0;
-}
-
-static int snd_p16v_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- int high_low = (kcontrol->private_value >> 8) & 0xff;
- int reg = kcontrol->private_value & 0xff;
- u32 value;
-
- value = snd_emu10k1_ptr20_read(emu, reg, high_low);
- if (high_low) {
- ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
- ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
- } else {
- ucontrol->value.integer.value[0] = 0xff - ((value >> 8) & 0xff); /* Left */
- ucontrol->value.integer.value[1] = 0xff - ((value >> 0) & 0xff); /* Right */
- }
- return 0;
-}
-
-static int snd_p16v_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- int high_low = (kcontrol->private_value >> 8) & 0xff;
- int reg = kcontrol->private_value & 0xff;
- u32 value, oval;
-
- oval = value = snd_emu10k1_ptr20_read(emu, reg, 0);
- if (high_low == 1) {
- value &= 0xffff;
- value |= ((0xff - ucontrol->value.integer.value[0]) << 24) |
- ((0xff - ucontrol->value.integer.value[1]) << 16);
- } else {
- value &= 0xffff0000;
- value |= ((0xff - ucontrol->value.integer.value[0]) << 8) |
- ((0xff - ucontrol->value.integer.value[1]) );
- }
- if (value != oval) {
- snd_emu10k1_ptr20_write(emu, reg, 0, value);
- return 1;
- }
- return 0;
-}
-
-static int snd_p16v_capture_source_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[8] = {
- "SPDIF", "I2S", "SRC48", "SRCMulti_SPDIF", "SRCMulti_I2S",
- "CDIF", "FX", "AC97"
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 8;
- if (uinfo->value.enumerated.item > 7)
- uinfo->value.enumerated.item = 7;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_p16v_capture_source_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = emu->p16v_capture_source;
- return 0;
-}
-
-static int snd_p16v_capture_source_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change = 0;
- u32 mask;
- u32 source;
-
- val = ucontrol->value.enumerated.item[0] ;
- if (val > 7)
- return -EINVAL;
- change = (emu->p16v_capture_source != val);
- if (change) {
- emu->p16v_capture_source = val;
- source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
- mask = snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & 0xffff;
- snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, source | mask);
- }
- return change;
-}
-
-static int snd_p16v_capture_channel_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[4] = { "0", "1", "2", "3", };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 4;
- if (uinfo->value.enumerated.item > 3)
- uinfo->value.enumerated.item = 3;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_p16v_capture_channel_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = emu->p16v_capture_channel;
- return 0;
-}
-
-static int snd_p16v_capture_channel_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change = 0;
- u32 tmp;
-
- val = ucontrol->value.enumerated.item[0] ;
- if (val > 3)
- return -EINVAL;
- change = (emu->p16v_capture_channel != val);
- if (change) {
- emu->p16v_capture_channel = val;
- tmp = snd_emu10k1_ptr20_read(emu, CAPTURE_P16V_SOURCE, 0) & 0xfffc;
- snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, tmp | val);
- }
- return change;
-}
-static const DECLARE_TLV_DB_SCALE(snd_p16v_db_scale1, -5175, 25, 1);
-
-#define P16V_VOL(xname,xreg,xhl) { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
- SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .info = snd_p16v_volume_info, \
- .get = snd_p16v_volume_get, \
- .put = snd_p16v_volume_put, \
- .tlv = { .p = snd_p16v_db_scale1 }, \
- .private_value = ((xreg) | ((xhl) << 8)) \
-}
-
-static struct snd_kcontrol_new p16v_mixer_controls[] __devinitdata = {
- P16V_VOL("HD Analog Front Playback Volume", PLAYBACK_VOLUME_MIXER9, 0),
- P16V_VOL("HD Analog Rear Playback Volume", PLAYBACK_VOLUME_MIXER10, 1),
- P16V_VOL("HD Analog Center/LFE Playback Volume", PLAYBACK_VOLUME_MIXER9, 1),
- P16V_VOL("HD Analog Side Playback Volume", PLAYBACK_VOLUME_MIXER10, 0),
- P16V_VOL("HD SPDIF Front Playback Volume", PLAYBACK_VOLUME_MIXER7, 0),
- P16V_VOL("HD SPDIF Rear Playback Volume", PLAYBACK_VOLUME_MIXER8, 1),
- P16V_VOL("HD SPDIF Center/LFE Playback Volume", PLAYBACK_VOLUME_MIXER7, 1),
- P16V_VOL("HD SPDIF Side Playback Volume", PLAYBACK_VOLUME_MIXER8, 0),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "HD source Capture",
- .info = snd_p16v_capture_source_info,
- .get = snd_p16v_capture_source_get,
- .put = snd_p16v_capture_source_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "HD channel Capture",
- .info = snd_p16v_capture_channel_info,
- .get = snd_p16v_capture_channel_get,
- .put = snd_p16v_capture_channel_put
- },
-};
-
-
-int __devinit snd_p16v_mixer(struct snd_emu10k1 *emu)
-{
- int i, err;
- struct snd_card *card = emu->card;
-
- for (i = 0; i < ARRAY_SIZE(p16v_mixer_controls); i++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&p16v_mixer_controls[i],
- emu))) < 0)
- return err;
- }
- return 0;
-}
-
-#ifdef CONFIG_PM
-
-#define NUM_CHS 1 /* up to 4, but only first channel is used */
-
-int __devinit snd_p16v_alloc_pm_buffer(struct snd_emu10k1 *emu)
-{
- emu->p16v_saved = vmalloc(NUM_CHS * 4 * 0x80);
- if (! emu->p16v_saved)
- return -ENOMEM;
- return 0;
-}
-
-void snd_p16v_free_pm_buffer(struct snd_emu10k1 *emu)
-{
- vfree(emu->p16v_saved);
-}
-
-void snd_p16v_suspend(struct snd_emu10k1 *emu)
-{
- int i, ch;
- unsigned int *val;
-
- val = emu->p16v_saved;
- for (ch = 0; ch < NUM_CHS; ch++)
- for (i = 0; i < 0x80; i++, val++)
- *val = snd_emu10k1_ptr20_read(emu, i, ch);
-}
-
-void snd_p16v_resume(struct snd_emu10k1 *emu)
-{
- int i, ch;
- unsigned int *val;
-
- val = emu->p16v_saved;
- for (ch = 0; ch < NUM_CHS; ch++)
- for (i = 0; i < 0x80; i++, val++)
- snd_emu10k1_ptr20_write(emu, i, ch, *val);
-}
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/p16v.h b/ANDROID_3.4.5/sound/pci/emu10k1/p16v.h
deleted file mode 100644
index 4e0ee1a9..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/p16v.h
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
- * Driver p16v chips
- * Version: 0.21
- *
- * FEATURES currently supported:
- * Output fixed at S32_LE, 2 channel to hw:0,0
- * Rates: 44.1, 48, 96, 192.
- *
- * Changelog:
- * 0.8
- * Use separate card based buffer for periods table.
- * 0.9
- * Use 2 channel output streams instead of 8 channel.
- * (8 channel output streams might be good for ASIO type output)
- * Corrected speaker output, so Front -> Front etc.
- * 0.10
- * Fixed missed interrupts.
- * 0.11
- * Add Sound card model number and names.
- * Add Analog volume controls.
- * 0.12
- * Corrected playback interrupts. Now interrupt per period, instead of half period.
- * 0.13
- * Use single trigger for multichannel.
- * 0.14
- * Mic capture now works at fixed: S32_LE, 96000Hz, Stereo.
- * 0.15
- * Force buffer_size / period_size == INTEGER.
- * 0.16
- * Update p16v.c to work with changed alsa api.
- * 0.17
- * Update p16v.c to work with changed alsa api. Removed boot_devs.
- * 0.18
- * Merging with snd-emu10k1 driver.
- * 0.19
- * One stereo channel at 24bit now works.
- * 0.20
- * Added better register defines.
- * 0.21
- * Split from p16v.c
- *
- *
- * BUGS:
- * Some stability problems when unloading the snd-p16v kernel module.
- * --
- *
- * TODO:
- * SPDIF out.
- * Find out how to change capture sample rates. E.g. To record SPDIF at 48000Hz.
- * Currently capture fixed at 48000Hz.
- *
- * --
- * GENERAL INFO:
- * Model: SB0240
- * P16V Chip: CA0151-DBS
- * Audigy 2 Chip: CA0102-IAT
- * AC97 Codec: STAC 9721
- * ADC: Philips 1361T (Stereo 24bit)
- * DAC: CS4382-K (8-channel, 24bit, 192Khz)
- *
- * This code was initially based on code from ALSA's emu10k1x.c which is:
- * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/********************************************************************************************************/
-/* Audigy2 P16V pointer-offset register set, accessed through the PTR2 and DATA2 registers */
-/********************************************************************************************************/
-
-/* The sample rate of the SPDIF outputs is set by modifying a register in the EMU10K2 PTR register A_SPDIF_SAMPLERATE.
- * The sample rate is also controlled by the same registers that control the rate of the EMU10K2 sample rate converters.
- */
-
-/* Initially all registers from 0x00 to 0x3f have zero contents. */
-#define PLAYBACK_LIST_ADDR 0x00 /* Base DMA address of a list of pointers to each period/size */
- /* One list entry: 4 bytes for DMA address,
- * 4 bytes for period_size << 16.
- * One list entry is 8 bytes long.
- * One list entry for each period in the buffer.
- */
-#define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */
-#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */
-#define PLAYBACK_UNKNOWN3 0x03 /* Not used */
-#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA address */
-#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size. win2000 uses 0x04000000 */
-#define PLAYBACK_POINTER 0x06 /* Playback period pointer. Used with PLAYBACK_LIST_PTR to determine buffer position currently in DAC */
-#define PLAYBACK_FIFO_END_ADDRESS 0x07 /* Playback FIFO end address */
-#define PLAYBACK_FIFO_POINTER 0x08 /* Playback FIFO pointer and number of valid sound samples in cache */
-#define PLAYBACK_UNKNOWN9 0x09 /* Not used */
-#define CAPTURE_DMA_ADDR 0x10 /* Capture DMA address */
-#define CAPTURE_BUFFER_SIZE 0x11 /* Capture buffer size */
-#define CAPTURE_POINTER 0x12 /* Capture buffer pointer. Sample currently in ADC */
-#define CAPTURE_FIFO_POINTER 0x13 /* Capture FIFO pointer and number of valid sound samples in cache */
-#define CAPTURE_P16V_VOLUME1 0x14 /* Low: Capture volume 0xXXXX3030 */
-#define CAPTURE_P16V_VOLUME2 0x15 /* High:Has no effect on capture volume */
-#define CAPTURE_P16V_SOURCE 0x16 /* P16V source select. Set to 0x0700E4E5 for AC97 CAPTURE */
- /* [0:1] Capture input 0 channel select. 0 = Capture output 0.
- * 1 = Capture output 1.
- * 2 = Capture output 2.
- * 3 = Capture output 3.
- * [3:2] Capture input 1 channel select. 0 = Capture output 0.
- * 1 = Capture output 1.
- * 2 = Capture output 2.
- * 3 = Capture output 3.
- * [5:4] Capture input 2 channel select. 0 = Capture output 0.
- * 1 = Capture output 1.
- * 2 = Capture output 2.
- * 3 = Capture output 3.
- * [7:6] Capture input 3 channel select. 0 = Capture output 0.
- * 1 = Capture output 1.
- * 2 = Capture output 2.
- * 3 = Capture output 3.
- * [9:8] Playback input 0 channel select. 0 = Play output 0.
- * 1 = Play output 1.
- * 2 = Play output 2.
- * 3 = Play output 3.
- * [11:10] Playback input 1 channel select. 0 = Play output 0.
- * 1 = Play output 1.
- * 2 = Play output 2.
- * 3 = Play output 3.
- * [13:12] Playback input 2 channel select. 0 = Play output 0.
- * 1 = Play output 1.
- * 2 = Play output 2.
- * 3 = Play output 3.
- * [15:14] Playback input 3 channel select. 0 = Play output 0.
- * 1 = Play output 1.
- * 2 = Play output 2.
- * 3 = Play output 3.
- * [19:16] Playback mixer output enable. 1 bit per channel.
- * [23:20] Capture mixer output enable. 1 bit per channel.
- * [26:24] FX engine channel capture 0 = 0x60-0x67.
- * 1 = 0x68-0x6f.
- * 2 = 0x70-0x77.
- * 3 = 0x78-0x7f.
- * 4 = 0x80-0x87.
- * 5 = 0x88-0x8f.
- * 6 = 0x90-0x97.
- * 7 = 0x98-0x9f.
- * [31:27] Not used.
- */
-
- /* 0x1 = capture on.
- * 0x100 = capture off.
- * 0x200 = capture off.
- * 0x1000 = capture off.
- */
-#define CAPTURE_RATE_STATUS 0x17 /* Capture sample rate. Read only */
- /* [15:0] Not used.
- * [18:16] Channel 0 Detected sample rate. 0 - 44.1khz
- * 1 - 48 khz
- * 2 - 96 khz
- * 3 - 192 khz
- * 7 - undefined rate.
- * [19] Channel 0. 1 - Valid, 0 - Not Valid.
- * [22:20] Channel 1 Detected sample rate.
- * [23] Channel 1. 1 - Valid, 0 - Not Valid.
- * [26:24] Channel 2 Detected sample rate.
- * [27] Channel 2. 1 - Valid, 0 - Not Valid.
- * [30:28] Channel 3 Detected sample rate.
- * [31] Channel 3. 1 - Valid, 0 - Not Valid.
- */
-/* 0x18 - 0x1f unused */
-#define PLAYBACK_LAST_SAMPLE 0x20 /* The sample currently being played. Read only */
-/* 0x21 - 0x3f unused */
-#define BASIC_INTERRUPT 0x40 /* Used by both playback and capture interrupt handler */
- /* Playback (0x1<<channel_id) Don't touch high 16bits. */
- /* Capture (0x100<<channel_id). not tested */
- /* Start Playback [3:0] (one bit per channel)
- * Start Capture [11:8] (one bit per channel)
- * Record source select for channel 0 [18:16]
- * Record source select for channel 1 [22:20]
- * Record source select for channel 2 [26:24]
- * Record source select for channel 3 [30:28]
- * 0 - SPDIF channel.
- * 1 - I2S channel.
- * 2 - SRC48 channel.
- * 3 - SRCMulti_SPDIF channel.
- * 4 - SRCMulti_I2S channel.
- * 5 - SPDIF channel.
- * 6 - fxengine capture.
- * 7 - AC97 capture.
- */
- /* Default 41110000.
- * Writing 0xffffffff hangs the PC.
- * Writing 0xffff0000 -> 77770000 so it must be some sort of route.
- * bit 0x1 starts DMA playback on channel_id 0
- */
-/* 0x41,42 take values from 0 - 0xffffffff, but have no effect on playback */
-/* 0x43,0x48 do not remember settings */
-/* 0x41-45 unused */
-#define WATERMARK 0x46 /* Test bit to indicate cache level usage */
- /* Values it can have while playing on channel 0.
- * 0000f000, 0000f004, 0000f008, 0000f00c.
- * Readonly.
- */
-/* 0x47-0x4f unused */
-/* 0x50-0x5f Capture cache data */
-#define SRCSel 0x60 /* SRCSel. Default 0x4. Bypass P16V 0x14 */
- /* [0] 0 = 10K2 audio, 1 = SRC48 mixer output.
- * [2] 0 = 10K2 audio, 1 = SRCMulti SPDIF mixer output.
- * [4] 0 = 10K2 audio, 1 = SRCMulti I2S mixer output.
- */
- /* SRC48 converts samples rates 44.1, 48, 96, 192 to 48 khz. */
- /* SRCMulti converts 48khz samples rates to 44.1, 48, 96, 192 to 48. */
- /* SRC48 and SRCMULTI sample rate select and output select. */
- /* 0xffffffff -> 0xC0000015
- * 0xXXXXXXX4 = Enable Front Left/Right
- * Enable PCMs
- */
-
-/* 0x61 -> 0x6c are Volume controls */
-#define PLAYBACK_VOLUME_MIXER1 0x61 /* SRC48 Low to mixer input volume control. */
-#define PLAYBACK_VOLUME_MIXER2 0x62 /* SRC48 High to mixer input volume control. */
-#define PLAYBACK_VOLUME_MIXER3 0x63 /* SRCMULTI SPDIF Low to mixer input volume control. */
-#define PLAYBACK_VOLUME_MIXER4 0x64 /* SRCMULTI SPDIF High to mixer input volume control. */
-#define PLAYBACK_VOLUME_MIXER5 0x65 /* SRCMULTI I2S Low to mixer input volume control. */
-#define PLAYBACK_VOLUME_MIXER6 0x66 /* SRCMULTI I2S High to mixer input volume control. */
-#define PLAYBACK_VOLUME_MIXER7 0x67 /* P16V Low to SRCMULTI SPDIF mixer input volume control. */
-#define PLAYBACK_VOLUME_MIXER8 0x68 /* P16V High to SRCMULTI SPDIF mixer input volume control. */
-#define PLAYBACK_VOLUME_MIXER9 0x69 /* P16V Low to SRCMULTI I2S mixer input volume control. */
- /* 0xXXXX3030 = PCM0 Volume (Front).
- * 0x3030XXXX = PCM1 Volume (Center)
- */
-#define PLAYBACK_VOLUME_MIXER10 0x6a /* P16V High to SRCMULTI I2S mixer input volume control. */
- /* 0x3030XXXX = PCM3 Volume (Rear). */
-#define PLAYBACK_VOLUME_MIXER11 0x6b /* E10K2 Low to SRC48 mixer input volume control. */
-#define PLAYBACK_VOLUME_MIXER12 0x6c /* E10K2 High to SRC48 mixer input volume control. */
-
-#define SRC48_ENABLE 0x6d /* SRC48 input audio enable */
- /* SRC48 converts samples rates 44.1, 48, 96, 192 to 48 khz. */
- /* [23:16] The corresponding P16V channel to SRC48 enabled if == 1.
- * [31:24] The corresponding E10K2 channel to SRC48 enabled.
- */
-#define SRCMULTI_ENABLE 0x6e /* SRCMulti input audio enable. Default 0xffffffff */
- /* SRCMulti converts 48khz samples rates to 44.1, 48, 96, 192 to 48. */
- /* [7:0] The corresponding P16V channel to SRCMulti_I2S enabled if == 1.
- * [15:8] The corresponding E10K2 channel to SRCMulti I2S enabled.
- * [23:16] The corresponding P16V channel to SRCMulti SPDIF enabled.
- * [31:24] The corresponding E10K2 channel to SRCMulti SPDIF enabled.
- */
- /* Bypass P16V 0xff00ff00
- * Bitmap. 0 = Off, 1 = On.
- * P16V playback outputs:
- * 0xXXXXXXX1 = PCM0 Left. (Front)
- * 0xXXXXXXX2 = PCM0 Right.
- * 0xXXXXXXX4 = PCM1 Left. (Center/LFE)
- * 0xXXXXXXX8 = PCM1 Right.
- * 0xXXXXXX1X = PCM2 Left. (Unknown)
- * 0xXXXXXX2X = PCM2 Right.
- * 0xXXXXXX4X = PCM3 Left. (Rear)
- * 0xXXXXXX8X = PCM3 Right.
- */
-#define AUDIO_OUT_ENABLE 0x6f /* Default: 000100FF */
- /* [3:0] Does something, but not documented. Probably capture enable.
- * [7:4] Playback channels enable. not documented.
- * [16] AC97 output enable if == 1
- * [30] 0 = SRCMulti_I2S input from fxengine 0x68-0x6f.
- * 1 = SRCMulti_I2S input from SRC48 output.
- * [31] 0 = SRCMulti_SPDIF input from fxengine 0x60-0x67.
- * 1 = SRCMulti_SPDIF input from SRC48 output.
- */
- /* 0xffffffff -> C00100FF */
- /* 0 -> Not playback sound, irq still running */
- /* 0xXXXXXX10 = PCM0 Left/Right On. (Front)
- * 0xXXXXXX20 = PCM1 Left/Right On. (Center/LFE)
- * 0xXXXXXX40 = PCM2 Left/Right On. (Unknown)
- * 0xXXXXXX80 = PCM3 Left/Right On. (Rear)
- */
-#define PLAYBACK_SPDIF_SELECT 0x70 /* Default: 12030F00 */
- /* 0xffffffff -> 3FF30FFF */
- /* 0x00000001 pauses stream/irq fail. */
- /* All other bits do not effect playback */
-#define PLAYBACK_SPDIF_SRC_SELECT 0x71 /* Default: 0000E4E4 */
- /* 0xffffffff -> F33FFFFF */
- /* All bits do not effect playback */
-#define PLAYBACK_SPDIF_USER_DATA0 0x72 /* SPDIF out user data 0 */
-#define PLAYBACK_SPDIF_USER_DATA1 0x73 /* SPDIF out user data 1 */
-/* 0x74-0x75 unknown */
-#define CAPTURE_SPDIF_CONTROL 0x76 /* SPDIF in control setting */
-#define CAPTURE_SPDIF_STATUS 0x77 /* SPDIF in status */
-#define CAPURE_SPDIF_USER_DATA0 0x78 /* SPDIF in user data 0 */
-#define CAPURE_SPDIF_USER_DATA1 0x79 /* SPDIF in user data 1 */
-#define CAPURE_SPDIF_USER_DATA2 0x7a /* SPDIF in user data 2 */
-
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/p17v.h b/ANDROID_3.4.5/sound/pci/emu10k1/p17v.h
deleted file mode 100644
index 4ef5f68a..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/p17v.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
- * Driver p17v chips
- * Version: 0.01
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/******************************************************************************/
-/* Audigy2Value Tina (P17V) pointer-offset register set,
- * accessed through the PTR20 and DATA24 registers */
-/******************************************************************************/
-
-/* 00 - 07: Not used */
-#define P17V_PLAYBACK_FIFO_PTR 0x08 /* Current playback fifo pointer
- * and number of sound samples in cache.
- */
-/* 09 - 12: Not used */
-#define P17V_CAPTURE_FIFO_PTR 0x13 /* Current capture fifo pointer
- * and number of sound samples in cache.
- */
-/* 14 - 17: Not used */
-#define P17V_PB_CHN_SEL 0x18 /* P17v playback channel select */
-#define P17V_SE_SLOT_SEL_L 0x19 /* Sound Engine slot select low */
-#define P17V_SE_SLOT_SEL_H 0x1a /* Sound Engine slot select high */
-/* 1b - 1f: Not used */
-/* 20 - 2f: Not used */
-/* 30 - 3b: Not used */
-#define P17V_SPI 0x3c /* SPI interface register */
-#define P17V_I2C_ADDR 0x3d /* I2C Address */
-#define P17V_I2C_0 0x3e /* I2C Data */
-#define P17V_I2C_1 0x3f /* I2C Data */
-/* I2C values */
-#define I2C_A_ADC_ADD_MASK 0x000000fe /*The address is a 7 bit address */
-#define I2C_A_ADC_RW_MASK 0x00000001 /*bit mask for R/W */
-#define I2C_A_ADC_TRANS_MASK 0x00000010 /*Bit mask for I2c address DAC value */
-#define I2C_A_ADC_ABORT_MASK 0x00000020 /*Bit mask for I2C transaction abort flag */
-#define I2C_A_ADC_LAST_MASK 0x00000040 /*Bit mask for Last word transaction */
-#define I2C_A_ADC_BYTE_MASK 0x00000080 /*Bit mask for Byte Mode */
-
-#define I2C_A_ADC_ADD 0x00000034 /*This is the Device address for ADC */
-#define I2C_A_ADC_READ 0x00000001 /*To perform a read operation */
-#define I2C_A_ADC_START 0x00000100 /*Start I2C transaction */
-#define I2C_A_ADC_ABORT 0x00000200 /*I2C transaction abort */
-#define I2C_A_ADC_LAST 0x00000400 /*I2C last transaction */
-#define I2C_A_ADC_BYTE 0x00000800 /*I2C one byte mode */
-
-#define I2C_D_ADC_REG_MASK 0xfe000000 /*ADC address register */
-#define I2C_D_ADC_DAT_MASK 0x01ff0000 /*ADC data register */
-
-#define ADC_TIMEOUT 0x00000007 /*ADC Timeout Clock Disable */
-#define ADC_IFC_CTRL 0x0000000b /*ADC Interface Control */
-#define ADC_MASTER 0x0000000c /*ADC Master Mode Control */
-#define ADC_POWER 0x0000000d /*ADC PowerDown Control */
-#define ADC_ATTEN_ADCL 0x0000000e /*ADC Attenuation ADCL */
-#define ADC_ATTEN_ADCR 0x0000000f /*ADC Attenuation ADCR */
-#define ADC_ALC_CTRL1 0x00000010 /*ADC ALC Control 1 */
-#define ADC_ALC_CTRL2 0x00000011 /*ADC ALC Control 2 */
-#define ADC_ALC_CTRL3 0x00000012 /*ADC ALC Control 3 */
-#define ADC_NOISE_CTRL 0x00000013 /*ADC Noise Gate Control */
-#define ADC_LIMIT_CTRL 0x00000014 /*ADC Limiter Control */
-#define ADC_MUX 0x00000015 /*ADC Mux offset */
-#if 0
-/* FIXME: Not tested yet. */
-#define ADC_GAIN_MASK 0x000000ff //Mask for ADC Gain
-#define ADC_ZERODB 0x000000cf //Value to set ADC to 0dB
-#define ADC_MUTE_MASK 0x000000c0 //Mask for ADC mute
-#define ADC_MUTE 0x000000c0 //Value to mute ADC
-#define ADC_OSR 0x00000008 //Mask for ADC oversample rate select
-#define ADC_TIMEOUT_DISABLE 0x00000008 //Value and mask to disable Timeout clock
-#define ADC_HPF_DISABLE 0x00000100 //Value and mask to disable High pass filter
-#define ADC_TRANWIN_MASK 0x00000070 //Mask for Length of Transient Window
-#endif
-
-#define ADC_MUX_MASK 0x0000000f //Mask for ADC Mux
-#define ADC_MUX_0 0x00000001 //Value to select Unknown at ADC Mux (Not used)
-#define ADC_MUX_1 0x00000002 //Value to select Unknown at ADC Mux (Not used)
-#define ADC_MUX_2 0x00000004 //Value to select Mic at ADC Mux
-#define ADC_MUX_3 0x00000008 //Value to select Line-In at ADC Mux
-
-#define P17V_START_AUDIO 0x40 /* Start Audio bit */
-/* 41 - 47: Reserved */
-#define P17V_START_CAPTURE 0x48 /* Start Capture bit */
-#define P17V_CAPTURE_FIFO_BASE 0x49 /* Record FIFO base address */
-#define P17V_CAPTURE_FIFO_SIZE 0x4a /* Record FIFO buffer size */
-#define P17V_CAPTURE_FIFO_INDEX 0x4b /* Record FIFO capture index */
-#define P17V_CAPTURE_VOL_H 0x4c /* P17v capture volume control */
-#define P17V_CAPTURE_VOL_L 0x4d /* P17v capture volume control */
-/* 4e - 4f: Not used */
-/* 50 - 5f: Not used */
-#define P17V_SRCSel 0x60 /* SRC48 and SRCMulti sample rate select
- * and output select
- */
-#define P17V_MIXER_AC97_10K1_VOL_L 0x61 /* 10K to Mixer_AC97 input volume control */
-#define P17V_MIXER_AC97_10K1_VOL_H 0x62 /* 10K to Mixer_AC97 input volume control */
-#define P17V_MIXER_AC97_P17V_VOL_L 0x63 /* P17V to Mixer_AC97 input volume control */
-#define P17V_MIXER_AC97_P17V_VOL_H 0x64 /* P17V to Mixer_AC97 input volume control */
-#define P17V_MIXER_AC97_SRP_REC_VOL_L 0x65 /* SRP Record to Mixer_AC97 input volume control */
-#define P17V_MIXER_AC97_SRP_REC_VOL_H 0x66 /* SRP Record to Mixer_AC97 input volume control */
-/* 67 - 68: Reserved */
-#define P17V_MIXER_Spdif_10K1_VOL_L 0x69 /* 10K to Mixer_Spdif input volume control */
-#define P17V_MIXER_Spdif_10K1_VOL_H 0x6A /* 10K to Mixer_Spdif input volume control */
-#define P17V_MIXER_Spdif_P17V_VOL_L 0x6B /* P17V to Mixer_Spdif input volume control */
-#define P17V_MIXER_Spdif_P17V_VOL_H 0x6C /* P17V to Mixer_Spdif input volume control */
-#define P17V_MIXER_Spdif_SRP_REC_VOL_L 0x6D /* SRP Record to Mixer_Spdif input volume control */
-#define P17V_MIXER_Spdif_SRP_REC_VOL_H 0x6E /* SRP Record to Mixer_Spdif input volume control */
-/* 6f - 70: Reserved */
-#define P17V_MIXER_I2S_10K1_VOL_L 0x71 /* 10K to Mixer_I2S input volume control */
-#define P17V_MIXER_I2S_10K1_VOL_H 0x72 /* 10K to Mixer_I2S input volume control */
-#define P17V_MIXER_I2S_P17V_VOL_L 0x73 /* P17V to Mixer_I2S input volume control */
-#define P17V_MIXER_I2S_P17V_VOL_H 0x74 /* P17V to Mixer_I2S input volume control */
-#define P17V_MIXER_I2S_SRP_REC_VOL_L 0x75 /* SRP Record to Mixer_I2S input volume control */
-#define P17V_MIXER_I2S_SRP_REC_VOL_H 0x76 /* SRP Record to Mixer_I2S input volume control */
-/* 77 - 78: Reserved */
-#define P17V_MIXER_AC97_ENABLE 0x79 /* Mixer AC97 input audio enable */
-#define P17V_MIXER_SPDIF_ENABLE 0x7A /* Mixer SPDIF input audio enable */
-#define P17V_MIXER_I2S_ENABLE 0x7B /* Mixer I2S input audio enable */
-#define P17V_AUDIO_OUT_ENABLE 0x7C /* Audio out enable */
-#define P17V_MIXER_ATT 0x7D /* SRP Mixer Attenuation Select */
-#define P17V_SRP_RECORD_SRR 0x7E /* SRP Record channel source Select */
-#define P17V_SOFT_RESET_SRP_MIXER 0x7F /* SRP and mixer soft reset */
-
-#define P17V_AC97_OUT_MASTER_VOL_L 0x80 /* AC97 Output master volume control */
-#define P17V_AC97_OUT_MASTER_VOL_H 0x81 /* AC97 Output master volume control */
-#define P17V_SPDIF_OUT_MASTER_VOL_L 0x82 /* SPDIF Output master volume control */
-#define P17V_SPDIF_OUT_MASTER_VOL_H 0x83 /* SPDIF Output master volume control */
-#define P17V_I2S_OUT_MASTER_VOL_L 0x84 /* I2S Output master volume control */
-#define P17V_I2S_OUT_MASTER_VOL_H 0x85 /* I2S Output master volume control */
-/* 86 - 87: Not used */
-#define P17V_I2S_CHANNEL_SWAP_PHASE_INVERSE 0x88 /* I2S out mono channel swap
- * and phase inverse */
-#define P17V_SPDIF_CHANNEL_SWAP_PHASE_INVERSE 0x89 /* SPDIF out mono channel swap
- * and phase inverse */
-/* 8A: Not used */
-#define P17V_SRP_P17V_ESR 0x8B /* SRP_P17V estimated sample rate and rate lock */
-#define P17V_SRP_REC_ESR 0x8C /* SRP_REC estimated sample rate and rate lock */
-#define P17V_SRP_BYPASS 0x8D /* srps channel bypass and srps bypass */
-/* 8E - 92: Not used */
-#define P17V_I2S_SRC_SEL 0x93 /* I2SIN mode sel */
-
-
-
-
-
-
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/timer.c b/ANDROID_3.4.5/sound/pci/emu10k1/timer.c
deleted file mode 100644
index 72321e94..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/timer.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) by Lee Revell <rlrevell@joe-job.com>
- * Clemens Ladisch <clemens@ladisch.de>
- * Routines for control of EMU10K1 chips
- *
- * BUGS:
- * --
- *
- * TODO:
- * --
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <sound/core.h>
-#include <sound/emu10k1.h>
-
-static int snd_emu10k1_timer_start(struct snd_timer *timer)
-{
- struct snd_emu10k1 *emu;
- unsigned long flags;
- unsigned int delay;
-
- emu = snd_timer_chip(timer);
- delay = timer->sticks - 1;
- if (delay < 5 ) /* minimum time is 5 ticks */
- delay = 5;
- spin_lock_irqsave(&emu->reg_lock, flags);
- snd_emu10k1_intr_enable(emu, INTE_INTERVALTIMERENB);
- outw(delay & TIMER_RATE_MASK, emu->port + TIMER);
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return 0;
-}
-
-static int snd_emu10k1_timer_stop(struct snd_timer *timer)
-{
- struct snd_emu10k1 *emu;
- unsigned long flags;
-
- emu = snd_timer_chip(timer);
- spin_lock_irqsave(&emu->reg_lock, flags);
- snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB);
- spin_unlock_irqrestore(&emu->reg_lock, flags);
- return 0;
-}
-
-static int snd_emu10k1_timer_precise_resolution(struct snd_timer *timer,
- unsigned long *num, unsigned long *den)
-{
- *num = 1;
- *den = 48000;
- return 0;
-}
-
-static struct snd_timer_hardware snd_emu10k1_timer_hw = {
- .flags = SNDRV_TIMER_HW_AUTO,
- .resolution = 20833, /* 1 sample @ 48KHZ = 20.833...us */
- .ticks = 1024,
- .start = snd_emu10k1_timer_start,
- .stop = snd_emu10k1_timer_stop,
- .precise_resolution = snd_emu10k1_timer_precise_resolution,
-};
-
-int __devinit snd_emu10k1_timer(struct snd_emu10k1 *emu, int device)
-{
- struct snd_timer *timer = NULL;
- struct snd_timer_id tid;
- int err;
-
- tid.dev_class = SNDRV_TIMER_CLASS_CARD;
- tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
- tid.card = emu->card->number;
- tid.device = device;
- tid.subdevice = 0;
- if ((err = snd_timer_new(emu->card, "EMU10K1", &tid, &timer)) >= 0) {
- strcpy(timer->name, "EMU10K1 timer");
- timer->private_data = emu;
- timer->hw = snd_emu10k1_timer_hw;
- }
- emu->timer = timer;
- return err;
-}
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/tina2.h b/ANDROID_3.4.5/sound/pci/emu10k1/tina2.h
deleted file mode 100644
index f2d8eb6c..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/tina2.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
- * Driver tina2 chips
- * Version: 0.1
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/********************************************************************************************************/
-/* Audigy2 Tina2 (notebook) pointer-offset register set, accessed through the PTR2 and DATA2 registers */
-/********************************************************************************************************/
-
-#define TINA2_VOLUME 0x71 /* Attenuate playback volume to prevent distortion. */
- /* The windows driver does not use this register,
- * so it must use some other attenuation method.
- * Without this, the output is 12dB too loud,
- * resulting in distortion.
- */
-
diff --git a/ANDROID_3.4.5/sound/pci/emu10k1/voice.c b/ANDROID_3.4.5/sound/pci/emu10k1/voice.c
deleted file mode 100644
index 101e7cb7..00000000
--- a/ANDROID_3.4.5/sound/pci/emu10k1/voice.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Creative Labs, Inc.
- * Lee Revell <rlrevell@joe-job.com>
- * Routines for control of EMU10K1 chips - voice manager
- *
- * Rewrote voice allocator for multichannel support - rlrevell 12/2004
- *
- * BUGS:
- * --
- *
- * TODO:
- * --
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/time.h>
-#include <linux/export.h>
-#include <sound/core.h>
-#include <sound/emu10k1.h>
-
-/* Previously the voice allocator started at 0 every time. The new voice
- * allocator uses a round robin scheme. The next free voice is tracked in
- * the card record and each allocation begins where the last left off. The
- * hardware requires stereo interleaved voices be aligned to an even/odd
- * boundary. For multichannel voice allocation we ensure than the block of
- * voices does not cross the 32 voice boundary. This simplifies the
- * multichannel support and ensures we can use a single write to the
- * (set|clear)_loop_stop registers. Otherwise (for example) the voices would
- * get out of sync when pausing/resuming a stream.
- * --rlrevell
- */
-
-static int voice_alloc(struct snd_emu10k1 *emu, int type, int number,
- struct snd_emu10k1_voice **rvoice)
-{
- struct snd_emu10k1_voice *voice;
- int i, j, k, first_voice, last_voice, skip;
-
- *rvoice = NULL;
- first_voice = last_voice = 0;
- for (i = emu->next_free_voice, j = 0; j < NUM_G ; i += number, j += number) {
- /*
- printk(KERN_DEBUG "i %d j %d next free %d!\n",
- i, j, emu->next_free_voice);
- */
- i %= NUM_G;
-
- /* stereo voices must be even/odd */
- if ((number == 2) && (i % 2)) {
- i++;
- continue;
- }
-
- skip = 0;
- for (k = 0; k < number; k++) {
- voice = &emu->voices[(i+k) % NUM_G];
- if (voice->use) {
- skip = 1;
- break;
- }
- }
- if (!skip) {
- /* printk(KERN_DEBUG "allocated voice %d\n", i); */
- first_voice = i;
- last_voice = (i + number) % NUM_G;
- emu->next_free_voice = last_voice;
- break;
- }
- }
-
- if (first_voice == last_voice)
- return -ENOMEM;
-
- for (i = 0; i < number; i++) {
- voice = &emu->voices[(first_voice + i) % NUM_G];
- /*
- printk(kERN_DEBUG "voice alloc - %i, %i of %i\n",
- voice->number, idx-first_voice+1, number);
- */
- voice->use = 1;
- switch (type) {
- case EMU10K1_PCM:
- voice->pcm = 1;
- break;
- case EMU10K1_SYNTH:
- voice->synth = 1;
- break;
- case EMU10K1_MIDI:
- voice->midi = 1;
- break;
- case EMU10K1_EFX:
- voice->efx = 1;
- break;
- }
- }
- *rvoice = &emu->voices[first_voice];
- return 0;
-}
-
-int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int number,
- struct snd_emu10k1_voice **rvoice)
-{
- unsigned long flags;
- int result;
-
- if (snd_BUG_ON(!rvoice))
- return -EINVAL;
- if (snd_BUG_ON(!number))
- return -EINVAL;
-
- spin_lock_irqsave(&emu->voice_lock, flags);
- for (;;) {
- result = voice_alloc(emu, type, number, rvoice);
- if (result == 0 || type == EMU10K1_SYNTH || type == EMU10K1_MIDI)
- break;
-
- /* free a voice from synth */
- if (emu->get_synth_voice) {
- result = emu->get_synth_voice(emu);
- if (result >= 0) {
- struct snd_emu10k1_voice *pvoice = &emu->voices[result];
- pvoice->interrupt = NULL;
- pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = pvoice->efx = 0;
- pvoice->epcm = NULL;
- }
- }
- if (result < 0)
- break;
- }
- spin_unlock_irqrestore(&emu->voice_lock, flags);
-
- return result;
-}
-
-EXPORT_SYMBOL(snd_emu10k1_voice_alloc);
-
-int snd_emu10k1_voice_free(struct snd_emu10k1 *emu,
- struct snd_emu10k1_voice *pvoice)
-{
- unsigned long flags;
-
- if (snd_BUG_ON(!pvoice))
- return -EINVAL;
- spin_lock_irqsave(&emu->voice_lock, flags);
- pvoice->interrupt = NULL;
- pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = pvoice->efx = 0;
- pvoice->epcm = NULL;
- snd_emu10k1_voice_init(emu, pvoice->number);
- spin_unlock_irqrestore(&emu->voice_lock, flags);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_emu10k1_voice_free);
diff --git a/ANDROID_3.4.5/sound/pci/ens1370.c b/ANDROID_3.4.5/sound/pci/ens1370.c
deleted file mode 100644
index 47a245e8..00000000
--- a/ANDROID_3.4.5/sound/pci/ens1370.c
+++ /dev/null
@@ -1,2513 +0,0 @@
-/*
- * Driver for Ensoniq ES1370/ES1371 AudioPCI soundcard
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
- * Thomas Sailer <sailer@ife.ee.ethz.ch>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/* Power-Management-Code ( CONFIG_PM )
- * for ens1371 only ( FIXME )
- * derived from cs4281.c, atiixp.c and via82xx.c
- * using http://www.alsa-project.org/~tiwai/writing-an-alsa-driver/
- * by Kurt J. Bosch
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/gameport.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/rawmidi.h>
-#ifdef CHIP1371
-#include <sound/ac97_codec.h>
-#else
-#include <sound/ak4531_codec.h>
-#endif
-#include <sound/initval.h>
-#include <sound/asoundef.h>
-
-#ifndef CHIP1371
-#undef CHIP1370
-#define CHIP1370
-#endif
-
-#ifdef CHIP1370
-#define DRIVER_NAME "ENS1370"
-#else
-#define DRIVER_NAME "ENS1371"
-#endif
-
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Thomas Sailer <sailer@ife.ee.ethz.ch>");
-MODULE_LICENSE("GPL");
-#ifdef CHIP1370
-MODULE_DESCRIPTION("Ensoniq AudioPCI ES1370");
-MODULE_SUPPORTED_DEVICE("{{Ensoniq,AudioPCI-97 ES1370},"
- "{Creative Labs,SB PCI64/128 (ES1370)}}");
-#endif
-#ifdef CHIP1371
-MODULE_DESCRIPTION("Ensoniq/Creative AudioPCI ES1371+");
-MODULE_SUPPORTED_DEVICE("{{Ensoniq,AudioPCI ES1371/73},"
- "{Ensoniq,AudioPCI ES1373},"
- "{Creative Labs,Ectiva EV1938},"
- "{Creative Labs,SB PCI64/128 (ES1371/73)},"
- "{Creative Labs,Vibra PCI128},"
- "{Ectiva,EV1938}}");
-#endif
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK
-#endif
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
-#ifdef SUPPORT_JOYSTICK
-#ifdef CHIP1371
-static int joystick_port[SNDRV_CARDS];
-#else
-static bool joystick[SNDRV_CARDS];
-#endif
-#endif
-#ifdef CHIP1371
-static int spdif[SNDRV_CARDS];
-static int lineio[SNDRV_CARDS];
-#endif
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Ensoniq AudioPCI soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Ensoniq AudioPCI soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Ensoniq AudioPCI soundcard.");
-#ifdef SUPPORT_JOYSTICK
-#ifdef CHIP1371
-module_param_array(joystick_port, int, NULL, 0444);
-MODULE_PARM_DESC(joystick_port, "Joystick port address.");
-#else
-module_param_array(joystick, bool, NULL, 0444);
-MODULE_PARM_DESC(joystick, "Enable joystick.");
-#endif
-#endif /* SUPPORT_JOYSTICK */
-#ifdef CHIP1371
-module_param_array(spdif, int, NULL, 0444);
-MODULE_PARM_DESC(spdif, "S/PDIF output (-1 = none, 0 = auto, 1 = force).");
-module_param_array(lineio, int, NULL, 0444);
-MODULE_PARM_DESC(lineio, "Line In to Rear Out (0 = auto, 1 = force).");
-#endif
-
-/* ES1371 chip ID */
-/* This is a little confusing because all ES1371 compatible chips have the
- same DEVICE_ID, the only thing differentiating them is the REV_ID field.
- This is only significant if you want to enable features on the later parts.
- Yes, I know it's stupid and why didn't we use the sub IDs?
-*/
-#define ES1371REV_ES1373_A 0x04
-#define ES1371REV_ES1373_B 0x06
-#define ES1371REV_CT5880_A 0x07
-#define CT5880REV_CT5880_C 0x02
-#define CT5880REV_CT5880_D 0x03 /* ??? -jk */
-#define CT5880REV_CT5880_E 0x04 /* mw */
-#define ES1371REV_ES1371_B 0x09
-#define EV1938REV_EV1938_A 0x00
-#define ES1371REV_ES1373_8 0x08
-
-/*
- * Direct registers
- */
-
-#define ES_REG(ensoniq, x) ((ensoniq)->port + ES_REG_##x)
-
-#define ES_REG_CONTROL 0x00 /* R/W: Interrupt/Chip select control register */
-#define ES_1370_ADC_STOP (1<<31) /* disable capture buffer transfers */
-#define ES_1370_XCTL1 (1<<30) /* general purpose output bit */
-#define ES_1373_BYPASS_P1 (1<<31) /* bypass SRC for PB1 */
-#define ES_1373_BYPASS_P2 (1<<30) /* bypass SRC for PB2 */
-#define ES_1373_BYPASS_R (1<<29) /* bypass SRC for REC */
-#define ES_1373_TEST_BIT (1<<28) /* should be set to 0 for normal operation */
-#define ES_1373_RECEN_B (1<<27) /* mix record with playback for I2S/SPDIF out */
-#define ES_1373_SPDIF_THRU (1<<26) /* 0 = SPDIF thru mode, 1 = SPDIF == dig out */
-#define ES_1371_JOY_ASEL(o) (((o)&0x03)<<24)/* joystick port mapping */
-#define ES_1371_JOY_ASELM (0x03<<24) /* mask for above */
-#define ES_1371_JOY_ASELI(i) (((i)>>24)&0x03)
-#define ES_1371_GPIO_IN(i) (((i)>>20)&0x0f)/* GPIO in [3:0] pins - R/O */
-#define ES_1370_PCLKDIVO(o) (((o)&0x1fff)<<16)/* clock divide ratio for DAC2 */
-#define ES_1370_PCLKDIVM ((0x1fff)<<16) /* mask for above */
-#define ES_1370_PCLKDIVI(i) (((i)>>16)&0x1fff)/* clock divide ratio for DAC2 */
-#define ES_1371_GPIO_OUT(o) (((o)&0x0f)<<16)/* GPIO out [3:0] pins - W/R */
-#define ES_1371_GPIO_OUTM (0x0f<<16) /* mask for above */
-#define ES_MSFMTSEL (1<<15) /* MPEG serial data format; 0 = SONY, 1 = I2S */
-#define ES_1370_M_SBB (1<<14) /* clock source for DAC - 0 = clock generator; 1 = MPEG clocks */
-#define ES_1371_SYNC_RES (1<<14) /* Warm AC97 reset */
-#define ES_1370_WTSRSEL(o) (((o)&0x03)<<12)/* fixed frequency clock for DAC1 */
-#define ES_1370_WTSRSELM (0x03<<12) /* mask for above */
-#define ES_1371_ADC_STOP (1<<13) /* disable CCB transfer capture information */
-#define ES_1371_PWR_INTRM (1<<12) /* power level change interrupts enable */
-#define ES_1370_DAC_SYNC (1<<11) /* DAC's are synchronous */
-#define ES_1371_M_CB (1<<11) /* capture clock source; 0 = AC'97 ADC; 1 = I2S */
-#define ES_CCB_INTRM (1<<10) /* CCB voice interrupts enable */
-#define ES_1370_M_CB (1<<9) /* capture clock source; 0 = ADC; 1 = MPEG */
-#define ES_1370_XCTL0 (1<<8) /* generap purpose output bit */
-#define ES_1371_PDLEV(o) (((o)&0x03)<<8) /* current power down level */
-#define ES_1371_PDLEVM (0x03<<8) /* mask for above */
-#define ES_BREQ (1<<7) /* memory bus request enable */
-#define ES_DAC1_EN (1<<6) /* DAC1 playback channel enable */
-#define ES_DAC2_EN (1<<5) /* DAC2 playback channel enable */
-#define ES_ADC_EN (1<<4) /* ADC capture channel enable */
-#define ES_UART_EN (1<<3) /* UART enable */
-#define ES_JYSTK_EN (1<<2) /* Joystick module enable */
-#define ES_1370_CDC_EN (1<<1) /* Codec interface enable */
-#define ES_1371_XTALCKDIS (1<<1) /* Xtal clock disable */
-#define ES_1370_SERR_DISABLE (1<<0) /* PCI serr signal disable */
-#define ES_1371_PCICLKDIS (1<<0) /* PCI clock disable */
-#define ES_REG_STATUS 0x04 /* R/O: Interrupt/Chip select status register */
-#define ES_INTR (1<<31) /* Interrupt is pending */
-#define ES_1371_ST_AC97_RST (1<<29) /* CT5880 AC'97 Reset bit */
-#define ES_1373_REAR_BIT27 (1<<27) /* rear bits: 000 - front, 010 - mirror, 101 - separate */
-#define ES_1373_REAR_BIT26 (1<<26)
-#define ES_1373_REAR_BIT24 (1<<24)
-#define ES_1373_GPIO_INT_EN(o)(((o)&0x0f)<<20)/* GPIO [3:0] pins - interrupt enable */
-#define ES_1373_SPDIF_EN (1<<18) /* SPDIF enable */
-#define ES_1373_SPDIF_TEST (1<<17) /* SPDIF test */
-#define ES_1371_TEST (1<<16) /* test ASIC */
-#define ES_1373_GPIO_INT(i) (((i)&0x0f)>>12)/* GPIO [3:0] pins - interrupt pending */
-#define ES_1370_CSTAT (1<<10) /* CODEC is busy or register write in progress */
-#define ES_1370_CBUSY (1<<9) /* CODEC is busy */
-#define ES_1370_CWRIP (1<<8) /* CODEC register write in progress */
-#define ES_1371_SYNC_ERR (1<<8) /* CODEC synchronization error occurred */
-#define ES_1371_VC(i) (((i)>>6)&0x03) /* voice code from CCB module */
-#define ES_1370_VC(i) (((i)>>5)&0x03) /* voice code from CCB module */
-#define ES_1371_MPWR (1<<5) /* power level interrupt pending */
-#define ES_MCCB (1<<4) /* CCB interrupt pending */
-#define ES_UART (1<<3) /* UART interrupt pending */
-#define ES_DAC1 (1<<2) /* DAC1 channel interrupt pending */
-#define ES_DAC2 (1<<1) /* DAC2 channel interrupt pending */
-#define ES_ADC (1<<0) /* ADC channel interrupt pending */
-#define ES_REG_UART_DATA 0x08 /* R/W: UART data register */
-#define ES_REG_UART_STATUS 0x09 /* R/O: UART status register */
-#define ES_RXINT (1<<7) /* RX interrupt occurred */
-#define ES_TXINT (1<<2) /* TX interrupt occurred */
-#define ES_TXRDY (1<<1) /* transmitter ready */
-#define ES_RXRDY (1<<0) /* receiver ready */
-#define ES_REG_UART_CONTROL 0x09 /* W/O: UART control register */
-#define ES_RXINTEN (1<<7) /* RX interrupt enable */
-#define ES_TXINTENO(o) (((o)&0x03)<<5) /* TX interrupt enable */
-#define ES_TXINTENM (0x03<<5) /* mask for above */
-#define ES_TXINTENI(i) (((i)>>5)&0x03)
-#define ES_CNTRL(o) (((o)&0x03)<<0) /* control */
-#define ES_CNTRLM (0x03<<0) /* mask for above */
-#define ES_REG_UART_RES 0x0a /* R/W: UART reserver register */
-#define ES_TEST_MODE (1<<0) /* test mode enabled */
-#define ES_REG_MEM_PAGE 0x0c /* R/W: Memory page register */
-#define ES_MEM_PAGEO(o) (((o)&0x0f)<<0) /* memory page select - out */
-#define ES_MEM_PAGEM (0x0f<<0) /* mask for above */
-#define ES_MEM_PAGEI(i) (((i)>>0)&0x0f) /* memory page select - in */
-#define ES_REG_1370_CODEC 0x10 /* W/O: Codec write register address */
-#define ES_1370_CODEC_WRITE(a,d) ((((a)&0xff)<<8)|(((d)&0xff)<<0))
-#define ES_REG_1371_CODEC 0x14 /* W/R: Codec Read/Write register address */
-#define ES_1371_CODEC_RDY (1<<31) /* codec ready */
-#define ES_1371_CODEC_WIP (1<<30) /* codec register access in progress */
-#define EV_1938_CODEC_MAGIC (1<<26)
-#define ES_1371_CODEC_PIRD (1<<23) /* codec read/write select register */
-#define ES_1371_CODEC_WRITE(a,d) ((((a)&0x7f)<<16)|(((d)&0xffff)<<0))
-#define ES_1371_CODEC_READS(a) ((((a)&0x7f)<<16)|ES_1371_CODEC_PIRD)
-#define ES_1371_CODEC_READ(i) (((i)>>0)&0xffff)
-
-#define ES_REG_1371_SMPRATE 0x10 /* W/R: Codec rate converter interface register */
-#define ES_1371_SRC_RAM_ADDRO(o) (((o)&0x7f)<<25)/* address of the sample rate converter */
-#define ES_1371_SRC_RAM_ADDRM (0x7f<<25) /* mask for above */
-#define ES_1371_SRC_RAM_ADDRI(i) (((i)>>25)&0x7f)/* address of the sample rate converter */
-#define ES_1371_SRC_RAM_WE (1<<24) /* R/W: read/write control for sample rate converter */
-#define ES_1371_SRC_RAM_BUSY (1<<23) /* R/O: sample rate memory is busy */
-#define ES_1371_SRC_DISABLE (1<<22) /* sample rate converter disable */
-#define ES_1371_DIS_P1 (1<<21) /* playback channel 1 accumulator update disable */
-#define ES_1371_DIS_P2 (1<<20) /* playback channel 1 accumulator update disable */
-#define ES_1371_DIS_R1 (1<<19) /* capture channel accumulator update disable */
-#define ES_1371_SRC_RAM_DATAO(o) (((o)&0xffff)<<0)/* current value of the sample rate converter */
-#define ES_1371_SRC_RAM_DATAM (0xffff<<0) /* mask for above */
-#define ES_1371_SRC_RAM_DATAI(i) (((i)>>0)&0xffff)/* current value of the sample rate converter */
-
-#define ES_REG_1371_LEGACY 0x18 /* W/R: Legacy control/status register */
-#define ES_1371_JFAST (1<<31) /* fast joystick timing */
-#define ES_1371_HIB (1<<30) /* host interrupt blocking enable */
-#define ES_1371_VSB (1<<29) /* SB; 0 = addr 0x220xH, 1 = 0x22FxH */
-#define ES_1371_VMPUO(o) (((o)&0x03)<<27)/* base register address; 0 = 0x320xH; 1 = 0x330xH; 2 = 0x340xH; 3 = 0x350xH */
-#define ES_1371_VMPUM (0x03<<27) /* mask for above */
-#define ES_1371_VMPUI(i) (((i)>>27)&0x03)/* base register address */
-#define ES_1371_VCDCO(o) (((o)&0x03)<<25)/* CODEC; 0 = 0x530xH; 1 = undefined; 2 = 0xe80xH; 3 = 0xF40xH */
-#define ES_1371_VCDCM (0x03<<25) /* mask for above */
-#define ES_1371_VCDCI(i) (((i)>>25)&0x03)/* CODEC address */
-#define ES_1371_FIRQ (1<<24) /* force an interrupt */
-#define ES_1371_SDMACAP (1<<23) /* enable event capture for slave DMA controller */
-#define ES_1371_SPICAP (1<<22) /* enable event capture for slave IRQ controller */
-#define ES_1371_MDMACAP (1<<21) /* enable event capture for master DMA controller */
-#define ES_1371_MPICAP (1<<20) /* enable event capture for master IRQ controller */
-#define ES_1371_ADCAP (1<<19) /* enable event capture for ADLIB register; 0x388xH */
-#define ES_1371_SVCAP (1<<18) /* enable event capture for SB registers */
-#define ES_1371_CDCCAP (1<<17) /* enable event capture for CODEC registers */
-#define ES_1371_BACAP (1<<16) /* enable event capture for SoundScape base address */
-#define ES_1371_EXI(i) (((i)>>8)&0x07) /* event number */
-#define ES_1371_AI(i) (((i)>>3)&0x1f) /* event significant I/O address */
-#define ES_1371_WR (1<<2) /* event capture; 0 = read; 1 = write */
-#define ES_1371_LEGINT (1<<0) /* interrupt for legacy events; 0 = interrupt did occur */
-
-#define ES_REG_CHANNEL_STATUS 0x1c /* R/W: first 32-bits from S/PDIF channel status block, es1373 */
-
-#define ES_REG_SERIAL 0x20 /* R/W: Serial interface control register */
-#define ES_1371_DAC_TEST (1<<22) /* DAC test mode enable */
-#define ES_P2_END_INCO(o) (((o)&0x07)<<19)/* binary offset value to increment / loop end */
-#define ES_P2_END_INCM (0x07<<19) /* mask for above */
-#define ES_P2_END_INCI(i) (((i)>>16)&0x07)/* binary offset value to increment / loop end */
-#define ES_P2_ST_INCO(o) (((o)&0x07)<<16)/* binary offset value to increment / start */
-#define ES_P2_ST_INCM (0x07<<16) /* mask for above */
-#define ES_P2_ST_INCI(i) (((i)<<16)&0x07)/* binary offset value to increment / start */
-#define ES_R1_LOOP_SEL (1<<15) /* ADC; 0 - loop mode; 1 = stop mode */
-#define ES_P2_LOOP_SEL (1<<14) /* DAC2; 0 - loop mode; 1 = stop mode */
-#define ES_P1_LOOP_SEL (1<<13) /* DAC1; 0 - loop mode; 1 = stop mode */
-#define ES_P2_PAUSE (1<<12) /* DAC2; 0 - play mode; 1 = pause mode */
-#define ES_P1_PAUSE (1<<11) /* DAC1; 0 - play mode; 1 = pause mode */
-#define ES_R1_INT_EN (1<<10) /* ADC interrupt enable */
-#define ES_P2_INT_EN (1<<9) /* DAC2 interrupt enable */
-#define ES_P1_INT_EN (1<<8) /* DAC1 interrupt enable */
-#define ES_P1_SCT_RLD (1<<7) /* force sample counter reload for DAC1 */
-#define ES_P2_DAC_SEN (1<<6) /* when stop mode: 0 - DAC2 play back zeros; 1 = DAC2 play back last sample */
-#define ES_R1_MODEO(o) (((o)&0x03)<<4) /* ADC mode; 0 = 8-bit mono; 1 = 8-bit stereo; 2 = 16-bit mono; 3 = 16-bit stereo */
-#define ES_R1_MODEM (0x03<<4) /* mask for above */
-#define ES_R1_MODEI(i) (((i)>>4)&0x03)
-#define ES_P2_MODEO(o) (((o)&0x03)<<2) /* DAC2 mode; -- '' -- */
-#define ES_P2_MODEM (0x03<<2) /* mask for above */
-#define ES_P2_MODEI(i) (((i)>>2)&0x03)
-#define ES_P1_MODEO(o) (((o)&0x03)<<0) /* DAC1 mode; -- '' -- */
-#define ES_P1_MODEM (0x03<<0) /* mask for above */
-#define ES_P1_MODEI(i) (((i)>>0)&0x03)
-
-#define ES_REG_DAC1_COUNT 0x24 /* R/W: DAC1 sample count register */
-#define ES_REG_DAC2_COUNT 0x28 /* R/W: DAC2 sample count register */
-#define ES_REG_ADC_COUNT 0x2c /* R/W: ADC sample count register */
-#define ES_REG_CURR_COUNT(i) (((i)>>16)&0xffff)
-#define ES_REG_COUNTO(o) (((o)&0xffff)<<0)
-#define ES_REG_COUNTM (0xffff<<0)
-#define ES_REG_COUNTI(i) (((i)>>0)&0xffff)
-
-#define ES_REG_DAC1_FRAME 0x30 /* R/W: PAGE 0x0c; DAC1 frame address */
-#define ES_REG_DAC1_SIZE 0x34 /* R/W: PAGE 0x0c; DAC1 frame size */
-#define ES_REG_DAC2_FRAME 0x38 /* R/W: PAGE 0x0c; DAC2 frame address */
-#define ES_REG_DAC2_SIZE 0x3c /* R/W: PAGE 0x0c; DAC2 frame size */
-#define ES_REG_ADC_FRAME 0x30 /* R/W: PAGE 0x0d; ADC frame address */
-#define ES_REG_ADC_SIZE 0x34 /* R/W: PAGE 0x0d; ADC frame size */
-#define ES_REG_FCURR_COUNTO(o) (((o)&0xffff)<<16)
-#define ES_REG_FCURR_COUNTM (0xffff<<16)
-#define ES_REG_FCURR_COUNTI(i) (((i)>>14)&0x3fffc)
-#define ES_REG_FSIZEO(o) (((o)&0xffff)<<0)
-#define ES_REG_FSIZEM (0xffff<<0)
-#define ES_REG_FSIZEI(i) (((i)>>0)&0xffff)
-#define ES_REG_PHANTOM_FRAME 0x38 /* R/W: PAGE 0x0d: phantom frame address */
-#define ES_REG_PHANTOM_COUNT 0x3c /* R/W: PAGE 0x0d: phantom frame count */
-
-#define ES_REG_UART_FIFO 0x30 /* R/W: PAGE 0x0e; UART FIFO register */
-#define ES_REG_UF_VALID (1<<8)
-#define ES_REG_UF_BYTEO(o) (((o)&0xff)<<0)
-#define ES_REG_UF_BYTEM (0xff<<0)
-#define ES_REG_UF_BYTEI(i) (((i)>>0)&0xff)
-
-
-/*
- * Pages
- */
-
-#define ES_PAGE_DAC 0x0c
-#define ES_PAGE_ADC 0x0d
-#define ES_PAGE_UART 0x0e
-#define ES_PAGE_UART1 0x0f
-
-/*
- * Sample rate converter addresses
- */
-
-#define ES_SMPREG_DAC1 0x70
-#define ES_SMPREG_DAC2 0x74
-#define ES_SMPREG_ADC 0x78
-#define ES_SMPREG_VOL_ADC 0x6c
-#define ES_SMPREG_VOL_DAC1 0x7c
-#define ES_SMPREG_VOL_DAC2 0x7e
-#define ES_SMPREG_TRUNC_N 0x00
-#define ES_SMPREG_INT_REGS 0x01
-#define ES_SMPREG_ACCUM_FRAC 0x02
-#define ES_SMPREG_VFREQ_FRAC 0x03
-
-/*
- * Some contants
- */
-
-#define ES_1370_SRCLOCK 1411200
-#define ES_1370_SRTODIV(x) (ES_1370_SRCLOCK/(x)-2)
-
-/*
- * Open modes
- */
-
-#define ES_MODE_PLAY1 0x0001
-#define ES_MODE_PLAY2 0x0002
-#define ES_MODE_CAPTURE 0x0004
-
-#define ES_MODE_OUTPUT 0x0001 /* for MIDI */
-#define ES_MODE_INPUT 0x0002 /* for MIDI */
-
-/*
-
- */
-
-struct ensoniq {
- spinlock_t reg_lock;
- struct mutex src_mutex;
-
- int irq;
-
- unsigned long playback1size;
- unsigned long playback2size;
- unsigned long capture3size;
-
- unsigned long port;
- unsigned int mode;
- unsigned int uartm; /* UART mode */
-
- unsigned int ctrl; /* control register */
- unsigned int sctrl; /* serial control register */
- unsigned int cssr; /* control status register */
- unsigned int uartc; /* uart control register */
- unsigned int rev; /* chip revision */
-
- union {
-#ifdef CHIP1371
- struct {
- struct snd_ac97 *ac97;
- } es1371;
-#else
- struct {
- int pclkdiv_lock;
- struct snd_ak4531 *ak4531;
- } es1370;
-#endif
- } u;
-
- struct pci_dev *pci;
- struct snd_card *card;
- struct snd_pcm *pcm1; /* DAC1/ADC PCM */
- struct snd_pcm *pcm2; /* DAC2 PCM */
- struct snd_pcm_substream *playback1_substream;
- struct snd_pcm_substream *playback2_substream;
- struct snd_pcm_substream *capture_substream;
- unsigned int p1_dma_size;
- unsigned int p2_dma_size;
- unsigned int c_dma_size;
- unsigned int p1_period_size;
- unsigned int p2_period_size;
- unsigned int c_period_size;
- struct snd_rawmidi *rmidi;
- struct snd_rawmidi_substream *midi_input;
- struct snd_rawmidi_substream *midi_output;
-
- unsigned int spdif;
- unsigned int spdif_default;
- unsigned int spdif_stream;
-
-#ifdef CHIP1370
- struct snd_dma_buffer dma_bug;
-#endif
-
-#ifdef SUPPORT_JOYSTICK
- struct gameport *gameport;
-#endif
-};
-
-static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id);
-
-static DEFINE_PCI_DEVICE_TABLE(snd_audiopci_ids) = {
-#ifdef CHIP1370
- { PCI_VDEVICE(ENSONIQ, 0x5000), 0, }, /* ES1370 */
-#endif
-#ifdef CHIP1371
- { PCI_VDEVICE(ENSONIQ, 0x1371), 0, }, /* ES1371 */
- { PCI_VDEVICE(ENSONIQ, 0x5880), 0, }, /* ES1373 - CT5880 */
- { PCI_VDEVICE(ECTIVA, 0x8938), 0, }, /* Ectiva EV1938 */
-#endif
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
-
-/*
- * constants
- */
-
-#define POLL_COUNT 0xa000
-
-#ifdef CHIP1370
-static unsigned int snd_es1370_fixed_rates[] =
- {5512, 11025, 22050, 44100};
-static struct snd_pcm_hw_constraint_list snd_es1370_hw_constraints_rates = {
- .count = 4,
- .list = snd_es1370_fixed_rates,
- .mask = 0,
-};
-static struct snd_ratnum es1370_clock = {
- .num = ES_1370_SRCLOCK,
- .den_min = 29,
- .den_max = 353,
- .den_step = 1,
-};
-static struct snd_pcm_hw_constraint_ratnums snd_es1370_hw_constraints_clock = {
- .nrats = 1,
- .rats = &es1370_clock,
-};
-#else
-static struct snd_ratden es1371_dac_clock = {
- .num_min = 3000 * (1 << 15),
- .num_max = 48000 * (1 << 15),
- .num_step = 3000,
- .den = 1 << 15,
-};
-static struct snd_pcm_hw_constraint_ratdens snd_es1371_hw_constraints_dac_clock = {
- .nrats = 1,
- .rats = &es1371_dac_clock,
-};
-static struct snd_ratnum es1371_adc_clock = {
- .num = 48000 << 15,
- .den_min = 32768,
- .den_max = 393216,
- .den_step = 1,
-};
-static struct snd_pcm_hw_constraint_ratnums snd_es1371_hw_constraints_adc_clock = {
- .nrats = 1,
- .rats = &es1371_adc_clock,
-};
-#endif
-static const unsigned int snd_ensoniq_sample_shift[] =
- {0, 1, 1, 2};
-
-/*
- * common I/O routines
- */
-
-#ifdef CHIP1371
-
-static unsigned int snd_es1371_wait_src_ready(struct ensoniq * ensoniq)
-{
- unsigned int t, r = 0;
-
- for (t = 0; t < POLL_COUNT; t++) {
- r = inl(ES_REG(ensoniq, 1371_SMPRATE));
- if ((r & ES_1371_SRC_RAM_BUSY) == 0)
- return r;
- cond_resched();
- }
- snd_printk(KERN_ERR "wait src ready timeout 0x%lx [0x%x]\n",
- ES_REG(ensoniq, 1371_SMPRATE), r);
- return 0;
-}
-
-static unsigned int snd_es1371_src_read(struct ensoniq * ensoniq, unsigned short reg)
-{
- unsigned int temp, i, orig, r;
-
- /* wait for ready */
- temp = orig = snd_es1371_wait_src_ready(ensoniq);
-
- /* expose the SRC state bits */
- r = temp & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |
- ES_1371_DIS_P2 | ES_1371_DIS_R1);
- r |= ES_1371_SRC_RAM_ADDRO(reg) | 0x10000;
- outl(r, ES_REG(ensoniq, 1371_SMPRATE));
-
- /* now, wait for busy and the correct time to read */
- temp = snd_es1371_wait_src_ready(ensoniq);
-
- if ((temp & 0x00870000) != 0x00010000) {
- /* wait for the right state */
- for (i = 0; i < POLL_COUNT; i++) {
- temp = inl(ES_REG(ensoniq, 1371_SMPRATE));
- if ((temp & 0x00870000) == 0x00010000)
- break;
- }
- }
-
- /* hide the state bits */
- r = orig & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |
- ES_1371_DIS_P2 | ES_1371_DIS_R1);
- r |= ES_1371_SRC_RAM_ADDRO(reg);
- outl(r, ES_REG(ensoniq, 1371_SMPRATE));
-
- return temp;
-}
-
-static void snd_es1371_src_write(struct ensoniq * ensoniq,
- unsigned short reg, unsigned short data)
-{
- unsigned int r;
-
- r = snd_es1371_wait_src_ready(ensoniq) &
- (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |
- ES_1371_DIS_P2 | ES_1371_DIS_R1);
- r |= ES_1371_SRC_RAM_ADDRO(reg) | ES_1371_SRC_RAM_DATAO(data);
- outl(r | ES_1371_SRC_RAM_WE, ES_REG(ensoniq, 1371_SMPRATE));
-}
-
-#endif /* CHIP1371 */
-
-#ifdef CHIP1370
-
-static void snd_es1370_codec_write(struct snd_ak4531 *ak4531,
- unsigned short reg, unsigned short val)
-{
- struct ensoniq *ensoniq = ak4531->private_data;
- unsigned long end_time = jiffies + HZ / 10;
-
-#if 0
- printk(KERN_DEBUG
- "CODEC WRITE: reg = 0x%x, val = 0x%x (0x%x), creg = 0x%x\n",
- reg, val, ES_1370_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1370_CODEC));
-#endif
- do {
- if (!(inl(ES_REG(ensoniq, STATUS)) & ES_1370_CSTAT)) {
- outw(ES_1370_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1370_CODEC));
- return;
- }
- schedule_timeout_uninterruptible(1);
- } while (time_after(end_time, jiffies));
- snd_printk(KERN_ERR "codec write timeout, status = 0x%x\n",
- inl(ES_REG(ensoniq, STATUS)));
-}
-
-#endif /* CHIP1370 */
-
-#ifdef CHIP1371
-
-static inline bool is_ev1938(struct ensoniq *ensoniq)
-{
- return ensoniq->pci->device == 0x8938;
-}
-
-static void snd_es1371_codec_write(struct snd_ac97 *ac97,
- unsigned short reg, unsigned short val)
-{
- struct ensoniq *ensoniq = ac97->private_data;
- unsigned int t, x, flag;
-
- flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0;
- mutex_lock(&ensoniq->src_mutex);
- for (t = 0; t < POLL_COUNT; t++) {
- if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) {
- /* save the current state for latter */
- x = snd_es1371_wait_src_ready(ensoniq);
- outl((x & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |
- ES_1371_DIS_P2 | ES_1371_DIS_R1)) | 0x00010000,
- ES_REG(ensoniq, 1371_SMPRATE));
- /* wait for not busy (state 0) first to avoid
- transition states */
- for (t = 0; t < POLL_COUNT; t++) {
- if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==
- 0x00000000)
- break;
- }
- /* wait for a SAFE time to write addr/data and then do it, dammit */
- for (t = 0; t < POLL_COUNT; t++) {
- if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==
- 0x00010000)
- break;
- }
- outl(ES_1371_CODEC_WRITE(reg, val) | flag,
- ES_REG(ensoniq, 1371_CODEC));
- /* restore SRC reg */
- snd_es1371_wait_src_ready(ensoniq);
- outl(x, ES_REG(ensoniq, 1371_SMPRATE));
- mutex_unlock(&ensoniq->src_mutex);
- return;
- }
- }
- mutex_unlock(&ensoniq->src_mutex);
- snd_printk(KERN_ERR "codec write timeout at 0x%lx [0x%x]\n",
- ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
-}
-
-static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- struct ensoniq *ensoniq = ac97->private_data;
- unsigned int t, x, flag, fail = 0;
-
- flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0;
- __again:
- mutex_lock(&ensoniq->src_mutex);
- for (t = 0; t < POLL_COUNT; t++) {
- if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) {
- /* save the current state for latter */
- x = snd_es1371_wait_src_ready(ensoniq);
- outl((x & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |
- ES_1371_DIS_P2 | ES_1371_DIS_R1)) | 0x00010000,
- ES_REG(ensoniq, 1371_SMPRATE));
- /* wait for not busy (state 0) first to avoid
- transition states */
- for (t = 0; t < POLL_COUNT; t++) {
- if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==
- 0x00000000)
- break;
- }
- /* wait for a SAFE time to write addr/data and then do it, dammit */
- for (t = 0; t < POLL_COUNT; t++) {
- if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==
- 0x00010000)
- break;
- }
- outl(ES_1371_CODEC_READS(reg) | flag,
- ES_REG(ensoniq, 1371_CODEC));
- /* restore SRC reg */
- snd_es1371_wait_src_ready(ensoniq);
- outl(x, ES_REG(ensoniq, 1371_SMPRATE));
- /* wait for WIP again */
- for (t = 0; t < POLL_COUNT; t++) {
- if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP))
- break;
- }
- /* now wait for the stinkin' data (RDY) */
- for (t = 0; t < POLL_COUNT; t++) {
- if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) {
- if (is_ev1938(ensoniq)) {
- for (t = 0; t < 100; t++)
- inl(ES_REG(ensoniq, CONTROL));
- x = inl(ES_REG(ensoniq, 1371_CODEC));
- }
- mutex_unlock(&ensoniq->src_mutex);
- return ES_1371_CODEC_READ(x);
- }
- }
- mutex_unlock(&ensoniq->src_mutex);
- if (++fail > 10) {
- snd_printk(KERN_ERR "codec read timeout (final) "
- "at 0x%lx, reg = 0x%x [0x%x]\n",
- ES_REG(ensoniq, 1371_CODEC), reg,
- inl(ES_REG(ensoniq, 1371_CODEC)));
- return 0;
- }
- goto __again;
- }
- }
- mutex_unlock(&ensoniq->src_mutex);
- snd_printk(KERN_ERR "es1371: codec read timeout at 0x%lx [0x%x]\n",
- ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
- return 0;
-}
-
-static void snd_es1371_codec_wait(struct snd_ac97 *ac97)
-{
- msleep(750);
- snd_es1371_codec_read(ac97, AC97_RESET);
- snd_es1371_codec_read(ac97, AC97_VENDOR_ID1);
- snd_es1371_codec_read(ac97, AC97_VENDOR_ID2);
- msleep(50);
-}
-
-static void snd_es1371_adc_rate(struct ensoniq * ensoniq, unsigned int rate)
-{
- unsigned int n, truncm, freq, result;
-
- mutex_lock(&ensoniq->src_mutex);
- n = rate / 3000;
- if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9)))
- n--;
- truncm = (21 * n - 1) | 1;
- freq = ((48000UL << 15) / rate) * n;
- result = (48000UL << 15) / (freq / n);
- if (rate >= 24000) {
- if (truncm > 239)
- truncm = 239;
- snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N,
- (((239 - truncm) >> 1) << 9) | (n << 4));
- } else {
- if (truncm > 119)
- truncm = 119;
- snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N,
- 0x8000 | (((119 - truncm) >> 1) << 9) | (n << 4));
- }
- snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_INT_REGS,
- (snd_es1371_src_read(ensoniq, ES_SMPREG_ADC +
- ES_SMPREG_INT_REGS) & 0x00ff) |
- ((freq >> 5) & 0xfc00));
- snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
- snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, n << 8);
- snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, n << 8);
- mutex_unlock(&ensoniq->src_mutex);
-}
-
-static void snd_es1371_dac1_rate(struct ensoniq * ensoniq, unsigned int rate)
-{
- unsigned int freq, r;
-
- mutex_lock(&ensoniq->src_mutex);
- freq = ((rate << 15) + 1500) / 3000;
- r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |
- ES_1371_DIS_P2 | ES_1371_DIS_R1)) |
- ES_1371_DIS_P1;
- outl(r, ES_REG(ensoniq, 1371_SMPRATE));
- snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS,
- (snd_es1371_src_read(ensoniq, ES_SMPREG_DAC1 +
- ES_SMPREG_INT_REGS) & 0x00ff) |
- ((freq >> 5) & 0xfc00));
- snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
- r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |
- ES_1371_DIS_P2 | ES_1371_DIS_R1));
- outl(r, ES_REG(ensoniq, 1371_SMPRATE));
- mutex_unlock(&ensoniq->src_mutex);
-}
-
-static void snd_es1371_dac2_rate(struct ensoniq * ensoniq, unsigned int rate)
-{
- unsigned int freq, r;
-
- mutex_lock(&ensoniq->src_mutex);
- freq = ((rate << 15) + 1500) / 3000;
- r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |
- ES_1371_DIS_P1 | ES_1371_DIS_R1)) |
- ES_1371_DIS_P2;
- outl(r, ES_REG(ensoniq, 1371_SMPRATE));
- snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS,
- (snd_es1371_src_read(ensoniq, ES_SMPREG_DAC2 +
- ES_SMPREG_INT_REGS) & 0x00ff) |
- ((freq >> 5) & 0xfc00));
- snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_VFREQ_FRAC,
- freq & 0x7fff);
- r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |
- ES_1371_DIS_P1 | ES_1371_DIS_R1));
- outl(r, ES_REG(ensoniq, 1371_SMPRATE));
- mutex_unlock(&ensoniq->src_mutex);
-}
-
-#endif /* CHIP1371 */
-
-static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- {
- unsigned int what = 0;
- struct snd_pcm_substream *s;
- snd_pcm_group_for_each_entry(s, substream) {
- if (s == ensoniq->playback1_substream) {
- what |= ES_P1_PAUSE;
- snd_pcm_trigger_done(s, substream);
- } else if (s == ensoniq->playback2_substream) {
- what |= ES_P2_PAUSE;
- snd_pcm_trigger_done(s, substream);
- } else if (s == ensoniq->capture_substream)
- return -EINVAL;
- }
- spin_lock(&ensoniq->reg_lock);
- if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
- ensoniq->sctrl |= what;
- else
- ensoniq->sctrl &= ~what;
- outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
- spin_unlock(&ensoniq->reg_lock);
- break;
- }
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_STOP:
- {
- unsigned int what = 0;
- struct snd_pcm_substream *s;
- snd_pcm_group_for_each_entry(s, substream) {
- if (s == ensoniq->playback1_substream) {
- what |= ES_DAC1_EN;
- snd_pcm_trigger_done(s, substream);
- } else if (s == ensoniq->playback2_substream) {
- what |= ES_DAC2_EN;
- snd_pcm_trigger_done(s, substream);
- } else if (s == ensoniq->capture_substream) {
- what |= ES_ADC_EN;
- snd_pcm_trigger_done(s, substream);
- }
- }
- spin_lock(&ensoniq->reg_lock);
- if (cmd == SNDRV_PCM_TRIGGER_START)
- ensoniq->ctrl |= what;
- else
- ensoniq->ctrl &= ~what;
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- spin_unlock(&ensoniq->reg_lock);
- break;
- }
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-/*
- * PCM part
- */
-
-static int snd_ensoniq_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static int snd_ensoniq_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_ensoniq_playback1_prepare(struct snd_pcm_substream *substream)
-{
- struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int mode = 0;
-
- ensoniq->p1_dma_size = snd_pcm_lib_buffer_bytes(substream);
- ensoniq->p1_period_size = snd_pcm_lib_period_bytes(substream);
- if (snd_pcm_format_width(runtime->format) == 16)
- mode |= 0x02;
- if (runtime->channels > 1)
- mode |= 0x01;
- spin_lock_irq(&ensoniq->reg_lock);
- ensoniq->ctrl &= ~ES_DAC1_EN;
-#ifdef CHIP1371
- /* 48k doesn't need SRC (it breaks AC3-passthru) */
- if (runtime->rate == 48000)
- ensoniq->ctrl |= ES_1373_BYPASS_P1;
- else
- ensoniq->ctrl &= ~ES_1373_BYPASS_P1;
-#endif
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
- outl(runtime->dma_addr, ES_REG(ensoniq, DAC1_FRAME));
- outl((ensoniq->p1_dma_size >> 2) - 1, ES_REG(ensoniq, DAC1_SIZE));
- ensoniq->sctrl &= ~(ES_P1_LOOP_SEL | ES_P1_PAUSE | ES_P1_SCT_RLD | ES_P1_MODEM);
- ensoniq->sctrl |= ES_P1_INT_EN | ES_P1_MODEO(mode);
- outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
- outl((ensoniq->p1_period_size >> snd_ensoniq_sample_shift[mode]) - 1,
- ES_REG(ensoniq, DAC1_COUNT));
-#ifdef CHIP1370
- ensoniq->ctrl &= ~ES_1370_WTSRSELM;
- switch (runtime->rate) {
- case 5512: ensoniq->ctrl |= ES_1370_WTSRSEL(0); break;
- case 11025: ensoniq->ctrl |= ES_1370_WTSRSEL(1); break;
- case 22050: ensoniq->ctrl |= ES_1370_WTSRSEL(2); break;
- case 44100: ensoniq->ctrl |= ES_1370_WTSRSEL(3); break;
- default: snd_BUG();
- }
-#endif
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- spin_unlock_irq(&ensoniq->reg_lock);
-#ifndef CHIP1370
- snd_es1371_dac1_rate(ensoniq, runtime->rate);
-#endif
- return 0;
-}
-
-static int snd_ensoniq_playback2_prepare(struct snd_pcm_substream *substream)
-{
- struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int mode = 0;
-
- ensoniq->p2_dma_size = snd_pcm_lib_buffer_bytes(substream);
- ensoniq->p2_period_size = snd_pcm_lib_period_bytes(substream);
- if (snd_pcm_format_width(runtime->format) == 16)
- mode |= 0x02;
- if (runtime->channels > 1)
- mode |= 0x01;
- spin_lock_irq(&ensoniq->reg_lock);
- ensoniq->ctrl &= ~ES_DAC2_EN;
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
- outl(runtime->dma_addr, ES_REG(ensoniq, DAC2_FRAME));
- outl((ensoniq->p2_dma_size >> 2) - 1, ES_REG(ensoniq, DAC2_SIZE));
- ensoniq->sctrl &= ~(ES_P2_LOOP_SEL | ES_P2_PAUSE | ES_P2_DAC_SEN |
- ES_P2_END_INCM | ES_P2_ST_INCM | ES_P2_MODEM);
- ensoniq->sctrl |= ES_P2_INT_EN | ES_P2_MODEO(mode) |
- ES_P2_END_INCO(mode & 2 ? 2 : 1) | ES_P2_ST_INCO(0);
- outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
- outl((ensoniq->p2_period_size >> snd_ensoniq_sample_shift[mode]) - 1,
- ES_REG(ensoniq, DAC2_COUNT));
-#ifdef CHIP1370
- if (!(ensoniq->u.es1370.pclkdiv_lock & ES_MODE_CAPTURE)) {
- ensoniq->ctrl &= ~ES_1370_PCLKDIVM;
- ensoniq->ctrl |= ES_1370_PCLKDIVO(ES_1370_SRTODIV(runtime->rate));
- ensoniq->u.es1370.pclkdiv_lock |= ES_MODE_PLAY2;
- }
-#endif
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- spin_unlock_irq(&ensoniq->reg_lock);
-#ifndef CHIP1370
- snd_es1371_dac2_rate(ensoniq, runtime->rate);
-#endif
- return 0;
-}
-
-static int snd_ensoniq_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int mode = 0;
-
- ensoniq->c_dma_size = snd_pcm_lib_buffer_bytes(substream);
- ensoniq->c_period_size = snd_pcm_lib_period_bytes(substream);
- if (snd_pcm_format_width(runtime->format) == 16)
- mode |= 0x02;
- if (runtime->channels > 1)
- mode |= 0x01;
- spin_lock_irq(&ensoniq->reg_lock);
- ensoniq->ctrl &= ~ES_ADC_EN;
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE));
- outl(runtime->dma_addr, ES_REG(ensoniq, ADC_FRAME));
- outl((ensoniq->c_dma_size >> 2) - 1, ES_REG(ensoniq, ADC_SIZE));
- ensoniq->sctrl &= ~(ES_R1_LOOP_SEL | ES_R1_MODEM);
- ensoniq->sctrl |= ES_R1_INT_EN | ES_R1_MODEO(mode);
- outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
- outl((ensoniq->c_period_size >> snd_ensoniq_sample_shift[mode]) - 1,
- ES_REG(ensoniq, ADC_COUNT));
-#ifdef CHIP1370
- if (!(ensoniq->u.es1370.pclkdiv_lock & ES_MODE_PLAY2)) {
- ensoniq->ctrl &= ~ES_1370_PCLKDIVM;
- ensoniq->ctrl |= ES_1370_PCLKDIVO(ES_1370_SRTODIV(runtime->rate));
- ensoniq->u.es1370.pclkdiv_lock |= ES_MODE_CAPTURE;
- }
-#endif
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- spin_unlock_irq(&ensoniq->reg_lock);
-#ifndef CHIP1370
- snd_es1371_adc_rate(ensoniq, runtime->rate);
-#endif
- return 0;
-}
-
-static snd_pcm_uframes_t snd_ensoniq_playback1_pointer(struct snd_pcm_substream *substream)
-{
- struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
- size_t ptr;
-
- spin_lock(&ensoniq->reg_lock);
- if (inl(ES_REG(ensoniq, CONTROL)) & ES_DAC1_EN) {
- outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
- ptr = ES_REG_FCURR_COUNTI(inl(ES_REG(ensoniq, DAC1_SIZE)));
- ptr = bytes_to_frames(substream->runtime, ptr);
- } else {
- ptr = 0;
- }
- spin_unlock(&ensoniq->reg_lock);
- return ptr;
-}
-
-static snd_pcm_uframes_t snd_ensoniq_playback2_pointer(struct snd_pcm_substream *substream)
-{
- struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
- size_t ptr;
-
- spin_lock(&ensoniq->reg_lock);
- if (inl(ES_REG(ensoniq, CONTROL)) & ES_DAC2_EN) {
- outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
- ptr = ES_REG_FCURR_COUNTI(inl(ES_REG(ensoniq, DAC2_SIZE)));
- ptr = bytes_to_frames(substream->runtime, ptr);
- } else {
- ptr = 0;
- }
- spin_unlock(&ensoniq->reg_lock);
- return ptr;
-}
-
-static snd_pcm_uframes_t snd_ensoniq_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
- size_t ptr;
-
- spin_lock(&ensoniq->reg_lock);
- if (inl(ES_REG(ensoniq, CONTROL)) & ES_ADC_EN) {
- outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE));
- ptr = ES_REG_FCURR_COUNTI(inl(ES_REG(ensoniq, ADC_SIZE)));
- ptr = bytes_to_frames(substream->runtime, ptr);
- } else {
- ptr = 0;
- }
- spin_unlock(&ensoniq->reg_lock);
- return ptr;
-}
-
-static struct snd_pcm_hardware snd_ensoniq_playback1 =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates =
-#ifndef CHIP1370
- SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
-#else
- (SNDRV_PCM_RATE_KNOT | /* 5512Hz rate */
- SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_22050 |
- SNDRV_PCM_RATE_44100),
-#endif
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_ensoniq_playback2 =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_ensoniq_capture =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static int snd_ensoniq_playback1_open(struct snd_pcm_substream *substream)
-{
- struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- ensoniq->mode |= ES_MODE_PLAY1;
- ensoniq->playback1_substream = substream;
- runtime->hw = snd_ensoniq_playback1;
- snd_pcm_set_sync(substream);
- spin_lock_irq(&ensoniq->reg_lock);
- if (ensoniq->spdif && ensoniq->playback2_substream == NULL)
- ensoniq->spdif_stream = ensoniq->spdif_default;
- spin_unlock_irq(&ensoniq->reg_lock);
-#ifdef CHIP1370
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &snd_es1370_hw_constraints_rates);
-#else
- snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &snd_es1371_hw_constraints_dac_clock);
-#endif
- return 0;
-}
-
-static int snd_ensoniq_playback2_open(struct snd_pcm_substream *substream)
-{
- struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- ensoniq->mode |= ES_MODE_PLAY2;
- ensoniq->playback2_substream = substream;
- runtime->hw = snd_ensoniq_playback2;
- snd_pcm_set_sync(substream);
- spin_lock_irq(&ensoniq->reg_lock);
- if (ensoniq->spdif && ensoniq->playback1_substream == NULL)
- ensoniq->spdif_stream = ensoniq->spdif_default;
- spin_unlock_irq(&ensoniq->reg_lock);
-#ifdef CHIP1370
- snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &snd_es1370_hw_constraints_clock);
-#else
- snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &snd_es1371_hw_constraints_dac_clock);
-#endif
- return 0;
-}
-
-static int snd_ensoniq_capture_open(struct snd_pcm_substream *substream)
-{
- struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- ensoniq->mode |= ES_MODE_CAPTURE;
- ensoniq->capture_substream = substream;
- runtime->hw = snd_ensoniq_capture;
- snd_pcm_set_sync(substream);
-#ifdef CHIP1370
- snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &snd_es1370_hw_constraints_clock);
-#else
- snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &snd_es1371_hw_constraints_adc_clock);
-#endif
- return 0;
-}
-
-static int snd_ensoniq_playback1_close(struct snd_pcm_substream *substream)
-{
- struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
-
- ensoniq->playback1_substream = NULL;
- ensoniq->mode &= ~ES_MODE_PLAY1;
- return 0;
-}
-
-static int snd_ensoniq_playback2_close(struct snd_pcm_substream *substream)
-{
- struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
-
- ensoniq->playback2_substream = NULL;
- spin_lock_irq(&ensoniq->reg_lock);
-#ifdef CHIP1370
- ensoniq->u.es1370.pclkdiv_lock &= ~ES_MODE_PLAY2;
-#endif
- ensoniq->mode &= ~ES_MODE_PLAY2;
- spin_unlock_irq(&ensoniq->reg_lock);
- return 0;
-}
-
-static int snd_ensoniq_capture_close(struct snd_pcm_substream *substream)
-{
- struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
-
- ensoniq->capture_substream = NULL;
- spin_lock_irq(&ensoniq->reg_lock);
-#ifdef CHIP1370
- ensoniq->u.es1370.pclkdiv_lock &= ~ES_MODE_CAPTURE;
-#endif
- ensoniq->mode &= ~ES_MODE_CAPTURE;
- spin_unlock_irq(&ensoniq->reg_lock);
- return 0;
-}
-
-static struct snd_pcm_ops snd_ensoniq_playback1_ops = {
- .open = snd_ensoniq_playback1_open,
- .close = snd_ensoniq_playback1_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ensoniq_hw_params,
- .hw_free = snd_ensoniq_hw_free,
- .prepare = snd_ensoniq_playback1_prepare,
- .trigger = snd_ensoniq_trigger,
- .pointer = snd_ensoniq_playback1_pointer,
-};
-
-static struct snd_pcm_ops snd_ensoniq_playback2_ops = {
- .open = snd_ensoniq_playback2_open,
- .close = snd_ensoniq_playback2_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ensoniq_hw_params,
- .hw_free = snd_ensoniq_hw_free,
- .prepare = snd_ensoniq_playback2_prepare,
- .trigger = snd_ensoniq_trigger,
- .pointer = snd_ensoniq_playback2_pointer,
-};
-
-static struct snd_pcm_ops snd_ensoniq_capture_ops = {
- .open = snd_ensoniq_capture_open,
- .close = snd_ensoniq_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ensoniq_hw_params,
- .hw_free = snd_ensoniq_hw_free,
- .prepare = snd_ensoniq_capture_prepare,
- .trigger = snd_ensoniq_trigger,
- .pointer = snd_ensoniq_capture_pointer,
-};
-
-static int __devinit snd_ensoniq_pcm(struct ensoniq * ensoniq, int device,
- struct snd_pcm ** rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
-#ifdef CHIP1370
- err = snd_pcm_new(ensoniq->card, "ES1370/1", device, 1, 1, &pcm);
-#else
- err = snd_pcm_new(ensoniq->card, "ES1371/1", device, 1, 1, &pcm);
-#endif
- if (err < 0)
- return err;
-
-#ifdef CHIP1370
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback2_ops);
-#else
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback1_ops);
-#endif
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ensoniq_capture_ops);
-
- pcm->private_data = ensoniq;
- pcm->info_flags = 0;
-#ifdef CHIP1370
- strcpy(pcm->name, "ES1370 DAC2/ADC");
-#else
- strcpy(pcm->name, "ES1371 DAC2/ADC");
-#endif
- ensoniq->pcm1 = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(ensoniq->pci), 64*1024, 128*1024);
-
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-static int __devinit snd_ensoniq_pcm2(struct ensoniq * ensoniq, int device,
- struct snd_pcm ** rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
-#ifdef CHIP1370
- err = snd_pcm_new(ensoniq->card, "ES1370/2", device, 1, 0, &pcm);
-#else
- err = snd_pcm_new(ensoniq->card, "ES1371/2", device, 1, 0, &pcm);
-#endif
- if (err < 0)
- return err;
-
-#ifdef CHIP1370
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback1_ops);
-#else
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback2_ops);
-#endif
- pcm->private_data = ensoniq;
- pcm->info_flags = 0;
-#ifdef CHIP1370
- strcpy(pcm->name, "ES1370 DAC1");
-#else
- strcpy(pcm->name, "ES1371 DAC1");
-#endif
- ensoniq->pcm2 = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(ensoniq->pci), 64*1024, 128*1024);
-
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-/*
- * Mixer section
- */
-
-/*
- * ENS1371 mixer (including SPDIF interface)
- */
-#ifdef CHIP1371
-static int snd_ens1373_spdif_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_ens1373_spdif_default_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&ensoniq->reg_lock);
- ucontrol->value.iec958.status[0] = (ensoniq->spdif_default >> 0) & 0xff;
- ucontrol->value.iec958.status[1] = (ensoniq->spdif_default >> 8) & 0xff;
- ucontrol->value.iec958.status[2] = (ensoniq->spdif_default >> 16) & 0xff;
- ucontrol->value.iec958.status[3] = (ensoniq->spdif_default >> 24) & 0xff;
- spin_unlock_irq(&ensoniq->reg_lock);
- return 0;
-}
-
-static int snd_ens1373_spdif_default_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change;
-
- val = ((u32)ucontrol->value.iec958.status[0] << 0) |
- ((u32)ucontrol->value.iec958.status[1] << 8) |
- ((u32)ucontrol->value.iec958.status[2] << 16) |
- ((u32)ucontrol->value.iec958.status[3] << 24);
- spin_lock_irq(&ensoniq->reg_lock);
- change = ensoniq->spdif_default != val;
- ensoniq->spdif_default = val;
- if (change && ensoniq->playback1_substream == NULL &&
- ensoniq->playback2_substream == NULL)
- outl(val, ES_REG(ensoniq, CHANNEL_STATUS));
- spin_unlock_irq(&ensoniq->reg_lock);
- return change;
-}
-
-static int snd_ens1373_spdif_mask_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.iec958.status[0] = 0xff;
- ucontrol->value.iec958.status[1] = 0xff;
- ucontrol->value.iec958.status[2] = 0xff;
- ucontrol->value.iec958.status[3] = 0xff;
- return 0;
-}
-
-static int snd_ens1373_spdif_stream_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&ensoniq->reg_lock);
- ucontrol->value.iec958.status[0] = (ensoniq->spdif_stream >> 0) & 0xff;
- ucontrol->value.iec958.status[1] = (ensoniq->spdif_stream >> 8) & 0xff;
- ucontrol->value.iec958.status[2] = (ensoniq->spdif_stream >> 16) & 0xff;
- ucontrol->value.iec958.status[3] = (ensoniq->spdif_stream >> 24) & 0xff;
- spin_unlock_irq(&ensoniq->reg_lock);
- return 0;
-}
-
-static int snd_ens1373_spdif_stream_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change;
-
- val = ((u32)ucontrol->value.iec958.status[0] << 0) |
- ((u32)ucontrol->value.iec958.status[1] << 8) |
- ((u32)ucontrol->value.iec958.status[2] << 16) |
- ((u32)ucontrol->value.iec958.status[3] << 24);
- spin_lock_irq(&ensoniq->reg_lock);
- change = ensoniq->spdif_stream != val;
- ensoniq->spdif_stream = val;
- if (change && (ensoniq->playback1_substream != NULL ||
- ensoniq->playback2_substream != NULL))
- outl(val, ES_REG(ensoniq, CHANNEL_STATUS));
- spin_unlock_irq(&ensoniq->reg_lock);
- return change;
-}
-
-#define ES1371_SPDIF(xname) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_es1371_spdif_info, \
- .get = snd_es1371_spdif_get, .put = snd_es1371_spdif_put }
-
-#define snd_es1371_spdif_info snd_ctl_boolean_mono_info
-
-static int snd_es1371_spdif_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&ensoniq->reg_lock);
- ucontrol->value.integer.value[0] = ensoniq->ctrl & ES_1373_SPDIF_THRU ? 1 : 0;
- spin_unlock_irq(&ensoniq->reg_lock);
- return 0;
-}
-
-static int snd_es1371_spdif_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
- unsigned int nval1, nval2;
- int change;
-
- nval1 = ucontrol->value.integer.value[0] ? ES_1373_SPDIF_THRU : 0;
- nval2 = ucontrol->value.integer.value[0] ? ES_1373_SPDIF_EN : 0;
- spin_lock_irq(&ensoniq->reg_lock);
- change = (ensoniq->ctrl & ES_1373_SPDIF_THRU) != nval1;
- ensoniq->ctrl &= ~ES_1373_SPDIF_THRU;
- ensoniq->ctrl |= nval1;
- ensoniq->cssr &= ~ES_1373_SPDIF_EN;
- ensoniq->cssr |= nval2;
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
- spin_unlock_irq(&ensoniq->reg_lock);
- return change;
-}
-
-
-/* spdif controls */
-static struct snd_kcontrol_new snd_es1371_mixer_spdif[] __devinitdata = {
- ES1371_SPDIF(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH)),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
- .info = snd_ens1373_spdif_info,
- .get = snd_ens1373_spdif_default_get,
- .put = snd_ens1373_spdif_default_put,
- },
- {
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
- .info = snd_ens1373_spdif_info,
- .get = snd_ens1373_spdif_mask_get
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
- .info = snd_ens1373_spdif_info,
- .get = snd_ens1373_spdif_stream_get,
- .put = snd_ens1373_spdif_stream_put
- },
-};
-
-
-#define snd_es1373_rear_info snd_ctl_boolean_mono_info
-
-static int snd_es1373_rear_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
- int val = 0;
-
- spin_lock_irq(&ensoniq->reg_lock);
- if ((ensoniq->cssr & (ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|
- ES_1373_REAR_BIT24)) == ES_1373_REAR_BIT26)
- val = 1;
- ucontrol->value.integer.value[0] = val;
- spin_unlock_irq(&ensoniq->reg_lock);
- return 0;
-}
-
-static int snd_es1373_rear_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
- unsigned int nval1;
- int change;
-
- nval1 = ucontrol->value.integer.value[0] ?
- ES_1373_REAR_BIT26 : (ES_1373_REAR_BIT27|ES_1373_REAR_BIT24);
- spin_lock_irq(&ensoniq->reg_lock);
- change = (ensoniq->cssr & (ES_1373_REAR_BIT27|
- ES_1373_REAR_BIT26|ES_1373_REAR_BIT24)) != nval1;
- ensoniq->cssr &= ~(ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|ES_1373_REAR_BIT24);
- ensoniq->cssr |= nval1;
- outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
- spin_unlock_irq(&ensoniq->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_ens1373_rear __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "AC97 2ch->4ch Copy Switch",
- .info = snd_es1373_rear_info,
- .get = snd_es1373_rear_get,
- .put = snd_es1373_rear_put,
-};
-
-#define snd_es1373_line_info snd_ctl_boolean_mono_info
-
-static int snd_es1373_line_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
- int val = 0;
-
- spin_lock_irq(&ensoniq->reg_lock);
- if ((ensoniq->ctrl & ES_1371_GPIO_OUTM) >= 4)
- val = 1;
- ucontrol->value.integer.value[0] = val;
- spin_unlock_irq(&ensoniq->reg_lock);
- return 0;
-}
-
-static int snd_es1373_line_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
- int changed;
- unsigned int ctrl;
-
- spin_lock_irq(&ensoniq->reg_lock);
- ctrl = ensoniq->ctrl;
- if (ucontrol->value.integer.value[0])
- ensoniq->ctrl |= ES_1371_GPIO_OUT(4); /* switch line-in -> rear out */
- else
- ensoniq->ctrl &= ~ES_1371_GPIO_OUT(4);
- changed = (ctrl != ensoniq->ctrl);
- if (changed)
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- spin_unlock_irq(&ensoniq->reg_lock);
- return changed;
-}
-
-static struct snd_kcontrol_new snd_ens1373_line __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Line In->Rear Out Switch",
- .info = snd_es1373_line_info,
- .get = snd_es1373_line_get,
- .put = snd_es1373_line_put,
-};
-
-static void snd_ensoniq_mixer_free_ac97(struct snd_ac97 *ac97)
-{
- struct ensoniq *ensoniq = ac97->private_data;
- ensoniq->u.es1371.ac97 = NULL;
-}
-
-struct es1371_quirk {
- unsigned short vid; /* vendor ID */
- unsigned short did; /* device ID */
- unsigned char rev; /* revision */
-};
-
-static int es1371_quirk_lookup(struct ensoniq *ensoniq,
- struct es1371_quirk *list)
-{
- while (list->vid != (unsigned short)PCI_ANY_ID) {
- if (ensoniq->pci->vendor == list->vid &&
- ensoniq->pci->device == list->did &&
- ensoniq->rev == list->rev)
- return 1;
- list++;
- }
- return 0;
-}
-
-static struct es1371_quirk es1371_spdif_present[] __devinitdata = {
- { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_C },
- { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_D },
- { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_E },
- { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_ES1371, .rev = ES1371REV_CT5880_A },
- { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_ES1371, .rev = ES1371REV_ES1373_8 },
- { .vid = PCI_ANY_ID, .did = PCI_ANY_ID }
-};
-
-static struct snd_pci_quirk ens1373_line_quirk[] __devinitdata = {
- SND_PCI_QUIRK_ID(0x1274, 0x2000), /* GA-7DXR */
- SND_PCI_QUIRK_ID(0x1458, 0xa000), /* GA-8IEXP */
- { } /* end */
-};
-
-static int __devinit snd_ensoniq_1371_mixer(struct ensoniq *ensoniq,
- int has_spdif, int has_line)
-{
- struct snd_card *card = ensoniq->card;
- struct snd_ac97_bus *pbus;
- struct snd_ac97_template ac97;
- int err;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_es1371_codec_write,
- .read = snd_es1371_codec_read,
- .wait = snd_es1371_codec_wait,
- };
-
- if ((err = snd_ac97_bus(card, 0, &ops, NULL, &pbus)) < 0)
- return err;
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = ensoniq;
- ac97.private_free = snd_ensoniq_mixer_free_ac97;
- ac97.pci = ensoniq->pci;
- ac97.scaps = AC97_SCAP_AUDIO;
- if ((err = snd_ac97_mixer(pbus, &ac97, &ensoniq->u.es1371.ac97)) < 0)
- return err;
- if (has_spdif > 0 ||
- (!has_spdif && es1371_quirk_lookup(ensoniq, es1371_spdif_present))) {
- struct snd_kcontrol *kctl;
- int i, is_spdif = 0;
-
- ensoniq->spdif_default = ensoniq->spdif_stream =
- SNDRV_PCM_DEFAULT_CON_SPDIF;
- outl(ensoniq->spdif_default, ES_REG(ensoniq, CHANNEL_STATUS));
-
- if (ensoniq->u.es1371.ac97->ext_id & AC97_EI_SPDIF)
- is_spdif++;
-
- for (i = 0; i < ARRAY_SIZE(snd_es1371_mixer_spdif); i++) {
- kctl = snd_ctl_new1(&snd_es1371_mixer_spdif[i], ensoniq);
- if (!kctl)
- return -ENOMEM;
- kctl->id.index = is_spdif;
- err = snd_ctl_add(card, kctl);
- if (err < 0)
- return err;
- }
- }
- if (ensoniq->u.es1371.ac97->ext_id & AC97_EI_SDAC) {
- /* mirror rear to front speakers */
- ensoniq->cssr &= ~(ES_1373_REAR_BIT27|ES_1373_REAR_BIT24);
- ensoniq->cssr |= ES_1373_REAR_BIT26;
- err = snd_ctl_add(card, snd_ctl_new1(&snd_ens1373_rear, ensoniq));
- if (err < 0)
- return err;
- }
- if (has_line > 0 ||
- snd_pci_quirk_lookup(ensoniq->pci, ens1373_line_quirk)) {
- err = snd_ctl_add(card, snd_ctl_new1(&snd_ens1373_line,
- ensoniq));
- if (err < 0)
- return err;
- }
-
- return 0;
-}
-
-#endif /* CHIP1371 */
-
-/* generic control callbacks for ens1370 */
-#ifdef CHIP1370
-#define ENSONIQ_CONTROL(xname, mask) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = xname, .info = snd_ensoniq_control_info, \
- .get = snd_ensoniq_control_get, .put = snd_ensoniq_control_put, \
- .private_value = mask }
-
-#define snd_ensoniq_control_info snd_ctl_boolean_mono_info
-
-static int snd_ensoniq_control_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
- int mask = kcontrol->private_value;
-
- spin_lock_irq(&ensoniq->reg_lock);
- ucontrol->value.integer.value[0] = ensoniq->ctrl & mask ? 1 : 0;
- spin_unlock_irq(&ensoniq->reg_lock);
- return 0;
-}
-
-static int snd_ensoniq_control_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
- int mask = kcontrol->private_value;
- unsigned int nval;
- int change;
-
- nval = ucontrol->value.integer.value[0] ? mask : 0;
- spin_lock_irq(&ensoniq->reg_lock);
- change = (ensoniq->ctrl & mask) != nval;
- ensoniq->ctrl &= ~mask;
- ensoniq->ctrl |= nval;
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- spin_unlock_irq(&ensoniq->reg_lock);
- return change;
-}
-
-/*
- * ENS1370 mixer
- */
-
-static struct snd_kcontrol_new snd_es1370_controls[2] __devinitdata = {
-ENSONIQ_CONTROL("PCM 0 Output also on Line-In Jack", ES_1370_XCTL0),
-ENSONIQ_CONTROL("Mic +5V bias", ES_1370_XCTL1)
-};
-
-#define ES1370_CONTROLS ARRAY_SIZE(snd_es1370_controls)
-
-static void snd_ensoniq_mixer_free_ak4531(struct snd_ak4531 *ak4531)
-{
- struct ensoniq *ensoniq = ak4531->private_data;
- ensoniq->u.es1370.ak4531 = NULL;
-}
-
-static int __devinit snd_ensoniq_1370_mixer(struct ensoniq * ensoniq)
-{
- struct snd_card *card = ensoniq->card;
- struct snd_ak4531 ak4531;
- unsigned int idx;
- int err;
-
- /* try reset AK4531 */
- outw(ES_1370_CODEC_WRITE(AK4531_RESET, 0x02), ES_REG(ensoniq, 1370_CODEC));
- inw(ES_REG(ensoniq, 1370_CODEC));
- udelay(100);
- outw(ES_1370_CODEC_WRITE(AK4531_RESET, 0x03), ES_REG(ensoniq, 1370_CODEC));
- inw(ES_REG(ensoniq, 1370_CODEC));
- udelay(100);
-
- memset(&ak4531, 0, sizeof(ak4531));
- ak4531.write = snd_es1370_codec_write;
- ak4531.private_data = ensoniq;
- ak4531.private_free = snd_ensoniq_mixer_free_ak4531;
- if ((err = snd_ak4531_mixer(card, &ak4531, &ensoniq->u.es1370.ak4531)) < 0)
- return err;
- for (idx = 0; idx < ES1370_CONTROLS; idx++) {
- err = snd_ctl_add(card, snd_ctl_new1(&snd_es1370_controls[idx], ensoniq));
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-#endif /* CHIP1370 */
-
-#ifdef SUPPORT_JOYSTICK
-
-#ifdef CHIP1371
-static int __devinit snd_ensoniq_get_joystick_port(int dev)
-{
- switch (joystick_port[dev]) {
- case 0: /* disabled */
- case 1: /* auto-detect */
- case 0x200:
- case 0x208:
- case 0x210:
- case 0x218:
- return joystick_port[dev];
-
- default:
- printk(KERN_ERR "ens1371: invalid joystick port %#x", joystick_port[dev]);
- return 0;
- }
-}
-#else
-static inline int snd_ensoniq_get_joystick_port(int dev)
-{
- return joystick[dev] ? 0x200 : 0;
-}
-#endif
-
-static int __devinit snd_ensoniq_create_gameport(struct ensoniq *ensoniq, int dev)
-{
- struct gameport *gp;
- int io_port;
-
- io_port = snd_ensoniq_get_joystick_port(dev);
-
- switch (io_port) {
- case 0:
- return -ENOSYS;
-
- case 1: /* auto_detect */
- for (io_port = 0x200; io_port <= 0x218; io_port += 8)
- if (request_region(io_port, 8, "ens137x: gameport"))
- break;
- if (io_port > 0x218) {
- printk(KERN_WARNING "ens137x: no gameport ports available\n");
- return -EBUSY;
- }
- break;
-
- default:
- if (!request_region(io_port, 8, "ens137x: gameport")) {
- printk(KERN_WARNING "ens137x: gameport io port 0x%#x in use\n",
- io_port);
- return -EBUSY;
- }
- break;
- }
-
- ensoniq->gameport = gp = gameport_allocate_port();
- if (!gp) {
- printk(KERN_ERR "ens137x: cannot allocate memory for gameport\n");
- release_region(io_port, 8);
- return -ENOMEM;
- }
-
- gameport_set_name(gp, "ES137x");
- gameport_set_phys(gp, "pci%s/gameport0", pci_name(ensoniq->pci));
- gameport_set_dev_parent(gp, &ensoniq->pci->dev);
- gp->io = io_port;
-
- ensoniq->ctrl |= ES_JYSTK_EN;
-#ifdef CHIP1371
- ensoniq->ctrl &= ~ES_1371_JOY_ASELM;
- ensoniq->ctrl |= ES_1371_JOY_ASEL((io_port - 0x200) / 8);
-#endif
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
-
- gameport_register_port(ensoniq->gameport);
-
- return 0;
-}
-
-static void snd_ensoniq_free_gameport(struct ensoniq *ensoniq)
-{
- if (ensoniq->gameport) {
- int port = ensoniq->gameport->io;
-
- gameport_unregister_port(ensoniq->gameport);
- ensoniq->gameport = NULL;
- ensoniq->ctrl &= ~ES_JYSTK_EN;
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- release_region(port, 8);
- }
-}
-#else
-static inline int snd_ensoniq_create_gameport(struct ensoniq *ensoniq, long port) { return -ENOSYS; }
-static inline void snd_ensoniq_free_gameport(struct ensoniq *ensoniq) { }
-#endif /* SUPPORT_JOYSTICK */
-
-/*
-
- */
-
-static void snd_ensoniq_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct ensoniq *ensoniq = entry->private_data;
-
-#ifdef CHIP1370
- snd_iprintf(buffer, "Ensoniq AudioPCI ES1370\n\n");
-#else
- snd_iprintf(buffer, "Ensoniq AudioPCI ES1371\n\n");
-#endif
- snd_iprintf(buffer, "Joystick enable : %s\n",
- ensoniq->ctrl & ES_JYSTK_EN ? "on" : "off");
-#ifdef CHIP1370
- snd_iprintf(buffer, "MIC +5V bias : %s\n",
- ensoniq->ctrl & ES_1370_XCTL1 ? "on" : "off");
- snd_iprintf(buffer, "Line In to AOUT : %s\n",
- ensoniq->ctrl & ES_1370_XCTL0 ? "on" : "off");
-#else
- snd_iprintf(buffer, "Joystick port : 0x%x\n",
- (ES_1371_JOY_ASELI(ensoniq->ctrl) * 8) + 0x200);
-#endif
-}
-
-static void __devinit snd_ensoniq_proc_init(struct ensoniq * ensoniq)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(ensoniq->card, "audiopci", &entry))
- snd_info_set_text_ops(entry, ensoniq, snd_ensoniq_proc_read);
-}
-
-/*
-
- */
-
-static int snd_ensoniq_free(struct ensoniq *ensoniq)
-{
- snd_ensoniq_free_gameport(ensoniq);
- if (ensoniq->irq < 0)
- goto __hw_end;
-#ifdef CHIP1370
- outl(ES_1370_SERR_DISABLE, ES_REG(ensoniq, CONTROL)); /* switch everything off */
- outl(0, ES_REG(ensoniq, SERIAL)); /* clear serial interface */
-#else
- outl(0, ES_REG(ensoniq, CONTROL)); /* switch everything off */
- outl(0, ES_REG(ensoniq, SERIAL)); /* clear serial interface */
-#endif
- if (ensoniq->irq >= 0)
- synchronize_irq(ensoniq->irq);
- pci_set_power_state(ensoniq->pci, 3);
- __hw_end:
-#ifdef CHIP1370
- if (ensoniq->dma_bug.area)
- snd_dma_free_pages(&ensoniq->dma_bug);
-#endif
- if (ensoniq->irq >= 0)
- free_irq(ensoniq->irq, ensoniq);
- pci_release_regions(ensoniq->pci);
- pci_disable_device(ensoniq->pci);
- kfree(ensoniq);
- return 0;
-}
-
-static int snd_ensoniq_dev_free(struct snd_device *device)
-{
- struct ensoniq *ensoniq = device->device_data;
- return snd_ensoniq_free(ensoniq);
-}
-
-#ifdef CHIP1371
-static struct snd_pci_quirk es1371_amplifier_hack[] __devinitdata = {
- SND_PCI_QUIRK_ID(0x107b, 0x2150), /* Gateway Solo 2150 */
- SND_PCI_QUIRK_ID(0x13bd, 0x100c), /* EV1938 on Mebius PC-MJ100V */
- SND_PCI_QUIRK_ID(0x1102, 0x5938), /* Targa Xtender300 */
- SND_PCI_QUIRK_ID(0x1102, 0x8938), /* IPC Topnote G notebook */
- { } /* end */
-};
-
-static struct es1371_quirk es1371_ac97_reset_hack[] = {
- { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_C },
- { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_D },
- { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_E },
- { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_ES1371, .rev = ES1371REV_CT5880_A },
- { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_ES1371, .rev = ES1371REV_ES1373_8 },
- { .vid = PCI_ANY_ID, .did = PCI_ANY_ID }
-};
-#endif
-
-static void snd_ensoniq_chip_init(struct ensoniq *ensoniq)
-{
-#ifdef CHIP1371
- int idx;
-#endif
- /* this code was part of snd_ensoniq_create before intruduction
- * of suspend/resume
- */
-#ifdef CHIP1370
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
- outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE));
- outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME));
- outl(0, ES_REG(ensoniq, PHANTOM_COUNT));
-#else
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
- outl(0, ES_REG(ensoniq, 1371_LEGACY));
- if (es1371_quirk_lookup(ensoniq, es1371_ac97_reset_hack)) {
- outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
- /* need to delay around 20ms(bleech) to give
- some CODECs enough time to wakeup */
- msleep(20);
- }
- /* AC'97 warm reset to start the bitclk */
- outl(ensoniq->ctrl | ES_1371_SYNC_RES, ES_REG(ensoniq, CONTROL));
- inl(ES_REG(ensoniq, CONTROL));
- udelay(20);
- outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
- /* Init the sample rate converter */
- snd_es1371_wait_src_ready(ensoniq);
- outl(ES_1371_SRC_DISABLE, ES_REG(ensoniq, 1371_SMPRATE));
- for (idx = 0; idx < 0x80; idx++)
- snd_es1371_src_write(ensoniq, idx, 0);
- snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4);
- snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10);
- snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4);
- snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10);
- snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, 1 << 12);
- snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, 1 << 12);
- snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1, 1 << 12);
- snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1 + 1, 1 << 12);
- snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2, 1 << 12);
- snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2 + 1, 1 << 12);
- snd_es1371_adc_rate(ensoniq, 22050);
- snd_es1371_dac1_rate(ensoniq, 22050);
- snd_es1371_dac2_rate(ensoniq, 22050);
- /* WARNING:
- * enabling the sample rate converter without properly programming
- * its parameters causes the chip to lock up (the SRC busy bit will
- * be stuck high, and I've found no way to rectify this other than
- * power cycle) - Thomas Sailer
- */
- snd_es1371_wait_src_ready(ensoniq);
- outl(0, ES_REG(ensoniq, 1371_SMPRATE));
- /* try reset codec directly */
- outl(ES_1371_CODEC_WRITE(0, 0), ES_REG(ensoniq, 1371_CODEC));
-#endif
- outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL));
- outb(0x00, ES_REG(ensoniq, UART_RES));
- outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
- synchronize_irq(ensoniq->irq);
-}
-
-#ifdef CONFIG_PM
-static int snd_ensoniq_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct ensoniq *ensoniq = card->private_data;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-
- snd_pcm_suspend_all(ensoniq->pcm1);
- snd_pcm_suspend_all(ensoniq->pcm2);
-
-#ifdef CHIP1371
- snd_ac97_suspend(ensoniq->u.es1371.ac97);
-#else
- /* try to reset AK4531 */
- outw(ES_1370_CODEC_WRITE(AK4531_RESET, 0x02), ES_REG(ensoniq, 1370_CODEC));
- inw(ES_REG(ensoniq, 1370_CODEC));
- udelay(100);
- outw(ES_1370_CODEC_WRITE(AK4531_RESET, 0x03), ES_REG(ensoniq, 1370_CODEC));
- inw(ES_REG(ensoniq, 1370_CODEC));
- udelay(100);
- snd_ak4531_suspend(ensoniq->u.es1370.ak4531);
-#endif
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int snd_ensoniq_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct ensoniq *ensoniq = card->private_data;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR DRIVER_NAME ": pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
-
- snd_ensoniq_chip_init(ensoniq);
-
-#ifdef CHIP1371
- snd_ac97_resume(ensoniq->u.es1371.ac97);
-#else
- snd_ak4531_resume(ensoniq->u.es1370.ak4531);
-#endif
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif /* CONFIG_PM */
-
-
-static int __devinit snd_ensoniq_create(struct snd_card *card,
- struct pci_dev *pci,
- struct ensoniq ** rensoniq)
-{
- struct ensoniq *ensoniq;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_ensoniq_dev_free,
- };
-
- *rensoniq = NULL;
- if ((err = pci_enable_device(pci)) < 0)
- return err;
- ensoniq = kzalloc(sizeof(*ensoniq), GFP_KERNEL);
- if (ensoniq == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
- spin_lock_init(&ensoniq->reg_lock);
- mutex_init(&ensoniq->src_mutex);
- ensoniq->card = card;
- ensoniq->pci = pci;
- ensoniq->irq = -1;
- if ((err = pci_request_regions(pci, "Ensoniq AudioPCI")) < 0) {
- kfree(ensoniq);
- pci_disable_device(pci);
- return err;
- }
- ensoniq->port = pci_resource_start(pci, 0);
- if (request_irq(pci->irq, snd_audiopci_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, ensoniq)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_ensoniq_free(ensoniq);
- return -EBUSY;
- }
- ensoniq->irq = pci->irq;
-#ifdef CHIP1370
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
- 16, &ensoniq->dma_bug) < 0) {
- snd_printk(KERN_ERR "unable to allocate space for phantom area - dma_bug\n");
- snd_ensoniq_free(ensoniq);
- return -EBUSY;
- }
-#endif
- pci_set_master(pci);
- ensoniq->rev = pci->revision;
-#ifdef CHIP1370
-#if 0
- ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_SERR_DISABLE |
- ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000));
-#else /* get microphone working */
- ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000));
-#endif
- ensoniq->sctrl = 0;
-#else
- ensoniq->ctrl = 0;
- ensoniq->sctrl = 0;
- ensoniq->cssr = 0;
- if (snd_pci_quirk_lookup(pci, es1371_amplifier_hack))
- ensoniq->ctrl |= ES_1371_GPIO_OUT(1); /* turn amplifier on */
-
- if (es1371_quirk_lookup(ensoniq, es1371_ac97_reset_hack))
- ensoniq->cssr |= ES_1371_ST_AC97_RST;
-#endif
-
- snd_ensoniq_chip_init(ensoniq);
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) {
- snd_ensoniq_free(ensoniq);
- return err;
- }
-
- snd_ensoniq_proc_init(ensoniq);
-
- snd_card_set_dev(card, &pci->dev);
-
- *rensoniq = ensoniq;
- return 0;
-}
-
-/*
- * MIDI section
- */
-
-static void snd_ensoniq_midi_interrupt(struct ensoniq * ensoniq)
-{
- struct snd_rawmidi *rmidi = ensoniq->rmidi;
- unsigned char status, mask, byte;
-
- if (rmidi == NULL)
- return;
- /* do Rx at first */
- spin_lock(&ensoniq->reg_lock);
- mask = ensoniq->uartm & ES_MODE_INPUT ? ES_RXRDY : 0;
- while (mask) {
- status = inb(ES_REG(ensoniq, UART_STATUS));
- if ((status & mask) == 0)
- break;
- byte = inb(ES_REG(ensoniq, UART_DATA));
- snd_rawmidi_receive(ensoniq->midi_input, &byte, 1);
- }
- spin_unlock(&ensoniq->reg_lock);
-
- /* do Tx at second */
- spin_lock(&ensoniq->reg_lock);
- mask = ensoniq->uartm & ES_MODE_OUTPUT ? ES_TXRDY : 0;
- while (mask) {
- status = inb(ES_REG(ensoniq, UART_STATUS));
- if ((status & mask) == 0)
- break;
- if (snd_rawmidi_transmit(ensoniq->midi_output, &byte, 1) != 1) {
- ensoniq->uartc &= ~ES_TXINTENM;
- outb(ensoniq->uartc, ES_REG(ensoniq, UART_CONTROL));
- mask &= ~ES_TXRDY;
- } else {
- outb(byte, ES_REG(ensoniq, UART_DATA));
- }
- }
- spin_unlock(&ensoniq->reg_lock);
-}
-
-static int snd_ensoniq_midi_input_open(struct snd_rawmidi_substream *substream)
-{
- struct ensoniq *ensoniq = substream->rmidi->private_data;
-
- spin_lock_irq(&ensoniq->reg_lock);
- ensoniq->uartm |= ES_MODE_INPUT;
- ensoniq->midi_input = substream;
- if (!(ensoniq->uartm & ES_MODE_OUTPUT)) {
- outb(ES_CNTRL(3), ES_REG(ensoniq, UART_CONTROL));
- outb(ensoniq->uartc = 0, ES_REG(ensoniq, UART_CONTROL));
- outl(ensoniq->ctrl |= ES_UART_EN, ES_REG(ensoniq, CONTROL));
- }
- spin_unlock_irq(&ensoniq->reg_lock);
- return 0;
-}
-
-static int snd_ensoniq_midi_input_close(struct snd_rawmidi_substream *substream)
-{
- struct ensoniq *ensoniq = substream->rmidi->private_data;
-
- spin_lock_irq(&ensoniq->reg_lock);
- if (!(ensoniq->uartm & ES_MODE_OUTPUT)) {
- outb(ensoniq->uartc = 0, ES_REG(ensoniq, UART_CONTROL));
- outl(ensoniq->ctrl &= ~ES_UART_EN, ES_REG(ensoniq, CONTROL));
- } else {
- outb(ensoniq->uartc &= ~ES_RXINTEN, ES_REG(ensoniq, UART_CONTROL));
- }
- ensoniq->midi_input = NULL;
- ensoniq->uartm &= ~ES_MODE_INPUT;
- spin_unlock_irq(&ensoniq->reg_lock);
- return 0;
-}
-
-static int snd_ensoniq_midi_output_open(struct snd_rawmidi_substream *substream)
-{
- struct ensoniq *ensoniq = substream->rmidi->private_data;
-
- spin_lock_irq(&ensoniq->reg_lock);
- ensoniq->uartm |= ES_MODE_OUTPUT;
- ensoniq->midi_output = substream;
- if (!(ensoniq->uartm & ES_MODE_INPUT)) {
- outb(ES_CNTRL(3), ES_REG(ensoniq, UART_CONTROL));
- outb(ensoniq->uartc = 0, ES_REG(ensoniq, UART_CONTROL));
- outl(ensoniq->ctrl |= ES_UART_EN, ES_REG(ensoniq, CONTROL));
- }
- spin_unlock_irq(&ensoniq->reg_lock);
- return 0;
-}
-
-static int snd_ensoniq_midi_output_close(struct snd_rawmidi_substream *substream)
-{
- struct ensoniq *ensoniq = substream->rmidi->private_data;
-
- spin_lock_irq(&ensoniq->reg_lock);
- if (!(ensoniq->uartm & ES_MODE_INPUT)) {
- outb(ensoniq->uartc = 0, ES_REG(ensoniq, UART_CONTROL));
- outl(ensoniq->ctrl &= ~ES_UART_EN, ES_REG(ensoniq, CONTROL));
- } else {
- outb(ensoniq->uartc &= ~ES_TXINTENM, ES_REG(ensoniq, UART_CONTROL));
- }
- ensoniq->midi_output = NULL;
- ensoniq->uartm &= ~ES_MODE_OUTPUT;
- spin_unlock_irq(&ensoniq->reg_lock);
- return 0;
-}
-
-static void snd_ensoniq_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- unsigned long flags;
- struct ensoniq *ensoniq = substream->rmidi->private_data;
- int idx;
-
- spin_lock_irqsave(&ensoniq->reg_lock, flags);
- if (up) {
- if ((ensoniq->uartc & ES_RXINTEN) == 0) {
- /* empty input FIFO */
- for (idx = 0; idx < 32; idx++)
- inb(ES_REG(ensoniq, UART_DATA));
- ensoniq->uartc |= ES_RXINTEN;
- outb(ensoniq->uartc, ES_REG(ensoniq, UART_CONTROL));
- }
- } else {
- if (ensoniq->uartc & ES_RXINTEN) {
- ensoniq->uartc &= ~ES_RXINTEN;
- outb(ensoniq->uartc, ES_REG(ensoniq, UART_CONTROL));
- }
- }
- spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
-}
-
-static void snd_ensoniq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- unsigned long flags;
- struct ensoniq *ensoniq = substream->rmidi->private_data;
- unsigned char byte;
-
- spin_lock_irqsave(&ensoniq->reg_lock, flags);
- if (up) {
- if (ES_TXINTENI(ensoniq->uartc) == 0) {
- ensoniq->uartc |= ES_TXINTENO(1);
- /* fill UART FIFO buffer at first, and turn Tx interrupts only if necessary */
- while (ES_TXINTENI(ensoniq->uartc) == 1 &&
- (inb(ES_REG(ensoniq, UART_STATUS)) & ES_TXRDY)) {
- if (snd_rawmidi_transmit(substream, &byte, 1) != 1) {
- ensoniq->uartc &= ~ES_TXINTENM;
- } else {
- outb(byte, ES_REG(ensoniq, UART_DATA));
- }
- }
- outb(ensoniq->uartc, ES_REG(ensoniq, UART_CONTROL));
- }
- } else {
- if (ES_TXINTENI(ensoniq->uartc) == 1) {
- ensoniq->uartc &= ~ES_TXINTENM;
- outb(ensoniq->uartc, ES_REG(ensoniq, UART_CONTROL));
- }
- }
- spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
-}
-
-static struct snd_rawmidi_ops snd_ensoniq_midi_output =
-{
- .open = snd_ensoniq_midi_output_open,
- .close = snd_ensoniq_midi_output_close,
- .trigger = snd_ensoniq_midi_output_trigger,
-};
-
-static struct snd_rawmidi_ops snd_ensoniq_midi_input =
-{
- .open = snd_ensoniq_midi_input_open,
- .close = snd_ensoniq_midi_input_close,
- .trigger = snd_ensoniq_midi_input_trigger,
-};
-
-static int __devinit snd_ensoniq_midi(struct ensoniq * ensoniq, int device,
- struct snd_rawmidi **rrawmidi)
-{
- struct snd_rawmidi *rmidi;
- int err;
-
- if (rrawmidi)
- *rrawmidi = NULL;
- if ((err = snd_rawmidi_new(ensoniq->card, "ES1370/1", device, 1, 1, &rmidi)) < 0)
- return err;
-#ifdef CHIP1370
- strcpy(rmidi->name, "ES1370");
-#else
- strcpy(rmidi->name, "ES1371");
-#endif
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_ensoniq_midi_output);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_ensoniq_midi_input);
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
- rmidi->private_data = ensoniq;
- ensoniq->rmidi = rmidi;
- if (rrawmidi)
- *rrawmidi = rmidi;
- return 0;
-}
-
-/*
- * Interrupt handler
- */
-
-static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id)
-{
- struct ensoniq *ensoniq = dev_id;
- unsigned int status, sctrl;
-
- if (ensoniq == NULL)
- return IRQ_NONE;
-
- status = inl(ES_REG(ensoniq, STATUS));
- if (!(status & ES_INTR))
- return IRQ_NONE;
-
- spin_lock(&ensoniq->reg_lock);
- sctrl = ensoniq->sctrl;
- if (status & ES_DAC1)
- sctrl &= ~ES_P1_INT_EN;
- if (status & ES_DAC2)
- sctrl &= ~ES_P2_INT_EN;
- if (status & ES_ADC)
- sctrl &= ~ES_R1_INT_EN;
- outl(sctrl, ES_REG(ensoniq, SERIAL));
- outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
- spin_unlock(&ensoniq->reg_lock);
-
- if (status & ES_UART)
- snd_ensoniq_midi_interrupt(ensoniq);
- if ((status & ES_DAC2) && ensoniq->playback2_substream)
- snd_pcm_period_elapsed(ensoniq->playback2_substream);
- if ((status & ES_ADC) && ensoniq->capture_substream)
- snd_pcm_period_elapsed(ensoniq->capture_substream);
- if ((status & ES_DAC1) && ensoniq->playback1_substream)
- snd_pcm_period_elapsed(ensoniq->playback1_substream);
- return IRQ_HANDLED;
-}
-
-static int __devinit snd_audiopci_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct ensoniq *ensoniq;
- int err, pcm_devs[2];
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- if ((err = snd_ensoniq_create(card, pci, &ensoniq)) < 0) {
- snd_card_free(card);
- return err;
- }
- card->private_data = ensoniq;
-
- pcm_devs[0] = 0; pcm_devs[1] = 1;
-#ifdef CHIP1370
- if ((err = snd_ensoniq_1370_mixer(ensoniq)) < 0) {
- snd_card_free(card);
- return err;
- }
-#endif
-#ifdef CHIP1371
- if ((err = snd_ensoniq_1371_mixer(ensoniq, spdif[dev], lineio[dev])) < 0) {
- snd_card_free(card);
- return err;
- }
-#endif
- if ((err = snd_ensoniq_pcm(ensoniq, 0, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_ensoniq_pcm2(ensoniq, 1, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_ensoniq_midi(ensoniq, 0, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- snd_ensoniq_create_gameport(ensoniq, dev);
-
- strcpy(card->driver, DRIVER_NAME);
-
- strcpy(card->shortname, "Ensoniq AudioPCI");
- sprintf(card->longname, "%s %s at 0x%lx, irq %i",
- card->shortname,
- card->driver,
- ensoniq->port,
- ensoniq->irq);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_audiopci_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_audiopci_ids,
- .probe = snd_audiopci_probe,
- .remove = __devexit_p(snd_audiopci_remove),
-#ifdef CONFIG_PM
- .suspend = snd_ensoniq_suspend,
- .resume = snd_ensoniq_resume,
-#endif
-};
-
-static int __init alsa_card_ens137x_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_ens137x_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_ens137x_init)
-module_exit(alsa_card_ens137x_exit)
diff --git a/ANDROID_3.4.5/sound/pci/ens1371.c b/ANDROID_3.4.5/sound/pci/ens1371.c
deleted file mode 100644
index ca0da0ab..00000000
--- a/ANDROID_3.4.5/sound/pci/ens1371.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define CHIP1371
-#include "ens1370.c"
diff --git a/ANDROID_3.4.5/sound/pci/es1938.c b/ANDROID_3.4.5/sound/pci/es1938.c
deleted file mode 100644
index 53eb76b4..00000000
--- a/ANDROID_3.4.5/sound/pci/es1938.c
+++ /dev/null
@@ -1,1907 +0,0 @@
-/*
- * Driver for ESS Solo-1 (ES1938, ES1946, ES1969) soundcard
- * Copyright (c) by Jaromir Koutek <miri@punknet.cz>,
- * Jaroslav Kysela <perex@perex.cz>,
- * Thomas Sailer <sailer@ife.ee.ethz.ch>,
- * Abramo Bagnara <abramo@alsa-project.org>,
- * Markus Gruber <gruber@eikon.tum.de>
- *
- * Rewritten from sonicvibes.c source.
- *
- * TODO:
- * Rewrite better spinlocks
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- NOTES:
- - Capture data is written unaligned starting from dma_base + 1 so I need to
- disable mmap and to add a copy callback.
- - After several cycle of the following:
- while : ; do arecord -d1 -f cd -t raw | aplay -f cd ; done
- a "playback write error (DMA or IRQ trouble?)" may happen.
- This is due to playback interrupts not generated.
- I suspect a timing issue.
- - Sometimes the interrupt handler is invoked wrongly during playback.
- This generates some harmless "Unexpected hw_pointer: wrong interrupt
- acknowledge".
- I've seen that using small period sizes.
- Reproducible with:
- mpg123 test.mp3 &
- hdparm -t -T /dev/hda
-*/
-
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/gameport.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/opl3.h>
-#include <sound/mpu401.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include <asm/io.h>
-
-MODULE_AUTHOR("Jaromir Koutek <miri@punknet.cz>");
-MODULE_DESCRIPTION("ESS Solo-1");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ESS,ES1938},"
- "{ESS,ES1946},"
- "{ESS,ES1969},"
- "{TerraTec,128i PCI}}");
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK 1
-#endif
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for ESS Solo-1 soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for ESS Solo-1 soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable ESS Solo-1 soundcard.");
-
-#define SLIO_REG(chip, x) ((chip)->io_port + ESSIO_REG_##x)
-
-#define SLDM_REG(chip, x) ((chip)->ddma_port + ESSDM_REG_##x)
-
-#define SLSB_REG(chip, x) ((chip)->sb_port + ESSSB_REG_##x)
-
-#define SL_PCI_LEGACYCONTROL 0x40
-#define SL_PCI_CONFIG 0x50
-#define SL_PCI_DDMACONTROL 0x60
-
-#define ESSIO_REG_AUDIO2DMAADDR 0
-#define ESSIO_REG_AUDIO2DMACOUNT 4
-#define ESSIO_REG_AUDIO2MODE 6
-#define ESSIO_REG_IRQCONTROL 7
-
-#define ESSDM_REG_DMAADDR 0x00
-#define ESSDM_REG_DMACOUNT 0x04
-#define ESSDM_REG_DMACOMMAND 0x08
-#define ESSDM_REG_DMASTATUS 0x08
-#define ESSDM_REG_DMAMODE 0x0b
-#define ESSDM_REG_DMACLEAR 0x0d
-#define ESSDM_REG_DMAMASK 0x0f
-
-#define ESSSB_REG_FMLOWADDR 0x00
-#define ESSSB_REG_FMHIGHADDR 0x02
-#define ESSSB_REG_MIXERADDR 0x04
-#define ESSSB_REG_MIXERDATA 0x05
-
-#define ESSSB_IREG_AUDIO1 0x14
-#define ESSSB_IREG_MICMIX 0x1a
-#define ESSSB_IREG_RECSRC 0x1c
-#define ESSSB_IREG_MASTER 0x32
-#define ESSSB_IREG_FM 0x36
-#define ESSSB_IREG_AUXACD 0x38
-#define ESSSB_IREG_AUXB 0x3a
-#define ESSSB_IREG_PCSPEAKER 0x3c
-#define ESSSB_IREG_LINE 0x3e
-#define ESSSB_IREG_SPATCONTROL 0x50
-#define ESSSB_IREG_SPATLEVEL 0x52
-#define ESSSB_IREG_MASTER_LEFT 0x60
-#define ESSSB_IREG_MASTER_RIGHT 0x62
-#define ESSSB_IREG_MPU401CONTROL 0x64
-#define ESSSB_IREG_MICMIXRECORD 0x68
-#define ESSSB_IREG_AUDIO2RECORD 0x69
-#define ESSSB_IREG_AUXACDRECORD 0x6a
-#define ESSSB_IREG_FMRECORD 0x6b
-#define ESSSB_IREG_AUXBRECORD 0x6c
-#define ESSSB_IREG_MONO 0x6d
-#define ESSSB_IREG_LINERECORD 0x6e
-#define ESSSB_IREG_MONORECORD 0x6f
-#define ESSSB_IREG_AUDIO2SAMPLE 0x70
-#define ESSSB_IREG_AUDIO2MODE 0x71
-#define ESSSB_IREG_AUDIO2FILTER 0x72
-#define ESSSB_IREG_AUDIO2TCOUNTL 0x74
-#define ESSSB_IREG_AUDIO2TCOUNTH 0x76
-#define ESSSB_IREG_AUDIO2CONTROL1 0x78
-#define ESSSB_IREG_AUDIO2CONTROL2 0x7a
-#define ESSSB_IREG_AUDIO2 0x7c
-
-#define ESSSB_REG_RESET 0x06
-
-#define ESSSB_REG_READDATA 0x0a
-#define ESSSB_REG_WRITEDATA 0x0c
-#define ESSSB_REG_READSTATUS 0x0c
-
-#define ESSSB_REG_STATUS 0x0e
-
-#define ESS_CMD_EXTSAMPLERATE 0xa1
-#define ESS_CMD_FILTERDIV 0xa2
-#define ESS_CMD_DMACNTRELOADL 0xa4
-#define ESS_CMD_DMACNTRELOADH 0xa5
-#define ESS_CMD_ANALOGCONTROL 0xa8
-#define ESS_CMD_IRQCONTROL 0xb1
-#define ESS_CMD_DRQCONTROL 0xb2
-#define ESS_CMD_RECLEVEL 0xb4
-#define ESS_CMD_SETFORMAT 0xb6
-#define ESS_CMD_SETFORMAT2 0xb7
-#define ESS_CMD_DMACONTROL 0xb8
-#define ESS_CMD_DMATYPE 0xb9
-#define ESS_CMD_OFFSETLEFT 0xba
-#define ESS_CMD_OFFSETRIGHT 0xbb
-#define ESS_CMD_READREG 0xc0
-#define ESS_CMD_ENABLEEXT 0xc6
-#define ESS_CMD_PAUSEDMA 0xd0
-#define ESS_CMD_ENABLEAUDIO1 0xd1
-#define ESS_CMD_STOPAUDIO1 0xd3
-#define ESS_CMD_AUDIO1STATUS 0xd8
-#define ESS_CMD_CONTDMA 0xd4
-#define ESS_CMD_TESTIRQ 0xf2
-
-#define ESS_RECSRC_MIC 0
-#define ESS_RECSRC_AUXACD 2
-#define ESS_RECSRC_AUXB 5
-#define ESS_RECSRC_LINE 6
-#define ESS_RECSRC_NONE 7
-
-#define DAC1 0x01
-#define ADC1 0x02
-#define DAC2 0x04
-
-/*
-
- */
-
-#define SAVED_REG_SIZE 32 /* max. number of registers to save */
-
-struct es1938 {
- int irq;
-
- unsigned long io_port;
- unsigned long sb_port;
- unsigned long vc_port;
- unsigned long mpu_port;
- unsigned long game_port;
- unsigned long ddma_port;
-
- unsigned char irqmask;
- unsigned char revision;
-
- struct snd_kcontrol *hw_volume;
- struct snd_kcontrol *hw_switch;
- struct snd_kcontrol *master_volume;
- struct snd_kcontrol *master_switch;
-
- struct pci_dev *pci;
- struct snd_card *card;
- struct snd_pcm *pcm;
- struct snd_pcm_substream *capture_substream;
- struct snd_pcm_substream *playback1_substream;
- struct snd_pcm_substream *playback2_substream;
- struct snd_rawmidi *rmidi;
-
- unsigned int dma1_size;
- unsigned int dma2_size;
- unsigned int dma1_start;
- unsigned int dma2_start;
- unsigned int dma1_shift;
- unsigned int dma2_shift;
- unsigned int last_capture_dmaaddr;
- unsigned int active;
-
- spinlock_t reg_lock;
- spinlock_t mixer_lock;
- struct snd_info_entry *proc_entry;
-
-#ifdef SUPPORT_JOYSTICK
- struct gameport *gameport;
-#endif
-#ifdef CONFIG_PM
- unsigned char saved_regs[SAVED_REG_SIZE];
-#endif
-};
-
-static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id);
-
-static DEFINE_PCI_DEVICE_TABLE(snd_es1938_ids) = {
- { PCI_VDEVICE(ESS, 0x1969), 0, }, /* Solo-1 */
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_es1938_ids);
-
-#define RESET_LOOP_TIMEOUT 0x10000
-#define WRITE_LOOP_TIMEOUT 0x10000
-#define GET_LOOP_TIMEOUT 0x01000
-
-#undef REG_DEBUG
-/* -----------------------------------------------------------------
- * Write to a mixer register
- * -----------------------------------------------------------------*/
-static void snd_es1938_mixer_write(struct es1938 *chip, unsigned char reg, unsigned char val)
-{
- unsigned long flags;
- spin_lock_irqsave(&chip->mixer_lock, flags);
- outb(reg, SLSB_REG(chip, MIXERADDR));
- outb(val, SLSB_REG(chip, MIXERDATA));
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
-#ifdef REG_DEBUG
- snd_printk(KERN_DEBUG "Mixer reg %02x set to %02x\n", reg, val);
-#endif
-}
-
-/* -----------------------------------------------------------------
- * Read from a mixer register
- * -----------------------------------------------------------------*/
-static int snd_es1938_mixer_read(struct es1938 *chip, unsigned char reg)
-{
- int data;
- unsigned long flags;
- spin_lock_irqsave(&chip->mixer_lock, flags);
- outb(reg, SLSB_REG(chip, MIXERADDR));
- data = inb(SLSB_REG(chip, MIXERDATA));
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
-#ifdef REG_DEBUG
- snd_printk(KERN_DEBUG "Mixer reg %02x now is %02x\n", reg, data);
-#endif
- return data;
-}
-
-/* -----------------------------------------------------------------
- * Write to some bits of a mixer register (return old value)
- * -----------------------------------------------------------------*/
-static int snd_es1938_mixer_bits(struct es1938 *chip, unsigned char reg,
- unsigned char mask, unsigned char val)
-{
- unsigned long flags;
- unsigned char old, new, oval;
- spin_lock_irqsave(&chip->mixer_lock, flags);
- outb(reg, SLSB_REG(chip, MIXERADDR));
- old = inb(SLSB_REG(chip, MIXERDATA));
- oval = old & mask;
- if (val != oval) {
- new = (old & ~mask) | (val & mask);
- outb(new, SLSB_REG(chip, MIXERDATA));
-#ifdef REG_DEBUG
- snd_printk(KERN_DEBUG "Mixer reg %02x was %02x, set to %02x\n",
- reg, old, new);
-#endif
- }
- spin_unlock_irqrestore(&chip->mixer_lock, flags);
- return oval;
-}
-
-/* -----------------------------------------------------------------
- * Write command to Controller Registers
- * -----------------------------------------------------------------*/
-static void snd_es1938_write_cmd(struct es1938 *chip, unsigned char cmd)
-{
- int i;
- unsigned char v;
- for (i = 0; i < WRITE_LOOP_TIMEOUT; i++) {
- if (!(v = inb(SLSB_REG(chip, READSTATUS)) & 0x80)) {
- outb(cmd, SLSB_REG(chip, WRITEDATA));
- return;
- }
- }
- printk(KERN_ERR "snd_es1938_write_cmd timeout (0x02%x/0x02%x)\n", cmd, v);
-}
-
-/* -----------------------------------------------------------------
- * Read the Read Data Buffer
- * -----------------------------------------------------------------*/
-static int snd_es1938_get_byte(struct es1938 *chip)
-{
- int i;
- unsigned char v;
- for (i = GET_LOOP_TIMEOUT; i; i--)
- if ((v = inb(SLSB_REG(chip, STATUS))) & 0x80)
- return inb(SLSB_REG(chip, READDATA));
- snd_printk(KERN_ERR "get_byte timeout: status 0x02%x\n", v);
- return -ENODEV;
-}
-
-/* -----------------------------------------------------------------
- * Write value cmd register
- * -----------------------------------------------------------------*/
-static void snd_es1938_write(struct es1938 *chip, unsigned char reg, unsigned char val)
-{
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1938_write_cmd(chip, reg);
- snd_es1938_write_cmd(chip, val);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-#ifdef REG_DEBUG
- snd_printk(KERN_DEBUG "Reg %02x set to %02x\n", reg, val);
-#endif
-}
-
-/* -----------------------------------------------------------------
- * Read data from cmd register and return it
- * -----------------------------------------------------------------*/
-static unsigned char snd_es1938_read(struct es1938 *chip, unsigned char reg)
-{
- unsigned char val;
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1938_write_cmd(chip, ESS_CMD_READREG);
- snd_es1938_write_cmd(chip, reg);
- val = snd_es1938_get_byte(chip);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-#ifdef REG_DEBUG
- snd_printk(KERN_DEBUG "Reg %02x now is %02x\n", reg, val);
-#endif
- return val;
-}
-
-/* -----------------------------------------------------------------
- * Write data to cmd register and return old value
- * -----------------------------------------------------------------*/
-static int snd_es1938_bits(struct es1938 *chip, unsigned char reg, unsigned char mask,
- unsigned char val)
-{
- unsigned long flags;
- unsigned char old, new, oval;
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_es1938_write_cmd(chip, ESS_CMD_READREG);
- snd_es1938_write_cmd(chip, reg);
- old = snd_es1938_get_byte(chip);
- oval = old & mask;
- if (val != oval) {
- snd_es1938_write_cmd(chip, reg);
- new = (old & ~mask) | (val & mask);
- snd_es1938_write_cmd(chip, new);
-#ifdef REG_DEBUG
- snd_printk(KERN_DEBUG "Reg %02x was %02x, set to %02x\n",
- reg, old, new);
-#endif
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return oval;
-}
-
-/* --------------------------------------------------------------------
- * Reset the chip
- * --------------------------------------------------------------------*/
-static void snd_es1938_reset(struct es1938 *chip)
-{
- int i;
-
- outb(3, SLSB_REG(chip, RESET));
- inb(SLSB_REG(chip, RESET));
- outb(0, SLSB_REG(chip, RESET));
- for (i = 0; i < RESET_LOOP_TIMEOUT; i++) {
- if (inb(SLSB_REG(chip, STATUS)) & 0x80) {
- if (inb(SLSB_REG(chip, READDATA)) == 0xaa)
- goto __next;
- }
- }
- snd_printk(KERN_ERR "ESS Solo-1 reset failed\n");
-
- __next:
- snd_es1938_write_cmd(chip, ESS_CMD_ENABLEEXT);
-
- /* Demand transfer DMA: 4 bytes per DMA request */
- snd_es1938_write(chip, ESS_CMD_DMATYPE, 2);
-
- /* Change behaviour of register A1
- 4x oversampling
- 2nd channel DAC asynchronous */
- snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2MODE, 0x32);
- /* enable/select DMA channel and IRQ channel */
- snd_es1938_bits(chip, ESS_CMD_IRQCONTROL, 0xf0, 0x50);
- snd_es1938_bits(chip, ESS_CMD_DRQCONTROL, 0xf0, 0x50);
- snd_es1938_write_cmd(chip, ESS_CMD_ENABLEAUDIO1);
- /* Set spatializer parameters to recommended values */
- snd_es1938_mixer_write(chip, 0x54, 0x8f);
- snd_es1938_mixer_write(chip, 0x56, 0x95);
- snd_es1938_mixer_write(chip, 0x58, 0x94);
- snd_es1938_mixer_write(chip, 0x5a, 0x80);
-}
-
-/* --------------------------------------------------------------------
- * Reset the FIFOs
- * --------------------------------------------------------------------*/
-static void snd_es1938_reset_fifo(struct es1938 *chip)
-{
- outb(2, SLSB_REG(chip, RESET));
- outb(0, SLSB_REG(chip, RESET));
-}
-
-static struct snd_ratnum clocks[2] = {
- {
- .num = 793800,
- .den_min = 1,
- .den_max = 128,
- .den_step = 1,
- },
- {
- .num = 768000,
- .den_min = 1,
- .den_max = 128,
- .den_step = 1,
- }
-};
-
-static struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks = {
- .nrats = 2,
- .rats = clocks,
-};
-
-
-static void snd_es1938_rate_set(struct es1938 *chip,
- struct snd_pcm_substream *substream,
- int mode)
-{
- unsigned int bits, div0;
- struct snd_pcm_runtime *runtime = substream->runtime;
- if (runtime->rate_num == clocks[0].num)
- bits = 128 - runtime->rate_den;
- else
- bits = 256 - runtime->rate_den;
-
- /* set filter register */
- div0 = 256 - 7160000*20/(8*82*runtime->rate);
-
- if (mode == DAC2) {
- snd_es1938_mixer_write(chip, 0x70, bits);
- snd_es1938_mixer_write(chip, 0x72, div0);
- } else {
- snd_es1938_write(chip, 0xA1, bits);
- snd_es1938_write(chip, 0xA2, div0);
- }
-}
-
-/* --------------------------------------------------------------------
- * Configure Solo1 builtin DMA Controller
- * --------------------------------------------------------------------*/
-
-static void snd_es1938_playback1_setdma(struct es1938 *chip)
-{
- outb(0x00, SLIO_REG(chip, AUDIO2MODE));
- outl(chip->dma2_start, SLIO_REG(chip, AUDIO2DMAADDR));
- outw(0, SLIO_REG(chip, AUDIO2DMACOUNT));
- outw(chip->dma2_size, SLIO_REG(chip, AUDIO2DMACOUNT));
-}
-
-static void snd_es1938_playback2_setdma(struct es1938 *chip)
-{
- /* Enable DMA controller */
- outb(0xc4, SLDM_REG(chip, DMACOMMAND));
- /* 1. Master reset */
- outb(0, SLDM_REG(chip, DMACLEAR));
- /* 2. Mask DMA */
- outb(1, SLDM_REG(chip, DMAMASK));
- outb(0x18, SLDM_REG(chip, DMAMODE));
- outl(chip->dma1_start, SLDM_REG(chip, DMAADDR));
- outw(chip->dma1_size - 1, SLDM_REG(chip, DMACOUNT));
- /* 3. Unmask DMA */
- outb(0, SLDM_REG(chip, DMAMASK));
-}
-
-static void snd_es1938_capture_setdma(struct es1938 *chip)
-{
- /* Enable DMA controller */
- outb(0xc4, SLDM_REG(chip, DMACOMMAND));
- /* 1. Master reset */
- outb(0, SLDM_REG(chip, DMACLEAR));
- /* 2. Mask DMA */
- outb(1, SLDM_REG(chip, DMAMASK));
- outb(0x14, SLDM_REG(chip, DMAMODE));
- outl(chip->dma1_start, SLDM_REG(chip, DMAADDR));
- chip->last_capture_dmaaddr = chip->dma1_start;
- outw(chip->dma1_size - 1, SLDM_REG(chip, DMACOUNT));
- /* 3. Unmask DMA */
- outb(0, SLDM_REG(chip, DMAMASK));
-}
-
-/* ----------------------------------------------------------------------
- *
- * *** PCM part ***
- */
-
-static int snd_es1938_capture_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct es1938 *chip = snd_pcm_substream_chip(substream);
- int val;
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- val = 0x0f;
- chip->active |= ADC1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- val = 0x00;
- chip->active &= ~ADC1;
- break;
- default:
- return -EINVAL;
- }
- snd_es1938_write(chip, ESS_CMD_DMACONTROL, val);
- return 0;
-}
-
-static int snd_es1938_playback1_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct es1938 *chip = snd_pcm_substream_chip(substream);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- /* According to the documentation this should be:
- 0x13 but that value may randomly swap stereo channels */
- snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0x92);
- udelay(10);
- snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0x93);
- /* This two stage init gives the FIFO -> DAC connection time to
- * settle before first data from DMA flows in. This should ensure
- * no swapping of stereo channels. Report a bug if otherwise :-) */
- outb(0x0a, SLIO_REG(chip, AUDIO2MODE));
- chip->active |= DAC2;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- outb(0, SLIO_REG(chip, AUDIO2MODE));
- snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0);
- chip->active &= ~DAC2;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int snd_es1938_playback2_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct es1938 *chip = snd_pcm_substream_chip(substream);
- int val;
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- val = 5;
- chip->active |= DAC1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- val = 0;
- chip->active &= ~DAC1;
- break;
- default:
- return -EINVAL;
- }
- snd_es1938_write(chip, ESS_CMD_DMACONTROL, val);
- return 0;
-}
-
-static int snd_es1938_playback_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- switch (substream->number) {
- case 0:
- return snd_es1938_playback1_trigger(substream, cmd);
- case 1:
- return snd_es1938_playback2_trigger(substream, cmd);
- }
- snd_BUG();
- return -EINVAL;
-}
-
-/* --------------------------------------------------------------------
- * First channel for Extended Mode Audio 1 ADC Operation
- * --------------------------------------------------------------------*/
-static int snd_es1938_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct es1938 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int u, is8, mono;
- unsigned int size = snd_pcm_lib_buffer_bytes(substream);
- unsigned int count = snd_pcm_lib_period_bytes(substream);
-
- chip->dma1_size = size;
- chip->dma1_start = runtime->dma_addr;
-
- mono = (runtime->channels > 1) ? 0 : 1;
- is8 = snd_pcm_format_width(runtime->format) == 16 ? 0 : 1;
- u = snd_pcm_format_unsigned(runtime->format);
-
- chip->dma1_shift = 2 - mono - is8;
-
- snd_es1938_reset_fifo(chip);
-
- /* program type */
- snd_es1938_bits(chip, ESS_CMD_ANALOGCONTROL, 0x03, (mono ? 2 : 1));
-
- /* set clock and counters */
- snd_es1938_rate_set(chip, substream, ADC1);
-
- count = 0x10000 - count;
- snd_es1938_write(chip, ESS_CMD_DMACNTRELOADL, count & 0xff);
- snd_es1938_write(chip, ESS_CMD_DMACNTRELOADH, count >> 8);
-
- /* initialize and configure ADC */
- snd_es1938_write(chip, ESS_CMD_SETFORMAT2, u ? 0x51 : 0x71);
- snd_es1938_write(chip, ESS_CMD_SETFORMAT2, 0x90 |
- (u ? 0x00 : 0x20) |
- (is8 ? 0x00 : 0x04) |
- (mono ? 0x40 : 0x08));
-
- // snd_es1938_reset_fifo(chip);
-
- /* 11. configure system interrupt controller and DMA controller */
- snd_es1938_capture_setdma(chip);
-
- return 0;
-}
-
-
-/* ------------------------------------------------------------------------------
- * Second Audio channel DAC Operation
- * ------------------------------------------------------------------------------*/
-static int snd_es1938_playback1_prepare(struct snd_pcm_substream *substream)
-{
- struct es1938 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int u, is8, mono;
- unsigned int size = snd_pcm_lib_buffer_bytes(substream);
- unsigned int count = snd_pcm_lib_period_bytes(substream);
-
- chip->dma2_size = size;
- chip->dma2_start = runtime->dma_addr;
-
- mono = (runtime->channels > 1) ? 0 : 1;
- is8 = snd_pcm_format_width(runtime->format) == 16 ? 0 : 1;
- u = snd_pcm_format_unsigned(runtime->format);
-
- chip->dma2_shift = 2 - mono - is8;
-
- snd_es1938_reset_fifo(chip);
-
- /* set clock and counters */
- snd_es1938_rate_set(chip, substream, DAC2);
-
- count >>= 1;
- count = 0x10000 - count;
- snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2TCOUNTL, count & 0xff);
- snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2TCOUNTH, count >> 8);
-
- /* initialize and configure Audio 2 DAC */
- snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL2, 0x40 | (u ? 0 : 4) |
- (mono ? 0 : 2) | (is8 ? 0 : 1));
-
- /* program DMA */
- snd_es1938_playback1_setdma(chip);
-
- return 0;
-}
-
-static int snd_es1938_playback2_prepare(struct snd_pcm_substream *substream)
-{
- struct es1938 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int u, is8, mono;
- unsigned int size = snd_pcm_lib_buffer_bytes(substream);
- unsigned int count = snd_pcm_lib_period_bytes(substream);
-
- chip->dma1_size = size;
- chip->dma1_start = runtime->dma_addr;
-
- mono = (runtime->channels > 1) ? 0 : 1;
- is8 = snd_pcm_format_width(runtime->format) == 16 ? 0 : 1;
- u = snd_pcm_format_unsigned(runtime->format);
-
- chip->dma1_shift = 2 - mono - is8;
-
- count = 0x10000 - count;
-
- /* reset */
- snd_es1938_reset_fifo(chip);
-
- snd_es1938_bits(chip, ESS_CMD_ANALOGCONTROL, 0x03, (mono ? 2 : 1));
-
- /* set clock and counters */
- snd_es1938_rate_set(chip, substream, DAC1);
- snd_es1938_write(chip, ESS_CMD_DMACNTRELOADL, count & 0xff);
- snd_es1938_write(chip, ESS_CMD_DMACNTRELOADH, count >> 8);
-
- /* initialized and configure DAC */
- snd_es1938_write(chip, ESS_CMD_SETFORMAT, u ? 0x80 : 0x00);
- snd_es1938_write(chip, ESS_CMD_SETFORMAT, u ? 0x51 : 0x71);
- snd_es1938_write(chip, ESS_CMD_SETFORMAT2,
- 0x90 | (mono ? 0x40 : 0x08) |
- (is8 ? 0x00 : 0x04) | (u ? 0x00 : 0x20));
-
- /* program DMA */
- snd_es1938_playback2_setdma(chip);
-
- return 0;
-}
-
-static int snd_es1938_playback_prepare(struct snd_pcm_substream *substream)
-{
- switch (substream->number) {
- case 0:
- return snd_es1938_playback1_prepare(substream);
- case 1:
- return snd_es1938_playback2_prepare(substream);
- }
- snd_BUG();
- return -EINVAL;
-}
-
-/* during the incrementing of dma counters the DMA register reads sometimes
- returns garbage. To ensure a valid hw pointer, the following checks which
- should be very unlikely to fail are used:
- - is the current DMA address in the valid DMA range ?
- - is the sum of DMA address and DMA counter pointing to the last DMA byte ?
- One can argue this could differ by one byte depending on which register is
- updated first, so the implementation below allows for that.
-*/
-static snd_pcm_uframes_t snd_es1938_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct es1938 *chip = snd_pcm_substream_chip(substream);
- size_t ptr;
-#if 0
- size_t old, new;
- /* This stuff is *needed*, don't ask why - AB */
- old = inw(SLDM_REG(chip, DMACOUNT));
- while ((new = inw(SLDM_REG(chip, DMACOUNT))) != old)
- old = new;
- ptr = chip->dma1_size - 1 - new;
-#else
- size_t count;
- unsigned int diff;
-
- ptr = inl(SLDM_REG(chip, DMAADDR));
- count = inw(SLDM_REG(chip, DMACOUNT));
- diff = chip->dma1_start + chip->dma1_size - ptr - count;
-
- if (diff > 3 || ptr < chip->dma1_start
- || ptr >= chip->dma1_start+chip->dma1_size)
- ptr = chip->last_capture_dmaaddr; /* bad, use last saved */
- else
- chip->last_capture_dmaaddr = ptr; /* good, remember it */
-
- ptr -= chip->dma1_start;
-#endif
- return ptr >> chip->dma1_shift;
-}
-
-static snd_pcm_uframes_t snd_es1938_playback1_pointer(struct snd_pcm_substream *substream)
-{
- struct es1938 *chip = snd_pcm_substream_chip(substream);
- size_t ptr;
-#if 1
- ptr = chip->dma2_size - inw(SLIO_REG(chip, AUDIO2DMACOUNT));
-#else
- ptr = inl(SLIO_REG(chip, AUDIO2DMAADDR)) - chip->dma2_start;
-#endif
- return ptr >> chip->dma2_shift;
-}
-
-static snd_pcm_uframes_t snd_es1938_playback2_pointer(struct snd_pcm_substream *substream)
-{
- struct es1938 *chip = snd_pcm_substream_chip(substream);
- size_t ptr;
- size_t old, new;
-#if 1
- /* This stuff is *needed*, don't ask why - AB */
- old = inw(SLDM_REG(chip, DMACOUNT));
- while ((new = inw(SLDM_REG(chip, DMACOUNT))) != old)
- old = new;
- ptr = chip->dma1_size - 1 - new;
-#else
- ptr = inl(SLDM_REG(chip, DMAADDR)) - chip->dma1_start;
-#endif
- return ptr >> chip->dma1_shift;
-}
-
-static snd_pcm_uframes_t snd_es1938_playback_pointer(struct snd_pcm_substream *substream)
-{
- switch (substream->number) {
- case 0:
- return snd_es1938_playback1_pointer(substream);
- case 1:
- return snd_es1938_playback2_pointer(substream);
- }
- snd_BUG();
- return -EINVAL;
-}
-
-static int snd_es1938_capture_copy(struct snd_pcm_substream *substream,
- int channel,
- snd_pcm_uframes_t pos,
- void __user *dst,
- snd_pcm_uframes_t count)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct es1938 *chip = snd_pcm_substream_chip(substream);
- pos <<= chip->dma1_shift;
- count <<= chip->dma1_shift;
- if (snd_BUG_ON(pos + count > chip->dma1_size))
- return -EINVAL;
- if (pos + count < chip->dma1_size) {
- if (copy_to_user(dst, runtime->dma_area + pos + 1, count))
- return -EFAULT;
- } else {
- if (copy_to_user(dst, runtime->dma_area + pos + 1, count - 1))
- return -EFAULT;
- if (put_user(runtime->dma_area[0], ((unsigned char __user *)dst) + count - 1))
- return -EFAULT;
- }
- return 0;
-}
-
-/*
- * buffer management
- */
-static int snd_es1938_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-
-{
- int err;
-
- if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
- return err;
- return 0;
-}
-
-static int snd_es1938_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-/* ----------------------------------------------------------------------
- * Audio1 Capture (ADC)
- * ----------------------------------------------------------------------*/
-static struct snd_pcm_hardware snd_es1938_capture =
-{
- .info = (SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER),
- .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 6000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 0x8000, /* DMA controller screws on higher values */
- .period_bytes_min = 64,
- .period_bytes_max = 0x8000,
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 256,
-};
-
-/* -----------------------------------------------------------------------
- * Audio2 Playback (DAC)
- * -----------------------------------------------------------------------*/
-static struct snd_pcm_hardware snd_es1938_playback =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 6000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 0x8000, /* DMA controller screws on higher values */
- .period_bytes_min = 64,
- .period_bytes_max = 0x8000,
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 256,
-};
-
-static int snd_es1938_capture_open(struct snd_pcm_substream *substream)
-{
- struct es1938 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- if (chip->playback2_substream)
- return -EAGAIN;
- chip->capture_substream = substream;
- runtime->hw = snd_es1938_capture;
- snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &hw_constraints_clocks);
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, 0xff00);
- return 0;
-}
-
-static int snd_es1938_playback_open(struct snd_pcm_substream *substream)
-{
- struct es1938 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- switch (substream->number) {
- case 0:
- chip->playback1_substream = substream;
- break;
- case 1:
- if (chip->capture_substream)
- return -EAGAIN;
- chip->playback2_substream = substream;
- break;
- default:
- snd_BUG();
- return -EINVAL;
- }
- runtime->hw = snd_es1938_playback;
- snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &hw_constraints_clocks);
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, 0xff00);
- return 0;
-}
-
-static int snd_es1938_capture_close(struct snd_pcm_substream *substream)
-{
- struct es1938 *chip = snd_pcm_substream_chip(substream);
-
- chip->capture_substream = NULL;
- return 0;
-}
-
-static int snd_es1938_playback_close(struct snd_pcm_substream *substream)
-{
- struct es1938 *chip = snd_pcm_substream_chip(substream);
-
- switch (substream->number) {
- case 0:
- chip->playback1_substream = NULL;
- break;
- case 1:
- chip->playback2_substream = NULL;
- break;
- default:
- snd_BUG();
- return -EINVAL;
- }
- return 0;
-}
-
-static struct snd_pcm_ops snd_es1938_playback_ops = {
- .open = snd_es1938_playback_open,
- .close = snd_es1938_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_es1938_pcm_hw_params,
- .hw_free = snd_es1938_pcm_hw_free,
- .prepare = snd_es1938_playback_prepare,
- .trigger = snd_es1938_playback_trigger,
- .pointer = snd_es1938_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_es1938_capture_ops = {
- .open = snd_es1938_capture_open,
- .close = snd_es1938_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_es1938_pcm_hw_params,
- .hw_free = snd_es1938_pcm_hw_free,
- .prepare = snd_es1938_capture_prepare,
- .trigger = snd_es1938_capture_trigger,
- .pointer = snd_es1938_capture_pointer,
- .copy = snd_es1938_capture_copy,
-};
-
-static int __devinit snd_es1938_new_pcm(struct es1938 *chip, int device)
-{
- struct snd_pcm *pcm;
- int err;
-
- if ((err = snd_pcm_new(chip->card, "es-1938-1946", device, 2, 1, &pcm)) < 0)
- return err;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1938_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_es1938_capture_ops);
-
- pcm->private_data = chip;
- pcm->info_flags = 0;
- strcpy(pcm->name, "ESS Solo-1");
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci), 64*1024, 64*1024);
-
- chip->pcm = pcm;
- return 0;
-}
-
-/* -------------------------------------------------------------------
- *
- * *** Mixer part ***
- */
-
-static int snd_es1938_info_mux(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[8] = {
- "Mic", "Mic Master", "CD", "AOUT",
- "Mic1", "Mix", "Line", "Master"
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 8;
- if (uinfo->value.enumerated.item > 7)
- uinfo->value.enumerated.item = 7;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_es1938_get_mux(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct es1938 *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = snd_es1938_mixer_read(chip, 0x1c) & 0x07;
- return 0;
-}
-
-static int snd_es1938_put_mux(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct es1938 *chip = snd_kcontrol_chip(kcontrol);
- unsigned char val = ucontrol->value.enumerated.item[0];
-
- if (val > 7)
- return -EINVAL;
- return snd_es1938_mixer_bits(chip, 0x1c, 0x07, val) != val;
-}
-
-#define snd_es1938_info_spatializer_enable snd_ctl_boolean_mono_info
-
-static int snd_es1938_get_spatializer_enable(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct es1938 *chip = snd_kcontrol_chip(kcontrol);
- unsigned char val = snd_es1938_mixer_read(chip, 0x50);
- ucontrol->value.integer.value[0] = !!(val & 8);
- return 0;
-}
-
-static int snd_es1938_put_spatializer_enable(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct es1938 *chip = snd_kcontrol_chip(kcontrol);
- unsigned char oval, nval;
- int change;
- nval = ucontrol->value.integer.value[0] ? 0x0c : 0x04;
- oval = snd_es1938_mixer_read(chip, 0x50) & 0x0c;
- change = nval != oval;
- if (change) {
- snd_es1938_mixer_write(chip, 0x50, nval & ~0x04);
- snd_es1938_mixer_write(chip, 0x50, nval);
- }
- return change;
-}
-
-static int snd_es1938_info_hw_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 63;
- return 0;
-}
-
-static int snd_es1938_get_hw_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct es1938 *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = snd_es1938_mixer_read(chip, 0x61) & 0x3f;
- ucontrol->value.integer.value[1] = snd_es1938_mixer_read(chip, 0x63) & 0x3f;
- return 0;
-}
-
-#define snd_es1938_info_hw_switch snd_ctl_boolean_stereo_info
-
-static int snd_es1938_get_hw_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct es1938 *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = !(snd_es1938_mixer_read(chip, 0x61) & 0x40);
- ucontrol->value.integer.value[1] = !(snd_es1938_mixer_read(chip, 0x63) & 0x40);
- return 0;
-}
-
-static void snd_es1938_hwv_free(struct snd_kcontrol *kcontrol)
-{
- struct es1938 *chip = snd_kcontrol_chip(kcontrol);
- chip->master_volume = NULL;
- chip->master_switch = NULL;
- chip->hw_volume = NULL;
- chip->hw_switch = NULL;
-}
-
-static int snd_es1938_reg_bits(struct es1938 *chip, unsigned char reg,
- unsigned char mask, unsigned char val)
-{
- if (reg < 0xa0)
- return snd_es1938_mixer_bits(chip, reg, mask, val);
- else
- return snd_es1938_bits(chip, reg, mask, val);
-}
-
-static int snd_es1938_reg_read(struct es1938 *chip, unsigned char reg)
-{
- if (reg < 0xa0)
- return snd_es1938_mixer_read(chip, reg);
- else
- return snd_es1938_read(chip, reg);
-}
-
-#define ES1938_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,\
- .name = xname, .index = xindex, \
- .info = snd_es1938_info_single, \
- .get = snd_es1938_get_single, .put = snd_es1938_put_single, \
- .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \
- .tlv = { .p = xtlv } }
-#define ES1938_SINGLE(xname, xindex, reg, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_es1938_info_single, \
- .get = snd_es1938_get_single, .put = snd_es1938_put_single, \
- .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
-
-static int snd_es1938_info_single(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 16) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_es1938_get_single(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct es1938 *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
- int val;
-
- val = snd_es1938_reg_read(chip, reg);
- ucontrol->value.integer.value[0] = (val >> shift) & mask;
- if (invert)
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- return 0;
-}
-
-static int snd_es1938_put_single(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct es1938 *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
- unsigned char val;
-
- val = (ucontrol->value.integer.value[0] & mask);
- if (invert)
- val = mask - val;
- mask <<= shift;
- val <<= shift;
- return snd_es1938_reg_bits(chip, reg, mask, val) != val;
-}
-
-#define ES1938_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert, xtlv) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,\
- .name = xname, .index = xindex, \
- .info = snd_es1938_info_double, \
- .get = snd_es1938_get_double, .put = snd_es1938_put_double, \
- .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22), \
- .tlv = { .p = xtlv } }
-#define ES1938_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_es1938_info_double, \
- .get = snd_es1938_get_double, .put = snd_es1938_put_double, \
- .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
-
-static int snd_es1938_info_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 24) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_es1938_get_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct es1938 *chip = snd_kcontrol_chip(kcontrol);
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int shift_left = (kcontrol->private_value >> 16) & 0x07;
- int shift_right = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
- unsigned char left, right;
-
- left = snd_es1938_reg_read(chip, left_reg);
- if (left_reg != right_reg)
- right = snd_es1938_reg_read(chip, right_reg);
- else
- right = left;
- ucontrol->value.integer.value[0] = (left >> shift_left) & mask;
- ucontrol->value.integer.value[1] = (right >> shift_right) & mask;
- if (invert) {
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
- }
- return 0;
-}
-
-static int snd_es1938_put_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct es1938 *chip = snd_kcontrol_chip(kcontrol);
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int shift_left = (kcontrol->private_value >> 16) & 0x07;
- int shift_right = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
- int change;
- unsigned char val1, val2, mask1, mask2;
-
- val1 = ucontrol->value.integer.value[0] & mask;
- val2 = ucontrol->value.integer.value[1] & mask;
- if (invert) {
- val1 = mask - val1;
- val2 = mask - val2;
- }
- val1 <<= shift_left;
- val2 <<= shift_right;
- mask1 = mask << shift_left;
- mask2 = mask << shift_right;
- if (left_reg != right_reg) {
- change = 0;
- if (snd_es1938_reg_bits(chip, left_reg, mask1, val1) != val1)
- change = 1;
- if (snd_es1938_reg_bits(chip, right_reg, mask2, val2) != val2)
- change = 1;
- } else {
- change = (snd_es1938_reg_bits(chip, left_reg, mask1 | mask2,
- val1 | val2) != (val1 | val2));
- }
- return change;
-}
-
-static unsigned int db_scale_master[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 54, TLV_DB_SCALE_ITEM(-3600, 50, 1),
- 54, 63, TLV_DB_SCALE_ITEM(-900, 100, 0),
-};
-
-static unsigned int db_scale_audio1[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 8, TLV_DB_SCALE_ITEM(-3300, 300, 1),
- 8, 15, TLV_DB_SCALE_ITEM(-900, 150, 0),
-};
-
-static unsigned int db_scale_audio2[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 8, TLV_DB_SCALE_ITEM(-3450, 300, 1),
- 8, 15, TLV_DB_SCALE_ITEM(-1050, 150, 0),
-};
-
-static unsigned int db_scale_mic[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 8, TLV_DB_SCALE_ITEM(-2400, 300, 1),
- 8, 15, TLV_DB_SCALE_ITEM(0, 150, 0),
-};
-
-static unsigned int db_scale_line[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 8, TLV_DB_SCALE_ITEM(-3150, 300, 1),
- 8, 15, TLV_DB_SCALE_ITEM(-750, 150, 0),
-};
-
-static const DECLARE_TLV_DB_SCALE(db_scale_capture, 0, 150, 0);
-
-static struct snd_kcontrol_new snd_es1938_controls[] = {
-ES1938_DOUBLE_TLV("Master Playback Volume", 0, 0x60, 0x62, 0, 0, 63, 0,
- db_scale_master),
-ES1938_DOUBLE("Master Playback Switch", 0, 0x60, 0x62, 6, 6, 1, 1),
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Hardware Master Playback Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .info = snd_es1938_info_hw_volume,
- .get = snd_es1938_get_hw_volume,
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READ |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Hardware Master Playback Switch",
- .info = snd_es1938_info_hw_switch,
- .get = snd_es1938_get_hw_switch,
- .tlv = { .p = db_scale_master },
-},
-ES1938_SINGLE("Hardware Volume Split", 0, 0x64, 7, 1, 0),
-ES1938_DOUBLE_TLV("Line Playback Volume", 0, 0x3e, 0x3e, 4, 0, 15, 0,
- db_scale_line),
-ES1938_DOUBLE("CD Playback Volume", 0, 0x38, 0x38, 4, 0, 15, 0),
-ES1938_DOUBLE_TLV("FM Playback Volume", 0, 0x36, 0x36, 4, 0, 15, 0,
- db_scale_mic),
-ES1938_DOUBLE_TLV("Mono Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0,
- db_scale_line),
-ES1938_DOUBLE_TLV("Mic Playback Volume", 0, 0x1a, 0x1a, 4, 0, 15, 0,
- db_scale_mic),
-ES1938_DOUBLE_TLV("Aux Playback Volume", 0, 0x3a, 0x3a, 4, 0, 15, 0,
- db_scale_line),
-ES1938_DOUBLE_TLV("Capture Volume", 0, 0xb4, 0xb4, 4, 0, 15, 0,
- db_scale_capture),
-ES1938_SINGLE("Beep Volume", 0, 0x3c, 0, 7, 0),
-ES1938_SINGLE("Record Monitor", 0, 0xa8, 3, 1, 0),
-ES1938_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1),
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = snd_es1938_info_mux,
- .get = snd_es1938_get_mux,
- .put = snd_es1938_put_mux,
-},
-ES1938_DOUBLE_TLV("Mono Input Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0,
- db_scale_line),
-ES1938_DOUBLE_TLV("PCM Capture Volume", 0, 0x69, 0x69, 4, 0, 15, 0,
- db_scale_audio2),
-ES1938_DOUBLE_TLV("Mic Capture Volume", 0, 0x68, 0x68, 4, 0, 15, 0,
- db_scale_mic),
-ES1938_DOUBLE_TLV("Line Capture Volume", 0, 0x6e, 0x6e, 4, 0, 15, 0,
- db_scale_line),
-ES1938_DOUBLE_TLV("FM Capture Volume", 0, 0x6b, 0x6b, 4, 0, 15, 0,
- db_scale_mic),
-ES1938_DOUBLE_TLV("Mono Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0,
- db_scale_line),
-ES1938_DOUBLE_TLV("CD Capture Volume", 0, 0x6a, 0x6a, 4, 0, 15, 0,
- db_scale_line),
-ES1938_DOUBLE_TLV("Aux Capture Volume", 0, 0x6c, 0x6c, 4, 0, 15, 0,
- db_scale_line),
-ES1938_DOUBLE_TLV("PCM Playback Volume", 0, 0x7c, 0x7c, 4, 0, 15, 0,
- db_scale_audio2),
-ES1938_DOUBLE_TLV("PCM Playback Volume", 1, 0x14, 0x14, 4, 0, 15, 0,
- db_scale_audio1),
-ES1938_SINGLE("3D Control - Level", 0, 0x52, 0, 63, 0),
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "3D Control - Switch",
- .info = snd_es1938_info_spatializer_enable,
- .get = snd_es1938_get_spatializer_enable,
- .put = snd_es1938_put_spatializer_enable,
-},
-ES1938_SINGLE("Mic Boost (+26dB)", 0, 0x7d, 3, 1, 0)
-};
-
-
-/* ---------------------------------------------------------------------------- */
-/* ---------------------------------------------------------------------------- */
-
-/*
- * initialize the chip - used by resume callback, too
- */
-static void snd_es1938_chip_init(struct es1938 *chip)
-{
- /* reset chip */
- snd_es1938_reset(chip);
-
- /* configure native mode */
-
- /* enable bus master */
- pci_set_master(chip->pci);
-
- /* disable legacy audio */
- pci_write_config_word(chip->pci, SL_PCI_LEGACYCONTROL, 0x805f);
-
- /* set DDMA base */
- pci_write_config_word(chip->pci, SL_PCI_DDMACONTROL, chip->ddma_port | 1);
-
- /* set DMA/IRQ policy */
- pci_write_config_dword(chip->pci, SL_PCI_CONFIG, 0);
-
- /* enable Audio 1, Audio 2, MPU401 IRQ and HW volume IRQ*/
- outb(0xf0, SLIO_REG(chip, IRQCONTROL));
-
- /* reset DMA */
- outb(0, SLDM_REG(chip, DMACLEAR));
-}
-
-#ifdef CONFIG_PM
-/*
- * PM support
- */
-
-static unsigned char saved_regs[SAVED_REG_SIZE+1] = {
- 0x14, 0x1a, 0x1c, 0x3a, 0x3c, 0x3e, 0x36, 0x38,
- 0x50, 0x52, 0x60, 0x61, 0x62, 0x63, 0x64, 0x68,
- 0x69, 0x6a, 0x6b, 0x6d, 0x6e, 0x6f, 0x7c, 0x7d,
- 0xa8, 0xb4,
-};
-
-
-static int es1938_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct es1938 *chip = card->private_data;
- unsigned char *s, *d;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(chip->pcm);
-
- /* save mixer-related registers */
- for (s = saved_regs, d = chip->saved_regs; *s; s++, d++)
- *d = snd_es1938_reg_read(chip, *s);
-
- outb(0x00, SLIO_REG(chip, IRQCONTROL)); /* disable irqs */
- if (chip->irq >= 0) {
- free_irq(chip->irq, chip);
- chip->irq = -1;
- }
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int es1938_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct es1938 *chip = card->private_data;
- unsigned char *s, *d;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "es1938: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
-
- if (request_irq(pci->irq, snd_es1938_interrupt,
- IRQF_SHARED, KBUILD_MODNAME, chip)) {
- printk(KERN_ERR "es1938: unable to grab IRQ %d, "
- "disabling device\n", pci->irq);
- snd_card_disconnect(card);
- return -EIO;
- }
- chip->irq = pci->irq;
- snd_es1938_chip_init(chip);
-
- /* restore mixer-related registers */
- for (s = saved_regs, d = chip->saved_regs; *s; s++, d++) {
- if (*s < 0xa0)
- snd_es1938_mixer_write(chip, *s, *d);
- else
- snd_es1938_write(chip, *s, *d);
- }
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif /* CONFIG_PM */
-
-#ifdef SUPPORT_JOYSTICK
-static int __devinit snd_es1938_create_gameport(struct es1938 *chip)
-{
- struct gameport *gp;
-
- chip->gameport = gp = gameport_allocate_port();
- if (!gp) {
- printk(KERN_ERR "es1938: cannot allocate memory for gameport\n");
- return -ENOMEM;
- }
-
- gameport_set_name(gp, "ES1938");
- gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
- gameport_set_dev_parent(gp, &chip->pci->dev);
- gp->io = chip->game_port;
-
- gameport_register_port(gp);
-
- return 0;
-}
-
-static void snd_es1938_free_gameport(struct es1938 *chip)
-{
- if (chip->gameport) {
- gameport_unregister_port(chip->gameport);
- chip->gameport = NULL;
- }
-}
-#else
-static inline int snd_es1938_create_gameport(struct es1938 *chip) { return -ENOSYS; }
-static inline void snd_es1938_free_gameport(struct es1938 *chip) { }
-#endif /* SUPPORT_JOYSTICK */
-
-static int snd_es1938_free(struct es1938 *chip)
-{
- /* disable irqs */
- outb(0x00, SLIO_REG(chip, IRQCONTROL));
- if (chip->rmidi)
- snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0);
-
- snd_es1938_free_gameport(chip);
-
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
- kfree(chip);
- return 0;
-}
-
-static int snd_es1938_dev_free(struct snd_device *device)
-{
- struct es1938 *chip = device->device_data;
- return snd_es1938_free(chip);
-}
-
-static int __devinit snd_es1938_create(struct snd_card *card,
- struct pci_dev * pci,
- struct es1938 ** rchip)
-{
- struct es1938 *chip;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_es1938_dev_free,
- };
-
- *rchip = NULL;
-
- /* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
- return err;
- /* check, if we can restrict PCI DMA transfers to 24 bits */
- if (pci_set_dma_mask(pci, DMA_BIT_MASK(24)) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(24)) < 0) {
- snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
- pci_disable_device(pci);
- return -ENXIO;
- }
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
- spin_lock_init(&chip->reg_lock);
- spin_lock_init(&chip->mixer_lock);
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
- if ((err = pci_request_regions(pci, "ESS Solo-1")) < 0) {
- kfree(chip);
- pci_disable_device(pci);
- return err;
- }
- chip->io_port = pci_resource_start(pci, 0);
- chip->sb_port = pci_resource_start(pci, 1);
- chip->vc_port = pci_resource_start(pci, 2);
- chip->mpu_port = pci_resource_start(pci, 3);
- chip->game_port = pci_resource_start(pci, 4);
- if (request_irq(pci->irq, snd_es1938_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_es1938_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
-#ifdef ES1938_DDEBUG
- snd_printk(KERN_DEBUG "create: io: 0x%lx, sb: 0x%lx, vc: 0x%lx, mpu: 0x%lx, game: 0x%lx\n",
- chip->io_port, chip->sb_port, chip->vc_port, chip->mpu_port, chip->game_port);
-#endif
-
- chip->ddma_port = chip->vc_port + 0x00; /* fix from Thomas Sailer */
-
- snd_es1938_chip_init(chip);
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_es1938_free(chip);
- return err;
- }
-
- snd_card_set_dev(card, &pci->dev);
-
- *rchip = chip;
- return 0;
-}
-
-/* --------------------------------------------------------------------
- * Interrupt handler
- * -------------------------------------------------------------------- */
-static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id)
-{
- struct es1938 *chip = dev_id;
- unsigned char status, audiostatus;
- int handled = 0;
-
- status = inb(SLIO_REG(chip, IRQCONTROL));
-#if 0
- printk(KERN_DEBUG "Es1938debug - interrupt status: =0x%x\n", status);
-#endif
-
- /* AUDIO 1 */
- if (status & 0x10) {
-#if 0
- printk(KERN_DEBUG
- "Es1938debug - AUDIO channel 1 interrupt\n");
- printk(KERN_DEBUG
- "Es1938debug - AUDIO channel 1 DMAC DMA count: %u\n",
- inw(SLDM_REG(chip, DMACOUNT)));
- printk(KERN_DEBUG
- "Es1938debug - AUDIO channel 1 DMAC DMA base: %u\n",
- inl(SLDM_REG(chip, DMAADDR)));
- printk(KERN_DEBUG
- "Es1938debug - AUDIO channel 1 DMAC DMA status: 0x%x\n",
- inl(SLDM_REG(chip, DMASTATUS)));
-#endif
- /* clear irq */
- handled = 1;
- audiostatus = inb(SLSB_REG(chip, STATUS));
- if (chip->active & ADC1)
- snd_pcm_period_elapsed(chip->capture_substream);
- else if (chip->active & DAC1)
- snd_pcm_period_elapsed(chip->playback2_substream);
- }
-
- /* AUDIO 2 */
- if (status & 0x20) {
-#if 0
- printk(KERN_DEBUG
- "Es1938debug - AUDIO channel 2 interrupt\n");
- printk(KERN_DEBUG
- "Es1938debug - AUDIO channel 2 DMAC DMA count: %u\n",
- inw(SLIO_REG(chip, AUDIO2DMACOUNT)));
- printk(KERN_DEBUG
- "Es1938debug - AUDIO channel 2 DMAC DMA base: %u\n",
- inl(SLIO_REG(chip, AUDIO2DMAADDR)));
-
-#endif
- /* clear irq */
- handled = 1;
- snd_es1938_mixer_bits(chip, ESSSB_IREG_AUDIO2CONTROL2, 0x80, 0);
- if (chip->active & DAC2)
- snd_pcm_period_elapsed(chip->playback1_substream);
- }
-
- /* Hardware volume */
- if (status & 0x40) {
- int split = snd_es1938_mixer_read(chip, 0x64) & 0x80;
- handled = 1;
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_switch->id);
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_volume->id);
- if (!split) {
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->master_switch->id);
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->master_volume->id);
- }
- /* ack interrupt */
- snd_es1938_mixer_write(chip, 0x66, 0x00);
- }
-
- /* MPU401 */
- if (status & 0x80) {
- // the following line is evil! It switches off MIDI interrupt handling after the first interrupt received.
- // replacing the last 0 by 0x40 works for ESS-Solo1, but just doing nothing works as well!
- // andreas@flying-snail.de
- // snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0); /* ack? */
- if (chip->rmidi) {
- handled = 1;
- snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
- }
- }
- return IRQ_RETVAL(handled);
-}
-
-#define ES1938_DMA_SIZE 64
-
-static int __devinit snd_es1938_mixer(struct es1938 *chip)
-{
- struct snd_card *card;
- unsigned int idx;
- int err;
-
- card = chip->card;
-
- strcpy(card->mixername, "ESS Solo-1");
-
- for (idx = 0; idx < ARRAY_SIZE(snd_es1938_controls); idx++) {
- struct snd_kcontrol *kctl;
- kctl = snd_ctl_new1(&snd_es1938_controls[idx], chip);
- switch (idx) {
- case 0:
- chip->master_volume = kctl;
- kctl->private_free = snd_es1938_hwv_free;
- break;
- case 1:
- chip->master_switch = kctl;
- kctl->private_free = snd_es1938_hwv_free;
- break;
- case 2:
- chip->hw_volume = kctl;
- kctl->private_free = snd_es1938_hwv_free;
- break;
- case 3:
- chip->hw_switch = kctl;
- kctl->private_free = snd_es1938_hwv_free;
- break;
- }
- if ((err = snd_ctl_add(card, kctl)) < 0)
- return err;
- }
- return 0;
-}
-
-
-static int __devinit snd_es1938_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct es1938 *chip;
- struct snd_opl3 *opl3;
- int idx, err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
- for (idx = 0; idx < 5; idx++) {
- if (pci_resource_start(pci, idx) == 0 ||
- !(pci_resource_flags(pci, idx) & IORESOURCE_IO)) {
- snd_card_free(card);
- return -ENODEV;
- }
- }
- if ((err = snd_es1938_create(card, pci, &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
- card->private_data = chip;
-
- strcpy(card->driver, "ES1938");
- strcpy(card->shortname, "ESS ES1938 (Solo-1)");
- sprintf(card->longname, "%s rev %i, irq %i",
- card->shortname,
- chip->revision,
- chip->irq);
-
- if ((err = snd_es1938_new_pcm(chip, 0)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_es1938_mixer(chip)) < 0) {
- snd_card_free(card);
- return err;
- }
- if (snd_opl3_create(card,
- SLSB_REG(chip, FMLOWADDR),
- SLSB_REG(chip, FMHIGHADDR),
- OPL3_HW_OPL3, 1, &opl3) < 0) {
- printk(KERN_ERR "es1938: OPL3 not detected at 0x%lx\n",
- SLSB_REG(chip, FMLOWADDR));
- } else {
- if ((err = snd_opl3_timer_new(opl3, 0, 1)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- }
- if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
- chip->mpu_port,
- MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK,
- -1, &chip->rmidi) < 0) {
- printk(KERN_ERR "es1938: unable to initialize MPU-401\n");
- } else {
- // this line is vital for MIDI interrupt handling on ess-solo1
- // andreas@flying-snail.de
- snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0x40);
- }
-
- snd_es1938_create_gameport(chip);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_es1938_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_es1938_ids,
- .probe = snd_es1938_probe,
- .remove = __devexit_p(snd_es1938_remove),
-#ifdef CONFIG_PM
- .suspend = es1938_suspend,
- .resume = es1938_resume,
-#endif
-};
-
-static int __init alsa_card_es1938_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_es1938_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_es1938_init)
-module_exit(alsa_card_es1938_exit)
diff --git a/ANDROID_3.4.5/sound/pci/es1968.c b/ANDROID_3.4.5/sound/pci/es1968.c
deleted file mode 100644
index a8faae1c..00000000
--- a/ANDROID_3.4.5/sound/pci/es1968.c
+++ /dev/null
@@ -1,2923 +0,0 @@
-/*
- * Driver for ESS Maestro 1/2/2E Sound Card (started 21.8.99)
- * Copyright (c) by Matze Braun <MatzeBraun@gmx.de>.
- * Takashi Iwai <tiwai@suse.de>
- *
- * Most of the driver code comes from Zach Brown(zab@redhat.com)
- * Alan Cox OSS Driver
- * Rewritted from card-es1938.c source.
- *
- * TODO:
- * Perhaps Synth
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
- * Notes from Zach Brown about the driver code
- *
- * Hardware Description
- *
- * A working Maestro setup contains the Maestro chip wired to a
- * codec or 2. In the Maestro we have the APUs, the ASSP, and the
- * Wavecache. The APUs can be though of as virtual audio routing
- * channels. They can take data from a number of sources and perform
- * basic encodings of the data. The wavecache is a storehouse for
- * PCM data. Typically it deals with PCI and interracts with the
- * APUs. The ASSP is a wacky DSP like device that ESS is loth
- * to release docs on. Thankfully it isn't required on the Maestro
- * until you start doing insane things like FM emulation and surround
- * encoding. The codecs are almost always AC-97 compliant codecs,
- * but it appears that early Maestros may have had PT101 (an ESS
- * part?) wired to them. The only real difference in the Maestro
- * families is external goop like docking capability, memory for
- * the ASSP, and initialization differences.
- *
- * Driver Operation
- *
- * We only drive the APU/Wavecache as typical DACs and drive the
- * mixers in the codecs. There are 64 APUs. We assign 6 to each
- * /dev/dsp? device. 2 channels for output, and 4 channels for
- * input.
- *
- * Each APU can do a number of things, but we only really use
- * 3 basic functions. For playback we use them to convert PCM
- * data fetched over PCI by the wavecahche into analog data that
- * is handed to the codec. One APU for mono, and a pair for stereo.
- * When in stereo, the combination of smarts in the APU and Wavecache
- * decide which wavecache gets the left or right channel.
- *
- * For record we still use the old overly mono system. For each in
- * coming channel the data comes in from the codec, through a 'input'
- * APU, through another rate converter APU, and then into memory via
- * the wavecache and PCI. If its stereo, we mash it back into LRLR in
- * software. The pass between the 2 APUs is supposedly what requires us
- * to have a 512 byte buffer sitting around in wavecache/memory.
- *
- * The wavecache makes our life even more fun. First off, it can
- * only address the first 28 bits of PCI address space, making it
- * useless on quite a few architectures. Secondly, its insane.
- * It claims to fetch from 4 regions of PCI space, each 4 meg in length.
- * But that doesn't really work. You can only use 1 region. So all our
- * allocations have to be in 4meg of each other. Booo. Hiss.
- * So we have a module parameter, dsps_order, that is the order of
- * the number of dsps to provide. All their buffer space is allocated
- * on open time. The sonicvibes OSS routines we inherited really want
- * power of 2 buffers, so we have all those next to each other, then
- * 512 byte regions for the recording wavecaches. This ends up
- * wasting quite a bit of memory. The only fixes I can see would be
- * getting a kernel allocator that could work in zones, or figuring out
- * just how to coerce the WP into doing what we want.
- *
- * The indirection of the various registers means we have to spinlock
- * nearly all register accesses. We have the main register indirection
- * like the wave cache, maestro registers, etc. Then we have beasts
- * like the APU interface that is indirect registers gotten at through
- * the main maestro indirection. Ouch. We spinlock around the actual
- * ports on a per card basis. This means spinlock activity at each IO
- * operation, but the only IO operation clusters are in non critical
- * paths and it makes the code far easier to follow. Interrupts are
- * blocked while holding the locks because the int handler has to
- * get at some of them :(. The mixer interface doesn't, however.
- * We also have an OSS state lock that is thrown around in a few
- * places.
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-#include <linux/gameport.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/input.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/mpu401.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-
-#ifdef CONFIG_SND_ES1968_RADIO
-#include <sound/tea575x-tuner.h>
-#endif
-
-#define CARD_NAME "ESS Maestro1/2"
-#define DRIVER_NAME "ES1968"
-
-MODULE_DESCRIPTION("ESS Maestro");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ESS,Maestro 2e},"
- "{ESS,Maestro 2},"
- "{ESS,Maestro 1},"
- "{TerraTec,DMX}}");
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK 1
-#endif
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 1-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int total_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1024 };
-static int pcm_substreams_p[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4 };
-static int pcm_substreams_c[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1 };
-static int clock[SNDRV_CARDS];
-static int use_pm[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
-static int enable_mpu[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
-#ifdef SUPPORT_JOYSTICK
-static bool joystick[SNDRV_CARDS];
-#endif
-static int radio_nr[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
-module_param_array(total_bufsize, int, NULL, 0444);
-MODULE_PARM_DESC(total_bufsize, "Total buffer size in kB.");
-module_param_array(pcm_substreams_p, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_substreams_p, "PCM Playback substreams for " CARD_NAME " soundcard.");
-module_param_array(pcm_substreams_c, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_substreams_c, "PCM Capture substreams for " CARD_NAME " soundcard.");
-module_param_array(clock, int, NULL, 0444);
-MODULE_PARM_DESC(clock, "Clock on " CARD_NAME " soundcard. (0 = auto-detect)");
-module_param_array(use_pm, int, NULL, 0444);
-MODULE_PARM_DESC(use_pm, "Toggle power-management. (0 = off, 1 = on, 2 = auto)");
-module_param_array(enable_mpu, int, NULL, 0444);
-MODULE_PARM_DESC(enable_mpu, "Enable MPU401. (0 = off, 1 = on, 2 = auto)");
-#ifdef SUPPORT_JOYSTICK
-module_param_array(joystick, bool, NULL, 0444);
-MODULE_PARM_DESC(joystick, "Enable joystick.");
-#endif
-module_param_array(radio_nr, int, NULL, 0444);
-MODULE_PARM_DESC(radio_nr, "Radio device numbers");
-
-
-
-#define NR_APUS 64
-#define NR_APU_REGS 16
-
-/* NEC Versas ? */
-#define NEC_VERSA_SUBID1 0x80581033
-#define NEC_VERSA_SUBID2 0x803c1033
-
-/* Mode Flags */
-#define ESS_FMT_STEREO 0x01
-#define ESS_FMT_16BIT 0x02
-
-#define DAC_RUNNING 1
-#define ADC_RUNNING 2
-
-/* Values for the ESM_LEGACY_AUDIO_CONTROL */
-
-#define ESS_DISABLE_AUDIO 0x8000
-#define ESS_ENABLE_SERIAL_IRQ 0x4000
-#define IO_ADRESS_ALIAS 0x0020
-#define MPU401_IRQ_ENABLE 0x0010
-#define MPU401_IO_ENABLE 0x0008
-#define GAME_IO_ENABLE 0x0004
-#define FM_IO_ENABLE 0x0002
-#define SB_IO_ENABLE 0x0001
-
-/* Values for the ESM_CONFIG_A */
-
-#define PIC_SNOOP1 0x4000
-#define PIC_SNOOP2 0x2000
-#define SAFEGUARD 0x0800
-#define DMA_CLEAR 0x0700
-#define DMA_DDMA 0x0000
-#define DMA_TDMA 0x0100
-#define DMA_PCPCI 0x0200
-#define POST_WRITE 0x0080
-#define PCI_TIMING 0x0040
-#define SWAP_LR 0x0020
-#define SUBTR_DECODE 0x0002
-
-/* Values for the ESM_CONFIG_B */
-
-#define SPDIF_CONFB 0x0100
-#define HWV_CONFB 0x0080
-#define DEBOUNCE 0x0040
-#define GPIO_CONFB 0x0020
-#define CHI_CONFB 0x0010
-#define IDMA_CONFB 0x0008 /*undoc */
-#define MIDI_FIX 0x0004 /*undoc */
-#define IRQ_TO_ISA 0x0001 /*undoc */
-
-/* Values for Ring Bus Control B */
-#define RINGB_2CODEC_ID_MASK 0x0003
-#define RINGB_DIS_VALIDATION 0x0008
-#define RINGB_EN_SPDIF 0x0010
-#define RINGB_EN_2CODEC 0x0020
-#define RINGB_SING_BIT_DUAL 0x0040
-
-/* ****Port Addresses**** */
-
-/* Write & Read */
-#define ESM_INDEX 0x02
-#define ESM_DATA 0x00
-
-/* AC97 + RingBus */
-#define ESM_AC97_INDEX 0x30
-#define ESM_AC97_DATA 0x32
-#define ESM_RING_BUS_DEST 0x34
-#define ESM_RING_BUS_CONTR_A 0x36
-#define ESM_RING_BUS_CONTR_B 0x38
-#define ESM_RING_BUS_SDO 0x3A
-
-/* WaveCache*/
-#define WC_INDEX 0x10
-#define WC_DATA 0x12
-#define WC_CONTROL 0x14
-
-/* ASSP*/
-#define ASSP_INDEX 0x80
-#define ASSP_MEMORY 0x82
-#define ASSP_DATA 0x84
-#define ASSP_CONTROL_A 0xA2
-#define ASSP_CONTROL_B 0xA4
-#define ASSP_CONTROL_C 0xA6
-#define ASSP_HOSTW_INDEX 0xA8
-#define ASSP_HOSTW_DATA 0xAA
-#define ASSP_HOSTW_IRQ 0xAC
-/* Midi */
-#define ESM_MPU401_PORT 0x98
-/* Others */
-#define ESM_PORT_HOST_IRQ 0x18
-
-#define IDR0_DATA_PORT 0x00
-#define IDR1_CRAM_POINTER 0x01
-#define IDR2_CRAM_DATA 0x02
-#define IDR3_WAVE_DATA 0x03
-#define IDR4_WAVE_PTR_LOW 0x04
-#define IDR5_WAVE_PTR_HI 0x05
-#define IDR6_TIMER_CTRL 0x06
-#define IDR7_WAVE_ROMRAM 0x07
-
-#define WRITEABLE_MAP 0xEFFFFF
-#define READABLE_MAP 0x64003F
-
-/* PCI Register */
-
-#define ESM_LEGACY_AUDIO_CONTROL 0x40
-#define ESM_ACPI_COMMAND 0x54
-#define ESM_CONFIG_A 0x50
-#define ESM_CONFIG_B 0x52
-#define ESM_DDMA 0x60
-
-/* Bob Bits */
-#define ESM_BOB_ENABLE 0x0001
-#define ESM_BOB_START 0x0001
-
-/* Host IRQ Control Bits */
-#define ESM_RESET_MAESTRO 0x8000
-#define ESM_RESET_DIRECTSOUND 0x4000
-#define ESM_HIRQ_ClkRun 0x0100
-#define ESM_HIRQ_HW_VOLUME 0x0040
-#define ESM_HIRQ_HARPO 0x0030 /* What's that? */
-#define ESM_HIRQ_ASSP 0x0010
-#define ESM_HIRQ_DSIE 0x0004
-#define ESM_HIRQ_MPU401 0x0002
-#define ESM_HIRQ_SB 0x0001
-
-/* Host IRQ Status Bits */
-#define ESM_MPU401_IRQ 0x02
-#define ESM_SB_IRQ 0x01
-#define ESM_SOUND_IRQ 0x04
-#define ESM_ASSP_IRQ 0x10
-#define ESM_HWVOL_IRQ 0x40
-
-#define ESS_SYSCLK 50000000
-#define ESM_BOB_FREQ 200
-#define ESM_BOB_FREQ_MAX 800
-
-#define ESM_FREQ_ESM1 (49152000L / 1024L) /* default rate 48000 */
-#define ESM_FREQ_ESM2 (50000000L / 1024L)
-
-/* APU Modes: reg 0x00, bit 4-7 */
-#define ESM_APU_MODE_SHIFT 4
-#define ESM_APU_MODE_MASK (0xf << 4)
-#define ESM_APU_OFF 0x00
-#define ESM_APU_16BITLINEAR 0x01 /* 16-Bit Linear Sample Player */
-#define ESM_APU_16BITSTEREO 0x02 /* 16-Bit Stereo Sample Player */
-#define ESM_APU_8BITLINEAR 0x03 /* 8-Bit Linear Sample Player */
-#define ESM_APU_8BITSTEREO 0x04 /* 8-Bit Stereo Sample Player */
-#define ESM_APU_8BITDIFF 0x05 /* 8-Bit Differential Sample Playrer */
-#define ESM_APU_DIGITALDELAY 0x06 /* Digital Delay Line */
-#define ESM_APU_DUALTAP 0x07 /* Dual Tap Reader */
-#define ESM_APU_CORRELATOR 0x08 /* Correlator */
-#define ESM_APU_INPUTMIXER 0x09 /* Input Mixer */
-#define ESM_APU_WAVETABLE 0x0A /* Wave Table Mode */
-#define ESM_APU_SRCONVERTOR 0x0B /* Sample Rate Convertor */
-#define ESM_APU_16BITPINGPONG 0x0C /* 16-Bit Ping-Pong Sample Player */
-#define ESM_APU_RESERVED1 0x0D /* Reserved 1 */
-#define ESM_APU_RESERVED2 0x0E /* Reserved 2 */
-#define ESM_APU_RESERVED3 0x0F /* Reserved 3 */
-
-/* reg 0x00 */
-#define ESM_APU_FILTER_Q_SHIFT 0
-#define ESM_APU_FILTER_Q_MASK (3 << 0)
-/* APU Filtey Q Control */
-#define ESM_APU_FILTER_LESSQ 0x00
-#define ESM_APU_FILTER_MOREQ 0x03
-
-#define ESM_APU_FILTER_TYPE_SHIFT 2
-#define ESM_APU_FILTER_TYPE_MASK (3 << 2)
-#define ESM_APU_ENV_TYPE_SHIFT 8
-#define ESM_APU_ENV_TYPE_MASK (3 << 8)
-#define ESM_APU_ENV_STATE_SHIFT 10
-#define ESM_APU_ENV_STATE_MASK (3 << 10)
-#define ESM_APU_END_CURVE (1 << 12)
-#define ESM_APU_INT_ON_LOOP (1 << 13)
-#define ESM_APU_DMA_ENABLE (1 << 14)
-
-/* reg 0x02 */
-#define ESM_APU_SUBMIX_GROUP_SHIRT 0
-#define ESM_APU_SUBMIX_GROUP_MASK (7 << 0)
-#define ESM_APU_SUBMIX_MODE (1 << 3)
-#define ESM_APU_6dB (1 << 4)
-#define ESM_APU_DUAL_EFFECT (1 << 5)
-#define ESM_APU_EFFECT_CHANNELS_SHIFT 6
-#define ESM_APU_EFFECT_CHANNELS_MASK (3 << 6)
-
-/* reg 0x03 */
-#define ESM_APU_STEP_SIZE_MASK 0x0fff
-
-/* reg 0x04 */
-#define ESM_APU_PHASE_SHIFT 0
-#define ESM_APU_PHASE_MASK (0xff << 0)
-#define ESM_APU_WAVE64K_PAGE_SHIFT 8 /* most 8bit of wave start offset */
-#define ESM_APU_WAVE64K_PAGE_MASK (0xff << 8)
-
-/* reg 0x05 - wave start offset */
-/* reg 0x06 - wave end offset */
-/* reg 0x07 - wave loop length */
-
-/* reg 0x08 */
-#define ESM_APU_EFFECT_GAIN_SHIFT 0
-#define ESM_APU_EFFECT_GAIN_MASK (0xff << 0)
-#define ESM_APU_TREMOLO_DEPTH_SHIFT 8
-#define ESM_APU_TREMOLO_DEPTH_MASK (0xf << 8)
-#define ESM_APU_TREMOLO_RATE_SHIFT 12
-#define ESM_APU_TREMOLO_RATE_MASK (0xf << 12)
-
-/* reg 0x09 */
-/* bit 0-7 amplitude dest? */
-#define ESM_APU_AMPLITUDE_NOW_SHIFT 8
-#define ESM_APU_AMPLITUDE_NOW_MASK (0xff << 8)
-
-/* reg 0x0a */
-#define ESM_APU_POLAR_PAN_SHIFT 0
-#define ESM_APU_POLAR_PAN_MASK (0x3f << 0)
-/* Polar Pan Control */
-#define ESM_APU_PAN_CENTER_CIRCLE 0x00
-#define ESM_APU_PAN_MIDDLE_RADIUS 0x01
-#define ESM_APU_PAN_OUTSIDE_RADIUS 0x02
-
-#define ESM_APU_FILTER_TUNING_SHIFT 8
-#define ESM_APU_FILTER_TUNING_MASK (0xff << 8)
-
-/* reg 0x0b */
-#define ESM_APU_DATA_SRC_A_SHIFT 0
-#define ESM_APU_DATA_SRC_A_MASK (0x7f << 0)
-#define ESM_APU_INV_POL_A (1 << 7)
-#define ESM_APU_DATA_SRC_B_SHIFT 8
-#define ESM_APU_DATA_SRC_B_MASK (0x7f << 8)
-#define ESM_APU_INV_POL_B (1 << 15)
-
-#define ESM_APU_VIBRATO_RATE_SHIFT 0
-#define ESM_APU_VIBRATO_RATE_MASK (0xf << 0)
-#define ESM_APU_VIBRATO_DEPTH_SHIFT 4
-#define ESM_APU_VIBRATO_DEPTH_MASK (0xf << 4)
-#define ESM_APU_VIBRATO_PHASE_SHIFT 8
-#define ESM_APU_VIBRATO_PHASE_MASK (0xff << 8)
-
-/* reg 0x0c */
-#define ESM_APU_RADIUS_SELECT (1 << 6)
-
-/* APU Filter Control */
-#define ESM_APU_FILTER_2POLE_LOPASS 0x00
-#define ESM_APU_FILTER_2POLE_BANDPASS 0x01
-#define ESM_APU_FILTER_2POLE_HIPASS 0x02
-#define ESM_APU_FILTER_1POLE_LOPASS 0x03
-#define ESM_APU_FILTER_1POLE_HIPASS 0x04
-#define ESM_APU_FILTER_OFF 0x05
-
-/* APU ATFP Type */
-#define ESM_APU_ATFP_AMPLITUDE 0x00
-#define ESM_APU_ATFP_TREMELO 0x01
-#define ESM_APU_ATFP_FILTER 0x02
-#define ESM_APU_ATFP_PAN 0x03
-
-/* APU ATFP Flags */
-#define ESM_APU_ATFP_FLG_OFF 0x00
-#define ESM_APU_ATFP_FLG_WAIT 0x01
-#define ESM_APU_ATFP_FLG_DONE 0x02
-#define ESM_APU_ATFP_FLG_INPROCESS 0x03
-
-
-/* capture mixing buffer size */
-#define ESM_MEM_ALIGN 0x1000
-#define ESM_MIXBUF_SIZE 0x400
-
-#define ESM_MODE_PLAY 0
-#define ESM_MODE_CAPTURE 1
-
-
-/* APU use in the driver */
-enum snd_enum_apu_type {
- ESM_APU_PCM_PLAY,
- ESM_APU_PCM_CAPTURE,
- ESM_APU_PCM_RATECONV,
- ESM_APU_FREE
-};
-
-/* chip type */
-enum {
- TYPE_MAESTRO, TYPE_MAESTRO2, TYPE_MAESTRO2E
-};
-
-/* DMA Hack! */
-struct esm_memory {
- struct snd_dma_buffer buf;
- int empty; /* status */
- struct list_head list;
-};
-
-/* Playback Channel */
-struct esschan {
- int running;
-
- u8 apu[4];
- u8 apu_mode[4];
-
- /* playback/capture pcm buffer */
- struct esm_memory *memory;
- /* capture mixer buffer */
- struct esm_memory *mixbuf;
-
- unsigned int hwptr; /* current hw pointer in bytes */
- unsigned int count; /* sample counter in bytes */
- unsigned int dma_size; /* total buffer size in bytes */
- unsigned int frag_size; /* period size in bytes */
- unsigned int wav_shift;
- u16 base[4]; /* offset for ptr */
-
- /* stereo/16bit flag */
- unsigned char fmt;
- int mode; /* playback / capture */
-
- int bob_freq; /* required timer frequency */
-
- struct snd_pcm_substream *substream;
-
- /* linked list */
- struct list_head list;
-
-#ifdef CONFIG_PM
- u16 wc_map[4];
-#endif
-};
-
-struct es1968 {
- /* Module Config */
- int total_bufsize; /* in bytes */
-
- int playback_streams, capture_streams;
-
- unsigned int clock; /* clock */
- /* for clock measurement */
- unsigned int in_measurement: 1;
- unsigned int measure_apu;
- unsigned int measure_lastpos;
- unsigned int measure_count;
-
- /* buffer */
- struct snd_dma_buffer dma;
-
- /* Resources... */
- int irq;
- unsigned long io_port;
- int type;
- struct pci_dev *pci;
- struct snd_card *card;
- struct snd_pcm *pcm;
- int do_pm; /* power-management enabled */
-
- /* DMA memory block */
- struct list_head buf_list;
-
- /* ALSA Stuff */
- struct snd_ac97 *ac97;
- struct snd_rawmidi *rmidi;
-
- spinlock_t reg_lock;
- unsigned int in_suspend;
-
- /* Maestro Stuff */
- u16 maestro_map[32];
- int bobclient; /* active timer instancs */
- int bob_freq; /* timer frequency */
- struct mutex memory_mutex; /* memory lock */
-
- /* APU states */
- unsigned char apu[NR_APUS];
-
- /* active substreams */
- struct list_head substream_list;
- spinlock_t substream_lock;
-
-#ifdef CONFIG_PM
- u16 apu_map[NR_APUS][NR_APU_REGS];
-#endif
-
-#ifdef SUPPORT_JOYSTICK
- struct gameport *gameport;
-#endif
-
-#ifdef CONFIG_SND_ES1968_INPUT
- struct input_dev *input_dev;
- char phys[64]; /* physical device path */
-#else
- struct snd_kcontrol *master_switch; /* for h/w volume control */
- struct snd_kcontrol *master_volume;
-#endif
- struct work_struct hwvol_work;
-
-#ifdef CONFIG_SND_ES1968_RADIO
- struct v4l2_device v4l2_dev;
- struct snd_tea575x tea;
-#endif
-};
-
-static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id);
-
-static DEFINE_PCI_DEVICE_TABLE(snd_es1968_ids) = {
- /* Maestro 1 */
- { 0x1285, 0x0100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TYPE_MAESTRO },
- /* Maestro 2 */
- { 0x125d, 0x1968, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TYPE_MAESTRO2 },
- /* Maestro 2E */
- { 0x125d, 0x1978, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TYPE_MAESTRO2E },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_es1968_ids);
-
-/* *********************
- * Low Level Funcs! *
- *********************/
-
-/* no spinlock */
-static void __maestro_write(struct es1968 *chip, u16 reg, u16 data)
-{
- outw(reg, chip->io_port + ESM_INDEX);
- outw(data, chip->io_port + ESM_DATA);
- chip->maestro_map[reg] = data;
-}
-
-static inline void maestro_write(struct es1968 *chip, u16 reg, u16 data)
-{
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
- __maestro_write(chip, reg, data);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-
-/* no spinlock */
-static u16 __maestro_read(struct es1968 *chip, u16 reg)
-{
- if (READABLE_MAP & (1 << reg)) {
- outw(reg, chip->io_port + ESM_INDEX);
- chip->maestro_map[reg] = inw(chip->io_port + ESM_DATA);
- }
- return chip->maestro_map[reg];
-}
-
-static inline u16 maestro_read(struct es1968 *chip, u16 reg)
-{
- unsigned long flags;
- u16 result;
- spin_lock_irqsave(&chip->reg_lock, flags);
- result = __maestro_read(chip, reg);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return result;
-}
-
-/* Wait for the codec bus to be free */
-static int snd_es1968_ac97_wait(struct es1968 *chip)
-{
- int timeout = 100000;
-
- while (timeout-- > 0) {
- if (!(inb(chip->io_port + ESM_AC97_INDEX) & 1))
- return 0;
- cond_resched();
- }
- snd_printd("es1968: ac97 timeout\n");
- return 1; /* timeout */
-}
-
-static int snd_es1968_ac97_wait_poll(struct es1968 *chip)
-{
- int timeout = 100000;
-
- while (timeout-- > 0) {
- if (!(inb(chip->io_port + ESM_AC97_INDEX) & 1))
- return 0;
- }
- snd_printd("es1968: ac97 timeout\n");
- return 1; /* timeout */
-}
-
-static void snd_es1968_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
-{
- struct es1968 *chip = ac97->private_data;
-
- snd_es1968_ac97_wait(chip);
-
- /* Write the bus */
- outw(val, chip->io_port + ESM_AC97_DATA);
- /*msleep(1);*/
- outb(reg, chip->io_port + ESM_AC97_INDEX);
- /*msleep(1);*/
-}
-
-static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
-{
- u16 data = 0;
- struct es1968 *chip = ac97->private_data;
-
- snd_es1968_ac97_wait(chip);
-
- outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX);
- /*msleep(1);*/
-
- if (!snd_es1968_ac97_wait_poll(chip)) {
- data = inw(chip->io_port + ESM_AC97_DATA);
- /*msleep(1);*/
- }
-
- return data;
-}
-
-/* no spinlock */
-static void apu_index_set(struct es1968 *chip, u16 index)
-{
- int i;
- __maestro_write(chip, IDR1_CRAM_POINTER, index);
- for (i = 0; i < 1000; i++)
- if (__maestro_read(chip, IDR1_CRAM_POINTER) == index)
- return;
- snd_printd("es1968: APU register select failed. (Timeout)\n");
-}
-
-/* no spinlock */
-static void apu_data_set(struct es1968 *chip, u16 data)
-{
- int i;
- for (i = 0; i < 1000; i++) {
- if (__maestro_read(chip, IDR0_DATA_PORT) == data)
- return;
- __maestro_write(chip, IDR0_DATA_PORT, data);
- }
- snd_printd("es1968: APU register set probably failed (Timeout)!\n");
-}
-
-/* no spinlock */
-static void __apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data)
-{
- if (snd_BUG_ON(channel >= NR_APUS))
- return;
-#ifdef CONFIG_PM
- chip->apu_map[channel][reg] = data;
-#endif
- reg |= (channel << 4);
- apu_index_set(chip, reg);
- apu_data_set(chip, data);
-}
-
-static void apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data)
-{
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
- __apu_set_register(chip, channel, reg, data);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-
-static u16 __apu_get_register(struct es1968 *chip, u16 channel, u8 reg)
-{
- if (snd_BUG_ON(channel >= NR_APUS))
- return 0;
- reg |= (channel << 4);
- apu_index_set(chip, reg);
- return __maestro_read(chip, IDR0_DATA_PORT);
-}
-
-static u16 apu_get_register(struct es1968 *chip, u16 channel, u8 reg)
-{
- unsigned long flags;
- u16 v;
- spin_lock_irqsave(&chip->reg_lock, flags);
- v = __apu_get_register(chip, channel, reg);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return v;
-}
-
-#if 0 /* ASSP is not supported */
-
-static void assp_set_register(struct es1968 *chip, u32 reg, u32 value)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- outl(reg, chip->io_port + ASSP_INDEX);
- outl(value, chip->io_port + ASSP_DATA);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-
-static u32 assp_get_register(struct es1968 *chip, u32 reg)
-{
- unsigned long flags;
- u32 value;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- outl(reg, chip->io_port + ASSP_INDEX);
- value = inl(chip->io_port + ASSP_DATA);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- return value;
-}
-
-#endif
-
-static void wave_set_register(struct es1968 *chip, u16 reg, u16 value)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- outw(reg, chip->io_port + WC_INDEX);
- outw(value, chip->io_port + WC_DATA);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-
-static u16 wave_get_register(struct es1968 *chip, u16 reg)
-{
- unsigned long flags;
- u16 value;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- outw(reg, chip->io_port + WC_INDEX);
- value = inw(chip->io_port + WC_DATA);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- return value;
-}
-
-/* *******************
- * Bob the Timer! *
- *******************/
-
-static void snd_es1968_bob_stop(struct es1968 *chip)
-{
- u16 reg;
-
- reg = __maestro_read(chip, 0x11);
- reg &= ~ESM_BOB_ENABLE;
- __maestro_write(chip, 0x11, reg);
- reg = __maestro_read(chip, 0x17);
- reg &= ~ESM_BOB_START;
- __maestro_write(chip, 0x17, reg);
-}
-
-static void snd_es1968_bob_start(struct es1968 *chip)
-{
- int prescale;
- int divide;
-
- /* compute ideal interrupt frequency for buffer size & play rate */
- /* first, find best prescaler value to match freq */
- for (prescale = 5; prescale < 12; prescale++)
- if (chip->bob_freq > (ESS_SYSCLK >> (prescale + 9)))
- break;
-
- /* next, back off prescaler whilst getting divider into optimum range */
- divide = 1;
- while ((prescale > 5) && (divide < 32)) {
- prescale--;
- divide <<= 1;
- }
- divide >>= 1;
-
- /* now fine-tune the divider for best match */
- for (; divide < 31; divide++)
- if (chip->bob_freq >
- ((ESS_SYSCLK >> (prescale + 9)) / (divide + 1))) break;
-
- /* divide = 0 is illegal, but don't let prescale = 4! */
- if (divide == 0) {
- divide++;
- if (prescale > 5)
- prescale--;
- } else if (divide > 1)
- divide--;
-
- __maestro_write(chip, 6, 0x9000 | (prescale << 5) | divide); /* set reg */
-
- /* Now set IDR 11/17 */
- __maestro_write(chip, 0x11, __maestro_read(chip, 0x11) | 1);
- __maestro_write(chip, 0x17, __maestro_read(chip, 0x17) | 1);
-}
-
-/* call with substream spinlock */
-static void snd_es1968_bob_inc(struct es1968 *chip, int freq)
-{
- chip->bobclient++;
- if (chip->bobclient == 1) {
- chip->bob_freq = freq;
- snd_es1968_bob_start(chip);
- } else if (chip->bob_freq < freq) {
- snd_es1968_bob_stop(chip);
- chip->bob_freq = freq;
- snd_es1968_bob_start(chip);
- }
-}
-
-/* call with substream spinlock */
-static void snd_es1968_bob_dec(struct es1968 *chip)
-{
- chip->bobclient--;
- if (chip->bobclient <= 0)
- snd_es1968_bob_stop(chip);
- else if (chip->bob_freq > ESM_BOB_FREQ) {
- /* check reduction of timer frequency */
- int max_freq = ESM_BOB_FREQ;
- struct esschan *es;
- list_for_each_entry(es, &chip->substream_list, list) {
- if (max_freq < es->bob_freq)
- max_freq = es->bob_freq;
- }
- if (max_freq != chip->bob_freq) {
- snd_es1968_bob_stop(chip);
- chip->bob_freq = max_freq;
- snd_es1968_bob_start(chip);
- }
- }
-}
-
-static int
-snd_es1968_calc_bob_rate(struct es1968 *chip, struct esschan *es,
- struct snd_pcm_runtime *runtime)
-{
- /* we acquire 4 interrupts per period for precise control.. */
- int freq = runtime->rate * 4;
- if (es->fmt & ESS_FMT_STEREO)
- freq <<= 1;
- if (es->fmt & ESS_FMT_16BIT)
- freq <<= 1;
- freq /= es->frag_size;
- if (freq < ESM_BOB_FREQ)
- freq = ESM_BOB_FREQ;
- else if (freq > ESM_BOB_FREQ_MAX)
- freq = ESM_BOB_FREQ_MAX;
- return freq;
-}
-
-
-/*************
- * PCM Part *
- *************/
-
-static u32 snd_es1968_compute_rate(struct es1968 *chip, u32 freq)
-{
- u32 rate = (freq << 16) / chip->clock;
-#if 0 /* XXX: do we need this? */
- if (rate > 0x10000)
- rate = 0x10000;
-#endif
- return rate;
-}
-
-/* get current pointer */
-static inline unsigned int
-snd_es1968_get_dma_ptr(struct es1968 *chip, struct esschan *es)
-{
- unsigned int offset;
-
- offset = apu_get_register(chip, es->apu[0], 5);
-
- offset -= es->base[0];
-
- return (offset & 0xFFFE); /* hardware is in words */
-}
-
-static void snd_es1968_apu_set_freq(struct es1968 *chip, int apu, int freq)
-{
- apu_set_register(chip, apu, 2,
- (apu_get_register(chip, apu, 2) & 0x00FF) |
- ((freq & 0xff) << 8) | 0x10);
- apu_set_register(chip, apu, 3, freq >> 8);
-}
-
-/* spin lock held */
-static inline void snd_es1968_trigger_apu(struct es1968 *esm, int apu, int mode)
-{
- /* set the APU mode */
- __apu_set_register(esm, apu, 0,
- (__apu_get_register(esm, apu, 0) & 0xff0f) |
- (mode << 4));
-}
-
-static void snd_es1968_pcm_start(struct es1968 *chip, struct esschan *es)
-{
- spin_lock(&chip->reg_lock);
- __apu_set_register(chip, es->apu[0], 5, es->base[0]);
- snd_es1968_trigger_apu(chip, es->apu[0], es->apu_mode[0]);
- if (es->mode == ESM_MODE_CAPTURE) {
- __apu_set_register(chip, es->apu[2], 5, es->base[2]);
- snd_es1968_trigger_apu(chip, es->apu[2], es->apu_mode[2]);
- }
- if (es->fmt & ESS_FMT_STEREO) {
- __apu_set_register(chip, es->apu[1], 5, es->base[1]);
- snd_es1968_trigger_apu(chip, es->apu[1], es->apu_mode[1]);
- if (es->mode == ESM_MODE_CAPTURE) {
- __apu_set_register(chip, es->apu[3], 5, es->base[3]);
- snd_es1968_trigger_apu(chip, es->apu[3], es->apu_mode[3]);
- }
- }
- spin_unlock(&chip->reg_lock);
-}
-
-static void snd_es1968_pcm_stop(struct es1968 *chip, struct esschan *es)
-{
- spin_lock(&chip->reg_lock);
- snd_es1968_trigger_apu(chip, es->apu[0], 0);
- snd_es1968_trigger_apu(chip, es->apu[1], 0);
- if (es->mode == ESM_MODE_CAPTURE) {
- snd_es1968_trigger_apu(chip, es->apu[2], 0);
- snd_es1968_trigger_apu(chip, es->apu[3], 0);
- }
- spin_unlock(&chip->reg_lock);
-}
-
-/* set the wavecache control reg */
-static void snd_es1968_program_wavecache(struct es1968 *chip, struct esschan *es,
- int channel, u32 addr, int capture)
-{
- u32 tmpval = (addr - 0x10) & 0xFFF8;
-
- if (! capture) {
- if (!(es->fmt & ESS_FMT_16BIT))
- tmpval |= 4; /* 8bit */
- if (es->fmt & ESS_FMT_STEREO)
- tmpval |= 2; /* stereo */
- }
-
- /* set the wavecache control reg */
- wave_set_register(chip, es->apu[channel] << 3, tmpval);
-
-#ifdef CONFIG_PM
- es->wc_map[channel] = tmpval;
-#endif
-}
-
-
-static void snd_es1968_playback_setup(struct es1968 *chip, struct esschan *es,
- struct snd_pcm_runtime *runtime)
-{
- u32 pa;
- int high_apu = 0;
- int channel, apu;
- int i, size;
- unsigned long flags;
- u32 freq;
-
- size = es->dma_size >> es->wav_shift;
-
- if (es->fmt & ESS_FMT_STEREO)
- high_apu++;
-
- for (channel = 0; channel <= high_apu; channel++) {
- apu = es->apu[channel];
-
- snd_es1968_program_wavecache(chip, es, channel, es->memory->buf.addr, 0);
-
- /* Offset to PCMBAR */
- pa = es->memory->buf.addr;
- pa -= chip->dma.addr;
- pa >>= 1; /* words */
-
- pa |= 0x00400000; /* System RAM (Bit 22) */
-
- if (es->fmt & ESS_FMT_STEREO) {
- /* Enable stereo */
- if (channel)
- pa |= 0x00800000; /* (Bit 23) */
- if (es->fmt & ESS_FMT_16BIT)
- pa >>= 1;
- }
-
- /* base offset of dma calcs when reading the pointer
- on this left one */
- es->base[channel] = pa & 0xFFFF;
-
- for (i = 0; i < 16; i++)
- apu_set_register(chip, apu, i, 0x0000);
-
- /* Load the buffer into the wave engine */
- apu_set_register(chip, apu, 4, ((pa >> 16) & 0xFF) << 8);
- apu_set_register(chip, apu, 5, pa & 0xFFFF);
- apu_set_register(chip, apu, 6, (pa + size) & 0xFFFF);
- /* setting loop == sample len */
- apu_set_register(chip, apu, 7, size);
-
- /* clear effects/env.. */
- apu_set_register(chip, apu, 8, 0x0000);
- /* set amp now to 0xd0 (?), low byte is 'amplitude dest'? */
- apu_set_register(chip, apu, 9, 0xD000);
-
- /* clear routing stuff */
- apu_set_register(chip, apu, 11, 0x0000);
- /* dma on, no envelopes, filter to all 1s) */
- apu_set_register(chip, apu, 0, 0x400F);
-
- if (es->fmt & ESS_FMT_16BIT)
- es->apu_mode[channel] = ESM_APU_16BITLINEAR;
- else
- es->apu_mode[channel] = ESM_APU_8BITLINEAR;
-
- if (es->fmt & ESS_FMT_STEREO) {
- /* set panning: left or right */
- /* Check: different panning. On my Canyon 3D Chipset the
- Channels are swapped. I don't know, about the output
- to the SPDif Link. Perhaps you have to change this
- and not the APU Regs 4-5. */
- apu_set_register(chip, apu, 10,
- 0x8F00 | (channel ? 0 : 0x10));
- es->apu_mode[channel] += 1; /* stereo */
- } else
- apu_set_register(chip, apu, 10, 0x8F08);
- }
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- /* clear WP interrupts */
- outw(1, chip->io_port + 0x04);
- /* enable WP ints */
- outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- freq = runtime->rate;
- /* set frequency */
- if (freq > 48000)
- freq = 48000;
- if (freq < 4000)
- freq = 4000;
-
- /* hmmm.. */
- if (!(es->fmt & ESS_FMT_16BIT) && !(es->fmt & ESS_FMT_STEREO))
- freq >>= 1;
-
- freq = snd_es1968_compute_rate(chip, freq);
-
- /* Load the frequency, turn on 6dB */
- snd_es1968_apu_set_freq(chip, es->apu[0], freq);
- snd_es1968_apu_set_freq(chip, es->apu[1], freq);
-}
-
-
-static void init_capture_apu(struct es1968 *chip, struct esschan *es, int channel,
- unsigned int pa, unsigned int bsize,
- int mode, int route)
-{
- int i, apu = es->apu[channel];
-
- es->apu_mode[channel] = mode;
-
- /* set the wavecache control reg */
- snd_es1968_program_wavecache(chip, es, channel, pa, 1);
-
- /* Offset to PCMBAR */
- pa -= chip->dma.addr;
- pa >>= 1; /* words */
-
- /* base offset of dma calcs when reading the pointer
- on this left one */
- es->base[channel] = pa & 0xFFFF;
- pa |= 0x00400000; /* bit 22 -> System RAM */
-
- /* Begin loading the APU */
- for (i = 0; i < 16; i++)
- apu_set_register(chip, apu, i, 0x0000);
-
- /* need to enable subgroups.. and we should probably
- have different groups for different /dev/dsps.. */
- apu_set_register(chip, apu, 2, 0x8);
-
- /* Load the buffer into the wave engine */
- apu_set_register(chip, apu, 4, ((pa >> 16) & 0xFF) << 8);
- apu_set_register(chip, apu, 5, pa & 0xFFFF);
- apu_set_register(chip, apu, 6, (pa + bsize) & 0xFFFF);
- apu_set_register(chip, apu, 7, bsize);
- /* clear effects/env.. */
- apu_set_register(chip, apu, 8, 0x00F0);
- /* amplitude now? sure. why not. */
- apu_set_register(chip, apu, 9, 0x0000);
- /* set filter tune, radius, polar pan */
- apu_set_register(chip, apu, 10, 0x8F08);
- /* route input */
- apu_set_register(chip, apu, 11, route);
- /* dma on, no envelopes, filter to all 1s) */
- apu_set_register(chip, apu, 0, 0x400F);
-}
-
-static void snd_es1968_capture_setup(struct es1968 *chip, struct esschan *es,
- struct snd_pcm_runtime *runtime)
-{
- int size;
- u32 freq;
- unsigned long flags;
-
- size = es->dma_size >> es->wav_shift;
-
- /* APU assignments:
- 0 = mono/left SRC
- 1 = right SRC
- 2 = mono/left Input Mixer
- 3 = right Input Mixer
- */
- /* data seems to flow from the codec, through an apu into
- the 'mixbuf' bit of page, then through the SRC apu
- and out to the real 'buffer'. ok. sure. */
-
- /* input mixer (left/mono) */
- /* parallel in crap, see maestro reg 0xC [8-11] */
- init_capture_apu(chip, es, 2,
- es->mixbuf->buf.addr, ESM_MIXBUF_SIZE/4, /* in words */
- ESM_APU_INPUTMIXER, 0x14);
- /* SRC (left/mono); get input from inputing apu */
- init_capture_apu(chip, es, 0, es->memory->buf.addr, size,
- ESM_APU_SRCONVERTOR, es->apu[2]);
- if (es->fmt & ESS_FMT_STEREO) {
- /* input mixer (right) */
- init_capture_apu(chip, es, 3,
- es->mixbuf->buf.addr + ESM_MIXBUF_SIZE/2,
- ESM_MIXBUF_SIZE/4, /* in words */
- ESM_APU_INPUTMIXER, 0x15);
- /* SRC (right) */
- init_capture_apu(chip, es, 1,
- es->memory->buf.addr + size*2, size,
- ESM_APU_SRCONVERTOR, es->apu[3]);
- }
-
- freq = runtime->rate;
- /* Sample Rate conversion APUs don't like 0x10000 for their rate */
- if (freq > 47999)
- freq = 47999;
- if (freq < 4000)
- freq = 4000;
-
- freq = snd_es1968_compute_rate(chip, freq);
-
- /* Load the frequency, turn on 6dB */
- snd_es1968_apu_set_freq(chip, es->apu[0], freq);
- snd_es1968_apu_set_freq(chip, es->apu[1], freq);
-
- /* fix mixer rate at 48khz. and its _must_ be 0x10000. */
- freq = 0x10000;
- snd_es1968_apu_set_freq(chip, es->apu[2], freq);
- snd_es1968_apu_set_freq(chip, es->apu[3], freq);
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- /* clear WP interrupts */
- outw(1, chip->io_port + 0x04);
- /* enable WP ints */
- outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-
-/*******************
- * ALSA Interface *
- *******************/
-
-static int snd_es1968_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct es1968 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct esschan *es = runtime->private_data;
-
- es->dma_size = snd_pcm_lib_buffer_bytes(substream);
- es->frag_size = snd_pcm_lib_period_bytes(substream);
-
- es->wav_shift = 1; /* maestro handles always 16bit */
- es->fmt = 0;
- if (snd_pcm_format_width(runtime->format) == 16)
- es->fmt |= ESS_FMT_16BIT;
- if (runtime->channels > 1) {
- es->fmt |= ESS_FMT_STEREO;
- if (es->fmt & ESS_FMT_16BIT) /* 8bit is already word shifted */
- es->wav_shift++;
- }
- es->bob_freq = snd_es1968_calc_bob_rate(chip, es, runtime);
-
- switch (es->mode) {
- case ESM_MODE_PLAY:
- snd_es1968_playback_setup(chip, es, runtime);
- break;
- case ESM_MODE_CAPTURE:
- snd_es1968_capture_setup(chip, es, runtime);
- break;
- }
-
- return 0;
-}
-
-static int snd_es1968_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct es1968 *chip = snd_pcm_substream_chip(substream);
- struct esschan *es = substream->runtime->private_data;
-
- spin_lock(&chip->substream_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- if (es->running)
- break;
- snd_es1968_bob_inc(chip, es->bob_freq);
- es->count = 0;
- es->hwptr = 0;
- snd_es1968_pcm_start(chip, es);
- es->running = 1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- if (! es->running)
- break;
- snd_es1968_pcm_stop(chip, es);
- es->running = 0;
- snd_es1968_bob_dec(chip);
- break;
- }
- spin_unlock(&chip->substream_lock);
- return 0;
-}
-
-static snd_pcm_uframes_t snd_es1968_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct es1968 *chip = snd_pcm_substream_chip(substream);
- struct esschan *es = substream->runtime->private_data;
- unsigned int ptr;
-
- ptr = snd_es1968_get_dma_ptr(chip, es) << es->wav_shift;
-
- return bytes_to_frames(substream->runtime, ptr % es->dma_size);
-}
-
-static struct snd_pcm_hardware snd_es1968_playback = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- /*SNDRV_PCM_INFO_PAUSE |*/
- SNDRV_PCM_INFO_RESUME),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 65536,
- .period_bytes_min = 256,
- .period_bytes_max = 65536,
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_es1968_capture = {
- .info = (SNDRV_PCM_INFO_NONINTERLEAVED |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- /*SNDRV_PCM_INFO_PAUSE |*/
- SNDRV_PCM_INFO_RESUME),
- .formats = /*SNDRV_PCM_FMTBIT_U8 |*/ SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 65536,
- .period_bytes_min = 256,
- .period_bytes_max = 65536,
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-/* *************************
- * DMA memory management *
- *************************/
-
-/* Because the Maestro can only take addresses relative to the PCM base address
- register :( */
-
-static int calc_available_memory_size(struct es1968 *chip)
-{
- int max_size = 0;
- struct esm_memory *buf;
-
- mutex_lock(&chip->memory_mutex);
- list_for_each_entry(buf, &chip->buf_list, list) {
- if (buf->empty && buf->buf.bytes > max_size)
- max_size = buf->buf.bytes;
- }
- mutex_unlock(&chip->memory_mutex);
- if (max_size >= 128*1024)
- max_size = 127*1024;
- return max_size;
-}
-
-/* allocate a new memory chunk with the specified size */
-static struct esm_memory *snd_es1968_new_memory(struct es1968 *chip, int size)
-{
- struct esm_memory *buf;
-
- size = ALIGN(size, ESM_MEM_ALIGN);
- mutex_lock(&chip->memory_mutex);
- list_for_each_entry(buf, &chip->buf_list, list) {
- if (buf->empty && buf->buf.bytes >= size)
- goto __found;
- }
- mutex_unlock(&chip->memory_mutex);
- return NULL;
-
-__found:
- if (buf->buf.bytes > size) {
- struct esm_memory *chunk = kmalloc(sizeof(*chunk), GFP_KERNEL);
- if (chunk == NULL) {
- mutex_unlock(&chip->memory_mutex);
- return NULL;
- }
- chunk->buf = buf->buf;
- chunk->buf.bytes -= size;
- chunk->buf.area += size;
- chunk->buf.addr += size;
- chunk->empty = 1;
- buf->buf.bytes = size;
- list_add(&chunk->list, &buf->list);
- }
- buf->empty = 0;
- mutex_unlock(&chip->memory_mutex);
- return buf;
-}
-
-/* free a memory chunk */
-static void snd_es1968_free_memory(struct es1968 *chip, struct esm_memory *buf)
-{
- struct esm_memory *chunk;
-
- mutex_lock(&chip->memory_mutex);
- buf->empty = 1;
- if (buf->list.prev != &chip->buf_list) {
- chunk = list_entry(buf->list.prev, struct esm_memory, list);
- if (chunk->empty) {
- chunk->buf.bytes += buf->buf.bytes;
- list_del(&buf->list);
- kfree(buf);
- buf = chunk;
- }
- }
- if (buf->list.next != &chip->buf_list) {
- chunk = list_entry(buf->list.next, struct esm_memory, list);
- if (chunk->empty) {
- buf->buf.bytes += chunk->buf.bytes;
- list_del(&chunk->list);
- kfree(chunk);
- }
- }
- mutex_unlock(&chip->memory_mutex);
-}
-
-static void snd_es1968_free_dmabuf(struct es1968 *chip)
-{
- struct list_head *p;
-
- if (! chip->dma.area)
- return;
- snd_dma_reserve_buf(&chip->dma, snd_dma_pci_buf_id(chip->pci));
- while ((p = chip->buf_list.next) != &chip->buf_list) {
- struct esm_memory *chunk = list_entry(p, struct esm_memory, list);
- list_del(p);
- kfree(chunk);
- }
-}
-
-static int __devinit
-snd_es1968_init_dmabuf(struct es1968 *chip)
-{
- int err;
- struct esm_memory *chunk;
-
- chip->dma.dev.type = SNDRV_DMA_TYPE_DEV;
- chip->dma.dev.dev = snd_dma_pci_data(chip->pci);
- if (! snd_dma_get_reserved_buf(&chip->dma, snd_dma_pci_buf_id(chip->pci))) {
- err = snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- chip->total_bufsize, &chip->dma);
- if (err < 0 || ! chip->dma.area) {
- snd_printk(KERN_ERR "es1968: can't allocate dma pages for size %d\n",
- chip->total_bufsize);
- return -ENOMEM;
- }
- if ((chip->dma.addr + chip->dma.bytes - 1) & ~((1 << 28) - 1)) {
- snd_dma_free_pages(&chip->dma);
- snd_printk(KERN_ERR "es1968: DMA buffer beyond 256MB.\n");
- return -ENOMEM;
- }
- }
-
- INIT_LIST_HEAD(&chip->buf_list);
- /* allocate an empty chunk */
- chunk = kmalloc(sizeof(*chunk), GFP_KERNEL);
- if (chunk == NULL) {
- snd_es1968_free_dmabuf(chip);
- return -ENOMEM;
- }
- memset(chip->dma.area, 0, ESM_MEM_ALIGN);
- chunk->buf = chip->dma;
- chunk->buf.area += ESM_MEM_ALIGN;
- chunk->buf.addr += ESM_MEM_ALIGN;
- chunk->buf.bytes -= ESM_MEM_ALIGN;
- chunk->empty = 1;
- list_add(&chunk->list, &chip->buf_list);
-
- return 0;
-}
-
-/* setup the dma_areas */
-/* buffer is extracted from the pre-allocated memory chunk */
-static int snd_es1968_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct es1968 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct esschan *chan = runtime->private_data;
- int size = params_buffer_bytes(hw_params);
-
- if (chan->memory) {
- if (chan->memory->buf.bytes >= size) {
- runtime->dma_bytes = size;
- return 0;
- }
- snd_es1968_free_memory(chip, chan->memory);
- }
- chan->memory = snd_es1968_new_memory(chip, size);
- if (chan->memory == NULL) {
- // snd_printd("cannot allocate dma buffer: size = %d\n", size);
- return -ENOMEM;
- }
- snd_pcm_set_runtime_buffer(substream, &chan->memory->buf);
- return 1; /* area was changed */
-}
-
-/* remove dma areas if allocated */
-static int snd_es1968_hw_free(struct snd_pcm_substream *substream)
-{
- struct es1968 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct esschan *chan;
-
- if (runtime->private_data == NULL)
- return 0;
- chan = runtime->private_data;
- if (chan->memory) {
- snd_es1968_free_memory(chip, chan->memory);
- chan->memory = NULL;
- }
- return 0;
-}
-
-
-/*
- * allocate APU pair
- */
-static int snd_es1968_alloc_apu_pair(struct es1968 *chip, int type)
-{
- int apu;
-
- for (apu = 0; apu < NR_APUS; apu += 2) {
- if (chip->apu[apu] == ESM_APU_FREE &&
- chip->apu[apu + 1] == ESM_APU_FREE) {
- chip->apu[apu] = chip->apu[apu + 1] = type;
- return apu;
- }
- }
- return -EBUSY;
-}
-
-/*
- * release APU pair
- */
-static void snd_es1968_free_apu_pair(struct es1968 *chip, int apu)
-{
- chip->apu[apu] = chip->apu[apu + 1] = ESM_APU_FREE;
-}
-
-
-/******************
- * PCM open/close *
- ******************/
-
-static int snd_es1968_playback_open(struct snd_pcm_substream *substream)
-{
- struct es1968 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct esschan *es;
- int apu1;
-
- /* search 2 APUs */
- apu1 = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_PLAY);
- if (apu1 < 0)
- return apu1;
-
- es = kzalloc(sizeof(*es), GFP_KERNEL);
- if (!es) {
- snd_es1968_free_apu_pair(chip, apu1);
- return -ENOMEM;
- }
-
- es->apu[0] = apu1;
- es->apu[1] = apu1 + 1;
- es->apu_mode[0] = 0;
- es->apu_mode[1] = 0;
- es->running = 0;
- es->substream = substream;
- es->mode = ESM_MODE_PLAY;
-
- runtime->private_data = es;
- runtime->hw = snd_es1968_playback;
- runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max =
- calc_available_memory_size(chip);
-
- spin_lock_irq(&chip->substream_lock);
- list_add(&es->list, &chip->substream_list);
- spin_unlock_irq(&chip->substream_lock);
-
- return 0;
-}
-
-static int snd_es1968_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct es1968 *chip = snd_pcm_substream_chip(substream);
- struct esschan *es;
- int apu1, apu2;
-
- apu1 = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_CAPTURE);
- if (apu1 < 0)
- return apu1;
- apu2 = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_RATECONV);
- if (apu2 < 0) {
- snd_es1968_free_apu_pair(chip, apu1);
- return apu2;
- }
-
- es = kzalloc(sizeof(*es), GFP_KERNEL);
- if (!es) {
- snd_es1968_free_apu_pair(chip, apu1);
- snd_es1968_free_apu_pair(chip, apu2);
- return -ENOMEM;
- }
-
- es->apu[0] = apu1;
- es->apu[1] = apu1 + 1;
- es->apu[2] = apu2;
- es->apu[3] = apu2 + 1;
- es->apu_mode[0] = 0;
- es->apu_mode[1] = 0;
- es->apu_mode[2] = 0;
- es->apu_mode[3] = 0;
- es->running = 0;
- es->substream = substream;
- es->mode = ESM_MODE_CAPTURE;
-
- /* get mixbuffer */
- if ((es->mixbuf = snd_es1968_new_memory(chip, ESM_MIXBUF_SIZE)) == NULL) {
- snd_es1968_free_apu_pair(chip, apu1);
- snd_es1968_free_apu_pair(chip, apu2);
- kfree(es);
- return -ENOMEM;
- }
- memset(es->mixbuf->buf.area, 0, ESM_MIXBUF_SIZE);
-
- runtime->private_data = es;
- runtime->hw = snd_es1968_capture;
- runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max =
- calc_available_memory_size(chip) - 1024; /* keep MIXBUF size */
- snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
-
- spin_lock_irq(&chip->substream_lock);
- list_add(&es->list, &chip->substream_list);
- spin_unlock_irq(&chip->substream_lock);
-
- return 0;
-}
-
-static int snd_es1968_playback_close(struct snd_pcm_substream *substream)
-{
- struct es1968 *chip = snd_pcm_substream_chip(substream);
- struct esschan *es;
-
- if (substream->runtime->private_data == NULL)
- return 0;
- es = substream->runtime->private_data;
- spin_lock_irq(&chip->substream_lock);
- list_del(&es->list);
- spin_unlock_irq(&chip->substream_lock);
- snd_es1968_free_apu_pair(chip, es->apu[0]);
- kfree(es);
-
- return 0;
-}
-
-static int snd_es1968_capture_close(struct snd_pcm_substream *substream)
-{
- struct es1968 *chip = snd_pcm_substream_chip(substream);
- struct esschan *es;
-
- if (substream->runtime->private_data == NULL)
- return 0;
- es = substream->runtime->private_data;
- spin_lock_irq(&chip->substream_lock);
- list_del(&es->list);
- spin_unlock_irq(&chip->substream_lock);
- snd_es1968_free_memory(chip, es->mixbuf);
- snd_es1968_free_apu_pair(chip, es->apu[0]);
- snd_es1968_free_apu_pair(chip, es->apu[2]);
- kfree(es);
-
- return 0;
-}
-
-static struct snd_pcm_ops snd_es1968_playback_ops = {
- .open = snd_es1968_playback_open,
- .close = snd_es1968_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_es1968_hw_params,
- .hw_free = snd_es1968_hw_free,
- .prepare = snd_es1968_pcm_prepare,
- .trigger = snd_es1968_pcm_trigger,
- .pointer = snd_es1968_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_es1968_capture_ops = {
- .open = snd_es1968_capture_open,
- .close = snd_es1968_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_es1968_hw_params,
- .hw_free = snd_es1968_hw_free,
- .prepare = snd_es1968_pcm_prepare,
- .trigger = snd_es1968_pcm_trigger,
- .pointer = snd_es1968_pcm_pointer,
-};
-
-
-/*
- * measure clock
- */
-#define CLOCK_MEASURE_BUFSIZE 16768 /* enough large for a single shot */
-
-static void __devinit es1968_measure_clock(struct es1968 *chip)
-{
- int i, apu;
- unsigned int pa, offset, t;
- struct esm_memory *memory;
- struct timeval start_time, stop_time;
-
- if (chip->clock == 0)
- chip->clock = 48000; /* default clock value */
-
- /* search 2 APUs (although one apu is enough) */
- if ((apu = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_PLAY)) < 0) {
- snd_printk(KERN_ERR "Hmm, cannot find empty APU pair!?\n");
- return;
- }
- if ((memory = snd_es1968_new_memory(chip, CLOCK_MEASURE_BUFSIZE)) == NULL) {
- snd_printk(KERN_ERR "cannot allocate dma buffer - using default clock %d\n", chip->clock);
- snd_es1968_free_apu_pair(chip, apu);
- return;
- }
-
- memset(memory->buf.area, 0, CLOCK_MEASURE_BUFSIZE);
-
- wave_set_register(chip, apu << 3, (memory->buf.addr - 0x10) & 0xfff8);
-
- pa = (unsigned int)((memory->buf.addr - chip->dma.addr) >> 1);
- pa |= 0x00400000; /* System RAM (Bit 22) */
-
- /* initialize apu */
- for (i = 0; i < 16; i++)
- apu_set_register(chip, apu, i, 0x0000);
-
- apu_set_register(chip, apu, 0, 0x400f);
- apu_set_register(chip, apu, 4, ((pa >> 16) & 0xff) << 8);
- apu_set_register(chip, apu, 5, pa & 0xffff);
- apu_set_register(chip, apu, 6, (pa + CLOCK_MEASURE_BUFSIZE/2) & 0xffff);
- apu_set_register(chip, apu, 7, CLOCK_MEASURE_BUFSIZE/2);
- apu_set_register(chip, apu, 8, 0x0000);
- apu_set_register(chip, apu, 9, 0xD000);
- apu_set_register(chip, apu, 10, 0x8F08);
- apu_set_register(chip, apu, 11, 0x0000);
- spin_lock_irq(&chip->reg_lock);
- outw(1, chip->io_port + 0x04); /* clear WP interrupts */
- outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ); /* enable WP ints */
- spin_unlock_irq(&chip->reg_lock);
-
- snd_es1968_apu_set_freq(chip, apu, ((unsigned int)48000 << 16) / chip->clock); /* 48000 Hz */
-
- chip->in_measurement = 1;
- chip->measure_apu = apu;
- spin_lock_irq(&chip->reg_lock);
- snd_es1968_bob_inc(chip, ESM_BOB_FREQ);
- __apu_set_register(chip, apu, 5, pa & 0xffff);
- snd_es1968_trigger_apu(chip, apu, ESM_APU_16BITLINEAR);
- do_gettimeofday(&start_time);
- spin_unlock_irq(&chip->reg_lock);
- msleep(50);
- spin_lock_irq(&chip->reg_lock);
- offset = __apu_get_register(chip, apu, 5);
- do_gettimeofday(&stop_time);
- snd_es1968_trigger_apu(chip, apu, 0); /* stop */
- snd_es1968_bob_dec(chip);
- chip->in_measurement = 0;
- spin_unlock_irq(&chip->reg_lock);
-
- /* check the current position */
- offset -= (pa & 0xffff);
- offset &= 0xfffe;
- offset += chip->measure_count * (CLOCK_MEASURE_BUFSIZE/2);
-
- t = stop_time.tv_sec - start_time.tv_sec;
- t *= 1000000;
- if (stop_time.tv_usec < start_time.tv_usec)
- t -= start_time.tv_usec - stop_time.tv_usec;
- else
- t += stop_time.tv_usec - start_time.tv_usec;
- if (t == 0) {
- snd_printk(KERN_ERR "?? calculation error..\n");
- } else {
- offset *= 1000;
- offset = (offset / t) * 1000 + ((offset % t) * 1000) / t;
- if (offset < 47500 || offset > 48500) {
- if (offset >= 40000 && offset <= 50000)
- chip->clock = (chip->clock * offset) / 48000;
- }
- printk(KERN_INFO "es1968: clocking to %d\n", chip->clock);
- }
- snd_es1968_free_memory(chip, memory);
- snd_es1968_free_apu_pair(chip, apu);
-}
-
-
-/*
- */
-
-static void snd_es1968_pcm_free(struct snd_pcm *pcm)
-{
- struct es1968 *esm = pcm->private_data;
- snd_es1968_free_dmabuf(esm);
- esm->pcm = NULL;
-}
-
-static int __devinit
-snd_es1968_pcm(struct es1968 *chip, int device)
-{
- struct snd_pcm *pcm;
- int err;
-
- /* get DMA buffer */
- if ((err = snd_es1968_init_dmabuf(chip)) < 0)
- return err;
-
- /* set PCMBAR */
- wave_set_register(chip, 0x01FC, chip->dma.addr >> 12);
- wave_set_register(chip, 0x01FD, chip->dma.addr >> 12);
- wave_set_register(chip, 0x01FE, chip->dma.addr >> 12);
- wave_set_register(chip, 0x01FF, chip->dma.addr >> 12);
-
- if ((err = snd_pcm_new(chip->card, "ESS Maestro", device,
- chip->playback_streams,
- chip->capture_streams, &pcm)) < 0)
- return err;
-
- pcm->private_data = chip;
- pcm->private_free = snd_es1968_pcm_free;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1968_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_es1968_capture_ops);
-
- pcm->info_flags = 0;
-
- strcpy(pcm->name, "ESS Maestro");
-
- chip->pcm = pcm;
-
- return 0;
-}
-/*
- * suppress jitter on some maestros when playing stereo
- */
-static void snd_es1968_suppress_jitter(struct es1968 *chip, struct esschan *es)
-{
- unsigned int cp1;
- unsigned int cp2;
- unsigned int diff;
-
- cp1 = __apu_get_register(chip, 0, 5);
- cp2 = __apu_get_register(chip, 1, 5);
- diff = (cp1 > cp2 ? cp1 - cp2 : cp2 - cp1);
-
- if (diff > 1)
- __maestro_write(chip, IDR0_DATA_PORT, cp1);
-}
-
-/*
- * update pointer
- */
-static void snd_es1968_update_pcm(struct es1968 *chip, struct esschan *es)
-{
- unsigned int hwptr;
- unsigned int diff;
- struct snd_pcm_substream *subs = es->substream;
-
- if (subs == NULL || !es->running)
- return;
-
- hwptr = snd_es1968_get_dma_ptr(chip, es) << es->wav_shift;
- hwptr %= es->dma_size;
-
- diff = (es->dma_size + hwptr - es->hwptr) % es->dma_size;
-
- es->hwptr = hwptr;
- es->count += diff;
-
- if (es->count > es->frag_size) {
- spin_unlock(&chip->substream_lock);
- snd_pcm_period_elapsed(subs);
- spin_lock(&chip->substream_lock);
- es->count %= es->frag_size;
- }
-}
-
-/* The hardware volume works by incrementing / decrementing 2 counters
- (without wrap around) in response to volume button presses and then
- generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7
- of a byte wide register. The meaning of bits 0 and 4 is unknown. */
-static void es1968_update_hw_volume(struct work_struct *work)
-{
- struct es1968 *chip = container_of(work, struct es1968, hwvol_work);
- int x, val;
-
- /* Figure out which volume control button was pushed,
- based on differences from the default register
- values. */
- x = inb(chip->io_port + 0x1c) & 0xee;
- /* Reset the volume control registers. */
- outb(0x88, chip->io_port + 0x1c);
- outb(0x88, chip->io_port + 0x1d);
- outb(0x88, chip->io_port + 0x1e);
- outb(0x88, chip->io_port + 0x1f);
-
- if (chip->in_suspend)
- return;
-
-#ifndef CONFIG_SND_ES1968_INPUT
- if (! chip->master_switch || ! chip->master_volume)
- return;
-
- val = snd_ac97_read(chip->ac97, AC97_MASTER);
- switch (x) {
- case 0x88:
- /* mute */
- val ^= 0x8000;
- break;
- case 0xaa:
- /* volume up */
- if ((val & 0x7f) > 0)
- val--;
- if ((val & 0x7f00) > 0)
- val -= 0x0100;
- break;
- case 0x66:
- /* volume down */
- if ((val & 0x7f) < 0x1f)
- val++;
- if ((val & 0x7f00) < 0x1f00)
- val += 0x0100;
- break;
- }
- if (snd_ac97_update(chip->ac97, AC97_MASTER, val))
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->master_volume->id);
-#else
- if (!chip->input_dev)
- return;
-
- val = 0;
- switch (x) {
- case 0x88:
- /* The counters have not changed, yet we've received a HV
- interrupt. According to tests run by various people this
- happens when pressing the mute button. */
- val = KEY_MUTE;
- break;
- case 0xaa:
- /* counters increased by 1 -> volume up */
- val = KEY_VOLUMEUP;
- break;
- case 0x66:
- /* counters decreased by 1 -> volume down */
- val = KEY_VOLUMEDOWN;
- break;
- }
-
- if (val) {
- input_report_key(chip->input_dev, val, 1);
- input_sync(chip->input_dev);
- input_report_key(chip->input_dev, val, 0);
- input_sync(chip->input_dev);
- }
-#endif
-}
-
-/*
- * interrupt handler
- */
-static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
-{
- struct es1968 *chip = dev_id;
- u32 event;
-
- if (!(event = inb(chip->io_port + 0x1A)))
- return IRQ_NONE;
-
- outw(inw(chip->io_port + 4) & 1, chip->io_port + 4);
-
- if (event & ESM_HWVOL_IRQ)
- schedule_work(&chip->hwvol_work);
-
- /* else ack 'em all, i imagine */
- outb(0xFF, chip->io_port + 0x1A);
-
- if ((event & ESM_MPU401_IRQ) && chip->rmidi) {
- snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
- }
-
- if (event & ESM_SOUND_IRQ) {
- struct esschan *es;
- spin_lock(&chip->substream_lock);
- list_for_each_entry(es, &chip->substream_list, list) {
- if (es->running) {
- snd_es1968_update_pcm(chip, es);
- if (es->fmt & ESS_FMT_STEREO)
- snd_es1968_suppress_jitter(chip, es);
- }
- }
- spin_unlock(&chip->substream_lock);
- if (chip->in_measurement) {
- unsigned int curp = __apu_get_register(chip, chip->measure_apu, 5);
- if (curp < chip->measure_lastpos)
- chip->measure_count++;
- chip->measure_lastpos = curp;
- }
- }
-
- return IRQ_HANDLED;
-}
-
-/*
- * Mixer stuff
- */
-
-static int __devinit
-snd_es1968_mixer(struct es1968 *chip)
-{
- struct snd_ac97_bus *pbus;
- struct snd_ac97_template ac97;
-#ifndef CONFIG_SND_ES1968_INPUT
- struct snd_ctl_elem_id elem_id;
-#endif
- int err;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_es1968_ac97_write,
- .read = snd_es1968_ac97_read,
- };
-
- if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
- return err;
- pbus->no_vra = 1; /* ES1968 doesn't need VRA */
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = chip;
- if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0)
- return err;
-
-#ifndef CONFIG_SND_ES1968_INPUT
- /* attach master switch / volumes for h/w volume control */
- memset(&elem_id, 0, sizeof(elem_id));
- elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(elem_id.name, "Master Playback Switch");
- chip->master_switch = snd_ctl_find_id(chip->card, &elem_id);
- memset(&elem_id, 0, sizeof(elem_id));
- elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(elem_id.name, "Master Playback Volume");
- chip->master_volume = snd_ctl_find_id(chip->card, &elem_id);
-#endif
-
- return 0;
-}
-
-/*
- * reset ac97 codec
- */
-
-static void snd_es1968_ac97_reset(struct es1968 *chip)
-{
- unsigned long ioaddr = chip->io_port;
-
- unsigned short save_ringbus_a;
- unsigned short save_68;
- unsigned short w;
- unsigned int vend;
-
- /* save configuration */
- save_ringbus_a = inw(ioaddr + 0x36);
-
- //outw(inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38); /* clear second codec id? */
- /* set command/status address i/o to 1st codec */
- outw(inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a);
- outw(inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
-
- /* disable ac link */
- outw(0x0000, ioaddr + 0x36);
- save_68 = inw(ioaddr + 0x68);
- pci_read_config_word(chip->pci, 0x58, &w); /* something magical with gpio and bus arb. */
- pci_read_config_dword(chip->pci, PCI_SUBSYSTEM_VENDOR_ID, &vend);
- if (w & 1)
- save_68 |= 0x10;
- outw(0xfffe, ioaddr + 0x64); /* unmask gpio 0 */
- outw(0x0001, ioaddr + 0x68); /* gpio write */
- outw(0x0000, ioaddr + 0x60); /* write 0 to gpio 0 */
- udelay(20);
- outw(0x0001, ioaddr + 0x60); /* write 1 to gpio 1 */
- msleep(20);
-
- outw(save_68 | 0x1, ioaddr + 0x68); /* now restore .. */
- outw((inw(ioaddr + 0x38) & 0xfffc) | 0x1, ioaddr + 0x38);
- outw((inw(ioaddr + 0x3a) & 0xfffc) | 0x1, ioaddr + 0x3a);
- outw((inw(ioaddr + 0x3c) & 0xfffc) | 0x1, ioaddr + 0x3c);
-
- /* now the second codec */
- /* disable ac link */
- outw(0x0000, ioaddr + 0x36);
- outw(0xfff7, ioaddr + 0x64); /* unmask gpio 3 */
- save_68 = inw(ioaddr + 0x68);
- outw(0x0009, ioaddr + 0x68); /* gpio write 0 & 3 ?? */
- outw(0x0001, ioaddr + 0x60); /* write 1 to gpio */
- udelay(20);
- outw(0x0009, ioaddr + 0x60); /* write 9 to gpio */
- msleep(500);
- //outw(inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38);
- outw(inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a);
- outw(inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
-
-#if 0 /* the loop here needs to be much better if we want it.. */
- snd_printk(KERN_INFO "trying software reset\n");
- /* try and do a software reset */
- outb(0x80 | 0x7c, ioaddr + 0x30);
- for (w = 0;; w++) {
- if ((inw(ioaddr + 0x30) & 1) == 0) {
- if (inb(ioaddr + 0x32) != 0)
- break;
-
- outb(0x80 | 0x7d, ioaddr + 0x30);
- if (((inw(ioaddr + 0x30) & 1) == 0)
- && (inb(ioaddr + 0x32) != 0))
- break;
- outb(0x80 | 0x7f, ioaddr + 0x30);
- if (((inw(ioaddr + 0x30) & 1) == 0)
- && (inb(ioaddr + 0x32) != 0))
- break;
- }
-
- if (w > 10000) {
- outb(inb(ioaddr + 0x37) | 0x08, ioaddr + 0x37); /* do a software reset */
- msleep(500); /* oh my.. */
- outb(inb(ioaddr + 0x37) & ~0x08,
- ioaddr + 0x37);
- udelay(1);
- outw(0x80, ioaddr + 0x30);
- for (w = 0; w < 10000; w++) {
- if ((inw(ioaddr + 0x30) & 1) == 0)
- break;
- }
- }
- }
-#endif
- if (vend == NEC_VERSA_SUBID1 || vend == NEC_VERSA_SUBID2) {
- /* turn on external amp? */
- outw(0xf9ff, ioaddr + 0x64);
- outw(inw(ioaddr + 0x68) | 0x600, ioaddr + 0x68);
- outw(0x0209, ioaddr + 0x60);
- }
-
- /* restore.. */
- outw(save_ringbus_a, ioaddr + 0x36);
-
- /* Turn on the 978 docking chip.
- First frob the "master output enable" bit,
- then set most of the playback volume control registers to max. */
- outb(inb(ioaddr+0xc0)|(1<<5), ioaddr+0xc0);
- outb(0xff, ioaddr+0xc3);
- outb(0xff, ioaddr+0xc4);
- outb(0xff, ioaddr+0xc6);
- outb(0xff, ioaddr+0xc8);
- outb(0x3f, ioaddr+0xcf);
- outb(0x3f, ioaddr+0xd0);
-}
-
-static void snd_es1968_reset(struct es1968 *chip)
-{
- /* Reset */
- outw(ESM_RESET_MAESTRO | ESM_RESET_DIRECTSOUND,
- chip->io_port + ESM_PORT_HOST_IRQ);
- udelay(10);
- outw(0x0000, chip->io_port + ESM_PORT_HOST_IRQ);
- udelay(10);
-}
-
-/*
- * initialize maestro chip
- */
-static void snd_es1968_chip_init(struct es1968 *chip)
-{
- struct pci_dev *pci = chip->pci;
- int i;
- unsigned long iobase = chip->io_port;
- u16 w;
- u32 n;
-
- /* We used to muck around with pci config space that
- * we had no business messing with. We don't know enough
- * about the machine to know which DMA mode is appropriate,
- * etc. We were guessing wrong on some machines and making
- * them unhappy. We now trust in the BIOS to do things right,
- * which almost certainly means a new host of problems will
- * arise with broken BIOS implementations. screw 'em.
- * We're already intolerant of machines that don't assign
- * IRQs.
- */
-
- /* Config Reg A */
- pci_read_config_word(pci, ESM_CONFIG_A, &w);
-
- w &= ~DMA_CLEAR; /* Clear DMA bits */
- w &= ~(PIC_SNOOP1 | PIC_SNOOP2); /* Clear Pic Snoop Mode Bits */
- w &= ~SAFEGUARD; /* Safeguard off */
- w |= POST_WRITE; /* Posted write */
- w |= PCI_TIMING; /* PCI timing on */
- /* XXX huh? claims to be reserved.. */
- w &= ~SWAP_LR; /* swap left/right
- seems to only have effect on SB
- Emulation */
- w &= ~SUBTR_DECODE; /* Subtractive decode off */
-
- pci_write_config_word(pci, ESM_CONFIG_A, w);
-
- /* Config Reg B */
-
- pci_read_config_word(pci, ESM_CONFIG_B, &w);
-
- w &= ~(1 << 15); /* Turn off internal clock multiplier */
- /* XXX how do we know which to use? */
- w &= ~(1 << 14); /* External clock */
-
- w &= ~SPDIF_CONFB; /* disable S/PDIF output */
- w |= HWV_CONFB; /* HWV on */
- w |= DEBOUNCE; /* Debounce off: easier to push the HW buttons */
- w &= ~GPIO_CONFB; /* GPIO 4:5 */
- w |= CHI_CONFB; /* Disconnect from the CHI. Enabling this made a dell 7500 work. */
- w &= ~IDMA_CONFB; /* IDMA off (undocumented) */
- w &= ~MIDI_FIX; /* MIDI fix off (undoc) */
- w &= ~(1 << 1); /* reserved, always write 0 */
- w &= ~IRQ_TO_ISA; /* IRQ to ISA off (undoc) */
-
- pci_write_config_word(pci, ESM_CONFIG_B, w);
-
- /* DDMA off */
-
- pci_read_config_word(pci, ESM_DDMA, &w);
- w &= ~(1 << 0);
- pci_write_config_word(pci, ESM_DDMA, w);
-
- /*
- * Legacy mode
- */
-
- pci_read_config_word(pci, ESM_LEGACY_AUDIO_CONTROL, &w);
-
- w |= ESS_DISABLE_AUDIO; /* Disable Legacy Audio */
- w &= ~ESS_ENABLE_SERIAL_IRQ; /* Disable SIRQ */
- w &= ~(0x1f); /* disable mpu irq/io, game port, fm, SB */
-
- pci_write_config_word(pci, ESM_LEGACY_AUDIO_CONTROL, w);
-
- /* Set up 978 docking control chip. */
- pci_read_config_word(pci, 0x58, &w);
- w|=1<<2; /* Enable 978. */
- w|=1<<3; /* Turn on 978 hardware volume control. */
- w&=~(1<<11); /* Turn on 978 mixer volume control. */
- pci_write_config_word(pci, 0x58, w);
-
- /* Sound Reset */
-
- snd_es1968_reset(chip);
-
- /*
- * Ring Bus Setup
- */
-
- /* setup usual 0x34 stuff.. 0x36 may be chip specific */
- outw(0xC090, iobase + ESM_RING_BUS_DEST); /* direct sound, stereo */
- udelay(20);
- outw(0x3000, iobase + ESM_RING_BUS_CONTR_A); /* enable ringbus/serial */
- udelay(20);
-
- /*
- * Reset the CODEC
- */
-
- snd_es1968_ac97_reset(chip);
-
- /* Ring Bus Control B */
-
- n = inl(iobase + ESM_RING_BUS_CONTR_B);
- n &= ~RINGB_EN_SPDIF; /* SPDIF off */
- //w |= RINGB_EN_2CODEC; /* enable 2nd codec */
- outl(n, iobase + ESM_RING_BUS_CONTR_B);
-
- /* Set hardware volume control registers to midpoints.
- We can tell which button was pushed based on how they change. */
- outb(0x88, iobase+0x1c);
- outb(0x88, iobase+0x1d);
- outb(0x88, iobase+0x1e);
- outb(0x88, iobase+0x1f);
-
- /* it appears some maestros (dell 7500) only work if these are set,
- regardless of wether we use the assp or not. */
-
- outb(0, iobase + ASSP_CONTROL_B);
- outb(3, iobase + ASSP_CONTROL_A); /* M: Reserved bits... */
- outb(0, iobase + ASSP_CONTROL_C); /* M: Disable ASSP, ASSP IRQ's and FM Port */
-
- /*
- * set up wavecache
- */
- for (i = 0; i < 16; i++) {
- /* Write 0 into the buffer area 0x1E0->1EF */
- outw(0x01E0 + i, iobase + WC_INDEX);
- outw(0x0000, iobase + WC_DATA);
-
- /* The 1.10 test program seem to write 0 into the buffer area
- * 0x1D0-0x1DF too.*/
- outw(0x01D0 + i, iobase + WC_INDEX);
- outw(0x0000, iobase + WC_DATA);
- }
- wave_set_register(chip, IDR7_WAVE_ROMRAM,
- (wave_get_register(chip, IDR7_WAVE_ROMRAM) & 0xFF00));
- wave_set_register(chip, IDR7_WAVE_ROMRAM,
- wave_get_register(chip, IDR7_WAVE_ROMRAM) | 0x100);
- wave_set_register(chip, IDR7_WAVE_ROMRAM,
- wave_get_register(chip, IDR7_WAVE_ROMRAM) & ~0x200);
- wave_set_register(chip, IDR7_WAVE_ROMRAM,
- wave_get_register(chip, IDR7_WAVE_ROMRAM) | ~0x400);
-
-
- maestro_write(chip, IDR2_CRAM_DATA, 0x0000);
- /* Now back to the DirectSound stuff */
- /* audio serial configuration.. ? */
- maestro_write(chip, 0x08, 0xB004);
- maestro_write(chip, 0x09, 0x001B);
- maestro_write(chip, 0x0A, 0x8000);
- maestro_write(chip, 0x0B, 0x3F37);
- maestro_write(chip, 0x0C, 0x0098);
-
- /* parallel in, has something to do with recording :) */
- maestro_write(chip, 0x0C,
- (maestro_read(chip, 0x0C) & ~0xF000) | 0x8000);
- /* parallel out */
- maestro_write(chip, 0x0C,
- (maestro_read(chip, 0x0C) & ~0x0F00) | 0x0500);
-
- maestro_write(chip, 0x0D, 0x7632);
-
- /* Wave cache control on - test off, sg off,
- enable, enable extra chans 1Mb */
-
- w = inw(iobase + WC_CONTROL);
-
- w &= ~0xFA00; /* Seems to be reserved? I don't know */
- w |= 0xA000; /* reserved... I don't know */
- w &= ~0x0200; /* Channels 56,57,58,59 as Extra Play,Rec Channel enable
- Seems to crash the Computer if enabled... */
- w |= 0x0100; /* Wave Cache Operation Enabled */
- w |= 0x0080; /* Channels 60/61 as Placback/Record enabled */
- w &= ~0x0060; /* Clear Wavtable Size */
- w |= 0x0020; /* Wavetable Size : 1MB */
- /* Bit 4 is reserved */
- w &= ~0x000C; /* DMA Stuff? I don't understand what the datasheet means */
- /* Bit 1 is reserved */
- w &= ~0x0001; /* Test Mode off */
-
- outw(w, iobase + WC_CONTROL);
-
- /* Now clear the APU control ram */
- for (i = 0; i < NR_APUS; i++) {
- for (w = 0; w < NR_APU_REGS; w++)
- apu_set_register(chip, i, w, 0);
-
- }
-}
-
-/* Enable IRQ's */
-static void snd_es1968_start_irq(struct es1968 *chip)
-{
- unsigned short w;
- w = ESM_HIRQ_DSIE | ESM_HIRQ_HW_VOLUME;
- if (chip->rmidi)
- w |= ESM_HIRQ_MPU401;
- outb(w, chip->io_port + 0x1A);
- outw(w, chip->io_port + ESM_PORT_HOST_IRQ);
-}
-
-#ifdef CONFIG_PM
-/*
- * PM support
- */
-static int es1968_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct es1968 *chip = card->private_data;
-
- if (! chip->do_pm)
- return 0;
-
- chip->in_suspend = 1;
- cancel_work_sync(&chip->hwvol_work);
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(chip->pcm);
- snd_ac97_suspend(chip->ac97);
- snd_es1968_bob_stop(chip);
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int es1968_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct es1968 *chip = card->private_data;
- struct esschan *es;
-
- if (! chip->do_pm)
- return 0;
-
- /* restore all our config */
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "es1968: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
-
- snd_es1968_chip_init(chip);
-
- /* need to restore the base pointers.. */
- if (chip->dma.addr) {
- /* set PCMBAR */
- wave_set_register(chip, 0x01FC, chip->dma.addr >> 12);
- }
-
- snd_es1968_start_irq(chip);
-
- /* restore ac97 state */
- snd_ac97_resume(chip->ac97);
-
- list_for_each_entry(es, &chip->substream_list, list) {
- switch (es->mode) {
- case ESM_MODE_PLAY:
- snd_es1968_playback_setup(chip, es, es->substream->runtime);
- break;
- case ESM_MODE_CAPTURE:
- snd_es1968_capture_setup(chip, es, es->substream->runtime);
- break;
- }
- }
-
- /* start timer again */
- if (chip->bobclient)
- snd_es1968_bob_start(chip);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- chip->in_suspend = 0;
- return 0;
-}
-#endif /* CONFIG_PM */
-
-#ifdef SUPPORT_JOYSTICK
-#define JOYSTICK_ADDR 0x200
-static int __devinit snd_es1968_create_gameport(struct es1968 *chip, int dev)
-{
- struct gameport *gp;
- struct resource *r;
- u16 val;
-
- if (!joystick[dev])
- return -ENODEV;
-
- r = request_region(JOYSTICK_ADDR, 8, "ES1968 gameport");
- if (!r)
- return -EBUSY;
-
- chip->gameport = gp = gameport_allocate_port();
- if (!gp) {
- printk(KERN_ERR "es1968: cannot allocate memory for gameport\n");
- release_and_free_resource(r);
- return -ENOMEM;
- }
-
- pci_read_config_word(chip->pci, ESM_LEGACY_AUDIO_CONTROL, &val);
- pci_write_config_word(chip->pci, ESM_LEGACY_AUDIO_CONTROL, val | 0x04);
-
- gameport_set_name(gp, "ES1968 Gameport");
- gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
- gameport_set_dev_parent(gp, &chip->pci->dev);
- gp->io = JOYSTICK_ADDR;
- gameport_set_port_data(gp, r);
-
- gameport_register_port(gp);
-
- return 0;
-}
-
-static void snd_es1968_free_gameport(struct es1968 *chip)
-{
- if (chip->gameport) {
- struct resource *r = gameport_get_port_data(chip->gameport);
-
- gameport_unregister_port(chip->gameport);
- chip->gameport = NULL;
-
- release_and_free_resource(r);
- }
-}
-#else
-static inline int snd_es1968_create_gameport(struct es1968 *chip, int dev) { return -ENOSYS; }
-static inline void snd_es1968_free_gameport(struct es1968 *chip) { }
-#endif
-
-#ifdef CONFIG_SND_ES1968_INPUT
-static int __devinit snd_es1968_input_register(struct es1968 *chip)
-{
- struct input_dev *input_dev;
- int err;
-
- input_dev = input_allocate_device();
- if (!input_dev)
- return -ENOMEM;
-
- snprintf(chip->phys, sizeof(chip->phys), "pci-%s/input0",
- pci_name(chip->pci));
-
- input_dev->name = chip->card->driver;
- input_dev->phys = chip->phys;
- input_dev->id.bustype = BUS_PCI;
- input_dev->id.vendor = chip->pci->vendor;
- input_dev->id.product = chip->pci->device;
- input_dev->dev.parent = &chip->pci->dev;
-
- __set_bit(EV_KEY, input_dev->evbit);
- __set_bit(KEY_MUTE, input_dev->keybit);
- __set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
- __set_bit(KEY_VOLUMEUP, input_dev->keybit);
-
- err = input_register_device(input_dev);
- if (err) {
- input_free_device(input_dev);
- return err;
- }
-
- chip->input_dev = input_dev;
- return 0;
-}
-#endif /* CONFIG_SND_ES1968_INPUT */
-
-#ifdef CONFIG_SND_ES1968_RADIO
-#define GPIO_DATA 0x60
-#define IO_MASK 4 /* mask register offset from GPIO_DATA
- bits 1=unmask write to given bit */
-#define IO_DIR 8 /* direction register offset from GPIO_DATA
- bits 0/1=read/write direction */
-/* mask bits for GPIO lines */
-#define STR_DATA 0x0040 /* GPIO6 */
-#define STR_CLK 0x0080 /* GPIO7 */
-#define STR_WREN 0x0100 /* GPIO8 */
-#define STR_MOST 0x0200 /* GPIO9 */
-
-static void snd_es1968_tea575x_set_pins(struct snd_tea575x *tea, u8 pins)
-{
- struct es1968 *chip = tea->private_data;
- unsigned long io = chip->io_port + GPIO_DATA;
- u16 val = 0;
-
- val |= (pins & TEA575X_DATA) ? STR_DATA : 0;
- val |= (pins & TEA575X_CLK) ? STR_CLK : 0;
- val |= (pins & TEA575X_WREN) ? STR_WREN : 0;
-
- outw(val, io);
-}
-
-static u8 snd_es1968_tea575x_get_pins(struct snd_tea575x *tea)
-{
- struct es1968 *chip = tea->private_data;
- unsigned long io = chip->io_port + GPIO_DATA;
- u16 val = inw(io);
-
- return (val & STR_DATA) ? TEA575X_DATA : 0 |
- (val & STR_MOST) ? TEA575X_MOST : 0;
-}
-
-static void snd_es1968_tea575x_set_direction(struct snd_tea575x *tea, bool output)
-{
- struct es1968 *chip = tea->private_data;
- unsigned long io = chip->io_port + GPIO_DATA;
- u16 odir = inw(io + IO_DIR);
-
- if (output) {
- outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK);
- outw(odir | STR_DATA | STR_CLK | STR_WREN, io + IO_DIR);
- } else {
- outw(~(STR_CLK | STR_WREN | STR_DATA | STR_MOST), io + IO_MASK);
- outw((odir & ~(STR_DATA | STR_MOST)) | STR_CLK | STR_WREN, io + IO_DIR);
- }
-}
-
-static struct snd_tea575x_ops snd_es1968_tea_ops = {
- .set_pins = snd_es1968_tea575x_set_pins,
- .get_pins = snd_es1968_tea575x_get_pins,
- .set_direction = snd_es1968_tea575x_set_direction,
-};
-#endif
-
-static int snd_es1968_free(struct es1968 *chip)
-{
- cancel_work_sync(&chip->hwvol_work);
-#ifdef CONFIG_SND_ES1968_INPUT
- if (chip->input_dev)
- input_unregister_device(chip->input_dev);
-#endif
-
- if (chip->io_port) {
- if (chip->irq >= 0)
- synchronize_irq(chip->irq);
- outw(1, chip->io_port + 0x04); /* clear WP interrupts */
- outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */
- }
-
-#ifdef CONFIG_SND_ES1968_RADIO
- snd_tea575x_exit(&chip->tea);
- v4l2_device_unregister(&chip->v4l2_dev);
-#endif
-
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
- snd_es1968_free_gameport(chip);
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
- kfree(chip);
- return 0;
-}
-
-static int snd_es1968_dev_free(struct snd_device *device)
-{
- struct es1968 *chip = device->device_data;
- return snd_es1968_free(chip);
-}
-
-struct ess_device_list {
- unsigned short type; /* chip type */
- unsigned short vendor; /* subsystem vendor id */
-};
-
-static struct ess_device_list pm_whitelist[] __devinitdata = {
- { TYPE_MAESTRO2E, 0x0e11 }, /* Compaq Armada */
- { TYPE_MAESTRO2E, 0x1028 },
- { TYPE_MAESTRO2E, 0x103c },
- { TYPE_MAESTRO2E, 0x1179 },
- { TYPE_MAESTRO2E, 0x14c0 }, /* HP omnibook 4150 */
- { TYPE_MAESTRO2E, 0x1558 },
-};
-
-static struct ess_device_list mpu_blacklist[] __devinitdata = {
- { TYPE_MAESTRO2, 0x125d },
-};
-
-static int __devinit snd_es1968_create(struct snd_card *card,
- struct pci_dev *pci,
- int total_bufsize,
- int play_streams,
- int capt_streams,
- int chip_type,
- int do_pm,
- int radio_nr,
- struct es1968 **chip_ret)
-{
- static struct snd_device_ops ops = {
- .dev_free = snd_es1968_dev_free,
- };
- struct es1968 *chip;
- int i, err;
-
- *chip_ret = NULL;
-
- /* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
- return err;
- /* check, if we can restrict PCI DMA transfers to 28 bits */
- if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) {
- snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n");
- pci_disable_device(pci);
- return -ENXIO;
- }
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (! chip) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- /* Set Vars */
- chip->type = chip_type;
- spin_lock_init(&chip->reg_lock);
- spin_lock_init(&chip->substream_lock);
- INIT_LIST_HEAD(&chip->buf_list);
- INIT_LIST_HEAD(&chip->substream_list);
- mutex_init(&chip->memory_mutex);
- INIT_WORK(&chip->hwvol_work, es1968_update_hw_volume);
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
- chip->total_bufsize = total_bufsize; /* in bytes */
- chip->playback_streams = play_streams;
- chip->capture_streams = capt_streams;
-
- if ((err = pci_request_regions(pci, "ESS Maestro")) < 0) {
- kfree(chip);
- pci_disable_device(pci);
- return err;
- }
- chip->io_port = pci_resource_start(pci, 0);
- if (request_irq(pci->irq, snd_es1968_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_es1968_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
-
- /* Clear Maestro_map */
- for (i = 0; i < 32; i++)
- chip->maestro_map[i] = 0;
-
- /* Clear Apu Map */
- for (i = 0; i < NR_APUS; i++)
- chip->apu[i] = ESM_APU_FREE;
-
- /* just to be sure */
- pci_set_master(pci);
-
- if (do_pm > 1) {
- /* disable power-management if not on the whitelist */
- unsigned short vend;
- pci_read_config_word(chip->pci, PCI_SUBSYSTEM_VENDOR_ID, &vend);
- for (i = 0; i < (int)ARRAY_SIZE(pm_whitelist); i++) {
- if (chip->type == pm_whitelist[i].type &&
- vend == pm_whitelist[i].vendor) {
- do_pm = 1;
- break;
- }
- }
- if (do_pm > 1) {
- /* not matched; disabling pm */
- printk(KERN_INFO "es1968: not attempting power management.\n");
- do_pm = 0;
- }
- }
- chip->do_pm = do_pm;
-
- snd_es1968_chip_init(chip);
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_es1968_free(chip);
- return err;
- }
-
- snd_card_set_dev(card, &pci->dev);
-
-#ifdef CONFIG_SND_ES1968_RADIO
- err = v4l2_device_register(&pci->dev, &chip->v4l2_dev);
- if (err < 0) {
- snd_es1968_free(chip);
- return err;
- }
- chip->tea.v4l2_dev = &chip->v4l2_dev;
- chip->tea.private_data = chip;
- chip->tea.radio_nr = radio_nr;
- chip->tea.ops = &snd_es1968_tea_ops;
- strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card));
- sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
- if (!snd_tea575x_init(&chip->tea))
- printk(KERN_INFO "es1968: detected TEA575x radio\n");
-#endif
-
- *chip_ret = chip;
-
- return 0;
-}
-
-
-/*
- */
-static int __devinit snd_es1968_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct es1968 *chip;
- unsigned int i;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- if (total_bufsize[dev] < 128)
- total_bufsize[dev] = 128;
- if (total_bufsize[dev] > 4096)
- total_bufsize[dev] = 4096;
- if ((err = snd_es1968_create(card, pci,
- total_bufsize[dev] * 1024, /* in bytes */
- pcm_substreams_p[dev],
- pcm_substreams_c[dev],
- pci_id->driver_data,
- use_pm[dev],
- radio_nr[dev],
- &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
- card->private_data = chip;
-
- switch (chip->type) {
- case TYPE_MAESTRO2E:
- strcpy(card->driver, "ES1978");
- strcpy(card->shortname, "ESS ES1978 (Maestro 2E)");
- break;
- case TYPE_MAESTRO2:
- strcpy(card->driver, "ES1968");
- strcpy(card->shortname, "ESS ES1968 (Maestro 2)");
- break;
- case TYPE_MAESTRO:
- strcpy(card->driver, "ESM1");
- strcpy(card->shortname, "ESS Maestro 1");
- break;
- }
-
- if ((err = snd_es1968_pcm(chip, 0)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- if ((err = snd_es1968_mixer(chip)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- if (enable_mpu[dev] == 2) {
- /* check the black list */
- unsigned short vend;
- pci_read_config_word(chip->pci, PCI_SUBSYSTEM_VENDOR_ID, &vend);
- for (i = 0; i < ARRAY_SIZE(mpu_blacklist); i++) {
- if (chip->type == mpu_blacklist[i].type &&
- vend == mpu_blacklist[i].vendor) {
- enable_mpu[dev] = 0;
- break;
- }
- }
- }
- if (enable_mpu[dev]) {
- if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
- chip->io_port + ESM_MPU401_PORT,
- MPU401_INFO_INTEGRATED |
- MPU401_INFO_IRQ_HOOK,
- -1, &chip->rmidi)) < 0) {
- printk(KERN_WARNING "es1968: skipping MPU-401 MIDI support..\n");
- }
- }
-
- snd_es1968_create_gameport(chip, dev);
-
-#ifdef CONFIG_SND_ES1968_INPUT
- err = snd_es1968_input_register(chip);
- if (err)
- snd_printk(KERN_WARNING "Input device registration "
- "failed with error %i", err);
-#endif
-
- snd_es1968_start_irq(chip);
-
- chip->clock = clock[dev];
- if (! chip->clock)
- es1968_measure_clock(chip);
-
- sprintf(card->longname, "%s at 0x%lx, irq %i",
- card->shortname, chip->io_port, chip->irq);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_es1968_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_es1968_ids,
- .probe = snd_es1968_probe,
- .remove = __devexit_p(snd_es1968_remove),
-#ifdef CONFIG_PM
- .suspend = es1968_suspend,
- .resume = es1968_resume,
-#endif
-};
-
-static int __init alsa_card_es1968_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_es1968_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_es1968_init)
-module_exit(alsa_card_es1968_exit)
diff --git a/ANDROID_3.4.5/sound/pci/fm801.c b/ANDROID_3.4.5/sound/pci/fm801.c
deleted file mode 100644
index a416ea8a..00000000
--- a/ANDROID_3.4.5/sound/pci/fm801.c
+++ /dev/null
@@ -1,1441 +0,0 @@
-/*
- * The driver for the ForteMedia FM801 based soundcards
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- * Support FM only card by Andy Shevchenko <andy@smile.org.ua>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/tlv.h>
-#include <sound/ac97_codec.h>
-#include <sound/mpu401.h>
-#include <sound/opl3.h>
-#include <sound/initval.h>
-
-#include <asm/io.h>
-
-#ifdef CONFIG_SND_FM801_TEA575X_BOOL
-#include <sound/tea575x-tuner.h>
-#endif
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("ForteMedia FM801");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ForteMedia,FM801},"
- "{Genius,SoundMaker Live 5.1}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-/*
- * Enable TEA575x tuner
- * 1 = MediaForte 256-PCS
- * 2 = MediaForte 256-PCP
- * 3 = MediaForte 64-PCR
- * 16 = setup tuner only (this is additional bit), i.e. SF64-PCR FM card
- * High 16-bits are video (radio) device number + 1
- */
-static int tea575x_tuner[SNDRV_CARDS];
-static int radio_nr[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for the FM801 soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for the FM801 soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable FM801 soundcard.");
-module_param_array(tea575x_tuner, int, NULL, 0444);
-MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (0 = auto, 1 = SF256-PCS, 2=SF256-PCP, 3=SF64-PCR, 8=disable, +16=tuner-only).");
-module_param_array(radio_nr, int, NULL, 0444);
-MODULE_PARM_DESC(radio_nr, "Radio device numbers");
-
-
-#define TUNER_DISABLED (1<<3)
-#define TUNER_ONLY (1<<4)
-#define TUNER_TYPE_MASK (~TUNER_ONLY & 0xFFFF)
-
-/*
- * Direct registers
- */
-
-#define FM801_REG(chip, reg) (chip->port + FM801_##reg)
-
-#define FM801_PCM_VOL 0x00 /* PCM Output Volume */
-#define FM801_FM_VOL 0x02 /* FM Output Volume */
-#define FM801_I2S_VOL 0x04 /* I2S Volume */
-#define FM801_REC_SRC 0x06 /* Record Source */
-#define FM801_PLY_CTRL 0x08 /* Playback Control */
-#define FM801_PLY_COUNT 0x0a /* Playback Count */
-#define FM801_PLY_BUF1 0x0c /* Playback Bufer I */
-#define FM801_PLY_BUF2 0x10 /* Playback Buffer II */
-#define FM801_CAP_CTRL 0x14 /* Capture Control */
-#define FM801_CAP_COUNT 0x16 /* Capture Count */
-#define FM801_CAP_BUF1 0x18 /* Capture Buffer I */
-#define FM801_CAP_BUF2 0x1c /* Capture Buffer II */
-#define FM801_CODEC_CTRL 0x22 /* Codec Control */
-#define FM801_I2S_MODE 0x24 /* I2S Mode Control */
-#define FM801_VOLUME 0x26 /* Volume Up/Down/Mute Status */
-#define FM801_I2C_CTRL 0x29 /* I2C Control */
-#define FM801_AC97_CMD 0x2a /* AC'97 Command */
-#define FM801_AC97_DATA 0x2c /* AC'97 Data */
-#define FM801_MPU401_DATA 0x30 /* MPU401 Data */
-#define FM801_MPU401_CMD 0x31 /* MPU401 Command */
-#define FM801_GPIO_CTRL 0x52 /* General Purpose I/O Control */
-#define FM801_GEN_CTRL 0x54 /* General Control */
-#define FM801_IRQ_MASK 0x56 /* Interrupt Mask */
-#define FM801_IRQ_STATUS 0x5a /* Interrupt Status */
-#define FM801_OPL3_BANK0 0x68 /* OPL3 Status Read / Bank 0 Write */
-#define FM801_OPL3_DATA0 0x69 /* OPL3 Data 0 Write */
-#define FM801_OPL3_BANK1 0x6a /* OPL3 Bank 1 Write */
-#define FM801_OPL3_DATA1 0x6b /* OPL3 Bank 1 Write */
-#define FM801_POWERDOWN 0x70 /* Blocks Power Down Control */
-
-/* codec access */
-#define FM801_AC97_READ (1<<7) /* read=1, write=0 */
-#define FM801_AC97_VALID (1<<8) /* port valid=1 */
-#define FM801_AC97_BUSY (1<<9) /* busy=1 */
-#define FM801_AC97_ADDR_SHIFT 10 /* codec id (2bit) */
-
-/* playback and record control register bits */
-#define FM801_BUF1_LAST (1<<1)
-#define FM801_BUF2_LAST (1<<2)
-#define FM801_START (1<<5)
-#define FM801_PAUSE (1<<6)
-#define FM801_IMMED_STOP (1<<7)
-#define FM801_RATE_SHIFT 8
-#define FM801_RATE_MASK (15 << FM801_RATE_SHIFT)
-#define FM801_CHANNELS_4 (1<<12) /* playback only */
-#define FM801_CHANNELS_6 (2<<12) /* playback only */
-#define FM801_CHANNELS_6MS (3<<12) /* playback only */
-#define FM801_CHANNELS_MASK (3<<12)
-#define FM801_16BIT (1<<14)
-#define FM801_STEREO (1<<15)
-
-/* IRQ status bits */
-#define FM801_IRQ_PLAYBACK (1<<8)
-#define FM801_IRQ_CAPTURE (1<<9)
-#define FM801_IRQ_VOLUME (1<<14)
-#define FM801_IRQ_MPU (1<<15)
-
-/* GPIO control register */
-#define FM801_GPIO_GP0 (1<<0) /* read/write */
-#define FM801_GPIO_GP1 (1<<1)
-#define FM801_GPIO_GP2 (1<<2)
-#define FM801_GPIO_GP3 (1<<3)
-#define FM801_GPIO_GP(x) (1<<(0+(x)))
-#define FM801_GPIO_GD0 (1<<8) /* directions: 1 = input, 0 = output*/
-#define FM801_GPIO_GD1 (1<<9)
-#define FM801_GPIO_GD2 (1<<10)
-#define FM801_GPIO_GD3 (1<<11)
-#define FM801_GPIO_GD(x) (1<<(8+(x)))
-#define FM801_GPIO_GS0 (1<<12) /* function select: */
-#define FM801_GPIO_GS1 (1<<13) /* 1 = GPIO */
-#define FM801_GPIO_GS2 (1<<14) /* 0 = other (S/PDIF, VOL) */
-#define FM801_GPIO_GS3 (1<<15)
-#define FM801_GPIO_GS(x) (1<<(12+(x)))
-
-/*
-
- */
-
-struct fm801 {
- int irq;
-
- unsigned long port; /* I/O port number */
- unsigned int multichannel: 1, /* multichannel support */
- secondary: 1; /* secondary codec */
- unsigned char secondary_addr; /* address of the secondary codec */
- unsigned int tea575x_tuner; /* tuner access method & flags */
-
- unsigned short ply_ctrl; /* playback control */
- unsigned short cap_ctrl; /* capture control */
-
- unsigned long ply_buffer;
- unsigned int ply_buf;
- unsigned int ply_count;
- unsigned int ply_size;
- unsigned int ply_pos;
-
- unsigned long cap_buffer;
- unsigned int cap_buf;
- unsigned int cap_count;
- unsigned int cap_size;
- unsigned int cap_pos;
-
- struct snd_ac97_bus *ac97_bus;
- struct snd_ac97 *ac97;
- struct snd_ac97 *ac97_sec;
-
- struct pci_dev *pci;
- struct snd_card *card;
- struct snd_pcm *pcm;
- struct snd_rawmidi *rmidi;
- struct snd_pcm_substream *playback_substream;
- struct snd_pcm_substream *capture_substream;
- unsigned int p_dma_size;
- unsigned int c_dma_size;
-
- spinlock_t reg_lock;
- struct snd_info_entry *proc_entry;
-
-#ifdef CONFIG_SND_FM801_TEA575X_BOOL
- struct v4l2_device v4l2_dev;
- struct snd_tea575x tea;
-#endif
-
-#ifdef CONFIG_PM
- u16 saved_regs[0x20];
-#endif
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_fm801_ids) = {
- { 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* FM801 */
- { 0x5213, 0x0510, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* Gallant Odyssey Sound 4 */
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_fm801_ids);
-
-/*
- * common I/O routines
- */
-
-static int snd_fm801_update_bits(struct fm801 *chip, unsigned short reg,
- unsigned short mask, unsigned short value)
-{
- int change;
- unsigned long flags;
- unsigned short old, new;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- old = inw(chip->port + reg);
- new = (old & ~mask) | value;
- change = old != new;
- if (change)
- outw(new, chip->port + reg);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return change;
-}
-
-static void snd_fm801_codec_write(struct snd_ac97 *ac97,
- unsigned short reg,
- unsigned short val)
-{
- struct fm801 *chip = ac97->private_data;
- int idx;
-
- /*
- * Wait until the codec interface is not ready..
- */
- for (idx = 0; idx < 100; idx++) {
- if (!(inw(FM801_REG(chip, AC97_CMD)) & FM801_AC97_BUSY))
- goto ok1;
- udelay(10);
- }
- snd_printk(KERN_ERR "AC'97 interface is busy (1)\n");
- return;
-
- ok1:
- /* write data and address */
- outw(val, FM801_REG(chip, AC97_DATA));
- outw(reg | (ac97->addr << FM801_AC97_ADDR_SHIFT), FM801_REG(chip, AC97_CMD));
- /*
- * Wait until the write command is not completed..
- */
- for (idx = 0; idx < 1000; idx++) {
- if (!(inw(FM801_REG(chip, AC97_CMD)) & FM801_AC97_BUSY))
- return;
- udelay(10);
- }
- snd_printk(KERN_ERR "AC'97 interface #%d is busy (2)\n", ac97->num);
-}
-
-static unsigned short snd_fm801_codec_read(struct snd_ac97 *ac97, unsigned short reg)
-{
- struct fm801 *chip = ac97->private_data;
- int idx;
-
- /*
- * Wait until the codec interface is not ready..
- */
- for (idx = 0; idx < 100; idx++) {
- if (!(inw(FM801_REG(chip, AC97_CMD)) & FM801_AC97_BUSY))
- goto ok1;
- udelay(10);
- }
- snd_printk(KERN_ERR "AC'97 interface is busy (1)\n");
- return 0;
-
- ok1:
- /* read command */
- outw(reg | (ac97->addr << FM801_AC97_ADDR_SHIFT) | FM801_AC97_READ,
- FM801_REG(chip, AC97_CMD));
- for (idx = 0; idx < 100; idx++) {
- if (!(inw(FM801_REG(chip, AC97_CMD)) & FM801_AC97_BUSY))
- goto ok2;
- udelay(10);
- }
- snd_printk(KERN_ERR "AC'97 interface #%d is busy (2)\n", ac97->num);
- return 0;
-
- ok2:
- for (idx = 0; idx < 1000; idx++) {
- if (inw(FM801_REG(chip, AC97_CMD)) & FM801_AC97_VALID)
- goto ok3;
- udelay(10);
- }
- snd_printk(KERN_ERR "AC'97 interface #%d is not valid (2)\n", ac97->num);
- return 0;
-
- ok3:
- return inw(FM801_REG(chip, AC97_DATA));
-}
-
-static unsigned int rates[] = {
- 5500, 8000, 9600, 11025,
- 16000, 19200, 22050, 32000,
- 38400, 44100, 48000
-};
-
-static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
- .count = ARRAY_SIZE(rates),
- .list = rates,
- .mask = 0,
-};
-
-static unsigned int channels[] = {
- 2, 4, 6
-};
-
-static struct snd_pcm_hw_constraint_list hw_constraints_channels = {
- .count = ARRAY_SIZE(channels),
- .list = channels,
- .mask = 0,
-};
-
-/*
- * Sample rate routines
- */
-
-static unsigned short snd_fm801_rate_bits(unsigned int rate)
-{
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(rates); idx++)
- if (rates[idx] == rate)
- return idx;
- snd_BUG();
- return ARRAY_SIZE(rates) - 1;
-}
-
-/*
- * PCM part
- */
-
-static int snd_fm801_playback_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct fm801 *chip = snd_pcm_substream_chip(substream);
-
- spin_lock(&chip->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- chip->ply_ctrl &= ~(FM801_BUF1_LAST |
- FM801_BUF2_LAST |
- FM801_PAUSE);
- chip->ply_ctrl |= FM801_START |
- FM801_IMMED_STOP;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- chip->ply_ctrl &= ~(FM801_START | FM801_PAUSE);
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- chip->ply_ctrl |= FM801_PAUSE;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
- chip->ply_ctrl &= ~FM801_PAUSE;
- break;
- default:
- spin_unlock(&chip->reg_lock);
- snd_BUG();
- return -EINVAL;
- }
- outw(chip->ply_ctrl, FM801_REG(chip, PLY_CTRL));
- spin_unlock(&chip->reg_lock);
- return 0;
-}
-
-static int snd_fm801_capture_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct fm801 *chip = snd_pcm_substream_chip(substream);
-
- spin_lock(&chip->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- chip->cap_ctrl &= ~(FM801_BUF1_LAST |
- FM801_BUF2_LAST |
- FM801_PAUSE);
- chip->cap_ctrl |= FM801_START |
- FM801_IMMED_STOP;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- chip->cap_ctrl &= ~(FM801_START | FM801_PAUSE);
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- chip->cap_ctrl |= FM801_PAUSE;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
- chip->cap_ctrl &= ~FM801_PAUSE;
- break;
- default:
- spin_unlock(&chip->reg_lock);
- snd_BUG();
- return -EINVAL;
- }
- outw(chip->cap_ctrl, FM801_REG(chip, CAP_CTRL));
- spin_unlock(&chip->reg_lock);
- return 0;
-}
-
-static int snd_fm801_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static int snd_fm801_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_fm801_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct fm801 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- chip->ply_size = snd_pcm_lib_buffer_bytes(substream);
- chip->ply_count = snd_pcm_lib_period_bytes(substream);
- spin_lock_irq(&chip->reg_lock);
- chip->ply_ctrl &= ~(FM801_START | FM801_16BIT |
- FM801_STEREO | FM801_RATE_MASK |
- FM801_CHANNELS_MASK);
- if (snd_pcm_format_width(runtime->format) == 16)
- chip->ply_ctrl |= FM801_16BIT;
- if (runtime->channels > 1) {
- chip->ply_ctrl |= FM801_STEREO;
- if (runtime->channels == 4)
- chip->ply_ctrl |= FM801_CHANNELS_4;
- else if (runtime->channels == 6)
- chip->ply_ctrl |= FM801_CHANNELS_6;
- }
- chip->ply_ctrl |= snd_fm801_rate_bits(runtime->rate) << FM801_RATE_SHIFT;
- chip->ply_buf = 0;
- outw(chip->ply_ctrl, FM801_REG(chip, PLY_CTRL));
- outw(chip->ply_count - 1, FM801_REG(chip, PLY_COUNT));
- chip->ply_buffer = runtime->dma_addr;
- chip->ply_pos = 0;
- outl(chip->ply_buffer, FM801_REG(chip, PLY_BUF1));
- outl(chip->ply_buffer + (chip->ply_count % chip->ply_size), FM801_REG(chip, PLY_BUF2));
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static int snd_fm801_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct fm801 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- chip->cap_size = snd_pcm_lib_buffer_bytes(substream);
- chip->cap_count = snd_pcm_lib_period_bytes(substream);
- spin_lock_irq(&chip->reg_lock);
- chip->cap_ctrl &= ~(FM801_START | FM801_16BIT |
- FM801_STEREO | FM801_RATE_MASK);
- if (snd_pcm_format_width(runtime->format) == 16)
- chip->cap_ctrl |= FM801_16BIT;
- if (runtime->channels > 1)
- chip->cap_ctrl |= FM801_STEREO;
- chip->cap_ctrl |= snd_fm801_rate_bits(runtime->rate) << FM801_RATE_SHIFT;
- chip->cap_buf = 0;
- outw(chip->cap_ctrl, FM801_REG(chip, CAP_CTRL));
- outw(chip->cap_count - 1, FM801_REG(chip, CAP_COUNT));
- chip->cap_buffer = runtime->dma_addr;
- chip->cap_pos = 0;
- outl(chip->cap_buffer, FM801_REG(chip, CAP_BUF1));
- outl(chip->cap_buffer + (chip->cap_count % chip->cap_size), FM801_REG(chip, CAP_BUF2));
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static snd_pcm_uframes_t snd_fm801_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct fm801 *chip = snd_pcm_substream_chip(substream);
- size_t ptr;
-
- if (!(chip->ply_ctrl & FM801_START))
- return 0;
- spin_lock(&chip->reg_lock);
- ptr = chip->ply_pos + (chip->ply_count - 1) - inw(FM801_REG(chip, PLY_COUNT));
- if (inw(FM801_REG(chip, IRQ_STATUS)) & FM801_IRQ_PLAYBACK) {
- ptr += chip->ply_count;
- ptr %= chip->ply_size;
- }
- spin_unlock(&chip->reg_lock);
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-static snd_pcm_uframes_t snd_fm801_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct fm801 *chip = snd_pcm_substream_chip(substream);
- size_t ptr;
-
- if (!(chip->cap_ctrl & FM801_START))
- return 0;
- spin_lock(&chip->reg_lock);
- ptr = chip->cap_pos + (chip->cap_count - 1) - inw(FM801_REG(chip, CAP_COUNT));
- if (inw(FM801_REG(chip, IRQ_STATUS)) & FM801_IRQ_CAPTURE) {
- ptr += chip->cap_count;
- ptr %= chip->cap_size;
- }
- spin_unlock(&chip->reg_lock);
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-static irqreturn_t snd_fm801_interrupt(int irq, void *dev_id)
-{
- struct fm801 *chip = dev_id;
- unsigned short status;
- unsigned int tmp;
-
- status = inw(FM801_REG(chip, IRQ_STATUS));
- status &= FM801_IRQ_PLAYBACK|FM801_IRQ_CAPTURE|FM801_IRQ_MPU|FM801_IRQ_VOLUME;
- if (! status)
- return IRQ_NONE;
- /* ack first */
- outw(status, FM801_REG(chip, IRQ_STATUS));
- if (chip->pcm && (status & FM801_IRQ_PLAYBACK) && chip->playback_substream) {
- spin_lock(&chip->reg_lock);
- chip->ply_buf++;
- chip->ply_pos += chip->ply_count;
- chip->ply_pos %= chip->ply_size;
- tmp = chip->ply_pos + chip->ply_count;
- tmp %= chip->ply_size;
- outl(chip->ply_buffer + tmp,
- (chip->ply_buf & 1) ?
- FM801_REG(chip, PLY_BUF1) :
- FM801_REG(chip, PLY_BUF2));
- spin_unlock(&chip->reg_lock);
- snd_pcm_period_elapsed(chip->playback_substream);
- }
- if (chip->pcm && (status & FM801_IRQ_CAPTURE) && chip->capture_substream) {
- spin_lock(&chip->reg_lock);
- chip->cap_buf++;
- chip->cap_pos += chip->cap_count;
- chip->cap_pos %= chip->cap_size;
- tmp = chip->cap_pos + chip->cap_count;
- tmp %= chip->cap_size;
- outl(chip->cap_buffer + tmp,
- (chip->cap_buf & 1) ?
- FM801_REG(chip, CAP_BUF1) :
- FM801_REG(chip, CAP_BUF2));
- spin_unlock(&chip->reg_lock);
- snd_pcm_period_elapsed(chip->capture_substream);
- }
- if (chip->rmidi && (status & FM801_IRQ_MPU))
- snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
- if (status & FM801_IRQ_VOLUME)
- ;/* TODO */
-
- return IRQ_HANDLED;
-}
-
-static struct snd_pcm_hardware snd_fm801_playback =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 5500,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_fm801_capture =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 5500,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static int snd_fm801_playback_open(struct snd_pcm_substream *substream)
-{
- struct fm801 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- chip->playback_substream = substream;
- runtime->hw = snd_fm801_playback;
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &hw_constraints_rates);
- if (chip->multichannel) {
- runtime->hw.channels_max = 6;
- snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- &hw_constraints_channels);
- }
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
- return err;
- return 0;
-}
-
-static int snd_fm801_capture_open(struct snd_pcm_substream *substream)
-{
- struct fm801 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- chip->capture_substream = substream;
- runtime->hw = snd_fm801_capture;
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &hw_constraints_rates);
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
- return err;
- return 0;
-}
-
-static int snd_fm801_playback_close(struct snd_pcm_substream *substream)
-{
- struct fm801 *chip = snd_pcm_substream_chip(substream);
-
- chip->playback_substream = NULL;
- return 0;
-}
-
-static int snd_fm801_capture_close(struct snd_pcm_substream *substream)
-{
- struct fm801 *chip = snd_pcm_substream_chip(substream);
-
- chip->capture_substream = NULL;
- return 0;
-}
-
-static struct snd_pcm_ops snd_fm801_playback_ops = {
- .open = snd_fm801_playback_open,
- .close = snd_fm801_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_fm801_hw_params,
- .hw_free = snd_fm801_hw_free,
- .prepare = snd_fm801_playback_prepare,
- .trigger = snd_fm801_playback_trigger,
- .pointer = snd_fm801_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_fm801_capture_ops = {
- .open = snd_fm801_capture_open,
- .close = snd_fm801_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_fm801_hw_params,
- .hw_free = snd_fm801_hw_free,
- .prepare = snd_fm801_capture_prepare,
- .trigger = snd_fm801_capture_trigger,
- .pointer = snd_fm801_capture_pointer,
-};
-
-static int __devinit snd_fm801_pcm(struct fm801 *chip, int device, struct snd_pcm ** rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
- if ((err = snd_pcm_new(chip->card, "FM801", device, 1, 1, &pcm)) < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_fm801_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_fm801_capture_ops);
-
- pcm->private_data = chip;
- pcm->info_flags = 0;
- strcpy(pcm->name, "FM801");
- chip->pcm = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- chip->multichannel ? 128*1024 : 64*1024, 128*1024);
-
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-/*
- * TEA5757 radio
- */
-
-#ifdef CONFIG_SND_FM801_TEA575X_BOOL
-
-/* GPIO to TEA575x maps */
-struct snd_fm801_tea575x_gpio {
- u8 data, clk, wren, most;
- char *name;
-};
-
-static struct snd_fm801_tea575x_gpio snd_fm801_tea575x_gpios[] = {
- { .data = 1, .clk = 3, .wren = 2, .most = 0, .name = "SF256-PCS" },
- { .data = 1, .clk = 0, .wren = 2, .most = 3, .name = "SF256-PCP" },
- { .data = 2, .clk = 0, .wren = 1, .most = 3, .name = "SF64-PCR" },
-};
-
-#define get_tea575x_gpio(chip) \
- (&snd_fm801_tea575x_gpios[((chip)->tea575x_tuner & TUNER_TYPE_MASK) - 1])
-
-static void snd_fm801_tea575x_set_pins(struct snd_tea575x *tea, u8 pins)
-{
- struct fm801 *chip = tea->private_data;
- unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL));
- struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip);
-
- reg &= ~(FM801_GPIO_GP(gpio.data) |
- FM801_GPIO_GP(gpio.clk) |
- FM801_GPIO_GP(gpio.wren));
-
- reg |= (pins & TEA575X_DATA) ? FM801_GPIO_GP(gpio.data) : 0;
- reg |= (pins & TEA575X_CLK) ? FM801_GPIO_GP(gpio.clk) : 0;
- /* WRITE_ENABLE is inverted */
- reg |= (pins & TEA575X_WREN) ? 0 : FM801_GPIO_GP(gpio.wren);
-
- outw(reg, FM801_REG(chip, GPIO_CTRL));
-}
-
-static u8 snd_fm801_tea575x_get_pins(struct snd_tea575x *tea)
-{
- struct fm801 *chip = tea->private_data;
- unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL));
- struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip);
-
- return (reg & FM801_GPIO_GP(gpio.data)) ? TEA575X_DATA : 0 |
- (reg & FM801_GPIO_GP(gpio.most)) ? TEA575X_MOST : 0;
-}
-
-static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output)
-{
- struct fm801 *chip = tea->private_data;
- unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL));
- struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip);
-
- /* use GPIO lines and set write enable bit */
- reg |= FM801_GPIO_GS(gpio.data) |
- FM801_GPIO_GS(gpio.wren) |
- FM801_GPIO_GS(gpio.clk) |
- FM801_GPIO_GS(gpio.most);
- if (output) {
- /* all of lines are in the write direction */
- /* clear data and clock lines */
- reg &= ~(FM801_GPIO_GD(gpio.data) |
- FM801_GPIO_GD(gpio.wren) |
- FM801_GPIO_GD(gpio.clk) |
- FM801_GPIO_GP(gpio.data) |
- FM801_GPIO_GP(gpio.clk) |
- FM801_GPIO_GP(gpio.wren));
- } else {
- /* use GPIO lines, set data direction to input */
- reg |= FM801_GPIO_GD(gpio.data) |
- FM801_GPIO_GD(gpio.most) |
- FM801_GPIO_GP(gpio.data) |
- FM801_GPIO_GP(gpio.most) |
- FM801_GPIO_GP(gpio.wren);
- /* all of lines are in the write direction, except data */
- /* clear data, write enable and clock lines */
- reg &= ~(FM801_GPIO_GD(gpio.wren) |
- FM801_GPIO_GD(gpio.clk) |
- FM801_GPIO_GP(gpio.clk));
- }
-
- outw(reg, FM801_REG(chip, GPIO_CTRL));
-}
-
-static struct snd_tea575x_ops snd_fm801_tea_ops = {
- .set_pins = snd_fm801_tea575x_set_pins,
- .get_pins = snd_fm801_tea575x_get_pins,
- .set_direction = snd_fm801_tea575x_set_direction,
-};
-#endif
-
-/*
- * Mixer routines
- */
-
-#define FM801_SINGLE(xname, reg, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_fm801_info_single, \
- .get = snd_fm801_get_single, .put = snd_fm801_put_single, \
- .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
-
-static int snd_fm801_info_single(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 16) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_fm801_get_single(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct fm801 *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
-
- ucontrol->value.integer.value[0] = (inw(chip->port + reg) >> shift) & mask;
- if (invert)
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- return 0;
-}
-
-static int snd_fm801_put_single(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct fm801 *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
- unsigned short val;
-
- val = (ucontrol->value.integer.value[0] & mask);
- if (invert)
- val = mask - val;
- return snd_fm801_update_bits(chip, reg, mask << shift, val << shift);
-}
-
-#define FM801_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_fm801_info_double, \
- .get = snd_fm801_get_double, .put = snd_fm801_put_double, \
- .private_value = reg | (shift_left << 8) | (shift_right << 12) | (mask << 16) | (invert << 24) }
-#define FM801_DOUBLE_TLV(xname, reg, shift_left, shift_right, mask, invert, xtlv) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .name = xname, .info = snd_fm801_info_double, \
- .get = snd_fm801_get_double, .put = snd_fm801_put_double, \
- .private_value = reg | (shift_left << 8) | (shift_right << 12) | (mask << 16) | (invert << 24), \
- .tlv = { .p = (xtlv) } }
-
-static int snd_fm801_info_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 16) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_fm801_get_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct fm801 *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift_left = (kcontrol->private_value >> 8) & 0x0f;
- int shift_right = (kcontrol->private_value >> 12) & 0x0f;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
-
- spin_lock_irq(&chip->reg_lock);
- ucontrol->value.integer.value[0] = (inw(chip->port + reg) >> shift_left) & mask;
- ucontrol->value.integer.value[1] = (inw(chip->port + reg) >> shift_right) & mask;
- spin_unlock_irq(&chip->reg_lock);
- if (invert) {
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
- }
- return 0;
-}
-
-static int snd_fm801_put_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct fm801 *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift_left = (kcontrol->private_value >> 8) & 0x0f;
- int shift_right = (kcontrol->private_value >> 12) & 0x0f;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
- unsigned short val1, val2;
-
- val1 = ucontrol->value.integer.value[0] & mask;
- val2 = ucontrol->value.integer.value[1] & mask;
- if (invert) {
- val1 = mask - val1;
- val2 = mask - val2;
- }
- return snd_fm801_update_bits(chip, reg,
- (mask << shift_left) | (mask << shift_right),
- (val1 << shift_left ) | (val2 << shift_right));
-}
-
-static int snd_fm801_info_mux(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[5] = {
- "AC97 Primary", "FM", "I2S", "PCM", "AC97 Secondary"
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 5;
- if (uinfo->value.enumerated.item > 4)
- uinfo->value.enumerated.item = 4;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_fm801_get_mux(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct fm801 *chip = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- val = inw(FM801_REG(chip, REC_SRC)) & 7;
- if (val > 4)
- val = 4;
- ucontrol->value.enumerated.item[0] = val;
- return 0;
-}
-
-static int snd_fm801_put_mux(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct fm801 *chip = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- if ((val = ucontrol->value.enumerated.item[0]) > 4)
- return -EINVAL;
- return snd_fm801_update_bits(chip, FM801_REC_SRC, 7, val);
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_dsp, -3450, 150, 0);
-
-#define FM801_CONTROLS ARRAY_SIZE(snd_fm801_controls)
-
-static struct snd_kcontrol_new snd_fm801_controls[] __devinitdata = {
-FM801_DOUBLE_TLV("Wave Playback Volume", FM801_PCM_VOL, 0, 8, 31, 1,
- db_scale_dsp),
-FM801_SINGLE("Wave Playback Switch", FM801_PCM_VOL, 15, 1, 1),
-FM801_DOUBLE_TLV("I2S Playback Volume", FM801_I2S_VOL, 0, 8, 31, 1,
- db_scale_dsp),
-FM801_SINGLE("I2S Playback Switch", FM801_I2S_VOL, 15, 1, 1),
-FM801_DOUBLE_TLV("FM Playback Volume", FM801_FM_VOL, 0, 8, 31, 1,
- db_scale_dsp),
-FM801_SINGLE("FM Playback Switch", FM801_FM_VOL, 15, 1, 1),
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Digital Capture Source",
- .info = snd_fm801_info_mux,
- .get = snd_fm801_get_mux,
- .put = snd_fm801_put_mux,
-}
-};
-
-#define FM801_CONTROLS_MULTI ARRAY_SIZE(snd_fm801_controls_multi)
-
-static struct snd_kcontrol_new snd_fm801_controls_multi[] __devinitdata = {
-FM801_SINGLE("AC97 2ch->4ch Copy Switch", FM801_CODEC_CTRL, 7, 1, 0),
-FM801_SINGLE("AC97 18-bit Switch", FM801_CODEC_CTRL, 10, 1, 0),
-FM801_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), FM801_I2S_MODE, 8, 1, 0),
-FM801_SINGLE(SNDRV_CTL_NAME_IEC958("Raw Data ",PLAYBACK,SWITCH), FM801_I2S_MODE, 9, 1, 0),
-FM801_SINGLE(SNDRV_CTL_NAME_IEC958("Raw Data ",CAPTURE,SWITCH), FM801_I2S_MODE, 10, 1, 0),
-FM801_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), FM801_GEN_CTRL, 2, 1, 0),
-};
-
-static void snd_fm801_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
-{
- struct fm801 *chip = bus->private_data;
- chip->ac97_bus = NULL;
-}
-
-static void snd_fm801_mixer_free_ac97(struct snd_ac97 *ac97)
-{
- struct fm801 *chip = ac97->private_data;
- if (ac97->num == 0) {
- chip->ac97 = NULL;
- } else {
- chip->ac97_sec = NULL;
- }
-}
-
-static int __devinit snd_fm801_mixer(struct fm801 *chip)
-{
- struct snd_ac97_template ac97;
- unsigned int i;
- int err;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_fm801_codec_write,
- .read = snd_fm801_codec_read,
- };
-
- if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
- return err;
- chip->ac97_bus->private_free = snd_fm801_mixer_free_ac97_bus;
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = chip;
- ac97.private_free = snd_fm801_mixer_free_ac97;
- if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
- return err;
- if (chip->secondary) {
- ac97.num = 1;
- ac97.addr = chip->secondary_addr;
- if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97_sec)) < 0)
- return err;
- }
- for (i = 0; i < FM801_CONTROLS; i++)
- snd_ctl_add(chip->card, snd_ctl_new1(&snd_fm801_controls[i], chip));
- if (chip->multichannel) {
- for (i = 0; i < FM801_CONTROLS_MULTI; i++)
- snd_ctl_add(chip->card, snd_ctl_new1(&snd_fm801_controls_multi[i], chip));
- }
- return 0;
-}
-
-/*
- * initialization routines
- */
-
-static int wait_for_codec(struct fm801 *chip, unsigned int codec_id,
- unsigned short reg, unsigned long waits)
-{
- unsigned long timeout = jiffies + waits;
-
- outw(FM801_AC97_READ | (codec_id << FM801_AC97_ADDR_SHIFT) | reg,
- FM801_REG(chip, AC97_CMD));
- udelay(5);
- do {
- if ((inw(FM801_REG(chip, AC97_CMD)) & (FM801_AC97_VALID|FM801_AC97_BUSY))
- == FM801_AC97_VALID)
- return 0;
- schedule_timeout_uninterruptible(1);
- } while (time_after(timeout, jiffies));
- return -EIO;
-}
-
-static int snd_fm801_chip_init(struct fm801 *chip, int resume)
-{
- unsigned short cmdw;
-
- if (chip->tea575x_tuner & TUNER_ONLY)
- goto __ac97_ok;
-
- /* codec cold reset + AC'97 warm reset */
- outw((1<<5) | (1<<6), FM801_REG(chip, CODEC_CTRL));
- inw(FM801_REG(chip, CODEC_CTRL)); /* flush posting data */
- udelay(100);
- outw(0, FM801_REG(chip, CODEC_CTRL));
-
- if (wait_for_codec(chip, 0, AC97_RESET, msecs_to_jiffies(750)) < 0)
- if (!resume) {
- snd_printk(KERN_INFO "Primary AC'97 codec not found, "
- "assume SF64-PCR (tuner-only)\n");
- chip->tea575x_tuner = 3 | TUNER_ONLY;
- goto __ac97_ok;
- }
-
- if (chip->multichannel) {
- if (chip->secondary_addr) {
- wait_for_codec(chip, chip->secondary_addr,
- AC97_VENDOR_ID1, msecs_to_jiffies(50));
- } else {
- /* my card has the secondary codec */
- /* at address #3, so the loop is inverted */
- int i;
- for (i = 3; i > 0; i--) {
- if (!wait_for_codec(chip, i, AC97_VENDOR_ID1,
- msecs_to_jiffies(50))) {
- cmdw = inw(FM801_REG(chip, AC97_DATA));
- if (cmdw != 0xffff && cmdw != 0) {
- chip->secondary = 1;
- chip->secondary_addr = i;
- break;
- }
- }
- }
- }
-
- /* the recovery phase, it seems that probing for non-existing codec might */
- /* cause timeout problems */
- wait_for_codec(chip, 0, AC97_VENDOR_ID1, msecs_to_jiffies(750));
- }
-
- __ac97_ok:
-
- /* init volume */
- outw(0x0808, FM801_REG(chip, PCM_VOL));
- outw(0x9f1f, FM801_REG(chip, FM_VOL));
- outw(0x8808, FM801_REG(chip, I2S_VOL));
-
- /* I2S control - I2S mode */
- outw(0x0003, FM801_REG(chip, I2S_MODE));
-
- /* interrupt setup */
- cmdw = inw(FM801_REG(chip, IRQ_MASK));
- if (chip->irq < 0)
- cmdw |= 0x00c3; /* mask everything, no PCM nor MPU */
- else
- cmdw &= ~0x0083; /* unmask MPU, PLAYBACK & CAPTURE */
- outw(cmdw, FM801_REG(chip, IRQ_MASK));
-
- /* interrupt clear */
- outw(FM801_IRQ_PLAYBACK|FM801_IRQ_CAPTURE|FM801_IRQ_MPU, FM801_REG(chip, IRQ_STATUS));
-
- return 0;
-}
-
-
-static int snd_fm801_free(struct fm801 *chip)
-{
- unsigned short cmdw;
-
- if (chip->irq < 0)
- goto __end_hw;
-
- /* interrupt setup - mask everything */
- cmdw = inw(FM801_REG(chip, IRQ_MASK));
- cmdw |= 0x00c3;
- outw(cmdw, FM801_REG(chip, IRQ_MASK));
-
- __end_hw:
-#ifdef CONFIG_SND_FM801_TEA575X_BOOL
- if (!(chip->tea575x_tuner & TUNER_DISABLED)) {
- snd_tea575x_exit(&chip->tea);
- v4l2_device_unregister(&chip->v4l2_dev);
- }
-#endif
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
-
- kfree(chip);
- return 0;
-}
-
-static int snd_fm801_dev_free(struct snd_device *device)
-{
- struct fm801 *chip = device->device_data;
- return snd_fm801_free(chip);
-}
-
-static int __devinit snd_fm801_create(struct snd_card *card,
- struct pci_dev * pci,
- int tea575x_tuner,
- int radio_nr,
- struct fm801 ** rchip)
-{
- struct fm801 *chip;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_fm801_dev_free,
- };
-
- *rchip = NULL;
- if ((err = pci_enable_device(pci)) < 0)
- return err;
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
- spin_lock_init(&chip->reg_lock);
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
- chip->tea575x_tuner = tea575x_tuner;
- if ((err = pci_request_regions(pci, "FM801")) < 0) {
- kfree(chip);
- pci_disable_device(pci);
- return err;
- }
- chip->port = pci_resource_start(pci, 0);
- if ((tea575x_tuner & TUNER_ONLY) == 0) {
- if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq);
- snd_fm801_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
- pci_set_master(pci);
- }
-
- if (pci->revision >= 0xb1) /* FM801-AU */
- chip->multichannel = 1;
-
- snd_fm801_chip_init(chip, 0);
- /* init might set tuner access method */
- tea575x_tuner = chip->tea575x_tuner;
-
- if (chip->irq >= 0 && (tea575x_tuner & TUNER_ONLY)) {
- pci_clear_master(pci);
- free_irq(chip->irq, chip);
- chip->irq = -1;
- }
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_fm801_free(chip);
- return err;
- }
-
- snd_card_set_dev(card, &pci->dev);
-
-#ifdef CONFIG_SND_FM801_TEA575X_BOOL
- err = v4l2_device_register(&pci->dev, &chip->v4l2_dev);
- if (err < 0) {
- snd_fm801_free(chip);
- return err;
- }
- chip->tea.v4l2_dev = &chip->v4l2_dev;
- chip->tea.radio_nr = radio_nr;
- chip->tea.private_data = chip;
- chip->tea.ops = &snd_fm801_tea_ops;
- sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
- if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 &&
- (tea575x_tuner & TUNER_TYPE_MASK) < 4) {
- if (snd_tea575x_init(&chip->tea)) {
- snd_printk(KERN_ERR "TEA575x radio not found\n");
- snd_fm801_free(chip);
- return -ENODEV;
- }
- } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) {
- /* autodetect tuner connection */
- for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) {
- chip->tea575x_tuner = tea575x_tuner;
- if (!snd_tea575x_init(&chip->tea)) {
- snd_printk(KERN_INFO "detected TEA575x radio type %s\n",
- get_tea575x_gpio(chip)->name);
- break;
- }
- }
- if (tea575x_tuner == 4) {
- snd_printk(KERN_ERR "TEA575x radio not found\n");
- chip->tea575x_tuner = TUNER_DISABLED;
- }
- }
- if (!(chip->tea575x_tuner & TUNER_DISABLED)) {
- strlcpy(chip->tea.card, get_tea575x_gpio(chip)->name,
- sizeof(chip->tea.card));
- }
-#endif
-
- *rchip = chip;
- return 0;
-}
-
-static int __devinit snd_card_fm801_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct fm801 *chip;
- struct snd_opl3 *opl3;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
- if ((err = snd_fm801_create(card, pci, tea575x_tuner[dev], radio_nr[dev], &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
- card->private_data = chip;
-
- strcpy(card->driver, "FM801");
- strcpy(card->shortname, "ForteMedia FM801-");
- strcat(card->shortname, chip->multichannel ? "AU" : "AS");
- sprintf(card->longname, "%s at 0x%lx, irq %i",
- card->shortname, chip->port, chip->irq);
-
- if (chip->tea575x_tuner & TUNER_ONLY)
- goto __fm801_tuner_only;
-
- if ((err = snd_fm801_pcm(chip, 0, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_fm801_mixer(chip)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_FM801,
- FM801_REG(chip, MPU401_DATA),
- MPU401_INFO_INTEGRATED |
- MPU401_INFO_IRQ_HOOK,
- -1, &chip->rmidi)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_opl3_create(card, FM801_REG(chip, OPL3_BANK0),
- FM801_REG(chip, OPL3_BANK1),
- OPL3_HW_OPL3_FM801, 1, &opl3)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- __fm801_tuner_only:
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_card_fm801_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-#ifdef CONFIG_PM
-static unsigned char saved_regs[] = {
- FM801_PCM_VOL, FM801_I2S_VOL, FM801_FM_VOL, FM801_REC_SRC,
- FM801_PLY_CTRL, FM801_PLY_COUNT, FM801_PLY_BUF1, FM801_PLY_BUF2,
- FM801_CAP_CTRL, FM801_CAP_COUNT, FM801_CAP_BUF1, FM801_CAP_BUF2,
- FM801_CODEC_CTRL, FM801_I2S_MODE, FM801_VOLUME, FM801_GEN_CTRL,
-};
-
-static int snd_fm801_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct fm801 *chip = card->private_data;
- int i;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(chip->pcm);
- snd_ac97_suspend(chip->ac97);
- snd_ac97_suspend(chip->ac97_sec);
- for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
- chip->saved_regs[i] = inw(chip->port + saved_regs[i]);
- /* FIXME: tea575x suspend */
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int snd_fm801_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct fm801 *chip = card->private_data;
- int i;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "fm801: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
-
- snd_fm801_chip_init(chip, 1);
- snd_ac97_resume(chip->ac97);
- snd_ac97_resume(chip->ac97_sec);
- for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
- outw(chip->saved_regs[i], chip->port + saved_regs[i]);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_fm801_ids,
- .probe = snd_card_fm801_probe,
- .remove = __devexit_p(snd_card_fm801_remove),
-#ifdef CONFIG_PM
- .suspend = snd_fm801_suspend,
- .resume = snd_fm801_resume,
-#endif
-};
-
-static int __init alsa_card_fm801_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_fm801_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_fm801_init)
-module_exit(alsa_card_fm801_exit)
diff --git a/ANDROID_3.4.5/sound/pci/hda/Kconfig b/ANDROID_3.4.5/sound/pci/hda/Kconfig
deleted file mode 100644
index 163b6b5d..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/Kconfig
+++ /dev/null
@@ -1,261 +0,0 @@
-menuconfig SND_HDA_INTEL
- tristate "Intel HD Audio"
- select SND_PCM
- select SND_VMASTER
- select SND_KCTL_JACK
- help
- Say Y here to include support for Intel "High Definition
- Audio" (Azalia) and its compatible devices.
-
- This option enables the HD-audio controller. Don't forget
- to choose the appropriate codec options below.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-hda-intel.
-
-if SND_HDA_INTEL
-
-config SND_HDA_PREALLOC_SIZE
- int "Pre-allocated buffer size for HD-audio driver"
- range 0 32768
- default 64
- help
- Specifies the default pre-allocated buffer-size in kB for the
- HD-audio driver. A larger buffer (e.g. 2048) is preferred
- for systems using PulseAudio. The default 64 is chosen just
- for compatibility reasons.
-
- Note that the pre-allocation size can be changed dynamically
- via a proc file (/proc/asound/card*/pcm*/sub*/prealloc), too.
-
-config SND_HDA_HWDEP
- bool "Build hwdep interface for HD-audio driver"
- select SND_HWDEP
- help
- Say Y here to build a hwdep interface for HD-audio driver.
- This interface can be used for out-of-band communication
- with codecs for debugging purposes.
-
-config SND_HDA_RECONFIG
- bool "Allow dynamic codec reconfiguration (EXPERIMENTAL)"
- depends on SND_HDA_HWDEP && EXPERIMENTAL
- help
- Say Y here to enable the HD-audio codec re-configuration feature.
- This adds the sysfs interfaces to allow user to clear the whole
- codec configuration, change the codec setup, add extra verbs,
- and re-configure the codec dynamically.
-
-config SND_HDA_INPUT_BEEP
- bool "Support digital beep via input layer"
- depends on INPUT=y || INPUT=SND_HDA_INTEL
- help
- Say Y here to build a digital beep interface for HD-audio
- driver. This interface is used to generate digital beeps.
-
-config SND_HDA_INPUT_BEEP_MODE
- int "Digital beep registration mode (0=off, 1=on, 2=mute sw on/off)"
- depends on SND_HDA_INPUT_BEEP=y
- default "1"
- range 0 2
- help
- Set 0 to disable the digital beep interface for HD-audio by default.
- Set 1 to always enable the digital beep interface for HD-audio by
- default. Set 2 to control the beep device registration to input
- layer using a "Beep Switch" in mixer applications.
-
-config SND_HDA_INPUT_JACK
- bool "Support jack plugging notification via input layer"
- depends on INPUT=y || INPUT=SND
- select SND_JACK
- help
- Say Y here to enable the jack plugging notification via
- input layer.
-
-config SND_HDA_PATCH_LOADER
- bool "Support initialization patch loading for HD-audio"
- depends on EXPERIMENTAL
- select FW_LOADER
- select SND_HDA_HWDEP
- select SND_HDA_RECONFIG
- help
- Say Y here to allow the HD-audio driver to load a pseudo
- firmware file ("patch") for overriding the BIOS setup at
- start up. The "patch" file can be specified via patch module
- option, such as patch=hda-init.
-
- This option turns on hwdep and reconfig features automatically.
-
-config SND_HDA_CODEC_REALTEK
- bool "Build Realtek HD-audio codec support"
- default y
- help
- Say Y here to include Realtek HD-audio codec support in
- snd-hda-intel driver, such as ALC880.
-
- When the HD-audio driver is built as a module, the codec
- support code is also built as another module,
- snd-hda-codec-realtek.
- This module is automatically loaded at probing.
-
-config SND_HDA_ENABLE_REALTEK_QUIRKS
- bool "Build static quirks for Realtek codecs"
- depends on SND_HDA_CODEC_REALTEK
- default y
- help
- Say Y here to build the static quirks codes for Realtek codecs.
- If you need the "model" preset that the default BIOS auto-parser
- can't handle, turn this option on.
-
- If your device works with model=auto option, basically you don't
- need the quirk code. By turning this off, you can reduce the
- module size quite a lot.
-
-config SND_HDA_CODEC_ANALOG
- bool "Build Analog Device HD-audio codec support"
- default y
- help
- Say Y here to include Analog Device HD-audio codec support in
- snd-hda-intel driver, such as AD1986A.
-
- When the HD-audio driver is built as a module, the codec
- support code is also built as another module,
- snd-hda-codec-analog.
- This module is automatically loaded at probing.
-
-config SND_HDA_CODEC_SIGMATEL
- bool "Build IDT/Sigmatel HD-audio codec support"
- default y
- help
- Say Y here to include IDT (Sigmatel) HD-audio codec support in
- snd-hda-intel driver, such as STAC9200.
-
- When the HD-audio driver is built as a module, the codec
- support code is also built as another module,
- snd-hda-codec-idt.
- This module is automatically loaded at probing.
-
-config SND_HDA_CODEC_VIA
- bool "Build VIA HD-audio codec support"
- default y
- help
- Say Y here to include VIA HD-audio codec support in
- snd-hda-intel driver, such as VT1708.
-
- When the HD-audio driver is built as a module, the codec
- support code is also built as another module,
- snd-hda-codec-via.
- This module is automatically loaded at probing.
-
-config SND_HDA_CODEC_HDMI
- bool "Build HDMI/DisplayPort HD-audio codec support"
- select SND_DYNAMIC_MINORS
- default y
- help
- Say Y here to include HDMI and DisplayPort HD-audio codec
- support in snd-hda-intel driver. This includes all AMD/ATI,
- Intel and Nvidia HDMI/DisplayPort codecs.
-
- When the HD-audio driver is built as a module, the codec
- support code is also built as another module,
- snd-hda-codec-hdmi.
- This module is automatically loaded at probing.
-
-config SND_HDA_CODEC_CIRRUS
- bool "Build Cirrus Logic codec support"
- depends on SND_HDA_INTEL
- default y
- help
- Say Y here to include Cirrus Logic codec support in
- snd-hda-intel driver, such as CS4206.
-
- When the HD-audio driver is built as a module, the codec
- support code is also built as another module,
- snd-hda-codec-cirrus.
- This module is automatically loaded at probing.
-
-config SND_HDA_CODEC_CONEXANT
- bool "Build Conexant HD-audio codec support"
- default y
- help
- Say Y here to include Conexant HD-audio codec support in
- snd-hda-intel driver, such as CX20549.
-
- When the HD-audio driver is built as a module, the codec
- support code is also built as another module,
- snd-hda-codec-conexant.
- This module is automatically loaded at probing.
-
-config SND_HDA_CODEC_CA0110
- bool "Build Creative CA0110-IBG codec support"
- depends on SND_HDA_INTEL
- default y
- help
- Say Y here to include Creative CA0110-IBG codec support in
- snd-hda-intel driver, found on some Creative X-Fi cards.
-
- When the HD-audio driver is built as a module, the codec
- support code is also built as another module,
- snd-hda-codec-ca0110.
- This module is automatically loaded at probing.
-
-config SND_HDA_CODEC_CA0132
- bool "Build Creative CA0132 codec support"
- depends on SND_HDA_INTEL
- default y
- help
- Say Y here to include Creative CA0132 codec support in
- snd-hda-intel driver.
-
- When the HD-audio driver is built as a module, the codec
- support code is also built as another module,
- snd-hda-codec-ca0132.
- This module is automatically loaded at probing.
-
-config SND_HDA_CODEC_CMEDIA
- bool "Build C-Media HD-audio codec support"
- default y
- help
- Say Y here to include C-Media HD-audio codec support in
- snd-hda-intel driver, such as CMI9880.
-
- When the HD-audio driver is built as a module, the codec
- support code is also built as another module,
- snd-hda-codec-cmedia.
- This module is automatically loaded at probing.
-
-config SND_HDA_CODEC_SI3054
- bool "Build Silicon Labs 3054 HD-modem codec support"
- default y
- help
- Say Y here to include Silicon Labs 3054 HD-modem codec
- (and compatibles) support in snd-hda-intel driver.
-
- When the HD-audio driver is built as a module, the codec
- support code is also built as another module,
- snd-hda-codec-si3054.
- This module is automatically loaded at probing.
-
-config SND_HDA_GENERIC
- bool "Enable generic HD-audio codec parser"
- default y
- help
- Say Y here to enable the generic HD-audio codec parser
- in snd-hda-intel driver.
-
-config SND_HDA_POWER_SAVE
- bool "Aggressive power-saving on HD-audio"
- depends on PM
- help
- Say Y here to enable more aggressive power-saving mode on
- HD-audio driver. The power-saving timeout can be configured
- via power_save option or over sysfs on-the-fly.
-
-config SND_HDA_POWER_SAVE_DEFAULT
- int "Default time-out for HD-audio power-save mode"
- depends on SND_HDA_POWER_SAVE
- default 0
- help
- The default time-out value in seconds for HD-audio automatic
- power-save mode. 0 means to disable the power-save mode.
-
-endif
diff --git a/ANDROID_3.4.5/sound/pci/hda/Makefile b/ANDROID_3.4.5/sound/pci/hda/Makefile
deleted file mode 100644
index ace157cc..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/Makefile
+++ /dev/null
@@ -1,65 +0,0 @@
-snd-hda-intel-objs := hda_intel.o
-
-snd-hda-codec-y := hda_codec.o hda_jack.o
-snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
-snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o
-snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
-snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
-
-# for trace-points
-CFLAGS_hda_codec.o := -I$(src)
-
-snd-hda-codec-realtek-objs := patch_realtek.o
-snd-hda-codec-cmedia-objs := patch_cmedia.o
-snd-hda-codec-analog-objs := patch_analog.o
-snd-hda-codec-idt-objs := patch_sigmatel.o
-snd-hda-codec-si3054-objs := patch_si3054.o
-snd-hda-codec-cirrus-objs := patch_cirrus.o
-snd-hda-codec-ca0110-objs := patch_ca0110.o
-snd-hda-codec-ca0132-objs := patch_ca0132.o
-snd-hda-codec-conexant-objs := patch_conexant.o
-snd-hda-codec-via-objs := patch_via.o
-snd-hda-codec-hdmi-objs := patch_hdmi.o hda_eld.o
-
-# common driver
-obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o
-
-# codec drivers (note: CONFIG_SND_HDA_CODEC_XXX are booleans)
-ifdef CONFIG_SND_HDA_CODEC_REALTEK
-obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-realtek.o
-endif
-ifdef CONFIG_SND_HDA_CODEC_CMEDIA
-obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-cmedia.o
-endif
-ifdef CONFIG_SND_HDA_CODEC_ANALOG
-obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-analog.o
-endif
-ifdef CONFIG_SND_HDA_CODEC_SIGMATEL
-obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-idt.o
-endif
-ifdef CONFIG_SND_HDA_CODEC_SI3054
-obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-si3054.o
-endif
-ifdef CONFIG_SND_HDA_CODEC_CIRRUS
-obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-cirrus.o
-endif
-ifdef CONFIG_SND_HDA_CODEC_CA0110
-obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0110.o
-endif
-ifdef CONFIG_SND_HDA_CODEC_CA0132
-obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0132.o
-endif
-ifdef CONFIG_SND_HDA_CODEC_CONEXANT
-obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-conexant.o
-endif
-ifdef CONFIG_SND_HDA_CODEC_VIA
-obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-via.o
-endif
-ifdef CONFIG_SND_HDA_CODEC_HDMI
-obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-hdmi.o
-endif
-
-# this must be the last entry after codec drivers;
-# otherwise the codec patches won't be hooked before the PCI probe
-# when built in kernel
-obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o
diff --git a/ANDROID_3.4.5/sound/pci/hda/hda_beep.c b/ANDROID_3.4.5/sound/pci/hda/hda_beep.c
deleted file mode 100644
index 60738e52..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/hda_beep.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Digital Beep Input Interface for HD-audio codec
- *
- * Author: Matthew Ranostay <mranostay@embeddedalley.com>
- * Copyright (c) 2008 Embedded Alley Solutions Inc
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/input.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <linux/export.h>
-#include <sound/core.h>
-#include "hda_beep.h"
-#include "hda_local.h"
-
-enum {
- DIGBEEP_HZ_STEP = 46875, /* 46.875 Hz */
- DIGBEEP_HZ_MIN = 93750, /* 93.750 Hz */
- DIGBEEP_HZ_MAX = 12000000, /* 12 KHz */
-};
-
-static void snd_hda_generate_beep(struct work_struct *work)
-{
- struct hda_beep *beep =
- container_of(work, struct hda_beep, beep_work);
- struct hda_codec *codec = beep->codec;
-
- if (!beep->enabled)
- return;
-
- /* generate tone */
- snd_hda_codec_write(codec, beep->nid, 0,
- AC_VERB_SET_BEEP_CONTROL, beep->tone);
-}
-
-/* (non-standard) Linear beep tone calculation for IDT/STAC codecs
- *
- * The tone frequency of beep generator on IDT/STAC codecs is
- * defined from the 8bit tone parameter, in Hz,
- * freq = 48000 * (257 - tone) / 1024
- * that is from 12kHz to 93.75Hz in steps of 46.875 Hz
- */
-static int beep_linear_tone(struct hda_beep *beep, int hz)
-{
- if (hz <= 0)
- return 0;
- hz *= 1000; /* fixed point */
- hz = hz - DIGBEEP_HZ_MIN
- + DIGBEEP_HZ_STEP / 2; /* round to nearest step */
- if (hz < 0)
- hz = 0; /* turn off PC beep*/
- else if (hz >= (DIGBEEP_HZ_MAX - DIGBEEP_HZ_MIN))
- hz = 1; /* max frequency */
- else {
- hz /= DIGBEEP_HZ_STEP;
- hz = 255 - hz;
- }
- return hz;
-}
-
-/* HD-audio standard beep tone parameter calculation
- *
- * The tone frequency in Hz is calculated as
- * freq = 48000 / (tone * 4)
- * from 47Hz to 12kHz
- */
-static int beep_standard_tone(struct hda_beep *beep, int hz)
-{
- if (hz <= 0)
- return 0; /* disabled */
- hz = 12000 / hz;
- if (hz > 0xff)
- return 0xff;
- if (hz <= 0)
- return 1;
- return hz;
-}
-
-static int snd_hda_beep_event(struct input_dev *dev, unsigned int type,
- unsigned int code, int hz)
-{
- struct hda_beep *beep = input_get_drvdata(dev);
-
- switch (code) {
- case SND_BELL:
- if (hz)
- hz = 1000;
- case SND_TONE:
- if (beep->linear_tone)
- beep->tone = beep_linear_tone(beep, hz);
- else
- beep->tone = beep_standard_tone(beep, hz);
- break;
- default:
- return -1;
- }
-
- /* schedule beep event */
- schedule_work(&beep->beep_work);
- return 0;
-}
-
-static void snd_hda_do_detach(struct hda_beep *beep)
-{
- input_unregister_device(beep->dev);
- beep->dev = NULL;
- cancel_work_sync(&beep->beep_work);
- /* turn off beep for sure */
- snd_hda_codec_write(beep->codec, beep->nid, 0,
- AC_VERB_SET_BEEP_CONTROL, 0);
-}
-
-static int snd_hda_do_attach(struct hda_beep *beep)
-{
- struct input_dev *input_dev;
- struct hda_codec *codec = beep->codec;
- int err;
-
- input_dev = input_allocate_device();
- if (!input_dev) {
- printk(KERN_INFO "hda_beep: unable to allocate input device\n");
- return -ENOMEM;
- }
-
- /* setup digital beep device */
- input_dev->name = "HDA Digital PCBeep";
- input_dev->phys = beep->phys;
- input_dev->id.bustype = BUS_PCI;
-
- input_dev->id.vendor = codec->vendor_id >> 16;
- input_dev->id.product = codec->vendor_id & 0xffff;
- input_dev->id.version = 0x01;
-
- input_dev->evbit[0] = BIT_MASK(EV_SND);
- input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
- input_dev->event = snd_hda_beep_event;
- input_dev->dev.parent = &codec->bus->pci->dev;
- input_set_drvdata(input_dev, beep);
-
- err = input_register_device(input_dev);
- if (err < 0) {
- input_free_device(input_dev);
- printk(KERN_INFO "hda_beep: unable to register input device\n");
- return err;
- }
- beep->dev = input_dev;
- return 0;
-}
-
-static void snd_hda_do_register(struct work_struct *work)
-{
- struct hda_beep *beep =
- container_of(work, struct hda_beep, register_work);
-
- mutex_lock(&beep->mutex);
- if (beep->enabled && !beep->dev)
- snd_hda_do_attach(beep);
- mutex_unlock(&beep->mutex);
-}
-
-static void snd_hda_do_unregister(struct work_struct *work)
-{
- struct hda_beep *beep =
- container_of(work, struct hda_beep, unregister_work.work);
-
- mutex_lock(&beep->mutex);
- if (!beep->enabled && beep->dev)
- snd_hda_do_detach(beep);
- mutex_unlock(&beep->mutex);
-}
-
-int snd_hda_enable_beep_device(struct hda_codec *codec, int enable)
-{
- struct hda_beep *beep = codec->beep;
- enable = !!enable;
- if (beep == NULL)
- return 0;
- if (beep->enabled != enable) {
- beep->enabled = enable;
- if (!enable) {
- /* turn off beep */
- snd_hda_codec_write(beep->codec, beep->nid, 0,
- AC_VERB_SET_BEEP_CONTROL, 0);
- }
- if (beep->mode == HDA_BEEP_MODE_SWREG) {
- if (enable) {
- cancel_delayed_work(&beep->unregister_work);
- schedule_work(&beep->register_work);
- } else {
- schedule_delayed_work(&beep->unregister_work,
- HZ);
- }
- }
- return 1;
- }
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_enable_beep_device);
-
-int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
-{
- struct hda_beep *beep;
-
- if (!snd_hda_get_bool_hint(codec, "beep"))
- return 0; /* disabled explicitly by hints */
- if (codec->beep_mode == HDA_BEEP_MODE_OFF)
- return 0; /* disabled by module option */
-
- beep = kzalloc(sizeof(*beep), GFP_KERNEL);
- if (beep == NULL)
- return -ENOMEM;
- snprintf(beep->phys, sizeof(beep->phys),
- "card%d/codec#%d/beep0", codec->bus->card->number, codec->addr);
- /* enable linear scale */
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_DIGI_CONVERT_2, 0x01);
-
- beep->nid = nid;
- beep->codec = codec;
- beep->mode = codec->beep_mode;
- codec->beep = beep;
-
- INIT_WORK(&beep->register_work, &snd_hda_do_register);
- INIT_DELAYED_WORK(&beep->unregister_work, &snd_hda_do_unregister);
- INIT_WORK(&beep->beep_work, &snd_hda_generate_beep);
- mutex_init(&beep->mutex);
-
- if (beep->mode == HDA_BEEP_MODE_ON) {
- int err = snd_hda_do_attach(beep);
- if (err < 0) {
- kfree(beep);
- codec->beep = NULL;
- return err;
- }
- }
-
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_attach_beep_device);
-
-void snd_hda_detach_beep_device(struct hda_codec *codec)
-{
- struct hda_beep *beep = codec->beep;
- if (beep) {
- cancel_work_sync(&beep->register_work);
- cancel_delayed_work(&beep->unregister_work);
- if (beep->dev)
- snd_hda_do_detach(beep);
- codec->beep = NULL;
- kfree(beep);
- }
-}
-EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device);
diff --git a/ANDROID_3.4.5/sound/pci/hda/hda_beep.h b/ANDROID_3.4.5/sound/pci/hda/hda_beep.h
deleted file mode 100644
index 55f06474..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/hda_beep.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Digital Beep Input Interface for HD-audio codec
- *
- * Author: Matthew Ranostay <mranostay@embeddedalley.com>
- * Copyright (c) 2008 Embedded Alley Solutions Inc
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __SOUND_HDA_BEEP_H
-#define __SOUND_HDA_BEEP_H
-
-#include "hda_codec.h"
-
-#define HDA_BEEP_MODE_OFF 0
-#define HDA_BEEP_MODE_ON 1
-#define HDA_BEEP_MODE_SWREG 2
-
-/* beep information */
-struct hda_beep {
- struct input_dev *dev;
- struct hda_codec *codec;
- unsigned int mode;
- char phys[32];
- int tone;
- hda_nid_t nid;
- unsigned int enabled:1;
- unsigned int request_enable:1;
- unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */
- struct work_struct register_work; /* registration work */
- struct delayed_work unregister_work; /* unregistration work */
- struct work_struct beep_work; /* scheduled task for beep event */
- struct mutex mutex;
-};
-
-#ifdef CONFIG_SND_HDA_INPUT_BEEP
-int snd_hda_enable_beep_device(struct hda_codec *codec, int enable);
-int snd_hda_attach_beep_device(struct hda_codec *codec, int nid);
-void snd_hda_detach_beep_device(struct hda_codec *codec);
-#else
-static inline int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
-{
- return 0;
-}
-static inline void snd_hda_detach_beep_device(struct hda_codec *codec)
-{
-}
-#endif
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/hda/hda_codec.c b/ANDROID_3.4.5/sound/pci/hda/hda_codec.c
deleted file mode 100644
index 926b4553..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/hda_codec.c
+++ /dev/null
@@ -1,5548 +0,0 @@
-/*
- * Universal Interface for Intel High Definition Audio Codec
- *
- * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
- *
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/mutex.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include "hda_codec.h"
-#include <sound/asoundef.h>
-#include <sound/tlv.h>
-#include <sound/initval.h>
-#include <sound/jack.h>
-#include "hda_local.h"
-#include "hda_beep.h"
-#include "hda_jack.h"
-#include <sound/hda_hwdep.h>
-
-#define CREATE_TRACE_POINTS
-#include "hda_trace.h"
-
-/*
- * vendor / preset table
- */
-
-struct hda_vendor_id {
- unsigned int id;
- const char *name;
-};
-
-/* codec vendor labels */
-static struct hda_vendor_id hda_vendor_ids[] = {
- { 0x1002, "ATI" },
- { 0x1013, "Cirrus Logic" },
- { 0x1057, "Motorola" },
- { 0x1095, "Silicon Image" },
- { 0x10de, "Nvidia" },
- { 0x10ec, "Realtek" },
- { 0x1102, "Creative" },
- { 0x1106, "VIA" },
- { 0x111d, "IDT" },
- { 0x11c1, "LSI" },
- { 0x11d4, "Analog Devices" },
- { 0x13f6, "C-Media" },
- { 0x14f1, "Conexant" },
- { 0x17e8, "Chrontel" },
- { 0x1854, "LG" },
- { 0x1aec, "Wolfson Microelectronics" },
- { 0x434d, "C-Media" },
- { 0x8086, "Intel" },
- { 0x8384, "SigmaTel" },
- {} /* terminator */
-};
-
-static DEFINE_MUTEX(preset_mutex);
-static LIST_HEAD(hda_preset_tables);
-
-int snd_hda_add_codec_preset(struct hda_codec_preset_list *preset)
-{
- mutex_lock(&preset_mutex);
- list_add_tail(&preset->list, &hda_preset_tables);
- mutex_unlock(&preset_mutex);
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_add_codec_preset);
-
-int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset)
-{
- mutex_lock(&preset_mutex);
- list_del(&preset->list);
- mutex_unlock(&preset_mutex);
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset);
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static void hda_power_work(struct work_struct *work);
-static void hda_keep_power_on(struct hda_codec *codec);
-#define hda_codec_is_power_on(codec) ((codec)->power_on)
-#else
-static inline void hda_keep_power_on(struct hda_codec *codec) {}
-#define hda_codec_is_power_on(codec) 1
-#endif
-
-/**
- * snd_hda_get_jack_location - Give a location string of the jack
- * @cfg: pin default config value
- *
- * Parse the pin default config value and returns the string of the
- * jack location, e.g. "Rear", "Front", etc.
- */
-const char *snd_hda_get_jack_location(u32 cfg)
-{
- static char *bases[7] = {
- "N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom",
- };
- static unsigned char specials_idx[] = {
- 0x07, 0x08,
- 0x17, 0x18, 0x19,
- 0x37, 0x38
- };
- static char *specials[] = {
- "Rear Panel", "Drive Bar",
- "Riser", "HDMI", "ATAPI",
- "Mobile-In", "Mobile-Out"
- };
- int i;
- cfg = (cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT;
- if ((cfg & 0x0f) < 7)
- return bases[cfg & 0x0f];
- for (i = 0; i < ARRAY_SIZE(specials_idx); i++) {
- if (cfg == specials_idx[i])
- return specials[i];
- }
- return "UNKNOWN";
-}
-EXPORT_SYMBOL_HDA(snd_hda_get_jack_location);
-
-/**
- * snd_hda_get_jack_connectivity - Give a connectivity string of the jack
- * @cfg: pin default config value
- *
- * Parse the pin default config value and returns the string of the
- * jack connectivity, i.e. external or internal connection.
- */
-const char *snd_hda_get_jack_connectivity(u32 cfg)
-{
- static char *jack_locations[4] = { "Ext", "Int", "Sep", "Oth" };
-
- return jack_locations[(cfg >> (AC_DEFCFG_LOCATION_SHIFT + 4)) & 3];
-}
-EXPORT_SYMBOL_HDA(snd_hda_get_jack_connectivity);
-
-/**
- * snd_hda_get_jack_type - Give a type string of the jack
- * @cfg: pin default config value
- *
- * Parse the pin default config value and returns the string of the
- * jack type, i.e. the purpose of the jack, such as Line-Out or CD.
- */
-const char *snd_hda_get_jack_type(u32 cfg)
-{
- static char *jack_types[16] = {
- "Line Out", "Speaker", "HP Out", "CD",
- "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
- "Line In", "Aux", "Mic", "Telephony",
- "SPDIF In", "Digitial In", "Reserved", "Other"
- };
-
- return jack_types[(cfg & AC_DEFCFG_DEVICE)
- >> AC_DEFCFG_DEVICE_SHIFT];
-}
-EXPORT_SYMBOL_HDA(snd_hda_get_jack_type);
-
-/*
- * Compose a 32bit command word to be sent to the HD-audio controller
- */
-static inline unsigned int
-make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
- unsigned int verb, unsigned int parm)
-{
- u32 val;
-
- if ((codec->addr & ~0xf) || (direct & ~1) || (nid & ~0x7f) ||
- (verb & ~0xfff) || (parm & ~0xffff)) {
- printk(KERN_ERR "hda-codec: out of range cmd %x:%x:%x:%x:%x\n",
- codec->addr, direct, nid, verb, parm);
- return ~0;
- }
-
- val = (u32)codec->addr << 28;
- val |= (u32)direct << 27;
- val |= (u32)nid << 20;
- val |= verb << 8;
- val |= parm;
- return val;
-}
-
-/*
- * Send and receive a verb
- */
-static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
- unsigned int *res)
-{
- struct hda_bus *bus = codec->bus;
- int err;
-
- if (cmd == ~0)
- return -1;
-
- if (res)
- *res = -1;
- again:
- snd_hda_power_up(codec);
- mutex_lock(&bus->cmd_mutex);
- trace_hda_send_cmd(codec, cmd);
- err = bus->ops.command(bus, cmd);
- if (!err && res) {
- *res = bus->ops.get_response(bus, codec->addr);
- trace_hda_get_response(codec, *res);
- }
- mutex_unlock(&bus->cmd_mutex);
- snd_hda_power_down(codec);
- if (res && *res == -1 && bus->rirb_error) {
- if (bus->response_reset) {
- snd_printd("hda_codec: resetting BUS due to "
- "fatal communication error\n");
- trace_hda_bus_reset(bus);
- bus->ops.bus_reset(bus);
- }
- goto again;
- }
- /* clear reset-flag when the communication gets recovered */
- if (!err)
- bus->response_reset = 0;
- return err;
-}
-
-/**
- * snd_hda_codec_read - send a command and get the response
- * @codec: the HDA codec
- * @nid: NID to send the command
- * @direct: direct flag
- * @verb: the verb to send
- * @parm: the parameter for the verb
- *
- * Send a single command and read the corresponding response.
- *
- * Returns the obtained response value, or -1 for an error.
- */
-unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
- int direct,
- unsigned int verb, unsigned int parm)
-{
- unsigned cmd = make_codec_cmd(codec, nid, direct, verb, parm);
- unsigned int res;
- if (codec_exec_verb(codec, cmd, &res))
- return -1;
- return res;
-}
-EXPORT_SYMBOL_HDA(snd_hda_codec_read);
-
-/**
- * snd_hda_codec_write - send a single command without waiting for response
- * @codec: the HDA codec
- * @nid: NID to send the command
- * @direct: direct flag
- * @verb: the verb to send
- * @parm: the parameter for the verb
- *
- * Send a single command without waiting for response.
- *
- * Returns 0 if successful, or a negative error code.
- */
-int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
- unsigned int verb, unsigned int parm)
-{
- unsigned int cmd = make_codec_cmd(codec, nid, direct, verb, parm);
- unsigned int res;
- return codec_exec_verb(codec, cmd,
- codec->bus->sync_write ? &res : NULL);
-}
-EXPORT_SYMBOL_HDA(snd_hda_codec_write);
-
-/**
- * snd_hda_sequence_write - sequence writes
- * @codec: the HDA codec
- * @seq: VERB array to send
- *
- * Send the commands sequentially from the given array.
- * The array must be terminated with NID=0.
- */
-void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq)
-{
- for (; seq->nid; seq++)
- snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param);
-}
-EXPORT_SYMBOL_HDA(snd_hda_sequence_write);
-
-/**
- * snd_hda_get_sub_nodes - get the range of sub nodes
- * @codec: the HDA codec
- * @nid: NID to parse
- * @start_id: the pointer to store the start NID
- *
- * Parse the NID and store the start NID of its sub-nodes.
- * Returns the number of sub-nodes.
- */
-int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
- hda_nid_t *start_id)
-{
- unsigned int parm;
-
- parm = snd_hda_param_read(codec, nid, AC_PAR_NODE_COUNT);
- if (parm == -1)
- return 0;
- *start_id = (parm >> 16) & 0x7fff;
- return (int)(parm & 0x7fff);
-}
-EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes);
-
-/* look up the cached results */
-static hda_nid_t *lookup_conn_list(struct snd_array *array, hda_nid_t nid)
-{
- int i, len;
- for (i = 0; i < array->used; ) {
- hda_nid_t *p = snd_array_elem(array, i);
- if (nid == *p)
- return p;
- len = p[1];
- i += len + 2;
- }
- return NULL;
-}
-
-/**
- * snd_hda_get_conn_list - get connection list
- * @codec: the HDA codec
- * @nid: NID to parse
- * @listp: the pointer to store NID list
- *
- * Parses the connection list of the given widget and stores the list
- * of NIDs.
- *
- * Returns the number of connections, or a negative error code.
- */
-int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid,
- const hda_nid_t **listp)
-{
- struct snd_array *array = &codec->conn_lists;
- int len, err;
- hda_nid_t list[HDA_MAX_CONNECTIONS];
- hda_nid_t *p;
- bool added = false;
-
- again:
- /* if the connection-list is already cached, read it */
- p = lookup_conn_list(array, nid);
- if (p) {
- if (listp)
- *listp = p + 2;
- return p[1];
- }
- if (snd_BUG_ON(added))
- return -EINVAL;
-
- /* read the connection and add to the cache */
- len = snd_hda_get_raw_connections(codec, nid, list, HDA_MAX_CONNECTIONS);
- if (len < 0)
- return len;
- err = snd_hda_override_conn_list(codec, nid, len, list);
- if (err < 0)
- return err;
- added = true;
- goto again;
-}
-EXPORT_SYMBOL_HDA(snd_hda_get_conn_list);
-
-/**
- * snd_hda_get_connections - copy connection list
- * @codec: the HDA codec
- * @nid: NID to parse
- * @conn_list: connection list array
- * @max_conns: max. number of connections to store
- *
- * Parses the connection list of the given widget and stores the list
- * of NIDs.
- *
- * Returns the number of connections, or a negative error code.
- */
-int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
- hda_nid_t *conn_list, int max_conns)
-{
- const hda_nid_t *list;
- int len = snd_hda_get_conn_list(codec, nid, &list);
-
- if (len <= 0)
- return len;
- if (len > max_conns) {
- snd_printk(KERN_ERR "hda_codec: "
- "Too many connections %d for NID 0x%x\n",
- len, nid);
- return -EINVAL;
- }
- memcpy(conn_list, list, len * sizeof(hda_nid_t));
- return len;
-}
-EXPORT_SYMBOL_HDA(snd_hda_get_connections);
-
-/**
- * snd_hda_get_raw_connections - copy connection list without cache
- * @codec: the HDA codec
- * @nid: NID to parse
- * @conn_list: connection list array
- * @max_conns: max. number of connections to store
- *
- * Like snd_hda_get_connections(), copy the connection list but without
- * checking through the connection-list cache.
- * Currently called only from hda_proc.c, so not exported.
- */
-int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
- hda_nid_t *conn_list, int max_conns)
-{
- unsigned int parm;
- int i, conn_len, conns;
- unsigned int shift, num_elems, mask;
- unsigned int wcaps;
- hda_nid_t prev_nid;
-
- if (snd_BUG_ON(!conn_list || max_conns <= 0))
- return -EINVAL;
-
- wcaps = get_wcaps(codec, nid);
- if (!(wcaps & AC_WCAP_CONN_LIST) &&
- get_wcaps_type(wcaps) != AC_WID_VOL_KNB)
- return 0;
-
- parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN);
- if (parm & AC_CLIST_LONG) {
- /* long form */
- shift = 16;
- num_elems = 2;
- } else {
- /* short form */
- shift = 8;
- num_elems = 4;
- }
- conn_len = parm & AC_CLIST_LENGTH;
- mask = (1 << (shift-1)) - 1;
-
- if (!conn_len)
- return 0; /* no connection */
-
- if (conn_len == 1) {
- /* single connection */
- parm = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_CONNECT_LIST, 0);
- if (parm == -1 && codec->bus->rirb_error)
- return -EIO;
- conn_list[0] = parm & mask;
- return 1;
- }
-
- /* multi connection */
- conns = 0;
- prev_nid = 0;
- for (i = 0; i < conn_len; i++) {
- int range_val;
- hda_nid_t val, n;
-
- if (i % num_elems == 0) {
- parm = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_CONNECT_LIST, i);
- if (parm == -1 && codec->bus->rirb_error)
- return -EIO;
- }
- range_val = !!(parm & (1 << (shift-1))); /* ranges */
- val = parm & mask;
- if (val == 0) {
- snd_printk(KERN_WARNING "hda_codec: "
- "invalid CONNECT_LIST verb %x[%i]:%x\n",
- nid, i, parm);
- return 0;
- }
- parm >>= shift;
- if (range_val) {
- /* ranges between the previous and this one */
- if (!prev_nid || prev_nid >= val) {
- snd_printk(KERN_WARNING "hda_codec: "
- "invalid dep_range_val %x:%x\n",
- prev_nid, val);
- continue;
- }
- for (n = prev_nid + 1; n <= val; n++) {
- if (conns >= max_conns) {
- snd_printk(KERN_ERR "hda_codec: "
- "Too many connections %d for NID 0x%x\n",
- conns, nid);
- return -EINVAL;
- }
- conn_list[conns++] = n;
- }
- } else {
- if (conns >= max_conns) {
- snd_printk(KERN_ERR "hda_codec: "
- "Too many connections %d for NID 0x%x\n",
- conns, nid);
- return -EINVAL;
- }
- conn_list[conns++] = val;
- }
- prev_nid = val;
- }
- return conns;
-}
-
-static bool add_conn_list(struct snd_array *array, hda_nid_t nid)
-{
- hda_nid_t *p = snd_array_new(array);
- if (!p)
- return false;
- *p = nid;
- return true;
-}
-
-/**
- * snd_hda_override_conn_list - add/modify the connection-list to cache
- * @codec: the HDA codec
- * @nid: NID to parse
- * @len: number of connection list entries
- * @list: the list of connection entries
- *
- * Add or modify the given connection-list to the cache. If the corresponding
- * cache already exists, invalidate it and append a new one.
- *
- * Returns zero or a negative error code.
- */
-int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int len,
- const hda_nid_t *list)
-{
- struct snd_array *array = &codec->conn_lists;
- hda_nid_t *p;
- int i, old_used;
-
- p = lookup_conn_list(array, nid);
- if (p)
- *p = -1; /* invalidate the old entry */
-
- old_used = array->used;
- if (!add_conn_list(array, nid) || !add_conn_list(array, len))
- goto error_add;
- for (i = 0; i < len; i++)
- if (!add_conn_list(array, list[i]))
- goto error_add;
- return 0;
-
- error_add:
- array->used = old_used;
- return -ENOMEM;
-}
-EXPORT_SYMBOL_HDA(snd_hda_override_conn_list);
-
-/**
- * snd_hda_get_conn_index - get the connection index of the given NID
- * @codec: the HDA codec
- * @mux: NID containing the list
- * @nid: NID to select
- * @recursive: 1 when searching NID recursively, otherwise 0
- *
- * Parses the connection list of the widget @mux and checks whether the
- * widget @nid is present. If it is, return the connection index.
- * Otherwise it returns -1.
- */
-int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
- hda_nid_t nid, int recursive)
-{
- hda_nid_t conn[HDA_MAX_NUM_INPUTS];
- int i, nums;
-
- nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
- for (i = 0; i < nums; i++)
- if (conn[i] == nid)
- return i;
- if (!recursive)
- return -1;
- if (recursive > 5) {
- snd_printd("hda_codec: too deep connection for 0x%x\n", nid);
- return -1;
- }
- recursive++;
- for (i = 0; i < nums; i++) {
- unsigned int type = get_wcaps_type(get_wcaps(codec, conn[i]));
- if (type == AC_WID_PIN || type == AC_WID_AUD_OUT)
- continue;
- if (snd_hda_get_conn_index(codec, conn[i], nid, recursive) >= 0)
- return i;
- }
- return -1;
-}
-EXPORT_SYMBOL_HDA(snd_hda_get_conn_index);
-
-/**
- * snd_hda_queue_unsol_event - add an unsolicited event to queue
- * @bus: the BUS
- * @res: unsolicited event (lower 32bit of RIRB entry)
- * @res_ex: codec addr and flags (upper 32bit or RIRB entry)
- *
- * Adds the given event to the queue. The events are processed in
- * the workqueue asynchronously. Call this function in the interrupt
- * hanlder when RIRB receives an unsolicited event.
- *
- * Returns 0 if successful, or a negative error code.
- */
-int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
-{
- struct hda_bus_unsolicited *unsol;
- unsigned int wp;
-
- trace_hda_unsol_event(bus, res, res_ex);
- unsol = bus->unsol;
- if (!unsol)
- return 0;
-
- wp = (unsol->wp + 1) % HDA_UNSOL_QUEUE_SIZE;
- unsol->wp = wp;
-
- wp <<= 1;
- unsol->queue[wp] = res;
- unsol->queue[wp + 1] = res_ex;
-
- queue_work(bus->workq, &unsol->work);
-
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_queue_unsol_event);
-
-/*
- * process queued unsolicited events
- */
-static void process_unsol_events(struct work_struct *work)
-{
- struct hda_bus_unsolicited *unsol =
- container_of(work, struct hda_bus_unsolicited, work);
- struct hda_bus *bus = unsol->bus;
- struct hda_codec *codec;
- unsigned int rp, caddr, res;
-
- while (unsol->rp != unsol->wp) {
- rp = (unsol->rp + 1) % HDA_UNSOL_QUEUE_SIZE;
- unsol->rp = rp;
- rp <<= 1;
- res = unsol->queue[rp];
- caddr = unsol->queue[rp + 1];
- if (!(caddr & (1 << 4))) /* no unsolicited event? */
- continue;
- codec = bus->caddr_tbl[caddr & 0x0f];
- if (codec && codec->patch_ops.unsol_event)
- codec->patch_ops.unsol_event(codec, res);
- }
-}
-
-/*
- * initialize unsolicited queue
- */
-static int init_unsol_queue(struct hda_bus *bus)
-{
- struct hda_bus_unsolicited *unsol;
-
- if (bus->unsol) /* already initialized */
- return 0;
-
- unsol = kzalloc(sizeof(*unsol), GFP_KERNEL);
- if (!unsol) {
- snd_printk(KERN_ERR "hda_codec: "
- "can't allocate unsolicited queue\n");
- return -ENOMEM;
- }
- INIT_WORK(&unsol->work, process_unsol_events);
- unsol->bus = bus;
- bus->unsol = unsol;
- return 0;
-}
-
-/*
- * destructor
- */
-static void snd_hda_codec_free(struct hda_codec *codec);
-
-static int snd_hda_bus_free(struct hda_bus *bus)
-{
- struct hda_codec *codec, *n;
-
- if (!bus)
- return 0;
- if (bus->workq)
- flush_workqueue(bus->workq);
- if (bus->unsol)
- kfree(bus->unsol);
- list_for_each_entry_safe(codec, n, &bus->codec_list, list) {
- snd_hda_codec_free(codec);
- }
- if (bus->ops.private_free)
- bus->ops.private_free(bus);
- if (bus->workq)
- destroy_workqueue(bus->workq);
- kfree(bus);
- return 0;
-}
-
-static int snd_hda_bus_dev_free(struct snd_device *device)
-{
- struct hda_bus *bus = device->device_data;
- bus->shutdown = 1;
- return snd_hda_bus_free(bus);
-}
-
-#ifdef CONFIG_SND_HDA_HWDEP
-static int snd_hda_bus_dev_register(struct snd_device *device)
-{
- struct hda_bus *bus = device->device_data;
- struct hda_codec *codec;
- list_for_each_entry(codec, &bus->codec_list, list) {
- snd_hda_hwdep_add_sysfs(codec);
- snd_hda_hwdep_add_power_sysfs(codec);
- }
- return 0;
-}
-#else
-#define snd_hda_bus_dev_register NULL
-#endif
-
-/**
- * snd_hda_bus_new - create a HDA bus
- * @card: the card entry
- * @temp: the template for hda_bus information
- * @busp: the pointer to store the created bus instance
- *
- * Returns 0 if successful, or a negative error code.
- */
-int /*__devinit*/ snd_hda_bus_new(struct snd_card *card,
- const struct hda_bus_template *temp,
- struct hda_bus **busp)
-{
- struct hda_bus *bus;
- int err;
- static struct snd_device_ops dev_ops = {
- .dev_register = snd_hda_bus_dev_register,
- .dev_free = snd_hda_bus_dev_free,
- };
-
- if (snd_BUG_ON(!temp))
- return -EINVAL;
- if (snd_BUG_ON(!temp->ops.command || !temp->ops.get_response))
- return -EINVAL;
-
- if (busp)
- *busp = NULL;
-
- bus = kzalloc(sizeof(*bus), GFP_KERNEL);
- if (bus == NULL) {
- snd_printk(KERN_ERR "can't allocate struct hda_bus\n");
- return -ENOMEM;
- }
-
- bus->card = card;
- bus->private_data = temp->private_data;
- bus->pci = temp->pci;
- bus->modelname = temp->modelname;
- bus->power_save = temp->power_save;
- bus->ops = temp->ops;
-
- mutex_init(&bus->cmd_mutex);
- mutex_init(&bus->prepare_mutex);
- INIT_LIST_HEAD(&bus->codec_list);
-
- snprintf(bus->workq_name, sizeof(bus->workq_name),
- "hd-audio%d", card->number);
- bus->workq = create_singlethread_workqueue(bus->workq_name);
- if (!bus->workq) {
- snd_printk(KERN_ERR "cannot create workqueue %s\n",
- bus->workq_name);
- kfree(bus);
- return -ENOMEM;
- }
-
- err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops);
- if (err < 0) {
- snd_hda_bus_free(bus);
- return err;
- }
- if (busp)
- *busp = bus;
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_bus_new);
-
-#ifdef CONFIG_SND_HDA_GENERIC
-#define is_generic_config(codec) \
- (codec->modelname && !strcmp(codec->modelname, "generic"))
-#else
-#define is_generic_config(codec) 0
-#endif
-
-#ifdef MODULE
-#define HDA_MODREQ_MAX_COUNT 2 /* two request_modules()'s */
-#else
-#define HDA_MODREQ_MAX_COUNT 0 /* all presets are statically linked */
-#endif
-
-/*
- * find a matching codec preset
- */
-static const struct hda_codec_preset *
-find_codec_preset(struct hda_codec *codec)
-{
- struct hda_codec_preset_list *tbl;
- const struct hda_codec_preset *preset;
- int mod_requested = 0;
-
- if (is_generic_config(codec))
- return NULL; /* use the generic parser */
-
- again:
- mutex_lock(&preset_mutex);
- list_for_each_entry(tbl, &hda_preset_tables, list) {
- if (!try_module_get(tbl->owner)) {
- snd_printk(KERN_ERR "hda_codec: cannot module_get\n");
- continue;
- }
- for (preset = tbl->preset; preset->id; preset++) {
- u32 mask = preset->mask;
- if (preset->afg && preset->afg != codec->afg)
- continue;
- if (preset->mfg && preset->mfg != codec->mfg)
- continue;
- if (!mask)
- mask = ~0;
- if (preset->id == (codec->vendor_id & mask) &&
- (!preset->rev ||
- preset->rev == codec->revision_id)) {
- mutex_unlock(&preset_mutex);
- codec->owner = tbl->owner;
- return preset;
- }
- }
- module_put(tbl->owner);
- }
- mutex_unlock(&preset_mutex);
-
- if (mod_requested < HDA_MODREQ_MAX_COUNT) {
- char name[32];
- if (!mod_requested)
- snprintf(name, sizeof(name), "snd-hda-codec-id:%08x",
- codec->vendor_id);
- else
- snprintf(name, sizeof(name), "snd-hda-codec-id:%04x*",
- (codec->vendor_id >> 16) & 0xffff);
- request_module(name);
- mod_requested++;
- goto again;
- }
- return NULL;
-}
-
-/*
- * get_codec_name - store the codec name
- */
-static int get_codec_name(struct hda_codec *codec)
-{
- const struct hda_vendor_id *c;
- const char *vendor = NULL;
- u16 vendor_id = codec->vendor_id >> 16;
- char tmp[16];
-
- if (codec->vendor_name)
- goto get_chip_name;
-
- for (c = hda_vendor_ids; c->id; c++) {
- if (c->id == vendor_id) {
- vendor = c->name;
- break;
- }
- }
- if (!vendor) {
- sprintf(tmp, "Generic %04x", vendor_id);
- vendor = tmp;
- }
- codec->vendor_name = kstrdup(vendor, GFP_KERNEL);
- if (!codec->vendor_name)
- return -ENOMEM;
-
- get_chip_name:
- if (codec->chip_name)
- return 0;
-
- if (codec->preset && codec->preset->name)
- codec->chip_name = kstrdup(codec->preset->name, GFP_KERNEL);
- else {
- sprintf(tmp, "ID %x", codec->vendor_id & 0xffff);
- codec->chip_name = kstrdup(tmp, GFP_KERNEL);
- }
- if (!codec->chip_name)
- return -ENOMEM;
- return 0;
-}
-
-/*
- * look for an AFG and MFG nodes
- */
-static void /*__devinit*/ setup_fg_nodes(struct hda_codec *codec)
-{
- int i, total_nodes, function_id;
- hda_nid_t nid;
-
- total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid);
- for (i = 0; i < total_nodes; i++, nid++) {
- function_id = snd_hda_param_read(codec, nid,
- AC_PAR_FUNCTION_TYPE);
- switch (function_id & 0xff) {
- case AC_GRP_AUDIO_FUNCTION:
- codec->afg = nid;
- codec->afg_function_id = function_id & 0xff;
- codec->afg_unsol = (function_id >> 8) & 1;
- break;
- case AC_GRP_MODEM_FUNCTION:
- codec->mfg = nid;
- codec->mfg_function_id = function_id & 0xff;
- codec->mfg_unsol = (function_id >> 8) & 1;
- break;
- default:
- break;
- }
- }
-}
-
-/*
- * read widget caps for each widget and store in cache
- */
-static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node)
-{
- int i;
- hda_nid_t nid;
-
- codec->num_nodes = snd_hda_get_sub_nodes(codec, fg_node,
- &codec->start_nid);
- codec->wcaps = kmalloc(codec->num_nodes * 4, GFP_KERNEL);
- if (!codec->wcaps)
- return -ENOMEM;
- nid = codec->start_nid;
- for (i = 0; i < codec->num_nodes; i++, nid++)
- codec->wcaps[i] = snd_hda_param_read(codec, nid,
- AC_PAR_AUDIO_WIDGET_CAP);
- return 0;
-}
-
-/* read all pin default configurations and save codec->init_pins */
-static int read_pin_defaults(struct hda_codec *codec)
-{
- int i;
- hda_nid_t nid = codec->start_nid;
-
- for (i = 0; i < codec->num_nodes; i++, nid++) {
- struct hda_pincfg *pin;
- unsigned int wcaps = get_wcaps(codec, nid);
- unsigned int wid_type = get_wcaps_type(wcaps);
- if (wid_type != AC_WID_PIN)
- continue;
- pin = snd_array_new(&codec->init_pins);
- if (!pin)
- return -ENOMEM;
- pin->nid = nid;
- pin->cfg = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_CONFIG_DEFAULT, 0);
- pin->ctrl = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL,
- 0);
- }
- return 0;
-}
-
-/* look up the given pin config list and return the item matching with NID */
-static struct hda_pincfg *look_up_pincfg(struct hda_codec *codec,
- struct snd_array *array,
- hda_nid_t nid)
-{
- int i;
- for (i = 0; i < array->used; i++) {
- struct hda_pincfg *pin = snd_array_elem(array, i);
- if (pin->nid == nid)
- return pin;
- }
- return NULL;
-}
-
-/* write a config value for the given NID */
-static void set_pincfg(struct hda_codec *codec, hda_nid_t nid,
- unsigned int cfg)
-{
- int i;
- for (i = 0; i < 4; i++) {
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
- cfg & 0xff);
- cfg >>= 8;
- }
-}
-
-/* set the current pin config value for the given NID.
- * the value is cached, and read via snd_hda_codec_get_pincfg()
- */
-int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
- hda_nid_t nid, unsigned int cfg)
-{
- struct hda_pincfg *pin;
- unsigned int oldcfg;
-
- if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
- return -EINVAL;
-
- oldcfg = snd_hda_codec_get_pincfg(codec, nid);
- pin = look_up_pincfg(codec, list, nid);
- if (!pin) {
- pin = snd_array_new(list);
- if (!pin)
- return -ENOMEM;
- pin->nid = nid;
- }
- pin->cfg = cfg;
-
- /* change only when needed; e.g. if the pincfg is already present
- * in user_pins[], don't write it
- */
- cfg = snd_hda_codec_get_pincfg(codec, nid);
- if (oldcfg != cfg)
- set_pincfg(codec, nid, cfg);
- return 0;
-}
-
-/**
- * snd_hda_codec_set_pincfg - Override a pin default configuration
- * @codec: the HDA codec
- * @nid: NID to set the pin config
- * @cfg: the pin default config value
- *
- * Override a pin default configuration value in the cache.
- * This value can be read by snd_hda_codec_get_pincfg() in a higher
- * priority than the real hardware value.
- */
-int snd_hda_codec_set_pincfg(struct hda_codec *codec,
- hda_nid_t nid, unsigned int cfg)
-{
- return snd_hda_add_pincfg(codec, &codec->driver_pins, nid, cfg);
-}
-EXPORT_SYMBOL_HDA(snd_hda_codec_set_pincfg);
-
-/**
- * snd_hda_codec_get_pincfg - Obtain a pin-default configuration
- * @codec: the HDA codec
- * @nid: NID to get the pin config
- *
- * Get the current pin config value of the given pin NID.
- * If the pincfg value is cached or overridden via sysfs or driver,
- * returns the cached value.
- */
-unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid)
-{
- struct hda_pincfg *pin;
-
-#ifdef CONFIG_SND_HDA_HWDEP
- pin = look_up_pincfg(codec, &codec->user_pins, nid);
- if (pin)
- return pin->cfg;
-#endif
- pin = look_up_pincfg(codec, &codec->driver_pins, nid);
- if (pin)
- return pin->cfg;
- pin = look_up_pincfg(codec, &codec->init_pins, nid);
- if (pin)
- return pin->cfg;
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_codec_get_pincfg);
-
-/* restore all current pin configs */
-static void restore_pincfgs(struct hda_codec *codec)
-{
- int i;
- for (i = 0; i < codec->init_pins.used; i++) {
- struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
- set_pincfg(codec, pin->nid,
- snd_hda_codec_get_pincfg(codec, pin->nid));
- }
-}
-
-/**
- * snd_hda_shutup_pins - Shut up all pins
- * @codec: the HDA codec
- *
- * Clear all pin controls to shup up before suspend for avoiding click noise.
- * The controls aren't cached so that they can be resumed properly.
- */
-void snd_hda_shutup_pins(struct hda_codec *codec)
-{
- int i;
- /* don't shut up pins when unloading the driver; otherwise it breaks
- * the default pin setup at the next load of the driver
- */
- if (codec->bus->shutdown)
- return;
- for (i = 0; i < codec->init_pins.used; i++) {
- struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
- /* use read here for syncing after issuing each verb */
- snd_hda_codec_read(codec, pin->nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
- }
- codec->pins_shutup = 1;
-}
-EXPORT_SYMBOL_HDA(snd_hda_shutup_pins);
-
-#ifdef CONFIG_PM
-/* Restore the pin controls cleared previously via snd_hda_shutup_pins() */
-static void restore_shutup_pins(struct hda_codec *codec)
-{
- int i;
- if (!codec->pins_shutup)
- return;
- if (codec->bus->shutdown)
- return;
- for (i = 0; i < codec->init_pins.used; i++) {
- struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
- snd_hda_codec_write(codec, pin->nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- pin->ctrl);
- }
- codec->pins_shutup = 0;
-}
-#endif
-
-static void init_hda_cache(struct hda_cache_rec *cache,
- unsigned int record_size);
-static void free_hda_cache(struct hda_cache_rec *cache);
-
-/* restore the initial pin cfgs and release all pincfg lists */
-static void restore_init_pincfgs(struct hda_codec *codec)
-{
- /* first free driver_pins and user_pins, then call restore_pincfg
- * so that only the values in init_pins are restored
- */
- snd_array_free(&codec->driver_pins);
-#ifdef CONFIG_SND_HDA_HWDEP
- snd_array_free(&codec->user_pins);
-#endif
- restore_pincfgs(codec);
- snd_array_free(&codec->init_pins);
-}
-
-/*
- * audio-converter setup caches
- */
-struct hda_cvt_setup {
- hda_nid_t nid;
- u8 stream_tag;
- u8 channel_id;
- u16 format_id;
- unsigned char active; /* cvt is currently used */
- unsigned char dirty; /* setups should be cleared */
-};
-
-/* get or create a cache entry for the given audio converter NID */
-static struct hda_cvt_setup *
-get_hda_cvt_setup(struct hda_codec *codec, hda_nid_t nid)
-{
- struct hda_cvt_setup *p;
- int i;
-
- for (i = 0; i < codec->cvt_setups.used; i++) {
- p = snd_array_elem(&codec->cvt_setups, i);
- if (p->nid == nid)
- return p;
- }
- p = snd_array_new(&codec->cvt_setups);
- if (p)
- p->nid = nid;
- return p;
-}
-
-/*
- * codec destructor
- */
-static void snd_hda_codec_free(struct hda_codec *codec)
-{
- if (!codec)
- return;
- snd_hda_jack_tbl_clear(codec);
- restore_init_pincfgs(codec);
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- cancel_delayed_work(&codec->power_work);
- flush_workqueue(codec->bus->workq);
-#endif
- list_del(&codec->list);
- snd_array_free(&codec->mixers);
- snd_array_free(&codec->nids);
- snd_array_free(&codec->cvt_setups);
- snd_array_free(&codec->conn_lists);
- snd_array_free(&codec->spdif_out);
- codec->bus->caddr_tbl[codec->addr] = NULL;
- if (codec->patch_ops.free)
- codec->patch_ops.free(codec);
- module_put(codec->owner);
- free_hda_cache(&codec->amp_cache);
- free_hda_cache(&codec->cmd_cache);
- kfree(codec->vendor_name);
- kfree(codec->chip_name);
- kfree(codec->modelname);
- kfree(codec->wcaps);
- kfree(codec);
-}
-
-static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
- unsigned int power_state);
-
-/**
- * snd_hda_codec_new - create a HDA codec
- * @bus: the bus to assign
- * @codec_addr: the codec address
- * @codecp: the pointer to store the generated codec
- *
- * Returns 0 if successful, or a negative error code.
- */
-int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
- unsigned int codec_addr,
- struct hda_codec **codecp)
-{
- struct hda_codec *codec;
- char component[31];
- int err;
-
- if (snd_BUG_ON(!bus))
- return -EINVAL;
- if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS))
- return -EINVAL;
-
- if (bus->caddr_tbl[codec_addr]) {
- snd_printk(KERN_ERR "hda_codec: "
- "address 0x%x is already occupied\n", codec_addr);
- return -EBUSY;
- }
-
- codec = kzalloc(sizeof(*codec), GFP_KERNEL);
- if (codec == NULL) {
- snd_printk(KERN_ERR "can't allocate struct hda_codec\n");
- return -ENOMEM;
- }
-
- codec->bus = bus;
- codec->addr = codec_addr;
- mutex_init(&codec->spdif_mutex);
- mutex_init(&codec->control_mutex);
- init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
- init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
- snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
- snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
- snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
- snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
- snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
- snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64);
- snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16);
- if (codec->bus->modelname) {
- codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL);
- if (!codec->modelname) {
- snd_hda_codec_free(codec);
- return -ENODEV;
- }
- }
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- INIT_DELAYED_WORK(&codec->power_work, hda_power_work);
- /* snd_hda_codec_new() marks the codec as power-up, and leave it as is.
- * the caller has to power down appropriatley after initialization
- * phase.
- */
- hda_keep_power_on(codec);
-#endif
-
- list_add_tail(&codec->list, &bus->codec_list);
- bus->caddr_tbl[codec_addr] = codec;
-
- codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT,
- AC_PAR_VENDOR_ID);
- if (codec->vendor_id == -1)
- /* read again, hopefully the access method was corrected
- * in the last read...
- */
- codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT,
- AC_PAR_VENDOR_ID);
- codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT,
- AC_PAR_SUBSYSTEM_ID);
- codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT,
- AC_PAR_REV_ID);
-
- setup_fg_nodes(codec);
- if (!codec->afg && !codec->mfg) {
- snd_printdd("hda_codec: no AFG or MFG node found\n");
- err = -ENODEV;
- goto error;
- }
-
- err = read_widget_caps(codec, codec->afg ? codec->afg : codec->mfg);
- if (err < 0) {
- snd_printk(KERN_ERR "hda_codec: cannot malloc\n");
- goto error;
- }
- err = read_pin_defaults(codec);
- if (err < 0)
- goto error;
-
- if (!codec->subsystem_id) {
- hda_nid_t nid = codec->afg ? codec->afg : codec->mfg;
- codec->subsystem_id =
- snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_SUBSYSTEM_ID, 0);
- }
-
- /* power-up all before initialization */
- hda_set_power_state(codec,
- codec->afg ? codec->afg : codec->mfg,
- AC_PWRST_D0);
-
- snd_hda_codec_proc_new(codec);
-
- snd_hda_create_hwdep(codec);
-
- sprintf(component, "HDA:%08x,%08x,%08x", codec->vendor_id,
- codec->subsystem_id, codec->revision_id);
- snd_component_add(codec->bus->card, component);
-
- if (codecp)
- *codecp = codec;
- return 0;
-
- error:
- snd_hda_codec_free(codec);
- return err;
-}
-EXPORT_SYMBOL_HDA(snd_hda_codec_new);
-
-/**
- * snd_hda_codec_configure - (Re-)configure the HD-audio codec
- * @codec: the HDA codec
- *
- * Start parsing of the given codec tree and (re-)initialize the whole
- * patch instance.
- *
- * Returns 0 if successful or a negative error code.
- */
-int snd_hda_codec_configure(struct hda_codec *codec)
-{
- int err;
-
- codec->preset = find_codec_preset(codec);
- if (!codec->vendor_name || !codec->chip_name) {
- err = get_codec_name(codec);
- if (err < 0)
- return err;
- }
-
- if (is_generic_config(codec)) {
- err = snd_hda_parse_generic_codec(codec);
- goto patched;
- }
- if (codec->preset && codec->preset->patch) {
- err = codec->preset->patch(codec);
- goto patched;
- }
-
- /* call the default parser */
- err = snd_hda_parse_generic_codec(codec);
- if (err < 0)
- printk(KERN_ERR "hda-codec: No codec parser is available\n");
-
- patched:
- if (!err && codec->patch_ops.unsol_event)
- err = init_unsol_queue(codec->bus);
- /* audio codec should override the mixer name */
- if (!err && (codec->afg || !*codec->bus->card->mixername))
- snprintf(codec->bus->card->mixername,
- sizeof(codec->bus->card->mixername),
- "%s %s", codec->vendor_name, codec->chip_name);
- return err;
-}
-EXPORT_SYMBOL_HDA(snd_hda_codec_configure);
-
-/**
- * snd_hda_codec_setup_stream - set up the codec for streaming
- * @codec: the CODEC to set up
- * @nid: the NID to set up
- * @stream_tag: stream tag to pass, it's between 0x1 and 0xf.
- * @channel_id: channel id to pass, zero based.
- * @format: stream format.
- */
-void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
- u32 stream_tag,
- int channel_id, int format)
-{
- struct hda_codec *c;
- struct hda_cvt_setup *p;
- unsigned int oldval, newval;
- int type;
- int i;
-
- if (!nid)
- return;
-
- snd_printdd("hda_codec_setup_stream: "
- "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
- nid, stream_tag, channel_id, format);
- p = get_hda_cvt_setup(codec, nid);
- if (!p)
- return;
- /* update the stream-id if changed */
- if (p->stream_tag != stream_tag || p->channel_id != channel_id) {
- oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
- newval = (stream_tag << 4) | channel_id;
- if (oldval != newval)
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_CHANNEL_STREAMID,
- newval);
- p->stream_tag = stream_tag;
- p->channel_id = channel_id;
- }
- /* update the format-id if changed */
- if (p->format_id != format) {
- oldval = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_STREAM_FORMAT, 0);
- if (oldval != format) {
- msleep(1);
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_STREAM_FORMAT,
- format);
- }
- p->format_id = format;
- }
- p->active = 1;
- p->dirty = 0;
-
- /* make other inactive cvts with the same stream-tag dirty */
- type = get_wcaps_type(get_wcaps(codec, nid));
- list_for_each_entry(c, &codec->bus->codec_list, list) {
- for (i = 0; i < c->cvt_setups.used; i++) {
- p = snd_array_elem(&c->cvt_setups, i);
- if (!p->active && p->stream_tag == stream_tag &&
- get_wcaps_type(get_wcaps(c, p->nid)) == type)
- p->dirty = 1;
- }
- }
-}
-EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream);
-
-static void really_cleanup_stream(struct hda_codec *codec,
- struct hda_cvt_setup *q);
-
-/**
- * __snd_hda_codec_cleanup_stream - clean up the codec for closing
- * @codec: the CODEC to clean up
- * @nid: the NID to clean up
- * @do_now: really clean up the stream instead of clearing the active flag
- */
-void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid,
- int do_now)
-{
- struct hda_cvt_setup *p;
-
- if (!nid)
- return;
-
- if (codec->no_sticky_stream)
- do_now = 1;
-
- snd_printdd("hda_codec_cleanup_stream: NID=0x%x\n", nid);
- p = get_hda_cvt_setup(codec, nid);
- if (p) {
- /* here we just clear the active flag when do_now isn't set;
- * actual clean-ups will be done later in
- * purify_inactive_streams() called from snd_hda_codec_prpapre()
- */
- if (do_now)
- really_cleanup_stream(codec, p);
- else
- p->active = 0;
- }
-}
-EXPORT_SYMBOL_HDA(__snd_hda_codec_cleanup_stream);
-
-static void really_cleanup_stream(struct hda_codec *codec,
- struct hda_cvt_setup *q)
-{
- hda_nid_t nid = q->nid;
- if (q->stream_tag || q->channel_id)
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
- if (q->format_id)
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0
-);
- memset(q, 0, sizeof(*q));
- q->nid = nid;
-}
-
-/* clean up the all conflicting obsolete streams */
-static void purify_inactive_streams(struct hda_codec *codec)
-{
- struct hda_codec *c;
- int i;
-
- list_for_each_entry(c, &codec->bus->codec_list, list) {
- for (i = 0; i < c->cvt_setups.used; i++) {
- struct hda_cvt_setup *p;
- p = snd_array_elem(&c->cvt_setups, i);
- if (p->dirty)
- really_cleanup_stream(c, p);
- }
- }
-}
-
-#ifdef CONFIG_PM
-/* clean up all streams; called from suspend */
-static void hda_cleanup_all_streams(struct hda_codec *codec)
-{
- int i;
-
- for (i = 0; i < codec->cvt_setups.used; i++) {
- struct hda_cvt_setup *p = snd_array_elem(&codec->cvt_setups, i);
- if (p->stream_tag)
- really_cleanup_stream(codec, p);
- }
-}
-#endif
-
-/*
- * amp access functions
- */
-
-/* FIXME: more better hash key? */
-#define HDA_HASH_KEY(nid, dir, idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24))
-#define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24))
-#define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24))
-#define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24))
-#define INFO_AMP_CAPS (1<<0)
-#define INFO_AMP_VOL(ch) (1 << (1 + (ch)))
-
-/* initialize the hash table */
-static void /*__devinit*/ init_hda_cache(struct hda_cache_rec *cache,
- unsigned int record_size)
-{
- memset(cache, 0, sizeof(*cache));
- memset(cache->hash, 0xff, sizeof(cache->hash));
- snd_array_init(&cache->buf, record_size, 64);
-}
-
-static void free_hda_cache(struct hda_cache_rec *cache)
-{
- snd_array_free(&cache->buf);
-}
-
-/* query the hash. allocate an entry if not found. */
-static struct hda_cache_head *get_hash(struct hda_cache_rec *cache, u32 key)
-{
- u16 idx = key % (u16)ARRAY_SIZE(cache->hash);
- u16 cur = cache->hash[idx];
- struct hda_cache_head *info;
-
- while (cur != 0xffff) {
- info = snd_array_elem(&cache->buf, cur);
- if (info->key == key)
- return info;
- cur = info->next;
- }
- return NULL;
-}
-
-/* query the hash. allocate an entry if not found. */
-static struct hda_cache_head *get_alloc_hash(struct hda_cache_rec *cache,
- u32 key)
-{
- struct hda_cache_head *info = get_hash(cache, key);
- if (!info) {
- u16 idx, cur;
- /* add a new hash entry */
- info = snd_array_new(&cache->buf);
- if (!info)
- return NULL;
- cur = snd_array_index(&cache->buf, info);
- info->key = key;
- info->val = 0;
- idx = key % (u16)ARRAY_SIZE(cache->hash);
- info->next = cache->hash[idx];
- cache->hash[idx] = cur;
- }
- return info;
-}
-
-/* query and allocate an amp hash entry */
-static inline struct hda_amp_info *
-get_alloc_amp_hash(struct hda_codec *codec, u32 key)
-{
- return (struct hda_amp_info *)get_alloc_hash(&codec->amp_cache, key);
-}
-
-/**
- * query_amp_caps - query AMP capabilities
- * @codec: the HD-auio codec
- * @nid: the NID to query
- * @direction: either #HDA_INPUT or #HDA_OUTPUT
- *
- * Query AMP capabilities for the given widget and direction.
- * Returns the obtained capability bits.
- *
- * When cap bits have been already read, this doesn't read again but
- * returns the cached value.
- */
-u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
-{
- struct hda_amp_info *info;
-
- info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0));
- if (!info)
- return 0;
- if (!(info->head.val & INFO_AMP_CAPS)) {
- if (!(get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD))
- nid = codec->afg;
- info->amp_caps = snd_hda_param_read(codec, nid,
- direction == HDA_OUTPUT ?
- AC_PAR_AMP_OUT_CAP :
- AC_PAR_AMP_IN_CAP);
- if (info->amp_caps)
- info->head.val |= INFO_AMP_CAPS;
- }
- return info->amp_caps;
-}
-EXPORT_SYMBOL_HDA(query_amp_caps);
-
-/**
- * snd_hda_override_amp_caps - Override the AMP capabilities
- * @codec: the CODEC to clean up
- * @nid: the NID to clean up
- * @direction: either #HDA_INPUT or #HDA_OUTPUT
- * @caps: the capability bits to set
- *
- * Override the cached AMP caps bits value by the given one.
- * This function is useful if the driver needs to adjust the AMP ranges,
- * e.g. limit to 0dB, etc.
- *
- * Returns zero if successful or a negative error code.
- */
-int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
- unsigned int caps)
-{
- struct hda_amp_info *info;
-
- info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, dir, 0));
- if (!info)
- return -EINVAL;
- info->amp_caps = caps;
- info->head.val |= INFO_AMP_CAPS;
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_override_amp_caps);
-
-static unsigned int
-query_caps_hash(struct hda_codec *codec, hda_nid_t nid, u32 key,
- unsigned int (*func)(struct hda_codec *, hda_nid_t))
-{
- struct hda_amp_info *info;
-
- info = get_alloc_amp_hash(codec, key);
- if (!info)
- return 0;
- if (!info->head.val) {
- info->head.val |= INFO_AMP_CAPS;
- info->amp_caps = func(codec, nid);
- }
- return info->amp_caps;
-}
-
-static unsigned int read_pin_cap(struct hda_codec *codec, hda_nid_t nid)
-{
- return snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
-}
-
-/**
- * snd_hda_query_pin_caps - Query PIN capabilities
- * @codec: the HD-auio codec
- * @nid: the NID to query
- *
- * Query PIN capabilities for the given widget.
- * Returns the obtained capability bits.
- *
- * When cap bits have been already read, this doesn't read again but
- * returns the cached value.
- */
-u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid)
-{
- return query_caps_hash(codec, nid, HDA_HASH_PINCAP_KEY(nid),
- read_pin_cap);
-}
-EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps);
-
-/**
- * snd_hda_override_pin_caps - Override the pin capabilities
- * @codec: the CODEC
- * @nid: the NID to override
- * @caps: the capability bits to set
- *
- * Override the cached PIN capabilitiy bits value by the given one.
- *
- * Returns zero if successful or a negative error code.
- */
-int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid,
- unsigned int caps)
-{
- struct hda_amp_info *info;
- info = get_alloc_amp_hash(codec, HDA_HASH_PINCAP_KEY(nid));
- if (!info)
- return -ENOMEM;
- info->amp_caps = caps;
- info->head.val |= INFO_AMP_CAPS;
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_override_pin_caps);
-
-/*
- * read the current volume to info
- * if the cache exists, read the cache value.
- */
-static unsigned int get_vol_mute(struct hda_codec *codec,
- struct hda_amp_info *info, hda_nid_t nid,
- int ch, int direction, int index)
-{
- u32 val, parm;
-
- if (info->head.val & INFO_AMP_VOL(ch))
- return info->vol[ch];
-
- parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT;
- parm |= direction == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT;
- parm |= index;
- val = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_AMP_GAIN_MUTE, parm);
- info->vol[ch] = val & 0xff;
- info->head.val |= INFO_AMP_VOL(ch);
- return info->vol[ch];
-}
-
-/*
- * write the current volume in info to the h/w and update the cache
- */
-static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
- hda_nid_t nid, int ch, int direction, int index,
- int val)
-{
- u32 parm;
-
- parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT;
- parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT;
- parm |= index << AC_AMP_SET_INDEX_SHIFT;
- if ((val & HDA_AMP_MUTE) && !(info->amp_caps & AC_AMPCAP_MUTE) &&
- (info->amp_caps & AC_AMPCAP_MIN_MUTE))
- ; /* set the zero value as a fake mute */
- else
- parm |= val;
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm);
- info->vol[ch] = val;
-}
-
-/**
- * snd_hda_codec_amp_read - Read AMP value
- * @codec: HD-audio codec
- * @nid: NID to read the AMP value
- * @ch: channel (left=0 or right=1)
- * @direction: #HDA_INPUT or #HDA_OUTPUT
- * @index: the index value (only for input direction)
- *
- * Read AMP value. The volume is between 0 to 0x7f, 0x80 = mute bit.
- */
-int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
- int direction, int index)
-{
- struct hda_amp_info *info;
- info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index));
- if (!info)
- return 0;
- return get_vol_mute(codec, info, nid, ch, direction, index);
-}
-EXPORT_SYMBOL_HDA(snd_hda_codec_amp_read);
-
-/**
- * snd_hda_codec_amp_update - update the AMP value
- * @codec: HD-audio codec
- * @nid: NID to read the AMP value
- * @ch: channel (left=0 or right=1)
- * @direction: #HDA_INPUT or #HDA_OUTPUT
- * @idx: the index value (only for input direction)
- * @mask: bit mask to set
- * @val: the bits value to set
- *
- * Update the AMP value with a bit mask.
- * Returns 0 if the value is unchanged, 1 if changed.
- */
-int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
- int direction, int idx, int mask, int val)
-{
- struct hda_amp_info *info;
-
- info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx));
- if (!info)
- return 0;
- if (snd_BUG_ON(mask & ~0xff))
- mask &= 0xff;
- val &= mask;
- val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask;
- if (info->vol[ch] == val)
- return 0;
- put_vol_mute(codec, info, nid, ch, direction, idx, val);
- return 1;
-}
-EXPORT_SYMBOL_HDA(snd_hda_codec_amp_update);
-
-/**
- * snd_hda_codec_amp_stereo - update the AMP stereo values
- * @codec: HD-audio codec
- * @nid: NID to read the AMP value
- * @direction: #HDA_INPUT or #HDA_OUTPUT
- * @idx: the index value (only for input direction)
- * @mask: bit mask to set
- * @val: the bits value to set
- *
- * Update the AMP values like snd_hda_codec_amp_update(), but for a
- * stereo widget with the same mask and value.
- */
-int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
- int direction, int idx, int mask, int val)
-{
- int ch, ret = 0;
-
- if (snd_BUG_ON(mask & ~0xff))
- mask &= 0xff;
- for (ch = 0; ch < 2; ch++)
- ret |= snd_hda_codec_amp_update(codec, nid, ch, direction,
- idx, mask, val);
- return ret;
-}
-EXPORT_SYMBOL_HDA(snd_hda_codec_amp_stereo);
-
-#ifdef CONFIG_PM
-/**
- * snd_hda_codec_resume_amp - Resume all AMP commands from the cache
- * @codec: HD-audio codec
- *
- * Resume the all amp commands from the cache.
- */
-void snd_hda_codec_resume_amp(struct hda_codec *codec)
-{
- struct hda_amp_info *buffer = codec->amp_cache.buf.list;
- int i;
-
- for (i = 0; i < codec->amp_cache.buf.used; i++, buffer++) {
- u32 key = buffer->head.key;
- hda_nid_t nid;
- unsigned int idx, dir, ch;
- if (!key)
- continue;
- nid = key & 0xff;
- idx = (key >> 16) & 0xff;
- dir = (key >> 24) & 0xff;
- for (ch = 0; ch < 2; ch++) {
- if (!(buffer->head.val & INFO_AMP_VOL(ch)))
- continue;
- put_vol_mute(codec, buffer, nid, ch, dir, idx,
- buffer->vol[ch]);
- }
- }
-}
-EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp);
-#endif /* CONFIG_PM */
-
-static u32 get_amp_max_value(struct hda_codec *codec, hda_nid_t nid, int dir,
- unsigned int ofs)
-{
- u32 caps = query_amp_caps(codec, nid, dir);
- /* get num steps */
- caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
- if (ofs < caps)
- caps -= ofs;
- return caps;
-}
-
-/**
- * snd_hda_mixer_amp_volume_info - Info callback for a standard AMP mixer
- *
- * The control element is supposed to have the private_value field
- * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
- */
-int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- u16 nid = get_amp_nid(kcontrol);
- u8 chs = get_amp_channels(kcontrol);
- int dir = get_amp_direction(kcontrol);
- unsigned int ofs = get_amp_offset(kcontrol);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = chs == 3 ? 2 : 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = get_amp_max_value(codec, nid, dir, ofs);
- if (!uinfo->value.integer.max) {
- printk(KERN_WARNING "hda_codec: "
- "num_steps = 0 for NID=0x%x (ctl = %s)\n", nid,
- kcontrol->id.name);
- return -EINVAL;
- }
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_info);
-
-
-static inline unsigned int
-read_amp_value(struct hda_codec *codec, hda_nid_t nid,
- int ch, int dir, int idx, unsigned int ofs)
-{
- unsigned int val;
- val = snd_hda_codec_amp_read(codec, nid, ch, dir, idx);
- val &= HDA_AMP_VOLMASK;
- if (val >= ofs)
- val -= ofs;
- else
- val = 0;
- return val;
-}
-
-static inline int
-update_amp_value(struct hda_codec *codec, hda_nid_t nid,
- int ch, int dir, int idx, unsigned int ofs,
- unsigned int val)
-{
- unsigned int maxval;
-
- if (val > 0)
- val += ofs;
- /* ofs = 0: raw max value */
- maxval = get_amp_max_value(codec, nid, dir, 0);
- if (val > maxval)
- val = maxval;
- return snd_hda_codec_amp_update(codec, nid, ch, dir, idx,
- HDA_AMP_VOLMASK, val);
-}
-
-/**
- * snd_hda_mixer_amp_volume_get - Get callback for a standard AMP mixer volume
- *
- * The control element is supposed to have the private_value field
- * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
- */
-int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- hda_nid_t nid = get_amp_nid(kcontrol);
- int chs = get_amp_channels(kcontrol);
- int dir = get_amp_direction(kcontrol);
- int idx = get_amp_index(kcontrol);
- unsigned int ofs = get_amp_offset(kcontrol);
- long *valp = ucontrol->value.integer.value;
-
- if (chs & 1)
- *valp++ = read_amp_value(codec, nid, 0, dir, idx, ofs);
- if (chs & 2)
- *valp = read_amp_value(codec, nid, 1, dir, idx, ofs);
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_get);
-
-/**
- * snd_hda_mixer_amp_volume_put - Put callback for a standard AMP mixer volume
- *
- * The control element is supposed to have the private_value field
- * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
- */
-int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- hda_nid_t nid = get_amp_nid(kcontrol);
- int chs = get_amp_channels(kcontrol);
- int dir = get_amp_direction(kcontrol);
- int idx = get_amp_index(kcontrol);
- unsigned int ofs = get_amp_offset(kcontrol);
- long *valp = ucontrol->value.integer.value;
- int change = 0;
-
- snd_hda_power_up(codec);
- if (chs & 1) {
- change = update_amp_value(codec, nid, 0, dir, idx, ofs, *valp);
- valp++;
- }
- if (chs & 2)
- change |= update_amp_value(codec, nid, 1, dir, idx, ofs, *valp);
- snd_hda_power_down(codec);
- return change;
-}
-EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_put);
-
-/**
- * snd_hda_mixer_amp_volume_put - TLV callback for a standard AMP mixer volume
- *
- * The control element is supposed to have the private_value field
- * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
- */
-int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
- unsigned int size, unsigned int __user *_tlv)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- hda_nid_t nid = get_amp_nid(kcontrol);
- int dir = get_amp_direction(kcontrol);
- unsigned int ofs = get_amp_offset(kcontrol);
- bool min_mute = get_amp_min_mute(kcontrol);
- u32 caps, val1, val2;
-
- if (size < 4 * sizeof(unsigned int))
- return -ENOMEM;
- caps = query_amp_caps(codec, nid, dir);
- val2 = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT;
- val2 = (val2 + 1) * 25;
- val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT);
- val1 += ofs;
- val1 = ((int)val1) * ((int)val2);
- if (min_mute || (caps & AC_AMPCAP_MIN_MUTE))
- val2 |= TLV_DB_SCALE_MUTE;
- if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv))
- return -EFAULT;
- if (put_user(2 * sizeof(unsigned int), _tlv + 1))
- return -EFAULT;
- if (put_user(val1, _tlv + 2))
- return -EFAULT;
- if (put_user(val2, _tlv + 3))
- return -EFAULT;
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_tlv);
-
-/**
- * snd_hda_set_vmaster_tlv - Set TLV for a virtual master control
- * @codec: HD-audio codec
- * @nid: NID of a reference widget
- * @dir: #HDA_INPUT or #HDA_OUTPUT
- * @tlv: TLV data to be stored, at least 4 elements
- *
- * Set (static) TLV data for a virtual master volume using the AMP caps
- * obtained from the reference NID.
- * The volume range is recalculated as if the max volume is 0dB.
- */
-void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
- unsigned int *tlv)
-{
- u32 caps;
- int nums, step;
-
- caps = query_amp_caps(codec, nid, dir);
- nums = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
- step = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT;
- step = (step + 1) * 25;
- tlv[0] = SNDRV_CTL_TLVT_DB_SCALE;
- tlv[1] = 2 * sizeof(unsigned int);
- tlv[2] = -nums * step;
- tlv[3] = step;
-}
-EXPORT_SYMBOL_HDA(snd_hda_set_vmaster_tlv);
-
-/* find a mixer control element with the given name */
-static struct snd_kcontrol *
-_snd_hda_find_mixer_ctl(struct hda_codec *codec,
- const char *name, int idx)
-{
- struct snd_ctl_elem_id id;
- memset(&id, 0, sizeof(id));
- id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- id.index = idx;
- if (snd_BUG_ON(strlen(name) >= sizeof(id.name)))
- return NULL;
- strcpy(id.name, name);
- return snd_ctl_find_id(codec->bus->card, &id);
-}
-
-/**
- * snd_hda_find_mixer_ctl - Find a mixer control element with the given name
- * @codec: HD-audio codec
- * @name: ctl id name string
- *
- * Get the control element with the given id string and IFACE_MIXER.
- */
-struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
- const char *name)
-{
- return _snd_hda_find_mixer_ctl(codec, name, 0);
-}
-EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
-
-static int find_empty_mixer_ctl_idx(struct hda_codec *codec, const char *name)
-{
- int idx;
- for (idx = 0; idx < 16; idx++) { /* 16 ctlrs should be large enough */
- if (!_snd_hda_find_mixer_ctl(codec, name, idx))
- return idx;
- }
- return -EBUSY;
-}
-
-/**
- * snd_hda_ctl_add - Add a control element and assign to the codec
- * @codec: HD-audio codec
- * @nid: corresponding NID (optional)
- * @kctl: the control element to assign
- *
- * Add the given control element to an array inside the codec instance.
- * All control elements belonging to a codec are supposed to be added
- * by this function so that a proper clean-up works at the free or
- * reconfiguration time.
- *
- * If non-zero @nid is passed, the NID is assigned to the control element.
- * The assignment is shown in the codec proc file.
- *
- * snd_hda_ctl_add() checks the control subdev id field whether
- * #HDA_SUBDEV_NID_FLAG bit is set. If set (and @nid is zero), the lower
- * bits value is taken as the NID to assign. The #HDA_NID_ITEM_AMP bit
- * specifies if kctl->private_value is a HDA amplifier value.
- */
-int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
- struct snd_kcontrol *kctl)
-{
- int err;
- unsigned short flags = 0;
- struct hda_nid_item *item;
-
- if (kctl->id.subdevice & HDA_SUBDEV_AMP_FLAG) {
- flags |= HDA_NID_ITEM_AMP;
- if (nid == 0)
- nid = get_amp_nid_(kctl->private_value);
- }
- if ((kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) != 0 && nid == 0)
- nid = kctl->id.subdevice & 0xffff;
- if (kctl->id.subdevice & (HDA_SUBDEV_NID_FLAG|HDA_SUBDEV_AMP_FLAG))
- kctl->id.subdevice = 0;
- err = snd_ctl_add(codec->bus->card, kctl);
- if (err < 0)
- return err;
- item = snd_array_new(&codec->mixers);
- if (!item)
- return -ENOMEM;
- item->kctl = kctl;
- item->nid = nid;
- item->flags = flags;
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_ctl_add);
-
-/**
- * snd_hda_add_nid - Assign a NID to a control element
- * @codec: HD-audio codec
- * @nid: corresponding NID (optional)
- * @kctl: the control element to assign
- * @index: index to kctl
- *
- * Add the given control element to an array inside the codec instance.
- * This function is used when #snd_hda_ctl_add cannot be used for 1:1
- * NID:KCTL mapping - for example "Capture Source" selector.
- */
-int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
- unsigned int index, hda_nid_t nid)
-{
- struct hda_nid_item *item;
-
- if (nid > 0) {
- item = snd_array_new(&codec->nids);
- if (!item)
- return -ENOMEM;
- item->kctl = kctl;
- item->index = index;
- item->nid = nid;
- return 0;
- }
- printk(KERN_ERR "hda-codec: no NID for mapping control %s:%d:%d\n",
- kctl->id.name, kctl->id.index, index);
- return -EINVAL;
-}
-EXPORT_SYMBOL_HDA(snd_hda_add_nid);
-
-/**
- * snd_hda_ctls_clear - Clear all controls assigned to the given codec
- * @codec: HD-audio codec
- */
-void snd_hda_ctls_clear(struct hda_codec *codec)
-{
- int i;
- struct hda_nid_item *items = codec->mixers.list;
- for (i = 0; i < codec->mixers.used; i++)
- snd_ctl_remove(codec->bus->card, items[i].kctl);
- snd_array_free(&codec->mixers);
- snd_array_free(&codec->nids);
-}
-
-/* pseudo device locking
- * toggle card->shutdown to allow/disallow the device access (as a hack)
- */
-static int hda_lock_devices(struct snd_card *card)
-{
- spin_lock(&card->files_lock);
- if (card->shutdown) {
- spin_unlock(&card->files_lock);
- return -EINVAL;
- }
- card->shutdown = 1;
- spin_unlock(&card->files_lock);
- return 0;
-}
-
-static void hda_unlock_devices(struct snd_card *card)
-{
- spin_lock(&card->files_lock);
- card->shutdown = 0;
- spin_unlock(&card->files_lock);
-}
-
-/**
- * snd_hda_codec_reset - Clear all objects assigned to the codec
- * @codec: HD-audio codec
- *
- * This frees the all PCM and control elements assigned to the codec, and
- * clears the caches and restores the pin default configurations.
- *
- * When a device is being used, it returns -EBSY. If successfully freed,
- * returns zero.
- */
-int snd_hda_codec_reset(struct hda_codec *codec)
-{
- struct snd_card *card = codec->bus->card;
- int i, pcm;
-
- if (hda_lock_devices(card) < 0)
- return -EBUSY;
- /* check whether the codec isn't used by any mixer or PCM streams */
- if (!list_empty(&card->ctl_files)) {
- hda_unlock_devices(card);
- return -EBUSY;
- }
- for (pcm = 0; pcm < codec->num_pcms; pcm++) {
- struct hda_pcm *cpcm = &codec->pcm_info[pcm];
- if (!cpcm->pcm)
- continue;
- if (cpcm->pcm->streams[0].substream_opened ||
- cpcm->pcm->streams[1].substream_opened) {
- hda_unlock_devices(card);
- return -EBUSY;
- }
- }
-
- /* OK, let it free */
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- cancel_delayed_work(&codec->power_work);
- flush_workqueue(codec->bus->workq);
-#endif
- snd_hda_ctls_clear(codec);
- /* relase PCMs */
- for (i = 0; i < codec->num_pcms; i++) {
- if (codec->pcm_info[i].pcm) {
- snd_device_free(card, codec->pcm_info[i].pcm);
- clear_bit(codec->pcm_info[i].device,
- codec->bus->pcm_dev_bits);
- }
- }
- if (codec->patch_ops.free)
- codec->patch_ops.free(codec);
- snd_hda_jack_tbl_clear(codec);
- codec->proc_widget_hook = NULL;
- codec->spec = NULL;
- free_hda_cache(&codec->amp_cache);
- free_hda_cache(&codec->cmd_cache);
- init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
- init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
- /* free only driver_pins so that init_pins + user_pins are restored */
- snd_array_free(&codec->driver_pins);
- restore_pincfgs(codec);
- codec->num_pcms = 0;
- codec->pcm_info = NULL;
- codec->preset = NULL;
- memset(&codec->patch_ops, 0, sizeof(codec->patch_ops));
- codec->slave_dig_outs = NULL;
- codec->spdif_status_reset = 0;
- module_put(codec->owner);
- codec->owner = NULL;
-
- /* allow device access again */
- hda_unlock_devices(card);
- return 0;
-}
-
-typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *);
-
-/* apply the function to all matching slave ctls in the mixer list */
-static int map_slaves(struct hda_codec *codec, const char * const *slaves,
- const char *suffix, map_slave_func_t func, void *data)
-{
- struct hda_nid_item *items;
- const char * const *s;
- int i, err;
-
- items = codec->mixers.list;
- for (i = 0; i < codec->mixers.used; i++) {
- struct snd_kcontrol *sctl = items[i].kctl;
- if (!sctl || !sctl->id.name ||
- sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER)
- continue;
- for (s = slaves; *s; s++) {
- char tmpname[sizeof(sctl->id.name)];
- const char *name = *s;
- if (suffix) {
- snprintf(tmpname, sizeof(tmpname), "%s %s",
- name, suffix);
- name = tmpname;
- }
- if (!strcmp(sctl->id.name, name)) {
- err = func(data, sctl);
- if (err)
- return err;
- break;
- }
- }
- }
- return 0;
-}
-
-static int check_slave_present(void *data, struct snd_kcontrol *sctl)
-{
- return 1;
-}
-
-/* guess the value corresponding to 0dB */
-static int get_kctl_0dB_offset(struct snd_kcontrol *kctl)
-{
- int _tlv[4];
- const int *tlv = NULL;
- int val = -1;
-
- if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
- /* FIXME: set_fs() hack for obtaining user-space TLV data */
- mm_segment_t fs = get_fs();
- set_fs(get_ds());
- if (!kctl->tlv.c(kctl, 0, sizeof(_tlv), _tlv))
- tlv = _tlv;
- set_fs(fs);
- } else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ)
- tlv = kctl->tlv.p;
- if (tlv && tlv[0] == SNDRV_CTL_TLVT_DB_SCALE)
- val = -tlv[2] / tlv[3];
- return val;
-}
-
-/* call kctl->put with the given value(s) */
-static int put_kctl_with_value(struct snd_kcontrol *kctl, int val)
-{
- struct snd_ctl_elem_value *ucontrol;
- ucontrol = kzalloc(sizeof(*ucontrol), GFP_KERNEL);
- if (!ucontrol)
- return -ENOMEM;
- ucontrol->value.integer.value[0] = val;
- ucontrol->value.integer.value[1] = val;
- kctl->put(kctl, ucontrol);
- kfree(ucontrol);
- return 0;
-}
-
-/* initialize the slave volume with 0dB */
-static int init_slave_0dB(void *data, struct snd_kcontrol *slave)
-{
- int offset = get_kctl_0dB_offset(slave);
- if (offset > 0)
- put_kctl_with_value(slave, offset);
- return 0;
-}
-
-/* unmute the slave */
-static int init_slave_unmute(void *data, struct snd_kcontrol *slave)
-{
- return put_kctl_with_value(slave, 1);
-}
-
-/**
- * snd_hda_add_vmaster - create a virtual master control and add slaves
- * @codec: HD-audio codec
- * @name: vmaster control name
- * @tlv: TLV data (optional)
- * @slaves: slave control names (optional)
- * @suffix: suffix string to each slave name (optional)
- * @init_slave_vol: initialize slaves to unmute/0dB
- * @ctl_ret: store the vmaster kcontrol in return
- *
- * Create a virtual master control with the given name. The TLV data
- * must be either NULL or a valid data.
- *
- * @slaves is a NULL-terminated array of strings, each of which is a
- * slave control name. All controls with these names are assigned to
- * the new virtual master control.
- *
- * This function returns zero if successful or a negative error code.
- */
-int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
- unsigned int *tlv, const char * const *slaves,
- const char *suffix, bool init_slave_vol,
- struct snd_kcontrol **ctl_ret)
-{
- struct snd_kcontrol *kctl;
- int err;
-
- if (ctl_ret)
- *ctl_ret = NULL;
-
- err = map_slaves(codec, slaves, suffix, check_slave_present, NULL);
- if (err != 1) {
- snd_printdd("No slave found for %s\n", name);
- return 0;
- }
- kctl = snd_ctl_make_virtual_master(name, tlv);
- if (!kctl)
- return -ENOMEM;
- err = snd_hda_ctl_add(codec, 0, kctl);
- if (err < 0)
- return err;
-
- err = map_slaves(codec, slaves, suffix,
- (map_slave_func_t)snd_ctl_add_slave, kctl);
- if (err < 0)
- return err;
-
- /* init with master mute & zero volume */
- put_kctl_with_value(kctl, 0);
- if (init_slave_vol)
- map_slaves(codec, slaves, suffix,
- tlv ? init_slave_0dB : init_slave_unmute, kctl);
-
- if (ctl_ret)
- *ctl_ret = kctl;
- return 0;
-}
-EXPORT_SYMBOL_HDA(__snd_hda_add_vmaster);
-
-/*
- * mute-LED control using vmaster
- */
-static int vmaster_mute_mode_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static const char * const texts[] = {
- "Off", "On", "Follow Master"
- };
- unsigned int index;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- index = uinfo->value.enumerated.item;
- if (index >= 3)
- index = 2;
- strcpy(uinfo->value.enumerated.name, texts[index]);
- return 0;
-}
-
-static int vmaster_mute_mode_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = hook->mute_mode;
- return 0;
-}
-
-static int vmaster_mute_mode_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol);
- unsigned int old_mode = hook->mute_mode;
-
- hook->mute_mode = ucontrol->value.enumerated.item[0];
- if (hook->mute_mode > HDA_VMUTE_FOLLOW_MASTER)
- hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
- if (old_mode == hook->mute_mode)
- return 0;
- snd_hda_sync_vmaster_hook(hook);
- return 1;
-}
-
-static struct snd_kcontrol_new vmaster_mute_mode = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Mute-LED Mode",
- .info = vmaster_mute_mode_info,
- .get = vmaster_mute_mode_get,
- .put = vmaster_mute_mode_put,
-};
-
-/*
- * Add a mute-LED hook with the given vmaster switch kctl
- * "Mute-LED Mode" control is automatically created and associated with
- * the given hook.
- */
-int snd_hda_add_vmaster_hook(struct hda_codec *codec,
- struct hda_vmaster_mute_hook *hook,
- bool expose_enum_ctl)
-{
- struct snd_kcontrol *kctl;
-
- if (!hook->hook || !hook->sw_kctl)
- return 0;
- snd_ctl_add_vmaster_hook(hook->sw_kctl, hook->hook, codec);
- hook->codec = codec;
- hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
- if (!expose_enum_ctl)
- return 0;
- kctl = snd_ctl_new1(&vmaster_mute_mode, hook);
- if (!kctl)
- return -ENOMEM;
- return snd_hda_ctl_add(codec, 0, kctl);
-}
-EXPORT_SYMBOL_HDA(snd_hda_add_vmaster_hook);
-
-/*
- * Call the hook with the current value for synchronization
- * Should be called in init callback
- */
-void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook)
-{
- if (!hook->hook || !hook->codec)
- return;
- switch (hook->mute_mode) {
- case HDA_VMUTE_FOLLOW_MASTER:
- snd_ctl_sync_vmaster_hook(hook->sw_kctl);
- break;
- default:
- hook->hook(hook->codec, hook->mute_mode);
- break;
- }
-}
-EXPORT_SYMBOL_HDA(snd_hda_sync_vmaster_hook);
-
-
-/**
- * snd_hda_mixer_amp_switch_info - Info callback for a standard AMP mixer switch
- *
- * The control element is supposed to have the private_value field
- * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
- */
-int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int chs = get_amp_channels(kcontrol);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = chs == 3 ? 2 : 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_info);
-
-/**
- * snd_hda_mixer_amp_switch_get - Get callback for a standard AMP mixer switch
- *
- * The control element is supposed to have the private_value field
- * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
- */
-int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- hda_nid_t nid = get_amp_nid(kcontrol);
- int chs = get_amp_channels(kcontrol);
- int dir = get_amp_direction(kcontrol);
- int idx = get_amp_index(kcontrol);
- long *valp = ucontrol->value.integer.value;
-
- if (chs & 1)
- *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) &
- HDA_AMP_MUTE) ? 0 : 1;
- if (chs & 2)
- *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) &
- HDA_AMP_MUTE) ? 0 : 1;
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_get);
-
-/**
- * snd_hda_mixer_amp_switch_put - Put callback for a standard AMP mixer switch
- *
- * The control element is supposed to have the private_value field
- * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
- */
-int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- hda_nid_t nid = get_amp_nid(kcontrol);
- int chs = get_amp_channels(kcontrol);
- int dir = get_amp_direction(kcontrol);
- int idx = get_amp_index(kcontrol);
- long *valp = ucontrol->value.integer.value;
- int change = 0;
-
- snd_hda_power_up(codec);
- if (chs & 1) {
- change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx,
- HDA_AMP_MUTE,
- *valp ? 0 : HDA_AMP_MUTE);
- valp++;
- }
- if (chs & 2)
- change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx,
- HDA_AMP_MUTE,
- *valp ? 0 : HDA_AMP_MUTE);
- hda_call_check_power_status(codec, nid);
- snd_hda_power_down(codec);
- return change;
-}
-EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put);
-
-#ifdef CONFIG_SND_HDA_INPUT_BEEP
-/**
- * snd_hda_mixer_amp_switch_put_beep - Put callback for a beep AMP switch
- *
- * This function calls snd_hda_enable_beep_device(), which behaves differently
- * depending on beep_mode option.
- */
-int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- long *valp = ucontrol->value.integer.value;
-
- snd_hda_enable_beep_device(codec, *valp);
- return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
-}
-EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep);
-#endif /* CONFIG_SND_HDA_INPUT_BEEP */
-
-/*
- * bound volume controls
- *
- * bind multiple volumes (# indices, from 0)
- */
-
-#define AMP_VAL_IDX_SHIFT 19
-#define AMP_VAL_IDX_MASK (0x0f<<19)
-
-/**
- * snd_hda_mixer_bind_switch_get - Get callback for a bound volume control
- *
- * The control element is supposed to have the private_value field
- * set up via HDA_BIND_MUTE*() macros.
- */
-int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned long pval;
- int err;
-
- mutex_lock(&codec->control_mutex);
- pval = kcontrol->private_value;
- kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
- err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
- kcontrol->private_value = pval;
- mutex_unlock(&codec->control_mutex);
- return err;
-}
-EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_get);
-
-/**
- * snd_hda_mixer_bind_switch_put - Put callback for a bound volume control
- *
- * The control element is supposed to have the private_value field
- * set up via HDA_BIND_MUTE*() macros.
- */
-int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned long pval;
- int i, indices, err = 0, change = 0;
-
- mutex_lock(&codec->control_mutex);
- pval = kcontrol->private_value;
- indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
- for (i = 0; i < indices; i++) {
- kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) |
- (i << AMP_VAL_IDX_SHIFT);
- err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
- if (err < 0)
- break;
- change |= err;
- }
- kcontrol->private_value = pval;
- mutex_unlock(&codec->control_mutex);
- return err < 0 ? err : change;
-}
-EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_put);
-
-/**
- * snd_hda_mixer_bind_ctls_info - Info callback for a generic bound control
- *
- * The control element is supposed to have the private_value field
- * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros.
- */
-int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct hda_bind_ctls *c;
- int err;
-
- mutex_lock(&codec->control_mutex);
- c = (struct hda_bind_ctls *)kcontrol->private_value;
- kcontrol->private_value = *c->values;
- err = c->ops->info(kcontrol, uinfo);
- kcontrol->private_value = (long)c;
- mutex_unlock(&codec->control_mutex);
- return err;
-}
-EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_info);
-
-/**
- * snd_hda_mixer_bind_ctls_get - Get callback for a generic bound control
- *
- * The control element is supposed to have the private_value field
- * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros.
- */
-int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct hda_bind_ctls *c;
- int err;
-
- mutex_lock(&codec->control_mutex);
- c = (struct hda_bind_ctls *)kcontrol->private_value;
- kcontrol->private_value = *c->values;
- err = c->ops->get(kcontrol, ucontrol);
- kcontrol->private_value = (long)c;
- mutex_unlock(&codec->control_mutex);
- return err;
-}
-EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_get);
-
-/**
- * snd_hda_mixer_bind_ctls_put - Put callback for a generic bound control
- *
- * The control element is supposed to have the private_value field
- * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros.
- */
-int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct hda_bind_ctls *c;
- unsigned long *vals;
- int err = 0, change = 0;
-
- mutex_lock(&codec->control_mutex);
- c = (struct hda_bind_ctls *)kcontrol->private_value;
- for (vals = c->values; *vals; vals++) {
- kcontrol->private_value = *vals;
- err = c->ops->put(kcontrol, ucontrol);
- if (err < 0)
- break;
- change |= err;
- }
- kcontrol->private_value = (long)c;
- mutex_unlock(&codec->control_mutex);
- return err < 0 ? err : change;
-}
-EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_put);
-
-/**
- * snd_hda_mixer_bind_tlv - TLV callback for a generic bound control
- *
- * The control element is supposed to have the private_value field
- * set up via HDA_BIND_VOL() macro.
- */
-int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
- unsigned int size, unsigned int __user *tlv)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct hda_bind_ctls *c;
- int err;
-
- mutex_lock(&codec->control_mutex);
- c = (struct hda_bind_ctls *)kcontrol->private_value;
- kcontrol->private_value = *c->values;
- err = c->ops->tlv(kcontrol, op_flag, size, tlv);
- kcontrol->private_value = (long)c;
- mutex_unlock(&codec->control_mutex);
- return err;
-}
-EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_tlv);
-
-struct hda_ctl_ops snd_hda_bind_vol = {
- .info = snd_hda_mixer_amp_volume_info,
- .get = snd_hda_mixer_amp_volume_get,
- .put = snd_hda_mixer_amp_volume_put,
- .tlv = snd_hda_mixer_amp_tlv
-};
-EXPORT_SYMBOL_HDA(snd_hda_bind_vol);
-
-struct hda_ctl_ops snd_hda_bind_sw = {
- .info = snd_hda_mixer_amp_switch_info,
- .get = snd_hda_mixer_amp_switch_get,
- .put = snd_hda_mixer_amp_switch_put,
- .tlv = snd_hda_mixer_amp_tlv
-};
-EXPORT_SYMBOL_HDA(snd_hda_bind_sw);
-
-/*
- * SPDIF out controls
- */
-
-static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
- IEC958_AES0_NONAUDIO |
- IEC958_AES0_CON_EMPHASIS_5015 |
- IEC958_AES0_CON_NOT_COPYRIGHT;
- ucontrol->value.iec958.status[1] = IEC958_AES1_CON_CATEGORY |
- IEC958_AES1_CON_ORIGINAL;
- return 0;
-}
-
-static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
- IEC958_AES0_NONAUDIO |
- IEC958_AES0_PRO_EMPHASIS_5015;
- return 0;
-}
-
-static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- int idx = kcontrol->private_value;
- struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
-
- ucontrol->value.iec958.status[0] = spdif->status & 0xff;
- ucontrol->value.iec958.status[1] = (spdif->status >> 8) & 0xff;
- ucontrol->value.iec958.status[2] = (spdif->status >> 16) & 0xff;
- ucontrol->value.iec958.status[3] = (spdif->status >> 24) & 0xff;
-
- return 0;
-}
-
-/* convert from SPDIF status bits to HDA SPDIF bits
- * bit 0 (DigEn) is always set zero (to be filled later)
- */
-static unsigned short convert_from_spdif_status(unsigned int sbits)
-{
- unsigned short val = 0;
-
- if (sbits & IEC958_AES0_PROFESSIONAL)
- val |= AC_DIG1_PROFESSIONAL;
- if (sbits & IEC958_AES0_NONAUDIO)
- val |= AC_DIG1_NONAUDIO;
- if (sbits & IEC958_AES0_PROFESSIONAL) {
- if ((sbits & IEC958_AES0_PRO_EMPHASIS) ==
- IEC958_AES0_PRO_EMPHASIS_5015)
- val |= AC_DIG1_EMPHASIS;
- } else {
- if ((sbits & IEC958_AES0_CON_EMPHASIS) ==
- IEC958_AES0_CON_EMPHASIS_5015)
- val |= AC_DIG1_EMPHASIS;
- if (!(sbits & IEC958_AES0_CON_NOT_COPYRIGHT))
- val |= AC_DIG1_COPYRIGHT;
- if (sbits & (IEC958_AES1_CON_ORIGINAL << 8))
- val |= AC_DIG1_LEVEL;
- val |= sbits & (IEC958_AES1_CON_CATEGORY << 8);
- }
- return val;
-}
-
-/* convert to SPDIF status bits from HDA SPDIF bits
- */
-static unsigned int convert_to_spdif_status(unsigned short val)
-{
- unsigned int sbits = 0;
-
- if (val & AC_DIG1_NONAUDIO)
- sbits |= IEC958_AES0_NONAUDIO;
- if (val & AC_DIG1_PROFESSIONAL)
- sbits |= IEC958_AES0_PROFESSIONAL;
- if (sbits & IEC958_AES0_PROFESSIONAL) {
- if (sbits & AC_DIG1_EMPHASIS)
- sbits |= IEC958_AES0_PRO_EMPHASIS_5015;
- } else {
- if (val & AC_DIG1_EMPHASIS)
- sbits |= IEC958_AES0_CON_EMPHASIS_5015;
- if (!(val & AC_DIG1_COPYRIGHT))
- sbits |= IEC958_AES0_CON_NOT_COPYRIGHT;
- if (val & AC_DIG1_LEVEL)
- sbits |= (IEC958_AES1_CON_ORIGINAL << 8);
- sbits |= val & (0x7f << 8);
- }
- return sbits;
-}
-
-/* set digital convert verbs both for the given NID and its slaves */
-static void set_dig_out(struct hda_codec *codec, hda_nid_t nid,
- int verb, int val)
-{
- const hda_nid_t *d;
-
- snd_hda_codec_write_cache(codec, nid, 0, verb, val);
- d = codec->slave_dig_outs;
- if (!d)
- return;
- for (; *d; d++)
- snd_hda_codec_write_cache(codec, *d, 0, verb, val);
-}
-
-static inline void set_dig_out_convert(struct hda_codec *codec, hda_nid_t nid,
- int dig1, int dig2)
-{
- if (dig1 != -1)
- set_dig_out(codec, nid, AC_VERB_SET_DIGI_CONVERT_1, dig1);
- if (dig2 != -1)
- set_dig_out(codec, nid, AC_VERB_SET_DIGI_CONVERT_2, dig2);
-}
-
-static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- int idx = kcontrol->private_value;
- struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
- hda_nid_t nid = spdif->nid;
- unsigned short val;
- int change;
-
- mutex_lock(&codec->spdif_mutex);
- spdif->status = ucontrol->value.iec958.status[0] |
- ((unsigned int)ucontrol->value.iec958.status[1] << 8) |
- ((unsigned int)ucontrol->value.iec958.status[2] << 16) |
- ((unsigned int)ucontrol->value.iec958.status[3] << 24);
- val = convert_from_spdif_status(spdif->status);
- val |= spdif->ctls & 1;
- change = spdif->ctls != val;
- spdif->ctls = val;
- if (change && nid != (u16)-1)
- set_dig_out_convert(codec, nid, val & 0xff, (val >> 8) & 0xff);
- mutex_unlock(&codec->spdif_mutex);
- return change;
-}
-
-#define snd_hda_spdif_out_switch_info snd_ctl_boolean_mono_info
-
-static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- int idx = kcontrol->private_value;
- struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
-
- ucontrol->value.integer.value[0] = spdif->ctls & AC_DIG1_ENABLE;
- return 0;
-}
-
-static inline void set_spdif_ctls(struct hda_codec *codec, hda_nid_t nid,
- int dig1, int dig2)
-{
- set_dig_out_convert(codec, nid, dig1, dig2);
- /* unmute amp switch (if any) */
- if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
- (dig1 & AC_DIG1_ENABLE))
- snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, 0);
-}
-
-static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- int idx = kcontrol->private_value;
- struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
- hda_nid_t nid = spdif->nid;
- unsigned short val;
- int change;
-
- mutex_lock(&codec->spdif_mutex);
- val = spdif->ctls & ~AC_DIG1_ENABLE;
- if (ucontrol->value.integer.value[0])
- val |= AC_DIG1_ENABLE;
- change = spdif->ctls != val;
- spdif->ctls = val;
- if (change && nid != (u16)-1)
- set_spdif_ctls(codec, nid, val & 0xff, -1);
- mutex_unlock(&codec->spdif_mutex);
- return change;
-}
-
-static struct snd_kcontrol_new dig_mixes[] = {
- {
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
- .info = snd_hda_spdif_mask_info,
- .get = snd_hda_spdif_cmask_get,
- },
- {
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK),
- .info = snd_hda_spdif_mask_info,
- .get = snd_hda_spdif_pmask_get,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
- .info = snd_hda_spdif_mask_info,
- .get = snd_hda_spdif_default_get,
- .put = snd_hda_spdif_default_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
- .info = snd_hda_spdif_out_switch_info,
- .get = snd_hda_spdif_out_switch_get,
- .put = snd_hda_spdif_out_switch_put,
- },
- { } /* end */
-};
-
-/**
- * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls
- * @codec: the HDA codec
- * @nid: audio out widget NID
- *
- * Creates controls related with the SPDIF output.
- * Called from each patch supporting the SPDIF out.
- *
- * Returns 0 if successful, or a negative error code.
- */
-int snd_hda_create_spdif_out_ctls(struct hda_codec *codec,
- hda_nid_t associated_nid,
- hda_nid_t cvt_nid)
-{
- int err;
- struct snd_kcontrol *kctl;
- struct snd_kcontrol_new *dig_mix;
- int idx;
- struct hda_spdif_out *spdif;
-
- idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch");
- if (idx < 0) {
- printk(KERN_ERR "hda_codec: too many IEC958 outputs\n");
- return -EBUSY;
- }
- spdif = snd_array_new(&codec->spdif_out);
- for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
- kctl = snd_ctl_new1(dig_mix, codec);
- if (!kctl)
- return -ENOMEM;
- kctl->id.index = idx;
- kctl->private_value = codec->spdif_out.used - 1;
- err = snd_hda_ctl_add(codec, associated_nid, kctl);
- if (err < 0)
- return err;
- }
- spdif->nid = cvt_nid;
- spdif->ctls = snd_hda_codec_read(codec, cvt_nid, 0,
- AC_VERB_GET_DIGI_CONVERT_1, 0);
- spdif->status = convert_to_spdif_status(spdif->ctls);
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_create_spdif_out_ctls);
-
-struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec,
- hda_nid_t nid)
-{
- int i;
- for (i = 0; i < codec->spdif_out.used; i++) {
- struct hda_spdif_out *spdif =
- snd_array_elem(&codec->spdif_out, i);
- if (spdif->nid == nid)
- return spdif;
- }
- return NULL;
-}
-EXPORT_SYMBOL_HDA(snd_hda_spdif_out_of_nid);
-
-void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx)
-{
- struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
-
- mutex_lock(&codec->spdif_mutex);
- spdif->nid = (u16)-1;
- mutex_unlock(&codec->spdif_mutex);
-}
-EXPORT_SYMBOL_HDA(snd_hda_spdif_ctls_unassign);
-
-void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid)
-{
- struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
- unsigned short val;
-
- mutex_lock(&codec->spdif_mutex);
- if (spdif->nid != nid) {
- spdif->nid = nid;
- val = spdif->ctls;
- set_spdif_ctls(codec, nid, val & 0xff, (val >> 8) & 0xff);
- }
- mutex_unlock(&codec->spdif_mutex);
-}
-EXPORT_SYMBOL_HDA(snd_hda_spdif_ctls_assign);
-
-/*
- * SPDIF sharing with analog output
- */
-static int spdif_share_sw_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_multi_out *mout = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = mout->share_spdif;
- return 0;
-}
-
-static int spdif_share_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_multi_out *mout = snd_kcontrol_chip(kcontrol);
- mout->share_spdif = !!ucontrol->value.integer.value[0];
- return 0;
-}
-
-static struct snd_kcontrol_new spdif_share_sw = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "IEC958 Default PCM Playback Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = spdif_share_sw_get,
- .put = spdif_share_sw_put,
-};
-
-/**
- * snd_hda_create_spdif_share_sw - create Default PCM switch
- * @codec: the HDA codec
- * @mout: multi-out instance
- */
-int snd_hda_create_spdif_share_sw(struct hda_codec *codec,
- struct hda_multi_out *mout)
-{
- if (!mout->dig_out_nid)
- return 0;
- /* ATTENTION: here mout is passed as private_data, instead of codec */
- return snd_hda_ctl_add(codec, mout->dig_out_nid,
- snd_ctl_new1(&spdif_share_sw, mout));
-}
-EXPORT_SYMBOL_HDA(snd_hda_create_spdif_share_sw);
-
-/*
- * SPDIF input
- */
-
-#define snd_hda_spdif_in_switch_info snd_hda_spdif_out_switch_info
-
-static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = codec->spdif_in_enable;
- return 0;
-}
-
-static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- hda_nid_t nid = kcontrol->private_value;
- unsigned int val = !!ucontrol->value.integer.value[0];
- int change;
-
- mutex_lock(&codec->spdif_mutex);
- change = codec->spdif_in_enable != val;
- if (change) {
- codec->spdif_in_enable = val;
- snd_hda_codec_write_cache(codec, nid, 0,
- AC_VERB_SET_DIGI_CONVERT_1, val);
- }
- mutex_unlock(&codec->spdif_mutex);
- return change;
-}
-
-static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- hda_nid_t nid = kcontrol->private_value;
- unsigned short val;
- unsigned int sbits;
-
- val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT_1, 0);
- sbits = convert_to_spdif_status(val);
- ucontrol->value.iec958.status[0] = sbits;
- ucontrol->value.iec958.status[1] = sbits >> 8;
- ucontrol->value.iec958.status[2] = sbits >> 16;
- ucontrol->value.iec958.status[3] = sbits >> 24;
- return 0;
-}
-
-static struct snd_kcontrol_new dig_in_ctls[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
- .info = snd_hda_spdif_in_switch_info,
- .get = snd_hda_spdif_in_switch_get,
- .put = snd_hda_spdif_in_switch_put,
- },
- {
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
- .info = snd_hda_spdif_mask_info,
- .get = snd_hda_spdif_in_status_get,
- },
- { } /* end */
-};
-
-/**
- * snd_hda_create_spdif_in_ctls - create Input SPDIF-related controls
- * @codec: the HDA codec
- * @nid: audio in widget NID
- *
- * Creates controls related with the SPDIF input.
- * Called from each patch supporting the SPDIF in.
- *
- * Returns 0 if successful, or a negative error code.
- */
-int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
-{
- int err;
- struct snd_kcontrol *kctl;
- struct snd_kcontrol_new *dig_mix;
- int idx;
-
- idx = find_empty_mixer_ctl_idx(codec, "IEC958 Capture Switch");
- if (idx < 0) {
- printk(KERN_ERR "hda_codec: too many IEC958 inputs\n");
- return -EBUSY;
- }
- for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) {
- kctl = snd_ctl_new1(dig_mix, codec);
- if (!kctl)
- return -ENOMEM;
- kctl->private_value = nid;
- err = snd_hda_ctl_add(codec, nid, kctl);
- if (err < 0)
- return err;
- }
- codec->spdif_in_enable =
- snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_DIGI_CONVERT_1, 0) &
- AC_DIG1_ENABLE;
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_create_spdif_in_ctls);
-
-#ifdef CONFIG_PM
-/*
- * command cache
- */
-
-/* build a 32bit cache key with the widget id and the command parameter */
-#define build_cmd_cache_key(nid, verb) ((verb << 8) | nid)
-#define get_cmd_cache_nid(key) ((key) & 0xff)
-#define get_cmd_cache_cmd(key) (((key) >> 8) & 0xffff)
-
-/**
- * snd_hda_codec_write_cache - send a single command with caching
- * @codec: the HDA codec
- * @nid: NID to send the command
- * @direct: direct flag
- * @verb: the verb to send
- * @parm: the parameter for the verb
- *
- * Send a single command without waiting for response.
- *
- * Returns 0 if successful, or a negative error code.
- */
-int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
- int direct, unsigned int verb, unsigned int parm)
-{
- int err = snd_hda_codec_write(codec, nid, direct, verb, parm);
- struct hda_cache_head *c;
- u32 key;
-
- if (err < 0)
- return err;
- /* parm may contain the verb stuff for get/set amp */
- verb = verb | (parm >> 8);
- parm &= 0xff;
- key = build_cmd_cache_key(nid, verb);
- mutex_lock(&codec->bus->cmd_mutex);
- c = get_alloc_hash(&codec->cmd_cache, key);
- if (c)
- c->val = parm;
- mutex_unlock(&codec->bus->cmd_mutex);
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache);
-
-/**
- * snd_hda_codec_update_cache - check cache and write the cmd only when needed
- * @codec: the HDA codec
- * @nid: NID to send the command
- * @direct: direct flag
- * @verb: the verb to send
- * @parm: the parameter for the verb
- *
- * This function works like snd_hda_codec_write_cache(), but it doesn't send
- * command if the parameter is already identical with the cached value.
- * If not, it sends the command and refreshes the cache.
- *
- * Returns 0 if successful, or a negative error code.
- */
-int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid,
- int direct, unsigned int verb, unsigned int parm)
-{
- struct hda_cache_head *c;
- u32 key;
-
- /* parm may contain the verb stuff for get/set amp */
- verb = verb | (parm >> 8);
- parm &= 0xff;
- key = build_cmd_cache_key(nid, verb);
- mutex_lock(&codec->bus->cmd_mutex);
- c = get_hash(&codec->cmd_cache, key);
- if (c && c->val == parm) {
- mutex_unlock(&codec->bus->cmd_mutex);
- return 0;
- }
- mutex_unlock(&codec->bus->cmd_mutex);
- return snd_hda_codec_write_cache(codec, nid, direct, verb, parm);
-}
-EXPORT_SYMBOL_HDA(snd_hda_codec_update_cache);
-
-/**
- * snd_hda_codec_resume_cache - Resume the all commands from the cache
- * @codec: HD-audio codec
- *
- * Execute all verbs recorded in the command caches to resume.
- */
-void snd_hda_codec_resume_cache(struct hda_codec *codec)
-{
- struct hda_cache_head *buffer = codec->cmd_cache.buf.list;
- int i;
-
- for (i = 0; i < codec->cmd_cache.buf.used; i++, buffer++) {
- u32 key = buffer->key;
- if (!key)
- continue;
- snd_hda_codec_write(codec, get_cmd_cache_nid(key), 0,
- get_cmd_cache_cmd(key), buffer->val);
- }
-}
-EXPORT_SYMBOL_HDA(snd_hda_codec_resume_cache);
-
-/**
- * snd_hda_sequence_write_cache - sequence writes with caching
- * @codec: the HDA codec
- * @seq: VERB array to send
- *
- * Send the commands sequentially from the given array.
- * Thte commands are recorded on cache for power-save and resume.
- * The array must be terminated with NID=0.
- */
-void snd_hda_sequence_write_cache(struct hda_codec *codec,
- const struct hda_verb *seq)
-{
- for (; seq->nid; seq++)
- snd_hda_codec_write_cache(codec, seq->nid, 0, seq->verb,
- seq->param);
-}
-EXPORT_SYMBOL_HDA(snd_hda_sequence_write_cache);
-#endif /* CONFIG_PM */
-
-void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
- unsigned int power_state,
- bool eapd_workaround)
-{
- hda_nid_t nid = codec->start_nid;
- int i;
-
- for (i = 0; i < codec->num_nodes; i++, nid++) {
- unsigned int wcaps = get_wcaps(codec, nid);
- if (!(wcaps & AC_WCAP_POWER))
- continue;
- /* don't power down the widget if it controls eapd and
- * EAPD_BTLENABLE is set.
- */
- if (eapd_workaround && power_state == AC_PWRST_D3 &&
- get_wcaps_type(wcaps) == AC_WID_PIN &&
- (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) {
- int eapd = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_EAPD_BTLENABLE, 0);
- if (eapd & 0x02)
- continue;
- }
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE,
- power_state);
- }
-
- if (power_state == AC_PWRST_D0) {
- unsigned long end_time;
- int state;
- /* wait until the codec reachs to D0 */
- end_time = jiffies + msecs_to_jiffies(500);
- do {
- state = snd_hda_codec_read(codec, fg, 0,
- AC_VERB_GET_POWER_STATE, 0);
- if (state == power_state)
- break;
- msleep(1);
- } while (time_after_eq(end_time, jiffies));
- }
-}
-EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all);
-
-/*
- * set power state of the codec
- */
-static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
- unsigned int power_state)
-{
- if (codec->patch_ops.set_power_state) {
- codec->patch_ops.set_power_state(codec, fg, power_state);
- return;
- }
-
- /* this delay seems necessary to avoid click noise at power-down */
- if (power_state == AC_PWRST_D3)
- msleep(100);
- snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
- power_state);
- snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
-}
-
-#ifdef CONFIG_SND_HDA_HWDEP
-/* execute additional init verbs */
-static void hda_exec_init_verbs(struct hda_codec *codec)
-{
- if (codec->init_verbs.list)
- snd_hda_sequence_write(codec, codec->init_verbs.list);
-}
-#else
-static inline void hda_exec_init_verbs(struct hda_codec *codec) {}
-#endif
-
-#ifdef CONFIG_PM
-/*
- * call suspend and power-down; used both from PM and power-save
- */
-static void hda_call_codec_suspend(struct hda_codec *codec)
-{
- if (codec->patch_ops.suspend)
- codec->patch_ops.suspend(codec, PMSG_SUSPEND);
- hda_cleanup_all_streams(codec);
- hda_set_power_state(codec,
- codec->afg ? codec->afg : codec->mfg,
- AC_PWRST_D3);
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- snd_hda_update_power_acct(codec);
- cancel_delayed_work(&codec->power_work);
- codec->power_on = 0;
- codec->power_transition = 0;
- codec->power_jiffies = jiffies;
-#endif
-}
-
-/*
- * kick up codec; used both from PM and power-save
- */
-static void hda_call_codec_resume(struct hda_codec *codec)
-{
- hda_set_power_state(codec,
- codec->afg ? codec->afg : codec->mfg,
- AC_PWRST_D0);
- restore_pincfgs(codec); /* restore all current pin configs */
- restore_shutup_pins(codec);
- hda_exec_init_verbs(codec);
- snd_hda_jack_set_dirty_all(codec);
- if (codec->patch_ops.resume)
- codec->patch_ops.resume(codec);
- else {
- if (codec->patch_ops.init)
- codec->patch_ops.init(codec);
- snd_hda_codec_resume_amp(codec);
- snd_hda_codec_resume_cache(codec);
- }
-}
-#endif /* CONFIG_PM */
-
-
-/**
- * snd_hda_build_controls - build mixer controls
- * @bus: the BUS
- *
- * Creates mixer controls for each codec included in the bus.
- *
- * Returns 0 if successful, otherwise a negative error code.
- */
-int /*__devinit*/ snd_hda_build_controls(struct hda_bus *bus)
-{
- struct hda_codec *codec;
-
- list_for_each_entry(codec, &bus->codec_list, list) {
- int err = snd_hda_codec_build_controls(codec);
- if (err < 0) {
- printk(KERN_ERR "hda_codec: cannot build controls "
- "for #%d (error %d)\n", codec->addr, err);
- err = snd_hda_codec_reset(codec);
- if (err < 0) {
- printk(KERN_ERR
- "hda_codec: cannot revert codec\n");
- return err;
- }
- }
- }
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_build_controls);
-
-int snd_hda_codec_build_controls(struct hda_codec *codec)
-{
- int err = 0;
- hda_exec_init_verbs(codec);
- /* continue to initialize... */
- if (codec->patch_ops.init)
- err = codec->patch_ops.init(codec);
- if (!err && codec->patch_ops.build_controls)
- err = codec->patch_ops.build_controls(codec);
- if (err < 0)
- return err;
- return 0;
-}
-
-/*
- * stream formats
- */
-struct hda_rate_tbl {
- unsigned int hz;
- unsigned int alsa_bits;
- unsigned int hda_fmt;
-};
-
-/* rate = base * mult / div */
-#define HDA_RATE(base, mult, div) \
- (AC_FMT_BASE_##base##K | (((mult) - 1) << AC_FMT_MULT_SHIFT) | \
- (((div) - 1) << AC_FMT_DIV_SHIFT))
-
-static struct hda_rate_tbl rate_bits[] = {
- /* rate in Hz, ALSA rate bitmask, HDA format value */
-
- /* autodetected value used in snd_hda_query_supported_pcm */
- { 8000, SNDRV_PCM_RATE_8000, HDA_RATE(48, 1, 6) },
- { 11025, SNDRV_PCM_RATE_11025, HDA_RATE(44, 1, 4) },
- { 16000, SNDRV_PCM_RATE_16000, HDA_RATE(48, 1, 3) },
- { 22050, SNDRV_PCM_RATE_22050, HDA_RATE(44, 1, 2) },
- { 32000, SNDRV_PCM_RATE_32000, HDA_RATE(48, 2, 3) },
- { 44100, SNDRV_PCM_RATE_44100, HDA_RATE(44, 1, 1) },
- { 48000, SNDRV_PCM_RATE_48000, HDA_RATE(48, 1, 1) },
- { 88200, SNDRV_PCM_RATE_88200, HDA_RATE(44, 2, 1) },
- { 96000, SNDRV_PCM_RATE_96000, HDA_RATE(48, 2, 1) },
- { 176400, SNDRV_PCM_RATE_176400, HDA_RATE(44, 4, 1) },
- { 192000, SNDRV_PCM_RATE_192000, HDA_RATE(48, 4, 1) },
-#define AC_PAR_PCM_RATE_BITS 11
- /* up to bits 10, 384kHZ isn't supported properly */
-
- /* not autodetected value */
- { 9600, SNDRV_PCM_RATE_KNOT, HDA_RATE(48, 1, 5) },
-
- { 0 } /* terminator */
-};
-
-/**
- * snd_hda_calc_stream_format - calculate format bitset
- * @rate: the sample rate
- * @channels: the number of channels
- * @format: the PCM format (SNDRV_PCM_FORMAT_XXX)
- * @maxbps: the max. bps
- *
- * Calculate the format bitset from the given rate, channels and th PCM format.
- *
- * Return zero if invalid.
- */
-unsigned int snd_hda_calc_stream_format(unsigned int rate,
- unsigned int channels,
- unsigned int format,
- unsigned int maxbps,
- unsigned short spdif_ctls)
-{
- int i;
- unsigned int val = 0;
-
- for (i = 0; rate_bits[i].hz; i++)
- if (rate_bits[i].hz == rate) {
- val = rate_bits[i].hda_fmt;
- break;
- }
- if (!rate_bits[i].hz) {
- snd_printdd("invalid rate %d\n", rate);
- return 0;
- }
-
- if (channels == 0 || channels > 8) {
- snd_printdd("invalid channels %d\n", channels);
- return 0;
- }
- val |= channels - 1;
-
- switch (snd_pcm_format_width(format)) {
- case 8:
- val |= AC_FMT_BITS_8;
- break;
- case 16:
- val |= AC_FMT_BITS_16;
- break;
- case 20:
- case 24:
- case 32:
- if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE)
- val |= AC_FMT_BITS_32;
- else if (maxbps >= 24)
- val |= AC_FMT_BITS_24;
- else
- val |= AC_FMT_BITS_20;
- break;
- default:
- snd_printdd("invalid format width %d\n",
- snd_pcm_format_width(format));
- return 0;
- }
-
- if (spdif_ctls & AC_DIG1_NONAUDIO)
- val |= AC_FMT_TYPE_NON_PCM;
-
- return val;
-}
-EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format);
-
-static unsigned int get_pcm_param(struct hda_codec *codec, hda_nid_t nid)
-{
- unsigned int val = 0;
- if (nid != codec->afg &&
- (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD))
- val = snd_hda_param_read(codec, nid, AC_PAR_PCM);
- if (!val || val == -1)
- val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);
- if (!val || val == -1)
- return 0;
- return val;
-}
-
-static unsigned int query_pcm_param(struct hda_codec *codec, hda_nid_t nid)
-{
- return query_caps_hash(codec, nid, HDA_HASH_PARPCM_KEY(nid),
- get_pcm_param);
-}
-
-static unsigned int get_stream_param(struct hda_codec *codec, hda_nid_t nid)
-{
- unsigned int streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
- if (!streams || streams == -1)
- streams = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM);
- if (!streams || streams == -1)
- return 0;
- return streams;
-}
-
-static unsigned int query_stream_param(struct hda_codec *codec, hda_nid_t nid)
-{
- return query_caps_hash(codec, nid, HDA_HASH_PARSTR_KEY(nid),
- get_stream_param);
-}
-
-/**
- * snd_hda_query_supported_pcm - query the supported PCM rates and formats
- * @codec: the HDA codec
- * @nid: NID to query
- * @ratesp: the pointer to store the detected rate bitflags
- * @formatsp: the pointer to store the detected formats
- * @bpsp: the pointer to store the detected format widths
- *
- * Queries the supported PCM rates and formats. The NULL @ratesp, @formatsp
- * or @bsps argument is ignored.
- *
- * Returns 0 if successful, otherwise a negative error code.
- */
-int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
- u32 *ratesp, u64 *formatsp, unsigned int *bpsp)
-{
- unsigned int i, val, wcaps;
-
- wcaps = get_wcaps(codec, nid);
- val = query_pcm_param(codec, nid);
-
- if (ratesp) {
- u32 rates = 0;
- for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) {
- if (val & (1 << i))
- rates |= rate_bits[i].alsa_bits;
- }
- if (rates == 0) {
- snd_printk(KERN_ERR "hda_codec: rates == 0 "
- "(nid=0x%x, val=0x%x, ovrd=%i)\n",
- nid, val,
- (wcaps & AC_WCAP_FORMAT_OVRD) ? 1 : 0);
- return -EIO;
- }
- *ratesp = rates;
- }
-
- if (formatsp || bpsp) {
- u64 formats = 0;
- unsigned int streams, bps;
-
- streams = query_stream_param(codec, nid);
- if (!streams)
- return -EIO;
-
- bps = 0;
- if (streams & AC_SUPFMT_PCM) {
- if (val & AC_SUPPCM_BITS_8) {
- formats |= SNDRV_PCM_FMTBIT_U8;
- bps = 8;
- }
- if (val & AC_SUPPCM_BITS_16) {
- formats |= SNDRV_PCM_FMTBIT_S16_LE;
- bps = 16;
- }
- if (wcaps & AC_WCAP_DIGITAL) {
- if (val & AC_SUPPCM_BITS_32)
- formats |= SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
- if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24))
- formats |= SNDRV_PCM_FMTBIT_S32_LE;
- if (val & AC_SUPPCM_BITS_24)
- bps = 24;
- else if (val & AC_SUPPCM_BITS_20)
- bps = 20;
- } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|
- AC_SUPPCM_BITS_32)) {
- formats |= SNDRV_PCM_FMTBIT_S32_LE;
- if (val & AC_SUPPCM_BITS_32)
- bps = 32;
- else if (val & AC_SUPPCM_BITS_24)
- bps = 24;
- else if (val & AC_SUPPCM_BITS_20)
- bps = 20;
- }
- }
- if (streams & AC_SUPFMT_FLOAT32) {
- formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
- if (!bps)
- bps = 32;
- }
- if (streams == AC_SUPFMT_AC3) {
- /* should be exclusive */
- /* temporary hack: we have still no proper support
- * for the direct AC3 stream...
- */
- formats |= SNDRV_PCM_FMTBIT_U8;
- bps = 8;
- }
- if (formats == 0) {
- snd_printk(KERN_ERR "hda_codec: formats == 0 "
- "(nid=0x%x, val=0x%x, ovrd=%i, "
- "streams=0x%x)\n",
- nid, val,
- (wcaps & AC_WCAP_FORMAT_OVRD) ? 1 : 0,
- streams);
- return -EIO;
- }
- if (formatsp)
- *formatsp = formats;
- if (bpsp)
- *bpsp = bps;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_query_supported_pcm);
-
-/**
- * snd_hda_is_supported_format - Check the validity of the format
- * @codec: HD-audio codec
- * @nid: NID to check
- * @format: the HD-audio format value to check
- *
- * Check whether the given node supports the format value.
- *
- * Returns 1 if supported, 0 if not.
- */
-int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
- unsigned int format)
-{
- int i;
- unsigned int val = 0, rate, stream;
-
- val = query_pcm_param(codec, nid);
- if (!val)
- return 0;
-
- rate = format & 0xff00;
- for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++)
- if (rate_bits[i].hda_fmt == rate) {
- if (val & (1 << i))
- break;
- return 0;
- }
- if (i >= AC_PAR_PCM_RATE_BITS)
- return 0;
-
- stream = query_stream_param(codec, nid);
- if (!stream)
- return 0;
-
- if (stream & AC_SUPFMT_PCM) {
- switch (format & 0xf0) {
- case 0x00:
- if (!(val & AC_SUPPCM_BITS_8))
- return 0;
- break;
- case 0x10:
- if (!(val & AC_SUPPCM_BITS_16))
- return 0;
- break;
- case 0x20:
- if (!(val & AC_SUPPCM_BITS_20))
- return 0;
- break;
- case 0x30:
- if (!(val & AC_SUPPCM_BITS_24))
- return 0;
- break;
- case 0x40:
- if (!(val & AC_SUPPCM_BITS_32))
- return 0;
- break;
- default:
- return 0;
- }
- } else {
- /* FIXME: check for float32 and AC3? */
- }
-
- return 1;
-}
-EXPORT_SYMBOL_HDA(snd_hda_is_supported_format);
-
-/*
- * PCM stuff
- */
-static int hda_pcm_default_open_close(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- return 0;
-}
-
-static int hda_pcm_default_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format);
- return 0;
-}
-
-static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- snd_hda_codec_cleanup_stream(codec, hinfo->nid);
- return 0;
-}
-
-static int set_pcm_default_values(struct hda_codec *codec,
- struct hda_pcm_stream *info)
-{
- int err;
-
- /* query support PCM information from the given NID */
- if (info->nid && (!info->rates || !info->formats)) {
- err = snd_hda_query_supported_pcm(codec, info->nid,
- info->rates ? NULL : &info->rates,
- info->formats ? NULL : &info->formats,
- info->maxbps ? NULL : &info->maxbps);
- if (err < 0)
- return err;
- }
- if (info->ops.open == NULL)
- info->ops.open = hda_pcm_default_open_close;
- if (info->ops.close == NULL)
- info->ops.close = hda_pcm_default_open_close;
- if (info->ops.prepare == NULL) {
- if (snd_BUG_ON(!info->nid))
- return -EINVAL;
- info->ops.prepare = hda_pcm_default_prepare;
- }
- if (info->ops.cleanup == NULL) {
- if (snd_BUG_ON(!info->nid))
- return -EINVAL;
- info->ops.cleanup = hda_pcm_default_cleanup;
- }
- return 0;
-}
-
-/*
- * codec prepare/cleanup entries
- */
-int snd_hda_codec_prepare(struct hda_codec *codec,
- struct hda_pcm_stream *hinfo,
- unsigned int stream,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- int ret;
- mutex_lock(&codec->bus->prepare_mutex);
- ret = hinfo->ops.prepare(hinfo, codec, stream, format, substream);
- if (ret >= 0)
- purify_inactive_streams(codec);
- mutex_unlock(&codec->bus->prepare_mutex);
- return ret;
-}
-EXPORT_SYMBOL_HDA(snd_hda_codec_prepare);
-
-void snd_hda_codec_cleanup(struct hda_codec *codec,
- struct hda_pcm_stream *hinfo,
- struct snd_pcm_substream *substream)
-{
- mutex_lock(&codec->bus->prepare_mutex);
- hinfo->ops.cleanup(hinfo, codec, substream);
- mutex_unlock(&codec->bus->prepare_mutex);
-}
-EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup);
-
-/* global */
-const char *snd_hda_pcm_type_name[HDA_PCM_NTYPES] = {
- "Audio", "SPDIF", "HDMI", "Modem"
-};
-
-/*
- * get the empty PCM device number to assign
- *
- * note the max device number is limited by HDA_MAX_PCMS, currently 10
- */
-static int get_empty_pcm_device(struct hda_bus *bus, int type)
-{
- /* audio device indices; not linear to keep compatibility */
- static int audio_idx[HDA_PCM_NTYPES][5] = {
- [HDA_PCM_TYPE_AUDIO] = { 0, 2, 4, 5, -1 },
- [HDA_PCM_TYPE_SPDIF] = { 1, -1 },
- [HDA_PCM_TYPE_HDMI] = { 3, 7, 8, 9, -1 },
- [HDA_PCM_TYPE_MODEM] = { 6, -1 },
- };
- int i;
-
- if (type >= HDA_PCM_NTYPES) {
- snd_printk(KERN_WARNING "Invalid PCM type %d\n", type);
- return -EINVAL;
- }
-
- for (i = 0; audio_idx[type][i] >= 0 ; i++)
- if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits))
- return audio_idx[type][i];
-
- /* non-fixed slots starting from 10 */
- for (i = 10; i < 32; i++) {
- if (!test_and_set_bit(i, bus->pcm_dev_bits))
- return i;
- }
-
- snd_printk(KERN_WARNING "Too many %s devices\n",
- snd_hda_pcm_type_name[type]);
- return -EAGAIN;
-}
-
-/*
- * attach a new PCM stream
- */
-static int snd_hda_attach_pcm(struct hda_codec *codec, struct hda_pcm *pcm)
-{
- struct hda_bus *bus = codec->bus;
- struct hda_pcm_stream *info;
- int stream, err;
-
- if (snd_BUG_ON(!pcm->name))
- return -EINVAL;
- for (stream = 0; stream < 2; stream++) {
- info = &pcm->stream[stream];
- if (info->substreams) {
- err = set_pcm_default_values(codec, info);
- if (err < 0)
- return err;
- }
- }
- return bus->ops.attach_pcm(bus, codec, pcm);
-}
-
-/* assign all PCMs of the given codec */
-int snd_hda_codec_build_pcms(struct hda_codec *codec)
-{
- unsigned int pcm;
- int err;
-
- if (!codec->num_pcms) {
- if (!codec->patch_ops.build_pcms)
- return 0;
- err = codec->patch_ops.build_pcms(codec);
- if (err < 0) {
- printk(KERN_ERR "hda_codec: cannot build PCMs"
- "for #%d (error %d)\n", codec->addr, err);
- err = snd_hda_codec_reset(codec);
- if (err < 0) {
- printk(KERN_ERR
- "hda_codec: cannot revert codec\n");
- return err;
- }
- }
- }
- for (pcm = 0; pcm < codec->num_pcms; pcm++) {
- struct hda_pcm *cpcm = &codec->pcm_info[pcm];
- int dev;
-
- if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams)
- continue; /* no substreams assigned */
-
- if (!cpcm->pcm) {
- dev = get_empty_pcm_device(codec->bus, cpcm->pcm_type);
- if (dev < 0)
- continue; /* no fatal error */
- cpcm->device = dev;
- err = snd_hda_attach_pcm(codec, cpcm);
- if (err < 0) {
- printk(KERN_ERR "hda_codec: cannot attach "
- "PCM stream %d for codec #%d\n",
- dev, codec->addr);
- continue; /* no fatal error */
- }
- }
- }
- return 0;
-}
-
-/**
- * snd_hda_build_pcms - build PCM information
- * @bus: the BUS
- *
- * Create PCM information for each codec included in the bus.
- *
- * The build_pcms codec patch is requested to set up codec->num_pcms and
- * codec->pcm_info properly. The array is referred by the top-level driver
- * to create its PCM instances.
- * The allocated codec->pcm_info should be released in codec->patch_ops.free
- * callback.
- *
- * At least, substreams, channels_min and channels_max must be filled for
- * each stream. substreams = 0 indicates that the stream doesn't exist.
- * When rates and/or formats are zero, the supported values are queried
- * from the given nid. The nid is used also by the default ops.prepare
- * and ops.cleanup callbacks.
- *
- * The driver needs to call ops.open in its open callback. Similarly,
- * ops.close is supposed to be called in the close callback.
- * ops.prepare should be called in the prepare or hw_params callback
- * with the proper parameters for set up.
- * ops.cleanup should be called in hw_free for clean up of streams.
- *
- * This function returns 0 if successful, or a negative error code.
- */
-int __devinit snd_hda_build_pcms(struct hda_bus *bus)
-{
- struct hda_codec *codec;
-
- list_for_each_entry(codec, &bus->codec_list, list) {
- int err = snd_hda_codec_build_pcms(codec);
- if (err < 0)
- return err;
- }
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_build_pcms);
-
-/**
- * snd_hda_check_board_config - compare the current codec with the config table
- * @codec: the HDA codec
- * @num_configs: number of config enums
- * @models: array of model name strings
- * @tbl: configuration table, terminated by null entries
- *
- * Compares the modelname or PCI subsystem id of the current codec with the
- * given configuration table. If a matching entry is found, returns its
- * config value (supposed to be 0 or positive).
- *
- * If no entries are matching, the function returns a negative value.
- */
-int snd_hda_check_board_config(struct hda_codec *codec,
- int num_configs, const char * const *models,
- const struct snd_pci_quirk *tbl)
-{
- if (codec->modelname && models) {
- int i;
- for (i = 0; i < num_configs; i++) {
- if (models[i] &&
- !strcmp(codec->modelname, models[i])) {
- snd_printd(KERN_INFO "hda_codec: model '%s' is "
- "selected\n", models[i]);
- return i;
- }
- }
- }
-
- if (!codec->bus->pci || !tbl)
- return -1;
-
- tbl = snd_pci_quirk_lookup(codec->bus->pci, tbl);
- if (!tbl)
- return -1;
- if (tbl->value >= 0 && tbl->value < num_configs) {
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- char tmp[10];
- const char *model = NULL;
- if (models)
- model = models[tbl->value];
- if (!model) {
- sprintf(tmp, "#%d", tbl->value);
- model = tmp;
- }
- snd_printdd(KERN_INFO "hda_codec: model '%s' is selected "
- "for config %x:%x (%s)\n",
- model, tbl->subvendor, tbl->subdevice,
- (tbl->name ? tbl->name : "Unknown device"));
-#endif
- return tbl->value;
- }
- return -1;
-}
-EXPORT_SYMBOL_HDA(snd_hda_check_board_config);
-
-/**
- * snd_hda_check_board_codec_sid_config - compare the current codec
- subsystem ID with the
- config table
-
- This is important for Gateway notebooks with SB450 HDA Audio
- where the vendor ID of the PCI device is:
- ATI Technologies Inc SB450 HDA Audio [1002:437b]
- and the vendor/subvendor are found only at the codec.
-
- * @codec: the HDA codec
- * @num_configs: number of config enums
- * @models: array of model name strings
- * @tbl: configuration table, terminated by null entries
- *
- * Compares the modelname or PCI subsystem id of the current codec with the
- * given configuration table. If a matching entry is found, returns its
- * config value (supposed to be 0 or positive).
- *
- * If no entries are matching, the function returns a negative value.
- */
-int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
- int num_configs, const char * const *models,
- const struct snd_pci_quirk *tbl)
-{
- const struct snd_pci_quirk *q;
-
- /* Search for codec ID */
- for (q = tbl; q->subvendor; q++) {
- unsigned int mask = 0xffff0000 | q->subdevice_mask;
- unsigned int id = (q->subdevice | (q->subvendor << 16)) & mask;
- if ((codec->subsystem_id & mask) == id)
- break;
- }
-
- if (!q->subvendor)
- return -1;
-
- tbl = q;
-
- if (tbl->value >= 0 && tbl->value < num_configs) {
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- char tmp[10];
- const char *model = NULL;
- if (models)
- model = models[tbl->value];
- if (!model) {
- sprintf(tmp, "#%d", tbl->value);
- model = tmp;
- }
- snd_printdd(KERN_INFO "hda_codec: model '%s' is selected "
- "for config %x:%x (%s)\n",
- model, tbl->subvendor, tbl->subdevice,
- (tbl->name ? tbl->name : "Unknown device"));
-#endif
- return tbl->value;
- }
- return -1;
-}
-EXPORT_SYMBOL_HDA(snd_hda_check_board_codec_sid_config);
-
-/**
- * snd_hda_add_new_ctls - create controls from the array
- * @codec: the HDA codec
- * @knew: the array of struct snd_kcontrol_new
- *
- * This helper function creates and add new controls in the given array.
- * The array must be terminated with an empty entry as terminator.
- *
- * Returns 0 if successful, or a negative error code.
- */
-int snd_hda_add_new_ctls(struct hda_codec *codec,
- const struct snd_kcontrol_new *knew)
-{
- int err;
-
- for (; knew->name; knew++) {
- struct snd_kcontrol *kctl;
- int addr = 0, idx = 0;
- if (knew->iface == -1) /* skip this codec private value */
- continue;
- for (;;) {
- kctl = snd_ctl_new1(knew, codec);
- if (!kctl)
- return -ENOMEM;
- if (addr > 0)
- kctl->id.device = addr;
- if (idx > 0)
- kctl->id.index = idx;
- err = snd_hda_ctl_add(codec, 0, kctl);
- if (!err)
- break;
- /* try first with another device index corresponding to
- * the codec addr; if it still fails (or it's the
- * primary codec), then try another control index
- */
- if (!addr && codec->addr)
- addr = codec->addr;
- else if (!idx && !knew->index) {
- idx = find_empty_mixer_ctl_idx(codec,
- knew->name);
- if (idx <= 0)
- return err;
- } else
- return err;
- }
- }
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls);
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static void hda_power_work(struct work_struct *work)
-{
- struct hda_codec *codec =
- container_of(work, struct hda_codec, power_work.work);
- struct hda_bus *bus = codec->bus;
-
- if (!codec->power_on || codec->power_count) {
- codec->power_transition = 0;
- return;
- }
-
- trace_hda_power_down(codec);
- hda_call_codec_suspend(codec);
- if (bus->ops.pm_notify)
- bus->ops.pm_notify(bus);
-}
-
-static void hda_keep_power_on(struct hda_codec *codec)
-{
- codec->power_count++;
- codec->power_on = 1;
- codec->power_jiffies = jiffies;
-}
-
-/* update the power on/off account with the current jiffies */
-void snd_hda_update_power_acct(struct hda_codec *codec)
-{
- unsigned long delta = jiffies - codec->power_jiffies;
- if (codec->power_on)
- codec->power_on_acct += delta;
- else
- codec->power_off_acct += delta;
- codec->power_jiffies += delta;
-}
-
-/**
- * snd_hda_power_up - Power-up the codec
- * @codec: HD-audio codec
- *
- * Increment the power-up counter and power up the hardware really when
- * not turned on yet.
- */
-void snd_hda_power_up(struct hda_codec *codec)
-{
- struct hda_bus *bus = codec->bus;
-
- codec->power_count++;
- if (codec->power_on || codec->power_transition)
- return;
-
- trace_hda_power_up(codec);
- snd_hda_update_power_acct(codec);
- codec->power_on = 1;
- codec->power_jiffies = jiffies;
- if (bus->ops.pm_notify)
- bus->ops.pm_notify(bus);
- hda_call_codec_resume(codec);
- cancel_delayed_work(&codec->power_work);
- codec->power_transition = 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_power_up);
-
-#define power_save(codec) \
- ((codec)->bus->power_save ? *(codec)->bus->power_save : 0)
-
-/**
- * snd_hda_power_down - Power-down the codec
- * @codec: HD-audio codec
- *
- * Decrement the power-up counter and schedules the power-off work if
- * the counter rearches to zero.
- */
-void snd_hda_power_down(struct hda_codec *codec)
-{
- --codec->power_count;
- if (!codec->power_on || codec->power_count || codec->power_transition)
- return;
- if (power_save(codec)) {
- codec->power_transition = 1; /* avoid reentrance */
- queue_delayed_work(codec->bus->workq, &codec->power_work,
- msecs_to_jiffies(power_save(codec) * 1000));
- }
-}
-EXPORT_SYMBOL_HDA(snd_hda_power_down);
-
-/**
- * snd_hda_check_amp_list_power - Check the amp list and update the power
- * @codec: HD-audio codec
- * @check: the object containing an AMP list and the status
- * @nid: NID to check / update
- *
- * Check whether the given NID is in the amp list. If it's in the list,
- * check the current AMP status, and update the the power-status according
- * to the mute status.
- *
- * This function is supposed to be set or called from the check_power_status
- * patch ops.
- */
-int snd_hda_check_amp_list_power(struct hda_codec *codec,
- struct hda_loopback_check *check,
- hda_nid_t nid)
-{
- const struct hda_amp_list *p;
- int ch, v;
-
- if (!check->amplist)
- return 0;
- for (p = check->amplist; p->nid; p++) {
- if (p->nid == nid)
- break;
- }
- if (!p->nid)
- return 0; /* nothing changed */
-
- for (p = check->amplist; p->nid; p++) {
- for (ch = 0; ch < 2; ch++) {
- v = snd_hda_codec_amp_read(codec, p->nid, ch, p->dir,
- p->idx);
- if (!(v & HDA_AMP_MUTE) && v > 0) {
- if (!check->power_on) {
- check->power_on = 1;
- snd_hda_power_up(codec);
- }
- return 1;
- }
- }
- }
- if (check->power_on) {
- check->power_on = 0;
- snd_hda_power_down(codec);
- }
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_check_amp_list_power);
-#endif
-
-/*
- * Channel mode helper
- */
-
-/**
- * snd_hda_ch_mode_info - Info callback helper for the channel mode enum
- */
-int snd_hda_ch_mode_info(struct hda_codec *codec,
- struct snd_ctl_elem_info *uinfo,
- const struct hda_channel_mode *chmode,
- int num_chmodes)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = num_chmodes;
- if (uinfo->value.enumerated.item >= num_chmodes)
- uinfo->value.enumerated.item = num_chmodes - 1;
- sprintf(uinfo->value.enumerated.name, "%dch",
- chmode[uinfo->value.enumerated.item].channels);
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_ch_mode_info);
-
-/**
- * snd_hda_ch_mode_get - Get callback helper for the channel mode enum
- */
-int snd_hda_ch_mode_get(struct hda_codec *codec,
- struct snd_ctl_elem_value *ucontrol,
- const struct hda_channel_mode *chmode,
- int num_chmodes,
- int max_channels)
-{
- int i;
-
- for (i = 0; i < num_chmodes; i++) {
- if (max_channels == chmode[i].channels) {
- ucontrol->value.enumerated.item[0] = i;
- break;
- }
- }
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_ch_mode_get);
-
-/**
- * snd_hda_ch_mode_put - Put callback helper for the channel mode enum
- */
-int snd_hda_ch_mode_put(struct hda_codec *codec,
- struct snd_ctl_elem_value *ucontrol,
- const struct hda_channel_mode *chmode,
- int num_chmodes,
- int *max_channelsp)
-{
- unsigned int mode;
-
- mode = ucontrol->value.enumerated.item[0];
- if (mode >= num_chmodes)
- return -EINVAL;
- if (*max_channelsp == chmode[mode].channels)
- return 0;
- /* change the current channel setting */
- *max_channelsp = chmode[mode].channels;
- if (chmode[mode].sequence)
- snd_hda_sequence_write_cache(codec, chmode[mode].sequence);
- return 1;
-}
-EXPORT_SYMBOL_HDA(snd_hda_ch_mode_put);
-
-/*
- * input MUX helper
- */
-
-/**
- * snd_hda_input_mux_info_info - Info callback helper for the input-mux enum
- */
-int snd_hda_input_mux_info(const struct hda_input_mux *imux,
- struct snd_ctl_elem_info *uinfo)
-{
- unsigned int index;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = imux->num_items;
- if (!imux->num_items)
- return 0;
- index = uinfo->value.enumerated.item;
- if (index >= imux->num_items)
- index = imux->num_items - 1;
- strcpy(uinfo->value.enumerated.name, imux->items[index].label);
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_input_mux_info);
-
-/**
- * snd_hda_input_mux_info_put - Put callback helper for the input-mux enum
- */
-int snd_hda_input_mux_put(struct hda_codec *codec,
- const struct hda_input_mux *imux,
- struct snd_ctl_elem_value *ucontrol,
- hda_nid_t nid,
- unsigned int *cur_val)
-{
- unsigned int idx;
-
- if (!imux->num_items)
- return 0;
- idx = ucontrol->value.enumerated.item[0];
- if (idx >= imux->num_items)
- idx = imux->num_items - 1;
- if (*cur_val == idx)
- return 0;
- snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
- imux->items[idx].index);
- *cur_val = idx;
- return 1;
-}
-EXPORT_SYMBOL_HDA(snd_hda_input_mux_put);
-
-
-/*
- * Multi-channel / digital-out PCM helper functions
- */
-
-/* setup SPDIF output stream */
-static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
- unsigned int stream_tag, unsigned int format)
-{
- struct hda_spdif_out *spdif = snd_hda_spdif_out_of_nid(codec, nid);
-
- /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
- if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE))
- set_dig_out_convert(codec, nid,
- spdif->ctls & ~AC_DIG1_ENABLE & 0xff,
- -1);
- snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
- if (codec->slave_dig_outs) {
- const hda_nid_t *d;
- for (d = codec->slave_dig_outs; *d; d++)
- snd_hda_codec_setup_stream(codec, *d, stream_tag, 0,
- format);
- }
- /* turn on again (if needed) */
- if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE))
- set_dig_out_convert(codec, nid,
- spdif->ctls & 0xff, -1);
-}
-
-static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid)
-{
- snd_hda_codec_cleanup_stream(codec, nid);
- if (codec->slave_dig_outs) {
- const hda_nid_t *d;
- for (d = codec->slave_dig_outs; *d; d++)
- snd_hda_codec_cleanup_stream(codec, *d);
- }
-}
-
-/**
- * snd_hda_bus_reboot_notify - call the reboot notifier of each codec
- * @bus: HD-audio bus
- */
-void snd_hda_bus_reboot_notify(struct hda_bus *bus)
-{
- struct hda_codec *codec;
-
- if (!bus)
- return;
- list_for_each_entry(codec, &bus->codec_list, list) {
- if (hda_codec_is_power_on(codec) &&
- codec->patch_ops.reboot_notify)
- codec->patch_ops.reboot_notify(codec);
- }
-}
-EXPORT_SYMBOL_HDA(snd_hda_bus_reboot_notify);
-
-/**
- * snd_hda_multi_out_dig_open - open the digital out in the exclusive mode
- */
-int snd_hda_multi_out_dig_open(struct hda_codec *codec,
- struct hda_multi_out *mout)
-{
- mutex_lock(&codec->spdif_mutex);
- if (mout->dig_out_used == HDA_DIG_ANALOG_DUP)
- /* already opened as analog dup; reset it once */
- cleanup_dig_out_stream(codec, mout->dig_out_nid);
- mout->dig_out_used = HDA_DIG_EXCLUSIVE;
- mutex_unlock(&codec->spdif_mutex);
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_open);
-
-/**
- * snd_hda_multi_out_dig_prepare - prepare the digital out stream
- */
-int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
- struct hda_multi_out *mout,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- mutex_lock(&codec->spdif_mutex);
- setup_dig_out_stream(codec, mout->dig_out_nid, stream_tag, format);
- mutex_unlock(&codec->spdif_mutex);
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_prepare);
-
-/**
- * snd_hda_multi_out_dig_cleanup - clean-up the digital out stream
- */
-int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec,
- struct hda_multi_out *mout)
-{
- mutex_lock(&codec->spdif_mutex);
- cleanup_dig_out_stream(codec, mout->dig_out_nid);
- mutex_unlock(&codec->spdif_mutex);
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_cleanup);
-
-/**
- * snd_hda_multi_out_dig_close - release the digital out stream
- */
-int snd_hda_multi_out_dig_close(struct hda_codec *codec,
- struct hda_multi_out *mout)
-{
- mutex_lock(&codec->spdif_mutex);
- mout->dig_out_used = 0;
- mutex_unlock(&codec->spdif_mutex);
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_close);
-
-/**
- * snd_hda_multi_out_analog_open - open analog outputs
- *
- * Open analog outputs and set up the hw-constraints.
- * If the digital outputs can be opened as slave, open the digital
- * outputs, too.
- */
-int snd_hda_multi_out_analog_open(struct hda_codec *codec,
- struct hda_multi_out *mout,
- struct snd_pcm_substream *substream,
- struct hda_pcm_stream *hinfo)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- runtime->hw.channels_max = mout->max_channels;
- if (mout->dig_out_nid) {
- if (!mout->analog_rates) {
- mout->analog_rates = hinfo->rates;
- mout->analog_formats = hinfo->formats;
- mout->analog_maxbps = hinfo->maxbps;
- } else {
- runtime->hw.rates = mout->analog_rates;
- runtime->hw.formats = mout->analog_formats;
- hinfo->maxbps = mout->analog_maxbps;
- }
- if (!mout->spdif_rates) {
- snd_hda_query_supported_pcm(codec, mout->dig_out_nid,
- &mout->spdif_rates,
- &mout->spdif_formats,
- &mout->spdif_maxbps);
- }
- mutex_lock(&codec->spdif_mutex);
- if (mout->share_spdif) {
- if ((runtime->hw.rates & mout->spdif_rates) &&
- (runtime->hw.formats & mout->spdif_formats)) {
- runtime->hw.rates &= mout->spdif_rates;
- runtime->hw.formats &= mout->spdif_formats;
- if (mout->spdif_maxbps < hinfo->maxbps)
- hinfo->maxbps = mout->spdif_maxbps;
- } else {
- mout->share_spdif = 0;
- /* FIXME: need notify? */
- }
- }
- mutex_unlock(&codec->spdif_mutex);
- }
- return snd_pcm_hw_constraint_step(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS, 2);
-}
-EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_open);
-
-/**
- * snd_hda_multi_out_analog_prepare - Preapre the analog outputs.
- *
- * Set up the i/o for analog out.
- * When the digital out is available, copy the front out to digital out, too.
- */
-int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
- struct hda_multi_out *mout,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- const hda_nid_t *nids = mout->dac_nids;
- int chs = substream->runtime->channels;
- struct hda_spdif_out *spdif =
- snd_hda_spdif_out_of_nid(codec, mout->dig_out_nid);
- int i;
-
- mutex_lock(&codec->spdif_mutex);
- if (mout->dig_out_nid && mout->share_spdif &&
- mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
- if (chs == 2 &&
- snd_hda_is_supported_format(codec, mout->dig_out_nid,
- format) &&
- !(spdif->status & IEC958_AES0_NONAUDIO)) {
- mout->dig_out_used = HDA_DIG_ANALOG_DUP;
- setup_dig_out_stream(codec, mout->dig_out_nid,
- stream_tag, format);
- } else {
- mout->dig_out_used = 0;
- cleanup_dig_out_stream(codec, mout->dig_out_nid);
- }
- }
- mutex_unlock(&codec->spdif_mutex);
-
- /* front */
- snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
- 0, format);
- if (!mout->no_share_stream &&
- mout->hp_nid && mout->hp_nid != nids[HDA_FRONT])
- /* headphone out will just decode front left/right (stereo) */
- snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
- 0, format);
- /* extra outputs copied from front */
- for (i = 0; i < ARRAY_SIZE(mout->hp_out_nid); i++)
- if (!mout->no_share_stream && mout->hp_out_nid[i])
- snd_hda_codec_setup_stream(codec,
- mout->hp_out_nid[i],
- stream_tag, 0, format);
- for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
- if (!mout->no_share_stream && mout->extra_out_nid[i])
- snd_hda_codec_setup_stream(codec,
- mout->extra_out_nid[i],
- stream_tag, 0, format);
-
- /* surrounds */
- for (i = 1; i < mout->num_dacs; i++) {
- if (chs >= (i + 1) * 2) /* independent out */
- snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
- i * 2, format);
- else if (!mout->no_share_stream) /* copy front */
- snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
- 0, format);
- }
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_prepare);
-
-/**
- * snd_hda_multi_out_analog_cleanup - clean up the setting for analog out
- */
-int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
- struct hda_multi_out *mout)
-{
- const hda_nid_t *nids = mout->dac_nids;
- int i;
-
- for (i = 0; i < mout->num_dacs; i++)
- snd_hda_codec_cleanup_stream(codec, nids[i]);
- if (mout->hp_nid)
- snd_hda_codec_cleanup_stream(codec, mout->hp_nid);
- for (i = 0; i < ARRAY_SIZE(mout->hp_out_nid); i++)
- if (mout->hp_out_nid[i])
- snd_hda_codec_cleanup_stream(codec,
- mout->hp_out_nid[i]);
- for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
- if (mout->extra_out_nid[i])
- snd_hda_codec_cleanup_stream(codec,
- mout->extra_out_nid[i]);
- mutex_lock(&codec->spdif_mutex);
- if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
- cleanup_dig_out_stream(codec, mout->dig_out_nid);
- mout->dig_out_used = 0;
- }
- mutex_unlock(&codec->spdif_mutex);
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup);
-
-/*
- * Helper for automatic pin configuration
- */
-
-static int is_in_nid_list(hda_nid_t nid, const hda_nid_t *list)
-{
- for (; *list; list++)
- if (*list == nid)
- return 1;
- return 0;
-}
-
-
-/*
- * Sort an associated group of pins according to their sequence numbers.
- */
-static void sort_pins_by_sequence(hda_nid_t *pins, short *sequences,
- int num_pins)
-{
- int i, j;
- short seq;
- hda_nid_t nid;
-
- for (i = 0; i < num_pins; i++) {
- for (j = i + 1; j < num_pins; j++) {
- if (sequences[i] > sequences[j]) {
- seq = sequences[i];
- sequences[i] = sequences[j];
- sequences[j] = seq;
- nid = pins[i];
- pins[i] = pins[j];
- pins[j] = nid;
- }
- }
- }
-}
-
-
-/* add the found input-pin to the cfg->inputs[] table */
-static void add_auto_cfg_input_pin(struct auto_pin_cfg *cfg, hda_nid_t nid,
- int type)
-{
- if (cfg->num_inputs < AUTO_CFG_MAX_INS) {
- cfg->inputs[cfg->num_inputs].pin = nid;
- cfg->inputs[cfg->num_inputs].type = type;
- cfg->num_inputs++;
- }
-}
-
-/* sort inputs in the order of AUTO_PIN_* type */
-static void sort_autocfg_input_pins(struct auto_pin_cfg *cfg)
-{
- int i, j;
-
- for (i = 0; i < cfg->num_inputs; i++) {
- for (j = i + 1; j < cfg->num_inputs; j++) {
- if (cfg->inputs[i].type > cfg->inputs[j].type) {
- struct auto_pin_cfg_item tmp;
- tmp = cfg->inputs[i];
- cfg->inputs[i] = cfg->inputs[j];
- cfg->inputs[j] = tmp;
- }
- }
- }
-}
-
-/* Reorder the surround channels
- * ALSA sequence is front/surr/clfe/side
- * HDA sequence is:
- * 4-ch: front/surr => OK as it is
- * 6-ch: front/clfe/surr
- * 8-ch: front/clfe/rear/side|fc
- */
-static void reorder_outputs(unsigned int nums, hda_nid_t *pins)
-{
- hda_nid_t nid;
-
- switch (nums) {
- case 3:
- case 4:
- nid = pins[1];
- pins[1] = pins[2];
- pins[2] = nid;
- break;
- }
-}
-
-/*
- * Parse all pin widgets and store the useful pin nids to cfg
- *
- * The number of line-outs or any primary output is stored in line_outs,
- * and the corresponding output pins are assigned to line_out_pins[],
- * in the order of front, rear, CLFE, side, ...
- *
- * If more extra outputs (speaker and headphone) are found, the pins are
- * assisnged to hp_pins[] and speaker_pins[], respectively. If no line-out jack
- * is detected, one of speaker of HP pins is assigned as the primary
- * output, i.e. to line_out_pins[0]. So, line_outs is always positive
- * if any analog output exists.
- *
- * The analog input pins are assigned to inputs array.
- * The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
- * respectively.
- */
-int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
- struct auto_pin_cfg *cfg,
- const hda_nid_t *ignore_nids,
- unsigned int cond_flags)
-{
- hda_nid_t nid, end_nid;
- short seq, assoc_line_out;
- short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)];
- short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)];
- short sequences_hp[ARRAY_SIZE(cfg->hp_pins)];
- int i;
-
- memset(cfg, 0, sizeof(*cfg));
-
- memset(sequences_line_out, 0, sizeof(sequences_line_out));
- memset(sequences_speaker, 0, sizeof(sequences_speaker));
- memset(sequences_hp, 0, sizeof(sequences_hp));
- assoc_line_out = 0;
-
- codec->ignore_misc_bit = true;
- end_nid = codec->start_nid + codec->num_nodes;
- for (nid = codec->start_nid; nid < end_nid; nid++) {
- unsigned int wid_caps = get_wcaps(codec, nid);
- unsigned int wid_type = get_wcaps_type(wid_caps);
- unsigned int def_conf;
- short assoc, loc, conn, dev;
-
- /* read all default configuration for pin complex */
- if (wid_type != AC_WID_PIN)
- continue;
- /* ignore the given nids (e.g. pc-beep returns error) */
- if (ignore_nids && is_in_nid_list(nid, ignore_nids))
- continue;
-
- def_conf = snd_hda_codec_get_pincfg(codec, nid);
- if (!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
- AC_DEFCFG_MISC_NO_PRESENCE))
- codec->ignore_misc_bit = false;
- conn = get_defcfg_connect(def_conf);
- if (conn == AC_JACK_PORT_NONE)
- continue;
- loc = get_defcfg_location(def_conf);
- dev = get_defcfg_device(def_conf);
-
- /* workaround for buggy BIOS setups */
- if (dev == AC_JACK_LINE_OUT) {
- if (conn == AC_JACK_PORT_FIXED)
- dev = AC_JACK_SPEAKER;
- }
-
- switch (dev) {
- case AC_JACK_LINE_OUT:
- seq = get_defcfg_sequence(def_conf);
- assoc = get_defcfg_association(def_conf);
-
- if (!(wid_caps & AC_WCAP_STEREO))
- if (!cfg->mono_out_pin)
- cfg->mono_out_pin = nid;
- if (!assoc)
- continue;
- if (!assoc_line_out)
- assoc_line_out = assoc;
- else if (assoc_line_out != assoc)
- continue;
- if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins))
- continue;
- cfg->line_out_pins[cfg->line_outs] = nid;
- sequences_line_out[cfg->line_outs] = seq;
- cfg->line_outs++;
- break;
- case AC_JACK_SPEAKER:
- seq = get_defcfg_sequence(def_conf);
- assoc = get_defcfg_association(def_conf);
- if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins))
- continue;
- cfg->speaker_pins[cfg->speaker_outs] = nid;
- sequences_speaker[cfg->speaker_outs] = (assoc << 4) | seq;
- cfg->speaker_outs++;
- break;
- case AC_JACK_HP_OUT:
- seq = get_defcfg_sequence(def_conf);
- assoc = get_defcfg_association(def_conf);
- if (cfg->hp_outs >= ARRAY_SIZE(cfg->hp_pins))
- continue;
- cfg->hp_pins[cfg->hp_outs] = nid;
- sequences_hp[cfg->hp_outs] = (assoc << 4) | seq;
- cfg->hp_outs++;
- break;
- case AC_JACK_MIC_IN:
- add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_MIC);
- break;
- case AC_JACK_LINE_IN:
- add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_LINE_IN);
- break;
- case AC_JACK_CD:
- add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_CD);
- break;
- case AC_JACK_AUX:
- add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_AUX);
- break;
- case AC_JACK_SPDIF_OUT:
- case AC_JACK_DIG_OTHER_OUT:
- if (cfg->dig_outs >= ARRAY_SIZE(cfg->dig_out_pins))
- continue;
- cfg->dig_out_pins[cfg->dig_outs] = nid;
- cfg->dig_out_type[cfg->dig_outs] =
- (loc == AC_JACK_LOC_HDMI) ?
- HDA_PCM_TYPE_HDMI : HDA_PCM_TYPE_SPDIF;
- cfg->dig_outs++;
- break;
- case AC_JACK_SPDIF_IN:
- case AC_JACK_DIG_OTHER_IN:
- cfg->dig_in_pin = nid;
- if (loc == AC_JACK_LOC_HDMI)
- cfg->dig_in_type = HDA_PCM_TYPE_HDMI;
- else
- cfg->dig_in_type = HDA_PCM_TYPE_SPDIF;
- break;
- }
- }
-
- /* FIX-UP:
- * If no line-out is defined but multiple HPs are found,
- * some of them might be the real line-outs.
- */
- if (!cfg->line_outs && cfg->hp_outs > 1 &&
- !(cond_flags & HDA_PINCFG_NO_HP_FIXUP)) {
- int i = 0;
- while (i < cfg->hp_outs) {
- /* The real HPs should have the sequence 0x0f */
- if ((sequences_hp[i] & 0x0f) == 0x0f) {
- i++;
- continue;
- }
- /* Move it to the line-out table */
- cfg->line_out_pins[cfg->line_outs] = cfg->hp_pins[i];
- sequences_line_out[cfg->line_outs] = sequences_hp[i];
- cfg->line_outs++;
- cfg->hp_outs--;
- memmove(cfg->hp_pins + i, cfg->hp_pins + i + 1,
- sizeof(cfg->hp_pins[0]) * (cfg->hp_outs - i));
- memmove(sequences_hp + i, sequences_hp + i + 1,
- sizeof(sequences_hp[0]) * (cfg->hp_outs - i));
- }
- memset(cfg->hp_pins + cfg->hp_outs, 0,
- sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - cfg->hp_outs));
- if (!cfg->hp_outs)
- cfg->line_out_type = AUTO_PIN_HP_OUT;
-
- }
-
- /* sort by sequence */
- sort_pins_by_sequence(cfg->line_out_pins, sequences_line_out,
- cfg->line_outs);
- sort_pins_by_sequence(cfg->speaker_pins, sequences_speaker,
- cfg->speaker_outs);
- sort_pins_by_sequence(cfg->hp_pins, sequences_hp,
- cfg->hp_outs);
-
- /*
- * FIX-UP: if no line-outs are detected, try to use speaker or HP pin
- * as a primary output
- */
- if (!cfg->line_outs &&
- !(cond_flags & HDA_PINCFG_NO_LO_FIXUP)) {
- if (cfg->speaker_outs) {
- cfg->line_outs = cfg->speaker_outs;
- memcpy(cfg->line_out_pins, cfg->speaker_pins,
- sizeof(cfg->speaker_pins));
- cfg->speaker_outs = 0;
- memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
- cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
- } else if (cfg->hp_outs) {
- cfg->line_outs = cfg->hp_outs;
- memcpy(cfg->line_out_pins, cfg->hp_pins,
- sizeof(cfg->hp_pins));
- cfg->hp_outs = 0;
- memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
- cfg->line_out_type = AUTO_PIN_HP_OUT;
- }
- }
-
- reorder_outputs(cfg->line_outs, cfg->line_out_pins);
- reorder_outputs(cfg->hp_outs, cfg->hp_pins);
- reorder_outputs(cfg->speaker_outs, cfg->speaker_pins);
-
- sort_autocfg_input_pins(cfg);
-
- /*
- * debug prints of the parsed results
- */
- snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x) type:%s\n",
- cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1],
- cfg->line_out_pins[2], cfg->line_out_pins[3],
- cfg->line_out_pins[4],
- cfg->line_out_type == AUTO_PIN_HP_OUT ? "hp" :
- (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT ?
- "speaker" : "line"));
- snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
- cfg->speaker_outs, cfg->speaker_pins[0],
- cfg->speaker_pins[1], cfg->speaker_pins[2],
- cfg->speaker_pins[3], cfg->speaker_pins[4]);
- snd_printd(" hp_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
- cfg->hp_outs, cfg->hp_pins[0],
- cfg->hp_pins[1], cfg->hp_pins[2],
- cfg->hp_pins[3], cfg->hp_pins[4]);
- snd_printd(" mono: mono_out=0x%x\n", cfg->mono_out_pin);
- if (cfg->dig_outs)
- snd_printd(" dig-out=0x%x/0x%x\n",
- cfg->dig_out_pins[0], cfg->dig_out_pins[1]);
- snd_printd(" inputs:");
- for (i = 0; i < cfg->num_inputs; i++) {
- snd_printd(" %s=0x%x",
- hda_get_autocfg_input_label(codec, cfg, i),
- cfg->inputs[i].pin);
- }
- snd_printd("\n");
- if (cfg->dig_in_pin)
- snd_printd(" dig-in=0x%x\n", cfg->dig_in_pin);
-
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_parse_pin_defcfg);
-
-int snd_hda_get_input_pin_attr(unsigned int def_conf)
-{
- unsigned int loc = get_defcfg_location(def_conf);
- unsigned int conn = get_defcfg_connect(def_conf);
- if (conn == AC_JACK_PORT_NONE)
- return INPUT_PIN_ATTR_UNUSED;
- /* Windows may claim the internal mic to be BOTH, too */
- if (conn == AC_JACK_PORT_FIXED || conn == AC_JACK_PORT_BOTH)
- return INPUT_PIN_ATTR_INT;
- if ((loc & 0x30) == AC_JACK_LOC_INTERNAL)
- return INPUT_PIN_ATTR_INT;
- if ((loc & 0x30) == AC_JACK_LOC_SEPARATE)
- return INPUT_PIN_ATTR_DOCK;
- if (loc == AC_JACK_LOC_REAR)
- return INPUT_PIN_ATTR_REAR;
- if (loc == AC_JACK_LOC_FRONT)
- return INPUT_PIN_ATTR_FRONT;
- return INPUT_PIN_ATTR_NORMAL;
-}
-EXPORT_SYMBOL_HDA(snd_hda_get_input_pin_attr);
-
-/**
- * hda_get_input_pin_label - Give a label for the given input pin
- *
- * When check_location is true, the function checks the pin location
- * for mic and line-in pins, and set an appropriate prefix like "Front",
- * "Rear", "Internal".
- */
-
-static const char *hda_get_input_pin_label(struct hda_codec *codec,
- hda_nid_t pin, bool check_location)
-{
- unsigned int def_conf;
- static const char * const mic_names[] = {
- "Internal Mic", "Dock Mic", "Mic", "Front Mic", "Rear Mic",
- };
- int attr;
-
- def_conf = snd_hda_codec_get_pincfg(codec, pin);
-
- switch (get_defcfg_device(def_conf)) {
- case AC_JACK_MIC_IN:
- if (!check_location)
- return "Mic";
- attr = snd_hda_get_input_pin_attr(def_conf);
- if (!attr)
- return "None";
- return mic_names[attr - 1];
- case AC_JACK_LINE_IN:
- if (!check_location)
- return "Line";
- attr = snd_hda_get_input_pin_attr(def_conf);
- if (!attr)
- return "None";
- if (attr == INPUT_PIN_ATTR_DOCK)
- return "Dock Line";
- return "Line";
- case AC_JACK_AUX:
- return "Aux";
- case AC_JACK_CD:
- return "CD";
- case AC_JACK_SPDIF_IN:
- return "SPDIF In";
- case AC_JACK_DIG_OTHER_IN:
- return "Digital In";
- default:
- return "Misc";
- }
-}
-
-/* Check whether the location prefix needs to be added to the label.
- * If all mic-jacks are in the same location (e.g. rear panel), we don't
- * have to put "Front" prefix to each label. In such a case, returns false.
- */
-static int check_mic_location_need(struct hda_codec *codec,
- const struct auto_pin_cfg *cfg,
- int input)
-{
- unsigned int defc;
- int i, attr, attr2;
-
- defc = snd_hda_codec_get_pincfg(codec, cfg->inputs[input].pin);
- attr = snd_hda_get_input_pin_attr(defc);
- /* for internal or docking mics, we need locations */
- if (attr <= INPUT_PIN_ATTR_NORMAL)
- return 1;
-
- attr = 0;
- for (i = 0; i < cfg->num_inputs; i++) {
- defc = snd_hda_codec_get_pincfg(codec, cfg->inputs[i].pin);
- attr2 = snd_hda_get_input_pin_attr(defc);
- if (attr2 >= INPUT_PIN_ATTR_NORMAL) {
- if (attr && attr != attr2)
- return 1; /* different locations found */
- attr = attr2;
- }
- }
- return 0;
-}
-
-/**
- * hda_get_autocfg_input_label - Get a label for the given input
- *
- * Get a label for the given input pin defined by the autocfg item.
- * Unlike hda_get_input_pin_label(), this function checks all inputs
- * defined in autocfg and avoids the redundant mic/line prefix as much as
- * possible.
- */
-const char *hda_get_autocfg_input_label(struct hda_codec *codec,
- const struct auto_pin_cfg *cfg,
- int input)
-{
- int type = cfg->inputs[input].type;
- int has_multiple_pins = 0;
-
- if ((input > 0 && cfg->inputs[input - 1].type == type) ||
- (input < cfg->num_inputs - 1 && cfg->inputs[input + 1].type == type))
- has_multiple_pins = 1;
- if (has_multiple_pins && type == AUTO_PIN_MIC)
- has_multiple_pins &= check_mic_location_need(codec, cfg, input);
- return hda_get_input_pin_label(codec, cfg->inputs[input].pin,
- has_multiple_pins);
-}
-EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label);
-
-/* return the position of NID in the list, or -1 if not found */
-static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
-{
- int i;
- for (i = 0; i < nums; i++)
- if (list[i] == nid)
- return i;
- return -1;
-}
-
-/* get a unique suffix or an index number */
-static const char *check_output_sfx(hda_nid_t nid, const hda_nid_t *pins,
- int num_pins, int *indexp)
-{
- static const char * const channel_sfx[] = {
- " Front", " Surround", " CLFE", " Side"
- };
- int i;
-
- i = find_idx_in_nid_list(nid, pins, num_pins);
- if (i < 0)
- return NULL;
- if (num_pins == 1)
- return "";
- if (num_pins > ARRAY_SIZE(channel_sfx)) {
- if (indexp)
- *indexp = i;
- return "";
- }
- return channel_sfx[i];
-}
-
-static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid,
- const struct auto_pin_cfg *cfg,
- const char *name, char *label, int maxlen,
- int *indexp)
-{
- unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
- int attr = snd_hda_get_input_pin_attr(def_conf);
- const char *pfx = "", *sfx = "";
-
- /* handle as a speaker if it's a fixed line-out */
- if (!strcmp(name, "Line Out") && attr == INPUT_PIN_ATTR_INT)
- name = "Speaker";
- /* check the location */
- switch (attr) {
- case INPUT_PIN_ATTR_DOCK:
- pfx = "Dock ";
- break;
- case INPUT_PIN_ATTR_FRONT:
- pfx = "Front ";
- break;
- }
- if (cfg) {
- /* try to give a unique suffix if needed */
- sfx = check_output_sfx(nid, cfg->line_out_pins, cfg->line_outs,
- indexp);
- if (!sfx)
- sfx = check_output_sfx(nid, cfg->speaker_pins, cfg->speaker_outs,
- indexp);
- if (!sfx) {
- /* don't add channel suffix for Headphone controls */
- int idx = find_idx_in_nid_list(nid, cfg->hp_pins,
- cfg->hp_outs);
- if (idx >= 0)
- *indexp = idx;
- sfx = "";
- }
- }
- snprintf(label, maxlen, "%s%s%s", pfx, name, sfx);
- return 1;
-}
-
-/**
- * snd_hda_get_pin_label - Get a label for the given I/O pin
- *
- * Get a label for the given pin. This function works for both input and
- * output pins. When @cfg is given as non-NULL, the function tries to get
- * an optimized label using hda_get_autocfg_input_label().
- *
- * This function tries to give a unique label string for the pin as much as
- * possible. For example, when the multiple line-outs are present, it adds
- * the channel suffix like "Front", "Surround", etc (only when @cfg is given).
- * If no unique name with a suffix is available and @indexp is non-NULL, the
- * index number is stored in the pointer.
- */
-int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid,
- const struct auto_pin_cfg *cfg,
- char *label, int maxlen, int *indexp)
-{
- unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
- const char *name = NULL;
- int i;
-
- if (indexp)
- *indexp = 0;
- if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
- return 0;
-
- switch (get_defcfg_device(def_conf)) {
- case AC_JACK_LINE_OUT:
- return fill_audio_out_name(codec, nid, cfg, "Line Out",
- label, maxlen, indexp);
- case AC_JACK_SPEAKER:
- return fill_audio_out_name(codec, nid, cfg, "Speaker",
- label, maxlen, indexp);
- case AC_JACK_HP_OUT:
- return fill_audio_out_name(codec, nid, cfg, "Headphone",
- label, maxlen, indexp);
- case AC_JACK_SPDIF_OUT:
- case AC_JACK_DIG_OTHER_OUT:
- if (get_defcfg_location(def_conf) == AC_JACK_LOC_HDMI)
- name = "HDMI";
- else
- name = "SPDIF";
- if (cfg && indexp) {
- i = find_idx_in_nid_list(nid, cfg->dig_out_pins,
- cfg->dig_outs);
- if (i >= 0)
- *indexp = i;
- }
- break;
- default:
- if (cfg) {
- for (i = 0; i < cfg->num_inputs; i++) {
- if (cfg->inputs[i].pin != nid)
- continue;
- name = hda_get_autocfg_input_label(codec, cfg, i);
- if (name)
- break;
- }
- }
- if (!name)
- name = hda_get_input_pin_label(codec, nid, true);
- break;
- }
- if (!name)
- return 0;
- strlcpy(label, name, maxlen);
- return 1;
-}
-EXPORT_SYMBOL_HDA(snd_hda_get_pin_label);
-
-/**
- * snd_hda_add_imux_item - Add an item to input_mux
- *
- * When the same label is used already in the existing items, the number
- * suffix is appended to the label. This label index number is stored
- * to type_idx when non-NULL pointer is given.
- */
-int snd_hda_add_imux_item(struct hda_input_mux *imux, const char *label,
- int index, int *type_idx)
-{
- int i, label_idx = 0;
- if (imux->num_items >= HDA_MAX_NUM_INPUTS) {
- snd_printd(KERN_ERR "hda_codec: Too many imux items!\n");
- return -EINVAL;
- }
- for (i = 0; i < imux->num_items; i++) {
- if (!strncmp(label, imux->items[i].label, strlen(label)))
- label_idx++;
- }
- if (type_idx)
- *type_idx = label_idx;
- if (label_idx > 0)
- snprintf(imux->items[imux->num_items].label,
- sizeof(imux->items[imux->num_items].label),
- "%s %d", label, label_idx);
- else
- strlcpy(imux->items[imux->num_items].label, label,
- sizeof(imux->items[imux->num_items].label));
- imux->items[imux->num_items].index = index;
- imux->num_items++;
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_add_imux_item);
-
-
-#ifdef CONFIG_PM
-/*
- * power management
- */
-
-/**
- * snd_hda_suspend - suspend the codecs
- * @bus: the HDA bus
- *
- * Returns 0 if successful.
- */
-int snd_hda_suspend(struct hda_bus *bus)
-{
- struct hda_codec *codec;
-
- list_for_each_entry(codec, &bus->codec_list, list) {
- if (hda_codec_is_power_on(codec))
- hda_call_codec_suspend(codec);
- if (codec->patch_ops.post_suspend)
- codec->patch_ops.post_suspend(codec);
- }
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_suspend);
-
-/**
- * snd_hda_resume - resume the codecs
- * @bus: the HDA bus
- *
- * Returns 0 if successful.
- *
- * This function is defined only when POWER_SAVE isn't set.
- * In the power-save mode, the codec is resumed dynamically.
- */
-int snd_hda_resume(struct hda_bus *bus)
-{
- struct hda_codec *codec;
-
- list_for_each_entry(codec, &bus->codec_list, list) {
- if (codec->patch_ops.pre_resume)
- codec->patch_ops.pre_resume(codec);
- if (snd_hda_codec_needs_resume(codec))
- hda_call_codec_resume(codec);
- }
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_resume);
-#endif /* CONFIG_PM */
-
-/*
- * generic arrays
- */
-
-/**
- * snd_array_new - get a new element from the given array
- * @array: the array object
- *
- * Get a new element from the given array. If it exceeds the
- * pre-allocated array size, re-allocate the array.
- *
- * Returns NULL if allocation failed.
- */
-void *snd_array_new(struct snd_array *array)
-{
- if (array->used >= array->alloced) {
- int num = array->alloced + array->alloc_align;
- int size = (num + 1) * array->elem_size;
- int oldsize = array->alloced * array->elem_size;
- void *nlist;
- if (snd_BUG_ON(num >= 4096))
- return NULL;
- nlist = krealloc(array->list, size, GFP_KERNEL);
- if (!nlist)
- return NULL;
- memset(nlist + oldsize, 0, size - oldsize);
- array->list = nlist;
- array->alloced = num;
- }
- return snd_array_elem(array, array->used++);
-}
-EXPORT_SYMBOL_HDA(snd_array_new);
-
-/**
- * snd_array_free - free the given array elements
- * @array: the array object
- */
-void snd_array_free(struct snd_array *array)
-{
- kfree(array->list);
- array->used = 0;
- array->alloced = 0;
- array->list = NULL;
-}
-EXPORT_SYMBOL_HDA(snd_array_free);
-
-/**
- * snd_print_pcm_bits - Print the supported PCM fmt bits to the string buffer
- * @pcm: PCM caps bits
- * @buf: the string buffer to write
- * @buflen: the max buffer length
- *
- * used by hda_proc.c and hda_eld.c
- */
-void snd_print_pcm_bits(int pcm, char *buf, int buflen)
-{
- static unsigned int bits[] = { 8, 16, 20, 24, 32 };
- int i, j;
-
- for (i = 0, j = 0; i < ARRAY_SIZE(bits); i++)
- if (pcm & (AC_SUPPCM_BITS_8 << i))
- j += snprintf(buf + j, buflen - j, " %d", bits[i]);
-
- buf[j] = '\0'; /* necessary when j == 0 */
-}
-EXPORT_SYMBOL_HDA(snd_print_pcm_bits);
-
-MODULE_DESCRIPTION("HDA codec core");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/pci/hda/hda_codec.h b/ANDROID_3.4.5/sound/pci/hda/hda_codec.h
deleted file mode 100644
index 56b4f74c..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/hda_codec.h
+++ /dev/null
@@ -1,1084 +0,0 @@
-/*
- * Universal Interface for Intel High Definition Audio Codec
- *
- * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __SOUND_HDA_CODEC_H
-#define __SOUND_HDA_CODEC_H
-
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/hwdep.h>
-
-/*
- * nodes
- */
-#define AC_NODE_ROOT 0x00
-
-/*
- * function group types
- */
-enum {
- AC_GRP_AUDIO_FUNCTION = 0x01,
- AC_GRP_MODEM_FUNCTION = 0x02,
-};
-
-/*
- * widget types
- */
-enum {
- AC_WID_AUD_OUT, /* Audio Out */
- AC_WID_AUD_IN, /* Audio In */
- AC_WID_AUD_MIX, /* Audio Mixer */
- AC_WID_AUD_SEL, /* Audio Selector */
- AC_WID_PIN, /* Pin Complex */
- AC_WID_POWER, /* Power */
- AC_WID_VOL_KNB, /* Volume Knob */
- AC_WID_BEEP, /* Beep Generator */
- AC_WID_VENDOR = 0x0f /* Vendor specific */
-};
-
-/*
- * GET verbs
- */
-#define AC_VERB_GET_STREAM_FORMAT 0x0a00
-#define AC_VERB_GET_AMP_GAIN_MUTE 0x0b00
-#define AC_VERB_GET_PROC_COEF 0x0c00
-#define AC_VERB_GET_COEF_INDEX 0x0d00
-#define AC_VERB_PARAMETERS 0x0f00
-#define AC_VERB_GET_CONNECT_SEL 0x0f01
-#define AC_VERB_GET_CONNECT_LIST 0x0f02
-#define AC_VERB_GET_PROC_STATE 0x0f03
-#define AC_VERB_GET_SDI_SELECT 0x0f04
-#define AC_VERB_GET_POWER_STATE 0x0f05
-#define AC_VERB_GET_CONV 0x0f06
-#define AC_VERB_GET_PIN_WIDGET_CONTROL 0x0f07
-#define AC_VERB_GET_UNSOLICITED_RESPONSE 0x0f08
-#define AC_VERB_GET_PIN_SENSE 0x0f09
-#define AC_VERB_GET_BEEP_CONTROL 0x0f0a
-#define AC_VERB_GET_EAPD_BTLENABLE 0x0f0c
-#define AC_VERB_GET_DIGI_CONVERT_1 0x0f0d
-#define AC_VERB_GET_DIGI_CONVERT_2 0x0f0e /* unused */
-#define AC_VERB_GET_VOLUME_KNOB_CONTROL 0x0f0f
-/* f10-f1a: GPIO */
-#define AC_VERB_GET_GPIO_DATA 0x0f15
-#define AC_VERB_GET_GPIO_MASK 0x0f16
-#define AC_VERB_GET_GPIO_DIRECTION 0x0f17
-#define AC_VERB_GET_GPIO_WAKE_MASK 0x0f18
-#define AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK 0x0f19
-#define AC_VERB_GET_GPIO_STICKY_MASK 0x0f1a
-#define AC_VERB_GET_CONFIG_DEFAULT 0x0f1c
-/* f20: AFG/MFG */
-#define AC_VERB_GET_SUBSYSTEM_ID 0x0f20
-#define AC_VERB_GET_CVT_CHAN_COUNT 0x0f2d
-#define AC_VERB_GET_HDMI_DIP_SIZE 0x0f2e
-#define AC_VERB_GET_HDMI_ELDD 0x0f2f
-#define AC_VERB_GET_HDMI_DIP_INDEX 0x0f30
-#define AC_VERB_GET_HDMI_DIP_DATA 0x0f31
-#define AC_VERB_GET_HDMI_DIP_XMIT 0x0f32
-#define AC_VERB_GET_HDMI_CP_CTRL 0x0f33
-#define AC_VERB_GET_HDMI_CHAN_SLOT 0x0f34
-
-/*
- * SET verbs
- */
-#define AC_VERB_SET_STREAM_FORMAT 0x200
-#define AC_VERB_SET_AMP_GAIN_MUTE 0x300
-#define AC_VERB_SET_PROC_COEF 0x400
-#define AC_VERB_SET_COEF_INDEX 0x500
-#define AC_VERB_SET_CONNECT_SEL 0x701
-#define AC_VERB_SET_PROC_STATE 0x703
-#define AC_VERB_SET_SDI_SELECT 0x704
-#define AC_VERB_SET_POWER_STATE 0x705
-#define AC_VERB_SET_CHANNEL_STREAMID 0x706
-#define AC_VERB_SET_PIN_WIDGET_CONTROL 0x707
-#define AC_VERB_SET_UNSOLICITED_ENABLE 0x708
-#define AC_VERB_SET_PIN_SENSE 0x709
-#define AC_VERB_SET_BEEP_CONTROL 0x70a
-#define AC_VERB_SET_EAPD_BTLENABLE 0x70c
-#define AC_VERB_SET_DIGI_CONVERT_1 0x70d
-#define AC_VERB_SET_DIGI_CONVERT_2 0x70e
-#define AC_VERB_SET_VOLUME_KNOB_CONTROL 0x70f
-#define AC_VERB_SET_GPIO_DATA 0x715
-#define AC_VERB_SET_GPIO_MASK 0x716
-#define AC_VERB_SET_GPIO_DIRECTION 0x717
-#define AC_VERB_SET_GPIO_WAKE_MASK 0x718
-#define AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK 0x719
-#define AC_VERB_SET_GPIO_STICKY_MASK 0x71a
-#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 0x71c
-#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_1 0x71d
-#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_2 0x71e
-#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_3 0x71f
-#define AC_VERB_SET_EAPD 0x788
-#define AC_VERB_SET_CODEC_RESET 0x7ff
-#define AC_VERB_SET_CVT_CHAN_COUNT 0x72d
-#define AC_VERB_SET_HDMI_DIP_INDEX 0x730
-#define AC_VERB_SET_HDMI_DIP_DATA 0x731
-#define AC_VERB_SET_HDMI_DIP_XMIT 0x732
-#define AC_VERB_SET_HDMI_CP_CTRL 0x733
-#define AC_VERB_SET_HDMI_CHAN_SLOT 0x734
-
-/*
- * Parameter IDs
- */
-#define AC_PAR_VENDOR_ID 0x00
-#define AC_PAR_SUBSYSTEM_ID 0x01
-#define AC_PAR_REV_ID 0x02
-#define AC_PAR_NODE_COUNT 0x04
-#define AC_PAR_FUNCTION_TYPE 0x05
-#define AC_PAR_AUDIO_FG_CAP 0x08
-#define AC_PAR_AUDIO_WIDGET_CAP 0x09
-#define AC_PAR_PCM 0x0a
-#define AC_PAR_STREAM 0x0b
-#define AC_PAR_PIN_CAP 0x0c
-#define AC_PAR_AMP_IN_CAP 0x0d
-#define AC_PAR_CONNLIST_LEN 0x0e
-#define AC_PAR_POWER_STATE 0x0f
-#define AC_PAR_PROC_CAP 0x10
-#define AC_PAR_GPIO_CAP 0x11
-#define AC_PAR_AMP_OUT_CAP 0x12
-#define AC_PAR_VOL_KNB_CAP 0x13
-#define AC_PAR_HDMI_LPCM_CAP 0x20
-
-/*
- * AC_VERB_PARAMETERS results (32bit)
- */
-
-/* Function Group Type */
-#define AC_FGT_TYPE (0xff<<0)
-#define AC_FGT_TYPE_SHIFT 0
-#define AC_FGT_UNSOL_CAP (1<<8)
-
-/* Audio Function Group Capabilities */
-#define AC_AFG_OUT_DELAY (0xf<<0)
-#define AC_AFG_IN_DELAY (0xf<<8)
-#define AC_AFG_BEEP_GEN (1<<16)
-
-/* Audio Widget Capabilities */
-#define AC_WCAP_STEREO (1<<0) /* stereo I/O */
-#define AC_WCAP_IN_AMP (1<<1) /* AMP-in present */
-#define AC_WCAP_OUT_AMP (1<<2) /* AMP-out present */
-#define AC_WCAP_AMP_OVRD (1<<3) /* AMP-parameter override */
-#define AC_WCAP_FORMAT_OVRD (1<<4) /* format override */
-#define AC_WCAP_STRIPE (1<<5) /* stripe */
-#define AC_WCAP_PROC_WID (1<<6) /* Proc Widget */
-#define AC_WCAP_UNSOL_CAP (1<<7) /* Unsol capable */
-#define AC_WCAP_CONN_LIST (1<<8) /* connection list */
-#define AC_WCAP_DIGITAL (1<<9) /* digital I/O */
-#define AC_WCAP_POWER (1<<10) /* power control */
-#define AC_WCAP_LR_SWAP (1<<11) /* L/R swap */
-#define AC_WCAP_CP_CAPS (1<<12) /* content protection */
-#define AC_WCAP_CHAN_CNT_EXT (7<<13) /* channel count ext */
-#define AC_WCAP_DELAY (0xf<<16)
-#define AC_WCAP_DELAY_SHIFT 16
-#define AC_WCAP_TYPE (0xf<<20)
-#define AC_WCAP_TYPE_SHIFT 20
-
-/* supported PCM rates and bits */
-#define AC_SUPPCM_RATES (0xfff << 0)
-#define AC_SUPPCM_BITS_8 (1<<16)
-#define AC_SUPPCM_BITS_16 (1<<17)
-#define AC_SUPPCM_BITS_20 (1<<18)
-#define AC_SUPPCM_BITS_24 (1<<19)
-#define AC_SUPPCM_BITS_32 (1<<20)
-
-/* supported PCM stream format */
-#define AC_SUPFMT_PCM (1<<0)
-#define AC_SUPFMT_FLOAT32 (1<<1)
-#define AC_SUPFMT_AC3 (1<<2)
-
-/* GP I/O count */
-#define AC_GPIO_IO_COUNT (0xff<<0)
-#define AC_GPIO_O_COUNT (0xff<<8)
-#define AC_GPIO_O_COUNT_SHIFT 8
-#define AC_GPIO_I_COUNT (0xff<<16)
-#define AC_GPIO_I_COUNT_SHIFT 16
-#define AC_GPIO_UNSOLICITED (1<<30)
-#define AC_GPIO_WAKE (1<<31)
-
-/* Converter stream, channel */
-#define AC_CONV_CHANNEL (0xf<<0)
-#define AC_CONV_STREAM (0xf<<4)
-#define AC_CONV_STREAM_SHIFT 4
-
-/* Input converter SDI select */
-#define AC_SDI_SELECT (0xf<<0)
-
-/* stream format id */
-#define AC_FMT_CHAN_SHIFT 0
-#define AC_FMT_CHAN_MASK (0x0f << 0)
-#define AC_FMT_BITS_SHIFT 4
-#define AC_FMT_BITS_MASK (7 << 4)
-#define AC_FMT_BITS_8 (0 << 4)
-#define AC_FMT_BITS_16 (1 << 4)
-#define AC_FMT_BITS_20 (2 << 4)
-#define AC_FMT_BITS_24 (3 << 4)
-#define AC_FMT_BITS_32 (4 << 4)
-#define AC_FMT_DIV_SHIFT 8
-#define AC_FMT_DIV_MASK (7 << 8)
-#define AC_FMT_MULT_SHIFT 11
-#define AC_FMT_MULT_MASK (7 << 11)
-#define AC_FMT_BASE_SHIFT 14
-#define AC_FMT_BASE_48K (0 << 14)
-#define AC_FMT_BASE_44K (1 << 14)
-#define AC_FMT_TYPE_SHIFT 15
-#define AC_FMT_TYPE_PCM (0 << 15)
-#define AC_FMT_TYPE_NON_PCM (1 << 15)
-
-/* Unsolicited response control */
-#define AC_UNSOL_TAG (0x3f<<0)
-#define AC_UNSOL_ENABLED (1<<7)
-#define AC_USRSP_EN AC_UNSOL_ENABLED
-
-/* Unsolicited responses */
-#define AC_UNSOL_RES_TAG (0x3f<<26)
-#define AC_UNSOL_RES_TAG_SHIFT 26
-#define AC_UNSOL_RES_SUBTAG (0x1f<<21)
-#define AC_UNSOL_RES_SUBTAG_SHIFT 21
-#define AC_UNSOL_RES_ELDV (1<<1) /* ELD Data valid (for HDMI) */
-#define AC_UNSOL_RES_PD (1<<0) /* pinsense detect */
-#define AC_UNSOL_RES_CP_STATE (1<<1) /* content protection */
-#define AC_UNSOL_RES_CP_READY (1<<0) /* content protection */
-
-/* Pin widget capabilies */
-#define AC_PINCAP_IMP_SENSE (1<<0) /* impedance sense capable */
-#define AC_PINCAP_TRIG_REQ (1<<1) /* trigger required */
-#define AC_PINCAP_PRES_DETECT (1<<2) /* presence detect capable */
-#define AC_PINCAP_HP_DRV (1<<3) /* headphone drive capable */
-#define AC_PINCAP_OUT (1<<4) /* output capable */
-#define AC_PINCAP_IN (1<<5) /* input capable */
-#define AC_PINCAP_BALANCE (1<<6) /* balanced I/O capable */
-/* Note: This LR_SWAP pincap is defined in the Realtek ALC883 specification,
- * but is marked reserved in the Intel HDA specification.
- */
-#define AC_PINCAP_LR_SWAP (1<<7) /* L/R swap */
-/* Note: The same bit as LR_SWAP is newly defined as HDMI capability
- * in HD-audio specification
- */
-#define AC_PINCAP_HDMI (1<<7) /* HDMI pin */
-#define AC_PINCAP_DP (1<<24) /* DisplayPort pin, can
- * coexist with AC_PINCAP_HDMI
- */
-#define AC_PINCAP_VREF (0x37<<8)
-#define AC_PINCAP_VREF_SHIFT 8
-#define AC_PINCAP_EAPD (1<<16) /* EAPD capable */
-#define AC_PINCAP_HBR (1<<27) /* High Bit Rate */
-/* Vref status (used in pin cap) */
-#define AC_PINCAP_VREF_HIZ (1<<0) /* Hi-Z */
-#define AC_PINCAP_VREF_50 (1<<1) /* 50% */
-#define AC_PINCAP_VREF_GRD (1<<2) /* ground */
-#define AC_PINCAP_VREF_80 (1<<4) /* 80% */
-#define AC_PINCAP_VREF_100 (1<<5) /* 100% */
-
-/* Amplifier capabilities */
-#define AC_AMPCAP_OFFSET (0x7f<<0) /* 0dB offset */
-#define AC_AMPCAP_OFFSET_SHIFT 0
-#define AC_AMPCAP_NUM_STEPS (0x7f<<8) /* number of steps */
-#define AC_AMPCAP_NUM_STEPS_SHIFT 8
-#define AC_AMPCAP_STEP_SIZE (0x7f<<16) /* step size 0-32dB
- * in 0.25dB
- */
-#define AC_AMPCAP_STEP_SIZE_SHIFT 16
-#define AC_AMPCAP_MUTE (1<<31) /* mute capable */
-#define AC_AMPCAP_MUTE_SHIFT 31
-
-/* driver-specific amp-caps: using bits 24-30 */
-#define AC_AMPCAP_MIN_MUTE (1 << 30) /* min-volume = mute */
-
-/* Connection list */
-#define AC_CLIST_LENGTH (0x7f<<0)
-#define AC_CLIST_LONG (1<<7)
-
-/* Supported power status */
-#define AC_PWRST_D0SUP (1<<0)
-#define AC_PWRST_D1SUP (1<<1)
-#define AC_PWRST_D2SUP (1<<2)
-#define AC_PWRST_D3SUP (1<<3)
-#define AC_PWRST_D3COLDSUP (1<<4)
-#define AC_PWRST_S3D3COLDSUP (1<<29)
-#define AC_PWRST_CLKSTOP (1<<30)
-#define AC_PWRST_EPSS (1U<<31)
-
-/* Power state values */
-#define AC_PWRST_SETTING (0xf<<0)
-#define AC_PWRST_ACTUAL (0xf<<4)
-#define AC_PWRST_ACTUAL_SHIFT 4
-#define AC_PWRST_D0 0x00
-#define AC_PWRST_D1 0x01
-#define AC_PWRST_D2 0x02
-#define AC_PWRST_D3 0x03
-
-/* Processing capabilies */
-#define AC_PCAP_BENIGN (1<<0)
-#define AC_PCAP_NUM_COEF (0xff<<8)
-#define AC_PCAP_NUM_COEF_SHIFT 8
-
-/* Volume knobs capabilities */
-#define AC_KNBCAP_NUM_STEPS (0x7f<<0)
-#define AC_KNBCAP_DELTA (1<<7)
-
-/* HDMI LPCM capabilities */
-#define AC_LPCMCAP_48K_CP_CHNS (0x0f<<0) /* max channels w/ CP-on */
-#define AC_LPCMCAP_48K_NO_CHNS (0x0f<<4) /* max channels w/o CP-on */
-#define AC_LPCMCAP_48K_20BIT (1<<8) /* 20b bitrate supported */
-#define AC_LPCMCAP_48K_24BIT (1<<9) /* 24b bitrate supported */
-#define AC_LPCMCAP_96K_CP_CHNS (0x0f<<10) /* max channels w/ CP-on */
-#define AC_LPCMCAP_96K_NO_CHNS (0x0f<<14) /* max channels w/o CP-on */
-#define AC_LPCMCAP_96K_20BIT (1<<18) /* 20b bitrate supported */
-#define AC_LPCMCAP_96K_24BIT (1<<19) /* 24b bitrate supported */
-#define AC_LPCMCAP_192K_CP_CHNS (0x0f<<20) /* max channels w/ CP-on */
-#define AC_LPCMCAP_192K_NO_CHNS (0x0f<<24) /* max channels w/o CP-on */
-#define AC_LPCMCAP_192K_20BIT (1<<28) /* 20b bitrate supported */
-#define AC_LPCMCAP_192K_24BIT (1<<29) /* 24b bitrate supported */
-#define AC_LPCMCAP_44K (1<<30) /* 44.1kHz support */
-#define AC_LPCMCAP_44K_MS (1<<31) /* 44.1kHz-multiplies support */
-
-/*
- * Control Parameters
- */
-
-/* Amp gain/mute */
-#define AC_AMP_MUTE (1<<7)
-#define AC_AMP_GAIN (0x7f)
-#define AC_AMP_GET_INDEX (0xf<<0)
-
-#define AC_AMP_GET_LEFT (1<<13)
-#define AC_AMP_GET_RIGHT (0<<13)
-#define AC_AMP_GET_OUTPUT (1<<15)
-#define AC_AMP_GET_INPUT (0<<15)
-
-#define AC_AMP_SET_INDEX (0xf<<8)
-#define AC_AMP_SET_INDEX_SHIFT 8
-#define AC_AMP_SET_RIGHT (1<<12)
-#define AC_AMP_SET_LEFT (1<<13)
-#define AC_AMP_SET_INPUT (1<<14)
-#define AC_AMP_SET_OUTPUT (1<<15)
-
-/* DIGITAL1 bits */
-#define AC_DIG1_ENABLE (1<<0)
-#define AC_DIG1_V (1<<1)
-#define AC_DIG1_VCFG (1<<2)
-#define AC_DIG1_EMPHASIS (1<<3)
-#define AC_DIG1_COPYRIGHT (1<<4)
-#define AC_DIG1_NONAUDIO (1<<5)
-#define AC_DIG1_PROFESSIONAL (1<<6)
-#define AC_DIG1_LEVEL (1<<7)
-
-/* DIGITAL2 bits */
-#define AC_DIG2_CC (0x7f<<0)
-
-/* Pin widget control - 8bit */
-#define AC_PINCTL_EPT (0x3<<0)
-#define AC_PINCTL_EPT_NATIVE 0
-#define AC_PINCTL_EPT_HBR 3
-#define AC_PINCTL_VREFEN (0x7<<0)
-#define AC_PINCTL_VREF_HIZ 0 /* Hi-Z */
-#define AC_PINCTL_VREF_50 1 /* 50% */
-#define AC_PINCTL_VREF_GRD 2 /* ground */
-#define AC_PINCTL_VREF_80 4 /* 80% */
-#define AC_PINCTL_VREF_100 5 /* 100% */
-#define AC_PINCTL_IN_EN (1<<5)
-#define AC_PINCTL_OUT_EN (1<<6)
-#define AC_PINCTL_HP_EN (1<<7)
-
-/* Pin sense - 32bit */
-#define AC_PINSENSE_IMPEDANCE_MASK (0x7fffffff)
-#define AC_PINSENSE_PRESENCE (1<<31)
-#define AC_PINSENSE_ELDV (1<<30) /* ELD valid (HDMI) */
-
-/* EAPD/BTL enable - 32bit */
-#define AC_EAPDBTL_BALANCED (1<<0)
-#define AC_EAPDBTL_EAPD (1<<1)
-#define AC_EAPDBTL_LR_SWAP (1<<2)
-
-/* HDMI ELD data */
-#define AC_ELDD_ELD_VALID (1<<31)
-#define AC_ELDD_ELD_DATA 0xff
-
-/* HDMI DIP size */
-#define AC_DIPSIZE_ELD_BUF (1<<3) /* ELD buf size of packet size */
-#define AC_DIPSIZE_PACK_IDX (0x07<<0) /* packet index */
-
-/* HDMI DIP index */
-#define AC_DIPIDX_PACK_IDX (0x07<<5) /* packet idnex */
-#define AC_DIPIDX_BYTE_IDX (0x1f<<0) /* byte index */
-
-/* HDMI DIP xmit (transmit) control */
-#define AC_DIPXMIT_MASK (0x3<<6)
-#define AC_DIPXMIT_DISABLE (0x0<<6) /* disable xmit */
-#define AC_DIPXMIT_ONCE (0x2<<6) /* xmit once then disable */
-#define AC_DIPXMIT_BEST (0x3<<6) /* best effort */
-
-/* HDMI content protection (CP) control */
-#define AC_CPCTRL_CES (1<<9) /* current encryption state */
-#define AC_CPCTRL_READY (1<<8) /* ready bit */
-#define AC_CPCTRL_SUBTAG (0x1f<<3) /* subtag for unsol-resp */
-#define AC_CPCTRL_STATE (3<<0) /* current CP request state */
-
-/* Converter channel <-> HDMI slot mapping */
-#define AC_CVTMAP_HDMI_SLOT (0xf<<0) /* HDMI slot number */
-#define AC_CVTMAP_CHAN (0xf<<4) /* converter channel number */
-
-/* configuration default - 32bit */
-#define AC_DEFCFG_SEQUENCE (0xf<<0)
-#define AC_DEFCFG_DEF_ASSOC (0xf<<4)
-#define AC_DEFCFG_ASSOC_SHIFT 4
-#define AC_DEFCFG_MISC (0xf<<8)
-#define AC_DEFCFG_MISC_SHIFT 8
-#define AC_DEFCFG_MISC_NO_PRESENCE (1<<0)
-#define AC_DEFCFG_COLOR (0xf<<12)
-#define AC_DEFCFG_COLOR_SHIFT 12
-#define AC_DEFCFG_CONN_TYPE (0xf<<16)
-#define AC_DEFCFG_CONN_TYPE_SHIFT 16
-#define AC_DEFCFG_DEVICE (0xf<<20)
-#define AC_DEFCFG_DEVICE_SHIFT 20
-#define AC_DEFCFG_LOCATION (0x3f<<24)
-#define AC_DEFCFG_LOCATION_SHIFT 24
-#define AC_DEFCFG_PORT_CONN (0x3<<30)
-#define AC_DEFCFG_PORT_CONN_SHIFT 30
-
-/* device device types (0x0-0xf) */
-enum {
- AC_JACK_LINE_OUT,
- AC_JACK_SPEAKER,
- AC_JACK_HP_OUT,
- AC_JACK_CD,
- AC_JACK_SPDIF_OUT,
- AC_JACK_DIG_OTHER_OUT,
- AC_JACK_MODEM_LINE_SIDE,
- AC_JACK_MODEM_HAND_SIDE,
- AC_JACK_LINE_IN,
- AC_JACK_AUX,
- AC_JACK_MIC_IN,
- AC_JACK_TELEPHONY,
- AC_JACK_SPDIF_IN,
- AC_JACK_DIG_OTHER_IN,
- AC_JACK_OTHER = 0xf,
-};
-
-/* jack connection types (0x0-0xf) */
-enum {
- AC_JACK_CONN_UNKNOWN,
- AC_JACK_CONN_1_8,
- AC_JACK_CONN_1_4,
- AC_JACK_CONN_ATAPI,
- AC_JACK_CONN_RCA,
- AC_JACK_CONN_OPTICAL,
- AC_JACK_CONN_OTHER_DIGITAL,
- AC_JACK_CONN_OTHER_ANALOG,
- AC_JACK_CONN_DIN,
- AC_JACK_CONN_XLR,
- AC_JACK_CONN_RJ11,
- AC_JACK_CONN_COMB,
- AC_JACK_CONN_OTHER = 0xf,
-};
-
-/* jack colors (0x0-0xf) */
-enum {
- AC_JACK_COLOR_UNKNOWN,
- AC_JACK_COLOR_BLACK,
- AC_JACK_COLOR_GREY,
- AC_JACK_COLOR_BLUE,
- AC_JACK_COLOR_GREEN,
- AC_JACK_COLOR_RED,
- AC_JACK_COLOR_ORANGE,
- AC_JACK_COLOR_YELLOW,
- AC_JACK_COLOR_PURPLE,
- AC_JACK_COLOR_PINK,
- AC_JACK_COLOR_WHITE = 0xe,
- AC_JACK_COLOR_OTHER,
-};
-
-/* Jack location (0x0-0x3f) */
-/* common case */
-enum {
- AC_JACK_LOC_NONE,
- AC_JACK_LOC_REAR,
- AC_JACK_LOC_FRONT,
- AC_JACK_LOC_LEFT,
- AC_JACK_LOC_RIGHT,
- AC_JACK_LOC_TOP,
- AC_JACK_LOC_BOTTOM,
-};
-/* bits 4-5 */
-enum {
- AC_JACK_LOC_EXTERNAL = 0x00,
- AC_JACK_LOC_INTERNAL = 0x10,
- AC_JACK_LOC_SEPARATE = 0x20,
- AC_JACK_LOC_OTHER = 0x30,
-};
-enum {
- /* external on primary chasis */
- AC_JACK_LOC_REAR_PANEL = 0x07,
- AC_JACK_LOC_DRIVE_BAY,
- /* internal */
- AC_JACK_LOC_RISER = 0x17,
- AC_JACK_LOC_HDMI,
- AC_JACK_LOC_ATAPI,
- /* others */
- AC_JACK_LOC_MOBILE_IN = 0x37,
- AC_JACK_LOC_MOBILE_OUT,
-};
-
-/* Port connectivity (0-3) */
-enum {
- AC_JACK_PORT_COMPLEX,
- AC_JACK_PORT_NONE,
- AC_JACK_PORT_FIXED,
- AC_JACK_PORT_BOTH,
-};
-
-/* max. connections to a widget */
-#define HDA_MAX_CONNECTIONS 32
-
-/* max. codec address */
-#define HDA_MAX_CODEC_ADDRESS 0x0f
-
-/*
- * generic arrays
- */
-struct snd_array {
- unsigned int used;
- unsigned int alloced;
- unsigned int elem_size;
- unsigned int alloc_align;
- void *list;
-};
-
-void *snd_array_new(struct snd_array *array);
-void snd_array_free(struct snd_array *array);
-static inline void snd_array_init(struct snd_array *array, unsigned int size,
- unsigned int align)
-{
- array->elem_size = size;
- array->alloc_align = align;
-}
-
-static inline void *snd_array_elem(struct snd_array *array, unsigned int idx)
-{
- return array->list + idx * array->elem_size;
-}
-
-static inline unsigned int snd_array_index(struct snd_array *array, void *ptr)
-{
- return (unsigned long)(ptr - array->list) / array->elem_size;
-}
-
-/*
- * Structures
- */
-
-struct hda_bus;
-struct hda_beep;
-struct hda_codec;
-struct hda_pcm;
-struct hda_pcm_stream;
-struct hda_bus_unsolicited;
-
-/* NID type */
-typedef u16 hda_nid_t;
-
-/* bus operators */
-struct hda_bus_ops {
- /* send a single command */
- int (*command)(struct hda_bus *bus, unsigned int cmd);
- /* get a response from the last command */
- unsigned int (*get_response)(struct hda_bus *bus, unsigned int addr);
- /* free the private data */
- void (*private_free)(struct hda_bus *);
- /* attach a PCM stream */
- int (*attach_pcm)(struct hda_bus *bus, struct hda_codec *codec,
- struct hda_pcm *pcm);
- /* reset bus for retry verb */
- void (*bus_reset)(struct hda_bus *bus);
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- /* notify power-up/down from codec to controller */
- void (*pm_notify)(struct hda_bus *bus);
-#endif
-};
-
-/* template to pass to the bus constructor */
-struct hda_bus_template {
- void *private_data;
- struct pci_dev *pci;
- const char *modelname;
- int *power_save;
- struct hda_bus_ops ops;
-};
-
-/*
- * codec bus
- *
- * each controller needs to creata a hda_bus to assign the accessor.
- * A hda_bus contains several codecs in the list codec_list.
- */
-struct hda_bus {
- struct snd_card *card;
-
- /* copied from template */
- void *private_data;
- struct pci_dev *pci;
- const char *modelname;
- int *power_save;
- struct hda_bus_ops ops;
-
- /* codec linked list */
- struct list_head codec_list;
- /* link caddr -> codec */
- struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1];
-
- struct mutex cmd_mutex;
- struct mutex prepare_mutex;
-
- /* unsolicited event queue */
- struct hda_bus_unsolicited *unsol;
- char workq_name[16];
- struct workqueue_struct *workq; /* common workqueue for codecs */
-
- /* assigned PCMs */
- DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES);
-
- /* misc op flags */
- unsigned int needs_damn_long_delay :1;
- unsigned int allow_bus_reset:1; /* allow bus reset at fatal error */
- unsigned int sync_write:1; /* sync after verb write */
- /* status for codec/controller */
- unsigned int shutdown :1; /* being unloaded */
- unsigned int rirb_error:1; /* error in codec communication */
- unsigned int response_reset:1; /* controller was reset */
- unsigned int in_reset:1; /* during reset operation */
- unsigned int power_keep_link_on:1; /* don't power off HDA link */
-};
-
-/*
- * codec preset
- *
- * Known codecs have the patch to build and set up the controls/PCMs
- * better than the generic parser.
- */
-struct hda_codec_preset {
- unsigned int id;
- unsigned int mask;
- unsigned int subs;
- unsigned int subs_mask;
- unsigned int rev;
- hda_nid_t afg, mfg;
- const char *name;
- int (*patch)(struct hda_codec *codec);
-};
-
-struct hda_codec_preset_list {
- const struct hda_codec_preset *preset;
- struct module *owner;
- struct list_head list;
-};
-
-/* initial hook */
-int snd_hda_add_codec_preset(struct hda_codec_preset_list *preset);
-int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset);
-
-/* ops set by the preset patch */
-struct hda_codec_ops {
- int (*build_controls)(struct hda_codec *codec);
- int (*build_pcms)(struct hda_codec *codec);
- int (*init)(struct hda_codec *codec);
- void (*free)(struct hda_codec *codec);
- void (*unsol_event)(struct hda_codec *codec, unsigned int res);
- void (*set_power_state)(struct hda_codec *codec, hda_nid_t fg,
- unsigned int power_state);
-#ifdef CONFIG_PM
- int (*suspend)(struct hda_codec *codec, pm_message_t state);
- int (*post_suspend)(struct hda_codec *codec);
- int (*pre_resume)(struct hda_codec *codec);
- int (*resume)(struct hda_codec *codec);
-#endif
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- int (*check_power_status)(struct hda_codec *codec, hda_nid_t nid);
-#endif
- void (*reboot_notify)(struct hda_codec *codec);
-};
-
-/* record for amp information cache */
-struct hda_cache_head {
- u32 key; /* hash key */
- u16 val; /* assigned value */
- u16 next; /* next link; -1 = terminal */
-};
-
-struct hda_amp_info {
- struct hda_cache_head head;
- u32 amp_caps; /* amp capabilities */
- u16 vol[2]; /* current volume & mute */
-};
-
-struct hda_cache_rec {
- u16 hash[64]; /* hash table for index */
- struct snd_array buf; /* record entries */
-};
-
-/* PCM callbacks */
-struct hda_pcm_ops {
- int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec,
- struct snd_pcm_substream *substream);
- int (*close)(struct hda_pcm_stream *info, struct hda_codec *codec,
- struct snd_pcm_substream *substream);
- int (*prepare)(struct hda_pcm_stream *info, struct hda_codec *codec,
- unsigned int stream_tag, unsigned int format,
- struct snd_pcm_substream *substream);
- int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec,
- struct snd_pcm_substream *substream);
-};
-
-/* PCM information for each substream */
-struct hda_pcm_stream {
- unsigned int substreams; /* number of substreams, 0 = not exist*/
- unsigned int channels_min; /* min. number of channels */
- unsigned int channels_max; /* max. number of channels */
- hda_nid_t nid; /* default NID to query rates/formats/bps, or set up */
- u32 rates; /* supported rates */
- u64 formats; /* supported formats (SNDRV_PCM_FMTBIT_) */
- unsigned int maxbps; /* supported max. bit per sample */
- struct hda_pcm_ops ops;
-};
-
-/* PCM types */
-enum {
- HDA_PCM_TYPE_AUDIO,
- HDA_PCM_TYPE_SPDIF,
- HDA_PCM_TYPE_HDMI,
- HDA_PCM_TYPE_MODEM,
- HDA_PCM_NTYPES
-};
-
-/* for PCM creation */
-struct hda_pcm {
- char *name;
- struct hda_pcm_stream stream[2];
- unsigned int pcm_type; /* HDA_PCM_TYPE_XXX */
- int device; /* device number to assign */
- struct snd_pcm *pcm; /* assigned PCM instance */
-};
-
-/* codec information */
-struct hda_codec {
- struct hda_bus *bus;
- unsigned int addr; /* codec addr*/
- struct list_head list; /* list point */
-
- hda_nid_t afg; /* AFG node id */
- hda_nid_t mfg; /* MFG node id */
-
- /* ids */
- u8 afg_function_id;
- u8 mfg_function_id;
- u8 afg_unsol;
- u8 mfg_unsol;
- u32 vendor_id;
- u32 subsystem_id;
- u32 revision_id;
-
- /* detected preset */
- const struct hda_codec_preset *preset;
- struct module *owner;
- const char *vendor_name; /* codec vendor name */
- const char *chip_name; /* codec chip name */
- const char *modelname; /* model name for preset */
-
- /* set by patch */
- struct hda_codec_ops patch_ops;
-
- /* PCM to create, set by patch_ops.build_pcms callback */
- unsigned int num_pcms;
- struct hda_pcm *pcm_info;
-
- /* codec specific info */
- void *spec;
-
- /* beep device */
- struct hda_beep *beep;
- unsigned int beep_mode;
-
- /* widget capabilities cache */
- unsigned int num_nodes;
- hda_nid_t start_nid;
- u32 *wcaps;
-
- struct snd_array mixers; /* list of assigned mixer elements */
- struct snd_array nids; /* list of mapped mixer elements */
-
- struct hda_cache_rec amp_cache; /* cache for amp access */
- struct hda_cache_rec cmd_cache; /* cache for other commands */
-
- struct snd_array conn_lists; /* connection-list array */
-
- struct mutex spdif_mutex;
- struct mutex control_mutex;
- struct snd_array spdif_out;
- unsigned int spdif_in_enable; /* SPDIF input enable? */
- const hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */
- struct snd_array init_pins; /* initial (BIOS) pin configurations */
- struct snd_array driver_pins; /* pin configs set by codec parser */
- struct snd_array cvt_setups; /* audio convert setups */
-
-#ifdef CONFIG_SND_HDA_HWDEP
- struct snd_hwdep *hwdep; /* assigned hwdep device */
- struct snd_array init_verbs; /* additional init verbs */
- struct snd_array hints; /* additional hints */
- struct snd_array user_pins; /* default pin configs to override */
-#endif
-
- /* misc flags */
- unsigned int spdif_status_reset :1; /* needs to toggle SPDIF for each
- * status change
- * (e.g. Realtek codecs)
- */
- unsigned int pin_amp_workaround:1; /* pin out-amp takes index
- * (e.g. Conexant codecs)
- */
- unsigned int single_adc_amp:1; /* adc in-amp takes no index
- * (e.g. CX20549 codec)
- */
- unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */
- unsigned int pins_shutup:1; /* pins are shut up */
- unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */
- unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */
- unsigned int no_jack_detect:1; /* Machine has no jack-detection */
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- unsigned int power_on :1; /* current (global) power-state */
- unsigned int power_transition :1; /* power-state in transition */
- int power_count; /* current (global) power refcount */
- struct delayed_work power_work; /* delayed task for powerdown */
- unsigned long power_on_acct;
- unsigned long power_off_acct;
- unsigned long power_jiffies;
-#endif
-
- /* codec-specific additional proc output */
- void (*proc_widget_hook)(struct snd_info_buffer *buffer,
- struct hda_codec *codec, hda_nid_t nid);
-
- /* jack detection */
- struct snd_array jacktbl;
-
-#ifdef CONFIG_SND_HDA_INPUT_JACK
- /* jack detection */
- struct snd_array jacks;
-#endif
-};
-
-/* direction */
-enum {
- HDA_INPUT, HDA_OUTPUT
-};
-
-
-/*
- * constructors
- */
-int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
- struct hda_bus **busp);
-int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
- struct hda_codec **codecp);
-int snd_hda_codec_configure(struct hda_codec *codec);
-
-/*
- * low level functions
- */
-unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
- int direct,
- unsigned int verb, unsigned int parm);
-int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
- unsigned int verb, unsigned int parm);
-#define snd_hda_param_read(codec, nid, param) \
- snd_hda_codec_read(codec, nid, 0, AC_VERB_PARAMETERS, param)
-int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
- hda_nid_t *start_id);
-int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
- hda_nid_t *conn_list, int max_conns);
-int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
- hda_nid_t *conn_list, int max_conns);
-int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid,
- const hda_nid_t **listp);
-int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int nums,
- const hda_nid_t *list);
-int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
- hda_nid_t nid, int recursive);
-int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
- u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
-
-struct hda_verb {
- hda_nid_t nid;
- u32 verb;
- u32 param;
-};
-
-void snd_hda_sequence_write(struct hda_codec *codec,
- const struct hda_verb *seq);
-
-/* unsolicited event */
-int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex);
-
-/* cached write */
-#ifdef CONFIG_PM
-int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
- int direct, unsigned int verb, unsigned int parm);
-void snd_hda_sequence_write_cache(struct hda_codec *codec,
- const struct hda_verb *seq);
-int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid,
- int direct, unsigned int verb, unsigned int parm);
-void snd_hda_codec_resume_cache(struct hda_codec *codec);
-#else
-#define snd_hda_codec_write_cache snd_hda_codec_write
-#define snd_hda_codec_update_cache snd_hda_codec_write
-#define snd_hda_sequence_write_cache snd_hda_sequence_write
-#endif
-
-/* the struct for codec->pin_configs */
-struct hda_pincfg {
- hda_nid_t nid;
- unsigned char ctrl; /* current pin control value */
- unsigned char pad; /* reserved */
- unsigned int cfg; /* default configuration */
-};
-
-unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid);
-int snd_hda_codec_set_pincfg(struct hda_codec *codec, hda_nid_t nid,
- unsigned int cfg);
-int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
- hda_nid_t nid, unsigned int cfg); /* for hwdep */
-void snd_hda_shutup_pins(struct hda_codec *codec);
-
-/* SPDIF controls */
-struct hda_spdif_out {
- hda_nid_t nid; /* Converter nid values relate to */
- unsigned int status; /* IEC958 status bits */
- unsigned short ctls; /* SPDIF control bits */
-};
-struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec,
- hda_nid_t nid);
-void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx);
-void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid);
-
-/*
- * Mixer
- */
-int snd_hda_build_controls(struct hda_bus *bus);
-int snd_hda_codec_build_controls(struct hda_codec *codec);
-
-/*
- * PCM
- */
-int snd_hda_build_pcms(struct hda_bus *bus);
-int snd_hda_codec_build_pcms(struct hda_codec *codec);
-
-int snd_hda_codec_prepare(struct hda_codec *codec,
- struct hda_pcm_stream *hinfo,
- unsigned int stream,
- unsigned int format,
- struct snd_pcm_substream *substream);
-void snd_hda_codec_cleanup(struct hda_codec *codec,
- struct hda_pcm_stream *hinfo,
- struct snd_pcm_substream *substream);
-
-void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
- u32 stream_tag,
- int channel_id, int format);
-void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid,
- int do_now);
-#define snd_hda_codec_cleanup_stream(codec, nid) \
- __snd_hda_codec_cleanup_stream(codec, nid, 0)
-unsigned int snd_hda_calc_stream_format(unsigned int rate,
- unsigned int channels,
- unsigned int format,
- unsigned int maxbps,
- unsigned short spdif_ctls);
-int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
- unsigned int format);
-
-/*
- * Misc
- */
-void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen);
-void snd_hda_bus_reboot_notify(struct hda_bus *bus);
-void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
- unsigned int power_state,
- bool eapd_workaround);
-
-/*
- * power management
- */
-#ifdef CONFIG_PM
-int snd_hda_suspend(struct hda_bus *bus);
-int snd_hda_resume(struct hda_bus *bus);
-#endif
-
-static inline
-int hda_call_check_power_status(struct hda_codec *codec, hda_nid_t nid)
-{
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- if (codec->patch_ops.check_power_status)
- return codec->patch_ops.check_power_status(codec, nid);
-#endif
- return 0;
-}
-
-/*
- * get widget information
- */
-const char *snd_hda_get_jack_connectivity(u32 cfg);
-const char *snd_hda_get_jack_type(u32 cfg);
-const char *snd_hda_get_jack_location(u32 cfg);
-
-/*
- * power saving
- */
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-void snd_hda_power_up(struct hda_codec *codec);
-void snd_hda_power_down(struct hda_codec *codec);
-#define snd_hda_codec_needs_resume(codec) codec->power_count
-void snd_hda_update_power_acct(struct hda_codec *codec);
-#else
-static inline void snd_hda_power_up(struct hda_codec *codec) {}
-static inline void snd_hda_power_down(struct hda_codec *codec) {}
-#define snd_hda_codec_needs_resume(codec) 1
-#endif
-
-#ifdef CONFIG_SND_HDA_PATCH_LOADER
-/*
- * patch firmware
- */
-int snd_hda_load_patch(struct hda_bus *bus, const char *patch);
-#endif
-
-/*
- * Codec modularization
- */
-
-/* Export symbols only for communication with codec drivers;
- * When built in kernel, all HD-audio drivers are supposed to be statically
- * linked to the kernel. Thus, the symbols don't have to (or shouldn't) be
- * exported unless it's built as a module.
- */
-#ifdef MODULE
-#define EXPORT_SYMBOL_HDA(sym) EXPORT_SYMBOL_GPL(sym)
-#else
-#define EXPORT_SYMBOL_HDA(sym)
-#endif
-
-#endif /* __SOUND_HDA_CODEC_H */
diff --git a/ANDROID_3.4.5/sound/pci/hda/hda_eld.c b/ANDROID_3.4.5/sound/pci/hda/hda_eld.c
deleted file mode 100644
index 4c054f44..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/hda_eld.c
+++ /dev/null
@@ -1,671 +0,0 @@
-/*
- * Generic routines and proc interface for ELD(EDID Like Data) information
- *
- * Copyright(c) 2008 Intel Corporation.
- *
- * Authors:
- * Wu Fengguang <wfg@linux.intel.com>
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <asm/unaligned.h>
-#include "hda_codec.h"
-#include "hda_local.h"
-
-enum eld_versions {
- ELD_VER_CEA_861D = 2,
- ELD_VER_PARTIAL = 31,
-};
-
-enum cea_edid_versions {
- CEA_EDID_VER_NONE = 0,
- CEA_EDID_VER_CEA861 = 1,
- CEA_EDID_VER_CEA861A = 2,
- CEA_EDID_VER_CEA861BCD = 3,
- CEA_EDID_VER_RESERVED = 4,
-};
-
-static char *cea_speaker_allocation_names[] = {
- /* 0 */ "FL/FR",
- /* 1 */ "LFE",
- /* 2 */ "FC",
- /* 3 */ "RL/RR",
- /* 4 */ "RC",
- /* 5 */ "FLC/FRC",
- /* 6 */ "RLC/RRC",
- /* 7 */ "FLW/FRW",
- /* 8 */ "FLH/FRH",
- /* 9 */ "TC",
- /* 10 */ "FCH",
-};
-
-static char *eld_connection_type_names[4] = {
- "HDMI",
- "DisplayPort",
- "2-reserved",
- "3-reserved"
-};
-
-enum cea_audio_coding_types {
- AUDIO_CODING_TYPE_REF_STREAM_HEADER = 0,
- AUDIO_CODING_TYPE_LPCM = 1,
- AUDIO_CODING_TYPE_AC3 = 2,
- AUDIO_CODING_TYPE_MPEG1 = 3,
- AUDIO_CODING_TYPE_MP3 = 4,
- AUDIO_CODING_TYPE_MPEG2 = 5,
- AUDIO_CODING_TYPE_AACLC = 6,
- AUDIO_CODING_TYPE_DTS = 7,
- AUDIO_CODING_TYPE_ATRAC = 8,
- AUDIO_CODING_TYPE_SACD = 9,
- AUDIO_CODING_TYPE_EAC3 = 10,
- AUDIO_CODING_TYPE_DTS_HD = 11,
- AUDIO_CODING_TYPE_MLP = 12,
- AUDIO_CODING_TYPE_DST = 13,
- AUDIO_CODING_TYPE_WMAPRO = 14,
- AUDIO_CODING_TYPE_REF_CXT = 15,
- /* also include valid xtypes below */
- AUDIO_CODING_TYPE_HE_AAC = 15,
- AUDIO_CODING_TYPE_HE_AAC2 = 16,
- AUDIO_CODING_TYPE_MPEG_SURROUND = 17,
-};
-
-enum cea_audio_coding_xtypes {
- AUDIO_CODING_XTYPE_HE_REF_CT = 0,
- AUDIO_CODING_XTYPE_HE_AAC = 1,
- AUDIO_CODING_XTYPE_HE_AAC2 = 2,
- AUDIO_CODING_XTYPE_MPEG_SURROUND = 3,
- AUDIO_CODING_XTYPE_FIRST_RESERVED = 4,
-};
-
-static char *cea_audio_coding_type_names[] = {
- /* 0 */ "undefined",
- /* 1 */ "LPCM",
- /* 2 */ "AC-3",
- /* 3 */ "MPEG1",
- /* 4 */ "MP3",
- /* 5 */ "MPEG2",
- /* 6 */ "AAC-LC",
- /* 7 */ "DTS",
- /* 8 */ "ATRAC",
- /* 9 */ "DSD (One Bit Audio)",
- /* 10 */ "E-AC-3/DD+ (Dolby Digital Plus)",
- /* 11 */ "DTS-HD",
- /* 12 */ "MLP (Dolby TrueHD)",
- /* 13 */ "DST",
- /* 14 */ "WMAPro",
- /* 15 */ "HE-AAC",
- /* 16 */ "HE-AACv2",
- /* 17 */ "MPEG Surround",
-};
-
-/*
- * The following two lists are shared between
- * - HDMI audio InfoFrame (source to sink)
- * - CEA E-EDID Extension (sink to source)
- */
-
-/*
- * SS1:SS0 index => sample size
- */
-static int cea_sample_sizes[4] = {
- 0, /* 0: Refer to Stream Header */
- AC_SUPPCM_BITS_16, /* 1: 16 bits */
- AC_SUPPCM_BITS_20, /* 2: 20 bits */
- AC_SUPPCM_BITS_24, /* 3: 24 bits */
-};
-
-/*
- * SF2:SF1:SF0 index => sampling frequency
- */
-static int cea_sampling_frequencies[8] = {
- 0, /* 0: Refer to Stream Header */
- SNDRV_PCM_RATE_32000, /* 1: 32000Hz */
- SNDRV_PCM_RATE_44100, /* 2: 44100Hz */
- SNDRV_PCM_RATE_48000, /* 3: 48000Hz */
- SNDRV_PCM_RATE_88200, /* 4: 88200Hz */
- SNDRV_PCM_RATE_96000, /* 5: 96000Hz */
- SNDRV_PCM_RATE_176400, /* 6: 176400Hz */
- SNDRV_PCM_RATE_192000, /* 7: 192000Hz */
-};
-
-static unsigned int hdmi_get_eld_data(struct hda_codec *codec, hda_nid_t nid,
- int byte_index)
-{
- unsigned int val;
-
- val = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_HDMI_ELDD, byte_index);
-#ifdef BE_PARANOID
- printk(KERN_INFO "HDMI: ELD data byte %d: 0x%x\n", byte_index, val);
-#endif
- return val;
-}
-
-#define GRAB_BITS(buf, byte, lowbit, bits) \
-({ \
- BUILD_BUG_ON(lowbit > 7); \
- BUILD_BUG_ON(bits > 8); \
- BUILD_BUG_ON(bits <= 0); \
- \
- (buf[byte] >> (lowbit)) & ((1 << (bits)) - 1); \
-})
-
-static void hdmi_update_short_audio_desc(struct cea_sad *a,
- const unsigned char *buf)
-{
- int i;
- int val;
-
- val = GRAB_BITS(buf, 1, 0, 7);
- a->rates = 0;
- for (i = 0; i < 7; i++)
- if (val & (1 << i))
- a->rates |= cea_sampling_frequencies[i + 1];
-
- a->channels = GRAB_BITS(buf, 0, 0, 3);
- a->channels++;
-
- a->sample_bits = 0;
- a->max_bitrate = 0;
-
- a->format = GRAB_BITS(buf, 0, 3, 4);
- switch (a->format) {
- case AUDIO_CODING_TYPE_REF_STREAM_HEADER:
- snd_printd(KERN_INFO
- "HDMI: audio coding type 0 not expected\n");
- break;
-
- case AUDIO_CODING_TYPE_LPCM:
- val = GRAB_BITS(buf, 2, 0, 3);
- for (i = 0; i < 3; i++)
- if (val & (1 << i))
- a->sample_bits |= cea_sample_sizes[i + 1];
- break;
-
- case AUDIO_CODING_TYPE_AC3:
- case AUDIO_CODING_TYPE_MPEG1:
- case AUDIO_CODING_TYPE_MP3:
- case AUDIO_CODING_TYPE_MPEG2:
- case AUDIO_CODING_TYPE_AACLC:
- case AUDIO_CODING_TYPE_DTS:
- case AUDIO_CODING_TYPE_ATRAC:
- a->max_bitrate = GRAB_BITS(buf, 2, 0, 8);
- a->max_bitrate *= 8000;
- break;
-
- case AUDIO_CODING_TYPE_SACD:
- break;
-
- case AUDIO_CODING_TYPE_EAC3:
- break;
-
- case AUDIO_CODING_TYPE_DTS_HD:
- break;
-
- case AUDIO_CODING_TYPE_MLP:
- break;
-
- case AUDIO_CODING_TYPE_DST:
- break;
-
- case AUDIO_CODING_TYPE_WMAPRO:
- a->profile = GRAB_BITS(buf, 2, 0, 3);
- break;
-
- case AUDIO_CODING_TYPE_REF_CXT:
- a->format = GRAB_BITS(buf, 2, 3, 5);
- if (a->format == AUDIO_CODING_XTYPE_HE_REF_CT ||
- a->format >= AUDIO_CODING_XTYPE_FIRST_RESERVED) {
- snd_printd(KERN_INFO
- "HDMI: audio coding xtype %d not expected\n",
- a->format);
- a->format = 0;
- } else
- a->format += AUDIO_CODING_TYPE_HE_AAC -
- AUDIO_CODING_XTYPE_HE_AAC;
- break;
- }
-}
-
-/*
- * Be careful, ELD buf could be totally rubbish!
- */
-static int hdmi_update_eld(struct hdmi_eld *e,
- const unsigned char *buf, int size)
-{
- int mnl;
- int i;
-
- e->eld_ver = GRAB_BITS(buf, 0, 3, 5);
- if (e->eld_ver != ELD_VER_CEA_861D &&
- e->eld_ver != ELD_VER_PARTIAL) {
- snd_printd(KERN_INFO "HDMI: Unknown ELD version %d\n",
- e->eld_ver);
- goto out_fail;
- }
-
- e->eld_size = size;
- e->baseline_len = GRAB_BITS(buf, 2, 0, 8);
- mnl = GRAB_BITS(buf, 4, 0, 5);
- e->cea_edid_ver = GRAB_BITS(buf, 4, 5, 3);
-
- e->support_hdcp = GRAB_BITS(buf, 5, 0, 1);
- e->support_ai = GRAB_BITS(buf, 5, 1, 1);
- e->conn_type = GRAB_BITS(buf, 5, 2, 2);
- e->sad_count = GRAB_BITS(buf, 5, 4, 4);
-
- e->aud_synch_delay = GRAB_BITS(buf, 6, 0, 8) * 2;
- e->spk_alloc = GRAB_BITS(buf, 7, 0, 7);
-
- e->port_id = get_unaligned_le64(buf + 8);
-
- /* not specified, but the spec's tendency is little endian */
- e->manufacture_id = get_unaligned_le16(buf + 16);
- e->product_id = get_unaligned_le16(buf + 18);
-
- if (mnl > ELD_MAX_MNL) {
- snd_printd(KERN_INFO "HDMI: MNL is reserved value %d\n", mnl);
- goto out_fail;
- } else if (ELD_FIXED_BYTES + mnl > size) {
- snd_printd(KERN_INFO "HDMI: out of range MNL %d\n", mnl);
- goto out_fail;
- } else
- strlcpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl + 1);
-
- for (i = 0; i < e->sad_count; i++) {
- if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) {
- snd_printd(KERN_INFO "HDMI: out of range SAD %d\n", i);
- goto out_fail;
- }
- hdmi_update_short_audio_desc(e->sad + i,
- buf + ELD_FIXED_BYTES + mnl + 3 * i);
- }
-
- /*
- * HDMI sink's ELD info cannot always be retrieved for now, e.g.
- * in console or for audio devices. Assume the highest speakers
- * configuration, to _not_ prohibit multi-channel audio playback.
- */
- if (!e->spk_alloc)
- e->spk_alloc = 0xffff;
-
- e->eld_valid = true;
- return 0;
-
-out_fail:
- return -EINVAL;
-}
-
-int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid)
-{
- return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
- AC_DIPSIZE_ELD_BUF);
-}
-
-int snd_hdmi_get_eld(struct hdmi_eld *eld,
- struct hda_codec *codec, hda_nid_t nid)
-{
- int i;
- int ret;
- int size;
- unsigned char *buf;
-
- /*
- * ELD size is initialized to zero in caller function. If no errors and
- * ELD is valid, actual eld_size is assigned in hdmi_update_eld()
- */
-
- size = snd_hdmi_get_eld_size(codec, nid);
- if (size == 0) {
- /* wfg: workaround for ASUS P5E-VM HDMI board */
- snd_printd(KERN_INFO "HDMI: ELD buf size is 0, force 128\n");
- size = 128;
- }
- if (size < ELD_FIXED_BYTES || size > ELD_MAX_SIZE) {
- snd_printd(KERN_INFO "HDMI: invalid ELD buf size %d\n", size);
- return -ERANGE;
- }
-
- /* set ELD buffer */
- buf = eld->eld_buffer;
-
- for (i = 0; i < size; i++) {
- unsigned int val = hdmi_get_eld_data(codec, nid, i);
- /*
- * Graphics driver might be writing to ELD buffer right now.
- * Just abort. The caller will repoll after a while.
- */
- if (!(val & AC_ELDD_ELD_VALID)) {
- snd_printd(KERN_INFO
- "HDMI: invalid ELD data byte %d\n", i);
- ret = -EINVAL;
- goto error;
- }
- val &= AC_ELDD_ELD_DATA;
- /*
- * The first byte cannot be zero. This can happen on some DVI
- * connections. Some Intel chips may also need some 250ms delay
- * to return non-zero ELD data, even when the graphics driver
- * correctly writes ELD content before setting ELD_valid bit.
- */
- if (!val && !i) {
- snd_printdd(KERN_INFO "HDMI: 0 ELD data\n");
- ret = -EINVAL;
- goto error;
- }
- buf[i] = val;
- }
-
- ret = hdmi_update_eld(eld, buf, size);
-
-error:
- return ret;
-}
-
-/**
- * SNDRV_PCM_RATE_* and AC_PAR_PCM values don't match, print correct rates with
- * hdmi-specific routine.
- */
-static void hdmi_print_pcm_rates(int pcm, char *buf, int buflen)
-{
- static unsigned int alsa_rates[] = {
- 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000,
- 88200, 96000, 176400, 192000, 384000
- };
- int i, j;
-
- for (i = 0, j = 0; i < ARRAY_SIZE(alsa_rates); i++)
- if (pcm & (1 << i))
- j += snprintf(buf + j, buflen - j, " %d",
- alsa_rates[i]);
-
- buf[j] = '\0'; /* necessary when j == 0 */
-}
-
-#define SND_PRINT_RATES_ADVISED_BUFSIZE 80
-
-static void hdmi_show_short_audio_desc(struct cea_sad *a)
-{
- char buf[SND_PRINT_RATES_ADVISED_BUFSIZE];
- char buf2[8 + SND_PRINT_BITS_ADVISED_BUFSIZE] = ", bits =";
-
- if (!a->format)
- return;
-
- hdmi_print_pcm_rates(a->rates, buf, sizeof(buf));
-
- if (a->format == AUDIO_CODING_TYPE_LPCM)
- snd_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2) - 8);
- else if (a->max_bitrate)
- snprintf(buf2, sizeof(buf2),
- ", max bitrate = %d", a->max_bitrate);
- else
- buf2[0] = '\0';
-
- _snd_printd(SND_PR_VERBOSE, "HDMI: supports coding type %s:"
- " channels = %d, rates =%s%s\n",
- cea_audio_coding_type_names[a->format],
- a->channels,
- buf,
- buf2);
-}
-
-void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen)
-{
- int i, j;
-
- for (i = 0, j = 0; i < ARRAY_SIZE(cea_speaker_allocation_names); i++) {
- if (spk_alloc & (1 << i))
- j += snprintf(buf + j, buflen - j, " %s",
- cea_speaker_allocation_names[i]);
- }
- buf[j] = '\0'; /* necessary when j == 0 */
-}
-
-void snd_hdmi_show_eld(struct hdmi_eld *e)
-{
- int i;
-
- _snd_printd(SND_PR_VERBOSE, "HDMI: detected monitor %s at connection type %s\n",
- e->monitor_name,
- eld_connection_type_names[e->conn_type]);
-
- if (e->spk_alloc) {
- char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
- snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf));
- _snd_printd(SND_PR_VERBOSE, "HDMI: available speakers:%s\n", buf);
- }
-
- for (i = 0; i < e->sad_count; i++)
- hdmi_show_short_audio_desc(e->sad + i);
-}
-
-#ifdef CONFIG_PROC_FS
-
-static void hdmi_print_sad_info(int i, struct cea_sad *a,
- struct snd_info_buffer *buffer)
-{
- char buf[SND_PRINT_RATES_ADVISED_BUFSIZE];
-
- snd_iprintf(buffer, "sad%d_coding_type\t[0x%x] %s\n",
- i, a->format, cea_audio_coding_type_names[a->format]);
- snd_iprintf(buffer, "sad%d_channels\t\t%d\n", i, a->channels);
-
- hdmi_print_pcm_rates(a->rates, buf, sizeof(buf));
- snd_iprintf(buffer, "sad%d_rates\t\t[0x%x]%s\n", i, a->rates, buf);
-
- if (a->format == AUDIO_CODING_TYPE_LPCM) {
- snd_print_pcm_bits(a->sample_bits, buf, sizeof(buf));
- snd_iprintf(buffer, "sad%d_bits\t\t[0x%x]%s\n",
- i, a->sample_bits, buf);
- }
-
- if (a->max_bitrate)
- snd_iprintf(buffer, "sad%d_max_bitrate\t%d\n",
- i, a->max_bitrate);
-
- if (a->profile)
- snd_iprintf(buffer, "sad%d_profile\t\t%d\n", i, a->profile);
-}
-
-static void hdmi_print_eld_info(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct hdmi_eld *e = entry->private_data;
- char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
- int i;
- static char *eld_versoin_names[32] = {
- "reserved",
- "reserved",
- "CEA-861D or below",
- [3 ... 30] = "reserved",
- [31] = "partial"
- };
- static char *cea_edid_version_names[8] = {
- "no CEA EDID Timing Extension block present",
- "CEA-861",
- "CEA-861-A",
- "CEA-861-B, C or D",
- [4 ... 7] = "reserved"
- };
-
- snd_iprintf(buffer, "monitor_present\t\t%d\n", e->monitor_present);
- snd_iprintf(buffer, "eld_valid\t\t%d\n", e->eld_valid);
- if (!e->eld_valid)
- return;
- snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name);
- snd_iprintf(buffer, "connection_type\t\t%s\n",
- eld_connection_type_names[e->conn_type]);
- snd_iprintf(buffer, "eld_version\t\t[0x%x] %s\n", e->eld_ver,
- eld_versoin_names[e->eld_ver]);
- snd_iprintf(buffer, "edid_version\t\t[0x%x] %s\n", e->cea_edid_ver,
- cea_edid_version_names[e->cea_edid_ver]);
- snd_iprintf(buffer, "manufacture_id\t\t0x%x\n", e->manufacture_id);
- snd_iprintf(buffer, "product_id\t\t0x%x\n", e->product_id);
- snd_iprintf(buffer, "port_id\t\t\t0x%llx\n", (long long)e->port_id);
- snd_iprintf(buffer, "support_hdcp\t\t%d\n", e->support_hdcp);
- snd_iprintf(buffer, "support_ai\t\t%d\n", e->support_ai);
- snd_iprintf(buffer, "audio_sync_delay\t%d\n", e->aud_synch_delay);
-
- snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf));
- snd_iprintf(buffer, "speakers\t\t[0x%x]%s\n", e->spk_alloc, buf);
-
- snd_iprintf(buffer, "sad_count\t\t%d\n", e->sad_count);
-
- for (i = 0; i < e->sad_count; i++)
- hdmi_print_sad_info(i, e->sad + i, buffer);
-}
-
-static void hdmi_write_eld_info(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct hdmi_eld *e = entry->private_data;
- char line[64];
- char name[64];
- char *sname;
- long long val;
- unsigned int n;
-
- while (!snd_info_get_line(buffer, line, sizeof(line))) {
- if (sscanf(line, "%s %llx", name, &val) != 2)
- continue;
- /*
- * We don't allow modification to these fields:
- * monitor_name manufacture_id product_id
- * eld_version edid_version
- */
- if (!strcmp(name, "monitor_present"))
- e->monitor_present = val;
- else if (!strcmp(name, "eld_valid"))
- e->eld_valid = val;
- else if (!strcmp(name, "connection_type"))
- e->conn_type = val;
- else if (!strcmp(name, "port_id"))
- e->port_id = val;
- else if (!strcmp(name, "support_hdcp"))
- e->support_hdcp = val;
- else if (!strcmp(name, "support_ai"))
- e->support_ai = val;
- else if (!strcmp(name, "audio_sync_delay"))
- e->aud_synch_delay = val;
- else if (!strcmp(name, "speakers"))
- e->spk_alloc = val;
- else if (!strcmp(name, "sad_count"))
- e->sad_count = val;
- else if (!strncmp(name, "sad", 3)) {
- sname = name + 4;
- n = name[3] - '0';
- if (name[4] >= '0' && name[4] <= '9') {
- sname++;
- n = 10 * n + name[4] - '0';
- }
- if (n >= ELD_MAX_SAD)
- continue;
- if (!strcmp(sname, "_coding_type"))
- e->sad[n].format = val;
- else if (!strcmp(sname, "_channels"))
- e->sad[n].channels = val;
- else if (!strcmp(sname, "_rates"))
- e->sad[n].rates = val;
- else if (!strcmp(sname, "_bits"))
- e->sad[n].sample_bits = val;
- else if (!strcmp(sname, "_max_bitrate"))
- e->sad[n].max_bitrate = val;
- else if (!strcmp(sname, "_profile"))
- e->sad[n].profile = val;
- if (n >= e->sad_count)
- e->sad_count = n + 1;
- }
- }
-}
-
-
-int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld,
- int index)
-{
- char name[32];
- struct snd_info_entry *entry;
- int err;
-
- snprintf(name, sizeof(name), "eld#%d.%d", codec->addr, index);
- err = snd_card_proc_new(codec->bus->card, name, &entry);
- if (err < 0)
- return err;
-
- snd_info_set_text_ops(entry, eld, hdmi_print_eld_info);
- entry->c.text.write = hdmi_write_eld_info;
- entry->mode |= S_IWUSR;
- eld->proc_entry = entry;
-
- return 0;
-}
-
-void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
-{
- if (!codec->bus->shutdown && eld->proc_entry) {
- snd_device_free(codec->bus->card, eld->proc_entry);
- eld->proc_entry = NULL;
- }
-}
-
-#endif /* CONFIG_PROC_FS */
-
-/* update PCM info based on ELD */
-void snd_hdmi_eld_update_pcm_info(struct hdmi_eld *eld,
- struct hda_pcm_stream *hinfo)
-{
- u32 rates;
- u64 formats;
- unsigned int maxbps;
- unsigned int channels_max;
- int i;
-
- /* assume basic audio support (the basic audio flag is not in ELD;
- * however, all audio capable sinks are required to support basic
- * audio) */
- rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000;
- formats = SNDRV_PCM_FMTBIT_S16_LE;
- maxbps = 16;
- channels_max = 2;
- for (i = 0; i < eld->sad_count; i++) {
- struct cea_sad *a = &eld->sad[i];
- rates |= a->rates;
- if (a->channels > channels_max)
- channels_max = a->channels;
- if (a->format == AUDIO_CODING_TYPE_LPCM) {
- if (a->sample_bits & AC_SUPPCM_BITS_20) {
- formats |= SNDRV_PCM_FMTBIT_S32_LE;
- if (maxbps < 20)
- maxbps = 20;
- }
- if (a->sample_bits & AC_SUPPCM_BITS_24) {
- formats |= SNDRV_PCM_FMTBIT_S32_LE;
- if (maxbps < 24)
- maxbps = 24;
- }
- }
- }
-
- /* restrict the parameters by the values the codec provides */
- hinfo->rates &= rates;
- hinfo->formats &= formats;
- hinfo->maxbps = min(hinfo->maxbps, maxbps);
- hinfo->channels_max = min(hinfo->channels_max, channels_max);
-}
diff --git a/ANDROID_3.4.5/sound/pci/hda/hda_generic.c b/ANDROID_3.4.5/sound/pci/hda/hda_generic.c
deleted file mode 100644
index 431bf868..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/hda_generic.c
+++ /dev/null
@@ -1,1085 +0,0 @@
-/*
- * Universal Interface for Intel High Definition Audio Codec
- *
- * Generic widget tree parser
- *
- * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/export.h>
-#include <sound/core.h>
-#include "hda_codec.h"
-#include "hda_local.h"
-
-/* widget node for parsing */
-struct hda_gnode {
- hda_nid_t nid; /* NID of this widget */
- unsigned short nconns; /* number of input connections */
- hda_nid_t *conn_list;
- hda_nid_t slist[2]; /* temporay list */
- unsigned int wid_caps; /* widget capabilities */
- unsigned char type; /* widget type */
- unsigned char pin_ctl; /* pin controls */
- unsigned char checked; /* the flag indicates that the node is already parsed */
- unsigned int pin_caps; /* pin widget capabilities */
- unsigned int def_cfg; /* default configuration */
- unsigned int amp_out_caps; /* AMP out capabilities */
- unsigned int amp_in_caps; /* AMP in capabilities */
- struct list_head list;
-};
-
-/* patch-specific record */
-
-#define MAX_PCM_VOLS 2
-struct pcm_vol {
- struct hda_gnode *node; /* Node for PCM volume */
- unsigned int index; /* connection of PCM volume */
-};
-
-struct hda_gspec {
- struct hda_gnode *dac_node[2]; /* DAC node */
- struct hda_gnode *out_pin_node[2]; /* Output pin (Line-Out) node */
- struct pcm_vol pcm_vol[MAX_PCM_VOLS]; /* PCM volumes */
- unsigned int pcm_vol_nodes; /* number of PCM volumes */
-
- struct hda_gnode *adc_node; /* ADC node */
- struct hda_gnode *cap_vol_node; /* Node for capture volume */
- unsigned int cur_cap_src; /* current capture source */
- struct hda_input_mux input_mux;
-
- unsigned int def_amp_in_caps;
- unsigned int def_amp_out_caps;
-
- struct hda_pcm pcm_rec; /* PCM information */
-
- struct list_head nid_list; /* list of widgets */
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-#define MAX_LOOPBACK_AMPS 7
- struct hda_loopback_check loopback;
- int num_loopbacks;
- struct hda_amp_list loopback_list[MAX_LOOPBACK_AMPS + 1];
-#endif
-};
-
-/*
- * retrieve the default device type from the default config value
- */
-#define defcfg_type(node) (((node)->def_cfg & AC_DEFCFG_DEVICE) >> \
- AC_DEFCFG_DEVICE_SHIFT)
-#define defcfg_location(node) (((node)->def_cfg & AC_DEFCFG_LOCATION) >> \
- AC_DEFCFG_LOCATION_SHIFT)
-#define defcfg_port_conn(node) (((node)->def_cfg & AC_DEFCFG_PORT_CONN) >> \
- AC_DEFCFG_PORT_CONN_SHIFT)
-
-/*
- * destructor
- */
-static void snd_hda_generic_free(struct hda_codec *codec)
-{
- struct hda_gspec *spec = codec->spec;
- struct hda_gnode *node, *n;
-
- if (! spec)
- return;
- /* free all widgets */
- list_for_each_entry_safe(node, n, &spec->nid_list, list) {
- if (node->conn_list != node->slist)
- kfree(node->conn_list);
- kfree(node);
- }
- kfree(spec);
-}
-
-
-/*
- * add a new widget node and read its attributes
- */
-static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid_t nid)
-{
- struct hda_gnode *node;
- int nconns;
- hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
-
- node = kzalloc(sizeof(*node), GFP_KERNEL);
- if (node == NULL)
- return -ENOMEM;
- node->nid = nid;
- node->wid_caps = get_wcaps(codec, nid);
- node->type = get_wcaps_type(node->wid_caps);
- if (node->wid_caps & AC_WCAP_CONN_LIST) {
- nconns = snd_hda_get_connections(codec, nid, conn_list,
- HDA_MAX_CONNECTIONS);
- if (nconns < 0) {
- kfree(node);
- return nconns;
- }
- } else {
- nconns = 0;
- }
- if (nconns <= ARRAY_SIZE(node->slist))
- node->conn_list = node->slist;
- else {
- node->conn_list = kmalloc(sizeof(hda_nid_t) * nconns,
- GFP_KERNEL);
- if (! node->conn_list) {
- snd_printk(KERN_ERR "hda-generic: cannot malloc\n");
- kfree(node);
- return -ENOMEM;
- }
- }
- memcpy(node->conn_list, conn_list, nconns * sizeof(hda_nid_t));
- node->nconns = nconns;
-
- if (node->type == AC_WID_PIN) {
- node->pin_caps = snd_hda_query_pin_caps(codec, node->nid);
- node->pin_ctl = snd_hda_codec_read(codec, node->nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
- node->def_cfg = snd_hda_codec_get_pincfg(codec, node->nid);
- }
-
- if (node->wid_caps & AC_WCAP_OUT_AMP) {
- if (node->wid_caps & AC_WCAP_AMP_OVRD)
- node->amp_out_caps = snd_hda_param_read(codec, node->nid, AC_PAR_AMP_OUT_CAP);
- if (! node->amp_out_caps)
- node->amp_out_caps = spec->def_amp_out_caps;
- }
- if (node->wid_caps & AC_WCAP_IN_AMP) {
- if (node->wid_caps & AC_WCAP_AMP_OVRD)
- node->amp_in_caps = snd_hda_param_read(codec, node->nid, AC_PAR_AMP_IN_CAP);
- if (! node->amp_in_caps)
- node->amp_in_caps = spec->def_amp_in_caps;
- }
- list_add_tail(&node->list, &spec->nid_list);
- return 0;
-}
-
-/*
- * build the AFG subtree
- */
-static int build_afg_tree(struct hda_codec *codec)
-{
- struct hda_gspec *spec = codec->spec;
- int i, nodes, err;
- hda_nid_t nid;
-
- if (snd_BUG_ON(!spec))
- return -EINVAL;
-
- spec->def_amp_out_caps = snd_hda_param_read(codec, codec->afg, AC_PAR_AMP_OUT_CAP);
- spec->def_amp_in_caps = snd_hda_param_read(codec, codec->afg, AC_PAR_AMP_IN_CAP);
-
- nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
- if (! nid || nodes < 0) {
- printk(KERN_ERR "Invalid AFG subtree\n");
- return -EINVAL;
- }
-
- /* parse all nodes belonging to the AFG */
- for (i = 0; i < nodes; i++, nid++) {
- if ((err = add_new_node(codec, spec, nid)) < 0)
- return err;
- }
-
- return 0;
-}
-
-
-/*
- * look for the node record for the given NID
- */
-/* FIXME: should avoid the braindead linear search */
-static struct hda_gnode *hda_get_node(struct hda_gspec *spec, hda_nid_t nid)
-{
- struct hda_gnode *node;
-
- list_for_each_entry(node, &spec->nid_list, list) {
- if (node->nid == nid)
- return node;
- }
- return NULL;
-}
-
-/*
- * unmute (and set max vol) the output amplifier
- */
-static int unmute_output(struct hda_codec *codec, struct hda_gnode *node)
-{
- unsigned int val, ofs;
- snd_printdd("UNMUTE OUT: NID=0x%x\n", node->nid);
- val = (node->amp_out_caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
- ofs = (node->amp_out_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
- if (val >= ofs)
- val -= ofs;
- snd_hda_codec_amp_stereo(codec, node->nid, HDA_OUTPUT, 0, 0xff, val);
- return 0;
-}
-
-/*
- * unmute (and set max vol) the input amplifier
- */
-static int unmute_input(struct hda_codec *codec, struct hda_gnode *node, unsigned int index)
-{
- unsigned int val, ofs;
- snd_printdd("UNMUTE IN: NID=0x%x IDX=0x%x\n", node->nid, index);
- val = (node->amp_in_caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
- ofs = (node->amp_in_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
- if (val >= ofs)
- val -= ofs;
- snd_hda_codec_amp_stereo(codec, node->nid, HDA_INPUT, index, 0xff, val);
- return 0;
-}
-
-/*
- * select the input connection of the given node.
- */
-static int select_input_connection(struct hda_codec *codec, struct hda_gnode *node,
- unsigned int index)
-{
- snd_printdd("CONNECT: NID=0x%x IDX=0x%x\n", node->nid, index);
- return snd_hda_codec_write_cache(codec, node->nid, 0,
- AC_VERB_SET_CONNECT_SEL, index);
-}
-
-/*
- * clear checked flag of each node in the node list
- */
-static void clear_check_flags(struct hda_gspec *spec)
-{
- struct hda_gnode *node;
-
- list_for_each_entry(node, &spec->nid_list, list) {
- node->checked = 0;
- }
-}
-
-/*
- * parse the output path recursively until reach to an audio output widget
- *
- * returns 0 if not found, 1 if found, or a negative error code.
- */
-static int parse_output_path(struct hda_codec *codec, struct hda_gspec *spec,
- struct hda_gnode *node, int dac_idx)
-{
- int i, err;
- struct hda_gnode *child;
-
- if (node->checked)
- return 0;
-
- node->checked = 1;
- if (node->type == AC_WID_AUD_OUT) {
- if (node->wid_caps & AC_WCAP_DIGITAL) {
- snd_printdd("Skip Digital OUT node %x\n", node->nid);
- return 0;
- }
- snd_printdd("AUD_OUT found %x\n", node->nid);
- if (spec->dac_node[dac_idx]) {
- /* already DAC node is assigned, just unmute & connect */
- return node == spec->dac_node[dac_idx];
- }
- spec->dac_node[dac_idx] = node;
- if ((node->wid_caps & AC_WCAP_OUT_AMP) &&
- spec->pcm_vol_nodes < MAX_PCM_VOLS) {
- spec->pcm_vol[spec->pcm_vol_nodes].node = node;
- spec->pcm_vol[spec->pcm_vol_nodes].index = 0;
- spec->pcm_vol_nodes++;
- }
- return 1; /* found */
- }
-
- for (i = 0; i < node->nconns; i++) {
- child = hda_get_node(spec, node->conn_list[i]);
- if (! child)
- continue;
- err = parse_output_path(codec, spec, child, dac_idx);
- if (err < 0)
- return err;
- else if (err > 0) {
- /* found one,
- * select the path, unmute both input and output
- */
- if (node->nconns > 1)
- select_input_connection(codec, node, i);
- unmute_input(codec, node, i);
- unmute_output(codec, node);
- if (spec->dac_node[dac_idx] &&
- spec->pcm_vol_nodes < MAX_PCM_VOLS &&
- !(spec->dac_node[dac_idx]->wid_caps &
- AC_WCAP_OUT_AMP)) {
- if ((node->wid_caps & AC_WCAP_IN_AMP) ||
- (node->wid_caps & AC_WCAP_OUT_AMP)) {
- int n = spec->pcm_vol_nodes;
- spec->pcm_vol[n].node = node;
- spec->pcm_vol[n].index = i;
- spec->pcm_vol_nodes++;
- }
- }
- return 1;
- }
- }
- return 0;
-}
-
-/*
- * Look for the output PIN widget with the given jack type
- * and parse the output path to that PIN.
- *
- * Returns the PIN node when the path to DAC is established.
- */
-static struct hda_gnode *parse_output_jack(struct hda_codec *codec,
- struct hda_gspec *spec,
- int jack_type)
-{
- struct hda_gnode *node;
- int err;
-
- list_for_each_entry(node, &spec->nid_list, list) {
- if (node->type != AC_WID_PIN)
- continue;
- /* output capable? */
- if (! (node->pin_caps & AC_PINCAP_OUT))
- continue;
- if (defcfg_port_conn(node) == AC_JACK_PORT_NONE)
- continue; /* unconnected */
- if (jack_type >= 0) {
- if (jack_type != defcfg_type(node))
- continue;
- if (node->wid_caps & AC_WCAP_DIGITAL)
- continue; /* skip SPDIF */
- } else {
- /* output as default? */
- if (! (node->pin_ctl & AC_PINCTL_OUT_EN))
- continue;
- }
- clear_check_flags(spec);
- err = parse_output_path(codec, spec, node, 0);
- if (err < 0)
- return NULL;
- if (! err && spec->out_pin_node[0]) {
- err = parse_output_path(codec, spec, node, 1);
- if (err < 0)
- return NULL;
- }
- if (err > 0) {
- /* unmute the PIN output */
- unmute_output(codec, node);
- /* set PIN-Out enable */
- snd_hda_codec_write_cache(codec, node->nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- AC_PINCTL_OUT_EN |
- ((node->pin_caps & AC_PINCAP_HP_DRV) ?
- AC_PINCTL_HP_EN : 0));
- return node;
- }
- }
- return NULL;
-}
-
-
-/*
- * parse outputs
- */
-static int parse_output(struct hda_codec *codec)
-{
- struct hda_gspec *spec = codec->spec;
- struct hda_gnode *node;
-
- /*
- * Look for the output PIN widget
- */
- /* first, look for the line-out pin */
- node = parse_output_jack(codec, spec, AC_JACK_LINE_OUT);
- if (node) /* found, remember the PIN node */
- spec->out_pin_node[0] = node;
- else {
- /* if no line-out is found, try speaker out */
- node = parse_output_jack(codec, spec, AC_JACK_SPEAKER);
- if (node)
- spec->out_pin_node[0] = node;
- }
- /* look for the HP-out pin */
- node = parse_output_jack(codec, spec, AC_JACK_HP_OUT);
- if (node) {
- if (! spec->out_pin_node[0])
- spec->out_pin_node[0] = node;
- else
- spec->out_pin_node[1] = node;
- }
-
- if (! spec->out_pin_node[0]) {
- /* no line-out or HP pins found,
- * then choose for the first output pin
- */
- spec->out_pin_node[0] = parse_output_jack(codec, spec, -1);
- if (! spec->out_pin_node[0])
- snd_printd("hda_generic: no proper output path found\n");
- }
-
- return 0;
-}
-
-/*
- * input MUX
- */
-
-/* control callbacks */
-static int capture_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct hda_gspec *spec = codec->spec;
- return snd_hda_input_mux_info(&spec->input_mux, uinfo);
-}
-
-static int capture_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct hda_gspec *spec = codec->spec;
-
- ucontrol->value.enumerated.item[0] = spec->cur_cap_src;
- return 0;
-}
-
-static int capture_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct hda_gspec *spec = codec->spec;
- return snd_hda_input_mux_put(codec, &spec->input_mux, ucontrol,
- spec->adc_node->nid, &spec->cur_cap_src);
-}
-
-/*
- * return the string name of the given input PIN widget
- */
-static const char *get_input_type(struct hda_gnode *node, unsigned int *pinctl)
-{
- unsigned int location = defcfg_location(node);
- switch (defcfg_type(node)) {
- case AC_JACK_LINE_IN:
- if ((location & 0x0f) == AC_JACK_LOC_FRONT)
- return "Front Line";
- return "Line";
- case AC_JACK_CD:
-#if 0
- if (pinctl)
- *pinctl |= AC_PINCTL_VREF_GRD;
-#endif
- return "CD";
- case AC_JACK_AUX:
- if ((location & 0x0f) == AC_JACK_LOC_FRONT)
- return "Front Aux";
- return "Aux";
- case AC_JACK_MIC_IN:
- if (pinctl &&
- (node->pin_caps &
- (AC_PINCAP_VREF_80 << AC_PINCAP_VREF_SHIFT)))
- *pinctl |= AC_PINCTL_VREF_80;
- if ((location & 0x0f) == AC_JACK_LOC_FRONT)
- return "Front Mic";
- return "Mic";
- case AC_JACK_SPDIF_IN:
- return "SPDIF";
- case AC_JACK_DIG_OTHER_IN:
- return "Digital";
- }
- return NULL;
-}
-
-/*
- * parse the nodes recursively until reach to the input PIN
- *
- * returns 0 if not found, 1 if found, or a negative error code.
- */
-static int parse_adc_sub_nodes(struct hda_codec *codec, struct hda_gspec *spec,
- struct hda_gnode *node, int idx)
-{
- int i, err;
- unsigned int pinctl;
- const char *type;
-
- if (node->checked)
- return 0;
-
- node->checked = 1;
- if (node->type != AC_WID_PIN) {
- for (i = 0; i < node->nconns; i++) {
- struct hda_gnode *child;
- child = hda_get_node(spec, node->conn_list[i]);
- if (! child)
- continue;
- err = parse_adc_sub_nodes(codec, spec, child, idx);
- if (err < 0)
- return err;
- if (err > 0) {
- /* found one,
- * select the path, unmute both input and output
- */
- if (node->nconns > 1)
- select_input_connection(codec, node, i);
- unmute_input(codec, node, i);
- unmute_output(codec, node);
- return err;
- }
- }
- return 0;
- }
-
- /* input capable? */
- if (! (node->pin_caps & AC_PINCAP_IN))
- return 0;
-
- if (defcfg_port_conn(node) == AC_JACK_PORT_NONE)
- return 0; /* unconnected */
-
- if (node->wid_caps & AC_WCAP_DIGITAL)
- return 0; /* skip SPDIF */
-
- if (spec->input_mux.num_items >= HDA_MAX_NUM_INPUTS) {
- snd_printk(KERN_ERR "hda_generic: Too many items for capture\n");
- return -EINVAL;
- }
-
- pinctl = AC_PINCTL_IN_EN;
- /* create a proper capture source label */
- type = get_input_type(node, &pinctl);
- if (! type) {
- /* input as default? */
- if (! (node->pin_ctl & AC_PINCTL_IN_EN))
- return 0;
- type = "Input";
- }
- snd_hda_add_imux_item(&spec->input_mux, type, idx, NULL);
-
- /* unmute the PIN external input */
- unmute_input(codec, node, 0); /* index = 0? */
- /* set PIN-In enable */
- snd_hda_codec_write_cache(codec, node->nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
-
- return 1; /* found */
-}
-
-/*
- * parse input
- */
-static int parse_input_path(struct hda_codec *codec, struct hda_gnode *adc_node)
-{
- struct hda_gspec *spec = codec->spec;
- struct hda_gnode *node;
- int i, err;
-
- snd_printdd("AUD_IN = %x\n", adc_node->nid);
- clear_check_flags(spec);
-
- // awk added - fixed no recording due to muted widget
- unmute_input(codec, adc_node, 0);
-
- /*
- * check each connection of the ADC
- * if it reaches to a proper input PIN, add the path as the
- * input path.
- */
- /* first, check the direct connections to PIN widgets */
- for (i = 0; i < adc_node->nconns; i++) {
- node = hda_get_node(spec, adc_node->conn_list[i]);
- if (node && node->type == AC_WID_PIN) {
- err = parse_adc_sub_nodes(codec, spec, node, i);
- if (err < 0)
- return err;
- }
- }
- /* ... then check the rests, more complicated connections */
- for (i = 0; i < adc_node->nconns; i++) {
- node = hda_get_node(spec, adc_node->conn_list[i]);
- if (node && node->type != AC_WID_PIN) {
- err = parse_adc_sub_nodes(codec, spec, node, i);
- if (err < 0)
- return err;
- }
- }
-
- if (! spec->input_mux.num_items)
- return 0; /* no input path found... */
-
- snd_printdd("[Capture Source] NID=0x%x, #SRC=%d\n", adc_node->nid, spec->input_mux.num_items);
- for (i = 0; i < spec->input_mux.num_items; i++)
- snd_printdd(" [%s] IDX=0x%x\n", spec->input_mux.items[i].label,
- spec->input_mux.items[i].index);
-
- spec->adc_node = adc_node;
- return 1;
-}
-
-/*
- * parse input
- */
-static int parse_input(struct hda_codec *codec)
-{
- struct hda_gspec *spec = codec->spec;
- struct hda_gnode *node;
- int err;
-
- /*
- * At first we look for an audio input widget.
- * If it reaches to certain input PINs, we take it as the
- * input path.
- */
- list_for_each_entry(node, &spec->nid_list, list) {
- if (node->wid_caps & AC_WCAP_DIGITAL)
- continue; /* skip SPDIF */
- if (node->type == AC_WID_AUD_IN) {
- err = parse_input_path(codec, node);
- if (err < 0)
- return err;
- else if (err > 0)
- return 0;
- }
- }
- snd_printd("hda_generic: no proper input path found\n");
- return 0;
-}
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static void add_input_loopback(struct hda_codec *codec, hda_nid_t nid,
- int dir, int idx)
-{
- struct hda_gspec *spec = codec->spec;
- struct hda_amp_list *p;
-
- if (spec->num_loopbacks >= MAX_LOOPBACK_AMPS) {
- snd_printk(KERN_ERR "hda_generic: Too many loopback ctls\n");
- return;
- }
- p = &spec->loopback_list[spec->num_loopbacks++];
- p->nid = nid;
- p->dir = dir;
- p->idx = idx;
- spec->loopback.amplist = spec->loopback_list;
-}
-#else
-#define add_input_loopback(codec,nid,dir,idx)
-#endif
-
-/*
- * create mixer controls if possible
- */
-static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
- unsigned int index, const char *type,
- const char *dir_sfx, int is_loopback)
-{
- char name[32];
- int err;
- int created = 0;
- struct snd_kcontrol_new knew;
-
- if (type)
- sprintf(name, "%s %s Switch", type, dir_sfx);
- else
- sprintf(name, "%s Switch", dir_sfx);
- if ((node->wid_caps & AC_WCAP_IN_AMP) &&
- (node->amp_in_caps & AC_AMPCAP_MUTE)) {
- knew = (struct snd_kcontrol_new)HDA_CODEC_MUTE(name, node->nid, index, HDA_INPUT);
- if (is_loopback)
- add_input_loopback(codec, node->nid, HDA_INPUT, index);
- snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index);
- err = snd_hda_ctl_add(codec, node->nid,
- snd_ctl_new1(&knew, codec));
- if (err < 0)
- return err;
- created = 1;
- } else if ((node->wid_caps & AC_WCAP_OUT_AMP) &&
- (node->amp_out_caps & AC_AMPCAP_MUTE)) {
- knew = (struct snd_kcontrol_new)HDA_CODEC_MUTE(name, node->nid, 0, HDA_OUTPUT);
- if (is_loopback)
- add_input_loopback(codec, node->nid, HDA_OUTPUT, 0);
- snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid);
- err = snd_hda_ctl_add(codec, node->nid,
- snd_ctl_new1(&knew, codec));
- if (err < 0)
- return err;
- created = 1;
- }
-
- if (type)
- sprintf(name, "%s %s Volume", type, dir_sfx);
- else
- sprintf(name, "%s Volume", dir_sfx);
- if ((node->wid_caps & AC_WCAP_IN_AMP) &&
- (node->amp_in_caps & AC_AMPCAP_NUM_STEPS)) {
- knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, index, HDA_INPUT);
- snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index);
- err = snd_hda_ctl_add(codec, node->nid,
- snd_ctl_new1(&knew, codec));
- if (err < 0)
- return err;
- created = 1;
- } else if ((node->wid_caps & AC_WCAP_OUT_AMP) &&
- (node->amp_out_caps & AC_AMPCAP_NUM_STEPS)) {
- knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, 0, HDA_OUTPUT);
- snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid);
- err = snd_hda_ctl_add(codec, node->nid,
- snd_ctl_new1(&knew, codec));
- if (err < 0)
- return err;
- created = 1;
- }
-
- return created;
-}
-
-/*
- * check whether the controls with the given name and direction suffix already exist
- */
-static int check_existing_control(struct hda_codec *codec, const char *type, const char *dir)
-{
- struct snd_ctl_elem_id id;
- memset(&id, 0, sizeof(id));
- sprintf(id.name, "%s %s Volume", type, dir);
- id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- if (snd_ctl_find_id(codec->bus->card, &id))
- return 1;
- sprintf(id.name, "%s %s Switch", type, dir);
- id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- if (snd_ctl_find_id(codec->bus->card, &id))
- return 1;
- return 0;
-}
-
-/*
- * build output mixer controls
- */
-static int create_output_mixers(struct hda_codec *codec,
- const char * const *names)
-{
- struct hda_gspec *spec = codec->spec;
- int i, err;
-
- for (i = 0; i < spec->pcm_vol_nodes; i++) {
- err = create_mixer(codec, spec->pcm_vol[i].node,
- spec->pcm_vol[i].index,
- names[i], "Playback", 0);
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-static int build_output_controls(struct hda_codec *codec)
-{
- struct hda_gspec *spec = codec->spec;
- static const char * const types_speaker[] = { "Speaker", "Headphone" };
- static const char * const types_line[] = { "Front", "Headphone" };
-
- switch (spec->pcm_vol_nodes) {
- case 1:
- return create_mixer(codec, spec->pcm_vol[0].node,
- spec->pcm_vol[0].index,
- "Master", "Playback", 0);
- case 2:
- if (defcfg_type(spec->out_pin_node[0]) == AC_JACK_SPEAKER)
- return create_output_mixers(codec, types_speaker);
- else
- return create_output_mixers(codec, types_line);
- }
- return 0;
-}
-
-/* create capture volume/switch */
-static int build_input_controls(struct hda_codec *codec)
-{
- struct hda_gspec *spec = codec->spec;
- struct hda_gnode *adc_node = spec->adc_node;
- int i, err;
- static struct snd_kcontrol_new cap_sel = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = capture_source_info,
- .get = capture_source_get,
- .put = capture_source_put,
- };
-
- if (! adc_node || ! spec->input_mux.num_items)
- return 0; /* not found */
-
- spec->cur_cap_src = 0;
- select_input_connection(codec, adc_node,
- spec->input_mux.items[0].index);
-
- /* create capture volume and switch controls if the ADC has an amp */
- /* do we have only a single item? */
- if (spec->input_mux.num_items == 1) {
- err = create_mixer(codec, adc_node,
- spec->input_mux.items[0].index,
- NULL, "Capture", 0);
- if (err < 0)
- return err;
- return 0;
- }
-
- /* create input MUX if multiple sources are available */
- err = snd_hda_ctl_add(codec, spec->adc_node->nid,
- snd_ctl_new1(&cap_sel, codec));
- if (err < 0)
- return err;
-
- /* no volume control? */
- if (! (adc_node->wid_caps & AC_WCAP_IN_AMP) ||
- ! (adc_node->amp_in_caps & AC_AMPCAP_NUM_STEPS))
- return 0;
-
- for (i = 0; i < spec->input_mux.num_items; i++) {
- struct snd_kcontrol_new knew;
- char name[32];
- sprintf(name, "%s Capture Volume",
- spec->input_mux.items[i].label);
- knew = (struct snd_kcontrol_new)
- HDA_CODEC_VOLUME(name, adc_node->nid,
- spec->input_mux.items[i].index,
- HDA_INPUT);
- err = snd_hda_ctl_add(codec, adc_node->nid,
- snd_ctl_new1(&knew, codec));
- if (err < 0)
- return err;
- }
-
- return 0;
-}
-
-
-/*
- * parse the nodes recursively until reach to the output PIN.
- *
- * returns 0 - if not found,
- * 1 - if found, but no mixer is created
- * 2 - if found and mixer was already created, (just skip)
- * a negative error code
- */
-static int parse_loopback_path(struct hda_codec *codec, struct hda_gspec *spec,
- struct hda_gnode *node, struct hda_gnode *dest_node,
- const char *type)
-{
- int i, err;
-
- if (node->checked)
- return 0;
-
- node->checked = 1;
- if (node == dest_node) {
- /* loopback connection found */
- return 1;
- }
-
- for (i = 0; i < node->nconns; i++) {
- struct hda_gnode *child = hda_get_node(spec, node->conn_list[i]);
- if (! child)
- continue;
- err = parse_loopback_path(codec, spec, child, dest_node, type);
- if (err < 0)
- return err;
- else if (err >= 1) {
- if (err == 1) {
- err = create_mixer(codec, node, i, type,
- "Playback", 1);
- if (err < 0)
- return err;
- if (err > 0)
- return 2; /* ok, created */
- /* not created, maybe in the lower path */
- err = 1;
- }
- /* connect and unmute */
- if (node->nconns > 1)
- select_input_connection(codec, node, i);
- unmute_input(codec, node, i);
- unmute_output(codec, node);
- return err;
- }
- }
- return 0;
-}
-
-/*
- * parse the tree and build the loopback controls
- */
-static int build_loopback_controls(struct hda_codec *codec)
-{
- struct hda_gspec *spec = codec->spec;
- struct hda_gnode *node;
- int err;
- const char *type;
-
- if (! spec->out_pin_node[0])
- return 0;
-
- list_for_each_entry(node, &spec->nid_list, list) {
- if (node->type != AC_WID_PIN)
- continue;
- /* input capable? */
- if (! (node->pin_caps & AC_PINCAP_IN))
- return 0;
- type = get_input_type(node, NULL);
- if (type) {
- if (check_existing_control(codec, type, "Playback"))
- continue;
- clear_check_flags(spec);
- err = parse_loopback_path(codec, spec,
- spec->out_pin_node[0],
- node, type);
- if (err < 0)
- return err;
- if (! err)
- continue;
- }
- }
- return 0;
-}
-
-/*
- * build mixer controls
- */
-static int build_generic_controls(struct hda_codec *codec)
-{
- int err;
-
- if ((err = build_input_controls(codec)) < 0 ||
- (err = build_output_controls(codec)) < 0 ||
- (err = build_loopback_controls(codec)) < 0)
- return err;
-
- return 0;
-}
-
-/*
- * PCM
- */
-static struct hda_pcm_stream generic_pcm_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
-};
-
-static int generic_pcm2_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct hda_gspec *spec = codec->spec;
-
- snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format);
- snd_hda_codec_setup_stream(codec, spec->dac_node[1]->nid,
- stream_tag, 0, format);
- return 0;
-}
-
-static int generic_pcm2_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct hda_gspec *spec = codec->spec;
-
- snd_hda_codec_cleanup_stream(codec, hinfo->nid);
- snd_hda_codec_cleanup_stream(codec, spec->dac_node[1]->nid);
- return 0;
-}
-
-static int build_generic_pcms(struct hda_codec *codec)
-{
- struct hda_gspec *spec = codec->spec;
- struct hda_pcm *info = &spec->pcm_rec;
-
- if (! spec->dac_node[0] && ! spec->adc_node) {
- snd_printd("hda_generic: no PCM found\n");
- return 0;
- }
-
- codec->num_pcms = 1;
- codec->pcm_info = info;
-
- info->name = "HDA Generic";
- if (spec->dac_node[0]) {
- info->stream[0] = generic_pcm_playback;
- info->stream[0].nid = spec->dac_node[0]->nid;
- if (spec->dac_node[1]) {
- info->stream[0].ops.prepare = generic_pcm2_prepare;
- info->stream[0].ops.cleanup = generic_pcm2_cleanup;
- }
- }
- if (spec->adc_node) {
- info->stream[1] = generic_pcm_playback;
- info->stream[1].nid = spec->adc_node->nid;
- }
-
- return 0;
-}
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static int generic_check_power_status(struct hda_codec *codec, hda_nid_t nid)
-{
- struct hda_gspec *spec = codec->spec;
- return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
-}
-#endif
-
-
-/*
- */
-static struct hda_codec_ops generic_patch_ops = {
- .build_controls = build_generic_controls,
- .build_pcms = build_generic_pcms,
- .free = snd_hda_generic_free,
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- .check_power_status = generic_check_power_status,
-#endif
-};
-
-/*
- * the generic parser
- */
-int snd_hda_parse_generic_codec(struct hda_codec *codec)
-{
- struct hda_gspec *spec;
- int err;
-
- if(!codec->afg)
- return 0;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL) {
- printk(KERN_ERR "hda_generic: can't allocate spec\n");
- return -ENOMEM;
- }
- codec->spec = spec;
- INIT_LIST_HEAD(&spec->nid_list);
-
- if ((err = build_afg_tree(codec)) < 0)
- goto error;
-
- if ((err = parse_input(codec)) < 0 ||
- (err = parse_output(codec)) < 0)
- goto error;
-
- codec->patch_ops = generic_patch_ops;
-
- return 0;
-
- error:
- snd_hda_generic_free(codec);
- return err;
-}
-EXPORT_SYMBOL(snd_hda_parse_generic_codec);
diff --git a/ANDROID_3.4.5/sound/pci/hda/hda_hwdep.c b/ANDROID_3.4.5/sound/pci/hda/hda_hwdep.c
deleted file mode 100644
index 6b2efb8c..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/hda_hwdep.c
+++ /dev/null
@@ -1,817 +0,0 @@
-/*
- * HWDEP Interface for HD-audio codec
- *
- * Copyright (c) 2007 Takashi Iwai <tiwai@suse.de>
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/compat.h>
-#include <linux/mutex.h>
-#include <linux/ctype.h>
-#include <linux/string.h>
-#include <linux/firmware.h>
-#include <linux/export.h>
-#include <sound/core.h>
-#include "hda_codec.h"
-#include "hda_local.h"
-#include <sound/hda_hwdep.h>
-#include <sound/minors.h>
-
-/* hint string pair */
-struct hda_hint {
- const char *key;
- const char *val; /* contained in the same alloc as key */
-};
-
-/*
- * write/read an out-of-bound verb
- */
-static int verb_write_ioctl(struct hda_codec *codec,
- struct hda_verb_ioctl __user *arg)
-{
- u32 verb, res;
-
- if (get_user(verb, &arg->verb))
- return -EFAULT;
- res = snd_hda_codec_read(codec, verb >> 24, 0,
- (verb >> 8) & 0xffff, verb & 0xff);
- if (put_user(res, &arg->res))
- return -EFAULT;
- return 0;
-}
-
-static int get_wcap_ioctl(struct hda_codec *codec,
- struct hda_verb_ioctl __user *arg)
-{
- u32 verb, res;
-
- if (get_user(verb, &arg->verb))
- return -EFAULT;
- res = get_wcaps(codec, verb >> 24);
- if (put_user(res, &arg->res))
- return -EFAULT;
- return 0;
-}
-
-
-/*
- */
-static int hda_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct hda_codec *codec = hw->private_data;
- void __user *argp = (void __user *)arg;
-
- switch (cmd) {
- case HDA_IOCTL_PVERSION:
- return put_user(HDA_HWDEP_VERSION, (int __user *)argp);
- case HDA_IOCTL_VERB_WRITE:
- return verb_write_ioctl(codec, argp);
- case HDA_IOCTL_GET_WCAP:
- return get_wcap_ioctl(codec, argp);
- }
- return -ENOIOCTLCMD;
-}
-
-#ifdef CONFIG_COMPAT
-static int hda_hwdep_ioctl_compat(struct snd_hwdep *hw, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- return hda_hwdep_ioctl(hw, file, cmd, (unsigned long)compat_ptr(arg));
-}
-#endif
-
-static int hda_hwdep_open(struct snd_hwdep *hw, struct file *file)
-{
-#ifndef CONFIG_SND_DEBUG_VERBOSE
- if (!capable(CAP_SYS_RAWIO))
- return -EACCES;
-#endif
- return 0;
-}
-
-static void clear_hwdep_elements(struct hda_codec *codec)
-{
- int i;
-
- /* clear init verbs */
- snd_array_free(&codec->init_verbs);
- /* clear hints */
- for (i = 0; i < codec->hints.used; i++) {
- struct hda_hint *hint = snd_array_elem(&codec->hints, i);
- kfree(hint->key); /* we don't need to free hint->val */
- }
- snd_array_free(&codec->hints);
- snd_array_free(&codec->user_pins);
-}
-
-static void hwdep_free(struct snd_hwdep *hwdep)
-{
- clear_hwdep_elements(hwdep->private_data);
-}
-
-int /*__devinit*/ snd_hda_create_hwdep(struct hda_codec *codec)
-{
- char hwname[16];
- struct snd_hwdep *hwdep;
- int err;
-
- sprintf(hwname, "HDA Codec %d", codec->addr);
- err = snd_hwdep_new(codec->bus->card, hwname, codec->addr, &hwdep);
- if (err < 0)
- return err;
- codec->hwdep = hwdep;
- sprintf(hwdep->name, "HDA Codec %d", codec->addr);
- hwdep->iface = SNDRV_HWDEP_IFACE_HDA;
- hwdep->private_data = codec;
- hwdep->private_free = hwdep_free;
- hwdep->exclusive = 1;
-
- hwdep->ops.open = hda_hwdep_open;
- hwdep->ops.ioctl = hda_hwdep_ioctl;
-#ifdef CONFIG_COMPAT
- hwdep->ops.ioctl_compat = hda_hwdep_ioctl_compat;
-#endif
-
- snd_array_init(&codec->init_verbs, sizeof(struct hda_verb), 32);
- snd_array_init(&codec->hints, sizeof(struct hda_hint), 32);
- snd_array_init(&codec->user_pins, sizeof(struct hda_pincfg), 16);
-
- return 0;
-}
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static ssize_t power_on_acct_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct snd_hwdep *hwdep = dev_get_drvdata(dev);
- struct hda_codec *codec = hwdep->private_data;
- snd_hda_update_power_acct(codec);
- return sprintf(buf, "%u\n", jiffies_to_msecs(codec->power_on_acct));
-}
-
-static ssize_t power_off_acct_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct snd_hwdep *hwdep = dev_get_drvdata(dev);
- struct hda_codec *codec = hwdep->private_data;
- snd_hda_update_power_acct(codec);
- return sprintf(buf, "%u\n", jiffies_to_msecs(codec->power_off_acct));
-}
-
-static struct device_attribute power_attrs[] = {
- __ATTR_RO(power_on_acct),
- __ATTR_RO(power_off_acct),
-};
-
-int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec)
-{
- struct snd_hwdep *hwdep = codec->hwdep;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(power_attrs); i++)
- snd_add_device_sysfs_file(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card,
- hwdep->device, &power_attrs[i]);
- return 0;
-}
-#endif /* CONFIG_SND_HDA_POWER_SAVE */
-
-#ifdef CONFIG_SND_HDA_RECONFIG
-
-/*
- * sysfs interface
- */
-
-static int clear_codec(struct hda_codec *codec)
-{
- int err;
-
- err = snd_hda_codec_reset(codec);
- if (err < 0) {
- snd_printk(KERN_ERR "The codec is being used, can't free.\n");
- return err;
- }
- clear_hwdep_elements(codec);
- return 0;
-}
-
-static int reconfig_codec(struct hda_codec *codec)
-{
- int err;
-
- snd_hda_power_up(codec);
- snd_printk(KERN_INFO "hda-codec: reconfiguring\n");
- err = snd_hda_codec_reset(codec);
- if (err < 0) {
- snd_printk(KERN_ERR
- "The codec is being used, can't reconfigure.\n");
- goto error;
- }
- err = snd_hda_codec_configure(codec);
- if (err < 0)
- goto error;
- /* rebuild PCMs */
- err = snd_hda_codec_build_pcms(codec);
- if (err < 0)
- goto error;
- /* rebuild mixers */
- err = snd_hda_codec_build_controls(codec);
- if (err < 0)
- goto error;
- err = snd_card_register(codec->bus->card);
- error:
- snd_hda_power_down(codec);
- return err;
-}
-
-/*
- * allocate a string at most len chars, and remove the trailing EOL
- */
-static char *kstrndup_noeol(const char *src, size_t len)
-{
- char *s = kstrndup(src, len, GFP_KERNEL);
- char *p;
- if (!s)
- return NULL;
- p = strchr(s, '\n');
- if (p)
- *p = 0;
- return s;
-}
-
-#define CODEC_INFO_SHOW(type) \
-static ssize_t type##_show(struct device *dev, \
- struct device_attribute *attr, \
- char *buf) \
-{ \
- struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
- struct hda_codec *codec = hwdep->private_data; \
- return sprintf(buf, "0x%x\n", codec->type); \
-}
-
-#define CODEC_INFO_STR_SHOW(type) \
-static ssize_t type##_show(struct device *dev, \
- struct device_attribute *attr, \
- char *buf) \
-{ \
- struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
- struct hda_codec *codec = hwdep->private_data; \
- return sprintf(buf, "%s\n", \
- codec->type ? codec->type : ""); \
-}
-
-CODEC_INFO_SHOW(vendor_id);
-CODEC_INFO_SHOW(subsystem_id);
-CODEC_INFO_SHOW(revision_id);
-CODEC_INFO_SHOW(afg);
-CODEC_INFO_SHOW(mfg);
-CODEC_INFO_STR_SHOW(vendor_name);
-CODEC_INFO_STR_SHOW(chip_name);
-CODEC_INFO_STR_SHOW(modelname);
-
-#define CODEC_INFO_STORE(type) \
-static ssize_t type##_store(struct device *dev, \
- struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
- struct hda_codec *codec = hwdep->private_data; \
- unsigned long val; \
- int err = strict_strtoul(buf, 0, &val); \
- if (err < 0) \
- return err; \
- codec->type = val; \
- return count; \
-}
-
-#define CODEC_INFO_STR_STORE(type) \
-static ssize_t type##_store(struct device *dev, \
- struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
- struct hda_codec *codec = hwdep->private_data; \
- char *s = kstrndup_noeol(buf, 64); \
- if (!s) \
- return -ENOMEM; \
- kfree(codec->type); \
- codec->type = s; \
- return count; \
-}
-
-CODEC_INFO_STORE(vendor_id);
-CODEC_INFO_STORE(subsystem_id);
-CODEC_INFO_STORE(revision_id);
-CODEC_INFO_STR_STORE(vendor_name);
-CODEC_INFO_STR_STORE(chip_name);
-CODEC_INFO_STR_STORE(modelname);
-
-#define CODEC_ACTION_STORE(type) \
-static ssize_t type##_store(struct device *dev, \
- struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
- struct hda_codec *codec = hwdep->private_data; \
- int err = 0; \
- if (*buf) \
- err = type##_codec(codec); \
- return err < 0 ? err : count; \
-}
-
-CODEC_ACTION_STORE(reconfig);
-CODEC_ACTION_STORE(clear);
-
-static ssize_t init_verbs_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct snd_hwdep *hwdep = dev_get_drvdata(dev);
- struct hda_codec *codec = hwdep->private_data;
- int i, len = 0;
- for (i = 0; i < codec->init_verbs.used; i++) {
- struct hda_verb *v = snd_array_elem(&codec->init_verbs, i);
- len += snprintf(buf + len, PAGE_SIZE - len,
- "0x%02x 0x%03x 0x%04x\n",
- v->nid, v->verb, v->param);
- }
- return len;
-}
-
-static int parse_init_verbs(struct hda_codec *codec, const char *buf)
-{
- struct hda_verb *v;
- int nid, verb, param;
-
- if (sscanf(buf, "%i %i %i", &nid, &verb, &param) != 3)
- return -EINVAL;
- if (!nid || !verb)
- return -EINVAL;
- v = snd_array_new(&codec->init_verbs);
- if (!v)
- return -ENOMEM;
- v->nid = nid;
- v->verb = verb;
- v->param = param;
- return 0;
-}
-
-static ssize_t init_verbs_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct snd_hwdep *hwdep = dev_get_drvdata(dev);
- struct hda_codec *codec = hwdep->private_data;
- int err = parse_init_verbs(codec, buf);
- if (err < 0)
- return err;
- return count;
-}
-
-static ssize_t hints_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct snd_hwdep *hwdep = dev_get_drvdata(dev);
- struct hda_codec *codec = hwdep->private_data;
- int i, len = 0;
- for (i = 0; i < codec->hints.used; i++) {
- struct hda_hint *hint = snd_array_elem(&codec->hints, i);
- len += snprintf(buf + len, PAGE_SIZE - len,
- "%s = %s\n", hint->key, hint->val);
- }
- return len;
-}
-
-static struct hda_hint *get_hint(struct hda_codec *codec, const char *key)
-{
- int i;
-
- for (i = 0; i < codec->hints.used; i++) {
- struct hda_hint *hint = snd_array_elem(&codec->hints, i);
- if (!strcmp(hint->key, key))
- return hint;
- }
- return NULL;
-}
-
-static void remove_trail_spaces(char *str)
-{
- char *p;
- if (!*str)
- return;
- p = str + strlen(str) - 1;
- for (; isspace(*p); p--) {
- *p = 0;
- if (p == str)
- return;
- }
-}
-
-#define MAX_HINTS 1024
-
-static int parse_hints(struct hda_codec *codec, const char *buf)
-{
- char *key, *val;
- struct hda_hint *hint;
-
- buf = skip_spaces(buf);
- if (!*buf || *buf == '#' || *buf == '\n')
- return 0;
- if (*buf == '=')
- return -EINVAL;
- key = kstrndup_noeol(buf, 1024);
- if (!key)
- return -ENOMEM;
- /* extract key and val */
- val = strchr(key, '=');
- if (!val) {
- kfree(key);
- return -EINVAL;
- }
- *val++ = 0;
- val = skip_spaces(val);
- remove_trail_spaces(key);
- remove_trail_spaces(val);
- hint = get_hint(codec, key);
- if (hint) {
- /* replace */
- kfree(hint->key);
- hint->key = key;
- hint->val = val;
- return 0;
- }
- /* allocate a new hint entry */
- if (codec->hints.used >= MAX_HINTS)
- hint = NULL;
- else
- hint = snd_array_new(&codec->hints);
- if (!hint) {
- kfree(key);
- return -ENOMEM;
- }
- hint->key = key;
- hint->val = val;
- return 0;
-}
-
-static ssize_t hints_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct snd_hwdep *hwdep = dev_get_drvdata(dev);
- struct hda_codec *codec = hwdep->private_data;
- int err = parse_hints(codec, buf);
- if (err < 0)
- return err;
- return count;
-}
-
-static ssize_t pin_configs_show(struct hda_codec *codec,
- struct snd_array *list,
- char *buf)
-{
- int i, len = 0;
- for (i = 0; i < list->used; i++) {
- struct hda_pincfg *pin = snd_array_elem(list, i);
- len += sprintf(buf + len, "0x%02x 0x%08x\n",
- pin->nid, pin->cfg);
- }
- return len;
-}
-
-static ssize_t init_pin_configs_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct snd_hwdep *hwdep = dev_get_drvdata(dev);
- struct hda_codec *codec = hwdep->private_data;
- return pin_configs_show(codec, &codec->init_pins, buf);
-}
-
-static ssize_t user_pin_configs_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct snd_hwdep *hwdep = dev_get_drvdata(dev);
- struct hda_codec *codec = hwdep->private_data;
- return pin_configs_show(codec, &codec->user_pins, buf);
-}
-
-static ssize_t driver_pin_configs_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct snd_hwdep *hwdep = dev_get_drvdata(dev);
- struct hda_codec *codec = hwdep->private_data;
- return pin_configs_show(codec, &codec->driver_pins, buf);
-}
-
-#define MAX_PIN_CONFIGS 32
-
-static int parse_user_pin_configs(struct hda_codec *codec, const char *buf)
-{
- int nid, cfg;
-
- if (sscanf(buf, "%i %i", &nid, &cfg) != 2)
- return -EINVAL;
- if (!nid)
- return -EINVAL;
- return snd_hda_add_pincfg(codec, &codec->user_pins, nid, cfg);
-}
-
-static ssize_t user_pin_configs_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct snd_hwdep *hwdep = dev_get_drvdata(dev);
- struct hda_codec *codec = hwdep->private_data;
- int err = parse_user_pin_configs(codec, buf);
- if (err < 0)
- return err;
- return count;
-}
-
-#define CODEC_ATTR_RW(type) \
- __ATTR(type, 0644, type##_show, type##_store)
-#define CODEC_ATTR_RO(type) \
- __ATTR_RO(type)
-#define CODEC_ATTR_WO(type) \
- __ATTR(type, 0200, NULL, type##_store)
-
-static struct device_attribute codec_attrs[] = {
- CODEC_ATTR_RW(vendor_id),
- CODEC_ATTR_RW(subsystem_id),
- CODEC_ATTR_RW(revision_id),
- CODEC_ATTR_RO(afg),
- CODEC_ATTR_RO(mfg),
- CODEC_ATTR_RW(vendor_name),
- CODEC_ATTR_RW(chip_name),
- CODEC_ATTR_RW(modelname),
- CODEC_ATTR_RW(init_verbs),
- CODEC_ATTR_RW(hints),
- CODEC_ATTR_RO(init_pin_configs),
- CODEC_ATTR_RW(user_pin_configs),
- CODEC_ATTR_RO(driver_pin_configs),
- CODEC_ATTR_WO(reconfig),
- CODEC_ATTR_WO(clear),
-};
-
-/*
- * create sysfs files on hwdep directory
- */
-int snd_hda_hwdep_add_sysfs(struct hda_codec *codec)
-{
- struct snd_hwdep *hwdep = codec->hwdep;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(codec_attrs); i++)
- snd_add_device_sysfs_file(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card,
- hwdep->device, &codec_attrs[i]);
- return 0;
-}
-
-/*
- * Look for hint string
- */
-const char *snd_hda_get_hint(struct hda_codec *codec, const char *key)
-{
- struct hda_hint *hint = get_hint(codec, key);
- return hint ? hint->val : NULL;
-}
-EXPORT_SYMBOL_HDA(snd_hda_get_hint);
-
-int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key)
-{
- const char *p = snd_hda_get_hint(codec, key);
- if (!p || !*p)
- return -ENOENT;
- switch (toupper(*p)) {
- case 'T': /* true */
- case 'Y': /* yes */
- case '1':
- return 1;
- }
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_get_bool_hint);
-
-#endif /* CONFIG_SND_HDA_RECONFIG */
-
-#ifdef CONFIG_SND_HDA_PATCH_LOADER
-
-/* parser mode */
-enum {
- LINE_MODE_NONE,
- LINE_MODE_CODEC,
- LINE_MODE_MODEL,
- LINE_MODE_PINCFG,
- LINE_MODE_VERB,
- LINE_MODE_HINT,
- LINE_MODE_VENDOR_ID,
- LINE_MODE_SUBSYSTEM_ID,
- LINE_MODE_REVISION_ID,
- LINE_MODE_CHIP_NAME,
- NUM_LINE_MODES,
-};
-
-static inline int strmatch(const char *a, const char *b)
-{
- return strnicmp(a, b, strlen(b)) == 0;
-}
-
-/* parse the contents after the line "[codec]"
- * accept only the line with three numbers, and assign the current codec
- */
-static void parse_codec_mode(char *buf, struct hda_bus *bus,
- struct hda_codec **codecp)
-{
- int vendorid, subid, caddr;
- struct hda_codec *codec;
-
- *codecp = NULL;
- if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) {
- list_for_each_entry(codec, &bus->codec_list, list) {
- if ((vendorid <= 0 || codec->vendor_id == vendorid) &&
- (subid <= 0 || codec->subsystem_id == subid) &&
- codec->addr == caddr) {
- *codecp = codec;
- break;
- }
- }
- }
-}
-
-/* parse the contents after the other command tags, [pincfg], [verb],
- * [vendor_id], [subsystem_id], [revision_id], [chip_name], [hint] and [model]
- * just pass to the sysfs helper (only when any codec was specified)
- */
-static void parse_pincfg_mode(char *buf, struct hda_bus *bus,
- struct hda_codec **codecp)
-{
- parse_user_pin_configs(*codecp, buf);
-}
-
-static void parse_verb_mode(char *buf, struct hda_bus *bus,
- struct hda_codec **codecp)
-{
- parse_init_verbs(*codecp, buf);
-}
-
-static void parse_hint_mode(char *buf, struct hda_bus *bus,
- struct hda_codec **codecp)
-{
- parse_hints(*codecp, buf);
-}
-
-static void parse_model_mode(char *buf, struct hda_bus *bus,
- struct hda_codec **codecp)
-{
- kfree((*codecp)->modelname);
- (*codecp)->modelname = kstrdup(buf, GFP_KERNEL);
-}
-
-static void parse_chip_name_mode(char *buf, struct hda_bus *bus,
- struct hda_codec **codecp)
-{
- kfree((*codecp)->chip_name);
- (*codecp)->chip_name = kstrdup(buf, GFP_KERNEL);
-}
-
-#define DEFINE_PARSE_ID_MODE(name) \
-static void parse_##name##_mode(char *buf, struct hda_bus *bus, \
- struct hda_codec **codecp) \
-{ \
- unsigned long val; \
- if (!strict_strtoul(buf, 0, &val)) \
- (*codecp)->name = val; \
-}
-
-DEFINE_PARSE_ID_MODE(vendor_id);
-DEFINE_PARSE_ID_MODE(subsystem_id);
-DEFINE_PARSE_ID_MODE(revision_id);
-
-
-struct hda_patch_item {
- const char *tag;
- void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc);
- int need_codec;
-};
-
-static struct hda_patch_item patch_items[NUM_LINE_MODES] = {
- [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode, 0 },
- [LINE_MODE_MODEL] = { "[model]", parse_model_mode, 1 },
- [LINE_MODE_VERB] = { "[verb]", parse_verb_mode, 1 },
- [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode, 1 },
- [LINE_MODE_HINT] = { "[hint]", parse_hint_mode, 1 },
- [LINE_MODE_VENDOR_ID] = { "[vendor_id]", parse_vendor_id_mode, 1 },
- [LINE_MODE_SUBSYSTEM_ID] = { "[subsystem_id]", parse_subsystem_id_mode, 1 },
- [LINE_MODE_REVISION_ID] = { "[revision_id]", parse_revision_id_mode, 1 },
- [LINE_MODE_CHIP_NAME] = { "[chip_name]", parse_chip_name_mode, 1 },
-};
-
-/* check the line starting with '[' -- change the parser mode accodingly */
-static int parse_line_mode(char *buf, struct hda_bus *bus)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(patch_items); i++) {
- if (!patch_items[i].tag)
- continue;
- if (strmatch(buf, patch_items[i].tag))
- return i;
- }
- return LINE_MODE_NONE;
-}
-
-/* copy one line from the buffer in fw, and update the fields in fw
- * return zero if it reaches to the end of the buffer, or non-zero
- * if successfully copied a line
- *
- * the spaces at the beginning and the end of the line are stripped
- */
-static int get_line_from_fw(char *buf, int size, struct firmware *fw)
-{
- int len;
- const char *p = fw->data;
- while (isspace(*p) && fw->size) {
- p++;
- fw->size--;
- }
- if (!fw->size)
- return 0;
-
- for (len = 0; len < fw->size; len++) {
- if (!*p)
- break;
- if (*p == '\n') {
- p++;
- len++;
- break;
- }
- if (len < size)
- *buf++ = *p++;
- }
- *buf = 0;
- fw->size -= len;
- fw->data = p;
- remove_trail_spaces(buf);
- return 1;
-}
-
-/*
- * load a "patch" firmware file and parse it
- */
-int snd_hda_load_patch(struct hda_bus *bus, const char *patch)
-{
- int err;
- const struct firmware *fw;
- struct firmware tmp;
- char buf[128];
- struct hda_codec *codec;
- int line_mode;
- struct device *dev = bus->card->dev;
-
- if (snd_BUG_ON(!dev))
- return -ENODEV;
- err = request_firmware(&fw, patch, dev);
- if (err < 0) {
- printk(KERN_ERR "hda-codec: Cannot load the patch '%s'\n",
- patch);
- return err;
- }
-
- tmp = *fw;
- line_mode = LINE_MODE_NONE;
- codec = NULL;
- while (get_line_from_fw(buf, sizeof(buf) - 1, &tmp)) {
- if (!*buf || *buf == '#' || *buf == '\n')
- continue;
- if (*buf == '[')
- line_mode = parse_line_mode(buf, bus);
- else if (patch_items[line_mode].parser &&
- (codec || !patch_items[line_mode].need_codec))
- patch_items[line_mode].parser(buf, bus, &codec);
- }
- release_firmware(fw);
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_load_patch);
-#endif /* CONFIG_SND_HDA_PATCH_LOADER */
diff --git a/ANDROID_3.4.5/sound/pci/hda/hda_intel.c b/ANDROID_3.4.5/sound/pci/hda/hda_intel.c
deleted file mode 100644
index 1f350522..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/hda_intel.c
+++ /dev/null
@@ -1,3173 +0,0 @@
-/*
- *
- * hda_intel.c - Implementation of primary alsa driver code base
- * for Intel HD Audio.
- *
- * Copyright(c) 2004 Intel Corporation. All rights reserved.
- *
- * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
- * PeiSen Hou <pshou@realtek.com.tw>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * CONTACTS:
- *
- * Matt Jared matt.jared@intel.com
- * Andy Kopp andy.kopp@intel.com
- * Dan Kogan dan.d.kogan@intel.com
- *
- * CHANGES:
- *
- * 2004.12.01 Major rewrite by tiwai, merged the work of pshou
- *
- */
-
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/mutex.h>
-#include <linux/reboot.h>
-#include <linux/io.h>
-#ifdef CONFIG_X86
-/* for snoop control */
-#include <asm/pgtable.h>
-#include <asm/cacheflush.h>
-#endif
-#include <sound/core.h>
-#include <sound/initval.h>
-#include "hda_codec.h"
-
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static char *model[SNDRV_CARDS];
-static int position_fix[SNDRV_CARDS];
-static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
-static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
-static int probe_only[SNDRV_CARDS];
-static bool single_cmd;
-static int enable_msi = -1;
-#ifdef CONFIG_SND_HDA_PATCH_LOADER
-static char *patch[SNDRV_CARDS];
-#endif
-#ifdef CONFIG_SND_HDA_INPUT_BEEP
-static int beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] =
- CONFIG_SND_HDA_INPUT_BEEP_MODE};
-#endif
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Intel HD audio interface.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Intel HD audio interface.");
-module_param_array(model, charp, NULL, 0444);
-MODULE_PARM_DESC(model, "Use the given board model.");
-module_param_array(position_fix, int, NULL, 0444);
-MODULE_PARM_DESC(position_fix, "DMA pointer read method."
- "(0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO).");
-module_param_array(bdl_pos_adj, int, NULL, 0644);
-MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
-module_param_array(probe_mask, int, NULL, 0444);
-MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
-module_param_array(probe_only, int, NULL, 0444);
-MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization.");
-module_param(single_cmd, bool, 0444);
-MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
- "(for debugging only).");
-module_param(enable_msi, bint, 0444);
-MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
-#ifdef CONFIG_SND_HDA_PATCH_LOADER
-module_param_array(patch, charp, NULL, 0444);
-MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface.");
-#endif
-#ifdef CONFIG_SND_HDA_INPUT_BEEP
-module_param_array(beep_mode, int, NULL, 0444);
-MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode "
- "(0=off, 1=on, 2=mute switch on/off) (default=1).");
-#endif
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;
-module_param(power_save, int, 0644);
-MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
- "(in second, 0 = disable).");
-
-/* reset the HD-audio controller in power save mode.
- * this may give more power-saving, but will take longer time to
- * wake up.
- */
-static bool power_save_controller = 1;
-module_param(power_save_controller, bool, 0644);
-MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
-#endif
-
-static int align_buffer_size = -1;
-module_param(align_buffer_size, bint, 0644);
-MODULE_PARM_DESC(align_buffer_size,
- "Force buffer and period sizes to be multiple of 128 bytes.");
-
-#ifdef CONFIG_X86
-static bool hda_snoop = true;
-module_param_named(snoop, hda_snoop, bool, 0444);
-MODULE_PARM_DESC(snoop, "Enable/disable snooping");
-#define azx_snoop(chip) (chip)->snoop
-#else
-#define hda_snoop true
-#define azx_snoop(chip) true
-#endif
-
-
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
- "{Intel, ICH6M},"
- "{Intel, ICH7},"
- "{Intel, ESB2},"
- "{Intel, ICH8},"
- "{Intel, ICH9},"
- "{Intel, ICH10},"
- "{Intel, PCH},"
- "{Intel, CPT},"
- "{Intel, PPT},"
- "{Intel, LPT},"
- "{Intel, PBG},"
- "{Intel, SCH},"
- "{ATI, SB450},"
- "{ATI, SB600},"
- "{ATI, RS600},"
- "{ATI, RS690},"
- "{ATI, RS780},"
- "{ATI, R600},"
- "{ATI, RV630},"
- "{ATI, RV610},"
- "{ATI, RV670},"
- "{ATI, RV635},"
- "{ATI, RV620},"
- "{ATI, RV770},"
- "{VIA, VT8251},"
- "{VIA, VT8237A},"
- "{SiS, SIS966},"
- "{ULI, M5461}}");
-MODULE_DESCRIPTION("Intel HDA driver");
-
-#ifdef CONFIG_SND_VERBOSE_PRINTK
-#define SFX /* nop */
-#else
-#define SFX "hda-intel: "
-#endif
-
-/*
- * registers
- */
-#define ICH6_REG_GCAP 0x00
-#define ICH6_GCAP_64OK (1 << 0) /* 64bit address support */
-#define ICH6_GCAP_NSDO (3 << 1) /* # of serial data out signals */
-#define ICH6_GCAP_BSS (31 << 3) /* # of bidirectional streams */
-#define ICH6_GCAP_ISS (15 << 8) /* # of input streams */
-#define ICH6_GCAP_OSS (15 << 12) /* # of output streams */
-#define ICH6_REG_VMIN 0x02
-#define ICH6_REG_VMAJ 0x03
-#define ICH6_REG_OUTPAY 0x04
-#define ICH6_REG_INPAY 0x06
-#define ICH6_REG_GCTL 0x08
-#define ICH6_GCTL_RESET (1 << 0) /* controller reset */
-#define ICH6_GCTL_FCNTRL (1 << 1) /* flush control */
-#define ICH6_GCTL_UNSOL (1 << 8) /* accept unsol. response enable */
-#define ICH6_REG_WAKEEN 0x0c
-#define ICH6_REG_STATESTS 0x0e
-#define ICH6_REG_GSTS 0x10
-#define ICH6_GSTS_FSTS (1 << 1) /* flush status */
-#define ICH6_REG_INTCTL 0x20
-#define ICH6_REG_INTSTS 0x24
-#define ICH6_REG_WALLCLK 0x30 /* 24Mhz source */
-#define ICH6_REG_OLD_SSYNC 0x34 /* SSYNC for old ICH */
-#define ICH6_REG_SSYNC 0x38
-#define ICH6_REG_CORBLBASE 0x40
-#define ICH6_REG_CORBUBASE 0x44
-#define ICH6_REG_CORBWP 0x48
-#define ICH6_REG_CORBRP 0x4a
-#define ICH6_CORBRP_RST (1 << 15) /* read pointer reset */
-#define ICH6_REG_CORBCTL 0x4c
-#define ICH6_CORBCTL_RUN (1 << 1) /* enable DMA */
-#define ICH6_CORBCTL_CMEIE (1 << 0) /* enable memory error irq */
-#define ICH6_REG_CORBSTS 0x4d
-#define ICH6_CORBSTS_CMEI (1 << 0) /* memory error indication */
-#define ICH6_REG_CORBSIZE 0x4e
-
-#define ICH6_REG_RIRBLBASE 0x50
-#define ICH6_REG_RIRBUBASE 0x54
-#define ICH6_REG_RIRBWP 0x58
-#define ICH6_RIRBWP_RST (1 << 15) /* write pointer reset */
-#define ICH6_REG_RINTCNT 0x5a
-#define ICH6_REG_RIRBCTL 0x5c
-#define ICH6_RBCTL_IRQ_EN (1 << 0) /* enable IRQ */
-#define ICH6_RBCTL_DMA_EN (1 << 1) /* enable DMA */
-#define ICH6_RBCTL_OVERRUN_EN (1 << 2) /* enable overrun irq */
-#define ICH6_REG_RIRBSTS 0x5d
-#define ICH6_RBSTS_IRQ (1 << 0) /* response irq */
-#define ICH6_RBSTS_OVERRUN (1 << 2) /* overrun irq */
-#define ICH6_REG_RIRBSIZE 0x5e
-
-#define ICH6_REG_IC 0x60
-#define ICH6_REG_IR 0x64
-#define ICH6_REG_IRS 0x68
-#define ICH6_IRS_VALID (1<<1)
-#define ICH6_IRS_BUSY (1<<0)
-
-#define ICH6_REG_DPLBASE 0x70
-#define ICH6_REG_DPUBASE 0x74
-#define ICH6_DPLBASE_ENABLE 0x1 /* Enable position buffer */
-
-/* SD offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */
-enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
-
-/* stream register offsets from stream base */
-#define ICH6_REG_SD_CTL 0x00
-#define ICH6_REG_SD_STS 0x03
-#define ICH6_REG_SD_LPIB 0x04
-#define ICH6_REG_SD_CBL 0x08
-#define ICH6_REG_SD_LVI 0x0c
-#define ICH6_REG_SD_FIFOW 0x0e
-#define ICH6_REG_SD_FIFOSIZE 0x10
-#define ICH6_REG_SD_FORMAT 0x12
-#define ICH6_REG_SD_BDLPL 0x18
-#define ICH6_REG_SD_BDLPU 0x1c
-
-/* PCI space */
-#define ICH6_PCIREG_TCSEL 0x44
-
-/*
- * other constants
- */
-
-/* max number of SDs */
-/* ICH, ATI and VIA have 4 playback and 4 capture */
-#define ICH6_NUM_CAPTURE 4
-#define ICH6_NUM_PLAYBACK 4
-
-/* ULI has 6 playback and 5 capture */
-#define ULI_NUM_CAPTURE 5
-#define ULI_NUM_PLAYBACK 6
-
-/* ATI HDMI has 1 playback and 0 capture */
-#define ATIHDMI_NUM_CAPTURE 0
-#define ATIHDMI_NUM_PLAYBACK 1
-
-/* TERA has 4 playback and 3 capture */
-#define TERA_NUM_CAPTURE 3
-#define TERA_NUM_PLAYBACK 4
-
-/* this number is statically defined for simplicity */
-#define MAX_AZX_DEV 16
-
-/* max number of fragments - we may use more if allocating more pages for BDL */
-#define BDL_SIZE 4096
-#define AZX_MAX_BDL_ENTRIES (BDL_SIZE / 16)
-#define AZX_MAX_FRAG 32
-/* max buffer size - no h/w limit, you can increase as you like */
-#define AZX_MAX_BUF_SIZE (1024*1024*1024)
-
-/* RIRB int mask: overrun[2], response[0] */
-#define RIRB_INT_RESPONSE 0x01
-#define RIRB_INT_OVERRUN 0x04
-#define RIRB_INT_MASK 0x05
-
-/* STATESTS int mask: S3,SD2,SD1,SD0 */
-#define AZX_MAX_CODECS 8
-#define AZX_DEFAULT_CODECS 4
-#define STATESTS_INT_MASK ((1 << AZX_MAX_CODECS) - 1)
-
-/* SD_CTL bits */
-#define SD_CTL_STREAM_RESET 0x01 /* stream reset bit */
-#define SD_CTL_DMA_START 0x02 /* stream DMA start bit */
-#define SD_CTL_STRIPE (3 << 16) /* stripe control */
-#define SD_CTL_TRAFFIC_PRIO (1 << 18) /* traffic priority */
-#define SD_CTL_DIR (1 << 19) /* bi-directional stream */
-#define SD_CTL_STREAM_TAG_MASK (0xf << 20)
-#define SD_CTL_STREAM_TAG_SHIFT 20
-
-/* SD_CTL and SD_STS */
-#define SD_INT_DESC_ERR 0x10 /* descriptor error interrupt */
-#define SD_INT_FIFO_ERR 0x08 /* FIFO error interrupt */
-#define SD_INT_COMPLETE 0x04 /* completion interrupt */
-#define SD_INT_MASK (SD_INT_DESC_ERR|SD_INT_FIFO_ERR|\
- SD_INT_COMPLETE)
-
-/* SD_STS */
-#define SD_STS_FIFO_READY 0x20 /* FIFO ready */
-
-/* INTCTL and INTSTS */
-#define ICH6_INT_ALL_STREAM 0xff /* all stream interrupts */
-#define ICH6_INT_CTRL_EN 0x40000000 /* controller interrupt enable bit */
-#define ICH6_INT_GLOBAL_EN 0x80000000 /* global interrupt enable bit */
-
-/* below are so far hardcoded - should read registers in future */
-#define ICH6_MAX_CORB_ENTRIES 256
-#define ICH6_MAX_RIRB_ENTRIES 256
-
-/* position fix mode */
-enum {
- POS_FIX_AUTO,
- POS_FIX_LPIB,
- POS_FIX_POSBUF,
- POS_FIX_VIACOMBO,
- POS_FIX_COMBO,
-};
-
-/* Defines for ATI HD Audio support in SB450 south bridge */
-#define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR 0x42
-#define ATI_SB450_HDAUDIO_ENABLE_SNOOP 0x02
-
-/* Defines for Nvidia HDA support */
-#define NVIDIA_HDA_TRANSREG_ADDR 0x4e
-#define NVIDIA_HDA_ENABLE_COHBITS 0x0f
-#define NVIDIA_HDA_ISTRM_COH 0x4d
-#define NVIDIA_HDA_OSTRM_COH 0x4c
-#define NVIDIA_HDA_ENABLE_COHBIT 0x01
-
-/* Defines for Intel SCH HDA snoop control */
-#define INTEL_SCH_HDA_DEVC 0x78
-#define INTEL_SCH_HDA_DEVC_NOSNOOP (0x1<<11)
-
-/* Define IN stream 0 FIFO size offset in VIA controller */
-#define VIA_IN_STREAM0_FIFO_SIZE_OFFSET 0x90
-/* Define VIA HD Audio Device ID*/
-#define VIA_HDAC_DEVICE_ID 0x3288
-
-/* HD Audio class code */
-#define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403
-
-/*
- */
-
-struct azx_dev {
- struct snd_dma_buffer bdl; /* BDL buffer */
- u32 *posbuf; /* position buffer pointer */
-
- unsigned int bufsize; /* size of the play buffer in bytes */
- unsigned int period_bytes; /* size of the period in bytes */
- unsigned int frags; /* number for period in the play buffer */
- unsigned int fifo_size; /* FIFO size */
- unsigned long start_wallclk; /* start + minimum wallclk */
- unsigned long period_wallclk; /* wallclk for period */
-
- void __iomem *sd_addr; /* stream descriptor pointer */
-
- u32 sd_int_sta_mask; /* stream int status mask */
-
- /* pcm support */
- struct snd_pcm_substream *substream; /* assigned substream,
- * set in PCM open
- */
- unsigned int format_val; /* format value to be set in the
- * controller and the codec
- */
- unsigned char stream_tag; /* assigned stream */
- unsigned char index; /* stream index */
- int assigned_key; /* last device# key assigned to */
-
- unsigned int opened :1;
- unsigned int running :1;
- unsigned int irq_pending :1;
- /*
- * For VIA:
- * A flag to ensure DMA position is 0
- * when link position is not greater than FIFO size
- */
- unsigned int insufficient :1;
- unsigned int wc_marked:1;
-};
-
-/* CORB/RIRB */
-struct azx_rb {
- u32 *buf; /* CORB/RIRB buffer
- * Each CORB entry is 4byte, RIRB is 8byte
- */
- dma_addr_t addr; /* physical address of CORB/RIRB buffer */
- /* for RIRB */
- unsigned short rp, wp; /* read/write pointers */
- int cmds[AZX_MAX_CODECS]; /* number of pending requests */
- u32 res[AZX_MAX_CODECS]; /* last read value */
-};
-
-struct azx_pcm {
- struct azx *chip;
- struct snd_pcm *pcm;
- struct hda_codec *codec;
- struct hda_pcm_stream *hinfo[2];
- struct list_head list;
-};
-
-struct azx {
- struct snd_card *card;
- struct pci_dev *pci;
- int dev_index;
-
- /* chip type specific */
- int driver_type;
- unsigned int driver_caps;
- int playback_streams;
- int playback_index_offset;
- int capture_streams;
- int capture_index_offset;
- int num_streams;
-
- /* pci resources */
- unsigned long addr;
- void __iomem *remap_addr;
- int irq;
-
- /* locks */
- spinlock_t reg_lock;
- struct mutex open_mutex;
-
- /* streams (x num_streams) */
- struct azx_dev *azx_dev;
-
- /* PCM */
- struct list_head pcm_list; /* azx_pcm list */
-
- /* HD codec */
- unsigned short codec_mask;
- int codec_probe_mask; /* copied from probe_mask option */
- struct hda_bus *bus;
- unsigned int beep_mode;
-
- /* CORB/RIRB */
- struct azx_rb corb;
- struct azx_rb rirb;
-
- /* CORB/RIRB and position buffers */
- struct snd_dma_buffer rb;
- struct snd_dma_buffer posbuf;
-
- /* flags */
- int position_fix[2]; /* for both playback/capture streams */
- int poll_count;
- unsigned int running :1;
- unsigned int initialized :1;
- unsigned int single_cmd :1;
- unsigned int polling_mode :1;
- unsigned int msi :1;
- unsigned int irq_pending_warned :1;
- unsigned int probing :1; /* codec probing phase */
- unsigned int snoop:1;
- unsigned int align_buffer_size:1;
-
- /* for debugging */
- unsigned int last_cmd[AZX_MAX_CODECS];
-
- /* for pending irqs */
- struct work_struct irq_pending_work;
-
- /* reboot notifier (for mysterious hangup problem at power-down) */
- struct notifier_block reboot_notifier;
-};
-
-/* driver types */
-enum {
- AZX_DRIVER_ICH,
- AZX_DRIVER_PCH,
- AZX_DRIVER_SCH,
- AZX_DRIVER_ATI,
- AZX_DRIVER_ATIHDMI,
- AZX_DRIVER_ATIHDMI_NS,
- AZX_DRIVER_VIA,
- AZX_DRIVER_SIS,
- AZX_DRIVER_ULI,
- AZX_DRIVER_NVIDIA,
- AZX_DRIVER_TERA,
- AZX_DRIVER_CTX,
- AZX_DRIVER_GENERIC,
- AZX_NUM_DRIVERS, /* keep this as last entry */
-};
-
-/* driver quirks (capabilities) */
-/* bits 0-7 are used for indicating driver type */
-#define AZX_DCAPS_NO_TCSEL (1 << 8) /* No Intel TCSEL bit */
-#define AZX_DCAPS_NO_MSI (1 << 9) /* No MSI support */
-#define AZX_DCAPS_ATI_SNOOP (1 << 10) /* ATI snoop enable */
-#define AZX_DCAPS_NVIDIA_SNOOP (1 << 11) /* Nvidia snoop enable */
-#define AZX_DCAPS_SCH_SNOOP (1 << 12) /* SCH/PCH snoop enable */
-#define AZX_DCAPS_RIRB_DELAY (1 << 13) /* Long delay in read loop */
-#define AZX_DCAPS_RIRB_PRE_DELAY (1 << 14) /* Put a delay before read */
-#define AZX_DCAPS_CTX_WORKAROUND (1 << 15) /* X-Fi workaround */
-#define AZX_DCAPS_POSFIX_LPIB (1 << 16) /* Use LPIB as default */
-#define AZX_DCAPS_POSFIX_VIA (1 << 17) /* Use VIACOMBO as default */
-#define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */
-#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */
-#define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */
-#define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */
-#define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */
-
-/* quirks for ATI SB / AMD Hudson */
-#define AZX_DCAPS_PRESET_ATI_SB \
- (AZX_DCAPS_ATI_SNOOP | AZX_DCAPS_NO_TCSEL | \
- AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB)
-
-/* quirks for ATI/AMD HDMI */
-#define AZX_DCAPS_PRESET_ATI_HDMI \
- (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB)
-
-/* quirks for Nvidia */
-#define AZX_DCAPS_PRESET_NVIDIA \
- (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI |\
- AZX_DCAPS_ALIGN_BUFSIZE)
-
-static char *driver_short_names[] __devinitdata = {
- [AZX_DRIVER_ICH] = "HDA Intel",
- [AZX_DRIVER_PCH] = "HDA Intel PCH",
- [AZX_DRIVER_SCH] = "HDA Intel MID",
- [AZX_DRIVER_ATI] = "HDA ATI SB",
- [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI",
- [AZX_DRIVER_ATIHDMI_NS] = "HDA ATI HDMI",
- [AZX_DRIVER_VIA] = "HDA VIA VT82xx",
- [AZX_DRIVER_SIS] = "HDA SIS966",
- [AZX_DRIVER_ULI] = "HDA ULI M5461",
- [AZX_DRIVER_NVIDIA] = "HDA NVidia",
- [AZX_DRIVER_TERA] = "HDA Teradici",
- [AZX_DRIVER_CTX] = "HDA Creative",
- [AZX_DRIVER_GENERIC] = "HD-Audio Generic",
-};
-
-/*
- * macros for easy use
- */
-#define azx_writel(chip,reg,value) \
- writel(value, (chip)->remap_addr + ICH6_REG_##reg)
-#define azx_readl(chip,reg) \
- readl((chip)->remap_addr + ICH6_REG_##reg)
-#define azx_writew(chip,reg,value) \
- writew(value, (chip)->remap_addr + ICH6_REG_##reg)
-#define azx_readw(chip,reg) \
- readw((chip)->remap_addr + ICH6_REG_##reg)
-#define azx_writeb(chip,reg,value) \
- writeb(value, (chip)->remap_addr + ICH6_REG_##reg)
-#define azx_readb(chip,reg) \
- readb((chip)->remap_addr + ICH6_REG_##reg)
-
-#define azx_sd_writel(dev,reg,value) \
- writel(value, (dev)->sd_addr + ICH6_REG_##reg)
-#define azx_sd_readl(dev,reg) \
- readl((dev)->sd_addr + ICH6_REG_##reg)
-#define azx_sd_writew(dev,reg,value) \
- writew(value, (dev)->sd_addr + ICH6_REG_##reg)
-#define azx_sd_readw(dev,reg) \
- readw((dev)->sd_addr + ICH6_REG_##reg)
-#define azx_sd_writeb(dev,reg,value) \
- writeb(value, (dev)->sd_addr + ICH6_REG_##reg)
-#define azx_sd_readb(dev,reg) \
- readb((dev)->sd_addr + ICH6_REG_##reg)
-
-/* for pcm support */
-#define get_azx_dev(substream) (substream->runtime->private_data)
-
-#ifdef CONFIG_X86
-static void __mark_pages_wc(struct azx *chip, void *addr, size_t size, bool on)
-{
- if (azx_snoop(chip))
- return;
- if (addr && size) {
- int pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
- if (on)
- set_memory_wc((unsigned long)addr, pages);
- else
- set_memory_wb((unsigned long)addr, pages);
- }
-}
-
-static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf,
- bool on)
-{
- __mark_pages_wc(chip, buf->area, buf->bytes, on);
-}
-static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev,
- struct snd_pcm_runtime *runtime, bool on)
-{
- if (azx_dev->wc_marked != on) {
- __mark_pages_wc(chip, runtime->dma_area, runtime->dma_bytes, on);
- azx_dev->wc_marked = on;
- }
-}
-#else
-/* NOP for other archs */
-static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf,
- bool on)
-{
-}
-static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev,
- struct snd_pcm_runtime *runtime, bool on)
-{
-}
-#endif
-
-static int azx_acquire_irq(struct azx *chip, int do_disconnect);
-static int azx_send_cmd(struct hda_bus *bus, unsigned int val);
-/*
- * Interface for HD codec
- */
-
-/*
- * CORB / RIRB interface
- */
-static int azx_alloc_cmd_io(struct azx *chip)
-{
- int err;
-
- /* single page (at least 4096 bytes) must suffice for both ringbuffes */
- err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- PAGE_SIZE, &chip->rb);
- if (err < 0) {
- snd_printk(KERN_ERR SFX "cannot allocate CORB/RIRB\n");
- return err;
- }
- mark_pages_wc(chip, &chip->rb, true);
- return 0;
-}
-
-static void azx_init_cmd_io(struct azx *chip)
-{
- spin_lock_irq(&chip->reg_lock);
- /* CORB set up */
- chip->corb.addr = chip->rb.addr;
- chip->corb.buf = (u32 *)chip->rb.area;
- azx_writel(chip, CORBLBASE, (u32)chip->corb.addr);
- azx_writel(chip, CORBUBASE, upper_32_bits(chip->corb.addr));
-
- /* set the corb size to 256 entries (ULI requires explicitly) */
- azx_writeb(chip, CORBSIZE, 0x02);
- /* set the corb write pointer to 0 */
- azx_writew(chip, CORBWP, 0);
- /* reset the corb hw read pointer */
- azx_writew(chip, CORBRP, ICH6_CORBRP_RST);
- /* enable corb dma */
- azx_writeb(chip, CORBCTL, ICH6_CORBCTL_RUN);
-
- /* RIRB set up */
- chip->rirb.addr = chip->rb.addr + 2048;
- chip->rirb.buf = (u32 *)(chip->rb.area + 2048);
- chip->rirb.wp = chip->rirb.rp = 0;
- memset(chip->rirb.cmds, 0, sizeof(chip->rirb.cmds));
- azx_writel(chip, RIRBLBASE, (u32)chip->rirb.addr);
- azx_writel(chip, RIRBUBASE, upper_32_bits(chip->rirb.addr));
-
- /* set the rirb size to 256 entries (ULI requires explicitly) */
- azx_writeb(chip, RIRBSIZE, 0x02);
- /* reset the rirb hw write pointer */
- azx_writew(chip, RIRBWP, ICH6_RIRBWP_RST);
- /* set N=1, get RIRB response interrupt for new entry */
- if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND)
- azx_writew(chip, RINTCNT, 0xc0);
- else
- azx_writew(chip, RINTCNT, 1);
- /* enable rirb dma and response irq */
- azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN);
- spin_unlock_irq(&chip->reg_lock);
-}
-
-static void azx_free_cmd_io(struct azx *chip)
-{
- spin_lock_irq(&chip->reg_lock);
- /* disable ringbuffer DMAs */
- azx_writeb(chip, RIRBCTL, 0);
- azx_writeb(chip, CORBCTL, 0);
- spin_unlock_irq(&chip->reg_lock);
-}
-
-static unsigned int azx_command_addr(u32 cmd)
-{
- unsigned int addr = cmd >> 28;
-
- if (addr >= AZX_MAX_CODECS) {
- snd_BUG();
- addr = 0;
- }
-
- return addr;
-}
-
-static unsigned int azx_response_addr(u32 res)
-{
- unsigned int addr = res & 0xf;
-
- if (addr >= AZX_MAX_CODECS) {
- snd_BUG();
- addr = 0;
- }
-
- return addr;
-}
-
-/* send a command */
-static int azx_corb_send_cmd(struct hda_bus *bus, u32 val)
-{
- struct azx *chip = bus->private_data;
- unsigned int addr = azx_command_addr(val);
- unsigned int wp;
-
- spin_lock_irq(&chip->reg_lock);
-
- /* add command to corb */
- wp = azx_readb(chip, CORBWP);
- wp++;
- wp %= ICH6_MAX_CORB_ENTRIES;
-
- chip->rirb.cmds[addr]++;
- chip->corb.buf[wp] = cpu_to_le32(val);
- azx_writel(chip, CORBWP, wp);
-
- spin_unlock_irq(&chip->reg_lock);
-
- return 0;
-}
-
-#define ICH6_RIRB_EX_UNSOL_EV (1<<4)
-
-/* retrieve RIRB entry - called from interrupt handler */
-static void azx_update_rirb(struct azx *chip)
-{
- unsigned int rp, wp;
- unsigned int addr;
- u32 res, res_ex;
-
- wp = azx_readb(chip, RIRBWP);
- if (wp == chip->rirb.wp)
- return;
- chip->rirb.wp = wp;
-
- while (chip->rirb.rp != wp) {
- chip->rirb.rp++;
- chip->rirb.rp %= ICH6_MAX_RIRB_ENTRIES;
-
- rp = chip->rirb.rp << 1; /* an RIRB entry is 8-bytes */
- res_ex = le32_to_cpu(chip->rirb.buf[rp + 1]);
- res = le32_to_cpu(chip->rirb.buf[rp]);
- addr = azx_response_addr(res_ex);
- if (res_ex & ICH6_RIRB_EX_UNSOL_EV)
- snd_hda_queue_unsol_event(chip->bus, res, res_ex);
- else if (chip->rirb.cmds[addr]) {
- chip->rirb.res[addr] = res;
- smp_wmb();
- chip->rirb.cmds[addr]--;
- } else
- snd_printk(KERN_ERR SFX "spurious response %#x:%#x, "
- "last cmd=%#08x\n",
- res, res_ex,
- chip->last_cmd[addr]);
- }
-}
-
-/* receive a response */
-static unsigned int azx_rirb_get_response(struct hda_bus *bus,
- unsigned int addr)
-{
- struct azx *chip = bus->private_data;
- unsigned long timeout;
- unsigned long loopcounter;
- int do_poll = 0;
-
- again:
- timeout = jiffies + msecs_to_jiffies(1000);
-
- for (loopcounter = 0;; loopcounter++) {
- if (chip->polling_mode || do_poll) {
- spin_lock_irq(&chip->reg_lock);
- azx_update_rirb(chip);
- spin_unlock_irq(&chip->reg_lock);
- }
- if (!chip->rirb.cmds[addr]) {
- smp_rmb();
- bus->rirb_error = 0;
-
- if (!do_poll)
- chip->poll_count = 0;
- return chip->rirb.res[addr]; /* the last value */
- }
- if (time_after(jiffies, timeout))
- break;
- if (bus->needs_damn_long_delay || loopcounter > 3000)
- msleep(2); /* temporary workaround */
- else {
- udelay(10);
- cond_resched();
- }
- }
-
- if (!chip->polling_mode && chip->poll_count < 2) {
- snd_printdd(SFX "azx_get_response timeout, "
- "polling the codec once: last cmd=0x%08x\n",
- chip->last_cmd[addr]);
- do_poll = 1;
- chip->poll_count++;
- goto again;
- }
-
-
- if (!chip->polling_mode) {
- snd_printk(KERN_WARNING SFX "azx_get_response timeout, "
- "switching to polling mode: last cmd=0x%08x\n",
- chip->last_cmd[addr]);
- chip->polling_mode = 1;
- goto again;
- }
-
- if (chip->msi) {
- snd_printk(KERN_WARNING SFX "No response from codec, "
- "disabling MSI: last cmd=0x%08x\n",
- chip->last_cmd[addr]);
- free_irq(chip->irq, chip);
- chip->irq = -1;
- pci_disable_msi(chip->pci);
- chip->msi = 0;
- if (azx_acquire_irq(chip, 1) < 0) {
- bus->rirb_error = 1;
- return -1;
- }
- goto again;
- }
-
- if (chip->probing) {
- /* If this critical timeout happens during the codec probing
- * phase, this is likely an access to a non-existing codec
- * slot. Better to return an error and reset the system.
- */
- return -1;
- }
-
- /* a fatal communication error; need either to reset or to fallback
- * to the single_cmd mode
- */
- bus->rirb_error = 1;
- if (bus->allow_bus_reset && !bus->response_reset && !bus->in_reset) {
- bus->response_reset = 1;
- return -1; /* give a chance to retry */
- }
-
- snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, "
- "switching to single_cmd mode: last cmd=0x%08x\n",
- chip->last_cmd[addr]);
- chip->single_cmd = 1;
- bus->response_reset = 0;
- /* release CORB/RIRB */
- azx_free_cmd_io(chip);
- /* disable unsolicited responses */
- azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_UNSOL);
- return -1;
-}
-
-/*
- * Use the single immediate command instead of CORB/RIRB for simplicity
- *
- * Note: according to Intel, this is not preferred use. The command was
- * intended for the BIOS only, and may get confused with unsolicited
- * responses. So, we shouldn't use it for normal operation from the
- * driver.
- * I left the codes, however, for debugging/testing purposes.
- */
-
-/* receive a response */
-static int azx_single_wait_for_response(struct azx *chip, unsigned int addr)
-{
- int timeout = 50;
-
- while (timeout--) {
- /* check IRV busy bit */
- if (azx_readw(chip, IRS) & ICH6_IRS_VALID) {
- /* reuse rirb.res as the response return value */
- chip->rirb.res[addr] = azx_readl(chip, IR);
- return 0;
- }
- udelay(1);
- }
- if (printk_ratelimit())
- snd_printd(SFX "get_response timeout: IRS=0x%x\n",
- azx_readw(chip, IRS));
- chip->rirb.res[addr] = -1;
- return -EIO;
-}
-
-/* send a command */
-static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
-{
- struct azx *chip = bus->private_data;
- unsigned int addr = azx_command_addr(val);
- int timeout = 50;
-
- bus->rirb_error = 0;
- while (timeout--) {
- /* check ICB busy bit */
- if (!((azx_readw(chip, IRS) & ICH6_IRS_BUSY))) {
- /* Clear IRV valid bit */
- azx_writew(chip, IRS, azx_readw(chip, IRS) |
- ICH6_IRS_VALID);
- azx_writel(chip, IC, val);
- azx_writew(chip, IRS, azx_readw(chip, IRS) |
- ICH6_IRS_BUSY);
- return azx_single_wait_for_response(chip, addr);
- }
- udelay(1);
- }
- if (printk_ratelimit())
- snd_printd(SFX "send_cmd timeout: IRS=0x%x, val=0x%x\n",
- azx_readw(chip, IRS), val);
- return -EIO;
-}
-
-/* receive a response */
-static unsigned int azx_single_get_response(struct hda_bus *bus,
- unsigned int addr)
-{
- struct azx *chip = bus->private_data;
- return chip->rirb.res[addr];
-}
-
-/*
- * The below are the main callbacks from hda_codec.
- *
- * They are just the skeleton to call sub-callbacks according to the
- * current setting of chip->single_cmd.
- */
-
-/* send a command */
-static int azx_send_cmd(struct hda_bus *bus, unsigned int val)
-{
- struct azx *chip = bus->private_data;
-
- chip->last_cmd[azx_command_addr(val)] = val;
- if (chip->single_cmd)
- return azx_single_send_cmd(bus, val);
- else
- return azx_corb_send_cmd(bus, val);
-}
-
-/* get a response */
-static unsigned int azx_get_response(struct hda_bus *bus,
- unsigned int addr)
-{
- struct azx *chip = bus->private_data;
- if (chip->single_cmd)
- return azx_single_get_response(bus, addr);
- else
- return azx_rirb_get_response(bus, addr);
-}
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static void azx_power_notify(struct hda_bus *bus);
-#endif
-
-/* reset codec link */
-static int azx_reset(struct azx *chip, int full_reset)
-{
- int count;
-
- if (!full_reset)
- goto __skip;
-
- /* clear STATESTS */
- azx_writeb(chip, STATESTS, STATESTS_INT_MASK);
-
- /* reset controller */
- azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_RESET);
-
- count = 50;
- while (azx_readb(chip, GCTL) && --count)
- msleep(1);
-
- /* delay for >= 100us for codec PLL to settle per spec
- * Rev 0.9 section 5.5.1
- */
- msleep(1);
-
- /* Bring controller out of reset */
- azx_writeb(chip, GCTL, azx_readb(chip, GCTL) | ICH6_GCTL_RESET);
-
- count = 50;
- while (!azx_readb(chip, GCTL) && --count)
- msleep(1);
-
- /* Brent Chartrand said to wait >= 540us for codecs to initialize */
- msleep(1);
-
- __skip:
- /* check to see if controller is ready */
- if (!azx_readb(chip, GCTL)) {
- snd_printd(SFX "azx_reset: controller not ready!\n");
- return -EBUSY;
- }
-
- /* Accept unsolicited responses */
- if (!chip->single_cmd)
- azx_writel(chip, GCTL, azx_readl(chip, GCTL) |
- ICH6_GCTL_UNSOL);
-
- /* detect codecs */
- if (!chip->codec_mask) {
- chip->codec_mask = azx_readw(chip, STATESTS);
- snd_printdd(SFX "codec_mask = 0x%x\n", chip->codec_mask);
- }
-
- return 0;
-}
-
-
-/*
- * Lowlevel interface
- */
-
-/* enable interrupts */
-static void azx_int_enable(struct azx *chip)
-{
- /* enable controller CIE and GIE */
- azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) |
- ICH6_INT_CTRL_EN | ICH6_INT_GLOBAL_EN);
-}
-
-/* disable interrupts */
-static void azx_int_disable(struct azx *chip)
-{
- int i;
-
- /* disable interrupts in stream descriptor */
- for (i = 0; i < chip->num_streams; i++) {
- struct azx_dev *azx_dev = &chip->azx_dev[i];
- azx_sd_writeb(azx_dev, SD_CTL,
- azx_sd_readb(azx_dev, SD_CTL) & ~SD_INT_MASK);
- }
-
- /* disable SIE for all streams */
- azx_writeb(chip, INTCTL, 0);
-
- /* disable controller CIE and GIE */
- azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) &
- ~(ICH6_INT_CTRL_EN | ICH6_INT_GLOBAL_EN));
-}
-
-/* clear interrupts */
-static void azx_int_clear(struct azx *chip)
-{
- int i;
-
- /* clear stream status */
- for (i = 0; i < chip->num_streams; i++) {
- struct azx_dev *azx_dev = &chip->azx_dev[i];
- azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK);
- }
-
- /* clear STATESTS */
- azx_writeb(chip, STATESTS, STATESTS_INT_MASK);
-
- /* clear rirb status */
- azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
-
- /* clear int status */
- azx_writel(chip, INTSTS, ICH6_INT_CTRL_EN | ICH6_INT_ALL_STREAM);
-}
-
-/* start a stream */
-static void azx_stream_start(struct azx *chip, struct azx_dev *azx_dev)
-{
- /*
- * Before stream start, initialize parameter
- */
- azx_dev->insufficient = 1;
-
- /* enable SIE */
- azx_writel(chip, INTCTL,
- azx_readl(chip, INTCTL) | (1 << azx_dev->index));
- /* set DMA start and interrupt mask */
- azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) |
- SD_CTL_DMA_START | SD_INT_MASK);
-}
-
-/* stop DMA */
-static void azx_stream_clear(struct azx *chip, struct azx_dev *azx_dev)
-{
- azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) &
- ~(SD_CTL_DMA_START | SD_INT_MASK));
- azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */
-}
-
-/* stop a stream */
-static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
-{
- azx_stream_clear(chip, azx_dev);
- /* disable SIE */
- azx_writel(chip, INTCTL,
- azx_readl(chip, INTCTL) & ~(1 << azx_dev->index));
-}
-
-
-/*
- * reset and start the controller registers
- */
-static void azx_init_chip(struct azx *chip, int full_reset)
-{
- if (chip->initialized)
- return;
-
- /* reset controller */
- azx_reset(chip, full_reset);
-
- /* initialize interrupts */
- azx_int_clear(chip);
- azx_int_enable(chip);
-
- /* initialize the codec command I/O */
- if (!chip->single_cmd)
- azx_init_cmd_io(chip);
-
- /* program the position buffer */
- azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
- azx_writel(chip, DPUBASE, upper_32_bits(chip->posbuf.addr));
-
- chip->initialized = 1;
-}
-
-/*
- * initialize the PCI registers
- */
-/* update bits in a PCI register byte */
-static void update_pci_byte(struct pci_dev *pci, unsigned int reg,
- unsigned char mask, unsigned char val)
-{
- unsigned char data;
-
- pci_read_config_byte(pci, reg, &data);
- data &= ~mask;
- data |= (val & mask);
- pci_write_config_byte(pci, reg, data);
-}
-
-static void azx_init_pci(struct azx *chip)
-{
- /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
- * TCSEL == Traffic Class Select Register, which sets PCI express QOS
- * Ensuring these bits are 0 clears playback static on some HD Audio
- * codecs.
- * The PCI register TCSEL is defined in the Intel manuals.
- */
- if (!(chip->driver_caps & AZX_DCAPS_NO_TCSEL)) {
- snd_printdd(SFX "Clearing TCSEL\n");
- update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0);
- }
-
- /* For ATI SB450/600/700/800/900 and AMD Hudson azalia HD audio,
- * we need to enable snoop.
- */
- if (chip->driver_caps & AZX_DCAPS_ATI_SNOOP) {
- snd_printdd(SFX "Setting ATI snoop: %d\n", azx_snoop(chip));
- update_pci_byte(chip->pci,
- ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 0x07,
- azx_snoop(chip) ? ATI_SB450_HDAUDIO_ENABLE_SNOOP : 0);
- }
-
- /* For NVIDIA HDA, enable snoop */
- if (chip->driver_caps & AZX_DCAPS_NVIDIA_SNOOP) {
- snd_printdd(SFX "Setting Nvidia snoop: %d\n", azx_snoop(chip));
- update_pci_byte(chip->pci,
- NVIDIA_HDA_TRANSREG_ADDR,
- 0x0f, NVIDIA_HDA_ENABLE_COHBITS);
- update_pci_byte(chip->pci,
- NVIDIA_HDA_ISTRM_COH,
- 0x01, NVIDIA_HDA_ENABLE_COHBIT);
- update_pci_byte(chip->pci,
- NVIDIA_HDA_OSTRM_COH,
- 0x01, NVIDIA_HDA_ENABLE_COHBIT);
- }
-
- /* Enable SCH/PCH snoop if needed */
- if (chip->driver_caps & AZX_DCAPS_SCH_SNOOP) {
- unsigned short snoop;
- pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
- if ((!azx_snoop(chip) && !(snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)) ||
- (azx_snoop(chip) && (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP))) {
- snoop &= ~INTEL_SCH_HDA_DEVC_NOSNOOP;
- if (!azx_snoop(chip))
- snoop |= INTEL_SCH_HDA_DEVC_NOSNOOP;
- pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, snoop);
- pci_read_config_word(chip->pci,
- INTEL_SCH_HDA_DEVC, &snoop);
- }
- snd_printdd(SFX "SCH snoop: %s\n",
- (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)
- ? "Disabled" : "Enabled");
- }
-}
-
-
-static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev);
-
-/*
- * interrupt handler
- */
-static irqreturn_t azx_interrupt(int irq, void *dev_id)
-{
- struct azx *chip = dev_id;
- struct azx_dev *azx_dev;
- u32 status;
- u8 sd_status;
- int i, ok;
-
- spin_lock(&chip->reg_lock);
-
- status = azx_readl(chip, INTSTS);
- if (status == 0) {
- spin_unlock(&chip->reg_lock);
- return IRQ_NONE;
- }
-
- for (i = 0; i < chip->num_streams; i++) {
- azx_dev = &chip->azx_dev[i];
- if (status & azx_dev->sd_int_sta_mask) {
- sd_status = azx_sd_readb(azx_dev, SD_STS);
- azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK);
- if (!azx_dev->substream || !azx_dev->running ||
- !(sd_status & SD_INT_COMPLETE))
- continue;
- /* check whether this IRQ is really acceptable */
- ok = azx_position_ok(chip, azx_dev);
- if (ok == 1) {
- azx_dev->irq_pending = 0;
- spin_unlock(&chip->reg_lock);
- snd_pcm_period_elapsed(azx_dev->substream);
- spin_lock(&chip->reg_lock);
- } else if (ok == 0 && chip->bus && chip->bus->workq) {
- /* bogus IRQ, process it later */
- azx_dev->irq_pending = 1;
- queue_work(chip->bus->workq,
- &chip->irq_pending_work);
- }
- }
- }
-
- /* clear rirb int */
- status = azx_readb(chip, RIRBSTS);
- if (status & RIRB_INT_MASK) {
- if (status & RIRB_INT_RESPONSE) {
- if (chip->driver_caps & AZX_DCAPS_RIRB_PRE_DELAY)
- udelay(80);
- azx_update_rirb(chip);
- }
- azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
- }
-
-#if 0
- /* clear state status int */
- if (azx_readb(chip, STATESTS) & 0x04)
- azx_writeb(chip, STATESTS, 0x04);
-#endif
- spin_unlock(&chip->reg_lock);
-
- return IRQ_HANDLED;
-}
-
-
-/*
- * set up a BDL entry
- */
-static int setup_bdle(struct snd_pcm_substream *substream,
- struct azx_dev *azx_dev, u32 **bdlp,
- int ofs, int size, int with_ioc)
-{
- u32 *bdl = *bdlp;
-
- while (size > 0) {
- dma_addr_t addr;
- int chunk;
-
- if (azx_dev->frags >= AZX_MAX_BDL_ENTRIES)
- return -EINVAL;
-
- addr = snd_pcm_sgbuf_get_addr(substream, ofs);
- /* program the address field of the BDL entry */
- bdl[0] = cpu_to_le32((u32)addr);
- bdl[1] = cpu_to_le32(upper_32_bits(addr));
- /* program the size field of the BDL entry */
- chunk = snd_pcm_sgbuf_get_chunk_size(substream, ofs, size);
- bdl[2] = cpu_to_le32(chunk);
- /* program the IOC to enable interrupt
- * only when the whole fragment is processed
- */
- size -= chunk;
- bdl[3] = (size || !with_ioc) ? 0 : cpu_to_le32(0x01);
- bdl += 4;
- azx_dev->frags++;
- ofs += chunk;
- }
- *bdlp = bdl;
- return ofs;
-}
-
-/*
- * set up BDL entries
- */
-static int azx_setup_periods(struct azx *chip,
- struct snd_pcm_substream *substream,
- struct azx_dev *azx_dev)
-{
- u32 *bdl;
- int i, ofs, periods, period_bytes;
- int pos_adj;
-
- /* reset BDL address */
- azx_sd_writel(azx_dev, SD_BDLPL, 0);
- azx_sd_writel(azx_dev, SD_BDLPU, 0);
-
- period_bytes = azx_dev->period_bytes;
- periods = azx_dev->bufsize / period_bytes;
-
- /* program the initial BDL entries */
- bdl = (u32 *)azx_dev->bdl.area;
- ofs = 0;
- azx_dev->frags = 0;
- pos_adj = bdl_pos_adj[chip->dev_index];
- if (pos_adj > 0) {
- struct snd_pcm_runtime *runtime = substream->runtime;
- int pos_align = pos_adj;
- pos_adj = (pos_adj * runtime->rate + 47999) / 48000;
- if (!pos_adj)
- pos_adj = pos_align;
- else
- pos_adj = ((pos_adj + pos_align - 1) / pos_align) *
- pos_align;
- pos_adj = frames_to_bytes(runtime, pos_adj);
- if (pos_adj >= period_bytes) {
- snd_printk(KERN_WARNING SFX "Too big adjustment %d\n",
- bdl_pos_adj[chip->dev_index]);
- pos_adj = 0;
- } else {
- ofs = setup_bdle(substream, azx_dev,
- &bdl, ofs, pos_adj,
- !substream->runtime->no_period_wakeup);
- if (ofs < 0)
- goto error;
- }
- } else
- pos_adj = 0;
- for (i = 0; i < periods; i++) {
- if (i == periods - 1 && pos_adj)
- ofs = setup_bdle(substream, azx_dev, &bdl, ofs,
- period_bytes - pos_adj, 0);
- else
- ofs = setup_bdle(substream, azx_dev, &bdl, ofs,
- period_bytes,
- !substream->runtime->no_period_wakeup);
- if (ofs < 0)
- goto error;
- }
- return 0;
-
- error:
- snd_printk(KERN_ERR SFX "Too many BDL entries: buffer=%d, period=%d\n",
- azx_dev->bufsize, period_bytes);
- return -EINVAL;
-}
-
-/* reset stream */
-static void azx_stream_reset(struct azx *chip, struct azx_dev *azx_dev)
-{
- unsigned char val;
- int timeout;
-
- azx_stream_clear(chip, azx_dev);
-
- azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) |
- SD_CTL_STREAM_RESET);
- udelay(3);
- timeout = 300;
- while (!((val = azx_sd_readb(azx_dev, SD_CTL)) & SD_CTL_STREAM_RESET) &&
- --timeout)
- ;
- val &= ~SD_CTL_STREAM_RESET;
- azx_sd_writeb(azx_dev, SD_CTL, val);
- udelay(3);
-
- timeout = 300;
- /* waiting for hardware to report that the stream is out of reset */
- while (((val = azx_sd_readb(azx_dev, SD_CTL)) & SD_CTL_STREAM_RESET) &&
- --timeout)
- ;
-
- /* reset first position - may not be synced with hw at this time */
- *azx_dev->posbuf = 0;
-}
-
-/*
- * set up the SD for streaming
- */
-static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
-{
- unsigned int val;
- /* make sure the run bit is zero for SD */
- azx_stream_clear(chip, azx_dev);
- /* program the stream_tag */
- val = azx_sd_readl(azx_dev, SD_CTL);
- val = (val & ~SD_CTL_STREAM_TAG_MASK) |
- (azx_dev->stream_tag << SD_CTL_STREAM_TAG_SHIFT);
- if (!azx_snoop(chip))
- val |= SD_CTL_TRAFFIC_PRIO;
- azx_sd_writel(azx_dev, SD_CTL, val);
-
- /* program the length of samples in cyclic buffer */
- azx_sd_writel(azx_dev, SD_CBL, azx_dev->bufsize);
-
- /* program the stream format */
- /* this value needs to be the same as the one programmed */
- azx_sd_writew(azx_dev, SD_FORMAT, azx_dev->format_val);
-
- /* program the stream LVI (last valid index) of the BDL */
- azx_sd_writew(azx_dev, SD_LVI, azx_dev->frags - 1);
-
- /* program the BDL address */
- /* lower BDL address */
- azx_sd_writel(azx_dev, SD_BDLPL, (u32)azx_dev->bdl.addr);
- /* upper BDL address */
- azx_sd_writel(azx_dev, SD_BDLPU, upper_32_bits(azx_dev->bdl.addr));
-
- /* enable the position buffer */
- if (chip->position_fix[0] != POS_FIX_LPIB ||
- chip->position_fix[1] != POS_FIX_LPIB) {
- if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
- azx_writel(chip, DPLBASE,
- (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE);
- }
-
- /* set the interrupt enable bits in the descriptor control register */
- azx_sd_writel(azx_dev, SD_CTL,
- azx_sd_readl(azx_dev, SD_CTL) | SD_INT_MASK);
-
- return 0;
-}
-
-/*
- * Probe the given codec address
- */
-static int probe_codec(struct azx *chip, int addr)
-{
- unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) |
- (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
- unsigned int res;
-
- mutex_lock(&chip->bus->cmd_mutex);
- chip->probing = 1;
- azx_send_cmd(chip->bus, cmd);
- res = azx_get_response(chip->bus, addr);
- chip->probing = 0;
- mutex_unlock(&chip->bus->cmd_mutex);
- if (res == -1)
- return -EIO;
- snd_printdd(SFX "codec #%d probed OK\n", addr);
- return 0;
-}
-
-static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
- struct hda_pcm *cpcm);
-static void azx_stop_chip(struct azx *chip);
-
-static void azx_bus_reset(struct hda_bus *bus)
-{
- struct azx *chip = bus->private_data;
-
- bus->in_reset = 1;
- azx_stop_chip(chip);
- azx_init_chip(chip, 1);
-#ifdef CONFIG_PM
- if (chip->initialized) {
- struct azx_pcm *p;
- list_for_each_entry(p, &chip->pcm_list, list)
- snd_pcm_suspend_all(p->pcm);
- snd_hda_suspend(chip->bus);
- snd_hda_resume(chip->bus);
- }
-#endif
- bus->in_reset = 0;
-}
-
-/*
- * Codec initialization
- */
-
-/* number of codec slots for each chipset: 0 = default slots (i.e. 4) */
-static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = {
- [AZX_DRIVER_NVIDIA] = 8,
- [AZX_DRIVER_TERA] = 1,
-};
-
-static int __devinit azx_codec_create(struct azx *chip, const char *model)
-{
- struct hda_bus_template bus_temp;
- int c, codecs, err;
- int max_slots;
-
- memset(&bus_temp, 0, sizeof(bus_temp));
- bus_temp.private_data = chip;
- bus_temp.modelname = model;
- bus_temp.pci = chip->pci;
- bus_temp.ops.command = azx_send_cmd;
- bus_temp.ops.get_response = azx_get_response;
- bus_temp.ops.attach_pcm = azx_attach_pcm_stream;
- bus_temp.ops.bus_reset = azx_bus_reset;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- bus_temp.power_save = &power_save;
- bus_temp.ops.pm_notify = azx_power_notify;
-#endif
-
- err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus);
- if (err < 0)
- return err;
-
- if (chip->driver_caps & AZX_DCAPS_RIRB_DELAY) {
- snd_printd(SFX "Enable delay in RIRB handling\n");
- chip->bus->needs_damn_long_delay = 1;
- }
-
- codecs = 0;
- max_slots = azx_max_codecs[chip->driver_type];
- if (!max_slots)
- max_slots = AZX_DEFAULT_CODECS;
-
- /* First try to probe all given codec slots */
- for (c = 0; c < max_slots; c++) {
- if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) {
- if (probe_codec(chip, c) < 0) {
- /* Some BIOSen give you wrong codec addresses
- * that don't exist
- */
- snd_printk(KERN_WARNING SFX
- "Codec #%d probe error; "
- "disabling it...\n", c);
- chip->codec_mask &= ~(1 << c);
- /* More badly, accessing to a non-existing
- * codec often screws up the controller chip,
- * and disturbs the further communications.
- * Thus if an error occurs during probing,
- * better to reset the controller chip to
- * get back to the sanity state.
- */
- azx_stop_chip(chip);
- azx_init_chip(chip, 1);
- }
- }
- }
-
- /* AMD chipsets often cause the communication stalls upon certain
- * sequence like the pin-detection. It seems that forcing the synced
- * access works around the stall. Grrr...
- */
- if (chip->driver_caps & AZX_DCAPS_SYNC_WRITE) {
- snd_printd(SFX "Enable sync_write for stable communication\n");
- chip->bus->sync_write = 1;
- chip->bus->allow_bus_reset = 1;
- }
-
- /* Then create codec instances */
- for (c = 0; c < max_slots; c++) {
- if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) {
- struct hda_codec *codec;
- err = snd_hda_codec_new(chip->bus, c, &codec);
- if (err < 0)
- continue;
- codec->beep_mode = chip->beep_mode;
- codecs++;
- }
- }
- if (!codecs) {
- snd_printk(KERN_ERR SFX "no codecs initialized\n");
- return -ENXIO;
- }
- return 0;
-}
-
-/* configure each codec instance */
-static int __devinit azx_codec_configure(struct azx *chip)
-{
- struct hda_codec *codec;
- list_for_each_entry(codec, &chip->bus->codec_list, list) {
- snd_hda_codec_configure(codec);
- }
- return 0;
-}
-
-
-/*
- * PCM support
- */
-
-/* assign a stream for the PCM */
-static inline struct azx_dev *
-azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream)
-{
- int dev, i, nums;
- struct azx_dev *res = NULL;
- /* make a non-zero unique key for the substream */
- int key = (substream->pcm->device << 16) | (substream->number << 2) |
- (substream->stream + 1);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- dev = chip->playback_index_offset;
- nums = chip->playback_streams;
- } else {
- dev = chip->capture_index_offset;
- nums = chip->capture_streams;
- }
- for (i = 0; i < nums; i++, dev++)
- if (!chip->azx_dev[dev].opened) {
- res = &chip->azx_dev[dev];
- if (res->assigned_key == key)
- break;
- }
- if (res) {
- res->opened = 1;
- res->assigned_key = key;
- }
- return res;
-}
-
-/* release the assigned stream */
-static inline void azx_release_device(struct azx_dev *azx_dev)
-{
- azx_dev->opened = 0;
-}
-
-static struct snd_pcm_hardware azx_pcm_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- /* No full-resume yet implemented */
- /* SNDRV_PCM_INFO_RESUME |*/
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START |
- SNDRV_PCM_INFO_NO_PERIOD_WAKEUP),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = AZX_MAX_BUF_SIZE,
- .period_bytes_min = 128,
- .period_bytes_max = AZX_MAX_BUF_SIZE / 2,
- .periods_min = 2,
- .periods_max = AZX_MAX_FRAG,
- .fifo_size = 0,
-};
-
-static int azx_pcm_open(struct snd_pcm_substream *substream)
-{
- struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
- struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
- struct azx *chip = apcm->chip;
- struct azx_dev *azx_dev;
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long flags;
- int err;
- int buff_step;
-
- mutex_lock(&chip->open_mutex);
- azx_dev = azx_assign_device(chip, substream);
- if (azx_dev == NULL) {
- mutex_unlock(&chip->open_mutex);
- return -EBUSY;
- }
- runtime->hw = azx_pcm_hw;
- runtime->hw.channels_min = hinfo->channels_min;
- runtime->hw.channels_max = hinfo->channels_max;
- runtime->hw.formats = hinfo->formats;
- runtime->hw.rates = hinfo->rates;
- snd_pcm_limit_hw_rates(runtime);
- snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
- if (chip->align_buffer_size)
- /* constrain buffer sizes to be multiple of 128
- bytes. This is more efficient in terms of memory
- access but isn't required by the HDA spec and
- prevents users from specifying exact period/buffer
- sizes. For example for 44.1kHz, a period size set
- to 20ms will be rounded to 19.59ms. */
- buff_step = 128;
- else
- /* Don't enforce steps on buffer sizes, still need to
- be multiple of 4 bytes (HDA spec). Tested on Intel
- HDA controllers, may not work on all devices where
- option needs to be disabled */
- buff_step = 4;
-
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
- buff_step);
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- buff_step);
- snd_hda_power_up(apcm->codec);
- err = hinfo->ops.open(hinfo, apcm->codec, substream);
- if (err < 0) {
- azx_release_device(azx_dev);
- snd_hda_power_down(apcm->codec);
- mutex_unlock(&chip->open_mutex);
- return err;
- }
- snd_pcm_limit_hw_rates(runtime);
- /* sanity check */
- if (snd_BUG_ON(!runtime->hw.channels_min) ||
- snd_BUG_ON(!runtime->hw.channels_max) ||
- snd_BUG_ON(!runtime->hw.formats) ||
- snd_BUG_ON(!runtime->hw.rates)) {
- azx_release_device(azx_dev);
- hinfo->ops.close(hinfo, apcm->codec, substream);
- snd_hda_power_down(apcm->codec);
- mutex_unlock(&chip->open_mutex);
- return -EINVAL;
- }
- spin_lock_irqsave(&chip->reg_lock, flags);
- azx_dev->substream = substream;
- azx_dev->running = 0;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- runtime->private_data = azx_dev;
- snd_pcm_set_sync(substream);
- mutex_unlock(&chip->open_mutex);
- return 0;
-}
-
-static int azx_pcm_close(struct snd_pcm_substream *substream)
-{
- struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
- struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
- struct azx *chip = apcm->chip;
- struct azx_dev *azx_dev = get_azx_dev(substream);
- unsigned long flags;
-
- mutex_lock(&chip->open_mutex);
- spin_lock_irqsave(&chip->reg_lock, flags);
- azx_dev->substream = NULL;
- azx_dev->running = 0;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- azx_release_device(azx_dev);
- hinfo->ops.close(hinfo, apcm->codec, substream);
- snd_hda_power_down(apcm->codec);
- mutex_unlock(&chip->open_mutex);
- return 0;
-}
-
-static int azx_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
- struct azx *chip = apcm->chip;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct azx_dev *azx_dev = get_azx_dev(substream);
- int ret;
-
- mark_runtime_wc(chip, azx_dev, runtime, false);
- azx_dev->bufsize = 0;
- azx_dev->period_bytes = 0;
- azx_dev->format_val = 0;
- ret = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- if (ret < 0)
- return ret;
- mark_runtime_wc(chip, azx_dev, runtime, true);
- return ret;
-}
-
-static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
- struct azx_dev *azx_dev = get_azx_dev(substream);
- struct azx *chip = apcm->chip;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
-
- /* reset BDL address */
- azx_sd_writel(azx_dev, SD_BDLPL, 0);
- azx_sd_writel(azx_dev, SD_BDLPU, 0);
- azx_sd_writel(azx_dev, SD_CTL, 0);
- azx_dev->bufsize = 0;
- azx_dev->period_bytes = 0;
- azx_dev->format_val = 0;
-
- snd_hda_codec_cleanup(apcm->codec, hinfo, substream);
-
- mark_runtime_wc(chip, azx_dev, runtime, false);
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int azx_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
- struct azx *chip = apcm->chip;
- struct azx_dev *azx_dev = get_azx_dev(substream);
- struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int bufsize, period_bytes, format_val, stream_tag;
- int err;
- struct hda_spdif_out *spdif =
- snd_hda_spdif_out_of_nid(apcm->codec, hinfo->nid);
- unsigned short ctls = spdif ? spdif->ctls : 0;
-
- azx_stream_reset(chip, azx_dev);
- format_val = snd_hda_calc_stream_format(runtime->rate,
- runtime->channels,
- runtime->format,
- hinfo->maxbps,
- ctls);
- if (!format_val) {
- snd_printk(KERN_ERR SFX
- "invalid format_val, rate=%d, ch=%d, format=%d\n",
- runtime->rate, runtime->channels, runtime->format);
- return -EINVAL;
- }
-
- bufsize = snd_pcm_lib_buffer_bytes(substream);
- period_bytes = snd_pcm_lib_period_bytes(substream);
-
- snd_printdd(SFX "azx_pcm_prepare: bufsize=0x%x, format=0x%x\n",
- bufsize, format_val);
-
- if (bufsize != azx_dev->bufsize ||
- period_bytes != azx_dev->period_bytes ||
- format_val != azx_dev->format_val) {
- azx_dev->bufsize = bufsize;
- azx_dev->period_bytes = period_bytes;
- azx_dev->format_val = format_val;
- err = azx_setup_periods(chip, substream, azx_dev);
- if (err < 0)
- return err;
- }
-
- /* wallclk has 24Mhz clock source */
- azx_dev->period_wallclk = (((runtime->period_size * 24000) /
- runtime->rate) * 1000);
- azx_setup_controller(chip, azx_dev);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1;
- else
- azx_dev->fifo_size = 0;
-
- stream_tag = azx_dev->stream_tag;
- /* CA-IBG chips need the playback stream starting from 1 */
- if ((chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) &&
- stream_tag > chip->capture_streams)
- stream_tag -= chip->capture_streams;
- return snd_hda_codec_prepare(apcm->codec, hinfo, stream_tag,
- azx_dev->format_val, substream);
-}
-
-static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
- struct azx *chip = apcm->chip;
- struct azx_dev *azx_dev;
- struct snd_pcm_substream *s;
- int rstart = 0, start, nsync = 0, sbits = 0;
- int nwait, timeout;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- rstart = 1;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
- start = 1;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_STOP:
- start = 0;
- break;
- default:
- return -EINVAL;
- }
-
- snd_pcm_group_for_each_entry(s, substream) {
- if (s->pcm->card != substream->pcm->card)
- continue;
- azx_dev = get_azx_dev(s);
- sbits |= 1 << azx_dev->index;
- nsync++;
- snd_pcm_trigger_done(s, substream);
- }
-
- spin_lock(&chip->reg_lock);
- if (nsync > 1) {
- /* first, set SYNC bits of corresponding streams */
- if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
- azx_writel(chip, OLD_SSYNC,
- azx_readl(chip, OLD_SSYNC) | sbits);
- else
- azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) | sbits);
- }
- snd_pcm_group_for_each_entry(s, substream) {
- if (s->pcm->card != substream->pcm->card)
- continue;
- azx_dev = get_azx_dev(s);
- if (start) {
- azx_dev->start_wallclk = azx_readl(chip, WALLCLK);
- if (!rstart)
- azx_dev->start_wallclk -=
- azx_dev->period_wallclk;
- azx_stream_start(chip, azx_dev);
- } else {
- azx_stream_stop(chip, azx_dev);
- }
- azx_dev->running = start;
- }
- spin_unlock(&chip->reg_lock);
- if (start) {
- if (nsync == 1)
- return 0;
- /* wait until all FIFOs get ready */
- for (timeout = 5000; timeout; timeout--) {
- nwait = 0;
- snd_pcm_group_for_each_entry(s, substream) {
- if (s->pcm->card != substream->pcm->card)
- continue;
- azx_dev = get_azx_dev(s);
- if (!(azx_sd_readb(azx_dev, SD_STS) &
- SD_STS_FIFO_READY))
- nwait++;
- }
- if (!nwait)
- break;
- cpu_relax();
- }
- } else {
- /* wait until all RUN bits are cleared */
- for (timeout = 5000; timeout; timeout--) {
- nwait = 0;
- snd_pcm_group_for_each_entry(s, substream) {
- if (s->pcm->card != substream->pcm->card)
- continue;
- azx_dev = get_azx_dev(s);
- if (azx_sd_readb(azx_dev, SD_CTL) &
- SD_CTL_DMA_START)
- nwait++;
- }
- if (!nwait)
- break;
- cpu_relax();
- }
- }
- if (nsync > 1) {
- spin_lock(&chip->reg_lock);
- /* reset SYNC bits */
- if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
- azx_writel(chip, OLD_SSYNC,
- azx_readl(chip, OLD_SSYNC) & ~sbits);
- else
- azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) & ~sbits);
- spin_unlock(&chip->reg_lock);
- }
- return 0;
-}
-
-/* get the current DMA position with correction on VIA chips */
-static unsigned int azx_via_get_position(struct azx *chip,
- struct azx_dev *azx_dev)
-{
- unsigned int link_pos, mini_pos, bound_pos;
- unsigned int mod_link_pos, mod_dma_pos, mod_mini_pos;
- unsigned int fifo_size;
-
- link_pos = azx_sd_readl(azx_dev, SD_LPIB);
- if (azx_dev->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- /* Playback, no problem using link position */
- return link_pos;
- }
-
- /* Capture */
- /* For new chipset,
- * use mod to get the DMA position just like old chipset
- */
- mod_dma_pos = le32_to_cpu(*azx_dev->posbuf);
- mod_dma_pos %= azx_dev->period_bytes;
-
- /* azx_dev->fifo_size can't get FIFO size of in stream.
- * Get from base address + offset.
- */
- fifo_size = readw(chip->remap_addr + VIA_IN_STREAM0_FIFO_SIZE_OFFSET);
-
- if (azx_dev->insufficient) {
- /* Link position never gather than FIFO size */
- if (link_pos <= fifo_size)
- return 0;
-
- azx_dev->insufficient = 0;
- }
-
- if (link_pos <= fifo_size)
- mini_pos = azx_dev->bufsize + link_pos - fifo_size;
- else
- mini_pos = link_pos - fifo_size;
-
- /* Find nearest previous boudary */
- mod_mini_pos = mini_pos % azx_dev->period_bytes;
- mod_link_pos = link_pos % azx_dev->period_bytes;
- if (mod_link_pos >= fifo_size)
- bound_pos = link_pos - mod_link_pos;
- else if (mod_dma_pos >= mod_mini_pos)
- bound_pos = mini_pos - mod_mini_pos;
- else {
- bound_pos = mini_pos - mod_mini_pos + azx_dev->period_bytes;
- if (bound_pos >= azx_dev->bufsize)
- bound_pos = 0;
- }
-
- /* Calculate real DMA position we want */
- return bound_pos + mod_dma_pos;
-}
-
-static unsigned int azx_get_position(struct azx *chip,
- struct azx_dev *azx_dev,
- bool with_check)
-{
- unsigned int pos;
- int stream = azx_dev->substream->stream;
-
- switch (chip->position_fix[stream]) {
- case POS_FIX_LPIB:
- /* read LPIB */
- pos = azx_sd_readl(azx_dev, SD_LPIB);
- break;
- case POS_FIX_VIACOMBO:
- pos = azx_via_get_position(chip, azx_dev);
- break;
- default:
- /* use the position buffer */
- pos = le32_to_cpu(*azx_dev->posbuf);
- if (with_check && chip->position_fix[stream] == POS_FIX_AUTO) {
- if (!pos || pos == (u32)-1) {
- printk(KERN_WARNING
- "hda-intel: Invalid position buffer, "
- "using LPIB read method instead.\n");
- chip->position_fix[stream] = POS_FIX_LPIB;
- pos = azx_sd_readl(azx_dev, SD_LPIB);
- } else
- chip->position_fix[stream] = POS_FIX_POSBUF;
- }
- break;
- }
-
- if (pos >= azx_dev->bufsize)
- pos = 0;
- return pos;
-}
-
-static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
- struct azx *chip = apcm->chip;
- struct azx_dev *azx_dev = get_azx_dev(substream);
- return bytes_to_frames(substream->runtime,
- azx_get_position(chip, azx_dev, false));
-}
-
-/*
- * Check whether the current DMA position is acceptable for updating
- * periods. Returns non-zero if it's OK.
- *
- * Many HD-audio controllers appear pretty inaccurate about
- * the update-IRQ timing. The IRQ is issued before actually the
- * data is processed. So, we need to process it afterwords in a
- * workqueue.
- */
-static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
-{
- u32 wallclk;
- unsigned int pos;
- int stream;
-
- wallclk = azx_readl(chip, WALLCLK) - azx_dev->start_wallclk;
- if (wallclk < (azx_dev->period_wallclk * 2) / 3)
- return -1; /* bogus (too early) interrupt */
-
- stream = azx_dev->substream->stream;
- pos = azx_get_position(chip, azx_dev, true);
-
- if (WARN_ONCE(!azx_dev->period_bytes,
- "hda-intel: zero azx_dev->period_bytes"))
- return -1; /* this shouldn't happen! */
- if (wallclk < (azx_dev->period_wallclk * 5) / 4 &&
- pos % azx_dev->period_bytes > azx_dev->period_bytes / 2)
- /* NG - it's below the first next period boundary */
- return bdl_pos_adj[chip->dev_index] ? 0 : -1;
- azx_dev->start_wallclk += wallclk;
- return 1; /* OK, it's fine */
-}
-
-/*
- * The work for pending PCM period updates.
- */
-static void azx_irq_pending_work(struct work_struct *work)
-{
- struct azx *chip = container_of(work, struct azx, irq_pending_work);
- int i, pending, ok;
-
- if (!chip->irq_pending_warned) {
- printk(KERN_WARNING
- "hda-intel: IRQ timing workaround is activated "
- "for card #%d. Suggest a bigger bdl_pos_adj.\n",
- chip->card->number);
- chip->irq_pending_warned = 1;
- }
-
- for (;;) {
- pending = 0;
- spin_lock_irq(&chip->reg_lock);
- for (i = 0; i < chip->num_streams; i++) {
- struct azx_dev *azx_dev = &chip->azx_dev[i];
- if (!azx_dev->irq_pending ||
- !azx_dev->substream ||
- !azx_dev->running)
- continue;
- ok = azx_position_ok(chip, azx_dev);
- if (ok > 0) {
- azx_dev->irq_pending = 0;
- spin_unlock(&chip->reg_lock);
- snd_pcm_period_elapsed(azx_dev->substream);
- spin_lock(&chip->reg_lock);
- } else if (ok < 0) {
- pending = 0; /* too early */
- } else
- pending++;
- }
- spin_unlock_irq(&chip->reg_lock);
- if (!pending)
- return;
- msleep(1);
- }
-}
-
-/* clear irq_pending flags and assure no on-going workq */
-static void azx_clear_irq_pending(struct azx *chip)
-{
- int i;
-
- spin_lock_irq(&chip->reg_lock);
- for (i = 0; i < chip->num_streams; i++)
- chip->azx_dev[i].irq_pending = 0;
- spin_unlock_irq(&chip->reg_lock);
-}
-
-#ifdef CONFIG_X86
-static int azx_pcm_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *area)
-{
- struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
- struct azx *chip = apcm->chip;
- if (!azx_snoop(chip))
- area->vm_page_prot = pgprot_writecombine(area->vm_page_prot);
- return snd_pcm_lib_default_mmap(substream, area);
-}
-#else
-#define azx_pcm_mmap NULL
-#endif
-
-static struct snd_pcm_ops azx_pcm_ops = {
- .open = azx_pcm_open,
- .close = azx_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = azx_pcm_hw_params,
- .hw_free = azx_pcm_hw_free,
- .prepare = azx_pcm_prepare,
- .trigger = azx_pcm_trigger,
- .pointer = azx_pcm_pointer,
- .mmap = azx_pcm_mmap,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
-static void azx_pcm_free(struct snd_pcm *pcm)
-{
- struct azx_pcm *apcm = pcm->private_data;
- if (apcm) {
- list_del(&apcm->list);
- kfree(apcm);
- }
-}
-
-#define MAX_PREALLOC_SIZE (32 * 1024 * 1024)
-
-static int
-azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
- struct hda_pcm *cpcm)
-{
- struct azx *chip = bus->private_data;
- struct snd_pcm *pcm;
- struct azx_pcm *apcm;
- int pcm_dev = cpcm->device;
- unsigned int size;
- int s, err;
-
- list_for_each_entry(apcm, &chip->pcm_list, list) {
- if (apcm->pcm->device == pcm_dev) {
- snd_printk(KERN_ERR SFX "PCM %d already exists\n", pcm_dev);
- return -EBUSY;
- }
- }
- err = snd_pcm_new(chip->card, cpcm->name, pcm_dev,
- cpcm->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams,
- cpcm->stream[SNDRV_PCM_STREAM_CAPTURE].substreams,
- &pcm);
- if (err < 0)
- return err;
- strlcpy(pcm->name, cpcm->name, sizeof(pcm->name));
- apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
- if (apcm == NULL)
- return -ENOMEM;
- apcm->chip = chip;
- apcm->pcm = pcm;
- apcm->codec = codec;
- pcm->private_data = apcm;
- pcm->private_free = azx_pcm_free;
- if (cpcm->pcm_type == HDA_PCM_TYPE_MODEM)
- pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
- list_add_tail(&apcm->list, &chip->pcm_list);
- cpcm->pcm = pcm;
- for (s = 0; s < 2; s++) {
- apcm->hinfo[s] = &cpcm->stream[s];
- if (cpcm->stream[s].substreams)
- snd_pcm_set_ops(pcm, s, &azx_pcm_ops);
- }
- /* buffer pre-allocation */
- size = CONFIG_SND_HDA_PREALLOC_SIZE * 1024;
- if (size > MAX_PREALLOC_SIZE)
- size = MAX_PREALLOC_SIZE;
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(chip->pci),
- size, MAX_PREALLOC_SIZE);
- return 0;
-}
-
-/*
- * mixer creation - all stuff is implemented in hda module
- */
-static int __devinit azx_mixer_create(struct azx *chip)
-{
- return snd_hda_build_controls(chip->bus);
-}
-
-
-/*
- * initialize SD streams
- */
-static int __devinit azx_init_stream(struct azx *chip)
-{
- int i;
-
- /* initialize each stream (aka device)
- * assign the starting bdl address to each stream (device)
- * and initialize
- */
- for (i = 0; i < chip->num_streams; i++) {
- struct azx_dev *azx_dev = &chip->azx_dev[i];
- azx_dev->posbuf = (u32 __iomem *)(chip->posbuf.area + i * 8);
- /* offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */
- azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80);
- /* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */
- azx_dev->sd_int_sta_mask = 1 << i;
- /* stream tag: must be non-zero and unique */
- azx_dev->index = i;
- azx_dev->stream_tag = i + 1;
- }
-
- return 0;
-}
-
-static int azx_acquire_irq(struct azx *chip, int do_disconnect)
-{
- if (request_irq(chip->pci->irq, azx_interrupt,
- chip->msi ? 0 : IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
- printk(KERN_ERR "hda-intel: unable to grab IRQ %d, "
- "disabling device\n", chip->pci->irq);
- if (do_disconnect)
- snd_card_disconnect(chip->card);
- return -1;
- }
- chip->irq = chip->pci->irq;
- pci_intx(chip->pci, !chip->msi);
- return 0;
-}
-
-
-static void azx_stop_chip(struct azx *chip)
-{
- if (!chip->initialized)
- return;
-
- /* disable interrupts */
- azx_int_disable(chip);
- azx_int_clear(chip);
-
- /* disable CORB/RIRB */
- azx_free_cmd_io(chip);
-
- /* disable position buffer */
- azx_writel(chip, DPLBASE, 0);
- azx_writel(chip, DPUBASE, 0);
-
- chip->initialized = 0;
-}
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-/* power-up/down the controller */
-static void azx_power_notify(struct hda_bus *bus)
-{
- struct azx *chip = bus->private_data;
- struct hda_codec *c;
- int power_on = 0;
-
- list_for_each_entry(c, &bus->codec_list, list) {
- if (c->power_on) {
- power_on = 1;
- break;
- }
- }
- if (power_on)
- azx_init_chip(chip, 1);
- else if (chip->running && power_save_controller &&
- !bus->power_keep_link_on)
- azx_stop_chip(chip);
-}
-#endif /* CONFIG_SND_HDA_POWER_SAVE */
-
-#ifdef CONFIG_PM
-/*
- * power management
- */
-
-static int snd_hda_codecs_inuse(struct hda_bus *bus)
-{
- struct hda_codec *codec;
-
- list_for_each_entry(codec, &bus->codec_list, list) {
- if (snd_hda_codec_needs_resume(codec))
- return 1;
- }
- return 0;
-}
-
-static int azx_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct azx *chip = card->private_data;
- struct azx_pcm *p;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- azx_clear_irq_pending(chip);
- list_for_each_entry(p, &chip->pcm_list, list)
- snd_pcm_suspend_all(p->pcm);
- if (chip->initialized)
- snd_hda_suspend(chip->bus);
- azx_stop_chip(chip);
- if (chip->irq >= 0) {
- free_irq(chip->irq, chip);
- chip->irq = -1;
- }
- if (chip->msi)
- pci_disable_msi(chip->pci);
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int azx_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct azx *chip = card->private_data;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "hda-intel: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
- if (chip->msi)
- if (pci_enable_msi(pci) < 0)
- chip->msi = 0;
- if (azx_acquire_irq(chip, 1) < 0)
- return -EIO;
- azx_init_pci(chip);
-
- if (snd_hda_codecs_inuse(chip->bus))
- azx_init_chip(chip, 1);
-
- snd_hda_resume(chip->bus);
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif /* CONFIG_PM */
-
-
-/*
- * reboot notifier for hang-up problem at power-down
- */
-static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf)
-{
- struct azx *chip = container_of(nb, struct azx, reboot_notifier);
- snd_hda_bus_reboot_notify(chip->bus);
- azx_stop_chip(chip);
- return NOTIFY_OK;
-}
-
-static void azx_notifier_register(struct azx *chip)
-{
- chip->reboot_notifier.notifier_call = azx_halt;
- register_reboot_notifier(&chip->reboot_notifier);
-}
-
-static void azx_notifier_unregister(struct azx *chip)
-{
- if (chip->reboot_notifier.notifier_call)
- unregister_reboot_notifier(&chip->reboot_notifier);
-}
-
-/*
- * destructor
- */
-static int azx_free(struct azx *chip)
-{
- int i;
-
- azx_notifier_unregister(chip);
-
- if (chip->initialized) {
- azx_clear_irq_pending(chip);
- for (i = 0; i < chip->num_streams; i++)
- azx_stream_stop(chip, &chip->azx_dev[i]);
- azx_stop_chip(chip);
- }
-
- if (chip->irq >= 0)
- free_irq(chip->irq, (void*)chip);
- if (chip->msi)
- pci_disable_msi(chip->pci);
- if (chip->remap_addr)
- iounmap(chip->remap_addr);
-
- if (chip->azx_dev) {
- for (i = 0; i < chip->num_streams; i++)
- if (chip->azx_dev[i].bdl.area) {
- mark_pages_wc(chip, &chip->azx_dev[i].bdl, false);
- snd_dma_free_pages(&chip->azx_dev[i].bdl);
- }
- }
- if (chip->rb.area) {
- mark_pages_wc(chip, &chip->rb, false);
- snd_dma_free_pages(&chip->rb);
- }
- if (chip->posbuf.area) {
- mark_pages_wc(chip, &chip->posbuf, false);
- snd_dma_free_pages(&chip->posbuf);
- }
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
- kfree(chip->azx_dev);
- kfree(chip);
-
- return 0;
-}
-
-static int azx_dev_free(struct snd_device *device)
-{
- return azx_free(device->device_data);
-}
-
-/*
- * white/black-listing for position_fix
- */
-static struct snd_pci_quirk position_fix_list[] __devinitdata = {
- SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
- SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
- SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
- SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
- SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
- SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB),
- SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),
- SND_PCI_QUIRK(0x10de, 0xcb89, "Macbook Pro 7,1", POS_FIX_LPIB),
- SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB),
- SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB),
- SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
- SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB),
- SND_PCI_QUIRK(0x1849, 0x0888, "775Dual-VSTA", POS_FIX_LPIB),
- SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB),
- {}
-};
-
-static int __devinit check_position_fix(struct azx *chip, int fix)
-{
- const struct snd_pci_quirk *q;
-
- switch (fix) {
- case POS_FIX_LPIB:
- case POS_FIX_POSBUF:
- case POS_FIX_VIACOMBO:
- case POS_FIX_COMBO:
- return fix;
- }
-
- q = snd_pci_quirk_lookup(chip->pci, position_fix_list);
- if (q) {
- printk(KERN_INFO
- "hda_intel: position_fix set to %d "
- "for device %04x:%04x\n",
- q->value, q->subvendor, q->subdevice);
- return q->value;
- }
-
- /* Check VIA/ATI HD Audio Controller exist */
- if (chip->driver_caps & AZX_DCAPS_POSFIX_VIA) {
- snd_printd(SFX "Using VIACOMBO position fix\n");
- return POS_FIX_VIACOMBO;
- }
- if (chip->driver_caps & AZX_DCAPS_POSFIX_LPIB) {
- snd_printd(SFX "Using LPIB position fix\n");
- return POS_FIX_LPIB;
- }
- return POS_FIX_AUTO;
-}
-
-/*
- * black-lists for probe_mask
- */
-static struct snd_pci_quirk probe_mask_list[] __devinitdata = {
- /* Thinkpad often breaks the controller communication when accessing
- * to the non-working (or non-existing) modem codec slot.
- */
- SND_PCI_QUIRK(0x1014, 0x05b7, "Thinkpad Z60", 0x01),
- SND_PCI_QUIRK(0x17aa, 0x2010, "Thinkpad X/T/R60", 0x01),
- SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X/T/R61", 0x01),
- /* broken BIOS */
- SND_PCI_QUIRK(0x1028, 0x20ac, "Dell Studio Desktop", 0x01),
- /* including bogus ALC268 in slot#2 that conflicts with ALC888 */
- SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01),
- /* forced codec slots */
- SND_PCI_QUIRK(0x1043, 0x1262, "ASUS W5Fm", 0x103),
- SND_PCI_QUIRK(0x1046, 0x1262, "ASUS W5F", 0x103),
- {}
-};
-
-#define AZX_FORCE_CODEC_MASK 0x100
-
-static void __devinit check_probe_mask(struct azx *chip, int dev)
-{
- const struct snd_pci_quirk *q;
-
- chip->codec_probe_mask = probe_mask[dev];
- if (chip->codec_probe_mask == -1) {
- q = snd_pci_quirk_lookup(chip->pci, probe_mask_list);
- if (q) {
- printk(KERN_INFO
- "hda_intel: probe_mask set to 0x%x "
- "for device %04x:%04x\n",
- q->value, q->subvendor, q->subdevice);
- chip->codec_probe_mask = q->value;
- }
- }
-
- /* check forced option */
- if (chip->codec_probe_mask != -1 &&
- (chip->codec_probe_mask & AZX_FORCE_CODEC_MASK)) {
- chip->codec_mask = chip->codec_probe_mask & 0xff;
- printk(KERN_INFO "hda_intel: codec_mask forced to 0x%x\n",
- chip->codec_mask);
- }
-}
-
-/*
- * white/black-list for enable_msi
- */
-static struct snd_pci_quirk msi_black_list[] __devinitdata = {
- SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */
- SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
- SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */
- SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */
- SND_PCI_QUIRK(0xa0a0, 0x0575, "Aopen MZ915-M", 0), /* ICH6 */
- {}
-};
-
-static void __devinit check_msi(struct azx *chip)
-{
- const struct snd_pci_quirk *q;
-
- if (enable_msi >= 0) {
- chip->msi = !!enable_msi;
- return;
- }
- chip->msi = 1; /* enable MSI as default */
- q = snd_pci_quirk_lookup(chip->pci, msi_black_list);
- if (q) {
- printk(KERN_INFO
- "hda_intel: msi for device %04x:%04x set to %d\n",
- q->subvendor, q->subdevice, q->value);
- chip->msi = q->value;
- return;
- }
-
- /* NVidia chipsets seem to cause troubles with MSI */
- if (chip->driver_caps & AZX_DCAPS_NO_MSI) {
- printk(KERN_INFO "hda_intel: Disabling MSI\n");
- chip->msi = 0;
- }
-}
-
-/* check the snoop mode availability */
-static void __devinit azx_check_snoop_available(struct azx *chip)
-{
- bool snoop = chip->snoop;
-
- switch (chip->driver_type) {
- case AZX_DRIVER_VIA:
- /* force to non-snoop mode for a new VIA controller
- * when BIOS is set
- */
- if (snoop) {
- u8 val;
- pci_read_config_byte(chip->pci, 0x42, &val);
- if (!(val & 0x80) && chip->pci->revision == 0x30)
- snoop = false;
- }
- break;
- case AZX_DRIVER_ATIHDMI_NS:
- /* new ATI HDMI requires non-snoop */
- snoop = false;
- break;
- }
-
- if (snoop != chip->snoop) {
- snd_printk(KERN_INFO SFX "Force to %s mode\n",
- snoop ? "snoop" : "non-snoop");
- chip->snoop = snoop;
- }
-}
-
-/*
- * constructor
- */
-static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
- int dev, unsigned int driver_caps,
- struct azx **rchip)
-{
- struct azx *chip;
- int i, err;
- unsigned short gcap;
- static struct snd_device_ops ops = {
- .dev_free = azx_dev_free,
- };
-
- *rchip = NULL;
-
- err = pci_enable_device(pci);
- if (err < 0)
- return err;
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (!chip) {
- snd_printk(KERN_ERR SFX "cannot allocate chip\n");
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- spin_lock_init(&chip->reg_lock);
- mutex_init(&chip->open_mutex);
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
- chip->driver_caps = driver_caps;
- chip->driver_type = driver_caps & 0xff;
- check_msi(chip);
- chip->dev_index = dev;
- INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work);
- INIT_LIST_HEAD(&chip->pcm_list);
-
- chip->position_fix[0] = chip->position_fix[1] =
- check_position_fix(chip, position_fix[dev]);
- /* combo mode uses LPIB for playback */
- if (chip->position_fix[0] == POS_FIX_COMBO) {
- chip->position_fix[0] = POS_FIX_LPIB;
- chip->position_fix[1] = POS_FIX_AUTO;
- }
-
- check_probe_mask(chip, dev);
-
- chip->single_cmd = single_cmd;
- chip->snoop = hda_snoop;
- azx_check_snoop_available(chip);
-
- if (bdl_pos_adj[dev] < 0) {
- switch (chip->driver_type) {
- case AZX_DRIVER_ICH:
- case AZX_DRIVER_PCH:
- bdl_pos_adj[dev] = 1;
- break;
- default:
- bdl_pos_adj[dev] = 32;
- break;
- }
- }
-
-#if BITS_PER_LONG != 64
- /* Fix up base address on ULI M5461 */
- if (chip->driver_type == AZX_DRIVER_ULI) {
- u16 tmp3;
- pci_read_config_word(pci, 0x40, &tmp3);
- pci_write_config_word(pci, 0x40, tmp3 | 0x10);
- pci_write_config_dword(pci, PCI_BASE_ADDRESS_1, 0);
- }
-#endif
-
- err = pci_request_regions(pci, "ICH HD audio");
- if (err < 0) {
- kfree(chip);
- pci_disable_device(pci);
- return err;
- }
-
- chip->addr = pci_resource_start(pci, 0);
- chip->remap_addr = pci_ioremap_bar(pci, 0);
- if (chip->remap_addr == NULL) {
- snd_printk(KERN_ERR SFX "ioremap error\n");
- err = -ENXIO;
- goto errout;
- }
-
- if (chip->msi)
- if (pci_enable_msi(pci) < 0)
- chip->msi = 0;
-
- if (azx_acquire_irq(chip, 0) < 0) {
- err = -EBUSY;
- goto errout;
- }
-
- pci_set_master(pci);
- synchronize_irq(chip->irq);
-
- gcap = azx_readw(chip, GCAP);
- snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap);
-
- /* disable SB600 64bit support for safety */
- if (chip->pci->vendor == PCI_VENDOR_ID_ATI) {
- struct pci_dev *p_smbus;
- p_smbus = pci_get_device(PCI_VENDOR_ID_ATI,
- PCI_DEVICE_ID_ATI_SBX00_SMBUS,
- NULL);
- if (p_smbus) {
- if (p_smbus->revision < 0x30)
- gcap &= ~ICH6_GCAP_64OK;
- pci_dev_put(p_smbus);
- }
- }
-
- /* disable 64bit DMA address on some devices */
- if (chip->driver_caps & AZX_DCAPS_NO_64BIT) {
- snd_printd(SFX "Disabling 64bit DMA\n");
- gcap &= ~ICH6_GCAP_64OK;
- }
-
- /* disable buffer size rounding to 128-byte multiples if supported */
- if (align_buffer_size >= 0)
- chip->align_buffer_size = !!align_buffer_size;
- else {
- if (chip->driver_caps & AZX_DCAPS_BUFSIZE)
- chip->align_buffer_size = 0;
- else if (chip->driver_caps & AZX_DCAPS_ALIGN_BUFSIZE)
- chip->align_buffer_size = 1;
- else
- chip->align_buffer_size = 1;
- }
-
- /* allow 64bit DMA address if supported by H/W */
- if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
- pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
- else {
- pci_set_dma_mask(pci, DMA_BIT_MASK(32));
- pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32));
- }
-
- /* read number of streams from GCAP register instead of using
- * hardcoded value
- */
- chip->capture_streams = (gcap >> 8) & 0x0f;
- chip->playback_streams = (gcap >> 12) & 0x0f;
- if (!chip->playback_streams && !chip->capture_streams) {
- /* gcap didn't give any info, switching to old method */
-
- switch (chip->driver_type) {
- case AZX_DRIVER_ULI:
- chip->playback_streams = ULI_NUM_PLAYBACK;
- chip->capture_streams = ULI_NUM_CAPTURE;
- break;
- case AZX_DRIVER_ATIHDMI:
- case AZX_DRIVER_ATIHDMI_NS:
- chip->playback_streams = ATIHDMI_NUM_PLAYBACK;
- chip->capture_streams = ATIHDMI_NUM_CAPTURE;
- break;
- case AZX_DRIVER_GENERIC:
- default:
- chip->playback_streams = ICH6_NUM_PLAYBACK;
- chip->capture_streams = ICH6_NUM_CAPTURE;
- break;
- }
- }
- chip->capture_index_offset = 0;
- chip->playback_index_offset = chip->capture_streams;
- chip->num_streams = chip->playback_streams + chip->capture_streams;
- chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev),
- GFP_KERNEL);
- if (!chip->azx_dev) {
- snd_printk(KERN_ERR SFX "cannot malloc azx_dev\n");
- goto errout;
- }
-
- for (i = 0; i < chip->num_streams; i++) {
- /* allocate memory for the BDL for each stream */
- err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- BDL_SIZE, &chip->azx_dev[i].bdl);
- if (err < 0) {
- snd_printk(KERN_ERR SFX "cannot allocate BDL\n");
- goto errout;
- }
- mark_pages_wc(chip, &chip->azx_dev[i].bdl, true);
- }
- /* allocate memory for the position buffer */
- err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- chip->num_streams * 8, &chip->posbuf);
- if (err < 0) {
- snd_printk(KERN_ERR SFX "cannot allocate posbuf\n");
- goto errout;
- }
- mark_pages_wc(chip, &chip->posbuf, true);
- /* allocate CORB/RIRB */
- err = azx_alloc_cmd_io(chip);
- if (err < 0)
- goto errout;
-
- /* initialize streams */
- azx_init_stream(chip);
-
- /* initialize chip */
- azx_init_pci(chip);
- azx_init_chip(chip, (probe_only[dev] & 2) == 0);
-
- /* codec detection */
- if (!chip->codec_mask) {
- snd_printk(KERN_ERR SFX "no codecs found!\n");
- err = -ENODEV;
- goto errout;
- }
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
- if (err <0) {
- snd_printk(KERN_ERR SFX "Error creating device [card]!\n");
- goto errout;
- }
-
- strcpy(card->driver, "HDA-Intel");
- strlcpy(card->shortname, driver_short_names[chip->driver_type],
- sizeof(card->shortname));
- snprintf(card->longname, sizeof(card->longname),
- "%s at 0x%lx irq %i",
- card->shortname, chip->addr, chip->irq);
-
- *rchip = chip;
- return 0;
-
- errout:
- azx_free(chip);
- return err;
-}
-
-static void power_down_all_codecs(struct azx *chip)
-{
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- /* The codecs were powered up in snd_hda_codec_new().
- * Now all initialization done, so turn them down if possible
- */
- struct hda_codec *codec;
- list_for_each_entry(codec, &chip->bus->codec_list, list) {
- snd_hda_power_down(codec);
- }
-#endif
-}
-
-static int __devinit azx_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct azx *chip;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0) {
- snd_printk(KERN_ERR SFX "Error creating card!\n");
- return err;
- }
-
- /* set this here since it's referred in snd_hda_load_patch() */
- snd_card_set_dev(card, &pci->dev);
-
- err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
- if (err < 0)
- goto out_free;
- card->private_data = chip;
-
-#ifdef CONFIG_SND_HDA_INPUT_BEEP
- chip->beep_mode = beep_mode[dev];
-#endif
-
- /* create codec instances */
- err = azx_codec_create(chip, model[dev]);
- if (err < 0)
- goto out_free;
-#ifdef CONFIG_SND_HDA_PATCH_LOADER
- if (patch[dev] && *patch[dev]) {
- snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n",
- patch[dev]);
- err = snd_hda_load_patch(chip->bus, patch[dev]);
- if (err < 0)
- goto out_free;
- }
-#endif
- if ((probe_only[dev] & 1) == 0) {
- err = azx_codec_configure(chip);
- if (err < 0)
- goto out_free;
- }
-
- /* create PCM streams */
- err = snd_hda_build_pcms(chip->bus);
- if (err < 0)
- goto out_free;
-
- /* create mixer controls */
- err = azx_mixer_create(chip);
- if (err < 0)
- goto out_free;
-
- err = snd_card_register(card);
- if (err < 0)
- goto out_free;
-
- pci_set_drvdata(pci, card);
- chip->running = 1;
- power_down_all_codecs(chip);
- azx_notifier_register(chip);
-
- dev++;
- return err;
-out_free:
- snd_card_free(card);
- return err;
-}
-
-static void __devexit azx_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-/* PCI IDs */
-static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
- /* CPT */
- { PCI_DEVICE(0x8086, 0x1c20),
- .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE },
- /* PBG */
- { PCI_DEVICE(0x8086, 0x1d20),
- .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE},
- /* Panther Point */
- { PCI_DEVICE(0x8086, 0x1e20),
- .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE},
- /* Lynx Point */
- { PCI_DEVICE(0x8086, 0x8c20),
- .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE},
- /* SCH */
- { PCI_DEVICE(0x8086, 0x811b),
- .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_LPIB }, /* Poulsbo */
- { PCI_DEVICE(0x8086, 0x080a),
- .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_LPIB }, /* Oaktrail */
- /* ICH */
- { PCI_DEVICE(0x8086, 0x2668),
- .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
- AZX_DCAPS_BUFSIZE }, /* ICH6 */
- { PCI_DEVICE(0x8086, 0x27d8),
- .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
- AZX_DCAPS_BUFSIZE }, /* ICH7 */
- { PCI_DEVICE(0x8086, 0x269a),
- .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
- AZX_DCAPS_BUFSIZE }, /* ESB2 */
- { PCI_DEVICE(0x8086, 0x284b),
- .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
- AZX_DCAPS_BUFSIZE }, /* ICH8 */
- { PCI_DEVICE(0x8086, 0x293e),
- .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
- AZX_DCAPS_BUFSIZE }, /* ICH9 */
- { PCI_DEVICE(0x8086, 0x293f),
- .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
- AZX_DCAPS_BUFSIZE }, /* ICH9 */
- { PCI_DEVICE(0x8086, 0x3a3e),
- .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
- AZX_DCAPS_BUFSIZE }, /* ICH10 */
- { PCI_DEVICE(0x8086, 0x3a6e),
- .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
- AZX_DCAPS_BUFSIZE }, /* ICH10 */
- /* Generic Intel */
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),
- .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
- .class_mask = 0xffffff,
- .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_BUFSIZE },
- /* ATI SB 450/600/700/800/900 */
- { PCI_DEVICE(0x1002, 0x437b),
- .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },
- { PCI_DEVICE(0x1002, 0x4383),
- .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },
- /* AMD Hudson */
- { PCI_DEVICE(0x1022, 0x780d),
- .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB },
- /* ATI HDMI */
- { PCI_DEVICE(0x1002, 0x793b),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
- { PCI_DEVICE(0x1002, 0x7919),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
- { PCI_DEVICE(0x1002, 0x960f),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
- { PCI_DEVICE(0x1002, 0x970f),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
- { PCI_DEVICE(0x1002, 0xaa00),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
- { PCI_DEVICE(0x1002, 0xaa08),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
- { PCI_DEVICE(0x1002, 0xaa10),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
- { PCI_DEVICE(0x1002, 0xaa18),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
- { PCI_DEVICE(0x1002, 0xaa20),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
- { PCI_DEVICE(0x1002, 0xaa28),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
- { PCI_DEVICE(0x1002, 0xaa30),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
- { PCI_DEVICE(0x1002, 0xaa38),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
- { PCI_DEVICE(0x1002, 0xaa40),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
- { PCI_DEVICE(0x1002, 0xaa48),
- .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
- { PCI_DEVICE(0x1002, 0x9902),
- .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI },
- { PCI_DEVICE(0x1002, 0xaaa0),
- .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI },
- { PCI_DEVICE(0x1002, 0xaaa8),
- .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI },
- { PCI_DEVICE(0x1002, 0xaab0),
- .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI },
- /* VIA VT8251/VT8237A */
- { PCI_DEVICE(0x1106, 0x3288),
- .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA },
- /* SIS966 */
- { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS },
- /* ULI M5461 */
- { PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI },
- /* NVIDIA MCP */
- { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
- .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
- .class_mask = 0xffffff,
- .driver_data = AZX_DRIVER_NVIDIA | AZX_DCAPS_PRESET_NVIDIA },
- /* Teradici */
- { PCI_DEVICE(0x6549, 0x1200),
- .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT },
- /* Creative X-Fi (CA0110-IBG) */
-#if !defined(CONFIG_SND_CTXFI) && !defined(CONFIG_SND_CTXFI_MODULE)
- /* the following entry conflicts with snd-ctxfi driver,
- * as ctxfi driver mutates from HD-audio to native mode with
- * a special command sequence.
- */
- { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID),
- .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
- .class_mask = 0xffffff,
- .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
- AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
-#else
- /* this entry seems still valid -- i.e. without emu20kx chip */
- { PCI_DEVICE(0x1102, 0x0009),
- .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
- AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
-#endif
- /* Vortex86MX */
- { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC },
- /* VMware HDAudio */
- { PCI_DEVICE(0x15ad, 0x1977), .driver_data = AZX_DRIVER_GENERIC },
- /* AMD/ATI Generic, PCI class code and Vendor ID for HD Audio */
- { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID),
- .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
- .class_mask = 0xffffff,
- .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI },
- { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_ANY_ID),
- .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
- .class_mask = 0xffffff,
- .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI },
- { 0, }
-};
-MODULE_DEVICE_TABLE(pci, azx_ids);
-
-/* pci_driver definition */
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = azx_ids,
- .probe = azx_probe,
- .remove = __devexit_p(azx_remove),
-#ifdef CONFIG_PM
- .suspend = azx_suspend,
- .resume = azx_resume,
-#endif
-};
-
-static int __init alsa_card_azx_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_azx_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_azx_init)
-module_exit(alsa_card_azx_exit)
diff --git a/ANDROID_3.4.5/sound/pci/hda/hda_jack.c b/ANDROID_3.4.5/sound/pci/hda/hda_jack.c
deleted file mode 100644
index d6894849..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/hda_jack.c
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Jack-detection handling for HD-audio
- *
- * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/export.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/jack.h>
-#include "hda_codec.h"
-#include "hda_local.h"
-#include "hda_jack.h"
-
-bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
-{
- if (codec->no_jack_detect)
- return false;
- if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
- return false;
- if (!codec->ignore_misc_bit &&
- (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
- AC_DEFCFG_MISC_NO_PRESENCE))
- return false;
- if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
- return false;
- return true;
-}
-EXPORT_SYMBOL_HDA(is_jack_detectable);
-
-/* execute pin sense measurement */
-static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid)
-{
- u32 pincap;
-
- if (!codec->no_trigger_sense) {
- pincap = snd_hda_query_pin_caps(codec, nid);
- if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
- snd_hda_codec_read(codec, nid, 0,
- AC_VERB_SET_PIN_SENSE, 0);
- }
- return snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_PIN_SENSE, 0);
-}
-
-/**
- * snd_hda_jack_tbl_get - query the jack-table entry for the given NID
- */
-struct hda_jack_tbl *
-snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid)
-{
- struct hda_jack_tbl *jack = codec->jacktbl.list;
- int i;
-
- if (!nid || !jack)
- return NULL;
- for (i = 0; i < codec->jacktbl.used; i++, jack++)
- if (jack->nid == nid)
- return jack;
- return NULL;
-}
-EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get);
-
-/**
- * snd_hda_jack_tbl_get_from_tag - query the jack-table entry for the given tag
- */
-struct hda_jack_tbl *
-snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag)
-{
- struct hda_jack_tbl *jack = codec->jacktbl.list;
- int i;
-
- if (!tag || !jack)
- return NULL;
- for (i = 0; i < codec->jacktbl.used; i++, jack++)
- if (jack->tag == tag)
- return jack;
- return NULL;
-}
-EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get_from_tag);
-
-/**
- * snd_hda_jack_tbl_new - create a jack-table entry for the given NID
- */
-struct hda_jack_tbl *
-snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid)
-{
- struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
- if (jack)
- return jack;
- snd_array_init(&codec->jacktbl, sizeof(*jack), 16);
- jack = snd_array_new(&codec->jacktbl);
- if (!jack)
- return NULL;
- jack->nid = nid;
- jack->jack_dirty = 1;
- jack->tag = codec->jacktbl.used;
- return jack;
-}
-EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_new);
-
-void snd_hda_jack_tbl_clear(struct hda_codec *codec)
-{
-#ifdef CONFIG_SND_HDA_INPUT_JACK
- /* free jack instances manually when clearing/reconfiguring */
- if (!codec->bus->shutdown && codec->jacktbl.list) {
- struct hda_jack_tbl *jack = codec->jacktbl.list;
- int i;
- for (i = 0; i < codec->jacktbl.used; i++, jack++) {
- if (jack->jack)
- snd_device_free(codec->bus->card, jack->jack);
- }
- }
-#endif
- snd_array_free(&codec->jacktbl);
-}
-
-/* update the cached value and notification flag if needed */
-static void jack_detect_update(struct hda_codec *codec,
- struct hda_jack_tbl *jack)
-{
- if (jack->jack_dirty || !jack->jack_detect) {
- jack->pin_sense = read_pin_sense(codec, jack->nid);
- jack->jack_dirty = 0;
- }
-}
-
-/**
- * snd_hda_set_dirty_all - Mark all the cached as dirty
- *
- * This function sets the dirty flag to all entries of jack table.
- * It's called from the resume path in hda_codec.c.
- */
-void snd_hda_jack_set_dirty_all(struct hda_codec *codec)
-{
- struct hda_jack_tbl *jack = codec->jacktbl.list;
- int i;
-
- for (i = 0; i < codec->jacktbl.used; i++, jack++)
- if (jack->nid)
- jack->jack_dirty = 1;
-}
-EXPORT_SYMBOL_HDA(snd_hda_jack_set_dirty_all);
-
-/**
- * snd_hda_pin_sense - execute pin sense measurement
- * @codec: the CODEC to sense
- * @nid: the pin NID to sense
- *
- * Execute necessary pin sense measurement and return its Presence Detect,
- * Impedance, ELD Valid etc. status bits.
- */
-u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
-{
- struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
- if (jack) {
- jack_detect_update(codec, jack);
- return jack->pin_sense;
- }
- return read_pin_sense(codec, nid);
-}
-EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
-
-#define get_jack_plug_state(sense) !!(sense & AC_PINSENSE_PRESENCE)
-
-/**
- * snd_hda_jack_detect - query pin Presence Detect status
- * @codec: the CODEC to sense
- * @nid: the pin NID to sense
- *
- * Query and return the pin's Presence Detect status.
- */
-int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
-{
- u32 sense = snd_hda_pin_sense(codec, nid);
- return get_jack_plug_state(sense);
-}
-EXPORT_SYMBOL_HDA(snd_hda_jack_detect);
-
-/**
- * snd_hda_jack_detect_enable - enable the jack-detection
- */
-int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
- unsigned char action)
-{
- struct hda_jack_tbl *jack = snd_hda_jack_tbl_new(codec, nid);
- if (!jack)
- return -ENOMEM;
- if (jack->jack_detect)
- return 0; /* already registered */
- jack->jack_detect = 1;
- if (action)
- jack->action = action;
- return snd_hda_codec_write_cache(codec, nid, 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | jack->tag);
-}
-EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable);
-
-/**
- * snd_hda_jack_report_sync - sync the states of all jacks and report if changed
- */
-void snd_hda_jack_report_sync(struct hda_codec *codec)
-{
- struct hda_jack_tbl *jack = codec->jacktbl.list;
- int i, state;
-
- for (i = 0; i < codec->jacktbl.used; i++, jack++)
- if (jack->nid) {
- jack_detect_update(codec, jack);
- if (!jack->kctl)
- continue;
- state = get_jack_plug_state(jack->pin_sense);
- snd_kctl_jack_report(codec->bus->card, jack->kctl, state);
-#ifdef CONFIG_SND_HDA_INPUT_JACK
- if (jack->jack)
- snd_jack_report(jack->jack,
- state ? jack->type : 0);
-#endif
- }
-}
-EXPORT_SYMBOL_HDA(snd_hda_jack_report_sync);
-
-#ifdef CONFIG_SND_HDA_INPUT_JACK
-/* guess the jack type from the pin-config */
-static int get_input_jack_type(struct hda_codec *codec, hda_nid_t nid)
-{
- unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
- switch (get_defcfg_device(def_conf)) {
- case AC_JACK_LINE_OUT:
- case AC_JACK_SPEAKER:
- return SND_JACK_LINEOUT;
- case AC_JACK_HP_OUT:
- return SND_JACK_HEADPHONE;
- case AC_JACK_SPDIF_OUT:
- case AC_JACK_DIG_OTHER_OUT:
- return SND_JACK_AVOUT;
- case AC_JACK_MIC_IN:
- return SND_JACK_MICROPHONE;
- default:
- return SND_JACK_LINEIN;
- }
-}
-
-static void hda_free_jack_priv(struct snd_jack *jack)
-{
- struct hda_jack_tbl *jacks = jack->private_data;
- jacks->nid = 0;
- jacks->jack = NULL;
-}
-#endif
-
-/**
- * snd_hda_jack_add_kctl - Add a kctl for the given pin
- *
- * This assigns a jack-detection kctl to the given pin. The kcontrol
- * will have the given name and index.
- */
-int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
- const char *name, int idx)
-{
- struct hda_jack_tbl *jack;
- struct snd_kcontrol *kctl;
- int err, state;
-
- jack = snd_hda_jack_tbl_new(codec, nid);
- if (!jack)
- return 0;
- if (jack->kctl)
- return 0; /* already created */
- kctl = snd_kctl_jack_new(name, idx, codec);
- if (!kctl)
- return -ENOMEM;
- err = snd_hda_ctl_add(codec, nid, kctl);
- if (err < 0)
- return err;
- jack->kctl = kctl;
- state = snd_hda_jack_detect(codec, nid);
- snd_kctl_jack_report(codec->bus->card, kctl, state);
-#ifdef CONFIG_SND_HDA_INPUT_JACK
- jack->type = get_input_jack_type(codec, nid);
- err = snd_jack_new(codec->bus->card, name, jack->type, &jack->jack);
- if (err < 0)
- return err;
- jack->jack->private_data = jack;
- jack->jack->private_free = hda_free_jack_priv;
- snd_jack_report(jack->jack, state ? jack->type : 0);
-#endif
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl);
-
-static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
- const struct auto_pin_cfg *cfg,
- char *lastname, int *lastidx)
-{
- unsigned int def_conf, conn;
- char name[44];
- int idx, err;
-
- if (!nid)
- return 0;
- if (!is_jack_detectable(codec, nid))
- return 0;
- def_conf = snd_hda_codec_get_pincfg(codec, nid);
- conn = get_defcfg_connect(def_conf);
- if (conn != AC_JACK_PORT_COMPLEX)
- return 0;
-
- snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx);
- if (!strcmp(name, lastname) && idx == *lastidx)
- idx++;
- strncpy(lastname, name, 44);
- *lastidx = idx;
- err = snd_hda_jack_add_kctl(codec, nid, name, idx);
- if (err < 0)
- return err;
- return snd_hda_jack_detect_enable(codec, nid, 0);
-}
-
-/**
- * snd_hda_jack_add_kctls - Add kctls for all pins included in the given pincfg
- */
-int snd_hda_jack_add_kctls(struct hda_codec *codec,
- const struct auto_pin_cfg *cfg)
-{
- const hda_nid_t *p;
- int i, err, lastidx = 0;
- char lastname[44] = "";
-
- for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) {
- err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx);
- if (err < 0)
- return err;
- }
- for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) {
- if (*p == *cfg->line_out_pins) /* might be duplicated */
- break;
- err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx);
- if (err < 0)
- return err;
- }
- for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) {
- if (*p == *cfg->line_out_pins) /* might be duplicated */
- break;
- err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx);
- if (err < 0)
- return err;
- }
- for (i = 0; i < cfg->num_inputs; i++) {
- err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, lastname, &lastidx);
- if (err < 0)
- return err;
- }
- for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) {
- err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx);
- if (err < 0)
- return err;
- }
- err = add_jack_kctl(codec, cfg->dig_in_pin, cfg, lastname, &lastidx);
- if (err < 0)
- return err;
- err = add_jack_kctl(codec, cfg->mono_out_pin, cfg, lastname, &lastidx);
- if (err < 0)
- return err;
- return 0;
-}
-EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctls);
diff --git a/ANDROID_3.4.5/sound/pci/hda/hda_jack.h b/ANDROID_3.4.5/sound/pci/hda/hda_jack.h
deleted file mode 100644
index c66655cf..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/hda_jack.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Jack-detection handling for HD-audio
- *
- * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef __SOUND_HDA_JACK_H
-#define __SOUND_HDA_JACK_H
-
-struct hda_jack_tbl {
- hda_nid_t nid;
- unsigned char action; /* event action (0 = none) */
- unsigned char tag; /* unsol event tag */
- unsigned int private_data; /* arbitrary data */
- /* jack-detection stuff */
- unsigned int pin_sense; /* cached pin-sense value */
- unsigned int jack_detect:1; /* capable of jack-detection? */
- unsigned int jack_dirty:1; /* needs to update? */
- struct snd_kcontrol *kctl; /* assigned kctl for jack-detection */
-#ifdef CONFIG_SND_HDA_INPUT_JACK
- int type;
- struct snd_jack *jack;
-#endif
-};
-
-struct hda_jack_tbl *
-snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid);
-struct hda_jack_tbl *
-snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag);
-
-struct hda_jack_tbl *
-snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid);
-void snd_hda_jack_tbl_clear(struct hda_codec *codec);
-
-/**
- * snd_hda_jack_get_action - get jack-tbl entry for the tag
- *
- * Call this from the unsol event handler to get the assigned action for the
- * event. This will mark the dirty flag for the later reporting, too.
- */
-static inline unsigned char
-snd_hda_jack_get_action(struct hda_codec *codec, unsigned int tag)
-{
- struct hda_jack_tbl *jack = snd_hda_jack_tbl_get_from_tag(codec, tag);
- if (jack) {
- jack->jack_dirty = 1;
- return jack->action;
- }
- return 0;
-}
-
-void snd_hda_jack_set_dirty_all(struct hda_codec *codec);
-
-int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
- unsigned char action);
-
-u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
-int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
-
-bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid);
-
-int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
- const char *name, int idx);
-int snd_hda_jack_add_kctls(struct hda_codec *codec,
- const struct auto_pin_cfg *cfg);
-
-void snd_hda_jack_report_sync(struct hda_codec *codec);
-
-
-#endif /* __SOUND_HDA_JACK_H */
diff --git a/ANDROID_3.4.5/sound/pci/hda/hda_local.h b/ANDROID_3.4.5/sound/pci/hda/hda_local.h
deleted file mode 100644
index 0ec92481..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/hda_local.h
+++ /dev/null
@@ -1,708 +0,0 @@
-/*
- * Universal Interface for Intel High Definition Audio Codec
- *
- * Local helper functions
- *
- * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __SOUND_HDA_LOCAL_H
-#define __SOUND_HDA_LOCAL_H
-
-/* We abuse kcontrol_new.subdev field to pass the NID corresponding to
- * the given new control. If id.subdev has a bit flag HDA_SUBDEV_NID_FLAG,
- * snd_hda_ctl_add() takes the lower-bit subdev value as a valid NID.
- *
- * Note that the subdevice field is cleared again before the real registration
- * in snd_hda_ctl_add(), so that this value won't appear in the outside.
- */
-#define HDA_SUBDEV_NID_FLAG (1U << 31)
-#define HDA_SUBDEV_AMP_FLAG (1U << 30)
-
-/*
- * for mixer controls
- */
-#define HDA_COMPOSE_AMP_VAL_OFS(nid,chs,idx,dir,ofs) \
- ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19) | ((ofs)<<23))
-#define HDA_AMP_VAL_MIN_MUTE (1<<29)
-#define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) \
- HDA_COMPOSE_AMP_VAL_OFS(nid, chs, idx, dir, 0)
-/* mono volume with index (index=0,1,...) (channel=1,2) */
-#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, dir, flags) \
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
- .subdevice = HDA_SUBDEV_AMP_FLAG, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
- SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
- SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
- .info = snd_hda_mixer_amp_volume_info, \
- .get = snd_hda_mixer_amp_volume_get, \
- .put = snd_hda_mixer_amp_volume_put, \
- .tlv = { .c = snd_hda_mixer_amp_tlv }, \
- .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, dir) | flags }
-/* stereo volume with index */
-#define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \
- HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction, 0)
-/* mono volume */
-#define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \
- HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction, 0)
-/* stereo volume */
-#define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \
- HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction)
-/* stereo volume with min=mute */
-#define HDA_CODEC_VOLUME_MIN_MUTE(xname, nid, xindex, direction) \
- HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, 3, xindex, direction, \
- HDA_AMP_VAL_MIN_MUTE)
-/* mono mute switch with index (index=0,1,...) (channel=1,2) */
-#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
- .subdevice = HDA_SUBDEV_AMP_FLAG, \
- .info = snd_hda_mixer_amp_switch_info, \
- .get = snd_hda_mixer_amp_switch_get, \
- .put = snd_hda_mixer_amp_switch_put, \
- .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
-/* stereo mute switch with index */
-#define HDA_CODEC_MUTE_IDX(xname, xcidx, nid, xindex, direction) \
- HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, 3, xindex, direction)
-/* mono mute switch */
-#define HDA_CODEC_MUTE_MONO(xname, nid, channel, xindex, direction) \
- HDA_CODEC_MUTE_MONO_IDX(xname, 0, nid, channel, xindex, direction)
-/* stereo mute switch */
-#define HDA_CODEC_MUTE(xname, nid, xindex, direction) \
- HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction)
-#ifdef CONFIG_SND_HDA_INPUT_BEEP
-/* special beep mono mute switch with index (index=0,1,...) (channel=1,2) */
-#define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
- .subdevice = HDA_SUBDEV_AMP_FLAG, \
- .info = snd_hda_mixer_amp_switch_info, \
- .get = snd_hda_mixer_amp_switch_get, \
- .put = snd_hda_mixer_amp_switch_put_beep, \
- .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
-#else
-/* no digital beep - just the standard one */
-#define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, ch, xidx, dir) \
- HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, ch, xidx, dir)
-#endif /* CONFIG_SND_HDA_INPUT_BEEP */
-/* special beep mono mute switch */
-#define HDA_CODEC_MUTE_BEEP_MONO(xname, nid, channel, xindex, direction) \
- HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, 0, nid, channel, xindex, direction)
-/* special beep stereo mute switch */
-#define HDA_CODEC_MUTE_BEEP(xname, nid, xindex, direction) \
- HDA_CODEC_MUTE_BEEP_MONO(xname, nid, 3, xindex, direction)
-
-extern const char *snd_hda_pcm_type_name[];
-
-int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo);
-int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
- unsigned int size, unsigned int __user *tlv);
-int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo);
-int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-#ifdef CONFIG_SND_HDA_INPUT_BEEP
-int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-#endif
-/* lowlevel accessor with caching; use carefully */
-int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
- int direction, int index);
-int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
- int direction, int idx, int mask, int val);
-int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
- int dir, int idx, int mask, int val);
-#ifdef CONFIG_PM
-void snd_hda_codec_resume_amp(struct hda_codec *codec);
-#endif
-
-void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
- unsigned int *tlv);
-struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
- const char *name);
-int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
- unsigned int *tlv, const char * const *slaves,
- const char *suffix, bool init_slave_vol,
- struct snd_kcontrol **ctl_ret);
-#define snd_hda_add_vmaster(codec, name, tlv, slaves, suffix) \
- __snd_hda_add_vmaster(codec, name, tlv, slaves, suffix, true, NULL)
-int snd_hda_codec_reset(struct hda_codec *codec);
-
-enum {
- HDA_VMUTE_OFF,
- HDA_VMUTE_ON,
- HDA_VMUTE_FOLLOW_MASTER,
-};
-
-struct hda_vmaster_mute_hook {
- /* below two fields must be filled by the caller of
- * snd_hda_add_vmaster_hook() beforehand
- */
- struct snd_kcontrol *sw_kctl;
- void (*hook)(void *, int);
- /* below are initialized automatically */
- unsigned int mute_mode; /* HDA_VMUTE_XXX */
- struct hda_codec *codec;
-};
-
-int snd_hda_add_vmaster_hook(struct hda_codec *codec,
- struct hda_vmaster_mute_hook *hook,
- bool expose_enum_ctl);
-void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook);
-
-/* amp value bits */
-#define HDA_AMP_MUTE 0x80
-#define HDA_AMP_UNMUTE 0x00
-#define HDA_AMP_VOLMASK 0x7f
-
-/* mono switch binding multiple inputs */
-#define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
- .info = snd_hda_mixer_amp_switch_info, \
- .get = snd_hda_mixer_bind_switch_get, \
- .put = snd_hda_mixer_bind_switch_put, \
- .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) }
-
-/* stereo switch binding multiple inputs */
-#define HDA_BIND_MUTE(xname,nid,indices,dir) \
- HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir)
-
-int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-
-/* more generic bound controls */
-struct hda_ctl_ops {
- snd_kcontrol_info_t *info;
- snd_kcontrol_get_t *get;
- snd_kcontrol_put_t *put;
- snd_kcontrol_tlv_rw_t *tlv;
-};
-
-extern struct hda_ctl_ops snd_hda_bind_vol; /* for bind-volume with TLV */
-extern struct hda_ctl_ops snd_hda_bind_sw; /* for bind-switch */
-
-struct hda_bind_ctls {
- struct hda_ctl_ops *ops;
- unsigned long values[];
-};
-
-int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo);
-int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
- unsigned int size, unsigned int __user *tlv);
-
-#define HDA_BIND_VOL(xname, bindrec) \
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
- SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
- SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,\
- .info = snd_hda_mixer_bind_ctls_info,\
- .get = snd_hda_mixer_bind_ctls_get,\
- .put = snd_hda_mixer_bind_ctls_put,\
- .tlv = { .c = snd_hda_mixer_bind_tlv },\
- .private_value = (long) (bindrec) }
-#define HDA_BIND_SW(xname, bindrec) \
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\
- .name = xname, \
- .info = snd_hda_mixer_bind_ctls_info,\
- .get = snd_hda_mixer_bind_ctls_get,\
- .put = snd_hda_mixer_bind_ctls_put,\
- .private_value = (long) (bindrec) }
-
-/*
- * SPDIF I/O
- */
-int snd_hda_create_spdif_out_ctls(struct hda_codec *codec,
- hda_nid_t associated_nid,
- hda_nid_t cvt_nid);
-int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
-
-/*
- * input MUX helper
- */
-#define HDA_MAX_NUM_INPUTS 16
-struct hda_input_mux_item {
- char label[32];
- unsigned int index;
-};
-struct hda_input_mux {
- unsigned int num_items;
- struct hda_input_mux_item items[HDA_MAX_NUM_INPUTS];
-};
-
-int snd_hda_input_mux_info(const struct hda_input_mux *imux,
- struct snd_ctl_elem_info *uinfo);
-int snd_hda_input_mux_put(struct hda_codec *codec,
- const struct hda_input_mux *imux,
- struct snd_ctl_elem_value *ucontrol, hda_nid_t nid,
- unsigned int *cur_val);
-
-/*
- * Channel mode helper
- */
-struct hda_channel_mode {
- int channels;
- const struct hda_verb *sequence;
-};
-
-int snd_hda_ch_mode_info(struct hda_codec *codec,
- struct snd_ctl_elem_info *uinfo,
- const struct hda_channel_mode *chmode,
- int num_chmodes);
-int snd_hda_ch_mode_get(struct hda_codec *codec,
- struct snd_ctl_elem_value *ucontrol,
- const struct hda_channel_mode *chmode,
- int num_chmodes,
- int max_channels);
-int snd_hda_ch_mode_put(struct hda_codec *codec,
- struct snd_ctl_elem_value *ucontrol,
- const struct hda_channel_mode *chmode,
- int num_chmodes,
- int *max_channelsp);
-
-/*
- * Multi-channel / digital-out PCM helper
- */
-
-enum { HDA_FRONT, HDA_REAR, HDA_CLFE, HDA_SIDE }; /* index for dac_nidx */
-enum { HDA_DIG_NONE, HDA_DIG_EXCLUSIVE, HDA_DIG_ANALOG_DUP }; /* dig_out_used */
-
-#define HDA_MAX_OUTS 5
-
-struct hda_multi_out {
- int num_dacs; /* # of DACs, must be more than 1 */
- const hda_nid_t *dac_nids; /* DAC list */
- hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */
- hda_nid_t hp_out_nid[HDA_MAX_OUTS]; /* DACs for multiple HPs */
- hda_nid_t extra_out_nid[HDA_MAX_OUTS]; /* other (e.g. speaker) DACs */
- hda_nid_t dig_out_nid; /* digital out audio widget */
- const hda_nid_t *slave_dig_outs;
- int max_channels; /* currently supported analog channels */
- int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */
- int no_share_stream; /* don't share a stream with multiple pins */
- int share_spdif; /* share SPDIF pin */
- /* PCM information for both analog and SPDIF DACs */
- unsigned int analog_rates;
- unsigned int analog_maxbps;
- u64 analog_formats;
- unsigned int spdif_rates;
- unsigned int spdif_maxbps;
- u64 spdif_formats;
-};
-
-int snd_hda_create_spdif_share_sw(struct hda_codec *codec,
- struct hda_multi_out *mout);
-int snd_hda_multi_out_dig_open(struct hda_codec *codec,
- struct hda_multi_out *mout);
-int snd_hda_multi_out_dig_close(struct hda_codec *codec,
- struct hda_multi_out *mout);
-int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
- struct hda_multi_out *mout,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream);
-int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec,
- struct hda_multi_out *mout);
-int snd_hda_multi_out_analog_open(struct hda_codec *codec,
- struct hda_multi_out *mout,
- struct snd_pcm_substream *substream,
- struct hda_pcm_stream *hinfo);
-int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
- struct hda_multi_out *mout,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream);
-int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
- struct hda_multi_out *mout);
-
-/*
- * generic codec parser
- */
-#ifdef CONFIG_SND_HDA_GENERIC
-int snd_hda_parse_generic_codec(struct hda_codec *codec);
-#else
-static inline int snd_hda_parse_generic_codec(struct hda_codec *codec)
-{
- return -ENODEV;
-}
-#endif
-
-/*
- * generic proc interface
- */
-#ifdef CONFIG_PROC_FS
-int snd_hda_codec_proc_new(struct hda_codec *codec);
-#else
-static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; }
-#endif
-
-#define SND_PRINT_BITS_ADVISED_BUFSIZE 16
-void snd_print_pcm_bits(int pcm, char *buf, int buflen);
-
-/*
- * Misc
- */
-int snd_hda_check_board_config(struct hda_codec *codec, int num_configs,
- const char * const *modelnames,
- const struct snd_pci_quirk *pci_list);
-int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
- int num_configs, const char * const *models,
- const struct snd_pci_quirk *tbl);
-int snd_hda_add_new_ctls(struct hda_codec *codec,
- const struct snd_kcontrol_new *knew);
-
-/*
- * unsolicited event handler
- */
-
-#define HDA_UNSOL_QUEUE_SIZE 64
-
-struct hda_bus_unsolicited {
- /* ring buffer */
- u32 queue[HDA_UNSOL_QUEUE_SIZE * 2];
- unsigned int rp, wp;
-
- /* workqueue */
- struct work_struct work;
- struct hda_bus *bus;
-};
-
-/*
- * Helper for automatic pin configuration
- */
-
-enum {
- AUTO_PIN_MIC,
- AUTO_PIN_LINE_IN,
- AUTO_PIN_CD,
- AUTO_PIN_AUX,
- AUTO_PIN_LAST
-};
-
-enum {
- AUTO_PIN_LINE_OUT,
- AUTO_PIN_SPEAKER_OUT,
- AUTO_PIN_HP_OUT
-};
-
-#define AUTO_CFG_MAX_OUTS HDA_MAX_OUTS
-#define AUTO_CFG_MAX_INS 8
-
-struct auto_pin_cfg_item {
- hda_nid_t pin;
- int type;
-};
-
-struct auto_pin_cfg;
-const char *hda_get_autocfg_input_label(struct hda_codec *codec,
- const struct auto_pin_cfg *cfg,
- int input);
-int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid,
- const struct auto_pin_cfg *cfg,
- char *label, int maxlen, int *indexp);
-int snd_hda_add_imux_item(struct hda_input_mux *imux, const char *label,
- int index, int *type_index_ret);
-
-enum {
- INPUT_PIN_ATTR_UNUSED, /* pin not connected */
- INPUT_PIN_ATTR_INT, /* internal mic/line-in */
- INPUT_PIN_ATTR_DOCK, /* docking mic/line-in */
- INPUT_PIN_ATTR_NORMAL, /* mic/line-in jack */
- INPUT_PIN_ATTR_FRONT, /* mic/line-in jack in front */
- INPUT_PIN_ATTR_REAR, /* mic/line-in jack in rear */
-};
-
-int snd_hda_get_input_pin_attr(unsigned int def_conf);
-
-struct auto_pin_cfg {
- int line_outs;
- /* sorted in the order of Front/Surr/CLFE/Side */
- hda_nid_t line_out_pins[AUTO_CFG_MAX_OUTS];
- int speaker_outs;
- hda_nid_t speaker_pins[AUTO_CFG_MAX_OUTS];
- int hp_outs;
- int line_out_type; /* AUTO_PIN_XXX_OUT */
- hda_nid_t hp_pins[AUTO_CFG_MAX_OUTS];
- int num_inputs;
- struct auto_pin_cfg_item inputs[AUTO_CFG_MAX_INS];
- int dig_outs;
- hda_nid_t dig_out_pins[2];
- hda_nid_t dig_in_pin;
- hda_nid_t mono_out_pin;
- int dig_out_type[2]; /* HDA_PCM_TYPE_XXX */
- int dig_in_type; /* HDA_PCM_TYPE_XXX */
-};
-
-#define get_defcfg_connect(cfg) \
- ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT)
-#define get_defcfg_association(cfg) \
- ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT)
-#define get_defcfg_location(cfg) \
- ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT)
-#define get_defcfg_sequence(cfg) \
- (cfg & AC_DEFCFG_SEQUENCE)
-#define get_defcfg_device(cfg) \
- ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT)
-#define get_defcfg_misc(cfg) \
- ((cfg & AC_DEFCFG_MISC) >> AC_DEFCFG_MISC_SHIFT)
-
-/* bit-flags for snd_hda_parse_pin_def_config() behavior */
-#define HDA_PINCFG_NO_HP_FIXUP (1 << 0) /* no HP-split */
-#define HDA_PINCFG_NO_LO_FIXUP (1 << 1) /* don't take other outs as LO */
-
-int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
- struct auto_pin_cfg *cfg,
- const hda_nid_t *ignore_nids,
- unsigned int cond_flags);
-
-/* older function */
-#define snd_hda_parse_pin_def_config(codec, cfg, ignore) \
- snd_hda_parse_pin_defcfg(codec, cfg, ignore, 0)
-
-/* amp values */
-#define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8))
-#define AMP_IN_UNMUTE(idx) (0x7000 | ((idx)<<8))
-#define AMP_OUT_MUTE 0xb080
-#define AMP_OUT_UNMUTE 0xb000
-#define AMP_OUT_ZERO 0xb000
-/* pinctl values */
-#define PIN_IN (AC_PINCTL_IN_EN)
-#define PIN_VREFHIZ (AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ)
-#define PIN_VREF50 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_50)
-#define PIN_VREFGRD (AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD)
-#define PIN_VREF80 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_80)
-#define PIN_VREF100 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_100)
-#define PIN_OUT (AC_PINCTL_OUT_EN)
-#define PIN_HP (AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN)
-#define PIN_HP_AMP (AC_PINCTL_HP_EN)
-
-/*
- * get widget capabilities
- */
-static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid)
-{
- if (nid < codec->start_nid ||
- nid >= codec->start_nid + codec->num_nodes)
- return 0;
- return codec->wcaps[nid - codec->start_nid];
-}
-
-/* get the widget type from widget capability bits */
-static inline int get_wcaps_type(unsigned int wcaps)
-{
- if (!wcaps)
- return -1; /* invalid type */
- return (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
-}
-
-static inline unsigned int get_wcaps_channels(u32 wcaps)
-{
- unsigned int chans;
-
- chans = (wcaps & AC_WCAP_CHAN_CNT_EXT) >> 13;
- chans = ((chans << 1) | 1) + 1;
-
- return chans;
-}
-
-u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction);
-int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
- unsigned int caps);
-u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid);
-int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid,
- unsigned int caps);
-
-/* flags for hda_nid_item */
-#define HDA_NID_ITEM_AMP (1<<0)
-
-struct hda_nid_item {
- struct snd_kcontrol *kctl;
- unsigned int index;
- hda_nid_t nid;
- unsigned short flags;
-};
-
-int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
- struct snd_kcontrol *kctl);
-int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
- unsigned int index, hda_nid_t nid);
-void snd_hda_ctls_clear(struct hda_codec *codec);
-
-/*
- * hwdep interface
- */
-#ifdef CONFIG_SND_HDA_HWDEP
-int snd_hda_create_hwdep(struct hda_codec *codec);
-#else
-static inline int snd_hda_create_hwdep(struct hda_codec *codec) { return 0; }
-#endif
-
-#if defined(CONFIG_SND_HDA_POWER_SAVE) && defined(CONFIG_SND_HDA_HWDEP)
-int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec);
-#else
-static inline int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec)
-{
- return 0;
-}
-#endif
-
-#ifdef CONFIG_SND_HDA_RECONFIG
-int snd_hda_hwdep_add_sysfs(struct hda_codec *codec);
-#else
-static inline int snd_hda_hwdep_add_sysfs(struct hda_codec *codec)
-{
- return 0;
-}
-#endif
-
-#ifdef CONFIG_SND_HDA_RECONFIG
-const char *snd_hda_get_hint(struct hda_codec *codec, const char *key);
-int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key);
-#else
-static inline
-const char *snd_hda_get_hint(struct hda_codec *codec, const char *key)
-{
- return NULL;
-}
-
-static inline
-int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key)
-{
- return -ENOENT;
-}
-#endif
-
-/*
- * power-management
- */
-
-void snd_hda_schedule_power_save(struct hda_codec *codec);
-
-struct hda_amp_list {
- hda_nid_t nid;
- unsigned char dir;
- unsigned char idx;
-};
-
-struct hda_loopback_check {
- const struct hda_amp_list *amplist;
- int power_on;
-};
-
-int snd_hda_check_amp_list_power(struct hda_codec *codec,
- struct hda_loopback_check *check,
- hda_nid_t nid);
-
-/*
- * AMP control callbacks
- */
-/* retrieve parameters from private_value */
-#define get_amp_nid_(pv) ((pv) & 0xffff)
-#define get_amp_nid(kc) get_amp_nid_((kc)->private_value)
-#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3)
-#define get_amp_direction_(pv) (((pv) >> 18) & 0x1)
-#define get_amp_direction(kc) get_amp_direction_((kc)->private_value)
-#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf)
-#define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f)
-#define get_amp_min_mute(kc) (((kc)->private_value >> 29) & 0x1)
-
-/*
- * CEA Short Audio Descriptor data
- */
-struct cea_sad {
- int channels;
- int format; /* (format == 0) indicates invalid SAD */
- int rates;
- int sample_bits; /* for LPCM */
- int max_bitrate; /* for AC3...ATRAC */
- int profile; /* for WMAPRO */
-};
-
-#define ELD_FIXED_BYTES 20
-#define ELD_MAX_SIZE 256
-#define ELD_MAX_MNL 16
-#define ELD_MAX_SAD 16
-
-/*
- * ELD: EDID Like Data
- */
-struct hdmi_eld {
- bool monitor_present;
- bool eld_valid;
- int eld_size;
- int baseline_len;
- int eld_ver;
- int cea_edid_ver;
- char monitor_name[ELD_MAX_MNL + 1];
- int manufacture_id;
- int product_id;
- u64 port_id;
- int support_hdcp;
- int support_ai;
- int conn_type;
- int aud_synch_delay;
- int spk_alloc;
- int sad_count;
- struct cea_sad sad[ELD_MAX_SAD];
- /*
- * all fields above eld_buffer will be cleared before updating ELD
- */
- char eld_buffer[ELD_MAX_SIZE];
-#ifdef CONFIG_PROC_FS
- struct snd_info_entry *proc_entry;
-#endif
-};
-
-int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid);
-int snd_hdmi_get_eld(struct hdmi_eld *, struct hda_codec *, hda_nid_t);
-void snd_hdmi_show_eld(struct hdmi_eld *eld);
-void snd_hdmi_eld_update_pcm_info(struct hdmi_eld *eld,
- struct hda_pcm_stream *hinfo);
-
-#ifdef CONFIG_PROC_FS
-int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld,
- int index);
-void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld);
-#else
-static inline int snd_hda_eld_proc_new(struct hda_codec *codec,
- struct hdmi_eld *eld,
- int index)
-{
- return 0;
-}
-static inline void snd_hda_eld_proc_free(struct hda_codec *codec,
- struct hdmi_eld *eld)
-{
-}
-#endif
-
-#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80
-void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen);
-
-#endif /* __SOUND_HDA_LOCAL_H */
diff --git a/ANDROID_3.4.5/sound/pci/hda/hda_proc.c b/ANDROID_3.4.5/sound/pci/hda/hda_proc.c
deleted file mode 100644
index e59e2f05..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/hda_proc.c
+++ /dev/null
@@ -1,742 +0,0 @@
-/*
- * Universal Interface for Intel High Definition Audio Codec
- *
- * Generic proc interface
- *
- * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
- *
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <sound/core.h>
-#include "hda_codec.h"
-#include "hda_local.h"
-
-static char *bits_names(unsigned int bits, char *names[], int size)
-{
- int i, n;
- static char buf[128];
-
- for (i = 0, n = 0; i < size; i++) {
- if (bits & (1U<<i) && names[i])
- n += snprintf(buf + n, sizeof(buf) - n, " %s",
- names[i]);
- }
- buf[n] = '\0';
-
- return buf;
-}
-
-static const char *get_wid_type_name(unsigned int wid_value)
-{
- static char *names[16] = {
- [AC_WID_AUD_OUT] = "Audio Output",
- [AC_WID_AUD_IN] = "Audio Input",
- [AC_WID_AUD_MIX] = "Audio Mixer",
- [AC_WID_AUD_SEL] = "Audio Selector",
- [AC_WID_PIN] = "Pin Complex",
- [AC_WID_POWER] = "Power Widget",
- [AC_WID_VOL_KNB] = "Volume Knob Widget",
- [AC_WID_BEEP] = "Beep Generator Widget",
- [AC_WID_VENDOR] = "Vendor Defined Widget",
- };
- if (wid_value == -1)
- return "UNKNOWN Widget";
- wid_value &= 0xf;
- if (names[wid_value])
- return names[wid_value];
- else
- return "UNKNOWN Widget";
-}
-
-static void print_nid_array(struct snd_info_buffer *buffer,
- struct hda_codec *codec, hda_nid_t nid,
- struct snd_array *array)
-{
- int i;
- struct hda_nid_item *items = array->list, *item;
- struct snd_kcontrol *kctl;
- for (i = 0; i < array->used; i++) {
- item = &items[i];
- if (item->nid == nid) {
- kctl = item->kctl;
- snd_iprintf(buffer,
- " Control: name=\"%s\", index=%i, device=%i\n",
- kctl->id.name, kctl->id.index + item->index,
- kctl->id.device);
- if (item->flags & HDA_NID_ITEM_AMP)
- snd_iprintf(buffer,
- " ControlAmp: chs=%lu, dir=%s, "
- "idx=%lu, ofs=%lu\n",
- get_amp_channels(kctl),
- get_amp_direction(kctl) ? "Out" : "In",
- get_amp_index(kctl),
- get_amp_offset(kctl));
- }
- }
-}
-
-static void print_nid_pcms(struct snd_info_buffer *buffer,
- struct hda_codec *codec, hda_nid_t nid)
-{
- int pcm, type;
- struct hda_pcm *cpcm;
- for (pcm = 0; pcm < codec->num_pcms; pcm++) {
- cpcm = &codec->pcm_info[pcm];
- for (type = 0; type < 2; type++) {
- if (cpcm->stream[type].nid != nid || cpcm->pcm == NULL)
- continue;
- snd_iprintf(buffer, " Device: name=\"%s\", "
- "type=\"%s\", device=%i\n",
- cpcm->name,
- snd_hda_pcm_type_name[cpcm->pcm_type],
- cpcm->pcm->device);
- }
- }
-}
-
-static void print_amp_caps(struct snd_info_buffer *buffer,
- struct hda_codec *codec, hda_nid_t nid, int dir)
-{
- unsigned int caps;
- caps = snd_hda_param_read(codec, nid,
- dir == HDA_OUTPUT ?
- AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP);
- if (caps == -1 || caps == 0) {
- snd_iprintf(buffer, "N/A\n");
- return;
- }
- snd_iprintf(buffer, "ofs=0x%02x, nsteps=0x%02x, stepsize=0x%02x, "
- "mute=%x\n",
- caps & AC_AMPCAP_OFFSET,
- (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT,
- (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT,
- (caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT);
-}
-
-static void print_amp_vals(struct snd_info_buffer *buffer,
- struct hda_codec *codec, hda_nid_t nid,
- int dir, int stereo, int indices)
-{
- unsigned int val;
- int i;
-
- dir = dir == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT;
- for (i = 0; i < indices; i++) {
- snd_iprintf(buffer, " [");
- if (stereo) {
- val = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_AMP_GAIN_MUTE,
- AC_AMP_GET_LEFT | dir | i);
- snd_iprintf(buffer, "0x%02x ", val);
- }
- val = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_AMP_GAIN_MUTE,
- AC_AMP_GET_RIGHT | dir | i);
- snd_iprintf(buffer, "0x%02x]", val);
- }
- snd_iprintf(buffer, "\n");
-}
-
-static void print_pcm_rates(struct snd_info_buffer *buffer, unsigned int pcm)
-{
- static unsigned int rates[] = {
- 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
- 96000, 176400, 192000, 384000
- };
- int i;
-
- pcm &= AC_SUPPCM_RATES;
- snd_iprintf(buffer, " rates [0x%x]:", pcm);
- for (i = 0; i < ARRAY_SIZE(rates); i++)
- if (pcm & (1 << i))
- snd_iprintf(buffer, " %d", rates[i]);
- snd_iprintf(buffer, "\n");
-}
-
-static void print_pcm_bits(struct snd_info_buffer *buffer, unsigned int pcm)
-{
- char buf[SND_PRINT_BITS_ADVISED_BUFSIZE];
-
- snd_iprintf(buffer, " bits [0x%x]:", (pcm >> 16) & 0xff);
- snd_print_pcm_bits(pcm, buf, sizeof(buf));
- snd_iprintf(buffer, "%s\n", buf);
-}
-
-static void print_pcm_formats(struct snd_info_buffer *buffer,
- unsigned int streams)
-{
- snd_iprintf(buffer, " formats [0x%x]:", streams & 0xf);
- if (streams & AC_SUPFMT_PCM)
- snd_iprintf(buffer, " PCM");
- if (streams & AC_SUPFMT_FLOAT32)
- snd_iprintf(buffer, " FLOAT");
- if (streams & AC_SUPFMT_AC3)
- snd_iprintf(buffer, " AC3");
- snd_iprintf(buffer, "\n");
-}
-
-static void print_pcm_caps(struct snd_info_buffer *buffer,
- struct hda_codec *codec, hda_nid_t nid)
-{
- unsigned int pcm = snd_hda_param_read(codec, nid, AC_PAR_PCM);
- unsigned int stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
- if (pcm == -1 || stream == -1) {
- snd_iprintf(buffer, "N/A\n");
- return;
- }
- print_pcm_rates(buffer, pcm);
- print_pcm_bits(buffer, pcm);
- print_pcm_formats(buffer, stream);
-}
-
-static const char *get_jack_connection(u32 cfg)
-{
- static char *names[16] = {
- "Unknown", "1/8", "1/4", "ATAPI",
- "RCA", "Optical","Digital", "Analog",
- "DIN", "XLR", "RJ11", "Comb",
- NULL, NULL, NULL, "Other"
- };
- cfg = (cfg & AC_DEFCFG_CONN_TYPE) >> AC_DEFCFG_CONN_TYPE_SHIFT;
- if (names[cfg])
- return names[cfg];
- else
- return "UNKNOWN";
-}
-
-static const char *get_jack_color(u32 cfg)
-{
- static char *names[16] = {
- "Unknown", "Black", "Grey", "Blue",
- "Green", "Red", "Orange", "Yellow",
- "Purple", "Pink", NULL, NULL,
- NULL, NULL, "White", "Other",
- };
- cfg = (cfg & AC_DEFCFG_COLOR) >> AC_DEFCFG_COLOR_SHIFT;
- if (names[cfg])
- return names[cfg];
- else
- return "UNKNOWN";
-}
-
-static void print_pin_caps(struct snd_info_buffer *buffer,
- struct hda_codec *codec, hda_nid_t nid,
- int *supports_vref)
-{
- static char *jack_conns[4] = { "Jack", "N/A", "Fixed", "Both" };
- unsigned int caps, val;
-
- caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
- snd_iprintf(buffer, " Pincap 0x%08x:", caps);
- if (caps & AC_PINCAP_IN)
- snd_iprintf(buffer, " IN");
- if (caps & AC_PINCAP_OUT)
- snd_iprintf(buffer, " OUT");
- if (caps & AC_PINCAP_HP_DRV)
- snd_iprintf(buffer, " HP");
- if (caps & AC_PINCAP_EAPD)
- snd_iprintf(buffer, " EAPD");
- if (caps & AC_PINCAP_PRES_DETECT)
- snd_iprintf(buffer, " Detect");
- if (caps & AC_PINCAP_BALANCE)
- snd_iprintf(buffer, " Balanced");
- if (caps & AC_PINCAP_HDMI) {
- /* Realtek uses this bit as a different meaning */
- if ((codec->vendor_id >> 16) == 0x10ec)
- snd_iprintf(buffer, " R/L");
- else {
- if (caps & AC_PINCAP_HBR)
- snd_iprintf(buffer, " HBR");
- snd_iprintf(buffer, " HDMI");
- }
- }
- if (caps & AC_PINCAP_DP)
- snd_iprintf(buffer, " DP");
- if (caps & AC_PINCAP_TRIG_REQ)
- snd_iprintf(buffer, " Trigger");
- if (caps & AC_PINCAP_IMP_SENSE)
- snd_iprintf(buffer, " ImpSense");
- snd_iprintf(buffer, "\n");
- if (caps & AC_PINCAP_VREF) {
- unsigned int vref =
- (caps & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
- snd_iprintf(buffer, " Vref caps:");
- if (vref & AC_PINCAP_VREF_HIZ)
- snd_iprintf(buffer, " HIZ");
- if (vref & AC_PINCAP_VREF_50)
- snd_iprintf(buffer, " 50");
- if (vref & AC_PINCAP_VREF_GRD)
- snd_iprintf(buffer, " GRD");
- if (vref & AC_PINCAP_VREF_80)
- snd_iprintf(buffer, " 80");
- if (vref & AC_PINCAP_VREF_100)
- snd_iprintf(buffer, " 100");
- snd_iprintf(buffer, "\n");
- *supports_vref = 1;
- } else
- *supports_vref = 0;
- if (caps & AC_PINCAP_EAPD) {
- val = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_EAPD_BTLENABLE, 0);
- snd_iprintf(buffer, " EAPD 0x%x:", val);
- if (val & AC_EAPDBTL_BALANCED)
- snd_iprintf(buffer, " BALANCED");
- if (val & AC_EAPDBTL_EAPD)
- snd_iprintf(buffer, " EAPD");
- if (val & AC_EAPDBTL_LR_SWAP)
- snd_iprintf(buffer, " R/L");
- snd_iprintf(buffer, "\n");
- }
- caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
- snd_iprintf(buffer, " Pin Default 0x%08x: [%s] %s at %s %s\n", caps,
- jack_conns[(caps & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT],
- snd_hda_get_jack_type(caps),
- snd_hda_get_jack_connectivity(caps),
- snd_hda_get_jack_location(caps));
- snd_iprintf(buffer, " Conn = %s, Color = %s\n",
- get_jack_connection(caps),
- get_jack_color(caps));
- /* Default association and sequence values refer to default grouping
- * of pin complexes and their sequence within the group. This is used
- * for priority and resource allocation.
- */
- snd_iprintf(buffer, " DefAssociation = 0x%x, Sequence = 0x%x\n",
- (caps & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT,
- caps & AC_DEFCFG_SEQUENCE);
- if (((caps & AC_DEFCFG_MISC) >> AC_DEFCFG_MISC_SHIFT) &
- AC_DEFCFG_MISC_NO_PRESENCE) {
- /* Miscellaneous bit indicates external hardware does not
- * support presence detection even if the pin complex
- * indicates it is supported.
- */
- snd_iprintf(buffer, " Misc = NO_PRESENCE\n");
- }
-}
-
-static void print_pin_ctls(struct snd_info_buffer *buffer,
- struct hda_codec *codec, hda_nid_t nid,
- int supports_vref)
-{
- unsigned int pinctls;
-
- pinctls = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
- snd_iprintf(buffer, " Pin-ctls: 0x%02x:", pinctls);
- if (pinctls & AC_PINCTL_IN_EN)
- snd_iprintf(buffer, " IN");
- if (pinctls & AC_PINCTL_OUT_EN)
- snd_iprintf(buffer, " OUT");
- if (pinctls & AC_PINCTL_HP_EN)
- snd_iprintf(buffer, " HP");
- if (supports_vref) {
- int vref = pinctls & AC_PINCTL_VREFEN;
- switch (vref) {
- case AC_PINCTL_VREF_HIZ:
- snd_iprintf(buffer, " VREF_HIZ");
- break;
- case AC_PINCTL_VREF_50:
- snd_iprintf(buffer, " VREF_50");
- break;
- case AC_PINCTL_VREF_GRD:
- snd_iprintf(buffer, " VREF_GRD");
- break;
- case AC_PINCTL_VREF_80:
- snd_iprintf(buffer, " VREF_80");
- break;
- case AC_PINCTL_VREF_100:
- snd_iprintf(buffer, " VREF_100");
- break;
- }
- }
- snd_iprintf(buffer, "\n");
-}
-
-static void print_vol_knob(struct snd_info_buffer *buffer,
- struct hda_codec *codec, hda_nid_t nid)
-{
- unsigned int cap = snd_hda_param_read(codec, nid,
- AC_PAR_VOL_KNB_CAP);
- snd_iprintf(buffer, " Volume-Knob: delta=%d, steps=%d, ",
- (cap >> 7) & 1, cap & 0x7f);
- cap = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
- snd_iprintf(buffer, "direct=%d, val=%d\n",
- (cap >> 7) & 1, cap & 0x7f);
-}
-
-static void print_audio_io(struct snd_info_buffer *buffer,
- struct hda_codec *codec, hda_nid_t nid,
- unsigned int wid_type)
-{
- int conv = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
- snd_iprintf(buffer,
- " Converter: stream=%d, channel=%d\n",
- (conv & AC_CONV_STREAM) >> AC_CONV_STREAM_SHIFT,
- conv & AC_CONV_CHANNEL);
-
- if (wid_type == AC_WID_AUD_IN && (conv & AC_CONV_CHANNEL) == 0) {
- int sdi = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_SDI_SELECT, 0);
- snd_iprintf(buffer, " SDI-Select: %d\n",
- sdi & AC_SDI_SELECT);
- }
-}
-
-static void print_digital_conv(struct snd_info_buffer *buffer,
- struct hda_codec *codec, hda_nid_t nid)
-{
- unsigned int digi1 = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_DIGI_CONVERT_1, 0);
- snd_iprintf(buffer, " Digital:");
- if (digi1 & AC_DIG1_ENABLE)
- snd_iprintf(buffer, " Enabled");
- if (digi1 & AC_DIG1_V)
- snd_iprintf(buffer, " Validity");
- if (digi1 & AC_DIG1_VCFG)
- snd_iprintf(buffer, " ValidityCfg");
- if (digi1 & AC_DIG1_EMPHASIS)
- snd_iprintf(buffer, " Preemphasis");
- if (digi1 & AC_DIG1_COPYRIGHT)
- snd_iprintf(buffer, " Copyright");
- if (digi1 & AC_DIG1_NONAUDIO)
- snd_iprintf(buffer, " Non-Audio");
- if (digi1 & AC_DIG1_PROFESSIONAL)
- snd_iprintf(buffer, " Pro");
- if (digi1 & AC_DIG1_LEVEL)
- snd_iprintf(buffer, " GenLevel");
- snd_iprintf(buffer, "\n");
- snd_iprintf(buffer, " Digital category: 0x%x\n",
- (digi1 >> 8) & AC_DIG2_CC);
-}
-
-static const char *get_pwr_state(u32 state)
-{
- static const char * const buf[4] = {
- "D0", "D1", "D2", "D3"
- };
- if (state < 4)
- return buf[state];
- return "UNKNOWN";
-}
-
-static void print_power_state(struct snd_info_buffer *buffer,
- struct hda_codec *codec, hda_nid_t nid)
-{
- static char *names[] = {
- [ilog2(AC_PWRST_D0SUP)] = "D0",
- [ilog2(AC_PWRST_D1SUP)] = "D1",
- [ilog2(AC_PWRST_D2SUP)] = "D2",
- [ilog2(AC_PWRST_D3SUP)] = "D3",
- [ilog2(AC_PWRST_D3COLDSUP)] = "D3cold",
- [ilog2(AC_PWRST_S3D3COLDSUP)] = "S3D3cold",
- [ilog2(AC_PWRST_CLKSTOP)] = "CLKSTOP",
- [ilog2(AC_PWRST_EPSS)] = "EPSS",
- };
-
- int sup = snd_hda_param_read(codec, nid, AC_PAR_POWER_STATE);
- int pwr = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_POWER_STATE, 0);
- if (sup)
- snd_iprintf(buffer, " Power states: %s\n",
- bits_names(sup, names, ARRAY_SIZE(names)));
-
- snd_iprintf(buffer, " Power: setting=%s, actual=%s\n",
- get_pwr_state(pwr & AC_PWRST_SETTING),
- get_pwr_state((pwr & AC_PWRST_ACTUAL) >>
- AC_PWRST_ACTUAL_SHIFT));
-}
-
-static void print_unsol_cap(struct snd_info_buffer *buffer,
- struct hda_codec *codec, hda_nid_t nid)
-{
- int unsol = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_UNSOLICITED_RESPONSE, 0);
- snd_iprintf(buffer,
- " Unsolicited: tag=%02x, enabled=%d\n",
- unsol & AC_UNSOL_TAG,
- (unsol & AC_UNSOL_ENABLED) ? 1 : 0);
-}
-
-static void print_proc_caps(struct snd_info_buffer *buffer,
- struct hda_codec *codec, hda_nid_t nid)
-{
- unsigned int proc_caps = snd_hda_param_read(codec, nid,
- AC_PAR_PROC_CAP);
- snd_iprintf(buffer, " Processing caps: benign=%d, ncoeff=%d\n",
- proc_caps & AC_PCAP_BENIGN,
- (proc_caps & AC_PCAP_NUM_COEF) >> AC_PCAP_NUM_COEF_SHIFT);
-}
-
-static void print_conn_list(struct snd_info_buffer *buffer,
- struct hda_codec *codec, hda_nid_t nid,
- unsigned int wid_type, hda_nid_t *conn,
- int conn_len)
-{
- int c, curr = -1;
-
- if (conn_len > 1 &&
- wid_type != AC_WID_AUD_MIX &&
- wid_type != AC_WID_VOL_KNB &&
- wid_type != AC_WID_POWER)
- curr = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_CONNECT_SEL, 0);
- snd_iprintf(buffer, " Connection: %d\n", conn_len);
- if (conn_len > 0) {
- snd_iprintf(buffer, " ");
- for (c = 0; c < conn_len; c++) {
- snd_iprintf(buffer, " 0x%02x", conn[c]);
- if (c == curr)
- snd_iprintf(buffer, "*");
- }
- snd_iprintf(buffer, "\n");
- }
-}
-
-static void print_gpio(struct snd_info_buffer *buffer,
- struct hda_codec *codec, hda_nid_t nid)
-{
- unsigned int gpio =
- snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP);
- unsigned int enable, direction, wake, unsol, sticky, data;
- int i, max;
- snd_iprintf(buffer, "GPIO: io=%d, o=%d, i=%d, "
- "unsolicited=%d, wake=%d\n",
- gpio & AC_GPIO_IO_COUNT,
- (gpio & AC_GPIO_O_COUNT) >> AC_GPIO_O_COUNT_SHIFT,
- (gpio & AC_GPIO_I_COUNT) >> AC_GPIO_I_COUNT_SHIFT,
- (gpio & AC_GPIO_UNSOLICITED) ? 1 : 0,
- (gpio & AC_GPIO_WAKE) ? 1 : 0);
- max = gpio & AC_GPIO_IO_COUNT;
- if (!max || max > 8)
- return;
- enable = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_GPIO_MASK, 0);
- direction = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_GPIO_DIRECTION, 0);
- wake = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_GPIO_WAKE_MASK, 0);
- unsol = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK, 0);
- sticky = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_GPIO_STICKY_MASK, 0);
- data = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_GPIO_DATA, 0);
- for (i = 0; i < max; ++i)
- snd_iprintf(buffer,
- " IO[%d]: enable=%d, dir=%d, wake=%d, "
- "sticky=%d, data=%d, unsol=%d\n", i,
- (enable & (1<<i)) ? 1 : 0,
- (direction & (1<<i)) ? 1 : 0,
- (wake & (1<<i)) ? 1 : 0,
- (sticky & (1<<i)) ? 1 : 0,
- (data & (1<<i)) ? 1 : 0,
- (unsol & (1<<i)) ? 1 : 0);
- /* FIXME: add GPO and GPI pin information */
- print_nid_array(buffer, codec, nid, &codec->mixers);
- print_nid_array(buffer, codec, nid, &codec->nids);
-}
-
-static void print_codec_info(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct hda_codec *codec = entry->private_data;
- hda_nid_t nid;
- int i, nodes;
-
- snd_iprintf(buffer, "Codec: ");
- if (codec->vendor_name && codec->chip_name)
- snd_iprintf(buffer, "%s %s\n",
- codec->vendor_name, codec->chip_name);
- else
- snd_iprintf(buffer, "Not Set\n");
- snd_iprintf(buffer, "Address: %d\n", codec->addr);
- if (codec->afg)
- snd_iprintf(buffer, "AFG Function Id: 0x%x (unsol %u)\n",
- codec->afg_function_id, codec->afg_unsol);
- if (codec->mfg)
- snd_iprintf(buffer, "MFG Function Id: 0x%x (unsol %u)\n",
- codec->mfg_function_id, codec->mfg_unsol);
- snd_iprintf(buffer, "Vendor Id: 0x%08x\n", codec->vendor_id);
- snd_iprintf(buffer, "Subsystem Id: 0x%08x\n", codec->subsystem_id);
- snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id);
-
- if (codec->mfg)
- snd_iprintf(buffer, "Modem Function Group: 0x%x\n", codec->mfg);
- else
- snd_iprintf(buffer, "No Modem Function Group found\n");
-
- if (! codec->afg)
- return;
- snd_hda_power_up(codec);
- snd_iprintf(buffer, "Default PCM:\n");
- print_pcm_caps(buffer, codec, codec->afg);
- snd_iprintf(buffer, "Default Amp-In caps: ");
- print_amp_caps(buffer, codec, codec->afg, HDA_INPUT);
- snd_iprintf(buffer, "Default Amp-Out caps: ");
- print_amp_caps(buffer, codec, codec->afg, HDA_OUTPUT);
-
- nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
- if (! nid || nodes < 0) {
- snd_iprintf(buffer, "Invalid AFG subtree\n");
- snd_hda_power_down(codec);
- return;
- }
-
- print_gpio(buffer, codec, codec->afg);
- if (codec->proc_widget_hook)
- codec->proc_widget_hook(buffer, codec, codec->afg);
-
- for (i = 0; i < nodes; i++, nid++) {
- unsigned int wid_caps =
- snd_hda_param_read(codec, nid,
- AC_PAR_AUDIO_WIDGET_CAP);
- unsigned int wid_type = get_wcaps_type(wid_caps);
- hda_nid_t conn[HDA_MAX_CONNECTIONS];
- int conn_len = 0;
-
- snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid,
- get_wid_type_name(wid_type), wid_caps);
- if (wid_caps & AC_WCAP_STEREO) {
- unsigned int chans = get_wcaps_channels(wid_caps);
- if (chans == 2)
- snd_iprintf(buffer, " Stereo");
- else
- snd_iprintf(buffer, " %d-Channels", chans);
- } else
- snd_iprintf(buffer, " Mono");
- if (wid_caps & AC_WCAP_DIGITAL)
- snd_iprintf(buffer, " Digital");
- if (wid_caps & AC_WCAP_IN_AMP)
- snd_iprintf(buffer, " Amp-In");
- if (wid_caps & AC_WCAP_OUT_AMP)
- snd_iprintf(buffer, " Amp-Out");
- if (wid_caps & AC_WCAP_STRIPE)
- snd_iprintf(buffer, " Stripe");
- if (wid_caps & AC_WCAP_LR_SWAP)
- snd_iprintf(buffer, " R/L");
- if (wid_caps & AC_WCAP_CP_CAPS)
- snd_iprintf(buffer, " CP");
- snd_iprintf(buffer, "\n");
-
- print_nid_array(buffer, codec, nid, &codec->mixers);
- print_nid_array(buffer, codec, nid, &codec->nids);
- print_nid_pcms(buffer, codec, nid);
-
- /* volume knob is a special widget that always have connection
- * list
- */
- if (wid_type == AC_WID_VOL_KNB)
- wid_caps |= AC_WCAP_CONN_LIST;
-
- if (wid_caps & AC_WCAP_CONN_LIST)
- conn_len = snd_hda_get_raw_connections(codec, nid, conn,
- HDA_MAX_CONNECTIONS);
-
- if (wid_caps & AC_WCAP_IN_AMP) {
- snd_iprintf(buffer, " Amp-In caps: ");
- print_amp_caps(buffer, codec, nid, HDA_INPUT);
- snd_iprintf(buffer, " Amp-In vals: ");
- if (wid_type == AC_WID_PIN ||
- (codec->single_adc_amp &&
- wid_type == AC_WID_AUD_IN))
- print_amp_vals(buffer, codec, nid, HDA_INPUT,
- wid_caps & AC_WCAP_STEREO,
- 1);
- else
- print_amp_vals(buffer, codec, nid, HDA_INPUT,
- wid_caps & AC_WCAP_STEREO,
- conn_len);
- }
- if (wid_caps & AC_WCAP_OUT_AMP) {
- snd_iprintf(buffer, " Amp-Out caps: ");
- print_amp_caps(buffer, codec, nid, HDA_OUTPUT);
- snd_iprintf(buffer, " Amp-Out vals: ");
- if (wid_type == AC_WID_PIN &&
- codec->pin_amp_workaround)
- print_amp_vals(buffer, codec, nid, HDA_OUTPUT,
- wid_caps & AC_WCAP_STEREO,
- conn_len);
- else
- print_amp_vals(buffer, codec, nid, HDA_OUTPUT,
- wid_caps & AC_WCAP_STEREO, 1);
- }
-
- switch (wid_type) {
- case AC_WID_PIN: {
- int supports_vref;
- print_pin_caps(buffer, codec, nid, &supports_vref);
- print_pin_ctls(buffer, codec, nid, supports_vref);
- break;
- }
- case AC_WID_VOL_KNB:
- print_vol_knob(buffer, codec, nid);
- break;
- case AC_WID_AUD_OUT:
- case AC_WID_AUD_IN:
- print_audio_io(buffer, codec, nid, wid_type);
- if (wid_caps & AC_WCAP_DIGITAL)
- print_digital_conv(buffer, codec, nid);
- if (wid_caps & AC_WCAP_FORMAT_OVRD) {
- snd_iprintf(buffer, " PCM:\n");
- print_pcm_caps(buffer, codec, nid);
- }
- break;
- }
-
- if (wid_caps & AC_WCAP_UNSOL_CAP)
- print_unsol_cap(buffer, codec, nid);
-
- if (wid_caps & AC_WCAP_POWER)
- print_power_state(buffer, codec, nid);
-
- if (wid_caps & AC_WCAP_DELAY)
- snd_iprintf(buffer, " Delay: %d samples\n",
- (wid_caps & AC_WCAP_DELAY) >>
- AC_WCAP_DELAY_SHIFT);
-
- if (wid_caps & AC_WCAP_CONN_LIST)
- print_conn_list(buffer, codec, nid, wid_type,
- conn, conn_len);
-
- if (wid_caps & AC_WCAP_PROC_WID)
- print_proc_caps(buffer, codec, nid);
-
- if (codec->proc_widget_hook)
- codec->proc_widget_hook(buffer, codec, nid);
- }
- snd_hda_power_down(codec);
-}
-
-/*
- * create a proc read
- */
-int snd_hda_codec_proc_new(struct hda_codec *codec)
-{
- char name[32];
- struct snd_info_entry *entry;
- int err;
-
- snprintf(name, sizeof(name), "codec#%d", codec->addr);
- err = snd_card_proc_new(codec->bus->card, name, &entry);
- if (err < 0)
- return err;
-
- snd_info_set_text_ops(entry, codec, print_codec_info);
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/pci/hda/hda_trace.h b/ANDROID_3.4.5/sound/pci/hda/hda_trace.h
deleted file mode 100644
index 9884871d..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/hda_trace.h
+++ /dev/null
@@ -1,117 +0,0 @@
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM hda
-#define TRACE_INCLUDE_FILE hda_trace
-
-#if !defined(_TRACE_HDA_H) || defined(TRACE_HEADER_MULTI_READ)
-#define _TRACE_HDA_H
-
-#include <linux/tracepoint.h>
-
-struct hda_bus;
-struct hda_codec;
-
-DECLARE_EVENT_CLASS(hda_cmd,
-
- TP_PROTO(struct hda_codec *codec, unsigned int val),
-
- TP_ARGS(codec, val),
-
- TP_STRUCT__entry(
- __field( unsigned int, card )
- __field( unsigned int, addr )
- __field( unsigned int, val )
- ),
-
- TP_fast_assign(
- __entry->card = (codec)->bus->card->number;
- __entry->addr = (codec)->addr;
- __entry->val = (val);
- ),
-
- TP_printk("[%d:%d] val=%x", __entry->card, __entry->addr, __entry->val)
-);
-
-DEFINE_EVENT(hda_cmd, hda_send_cmd,
- TP_PROTO(struct hda_codec *codec, unsigned int val),
- TP_ARGS(codec, val)
-);
-
-DEFINE_EVENT(hda_cmd, hda_get_response,
- TP_PROTO(struct hda_codec *codec, unsigned int val),
- TP_ARGS(codec, val)
-);
-
-TRACE_EVENT(hda_bus_reset,
-
- TP_PROTO(struct hda_bus *bus),
-
- TP_ARGS(bus),
-
- TP_STRUCT__entry(
- __field( unsigned int, card )
- ),
-
- TP_fast_assign(
- __entry->card = (bus)->card->number;
- ),
-
- TP_printk("[%d]", __entry->card)
-);
-
-DECLARE_EVENT_CLASS(hda_power,
-
- TP_PROTO(struct hda_codec *codec),
-
- TP_ARGS(codec),
-
- TP_STRUCT__entry(
- __field( unsigned int, card )
- __field( unsigned int, addr )
- ),
-
- TP_fast_assign(
- __entry->card = (codec)->bus->card->number;
- __entry->addr = (codec)->addr;
- ),
-
- TP_printk("[%d:%d]", __entry->card, __entry->addr)
-);
-
-DEFINE_EVENT(hda_power, hda_power_down,
- TP_PROTO(struct hda_codec *codec),
- TP_ARGS(codec)
-);
-
-DEFINE_EVENT(hda_power, hda_power_up,
- TP_PROTO(struct hda_codec *codec),
- TP_ARGS(codec)
-);
-
-TRACE_EVENT(hda_unsol_event,
-
- TP_PROTO(struct hda_bus *bus, u32 res, u32 res_ex),
-
- TP_ARGS(bus, res, res_ex),
-
- TP_STRUCT__entry(
- __field( unsigned int, card )
- __field( u32, res )
- __field( u32, res_ex )
- ),
-
- TP_fast_assign(
- __entry->card = (bus)->card->number;
- __entry->res = res;
- __entry->res_ex = res_ex;
- ),
-
- TP_printk("[%d] res=%x, res_ex=%x", __entry->card,
- __entry->res, __entry->res_ex)
-);
-
-#endif /* _TRACE_HDA_H */
-
-/* This part must be outside protection */
-#undef TRACE_INCLUDE_PATH
-#define TRACE_INCLUDE_PATH .
-#include <trace/define_trace.h>
diff --git a/ANDROID_3.4.5/sound/pci/hda/patch_analog.c b/ANDROID_3.4.5/sound/pci/hda/patch_analog.c
deleted file mode 100644
index 71433939..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/patch_analog.c
+++ /dev/null
@@ -1,5067 +0,0 @@
-/*
- * HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984,
- * AD1986A, AD1988
- *
- * Copyright (c) 2005-2007 Takashi Iwai <tiwai@suse.de>
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-
-#include <sound/core.h>
-#include "hda_codec.h"
-#include "hda_local.h"
-#include "hda_beep.h"
-#include "hda_jack.h"
-
-struct ad198x_spec {
- const struct snd_kcontrol_new *mixers[6];
- int num_mixers;
- unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
- const struct hda_verb *init_verbs[6]; /* initialization verbs
- * don't forget NULL termination!
- */
- unsigned int num_init_verbs;
-
- /* playback */
- struct hda_multi_out multiout; /* playback set-up
- * max_channels, dacs must be set
- * dig_out_nid and hp_nid are optional
- */
- unsigned int cur_eapd;
- unsigned int need_dac_fix;
-
- const hda_nid_t *alt_dac_nid;
- const struct hda_pcm_stream *stream_analog_alt_playback;
- int independent_hp;
- int num_active_streams;
-
- /* capture */
- unsigned int num_adc_nids;
- const hda_nid_t *adc_nids;
- hda_nid_t dig_in_nid; /* digital-in NID; optional */
-
- /* capture source */
- const struct hda_input_mux *input_mux;
- const hda_nid_t *capsrc_nids;
- unsigned int cur_mux[3];
-
- /* channel model */
- const struct hda_channel_mode *channel_mode;
- int num_channel_mode;
-
- /* PCM information */
- struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
-
- unsigned int spdif_route;
-
- /* dynamic controls, init_verbs and input_mux */
- struct auto_pin_cfg autocfg;
- struct snd_array kctls;
- struct hda_input_mux private_imux;
- hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
-
- unsigned int jack_present: 1;
- unsigned int inv_jack_detect: 1;/* inverted jack-detection */
- unsigned int inv_eapd: 1; /* inverted EAPD implementation */
- unsigned int analog_beep: 1; /* analog beep input present */
- unsigned int avoid_init_slave_vol:1;
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- struct hda_loopback_check loopback;
-#endif
- /* for virtual master */
- hda_nid_t vmaster_nid;
- const char * const *slave_vols;
- const char * const *slave_sws;
-};
-
-/*
- * input MUX handling (common part)
- */
-static int ad198x_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ad198x_spec *spec = codec->spec;
-
- return snd_hda_input_mux_info(spec->input_mux, uinfo);
-}
-
-static int ad198x_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ad198x_spec *spec = codec->spec;
- unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-
- ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
- return 0;
-}
-
-static int ad198x_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ad198x_spec *spec = codec->spec;
- unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-
- return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
- spec->capsrc_nids[adc_idx],
- &spec->cur_mux[adc_idx]);
-}
-
-/*
- * initialization (common callbacks)
- */
-static int ad198x_init(struct hda_codec *codec)
-{
- struct ad198x_spec *spec = codec->spec;
- int i;
-
- for (i = 0; i < spec->num_init_verbs; i++)
- snd_hda_sequence_write(codec, spec->init_verbs[i]);
- return 0;
-}
-
-static const char * const ad_slave_pfxs[] = {
- "Front", "Surround", "Center", "LFE", "Side",
- "Headphone", "Mono", "Speaker", "IEC958",
- NULL
-};
-
-static const char * const ad1988_6stack_fp_slave_pfxs[] = {
- "Front", "Surround", "Center", "LFE", "Side", "IEC958",
- NULL
-};
-
-static void ad198x_free_kctls(struct hda_codec *codec);
-
-#ifdef CONFIG_SND_HDA_INPUT_BEEP
-/* additional beep mixers; the actual parameters are overwritten at build */
-static const struct snd_kcontrol_new ad_beep_mixer[] = {
- HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT),
- HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new ad_beep2_mixer[] = {
- HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0, 0, HDA_OUTPUT),
- HDA_CODEC_MUTE_BEEP("Digital Beep Playback Switch", 0, 0, HDA_OUTPUT),
- { } /* end */
-};
-
-#define set_beep_amp(spec, nid, idx, dir) \
- ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */
-#else
-#define set_beep_amp(spec, nid, idx, dir) /* NOP */
-#endif
-
-static int ad198x_build_controls(struct hda_codec *codec)
-{
- struct ad198x_spec *spec = codec->spec;
- struct snd_kcontrol *kctl;
- unsigned int i;
- int err;
-
- for (i = 0; i < spec->num_mixers; i++) {
- err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
- if (err < 0)
- return err;
- }
- if (spec->multiout.dig_out_nid) {
- err = snd_hda_create_spdif_out_ctls(codec,
- spec->multiout.dig_out_nid,
- spec->multiout.dig_out_nid);
- if (err < 0)
- return err;
- err = snd_hda_create_spdif_share_sw(codec,
- &spec->multiout);
- if (err < 0)
- return err;
- spec->multiout.share_spdif = 1;
- }
- if (spec->dig_in_nid) {
- err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
- if (err < 0)
- return err;
- }
-
- /* create beep controls if needed */
-#ifdef CONFIG_SND_HDA_INPUT_BEEP
- if (spec->beep_amp) {
- const struct snd_kcontrol_new *knew;
- knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer;
- for ( ; knew->name; knew++) {
- struct snd_kcontrol *kctl;
- kctl = snd_ctl_new1(knew, codec);
- if (!kctl)
- return -ENOMEM;
- kctl->private_value = spec->beep_amp;
- err = snd_hda_ctl_add(codec, 0, kctl);
- if (err < 0)
- return err;
- }
- }
-#endif
-
- /* if we have no master control, let's create it */
- if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
- unsigned int vmaster_tlv[4];
- snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
- HDA_OUTPUT, vmaster_tlv);
- err = __snd_hda_add_vmaster(codec, "Master Playback Volume",
- vmaster_tlv,
- (spec->slave_vols ?
- spec->slave_vols : ad_slave_pfxs),
- "Playback Volume",
- !spec->avoid_init_slave_vol, NULL);
- if (err < 0)
- return err;
- }
- if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
- err = snd_hda_add_vmaster(codec, "Master Playback Switch",
- NULL,
- (spec->slave_sws ?
- spec->slave_sws : ad_slave_pfxs),
- "Playback Switch");
- if (err < 0)
- return err;
- }
-
- ad198x_free_kctls(codec); /* no longer needed */
-
- /* assign Capture Source enums to NID */
- kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
- if (!kctl)
- kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
- for (i = 0; kctl && i < kctl->count; i++) {
- err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]);
- if (err < 0)
- return err;
- }
-
- /* assign IEC958 enums to NID */
- kctl = snd_hda_find_mixer_ctl(codec,
- SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source");
- if (kctl) {
- err = snd_hda_add_nid(codec, kctl, 0,
- spec->multiout.dig_out_nid);
- if (err < 0)
- return err;
- }
-
- return 0;
-}
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static int ad198x_check_power_status(struct hda_codec *codec, hda_nid_t nid)
-{
- struct ad198x_spec *spec = codec->spec;
- return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
-}
-#endif
-
-static void activate_ctl(struct hda_codec *codec, const char *name, int active)
-{
- struct snd_kcontrol *ctl = snd_hda_find_mixer_ctl(codec, name);
- if (ctl) {
- ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- ctl->vd[0].access |= active ? 0 :
- SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_WRITE;
- ctl->vd[0].access |= active ?
- SNDRV_CTL_ELEM_ACCESS_WRITE : 0;
- snd_ctl_notify(codec->bus->card,
- SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
- }
-}
-
-static void set_stream_active(struct hda_codec *codec, bool active)
-{
- struct ad198x_spec *spec = codec->spec;
- if (active)
- spec->num_active_streams++;
- else
- spec->num_active_streams--;
- activate_ctl(codec, "Independent HP", spec->num_active_streams == 0);
-}
-
-static int ad1988_independent_hp_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static const char * const texts[] = { "OFF", "ON", NULL};
- int index;
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- index = uinfo->value.enumerated.item;
- if (index >= 2)
- index = 1;
- strcpy(uinfo->value.enumerated.name, texts[index]);
- return 0;
-}
-
-static int ad1988_independent_hp_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ad198x_spec *spec = codec->spec;
- ucontrol->value.enumerated.item[0] = spec->independent_hp;
- return 0;
-}
-
-static int ad1988_independent_hp_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ad198x_spec *spec = codec->spec;
- unsigned int select = ucontrol->value.enumerated.item[0];
- if (spec->independent_hp != select) {
- spec->independent_hp = select;
- if (spec->independent_hp)
- spec->multiout.hp_nid = 0;
- else
- spec->multiout.hp_nid = spec->alt_dac_nid[0];
- return 1;
- }
- return 0;
-}
-
-/*
- * Analog playback callbacks
- */
-static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct ad198x_spec *spec = codec->spec;
- int err;
- set_stream_active(codec, true);
- err = snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
- hinfo);
- if (err < 0) {
- set_stream_active(codec, false);
- return err;
- }
- return 0;
-}
-
-static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct ad198x_spec *spec = codec->spec;
- return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
- format, substream);
-}
-
-static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct ad198x_spec *spec = codec->spec;
- return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
-}
-
-static int ad198x_playback_pcm_close(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- set_stream_active(codec, false);
- return 0;
-}
-
-static int ad1988_alt_playback_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct ad198x_spec *spec = codec->spec;
- if (!spec->independent_hp)
- return -EBUSY;
- set_stream_active(codec, true);
- return 0;
-}
-
-static int ad1988_alt_playback_pcm_close(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- set_stream_active(codec, false);
- return 0;
-}
-
-static const struct hda_pcm_stream ad198x_pcm_analog_alt_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .ops = {
- .open = ad1988_alt_playback_pcm_open,
- .close = ad1988_alt_playback_pcm_close
- },
-};
-
-/*
- * Digital out
- */
-static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct ad198x_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_open(codec, &spec->multiout);
-}
-
-static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct ad198x_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_close(codec, &spec->multiout);
-}
-
-static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct ad198x_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
- format, substream);
-}
-
-static int ad198x_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct ad198x_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
-}
-
-/*
- * Analog capture
- */
-static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct ad198x_spec *spec = codec->spec;
- snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
- stream_tag, 0, format);
- return 0;
-}
-
-static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct ad198x_spec *spec = codec->spec;
- snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
- return 0;
-}
-
-/*
- */
-static const struct hda_pcm_stream ad198x_pcm_analog_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 6, /* changed later */
- .nid = 0, /* fill later */
- .ops = {
- .open = ad198x_playback_pcm_open,
- .prepare = ad198x_playback_pcm_prepare,
- .cleanup = ad198x_playback_pcm_cleanup,
- .close = ad198x_playback_pcm_close
- },
-};
-
-static const struct hda_pcm_stream ad198x_pcm_analog_capture = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .nid = 0, /* fill later */
- .ops = {
- .prepare = ad198x_capture_pcm_prepare,
- .cleanup = ad198x_capture_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream ad198x_pcm_digital_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .nid = 0, /* fill later */
- .ops = {
- .open = ad198x_dig_playback_pcm_open,
- .close = ad198x_dig_playback_pcm_close,
- .prepare = ad198x_dig_playback_pcm_prepare,
- .cleanup = ad198x_dig_playback_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream ad198x_pcm_digital_capture = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- /* NID is set in alc_build_pcms */
-};
-
-static int ad198x_build_pcms(struct hda_codec *codec)
-{
- struct ad198x_spec *spec = codec->spec;
- struct hda_pcm *info = spec->pcm_rec;
-
- codec->num_pcms = 1;
- codec->pcm_info = info;
-
- info->name = "AD198x Analog";
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_analog_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
- info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
-
- if (spec->multiout.dig_out_nid) {
- info++;
- codec->num_pcms++;
- info->name = "AD198x Digital";
- info->pcm_type = HDA_PCM_TYPE_SPDIF;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
- if (spec->dig_in_nid) {
- info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
- }
- }
-
- if (spec->alt_dac_nid && spec->stream_analog_alt_playback) {
- codec->num_pcms++;
- info = spec->pcm_rec + 2;
- info->name = "AD198x Headphone";
- info->pcm_type = HDA_PCM_TYPE_AUDIO;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
- *spec->stream_analog_alt_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
- spec->alt_dac_nid[0];
- }
-
- return 0;
-}
-
-static void ad198x_free_kctls(struct hda_codec *codec)
-{
- struct ad198x_spec *spec = codec->spec;
-
- if (spec->kctls.list) {
- struct snd_kcontrol_new *kctl = spec->kctls.list;
- int i;
- for (i = 0; i < spec->kctls.used; i++)
- kfree(kctl[i].name);
- }
- snd_array_free(&spec->kctls);
-}
-
-static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
- hda_nid_t hp)
-{
- struct ad198x_spec *spec = codec->spec;
- if (snd_hda_query_pin_caps(codec, front) & AC_PINCAP_EAPD)
- snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE,
- !spec->inv_eapd ? 0x00 : 0x02);
- if (snd_hda_query_pin_caps(codec, hp) & AC_PINCAP_EAPD)
- snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE,
- !spec->inv_eapd ? 0x00 : 0x02);
-}
-
-static void ad198x_power_eapd(struct hda_codec *codec)
-{
- /* We currently only handle front, HP */
- switch (codec->vendor_id) {
- case 0x11d41882:
- case 0x11d4882a:
- case 0x11d41884:
- case 0x11d41984:
- case 0x11d41883:
- case 0x11d4184a:
- case 0x11d4194a:
- case 0x11d4194b:
- case 0x11d41988:
- case 0x11d4198b:
- case 0x11d4989a:
- case 0x11d4989b:
- ad198x_power_eapd_write(codec, 0x12, 0x11);
- break;
- case 0x11d41981:
- case 0x11d41983:
- ad198x_power_eapd_write(codec, 0x05, 0x06);
- break;
- case 0x11d41986:
- ad198x_power_eapd_write(codec, 0x1b, 0x1a);
- break;
- }
-}
-
-static void ad198x_shutup(struct hda_codec *codec)
-{
- snd_hda_shutup_pins(codec);
- ad198x_power_eapd(codec);
-}
-
-static void ad198x_free(struct hda_codec *codec)
-{
- struct ad198x_spec *spec = codec->spec;
-
- if (!spec)
- return;
-
- ad198x_shutup(codec);
- ad198x_free_kctls(codec);
- kfree(spec);
- snd_hda_detach_beep_device(codec);
-}
-
-#ifdef CONFIG_PM
-static int ad198x_suspend(struct hda_codec *codec, pm_message_t state)
-{
- ad198x_shutup(codec);
- return 0;
-}
-#endif
-
-static const struct hda_codec_ops ad198x_patch_ops = {
- .build_controls = ad198x_build_controls,
- .build_pcms = ad198x_build_pcms,
- .init = ad198x_init,
- .free = ad198x_free,
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- .check_power_status = ad198x_check_power_status,
-#endif
-#ifdef CONFIG_PM
- .suspend = ad198x_suspend,
-#endif
- .reboot_notify = ad198x_shutup,
-};
-
-
-/*
- * EAPD control
- * the private value = nid
- */
-#define ad198x_eapd_info snd_ctl_boolean_mono_info
-
-static int ad198x_eapd_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ad198x_spec *spec = codec->spec;
- if (spec->inv_eapd)
- ucontrol->value.integer.value[0] = ! spec->cur_eapd;
- else
- ucontrol->value.integer.value[0] = spec->cur_eapd;
- return 0;
-}
-
-static int ad198x_eapd_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ad198x_spec *spec = codec->spec;
- hda_nid_t nid = kcontrol->private_value & 0xff;
- unsigned int eapd;
- eapd = !!ucontrol->value.integer.value[0];
- if (spec->inv_eapd)
- eapd = !eapd;
- if (eapd == spec->cur_eapd)
- return 0;
- spec->cur_eapd = eapd;
- snd_hda_codec_write_cache(codec, nid,
- 0, AC_VERB_SET_EAPD_BTLENABLE,
- eapd ? 0x02 : 0x00);
- return 1;
-}
-
-static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo);
-static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-
-
-/*
- * AD1986A specific
- */
-
-#define AD1986A_SPDIF_OUT 0x02
-#define AD1986A_FRONT_DAC 0x03
-#define AD1986A_SURR_DAC 0x04
-#define AD1986A_CLFE_DAC 0x05
-#define AD1986A_ADC 0x06
-
-static const hda_nid_t ad1986a_dac_nids[3] = {
- AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
-};
-static const hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC };
-static const hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 };
-
-static const struct hda_input_mux ad1986a_capture_source = {
- .num_items = 7,
- .items = {
- { "Mic", 0x0 },
- { "CD", 0x1 },
- { "Aux", 0x3 },
- { "Line", 0x4 },
- { "Mix", 0x5 },
- { "Mono", 0x6 },
- { "Phone", 0x7 },
- },
-};
-
-
-static const struct hda_bind_ctls ad1986a_bind_pcm_vol = {
- .ops = &snd_hda_bind_vol,
- .values = {
- HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
- HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
- HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
- 0
- },
-};
-
-static const struct hda_bind_ctls ad1986a_bind_pcm_sw = {
- .ops = &snd_hda_bind_sw,
- .values = {
- HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
- HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
- HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
- 0
- },
-};
-
-/*
- * mixers
- */
-static const struct snd_kcontrol_new ad1986a_mixers[] = {
- /*
- * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
- */
- HDA_BIND_VOL("PCM Playback Volume", &ad1986a_bind_pcm_vol),
- HDA_BIND_SW("PCM Playback Switch", &ad1986a_bind_pcm_sw),
- HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = ad198x_mux_enum_info,
- .get = ad198x_mux_enum_get,
- .put = ad198x_mux_enum_put,
- },
- HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT),
- { } /* end */
-};
-
-/* additional mixers for 3stack mode */
-static const struct snd_kcontrol_new ad1986a_3st_mixers[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Channel Mode",
- .info = ad198x_ch_mode_info,
- .get = ad198x_ch_mode_get,
- .put = ad198x_ch_mode_put,
- },
- { } /* end */
-};
-
-/* laptop model - 2ch only */
-static const hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC };
-
-/* master controls both pins 0x1a and 0x1b */
-static const struct hda_bind_ctls ad1986a_laptop_master_vol = {
- .ops = &snd_hda_bind_vol,
- .values = {
- HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
- HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
- 0,
- },
-};
-
-static const struct hda_bind_ctls ad1986a_laptop_master_sw = {
- .ops = &snd_hda_bind_sw,
- .values = {
- HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
- HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
- 0,
- },
-};
-
-static const struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
- HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
- HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
- HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
- /*
- HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */
- HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = ad198x_mux_enum_info,
- .get = ad198x_mux_enum_get,
- .put = ad198x_mux_enum_put,
- },
- { } /* end */
-};
-
-/* laptop-eapd model - 2ch only */
-
-static const struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
- .num_items = 3,
- .items = {
- { "Mic", 0x0 },
- { "Internal Mic", 0x4 },
- { "Mix", 0x5 },
- },
-};
-
-static const struct hda_input_mux ad1986a_automic_capture_source = {
- .num_items = 2,
- .items = {
- { "Mic", 0x0 },
- { "Mix", 0x5 },
- },
-};
-
-static const struct snd_kcontrol_new ad1986a_laptop_master_mixers[] = {
- HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
- HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
- HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = ad198x_mux_enum_info,
- .get = ad198x_mux_enum_get,
- .put = ad198x_mux_enum_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "External Amplifier",
- .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
- .info = ad198x_eapd_info,
- .get = ad198x_eapd_get,
- .put = ad198x_eapd_put,
- .private_value = 0x1b, /* port-D */
- },
- { } /* end */
-};
-
-static const struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = {
- HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT),
- { } /* end */
-};
-
-/* re-connect the mic boost input according to the jack sensing */
-static void ad1986a_automic(struct hda_codec *codec)
-{
- unsigned int present;
- present = snd_hda_jack_detect(codec, 0x1f);
- /* 0 = 0x1f, 2 = 0x1d, 4 = mixed */
- snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_CONNECT_SEL,
- present ? 0 : 2);
-}
-
-#define AD1986A_MIC_EVENT 0x36
-
-static void ad1986a_automic_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- if ((res >> 26) != AD1986A_MIC_EVENT)
- return;
- ad1986a_automic(codec);
-}
-
-static int ad1986a_automic_init(struct hda_codec *codec)
-{
- ad198x_init(codec);
- ad1986a_automic(codec);
- return 0;
-}
-
-/* laptop-automute - 2ch only */
-
-static void ad1986a_update_hp(struct hda_codec *codec)
-{
- struct ad198x_spec *spec = codec->spec;
- unsigned int mute;
-
- if (spec->jack_present)
- mute = HDA_AMP_MUTE; /* mute internal speaker */
- else
- /* unmute internal speaker if necessary */
- mute = snd_hda_codec_amp_read(codec, 0x1a, 0, HDA_OUTPUT, 0);
- snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, mute);
-}
-
-static void ad1986a_hp_automute(struct hda_codec *codec)
-{
- struct ad198x_spec *spec = codec->spec;
-
- spec->jack_present = snd_hda_jack_detect(codec, 0x1a);
- if (spec->inv_jack_detect)
- spec->jack_present = !spec->jack_present;
- ad1986a_update_hp(codec);
-}
-
-#define AD1986A_HP_EVENT 0x37
-
-static void ad1986a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- if ((res >> 26) != AD1986A_HP_EVENT)
- return;
- ad1986a_hp_automute(codec);
-}
-
-static int ad1986a_hp_init(struct hda_codec *codec)
-{
- ad198x_init(codec);
- ad1986a_hp_automute(codec);
- return 0;
-}
-
-/* bind hp and internal speaker mute (with plug check) */
-static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- long *valp = ucontrol->value.integer.value;
- int change;
-
- change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0,
- HDA_AMP_MUTE,
- valp[0] ? 0 : HDA_AMP_MUTE);
- change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0,
- HDA_AMP_MUTE,
- valp[1] ? 0 : HDA_AMP_MUTE);
- if (change)
- ad1986a_update_hp(codec);
- return change;
-}
-
-static const struct snd_kcontrol_new ad1986a_automute_master_mixers[] = {
- HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .subdevice = HDA_SUBDEV_AMP_FLAG,
- .info = snd_hda_mixer_amp_switch_info,
- .get = snd_hda_mixer_amp_switch_get,
- .put = ad1986a_hp_master_sw_put,
- .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
- },
- { } /* end */
-};
-
-
-/*
- * initialization verbs
- */
-static const struct hda_verb ad1986a_init_verbs[] = {
- /* Front, Surround, CLFE DAC; mute as default */
- {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- /* Downmix - off */
- {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- /* HP, Line-Out, Surround, CLFE selectors */
- {0x0a, AC_VERB_SET_CONNECT_SEL, 0x0},
- {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0},
- {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
- {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
- /* Mono selector */
- {0x0e, AC_VERB_SET_CONNECT_SEL, 0x0},
- /* Mic selector: Mic 1/2 pin */
- {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
- /* Line-in selector: Line-in */
- {0x10, AC_VERB_SET_CONNECT_SEL, 0x0},
- /* Mic 1/2 swap */
- {0x11, AC_VERB_SET_CONNECT_SEL, 0x0},
- /* Record selector: mic */
- {0x12, AC_VERB_SET_CONNECT_SEL, 0x0},
- /* Mic, Phone, CD, Aux, Line-In amp; mute as default */
- {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- /* PC beep */
- {0x18, AC_VERB_SET_CONNECT_SEL, 0x0},
- /* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */
- {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- /* HP Pin */
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
- /* Front, Surround, CLFE Pins */
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
- {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
- {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
- /* Mono Pin */
- {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
- /* Mic Pin */
- {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
- /* Line, Aux, CD, Beep-In Pin */
- {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
- {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
- {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
- {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
- {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
- { } /* end */
-};
-
-static const struct hda_verb ad1986a_ch2_init[] = {
- /* Surround out -> Line In */
- { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
- /* Line-in selectors */
- { 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 },
- /* CLFE -> Mic in */
- { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
- /* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */
- { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
- { } /* end */
-};
-
-static const struct hda_verb ad1986a_ch4_init[] = {
- /* Surround out -> Surround */
- { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
- /* CLFE -> Mic in */
- { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
- { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
- { } /* end */
-};
-
-static const struct hda_verb ad1986a_ch6_init[] = {
- /* Surround out -> Surround out */
- { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
- /* CLFE -> CLFE */
- { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 },
- { } /* end */
-};
-
-static const struct hda_channel_mode ad1986a_modes[3] = {
- { 2, ad1986a_ch2_init },
- { 4, ad1986a_ch4_init },
- { 6, ad1986a_ch6_init },
-};
-
-/* eapd initialization */
-static const struct hda_verb ad1986a_eapd_init_verbs[] = {
- {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
- {}
-};
-
-static const struct hda_verb ad1986a_automic_verbs[] = {
- {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- /*{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},*/
- {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
- {0x1f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_MIC_EVENT},
- {}
-};
-
-/* Ultra initialization */
-static const struct hda_verb ad1986a_ultra_init[] = {
- /* eapd initialization */
- { 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
- /* CLFE -> Mic in */
- { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2 },
- { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
- { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
- { } /* end */
-};
-
-/* pin sensing on HP jack */
-static const struct hda_verb ad1986a_hp_init_verbs[] = {
- {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT},
- {}
-};
-
-static void ad1986a_samsung_p50_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- switch (res >> 26) {
- case AD1986A_HP_EVENT:
- ad1986a_hp_automute(codec);
- break;
- case AD1986A_MIC_EVENT:
- ad1986a_automic(codec);
- break;
- }
-}
-
-static int ad1986a_samsung_p50_init(struct hda_codec *codec)
-{
- ad198x_init(codec);
- ad1986a_hp_automute(codec);
- ad1986a_automic(codec);
- return 0;
-}
-
-
-/* models */
-enum {
- AD1986A_6STACK,
- AD1986A_3STACK,
- AD1986A_LAPTOP,
- AD1986A_LAPTOP_EAPD,
- AD1986A_LAPTOP_AUTOMUTE,
- AD1986A_ULTRA,
- AD1986A_SAMSUNG,
- AD1986A_SAMSUNG_P50,
- AD1986A_MODELS
-};
-
-static const char * const ad1986a_models[AD1986A_MODELS] = {
- [AD1986A_6STACK] = "6stack",
- [AD1986A_3STACK] = "3stack",
- [AD1986A_LAPTOP] = "laptop",
- [AD1986A_LAPTOP_EAPD] = "laptop-eapd",
- [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute",
- [AD1986A_ULTRA] = "ultra",
- [AD1986A_SAMSUNG] = "samsung",
- [AD1986A_SAMSUNG_P50] = "samsung-p50",
-};
-
-static const struct snd_pci_quirk ad1986a_cfg_tbl[] = {
- SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD),
- SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD),
- SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD),
- SND_PCI_QUIRK(0x1043, 0x1213, "ASUS A6J", AD1986A_LAPTOP_EAPD),
- SND_PCI_QUIRK(0x1043, 0x1263, "ASUS U5F", AD1986A_LAPTOP_EAPD),
- SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD),
- SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD),
- SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD),
- SND_PCI_QUIRK(0x1043, 0x1443, "ASUS VX1", AD1986A_LAPTOP),
- SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8J", AD1986A_3STACK),
- SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK),
- SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP),
- SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK),
- SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK),
- SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK),
- SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK),
- SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40-10Q", AD1986A_3STACK),
- SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK),
- SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
- SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50),
- SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA),
- SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_SAMSUNG),
- SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK),
- SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP),
- SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK),
- SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_AUTOMUTE),
- SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP),
- {}
-};
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static const struct hda_amp_list ad1986a_loopbacks[] = {
- { 0x13, HDA_OUTPUT, 0 }, /* Mic */
- { 0x14, HDA_OUTPUT, 0 }, /* Phone */
- { 0x15, HDA_OUTPUT, 0 }, /* CD */
- { 0x16, HDA_OUTPUT, 0 }, /* Aux */
- { 0x17, HDA_OUTPUT, 0 }, /* Line */
- { } /* end */
-};
-#endif
-
-static int is_jack_available(struct hda_codec *codec, hda_nid_t nid)
-{
- unsigned int conf = snd_hda_codec_get_pincfg(codec, nid);
- return get_defcfg_connect(conf) != AC_JACK_PORT_NONE;
-}
-
-static int patch_ad1986a(struct hda_codec *codec)
-{
- struct ad198x_spec *spec;
- int err, board_config;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->spec = spec;
-
- err = snd_hda_attach_beep_device(codec, 0x19);
- if (err < 0) {
- ad198x_free(codec);
- return err;
- }
- set_beep_amp(spec, 0x18, 0, HDA_OUTPUT);
-
- spec->multiout.max_channels = 6;
- spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
- spec->multiout.dac_nids = ad1986a_dac_nids;
- spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
- spec->num_adc_nids = 1;
- spec->adc_nids = ad1986a_adc_nids;
- spec->capsrc_nids = ad1986a_capsrc_nids;
- spec->input_mux = &ad1986a_capture_source;
- spec->num_mixers = 1;
- spec->mixers[0] = ad1986a_mixers;
- spec->num_init_verbs = 1;
- spec->init_verbs[0] = ad1986a_init_verbs;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- spec->loopback.amplist = ad1986a_loopbacks;
-#endif
- spec->vmaster_nid = 0x1b;
- spec->inv_eapd = 1; /* AD1986A has the inverted EAPD implementation */
-
- codec->patch_ops = ad198x_patch_ops;
-
- /* override some parameters */
- board_config = snd_hda_check_board_config(codec, AD1986A_MODELS,
- ad1986a_models,
- ad1986a_cfg_tbl);
- switch (board_config) {
- case AD1986A_3STACK:
- spec->num_mixers = 2;
- spec->mixers[1] = ad1986a_3st_mixers;
- spec->num_init_verbs = 2;
- spec->init_verbs[1] = ad1986a_ch2_init;
- spec->channel_mode = ad1986a_modes;
- spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes);
- spec->need_dac_fix = 1;
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = 1;
- break;
- case AD1986A_LAPTOP:
- spec->mixers[0] = ad1986a_laptop_mixers;
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = 1;
- spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
- break;
- case AD1986A_LAPTOP_EAPD:
- spec->num_mixers = 3;
- spec->mixers[0] = ad1986a_laptop_master_mixers;
- spec->mixers[1] = ad1986a_laptop_eapd_mixers;
- spec->mixers[2] = ad1986a_laptop_intmic_mixers;
- spec->num_init_verbs = 2;
- spec->init_verbs[1] = ad1986a_eapd_init_verbs;
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = 1;
- spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
- if (!is_jack_available(codec, 0x25))
- spec->multiout.dig_out_nid = 0;
- spec->input_mux = &ad1986a_laptop_eapd_capture_source;
- break;
- case AD1986A_SAMSUNG:
- spec->num_mixers = 2;
- spec->mixers[0] = ad1986a_laptop_master_mixers;
- spec->mixers[1] = ad1986a_laptop_eapd_mixers;
- spec->num_init_verbs = 3;
- spec->init_verbs[1] = ad1986a_eapd_init_verbs;
- spec->init_verbs[2] = ad1986a_automic_verbs;
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = 1;
- spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
- if (!is_jack_available(codec, 0x25))
- spec->multiout.dig_out_nid = 0;
- spec->input_mux = &ad1986a_automic_capture_source;
- codec->patch_ops.unsol_event = ad1986a_automic_unsol_event;
- codec->patch_ops.init = ad1986a_automic_init;
- break;
- case AD1986A_SAMSUNG_P50:
- spec->num_mixers = 2;
- spec->mixers[0] = ad1986a_automute_master_mixers;
- spec->mixers[1] = ad1986a_laptop_eapd_mixers;
- spec->num_init_verbs = 4;
- spec->init_verbs[1] = ad1986a_eapd_init_verbs;
- spec->init_verbs[2] = ad1986a_automic_verbs;
- spec->init_verbs[3] = ad1986a_hp_init_verbs;
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = 1;
- spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
- if (!is_jack_available(codec, 0x25))
- spec->multiout.dig_out_nid = 0;
- spec->input_mux = &ad1986a_automic_capture_source;
- codec->patch_ops.unsol_event = ad1986a_samsung_p50_unsol_event;
- codec->patch_ops.init = ad1986a_samsung_p50_init;
- break;
- case AD1986A_LAPTOP_AUTOMUTE:
- spec->num_mixers = 3;
- spec->mixers[0] = ad1986a_automute_master_mixers;
- spec->mixers[1] = ad1986a_laptop_eapd_mixers;
- spec->mixers[2] = ad1986a_laptop_intmic_mixers;
- spec->num_init_verbs = 3;
- spec->init_verbs[1] = ad1986a_eapd_init_verbs;
- spec->init_verbs[2] = ad1986a_hp_init_verbs;
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = 1;
- spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
- if (!is_jack_available(codec, 0x25))
- spec->multiout.dig_out_nid = 0;
- spec->input_mux = &ad1986a_laptop_eapd_capture_source;
- codec->patch_ops.unsol_event = ad1986a_hp_unsol_event;
- codec->patch_ops.init = ad1986a_hp_init;
- /* Lenovo N100 seems to report the reversed bit
- * for HP jack-sensing
- */
- spec->inv_jack_detect = 1;
- break;
- case AD1986A_ULTRA:
- spec->mixers[0] = ad1986a_laptop_eapd_mixers;
- spec->num_init_verbs = 2;
- spec->init_verbs[1] = ad1986a_ultra_init;
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = 1;
- spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
- spec->multiout.dig_out_nid = 0;
- break;
- }
-
- /* AD1986A has a hardware problem that it can't share a stream
- * with multiple output pins. The copy of front to surrounds
- * causes noisy or silent outputs at a certain timing, e.g.
- * changing the volume.
- * So, let's disable the shared stream.
- */
- spec->multiout.no_share_stream = 1;
-
- codec->no_trigger_sense = 1;
- codec->no_sticky_stream = 1;
-
- return 0;
-}
-
-/*
- * AD1983 specific
- */
-
-#define AD1983_SPDIF_OUT 0x02
-#define AD1983_DAC 0x03
-#define AD1983_ADC 0x04
-
-static const hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
-static const hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
-static const hda_nid_t ad1983_capsrc_nids[1] = { 0x15 };
-
-static const struct hda_input_mux ad1983_capture_source = {
- .num_items = 4,
- .items = {
- { "Mic", 0x0 },
- { "Line", 0x1 },
- { "Mix", 0x2 },
- { "Mix Mono", 0x3 },
- },
-};
-
-/*
- * SPDIF playback route
- */
-static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static const char * const texts[] = { "PCM", "ADC" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item > 1)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int ad1983_spdif_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ad198x_spec *spec = codec->spec;
-
- ucontrol->value.enumerated.item[0] = spec->spdif_route;
- return 0;
-}
-
-static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ad198x_spec *spec = codec->spec;
-
- if (ucontrol->value.enumerated.item[0] > 1)
- return -EINVAL;
- if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
- spec->spdif_route = ucontrol->value.enumerated.item[0];
- snd_hda_codec_write_cache(codec, spec->multiout.dig_out_nid, 0,
- AC_VERB_SET_CONNECT_SEL,
- spec->spdif_route);
- return 1;
- }
- return 0;
-}
-
-static const struct snd_kcontrol_new ad1983_mixers[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = ad198x_mux_enum_info,
- .get = ad198x_mux_enum_get,
- .put = ad198x_mux_enum_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
- .info = ad1983_spdif_route_info,
- .get = ad1983_spdif_route_get,
- .put = ad1983_spdif_route_put,
- },
- { } /* end */
-};
-
-static const struct hda_verb ad1983_init_verbs[] = {
- /* Front, HP, Mono; mute as default */
- {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- /* Beep, PCM, Mic, Line-In: mute */
- {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- /* Front, HP selectors; from Mix */
- {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
- {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
- /* Mono selector; from Mix */
- {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
- /* Mic selector; Mic */
- {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
- /* Line-in selector: Line-in */
- {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
- /* Mic boost: 0dB */
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
- /* Record selector: mic */
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- /* SPDIF route: PCM */
- {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
- /* Front Pin */
- {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
- /* HP Pin */
- {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
- /* Mono Pin */
- {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
- /* Mic Pin */
- {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
- /* Line Pin */
- {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
- { } /* end */
-};
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static const struct hda_amp_list ad1983_loopbacks[] = {
- { 0x12, HDA_OUTPUT, 0 }, /* Mic */
- { 0x13, HDA_OUTPUT, 0 }, /* Line */
- { } /* end */
-};
-#endif
-
-static int patch_ad1983(struct hda_codec *codec)
-{
- struct ad198x_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->spec = spec;
-
- err = snd_hda_attach_beep_device(codec, 0x10);
- if (err < 0) {
- ad198x_free(codec);
- return err;
- }
- set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
-
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
- spec->multiout.dac_nids = ad1983_dac_nids;
- spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
- spec->num_adc_nids = 1;
- spec->adc_nids = ad1983_adc_nids;
- spec->capsrc_nids = ad1983_capsrc_nids;
- spec->input_mux = &ad1983_capture_source;
- spec->num_mixers = 1;
- spec->mixers[0] = ad1983_mixers;
- spec->num_init_verbs = 1;
- spec->init_verbs[0] = ad1983_init_verbs;
- spec->spdif_route = 0;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- spec->loopback.amplist = ad1983_loopbacks;
-#endif
- spec->vmaster_nid = 0x05;
-
- codec->patch_ops = ad198x_patch_ops;
-
- codec->no_trigger_sense = 1;
- codec->no_sticky_stream = 1;
-
- return 0;
-}
-
-
-/*
- * AD1981 HD specific
- */
-
-#define AD1981_SPDIF_OUT 0x02
-#define AD1981_DAC 0x03
-#define AD1981_ADC 0x04
-
-static const hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
-static const hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
-static const hda_nid_t ad1981_capsrc_nids[1] = { 0x15 };
-
-/* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
-static const struct hda_input_mux ad1981_capture_source = {
- .num_items = 7,
- .items = {
- { "Front Mic", 0x0 },
- { "Line", 0x1 },
- { "Mix", 0x2 },
- { "Mix Mono", 0x3 },
- { "CD", 0x4 },
- { "Mic", 0x6 },
- { "Aux", 0x7 },
- },
-};
-
-static const struct snd_kcontrol_new ad1981_mixers[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = ad198x_mux_enum_info,
- .get = ad198x_mux_enum_get,
- .put = ad198x_mux_enum_put,
- },
- /* identical with AD1983 */
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
- .info = ad1983_spdif_route_info,
- .get = ad1983_spdif_route_get,
- .put = ad1983_spdif_route_put,
- },
- { } /* end */
-};
-
-static const struct hda_verb ad1981_init_verbs[] = {
- /* Front, HP, Mono; mute as default */
- {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- /* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */
- {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- /* Front, HP selectors; from Mix */
- {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
- {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
- /* Mono selector; from Mix */
- {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
- /* Mic Mixer; select Front Mic */
- {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
- {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- /* Mic boost: 0dB */
- {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- /* Record selector: Front mic */
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- /* SPDIF route: PCM */
- {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
- /* Front Pin */
- {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
- /* HP Pin */
- {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
- /* Mono Pin */
- {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
- /* Front & Rear Mic Pins */
- {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
- {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
- /* Line Pin */
- {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
- /* Digital Beep */
- {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
- /* Line-Out as Input: disabled */
- {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- { } /* end */
-};
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static const struct hda_amp_list ad1981_loopbacks[] = {
- { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */
- { 0x13, HDA_OUTPUT, 0 }, /* Line */
- { 0x1b, HDA_OUTPUT, 0 }, /* Aux */
- { 0x1c, HDA_OUTPUT, 0 }, /* Mic */
- { 0x1d, HDA_OUTPUT, 0 }, /* CD */
- { } /* end */
-};
-#endif
-
-/*
- * Patch for HP nx6320
- *
- * nx6320 uses EAPD in the reverse way - EAPD-on means the internal
- * speaker output enabled _and_ mute-LED off.
- */
-
-#define AD1981_HP_EVENT 0x37
-#define AD1981_MIC_EVENT 0x38
-
-static const struct hda_verb ad1981_hp_init_verbs[] = {
- {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */
- /* pin sensing on HP and Mic jacks */
- {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
- {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
- {}
-};
-
-/* turn on/off EAPD (+ mute HP) as a master switch */
-static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ad198x_spec *spec = codec->spec;
-
- if (! ad198x_eapd_put(kcontrol, ucontrol))
- return 0;
- /* change speaker pin appropriately */
- snd_hda_codec_write(codec, 0x05, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- spec->cur_eapd ? PIN_OUT : 0);
- /* toggle HP mute appropriately */
- snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0,
- HDA_AMP_MUTE,
- spec->cur_eapd ? 0 : HDA_AMP_MUTE);
- return 1;
-}
-
-/* bind volumes of both NID 0x05 and 0x06 */
-static const struct hda_bind_ctls ad1981_hp_bind_master_vol = {
- .ops = &snd_hda_bind_vol,
- .values = {
- HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
- HDA_COMPOSE_AMP_VAL(0x06, 3, 0, HDA_OUTPUT),
- 0
- },
-};
-
-/* mute internal speaker if HP is plugged */
-static void ad1981_hp_automute(struct hda_codec *codec)
-{
- unsigned int present;
-
- present = snd_hda_jack_detect(codec, 0x06);
- snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
-}
-
-/* toggle input of built-in and mic jack appropriately */
-static void ad1981_hp_automic(struct hda_codec *codec)
-{
- static const struct hda_verb mic_jack_on[] = {
- {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
- {}
- };
- static const struct hda_verb mic_jack_off[] = {
- {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
- {}
- };
- unsigned int present;
-
- present = snd_hda_jack_detect(codec, 0x08);
- if (present)
- snd_hda_sequence_write(codec, mic_jack_on);
- else
- snd_hda_sequence_write(codec, mic_jack_off);
-}
-
-/* unsolicited event for HP jack sensing */
-static void ad1981_hp_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- res >>= 26;
- switch (res) {
- case AD1981_HP_EVENT:
- ad1981_hp_automute(codec);
- break;
- case AD1981_MIC_EVENT:
- ad1981_hp_automic(codec);
- break;
- }
-}
-
-static const struct hda_input_mux ad1981_hp_capture_source = {
- .num_items = 3,
- .items = {
- { "Mic", 0x0 },
- { "Docking-Station", 0x1 },
- { "Mix", 0x2 },
- },
-};
-
-static const struct snd_kcontrol_new ad1981_hp_mixers[] = {
- HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .subdevice = HDA_SUBDEV_NID_FLAG | 0x05,
- .name = "Master Playback Switch",
- .info = ad198x_eapd_info,
- .get = ad198x_eapd_get,
- .put = ad1981_hp_master_sw_put,
- .private_value = 0x05,
- },
- HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
-#if 0
- /* FIXME: analog mic/line loopback doesn't work with my tests...
- * (although recording is OK)
- */
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Docking-Station Playback Volume", 0x13, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Docking-Station Playback Switch", 0x13, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
- /* FIXME: does this laptop have analog CD connection? */
- HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
-#endif
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x18, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = ad198x_mux_enum_info,
- .get = ad198x_mux_enum_get,
- .put = ad198x_mux_enum_put,
- },
- { } /* end */
-};
-
-/* initialize jack-sensing, too */
-static int ad1981_hp_init(struct hda_codec *codec)
-{
- ad198x_init(codec);
- ad1981_hp_automute(codec);
- ad1981_hp_automic(codec);
- return 0;
-}
-
-/* configuration for Toshiba Laptops */
-static const struct hda_verb ad1981_toshiba_init_verbs[] = {
- {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */
- /* pin sensing on HP and Mic jacks */
- {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
- {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
- {}
-};
-
-static const struct snd_kcontrol_new ad1981_toshiba_mixers[] = {
- HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT),
- { }
-};
-
-/* configuration for Lenovo Thinkpad T60 */
-static const struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
- HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = ad198x_mux_enum_info,
- .get = ad198x_mux_enum_get,
- .put = ad198x_mux_enum_put,
- },
- /* identical with AD1983 */
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
- .info = ad1983_spdif_route_info,
- .get = ad1983_spdif_route_get,
- .put = ad1983_spdif_route_put,
- },
- { } /* end */
-};
-
-static const struct hda_input_mux ad1981_thinkpad_capture_source = {
- .num_items = 3,
- .items = {
- { "Mic", 0x0 },
- { "Mix", 0x2 },
- { "CD", 0x4 },
- },
-};
-
-/* models */
-enum {
- AD1981_BASIC,
- AD1981_HP,
- AD1981_THINKPAD,
- AD1981_TOSHIBA,
- AD1981_MODELS
-};
-
-static const char * const ad1981_models[AD1981_MODELS] = {
- [AD1981_HP] = "hp",
- [AD1981_THINKPAD] = "thinkpad",
- [AD1981_BASIC] = "basic",
- [AD1981_TOSHIBA] = "toshiba"
-};
-
-static const struct snd_pci_quirk ad1981_cfg_tbl[] = {
- SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
- SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD),
- /* All HP models */
- SND_PCI_QUIRK_VENDOR(0x103c, "HP nx", AD1981_HP),
- SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA),
- /* Lenovo Thinkpad T60/X60/Z6xx */
- SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1981_THINKPAD),
- /* HP nx6320 (reversed SSID, H/W bug) */
- SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP),
- {}
-};
-
-static int patch_ad1981(struct hda_codec *codec)
-{
- struct ad198x_spec *spec;
- int err, board_config;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->spec = spec;
-
- err = snd_hda_attach_beep_device(codec, 0x10);
- if (err < 0) {
- ad198x_free(codec);
- return err;
- }
- set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT);
-
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
- spec->multiout.dac_nids = ad1981_dac_nids;
- spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
- spec->num_adc_nids = 1;
- spec->adc_nids = ad1981_adc_nids;
- spec->capsrc_nids = ad1981_capsrc_nids;
- spec->input_mux = &ad1981_capture_source;
- spec->num_mixers = 1;
- spec->mixers[0] = ad1981_mixers;
- spec->num_init_verbs = 1;
- spec->init_verbs[0] = ad1981_init_verbs;
- spec->spdif_route = 0;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- spec->loopback.amplist = ad1981_loopbacks;
-#endif
- spec->vmaster_nid = 0x05;
-
- codec->patch_ops = ad198x_patch_ops;
-
- /* override some parameters */
- board_config = snd_hda_check_board_config(codec, AD1981_MODELS,
- ad1981_models,
- ad1981_cfg_tbl);
- switch (board_config) {
- case AD1981_HP:
- spec->mixers[0] = ad1981_hp_mixers;
- spec->num_init_verbs = 2;
- spec->init_verbs[1] = ad1981_hp_init_verbs;
- if (!is_jack_available(codec, 0x0a))
- spec->multiout.dig_out_nid = 0;
- spec->input_mux = &ad1981_hp_capture_source;
-
- codec->patch_ops.init = ad1981_hp_init;
- codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
- /* set the upper-limit for mixer amp to 0dB for avoiding the
- * possible damage by overloading
- */
- snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
- (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
- (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
- (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
- (1 << AC_AMPCAP_MUTE_SHIFT));
- break;
- case AD1981_THINKPAD:
- spec->mixers[0] = ad1981_thinkpad_mixers;
- spec->input_mux = &ad1981_thinkpad_capture_source;
- /* set the upper-limit for mixer amp to 0dB for avoiding the
- * possible damage by overloading
- */
- snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
- (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
- (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
- (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
- (1 << AC_AMPCAP_MUTE_SHIFT));
- break;
- case AD1981_TOSHIBA:
- spec->mixers[0] = ad1981_hp_mixers;
- spec->mixers[1] = ad1981_toshiba_mixers;
- spec->num_init_verbs = 2;
- spec->init_verbs[1] = ad1981_toshiba_init_verbs;
- spec->multiout.dig_out_nid = 0;
- spec->input_mux = &ad1981_hp_capture_source;
- codec->patch_ops.init = ad1981_hp_init;
- codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
- break;
- }
-
- codec->no_trigger_sense = 1;
- codec->no_sticky_stream = 1;
-
- return 0;
-}
-
-
-/*
- * AD1988
- *
- * Output pins and routes
- *
- * Pin Mix Sel DAC (*)
- * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06
- * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06
- * port-C 0x15 (mute) <- 0x2c <- 0x31 <- 05/0a
- * port-D 0x12 (mute/hp) <- 0x29 <- 04
- * port-E 0x17 (mute/hp) <- 0x26 <- 0x32 <- 05/0a
- * port-F 0x16 (mute) <- 0x2a <- 06
- * port-G 0x24 (mute) <- 0x27 <- 05
- * port-H 0x25 (mute) <- 0x28 <- 0a
- * mono 0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06
- *
- * DAC0 = 03h, DAC1 = 04h, DAC2 = 05h, DAC3 = 06h, DAC4 = 0ah
- * (*) DAC2/3/4 are swapped to DAC3/4/2 on AD198A rev.2 due to a h/w bug.
- *
- * Input pins and routes
- *
- * pin boost mix input # / adc input #
- * port-A 0x11 -> 0x38 -> mix 2, ADC 0
- * port-B 0x14 -> 0x39 -> mix 0, ADC 1
- * port-C 0x15 -> 0x3a -> 33:0 - mix 1, ADC 2
- * port-D 0x12 -> 0x3d -> mix 3, ADC 8
- * port-E 0x17 -> 0x3c -> 34:0 - mix 4, ADC 4
- * port-F 0x16 -> 0x3b -> mix 5, ADC 3
- * port-G 0x24 -> N/A -> 33:1 - mix 1, 34:1 - mix 4, ADC 6
- * port-H 0x25 -> N/A -> 33:2 - mix 1, 34:2 - mix 4, ADC 7
- *
- *
- * DAC assignment
- * 6stack - front/surr/CLFE/side/opt DACs - 04/06/05/0a/03
- * 3stack - front/surr/CLFE/opt DACs - 04/05/0a/03
- *
- * Inputs of Analog Mix (0x20)
- * 0:Port-B (front mic)
- * 1:Port-C/G/H (line-in)
- * 2:Port-A
- * 3:Port-D (line-in/2)
- * 4:Port-E/G/H (mic-in)
- * 5:Port-F (mic2-in)
- * 6:CD
- * 7:Beep
- *
- * ADC selection
- * 0:Port-A
- * 1:Port-B (front mic-in)
- * 2:Port-C (line-in)
- * 3:Port-F (mic2-in)
- * 4:Port-E (mic-in)
- * 5:CD
- * 6:Port-G
- * 7:Port-H
- * 8:Port-D (line-in/2)
- * 9:Mix
- *
- * Proposed pin assignments by the datasheet
- *
- * 6-stack
- * Port-A front headphone
- * B front mic-in
- * C rear line-in
- * D rear front-out
- * E rear mic-in
- * F rear surround
- * G rear CLFE
- * H rear side
- *
- * 3-stack
- * Port-A front headphone
- * B front mic
- * C rear line-in/surround
- * D rear front-out
- * E rear mic-in/CLFE
- *
- * laptop
- * Port-A headphone
- * B mic-in
- * C docking station
- * D internal speaker (with EAPD)
- * E/F quad mic array
- */
-
-
-/* models */
-enum {
- AD1988_6STACK,
- AD1988_6STACK_DIG,
- AD1988_3STACK,
- AD1988_3STACK_DIG,
- AD1988_LAPTOP,
- AD1988_LAPTOP_DIG,
- AD1988_AUTO,
- AD1988_MODEL_LAST,
-};
-
-/* reivision id to check workarounds */
-#define AD1988A_REV2 0x100200
-
-#define is_rev2(codec) \
- ((codec)->vendor_id == 0x11d41988 && \
- (codec)->revision_id == AD1988A_REV2)
-
-/*
- * mixers
- */
-
-static const hda_nid_t ad1988_6stack_dac_nids[4] = {
- 0x04, 0x06, 0x05, 0x0a
-};
-
-static const hda_nid_t ad1988_3stack_dac_nids[3] = {
- 0x04, 0x05, 0x0a
-};
-
-/* for AD1988A revision-2, DAC2-4 are swapped */
-static const hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
- 0x04, 0x05, 0x0a, 0x06
-};
-
-static const hda_nid_t ad1988_alt_dac_nid[1] = {
- 0x03
-};
-
-static const hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
- 0x04, 0x0a, 0x06
-};
-
-static const hda_nid_t ad1988_adc_nids[3] = {
- 0x08, 0x09, 0x0f
-};
-
-static const hda_nid_t ad1988_capsrc_nids[3] = {
- 0x0c, 0x0d, 0x0e
-};
-
-#define AD1988_SPDIF_OUT 0x02
-#define AD1988_SPDIF_OUT_HDMI 0x0b
-#define AD1988_SPDIF_IN 0x07
-
-static const hda_nid_t ad1989b_slave_dig_outs[] = {
- AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0
-};
-
-static const struct hda_input_mux ad1988_6stack_capture_source = {
- .num_items = 5,
- .items = {
- { "Front Mic", 0x1 }, /* port-B */
- { "Line", 0x2 }, /* port-C */
- { "Mic", 0x4 }, /* port-E */
- { "CD", 0x5 },
- { "Mix", 0x9 },
- },
-};
-
-static const struct hda_input_mux ad1988_laptop_capture_source = {
- .num_items = 3,
- .items = {
- { "Mic/Line", 0x1 }, /* port-B */
- { "CD", 0x5 },
- { "Mix", 0x9 },
- },
-};
-
-/*
- */
-static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ad198x_spec *spec = codec->spec;
- return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
- spec->num_channel_mode);
-}
-
-static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ad198x_spec *spec = codec->spec;
- return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
- spec->num_channel_mode, spec->multiout.max_channels);
-}
-
-static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ad198x_spec *spec = codec->spec;
- int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
- spec->num_channel_mode,
- &spec->multiout.max_channels);
- if (err >= 0 && spec->need_dac_fix)
- spec->multiout.num_dacs = spec->multiout.max_channels / 2;
- return err;
-}
-
-static const struct snd_kcontrol_new ad1988_hp_mixers[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Independent HP",
- .info = ad1988_independent_hp_info,
- .get = ad1988_independent_hp_get,
- .put = ad1988_independent_hp_put,
- },
- { } /* end */
-};
-
-/* 6-stack mode */
-static const struct snd_kcontrol_new ad1988_6stack_mixers1[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Side Playback Volume", 0x06, 0x0, HDA_OUTPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
- HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
- HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
- HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
- HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT),
- HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT),
- HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
- HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
-
- HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
-
- HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
-
- HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
- { } /* end */
-};
-
-/* 3-stack mode */
-static const struct snd_kcontrol_new ad1988_3stack_mixers1[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x06, 2, 0x0, HDA_OUTPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
- HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
- HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT),
- HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT),
- HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x26, 2, 2, HDA_INPUT),
- HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
- HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
-
- HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
-
- HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
-
- HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Channel Mode",
- .info = ad198x_ch_mode_info,
- .get = ad198x_ch_mode_get,
- .put = ad198x_ch_mode_put,
- },
-
- { } /* end */
-};
-
-/* laptop mode */
-static const struct snd_kcontrol_new ad1988_laptop_mixers[] = {
- HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT),
- HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
-
- HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
-
- HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
-
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
-
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "External Amplifier",
- .subdevice = HDA_SUBDEV_NID_FLAG | 0x12,
- .info = ad198x_eapd_info,
- .get = ad198x_eapd_get,
- .put = ad198x_eapd_put,
- .private_value = 0x12, /* port-D */
- },
-
- { } /* end */
-};
-
-/* capture */
-static const struct snd_kcontrol_new ad1988_capture_mixers[] = {
- HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x0e, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x0e, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- /* The multiple "Capture Source" controls confuse alsamixer
- * So call somewhat different..
- */
- /* .name = "Capture Source", */
- .name = "Input Source",
- .count = 3,
- .info = ad198x_mux_enum_info,
- .get = ad198x_mux_enum_get,
- .put = ad198x_mux_enum_put,
- },
- { } /* end */
-};
-
-static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static const char * const texts[] = {
- "PCM", "ADC1", "ADC2", "ADC3"
- };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 4;
- if (uinfo->value.enumerated.item >= 4)
- uinfo->value.enumerated.item = 3;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int sel;
-
- sel = snd_hda_codec_read(codec, 0x1d, 0, AC_VERB_GET_AMP_GAIN_MUTE,
- AC_AMP_GET_INPUT);
- if (!(sel & 0x80))
- ucontrol->value.enumerated.item[0] = 0;
- else {
- sel = snd_hda_codec_read(codec, 0x0b, 0,
- AC_VERB_GET_CONNECT_SEL, 0);
- if (sel < 3)
- sel++;
- else
- sel = 0;
- ucontrol->value.enumerated.item[0] = sel;
- }
- return 0;
-}
-
-static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int val, sel;
- int change;
-
- val = ucontrol->value.enumerated.item[0];
- if (val > 3)
- return -EINVAL;
- if (!val) {
- sel = snd_hda_codec_read(codec, 0x1d, 0,
- AC_VERB_GET_AMP_GAIN_MUTE,
- AC_AMP_GET_INPUT);
- change = sel & 0x80;
- if (change) {
- snd_hda_codec_write_cache(codec, 0x1d, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_IN_UNMUTE(0));
- snd_hda_codec_write_cache(codec, 0x1d, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_IN_MUTE(1));
- }
- } else {
- sel = snd_hda_codec_read(codec, 0x1d, 0,
- AC_VERB_GET_AMP_GAIN_MUTE,
- AC_AMP_GET_INPUT | 0x01);
- change = sel & 0x80;
- if (change) {
- snd_hda_codec_write_cache(codec, 0x1d, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_IN_MUTE(0));
- snd_hda_codec_write_cache(codec, 0x1d, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_IN_UNMUTE(1));
- }
- sel = snd_hda_codec_read(codec, 0x0b, 0,
- AC_VERB_GET_CONNECT_SEL, 0) + 1;
- change |= sel != val;
- if (change)
- snd_hda_codec_write_cache(codec, 0x0b, 0,
- AC_VERB_SET_CONNECT_SEL,
- val - 1);
- }
- return change;
-}
-
-static const struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
- HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "IEC958 Playback Source",
- .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
- .info = ad1988_spdif_playback_source_info,
- .get = ad1988_spdif_playback_source_get,
- .put = ad1988_spdif_playback_source_put,
- },
- { } /* end */
-};
-
-static const struct snd_kcontrol_new ad1988_spdif_in_mixers[] = {
- HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new ad1989_spdif_out_mixers[] = {
- HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
- { } /* end */
-};
-
-/*
- * initialization verbs
- */
-
-/*
- * for 6-stack (+dig)
- */
-static const struct hda_verb ad1988_6stack_init_verbs[] = {
- /* Front, Surround, CLFE, side DAC; unmute as default */
- {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* Port-A front headphon path */
- {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- /* Port-D line-out path */
- {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- /* Port-F surround path */
- {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- /* Port-G CLFE path */
- {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- /* Port-H side path */
- {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- /* Mono out path */
- {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
- {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
- /* Port-B front mic-in path */
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- /* Port-C line-in path */
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
- {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
- /* Port-E mic-in path */
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
- /* Analog CD Input */
- {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
- /* Analog Mix output amp */
- {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
-
- { }
-};
-
-static const struct hda_verb ad1988_6stack_fp_init_verbs[] = {
- /* Headphone; unmute as default */
- {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* Port-A front headphon path */
- {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-
- { }
-};
-
-static const struct hda_verb ad1988_capture_init_verbs[] = {
- /* mute analog mix */
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
- /* select ADCs - front-mic */
- {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
- {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
- {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
-
- { }
-};
-
-static const struct hda_verb ad1988_spdif_init_verbs[] = {
- /* SPDIF out sel */
- {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
- {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
- {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- /* SPDIF out pin */
- {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
-
- { }
-};
-
-static const struct hda_verb ad1988_spdif_in_init_verbs[] = {
- /* unmute SPDIF input pin */
- {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- { }
-};
-
-/* AD1989 has no ADC -> SPDIF route */
-static const struct hda_verb ad1989_spdif_init_verbs[] = {
- /* SPDIF-1 out pin */
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
- /* SPDIF-2/HDMI out pin */
- {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
- { }
-};
-
-/*
- * verbs for 3stack (+dig)
- */
-static const struct hda_verb ad1988_3stack_ch2_init[] = {
- /* set port-C to line-in */
- { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
- /* set port-E to mic-in */
- { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
- { } /* end */
-};
-
-static const struct hda_verb ad1988_3stack_ch6_init[] = {
- /* set port-C to surround out */
- { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- /* set port-E to CLFE out */
- { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { } /* end */
-};
-
-static const struct hda_channel_mode ad1988_3stack_modes[2] = {
- { 2, ad1988_3stack_ch2_init },
- { 6, ad1988_3stack_ch6_init },
-};
-
-static const struct hda_verb ad1988_3stack_init_verbs[] = {
- /* Front, Surround, CLFE, side DAC; unmute as default */
- {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* Port-A front headphon path */
- {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- /* Port-D line-out path */
- {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- /* Mono out path */
- {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
- {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
- /* Port-B front mic-in path */
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- /* Port-C line-in/surround path - 6ch mode as default */
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- {0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */
- {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
- /* Port-E mic-in/CLFE path - 6ch mode as default */
- {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- {0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x0a */
- {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
- /* mute analog mix */
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
- /* select ADCs - front-mic */
- {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
- {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
- {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
- /* Analog Mix output amp */
- {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
- { }
-};
-
-/*
- * verbs for laptop mode (+dig)
- */
-static const struct hda_verb ad1988_laptop_hp_on[] = {
- /* unmute port-A and mute port-D */
- { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { } /* end */
-};
-static const struct hda_verb ad1988_laptop_hp_off[] = {
- /* mute port-A and unmute port-D */
- { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
- { } /* end */
-};
-
-#define AD1988_HP_EVENT 0x01
-
-static const struct hda_verb ad1988_laptop_init_verbs[] = {
- /* Front, Surround, CLFE, side DAC; unmute as default */
- {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* Port-A front headphon path */
- {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- /* unsolicited event for pin-sense */
- {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT },
- /* Port-D line-out path + EAPD */
- {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */
- /* Mono out path */
- {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
- {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
- /* Port-B mic-in path */
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- /* Port-C docking station - try to output */
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
- /* mute analog mix */
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
- /* select ADCs - mic */
- {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
- {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
- {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
- /* Analog Mix output amp */
- {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
- { }
-};
-
-static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- if ((res >> 26) != AD1988_HP_EVENT)
- return;
- if (snd_hda_jack_detect(codec, 0x11))
- snd_hda_sequence_write(codec, ad1988_laptop_hp_on);
- else
- snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
-}
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static const struct hda_amp_list ad1988_loopbacks[] = {
- { 0x20, HDA_INPUT, 0 }, /* Front Mic */
- { 0x20, HDA_INPUT, 1 }, /* Line */
- { 0x20, HDA_INPUT, 4 }, /* Mic */
- { 0x20, HDA_INPUT, 6 }, /* CD */
- { } /* end */
-};
-#endif
-
-/*
- * Automatic parse of I/O pins from the BIOS configuration
- */
-
-enum {
- AD_CTL_WIDGET_VOL,
- AD_CTL_WIDGET_MUTE,
- AD_CTL_BIND_MUTE,
-};
-static const struct snd_kcontrol_new ad1988_control_templates[] = {
- HDA_CODEC_VOLUME(NULL, 0, 0, 0),
- HDA_CODEC_MUTE(NULL, 0, 0, 0),
- HDA_BIND_MUTE(NULL, 0, 0, 0),
-};
-
-/* add dynamic controls */
-static int add_control(struct ad198x_spec *spec, int type, const char *name,
- unsigned long val)
-{
- struct snd_kcontrol_new *knew;
-
- snd_array_init(&spec->kctls, sizeof(*knew), 32);
- knew = snd_array_new(&spec->kctls);
- if (!knew)
- return -ENOMEM;
- *knew = ad1988_control_templates[type];
- knew->name = kstrdup(name, GFP_KERNEL);
- if (! knew->name)
- return -ENOMEM;
- if (get_amp_nid_(val))
- knew->subdevice = HDA_SUBDEV_AMP_FLAG;
- knew->private_value = val;
- return 0;
-}
-
-#define AD1988_PIN_CD_NID 0x18
-#define AD1988_PIN_BEEP_NID 0x10
-
-static const hda_nid_t ad1988_mixer_nids[8] = {
- /* A B C D E F G H */
- 0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28
-};
-
-static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx)
-{
- static const hda_nid_t idx_to_dac[8] = {
- /* A B C D E F G H */
- 0x03, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a
- };
- static const hda_nid_t idx_to_dac_rev2[8] = {
- /* A B C D E F G H */
- 0x03, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06
- };
- if (is_rev2(codec))
- return idx_to_dac_rev2[idx];
- else
- return idx_to_dac[idx];
-}
-
-static const hda_nid_t ad1988_boost_nids[8] = {
- 0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0
-};
-
-static int ad1988_pin_idx(hda_nid_t nid)
-{
- static const hda_nid_t ad1988_io_pins[8] = {
- 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25
- };
- int i;
- for (i = 0; i < ARRAY_SIZE(ad1988_io_pins); i++)
- if (ad1988_io_pins[i] == nid)
- return i;
- return 0; /* should be -1 */
-}
-
-static int ad1988_pin_to_loopback_idx(hda_nid_t nid)
-{
- static const int loopback_idx[8] = {
- 2, 0, 1, 3, 4, 5, 1, 4
- };
- switch (nid) {
- case AD1988_PIN_CD_NID:
- return 6;
- default:
- return loopback_idx[ad1988_pin_idx(nid)];
- }
-}
-
-static int ad1988_pin_to_adc_idx(hda_nid_t nid)
-{
- static const int adc_idx[8] = {
- 0, 1, 2, 8, 4, 3, 6, 7
- };
- switch (nid) {
- case AD1988_PIN_CD_NID:
- return 5;
- default:
- return adc_idx[ad1988_pin_idx(nid)];
- }
-}
-
-/* fill in the dac_nids table from the parsed pin configuration */
-static int ad1988_auto_fill_dac_nids(struct hda_codec *codec,
- const struct auto_pin_cfg *cfg)
-{
- struct ad198x_spec *spec = codec->spec;
- int i, idx;
-
- spec->multiout.dac_nids = spec->private_dac_nids;
-
- /* check the pins hardwired to audio widget */
- for (i = 0; i < cfg->line_outs; i++) {
- idx = ad1988_pin_idx(cfg->line_out_pins[i]);
- spec->private_dac_nids[i] = ad1988_idx_to_dac(codec, idx);
- }
- spec->multiout.num_dacs = cfg->line_outs;
- return 0;
-}
-
-/* add playback controls from the parsed DAC table */
-static int ad1988_auto_create_multi_out_ctls(struct ad198x_spec *spec,
- const struct auto_pin_cfg *cfg)
-{
- char name[32];
- static const char * const chname[4] = {
- "Front", "Surround", NULL /*CLFE*/, "Side"
- };
- hda_nid_t nid;
- int i, err;
-
- for (i = 0; i < cfg->line_outs; i++) {
- hda_nid_t dac = spec->multiout.dac_nids[i];
- if (! dac)
- continue;
- nid = ad1988_mixer_nids[ad1988_pin_idx(cfg->line_out_pins[i])];
- if (i == 2) {
- /* Center/LFE */
- err = add_control(spec, AD_CTL_WIDGET_VOL,
- "Center Playback Volume",
- HDA_COMPOSE_AMP_VAL(dac, 1, 0, HDA_OUTPUT));
- if (err < 0)
- return err;
- err = add_control(spec, AD_CTL_WIDGET_VOL,
- "LFE Playback Volume",
- HDA_COMPOSE_AMP_VAL(dac, 2, 0, HDA_OUTPUT));
- if (err < 0)
- return err;
- err = add_control(spec, AD_CTL_BIND_MUTE,
- "Center Playback Switch",
- HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT));
- if (err < 0)
- return err;
- err = add_control(spec, AD_CTL_BIND_MUTE,
- "LFE Playback Switch",
- HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT));
- if (err < 0)
- return err;
- } else {
- sprintf(name, "%s Playback Volume", chname[i]);
- err = add_control(spec, AD_CTL_WIDGET_VOL, name,
- HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT));
- if (err < 0)
- return err;
- sprintf(name, "%s Playback Switch", chname[i]);
- err = add_control(spec, AD_CTL_BIND_MUTE, name,
- HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
- if (err < 0)
- return err;
- }
- }
- return 0;
-}
-
-/* add playback controls for speaker and HP outputs */
-static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
- const char *pfx)
-{
- struct ad198x_spec *spec = codec->spec;
- hda_nid_t nid;
- int i, idx, err;
- char name[32];
-
- if (! pin)
- return 0;
-
- idx = ad1988_pin_idx(pin);
- nid = ad1988_idx_to_dac(codec, idx);
- /* check whether the corresponding DAC was already taken */
- for (i = 0; i < spec->autocfg.line_outs; i++) {
- hda_nid_t pin = spec->autocfg.line_out_pins[i];
- hda_nid_t dac = ad1988_idx_to_dac(codec, ad1988_pin_idx(pin));
- if (dac == nid)
- break;
- }
- if (i >= spec->autocfg.line_outs) {
- /* specify the DAC as the extra output */
- if (!spec->multiout.hp_nid)
- spec->multiout.hp_nid = nid;
- else
- spec->multiout.extra_out_nid[0] = nid;
- /* control HP volume/switch on the output mixer amp */
- sprintf(name, "%s Playback Volume", pfx);
- err = add_control(spec, AD_CTL_WIDGET_VOL, name,
- HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
- if (err < 0)
- return err;
- }
- nid = ad1988_mixer_nids[idx];
- sprintf(name, "%s Playback Switch", pfx);
- if ((err = add_control(spec, AD_CTL_BIND_MUTE, name,
- HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
- return err;
- return 0;
-}
-
-/* create input playback/capture controls for the given pin */
-static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin,
- const char *ctlname, int ctlidx, int boost)
-{
- char name[32];
- int err, idx;
-
- sprintf(name, "%s Playback Volume", ctlname);
- idx = ad1988_pin_to_loopback_idx(pin);
- if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
- HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
- return err;
- sprintf(name, "%s Playback Switch", ctlname);
- if ((err = add_control(spec, AD_CTL_WIDGET_MUTE, name,
- HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
- return err;
- if (boost) {
- hda_nid_t bnid;
- idx = ad1988_pin_idx(pin);
- bnid = ad1988_boost_nids[idx];
- if (bnid) {
- sprintf(name, "%s Boost Volume", ctlname);
- return add_control(spec, AD_CTL_WIDGET_VOL, name,
- HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT));
-
- }
- }
- return 0;
-}
-
-/* create playback/capture controls for input pins */
-static int ad1988_auto_create_analog_input_ctls(struct hda_codec *codec,
- const struct auto_pin_cfg *cfg)
-{
- struct ad198x_spec *spec = codec->spec;
- struct hda_input_mux *imux = &spec->private_imux;
- int i, err, type, type_idx;
-
- for (i = 0; i < cfg->num_inputs; i++) {
- const char *label;
- type = cfg->inputs[i].type;
- label = hda_get_autocfg_input_label(codec, cfg, i);
- snd_hda_add_imux_item(imux, label,
- ad1988_pin_to_adc_idx(cfg->inputs[i].pin),
- &type_idx);
- err = new_analog_input(spec, cfg->inputs[i].pin,
- label, type_idx,
- type == AUTO_PIN_MIC);
- if (err < 0)
- return err;
- }
- snd_hda_add_imux_item(imux, "Mix", 9, NULL);
-
- if ((err = add_control(spec, AD_CTL_WIDGET_VOL,
- "Analog Mix Playback Volume",
- HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
- return err;
- if ((err = add_control(spec, AD_CTL_WIDGET_MUTE,
- "Analog Mix Playback Switch",
- HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
- return err;
-
- return 0;
-}
-
-static void ad1988_auto_set_output_and_unmute(struct hda_codec *codec,
- hda_nid_t nid, int pin_type,
- int dac_idx)
-{
- /* set as output */
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
- switch (nid) {
- case 0x11: /* port-A - DAC 03 */
- snd_hda_codec_write(codec, 0x37, 0, AC_VERB_SET_CONNECT_SEL, 0x00);
- break;
- case 0x14: /* port-B - DAC 06 */
- snd_hda_codec_write(codec, 0x30, 0, AC_VERB_SET_CONNECT_SEL, 0x02);
- break;
- case 0x15: /* port-C - DAC 05 */
- snd_hda_codec_write(codec, 0x31, 0, AC_VERB_SET_CONNECT_SEL, 0x00);
- break;
- case 0x17: /* port-E - DAC 0a */
- snd_hda_codec_write(codec, 0x32, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
- break;
- case 0x13: /* mono - DAC 04 */
- snd_hda_codec_write(codec, 0x36, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
- break;
- }
-}
-
-static void ad1988_auto_init_multi_out(struct hda_codec *codec)
-{
- struct ad198x_spec *spec = codec->spec;
- int i;
-
- for (i = 0; i < spec->autocfg.line_outs; i++) {
- hda_nid_t nid = spec->autocfg.line_out_pins[i];
- ad1988_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
- }
-}
-
-static void ad1988_auto_init_extra_out(struct hda_codec *codec)
-{
- struct ad198x_spec *spec = codec->spec;
- hda_nid_t pin;
-
- pin = spec->autocfg.speaker_pins[0];
- if (pin) /* connect to front */
- ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
- pin = spec->autocfg.hp_pins[0];
- if (pin) /* connect to front */
- ad1988_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
-}
-
-static void ad1988_auto_init_analog_input(struct hda_codec *codec)
-{
- struct ad198x_spec *spec = codec->spec;
- const struct auto_pin_cfg *cfg = &spec->autocfg;
- int i, idx;
-
- for (i = 0; i < cfg->num_inputs; i++) {
- hda_nid_t nid = cfg->inputs[i].pin;
- int type = cfg->inputs[i].type;
- switch (nid) {
- case 0x15: /* port-C */
- snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
- break;
- case 0x17: /* port-E */
- snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
- break;
- }
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
- type == AUTO_PIN_MIC ? PIN_VREF80 : PIN_IN);
- if (nid != AD1988_PIN_CD_NID)
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_OUT_MUTE);
- idx = ad1988_pin_idx(nid);
- if (ad1988_boost_nids[idx])
- snd_hda_codec_write(codec, ad1988_boost_nids[idx], 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_OUT_ZERO);
- }
-}
-
-/* parse the BIOS configuration and set up the alc_spec */
-/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
-static int ad1988_parse_auto_config(struct hda_codec *codec)
-{
- struct ad198x_spec *spec = codec->spec;
- int err;
-
- if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
- return err;
- if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
- return err;
- if (! spec->autocfg.line_outs)
- return 0; /* can't find valid BIOS pin config */
- if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
- (err = ad1988_auto_create_extra_out(codec,
- spec->autocfg.speaker_pins[0],
- "Speaker")) < 0 ||
- (err = ad1988_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
- "Headphone")) < 0 ||
- (err = ad1988_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
- return err;
-
- spec->multiout.max_channels = spec->multiout.num_dacs * 2;
-
- if (spec->autocfg.dig_outs)
- spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
- if (spec->autocfg.dig_in_pin)
- spec->dig_in_nid = AD1988_SPDIF_IN;
-
- if (spec->kctls.list)
- spec->mixers[spec->num_mixers++] = spec->kctls.list;
-
- spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs;
-
- spec->input_mux = &spec->private_imux;
-
- return 1;
-}
-
-/* init callback for auto-configuration model -- overriding the default init */
-static int ad1988_auto_init(struct hda_codec *codec)
-{
- ad198x_init(codec);
- ad1988_auto_init_multi_out(codec);
- ad1988_auto_init_extra_out(codec);
- ad1988_auto_init_analog_input(codec);
- return 0;
-}
-
-/*
- */
-
-static const char * const ad1988_models[AD1988_MODEL_LAST] = {
- [AD1988_6STACK] = "6stack",
- [AD1988_6STACK_DIG] = "6stack-dig",
- [AD1988_3STACK] = "3stack",
- [AD1988_3STACK_DIG] = "3stack-dig",
- [AD1988_LAPTOP] = "laptop",
- [AD1988_LAPTOP_DIG] = "laptop-dig",
- [AD1988_AUTO] = "auto",
-};
-
-static const struct snd_pci_quirk ad1988_cfg_tbl[] = {
- SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
- SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
- SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG),
- SND_PCI_QUIRK(0x1043, 0x82c0, "Asus M3N-HT Deluxe", AD1988_6STACK_DIG),
- SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG),
- {}
-};
-
-static int patch_ad1988(struct hda_codec *codec)
-{
- struct ad198x_spec *spec;
- int err, board_config;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->spec = spec;
-
- if (is_rev2(codec))
- snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
-
- board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST,
- ad1988_models, ad1988_cfg_tbl);
- if (board_config < 0) {
- printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
- codec->chip_name);
- board_config = AD1988_AUTO;
- }
-
- if (board_config == AD1988_AUTO) {
- /* automatic parse from the BIOS config */
- err = ad1988_parse_auto_config(codec);
- if (err < 0) {
- ad198x_free(codec);
- return err;
- } else if (! err) {
- printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using 6-stack mode...\n");
- board_config = AD1988_6STACK;
- }
- }
-
- err = snd_hda_attach_beep_device(codec, 0x10);
- if (err < 0) {
- ad198x_free(codec);
- return err;
- }
- set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
-
- if (!spec->multiout.hp_nid)
- spec->multiout.hp_nid = ad1988_alt_dac_nid[0];
- switch (board_config) {
- case AD1988_6STACK:
- case AD1988_6STACK_DIG:
- spec->multiout.max_channels = 8;
- spec->multiout.num_dacs = 4;
- if (is_rev2(codec))
- spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2;
- else
- spec->multiout.dac_nids = ad1988_6stack_dac_nids;
- spec->input_mux = &ad1988_6stack_capture_source;
- spec->num_mixers = 2;
- if (is_rev2(codec))
- spec->mixers[0] = ad1988_6stack_mixers1_rev2;
- else
- spec->mixers[0] = ad1988_6stack_mixers1;
- spec->mixers[1] = ad1988_6stack_mixers2;
- spec->num_init_verbs = 1;
- spec->init_verbs[0] = ad1988_6stack_init_verbs;
- if (board_config == AD1988_6STACK_DIG) {
- spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
- spec->dig_in_nid = AD1988_SPDIF_IN;
- }
- break;
- case AD1988_3STACK:
- case AD1988_3STACK_DIG:
- spec->multiout.max_channels = 6;
- spec->multiout.num_dacs = 3;
- if (is_rev2(codec))
- spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2;
- else
- spec->multiout.dac_nids = ad1988_3stack_dac_nids;
- spec->input_mux = &ad1988_6stack_capture_source;
- spec->channel_mode = ad1988_3stack_modes;
- spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes);
- spec->num_mixers = 2;
- if (is_rev2(codec))
- spec->mixers[0] = ad1988_3stack_mixers1_rev2;
- else
- spec->mixers[0] = ad1988_3stack_mixers1;
- spec->mixers[1] = ad1988_3stack_mixers2;
- spec->num_init_verbs = 1;
- spec->init_verbs[0] = ad1988_3stack_init_verbs;
- if (board_config == AD1988_3STACK_DIG)
- spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
- break;
- case AD1988_LAPTOP:
- case AD1988_LAPTOP_DIG:
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = 1;
- spec->multiout.dac_nids = ad1988_3stack_dac_nids;
- spec->input_mux = &ad1988_laptop_capture_source;
- spec->num_mixers = 1;
- spec->mixers[0] = ad1988_laptop_mixers;
- spec->inv_eapd = 1; /* inverted EAPD */
- spec->num_init_verbs = 1;
- spec->init_verbs[0] = ad1988_laptop_init_verbs;
- if (board_config == AD1988_LAPTOP_DIG)
- spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
- break;
- }
-
- if (spec->autocfg.hp_pins[0]) {
- spec->mixers[spec->num_mixers++] = ad1988_hp_mixers;
- spec->slave_vols = ad1988_6stack_fp_slave_pfxs;
- spec->slave_sws = ad1988_6stack_fp_slave_pfxs;
- spec->alt_dac_nid = ad1988_alt_dac_nid;
- spec->stream_analog_alt_playback =
- &ad198x_pcm_analog_alt_playback;
- }
-
- spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
- spec->adc_nids = ad1988_adc_nids;
- spec->capsrc_nids = ad1988_capsrc_nids;
- spec->mixers[spec->num_mixers++] = ad1988_capture_mixers;
- spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs;
- if (spec->multiout.dig_out_nid) {
- if (codec->vendor_id >= 0x11d4989a) {
- spec->mixers[spec->num_mixers++] =
- ad1989_spdif_out_mixers;
- spec->init_verbs[spec->num_init_verbs++] =
- ad1989_spdif_init_verbs;
- codec->slave_dig_outs = ad1989b_slave_dig_outs;
- } else {
- spec->mixers[spec->num_mixers++] =
- ad1988_spdif_out_mixers;
- spec->init_verbs[spec->num_init_verbs++] =
- ad1988_spdif_init_verbs;
- }
- }
- if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) {
- spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
- spec->init_verbs[spec->num_init_verbs++] =
- ad1988_spdif_in_init_verbs;
- }
-
- codec->patch_ops = ad198x_patch_ops;
- switch (board_config) {
- case AD1988_AUTO:
- codec->patch_ops.init = ad1988_auto_init;
- break;
- case AD1988_LAPTOP:
- case AD1988_LAPTOP_DIG:
- codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
- break;
- }
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- spec->loopback.amplist = ad1988_loopbacks;
-#endif
- spec->vmaster_nid = 0x04;
-
- codec->no_trigger_sense = 1;
- codec->no_sticky_stream = 1;
-
- return 0;
-}
-
-
-/*
- * AD1884 / AD1984
- *
- * port-B - front line/mic-in
- * port-E - aux in/out
- * port-F - aux in/out
- * port-C - rear line/mic-in
- * port-D - rear line/hp-out
- * port-A - front line/hp-out
- *
- * AD1984 = AD1884 + two digital mic-ins
- *
- * FIXME:
- * For simplicity, we share the single DAC for both HP and line-outs
- * right now. The inidividual playbacks could be easily implemented,
- * but no build-up framework is given, so far.
- */
-
-static const hda_nid_t ad1884_dac_nids[1] = {
- 0x04,
-};
-
-static const hda_nid_t ad1884_adc_nids[2] = {
- 0x08, 0x09,
-};
-
-static const hda_nid_t ad1884_capsrc_nids[2] = {
- 0x0c, 0x0d,
-};
-
-#define AD1884_SPDIF_OUT 0x02
-
-static const struct hda_input_mux ad1884_capture_source = {
- .num_items = 4,
- .items = {
- { "Front Mic", 0x0 },
- { "Mic", 0x1 },
- { "CD", 0x2 },
- { "Mix", 0x3 },
- },
-};
-
-static const struct snd_kcontrol_new ad1884_base_mixers[] = {
- HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
- /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- /* The multiple "Capture Source" controls confuse alsamixer
- * So call somewhat different..
- */
- /* .name = "Capture Source", */
- .name = "Input Source",
- .count = 2,
- .info = ad198x_mux_enum_info,
- .get = ad198x_mux_enum_get,
- .put = ad198x_mux_enum_put,
- },
- /* SPDIF controls */
- HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
- /* identical with ad1983 */
- .info = ad1983_spdif_route_info,
- .get = ad1983_spdif_route_get,
- .put = ad1983_spdif_route_put,
- },
- { } /* end */
-};
-
-static const struct snd_kcontrol_new ad1984_dmic_mixers[] = {
- HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0,
- HDA_INPUT),
- HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0,
- HDA_INPUT),
- { } /* end */
-};
-
-/*
- * initialization verbs
- */
-static const struct hda_verb ad1884_init_verbs[] = {
- /* DACs; mute as default */
- {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- /* Port-A (HP) mixer */
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- /* Port-A pin */
- {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* HP selector - select DAC2 */
- {0x22, AC_VERB_SET_CONNECT_SEL, 0x1},
- /* Port-D (Line-out) mixer */
- {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- /* Port-D pin */
- {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* Mono-out mixer */
- {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- /* Mono-out pin */
- {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* Mono selector */
- {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
- /* Port-B (front mic) pin */
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- /* Port-C (rear mic) pin */
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- /* Analog mixer; mute as default */
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- /* Analog Mix output amp */
- {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
- /* SPDIF output selector */
- {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
- {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
- { } /* end */
-};
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static const struct hda_amp_list ad1884_loopbacks[] = {
- { 0x20, HDA_INPUT, 0 }, /* Front Mic */
- { 0x20, HDA_INPUT, 1 }, /* Mic */
- { 0x20, HDA_INPUT, 2 }, /* CD */
- { 0x20, HDA_INPUT, 4 }, /* Docking */
- { } /* end */
-};
-#endif
-
-static const char * const ad1884_slave_vols[] = {
- "PCM", "Mic", "Mono", "Front Mic", "Mic", "CD",
- "Internal Mic", "Docking Mic", /* "Beep", */ "IEC958",
- NULL
-};
-
-static int patch_ad1884(struct hda_codec *codec)
-{
- struct ad198x_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->spec = spec;
-
- err = snd_hda_attach_beep_device(codec, 0x10);
- if (err < 0) {
- ad198x_free(codec);
- return err;
- }
- set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
-
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids);
- spec->multiout.dac_nids = ad1884_dac_nids;
- spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
- spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids);
- spec->adc_nids = ad1884_adc_nids;
- spec->capsrc_nids = ad1884_capsrc_nids;
- spec->input_mux = &ad1884_capture_source;
- spec->num_mixers = 1;
- spec->mixers[0] = ad1884_base_mixers;
- spec->num_init_verbs = 1;
- spec->init_verbs[0] = ad1884_init_verbs;
- spec->spdif_route = 0;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- spec->loopback.amplist = ad1884_loopbacks;
-#endif
- spec->vmaster_nid = 0x04;
- /* we need to cover all playback volumes */
- spec->slave_vols = ad1884_slave_vols;
- /* slaves may contain input volumes, so we can't raise to 0dB blindly */
- spec->avoid_init_slave_vol = 1;
-
- codec->patch_ops = ad198x_patch_ops;
-
- codec->no_trigger_sense = 1;
- codec->no_sticky_stream = 1;
-
- return 0;
-}
-
-/*
- * Lenovo Thinkpad T61/X61
- */
-static const struct hda_input_mux ad1984_thinkpad_capture_source = {
- .num_items = 4,
- .items = {
- { "Mic", 0x0 },
- { "Internal Mic", 0x1 },
- { "Mix", 0x3 },
- { "Docking-Station", 0x4 },
- },
-};
-
-
-/*
- * Dell Precision T3400
- */
-static const struct hda_input_mux ad1984_dell_desktop_capture_source = {
- .num_items = 3,
- .items = {
- { "Front Mic", 0x0 },
- { "Line-In", 0x1 },
- { "Mix", 0x3 },
- },
-};
-
-
-static const struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
- HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
- /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
- HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
- HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- /* The multiple "Capture Source" controls confuse alsamixer
- * So call somewhat different..
- */
- /* .name = "Capture Source", */
- .name = "Input Source",
- .count = 2,
- .info = ad198x_mux_enum_info,
- .get = ad198x_mux_enum_get,
- .put = ad198x_mux_enum_put,
- },
- /* SPDIF controls */
- HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
- /* identical with ad1983 */
- .info = ad1983_spdif_route_info,
- .get = ad1983_spdif_route_get,
- .put = ad1983_spdif_route_put,
- },
- { } /* end */
-};
-
-/* additional verbs */
-static const struct hda_verb ad1984_thinkpad_init_verbs[] = {
- /* Port-E (docking station mic) pin */
- {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* docking mic boost */
- {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- /* Analog PC Beeper - allow firmware/ACPI beeps */
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3) | 0x1a},
- /* Analog mixer - docking mic; mute as default */
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- /* enable EAPD bit */
- {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
- { } /* end */
-};
-
-/*
- * Dell Precision T3400
- */
-static const struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = {
- HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
- HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("Line-In Boost Volume", 0x15, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- /* The multiple "Capture Source" controls confuse alsamixer
- * So call somewhat different..
- */
- /* .name = "Capture Source", */
- .name = "Input Source",
- .count = 2,
- .info = ad198x_mux_enum_info,
- .get = ad198x_mux_enum_get,
- .put = ad198x_mux_enum_put,
- },
- { } /* end */
-};
-
-/* Digial MIC ADC NID 0x05 + 0x06 */
-static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
- stream_tag, 0, format);
- return 0;
-}
-
-static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- snd_hda_codec_cleanup_stream(codec, 0x05 + substream->number);
- return 0;
-}
-
-static const struct hda_pcm_stream ad1984_pcm_dmic_capture = {
- .substreams = 2,
- .channels_min = 2,
- .channels_max = 2,
- .nid = 0x05,
- .ops = {
- .prepare = ad1984_pcm_dmic_prepare,
- .cleanup = ad1984_pcm_dmic_cleanup
- },
-};
-
-static int ad1984_build_pcms(struct hda_codec *codec)
-{
- struct ad198x_spec *spec = codec->spec;
- struct hda_pcm *info;
- int err;
-
- err = ad198x_build_pcms(codec);
- if (err < 0)
- return err;
-
- info = spec->pcm_rec + codec->num_pcms;
- codec->num_pcms++;
- info->name = "AD1984 Digital Mic";
- info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture;
- return 0;
-}
-
-/* models */
-enum {
- AD1984_BASIC,
- AD1984_THINKPAD,
- AD1984_DELL_DESKTOP,
- AD1984_MODELS
-};
-
-static const char * const ad1984_models[AD1984_MODELS] = {
- [AD1984_BASIC] = "basic",
- [AD1984_THINKPAD] = "thinkpad",
- [AD1984_DELL_DESKTOP] = "dell_desktop",
-};
-
-static const struct snd_pci_quirk ad1984_cfg_tbl[] = {
- /* Lenovo Thinkpad T61/X61 */
- SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD),
- SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP),
- SND_PCI_QUIRK(0x1028, 0x0233, "Dell Latitude E6400", AD1984_DELL_DESKTOP),
- {}
-};
-
-static int patch_ad1984(struct hda_codec *codec)
-{
- struct ad198x_spec *spec;
- int board_config, err;
-
- err = patch_ad1884(codec);
- if (err < 0)
- return err;
- spec = codec->spec;
- board_config = snd_hda_check_board_config(codec, AD1984_MODELS,
- ad1984_models, ad1984_cfg_tbl);
- switch (board_config) {
- case AD1984_BASIC:
- /* additional digital mics */
- spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers;
- codec->patch_ops.build_pcms = ad1984_build_pcms;
- break;
- case AD1984_THINKPAD:
- if (codec->subsystem_id == 0x17aa20fb) {
- /* Thinpad X300 does not have the ability to do SPDIF,
- or attach to docking station to use SPDIF */
- spec->multiout.dig_out_nid = 0;
- } else
- spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
- spec->input_mux = &ad1984_thinkpad_capture_source;
- spec->mixers[0] = ad1984_thinkpad_mixers;
- spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
- spec->analog_beep = 1;
- break;
- case AD1984_DELL_DESKTOP:
- spec->multiout.dig_out_nid = 0;
- spec->input_mux = &ad1984_dell_desktop_capture_source;
- spec->mixers[0] = ad1984_dell_desktop_mixers;
- break;
- }
- return 0;
-}
-
-
-/*
- * AD1883 / AD1884A / AD1984A / AD1984B
- *
- * port-B (0x14) - front mic-in
- * port-E (0x1c) - rear mic-in
- * port-F (0x16) - CD / ext out
- * port-C (0x15) - rear line-in
- * port-D (0x12) - rear line-out
- * port-A (0x11) - front hp-out
- *
- * AD1984A = AD1884A + digital-mic
- * AD1883 = equivalent with AD1984A
- * AD1984B = AD1984A + extra SPDIF-out
- *
- * FIXME:
- * We share the single DAC for both HP and line-outs (see AD1884/1984).
- */
-
-static const hda_nid_t ad1884a_dac_nids[1] = {
- 0x03,
-};
-
-#define ad1884a_adc_nids ad1884_adc_nids
-#define ad1884a_capsrc_nids ad1884_capsrc_nids
-
-#define AD1884A_SPDIF_OUT 0x02
-
-static const struct hda_input_mux ad1884a_capture_source = {
- .num_items = 5,
- .items = {
- { "Front Mic", 0x0 },
- { "Mic", 0x4 },
- { "Line", 0x1 },
- { "CD", 0x2 },
- { "Mix", 0x3 },
- },
-};
-
-static const struct snd_kcontrol_new ad1884a_base_mixers[] = {
- HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
- HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- /* The multiple "Capture Source" controls confuse alsamixer
- * So call somewhat different..
- */
- /* .name = "Capture Source", */
- .name = "Input Source",
- .count = 2,
- .info = ad198x_mux_enum_info,
- .get = ad198x_mux_enum_get,
- .put = ad198x_mux_enum_put,
- },
- /* SPDIF controls */
- HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
- /* identical with ad1983 */
- .info = ad1983_spdif_route_info,
- .get = ad1983_spdif_route_get,
- .put = ad1983_spdif_route_put,
- },
- { } /* end */
-};
-
-/*
- * initialization verbs
- */
-static const struct hda_verb ad1884a_init_verbs[] = {
- /* DACs; unmute as default */
- {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
- {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
- /* Port-A (HP) mixer - route only from analog mixer */
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- /* Port-A pin */
- {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* Port-D (Line-out) mixer - route only from analog mixer */
- {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- /* Port-D pin */
- {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* Mono-out mixer - route only from analog mixer */
- {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- /* Mono-out pin */
- {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* Port-B (front mic) pin */
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- /* Port-C (rear line-in) pin */
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- /* Port-E (rear mic) pin */
- {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* no boost */
- /* Port-F (CD) pin */
- {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
- {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* Analog mixer; mute as default */
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* aux */
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
- /* Analog Mix output amp */
- {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* capture sources */
- {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
- {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* SPDIF output amp */
- {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
- { } /* end */
-};
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static const struct hda_amp_list ad1884a_loopbacks[] = {
- { 0x20, HDA_INPUT, 0 }, /* Front Mic */
- { 0x20, HDA_INPUT, 1 }, /* Mic */
- { 0x20, HDA_INPUT, 2 }, /* CD */
- { 0x20, HDA_INPUT, 4 }, /* Docking */
- { } /* end */
-};
-#endif
-
-/*
- * Laptop model
- *
- * Port A: Headphone jack
- * Port B: MIC jack
- * Port C: Internal MIC
- * Port D: Dock Line Out (if enabled)
- * Port E: Dock Line In (if enabled)
- * Port F: Internal speakers
- */
-
-static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- int ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
- int mute = (!ucontrol->value.integer.value[0] &&
- !ucontrol->value.integer.value[1]);
- /* toggle GPIO1 according to the mute state */
- snd_hda_codec_write_cache(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
- mute ? 0x02 : 0x0);
- return ret;
-}
-
-static const struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
- HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .subdevice = HDA_SUBDEV_AMP_FLAG,
- .info = snd_hda_mixer_amp_switch_info,
- .get = snd_hda_mixer_amp_switch_get,
- .put = ad1884a_mobile_master_sw_put,
- .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
- },
- HDA_CODEC_MUTE("Dock Playback Switch", 0x12, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
- HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
- HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
- /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .subdevice = HDA_SUBDEV_AMP_FLAG,
- .info = snd_hda_mixer_amp_switch_info,
- .get = snd_hda_mixer_amp_switch_get,
- .put = ad1884a_mobile_master_sw_put,
- .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
- },
- HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
- HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
- { } /* end */
-};
-
-/* mute internal speaker if HP is plugged */
-static void ad1884a_hp_automute(struct hda_codec *codec)
-{
- unsigned int present;
-
- present = snd_hda_jack_detect(codec, 0x11);
- snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
- snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
- present ? 0x00 : 0x02);
-}
-
-/* switch to external mic if plugged */
-static void ad1884a_hp_automic(struct hda_codec *codec)
-{
- unsigned int present;
-
- present = snd_hda_jack_detect(codec, 0x14);
- snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL,
- present ? 0 : 1);
-}
-
-#define AD1884A_HP_EVENT 0x37
-#define AD1884A_MIC_EVENT 0x36
-
-/* unsolicited event for HP jack sensing */
-static void ad1884a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- switch (res >> 26) {
- case AD1884A_HP_EVENT:
- ad1884a_hp_automute(codec);
- break;
- case AD1884A_MIC_EVENT:
- ad1884a_hp_automic(codec);
- break;
- }
-}
-
-/* initialize jack-sensing, too */
-static int ad1884a_hp_init(struct hda_codec *codec)
-{
- ad198x_init(codec);
- ad1884a_hp_automute(codec);
- ad1884a_hp_automic(codec);
- return 0;
-}
-
-/* mute internal speaker if HP or docking HP is plugged */
-static void ad1884a_laptop_automute(struct hda_codec *codec)
-{
- unsigned int present;
-
- present = snd_hda_jack_detect(codec, 0x11);
- if (!present)
- present = snd_hda_jack_detect(codec, 0x12);
- snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
- snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
- present ? 0x00 : 0x02);
-}
-
-/* switch to external mic if plugged */
-static void ad1884a_laptop_automic(struct hda_codec *codec)
-{
- unsigned int idx;
-
- if (snd_hda_jack_detect(codec, 0x14))
- idx = 0;
- else if (snd_hda_jack_detect(codec, 0x1c))
- idx = 4;
- else
- idx = 1;
- snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, idx);
-}
-
-/* unsolicited event for HP jack sensing */
-static void ad1884a_laptop_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- switch (res >> 26) {
- case AD1884A_HP_EVENT:
- ad1884a_laptop_automute(codec);
- break;
- case AD1884A_MIC_EVENT:
- ad1884a_laptop_automic(codec);
- break;
- }
-}
-
-/* initialize jack-sensing, too */
-static int ad1884a_laptop_init(struct hda_codec *codec)
-{
- ad198x_init(codec);
- ad1884a_laptop_automute(codec);
- ad1884a_laptop_automic(codec);
- return 0;
-}
-
-/* additional verbs for laptop model */
-static const struct hda_verb ad1884a_laptop_verbs[] = {
- /* Port-A (HP) pin - always unmuted */
- {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* Port-F (int speaker) mixer - route only from analog mixer */
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- /* Port-F (int speaker) pin */
- {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* required for compaq 6530s/6531s speaker output */
- {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- /* Port-C pin - internal mic-in */
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
- /* Port-D (docking line-out) pin - default unmuted */
- {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* analog mix */
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- /* unsolicited event for pin-sense */
- {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
- {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
- {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
- {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
- /* allow to touch GPIO1 (for mute control) */
- {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
- {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
- {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
- { } /* end */
-};
-
-static const struct hda_verb ad1884a_mobile_verbs[] = {
- /* DACs; unmute as default */
- {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
- {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
- /* Port-A (HP) mixer - route only from analog mixer */
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- /* Port-A pin */
- {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- /* Port-A (HP) pin - always unmuted */
- {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* Port-B (mic jack) pin */
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
- /* Port-C (int mic) pin */
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
- /* Port-F (int speaker) mixer - route only from analog mixer */
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- /* Port-F pin */
- {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* Analog mixer; mute as default */
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
- /* Analog Mix output amp */
- {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* capture sources */
- /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
- {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* unsolicited event for pin-sense */
- {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
- {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
- /* allow to touch GPIO1 (for mute control) */
- {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
- {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
- {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
- { } /* end */
-};
-
-/*
- * Thinkpad X300
- * 0x11 - HP
- * 0x12 - speaker
- * 0x14 - mic-in
- * 0x17 - built-in mic
- */
-
-static const struct hda_verb ad1984a_thinkpad_verbs[] = {
- /* HP unmute */
- {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* analog mix */
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- /* turn on EAPD */
- {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
- /* unsolicited event for pin-sense */
- {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
- /* internal mic - dmic */
- {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
- /* set magic COEFs for dmic */
- {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
- {0x01, AC_VERB_SET_PROC_COEF, 0x08},
- { } /* end */
-};
-
-static const struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
- HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
- HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = ad198x_mux_enum_info,
- .get = ad198x_mux_enum_get,
- .put = ad198x_mux_enum_put,
- },
- { } /* end */
-};
-
-static const struct hda_input_mux ad1984a_thinkpad_capture_source = {
- .num_items = 3,
- .items = {
- { "Mic", 0x0 },
- { "Internal Mic", 0x5 },
- { "Mix", 0x3 },
- },
-};
-
-/* mute internal speaker if HP is plugged */
-static void ad1984a_thinkpad_automute(struct hda_codec *codec)
-{
- unsigned int present;
-
- present = snd_hda_jack_detect(codec, 0x11);
- snd_hda_codec_amp_stereo(codec, 0x12, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
-}
-
-/* unsolicited event for HP jack sensing */
-static void ad1984a_thinkpad_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- if ((res >> 26) != AD1884A_HP_EVENT)
- return;
- ad1984a_thinkpad_automute(codec);
-}
-
-/* initialize jack-sensing, too */
-static int ad1984a_thinkpad_init(struct hda_codec *codec)
-{
- ad198x_init(codec);
- ad1984a_thinkpad_automute(codec);
- return 0;
-}
-
-/*
- * Precision R5500
- * 0x12 - HP/line-out
- * 0x13 - speaker (mono)
- * 0x15 - mic-in
- */
-
-static const struct hda_verb ad1984a_precision_verbs[] = {
- /* Unmute main output path */
- {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
- {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x1f}, /* 0dB */
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) + 0x17}, /* 0dB */
- /* Analog mixer; mute as default */
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- /* Select mic as input */
- {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x27}, /* 0dB */
- /* Configure as mic */
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
- /* HP unmute */
- {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* turn on EAPD */
- {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
- /* unsolicited event for pin-sense */
- {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
- { } /* end */
-};
-
-static const struct snd_kcontrol_new ad1984a_precision_mixers[] = {
- HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
- HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Speaker Playback Volume", 0x13, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
- { } /* end */
-};
-
-
-/* mute internal speaker if HP is plugged */
-static void ad1984a_precision_automute(struct hda_codec *codec)
-{
- unsigned int present;
-
- present = snd_hda_jack_detect(codec, 0x12);
- snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
-}
-
-
-/* unsolicited event for HP jack sensing */
-static void ad1984a_precision_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- if ((res >> 26) != AD1884A_HP_EVENT)
- return;
- ad1984a_precision_automute(codec);
-}
-
-/* initialize jack-sensing, too */
-static int ad1984a_precision_init(struct hda_codec *codec)
-{
- ad198x_init(codec);
- ad1984a_precision_automute(codec);
- return 0;
-}
-
-
-/*
- * HP Touchsmart
- * port-A (0x11) - front hp-out
- * port-B (0x14) - unused
- * port-C (0x15) - unused
- * port-D (0x12) - rear line out
- * port-E (0x1c) - front mic-in
- * port-F (0x16) - Internal speakers
- * digital-mic (0x17) - Internal mic
- */
-
-static const struct hda_verb ad1984a_touchsmart_verbs[] = {
- /* DACs; unmute as default */
- {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
- {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
- /* Port-A (HP) mixer - route only from analog mixer */
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- /* Port-A pin */
- {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- /* Port-A (HP) pin - always unmuted */
- {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* Port-E (int speaker) mixer - route only from analog mixer */
- {0x25, AC_VERB_SET_AMP_GAIN_MUTE, 0x03},
- /* Port-E pin */
- {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
- {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- /* Port-F (int speaker) mixer - route only from analog mixer */
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- /* Port-F pin */
- {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* Analog mixer; mute as default */
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
- /* Analog Mix output amp */
- {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* capture sources */
- /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
- {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
- {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* unsolicited event for pin-sense */
- {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
- {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
- /* allow to touch GPIO1 (for mute control) */
- {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
- {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
- {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
- /* internal mic - dmic */
- {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
- /* set magic COEFs for dmic */
- {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
- {0x01, AC_VERB_SET_PROC_COEF, 0x08},
- { } /* end */
-};
-
-static const struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
- HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
-/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .subdevice = HDA_SUBDEV_AMP_FLAG,
- .name = "Master Playback Switch",
- .info = snd_hda_mixer_amp_switch_info,
- .get = snd_hda_mixer_amp_switch_get,
- .put = ad1884a_mobile_master_sw_put,
- .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
- },
- HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
- HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT),
- { } /* end */
-};
-
-/* switch to external mic if plugged */
-static void ad1984a_touchsmart_automic(struct hda_codec *codec)
-{
- if (snd_hda_jack_detect(codec, 0x1c))
- snd_hda_codec_write(codec, 0x0c, 0,
- AC_VERB_SET_CONNECT_SEL, 0x4);
- else
- snd_hda_codec_write(codec, 0x0c, 0,
- AC_VERB_SET_CONNECT_SEL, 0x5);
-}
-
-
-/* unsolicited event for HP jack sensing */
-static void ad1984a_touchsmart_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- switch (res >> 26) {
- case AD1884A_HP_EVENT:
- ad1884a_hp_automute(codec);
- break;
- case AD1884A_MIC_EVENT:
- ad1984a_touchsmart_automic(codec);
- break;
- }
-}
-
-/* initialize jack-sensing, too */
-static int ad1984a_touchsmart_init(struct hda_codec *codec)
-{
- ad198x_init(codec);
- ad1884a_hp_automute(codec);
- ad1984a_touchsmart_automic(codec);
- return 0;
-}
-
-
-/*
- */
-
-enum {
- AD1884A_DESKTOP,
- AD1884A_LAPTOP,
- AD1884A_MOBILE,
- AD1884A_THINKPAD,
- AD1984A_TOUCHSMART,
- AD1984A_PRECISION,
- AD1884A_MODELS
-};
-
-static const char * const ad1884a_models[AD1884A_MODELS] = {
- [AD1884A_DESKTOP] = "desktop",
- [AD1884A_LAPTOP] = "laptop",
- [AD1884A_MOBILE] = "mobile",
- [AD1884A_THINKPAD] = "thinkpad",
- [AD1984A_TOUCHSMART] = "touchsmart",
- [AD1984A_PRECISION] = "precision",
-};
-
-static const struct snd_pci_quirk ad1884a_cfg_tbl[] = {
- SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION),
- SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
- SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP),
- SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE),
- SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x3070, "HP", AD1884A_MOBILE),
- SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30d0, "HP laptop", AD1884A_LAPTOP),
- SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30e0, "HP laptop", AD1884A_LAPTOP),
- SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP),
- SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE),
- SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
- SND_PCI_QUIRK(0x103c, 0x2a82, "Touchsmart", AD1984A_TOUCHSMART),
- {}
-};
-
-static int patch_ad1884a(struct hda_codec *codec)
-{
- struct ad198x_spec *spec;
- int err, board_config;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->spec = spec;
-
- err = snd_hda_attach_beep_device(codec, 0x10);
- if (err < 0) {
- ad198x_free(codec);
- return err;
- }
- set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
-
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = ARRAY_SIZE(ad1884a_dac_nids);
- spec->multiout.dac_nids = ad1884a_dac_nids;
- spec->multiout.dig_out_nid = AD1884A_SPDIF_OUT;
- spec->num_adc_nids = ARRAY_SIZE(ad1884a_adc_nids);
- spec->adc_nids = ad1884a_adc_nids;
- spec->capsrc_nids = ad1884a_capsrc_nids;
- spec->input_mux = &ad1884a_capture_source;
- spec->num_mixers = 1;
- spec->mixers[0] = ad1884a_base_mixers;
- spec->num_init_verbs = 1;
- spec->init_verbs[0] = ad1884a_init_verbs;
- spec->spdif_route = 0;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- spec->loopback.amplist = ad1884a_loopbacks;
-#endif
- codec->patch_ops = ad198x_patch_ops;
-
- /* override some parameters */
- board_config = snd_hda_check_board_config(codec, AD1884A_MODELS,
- ad1884a_models,
- ad1884a_cfg_tbl);
- switch (board_config) {
- case AD1884A_LAPTOP:
- spec->mixers[0] = ad1884a_laptop_mixers;
- spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs;
- spec->multiout.dig_out_nid = 0;
- codec->patch_ops.unsol_event = ad1884a_laptop_unsol_event;
- codec->patch_ops.init = ad1884a_laptop_init;
- /* set the upper-limit for mixer amp to 0dB for avoiding the
- * possible damage by overloading
- */
- snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
- (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
- (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
- (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
- (1 << AC_AMPCAP_MUTE_SHIFT));
- break;
- case AD1884A_MOBILE:
- spec->mixers[0] = ad1884a_mobile_mixers;
- spec->init_verbs[0] = ad1884a_mobile_verbs;
- spec->multiout.dig_out_nid = 0;
- codec->patch_ops.unsol_event = ad1884a_hp_unsol_event;
- codec->patch_ops.init = ad1884a_hp_init;
- /* set the upper-limit for mixer amp to 0dB for avoiding the
- * possible damage by overloading
- */
- snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
- (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
- (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
- (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
- (1 << AC_AMPCAP_MUTE_SHIFT));
- break;
- case AD1884A_THINKPAD:
- spec->mixers[0] = ad1984a_thinkpad_mixers;
- spec->init_verbs[spec->num_init_verbs++] =
- ad1984a_thinkpad_verbs;
- spec->multiout.dig_out_nid = 0;
- spec->input_mux = &ad1984a_thinkpad_capture_source;
- codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
- codec->patch_ops.init = ad1984a_thinkpad_init;
- break;
- case AD1984A_PRECISION:
- spec->mixers[0] = ad1984a_precision_mixers;
- spec->init_verbs[spec->num_init_verbs++] =
- ad1984a_precision_verbs;
- spec->multiout.dig_out_nid = 0;
- codec->patch_ops.unsol_event = ad1984a_precision_unsol_event;
- codec->patch_ops.init = ad1984a_precision_init;
- break;
- case AD1984A_TOUCHSMART:
- spec->mixers[0] = ad1984a_touchsmart_mixers;
- spec->init_verbs[0] = ad1984a_touchsmart_verbs;
- spec->multiout.dig_out_nid = 0;
- codec->patch_ops.unsol_event = ad1984a_touchsmart_unsol_event;
- codec->patch_ops.init = ad1984a_touchsmart_init;
- /* set the upper-limit for mixer amp to 0dB for avoiding the
- * possible damage by overloading
- */
- snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
- (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
- (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
- (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
- (1 << AC_AMPCAP_MUTE_SHIFT));
- break;
- }
-
- codec->no_trigger_sense = 1;
- codec->no_sticky_stream = 1;
-
- return 0;
-}
-
-
-/*
- * AD1882 / AD1882A
- *
- * port-A - front hp-out
- * port-B - front mic-in
- * port-C - rear line-in, shared surr-out (3stack)
- * port-D - rear line-out
- * port-E - rear mic-in, shared clfe-out (3stack)
- * port-F - rear surr-out (6stack)
- * port-G - rear clfe-out (6stack)
- */
-
-static const hda_nid_t ad1882_dac_nids[3] = {
- 0x04, 0x03, 0x05
-};
-
-static const hda_nid_t ad1882_adc_nids[2] = {
- 0x08, 0x09,
-};
-
-static const hda_nid_t ad1882_capsrc_nids[2] = {
- 0x0c, 0x0d,
-};
-
-#define AD1882_SPDIF_OUT 0x02
-
-/* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */
-static const struct hda_input_mux ad1882_capture_source = {
- .num_items = 5,
- .items = {
- { "Front Mic", 0x1 },
- { "Mic", 0x4 },
- { "Line", 0x2 },
- { "CD", 0x3 },
- { "Mix", 0x7 },
- },
-};
-
-/* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */
-static const struct hda_input_mux ad1882a_capture_source = {
- .num_items = 5,
- .items = {
- { "Front Mic", 0x1 },
- { "Mic", 0x4},
- { "Line", 0x2 },
- { "Digital Mic", 0x06 },
- { "Mix", 0x7 },
- },
-};
-
-static const struct snd_kcontrol_new ad1882_base_mixers[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
-
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Line-In Boost Volume", 0x3a, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- /* The multiple "Capture Source" controls confuse alsamixer
- * So call somewhat different..
- */
- /* .name = "Capture Source", */
- .name = "Input Source",
- .count = 2,
- .info = ad198x_mux_enum_info,
- .get = ad198x_mux_enum_get,
- .put = ad198x_mux_enum_put,
- },
- /* SPDIF controls */
- HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
- /* identical with ad1983 */
- .info = ad1983_spdif_route_info,
- .get = ad1983_spdif_route_get,
- .put = ad1983_spdif_route_put,
- },
- { } /* end */
-};
-
-static const struct snd_kcontrol_new ad1882_loopback_mixers[] = {
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
- HDA_CODEC_VOLUME("Digital Mic Boost Volume", 0x1f, 0x0, HDA_INPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new ad1882_3stack_mixers[] = {
- HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Channel Mode",
- .info = ad198x_ch_mode_info,
- .get = ad198x_ch_mode_get,
- .put = ad198x_ch_mode_put,
- },
- { } /* end */
-};
-
-static const struct snd_kcontrol_new ad1882_6stack_mixers[] = {
- HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT),
- { } /* end */
-};
-
-static const struct hda_verb ad1882_ch2_init[] = {
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
- {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- { } /* end */
-};
-
-static const struct hda_verb ad1882_ch4_init[] = {
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- { } /* end */
-};
-
-static const struct hda_verb ad1882_ch6_init[] = {
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- { } /* end */
-};
-
-static const struct hda_channel_mode ad1882_modes[3] = {
- { 2, ad1882_ch2_init },
- { 4, ad1882_ch4_init },
- { 6, ad1882_ch6_init },
-};
-
-/*
- * initialization verbs
- */
-static const struct hda_verb ad1882_init_verbs[] = {
- /* DACs; mute as default */
- {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- /* Port-A (HP) mixer */
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- /* Port-A pin */
- {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* HP selector - select DAC2 */
- {0x37, AC_VERB_SET_CONNECT_SEL, 0x1},
- /* Port-D (Line-out) mixer */
- {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- /* Port-D pin */
- {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* Mono-out mixer */
- {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- /* Mono-out pin */
- {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* Port-B (front mic) pin */
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
- /* Port-C (line-in) pin */
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
- /* Port-C mixer - mute as input */
- {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- /* Port-E (mic-in) pin */
- {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
- /* Port-E mixer - mute as input */
- {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- /* Port-F (surround) */
- {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* Port-G (CLFE) */
- {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- /* Analog mixer; mute as default */
- /* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
- {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
- /* Analog Mix output amp */
- {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
- /* SPDIF output selector */
- {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
- {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
- {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
- { } /* end */
-};
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static const struct hda_amp_list ad1882_loopbacks[] = {
- { 0x20, HDA_INPUT, 0 }, /* Front Mic */
- { 0x20, HDA_INPUT, 1 }, /* Mic */
- { 0x20, HDA_INPUT, 4 }, /* Line */
- { 0x20, HDA_INPUT, 6 }, /* CD */
- { } /* end */
-};
-#endif
-
-/* models */
-enum {
- AD1882_3STACK,
- AD1882_6STACK,
- AD1882_MODELS
-};
-
-static const char * const ad1882_models[AD1986A_MODELS] = {
- [AD1882_3STACK] = "3stack",
- [AD1882_6STACK] = "6stack",
-};
-
-
-static int patch_ad1882(struct hda_codec *codec)
-{
- struct ad198x_spec *spec;
- int err, board_config;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->spec = spec;
-
- err = snd_hda_attach_beep_device(codec, 0x10);
- if (err < 0) {
- ad198x_free(codec);
- return err;
- }
- set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
-
- spec->multiout.max_channels = 6;
- spec->multiout.num_dacs = 3;
- spec->multiout.dac_nids = ad1882_dac_nids;
- spec->multiout.dig_out_nid = AD1882_SPDIF_OUT;
- spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids);
- spec->adc_nids = ad1882_adc_nids;
- spec->capsrc_nids = ad1882_capsrc_nids;
- if (codec->vendor_id == 0x11d41882)
- spec->input_mux = &ad1882_capture_source;
- else
- spec->input_mux = &ad1882a_capture_source;
- spec->num_mixers = 2;
- spec->mixers[0] = ad1882_base_mixers;
- if (codec->vendor_id == 0x11d41882)
- spec->mixers[1] = ad1882_loopback_mixers;
- else
- spec->mixers[1] = ad1882a_loopback_mixers;
- spec->num_init_verbs = 1;
- spec->init_verbs[0] = ad1882_init_verbs;
- spec->spdif_route = 0;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- spec->loopback.amplist = ad1882_loopbacks;
-#endif
- spec->vmaster_nid = 0x04;
-
- codec->patch_ops = ad198x_patch_ops;
-
- /* override some parameters */
- board_config = snd_hda_check_board_config(codec, AD1882_MODELS,
- ad1882_models, NULL);
- switch (board_config) {
- default:
- case AD1882_3STACK:
- spec->num_mixers = 3;
- spec->mixers[2] = ad1882_3stack_mixers;
- spec->channel_mode = ad1882_modes;
- spec->num_channel_mode = ARRAY_SIZE(ad1882_modes);
- spec->need_dac_fix = 1;
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = 1;
- break;
- case AD1882_6STACK:
- spec->num_mixers = 3;
- spec->mixers[2] = ad1882_6stack_mixers;
- break;
- }
-
- codec->no_trigger_sense = 1;
- codec->no_sticky_stream = 1;
-
- return 0;
-}
-
-
-/*
- * patch entries
- */
-static const struct hda_codec_preset snd_hda_preset_analog[] = {
- { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a },
- { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
- { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a },
- { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 },
- { .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884a },
- { .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884a },
- { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
- { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
- { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1984 },
- { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
- { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
- { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
- { .id = 0x11d4882a, .name = "AD1882A", .patch = patch_ad1882 },
- { .id = 0x11d4989a, .name = "AD1989A", .patch = patch_ad1988 },
- { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 },
- {} /* terminator */
-};
-
-MODULE_ALIAS("snd-hda-codec-id:11d4*");
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Analog Devices HD-audio codec");
-
-static struct hda_codec_preset_list analog_list = {
- .preset = snd_hda_preset_analog,
- .owner = THIS_MODULE,
-};
-
-static int __init patch_analog_init(void)
-{
- return snd_hda_add_codec_preset(&analog_list);
-}
-
-static void __exit patch_analog_exit(void)
-{
- snd_hda_delete_codec_preset(&analog_list);
-}
-
-module_init(patch_analog_init)
-module_exit(patch_analog_exit)
diff --git a/ANDROID_3.4.5/sound/pci/hda/patch_ca0110.c b/ANDROID_3.4.5/sound/pci/hda/patch_ca0110.c
deleted file mode 100644
index 09ccfabb..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/patch_ca0110.c
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * HD audio interface patch for Creative X-Fi CA0110-IBG chip
- *
- * Copyright (c) 2008 Takashi Iwai <tiwai@suse.de>
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include "hda_codec.h"
-#include "hda_local.h"
-
-/*
- */
-
-struct ca0110_spec {
- struct auto_pin_cfg autocfg;
- struct hda_multi_out multiout;
- hda_nid_t out_pins[AUTO_CFG_MAX_OUTS];
- hda_nid_t dacs[AUTO_CFG_MAX_OUTS];
- hda_nid_t hp_dac;
- hda_nid_t input_pins[AUTO_PIN_LAST];
- hda_nid_t adcs[AUTO_PIN_LAST];
- hda_nid_t dig_out;
- hda_nid_t dig_in;
- unsigned int num_inputs;
- char input_labels[AUTO_PIN_LAST][32];
- struct hda_pcm pcm_rec[2]; /* PCM information */
-};
-
-/*
- * PCM callbacks
- */
-static int ca0110_playback_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct ca0110_spec *spec = codec->spec;
- return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
- hinfo);
-}
-
-static int ca0110_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct ca0110_spec *spec = codec->spec;
- return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
- stream_tag, format, substream);
-}
-
-static int ca0110_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct ca0110_spec *spec = codec->spec;
- return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
-}
-
-/*
- * Digital out
- */
-static int ca0110_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct ca0110_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_open(codec, &spec->multiout);
-}
-
-static int ca0110_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct ca0110_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_close(codec, &spec->multiout);
-}
-
-static int ca0110_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct ca0110_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
- format, substream);
-}
-
-/*
- * Analog capture
- */
-static int ca0110_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct ca0110_spec *spec = codec->spec;
-
- snd_hda_codec_setup_stream(codec, spec->adcs[substream->number],
- stream_tag, 0, format);
- return 0;
-}
-
-static int ca0110_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct ca0110_spec *spec = codec->spec;
-
- snd_hda_codec_cleanup_stream(codec, spec->adcs[substream->number]);
- return 0;
-}
-
-/*
- */
-
-static const char * const dirstr[2] = { "Playback", "Capture" };
-
-static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
- int chan, int dir)
-{
- char namestr[44];
- int type = dir ? HDA_INPUT : HDA_OUTPUT;
- struct snd_kcontrol_new knew =
- HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type);
- sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]);
- return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
-}
-
-static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
- int chan, int dir)
-{
- char namestr[44];
- int type = dir ? HDA_INPUT : HDA_OUTPUT;
- struct snd_kcontrol_new knew =
- HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type);
- sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]);
- return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
-}
-
-#define add_out_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 0)
-#define add_out_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 0)
-#define add_in_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 1)
-#define add_in_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 1)
-#define add_mono_switch(codec, nid, pfx, chan) \
- _add_switch(codec, nid, pfx, chan, 0)
-#define add_mono_volume(codec, nid, pfx, chan) \
- _add_volume(codec, nid, pfx, chan, 0)
-
-static int ca0110_build_controls(struct hda_codec *codec)
-{
- struct ca0110_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- static const char * const prefix[AUTO_CFG_MAX_OUTS] = {
- "Front", "Surround", NULL, "Side", "Multi"
- };
- hda_nid_t mutenid;
- int i, err;
-
- for (i = 0; i < spec->multiout.num_dacs; i++) {
- if (get_wcaps(codec, spec->out_pins[i]) & AC_WCAP_OUT_AMP)
- mutenid = spec->out_pins[i];
- else
- mutenid = spec->multiout.dac_nids[i];
- if (!prefix[i]) {
- err = add_mono_switch(codec, mutenid,
- "Center", 1);
- if (err < 0)
- return err;
- err = add_mono_switch(codec, mutenid,
- "LFE", 1);
- if (err < 0)
- return err;
- err = add_mono_volume(codec, spec->multiout.dac_nids[i],
- "Center", 1);
- if (err < 0)
- return err;
- err = add_mono_volume(codec, spec->multiout.dac_nids[i],
- "LFE", 1);
- if (err < 0)
- return err;
- } else {
- err = add_out_switch(codec, mutenid,
- prefix[i]);
- if (err < 0)
- return err;
- err = add_out_volume(codec, spec->multiout.dac_nids[i],
- prefix[i]);
- if (err < 0)
- return err;
- }
- }
- if (cfg->hp_outs) {
- if (get_wcaps(codec, cfg->hp_pins[0]) & AC_WCAP_OUT_AMP)
- mutenid = cfg->hp_pins[0];
- else
- mutenid = spec->multiout.dac_nids[i];
-
- err = add_out_switch(codec, mutenid, "Headphone");
- if (err < 0)
- return err;
- if (spec->hp_dac) {
- err = add_out_volume(codec, spec->hp_dac, "Headphone");
- if (err < 0)
- return err;
- }
- }
- for (i = 0; i < spec->num_inputs; i++) {
- const char *label = spec->input_labels[i];
- if (get_wcaps(codec, spec->input_pins[i]) & AC_WCAP_IN_AMP)
- mutenid = spec->input_pins[i];
- else
- mutenid = spec->adcs[i];
- err = add_in_switch(codec, mutenid, label);
- if (err < 0)
- return err;
- err = add_in_volume(codec, spec->adcs[i], label);
- if (err < 0)
- return err;
- }
-
- if (spec->dig_out) {
- err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out,
- spec->dig_out);
- if (err < 0)
- return err;
- err = snd_hda_create_spdif_share_sw(codec, &spec->multiout);
- if (err < 0)
- return err;
- spec->multiout.share_spdif = 1;
- }
- if (spec->dig_in) {
- err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in);
- if (err < 0)
- return err;
- err = add_in_volume(codec, spec->dig_in, "IEC958");
- }
- return 0;
-}
-
-/*
- */
-static const struct hda_pcm_stream ca0110_pcm_analog_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 8,
- .ops = {
- .open = ca0110_playback_pcm_open,
- .prepare = ca0110_playback_pcm_prepare,
- .cleanup = ca0110_playback_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream ca0110_pcm_analog_capture = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .ops = {
- .prepare = ca0110_capture_pcm_prepare,
- .cleanup = ca0110_capture_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream ca0110_pcm_digital_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .ops = {
- .open = ca0110_dig_playback_pcm_open,
- .close = ca0110_dig_playback_pcm_close,
- .prepare = ca0110_dig_playback_pcm_prepare
- },
-};
-
-static const struct hda_pcm_stream ca0110_pcm_digital_capture = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
-};
-
-static int ca0110_build_pcms(struct hda_codec *codec)
-{
- struct ca0110_spec *spec = codec->spec;
- struct hda_pcm *info = spec->pcm_rec;
-
- codec->pcm_info = info;
- codec->num_pcms = 0;
-
- info->name = "CA0110 Analog";
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ca0110_pcm_analog_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dacs[0];
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
- spec->multiout.max_channels;
- info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0110_pcm_analog_capture;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_inputs;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0];
- codec->num_pcms++;
-
- if (!spec->dig_out && !spec->dig_in)
- return 0;
-
- info++;
- info->name = "CA0110 Digital";
- info->pcm_type = HDA_PCM_TYPE_SPDIF;
- if (spec->dig_out) {
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
- ca0110_pcm_digital_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dig_out;
- }
- if (spec->dig_in) {
- info->stream[SNDRV_PCM_STREAM_CAPTURE] =
- ca0110_pcm_digital_capture;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in;
- }
- codec->num_pcms++;
-
- return 0;
-}
-
-static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac)
-{
- if (pin) {
- snd_hda_codec_write(codec, pin, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
- if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
- snd_hda_codec_write(codec, pin, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_OUT_UNMUTE);
- }
- if (dac)
- snd_hda_codec_write(codec, dac, 0,
- AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO);
-}
-
-static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
-{
- if (pin) {
- snd_hda_codec_write(codec, pin, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80);
- if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP)
- snd_hda_codec_write(codec, pin, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_IN_UNMUTE(0));
- }
- if (adc)
- snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_IN_UNMUTE(0));
-}
-
-static int ca0110_init(struct hda_codec *codec)
-{
- struct ca0110_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i;
-
- for (i = 0; i < spec->multiout.num_dacs; i++)
- init_output(codec, spec->out_pins[i],
- spec->multiout.dac_nids[i]);
- init_output(codec, cfg->hp_pins[0], spec->hp_dac);
- init_output(codec, cfg->dig_out_pins[0], spec->dig_out);
-
- for (i = 0; i < spec->num_inputs; i++)
- init_input(codec, spec->input_pins[i], spec->adcs[i]);
- init_input(codec, cfg->dig_in_pin, spec->dig_in);
- return 0;
-}
-
-static void ca0110_free(struct hda_codec *codec)
-{
- kfree(codec->spec);
-}
-
-static const struct hda_codec_ops ca0110_patch_ops = {
- .build_controls = ca0110_build_controls,
- .build_pcms = ca0110_build_pcms,
- .init = ca0110_init,
- .free = ca0110_free,
-};
-
-
-static void parse_line_outs(struct hda_codec *codec)
-{
- struct ca0110_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i, n;
- unsigned int def_conf;
- hda_nid_t nid;
-
- n = 0;
- for (i = 0; i < cfg->line_outs; i++) {
- nid = cfg->line_out_pins[i];
- def_conf = snd_hda_codec_get_pincfg(codec, nid);
- if (!def_conf)
- continue; /* invalid pin */
- if (snd_hda_get_connections(codec, nid, &spec->dacs[i], 1) != 1)
- continue;
- spec->out_pins[n++] = nid;
- }
- spec->multiout.dac_nids = spec->dacs;
- spec->multiout.num_dacs = n;
- spec->multiout.max_channels = n * 2;
-}
-
-static void parse_hp_out(struct hda_codec *codec)
-{
- struct ca0110_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i;
- unsigned int def_conf;
- hda_nid_t nid, dac;
-
- if (!cfg->hp_outs)
- return;
- nid = cfg->hp_pins[0];
- def_conf = snd_hda_codec_get_pincfg(codec, nid);
- if (!def_conf) {
- cfg->hp_outs = 0;
- return;
- }
- if (snd_hda_get_connections(codec, nid, &dac, 1) != 1)
- return;
-
- for (i = 0; i < cfg->line_outs; i++)
- if (dac == spec->dacs[i])
- break;
- if (i >= cfg->line_outs) {
- spec->hp_dac = dac;
- spec->multiout.hp_nid = dac;
- }
-}
-
-static void parse_input(struct hda_codec *codec)
-{
- struct ca0110_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- hda_nid_t nid, pin;
- int n, i, j;
-
- n = 0;
- nid = codec->start_nid;
- for (i = 0; i < codec->num_nodes; i++, nid++) {
- unsigned int wcaps = get_wcaps(codec, nid);
- unsigned int type = get_wcaps_type(wcaps);
- if (type != AC_WID_AUD_IN)
- continue;
- if (snd_hda_get_connections(codec, nid, &pin, 1) != 1)
- continue;
- if (pin == cfg->dig_in_pin) {
- spec->dig_in = nid;
- continue;
- }
- for (j = 0; j < cfg->num_inputs; j++)
- if (cfg->inputs[j].pin == pin)
- break;
- if (j >= cfg->num_inputs)
- continue;
- spec->input_pins[n] = pin;
- snd_hda_get_pin_label(codec, pin, cfg,
- spec->input_labels[n],
- sizeof(spec->input_labels[n]), NULL);
- spec->adcs[n] = nid;
- n++;
- }
- spec->num_inputs = n;
-}
-
-static void parse_digital(struct hda_codec *codec)
-{
- struct ca0110_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
-
- if (cfg->dig_outs &&
- snd_hda_get_connections(codec, cfg->dig_out_pins[0],
- &spec->dig_out, 1) == 1)
- spec->multiout.dig_out_nid = spec->dig_out;
-}
-
-static int ca0110_parse_auto_config(struct hda_codec *codec)
-{
- struct ca0110_spec *spec = codec->spec;
- int err;
-
- err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
- if (err < 0)
- return err;
-
- parse_line_outs(codec);
- parse_hp_out(codec);
- parse_digital(codec);
- parse_input(codec);
- return 0;
-}
-
-
-static int patch_ca0110(struct hda_codec *codec)
-{
- struct ca0110_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- codec->spec = spec;
-
- codec->bus->needs_damn_long_delay = 1;
-
- err = ca0110_parse_auto_config(codec);
- if (err < 0)
- goto error;
-
- codec->patch_ops = ca0110_patch_ops;
-
- return 0;
-
- error:
- kfree(codec->spec);
- codec->spec = NULL;
- return err;
-}
-
-
-/*
- * patch entries
- */
-static const struct hda_codec_preset snd_hda_preset_ca0110[] = {
- { .id = 0x1102000a, .name = "CA0110-IBG", .patch = patch_ca0110 },
- { .id = 0x1102000b, .name = "CA0110-IBG", .patch = patch_ca0110 },
- { .id = 0x1102000d, .name = "SB0880 X-Fi", .patch = patch_ca0110 },
- {} /* terminator */
-};
-
-MODULE_ALIAS("snd-hda-codec-id:1102000a");
-MODULE_ALIAS("snd-hda-codec-id:1102000b");
-MODULE_ALIAS("snd-hda-codec-id:1102000d");
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Creative CA0110-IBG HD-audio codec");
-
-static struct hda_codec_preset_list ca0110_list = {
- .preset = snd_hda_preset_ca0110,
- .owner = THIS_MODULE,
-};
-
-static int __init patch_ca0110_init(void)
-{
- return snd_hda_add_codec_preset(&ca0110_list);
-}
-
-static void __exit patch_ca0110_exit(void)
-{
- snd_hda_delete_codec_preset(&ca0110_list);
-}
-
-module_init(patch_ca0110_init)
-module_exit(patch_ca0110_exit)
diff --git a/ANDROID_3.4.5/sound/pci/hda/patch_ca0132.c b/ANDROID_3.4.5/sound/pci/hda/patch_ca0132.c
deleted file mode 100644
index 21d91d58..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/patch_ca0132.c
+++ /dev/null
@@ -1,1103 +0,0 @@
-/*
- * HD audio interface patch for Creative CA0132 chip
- *
- * Copyright (c) 2011, Creative Technology Ltd.
- *
- * Based on patch_ca0110.c
- * Copyright (c) 2008 Takashi Iwai <tiwai@suse.de>
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/mutex.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include "hda_codec.h"
-#include "hda_local.h"
-
-#define WIDGET_CHIP_CTRL 0x15
-#define WIDGET_DSP_CTRL 0x16
-
-#define WUH_MEM_CONNID 10
-#define DSP_MEM_CONNID 16
-
-enum hda_cmd_vendor_io {
- /* for DspIO node */
- VENDOR_DSPIO_SCP_WRITE_DATA_LOW = 0x000,
- VENDOR_DSPIO_SCP_WRITE_DATA_HIGH = 0x100,
-
- VENDOR_DSPIO_STATUS = 0xF01,
- VENDOR_DSPIO_SCP_POST_READ_DATA = 0x702,
- VENDOR_DSPIO_SCP_READ_DATA = 0xF02,
- VENDOR_DSPIO_DSP_INIT = 0x703,
- VENDOR_DSPIO_SCP_POST_COUNT_QUERY = 0x704,
- VENDOR_DSPIO_SCP_READ_COUNT = 0xF04,
-
- /* for ChipIO node */
- VENDOR_CHIPIO_ADDRESS_LOW = 0x000,
- VENDOR_CHIPIO_ADDRESS_HIGH = 0x100,
- VENDOR_CHIPIO_STREAM_FORMAT = 0x200,
- VENDOR_CHIPIO_DATA_LOW = 0x300,
- VENDOR_CHIPIO_DATA_HIGH = 0x400,
-
- VENDOR_CHIPIO_GET_PARAMETER = 0xF00,
- VENDOR_CHIPIO_STATUS = 0xF01,
- VENDOR_CHIPIO_HIC_POST_READ = 0x702,
- VENDOR_CHIPIO_HIC_READ_DATA = 0xF03,
-
- VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE = 0x70A,
-
- VENDOR_CHIPIO_PLL_PMU_WRITE = 0x70C,
- VENDOR_CHIPIO_PLL_PMU_READ = 0xF0C,
- VENDOR_CHIPIO_8051_ADDRESS_LOW = 0x70D,
- VENDOR_CHIPIO_8051_ADDRESS_HIGH = 0x70E,
- VENDOR_CHIPIO_FLAG_SET = 0x70F,
- VENDOR_CHIPIO_FLAGS_GET = 0xF0F,
- VENDOR_CHIPIO_PARAMETER_SET = 0x710,
- VENDOR_CHIPIO_PARAMETER_GET = 0xF10,
-
- VENDOR_CHIPIO_PORT_ALLOC_CONFIG_SET = 0x711,
- VENDOR_CHIPIO_PORT_ALLOC_SET = 0x712,
- VENDOR_CHIPIO_PORT_ALLOC_GET = 0xF12,
- VENDOR_CHIPIO_PORT_FREE_SET = 0x713,
-
- VENDOR_CHIPIO_PARAMETER_EX_ID_GET = 0xF17,
- VENDOR_CHIPIO_PARAMETER_EX_ID_SET = 0x717,
- VENDOR_CHIPIO_PARAMETER_EX_VALUE_GET = 0xF18,
- VENDOR_CHIPIO_PARAMETER_EX_VALUE_SET = 0x718
-};
-
-/*
- * Control flag IDs
- */
-enum control_flag_id {
- /* Connection manager stream setup is bypassed/enabled */
- CONTROL_FLAG_C_MGR = 0,
- /* DSP DMA is bypassed/enabled */
- CONTROL_FLAG_DMA = 1,
- /* 8051 'idle' mode is disabled/enabled */
- CONTROL_FLAG_IDLE_ENABLE = 2,
- /* Tracker for the SPDIF-in path is bypassed/enabled */
- CONTROL_FLAG_TRACKER = 3,
- /* DigitalOut to Spdif2Out connection is disabled/enabled */
- CONTROL_FLAG_SPDIF2OUT = 4,
- /* Digital Microphone is disabled/enabled */
- CONTROL_FLAG_DMIC = 5,
- /* ADC_B rate is 48 kHz/96 kHz */
- CONTROL_FLAG_ADC_B_96KHZ = 6,
- /* ADC_C rate is 48 kHz/96 kHz */
- CONTROL_FLAG_ADC_C_96KHZ = 7,
- /* DAC rate is 48 kHz/96 kHz (affects all DACs) */
- CONTROL_FLAG_DAC_96KHZ = 8,
- /* DSP rate is 48 kHz/96 kHz */
- CONTROL_FLAG_DSP_96KHZ = 9,
- /* SRC clock is 98 MHz/196 MHz (196 MHz forces rate to 96 KHz) */
- CONTROL_FLAG_SRC_CLOCK_196MHZ = 10,
- /* SRC rate is 48 kHz/96 kHz (48 kHz disabled when clock is 196 MHz) */
- CONTROL_FLAG_SRC_RATE_96KHZ = 11,
- /* Decode Loop (DSP->SRC->DSP) is disabled/enabled */
- CONTROL_FLAG_DECODE_LOOP = 12,
- /* De-emphasis filter on DAC-1 disabled/enabled */
- CONTROL_FLAG_DAC1_DEEMPHASIS = 13,
- /* De-emphasis filter on DAC-2 disabled/enabled */
- CONTROL_FLAG_DAC2_DEEMPHASIS = 14,
- /* De-emphasis filter on DAC-3 disabled/enabled */
- CONTROL_FLAG_DAC3_DEEMPHASIS = 15,
- /* High-pass filter on ADC_B disabled/enabled */
- CONTROL_FLAG_ADC_B_HIGH_PASS = 16,
- /* High-pass filter on ADC_C disabled/enabled */
- CONTROL_FLAG_ADC_C_HIGH_PASS = 17,
- /* Common mode on Port_A disabled/enabled */
- CONTROL_FLAG_PORT_A_COMMON_MODE = 18,
- /* Common mode on Port_D disabled/enabled */
- CONTROL_FLAG_PORT_D_COMMON_MODE = 19,
- /* Impedance for ramp generator on Port_A 16 Ohm/10K Ohm */
- CONTROL_FLAG_PORT_A_10KOHM_LOAD = 20,
- /* Impedance for ramp generator on Port_D, 16 Ohm/10K Ohm */
- CONTROL_FLAG_PORT_D_10K0HM_LOAD = 21,
- /* ASI rate is 48kHz/96kHz */
- CONTROL_FLAG_ASI_96KHZ = 22,
- /* DAC power settings able to control attached ports no/yes */
- CONTROL_FLAG_DACS_CONTROL_PORTS = 23,
- /* Clock Stop OK reporting is disabled/enabled */
- CONTROL_FLAG_CONTROL_STOP_OK_ENABLE = 24,
- /* Number of control flags */
- CONTROL_FLAGS_MAX = (CONTROL_FLAG_CONTROL_STOP_OK_ENABLE+1)
-};
-
-/*
- * Control parameter IDs
- */
-enum control_parameter_id {
- /* 0: force HDA, 1: allow DSP if HDA Spdif1Out stream is idle */
- CONTROL_PARAM_SPDIF1_SOURCE = 2,
-
- /* Stream Control */
-
- /* Select stream with the given ID */
- CONTROL_PARAM_STREAM_ID = 24,
- /* Source connection point for the selected stream */
- CONTROL_PARAM_STREAM_SOURCE_CONN_POINT = 25,
- /* Destination connection point for the selected stream */
- CONTROL_PARAM_STREAM_DEST_CONN_POINT = 26,
- /* Number of audio channels in the selected stream */
- CONTROL_PARAM_STREAMS_CHANNELS = 27,
- /*Enable control for the selected stream */
- CONTROL_PARAM_STREAM_CONTROL = 28,
-
- /* Connection Point Control */
-
- /* Select connection point with the given ID */
- CONTROL_PARAM_CONN_POINT_ID = 29,
- /* Connection point sample rate */
- CONTROL_PARAM_CONN_POINT_SAMPLE_RATE = 30,
-
- /* Node Control */
-
- /* Select HDA node with the given ID */
- CONTROL_PARAM_NODE_ID = 31
-};
-
-/*
- * Dsp Io Status codes
- */
-enum hda_vendor_status_dspio {
- /* Success */
- VENDOR_STATUS_DSPIO_OK = 0x00,
- /* Busy, unable to accept new command, the host must retry */
- VENDOR_STATUS_DSPIO_BUSY = 0x01,
- /* SCP command queue is full */
- VENDOR_STATUS_DSPIO_SCP_COMMAND_QUEUE_FULL = 0x02,
- /* SCP response queue is empty */
- VENDOR_STATUS_DSPIO_SCP_RESPONSE_QUEUE_EMPTY = 0x03
-};
-
-/*
- * Chip Io Status codes
- */
-enum hda_vendor_status_chipio {
- /* Success */
- VENDOR_STATUS_CHIPIO_OK = 0x00,
- /* Busy, unable to accept new command, the host must retry */
- VENDOR_STATUS_CHIPIO_BUSY = 0x01
-};
-
-/*
- * CA0132 sample rate
- */
-enum ca0132_sample_rate {
- SR_6_000 = 0x00,
- SR_8_000 = 0x01,
- SR_9_600 = 0x02,
- SR_11_025 = 0x03,
- SR_16_000 = 0x04,
- SR_22_050 = 0x05,
- SR_24_000 = 0x06,
- SR_32_000 = 0x07,
- SR_44_100 = 0x08,
- SR_48_000 = 0x09,
- SR_88_200 = 0x0A,
- SR_96_000 = 0x0B,
- SR_144_000 = 0x0C,
- SR_176_400 = 0x0D,
- SR_192_000 = 0x0E,
- SR_384_000 = 0x0F,
-
- SR_COUNT = 0x10,
-
- SR_RATE_UNKNOWN = 0x1F
-};
-
-/*
- * Scp Helper function
- */
-enum get_set {
- IS_SET = 0,
- IS_GET = 1,
-};
-
-/*
- * Duplicated from ca0110 codec
- */
-
-static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac)
-{
- if (pin) {
- snd_hda_codec_write(codec, pin, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
- if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
- snd_hda_codec_write(codec, pin, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_OUT_UNMUTE);
- }
- if (dac)
- snd_hda_codec_write(codec, dac, 0,
- AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO);
-}
-
-static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
-{
- if (pin) {
- snd_hda_codec_write(codec, pin, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- PIN_VREF80);
- if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP)
- snd_hda_codec_write(codec, pin, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_IN_UNMUTE(0));
- }
- if (adc)
- snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_IN_UNMUTE(0));
-}
-
-static char *dirstr[2] = { "Playback", "Capture" };
-
-static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
- int chan, int dir)
-{
- char namestr[44];
- int type = dir ? HDA_INPUT : HDA_OUTPUT;
- struct snd_kcontrol_new knew =
- HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type);
- sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]);
- return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
-}
-
-static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
- int chan, int dir)
-{
- char namestr[44];
- int type = dir ? HDA_INPUT : HDA_OUTPUT;
- struct snd_kcontrol_new knew =
- HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type);
- sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]);
- return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
-}
-
-#define add_out_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 0)
-#define add_out_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 0)
-#define add_in_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 1)
-#define add_in_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 1)
-#define add_mono_switch(codec, nid, pfx, chan) \
- _add_switch(codec, nid, pfx, chan, 0)
-#define add_mono_volume(codec, nid, pfx, chan) \
- _add_volume(codec, nid, pfx, chan, 0)
-#define add_in_mono_switch(codec, nid, pfx, chan) \
- _add_switch(codec, nid, pfx, chan, 1)
-#define add_in_mono_volume(codec, nid, pfx, chan) \
- _add_volume(codec, nid, pfx, chan, 1)
-
-
-/*
- * CA0132 specific
- */
-
-struct ca0132_spec {
- struct auto_pin_cfg autocfg;
- struct hda_multi_out multiout;
- hda_nid_t out_pins[AUTO_CFG_MAX_OUTS];
- hda_nid_t dacs[AUTO_CFG_MAX_OUTS];
- hda_nid_t hp_dac;
- hda_nid_t input_pins[AUTO_PIN_LAST];
- hda_nid_t adcs[AUTO_PIN_LAST];
- hda_nid_t dig_out;
- hda_nid_t dig_in;
- unsigned int num_inputs;
- long curr_hp_switch;
- long curr_hp_volume[2];
- long curr_speaker_switch;
- struct mutex chipio_mutex;
- const char *input_labels[AUTO_PIN_LAST];
- struct hda_pcm pcm_rec[2]; /* PCM information */
-};
-
-/* Chip access helper function */
-static int chipio_send(struct hda_codec *codec,
- unsigned int reg,
- unsigned int data)
-{
- unsigned int res;
- int retry = 50;
-
- /* send bits of data specified by reg */
- do {
- res = snd_hda_codec_read(codec, WIDGET_CHIP_CTRL, 0,
- reg, data);
- if (res == VENDOR_STATUS_CHIPIO_OK)
- return 0;
- } while (--retry);
- return -EIO;
-}
-
-/*
- * Write chip address through the vendor widget -- NOT protected by the Mutex!
- */
-static int chipio_write_address(struct hda_codec *codec,
- unsigned int chip_addx)
-{
- int res;
-
- /* send low 16 bits of the address */
- res = chipio_send(codec, VENDOR_CHIPIO_ADDRESS_LOW,
- chip_addx & 0xffff);
-
- if (res != -EIO) {
- /* send high 16 bits of the address */
- res = chipio_send(codec, VENDOR_CHIPIO_ADDRESS_HIGH,
- chip_addx >> 16);
- }
-
- return res;
-}
-
-/*
- * Write data through the vendor widget -- NOT protected by the Mutex!
- */
-
-static int chipio_write_data(struct hda_codec *codec, unsigned int data)
-{
- int res;
-
- /* send low 16 bits of the data */
- res = chipio_send(codec, VENDOR_CHIPIO_DATA_LOW, data & 0xffff);
-
- if (res != -EIO) {
- /* send high 16 bits of the data */
- res = chipio_send(codec, VENDOR_CHIPIO_DATA_HIGH,
- data >> 16);
- }
-
- return res;
-}
-
-/*
- * Read data through the vendor widget -- NOT protected by the Mutex!
- */
-static int chipio_read_data(struct hda_codec *codec, unsigned int *data)
-{
- int res;
-
- /* post read */
- res = chipio_send(codec, VENDOR_CHIPIO_HIC_POST_READ, 0);
-
- if (res != -EIO) {
- /* read status */
- res = chipio_send(codec, VENDOR_CHIPIO_STATUS, 0);
- }
-
- if (res != -EIO) {
- /* read data */
- *data = snd_hda_codec_read(codec, WIDGET_CHIP_CTRL, 0,
- VENDOR_CHIPIO_HIC_READ_DATA,
- 0);
- }
-
- return res;
-}
-
-/*
- * Write given value to the given address through the chip I/O widget.
- * protected by the Mutex
- */
-static int chipio_write(struct hda_codec *codec,
- unsigned int chip_addx, const unsigned int data)
-{
- struct ca0132_spec *spec = codec->spec;
- int err;
-
- mutex_lock(&spec->chipio_mutex);
-
- /* write the address, and if successful proceed to write data */
- err = chipio_write_address(codec, chip_addx);
- if (err < 0)
- goto exit;
-
- err = chipio_write_data(codec, data);
- if (err < 0)
- goto exit;
-
-exit:
- mutex_unlock(&spec->chipio_mutex);
- return err;
-}
-
-/*
- * Read the given address through the chip I/O widget
- * protected by the Mutex
- */
-static int chipio_read(struct hda_codec *codec,
- unsigned int chip_addx, unsigned int *data)
-{
- struct ca0132_spec *spec = codec->spec;
- int err;
-
- mutex_lock(&spec->chipio_mutex);
-
- /* write the address, and if successful proceed to write data */
- err = chipio_write_address(codec, chip_addx);
- if (err < 0)
- goto exit;
-
- err = chipio_read_data(codec, data);
- if (err < 0)
- goto exit;
-
-exit:
- mutex_unlock(&spec->chipio_mutex);
- return err;
-}
-
-/*
- * PCM stuffs
- */
-static void ca0132_setup_stream(struct hda_codec *codec, hda_nid_t nid,
- u32 stream_tag,
- int channel_id, int format)
-{
- unsigned int oldval, newval;
-
- if (!nid)
- return;
-
- snd_printdd("ca0132_setup_stream: "
- "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
- nid, stream_tag, channel_id, format);
-
- /* update the format-id if changed */
- oldval = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_STREAM_FORMAT,
- 0);
- if (oldval != format) {
- msleep(20);
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_STREAM_FORMAT,
- format);
- }
-
- oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
- newval = (stream_tag << 4) | channel_id;
- if (oldval != newval) {
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_CHANNEL_STREAMID,
- newval);
- }
-}
-
-static void ca0132_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
-{
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0);
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
-}
-
-/*
- * PCM callbacks
- */
-static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct ca0132_spec *spec = codec->spec;
-
- ca0132_setup_stream(codec, spec->dacs[0], stream_tag, 0, format);
-
- return 0;
-}
-
-static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct ca0132_spec *spec = codec->spec;
-
- ca0132_cleanup_stream(codec, spec->dacs[0]);
-
- return 0;
-}
-
-/*
- * Digital out
- */
-static int ca0132_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct ca0132_spec *spec = codec->spec;
-
- ca0132_setup_stream(codec, spec->dig_out, stream_tag, 0, format);
-
- return 0;
-}
-
-static int ca0132_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct ca0132_spec *spec = codec->spec;
-
- ca0132_cleanup_stream(codec, spec->dig_out);
-
- return 0;
-}
-
-/*
- * Analog capture
- */
-static int ca0132_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct ca0132_spec *spec = codec->spec;
-
- ca0132_setup_stream(codec, spec->adcs[substream->number],
- stream_tag, 0, format);
-
- return 0;
-}
-
-static int ca0132_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct ca0132_spec *spec = codec->spec;
-
- ca0132_cleanup_stream(codec, spec->adcs[substream->number]);
-
- return 0;
-}
-
-/*
- * Digital capture
- */
-static int ca0132_dig_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct ca0132_spec *spec = codec->spec;
-
- ca0132_setup_stream(codec, spec->dig_in, stream_tag, 0, format);
-
- return 0;
-}
-
-static int ca0132_dig_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct ca0132_spec *spec = codec->spec;
-
- ca0132_cleanup_stream(codec, spec->dig_in);
-
- return 0;
-}
-
-/*
- */
-static struct hda_pcm_stream ca0132_pcm_analog_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .ops = {
- .prepare = ca0132_playback_pcm_prepare,
- .cleanup = ca0132_playback_pcm_cleanup
- },
-};
-
-static struct hda_pcm_stream ca0132_pcm_analog_capture = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .ops = {
- .prepare = ca0132_capture_pcm_prepare,
- .cleanup = ca0132_capture_pcm_cleanup
- },
-};
-
-static struct hda_pcm_stream ca0132_pcm_digital_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .ops = {
- .prepare = ca0132_dig_playback_pcm_prepare,
- .cleanup = ca0132_dig_playback_pcm_cleanup
- },
-};
-
-static struct hda_pcm_stream ca0132_pcm_digital_capture = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .ops = {
- .prepare = ca0132_dig_capture_pcm_prepare,
- .cleanup = ca0132_dig_capture_pcm_cleanup
- },
-};
-
-static int ca0132_build_pcms(struct hda_codec *codec)
-{
- struct ca0132_spec *spec = codec->spec;
- struct hda_pcm *info = spec->pcm_rec;
-
- codec->pcm_info = info;
- codec->num_pcms = 0;
-
- info->name = "CA0132 Analog";
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ca0132_pcm_analog_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dacs[0];
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
- spec->multiout.max_channels;
- info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_inputs;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0];
- codec->num_pcms++;
-
- if (!spec->dig_out && !spec->dig_in)
- return 0;
-
- info++;
- info->name = "CA0132 Digital";
- info->pcm_type = HDA_PCM_TYPE_SPDIF;
- if (spec->dig_out) {
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
- ca0132_pcm_digital_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dig_out;
- }
- if (spec->dig_in) {
- info->stream[SNDRV_PCM_STREAM_CAPTURE] =
- ca0132_pcm_digital_capture;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in;
- }
- codec->num_pcms++;
-
- return 0;
-}
-
-#define REG_CODEC_MUTE 0x18b014
-#define REG_CODEC_HP_VOL_L 0x18b070
-#define REG_CODEC_HP_VOL_R 0x18b074
-
-static int ca0132_hp_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ca0132_spec *spec = codec->spec;
- long *valp = ucontrol->value.integer.value;
-
- *valp = spec->curr_hp_switch;
- return 0;
-}
-
-static int ca0132_hp_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ca0132_spec *spec = codec->spec;
- long *valp = ucontrol->value.integer.value;
- unsigned int data;
- int err;
-
- /* any change? */
- if (spec->curr_hp_switch == *valp)
- return 0;
-
- snd_hda_power_up(codec);
-
- err = chipio_read(codec, REG_CODEC_MUTE, &data);
- if (err < 0)
- goto exit;
-
- /* *valp 0 is mute, 1 is unmute */
- data = (data & 0x7f) | (*valp ? 0 : 0x80);
- err = chipio_write(codec, REG_CODEC_MUTE, data);
- if (err < 0)
- goto exit;
-
- spec->curr_hp_switch = *valp;
-
- exit:
- snd_hda_power_down(codec);
- return err < 0 ? err : 1;
-}
-
-static int ca0132_speaker_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ca0132_spec *spec = codec->spec;
- long *valp = ucontrol->value.integer.value;
-
- *valp = spec->curr_speaker_switch;
- return 0;
-}
-
-static int ca0132_speaker_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ca0132_spec *spec = codec->spec;
- long *valp = ucontrol->value.integer.value;
- unsigned int data;
- int err;
-
- /* any change? */
- if (spec->curr_speaker_switch == *valp)
- return 0;
-
- snd_hda_power_up(codec);
-
- err = chipio_read(codec, REG_CODEC_MUTE, &data);
- if (err < 0)
- goto exit;
-
- /* *valp 0 is mute, 1 is unmute */
- data = (data & 0xef) | (*valp ? 0 : 0x10);
- err = chipio_write(codec, REG_CODEC_MUTE, data);
- if (err < 0)
- goto exit;
-
- spec->curr_speaker_switch = *valp;
-
- exit:
- snd_hda_power_down(codec);
- return err < 0 ? err : 1;
-}
-
-static int ca0132_hp_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ca0132_spec *spec = codec->spec;
- long *valp = ucontrol->value.integer.value;
-
- *valp++ = spec->curr_hp_volume[0];
- *valp = spec->curr_hp_volume[1];
- return 0;
-}
-
-static int ca0132_hp_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ca0132_spec *spec = codec->spec;
- long *valp = ucontrol->value.integer.value;
- long left_vol, right_vol;
- unsigned int data;
- int val;
- int err;
-
- left_vol = *valp++;
- right_vol = *valp;
-
- /* any change? */
- if ((spec->curr_hp_volume[0] == left_vol) &&
- (spec->curr_hp_volume[1] == right_vol))
- return 0;
-
- snd_hda_power_up(codec);
-
- err = chipio_read(codec, REG_CODEC_HP_VOL_L, &data);
- if (err < 0)
- goto exit;
-
- val = 31 - left_vol;
- data = (data & 0xe0) | val;
- err = chipio_write(codec, REG_CODEC_HP_VOL_L, data);
- if (err < 0)
- goto exit;
-
- val = 31 - right_vol;
- data = (data & 0xe0) | val;
- err = chipio_write(codec, REG_CODEC_HP_VOL_R, data);
- if (err < 0)
- goto exit;
-
- spec->curr_hp_volume[0] = left_vol;
- spec->curr_hp_volume[1] = right_vol;
-
- exit:
- snd_hda_power_down(codec);
- return err < 0 ? err : 1;
-}
-
-static int add_hp_switch(struct hda_codec *codec, hda_nid_t nid)
-{
- struct snd_kcontrol_new knew =
- HDA_CODEC_MUTE_MONO("Headphone Playback Switch",
- nid, 1, 0, HDA_OUTPUT);
- knew.get = ca0132_hp_switch_get;
- knew.put = ca0132_hp_switch_put;
- return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
-}
-
-static int add_hp_volume(struct hda_codec *codec, hda_nid_t nid)
-{
- struct snd_kcontrol_new knew =
- HDA_CODEC_VOLUME_MONO("Headphone Playback Volume",
- nid, 3, 0, HDA_OUTPUT);
- knew.get = ca0132_hp_volume_get;
- knew.put = ca0132_hp_volume_put;
- return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
-}
-
-static int add_speaker_switch(struct hda_codec *codec, hda_nid_t nid)
-{
- struct snd_kcontrol_new knew =
- HDA_CODEC_MUTE_MONO("Speaker Playback Switch",
- nid, 1, 0, HDA_OUTPUT);
- knew.get = ca0132_speaker_switch_get;
- knew.put = ca0132_speaker_switch_put;
- return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
-}
-
-static void ca0132_fix_hp_caps(struct hda_codec *codec)
-{
- struct ca0132_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- unsigned int caps;
-
- /* set mute-capable, 1db step, 32 steps, ofs 6 */
- caps = 0x80031f06;
- snd_hda_override_amp_caps(codec, cfg->hp_pins[0], HDA_OUTPUT, caps);
-}
-
-static int ca0132_build_controls(struct hda_codec *codec)
-{
- struct ca0132_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i, err;
-
- if (spec->multiout.num_dacs) {
- err = add_speaker_switch(codec, spec->out_pins[0]);
- if (err < 0)
- return err;
- }
-
- if (cfg->hp_outs) {
- ca0132_fix_hp_caps(codec);
- err = add_hp_switch(codec, cfg->hp_pins[0]);
- if (err < 0)
- return err;
- err = add_hp_volume(codec, cfg->hp_pins[0]);
- if (err < 0)
- return err;
- }
-
- for (i = 0; i < spec->num_inputs; i++) {
- const char *label = spec->input_labels[i];
-
- err = add_in_switch(codec, spec->adcs[i], label);
- if (err < 0)
- return err;
- err = add_in_volume(codec, spec->adcs[i], label);
- if (err < 0)
- return err;
- if (cfg->inputs[i].type == AUTO_PIN_MIC) {
- /* add Mic-Boost */
- err = add_in_mono_volume(codec, spec->input_pins[i],
- "Mic Boost", 1);
- if (err < 0)
- return err;
- }
- }
-
- if (spec->dig_out) {
- err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out,
- spec->dig_out);
- if (err < 0)
- return err;
- err = add_out_volume(codec, spec->dig_out, "IEC958");
- if (err < 0)
- return err;
- }
-
- if (spec->dig_in) {
- err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in);
- if (err < 0)
- return err;
- err = add_in_volume(codec, spec->dig_in, "IEC958");
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-
-static void ca0132_set_ct_ext(struct hda_codec *codec, int enable)
-{
- /* Set Creative extension */
- snd_printdd("SET CREATIVE EXTENSION\n");
- snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
- VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE,
- enable);
- msleep(20);
-}
-
-
-static void ca0132_config(struct hda_codec *codec)
-{
- struct ca0132_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
-
- /* line-outs */
- cfg->line_outs = 1;
- cfg->line_out_pins[0] = 0x0b; /* front */
- cfg->line_out_type = AUTO_PIN_LINE_OUT;
-
- spec->dacs[0] = 0x02;
- spec->out_pins[0] = 0x0b;
- spec->multiout.dac_nids = spec->dacs;
- spec->multiout.num_dacs = 1;
- spec->multiout.max_channels = 2;
-
- /* headphone */
- cfg->hp_outs = 1;
- cfg->hp_pins[0] = 0x0f;
-
- spec->hp_dac = 0;
- spec->multiout.hp_nid = 0;
-
- /* inputs */
- cfg->num_inputs = 2; /* Mic-in and line-in */
- cfg->inputs[0].pin = 0x12;
- cfg->inputs[0].type = AUTO_PIN_MIC;
- cfg->inputs[1].pin = 0x11;
- cfg->inputs[1].type = AUTO_PIN_LINE_IN;
-
- /* Mic-in */
- spec->input_pins[0] = 0x12;
- spec->input_labels[0] = "Mic-In";
- spec->adcs[0] = 0x07;
-
- /* Line-In */
- spec->input_pins[1] = 0x11;
- spec->input_labels[1] = "Line-In";
- spec->adcs[1] = 0x08;
- spec->num_inputs = 2;
-}
-
-static void ca0132_init_chip(struct hda_codec *codec)
-{
- struct ca0132_spec *spec = codec->spec;
-
- mutex_init(&spec->chipio_mutex);
-}
-
-static void ca0132_exit_chip(struct hda_codec *codec)
-{
- /* put any chip cleanup stuffs here. */
-}
-
-static int ca0132_init(struct hda_codec *codec)
-{
- struct ca0132_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i;
-
- for (i = 0; i < spec->multiout.num_dacs; i++) {
- init_output(codec, spec->out_pins[i],
- spec->multiout.dac_nids[i]);
- }
- init_output(codec, cfg->hp_pins[0], spec->hp_dac);
- init_output(codec, cfg->dig_out_pins[0], spec->dig_out);
-
- for (i = 0; i < spec->num_inputs; i++)
- init_input(codec, spec->input_pins[i], spec->adcs[i]);
-
- init_input(codec, cfg->dig_in_pin, spec->dig_in);
-
- ca0132_set_ct_ext(codec, 1);
-
- return 0;
-}
-
-
-static void ca0132_free(struct hda_codec *codec)
-{
- ca0132_set_ct_ext(codec, 0);
- ca0132_exit_chip(codec);
- kfree(codec->spec);
-}
-
-static struct hda_codec_ops ca0132_patch_ops = {
- .build_controls = ca0132_build_controls,
- .build_pcms = ca0132_build_pcms,
- .init = ca0132_init,
- .free = ca0132_free,
-};
-
-
-
-static int patch_ca0132(struct hda_codec *codec)
-{
- struct ca0132_spec *spec;
-
- snd_printdd("patch_ca0132\n");
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- codec->spec = spec;
-
- ca0132_init_chip(codec);
-
- ca0132_config(codec);
-
- codec->patch_ops = ca0132_patch_ops;
-
- return 0;
-}
-
-/*
- * patch entries
- */
-static struct hda_codec_preset snd_hda_preset_ca0132[] = {
- { .id = 0x11020011, .name = "CA0132", .patch = patch_ca0132 },
- {} /* terminator */
-};
-
-MODULE_ALIAS("snd-hda-codec-id:11020011");
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Creative CA0132, CA0132 HD-audio codec");
-
-static struct hda_codec_preset_list ca0132_list = {
- .preset = snd_hda_preset_ca0132,
- .owner = THIS_MODULE,
-};
-
-static int __init patch_ca0132_init(void)
-{
- return snd_hda_add_codec_preset(&ca0132_list);
-}
-
-static void __exit patch_ca0132_exit(void)
-{
- snd_hda_delete_codec_preset(&ca0132_list);
-}
-
-module_init(patch_ca0132_init)
-module_exit(patch_ca0132_exit)
diff --git a/ANDROID_3.4.5/sound/pci/hda/patch_cirrus.c b/ANDROID_3.4.5/sound/pci/hda/patch_cirrus.c
deleted file mode 100644
index c83ccdba..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/patch_cirrus.c
+++ /dev/null
@@ -1,2053 +0,0 @@
-/*
- * HD audio interface patch for Cirrus Logic CS420x chip
- *
- * Copyright (c) 2009 Takashi Iwai <tiwai@suse.de>
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include "hda_codec.h"
-#include "hda_local.h"
-#include "hda_jack.h"
-#include <sound/tlv.h>
-
-/*
- */
-
-struct cs_spec {
- int board_config;
- struct auto_pin_cfg autocfg;
- struct hda_multi_out multiout;
- struct snd_kcontrol *vmaster_sw;
- struct snd_kcontrol *vmaster_vol;
-
- hda_nid_t dac_nid[AUTO_CFG_MAX_OUTS];
- hda_nid_t slave_dig_outs[2];
-
- unsigned int input_idx[AUTO_PIN_LAST];
- unsigned int capsrc_idx[AUTO_PIN_LAST];
- hda_nid_t adc_nid[AUTO_PIN_LAST];
- unsigned int adc_idx[AUTO_PIN_LAST];
- unsigned int num_inputs;
- unsigned int cur_input;
- unsigned int automic_idx;
- hda_nid_t cur_adc;
- unsigned int cur_adc_stream_tag;
- unsigned int cur_adc_format;
- hda_nid_t dig_in;
-
- const struct hda_bind_ctls *capture_bind[2];
-
- unsigned int gpio_mask;
- unsigned int gpio_dir;
- unsigned int gpio_data;
- unsigned int gpio_eapd_hp; /* EAPD GPIO bit for headphones */
- unsigned int gpio_eapd_speaker; /* EAPD GPIO bit for speakers */
-
- struct hda_pcm pcm_rec[2]; /* PCM information */
-
- unsigned int hp_detect:1;
- unsigned int mic_detect:1;
- /* CS421x */
- unsigned int spdif_detect:1;
- unsigned int sense_b:1;
- hda_nid_t vendor_nid;
- struct hda_input_mux input_mux;
- unsigned int last_input;
-};
-
-/* available models with CS420x */
-enum {
- CS420X_MBP53,
- CS420X_MBP55,
- CS420X_IMAC27,
- CS420X_IMAC27_122,
- CS420X_APPLE,
- CS420X_AUTO,
- CS420X_MODELS
-};
-
-/* CS421x boards */
-enum {
- CS421X_CDB4210,
- CS421X_MODELS
-};
-
-/* Vendor-specific processing widget */
-#define CS420X_VENDOR_NID 0x11
-#define CS_DIG_OUT1_PIN_NID 0x10
-#define CS_DIG_OUT2_PIN_NID 0x15
-#define CS_DMIC1_PIN_NID 0x12
-#define CS_DMIC2_PIN_NID 0x0e
-
-/* coef indices */
-#define IDX_SPDIF_STAT 0x0000
-#define IDX_SPDIF_CTL 0x0001
-#define IDX_ADC_CFG 0x0002
-/* SZC bitmask, 4 modes below:
- * 0 = immediate,
- * 1 = digital immediate, analog zero-cross
- * 2 = digtail & analog soft-ramp
- * 3 = digital soft-ramp, analog zero-cross
- */
-#define CS_COEF_ADC_SZC_MASK (3 << 0)
-#define CS_COEF_ADC_MIC_SZC_MODE (3 << 0) /* SZC setup for mic */
-#define CS_COEF_ADC_LI_SZC_MODE (3 << 0) /* SZC setup for line-in */
-/* PGA mode: 0 = differential, 1 = signle-ended */
-#define CS_COEF_ADC_MIC_PGA_MODE (1 << 5) /* PGA setup for mic */
-#define CS_COEF_ADC_LI_PGA_MODE (1 << 6) /* PGA setup for line-in */
-#define IDX_DAC_CFG 0x0003
-/* SZC bitmask, 4 modes below:
- * 0 = Immediate
- * 1 = zero-cross
- * 2 = soft-ramp
- * 3 = soft-ramp on zero-cross
- */
-#define CS_COEF_DAC_HP_SZC_MODE (3 << 0) /* nid 0x02 */
-#define CS_COEF_DAC_LO_SZC_MODE (3 << 2) /* nid 0x03 */
-#define CS_COEF_DAC_SPK_SZC_MODE (3 << 4) /* nid 0x04 */
-
-#define IDX_BEEP_CFG 0x0004
-/* 0x0008 - test reg key */
-/* 0x0009 - 0x0014 -> 12 test regs */
-/* 0x0015 - visibility reg */
-
-/*
- * Cirrus Logic CS4210
- *
- * 1 DAC => HP(sense) / Speakers,
- * 1 ADC <= LineIn(sense) / MicIn / DMicIn,
- * 1 SPDIF OUT => SPDIF Trasmitter(sense)
-*/
-#define CS4210_DAC_NID 0x02
-#define CS4210_ADC_NID 0x03
-#define CS4210_VENDOR_NID 0x0B
-#define CS421X_DMIC_PIN_NID 0x09 /* Port E */
-#define CS421X_SPDIF_PIN_NID 0x0A /* Port H */
-
-#define CS421X_IDX_DEV_CFG 0x01
-#define CS421X_IDX_ADC_CFG 0x02
-#define CS421X_IDX_DAC_CFG 0x03
-#define CS421X_IDX_SPK_CTL 0x04
-
-#define SPDIF_EVENT 0x04
-
-/* Cirrus Logic CS4213 is like CS4210 but does not have SPDIF input/output */
-#define CS4213_VENDOR_NID 0x09
-
-
-static inline int cs_vendor_coef_get(struct hda_codec *codec, unsigned int idx)
-{
- struct cs_spec *spec = codec->spec;
- snd_hda_codec_write(codec, spec->vendor_nid, 0,
- AC_VERB_SET_COEF_INDEX, idx);
- return snd_hda_codec_read(codec, spec->vendor_nid, 0,
- AC_VERB_GET_PROC_COEF, 0);
-}
-
-static inline void cs_vendor_coef_set(struct hda_codec *codec, unsigned int idx,
- unsigned int coef)
-{
- struct cs_spec *spec = codec->spec;
- snd_hda_codec_write(codec, spec->vendor_nid, 0,
- AC_VERB_SET_COEF_INDEX, idx);
- snd_hda_codec_write(codec, spec->vendor_nid, 0,
- AC_VERB_SET_PROC_COEF, coef);
-}
-
-
-#define HP_EVENT 1
-#define MIC_EVENT 2
-
-/*
- * PCM callbacks
- */
-static int cs_playback_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct cs_spec *spec = codec->spec;
- return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
- hinfo);
-}
-
-static int cs_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct cs_spec *spec = codec->spec;
- return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
- stream_tag, format, substream);
-}
-
-static int cs_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct cs_spec *spec = codec->spec;
- return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
-}
-
-/*
- * Digital out
- */
-static int cs_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct cs_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_open(codec, &spec->multiout);
-}
-
-static int cs_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct cs_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_close(codec, &spec->multiout);
-}
-
-static int cs_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct cs_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
- format, substream);
-}
-
-static int cs_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct cs_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
-}
-
-static void cs_update_input_select(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- if (spec->cur_adc)
- snd_hda_codec_write(codec, spec->cur_adc, 0,
- AC_VERB_SET_CONNECT_SEL,
- spec->adc_idx[spec->cur_input]);
-}
-
-/*
- * Analog capture
- */
-static int cs_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct cs_spec *spec = codec->spec;
- spec->cur_adc = spec->adc_nid[spec->cur_input];
- spec->cur_adc_stream_tag = stream_tag;
- spec->cur_adc_format = format;
- cs_update_input_select(codec);
- snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
- return 0;
-}
-
-static int cs_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct cs_spec *spec = codec->spec;
- snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
- spec->cur_adc = 0;
- return 0;
-}
-
-/*
- */
-static const struct hda_pcm_stream cs_pcm_analog_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .ops = {
- .open = cs_playback_pcm_open,
- .prepare = cs_playback_pcm_prepare,
- .cleanup = cs_playback_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream cs_pcm_analog_capture = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .ops = {
- .prepare = cs_capture_pcm_prepare,
- .cleanup = cs_capture_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream cs_pcm_digital_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .ops = {
- .open = cs_dig_playback_pcm_open,
- .close = cs_dig_playback_pcm_close,
- .prepare = cs_dig_playback_pcm_prepare,
- .cleanup = cs_dig_playback_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream cs_pcm_digital_capture = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
-};
-
-static int cs_build_pcms(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- struct hda_pcm *info = spec->pcm_rec;
-
- codec->pcm_info = info;
- codec->num_pcms = 0;
-
- info->name = "Cirrus Analog";
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] = cs_pcm_analog_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dac_nid[0];
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
- spec->multiout.max_channels;
- info->stream[SNDRV_PCM_STREAM_CAPTURE] = cs_pcm_analog_capture;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
- spec->adc_nid[spec->cur_input];
- codec->num_pcms++;
-
- if (!spec->multiout.dig_out_nid && !spec->dig_in)
- return 0;
-
- info++;
- info->name = "Cirrus Digital";
- info->pcm_type = spec->autocfg.dig_out_type[0];
- if (!info->pcm_type)
- info->pcm_type = HDA_PCM_TYPE_SPDIF;
- if (spec->multiout.dig_out_nid) {
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
- cs_pcm_digital_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
- spec->multiout.dig_out_nid;
- }
- if (spec->dig_in) {
- info->stream[SNDRV_PCM_STREAM_CAPTURE] =
- cs_pcm_digital_capture;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in;
- }
- codec->num_pcms++;
-
- return 0;
-}
-
-/*
- * parse codec topology
- */
-
-static hda_nid_t get_dac(struct hda_codec *codec, hda_nid_t pin)
-{
- hda_nid_t dac;
- if (!pin)
- return 0;
- if (snd_hda_get_connections(codec, pin, &dac, 1) != 1)
- return 0;
- return dac;
-}
-
-static int is_ext_mic(struct hda_codec *codec, unsigned int idx)
-{
- struct cs_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- hda_nid_t pin = cfg->inputs[idx].pin;
- unsigned int val;
- if (!is_jack_detectable(codec, pin))
- return 0;
- val = snd_hda_codec_get_pincfg(codec, pin);
- return (snd_hda_get_input_pin_attr(val) != INPUT_PIN_ATTR_INT);
-}
-
-static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin,
- unsigned int *idxp)
-{
- int i, idx;
- hda_nid_t nid;
-
- nid = codec->start_nid;
- for (i = 0; i < codec->num_nodes; i++, nid++) {
- unsigned int type;
- type = get_wcaps_type(get_wcaps(codec, nid));
- if (type != AC_WID_AUD_IN)
- continue;
- idx = snd_hda_get_conn_index(codec, nid, pin, false);
- if (idx >= 0) {
- *idxp = idx;
- return nid;
- }
- }
- return 0;
-}
-
-static int is_active_pin(struct hda_codec *codec, hda_nid_t nid)
-{
- unsigned int val;
- val = snd_hda_codec_get_pincfg(codec, nid);
- return (get_defcfg_connect(val) != AC_JACK_PORT_NONE);
-}
-
-static int parse_output(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i, extra_nids;
- hda_nid_t dac;
-
- for (i = 0; i < cfg->line_outs; i++) {
- dac = get_dac(codec, cfg->line_out_pins[i]);
- if (!dac)
- break;
- spec->dac_nid[i] = dac;
- }
- spec->multiout.num_dacs = i;
- spec->multiout.dac_nids = spec->dac_nid;
- spec->multiout.max_channels = i * 2;
-
- /* add HP and speakers */
- extra_nids = 0;
- for (i = 0; i < cfg->hp_outs; i++) {
- dac = get_dac(codec, cfg->hp_pins[i]);
- if (!dac)
- break;
- if (!i)
- spec->multiout.hp_nid = dac;
- else
- spec->multiout.extra_out_nid[extra_nids++] = dac;
- }
- for (i = 0; i < cfg->speaker_outs; i++) {
- dac = get_dac(codec, cfg->speaker_pins[i]);
- if (!dac)
- break;
- spec->multiout.extra_out_nid[extra_nids++] = dac;
- }
-
- if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
- cfg->speaker_outs = cfg->line_outs;
- memcpy(cfg->speaker_pins, cfg->line_out_pins,
- sizeof(cfg->speaker_pins));
- cfg->line_outs = 0;
- }
-
- return 0;
-}
-
-static int parse_input(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i;
-
- for (i = 0; i < cfg->num_inputs; i++) {
- hda_nid_t pin = cfg->inputs[i].pin;
- spec->input_idx[spec->num_inputs] = i;
- spec->capsrc_idx[i] = spec->num_inputs++;
- spec->cur_input = i;
- spec->adc_nid[i] = get_adc(codec, pin, &spec->adc_idx[i]);
- }
- if (!spec->num_inputs)
- return 0;
-
- /* check whether the automatic mic switch is available */
- if (spec->num_inputs == 2 &&
- cfg->inputs[0].type == AUTO_PIN_MIC &&
- cfg->inputs[1].type == AUTO_PIN_MIC) {
- if (is_ext_mic(codec, cfg->inputs[0].pin)) {
- if (!is_ext_mic(codec, cfg->inputs[1].pin)) {
- spec->mic_detect = 1;
- spec->automic_idx = 0;
- }
- } else {
- if (is_ext_mic(codec, cfg->inputs[1].pin)) {
- spec->mic_detect = 1;
- spec->automic_idx = 1;
- }
- }
- }
- return 0;
-}
-
-
-static int parse_digital_output(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- hda_nid_t nid;
-
- if (!cfg->dig_outs)
- return 0;
- if (snd_hda_get_connections(codec, cfg->dig_out_pins[0], &nid, 1) < 1)
- return 0;
- spec->multiout.dig_out_nid = nid;
- spec->multiout.share_spdif = 1;
- if (cfg->dig_outs > 1 &&
- snd_hda_get_connections(codec, cfg->dig_out_pins[1], &nid, 1) > 0) {
- spec->slave_dig_outs[0] = nid;
- codec->slave_dig_outs = spec->slave_dig_outs;
- }
- return 0;
-}
-
-static int parse_digital_input(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int idx;
-
- if (cfg->dig_in_pin)
- spec->dig_in = get_adc(codec, cfg->dig_in_pin, &idx);
- return 0;
-}
-
-/*
- * create mixer controls
- */
-
-static const char * const dir_sfx[2] = { "Playback", "Capture" };
-
-static int add_mute(struct hda_codec *codec, const char *name, int index,
- unsigned int pval, int dir, struct snd_kcontrol **kctlp)
-{
- char tmp[44];
- struct snd_kcontrol_new knew =
- HDA_CODEC_MUTE_IDX(tmp, index, 0, 0, HDA_OUTPUT);
- knew.private_value = pval;
- snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]);
- *kctlp = snd_ctl_new1(&knew, codec);
- (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG;
- return snd_hda_ctl_add(codec, 0, *kctlp);
-}
-
-static int add_volume(struct hda_codec *codec, const char *name,
- int index, unsigned int pval, int dir,
- struct snd_kcontrol **kctlp)
-{
- char tmp[44];
- struct snd_kcontrol_new knew =
- HDA_CODEC_VOLUME_IDX(tmp, index, 0, 0, HDA_OUTPUT);
- knew.private_value = pval;
- snprintf(tmp, sizeof(tmp), "%s %s Volume", name, dir_sfx[dir]);
- *kctlp = snd_ctl_new1(&knew, codec);
- (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG;
- return snd_hda_ctl_add(codec, 0, *kctlp);
-}
-
-static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac)
-{
- unsigned int caps;
-
- /* set the upper-limit for mixer amp to 0dB */
- caps = query_amp_caps(codec, dac, HDA_OUTPUT);
- caps &= ~(0x7f << AC_AMPCAP_NUM_STEPS_SHIFT);
- caps |= ((caps >> AC_AMPCAP_OFFSET_SHIFT) & 0x7f)
- << AC_AMPCAP_NUM_STEPS_SHIFT;
- snd_hda_override_amp_caps(codec, dac, HDA_OUTPUT, caps);
-}
-
-static int add_vmaster(struct hda_codec *codec, hda_nid_t dac)
-{
- struct cs_spec *spec = codec->spec;
- unsigned int tlv[4];
- int err;
-
- spec->vmaster_sw =
- snd_ctl_make_virtual_master("Master Playback Switch", NULL);
- err = snd_hda_ctl_add(codec, dac, spec->vmaster_sw);
- if (err < 0)
- return err;
-
- snd_hda_set_vmaster_tlv(codec, dac, HDA_OUTPUT, tlv);
- spec->vmaster_vol =
- snd_ctl_make_virtual_master("Master Playback Volume", tlv);
- err = snd_hda_ctl_add(codec, dac, spec->vmaster_vol);
- if (err < 0)
- return err;
- return 0;
-}
-
-static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx,
- int num_ctls, int type)
-{
- struct cs_spec *spec = codec->spec;
- const char *name;
- int err, index;
- struct snd_kcontrol *kctl;
- static const char * const speakers[] = {
- "Front Speaker", "Surround Speaker", "Bass Speaker"
- };
- static const char * const line_outs[] = {
- "Front Line Out", "Surround Line Out", "Bass Line Out"
- };
-
- fix_volume_caps(codec, dac);
- if (!spec->vmaster_sw) {
- err = add_vmaster(codec, dac);
- if (err < 0)
- return err;
- }
-
- index = 0;
- switch (type) {
- case AUTO_PIN_HP_OUT:
- name = "Headphone";
- index = idx;
- break;
- case AUTO_PIN_SPEAKER_OUT:
- if (num_ctls > 1)
- name = speakers[idx];
- else
- name = "Speaker";
- break;
- default:
- if (num_ctls > 1)
- name = line_outs[idx];
- else
- name = "Line Out";
- break;
- }
-
- err = add_mute(codec, name, index,
- HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl);
- if (err < 0)
- return err;
- err = snd_ctl_add_slave(spec->vmaster_sw, kctl);
- if (err < 0)
- return err;
-
- err = add_volume(codec, name, index,
- HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl);
- if (err < 0)
- return err;
- err = snd_ctl_add_slave(spec->vmaster_vol, kctl);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static int build_output(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i, err;
-
- for (i = 0; i < cfg->line_outs; i++) {
- err = add_output(codec, get_dac(codec, cfg->line_out_pins[i]),
- i, cfg->line_outs, cfg->line_out_type);
- if (err < 0)
- return err;
- }
- for (i = 0; i < cfg->hp_outs; i++) {
- err = add_output(codec, get_dac(codec, cfg->hp_pins[i]),
- i, cfg->hp_outs, AUTO_PIN_HP_OUT);
- if (err < 0)
- return err;
- }
- for (i = 0; i < cfg->speaker_outs; i++) {
- err = add_output(codec, get_dac(codec, cfg->speaker_pins[i]),
- i, cfg->speaker_outs, AUTO_PIN_SPEAKER_OUT);
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-/*
- */
-
-static const struct snd_kcontrol_new cs_capture_ctls[] = {
- HDA_BIND_SW("Capture Switch", 0),
- HDA_BIND_VOL("Capture Volume", 0),
-};
-
-static int change_cur_input(struct hda_codec *codec, unsigned int idx,
- int force)
-{
- struct cs_spec *spec = codec->spec;
-
- if (spec->cur_input == idx && !force)
- return 0;
- if (spec->cur_adc && spec->cur_adc != spec->adc_nid[idx]) {
- /* stream is running, let's swap the current ADC */
- __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
- spec->cur_adc = spec->adc_nid[idx];
- snd_hda_codec_setup_stream(codec, spec->cur_adc,
- spec->cur_adc_stream_tag, 0,
- spec->cur_adc_format);
- }
- spec->cur_input = idx;
- cs_update_input_select(codec);
- return 1;
-}
-
-static int cs_capture_source_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct cs_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- unsigned int idx;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = spec->num_inputs;
- if (uinfo->value.enumerated.item >= spec->num_inputs)
- uinfo->value.enumerated.item = spec->num_inputs - 1;
- idx = spec->input_idx[uinfo->value.enumerated.item];
- snd_hda_get_pin_label(codec, cfg->inputs[idx].pin, cfg,
- uinfo->value.enumerated.name,
- sizeof(uinfo->value.enumerated.name), NULL);
- return 0;
-}
-
-static int cs_capture_source_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct cs_spec *spec = codec->spec;
- ucontrol->value.enumerated.item[0] = spec->capsrc_idx[spec->cur_input];
- return 0;
-}
-
-static int cs_capture_source_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct cs_spec *spec = codec->spec;
- unsigned int idx = ucontrol->value.enumerated.item[0];
-
- if (idx >= spec->num_inputs)
- return -EINVAL;
- idx = spec->input_idx[idx];
- return change_cur_input(codec, idx, 0);
-}
-
-static const struct snd_kcontrol_new cs_capture_source = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = cs_capture_source_info,
- .get = cs_capture_source_get,
- .put = cs_capture_source_put,
-};
-
-static const struct hda_bind_ctls *make_bind_capture(struct hda_codec *codec,
- struct hda_ctl_ops *ops)
-{
- struct cs_spec *spec = codec->spec;
- struct hda_bind_ctls *bind;
- int i, n;
-
- bind = kzalloc(sizeof(*bind) + sizeof(long) * (spec->num_inputs + 1),
- GFP_KERNEL);
- if (!bind)
- return NULL;
- bind->ops = ops;
- n = 0;
- for (i = 0; i < AUTO_PIN_LAST; i++) {
- if (!spec->adc_nid[i])
- continue;
- bind->values[n++] =
- HDA_COMPOSE_AMP_VAL(spec->adc_nid[i], 3,
- spec->adc_idx[i], HDA_INPUT);
- }
- return bind;
-}
-
-/* add a (input-boost) volume control to the given input pin */
-static int add_input_volume_control(struct hda_codec *codec,
- struct auto_pin_cfg *cfg,
- int item)
-{
- hda_nid_t pin = cfg->inputs[item].pin;
- u32 caps;
- const char *label;
- struct snd_kcontrol *kctl;
-
- if (!(get_wcaps(codec, pin) & AC_WCAP_IN_AMP))
- return 0;
- caps = query_amp_caps(codec, pin, HDA_INPUT);
- caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
- if (caps <= 1)
- return 0;
- label = hda_get_autocfg_input_label(codec, cfg, item);
- return add_volume(codec, label, 0,
- HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT), 1, &kctl);
-}
-
-static int build_input(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- int i, err;
-
- if (!spec->num_inputs)
- return 0;
-
- /* make bind-capture */
- spec->capture_bind[0] = make_bind_capture(codec, &snd_hda_bind_sw);
- spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol);
- for (i = 0; i < 2; i++) {
- struct snd_kcontrol *kctl;
- int n;
- if (!spec->capture_bind[i])
- return -ENOMEM;
- kctl = snd_ctl_new1(&cs_capture_ctls[i], codec);
- if (!kctl)
- return -ENOMEM;
- kctl->private_value = (long)spec->capture_bind[i];
- err = snd_hda_ctl_add(codec, 0, kctl);
- if (err < 0)
- return err;
- for (n = 0; n < AUTO_PIN_LAST; n++) {
- if (!spec->adc_nid[n])
- continue;
- err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[n]);
- if (err < 0)
- return err;
- }
- }
-
- if (spec->num_inputs > 1 && !spec->mic_detect) {
- err = snd_hda_ctl_add(codec, 0,
- snd_ctl_new1(&cs_capture_source, codec));
- if (err < 0)
- return err;
- }
-
- for (i = 0; i < spec->num_inputs; i++) {
- err = add_input_volume_control(codec, &spec->autocfg, i);
- if (err < 0)
- return err;
- }
-
- return 0;
-}
-
-/*
- */
-
-static int build_digital_output(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- int err;
-
- if (!spec->multiout.dig_out_nid)
- return 0;
-
- err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid,
- spec->multiout.dig_out_nid);
- if (err < 0)
- return err;
- err = snd_hda_create_spdif_share_sw(codec, &spec->multiout);
- if (err < 0)
- return err;
- return 0;
-}
-
-static int build_digital_input(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- if (spec->dig_in)
- return snd_hda_create_spdif_in_ctls(codec, spec->dig_in);
- return 0;
-}
-
-/*
- * auto-mute and auto-mic switching
- * CS421x auto-output redirecting
- * HP/SPK/SPDIF
- */
-
-static void cs_automute(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- unsigned int hp_present;
- unsigned int spdif_present;
- hda_nid_t nid;
- int i;
-
- spdif_present = 0;
- if (cfg->dig_outs) {
- nid = cfg->dig_out_pins[0];
- if (is_jack_detectable(codec, nid)) {
- /*
- TODO: SPDIF output redirect when SENSE_B is enabled.
- Shared (SENSE_A) jack (e.g HP/mini-TOSLINK)
- assumed.
- */
- if (snd_hda_jack_detect(codec, nid)
- /* && spec->sense_b */)
- spdif_present = 1;
- }
- }
-
- hp_present = 0;
- for (i = 0; i < cfg->hp_outs; i++) {
- nid = cfg->hp_pins[i];
- if (!is_jack_detectable(codec, nid))
- continue;
- hp_present = snd_hda_jack_detect(codec, nid);
- if (hp_present)
- break;
- }
-
- /* mute speakers if spdif or hp jack is plugged in */
- for (i = 0; i < cfg->speaker_outs; i++) {
- int pin_ctl = hp_present ? 0 : PIN_OUT;
- /* detect on spdif is specific to CS4210 */
- if (spdif_present && (spec->vendor_nid == CS4210_VENDOR_NID))
- pin_ctl = 0;
-
- nid = cfg->speaker_pins[i];
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, pin_ctl);
- }
- if (spec->gpio_eapd_hp) {
- unsigned int gpio = hp_present ?
- spec->gpio_eapd_hp : spec->gpio_eapd_speaker;
- snd_hda_codec_write(codec, 0x01, 0,
- AC_VERB_SET_GPIO_DATA, gpio);
- }
-
- /* specific to CS4210 */
- if (spec->vendor_nid == CS4210_VENDOR_NID) {
- /* mute HPs if spdif jack (SENSE_B) is present */
- for (i = 0; i < cfg->hp_outs; i++) {
- nid = cfg->hp_pins[i];
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- (spdif_present && spec->sense_b) ? 0 : PIN_HP);
- }
-
- /* SPDIF TX on/off */
- if (cfg->dig_outs) {
- nid = cfg->dig_out_pins[0];
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- spdif_present ? PIN_OUT : 0);
-
- }
- /* Update board GPIOs if neccessary ... */
- }
-}
-
-/*
- * Auto-input redirect for CS421x
- * Switch max 3 inputs of a single ADC (nid 3)
-*/
-
-static void cs_automic(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- hda_nid_t nid;
- unsigned int present;
-
- nid = cfg->inputs[spec->automic_idx].pin;
- present = snd_hda_jack_detect(codec, nid);
-
- /* specific to CS421x, single ADC */
- if (spec->vendor_nid == CS420X_VENDOR_NID) {
- if (present)
- change_cur_input(codec, spec->automic_idx, 0);
- else
- change_cur_input(codec, !spec->automic_idx, 0);
- } else {
- if (present) {
- if (spec->cur_input != spec->automic_idx) {
- spec->last_input = spec->cur_input;
- spec->cur_input = spec->automic_idx;
- }
- } else {
- spec->cur_input = spec->last_input;
- }
- cs_update_input_select(codec);
- }
-}
-
-/*
- */
-
-static void init_output(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i;
-
- /* mute first */
- for (i = 0; i < spec->multiout.num_dacs; i++)
- snd_hda_codec_write(codec, spec->multiout.dac_nids[i], 0,
- AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
- if (spec->multiout.hp_nid)
- snd_hda_codec_write(codec, spec->multiout.hp_nid, 0,
- AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
- for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) {
- if (!spec->multiout.extra_out_nid[i])
- break;
- snd_hda_codec_write(codec, spec->multiout.extra_out_nid[i], 0,
- AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
- }
-
- /* set appropriate pin controls */
- for (i = 0; i < cfg->line_outs; i++)
- snd_hda_codec_write(codec, cfg->line_out_pins[i], 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
- /* HP */
- for (i = 0; i < cfg->hp_outs; i++) {
- hda_nid_t nid = cfg->hp_pins[i];
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
- if (!cfg->speaker_outs)
- continue;
- if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
- snd_hda_jack_detect_enable(codec, nid, HP_EVENT);
- spec->hp_detect = 1;
- }
- }
-
- /* Speaker */
- for (i = 0; i < cfg->speaker_outs; i++)
- snd_hda_codec_write(codec, cfg->speaker_pins[i], 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
-
- /* SPDIF is enabled on presence detect for CS421x */
- if (spec->hp_detect || spec->spdif_detect)
- cs_automute(codec);
-}
-
-static void init_input(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- unsigned int coef;
- int i;
-
- for (i = 0; i < cfg->num_inputs; i++) {
- unsigned int ctl;
- hda_nid_t pin = cfg->inputs[i].pin;
- if (!spec->adc_nid[i])
- continue;
- /* set appropriate pin control and mute first */
- ctl = PIN_IN;
- if (cfg->inputs[i].type == AUTO_PIN_MIC) {
- unsigned int caps = snd_hda_query_pin_caps(codec, pin);
- caps >>= AC_PINCAP_VREF_SHIFT;
- if (caps & AC_PINCAP_VREF_80)
- ctl = PIN_VREF80;
- }
- snd_hda_codec_write(codec, pin, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
- snd_hda_codec_write(codec, spec->adc_nid[i], 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_IN_MUTE(spec->adc_idx[i]));
- if (spec->mic_detect && spec->automic_idx == i)
- snd_hda_jack_detect_enable(codec, pin, MIC_EVENT);
- }
- /* CS420x has multiple ADC, CS421x has single ADC */
- if (spec->vendor_nid == CS420X_VENDOR_NID) {
- change_cur_input(codec, spec->cur_input, 1);
- if (spec->mic_detect)
- cs_automic(codec);
-
- coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */
- if (is_active_pin(codec, CS_DMIC2_PIN_NID))
- coef |= 0x0500; /* DMIC2 2 chan on, GPIO1 off */
- if (is_active_pin(codec, CS_DMIC1_PIN_NID))
- coef |= 0x1800; /* DMIC1 2 chan on, GPIO0 off
- * No effect if SPDIF_OUT2 is
- * selected in IDX_SPDIF_CTL.
- */
- cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
- } else {
- if (spec->mic_detect)
- cs_automic(codec);
- else {
- spec->cur_adc = spec->adc_nid[spec->cur_input];
- cs_update_input_select(codec);
- }
- }
-}
-
-static const struct hda_verb cs_coef_init_verbs[] = {
- {0x11, AC_VERB_SET_PROC_STATE, 1},
- {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG},
- {0x11, AC_VERB_SET_PROC_COEF,
- (0x002a /* DAC1/2/3 SZCMode Soft Ramp */
- | 0x0040 /* Mute DACs on FIFO error */
- | 0x1000 /* Enable DACs High Pass Filter */
- | 0x0400 /* Disable Coefficient Auto increment */
- )},
- /* Beep */
- {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG},
- {0x11, AC_VERB_SET_PROC_COEF, 0x0007}, /* Enable Beep thru DAC1/2/3 */
-
- {} /* terminator */
-};
-
-/* Errata: CS4207 rev C0/C1/C2 Silicon
- *
- * http://www.cirrus.com/en/pubs/errata/ER880C3.pdf
- *
- * 6. At high temperature (TA > +85°C), the digital supply current (IVD)
- * may be excessive (up to an additional 200 μA), which is most easily
- * observed while the part is being held in reset (RESET# active low).
- *
- * Root Cause: At initial powerup of the device, the logic that drives
- * the clock and write enable to the S/PDIF SRC RAMs is not properly
- * initialized.
- * Certain random patterns will cause a steady leakage current in those
- * RAM cells. The issue will resolve once the SRCs are used (turned on).
- *
- * Workaround: The following verb sequence briefly turns on the S/PDIF SRC
- * blocks, which will alleviate the issue.
- */
-
-static const struct hda_verb cs_errata_init_verbs[] = {
- {0x01, AC_VERB_SET_POWER_STATE, 0x00}, /* AFG: D0 */
- {0x11, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */
-
- {0x11, AC_VERB_SET_COEF_INDEX, 0x0008},
- {0x11, AC_VERB_SET_PROC_COEF, 0x9999},
- {0x11, AC_VERB_SET_COEF_INDEX, 0x0017},
- {0x11, AC_VERB_SET_PROC_COEF, 0xa412},
- {0x11, AC_VERB_SET_COEF_INDEX, 0x0001},
- {0x11, AC_VERB_SET_PROC_COEF, 0x0009},
-
- {0x07, AC_VERB_SET_POWER_STATE, 0x00}, /* S/PDIF Rx: D0 */
- {0x08, AC_VERB_SET_POWER_STATE, 0x00}, /* S/PDIF Tx: D0 */
-
- {0x11, AC_VERB_SET_COEF_INDEX, 0x0017},
- {0x11, AC_VERB_SET_PROC_COEF, 0x2412},
- {0x11, AC_VERB_SET_COEF_INDEX, 0x0008},
- {0x11, AC_VERB_SET_PROC_COEF, 0x0000},
- {0x11, AC_VERB_SET_COEF_INDEX, 0x0001},
- {0x11, AC_VERB_SET_PROC_COEF, 0x0008},
- {0x11, AC_VERB_SET_PROC_STATE, 0x00},
-
-#if 0 /* Don't to set to D3 as we are in power-up sequence */
- {0x07, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Rx: D3 */
- {0x08, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Tx: D3 */
- /*{0x01, AC_VERB_SET_POWER_STATE, 0x03},*/ /* AFG: D3 This is already handled */
-#endif
-
- {} /* terminator */
-};
-
-/* SPDIF setup */
-static void init_digital(struct hda_codec *codec)
-{
- unsigned int coef;
-
- coef = 0x0002; /* SRC_MUTE soft-mute on SPDIF (if no lock) */
- coef |= 0x0008; /* Replace with mute on error */
- if (is_active_pin(codec, CS_DIG_OUT2_PIN_NID))
- coef |= 0x4000; /* RX to TX1 or TX2 Loopthru / SPDIF2
- * SPDIF_OUT2 is shared with GPIO1 and
- * DMIC_SDA2.
- */
- cs_vendor_coef_set(codec, IDX_SPDIF_CTL, coef);
-}
-
-static int cs_init(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
-
- /* init_verb sequence for C0/C1/C2 errata*/
- snd_hda_sequence_write(codec, cs_errata_init_verbs);
-
- snd_hda_sequence_write(codec, cs_coef_init_verbs);
-
- if (spec->gpio_mask) {
- snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK,
- spec->gpio_mask);
- snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION,
- spec->gpio_dir);
- snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
- spec->gpio_data);
- }
-
- init_output(codec);
- init_input(codec);
- init_digital(codec);
- snd_hda_jack_report_sync(codec);
-
- return 0;
-}
-
-static int cs_build_controls(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- int err;
-
- err = build_output(codec);
- if (err < 0)
- return err;
- err = build_input(codec);
- if (err < 0)
- return err;
- err = build_digital_output(codec);
- if (err < 0)
- return err;
- err = build_digital_input(codec);
- if (err < 0)
- return err;
- err = cs_init(codec);
- if (err < 0)
- return err;
-
- err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static void cs_free(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- kfree(spec->capture_bind[0]);
- kfree(spec->capture_bind[1]);
- kfree(codec->spec);
-}
-
-static void cs_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- switch (snd_hda_jack_get_action(codec, res >> 26)) {
- case HP_EVENT:
- cs_automute(codec);
- break;
- case MIC_EVENT:
- cs_automic(codec);
- break;
- }
- snd_hda_jack_report_sync(codec);
-}
-
-static const struct hda_codec_ops cs_patch_ops = {
- .build_controls = cs_build_controls,
- .build_pcms = cs_build_pcms,
- .init = cs_init,
- .free = cs_free,
- .unsol_event = cs_unsol_event,
-};
-
-static int cs_parse_auto_config(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- int err;
-
- err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
- if (err < 0)
- return err;
-
- err = parse_output(codec);
- if (err < 0)
- return err;
- err = parse_input(codec);
- if (err < 0)
- return err;
- err = parse_digital_output(codec);
- if (err < 0)
- return err;
- err = parse_digital_input(codec);
- if (err < 0)
- return err;
- return 0;
-}
-
-static const char * const cs420x_models[CS420X_MODELS] = {
- [CS420X_MBP53] = "mbp53",
- [CS420X_MBP55] = "mbp55",
- [CS420X_IMAC27] = "imac27",
- [CS420X_IMAC27_122] = "imac27_122",
- [CS420X_APPLE] = "apple",
- [CS420X_AUTO] = "auto",
-};
-
-
-static const struct snd_pci_quirk cs420x_cfg_tbl[] = {
- SND_PCI_QUIRK(0x10de, 0x0ac0, "MacBookPro 5,3", CS420X_MBP53),
- SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55),
- SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55),
- SND_PCI_QUIRK(0x10de, 0xcb89, "MacBookPro 7,1", CS420X_MBP55),
- /* this conflicts with too many other models */
- /*SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),*/
- {} /* terminator */
-};
-
-static const struct snd_pci_quirk cs420x_codec_cfg_tbl[] = {
- SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122),
- SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE),
- {} /* terminator */
-};
-
-struct cs_pincfg {
- hda_nid_t nid;
- u32 val;
-};
-
-static const struct cs_pincfg mbp53_pincfgs[] = {
- { 0x09, 0x012b4050 },
- { 0x0a, 0x90100141 },
- { 0x0b, 0x90100140 },
- { 0x0c, 0x018b3020 },
- { 0x0d, 0x90a00110 },
- { 0x0e, 0x400000f0 },
- { 0x0f, 0x01cbe030 },
- { 0x10, 0x014be060 },
- { 0x12, 0x400000f0 },
- { 0x15, 0x400000f0 },
- {} /* terminator */
-};
-
-static const struct cs_pincfg mbp55_pincfgs[] = {
- { 0x09, 0x012b4030 },
- { 0x0a, 0x90100121 },
- { 0x0b, 0x90100120 },
- { 0x0c, 0x400000f0 },
- { 0x0d, 0x90a00110 },
- { 0x0e, 0x400000f0 },
- { 0x0f, 0x400000f0 },
- { 0x10, 0x014be040 },
- { 0x12, 0x400000f0 },
- { 0x15, 0x400000f0 },
- {} /* terminator */
-};
-
-static const struct cs_pincfg imac27_pincfgs[] = {
- { 0x09, 0x012b4050 },
- { 0x0a, 0x90100140 },
- { 0x0b, 0x90100142 },
- { 0x0c, 0x018b3020 },
- { 0x0d, 0x90a00110 },
- { 0x0e, 0x400000f0 },
- { 0x0f, 0x01cbe030 },
- { 0x10, 0x014be060 },
- { 0x12, 0x01ab9070 },
- { 0x15, 0x400000f0 },
- {} /* terminator */
-};
-
-static const struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = {
- [CS420X_MBP53] = mbp53_pincfgs,
- [CS420X_MBP55] = mbp55_pincfgs,
- [CS420X_IMAC27] = imac27_pincfgs,
-};
-
-static void fix_pincfg(struct hda_codec *codec, int model,
- const struct cs_pincfg **pin_configs)
-{
- const struct cs_pincfg *cfg = pin_configs[model];
- if (!cfg)
- return;
- for (; cfg->nid; cfg++)
- snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
-}
-
-static int patch_cs420x(struct hda_codec *codec)
-{
- struct cs_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- codec->spec = spec;
-
- spec->vendor_nid = CS420X_VENDOR_NID;
-
- spec->board_config =
- snd_hda_check_board_config(codec, CS420X_MODELS,
- cs420x_models, cs420x_cfg_tbl);
- if (spec->board_config < 0)
- spec->board_config =
- snd_hda_check_board_codec_sid_config(codec,
- CS420X_MODELS, NULL, cs420x_codec_cfg_tbl);
- if (spec->board_config >= 0)
- fix_pincfg(codec, spec->board_config, cs_pincfgs);
-
- switch (spec->board_config) {
- case CS420X_IMAC27:
- case CS420X_MBP53:
- case CS420X_MBP55:
- case CS420X_APPLE:
- spec->gpio_eapd_hp = 2; /* GPIO1 = headphones */
- spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */
- spec->gpio_mask = spec->gpio_dir =
- spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
- break;
- case CS420X_IMAC27_122:
- spec->gpio_eapd_hp = 4; /* GPIO2 = headphones */
- spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */
- spec->gpio_mask = spec->gpio_dir =
- spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
- break;
- }
-
- err = cs_parse_auto_config(codec);
- if (err < 0)
- goto error;
-
- codec->patch_ops = cs_patch_ops;
-
- return 0;
-
- error:
- kfree(codec->spec);
- codec->spec = NULL;
- return err;
-}
-
-/*
- * Cirrus Logic CS4210
- *
- * 1 DAC => HP(sense) / Speakers,
- * 1 ADC <= LineIn(sense) / MicIn / DMicIn,
- * 1 SPDIF OUT => SPDIF Trasmitter(sense)
-*/
-
-/* CS4210 board names */
-static const char *cs421x_models[CS421X_MODELS] = {
- [CS421X_CDB4210] = "cdb4210",
-};
-
-static const struct snd_pci_quirk cs421x_cfg_tbl[] = {
- /* Test Intel board + CDB2410 */
- SND_PCI_QUIRK(0x8086, 0x5001, "DP45SG/CDB4210", CS421X_CDB4210),
- {} /* terminator */
-};
-
-/* CS4210 board pinconfigs */
-/* Default CS4210 (CDB4210)*/
-static const struct cs_pincfg cdb4210_pincfgs[] = {
- { 0x05, 0x0321401f },
- { 0x06, 0x90170010 },
- { 0x07, 0x03813031 },
- { 0x08, 0xb7a70037 },
- { 0x09, 0xb7a6003e },
- { 0x0a, 0x034510f0 },
- {} /* terminator */
-};
-
-static const struct cs_pincfg *cs421x_pincfgs[CS421X_MODELS] = {
- [CS421X_CDB4210] = cdb4210_pincfgs,
-};
-
-static const struct hda_verb cs421x_coef_init_verbs[] = {
- {0x0B, AC_VERB_SET_PROC_STATE, 1},
- {0x0B, AC_VERB_SET_COEF_INDEX, CS421X_IDX_DEV_CFG},
- /*
- Disable Coefficient Index Auto-Increment(DAI)=1,
- PDREF=0
- */
- {0x0B, AC_VERB_SET_PROC_COEF, 0x0001 },
-
- {0x0B, AC_VERB_SET_COEF_INDEX, CS421X_IDX_ADC_CFG},
- /* ADC SZCMode = Digital Soft Ramp */
- {0x0B, AC_VERB_SET_PROC_COEF, 0x0002 },
-
- {0x0B, AC_VERB_SET_COEF_INDEX, CS421X_IDX_DAC_CFG},
- {0x0B, AC_VERB_SET_PROC_COEF,
- (0x0002 /* DAC SZCMode = Digital Soft Ramp */
- | 0x0004 /* Mute DAC on FIFO error */
- | 0x0008 /* Enable DAC High Pass Filter */
- )},
- {} /* terminator */
-};
-
-/* Errata: CS4210 rev A1 Silicon
- *
- * http://www.cirrus.com/en/pubs/errata/
- *
- * Description:
- * 1. Performance degredation is present in the ADC.
- * 2. Speaker output is not completely muted upon HP detect.
- * 3. Noise is present when clipping occurs on the amplified
- * speaker outputs.
- *
- * Workaround:
- * The following verb sequence written to the registers during
- * initialization will correct the issues listed above.
- */
-
-static const struct hda_verb cs421x_coef_init_verbs_A1_silicon_fixes[] = {
- {0x0B, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */
-
- {0x0B, AC_VERB_SET_COEF_INDEX, 0x0006},
- {0x0B, AC_VERB_SET_PROC_COEF, 0x9999}, /* Test mode: on */
-
- {0x0B, AC_VERB_SET_COEF_INDEX, 0x000A},
- {0x0B, AC_VERB_SET_PROC_COEF, 0x14CB}, /* Chop double */
-
- {0x0B, AC_VERB_SET_COEF_INDEX, 0x0011},
- {0x0B, AC_VERB_SET_PROC_COEF, 0xA2D0}, /* Increase ADC current */
-
- {0x0B, AC_VERB_SET_COEF_INDEX, 0x001A},
- {0x0B, AC_VERB_SET_PROC_COEF, 0x02A9}, /* Mute speaker */
-
- {0x0B, AC_VERB_SET_COEF_INDEX, 0x001B},
- {0x0B, AC_VERB_SET_PROC_COEF, 0X1006}, /* Remove noise */
-
- {} /* terminator */
-};
-
-/* Speaker Amp Gain is controlled by the vendor widget's coef 4 */
-static const DECLARE_TLV_DB_SCALE(cs421x_speaker_boost_db_scale, 900, 300, 0);
-
-static int cs421x_boost_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 3;
- return 0;
-}
-
-static int cs421x_boost_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] =
- cs_vendor_coef_get(codec, CS421X_IDX_SPK_CTL) & 0x0003;
- return 0;
-}
-
-static int cs421x_boost_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-
- unsigned int vol = ucontrol->value.integer.value[0];
- unsigned int coef =
- cs_vendor_coef_get(codec, CS421X_IDX_SPK_CTL);
- unsigned int original_coef = coef;
-
- coef &= ~0x0003;
- coef |= (vol & 0x0003);
- if (original_coef == coef)
- return 0;
- else {
- cs_vendor_coef_set(codec, CS421X_IDX_SPK_CTL, coef);
- return 1;
- }
-}
-
-static const struct snd_kcontrol_new cs421x_speaker_bost_ctl = {
-
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Speaker Boost Playback Volume",
- .info = cs421x_boost_vol_info,
- .get = cs421x_boost_vol_get,
- .put = cs421x_boost_vol_put,
- .tlv = { .p = cs421x_speaker_boost_db_scale },
-};
-
-static void cs4210_pinmux_init(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- unsigned int def_conf, coef;
-
- /* GPIO, DMIC_SCL, DMIC_SDA and SENSE_B are multiplexed */
- coef = cs_vendor_coef_get(codec, CS421X_IDX_DEV_CFG);
-
- if (spec->gpio_mask)
- coef |= 0x0008; /* B1,B2 are GPIOs */
- else
- coef &= ~0x0008;
-
- if (spec->sense_b)
- coef |= 0x0010; /* B2 is SENSE_B, not inverted */
- else
- coef &= ~0x0010;
-
- cs_vendor_coef_set(codec, CS421X_IDX_DEV_CFG, coef);
-
- if ((spec->gpio_mask || spec->sense_b) &&
- is_active_pin(codec, CS421X_DMIC_PIN_NID)) {
-
- /*
- GPIO or SENSE_B forced - disconnect the DMIC pin.
- */
- def_conf = snd_hda_codec_get_pincfg(codec, CS421X_DMIC_PIN_NID);
- def_conf &= ~AC_DEFCFG_PORT_CONN;
- def_conf |= (AC_JACK_PORT_NONE << AC_DEFCFG_PORT_CONN_SHIFT);
- snd_hda_codec_set_pincfg(codec, CS421X_DMIC_PIN_NID, def_conf);
- }
-}
-
-static void init_cs421x_digital(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i;
-
-
- for (i = 0; i < cfg->dig_outs; i++) {
- hda_nid_t nid = cfg->dig_out_pins[i];
- if (!cfg->speaker_outs)
- continue;
- if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
- snd_hda_jack_detect_enable(codec, nid, SPDIF_EVENT);
- spec->spdif_detect = 1;
- }
- }
-}
-
-static int cs421x_init(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
-
- if (spec->vendor_nid == CS4210_VENDOR_NID) {
- snd_hda_sequence_write(codec, cs421x_coef_init_verbs);
- snd_hda_sequence_write(codec, cs421x_coef_init_verbs_A1_silicon_fixes);
- cs4210_pinmux_init(codec);
- }
-
- if (spec->gpio_mask) {
- snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK,
- spec->gpio_mask);
- snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION,
- spec->gpio_dir);
- snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
- spec->gpio_data);
- }
-
- init_output(codec);
- init_input(codec);
- init_cs421x_digital(codec);
- snd_hda_jack_report_sync(codec);
-
- return 0;
-}
-
-/*
- * CS4210 Input MUX (1 ADC)
- */
-static int cs421x_mux_enum_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct cs_spec *spec = codec->spec;
-
- return snd_hda_input_mux_info(&spec->input_mux, uinfo);
-}
-
-static int cs421x_mux_enum_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct cs_spec *spec = codec->spec;
-
- ucontrol->value.enumerated.item[0] = spec->cur_input;
- return 0;
-}
-
-static int cs421x_mux_enum_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct cs_spec *spec = codec->spec;
-
- return snd_hda_input_mux_put(codec, &spec->input_mux, ucontrol,
- spec->adc_nid[0], &spec->cur_input);
-
-}
-
-static struct snd_kcontrol_new cs421x_capture_source = {
-
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = cs421x_mux_enum_info,
- .get = cs421x_mux_enum_get,
- .put = cs421x_mux_enum_put,
-};
-
-static int cs421x_add_input_volume_control(struct hda_codec *codec, int item)
-{
- struct cs_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- const struct hda_input_mux *imux = &spec->input_mux;
- hda_nid_t pin = cfg->inputs[item].pin;
- struct snd_kcontrol *kctl;
- u32 caps;
-
- if (!(get_wcaps(codec, pin) & AC_WCAP_IN_AMP))
- return 0;
-
- caps = query_amp_caps(codec, pin, HDA_INPUT);
- caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
- if (caps <= 1)
- return 0;
-
- return add_volume(codec, imux->items[item].label, 0,
- HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT), 1, &kctl);
-}
-
-/* add a (input-boost) volume control to the given input pin */
-static int build_cs421x_input(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- struct hda_input_mux *imux = &spec->input_mux;
- int i, err, type_idx;
- const char *label;
-
- if (!spec->num_inputs)
- return 0;
-
- /* make bind-capture */
- spec->capture_bind[0] = make_bind_capture(codec, &snd_hda_bind_sw);
- spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol);
- for (i = 0; i < 2; i++) {
- struct snd_kcontrol *kctl;
- int n;
- if (!spec->capture_bind[i])
- return -ENOMEM;
- kctl = snd_ctl_new1(&cs_capture_ctls[i], codec);
- if (!kctl)
- return -ENOMEM;
- kctl->private_value = (long)spec->capture_bind[i];
- err = snd_hda_ctl_add(codec, 0, kctl);
- if (err < 0)
- return err;
- for (n = 0; n < AUTO_PIN_LAST; n++) {
- if (!spec->adc_nid[n])
- continue;
- err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[n]);
- if (err < 0)
- return err;
- }
- }
-
- /* Add Input MUX Items + Capture Volume/Switch */
- for (i = 0; i < spec->num_inputs; i++) {
- label = hda_get_autocfg_input_label(codec, cfg, i);
- snd_hda_add_imux_item(imux, label, spec->adc_idx[i], &type_idx);
-
- err = cs421x_add_input_volume_control(codec, i);
- if (err < 0)
- return err;
- }
-
- /*
- Add 'Capture Source' Switch if
- * 2 inputs and no mic detec
- * 3 inputs
- */
- if ((spec->num_inputs == 2 && !spec->mic_detect) ||
- (spec->num_inputs == 3)) {
-
- err = snd_hda_ctl_add(codec, spec->adc_nid[0],
- snd_ctl_new1(&cs421x_capture_source, codec));
- if (err < 0)
- return err;
- }
-
- return 0;
-}
-
-/* Single DAC (Mute/Gain) */
-static int build_cs421x_output(struct hda_codec *codec)
-{
- hda_nid_t dac = CS4210_DAC_NID;
- struct cs_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- struct snd_kcontrol *kctl;
- int err;
- char *name = "Master";
-
- fix_volume_caps(codec, dac);
-
- err = add_mute(codec, name, 0,
- HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl);
- if (err < 0)
- return err;
-
- err = add_volume(codec, name, 0,
- HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl);
- if (err < 0)
- return err;
-
- if (cfg->speaker_outs && (spec->vendor_nid == CS4210_VENDOR_NID)) {
- err = snd_hda_ctl_add(codec, 0,
- snd_ctl_new1(&cs421x_speaker_bost_ctl, codec));
- if (err < 0)
- return err;
- }
- return err;
-}
-
-static int cs421x_build_controls(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- int err;
-
- err = build_cs421x_output(codec);
- if (err < 0)
- return err;
- err = build_cs421x_input(codec);
- if (err < 0)
- return err;
- err = build_digital_output(codec);
- if (err < 0)
- return err;
- err = cs421x_init(codec);
- if (err < 0)
- return err;
-
- err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static void cs421x_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- switch (snd_hda_jack_get_action(codec, res >> 26)) {
- case HP_EVENT:
- case SPDIF_EVENT:
- cs_automute(codec);
- break;
-
- case MIC_EVENT:
- cs_automic(codec);
- break;
- }
- snd_hda_jack_report_sync(codec);
-}
-
-static int parse_cs421x_input(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i;
-
- for (i = 0; i < cfg->num_inputs; i++) {
- hda_nid_t pin = cfg->inputs[i].pin;
- spec->adc_nid[i] = get_adc(codec, pin, &spec->adc_idx[i]);
- spec->cur_input = spec->last_input = i;
- spec->num_inputs++;
-
- /* check whether the automatic mic switch is available */
- if (is_ext_mic(codec, i) && cfg->num_inputs >= 2) {
- spec->mic_detect = 1;
- spec->automic_idx = i;
- }
- }
- return 0;
-}
-
-static int cs421x_parse_auto_config(struct hda_codec *codec)
-{
- struct cs_spec *spec = codec->spec;
- int err;
-
- err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
- if (err < 0)
- return err;
- err = parse_output(codec);
- if (err < 0)
- return err;
- err = parse_cs421x_input(codec);
- if (err < 0)
- return err;
- err = parse_digital_output(codec);
- if (err < 0)
- return err;
- return 0;
-}
-
-#ifdef CONFIG_PM
-/*
- Manage PDREF, when transitioning to D3hot
- (DAC,ADC) -> D3, PDREF=1, AFG->D3
-*/
-static int cs421x_suspend(struct hda_codec *codec, pm_message_t state)
-{
- struct cs_spec *spec = codec->spec;
- unsigned int coef;
-
- snd_hda_shutup_pins(codec);
-
- snd_hda_codec_write(codec, CS4210_DAC_NID, 0,
- AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
- snd_hda_codec_write(codec, CS4210_ADC_NID, 0,
- AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
-
- if (spec->vendor_nid == CS4210_VENDOR_NID) {
- coef = cs_vendor_coef_get(codec, CS421X_IDX_DEV_CFG);
- coef |= 0x0004; /* PDREF */
- cs_vendor_coef_set(codec, CS421X_IDX_DEV_CFG, coef);
- }
-
- return 0;
-}
-#endif
-
-static struct hda_codec_ops cs421x_patch_ops = {
- .build_controls = cs421x_build_controls,
- .build_pcms = cs_build_pcms,
- .init = cs421x_init,
- .free = cs_free,
- .unsol_event = cs421x_unsol_event,
-#ifdef CONFIG_PM
- .suspend = cs421x_suspend,
-#endif
-};
-
-static int patch_cs4210(struct hda_codec *codec)
-{
- struct cs_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- codec->spec = spec;
-
- spec->vendor_nid = CS4210_VENDOR_NID;
-
- spec->board_config =
- snd_hda_check_board_config(codec, CS421X_MODELS,
- cs421x_models, cs421x_cfg_tbl);
- if (spec->board_config >= 0)
- fix_pincfg(codec, spec->board_config, cs421x_pincfgs);
- /*
- Setup GPIO/SENSE for each board (if used)
- */
- switch (spec->board_config) {
- case CS421X_CDB4210:
- snd_printd("CS4210 board: %s\n",
- cs421x_models[spec->board_config]);
-/* spec->gpio_mask = 3;
- spec->gpio_dir = 3;
- spec->gpio_data = 3;
-*/
- spec->sense_b = 1;
-
- break;
- }
-
- /*
- Update the GPIO/DMIC/SENSE_B pinmux before the configuration
- is auto-parsed. If GPIO or SENSE_B is forced, DMIC input
- is disabled.
- */
- cs4210_pinmux_init(codec);
-
- err = cs421x_parse_auto_config(codec);
- if (err < 0)
- goto error;
-
- codec->patch_ops = cs421x_patch_ops;
-
- return 0;
-
- error:
- kfree(codec->spec);
- codec->spec = NULL;
- return err;
-}
-
-static int patch_cs4213(struct hda_codec *codec)
-{
- struct cs_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- codec->spec = spec;
-
- spec->vendor_nid = CS4213_VENDOR_NID;
-
- err = cs421x_parse_auto_config(codec);
- if (err < 0)
- goto error;
-
- codec->patch_ops = cs421x_patch_ops;
- return 0;
-
- error:
- kfree(codec->spec);
- codec->spec = NULL;
- return err;
-}
-
-
-/*
- * patch entries
- */
-static const struct hda_codec_preset snd_hda_preset_cirrus[] = {
- { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x },
- { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x },
- { .id = 0x10134210, .name = "CS4210", .patch = patch_cs4210 },
- { .id = 0x10134213, .name = "CS4213", .patch = patch_cs4213 },
- {} /* terminator */
-};
-
-MODULE_ALIAS("snd-hda-codec-id:10134206");
-MODULE_ALIAS("snd-hda-codec-id:10134207");
-MODULE_ALIAS("snd-hda-codec-id:10134210");
-MODULE_ALIAS("snd-hda-codec-id:10134213");
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Cirrus Logic HD-audio codec");
-
-static struct hda_codec_preset_list cirrus_list = {
- .preset = snd_hda_preset_cirrus,
- .owner = THIS_MODULE,
-};
-
-static int __init patch_cirrus_init(void)
-{
- return snd_hda_add_codec_preset(&cirrus_list);
-}
-
-static void __exit patch_cirrus_exit(void)
-{
- snd_hda_delete_codec_preset(&cirrus_list);
-}
-
-module_init(patch_cirrus_init)
-module_exit(patch_cirrus_exit)
diff --git a/ANDROID_3.4.5/sound/pci/hda/patch_cmedia.c b/ANDROID_3.4.5/sound/pci/hda/patch_cmedia.c
deleted file mode 100644
index b6767b4c..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/patch_cmedia.c
+++ /dev/null
@@ -1,776 +0,0 @@
-/*
- * Universal Interface for Intel High Definition Audio Codec
- *
- * HD audio interface patch for C-Media CMI9880
- *
- * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
- *
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include "hda_codec.h"
-#include "hda_local.h"
-#define NUM_PINS 11
-
-
-/* board config type */
-enum {
- CMI_MINIMAL, /* back 3-jack */
- CMI_MIN_FP, /* back 3-jack + front-panel 2-jack */
- CMI_FULL, /* back 6-jack + front-panel 2-jack */
- CMI_FULL_DIG, /* back 6-jack + front-panel 2-jack + digital I/O */
- CMI_ALLOUT, /* back 5-jack + front-panel 2-jack + digital out */
- CMI_AUTO, /* let driver guess it */
- CMI_MODELS
-};
-
-struct cmi_spec {
- int board_config;
- unsigned int no_line_in: 1; /* no line-in (5-jack) */
- unsigned int front_panel: 1; /* has front-panel 2-jack */
-
- /* playback */
- struct hda_multi_out multiout;
- hda_nid_t dac_nids[AUTO_CFG_MAX_OUTS]; /* NID for each DAC */
- int num_dacs;
-
- /* capture */
- const hda_nid_t *adc_nids;
- hda_nid_t dig_in_nid;
-
- /* capture source */
- const struct hda_input_mux *input_mux;
- unsigned int cur_mux[2];
-
- /* channel mode */
- int num_channel_modes;
- const struct hda_channel_mode *channel_modes;
-
- struct hda_pcm pcm_rec[2]; /* PCM information */
-
- /* pin default configuration */
- hda_nid_t pin_nid[NUM_PINS];
- unsigned int def_conf[NUM_PINS];
- unsigned int pin_def_confs;
-
- /* multichannel pins */
- struct hda_verb multi_init[9]; /* 2 verbs for each pin + terminator */
-};
-
-/*
- * input MUX
- */
-static int cmi_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct cmi_spec *spec = codec->spec;
- return snd_hda_input_mux_info(spec->input_mux, uinfo);
-}
-
-static int cmi_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct cmi_spec *spec = codec->spec;
- unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-
- ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
- return 0;
-}
-
-static int cmi_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct cmi_spec *spec = codec->spec;
- unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-
- return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
- spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);
-}
-
-/*
- * shared line-in, mic for surrounds
- */
-
-/* 3-stack / 2 channel */
-static const struct hda_verb cmi9880_ch2_init[] = {
- /* set line-in PIN for input */
- { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
- /* set mic PIN for input, also enable vref */
- { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
- /* route front PCM (DAC1) to HP */
- { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
- {}
-};
-
-/* 3-stack / 6 channel */
-static const struct hda_verb cmi9880_ch6_init[] = {
- /* set line-in PIN for output */
- { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- /* set mic PIN for output */
- { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- /* route front PCM (DAC1) to HP */
- { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
- {}
-};
-
-/* 3-stack+front / 8 channel */
-static const struct hda_verb cmi9880_ch8_init[] = {
- /* set line-in PIN for output */
- { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- /* set mic PIN for output */
- { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- /* route rear-surround PCM (DAC4) to HP */
- { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x03 },
- {}
-};
-
-static const struct hda_channel_mode cmi9880_channel_modes[3] = {
- { 2, cmi9880_ch2_init },
- { 6, cmi9880_ch6_init },
- { 8, cmi9880_ch8_init },
-};
-
-static int cmi_ch_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct cmi_spec *spec = codec->spec;
- return snd_hda_ch_mode_info(codec, uinfo, spec->channel_modes,
- spec->num_channel_modes);
-}
-
-static int cmi_ch_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct cmi_spec *spec = codec->spec;
- return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_modes,
- spec->num_channel_modes, spec->multiout.max_channels);
-}
-
-static int cmi_ch_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct cmi_spec *spec = codec->spec;
- return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_modes,
- spec->num_channel_modes, &spec->multiout.max_channels);
-}
-
-/*
- */
-static const struct snd_kcontrol_new cmi9880_basic_mixer[] = {
- /* CMI9880 has no playback volumes! */
- HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), /* front */
- HDA_CODEC_MUTE("Surround Playback Switch", 0x04, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Side Playback Switch", 0x06, 0x0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- /* The multiple "Capture Source" controls confuse alsamixer
- * So call somewhat different..
- */
- /* .name = "Capture Source", */
- .name = "Input Source",
- .count = 2,
- .info = cmi_mux_enum_info,
- .get = cmi_mux_enum_get,
- .put = cmi_mux_enum_put,
- },
- HDA_CODEC_VOLUME("Capture Volume", 0x08, 0, HDA_INPUT),
- HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x08, 0, HDA_INPUT),
- HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Beep Playback Volume", 0x23, 0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Beep Playback Switch", 0x23, 0, HDA_OUTPUT),
- { } /* end */
-};
-
-/*
- * shared I/O pins
- */
-static const struct snd_kcontrol_new cmi9880_ch_mode_mixer[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Channel Mode",
- .info = cmi_ch_mode_info,
- .get = cmi_ch_mode_get,
- .put = cmi_ch_mode_put,
- },
- { } /* end */
-};
-
-/* AUD-in selections:
- * 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x1f 0x20
- */
-static const struct hda_input_mux cmi9880_basic_mux = {
- .num_items = 4,
- .items = {
- { "Front Mic", 0x5 },
- { "Rear Mic", 0x2 },
- { "Line", 0x1 },
- { "CD", 0x7 },
- }
-};
-
-static const struct hda_input_mux cmi9880_no_line_mux = {
- .num_items = 3,
- .items = {
- { "Front Mic", 0x5 },
- { "Rear Mic", 0x2 },
- { "CD", 0x7 },
- }
-};
-
-/* front, rear, clfe, rear_surr */
-static const hda_nid_t cmi9880_dac_nids[4] = {
- 0x03, 0x04, 0x05, 0x06
-};
-/* ADC0, ADC1 */
-static const hda_nid_t cmi9880_adc_nids[2] = {
- 0x08, 0x09
-};
-
-#define CMI_DIG_OUT_NID 0x07
-#define CMI_DIG_IN_NID 0x0a
-
-/*
- */
-static const struct hda_verb cmi9880_basic_init[] = {
- /* port-D for line out (rear panel) */
- { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
- /* port-E for HP out (front panel) */
- { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
- /* route front PCM to HP */
- { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
- /* port-A for surround (rear panel) */
- { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
- /* port-G for CLFE (rear panel) */
- { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
- { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x02 },
- /* port-H for side (rear panel) */
- { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
- { 0x20, AC_VERB_SET_CONNECT_SEL, 0x01 },
- /* port-C for line-in (rear panel) */
- { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
- /* port-B for mic-in (rear panel) with vref */
- { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
- /* port-F for mic-in (front panel) with vref */
- { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
- /* CD-in */
- { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
- /* route front mic to ADC1/2 */
- { 0x08, AC_VERB_SET_CONNECT_SEL, 0x05 },
- { 0x09, AC_VERB_SET_CONNECT_SEL, 0x05 },
- {} /* terminator */
-};
-
-static const struct hda_verb cmi9880_allout_init[] = {
- /* port-D for line out (rear panel) */
- { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
- /* port-E for HP out (front panel) */
- { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
- /* route front PCM to HP */
- { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
- /* port-A for side (rear panel) */
- { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
- /* port-G for CLFE (rear panel) */
- { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
- { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x02 },
- /* port-H for side (rear panel) */
- { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
- { 0x20, AC_VERB_SET_CONNECT_SEL, 0x01 },
- /* port-C for surround (rear panel) */
- { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
- /* port-B for mic-in (rear panel) with vref */
- { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
- /* port-F for mic-in (front panel) with vref */
- { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
- /* CD-in */
- { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
- /* route front mic to ADC1/2 */
- { 0x08, AC_VERB_SET_CONNECT_SEL, 0x05 },
- { 0x09, AC_VERB_SET_CONNECT_SEL, 0x05 },
- {} /* terminator */
-};
-
-/*
- */
-static int cmi9880_build_controls(struct hda_codec *codec)
-{
- struct cmi_spec *spec = codec->spec;
- struct snd_kcontrol *kctl;
- int i, err;
-
- err = snd_hda_add_new_ctls(codec, cmi9880_basic_mixer);
- if (err < 0)
- return err;
- if (spec->channel_modes) {
- err = snd_hda_add_new_ctls(codec, cmi9880_ch_mode_mixer);
- if (err < 0)
- return err;
- }
- if (spec->multiout.dig_out_nid) {
- err = snd_hda_create_spdif_out_ctls(codec,
- spec->multiout.dig_out_nid,
- spec->multiout.dig_out_nid);
- if (err < 0)
- return err;
- err = snd_hda_create_spdif_share_sw(codec,
- &spec->multiout);
- if (err < 0)
- return err;
- spec->multiout.share_spdif = 1;
- }
- if (spec->dig_in_nid) {
- err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
- if (err < 0)
- return err;
- }
-
- /* assign Capture Source enums to NID */
- kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
- for (i = 0; kctl && i < kctl->count; i++) {
- err = snd_hda_add_nid(codec, kctl, i, spec->adc_nids[i]);
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-/* fill in the multi_dac_nids table, which will decide
- which audio widget to use for each channel */
-static int cmi9880_fill_multi_dac_nids(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
-{
- struct cmi_spec *spec = codec->spec;
- hda_nid_t nid;
- int assigned[4];
- int i, j;
-
- /* clear the table, only one c-media dac assumed here */
- memset(spec->dac_nids, 0, sizeof(spec->dac_nids));
- memset(assigned, 0, sizeof(assigned));
- /* check the pins we found */
- for (i = 0; i < cfg->line_outs; i++) {
- nid = cfg->line_out_pins[i];
- /* nid 0x0b~0x0e is hardwired to audio widget 0x3~0x6 */
- if (nid >= 0x0b && nid <= 0x0e) {
- spec->dac_nids[i] = (nid - 0x0b) + 0x03;
- assigned[nid - 0x0b] = 1;
- }
- }
- /* left pin can be connect to any audio widget */
- for (i = 0; i < cfg->line_outs; i++) {
- nid = cfg->line_out_pins[i];
- if (nid <= 0x0e)
- continue;
- /* search for an empty channel */
- for (j = 0; j < cfg->line_outs; j++) {
- if (! assigned[j]) {
- spec->dac_nids[i] = j + 0x03;
- assigned[j] = 1;
- break;
- }
- }
- }
- spec->num_dacs = cfg->line_outs;
- return 0;
-}
-
-/* create multi_init table, which is used for multichannel initialization */
-static int cmi9880_fill_multi_init(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
-{
- struct cmi_spec *spec = codec->spec;
- hda_nid_t nid;
- int i, j, k;
-
- /* clear the table, only one c-media dac assumed here */
- memset(spec->multi_init, 0, sizeof(spec->multi_init));
- for (j = 0, i = 0; i < cfg->line_outs; i++) {
- nid = cfg->line_out_pins[i];
- /* set as output */
- spec->multi_init[j].nid = nid;
- spec->multi_init[j].verb = AC_VERB_SET_PIN_WIDGET_CONTROL;
- spec->multi_init[j].param = PIN_OUT;
- j++;
- if (nid > 0x0e) {
- /* set connection */
- spec->multi_init[j].nid = nid;
- spec->multi_init[j].verb = AC_VERB_SET_CONNECT_SEL;
- spec->multi_init[j].param = 0;
- /* find the index in connect list */
- k = snd_hda_get_conn_index(codec, nid,
- spec->dac_nids[i], 0);
- if (k >= 0)
- spec->multi_init[j].param = k;
- j++;
- }
- }
- return 0;
-}
-
-static int cmi9880_init(struct hda_codec *codec)
-{
- struct cmi_spec *spec = codec->spec;
- if (spec->board_config == CMI_ALLOUT)
- snd_hda_sequence_write(codec, cmi9880_allout_init);
- else
- snd_hda_sequence_write(codec, cmi9880_basic_init);
- if (spec->board_config == CMI_AUTO)
- snd_hda_sequence_write(codec, spec->multi_init);
- return 0;
-}
-
-/*
- * Analog playback callbacks
- */
-static int cmi9880_playback_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct cmi_spec *spec = codec->spec;
- return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
- hinfo);
-}
-
-static int cmi9880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct cmi_spec *spec = codec->spec;
- return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
- format, substream);
-}
-
-static int cmi9880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct cmi_spec *spec = codec->spec;
- return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
-}
-
-/*
- * Digital out
- */
-static int cmi9880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct cmi_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_open(codec, &spec->multiout);
-}
-
-static int cmi9880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct cmi_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_close(codec, &spec->multiout);
-}
-
-static int cmi9880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct cmi_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
- format, substream);
-}
-
-/*
- * Analog capture
- */
-static int cmi9880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct cmi_spec *spec = codec->spec;
-
- snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
- stream_tag, 0, format);
- return 0;
-}
-
-static int cmi9880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct cmi_spec *spec = codec->spec;
-
- snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
- return 0;
-}
-
-
-/*
- */
-static const struct hda_pcm_stream cmi9880_pcm_analog_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 8,
- .nid = 0x03, /* NID to query formats and rates */
- .ops = {
- .open = cmi9880_playback_pcm_open,
- .prepare = cmi9880_playback_pcm_prepare,
- .cleanup = cmi9880_playback_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream cmi9880_pcm_analog_capture = {
- .substreams = 2,
- .channels_min = 2,
- .channels_max = 2,
- .nid = 0x08, /* NID to query formats and rates */
- .ops = {
- .prepare = cmi9880_capture_pcm_prepare,
- .cleanup = cmi9880_capture_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream cmi9880_pcm_digital_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- /* NID is set in cmi9880_build_pcms */
- .ops = {
- .open = cmi9880_dig_playback_pcm_open,
- .close = cmi9880_dig_playback_pcm_close,
- .prepare = cmi9880_dig_playback_pcm_prepare
- },
-};
-
-static const struct hda_pcm_stream cmi9880_pcm_digital_capture = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- /* NID is set in cmi9880_build_pcms */
-};
-
-static int cmi9880_build_pcms(struct hda_codec *codec)
-{
- struct cmi_spec *spec = codec->spec;
- struct hda_pcm *info = spec->pcm_rec;
-
- codec->num_pcms = 1;
- codec->pcm_info = info;
-
- info->name = "CMI9880";
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] = cmi9880_pcm_analog_playback;
- info->stream[SNDRV_PCM_STREAM_CAPTURE] = cmi9880_pcm_analog_capture;
-
- if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
- codec->num_pcms++;
- info++;
- info->name = "CMI9880 Digital";
- info->pcm_type = HDA_PCM_TYPE_SPDIF;
- if (spec->multiout.dig_out_nid) {
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] = cmi9880_pcm_digital_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
- }
- if (spec->dig_in_nid) {
- info->stream[SNDRV_PCM_STREAM_CAPTURE] = cmi9880_pcm_digital_capture;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
- }
- }
-
- return 0;
-}
-
-static void cmi9880_free(struct hda_codec *codec)
-{
- kfree(codec->spec);
-}
-
-/*
- */
-
-static const char * const cmi9880_models[CMI_MODELS] = {
- [CMI_MINIMAL] = "minimal",
- [CMI_MIN_FP] = "min_fp",
- [CMI_FULL] = "full",
- [CMI_FULL_DIG] = "full_dig",
- [CMI_ALLOUT] = "allout",
- [CMI_AUTO] = "auto",
-};
-
-static const struct snd_pci_quirk cmi9880_cfg_tbl[] = {
- SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", CMI_FULL_DIG),
- SND_PCI_QUIRK(0x1854, 0x002b, "LG LS75", CMI_MINIMAL),
- SND_PCI_QUIRK(0x1854, 0x0032, "LG", CMI_FULL_DIG),
- {} /* terminator */
-};
-
-static const struct hda_codec_ops cmi9880_patch_ops = {
- .build_controls = cmi9880_build_controls,
- .build_pcms = cmi9880_build_pcms,
- .init = cmi9880_init,
- .free = cmi9880_free,
-};
-
-static int patch_cmi9880(struct hda_codec *codec)
-{
- struct cmi_spec *spec;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->spec = spec;
- spec->board_config = snd_hda_check_board_config(codec, CMI_MODELS,
- cmi9880_models,
- cmi9880_cfg_tbl);
- if (spec->board_config < 0) {
- snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
- codec->chip_name);
- spec->board_config = CMI_AUTO; /* try everything */
- }
-
- /* copy default DAC NIDs */
- memcpy(spec->dac_nids, cmi9880_dac_nids, sizeof(spec->dac_nids));
- spec->num_dacs = 4;
-
- switch (spec->board_config) {
- case CMI_MINIMAL:
- case CMI_MIN_FP:
- spec->channel_modes = cmi9880_channel_modes;
- if (spec->board_config == CMI_MINIMAL)
- spec->num_channel_modes = 2;
- else {
- spec->front_panel = 1;
- spec->num_channel_modes = 3;
- }
- spec->multiout.max_channels = cmi9880_channel_modes[0].channels;
- spec->input_mux = &cmi9880_basic_mux;
- break;
- case CMI_FULL:
- case CMI_FULL_DIG:
- spec->front_panel = 1;
- spec->multiout.max_channels = 8;
- spec->input_mux = &cmi9880_basic_mux;
- if (spec->board_config == CMI_FULL_DIG) {
- spec->multiout.dig_out_nid = CMI_DIG_OUT_NID;
- spec->dig_in_nid = CMI_DIG_IN_NID;
- }
- break;
- case CMI_ALLOUT:
- spec->front_panel = 1;
- spec->multiout.max_channels = 8;
- spec->no_line_in = 1;
- spec->input_mux = &cmi9880_no_line_mux;
- spec->multiout.dig_out_nid = CMI_DIG_OUT_NID;
- break;
- case CMI_AUTO:
- {
- unsigned int port_e, port_f, port_g, port_h;
- unsigned int port_spdifi, port_spdifo;
- struct auto_pin_cfg cfg;
-
- /* collect pin default configuration */
- port_e = snd_hda_codec_get_pincfg(codec, 0x0f);
- port_f = snd_hda_codec_get_pincfg(codec, 0x10);
- spec->front_panel = 1;
- if (get_defcfg_connect(port_e) == AC_JACK_PORT_NONE ||
- get_defcfg_connect(port_f) == AC_JACK_PORT_NONE) {
- port_g = snd_hda_codec_get_pincfg(codec, 0x1f);
- port_h = snd_hda_codec_get_pincfg(codec, 0x20);
- spec->channel_modes = cmi9880_channel_modes;
- /* no front panel */
- if (get_defcfg_connect(port_g) == AC_JACK_PORT_NONE ||
- get_defcfg_connect(port_h) == AC_JACK_PORT_NONE) {
- /* no optional rear panel */
- spec->board_config = CMI_MINIMAL;
- spec->front_panel = 0;
- spec->num_channel_modes = 2;
- } else {
- spec->board_config = CMI_MIN_FP;
- spec->num_channel_modes = 3;
- }
- spec->input_mux = &cmi9880_basic_mux;
- spec->multiout.max_channels = cmi9880_channel_modes[0].channels;
- } else {
- spec->input_mux = &cmi9880_basic_mux;
- port_spdifi = snd_hda_codec_get_pincfg(codec, 0x13);
- port_spdifo = snd_hda_codec_get_pincfg(codec, 0x12);
- if (get_defcfg_connect(port_spdifo) != AC_JACK_PORT_NONE)
- spec->multiout.dig_out_nid = CMI_DIG_OUT_NID;
- if (get_defcfg_connect(port_spdifi) != AC_JACK_PORT_NONE)
- spec->dig_in_nid = CMI_DIG_IN_NID;
- spec->multiout.max_channels = 8;
- }
- snd_hda_parse_pin_def_config(codec, &cfg, NULL);
- if (cfg.line_outs) {
- spec->multiout.max_channels = cfg.line_outs * 2;
- cmi9880_fill_multi_dac_nids(codec, &cfg);
- cmi9880_fill_multi_init(codec, &cfg);
- } else
- snd_printd("patch_cmedia: cannot detect association in defcfg\n");
- break;
- }
- }
-
- spec->multiout.num_dacs = spec->num_dacs;
- spec->multiout.dac_nids = spec->dac_nids;
-
- spec->adc_nids = cmi9880_adc_nids;
-
- codec->patch_ops = cmi9880_patch_ops;
-
- return 0;
-}
-
-/*
- * patch entries
- */
-static const struct hda_codec_preset snd_hda_preset_cmedia[] = {
- { .id = 0x13f69880, .name = "CMI9880", .patch = patch_cmi9880 },
- { .id = 0x434d4980, .name = "CMI9880", .patch = patch_cmi9880 },
- {} /* terminator */
-};
-
-MODULE_ALIAS("snd-hda-codec-id:13f69880");
-MODULE_ALIAS("snd-hda-codec-id:434d4980");
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("C-Media HD-audio codec");
-
-static struct hda_codec_preset_list cmedia_list = {
- .preset = snd_hda_preset_cmedia,
- .owner = THIS_MODULE,
-};
-
-static int __init patch_cmedia_init(void)
-{
- return snd_hda_add_codec_preset(&cmedia_list);
-}
-
-static void __exit patch_cmedia_exit(void)
-{
- snd_hda_delete_codec_preset(&cmedia_list);
-}
-
-module_init(patch_cmedia_init)
-module_exit(patch_cmedia_exit)
diff --git a/ANDROID_3.4.5/sound/pci/hda/patch_conexant.c b/ANDROID_3.4.5/sound/pci/hda/patch_conexant.c
deleted file mode 100644
index d906c5b7..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/patch_conexant.c
+++ /dev/null
@@ -1,4599 +0,0 @@
-/*
- * HD audio interface patch for Conexant HDA audio codec
- *
- * Copyright (c) 2006 Pototskiy Akex <alex.pototskiy@gmail.com>
- * Takashi Iwai <tiwai@suse.de>
- * Tobin Davis <tdavis@dsl-only.net>
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/jack.h>
-
-#include "hda_codec.h"
-#include "hda_local.h"
-#include "hda_beep.h"
-#include "hda_jack.h"
-
-#define CXT_PIN_DIR_IN 0x00
-#define CXT_PIN_DIR_OUT 0x01
-#define CXT_PIN_DIR_INOUT 0x02
-#define CXT_PIN_DIR_IN_NOMICBIAS 0x03
-#define CXT_PIN_DIR_INOUT_NOMICBIAS 0x04
-
-#define CONEXANT_HP_EVENT 0x37
-#define CONEXANT_MIC_EVENT 0x38
-#define CONEXANT_LINE_EVENT 0x39
-
-/* Conexant 5051 specific */
-
-#define CXT5051_SPDIF_OUT 0x12
-#define CXT5051_PORTB_EVENT 0x38
-#define CXT5051_PORTC_EVENT 0x39
-
-#define AUTO_MIC_PORTB (1 << 1)
-#define AUTO_MIC_PORTC (1 << 2)
-
-struct pin_dac_pair {
- hda_nid_t pin;
- hda_nid_t dac;
- int type;
-};
-
-struct imux_info {
- hda_nid_t pin; /* input pin NID */
- hda_nid_t adc; /* connected ADC NID */
- hda_nid_t boost; /* optional boost volume NID */
- int index; /* corresponding to autocfg.input */
-};
-
-struct conexant_spec {
-
- const struct snd_kcontrol_new *mixers[5];
- int num_mixers;
- hda_nid_t vmaster_nid;
- struct hda_vmaster_mute_hook vmaster_mute;
- bool vmaster_mute_led;
-
- const struct hda_verb *init_verbs[5]; /* initialization verbs
- * don't forget NULL
- * termination!
- */
- unsigned int num_init_verbs;
-
- /* playback */
- struct hda_multi_out multiout; /* playback set-up
- * max_channels, dacs must be set
- * dig_out_nid and hp_nid are optional
- */
- unsigned int cur_eapd;
- unsigned int hp_present;
- unsigned int line_present;
- unsigned int auto_mic;
- int auto_mic_ext; /* imux_pins[] index for ext mic */
- int auto_mic_dock; /* imux_pins[] index for dock mic */
- int auto_mic_int; /* imux_pins[] index for int mic */
- unsigned int need_dac_fix;
- hda_nid_t slave_dig_outs[2];
-
- /* capture */
- unsigned int num_adc_nids;
- const hda_nid_t *adc_nids;
- hda_nid_t dig_in_nid; /* digital-in NID; optional */
-
- unsigned int cur_adc_idx;
- hda_nid_t cur_adc;
- unsigned int cur_adc_stream_tag;
- unsigned int cur_adc_format;
-
- const struct hda_pcm_stream *capture_stream;
-
- /* capture source */
- const struct hda_input_mux *input_mux;
- const hda_nid_t *capsrc_nids;
- unsigned int cur_mux[3];
-
- /* channel model */
- const struct hda_channel_mode *channel_mode;
- int num_channel_mode;
-
- /* PCM information */
- struct hda_pcm pcm_rec[2]; /* used in build_pcms() */
-
- unsigned int spdif_route;
-
- /* dynamic controls, init_verbs and input_mux */
- struct auto_pin_cfg autocfg;
- struct hda_input_mux private_imux;
- struct imux_info imux_info[HDA_MAX_NUM_INPUTS];
- hda_nid_t private_adc_nids[HDA_MAX_NUM_INPUTS];
- hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
- struct pin_dac_pair dac_info[8];
- int dac_info_filled;
-
- unsigned int port_d_mode;
- unsigned int auto_mute:1; /* used in auto-parser */
- unsigned int detect_line:1; /* Line-out detection enabled */
- unsigned int automute_lines:1; /* automute line-out as well */
- unsigned int automute_hp_lo:1; /* both HP and LO available */
- unsigned int dell_automute:1;
- unsigned int dell_vostro:1;
- unsigned int ideapad:1;
- unsigned int thinkpad:1;
- unsigned int hp_laptop:1;
- unsigned int asus:1;
- unsigned int pin_eapd_ctrls:1;
-
- unsigned int adc_switching:1;
-
- unsigned int ext_mic_present;
- unsigned int recording;
- void (*capture_prepare)(struct hda_codec *codec);
- void (*capture_cleanup)(struct hda_codec *codec);
-
- /* OLPC XO-1.5 supports DC input mode (e.g. for use with analog sensors)
- * through the microphone jack.
- * When the user enables this through a mixer switch, both internal and
- * external microphones are disabled. Gain is fixed at 0dB. In this mode,
- * we also allow the bias to be configured through a separate mixer
- * control. */
- unsigned int dc_enable;
- unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */
- unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */
-
- unsigned int beep_amp;
-
- /* extra EAPD pins */
- unsigned int num_eapds;
- hda_nid_t eapds[4];
-};
-
-static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct conexant_spec *spec = codec->spec;
- return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
- hinfo);
-}
-
-static int conexant_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct conexant_spec *spec = codec->spec;
- return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
- stream_tag,
- format, substream);
-}
-
-static int conexant_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct conexant_spec *spec = codec->spec;
- return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
-}
-
-/*
- * Digital out
- */
-static int conexant_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct conexant_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_open(codec, &spec->multiout);
-}
-
-static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct conexant_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_close(codec, &spec->multiout);
-}
-
-static int conexant_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct conexant_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
- stream_tag,
- format, substream);
-}
-
-/*
- * Analog capture
- */
-static int conexant_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct conexant_spec *spec = codec->spec;
- if (spec->capture_prepare)
- spec->capture_prepare(codec);
- snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
- stream_tag, 0, format);
- return 0;
-}
-
-static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct conexant_spec *spec = codec->spec;
- snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
- if (spec->capture_cleanup)
- spec->capture_cleanup(codec);
- return 0;
-}
-
-
-
-static const struct hda_pcm_stream conexant_pcm_analog_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .nid = 0, /* fill later */
- .ops = {
- .open = conexant_playback_pcm_open,
- .prepare = conexant_playback_pcm_prepare,
- .cleanup = conexant_playback_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream conexant_pcm_analog_capture = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .nid = 0, /* fill later */
- .ops = {
- .prepare = conexant_capture_pcm_prepare,
- .cleanup = conexant_capture_pcm_cleanup
- },
-};
-
-
-static const struct hda_pcm_stream conexant_pcm_digital_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .nid = 0, /* fill later */
- .ops = {
- .open = conexant_dig_playback_pcm_open,
- .close = conexant_dig_playback_pcm_close,
- .prepare = conexant_dig_playback_pcm_prepare
- },
-};
-
-static const struct hda_pcm_stream conexant_pcm_digital_capture = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- /* NID is set in alc_build_pcms */
-};
-
-static int cx5051_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct conexant_spec *spec = codec->spec;
- spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
- spec->cur_adc_stream_tag = stream_tag;
- spec->cur_adc_format = format;
- snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
- return 0;
-}
-
-static int cx5051_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct conexant_spec *spec = codec->spec;
- snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
- spec->cur_adc = 0;
- return 0;
-}
-
-static const struct hda_pcm_stream cx5051_pcm_analog_capture = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .nid = 0, /* fill later */
- .ops = {
- .prepare = cx5051_capture_pcm_prepare,
- .cleanup = cx5051_capture_pcm_cleanup
- },
-};
-
-static int conexant_build_pcms(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- struct hda_pcm *info = spec->pcm_rec;
-
- codec->num_pcms = 1;
- codec->pcm_info = info;
-
- info->name = "CONEXANT Analog";
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] = conexant_pcm_analog_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
- spec->multiout.max_channels;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
- spec->multiout.dac_nids[0];
- if (spec->capture_stream)
- info->stream[SNDRV_PCM_STREAM_CAPTURE] = *spec->capture_stream;
- else {
- if (codec->vendor_id == 0x14f15051)
- info->stream[SNDRV_PCM_STREAM_CAPTURE] =
- cx5051_pcm_analog_capture;
- else {
- info->stream[SNDRV_PCM_STREAM_CAPTURE] =
- conexant_pcm_analog_capture;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
- spec->num_adc_nids;
- }
- }
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
-
- if (spec->multiout.dig_out_nid) {
- info++;
- codec->num_pcms++;
- info->name = "Conexant Digital";
- info->pcm_type = HDA_PCM_TYPE_SPDIF;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
- conexant_pcm_digital_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
- spec->multiout.dig_out_nid;
- if (spec->dig_in_nid) {
- info->stream[SNDRV_PCM_STREAM_CAPTURE] =
- conexant_pcm_digital_capture;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
- spec->dig_in_nid;
- }
- if (spec->slave_dig_outs[0])
- codec->slave_dig_outs = spec->slave_dig_outs;
- }
-
- return 0;
-}
-
-static int conexant_mux_enum_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
-
- return snd_hda_input_mux_info(spec->input_mux, uinfo);
-}
-
-static int conexant_mux_enum_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
- unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-
- ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
- return 0;
-}
-
-static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
- unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-
- return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
- spec->capsrc_nids[adc_idx],
- &spec->cur_mux[adc_idx]);
-}
-
-static void conexant_set_power(struct hda_codec *codec, hda_nid_t fg,
- unsigned int power_state)
-{
- if (power_state == AC_PWRST_D3)
- msleep(100);
- snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
- power_state);
- /* partial workaround for "azx_get_response timeout" */
- if (power_state == AC_PWRST_D0)
- msleep(10);
- snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
-}
-
-static int conexant_init(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- int i;
-
- for (i = 0; i < spec->num_init_verbs; i++)
- snd_hda_sequence_write(codec, spec->init_verbs[i]);
- return 0;
-}
-
-static void conexant_free(struct hda_codec *codec)
-{
- snd_hda_detach_beep_device(codec);
- kfree(codec->spec);
-}
-
-static const struct snd_kcontrol_new cxt_capture_mixers[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = conexant_mux_enum_info,
- .get = conexant_mux_enum_get,
- .put = conexant_mux_enum_put
- },
- {}
-};
-
-#ifdef CONFIG_SND_HDA_INPUT_BEEP
-/* additional beep mixers; the actual parameters are overwritten at build */
-static const struct snd_kcontrol_new cxt_beep_mixer[] = {
- HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT),
- HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT),
- { } /* end */
-};
-#endif
-
-static const char * const slave_pfxs[] = {
- "Headphone", "Speaker", "Front", "Surround", "CLFE",
- NULL
-};
-
-static int conexant_build_controls(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- unsigned int i;
- int err;
-
- for (i = 0; i < spec->num_mixers; i++) {
- err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
- if (err < 0)
- return err;
- }
- if (spec->multiout.dig_out_nid) {
- err = snd_hda_create_spdif_out_ctls(codec,
- spec->multiout.dig_out_nid,
- spec->multiout.dig_out_nid);
- if (err < 0)
- return err;
- err = snd_hda_create_spdif_share_sw(codec,
- &spec->multiout);
- if (err < 0)
- return err;
- spec->multiout.share_spdif = 1;
- }
- if (spec->dig_in_nid) {
- err = snd_hda_create_spdif_in_ctls(codec,spec->dig_in_nid);
- if (err < 0)
- return err;
- }
-
- /* if we have no master control, let's create it */
- if (spec->vmaster_nid &&
- !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
- unsigned int vmaster_tlv[4];
- snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
- HDA_OUTPUT, vmaster_tlv);
- err = snd_hda_add_vmaster(codec, "Master Playback Volume",
- vmaster_tlv, slave_pfxs,
- "Playback Volume");
- if (err < 0)
- return err;
- }
- if (spec->vmaster_nid &&
- !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
- err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
- NULL, slave_pfxs,
- "Playback Switch", true,
- &spec->vmaster_mute.sw_kctl);
- if (err < 0)
- return err;
- }
-
- if (spec->input_mux) {
- err = snd_hda_add_new_ctls(codec, cxt_capture_mixers);
- if (err < 0)
- return err;
- }
-
-#ifdef CONFIG_SND_HDA_INPUT_BEEP
- /* create beep controls if needed */
- if (spec->beep_amp) {
- const struct snd_kcontrol_new *knew;
- for (knew = cxt_beep_mixer; knew->name; knew++) {
- struct snd_kcontrol *kctl;
- kctl = snd_ctl_new1(knew, codec);
- if (!kctl)
- return -ENOMEM;
- kctl->private_value = spec->beep_amp;
- err = snd_hda_ctl_add(codec, 0, kctl);
- if (err < 0)
- return err;
- }
- }
-#endif
-
- return 0;
-}
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static int conexant_suspend(struct hda_codec *codec, pm_message_t state)
-{
- snd_hda_shutup_pins(codec);
- return 0;
-}
-#endif
-
-static const struct hda_codec_ops conexant_patch_ops = {
- .build_controls = conexant_build_controls,
- .build_pcms = conexant_build_pcms,
- .init = conexant_init,
- .free = conexant_free,
- .set_power_state = conexant_set_power,
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- .suspend = conexant_suspend,
-#endif
- .reboot_notify = snd_hda_shutup_pins,
-};
-
-#ifdef CONFIG_SND_HDA_INPUT_BEEP
-#define set_beep_amp(spec, nid, idx, dir) \
- ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir))
-#else
-#define set_beep_amp(spec, nid, idx, dir) /* NOP */
-#endif
-
-static int patch_conexant_auto(struct hda_codec *codec);
-/*
- * EAPD control
- * the private value = nid | (invert << 8)
- */
-
-#define cxt_eapd_info snd_ctl_boolean_mono_info
-
-static int cxt_eapd_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
- int invert = (kcontrol->private_value >> 8) & 1;
- if (invert)
- ucontrol->value.integer.value[0] = !spec->cur_eapd;
- else
- ucontrol->value.integer.value[0] = spec->cur_eapd;
- return 0;
-
-}
-
-static int cxt_eapd_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
- int invert = (kcontrol->private_value >> 8) & 1;
- hda_nid_t nid = kcontrol->private_value & 0xff;
- unsigned int eapd;
-
- eapd = !!ucontrol->value.integer.value[0];
- if (invert)
- eapd = !eapd;
- if (eapd == spec->cur_eapd)
- return 0;
-
- spec->cur_eapd = eapd;
- snd_hda_codec_write_cache(codec, nid,
- 0, AC_VERB_SET_EAPD_BTLENABLE,
- eapd ? 0x02 : 0x00);
- return 1;
-}
-
-/* controls for test mode */
-#ifdef CONFIG_SND_DEBUG
-
-#define CXT_EAPD_SWITCH(xname, nid, mask) \
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
- .info = cxt_eapd_info, \
- .get = cxt_eapd_get, \
- .put = cxt_eapd_put, \
- .private_value = nid | (mask<<16) }
-
-
-
-static int conexant_ch_mode_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
- return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
- spec->num_channel_mode);
-}
-
-static int conexant_ch_mode_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
- return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
- spec->num_channel_mode,
- spec->multiout.max_channels);
-}
-
-static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
- int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
- spec->num_channel_mode,
- &spec->multiout.max_channels);
- if (err >= 0 && spec->need_dac_fix)
- spec->multiout.num_dacs = spec->multiout.max_channels / 2;
- return err;
-}
-
-#define CXT_PIN_MODE(xname, nid, dir) \
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
- .info = conexant_ch_mode_info, \
- .get = conexant_ch_mode_get, \
- .put = conexant_ch_mode_put, \
- .private_value = nid | (dir<<16) }
-
-#endif /* CONFIG_SND_DEBUG */
-
-/* Conexant 5045 specific */
-
-static const hda_nid_t cxt5045_dac_nids[1] = { 0x19 };
-static const hda_nid_t cxt5045_adc_nids[1] = { 0x1a };
-static const hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a };
-#define CXT5045_SPDIF_OUT 0x18
-
-static const struct hda_channel_mode cxt5045_modes[1] = {
- { 2, NULL },
-};
-
-static const struct hda_input_mux cxt5045_capture_source = {
- .num_items = 2,
- .items = {
- { "Internal Mic", 0x1 },
- { "Mic", 0x2 },
- }
-};
-
-static const struct hda_input_mux cxt5045_capture_source_benq = {
- .num_items = 4,
- .items = {
- { "Internal Mic", 0x1 },
- { "Mic", 0x2 },
- { "Line", 0x3 },
- { "Mixer", 0x0 },
- }
-};
-
-static const struct hda_input_mux cxt5045_capture_source_hp530 = {
- .num_items = 2,
- .items = {
- { "Mic", 0x1 },
- { "Internal Mic", 0x2 },
- }
-};
-
-/* turn on/off EAPD (+ mute HP) as a master switch */
-static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
- unsigned int bits;
-
- if (!cxt_eapd_put(kcontrol, ucontrol))
- return 0;
-
- /* toggle internal speakers mute depending of presence of
- * the headphone jack
- */
- bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
- snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, bits);
-
- bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
- snd_hda_codec_amp_stereo(codec, 0x11, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, bits);
- return 1;
-}
-
-/* bind volumes of both NID 0x10 and 0x11 */
-static const struct hda_bind_ctls cxt5045_hp_bind_master_vol = {
- .ops = &snd_hda_bind_vol,
- .values = {
- HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT),
- HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
- 0
- },
-};
-
-/* toggle input of built-in and mic jack appropriately */
-static void cxt5045_hp_automic(struct hda_codec *codec)
-{
- static const struct hda_verb mic_jack_on[] = {
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
- {}
- };
- static const struct hda_verb mic_jack_off[] = {
- {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
- {}
- };
- unsigned int present;
-
- present = snd_hda_jack_detect(codec, 0x12);
- if (present)
- snd_hda_sequence_write(codec, mic_jack_on);
- else
- snd_hda_sequence_write(codec, mic_jack_off);
-}
-
-
-/* mute internal speaker if HP is plugged */
-static void cxt5045_hp_automute(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- unsigned int bits;
-
- spec->hp_present = snd_hda_jack_detect(codec, 0x11);
-
- bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0;
- snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, bits);
-}
-
-/* unsolicited event for HP jack sensing */
-static void cxt5045_hp_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- res >>= 26;
- switch (res) {
- case CONEXANT_HP_EVENT:
- cxt5045_hp_automute(codec);
- break;
- case CONEXANT_MIC_EVENT:
- cxt5045_hp_automic(codec);
- break;
-
- }
-}
-
-static const struct snd_kcontrol_new cxt5045_mixers[] = {
- HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x00, HDA_INPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
- HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = cxt_eapd_info,
- .get = cxt_eapd_get,
- .put = cxt5045_hp_master_sw_put,
- .private_value = 0x10,
- },
-
- {}
-};
-
-static const struct snd_kcontrol_new cxt5045_benq_mixers[] = {
- HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x3, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x3, HDA_INPUT),
-
- {}
-};
-
-static const struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
- HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x00, HDA_INPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
- HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
- HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = cxt_eapd_info,
- .get = cxt_eapd_get,
- .put = cxt5045_hp_master_sw_put,
- .private_value = 0x10,
- },
-
- {}
-};
-
-static const struct hda_verb cxt5045_init_verbs[] = {
- /* Line in, Mic */
- {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
- /* HP, Amp */
- {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
- {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x11, AC_VERB_SET_CONNECT_SEL, 0x1},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- /* Record selector: Internal mic */
- {0x1a, AC_VERB_SET_CONNECT_SEL,0x1},
- {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
- AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
- /* SPDIF route: PCM */
- {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- { 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 },
- /* EAPD */
- {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */
- { } /* end */
-};
-
-static const struct hda_verb cxt5045_benq_init_verbs[] = {
- /* Internal Mic, Mic */
- {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
- /* Line In,HP, Amp */
- {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
- {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
- {0x11, AC_VERB_SET_CONNECT_SEL, 0x1},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- /* Record selector: Internal mic */
- {0x1a, AC_VERB_SET_CONNECT_SEL, 0x1},
- {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
- AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
- /* SPDIF route: PCM */
- {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
- /* EAPD */
- {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
- { } /* end */
-};
-
-static const struct hda_verb cxt5045_hp_sense_init_verbs[] = {
- /* pin sensing on HP jack */
- {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
- { } /* end */
-};
-
-static const struct hda_verb cxt5045_mic_sense_init_verbs[] = {
- /* pin sensing on HP jack */
- {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
- { } /* end */
-};
-
-#ifdef CONFIG_SND_DEBUG
-/* Test configuration for debugging, modelled after the ALC260 test
- * configuration.
- */
-static const struct hda_input_mux cxt5045_test_capture_source = {
- .num_items = 5,
- .items = {
- { "MIXER", 0x0 },
- { "MIC1 pin", 0x1 },
- { "LINE1 pin", 0x2 },
- { "HP-OUT pin", 0x3 },
- { "CD pin", 0x4 },
- },
-};
-
-static const struct snd_kcontrol_new cxt5045_test_mixer[] = {
-
- /* Output controls */
- HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("HP-OUT Playback Volume", 0x11, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("HP-OUT Playback Switch", 0x11, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x12, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("LINE1 Playback Switch", 0x12, 0x0, HDA_OUTPUT),
-
- /* Modes for retasking pin widgets */
- CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT),
- CXT_PIN_MODE("LINE1 pin mode", 0x12, CXT_PIN_DIR_INOUT),
-
- /* EAPD Switch Control */
- CXT_EAPD_SWITCH("External Amplifier", 0x10, 0x0),
-
- /* Loopback mixer controls */
-
- HDA_CODEC_VOLUME("PCM Volume", 0x17, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("PCM Switch", 0x17, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("MIC1 pin Volume", 0x17, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("MIC1 pin Switch", 0x17, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("LINE1 pin Volume", 0x17, 0x2, HDA_INPUT),
- HDA_CODEC_MUTE("LINE1 pin Switch", 0x17, 0x2, HDA_INPUT),
- HDA_CODEC_VOLUME("HP-OUT pin Volume", 0x17, 0x3, HDA_INPUT),
- HDA_CODEC_MUTE("HP-OUT pin Switch", 0x17, 0x3, HDA_INPUT),
- HDA_CODEC_VOLUME("CD pin Volume", 0x17, 0x4, HDA_INPUT),
- HDA_CODEC_MUTE("CD pin Switch", 0x17, 0x4, HDA_INPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input Source",
- .info = conexant_mux_enum_info,
- .get = conexant_mux_enum_get,
- .put = conexant_mux_enum_put,
- },
- /* Audio input controls */
- HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT),
- { } /* end */
-};
-
-static const struct hda_verb cxt5045_test_init_verbs[] = {
- /* Set connections */
- { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
- { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 },
- { 0x12, AC_VERB_SET_CONNECT_SEL, 0x0 },
- /* Enable retasking pins as output, initially without power amp */
- {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-
- /* Disable digital (SPDIF) pins initially, but users can enable
- * them via a mixer switch. In the case of SPDIF-out, this initverb
- * payload also sets the generation to 0, output to be in "consumer"
- * PCM format, copyright asserted, no pre-emphasis and no validity
- * control.
- */
- {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
-
- /* Unmute retasking pin widget output buffers since the default
- * state appears to be output. As the pin mode is changed by the
- * user the pin mode control will take care of enabling the pin's
- * input/output buffers as needed.
- */
- {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
- /* Mute capture amp left and right */
- {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-
- /* Set ADC connection select to match default mixer setting (mic1
- * pin)
- */
- {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
- {0x17, AC_VERB_SET_CONNECT_SEL, 0x01},
-
- /* Mute all inputs to mixer widget (even unconnected ones) */
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer */
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* Mic1 pin */
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* Line pin */
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* HP pin */
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
-
- { }
-};
-#endif
-
-
-/* initialize jack-sensing, too */
-static int cxt5045_init(struct hda_codec *codec)
-{
- conexant_init(codec);
- cxt5045_hp_automute(codec);
- return 0;
-}
-
-
-enum {
- CXT5045_LAPTOP_HPSENSE,
- CXT5045_LAPTOP_MICSENSE,
- CXT5045_LAPTOP_HPMICSENSE,
- CXT5045_BENQ,
- CXT5045_LAPTOP_HP530,
-#ifdef CONFIG_SND_DEBUG
- CXT5045_TEST,
-#endif
- CXT5045_AUTO,
- CXT5045_MODELS
-};
-
-static const char * const cxt5045_models[CXT5045_MODELS] = {
- [CXT5045_LAPTOP_HPSENSE] = "laptop-hpsense",
- [CXT5045_LAPTOP_MICSENSE] = "laptop-micsense",
- [CXT5045_LAPTOP_HPMICSENSE] = "laptop-hpmicsense",
- [CXT5045_BENQ] = "benq",
- [CXT5045_LAPTOP_HP530] = "laptop-hp530",
-#ifdef CONFIG_SND_DEBUG
- [CXT5045_TEST] = "test",
-#endif
- [CXT5045_AUTO] = "auto",
-};
-
-static const struct snd_pci_quirk cxt5045_cfg_tbl[] = {
- SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530),
- SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE),
- SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ),
- SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE),
- SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP_HPMICSENSE),
- SND_PCI_QUIRK(0x1734, 0x110e, "Fujitsu V5505",
- CXT5045_LAPTOP_HPMICSENSE),
- SND_PCI_QUIRK(0x1509, 0x1e40, "FIC", CXT5045_LAPTOP_HPMICSENSE),
- SND_PCI_QUIRK(0x1509, 0x2f05, "FIC", CXT5045_LAPTOP_HPMICSENSE),
- SND_PCI_QUIRK(0x1509, 0x2f06, "FIC", CXT5045_LAPTOP_HPMICSENSE),
- SND_PCI_QUIRK_MASK(0x1631, 0xff00, 0xc100, "Packard Bell",
- CXT5045_LAPTOP_HPMICSENSE),
- SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP_HPSENSE),
- {}
-};
-
-static int patch_cxt5045(struct hda_codec *codec)
-{
- struct conexant_spec *spec;
- int board_config;
-
- board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
- cxt5045_models,
- cxt5045_cfg_tbl);
- if (board_config < 0)
- board_config = CXT5045_AUTO; /* model=auto as default */
- if (board_config == CXT5045_AUTO)
- return patch_conexant_auto(codec);
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- codec->spec = spec;
- codec->single_adc_amp = 1;
-
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = ARRAY_SIZE(cxt5045_dac_nids);
- spec->multiout.dac_nids = cxt5045_dac_nids;
- spec->multiout.dig_out_nid = CXT5045_SPDIF_OUT;
- spec->num_adc_nids = 1;
- spec->adc_nids = cxt5045_adc_nids;
- spec->capsrc_nids = cxt5045_capsrc_nids;
- spec->input_mux = &cxt5045_capture_source;
- spec->num_mixers = 1;
- spec->mixers[0] = cxt5045_mixers;
- spec->num_init_verbs = 1;
- spec->init_verbs[0] = cxt5045_init_verbs;
- spec->spdif_route = 0;
- spec->num_channel_mode = ARRAY_SIZE(cxt5045_modes);
- spec->channel_mode = cxt5045_modes;
-
- set_beep_amp(spec, 0x16, 0, 1);
-
- codec->patch_ops = conexant_patch_ops;
-
- switch (board_config) {
- case CXT5045_LAPTOP_HPSENSE:
- codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
- spec->input_mux = &cxt5045_capture_source;
- spec->num_init_verbs = 2;
- spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
- spec->mixers[0] = cxt5045_mixers;
- codec->patch_ops.init = cxt5045_init;
- break;
- case CXT5045_LAPTOP_MICSENSE:
- codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
- spec->input_mux = &cxt5045_capture_source;
- spec->num_init_verbs = 2;
- spec->init_verbs[1] = cxt5045_mic_sense_init_verbs;
- spec->mixers[0] = cxt5045_mixers;
- codec->patch_ops.init = cxt5045_init;
- break;
- default:
- case CXT5045_LAPTOP_HPMICSENSE:
- codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
- spec->input_mux = &cxt5045_capture_source;
- spec->num_init_verbs = 3;
- spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
- spec->init_verbs[2] = cxt5045_mic_sense_init_verbs;
- spec->mixers[0] = cxt5045_mixers;
- codec->patch_ops.init = cxt5045_init;
- break;
- case CXT5045_BENQ:
- codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
- spec->input_mux = &cxt5045_capture_source_benq;
- spec->num_init_verbs = 1;
- spec->init_verbs[0] = cxt5045_benq_init_verbs;
- spec->mixers[0] = cxt5045_mixers;
- spec->mixers[1] = cxt5045_benq_mixers;
- spec->num_mixers = 2;
- codec->patch_ops.init = cxt5045_init;
- break;
- case CXT5045_LAPTOP_HP530:
- codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
- spec->input_mux = &cxt5045_capture_source_hp530;
- spec->num_init_verbs = 2;
- spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
- spec->mixers[0] = cxt5045_mixers_hp530;
- codec->patch_ops.init = cxt5045_init;
- break;
-#ifdef CONFIG_SND_DEBUG
- case CXT5045_TEST:
- spec->input_mux = &cxt5045_test_capture_source;
- spec->mixers[0] = cxt5045_test_mixer;
- spec->init_verbs[0] = cxt5045_test_init_verbs;
- break;
-
-#endif
- }
-
- switch (codec->subsystem_id >> 16) {
- case 0x103c:
- case 0x1631:
- case 0x1734:
- case 0x17aa:
- /* HP, Packard Bell, Fujitsu-Siemens & Lenovo laptops have
- * really bad sound over 0dB on NID 0x17. Fix max PCM level to
- * 0 dB (originally it has 0x2b steps with 0dB offset 0x14)
- */
- snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT,
- (0x14 << AC_AMPCAP_OFFSET_SHIFT) |
- (0x14 << AC_AMPCAP_NUM_STEPS_SHIFT) |
- (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
- (1 << AC_AMPCAP_MUTE_SHIFT));
- break;
- }
-
- if (spec->beep_amp)
- snd_hda_attach_beep_device(codec, spec->beep_amp);
-
- return 0;
-}
-
-
-/* Conexant 5047 specific */
-#define CXT5047_SPDIF_OUT 0x11
-
-static const hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; /* 0x1c */
-static const hda_nid_t cxt5047_adc_nids[1] = { 0x12 };
-static const hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a };
-
-static const struct hda_channel_mode cxt5047_modes[1] = {
- { 2, NULL },
-};
-
-static const struct hda_input_mux cxt5047_toshiba_capture_source = {
- .num_items = 2,
- .items = {
- { "ExtMic", 0x2 },
- { "Line-In", 0x1 },
- }
-};
-
-/* turn on/off EAPD (+ mute HP) as a master switch */
-static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
- unsigned int bits;
-
- if (!cxt_eapd_put(kcontrol, ucontrol))
- return 0;
-
- /* toggle internal speakers mute depending of presence of
- * the headphone jack
- */
- bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
- /* NOTE: Conexat codec needs the index for *OUTPUT* amp of
- * pin widgets unlike other codecs. In this case, we need to
- * set index 0x01 for the volume from the mixer amp 0x19.
- */
- snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0x01,
- HDA_AMP_MUTE, bits);
- bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
- snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, bits);
- return 1;
-}
-
-/* mute internal speaker if HP is plugged */
-static void cxt5047_hp_automute(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- unsigned int bits;
-
- spec->hp_present = snd_hda_jack_detect(codec, 0x13);
-
- bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0;
- /* See the note in cxt5047_hp_master_sw_put */
- snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0x01,
- HDA_AMP_MUTE, bits);
-}
-
-/* toggle input of built-in and mic jack appropriately */
-static void cxt5047_hp_automic(struct hda_codec *codec)
-{
- static const struct hda_verb mic_jack_on[] = {
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {}
- };
- static const struct hda_verb mic_jack_off[] = {
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {}
- };
- unsigned int present;
-
- present = snd_hda_jack_detect(codec, 0x15);
- if (present)
- snd_hda_sequence_write(codec, mic_jack_on);
- else
- snd_hda_sequence_write(codec, mic_jack_off);
-}
-
-/* unsolicited event for HP jack sensing */
-static void cxt5047_hp_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- switch (res >> 26) {
- case CONEXANT_HP_EVENT:
- cxt5047_hp_automute(codec);
- break;
- case CONEXANT_MIC_EVENT:
- cxt5047_hp_automic(codec);
- break;
- }
-}
-
-static const struct snd_kcontrol_new cxt5047_base_mixers[] = {
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
- HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
- HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = cxt_eapd_info,
- .get = cxt_eapd_get,
- .put = cxt5047_hp_master_sw_put,
- .private_value = 0x13,
- },
-
- {}
-};
-
-static const struct snd_kcontrol_new cxt5047_hp_spk_mixers[] = {
- /* See the note in cxt5047_hp_master_sw_put */
- HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x01, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT),
- {}
-};
-
-static const struct snd_kcontrol_new cxt5047_hp_only_mixers[] = {
- HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT),
- { } /* end */
-};
-
-static const struct hda_verb cxt5047_init_verbs[] = {
- /* Line in, Mic, Built-in Mic */
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
- {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
- /* HP, Speaker */
- {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
- {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, /* mixer(0x19) */
- {0x1d, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mixer(0x19) */
- /* Record selector: Mic */
- {0x12, AC_VERB_SET_CONNECT_SEL,0x03},
- {0x19, AC_VERB_SET_AMP_GAIN_MUTE,
- AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
- {0x1A, AC_VERB_SET_CONNECT_SEL,0x02},
- {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
- AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
- {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
- AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
- /* SPDIF route: PCM */
- { 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 },
- /* Enable unsolicited events */
- {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
- {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
- { } /* end */
-};
-
-/* configuration for Toshiba Laptops */
-static const struct hda_verb cxt5047_toshiba_init_verbs[] = {
- {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0}, /* default off */
- {}
-};
-
-/* Test configuration for debugging, modelled after the ALC260 test
- * configuration.
- */
-#ifdef CONFIG_SND_DEBUG
-static const struct hda_input_mux cxt5047_test_capture_source = {
- .num_items = 4,
- .items = {
- { "LINE1 pin", 0x0 },
- { "MIC1 pin", 0x1 },
- { "MIC2 pin", 0x2 },
- { "CD pin", 0x3 },
- },
-};
-
-static const struct snd_kcontrol_new cxt5047_test_mixer[] = {
-
- /* Output only controls */
- HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("OutAmp-1 Switch", 0x10,0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("OutAmp-2 Volume", 0x1c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("OutAmp-2 Switch", 0x1c, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("HeadPhone Playback Volume", 0x13, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("HeadPhone Playback Switch", 0x13, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Line1-Out Playback Volume", 0x14, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Line1-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Line2-Out Playback Volume", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Line2-Out Playback Switch", 0x15, 0x0, HDA_OUTPUT),
-
- /* Modes for retasking pin widgets */
- CXT_PIN_MODE("LINE1 pin mode", 0x14, CXT_PIN_DIR_INOUT),
- CXT_PIN_MODE("MIC1 pin mode", 0x15, CXT_PIN_DIR_INOUT),
-
- /* EAPD Switch Control */
- CXT_EAPD_SWITCH("External Amplifier", 0x13, 0x0),
-
- /* Loopback mixer controls */
- HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x12, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("MIC1 Playback Switch", 0x12, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x12, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("MIC2 Playback Switch", 0x12, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("LINE Playback Volume", 0x12, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("LINE Playback Switch", 0x12, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x12, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x12, 0x04, HDA_INPUT),
-
- HDA_CODEC_VOLUME("Capture-1 Volume", 0x19, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Capture-1 Switch", 0x19, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Capture-2 Volume", 0x19, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Capture-2 Switch", 0x19, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Capture-3 Volume", 0x19, 0x2, HDA_INPUT),
- HDA_CODEC_MUTE("Capture-3 Switch", 0x19, 0x2, HDA_INPUT),
- HDA_CODEC_VOLUME("Capture-4 Volume", 0x19, 0x3, HDA_INPUT),
- HDA_CODEC_MUTE("Capture-4 Switch", 0x19, 0x3, HDA_INPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input Source",
- .info = conexant_mux_enum_info,
- .get = conexant_mux_enum_get,
- .put = conexant_mux_enum_put,
- },
- HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT),
-
- { } /* end */
-};
-
-static const struct hda_verb cxt5047_test_init_verbs[] = {
- /* Enable retasking pins as output, initially without power amp */
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-
- /* Disable digital (SPDIF) pins initially, but users can enable
- * them via a mixer switch. In the case of SPDIF-out, this initverb
- * payload also sets the generation to 0, output to be in "consumer"
- * PCM format, copyright asserted, no pre-emphasis and no validity
- * control.
- */
- {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
-
- /* Ensure mic1, mic2, line1 pin widgets take input from the
- * OUT1 sum bus when acting as an output.
- */
- {0x1a, AC_VERB_SET_CONNECT_SEL, 0},
- {0x1b, AC_VERB_SET_CONNECT_SEL, 0},
-
- /* Start with output sum widgets muted and their output gains at min */
- {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-
- /* Unmute retasking pin widget output buffers since the default
- * state appears to be output. As the pin mode is changed by the
- * user the pin mode control will take care of enabling the pin's
- * input/output buffers as needed.
- */
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
- /* Mute capture amp left and right */
- {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-
- /* Set ADC connection select to match default mixer setting (mic1
- * pin)
- */
- {0x12, AC_VERB_SET_CONNECT_SEL, 0x00},
-
- /* Mute all inputs to mixer widget (even unconnected ones) */
- {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
- {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
- {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
- {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
- {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
- {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
- {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
- {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
-
- { }
-};
-#endif
-
-
-/* initialize jack-sensing, too */
-static int cxt5047_hp_init(struct hda_codec *codec)
-{
- conexant_init(codec);
- cxt5047_hp_automute(codec);
- return 0;
-}
-
-
-enum {
- CXT5047_LAPTOP, /* Laptops w/o EAPD support */
- CXT5047_LAPTOP_HP, /* Some HP laptops */
- CXT5047_LAPTOP_EAPD, /* Laptops with EAPD support */
-#ifdef CONFIG_SND_DEBUG
- CXT5047_TEST,
-#endif
- CXT5047_AUTO,
- CXT5047_MODELS
-};
-
-static const char * const cxt5047_models[CXT5047_MODELS] = {
- [CXT5047_LAPTOP] = "laptop",
- [CXT5047_LAPTOP_HP] = "laptop-hp",
- [CXT5047_LAPTOP_EAPD] = "laptop-eapd",
-#ifdef CONFIG_SND_DEBUG
- [CXT5047_TEST] = "test",
-#endif
- [CXT5047_AUTO] = "auto",
-};
-
-static const struct snd_pci_quirk cxt5047_cfg_tbl[] = {
- SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP),
- SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
- CXT5047_LAPTOP),
- SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD),
- {}
-};
-
-static int patch_cxt5047(struct hda_codec *codec)
-{
- struct conexant_spec *spec;
- int board_config;
-
- board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
- cxt5047_models,
- cxt5047_cfg_tbl);
- if (board_config < 0)
- board_config = CXT5047_AUTO; /* model=auto as default */
- if (board_config == CXT5047_AUTO)
- return patch_conexant_auto(codec);
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- codec->spec = spec;
- codec->pin_amp_workaround = 1;
-
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = ARRAY_SIZE(cxt5047_dac_nids);
- spec->multiout.dac_nids = cxt5047_dac_nids;
- spec->multiout.dig_out_nid = CXT5047_SPDIF_OUT;
- spec->num_adc_nids = 1;
- spec->adc_nids = cxt5047_adc_nids;
- spec->capsrc_nids = cxt5047_capsrc_nids;
- spec->num_mixers = 1;
- spec->mixers[0] = cxt5047_base_mixers;
- spec->num_init_verbs = 1;
- spec->init_verbs[0] = cxt5047_init_verbs;
- spec->spdif_route = 0;
- spec->num_channel_mode = ARRAY_SIZE(cxt5047_modes),
- spec->channel_mode = cxt5047_modes,
-
- codec->patch_ops = conexant_patch_ops;
-
- switch (board_config) {
- case CXT5047_LAPTOP:
- spec->num_mixers = 2;
- spec->mixers[1] = cxt5047_hp_spk_mixers;
- codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
- break;
- case CXT5047_LAPTOP_HP:
- spec->num_mixers = 2;
- spec->mixers[1] = cxt5047_hp_only_mixers;
- codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
- codec->patch_ops.init = cxt5047_hp_init;
- break;
- case CXT5047_LAPTOP_EAPD:
- spec->input_mux = &cxt5047_toshiba_capture_source;
- spec->num_mixers = 2;
- spec->mixers[1] = cxt5047_hp_spk_mixers;
- spec->num_init_verbs = 2;
- spec->init_verbs[1] = cxt5047_toshiba_init_verbs;
- codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
- break;
-#ifdef CONFIG_SND_DEBUG
- case CXT5047_TEST:
- spec->input_mux = &cxt5047_test_capture_source;
- spec->mixers[0] = cxt5047_test_mixer;
- spec->init_verbs[0] = cxt5047_test_init_verbs;
- codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
-#endif
- }
- spec->vmaster_nid = 0x13;
-
- switch (codec->subsystem_id >> 16) {
- case 0x103c:
- /* HP laptops have really bad sound over 0 dB on NID 0x10.
- * Fix max PCM level to 0 dB (originally it has 0x1e steps
- * with 0 dB offset 0x17)
- */
- snd_hda_override_amp_caps(codec, 0x10, HDA_INPUT,
- (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
- (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
- (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
- (1 << AC_AMPCAP_MUTE_SHIFT));
- break;
- }
-
- return 0;
-}
-
-/* Conexant 5051 specific */
-static const hda_nid_t cxt5051_dac_nids[1] = { 0x10 };
-static const hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 };
-
-static const struct hda_channel_mode cxt5051_modes[1] = {
- { 2, NULL },
-};
-
-static void cxt5051_update_speaker(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- unsigned int pinctl;
- /* headphone pin */
- pinctl = (spec->hp_present && spec->cur_eapd) ? PIN_HP : 0;
- snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
- pinctl);
- /* speaker pin */
- pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
- snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
- pinctl);
- /* on ideapad there is an additional speaker (subwoofer) to mute */
- if (spec->ideapad)
- snd_hda_codec_write(codec, 0x1b, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- pinctl);
-}
-
-/* turn on/off EAPD (+ mute HP) as a master switch */
-static int cxt5051_hp_master_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-
- if (!cxt_eapd_put(kcontrol, ucontrol))
- return 0;
- cxt5051_update_speaker(codec);
- return 1;
-}
-
-/* toggle input of built-in and mic jack appropriately */
-static void cxt5051_portb_automic(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- unsigned int present;
-
- if (!(spec->auto_mic & AUTO_MIC_PORTB))
- return;
- present = snd_hda_jack_detect(codec, 0x17);
- snd_hda_codec_write(codec, 0x14, 0,
- AC_VERB_SET_CONNECT_SEL,
- present ? 0x01 : 0x00);
-}
-
-/* switch the current ADC according to the jack state */
-static void cxt5051_portc_automic(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- unsigned int present;
- hda_nid_t new_adc;
-
- if (!(spec->auto_mic & AUTO_MIC_PORTC))
- return;
- present = snd_hda_jack_detect(codec, 0x18);
- if (present)
- spec->cur_adc_idx = 1;
- else
- spec->cur_adc_idx = 0;
- new_adc = spec->adc_nids[spec->cur_adc_idx];
- if (spec->cur_adc && spec->cur_adc != new_adc) {
- /* stream is running, let's swap the current ADC */
- __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
- spec->cur_adc = new_adc;
- snd_hda_codec_setup_stream(codec, new_adc,
- spec->cur_adc_stream_tag, 0,
- spec->cur_adc_format);
- }
-}
-
-/* mute internal speaker if HP is plugged */
-static void cxt5051_hp_automute(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
-
- spec->hp_present = snd_hda_jack_detect(codec, 0x16);
- cxt5051_update_speaker(codec);
-}
-
-/* unsolicited event for HP jack sensing */
-static void cxt5051_hp_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- switch (res >> 26) {
- case CONEXANT_HP_EVENT:
- cxt5051_hp_automute(codec);
- break;
- case CXT5051_PORTB_EVENT:
- cxt5051_portb_automic(codec);
- break;
- case CXT5051_PORTC_EVENT:
- cxt5051_portc_automic(codec);
- break;
- }
-}
-
-static const struct snd_kcontrol_new cxt5051_playback_mixers[] = {
- HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = cxt_eapd_info,
- .get = cxt_eapd_get,
- .put = cxt5051_hp_master_sw_put,
- .private_value = 0x1a,
- },
- {}
-};
-
-static const struct snd_kcontrol_new cxt5051_capture_mixers[] = {
- HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
- HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
- HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
- {}
-};
-
-static const struct snd_kcontrol_new cxt5051_hp_mixers[] = {
- HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
- HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Volume", 0x15, 0x00, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Switch", 0x15, 0x00, HDA_INPUT),
- {}
-};
-
-static const struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = {
- HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT),
- {}
-};
-
-static const struct snd_kcontrol_new cxt5051_f700_mixers[] = {
- HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT),
- {}
-};
-
-static const struct snd_kcontrol_new cxt5051_toshiba_mixers[] = {
- HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
- HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
- {}
-};
-
-static const struct hda_verb cxt5051_init_verbs[] = {
- /* Line in, Mic */
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
- {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
- {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
- {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
- /* SPK */
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
- /* HP, Amp */
- {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
- /* DAC1 */
- {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* Record selector: Internal mic */
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
- /* SPDIF route: PCM */
- {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
- /* EAPD */
- {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
- {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
- { } /* end */
-};
-
-static const struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
- /* Line in, Mic */
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
- {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
- {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
- /* SPK */
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
- /* HP, Amp */
- {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
- /* DAC1 */
- {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* Record selector: Internal mic */
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
- {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
- /* SPDIF route: PCM */
- {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
- /* EAPD */
- {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
- {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
- { } /* end */
-};
-
-static const struct hda_verb cxt5051_f700_init_verbs[] = {
- /* Line in, Mic */
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
- {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
- {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
- /* SPK */
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
- /* HP, Amp */
- {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
- /* DAC1 */
- {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* Record selector: Internal mic */
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
- {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
- /* SPDIF route: PCM */
- {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
- /* EAPD */
- {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
- {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
- { } /* end */
-};
-
-static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid,
- unsigned int event)
-{
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | event);
-}
-
-static const struct hda_verb cxt5051_ideapad_init_verbs[] = {
- /* Subwoofer */
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
- { } /* end */
-};
-
-/* initialize jack-sensing, too */
-static int cxt5051_init(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
-
- conexant_init(codec);
-
- if (spec->auto_mic & AUTO_MIC_PORTB)
- cxt5051_init_mic_port(codec, 0x17, CXT5051_PORTB_EVENT);
- if (spec->auto_mic & AUTO_MIC_PORTC)
- cxt5051_init_mic_port(codec, 0x18, CXT5051_PORTC_EVENT);
-
- if (codec->patch_ops.unsol_event) {
- cxt5051_hp_automute(codec);
- cxt5051_portb_automic(codec);
- cxt5051_portc_automic(codec);
- }
- return 0;
-}
-
-
-enum {
- CXT5051_LAPTOP, /* Laptops w/ EAPD support */
- CXT5051_HP, /* no docking */
- CXT5051_HP_DV6736, /* HP without mic switch */
- CXT5051_F700, /* HP Compaq Presario F700 */
- CXT5051_TOSHIBA, /* Toshiba M300 & co */
- CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */
- CXT5051_AUTO, /* auto-parser */
- CXT5051_MODELS
-};
-
-static const char *const cxt5051_models[CXT5051_MODELS] = {
- [CXT5051_LAPTOP] = "laptop",
- [CXT5051_HP] = "hp",
- [CXT5051_HP_DV6736] = "hp-dv6736",
- [CXT5051_F700] = "hp-700",
- [CXT5051_TOSHIBA] = "toshiba",
- [CXT5051_IDEAPAD] = "ideapad",
- [CXT5051_AUTO] = "auto",
-};
-
-static const struct snd_pci_quirk cxt5051_cfg_tbl[] = {
- SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
- SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
- SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700),
- SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba M30x", CXT5051_TOSHIBA),
- SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
- CXT5051_LAPTOP),
- SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
- SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo IdeaPad", CXT5051_IDEAPAD),
- {}
-};
-
-static int patch_cxt5051(struct hda_codec *codec)
-{
- struct conexant_spec *spec;
- int board_config;
-
- board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
- cxt5051_models,
- cxt5051_cfg_tbl);
- if (board_config < 0)
- board_config = CXT5051_AUTO; /* model=auto as default */
- if (board_config == CXT5051_AUTO)
- return patch_conexant_auto(codec);
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- codec->spec = spec;
- codec->pin_amp_workaround = 1;
-
- codec->patch_ops = conexant_patch_ops;
- codec->patch_ops.init = cxt5051_init;
-
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = ARRAY_SIZE(cxt5051_dac_nids);
- spec->multiout.dac_nids = cxt5051_dac_nids;
- spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT;
- spec->num_adc_nids = 1; /* not 2; via auto-mic switch */
- spec->adc_nids = cxt5051_adc_nids;
- spec->num_mixers = 2;
- spec->mixers[0] = cxt5051_capture_mixers;
- spec->mixers[1] = cxt5051_playback_mixers;
- spec->num_init_verbs = 1;
- spec->init_verbs[0] = cxt5051_init_verbs;
- spec->spdif_route = 0;
- spec->num_channel_mode = ARRAY_SIZE(cxt5051_modes);
- spec->channel_mode = cxt5051_modes;
- spec->cur_adc = 0;
- spec->cur_adc_idx = 0;
-
- set_beep_amp(spec, 0x13, 0, HDA_OUTPUT);
-
- codec->patch_ops.unsol_event = cxt5051_hp_unsol_event;
-
- spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC;
- switch (board_config) {
- case CXT5051_HP:
- spec->mixers[0] = cxt5051_hp_mixers;
- break;
- case CXT5051_HP_DV6736:
- spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs;
- spec->mixers[0] = cxt5051_hp_dv6736_mixers;
- spec->auto_mic = 0;
- break;
- case CXT5051_F700:
- spec->init_verbs[0] = cxt5051_f700_init_verbs;
- spec->mixers[0] = cxt5051_f700_mixers;
- spec->auto_mic = 0;
- break;
- case CXT5051_TOSHIBA:
- spec->mixers[0] = cxt5051_toshiba_mixers;
- spec->auto_mic = AUTO_MIC_PORTB;
- break;
- case CXT5051_IDEAPAD:
- spec->init_verbs[spec->num_init_verbs++] =
- cxt5051_ideapad_init_verbs;
- spec->ideapad = 1;
- break;
- }
-
- if (spec->beep_amp)
- snd_hda_attach_beep_device(codec, spec->beep_amp);
-
- return 0;
-}
-
-/* Conexant 5066 specific */
-
-static const hda_nid_t cxt5066_dac_nids[1] = { 0x10 };
-static const hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 };
-static const hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 };
-static const hda_nid_t cxt5066_digout_pin_nids[2] = { 0x20, 0x22 };
-
-/* OLPC's microphone port is DC coupled for use with external sensors,
- * therefore we use a 50% mic bias in order to center the input signal with
- * the DC input range of the codec. */
-#define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50
-
-static const struct hda_channel_mode cxt5066_modes[1] = {
- { 2, NULL },
-};
-
-#define HP_PRESENT_PORT_A (1 << 0)
-#define HP_PRESENT_PORT_D (1 << 1)
-#define hp_port_a_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_A)
-#define hp_port_d_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_D)
-
-static void cxt5066_update_speaker(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- unsigned int pinctl;
-
- snd_printdd("CXT5066: update speaker, hp_present=%d, cur_eapd=%d\n",
- spec->hp_present, spec->cur_eapd);
-
- /* Port A (HP) */
- pinctl = (hp_port_a_present(spec) && spec->cur_eapd) ? PIN_HP : 0;
- snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
- pinctl);
-
- /* Port D (HP/LO) */
- pinctl = spec->cur_eapd ? spec->port_d_mode : 0;
- if (spec->dell_automute || spec->thinkpad) {
- /* Mute if Port A is connected */
- if (hp_port_a_present(spec))
- pinctl = 0;
- } else {
- /* Thinkpad/Dell doesn't give pin-D status */
- if (!hp_port_d_present(spec))
- pinctl = 0;
- }
- snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
- pinctl);
-
- /* CLASS_D AMP */
- pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
- snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
- pinctl);
-}
-
-/* turn on/off EAPD (+ mute HP) as a master switch */
-static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-
- if (!cxt_eapd_put(kcontrol, ucontrol))
- return 0;
-
- cxt5066_update_speaker(codec);
- return 1;
-}
-
-static const struct hda_input_mux cxt5066_olpc_dc_bias = {
- .num_items = 3,
- .items = {
- { "Off", PIN_IN },
- { "50%", PIN_VREF50 },
- { "80%", PIN_VREF80 },
- },
-};
-
-static int cxt5066_set_olpc_dc_bias(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- /* Even though port F is the DC input, the bias is controlled on port B.
- * we also leave that port as an active input (but unselected) in DC mode
- * just in case that is necessary to make the bias setting take effect. */
- return snd_hda_codec_write_cache(codec, 0x1a, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- cxt5066_olpc_dc_bias.items[spec->dc_input_bias].index);
-}
-
-/* OLPC defers mic widget control until when capture is started because the
- * microphone LED comes on as soon as these settings are put in place. if we
- * did this before recording, it would give the false indication that recording
- * is happening when it is not. */
-static void cxt5066_olpc_select_mic(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- if (!spec->recording)
- return;
-
- if (spec->dc_enable) {
- /* in DC mode we ignore presence detection and just use the jack
- * through our special DC port */
- const struct hda_verb enable_dc_mode[] = {
- /* disble internal mic, port C */
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
- /* enable DC capture, port F */
- {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
- {},
- };
-
- snd_hda_sequence_write(codec, enable_dc_mode);
- /* port B input disabled (and bias set) through the following call */
- cxt5066_set_olpc_dc_bias(codec);
- return;
- }
-
- /* disable DC (port F) */
- snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
-
- /* external mic, port B */
- snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
- spec->ext_mic_present ? CXT5066_OLPC_EXT_MIC_BIAS : 0);
-
- /* internal mic, port C */
- snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
- spec->ext_mic_present ? 0 : PIN_VREF80);
-}
-
-/* toggle input of built-in and mic jack appropriately */
-static void cxt5066_olpc_automic(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- unsigned int present;
-
- if (spec->dc_enable) /* don't do presence detection in DC mode */
- return;
-
- present = snd_hda_codec_read(codec, 0x1a, 0,
- AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- if (present)
- snd_printdd("CXT5066: external microphone detected\n");
- else
- snd_printdd("CXT5066: external microphone absent\n");
-
- snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
- present ? 0 : 1);
- spec->ext_mic_present = !!present;
-
- cxt5066_olpc_select_mic(codec);
-}
-
-/* toggle input of built-in digital mic and mic jack appropriately */
-static void cxt5066_vostro_automic(struct hda_codec *codec)
-{
- unsigned int present;
-
- struct hda_verb ext_mic_present[] = {
- /* enable external mic, port B */
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-
- /* switch to external mic input */
- {0x17, AC_VERB_SET_CONNECT_SEL, 0},
- {0x14, AC_VERB_SET_CONNECT_SEL, 0},
-
- /* disable internal digital mic */
- {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
- {}
- };
- static const struct hda_verb ext_mic_absent[] = {
- /* enable internal mic, port C */
- {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
- /* switch to internal mic input */
- {0x14, AC_VERB_SET_CONNECT_SEL, 2},
-
- /* disable external mic, port B */
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
- {}
- };
-
- present = snd_hda_jack_detect(codec, 0x1a);
- if (present) {
- snd_printdd("CXT5066: external microphone detected\n");
- snd_hda_sequence_write(codec, ext_mic_present);
- } else {
- snd_printdd("CXT5066: external microphone absent\n");
- snd_hda_sequence_write(codec, ext_mic_absent);
- }
-}
-
-/* toggle input of built-in digital mic and mic jack appropriately */
-static void cxt5066_ideapad_automic(struct hda_codec *codec)
-{
- unsigned int present;
-
- struct hda_verb ext_mic_present[] = {
- {0x14, AC_VERB_SET_CONNECT_SEL, 0},
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
- {}
- };
- static const struct hda_verb ext_mic_absent[] = {
- {0x14, AC_VERB_SET_CONNECT_SEL, 2},
- {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
- {}
- };
-
- present = snd_hda_jack_detect(codec, 0x1b);
- if (present) {
- snd_printdd("CXT5066: external microphone detected\n");
- snd_hda_sequence_write(codec, ext_mic_present);
- } else {
- snd_printdd("CXT5066: external microphone absent\n");
- snd_hda_sequence_write(codec, ext_mic_absent);
- }
-}
-
-
-/* toggle input of built-in digital mic and mic jack appropriately */
-static void cxt5066_asus_automic(struct hda_codec *codec)
-{
- unsigned int present;
-
- present = snd_hda_jack_detect(codec, 0x1b);
- snd_printdd("CXT5066: external microphone present=%d\n", present);
- snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
- present ? 1 : 0);
-}
-
-
-/* toggle input of built-in digital mic and mic jack appropriately */
-static void cxt5066_hp_laptop_automic(struct hda_codec *codec)
-{
- unsigned int present;
-
- present = snd_hda_jack_detect(codec, 0x1b);
- snd_printdd("CXT5066: external microphone present=%d\n", present);
- snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
- present ? 1 : 3);
-}
-
-
-/* toggle input of built-in digital mic and mic jack appropriately
- order is: external mic -> dock mic -> interal mic */
-static void cxt5066_thinkpad_automic(struct hda_codec *codec)
-{
- unsigned int ext_present, dock_present;
-
- static const struct hda_verb ext_mic_present[] = {
- {0x14, AC_VERB_SET_CONNECT_SEL, 0},
- {0x17, AC_VERB_SET_CONNECT_SEL, 1},
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
- {}
- };
- static const struct hda_verb dock_mic_present[] = {
- {0x14, AC_VERB_SET_CONNECT_SEL, 0},
- {0x17, AC_VERB_SET_CONNECT_SEL, 0},
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
- {}
- };
- static const struct hda_verb ext_mic_absent[] = {
- {0x14, AC_VERB_SET_CONNECT_SEL, 2},
- {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
- {}
- };
-
- ext_present = snd_hda_jack_detect(codec, 0x1b);
- dock_present = snd_hda_jack_detect(codec, 0x1a);
- if (ext_present) {
- snd_printdd("CXT5066: external microphone detected\n");
- snd_hda_sequence_write(codec, ext_mic_present);
- } else if (dock_present) {
- snd_printdd("CXT5066: dock microphone detected\n");
- snd_hda_sequence_write(codec, dock_mic_present);
- } else {
- snd_printdd("CXT5066: external microphone absent\n");
- snd_hda_sequence_write(codec, ext_mic_absent);
- }
-}
-
-/* mute internal speaker if HP is plugged */
-static void cxt5066_hp_automute(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- unsigned int portA, portD;
-
- /* Port A */
- portA = snd_hda_jack_detect(codec, 0x19);
-
- /* Port D */
- portD = snd_hda_jack_detect(codec, 0x1c);
-
- spec->hp_present = portA ? HP_PRESENT_PORT_A : 0;
- spec->hp_present |= portD ? HP_PRESENT_PORT_D : 0;
- snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n",
- portA, portD, spec->hp_present);
- cxt5066_update_speaker(codec);
-}
-
-/* Dispatch the right mic autoswitch function */
-static void cxt5066_automic(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
-
- if (spec->dell_vostro)
- cxt5066_vostro_automic(codec);
- else if (spec->ideapad)
- cxt5066_ideapad_automic(codec);
- else if (spec->thinkpad)
- cxt5066_thinkpad_automic(codec);
- else if (spec->hp_laptop)
- cxt5066_hp_laptop_automic(codec);
- else if (spec->asus)
- cxt5066_asus_automic(codec);
-}
-
-/* unsolicited event for jack sensing */
-static void cxt5066_olpc_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- struct conexant_spec *spec = codec->spec;
- snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
- switch (res >> 26) {
- case CONEXANT_HP_EVENT:
- cxt5066_hp_automute(codec);
- break;
- case CONEXANT_MIC_EVENT:
- /* ignore mic events in DC mode; we're always using the jack */
- if (!spec->dc_enable)
- cxt5066_olpc_automic(codec);
- break;
- }
-}
-
-/* unsolicited event for jack sensing */
-static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
- switch (res >> 26) {
- case CONEXANT_HP_EVENT:
- cxt5066_hp_automute(codec);
- break;
- case CONEXANT_MIC_EVENT:
- cxt5066_automic(codec);
- break;
- }
-}
-
-
-static const struct hda_input_mux cxt5066_analog_mic_boost = {
- .num_items = 5,
- .items = {
- { "0dB", 0 },
- { "10dB", 1 },
- { "20dB", 2 },
- { "30dB", 3 },
- { "40dB", 4 },
- },
-};
-
-static void cxt5066_set_mic_boost(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- snd_hda_codec_write_cache(codec, 0x17, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT |
- cxt5066_analog_mic_boost.items[spec->mic_boost].index);
- if (spec->ideapad || spec->thinkpad) {
- /* adjust the internal mic as well...it is not through 0x17 */
- snd_hda_codec_write_cache(codec, 0x23, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_INPUT |
- cxt5066_analog_mic_boost.
- items[spec->mic_boost].index);
- }
-}
-
-static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- return snd_hda_input_mux_info(&cxt5066_analog_mic_boost, uinfo);
-}
-
-static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
- ucontrol->value.enumerated.item[0] = spec->mic_boost;
- return 0;
-}
-
-static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
- const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
- unsigned int idx;
- idx = ucontrol->value.enumerated.item[0];
- if (idx >= imux->num_items)
- idx = imux->num_items - 1;
-
- spec->mic_boost = idx;
- if (!spec->dc_enable)
- cxt5066_set_mic_boost(codec);
- return 1;
-}
-
-static void cxt5066_enable_dc(struct hda_codec *codec)
-{
- const struct hda_verb enable_dc_mode[] = {
- /* disable gain */
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
- /* switch to DC input */
- {0x17, AC_VERB_SET_CONNECT_SEL, 3},
- {}
- };
-
- /* configure as input source */
- snd_hda_sequence_write(codec, enable_dc_mode);
- cxt5066_olpc_select_mic(codec); /* also sets configured bias */
-}
-
-static void cxt5066_disable_dc(struct hda_codec *codec)
-{
- /* reconfigure input source */
- cxt5066_set_mic_boost(codec);
- /* automic also selects the right mic if we're recording */
- cxt5066_olpc_automic(codec);
-}
-
-static int cxt5066_olpc_dc_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
- ucontrol->value.integer.value[0] = spec->dc_enable;
- return 0;
-}
-
-static int cxt5066_olpc_dc_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
- int dc_enable = !!ucontrol->value.integer.value[0];
-
- if (dc_enable == spec->dc_enable)
- return 0;
-
- spec->dc_enable = dc_enable;
- if (dc_enable)
- cxt5066_enable_dc(codec);
- else
- cxt5066_disable_dc(codec);
-
- return 1;
-}
-
-static int cxt5066_olpc_dc_bias_enum_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- return snd_hda_input_mux_info(&cxt5066_olpc_dc_bias, uinfo);
-}
-
-static int cxt5066_olpc_dc_bias_enum_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
- ucontrol->value.enumerated.item[0] = spec->dc_input_bias;
- return 0;
-}
-
-static int cxt5066_olpc_dc_bias_enum_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
- const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
- unsigned int idx;
-
- idx = ucontrol->value.enumerated.item[0];
- if (idx >= imux->num_items)
- idx = imux->num_items - 1;
-
- spec->dc_input_bias = idx;
- if (spec->dc_enable)
- cxt5066_set_olpc_dc_bias(codec);
- return 1;
-}
-
-static void cxt5066_olpc_capture_prepare(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- /* mark as recording and configure the microphone widget so that the
- * recording LED comes on. */
- spec->recording = 1;
- cxt5066_olpc_select_mic(codec);
-}
-
-static void cxt5066_olpc_capture_cleanup(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- const struct hda_verb disable_mics[] = {
- /* disable external mic, port B */
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
- /* disble internal mic, port C */
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
- /* disable DC capture, port F */
- {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
- {},
- };
-
- snd_hda_sequence_write(codec, disable_mics);
- spec->recording = 0;
-}
-
-static void conexant_check_dig_outs(struct hda_codec *codec,
- const hda_nid_t *dig_pins,
- int num_pins)
-{
- struct conexant_spec *spec = codec->spec;
- hda_nid_t *nid_loc = &spec->multiout.dig_out_nid;
- int i;
-
- for (i = 0; i < num_pins; i++, dig_pins++) {
- unsigned int cfg = snd_hda_codec_get_pincfg(codec, *dig_pins);
- if (get_defcfg_connect(cfg) == AC_JACK_PORT_NONE)
- continue;
- if (snd_hda_get_connections(codec, *dig_pins, nid_loc, 1) != 1)
- continue;
- if (spec->slave_dig_outs[0])
- nid_loc++;
- else
- nid_loc = spec->slave_dig_outs;
- }
-}
-
-static const struct hda_input_mux cxt5066_capture_source = {
- .num_items = 4,
- .items = {
- { "Mic B", 0 },
- { "Mic C", 1 },
- { "Mic E", 2 },
- { "Mic F", 3 },
- },
-};
-
-static const struct hda_bind_ctls cxt5066_bind_capture_vol_others = {
- .ops = &snd_hda_bind_vol,
- .values = {
- HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
- HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
- 0
- },
-};
-
-static const struct hda_bind_ctls cxt5066_bind_capture_sw_others = {
- .ops = &snd_hda_bind_sw,
- .values = {
- HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
- HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
- 0
- },
-};
-
-static const struct snd_kcontrol_new cxt5066_mixer_master[] = {
- HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
- {}
-};
-
-static const struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ |
- SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
- .subdevice = HDA_SUBDEV_AMP_FLAG,
- .info = snd_hda_mixer_amp_volume_info,
- .get = snd_hda_mixer_amp_volume_get,
- .put = snd_hda_mixer_amp_volume_put,
- .tlv = { .c = snd_hda_mixer_amp_tlv },
- /* offset by 28 volume steps to limit minimum gain to -46dB */
- .private_value =
- HDA_COMPOSE_AMP_VAL_OFS(0x10, 3, 0, HDA_OUTPUT, 28),
- },
- {}
-};
-
-static const struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "DC Mode Enable Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = cxt5066_olpc_dc_get,
- .put = cxt5066_olpc_dc_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "DC Input Bias Enum",
- .info = cxt5066_olpc_dc_bias_enum_info,
- .get = cxt5066_olpc_dc_bias_enum_get,
- .put = cxt5066_olpc_dc_bias_enum_put,
- },
- {}
-};
-
-static const struct snd_kcontrol_new cxt5066_mixers[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = cxt_eapd_info,
- .get = cxt_eapd_get,
- .put = cxt5066_hp_master_sw_put,
- .private_value = 0x1d,
- },
-
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Mic Boost Capture Enum",
- .info = cxt5066_mic_boost_mux_enum_info,
- .get = cxt5066_mic_boost_mux_enum_get,
- .put = cxt5066_mic_boost_mux_enum_put,
- },
-
- HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others),
- HDA_BIND_SW("Capture Switch", &cxt5066_bind_capture_sw_others),
- {}
-};
-
-static const struct snd_kcontrol_new cxt5066_vostro_mixers[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Internal Mic Boost Capture Enum",
- .info = cxt5066_mic_boost_mux_enum_info,
- .get = cxt5066_mic_boost_mux_enum_get,
- .put = cxt5066_mic_boost_mux_enum_put,
- .private_value = 0x23 | 0x100,
- },
- {}
-};
-
-static const struct hda_verb cxt5066_init_verbs[] = {
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
- {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
- {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
-
- /* Speakers */
- {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
-
- /* HP, Amp */
- {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
-
- {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
-
- /* DAC1 */
- {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
- /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-
- /* no digital microphone support yet */
- {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
- /* Audio input selector */
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
-
- /* SPDIF route: PCM */
- {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
- {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
-
- {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-
- /* EAPD */
- {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
-
- /* not handling these yet */
- {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
- {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
- {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
- {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
- {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
- {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
- {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
- {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
- { } /* end */
-};
-
-static const struct hda_verb cxt5066_init_verbs_olpc[] = {
- /* Port A: headphones */
- {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
-
- /* Port B: external microphone */
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
- /* Port C: internal microphone */
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
- /* Port D: unused */
- {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
- /* Port E: unused, but has primary EAPD */
- {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
- {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
-
- /* Port F: external DC input through microphone port */
- {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
- /* Port G: internal speakers */
- {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
-
- /* DAC1 */
- {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
- /* DAC2: unused */
- {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-
- /* Disable digital microphone port */
- {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
- /* Audio input selectors */
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
- {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
-
- /* Disable SPDIF */
- {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
- {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
- /* enable unsolicited events for Port A and B */
- {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
- {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
- { } /* end */
-};
-
-static const struct hda_verb cxt5066_init_verbs_vostro[] = {
- /* Port A: headphones */
- {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
- {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
-
- /* Port B: external microphone */
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
- /* Port C: unused */
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
- /* Port D: unused */
- {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
- /* Port E: unused, but has primary EAPD */
- {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
- {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
-
- /* Port F: unused */
- {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
- /* Port G: internal speakers */
- {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
-
- /* DAC1 */
- {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
- /* DAC2: unused */
- {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
- {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-
- /* Digital microphone port */
- {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
- /* Audio input selectors */
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
- {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
-
- /* Disable SPDIF */
- {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
- {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
- /* enable unsolicited events for Port A and B */
- {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
- {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
- { } /* end */
-};
-
-static const struct hda_verb cxt5066_init_verbs_ideapad[] = {
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
- {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
- {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
-
- /* Speakers */
- {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
-
- /* HP, Amp */
- {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
-
- {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
-
- /* DAC1 */
- {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
- /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- {0x14, AC_VERB_SET_CONNECT_SEL, 2}, /* default to internal mic */
-
- /* Audio input selector */
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2},
- {0x17, AC_VERB_SET_CONNECT_SEL, 1}, /* route ext mic */
-
- /* SPDIF route: PCM */
- {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
- {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
-
- {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-
- /* internal microphone */
- {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */
-
- /* EAPD */
- {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
-
- {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
- {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
- { } /* end */
-};
-
-static const struct hda_verb cxt5066_init_verbs_thinkpad[] = {
- {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
- {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
-
- /* Port G: internal speakers */
- {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
-
- /* Port A: HP, Amp */
- {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
- {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
-
- /* Port B: Mic Dock */
- {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
- /* Port C: Mic */
- {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
- /* Port D: HP Dock, Amp */
- {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
- {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
-
- /* DAC1 */
- {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
- /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- {0x14, AC_VERB_SET_CONNECT_SEL, 2}, /* default to internal mic */
-
- /* Audio input selector */
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2},
- {0x17, AC_VERB_SET_CONNECT_SEL, 1}, /* route ext mic */
-
- /* SPDIF route: PCM */
- {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
- {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
-
- {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-
- /* internal microphone */
- {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */
-
- /* EAPD */
- {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
-
- /* enable unsolicited events for Port A, B, C and D */
- {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
- {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
- {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
- {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
- { } /* end */
-};
-
-static const struct hda_verb cxt5066_init_verbs_portd_lo[] = {
- {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- { } /* end */
-};
-
-
-static const struct hda_verb cxt5066_init_verbs_hp_laptop[] = {
- {0x14, AC_VERB_SET_CONNECT_SEL, 0x0},
- {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
- {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
- { } /* end */
-};
-
-/* initialize jack-sensing, too */
-static int cxt5066_init(struct hda_codec *codec)
-{
- snd_printdd("CXT5066: init\n");
- conexant_init(codec);
- if (codec->patch_ops.unsol_event) {
- cxt5066_hp_automute(codec);
- cxt5066_automic(codec);
- }
- cxt5066_set_mic_boost(codec);
- return 0;
-}
-
-static int cxt5066_olpc_init(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- snd_printdd("CXT5066: init\n");
- conexant_init(codec);
- cxt5066_hp_automute(codec);
- if (!spec->dc_enable) {
- cxt5066_set_mic_boost(codec);
- cxt5066_olpc_automic(codec);
- } else {
- cxt5066_enable_dc(codec);
- }
- return 0;
-}
-
-enum {
- CXT5066_LAPTOP, /* Laptops w/ EAPD support */
- CXT5066_DELL_LAPTOP, /* Dell Laptop */
- CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */
- CXT5066_DELL_VOSTRO, /* Dell Vostro 1015i */
- CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */
- CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */
- CXT5066_ASUS, /* Asus K52JU, Lenovo G560 - Int mic at 0x1a and Ext mic at 0x1b */
- CXT5066_HP_LAPTOP, /* HP Laptop */
- CXT5066_AUTO, /* BIOS auto-parser */
- CXT5066_MODELS
-};
-
-static const char * const cxt5066_models[CXT5066_MODELS] = {
- [CXT5066_LAPTOP] = "laptop",
- [CXT5066_DELL_LAPTOP] = "dell-laptop",
- [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5",
- [CXT5066_DELL_VOSTRO] = "dell-vostro",
- [CXT5066_IDEAPAD] = "ideapad",
- [CXT5066_THINKPAD] = "thinkpad",
- [CXT5066_ASUS] = "asus",
- [CXT5066_HP_LAPTOP] = "hp-laptop",
- [CXT5066_AUTO] = "auto",
-};
-
-static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
- SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT5066_AUTO),
- SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD),
- SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO),
- SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD),
- SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO),
- SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO),
- SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
- SND_PCI_QUIRK(0x1028, 0x050f, "Dell Inspiron", CXT5066_IDEAPAD),
- SND_PCI_QUIRK(0x1028, 0x0510, "Dell Vostro", CXT5066_IDEAPAD),
- SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
- SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_ASUS),
- SND_PCI_QUIRK(0x1043, 0x1643, "Asus K52JU", CXT5066_ASUS),
- SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS),
- SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD),
- SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
- SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
- CXT5066_LAPTOP),
- SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
- SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
- SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
- SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS),
- SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T510", CXT5066_AUTO),
- SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520 & W520", CXT5066_AUTO),
- SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD),
- SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD),
- SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS),
- SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
- SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO),
- SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO),
- {}
-};
-
-static int patch_cxt5066(struct hda_codec *codec)
-{
- struct conexant_spec *spec;
- int board_config;
-
- board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
- cxt5066_models, cxt5066_cfg_tbl);
- if (board_config < 0)
- board_config = CXT5066_AUTO; /* model=auto as default */
- if (board_config == CXT5066_AUTO)
- return patch_conexant_auto(codec);
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- codec->spec = spec;
-
- codec->patch_ops = conexant_patch_ops;
- codec->patch_ops.init = conexant_init;
-
- spec->dell_automute = 0;
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = ARRAY_SIZE(cxt5066_dac_nids);
- spec->multiout.dac_nids = cxt5066_dac_nids;
- conexant_check_dig_outs(codec, cxt5066_digout_pin_nids,
- ARRAY_SIZE(cxt5066_digout_pin_nids));
- spec->num_adc_nids = 1;
- spec->adc_nids = cxt5066_adc_nids;
- spec->capsrc_nids = cxt5066_capsrc_nids;
- spec->input_mux = &cxt5066_capture_source;
-
- spec->port_d_mode = PIN_HP;
-
- spec->num_init_verbs = 1;
- spec->init_verbs[0] = cxt5066_init_verbs;
- spec->num_channel_mode = ARRAY_SIZE(cxt5066_modes);
- spec->channel_mode = cxt5066_modes;
- spec->cur_adc = 0;
- spec->cur_adc_idx = 0;
-
- set_beep_amp(spec, 0x13, 0, HDA_OUTPUT);
-
- switch (board_config) {
- default:
- case CXT5066_LAPTOP:
- spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
- spec->mixers[spec->num_mixers++] = cxt5066_mixers;
- break;
- case CXT5066_DELL_LAPTOP:
- spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
- spec->mixers[spec->num_mixers++] = cxt5066_mixers;
-
- spec->port_d_mode = PIN_OUT;
- spec->init_verbs[spec->num_init_verbs] = cxt5066_init_verbs_portd_lo;
- spec->num_init_verbs++;
- spec->dell_automute = 1;
- break;
- case CXT5066_ASUS:
- case CXT5066_HP_LAPTOP:
- codec->patch_ops.init = cxt5066_init;
- codec->patch_ops.unsol_event = cxt5066_unsol_event;
- spec->init_verbs[spec->num_init_verbs] =
- cxt5066_init_verbs_hp_laptop;
- spec->num_init_verbs++;
- spec->hp_laptop = board_config == CXT5066_HP_LAPTOP;
- spec->asus = board_config == CXT5066_ASUS;
- spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
- spec->mixers[spec->num_mixers++] = cxt5066_mixers;
- /* no S/PDIF out */
- if (board_config == CXT5066_HP_LAPTOP)
- spec->multiout.dig_out_nid = 0;
- /* input source automatically selected */
- spec->input_mux = NULL;
- spec->port_d_mode = 0;
- spec->mic_boost = 3; /* default 30dB gain */
- break;
-
- case CXT5066_OLPC_XO_1_5:
- codec->patch_ops.init = cxt5066_olpc_init;
- codec->patch_ops.unsol_event = cxt5066_olpc_unsol_event;
- spec->init_verbs[0] = cxt5066_init_verbs_olpc;
- spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
- spec->mixers[spec->num_mixers++] = cxt5066_mixer_olpc_dc;
- spec->mixers[spec->num_mixers++] = cxt5066_mixers;
- spec->port_d_mode = 0;
- spec->mic_boost = 3; /* default 30dB gain */
-
- /* no S/PDIF out */
- spec->multiout.dig_out_nid = 0;
-
- /* input source automatically selected */
- spec->input_mux = NULL;
-
- /* our capture hooks which allow us to turn on the microphone LED
- * at the right time */
- spec->capture_prepare = cxt5066_olpc_capture_prepare;
- spec->capture_cleanup = cxt5066_olpc_capture_cleanup;
- break;
- case CXT5066_DELL_VOSTRO:
- codec->patch_ops.init = cxt5066_init;
- codec->patch_ops.unsol_event = cxt5066_unsol_event;
- spec->init_verbs[0] = cxt5066_init_verbs_vostro;
- spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
- spec->mixers[spec->num_mixers++] = cxt5066_mixers;
- spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers;
- spec->port_d_mode = 0;
- spec->dell_vostro = 1;
- spec->mic_boost = 3; /* default 30dB gain */
-
- /* no S/PDIF out */
- spec->multiout.dig_out_nid = 0;
-
- /* input source automatically selected */
- spec->input_mux = NULL;
- break;
- case CXT5066_IDEAPAD:
- codec->patch_ops.init = cxt5066_init;
- codec->patch_ops.unsol_event = cxt5066_unsol_event;
- spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
- spec->mixers[spec->num_mixers++] = cxt5066_mixers;
- spec->init_verbs[0] = cxt5066_init_verbs_ideapad;
- spec->port_d_mode = 0;
- spec->ideapad = 1;
- spec->mic_boost = 2; /* default 20dB gain */
-
- /* no S/PDIF out */
- spec->multiout.dig_out_nid = 0;
-
- /* input source automatically selected */
- spec->input_mux = NULL;
- break;
- case CXT5066_THINKPAD:
- codec->patch_ops.init = cxt5066_init;
- codec->patch_ops.unsol_event = cxt5066_unsol_event;
- spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
- spec->mixers[spec->num_mixers++] = cxt5066_mixers;
- spec->init_verbs[0] = cxt5066_init_verbs_thinkpad;
- spec->thinkpad = 1;
- spec->port_d_mode = PIN_OUT;
- spec->mic_boost = 2; /* default 20dB gain */
-
- /* no S/PDIF out */
- spec->multiout.dig_out_nid = 0;
-
- /* input source automatically selected */
- spec->input_mux = NULL;
- break;
- }
-
- if (spec->beep_amp)
- snd_hda_attach_beep_device(codec, spec->beep_amp);
-
- return 0;
-}
-
-/*
- * Automatic parser for CX20641 & co
- */
-
-static int cx_auto_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct conexant_spec *spec = codec->spec;
- hda_nid_t adc = spec->imux_info[spec->cur_mux[0]].adc;
- if (spec->adc_switching) {
- spec->cur_adc = adc;
- spec->cur_adc_stream_tag = stream_tag;
- spec->cur_adc_format = format;
- }
- snd_hda_codec_setup_stream(codec, adc, stream_tag, 0, format);
- return 0;
-}
-
-static int cx_auto_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct conexant_spec *spec = codec->spec;
- snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
- spec->cur_adc = 0;
- return 0;
-}
-
-static const struct hda_pcm_stream cx_auto_pcm_analog_capture = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .nid = 0, /* fill later */
- .ops = {
- .prepare = cx_auto_capture_pcm_prepare,
- .cleanup = cx_auto_capture_pcm_cleanup
- },
-};
-
-static const hda_nid_t cx_auto_adc_nids[] = { 0x14 };
-
-#define get_connection_index(codec, mux, nid)\
- snd_hda_get_conn_index(codec, mux, nid, 0)
-
-/* get an unassigned DAC from the given list.
- * Return the nid if found and reduce the DAC list, or return zero if
- * not found
- */
-static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t pin,
- hda_nid_t *dacs, int *num_dacs)
-{
- int i, nums = *num_dacs;
- hda_nid_t ret = 0;
-
- for (i = 0; i < nums; i++) {
- if (get_connection_index(codec, pin, dacs[i]) >= 0) {
- ret = dacs[i];
- break;
- }
- }
- if (!ret)
- return 0;
- if (--nums > 0)
- memmove(dacs, dacs + 1, nums * sizeof(hda_nid_t));
- *num_dacs = nums;
- return ret;
-}
-
-#define MAX_AUTO_DACS 5
-
-#define DAC_SLAVE_FLAG 0x8000 /* filled dac is a slave */
-
-/* fill analog DAC list from the widget tree */
-static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs)
-{
- hda_nid_t nid, end_nid;
- int nums = 0;
-
- end_nid = codec->start_nid + codec->num_nodes;
- for (nid = codec->start_nid; nid < end_nid; nid++) {
- unsigned int wcaps = get_wcaps(codec, nid);
- unsigned int type = get_wcaps_type(wcaps);
- if (type == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL)) {
- dacs[nums++] = nid;
- if (nums >= MAX_AUTO_DACS)
- break;
- }
- }
- return nums;
-}
-
-/* fill pin_dac_pair list from the pin and dac list */
-static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins,
- int num_pins, hda_nid_t *dacs, int *rest,
- struct pin_dac_pair *filled, int nums,
- int type)
-{
- int i, start = nums;
-
- for (i = 0; i < num_pins; i++, nums++) {
- filled[nums].pin = pins[i];
- filled[nums].type = type;
- filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest);
- if (filled[nums].dac)
- continue;
- if (filled[start].dac && get_connection_index(codec, pins[i], filled[start].dac) >= 0) {
- filled[nums].dac = filled[start].dac | DAC_SLAVE_FLAG;
- continue;
- }
- if (filled[0].dac && get_connection_index(codec, pins[i], filled[0].dac) >= 0) {
- filled[nums].dac = filled[0].dac | DAC_SLAVE_FLAG;
- continue;
- }
- snd_printdd("Failed to find a DAC for pin 0x%x", pins[i]);
- }
- return nums;
-}
-
-/* parse analog output paths */
-static void cx_auto_parse_output(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- hda_nid_t dacs[MAX_AUTO_DACS];
- int i, j, nums, rest;
-
- rest = fill_cx_auto_dacs(codec, dacs);
- /* parse all analog output pins */
- nums = fill_dacs_for_pins(codec, cfg->line_out_pins, cfg->line_outs,
- dacs, &rest, spec->dac_info, 0,
- AUTO_PIN_LINE_OUT);
- nums = fill_dacs_for_pins(codec, cfg->hp_pins, cfg->hp_outs,
- dacs, &rest, spec->dac_info, nums,
- AUTO_PIN_HP_OUT);
- nums = fill_dacs_for_pins(codec, cfg->speaker_pins, cfg->speaker_outs,
- dacs, &rest, spec->dac_info, nums,
- AUTO_PIN_SPEAKER_OUT);
- spec->dac_info_filled = nums;
- /* fill multiout struct */
- for (i = 0; i < nums; i++) {
- hda_nid_t dac = spec->dac_info[i].dac;
- if (!dac || (dac & DAC_SLAVE_FLAG))
- continue;
- switch (spec->dac_info[i].type) {
- case AUTO_PIN_LINE_OUT:
- spec->private_dac_nids[spec->multiout.num_dacs] = dac;
- spec->multiout.num_dacs++;
- break;
- case AUTO_PIN_HP_OUT:
- case AUTO_PIN_SPEAKER_OUT:
- if (!spec->multiout.hp_nid) {
- spec->multiout.hp_nid = dac;
- break;
- }
- for (j = 0; j < ARRAY_SIZE(spec->multiout.extra_out_nid); j++)
- if (!spec->multiout.extra_out_nid[j]) {
- spec->multiout.extra_out_nid[j] = dac;
- break;
- }
- break;
- }
- }
- spec->multiout.dac_nids = spec->private_dac_nids;
- spec->multiout.max_channels = spec->multiout.num_dacs * 2;
-
- for (i = 0; i < cfg->hp_outs; i++) {
- if (is_jack_detectable(codec, cfg->hp_pins[i])) {
- spec->auto_mute = 1;
- break;
- }
- }
- if (spec->auto_mute &&
- cfg->line_out_pins[0] &&
- cfg->line_out_type != AUTO_PIN_SPEAKER_OUT &&
- cfg->line_out_pins[0] != cfg->hp_pins[0] &&
- cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
- for (i = 0; i < cfg->line_outs; i++) {
- if (is_jack_detectable(codec, cfg->line_out_pins[i])) {
- spec->detect_line = 1;
- break;
- }
- }
- spec->automute_lines = spec->detect_line;
- }
-
- spec->vmaster_nid = spec->private_dac_nids[0];
-}
-
-static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
- hda_nid_t *pins, bool on);
-
-static void do_automute(struct hda_codec *codec, int num_pins,
- hda_nid_t *pins, bool on)
-{
- struct conexant_spec *spec = codec->spec;
- int i;
- for (i = 0; i < num_pins; i++)
- snd_hda_codec_write(codec, pins[i], 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- on ? PIN_OUT : 0);
- if (spec->pin_eapd_ctrls)
- cx_auto_turn_eapd(codec, num_pins, pins, on);
-}
-
-static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
-{
- int i, present = 0;
-
- for (i = 0; i < num_pins; i++) {
- hda_nid_t nid = pins[i];
- if (!nid || !is_jack_detectable(codec, nid))
- break;
- present |= snd_hda_jack_detect(codec, nid);
- }
- return present;
-}
-
-/* auto-mute/unmute speaker and line outs according to headphone jack */
-static void cx_auto_update_speakers(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int on = 1;
-
- /* turn on HP EAPD when HP jacks are present */
- if (spec->pin_eapd_ctrls) {
- if (spec->auto_mute)
- on = spec->hp_present;
- cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on);
- }
-
- /* mute speakers in auto-mode if HP or LO jacks are plugged */
- if (spec->auto_mute)
- on = !(spec->hp_present ||
- (spec->detect_line && spec->line_present));
- do_automute(codec, cfg->speaker_outs, cfg->speaker_pins, on);
-
- /* toggle line-out mutes if needed, too */
- /* if LO is a copy of either HP or Speaker, don't need to handle it */
- if (cfg->line_out_pins[0] == cfg->hp_pins[0] ||
- cfg->line_out_pins[0] == cfg->speaker_pins[0])
- return;
- if (spec->auto_mute) {
- /* mute LO in auto-mode when HP jack is present */
- if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT ||
- spec->automute_lines)
- on = !spec->hp_present;
- else
- on = 1;
- }
- do_automute(codec, cfg->line_outs, cfg->line_out_pins, on);
-}
-
-static void cx_auto_hp_automute(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
-
- if (!spec->auto_mute)
- return;
- spec->hp_present = detect_jacks(codec, cfg->hp_outs, cfg->hp_pins);
- cx_auto_update_speakers(codec);
-}
-
-static void cx_auto_line_automute(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
-
- if (!spec->auto_mute || !spec->detect_line)
- return;
- spec->line_present = detect_jacks(codec, cfg->line_outs,
- cfg->line_out_pins);
- cx_auto_update_speakers(codec);
-}
-
-static int cx_automute_mode_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
- static const char * const texts2[] = {
- "Disabled", "Enabled"
- };
- static const char * const texts3[] = {
- "Disabled", "Speaker Only", "Line Out+Speaker"
- };
- const char * const *texts;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- if (spec->automute_hp_lo) {
- uinfo->value.enumerated.items = 3;
- texts = texts3;
- } else {
- uinfo->value.enumerated.items = 2;
- texts = texts2;
- }
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int cx_automute_mode_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
- unsigned int val;
- if (!spec->auto_mute)
- val = 0;
- else if (!spec->automute_lines)
- val = 1;
- else
- val = 2;
- ucontrol->value.enumerated.item[0] = val;
- return 0;
-}
-
-static int cx_automute_mode_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
-
- switch (ucontrol->value.enumerated.item[0]) {
- case 0:
- if (!spec->auto_mute)
- return 0;
- spec->auto_mute = 0;
- break;
- case 1:
- if (spec->auto_mute && !spec->automute_lines)
- return 0;
- spec->auto_mute = 1;
- spec->automute_lines = 0;
- break;
- case 2:
- if (!spec->automute_hp_lo)
- return -EINVAL;
- if (spec->auto_mute && spec->automute_lines)
- return 0;
- spec->auto_mute = 1;
- spec->automute_lines = 1;
- break;
- default:
- return -EINVAL;
- }
- cx_auto_update_speakers(codec);
- return 1;
-}
-
-static const struct snd_kcontrol_new cx_automute_mode_enum[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Auto-Mute Mode",
- .info = cx_automute_mode_info,
- .get = cx_automute_mode_get,
- .put = cx_automute_mode_put,
- },
- { }
-};
-
-static int cx_auto_mux_enum_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
-
- return snd_hda_input_mux_info(&spec->private_imux, uinfo);
-}
-
-static int cx_auto_mux_enum_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
-
- ucontrol->value.enumerated.item[0] = spec->cur_mux[0];
- return 0;
-}
-
-/* look for the route the given pin from mux and return the index;
- * if do_select is set, actually select the route.
- */
-static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux,
- hda_nid_t pin, hda_nid_t *srcp,
- bool do_select, int depth)
-{
- hda_nid_t conn[HDA_MAX_NUM_INPUTS];
- int i, nums;
-
- switch (get_wcaps_type(get_wcaps(codec, mux))) {
- case AC_WID_AUD_IN:
- case AC_WID_AUD_SEL:
- case AC_WID_AUD_MIX:
- break;
- default:
- return -1;
- }
-
- nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
- for (i = 0; i < nums; i++)
- if (conn[i] == pin) {
- if (do_select)
- snd_hda_codec_write(codec, mux, 0,
- AC_VERB_SET_CONNECT_SEL, i);
- if (srcp)
- *srcp = mux;
- return i;
- }
- depth++;
- if (depth == 2)
- return -1;
- for (i = 0; i < nums; i++) {
- int ret = __select_input_connection(codec, conn[i], pin, srcp,
- do_select, depth);
- if (ret >= 0) {
- if (do_select)
- snd_hda_codec_write(codec, mux, 0,
- AC_VERB_SET_CONNECT_SEL, i);
- return i;
- }
- }
- return -1;
-}
-
-static void select_input_connection(struct hda_codec *codec, hda_nid_t mux,
- hda_nid_t pin)
-{
- __select_input_connection(codec, mux, pin, NULL, true, 0);
-}
-
-static int get_input_connection(struct hda_codec *codec, hda_nid_t mux,
- hda_nid_t pin)
-{
- return __select_input_connection(codec, mux, pin, NULL, false, 0);
-}
-
-static int cx_auto_mux_enum_update(struct hda_codec *codec,
- const struct hda_input_mux *imux,
- unsigned int idx)
-{
- struct conexant_spec *spec = codec->spec;
- hda_nid_t adc;
- int changed = 1;
-
- if (!imux->num_items)
- return 0;
- if (idx >= imux->num_items)
- idx = imux->num_items - 1;
- if (spec->cur_mux[0] == idx)
- changed = 0;
- adc = spec->imux_info[idx].adc;
- select_input_connection(codec, spec->imux_info[idx].adc,
- spec->imux_info[idx].pin);
- if (spec->cur_adc && spec->cur_adc != adc) {
- /* stream is running, let's swap the current ADC */
- __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
- spec->cur_adc = adc;
- snd_hda_codec_setup_stream(codec, adc,
- spec->cur_adc_stream_tag, 0,
- spec->cur_adc_format);
- }
- spec->cur_mux[0] = idx;
- return changed;
-}
-
-static int cx_auto_mux_enum_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct conexant_spec *spec = codec->spec;
-
- return cx_auto_mux_enum_update(codec, &spec->private_imux,
- ucontrol->value.enumerated.item[0]);
-}
-
-static const struct snd_kcontrol_new cx_auto_capture_mixers[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = cx_auto_mux_enum_info,
- .get = cx_auto_mux_enum_get,
- .put = cx_auto_mux_enum_put
- },
- {}
-};
-
-static bool select_automic(struct hda_codec *codec, int idx, bool detect)
-{
- struct conexant_spec *spec = codec->spec;
- if (idx < 0)
- return false;
- if (detect && !snd_hda_jack_detect(codec, spec->imux_info[idx].pin))
- return false;
- cx_auto_mux_enum_update(codec, &spec->private_imux, idx);
- return true;
-}
-
-/* automatic switch internal and external mic */
-static void cx_auto_automic(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
-
- if (!spec->auto_mic)
- return;
- if (!select_automic(codec, spec->auto_mic_ext, true))
- if (!select_automic(codec, spec->auto_mic_dock, true))
- select_automic(codec, spec->auto_mic_int, false);
-}
-
-static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- switch (snd_hda_jack_get_action(codec, res >> 26)) {
- case CONEXANT_HP_EVENT:
- cx_auto_hp_automute(codec);
- break;
- case CONEXANT_LINE_EVENT:
- cx_auto_line_automute(codec);
- break;
- case CONEXANT_MIC_EVENT:
- cx_auto_automic(codec);
- break;
- }
- snd_hda_jack_report_sync(codec);
-}
-
-/* check whether the pin config is suitable for auto-mic switching;
- * auto-mic is enabled only when one int-mic and one ext- and/or
- * one dock-mic exist
- */
-static void cx_auto_check_auto_mic(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- int pset[INPUT_PIN_ATTR_NORMAL + 1];
- int i;
-
- for (i = 0; i < ARRAY_SIZE(pset); i++)
- pset[i] = -1;
- for (i = 0; i < spec->private_imux.num_items; i++) {
- hda_nid_t pin = spec->imux_info[i].pin;
- unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin);
- int type, attr;
- attr = snd_hda_get_input_pin_attr(def_conf);
- if (attr == INPUT_PIN_ATTR_UNUSED)
- return; /* invalid entry */
- if (attr > INPUT_PIN_ATTR_NORMAL)
- attr = INPUT_PIN_ATTR_NORMAL;
- if (attr != INPUT_PIN_ATTR_INT &&
- !is_jack_detectable(codec, pin))
- return; /* non-detectable pin */
- type = get_defcfg_device(def_conf);
- if (type != AC_JACK_MIC_IN &&
- (attr != INPUT_PIN_ATTR_DOCK || type != AC_JACK_LINE_IN))
- return; /* no valid input type */
- if (pset[attr] >= 0)
- return; /* already occupied */
- pset[attr] = i;
- }
- if (pset[INPUT_PIN_ATTR_INT] < 0 ||
- (pset[INPUT_PIN_ATTR_NORMAL] < 0 && pset[INPUT_PIN_ATTR_DOCK]))
- return; /* no input to switch*/
- spec->auto_mic = 1;
- spec->auto_mic_ext = pset[INPUT_PIN_ATTR_NORMAL];
- spec->auto_mic_dock = pset[INPUT_PIN_ATTR_DOCK];
- spec->auto_mic_int = pset[INPUT_PIN_ATTR_INT];
-}
-
-static void cx_auto_parse_input(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- struct hda_input_mux *imux;
- int i, j;
-
- imux = &spec->private_imux;
- for (i = 0; i < cfg->num_inputs; i++) {
- for (j = 0; j < spec->num_adc_nids; j++) {
- hda_nid_t adc = spec->adc_nids[j];
- int idx = get_input_connection(codec, adc,
- cfg->inputs[i].pin);
- if (idx >= 0) {
- const char *label;
- label = hda_get_autocfg_input_label(codec, cfg, i);
- spec->imux_info[imux->num_items].index = i;
- spec->imux_info[imux->num_items].boost = 0;
- spec->imux_info[imux->num_items].adc = adc;
- spec->imux_info[imux->num_items].pin =
- cfg->inputs[i].pin;
- snd_hda_add_imux_item(imux, label, idx, NULL);
- break;
- }
- }
- }
- if (imux->num_items >= 2 && cfg->num_inputs == imux->num_items)
- cx_auto_check_auto_mic(codec);
- if (imux->num_items > 1) {
- for (i = 1; i < imux->num_items; i++) {
- if (spec->imux_info[i].adc != spec->imux_info[0].adc) {
- spec->adc_switching = 1;
- break;
- }
- }
- }
-}
-
-/* get digital-input audio widget corresponding to the given pin */
-static hda_nid_t cx_auto_get_dig_in(struct hda_codec *codec, hda_nid_t pin)
-{
- hda_nid_t nid, end_nid;
-
- end_nid = codec->start_nid + codec->num_nodes;
- for (nid = codec->start_nid; nid < end_nid; nid++) {
- unsigned int wcaps = get_wcaps(codec, nid);
- unsigned int type = get_wcaps_type(wcaps);
- if (type == AC_WID_AUD_IN && (wcaps & AC_WCAP_DIGITAL)) {
- if (get_connection_index(codec, nid, pin) >= 0)
- return nid;
- }
- }
- return 0;
-}
-
-static void cx_auto_parse_digital(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- hda_nid_t nid;
-
- if (cfg->dig_outs &&
- snd_hda_get_connections(codec, cfg->dig_out_pins[0], &nid, 1) == 1)
- spec->multiout.dig_out_nid = nid;
- if (cfg->dig_in_pin)
- spec->dig_in_nid = cx_auto_get_dig_in(codec, cfg->dig_in_pin);
-}
-
-#ifdef CONFIG_SND_HDA_INPUT_BEEP
-static void cx_auto_parse_beep(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- hda_nid_t nid, end_nid;
-
- end_nid = codec->start_nid + codec->num_nodes;
- for (nid = codec->start_nid; nid < end_nid; nid++)
- if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_BEEP) {
- set_beep_amp(spec, nid, 0, HDA_OUTPUT);
- break;
- }
-}
-#else
-#define cx_auto_parse_beep(codec)
-#endif
-
-/* parse EAPDs */
-static void cx_auto_parse_eapd(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- hda_nid_t nid, end_nid;
-
- end_nid = codec->start_nid + codec->num_nodes;
- for (nid = codec->start_nid; nid < end_nid; nid++) {
- if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
- continue;
- if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD))
- continue;
- spec->eapds[spec->num_eapds++] = nid;
- if (spec->num_eapds >= ARRAY_SIZE(spec->eapds))
- break;
- }
-
- /* NOTE: below is a wild guess; if we have more than two EAPDs,
- * it's a new chip, where EAPDs are supposed to be associated to
- * pins, and we can control EAPD per pin.
- * OTOH, if only one or two EAPDs are found, it's an old chip,
- * thus it might control over all pins.
- */
- spec->pin_eapd_ctrls = spec->num_eapds > 2;
-}
-
-static int cx_auto_parse_auto_config(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- int err;
-
- err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
- if (err < 0)
- return err;
-
- cx_auto_parse_output(codec);
- cx_auto_parse_input(codec);
- cx_auto_parse_digital(codec);
- cx_auto_parse_beep(codec);
- cx_auto_parse_eapd(codec);
- return 0;
-}
-
-static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
- hda_nid_t *pins, bool on)
-{
- int i;
- for (i = 0; i < num_pins; i++) {
- if (snd_hda_query_pin_caps(codec, pins[i]) & AC_PINCAP_EAPD)
- snd_hda_codec_write(codec, pins[i], 0,
- AC_VERB_SET_EAPD_BTLENABLE,
- on ? 0x02 : 0);
- }
-}
-
-static void select_connection(struct hda_codec *codec, hda_nid_t pin,
- hda_nid_t src)
-{
- int idx = get_connection_index(codec, pin, src);
- if (idx >= 0)
- snd_hda_codec_write(codec, pin, 0,
- AC_VERB_SET_CONNECT_SEL, idx);
-}
-
-static void mute_outputs(struct hda_codec *codec, int num_nids,
- const hda_nid_t *nids)
-{
- int i, val;
-
- for (i = 0; i < num_nids; i++) {
- hda_nid_t nid = nids[i];
- if (!(get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
- continue;
- if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE)
- val = AMP_OUT_MUTE;
- else
- val = AMP_OUT_ZERO;
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_AMP_GAIN_MUTE, val);
- }
-}
-
-static void enable_unsol_pins(struct hda_codec *codec, int num_pins,
- hda_nid_t *pins, unsigned int action)
-{
- int i;
- for (i = 0; i < num_pins; i++)
- snd_hda_jack_detect_enable(codec, pins[i], action);
-}
-
-static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
-{
- int i;
- for (i = 0; i < nums; i++)
- if (list[i] == nid)
- return true;
- return false;
-}
-
-/* is the given NID found in any of autocfg items? */
-static bool found_in_autocfg(struct auto_pin_cfg *cfg, hda_nid_t nid)
-{
- int i;
-
- if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) ||
- found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) ||
- found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs) ||
- found_in_nid_list(nid, cfg->dig_out_pins, cfg->dig_outs))
- return true;
- for (i = 0; i < cfg->num_inputs; i++)
- if (cfg->inputs[i].pin == nid)
- return true;
- if (cfg->dig_in_pin == nid)
- return true;
- return false;
-}
-
-/* clear unsol-event tags on unused pins; Conexant codecs seem to leave
- * invalid unsol tags by some reason
- */
-static void clear_unsol_on_unused_pins(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i;
-
- for (i = 0; i < codec->init_pins.used; i++) {
- struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
- if (!found_in_autocfg(cfg, pin->nid))
- snd_hda_codec_write(codec, pin->nid, 0,
- AC_VERB_SET_UNSOLICITED_ENABLE, 0);
- }
-}
-
-/* turn on/off EAPD according to Master switch */
-static void cx_auto_vmaster_hook(void *private_data, int enabled)
-{
- struct hda_codec *codec = private_data;
- struct conexant_spec *spec = codec->spec;
-
- if (enabled && spec->pin_eapd_ctrls) {
- cx_auto_update_speakers(codec);
- return;
- }
- cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, enabled);
-}
-
-static void cx_auto_init_output(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- hda_nid_t nid;
- int i;
-
- mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids);
- for (i = 0; i < cfg->hp_outs; i++) {
- unsigned int val = PIN_OUT;
- if (snd_hda_query_pin_caps(codec, cfg->hp_pins[i]) &
- AC_PINCAP_HP_DRV)
- val |= AC_PINCTL_HP_EN;
- snd_hda_codec_write(codec, cfg->hp_pins[i], 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, val);
- }
- mute_outputs(codec, cfg->hp_outs, cfg->hp_pins);
- mute_outputs(codec, cfg->line_outs, cfg->line_out_pins);
- mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins);
- for (i = 0; i < spec->dac_info_filled; i++) {
- nid = spec->dac_info[i].dac;
- if (!nid)
- nid = spec->multiout.dac_nids[0];
- else if (nid & DAC_SLAVE_FLAG)
- nid &= ~DAC_SLAVE_FLAG;
- select_connection(codec, spec->dac_info[i].pin, nid);
- }
- if (spec->auto_mute) {
- enable_unsol_pins(codec, cfg->hp_outs, cfg->hp_pins,
- CONEXANT_HP_EVENT);
- spec->hp_present = detect_jacks(codec, cfg->hp_outs,
- cfg->hp_pins);
- if (spec->detect_line) {
- enable_unsol_pins(codec, cfg->line_outs,
- cfg->line_out_pins,
- CONEXANT_LINE_EVENT);
- spec->line_present =
- detect_jacks(codec, cfg->line_outs,
- cfg->line_out_pins);
- }
- }
- cx_auto_update_speakers(codec);
- /* turn on all EAPDs if no individual EAPD control is available */
- if (!spec->pin_eapd_ctrls)
- cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
- clear_unsol_on_unused_pins(codec);
-}
-
-static void cx_auto_init_input(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i, val;
-
- for (i = 0; i < spec->num_adc_nids; i++) {
- hda_nid_t nid = spec->adc_nids[i];
- if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP))
- continue;
- if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE)
- val = AMP_IN_MUTE(0);
- else
- val = AMP_IN_UNMUTE(0);
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
- val);
- }
-
- for (i = 0; i < cfg->num_inputs; i++) {
- unsigned int type;
- if (cfg->inputs[i].type == AUTO_PIN_MIC)
- type = PIN_VREF80;
- else
- type = PIN_IN;
- snd_hda_codec_write(codec, cfg->inputs[i].pin, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, type);
- }
-
- if (spec->auto_mic) {
- if (spec->auto_mic_ext >= 0) {
- snd_hda_jack_detect_enable(codec,
- cfg->inputs[spec->auto_mic_ext].pin,
- CONEXANT_MIC_EVENT);
- }
- if (spec->auto_mic_dock >= 0) {
- snd_hda_jack_detect_enable(codec,
- cfg->inputs[spec->auto_mic_dock].pin,
- CONEXANT_MIC_EVENT);
- }
- cx_auto_automic(codec);
- } else {
- select_input_connection(codec, spec->imux_info[0].adc,
- spec->imux_info[0].pin);
- }
-}
-
-static void cx_auto_init_digital(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
-
- if (spec->multiout.dig_out_nid)
- snd_hda_codec_write(codec, cfg->dig_out_pins[0], 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
- if (spec->dig_in_nid)
- snd_hda_codec_write(codec, cfg->dig_in_pin, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
-}
-
-static int cx_auto_init(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- /*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/
- cx_auto_init_output(codec);
- cx_auto_init_input(codec);
- cx_auto_init_digital(codec);
- snd_hda_jack_report_sync(codec);
- snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
- return 0;
-}
-
-static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
- const char *dir, int cidx,
- hda_nid_t nid, int hda_dir, int amp_idx)
-{
- static char name[32];
- static struct snd_kcontrol_new knew[] = {
- HDA_CODEC_VOLUME(name, 0, 0, 0),
- HDA_CODEC_MUTE(name, 0, 0, 0),
- };
- static const char * const sfx[2] = { "Volume", "Switch" };
- int i, err;
-
- for (i = 0; i < 2; i++) {
- struct snd_kcontrol *kctl;
- knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, 3, amp_idx,
- hda_dir);
- knew[i].subdevice = HDA_SUBDEV_AMP_FLAG;
- knew[i].index = cidx;
- snprintf(name, sizeof(name), "%s%s %s", basename, dir, sfx[i]);
- kctl = snd_ctl_new1(&knew[i], codec);
- if (!kctl)
- return -ENOMEM;
- err = snd_hda_ctl_add(codec, nid, kctl);
- if (err < 0)
- return err;
- if (!(query_amp_caps(codec, nid, hda_dir) &
- (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE)))
- break;
- }
- return 0;
-}
-
-#define cx_auto_add_volume(codec, str, dir, cidx, nid, hda_dir) \
- cx_auto_add_volume_idx(codec, str, dir, cidx, nid, hda_dir, 0)
-
-#define cx_auto_add_pb_volume(codec, nid, str, idx) \
- cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT)
-
-static int try_add_pb_volume(struct hda_codec *codec, hda_nid_t dac,
- hda_nid_t pin, const char *name, int idx)
-{
- unsigned int caps;
- if (dac && !(dac & DAC_SLAVE_FLAG)) {
- caps = query_amp_caps(codec, dac, HDA_OUTPUT);
- if (caps & AC_AMPCAP_NUM_STEPS)
- return cx_auto_add_pb_volume(codec, dac, name, idx);
- }
- caps = query_amp_caps(codec, pin, HDA_OUTPUT);
- if (caps & AC_AMPCAP_NUM_STEPS)
- return cx_auto_add_pb_volume(codec, pin, name, idx);
- return 0;
-}
-
-static int cx_auto_build_output_controls(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- int i, err;
- int num_line = 0, num_hp = 0, num_spk = 0;
- static const char * const texts[3] = { "Front", "Surround", "CLFE" };
-
- if (spec->dac_info_filled == 1)
- return try_add_pb_volume(codec, spec->dac_info[0].dac,
- spec->dac_info[0].pin,
- "Master", 0);
-
- for (i = 0; i < spec->dac_info_filled; i++) {
- const char *label;
- int idx, type;
- hda_nid_t dac = spec->dac_info[i].dac;
- type = spec->dac_info[i].type;
- if (type == AUTO_PIN_LINE_OUT)
- type = spec->autocfg.line_out_type;
- switch (type) {
- case AUTO_PIN_LINE_OUT:
- default:
- label = texts[num_line++];
- idx = 0;
- break;
- case AUTO_PIN_HP_OUT:
- label = "Headphone";
- idx = num_hp++;
- break;
- case AUTO_PIN_SPEAKER_OUT:
- label = "Speaker";
- idx = num_spk++;
- break;
- }
- err = try_add_pb_volume(codec, dac,
- spec->dac_info[i].pin,
- label, idx);
- if (err < 0)
- return err;
- }
-
- if (spec->auto_mute) {
- err = snd_hda_add_new_ctls(codec, cx_automute_mode_enum);
- if (err < 0)
- return err;
- }
-
- return 0;
-}
-
-static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid,
- const char *label, const char *pfx,
- int cidx)
-{
- struct conexant_spec *spec = codec->spec;
- int i;
-
- for (i = 0; i < spec->num_adc_nids; i++) {
- hda_nid_t adc_nid = spec->adc_nids[i];
- int idx = get_input_connection(codec, adc_nid, nid);
- if (idx < 0)
- continue;
- if (codec->single_adc_amp)
- idx = 0;
- return cx_auto_add_volume_idx(codec, label, pfx,
- cidx, adc_nid, HDA_INPUT, idx);
- }
- return 0;
-}
-
-static int cx_auto_add_boost_volume(struct hda_codec *codec, int idx,
- const char *label, int cidx)
-{
- struct conexant_spec *spec = codec->spec;
- hda_nid_t mux, nid;
- int i, con;
-
- nid = spec->imux_info[idx].pin;
- if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
- return cx_auto_add_volume(codec, label, " Boost", cidx,
- nid, HDA_INPUT);
- con = __select_input_connection(codec, spec->imux_info[idx].adc, nid,
- &mux, false, 0);
- if (con < 0)
- return 0;
- for (i = 0; i < idx; i++) {
- if (spec->imux_info[i].boost == mux)
- return 0; /* already present */
- }
-
- if (get_wcaps(codec, mux) & AC_WCAP_OUT_AMP) {
- spec->imux_info[idx].boost = mux;
- return cx_auto_add_volume(codec, label, " Boost", 0,
- mux, HDA_OUTPUT);
- }
- return 0;
-}
-
-static int cx_auto_build_input_controls(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- struct hda_input_mux *imux = &spec->private_imux;
- const char *prev_label;
- int input_conn[HDA_MAX_NUM_INPUTS];
- int i, j, err, cidx;
- int multi_connection;
-
- if (!imux->num_items)
- return 0;
-
- multi_connection = 0;
- for (i = 0; i < imux->num_items; i++) {
- cidx = get_input_connection(codec, spec->imux_info[i].adc,
- spec->imux_info[i].pin);
- if (cidx < 0)
- continue;
- input_conn[i] = spec->imux_info[i].adc;
- if (!codec->single_adc_amp)
- input_conn[i] |= cidx << 8;
- if (i > 0 && input_conn[i] != input_conn[0])
- multi_connection = 1;
- }
-
- prev_label = NULL;
- cidx = 0;
- for (i = 0; i < imux->num_items; i++) {
- hda_nid_t nid = spec->imux_info[i].pin;
- const char *label;
-
- label = hda_get_autocfg_input_label(codec, &spec->autocfg,
- spec->imux_info[i].index);
- if (label == prev_label)
- cidx++;
- else
- cidx = 0;
- prev_label = label;
-
- err = cx_auto_add_boost_volume(codec, i, label, cidx);
- if (err < 0)
- return err;
-
- if (!multi_connection) {
- if (i > 0)
- continue;
- err = cx_auto_add_capture_volume(codec, nid,
- "Capture", "", cidx);
- } else {
- bool dup_found = false;
- for (j = 0; j < i; j++) {
- if (input_conn[j] == input_conn[i]) {
- dup_found = true;
- break;
- }
- }
- if (dup_found)
- continue;
- err = cx_auto_add_capture_volume(codec, nid,
- label, " Capture", cidx);
- }
- if (err < 0)
- return err;
- }
-
- if (spec->private_imux.num_items > 1 && !spec->auto_mic) {
- err = snd_hda_add_new_ctls(codec, cx_auto_capture_mixers);
- if (err < 0)
- return err;
- }
-
- return 0;
-}
-
-static int cx_auto_build_controls(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- int err;
-
- err = cx_auto_build_output_controls(codec);
- if (err < 0)
- return err;
- err = cx_auto_build_input_controls(codec);
- if (err < 0)
- return err;
- err = conexant_build_controls(codec);
- if (err < 0)
- return err;
- err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
- if (err < 0)
- return err;
- if (spec->vmaster_mute.sw_kctl) {
- spec->vmaster_mute.hook = cx_auto_vmaster_hook;
- err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute,
- spec->vmaster_mute_led);
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-static int cx_auto_search_adcs(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- hda_nid_t nid, end_nid;
-
- end_nid = codec->start_nid + codec->num_nodes;
- for (nid = codec->start_nid; nid < end_nid; nid++) {
- unsigned int caps = get_wcaps(codec, nid);
- if (get_wcaps_type(caps) != AC_WID_AUD_IN)
- continue;
- if (caps & AC_WCAP_DIGITAL)
- continue;
- if (snd_BUG_ON(spec->num_adc_nids >=
- ARRAY_SIZE(spec->private_adc_nids)))
- break;
- spec->private_adc_nids[spec->num_adc_nids++] = nid;
- }
- spec->adc_nids = spec->private_adc_nids;
- return 0;
-}
-
-static const struct hda_codec_ops cx_auto_patch_ops = {
- .build_controls = cx_auto_build_controls,
- .build_pcms = conexant_build_pcms,
- .init = cx_auto_init,
- .free = conexant_free,
- .unsol_event = cx_auto_unsol_event,
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- .suspend = conexant_suspend,
-#endif
- .reboot_notify = snd_hda_shutup_pins,
-};
-
-/*
- * pin fix-up
- */
-struct cxt_pincfg {
- hda_nid_t nid;
- u32 val;
-};
-
-static void apply_pincfg(struct hda_codec *codec, const struct cxt_pincfg *cfg)
-{
- for (; cfg->nid; cfg++)
- snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
-
-}
-
-static void apply_pin_fixup(struct hda_codec *codec,
- const struct snd_pci_quirk *quirk,
- const struct cxt_pincfg **table)
-{
- quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
- if (quirk) {
- snd_printdd(KERN_INFO "hda_codec: applying pincfg for %s\n",
- quirk->name);
- apply_pincfg(codec, table[quirk->value]);
- }
-}
-
-enum {
- CXT_PINCFG_LENOVO_X200,
- CXT_PINCFG_LENOVO_TP410,
-};
-
-/* ThinkPad X200 & co with cxt5051 */
-static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = {
- { 0x16, 0x042140ff }, /* HP (seq# overridden) */
- { 0x17, 0x21a11000 }, /* dock-mic */
- { 0x19, 0x2121103f }, /* dock-HP */
- { 0x1c, 0x21440100 }, /* dock SPDIF out */
- {}
-};
-
-/* ThinkPad 410/420/510/520, X201 & co with cxt5066 */
-static const struct cxt_pincfg cxt_pincfg_lenovo_tp410[] = {
- { 0x19, 0x042110ff }, /* HP (seq# overridden) */
- { 0x1a, 0x21a190f0 }, /* dock-mic */
- { 0x1c, 0x212140ff }, /* dock-HP */
- {}
-};
-
-static const struct cxt_pincfg *cxt_pincfg_tbl[] = {
- [CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200,
- [CXT_PINCFG_LENOVO_TP410] = cxt_pincfg_lenovo_tp410,
-};
-
-static const struct snd_pci_quirk cxt5051_fixups[] = {
- SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200),
- {}
-};
-
-static const struct snd_pci_quirk cxt5066_fixups[] = {
- SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
- SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410),
- SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410),
- SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410),
- SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410),
- {}
-};
-
-/* add "fake" mute amp-caps to DACs on cx5051 so that mixer mute switches
- * can be created (bko#42825)
- */
-static void add_cx5051_fake_mutes(struct hda_codec *codec)
-{
- static hda_nid_t out_nids[] = {
- 0x10, 0x11, 0
- };
- hda_nid_t *p;
-
- for (p = out_nids; *p; p++)
- snd_hda_override_amp_caps(codec, *p, HDA_OUTPUT,
- AC_AMPCAP_MIN_MUTE |
- query_amp_caps(codec, *p, HDA_OUTPUT));
-}
-
-static int patch_conexant_auto(struct hda_codec *codec)
-{
- struct conexant_spec *spec;
- int err;
-
- printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
- codec->chip_name);
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- codec->spec = spec;
-
- switch (codec->vendor_id) {
- case 0x14f15045:
- codec->single_adc_amp = 1;
- break;
- case 0x14f15051:
- add_cx5051_fake_mutes(codec);
- codec->pin_amp_workaround = 1;
- apply_pin_fixup(codec, cxt5051_fixups, cxt_pincfg_tbl);
- break;
- default:
- codec->pin_amp_workaround = 1;
- apply_pin_fixup(codec, cxt5066_fixups, cxt_pincfg_tbl);
- }
-
- /* Show mute-led control only on HP laptops
- * This is a sort of white-list: on HP laptops, EAPD corresponds
- * only to the mute-LED without actualy amp function. Meanwhile,
- * others may use EAPD really as an amp switch, so it might be
- * not good to expose it blindly.
- */
- switch (codec->subsystem_id >> 16) {
- case 0x103c:
- spec->vmaster_mute_led = 1;
- break;
- }
-
- err = cx_auto_search_adcs(codec);
- if (err < 0)
- return err;
- err = cx_auto_parse_auto_config(codec);
- if (err < 0) {
- kfree(codec->spec);
- codec->spec = NULL;
- return err;
- }
- spec->capture_stream = &cx_auto_pcm_analog_capture;
- codec->patch_ops = cx_auto_patch_ops;
- if (spec->beep_amp)
- snd_hda_attach_beep_device(codec, spec->beep_amp);
-
- /* Some laptops with Conexant chips show stalls in S3 resume,
- * which falls into the single-cmd mode.
- * Better to make reset, then.
- */
- if (!codec->bus->sync_write) {
- snd_printd("hda_codec: "
- "Enable sync_write for stable communication\n");
- codec->bus->sync_write = 1;
- codec->bus->allow_bus_reset = 1;
- }
-
- return 0;
-}
-
-/*
- */
-
-static const struct hda_codec_preset snd_hda_preset_conexant[] = {
- { .id = 0x14f15045, .name = "CX20549 (Venice)",
- .patch = patch_cxt5045 },
- { .id = 0x14f15047, .name = "CX20551 (Waikiki)",
- .patch = patch_cxt5047 },
- { .id = 0x14f15051, .name = "CX20561 (Hermosa)",
- .patch = patch_cxt5051 },
- { .id = 0x14f15066, .name = "CX20582 (Pebble)",
- .patch = patch_cxt5066 },
- { .id = 0x14f15067, .name = "CX20583 (Pebble HSF)",
- .patch = patch_cxt5066 },
- { .id = 0x14f15068, .name = "CX20584",
- .patch = patch_cxt5066 },
- { .id = 0x14f15069, .name = "CX20585",
- .patch = patch_cxt5066 },
- { .id = 0x14f1506c, .name = "CX20588",
- .patch = patch_cxt5066 },
- { .id = 0x14f1506e, .name = "CX20590",
- .patch = patch_cxt5066 },
- { .id = 0x14f15097, .name = "CX20631",
- .patch = patch_conexant_auto },
- { .id = 0x14f15098, .name = "CX20632",
- .patch = patch_conexant_auto },
- { .id = 0x14f150a1, .name = "CX20641",
- .patch = patch_conexant_auto },
- { .id = 0x14f150a2, .name = "CX20642",
- .patch = patch_conexant_auto },
- { .id = 0x14f150ab, .name = "CX20651",
- .patch = patch_conexant_auto },
- { .id = 0x14f150ac, .name = "CX20652",
- .patch = patch_conexant_auto },
- { .id = 0x14f150b8, .name = "CX20664",
- .patch = patch_conexant_auto },
- { .id = 0x14f150b9, .name = "CX20665",
- .patch = patch_conexant_auto },
- {} /* terminator */
-};
-
-MODULE_ALIAS("snd-hda-codec-id:14f15045");
-MODULE_ALIAS("snd-hda-codec-id:14f15047");
-MODULE_ALIAS("snd-hda-codec-id:14f15051");
-MODULE_ALIAS("snd-hda-codec-id:14f15066");
-MODULE_ALIAS("snd-hda-codec-id:14f15067");
-MODULE_ALIAS("snd-hda-codec-id:14f15068");
-MODULE_ALIAS("snd-hda-codec-id:14f15069");
-MODULE_ALIAS("snd-hda-codec-id:14f1506c");
-MODULE_ALIAS("snd-hda-codec-id:14f1506e");
-MODULE_ALIAS("snd-hda-codec-id:14f15097");
-MODULE_ALIAS("snd-hda-codec-id:14f15098");
-MODULE_ALIAS("snd-hda-codec-id:14f150a1");
-MODULE_ALIAS("snd-hda-codec-id:14f150a2");
-MODULE_ALIAS("snd-hda-codec-id:14f150ab");
-MODULE_ALIAS("snd-hda-codec-id:14f150ac");
-MODULE_ALIAS("snd-hda-codec-id:14f150b8");
-MODULE_ALIAS("snd-hda-codec-id:14f150b9");
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Conexant HD-audio codec");
-
-static struct hda_codec_preset_list conexant_list = {
- .preset = snd_hda_preset_conexant,
- .owner = THIS_MODULE,
-};
-
-static int __init patch_conexant_init(void)
-{
- return snd_hda_add_codec_preset(&conexant_list);
-}
-
-static void __exit patch_conexant_exit(void)
-{
- snd_hda_delete_codec_preset(&conexant_list);
-}
-
-module_init(patch_conexant_init)
-module_exit(patch_conexant_exit)
diff --git a/ANDROID_3.4.5/sound/pci/hda/patch_hdmi.c b/ANDROID_3.4.5/sound/pci/hda/patch_hdmi.c
deleted file mode 100644
index 83f345f3..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/patch_hdmi.c
+++ /dev/null
@@ -1,1986 +0,0 @@
-/*
- *
- * patch_hdmi.c - routines for HDMI/DisplayPort codecs
- *
- * Copyright(c) 2008-2010 Intel Corporation. All rights reserved.
- * Copyright (c) 2006 ATI Technologies Inc.
- * Copyright (c) 2008 NVIDIA Corp. All rights reserved.
- * Copyright (c) 2008 Wei Ni <wni@nvidia.com>
- *
- * Authors:
- * Wu Fengguang <wfg@linux.intel.com>
- *
- * Maintained by:
- * Wu Fengguang <wfg@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/jack.h>
-#include "hda_codec.h"
-#include "hda_local.h"
-#include "hda_jack.h"
-
-static bool static_hdmi_pcm;
-module_param(static_hdmi_pcm, bool, 0644);
-MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
-
-/*
- * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device
- * could support N independent pipes, each of them can be connected to one or
- * more ports (DVI, HDMI or DisplayPort).
- *
- * The HDA correspondence of pipes/ports are converter/pin nodes.
- */
-#define MAX_HDMI_CVTS 8
-#define MAX_HDMI_PINS 8
-
-struct hdmi_spec_per_cvt {
- hda_nid_t cvt_nid;
- int assigned;
- unsigned int channels_min;
- unsigned int channels_max;
- u32 rates;
- u64 formats;
- unsigned int maxbps;
-};
-
-struct hdmi_spec_per_pin {
- hda_nid_t pin_nid;
- int num_mux_nids;
- hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
-
- struct hda_codec *codec;
- struct hdmi_eld sink_eld;
- struct delayed_work work;
- int repoll_count;
-};
-
-struct hdmi_spec {
- int num_cvts;
- struct hdmi_spec_per_cvt cvts[MAX_HDMI_CVTS];
-
- int num_pins;
- struct hdmi_spec_per_pin pins[MAX_HDMI_PINS];
- struct hda_pcm pcm_rec[MAX_HDMI_PINS];
-
- /*
- * Non-generic ATI/NVIDIA specific
- */
- struct hda_multi_out multiout;
- const struct hda_pcm_stream *pcm_playback;
-};
-
-
-struct hdmi_audio_infoframe {
- u8 type; /* 0x84 */
- u8 ver; /* 0x01 */
- u8 len; /* 0x0a */
-
- u8 checksum;
-
- u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */
- u8 SS01_SF24;
- u8 CXT04;
- u8 CA;
- u8 LFEPBL01_LSV36_DM_INH7;
-};
-
-struct dp_audio_infoframe {
- u8 type; /* 0x84 */
- u8 len; /* 0x1b */
- u8 ver; /* 0x11 << 2 */
-
- u8 CC02_CT47; /* match with HDMI infoframe from this on */
- u8 SS01_SF24;
- u8 CXT04;
- u8 CA;
- u8 LFEPBL01_LSV36_DM_INH7;
-};
-
-union audio_infoframe {
- struct hdmi_audio_infoframe hdmi;
- struct dp_audio_infoframe dp;
- u8 bytes[0];
-};
-
-/*
- * CEA speaker placement:
- *
- * FLH FCH FRH
- * FLW FL FLC FC FRC FR FRW
- *
- * LFE
- * TC
- *
- * RL RLC RC RRC RR
- *
- * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
- * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
- */
-enum cea_speaker_placement {
- FL = (1 << 0), /* Front Left */
- FC = (1 << 1), /* Front Center */
- FR = (1 << 2), /* Front Right */
- FLC = (1 << 3), /* Front Left Center */
- FRC = (1 << 4), /* Front Right Center */
- RL = (1 << 5), /* Rear Left */
- RC = (1 << 6), /* Rear Center */
- RR = (1 << 7), /* Rear Right */
- RLC = (1 << 8), /* Rear Left Center */
- RRC = (1 << 9), /* Rear Right Center */
- LFE = (1 << 10), /* Low Frequency Effect */
- FLW = (1 << 11), /* Front Left Wide */
- FRW = (1 << 12), /* Front Right Wide */
- FLH = (1 << 13), /* Front Left High */
- FCH = (1 << 14), /* Front Center High */
- FRH = (1 << 15), /* Front Right High */
- TC = (1 << 16), /* Top Center */
-};
-
-/*
- * ELD SA bits in the CEA Speaker Allocation data block
- */
-static int eld_speaker_allocation_bits[] = {
- [0] = FL | FR,
- [1] = LFE,
- [2] = FC,
- [3] = RL | RR,
- [4] = RC,
- [5] = FLC | FRC,
- [6] = RLC | RRC,
- /* the following are not defined in ELD yet */
- [7] = FLW | FRW,
- [8] = FLH | FRH,
- [9] = TC,
- [10] = FCH,
-};
-
-struct cea_channel_speaker_allocation {
- int ca_index;
- int speakers[8];
-
- /* derived values, just for convenience */
- int channels;
- int spk_mask;
-};
-
-/*
- * ALSA sequence is:
- *
- * surround40 surround41 surround50 surround51 surround71
- * ch0 front left = = = =
- * ch1 front right = = = =
- * ch2 rear left = = = =
- * ch3 rear right = = = =
- * ch4 LFE center center center
- * ch5 LFE LFE
- * ch6 side left
- * ch7 side right
- *
- * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR}
- */
-static int hdmi_channel_mapping[0x32][8] = {
- /* stereo */
- [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
- /* 2.1 */
- [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
- /* Dolby Surround */
- [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 },
- /* surround40 */
- [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 },
- /* 4ch */
- [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 },
- /* surround41 */
- [0x09] = { 0x00, 0x11, 0x24, 0x35, 0x42, 0xf3, 0xf6, 0xf7 },
- /* surround50 */
- [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 },
- /* surround51 */
- [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 },
- /* 7.1 */
- [0x13] = { 0x00, 0x11, 0x26, 0x37, 0x43, 0x52, 0x64, 0x75 },
-};
-
-/*
- * This is an ordered list!
- *
- * The preceding ones have better chances to be selected by
- * hdmi_channel_allocation().
- */
-static struct cea_channel_speaker_allocation channel_allocations[] = {
-/* channel: 7 6 5 4 3 2 1 0 */
-{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
- /* 2.1 */
-{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
- /* Dolby Surround */
-{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
- /* surround40 */
-{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
- /* surround41 */
-{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
- /* surround50 */
-{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
- /* surround51 */
-{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
- /* 6.1 */
-{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
- /* surround71 */
-{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
-
-{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
-{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
-{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
-{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
-{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
-{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
-{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
-{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
-{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
-{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
-{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
-{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
-{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
-{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
-{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
-{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
-{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
-{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
-{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
-{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
-{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
-{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
-{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
-{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
-{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
-{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
-{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
-{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
-{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
-{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
-{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
-{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
-{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
-{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
-{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
-{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
-{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
-{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
-{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
-{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
-{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
-};
-
-
-/*
- * HDMI routines
- */
-
-static int pin_nid_to_pin_index(struct hdmi_spec *spec, hda_nid_t pin_nid)
-{
- int pin_idx;
-
- for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++)
- if (spec->pins[pin_idx].pin_nid == pin_nid)
- return pin_idx;
-
- snd_printk(KERN_WARNING "HDMI: pin nid %d not registered\n", pin_nid);
- return -EINVAL;
-}
-
-static int hinfo_to_pin_index(struct hdmi_spec *spec,
- struct hda_pcm_stream *hinfo)
-{
- int pin_idx;
-
- for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++)
- if (&spec->pcm_rec[pin_idx].stream[0] == hinfo)
- return pin_idx;
-
- snd_printk(KERN_WARNING "HDMI: hinfo %p not registered\n", hinfo);
- return -EINVAL;
-}
-
-static int cvt_nid_to_cvt_index(struct hdmi_spec *spec, hda_nid_t cvt_nid)
-{
- int cvt_idx;
-
- for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++)
- if (spec->cvts[cvt_idx].cvt_nid == cvt_nid)
- return cvt_idx;
-
- snd_printk(KERN_WARNING "HDMI: cvt nid %d not registered\n", cvt_nid);
- return -EINVAL;
-}
-
-static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct hdmi_spec *spec;
- int pin_idx;
-
- spec = codec->spec;
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
-
- pin_idx = kcontrol->private_value;
- uinfo->count = spec->pins[pin_idx].sink_eld.eld_size;
-
- return 0;
-}
-
-static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct hdmi_spec *spec;
- int pin_idx;
-
- spec = codec->spec;
- pin_idx = kcontrol->private_value;
-
- memcpy(ucontrol->value.bytes.data,
- spec->pins[pin_idx].sink_eld.eld_buffer, ELD_MAX_SIZE);
-
- return 0;
-}
-
-static struct snd_kcontrol_new eld_bytes_ctl = {
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "ELD",
- .info = hdmi_eld_ctl_info,
- .get = hdmi_eld_ctl_get,
-};
-
-static int hdmi_create_eld_ctl(struct hda_codec *codec, int pin_idx,
- int device)
-{
- struct snd_kcontrol *kctl;
- struct hdmi_spec *spec = codec->spec;
- int err;
-
- kctl = snd_ctl_new1(&eld_bytes_ctl, codec);
- if (!kctl)
- return -ENOMEM;
- kctl->private_value = pin_idx;
- kctl->id.device = device;
-
- err = snd_hda_ctl_add(codec, spec->pins[pin_idx].pin_nid, kctl);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-#ifdef BE_PARANOID
-static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
- int *packet_index, int *byte_index)
-{
- int val;
-
- val = snd_hda_codec_read(codec, pin_nid, 0,
- AC_VERB_GET_HDMI_DIP_INDEX, 0);
-
- *packet_index = val >> 5;
- *byte_index = val & 0x1f;
-}
-#endif
-
-static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
- int packet_index, int byte_index)
-{
- int val;
-
- val = (packet_index << 5) | (byte_index & 0x1f);
-
- snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
-}
-
-static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid,
- unsigned char val)
-{
- snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
-}
-
-static void hdmi_init_pin(struct hda_codec *codec, hda_nid_t pin_nid)
-{
- /* Unmute */
- if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
- snd_hda_codec_write(codec, pin_nid, 0,
- AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
- /* Disable pin out until stream is active*/
- snd_hda_codec_write(codec, pin_nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
-}
-
-static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t cvt_nid)
-{
- return 1 + snd_hda_codec_read(codec, cvt_nid, 0,
- AC_VERB_GET_CVT_CHAN_COUNT, 0);
-}
-
-static void hdmi_set_channel_count(struct hda_codec *codec,
- hda_nid_t cvt_nid, int chs)
-{
- if (chs != hdmi_get_channel_count(codec, cvt_nid))
- snd_hda_codec_write(codec, cvt_nid, 0,
- AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
-}
-
-
-/*
- * Channel mapping routines
- */
-
-/*
- * Compute derived values in channel_allocations[].
- */
-static void init_channel_allocations(void)
-{
- int i, j;
- struct cea_channel_speaker_allocation *p;
-
- for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
- p = channel_allocations + i;
- p->channels = 0;
- p->spk_mask = 0;
- for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
- if (p->speakers[j]) {
- p->channels++;
- p->spk_mask |= p->speakers[j];
- }
- }
-}
-
-/*
- * The transformation takes two steps:
- *
- * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
- * spk_mask => (channel_allocations[]) => ai->CA
- *
- * TODO: it could select the wrong CA from multiple candidates.
-*/
-static int hdmi_channel_allocation(struct hdmi_eld *eld, int channels)
-{
- int i;
- int ca = 0;
- int spk_mask = 0;
- char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
-
- /*
- * CA defaults to 0 for basic stereo audio
- */
- if (channels <= 2)
- return 0;
-
- /*
- * expand ELD's speaker allocation mask
- *
- * ELD tells the speaker mask in a compact(paired) form,
- * expand ELD's notions to match the ones used by Audio InfoFrame.
- */
- for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
- if (eld->spk_alloc & (1 << i))
- spk_mask |= eld_speaker_allocation_bits[i];
- }
-
- /* search for the first working match in the CA table */
- for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
- if (channels == channel_allocations[i].channels &&
- (spk_mask & channel_allocations[i].spk_mask) ==
- channel_allocations[i].spk_mask) {
- ca = channel_allocations[i].ca_index;
- break;
- }
- }
-
- snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
- snd_printdd("HDMI: select CA 0x%x for %d-channel allocation: %s\n",
- ca, channels, buf);
-
- return ca;
-}
-
-static void hdmi_debug_channel_mapping(struct hda_codec *codec,
- hda_nid_t pin_nid)
-{
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- int i;
- int slot;
-
- for (i = 0; i < 8; i++) {
- slot = snd_hda_codec_read(codec, pin_nid, 0,
- AC_VERB_GET_HDMI_CHAN_SLOT, i);
- printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
- slot >> 4, slot & 0xf);
- }
-#endif
-}
-
-
-static void hdmi_setup_channel_mapping(struct hda_codec *codec,
- hda_nid_t pin_nid,
- int ca)
-{
- int i;
- int err;
-
- if (hdmi_channel_mapping[ca][1] == 0) {
- for (i = 0; i < channel_allocations[ca].channels; i++)
- hdmi_channel_mapping[ca][i] = i | (i << 4);
- for (; i < 8; i++)
- hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
- }
-
- for (i = 0; i < 8; i++) {
- err = snd_hda_codec_write(codec, pin_nid, 0,
- AC_VERB_SET_HDMI_CHAN_SLOT,
- hdmi_channel_mapping[ca][i]);
- if (err) {
- snd_printdd(KERN_NOTICE
- "HDMI: channel mapping failed\n");
- break;
- }
- }
-
- hdmi_debug_channel_mapping(codec, pin_nid);
-}
-
-
-/*
- * Audio InfoFrame routines
- */
-
-/*
- * Enable Audio InfoFrame Transmission
- */
-static void hdmi_start_infoframe_trans(struct hda_codec *codec,
- hda_nid_t pin_nid)
-{
- hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
- snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
- AC_DIPXMIT_BEST);
-}
-
-/*
- * Disable Audio InfoFrame Transmission
- */
-static void hdmi_stop_infoframe_trans(struct hda_codec *codec,
- hda_nid_t pin_nid)
-{
- hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
- snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
- AC_DIPXMIT_DISABLE);
-}
-
-static void hdmi_debug_dip_size(struct hda_codec *codec, hda_nid_t pin_nid)
-{
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- int i;
- int size;
-
- size = snd_hdmi_get_eld_size(codec, pin_nid);
- printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
-
- for (i = 0; i < 8; i++) {
- size = snd_hda_codec_read(codec, pin_nid, 0,
- AC_VERB_GET_HDMI_DIP_SIZE, i);
- printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
- }
-#endif
-}
-
-static void hdmi_clear_dip_buffers(struct hda_codec *codec, hda_nid_t pin_nid)
-{
-#ifdef BE_PARANOID
- int i, j;
- int size;
- int pi, bi;
- for (i = 0; i < 8; i++) {
- size = snd_hda_codec_read(codec, pin_nid, 0,
- AC_VERB_GET_HDMI_DIP_SIZE, i);
- if (size == 0)
- continue;
-
- hdmi_set_dip_index(codec, pin_nid, i, 0x0);
- for (j = 1; j < 1000; j++) {
- hdmi_write_dip_byte(codec, pin_nid, 0x0);
- hdmi_get_dip_index(codec, pin_nid, &pi, &bi);
- if (pi != i)
- snd_printd(KERN_INFO "dip index %d: %d != %d\n",
- bi, pi, i);
- if (bi == 0) /* byte index wrapped around */
- break;
- }
- snd_printd(KERN_INFO
- "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n",
- i, size, j);
- }
-#endif
-}
-
-static void hdmi_checksum_audio_infoframe(struct hdmi_audio_infoframe *hdmi_ai)
-{
- u8 *bytes = (u8 *)hdmi_ai;
- u8 sum = 0;
- int i;
-
- hdmi_ai->checksum = 0;
-
- for (i = 0; i < sizeof(*hdmi_ai); i++)
- sum += bytes[i];
-
- hdmi_ai->checksum = -sum;
-}
-
-static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
- hda_nid_t pin_nid,
- u8 *dip, int size)
-{
- int i;
-
- hdmi_debug_dip_size(codec, pin_nid);
- hdmi_clear_dip_buffers(codec, pin_nid); /* be paranoid */
-
- hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
- for (i = 0; i < size; i++)
- hdmi_write_dip_byte(codec, pin_nid, dip[i]);
-}
-
-static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
- u8 *dip, int size)
-{
- u8 val;
- int i;
-
- if (snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_DIP_XMIT, 0)
- != AC_DIPXMIT_BEST)
- return false;
-
- hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
- for (i = 0; i < size; i++) {
- val = snd_hda_codec_read(codec, pin_nid, 0,
- AC_VERB_GET_HDMI_DIP_DATA, 0);
- if (val != dip[i])
- return false;
- }
-
- return true;
-}
-
-static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
- struct snd_pcm_substream *substream)
-{
- struct hdmi_spec *spec = codec->spec;
- struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
- hda_nid_t pin_nid = per_pin->pin_nid;
- int channels = substream->runtime->channels;
- struct hdmi_eld *eld;
- int ca;
- union audio_infoframe ai;
-
- eld = &spec->pins[pin_idx].sink_eld;
- if (!eld->monitor_present)
- return;
-
- ca = hdmi_channel_allocation(eld, channels);
-
- memset(&ai, 0, sizeof(ai));
- if (eld->conn_type == 0) { /* HDMI */
- struct hdmi_audio_infoframe *hdmi_ai = &ai.hdmi;
-
- hdmi_ai->type = 0x84;
- hdmi_ai->ver = 0x01;
- hdmi_ai->len = 0x0a;
- hdmi_ai->CC02_CT47 = channels - 1;
- hdmi_ai->CA = ca;
- hdmi_checksum_audio_infoframe(hdmi_ai);
- } else if (eld->conn_type == 1) { /* DisplayPort */
- struct dp_audio_infoframe *dp_ai = &ai.dp;
-
- dp_ai->type = 0x84;
- dp_ai->len = 0x1b;
- dp_ai->ver = 0x11 << 2;
- dp_ai->CC02_CT47 = channels - 1;
- dp_ai->CA = ca;
- } else {
- snd_printd("HDMI: unknown connection type at pin %d\n",
- pin_nid);
- return;
- }
-
- /*
- * sizeof(ai) is used instead of sizeof(*hdmi_ai) or
- * sizeof(*dp_ai) to avoid partial match/update problems when
- * the user switches between HDMI/DP monitors.
- */
- if (!hdmi_infoframe_uptodate(codec, pin_nid, ai.bytes,
- sizeof(ai))) {
- snd_printdd("hdmi_setup_audio_infoframe: "
- "pin=%d channels=%d\n",
- pin_nid,
- channels);
- hdmi_setup_channel_mapping(codec, pin_nid, ca);
- hdmi_stop_infoframe_trans(codec, pin_nid);
- hdmi_fill_audio_infoframe(codec, pin_nid,
- ai.bytes, sizeof(ai));
- hdmi_start_infoframe_trans(codec, pin_nid);
- }
-}
-
-
-/*
- * Unsolicited events
- */
-
-static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll);
-
-static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
-{
- struct hdmi_spec *spec = codec->spec;
- int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
- int pin_nid;
- int pin_idx;
- struct hda_jack_tbl *jack;
-
- jack = snd_hda_jack_tbl_get_from_tag(codec, tag);
- if (!jack)
- return;
- pin_nid = jack->nid;
- jack->jack_dirty = 1;
-
- _snd_printd(SND_PR_VERBOSE,
- "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
- codec->addr, pin_nid,
- !!(res & AC_UNSOL_RES_PD), !!(res & AC_UNSOL_RES_ELDV));
-
- pin_idx = pin_nid_to_pin_index(spec, pin_nid);
- if (pin_idx < 0)
- return;
-
- hdmi_present_sense(&spec->pins[pin_idx], 1);
- snd_hda_jack_report_sync(codec);
-}
-
-static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
-{
- int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
- int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
- int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
- int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
-
- printk(KERN_INFO
- "HDMI CP event: CODEC=%d PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
- codec->addr,
- tag,
- subtag,
- cp_state,
- cp_ready);
-
- /* TODO */
- if (cp_state)
- ;
- if (cp_ready)
- ;
-}
-
-
-static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
- int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
-
- if (!snd_hda_jack_tbl_get_from_tag(codec, tag)) {
- snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
- return;
- }
-
- if (subtag == 0)
- hdmi_intrinsic_event(codec, res);
- else
- hdmi_non_intrinsic_event(codec, res);
-}
-
-/*
- * Callbacks
- */
-
-/* HBR should be Non-PCM, 8 channels */
-#define is_hbr_format(format) \
- ((format & AC_FMT_TYPE_NON_PCM) && (format & AC_FMT_CHAN_MASK) == 7)
-
-static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
- hda_nid_t pin_nid, u32 stream_tag, int format)
-{
- int pinctl;
- int new_pinctl = 0;
-
- if (snd_hda_query_pin_caps(codec, pin_nid) & AC_PINCAP_HBR) {
- pinctl = snd_hda_codec_read(codec, pin_nid, 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
-
- new_pinctl = pinctl & ~AC_PINCTL_EPT;
- if (is_hbr_format(format))
- new_pinctl |= AC_PINCTL_EPT_HBR;
- else
- new_pinctl |= AC_PINCTL_EPT_NATIVE;
-
- snd_printdd("hdmi_setup_stream: "
- "NID=0x%x, %spinctl=0x%x\n",
- pin_nid,
- pinctl == new_pinctl ? "" : "new-",
- new_pinctl);
-
- if (pinctl != new_pinctl)
- snd_hda_codec_write(codec, pin_nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- new_pinctl);
-
- }
- if (is_hbr_format(format) && !new_pinctl) {
- snd_printdd("hdmi_setup_stream: HBR is not supported\n");
- return -EINVAL;
- }
-
- snd_hda_codec_setup_stream(codec, cvt_nid, stream_tag, 0, format);
- return 0;
-}
-
-/*
- * HDA PCM callbacks
- */
-static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct hdmi_spec *spec = codec->spec;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int pin_idx, cvt_idx, mux_idx = 0;
- struct hdmi_spec_per_pin *per_pin;
- struct hdmi_eld *eld;
- struct hdmi_spec_per_cvt *per_cvt = NULL;
- int pinctl;
-
- /* Validate hinfo */
- pin_idx = hinfo_to_pin_index(spec, hinfo);
- if (snd_BUG_ON(pin_idx < 0))
- return -EINVAL;
- per_pin = &spec->pins[pin_idx];
- eld = &per_pin->sink_eld;
-
- /* Dynamically assign converter to stream */
- for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) {
- per_cvt = &spec->cvts[cvt_idx];
-
- /* Must not already be assigned */
- if (per_cvt->assigned)
- continue;
- /* Must be in pin's mux's list of converters */
- for (mux_idx = 0; mux_idx < per_pin->num_mux_nids; mux_idx++)
- if (per_pin->mux_nids[mux_idx] == per_cvt->cvt_nid)
- break;
- /* Not in mux list */
- if (mux_idx == per_pin->num_mux_nids)
- continue;
- break;
- }
- /* No free converters */
- if (cvt_idx == spec->num_cvts)
- return -ENODEV;
-
- /* Claim converter */
- per_cvt->assigned = 1;
- hinfo->nid = per_cvt->cvt_nid;
-
- snd_hda_codec_write(codec, per_pin->pin_nid, 0,
- AC_VERB_SET_CONNECT_SEL,
- mux_idx);
- pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
- snd_hda_codec_write(codec, per_pin->pin_nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- pinctl | PIN_OUT);
- snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid);
-
- /* Initially set the converter's capabilities */
- hinfo->channels_min = per_cvt->channels_min;
- hinfo->channels_max = per_cvt->channels_max;
- hinfo->rates = per_cvt->rates;
- hinfo->formats = per_cvt->formats;
- hinfo->maxbps = per_cvt->maxbps;
-
- /* Restrict capabilities by ELD if this isn't disabled */
- if (!static_hdmi_pcm && eld->eld_valid) {
- snd_hdmi_eld_update_pcm_info(eld, hinfo);
- if (hinfo->channels_min > hinfo->channels_max ||
- !hinfo->rates || !hinfo->formats)
- return -ENODEV;
- }
-
- /* Store the updated parameters */
- runtime->hw.channels_min = hinfo->channels_min;
- runtime->hw.channels_max = hinfo->channels_max;
- runtime->hw.formats = hinfo->formats;
- runtime->hw.rates = hinfo->rates;
-
- snd_pcm_hw_constraint_step(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS, 2);
- return 0;
-}
-
-/*
- * HDA/HDMI auto parsing
- */
-static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx)
-{
- struct hdmi_spec *spec = codec->spec;
- struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
- hda_nid_t pin_nid = per_pin->pin_nid;
-
- if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
- snd_printk(KERN_WARNING
- "HDMI: pin %d wcaps %#x "
- "does not support connection list\n",
- pin_nid, get_wcaps(codec, pin_nid));
- return -EINVAL;
- }
-
- per_pin->num_mux_nids = snd_hda_get_connections(codec, pin_nid,
- per_pin->mux_nids,
- HDA_MAX_CONNECTIONS);
-
- return 0;
-}
-
-static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
-{
- struct hda_codec *codec = per_pin->codec;
- struct hdmi_eld *eld = &per_pin->sink_eld;
- hda_nid_t pin_nid = per_pin->pin_nid;
- /*
- * Always execute a GetPinSense verb here, even when called from
- * hdmi_intrinsic_event; for some NVIDIA HW, the unsolicited
- * response's PD bit is not the real PD value, but indicates that
- * the real PD value changed. An older version of the HD-audio
- * specification worked this way. Hence, we just ignore the data in
- * the unsolicited response to avoid custom WARs.
- */
- int present = snd_hda_pin_sense(codec, pin_nid);
- bool eld_valid = false;
-
- memset(eld, 0, offsetof(struct hdmi_eld, eld_buffer));
-
- eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
- if (eld->monitor_present)
- eld_valid = !!(present & AC_PINSENSE_ELDV);
-
- _snd_printd(SND_PR_VERBOSE,
- "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
- codec->addr, pin_nid, eld->monitor_present, eld_valid);
-
- if (eld_valid) {
- if (!snd_hdmi_get_eld(eld, codec, pin_nid))
- snd_hdmi_show_eld(eld);
- else if (repoll) {
- queue_delayed_work(codec->bus->workq,
- &per_pin->work,
- msecs_to_jiffies(300));
- }
- }
-}
-
-static void hdmi_repoll_eld(struct work_struct *work)
-{
- struct hdmi_spec_per_pin *per_pin =
- container_of(to_delayed_work(work), struct hdmi_spec_per_pin, work);
-
- if (per_pin->repoll_count++ > 6)
- per_pin->repoll_count = 0;
-
- hdmi_present_sense(per_pin, per_pin->repoll_count);
-}
-
-static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
-{
- struct hdmi_spec *spec = codec->spec;
- unsigned int caps, config;
- int pin_idx;
- struct hdmi_spec_per_pin *per_pin;
- int err;
-
- caps = snd_hda_param_read(codec, pin_nid, AC_PAR_PIN_CAP);
- if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
- return 0;
-
- config = snd_hda_codec_read(codec, pin_nid, 0,
- AC_VERB_GET_CONFIG_DEFAULT, 0);
- if (get_defcfg_connect(config) == AC_JACK_PORT_NONE)
- return 0;
-
- if (snd_BUG_ON(spec->num_pins >= MAX_HDMI_PINS))
- return -E2BIG;
-
- pin_idx = spec->num_pins;
- per_pin = &spec->pins[pin_idx];
-
- per_pin->pin_nid = pin_nid;
-
- err = hdmi_read_pin_conn(codec, pin_idx);
- if (err < 0)
- return err;
-
- spec->num_pins++;
-
- return 0;
-}
-
-static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
-{
- struct hdmi_spec *spec = codec->spec;
- int cvt_idx;
- struct hdmi_spec_per_cvt *per_cvt;
- unsigned int chans;
- int err;
-
- if (snd_BUG_ON(spec->num_cvts >= MAX_HDMI_CVTS))
- return -E2BIG;
-
- chans = get_wcaps(codec, cvt_nid);
- chans = get_wcaps_channels(chans);
-
- cvt_idx = spec->num_cvts;
- per_cvt = &spec->cvts[cvt_idx];
-
- per_cvt->cvt_nid = cvt_nid;
- per_cvt->channels_min = 2;
- if (chans <= 16)
- per_cvt->channels_max = chans;
-
- err = snd_hda_query_supported_pcm(codec, cvt_nid,
- &per_cvt->rates,
- &per_cvt->formats,
- &per_cvt->maxbps);
- if (err < 0)
- return err;
-
- spec->num_cvts++;
-
- return 0;
-}
-
-static int hdmi_parse_codec(struct hda_codec *codec)
-{
- hda_nid_t nid;
- int i, nodes;
-
- nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
- if (!nid || nodes < 0) {
- snd_printk(KERN_WARNING "HDMI: failed to get afg sub nodes\n");
- return -EINVAL;
- }
-
- for (i = 0; i < nodes; i++, nid++) {
- unsigned int caps;
- unsigned int type;
-
- caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
- type = get_wcaps_type(caps);
-
- if (!(caps & AC_WCAP_DIGITAL))
- continue;
-
- switch (type) {
- case AC_WID_AUD_OUT:
- hdmi_add_cvt(codec, nid);
- break;
- case AC_WID_PIN:
- hdmi_add_pin(codec, nid);
- break;
- }
- }
-
- /*
- * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
- * can be lost and presence sense verb will become inaccurate if the
- * HDA link is powered off at hot plug or hw initialization time.
- */
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) &
- AC_PWRST_EPSS))
- codec->bus->power_keep_link_on = 1;
-#endif
-
- return 0;
-}
-
-/*
- */
-static char *get_hdmi_pcm_name(int idx)
-{
- static char names[MAX_HDMI_PINS][8];
- sprintf(&names[idx][0], "HDMI %d", idx);
- return &names[idx][0];
-}
-
-/*
- * HDMI callbacks
- */
-
-static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- hda_nid_t cvt_nid = hinfo->nid;
- struct hdmi_spec *spec = codec->spec;
- int pin_idx = hinfo_to_pin_index(spec, hinfo);
- hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid;
-
- hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels);
-
- hdmi_setup_audio_infoframe(codec, pin_idx, substream);
-
- return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
-}
-
-static int generic_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct hdmi_spec *spec = codec->spec;
- int cvt_idx, pin_idx;
- struct hdmi_spec_per_cvt *per_cvt;
- struct hdmi_spec_per_pin *per_pin;
- int pinctl;
-
- snd_hda_codec_cleanup_stream(codec, hinfo->nid);
-
- if (hinfo->nid) {
- cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid);
- if (snd_BUG_ON(cvt_idx < 0))
- return -EINVAL;
- per_cvt = &spec->cvts[cvt_idx];
-
- snd_BUG_ON(!per_cvt->assigned);
- per_cvt->assigned = 0;
- hinfo->nid = 0;
-
- pin_idx = hinfo_to_pin_index(spec, hinfo);
- if (snd_BUG_ON(pin_idx < 0))
- return -EINVAL;
- per_pin = &spec->pins[pin_idx];
-
- pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
- snd_hda_codec_write(codec, per_pin->pin_nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- pinctl & ~PIN_OUT);
- snd_hda_spdif_ctls_unassign(codec, pin_idx);
- }
-
- return 0;
-}
-
-static const struct hda_pcm_ops generic_ops = {
- .open = hdmi_pcm_open,
- .prepare = generic_hdmi_playback_pcm_prepare,
- .cleanup = generic_hdmi_playback_pcm_cleanup,
-};
-
-static int generic_hdmi_build_pcms(struct hda_codec *codec)
-{
- struct hdmi_spec *spec = codec->spec;
- int pin_idx;
-
- for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
- struct hda_pcm *info;
- struct hda_pcm_stream *pstr;
-
- info = &spec->pcm_rec[pin_idx];
- info->name = get_hdmi_pcm_name(pin_idx);
- info->pcm_type = HDA_PCM_TYPE_HDMI;
-
- pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
- pstr->substreams = 1;
- pstr->ops = generic_ops;
- /* other pstr fields are set in open */
- }
-
- codec->num_pcms = spec->num_pins;
- codec->pcm_info = spec->pcm_rec;
-
- return 0;
-}
-
-static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx)
-{
- char hdmi_str[32] = "HDMI/DP";
- struct hdmi_spec *spec = codec->spec;
- struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
- int pcmdev = spec->pcm_rec[pin_idx].device;
-
- if (pcmdev > 0)
- sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev);
-
- return snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str, 0);
-}
-
-static int generic_hdmi_build_controls(struct hda_codec *codec)
-{
- struct hdmi_spec *spec = codec->spec;
- int err;
- int pin_idx;
-
- for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
- struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
-
- err = generic_hdmi_build_jack(codec, pin_idx);
- if (err < 0)
- return err;
-
- err = snd_hda_create_spdif_out_ctls(codec,
- per_pin->pin_nid,
- per_pin->mux_nids[0]);
- if (err < 0)
- return err;
- snd_hda_spdif_ctls_unassign(codec, pin_idx);
-
- /* add control for ELD Bytes */
- err = hdmi_create_eld_ctl(codec,
- pin_idx,
- spec->pcm_rec[pin_idx].device);
-
- if (err < 0)
- return err;
-
- hdmi_present_sense(per_pin, 0);
- }
-
- return 0;
-}
-
-static int generic_hdmi_init(struct hda_codec *codec)
-{
- struct hdmi_spec *spec = codec->spec;
- int pin_idx;
-
- for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
- struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
- hda_nid_t pin_nid = per_pin->pin_nid;
- struct hdmi_eld *eld = &per_pin->sink_eld;
-
- hdmi_init_pin(codec, pin_nid);
- snd_hda_jack_detect_enable(codec, pin_nid, pin_nid);
-
- per_pin->codec = codec;
- INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld);
- snd_hda_eld_proc_new(codec, eld, pin_idx);
- }
- snd_hda_jack_report_sync(codec);
- return 0;
-}
-
-static void generic_hdmi_free(struct hda_codec *codec)
-{
- struct hdmi_spec *spec = codec->spec;
- int pin_idx;
-
- for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
- struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
- struct hdmi_eld *eld = &per_pin->sink_eld;
-
- cancel_delayed_work(&per_pin->work);
- snd_hda_eld_proc_free(codec, eld);
- }
-
- flush_workqueue(codec->bus->workq);
- kfree(spec);
-}
-
-static const struct hda_codec_ops generic_hdmi_patch_ops = {
- .init = generic_hdmi_init,
- .free = generic_hdmi_free,
- .build_pcms = generic_hdmi_build_pcms,
- .build_controls = generic_hdmi_build_controls,
- .unsol_event = hdmi_unsol_event,
-};
-
-static int patch_generic_hdmi(struct hda_codec *codec)
-{
- struct hdmi_spec *spec;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->spec = spec;
- if (hdmi_parse_codec(codec) < 0) {
- codec->spec = NULL;
- kfree(spec);
- return -EINVAL;
- }
- codec->patch_ops = generic_hdmi_patch_ops;
-
- init_channel_allocations();
-
- return 0;
-}
-
-/*
- * Shared non-generic implementations
- */
-
-static int simple_playback_build_pcms(struct hda_codec *codec)
-{
- struct hdmi_spec *spec = codec->spec;
- struct hda_pcm *info = spec->pcm_rec;
- int i;
-
- codec->num_pcms = spec->num_cvts;
- codec->pcm_info = info;
-
- for (i = 0; i < codec->num_pcms; i++, info++) {
- unsigned int chans;
- struct hda_pcm_stream *pstr;
-
- chans = get_wcaps(codec, spec->cvts[i].cvt_nid);
- chans = get_wcaps_channels(chans);
-
- info->name = get_hdmi_pcm_name(i);
- info->pcm_type = HDA_PCM_TYPE_HDMI;
- pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
- snd_BUG_ON(!spec->pcm_playback);
- *pstr = *spec->pcm_playback;
- pstr->nid = spec->cvts[i].cvt_nid;
- if (pstr->channels_max <= 2 && chans && chans <= 16)
- pstr->channels_max = chans;
- }
-
- return 0;
-}
-
-static int simple_playback_build_controls(struct hda_codec *codec)
-{
- struct hdmi_spec *spec = codec->spec;
- int err;
- int i;
-
- for (i = 0; i < codec->num_pcms; i++) {
- err = snd_hda_create_spdif_out_ctls(codec,
- spec->cvts[i].cvt_nid,
- spec->cvts[i].cvt_nid);
- if (err < 0)
- return err;
- }
-
- return 0;
-}
-
-static void simple_playback_free(struct hda_codec *codec)
-{
- struct hdmi_spec *spec = codec->spec;
-
- kfree(spec);
-}
-
-/*
- * Nvidia specific implementations
- */
-
-#define Nv_VERB_SET_Channel_Allocation 0xF79
-#define Nv_VERB_SET_Info_Frame_Checksum 0xF7A
-#define Nv_VERB_SET_Audio_Protection_On 0xF98
-#define Nv_VERB_SET_Audio_Protection_Off 0xF99
-
-#define nvhdmi_master_con_nid_7x 0x04
-#define nvhdmi_master_pin_nid_7x 0x05
-
-static const hda_nid_t nvhdmi_con_nids_7x[4] = {
- /*front, rear, clfe, rear_surr */
- 0x6, 0x8, 0xa, 0xc,
-};
-
-static const struct hda_verb nvhdmi_basic_init_7x[] = {
- /* set audio protect on */
- { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
- /* enable digital output on pin widget */
- { 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
- { 0x7, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
- { 0x9, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
- { 0xb, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
- { 0xd, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
- {} /* terminator */
-};
-
-#ifdef LIMITED_RATE_FMT_SUPPORT
-/* support only the safe format and rate */
-#define SUPPORTED_RATES SNDRV_PCM_RATE_48000
-#define SUPPORTED_MAXBPS 16
-#define SUPPORTED_FORMATS SNDRV_PCM_FMTBIT_S16_LE
-#else
-/* support all rates and formats */
-#define SUPPORTED_RATES \
- (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
- SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
- SNDRV_PCM_RATE_192000)
-#define SUPPORTED_MAXBPS 24
-#define SUPPORTED_FORMATS \
- (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
-#endif
-
-static int nvhdmi_7x_init(struct hda_codec *codec)
-{
- snd_hda_sequence_write(codec, nvhdmi_basic_init_7x);
- return 0;
-}
-
-static unsigned int channels_2_6_8[] = {
- 2, 6, 8
-};
-
-static unsigned int channels_2_8[] = {
- 2, 8
-};
-
-static struct snd_pcm_hw_constraint_list hw_constraints_2_6_8_channels = {
- .count = ARRAY_SIZE(channels_2_6_8),
- .list = channels_2_6_8,
- .mask = 0,
-};
-
-static struct snd_pcm_hw_constraint_list hw_constraints_2_8_channels = {
- .count = ARRAY_SIZE(channels_2_8),
- .list = channels_2_8,
- .mask = 0,
-};
-
-static int simple_playback_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct hdmi_spec *spec = codec->spec;
- struct snd_pcm_hw_constraint_list *hw_constraints_channels = NULL;
-
- switch (codec->preset->id) {
- case 0x10de0002:
- case 0x10de0003:
- case 0x10de0005:
- case 0x10de0006:
- hw_constraints_channels = &hw_constraints_2_8_channels;
- break;
- case 0x10de0007:
- hw_constraints_channels = &hw_constraints_2_6_8_channels;
- break;
- default:
- break;
- }
-
- if (hw_constraints_channels != NULL) {
- snd_pcm_hw_constraint_list(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- hw_constraints_channels);
- } else {
- snd_pcm_hw_constraint_step(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS, 2);
- }
-
- return snd_hda_multi_out_dig_open(codec, &spec->multiout);
-}
-
-static int simple_playback_pcm_close(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct hdmi_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_close(codec, &spec->multiout);
-}
-
-static int simple_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct hdmi_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
- stream_tag, format, substream);
-}
-
-static void nvhdmi_8ch_7x_set_info_frame_parameters(struct hda_codec *codec,
- int channels)
-{
- unsigned int chanmask;
- int chan = channels ? (channels - 1) : 1;
-
- switch (channels) {
- default:
- case 0:
- case 2:
- chanmask = 0x00;
- break;
- case 4:
- chanmask = 0x08;
- break;
- case 6:
- chanmask = 0x0b;
- break;
- case 8:
- chanmask = 0x13;
- break;
- }
-
- /* Set the audio infoframe channel allocation and checksum fields. The
- * channel count is computed implicitly by the hardware. */
- snd_hda_codec_write(codec, 0x1, 0,
- Nv_VERB_SET_Channel_Allocation, chanmask);
-
- snd_hda_codec_write(codec, 0x1, 0,
- Nv_VERB_SET_Info_Frame_Checksum,
- (0x71 - chan - chanmask));
-}
-
-static int nvhdmi_8ch_7x_pcm_close(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct hdmi_spec *spec = codec->spec;
- int i;
-
- snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x,
- 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
- for (i = 0; i < 4; i++) {
- /* set the stream id */
- snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
- AC_VERB_SET_CHANNEL_STREAMID, 0);
- /* set the stream format */
- snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
- AC_VERB_SET_STREAM_FORMAT, 0);
- }
-
- /* The audio hardware sends a channel count of 0x7 (8ch) when all the
- * streams are disabled. */
- nvhdmi_8ch_7x_set_info_frame_parameters(codec, 8);
-
- return snd_hda_multi_out_dig_close(codec, &spec->multiout);
-}
-
-static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- int chs;
- unsigned int dataDCC2, channel_id;
- int i;
- struct hdmi_spec *spec = codec->spec;
- struct hda_spdif_out *spdif =
- snd_hda_spdif_out_of_nid(codec, spec->cvts[0].cvt_nid);
-
- mutex_lock(&codec->spdif_mutex);
-
- chs = substream->runtime->channels;
-
- dataDCC2 = 0x2;
-
- /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
- if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE))
- snd_hda_codec_write(codec,
- nvhdmi_master_con_nid_7x,
- 0,
- AC_VERB_SET_DIGI_CONVERT_1,
- spdif->ctls & ~AC_DIG1_ENABLE & 0xff);
-
- /* set the stream id */
- snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
- AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0);
-
- /* set the stream format */
- snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
- AC_VERB_SET_STREAM_FORMAT, format);
-
- /* turn on again (if needed) */
- /* enable and set the channel status audio/data flag */
- if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE)) {
- snd_hda_codec_write(codec,
- nvhdmi_master_con_nid_7x,
- 0,
- AC_VERB_SET_DIGI_CONVERT_1,
- spdif->ctls & 0xff);
- snd_hda_codec_write(codec,
- nvhdmi_master_con_nid_7x,
- 0,
- AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
- }
-
- for (i = 0; i < 4; i++) {
- if (chs == 2)
- channel_id = 0;
- else
- channel_id = i * 2;
-
- /* turn off SPDIF once;
- *otherwise the IEC958 bits won't be updated
- */
- if (codec->spdif_status_reset &&
- (spdif->ctls & AC_DIG1_ENABLE))
- snd_hda_codec_write(codec,
- nvhdmi_con_nids_7x[i],
- 0,
- AC_VERB_SET_DIGI_CONVERT_1,
- spdif->ctls & ~AC_DIG1_ENABLE & 0xff);
- /* set the stream id */
- snd_hda_codec_write(codec,
- nvhdmi_con_nids_7x[i],
- 0,
- AC_VERB_SET_CHANNEL_STREAMID,
- (stream_tag << 4) | channel_id);
- /* set the stream format */
- snd_hda_codec_write(codec,
- nvhdmi_con_nids_7x[i],
- 0,
- AC_VERB_SET_STREAM_FORMAT,
- format);
- /* turn on again (if needed) */
- /* enable and set the channel status audio/data flag */
- if (codec->spdif_status_reset &&
- (spdif->ctls & AC_DIG1_ENABLE)) {
- snd_hda_codec_write(codec,
- nvhdmi_con_nids_7x[i],
- 0,
- AC_VERB_SET_DIGI_CONVERT_1,
- spdif->ctls & 0xff);
- snd_hda_codec_write(codec,
- nvhdmi_con_nids_7x[i],
- 0,
- AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
- }
- }
-
- nvhdmi_8ch_7x_set_info_frame_parameters(codec, chs);
-
- mutex_unlock(&codec->spdif_mutex);
- return 0;
-}
-
-static const struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 8,
- .nid = nvhdmi_master_con_nid_7x,
- .rates = SUPPORTED_RATES,
- .maxbps = SUPPORTED_MAXBPS,
- .formats = SUPPORTED_FORMATS,
- .ops = {
- .open = simple_playback_pcm_open,
- .close = nvhdmi_8ch_7x_pcm_close,
- .prepare = nvhdmi_8ch_7x_pcm_prepare
- },
-};
-
-static const struct hda_pcm_stream nvhdmi_pcm_playback_2ch = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .nid = nvhdmi_master_con_nid_7x,
- .rates = SUPPORTED_RATES,
- .maxbps = SUPPORTED_MAXBPS,
- .formats = SUPPORTED_FORMATS,
- .ops = {
- .open = simple_playback_pcm_open,
- .close = simple_playback_pcm_close,
- .prepare = simple_playback_pcm_prepare
- },
-};
-
-static const struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
- .build_controls = simple_playback_build_controls,
- .build_pcms = simple_playback_build_pcms,
- .init = nvhdmi_7x_init,
- .free = simple_playback_free,
-};
-
-static const struct hda_codec_ops nvhdmi_patch_ops_2ch = {
- .build_controls = simple_playback_build_controls,
- .build_pcms = simple_playback_build_pcms,
- .init = nvhdmi_7x_init,
- .free = simple_playback_free,
-};
-
-static int patch_nvhdmi_2ch(struct hda_codec *codec)
-{
- struct hdmi_spec *spec;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->spec = spec;
-
- spec->multiout.num_dacs = 0; /* no analog */
- spec->multiout.max_channels = 2;
- spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
- spec->num_cvts = 1;
- spec->cvts[0].cvt_nid = nvhdmi_master_con_nid_7x;
- spec->pcm_playback = &nvhdmi_pcm_playback_2ch;
-
- codec->patch_ops = nvhdmi_patch_ops_2ch;
-
- return 0;
-}
-
-static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
-{
- struct hdmi_spec *spec;
- int err = patch_nvhdmi_2ch(codec);
-
- if (err < 0)
- return err;
- spec = codec->spec;
- spec->multiout.max_channels = 8;
- spec->pcm_playback = &nvhdmi_pcm_playback_8ch_7x;
- codec->patch_ops = nvhdmi_patch_ops_8ch_7x;
-
- /* Initialize the audio infoframe channel mask and checksum to something
- * valid */
- nvhdmi_8ch_7x_set_info_frame_parameters(codec, 8);
-
- return 0;
-}
-
-/*
- * ATI-specific implementations
- *
- * FIXME: we may omit the whole this and use the generic code once after
- * it's confirmed to work.
- */
-
-#define ATIHDMI_CVT_NID 0x02 /* audio converter */
-#define ATIHDMI_PIN_NID 0x03 /* HDMI output pin */
-
-static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct hdmi_spec *spec = codec->spec;
- int chans = substream->runtime->channels;
- int i, err;
-
- err = simple_playback_pcm_prepare(hinfo, codec, stream_tag, format,
- substream);
- if (err < 0)
- return err;
- snd_hda_codec_write(codec, spec->cvts[0].cvt_nid, 0,
- AC_VERB_SET_CVT_CHAN_COUNT, chans - 1);
- /* FIXME: XXX */
- for (i = 0; i < chans; i++) {
- snd_hda_codec_write(codec, spec->cvts[0].cvt_nid, 0,
- AC_VERB_SET_HDMI_CHAN_SLOT,
- (i << 4) | i);
- }
- return 0;
-}
-
-static const struct hda_pcm_stream atihdmi_pcm_digital_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .nid = ATIHDMI_CVT_NID,
- .ops = {
- .open = simple_playback_pcm_open,
- .close = simple_playback_pcm_close,
- .prepare = atihdmi_playback_pcm_prepare
- },
-};
-
-static const struct hda_verb atihdmi_basic_init[] = {
- /* enable digital output on pin widget */
- { 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- {} /* terminator */
-};
-
-static int atihdmi_init(struct hda_codec *codec)
-{
- struct hdmi_spec *spec = codec->spec;
-
- snd_hda_sequence_write(codec, atihdmi_basic_init);
- /* SI codec requires to unmute the pin */
- if (get_wcaps(codec, spec->pins[0].pin_nid) & AC_WCAP_OUT_AMP)
- snd_hda_codec_write(codec, spec->pins[0].pin_nid, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_OUT_UNMUTE);
- return 0;
-}
-
-static const struct hda_codec_ops atihdmi_patch_ops = {
- .build_controls = simple_playback_build_controls,
- .build_pcms = simple_playback_build_pcms,
- .init = atihdmi_init,
- .free = simple_playback_free,
-};
-
-
-static int patch_atihdmi(struct hda_codec *codec)
-{
- struct hdmi_spec *spec;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->spec = spec;
-
- spec->multiout.num_dacs = 0; /* no analog */
- spec->multiout.max_channels = 2;
- spec->multiout.dig_out_nid = ATIHDMI_CVT_NID;
- spec->num_cvts = 1;
- spec->cvts[0].cvt_nid = ATIHDMI_CVT_NID;
- spec->pins[0].pin_nid = ATIHDMI_PIN_NID;
- spec->pcm_playback = &atihdmi_pcm_digital_playback;
-
- codec->patch_ops = atihdmi_patch_ops;
-
- return 0;
-}
-
-
-/*
- * patch entries
- */
-static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
-{ .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi },
-{ .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi },
-{ .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi },
-{ .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_generic_hdmi },
-{ .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_generic_hdmi },
-{ .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_generic_hdmi },
-{ .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_generic_hdmi },
-{ .id = 0x10de0002, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
-{ .id = 0x10de0003, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
-{ .id = 0x10de0005, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
-{ .id = 0x10de0006, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
-{ .id = 0x10de0007, .name = "MCP79/7A HDMI", .patch = patch_nvhdmi_8ch_7x },
-{ .id = 0x10de000a, .name = "GPU 0a HDMI/DP", .patch = patch_generic_hdmi },
-{ .id = 0x10de000b, .name = "GPU 0b HDMI/DP", .patch = patch_generic_hdmi },
-{ .id = 0x10de000c, .name = "MCP89 HDMI", .patch = patch_generic_hdmi },
-{ .id = 0x10de000d, .name = "GPU 0d HDMI/DP", .patch = patch_generic_hdmi },
-{ .id = 0x10de0010, .name = "GPU 10 HDMI/DP", .patch = patch_generic_hdmi },
-{ .id = 0x10de0011, .name = "GPU 11 HDMI/DP", .patch = patch_generic_hdmi },
-{ .id = 0x10de0012, .name = "GPU 12 HDMI/DP", .patch = patch_generic_hdmi },
-{ .id = 0x10de0013, .name = "GPU 13 HDMI/DP", .patch = patch_generic_hdmi },
-{ .id = 0x10de0014, .name = "GPU 14 HDMI/DP", .patch = patch_generic_hdmi },
-{ .id = 0x10de0015, .name = "GPU 15 HDMI/DP", .patch = patch_generic_hdmi },
-{ .id = 0x10de0016, .name = "GPU 16 HDMI/DP", .patch = patch_generic_hdmi },
-/* 17 is known to be absent */
-{ .id = 0x10de0018, .name = "GPU 18 HDMI/DP", .patch = patch_generic_hdmi },
-{ .id = 0x10de0019, .name = "GPU 19 HDMI/DP", .patch = patch_generic_hdmi },
-{ .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_generic_hdmi },
-{ .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_generic_hdmi },
-{ .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_generic_hdmi },
-{ .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_generic_hdmi },
-{ .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_generic_hdmi },
-{ .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_generic_hdmi },
-{ .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_generic_hdmi },
-{ .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_generic_hdmi },
-{ .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
-{ .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
-{ .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi },
-{ .id = 0x80862801, .name = "Bearlake HDMI", .patch = patch_generic_hdmi },
-{ .id = 0x80862802, .name = "Cantiga HDMI", .patch = patch_generic_hdmi },
-{ .id = 0x80862803, .name = "Eaglelake HDMI", .patch = patch_generic_hdmi },
-{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi },
-{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi },
-{ .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi },
-{ .id = 0x80862880, .name = "CedarTrail HDMI", .patch = patch_generic_hdmi },
-{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi },
-{} /* terminator */
-};
-
-MODULE_ALIAS("snd-hda-codec-id:1002793c");
-MODULE_ALIAS("snd-hda-codec-id:10027919");
-MODULE_ALIAS("snd-hda-codec-id:1002791a");
-MODULE_ALIAS("snd-hda-codec-id:1002aa01");
-MODULE_ALIAS("snd-hda-codec-id:10951390");
-MODULE_ALIAS("snd-hda-codec-id:10951392");
-MODULE_ALIAS("snd-hda-codec-id:10de0002");
-MODULE_ALIAS("snd-hda-codec-id:10de0003");
-MODULE_ALIAS("snd-hda-codec-id:10de0005");
-MODULE_ALIAS("snd-hda-codec-id:10de0006");
-MODULE_ALIAS("snd-hda-codec-id:10de0007");
-MODULE_ALIAS("snd-hda-codec-id:10de000a");
-MODULE_ALIAS("snd-hda-codec-id:10de000b");
-MODULE_ALIAS("snd-hda-codec-id:10de000c");
-MODULE_ALIAS("snd-hda-codec-id:10de000d");
-MODULE_ALIAS("snd-hda-codec-id:10de0010");
-MODULE_ALIAS("snd-hda-codec-id:10de0011");
-MODULE_ALIAS("snd-hda-codec-id:10de0012");
-MODULE_ALIAS("snd-hda-codec-id:10de0013");
-MODULE_ALIAS("snd-hda-codec-id:10de0014");
-MODULE_ALIAS("snd-hda-codec-id:10de0015");
-MODULE_ALIAS("snd-hda-codec-id:10de0016");
-MODULE_ALIAS("snd-hda-codec-id:10de0018");
-MODULE_ALIAS("snd-hda-codec-id:10de0019");
-MODULE_ALIAS("snd-hda-codec-id:10de001a");
-MODULE_ALIAS("snd-hda-codec-id:10de001b");
-MODULE_ALIAS("snd-hda-codec-id:10de001c");
-MODULE_ALIAS("snd-hda-codec-id:10de0040");
-MODULE_ALIAS("snd-hda-codec-id:10de0041");
-MODULE_ALIAS("snd-hda-codec-id:10de0042");
-MODULE_ALIAS("snd-hda-codec-id:10de0043");
-MODULE_ALIAS("snd-hda-codec-id:10de0044");
-MODULE_ALIAS("snd-hda-codec-id:10de0067");
-MODULE_ALIAS("snd-hda-codec-id:10de8001");
-MODULE_ALIAS("snd-hda-codec-id:17e80047");
-MODULE_ALIAS("snd-hda-codec-id:80860054");
-MODULE_ALIAS("snd-hda-codec-id:80862801");
-MODULE_ALIAS("snd-hda-codec-id:80862802");
-MODULE_ALIAS("snd-hda-codec-id:80862803");
-MODULE_ALIAS("snd-hda-codec-id:80862804");
-MODULE_ALIAS("snd-hda-codec-id:80862805");
-MODULE_ALIAS("snd-hda-codec-id:80862806");
-MODULE_ALIAS("snd-hda-codec-id:80862880");
-MODULE_ALIAS("snd-hda-codec-id:808629fb");
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("HDMI HD-audio codec");
-MODULE_ALIAS("snd-hda-codec-intelhdmi");
-MODULE_ALIAS("snd-hda-codec-nvhdmi");
-MODULE_ALIAS("snd-hda-codec-atihdmi");
-
-static struct hda_codec_preset_list intel_list = {
- .preset = snd_hda_preset_hdmi,
- .owner = THIS_MODULE,
-};
-
-static int __init patch_hdmi_init(void)
-{
- return snd_hda_add_codec_preset(&intel_list);
-}
-
-static void __exit patch_hdmi_exit(void)
-{
- snd_hda_delete_codec_preset(&intel_list);
-}
-
-module_init(patch_hdmi_init)
-module_exit(patch_hdmi_exit)
diff --git a/ANDROID_3.4.5/sound/pci/hda/patch_realtek.c b/ANDROID_3.4.5/sound/pci/hda/patch_realtek.c
deleted file mode 100644
index c43264f5..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/patch_realtek.c
+++ /dev/null
@@ -1,7034 +0,0 @@
-/*
- * Universal Interface for Intel High Definition Audio Codec
- *
- * HD audio interface patch for Realtek ALC codecs
- *
- * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
- * PeiSen Hou <pshou@realtek.com.tw>
- * Takashi Iwai <tiwai@suse.de>
- * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/jack.h>
-#include "hda_codec.h"
-#include "hda_local.h"
-#include "hda_beep.h"
-#include "hda_jack.h"
-
-/* unsol event tags */
-#define ALC_FRONT_EVENT 0x01
-#define ALC_DCVOL_EVENT 0x02
-#define ALC_HP_EVENT 0x04
-#define ALC_MIC_EVENT 0x08
-
-/* for GPIO Poll */
-#define GPIO_MASK 0x03
-
-/* extra amp-initialization sequence types */
-enum {
- ALC_INIT_NONE,
- ALC_INIT_DEFAULT,
- ALC_INIT_GPIO1,
- ALC_INIT_GPIO2,
- ALC_INIT_GPIO3,
-};
-
-struct alc_customize_define {
- unsigned int sku_cfg;
- unsigned char port_connectivity;
- unsigned char check_sum;
- unsigned char customization;
- unsigned char external_amp;
- unsigned int enable_pcbeep:1;
- unsigned int platform_type:1;
- unsigned int swap:1;
- unsigned int override:1;
- unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
-};
-
-struct alc_fixup;
-
-struct alc_multi_io {
- hda_nid_t pin; /* multi-io widget pin NID */
- hda_nid_t dac; /* DAC to be connected */
- unsigned int ctl_in; /* cached input-pin control value */
-};
-
-enum {
- ALC_AUTOMUTE_PIN, /* change the pin control */
- ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */
- ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
-};
-
-#define MAX_VOL_NIDS 0x40
-
-struct alc_spec {
- /* codec parameterization */
- const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
- unsigned int num_mixers;
- const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
- unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
-
- const struct hda_verb *init_verbs[10]; /* initialization verbs
- * don't forget NULL
- * termination!
- */
- unsigned int num_init_verbs;
-
- char stream_name_analog[32]; /* analog PCM stream */
- const struct hda_pcm_stream *stream_analog_playback;
- const struct hda_pcm_stream *stream_analog_capture;
- const struct hda_pcm_stream *stream_analog_alt_playback;
- const struct hda_pcm_stream *stream_analog_alt_capture;
-
- char stream_name_digital[32]; /* digital PCM stream */
- const struct hda_pcm_stream *stream_digital_playback;
- const struct hda_pcm_stream *stream_digital_capture;
-
- /* playback */
- struct hda_multi_out multiout; /* playback set-up
- * max_channels, dacs must be set
- * dig_out_nid and hp_nid are optional
- */
- hda_nid_t alt_dac_nid;
- hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
- int dig_out_type;
-
- /* capture */
- unsigned int num_adc_nids;
- const hda_nid_t *adc_nids;
- const hda_nid_t *capsrc_nids;
- hda_nid_t dig_in_nid; /* digital-in NID; optional */
- hda_nid_t mixer_nid; /* analog-mixer NID */
- DECLARE_BITMAP(vol_ctls, MAX_VOL_NIDS << 1);
- DECLARE_BITMAP(sw_ctls, MAX_VOL_NIDS << 1);
-
- /* capture setup for dynamic dual-adc switch */
- hda_nid_t cur_adc;
- unsigned int cur_adc_stream_tag;
- unsigned int cur_adc_format;
-
- /* capture source */
- unsigned int num_mux_defs;
- const struct hda_input_mux *input_mux;
- unsigned int cur_mux[3];
- hda_nid_t ext_mic_pin;
- hda_nid_t dock_mic_pin;
- hda_nid_t int_mic_pin;
-
- /* channel model */
- const struct hda_channel_mode *channel_mode;
- int num_channel_mode;
- int need_dac_fix;
- int const_channel_count;
- int ext_channel_count;
-
- /* PCM information */
- struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
-
- /* dynamic controls, init_verbs and input_mux */
- struct auto_pin_cfg autocfg;
- struct alc_customize_define cdefine;
- struct snd_array kctls;
- struct hda_input_mux private_imux[3];
- hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
- hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
- hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
- hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS];
- unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS];
- int int_mic_idx, ext_mic_idx, dock_mic_idx; /* for auto-mic */
-
- /* hooks */
- void (*init_hook)(struct hda_codec *codec);
- void (*unsol_event)(struct hda_codec *codec, unsigned int res);
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- void (*power_hook)(struct hda_codec *codec);
-#endif
- void (*shutup)(struct hda_codec *codec);
- void (*automute_hook)(struct hda_codec *codec);
-
- /* for pin sensing */
- unsigned int hp_jack_present:1;
- unsigned int line_jack_present:1;
- unsigned int master_mute:1;
- unsigned int auto_mic:1;
- unsigned int auto_mic_valid_imux:1; /* valid imux for auto-mic */
- unsigned int automute_speaker:1; /* automute speaker outputs */
- unsigned int automute_lo:1; /* automute LO outputs */
- unsigned int detect_hp:1; /* Headphone detection enabled */
- unsigned int detect_lo:1; /* Line-out detection enabled */
- unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */
- unsigned int automute_lo_possible:1; /* there are line outs and HP */
- unsigned int keep_vref_in_automute:1; /* Don't clear VREF in automute */
-
- /* other flags */
- unsigned int no_analog :1; /* digital I/O only */
- unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */
- unsigned int single_input_src:1;
- unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */
- unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */
- unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */
-
- /* auto-mute control */
- int automute_mode;
- hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS];
-
- int init_amp;
- int codec_variant; /* flag for other variants */
-
- /* for virtual master */
- hda_nid_t vmaster_nid;
- struct hda_vmaster_mute_hook vmaster_mute;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- struct hda_loopback_check loopback;
- int num_loopbacks;
- struct hda_amp_list loopback_list[8];
-#endif
-
- /* for PLL fix */
- hda_nid_t pll_nid;
- unsigned int pll_coef_idx, pll_coef_bit;
- unsigned int coef0;
-
- /* fix-up list */
- int fixup_id;
- const struct alc_fixup *fixup_list;
- const char *fixup_name;
-
- /* multi-io */
- int multi_ios;
- struct alc_multi_io multi_io[4];
-
- /* bind volumes */
- struct snd_array bind_ctls;
-};
-
-static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid,
- int dir, unsigned int bits)
-{
- if (!nid)
- return false;
- if (get_wcaps(codec, nid) & (1 << (dir + 1)))
- if (query_amp_caps(codec, nid, dir) & bits)
- return true;
- return false;
-}
-
-#define nid_has_mute(codec, nid, dir) \
- check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE)
-#define nid_has_volume(codec, nid, dir) \
- check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS)
-
-/*
- * input MUX handling
- */
-static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
- unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
- if (mux_idx >= spec->num_mux_defs)
- mux_idx = 0;
- if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
- mux_idx = 0;
- return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
-}
-
-static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
- unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-
- ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
- return 0;
-}
-
-static bool alc_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur)
-{
- struct alc_spec *spec = codec->spec;
- hda_nid_t new_adc = spec->adc_nids[spec->dyn_adc_idx[cur]];
-
- if (spec->cur_adc && spec->cur_adc != new_adc) {
- /* stream is running, let's swap the current ADC */
- __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
- spec->cur_adc = new_adc;
- snd_hda_codec_setup_stream(codec, new_adc,
- spec->cur_adc_stream_tag, 0,
- spec->cur_adc_format);
- return true;
- }
- return false;
-}
-
-static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx)
-{
- return spec->capsrc_nids ?
- spec->capsrc_nids[idx] : spec->adc_nids[idx];
-}
-
-static void call_update_outputs(struct hda_codec *codec);
-
-/* select the given imux item; either unmute exclusively or select the route */
-static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
- unsigned int idx, bool force)
-{
- struct alc_spec *spec = codec->spec;
- const struct hda_input_mux *imux;
- unsigned int mux_idx;
- int i, type, num_conns;
- hda_nid_t nid;
-
- if (!spec->input_mux)
- return 0;
-
- mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
- imux = &spec->input_mux[mux_idx];
- if (!imux->num_items && mux_idx > 0)
- imux = &spec->input_mux[0];
- if (!imux->num_items)
- return 0;
-
- if (idx >= imux->num_items)
- idx = imux->num_items - 1;
- if (spec->cur_mux[adc_idx] == idx && !force)
- return 0;
- spec->cur_mux[adc_idx] = idx;
-
- /* for shared I/O, change the pin-control accordingly */
- if (spec->shared_mic_hp) {
- /* NOTE: this assumes that there are only two inputs, the
- * first is the real internal mic and the second is HP jack.
- */
- snd_hda_codec_write(codec, spec->autocfg.inputs[1].pin, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- spec->cur_mux[adc_idx] ?
- PIN_VREF80 : PIN_HP);
- spec->automute_speaker = !spec->cur_mux[adc_idx];
- call_update_outputs(codec);
- }
-
- if (spec->dyn_adc_switch) {
- alc_dyn_adc_pcm_resetup(codec, idx);
- adc_idx = spec->dyn_adc_idx[idx];
- }
-
- nid = get_capsrc(spec, adc_idx);
-
- /* no selection? */
- num_conns = snd_hda_get_conn_list(codec, nid, NULL);
- if (num_conns <= 1)
- return 1;
-
- type = get_wcaps_type(get_wcaps(codec, nid));
- if (type == AC_WID_AUD_MIX) {
- /* Matrix-mixer style (e.g. ALC882) */
- int active = imux->items[idx].index;
- for (i = 0; i < num_conns; i++) {
- unsigned int v = (i == active) ? 0 : HDA_AMP_MUTE;
- snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, i,
- HDA_AMP_MUTE, v);
- }
- } else {
- /* MUX style (e.g. ALC880) */
- snd_hda_codec_write_cache(codec, nid, 0,
- AC_VERB_SET_CONNECT_SEL,
- imux->items[idx].index);
- }
- return 1;
-}
-
-static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- return alc_mux_select(codec, adc_idx,
- ucontrol->value.enumerated.item[0], false);
-}
-
-/*
- * set up the input pin config (depending on the given auto-pin type)
- */
-static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
- int auto_pin_type)
-{
- unsigned int val = PIN_IN;
-
- if (auto_pin_type == AUTO_PIN_MIC) {
- unsigned int pincap;
- unsigned int oldval;
- oldval = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
- pincap = snd_hda_query_pin_caps(codec, nid);
- pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
- /* if the default pin setup is vref50, we give it priority */
- if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
- val = PIN_VREF80;
- else if (pincap & AC_PINCAP_VREF_50)
- val = PIN_VREF50;
- else if (pincap & AC_PINCAP_VREF_100)
- val = PIN_VREF100;
- else if (pincap & AC_PINCAP_VREF_GRD)
- val = PIN_VREFGRD;
- }
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
-}
-
-/*
- * Append the given mixer and verb elements for the later use
- * The mixer array is referred in build_controls(), and init_verbs are
- * called in init().
- */
-static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
-{
- if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
- return;
- spec->mixers[spec->num_mixers++] = mix;
-}
-
-static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
-{
- if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
- return;
- spec->init_verbs[spec->num_init_verbs++] = verb;
-}
-
-/*
- * GPIO setup tables, used in initialization
- */
-/* Enable GPIO mask and set output */
-static const struct hda_verb alc_gpio1_init_verbs[] = {
- {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
- {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
- {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
- { }
-};
-
-static const struct hda_verb alc_gpio2_init_verbs[] = {
- {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
- {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
- {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
- { }
-};
-
-static const struct hda_verb alc_gpio3_init_verbs[] = {
- {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
- {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
- {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
- { }
-};
-
-/*
- * Fix hardware PLL issue
- * On some codecs, the analog PLL gating control must be off while
- * the default value is 1.
- */
-static void alc_fix_pll(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- unsigned int val;
-
- if (!spec->pll_nid)
- return;
- snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
- spec->pll_coef_idx);
- val = snd_hda_codec_read(codec, spec->pll_nid, 0,
- AC_VERB_GET_PROC_COEF, 0);
- snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
- spec->pll_coef_idx);
- snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
- val & ~(1 << spec->pll_coef_bit));
-}
-
-static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
- unsigned int coef_idx, unsigned int coef_bit)
-{
- struct alc_spec *spec = codec->spec;
- spec->pll_nid = nid;
- spec->pll_coef_idx = coef_idx;
- spec->pll_coef_bit = coef_bit;
- alc_fix_pll(codec);
-}
-
-/*
- * Jack detections for HP auto-mute and mic-switch
- */
-
-/* check each pin in the given array; returns true if any of them is plugged */
-static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
-{
- int i, present = 0;
-
- for (i = 0; i < num_pins; i++) {
- hda_nid_t nid = pins[i];
- if (!nid)
- break;
- present |= snd_hda_jack_detect(codec, nid);
- }
- return present;
-}
-
-/* standard HP/line-out auto-mute helper */
-static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
- bool mute, bool hp_out)
-{
- struct alc_spec *spec = codec->spec;
- unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
- unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
- int i;
-
- for (i = 0; i < num_pins; i++) {
- hda_nid_t nid = pins[i];
- unsigned int val;
- if (!nid)
- break;
- switch (spec->automute_mode) {
- case ALC_AUTOMUTE_PIN:
- /* don't reset VREF value in case it's controlling
- * the amp (see alc861_fixup_asus_amp_vref_0f())
- */
- if (spec->keep_vref_in_automute) {
- val = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
- val &= ~PIN_HP;
- } else
- val = 0;
- val |= pin_bits;
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- val);
- break;
- case ALC_AUTOMUTE_AMP:
- snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, mute_bits);
- break;
- case ALC_AUTOMUTE_MIXER:
- nid = spec->automute_mixer_nid[i];
- if (!nid)
- break;
- snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
- HDA_AMP_MUTE, mute_bits);
- snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
- HDA_AMP_MUTE, mute_bits);
- break;
- }
- }
-}
-
-/* Toggle outputs muting */
-static void update_outputs(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- int on;
-
- /* Control HP pins/amps depending on master_mute state;
- * in general, HP pins/amps control should be enabled in all cases,
- * but currently set only for master_mute, just to be safe
- */
- if (!spec->shared_mic_hp) /* don't change HP-pin when shared with mic */
- do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
- spec->autocfg.hp_pins, spec->master_mute, true);
-
- if (!spec->automute_speaker)
- on = 0;
- else
- on = spec->hp_jack_present | spec->line_jack_present;
- on |= spec->master_mute;
- do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
- spec->autocfg.speaker_pins, on, false);
-
- /* toggle line-out mutes if needed, too */
- /* if LO is a copy of either HP or Speaker, don't need to handle it */
- if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
- spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
- return;
- if (!spec->automute_lo)
- on = 0;
- else
- on = spec->hp_jack_present;
- on |= spec->master_mute;
- do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
- spec->autocfg.line_out_pins, on, false);
-}
-
-static void call_update_outputs(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- if (spec->automute_hook)
- spec->automute_hook(codec);
- else
- update_outputs(codec);
-}
-
-/* standard HP-automute helper */
-static void alc_hp_automute(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->hp_jack_present =
- detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
- spec->autocfg.hp_pins);
- if (!spec->detect_hp || (!spec->automute_speaker && !spec->automute_lo))
- return;
- call_update_outputs(codec);
-}
-
-/* standard line-out-automute helper */
-static void alc_line_automute(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- /* check LO jack only when it's different from HP */
- if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0])
- return;
-
- spec->line_jack_present =
- detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
- spec->autocfg.line_out_pins);
- if (!spec->automute_speaker || !spec->detect_lo)
- return;
- call_update_outputs(codec);
-}
-
-#define get_connection_index(codec, mux, nid) \
- snd_hda_get_conn_index(codec, mux, nid, 0)
-
-/* standard mic auto-switch helper */
-static void alc_mic_automute(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- hda_nid_t *pins = spec->imux_pins;
-
- if (!spec->auto_mic || !spec->auto_mic_valid_imux)
- return;
- if (snd_BUG_ON(!spec->adc_nids))
- return;
- if (snd_BUG_ON(spec->int_mic_idx < 0 || spec->ext_mic_idx < 0))
- return;
-
- if (snd_hda_jack_detect(codec, pins[spec->ext_mic_idx]))
- alc_mux_select(codec, 0, spec->ext_mic_idx, false);
- else if (spec->dock_mic_idx >= 0 &&
- snd_hda_jack_detect(codec, pins[spec->dock_mic_idx]))
- alc_mux_select(codec, 0, spec->dock_mic_idx, false);
- else
- alc_mux_select(codec, 0, spec->int_mic_idx, false);
-}
-
-/* handle the specified unsol action (ALC_XXX_EVENT) */
-static void alc_exec_unsol_event(struct hda_codec *codec, int action)
-{
- switch (action) {
- case ALC_HP_EVENT:
- alc_hp_automute(codec);
- break;
- case ALC_FRONT_EVENT:
- alc_line_automute(codec);
- break;
- case ALC_MIC_EVENT:
- alc_mic_automute(codec);
- break;
- }
- snd_hda_jack_report_sync(codec);
-}
-
-/* update the master volume per volume-knob's unsol event */
-static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid)
-{
- unsigned int val;
- struct snd_kcontrol *kctl;
- struct snd_ctl_elem_value *uctl;
-
- kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
- if (!kctl)
- return;
- uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
- if (!uctl)
- return;
- val = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
- val &= HDA_AMP_VOLMASK;
- uctl->value.integer.value[0] = val;
- uctl->value.integer.value[1] = val;
- kctl->put(kctl, uctl);
- kfree(uctl);
-}
-
-/* unsolicited event for HP jack sensing */
-static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- int action;
-
- if (codec->vendor_id == 0x10ec0880)
- res >>= 28;
- else
- res >>= 26;
- action = snd_hda_jack_get_action(codec, res);
- if (action == ALC_DCVOL_EVENT) {
- /* Execute the dc-vol event here as it requires the NID
- * but we don't pass NID to alc_exec_unsol_event().
- * Once when we convert all static quirks to the auto-parser,
- * this can be integerated into there.
- */
- struct hda_jack_tbl *jack;
- jack = snd_hda_jack_tbl_get_from_tag(codec, res);
- if (jack)
- alc_update_knob_master(codec, jack->nid);
- return;
- }
- alc_exec_unsol_event(codec, action);
-}
-
-/* call init functions of standard auto-mute helpers */
-static void alc_inithook(struct hda_codec *codec)
-{
- alc_hp_automute(codec);
- alc_line_automute(codec);
- alc_mic_automute(codec);
-}
-
-/* additional initialization for ALC888 variants */
-static void alc888_coef_init(struct hda_codec *codec)
-{
- unsigned int tmp;
-
- snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
- tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
- snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
- if ((tmp & 0xf0) == 0x20)
- /* alc888S-VC */
- snd_hda_codec_read(codec, 0x20, 0,
- AC_VERB_SET_PROC_COEF, 0x830);
- else
- /* alc888-VB */
- snd_hda_codec_read(codec, 0x20, 0,
- AC_VERB_SET_PROC_COEF, 0x3030);
-}
-
-/* additional initialization for ALC889 variants */
-static void alc889_coef_init(struct hda_codec *codec)
-{
- unsigned int tmp;
-
- snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
- tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
- snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
- snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
-}
-
-/* turn on/off EAPD control (only if available) */
-static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
-{
- if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
- return;
- if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
- on ? 2 : 0);
-}
-
-/* turn on/off EAPD controls of the codec */
-static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
-{
- /* We currently only handle front, HP */
- static hda_nid_t pins[] = {
- 0x0f, 0x10, 0x14, 0x15, 0
- };
- hda_nid_t *p;
- for (p = pins; *p; p++)
- set_eapd(codec, *p, on);
-}
-
-/* generic shutup callback;
- * just turning off EPAD and a little pause for avoiding pop-noise
- */
-static void alc_eapd_shutup(struct hda_codec *codec)
-{
- alc_auto_setup_eapd(codec, false);
- msleep(200);
-}
-
-/* generic EAPD initialization */
-static void alc_auto_init_amp(struct hda_codec *codec, int type)
-{
- unsigned int tmp;
-
- alc_auto_setup_eapd(codec, true);
- switch (type) {
- case ALC_INIT_GPIO1:
- snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
- break;
- case ALC_INIT_GPIO2:
- snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
- break;
- case ALC_INIT_GPIO3:
- snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
- break;
- case ALC_INIT_DEFAULT:
- switch (codec->vendor_id) {
- case 0x10ec0260:
- snd_hda_codec_write(codec, 0x1a, 0,
- AC_VERB_SET_COEF_INDEX, 7);
- tmp = snd_hda_codec_read(codec, 0x1a, 0,
- AC_VERB_GET_PROC_COEF, 0);
- snd_hda_codec_write(codec, 0x1a, 0,
- AC_VERB_SET_COEF_INDEX, 7);
- snd_hda_codec_write(codec, 0x1a, 0,
- AC_VERB_SET_PROC_COEF,
- tmp | 0x2010);
- break;
- case 0x10ec0262:
- case 0x10ec0880:
- case 0x10ec0882:
- case 0x10ec0883:
- case 0x10ec0885:
- case 0x10ec0887:
- /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
- alc889_coef_init(codec);
- break;
- case 0x10ec0888:
- alc888_coef_init(codec);
- break;
-#if 0 /* XXX: This may cause the silent output on speaker on some machines */
- case 0x10ec0267:
- case 0x10ec0268:
- snd_hda_codec_write(codec, 0x20, 0,
- AC_VERB_SET_COEF_INDEX, 7);
- tmp = snd_hda_codec_read(codec, 0x20, 0,
- AC_VERB_GET_PROC_COEF, 0);
- snd_hda_codec_write(codec, 0x20, 0,
- AC_VERB_SET_COEF_INDEX, 7);
- snd_hda_codec_write(codec, 0x20, 0,
- AC_VERB_SET_PROC_COEF,
- tmp | 0x3000);
- break;
-#endif /* XXX */
- }
- break;
- }
-}
-
-/*
- * Auto-Mute mode mixer enum support
- */
-static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
- static const char * const texts2[] = {
- "Disabled", "Enabled"
- };
- static const char * const texts3[] = {
- "Disabled", "Speaker Only", "Line Out+Speaker"
- };
- const char * const *texts;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- if (spec->automute_speaker_possible && spec->automute_lo_possible) {
- uinfo->value.enumerated.items = 3;
- texts = texts3;
- } else {
- uinfo->value.enumerated.items = 2;
- texts = texts2;
- }
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
- unsigned int val = 0;
- if (spec->automute_speaker)
- val++;
- if (spec->automute_lo)
- val++;
-
- ucontrol->value.enumerated.item[0] = val;
- return 0;
-}
-
-static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
-
- switch (ucontrol->value.enumerated.item[0]) {
- case 0:
- if (!spec->automute_speaker && !spec->automute_lo)
- return 0;
- spec->automute_speaker = 0;
- spec->automute_lo = 0;
- break;
- case 1:
- if (spec->automute_speaker_possible) {
- if (!spec->automute_lo && spec->automute_speaker)
- return 0;
- spec->automute_speaker = 1;
- spec->automute_lo = 0;
- } else if (spec->automute_lo_possible) {
- if (spec->automute_lo)
- return 0;
- spec->automute_lo = 1;
- } else
- return -EINVAL;
- break;
- case 2:
- if (!spec->automute_lo_possible || !spec->automute_speaker_possible)
- return -EINVAL;
- if (spec->automute_speaker && spec->automute_lo)
- return 0;
- spec->automute_speaker = 1;
- spec->automute_lo = 1;
- break;
- default:
- return -EINVAL;
- }
- call_update_outputs(codec);
- return 1;
-}
-
-static const struct snd_kcontrol_new alc_automute_mode_enum = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Auto-Mute Mode",
- .info = alc_automute_mode_info,
- .get = alc_automute_mode_get,
- .put = alc_automute_mode_put,
-};
-
-static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
-{
- snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
- return snd_array_new(&spec->kctls);
-}
-
-static int alc_add_automute_mode_enum(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- struct snd_kcontrol_new *knew;
-
- knew = alc_kcontrol_new(spec);
- if (!knew)
- return -ENOMEM;
- *knew = alc_automute_mode_enum;
- knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
- if (!knew->name)
- return -ENOMEM;
- return 0;
-}
-
-/*
- * Check the availability of HP/line-out auto-mute;
- * Set up appropriately if really supported
- */
-static void alc_init_automute(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int present = 0;
- int i;
-
- if (cfg->hp_pins[0])
- present++;
- if (cfg->line_out_pins[0])
- present++;
- if (cfg->speaker_pins[0])
- present++;
- if (present < 2) /* need two different output types */
- return;
-
- if (!cfg->speaker_pins[0] &&
- cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
- memcpy(cfg->speaker_pins, cfg->line_out_pins,
- sizeof(cfg->speaker_pins));
- cfg->speaker_outs = cfg->line_outs;
- }
-
- if (!cfg->hp_pins[0] &&
- cfg->line_out_type == AUTO_PIN_HP_OUT) {
- memcpy(cfg->hp_pins, cfg->line_out_pins,
- sizeof(cfg->hp_pins));
- cfg->hp_outs = cfg->line_outs;
- }
-
- spec->automute_mode = ALC_AUTOMUTE_PIN;
-
- for (i = 0; i < cfg->hp_outs; i++) {
- hda_nid_t nid = cfg->hp_pins[i];
- if (!is_jack_detectable(codec, nid))
- continue;
- snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
- nid);
- snd_hda_jack_detect_enable(codec, nid, ALC_HP_EVENT);
- spec->detect_hp = 1;
- }
-
- if (cfg->line_out_type == AUTO_PIN_LINE_OUT && cfg->line_outs) {
- if (cfg->speaker_outs)
- for (i = 0; i < cfg->line_outs; i++) {
- hda_nid_t nid = cfg->line_out_pins[i];
- if (!is_jack_detectable(codec, nid))
- continue;
- snd_printdd("realtek: Enable Line-Out "
- "auto-muting on NID 0x%x\n", nid);
- snd_hda_jack_detect_enable(codec, nid,
- ALC_FRONT_EVENT);
- spec->detect_lo = 1;
- }
- spec->automute_lo_possible = spec->detect_hp;
- }
-
- spec->automute_speaker_possible = cfg->speaker_outs &&
- (spec->detect_hp || spec->detect_lo);
-
- spec->automute_lo = spec->automute_lo_possible;
- spec->automute_speaker = spec->automute_speaker_possible;
-
- if (spec->automute_speaker_possible || spec->automute_lo_possible) {
- /* create a control for automute mode */
- alc_add_automute_mode_enum(codec);
- spec->unsol_event = alc_sku_unsol_event;
- }
-}
-
-/* return the position of NID in the list, or -1 if not found */
-static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
-{
- int i;
- for (i = 0; i < nums; i++)
- if (list[i] == nid)
- return i;
- return -1;
-}
-
-/* check whether dynamic ADC-switching is available */
-static bool alc_check_dyn_adc_switch(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- struct hda_input_mux *imux = &spec->private_imux[0];
- int i, n, idx;
- hda_nid_t cap, pin;
-
- if (imux != spec->input_mux) /* no dynamic imux? */
- return false;
-
- for (n = 0; n < spec->num_adc_nids; n++) {
- cap = spec->private_capsrc_nids[n];
- for (i = 0; i < imux->num_items; i++) {
- pin = spec->imux_pins[i];
- if (!pin)
- return false;
- if (get_connection_index(codec, cap, pin) < 0)
- break;
- }
- if (i >= imux->num_items)
- return true; /* no ADC-switch is needed */
- }
-
- for (i = 0; i < imux->num_items; i++) {
- pin = spec->imux_pins[i];
- for (n = 0; n < spec->num_adc_nids; n++) {
- cap = spec->private_capsrc_nids[n];
- idx = get_connection_index(codec, cap, pin);
- if (idx >= 0) {
- imux->items[i].index = idx;
- spec->dyn_adc_idx[i] = n;
- break;
- }
- }
- }
-
- snd_printdd("realtek: enabling ADC switching\n");
- spec->dyn_adc_switch = 1;
- return true;
-}
-
-/* check whether all auto-mic pins are valid; setup indices if OK */
-static bool alc_auto_mic_check_imux(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- const struct hda_input_mux *imux;
-
- if (!spec->auto_mic)
- return false;
- if (spec->auto_mic_valid_imux)
- return true; /* already checked */
-
- /* fill up imux indices */
- if (!alc_check_dyn_adc_switch(codec)) {
- spec->auto_mic = 0;
- return false;
- }
-
- imux = spec->input_mux;
- spec->ext_mic_idx = find_idx_in_nid_list(spec->ext_mic_pin,
- spec->imux_pins, imux->num_items);
- spec->int_mic_idx = find_idx_in_nid_list(spec->int_mic_pin,
- spec->imux_pins, imux->num_items);
- spec->dock_mic_idx = find_idx_in_nid_list(spec->dock_mic_pin,
- spec->imux_pins, imux->num_items);
- if (spec->ext_mic_idx < 0 || spec->int_mic_idx < 0) {
- spec->auto_mic = 0;
- return false; /* no corresponding imux */
- }
-
- snd_hda_jack_detect_enable(codec, spec->ext_mic_pin, ALC_MIC_EVENT);
- if (spec->dock_mic_pin)
- snd_hda_jack_detect_enable(codec, spec->dock_mic_pin,
- ALC_MIC_EVENT);
-
- spec->auto_mic_valid_imux = 1;
- spec->auto_mic = 1;
- return true;
-}
-
-/*
- * Check the availability of auto-mic switch;
- * Set up if really supported
- */
-static void alc_init_auto_mic(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- hda_nid_t fixed, ext, dock;
- int i;
-
- if (spec->shared_mic_hp)
- return; /* no auto-mic for the shared I/O */
-
- spec->ext_mic_idx = spec->int_mic_idx = spec->dock_mic_idx = -1;
-
- fixed = ext = dock = 0;
- for (i = 0; i < cfg->num_inputs; i++) {
- hda_nid_t nid = cfg->inputs[i].pin;
- unsigned int defcfg;
- defcfg = snd_hda_codec_get_pincfg(codec, nid);
- switch (snd_hda_get_input_pin_attr(defcfg)) {
- case INPUT_PIN_ATTR_INT:
- if (fixed)
- return; /* already occupied */
- if (cfg->inputs[i].type != AUTO_PIN_MIC)
- return; /* invalid type */
- fixed = nid;
- break;
- case INPUT_PIN_ATTR_UNUSED:
- return; /* invalid entry */
- case INPUT_PIN_ATTR_DOCK:
- if (dock)
- return; /* already occupied */
- if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
- return; /* invalid type */
- dock = nid;
- break;
- default:
- if (ext)
- return; /* already occupied */
- if (cfg->inputs[i].type != AUTO_PIN_MIC)
- return; /* invalid type */
- ext = nid;
- break;
- }
- }
- if (!ext && dock) {
- ext = dock;
- dock = 0;
- }
- if (!ext || !fixed)
- return;
- if (!is_jack_detectable(codec, ext))
- return; /* no unsol support */
- if (dock && !is_jack_detectable(codec, dock))
- return; /* no unsol support */
-
- /* check imux indices */
- spec->ext_mic_pin = ext;
- spec->int_mic_pin = fixed;
- spec->dock_mic_pin = dock;
-
- spec->auto_mic = 1;
- if (!alc_auto_mic_check_imux(codec))
- return;
-
- snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
- ext, fixed, dock);
- spec->unsol_event = alc_sku_unsol_event;
-}
-
-/* check the availabilities of auto-mute and auto-mic switches */
-static void alc_auto_check_switches(struct hda_codec *codec)
-{
- alc_init_automute(codec);
- alc_init_auto_mic(codec);
-}
-
-/*
- * Realtek SSID verification
- */
-
-/* Could be any non-zero and even value. When used as fixup, tells
- * the driver to ignore any present sku defines.
- */
-#define ALC_FIXUP_SKU_IGNORE (2)
-
-static int alc_auto_parse_customize_define(struct hda_codec *codec)
-{
- unsigned int ass, tmp, i;
- unsigned nid = 0;
- struct alc_spec *spec = codec->spec;
-
- spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
-
- if (spec->cdefine.fixup) {
- ass = spec->cdefine.sku_cfg;
- if (ass == ALC_FIXUP_SKU_IGNORE)
- return -1;
- goto do_sku;
- }
-
- ass = codec->subsystem_id & 0xffff;
- if (ass != codec->bus->pci->subsystem_device && (ass & 1))
- goto do_sku;
-
- nid = 0x1d;
- if (codec->vendor_id == 0x10ec0260)
- nid = 0x17;
- ass = snd_hda_codec_get_pincfg(codec, nid);
-
- if (!(ass & 1)) {
- printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
- codec->chip_name, ass);
- return -1;
- }
-
- /* check sum */
- tmp = 0;
- for (i = 1; i < 16; i++) {
- if ((ass >> i) & 1)
- tmp++;
- }
- if (((ass >> 16) & 0xf) != tmp)
- return -1;
-
- spec->cdefine.port_connectivity = ass >> 30;
- spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
- spec->cdefine.check_sum = (ass >> 16) & 0xf;
- spec->cdefine.customization = ass >> 8;
-do_sku:
- spec->cdefine.sku_cfg = ass;
- spec->cdefine.external_amp = (ass & 0x38) >> 3;
- spec->cdefine.platform_type = (ass & 0x4) >> 2;
- spec->cdefine.swap = (ass & 0x2) >> 1;
- spec->cdefine.override = ass & 0x1;
-
- snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
- nid, spec->cdefine.sku_cfg);
- snd_printd("SKU: port_connectivity=0x%x\n",
- spec->cdefine.port_connectivity);
- snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
- snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
- snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
- snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
- snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
- snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
- snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
-
- return 0;
-}
-
-/* return true if the given NID is found in the list */
-static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
-{
- return find_idx_in_nid_list(nid, list, nums) >= 0;
-}
-
-/* check subsystem ID and set up device-specific initialization;
- * return 1 if initialized, 0 if invalid SSID
- */
-/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
- * 31 ~ 16 : Manufacture ID
- * 15 ~ 8 : SKU ID
- * 7 ~ 0 : Assembly ID
- * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
- */
-static int alc_subsystem_id(struct hda_codec *codec,
- hda_nid_t porta, hda_nid_t porte,
- hda_nid_t portd, hda_nid_t porti)
-{
- unsigned int ass, tmp, i;
- unsigned nid;
- struct alc_spec *spec = codec->spec;
-
- if (spec->cdefine.fixup) {
- ass = spec->cdefine.sku_cfg;
- if (ass == ALC_FIXUP_SKU_IGNORE)
- return 0;
- goto do_sku;
- }
-
- ass = codec->subsystem_id & 0xffff;
- if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
- goto do_sku;
-
- /* invalid SSID, check the special NID pin defcfg instead */
- /*
- * 31~30 : port connectivity
- * 29~21 : reserve
- * 20 : PCBEEP input
- * 19~16 : Check sum (15:1)
- * 15~1 : Custom
- * 0 : override
- */
- nid = 0x1d;
- if (codec->vendor_id == 0x10ec0260)
- nid = 0x17;
- ass = snd_hda_codec_get_pincfg(codec, nid);
- snd_printd("realtek: No valid SSID, "
- "checking pincfg 0x%08x for NID 0x%x\n",
- ass, nid);
- if (!(ass & 1))
- return 0;
- if ((ass >> 30) != 1) /* no physical connection */
- return 0;
-
- /* check sum */
- tmp = 0;
- for (i = 1; i < 16; i++) {
- if ((ass >> i) & 1)
- tmp++;
- }
- if (((ass >> 16) & 0xf) != tmp)
- return 0;
-do_sku:
- snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
- ass & 0xffff, codec->vendor_id);
- /*
- * 0 : override
- * 1 : Swap Jack
- * 2 : 0 --> Desktop, 1 --> Laptop
- * 3~5 : External Amplifier control
- * 7~6 : Reserved
- */
- tmp = (ass & 0x38) >> 3; /* external Amp control */
- switch (tmp) {
- case 1:
- spec->init_amp = ALC_INIT_GPIO1;
- break;
- case 3:
- spec->init_amp = ALC_INIT_GPIO2;
- break;
- case 7:
- spec->init_amp = ALC_INIT_GPIO3;
- break;
- case 5:
- default:
- spec->init_amp = ALC_INIT_DEFAULT;
- break;
- }
-
- /* is laptop or Desktop and enable the function "Mute internal speaker
- * when the external headphone out jack is plugged"
- */
- if (!(ass & 0x8000))
- return 1;
- /*
- * 10~8 : Jack location
- * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
- * 14~13: Resvered
- * 15 : 1 --> enable the function "Mute internal speaker
- * when the external headphone out jack is plugged"
- */
- if (!spec->autocfg.hp_pins[0] &&
- !(spec->autocfg.line_out_pins[0] &&
- spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)) {
- hda_nid_t nid;
- tmp = (ass >> 11) & 0x3; /* HP to chassis */
- if (tmp == 0)
- nid = porta;
- else if (tmp == 1)
- nid = porte;
- else if (tmp == 2)
- nid = portd;
- else if (tmp == 3)
- nid = porti;
- else
- return 1;
- if (found_in_nid_list(nid, spec->autocfg.line_out_pins,
- spec->autocfg.line_outs))
- return 1;
- spec->autocfg.hp_pins[0] = nid;
- }
- return 1;
-}
-
-/* Check the validity of ALC subsystem-id
- * ports contains an array of 4 pin NIDs for port-A, E, D and I */
-static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
-{
- if (!alc_subsystem_id(codec, ports[0], ports[1], ports[2], ports[3])) {
- struct alc_spec *spec = codec->spec;
- snd_printd("realtek: "
- "Enable default setup for auto mode as fallback\n");
- spec->init_amp = ALC_INIT_DEFAULT;
- }
-}
-
-/*
- * Fix-up pin default configurations and add default verbs
- */
-
-struct alc_pincfg {
- hda_nid_t nid;
- u32 val;
-};
-
-struct alc_model_fixup {
- const int id;
- const char *name;
-};
-
-struct alc_fixup {
- int type;
- bool chained;
- int chain_id;
- union {
- unsigned int sku;
- const struct alc_pincfg *pins;
- const struct hda_verb *verbs;
- void (*func)(struct hda_codec *codec,
- const struct alc_fixup *fix,
- int action);
- } v;
-};
-
-enum {
- ALC_FIXUP_INVALID,
- ALC_FIXUP_SKU,
- ALC_FIXUP_PINS,
- ALC_FIXUP_VERBS,
- ALC_FIXUP_FUNC,
-};
-
-enum {
- ALC_FIXUP_ACT_PRE_PROBE,
- ALC_FIXUP_ACT_PROBE,
- ALC_FIXUP_ACT_INIT,
- ALC_FIXUP_ACT_BUILD,
-};
-
-static void alc_apply_pincfgs(struct hda_codec *codec,
- const struct alc_pincfg *cfg)
-{
- for (; cfg->nid; cfg++)
- snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
-}
-
-static void alc_apply_fixup(struct hda_codec *codec, int action)
-{
- struct alc_spec *spec = codec->spec;
- int id = spec->fixup_id;
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- const char *modelname = spec->fixup_name;
-#endif
- int depth = 0;
-
- if (!spec->fixup_list)
- return;
-
- while (id >= 0) {
- const struct alc_fixup *fix = spec->fixup_list + id;
- const struct alc_pincfg *cfg;
-
- switch (fix->type) {
- case ALC_FIXUP_SKU:
- if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
- break;
- snd_printdd(KERN_INFO "hda_codec: %s: "
- "Apply sku override for %s\n",
- codec->chip_name, modelname);
- spec->cdefine.sku_cfg = fix->v.sku;
- spec->cdefine.fixup = 1;
- break;
- case ALC_FIXUP_PINS:
- cfg = fix->v.pins;
- if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
- break;
- snd_printdd(KERN_INFO "hda_codec: %s: "
- "Apply pincfg for %s\n",
- codec->chip_name, modelname);
- alc_apply_pincfgs(codec, cfg);
- break;
- case ALC_FIXUP_VERBS:
- if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
- break;
- snd_printdd(KERN_INFO "hda_codec: %s: "
- "Apply fix-verbs for %s\n",
- codec->chip_name, modelname);
- add_verb(codec->spec, fix->v.verbs);
- break;
- case ALC_FIXUP_FUNC:
- if (!fix->v.func)
- break;
- snd_printdd(KERN_INFO "hda_codec: %s: "
- "Apply fix-func for %s\n",
- codec->chip_name, modelname);
- fix->v.func(codec, fix, action);
- break;
- default:
- snd_printk(KERN_ERR "hda_codec: %s: "
- "Invalid fixup type %d\n",
- codec->chip_name, fix->type);
- break;
- }
- if (!fix->chained)
- break;
- if (++depth > 10)
- break;
- id = fix->chain_id;
- }
-}
-
-static void alc_pick_fixup(struct hda_codec *codec,
- const struct alc_model_fixup *models,
- const struct snd_pci_quirk *quirk,
- const struct alc_fixup *fixlist)
-{
- struct alc_spec *spec = codec->spec;
- const struct snd_pci_quirk *q;
- int id = -1;
- const char *name = NULL;
-
- /* when model=nofixup is given, don't pick up any fixups */
- if (codec->modelname && !strcmp(codec->modelname, "nofixup")) {
- spec->fixup_list = NULL;
- spec->fixup_id = -1;
- return;
- }
-
- if (codec->modelname && models) {
- while (models->name) {
- if (!strcmp(codec->modelname, models->name)) {
- id = models->id;
- name = models->name;
- break;
- }
- models++;
- }
- }
- if (id < 0) {
- q = snd_pci_quirk_lookup(codec->bus->pci, quirk);
- if (q) {
- id = q->value;
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- name = q->name;
-#endif
- }
- }
- if (id < 0) {
- for (q = quirk; q->subvendor; q++) {
- unsigned int vendorid =
- q->subdevice | (q->subvendor << 16);
- if (vendorid == codec->subsystem_id) {
- id = q->value;
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- name = q->name;
-#endif
- break;
- }
- }
- }
-
- spec->fixup_id = id;
- if (id >= 0) {
- spec->fixup_list = fixlist;
- spec->fixup_name = name;
- }
-}
-
-/*
- * COEF access helper functions
- */
-static int alc_read_coef_idx(struct hda_codec *codec,
- unsigned int coef_idx)
-{
- unsigned int val;
- snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
- coef_idx);
- val = snd_hda_codec_read(codec, 0x20, 0,
- AC_VERB_GET_PROC_COEF, 0);
- return val;
-}
-
-static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
- unsigned int coef_val)
-{
- snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
- coef_idx);
- snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
- coef_val);
-}
-
-/* a special bypass for COEF 0; read the cached value at the second time */
-static unsigned int alc_get_coef0(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- if (!spec->coef0)
- spec->coef0 = alc_read_coef_idx(codec, 0);
- return spec->coef0;
-}
-
-/*
- * Digital I/O handling
- */
-
-/* set right pin controls for digital I/O */
-static void alc_auto_init_digital(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- int i;
- hda_nid_t pin, dac;
-
- for (i = 0; i < spec->autocfg.dig_outs; i++) {
- pin = spec->autocfg.dig_out_pins[i];
- if (!pin)
- continue;
- snd_hda_codec_write(codec, pin, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
- if (!i)
- dac = spec->multiout.dig_out_nid;
- else
- dac = spec->slave_dig_outs[i - 1];
- if (!dac || !(get_wcaps(codec, dac) & AC_WCAP_OUT_AMP))
- continue;
- snd_hda_codec_write(codec, dac, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_OUT_UNMUTE);
- }
- pin = spec->autocfg.dig_in_pin;
- if (pin)
- snd_hda_codec_write(codec, pin, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- PIN_IN);
-}
-
-/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
-static void alc_auto_parse_digital(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- int i, err, nums;
- hda_nid_t dig_nid;
-
- /* support multiple SPDIFs; the secondary is set up as a slave */
- nums = 0;
- for (i = 0; i < spec->autocfg.dig_outs; i++) {
- hda_nid_t conn[4];
- err = snd_hda_get_connections(codec,
- spec->autocfg.dig_out_pins[i],
- conn, ARRAY_SIZE(conn));
- if (err <= 0)
- continue;
- dig_nid = conn[0]; /* assume the first element is audio-out */
- if (!nums) {
- spec->multiout.dig_out_nid = dig_nid;
- spec->dig_out_type = spec->autocfg.dig_out_type[0];
- } else {
- spec->multiout.slave_dig_outs = spec->slave_dig_outs;
- if (nums >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
- break;
- spec->slave_dig_outs[nums - 1] = dig_nid;
- }
- nums++;
- }
-
- if (spec->autocfg.dig_in_pin) {
- dig_nid = codec->start_nid;
- for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
- unsigned int wcaps = get_wcaps(codec, dig_nid);
- if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
- continue;
- if (!(wcaps & AC_WCAP_DIGITAL))
- continue;
- if (!(wcaps & AC_WCAP_CONN_LIST))
- continue;
- err = get_connection_index(codec, dig_nid,
- spec->autocfg.dig_in_pin);
- if (err >= 0) {
- spec->dig_in_nid = dig_nid;
- break;
- }
- }
- }
-}
-
-/*
- * capture mixer elements
- */
-static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
- unsigned long val;
- int err;
-
- mutex_lock(&codec->control_mutex);
- if (spec->vol_in_capsrc)
- val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT);
- else
- val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT);
- kcontrol->private_value = val;
- err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
- mutex_unlock(&codec->control_mutex);
- return err;
-}
-
-static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
- unsigned int size, unsigned int __user *tlv)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
- unsigned long val;
- int err;
-
- mutex_lock(&codec->control_mutex);
- if (spec->vol_in_capsrc)
- val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT);
- else
- val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT);
- kcontrol->private_value = val;
- err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
- mutex_unlock(&codec->control_mutex);
- return err;
-}
-
-typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-
-static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol,
- getput_call_t func, bool check_adc_switch)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
- int i, err = 0;
-
- mutex_lock(&codec->control_mutex);
- if (check_adc_switch && spec->dyn_adc_switch) {
- for (i = 0; i < spec->num_adc_nids; i++) {
- kcontrol->private_value =
- HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
- 3, 0, HDA_INPUT);
- err = func(kcontrol, ucontrol);
- if (err < 0)
- goto error;
- }
- } else {
- i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- if (spec->vol_in_capsrc)
- kcontrol->private_value =
- HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[i],
- 3, 0, HDA_OUTPUT);
- else
- kcontrol->private_value =
- HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
- 3, 0, HDA_INPUT);
- err = func(kcontrol, ucontrol);
- }
- error:
- mutex_unlock(&codec->control_mutex);
- return err;
-}
-
-static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- return alc_cap_getput_caller(kcontrol, ucontrol,
- snd_hda_mixer_amp_volume_get, false);
-}
-
-static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- return alc_cap_getput_caller(kcontrol, ucontrol,
- snd_hda_mixer_amp_volume_put, true);
-}
-
-/* capture mixer elements */
-#define alc_cap_sw_info snd_ctl_boolean_stereo_info
-
-static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- return alc_cap_getput_caller(kcontrol, ucontrol,
- snd_hda_mixer_amp_switch_get, false);
-}
-
-static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- return alc_cap_getput_caller(kcontrol, ucontrol,
- snd_hda_mixer_amp_switch_put, true);
-}
-
-#define _DEFINE_CAPMIX(num) \
- { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = "Capture Switch", \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
- .count = num, \
- .info = alc_cap_sw_info, \
- .get = alc_cap_sw_get, \
- .put = alc_cap_sw_put, \
- }, \
- { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = "Capture Volume", \
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
- SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
- SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
- .count = num, \
- .info = alc_cap_vol_info, \
- .get = alc_cap_vol_get, \
- .put = alc_cap_vol_put, \
- .tlv = { .c = alc_cap_vol_tlv }, \
- }
-
-#define _DEFINE_CAPSRC(num) \
- { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- /* .name = "Capture Source", */ \
- .name = "Input Source", \
- .count = num, \
- .info = alc_mux_enum_info, \
- .get = alc_mux_enum_get, \
- .put = alc_mux_enum_put, \
- }
-
-#define DEFINE_CAPMIX(num) \
-static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
- _DEFINE_CAPMIX(num), \
- _DEFINE_CAPSRC(num), \
- { } /* end */ \
-}
-
-#define DEFINE_CAPMIX_NOSRC(num) \
-static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
- _DEFINE_CAPMIX(num), \
- { } /* end */ \
-}
-
-/* up to three ADCs */
-DEFINE_CAPMIX(1);
-DEFINE_CAPMIX(2);
-DEFINE_CAPMIX(3);
-DEFINE_CAPMIX_NOSRC(1);
-DEFINE_CAPMIX_NOSRC(2);
-DEFINE_CAPMIX_NOSRC(3);
-
-/*
- * virtual master controls
- */
-
-/*
- * slave controls for virtual master
- */
-static const char * const alc_slave_pfxs[] = {
- "Front", "Surround", "Center", "LFE", "Side",
- "Headphone", "Speaker", "Mono", "Line Out",
- "CLFE", "Bass Speaker", "PCM",
- NULL,
-};
-
-/*
- * build control elements
- */
-
-#define NID_MAPPING (-1)
-
-#define SUBDEV_SPEAKER_ (0 << 6)
-#define SUBDEV_HP_ (1 << 6)
-#define SUBDEV_LINE_ (2 << 6)
-#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
-#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
-#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
-
-static void alc_free_kctls(struct hda_codec *codec);
-
-#ifdef CONFIG_SND_HDA_INPUT_BEEP
-/* additional beep mixers; the actual parameters are overwritten at build */
-static const struct snd_kcontrol_new alc_beep_mixer[] = {
- HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
- HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
- { } /* end */
-};
-#endif
-
-static int __alc_build_controls(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- struct snd_kcontrol *kctl = NULL;
- const struct snd_kcontrol_new *knew;
- int i, j, err;
- unsigned int u;
- hda_nid_t nid;
-
- for (i = 0; i < spec->num_mixers; i++) {
- err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
- if (err < 0)
- return err;
- }
- if (spec->cap_mixer) {
- err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
- if (err < 0)
- return err;
- }
- if (spec->multiout.dig_out_nid) {
- err = snd_hda_create_spdif_out_ctls(codec,
- spec->multiout.dig_out_nid,
- spec->multiout.dig_out_nid);
- if (err < 0)
- return err;
- if (!spec->no_analog) {
- err = snd_hda_create_spdif_share_sw(codec,
- &spec->multiout);
- if (err < 0)
- return err;
- spec->multiout.share_spdif = 1;
- }
- }
- if (spec->dig_in_nid) {
- err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
- if (err < 0)
- return err;
- }
-
-#ifdef CONFIG_SND_HDA_INPUT_BEEP
- /* create beep controls if needed */
- if (spec->beep_amp) {
- const struct snd_kcontrol_new *knew;
- for (knew = alc_beep_mixer; knew->name; knew++) {
- struct snd_kcontrol *kctl;
- kctl = snd_ctl_new1(knew, codec);
- if (!kctl)
- return -ENOMEM;
- kctl->private_value = spec->beep_amp;
- err = snd_hda_ctl_add(codec, 0, kctl);
- if (err < 0)
- return err;
- }
- }
-#endif
-
- /* if we have no master control, let's create it */
- if (!spec->no_analog &&
- !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
- unsigned int vmaster_tlv[4];
- snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
- HDA_OUTPUT, vmaster_tlv);
- err = snd_hda_add_vmaster(codec, "Master Playback Volume",
- vmaster_tlv, alc_slave_pfxs,
- "Playback Volume");
- if (err < 0)
- return err;
- }
- if (!spec->no_analog &&
- !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
- err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
- NULL, alc_slave_pfxs,
- "Playback Switch",
- true, &spec->vmaster_mute.sw_kctl);
- if (err < 0)
- return err;
- }
-
- /* assign Capture Source enums to NID */
- if (spec->capsrc_nids || spec->adc_nids) {
- kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
- if (!kctl)
- kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
- for (i = 0; kctl && i < kctl->count; i++) {
- err = snd_hda_add_nid(codec, kctl, i,
- get_capsrc(spec, i));
- if (err < 0)
- return err;
- }
- }
- if (spec->cap_mixer && spec->adc_nids) {
- const char *kname = kctl ? kctl->id.name : NULL;
- for (knew = spec->cap_mixer; knew->name; knew++) {
- if (kname && strcmp(knew->name, kname) == 0)
- continue;
- kctl = snd_hda_find_mixer_ctl(codec, knew->name);
- for (i = 0; kctl && i < kctl->count; i++) {
- err = snd_hda_add_nid(codec, kctl, i,
- spec->adc_nids[i]);
- if (err < 0)
- return err;
- }
- }
- }
-
- /* other nid->control mapping */
- for (i = 0; i < spec->num_mixers; i++) {
- for (knew = spec->mixers[i]; knew->name; knew++) {
- if (knew->iface != NID_MAPPING)
- continue;
- kctl = snd_hda_find_mixer_ctl(codec, knew->name);
- if (kctl == NULL)
- continue;
- u = knew->subdevice;
- for (j = 0; j < 4; j++, u >>= 8) {
- nid = u & 0x3f;
- if (nid == 0)
- continue;
- switch (u & 0xc0) {
- case SUBDEV_SPEAKER_:
- nid = spec->autocfg.speaker_pins[nid];
- break;
- case SUBDEV_LINE_:
- nid = spec->autocfg.line_out_pins[nid];
- break;
- case SUBDEV_HP_:
- nid = spec->autocfg.hp_pins[nid];
- break;
- default:
- continue;
- }
- err = snd_hda_add_nid(codec, kctl, 0, nid);
- if (err < 0)
- return err;
- }
- u = knew->private_value;
- for (j = 0; j < 4; j++, u >>= 8) {
- nid = u & 0xff;
- if (nid == 0)
- continue;
- err = snd_hda_add_nid(codec, kctl, 0, nid);
- if (err < 0)
- return err;
- }
- }
- }
-
- alc_free_kctls(codec); /* no longer needed */
-
- return 0;
-}
-
-static int alc_build_controls(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- int err = __alc_build_controls(codec);
- if (err < 0)
- return err;
- err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
- if (err < 0)
- return err;
- alc_apply_fixup(codec, ALC_FIXUP_ACT_BUILD);
- return 0;
-}
-
-
-/*
- * Common callbacks
- */
-
-static void alc_init_special_input_src(struct hda_codec *codec);
-static void alc_auto_init_std(struct hda_codec *codec);
-
-static int alc_init(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- unsigned int i;
-
- if (spec->init_hook)
- spec->init_hook(codec);
-
- alc_fix_pll(codec);
- alc_auto_init_amp(codec, spec->init_amp);
-
- for (i = 0; i < spec->num_init_verbs; i++)
- snd_hda_sequence_write(codec, spec->init_verbs[i]);
- alc_init_special_input_src(codec);
- alc_auto_init_std(codec);
-
- alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
-
- snd_hda_jack_report_sync(codec);
-
- hda_call_check_power_status(codec, 0x01);
- return 0;
-}
-
-static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- struct alc_spec *spec = codec->spec;
-
- if (spec->unsol_event)
- spec->unsol_event(codec, res);
-}
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
-{
- struct alc_spec *spec = codec->spec;
- return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
-}
-#endif
-
-/*
- * Analog playback callbacks
- */
-static int alc_playback_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct alc_spec *spec = codec->spec;
- return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
- hinfo);
-}
-
-static int alc_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct alc_spec *spec = codec->spec;
- return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
- stream_tag, format, substream);
-}
-
-static int alc_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct alc_spec *spec = codec->spec;
- return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
-}
-
-/*
- * Digital out
- */
-static int alc_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct alc_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_open(codec, &spec->multiout);
-}
-
-static int alc_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct alc_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
- stream_tag, format, substream);
-}
-
-static int alc_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct alc_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
-}
-
-static int alc_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct alc_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_close(codec, &spec->multiout);
-}
-
-/*
- * Analog capture
- */
-static int alc_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct alc_spec *spec = codec->spec;
-
- snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
- stream_tag, 0, format);
- return 0;
-}
-
-static int alc_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct alc_spec *spec = codec->spec;
-
- snd_hda_codec_cleanup_stream(codec,
- spec->adc_nids[substream->number + 1]);
- return 0;
-}
-
-/* analog capture with dynamic dual-adc changes */
-static int dyn_adc_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct alc_spec *spec = codec->spec;
- spec->cur_adc = spec->adc_nids[spec->dyn_adc_idx[spec->cur_mux[0]]];
- spec->cur_adc_stream_tag = stream_tag;
- spec->cur_adc_format = format;
- snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
- return 0;
-}
-
-static int dyn_adc_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct alc_spec *spec = codec->spec;
- snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
- spec->cur_adc = 0;
- return 0;
-}
-
-static const struct hda_pcm_stream dyn_adc_pcm_analog_capture = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .nid = 0, /* fill later */
- .ops = {
- .prepare = dyn_adc_capture_pcm_prepare,
- .cleanup = dyn_adc_capture_pcm_cleanup
- },
-};
-
-/*
- */
-static const struct hda_pcm_stream alc_pcm_analog_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 8,
- /* NID is set in alc_build_pcms */
- .ops = {
- .open = alc_playback_pcm_open,
- .prepare = alc_playback_pcm_prepare,
- .cleanup = alc_playback_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream alc_pcm_analog_capture = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- /* NID is set in alc_build_pcms */
-};
-
-static const struct hda_pcm_stream alc_pcm_analog_alt_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- /* NID is set in alc_build_pcms */
-};
-
-static const struct hda_pcm_stream alc_pcm_analog_alt_capture = {
- .substreams = 2, /* can be overridden */
- .channels_min = 2,
- .channels_max = 2,
- /* NID is set in alc_build_pcms */
- .ops = {
- .prepare = alc_alt_capture_pcm_prepare,
- .cleanup = alc_alt_capture_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream alc_pcm_digital_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- /* NID is set in alc_build_pcms */
- .ops = {
- .open = alc_dig_playback_pcm_open,
- .close = alc_dig_playback_pcm_close,
- .prepare = alc_dig_playback_pcm_prepare,
- .cleanup = alc_dig_playback_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream alc_pcm_digital_capture = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- /* NID is set in alc_build_pcms */
-};
-
-/* Used by alc_build_pcms to flag that a PCM has no playback stream */
-static const struct hda_pcm_stream alc_pcm_null_stream = {
- .substreams = 0,
- .channels_min = 0,
- .channels_max = 0,
-};
-
-static int alc_build_pcms(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- struct hda_pcm *info = spec->pcm_rec;
- const struct hda_pcm_stream *p;
- bool have_multi_adcs;
- int i;
-
- codec->num_pcms = 1;
- codec->pcm_info = info;
-
- if (spec->no_analog)
- goto skip_analog;
-
- snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
- "%s Analog", codec->chip_name);
- info->name = spec->stream_name_analog;
-
- if (spec->multiout.num_dacs > 0) {
- p = spec->stream_analog_playback;
- if (!p)
- p = &alc_pcm_analog_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
- }
- if (spec->adc_nids) {
- p = spec->stream_analog_capture;
- if (!p) {
- if (spec->dyn_adc_switch)
- p = &dyn_adc_pcm_analog_capture;
- else
- p = &alc_pcm_analog_capture;
- }
- info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
- }
-
- if (spec->channel_mode) {
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
- for (i = 0; i < spec->num_channel_mode; i++) {
- if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
- }
- }
- }
-
- skip_analog:
- /* SPDIF for stream index #1 */
- if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
- snprintf(spec->stream_name_digital,
- sizeof(spec->stream_name_digital),
- "%s Digital", codec->chip_name);
- codec->num_pcms = 2;
- codec->slave_dig_outs = spec->multiout.slave_dig_outs;
- info = spec->pcm_rec + 1;
- info->name = spec->stream_name_digital;
- if (spec->dig_out_type)
- info->pcm_type = spec->dig_out_type;
- else
- info->pcm_type = HDA_PCM_TYPE_SPDIF;
- if (spec->multiout.dig_out_nid) {
- p = spec->stream_digital_playback;
- if (!p)
- p = &alc_pcm_digital_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
- }
- if (spec->dig_in_nid) {
- p = spec->stream_digital_capture;
- if (!p)
- p = &alc_pcm_digital_capture;
- info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
- }
- /* FIXME: do we need this for all Realtek codec models? */
- codec->spdif_status_reset = 1;
- }
-
- if (spec->no_analog)
- return 0;
-
- /* If the use of more than one ADC is requested for the current
- * model, configure a second analog capture-only PCM.
- */
- have_multi_adcs = (spec->num_adc_nids > 1) &&
- !spec->dyn_adc_switch && !spec->auto_mic &&
- (!spec->input_mux || spec->input_mux->num_items > 1);
- /* Additional Analaog capture for index #2 */
- if (spec->alt_dac_nid || have_multi_adcs) {
- codec->num_pcms = 3;
- info = spec->pcm_rec + 2;
- info->name = spec->stream_name_analog;
- if (spec->alt_dac_nid) {
- p = spec->stream_analog_alt_playback;
- if (!p)
- p = &alc_pcm_analog_alt_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
- spec->alt_dac_nid;
- } else {
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
- alc_pcm_null_stream;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
- }
- if (have_multi_adcs) {
- p = spec->stream_analog_alt_capture;
- if (!p)
- p = &alc_pcm_analog_alt_capture;
- info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
- spec->adc_nids[1];
- info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
- spec->num_adc_nids - 1;
- } else {
- info->stream[SNDRV_PCM_STREAM_CAPTURE] =
- alc_pcm_null_stream;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
- }
- }
-
- return 0;
-}
-
-static inline void alc_shutup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- if (spec && spec->shutup)
- spec->shutup(codec);
- snd_hda_shutup_pins(codec);
-}
-
-static void alc_free_kctls(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- if (spec->kctls.list) {
- struct snd_kcontrol_new *kctl = spec->kctls.list;
- int i;
- for (i = 0; i < spec->kctls.used; i++)
- kfree(kctl[i].name);
- }
- snd_array_free(&spec->kctls);
-}
-
-static void alc_free_bind_ctls(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- if (spec->bind_ctls.list) {
- struct hda_bind_ctls **ctl = spec->bind_ctls.list;
- int i;
- for (i = 0; i < spec->bind_ctls.used; i++)
- kfree(ctl[i]);
- }
- snd_array_free(&spec->bind_ctls);
-}
-
-static void alc_free(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- if (!spec)
- return;
-
- alc_shutup(codec);
- alc_free_kctls(codec);
- alc_free_bind_ctls(codec);
- kfree(spec);
- snd_hda_detach_beep_device(codec);
-}
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static void alc_power_eapd(struct hda_codec *codec)
-{
- alc_auto_setup_eapd(codec, false);
-}
-
-static int alc_suspend(struct hda_codec *codec, pm_message_t state)
-{
- struct alc_spec *spec = codec->spec;
- alc_shutup(codec);
- if (spec && spec->power_hook)
- spec->power_hook(codec);
- return 0;
-}
-#endif
-
-#ifdef CONFIG_PM
-static int alc_resume(struct hda_codec *codec)
-{
- msleep(150); /* to avoid pop noise */
- codec->patch_ops.init(codec);
- snd_hda_codec_resume_amp(codec);
- snd_hda_codec_resume_cache(codec);
- hda_call_check_power_status(codec, 0x01);
- return 0;
-}
-#endif
-
-/*
- */
-static const struct hda_codec_ops alc_patch_ops = {
- .build_controls = alc_build_controls,
- .build_pcms = alc_build_pcms,
- .init = alc_init,
- .free = alc_free,
- .unsol_event = alc_unsol_event,
-#ifdef CONFIG_PM
- .resume = alc_resume,
-#endif
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- .suspend = alc_suspend,
- .check_power_status = alc_check_power_status,
-#endif
- .reboot_notify = alc_shutup,
-};
-
-/* replace the codec chip_name with the given string */
-static int alc_codec_rename(struct hda_codec *codec, const char *name)
-{
- kfree(codec->chip_name);
- codec->chip_name = kstrdup(name, GFP_KERNEL);
- if (!codec->chip_name) {
- alc_free(codec);
- return -ENOMEM;
- }
- return 0;
-}
-
-/*
- * Rename codecs appropriately from COEF value
- */
-struct alc_codec_rename_table {
- unsigned int vendor_id;
- unsigned short coef_mask;
- unsigned short coef_bits;
- const char *name;
-};
-
-static struct alc_codec_rename_table rename_tbl[] = {
- { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
- { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
- { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
- { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
- { 0x10ec0269, 0xffff, 0xa023, "ALC259" },
- { 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
- { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
- { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
- { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
- { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
- { 0x10ec0899, 0x2000, 0x2000, "ALC899" },
- { 0x10ec0892, 0xffff, 0x8020, "ALC661" },
- { 0x10ec0892, 0xffff, 0x8011, "ALC661" },
- { 0x10ec0892, 0xffff, 0x4011, "ALC656" },
- { } /* terminator */
-};
-
-static int alc_codec_rename_from_preset(struct hda_codec *codec)
-{
- const struct alc_codec_rename_table *p;
-
- for (p = rename_tbl; p->vendor_id; p++) {
- if (p->vendor_id != codec->vendor_id)
- continue;
- if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
- return alc_codec_rename(codec, p->name);
- }
- return 0;
-}
-
-/*
- * Automatic parse of I/O pins from the BIOS configuration
- */
-
-enum {
- ALC_CTL_WIDGET_VOL,
- ALC_CTL_WIDGET_MUTE,
- ALC_CTL_BIND_MUTE,
- ALC_CTL_BIND_VOL,
- ALC_CTL_BIND_SW,
-};
-static const struct snd_kcontrol_new alc_control_templates[] = {
- HDA_CODEC_VOLUME(NULL, 0, 0, 0),
- HDA_CODEC_MUTE(NULL, 0, 0, 0),
- HDA_BIND_MUTE(NULL, 0, 0, 0),
- HDA_BIND_VOL(NULL, 0),
- HDA_BIND_SW(NULL, 0),
-};
-
-/* add dynamic controls */
-static int add_control(struct alc_spec *spec, int type, const char *name,
- int cidx, unsigned long val)
-{
- struct snd_kcontrol_new *knew;
-
- knew = alc_kcontrol_new(spec);
- if (!knew)
- return -ENOMEM;
- *knew = alc_control_templates[type];
- knew->name = kstrdup(name, GFP_KERNEL);
- if (!knew->name)
- return -ENOMEM;
- knew->index = cidx;
- if (get_amp_nid_(val))
- knew->subdevice = HDA_SUBDEV_AMP_FLAG;
- knew->private_value = val;
- return 0;
-}
-
-static int add_control_with_pfx(struct alc_spec *spec, int type,
- const char *pfx, const char *dir,
- const char *sfx, int cidx, unsigned long val)
-{
- char name[32];
- snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
- return add_control(spec, type, name, cidx, val);
-}
-
-#define add_pb_vol_ctrl(spec, type, pfx, val) \
- add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
-#define add_pb_sw_ctrl(spec, type, pfx, val) \
- add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
-#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
- add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
-#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
- add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
-
-static const char * const channel_name[4] = {
- "Front", "Surround", "CLFE", "Side"
-};
-
-static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
- bool can_be_master, int *index)
-{
- struct auto_pin_cfg *cfg = &spec->autocfg;
-
- *index = 0;
- if (cfg->line_outs == 1 && !spec->multi_ios &&
- !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
- return "Master";
-
- switch (cfg->line_out_type) {
- case AUTO_PIN_SPEAKER_OUT:
- if (cfg->line_outs == 1)
- return "Speaker";
- if (cfg->line_outs == 2)
- return ch ? "Bass Speaker" : "Speaker";
- break;
- case AUTO_PIN_HP_OUT:
- /* for multi-io case, only the primary out */
- if (ch && spec->multi_ios)
- break;
- *index = ch;
- return "Headphone";
- default:
- if (cfg->line_outs == 1 && !spec->multi_ios)
- return "PCM";
- break;
- }
- if (snd_BUG_ON(ch >= ARRAY_SIZE(channel_name)))
- return "PCM";
-
- return channel_name[ch];
-}
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-/* add the powersave loopback-list entry */
-static void add_loopback_list(struct alc_spec *spec, hda_nid_t mix, int idx)
-{
- struct hda_amp_list *list;
-
- if (spec->num_loopbacks >= ARRAY_SIZE(spec->loopback_list) - 1)
- return;
- list = spec->loopback_list + spec->num_loopbacks;
- list->nid = mix;
- list->dir = HDA_INPUT;
- list->idx = idx;
- spec->num_loopbacks++;
- spec->loopback.amplist = spec->loopback_list;
-}
-#else
-#define add_loopback_list(spec, mix, idx) /* NOP */
-#endif
-
-/* create input playback/capture controls for the given pin */
-static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
- const char *ctlname, int ctlidx,
- int idx, hda_nid_t mix_nid)
-{
- int err;
-
- err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
- HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
- if (err < 0)
- return err;
- err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
- HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
- if (err < 0)
- return err;
- add_loopback_list(spec, mix_nid, idx);
- return 0;
-}
-
-static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
-{
- unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
- return (pincap & AC_PINCAP_IN) != 0;
-}
-
-/* Parse the codec tree and retrieve ADCs and corresponding capsrc MUXs */
-static int alc_auto_fill_adc_caps(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- hda_nid_t nid;
- hda_nid_t *adc_nids = spec->private_adc_nids;
- hda_nid_t *cap_nids = spec->private_capsrc_nids;
- int max_nums = ARRAY_SIZE(spec->private_adc_nids);
- int i, nums = 0;
-
- nid = codec->start_nid;
- for (i = 0; i < codec->num_nodes; i++, nid++) {
- hda_nid_t src;
- const hda_nid_t *list;
- unsigned int caps = get_wcaps(codec, nid);
- int type = get_wcaps_type(caps);
-
- if (type != AC_WID_AUD_IN || (caps & AC_WCAP_DIGITAL))
- continue;
- adc_nids[nums] = nid;
- cap_nids[nums] = nid;
- src = nid;
- for (;;) {
- int n;
- type = get_wcaps_type(get_wcaps(codec, src));
- if (type == AC_WID_PIN)
- break;
- if (type == AC_WID_AUD_SEL) {
- cap_nids[nums] = src;
- break;
- }
- n = snd_hda_get_conn_list(codec, src, &list);
- if (n > 1) {
- cap_nids[nums] = src;
- break;
- } else if (n != 1)
- break;
- src = *list;
- }
- if (++nums >= max_nums)
- break;
- }
- spec->adc_nids = spec->private_adc_nids;
- spec->capsrc_nids = spec->private_capsrc_nids;
- spec->num_adc_nids = nums;
- return nums;
-}
-
-/* create playback/capture controls for input pins */
-static int alc_auto_create_input_ctls(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- const struct auto_pin_cfg *cfg = &spec->autocfg;
- hda_nid_t mixer = spec->mixer_nid;
- struct hda_input_mux *imux = &spec->private_imux[0];
- int num_adcs;
- int i, c, err, idx, type_idx = 0;
- const char *prev_label = NULL;
-
- num_adcs = alc_auto_fill_adc_caps(codec);
- if (num_adcs < 0)
- return 0;
-
- for (i = 0; i < cfg->num_inputs; i++) {
- hda_nid_t pin;
- const char *label;
-
- pin = cfg->inputs[i].pin;
- if (!alc_is_input_pin(codec, pin))
- continue;
-
- label = hda_get_autocfg_input_label(codec, cfg, i);
- if (spec->shared_mic_hp && !strcmp(label, "Misc"))
- label = "Headphone Mic";
- if (prev_label && !strcmp(label, prev_label))
- type_idx++;
- else
- type_idx = 0;
- prev_label = label;
-
- if (mixer) {
- idx = get_connection_index(codec, mixer, pin);
- if (idx >= 0) {
- err = new_analog_input(spec, pin,
- label, type_idx,
- idx, mixer);
- if (err < 0)
- return err;
- }
- }
-
- for (c = 0; c < num_adcs; c++) {
- hda_nid_t cap = get_capsrc(spec, c);
- idx = get_connection_index(codec, cap, pin);
- if (idx >= 0) {
- spec->imux_pins[imux->num_items] = pin;
- snd_hda_add_imux_item(imux, label, idx, NULL);
- break;
- }
- }
- }
-
- spec->num_mux_defs = 1;
- spec->input_mux = imux;
-
- return 0;
-}
-
-/* create a shared input with the headphone out */
-static int alc_auto_create_shared_input(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- unsigned int defcfg;
- hda_nid_t nid;
-
- /* only one internal input pin? */
- if (cfg->num_inputs != 1)
- return 0;
- defcfg = snd_hda_codec_get_pincfg(codec, cfg->inputs[0].pin);
- if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
- return 0;
-
- if (cfg->hp_outs == 1 && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
- nid = cfg->hp_pins[0]; /* OK, we have a single HP-out */
- else if (cfg->line_outs == 1 && cfg->line_out_type == AUTO_PIN_HP_OUT)
- nid = cfg->line_out_pins[0]; /* OK, we have a single line-out */
- else
- return 0; /* both not available */
-
- if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_IN))
- return 0; /* no input */
-
- cfg->inputs[1].pin = nid;
- cfg->inputs[1].type = AUTO_PIN_MIC;
- cfg->num_inputs = 2;
- spec->shared_mic_hp = 1;
- snd_printdd("realtek: Enable shared I/O jack on NID 0x%x\n", nid);
- return 0;
-}
-
-static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
- unsigned int pin_type)
-{
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
- pin_type);
- /* unmute pin */
- if (nid_has_mute(codec, nid, HDA_OUTPUT))
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_OUT_UNMUTE);
-}
-
-static int get_pin_type(int line_out_type)
-{
- if (line_out_type == AUTO_PIN_HP_OUT)
- return PIN_HP;
- else
- return PIN_OUT;
-}
-
-static void alc_auto_init_analog_input(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i;
-
- for (i = 0; i < cfg->num_inputs; i++) {
- hda_nid_t nid = cfg->inputs[i].pin;
- if (alc_is_input_pin(codec, nid)) {
- alc_set_input_pin(codec, nid, cfg->inputs[i].type);
- if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_OUT_MUTE);
- }
- }
-
- /* mute all loopback inputs */
- if (spec->mixer_nid) {
- int nums = snd_hda_get_conn_list(codec, spec->mixer_nid, NULL);
- for (i = 0; i < nums; i++)
- snd_hda_codec_write(codec, spec->mixer_nid, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_IN_MUTE(i));
- }
-}
-
-/* convert from MIX nid to DAC */
-static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
-{
- hda_nid_t list[5];
- int i, num;
-
- if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_AUD_OUT)
- return nid;
- num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
- for (i = 0; i < num; i++) {
- if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
- return list[i];
- }
- return 0;
-}
-
-/* go down to the selector widget before the mixer */
-static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
-{
- hda_nid_t srcs[5];
- int num = snd_hda_get_connections(codec, pin, srcs,
- ARRAY_SIZE(srcs));
- if (num != 1 ||
- get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
- return pin;
- return srcs[0];
-}
-
-/* get MIX nid connected to the given pin targeted to DAC */
-static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
- hda_nid_t dac)
-{
- hda_nid_t mix[5];
- int i, num;
-
- pin = alc_go_down_to_selector(codec, pin);
- num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
- for (i = 0; i < num; i++) {
- if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
- return mix[i];
- }
- return 0;
-}
-
-/* select the connection from pin to DAC if needed */
-static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
- hda_nid_t dac)
-{
- hda_nid_t mix[5];
- int i, num;
-
- pin = alc_go_down_to_selector(codec, pin);
- num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
- if (num < 2)
- return 0;
- for (i = 0; i < num; i++) {
- if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
- snd_hda_codec_update_cache(codec, pin, 0,
- AC_VERB_SET_CONNECT_SEL, i);
- return 0;
- }
- }
- return 0;
-}
-
-static bool alc_is_dac_already_used(struct hda_codec *codec, hda_nid_t nid)
-{
- struct alc_spec *spec = codec->spec;
- int i;
- if (found_in_nid_list(nid, spec->multiout.dac_nids,
- ARRAY_SIZE(spec->private_dac_nids)) ||
- found_in_nid_list(nid, spec->multiout.hp_out_nid,
- ARRAY_SIZE(spec->multiout.hp_out_nid)) ||
- found_in_nid_list(nid, spec->multiout.extra_out_nid,
- ARRAY_SIZE(spec->multiout.extra_out_nid)))
- return true;
- for (i = 0; i < spec->multi_ios; i++) {
- if (spec->multi_io[i].dac == nid)
- return true;
- }
- return false;
-}
-
-/* look for an empty DAC slot */
-static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
-{
- hda_nid_t srcs[5];
- int i, num;
-
- pin = alc_go_down_to_selector(codec, pin);
- num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
- for (i = 0; i < num; i++) {
- hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
- if (!nid)
- continue;
- if (!alc_is_dac_already_used(codec, nid))
- return nid;
- }
- return 0;
-}
-
-/* check whether the DAC is reachable from the pin */
-static bool alc_auto_is_dac_reachable(struct hda_codec *codec,
- hda_nid_t pin, hda_nid_t dac)
-{
- hda_nid_t srcs[5];
- int i, num;
-
- if (!pin || !dac)
- return false;
- pin = alc_go_down_to_selector(codec, pin);
- num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
- for (i = 0; i < num; i++) {
- hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
- if (nid == dac)
- return true;
- }
- return false;
-}
-
-static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
-{
- struct alc_spec *spec = codec->spec;
- hda_nid_t sel = alc_go_down_to_selector(codec, pin);
- hda_nid_t nid, nid_found, srcs[5];
- int i, num = snd_hda_get_connections(codec, sel, srcs,
- ARRAY_SIZE(srcs));
- if (num == 1)
- return alc_auto_look_for_dac(codec, pin);
- nid_found = 0;
- for (i = 0; i < num; i++) {
- if (srcs[i] == spec->mixer_nid)
- continue;
- nid = alc_auto_mix_to_dac(codec, srcs[i]);
- if (nid && !alc_is_dac_already_used(codec, nid)) {
- if (nid_found)
- return 0;
- nid_found = nid;
- }
- }
- return nid_found;
-}
-
-/* mark up volume and mute control NIDs: used during badness parsing and
- * at creating actual controls
- */
-static inline unsigned int get_ctl_pos(unsigned int data)
-{
- hda_nid_t nid = get_amp_nid_(data);
- unsigned int dir;
- if (snd_BUG_ON(nid >= MAX_VOL_NIDS))
- return 0;
- dir = get_amp_direction_(data);
- return (nid << 1) | dir;
-}
-
-#define is_ctl_used(bits, data) \
- test_bit(get_ctl_pos(data), bits)
-#define mark_ctl_usage(bits, data) \
- set_bit(get_ctl_pos(data), bits)
-
-static void clear_vol_marks(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- memset(spec->vol_ctls, 0, sizeof(spec->vol_ctls));
- memset(spec->sw_ctls, 0, sizeof(spec->sw_ctls));
-}
-
-/* badness definition */
-enum {
- /* No primary DAC is found for the main output */
- BAD_NO_PRIMARY_DAC = 0x10000,
- /* No DAC is found for the extra output */
- BAD_NO_DAC = 0x4000,
- /* No possible multi-ios */
- BAD_MULTI_IO = 0x103,
- /* No individual DAC for extra output */
- BAD_NO_EXTRA_DAC = 0x102,
- /* No individual DAC for extra surrounds */
- BAD_NO_EXTRA_SURR_DAC = 0x101,
- /* Primary DAC shared with main surrounds */
- BAD_SHARED_SURROUND = 0x100,
- /* Primary DAC shared with main CLFE */
- BAD_SHARED_CLFE = 0x10,
- /* Primary DAC shared with extra surrounds */
- BAD_SHARED_EXTRA_SURROUND = 0x10,
- /* Volume widget is shared */
- BAD_SHARED_VOL = 0x10,
-};
-
-static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec,
- hda_nid_t pin, hda_nid_t dac);
-static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
- hda_nid_t pin, hda_nid_t dac);
-
-static int eval_shared_vol_badness(struct hda_codec *codec, hda_nid_t pin,
- hda_nid_t dac)
-{
- struct alc_spec *spec = codec->spec;
- hda_nid_t nid;
- unsigned int val;
- int badness = 0;
-
- nid = alc_look_for_out_vol_nid(codec, pin, dac);
- if (nid) {
- val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
- if (is_ctl_used(spec->vol_ctls, nid))
- badness += BAD_SHARED_VOL;
- else
- mark_ctl_usage(spec->vol_ctls, val);
- } else
- badness += BAD_SHARED_VOL;
- nid = alc_look_for_out_mute_nid(codec, pin, dac);
- if (nid) {
- unsigned int wid_type = get_wcaps_type(get_wcaps(codec, nid));
- if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT)
- val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
- else
- val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT);
- if (is_ctl_used(spec->sw_ctls, val))
- badness += BAD_SHARED_VOL;
- else
- mark_ctl_usage(spec->sw_ctls, val);
- } else
- badness += BAD_SHARED_VOL;
- return badness;
-}
-
-struct badness_table {
- int no_primary_dac; /* no primary DAC */
- int no_dac; /* no secondary DACs */
- int shared_primary; /* primary DAC is shared with main output */
- int shared_surr; /* secondary DAC shared with main or primary */
- int shared_clfe; /* third DAC shared with main or primary */
- int shared_surr_main; /* secondary DAC sahred with main/DAC0 */
-};
-
-static struct badness_table main_out_badness = {
- .no_primary_dac = BAD_NO_PRIMARY_DAC,
- .no_dac = BAD_NO_DAC,
- .shared_primary = BAD_NO_PRIMARY_DAC,
- .shared_surr = BAD_SHARED_SURROUND,
- .shared_clfe = BAD_SHARED_CLFE,
- .shared_surr_main = BAD_SHARED_SURROUND,
-};
-
-static struct badness_table extra_out_badness = {
- .no_primary_dac = BAD_NO_DAC,
- .no_dac = BAD_NO_DAC,
- .shared_primary = BAD_NO_EXTRA_DAC,
- .shared_surr = BAD_SHARED_EXTRA_SURROUND,
- .shared_clfe = BAD_SHARED_EXTRA_SURROUND,
- .shared_surr_main = BAD_NO_EXTRA_SURR_DAC,
-};
-
-/* try to assign DACs to pins and return the resultant badness */
-static int alc_auto_fill_dacs(struct hda_codec *codec, int num_outs,
- const hda_nid_t *pins, hda_nid_t *dacs,
- const struct badness_table *bad)
-{
- struct alc_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i, j;
- int badness = 0;
- hda_nid_t dac;
-
- if (!num_outs)
- return 0;
-
- for (i = 0; i < num_outs; i++) {
- hda_nid_t pin = pins[i];
- if (!dacs[i])
- dacs[i] = alc_auto_look_for_dac(codec, pin);
- if (!dacs[i] && !i) {
- for (j = 1; j < num_outs; j++) {
- if (alc_auto_is_dac_reachable(codec, pin, dacs[j])) {
- dacs[0] = dacs[j];
- dacs[j] = 0;
- break;
- }
- }
- }
- dac = dacs[i];
- if (!dac) {
- if (alc_auto_is_dac_reachable(codec, pin, dacs[0]))
- dac = dacs[0];
- else if (cfg->line_outs > i &&
- alc_auto_is_dac_reachable(codec, pin,
- spec->private_dac_nids[i]))
- dac = spec->private_dac_nids[i];
- if (dac) {
- if (!i)
- badness += bad->shared_primary;
- else if (i == 1)
- badness += bad->shared_surr;
- else
- badness += bad->shared_clfe;
- } else if (alc_auto_is_dac_reachable(codec, pin,
- spec->private_dac_nids[0])) {
- dac = spec->private_dac_nids[0];
- badness += bad->shared_surr_main;
- } else if (!i)
- badness += bad->no_primary_dac;
- else
- badness += bad->no_dac;
- }
- if (dac)
- badness += eval_shared_vol_badness(codec, pin, dac);
- }
-
- return badness;
-}
-
-static int alc_auto_fill_multi_ios(struct hda_codec *codec,
- hda_nid_t reference_pin,
- bool hardwired, int offset);
-
-static bool alc_map_singles(struct hda_codec *codec, int outs,
- const hda_nid_t *pins, hda_nid_t *dacs)
-{
- int i;
- bool found = false;
- for (i = 0; i < outs; i++) {
- if (dacs[i])
- continue;
- dacs[i] = get_dac_if_single(codec, pins[i]);
- if (dacs[i])
- found = true;
- }
- return found;
-}
-
-/* fill in the dac_nids table from the parsed pin configuration */
-static int fill_and_eval_dacs(struct hda_codec *codec,
- bool fill_hardwired,
- bool fill_mio_first)
-{
- struct alc_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i, err, badness;
-
- /* set num_dacs once to full for alc_auto_look_for_dac() */
- spec->multiout.num_dacs = cfg->line_outs;
- spec->multiout.dac_nids = spec->private_dac_nids;
- memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
- memset(spec->multiout.hp_out_nid, 0, sizeof(spec->multiout.hp_out_nid));
- memset(spec->multiout.extra_out_nid, 0, sizeof(spec->multiout.extra_out_nid));
- spec->multi_ios = 0;
- clear_vol_marks(codec);
- badness = 0;
-
- /* fill hard-wired DACs first */
- if (fill_hardwired) {
- bool mapped;
- do {
- mapped = alc_map_singles(codec, cfg->line_outs,
- cfg->line_out_pins,
- spec->private_dac_nids);
- mapped |= alc_map_singles(codec, cfg->hp_outs,
- cfg->hp_pins,
- spec->multiout.hp_out_nid);
- mapped |= alc_map_singles(codec, cfg->speaker_outs,
- cfg->speaker_pins,
- spec->multiout.extra_out_nid);
- if (fill_mio_first && cfg->line_outs == 1 &&
- cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
- err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], true, 0);
- if (!err)
- mapped = true;
- }
- } while (mapped);
- }
-
- badness += alc_auto_fill_dacs(codec, cfg->line_outs, cfg->line_out_pins,
- spec->private_dac_nids,
- &main_out_badness);
-
- /* re-count num_dacs and squash invalid entries */
- spec->multiout.num_dacs = 0;
- for (i = 0; i < cfg->line_outs; i++) {
- if (spec->private_dac_nids[i])
- spec->multiout.num_dacs++;
- else {
- memmove(spec->private_dac_nids + i,
- spec->private_dac_nids + i + 1,
- sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
- spec->private_dac_nids[cfg->line_outs - 1] = 0;
- }
- }
-
- if (fill_mio_first &&
- cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
- /* try to fill multi-io first */
- err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], false, 0);
- if (err < 0)
- return err;
- /* we don't count badness at this stage yet */
- }
-
- if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
- err = alc_auto_fill_dacs(codec, cfg->hp_outs, cfg->hp_pins,
- spec->multiout.hp_out_nid,
- &extra_out_badness);
- if (err < 0)
- return err;
- badness += err;
- }
- if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
- err = alc_auto_fill_dacs(codec, cfg->speaker_outs,
- cfg->speaker_pins,
- spec->multiout.extra_out_nid,
- &extra_out_badness);
- if (err < 0)
- return err;
- badness += err;
- }
- if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
- err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], false, 0);
- if (err < 0)
- return err;
- badness += err;
- }
- if (cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
- /* try multi-ios with HP + inputs */
- int offset = 0;
- if (cfg->line_outs >= 3)
- offset = 1;
- err = alc_auto_fill_multi_ios(codec, cfg->hp_pins[0], false,
- offset);
- if (err < 0)
- return err;
- badness += err;
- }
-
- if (spec->multi_ios == 2) {
- for (i = 0; i < 2; i++)
- spec->private_dac_nids[spec->multiout.num_dacs++] =
- spec->multi_io[i].dac;
- spec->ext_channel_count = 2;
- } else if (spec->multi_ios) {
- spec->multi_ios = 0;
- badness += BAD_MULTI_IO;
- }
-
- return badness;
-}
-
-#define DEBUG_BADNESS
-
-#ifdef DEBUG_BADNESS
-#define debug_badness snd_printdd
-#else
-#define debug_badness(...)
-#endif
-
-static void debug_show_configs(struct alc_spec *spec, struct auto_pin_cfg *cfg)
-{
- debug_badness("multi_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
- cfg->line_out_pins[0], cfg->line_out_pins[1],
- cfg->line_out_pins[2], cfg->line_out_pins[2],
- spec->multiout.dac_nids[0],
- spec->multiout.dac_nids[1],
- spec->multiout.dac_nids[2],
- spec->multiout.dac_nids[3]);
- if (spec->multi_ios > 0)
- debug_badness("multi_ios(%d) = %x/%x : %x/%x\n",
- spec->multi_ios,
- spec->multi_io[0].pin, spec->multi_io[1].pin,
- spec->multi_io[0].dac, spec->multi_io[1].dac);
- debug_badness("hp_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
- cfg->hp_pins[0], cfg->hp_pins[1],
- cfg->hp_pins[2], cfg->hp_pins[2],
- spec->multiout.hp_out_nid[0],
- spec->multiout.hp_out_nid[1],
- spec->multiout.hp_out_nid[2],
- spec->multiout.hp_out_nid[3]);
- debug_badness("spk_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
- cfg->speaker_pins[0], cfg->speaker_pins[1],
- cfg->speaker_pins[2], cfg->speaker_pins[3],
- spec->multiout.extra_out_nid[0],
- spec->multiout.extra_out_nid[1],
- spec->multiout.extra_out_nid[2],
- spec->multiout.extra_out_nid[3]);
-}
-
-static int alc_auto_fill_dac_nids(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- struct auto_pin_cfg *best_cfg;
- int best_badness = INT_MAX;
- int badness;
- bool fill_hardwired = true, fill_mio_first = true;
- bool best_wired = true, best_mio = true;
- bool hp_spk_swapped = false;
-
- best_cfg = kmalloc(sizeof(*best_cfg), GFP_KERNEL);
- if (!best_cfg)
- return -ENOMEM;
- *best_cfg = *cfg;
-
- for (;;) {
- badness = fill_and_eval_dacs(codec, fill_hardwired,
- fill_mio_first);
- if (badness < 0) {
- kfree(best_cfg);
- return badness;
- }
- debug_badness("==> lo_type=%d, wired=%d, mio=%d, badness=0x%x\n",
- cfg->line_out_type, fill_hardwired, fill_mio_first,
- badness);
- debug_show_configs(spec, cfg);
- if (badness < best_badness) {
- best_badness = badness;
- *best_cfg = *cfg;
- best_wired = fill_hardwired;
- best_mio = fill_mio_first;
- }
- if (!badness)
- break;
- fill_mio_first = !fill_mio_first;
- if (!fill_mio_first)
- continue;
- fill_hardwired = !fill_hardwired;
- if (!fill_hardwired)
- continue;
- if (hp_spk_swapped)
- break;
- hp_spk_swapped = true;
- if (cfg->speaker_outs > 0 &&
- cfg->line_out_type == AUTO_PIN_HP_OUT) {
- cfg->hp_outs = cfg->line_outs;
- memcpy(cfg->hp_pins, cfg->line_out_pins,
- sizeof(cfg->hp_pins));
- cfg->line_outs = cfg->speaker_outs;
- memcpy(cfg->line_out_pins, cfg->speaker_pins,
- sizeof(cfg->speaker_pins));
- cfg->speaker_outs = 0;
- memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
- cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
- fill_hardwired = true;
- continue;
- }
- if (cfg->hp_outs > 0 &&
- cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
- cfg->speaker_outs = cfg->line_outs;
- memcpy(cfg->speaker_pins, cfg->line_out_pins,
- sizeof(cfg->speaker_pins));
- cfg->line_outs = cfg->hp_outs;
- memcpy(cfg->line_out_pins, cfg->hp_pins,
- sizeof(cfg->hp_pins));
- cfg->hp_outs = 0;
- memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
- cfg->line_out_type = AUTO_PIN_HP_OUT;
- fill_hardwired = true;
- continue;
- }
- break;
- }
-
- if (badness) {
- *cfg = *best_cfg;
- fill_and_eval_dacs(codec, best_wired, best_mio);
- }
- debug_badness("==> Best config: lo_type=%d, wired=%d, mio=%d\n",
- cfg->line_out_type, best_wired, best_mio);
- debug_show_configs(spec, cfg);
-
- if (cfg->line_out_pins[0])
- spec->vmaster_nid =
- alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0],
- spec->multiout.dac_nids[0]);
-
- /* clear the bitmap flags for creating controls */
- clear_vol_marks(codec);
- kfree(best_cfg);
- return 0;
-}
-
-static int alc_auto_add_vol_ctl(struct hda_codec *codec,
- const char *pfx, int cidx,
- hda_nid_t nid, unsigned int chs)
-{
- struct alc_spec *spec = codec->spec;
- unsigned int val;
- if (!nid)
- return 0;
- val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
- if (is_ctl_used(spec->vol_ctls, val) && chs != 2) /* exclude LFE */
- return 0;
- mark_ctl_usage(spec->vol_ctls, val);
- return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx,
- val);
-}
-
-static int alc_auto_add_stereo_vol(struct hda_codec *codec,
- const char *pfx, int cidx,
- hda_nid_t nid)
-{
- int chs = 1;
- if (get_wcaps(codec, nid) & AC_WCAP_STEREO)
- chs = 3;
- return alc_auto_add_vol_ctl(codec, pfx, cidx, nid, chs);
-}
-
-/* create a mute-switch for the given mixer widget;
- * if it has multiple sources (e.g. DAC and loopback), create a bind-mute
- */
-static int alc_auto_add_sw_ctl(struct hda_codec *codec,
- const char *pfx, int cidx,
- hda_nid_t nid, unsigned int chs)
-{
- struct alc_spec *spec = codec->spec;
- int wid_type;
- int type;
- unsigned long val;
- if (!nid)
- return 0;
- wid_type = get_wcaps_type(get_wcaps(codec, nid));
- if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT) {
- type = ALC_CTL_WIDGET_MUTE;
- val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
- } else if (snd_hda_get_conn_list(codec, nid, NULL) == 1) {
- type = ALC_CTL_WIDGET_MUTE;
- val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT);
- } else {
- type = ALC_CTL_BIND_MUTE;
- val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT);
- }
- if (is_ctl_used(spec->sw_ctls, val) && chs != 2) /* exclude LFE */
- return 0;
- mark_ctl_usage(spec->sw_ctls, val);
- return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val);
-}
-
-static int alc_auto_add_stereo_sw(struct hda_codec *codec, const char *pfx,
- int cidx, hda_nid_t nid)
-{
- int chs = 1;
- if (get_wcaps(codec, nid) & AC_WCAP_STEREO)
- chs = 3;
- return alc_auto_add_sw_ctl(codec, pfx, cidx, nid, chs);
-}
-
-static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec,
- hda_nid_t pin, hda_nid_t dac)
-{
- hda_nid_t mix = alc_auto_dac_to_mix(codec, pin, dac);
- if (nid_has_mute(codec, pin, HDA_OUTPUT))
- return pin;
- else if (mix && nid_has_mute(codec, mix, HDA_INPUT))
- return mix;
- else if (nid_has_mute(codec, dac, HDA_OUTPUT))
- return dac;
- return 0;
-}
-
-static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
- hda_nid_t pin, hda_nid_t dac)
-{
- hda_nid_t mix = alc_auto_dac_to_mix(codec, pin, dac);
- if (nid_has_volume(codec, dac, HDA_OUTPUT))
- return dac;
- else if (nid_has_volume(codec, mix, HDA_OUTPUT))
- return mix;
- else if (nid_has_volume(codec, pin, HDA_OUTPUT))
- return pin;
- return 0;
-}
-
-/* add playback controls from the parsed DAC table */
-static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
- const struct auto_pin_cfg *cfg)
-{
- struct alc_spec *spec = codec->spec;
- int i, err, noutputs;
-
- noutputs = cfg->line_outs;
- if (spec->multi_ios > 0 && cfg->line_outs < 3)
- noutputs += spec->multi_ios;
-
- for (i = 0; i < noutputs; i++) {
- const char *name;
- int index;
- hda_nid_t dac, pin;
- hda_nid_t sw, vol;
-
- dac = spec->multiout.dac_nids[i];
- if (!dac)
- continue;
- if (i >= cfg->line_outs) {
- pin = spec->multi_io[i - 1].pin;
- index = 0;
- name = channel_name[i];
- } else {
- pin = cfg->line_out_pins[i];
- name = alc_get_line_out_pfx(spec, i, true, &index);
- }
-
- sw = alc_look_for_out_mute_nid(codec, pin, dac);
- vol = alc_look_for_out_vol_nid(codec, pin, dac);
- if (!name || !strcmp(name, "CLFE")) {
- /* Center/LFE */
- err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1);
- if (err < 0)
- return err;
- err = alc_auto_add_vol_ctl(codec, "LFE", 0, vol, 2);
- if (err < 0)
- return err;
- err = alc_auto_add_sw_ctl(codec, "Center", 0, sw, 1);
- if (err < 0)
- return err;
- err = alc_auto_add_sw_ctl(codec, "LFE", 0, sw, 2);
- if (err < 0)
- return err;
- } else {
- err = alc_auto_add_stereo_vol(codec, name, index, vol);
- if (err < 0)
- return err;
- err = alc_auto_add_stereo_sw(codec, name, index, sw);
- if (err < 0)
- return err;
- }
- }
- return 0;
-}
-
-static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
- hda_nid_t dac, const char *pfx,
- int cidx)
-{
- struct alc_spec *spec = codec->spec;
- hda_nid_t sw, vol;
- int err;
-
- if (!dac) {
- unsigned int val;
- /* the corresponding DAC is already occupied */
- if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
- return 0; /* no way */
- /* create a switch only */
- val = HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT);
- if (is_ctl_used(spec->sw_ctls, val))
- return 0; /* already created */
- mark_ctl_usage(spec->sw_ctls, val);
- return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, cidx, val);
- }
-
- sw = alc_look_for_out_mute_nid(codec, pin, dac);
- vol = alc_look_for_out_vol_nid(codec, pin, dac);
- err = alc_auto_add_stereo_vol(codec, pfx, cidx, vol);
- if (err < 0)
- return err;
- err = alc_auto_add_stereo_sw(codec, pfx, cidx, sw);
- if (err < 0)
- return err;
- return 0;
-}
-
-static struct hda_bind_ctls *new_bind_ctl(struct hda_codec *codec,
- unsigned int nums,
- struct hda_ctl_ops *ops)
-{
- struct alc_spec *spec = codec->spec;
- struct hda_bind_ctls **ctlp, *ctl;
- snd_array_init(&spec->bind_ctls, sizeof(ctl), 8);
- ctlp = snd_array_new(&spec->bind_ctls);
- if (!ctlp)
- return NULL;
- ctl = kzalloc(sizeof(*ctl) + sizeof(long) * (nums + 1), GFP_KERNEL);
- *ctlp = ctl;
- if (ctl)
- ctl->ops = ops;
- return ctl;
-}
-
-/* add playback controls for speaker and HP outputs */
-static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins,
- const hda_nid_t *pins,
- const hda_nid_t *dacs,
- const char *pfx)
-{
- struct alc_spec *spec = codec->spec;
- struct hda_bind_ctls *ctl;
- char name[32];
- int i, n, err;
-
- if (!num_pins || !pins[0])
- return 0;
-
- if (num_pins == 1) {
- hda_nid_t dac = *dacs;
- if (!dac)
- dac = spec->multiout.dac_nids[0];
- return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0);
- }
-
- for (i = 0; i < num_pins; i++) {
- hda_nid_t dac;
- if (dacs[num_pins - 1])
- dac = dacs[i]; /* with individual volumes */
- else
- dac = 0;
- if (num_pins == 2 && i == 1 && !strcmp(pfx, "Speaker")) {
- err = alc_auto_create_extra_out(codec, pins[i], dac,
- "Bass Speaker", 0);
- } else if (num_pins >= 3) {
- snprintf(name, sizeof(name), "%s %s",
- pfx, channel_name[i]);
- err = alc_auto_create_extra_out(codec, pins[i], dac,
- name, 0);
- } else {
- err = alc_auto_create_extra_out(codec, pins[i], dac,
- pfx, i);
- }
- if (err < 0)
- return err;
- }
- if (dacs[num_pins - 1])
- return 0;
-
- /* Let's create a bind-controls for volumes */
- ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_vol);
- if (!ctl)
- return -ENOMEM;
- n = 0;
- for (i = 0; i < num_pins; i++) {
- hda_nid_t vol;
- if (!pins[i] || !dacs[i])
- continue;
- vol = alc_look_for_out_vol_nid(codec, pins[i], dacs[i]);
- if (vol)
- ctl->values[n++] =
- HDA_COMPOSE_AMP_VAL(vol, 3, 0, HDA_OUTPUT);
- }
- if (n) {
- snprintf(name, sizeof(name), "%s Playback Volume", pfx);
- err = add_control(spec, ALC_CTL_BIND_VOL, name, 0, (long)ctl);
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-static int alc_auto_create_hp_out(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- return alc_auto_create_extra_outs(codec, spec->autocfg.hp_outs,
- spec->autocfg.hp_pins,
- spec->multiout.hp_out_nid,
- "Headphone");
-}
-
-static int alc_auto_create_speaker_out(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- return alc_auto_create_extra_outs(codec, spec->autocfg.speaker_outs,
- spec->autocfg.speaker_pins,
- spec->multiout.extra_out_nid,
- "Speaker");
-}
-
-static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
- hda_nid_t pin, int pin_type,
- hda_nid_t dac)
-{
- int i, num;
- hda_nid_t nid, mix = 0;
- hda_nid_t srcs[HDA_MAX_CONNECTIONS];
-
- alc_set_pin_output(codec, pin, pin_type);
- nid = alc_go_down_to_selector(codec, pin);
- num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
- for (i = 0; i < num; i++) {
- if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
- continue;
- mix = srcs[i];
- break;
- }
- if (!mix)
- return;
-
- /* need the manual connection? */
- if (num > 1)
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
- /* unmute mixer widget inputs */
- if (nid_has_mute(codec, mix, HDA_INPUT)) {
- snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_IN_UNMUTE(0));
- snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_IN_UNMUTE(1));
- }
- /* initialize volume */
- nid = alc_look_for_out_vol_nid(codec, pin, dac);
- if (nid)
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_OUT_ZERO);
-
- /* unmute DAC if it's not assigned to a mixer */
- nid = alc_look_for_out_mute_nid(codec, pin, dac);
- if (nid == mix && nid_has_mute(codec, dac, HDA_OUTPUT))
- snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_OUT_ZERO);
-}
-
-static void alc_auto_init_multi_out(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- int pin_type = get_pin_type(spec->autocfg.line_out_type);
- int i;
-
- for (i = 0; i <= HDA_SIDE; i++) {
- hda_nid_t nid = spec->autocfg.line_out_pins[i];
- if (nid)
- alc_auto_set_output_and_unmute(codec, nid, pin_type,
- spec->multiout.dac_nids[i]);
- }
-}
-
-static void alc_auto_init_extra_out(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- int i;
- hda_nid_t pin, dac;
-
- for (i = 0; i < spec->autocfg.hp_outs; i++) {
- if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)
- break;
- pin = spec->autocfg.hp_pins[i];
- if (!pin)
- break;
- dac = spec->multiout.hp_out_nid[i];
- if (!dac) {
- if (i > 0 && spec->multiout.hp_out_nid[0])
- dac = spec->multiout.hp_out_nid[0];
- else
- dac = spec->multiout.dac_nids[0];
- }
- alc_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
- }
- for (i = 0; i < spec->autocfg.speaker_outs; i++) {
- if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
- break;
- pin = spec->autocfg.speaker_pins[i];
- if (!pin)
- break;
- dac = spec->multiout.extra_out_nid[i];
- if (!dac) {
- if (i > 0 && spec->multiout.extra_out_nid[0])
- dac = spec->multiout.extra_out_nid[0];
- else
- dac = spec->multiout.dac_nids[0];
- }
- alc_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
- }
-}
-
-/* check whether the given pin can be a multi-io pin */
-static bool can_be_multiio_pin(struct hda_codec *codec,
- unsigned int location, hda_nid_t nid)
-{
- unsigned int defcfg, caps;
-
- defcfg = snd_hda_codec_get_pincfg(codec, nid);
- if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
- return false;
- if (location && get_defcfg_location(defcfg) != location)
- return false;
- caps = snd_hda_query_pin_caps(codec, nid);
- if (!(caps & AC_PINCAP_OUT))
- return false;
- return true;
-}
-
-/*
- * multi-io helper
- *
- * When hardwired is set, try to fill ony hardwired pins, and returns
- * zero if any pins are filled, non-zero if nothing found.
- * When hardwired is off, try to fill possible input pins, and returns
- * the badness value.
- */
-static int alc_auto_fill_multi_ios(struct hda_codec *codec,
- hda_nid_t reference_pin,
- bool hardwired, int offset)
-{
- struct alc_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int type, i, j, dacs, num_pins, old_pins;
- unsigned int defcfg = snd_hda_codec_get_pincfg(codec, reference_pin);
- unsigned int location = get_defcfg_location(defcfg);
- int badness = 0;
-
- old_pins = spec->multi_ios;
- if (old_pins >= 2)
- goto end_fill;
-
- num_pins = 0;
- for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
- for (i = 0; i < cfg->num_inputs; i++) {
- if (cfg->inputs[i].type != type)
- continue;
- if (can_be_multiio_pin(codec, location,
- cfg->inputs[i].pin))
- num_pins++;
- }
- }
- if (num_pins < 2)
- goto end_fill;
-
- dacs = spec->multiout.num_dacs;
- for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
- for (i = 0; i < cfg->num_inputs; i++) {
- hda_nid_t nid = cfg->inputs[i].pin;
- hda_nid_t dac = 0;
-
- if (cfg->inputs[i].type != type)
- continue;
- if (!can_be_multiio_pin(codec, location, nid))
- continue;
- for (j = 0; j < spec->multi_ios; j++) {
- if (nid == spec->multi_io[j].pin)
- break;
- }
- if (j < spec->multi_ios)
- continue;
-
- if (offset && offset + spec->multi_ios < dacs) {
- dac = spec->private_dac_nids[offset + spec->multi_ios];
- if (!alc_auto_is_dac_reachable(codec, nid, dac))
- dac = 0;
- }
- if (hardwired)
- dac = get_dac_if_single(codec, nid);
- else if (!dac)
- dac = alc_auto_look_for_dac(codec, nid);
- if (!dac) {
- badness++;
- continue;
- }
- spec->multi_io[spec->multi_ios].pin = nid;
- spec->multi_io[spec->multi_ios].dac = dac;
- spec->multi_ios++;
- if (spec->multi_ios >= 2)
- break;
- }
- }
- end_fill:
- if (badness)
- badness = BAD_MULTI_IO;
- if (old_pins == spec->multi_ios) {
- if (hardwired)
- return 1; /* nothing found */
- else
- return badness; /* no badness if nothing found */
- }
- if (!hardwired && spec->multi_ios < 2) {
- spec->multi_ios = old_pins;
- return badness;
- }
-
- return 0;
-}
-
-static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = spec->multi_ios + 1;
- if (uinfo->value.enumerated.item > spec->multi_ios)
- uinfo->value.enumerated.item = spec->multi_ios;
- sprintf(uinfo->value.enumerated.name, "%dch",
- (uinfo->value.enumerated.item + 1) * 2);
- return 0;
-}
-
-static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
- ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
- return 0;
-}
-
-static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
-{
- struct alc_spec *spec = codec->spec;
- hda_nid_t nid = spec->multi_io[idx].pin;
-
- if (!spec->multi_io[idx].ctl_in)
- spec->multi_io[idx].ctl_in =
- snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
- if (output) {
- snd_hda_codec_update_cache(codec, nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- PIN_OUT);
- if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
- snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, 0);
- alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
- } else {
- if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
- snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, HDA_AMP_MUTE);
- snd_hda_codec_update_cache(codec, nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- spec->multi_io[idx].ctl_in);
- }
- return 0;
-}
-
-static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
- int i, ch;
-
- ch = ucontrol->value.enumerated.item[0];
- if (ch < 0 || ch > spec->multi_ios)
- return -EINVAL;
- if (ch == (spec->ext_channel_count - 1) / 2)
- return 0;
- spec->ext_channel_count = (ch + 1) * 2;
- for (i = 0; i < spec->multi_ios; i++)
- alc_set_multi_io(codec, i, i < ch);
- spec->multiout.max_channels = spec->ext_channel_count;
- if (spec->need_dac_fix && !spec->const_channel_count)
- spec->multiout.num_dacs = spec->multiout.max_channels / 2;
- return 1;
-}
-
-static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Channel Mode",
- .info = alc_auto_ch_mode_info,
- .get = alc_auto_ch_mode_get,
- .put = alc_auto_ch_mode_put,
-};
-
-static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- if (spec->multi_ios > 0) {
- struct snd_kcontrol_new *knew;
-
- knew = alc_kcontrol_new(spec);
- if (!knew)
- return -ENOMEM;
- *knew = alc_auto_channel_mode_enum;
- knew->name = kstrdup("Channel Mode", GFP_KERNEL);
- if (!knew->name)
- return -ENOMEM;
- }
- return 0;
-}
-
-/* filter out invalid adc_nids (and capsrc_nids) that don't give all
- * active input pins
- */
-static void alc_remove_invalid_adc_nids(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- const struct hda_input_mux *imux;
- hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)];
- hda_nid_t capsrc_nids[ARRAY_SIZE(spec->private_adc_nids)];
- int i, n, nums;
-
- imux = spec->input_mux;
- if (!imux)
- return;
- if (spec->dyn_adc_switch)
- return;
-
- again:
- nums = 0;
- for (n = 0; n < spec->num_adc_nids; n++) {
- hda_nid_t cap = spec->private_capsrc_nids[n];
- int num_conns = snd_hda_get_conn_list(codec, cap, NULL);
- for (i = 0; i < imux->num_items; i++) {
- hda_nid_t pin = spec->imux_pins[i];
- if (pin) {
- if (get_connection_index(codec, cap, pin) < 0)
- break;
- } else if (num_conns <= imux->items[i].index)
- break;
- }
- if (i >= imux->num_items) {
- adc_nids[nums] = spec->private_adc_nids[n];
- capsrc_nids[nums++] = cap;
- }
- }
- if (!nums) {
- /* check whether ADC-switch is possible */
- if (!alc_check_dyn_adc_switch(codec)) {
- if (spec->shared_mic_hp) {
- spec->shared_mic_hp = 0;
- spec->private_imux[0].num_items = 1;
- goto again;
- }
- printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
- " using fallback 0x%x\n",
- codec->chip_name, spec->private_adc_nids[0]);
- spec->num_adc_nids = 1;
- spec->auto_mic = 0;
- return;
- }
- } else if (nums != spec->num_adc_nids) {
- memcpy(spec->private_adc_nids, adc_nids,
- nums * sizeof(hda_nid_t));
- memcpy(spec->private_capsrc_nids, capsrc_nids,
- nums * sizeof(hda_nid_t));
- spec->num_adc_nids = nums;
- }
-
- if (spec->auto_mic)
- alc_auto_mic_check_imux(codec); /* check auto-mic setups */
- else if (spec->input_mux->num_items == 1 || spec->shared_mic_hp)
- spec->num_adc_nids = 1; /* reduce to a single ADC */
-}
-
-/*
- * initialize ADC paths
- */
-static void alc_auto_init_adc(struct hda_codec *codec, int adc_idx)
-{
- struct alc_spec *spec = codec->spec;
- hda_nid_t nid;
-
- nid = spec->adc_nids[adc_idx];
- /* mute ADC */
- if (nid_has_mute(codec, nid, HDA_INPUT)) {
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_IN_MUTE(0));
- return;
- }
- if (!spec->capsrc_nids)
- return;
- nid = spec->capsrc_nids[adc_idx];
- if (nid_has_mute(codec, nid, HDA_OUTPUT))
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_OUT_MUTE);
-}
-
-static void alc_auto_init_input_src(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- int c, nums;
-
- for (c = 0; c < spec->num_adc_nids; c++)
- alc_auto_init_adc(codec, c);
- if (spec->dyn_adc_switch)
- nums = 1;
- else
- nums = spec->num_adc_nids;
- for (c = 0; c < nums; c++)
- alc_mux_select(codec, c, spec->cur_mux[c], true);
-}
-
-/* add mic boosts if needed */
-static int alc_auto_add_mic_boost(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i, err;
- int type_idx = 0;
- hda_nid_t nid;
- const char *prev_label = NULL;
-
- for (i = 0; i < cfg->num_inputs; i++) {
- if (cfg->inputs[i].type > AUTO_PIN_MIC)
- break;
- nid = cfg->inputs[i].pin;
- if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
- const char *label;
- char boost_label[32];
-
- label = hda_get_autocfg_input_label(codec, cfg, i);
- if (spec->shared_mic_hp && !strcmp(label, "Misc"))
- label = "Headphone Mic";
- if (prev_label && !strcmp(label, prev_label))
- type_idx++;
- else
- type_idx = 0;
- prev_label = label;
-
- snprintf(boost_label, sizeof(boost_label),
- "%s Boost Volume", label);
- err = add_control(spec, ALC_CTL_WIDGET_VOL,
- boost_label, type_idx,
- HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
- if (err < 0)
- return err;
- }
- }
- return 0;
-}
-
-/* select or unmute the given capsrc route */
-static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
- int idx)
-{
- if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
- snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
- HDA_AMP_MUTE, 0);
- } else if (snd_hda_get_conn_list(codec, cap, NULL) > 1) {
- snd_hda_codec_write_cache(codec, cap, 0,
- AC_VERB_SET_CONNECT_SEL, idx);
- }
-}
-
-/* set the default connection to that pin */
-static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
-{
- struct alc_spec *spec = codec->spec;
- int i;
-
- if (!pin)
- return 0;
- for (i = 0; i < spec->num_adc_nids; i++) {
- hda_nid_t cap = get_capsrc(spec, i);
- int idx;
-
- idx = get_connection_index(codec, cap, pin);
- if (idx < 0)
- continue;
- select_or_unmute_capsrc(codec, cap, idx);
- return i; /* return the found index */
- }
- return -1; /* not found */
-}
-
-/* initialize some special cases for input sources */
-static void alc_init_special_input_src(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- int i;
-
- for (i = 0; i < spec->autocfg.num_inputs; i++)
- init_capsrc_for_pin(codec, spec->autocfg.inputs[i].pin);
-}
-
-/* assign appropriate capture mixers */
-static void set_capture_mixer(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- static const struct snd_kcontrol_new *caps[2][3] = {
- { alc_capture_mixer_nosrc1,
- alc_capture_mixer_nosrc2,
- alc_capture_mixer_nosrc3 },
- { alc_capture_mixer1,
- alc_capture_mixer2,
- alc_capture_mixer3 },
- };
-
- /* check whether either of ADC or MUX has a volume control */
- if (!nid_has_volume(codec, spec->adc_nids[0], HDA_INPUT)) {
- if (!spec->capsrc_nids)
- return; /* no volume */
- if (!nid_has_volume(codec, spec->capsrc_nids[0], HDA_OUTPUT))
- return; /* no volume in capsrc, too */
- spec->vol_in_capsrc = 1;
- }
-
- if (spec->num_adc_nids > 0) {
- int mux = 0;
- int num_adcs = 0;
-
- if (spec->input_mux && spec->input_mux->num_items > 1)
- mux = 1;
- if (spec->auto_mic) {
- num_adcs = 1;
- mux = 0;
- } else if (spec->dyn_adc_switch)
- num_adcs = 1;
- if (!num_adcs) {
- if (spec->num_adc_nids > 3)
- spec->num_adc_nids = 3;
- else if (!spec->num_adc_nids)
- return;
- num_adcs = spec->num_adc_nids;
- }
- spec->cap_mixer = caps[mux][num_adcs - 1];
- }
-}
-
-/*
- * standard auto-parser initializations
- */
-static void alc_auto_init_std(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- alc_auto_init_multi_out(codec);
- alc_auto_init_extra_out(codec);
- alc_auto_init_analog_input(codec);
- alc_auto_init_input_src(codec);
- alc_auto_init_digital(codec);
- if (spec->unsol_event)
- alc_inithook(codec);
-}
-
-/*
- * Digital-beep handlers
- */
-#ifdef CONFIG_SND_HDA_INPUT_BEEP
-#define set_beep_amp(spec, nid, idx, dir) \
- ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
-
-static const struct snd_pci_quirk beep_white_list[] = {
- SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
- SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
- SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
- SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
- SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
- SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
- {}
-};
-
-static inline int has_cdefine_beep(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- const struct snd_pci_quirk *q;
- q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
- if (q)
- return q->value;
- return spec->cdefine.enable_pcbeep;
-}
-#else
-#define set_beep_amp(spec, nid, idx, dir) /* NOP */
-#define has_cdefine_beep(codec) 0
-#endif
-
-/* parse the BIOS configuration and set up the alc_spec */
-/* return 1 if successful, 0 if the proper config is not found,
- * or a negative error code
- */
-static int alc_parse_auto_config(struct hda_codec *codec,
- const hda_nid_t *ignore_nids,
- const hda_nid_t *ssid_nids)
-{
- struct alc_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int err;
-
- err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
- spec->parse_flags);
- if (err < 0)
- return err;
- if (!cfg->line_outs) {
- if (cfg->dig_outs || cfg->dig_in_pin) {
- spec->multiout.max_channels = 2;
- spec->no_analog = 1;
- goto dig_only;
- }
- return 0; /* can't find valid BIOS pin config */
- }
-
- if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT &&
- cfg->line_outs <= cfg->hp_outs) {
- /* use HP as primary out */
- cfg->speaker_outs = cfg->line_outs;
- memcpy(cfg->speaker_pins, cfg->line_out_pins,
- sizeof(cfg->speaker_pins));
- cfg->line_outs = cfg->hp_outs;
- memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
- cfg->hp_outs = 0;
- memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
- cfg->line_out_type = AUTO_PIN_HP_OUT;
- }
-
- err = alc_auto_fill_dac_nids(codec);
- if (err < 0)
- return err;
- err = alc_auto_add_multi_channel_mode(codec);
- if (err < 0)
- return err;
- err = alc_auto_create_multi_out_ctls(codec, cfg);
- if (err < 0)
- return err;
- err = alc_auto_create_hp_out(codec);
- if (err < 0)
- return err;
- err = alc_auto_create_speaker_out(codec);
- if (err < 0)
- return err;
- err = alc_auto_create_shared_input(codec);
- if (err < 0)
- return err;
- err = alc_auto_create_input_ctls(codec);
- if (err < 0)
- return err;
-
- spec->multiout.max_channels = spec->multiout.num_dacs * 2;
-
- dig_only:
- alc_auto_parse_digital(codec);
-
- if (!spec->no_analog)
- alc_remove_invalid_adc_nids(codec);
-
- if (ssid_nids)
- alc_ssid_check(codec, ssid_nids);
-
- if (!spec->no_analog) {
- alc_auto_check_switches(codec);
- err = alc_auto_add_mic_boost(codec);
- if (err < 0)
- return err;
- }
-
- if (spec->kctls.list)
- add_mixer(spec, spec->kctls.list);
-
- if (!spec->no_analog && !spec->cap_mixer)
- set_capture_mixer(codec);
-
- return 1;
-}
-
-static int alc880_parse_auto_config(struct hda_codec *codec)
-{
- static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
- static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
- return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
-}
-
-/*
- * ALC880 fix-ups
- */
-enum {
- ALC880_FIXUP_GPIO1,
- ALC880_FIXUP_GPIO2,
- ALC880_FIXUP_MEDION_RIM,
- ALC880_FIXUP_LG,
- ALC880_FIXUP_W810,
- ALC880_FIXUP_EAPD_COEF,
- ALC880_FIXUP_TCL_S700,
- ALC880_FIXUP_VOL_KNOB,
- ALC880_FIXUP_FUJITSU,
- ALC880_FIXUP_F1734,
- ALC880_FIXUP_UNIWILL,
- ALC880_FIXUP_UNIWILL_DIG,
- ALC880_FIXUP_Z71V,
- ALC880_FIXUP_3ST_BASE,
- ALC880_FIXUP_3ST,
- ALC880_FIXUP_3ST_DIG,
- ALC880_FIXUP_5ST_BASE,
- ALC880_FIXUP_5ST,
- ALC880_FIXUP_5ST_DIG,
- ALC880_FIXUP_6ST_BASE,
- ALC880_FIXUP_6ST,
- ALC880_FIXUP_6ST_DIG,
-};
-
-/* enable the volume-knob widget support on NID 0x21 */
-static void alc880_fixup_vol_knob(struct hda_codec *codec,
- const struct alc_fixup *fix, int action)
-{
- if (action == ALC_FIXUP_ACT_PROBE)
- snd_hda_jack_detect_enable(codec, 0x21, ALC_DCVOL_EVENT);
-}
-
-static const struct alc_fixup alc880_fixups[] = {
- [ALC880_FIXUP_GPIO1] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = alc_gpio1_init_verbs,
- },
- [ALC880_FIXUP_GPIO2] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = alc_gpio2_init_verbs,
- },
- [ALC880_FIXUP_MEDION_RIM] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = (const struct hda_verb[]) {
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
- { }
- },
- .chained = true,
- .chain_id = ALC880_FIXUP_GPIO2,
- },
- [ALC880_FIXUP_LG] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- /* disable bogus unused pins */
- { 0x16, 0x411111f0 },
- { 0x18, 0x411111f0 },
- { 0x1a, 0x411111f0 },
- { }
- }
- },
- [ALC880_FIXUP_W810] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- /* disable bogus unused pins */
- { 0x17, 0x411111f0 },
- { }
- },
- .chained = true,
- .chain_id = ALC880_FIXUP_GPIO2,
- },
- [ALC880_FIXUP_EAPD_COEF] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = (const struct hda_verb[]) {
- /* change to EAPD mode */
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
- {}
- },
- },
- [ALC880_FIXUP_TCL_S700] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = (const struct hda_verb[]) {
- /* change to EAPD mode */
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
- {}
- },
- .chained = true,
- .chain_id = ALC880_FIXUP_GPIO2,
- },
- [ALC880_FIXUP_VOL_KNOB] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc880_fixup_vol_knob,
- },
- [ALC880_FIXUP_FUJITSU] = {
- /* override all pins as BIOS on old Amilo is broken */
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x14, 0x0121411f }, /* HP */
- { 0x15, 0x99030120 }, /* speaker */
- { 0x16, 0x99030130 }, /* bass speaker */
- { 0x17, 0x411111f0 }, /* N/A */
- { 0x18, 0x411111f0 }, /* N/A */
- { 0x19, 0x01a19950 }, /* mic-in */
- { 0x1a, 0x411111f0 }, /* N/A */
- { 0x1b, 0x411111f0 }, /* N/A */
- { 0x1c, 0x411111f0 }, /* N/A */
- { 0x1d, 0x411111f0 }, /* N/A */
- { 0x1e, 0x01454140 }, /* SPDIF out */
- { }
- },
- .chained = true,
- .chain_id = ALC880_FIXUP_VOL_KNOB,
- },
- [ALC880_FIXUP_F1734] = {
- /* almost compatible with FUJITSU, but no bass and SPDIF */
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x14, 0x0121411f }, /* HP */
- { 0x15, 0x99030120 }, /* speaker */
- { 0x16, 0x411111f0 }, /* N/A */
- { 0x17, 0x411111f0 }, /* N/A */
- { 0x18, 0x411111f0 }, /* N/A */
- { 0x19, 0x01a19950 }, /* mic-in */
- { 0x1a, 0x411111f0 }, /* N/A */
- { 0x1b, 0x411111f0 }, /* N/A */
- { 0x1c, 0x411111f0 }, /* N/A */
- { 0x1d, 0x411111f0 }, /* N/A */
- { 0x1e, 0x411111f0 }, /* N/A */
- { }
- },
- .chained = true,
- .chain_id = ALC880_FIXUP_VOL_KNOB,
- },
- [ALC880_FIXUP_UNIWILL] = {
- /* need to fix HP and speaker pins to be parsed correctly */
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x14, 0x0121411f }, /* HP */
- { 0x15, 0x99030120 }, /* speaker */
- { 0x16, 0x99030130 }, /* bass speaker */
- { }
- },
- },
- [ALC880_FIXUP_UNIWILL_DIG] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- /* disable bogus unused pins */
- { 0x17, 0x411111f0 },
- { 0x19, 0x411111f0 },
- { 0x1b, 0x411111f0 },
- { 0x1f, 0x411111f0 },
- { }
- }
- },
- [ALC880_FIXUP_Z71V] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- /* set up the whole pins as BIOS is utterly broken */
- { 0x14, 0x99030120 }, /* speaker */
- { 0x15, 0x0121411f }, /* HP */
- { 0x16, 0x411111f0 }, /* N/A */
- { 0x17, 0x411111f0 }, /* N/A */
- { 0x18, 0x01a19950 }, /* mic-in */
- { 0x19, 0x411111f0 }, /* N/A */
- { 0x1a, 0x01813031 }, /* line-in */
- { 0x1b, 0x411111f0 }, /* N/A */
- { 0x1c, 0x411111f0 }, /* N/A */
- { 0x1d, 0x411111f0 }, /* N/A */
- { 0x1e, 0x0144111e }, /* SPDIF */
- { }
- }
- },
- [ALC880_FIXUP_3ST_BASE] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x14, 0x01014010 }, /* line-out */
- { 0x15, 0x411111f0 }, /* N/A */
- { 0x16, 0x411111f0 }, /* N/A */
- { 0x17, 0x411111f0 }, /* N/A */
- { 0x18, 0x01a19c30 }, /* mic-in */
- { 0x19, 0x0121411f }, /* HP */
- { 0x1a, 0x01813031 }, /* line-in */
- { 0x1b, 0x02a19c40 }, /* front-mic */
- { 0x1c, 0x411111f0 }, /* N/A */
- { 0x1d, 0x411111f0 }, /* N/A */
- /* 0x1e is filled in below */
- { 0x1f, 0x411111f0 }, /* N/A */
- { }
- }
- },
- [ALC880_FIXUP_3ST] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x1e, 0x411111f0 }, /* N/A */
- { }
- },
- .chained = true,
- .chain_id = ALC880_FIXUP_3ST_BASE,
- },
- [ALC880_FIXUP_3ST_DIG] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x1e, 0x0144111e }, /* SPDIF */
- { }
- },
- .chained = true,
- .chain_id = ALC880_FIXUP_3ST_BASE,
- },
- [ALC880_FIXUP_5ST_BASE] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x14, 0x01014010 }, /* front */
- { 0x15, 0x411111f0 }, /* N/A */
- { 0x16, 0x01011411 }, /* CLFE */
- { 0x17, 0x01016412 }, /* surr */
- { 0x18, 0x01a19c30 }, /* mic-in */
- { 0x19, 0x0121411f }, /* HP */
- { 0x1a, 0x01813031 }, /* line-in */
- { 0x1b, 0x02a19c40 }, /* front-mic */
- { 0x1c, 0x411111f0 }, /* N/A */
- { 0x1d, 0x411111f0 }, /* N/A */
- /* 0x1e is filled in below */
- { 0x1f, 0x411111f0 }, /* N/A */
- { }
- }
- },
- [ALC880_FIXUP_5ST] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x1e, 0x411111f0 }, /* N/A */
- { }
- },
- .chained = true,
- .chain_id = ALC880_FIXUP_5ST_BASE,
- },
- [ALC880_FIXUP_5ST_DIG] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x1e, 0x0144111e }, /* SPDIF */
- { }
- },
- .chained = true,
- .chain_id = ALC880_FIXUP_5ST_BASE,
- },
- [ALC880_FIXUP_6ST_BASE] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x14, 0x01014010 }, /* front */
- { 0x15, 0x01016412 }, /* surr */
- { 0x16, 0x01011411 }, /* CLFE */
- { 0x17, 0x01012414 }, /* side */
- { 0x18, 0x01a19c30 }, /* mic-in */
- { 0x19, 0x02a19c40 }, /* front-mic */
- { 0x1a, 0x01813031 }, /* line-in */
- { 0x1b, 0x0121411f }, /* HP */
- { 0x1c, 0x411111f0 }, /* N/A */
- { 0x1d, 0x411111f0 }, /* N/A */
- /* 0x1e is filled in below */
- { 0x1f, 0x411111f0 }, /* N/A */
- { }
- }
- },
- [ALC880_FIXUP_6ST] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x1e, 0x411111f0 }, /* N/A */
- { }
- },
- .chained = true,
- .chain_id = ALC880_FIXUP_6ST_BASE,
- },
- [ALC880_FIXUP_6ST_DIG] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x1e, 0x0144111e }, /* SPDIF */
- { }
- },
- .chained = true,
- .chain_id = ALC880_FIXUP_6ST_BASE,
- },
-};
-
-static const struct snd_pci_quirk alc880_fixup_tbl[] = {
- SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
- SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
- SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
- SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
- SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
- SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
- SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
- SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
- SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
- SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
- SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
- SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_FIXUP_F1734),
- SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
- SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
- SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
- SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
- SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
- SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
- SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
-
- /* Below is the copied entries from alc880_quirks.c.
- * It's not quite sure whether BIOS sets the correct pin-config table
- * on these machines, thus they are kept to be compatible with
- * the old static quirks. Once when it's confirmed to work without
- * these overrides, it'd be better to remove.
- */
- SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
- SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
- SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
- SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
- SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
- SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
- SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
- SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
- SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
- SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
- SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
- SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
- SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
- SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
- SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
- SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
- SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
- SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
- SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
- SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
- SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
- SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
- SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
- SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
- SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
- SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
- SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
- SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
- SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
- SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
- SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
- SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
- SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
- /* default Intel */
- SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
- SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
- SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
- {}
-};
-
-static const struct alc_model_fixup alc880_fixup_models[] = {
- {.id = ALC880_FIXUP_3ST, .name = "3stack"},
- {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
- {.id = ALC880_FIXUP_5ST, .name = "5stack"},
- {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
- {.id = ALC880_FIXUP_6ST, .name = "6stack"},
- {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
- {}
-};
-
-
-/*
- * OK, here we have finally the patch for ALC880
- */
-static int patch_alc880(struct hda_codec *codec)
-{
- struct alc_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->spec = spec;
-
- spec->mixer_nid = 0x0b;
- spec->need_dac_fix = 1;
-
- alc_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
- alc880_fixups);
- alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-
- /* automatic parse from the BIOS config */
- err = alc880_parse_auto_config(codec);
- if (err < 0)
- goto error;
-
- if (!spec->no_analog) {
- err = snd_hda_attach_beep_device(codec, 0x1);
- if (err < 0)
- goto error;
- set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
- }
-
- codec->patch_ops = alc_patch_ops;
-
- alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
- return 0;
-
- error:
- alc_free(codec);
- return err;
-}
-
-
-/*
- * ALC260 support
- */
-static int alc260_parse_auto_config(struct hda_codec *codec)
-{
- static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
- static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
- return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
-}
-
-/*
- * Pin config fixes
- */
-enum {
- ALC260_FIXUP_HP_DC5750,
- ALC260_FIXUP_HP_PIN_0F,
- ALC260_FIXUP_COEF,
- ALC260_FIXUP_GPIO1,
- ALC260_FIXUP_GPIO1_TOGGLE,
- ALC260_FIXUP_REPLACER,
- ALC260_FIXUP_HP_B1900,
- ALC260_FIXUP_KN1,
-};
-
-static void alc260_gpio1_automute(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
- spec->hp_jack_present);
-}
-
-static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
- const struct alc_fixup *fix, int action)
-{
- struct alc_spec *spec = codec->spec;
- if (action == ALC_FIXUP_ACT_PROBE) {
- /* although the machine has only one output pin, we need to
- * toggle GPIO1 according to the jack state
- */
- spec->automute_hook = alc260_gpio1_automute;
- spec->detect_hp = 1;
- spec->automute_speaker = 1;
- spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
- snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT);
- spec->unsol_event = alc_sku_unsol_event;
- add_verb(codec->spec, alc_gpio1_init_verbs);
- }
-}
-
-static void alc260_fixup_kn1(struct hda_codec *codec,
- const struct alc_fixup *fix, int action)
-{
- struct alc_spec *spec = codec->spec;
- static const struct alc_pincfg pincfgs[] = {
- { 0x0f, 0x02214000 }, /* HP/speaker */
- { 0x12, 0x90a60160 }, /* int mic */
- { 0x13, 0x02a19000 }, /* ext mic */
- { 0x18, 0x01446000 }, /* SPDIF out */
- /* disable bogus I/O pins */
- { 0x10, 0x411111f0 },
- { 0x11, 0x411111f0 },
- { 0x14, 0x411111f0 },
- { 0x15, 0x411111f0 },
- { 0x16, 0x411111f0 },
- { 0x17, 0x411111f0 },
- { 0x19, 0x411111f0 },
- { }
- };
-
- switch (action) {
- case ALC_FIXUP_ACT_PRE_PROBE:
- alc_apply_pincfgs(codec, pincfgs);
- break;
- case ALC_FIXUP_ACT_PROBE:
- spec->init_amp = ALC_INIT_NONE;
- break;
- }
-}
-
-static const struct alc_fixup alc260_fixups[] = {
- [ALC260_FIXUP_HP_DC5750] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x11, 0x90130110 }, /* speaker */
- { }
- }
- },
- [ALC260_FIXUP_HP_PIN_0F] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x0f, 0x01214000 }, /* HP */
- { }
- }
- },
- [ALC260_FIXUP_COEF] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = (const struct hda_verb[]) {
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x3040 },
- { }
- },
- .chained = true,
- .chain_id = ALC260_FIXUP_HP_PIN_0F,
- },
- [ALC260_FIXUP_GPIO1] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = alc_gpio1_init_verbs,
- },
- [ALC260_FIXUP_GPIO1_TOGGLE] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc260_fixup_gpio1_toggle,
- .chained = true,
- .chain_id = ALC260_FIXUP_HP_PIN_0F,
- },
- [ALC260_FIXUP_REPLACER] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = (const struct hda_verb[]) {
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
- { }
- },
- .chained = true,
- .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
- },
- [ALC260_FIXUP_HP_B1900] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc260_fixup_gpio1_toggle,
- .chained = true,
- .chain_id = ALC260_FIXUP_COEF,
- },
- [ALC260_FIXUP_KN1] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc260_fixup_kn1,
- },
-};
-
-static const struct snd_pci_quirk alc260_fixup_tbl[] = {
- SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
- SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
- SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
- SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
- SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
- SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
- SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
- SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
- SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
- {}
-};
-
-/*
- */
-static int patch_alc260(struct hda_codec *codec)
-{
- struct alc_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->spec = spec;
-
- spec->mixer_nid = 0x07;
-
- alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
- alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-
- /* automatic parse from the BIOS config */
- err = alc260_parse_auto_config(codec);
- if (err < 0)
- goto error;
-
- if (!spec->no_analog) {
- err = snd_hda_attach_beep_device(codec, 0x1);
- if (err < 0)
- goto error;
- set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
- }
-
- codec->patch_ops = alc_patch_ops;
- spec->shutup = alc_eapd_shutup;
-
- alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
- return 0;
-
- error:
- alc_free(codec);
- return err;
-}
-
-
-/*
- * ALC882/883/885/888/889 support
- *
- * ALC882 is almost identical with ALC880 but has cleaner and more flexible
- * configuration. Each pin widget can choose any input DACs and a mixer.
- * Each ADC is connected from a mixer of all inputs. This makes possible
- * 6-channel independent captures.
- *
- * In addition, an independent DAC for the multi-playback (not used in this
- * driver yet).
- */
-
-/*
- * Pin config fixes
- */
-enum {
- ALC882_FIXUP_ABIT_AW9D_MAX,
- ALC882_FIXUP_LENOVO_Y530,
- ALC882_FIXUP_PB_M5210,
- ALC882_FIXUP_ACER_ASPIRE_7736,
- ALC882_FIXUP_ASUS_W90V,
- ALC889_FIXUP_CD,
- ALC889_FIXUP_VAIO_TT,
- ALC888_FIXUP_EEE1601,
- ALC882_FIXUP_EAPD,
- ALC883_FIXUP_EAPD,
- ALC883_FIXUP_ACER_EAPD,
- ALC882_FIXUP_GPIO1,
- ALC882_FIXUP_GPIO2,
- ALC882_FIXUP_GPIO3,
- ALC889_FIXUP_COEF,
- ALC882_FIXUP_ASUS_W2JC,
- ALC882_FIXUP_ACER_ASPIRE_4930G,
- ALC882_FIXUP_ACER_ASPIRE_8930G,
- ALC882_FIXUP_ASPIRE_8930G_VERBS,
- ALC885_FIXUP_MACPRO_GPIO,
- ALC889_FIXUP_DAC_ROUTE,
- ALC889_FIXUP_MBP_VREF,
- ALC889_FIXUP_IMAC91_VREF,
-};
-
-static void alc889_fixup_coef(struct hda_codec *codec,
- const struct alc_fixup *fix, int action)
-{
- if (action != ALC_FIXUP_ACT_INIT)
- return;
- alc889_coef_init(codec);
-}
-
-/* toggle speaker-output according to the hp-jack state */
-static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
-{
- unsigned int gpiostate, gpiomask, gpiodir;
-
- gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
- AC_VERB_GET_GPIO_DATA, 0);
-
- if (!muted)
- gpiostate |= (1 << pin);
- else
- gpiostate &= ~(1 << pin);
-
- gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
- AC_VERB_GET_GPIO_MASK, 0);
- gpiomask |= (1 << pin);
-
- gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
- AC_VERB_GET_GPIO_DIRECTION, 0);
- gpiodir |= (1 << pin);
-
-
- snd_hda_codec_write(codec, codec->afg, 0,
- AC_VERB_SET_GPIO_MASK, gpiomask);
- snd_hda_codec_write(codec, codec->afg, 0,
- AC_VERB_SET_GPIO_DIRECTION, gpiodir);
-
- msleep(1);
-
- snd_hda_codec_write(codec, codec->afg, 0,
- AC_VERB_SET_GPIO_DATA, gpiostate);
-}
-
-/* set up GPIO at initialization */
-static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
- const struct alc_fixup *fix, int action)
-{
- if (action != ALC_FIXUP_ACT_INIT)
- return;
- alc882_gpio_mute(codec, 0, 0);
- alc882_gpio_mute(codec, 1, 0);
-}
-
-/* Fix the connection of some pins for ALC889:
- * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
- * work correctly (bko#42740)
- */
-static void alc889_fixup_dac_route(struct hda_codec *codec,
- const struct alc_fixup *fix, int action)
-{
- if (action == ALC_FIXUP_ACT_PRE_PROBE) {
- /* fake the connections during parsing the tree */
- hda_nid_t conn1[2] = { 0x0c, 0x0d };
- hda_nid_t conn2[2] = { 0x0e, 0x0f };
- snd_hda_override_conn_list(codec, 0x14, 2, conn1);
- snd_hda_override_conn_list(codec, 0x15, 2, conn1);
- snd_hda_override_conn_list(codec, 0x18, 2, conn2);
- snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
- } else if (action == ALC_FIXUP_ACT_PROBE) {
- /* restore the connections */
- hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
- snd_hda_override_conn_list(codec, 0x14, 5, conn);
- snd_hda_override_conn_list(codec, 0x15, 5, conn);
- snd_hda_override_conn_list(codec, 0x18, 5, conn);
- snd_hda_override_conn_list(codec, 0x1a, 5, conn);
- }
-}
-
-/* Set VREF on HP pin */
-static void alc889_fixup_mbp_vref(struct hda_codec *codec,
- const struct alc_fixup *fix, int action)
-{
- struct alc_spec *spec = codec->spec;
- static hda_nid_t nids[2] = { 0x14, 0x15 };
- int i;
-
- if (action != ALC_FIXUP_ACT_INIT)
- return;
- for (i = 0; i < ARRAY_SIZE(nids); i++) {
- unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
- if (get_defcfg_device(val) != AC_JACK_HP_OUT)
- continue;
- val = snd_hda_codec_read(codec, nids[i], 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
- val |= AC_PINCTL_VREF_80;
- snd_hda_codec_write(codec, nids[i], 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, val);
- spec->keep_vref_in_automute = 1;
- break;
- }
-}
-
-/* Set VREF on speaker pins on imac91 */
-static void alc889_fixup_imac91_vref(struct hda_codec *codec,
- const struct alc_fixup *fix, int action)
-{
- struct alc_spec *spec = codec->spec;
- static hda_nid_t nids[2] = { 0x18, 0x1a };
- int i;
-
- if (action != ALC_FIXUP_ACT_INIT)
- return;
- for (i = 0; i < ARRAY_SIZE(nids); i++) {
- unsigned int val;
- val = snd_hda_codec_read(codec, nids[i], 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
- val |= AC_PINCTL_VREF_50;
- snd_hda_codec_write(codec, nids[i], 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, val);
- }
- spec->keep_vref_in_automute = 1;
-}
-
-static const struct alc_fixup alc882_fixups[] = {
- [ALC882_FIXUP_ABIT_AW9D_MAX] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x15, 0x01080104 }, /* side */
- { 0x16, 0x01011012 }, /* rear */
- { 0x17, 0x01016011 }, /* clfe */
- { }
- }
- },
- [ALC882_FIXUP_LENOVO_Y530] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x15, 0x99130112 }, /* rear int speakers */
- { 0x16, 0x99130111 }, /* subwoofer */
- { }
- }
- },
- [ALC882_FIXUP_PB_M5210] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = (const struct hda_verb[]) {
- { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
- {}
- }
- },
- [ALC882_FIXUP_ACER_ASPIRE_7736] = {
- .type = ALC_FIXUP_SKU,
- .v.sku = ALC_FIXUP_SKU_IGNORE,
- },
- [ALC882_FIXUP_ASUS_W90V] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x16, 0x99130110 }, /* fix sequence for CLFE */
- { }
- }
- },
- [ALC889_FIXUP_CD] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x1c, 0x993301f0 }, /* CD */
- { }
- }
- },
- [ALC889_FIXUP_VAIO_TT] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x17, 0x90170111 }, /* hidden surround speaker */
- { }
- }
- },
- [ALC888_FIXUP_EEE1601] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = (const struct hda_verb[]) {
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 },
- { }
- }
- },
- [ALC882_FIXUP_EAPD] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = (const struct hda_verb[]) {
- /* change to EAPD mode */
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
- { }
- }
- },
- [ALC883_FIXUP_EAPD] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = (const struct hda_verb[]) {
- /* change to EAPD mode */
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
- { }
- }
- },
- [ALC883_FIXUP_ACER_EAPD] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = (const struct hda_verb[]) {
- /* eanable EAPD on Acer laptops */
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
- { }
- }
- },
- [ALC882_FIXUP_GPIO1] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = alc_gpio1_init_verbs,
- },
- [ALC882_FIXUP_GPIO2] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = alc_gpio2_init_verbs,
- },
- [ALC882_FIXUP_GPIO3] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = alc_gpio3_init_verbs,
- },
- [ALC882_FIXUP_ASUS_W2JC] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = alc_gpio1_init_verbs,
- .chained = true,
- .chain_id = ALC882_FIXUP_EAPD,
- },
- [ALC889_FIXUP_COEF] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc889_fixup_coef,
- },
- [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x16, 0x99130111 }, /* CLFE speaker */
- { 0x17, 0x99130112 }, /* surround speaker */
- { }
- },
- .chained = true,
- .chain_id = ALC882_FIXUP_GPIO1,
- },
- [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x16, 0x99130111 }, /* CLFE speaker */
- { 0x1b, 0x99130112 }, /* surround speaker */
- { }
- },
- .chained = true,
- .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
- },
- [ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
- /* additional init verbs for Acer Aspire 8930G */
- .type = ALC_FIXUP_VERBS,
- .v.verbs = (const struct hda_verb[]) {
- /* Enable all DACs */
- /* DAC DISABLE/MUTE 1? */
- /* setting bits 1-5 disables DAC nids 0x02-0x06
- * apparently. Init=0x38 */
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
- /* DAC DISABLE/MUTE 2? */
- /* some bit here disables the other DACs.
- * Init=0x4900 */
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
- /* DMIC fix
- * This laptop has a stereo digital microphone.
- * The mics are only 1cm apart which makes the stereo
- * useless. However, either the mic or the ALC889
- * makes the signal become a difference/sum signal
- * instead of standard stereo, which is annoying.
- * So instead we flip this bit which makes the
- * codec replicate the sum signal to both channels,
- * turning it into a normal mono mic.
- */
- /* DMIC_CONTROL? Init value = 0x0001 */
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
- { }
- },
- .chained = true,
- .chain_id = ALC882_FIXUP_GPIO1,
- },
- [ALC885_FIXUP_MACPRO_GPIO] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc885_fixup_macpro_gpio,
- },
- [ALC889_FIXUP_DAC_ROUTE] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc889_fixup_dac_route,
- },
- [ALC889_FIXUP_MBP_VREF] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc889_fixup_mbp_vref,
- .chained = true,
- .chain_id = ALC882_FIXUP_GPIO1,
- },
- [ALC889_FIXUP_IMAC91_VREF] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc889_fixup_imac91_vref,
- .chained = true,
- .chain_id = ALC882_FIXUP_GPIO1,
- },
-};
-
-static const struct snd_pci_quirk alc882_fixup_tbl[] = {
- SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
- SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
- SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
- SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
- SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
- SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
- SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
- ALC882_FIXUP_ACER_ASPIRE_4930G),
- SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
- ALC882_FIXUP_ACER_ASPIRE_4930G),
- SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
- ALC882_FIXUP_ACER_ASPIRE_8930G),
- SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
- ALC882_FIXUP_ACER_ASPIRE_8930G),
- SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
- ALC882_FIXUP_ACER_ASPIRE_4930G),
- SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
- ALC882_FIXUP_ACER_ASPIRE_4930G),
- SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
- ALC882_FIXUP_ACER_ASPIRE_4930G),
- SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
- SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
- ALC882_FIXUP_ACER_ASPIRE_4930G),
- SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
- SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
- SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
- SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
- SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
- SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
- SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
- SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
-
- /* All Apple entries are in codec SSIDs */
- SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
- SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
- SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
- SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO),
- SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
- SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
- SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
- SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
- SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
- SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBP_VREF),
- SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBP_VREF),
- SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
- SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
- SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
- SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
- SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
- SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
- SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO),
- SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
- SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
- SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF),
-
- SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
- SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
- SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
- SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3", ALC889_FIXUP_CD),
- SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
- SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
- SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
- SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
- SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
- {}
-};
-
-static const struct alc_model_fixup alc882_fixup_models[] = {
- {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
- {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
- {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
- {}
-};
-
-/*
- * BIOS auto configuration
- */
-/* almost identical with ALC880 parser... */
-static int alc882_parse_auto_config(struct hda_codec *codec)
-{
- static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
- static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
- return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
-}
-
-/*
- */
-static int patch_alc882(struct hda_codec *codec)
-{
- struct alc_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->spec = spec;
-
- spec->mixer_nid = 0x0b;
-
- switch (codec->vendor_id) {
- case 0x10ec0882:
- case 0x10ec0885:
- break;
- default:
- /* ALC883 and variants */
- alc_fix_pll_init(codec, 0x20, 0x0a, 10);
- break;
- }
-
- err = alc_codec_rename_from_preset(codec);
- if (err < 0)
- goto error;
-
- alc_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
- alc882_fixups);
- alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-
- alc_auto_parse_customize_define(codec);
-
- /* automatic parse from the BIOS config */
- err = alc882_parse_auto_config(codec);
- if (err < 0)
- goto error;
-
- if (!spec->no_analog && has_cdefine_beep(codec)) {
- err = snd_hda_attach_beep_device(codec, 0x1);
- if (err < 0)
- goto error;
- set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
- }
-
- codec->patch_ops = alc_patch_ops;
-
- alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
- return 0;
-
- error:
- alc_free(codec);
- return err;
-}
-
-
-/*
- * ALC262 support
- */
-static int alc262_parse_auto_config(struct hda_codec *codec)
-{
- static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
- static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
- return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
-}
-
-/*
- * Pin config fixes
- */
-enum {
- ALC262_FIXUP_FSC_H270,
- ALC262_FIXUP_HP_Z200,
- ALC262_FIXUP_TYAN,
- ALC262_FIXUP_LENOVO_3000,
- ALC262_FIXUP_BENQ,
- ALC262_FIXUP_BENQ_T31,
-};
-
-static const struct alc_fixup alc262_fixups[] = {
- [ALC262_FIXUP_FSC_H270] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x14, 0x99130110 }, /* speaker */
- { 0x15, 0x0221142f }, /* front HP */
- { 0x1b, 0x0121141f }, /* rear HP */
- { }
- }
- },
- [ALC262_FIXUP_HP_Z200] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x16, 0x99130120 }, /* internal speaker */
- { }
- }
- },
- [ALC262_FIXUP_TYAN] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x14, 0x1993e1f0 }, /* int AUX */
- { }
- }
- },
- [ALC262_FIXUP_LENOVO_3000] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = (const struct hda_verb[]) {
- { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
- {}
- },
- .chained = true,
- .chain_id = ALC262_FIXUP_BENQ,
- },
- [ALC262_FIXUP_BENQ] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = (const struct hda_verb[]) {
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
- {}
- }
- },
- [ALC262_FIXUP_BENQ_T31] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = (const struct hda_verb[]) {
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
- {}
- }
- },
-};
-
-static const struct snd_pci_quirk alc262_fixup_tbl[] = {
- SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
- SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ),
- SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
- SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
- SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
- SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
- SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
- SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
- {}
-};
-
-
-/*
- */
-static int patch_alc262(struct hda_codec *codec)
-{
- struct alc_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->spec = spec;
-
- spec->mixer_nid = 0x0b;
-
-#if 0
- /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
- * under-run
- */
- {
- int tmp;
- snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
- tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
- snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
- snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
- }
-#endif
- alc_fix_pll_init(codec, 0x20, 0x0a, 10);
-
- alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
- alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-
- alc_auto_parse_customize_define(codec);
-
- /* automatic parse from the BIOS config */
- err = alc262_parse_auto_config(codec);
- if (err < 0)
- goto error;
-
- if (!spec->no_analog && has_cdefine_beep(codec)) {
- err = snd_hda_attach_beep_device(codec, 0x1);
- if (err < 0)
- goto error;
- set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
- }
-
- codec->patch_ops = alc_patch_ops;
- spec->shutup = alc_eapd_shutup;
-
- alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
- return 0;
-
- error:
- alc_free(codec);
- return err;
-}
-
-/*
- * ALC268
- */
-/* bind Beep switches of both NID 0x0f and 0x10 */
-static const struct hda_bind_ctls alc268_bind_beep_sw = {
- .ops = &snd_hda_bind_sw,
- .values = {
- HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
- HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
- 0
- },
-};
-
-static const struct snd_kcontrol_new alc268_beep_mixer[] = {
- HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
- HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
- { }
-};
-
-/* set PCBEEP vol = 0, mute connections */
-static const struct hda_verb alc268_beep_init_verbs[] = {
- {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- { }
-};
-
-/*
- * BIOS auto configuration
- */
-static int alc268_parse_auto_config(struct hda_codec *codec)
-{
- static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
- struct alc_spec *spec = codec->spec;
- int err = alc_parse_auto_config(codec, NULL, alc268_ssids);
- if (err > 0) {
- if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) {
- add_mixer(spec, alc268_beep_mixer);
- add_verb(spec, alc268_beep_init_verbs);
- }
- }
- return err;
-}
-
-/*
- */
-static int patch_alc268(struct hda_codec *codec)
-{
- struct alc_spec *spec;
- int i, has_beep, err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->spec = spec;
-
- /* ALC268 has no aa-loopback mixer */
-
- /* automatic parse from the BIOS config */
- err = alc268_parse_auto_config(codec);
- if (err < 0)
- goto error;
-
- has_beep = 0;
- for (i = 0; i < spec->num_mixers; i++) {
- if (spec->mixers[i] == alc268_beep_mixer) {
- has_beep = 1;
- break;
- }
- }
-
- if (has_beep) {
- err = snd_hda_attach_beep_device(codec, 0x1);
- if (err < 0)
- goto error;
- if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
- /* override the amp caps for beep generator */
- snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
- (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
- (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
- (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
- (0 << AC_AMPCAP_MUTE_SHIFT));
- }
-
- codec->patch_ops = alc_patch_ops;
- spec->shutup = alc_eapd_shutup;
-
- return 0;
-
- error:
- alc_free(codec);
- return err;
-}
-
-/*
- * ALC269
- */
-static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 8,
- .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
- /* NID is set in alc_build_pcms */
- .ops = {
- .open = alc_playback_pcm_open,
- .prepare = alc_playback_pcm_prepare,
- .cleanup = alc_playback_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
- /* NID is set in alc_build_pcms */
-};
-
-/* different alc269-variants */
-enum {
- ALC269_TYPE_ALC269VA,
- ALC269_TYPE_ALC269VB,
- ALC269_TYPE_ALC269VC,
-};
-
-/*
- * BIOS auto configuration
- */
-static int alc269_parse_auto_config(struct hda_codec *codec)
-{
- static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
- static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
- static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
- struct alc_spec *spec = codec->spec;
- const hda_nid_t *ssids = spec->codec_variant == ALC269_TYPE_ALC269VA ?
- alc269va_ssids : alc269_ssids;
-
- return alc_parse_auto_config(codec, alc269_ignore, ssids);
-}
-
-static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
-{
- int val = alc_read_coef_idx(codec, 0x04);
- if (power_up)
- val |= 1 << 11;
- else
- val &= ~(1 << 11);
- alc_write_coef_idx(codec, 0x04, val);
-}
-
-static void alc269_shutup(struct hda_codec *codec)
-{
- if ((alc_get_coef0(codec) & 0x00ff) == 0x017)
- alc269_toggle_power_output(codec, 0);
- if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
- alc269_toggle_power_output(codec, 0);
- msleep(150);
- }
-}
-
-#ifdef CONFIG_PM
-static int alc269_resume(struct hda_codec *codec)
-{
- if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
- alc269_toggle_power_output(codec, 0);
- msleep(150);
- }
-
- codec->patch_ops.init(codec);
-
- if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
- alc269_toggle_power_output(codec, 1);
- msleep(200);
- }
-
- if ((alc_get_coef0(codec) & 0x00ff) == 0x018)
- alc269_toggle_power_output(codec, 1);
-
- snd_hda_codec_resume_amp(codec);
- snd_hda_codec_resume_cache(codec);
- hda_call_check_power_status(codec, 0x01);
- return 0;
-}
-#endif /* CONFIG_PM */
-
-static void alc269_fixup_hweq(struct hda_codec *codec,
- const struct alc_fixup *fix, int action)
-{
- int coef;
-
- if (action != ALC_FIXUP_ACT_INIT)
- return;
- coef = alc_read_coef_idx(codec, 0x1e);
- alc_write_coef_idx(codec, 0x1e, coef | 0x80);
-}
-
-static void alc271_fixup_dmic(struct hda_codec *codec,
- const struct alc_fixup *fix, int action)
-{
- static const struct hda_verb verbs[] = {
- {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
- {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
- {}
- };
- unsigned int cfg;
-
- if (strcmp(codec->chip_name, "ALC271X"))
- return;
- cfg = snd_hda_codec_get_pincfg(codec, 0x12);
- if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
- snd_hda_sequence_write(codec, verbs);
-}
-
-static void alc269_fixup_pcm_44k(struct hda_codec *codec,
- const struct alc_fixup *fix, int action)
-{
- struct alc_spec *spec = codec->spec;
-
- if (action != ALC_FIXUP_ACT_PROBE)
- return;
-
- /* Due to a hardware problem on Lenovo Ideadpad, we need to
- * fix the sample rate of analog I/O to 44.1kHz
- */
- spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
- spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
-}
-
-static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
- const struct alc_fixup *fix, int action)
-{
- int coef;
-
- if (action != ALC_FIXUP_ACT_INIT)
- return;
- /* The digital-mic unit sends PDM (differential signal) instead of
- * the standard PCM, thus you can't record a valid mono stream as is.
- * Below is a workaround specific to ALC269 to control the dmic
- * signal source as mono.
- */
- coef = alc_read_coef_idx(codec, 0x07);
- alc_write_coef_idx(codec, 0x07, coef | 0x80);
-}
-
-static void alc269_quanta_automute(struct hda_codec *codec)
-{
- update_outputs(codec);
-
- snd_hda_codec_write(codec, 0x20, 0,
- AC_VERB_SET_COEF_INDEX, 0x0c);
- snd_hda_codec_write(codec, 0x20, 0,
- AC_VERB_SET_PROC_COEF, 0x680);
-
- snd_hda_codec_write(codec, 0x20, 0,
- AC_VERB_SET_COEF_INDEX, 0x0c);
- snd_hda_codec_write(codec, 0x20, 0,
- AC_VERB_SET_PROC_COEF, 0x480);
-}
-
-static void alc269_fixup_quanta_mute(struct hda_codec *codec,
- const struct alc_fixup *fix, int action)
-{
- struct alc_spec *spec = codec->spec;
- if (action != ALC_FIXUP_ACT_PROBE)
- return;
- spec->automute_hook = alc269_quanta_automute;
-}
-
-/* update mute-LED according to the speaker mute state via mic2 VREF pin */
-static void alc269_fixup_mic2_mute_hook(void *private_data, int enabled)
-{
- struct hda_codec *codec = private_data;
- unsigned int pinval = enabled ? 0x20 : 0x24;
- snd_hda_codec_update_cache(codec, 0x19, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- pinval);
-}
-
-static void alc269_fixup_mic2_mute(struct hda_codec *codec,
- const struct alc_fixup *fix, int action)
-{
- struct alc_spec *spec = codec->spec;
- switch (action) {
- case ALC_FIXUP_ACT_BUILD:
- spec->vmaster_mute.hook = alc269_fixup_mic2_mute_hook;
- snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true);
- /* fallthru */
- case ALC_FIXUP_ACT_INIT:
- snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
- break;
- }
-}
-
-enum {
- ALC269_FIXUP_SONY_VAIO,
- ALC275_FIXUP_SONY_VAIO_GPIO2,
- ALC269_FIXUP_DELL_M101Z,
- ALC269_FIXUP_SKU_IGNORE,
- ALC269_FIXUP_ASUS_G73JW,
- ALC269_FIXUP_LENOVO_EAPD,
- ALC275_FIXUP_SONY_HWEQ,
- ALC271_FIXUP_DMIC,
- ALC269_FIXUP_PCM_44K,
- ALC269_FIXUP_STEREO_DMIC,
- ALC269_FIXUP_QUANTA_MUTE,
- ALC269_FIXUP_LIFEBOOK,
- ALC269_FIXUP_AMIC,
- ALC269_FIXUP_DMIC,
- ALC269VB_FIXUP_AMIC,
- ALC269VB_FIXUP_DMIC,
- ALC269_FIXUP_MIC2_MUTE_LED,
-};
-
-static const struct alc_fixup alc269_fixups[] = {
- [ALC269_FIXUP_SONY_VAIO] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = (const struct hda_verb[]) {
- {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
- {}
- }
- },
- [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = (const struct hda_verb[]) {
- {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
- {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
- {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
- { }
- },
- .chained = true,
- .chain_id = ALC269_FIXUP_SONY_VAIO
- },
- [ALC269_FIXUP_DELL_M101Z] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = (const struct hda_verb[]) {
- /* Enables internal speaker */
- {0x20, AC_VERB_SET_COEF_INDEX, 13},
- {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
- {}
- }
- },
- [ALC269_FIXUP_SKU_IGNORE] = {
- .type = ALC_FIXUP_SKU,
- .v.sku = ALC_FIXUP_SKU_IGNORE,
- },
- [ALC269_FIXUP_ASUS_G73JW] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x17, 0x99130111 }, /* subwoofer */
- { }
- }
- },
- [ALC269_FIXUP_LENOVO_EAPD] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = (const struct hda_verb[]) {
- {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
- {}
- }
- },
- [ALC275_FIXUP_SONY_HWEQ] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc269_fixup_hweq,
- .chained = true,
- .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
- },
- [ALC271_FIXUP_DMIC] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc271_fixup_dmic,
- },
- [ALC269_FIXUP_PCM_44K] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc269_fixup_pcm_44k,
- },
- [ALC269_FIXUP_STEREO_DMIC] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc269_fixup_stereo_dmic,
- },
- [ALC269_FIXUP_QUANTA_MUTE] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc269_fixup_quanta_mute,
- },
- [ALC269_FIXUP_LIFEBOOK] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x1a, 0x2101103f }, /* dock line-out */
- { 0x1b, 0x23a11040 }, /* dock mic-in */
- { }
- },
- .chained = true,
- .chain_id = ALC269_FIXUP_QUANTA_MUTE
- },
- [ALC269_FIXUP_AMIC] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x14, 0x99130110 }, /* speaker */
- { 0x15, 0x0121401f }, /* HP out */
- { 0x18, 0x01a19c20 }, /* mic */
- { 0x19, 0x99a3092f }, /* int-mic */
- { }
- },
- },
- [ALC269_FIXUP_DMIC] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x12, 0x99a3092f }, /* int-mic */
- { 0x14, 0x99130110 }, /* speaker */
- { 0x15, 0x0121401f }, /* HP out */
- { 0x18, 0x01a19c20 }, /* mic */
- { }
- },
- },
- [ALC269VB_FIXUP_AMIC] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x14, 0x99130110 }, /* speaker */
- { 0x18, 0x01a19c20 }, /* mic */
- { 0x19, 0x99a3092f }, /* int-mic */
- { 0x21, 0x0121401f }, /* HP out */
- { }
- },
- },
- [ALC269VB_FIXUP_DMIC] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x12, 0x99a3092f }, /* int-mic */
- { 0x14, 0x99130110 }, /* speaker */
- { 0x18, 0x01a19c20 }, /* mic */
- { 0x21, 0x0121401f }, /* HP out */
- { }
- },
- },
- [ALC269_FIXUP_MIC2_MUTE_LED] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc269_fixup_mic2_mute,
- },
-};
-
-static const struct snd_pci_quirk alc269_fixup_tbl[] = {
- SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED),
- SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC),
- SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
- SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
- SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
- SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
- SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
- SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
- SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
- SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
- SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
- SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
- SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
- SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
- SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
- SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
- SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
- SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
- SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
- SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
- SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_QUANTA_MUTE),
- SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K),
- SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
-
-#if 0
- /* Below is a quirk table taken from the old code.
- * Basically the device should work as is without the fixup table.
- * If BIOS doesn't give a proper info, enable the corresponding
- * fixup entry.
- */
- SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
- ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
- SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
- SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
- SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
-#endif
- {}
-};
-
-static const struct alc_model_fixup alc269_fixup_models[] = {
- {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
- {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
- {}
-};
-
-
-static void alc269_fill_coef(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- int val;
-
- if (spec->codec_variant != ALC269_TYPE_ALC269VB)
- return;
-
- if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
- alc_write_coef_idx(codec, 0xf, 0x960b);
- alc_write_coef_idx(codec, 0xe, 0x8817);
- }
-
- if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
- alc_write_coef_idx(codec, 0xf, 0x960b);
- alc_write_coef_idx(codec, 0xe, 0x8814);
- }
-
- if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
- val = alc_read_coef_idx(codec, 0x04);
- /* Power up output pin */
- alc_write_coef_idx(codec, 0x04, val | (1<<11));
- }
-
- if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
- val = alc_read_coef_idx(codec, 0xd);
- if ((val & 0x0c00) >> 10 != 0x1) {
- /* Capless ramp up clock control */
- alc_write_coef_idx(codec, 0xd, val | (1<<10));
- }
- val = alc_read_coef_idx(codec, 0x17);
- if ((val & 0x01c0) >> 6 != 0x4) {
- /* Class D power on reset */
- alc_write_coef_idx(codec, 0x17, val | (1<<7));
- }
- }
-
- val = alc_read_coef_idx(codec, 0xd); /* Class D */
- alc_write_coef_idx(codec, 0xd, val | (1<<14));
-
- val = alc_read_coef_idx(codec, 0x4); /* HP */
- alc_write_coef_idx(codec, 0x4, val | (1<<11));
-}
-
-/*
- */
-static int patch_alc269(struct hda_codec *codec)
-{
- struct alc_spec *spec;
- int err = 0;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->spec = spec;
-
- spec->mixer_nid = 0x0b;
-
- err = alc_codec_rename_from_preset(codec);
- if (err < 0)
- goto error;
-
- if (codec->vendor_id == 0x10ec0269) {
- spec->codec_variant = ALC269_TYPE_ALC269VA;
- switch (alc_get_coef0(codec) & 0x00f0) {
- case 0x0010:
- if (codec->bus->pci->subsystem_vendor == 0x1025 &&
- spec->cdefine.platform_type == 1)
- err = alc_codec_rename(codec, "ALC271X");
- spec->codec_variant = ALC269_TYPE_ALC269VB;
- break;
- case 0x0020:
- if (codec->bus->pci->subsystem_vendor == 0x17aa &&
- codec->bus->pci->subsystem_device == 0x21f3)
- err = alc_codec_rename(codec, "ALC3202");
- spec->codec_variant = ALC269_TYPE_ALC269VC;
- break;
- default:
- alc_fix_pll_init(codec, 0x20, 0x04, 15);
- }
- if (err < 0)
- goto error;
- spec->init_hook = alc269_fill_coef;
- alc269_fill_coef(codec);
- }
-
- alc_pick_fixup(codec, alc269_fixup_models,
- alc269_fixup_tbl, alc269_fixups);
- alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-
- alc_auto_parse_customize_define(codec);
-
- /* automatic parse from the BIOS config */
- err = alc269_parse_auto_config(codec);
- if (err < 0)
- goto error;
-
- if (!spec->no_analog && has_cdefine_beep(codec)) {
- err = snd_hda_attach_beep_device(codec, 0x1);
- if (err < 0)
- goto error;
- set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
- }
-
- codec->patch_ops = alc_patch_ops;
-#ifdef CONFIG_PM
- codec->patch_ops.resume = alc269_resume;
-#endif
- spec->shutup = alc269_shutup;
-
- alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
- return 0;
-
- error:
- alc_free(codec);
- return err;
-}
-
-/*
- * ALC861
- */
-
-static int alc861_parse_auto_config(struct hda_codec *codec)
-{
- static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
- static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
- return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
-}
-
-/* Pin config fixes */
-enum {
- ALC861_FIXUP_FSC_AMILO_PI1505,
- ALC861_FIXUP_AMP_VREF_0F,
- ALC861_FIXUP_NO_JACK_DETECT,
- ALC861_FIXUP_ASUS_A6RP,
-};
-
-/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
-static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
- const struct alc_fixup *fix, int action)
-{
- struct alc_spec *spec = codec->spec;
- unsigned int val;
-
- if (action != ALC_FIXUP_ACT_INIT)
- return;
- val = snd_hda_codec_read(codec, 0x0f, 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
- if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
- val |= AC_PINCTL_IN_EN;
- val |= AC_PINCTL_VREF_50;
- snd_hda_codec_write(codec, 0x0f, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, val);
- spec->keep_vref_in_automute = 1;
-}
-
-/* suppress the jack-detection */
-static void alc_fixup_no_jack_detect(struct hda_codec *codec,
- const struct alc_fixup *fix, int action)
-{
- if (action == ALC_FIXUP_ACT_PRE_PROBE)
- codec->no_jack_detect = 1;
-}
-
-static const struct alc_fixup alc861_fixups[] = {
- [ALC861_FIXUP_FSC_AMILO_PI1505] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x0b, 0x0221101f }, /* HP */
- { 0x0f, 0x90170310 }, /* speaker */
- { }
- }
- },
- [ALC861_FIXUP_AMP_VREF_0F] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc861_fixup_asus_amp_vref_0f,
- },
- [ALC861_FIXUP_NO_JACK_DETECT] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc_fixup_no_jack_detect,
- },
- [ALC861_FIXUP_ASUS_A6RP] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc861_fixup_asus_amp_vref_0f,
- .chained = true,
- .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
- }
-};
-
-static const struct snd_pci_quirk alc861_fixup_tbl[] = {
- SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
- SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
- SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
- SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
- SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
- SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
- {}
-};
-
-/*
- */
-static int patch_alc861(struct hda_codec *codec)
-{
- struct alc_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->spec = spec;
-
- spec->mixer_nid = 0x15;
-
- alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
- alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-
- /* automatic parse from the BIOS config */
- err = alc861_parse_auto_config(codec);
- if (err < 0)
- goto error;
-
- if (!spec->no_analog) {
- err = snd_hda_attach_beep_device(codec, 0x23);
- if (err < 0)
- goto error;
- set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
- }
-
- codec->patch_ops = alc_patch_ops;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- spec->power_hook = alc_power_eapd;
-#endif
-
- alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
- return 0;
-
- error:
- alc_free(codec);
- return err;
-}
-
-/*
- * ALC861-VD support
- *
- * Based on ALC882
- *
- * In addition, an independent DAC
- */
-static int alc861vd_parse_auto_config(struct hda_codec *codec)
-{
- static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
- static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
- return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
-}
-
-enum {
- ALC660VD_FIX_ASUS_GPIO1,
- ALC861VD_FIX_DALLAS,
-};
-
-/* exclude VREF80 */
-static void alc861vd_fixup_dallas(struct hda_codec *codec,
- const struct alc_fixup *fix, int action)
-{
- if (action == ALC_FIXUP_ACT_PRE_PROBE) {
- snd_hda_override_pin_caps(codec, 0x18, 0x00001714);
- snd_hda_override_pin_caps(codec, 0x19, 0x0000171c);
- }
-}
-
-static const struct alc_fixup alc861vd_fixups[] = {
- [ALC660VD_FIX_ASUS_GPIO1] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = (const struct hda_verb[]) {
- /* reset GPIO1 */
- {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
- {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
- {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
- { }
- }
- },
- [ALC861VD_FIX_DALLAS] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc861vd_fixup_dallas,
- },
-};
-
-static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
- SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
- SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
- SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
- {}
-};
-
-static const struct hda_verb alc660vd_eapd_verbs[] = {
- {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
- {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
- { }
-};
-
-/*
- */
-static int patch_alc861vd(struct hda_codec *codec)
-{
- struct alc_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->spec = spec;
-
- spec->mixer_nid = 0x0b;
-
- alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
- alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-
- /* automatic parse from the BIOS config */
- err = alc861vd_parse_auto_config(codec);
- if (err < 0)
- goto error;
-
- if (codec->vendor_id == 0x10ec0660) {
- /* always turn on EAPD */
- add_verb(spec, alc660vd_eapd_verbs);
- }
-
- if (!spec->no_analog) {
- err = snd_hda_attach_beep_device(codec, 0x23);
- if (err < 0)
- goto error;
- set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
- }
-
- codec->patch_ops = alc_patch_ops;
-
- spec->shutup = alc_eapd_shutup;
-
- alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
- return 0;
-
- error:
- alc_free(codec);
- return err;
-}
-
-/*
- * ALC662 support
- *
- * ALC662 is almost identical with ALC880 but has cleaner and more flexible
- * configuration. Each pin widget can choose any input DACs and a mixer.
- * Each ADC is connected from a mixer of all inputs. This makes possible
- * 6-channel independent captures.
- *
- * In addition, an independent DAC for the multi-playback (not used in this
- * driver yet).
- */
-
-/*
- * BIOS auto configuration
- */
-
-static int alc662_parse_auto_config(struct hda_codec *codec)
-{
- static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
- static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
- static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
- const hda_nid_t *ssids;
-
- if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
- codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
- ssids = alc663_ssids;
- else
- ssids = alc662_ssids;
- return alc_parse_auto_config(codec, alc662_ignore, ssids);
-}
-
-static void alc272_fixup_mario(struct hda_codec *codec,
- const struct alc_fixup *fix, int action)
-{
- if (action != ALC_FIXUP_ACT_PROBE)
- return;
- if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
- (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
- (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
- (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
- (0 << AC_AMPCAP_MUTE_SHIFT)))
- printk(KERN_WARNING
- "hda_codec: failed to override amp caps for NID 0x2\n");
-}
-
-enum {
- ALC662_FIXUP_ASPIRE,
- ALC662_FIXUP_IDEAPAD,
- ALC272_FIXUP_MARIO,
- ALC662_FIXUP_CZC_P10T,
- ALC662_FIXUP_SKU_IGNORE,
- ALC662_FIXUP_HP_RP5800,
- ALC662_FIXUP_ASUS_MODE1,
- ALC662_FIXUP_ASUS_MODE2,
- ALC662_FIXUP_ASUS_MODE3,
- ALC662_FIXUP_ASUS_MODE4,
- ALC662_FIXUP_ASUS_MODE5,
- ALC662_FIXUP_ASUS_MODE6,
- ALC662_FIXUP_ASUS_MODE7,
- ALC662_FIXUP_ASUS_MODE8,
- ALC662_FIXUP_NO_JACK_DETECT,
- ALC662_FIXUP_ZOTAC_Z68,
-};
-
-static const struct alc_fixup alc662_fixups[] = {
- [ALC662_FIXUP_ASPIRE] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x15, 0x99130112 }, /* subwoofer */
- { }
- }
- },
- [ALC662_FIXUP_IDEAPAD] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x17, 0x99130112 }, /* subwoofer */
- { }
- }
- },
- [ALC272_FIXUP_MARIO] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc272_fixup_mario,
- },
- [ALC662_FIXUP_CZC_P10T] = {
- .type = ALC_FIXUP_VERBS,
- .v.verbs = (const struct hda_verb[]) {
- {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
- {}
- }
- },
- [ALC662_FIXUP_SKU_IGNORE] = {
- .type = ALC_FIXUP_SKU,
- .v.sku = ALC_FIXUP_SKU_IGNORE,
- },
- [ALC662_FIXUP_HP_RP5800] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x14, 0x0221201f }, /* HP out */
- { }
- },
- .chained = true,
- .chain_id = ALC662_FIXUP_SKU_IGNORE
- },
- [ALC662_FIXUP_ASUS_MODE1] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x14, 0x99130110 }, /* speaker */
- { 0x18, 0x01a19c20 }, /* mic */
- { 0x19, 0x99a3092f }, /* int-mic */
- { 0x21, 0x0121401f }, /* HP out */
- { }
- },
- .chained = true,
- .chain_id = ALC662_FIXUP_SKU_IGNORE
- },
- [ALC662_FIXUP_ASUS_MODE2] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x14, 0x99130110 }, /* speaker */
- { 0x18, 0x01a19820 }, /* mic */
- { 0x19, 0x99a3092f }, /* int-mic */
- { 0x1b, 0x0121401f }, /* HP out */
- { }
- },
- .chained = true,
- .chain_id = ALC662_FIXUP_SKU_IGNORE
- },
- [ALC662_FIXUP_ASUS_MODE3] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x14, 0x99130110 }, /* speaker */
- { 0x15, 0x0121441f }, /* HP */
- { 0x18, 0x01a19840 }, /* mic */
- { 0x19, 0x99a3094f }, /* int-mic */
- { 0x21, 0x01211420 }, /* HP2 */
- { }
- },
- .chained = true,
- .chain_id = ALC662_FIXUP_SKU_IGNORE
- },
- [ALC662_FIXUP_ASUS_MODE4] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x14, 0x99130110 }, /* speaker */
- { 0x16, 0x99130111 }, /* speaker */
- { 0x18, 0x01a19840 }, /* mic */
- { 0x19, 0x99a3094f }, /* int-mic */
- { 0x21, 0x0121441f }, /* HP */
- { }
- },
- .chained = true,
- .chain_id = ALC662_FIXUP_SKU_IGNORE
- },
- [ALC662_FIXUP_ASUS_MODE5] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x14, 0x99130110 }, /* speaker */
- { 0x15, 0x0121441f }, /* HP */
- { 0x16, 0x99130111 }, /* speaker */
- { 0x18, 0x01a19840 }, /* mic */
- { 0x19, 0x99a3094f }, /* int-mic */
- { }
- },
- .chained = true,
- .chain_id = ALC662_FIXUP_SKU_IGNORE
- },
- [ALC662_FIXUP_ASUS_MODE6] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x14, 0x99130110 }, /* speaker */
- { 0x15, 0x01211420 }, /* HP2 */
- { 0x18, 0x01a19840 }, /* mic */
- { 0x19, 0x99a3094f }, /* int-mic */
- { 0x1b, 0x0121441f }, /* HP */
- { }
- },
- .chained = true,
- .chain_id = ALC662_FIXUP_SKU_IGNORE
- },
- [ALC662_FIXUP_ASUS_MODE7] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x14, 0x99130110 }, /* speaker */
- { 0x17, 0x99130111 }, /* speaker */
- { 0x18, 0x01a19840 }, /* mic */
- { 0x19, 0x99a3094f }, /* int-mic */
- { 0x1b, 0x01214020 }, /* HP */
- { 0x21, 0x0121401f }, /* HP */
- { }
- },
- .chained = true,
- .chain_id = ALC662_FIXUP_SKU_IGNORE
- },
- [ALC662_FIXUP_ASUS_MODE8] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x14, 0x99130110 }, /* speaker */
- { 0x12, 0x99a30970 }, /* int-mic */
- { 0x15, 0x01214020 }, /* HP */
- { 0x17, 0x99130111 }, /* speaker */
- { 0x18, 0x01a19840 }, /* mic */
- { 0x21, 0x0121401f }, /* HP */
- { }
- },
- .chained = true,
- .chain_id = ALC662_FIXUP_SKU_IGNORE
- },
- [ALC662_FIXUP_NO_JACK_DETECT] = {
- .type = ALC_FIXUP_FUNC,
- .v.func = alc_fixup_no_jack_detect,
- },
- [ALC662_FIXUP_ZOTAC_Z68] = {
- .type = ALC_FIXUP_PINS,
- .v.pins = (const struct alc_pincfg[]) {
- { 0x1b, 0x02214020 }, /* Front HP */
- { }
- }
- },
-};
-
-static const struct snd_pci_quirk alc662_fixup_tbl[] = {
- SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
- SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
- SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
- SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
- SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
- SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
- SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
- SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
- SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
- SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
- SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
- SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
-
-#if 0
- /* Below is a quirk table taken from the old code.
- * Basically the device should work as is without the fixup table.
- * If BIOS doesn't give a proper info, enable the corresponding
- * fixup entry.
- */
- SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
- SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
- SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
- SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
- SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
- SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
- SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
- SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
- SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
- SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
- SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
- SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
- SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
- SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
- SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
- SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
- SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
-#endif
- {}
-};
-
-static const struct alc_model_fixup alc662_fixup_models[] = {
- {.id = ALC272_FIXUP_MARIO, .name = "mario"},
- {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
- {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
- {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
- {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
- {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
- {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
- {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
- {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
- {}
-};
-
-
-/*
- */
-static int patch_alc662(struct hda_codec *codec)
-{
- struct alc_spec *spec;
- int err = 0;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
-
- codec->spec = spec;
-
- spec->mixer_nid = 0x0b;
-
- /* handle multiple HPs as is */
- spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
-
- alc_fix_pll_init(codec, 0x20, 0x04, 15);
-
- err = alc_codec_rename_from_preset(codec);
- if (err < 0)
- goto error;
-
- if ((alc_get_coef0(codec) & (1 << 14)) &&
- codec->bus->pci->subsystem_vendor == 0x1025 &&
- spec->cdefine.platform_type == 1) {
- if (alc_codec_rename(codec, "ALC272X") < 0)
- goto error;
- }
-
- alc_pick_fixup(codec, alc662_fixup_models,
- alc662_fixup_tbl, alc662_fixups);
- alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-
- alc_auto_parse_customize_define(codec);
-
- /* automatic parse from the BIOS config */
- err = alc662_parse_auto_config(codec);
- if (err < 0)
- goto error;
-
- if (!spec->no_analog && has_cdefine_beep(codec)) {
- err = snd_hda_attach_beep_device(codec, 0x1);
- if (err < 0)
- goto error;
- switch (codec->vendor_id) {
- case 0x10ec0662:
- set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
- break;
- case 0x10ec0272:
- case 0x10ec0663:
- case 0x10ec0665:
- set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
- break;
- case 0x10ec0273:
- set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
- break;
- }
- }
-
- codec->patch_ops = alc_patch_ops;
- spec->shutup = alc_eapd_shutup;
-
- alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
- return 0;
-
- error:
- alc_free(codec);
- return err;
-}
-
-/*
- * ALC680 support
- */
-
-static int alc680_parse_auto_config(struct hda_codec *codec)
-{
- return alc_parse_auto_config(codec, NULL, NULL);
-}
-
-/*
- */
-static int patch_alc680(struct hda_codec *codec)
-{
- struct alc_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->spec = spec;
-
- /* ALC680 has no aa-loopback mixer */
-
- /* automatic parse from the BIOS config */
- err = alc680_parse_auto_config(codec);
- if (err < 0) {
- alc_free(codec);
- return err;
- }
-
- codec->patch_ops = alc_patch_ops;
-
- return 0;
-}
-
-/*
- * patch entries
- */
-static const struct hda_codec_preset snd_hda_preset_realtek[] = {
- { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
- { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
- { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
- { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
- { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
- { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
- { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
- { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
- { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
- { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
- { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 },
- { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
- .patch = patch_alc861 },
- { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
- { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
- { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
- { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
- .patch = patch_alc882 },
- { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
- .patch = patch_alc662 },
- { .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3",
- .patch = patch_alc662 },
- { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
- { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
- { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
- { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
- { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
- { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
- { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
- { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
- .patch = patch_alc882 },
- { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
- .patch = patch_alc882 },
- { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
- { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
- { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
- .patch = patch_alc882 },
- { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
- { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
- { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
- { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 },
- {} /* terminator */
-};
-
-MODULE_ALIAS("snd-hda-codec-id:10ec*");
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Realtek HD-audio codec");
-
-static struct hda_codec_preset_list realtek_list = {
- .preset = snd_hda_preset_realtek,
- .owner = THIS_MODULE,
-};
-
-static int __init patch_realtek_init(void)
-{
- return snd_hda_add_codec_preset(&realtek_list);
-}
-
-static void __exit patch_realtek_exit(void)
-{
- snd_hda_delete_codec_preset(&realtek_list);
-}
-
-module_init(patch_realtek_init)
-module_exit(patch_realtek_exit)
diff --git a/ANDROID_3.4.5/sound/pci/hda/patch_si3054.c b/ANDROID_3.4.5/sound/pci/hda/patch_si3054.c
deleted file mode 100644
index 6679a509..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/patch_si3054.c
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Universal Interface for Intel High Definition Audio Codec
- *
- * HD audio interface patch for Silicon Labs 3054/5 modem codec
- *
- * Copyright (c) 2005 Sasha Khapyorsky <sashak@alsa-project.org>
- * Takashi Iwai <tiwai@suse.de>
- *
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include "hda_codec.h"
-#include "hda_local.h"
-
-/* si3054 verbs */
-#define SI3054_VERB_READ_NODE 0x900
-#define SI3054_VERB_WRITE_NODE 0x100
-
-/* si3054 nodes (registers) */
-#define SI3054_EXTENDED_MID 2
-#define SI3054_LINE_RATE 3
-#define SI3054_LINE_LEVEL 4
-#define SI3054_GPIO_CFG 5
-#define SI3054_GPIO_POLARITY 6
-#define SI3054_GPIO_STICKY 7
-#define SI3054_GPIO_WAKEUP 8
-#define SI3054_GPIO_STATUS 9
-#define SI3054_GPIO_CONTROL 10
-#define SI3054_MISC_AFE 11
-#define SI3054_CHIPID 12
-#define SI3054_LINE_CFG1 13
-#define SI3054_LINE_STATUS 14
-#define SI3054_DC_TERMINATION 15
-#define SI3054_LINE_CONFIG 16
-#define SI3054_CALLPROG_ATT 17
-#define SI3054_SQ_CONTROL 18
-#define SI3054_MISC_CONTROL 19
-#define SI3054_RING_CTRL1 20
-#define SI3054_RING_CTRL2 21
-
-/* extended MID */
-#define SI3054_MEI_READY 0xf
-
-/* line level */
-#define SI3054_ATAG_MASK 0x00f0
-#define SI3054_DTAG_MASK 0xf000
-
-/* GPIO bits */
-#define SI3054_GPIO_OH 0x0001
-#define SI3054_GPIO_CID 0x0002
-
-/* chipid and revisions */
-#define SI3054_CHIPID_CODEC_REV_MASK 0x000f
-#define SI3054_CHIPID_DAA_REV_MASK 0x00f0
-#define SI3054_CHIPID_INTERNATIONAL 0x0100
-#define SI3054_CHIPID_DAA_ID 0x0f00
-#define SI3054_CHIPID_CODEC_ID (1<<12)
-
-/* si3054 codec registers (nodes) access macros */
-#define GET_REG(codec,reg) (snd_hda_codec_read(codec,reg,0,SI3054_VERB_READ_NODE,0))
-#define SET_REG(codec,reg,val) (snd_hda_codec_write(codec,reg,0,SI3054_VERB_WRITE_NODE,val))
-#define SET_REG_CACHE(codec,reg,val) \
- snd_hda_codec_write_cache(codec,reg,0,SI3054_VERB_WRITE_NODE,val)
-
-
-struct si3054_spec {
- unsigned international;
- struct hda_pcm pcm;
-};
-
-
-/*
- * Modem mixer
- */
-
-#define PRIVATE_VALUE(reg,mask) ((reg<<16)|(mask&0xffff))
-#define PRIVATE_REG(val) ((val>>16)&0xffff)
-#define PRIVATE_MASK(val) (val&0xffff)
-
-#define si3054_switch_info snd_ctl_boolean_mono_info
-
-static int si3054_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *uvalue)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- u16 reg = PRIVATE_REG(kcontrol->private_value);
- u16 mask = PRIVATE_MASK(kcontrol->private_value);
- uvalue->value.integer.value[0] = (GET_REG(codec, reg)) & mask ? 1 : 0 ;
- return 0;
-}
-
-static int si3054_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *uvalue)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- u16 reg = PRIVATE_REG(kcontrol->private_value);
- u16 mask = PRIVATE_MASK(kcontrol->private_value);
- if (uvalue->value.integer.value[0])
- SET_REG_CACHE(codec, reg, (GET_REG(codec, reg)) | mask);
- else
- SET_REG_CACHE(codec, reg, (GET_REG(codec, reg)) & ~mask);
- return 0;
-}
-
-#define SI3054_KCONTROL(kname,reg,mask) { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = kname, \
- .subdevice = HDA_SUBDEV_NID_FLAG | reg, \
- .info = si3054_switch_info, \
- .get = si3054_switch_get, \
- .put = si3054_switch_put, \
- .private_value = PRIVATE_VALUE(reg,mask), \
-}
-
-
-static const struct snd_kcontrol_new si3054_modem_mixer[] = {
- SI3054_KCONTROL("Off-hook Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_OH),
- SI3054_KCONTROL("Caller ID Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_CID),
- {}
-};
-
-static int si3054_build_controls(struct hda_codec *codec)
-{
- return snd_hda_add_new_ctls(codec, si3054_modem_mixer);
-}
-
-
-/*
- * PCM callbacks
- */
-
-static int si3054_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- u16 val;
-
- SET_REG(codec, SI3054_LINE_RATE, substream->runtime->rate);
- val = GET_REG(codec, SI3054_LINE_LEVEL);
- val &= 0xff << (8 * (substream->stream != SNDRV_PCM_STREAM_PLAYBACK));
- val |= ((stream_tag & 0xf) << 4) << (8 * (substream->stream == SNDRV_PCM_STREAM_PLAYBACK));
- SET_REG(codec, SI3054_LINE_LEVEL, val);
-
- snd_hda_codec_setup_stream(codec, hinfo->nid,
- stream_tag, 0, format);
- return 0;
-}
-
-static int si3054_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- static unsigned int rates[] = { 8000, 9600, 16000 };
- static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
- .count = ARRAY_SIZE(rates),
- .list = rates,
- .mask = 0,
- };
- substream->runtime->hw.period_bytes_min = 80;
- return snd_pcm_hw_constraint_list(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
-}
-
-
-static const struct hda_pcm_stream si3054_pcm = {
- .substreams = 1,
- .channels_min = 1,
- .channels_max = 1,
- .nid = 0x1,
- .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_KNOT,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .maxbps = 16,
- .ops = {
- .open = si3054_pcm_open,
- .prepare = si3054_pcm_prepare,
- },
-};
-
-
-static int si3054_build_pcms(struct hda_codec *codec)
-{
- struct si3054_spec *spec = codec->spec;
- struct hda_pcm *info = &spec->pcm;
- codec->num_pcms = 1;
- codec->pcm_info = info;
- info->name = "Si3054 Modem";
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] = si3054_pcm;
- info->stream[SNDRV_PCM_STREAM_CAPTURE] = si3054_pcm;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = codec->mfg;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = codec->mfg;
- info->pcm_type = HDA_PCM_TYPE_MODEM;
- return 0;
-}
-
-
-/*
- * Init part
- */
-
-static int si3054_init(struct hda_codec *codec)
-{
- struct si3054_spec *spec = codec->spec;
- unsigned wait_count;
- u16 val;
-
- snd_hda_codec_write(codec, AC_NODE_ROOT, 0, AC_VERB_SET_CODEC_RESET, 0);
- snd_hda_codec_write(codec, codec->mfg, 0, AC_VERB_SET_STREAM_FORMAT, 0);
- SET_REG(codec, SI3054_LINE_RATE, 9600);
- SET_REG(codec, SI3054_LINE_LEVEL, SI3054_DTAG_MASK|SI3054_ATAG_MASK);
- SET_REG(codec, SI3054_EXTENDED_MID, 0);
-
- wait_count = 10;
- do {
- msleep(2);
- val = GET_REG(codec, SI3054_EXTENDED_MID);
- } while ((val & SI3054_MEI_READY) != SI3054_MEI_READY && wait_count--);
-
- if((val&SI3054_MEI_READY) != SI3054_MEI_READY) {
- snd_printk(KERN_ERR "si3054: cannot initialize. EXT MID = %04x\n", val);
- /* let's pray that this is no fatal error */
- /* return -EACCES; */
- }
-
- SET_REG(codec, SI3054_GPIO_POLARITY, 0xffff);
- SET_REG(codec, SI3054_GPIO_CFG, 0x0);
- SET_REG(codec, SI3054_MISC_AFE, 0);
- SET_REG(codec, SI3054_LINE_CFG1,0x200);
-
- if((GET_REG(codec,SI3054_LINE_STATUS) & (1<<6)) == 0) {
- snd_printd("Link Frame Detect(FDT) is not ready (line status: %04x)\n",
- GET_REG(codec,SI3054_LINE_STATUS));
- }
-
- spec->international = GET_REG(codec, SI3054_CHIPID) & SI3054_CHIPID_INTERNATIONAL;
-
- return 0;
-}
-
-static void si3054_free(struct hda_codec *codec)
-{
- kfree(codec->spec);
-}
-
-
-/*
- */
-
-static const struct hda_codec_ops si3054_patch_ops = {
- .build_controls = si3054_build_controls,
- .build_pcms = si3054_build_pcms,
- .init = si3054_init,
- .free = si3054_free,
-};
-
-static int patch_si3054(struct hda_codec *codec)
-{
- struct si3054_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
- codec->spec = spec;
- codec->patch_ops = si3054_patch_ops;
- return 0;
-}
-
-/*
- * patch entries
- */
-static const struct hda_codec_preset snd_hda_preset_si3054[] = {
- { .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 },
- { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 },
- { .id = 0x11c13026, .name = "Si3054", .patch = patch_si3054 },
- { .id = 0x11c13055, .name = "Si3054", .patch = patch_si3054 },
- { .id = 0x11c13155, .name = "Si3054", .patch = patch_si3054 },
- { .id = 0x10573055, .name = "Si3054", .patch = patch_si3054 },
- { .id = 0x10573057, .name = "Si3054", .patch = patch_si3054 },
- { .id = 0x10573155, .name = "Si3054", .patch = patch_si3054 },
- /* VIA HDA on Clevo m540 */
- { .id = 0x11063288, .name = "Si3054", .patch = patch_si3054 },
- /* Asus A8J Modem (SM56) */
- { .id = 0x15433155, .name = "Si3054", .patch = patch_si3054 },
- /* LG LW20 modem */
- { .id = 0x18540018, .name = "Si3054", .patch = patch_si3054 },
- {}
-};
-
-MODULE_ALIAS("snd-hda-codec-id:163c3055");
-MODULE_ALIAS("snd-hda-codec-id:163c3155");
-MODULE_ALIAS("snd-hda-codec-id:11c13026");
-MODULE_ALIAS("snd-hda-codec-id:11c13055");
-MODULE_ALIAS("snd-hda-codec-id:11c13155");
-MODULE_ALIAS("snd-hda-codec-id:10573055");
-MODULE_ALIAS("snd-hda-codec-id:10573057");
-MODULE_ALIAS("snd-hda-codec-id:10573155");
-MODULE_ALIAS("snd-hda-codec-id:11063288");
-MODULE_ALIAS("snd-hda-codec-id:15433155");
-MODULE_ALIAS("snd-hda-codec-id:18540018");
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Si3054 HD-audio modem codec");
-
-static struct hda_codec_preset_list si3054_list = {
- .preset = snd_hda_preset_si3054,
- .owner = THIS_MODULE,
-};
-
-static int __init patch_si3054_init(void)
-{
- return snd_hda_add_codec_preset(&si3054_list);
-}
-
-static void __exit patch_si3054_exit(void)
-{
- snd_hda_delete_codec_preset(&si3054_list);
-}
-
-module_init(patch_si3054_init)
-module_exit(patch_si3054_exit)
diff --git a/ANDROID_3.4.5/sound/pci/hda/patch_sigmatel.c b/ANDROID_3.4.5/sound/pci/hda/patch_sigmatel.c
deleted file mode 100644
index 7494fbc1..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/patch_sigmatel.c
+++ /dev/null
@@ -1,6515 +0,0 @@
-/*
- * Universal Interface for Intel High Definition Audio Codec
- *
- * HD audio interface patch for SigmaTel STAC92xx
- *
- * Copyright (c) 2005 Embedded Alley Solutions, Inc.
- * Matt Porter <mporter@embeddedalley.com>
- *
- * Based on patch_cmedia.c and patch_realtek.c
- * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/dmi.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/asoundef.h>
-#include <sound/jack.h>
-#include <sound/tlv.h>
-#include "hda_codec.h"
-#include "hda_local.h"
-#include "hda_beep.h"
-#include "hda_jack.h"
-
-enum {
- STAC_VREF_EVENT = 1,
- STAC_INSERT_EVENT,
- STAC_PWR_EVENT,
- STAC_HP_EVENT,
- STAC_LO_EVENT,
- STAC_MIC_EVENT,
-};
-
-enum {
- STAC_AUTO,
- STAC_REF,
- STAC_9200_OQO,
- STAC_9200_DELL_D21,
- STAC_9200_DELL_D22,
- STAC_9200_DELL_D23,
- STAC_9200_DELL_M21,
- STAC_9200_DELL_M22,
- STAC_9200_DELL_M23,
- STAC_9200_DELL_M24,
- STAC_9200_DELL_M25,
- STAC_9200_DELL_M26,
- STAC_9200_DELL_M27,
- STAC_9200_M4,
- STAC_9200_M4_2,
- STAC_9200_PANASONIC,
- STAC_9200_MODELS
-};
-
-enum {
- STAC_9205_AUTO,
- STAC_9205_REF,
- STAC_9205_DELL_M42,
- STAC_9205_DELL_M43,
- STAC_9205_DELL_M44,
- STAC_9205_EAPD,
- STAC_9205_MODELS
-};
-
-enum {
- STAC_92HD73XX_AUTO,
- STAC_92HD73XX_NO_JD, /* no jack-detection */
- STAC_92HD73XX_REF,
- STAC_92HD73XX_INTEL,
- STAC_DELL_M6_AMIC,
- STAC_DELL_M6_DMIC,
- STAC_DELL_M6_BOTH,
- STAC_DELL_EQ,
- STAC_ALIENWARE_M17X,
- STAC_92HD73XX_MODELS
-};
-
-enum {
- STAC_92HD83XXX_AUTO,
- STAC_92HD83XXX_REF,
- STAC_92HD83XXX_PWR_REF,
- STAC_DELL_S14,
- STAC_DELL_VOSTRO_3500,
- STAC_92HD83XXX_HP_cNB11_INTQUAD,
- STAC_HP_DV7_4000,
- STAC_HP_ZEPHYR,
- STAC_92HD83XXX_MODELS
-};
-
-enum {
- STAC_92HD71BXX_AUTO,
- STAC_92HD71BXX_REF,
- STAC_DELL_M4_1,
- STAC_DELL_M4_2,
- STAC_DELL_M4_3,
- STAC_HP_M4,
- STAC_HP_DV4,
- STAC_HP_DV5,
- STAC_HP_HDX,
- STAC_HP_DV4_1222NR,
- STAC_92HD71BXX_MODELS
-};
-
-enum {
- STAC_925x_AUTO,
- STAC_925x_REF,
- STAC_M1,
- STAC_M1_2,
- STAC_M2,
- STAC_M2_2,
- STAC_M3,
- STAC_M5,
- STAC_M6,
- STAC_925x_MODELS
-};
-
-enum {
- STAC_922X_AUTO,
- STAC_D945_REF,
- STAC_D945GTP3,
- STAC_D945GTP5,
- STAC_INTEL_MAC_V1,
- STAC_INTEL_MAC_V2,
- STAC_INTEL_MAC_V3,
- STAC_INTEL_MAC_V4,
- STAC_INTEL_MAC_V5,
- STAC_INTEL_MAC_AUTO, /* This model is selected if no module parameter
- * is given, one of the above models will be
- * chosen according to the subsystem id. */
- /* for backward compatibility */
- STAC_MACMINI,
- STAC_MACBOOK,
- STAC_MACBOOK_PRO_V1,
- STAC_MACBOOK_PRO_V2,
- STAC_IMAC_INTEL,
- STAC_IMAC_INTEL_20,
- STAC_ECS_202,
- STAC_922X_DELL_D81,
- STAC_922X_DELL_D82,
- STAC_922X_DELL_M81,
- STAC_922X_DELL_M82,
- STAC_922X_MODELS
-};
-
-enum {
- STAC_927X_AUTO,
- STAC_D965_REF_NO_JD, /* no jack-detection */
- STAC_D965_REF,
- STAC_D965_3ST,
- STAC_D965_5ST,
- STAC_D965_5ST_NO_FP,
- STAC_DELL_3ST,
- STAC_DELL_BIOS,
- STAC_927X_VOLKNOB,
- STAC_927X_MODELS
-};
-
-enum {
- STAC_9872_AUTO,
- STAC_9872_VAIO,
- STAC_9872_MODELS
-};
-
-struct sigmatel_mic_route {
- hda_nid_t pin;
- signed char mux_idx;
- signed char dmux_idx;
-};
-
-#define MAX_PINS_NUM 16
-#define MAX_ADCS_NUM 4
-#define MAX_DMICS_NUM 4
-
-struct sigmatel_spec {
- struct snd_kcontrol_new *mixers[4];
- unsigned int num_mixers;
-
- int board_config;
- unsigned int eapd_switch: 1;
- unsigned int surr_switch: 1;
- unsigned int alt_switch: 1;
- unsigned int hp_detect: 1;
- unsigned int spdif_mute: 1;
- unsigned int check_volume_offset:1;
- unsigned int auto_mic:1;
- unsigned int linear_tone_beep:1;
-
- /* gpio lines */
- unsigned int eapd_mask;
- unsigned int gpio_mask;
- unsigned int gpio_dir;
- unsigned int gpio_data;
- unsigned int gpio_mute;
- unsigned int gpio_led;
- unsigned int gpio_led_polarity;
- unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */
- unsigned int vref_led;
-
- /* stream */
- unsigned int stream_delay;
-
- /* analog loopback */
- const struct snd_kcontrol_new *aloopback_ctl;
- unsigned char aloopback_mask;
- unsigned char aloopback_shift;
-
- /* power management */
- unsigned int num_pwrs;
- const hda_nid_t *pwr_nids;
- const hda_nid_t *dac_list;
-
- /* playback */
- struct hda_input_mux *mono_mux;
- unsigned int cur_mmux;
- struct hda_multi_out multiout;
- hda_nid_t dac_nids[5];
- hda_nid_t hp_dacs[5];
- hda_nid_t speaker_dacs[5];
-
- int volume_offset;
-
- /* capture */
- const hda_nid_t *adc_nids;
- unsigned int num_adcs;
- const hda_nid_t *mux_nids;
- unsigned int num_muxes;
- const hda_nid_t *dmic_nids;
- unsigned int num_dmics;
- const hda_nid_t *dmux_nids;
- unsigned int num_dmuxes;
- const hda_nid_t *smux_nids;
- unsigned int num_smuxes;
- unsigned int num_analog_muxes;
-
- const unsigned long *capvols; /* amp-volume attr: HDA_COMPOSE_AMP_VAL() */
- const unsigned long *capsws; /* amp-mute attr: HDA_COMPOSE_AMP_VAL() */
- unsigned int num_caps; /* number of capture volume/switch elements */
-
- struct sigmatel_mic_route ext_mic;
- struct sigmatel_mic_route int_mic;
- struct sigmatel_mic_route dock_mic;
-
- const char * const *spdif_labels;
-
- hda_nid_t dig_in_nid;
- hda_nid_t mono_nid;
- hda_nid_t anabeep_nid;
- hda_nid_t digbeep_nid;
-
- /* pin widgets */
- const hda_nid_t *pin_nids;
- unsigned int num_pins;
-
- /* codec specific stuff */
- const struct hda_verb *init;
- const struct snd_kcontrol_new *mixer;
-
- /* capture source */
- struct hda_input_mux *dinput_mux;
- unsigned int cur_dmux[2];
- struct hda_input_mux *input_mux;
- unsigned int cur_mux[3];
- struct hda_input_mux *sinput_mux;
- unsigned int cur_smux[2];
- unsigned int cur_amux;
- hda_nid_t *amp_nids;
- unsigned int powerdown_adcs;
-
- /* i/o switches */
- unsigned int io_switch[2];
- unsigned int clfe_swap;
- hda_nid_t line_switch; /* shared line-in for input and output */
- hda_nid_t mic_switch; /* shared mic-in for input and output */
- hda_nid_t hp_switch; /* NID of HP as line-out */
- unsigned int aloopback;
-
- struct hda_pcm pcm_rec[2]; /* PCM information */
-
- /* dynamic controls and input_mux */
- struct auto_pin_cfg autocfg;
- struct snd_array kctls;
- struct hda_input_mux private_dimux;
- struct hda_input_mux private_imux;
- struct hda_input_mux private_smux;
- struct hda_input_mux private_mono_mux;
-
- /* auto spec */
- unsigned auto_pin_cnt;
- hda_nid_t auto_pin_nids[MAX_PINS_NUM];
- unsigned auto_adc_cnt;
- hda_nid_t auto_adc_nids[MAX_ADCS_NUM];
- hda_nid_t auto_mux_nids[MAX_ADCS_NUM];
- hda_nid_t auto_dmux_nids[MAX_ADCS_NUM];
- unsigned long auto_capvols[MAX_ADCS_NUM];
- unsigned auto_dmic_cnt;
- hda_nid_t auto_dmic_nids[MAX_DMICS_NUM];
-
- struct hda_vmaster_mute_hook vmaster_mute;
-};
-
-static const hda_nid_t stac9200_adc_nids[1] = {
- 0x03,
-};
-
-static const hda_nid_t stac9200_mux_nids[1] = {
- 0x0c,
-};
-
-static const hda_nid_t stac9200_dac_nids[1] = {
- 0x02,
-};
-
-static const hda_nid_t stac92hd73xx_pwr_nids[8] = {
- 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
- 0x0f, 0x10, 0x11
-};
-
-static const hda_nid_t stac92hd73xx_slave_dig_outs[2] = {
- 0x26, 0,
-};
-
-static const hda_nid_t stac92hd73xx_adc_nids[2] = {
- 0x1a, 0x1b
-};
-
-#define STAC92HD73XX_NUM_DMICS 2
-static const hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = {
- 0x13, 0x14, 0
-};
-
-#define STAC92HD73_DAC_COUNT 5
-
-static const hda_nid_t stac92hd73xx_mux_nids[2] = {
- 0x20, 0x21,
-};
-
-static const hda_nid_t stac92hd73xx_dmux_nids[2] = {
- 0x20, 0x21,
-};
-
-static const hda_nid_t stac92hd73xx_smux_nids[2] = {
- 0x22, 0x23,
-};
-
-#define STAC92HD73XX_NUM_CAPS 2
-static const unsigned long stac92hd73xx_capvols[] = {
- HDA_COMPOSE_AMP_VAL(0x20, 3, 0, HDA_OUTPUT),
- HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
-};
-#define stac92hd73xx_capsws stac92hd73xx_capvols
-
-#define STAC92HD83_DAC_COUNT 3
-
-static const hda_nid_t stac92hd83xxx_pwr_nids[7] = {
- 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
- 0x0f, 0x10
-};
-
-static const hda_nid_t stac92hd83xxx_slave_dig_outs[2] = {
- 0x1e, 0,
-};
-
-static const hda_nid_t stac92hd83xxx_dmic_nids[] = {
- 0x11, 0x20,
-};
-
-static const hda_nid_t stac92hd71bxx_pwr_nids[3] = {
- 0x0a, 0x0d, 0x0f
-};
-
-static const hda_nid_t stac92hd71bxx_adc_nids[2] = {
- 0x12, 0x13,
-};
-
-static const hda_nid_t stac92hd71bxx_mux_nids[2] = {
- 0x1a, 0x1b
-};
-
-static const hda_nid_t stac92hd71bxx_dmux_nids[2] = {
- 0x1c, 0x1d,
-};
-
-static const hda_nid_t stac92hd71bxx_smux_nids[2] = {
- 0x24, 0x25,
-};
-
-#define STAC92HD71BXX_NUM_DMICS 2
-static const hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = {
- 0x18, 0x19, 0
-};
-
-static const hda_nid_t stac92hd71bxx_dmic_5port_nids[STAC92HD71BXX_NUM_DMICS] = {
- 0x18, 0
-};
-
-static const hda_nid_t stac92hd71bxx_slave_dig_outs[2] = {
- 0x22, 0
-};
-
-#define STAC92HD71BXX_NUM_CAPS 2
-static const unsigned long stac92hd71bxx_capvols[] = {
- HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT),
- HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
-};
-#define stac92hd71bxx_capsws stac92hd71bxx_capvols
-
-static const hda_nid_t stac925x_adc_nids[1] = {
- 0x03,
-};
-
-static const hda_nid_t stac925x_mux_nids[1] = {
- 0x0f,
-};
-
-static const hda_nid_t stac925x_dac_nids[1] = {
- 0x02,
-};
-
-#define STAC925X_NUM_DMICS 1
-static const hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = {
- 0x15, 0
-};
-
-static const hda_nid_t stac925x_dmux_nids[1] = {
- 0x14,
-};
-
-static const unsigned long stac925x_capvols[] = {
- HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
-};
-static const unsigned long stac925x_capsws[] = {
- HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
-};
-
-static const hda_nid_t stac922x_adc_nids[2] = {
- 0x06, 0x07,
-};
-
-static const hda_nid_t stac922x_mux_nids[2] = {
- 0x12, 0x13,
-};
-
-#define STAC922X_NUM_CAPS 2
-static const unsigned long stac922x_capvols[] = {
- HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT),
- HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT),
-};
-#define stac922x_capsws stac922x_capvols
-
-static const hda_nid_t stac927x_slave_dig_outs[2] = {
- 0x1f, 0,
-};
-
-static const hda_nid_t stac927x_adc_nids[3] = {
- 0x07, 0x08, 0x09
-};
-
-static const hda_nid_t stac927x_mux_nids[3] = {
- 0x15, 0x16, 0x17
-};
-
-static const hda_nid_t stac927x_smux_nids[1] = {
- 0x21,
-};
-
-static const hda_nid_t stac927x_dac_nids[6] = {
- 0x02, 0x03, 0x04, 0x05, 0x06, 0
-};
-
-static const hda_nid_t stac927x_dmux_nids[1] = {
- 0x1b,
-};
-
-#define STAC927X_NUM_DMICS 2
-static const hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = {
- 0x13, 0x14, 0
-};
-
-#define STAC927X_NUM_CAPS 3
-static const unsigned long stac927x_capvols[] = {
- HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT),
- HDA_COMPOSE_AMP_VAL(0x19, 3, 0, HDA_INPUT),
- HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_INPUT),
-};
-static const unsigned long stac927x_capsws[] = {
- HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
- HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT),
- HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
-};
-
-static const char * const stac927x_spdif_labels[5] = {
- "Digital Playback", "ADAT", "Analog Mux 1",
- "Analog Mux 2", "Analog Mux 3"
-};
-
-static const hda_nid_t stac9205_adc_nids[2] = {
- 0x12, 0x13
-};
-
-static const hda_nid_t stac9205_mux_nids[2] = {
- 0x19, 0x1a
-};
-
-static const hda_nid_t stac9205_dmux_nids[1] = {
- 0x1d,
-};
-
-static const hda_nid_t stac9205_smux_nids[1] = {
- 0x21,
-};
-
-#define STAC9205_NUM_DMICS 2
-static const hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
- 0x17, 0x18, 0
-};
-
-#define STAC9205_NUM_CAPS 2
-static const unsigned long stac9205_capvols[] = {
- HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_INPUT),
- HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_INPUT),
-};
-static const unsigned long stac9205_capsws[] = {
- HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
- HDA_COMPOSE_AMP_VAL(0x1e, 3, 0, HDA_OUTPUT),
-};
-
-static const hda_nid_t stac9200_pin_nids[8] = {
- 0x08, 0x09, 0x0d, 0x0e,
- 0x0f, 0x10, 0x11, 0x12,
-};
-
-static const hda_nid_t stac925x_pin_nids[8] = {
- 0x07, 0x08, 0x0a, 0x0b,
- 0x0c, 0x0d, 0x10, 0x11,
-};
-
-static const hda_nid_t stac922x_pin_nids[10] = {
- 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
- 0x0f, 0x10, 0x11, 0x15, 0x1b,
-};
-
-static const hda_nid_t stac92hd73xx_pin_nids[13] = {
- 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
- 0x0f, 0x10, 0x11, 0x12, 0x13,
- 0x14, 0x22, 0x23
-};
-
-#define STAC92HD71BXX_NUM_PINS 13
-static const hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = {
- 0x0a, 0x0b, 0x0c, 0x0d, 0x00,
- 0x00, 0x14, 0x18, 0x19, 0x1e,
- 0x1f, 0x20, 0x27
-};
-static const hda_nid_t stac92hd71bxx_pin_nids_6port[STAC92HD71BXX_NUM_PINS] = {
- 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
- 0x0f, 0x14, 0x18, 0x19, 0x1e,
- 0x1f, 0x20, 0x27
-};
-
-static const hda_nid_t stac927x_pin_nids[14] = {
- 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
- 0x0f, 0x10, 0x11, 0x12, 0x13,
- 0x14, 0x21, 0x22, 0x23,
-};
-
-static const hda_nid_t stac9205_pin_nids[12] = {
- 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
- 0x0f, 0x14, 0x16, 0x17, 0x18,
- 0x21, 0x22,
-};
-
-static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
- return snd_hda_input_mux_info(spec->dinput_mux, uinfo);
-}
-
-static int stac92xx_dmux_enum_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
- unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-
- ucontrol->value.enumerated.item[0] = spec->cur_dmux[dmux_idx];
- return 0;
-}
-
-static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
- unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-
- return snd_hda_input_mux_put(codec, spec->dinput_mux, ucontrol,
- spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]);
-}
-
-static int stac92xx_smux_enum_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
- return snd_hda_input_mux_info(spec->sinput_mux, uinfo);
-}
-
-static int stac92xx_smux_enum_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
- unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-
- ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx];
- return 0;
-}
-
-static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
- struct hda_input_mux *smux = &spec->private_smux;
- unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- int err, val;
- hda_nid_t nid;
-
- err = snd_hda_input_mux_put(codec, spec->sinput_mux, ucontrol,
- spec->smux_nids[smux_idx], &spec->cur_smux[smux_idx]);
- if (err < 0)
- return err;
-
- if (spec->spdif_mute) {
- if (smux_idx == 0)
- nid = spec->multiout.dig_out_nid;
- else
- nid = codec->slave_dig_outs[smux_idx - 1];
- if (spec->cur_smux[smux_idx] == smux->num_items - 1)
- val = HDA_AMP_MUTE;
- else
- val = 0;
- /* un/mute SPDIF out */
- snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, val);
- }
- return 0;
-}
-
-static int stac_vrefout_set(struct hda_codec *codec,
- hda_nid_t nid, unsigned int new_vref)
-{
- int error, pinctl;
-
- snd_printdd("%s, nid %x ctl %x\n", __func__, nid, new_vref);
- pinctl = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
-
- if (pinctl < 0)
- return pinctl;
-
- pinctl &= 0xff;
- pinctl &= ~AC_PINCTL_VREFEN;
- pinctl |= (new_vref & AC_PINCTL_VREFEN);
-
- error = snd_hda_codec_write_cache(codec, nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
- if (error < 0)
- return error;
-
- return 1;
-}
-
-static unsigned int stac92xx_vref_set(struct hda_codec *codec,
- hda_nid_t nid, unsigned int new_vref)
-{
- int error;
- unsigned int pincfg;
- pincfg = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
-
- pincfg &= 0xff;
- pincfg &= ~(AC_PINCTL_VREFEN | AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
- pincfg |= new_vref;
-
- if (new_vref == AC_PINCTL_VREF_HIZ)
- pincfg |= AC_PINCTL_OUT_EN;
- else
- pincfg |= AC_PINCTL_IN_EN;
-
- error = snd_hda_codec_write_cache(codec, nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, pincfg);
- if (error < 0)
- return error;
- else
- return 1;
-}
-
-static unsigned int stac92xx_vref_get(struct hda_codec *codec, hda_nid_t nid)
-{
- unsigned int vref;
- vref = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
- vref &= AC_PINCTL_VREFEN;
- return vref;
-}
-
-static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
- return snd_hda_input_mux_info(spec->input_mux, uinfo);
-}
-
-static int stac92xx_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
- unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-
- ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
- return 0;
-}
-
-static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
- unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- const struct hda_input_mux *imux = spec->input_mux;
- unsigned int idx, prev_idx, didx;
-
- idx = ucontrol->value.enumerated.item[0];
- if (idx >= imux->num_items)
- idx = imux->num_items - 1;
- prev_idx = spec->cur_mux[adc_idx];
- if (prev_idx == idx)
- return 0;
- if (idx < spec->num_analog_muxes) {
- snd_hda_codec_write_cache(codec, spec->mux_nids[adc_idx], 0,
- AC_VERB_SET_CONNECT_SEL,
- imux->items[idx].index);
- if (prev_idx >= spec->num_analog_muxes &&
- spec->mux_nids[adc_idx] != spec->dmux_nids[adc_idx]) {
- imux = spec->dinput_mux;
- /* 0 = analog */
- snd_hda_codec_write_cache(codec,
- spec->dmux_nids[adc_idx], 0,
- AC_VERB_SET_CONNECT_SEL,
- imux->items[0].index);
- }
- } else {
- imux = spec->dinput_mux;
- /* first dimux item is hardcoded to select analog imux,
- * so lets skip it
- */
- didx = idx - spec->num_analog_muxes + 1;
- snd_hda_codec_write_cache(codec, spec->dmux_nids[adc_idx], 0,
- AC_VERB_SET_CONNECT_SEL,
- imux->items[didx].index);
- }
- spec->cur_mux[adc_idx] = idx;
- return 1;
-}
-
-static int stac92xx_mono_mux_enum_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
- return snd_hda_input_mux_info(spec->mono_mux, uinfo);
-}
-
-static int stac92xx_mono_mux_enum_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
-
- ucontrol->value.enumerated.item[0] = spec->cur_mmux;
- return 0;
-}
-
-static int stac92xx_mono_mux_enum_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
-
- return snd_hda_input_mux_put(codec, spec->mono_mux, ucontrol,
- spec->mono_nid, &spec->cur_mmux);
-}
-
-#define stac92xx_aloopback_info snd_ctl_boolean_mono_info
-
-static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- struct sigmatel_spec *spec = codec->spec;
-
- ucontrol->value.integer.value[0] = !!(spec->aloopback &
- (spec->aloopback_mask << idx));
- return 0;
-}
-
-static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
- unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- unsigned int dac_mode;
- unsigned int val, idx_val;
-
- idx_val = spec->aloopback_mask << idx;
- if (ucontrol->value.integer.value[0])
- val = spec->aloopback | idx_val;
- else
- val = spec->aloopback & ~idx_val;
- if (spec->aloopback == val)
- return 0;
-
- spec->aloopback = val;
-
- /* Only return the bits defined by the shift value of the
- * first two bytes of the mask
- */
- dac_mode = snd_hda_codec_read(codec, codec->afg, 0,
- kcontrol->private_value & 0xFFFF, 0x0);
- dac_mode >>= spec->aloopback_shift;
-
- if (spec->aloopback & idx_val) {
- snd_hda_power_up(codec);
- dac_mode |= idx_val;
- } else {
- snd_hda_power_down(codec);
- dac_mode &= ~idx_val;
- }
-
- snd_hda_codec_write_cache(codec, codec->afg, 0,
- kcontrol->private_value >> 16, dac_mode);
-
- return 1;
-}
-
-static const struct hda_verb stac9200_core_init[] = {
- /* set dac0mux for dac converter */
- { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
- {}
-};
-
-static const struct hda_verb stac9200_eapd_init[] = {
- /* set dac0mux for dac converter */
- {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
- {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
- {}
-};
-
-static const struct hda_verb dell_eq_core_init[] = {
- /* set master volume to max value without distortion
- * and direct control */
- { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
- {}
-};
-
-static const struct hda_verb stac92hd73xx_core_init[] = {
- /* set master volume and direct control */
- { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
- {}
-};
-
-static const struct hda_verb stac92hd83xxx_core_init[] = {
- /* power state controls amps */
- { 0x01, AC_VERB_SET_EAPD, 1 << 2},
- {}
-};
-
-static const struct hda_verb stac92hd83xxx_hp_zephyr_init[] = {
- { 0x22, 0x785, 0x43 },
- { 0x22, 0x782, 0xe0 },
- { 0x22, 0x795, 0x00 },
- {}
-};
-
-static const struct hda_verb stac92hd71bxx_core_init[] = {
- /* set master volume and direct control */
- { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
- {}
-};
-
-static const struct hda_verb stac92hd71bxx_unmute_core_init[] = {
- /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */
- { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {}
-};
-
-static const struct hda_verb stac925x_core_init[] = {
- /* set dac0mux for dac converter */
- { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
- /* mute the master volume */
- { 0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
- {}
-};
-
-static const struct hda_verb stac922x_core_init[] = {
- /* set master volume and direct control */
- { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
- {}
-};
-
-static const struct hda_verb d965_core_init[] = {
- /* set master volume and direct control */
- { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
- /* unmute node 0x1b */
- { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
- /* select node 0x03 as DAC */
- { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
- {}
-};
-
-static const struct hda_verb dell_3st_core_init[] = {
- /* don't set delta bit */
- {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
- /* unmute node 0x1b */
- {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
- /* select node 0x03 as DAC */
- {0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
- {}
-};
-
-static const struct hda_verb stac927x_core_init[] = {
- /* set master volume and direct control */
- { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
- /* enable analog pc beep path */
- { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
- {}
-};
-
-static const struct hda_verb stac927x_volknob_core_init[] = {
- /* don't set delta bit */
- {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
- /* enable analog pc beep path */
- {0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
- {}
-};
-
-static const struct hda_verb stac9205_core_init[] = {
- /* set master volume and direct control */
- { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
- /* enable analog pc beep path */
- { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
- {}
-};
-
-#define STAC_MONO_MUX \
- { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = "Mono Mux", \
- .count = 1, \
- .info = stac92xx_mono_mux_enum_info, \
- .get = stac92xx_mono_mux_enum_get, \
- .put = stac92xx_mono_mux_enum_put, \
- }
-
-#define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \
- { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = "Analog Loopback", \
- .count = cnt, \
- .info = stac92xx_aloopback_info, \
- .get = stac92xx_aloopback_get, \
- .put = stac92xx_aloopback_put, \
- .private_value = verb_read | (verb_write << 16), \
- }
-
-#define DC_BIAS(xname, idx, nid) \
- { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = idx, \
- .info = stac92xx_dc_bias_info, \
- .get = stac92xx_dc_bias_get, \
- .put = stac92xx_dc_bias_put, \
- .private_value = nid, \
- }
-
-static const struct snd_kcontrol_new stac9200_mixer[] = {
- HDA_CODEC_VOLUME_MIN_MUTE("PCM Playback Volume", 0xb, 0, HDA_OUTPUT),
- HDA_CODEC_MUTE("PCM Playback Switch", 0xb, 0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new stac92hd73xx_6ch_loopback[] = {
- STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3),
- {}
-};
-
-static const struct snd_kcontrol_new stac92hd73xx_8ch_loopback[] = {
- STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4),
- {}
-};
-
-static const struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = {
- STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5),
- {}
-};
-
-
-static const struct snd_kcontrol_new stac92hd71bxx_loopback[] = {
- STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2)
-};
-
-static const struct snd_kcontrol_new stac925x_mixer[] = {
- HDA_CODEC_VOLUME_MIN_MUTE("PCM Playback Volume", 0xe, 0, HDA_OUTPUT),
- HDA_CODEC_MUTE("PCM Playback Switch", 0x0e, 0, HDA_OUTPUT),
- { } /* end */
-};
-
-static const struct snd_kcontrol_new stac9205_loopback[] = {
- STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1),
- {}
-};
-
-static const struct snd_kcontrol_new stac927x_loopback[] = {
- STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1),
- {}
-};
-
-static struct snd_kcontrol_new stac_dmux_mixer = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Digital Input Source",
- /* count set later */
- .info = stac92xx_dmux_enum_info,
- .get = stac92xx_dmux_enum_get,
- .put = stac92xx_dmux_enum_put,
-};
-
-static struct snd_kcontrol_new stac_smux_mixer = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "IEC958 Playback Source",
- /* count set later */
- .info = stac92xx_smux_enum_info,
- .get = stac92xx_smux_enum_get,
- .put = stac92xx_smux_enum_put,
-};
-
-static const char * const slave_pfxs[] = {
- "Front", "Surround", "Center", "LFE", "Side",
- "Headphone", "Speaker", "IEC958",
- NULL
-};
-
-static void stac92xx_update_led_status(struct hda_codec *codec, int enabled);
-
-static void stac92xx_vmaster_hook(void *private_data, int val)
-{
- stac92xx_update_led_status(private_data, val);
-}
-
-static void stac92xx_free_kctls(struct hda_codec *codec);
-
-static int stac92xx_build_controls(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
- unsigned int vmaster_tlv[4];
- int err;
- int i;
-
- if (spec->mixer) {
- err = snd_hda_add_new_ctls(codec, spec->mixer);
- if (err < 0)
- return err;
- }
-
- for (i = 0; i < spec->num_mixers; i++) {
- err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
- if (err < 0)
- return err;
- }
- if (!spec->auto_mic && spec->num_dmuxes > 0 &&
- snd_hda_get_bool_hint(codec, "separate_dmux") == 1) {
- stac_dmux_mixer.count = spec->num_dmuxes;
- err = snd_hda_ctl_add(codec, 0,
- snd_ctl_new1(&stac_dmux_mixer, codec));
- if (err < 0)
- return err;
- }
- if (spec->num_smuxes > 0) {
- int wcaps = get_wcaps(codec, spec->multiout.dig_out_nid);
- struct hda_input_mux *smux = &spec->private_smux;
- /* check for mute support on SPDIF out */
- if (wcaps & AC_WCAP_OUT_AMP) {
- snd_hda_add_imux_item(smux, "Off", 0, NULL);
- spec->spdif_mute = 1;
- }
- stac_smux_mixer.count = spec->num_smuxes;
- err = snd_hda_ctl_add(codec, 0,
- snd_ctl_new1(&stac_smux_mixer, codec));
- if (err < 0)
- return err;
- }
-
- if (spec->multiout.dig_out_nid) {
- err = snd_hda_create_spdif_out_ctls(codec,
- spec->multiout.dig_out_nid,
- spec->multiout.dig_out_nid);
- if (err < 0)
- return err;
- err = snd_hda_create_spdif_share_sw(codec,
- &spec->multiout);
- if (err < 0)
- return err;
- spec->multiout.share_spdif = 1;
- }
- if (spec->dig_in_nid && !(spec->gpio_dir & 0x01)) {
- err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
- if (err < 0)
- return err;
- }
-
- /* if we have no master control, let's create it */
- snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
- HDA_OUTPUT, vmaster_tlv);
- /* correct volume offset */
- vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset;
- /* minimum value is actually mute */
- vmaster_tlv[3] |= TLV_DB_SCALE_MUTE;
- err = snd_hda_add_vmaster(codec, "Master Playback Volume",
- vmaster_tlv, slave_pfxs,
- "Playback Volume");
- if (err < 0)
- return err;
-
- err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
- NULL, slave_pfxs,
- "Playback Switch", true,
- &spec->vmaster_mute.sw_kctl);
- if (err < 0)
- return err;
-
- if (spec->gpio_led) {
- spec->vmaster_mute.hook = stac92xx_vmaster_hook;
- err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true);
- if (err < 0)
- return err;
- }
-
- if (spec->aloopback_ctl &&
- snd_hda_get_bool_hint(codec, "loopback") == 1) {
- err = snd_hda_add_new_ctls(codec, spec->aloopback_ctl);
- if (err < 0)
- return err;
- }
-
- stac92xx_free_kctls(codec); /* no longer needed */
-
- err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static const unsigned int ref9200_pin_configs[8] = {
- 0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
- 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
-};
-
-static const unsigned int gateway9200_m4_pin_configs[8] = {
- 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010,
- 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3,
-};
-static const unsigned int gateway9200_m4_2_pin_configs[8] = {
- 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010,
- 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3,
-};
-
-/*
- STAC 9200 pin configs for
- 102801A8
- 102801DE
- 102801E8
-*/
-static const unsigned int dell9200_d21_pin_configs[8] = {
- 0x400001f0, 0x400001f1, 0x02214030, 0x01014010,
- 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
-};
-
-/*
- STAC 9200 pin configs for
- 102801C0
- 102801C1
-*/
-static const unsigned int dell9200_d22_pin_configs[8] = {
- 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
- 0x01813020, 0x02a19021, 0x90100140, 0x400001f2,
-};
-
-/*
- STAC 9200 pin configs for
- 102801C4 (Dell Dimension E310)
- 102801C5
- 102801C7
- 102801D9
- 102801DA
- 102801E3
-*/
-static const unsigned int dell9200_d23_pin_configs[8] = {
- 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
- 0x01813020, 0x01a19021, 0x90100140, 0x400001f2,
-};
-
-
-/*
- STAC 9200-32 pin configs for
- 102801B5 (Dell Inspiron 630m)
- 102801D8 (Dell Inspiron 640m)
-*/
-static const unsigned int dell9200_m21_pin_configs[8] = {
- 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310,
- 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd,
-};
-
-/*
- STAC 9200-32 pin configs for
- 102801C2 (Dell Latitude D620)
- 102801C8
- 102801CC (Dell Latitude D820)
- 102801D4
- 102801D6
-*/
-static const unsigned int dell9200_m22_pin_configs[8] = {
- 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310,
- 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc,
-};
-
-/*
- STAC 9200-32 pin configs for
- 102801CE (Dell XPS M1710)
- 102801CF (Dell Precision M90)
-*/
-static const unsigned int dell9200_m23_pin_configs[8] = {
- 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310,
- 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc,
-};
-
-/*
- STAC 9200-32 pin configs for
- 102801C9
- 102801CA
- 102801CB (Dell Latitude 120L)
- 102801D3
-*/
-static const unsigned int dell9200_m24_pin_configs[8] = {
- 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310,
- 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe,
-};
-
-/*
- STAC 9200-32 pin configs for
- 102801BD (Dell Inspiron E1505n)
- 102801EE
- 102801EF
-*/
-static const unsigned int dell9200_m25_pin_configs[8] = {
- 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
- 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd,
-};
-
-/*
- STAC 9200-32 pin configs for
- 102801F5 (Dell Inspiron 1501)
- 102801F6
-*/
-static const unsigned int dell9200_m26_pin_configs[8] = {
- 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310,
- 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe,
-};
-
-/*
- STAC 9200-32
- 102801CD (Dell Inspiron E1705/9400)
-*/
-static const unsigned int dell9200_m27_pin_configs[8] = {
- 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
- 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc,
-};
-
-static const unsigned int oqo9200_pin_configs[8] = {
- 0x40c000f0, 0x404000f1, 0x0221121f, 0x02211210,
- 0x90170111, 0x90a70120, 0x400000f2, 0x400000f3,
-};
-
-
-static const unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
- [STAC_REF] = ref9200_pin_configs,
- [STAC_9200_OQO] = oqo9200_pin_configs,
- [STAC_9200_DELL_D21] = dell9200_d21_pin_configs,
- [STAC_9200_DELL_D22] = dell9200_d22_pin_configs,
- [STAC_9200_DELL_D23] = dell9200_d23_pin_configs,
- [STAC_9200_DELL_M21] = dell9200_m21_pin_configs,
- [STAC_9200_DELL_M22] = dell9200_m22_pin_configs,
- [STAC_9200_DELL_M23] = dell9200_m23_pin_configs,
- [STAC_9200_DELL_M24] = dell9200_m24_pin_configs,
- [STAC_9200_DELL_M25] = dell9200_m25_pin_configs,
- [STAC_9200_DELL_M26] = dell9200_m26_pin_configs,
- [STAC_9200_DELL_M27] = dell9200_m27_pin_configs,
- [STAC_9200_M4] = gateway9200_m4_pin_configs,
- [STAC_9200_M4_2] = gateway9200_m4_2_pin_configs,
- [STAC_9200_PANASONIC] = ref9200_pin_configs,
-};
-
-static const char * const stac9200_models[STAC_9200_MODELS] = {
- [STAC_AUTO] = "auto",
- [STAC_REF] = "ref",
- [STAC_9200_OQO] = "oqo",
- [STAC_9200_DELL_D21] = "dell-d21",
- [STAC_9200_DELL_D22] = "dell-d22",
- [STAC_9200_DELL_D23] = "dell-d23",
- [STAC_9200_DELL_M21] = "dell-m21",
- [STAC_9200_DELL_M22] = "dell-m22",
- [STAC_9200_DELL_M23] = "dell-m23",
- [STAC_9200_DELL_M24] = "dell-m24",
- [STAC_9200_DELL_M25] = "dell-m25",
- [STAC_9200_DELL_M26] = "dell-m26",
- [STAC_9200_DELL_M27] = "dell-m27",
- [STAC_9200_M4] = "gateway-m4",
- [STAC_9200_M4_2] = "gateway-m4-2",
- [STAC_9200_PANASONIC] = "panasonic",
-};
-
-static const struct snd_pci_quirk stac9200_cfg_tbl[] = {
- /* SigmaTel reference board */
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
- "DFI LanParty", STAC_REF),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
- "DFI LanParty", STAC_REF),
- /* Dell laptops have BIOS problem */
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
- "unknown Dell", STAC_9200_DELL_D21),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
- "Dell Inspiron 630m", STAC_9200_DELL_M21),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd,
- "Dell Inspiron E1505n", STAC_9200_DELL_M25),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0,
- "unknown Dell", STAC_9200_DELL_D22),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1,
- "unknown Dell", STAC_9200_DELL_D22),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
- "Dell Latitude D620", STAC_9200_DELL_M22),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5,
- "unknown Dell", STAC_9200_DELL_D23),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7,
- "unknown Dell", STAC_9200_DELL_D23),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8,
- "unknown Dell", STAC_9200_DELL_M22),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9,
- "unknown Dell", STAC_9200_DELL_M24),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca,
- "unknown Dell", STAC_9200_DELL_M24),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
- "Dell Latitude 120L", STAC_9200_DELL_M24),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
- "Dell Latitude D820", STAC_9200_DELL_M22),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
- "Dell Inspiron E1705/9400", STAC_9200_DELL_M27),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
- "Dell XPS M1710", STAC_9200_DELL_M23),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
- "Dell Precision M90", STAC_9200_DELL_M23),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3,
- "unknown Dell", STAC_9200_DELL_M22),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4,
- "unknown Dell", STAC_9200_DELL_M22),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
- "unknown Dell", STAC_9200_DELL_M22),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
- "Dell Inspiron 640m", STAC_9200_DELL_M21),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9,
- "unknown Dell", STAC_9200_DELL_D23),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da,
- "unknown Dell", STAC_9200_DELL_D23),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de,
- "unknown Dell", STAC_9200_DELL_D21),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3,
- "unknown Dell", STAC_9200_DELL_D23),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8,
- "unknown Dell", STAC_9200_DELL_D21),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee,
- "unknown Dell", STAC_9200_DELL_M25),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef,
- "unknown Dell", STAC_9200_DELL_M25),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
- "Dell Inspiron 1501", STAC_9200_DELL_M26),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
- "unknown Dell", STAC_9200_DELL_M26),
- /* Panasonic */
- SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC),
- /* Gateway machines needs EAPD to be set on resume */
- SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_M4),
- SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", STAC_9200_M4_2),
- SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", STAC_9200_M4_2),
- /* OQO Mobile */
- SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO),
- {} /* terminator */
-};
-
-static const unsigned int ref925x_pin_configs[8] = {
- 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
- 0x90a70320, 0x02214210, 0x01019020, 0x9033032e,
-};
-
-static const unsigned int stac925xM1_pin_configs[8] = {
- 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
- 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
-};
-
-static const unsigned int stac925xM1_2_pin_configs[8] = {
- 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
- 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
-};
-
-static const unsigned int stac925xM2_pin_configs[8] = {
- 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
- 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
-};
-
-static const unsigned int stac925xM2_2_pin_configs[8] = {
- 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
- 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
-};
-
-static const unsigned int stac925xM3_pin_configs[8] = {
- 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
- 0x40a000f0, 0x90100210, 0x400003f1, 0x503303f3,
-};
-
-static const unsigned int stac925xM5_pin_configs[8] = {
- 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
- 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
-};
-
-static const unsigned int stac925xM6_pin_configs[8] = {
- 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
- 0x40a000f0, 0x90100210, 0x400003f1, 0x90330320,
-};
-
-static const unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
- [STAC_REF] = ref925x_pin_configs,
- [STAC_M1] = stac925xM1_pin_configs,
- [STAC_M1_2] = stac925xM1_2_pin_configs,
- [STAC_M2] = stac925xM2_pin_configs,
- [STAC_M2_2] = stac925xM2_2_pin_configs,
- [STAC_M3] = stac925xM3_pin_configs,
- [STAC_M5] = stac925xM5_pin_configs,
- [STAC_M6] = stac925xM6_pin_configs,
-};
-
-static const char * const stac925x_models[STAC_925x_MODELS] = {
- [STAC_925x_AUTO] = "auto",
- [STAC_REF] = "ref",
- [STAC_M1] = "m1",
- [STAC_M1_2] = "m1-2",
- [STAC_M2] = "m2",
- [STAC_M2_2] = "m2-2",
- [STAC_M3] = "m3",
- [STAC_M5] = "m5",
- [STAC_M6] = "m6",
-};
-
-static const struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = {
- SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2),
- SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5),
- SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1),
- SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_M2),
- SND_PCI_QUIRK(0x107b, 0x0367, "Gateway MX6453", STAC_M1_2),
- /* Not sure about the brand name for those */
- SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M1),
- SND_PCI_QUIRK(0x107b, 0x0507, "Gateway mobile", STAC_M3),
- SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M6),
- SND_PCI_QUIRK(0x107b, 0x0685, "Gateway mobile", STAC_M2_2),
- {} /* terminator */
-};
-
-static const struct snd_pci_quirk stac925x_cfg_tbl[] = {
- /* SigmaTel reference board */
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF),
- SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF),
-
- /* Default table for unknown ID */
- SND_PCI_QUIRK(0x1002, 0x437b, "Gateway mobile", STAC_M2_2),
-
- {} /* terminator */
-};
-
-static const unsigned int ref92hd73xx_pin_configs[13] = {
- 0x02214030, 0x02a19040, 0x01a19020, 0x02214030,
- 0x0181302e, 0x01014010, 0x01014020, 0x01014030,
- 0x02319040, 0x90a000f0, 0x90a000f0, 0x01452050,
- 0x01452050,
-};
-
-static const unsigned int dell_m6_pin_configs[13] = {
- 0x0321101f, 0x4f00000f, 0x4f0000f0, 0x90170110,
- 0x03a11020, 0x0321101f, 0x4f0000f0, 0x4f0000f0,
- 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0,
- 0x4f0000f0,
-};
-
-static const unsigned int alienware_m17x_pin_configs[13] = {
- 0x0321101f, 0x0321101f, 0x03a11020, 0x03014020,
- 0x90170110, 0x4f0000f0, 0x4f0000f0, 0x4f0000f0,
- 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0,
- 0x904601b0,
-};
-
-static const unsigned int intel_dg45id_pin_configs[13] = {
- 0x02214230, 0x02A19240, 0x01013214, 0x01014210,
- 0x01A19250, 0x01011212, 0x01016211
-};
-
-static const unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
- [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs,
- [STAC_DELL_M6_AMIC] = dell_m6_pin_configs,
- [STAC_DELL_M6_DMIC] = dell_m6_pin_configs,
- [STAC_DELL_M6_BOTH] = dell_m6_pin_configs,
- [STAC_DELL_EQ] = dell_m6_pin_configs,
- [STAC_ALIENWARE_M17X] = alienware_m17x_pin_configs,
- [STAC_92HD73XX_INTEL] = intel_dg45id_pin_configs,
-};
-
-static const char * const stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
- [STAC_92HD73XX_AUTO] = "auto",
- [STAC_92HD73XX_NO_JD] = "no-jd",
- [STAC_92HD73XX_REF] = "ref",
- [STAC_92HD73XX_INTEL] = "intel",
- [STAC_DELL_M6_AMIC] = "dell-m6-amic",
- [STAC_DELL_M6_DMIC] = "dell-m6-dmic",
- [STAC_DELL_M6_BOTH] = "dell-m6",
- [STAC_DELL_EQ] = "dell-eq",
- [STAC_ALIENWARE_M17X] = "alienware",
-};
-
-static const struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
- /* SigmaTel reference board */
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
- "DFI LanParty", STAC_92HD73XX_REF),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
- "DFI LanParty", STAC_92HD73XX_REF),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5002,
- "Intel DG45ID", STAC_92HD73XX_INTEL),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5003,
- "Intel DG45FC", STAC_92HD73XX_INTEL),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254,
- "Dell Studio 1535", STAC_DELL_M6_DMIC),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255,
- "unknown Dell", STAC_DELL_M6_DMIC),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256,
- "unknown Dell", STAC_DELL_M6_BOTH),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257,
- "unknown Dell", STAC_DELL_M6_BOTH),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e,
- "unknown Dell", STAC_DELL_M6_AMIC),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f,
- "unknown Dell", STAC_DELL_M6_AMIC),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271,
- "unknown Dell", STAC_DELL_M6_DMIC),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0272,
- "unknown Dell", STAC_DELL_M6_DMIC),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x029f,
- "Dell Studio 1537", STAC_DELL_M6_DMIC),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a0,
- "Dell Studio 17", STAC_DELL_M6_DMIC),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02be,
- "Dell Studio 1555", STAC_DELL_M6_DMIC),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd,
- "Dell Studio 1557", STAC_DELL_M6_DMIC),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe,
- "Dell Studio XPS 1645", STAC_DELL_M6_DMIC),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413,
- "Dell Studio 1558", STAC_DELL_M6_DMIC),
- {} /* terminator */
-};
-
-static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = {
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1,
- "Alienware M17x", STAC_ALIENWARE_M17X),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a,
- "Alienware M17x", STAC_ALIENWARE_M17X),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490,
- "Alienware M17x R3", STAC_DELL_EQ),
- {} /* terminator */
-};
-
-static const unsigned int ref92hd83xxx_pin_configs[10] = {
- 0x02214030, 0x02211010, 0x02a19020, 0x02170130,
- 0x01014050, 0x01819040, 0x01014020, 0x90a3014e,
- 0x01451160, 0x98560170,
-};
-
-static const unsigned int dell_s14_pin_configs[10] = {
- 0x0221403f, 0x0221101f, 0x02a19020, 0x90170110,
- 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a60160,
- 0x40f000f0, 0x40f000f0,
-};
-
-static const unsigned int dell_vostro_3500_pin_configs[10] = {
- 0x02a11020, 0x0221101f, 0x400000f0, 0x90170110,
- 0x400000f1, 0x400000f2, 0x400000f3, 0x90a60160,
- 0x400000f4, 0x400000f5,
-};
-
-static const unsigned int hp_dv7_4000_pin_configs[10] = {
- 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110,
- 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140,
- 0x40f000f0, 0x40f000f0,
-};
-
-static const unsigned int hp_zephyr_pin_configs[10] = {
- 0x01813050, 0x0421201f, 0x04a1205e, 0x96130310,
- 0x96130310, 0x0101401f, 0x1111611f, 0xd5a30130,
- 0, 0,
-};
-
-static const unsigned int hp_cNB11_intquad_pin_configs[10] = {
- 0x40f000f0, 0x0221101f, 0x02a11020, 0x92170110,
- 0x40f000f0, 0x92170110, 0x40f000f0, 0xd5a30130,
- 0x40f000f0, 0x40f000f0,
-};
-
-static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
- [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs,
- [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs,
- [STAC_DELL_S14] = dell_s14_pin_configs,
- [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs,
- [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs,
- [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs,
- [STAC_HP_ZEPHYR] = hp_zephyr_pin_configs,
-};
-
-static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
- [STAC_92HD83XXX_AUTO] = "auto",
- [STAC_92HD83XXX_REF] = "ref",
- [STAC_92HD83XXX_PWR_REF] = "mic-ref",
- [STAC_DELL_S14] = "dell-s14",
- [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500",
- [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad",
- [STAC_HP_DV7_4000] = "hp-dv7-4000",
- [STAC_HP_ZEPHYR] = "hp-zephyr",
-};
-
-static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
- /* SigmaTel reference board */
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
- "DFI LanParty", STAC_92HD83XXX_REF),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
- "DFI LanParty", STAC_92HD83XXX_REF),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
- "unknown Dell", STAC_DELL_S14),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028,
- "Dell Vostro 3500", STAC_DELL_VOSTRO_3500),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
- "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657,
- "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658,
- "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659,
- "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A,
- "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B,
- "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388,
- "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3389,
- "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355B,
- "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355C,
- "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355D,
- "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355E,
- "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355F,
- "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3560,
- "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358B,
- "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358C,
- "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358D,
- "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3591,
- "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3592,
- "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593,
- "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561,
- "HP", STAC_HP_ZEPHYR),
- {} /* terminator */
-};
-
-static const struct snd_pci_quirk stac92hd83xxx_codec_id_cfg_tbl[] = {
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561,
- "HP", STAC_HP_ZEPHYR),
- {} /* terminator */
-};
-
-static const unsigned int ref92hd71bxx_pin_configs[STAC92HD71BXX_NUM_PINS] = {
- 0x02214030, 0x02a19040, 0x01a19020, 0x01014010,
- 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0,
- 0x90a000f0, 0x01452050, 0x01452050, 0x00000000,
- 0x00000000
-};
-
-static const unsigned int dell_m4_1_pin_configs[STAC92HD71BXX_NUM_PINS] = {
- 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110,
- 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0,
- 0x40f000f0, 0x4f0000f0, 0x4f0000f0, 0x00000000,
- 0x00000000
-};
-
-static const unsigned int dell_m4_2_pin_configs[STAC92HD71BXX_NUM_PINS] = {
- 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110,
- 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0,
- 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000,
- 0x00000000
-};
-
-static const unsigned int dell_m4_3_pin_configs[STAC92HD71BXX_NUM_PINS] = {
- 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110,
- 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0,
- 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000,
- 0x00000000
-};
-
-static const unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
- [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs,
- [STAC_DELL_M4_1] = dell_m4_1_pin_configs,
- [STAC_DELL_M4_2] = dell_m4_2_pin_configs,
- [STAC_DELL_M4_3] = dell_m4_3_pin_configs,
- [STAC_HP_M4] = NULL,
- [STAC_HP_DV4] = NULL,
- [STAC_HP_DV5] = NULL,
- [STAC_HP_HDX] = NULL,
- [STAC_HP_DV4_1222NR] = NULL,
-};
-
-static const char * const stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
- [STAC_92HD71BXX_AUTO] = "auto",
- [STAC_92HD71BXX_REF] = "ref",
- [STAC_DELL_M4_1] = "dell-m4-1",
- [STAC_DELL_M4_2] = "dell-m4-2",
- [STAC_DELL_M4_3] = "dell-m4-3",
- [STAC_HP_M4] = "hp-m4",
- [STAC_HP_DV4] = "hp-dv4",
- [STAC_HP_DV5] = "hp-dv5",
- [STAC_HP_HDX] = "hp-hdx",
- [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr",
-};
-
-static const struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
- /* SigmaTel reference board */
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
- "DFI LanParty", STAC_92HD71BXX_REF),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
- "DFI LanParty", STAC_92HD71BXX_REF),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fb,
- "HP dv4-1222nr", STAC_HP_DV4_1222NR),
- SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x1720,
- "HP", STAC_HP_DV5),
- SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080,
- "HP", STAC_HP_DV5),
- SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0,
- "HP dv4-7", STAC_HP_DV4),
- SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600,
- "HP dv4-7", STAC_HP_DV5),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610,
- "HP HDX", STAC_HP_HDX), /* HDX18 */
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
- "HP mini 1000", STAC_HP_M4),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361b,
- "HP HDX", STAC_HP_HDX), /* HDX16 */
- SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620,
- "HP dv6", STAC_HP_DV5),
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3061,
- "HP dv6", STAC_HP_DV5), /* HP dv6-1110ax */
- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x363e,
- "HP DV6", STAC_HP_DV5),
- SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010,
- "HP", STAC_HP_DV5),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
- "unknown Dell", STAC_DELL_M4_1),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234,
- "unknown Dell", STAC_DELL_M4_1),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0250,
- "unknown Dell", STAC_DELL_M4_1),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024f,
- "unknown Dell", STAC_DELL_M4_1),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024d,
- "unknown Dell", STAC_DELL_M4_1),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0251,
- "unknown Dell", STAC_DELL_M4_1),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0277,
- "unknown Dell", STAC_DELL_M4_1),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0263,
- "unknown Dell", STAC_DELL_M4_2),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0265,
- "unknown Dell", STAC_DELL_M4_2),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0262,
- "unknown Dell", STAC_DELL_M4_2),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0264,
- "unknown Dell", STAC_DELL_M4_2),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02aa,
- "unknown Dell", STAC_DELL_M4_3),
- {} /* terminator */
-};
-
-static const unsigned int ref922x_pin_configs[10] = {
- 0x01014010, 0x01016011, 0x01012012, 0x0221401f,
- 0x01813122, 0x01011014, 0x01441030, 0x01c41030,
- 0x40000100, 0x40000100,
-};
-
-/*
- STAC 922X pin configs for
- 102801A7
- 102801AB
- 102801A9
- 102801D1
- 102801D2
-*/
-static const unsigned int dell_922x_d81_pin_configs[10] = {
- 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
- 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1,
- 0x01813122, 0x400001f2,
-};
-
-/*
- STAC 922X pin configs for
- 102801AC
- 102801D0
-*/
-static const unsigned int dell_922x_d82_pin_configs[10] = {
- 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
- 0x02a19020, 0x01117011, 0x01451140, 0x400001f0,
- 0x01813122, 0x400001f1,
-};
-
-/*
- STAC 922X pin configs for
- 102801BF
-*/
-static const unsigned int dell_922x_m81_pin_configs[10] = {
- 0x0321101f, 0x01112024, 0x01111222, 0x91174220,
- 0x03a11050, 0x01116221, 0x90a70330, 0x01452340,
- 0x40C003f1, 0x405003f0,
-};
-
-/*
- STAC 9221 A1 pin configs for
- 102801D7 (Dell XPS M1210)
-*/
-static const unsigned int dell_922x_m82_pin_configs[10] = {
- 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310,
- 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2,
- 0x508003f3, 0x405003f4,
-};
-
-static const unsigned int d945gtp3_pin_configs[10] = {
- 0x0221401f, 0x01a19022, 0x01813021, 0x01014010,
- 0x40000100, 0x40000100, 0x40000100, 0x40000100,
- 0x02a19120, 0x40000100,
-};
-
-static const unsigned int d945gtp5_pin_configs[10] = {
- 0x0221401f, 0x01011012, 0x01813024, 0x01014010,
- 0x01a19021, 0x01016011, 0x01452130, 0x40000100,
- 0x02a19320, 0x40000100,
-};
-
-static const unsigned int intel_mac_v1_pin_configs[10] = {
- 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd,
- 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240,
- 0x400000fc, 0x400000fb,
-};
-
-static const unsigned int intel_mac_v2_pin_configs[10] = {
- 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
- 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa,
- 0x400000fc, 0x400000fb,
-};
-
-static const unsigned int intel_mac_v3_pin_configs[10] = {
- 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
- 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240,
- 0x400000fc, 0x400000fb,
-};
-
-static const unsigned int intel_mac_v4_pin_configs[10] = {
- 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
- 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
- 0x400000fc, 0x400000fb,
-};
-
-static const unsigned int intel_mac_v5_pin_configs[10] = {
- 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
- 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
- 0x400000fc, 0x400000fb,
-};
-
-static const unsigned int ecs202_pin_configs[10] = {
- 0x0221401f, 0x02a19020, 0x01a19020, 0x01114010,
- 0x408000f0, 0x01813022, 0x074510a0, 0x40c400f1,
- 0x9037012e, 0x40e000f2,
-};
-
-static const unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
- [STAC_D945_REF] = ref922x_pin_configs,
- [STAC_D945GTP3] = d945gtp3_pin_configs,
- [STAC_D945GTP5] = d945gtp5_pin_configs,
- [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs,
- [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs,
- [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs,
- [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs,
- [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs,
- [STAC_INTEL_MAC_AUTO] = intel_mac_v3_pin_configs,
- /* for backward compatibility */
- [STAC_MACMINI] = intel_mac_v3_pin_configs,
- [STAC_MACBOOK] = intel_mac_v5_pin_configs,
- [STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs,
- [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs,
- [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs,
- [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs,
- [STAC_ECS_202] = ecs202_pin_configs,
- [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs,
- [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs,
- [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs,
- [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs,
-};
-
-static const char * const stac922x_models[STAC_922X_MODELS] = {
- [STAC_922X_AUTO] = "auto",
- [STAC_D945_REF] = "ref",
- [STAC_D945GTP5] = "5stack",
- [STAC_D945GTP3] = "3stack",
- [STAC_INTEL_MAC_V1] = "intel-mac-v1",
- [STAC_INTEL_MAC_V2] = "intel-mac-v2",
- [STAC_INTEL_MAC_V3] = "intel-mac-v3",
- [STAC_INTEL_MAC_V4] = "intel-mac-v4",
- [STAC_INTEL_MAC_V5] = "intel-mac-v5",
- [STAC_INTEL_MAC_AUTO] = "intel-mac-auto",
- /* for backward compatibility */
- [STAC_MACMINI] = "macmini",
- [STAC_MACBOOK] = "macbook",
- [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1",
- [STAC_MACBOOK_PRO_V2] = "macbook-pro",
- [STAC_IMAC_INTEL] = "imac-intel",
- [STAC_IMAC_INTEL_20] = "imac-intel-20",
- [STAC_ECS_202] = "ecs202",
- [STAC_922X_DELL_D81] = "dell-d81",
- [STAC_922X_DELL_D82] = "dell-d82",
- [STAC_922X_DELL_M81] = "dell-m81",
- [STAC_922X_DELL_M82] = "dell-m82",
-};
-
-static const struct snd_pci_quirk stac922x_cfg_tbl[] = {
- /* SigmaTel reference board */
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
- "DFI LanParty", STAC_D945_REF),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
- "DFI LanParty", STAC_D945_REF),
- /* Intel 945G based systems */
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
- "Intel D945G", STAC_D945GTP3),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
- "Intel D945G", STAC_D945GTP3),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
- "Intel D945G", STAC_D945GTP3),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
- "Intel D945G", STAC_D945GTP3),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
- "Intel D945G", STAC_D945GTP3),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
- "Intel D945G", STAC_D945GTP3),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
- "Intel D945G", STAC_D945GTP3),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
- "Intel D945G", STAC_D945GTP3),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
- "Intel D945G", STAC_D945GTP3),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
- "Intel D945G", STAC_D945GTP3),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
- "Intel D945G", STAC_D945GTP3),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
- "Intel D945G", STAC_D945GTP3),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
- "Intel D945G", STAC_D945GTP3),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
- "Intel D945G", STAC_D945GTP3),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
- "Intel D945G", STAC_D945GTP3),
- /* Intel D945G 5-stack systems */
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
- "Intel D945G", STAC_D945GTP5),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
- "Intel D945G", STAC_D945GTP5),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
- "Intel D945G", STAC_D945GTP5),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
- "Intel D945G", STAC_D945GTP5),
- /* Intel 945P based systems */
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
- "Intel D945P", STAC_D945GTP3),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
- "Intel D945P", STAC_D945GTP3),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
- "Intel D945P", STAC_D945GTP3),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
- "Intel D945P", STAC_D945GTP3),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
- "Intel D945P", STAC_D945GTP3),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
- "Intel D945P", STAC_D945GTP5),
- /* other intel */
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0204,
- "Intel D945", STAC_D945_REF),
- /* other systems */
- /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */
- SND_PCI_QUIRK(0x8384, 0x7680,
- "Mac", STAC_INTEL_MAC_AUTO),
- /* Dell systems */
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
- "unknown Dell", STAC_922X_DELL_D81),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9,
- "unknown Dell", STAC_922X_DELL_D81),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab,
- "unknown Dell", STAC_922X_DELL_D81),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac,
- "unknown Dell", STAC_922X_DELL_D82),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf,
- "unknown Dell", STAC_922X_DELL_M81),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0,
- "unknown Dell", STAC_922X_DELL_D82),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1,
- "unknown Dell", STAC_922X_DELL_D81),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2,
- "unknown Dell", STAC_922X_DELL_D81),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
- "Dell XPS M1210", STAC_922X_DELL_M82),
- /* ECS/PC Chips boards */
- SND_PCI_QUIRK_MASK(0x1019, 0xf000, 0x2000,
- "ECS/PC chips", STAC_ECS_202),
- {} /* terminator */
-};
-
-static const unsigned int ref927x_pin_configs[14] = {
- 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
- 0x01a19040, 0x01011012, 0x01016011, 0x0101201f,
- 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070,
- 0x01c42190, 0x40000100,
-};
-
-static const unsigned int d965_3st_pin_configs[14] = {
- 0x0221401f, 0x02a19120, 0x40000100, 0x01014011,
- 0x01a19021, 0x01813024, 0x40000100, 0x40000100,
- 0x40000100, 0x40000100, 0x40000100, 0x40000100,
- 0x40000100, 0x40000100
-};
-
-static const unsigned int d965_5st_pin_configs[14] = {
- 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
- 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
- 0x40000100, 0x40000100, 0x40000100, 0x01442070,
- 0x40000100, 0x40000100
-};
-
-static const unsigned int d965_5st_no_fp_pin_configs[14] = {
- 0x40000100, 0x40000100, 0x0181304e, 0x01014010,
- 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
- 0x40000100, 0x40000100, 0x40000100, 0x01442070,
- 0x40000100, 0x40000100
-};
-
-static const unsigned int dell_3st_pin_configs[14] = {
- 0x02211230, 0x02a11220, 0x01a19040, 0x01114210,
- 0x01111212, 0x01116211, 0x01813050, 0x01112214,
- 0x403003fa, 0x90a60040, 0x90a60040, 0x404003fb,
- 0x40c003fc, 0x40000100
-};
-
-static const unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
- [STAC_D965_REF_NO_JD] = ref927x_pin_configs,
- [STAC_D965_REF] = ref927x_pin_configs,
- [STAC_D965_3ST] = d965_3st_pin_configs,
- [STAC_D965_5ST] = d965_5st_pin_configs,
- [STAC_D965_5ST_NO_FP] = d965_5st_no_fp_pin_configs,
- [STAC_DELL_3ST] = dell_3st_pin_configs,
- [STAC_DELL_BIOS] = NULL,
- [STAC_927X_VOLKNOB] = NULL,
-};
-
-static const char * const stac927x_models[STAC_927X_MODELS] = {
- [STAC_927X_AUTO] = "auto",
- [STAC_D965_REF_NO_JD] = "ref-no-jd",
- [STAC_D965_REF] = "ref",
- [STAC_D965_3ST] = "3stack",
- [STAC_D965_5ST] = "5stack",
- [STAC_D965_5ST_NO_FP] = "5stack-no-fp",
- [STAC_DELL_3ST] = "dell-3stack",
- [STAC_DELL_BIOS] = "dell-bios",
- [STAC_927X_VOLKNOB] = "volknob",
-};
-
-static const struct snd_pci_quirk stac927x_cfg_tbl[] = {
- /* SigmaTel reference board */
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
- "DFI LanParty", STAC_D965_REF),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
- "DFI LanParty", STAC_D965_REF),
- /* Intel 946 based systems */
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
- /* 965 based 3 stack systems */
- SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2100,
- "Intel D965", STAC_D965_3ST),
- SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000,
- "Intel D965", STAC_D965_3ST),
- /* Dell 3 stack systems */
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
- /* Dell 3 stack systems with verb table in BIOS */
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_BIOS),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS),
- /* 965 based 5 stack systems */
- SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2300,
- "Intel D965", STAC_D965_5ST),
- SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500,
- "Intel D965", STAC_D965_5ST),
- /* volume-knob fixes */
- SND_PCI_QUIRK_VENDOR(0x10cf, "FSC", STAC_927X_VOLKNOB),
- {} /* terminator */
-};
-
-static const unsigned int ref9205_pin_configs[12] = {
- 0x40000100, 0x40000100, 0x01016011, 0x01014010,
- 0x01813122, 0x01a19021, 0x01019020, 0x40000100,
- 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030
-};
-
-/*
- STAC 9205 pin configs for
- 102801F1
- 102801F2
- 102801FC
- 102801FD
- 10280204
- 1028021F
- 10280228 (Dell Vostro 1500)
- 10280229 (Dell Vostro 1700)
-*/
-static const unsigned int dell_9205_m42_pin_configs[12] = {
- 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310,
- 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9,
- 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE,
-};
-
-/*
- STAC 9205 pin configs for
- 102801F9
- 102801FA
- 102801FE
- 102801FF (Dell Precision M4300)
- 10280206
- 10280200
- 10280201
-*/
-static const unsigned int dell_9205_m43_pin_configs[12] = {
- 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310,
- 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9,
- 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8,
-};
-
-static const unsigned int dell_9205_m44_pin_configs[12] = {
- 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310,
- 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9,
- 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe,
-};
-
-static const unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
- [STAC_9205_REF] = ref9205_pin_configs,
- [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs,
- [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs,
- [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs,
- [STAC_9205_EAPD] = NULL,
-};
-
-static const char * const stac9205_models[STAC_9205_MODELS] = {
- [STAC_9205_AUTO] = "auto",
- [STAC_9205_REF] = "ref",
- [STAC_9205_DELL_M42] = "dell-m42",
- [STAC_9205_DELL_M43] = "dell-m43",
- [STAC_9205_DELL_M44] = "dell-m44",
- [STAC_9205_EAPD] = "eapd",
-};
-
-static const struct snd_pci_quirk stac9205_cfg_tbl[] = {
- /* SigmaTel reference board */
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
- "DFI LanParty", STAC_9205_REF),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xfb30,
- "SigmaTel", STAC_9205_REF),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
- "DFI LanParty", STAC_9205_REF),
- /* Dell */
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
- "unknown Dell", STAC_9205_DELL_M42),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
- "unknown Dell", STAC_9205_DELL_M42),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
- "Dell Precision", STAC_9205_DELL_M43),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
- "Dell Precision", STAC_9205_DELL_M43),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
- "Dell Precision", STAC_9205_DELL_M43),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
- "unknown Dell", STAC_9205_DELL_M42),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
- "unknown Dell", STAC_9205_DELL_M42),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe,
- "Dell Precision", STAC_9205_DELL_M43),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
- "Dell Precision M4300", STAC_9205_DELL_M43),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
- "unknown Dell", STAC_9205_DELL_M42),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
- "Dell Precision", STAC_9205_DELL_M43),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
- "Dell Precision", STAC_9205_DELL_M43),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
- "Dell Precision", STAC_9205_DELL_M43),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
- "Dell Inspiron", STAC_9205_DELL_M44),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228,
- "Dell Vostro 1500", STAC_9205_DELL_M42),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0229,
- "Dell Vostro 1700", STAC_9205_DELL_M42),
- /* Gateway */
- SND_PCI_QUIRK(0x107b, 0x0560, "Gateway T6834c", STAC_9205_EAPD),
- SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD),
- {} /* terminator */
-};
-
-static void stac92xx_set_config_regs(struct hda_codec *codec,
- const unsigned int *pincfgs)
-{
- int i;
- struct sigmatel_spec *spec = codec->spec;
-
- if (!pincfgs)
- return;
-
- for (i = 0; i < spec->num_pins; i++)
- if (spec->pin_nids[i] && pincfgs[i])
- snd_hda_codec_set_pincfg(codec, spec->pin_nids[i],
- pincfgs[i]);
-}
-
-/*
- * Analog playback callbacks
- */
-static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct sigmatel_spec *spec = codec->spec;
- if (spec->stream_delay)
- msleep(spec->stream_delay);
- return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
- hinfo);
-}
-
-static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct sigmatel_spec *spec = codec->spec;
- return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, format, substream);
-}
-
-static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct sigmatel_spec *spec = codec->spec;
- return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
-}
-
-/*
- * Digital playback callbacks
- */
-static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct sigmatel_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_open(codec, &spec->multiout);
-}
-
-static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct sigmatel_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_close(codec, &spec->multiout);
-}
-
-static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct sigmatel_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
- stream_tag, format, substream);
-}
-
-static int stac92xx_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct sigmatel_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
-}
-
-
-/*
- * Analog capture callbacks
- */
-static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct sigmatel_spec *spec = codec->spec;
- hda_nid_t nid = spec->adc_nids[substream->number];
-
- if (spec->powerdown_adcs) {
- msleep(40);
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
- }
- snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
- return 0;
-}
-
-static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct sigmatel_spec *spec = codec->spec;
- hda_nid_t nid = spec->adc_nids[substream->number];
-
- snd_hda_codec_cleanup_stream(codec, nid);
- if (spec->powerdown_adcs)
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
- return 0;
-}
-
-static const struct hda_pcm_stream stac92xx_pcm_digital_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- /* NID is set in stac92xx_build_pcms */
- .ops = {
- .open = stac92xx_dig_playback_pcm_open,
- .close = stac92xx_dig_playback_pcm_close,
- .prepare = stac92xx_dig_playback_pcm_prepare,
- .cleanup = stac92xx_dig_playback_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream stac92xx_pcm_digital_capture = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- /* NID is set in stac92xx_build_pcms */
-};
-
-static const struct hda_pcm_stream stac92xx_pcm_analog_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 8,
- .nid = 0x02, /* NID to query formats and rates */
- .ops = {
- .open = stac92xx_playback_pcm_open,
- .prepare = stac92xx_playback_pcm_prepare,
- .cleanup = stac92xx_playback_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- .nid = 0x06, /* NID to query formats and rates */
- .ops = {
- .open = stac92xx_playback_pcm_open,
- .prepare = stac92xx_playback_pcm_prepare,
- .cleanup = stac92xx_playback_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream stac92xx_pcm_analog_capture = {
- .channels_min = 2,
- .channels_max = 2,
- /* NID + .substreams is set in stac92xx_build_pcms */
- .ops = {
- .prepare = stac92xx_capture_pcm_prepare,
- .cleanup = stac92xx_capture_pcm_cleanup
- },
-};
-
-static int stac92xx_build_pcms(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
- struct hda_pcm *info = spec->pcm_rec;
-
- codec->num_pcms = 1;
- codec->pcm_info = info;
-
- info->name = "STAC92xx Analog";
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
- spec->multiout.dac_nids[0];
- info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
- info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs;
-
- if (spec->alt_switch) {
- codec->num_pcms++;
- info++;
- info->name = "STAC92xx Analog Alt";
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_alt_playback;
- }
-
- if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
- codec->num_pcms++;
- info++;
- info->name = "STAC92xx Digital";
- info->pcm_type = spec->autocfg.dig_out_type[0];
- if (spec->multiout.dig_out_nid) {
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
- }
- if (spec->dig_in_nid) {
- info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_digital_capture;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
- }
- }
-
- return 0;
-}
-
-static unsigned int stac92xx_get_default_vref(struct hda_codec *codec,
- hda_nid_t nid)
-{
- unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
- pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
- if (pincap & AC_PINCAP_VREF_100)
- return AC_PINCTL_VREF_100;
- if (pincap & AC_PINCAP_VREF_80)
- return AC_PINCTL_VREF_80;
- if (pincap & AC_PINCAP_VREF_50)
- return AC_PINCTL_VREF_50;
- if (pincap & AC_PINCAP_VREF_GRD)
- return AC_PINCTL_VREF_GRD;
- return 0;
-}
-
-static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
-
-{
- snd_hda_codec_write_cache(codec, nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
-}
-
-#define stac92xx_hp_switch_info snd_ctl_boolean_mono_info
-
-static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
-
- ucontrol->value.integer.value[0] = !!spec->hp_switch;
- return 0;
-}
-
-static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid);
-
-static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
- int nid = kcontrol->private_value;
-
- spec->hp_switch = ucontrol->value.integer.value[0] ? nid : 0;
-
- /* check to be sure that the ports are up to date with
- * switch changes
- */
- stac_issue_unsol_event(codec, nid);
-
- return 1;
-}
-
-static int stac92xx_dc_bias_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int i;
- static const char * const texts[] = {
- "Mic In", "Line In", "Line Out"
- };
-
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
- hda_nid_t nid = kcontrol->private_value;
-
- if (nid == spec->mic_switch || nid == spec->line_switch)
- i = 3;
- else
- i = 2;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->value.enumerated.items = i;
- uinfo->count = 1;
- if (uinfo->value.enumerated.item >= i)
- uinfo->value.enumerated.item = i-1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-static int stac92xx_dc_bias_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- hda_nid_t nid = kcontrol->private_value;
- unsigned int vref = stac92xx_vref_get(codec, nid);
-
- if (vref == stac92xx_get_default_vref(codec, nid))
- ucontrol->value.enumerated.item[0] = 0;
- else if (vref == AC_PINCTL_VREF_GRD)
- ucontrol->value.enumerated.item[0] = 1;
- else if (vref == AC_PINCTL_VREF_HIZ)
- ucontrol->value.enumerated.item[0] = 2;
-
- return 0;
-}
-
-static int stac92xx_dc_bias_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int new_vref = 0;
- int error;
- hda_nid_t nid = kcontrol->private_value;
-
- if (ucontrol->value.enumerated.item[0] == 0)
- new_vref = stac92xx_get_default_vref(codec, nid);
- else if (ucontrol->value.enumerated.item[0] == 1)
- new_vref = AC_PINCTL_VREF_GRD;
- else if (ucontrol->value.enumerated.item[0] == 2)
- new_vref = AC_PINCTL_VREF_HIZ;
- else
- return 0;
-
- if (new_vref != stac92xx_vref_get(codec, nid)) {
- error = stac92xx_vref_set(codec, nid, new_vref);
- return error;
- }
-
- return 0;
-}
-
-static int stac92xx_io_switch_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- char *texts[2];
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
-
- if (kcontrol->private_value == spec->line_switch)
- texts[0] = "Line In";
- else
- texts[0] = "Mic In";
- texts[1] = "Line Out";
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->value.enumerated.items = 2;
- uinfo->count = 1;
-
- if (uinfo->value.enumerated.item >= 2)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
- hda_nid_t nid = kcontrol->private_value;
- int io_idx = (nid == spec->mic_switch) ? 1 : 0;
-
- ucontrol->value.enumerated.item[0] = spec->io_switch[io_idx];
- return 0;
-}
-
-static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
- hda_nid_t nid = kcontrol->private_value;
- int io_idx = (nid == spec->mic_switch) ? 1 : 0;
- unsigned short val = !!ucontrol->value.enumerated.item[0];
-
- spec->io_switch[io_idx] = val;
-
- if (val)
- stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
- else {
- unsigned int pinctl = AC_PINCTL_IN_EN;
- if (io_idx) /* set VREF for mic */
- pinctl |= stac92xx_get_default_vref(codec, nid);
- stac92xx_auto_set_pinctl(codec, nid, pinctl);
- }
-
- /* check the auto-mute again: we need to mute/unmute the speaker
- * appropriately according to the pin direction
- */
- if (spec->hp_detect)
- stac_issue_unsol_event(codec, nid);
-
- return 1;
-}
-
-#define stac92xx_clfe_switch_info snd_ctl_boolean_mono_info
-
-static int stac92xx_clfe_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
-
- ucontrol->value.integer.value[0] = spec->clfe_swap;
- return 0;
-}
-
-static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
- hda_nid_t nid = kcontrol->private_value & 0xff;
- unsigned int val = !!ucontrol->value.integer.value[0];
-
- if (spec->clfe_swap == val)
- return 0;
-
- spec->clfe_swap = val;
-
- snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
- spec->clfe_swap ? 0x4 : 0x0);
-
- return 1;
-}
-
-#define STAC_CODEC_HP_SWITCH(xname) \
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = 0, \
- .info = stac92xx_hp_switch_info, \
- .get = stac92xx_hp_switch_get, \
- .put = stac92xx_hp_switch_put, \
- }
-
-#define STAC_CODEC_IO_SWITCH(xname, xpval) \
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = 0, \
- .info = stac92xx_io_switch_info, \
- .get = stac92xx_io_switch_get, \
- .put = stac92xx_io_switch_put, \
- .private_value = xpval, \
- }
-
-#define STAC_CODEC_CLFE_SWITCH(xname, xpval) \
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = 0, \
- .info = stac92xx_clfe_switch_info, \
- .get = stac92xx_clfe_switch_get, \
- .put = stac92xx_clfe_switch_put, \
- .private_value = xpval, \
- }
-
-enum {
- STAC_CTL_WIDGET_VOL,
- STAC_CTL_WIDGET_MUTE,
- STAC_CTL_WIDGET_MUTE_BEEP,
- STAC_CTL_WIDGET_MONO_MUX,
- STAC_CTL_WIDGET_HP_SWITCH,
- STAC_CTL_WIDGET_IO_SWITCH,
- STAC_CTL_WIDGET_CLFE_SWITCH,
- STAC_CTL_WIDGET_DC_BIAS
-};
-
-static const struct snd_kcontrol_new stac92xx_control_templates[] = {
- HDA_CODEC_VOLUME(NULL, 0, 0, 0),
- HDA_CODEC_MUTE(NULL, 0, 0, 0),
- HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0),
- STAC_MONO_MUX,
- STAC_CODEC_HP_SWITCH(NULL),
- STAC_CODEC_IO_SWITCH(NULL, 0),
- STAC_CODEC_CLFE_SWITCH(NULL, 0),
- DC_BIAS(NULL, 0, 0),
-};
-
-/* add dynamic controls */
-static struct snd_kcontrol_new *
-stac_control_new(struct sigmatel_spec *spec,
- const struct snd_kcontrol_new *ktemp,
- const char *name,
- unsigned int subdev)
-{
- struct snd_kcontrol_new *knew;
-
- snd_array_init(&spec->kctls, sizeof(*knew), 32);
- knew = snd_array_new(&spec->kctls);
- if (!knew)
- return NULL;
- *knew = *ktemp;
- knew->name = kstrdup(name, GFP_KERNEL);
- if (!knew->name) {
- /* roolback */
- memset(knew, 0, sizeof(*knew));
- spec->kctls.alloced--;
- return NULL;
- }
- knew->subdevice = subdev;
- return knew;
-}
-
-static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
- const struct snd_kcontrol_new *ktemp,
- int idx, const char *name,
- unsigned long val)
-{
- struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name,
- HDA_SUBDEV_AMP_FLAG);
- if (!knew)
- return -ENOMEM;
- knew->index = idx;
- knew->private_value = val;
- return 0;
-}
-
-static inline int stac92xx_add_control_idx(struct sigmatel_spec *spec,
- int type, int idx, const char *name,
- unsigned long val)
-{
- return stac92xx_add_control_temp(spec,
- &stac92xx_control_templates[type],
- idx, name, val);
-}
-
-
-/* add dynamic controls */
-static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type,
- const char *name, unsigned long val)
-{
- return stac92xx_add_control_idx(spec, type, 0, name, val);
-}
-
-static const struct snd_kcontrol_new stac_input_src_temp = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input Source",
- .info = stac92xx_mux_enum_info,
- .get = stac92xx_mux_enum_get,
- .put = stac92xx_mux_enum_put,
-};
-
-static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec,
- hda_nid_t nid, int idx)
-{
- int def_conf = snd_hda_codec_get_pincfg(codec, nid);
- int control = 0;
- struct sigmatel_spec *spec = codec->spec;
- char name[22];
-
- if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) {
- if (stac92xx_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD
- && nid == spec->line_switch)
- control = STAC_CTL_WIDGET_IO_SWITCH;
- else if (snd_hda_query_pin_caps(codec, nid)
- & (AC_PINCAP_VREF_GRD << AC_PINCAP_VREF_SHIFT))
- control = STAC_CTL_WIDGET_DC_BIAS;
- else if (nid == spec->mic_switch)
- control = STAC_CTL_WIDGET_IO_SWITCH;
- }
-
- if (control) {
- snd_hda_get_pin_label(codec, nid, &spec->autocfg,
- name, sizeof(name), NULL);
- return stac92xx_add_control(codec->spec, control,
- strcat(name, " Jack Mode"), nid);
- }
-
- return 0;
-}
-
-static int stac92xx_add_input_source(struct sigmatel_spec *spec)
-{
- struct snd_kcontrol_new *knew;
- struct hda_input_mux *imux = &spec->private_imux;
-
- if (spec->auto_mic)
- return 0; /* no need for input source */
- if (!spec->num_adcs || imux->num_items <= 1)
- return 0; /* no need for input source control */
- knew = stac_control_new(spec, &stac_input_src_temp,
- stac_input_src_temp.name, 0);
- if (!knew)
- return -ENOMEM;
- knew->count = spec->num_adcs;
- return 0;
-}
-
-/* check whether the line-input can be used as line-out */
-static hda_nid_t check_line_out_switch(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- hda_nid_t nid;
- unsigned int pincap;
- int i;
-
- if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
- return 0;
- for (i = 0; i < cfg->num_inputs; i++) {
- if (cfg->inputs[i].type == AUTO_PIN_LINE_IN) {
- nid = cfg->inputs[i].pin;
- pincap = snd_hda_query_pin_caps(codec, nid);
- if (pincap & AC_PINCAP_OUT)
- return nid;
- }
- }
- return 0;
-}
-
-static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid);
-
-/* check whether the mic-input can be used as line-out */
-static hda_nid_t check_mic_out_switch(struct hda_codec *codec, hda_nid_t *dac)
-{
- struct sigmatel_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- unsigned int def_conf, pincap;
- int i;
-
- *dac = 0;
- if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
- return 0;
- for (i = 0; i < cfg->num_inputs; i++) {
- hda_nid_t nid = cfg->inputs[i].pin;
- if (cfg->inputs[i].type != AUTO_PIN_MIC)
- continue;
- def_conf = snd_hda_codec_get_pincfg(codec, nid);
- /* some laptops have an internal analog microphone
- * which can't be used as a output */
- if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) {
- pincap = snd_hda_query_pin_caps(codec, nid);
- if (pincap & AC_PINCAP_OUT) {
- *dac = get_unassigned_dac(codec, nid);
- if (*dac)
- return nid;
- }
- }
- }
- return 0;
-}
-
-static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
-{
- int i;
-
- for (i = 0; i < spec->multiout.num_dacs; i++) {
- if (spec->multiout.dac_nids[i] == nid)
- return 1;
- }
-
- return 0;
-}
-
-static int check_all_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
-{
- int i;
- if (is_in_dac_nids(spec, nid))
- return 1;
- for (i = 0; i < spec->autocfg.hp_outs; i++)
- if (spec->hp_dacs[i] == nid)
- return 1;
- for (i = 0; i < spec->autocfg.speaker_outs; i++)
- if (spec->speaker_dacs[i] == nid)
- return 1;
- return 0;
-}
-
-static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
-{
- struct sigmatel_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int j, conn_len;
- hda_nid_t conn[HDA_MAX_CONNECTIONS], fallback_dac;
- unsigned int wcaps, wtype;
-
- conn_len = snd_hda_get_connections(codec, nid, conn,
- HDA_MAX_CONNECTIONS);
- /* 92HD88: trace back up the link of nids to find the DAC */
- while (conn_len == 1 && (get_wcaps_type(get_wcaps(codec, conn[0]))
- != AC_WID_AUD_OUT)) {
- nid = conn[0];
- conn_len = snd_hda_get_connections(codec, nid, conn,
- HDA_MAX_CONNECTIONS);
- }
- for (j = 0; j < conn_len; j++) {
- wcaps = get_wcaps(codec, conn[j]);
- wtype = get_wcaps_type(wcaps);
- /* we check only analog outputs */
- if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL))
- continue;
- /* if this route has a free DAC, assign it */
- if (!check_all_dac_nids(spec, conn[j])) {
- if (conn_len > 1) {
- /* select this DAC in the pin's input mux */
- snd_hda_codec_write_cache(codec, nid, 0,
- AC_VERB_SET_CONNECT_SEL, j);
- }
- return conn[j];
- }
- }
-
- /* if all DACs are already assigned, connect to the primary DAC,
- unless we're assigning a secondary headphone */
- fallback_dac = spec->multiout.dac_nids[0];
- if (spec->multiout.hp_nid) {
- for (j = 0; j < cfg->hp_outs; j++)
- if (cfg->hp_pins[j] == nid) {
- fallback_dac = spec->multiout.hp_nid;
- break;
- }
- }
-
- if (conn_len > 1) {
- for (j = 0; j < conn_len; j++) {
- if (conn[j] == fallback_dac) {
- snd_hda_codec_write_cache(codec, nid, 0,
- AC_VERB_SET_CONNECT_SEL, j);
- break;
- }
- }
- }
- return 0;
-}
-
-static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid);
-static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid);
-
-/*
- * Fill in the dac_nids table from the parsed pin configuration
- * This function only works when every pin in line_out_pins[]
- * contains atleast one DAC in its connection list. Some 92xx
- * codecs are not connected directly to a DAC, such as the 9200
- * and 9202/925x. For those, dac_nids[] must be hard-coded.
- */
-static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i;
- hda_nid_t nid, dac;
-
- for (i = 0; i < cfg->line_outs; i++) {
- nid = cfg->line_out_pins[i];
- dac = get_unassigned_dac(codec, nid);
- if (!dac) {
- if (spec->multiout.num_dacs > 0) {
- /* we have already working output pins,
- * so let's drop the broken ones again
- */
- cfg->line_outs = spec->multiout.num_dacs;
- break;
- }
- /* error out, no available DAC found */
- snd_printk(KERN_ERR
- "%s: No available DAC for pin 0x%x\n",
- __func__, nid);
- return -ENODEV;
- }
- add_spec_dacs(spec, dac);
- }
-
- for (i = 0; i < cfg->hp_outs; i++) {
- nid = cfg->hp_pins[i];
- dac = get_unassigned_dac(codec, nid);
- if (dac) {
- if (!spec->multiout.hp_nid)
- spec->multiout.hp_nid = dac;
- else
- add_spec_extra_dacs(spec, dac);
- }
- spec->hp_dacs[i] = dac;
- }
-
- for (i = 0; i < cfg->speaker_outs; i++) {
- nid = cfg->speaker_pins[i];
- dac = get_unassigned_dac(codec, nid);
- if (dac)
- add_spec_extra_dacs(spec, dac);
- spec->speaker_dacs[i] = dac;
- }
-
- /* add line-in as output */
- nid = check_line_out_switch(codec);
- if (nid) {
- dac = get_unassigned_dac(codec, nid);
- if (dac) {
- snd_printdd("STAC: Add line-in 0x%x as output %d\n",
- nid, cfg->line_outs);
- cfg->line_out_pins[cfg->line_outs] = nid;
- cfg->line_outs++;
- spec->line_switch = nid;
- add_spec_dacs(spec, dac);
- }
- }
- /* add mic as output */
- nid = check_mic_out_switch(codec, &dac);
- if (nid && dac) {
- snd_printdd("STAC: Add mic-in 0x%x as output %d\n",
- nid, cfg->line_outs);
- cfg->line_out_pins[cfg->line_outs] = nid;
- cfg->line_outs++;
- spec->mic_switch = nid;
- add_spec_dacs(spec, dac);
- }
-
- snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
- spec->multiout.num_dacs,
- spec->multiout.dac_nids[0],
- spec->multiout.dac_nids[1],
- spec->multiout.dac_nids[2],
- spec->multiout.dac_nids[3],
- spec->multiout.dac_nids[4]);
-
- return 0;
-}
-
-/* create volume control/switch for the given prefx type */
-static int create_controls_idx(struct hda_codec *codec, const char *pfx,
- int idx, hda_nid_t nid, int chs)
-{
- struct sigmatel_spec *spec = codec->spec;
- char name[32];
- int err;
-
- if (!spec->check_volume_offset) {
- unsigned int caps, step, nums, db_scale;
- caps = query_amp_caps(codec, nid, HDA_OUTPUT);
- step = (caps & AC_AMPCAP_STEP_SIZE) >>
- AC_AMPCAP_STEP_SIZE_SHIFT;
- step = (step + 1) * 25; /* in .01dB unit */
- nums = (caps & AC_AMPCAP_NUM_STEPS) >>
- AC_AMPCAP_NUM_STEPS_SHIFT;
- db_scale = nums * step;
- /* if dB scale is over -64dB, and finer enough,
- * let's reduce it to half
- */
- if (db_scale > 6400 && nums >= 0x1f)
- spec->volume_offset = nums / 2;
- spec->check_volume_offset = 1;
- }
-
- sprintf(name, "%s Playback Volume", pfx);
- err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_VOL, idx, name,
- HDA_COMPOSE_AMP_VAL_OFS(nid, chs, 0, HDA_OUTPUT,
- spec->volume_offset));
- if (err < 0)
- return err;
- sprintf(name, "%s Playback Switch", pfx);
- err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_MUTE, idx, name,
- HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
- if (err < 0)
- return err;
- return 0;
-}
-
-#define create_controls(codec, pfx, nid, chs) \
- create_controls_idx(codec, pfx, 0, nid, chs)
-
-static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
-{
- if (spec->multiout.num_dacs > 4) {
- printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
- return 1;
- } else {
- snd_BUG_ON(spec->multiout.dac_nids != spec->dac_nids);
- spec->dac_nids[spec->multiout.num_dacs] = nid;
- spec->multiout.num_dacs++;
- }
- return 0;
-}
-
-static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) {
- if (!spec->multiout.extra_out_nid[i]) {
- spec->multiout.extra_out_nid[i] = nid;
- return 0;
- }
- }
- printk(KERN_WARNING "stac92xx: No space for extra DAC 0x%x\n", nid);
- return 1;
-}
-
-/* Create output controls
- * The mixer elements are named depending on the given type (AUTO_PIN_XXX_OUT)
- */
-static int create_multi_out_ctls(struct hda_codec *codec, int num_outs,
- const hda_nid_t *pins,
- const hda_nid_t *dac_nids,
- int type)
-{
- struct sigmatel_spec *spec = codec->spec;
- static const char * const chname[4] = {
- "Front", "Surround", NULL /*CLFE*/, "Side"
- };
- hda_nid_t nid;
- int i, err;
- unsigned int wid_caps;
-
- for (i = 0; i < num_outs && i < ARRAY_SIZE(chname); i++) {
- if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) {
- if (is_jack_detectable(codec, pins[i]))
- spec->hp_detect = 1;
- }
- nid = dac_nids[i];
- if (!nid)
- continue;
- if (type != AUTO_PIN_HP_OUT && i == 2) {
- /* Center/LFE */
- err = create_controls(codec, "Center", nid, 1);
- if (err < 0)
- return err;
- err = create_controls(codec, "LFE", nid, 2);
- if (err < 0)
- return err;
-
- wid_caps = get_wcaps(codec, nid);
-
- if (wid_caps & AC_WCAP_LR_SWAP) {
- err = stac92xx_add_control(spec,
- STAC_CTL_WIDGET_CLFE_SWITCH,
- "Swap Center/LFE Playback Switch", nid);
-
- if (err < 0)
- return err;
- }
-
- } else {
- const char *name;
- int idx;
- switch (type) {
- case AUTO_PIN_HP_OUT:
- name = "Headphone";
- idx = i;
- break;
- case AUTO_PIN_SPEAKER_OUT:
- name = "Speaker";
- idx = i;
- break;
- default:
- name = chname[i];
- idx = 0;
- break;
- }
- err = create_controls_idx(codec, name, idx, nid, 3);
- if (err < 0)
- return err;
- }
- }
- return 0;
-}
-
-static int stac92xx_add_capvol_ctls(struct hda_codec *codec, unsigned long vol,
- unsigned long sw, int idx)
-{
- int err;
- err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_VOL, idx,
- "Capture Volume", vol);
- if (err < 0)
- return err;
- err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_MUTE, idx,
- "Capture Switch", sw);
- if (err < 0)
- return err;
- return 0;
-}
-
-/* add playback controls from the parsed DAC table */
-static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
- const struct auto_pin_cfg *cfg)
-{
- struct sigmatel_spec *spec = codec->spec;
- hda_nid_t nid;
- int err;
- int idx;
-
- err = create_multi_out_ctls(codec, cfg->line_outs, cfg->line_out_pins,
- spec->multiout.dac_nids,
- cfg->line_out_type);
- if (err < 0)
- return err;
-
- if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) {
- err = stac92xx_add_control(spec,
- STAC_CTL_WIDGET_HP_SWITCH,
- "Headphone as Line Out Switch",
- cfg->hp_pins[cfg->hp_outs - 1]);
- if (err < 0)
- return err;
- }
-
- for (idx = 0; idx < cfg->num_inputs; idx++) {
- if (cfg->inputs[idx].type > AUTO_PIN_LINE_IN)
- break;
- nid = cfg->inputs[idx].pin;
- err = stac92xx_add_jack_mode_control(codec, nid, idx);
- if (err < 0)
- return err;
- }
-
- return 0;
-}
-
-/* add playback controls for Speaker and HP outputs */
-static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
- struct auto_pin_cfg *cfg)
-{
- struct sigmatel_spec *spec = codec->spec;
- int err;
-
- err = create_multi_out_ctls(codec, cfg->hp_outs, cfg->hp_pins,
- spec->hp_dacs, AUTO_PIN_HP_OUT);
- if (err < 0)
- return err;
-
- err = create_multi_out_ctls(codec, cfg->speaker_outs, cfg->speaker_pins,
- spec->speaker_dacs, AUTO_PIN_SPEAKER_OUT);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-/* labels for mono mux outputs */
-static const char * const stac92xx_mono_labels[4] = {
- "DAC0", "DAC1", "Mixer", "DAC2"
-};
-
-/* create mono mux for mono out on capable codecs */
-static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
- struct hda_input_mux *mono_mux = &spec->private_mono_mux;
- int i, num_cons;
- hda_nid_t con_lst[ARRAY_SIZE(stac92xx_mono_labels)];
-
- num_cons = snd_hda_get_connections(codec,
- spec->mono_nid,
- con_lst,
- HDA_MAX_NUM_INPUTS);
- if (num_cons <= 0 || num_cons > ARRAY_SIZE(stac92xx_mono_labels))
- return -EINVAL;
-
- for (i = 0; i < num_cons; i++)
- snd_hda_add_imux_item(mono_mux, stac92xx_mono_labels[i], i,
- NULL);
-
- return stac92xx_add_control(spec, STAC_CTL_WIDGET_MONO_MUX,
- "Mono Mux", spec->mono_nid);
-}
-
-/* create PC beep volume controls */
-static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec,
- hda_nid_t nid)
-{
- struct sigmatel_spec *spec = codec->spec;
- u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
- int err, type = STAC_CTL_WIDGET_MUTE_BEEP;
-
- if (spec->anabeep_nid == nid)
- type = STAC_CTL_WIDGET_MUTE;
-
- /* check for mute support for the the amp */
- if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) {
- err = stac92xx_add_control(spec, type,
- "Beep Playback Switch",
- HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT));
- if (err < 0)
- return err;
- }
-
- /* check to see if there is volume support for the amp */
- if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) {
- err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL,
- "Beep Playback Volume",
- HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT));
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-#ifdef CONFIG_SND_HDA_INPUT_BEEP
-#define stac92xx_dig_beep_switch_info snd_ctl_boolean_mono_info
-
-static int stac92xx_dig_beep_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = codec->beep->enabled;
- return 0;
-}
-
-static int stac92xx_dig_beep_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- return snd_hda_enable_beep_device(codec, ucontrol->value.integer.value[0]);
-}
-
-static const struct snd_kcontrol_new stac92xx_dig_beep_ctrl = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = stac92xx_dig_beep_switch_info,
- .get = stac92xx_dig_beep_switch_get,
- .put = stac92xx_dig_beep_switch_put,
-};
-
-static int stac92xx_beep_switch_ctl(struct hda_codec *codec)
-{
- return stac92xx_add_control_temp(codec->spec, &stac92xx_dig_beep_ctrl,
- 0, "Beep Playback Switch", 0);
-}
-#endif
-
-static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
- int i, j, err = 0;
-
- for (i = 0; i < spec->num_muxes; i++) {
- hda_nid_t nid;
- unsigned int wcaps;
- unsigned long val;
-
- nid = spec->mux_nids[i];
- wcaps = get_wcaps(codec, nid);
- if (!(wcaps & AC_WCAP_OUT_AMP))
- continue;
-
- /* check whether already the same control was created as
- * normal Capture Volume.
- */
- val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
- for (j = 0; j < spec->num_caps; j++) {
- if (spec->capvols[j] == val)
- break;
- }
- if (j < spec->num_caps)
- continue;
-
- err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_VOL, i,
- "Mux Capture Volume", val);
- if (err < 0)
- return err;
- }
- return 0;
-};
-
-static const char * const stac92xx_spdif_labels[3] = {
- "Digital Playback", "Analog Mux 1", "Analog Mux 2",
-};
-
-static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
- struct hda_input_mux *spdif_mux = &spec->private_smux;
- const char * const *labels = spec->spdif_labels;
- int i, num_cons;
- hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
-
- num_cons = snd_hda_get_connections(codec,
- spec->smux_nids[0],
- con_lst,
- HDA_MAX_NUM_INPUTS);
- if (num_cons <= 0)
- return -EINVAL;
-
- if (!labels)
- labels = stac92xx_spdif_labels;
-
- for (i = 0; i < num_cons; i++)
- snd_hda_add_imux_item(spdif_mux, labels[i], i, NULL);
-
- return 0;
-}
-
-/* labels for dmic mux inputs */
-static const char * const stac92xx_dmic_labels[5] = {
- "Analog Inputs", "Digital Mic 1", "Digital Mic 2",
- "Digital Mic 3", "Digital Mic 4"
-};
-
-static hda_nid_t get_connected_node(struct hda_codec *codec, hda_nid_t mux,
- int idx)
-{
- hda_nid_t conn[HDA_MAX_NUM_INPUTS];
- int nums;
- nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
- if (idx >= 0 && idx < nums)
- return conn[idx];
- return 0;
-}
-
-/* look for NID recursively */
-#define get_connection_index(codec, mux, nid) \
- snd_hda_get_conn_index(codec, mux, nid, 1)
-
-/* create a volume assigned to the given pin (only if supported) */
-/* return 1 if the volume control is created */
-static int create_elem_capture_vol(struct hda_codec *codec, hda_nid_t nid,
- const char *label, int idx, int direction)
-{
- unsigned int caps, nums;
- char name[32];
- int err;
-
- if (direction == HDA_OUTPUT)
- caps = AC_WCAP_OUT_AMP;
- else
- caps = AC_WCAP_IN_AMP;
- if (!(get_wcaps(codec, nid) & caps))
- return 0;
- caps = query_amp_caps(codec, nid, direction);
- nums = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
- if (!nums)
- return 0;
- snprintf(name, sizeof(name), "%s Capture Volume", label);
- err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_VOL, idx, name,
- HDA_COMPOSE_AMP_VAL(nid, 3, 0, direction));
- if (err < 0)
- return err;
- return 1;
-}
-
-/* create playback/capture controls for input pins on dmic capable codecs */
-static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
- const struct auto_pin_cfg *cfg)
-{
- struct sigmatel_spec *spec = codec->spec;
- struct hda_input_mux *imux = &spec->private_imux;
- struct hda_input_mux *dimux = &spec->private_dimux;
- int err, i;
- unsigned int def_conf;
-
- snd_hda_add_imux_item(dimux, stac92xx_dmic_labels[0], 0, NULL);
-
- for (i = 0; i < spec->num_dmics; i++) {
- hda_nid_t nid;
- int index, type_idx;
- char label[32];
-
- nid = spec->dmic_nids[i];
- if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
- continue;
- def_conf = snd_hda_codec_get_pincfg(codec, nid);
- if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
- continue;
-
- index = get_connection_index(codec, spec->dmux_nids[0], nid);
- if (index < 0)
- continue;
-
- snd_hda_get_pin_label(codec, nid, &spec->autocfg,
- label, sizeof(label), NULL);
- snd_hda_add_imux_item(dimux, label, index, &type_idx);
- if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1)
- snd_hda_add_imux_item(imux, label, index, &type_idx);
-
- err = create_elem_capture_vol(codec, nid, label, type_idx,
- HDA_INPUT);
- if (err < 0)
- return err;
- if (!err) {
- err = create_elem_capture_vol(codec, nid, label,
- type_idx, HDA_OUTPUT);
- if (err < 0)
- return err;
- if (!err) {
- nid = get_connected_node(codec,
- spec->dmux_nids[0], index);
- if (nid)
- err = create_elem_capture_vol(codec,
- nid, label,
- type_idx, HDA_INPUT);
- if (err < 0)
- return err;
- }
- }
- }
-
- return 0;
-}
-
-static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid,
- hda_nid_t *fixed, hda_nid_t *ext, hda_nid_t *dock)
-{
- unsigned int cfg;
- unsigned int type;
-
- if (!nid)
- return 0;
- cfg = snd_hda_codec_get_pincfg(codec, nid);
- type = get_defcfg_device(cfg);
- switch (snd_hda_get_input_pin_attr(cfg)) {
- case INPUT_PIN_ATTR_INT:
- if (*fixed)
- return 1; /* already occupied */
- if (type != AC_JACK_MIC_IN)
- return 1; /* invalid type */
- *fixed = nid;
- break;
- case INPUT_PIN_ATTR_UNUSED:
- break;
- case INPUT_PIN_ATTR_DOCK:
- if (*dock)
- return 1; /* already occupied */
- if (type != AC_JACK_MIC_IN && type != AC_JACK_LINE_IN)
- return 1; /* invalid type */
- *dock = nid;
- break;
- default:
- if (*ext)
- return 1; /* already occupied */
- if (type != AC_JACK_MIC_IN)
- return 1; /* invalid type */
- *ext = nid;
- break;
- }
- return 0;
-}
-
-static int set_mic_route(struct hda_codec *codec,
- struct sigmatel_mic_route *mic,
- hda_nid_t pin)
-{
- struct sigmatel_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i;
-
- mic->pin = pin;
- if (pin == 0)
- return 0;
- for (i = 0; i < cfg->num_inputs; i++) {
- if (pin == cfg->inputs[i].pin)
- break;
- }
- if (i < cfg->num_inputs && cfg->inputs[i].type == AUTO_PIN_MIC) {
- /* analog pin */
- i = get_connection_index(codec, spec->mux_nids[0], pin);
- if (i < 0)
- return -1;
- mic->mux_idx = i;
- mic->dmux_idx = -1;
- if (spec->dmux_nids)
- mic->dmux_idx = get_connection_index(codec,
- spec->dmux_nids[0],
- spec->mux_nids[0]);
- } else if (spec->dmux_nids) {
- /* digital pin */
- i = get_connection_index(codec, spec->dmux_nids[0], pin);
- if (i < 0)
- return -1;
- mic->dmux_idx = i;
- mic->mux_idx = -1;
- if (spec->mux_nids)
- mic->mux_idx = get_connection_index(codec,
- spec->mux_nids[0],
- spec->dmux_nids[0]);
- }
- return 0;
-}
-
-/* return non-zero if the device is for automatic mic switch */
-static int stac_check_auto_mic(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- hda_nid_t fixed, ext, dock;
- int i;
-
- fixed = ext = dock = 0;
- for (i = 0; i < cfg->num_inputs; i++)
- if (check_mic_pin(codec, cfg->inputs[i].pin,
- &fixed, &ext, &dock))
- return 0;
- for (i = 0; i < spec->num_dmics; i++)
- if (check_mic_pin(codec, spec->dmic_nids[i],
- &fixed, &ext, &dock))
- return 0;
- if (!fixed || (!ext && !dock))
- return 0; /* no input to switch */
- if (!is_jack_detectable(codec, ext))
- return 0; /* no unsol support */
- if (set_mic_route(codec, &spec->ext_mic, ext) ||
- set_mic_route(codec, &spec->int_mic, fixed) ||
- set_mic_route(codec, &spec->dock_mic, dock))
- return 0; /* something is wrong */
- return 1;
-}
-
-/* create playback/capture controls for input pins */
-static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
-{
- struct sigmatel_spec *spec = codec->spec;
- struct hda_input_mux *imux = &spec->private_imux;
- int i, j;
- const char *label;
-
- for (i = 0; i < cfg->num_inputs; i++) {
- hda_nid_t nid = cfg->inputs[i].pin;
- int index, err, type_idx;
-
- index = -1;
- for (j = 0; j < spec->num_muxes; j++) {
- index = get_connection_index(codec, spec->mux_nids[j],
- nid);
- if (index >= 0)
- break;
- }
- if (index < 0)
- continue;
-
- label = hda_get_autocfg_input_label(codec, cfg, i);
- snd_hda_add_imux_item(imux, label, index, &type_idx);
-
- err = create_elem_capture_vol(codec, nid,
- label, type_idx,
- HDA_INPUT);
- if (err < 0)
- return err;
- }
- spec->num_analog_muxes = imux->num_items;
-
- if (imux->num_items) {
- /*
- * Set the current input for the muxes.
- * The STAC9221 has two input muxes with identical source
- * NID lists. Hopefully this won't get confused.
- */
- for (i = 0; i < spec->num_muxes; i++) {
- snd_hda_codec_write_cache(codec, spec->mux_nids[i], 0,
- AC_VERB_SET_CONNECT_SEL,
- imux->items[0].index);
- }
- }
-
- return 0;
-}
-
-static void stac92xx_auto_init_multi_out(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
- int i;
-
- for (i = 0; i < spec->autocfg.line_outs; i++) {
- hda_nid_t nid = spec->autocfg.line_out_pins[i];
- stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
- }
-}
-
-static void stac92xx_auto_init_hp_out(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
- int i;
-
- for (i = 0; i < spec->autocfg.hp_outs; i++) {
- hda_nid_t pin;
- pin = spec->autocfg.hp_pins[i];
- if (pin) /* connect to front */
- stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
- }
- for (i = 0; i < spec->autocfg.speaker_outs; i++) {
- hda_nid_t pin;
- pin = spec->autocfg.speaker_pins[i];
- if (pin) /* connect to front */
- stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN);
- }
-}
-
-static int is_dual_headphones(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
- int i, valid_hps;
-
- if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT ||
- spec->autocfg.hp_outs <= 1)
- return 0;
- valid_hps = 0;
- for (i = 0; i < spec->autocfg.hp_outs; i++) {
- hda_nid_t nid = spec->autocfg.hp_pins[i];
- unsigned int cfg = snd_hda_codec_get_pincfg(codec, nid);
- if (get_defcfg_location(cfg) & AC_JACK_LOC_SEPARATE)
- continue;
- valid_hps++;
- }
- return (valid_hps > 1);
-}
-
-
-static int stac92xx_parse_auto_config(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
- hda_nid_t dig_out = 0, dig_in = 0;
- int hp_swap = 0;
- int i, err;
-
- if ((err = snd_hda_parse_pin_def_config(codec,
- &spec->autocfg,
- spec->dmic_nids)) < 0)
- return err;
- if (! spec->autocfg.line_outs)
- return 0; /* can't find valid pin config */
-
- /* If we have no real line-out pin and multiple hp-outs, HPs should
- * be set up as multi-channel outputs.
- */
- if (is_dual_headphones(codec)) {
- /* Copy hp_outs to line_outs, backup line_outs in
- * speaker_outs so that the following routines can handle
- * HP pins as primary outputs.
- */
- snd_printdd("stac92xx: Enabling multi-HPs workaround\n");
- memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins,
- sizeof(spec->autocfg.line_out_pins));
- spec->autocfg.speaker_outs = spec->autocfg.line_outs;
- memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins,
- sizeof(spec->autocfg.hp_pins));
- spec->autocfg.line_outs = spec->autocfg.hp_outs;
- spec->autocfg.line_out_type = AUTO_PIN_HP_OUT;
- spec->autocfg.hp_outs = 0;
- hp_swap = 1;
- }
- if (spec->autocfg.mono_out_pin) {
- int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) &
- (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP);
- u32 caps = query_amp_caps(codec,
- spec->autocfg.mono_out_pin, dir);
- hda_nid_t conn_list[1];
-
- /* get the mixer node and then the mono mux if it exists */
- if (snd_hda_get_connections(codec,
- spec->autocfg.mono_out_pin, conn_list, 1) &&
- snd_hda_get_connections(codec, conn_list[0],
- conn_list, 1) > 0) {
-
- int wcaps = get_wcaps(codec, conn_list[0]);
- int wid_type = get_wcaps_type(wcaps);
- /* LR swap check, some stac925x have a mux that
- * changes the DACs output path instead of the
- * mono-mux path.
- */
- if (wid_type == AC_WID_AUD_SEL &&
- !(wcaps & AC_WCAP_LR_SWAP))
- spec->mono_nid = conn_list[0];
- }
- if (dir) {
- hda_nid_t nid = spec->autocfg.mono_out_pin;
-
- /* most mono outs have a least a mute/unmute switch */
- dir = (dir & AC_WCAP_OUT_AMP) ? HDA_OUTPUT : HDA_INPUT;
- err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE,
- "Mono Playback Switch",
- HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir));
- if (err < 0)
- return err;
- /* check for volume support for the amp */
- if ((caps & AC_AMPCAP_NUM_STEPS)
- >> AC_AMPCAP_NUM_STEPS_SHIFT) {
- err = stac92xx_add_control(spec,
- STAC_CTL_WIDGET_VOL,
- "Mono Playback Volume",
- HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir));
- if (err < 0)
- return err;
- }
- }
-
- stac92xx_auto_set_pinctl(codec, spec->autocfg.mono_out_pin,
- AC_PINCTL_OUT_EN);
- }
-
- if (!spec->multiout.num_dacs) {
- err = stac92xx_auto_fill_dac_nids(codec);
- if (err < 0)
- return err;
- err = stac92xx_auto_create_multi_out_ctls(codec,
- &spec->autocfg);
- if (err < 0)
- return err;
- }
-
- /* setup analog beep controls */
- if (spec->anabeep_nid > 0) {
- err = stac92xx_auto_create_beep_ctls(codec,
- spec->anabeep_nid);
- if (err < 0)
- return err;
- }
-
- /* setup digital beep controls and input device */
-#ifdef CONFIG_SND_HDA_INPUT_BEEP
- if (spec->digbeep_nid > 0) {
- hda_nid_t nid = spec->digbeep_nid;
- unsigned int caps;
-
- err = stac92xx_auto_create_beep_ctls(codec, nid);
- if (err < 0)
- return err;
- err = snd_hda_attach_beep_device(codec, nid);
- if (err < 0)
- return err;
- if (codec->beep) {
- /* IDT/STAC codecs have linear beep tone parameter */
- codec->beep->linear_tone = spec->linear_tone_beep;
- /* if no beep switch is available, make its own one */
- caps = query_amp_caps(codec, nid, HDA_OUTPUT);
- if (!(caps & AC_AMPCAP_MUTE)) {
- err = stac92xx_beep_switch_ctl(codec);
- if (err < 0)
- return err;
- }
- }
- }
-#endif
-
- err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
- if (err < 0)
- return err;
-
- /* All output parsing done, now restore the swapped hp pins */
- if (hp_swap) {
- memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins,
- sizeof(spec->autocfg.hp_pins));
- spec->autocfg.hp_outs = spec->autocfg.line_outs;
- spec->autocfg.line_out_type = AUTO_PIN_HP_OUT;
- spec->autocfg.line_outs = 0;
- }
-
- if (stac_check_auto_mic(codec)) {
- spec->auto_mic = 1;
- /* only one capture for auto-mic */
- spec->num_adcs = 1;
- spec->num_caps = 1;
- spec->num_muxes = 1;
- }
-
- for (i = 0; i < spec->num_caps; i++) {
- err = stac92xx_add_capvol_ctls(codec, spec->capvols[i],
- spec->capsws[i], i);
- if (err < 0)
- return err;
- }
-
- err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg);
- if (err < 0)
- return err;
-
- if (spec->mono_nid > 0) {
- err = stac92xx_auto_create_mono_output_ctls(codec);
- if (err < 0)
- return err;
- }
- if (spec->num_dmics > 0 && !spec->dinput_mux)
- if ((err = stac92xx_auto_create_dmic_input_ctls(codec,
- &spec->autocfg)) < 0)
- return err;
- if (spec->num_muxes > 0) {
- err = stac92xx_auto_create_mux_input_ctls(codec);
- if (err < 0)
- return err;
- }
- if (spec->num_smuxes > 0) {
- err = stac92xx_auto_create_spdif_mux_ctls(codec);
- if (err < 0)
- return err;
- }
-
- err = stac92xx_add_input_source(spec);
- if (err < 0)
- return err;
-
- spec->multiout.max_channels = spec->multiout.num_dacs * 2;
- if (spec->multiout.max_channels > 2)
- spec->surr_switch = 1;
-
- /* find digital out and in converters */
- for (i = codec->start_nid; i < codec->start_nid + codec->num_nodes; i++) {
- unsigned int wid_caps = get_wcaps(codec, i);
- if (wid_caps & AC_WCAP_DIGITAL) {
- switch (get_wcaps_type(wid_caps)) {
- case AC_WID_AUD_OUT:
- if (!dig_out)
- dig_out = i;
- break;
- case AC_WID_AUD_IN:
- if (!dig_in)
- dig_in = i;
- break;
- }
- }
- }
- if (spec->autocfg.dig_outs)
- spec->multiout.dig_out_nid = dig_out;
- if (dig_in && spec->autocfg.dig_in_pin)
- spec->dig_in_nid = dig_in;
-
- if (spec->kctls.list)
- spec->mixers[spec->num_mixers++] = spec->kctls.list;
-
- spec->input_mux = &spec->private_imux;
- if (!spec->dinput_mux)
- spec->dinput_mux = &spec->private_dimux;
- spec->sinput_mux = &spec->private_smux;
- spec->mono_mux = &spec->private_mono_mux;
- return 1;
-}
-
-/* add playback controls for HP output */
-static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
- struct auto_pin_cfg *cfg)
-{
- struct sigmatel_spec *spec = codec->spec;
- hda_nid_t pin = cfg->hp_pins[0];
-
- if (! pin)
- return 0;
-
- if (is_jack_detectable(codec, pin))
- spec->hp_detect = 1;
-
- return 0;
-}
-
-/* add playback controls for LFE output */
-static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec,
- struct auto_pin_cfg *cfg)
-{
- struct sigmatel_spec *spec = codec->spec;
- int err;
- hda_nid_t lfe_pin = 0x0;
- int i;
-
- /*
- * search speaker outs and line outs for a mono speaker pin
- * with an amp. If one is found, add LFE controls
- * for it.
- */
- for (i = 0; i < spec->autocfg.speaker_outs && lfe_pin == 0x0; i++) {
- hda_nid_t pin = spec->autocfg.speaker_pins[i];
- unsigned int wcaps = get_wcaps(codec, pin);
- wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
- if (wcaps == AC_WCAP_OUT_AMP)
- /* found a mono speaker with an amp, must be lfe */
- lfe_pin = pin;
- }
-
- /* if speaker_outs is 0, then speakers may be in line_outs */
- if (lfe_pin == 0 && spec->autocfg.speaker_outs == 0) {
- for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) {
- hda_nid_t pin = spec->autocfg.line_out_pins[i];
- unsigned int defcfg;
- defcfg = snd_hda_codec_get_pincfg(codec, pin);
- if (get_defcfg_device(defcfg) == AC_JACK_SPEAKER) {
- unsigned int wcaps = get_wcaps(codec, pin);
- wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP);
- if (wcaps == AC_WCAP_OUT_AMP)
- /* found a mono speaker with an amp,
- must be lfe */
- lfe_pin = pin;
- }
- }
- }
-
- if (lfe_pin) {
- err = create_controls(codec, "LFE", lfe_pin, 1);
- if (err < 0)
- return err;
- }
-
- return 0;
-}
-
-static int stac9200_parse_auto_config(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
- int err;
-
- if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
- return err;
-
- if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
- return err;
-
- if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0)
- return err;
-
- if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)
- return err;
-
- if (spec->num_muxes > 0) {
- err = stac92xx_auto_create_mux_input_ctls(codec);
- if (err < 0)
- return err;
- }
-
- err = stac92xx_add_input_source(spec);
- if (err < 0)
- return err;
-
- if (spec->autocfg.dig_outs)
- spec->multiout.dig_out_nid = 0x05;
- if (spec->autocfg.dig_in_pin)
- spec->dig_in_nid = 0x04;
-
- if (spec->kctls.list)
- spec->mixers[spec->num_mixers++] = spec->kctls.list;
-
- spec->input_mux = &spec->private_imux;
- spec->dinput_mux = &spec->private_dimux;
-
- return 1;
-}
-
-/*
- * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
- * funky external mute control using GPIO pins.
- */
-
-static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
- unsigned int dir_mask, unsigned int data)
-{
- unsigned int gpiostate, gpiomask, gpiodir;
-
- snd_printdd("%s msk %x dir %x gpio %x\n", __func__, mask, dir_mask, data);
-
- gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
- AC_VERB_GET_GPIO_DATA, 0);
- gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask);
-
- gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
- AC_VERB_GET_GPIO_MASK, 0);
- gpiomask |= mask;
-
- gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
- AC_VERB_GET_GPIO_DIRECTION, 0);
- gpiodir |= dir_mask;
-
- /* Configure GPIOx as CMOS */
- snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0);
-
- snd_hda_codec_write(codec, codec->afg, 0,
- AC_VERB_SET_GPIO_MASK, gpiomask);
- snd_hda_codec_read(codec, codec->afg, 0,
- AC_VERB_SET_GPIO_DIRECTION, gpiodir); /* sync */
-
- msleep(1);
-
- snd_hda_codec_read(codec, codec->afg, 0,
- AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
-}
-
-static int stac_add_event(struct hda_codec *codec, hda_nid_t nid,
- unsigned char type, int data)
-{
- struct hda_jack_tbl *event;
-
- event = snd_hda_jack_tbl_new(codec, nid);
- if (!event)
- return -ENOMEM;
- event->action = type;
- event->private_data = data;
-
- return 0;
-}
-
-/* check if given nid is a valid pin and no other events are assigned
- * to it. If OK, assign the event, set the unsol flag, and returns 1.
- * Otherwise, returns zero.
- */
-static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
- unsigned int type)
-{
- struct hda_jack_tbl *event;
-
- if (!is_jack_detectable(codec, nid))
- return 0;
- event = snd_hda_jack_tbl_new(codec, nid);
- if (!event)
- return -ENOMEM;
- if (event->action && event->action != type)
- return 0;
- event->action = type;
- snd_hda_jack_detect_enable(codec, nid, 0);
- return 1;
-}
-
-static int is_nid_out_jack_pin(struct auto_pin_cfg *cfg, hda_nid_t nid)
-{
- int i;
- for (i = 0; i < cfg->hp_outs; i++)
- if (cfg->hp_pins[i] == nid)
- return 1; /* nid is a HP-Out */
- for (i = 0; i < cfg->line_outs; i++)
- if (cfg->line_out_pins[i] == nid)
- return 1; /* nid is a line-Out */
- return 0; /* nid is not a HP-Out */
-};
-
-static void stac92xx_power_down(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
-
- /* power down inactive DACs */
- const hda_nid_t *dac;
- for (dac = spec->dac_list; *dac; dac++)
- if (!check_all_dac_nids(spec, *dac))
- snd_hda_codec_write(codec, *dac, 0,
- AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
-}
-
-static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
- int enable);
-
-static inline int get_int_hint(struct hda_codec *codec, const char *key,
- int *valp)
-{
- const char *p;
- p = snd_hda_get_hint(codec, key);
- if (p) {
- unsigned long val;
- if (!strict_strtoul(p, 0, &val)) {
- *valp = val;
- return 1;
- }
- }
- return 0;
-}
-
-/* override some hints from the hwdep entry */
-static void stac_store_hints(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
- int val;
-
- val = snd_hda_get_bool_hint(codec, "hp_detect");
- if (val >= 0)
- spec->hp_detect = val;
- if (get_int_hint(codec, "gpio_mask", &spec->gpio_mask)) {
- spec->eapd_mask = spec->gpio_dir = spec->gpio_data =
- spec->gpio_mask;
- }
- if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir))
- spec->gpio_mask &= spec->gpio_mask;
- if (get_int_hint(codec, "gpio_data", &spec->gpio_data))
- spec->gpio_dir &= spec->gpio_mask;
- if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask))
- spec->eapd_mask &= spec->gpio_mask;
- if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute))
- spec->gpio_mute &= spec->gpio_mask;
- val = snd_hda_get_bool_hint(codec, "eapd_switch");
- if (val >= 0)
- spec->eapd_switch = val;
- get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity);
- if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
- spec->gpio_mask |= spec->gpio_led;
- spec->gpio_dir |= spec->gpio_led;
- if (spec->gpio_led_polarity)
- spec->gpio_data |= spec->gpio_led;
- }
-}
-
-static void stac_issue_unsol_events(struct hda_codec *codec, int num_pins,
- const hda_nid_t *pins)
-{
- while (num_pins--)
- stac_issue_unsol_event(codec, *pins++);
-}
-
-/* fake event to set up pins */
-static void stac_fake_hp_events(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
-
- if (spec->autocfg.hp_outs)
- stac_issue_unsol_events(codec, spec->autocfg.hp_outs,
- spec->autocfg.hp_pins);
- if (spec->autocfg.line_outs &&
- spec->autocfg.line_out_pins[0] != spec->autocfg.hp_pins[0])
- stac_issue_unsol_events(codec, spec->autocfg.line_outs,
- spec->autocfg.line_out_pins);
-}
-
-static int stac92xx_init(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- unsigned int gpio;
- int i;
-
- snd_hda_sequence_write(codec, spec->init);
-
- /* power down adcs initially */
- if (spec->powerdown_adcs)
- for (i = 0; i < spec->num_adcs; i++)
- snd_hda_codec_write(codec,
- spec->adc_nids[i], 0,
- AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
-
- /* override some hints */
- stac_store_hints(codec);
-
- /* set up GPIO */
- gpio = spec->gpio_data;
- /* turn on EAPD statically when spec->eapd_switch isn't set.
- * otherwise, unsol event will turn it on/off dynamically
- */
- if (!spec->eapd_switch)
- gpio |= spec->eapd_mask;
- stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, gpio);
-
- /* set up pins */
- if (spec->hp_detect) {
- /* Enable unsolicited responses on the HP widget */
- for (i = 0; i < cfg->hp_outs; i++) {
- hda_nid_t nid = cfg->hp_pins[i];
- enable_pin_detect(codec, nid, STAC_HP_EVENT);
- }
- if (cfg->line_out_type == AUTO_PIN_LINE_OUT &&
- cfg->speaker_outs > 0) {
- /* enable pin-detect for line-outs as well */
- for (i = 0; i < cfg->line_outs; i++) {
- hda_nid_t nid = cfg->line_out_pins[i];
- enable_pin_detect(codec, nid, STAC_LO_EVENT);
- }
- }
-
- /* force to enable the first line-out; the others are set up
- * in unsol_event
- */
- stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
- AC_PINCTL_OUT_EN);
- /* fake event to set up pins */
- stac_fake_hp_events(codec);
- } else {
- stac92xx_auto_init_multi_out(codec);
- stac92xx_auto_init_hp_out(codec);
- for (i = 0; i < cfg->hp_outs; i++)
- stac_toggle_power_map(codec, cfg->hp_pins[i], 1);
- }
- if (spec->auto_mic) {
- /* initialize connection to analog input */
- if (spec->dmux_nids)
- snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0,
- AC_VERB_SET_CONNECT_SEL, 0);
- if (enable_pin_detect(codec, spec->ext_mic.pin, STAC_MIC_EVENT))
- stac_issue_unsol_event(codec, spec->ext_mic.pin);
- if (enable_pin_detect(codec, spec->dock_mic.pin,
- STAC_MIC_EVENT))
- stac_issue_unsol_event(codec, spec->dock_mic.pin);
- }
- for (i = 0; i < cfg->num_inputs; i++) {
- hda_nid_t nid = cfg->inputs[i].pin;
- int type = cfg->inputs[i].type;
- unsigned int pinctl, conf;
- if (type == AUTO_PIN_MIC) {
- /* for mic pins, force to initialize */
- pinctl = stac92xx_get_default_vref(codec, nid);
- pinctl |= AC_PINCTL_IN_EN;
- stac92xx_auto_set_pinctl(codec, nid, pinctl);
- } else {
- pinctl = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
- /* if PINCTL already set then skip */
- /* Also, if both INPUT and OUTPUT are set,
- * it must be a BIOS bug; need to override, too
- */
- if (!(pinctl & AC_PINCTL_IN_EN) ||
- (pinctl & AC_PINCTL_OUT_EN)) {
- pinctl &= ~AC_PINCTL_OUT_EN;
- pinctl |= AC_PINCTL_IN_EN;
- stac92xx_auto_set_pinctl(codec, nid, pinctl);
- }
- }
- conf = snd_hda_codec_get_pincfg(codec, nid);
- if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) {
- if (enable_pin_detect(codec, nid, STAC_INSERT_EVENT))
- stac_issue_unsol_event(codec, nid);
- }
- }
- for (i = 0; i < spec->num_dmics; i++)
- stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
- AC_PINCTL_IN_EN);
- if (cfg->dig_out_pins[0])
- stac92xx_auto_set_pinctl(codec, cfg->dig_out_pins[0],
- AC_PINCTL_OUT_EN);
- if (cfg->dig_in_pin)
- stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
- AC_PINCTL_IN_EN);
- for (i = 0; i < spec->num_pwrs; i++) {
- hda_nid_t nid = spec->pwr_nids[i];
- unsigned int pinctl, def_conf;
-
- /* power on when no jack detection is available */
- /* or when the VREF is used for controlling LED */
- if (!spec->hp_detect ||
- spec->vref_mute_led_nid == nid) {
- stac_toggle_power_map(codec, nid, 1);
- continue;
- }
-
- if (is_nid_out_jack_pin(cfg, nid))
- continue; /* already has an unsol event */
-
- pinctl = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
- /* outputs are only ports capable of power management
- * any attempts on powering down a input port cause the
- * referenced VREF to act quirky.
- */
- if (pinctl & AC_PINCTL_IN_EN) {
- stac_toggle_power_map(codec, nid, 1);
- continue;
- }
- def_conf = snd_hda_codec_get_pincfg(codec, nid);
- def_conf = get_defcfg_connect(def_conf);
- /* skip any ports that don't have jacks since presence
- * detection is useless */
- if (def_conf != AC_JACK_PORT_COMPLEX ||
- !is_jack_detectable(codec, nid)) {
- stac_toggle_power_map(codec, nid, 1);
- continue;
- }
- if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) {
- stac_issue_unsol_event(codec, nid);
- continue;
- }
- /* none of the above, turn the port OFF */
- stac_toggle_power_map(codec, nid, 0);
- }
-
- snd_hda_jack_report_sync(codec);
-
- /* sync mute LED */
- snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
- if (spec->dac_list)
- stac92xx_power_down(codec);
- return 0;
-}
-
-static void stac92xx_free_kctls(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
-
- if (spec->kctls.list) {
- struct snd_kcontrol_new *kctl = spec->kctls.list;
- int i;
- for (i = 0; i < spec->kctls.used; i++)
- kfree(kctl[i].name);
- }
- snd_array_free(&spec->kctls);
-}
-
-static void stac92xx_shutup_pins(struct hda_codec *codec)
-{
- unsigned int i, def_conf;
-
- if (codec->bus->shutdown)
- return;
- for (i = 0; i < codec->init_pins.used; i++) {
- struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
- def_conf = snd_hda_codec_get_pincfg(codec, pin->nid);
- if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)
- snd_hda_codec_write(codec, pin->nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
- }
-}
-
-static void stac92xx_shutup(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
-
- stac92xx_shutup_pins(codec);
-
- if (spec->eapd_mask)
- stac_gpio_set(codec, spec->gpio_mask,
- spec->gpio_dir, spec->gpio_data &
- ~spec->eapd_mask);
-}
-
-static void stac92xx_free(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
-
- if (! spec)
- return;
-
- stac92xx_shutup(codec);
-
- kfree(spec);
- snd_hda_detach_beep_device(codec);
-}
-
-static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
- unsigned int flag)
-{
- unsigned int old_ctl, pin_ctl;
-
- pin_ctl = snd_hda_codec_read(codec, nid,
- 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
-
- if (pin_ctl & AC_PINCTL_IN_EN) {
- /*
- * we need to check the current set-up direction of
- * shared input pins since they can be switched via
- * "xxx as Output" mixer switch
- */
- struct sigmatel_spec *spec = codec->spec;
- if (nid == spec->line_switch || nid == spec->mic_switch)
- return;
- }
-
- old_ctl = pin_ctl;
- /* if setting pin direction bits, clear the current
- direction bits first */
- if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
- pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
-
- pin_ctl |= flag;
- if (old_ctl != pin_ctl)
- snd_hda_codec_write_cache(codec, nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- pin_ctl);
-}
-
-static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
- unsigned int flag)
-{
- unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
- 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
- if (pin_ctl & flag)
- snd_hda_codec_write_cache(codec, nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- pin_ctl & ~flag);
-}
-
-static inline int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
-{
- if (!nid)
- return 0;
- return snd_hda_jack_detect(codec, nid);
-}
-
-static void stac92xx_line_out_detect(struct hda_codec *codec,
- int presence)
-{
- struct sigmatel_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i;
-
- for (i = 0; i < cfg->line_outs; i++) {
- if (presence)
- break;
- presence = get_pin_presence(codec, cfg->line_out_pins[i]);
- if (presence) {
- unsigned int pinctl;
- pinctl = snd_hda_codec_read(codec,
- cfg->line_out_pins[i], 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
- if (pinctl & AC_PINCTL_IN_EN)
- presence = 0; /* mic- or line-input */
- }
- }
-
- if (presence) {
- /* disable speakers */
- for (i = 0; i < cfg->speaker_outs; i++)
- stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
- AC_PINCTL_OUT_EN);
- if (spec->eapd_mask && spec->eapd_switch)
- stac_gpio_set(codec, spec->gpio_mask,
- spec->gpio_dir, spec->gpio_data &
- ~spec->eapd_mask);
- } else {
- /* enable speakers */
- for (i = 0; i < cfg->speaker_outs; i++)
- stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
- AC_PINCTL_OUT_EN);
- if (spec->eapd_mask && spec->eapd_switch)
- stac_gpio_set(codec, spec->gpio_mask,
- spec->gpio_dir, spec->gpio_data |
- spec->eapd_mask);
- }
-}
-
-/* return non-zero if the hp-pin of the given array index isn't
- * a jack-detection target
- */
-static int no_hp_sensing(struct sigmatel_spec *spec, int i)
-{
- struct auto_pin_cfg *cfg = &spec->autocfg;
-
- /* ignore sensing of shared line and mic jacks */
- if (cfg->hp_pins[i] == spec->line_switch)
- return 1;
- if (cfg->hp_pins[i] == spec->mic_switch)
- return 1;
- /* ignore if the pin is set as line-out */
- if (cfg->hp_pins[i] == spec->hp_switch)
- return 1;
- return 0;
-}
-
-static void stac92xx_hp_detect(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- int i, presence;
-
- presence = 0;
- if (spec->gpio_mute)
- presence = !(snd_hda_codec_read(codec, codec->afg, 0,
- AC_VERB_GET_GPIO_DATA, 0) & spec->gpio_mute);
-
- for (i = 0; i < cfg->hp_outs; i++) {
- if (presence)
- break;
- if (no_hp_sensing(spec, i))
- continue;
- presence = get_pin_presence(codec, cfg->hp_pins[i]);
- if (presence) {
- unsigned int pinctl;
- pinctl = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
- if (pinctl & AC_PINCTL_IN_EN)
- presence = 0; /* mic- or line-input */
- }
- }
-
- if (presence) {
- /* disable lineouts */
- if (spec->hp_switch)
- stac92xx_reset_pinctl(codec, spec->hp_switch,
- AC_PINCTL_OUT_EN);
- for (i = 0; i < cfg->line_outs; i++)
- stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
- AC_PINCTL_OUT_EN);
- } else {
- /* enable lineouts */
- if (spec->hp_switch)
- stac92xx_set_pinctl(codec, spec->hp_switch,
- AC_PINCTL_OUT_EN);
- for (i = 0; i < cfg->line_outs; i++)
- stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
- AC_PINCTL_OUT_EN);
- }
- stac92xx_line_out_detect(codec, presence);
- /* toggle hp outs */
- for (i = 0; i < cfg->hp_outs; i++) {
- unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN;
- if (no_hp_sensing(spec, i))
- continue;
- if (1 /*presence*/)
- stac92xx_set_pinctl(codec, cfg->hp_pins[i], val);
-#if 0 /* FIXME */
-/* Resetting the pinctl like below may lead to (a sort of) regressions
- * on some devices since they use the HP pin actually for line/speaker
- * outs although the default pin config shows a different pin (that is
- * wrong and useless).
- *
- * So, it's basically a problem of default pin configs, likely a BIOS issue.
- * But, disabling the code below just works around it, and I'm too tired of
- * bug reports with such devices...
- */
- else
- stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val);
-#endif /* FIXME */
- }
-}
-
-static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
- int enable)
-{
- struct sigmatel_spec *spec = codec->spec;
- unsigned int idx, val;
-
- for (idx = 0; idx < spec->num_pwrs; idx++) {
- if (spec->pwr_nids[idx] == nid)
- break;
- }
- if (idx >= spec->num_pwrs)
- return;
-
- idx = 1 << idx;
-
- val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0xff;
- if (enable)
- val &= ~idx;
- else
- val |= idx;
-
- /* power down unused output ports */
- snd_hda_codec_write(codec, codec->afg, 0, 0x7ec, val);
-}
-
-static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid)
-{
- stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid));
-}
-
-/* get the pin connection (fixed, none, etc) */
-static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx)
-{
- struct sigmatel_spec *spec = codec->spec;
- unsigned int cfg;
-
- cfg = snd_hda_codec_get_pincfg(codec, spec->pin_nids[idx]);
- return get_defcfg_connect(cfg);
-}
-
-static int stac92xx_connected_ports(struct hda_codec *codec,
- const hda_nid_t *nids, int num_nids)
-{
- struct sigmatel_spec *spec = codec->spec;
- int idx, num;
- unsigned int def_conf;
-
- for (num = 0; num < num_nids; num++) {
- for (idx = 0; idx < spec->num_pins; idx++)
- if (spec->pin_nids[idx] == nids[num])
- break;
- if (idx >= spec->num_pins)
- break;
- def_conf = stac_get_defcfg_connect(codec, idx);
- if (def_conf == AC_JACK_PORT_NONE)
- break;
- }
- return num;
-}
-
-static void stac92xx_mic_detect(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
- struct sigmatel_mic_route *mic;
-
- if (get_pin_presence(codec, spec->ext_mic.pin))
- mic = &spec->ext_mic;
- else if (get_pin_presence(codec, spec->dock_mic.pin))
- mic = &spec->dock_mic;
- else
- mic = &spec->int_mic;
- if (mic->dmux_idx >= 0)
- snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0,
- AC_VERB_SET_CONNECT_SEL,
- mic->dmux_idx);
- if (mic->mux_idx >= 0)
- snd_hda_codec_write_cache(codec, spec->mux_nids[0], 0,
- AC_VERB_SET_CONNECT_SEL,
- mic->mux_idx);
-}
-
-static void handle_unsol_event(struct hda_codec *codec,
- struct hda_jack_tbl *event)
-{
- struct sigmatel_spec *spec = codec->spec;
- int data;
-
- switch (event->action) {
- case STAC_HP_EVENT:
- case STAC_LO_EVENT:
- stac92xx_hp_detect(codec);
- break;
- case STAC_MIC_EVENT:
- stac92xx_mic_detect(codec);
- break;
- }
-
- switch (event->action) {
- case STAC_HP_EVENT:
- case STAC_LO_EVENT:
- case STAC_MIC_EVENT:
- case STAC_INSERT_EVENT:
- case STAC_PWR_EVENT:
- if (spec->num_pwrs > 0)
- stac92xx_pin_sense(codec, event->nid);
-
- switch (codec->subsystem_id) {
- case 0x103c308f:
- if (event->nid == 0xb) {
- int pin = AC_PINCTL_IN_EN;
-
- if (get_pin_presence(codec, 0xa)
- && get_pin_presence(codec, 0xb))
- pin |= AC_PINCTL_VREF_80;
- if (!get_pin_presence(codec, 0xb))
- pin |= AC_PINCTL_VREF_80;
-
- /* toggle VREF state based on mic + hp pin
- * status
- */
- stac92xx_auto_set_pinctl(codec, 0x0a, pin);
- }
- }
- break;
- case STAC_VREF_EVENT:
- data = snd_hda_codec_read(codec, codec->afg, 0,
- AC_VERB_GET_GPIO_DATA, 0);
- /* toggle VREF state based on GPIOx status */
- snd_hda_codec_write(codec, codec->afg, 0, 0x7e0,
- !!(data & (1 << event->private_data)));
- break;
- }
-}
-
-static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid)
-{
- struct hda_jack_tbl *event = snd_hda_jack_tbl_get(codec, nid);
- if (!event)
- return;
- handle_unsol_event(codec, event);
-}
-
-static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- struct hda_jack_tbl *event;
- int tag;
-
- tag = (res >> 26) & 0x7f;
- event = snd_hda_jack_tbl_get_from_tag(codec, tag);
- if (!event)
- return;
- event->jack_dirty = 1;
- handle_unsol_event(codec, event);
- snd_hda_jack_report_sync(codec);
-}
-
-static int hp_blike_system(u32 subsystem_id);
-
-static void set_hp_led_gpio(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
- unsigned int gpio;
-
- if (spec->gpio_led)
- return;
-
- gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP);
- gpio &= AC_GPIO_IO_COUNT;
- if (gpio > 3)
- spec->gpio_led = 0x08; /* GPIO 3 */
- else
- spec->gpio_led = 0x01; /* GPIO 0 */
-}
-
-/*
- * This method searches for the mute LED GPIO configuration
- * provided as OEM string in SMBIOS. The format of that string
- * is HP_Mute_LED_P_G or HP_Mute_LED_P
- * where P can be 0 or 1 and defines mute LED GPIO control state (low/high)
- * that corresponds to the NOT muted state of the master volume
- * and G is the index of the GPIO to use as the mute LED control (0..9)
- * If _G portion is missing it is assigned based on the codec ID
- *
- * So, HP B-series like systems may have HP_Mute_LED_0 (current models)
- * or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings
- *
- *
- * The dv-series laptops don't seem to have the HP_Mute_LED* strings in
- * SMBIOS - at least the ones I have seen do not have them - which include
- * my own system (HP Pavilion dv6-1110ax) and my cousin's
- * HP Pavilion dv9500t CTO.
- * Need more information on whether it is true across the entire series.
- * -- kunal
- */
-static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity)
-{
- struct sigmatel_spec *spec = codec->spec;
- const struct dmi_device *dev = NULL;
-
- if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) {
- while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING,
- NULL, dev))) {
- if (sscanf(dev->name, "HP_Mute_LED_%d_%x",
- &spec->gpio_led_polarity,
- &spec->gpio_led) == 2) {
- unsigned int max_gpio;
- max_gpio = snd_hda_param_read(codec, codec->afg,
- AC_PAR_GPIO_CAP);
- max_gpio &= AC_GPIO_IO_COUNT;
- if (spec->gpio_led < max_gpio)
- spec->gpio_led = 1 << spec->gpio_led;
- else
- spec->vref_mute_led_nid = spec->gpio_led;
- return 1;
- }
- if (sscanf(dev->name, "HP_Mute_LED_%d",
- &spec->gpio_led_polarity) == 1) {
- set_hp_led_gpio(codec);
- return 1;
- }
- /* BIOS bug: unfilled OEM string */
- if (strstr(dev->name, "HP_Mute_LED_P_G")) {
- set_hp_led_gpio(codec);
- switch (codec->subsystem_id) {
- case 0x103c148a:
- spec->gpio_led_polarity = 0;
- break;
- default:
- spec->gpio_led_polarity = 1;
- break;
- }
- return 1;
- }
- }
-
- /*
- * Fallback case - if we don't find the DMI strings,
- * we statically set the GPIO - if not a B-series system
- * and default polarity is provided
- */
- if (!hp_blike_system(codec->subsystem_id) &&
- (default_polarity == 0 || default_polarity == 1)) {
- set_hp_led_gpio(codec);
- spec->gpio_led_polarity = default_polarity;
- return 1;
- }
- }
- return 0;
-}
-
-static int hp_blike_system(u32 subsystem_id)
-{
- switch (subsystem_id) {
- case 0x103c1520:
- case 0x103c1521:
- case 0x103c1523:
- case 0x103c1524:
- case 0x103c1525:
- case 0x103c1722:
- case 0x103c1723:
- case 0x103c1724:
- case 0x103c1725:
- case 0x103c1726:
- case 0x103c1727:
- case 0x103c1728:
- case 0x103c1729:
- case 0x103c172a:
- case 0x103c172b:
- case 0x103c307e:
- case 0x103c307f:
- case 0x103c3080:
- case 0x103c3081:
- case 0x103c7007:
- case 0x103c7008:
- return 1;
- }
- return 0;
-}
-
-#ifdef CONFIG_PROC_FS
-static void stac92hd_proc_hook(struct snd_info_buffer *buffer,
- struct hda_codec *codec, hda_nid_t nid)
-{
- if (nid == codec->afg)
- snd_iprintf(buffer, "Power-Map: 0x%02x\n",
- snd_hda_codec_read(codec, nid, 0, 0x0fec, 0x0));
-}
-
-static void analog_loop_proc_hook(struct snd_info_buffer *buffer,
- struct hda_codec *codec,
- unsigned int verb)
-{
- snd_iprintf(buffer, "Analog Loopback: 0x%02x\n",
- snd_hda_codec_read(codec, codec->afg, 0, verb, 0));
-}
-
-/* stac92hd71bxx, stac92hd73xx */
-static void stac92hd7x_proc_hook(struct snd_info_buffer *buffer,
- struct hda_codec *codec, hda_nid_t nid)
-{
- stac92hd_proc_hook(buffer, codec, nid);
- if (nid == codec->afg)
- analog_loop_proc_hook(buffer, codec, 0xfa0);
-}
-
-static void stac9205_proc_hook(struct snd_info_buffer *buffer,
- struct hda_codec *codec, hda_nid_t nid)
-{
- if (nid == codec->afg)
- analog_loop_proc_hook(buffer, codec, 0xfe0);
-}
-
-static void stac927x_proc_hook(struct snd_info_buffer *buffer,
- struct hda_codec *codec, hda_nid_t nid)
-{
- if (nid == codec->afg)
- analog_loop_proc_hook(buffer, codec, 0xfeb);
-}
-#else
-#define stac92hd_proc_hook NULL
-#define stac92hd7x_proc_hook NULL
-#define stac9205_proc_hook NULL
-#define stac927x_proc_hook NULL
-#endif
-
-#ifdef CONFIG_PM
-static int stac92xx_resume(struct hda_codec *codec)
-{
- stac92xx_init(codec);
- snd_hda_codec_resume_amp(codec);
- snd_hda_codec_resume_cache(codec);
- /* fake event to set up pins again to override cached values */
- stac_fake_hp_events(codec);
- return 0;
-}
-
-static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
-{
- stac92xx_shutup(codec);
- return 0;
-}
-
-static int stac92xx_pre_resume(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
-
- /* sync mute LED */
- if (spec->vref_mute_led_nid)
- stac_vrefout_set(codec, spec->vref_mute_led_nid,
- spec->vref_led);
- else if (spec->gpio_led)
- stac_gpio_set(codec, spec->gpio_mask,
- spec->gpio_dir, spec->gpio_data);
- return 0;
-}
-
-static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
- unsigned int power_state)
-{
- unsigned int afg_power_state = power_state;
- struct sigmatel_spec *spec = codec->spec;
-
- if (power_state == AC_PWRST_D3) {
- if (spec->vref_mute_led_nid) {
- /* with vref-out pin used for mute led control
- * codec AFG is prevented from D3 state
- */
- afg_power_state = AC_PWRST_D1;
- }
- /* this delay seems necessary to avoid click noise at power-down */
- msleep(100);
- }
- snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
- afg_power_state);
- snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
-}
-#else
-#define stac92xx_suspend NULL
-#define stac92xx_resume NULL
-#define stac92xx_pre_resume NULL
-#define stac92xx_set_power_state NULL
-#endif /* CONFIG_PM */
-
-/* update mute-LED accoring to the master switch */
-static void stac92xx_update_led_status(struct hda_codec *codec, int enabled)
-{
- struct sigmatel_spec *spec = codec->spec;
- int muted = !enabled;
-
- if (!spec->gpio_led)
- return;
-
- /* LED state is inverted on these systems */
- if (spec->gpio_led_polarity)
- muted = !muted;
-
- if (!spec->vref_mute_led_nid) {
- if (muted)
- spec->gpio_data |= spec->gpio_led;
- else
- spec->gpio_data &= ~spec->gpio_led;
- stac_gpio_set(codec, spec->gpio_mask,
- spec->gpio_dir, spec->gpio_data);
- } else {
- spec->vref_led = muted ? AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD;
- stac_vrefout_set(codec, spec->vref_mute_led_nid,
- spec->vref_led);
- }
-}
-
-static const struct hda_codec_ops stac92xx_patch_ops = {
- .build_controls = stac92xx_build_controls,
- .build_pcms = stac92xx_build_pcms,
- .init = stac92xx_init,
- .free = stac92xx_free,
- .unsol_event = stac92xx_unsol_event,
-#ifdef CONFIG_PM
- .suspend = stac92xx_suspend,
- .resume = stac92xx_resume,
-#endif
- .reboot_notify = stac92xx_shutup,
-};
-
-static int patch_stac9200(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->no_trigger_sense = 1;
- codec->spec = spec;
- spec->linear_tone_beep = 1;
- spec->num_pins = ARRAY_SIZE(stac9200_pin_nids);
- spec->pin_nids = stac9200_pin_nids;
- spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
- stac9200_models,
- stac9200_cfg_tbl);
- if (spec->board_config < 0)
- snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
- codec->chip_name);
- else
- stac92xx_set_config_regs(codec,
- stac9200_brd_tbl[spec->board_config]);
-
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = 1;
- spec->multiout.dac_nids = stac9200_dac_nids;
- spec->adc_nids = stac9200_adc_nids;
- spec->mux_nids = stac9200_mux_nids;
- spec->num_muxes = 1;
- spec->num_dmics = 0;
- spec->num_adcs = 1;
- spec->num_pwrs = 0;
-
- if (spec->board_config == STAC_9200_M4 ||
- spec->board_config == STAC_9200_M4_2 ||
- spec->board_config == STAC_9200_OQO)
- spec->init = stac9200_eapd_init;
- else
- spec->init = stac9200_core_init;
- spec->mixer = stac9200_mixer;
-
- if (spec->board_config == STAC_9200_PANASONIC) {
- spec->gpio_mask = spec->gpio_dir = 0x09;
- spec->gpio_data = 0x00;
- }
-
- err = stac9200_parse_auto_config(codec);
- if (err < 0) {
- stac92xx_free(codec);
- return err;
- }
-
- /* CF-74 has no headphone detection, and the driver should *NOT*
- * do detection and HP/speaker toggle because the hardware does it.
- */
- if (spec->board_config == STAC_9200_PANASONIC)
- spec->hp_detect = 0;
-
- codec->patch_ops = stac92xx_patch_ops;
-
- return 0;
-}
-
-static int patch_stac925x(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->no_trigger_sense = 1;
- codec->spec = spec;
- spec->linear_tone_beep = 1;
- spec->num_pins = ARRAY_SIZE(stac925x_pin_nids);
- spec->pin_nids = stac925x_pin_nids;
-
- /* Check first for codec ID */
- spec->board_config = snd_hda_check_board_codec_sid_config(codec,
- STAC_925x_MODELS,
- stac925x_models,
- stac925x_codec_id_cfg_tbl);
-
- /* Now checks for PCI ID, if codec ID is not found */
- if (spec->board_config < 0)
- spec->board_config = snd_hda_check_board_config(codec,
- STAC_925x_MODELS,
- stac925x_models,
- stac925x_cfg_tbl);
- again:
- if (spec->board_config < 0)
- snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
- codec->chip_name);
- else
- stac92xx_set_config_regs(codec,
- stac925x_brd_tbl[spec->board_config]);
-
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = 1;
- spec->multiout.dac_nids = stac925x_dac_nids;
- spec->adc_nids = stac925x_adc_nids;
- spec->mux_nids = stac925x_mux_nids;
- spec->num_muxes = 1;
- spec->num_adcs = 1;
- spec->num_pwrs = 0;
- switch (codec->vendor_id) {
- case 0x83847632: /* STAC9202 */
- case 0x83847633: /* STAC9202D */
- case 0x83847636: /* STAC9251 */
- case 0x83847637: /* STAC9251D */
- spec->num_dmics = STAC925X_NUM_DMICS;
- spec->dmic_nids = stac925x_dmic_nids;
- spec->num_dmuxes = ARRAY_SIZE(stac925x_dmux_nids);
- spec->dmux_nids = stac925x_dmux_nids;
- break;
- default:
- spec->num_dmics = 0;
- break;
- }
-
- spec->init = stac925x_core_init;
- spec->mixer = stac925x_mixer;
- spec->num_caps = 1;
- spec->capvols = stac925x_capvols;
- spec->capsws = stac925x_capsws;
-
- err = stac92xx_parse_auto_config(codec);
- if (!err) {
- if (spec->board_config < 0) {
- printk(KERN_WARNING "hda_codec: No auto-config is "
- "available, default to model=ref\n");
- spec->board_config = STAC_925x_REF;
- goto again;
- }
- err = -EINVAL;
- }
- if (err < 0) {
- stac92xx_free(codec);
- return err;
- }
-
- codec->patch_ops = stac92xx_patch_ops;
-
- return 0;
-}
-
-static int patch_stac92hd73xx(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec;
- hda_nid_t conn[STAC92HD73_DAC_COUNT + 2];
- int err = 0;
- int num_dacs;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->no_trigger_sense = 1;
- codec->spec = spec;
- spec->linear_tone_beep = 0;
- codec->slave_dig_outs = stac92hd73xx_slave_dig_outs;
- spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids);
- spec->pin_nids = stac92hd73xx_pin_nids;
- spec->board_config = snd_hda_check_board_config(codec,
- STAC_92HD73XX_MODELS,
- stac92hd73xx_models,
- stac92hd73xx_cfg_tbl);
- /* check codec subsystem id if not found */
- if (spec->board_config < 0)
- spec->board_config =
- snd_hda_check_board_codec_sid_config(codec,
- STAC_92HD73XX_MODELS, stac92hd73xx_models,
- stac92hd73xx_codec_id_cfg_tbl);
-again:
- if (spec->board_config < 0)
- snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
- codec->chip_name);
- else
- stac92xx_set_config_regs(codec,
- stac92hd73xx_brd_tbl[spec->board_config]);
-
- num_dacs = snd_hda_get_connections(codec, 0x0a,
- conn, STAC92HD73_DAC_COUNT + 2) - 1;
-
- if (num_dacs < 3 || num_dacs > 5) {
- printk(KERN_WARNING "hda_codec: Could not determine "
- "number of channels defaulting to DAC count\n");
- num_dacs = STAC92HD73_DAC_COUNT;
- }
- spec->init = stac92hd73xx_core_init;
- switch (num_dacs) {
- case 0x3: /* 6 Channel */
- spec->aloopback_ctl = stac92hd73xx_6ch_loopback;
- break;
- case 0x4: /* 8 Channel */
- spec->aloopback_ctl = stac92hd73xx_8ch_loopback;
- break;
- case 0x5: /* 10 Channel */
- spec->aloopback_ctl = stac92hd73xx_10ch_loopback;
- break;
- }
- spec->multiout.dac_nids = spec->dac_nids;
-
- spec->aloopback_mask = 0x01;
- spec->aloopback_shift = 8;
-
- spec->digbeep_nid = 0x1c;
- spec->mux_nids = stac92hd73xx_mux_nids;
- spec->adc_nids = stac92hd73xx_adc_nids;
- spec->dmic_nids = stac92hd73xx_dmic_nids;
- spec->dmux_nids = stac92hd73xx_dmux_nids;
- spec->smux_nids = stac92hd73xx_smux_nids;
-
- spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids);
- spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids);
- spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids);
-
- spec->num_caps = STAC92HD73XX_NUM_CAPS;
- spec->capvols = stac92hd73xx_capvols;
- spec->capsws = stac92hd73xx_capsws;
-
- switch (spec->board_config) {
- case STAC_DELL_EQ:
- spec->init = dell_eq_core_init;
- /* fallthru */
- case STAC_DELL_M6_AMIC:
- case STAC_DELL_M6_DMIC:
- case STAC_DELL_M6_BOTH:
- spec->num_smuxes = 0;
- spec->eapd_switch = 0;
-
- switch (spec->board_config) {
- case STAC_DELL_M6_AMIC: /* Analog Mics */
- snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170);
- spec->num_dmics = 0;
- break;
- case STAC_DELL_M6_DMIC: /* Digital Mics */
- snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160);
- spec->num_dmics = 1;
- break;
- case STAC_DELL_M6_BOTH: /* Both */
- snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170);
- snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160);
- spec->num_dmics = 1;
- break;
- }
- break;
- case STAC_ALIENWARE_M17X:
- spec->num_dmics = STAC92HD73XX_NUM_DMICS;
- spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids);
- spec->eapd_switch = 0;
- break;
- default:
- spec->num_dmics = STAC92HD73XX_NUM_DMICS;
- spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids);
- spec->eapd_switch = 1;
- break;
- }
- if (spec->board_config != STAC_92HD73XX_REF) {
- /* GPIO0 High = Enable EAPD */
- spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
- spec->gpio_data = 0x01;
- }
-
- spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids);
- spec->pwr_nids = stac92hd73xx_pwr_nids;
-
- err = stac92xx_parse_auto_config(codec);
-
- if (!err) {
- if (spec->board_config < 0) {
- printk(KERN_WARNING "hda_codec: No auto-config is "
- "available, default to model=ref\n");
- spec->board_config = STAC_92HD73XX_REF;
- goto again;
- }
- err = -EINVAL;
- }
-
- if (err < 0) {
- stac92xx_free(codec);
- return err;
- }
-
- if (spec->board_config == STAC_92HD73XX_NO_JD)
- spec->hp_detect = 0;
-
- codec->patch_ops = stac92xx_patch_ops;
-
- codec->proc_widget_hook = stac92hd7x_proc_hook;
-
- return 0;
-}
-
-static int hp_bnb2011_with_dock(struct hda_codec *codec)
-{
- if (codec->vendor_id != 0x111d7605 &&
- codec->vendor_id != 0x111d76d1)
- return 0;
-
- switch (codec->subsystem_id) {
- case 0x103c1618:
- case 0x103c1619:
- case 0x103c161a:
- case 0x103c161b:
- case 0x103c161c:
- case 0x103c161d:
- case 0x103c161e:
- case 0x103c161f:
-
- case 0x103c162a:
- case 0x103c162b:
-
- case 0x103c1630:
- case 0x103c1631:
-
- case 0x103c1633:
- case 0x103c1634:
- case 0x103c1635:
-
- case 0x103c3587:
- case 0x103c3588:
- case 0x103c3589:
- case 0x103c358a:
-
- case 0x103c3667:
- case 0x103c3668:
- case 0x103c3669:
-
- return 1;
- }
- return 0;
-}
-
-static void stac92hd8x_add_pin(struct hda_codec *codec, hda_nid_t nid)
-{
- struct sigmatel_spec *spec = codec->spec;
- unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
- int i;
-
- spec->auto_pin_nids[spec->auto_pin_cnt] = nid;
- spec->auto_pin_cnt++;
-
- if (get_defcfg_device(def_conf) == AC_JACK_MIC_IN &&
- get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE) {
- for (i = 0; i < ARRAY_SIZE(stac92hd83xxx_dmic_nids); i++) {
- if (nid == stac92hd83xxx_dmic_nids[i]) {
- spec->auto_dmic_nids[spec->auto_dmic_cnt] = nid;
- spec->auto_dmic_cnt++;
- }
- }
- }
-}
-
-static void stac92hd8x_add_adc(struct hda_codec *codec, hda_nid_t nid)
-{
- struct sigmatel_spec *spec = codec->spec;
-
- spec->auto_adc_nids[spec->auto_adc_cnt] = nid;
- spec->auto_adc_cnt++;
-}
-
-static void stac92hd8x_add_mux(struct hda_codec *codec, hda_nid_t nid)
-{
- int i, j;
- struct sigmatel_spec *spec = codec->spec;
-
- for (i = 0; i < spec->auto_adc_cnt; i++) {
- if (get_connection_index(codec,
- spec->auto_adc_nids[i], nid) >= 0) {
- /* mux and volume for adc_nids[i] */
- if (!spec->auto_mux_nids[i]) {
- spec->auto_mux_nids[i] = nid;
- /* 92hd codecs capture volume is in mux */
- spec->auto_capvols[i] = HDA_COMPOSE_AMP_VAL(nid,
- 3, 0, HDA_OUTPUT);
- }
- for (j = 0; j < spec->auto_dmic_cnt; j++) {
- if (get_connection_index(codec, nid,
- spec->auto_dmic_nids[j]) >= 0) {
- /* dmux for adc_nids[i] */
- if (!spec->auto_dmux_nids[i])
- spec->auto_dmux_nids[i] = nid;
- break;
- }
- }
- break;
- }
- }
-}
-
-static void stac92hd8x_fill_auto_spec(struct hda_codec *codec)
-{
- hda_nid_t nid, end_nid;
- unsigned int wid_caps, wid_type;
- struct sigmatel_spec *spec = codec->spec;
-
- end_nid = codec->start_nid + codec->num_nodes;
-
- for (nid = codec->start_nid; nid < end_nid; nid++) {
- wid_caps = get_wcaps(codec, nid);
- wid_type = get_wcaps_type(wid_caps);
-
- if (wid_type == AC_WID_PIN)
- stac92hd8x_add_pin(codec, nid);
-
- if (wid_type == AC_WID_AUD_IN && !(wid_caps & AC_WCAP_DIGITAL))
- stac92hd8x_add_adc(codec, nid);
- }
-
- for (nid = codec->start_nid; nid < end_nid; nid++) {
- wid_caps = get_wcaps(codec, nid);
- wid_type = get_wcaps_type(wid_caps);
-
- if (wid_type == AC_WID_AUD_SEL)
- stac92hd8x_add_mux(codec, nid);
- }
-
- spec->pin_nids = spec->auto_pin_nids;
- spec->num_pins = spec->auto_pin_cnt;
- spec->adc_nids = spec->auto_adc_nids;
- spec->num_adcs = spec->auto_adc_cnt;
- spec->capvols = spec->auto_capvols;
- spec->capsws = spec->auto_capvols;
- spec->num_caps = spec->auto_adc_cnt;
- spec->mux_nids = spec->auto_mux_nids;
- spec->num_muxes = spec->auto_adc_cnt;
- spec->dmux_nids = spec->auto_dmux_nids;
- spec->num_dmuxes = spec->auto_adc_cnt;
- spec->dmic_nids = spec->auto_dmic_nids;
- spec->num_dmics = spec->auto_dmic_cnt;
-}
-
-static int patch_stac92hd83xxx(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- if (hp_bnb2011_with_dock(codec)) {
- snd_hda_codec_set_pincfg(codec, 0xa, 0x2101201f);
- snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e);
- }
-
- codec->no_trigger_sense = 1;
- codec->spec = spec;
-
- stac92hd8x_fill_auto_spec(codec);
-
- spec->linear_tone_beep = 0;
- codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
- spec->digbeep_nid = 0x21;
- spec->pwr_nids = stac92hd83xxx_pwr_nids;
- spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
- spec->multiout.dac_nids = spec->dac_nids;
- spec->init = stac92hd83xxx_core_init;
-
- spec->board_config = snd_hda_check_board_config(codec,
- STAC_92HD83XXX_MODELS,
- stac92hd83xxx_models,
- stac92hd83xxx_cfg_tbl);
- /* check codec subsystem id if not found */
- if (spec->board_config < 0)
- spec->board_config =
- snd_hda_check_board_codec_sid_config(codec,
- STAC_92HD83XXX_MODELS, stac92hd83xxx_models,
- stac92hd83xxx_codec_id_cfg_tbl);
-again:
- if (spec->board_config < 0)
- snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
- codec->chip_name);
- else
- stac92xx_set_config_regs(codec,
- stac92hd83xxx_brd_tbl[spec->board_config]);
-
- codec->patch_ops = stac92xx_patch_ops;
-
- switch (spec->board_config) {
- case STAC_HP_ZEPHYR:
- spec->init = stac92hd83xxx_hp_zephyr_init;
- break;
- }
-
- if (find_mute_led_cfg(codec, -1/*no default cfg*/))
- snd_printd("mute LED gpio %d polarity %d\n",
- spec->gpio_led,
- spec->gpio_led_polarity);
-
- if (spec->gpio_led) {
- if (!spec->vref_mute_led_nid) {
- spec->gpio_mask |= spec->gpio_led;
- spec->gpio_dir |= spec->gpio_led;
- spec->gpio_data |= spec->gpio_led;
- } else {
- codec->patch_ops.set_power_state =
- stac92xx_set_power_state;
- }
-#ifdef CONFIG_PM
- codec->patch_ops.pre_resume = stac92xx_pre_resume;
-#endif
- }
-
- err = stac92xx_parse_auto_config(codec);
- if (!err) {
- if (spec->board_config < 0) {
- printk(KERN_WARNING "hda_codec: No auto-config is "
- "available, default to model=ref\n");
- spec->board_config = STAC_92HD83XXX_REF;
- goto again;
- }
- err = -EINVAL;
- }
-
- if (err < 0) {
- stac92xx_free(codec);
- return err;
- }
-
- codec->proc_widget_hook = stac92hd_proc_hook;
-
- return 0;
-}
-
-static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec,
- hda_nid_t dig0pin)
-{
- struct sigmatel_spec *spec = codec->spec;
- int idx;
-
- for (idx = 0; idx < spec->num_pins; idx++)
- if (spec->pin_nids[idx] == dig0pin)
- break;
- if ((idx + 2) >= spec->num_pins)
- return 0;
-
- /* dig1pin case */
- if (stac_get_defcfg_connect(codec, idx + 1) != AC_JACK_PORT_NONE)
- return 2;
-
- /* dig0pin + dig2pin case */
- if (stac_get_defcfg_connect(codec, idx + 2) != AC_JACK_PORT_NONE)
- return 2;
- if (stac_get_defcfg_connect(codec, idx) != AC_JACK_PORT_NONE)
- return 1;
- else
- return 0;
-}
-
-/* HP dv7 bass switch - GPIO5 */
-#define stac_hp_bass_gpio_info snd_ctl_boolean_mono_info
-static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
- ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20);
- return 0;
-}
-
-static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sigmatel_spec *spec = codec->spec;
- unsigned int gpio_data;
-
- gpio_data = (spec->gpio_data & ~0x20) |
- (ucontrol->value.integer.value[0] ? 0x20 : 0);
- if (gpio_data == spec->gpio_data)
- return 0;
- spec->gpio_data = gpio_data;
- stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
- return 1;
-}
-
-static const struct snd_kcontrol_new stac_hp_bass_sw_ctrl = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = stac_hp_bass_gpio_info,
- .get = stac_hp_bass_gpio_get,
- .put = stac_hp_bass_gpio_put,
-};
-
-static int stac_add_hp_bass_switch(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec = codec->spec;
-
- if (!stac_control_new(spec, &stac_hp_bass_sw_ctrl,
- "Bass Speaker Playback Switch", 0))
- return -ENOMEM;
-
- spec->gpio_mask |= 0x20;
- spec->gpio_dir |= 0x20;
- spec->gpio_data |= 0x20;
- return 0;
-}
-
-static int patch_stac92hd71bxx(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec;
- const struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init;
- unsigned int pin_cfg;
- int err = 0;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->no_trigger_sense = 1;
- codec->spec = spec;
- spec->linear_tone_beep = 0;
- codec->patch_ops = stac92xx_patch_ops;
- spec->num_pins = STAC92HD71BXX_NUM_PINS;
- switch (codec->vendor_id) {
- case 0x111d76b6:
- case 0x111d76b7:
- spec->pin_nids = stac92hd71bxx_pin_nids_4port;
- break;
- case 0x111d7603:
- case 0x111d7608:
- /* On 92HD75Bx 0x27 isn't a pin nid */
- spec->num_pins--;
- /* fallthrough */
- default:
- spec->pin_nids = stac92hd71bxx_pin_nids_6port;
- }
- spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids);
- spec->board_config = snd_hda_check_board_config(codec,
- STAC_92HD71BXX_MODELS,
- stac92hd71bxx_models,
- stac92hd71bxx_cfg_tbl);
-again:
- if (spec->board_config < 0)
- snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
- codec->chip_name);
- else
- stac92xx_set_config_regs(codec,
- stac92hd71bxx_brd_tbl[spec->board_config]);
-
- if (spec->board_config != STAC_92HD71BXX_REF) {
- /* GPIO0 = EAPD */
- spec->gpio_mask = 0x01;
- spec->gpio_dir = 0x01;
- spec->gpio_data = 0x01;
- }
-
- spec->dmic_nids = stac92hd71bxx_dmic_nids;
- spec->dmux_nids = stac92hd71bxx_dmux_nids;
-
- spec->num_caps = STAC92HD71BXX_NUM_CAPS;
- spec->capvols = stac92hd71bxx_capvols;
- spec->capsws = stac92hd71bxx_capsws;
-
- switch (codec->vendor_id) {
- case 0x111d76b6: /* 4 Port without Analog Mixer */
- case 0x111d76b7:
- unmute_init++;
- /* fallthru */
- case 0x111d76b4: /* 6 Port without Analog Mixer */
- case 0x111d76b5:
- spec->init = stac92hd71bxx_core_init;
- codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
- spec->num_dmics = stac92xx_connected_ports(codec,
- stac92hd71bxx_dmic_nids,
- STAC92HD71BXX_NUM_DMICS);
- break;
- case 0x111d7608: /* 5 Port with Analog Mixer */
- switch (spec->board_config) {
- case STAC_HP_M4:
- /* Enable VREF power saving on GPIO1 detect */
- err = stac_add_event(codec, codec->afg,
- STAC_VREF_EVENT, 0x02);
- if (err < 0)
- return err;
- snd_hda_codec_write_cache(codec, codec->afg, 0,
- AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
- snd_hda_jack_detect_enable(codec, codec->afg, 0);
- spec->gpio_mask |= 0x02;
- break;
- }
- if ((codec->revision_id & 0xf) == 0 ||
- (codec->revision_id & 0xf) == 1)
- spec->stream_delay = 40; /* 40 milliseconds */
-
- /* disable VSW */
- spec->init = stac92hd71bxx_core_init;
- unmute_init++;
- snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0);
- snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3);
- spec->dmic_nids = stac92hd71bxx_dmic_5port_nids;
- spec->num_dmics = stac92xx_connected_ports(codec,
- stac92hd71bxx_dmic_5port_nids,
- STAC92HD71BXX_NUM_DMICS - 1);
- break;
- case 0x111d7603: /* 6 Port with Analog Mixer */
- if ((codec->revision_id & 0xf) == 1)
- spec->stream_delay = 40; /* 40 milliseconds */
-
- /* fallthru */
- default:
- spec->init = stac92hd71bxx_core_init;
- codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
- spec->num_dmics = stac92xx_connected_ports(codec,
- stac92hd71bxx_dmic_nids,
- STAC92HD71BXX_NUM_DMICS);
- break;
- }
-
- if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP)
- snd_hda_sequence_write_cache(codec, unmute_init);
-
- spec->aloopback_ctl = stac92hd71bxx_loopback;
- spec->aloopback_mask = 0x50;
- spec->aloopback_shift = 0;
-
- spec->powerdown_adcs = 1;
- spec->digbeep_nid = 0x26;
- spec->mux_nids = stac92hd71bxx_mux_nids;
- spec->adc_nids = stac92hd71bxx_adc_nids;
- spec->smux_nids = stac92hd71bxx_smux_nids;
- spec->pwr_nids = stac92hd71bxx_pwr_nids;
-
- spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids);
- spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids);
- spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
- spec->num_smuxes = stac92hd71bxx_connected_smuxes(codec, 0x1e);
-
- snd_printdd("Found board config: %d\n", spec->board_config);
-
- switch (spec->board_config) {
- case STAC_HP_M4:
- /* enable internal microphone */
- snd_hda_codec_set_pincfg(codec, 0x0e, 0x01813040);
- stac92xx_auto_set_pinctl(codec, 0x0e,
- AC_PINCTL_IN_EN | AC_PINCTL_VREF_80);
- /* fallthru */
- case STAC_DELL_M4_2:
- spec->num_dmics = 0;
- spec->num_smuxes = 0;
- spec->num_dmuxes = 0;
- break;
- case STAC_DELL_M4_1:
- case STAC_DELL_M4_3:
- spec->num_dmics = 1;
- spec->num_smuxes = 0;
- spec->num_dmuxes = 1;
- break;
- case STAC_HP_DV4_1222NR:
- spec->num_dmics = 1;
- /* I don't know if it needs 1 or 2 smuxes - will wait for
- * bug reports to fix if needed
- */
- spec->num_smuxes = 1;
- spec->num_dmuxes = 1;
- /* fallthrough */
- case STAC_HP_DV4:
- spec->gpio_led = 0x01;
- /* fallthrough */
- case STAC_HP_DV5:
- snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
- stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN);
- /* HP dv6 gives the headphone pin as a line-out. Thus we
- * need to set hp_detect flag here to force to enable HP
- * detection.
- */
- spec->hp_detect = 1;
- break;
- case STAC_HP_HDX:
- spec->num_dmics = 1;
- spec->num_dmuxes = 1;
- spec->num_smuxes = 1;
- spec->gpio_led = 0x08;
- break;
- }
-
- if (hp_blike_system(codec->subsystem_id)) {
- pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f);
- if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT ||
- get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER ||
- get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT) {
- /* It was changed in the BIOS to just satisfy MS DTM.
- * Lets turn it back into slaved HP
- */
- pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE))
- | (AC_JACK_HP_OUT <<
- AC_DEFCFG_DEVICE_SHIFT);
- pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC
- | AC_DEFCFG_SEQUENCE)))
- | 0x1f;
- snd_hda_codec_set_pincfg(codec, 0x0f, pin_cfg);
- }
- }
-
- if (find_mute_led_cfg(codec, 1))
- snd_printd("mute LED gpio %d polarity %d\n",
- spec->gpio_led,
- spec->gpio_led_polarity);
-
- if (spec->gpio_led) {
- if (!spec->vref_mute_led_nid) {
- spec->gpio_mask |= spec->gpio_led;
- spec->gpio_dir |= spec->gpio_led;
- spec->gpio_data |= spec->gpio_led;
- } else {
- codec->patch_ops.set_power_state =
- stac92xx_set_power_state;
- }
-#ifdef CONFIG_PM
- codec->patch_ops.pre_resume = stac92xx_pre_resume;
-#endif
- }
-
- spec->multiout.dac_nids = spec->dac_nids;
-
- err = stac92xx_parse_auto_config(codec);
- if (!err) {
- if (spec->board_config < 0) {
- printk(KERN_WARNING "hda_codec: No auto-config is "
- "available, default to model=ref\n");
- spec->board_config = STAC_92HD71BXX_REF;
- goto again;
- }
- err = -EINVAL;
- }
-
- if (err < 0) {
- stac92xx_free(codec);
- return err;
- }
-
- /* enable bass on HP dv7 */
- if (spec->board_config == STAC_HP_DV4 ||
- spec->board_config == STAC_HP_DV5) {
- unsigned int cap;
- cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP);
- cap &= AC_GPIO_IO_COUNT;
- if (cap >= 6)
- stac_add_hp_bass_switch(codec);
- }
-
- codec->proc_widget_hook = stac92hd7x_proc_hook;
-
- return 0;
-}
-
-static int patch_stac922x(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->no_trigger_sense = 1;
- codec->spec = spec;
- spec->linear_tone_beep = 1;
- spec->num_pins = ARRAY_SIZE(stac922x_pin_nids);
- spec->pin_nids = stac922x_pin_nids;
- spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS,
- stac922x_models,
- stac922x_cfg_tbl);
- if (spec->board_config == STAC_INTEL_MAC_AUTO) {
- spec->gpio_mask = spec->gpio_dir = 0x03;
- spec->gpio_data = 0x03;
- /* Intel Macs have all same PCI SSID, so we need to check
- * codec SSID to distinguish the exact models
- */
- printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id);
- switch (codec->subsystem_id) {
-
- case 0x106b0800:
- spec->board_config = STAC_INTEL_MAC_V1;
- break;
- case 0x106b0600:
- case 0x106b0700:
- spec->board_config = STAC_INTEL_MAC_V2;
- break;
- case 0x106b0e00:
- case 0x106b0f00:
- case 0x106b1600:
- case 0x106b1700:
- case 0x106b0200:
- case 0x106b1e00:
- spec->board_config = STAC_INTEL_MAC_V3;
- break;
- case 0x106b1a00:
- case 0x00000100:
- spec->board_config = STAC_INTEL_MAC_V4;
- break;
- case 0x106b0a00:
- case 0x106b2200:
- spec->board_config = STAC_INTEL_MAC_V5;
- break;
- default:
- spec->board_config = STAC_INTEL_MAC_V3;
- break;
- }
- }
-
- again:
- if (spec->board_config < 0)
- snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
- codec->chip_name);
- else
- stac92xx_set_config_regs(codec,
- stac922x_brd_tbl[spec->board_config]);
-
- spec->adc_nids = stac922x_adc_nids;
- spec->mux_nids = stac922x_mux_nids;
- spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids);
- spec->num_adcs = ARRAY_SIZE(stac922x_adc_nids);
- spec->num_dmics = 0;
- spec->num_pwrs = 0;
-
- spec->init = stac922x_core_init;
-
- spec->num_caps = STAC922X_NUM_CAPS;
- spec->capvols = stac922x_capvols;
- spec->capsws = stac922x_capsws;
-
- spec->multiout.dac_nids = spec->dac_nids;
-
- err = stac92xx_parse_auto_config(codec);
- if (!err) {
- if (spec->board_config < 0) {
- printk(KERN_WARNING "hda_codec: No auto-config is "
- "available, default to model=ref\n");
- spec->board_config = STAC_D945_REF;
- goto again;
- }
- err = -EINVAL;
- }
- if (err < 0) {
- stac92xx_free(codec);
- return err;
- }
-
- codec->patch_ops = stac92xx_patch_ops;
-
- /* Fix Mux capture level; max to 2 */
- snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
- (0 << AC_AMPCAP_OFFSET_SHIFT) |
- (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
- (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
- (0 << AC_AMPCAP_MUTE_SHIFT));
-
- return 0;
-}
-
-static int patch_stac927x(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->no_trigger_sense = 1;
- codec->spec = spec;
- spec->linear_tone_beep = 1;
- codec->slave_dig_outs = stac927x_slave_dig_outs;
- spec->num_pins = ARRAY_SIZE(stac927x_pin_nids);
- spec->pin_nids = stac927x_pin_nids;
- spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS,
- stac927x_models,
- stac927x_cfg_tbl);
- again:
- if (spec->board_config < 0)
- snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
- codec->chip_name);
- else
- stac92xx_set_config_regs(codec,
- stac927x_brd_tbl[spec->board_config]);
-
- spec->digbeep_nid = 0x23;
- spec->adc_nids = stac927x_adc_nids;
- spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
- spec->mux_nids = stac927x_mux_nids;
- spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
- spec->smux_nids = stac927x_smux_nids;
- spec->num_smuxes = ARRAY_SIZE(stac927x_smux_nids);
- spec->spdif_labels = stac927x_spdif_labels;
- spec->dac_list = stac927x_dac_nids;
- spec->multiout.dac_nids = spec->dac_nids;
-
- if (spec->board_config != STAC_D965_REF) {
- /* GPIO0 High = Enable EAPD */
- spec->eapd_mask = spec->gpio_mask = 0x01;
- spec->gpio_dir = spec->gpio_data = 0x01;
- }
-
- switch (spec->board_config) {
- case STAC_D965_3ST:
- case STAC_D965_5ST:
- /* GPIO0 High = Enable EAPD */
- spec->num_dmics = 0;
- spec->init = d965_core_init;
- break;
- case STAC_DELL_BIOS:
- switch (codec->subsystem_id) {
- case 0x10280209:
- case 0x1028022e:
- /* correct the device field to SPDIF out */
- snd_hda_codec_set_pincfg(codec, 0x21, 0x01442070);
- break;
- }
- /* configure the analog microphone on some laptops */
- snd_hda_codec_set_pincfg(codec, 0x0c, 0x90a79130);
- /* correct the front output jack as a hp out */
- snd_hda_codec_set_pincfg(codec, 0x0f, 0x0227011f);
- /* correct the front input jack as a mic */
- snd_hda_codec_set_pincfg(codec, 0x0e, 0x02a79130);
- /* fallthru */
- case STAC_DELL_3ST:
- if (codec->subsystem_id != 0x1028022f) {
- /* GPIO2 High = Enable EAPD */
- spec->eapd_mask = spec->gpio_mask = 0x04;
- spec->gpio_dir = spec->gpio_data = 0x04;
- }
- spec->dmic_nids = stac927x_dmic_nids;
- spec->num_dmics = STAC927X_NUM_DMICS;
-
- spec->init = dell_3st_core_init;
- spec->dmux_nids = stac927x_dmux_nids;
- spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids);
- break;
- case STAC_927X_VOLKNOB:
- spec->num_dmics = 0;
- spec->init = stac927x_volknob_core_init;
- break;
- default:
- spec->num_dmics = 0;
- spec->init = stac927x_core_init;
- break;
- }
-
- spec->num_caps = STAC927X_NUM_CAPS;
- spec->capvols = stac927x_capvols;
- spec->capsws = stac927x_capsws;
-
- spec->num_pwrs = 0;
- spec->aloopback_ctl = stac927x_loopback;
- spec->aloopback_mask = 0x40;
- spec->aloopback_shift = 0;
- spec->eapd_switch = 1;
-
- err = stac92xx_parse_auto_config(codec);
- if (!err) {
- if (spec->board_config < 0) {
- printk(KERN_WARNING "hda_codec: No auto-config is "
- "available, default to model=ref\n");
- spec->board_config = STAC_D965_REF;
- goto again;
- }
- err = -EINVAL;
- }
- if (err < 0) {
- stac92xx_free(codec);
- return err;
- }
-
- codec->patch_ops = stac92xx_patch_ops;
-
- codec->proc_widget_hook = stac927x_proc_hook;
-
- /*
- * !!FIXME!!
- * The STAC927x seem to require fairly long delays for certain
- * command sequences. With too short delays (even if the answer
- * is set to RIRB properly), it results in the silence output
- * on some hardwares like Dell.
- *
- * The below flag enables the longer delay (see get_response
- * in hda_intel.c).
- */
- codec->bus->needs_damn_long_delay = 1;
-
- /* no jack detecion for ref-no-jd model */
- if (spec->board_config == STAC_D965_REF_NO_JD)
- spec->hp_detect = 0;
-
- return 0;
-}
-
-static int patch_stac9205(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
-
- codec->no_trigger_sense = 1;
- codec->spec = spec;
- spec->linear_tone_beep = 1;
- spec->num_pins = ARRAY_SIZE(stac9205_pin_nids);
- spec->pin_nids = stac9205_pin_nids;
- spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS,
- stac9205_models,
- stac9205_cfg_tbl);
- again:
- if (spec->board_config < 0)
- snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
- codec->chip_name);
- else
- stac92xx_set_config_regs(codec,
- stac9205_brd_tbl[spec->board_config]);
-
- spec->digbeep_nid = 0x23;
- spec->adc_nids = stac9205_adc_nids;
- spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids);
- spec->mux_nids = stac9205_mux_nids;
- spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
- spec->smux_nids = stac9205_smux_nids;
- spec->num_smuxes = ARRAY_SIZE(stac9205_smux_nids);
- spec->dmic_nids = stac9205_dmic_nids;
- spec->num_dmics = STAC9205_NUM_DMICS;
- spec->dmux_nids = stac9205_dmux_nids;
- spec->num_dmuxes = ARRAY_SIZE(stac9205_dmux_nids);
- spec->num_pwrs = 0;
-
- spec->init = stac9205_core_init;
- spec->aloopback_ctl = stac9205_loopback;
-
- spec->num_caps = STAC9205_NUM_CAPS;
- spec->capvols = stac9205_capvols;
- spec->capsws = stac9205_capsws;
-
- spec->aloopback_mask = 0x40;
- spec->aloopback_shift = 0;
- /* Turn on/off EAPD per HP plugging */
- if (spec->board_config != STAC_9205_EAPD)
- spec->eapd_switch = 1;
- spec->multiout.dac_nids = spec->dac_nids;
-
- switch (spec->board_config){
- case STAC_9205_DELL_M43:
- /* Enable SPDIF in/out */
- snd_hda_codec_set_pincfg(codec, 0x1f, 0x01441030);
- snd_hda_codec_set_pincfg(codec, 0x20, 0x1c410030);
-
- /* Enable unsol response for GPIO4/Dock HP connection */
- err = stac_add_event(codec, codec->afg, STAC_VREF_EVENT, 0x01);
- if (err < 0)
- return err;
- snd_hda_codec_write_cache(codec, codec->afg, 0,
- AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
- snd_hda_jack_detect_enable(codec, codec->afg, 0);
-
- spec->gpio_dir = 0x0b;
- spec->eapd_mask = 0x01;
- spec->gpio_mask = 0x1b;
- spec->gpio_mute = 0x10;
- /* GPIO0 High = EAPD, GPIO1 Low = Headphone Mute,
- * GPIO3 Low = DRM
- */
- spec->gpio_data = 0x01;
- break;
- case STAC_9205_REF:
- /* SPDIF-In enabled */
- break;
- default:
- /* GPIO0 High = EAPD */
- spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
- spec->gpio_data = 0x01;
- break;
- }
-
- err = stac92xx_parse_auto_config(codec);
- if (!err) {
- if (spec->board_config < 0) {
- printk(KERN_WARNING "hda_codec: No auto-config is "
- "available, default to model=ref\n");
- spec->board_config = STAC_9205_REF;
- goto again;
- }
- err = -EINVAL;
- }
- if (err < 0) {
- stac92xx_free(codec);
- return err;
- }
-
- codec->patch_ops = stac92xx_patch_ops;
-
- codec->proc_widget_hook = stac9205_proc_hook;
-
- return 0;
-}
-
-/*
- * STAC9872 hack
- */
-
-static const struct hda_verb stac9872_core_init[] = {
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
- {}
-};
-
-static const hda_nid_t stac9872_pin_nids[] = {
- 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x11, 0x13, 0x14,
-};
-
-static const hda_nid_t stac9872_adc_nids[] = {
- 0x8 /*,0x6*/
-};
-
-static const hda_nid_t stac9872_mux_nids[] = {
- 0x15
-};
-
-static const unsigned long stac9872_capvols[] = {
- HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
-};
-#define stac9872_capsws stac9872_capvols
-
-static const unsigned int stac9872_vaio_pin_configs[9] = {
- 0x03211020, 0x411111f0, 0x411111f0, 0x03a15030,
- 0x411111f0, 0x90170110, 0x411111f0, 0x411111f0,
- 0x90a7013e
-};
-
-static const char * const stac9872_models[STAC_9872_MODELS] = {
- [STAC_9872_AUTO] = "auto",
- [STAC_9872_VAIO] = "vaio",
-};
-
-static const unsigned int *stac9872_brd_tbl[STAC_9872_MODELS] = {
- [STAC_9872_VAIO] = stac9872_vaio_pin_configs,
-};
-
-static const struct snd_pci_quirk stac9872_cfg_tbl[] = {
- SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0,
- "Sony VAIO F/S", STAC_9872_VAIO),
- {} /* terminator */
-};
-
-static int patch_stac9872(struct hda_codec *codec)
-{
- struct sigmatel_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return -ENOMEM;
- codec->no_trigger_sense = 1;
- codec->spec = spec;
- spec->linear_tone_beep = 1;
- spec->num_pins = ARRAY_SIZE(stac9872_pin_nids);
- spec->pin_nids = stac9872_pin_nids;
-
- spec->board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS,
- stac9872_models,
- stac9872_cfg_tbl);
- if (spec->board_config < 0)
- snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
- codec->chip_name);
- else
- stac92xx_set_config_regs(codec,
- stac9872_brd_tbl[spec->board_config]);
-
- spec->multiout.dac_nids = spec->dac_nids;
- spec->num_adcs = ARRAY_SIZE(stac9872_adc_nids);
- spec->adc_nids = stac9872_adc_nids;
- spec->num_muxes = ARRAY_SIZE(stac9872_mux_nids);
- spec->mux_nids = stac9872_mux_nids;
- spec->init = stac9872_core_init;
- spec->num_caps = 1;
- spec->capvols = stac9872_capvols;
- spec->capsws = stac9872_capsws;
-
- err = stac92xx_parse_auto_config(codec);
- if (err < 0) {
- stac92xx_free(codec);
- return -EINVAL;
- }
- spec->input_mux = &spec->private_imux;
- codec->patch_ops = stac92xx_patch_ops;
- return 0;
-}
-
-
-/*
- * patch entries
- */
-static const struct hda_codec_preset snd_hda_preset_sigmatel[] = {
- { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
- { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
- { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
- { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x },
- { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x },
- { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x },
- { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
- { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x },
- { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x },
- { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x },
- { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x },
- { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x },
- { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac927x },
- { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x },
- { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x },
- { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x },
- { .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x },
- { .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x },
- { .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x },
- { .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x },
- { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x },
- { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x },
- { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x },
- { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac925x },
- { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac925x },
- { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x },
- { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x },
- { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x },
- { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x },
- { .id = 0x83847645, .name = "92HD206X", .patch = patch_stac927x },
- { .id = 0x83847646, .name = "92HD206D", .patch = patch_stac927x },
- /* The following does not take into account .id=0x83847661 when subsys =
- * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
- * currently not fully supported.
- */
- { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 },
- { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 },
- { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 },
- { .id = 0x83847698, .name = "STAC9205", .patch = patch_stac9205 },
- { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 },
- { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 },
- { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 },
- { .id = 0x838476a3, .name = "STAC9204D", .patch = patch_stac9205 },
- { .id = 0x838476a4, .name = "STAC9255", .patch = patch_stac9205 },
- { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 },
- { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
- { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
- { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx},
- { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx},
- { .id = 0x111d76d4, .name = "92HD83C1C5", .patch = patch_stac92hd83xxx},
- { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx},
- { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx},
- { .id = 0x111d76d1, .name = "92HD87B1/3", .patch = patch_stac92hd83xxx},
- { .id = 0x111d76d9, .name = "92HD87B2/4", .patch = patch_stac92hd83xxx},
- { .id = 0x111d7666, .name = "92HD88B3", .patch = patch_stac92hd83xxx},
- { .id = 0x111d7667, .name = "92HD88B1", .patch = patch_stac92hd83xxx},
- { .id = 0x111d7668, .name = "92HD88B2", .patch = patch_stac92hd83xxx},
- { .id = 0x111d7669, .name = "92HD88B4", .patch = patch_stac92hd83xxx},
- { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx},
- { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx },
- { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx },
- { .id = 0x111d7676, .name = "92HD73E1X5", .patch = patch_stac92hd73xx },
- { .id = 0x111d76b0, .name = "92HD71B8X", .patch = patch_stac92hd71bxx },
- { .id = 0x111d76b1, .name = "92HD71B8X", .patch = patch_stac92hd71bxx },
- { .id = 0x111d76b2, .name = "92HD71B7X", .patch = patch_stac92hd71bxx },
- { .id = 0x111d76b3, .name = "92HD71B7X", .patch = patch_stac92hd71bxx },
- { .id = 0x111d76b4, .name = "92HD71B6X", .patch = patch_stac92hd71bxx },
- { .id = 0x111d76b5, .name = "92HD71B6X", .patch = patch_stac92hd71bxx },
- { .id = 0x111d76b6, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
- { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
- { .id = 0x111d76c0, .name = "92HD89C3", .patch = patch_stac92hd73xx },
- { .id = 0x111d76c1, .name = "92HD89C2", .patch = patch_stac92hd73xx },
- { .id = 0x111d76c2, .name = "92HD89C1", .patch = patch_stac92hd73xx },
- { .id = 0x111d76c3, .name = "92HD89B3", .patch = patch_stac92hd73xx },
- { .id = 0x111d76c4, .name = "92HD89B2", .patch = patch_stac92hd73xx },
- { .id = 0x111d76c5, .name = "92HD89B1", .patch = patch_stac92hd73xx },
- { .id = 0x111d76c6, .name = "92HD89E3", .patch = patch_stac92hd73xx },
- { .id = 0x111d76c7, .name = "92HD89E2", .patch = patch_stac92hd73xx },
- { .id = 0x111d76c8, .name = "92HD89E1", .patch = patch_stac92hd73xx },
- { .id = 0x111d76c9, .name = "92HD89D3", .patch = patch_stac92hd73xx },
- { .id = 0x111d76ca, .name = "92HD89D2", .patch = patch_stac92hd73xx },
- { .id = 0x111d76cb, .name = "92HD89D1", .patch = patch_stac92hd73xx },
- { .id = 0x111d76cc, .name = "92HD89F3", .patch = patch_stac92hd73xx },
- { .id = 0x111d76cd, .name = "92HD89F2", .patch = patch_stac92hd73xx },
- { .id = 0x111d76ce, .name = "92HD89F1", .patch = patch_stac92hd73xx },
- { .id = 0x111d76df, .name = "92HD93BXX", .patch = patch_stac92hd83xxx},
- { .id = 0x111d76e0, .name = "92HD91BXX", .patch = patch_stac92hd83xxx},
- { .id = 0x111d76e3, .name = "92HD98BXX", .patch = patch_stac92hd83xxx},
- { .id = 0x111d76e5, .name = "92HD99BXX", .patch = patch_stac92hd83xxx},
- { .id = 0x111d76e7, .name = "92HD90BXX", .patch = patch_stac92hd83xxx},
- { .id = 0x111d76e8, .name = "92HD66B1X5", .patch = patch_stac92hd83xxx},
- { .id = 0x111d76e9, .name = "92HD66B2X5", .patch = patch_stac92hd83xxx},
- { .id = 0x111d76ea, .name = "92HD66B3X5", .patch = patch_stac92hd83xxx},
- { .id = 0x111d76eb, .name = "92HD66C1X5", .patch = patch_stac92hd83xxx},
- { .id = 0x111d76ec, .name = "92HD66C2X5", .patch = patch_stac92hd83xxx},
- { .id = 0x111d76ed, .name = "92HD66C3X5", .patch = patch_stac92hd83xxx},
- { .id = 0x111d76ee, .name = "92HD66B1X3", .patch = patch_stac92hd83xxx},
- { .id = 0x111d76ef, .name = "92HD66B2X3", .patch = patch_stac92hd83xxx},
- { .id = 0x111d76f0, .name = "92HD66B3X3", .patch = patch_stac92hd83xxx},
- { .id = 0x111d76f1, .name = "92HD66C1X3", .patch = patch_stac92hd83xxx},
- { .id = 0x111d76f2, .name = "92HD66C2X3", .patch = patch_stac92hd83xxx},
- { .id = 0x111d76f3, .name = "92HD66C3/65", .patch = patch_stac92hd83xxx},
- {} /* terminator */
-};
-
-MODULE_ALIAS("snd-hda-codec-id:8384*");
-MODULE_ALIAS("snd-hda-codec-id:111d*");
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("IDT/Sigmatel HD-audio codec");
-
-static struct hda_codec_preset_list sigmatel_list = {
- .preset = snd_hda_preset_sigmatel,
- .owner = THIS_MODULE,
-};
-
-static int __init patch_sigmatel_init(void)
-{
- return snd_hda_add_codec_preset(&sigmatel_list);
-}
-
-static void __exit patch_sigmatel_exit(void)
-{
- snd_hda_delete_codec_preset(&sigmatel_list);
-}
-
-module_init(patch_sigmatel_init)
-module_exit(patch_sigmatel_exit)
diff --git a/ANDROID_3.4.5/sound/pci/hda/patch_via.c b/ANDROID_3.4.5/sound/pci/hda/patch_via.c
deleted file mode 100644
index 06214fdc..00000000
--- a/ANDROID_3.4.5/sound/pci/hda/patch_via.c
+++ /dev/null
@@ -1,3935 +0,0 @@
-/*
- * Universal Interface for Intel High Definition Audio Codec
- *
- * HD audio interface patch for VIA VT17xx/VT18xx/VT20xx codec
- *
- * (C) 2006-2009 VIA Technology, Inc.
- * (C) 2006-2008 Takashi Iwai <tiwai@suse.de>
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* * * * * * * * * * * * * * Release History * * * * * * * * * * * * * * * * */
-/* */
-/* 2006-03-03 Lydia Wang Create the basic patch to support VT1708 codec */
-/* 2006-03-14 Lydia Wang Modify hard code for some pin widget nid */
-/* 2006-08-02 Lydia Wang Add support to VT1709 codec */
-/* 2006-09-08 Lydia Wang Fix internal loopback recording source select bug */
-/* 2007-09-12 Lydia Wang Add EAPD enable during driver initialization */
-/* 2007-09-17 Lydia Wang Add VT1708B codec support */
-/* 2007-11-14 Lydia Wang Add VT1708A codec HP and CD pin connect config */
-/* 2008-02-03 Lydia Wang Fix Rear channels and Back channels inverse issue */
-/* 2008-03-06 Lydia Wang Add VT1702 codec and VT1708S codec support */
-/* 2008-04-09 Lydia Wang Add mute front speaker when HP plugin */
-/* 2008-04-09 Lydia Wang Add Independent HP feature */
-/* 2008-05-28 Lydia Wang Add second S/PDIF Out support for VT1702 */
-/* 2008-09-15 Logan Li Add VT1708S Mic Boost workaround/backdoor */
-/* 2009-02-16 Logan Li Add support for VT1718S */
-/* 2009-03-13 Logan Li Add support for VT1716S */
-/* 2009-04-14 Lydai Wang Add support for VT1828S and VT2020 */
-/* 2009-07-08 Lydia Wang Add support for VT2002P */
-/* 2009-07-21 Lydia Wang Add support for VT1812 */
-/* 2009-09-19 Lydia Wang Add support for VT1818S */
-/* */
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/asoundef.h>
-#include "hda_codec.h"
-#include "hda_local.h"
-#include "hda_jack.h"
-
-/* Pin Widget NID */
-#define VT1708_HP_PIN_NID 0x20
-#define VT1708_CD_PIN_NID 0x24
-
-enum VIA_HDA_CODEC {
- UNKNOWN = -1,
- VT1708,
- VT1709_10CH,
- VT1709_6CH,
- VT1708B_8CH,
- VT1708B_4CH,
- VT1708S,
- VT1708BCE,
- VT1702,
- VT1718S,
- VT1716S,
- VT2002P,
- VT1812,
- VT1802,
- CODEC_TYPES,
-};
-
-#define VT2002P_COMPATIBLE(spec) \
- ((spec)->codec_type == VT2002P ||\
- (spec)->codec_type == VT1812 ||\
- (spec)->codec_type == VT1802)
-
-#define MAX_NID_PATH_DEPTH 5
-
-/* output-path: DAC -> ... -> pin
- * idx[] contains the source index number of the next widget;
- * e.g. idx[0] is the index of the DAC selected by path[1] widget
- * multi[] indicates whether it's a selector widget with multi-connectors
- * (i.e. the connection selection is mandatory)
- * vol_ctl and mute_ctl contains the NIDs for the assigned mixers
- */
-struct nid_path {
- int depth;
- hda_nid_t path[MAX_NID_PATH_DEPTH];
- unsigned char idx[MAX_NID_PATH_DEPTH];
- unsigned char multi[MAX_NID_PATH_DEPTH];
- unsigned int vol_ctl;
- unsigned int mute_ctl;
-};
-
-/* input-path */
-struct via_input {
- hda_nid_t pin; /* input-pin or aa-mix */
- int adc_idx; /* ADC index to be used */
- int mux_idx; /* MUX index (if any) */
- const char *label; /* input-source label */
-};
-
-#define VIA_MAX_ADCS 3
-
-enum {
- STREAM_MULTI_OUT = (1 << 0),
- STREAM_INDEP_HP = (1 << 1),
-};
-
-struct via_spec {
- /* codec parameterization */
- const struct snd_kcontrol_new *mixers[6];
- unsigned int num_mixers;
-
- const struct hda_verb *init_verbs[5];
- unsigned int num_iverbs;
-
- char stream_name_analog[32];
- char stream_name_hp[32];
- const struct hda_pcm_stream *stream_analog_playback;
- const struct hda_pcm_stream *stream_analog_capture;
-
- char stream_name_digital[32];
- const struct hda_pcm_stream *stream_digital_playback;
- const struct hda_pcm_stream *stream_digital_capture;
-
- /* playback */
- struct hda_multi_out multiout;
- hda_nid_t slave_dig_outs[2];
- hda_nid_t hp_dac_nid;
- hda_nid_t speaker_dac_nid;
- int hp_indep_shared; /* indep HP-DAC is shared with side ch */
- int opened_streams; /* STREAM_* bits */
- int active_streams; /* STREAM_* bits */
- int aamix_mode; /* loopback is enabled for output-path? */
-
- /* Output-paths:
- * There are different output-paths depending on the setup.
- * out_path, hp_path and speaker_path are primary paths. If both
- * direct DAC and aa-loopback routes are available, these contain
- * the former paths. Meanwhile *_mix_path contain the paths with
- * loopback mixer. (Since the loopback is only for front channel,
- * no out_mix_path for surround channels.)
- * The HP output has another path, hp_indep_path, which is used in
- * the independent-HP mode.
- */
- struct nid_path out_path[HDA_SIDE + 1];
- struct nid_path out_mix_path;
- struct nid_path hp_path;
- struct nid_path hp_mix_path;
- struct nid_path hp_indep_path;
- struct nid_path speaker_path;
- struct nid_path speaker_mix_path;
-
- /* capture */
- unsigned int num_adc_nids;
- hda_nid_t adc_nids[VIA_MAX_ADCS];
- hda_nid_t mux_nids[VIA_MAX_ADCS];
- hda_nid_t aa_mix_nid;
- hda_nid_t dig_in_nid;
-
- /* capture source */
- bool dyn_adc_switch;
- int num_inputs;
- struct via_input inputs[AUTO_CFG_MAX_INS + 1];
- unsigned int cur_mux[VIA_MAX_ADCS];
-
- /* dynamic DAC switching */
- unsigned int cur_dac_stream_tag;
- unsigned int cur_dac_format;
- unsigned int cur_hp_stream_tag;
- unsigned int cur_hp_format;
-
- /* dynamic ADC switching */
- hda_nid_t cur_adc;
- unsigned int cur_adc_stream_tag;
- unsigned int cur_adc_format;
-
- /* PCM information */
- struct hda_pcm pcm_rec[3];
-
- /* dynamic controls, init_verbs and input_mux */
- struct auto_pin_cfg autocfg;
- struct snd_array kctls;
- hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
-
- /* HP mode source */
- unsigned int hp_independent_mode;
- unsigned int dmic_enabled;
- unsigned int no_pin_power_ctl;
- enum VIA_HDA_CODEC codec_type;
-
- /* analog low-power control */
- bool alc_mode;
-
- /* smart51 setup */
- unsigned int smart51_nums;
- hda_nid_t smart51_pins[2];
- int smart51_idxs[2];
- const char *smart51_labels[2];
- unsigned int smart51_enabled;
-
- /* work to check hp jack state */
- struct hda_codec *codec;
- struct delayed_work vt1708_hp_work;
- int hp_work_active;
- int vt1708_jack_detect;
- int vt1708_hp_present;
-
- void (*set_widgets_power_state)(struct hda_codec *codec);
-
- struct hda_loopback_check loopback;
- int num_loopbacks;
- struct hda_amp_list loopback_list[8];
-
- /* bind capture-volume */
- struct hda_bind_ctls *bind_cap_vol;
- struct hda_bind_ctls *bind_cap_sw;
-
- struct mutex config_mutex;
-};
-
-static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec);
-static struct via_spec * via_new_spec(struct hda_codec *codec)
-{
- struct via_spec *spec;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (spec == NULL)
- return NULL;
-
- mutex_init(&spec->config_mutex);
- codec->spec = spec;
- spec->codec = codec;
- spec->codec_type = get_codec_type(codec);
- /* VT1708BCE & VT1708S are almost same */
- if (spec->codec_type == VT1708BCE)
- spec->codec_type = VT1708S;
- return spec;
-}
-
-static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
-{
- u32 vendor_id = codec->vendor_id;
- u16 ven_id = vendor_id >> 16;
- u16 dev_id = vendor_id & 0xffff;
- enum VIA_HDA_CODEC codec_type;
-
- /* get codec type */
- if (ven_id != 0x1106)
- codec_type = UNKNOWN;
- else if (dev_id >= 0x1708 && dev_id <= 0x170b)
- codec_type = VT1708;
- else if (dev_id >= 0xe710 && dev_id <= 0xe713)
- codec_type = VT1709_10CH;
- else if (dev_id >= 0xe714 && dev_id <= 0xe717)
- codec_type = VT1709_6CH;
- else if (dev_id >= 0xe720 && dev_id <= 0xe723) {
- codec_type = VT1708B_8CH;
- if (snd_hda_param_read(codec, 0x16, AC_PAR_CONNLIST_LEN) == 0x7)
- codec_type = VT1708BCE;
- } else if (dev_id >= 0xe724 && dev_id <= 0xe727)
- codec_type = VT1708B_4CH;
- else if ((dev_id & 0xfff) == 0x397
- && (dev_id >> 12) < 8)
- codec_type = VT1708S;
- else if ((dev_id & 0xfff) == 0x398
- && (dev_id >> 12) < 8)
- codec_type = VT1702;
- else if ((dev_id & 0xfff) == 0x428
- && (dev_id >> 12) < 8)
- codec_type = VT1718S;
- else if (dev_id == 0x0433 || dev_id == 0xa721)
- codec_type = VT1716S;
- else if (dev_id == 0x0441 || dev_id == 0x4441)
- codec_type = VT1718S;
- else if (dev_id == 0x0438 || dev_id == 0x4438)
- codec_type = VT2002P;
- else if (dev_id == 0x0448)
- codec_type = VT1812;
- else if (dev_id == 0x0440)
- codec_type = VT1708S;
- else if ((dev_id & 0xfff) == 0x446)
- codec_type = VT1802;
- else
- codec_type = UNKNOWN;
- return codec_type;
-};
-
-#define VIA_JACK_EVENT 0x20
-#define VIA_HP_EVENT 0x01
-#define VIA_GPIO_EVENT 0x02
-#define VIA_LINE_EVENT 0x03
-
-enum {
- VIA_CTL_WIDGET_VOL,
- VIA_CTL_WIDGET_MUTE,
- VIA_CTL_WIDGET_ANALOG_MUTE,
-};
-
-static void analog_low_current_mode(struct hda_codec *codec);
-static bool is_aa_path_mute(struct hda_codec *codec);
-
-#define hp_detect_with_aa(codec) \
- (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1 && \
- !is_aa_path_mute(codec))
-
-static void vt1708_stop_hp_work(struct via_spec *spec)
-{
- if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
- return;
- if (spec->hp_work_active) {
- snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 1);
- cancel_delayed_work_sync(&spec->vt1708_hp_work);
- spec->hp_work_active = 0;
- }
-}
-
-static void vt1708_update_hp_work(struct via_spec *spec)
-{
- if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
- return;
- if (spec->vt1708_jack_detect &&
- (spec->active_streams || hp_detect_with_aa(spec->codec))) {
- if (!spec->hp_work_active) {
- snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 0);
- schedule_delayed_work(&spec->vt1708_hp_work,
- msecs_to_jiffies(100));
- spec->hp_work_active = 1;
- }
- } else if (!hp_detect_with_aa(spec->codec))
- vt1708_stop_hp_work(spec);
-}
-
-static void set_widgets_power_state(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- if (spec->set_widgets_power_state)
- spec->set_widgets_power_state(codec);
-}
-
-static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-
- set_widgets_power_state(codec);
- analog_low_current_mode(snd_kcontrol_chip(kcontrol));
- vt1708_update_hp_work(codec->spec);
- return change;
-}
-
-/* modify .put = snd_hda_mixer_amp_switch_put */
-#define ANALOG_INPUT_MUTE \
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = NULL, \
- .index = 0, \
- .info = snd_hda_mixer_amp_switch_info, \
- .get = snd_hda_mixer_amp_switch_get, \
- .put = analog_input_switch_put, \
- .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
-
-static const struct snd_kcontrol_new via_control_templates[] = {
- HDA_CODEC_VOLUME(NULL, 0, 0, 0),
- HDA_CODEC_MUTE(NULL, 0, 0, 0),
- ANALOG_INPUT_MUTE,
-};
-
-
-/* add dynamic controls */
-static struct snd_kcontrol_new *__via_clone_ctl(struct via_spec *spec,
- const struct snd_kcontrol_new *tmpl,
- const char *name)
-{
- struct snd_kcontrol_new *knew;
-
- snd_array_init(&spec->kctls, sizeof(*knew), 32);
- knew = snd_array_new(&spec->kctls);
- if (!knew)
- return NULL;
- *knew = *tmpl;
- if (!name)
- name = tmpl->name;
- if (name) {
- knew->name = kstrdup(name, GFP_KERNEL);
- if (!knew->name)
- return NULL;
- }
- return knew;
-}
-
-static int __via_add_control(struct via_spec *spec, int type, const char *name,
- int idx, unsigned long val)
-{
- struct snd_kcontrol_new *knew;
-
- knew = __via_clone_ctl(spec, &via_control_templates[type], name);
- if (!knew)
- return -ENOMEM;
- knew->index = idx;
- if (get_amp_nid_(val))
- knew->subdevice = HDA_SUBDEV_AMP_FLAG;
- knew->private_value = val;
- return 0;
-}
-
-#define via_add_control(spec, type, name, val) \
- __via_add_control(spec, type, name, 0, val)
-
-#define via_clone_control(spec, tmpl) __via_clone_ctl(spec, tmpl, NULL)
-
-static void via_free_kctls(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
-
- if (spec->kctls.list) {
- struct snd_kcontrol_new *kctl = spec->kctls.list;
- int i;
- for (i = 0; i < spec->kctls.used; i++)
- kfree(kctl[i].name);
- }
- snd_array_free(&spec->kctls);
-}
-
-/* create input playback/capture controls for the given pin */
-static int via_new_analog_input(struct via_spec *spec, const char *ctlname,
- int type_idx, int idx, int mix_nid)
-{
- char name[32];
- int err;
-
- sprintf(name, "%s Playback Volume", ctlname);
- err = __via_add_control(spec, VIA_CTL_WIDGET_VOL, name, type_idx,
- HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
- if (err < 0)
- return err;
- sprintf(name, "%s Playback Switch", ctlname);
- err = __via_add_control(spec, VIA_CTL_WIDGET_ANALOG_MUTE, name, type_idx,
- HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
- if (err < 0)
- return err;
- return 0;
-}
-
-#define get_connection_index(codec, mux, nid) \
- snd_hda_get_conn_index(codec, mux, nid, 0)
-
-static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
- unsigned int mask)
-{
- unsigned int caps;
- if (!nid)
- return false;
- caps = get_wcaps(codec, nid);
- if (dir == HDA_INPUT)
- caps &= AC_WCAP_IN_AMP;
- else
- caps &= AC_WCAP_OUT_AMP;
- if (!caps)
- return false;
- if (query_amp_caps(codec, nid, dir) & mask)
- return true;
- return false;
-}
-
-#define have_mute(codec, nid, dir) \
- check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE)
-
-/* enable/disable the output-route mixers */
-static void activate_output_mix(struct hda_codec *codec, struct nid_path *path,
- hda_nid_t mix_nid, int idx, bool enable)
-{
- int i, num, val;
-
- if (!path)
- return;
- num = snd_hda_get_conn_list(codec, mix_nid, NULL);
- for (i = 0; i < num; i++) {
- if (i == idx)
- val = AMP_IN_UNMUTE(i);
- else
- val = AMP_IN_MUTE(i);
- snd_hda_codec_write(codec, mix_nid, 0,
- AC_VERB_SET_AMP_GAIN_MUTE, val);
- }
-}
-
-/* enable/disable the output-route */
-static void activate_output_path(struct hda_codec *codec, struct nid_path *path,
- bool enable, bool force)
-{
- struct via_spec *spec = codec->spec;
- int i;
- for (i = 0; i < path->depth; i++) {
- hda_nid_t src, dst;
- int idx = path->idx[i];
- src = path->path[i];
- if (i < path->depth - 1)
- dst = path->path[i + 1];
- else
- dst = 0;
- if (enable && path->multi[i])
- snd_hda_codec_write(codec, dst, 0,
- AC_VERB_SET_CONNECT_SEL, idx);
- if (!force && (dst == spec->aa_mix_nid))
- continue;
- if (have_mute(codec, dst, HDA_INPUT))
- activate_output_mix(codec, path, dst, idx, enable);
- if (!force && (src == path->vol_ctl || src == path->mute_ctl))
- continue;
- if (have_mute(codec, src, HDA_OUTPUT)) {
- int val = enable ? AMP_OUT_UNMUTE : AMP_OUT_MUTE;
- snd_hda_codec_write(codec, src, 0,
- AC_VERB_SET_AMP_GAIN_MUTE, val);
- }
- }
-}
-
-/* set the given pin as output */
-static void init_output_pin(struct hda_codec *codec, hda_nid_t pin,
- int pin_type)
-{
- if (!pin)
- return;
- snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
- pin_type);
- if (snd_hda_query_pin_caps(codec, pin) & AC_PINCAP_EAPD)
- snd_hda_codec_write(codec, pin, 0,
- AC_VERB_SET_EAPD_BTLENABLE, 0x02);
-}
-
-static void via_auto_init_output(struct hda_codec *codec,
- struct nid_path *path, int pin_type)
-{
- unsigned int caps;
- hda_nid_t pin;
-
- if (!path->depth)
- return;
- pin = path->path[path->depth - 1];
-
- init_output_pin(codec, pin, pin_type);
- if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
- caps = query_amp_caps(codec, pin, HDA_OUTPUT);
- else
- caps = 0;
- if (caps & AC_AMPCAP_MUTE) {
- unsigned int val;
- val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
- snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_OUT_MUTE | val);
- }
- activate_output_path(codec, path, true, true); /* force on */
-}
-
-static void via_auto_init_multi_out(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- struct nid_path *path;
- int i;
-
- for (i = 0; i < spec->autocfg.line_outs + spec->smart51_nums; i++) {
- path = &spec->out_path[i];
- if (!i && spec->aamix_mode && spec->out_mix_path.depth)
- path = &spec->out_mix_path;
- via_auto_init_output(codec, path, PIN_OUT);
- }
-}
-
-/* deactivate the inactive headphone-paths */
-static void deactivate_hp_paths(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- int shared = spec->hp_indep_shared;
-
- if (spec->hp_independent_mode) {
- activate_output_path(codec, &spec->hp_path, false, false);
- activate_output_path(codec, &spec->hp_mix_path, false, false);
- if (shared)
- activate_output_path(codec, &spec->out_path[shared],
- false, false);
- } else if (spec->aamix_mode || !spec->hp_path.depth) {
- activate_output_path(codec, &spec->hp_indep_path, false, false);
- activate_output_path(codec, &spec->hp_path, false, false);
- } else {
- activate_output_path(codec, &spec->hp_indep_path, false, false);
- activate_output_path(codec, &spec->hp_mix_path, false, false);
- }
-}
-
-static void via_auto_init_hp_out(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
-
- if (!spec->hp_path.depth) {
- via_auto_init_output(codec, &spec->hp_mix_path, PIN_HP);
- return;
- }
- deactivate_hp_paths(codec);
- if (spec->hp_independent_mode)
- via_auto_init_output(codec, &spec->hp_indep_path, PIN_HP);
- else if (spec->aamix_mode)
- via_auto_init_output(codec, &spec->hp_mix_path, PIN_HP);
- else
- via_auto_init_output(codec, &spec->hp_path, PIN_HP);
-}
-
-static void via_auto_init_speaker_out(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
-
- if (!spec->autocfg.speaker_outs)
- return;
- if (!spec->speaker_path.depth) {
- via_auto_init_output(codec, &spec->speaker_mix_path, PIN_OUT);
- return;
- }
- if (!spec->aamix_mode) {
- activate_output_path(codec, &spec->speaker_mix_path,
- false, false);
- via_auto_init_output(codec, &spec->speaker_path, PIN_OUT);
- } else {
- activate_output_path(codec, &spec->speaker_path, false, false);
- via_auto_init_output(codec, &spec->speaker_mix_path, PIN_OUT);
- }
-}
-
-static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin);
-static void via_hp_automute(struct hda_codec *codec);
-
-static void via_auto_init_analog_input(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- const struct auto_pin_cfg *cfg = &spec->autocfg;
- hda_nid_t conn[HDA_MAX_CONNECTIONS];
- unsigned int ctl;
- int i, num_conns;
-
- /* init ADCs */
- for (i = 0; i < spec->num_adc_nids; i++) {
- hda_nid_t nid = spec->adc_nids[i];
- if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP) ||
- !(query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE))
- continue;
- snd_hda_codec_write(codec, spec->adc_nids[i], 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_IN_UNMUTE(0));
- }
-
- /* init pins */
- for (i = 0; i < cfg->num_inputs; i++) {
- hda_nid_t nid = cfg->inputs[i].pin;
- if (spec->smart51_enabled && is_smart51_pins(codec, nid))
- ctl = PIN_OUT;
- else if (cfg->inputs[i].type == AUTO_PIN_MIC)
- ctl = PIN_VREF50;
- else
- ctl = PIN_IN;
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
- }
-
- /* init input-src */
- for (i = 0; i < spec->num_adc_nids; i++) {
- int adc_idx = spec->inputs[spec->cur_mux[i]].adc_idx;
- /* secondary ADCs must have the unique MUX */
- if (i > 0 && !spec->mux_nids[i])
- break;
- if (spec->mux_nids[adc_idx]) {
- int mux_idx = spec->inputs[spec->cur_mux[i]].mux_idx;
- snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
- AC_VERB_SET_CONNECT_SEL,
- mux_idx);
- }
- if (spec->dyn_adc_switch)
- break; /* only one input-src */
- }
-
- /* init aa-mixer */
- if (!spec->aa_mix_nid)
- return;
- num_conns = snd_hda_get_connections(codec, spec->aa_mix_nid, conn,
- ARRAY_SIZE(conn));
- for (i = 0; i < num_conns; i++) {
- unsigned int caps = get_wcaps(codec, conn[i]);
- if (get_wcaps_type(caps) == AC_WID_PIN)
- snd_hda_codec_write(codec, spec->aa_mix_nid, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_IN_MUTE(i));
- }
-}
-
-static void update_power_state(struct hda_codec *codec, hda_nid_t nid,
- unsigned int parm)
-{
- if (snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_POWER_STATE, 0) == parm)
- return;
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
-}
-
-static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
- unsigned int *affected_parm)
-{
- unsigned parm;
- unsigned def_conf = snd_hda_codec_get_pincfg(codec, nid);
- unsigned no_presence = (def_conf & AC_DEFCFG_MISC)
- >> AC_DEFCFG_MISC_SHIFT
- & AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */
- struct via_spec *spec = codec->spec;
- unsigned present = 0;
-
- no_presence |= spec->no_pin_power_ctl;
- if (!no_presence)
- present = snd_hda_jack_detect(codec, nid);
- if ((spec->smart51_enabled && is_smart51_pins(codec, nid))
- || ((no_presence || present)
- && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) {
- *affected_parm = AC_PWRST_D0; /* if it's connected */
- parm = AC_PWRST_D0;
- } else
- parm = AC_PWRST_D3;
-
- update_power_state(codec, nid, parm);
-}
-
-static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static const char * const texts[] = {
- "Disabled", "Enabled"
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int via_pin_power_ctl_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct via_spec *spec = codec->spec;
- ucontrol->value.enumerated.item[0] = !spec->no_pin_power_ctl;
- return 0;
-}
-
-static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct via_spec *spec = codec->spec;
- unsigned int val = !ucontrol->value.enumerated.item[0];
-
- if (val == spec->no_pin_power_ctl)
- return 0;
- spec->no_pin_power_ctl = val;
- set_widgets_power_state(codec);
- analog_low_current_mode(codec);
- return 1;
-}
-
-static const struct snd_kcontrol_new via_pin_power_ctl_enum = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Dynamic Power-Control",
- .info = via_pin_power_ctl_info,
- .get = via_pin_power_ctl_get,
- .put = via_pin_power_ctl_put,
-};
-
-
-static int via_independent_hp_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static const char * const texts[] = { "OFF", "ON" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item >= 2)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct via_spec *spec = codec->spec;
-
- ucontrol->value.enumerated.item[0] = spec->hp_independent_mode;
- return 0;
-}
-
-/* adjust spec->multiout setup according to the current flags */
-static void setup_playback_multi_pcm(struct via_spec *spec)
-{
- const struct auto_pin_cfg *cfg = &spec->autocfg;
- spec->multiout.num_dacs = cfg->line_outs + spec->smart51_nums;
- spec->multiout.hp_nid = 0;
- if (!spec->hp_independent_mode) {
- if (!spec->hp_indep_shared)
- spec->multiout.hp_nid = spec->hp_dac_nid;
- } else {
- if (spec->hp_indep_shared)
- spec->multiout.num_dacs = cfg->line_outs - 1;
- }
-}
-
-/* update DAC setups according to indep-HP switch;
- * this function is called only when indep-HP is modified
- */
-static void switch_indep_hp_dacs(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- int shared = spec->hp_indep_shared;
- hda_nid_t shared_dac, hp_dac;
-
- if (!spec->opened_streams)
- return;
-
- shared_dac = shared ? spec->multiout.dac_nids[shared] : 0;
- hp_dac = spec->hp_dac_nid;
- if (spec->hp_independent_mode) {
- /* switch to indep-HP mode */
- if (spec->active_streams & STREAM_MULTI_OUT) {
- __snd_hda_codec_cleanup_stream(codec, hp_dac, 1);
- __snd_hda_codec_cleanup_stream(codec, shared_dac, 1);
- }
- if (spec->active_streams & STREAM_INDEP_HP)
- snd_hda_codec_setup_stream(codec, hp_dac,
- spec->cur_hp_stream_tag, 0,
- spec->cur_hp_format);
- } else {
- /* back to HP or shared-DAC */
- if (spec->active_streams & STREAM_INDEP_HP)
- __snd_hda_codec_cleanup_stream(codec, hp_dac, 1);
- if (spec->active_streams & STREAM_MULTI_OUT) {
- hda_nid_t dac;
- int ch;
- if (shared_dac) { /* reset mutli-ch DAC */
- dac = shared_dac;
- ch = shared * 2;
- } else { /* reset HP DAC */
- dac = hp_dac;
- ch = 0;
- }
- snd_hda_codec_setup_stream(codec, dac,
- spec->cur_dac_stream_tag, ch,
- spec->cur_dac_format);
- }
- }
- setup_playback_multi_pcm(spec);
-}
-
-static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct via_spec *spec = codec->spec;
- int cur, shared;
-
- mutex_lock(&spec->config_mutex);
- cur = !!ucontrol->value.enumerated.item[0];
- if (spec->hp_independent_mode == cur) {
- mutex_unlock(&spec->config_mutex);
- return 0;
- }
- spec->hp_independent_mode = cur;
- shared = spec->hp_indep_shared;
- deactivate_hp_paths(codec);
- if (cur)
- activate_output_path(codec, &spec->hp_indep_path, true, false);
- else {
- if (shared)
- activate_output_path(codec, &spec->out_path[shared],
- true, false);
- if (spec->aamix_mode || !spec->hp_path.depth)
- activate_output_path(codec, &spec->hp_mix_path,
- true, false);
- else
- activate_output_path(codec, &spec->hp_path,
- true, false);
- }
-
- switch_indep_hp_dacs(codec);
- mutex_unlock(&spec->config_mutex);
-
- /* update jack power state */
- set_widgets_power_state(codec);
- via_hp_automute(codec);
- return 1;
-}
-
-static const struct snd_kcontrol_new via_hp_mixer = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Independent HP",
- .info = via_independent_hp_info,
- .get = via_independent_hp_get,
- .put = via_independent_hp_put,
-};
-
-static int via_hp_build(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- struct snd_kcontrol_new *knew;
- hda_nid_t nid;
-
- nid = spec->autocfg.hp_pins[0];
- knew = via_clone_control(spec, &via_hp_mixer);
- if (knew == NULL)
- return -ENOMEM;
-
- knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
-
- return 0;
-}
-
-static void notify_aa_path_ctls(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- int i;
-
- for (i = 0; i < spec->smart51_nums; i++) {
- struct snd_kcontrol *ctl;
- struct snd_ctl_elem_id id;
- memset(&id, 0, sizeof(id));
- id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- sprintf(id.name, "%s Playback Volume", spec->smart51_labels[i]);
- ctl = snd_hda_find_mixer_ctl(codec, id.name);
- if (ctl)
- snd_ctl_notify(codec->bus->card,
- SNDRV_CTL_EVENT_MASK_VALUE,
- &ctl->id);
- }
-}
-
-static void mute_aa_path(struct hda_codec *codec, int mute)
-{
- struct via_spec *spec = codec->spec;
- int val = mute ? HDA_AMP_MUTE : HDA_AMP_UNMUTE;
- int i;
-
- /* check AA path's mute status */
- for (i = 0; i < spec->smart51_nums; i++) {
- if (spec->smart51_idxs[i] < 0)
- continue;
- snd_hda_codec_amp_stereo(codec, spec->aa_mix_nid,
- HDA_INPUT, spec->smart51_idxs[i],
- HDA_AMP_MUTE, val);
- }
-}
-
-static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin)
-{
- struct via_spec *spec = codec->spec;
- int i;
-
- for (i = 0; i < spec->smart51_nums; i++)
- if (spec->smart51_pins[i] == pin)
- return true;
- return false;
-}
-
-static int via_smart51_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct via_spec *spec = codec->spec;
-
- *ucontrol->value.integer.value = spec->smart51_enabled;
- return 0;
-}
-
-static int via_smart51_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct via_spec *spec = codec->spec;
- int out_in = *ucontrol->value.integer.value
- ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN;
- int i;
-
- for (i = 0; i < spec->smart51_nums; i++) {
- hda_nid_t nid = spec->smart51_pins[i];
- unsigned int parm;
-
- parm = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
- parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
- parm |= out_in;
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- parm);
- if (out_in == AC_PINCTL_OUT_EN) {
- mute_aa_path(codec, 1);
- notify_aa_path_ctls(codec);
- }
- }
- spec->smart51_enabled = *ucontrol->value.integer.value;
- set_widgets_power_state(codec);
- return 1;
-}
-
-static const struct snd_kcontrol_new via_smart51_mixer = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Smart 5.1",
- .count = 1,
- .info = snd_ctl_boolean_mono_info,
- .get = via_smart51_get,
- .put = via_smart51_put,
-};
-
-static int via_smart51_build(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
-
- if (!spec->smart51_nums)
- return 0;
- if (!via_clone_control(spec, &via_smart51_mixer))
- return -ENOMEM;
- return 0;
-}
-
-/* check AA path's mute status */
-static bool is_aa_path_mute(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- const struct hda_amp_list *p;
- int i, ch, v;
-
- for (i = 0; i < spec->num_loopbacks; i++) {
- p = &spec->loopback_list[i];
- for (ch = 0; ch < 2; ch++) {
- v = snd_hda_codec_amp_read(codec, p->nid, ch, p->dir,
- p->idx);
- if (!(v & HDA_AMP_MUTE) && v > 0)
- return false;
- }
- }
- return true;
-}
-
-/* enter/exit analog low-current mode */
-static void __analog_low_current_mode(struct hda_codec *codec, bool force)
-{
- struct via_spec *spec = codec->spec;
- bool enable;
- unsigned int verb, parm;
-
- if (spec->no_pin_power_ctl)
- enable = false;
- else
- enable = is_aa_path_mute(codec) && !spec->opened_streams;
- if (enable == spec->alc_mode && !force)
- return;
- spec->alc_mode = enable;
-
- /* decide low current mode's verb & parameter */
- switch (spec->codec_type) {
- case VT1708B_8CH:
- case VT1708B_4CH:
- verb = 0xf70;
- parm = enable ? 0x02 : 0x00; /* 0x02: 2/3x, 0x00: 1x */
- break;
- case VT1708S:
- case VT1718S:
- case VT1716S:
- verb = 0xf73;
- parm = enable ? 0x51 : 0xe1; /* 0x51: 4/28x, 0xe1: 1x */
- break;
- case VT1702:
- verb = 0xf73;
- parm = enable ? 0x01 : 0x1d; /* 0x01: 4/40x, 0x1d: 1x */
- break;
- case VT2002P:
- case VT1812:
- case VT1802:
- verb = 0xf93;
- parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */
- break;
- default:
- return; /* other codecs are not supported */
- }
- /* send verb */
- snd_hda_codec_write(codec, codec->afg, 0, verb, parm);
-}
-
-static void analog_low_current_mode(struct hda_codec *codec)
-{
- return __analog_low_current_mode(codec, false);
-}
-
-/*
- * generic initialization of ADC, input mixers and output mixers
- */
-static const struct hda_verb vt1708_init_verbs[] = {
- /* power down jack detect function */
- {0x1, 0xf81, 0x1},
- { }
-};
-
-static void set_stream_open(struct hda_codec *codec, int bit, bool active)
-{
- struct via_spec *spec = codec->spec;
-
- if (active)
- spec->opened_streams |= bit;
- else
- spec->opened_streams &= ~bit;
- analog_low_current_mode(codec);
-}
-
-static int via_playback_multi_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct via_spec *spec = codec->spec;
- const struct auto_pin_cfg *cfg = &spec->autocfg;
- int err;
-
- spec->multiout.num_dacs = cfg->line_outs + spec->smart51_nums;
- spec->multiout.max_channels = spec->multiout.num_dacs * 2;
- set_stream_open(codec, STREAM_MULTI_OUT, true);
- err = snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
- hinfo);
- if (err < 0) {
- set_stream_open(codec, STREAM_MULTI_OUT, false);
- return err;
- }
- return 0;
-}
-
-static int via_playback_multi_pcm_close(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- set_stream_open(codec, STREAM_MULTI_OUT, false);
- return 0;
-}
-
-static int via_playback_hp_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct via_spec *spec = codec->spec;
-
- if (snd_BUG_ON(!spec->hp_dac_nid))
- return -EINVAL;
- set_stream_open(codec, STREAM_INDEP_HP, true);
- return 0;
-}
-
-static int via_playback_hp_pcm_close(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- set_stream_open(codec, STREAM_INDEP_HP, false);
- return 0;
-}
-
-static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct via_spec *spec = codec->spec;
-
- mutex_lock(&spec->config_mutex);
- setup_playback_multi_pcm(spec);
- snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
- format, substream);
- /* remember for dynamic DAC switch with indep-HP */
- spec->active_streams |= STREAM_MULTI_OUT;
- spec->cur_dac_stream_tag = stream_tag;
- spec->cur_dac_format = format;
- mutex_unlock(&spec->config_mutex);
- vt1708_update_hp_work(spec);
- return 0;
-}
-
-static int via_playback_hp_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct via_spec *spec = codec->spec;
-
- mutex_lock(&spec->config_mutex);
- if (spec->hp_independent_mode)
- snd_hda_codec_setup_stream(codec, spec->hp_dac_nid,
- stream_tag, 0, format);
- spec->active_streams |= STREAM_INDEP_HP;
- spec->cur_hp_stream_tag = stream_tag;
- spec->cur_hp_format = format;
- mutex_unlock(&spec->config_mutex);
- vt1708_update_hp_work(spec);
- return 0;
-}
-
-static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct via_spec *spec = codec->spec;
-
- mutex_lock(&spec->config_mutex);
- snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
- spec->active_streams &= ~STREAM_MULTI_OUT;
- mutex_unlock(&spec->config_mutex);
- vt1708_update_hp_work(spec);
- return 0;
-}
-
-static int via_playback_hp_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct via_spec *spec = codec->spec;
-
- mutex_lock(&spec->config_mutex);
- if (spec->hp_independent_mode)
- snd_hda_codec_setup_stream(codec, spec->hp_dac_nid, 0, 0, 0);
- spec->active_streams &= ~STREAM_INDEP_HP;
- mutex_unlock(&spec->config_mutex);
- vt1708_update_hp_work(spec);
- return 0;
-}
-
-/*
- * Digital out
- */
-static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct via_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_open(codec, &spec->multiout);
-}
-
-static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct via_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_close(codec, &spec->multiout);
-}
-
-static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct via_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
- stream_tag, format, substream);
-}
-
-static int via_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct via_spec *spec = codec->spec;
- snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
- return 0;
-}
-
-/*
- * Analog capture
- */
-static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct via_spec *spec = codec->spec;
-
- snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
- stream_tag, 0, format);
- return 0;
-}
-
-static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct via_spec *spec = codec->spec;
- snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
- return 0;
-}
-
-/* analog capture with dynamic ADC switching */
-static int via_dyn_adc_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct via_spec *spec = codec->spec;
- int adc_idx = spec->inputs[spec->cur_mux[0]].adc_idx;
-
- mutex_lock(&spec->config_mutex);
- spec->cur_adc = spec->adc_nids[adc_idx];
- spec->cur_adc_stream_tag = stream_tag;
- spec->cur_adc_format = format;
- snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
- mutex_unlock(&spec->config_mutex);
- return 0;
-}
-
-static int via_dyn_adc_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- struct via_spec *spec = codec->spec;
-
- mutex_lock(&spec->config_mutex);
- snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
- spec->cur_adc = 0;
- mutex_unlock(&spec->config_mutex);
- return 0;
-}
-
-/* re-setup the stream if running; called from input-src put */
-static bool via_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur)
-{
- struct via_spec *spec = codec->spec;
- int adc_idx = spec->inputs[cur].adc_idx;
- hda_nid_t adc = spec->adc_nids[adc_idx];
- bool ret = false;
-
- mutex_lock(&spec->config_mutex);
- if (spec->cur_adc && spec->cur_adc != adc) {
- /* stream is running, let's swap the current ADC */
- __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
- spec->cur_adc = adc;
- snd_hda_codec_setup_stream(codec, adc,
- spec->cur_adc_stream_tag, 0,
- spec->cur_adc_format);
- ret = true;
- }
- mutex_unlock(&spec->config_mutex);
- return ret;
-}
-
-static const struct hda_pcm_stream via_pcm_analog_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 8,
- /* NID is set in via_build_pcms */
- .ops = {
- .open = via_playback_multi_pcm_open,
- .close = via_playback_multi_pcm_close,
- .prepare = via_playback_multi_pcm_prepare,
- .cleanup = via_playback_multi_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream via_pcm_hp_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- /* NID is set in via_build_pcms */
- .ops = {
- .open = via_playback_hp_pcm_open,
- .close = via_playback_hp_pcm_close,
- .prepare = via_playback_hp_pcm_prepare,
- .cleanup = via_playback_hp_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 8,
- /* NID is set in via_build_pcms */
- /* We got noisy outputs on the right channel on VT1708 when
- * 24bit samples are used. Until any workaround is found,
- * disable the 24bit format, so far.
- */
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .ops = {
- .open = via_playback_multi_pcm_open,
- .close = via_playback_multi_pcm_close,
- .prepare = via_playback_multi_pcm_prepare,
- .cleanup = via_playback_multi_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream via_pcm_analog_capture = {
- .substreams = 1, /* will be changed in via_build_pcms() */
- .channels_min = 2,
- .channels_max = 2,
- /* NID is set in via_build_pcms */
- .ops = {
- .prepare = via_capture_pcm_prepare,
- .cleanup = via_capture_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream via_pcm_dyn_adc_analog_capture = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- /* NID is set in via_build_pcms */
- .ops = {
- .prepare = via_dyn_adc_capture_pcm_prepare,
- .cleanup = via_dyn_adc_capture_pcm_cleanup,
- },
-};
-
-static const struct hda_pcm_stream via_pcm_digital_playback = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
- /* NID is set in via_build_pcms */
- .ops = {
- .open = via_dig_playback_pcm_open,
- .close = via_dig_playback_pcm_close,
- .prepare = via_dig_playback_pcm_prepare,
- .cleanup = via_dig_playback_pcm_cleanup
- },
-};
-
-static const struct hda_pcm_stream via_pcm_digital_capture = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 2,
-};
-
-/*
- * slave controls for virtual master
- */
-static const char * const via_slave_pfxs[] = {
- "Front", "Surround", "Center", "LFE", "Side",
- "Headphone", "Speaker",
- NULL,
-};
-
-static int via_build_controls(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- struct snd_kcontrol *kctl;
- int err, i;
-
- spec->no_pin_power_ctl = 1;
- if (spec->set_widgets_power_state)
- if (!via_clone_control(spec, &via_pin_power_ctl_enum))
- return -ENOMEM;
-
- for (i = 0; i < spec->num_mixers; i++) {
- err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
- if (err < 0)
- return err;
- }
-
- if (spec->multiout.dig_out_nid) {
- err = snd_hda_create_spdif_out_ctls(codec,
- spec->multiout.dig_out_nid,
- spec->multiout.dig_out_nid);
- if (err < 0)
- return err;
- err = snd_hda_create_spdif_share_sw(codec,
- &spec->multiout);
- if (err < 0)
- return err;
- spec->multiout.share_spdif = 1;
- }
- if (spec->dig_in_nid) {
- err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
- if (err < 0)
- return err;
- }
-
- /* if we have no master control, let's create it */
- if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
- unsigned int vmaster_tlv[4];
- snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
- HDA_OUTPUT, vmaster_tlv);
- err = snd_hda_add_vmaster(codec, "Master Playback Volume",
- vmaster_tlv, via_slave_pfxs,
- "Playback Volume");
- if (err < 0)
- return err;
- }
- if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
- err = snd_hda_add_vmaster(codec, "Master Playback Switch",
- NULL, via_slave_pfxs,
- "Playback Switch");
- if (err < 0)
- return err;
- }
-
- /* assign Capture Source enums to NID */
- kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
- for (i = 0; kctl && i < kctl->count; i++) {
- if (!spec->mux_nids[i])
- continue;
- err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]);
- if (err < 0)
- return err;
- }
-
- via_free_kctls(codec); /* no longer needed */
-
- err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static int via_build_pcms(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- struct hda_pcm *info = spec->pcm_rec;
-
- codec->num_pcms = 0;
- codec->pcm_info = info;
-
- if (spec->multiout.num_dacs || spec->num_adc_nids) {
- snprintf(spec->stream_name_analog,
- sizeof(spec->stream_name_analog),
- "%s Analog", codec->chip_name);
- info->name = spec->stream_name_analog;
-
- if (spec->multiout.num_dacs) {
- if (!spec->stream_analog_playback)
- spec->stream_analog_playback =
- &via_pcm_analog_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
- *spec->stream_analog_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
- spec->multiout.dac_nids[0];
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
- spec->multiout.max_channels;
- }
-
- if (!spec->stream_analog_capture) {
- if (spec->dyn_adc_switch)
- spec->stream_analog_capture =
- &via_pcm_dyn_adc_analog_capture;
- else
- spec->stream_analog_capture =
- &via_pcm_analog_capture;
- }
- if (spec->num_adc_nids) {
- info->stream[SNDRV_PCM_STREAM_CAPTURE] =
- *spec->stream_analog_capture;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
- spec->adc_nids[0];
- if (!spec->dyn_adc_switch)
- info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
- spec->num_adc_nids;
- }
- codec->num_pcms++;
- info++;
- }
-
- if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
- snprintf(spec->stream_name_digital,
- sizeof(spec->stream_name_digital),
- "%s Digital", codec->chip_name);
- info->name = spec->stream_name_digital;
- info->pcm_type = HDA_PCM_TYPE_SPDIF;
- if (spec->multiout.dig_out_nid) {
- if (!spec->stream_digital_playback)
- spec->stream_digital_playback =
- &via_pcm_digital_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
- *spec->stream_digital_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
- spec->multiout.dig_out_nid;
- }
- if (spec->dig_in_nid) {
- if (!spec->stream_digital_capture)
- spec->stream_digital_capture =
- &via_pcm_digital_capture;
- info->stream[SNDRV_PCM_STREAM_CAPTURE] =
- *spec->stream_digital_capture;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
- spec->dig_in_nid;
- }
- codec->num_pcms++;
- info++;
- }
-
- if (spec->hp_dac_nid) {
- snprintf(spec->stream_name_hp, sizeof(spec->stream_name_hp),
- "%s HP", codec->chip_name);
- info->name = spec->stream_name_hp;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] = via_pcm_hp_playback;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
- spec->hp_dac_nid;
- codec->num_pcms++;
- info++;
- }
- return 0;
-}
-
-static void via_free(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
-
- if (!spec)
- return;
-
- via_free_kctls(codec);
- vt1708_stop_hp_work(spec);
- kfree(spec->bind_cap_vol);
- kfree(spec->bind_cap_sw);
- kfree(spec);
-}
-
-/* mute/unmute outputs */
-static void toggle_output_mutes(struct hda_codec *codec, int num_pins,
- hda_nid_t *pins, bool mute)
-{
- int i;
- for (i = 0; i < num_pins; i++) {
- unsigned int parm = snd_hda_codec_read(codec, pins[i], 0,
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
- if (parm & AC_PINCTL_IN_EN)
- continue;
- if (mute)
- parm &= ~AC_PINCTL_OUT_EN;
- else
- parm |= AC_PINCTL_OUT_EN;
- snd_hda_codec_write(codec, pins[i], 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, parm);
- }
-}
-
-/* mute internal speaker if line-out is plugged */
-static void via_line_automute(struct hda_codec *codec, int present)
-{
- struct via_spec *spec = codec->spec;
-
- if (!spec->autocfg.speaker_outs)
- return;
- if (!present)
- present = snd_hda_jack_detect(codec,
- spec->autocfg.line_out_pins[0]);
- toggle_output_mutes(codec, spec->autocfg.speaker_outs,
- spec->autocfg.speaker_pins,
- present);
-}
-
-/* mute internal speaker if HP is plugged */
-static void via_hp_automute(struct hda_codec *codec)
-{
- int present = 0;
- int nums;
- struct via_spec *spec = codec->spec;
-
- if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0] &&
- (spec->codec_type != VT1708 || spec->vt1708_jack_detect))
- present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
-
- if (spec->smart51_enabled)
- nums = spec->autocfg.line_outs + spec->smart51_nums;
- else
- nums = spec->autocfg.line_outs;
- toggle_output_mutes(codec, nums, spec->autocfg.line_out_pins, present);
-
- via_line_automute(codec, present);
-}
-
-static void via_gpio_control(struct hda_codec *codec)
-{
- unsigned int gpio_data;
- unsigned int vol_counter;
- unsigned int vol;
- unsigned int master_vol;
-
- struct via_spec *spec = codec->spec;
-
- gpio_data = snd_hda_codec_read(codec, codec->afg, 0,
- AC_VERB_GET_GPIO_DATA, 0) & 0x03;
-
- vol_counter = (snd_hda_codec_read(codec, codec->afg, 0,
- 0xF84, 0) & 0x3F0000) >> 16;
-
- vol = vol_counter & 0x1F;
- master_vol = snd_hda_codec_read(codec, 0x1A, 0,
- AC_VERB_GET_AMP_GAIN_MUTE,
- AC_AMP_GET_INPUT);
-
- if (gpio_data == 0x02) {
- /* unmute line out */
- snd_hda_codec_write(codec, spec->autocfg.line_out_pins[0], 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- PIN_OUT);
- if (vol_counter & 0x20) {
- /* decrease volume */
- if (vol > master_vol)
- vol = master_vol;
- snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT,
- 0, HDA_AMP_VOLMASK,
- master_vol-vol);
- } else {
- /* increase volume */
- snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0,
- HDA_AMP_VOLMASK,
- ((master_vol+vol) > 0x2A) ? 0x2A :
- (master_vol+vol));
- }
- } else if (!(gpio_data & 0x02)) {
- /* mute line out */
- snd_hda_codec_write(codec, spec->autocfg.line_out_pins[0], 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL,
- 0);
- }
-}
-
-/* unsolicited event for jack sensing */
-static void via_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- res >>= 26;
- res = snd_hda_jack_get_action(codec, res);
-
- if (res & VIA_JACK_EVENT)
- set_widgets_power_state(codec);
-
- res &= ~VIA_JACK_EVENT;
-
- if (res == VIA_HP_EVENT || res == VIA_LINE_EVENT)
- via_hp_automute(codec);
- else if (res == VIA_GPIO_EVENT)
- via_gpio_control(codec);
- snd_hda_jack_report_sync(codec);
-}
-
-#ifdef CONFIG_PM
-static int via_suspend(struct hda_codec *codec, pm_message_t state)
-{
- struct via_spec *spec = codec->spec;
- vt1708_stop_hp_work(spec);
- return 0;
-}
-#endif
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
-{
- struct via_spec *spec = codec->spec;
- return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
-}
-#endif
-
-/*
- */
-
-static int via_init(struct hda_codec *codec);
-
-static const struct hda_codec_ops via_patch_ops = {
- .build_controls = via_build_controls,
- .build_pcms = via_build_pcms,
- .init = via_init,
- .free = via_free,
- .unsol_event = via_unsol_event,
-#ifdef CONFIG_PM
- .suspend = via_suspend,
-#endif
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- .check_power_status = via_check_power_status,
-#endif
-};
-
-static bool is_empty_dac(struct hda_codec *codec, hda_nid_t dac)
-{
- struct via_spec *spec = codec->spec;
- int i;
-
- for (i = 0; i < spec->multiout.num_dacs; i++) {
- if (spec->multiout.dac_nids[i] == dac)
- return false;
- }
- if (spec->hp_dac_nid == dac)
- return false;
- return true;
-}
-
-static bool __parse_output_path(struct hda_codec *codec, hda_nid_t nid,
- hda_nid_t target_dac, int with_aa_mix,
- struct nid_path *path, int depth)
-{
- struct via_spec *spec = codec->spec;
- hda_nid_t conn[8];
- int i, nums;
-
- if (nid == spec->aa_mix_nid) {
- if (!with_aa_mix)
- return false;
- with_aa_mix = 2; /* mark aa-mix is included */
- }
-
- nums = snd_hda_get_connections(codec, nid, conn, ARRAY_SIZE(conn));
- for (i = 0; i < nums; i++) {
- if (get_wcaps_type(get_wcaps(codec, conn[i])) != AC_WID_AUD_OUT)
- continue;
- if (conn[i] == target_dac || is_empty_dac(codec, conn[i])) {
- /* aa-mix is requested but not included? */
- if (!(spec->aa_mix_nid && with_aa_mix == 1))
- goto found;
- }
- }
- if (depth >= MAX_NID_PATH_DEPTH)
- return false;
- for (i = 0; i < nums; i++) {
- unsigned int type;
- type = get_wcaps_type(get_wcaps(codec, conn[i]));
- if (type == AC_WID_AUD_OUT)
- continue;
- if (__parse_output_path(codec, conn[i], target_dac,
- with_aa_mix, path, depth + 1))
- goto found;
- }
- return false;
-
- found:
- path->path[path->depth] = conn[i];
- path->idx[path->depth] = i;
- if (nums > 1 && get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_AUD_MIX)
- path->multi[path->depth] = 1;
- path->depth++;
- return true;
-}
-
-static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid,
- hda_nid_t target_dac, int with_aa_mix,
- struct nid_path *path)
-{
- if (__parse_output_path(codec, nid, target_dac, with_aa_mix, path, 1)) {
- path->path[path->depth] = nid;
- path->depth++;
- snd_printdd("output-path: depth=%d, %02x/%02x/%02x/%02x/%02x\n",
- path->depth, path->path[0], path->path[1],
- path->path[2], path->path[3], path->path[4]);
- return true;
- }
- return false;
-}
-
-static int via_auto_fill_dac_nids(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- const struct auto_pin_cfg *cfg = &spec->autocfg;
- int i, dac_num;
- hda_nid_t nid;
-
- spec->multiout.dac_nids = spec->private_dac_nids;
- dac_num = 0;
- for (i = 0; i < cfg->line_outs; i++) {
- hda_nid_t dac = 0;
- nid = cfg->line_out_pins[i];
- if (!nid)
- continue;
- if (parse_output_path(codec, nid, 0, 0, &spec->out_path[i]))
- dac = spec->out_path[i].path[0];
- if (!i && parse_output_path(codec, nid, dac, 1,
- &spec->out_mix_path))
- dac = spec->out_mix_path.path[0];
- if (dac) {
- spec->private_dac_nids[i] = dac;
- dac_num++;
- }
- }
- if (!spec->out_path[0].depth && spec->out_mix_path.depth) {
- spec->out_path[0] = spec->out_mix_path;
- spec->out_mix_path.depth = 0;
- }
- spec->multiout.num_dacs = dac_num;
- return 0;
-}
-
-static int create_ch_ctls(struct hda_codec *codec, const char *pfx,
- int chs, bool check_dac, struct nid_path *path)
-{
- struct via_spec *spec = codec->spec;
- char name[32];
- hda_nid_t dac, pin, sel, nid;
- int err;
-
- dac = check_dac ? path->path[0] : 0;
- pin = path->path[path->depth - 1];
- sel = path->depth > 1 ? path->path[1] : 0;
-
- if (dac && check_amp_caps(codec, dac, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS))
- nid = dac;
- else if (check_amp_caps(codec, pin, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS))
- nid = pin;
- else if (check_amp_caps(codec, sel, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS))
- nid = sel;
- else
- nid = 0;
- if (nid) {
- sprintf(name, "%s Playback Volume", pfx);
- err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
- HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
- if (err < 0)
- return err;
- path->vol_ctl = nid;
- }
-
- if (dac && check_amp_caps(codec, dac, HDA_OUTPUT, AC_AMPCAP_MUTE))
- nid = dac;
- else if (check_amp_caps(codec, pin, HDA_OUTPUT, AC_AMPCAP_MUTE))
- nid = pin;
- else if (check_amp_caps(codec, sel, HDA_OUTPUT, AC_AMPCAP_MUTE))
- nid = sel;
- else
- nid = 0;
- if (nid) {
- sprintf(name, "%s Playback Switch", pfx);
- err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
- HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
- if (err < 0)
- return err;
- path->mute_ctl = nid;
- }
- return 0;
-}
-
-static void mangle_smart51(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- struct auto_pin_cfg_item *ins = cfg->inputs;
- int i, j, nums, attr;
- int pins[AUTO_CFG_MAX_INS];
-
- for (attr = INPUT_PIN_ATTR_REAR; attr >= INPUT_PIN_ATTR_NORMAL; attr--) {
- nums = 0;
- for (i = 0; i < cfg->num_inputs; i++) {
- unsigned int def;
- if (ins[i].type > AUTO_PIN_LINE_IN)
- continue;
- def = snd_hda_codec_get_pincfg(codec, ins[i].pin);
- if (snd_hda_get_input_pin_attr(def) != attr)
- continue;
- for (j = 0; j < nums; j++)
- if (ins[pins[j]].type < ins[i].type) {
- memmove(pins + j + 1, pins + j,
- (nums - j) * sizeof(int));
- break;
- }
- pins[j] = i;
- nums++;
- }
- if (cfg->line_outs + nums < 3)
- continue;
- for (i = 0; i < nums; i++) {
- hda_nid_t pin = ins[pins[i]].pin;
- spec->smart51_pins[spec->smart51_nums++] = pin;
- cfg->line_out_pins[cfg->line_outs++] = pin;
- if (cfg->line_outs == 3)
- break;
- }
- return;
- }
-}
-
-static void copy_path_mixer_ctls(struct nid_path *dst, struct nid_path *src)
-{
- dst->vol_ctl = src->vol_ctl;
- dst->mute_ctl = src->mute_ctl;
-}
-
-/* add playback controls from the parsed DAC table */
-static int via_auto_create_multi_out_ctls(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- struct nid_path *path;
- static const char * const chname[4] = {
- "Front", "Surround", "C/LFE", "Side"
- };
- int i, idx, err;
- int old_line_outs;
-
- /* check smart51 */
- old_line_outs = cfg->line_outs;
- if (cfg->line_outs == 1)
- mangle_smart51(codec);
-
- err = via_auto_fill_dac_nids(codec);
- if (err < 0)
- return err;
-
- if (spec->multiout.num_dacs < 3) {
- spec->smart51_nums = 0;
- cfg->line_outs = old_line_outs;
- }
- for (i = 0; i < cfg->line_outs; i++) {
- hda_nid_t pin, dac;
- pin = cfg->line_out_pins[i];
- dac = spec->multiout.dac_nids[i];
- if (!pin || !dac)
- continue;
- path = spec->out_path + i;
- if (i == HDA_CLFE) {
- err = create_ch_ctls(codec, "Center", 1, true, path);
- if (err < 0)
- return err;
- err = create_ch_ctls(codec, "LFE", 2, true, path);
- if (err < 0)
- return err;
- } else {
- const char *pfx = chname[i];
- if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT &&
- cfg->line_outs == 1)
- pfx = "Speaker";
- err = create_ch_ctls(codec, pfx, 3, true, path);
- if (err < 0)
- return err;
- }
- if (path != spec->out_path + i)
- copy_path_mixer_ctls(&spec->out_path[i], path);
- if (path == spec->out_path && spec->out_mix_path.depth)
- copy_path_mixer_ctls(&spec->out_mix_path, path);
- }
-
- idx = get_connection_index(codec, spec->aa_mix_nid,
- spec->multiout.dac_nids[0]);
- if (idx >= 0) {
- /* add control to mixer */
- const char *name;
- name = spec->out_mix_path.depth ?
- "PCM Loopback Playback Volume" : "PCM Playback Volume";
- err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
- HDA_COMPOSE_AMP_VAL(spec->aa_mix_nid, 3,
- idx, HDA_INPUT));
- if (err < 0)
- return err;
- name = spec->out_mix_path.depth ?
- "PCM Loopback Playback Switch" : "PCM Playback Switch";
- err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
- HDA_COMPOSE_AMP_VAL(spec->aa_mix_nid, 3,
- idx, HDA_INPUT));
- if (err < 0)
- return err;
- }
-
- cfg->line_outs = old_line_outs;
-
- return 0;
-}
-
-static int via_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
-{
- struct via_spec *spec = codec->spec;
- struct nid_path *path;
- bool check_dac;
- int i, err;
-
- if (!pin)
- return 0;
-
- if (!parse_output_path(codec, pin, 0, 0, &spec->hp_indep_path)) {
- for (i = HDA_SIDE; i >= HDA_CLFE; i--) {
- if (i < spec->multiout.num_dacs &&
- parse_output_path(codec, pin,
- spec->multiout.dac_nids[i], 0,
- &spec->hp_indep_path)) {
- spec->hp_indep_shared = i;
- break;
- }
- }
- }
- if (spec->hp_indep_path.depth) {
- spec->hp_dac_nid = spec->hp_indep_path.path[0];
- if (!spec->hp_indep_shared)
- spec->hp_path = spec->hp_indep_path;
- }
- /* optionally check front-path w/o AA-mix */
- if (!spec->hp_path.depth)
- parse_output_path(codec, pin,
- spec->multiout.dac_nids[HDA_FRONT], 0,
- &spec->hp_path);
-
- if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
- 1, &spec->hp_mix_path) && !spec->hp_path.depth)
- return 0;
-
- if (spec->hp_path.depth) {
- path = &spec->hp_path;
- check_dac = true;
- } else {
- path = &spec->hp_mix_path;
- check_dac = false;
- }
- err = create_ch_ctls(codec, "Headphone", 3, check_dac, path);
- if (err < 0)
- return err;
- if (check_dac)
- copy_path_mixer_ctls(&spec->hp_mix_path, path);
- else
- copy_path_mixer_ctls(&spec->hp_path, path);
- if (spec->hp_indep_path.depth)
- copy_path_mixer_ctls(&spec->hp_indep_path, path);
- return 0;
-}
-
-static int via_auto_create_speaker_ctls(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- struct nid_path *path;
- bool check_dac;
- hda_nid_t pin, dac = 0;
- int err;
-
- pin = spec->autocfg.speaker_pins[0];
- if (!spec->autocfg.speaker_outs || !pin)
- return 0;
-
- if (parse_output_path(codec, pin, 0, 0, &spec->speaker_path))
- dac = spec->speaker_path.path[0];
- if (!dac)
- parse_output_path(codec, pin,
- spec->multiout.dac_nids[HDA_FRONT], 0,
- &spec->speaker_path);
- if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
- 1, &spec->speaker_mix_path) && !dac)
- return 0;
-
- /* no AA-path for front? */
- if (!spec->out_mix_path.depth && spec->speaker_mix_path.depth)
- dac = 0;
-
- spec->speaker_dac_nid = dac;
- spec->multiout.extra_out_nid[0] = dac;
- if (dac) {
- path = &spec->speaker_path;
- check_dac = true;
- } else {
- path = &spec->speaker_mix_path;
- check_dac = false;
- }
- err = create_ch_ctls(codec, "Speaker", 3, check_dac, path);
- if (err < 0)
- return err;
- if (check_dac)
- copy_path_mixer_ctls(&spec->speaker_mix_path, path);
- else
- copy_path_mixer_ctls(&spec->speaker_path, path);
- return 0;
-}
-
-#define via_aamix_ctl_info via_pin_power_ctl_info
-
-static int via_aamix_ctl_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct via_spec *spec = codec->spec;
- ucontrol->value.enumerated.item[0] = spec->aamix_mode;
- return 0;
-}
-
-static void update_aamix_paths(struct hda_codec *codec, int do_mix,
- struct nid_path *nomix, struct nid_path *mix)
-{
- if (do_mix) {
- activate_output_path(codec, nomix, false, false);
- activate_output_path(codec, mix, true, false);
- } else {
- activate_output_path(codec, mix, false, false);
- activate_output_path(codec, nomix, true, false);
- }
-}
-
-static int via_aamix_ctl_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct via_spec *spec = codec->spec;
- unsigned int val = ucontrol->value.enumerated.item[0];
-
- if (val == spec->aamix_mode)
- return 0;
- spec->aamix_mode = val;
- /* update front path */
- update_aamix_paths(codec, val, &spec->out_path[0], &spec->out_mix_path);
- /* update HP path */
- if (!spec->hp_independent_mode) {
- update_aamix_paths(codec, val, &spec->hp_path,
- &spec->hp_mix_path);
- }
- /* update speaker path */
- update_aamix_paths(codec, val, &spec->speaker_path,
- &spec->speaker_mix_path);
- return 1;
-}
-
-static const struct snd_kcontrol_new via_aamix_ctl_enum = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Loopback Mixing",
- .info = via_aamix_ctl_info,
- .get = via_aamix_ctl_get,
- .put = via_aamix_ctl_put,
-};
-
-static int via_auto_create_loopback_switch(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
-
- if (!spec->aa_mix_nid)
- return 0; /* no loopback switching available */
- if (!(spec->out_mix_path.depth || spec->hp_mix_path.depth ||
- spec->speaker_path.depth))
- return 0; /* no loopback switching available */
- if (!via_clone_control(spec, &via_aamix_ctl_enum))
- return -ENOMEM;
- return 0;
-}
-
-/* look for ADCs */
-static int via_fill_adcs(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- hda_nid_t nid = codec->start_nid;
- int i;
-
- for (i = 0; i < codec->num_nodes; i++, nid++) {
- unsigned int wcaps = get_wcaps(codec, nid);
- if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
- continue;
- if (wcaps & AC_WCAP_DIGITAL)
- continue;
- if (!(wcaps & AC_WCAP_CONN_LIST))
- continue;
- if (spec->num_adc_nids >= ARRAY_SIZE(spec->adc_nids))
- return -ENOMEM;
- spec->adc_nids[spec->num_adc_nids++] = nid;
- }
- return 0;
-}
-
-/* input-src control */
-static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct via_spec *spec = codec->spec;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = spec->num_inputs;
- if (uinfo->value.enumerated.item >= spec->num_inputs)
- uinfo->value.enumerated.item = spec->num_inputs - 1;
- strcpy(uinfo->value.enumerated.name,
- spec->inputs[uinfo->value.enumerated.item].label);
- return 0;
-}
-
-static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct via_spec *spec = codec->spec;
- unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-
- ucontrol->value.enumerated.item[0] = spec->cur_mux[idx];
- return 0;
-}
-
-static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct via_spec *spec = codec->spec;
- unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- hda_nid_t mux;
- int cur;
-
- cur = ucontrol->value.enumerated.item[0];
- if (cur < 0 || cur >= spec->num_inputs)
- return -EINVAL;
- if (spec->cur_mux[idx] == cur)
- return 0;
- spec->cur_mux[idx] = cur;
- if (spec->dyn_adc_switch) {
- int adc_idx = spec->inputs[cur].adc_idx;
- mux = spec->mux_nids[adc_idx];
- via_dyn_adc_pcm_resetup(codec, cur);
- } else {
- mux = spec->mux_nids[idx];
- if (snd_BUG_ON(!mux))
- return -EINVAL;
- }
-
- if (mux) {
- /* switch to D0 beofre change index */
- update_power_state(codec, mux, AC_PWRST_D0);
- snd_hda_codec_write(codec, mux, 0,
- AC_VERB_SET_CONNECT_SEL,
- spec->inputs[cur].mux_idx);
- }
-
- /* update jack power state */
- set_widgets_power_state(codec);
- return 0;
-}
-
-static const struct snd_kcontrol_new via_input_src_ctl = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- /* The multiple "Capture Source" controls confuse alsamixer
- * So call somewhat different..
- */
- /* .name = "Capture Source", */
- .name = "Input Source",
- .info = via_mux_enum_info,
- .get = via_mux_enum_get,
- .put = via_mux_enum_put,
-};
-
-static int create_input_src_ctls(struct hda_codec *codec, int count)
-{
- struct via_spec *spec = codec->spec;
- struct snd_kcontrol_new *knew;
-
- if (spec->num_inputs <= 1 || !count)
- return 0; /* no need for single src */
-
- knew = via_clone_control(spec, &via_input_src_ctl);
- if (!knew)
- return -ENOMEM;
- knew->count = count;
- return 0;
-}
-
-/* add the powersave loopback-list entry */
-static void add_loopback_list(struct via_spec *spec, hda_nid_t mix, int idx)
-{
- struct hda_amp_list *list;
-
- if (spec->num_loopbacks >= ARRAY_SIZE(spec->loopback_list) - 1)
- return;
- list = spec->loopback_list + spec->num_loopbacks;
- list->nid = mix;
- list->dir = HDA_INPUT;
- list->idx = idx;
- spec->num_loopbacks++;
- spec->loopback.amplist = spec->loopback_list;
-}
-
-static bool is_reachable_nid(struct hda_codec *codec, hda_nid_t src,
- hda_nid_t dst)
-{
- return snd_hda_get_conn_index(codec, src, dst, 1) >= 0;
-}
-
-/* add the input-route to the given pin */
-static bool add_input_route(struct hda_codec *codec, hda_nid_t pin)
-{
- struct via_spec *spec = codec->spec;
- int c, idx;
-
- spec->inputs[spec->num_inputs].adc_idx = -1;
- spec->inputs[spec->num_inputs].pin = pin;
- for (c = 0; c < spec->num_adc_nids; c++) {
- if (spec->mux_nids[c]) {
- idx = get_connection_index(codec, spec->mux_nids[c],
- pin);
- if (idx < 0)
- continue;
- spec->inputs[spec->num_inputs].mux_idx = idx;
- } else {
- if (!is_reachable_nid(codec, spec->adc_nids[c], pin))
- continue;
- }
- spec->inputs[spec->num_inputs].adc_idx = c;
- /* Can primary ADC satisfy all inputs? */
- if (!spec->dyn_adc_switch &&
- spec->num_inputs > 0 && spec->inputs[0].adc_idx != c) {
- snd_printd(KERN_INFO
- "via: dynamic ADC switching enabled\n");
- spec->dyn_adc_switch = 1;
- }
- return true;
- }
- return false;
-}
-
-static int get_mux_nids(struct hda_codec *codec);
-
-/* parse input-routes; fill ADCs, MUXs and input-src entries */
-static int parse_analog_inputs(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- const struct auto_pin_cfg *cfg = &spec->autocfg;
- int i, err;
-
- err = via_fill_adcs(codec);
- if (err < 0)
- return err;
- err = get_mux_nids(codec);
- if (err < 0)
- return err;
-
- /* fill all input-routes */
- for (i = 0; i < cfg->num_inputs; i++) {
- if (add_input_route(codec, cfg->inputs[i].pin))
- spec->inputs[spec->num_inputs++].label =
- hda_get_autocfg_input_label(codec, cfg, i);
- }
-
- /* check for internal loopback recording */
- if (spec->aa_mix_nid &&
- add_input_route(codec, spec->aa_mix_nid))
- spec->inputs[spec->num_inputs++].label = "Stereo Mixer";
-
- return 0;
-}
-
-/* create analog-loopback volume/switch controls */
-static int create_loopback_ctls(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- const struct auto_pin_cfg *cfg = &spec->autocfg;
- const char *prev_label = NULL;
- int type_idx = 0;
- int i, j, err, idx;
-
- if (!spec->aa_mix_nid)
- return 0;
-
- for (i = 0; i < cfg->num_inputs; i++) {
- hda_nid_t pin = cfg->inputs[i].pin;
- const char *label = hda_get_autocfg_input_label(codec, cfg, i);
-
- if (prev_label && !strcmp(label, prev_label))
- type_idx++;
- else
- type_idx = 0;
- prev_label = label;
- idx = get_connection_index(codec, spec->aa_mix_nid, pin);
- if (idx >= 0) {
- err = via_new_analog_input(spec, label, type_idx,
- idx, spec->aa_mix_nid);
- if (err < 0)
- return err;
- add_loopback_list(spec, spec->aa_mix_nid, idx);
- }
-
- /* remember the label for smart51 control */
- for (j = 0; j < spec->smart51_nums; j++) {
- if (spec->smart51_pins[j] == pin) {
- spec->smart51_idxs[j] = idx;
- spec->smart51_labels[j] = label;
- break;
- }
- }
- }
- return 0;
-}
-
-/* create mic-boost controls (if present) */
-static int create_mic_boost_ctls(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- const struct auto_pin_cfg *cfg = &spec->autocfg;
- const char *prev_label = NULL;
- int type_idx = 0;
- int i, err;
-
- for (i = 0; i < cfg->num_inputs; i++) {
- hda_nid_t pin = cfg->inputs[i].pin;
- unsigned int caps;
- const char *label;
- char name[32];
-
- if (cfg->inputs[i].type != AUTO_PIN_MIC)
- continue;
- caps = query_amp_caps(codec, pin, HDA_INPUT);
- if (caps == -1 || !(caps & AC_AMPCAP_NUM_STEPS))
- continue;
- label = hda_get_autocfg_input_label(codec, cfg, i);
- if (prev_label && !strcmp(label, prev_label))
- type_idx++;
- else
- type_idx = 0;
- prev_label = label;
- snprintf(name, sizeof(name), "%s Boost Volume", label);
- err = __via_add_control(spec, VIA_CTL_WIDGET_VOL, name, type_idx,
- HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT));
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-/* create capture and input-src controls for multiple streams */
-static int create_multi_adc_ctls(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- int i, err;
-
- /* create capture mixer elements */
- for (i = 0; i < spec->num_adc_nids; i++) {
- hda_nid_t adc = spec->adc_nids[i];
- err = __via_add_control(spec, VIA_CTL_WIDGET_VOL,
- "Capture Volume", i,
- HDA_COMPOSE_AMP_VAL(adc, 3, 0,
- HDA_INPUT));
- if (err < 0)
- return err;
- err = __via_add_control(spec, VIA_CTL_WIDGET_MUTE,
- "Capture Switch", i,
- HDA_COMPOSE_AMP_VAL(adc, 3, 0,
- HDA_INPUT));
- if (err < 0)
- return err;
- }
-
- /* input-source control */
- for (i = 0; i < spec->num_adc_nids; i++)
- if (!spec->mux_nids[i])
- break;
- err = create_input_src_ctls(codec, i);
- if (err < 0)
- return err;
- return 0;
-}
-
-/* bind capture volume/switch */
-static struct snd_kcontrol_new via_bind_cap_vol_ctl =
- HDA_BIND_VOL("Capture Volume", 0);
-static struct snd_kcontrol_new via_bind_cap_sw_ctl =
- HDA_BIND_SW("Capture Switch", 0);
-
-static int init_bind_ctl(struct via_spec *spec, struct hda_bind_ctls **ctl_ret,
- struct hda_ctl_ops *ops)
-{
- struct hda_bind_ctls *ctl;
- int i;
-
- ctl = kzalloc(sizeof(*ctl) + sizeof(long) * 4, GFP_KERNEL);
- if (!ctl)
- return -ENOMEM;
- ctl->ops = ops;
- for (i = 0; i < spec->num_adc_nids; i++)
- ctl->values[i] =
- HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], 3, 0, HDA_INPUT);
- *ctl_ret = ctl;
- return 0;
-}
-
-/* create capture and input-src controls for dynamic ADC-switch case */
-static int create_dyn_adc_ctls(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- struct snd_kcontrol_new *knew;
- int err;
-
- /* set up the bind capture ctls */
- err = init_bind_ctl(spec, &spec->bind_cap_vol, &snd_hda_bind_vol);
- if (err < 0)
- return err;
- err = init_bind_ctl(spec, &spec->bind_cap_sw, &snd_hda_bind_sw);
- if (err < 0)
- return err;
-
- /* create capture mixer elements */
- knew = via_clone_control(spec, &via_bind_cap_vol_ctl);
- if (!knew)
- return -ENOMEM;
- knew->private_value = (long)spec->bind_cap_vol;
-
- knew = via_clone_control(spec, &via_bind_cap_sw_ctl);
- if (!knew)
- return -ENOMEM;
- knew->private_value = (long)spec->bind_cap_sw;
-
- /* input-source control */
- err = create_input_src_ctls(codec, 1);
- if (err < 0)
- return err;
- return 0;
-}
-
-/* parse and create capture-related stuff */
-static int via_auto_create_analog_input_ctls(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- int err;
-
- err = parse_analog_inputs(codec);
- if (err < 0)
- return err;
- if (spec->dyn_adc_switch)
- err = create_dyn_adc_ctls(codec);
- else
- err = create_multi_adc_ctls(codec);
- if (err < 0)
- return err;
- err = create_loopback_ctls(codec);
- if (err < 0)
- return err;
- err = create_mic_boost_ctls(codec);
- if (err < 0)
- return err;
- return 0;
-}
-
-static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
-{
- unsigned int def_conf;
- unsigned char seqassoc;
-
- def_conf = snd_hda_codec_get_pincfg(codec, nid);
- seqassoc = (unsigned char) get_defcfg_association(def_conf);
- seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
- if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE
- && (seqassoc == 0xf0 || seqassoc == 0xff)) {
- def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
- snd_hda_codec_set_pincfg(codec, nid, def_conf);
- }
-
- return;
-}
-
-static int vt1708_jack_detect_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct via_spec *spec = codec->spec;
-
- if (spec->codec_type != VT1708)
- return 0;
- ucontrol->value.integer.value[0] = spec->vt1708_jack_detect;
- return 0;
-}
-
-static int vt1708_jack_detect_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct via_spec *spec = codec->spec;
- int val;
-
- if (spec->codec_type != VT1708)
- return 0;
- val = !!ucontrol->value.integer.value[0];
- if (spec->vt1708_jack_detect == val)
- return 0;
- spec->vt1708_jack_detect = val;
- if (spec->vt1708_jack_detect &&
- snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") != 1) {
- mute_aa_path(codec, 1);
- notify_aa_path_ctls(codec);
- }
- via_hp_automute(codec);
- vt1708_update_hp_work(spec);
- return 1;
-}
-
-static const struct snd_kcontrol_new vt1708_jack_detect_ctl = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Jack Detect",
- .count = 1,
- .info = snd_ctl_boolean_mono_info,
- .get = vt1708_jack_detect_get,
- .put = vt1708_jack_detect_put,
-};
-
-static void fill_dig_outs(struct hda_codec *codec);
-static void fill_dig_in(struct hda_codec *codec);
-
-static int via_parse_auto_config(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- int err;
-
- err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
- if (err < 0)
- return err;
- if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
- return -EINVAL;
-
- err = via_auto_create_multi_out_ctls(codec);
- if (err < 0)
- return err;
- err = via_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
- if (err < 0)
- return err;
- err = via_auto_create_speaker_ctls(codec);
- if (err < 0)
- return err;
- err = via_auto_create_loopback_switch(codec);
- if (err < 0)
- return err;
- err = via_auto_create_analog_input_ctls(codec);
- if (err < 0)
- return err;
-
- spec->multiout.max_channels = spec->multiout.num_dacs * 2;
-
- fill_dig_outs(codec);
- fill_dig_in(codec);
-
- if (spec->kctls.list)
- spec->mixers[spec->num_mixers++] = spec->kctls.list;
-
-
- if (spec->hp_dac_nid && spec->hp_mix_path.depth) {
- err = via_hp_build(codec);
- if (err < 0)
- return err;
- }
-
- err = via_smart51_build(codec);
- if (err < 0)
- return err;
-
- /* assign slave outs */
- if (spec->slave_dig_outs[0])
- codec->slave_dig_outs = spec->slave_dig_outs;
-
- return 1;
-}
-
-static void via_auto_init_dig_outs(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- if (spec->multiout.dig_out_nid)
- init_output_pin(codec, spec->autocfg.dig_out_pins[0], PIN_OUT);
- if (spec->slave_dig_outs[0])
- init_output_pin(codec, spec->autocfg.dig_out_pins[1], PIN_OUT);
-}
-
-static void via_auto_init_dig_in(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- if (!spec->dig_in_nid)
- return;
- snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
-}
-
-/* initialize the unsolicited events */
-static void via_auto_init_unsol_event(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- unsigned int ev;
- int i;
-
- if (cfg->hp_pins[0] && is_jack_detectable(codec, cfg->hp_pins[0]))
- snd_hda_jack_detect_enable(codec, cfg->hp_pins[0],
- VIA_HP_EVENT | VIA_JACK_EVENT);
-
- if (cfg->speaker_pins[0])
- ev = VIA_LINE_EVENT;
- else
- ev = 0;
- for (i = 0; i < cfg->line_outs; i++) {
- if (cfg->line_out_pins[i] &&
- is_jack_detectable(codec, cfg->line_out_pins[i]))
- snd_hda_jack_detect_enable(codec, cfg->line_out_pins[i],
- ev | VIA_JACK_EVENT);
- }
-
- for (i = 0; i < cfg->num_inputs; i++) {
- if (is_jack_detectable(codec, cfg->inputs[i].pin))
- snd_hda_jack_detect_enable(codec, cfg->inputs[i].pin,
- VIA_JACK_EVENT);
- }
-}
-
-static int via_init(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- int i;
-
- for (i = 0; i < spec->num_iverbs; i++)
- snd_hda_sequence_write(codec, spec->init_verbs[i]);
-
- /* init power states */
- set_widgets_power_state(codec);
- __analog_low_current_mode(codec, true);
-
- via_auto_init_multi_out(codec);
- via_auto_init_hp_out(codec);
- via_auto_init_speaker_out(codec);
- via_auto_init_analog_input(codec);
- via_auto_init_dig_outs(codec);
- via_auto_init_dig_in(codec);
-
- via_auto_init_unsol_event(codec);
-
- via_hp_automute(codec);
- vt1708_update_hp_work(spec);
- snd_hda_jack_report_sync(codec);
-
- return 0;
-}
-
-static void vt1708_update_hp_jack_state(struct work_struct *work)
-{
- struct via_spec *spec = container_of(work, struct via_spec,
- vt1708_hp_work.work);
- if (spec->codec_type != VT1708)
- return;
- snd_hda_jack_set_dirty_all(spec->codec);
- /* if jack state toggled */
- if (spec->vt1708_hp_present
- != snd_hda_jack_detect(spec->codec, spec->autocfg.hp_pins[0])) {
- spec->vt1708_hp_present ^= 1;
- via_hp_automute(spec->codec);
- }
- if (spec->vt1708_jack_detect)
- schedule_delayed_work(&spec->vt1708_hp_work,
- msecs_to_jiffies(100));
-}
-
-static int get_mux_nids(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- hda_nid_t nid, conn[8];
- unsigned int type;
- int i, n;
-
- for (i = 0; i < spec->num_adc_nids; i++) {
- nid = spec->adc_nids[i];
- while (nid) {
- type = get_wcaps_type(get_wcaps(codec, nid));
- if (type == AC_WID_PIN)
- break;
- n = snd_hda_get_connections(codec, nid, conn,
- ARRAY_SIZE(conn));
- if (n <= 0)
- break;
- if (n > 1) {
- spec->mux_nids[i] = nid;
- break;
- }
- nid = conn[0];
- }
- }
- return 0;
-}
-
-static int patch_vt1708(struct hda_codec *codec)
-{
- struct via_spec *spec;
- int err;
-
- /* create a codec specific record */
- spec = via_new_spec(codec);
- if (spec == NULL)
- return -ENOMEM;
-
- spec->aa_mix_nid = 0x17;
-
- /* Add HP and CD pin config connect bit re-config action */
- vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
- vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
-
- /* automatic parse from the BIOS config */
- err = via_parse_auto_config(codec);
- if (err < 0) {
- via_free(codec);
- return err;
- }
-
- /* add jack detect on/off control */
- if (!via_clone_control(spec, &vt1708_jack_detect_ctl))
- return -ENOMEM;
-
- /* disable 32bit format on VT1708 */
- if (codec->vendor_id == 0x11061708)
- spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback;
-
- spec->init_verbs[spec->num_iverbs++] = vt1708_init_verbs;
-
- codec->patch_ops = via_patch_ops;
-
- INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state);
- return 0;
-}
-
-static int patch_vt1709(struct hda_codec *codec)
-{
- struct via_spec *spec;
- int err;
-
- /* create a codec specific record */
- spec = via_new_spec(codec);
- if (spec == NULL)
- return -ENOMEM;
-
- spec->aa_mix_nid = 0x18;
-
- err = via_parse_auto_config(codec);
- if (err < 0) {
- via_free(codec);
- return err;
- }
-
- codec->patch_ops = via_patch_ops;
-
- return 0;
-}
-
-static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- int imux_is_smixer;
- unsigned int parm;
- int is_8ch = 0;
- if ((spec->codec_type != VT1708B_4CH) &&
- (codec->vendor_id != 0x11064397))
- is_8ch = 1;
-
- /* SW0 (17h) = stereo mixer */
- imux_is_smixer =
- (snd_hda_codec_read(codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
- == ((spec->codec_type == VT1708S) ? 5 : 0));
- /* inputs */
- /* PW 1/2/5 (1ah/1bh/1eh) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x1a, &parm);
- set_pin_power_state(codec, 0x1b, &parm);
- set_pin_power_state(codec, 0x1e, &parm);
- if (imux_is_smixer)
- parm = AC_PWRST_D0;
- /* SW0 (17h), AIW 0/1 (13h/14h) */
- update_power_state(codec, 0x17, parm);
- update_power_state(codec, 0x13, parm);
- update_power_state(codec, 0x14, parm);
-
- /* outputs */
- /* PW0 (19h), SW1 (18h), AOW1 (11h) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x19, &parm);
- if (spec->smart51_enabled)
- set_pin_power_state(codec, 0x1b, &parm);
- update_power_state(codec, 0x18, parm);
- update_power_state(codec, 0x11, parm);
-
- /* PW6 (22h), SW2 (26h), AOW2 (24h) */
- if (is_8ch) {
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x22, &parm);
- if (spec->smart51_enabled)
- set_pin_power_state(codec, 0x1a, &parm);
- update_power_state(codec, 0x26, parm);
- update_power_state(codec, 0x24, parm);
- } else if (codec->vendor_id == 0x11064397) {
- /* PW7(23h), SW2(27h), AOW2(25h) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x23, &parm);
- if (spec->smart51_enabled)
- set_pin_power_state(codec, 0x1a, &parm);
- update_power_state(codec, 0x27, parm);
- update_power_state(codec, 0x25, parm);
- }
-
- /* PW 3/4/7 (1ch/1dh/23h) */
- parm = AC_PWRST_D3;
- /* force to D0 for internal Speaker */
- set_pin_power_state(codec, 0x1c, &parm);
- set_pin_power_state(codec, 0x1d, &parm);
- if (is_8ch)
- set_pin_power_state(codec, 0x23, &parm);
-
- /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
- update_power_state(codec, 0x16, imux_is_smixer ? AC_PWRST_D0 : parm);
- update_power_state(codec, 0x10, parm);
- if (is_8ch) {
- update_power_state(codec, 0x25, parm);
- update_power_state(codec, 0x27, parm);
- } else if (codec->vendor_id == 0x11064397 && spec->hp_independent_mode)
- update_power_state(codec, 0x25, parm);
-}
-
-static int patch_vt1708S(struct hda_codec *codec);
-static int patch_vt1708B(struct hda_codec *codec)
-{
- struct via_spec *spec;
- int err;
-
- if (get_codec_type(codec) == VT1708BCE)
- return patch_vt1708S(codec);
-
- /* create a codec specific record */
- spec = via_new_spec(codec);
- if (spec == NULL)
- return -ENOMEM;
-
- spec->aa_mix_nid = 0x16;
-
- /* automatic parse from the BIOS config */
- err = via_parse_auto_config(codec);
- if (err < 0) {
- via_free(codec);
- return err;
- }
-
- codec->patch_ops = via_patch_ops;
-
- spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
-
- return 0;
-}
-
-/* Patch for VT1708S */
-static const struct hda_verb vt1708S_init_verbs[] = {
- /* Enable Mic Boost Volume backdoor */
- {0x1, 0xf98, 0x1},
- /* don't bybass mixer */
- {0x1, 0xf88, 0xc0},
- { }
-};
-
-/* fill out digital output widgets; one for master and one for slave outputs */
-static void fill_dig_outs(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- int i;
-
- for (i = 0; i < spec->autocfg.dig_outs; i++) {
- hda_nid_t nid;
- int conn;
-
- nid = spec->autocfg.dig_out_pins[i];
- if (!nid)
- continue;
- conn = snd_hda_get_connections(codec, nid, &nid, 1);
- if (conn < 1)
- continue;
- if (!spec->multiout.dig_out_nid)
- spec->multiout.dig_out_nid = nid;
- else {
- spec->slave_dig_outs[0] = nid;
- break; /* at most two dig outs */
- }
- }
-}
-
-static void fill_dig_in(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- hda_nid_t dig_nid;
- int i, err;
-
- if (!spec->autocfg.dig_in_pin)
- return;
-
- dig_nid = codec->start_nid;
- for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
- unsigned int wcaps = get_wcaps(codec, dig_nid);
- if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
- continue;
- if (!(wcaps & AC_WCAP_DIGITAL))
- continue;
- if (!(wcaps & AC_WCAP_CONN_LIST))
- continue;
- err = get_connection_index(codec, dig_nid,
- spec->autocfg.dig_in_pin);
- if (err >= 0) {
- spec->dig_in_nid = dig_nid;
- break;
- }
- }
-}
-
-static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin,
- int offset, int num_steps, int step_size)
-{
- snd_hda_override_amp_caps(codec, pin, HDA_INPUT,
- (offset << AC_AMPCAP_OFFSET_SHIFT) |
- (num_steps << AC_AMPCAP_NUM_STEPS_SHIFT) |
- (step_size << AC_AMPCAP_STEP_SIZE_SHIFT) |
- (0 << AC_AMPCAP_MUTE_SHIFT));
-}
-
-static int patch_vt1708S(struct hda_codec *codec)
-{
- struct via_spec *spec;
- int err;
-
- /* create a codec specific record */
- spec = via_new_spec(codec);
- if (spec == NULL)
- return -ENOMEM;
-
- spec->aa_mix_nid = 0x16;
- override_mic_boost(codec, 0x1a, 0, 3, 40);
- override_mic_boost(codec, 0x1e, 0, 3, 40);
-
- /* automatic parse from the BIOS config */
- err = via_parse_auto_config(codec);
- if (err < 0) {
- via_free(codec);
- return err;
- }
-
- spec->init_verbs[spec->num_iverbs++] = vt1708S_init_verbs;
-
- codec->patch_ops = via_patch_ops;
-
- /* correct names for VT1708BCE */
- if (get_codec_type(codec) == VT1708BCE) {
- kfree(codec->chip_name);
- codec->chip_name = kstrdup("VT1708BCE", GFP_KERNEL);
- snprintf(codec->bus->card->mixername,
- sizeof(codec->bus->card->mixername),
- "%s %s", codec->vendor_name, codec->chip_name);
- }
- /* correct names for VT1705 */
- if (codec->vendor_id == 0x11064397) {
- kfree(codec->chip_name);
- codec->chip_name = kstrdup("VT1705", GFP_KERNEL);
- snprintf(codec->bus->card->mixername,
- sizeof(codec->bus->card->mixername),
- "%s %s", codec->vendor_name, codec->chip_name);
- }
- spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
- return 0;
-}
-
-/* Patch for VT1702 */
-
-static const struct hda_verb vt1702_init_verbs[] = {
- /* mixer enable */
- {0x1, 0xF88, 0x3},
- /* GPIO 0~2 */
- {0x1, 0xF82, 0x3F},
- { }
-};
-
-static void set_widgets_power_state_vt1702(struct hda_codec *codec)
-{
- int imux_is_smixer =
- snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
- unsigned int parm;
- /* inputs */
- /* PW 1/2/5 (14h/15h/18h) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x14, &parm);
- set_pin_power_state(codec, 0x15, &parm);
- set_pin_power_state(codec, 0x18, &parm);
- if (imux_is_smixer)
- parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */
- /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
- update_power_state(codec, 0x13, parm);
- update_power_state(codec, 0x12, parm);
- update_power_state(codec, 0x1f, parm);
- update_power_state(codec, 0x20, parm);
-
- /* outputs */
- /* PW 3/4 (16h/17h) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x17, &parm);
- set_pin_power_state(codec, 0x16, &parm);
- /* MW0 (1ah), AOW 0/1 (10h/1dh) */
- update_power_state(codec, 0x1a, imux_is_smixer ? AC_PWRST_D0 : parm);
- update_power_state(codec, 0x10, parm);
- update_power_state(codec, 0x1d, parm);
-}
-
-static int patch_vt1702(struct hda_codec *codec)
-{
- struct via_spec *spec;
- int err;
-
- /* create a codec specific record */
- spec = via_new_spec(codec);
- if (spec == NULL)
- return -ENOMEM;
-
- spec->aa_mix_nid = 0x1a;
-
- /* limit AA path volume to 0 dB */
- snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT,
- (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
- (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
- (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) |
- (1 << AC_AMPCAP_MUTE_SHIFT));
-
- /* automatic parse from the BIOS config */
- err = via_parse_auto_config(codec);
- if (err < 0) {
- via_free(codec);
- return err;
- }
-
- spec->init_verbs[spec->num_iverbs++] = vt1702_init_verbs;
-
- codec->patch_ops = via_patch_ops;
-
- spec->set_widgets_power_state = set_widgets_power_state_vt1702;
- return 0;
-}
-
-/* Patch for VT1718S */
-
-static const struct hda_verb vt1718S_init_verbs[] = {
- /* Enable MW0 adjust Gain 5 */
- {0x1, 0xfb2, 0x10},
- /* Enable Boost Volume backdoor */
- {0x1, 0xf88, 0x8},
-
- { }
-};
-
-static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- int imux_is_smixer;
- unsigned int parm;
- /* MUX6 (1eh) = stereo mixer */
- imux_is_smixer =
- snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
- /* inputs */
- /* PW 5/6/7 (29h/2ah/2bh) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x29, &parm);
- set_pin_power_state(codec, 0x2a, &parm);
- set_pin_power_state(codec, 0x2b, &parm);
- if (imux_is_smixer)
- parm = AC_PWRST_D0;
- /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
- update_power_state(codec, 0x1e, parm);
- update_power_state(codec, 0x1f, parm);
- update_power_state(codec, 0x10, parm);
- update_power_state(codec, 0x11, parm);
-
- /* outputs */
- /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x27, &parm);
- update_power_state(codec, 0x1a, parm);
- update_power_state(codec, 0xb, parm);
-
- /* PW2 (26h), AOW2 (ah) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x26, &parm);
- if (spec->smart51_enabled)
- set_pin_power_state(codec, 0x2b, &parm);
- update_power_state(codec, 0xa, parm);
-
- /* PW0 (24h), AOW0 (8h) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x24, &parm);
- if (!spec->hp_independent_mode) /* check for redirected HP */
- set_pin_power_state(codec, 0x28, &parm);
- update_power_state(codec, 0x8, parm);
- /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
- update_power_state(codec, 0x21, imux_is_smixer ? AC_PWRST_D0 : parm);
-
- /* PW1 (25h), AOW1 (9h) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x25, &parm);
- if (spec->smart51_enabled)
- set_pin_power_state(codec, 0x2a, &parm);
- update_power_state(codec, 0x9, parm);
-
- if (spec->hp_independent_mode) {
- /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x28, &parm);
- update_power_state(codec, 0x1b, parm);
- update_power_state(codec, 0x34, parm);
- update_power_state(codec, 0xc, parm);
- }
-}
-
-/* Add a connection to the primary DAC from AA-mixer for some codecs
- * This isn't listed from the raw info, but the chip has a secret connection.
- */
-static int add_secret_dac_path(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- int i, nums;
- hda_nid_t conn[8];
- hda_nid_t nid;
-
- if (!spec->aa_mix_nid)
- return 0;
- nums = snd_hda_get_connections(codec, spec->aa_mix_nid, conn,
- ARRAY_SIZE(conn) - 1);
- for (i = 0; i < nums; i++) {
- if (get_wcaps_type(get_wcaps(codec, conn[i])) == AC_WID_AUD_OUT)
- return 0;
- }
-
- /* find the primary DAC and add to the connection list */
- nid = codec->start_nid;
- for (i = 0; i < codec->num_nodes; i++, nid++) {
- unsigned int caps = get_wcaps(codec, nid);
- if (get_wcaps_type(caps) == AC_WID_AUD_OUT &&
- !(caps & AC_WCAP_DIGITAL)) {
- conn[nums++] = nid;
- return snd_hda_override_conn_list(codec,
- spec->aa_mix_nid,
- nums, conn);
- }
- }
- return 0;
-}
-
-
-static int patch_vt1718S(struct hda_codec *codec)
-{
- struct via_spec *spec;
- int err;
-
- /* create a codec specific record */
- spec = via_new_spec(codec);
- if (spec == NULL)
- return -ENOMEM;
-
- spec->aa_mix_nid = 0x21;
- override_mic_boost(codec, 0x2b, 0, 3, 40);
- override_mic_boost(codec, 0x29, 0, 3, 40);
- add_secret_dac_path(codec);
-
- /* automatic parse from the BIOS config */
- err = via_parse_auto_config(codec);
- if (err < 0) {
- via_free(codec);
- return err;
- }
-
- spec->init_verbs[spec->num_iverbs++] = vt1718S_init_verbs;
-
- codec->patch_ops = via_patch_ops;
-
- spec->set_widgets_power_state = set_widgets_power_state_vt1718S;
-
- return 0;
-}
-
-/* Patch for VT1716S */
-
-static int vt1716s_dmic_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int vt1716s_dmic_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- int index = 0;
-
- index = snd_hda_codec_read(codec, 0x26, 0,
- AC_VERB_GET_CONNECT_SEL, 0);
- if (index != -1)
- *ucontrol->value.integer.value = index;
-
- return 0;
-}
-
-static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct via_spec *spec = codec->spec;
- int index = *ucontrol->value.integer.value;
-
- snd_hda_codec_write(codec, 0x26, 0,
- AC_VERB_SET_CONNECT_SEL, index);
- spec->dmic_enabled = index;
- set_widgets_power_state(codec);
- return 1;
-}
-
-static const struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
- HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Digital Mic Capture Switch",
- .subdevice = HDA_SUBDEV_NID_FLAG | 0x26,
- .count = 1,
- .info = vt1716s_dmic_info,
- .get = vt1716s_dmic_get,
- .put = vt1716s_dmic_put,
- },
- {} /* end */
-};
-
-
-/* mono-out mixer elements */
-static const struct snd_kcontrol_new vt1716S_mono_out_mixer[] = {
- HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT),
- { } /* end */
-};
-
-static const struct hda_verb vt1716S_init_verbs[] = {
- /* Enable Boost Volume backdoor */
- {0x1, 0xf8a, 0x80},
- /* don't bybass mixer */
- {0x1, 0xf88, 0xc0},
- /* Enable mono output */
- {0x1, 0xf90, 0x08},
- { }
-};
-
-static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- int imux_is_smixer;
- unsigned int parm;
- unsigned int mono_out, present;
- /* SW0 (17h) = stereo mixer */
- imux_is_smixer =
- (snd_hda_codec_read(codec, 0x17, 0,
- AC_VERB_GET_CONNECT_SEL, 0x00) == 5);
- /* inputs */
- /* PW 1/2/5 (1ah/1bh/1eh) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x1a, &parm);
- set_pin_power_state(codec, 0x1b, &parm);
- set_pin_power_state(codec, 0x1e, &parm);
- if (imux_is_smixer)
- parm = AC_PWRST_D0;
- /* SW0 (17h), AIW0(13h) */
- update_power_state(codec, 0x17, parm);
- update_power_state(codec, 0x13, parm);
-
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x1e, &parm);
- /* PW11 (22h) */
- if (spec->dmic_enabled)
- set_pin_power_state(codec, 0x22, &parm);
- else
- update_power_state(codec, 0x22, AC_PWRST_D3);
-
- /* SW2(26h), AIW1(14h) */
- update_power_state(codec, 0x26, parm);
- update_power_state(codec, 0x14, parm);
-
- /* outputs */
- /* PW0 (19h), SW1 (18h), AOW1 (11h) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x19, &parm);
- /* Smart 5.1 PW2(1bh) */
- if (spec->smart51_enabled)
- set_pin_power_state(codec, 0x1b, &parm);
- update_power_state(codec, 0x18, parm);
- update_power_state(codec, 0x11, parm);
-
- /* PW7 (23h), SW3 (27h), AOW3 (25h) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x23, &parm);
- /* Smart 5.1 PW1(1ah) */
- if (spec->smart51_enabled)
- set_pin_power_state(codec, 0x1a, &parm);
- update_power_state(codec, 0x27, parm);
-
- /* Smart 5.1 PW5(1eh) */
- if (spec->smart51_enabled)
- set_pin_power_state(codec, 0x1e, &parm);
- update_power_state(codec, 0x25, parm);
-
- /* Mono out */
- /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
- present = snd_hda_jack_detect(codec, 0x1c);
-
- if (present)
- mono_out = 0;
- else {
- present = snd_hda_jack_detect(codec, 0x1d);
- if (!spec->hp_independent_mode && present)
- mono_out = 0;
- else
- mono_out = 1;
- }
- parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
- update_power_state(codec, 0x28, parm);
- update_power_state(codec, 0x29, parm);
- update_power_state(codec, 0x2a, parm);
-
- /* PW 3/4 (1ch/1dh) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x1c, &parm);
- set_pin_power_state(codec, 0x1d, &parm);
- /* HP Independent Mode, power on AOW3 */
- if (spec->hp_independent_mode)
- update_power_state(codec, 0x25, parm);
-
- /* force to D0 for internal Speaker */
- /* MW0 (16h), AOW0 (10h) */
- update_power_state(codec, 0x16, imux_is_smixer ? AC_PWRST_D0 : parm);
- update_power_state(codec, 0x10, mono_out ? AC_PWRST_D0 : parm);
-}
-
-static int patch_vt1716S(struct hda_codec *codec)
-{
- struct via_spec *spec;
- int err;
-
- /* create a codec specific record */
- spec = via_new_spec(codec);
- if (spec == NULL)
- return -ENOMEM;
-
- spec->aa_mix_nid = 0x16;
- override_mic_boost(codec, 0x1a, 0, 3, 40);
- override_mic_boost(codec, 0x1e, 0, 3, 40);
-
- /* automatic parse from the BIOS config */
- err = via_parse_auto_config(codec);
- if (err < 0) {
- via_free(codec);
- return err;
- }
-
- spec->init_verbs[spec->num_iverbs++] = vt1716S_init_verbs;
-
- spec->mixers[spec->num_mixers] = vt1716s_dmic_mixer;
- spec->num_mixers++;
-
- spec->mixers[spec->num_mixers++] = vt1716S_mono_out_mixer;
-
- codec->patch_ops = via_patch_ops;
-
- spec->set_widgets_power_state = set_widgets_power_state_vt1716S;
- return 0;
-}
-
-/* for vt2002P */
-
-static const struct hda_verb vt2002P_init_verbs[] = {
- /* Class-D speaker related verbs */
- {0x1, 0xfe0, 0x4},
- {0x1, 0xfe9, 0x80},
- {0x1, 0xfe2, 0x22},
- /* Enable Boost Volume backdoor */
- {0x1, 0xfb9, 0x24},
- /* Enable AOW0 to MW9 */
- {0x1, 0xfb8, 0x88},
- { }
-};
-
-static const struct hda_verb vt1802_init_verbs[] = {
- /* Enable Boost Volume backdoor */
- {0x1, 0xfb9, 0x24},
- /* Enable AOW0 to MW9 */
- {0x1, 0xfb8, 0x88},
- { }
-};
-
-static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- int imux_is_smixer;
- unsigned int parm;
- unsigned int present;
- /* MUX9 (1eh) = stereo mixer */
- imux_is_smixer =
- snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
- /* inputs */
- /* PW 5/6/7 (29h/2ah/2bh) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x29, &parm);
- set_pin_power_state(codec, 0x2a, &parm);
- set_pin_power_state(codec, 0x2b, &parm);
- parm = AC_PWRST_D0;
- /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
- update_power_state(codec, 0x1e, parm);
- update_power_state(codec, 0x1f, parm);
- update_power_state(codec, 0x10, parm);
- update_power_state(codec, 0x11, parm);
-
- /* outputs */
- /* AOW0 (8h)*/
- update_power_state(codec, 0x8, parm);
-
- if (spec->codec_type == VT1802) {
- /* PW4 (28h), MW4 (18h), MUX4(38h) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x28, &parm);
- update_power_state(codec, 0x18, parm);
- update_power_state(codec, 0x38, parm);
- } else {
- /* PW4 (26h), MW4 (1ch), MUX4(37h) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x26, &parm);
- update_power_state(codec, 0x1c, parm);
- update_power_state(codec, 0x37, parm);
- }
-
- if (spec->codec_type == VT1802) {
- /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x25, &parm);
- update_power_state(codec, 0x15, parm);
- update_power_state(codec, 0x35, parm);
- } else {
- /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x25, &parm);
- update_power_state(codec, 0x19, parm);
- update_power_state(codec, 0x35, parm);
- }
-
- if (spec->hp_independent_mode)
- update_power_state(codec, 0x9, AC_PWRST_D0);
-
- /* Class-D */
- /* PW0 (24h), MW0(18h/14h), MUX0(34h) */
- present = snd_hda_jack_detect(codec, 0x25);
-
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x24, &parm);
- parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
- if (spec->codec_type == VT1802)
- update_power_state(codec, 0x14, parm);
- else
- update_power_state(codec, 0x18, parm);
- update_power_state(codec, 0x34, parm);
-
- /* Mono Out */
- present = snd_hda_jack_detect(codec, 0x26);
-
- parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
- if (spec->codec_type == VT1802) {
- /* PW15 (33h), MW8(1ch), MUX8(3ch) */
- update_power_state(codec, 0x33, parm);
- update_power_state(codec, 0x1c, parm);
- update_power_state(codec, 0x3c, parm);
- } else {
- /* PW15 (31h), MW8(17h), MUX8(3bh) */
- update_power_state(codec, 0x31, parm);
- update_power_state(codec, 0x17, parm);
- update_power_state(codec, 0x3b, parm);
- }
- /* MW9 (21h) */
- if (imux_is_smixer || !is_aa_path_mute(codec))
- update_power_state(codec, 0x21, AC_PWRST_D0);
- else
- update_power_state(codec, 0x21, AC_PWRST_D3);
-}
-
-/* patch for vt2002P */
-static int patch_vt2002P(struct hda_codec *codec)
-{
- struct via_spec *spec;
- int err;
-
- /* create a codec specific record */
- spec = via_new_spec(codec);
- if (spec == NULL)
- return -ENOMEM;
-
- spec->aa_mix_nid = 0x21;
- override_mic_boost(codec, 0x2b, 0, 3, 40);
- override_mic_boost(codec, 0x29, 0, 3, 40);
- add_secret_dac_path(codec);
-
- /* automatic parse from the BIOS config */
- err = via_parse_auto_config(codec);
- if (err < 0) {
- via_free(codec);
- return err;
- }
-
- if (spec->codec_type == VT1802)
- spec->init_verbs[spec->num_iverbs++] = vt1802_init_verbs;
- else
- spec->init_verbs[spec->num_iverbs++] = vt2002P_init_verbs;
-
- codec->patch_ops = via_patch_ops;
-
- spec->set_widgets_power_state = set_widgets_power_state_vt2002P;
- return 0;
-}
-
-/* for vt1812 */
-
-static const struct hda_verb vt1812_init_verbs[] = {
- /* Enable Boost Volume backdoor */
- {0x1, 0xfb9, 0x24},
- /* Enable AOW0 to MW9 */
- {0x1, 0xfb8, 0xa8},
- { }
-};
-
-static void set_widgets_power_state_vt1812(struct hda_codec *codec)
-{
- struct via_spec *spec = codec->spec;
- unsigned int parm;
- unsigned int present;
- /* inputs */
- /* PW 5/6/7 (29h/2ah/2bh) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x29, &parm);
- set_pin_power_state(codec, 0x2a, &parm);
- set_pin_power_state(codec, 0x2b, &parm);
- parm = AC_PWRST_D0;
- /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
- update_power_state(codec, 0x1e, parm);
- update_power_state(codec, 0x1f, parm);
- update_power_state(codec, 0x10, parm);
- update_power_state(codec, 0x11, parm);
-
- /* outputs */
- /* AOW0 (8h)*/
- update_power_state(codec, 0x8, AC_PWRST_D0);
-
- /* PW4 (28h), MW4 (18h), MUX4(38h) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x28, &parm);
- update_power_state(codec, 0x18, parm);
- update_power_state(codec, 0x38, parm);
-
- /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x25, &parm);
- update_power_state(codec, 0x15, parm);
- update_power_state(codec, 0x35, parm);
- if (spec->hp_independent_mode)
- update_power_state(codec, 0x9, AC_PWRST_D0);
-
- /* Internal Speaker */
- /* PW0 (24h), MW0(14h), MUX0(34h) */
- present = snd_hda_jack_detect(codec, 0x25);
-
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x24, &parm);
- if (present) {
- update_power_state(codec, 0x14, AC_PWRST_D3);
- update_power_state(codec, 0x34, AC_PWRST_D3);
- } else {
- update_power_state(codec, 0x14, AC_PWRST_D0);
- update_power_state(codec, 0x34, AC_PWRST_D0);
- }
-
-
- /* Mono Out */
- /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
- present = snd_hda_jack_detect(codec, 0x28);
-
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x31, &parm);
- if (present) {
- update_power_state(codec, 0x1c, AC_PWRST_D3);
- update_power_state(codec, 0x3c, AC_PWRST_D3);
- update_power_state(codec, 0x3e, AC_PWRST_D3);
- } else {
- update_power_state(codec, 0x1c, AC_PWRST_D0);
- update_power_state(codec, 0x3c, AC_PWRST_D0);
- update_power_state(codec, 0x3e, AC_PWRST_D0);
- }
-
- /* PW15 (33h), MW15 (1dh), MUX15(3dh) */
- parm = AC_PWRST_D3;
- set_pin_power_state(codec, 0x33, &parm);
- update_power_state(codec, 0x1d, parm);
- update_power_state(codec, 0x3d, parm);
-
-}
-
-/* patch for vt1812 */
-static int patch_vt1812(struct hda_codec *codec)
-{
- struct via_spec *spec;
- int err;
-
- /* create a codec specific record */
- spec = via_new_spec(codec);
- if (spec == NULL)
- return -ENOMEM;
-
- spec->aa_mix_nid = 0x21;
- override_mic_boost(codec, 0x2b, 0, 3, 40);
- override_mic_boost(codec, 0x29, 0, 3, 40);
- add_secret_dac_path(codec);
-
- /* automatic parse from the BIOS config */
- err = via_parse_auto_config(codec);
- if (err < 0) {
- via_free(codec);
- return err;
- }
-
- spec->init_verbs[spec->num_iverbs++] = vt1812_init_verbs;
-
- codec->patch_ops = via_patch_ops;
-
- spec->set_widgets_power_state = set_widgets_power_state_vt1812;
- return 0;
-}
-
-/*
- * patch entries
- */
-static const struct hda_codec_preset snd_hda_preset_via[] = {
- { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708},
- { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708},
- { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
- { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708},
- { .id = 0x1106e710, .name = "VT1709 10-Ch",
- .patch = patch_vt1709},
- { .id = 0x1106e711, .name = "VT1709 10-Ch",
- .patch = patch_vt1709},
- { .id = 0x1106e712, .name = "VT1709 10-Ch",
- .patch = patch_vt1709},
- { .id = 0x1106e713, .name = "VT1709 10-Ch",
- .patch = patch_vt1709},
- { .id = 0x1106e714, .name = "VT1709 6-Ch",
- .patch = patch_vt1709},
- { .id = 0x1106e715, .name = "VT1709 6-Ch",
- .patch = patch_vt1709},
- { .id = 0x1106e716, .name = "VT1709 6-Ch",
- .patch = patch_vt1709},
- { .id = 0x1106e717, .name = "VT1709 6-Ch",
- .patch = patch_vt1709},
- { .id = 0x1106e720, .name = "VT1708B 8-Ch",
- .patch = patch_vt1708B},
- { .id = 0x1106e721, .name = "VT1708B 8-Ch",
- .patch = patch_vt1708B},
- { .id = 0x1106e722, .name = "VT1708B 8-Ch",
- .patch = patch_vt1708B},
- { .id = 0x1106e723, .name = "VT1708B 8-Ch",
- .patch = patch_vt1708B},
- { .id = 0x1106e724, .name = "VT1708B 4-Ch",
- .patch = patch_vt1708B},
- { .id = 0x1106e725, .name = "VT1708B 4-Ch",
- .patch = patch_vt1708B},
- { .id = 0x1106e726, .name = "VT1708B 4-Ch",
- .patch = patch_vt1708B},
- { .id = 0x1106e727, .name = "VT1708B 4-Ch",
- .patch = patch_vt1708B},
- { .id = 0x11060397, .name = "VT1708S",
- .patch = patch_vt1708S},
- { .id = 0x11061397, .name = "VT1708S",
- .patch = patch_vt1708S},
- { .id = 0x11062397, .name = "VT1708S",
- .patch = patch_vt1708S},
- { .id = 0x11063397, .name = "VT1708S",
- .patch = patch_vt1708S},
- { .id = 0x11064397, .name = "VT1705",
- .patch = patch_vt1708S},
- { .id = 0x11065397, .name = "VT1708S",
- .patch = patch_vt1708S},
- { .id = 0x11066397, .name = "VT1708S",
- .patch = patch_vt1708S},
- { .id = 0x11067397, .name = "VT1708S",
- .patch = patch_vt1708S},
- { .id = 0x11060398, .name = "VT1702",
- .patch = patch_vt1702},
- { .id = 0x11061398, .name = "VT1702",
- .patch = patch_vt1702},
- { .id = 0x11062398, .name = "VT1702",
- .patch = patch_vt1702},
- { .id = 0x11063398, .name = "VT1702",
- .patch = patch_vt1702},
- { .id = 0x11064398, .name = "VT1702",
- .patch = patch_vt1702},
- { .id = 0x11065398, .name = "VT1702",
- .patch = patch_vt1702},
- { .id = 0x11066398, .name = "VT1702",
- .patch = patch_vt1702},
- { .id = 0x11067398, .name = "VT1702",
- .patch = patch_vt1702},
- { .id = 0x11060428, .name = "VT1718S",
- .patch = patch_vt1718S},
- { .id = 0x11064428, .name = "VT1718S",
- .patch = patch_vt1718S},
- { .id = 0x11060441, .name = "VT2020",
- .patch = patch_vt1718S},
- { .id = 0x11064441, .name = "VT1828S",
- .patch = patch_vt1718S},
- { .id = 0x11060433, .name = "VT1716S",
- .patch = patch_vt1716S},
- { .id = 0x1106a721, .name = "VT1716S",
- .patch = patch_vt1716S},
- { .id = 0x11060438, .name = "VT2002P", .patch = patch_vt2002P},
- { .id = 0x11064438, .name = "VT2002P", .patch = patch_vt2002P},
- { .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812},
- { .id = 0x11060440, .name = "VT1818S",
- .patch = patch_vt1708S},
- { .id = 0x11060446, .name = "VT1802",
- .patch = patch_vt2002P},
- { .id = 0x11068446, .name = "VT1802",
- .patch = patch_vt2002P},
- {} /* terminator */
-};
-
-MODULE_ALIAS("snd-hda-codec-id:1106*");
-
-static struct hda_codec_preset_list via_list = {
- .preset = snd_hda_preset_via,
- .owner = THIS_MODULE,
-};
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("VIA HD-audio codec");
-
-static int __init patch_via_init(void)
-{
- return snd_hda_add_codec_preset(&via_list);
-}
-
-static void __exit patch_via_exit(void)
-{
- snd_hda_delete_codec_preset(&via_list);
-}
-
-module_init(patch_via_init)
-module_exit(patch_via_exit)
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/Makefile b/ANDROID_3.4.5/sound/pci/ice1712/Makefile
deleted file mode 100644
index f7ce33f0..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-ice17xx-ak4xxx-objs := ak4xxx.o
-snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o
-snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o prodigy_hifi.o juli.o phase.o wtm.o se.o maya44.o quartet.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o snd-ice17xx-ak4xxx.o
-obj-$(CONFIG_SND_ICE1724) += snd-ice1724.o snd-ice17xx-ak4xxx.o
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/ak4xxx.c b/ANDROID_3.4.5/sound/pci/ice1712/ak4xxx.c
deleted file mode 100644
index 3981823f..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/ak4xxx.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * ALSA driver for ICEnsemble ICE1712 (Envy24)
- *
- * AK4524 / AK4528 / AK4529 / AK4355 / AK4381 interface
- *
- * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include "ice1712.h"
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("ICEnsemble ICE17xx <-> AK4xxx AD/DA chip interface");
-MODULE_LICENSE("GPL");
-
-static void snd_ice1712_akm4xxx_lock(struct snd_akm4xxx *ak, int chip)
-{
- struct snd_ice1712 *ice = ak->private_data[0];
-
- snd_ice1712_save_gpio_status(ice);
-}
-
-static void snd_ice1712_akm4xxx_unlock(struct snd_akm4xxx *ak, int chip)
-{
- struct snd_ice1712 *ice = ak->private_data[0];
-
- snd_ice1712_restore_gpio_status(ice);
-}
-
-/*
- * write AK4xxx register
- */
-static void snd_ice1712_akm4xxx_write(struct snd_akm4xxx *ak, int chip,
- unsigned char addr, unsigned char data)
-{
- unsigned int tmp;
- int idx;
- unsigned int addrdata;
- struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
- struct snd_ice1712 *ice = ak->private_data[0];
-
- if (snd_BUG_ON(chip < 0 || chip >= 4))
- return;
-
- tmp = snd_ice1712_gpio_read(ice);
- tmp |= priv->add_flags;
- tmp &= ~priv->mask_flags;
- if (priv->cs_mask == priv->cs_addr) {
- if (priv->cif) {
- tmp |= priv->cs_mask; /* start without chip select */
- } else {
- tmp &= ~priv->cs_mask; /* chip select low */
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- }
- } else {
- /* doesn't handle cf=1 yet */
- tmp &= ~priv->cs_mask;
- tmp |= priv->cs_addr;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- }
-
- /* build I2C address + data byte */
- addrdata = (priv->caddr << 6) | 0x20 | (addr & 0x1f);
- addrdata = (addrdata << 8) | data;
- for (idx = 15; idx >= 0; idx--) {
- /* drop clock */
- tmp &= ~priv->clk_mask;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- /* set data */
- if (addrdata & (1 << idx))
- tmp |= priv->data_mask;
- else
- tmp &= ~priv->data_mask;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- /* raise clock */
- tmp |= priv->clk_mask;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- }
-
- if (priv->cs_mask == priv->cs_addr) {
- if (priv->cif) {
- /* assert a cs pulse to trigger */
- tmp &= ~priv->cs_mask;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- }
- tmp |= priv->cs_mask; /* chip select high to trigger */
- } else {
- tmp &= ~priv->cs_mask;
- tmp |= priv->cs_none; /* deselect address */
- }
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
-}
-
-/*
- * initialize the struct snd_akm4xxx record with the template
- */
-int snd_ice1712_akm4xxx_init(struct snd_akm4xxx *ak, const struct snd_akm4xxx *temp,
- const struct snd_ak4xxx_private *_priv, struct snd_ice1712 *ice)
-{
- struct snd_ak4xxx_private *priv;
-
- if (_priv != NULL) {
- priv = kmalloc(sizeof(*priv), GFP_KERNEL);
- if (priv == NULL)
- return -ENOMEM;
- *priv = *_priv;
- } else {
- priv = NULL;
- }
- *ak = *temp;
- ak->card = ice->card;
- ak->private_value[0] = (unsigned long)priv;
- ak->private_data[0] = ice;
- if (ak->ops.lock == NULL)
- ak->ops.lock = snd_ice1712_akm4xxx_lock;
- if (ak->ops.unlock == NULL)
- ak->ops.unlock = snd_ice1712_akm4xxx_unlock;
- if (ak->ops.write == NULL)
- ak->ops.write = snd_ice1712_akm4xxx_write;
- snd_akm4xxx_init(ak);
- return 0;
-}
-
-void snd_ice1712_akm4xxx_free(struct snd_ice1712 *ice)
-{
- unsigned int akidx;
- if (ice->akm == NULL)
- return;
- for (akidx = 0; akidx < ice->akm_codecs; akidx++) {
- struct snd_akm4xxx *ak = &ice->akm[akidx];
- kfree((void*)ak->private_value[0]);
- }
- kfree(ice->akm);
-}
-
-/*
- * build AK4xxx controls
- */
-int snd_ice1712_akm4xxx_build_controls(struct snd_ice1712 *ice)
-{
- unsigned int akidx;
- int err;
-
- for (akidx = 0; akidx < ice->akm_codecs; akidx++) {
- struct snd_akm4xxx *ak = &ice->akm[akidx];
- err = snd_akm4xxx_build_controls(ak);
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-static int __init alsa_ice1712_akm4xxx_module_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_ice1712_akm4xxx_module_exit(void)
-{
-}
-
-module_init(alsa_ice1712_akm4xxx_module_init)
-module_exit(alsa_ice1712_akm4xxx_module_exit)
-
-EXPORT_SYMBOL(snd_ice1712_akm4xxx_init);
-EXPORT_SYMBOL(snd_ice1712_akm4xxx_free);
-EXPORT_SYMBOL(snd_ice1712_akm4xxx_build_controls);
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/amp.c b/ANDROID_3.4.5/sound/pci/ice1712/amp.c
deleted file mode 100644
index e525da26..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/amp.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * ALSA driver for ICEnsemble VT1724 (Envy24HT)
- *
- * Lowlevel functions for Advanced Micro Peripherals Ltd AUDIO2000
- *
- * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <sound/core.h>
-
-#include "ice1712.h"
-#include "envy24ht.h"
-#include "amp.h"
-
-static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
-{
- unsigned short cval;
- cval = (reg << 9) | val;
- snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff);
-}
-
-static int __devinit snd_vt1724_amp_init(struct snd_ice1712 *ice)
-{
- static const unsigned short wm_inits[] = {
- WM_ATTEN_L, 0x0000, /* 0 db */
- WM_ATTEN_R, 0x0000, /* 0 db */
- WM_DAC_CTRL, 0x0008, /* 24bit I2S */
- WM_INT_CTRL, 0x0001, /* 24bit I2S */
- };
-
- unsigned int i;
-
- /* only use basic functionality for now */
-
- /* VT1616 6ch codec connected to PSDOUT0 using packed mode */
- ice->num_total_dacs = 6;
- ice->num_total_adcs = 2;
-
- /* Chaintech AV-710 has another WM8728 codec connected to PSDOUT4
- (shared with the SPDIF output). Mixer control for this codec
- is not yet supported. */
- if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AV710) {
- for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
- wm_put(ice, wm_inits[i], wm_inits[i+1]);
- }
-
- return 0;
-}
-
-static int __devinit snd_vt1724_amp_add_controls(struct snd_ice1712 *ice)
-{
- if (ice->ac97)
- /* we use pins 39 and 41 of the VT1616 for left and right
- read outputs */
- snd_ac97_write_cache(ice->ac97, 0x5a,
- snd_ac97_read(ice->ac97, 0x5a) & ~0x8000);
- return 0;
-}
-
-
-/* entry point */
-struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = {
- {
- .subvendor = VT1724_SUBDEVICE_AV710,
- .name = "Chaintech AV-710",
- .model = "av710",
- .chip_init = snd_vt1724_amp_init,
- .build_controls = snd_vt1724_amp_add_controls,
- },
- {
- .subvendor = VT1724_SUBDEVICE_AUDIO2000,
- .name = "AMP Ltd AUDIO2000",
- .model = "amp2000",
- .chip_init = snd_vt1724_amp_init,
- .build_controls = snd_vt1724_amp_add_controls,
- },
- { } /* terminator */
-};
-
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/amp.h b/ANDROID_3.4.5/sound/pci/ice1712/amp.h
deleted file mode 100644
index bf81d30d..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/amp.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef __SOUND_AMP_H
-#define __SOUND_AMP_H
-
-/*
- * ALSA driver for VIA VT1724 (Envy24HT)
- *
- * Lowlevel functions for Advanced Micro Peripherals Ltd AUDIO2000
- *
- * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define AMP_AUDIO2000_DEVICE_DESC "{AMP Ltd,AUDIO2000},"\
- "{Chaintech,AV-710},"
-
-#if 0
-#define VT1724_SUBDEVICE_AUDIO2000 0x12142417 /* Advanced Micro Peripherals Ltd AUDIO2000 */
-#else
-#define VT1724_SUBDEVICE_AUDIO2000 0x00030003 /* a dummy ID for AMP Audio2000 */
-#endif
-#define VT1724_SUBDEVICE_AV710 0x12142417 /* AV710 - the same ID with Audio2000! */
-
-/* WM8728 on I2C for AV710 */
-#define WM_DEV 0x36
-
-#define WM_ATTEN_L 0x00
-#define WM_ATTEN_R 0x01
-#define WM_DAC_CTRL 0x02
-#define WM_INT_CTRL 0x03
-
-extern struct snd_ice1712_card_info snd_vt1724_amp_cards[];
-
-
-#endif /* __SOUND_AMP_H */
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/aureon.c b/ANDROID_3.4.5/sound/pci/ice1712/aureon.c
deleted file mode 100644
index 3e4f8c12..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/aureon.c
+++ /dev/null
@@ -1,2308 +0,0 @@
-/*
- * ALSA driver for ICEnsemble VT1724 (Envy24HT)
- *
- * Lowlevel functions for Terratec Aureon cards
- *
- * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
- * NOTES:
- *
- * - we reuse the struct snd_akm4xxx record for storing the wm8770 codec data.
- * both wm and akm codecs are pretty similar, so we can integrate
- * both controls in the future, once if wm codecs are reused in
- * many boards.
- *
- * - DAC digital volumes are not implemented in the mixer.
- * if they show better response than DAC analog volumes, we can use them
- * instead.
- *
- * Lowlevel functions for AudioTrak Prodigy 7.1 (and possibly 192) cards
- * Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
- *
- * version 0.82: Stable / not all features work yet (no communication with AC97 secondary)
- * added 64x/128x oversampling switch (should be 64x only for 96khz)
- * fixed some recording labels (still need to check the rest)
- * recording is working probably thanks to correct wm8770 initialization
- *
- * version 0.5: Initial release:
- * working: analog output, mixer, headphone amplifier switch
- * not working: prety much everything else, at least i could verify that
- * we have no digital output, no capture, pretty bad clicks and poops
- * on mixer switch and other coll stuff.
- */
-
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-
-#include <sound/core.h>
-
-#include "ice1712.h"
-#include "envy24ht.h"
-#include "aureon.h"
-#include <sound/tlv.h>
-
-/* AC97 register cache for Aureon */
-struct aureon_spec {
- unsigned short stac9744[64];
- unsigned int cs8415_mux;
- unsigned short master[2];
- unsigned short vol[8];
- unsigned char pca9554_out;
-};
-
-/* WM8770 registers */
-#define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */
-#define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */
-#define WM_DAC_DIG_ATTEN 0x09 /* DAC1-8 digital attenuation */
-#define WM_DAC_DIG_MASTER_ATTEN 0x11 /* DAC master digital attenuation */
-#define WM_PHASE_SWAP 0x12 /* DAC phase */
-#define WM_DAC_CTRL1 0x13 /* DAC control bits */
-#define WM_MUTE 0x14 /* mute controls */
-#define WM_DAC_CTRL2 0x15 /* de-emphasis and zefo-flag */
-#define WM_INT_CTRL 0x16 /* interface control */
-#define WM_MASTER 0x17 /* master clock and mode */
-#define WM_POWERDOWN 0x18 /* power-down controls */
-#define WM_ADC_GAIN 0x19 /* ADC gain L(19)/R(1a) */
-#define WM_ADC_MUX 0x1b /* input MUX */
-#define WM_OUT_MUX1 0x1c /* output MUX */
-#define WM_OUT_MUX2 0x1e /* output MUX */
-#define WM_RESET 0x1f /* software reset */
-
-/* CS8415A registers */
-#define CS8415_CTRL1 0x01
-#define CS8415_CTRL2 0x02
-#define CS8415_QSUB 0x14
-#define CS8415_RATIO 0x1E
-#define CS8415_C_BUFFER 0x20
-#define CS8415_ID 0x7F
-
-/* PCA9554 registers */
-#define PCA9554_DEV 0x40 /* I2C device address */
-#define PCA9554_IN 0x00 /* input port */
-#define PCA9554_OUT 0x01 /* output port */
-#define PCA9554_INVERT 0x02 /* input invert */
-#define PCA9554_DIR 0x03 /* port directions */
-
-/*
- * Aureon Universe additional controls using PCA9554
- */
-
-/*
- * Send data to pca9554
- */
-static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,
- unsigned char data)
-{
- unsigned int tmp;
- int i, j;
- unsigned char dev = PCA9554_DEV; /* ID 0100000, write */
- unsigned char val = 0;
-
- tmp = snd_ice1712_gpio_read(ice);
-
- snd_ice1712_gpio_set_mask(ice, ~(AUREON_SPI_MOSI|AUREON_SPI_CLK|
- AUREON_WM_RW|AUREON_WM_CS|
- AUREON_CS8415_CS));
- tmp |= AUREON_WM_RW;
- tmp |= AUREON_CS8415_CS | AUREON_WM_CS; /* disable SPI devices */
-
- tmp &= ~AUREON_SPI_MOSI;
- tmp &= ~AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(50);
-
- /*
- * send i2c stop condition and start condition
- * to obtain sane state
- */
- tmp |= AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(50);
- tmp |= AUREON_SPI_MOSI;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(100);
- tmp &= ~AUREON_SPI_MOSI;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(50);
- tmp &= ~AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(100);
- /*
- * send device address, command and value,
- * skipping ack cycles in between
- */
- for (j = 0; j < 3; j++) {
- switch (j) {
- case 0:
- val = dev;
- break;
- case 1:
- val = reg;
- break;
- case 2:
- val = data;
- break;
- }
- for (i = 7; i >= 0; i--) {
- tmp &= ~AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(40);
- if (val & (1 << i))
- tmp |= AUREON_SPI_MOSI;
- else
- tmp &= ~AUREON_SPI_MOSI;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(40);
- tmp |= AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(40);
- }
- tmp &= ~AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(40);
- tmp |= AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(40);
- tmp &= ~AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(40);
- }
- tmp &= ~AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(40);
- tmp &= ~AUREON_SPI_MOSI;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(40);
- tmp |= AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(50);
- tmp |= AUREON_SPI_MOSI;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(100);
-}
-
-static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- char *texts[3] = {"Internal Aux", "Wavetable", "Rear Line-In"};
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct aureon_spec *spec = ice->spec;
- ucontrol->value.enumerated.item[0] = spec->pca9554_out;
- return 0;
-}
-
-static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct aureon_spec *spec = ice->spec;
- unsigned char oval, nval;
- int change;
-
- nval = ucontrol->value.enumerated.item[0];
- if (nval >= 3)
- return -EINVAL;
- snd_ice1712_save_gpio_status(ice);
- oval = spec->pca9554_out;
- change = (oval != nval);
- if (change) {
- aureon_pca9554_write(ice, PCA9554_OUT, nval);
- spec->pca9554_out = nval;
- }
- snd_ice1712_restore_gpio_status(ice);
- return change;
-}
-
-
-static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
- unsigned short val)
-{
- struct aureon_spec *spec = ice->spec;
- unsigned int tmp;
-
- /* Send address to XILINX chip */
- tmp = (snd_ice1712_gpio_read(ice) & ~0xFF) | (reg & 0x7F);
- snd_ice1712_gpio_write(ice, tmp);
- udelay(10);
- tmp |= AUREON_AC97_ADDR;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(10);
- tmp &= ~AUREON_AC97_ADDR;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(10);
-
- /* Send low-order byte to XILINX chip */
- tmp &= ~AUREON_AC97_DATA_MASK;
- tmp |= val & AUREON_AC97_DATA_MASK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(10);
- tmp |= AUREON_AC97_DATA_LOW;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(10);
- tmp &= ~AUREON_AC97_DATA_LOW;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(10);
-
- /* Send high-order byte to XILINX chip */
- tmp &= ~AUREON_AC97_DATA_MASK;
- tmp |= (val >> 8) & AUREON_AC97_DATA_MASK;
-
- snd_ice1712_gpio_write(ice, tmp);
- udelay(10);
- tmp |= AUREON_AC97_DATA_HIGH;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(10);
- tmp &= ~AUREON_AC97_DATA_HIGH;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(10);
-
- /* Instruct XILINX chip to parse the data to the STAC9744 chip */
- tmp |= AUREON_AC97_COMMIT;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(10);
- tmp &= ~AUREON_AC97_COMMIT;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(10);
-
- /* Store the data in out private buffer */
- spec->stac9744[(reg & 0x7F) >> 1] = val;
-}
-
-static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short reg)
-{
- struct aureon_spec *spec = ice->spec;
- return spec->stac9744[(reg & 0x7F) >> 1];
-}
-
-/*
- * Initialize STAC9744 chip
- */
-static int aureon_ac97_init(struct snd_ice1712 *ice)
-{
- struct aureon_spec *spec = ice->spec;
- int i;
- static const unsigned short ac97_defaults[] = {
- 0x00, 0x9640,
- 0x02, 0x8000,
- 0x04, 0x8000,
- 0x06, 0x8000,
- 0x0C, 0x8008,
- 0x0E, 0x8008,
- 0x10, 0x8808,
- 0x12, 0x8808,
- 0x14, 0x8808,
- 0x16, 0x8808,
- 0x18, 0x8808,
- 0x1C, 0x8000,
- 0x26, 0x000F,
- 0x28, 0x0201,
- 0x2C, 0xBB80,
- 0x32, 0xBB80,
- 0x7C, 0x8384,
- 0x7E, 0x7644,
- (unsigned short)-1
- };
- unsigned int tmp;
-
- /* Cold reset */
- tmp = (snd_ice1712_gpio_read(ice) | AUREON_AC97_RESET) & ~AUREON_AC97_DATA_MASK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(3);
-
- tmp &= ~AUREON_AC97_RESET;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(3);
-
- tmp |= AUREON_AC97_RESET;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(3);
-
- memset(&spec->stac9744, 0, sizeof(spec->stac9744));
- for (i = 0; ac97_defaults[i] != (unsigned short)-1; i += 2)
- spec->stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
-
- /* Unmute AC'97 master volume permanently - muting is done by WM8770 */
- aureon_ac97_write(ice, AC97_MASTER, 0x0000);
-
- return 0;
-}
-
-#define AUREON_AC97_STEREO 0x80
-
-/*
- * AC'97 volume controls
- */
-static int aureon_ac97_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = kcontrol->private_value & AUREON_AC97_STEREO ? 2 : 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 31;
- return 0;
-}
-
-static int aureon_ac97_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short vol;
-
- mutex_lock(&ice->gpio_mutex);
-
- vol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
- ucontrol->value.integer.value[0] = 0x1F - (vol & 0x1F);
- if (kcontrol->private_value & AUREON_AC97_STEREO)
- ucontrol->value.integer.value[1] = 0x1F - ((vol >> 8) & 0x1F);
-
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int aureon_ac97_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short ovol, nvol;
- int change;
-
- snd_ice1712_save_gpio_status(ice);
-
- ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
- nvol = (0x1F - ucontrol->value.integer.value[0]) & 0x001F;
- if (kcontrol->private_value & AUREON_AC97_STEREO)
- nvol |= ((0x1F - ucontrol->value.integer.value[1]) << 8) & 0x1F00;
- nvol |= ovol & ~0x1F1F;
-
- change = (ovol != nvol);
- if (change)
- aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
-
- snd_ice1712_restore_gpio_status(ice);
-
- return change;
-}
-
-/*
- * AC'97 mute controls
- */
-#define aureon_ac97_mute_info snd_ctl_boolean_mono_info
-
-static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&ice->gpio_mutex);
-
- ucontrol->value.integer.value[0] = aureon_ac97_read(ice,
- kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1;
-
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int aureon_ac97_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short ovol, nvol;
- int change;
-
- snd_ice1712_save_gpio_status(ice);
-
- ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
- nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~0x8000);
-
- change = (ovol != nvol);
- if (change)
- aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
-
- snd_ice1712_restore_gpio_status(ice);
-
- return change;
-}
-
-/*
- * AC'97 mute controls
- */
-#define aureon_ac97_micboost_info snd_ctl_boolean_mono_info
-
-static int aureon_ac97_micboost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&ice->gpio_mutex);
-
- ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1;
-
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int aureon_ac97_micboost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short ovol, nvol;
- int change;
-
- snd_ice1712_save_gpio_status(ice);
-
- ovol = aureon_ac97_read(ice, AC97_MIC);
- nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x0020) | (ovol & ~0x0020);
-
- change = (ovol != nvol);
- if (change)
- aureon_ac97_write(ice, AC97_MIC, nvol);
-
- snd_ice1712_restore_gpio_status(ice);
-
- return change;
-}
-
-/*
- * write data in the SPI mode
- */
-static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits)
-{
- unsigned int tmp;
- int i;
- unsigned int mosi, clk;
-
- tmp = snd_ice1712_gpio_read(ice);
-
- if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
- ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) {
- snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS));
- mosi = PRODIGY_SPI_MOSI;
- clk = PRODIGY_SPI_CLK;
- } else {
- snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK|
- AUREON_WM_CS|AUREON_CS8415_CS));
- mosi = AUREON_SPI_MOSI;
- clk = AUREON_SPI_CLK;
-
- tmp |= AUREON_WM_RW;
- }
-
- tmp &= ~cs;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
-
- for (i = bits - 1; i >= 0; i--) {
- tmp &= ~clk;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- if (data & (1 << i))
- tmp |= mosi;
- else
- tmp &= ~mosi;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- tmp |= clk;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- }
-
- tmp &= ~clk;
- tmp |= cs;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- tmp |= clk;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
-}
-
-/*
- * Read data in SPI mode
- */
-static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs,
- unsigned int data, int bits, unsigned char *buffer, int size)
-{
- int i, j;
- unsigned int tmp;
-
- tmp = (snd_ice1712_gpio_read(ice) & ~AUREON_SPI_CLK) | AUREON_CS8415_CS|AUREON_WM_CS;
- snd_ice1712_gpio_write(ice, tmp);
- tmp &= ~cs;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
-
- for (i = bits-1; i >= 0; i--) {
- if (data & (1 << i))
- tmp |= AUREON_SPI_MOSI;
- else
- tmp &= ~AUREON_SPI_MOSI;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
-
- tmp |= AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
-
- tmp &= ~AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- }
-
- for (j = 0; j < size; j++) {
- unsigned char outdata = 0;
- for (i = 7; i >= 0; i--) {
- tmp = snd_ice1712_gpio_read(ice);
- outdata <<= 1;
- outdata |= (tmp & AUREON_SPI_MISO) ? 1 : 0;
- udelay(1);
-
- tmp |= AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
-
- tmp &= ~AUREON_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- }
- buffer[j] = outdata;
- }
-
- tmp |= cs;
- snd_ice1712_gpio_write(ice, tmp);
-}
-
-static unsigned char aureon_cs8415_get(struct snd_ice1712 *ice, int reg)
-{
- unsigned char val;
- aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
- aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, &val, 1);
- return val;
-}
-
-static void aureon_cs8415_read(struct snd_ice1712 *ice, int reg,
- unsigned char *buffer, int size)
-{
- aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
- aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, buffer, size);
-}
-
-static void aureon_cs8415_put(struct snd_ice1712 *ice, int reg,
- unsigned char val)
-{
- aureon_spi_write(ice, AUREON_CS8415_CS, 0x200000 | (reg << 8) | val, 24);
-}
-
-/*
- * get the current register value of WM codec
- */
-static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
-{
- reg <<= 1;
- return ((unsigned short)ice->akm[0].images[reg] << 8) |
- ice->akm[0].images[reg + 1];
-}
-
-/*
- * set the register value of WM codec
- */
-static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
-{
- aureon_spi_write(ice,
- ((ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
- ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) ?
- PRODIGY_WM_CS : AUREON_WM_CS),
- (reg << 9) | (val & 0x1ff), 16);
-}
-
-/*
- * set the register value of WM codec and remember it
- */
-static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
-{
- wm_put_nocache(ice, reg, val);
- reg <<= 1;
- ice->akm[0].images[reg] = val >> 8;
- ice->akm[0].images[reg + 1] = val;
-}
-
-/*
- */
-#define aureon_mono_bool_info snd_ctl_boolean_mono_info
-
-/*
- * AC'97 master playback mute controls (Mute on WM8770 chip)
- */
-#define aureon_ac97_mmute_info snd_ctl_boolean_mono_info
-
-static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&ice->gpio_mutex);
-
- ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01;
-
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short ovol, nvol;
- int change;
-
- snd_ice1712_save_gpio_status(ice);
-
- ovol = wm_get(ice, WM_OUT_MUX1);
- nvol = (ovol & ~0x02) | (ucontrol->value.integer.value[0] ? 0x02 : 0x00);
- change = (ovol != nvol);
- if (change)
- wm_put(ice, WM_OUT_MUX1, nvol);
-
- snd_ice1712_restore_gpio_status(ice);
-
- return change;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -10000, 100, 1);
-static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
-static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0);
-
-#define WM_VOL_MAX 100
-#define WM_VOL_CNT 101 /* 0dB .. -100dB */
-#define WM_VOL_MUTE 0x8000
-
-static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
-{
- unsigned char nvol;
-
- if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) {
- nvol = 0;
- } else {
- nvol = ((vol % WM_VOL_CNT) * (master % WM_VOL_CNT)) /
- WM_VOL_MAX;
- nvol += 0x1b;
- }
-
- wm_put(ice, index, nvol);
- wm_put_nocache(ice, index, 0x180 | nvol);
-}
-
-/*
- * DAC mute control
- */
-#define wm_pcm_mute_info snd_ctl_boolean_mono_info
-
-static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&ice->gpio_mutex);
- ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short nval, oval;
- int change;
-
- snd_ice1712_save_gpio_status(ice);
- oval = wm_get(ice, WM_MUTE);
- nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
- change = (oval != nval);
- if (change)
- wm_put(ice, WM_MUTE, nval);
- snd_ice1712_restore_gpio_status(ice);
-
- return change;
-}
-
-/*
- * Master volume attenuation mixer control
- */
-static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = WM_VOL_MAX;
- return 0;
-}
-
-static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct aureon_spec *spec = ice->spec;
- int i;
- for (i = 0; i < 2; i++)
- ucontrol->value.integer.value[i] =
- spec->master[i] & ~WM_VOL_MUTE;
- return 0;
-}
-
-static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct aureon_spec *spec = ice->spec;
- int ch, change = 0;
-
- snd_ice1712_save_gpio_status(ice);
- for (ch = 0; ch < 2; ch++) {
- unsigned int vol = ucontrol->value.integer.value[ch];
- if (vol > WM_VOL_MAX)
- vol = WM_VOL_MAX;
- vol |= spec->master[ch] & WM_VOL_MUTE;
- if (vol != spec->master[ch]) {
- int dac;
- spec->master[ch] = vol;
- for (dac = 0; dac < ice->num_total_dacs; dac += 2)
- wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
- spec->vol[dac + ch],
- spec->master[ch]);
- change = 1;
- }
- }
- snd_ice1712_restore_gpio_status(ice);
- return change;
-}
-
-/*
- * DAC volume attenuation mixer control
- */
-static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- int voices = kcontrol->private_value >> 8;
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = voices;
- uinfo->value.integer.min = 0; /* mute (-101dB) */
- uinfo->value.integer.max = WM_VOL_MAX; /* 0dB */
- return 0;
-}
-
-static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct aureon_spec *spec = ice->spec;
- int i, ofs, voices;
-
- voices = kcontrol->private_value >> 8;
- ofs = kcontrol->private_value & 0xff;
- for (i = 0; i < voices; i++)
- ucontrol->value.integer.value[i] =
- spec->vol[ofs+i] & ~WM_VOL_MUTE;
- return 0;
-}
-
-static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct aureon_spec *spec = ice->spec;
- int i, idx, ofs, voices;
- int change = 0;
-
- voices = kcontrol->private_value >> 8;
- ofs = kcontrol->private_value & 0xff;
- snd_ice1712_save_gpio_status(ice);
- for (i = 0; i < voices; i++) {
- unsigned int vol = ucontrol->value.integer.value[i];
- if (vol > WM_VOL_MAX)
- vol = WM_VOL_MAX;
- vol |= spec->vol[ofs+i] & WM_VOL_MUTE;
- if (vol != spec->vol[ofs+i]) {
- spec->vol[ofs+i] = vol;
- idx = WM_DAC_ATTEN + ofs + i;
- wm_set_vol(ice, idx, spec->vol[ofs + i],
- spec->master[i]);
- change = 1;
- }
- }
- snd_ice1712_restore_gpio_status(ice);
- return change;
-}
-
-/*
- * WM8770 mute control
- */
-static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = kcontrol->private_value >> 8;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct aureon_spec *spec = ice->spec;
- int voices, ofs, i;
-
- voices = kcontrol->private_value >> 8;
- ofs = kcontrol->private_value & 0xFF;
-
- for (i = 0; i < voices; i++)
- ucontrol->value.integer.value[i] =
- (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
- return 0;
-}
-
-static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct aureon_spec *spec = ice->spec;
- int change = 0, voices, ofs, i;
-
- voices = kcontrol->private_value >> 8;
- ofs = kcontrol->private_value & 0xFF;
-
- snd_ice1712_save_gpio_status(ice);
- for (i = 0; i < voices; i++) {
- int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
- if (ucontrol->value.integer.value[i] != val) {
- spec->vol[ofs + i] &= ~WM_VOL_MUTE;
- spec->vol[ofs + i] |=
- ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
- wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
- spec->master[i]);
- change = 1;
- }
- }
- snd_ice1712_restore_gpio_status(ice);
-
- return change;
-}
-
-/*
- * WM8770 master mute control
- */
-#define wm_master_mute_info snd_ctl_boolean_stereo_info
-
-static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct aureon_spec *spec = ice->spec;
-
- ucontrol->value.integer.value[0] =
- (spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
- ucontrol->value.integer.value[1] =
- (spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
- return 0;
-}
-
-static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct aureon_spec *spec = ice->spec;
- int change = 0, i;
-
- snd_ice1712_save_gpio_status(ice);
- for (i = 0; i < 2; i++) {
- int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
- if (ucontrol->value.integer.value[i] != val) {
- int dac;
- spec->master[i] &= ~WM_VOL_MUTE;
- spec->master[i] |=
- ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
- for (dac = 0; dac < ice->num_total_dacs; dac += 2)
- wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
- spec->vol[dac + i],
- spec->master[i]);
- change = 1;
- }
- }
- snd_ice1712_restore_gpio_status(ice);
-
- return change;
-}
-
-/* digital master volume */
-#define PCM_0dB 0xff
-#define PCM_RES 128 /* -64dB */
-#define PCM_MIN (PCM_0dB - PCM_RES)
-static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0; /* mute (-64dB) */
- uinfo->value.integer.max = PCM_RES; /* 0dB */
- return 0;
-}
-
-static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- mutex_lock(&ice->gpio_mutex);
- val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
- val = val > PCM_MIN ? (val - PCM_MIN) : 0;
- ucontrol->value.integer.value[0] = val;
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short ovol, nvol;
- int change = 0;
-
- nvol = ucontrol->value.integer.value[0];
- if (nvol > PCM_RES)
- return -EINVAL;
- snd_ice1712_save_gpio_status(ice);
- nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
- ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
- if (ovol != nvol) {
- wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
- wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */
- change = 1;
- }
- snd_ice1712_restore_gpio_status(ice);
- return change;
-}
-
-/*
- * ADC mute control
- */
-#define wm_adc_mute_info snd_ctl_boolean_stereo_info
-
-static int wm_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short val;
- int i;
-
- mutex_lock(&ice->gpio_mutex);
- for (i = 0; i < 2; i++) {
- val = wm_get(ice, WM_ADC_GAIN + i);
- ucontrol->value.integer.value[i] = ~val>>5 & 0x1;
- }
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int wm_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short new, old;
- int i, change = 0;
-
- snd_ice1712_save_gpio_status(ice);
- for (i = 0; i < 2; i++) {
- old = wm_get(ice, WM_ADC_GAIN + i);
- new = (~ucontrol->value.integer.value[i]<<5&0x20) | (old&~0x20);
- if (new != old) {
- wm_put(ice, WM_ADC_GAIN + i, new);
- change = 1;
- }
- }
- snd_ice1712_restore_gpio_status(ice);
-
- return change;
-}
-
-/*
- * ADC gain mixer control
- */
-static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0; /* -12dB */
- uinfo->value.integer.max = 0x1f; /* 19dB */
- return 0;
-}
-
-static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int i, idx;
- unsigned short vol;
-
- mutex_lock(&ice->gpio_mutex);
- for (i = 0; i < 2; i++) {
- idx = WM_ADC_GAIN + i;
- vol = wm_get(ice, idx) & 0x1f;
- ucontrol->value.integer.value[i] = vol;
- }
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int i, idx;
- unsigned short ovol, nvol;
- int change = 0;
-
- snd_ice1712_save_gpio_status(ice);
- for (i = 0; i < 2; i++) {
- idx = WM_ADC_GAIN + i;
- nvol = ucontrol->value.integer.value[i] & 0x1f;
- ovol = wm_get(ice, idx);
- if ((ovol & 0x1f) != nvol) {
- wm_put(ice, idx, nvol | (ovol & ~0x1f));
- change = 1;
- }
- }
- snd_ice1712_restore_gpio_status(ice);
- return change;
-}
-
-/*
- * ADC input mux mixer control
- */
-static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static const char * const texts[] = {
- "CD", /* AIN1 */
- "Aux", /* AIN2 */
- "Line", /* AIN3 */
- "Mic", /* AIN4 */
- "AC97" /* AIN5 */
- };
- static const char * const universe_texts[] = {
- "Aux1", /* AIN1 */
- "CD", /* AIN2 */
- "Phono", /* AIN3 */
- "Line", /* AIN4 */
- "Aux2", /* AIN5 */
- "Mic", /* AIN6 */
- "Aux3", /* AIN7 */
- "AC97" /* AIN8 */
- };
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 2;
- if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
- uinfo->value.enumerated.items = 8;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, universe_texts[uinfo->value.enumerated.item]);
- } else {
- uinfo->value.enumerated.items = 5;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- }
- return 0;
-}
-
-static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- mutex_lock(&ice->gpio_mutex);
- val = wm_get(ice, WM_ADC_MUX);
- ucontrol->value.enumerated.item[0] = val & 7;
- ucontrol->value.enumerated.item[1] = (val >> 4) & 7;
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short oval, nval;
- int change;
-
- snd_ice1712_save_gpio_status(ice);
- oval = wm_get(ice, WM_ADC_MUX);
- nval = oval & ~0x77;
- nval |= ucontrol->value.enumerated.item[0] & 7;
- nval |= (ucontrol->value.enumerated.item[1] & 7) << 4;
- change = (oval != nval);
- if (change)
- wm_put(ice, WM_ADC_MUX, nval);
- snd_ice1712_restore_gpio_status(ice);
- return change;
-}
-
-/*
- * CS8415 Input mux
- */
-static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- static const char * const aureon_texts[] = {
- "CD", /* RXP0 */
- "Optical" /* RXP1 */
- };
- static const char * const prodigy_texts[] = {
- "CD",
- "Coax"
- };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
- strcpy(uinfo->value.enumerated.name, prodigy_texts[uinfo->value.enumerated.item]);
- else
- strcpy(uinfo->value.enumerated.name, aureon_texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct aureon_spec *spec = ice->spec;
-
- /* snd_ice1712_save_gpio_status(ice); */
- /* val = aureon_cs8415_get(ice, CS8415_CTRL2); */
- ucontrol->value.enumerated.item[0] = spec->cs8415_mux;
- /* snd_ice1712_restore_gpio_status(ice); */
- return 0;
-}
-
-static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct aureon_spec *spec = ice->spec;
- unsigned short oval, nval;
- int change;
-
- snd_ice1712_save_gpio_status(ice);
- oval = aureon_cs8415_get(ice, CS8415_CTRL2);
- nval = oval & ~0x07;
- nval |= ucontrol->value.enumerated.item[0] & 7;
- change = (oval != nval);
- if (change)
- aureon_cs8415_put(ice, CS8415_CTRL2, nval);
- snd_ice1712_restore_gpio_status(ice);
- spec->cs8415_mux = ucontrol->value.enumerated.item[0];
- return change;
-}
-
-static int aureon_cs8415_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 192000;
- return 0;
-}
-
-static int aureon_cs8415_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char ratio;
- ratio = aureon_cs8415_get(ice, CS8415_RATIO);
- ucontrol->value.integer.value[0] = (int)((unsigned int)ratio * 750);
- return 0;
-}
-
-/*
- * CS8415A Mute
- */
-#define aureon_cs8415_mute_info snd_ctl_boolean_mono_info
-
-static int aureon_cs8415_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- snd_ice1712_save_gpio_status(ice);
- ucontrol->value.integer.value[0] = (aureon_cs8415_get(ice, CS8415_CTRL1) & 0x20) ? 0 : 1;
- snd_ice1712_restore_gpio_status(ice);
- return 0;
-}
-
-static int aureon_cs8415_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char oval, nval;
- int change;
- snd_ice1712_save_gpio_status(ice);
- oval = aureon_cs8415_get(ice, CS8415_CTRL1);
- if (ucontrol->value.integer.value[0])
- nval = oval & ~0x20;
- else
- nval = oval | 0x20;
- change = (oval != nval);
- if (change)
- aureon_cs8415_put(ice, CS8415_CTRL1, nval);
- snd_ice1712_restore_gpio_status(ice);
- return change;
-}
-
-/*
- * CS8415A Q-Sub info
- */
-static int aureon_cs8415_qsub_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
- uinfo->count = 10;
- return 0;
-}
-
-static int aureon_cs8415_qsub_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- snd_ice1712_save_gpio_status(ice);
- aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10);
- snd_ice1712_restore_gpio_status(ice);
-
- return 0;
-}
-
-static int aureon_cs8415_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int aureon_cs8415_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- memset(ucontrol->value.iec958.status, 0xFF, 24);
- return 0;
-}
-
-static int aureon_cs8415_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- snd_ice1712_save_gpio_status(ice);
- aureon_cs8415_read(ice, CS8415_C_BUFFER, ucontrol->value.iec958.status, 24);
- snd_ice1712_restore_gpio_status(ice);
- return 0;
-}
-
-/*
- * Headphone Amplifier
- */
-static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable)
-{
- unsigned int tmp, tmp2;
-
- tmp2 = tmp = snd_ice1712_gpio_read(ice);
- if (enable)
- if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
- ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
- tmp |= AUREON_HP_SEL;
- else
- tmp |= PRODIGY_HP_SEL;
- else
- if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
- ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
- tmp &= ~AUREON_HP_SEL;
- else
- tmp &= ~PRODIGY_HP_SEL;
- if (tmp != tmp2) {
- snd_ice1712_gpio_write(ice, tmp);
- return 1;
- }
- return 0;
-}
-
-static int aureon_get_headphone_amp(struct snd_ice1712 *ice)
-{
- unsigned int tmp = snd_ice1712_gpio_read(ice);
-
- return (tmp & AUREON_HP_SEL) != 0;
-}
-
-#define aureon_hpamp_info snd_ctl_boolean_mono_info
-
-static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
- return 0;
-}
-
-
-static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- return aureon_set_headphone_amp(ice, ucontrol->value.integer.value[0]);
-}
-
-/*
- * Deemphasis
- */
-
-#define aureon_deemp_info snd_ctl_boolean_mono_info
-
-static int aureon_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
- return 0;
-}
-
-static int aureon_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int temp, temp2;
- temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
- if (ucontrol->value.integer.value[0])
- temp |= 0xf;
- else
- temp &= ~0xf;
- if (temp != temp2) {
- wm_put(ice, WM_DAC_CTRL2, temp);
- return 1;
- }
- return 0;
-}
-
-/*
- * ADC Oversampling
- */
-static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
-{
- static const char * const texts[2] = { "128x", "64x" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
- return 0;
-}
-
-static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- int temp, temp2;
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- temp2 = temp = wm_get(ice, WM_MASTER);
-
- if (ucontrol->value.enumerated.item[0])
- temp |= 0x8;
- else
- temp &= ~0x8;
-
- if (temp != temp2) {
- wm_put(ice, WM_MASTER, temp);
- return 1;
- }
- return 0;
-}
-
-/*
- * mixers
- */
-
-static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = wm_master_mute_info,
- .get = wm_master_mute_get,
- .put = wm_master_mute_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Master Playback Volume",
- .info = wm_master_vol_info,
- .get = wm_master_vol_get,
- .put = wm_master_vol_put,
- .tlv = { .p = db_scale_wm_dac }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Front Playback Switch",
- .info = wm_mute_info,
- .get = wm_mute_get,
- .put = wm_mute_put,
- .private_value = (2 << 8) | 0
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Front Playback Volume",
- .info = wm_vol_info,
- .get = wm_vol_get,
- .put = wm_vol_put,
- .private_value = (2 << 8) | 0,
- .tlv = { .p = db_scale_wm_dac }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Rear Playback Switch",
- .info = wm_mute_info,
- .get = wm_mute_get,
- .put = wm_mute_put,
- .private_value = (2 << 8) | 2
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Rear Playback Volume",
- .info = wm_vol_info,
- .get = wm_vol_get,
- .put = wm_vol_put,
- .private_value = (2 << 8) | 2,
- .tlv = { .p = db_scale_wm_dac }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Center Playback Switch",
- .info = wm_mute_info,
- .get = wm_mute_get,
- .put = wm_mute_put,
- .private_value = (1 << 8) | 4
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Center Playback Volume",
- .info = wm_vol_info,
- .get = wm_vol_get,
- .put = wm_vol_put,
- .private_value = (1 << 8) | 4,
- .tlv = { .p = db_scale_wm_dac }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "LFE Playback Switch",
- .info = wm_mute_info,
- .get = wm_mute_get,
- .put = wm_mute_put,
- .private_value = (1 << 8) | 5
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "LFE Playback Volume",
- .info = wm_vol_info,
- .get = wm_vol_get,
- .put = wm_vol_put,
- .private_value = (1 << 8) | 5,
- .tlv = { .p = db_scale_wm_dac }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Side Playback Switch",
- .info = wm_mute_info,
- .get = wm_mute_get,
- .put = wm_mute_put,
- .private_value = (2 << 8) | 6
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Side Playback Volume",
- .info = wm_vol_info,
- .get = wm_vol_get,
- .put = wm_vol_put,
- .private_value = (2 << 8) | 6,
- .tlv = { .p = db_scale_wm_dac }
- }
-};
-
-static struct snd_kcontrol_new wm_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Playback Switch",
- .info = wm_pcm_mute_info,
- .get = wm_pcm_mute_get,
- .put = wm_pcm_mute_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "PCM Playback Volume",
- .info = wm_pcm_vol_info,
- .get = wm_pcm_vol_get,
- .put = wm_pcm_vol_put,
- .tlv = { .p = db_scale_wm_pcm }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Switch",
- .info = wm_adc_mute_info,
- .get = wm_adc_mute_get,
- .put = wm_adc_mute_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Capture Volume",
- .info = wm_adc_vol_info,
- .get = wm_adc_vol_get,
- .put = wm_adc_vol_put,
- .tlv = { .p = db_scale_wm_adc }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = wm_adc_mux_info,
- .get = wm_adc_mux_get,
- .put = wm_adc_mux_put,
- .private_value = 5
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "External Amplifier",
- .info = aureon_hpamp_info,
- .get = aureon_hpamp_get,
- .put = aureon_hpamp_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "DAC Deemphasis Switch",
- .info = aureon_deemp_info,
- .get = aureon_deemp_get,
- .put = aureon_deemp_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "ADC Oversampling",
- .info = aureon_oversampling_info,
- .get = aureon_oversampling_get,
- .put = aureon_oversampling_put
- }
-};
-
-static struct snd_kcontrol_new ac97_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "AC97 Playback Switch",
- .info = aureon_ac97_mmute_info,
- .get = aureon_ac97_mmute_get,
- .put = aureon_ac97_mmute_put,
- .private_value = AC97_MASTER
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "AC97 Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_MASTER|AUREON_AC97_STEREO,
- .tlv = { .p = db_scale_ac97_master }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "CD Playback Switch",
- .info = aureon_ac97_mute_info,
- .get = aureon_ac97_mute_get,
- .put = aureon_ac97_mute_put,
- .private_value = AC97_CD
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "CD Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_CD|AUREON_AC97_STEREO,
- .tlv = { .p = db_scale_ac97_gain }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Aux Playback Switch",
- .info = aureon_ac97_mute_info,
- .get = aureon_ac97_mute_get,
- .put = aureon_ac97_mute_put,
- .private_value = AC97_AUX,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Aux Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_AUX|AUREON_AC97_STEREO,
- .tlv = { .p = db_scale_ac97_gain }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Line Playback Switch",
- .info = aureon_ac97_mute_info,
- .get = aureon_ac97_mute_get,
- .put = aureon_ac97_mute_put,
- .private_value = AC97_LINE
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Line Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_LINE|AUREON_AC97_STEREO,
- .tlv = { .p = db_scale_ac97_gain }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Mic Playback Switch",
- .info = aureon_ac97_mute_info,
- .get = aureon_ac97_mute_get,
- .put = aureon_ac97_mute_put,
- .private_value = AC97_MIC
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Mic Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_MIC,
- .tlv = { .p = db_scale_ac97_gain }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Mic Boost (+20dB)",
- .info = aureon_ac97_micboost_info,
- .get = aureon_ac97_micboost_get,
- .put = aureon_ac97_micboost_put
- }
-};
-
-static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "AC97 Playback Switch",
- .info = aureon_ac97_mmute_info,
- .get = aureon_ac97_mmute_get,
- .put = aureon_ac97_mmute_put,
- .private_value = AC97_MASTER
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "AC97 Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_MASTER|AUREON_AC97_STEREO,
- .tlv = { .p = db_scale_ac97_master }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "CD Playback Switch",
- .info = aureon_ac97_mute_info,
- .get = aureon_ac97_mute_get,
- .put = aureon_ac97_mute_put,
- .private_value = AC97_AUX
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "CD Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_AUX|AUREON_AC97_STEREO,
- .tlv = { .p = db_scale_ac97_gain }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Phono Playback Switch",
- .info = aureon_ac97_mute_info,
- .get = aureon_ac97_mute_get,
- .put = aureon_ac97_mute_put,
- .private_value = AC97_CD
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Phono Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_CD|AUREON_AC97_STEREO,
- .tlv = { .p = db_scale_ac97_gain }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Line Playback Switch",
- .info = aureon_ac97_mute_info,
- .get = aureon_ac97_mute_get,
- .put = aureon_ac97_mute_put,
- .private_value = AC97_LINE
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Line Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_LINE|AUREON_AC97_STEREO,
- .tlv = { .p = db_scale_ac97_gain }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Mic Playback Switch",
- .info = aureon_ac97_mute_info,
- .get = aureon_ac97_mute_get,
- .put = aureon_ac97_mute_put,
- .private_value = AC97_MIC
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Mic Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_MIC,
- .tlv = { .p = db_scale_ac97_gain }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Mic Boost (+20dB)",
- .info = aureon_ac97_micboost_info,
- .get = aureon_ac97_micboost_get,
- .put = aureon_ac97_micboost_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Aux Playback Switch",
- .info = aureon_ac97_mute_info,
- .get = aureon_ac97_mute_get,
- .put = aureon_ac97_mute_put,
- .private_value = AC97_VIDEO,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Aux Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_VIDEO|AUREON_AC97_STEREO,
- .tlv = { .p = db_scale_ac97_gain }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Aux Source",
- .info = aureon_universe_inmux_info,
- .get = aureon_universe_inmux_get,
- .put = aureon_universe_inmux_put
- }
-
-};
-
-static struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
- .info = aureon_cs8415_mute_info,
- .get = aureon_cs8415_mute_get,
- .put = aureon_cs8415_mute_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Source",
- .info = aureon_cs8415_mux_info,
- .get = aureon_cs8415_mux_get,
- .put = aureon_cs8415_mux_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("Q-subcode ", CAPTURE, DEFAULT),
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = aureon_cs8415_qsub_info,
- .get = aureon_cs8415_qsub_get,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .info = aureon_cs8415_spdif_info,
- .get = aureon_cs8415_mask_get
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = aureon_cs8415_spdif_info,
- .get = aureon_cs8415_spdif_get
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Rate",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = aureon_cs8415_rate_info,
- .get = aureon_cs8415_rate_get
- }
-};
-
-static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
-{
- unsigned int i, counts;
- int err;
-
- counts = ARRAY_SIZE(aureon_dac_controls);
- if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
- counts -= 2; /* no side */
- for (i = 0; i < counts; i++) {
- err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice));
- if (err < 0)
- return err;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
- err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));
- if (err < 0)
- return err;
- }
-
- if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
- for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) {
- err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice));
- if (err < 0)
- return err;
- }
- } else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
- ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
- for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
- err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
- if (err < 0)
- return err;
- }
- }
-
- if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
- ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
- unsigned char id;
- snd_ice1712_save_gpio_status(ice);
- id = aureon_cs8415_get(ice, CS8415_ID);
- if (id != 0x41)
- snd_printk(KERN_INFO "No CS8415 chip. Skipping CS8415 controls.\n");
- else if ((id & 0x0F) != 0x01)
- snd_printk(KERN_INFO "Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
- else {
- for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) {
- struct snd_kcontrol *kctl;
- err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice)));
- if (err < 0)
- return err;
- if (i > 1)
- kctl->id.device = ice->pcm->device;
- }
- }
- snd_ice1712_restore_gpio_status(ice);
- }
-
- return 0;
-}
-
-/*
- * reset the chip
- */
-static int aureon_reset(struct snd_ice1712 *ice)
-{
- static const unsigned short wm_inits_aureon[] = {
- /* These come first to reduce init pop noise */
- 0x1b, 0x044, /* ADC Mux (AC'97 source) */
- 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
- 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
-
- 0x18, 0x000, /* All power-up */
-
- 0x16, 0x122, /* I2S, normal polarity, 24bit */
- 0x17, 0x022, /* 256fs, slave mode */
- 0x00, 0, /* DAC1 analog mute */
- 0x01, 0, /* DAC2 analog mute */
- 0x02, 0, /* DAC3 analog mute */
- 0x03, 0, /* DAC4 analog mute */
- 0x04, 0, /* DAC5 analog mute */
- 0x05, 0, /* DAC6 analog mute */
- 0x06, 0, /* DAC7 analog mute */
- 0x07, 0, /* DAC8 analog mute */
- 0x08, 0x100, /* master analog mute */
- 0x09, 0xff, /* DAC1 digital full */
- 0x0a, 0xff, /* DAC2 digital full */
- 0x0b, 0xff, /* DAC3 digital full */
- 0x0c, 0xff, /* DAC4 digital full */
- 0x0d, 0xff, /* DAC5 digital full */
- 0x0e, 0xff, /* DAC6 digital full */
- 0x0f, 0xff, /* DAC7 digital full */
- 0x10, 0xff, /* DAC8 digital full */
- 0x11, 0x1ff, /* master digital full */
- 0x12, 0x000, /* phase normal */
- 0x13, 0x090, /* unmute DAC L/R */
- 0x14, 0x000, /* all unmute */
- 0x15, 0x000, /* no deemphasis, no ZFLG */
- 0x19, 0x000, /* -12dB ADC/L */
- 0x1a, 0x000, /* -12dB ADC/R */
- (unsigned short)-1
- };
- static const unsigned short wm_inits_prodigy[] = {
-
- /* These come first to reduce init pop noise */
- 0x1b, 0x000, /* ADC Mux */
- 0x1c, 0x009, /* Out Mux1 */
- 0x1d, 0x009, /* Out Mux2 */
-
- 0x18, 0x000, /* All power-up */
-
- 0x16, 0x022, /* I2S, normal polarity, 24bit, high-pass on */
- 0x17, 0x006, /* 128fs, slave mode */
-
- 0x00, 0, /* DAC1 analog mute */
- 0x01, 0, /* DAC2 analog mute */
- 0x02, 0, /* DAC3 analog mute */
- 0x03, 0, /* DAC4 analog mute */
- 0x04, 0, /* DAC5 analog mute */
- 0x05, 0, /* DAC6 analog mute */
- 0x06, 0, /* DAC7 analog mute */
- 0x07, 0, /* DAC8 analog mute */
- 0x08, 0x100, /* master analog mute */
-
- 0x09, 0x7f, /* DAC1 digital full */
- 0x0a, 0x7f, /* DAC2 digital full */
- 0x0b, 0x7f, /* DAC3 digital full */
- 0x0c, 0x7f, /* DAC4 digital full */
- 0x0d, 0x7f, /* DAC5 digital full */
- 0x0e, 0x7f, /* DAC6 digital full */
- 0x0f, 0x7f, /* DAC7 digital full */
- 0x10, 0x7f, /* DAC8 digital full */
- 0x11, 0x1FF, /* master digital full */
-
- 0x12, 0x000, /* phase normal */
- 0x13, 0x090, /* unmute DAC L/R */
- 0x14, 0x000, /* all unmute */
- 0x15, 0x000, /* no deemphasis, no ZFLG */
-
- 0x19, 0x000, /* -12dB ADC/L */
- 0x1a, 0x000, /* -12dB ADC/R */
- (unsigned short)-1
-
- };
- static const unsigned short cs_inits[] = {
- 0x0441, /* RUN */
- 0x0180, /* no mute, OMCK output on RMCK pin */
- 0x0201, /* S/PDIF source on RXP1 */
- 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
- (unsigned short)-1
- };
- unsigned int tmp;
- const unsigned short *p;
- int err;
- struct aureon_spec *spec = ice->spec;
-
- err = aureon_ac97_init(ice);
- if (err != 0)
- return err;
-
- snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
-
- /* reset the wm codec as the SPI mode */
- snd_ice1712_save_gpio_status(ice);
- snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RESET|AUREON_WM_CS|AUREON_CS8415_CS|AUREON_HP_SEL));
-
- tmp = snd_ice1712_gpio_read(ice);
- tmp &= ~AUREON_WM_RESET;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- tmp |= AUREON_WM_CS | AUREON_CS8415_CS;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- tmp |= AUREON_WM_RESET;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
-
- /* initialize WM8770 codec */
- if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 ||
- ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
- ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT)
- p = wm_inits_prodigy;
- else
- p = wm_inits_aureon;
- for (; *p != (unsigned short)-1; p += 2)
- wm_put(ice, p[0], p[1]);
-
- /* initialize CS8415A codec */
- if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
- ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
- for (p = cs_inits; *p != (unsigned short)-1; p++)
- aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
- spec->cs8415_mux = 1;
-
- aureon_set_headphone_amp(ice, 1);
- }
-
- snd_ice1712_restore_gpio_status(ice);
-
- /* initialize PCA9554 pin directions & set default input */
- aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
- aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */
- return 0;
-}
-
-/*
- * suspend/resume
- */
-#ifdef CONFIG_PM
-static int aureon_resume(struct snd_ice1712 *ice)
-{
- struct aureon_spec *spec = ice->spec;
- int err, i;
-
- err = aureon_reset(ice);
- if (err != 0)
- return err;
-
- /* workaround for poking volume with alsamixer after resume:
- * just set stored volume again */
- for (i = 0; i < ice->num_total_dacs; i++)
- wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
- return 0;
-}
-#endif
-
-/*
- * initialize the chip
- */
-static int __devinit aureon_init(struct snd_ice1712 *ice)
-{
- struct aureon_spec *spec;
- int i, err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- ice->spec = spec;
-
- if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
- ice->num_total_dacs = 6;
- ice->num_total_adcs = 2;
- } else {
- /* aureon 7.1 and prodigy 7.1 */
- ice->num_total_dacs = 8;
- ice->num_total_adcs = 2;
- }
-
- /* to remember the register values of CS8415 */
- ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
- if (!ice->akm)
- return -ENOMEM;
- ice->akm_codecs = 1;
-
- err = aureon_reset(ice);
- if (err != 0)
- return err;
-
- spec->master[0] = WM_VOL_MUTE;
- spec->master[1] = WM_VOL_MUTE;
- for (i = 0; i < ice->num_total_dacs; i++) {
- spec->vol[i] = WM_VOL_MUTE;
- wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
- }
-
-#ifdef CONFIG_PM
- ice->pm_resume = aureon_resume;
- ice->pm_suspend_enabled = 1;
-#endif
-
- return 0;
-}
-
-
-/*
- * Aureon boards don't provide the EEPROM data except for the vendor IDs.
- * hence the driver needs to sets up it properly.
- */
-
-static unsigned char aureon51_eeprom[] __devinitdata = {
- [ICE_EEP2_SYSCONF] = 0x0a, /* clock 512, spdif-in/ADC, 3DACs */
- [ICE_EEP2_ACLINK] = 0x80, /* I2S */
- [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
- [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
- [ICE_EEP2_GPIO_DIR] = 0xff,
- [ICE_EEP2_GPIO_DIR1] = 0xff,
- [ICE_EEP2_GPIO_DIR2] = 0x5f,
- [ICE_EEP2_GPIO_MASK] = 0x00,
- [ICE_EEP2_GPIO_MASK1] = 0x00,
- [ICE_EEP2_GPIO_MASK2] = 0x00,
- [ICE_EEP2_GPIO_STATE] = 0x00,
- [ICE_EEP2_GPIO_STATE1] = 0x00,
- [ICE_EEP2_GPIO_STATE2] = 0x00,
-};
-
-static unsigned char aureon71_eeprom[] __devinitdata = {
- [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */
- [ICE_EEP2_ACLINK] = 0x80, /* I2S */
- [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
- [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
- [ICE_EEP2_GPIO_DIR] = 0xff,
- [ICE_EEP2_GPIO_DIR1] = 0xff,
- [ICE_EEP2_GPIO_DIR2] = 0x5f,
- [ICE_EEP2_GPIO_MASK] = 0x00,
- [ICE_EEP2_GPIO_MASK1] = 0x00,
- [ICE_EEP2_GPIO_MASK2] = 0x00,
- [ICE_EEP2_GPIO_STATE] = 0x00,
- [ICE_EEP2_GPIO_STATE1] = 0x00,
- [ICE_EEP2_GPIO_STATE2] = 0x00,
-};
-#define prodigy71_eeprom aureon71_eeprom
-
-static unsigned char aureon71_universe_eeprom[] __devinitdata = {
- [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, spdif-in/ADC,
- * 4DACs
- */
- [ICE_EEP2_ACLINK] = 0x80, /* I2S */
- [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
- [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
- [ICE_EEP2_GPIO_DIR] = 0xff,
- [ICE_EEP2_GPIO_DIR1] = 0xff,
- [ICE_EEP2_GPIO_DIR2] = 0x5f,
- [ICE_EEP2_GPIO_MASK] = 0x00,
- [ICE_EEP2_GPIO_MASK1] = 0x00,
- [ICE_EEP2_GPIO_MASK2] = 0x00,
- [ICE_EEP2_GPIO_STATE] = 0x00,
- [ICE_EEP2_GPIO_STATE1] = 0x00,
- [ICE_EEP2_GPIO_STATE2] = 0x00,
-};
-
-static unsigned char prodigy71lt_eeprom[] __devinitdata = {
- [ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */
- [ICE_EEP2_ACLINK] = 0x80, /* I2S */
- [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
- [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
- [ICE_EEP2_GPIO_DIR] = 0xff,
- [ICE_EEP2_GPIO_DIR1] = 0xff,
- [ICE_EEP2_GPIO_DIR2] = 0x5f,
- [ICE_EEP2_GPIO_MASK] = 0x00,
- [ICE_EEP2_GPIO_MASK1] = 0x00,
- [ICE_EEP2_GPIO_MASK2] = 0x00,
- [ICE_EEP2_GPIO_STATE] = 0x00,
- [ICE_EEP2_GPIO_STATE1] = 0x00,
- [ICE_EEP2_GPIO_STATE2] = 0x00,
-};
-#define prodigy71xt_eeprom prodigy71lt_eeprom
-
-/* entry point */
-struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
- {
- .subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
- .name = "Terratec Aureon 5.1-Sky",
- .model = "aureon51",
- .chip_init = aureon_init,
- .build_controls = aureon_add_controls,
- .eeprom_size = sizeof(aureon51_eeprom),
- .eeprom_data = aureon51_eeprom,
- .driver = "Aureon51",
- },
- {
- .subvendor = VT1724_SUBDEVICE_AUREON71_SPACE,
- .name = "Terratec Aureon 7.1-Space",
- .model = "aureon71",
- .chip_init = aureon_init,
- .build_controls = aureon_add_controls,
- .eeprom_size = sizeof(aureon71_eeprom),
- .eeprom_data = aureon71_eeprom,
- .driver = "Aureon71",
- },
- {
- .subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
- .name = "Terratec Aureon 7.1-Universe",
- .model = "universe",
- .chip_init = aureon_init,
- .build_controls = aureon_add_controls,
- .eeprom_size = sizeof(aureon71_universe_eeprom),
- .eeprom_data = aureon71_universe_eeprom,
- .driver = "Aureon71Univ", /* keep in 15 letters */
- },
- {
- .subvendor = VT1724_SUBDEVICE_PRODIGY71,
- .name = "Audiotrak Prodigy 7.1",
- .model = "prodigy71",
- .chip_init = aureon_init,
- .build_controls = aureon_add_controls,
- .eeprom_size = sizeof(prodigy71_eeprom),
- .eeprom_data = prodigy71_eeprom,
- .driver = "Prodigy71", /* should be identical with Aureon71 */
- },
- {
- .subvendor = VT1724_SUBDEVICE_PRODIGY71LT,
- .name = "Audiotrak Prodigy 7.1 LT",
- .model = "prodigy71lt",
- .chip_init = aureon_init,
- .build_controls = aureon_add_controls,
- .eeprom_size = sizeof(prodigy71lt_eeprom),
- .eeprom_data = prodigy71lt_eeprom,
- .driver = "Prodigy71LT",
- },
- {
- .subvendor = VT1724_SUBDEVICE_PRODIGY71XT,
- .name = "Audiotrak Prodigy 7.1 XT",
- .model = "prodigy71xt",
- .chip_init = aureon_init,
- .build_controls = aureon_add_controls,
- .eeprom_size = sizeof(prodigy71xt_eeprom),
- .eeprom_data = prodigy71xt_eeprom,
- .driver = "Prodigy71LT",
- },
- { } /* terminator */
-};
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/aureon.h b/ANDROID_3.4.5/sound/pci/ice1712/aureon.h
deleted file mode 100644
index c253b8e2..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/aureon.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef __SOUND_AUREON_H
-#define __SOUND_AUREON_H
-
-/*
- * ALSA driver for VIA VT1724 (Envy24HT)
- *
- * Lowlevel functions for Terratec Aureon cards
- *
- * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define AUREON_DEVICE_DESC "{Terratec,Aureon 5.1 Sky},"\
- "{Terratec,Aureon 7.1 Space},"\
- "{Terratec,Aureon 7.1 Universe}," \
- "{AudioTrak,Prodigy 7.1}," \
- "{AudioTrak,Prodigy 7.1 LT},"\
- "{AudioTrak,Prodigy 7.1 XT},"
-
-#define VT1724_SUBDEVICE_AUREON51_SKY 0x3b154711 /* Aureon 5.1 Sky */
-#define VT1724_SUBDEVICE_AUREON71_SPACE 0x3b154511 /* Aureon 7.1 Space */
-#define VT1724_SUBDEVICE_AUREON71_UNIVERSE 0x3b155311 /* Aureon 7.1 Universe */
-#define VT1724_SUBDEVICE_PRODIGY71 0x33495345 /* PRODIGY 7.1 */
-#define VT1724_SUBDEVICE_PRODIGY71LT 0x32315441 /* PRODIGY 7.1 LT */
-#define VT1724_SUBDEVICE_PRODIGY71XT 0x36315441 /* PRODIGY 7.1 XT*/
-
-extern struct snd_ice1712_card_info snd_vt1724_aureon_cards[];
-
-/* GPIO bits */
-#define AUREON_CS8415_CS (1 << 22)
-#define AUREON_SPI_MISO (1 << 21)
-#define AUREON_WM_RESET (1 << 20)
-#define AUREON_SPI_CLK (1 << 19)
-#define AUREON_SPI_MOSI (1 << 18)
-#define AUREON_WM_RW (1 << 17)
-#define AUREON_AC97_RESET (1 << 16)
-#define AUREON_DIGITAL_SEL1 (1 << 15)
-#define AUREON_HP_SEL (1 << 14)
-#define AUREON_WM_CS (1 << 12)
-#define AUREON_AC97_COMMIT (1 << 11)
-#define AUREON_AC97_ADDR (1 << 10)
-#define AUREON_AC97_DATA_LOW (1 << 9)
-#define AUREON_AC97_DATA_HIGH (1 << 8)
-#define AUREON_AC97_DATA_MASK 0xFF
-
-#define PRODIGY_WM_CS (1 << 8)
-#define PRODIGY_SPI_MOSI (1 << 10)
-#define PRODIGY_SPI_CLK (1 << 9)
-#define PRODIGY_HP_SEL (1 << 5)
-
-#endif /* __SOUND_AUREON_H */
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/delta.c b/ANDROID_3.4.5/sound/pci/ice1712/delta.c
deleted file mode 100644
index 20c6b079..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/delta.c
+++ /dev/null
@@ -1,881 +0,0 @@
-/*
- * ALSA driver for ICEnsemble ICE1712 (Envy24)
- *
- * Lowlevel functions for M-Audio Delta 1010, 1010E, 44, 66, 66E, Dio2496,
- * Audiophile, Digigram VX442
- *
- * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-
-#include <sound/core.h>
-#include <sound/cs8427.h>
-#include <sound/asoundef.h>
-
-#include "ice1712.h"
-#include "delta.h"
-
-#define SND_CS8403
-#include <sound/cs8403.h>
-
-
-/*
- * CS8427 via SPI mode (for Audiophile), emulated I2C
- */
-
-/* send 8 bits */
-static void ap_cs8427_write_byte(struct snd_ice1712 *ice, unsigned char data, unsigned char tmp)
-{
- int idx;
-
- for (idx = 7; idx >= 0; idx--) {
- tmp &= ~(ICE1712_DELTA_AP_DOUT|ICE1712_DELTA_AP_CCLK);
- if (data & (1 << idx))
- tmp |= ICE1712_DELTA_AP_DOUT;
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
- udelay(5);
- tmp |= ICE1712_DELTA_AP_CCLK;
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
- udelay(5);
- }
-}
-
-/* read 8 bits */
-static unsigned char ap_cs8427_read_byte(struct snd_ice1712 *ice, unsigned char tmp)
-{
- unsigned char data = 0;
- int idx;
-
- for (idx = 7; idx >= 0; idx--) {
- tmp &= ~ICE1712_DELTA_AP_CCLK;
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
- udelay(5);
- if (snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ICE1712_DELTA_AP_DIN)
- data |= 1 << idx;
- tmp |= ICE1712_DELTA_AP_CCLK;
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
- udelay(5);
- }
- return data;
-}
-
-/* assert chip select */
-static unsigned char ap_cs8427_codec_select(struct snd_ice1712 *ice)
-{
- unsigned char tmp;
- tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
- switch (ice->eeprom.subvendor) {
- case ICE1712_SUBDEVICE_DELTA1010E:
- case ICE1712_SUBDEVICE_DELTA1010LT:
- tmp &= ~ICE1712_DELTA_1010LT_CS;
- tmp |= ICE1712_DELTA_1010LT_CCLK | ICE1712_DELTA_1010LT_CS_CS8427;
- break;
- case ICE1712_SUBDEVICE_AUDIOPHILE:
- case ICE1712_SUBDEVICE_DELTA410:
- tmp |= ICE1712_DELTA_AP_CCLK | ICE1712_DELTA_AP_CS_CODEC;
- tmp &= ~ICE1712_DELTA_AP_CS_DIGITAL;
- break;
- case ICE1712_SUBDEVICE_DELTA66E:
- tmp |= ICE1712_DELTA_66E_CCLK | ICE1712_DELTA_66E_CS_CHIP_A |
- ICE1712_DELTA_66E_CS_CHIP_B;
- tmp &= ~ICE1712_DELTA_66E_CS_CS8427;
- break;
- case ICE1712_SUBDEVICE_VX442:
- tmp |= ICE1712_VX442_CCLK | ICE1712_VX442_CODEC_CHIP_A | ICE1712_VX442_CODEC_CHIP_B;
- tmp &= ~ICE1712_VX442_CS_DIGITAL;
- break;
- }
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
- udelay(5);
- return tmp;
-}
-
-/* deassert chip select */
-static void ap_cs8427_codec_deassert(struct snd_ice1712 *ice, unsigned char tmp)
-{
- switch (ice->eeprom.subvendor) {
- case ICE1712_SUBDEVICE_DELTA1010E:
- case ICE1712_SUBDEVICE_DELTA1010LT:
- tmp &= ~ICE1712_DELTA_1010LT_CS;
- tmp |= ICE1712_DELTA_1010LT_CS_NONE;
- break;
- case ICE1712_SUBDEVICE_AUDIOPHILE:
- case ICE1712_SUBDEVICE_DELTA410:
- tmp |= ICE1712_DELTA_AP_CS_DIGITAL;
- break;
- case ICE1712_SUBDEVICE_DELTA66E:
- tmp |= ICE1712_DELTA_66E_CS_CS8427;
- break;
- case ICE1712_SUBDEVICE_VX442:
- tmp |= ICE1712_VX442_CS_DIGITAL;
- break;
- }
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
-}
-
-/* sequential write */
-static int ap_cs8427_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count)
-{
- struct snd_ice1712 *ice = device->bus->private_data;
- int res = count;
- unsigned char tmp;
-
- mutex_lock(&ice->gpio_mutex);
- tmp = ap_cs8427_codec_select(ice);
- ap_cs8427_write_byte(ice, (device->addr << 1) | 0, tmp); /* address + write mode */
- while (count-- > 0)
- ap_cs8427_write_byte(ice, *bytes++, tmp);
- ap_cs8427_codec_deassert(ice, tmp);
- mutex_unlock(&ice->gpio_mutex);
- return res;
-}
-
-/* sequential read */
-static int ap_cs8427_readbytes(struct snd_i2c_device *device, unsigned char *bytes, int count)
-{
- struct snd_ice1712 *ice = device->bus->private_data;
- int res = count;
- unsigned char tmp;
-
- mutex_lock(&ice->gpio_mutex);
- tmp = ap_cs8427_codec_select(ice);
- ap_cs8427_write_byte(ice, (device->addr << 1) | 1, tmp); /* address + read mode */
- while (count-- > 0)
- *bytes++ = ap_cs8427_read_byte(ice, tmp);
- ap_cs8427_codec_deassert(ice, tmp);
- mutex_unlock(&ice->gpio_mutex);
- return res;
-}
-
-static int ap_cs8427_probeaddr(struct snd_i2c_bus *bus, unsigned short addr)
-{
- if (addr == 0x10)
- return 1;
- return -ENOENT;
-}
-
-static struct snd_i2c_ops ap_cs8427_i2c_ops = {
- .sendbytes = ap_cs8427_sendbytes,
- .readbytes = ap_cs8427_readbytes,
- .probeaddr = ap_cs8427_probeaddr,
-};
-
-/*
- */
-
-static void snd_ice1712_delta_cs8403_spdif_write(struct snd_ice1712 *ice, unsigned char bits)
-{
- unsigned char tmp, mask1, mask2;
- int idx;
- /* send byte to transmitter */
- mask1 = ICE1712_DELTA_SPDIF_OUT_STAT_CLOCK;
- mask2 = ICE1712_DELTA_SPDIF_OUT_STAT_DATA;
- mutex_lock(&ice->gpio_mutex);
- tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
- for (idx = 7; idx >= 0; idx--) {
- tmp &= ~(mask1 | mask2);
- if (bits & (1 << idx))
- tmp |= mask2;
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
- udelay(100);
- tmp |= mask1;
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
- udelay(100);
- }
- tmp &= ~mask1;
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
- mutex_unlock(&ice->gpio_mutex);
-}
-
-
-static void delta_spdif_default_get(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
-{
- snd_cs8403_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_bits);
-}
-
-static int delta_spdif_default_put(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
-{
- unsigned int val;
- int change;
-
- val = snd_cs8403_encode_spdif_bits(&ucontrol->value.iec958);
- spin_lock_irq(&ice->reg_lock);
- change = ice->spdif.cs8403_bits != val;
- ice->spdif.cs8403_bits = val;
- if (change && ice->playback_pro_substream == NULL) {
- spin_unlock_irq(&ice->reg_lock);
- snd_ice1712_delta_cs8403_spdif_write(ice, val);
- } else {
- spin_unlock_irq(&ice->reg_lock);
- }
- return change;
-}
-
-static void delta_spdif_stream_get(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
-{
- snd_cs8403_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_stream_bits);
-}
-
-static int delta_spdif_stream_put(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
-{
- unsigned int val;
- int change;
-
- val = snd_cs8403_encode_spdif_bits(&ucontrol->value.iec958);
- spin_lock_irq(&ice->reg_lock);
- change = ice->spdif.cs8403_stream_bits != val;
- ice->spdif.cs8403_stream_bits = val;
- if (change && ice->playback_pro_substream != NULL) {
- spin_unlock_irq(&ice->reg_lock);
- snd_ice1712_delta_cs8403_spdif_write(ice, val);
- } else {
- spin_unlock_irq(&ice->reg_lock);
- }
- return change;
-}
-
-
-/*
- * AK4524 on Delta 44 and 66 to choose the chip mask
- */
-static void delta_ak4524_lock(struct snd_akm4xxx *ak, int chip)
-{
- struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
- struct snd_ice1712 *ice = ak->private_data[0];
-
- snd_ice1712_save_gpio_status(ice);
- priv->cs_mask =
- priv->cs_addr = chip == 0 ? ICE1712_DELTA_CODEC_CHIP_A :
- ICE1712_DELTA_CODEC_CHIP_B;
-}
-
-/*
- * AK4524 on Delta1010LT to choose the chip address
- */
-static void delta1010lt_ak4524_lock(struct snd_akm4xxx *ak, int chip)
-{
- struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
- struct snd_ice1712 *ice = ak->private_data[0];
-
- snd_ice1712_save_gpio_status(ice);
- priv->cs_mask = ICE1712_DELTA_1010LT_CS;
- priv->cs_addr = chip << 4;
-}
-
-/*
- * AK4524 on Delta66 rev E to choose the chip address
- */
-static void delta66e_ak4524_lock(struct snd_akm4xxx *ak, int chip)
-{
- struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
- struct snd_ice1712 *ice = ak->private_data[0];
-
- snd_ice1712_save_gpio_status(ice);
- priv->cs_mask =
- priv->cs_addr = chip == 0 ? ICE1712_DELTA_66E_CS_CHIP_A :
- ICE1712_DELTA_66E_CS_CHIP_B;
-}
-
-/*
- * AK4528 on VX442 to choose the chip mask
- */
-static void vx442_ak4524_lock(struct snd_akm4xxx *ak, int chip)
-{
- struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
- struct snd_ice1712 *ice = ak->private_data[0];
-
- snd_ice1712_save_gpio_status(ice);
- priv->cs_mask =
- priv->cs_addr = chip == 0 ? ICE1712_VX442_CODEC_CHIP_A :
- ICE1712_VX442_CODEC_CHIP_B;
-}
-
-/*
- * change the DFS bit according rate for Delta1010
- */
-static void delta_1010_set_rate_val(struct snd_ice1712 *ice, unsigned int rate)
-{
- unsigned char tmp, tmp2;
-
- if (rate == 0) /* no hint - S/PDIF input is master, simply return */
- return;
-
- mutex_lock(&ice->gpio_mutex);
- tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
- tmp2 = tmp & ~ICE1712_DELTA_DFS;
- if (rate > 48000)
- tmp2 |= ICE1712_DELTA_DFS;
- if (tmp != tmp2)
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp2);
- mutex_unlock(&ice->gpio_mutex);
-}
-
-/*
- * change the rate of AK4524 on Delta 44/66, AP, 1010LT
- */
-static void delta_ak4524_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
-{
- unsigned char tmp, tmp2;
- struct snd_ice1712 *ice = ak->private_data[0];
-
- if (rate == 0) /* no hint - S/PDIF input is master, simply return */
- return;
-
- /* check before reset ak4524 to avoid unnecessary clicks */
- mutex_lock(&ice->gpio_mutex);
- tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
- mutex_unlock(&ice->gpio_mutex);
- tmp2 = tmp & ~ICE1712_DELTA_DFS;
- if (rate > 48000)
- tmp2 |= ICE1712_DELTA_DFS;
- if (tmp == tmp2)
- return;
-
- /* do it again */
- snd_akm4xxx_reset(ak, 1);
- mutex_lock(&ice->gpio_mutex);
- tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ~ICE1712_DELTA_DFS;
- if (rate > 48000)
- tmp |= ICE1712_DELTA_DFS;
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
- mutex_unlock(&ice->gpio_mutex);
- snd_akm4xxx_reset(ak, 0);
-}
-
-/*
- * change the rate of AK4524 on VX442
- */
-static void vx442_ak4524_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
-{
- unsigned char val;
-
- val = (rate > 48000) ? 0x65 : 0x60;
- if (snd_akm4xxx_get(ak, 0, 0x02) != val ||
- snd_akm4xxx_get(ak, 1, 0x02) != val) {
- snd_akm4xxx_reset(ak, 1);
- snd_akm4xxx_write(ak, 0, 0x02, val);
- snd_akm4xxx_write(ak, 1, 0x02, val);
- snd_akm4xxx_reset(ak, 0);
- }
-}
-
-
-/*
- * SPDIF ops for Delta 1010, Dio, 66
- */
-
-/* open callback */
-static void delta_open_spdif(struct snd_ice1712 *ice, struct snd_pcm_substream *substream)
-{
- ice->spdif.cs8403_stream_bits = ice->spdif.cs8403_bits;
-}
-
-/* set up */
-static void delta_setup_spdif(struct snd_ice1712 *ice, int rate)
-{
- unsigned long flags;
- unsigned int tmp;
- int change;
-
- spin_lock_irqsave(&ice->reg_lock, flags);
- tmp = ice->spdif.cs8403_stream_bits;
- if (tmp & 0x01) /* consumer */
- tmp &= (tmp & 0x01) ? ~0x06 : ~0x18;
- switch (rate) {
- case 32000: tmp |= (tmp & 0x01) ? 0x04 : 0x00; break;
- case 44100: tmp |= (tmp & 0x01) ? 0x00 : 0x10; break;
- case 48000: tmp |= (tmp & 0x01) ? 0x02 : 0x08; break;
- default: tmp |= (tmp & 0x01) ? 0x00 : 0x18; break;
- }
- change = ice->spdif.cs8403_stream_bits != tmp;
- ice->spdif.cs8403_stream_bits = tmp;
- spin_unlock_irqrestore(&ice->reg_lock, flags);
- if (change)
- snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &ice->spdif.stream_ctl->id);
- snd_ice1712_delta_cs8403_spdif_write(ice, tmp);
-}
-
-#define snd_ice1712_delta1010lt_wordclock_status_info \
- snd_ctl_boolean_mono_info
-
-static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- char reg = 0x10; /* CS8427 receiver error register */
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- if (snd_i2c_sendbytes(ice->cs8427, &reg, 1) != 1)
- snd_printk(KERN_ERR "unable to send register 0x%x byte to CS8427\n", reg);
- snd_i2c_readbytes(ice->cs8427, &reg, 1);
- ucontrol->value.integer.value[0] = (reg & CS8427_UNLOCK) ? 1 : 0;
- return 0;
-}
-
-static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata =
-{
- .access = (SNDRV_CTL_ELEM_ACCESS_READ),
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Word Clock Status",
- .info = snd_ice1712_delta1010lt_wordclock_status_info,
- .get = snd_ice1712_delta1010lt_wordclock_status_get,
-};
-
-/*
- * initialize the chips on M-Audio cards
- */
-
-static struct snd_akm4xxx akm_audiophile __devinitdata = {
- .type = SND_AK4528,
- .num_adcs = 2,
- .num_dacs = 2,
- .ops = {
- .set_rate_val = delta_ak4524_set_rate_val
- }
-};
-
-static struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = {
- .caddr = 2,
- .cif = 0,
- .data_mask = ICE1712_DELTA_AP_DOUT,
- .clk_mask = ICE1712_DELTA_AP_CCLK,
- .cs_mask = ICE1712_DELTA_AP_CS_CODEC,
- .cs_addr = ICE1712_DELTA_AP_CS_CODEC,
- .cs_none = 0,
- .add_flags = ICE1712_DELTA_AP_CS_DIGITAL,
- .mask_flags = 0,
-};
-
-static struct snd_akm4xxx akm_delta410 __devinitdata = {
- .type = SND_AK4529,
- .num_adcs = 2,
- .num_dacs = 8,
- .ops = {
- .set_rate_val = delta_ak4524_set_rate_val
- }
-};
-
-static struct snd_ak4xxx_private akm_delta410_priv __devinitdata = {
- .caddr = 0,
- .cif = 0,
- .data_mask = ICE1712_DELTA_AP_DOUT,
- .clk_mask = ICE1712_DELTA_AP_CCLK,
- .cs_mask = ICE1712_DELTA_AP_CS_CODEC,
- .cs_addr = ICE1712_DELTA_AP_CS_CODEC,
- .cs_none = 0,
- .add_flags = ICE1712_DELTA_AP_CS_DIGITAL,
- .mask_flags = 0,
-};
-
-static struct snd_akm4xxx akm_delta1010lt __devinitdata = {
- .type = SND_AK4524,
- .num_adcs = 8,
- .num_dacs = 8,
- .ops = {
- .lock = delta1010lt_ak4524_lock,
- .set_rate_val = delta_ak4524_set_rate_val
- }
-};
-
-static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
- .caddr = 2,
- .cif = 0, /* the default level of the CIF pin from AK4524 */
- .data_mask = ICE1712_DELTA_1010LT_DOUT,
- .clk_mask = ICE1712_DELTA_1010LT_CCLK,
- .cs_mask = 0,
- .cs_addr = 0, /* set later */
- .cs_none = ICE1712_DELTA_1010LT_CS_NONE,
- .add_flags = 0,
- .mask_flags = 0,
-};
-
-static struct snd_akm4xxx akm_delta66e __devinitdata = {
- .type = SND_AK4524,
- .num_adcs = 4,
- .num_dacs = 4,
- .ops = {
- .lock = delta66e_ak4524_lock,
- .set_rate_val = delta_ak4524_set_rate_val
- }
-};
-
-static struct snd_ak4xxx_private akm_delta66e_priv __devinitdata = {
- .caddr = 2,
- .cif = 0, /* the default level of the CIF pin from AK4524 */
- .data_mask = ICE1712_DELTA_66E_DOUT,
- .clk_mask = ICE1712_DELTA_66E_CCLK,
- .cs_mask = 0,
- .cs_addr = 0, /* set later */
- .cs_none = 0,
- .add_flags = 0,
- .mask_flags = 0,
-};
-
-
-static struct snd_akm4xxx akm_delta44 __devinitdata = {
- .type = SND_AK4524,
- .num_adcs = 4,
- .num_dacs = 4,
- .ops = {
- .lock = delta_ak4524_lock,
- .set_rate_val = delta_ak4524_set_rate_val
- }
-};
-
-static struct snd_ak4xxx_private akm_delta44_priv __devinitdata = {
- .caddr = 2,
- .cif = 0, /* the default level of the CIF pin from AK4524 */
- .data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA,
- .clk_mask = ICE1712_DELTA_CODEC_SERIAL_CLOCK,
- .cs_mask = 0,
- .cs_addr = 0, /* set later */
- .cs_none = 0,
- .add_flags = 0,
- .mask_flags = 0,
-};
-
-static struct snd_akm4xxx akm_vx442 __devinitdata = {
- .type = SND_AK4524,
- .num_adcs = 4,
- .num_dacs = 4,
- .ops = {
- .lock = vx442_ak4524_lock,
- .set_rate_val = vx442_ak4524_set_rate_val
- }
-};
-
-static struct snd_ak4xxx_private akm_vx442_priv __devinitdata = {
- .caddr = 2,
- .cif = 0,
- .data_mask = ICE1712_VX442_DOUT,
- .clk_mask = ICE1712_VX442_CCLK,
- .cs_mask = 0,
- .cs_addr = 0, /* set later */
- .cs_none = 0,
- .add_flags = 0,
- .mask_flags = 0,
-};
-
-static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
-{
- int err;
- struct snd_akm4xxx *ak;
- unsigned char tmp;
-
- if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DELTA1010 &&
- ice->eeprom.gpiodir == 0x7b)
- ice->eeprom.subvendor = ICE1712_SUBDEVICE_DELTA1010E;
-
- if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DELTA66 &&
- ice->eeprom.gpiodir == 0xfb)
- ice->eeprom.subvendor = ICE1712_SUBDEVICE_DELTA66E;
-
- /* determine I2C, DACs and ADCs */
- switch (ice->eeprom.subvendor) {
- case ICE1712_SUBDEVICE_AUDIOPHILE:
- ice->num_total_dacs = 2;
- ice->num_total_adcs = 2;
- break;
- case ICE1712_SUBDEVICE_DELTA410:
- ice->num_total_dacs = 8;
- ice->num_total_adcs = 2;
- break;
- case ICE1712_SUBDEVICE_DELTA44:
- case ICE1712_SUBDEVICE_DELTA66:
- ice->num_total_dacs = ice->omni ? 8 : 4;
- ice->num_total_adcs = ice->omni ? 8 : 4;
- break;
- case ICE1712_SUBDEVICE_DELTA1010:
- case ICE1712_SUBDEVICE_DELTA1010E:
- case ICE1712_SUBDEVICE_DELTA1010LT:
- case ICE1712_SUBDEVICE_MEDIASTATION:
- case ICE1712_SUBDEVICE_EDIROLDA2496:
- ice->num_total_dacs = 8;
- ice->num_total_adcs = 8;
- break;
- case ICE1712_SUBDEVICE_DELTADIO2496:
- ice->num_total_dacs = 4; /* two AK4324 codecs */
- break;
- case ICE1712_SUBDEVICE_VX442:
- case ICE1712_SUBDEVICE_DELTA66E: /* omni not suported yet */
- ice->num_total_dacs = 4;
- ice->num_total_adcs = 4;
- break;
- }
-
- /* initialize the SPI clock to high */
- tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
- tmp |= ICE1712_DELTA_AP_CCLK;
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
- udelay(5);
-
- /* initialize spdif */
- switch (ice->eeprom.subvendor) {
- case ICE1712_SUBDEVICE_AUDIOPHILE:
- case ICE1712_SUBDEVICE_DELTA410:
- case ICE1712_SUBDEVICE_DELTA1010E:
- case ICE1712_SUBDEVICE_DELTA1010LT:
- case ICE1712_SUBDEVICE_VX442:
- case ICE1712_SUBDEVICE_DELTA66E:
- if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
- snd_printk(KERN_ERR "unable to create I2C bus\n");
- return err;
- }
- ice->i2c->private_data = ice;
- ice->i2c->ops = &ap_cs8427_i2c_ops;
- if ((err = snd_ice1712_init_cs8427(ice, CS8427_BASE_ADDR)) < 0)
- return err;
- break;
- case ICE1712_SUBDEVICE_DELTA1010:
- case ICE1712_SUBDEVICE_MEDIASTATION:
- ice->gpio.set_pro_rate = delta_1010_set_rate_val;
- break;
- case ICE1712_SUBDEVICE_DELTADIO2496:
- ice->gpio.set_pro_rate = delta_1010_set_rate_val;
- /* fall thru */
- case ICE1712_SUBDEVICE_DELTA66:
- ice->spdif.ops.open = delta_open_spdif;
- ice->spdif.ops.setup_rate = delta_setup_spdif;
- ice->spdif.ops.default_get = delta_spdif_default_get;
- ice->spdif.ops.default_put = delta_spdif_default_put;
- ice->spdif.ops.stream_get = delta_spdif_stream_get;
- ice->spdif.ops.stream_put = delta_spdif_stream_put;
- /* Set spdif defaults */
- snd_ice1712_delta_cs8403_spdif_write(ice, ice->spdif.cs8403_bits);
- break;
- }
-
- /* no analog? */
- switch (ice->eeprom.subvendor) {
- case ICE1712_SUBDEVICE_DELTA1010:
- case ICE1712_SUBDEVICE_DELTA1010E:
- case ICE1712_SUBDEVICE_DELTADIO2496:
- case ICE1712_SUBDEVICE_MEDIASTATION:
- return 0;
- }
-
- /* second stage of initialization, analog parts and others */
- ak = ice->akm = kmalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
- if (! ak)
- return -ENOMEM;
- ice->akm_codecs = 1;
-
- switch (ice->eeprom.subvendor) {
- case ICE1712_SUBDEVICE_AUDIOPHILE:
- err = snd_ice1712_akm4xxx_init(ak, &akm_audiophile, &akm_audiophile_priv, ice);
- break;
- case ICE1712_SUBDEVICE_DELTA410:
- err = snd_ice1712_akm4xxx_init(ak, &akm_delta410, &akm_delta410_priv, ice);
- break;
- case ICE1712_SUBDEVICE_DELTA1010LT:
- case ICE1712_SUBDEVICE_EDIROLDA2496:
- err = snd_ice1712_akm4xxx_init(ak, &akm_delta1010lt, &akm_delta1010lt_priv, ice);
- break;
- case ICE1712_SUBDEVICE_DELTA66:
- case ICE1712_SUBDEVICE_DELTA44:
- err = snd_ice1712_akm4xxx_init(ak, &akm_delta44, &akm_delta44_priv, ice);
- break;
- case ICE1712_SUBDEVICE_VX442:
- err = snd_ice1712_akm4xxx_init(ak, &akm_vx442, &akm_vx442_priv, ice);
- break;
- case ICE1712_SUBDEVICE_DELTA66E:
- err = snd_ice1712_akm4xxx_init(ak, &akm_delta66e, &akm_delta66e_priv, ice);
- break;
- default:
- snd_BUG();
- return -EINVAL;
- }
-
- return err;
-}
-
-
-/*
- * additional controls for M-Audio cards
- */
-
-static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata =
-ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0);
-static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata =
-ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 0, 0);
-static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata =
-ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
-static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata =
-ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0);
-static struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata =
-ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
-
-
-static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice)
-{
- int err;
-
- /* 1010 and dio specific controls */
- switch (ice->eeprom.subvendor) {
- case ICE1712_SUBDEVICE_DELTA1010:
- case ICE1712_SUBDEVICE_MEDIASTATION:
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010_wordclock_select, ice));
- if (err < 0)
- return err;
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010_wordclock_status, ice));
- if (err < 0)
- return err;
- break;
- case ICE1712_SUBDEVICE_DELTADIO2496:
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_deltadio2496_spdif_in_select, ice));
- if (err < 0)
- return err;
- break;
- case ICE1712_SUBDEVICE_DELTA1010E:
- case ICE1712_SUBDEVICE_DELTA1010LT:
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010lt_wordclock_select, ice));
- if (err < 0)
- return err;
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010lt_wordclock_status, ice));
- if (err < 0)
- return err;
- break;
- }
-
- /* normal spdif controls */
- switch (ice->eeprom.subvendor) {
- case ICE1712_SUBDEVICE_DELTA1010:
- case ICE1712_SUBDEVICE_DELTADIO2496:
- case ICE1712_SUBDEVICE_DELTA66:
- case ICE1712_SUBDEVICE_MEDIASTATION:
- err = snd_ice1712_spdif_build_controls(ice);
- if (err < 0)
- return err;
- break;
- }
-
- /* spdif status in */
- switch (ice->eeprom.subvendor) {
- case ICE1712_SUBDEVICE_DELTA1010:
- case ICE1712_SUBDEVICE_DELTADIO2496:
- case ICE1712_SUBDEVICE_DELTA66:
- case ICE1712_SUBDEVICE_MEDIASTATION:
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta_spdif_in_status, ice));
- if (err < 0)
- return err;
- break;
- }
-
- /* ak4524 controls */
- switch (ice->eeprom.subvendor) {
- case ICE1712_SUBDEVICE_DELTA1010LT:
- case ICE1712_SUBDEVICE_AUDIOPHILE:
- case ICE1712_SUBDEVICE_DELTA410:
- case ICE1712_SUBDEVICE_DELTA44:
- case ICE1712_SUBDEVICE_DELTA66:
- case ICE1712_SUBDEVICE_VX442:
- case ICE1712_SUBDEVICE_DELTA66E:
- case ICE1712_SUBDEVICE_EDIROLDA2496:
- err = snd_ice1712_akm4xxx_build_controls(ice);
- if (err < 0)
- return err;
- break;
- }
-
- return 0;
-}
-
-
-/* entry point */
-struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = {
- {
- .subvendor = ICE1712_SUBDEVICE_DELTA1010,
- .name = "M Audio Delta 1010",
- .model = "delta1010",
- .chip_init = snd_ice1712_delta_init,
- .build_controls = snd_ice1712_delta_add_controls,
- },
- {
- .subvendor = ICE1712_SUBDEVICE_DELTADIO2496,
- .name = "M Audio Delta DiO 2496",
- .model = "dio2496",
- .chip_init = snd_ice1712_delta_init,
- .build_controls = snd_ice1712_delta_add_controls,
- .no_mpu401 = 1,
- },
- {
- .subvendor = ICE1712_SUBDEVICE_DELTA66,
- .name = "M Audio Delta 66",
- .model = "delta66",
- .chip_init = snd_ice1712_delta_init,
- .build_controls = snd_ice1712_delta_add_controls,
- .no_mpu401 = 1,
- },
- {
- .subvendor = ICE1712_SUBDEVICE_DELTA44,
- .name = "M Audio Delta 44",
- .model = "delta44",
- .chip_init = snd_ice1712_delta_init,
- .build_controls = snd_ice1712_delta_add_controls,
- .no_mpu401 = 1,
- },
- {
- .subvendor = ICE1712_SUBDEVICE_AUDIOPHILE,
- .name = "M Audio Audiophile 24/96",
- .model = "audiophile",
- .chip_init = snd_ice1712_delta_init,
- .build_controls = snd_ice1712_delta_add_controls,
- },
- {
- .subvendor = ICE1712_SUBDEVICE_DELTA410,
- .name = "M Audio Delta 410",
- .model = "delta410",
- .chip_init = snd_ice1712_delta_init,
- .build_controls = snd_ice1712_delta_add_controls,
- },
- {
- .subvendor = ICE1712_SUBDEVICE_DELTA1010LT,
- .name = "M Audio Delta 1010LT",
- .model = "delta1010lt",
- .chip_init = snd_ice1712_delta_init,
- .build_controls = snd_ice1712_delta_add_controls,
- },
- {
- .subvendor = ICE1712_SUBDEVICE_VX442,
- .name = "Digigram VX442",
- .model = "vx442",
- .chip_init = snd_ice1712_delta_init,
- .build_controls = snd_ice1712_delta_add_controls,
- .no_mpu401 = 1,
- },
- {
- .subvendor = ICE1712_SUBDEVICE_MEDIASTATION,
- .name = "Lionstracs Mediastation",
- .model = "mediastation",
- .chip_init = snd_ice1712_delta_init,
- .build_controls = snd_ice1712_delta_add_controls,
- },
- {
- .subvendor = ICE1712_SUBDEVICE_EDIROLDA2496,
- .name = "Edirol DA2496",
- .model = "da2496",
- .chip_init = snd_ice1712_delta_init,
- .build_controls = snd_ice1712_delta_add_controls,
- },
- { } /* terminator */
-};
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/delta.h b/ANDROID_3.4.5/sound/pci/ice1712/delta.h
deleted file mode 100644
index 11a9c3a7..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/delta.h
+++ /dev/null
@@ -1,166 +0,0 @@
-#ifndef __SOUND_DELTA_H
-#define __SOUND_DELTA_H
-
-/*
- * ALSA driver for ICEnsemble ICE1712 (Envy24)
- *
- * Lowlevel functions for M-Audio Delta 1010, 44, 66, Dio2496, Audiophile
- * Digigram VX442
- *
- * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define DELTA_DEVICE_DESC \
- "{MidiMan M Audio,Delta 1010},"\
- "{MidiMan M Audio,Delta 1010LT},"\
- "{MidiMan M Audio,Delta DiO 2496},"\
- "{MidiMan M Audio,Delta 66},"\
- "{MidiMan M Audio,Delta 44},"\
- "{MidiMan M Audio,Delta 410},"\
- "{MidiMan M Audio,Audiophile 24/96},"\
- "{Digigram,VX442},"\
- "{Lionstracs,Mediastation},"\
- "{Edirol,DA2496},"
-
-#define ICE1712_SUBDEVICE_DELTA1010 0x121430d6
-#define ICE1712_SUBDEVICE_DELTA1010E 0xff1430d6
-#define ICE1712_SUBDEVICE_DELTADIO2496 0x121431d6
-#define ICE1712_SUBDEVICE_DELTA66 0x121432d6
-#define ICE1712_SUBDEVICE_DELTA66E 0xff1432d6
-#define ICE1712_SUBDEVICE_DELTA44 0x121433d6
-#define ICE1712_SUBDEVICE_AUDIOPHILE 0x121434d6
-#define ICE1712_SUBDEVICE_DELTA410 0x121438d6
-#define ICE1712_SUBDEVICE_DELTA1010LT 0x12143bd6
-#define ICE1712_SUBDEVICE_VX442 0x12143cd6
-#define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100
-#define ICE1712_SUBDEVICE_EDIROLDA2496 0xce164010
-
-/* entry point */
-extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];
-
-
-/*
- * MidiMan M-Audio Delta GPIO definitions
- */
-
-/* MidiMan M-Audio Delta shared pins */
-#define ICE1712_DELTA_DFS 0x01 /* fast/slow sample rate mode */
- /* (>48kHz must be 1) */
-#define ICE1712_DELTA_SPDIF_IN_STAT 0x02
- /* S/PDIF input status */
- /* 0 = valid signal is present */
- /* all except Delta44 */
- /* look to CS8414 datasheet */
-#define ICE1712_DELTA_SPDIF_OUT_STAT_CLOCK 0x04
- /* S/PDIF output status clock */
- /* (writing on rising edge - 0->1) */
- /* all except Delta44 */
- /* look to CS8404A datasheet */
-#define ICE1712_DELTA_SPDIF_OUT_STAT_DATA 0x08
- /* S/PDIF output status data */
- /* all except Delta44 */
- /* look to CS8404A datasheet */
-/* MidiMan M-Audio DeltaDiO */
-/* 0x01 = DFS */
-/* 0x02 = SPDIF_IN_STAT */
-/* 0x04 = SPDIF_OUT_STAT_CLOCK */
-/* 0x08 = SPDIF_OUT_STAT_DATA */
-#define ICE1712_DELTA_SPDIF_INPUT_SELECT 0x10
- /* coaxial (0), optical (1) */
- /* S/PDIF input select*/
-
-/* MidiMan M-Audio Delta1010 */
-/* 0x01 = DFS */
-/* 0x02 = SPDIF_IN_STAT */
-/* 0x04 = SPDIF_OUT_STAT_CLOCK */
-/* 0x08 = SPDIF_OUT_STAT_DATA */
-#define ICE1712_DELTA_WORD_CLOCK_SELECT 0x10
- /* 1 - clock are taken from S/PDIF input */
- /* 0 - clock are taken from Word Clock input */
- /* affected SPMCLKIN pin of Envy24 */
-#define ICE1712_DELTA_WORD_CLOCK_STATUS 0x20
- /* 0 = valid word clock signal is present */
-
-/* MidiMan M-Audio Delta66 */
-/* 0x01 = DFS */
-/* 0x02 = SPDIF_IN_STAT */
-/* 0x04 = SPDIF_OUT_STAT_CLOCK */
-/* 0x08 = SPDIF_OUT_STAT_DATA */
-#define ICE1712_DELTA_CODEC_SERIAL_DATA 0x10
- /* AKM4524 serial data */
-#define ICE1712_DELTA_CODEC_SERIAL_CLOCK 0x20
- /* AKM4524 serial clock */
- /* (writing on rising edge - 0->1 */
-#define ICE1712_DELTA_CODEC_CHIP_A 0x40
-#define ICE1712_DELTA_CODEC_CHIP_B 0x80
- /* 1 - select chip A or B */
-
-/* MidiMan M-Audio Delta44 */
-/* 0x01 = DFS */
-/* 0x10 = CODEC_SERIAL_DATA */
-/* 0x20 = CODEC_SERIAL_CLOCK */
-/* 0x40 = CODEC_CHIP_A */
-/* 0x80 = CODEC_CHIP_B */
-
-/* MidiMan M-Audio Audiophile/Delta410 definitions */
-/* thanks to Kristof Pelckmans <Kristof.Pelckmans@antwerpen.be> for Delta410 info */
-/* 0x01 = DFS */
-#define ICE1712_DELTA_AP_CCLK 0x02 /* SPI clock */
- /* (clocking on rising edge - 0->1) */
-#define ICE1712_DELTA_AP_DIN 0x04 /* data input */
-#define ICE1712_DELTA_AP_DOUT 0x08 /* data output */
-#define ICE1712_DELTA_AP_CS_DIGITAL 0x10 /* CS8427 chip select */
- /* low signal = select */
-#define ICE1712_DELTA_AP_CS_CODEC 0x20 /* AK4528 (audiophile), AK4529 (Delta410) chip select */
- /* low signal = select */
-
-/* MidiMan M-Audio Delta1010LT definitions */
-/* thanks to Anders Johansson <ajh@watri.uwa.edu.au> */
-/* 0x01 = DFS */
-#define ICE1712_DELTA_1010LT_CCLK 0x02 /* SPI clock (AK4524 + CS8427) */
-#define ICE1712_DELTA_1010LT_DIN 0x04 /* data input (CS8427) */
-#define ICE1712_DELTA_1010LT_DOUT 0x08 /* data output (AK4524 + CS8427) */
-#define ICE1712_DELTA_1010LT_CS 0x70 /* mask for CS address */
-#define ICE1712_DELTA_1010LT_CS_CHIP_A 0x00 /* AK4524 #0 */
-#define ICE1712_DELTA_1010LT_CS_CHIP_B 0x10 /* AK4524 #1 */
-#define ICE1712_DELTA_1010LT_CS_CHIP_C 0x20 /* AK4524 #2 */
-#define ICE1712_DELTA_1010LT_CS_CHIP_D 0x30 /* AK4524 #3 */
-#define ICE1712_DELTA_1010LT_CS_CS8427 0x40 /* CS8427 */
-#define ICE1712_DELTA_1010LT_CS_NONE 0x50 /* nothing */
-#define ICE1712_DELTA_1010LT_WORDCLOCK 0x80 /* sample clock source: 0 = Word Clock Input, 1 = S/PDIF Input ??? */
-
-/* M-Audio Delta 66 rev. E definitions.
- * Newer revisions of Delta 66 have CS8427 over SPI for
- * S/PDIF transceiver instead of CS8404/CS8414. */
-/* 0x01 = DFS */
-#define ICE1712_DELTA_66E_CCLK 0x02 /* SPI clock */
-#define ICE1712_DELTA_66E_DIN 0x04 /* data input */
-#define ICE1712_DELTA_66E_DOUT 0x08 /* data output */
-#define ICE1712_DELTA_66E_CS_CS8427 0x10 /* chip select, low = CS8427 */
-#define ICE1712_DELTA_66E_CS_CHIP_A 0x20 /* AK4524 #0 */
-#define ICE1712_DELTA_66E_CS_CHIP_B 0x40 /* AK4524 #1 */
-
-/* Digigram VX442 definitions */
-#define ICE1712_VX442_CCLK 0x02 /* SPI clock */
-#define ICE1712_VX442_DIN 0x04 /* data input */
-#define ICE1712_VX442_DOUT 0x08 /* data output */
-#define ICE1712_VX442_CS_DIGITAL 0x10 /* chip select, low = CS8427 */
-#define ICE1712_VX442_CODEC_CHIP_A 0x20 /* select chip A */
-#define ICE1712_VX442_CODEC_CHIP_B 0x40 /* select chip B */
-
-#endif /* __SOUND_DELTA_H */
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/envy24ht.h b/ANDROID_3.4.5/sound/pci/ice1712/envy24ht.h
deleted file mode 100644
index 4ca33a80..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/envy24ht.h
+++ /dev/null
@@ -1,220 +0,0 @@
-#ifndef __SOUND_VT1724_H
-#define __SOUND_VT1724_H
-
-/*
- * ALSA driver for ICEnsemble VT1724 (Envy24)
- *
- * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <sound/control.h>
-#include <sound/ac97_codec.h>
-#include <sound/rawmidi.h>
-#include <sound/i2c.h>
-#include <sound/pcm.h>
-
-#include "ice1712.h"
-
-enum {
- ICE_EEP2_SYSCONF = 0, /* 06 */
- ICE_EEP2_ACLINK, /* 07 */
- ICE_EEP2_I2S, /* 08 */
- ICE_EEP2_SPDIF, /* 09 */
- ICE_EEP2_GPIO_DIR, /* 0a */
- ICE_EEP2_GPIO_DIR1, /* 0b */
- ICE_EEP2_GPIO_DIR2, /* 0c */
- ICE_EEP2_GPIO_MASK, /* 0d */
- ICE_EEP2_GPIO_MASK1, /* 0e */
- ICE_EEP2_GPIO_MASK2, /* 0f */
- ICE_EEP2_GPIO_STATE, /* 10 */
- ICE_EEP2_GPIO_STATE1, /* 11 */
- ICE_EEP2_GPIO_STATE2 /* 12 */
-};
-
-/*
- * Direct registers
- */
-
-#define ICEREG1724(ice, x) ((ice)->port + VT1724_REG_##x)
-
-#define VT1724_REG_CONTROL 0x00 /* byte */
-#define VT1724_RESET 0x80 /* reset whole chip */
-#define VT1724_REG_IRQMASK 0x01 /* byte */
-#define VT1724_IRQ_MPU_RX 0x80
-#define VT1724_IRQ_MPU_TX 0x20
-#define VT1724_IRQ_MTPCM 0x10
-#define VT1724_REG_IRQSTAT 0x02 /* byte */
-/* look to VT1724_IRQ_* */
-#define VT1724_REG_SYS_CFG 0x04 /* byte - system configuration PCI60 on Envy24*/
-#define VT1724_CFG_CLOCK 0xc0
-#define VT1724_CFG_CLOCK512 0x00 /* 22.5692Mhz, 44.1kHz*512 */
-#define VT1724_CFG_CLOCK384 0x40 /* 16.9344Mhz, 44.1kHz*384 */
-#define VT1724_CFG_MPU401 0x20 /* MPU401 UARTs */
-#define VT1724_CFG_ADC_MASK 0x0c /* one, two or one and S/PDIF, stereo ADCs */
-#define VT1724_CFG_ADC_NONE 0x0c /* no ADCs */
-#define VT1724_CFG_DAC_MASK 0x03 /* one, two, three, four stereo DACs */
-
-#define VT1724_REG_AC97_CFG 0x05 /* byte */
-#define VT1724_CFG_PRO_I2S 0x80 /* multitrack converter: I2S or AC'97 */
-#define VT1724_CFG_AC97_PACKED 0x01 /* split or packed mode - AC'97 */
-
-#define VT1724_REG_I2S_FEATURES 0x06 /* byte */
-#define VT1724_CFG_I2S_VOLUME 0x80 /* volume/mute capability */
-#define VT1724_CFG_I2S_96KHZ 0x40 /* supports 96kHz sampling */
-#define VT1724_CFG_I2S_RESMASK 0x30 /* resolution mask, 16,18,20,24-bit */
-#define VT1724_CFG_I2S_192KHZ 0x08 /* supports 192kHz sampling */
-#define VT1724_CFG_I2S_OTHER 0x07 /* other I2S IDs */
-
-#define VT1724_REG_SPDIF_CFG 0x07 /* byte */
-#define VT1724_CFG_SPDIF_OUT_EN 0x80 /*Internal S/PDIF output is enabled*/
-#define VT1724_CFG_SPDIF_OUT_INT 0x40 /*Internal S/PDIF output is implemented*/
-#define VT1724_CFG_I2S_CHIPID 0x3c /* I2S chip ID */
-#define VT1724_CFG_SPDIF_IN 0x02 /* S/PDIF input is present */
-#define VT1724_CFG_SPDIF_OUT 0x01 /* External S/PDIF output is present */
-
-/*there is no consumer AC97 codec with the VT1724*/
-//#define VT1724_REG_AC97_INDEX 0x08 /* byte */
-//#define VT1724_REG_AC97_CMD 0x09 /* byte */
-
-#define VT1724_REG_MPU_TXFIFO 0x0a /*byte ro. number of bytes in TX fifo*/
-#define VT1724_REG_MPU_RXFIFO 0x0b /*byte ro. number of bytes in RX fifo*/
-
-#define VT1724_REG_MPU_DATA 0x0c /* byte */
-#define VT1724_REG_MPU_CTRL 0x0d /* byte */
-#define VT1724_MPU_UART 0x01
-#define VT1724_MPU_TX_EMPTY 0x02
-#define VT1724_MPU_TX_FULL 0x04
-#define VT1724_MPU_RX_EMPTY 0x08
-#define VT1724_MPU_RX_FULL 0x10
-
-#define VT1724_REG_MPU_FIFO_WM 0x0e /*byte set the high/low watermarks for RX/TX fifos*/
-#define VT1724_MPU_RX_FIFO 0x20 //1=rx fifo watermark 0=tx fifo watermark
-#define VT1724_MPU_FIFO_MASK 0x1f
-
-#define VT1724_REG_I2C_DEV_ADDR 0x10 /* byte */
-#define VT1724_I2C_WRITE 0x01 /* write direction */
-#define VT1724_REG_I2C_BYTE_ADDR 0x11 /* byte */
-#define VT1724_REG_I2C_DATA 0x12 /* byte */
-#define VT1724_REG_I2C_CTRL 0x13 /* byte */
-#define VT1724_I2C_EEPROM 0x80 /* 1 = EEPROM exists */
-#define VT1724_I2C_BUSY 0x01 /* busy bit */
-
-#define VT1724_REG_GPIO_DATA 0x14 /* word */
-#define VT1724_REG_GPIO_WRITE_MASK 0x16 /* word */
-#define VT1724_REG_GPIO_DIRECTION 0x18 /* dword? (3 bytes) 0=input 1=output.
- bit3 - during reset used for Eeprom power-on strapping
- if TESTEN# pin active, bit 2 always input*/
-#define VT1724_REG_POWERDOWN 0x1c
-#define VT1724_REG_GPIO_DATA_22 0x1e /* byte direction for GPIO 16:22 */
-#define VT1724_REG_GPIO_WRITE_MASK_22 0x1f /* byte write mask for GPIO 16:22 */
-
-
-/*
- * Professional multi-track direct control registers
- */
-
-#define ICEMT1724(ice, x) ((ice)->profi_port + VT1724_MT_##x)
-
-#define VT1724_MT_IRQ 0x00 /* byte - interrupt mask */
-#define VT1724_MULTI_PDMA4 0x80 /* SPDIF Out / PDMA4 */
-#define VT1724_MULTI_PDMA3 0x40 /* PDMA3 */
-#define VT1724_MULTI_PDMA2 0x20 /* PDMA2 */
-#define VT1724_MULTI_PDMA1 0x10 /* PDMA1 */
-#define VT1724_MULTI_FIFO_ERR 0x08 /* DMA FIFO underrun/overrun. */
-#define VT1724_MULTI_RDMA1 0x04 /* RDMA1 (S/PDIF input) */
-#define VT1724_MULTI_RDMA0 0x02 /* RMDA0 */
-#define VT1724_MULTI_PDMA0 0x01 /* MC Interleave/PDMA0 */
-
-#define VT1724_MT_RATE 0x01 /* byte - sampling rate select */
-#define VT1724_SPDIF_MASTER 0x10 /* S/PDIF input is master clock */
-#define VT1724_MT_I2S_FORMAT 0x02 /* byte - I2S data format */
-#define VT1724_MT_I2S_MCLK_128X 0x08
-#define VT1724_MT_I2S_FORMAT_MASK 0x03
-#define VT1724_MT_I2S_FORMAT_I2S 0x00
-#define VT1724_MT_DMA_INT_MASK 0x03 /* byte -DMA Interrupt Mask */
-/* lool to VT1724_MULTI_* */
-#define VT1724_MT_AC97_INDEX 0x04 /* byte - AC'97 index */
-#define VT1724_MT_AC97_CMD 0x05 /* byte - AC'97 command & status */
-#define VT1724_AC97_COLD 0x80 /* cold reset */
-#define VT1724_AC97_WARM 0x40 /* warm reset */
-#define VT1724_AC97_WRITE 0x20 /* W: write, R: write in progress */
-#define VT1724_AC97_READ 0x10 /* W: read, R: read in progress */
-#define VT1724_AC97_READY 0x08 /* codec ready status bit */
-#define VT1724_AC97_ID_MASK 0x03 /* codec id mask */
-#define VT1724_MT_AC97_DATA 0x06 /* word - AC'97 data */
-#define VT1724_MT_PLAYBACK_ADDR 0x10 /* dword - playback address */
-#define VT1724_MT_PLAYBACK_SIZE 0x14 /* dword - playback size */
-#define VT1724_MT_DMA_CONTROL 0x18 /* byte - control */
-#define VT1724_PDMA4_START 0x80 /* SPDIF out / PDMA4 start */
-#define VT1724_PDMA3_START 0x40 /* PDMA3 start */
-#define VT1724_PDMA2_START 0x20 /* PDMA2 start */
-#define VT1724_PDMA1_START 0x10 /* PDMA1 start */
-#define VT1724_RDMA1_START 0x04 /* RDMA1 start */
-#define VT1724_RDMA0_START 0x02 /* RMDA0 start */
-#define VT1724_PDMA0_START 0x01 /* MC Interleave / PDMA0 start */
-#define VT1724_MT_BURST 0x19 /* Interleaved playback DMA Active streams / PCI burst size */
-#define VT1724_MT_DMA_FIFO_ERR 0x1a /*Global playback and record DMA FIFO Underrun/Overrun */
-#define VT1724_PDMA4_UNDERRUN 0x80
-#define VT1724_PDMA2_UNDERRUN 0x40
-#define VT1724_PDMA3_UNDERRUN 0x20
-#define VT1724_PDMA1_UNDERRUN 0x10
-#define VT1724_RDMA1_UNDERRUN 0x04
-#define VT1724_RDMA0_UNDERRUN 0x02
-#define VT1724_PDMA0_UNDERRUN 0x01
-#define VT1724_MT_DMA_PAUSE 0x1b /*Global playback and record DMA FIFO pause/resume */
-#define VT1724_PDMA4_PAUSE 0x80
-#define VT1724_PDMA3_PAUSE 0x40
-#define VT1724_PDMA2_PAUSE 0x20
-#define VT1724_PDMA1_PAUSE 0x10
-#define VT1724_RDMA1_PAUSE 0x04
-#define VT1724_RDMA0_PAUSE 0x02
-#define VT1724_PDMA0_PAUSE 0x01
-#define VT1724_MT_PLAYBACK_COUNT 0x1c /* word - playback count */
-#define VT1724_MT_CAPTURE_ADDR 0x20 /* dword - capture address */
-#define VT1724_MT_CAPTURE_SIZE 0x24 /* word - capture size */
-#define VT1724_MT_CAPTURE_COUNT 0x26 /* word - capture count */
-
-#define VT1724_MT_ROUTE_PLAYBACK 0x2c /* word */
-
-#define VT1724_MT_RDMA1_ADDR 0x30 /* dword - RDMA1 capture address */
-#define VT1724_MT_RDMA1_SIZE 0x34 /* word - RDMA1 capture size */
-#define VT1724_MT_RDMA1_COUNT 0x36 /* word - RDMA1 capture count */
-
-#define VT1724_MT_SPDIF_CTRL 0x3c /* word */
-#define VT1724_MT_MONITOR_PEAKINDEX 0x3e /* byte */
-#define VT1724_MT_MONITOR_PEAKDATA 0x3f /* byte */
-
-/* concurrent stereo channels */
-#define VT1724_MT_PDMA4_ADDR 0x40 /* dword */
-#define VT1724_MT_PDMA4_SIZE 0x44 /* word */
-#define VT1724_MT_PDMA4_COUNT 0x46 /* word */
-#define VT1724_MT_PDMA3_ADDR 0x50 /* dword */
-#define VT1724_MT_PDMA3_SIZE 0x54 /* word */
-#define VT1724_MT_PDMA3_COUNT 0x56 /* word */
-#define VT1724_MT_PDMA2_ADDR 0x60 /* dword */
-#define VT1724_MT_PDMA2_SIZE 0x64 /* word */
-#define VT1724_MT_PDMA2_COUNT 0x66 /* word */
-#define VT1724_MT_PDMA1_ADDR 0x70 /* dword */
-#define VT1724_MT_PDMA1_SIZE 0x74 /* word */
-#define VT1724_MT_PDMA1_COUNT 0x76 /* word */
-
-
-unsigned char snd_vt1724_read_i2c(struct snd_ice1712 *ice, unsigned char dev, unsigned char addr);
-void snd_vt1724_write_i2c(struct snd_ice1712 *ice, unsigned char dev, unsigned char addr, unsigned char data);
-
-#endif /* __SOUND_VT1724_H */
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/ews.c b/ANDROID_3.4.5/sound/pci/ice1712/ews.c
deleted file mode 100644
index 6fe35b81..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/ews.c
+++ /dev/null
@@ -1,1087 +0,0 @@
-/*
- * ALSA driver for ICEnsemble ICE1712 (Envy24)
- *
- * Lowlevel functions for Terratec EWS88MT/D, EWX24/96, DMX 6Fire
- *
- * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
- * 2002 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/cs8427.h>
-#include <sound/asoundef.h>
-
-#include "ice1712.h"
-#include "ews.h"
-
-#define SND_CS8404
-#include <sound/cs8403.h>
-
-enum {
- EWS_I2C_CS8404 = 0, EWS_I2C_PCF1, EWS_I2C_PCF2,
- EWS_I2C_88D = 0,
- EWS_I2C_6FIRE = 0
-};
-
-
-/* additional i2c devices for EWS boards */
-struct ews_spec {
- struct snd_i2c_device *i2cdevs[3];
-};
-
-/*
- * access via i2c mode (for EWX 24/96, EWS 88MT&D)
- */
-
-/* send SDA and SCL */
-static void ewx_i2c_setlines(struct snd_i2c_bus *bus, int clk, int data)
-{
- struct snd_ice1712 *ice = bus->private_data;
- unsigned char tmp = 0;
- if (clk)
- tmp |= ICE1712_EWX2496_SERIAL_CLOCK;
- if (data)
- tmp |= ICE1712_EWX2496_SERIAL_DATA;
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
- udelay(5);
-}
-
-static int ewx_i2c_getclock(struct snd_i2c_bus *bus)
-{
- struct snd_ice1712 *ice = bus->private_data;
- return snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ICE1712_EWX2496_SERIAL_CLOCK ? 1 : 0;
-}
-
-static int ewx_i2c_getdata(struct snd_i2c_bus *bus, int ack)
-{
- struct snd_ice1712 *ice = bus->private_data;
- int bit;
- /* set RW pin to low */
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~ICE1712_EWX2496_RW);
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, 0);
- if (ack)
- udelay(5);
- bit = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ICE1712_EWX2496_SERIAL_DATA ? 1 : 0;
- /* set RW pin to high */
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ICE1712_EWX2496_RW);
- /* reset write mask */
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~ICE1712_EWX2496_SERIAL_CLOCK);
- return bit;
-}
-
-static void ewx_i2c_start(struct snd_i2c_bus *bus)
-{
- struct snd_ice1712 *ice = bus->private_data;
- unsigned char mask;
-
- snd_ice1712_save_gpio_status(ice);
- /* set RW high */
- mask = ICE1712_EWX2496_RW;
- switch (ice->eeprom.subvendor) {
- case ICE1712_SUBDEVICE_EWX2496:
- mask |= ICE1712_EWX2496_AK4524_CS; /* CS high also */
- break;
- case ICE1712_SUBDEVICE_DMX6FIRE:
- mask |= ICE1712_6FIRE_AK4524_CS_MASK; /* CS high also */
- break;
- }
- snd_ice1712_gpio_write_bits(ice, mask, mask);
-}
-
-static void ewx_i2c_stop(struct snd_i2c_bus *bus)
-{
- struct snd_ice1712 *ice = bus->private_data;
- snd_ice1712_restore_gpio_status(ice);
-}
-
-static void ewx_i2c_direction(struct snd_i2c_bus *bus, int clock, int data)
-{
- struct snd_ice1712 *ice = bus->private_data;
- unsigned char mask = 0;
-
- if (clock)
- mask |= ICE1712_EWX2496_SERIAL_CLOCK; /* write SCL */
- if (data)
- mask |= ICE1712_EWX2496_SERIAL_DATA; /* write SDA */
- ice->gpio.direction &= ~(ICE1712_EWX2496_SERIAL_CLOCK|ICE1712_EWX2496_SERIAL_DATA);
- ice->gpio.direction |= mask;
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->gpio.direction);
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~mask);
-}
-
-static struct snd_i2c_bit_ops snd_ice1712_ewx_cs8427_bit_ops = {
- .start = ewx_i2c_start,
- .stop = ewx_i2c_stop,
- .direction = ewx_i2c_direction,
- .setlines = ewx_i2c_setlines,
- .getclock = ewx_i2c_getclock,
- .getdata = ewx_i2c_getdata,
-};
-
-
-/*
- * AK4524 access
- */
-
-/* AK4524 chip select; address 0x48 bit 0-3 */
-static int snd_ice1712_ews88mt_chip_select(struct snd_ice1712 *ice, int chip_mask)
-{
- struct ews_spec *spec = ice->spec;
- unsigned char data, ndata;
-
- if (snd_BUG_ON(chip_mask < 0 || chip_mask > 0x0f))
- return -EINVAL;
- snd_i2c_lock(ice->i2c);
- if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1)
- goto __error;
- ndata = (data & 0xf0) | chip_mask;
- if (ndata != data)
- if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_PCF2], &ndata, 1)
- != 1)
- goto __error;
- snd_i2c_unlock(ice->i2c);
- return 0;
-
- __error:
- snd_i2c_unlock(ice->i2c);
- snd_printk(KERN_ERR "AK4524 chip select failed, check cable to the front module\n");
- return -EIO;
-}
-
-/* start callback for EWS88MT, needs to select a certain chip mask */
-static void ews88mt_ak4524_lock(struct snd_akm4xxx *ak, int chip)
-{
- struct snd_ice1712 *ice = ak->private_data[0];
- unsigned char tmp;
- /* assert AK4524 CS */
- if (snd_ice1712_ews88mt_chip_select(ice, ~(1 << chip) & 0x0f) < 0)
- snd_printk(KERN_ERR "fatal error (ews88mt chip select)\n");
- snd_ice1712_save_gpio_status(ice);
- tmp = ICE1712_EWS88_SERIAL_DATA |
- ICE1712_EWS88_SERIAL_CLOCK |
- ICE1712_EWS88_RW;
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
- ice->gpio.direction | tmp);
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
-}
-
-/* stop callback for EWS88MT, needs to deselect chip mask */
-static void ews88mt_ak4524_unlock(struct snd_akm4xxx *ak, int chip)
-{
- struct snd_ice1712 *ice = ak->private_data[0];
- snd_ice1712_restore_gpio_status(ice);
- udelay(1);
- snd_ice1712_ews88mt_chip_select(ice, 0x0f);
-}
-
-/* start callback for EWX24/96 */
-static void ewx2496_ak4524_lock(struct snd_akm4xxx *ak, int chip)
-{
- struct snd_ice1712 *ice = ak->private_data[0];
- unsigned char tmp;
- snd_ice1712_save_gpio_status(ice);
- tmp = ICE1712_EWX2496_SERIAL_DATA |
- ICE1712_EWX2496_SERIAL_CLOCK |
- ICE1712_EWX2496_AK4524_CS |
- ICE1712_EWX2496_RW;
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
- ice->gpio.direction | tmp);
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
-}
-
-/* start callback for DMX 6fire */
-static void dmx6fire_ak4524_lock(struct snd_akm4xxx *ak, int chip)
-{
- struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
- struct snd_ice1712 *ice = ak->private_data[0];
- unsigned char tmp;
- snd_ice1712_save_gpio_status(ice);
- tmp = priv->cs_mask = priv->cs_addr = (1 << chip) & ICE1712_6FIRE_AK4524_CS_MASK;
- tmp |= ICE1712_6FIRE_SERIAL_DATA |
- ICE1712_6FIRE_SERIAL_CLOCK |
- ICE1712_6FIRE_RW;
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
- ice->gpio.direction | tmp);
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
-}
-
-/*
- * CS8404 interface on EWS88MT/D
- */
-
-static void snd_ice1712_ews_cs8404_spdif_write(struct snd_ice1712 *ice, unsigned char bits)
-{
- struct ews_spec *spec = ice->spec;
- unsigned char bytes[2];
-
- snd_i2c_lock(ice->i2c);
- switch (ice->eeprom.subvendor) {
- case ICE1712_SUBDEVICE_EWS88MT:
- case ICE1712_SUBDEVICE_EWS88MT_NEW:
- case ICE1712_SUBDEVICE_PHASE88:
- case ICE1712_SUBDEVICE_TS88:
- if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_CS8404], &bits, 1)
- != 1)
- goto _error;
- break;
- case ICE1712_SUBDEVICE_EWS88D:
- if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_88D], bytes, 2)
- != 2)
- goto _error;
- if (bits != bytes[1]) {
- bytes[1] = bits;
- if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_88D],
- bytes, 2) != 2)
- goto _error;
- }
- break;
- }
- _error:
- snd_i2c_unlock(ice->i2c);
-}
-
-/*
- */
-
-static void ews88_spdif_default_get(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
-{
- snd_cs8404_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_bits);
-}
-
-static int ews88_spdif_default_put(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
-{
- unsigned int val;
- int change;
-
- val = snd_cs8404_encode_spdif_bits(&ucontrol->value.iec958);
- spin_lock_irq(&ice->reg_lock);
- change = ice->spdif.cs8403_bits != val;
- ice->spdif.cs8403_bits = val;
- if (change && ice->playback_pro_substream == NULL) {
- spin_unlock_irq(&ice->reg_lock);
- snd_ice1712_ews_cs8404_spdif_write(ice, val);
- } else {
- spin_unlock_irq(&ice->reg_lock);
- }
- return change;
-}
-
-static void ews88_spdif_stream_get(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
-{
- snd_cs8404_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_stream_bits);
-}
-
-static int ews88_spdif_stream_put(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
-{
- unsigned int val;
- int change;
-
- val = snd_cs8404_encode_spdif_bits(&ucontrol->value.iec958);
- spin_lock_irq(&ice->reg_lock);
- change = ice->spdif.cs8403_stream_bits != val;
- ice->spdif.cs8403_stream_bits = val;
- if (change && ice->playback_pro_substream != NULL) {
- spin_unlock_irq(&ice->reg_lock);
- snd_ice1712_ews_cs8404_spdif_write(ice, val);
- } else {
- spin_unlock_irq(&ice->reg_lock);
- }
- return change;
-}
-
-
-/* open callback */
-static void ews88_open_spdif(struct snd_ice1712 *ice, struct snd_pcm_substream *substream)
-{
- ice->spdif.cs8403_stream_bits = ice->spdif.cs8403_bits;
-}
-
-/* set up SPDIF for EWS88MT / EWS88D */
-static void ews88_setup_spdif(struct snd_ice1712 *ice, int rate)
-{
- unsigned long flags;
- unsigned char tmp;
- int change;
-
- spin_lock_irqsave(&ice->reg_lock, flags);
- tmp = ice->spdif.cs8403_stream_bits;
- if (tmp & 0x10) /* consumer */
- tmp &= (tmp & 0x01) ? ~0x06 : ~0x60;
- switch (rate) {
- case 32000: tmp |= (tmp & 0x01) ? 0x02 : 0x00; break;
- case 44100: tmp |= (tmp & 0x01) ? 0x06 : 0x40; break;
- case 48000: tmp |= (tmp & 0x01) ? 0x04 : 0x20; break;
- default: tmp |= (tmp & 0x01) ? 0x06 : 0x40; break;
- }
- change = ice->spdif.cs8403_stream_bits != tmp;
- ice->spdif.cs8403_stream_bits = tmp;
- spin_unlock_irqrestore(&ice->reg_lock, flags);
- if (change)
- snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &ice->spdif.stream_ctl->id);
- snd_ice1712_ews_cs8404_spdif_write(ice, tmp);
-}
-
-
-/*
- */
-static struct snd_akm4xxx akm_ews88mt __devinitdata = {
- .num_adcs = 8,
- .num_dacs = 8,
- .type = SND_AK4524,
- .ops = {
- .lock = ews88mt_ak4524_lock,
- .unlock = ews88mt_ak4524_unlock
- }
-};
-
-static struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = {
- .caddr = 2,
- .cif = 1, /* CIF high */
- .data_mask = ICE1712_EWS88_SERIAL_DATA,
- .clk_mask = ICE1712_EWS88_SERIAL_CLOCK,
- .cs_mask = 0,
- .cs_addr = 0,
- .cs_none = 0, /* no chip select on gpio */
- .add_flags = ICE1712_EWS88_RW, /* set rw bit high */
- .mask_flags = 0,
-};
-
-static struct snd_akm4xxx akm_ewx2496 __devinitdata = {
- .num_adcs = 2,
- .num_dacs = 2,
- .type = SND_AK4524,
- .ops = {
- .lock = ewx2496_ak4524_lock
- }
-};
-
-static struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = {
- .caddr = 2,
- .cif = 1, /* CIF high */
- .data_mask = ICE1712_EWS88_SERIAL_DATA,
- .clk_mask = ICE1712_EWS88_SERIAL_CLOCK,
- .cs_mask = ICE1712_EWX2496_AK4524_CS,
- .cs_addr = ICE1712_EWX2496_AK4524_CS,
- .cs_none = 0,
- .add_flags = ICE1712_EWS88_RW, /* set rw bit high */
- .mask_flags = 0,
-};
-
-static struct snd_akm4xxx akm_6fire __devinitdata = {
- .num_adcs = 6,
- .num_dacs = 6,
- .type = SND_AK4524,
- .ops = {
- .lock = dmx6fire_ak4524_lock
- }
-};
-
-static struct snd_ak4xxx_private akm_6fire_priv __devinitdata = {
- .caddr = 2,
- .cif = 1, /* CIF high */
- .data_mask = ICE1712_6FIRE_SERIAL_DATA,
- .clk_mask = ICE1712_6FIRE_SERIAL_CLOCK,
- .cs_mask = 0,
- .cs_addr = 0, /* set later */
- .cs_none = 0,
- .add_flags = ICE1712_6FIRE_RW, /* set rw bit high */
- .mask_flags = 0,
-};
-
-/*
- * initialize the chip
- */
-
-/* 6fire specific */
-#define PCF9554_REG_INPUT 0
-#define PCF9554_REG_OUTPUT 1
-#define PCF9554_REG_POLARITY 2
-#define PCF9554_REG_CONFIG 3
-
-static int snd_ice1712_6fire_write_pca(struct snd_ice1712 *ice, unsigned char reg, unsigned char data);
-
-static int __devinit snd_ice1712_ews_init(struct snd_ice1712 *ice)
-{
- int err;
- struct snd_akm4xxx *ak;
- struct ews_spec *spec;
-
- /* set the analog DACs */
- switch (ice->eeprom.subvendor) {
- case ICE1712_SUBDEVICE_EWX2496:
- ice->num_total_dacs = 2;
- ice->num_total_adcs = 2;
- break;
- case ICE1712_SUBDEVICE_EWS88MT:
- case ICE1712_SUBDEVICE_EWS88MT_NEW:
- case ICE1712_SUBDEVICE_PHASE88:
- case ICE1712_SUBDEVICE_TS88:
- ice->num_total_dacs = 8;
- ice->num_total_adcs = 8;
- break;
- case ICE1712_SUBDEVICE_EWS88D:
- /* Note: not analog but ADAT I/O */
- ice->num_total_dacs = 8;
- ice->num_total_adcs = 8;
- break;
- case ICE1712_SUBDEVICE_DMX6FIRE:
- ice->num_total_dacs = 6;
- ice->num_total_adcs = 6;
- break;
- }
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- ice->spec = spec;
-
- /* create i2c */
- if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
- snd_printk(KERN_ERR "unable to create I2C bus\n");
- return err;
- }
- ice->i2c->private_data = ice;
- ice->i2c->hw_ops.bit = &snd_ice1712_ewx_cs8427_bit_ops;
-
- /* create i2c devices */
- switch (ice->eeprom.subvendor) {
- case ICE1712_SUBDEVICE_DMX6FIRE:
- err = snd_i2c_device_create(ice->i2c, "PCF9554",
- ICE1712_6FIRE_PCF9554_ADDR,
- &spec->i2cdevs[EWS_I2C_6FIRE]);
- if (err < 0) {
- snd_printk(KERN_ERR "PCF9554 initialization failed\n");
- return err;
- }
- snd_ice1712_6fire_write_pca(ice, PCF9554_REG_CONFIG, 0x80);
- break;
- case ICE1712_SUBDEVICE_EWS88MT:
- case ICE1712_SUBDEVICE_EWS88MT_NEW:
- case ICE1712_SUBDEVICE_PHASE88:
- case ICE1712_SUBDEVICE_TS88:
-
- err = snd_i2c_device_create(ice->i2c, "CS8404",
- ICE1712_EWS88MT_CS8404_ADDR,
- &spec->i2cdevs[EWS_I2C_CS8404]);
- if (err < 0)
- return err;
- err = snd_i2c_device_create(ice->i2c, "PCF8574 (1st)",
- ICE1712_EWS88MT_INPUT_ADDR,
- &spec->i2cdevs[EWS_I2C_PCF1]);
- if (err < 0)
- return err;
- err = snd_i2c_device_create(ice->i2c, "PCF8574 (2nd)",
- ICE1712_EWS88MT_OUTPUT_ADDR,
- &spec->i2cdevs[EWS_I2C_PCF2]);
- if (err < 0)
- return err;
- /* Check if the front module is connected */
- if ((err = snd_ice1712_ews88mt_chip_select(ice, 0x0f)) < 0)
- return err;
- break;
- case ICE1712_SUBDEVICE_EWS88D:
- err = snd_i2c_device_create(ice->i2c, "PCF8575",
- ICE1712_EWS88D_PCF_ADDR,
- &spec->i2cdevs[EWS_I2C_88D]);
- if (err < 0)
- return err;
- break;
- }
-
- /* set up SPDIF interface */
- switch (ice->eeprom.subvendor) {
- case ICE1712_SUBDEVICE_EWX2496:
- if ((err = snd_ice1712_init_cs8427(ice, CS8427_BASE_ADDR)) < 0)
- return err;
- snd_cs8427_reg_write(ice->cs8427, CS8427_REG_RECVERRMASK, CS8427_UNLOCK | CS8427_CONF | CS8427_BIP | CS8427_PAR);
- break;
- case ICE1712_SUBDEVICE_DMX6FIRE:
- if ((err = snd_ice1712_init_cs8427(ice, ICE1712_6FIRE_CS8427_ADDR)) < 0)
- return err;
- snd_cs8427_reg_write(ice->cs8427, CS8427_REG_RECVERRMASK, CS8427_UNLOCK | CS8427_CONF | CS8427_BIP | CS8427_PAR);
- break;
- case ICE1712_SUBDEVICE_EWS88MT:
- case ICE1712_SUBDEVICE_EWS88MT_NEW:
- case ICE1712_SUBDEVICE_PHASE88:
- case ICE1712_SUBDEVICE_TS88:
- case ICE1712_SUBDEVICE_EWS88D:
- /* set up CS8404 */
- ice->spdif.ops.open = ews88_open_spdif;
- ice->spdif.ops.setup_rate = ews88_setup_spdif;
- ice->spdif.ops.default_get = ews88_spdif_default_get;
- ice->spdif.ops.default_put = ews88_spdif_default_put;
- ice->spdif.ops.stream_get = ews88_spdif_stream_get;
- ice->spdif.ops.stream_put = ews88_spdif_stream_put;
- /* Set spdif defaults */
- snd_ice1712_ews_cs8404_spdif_write(ice, ice->spdif.cs8403_bits);
- break;
- }
-
- /* no analog? */
- switch (ice->eeprom.subvendor) {
- case ICE1712_SUBDEVICE_EWS88D:
- return 0;
- }
-
- /* analog section */
- ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
- if (! ak)
- return -ENOMEM;
- ice->akm_codecs = 1;
-
- switch (ice->eeprom.subvendor) {
- case ICE1712_SUBDEVICE_EWS88MT:
- case ICE1712_SUBDEVICE_EWS88MT_NEW:
- case ICE1712_SUBDEVICE_PHASE88:
- case ICE1712_SUBDEVICE_TS88:
- err = snd_ice1712_akm4xxx_init(ak, &akm_ews88mt, &akm_ews88mt_priv, ice);
- break;
- case ICE1712_SUBDEVICE_EWX2496:
- err = snd_ice1712_akm4xxx_init(ak, &akm_ewx2496, &akm_ewx2496_priv, ice);
- break;
- case ICE1712_SUBDEVICE_DMX6FIRE:
- err = snd_ice1712_akm4xxx_init(ak, &akm_6fire, &akm_6fire_priv, ice);
- break;
- default:
- err = 0;
- }
-
- return err;
-}
-
-/*
- * EWX 24/96 specific controls
- */
-
-/* i/o sensitivity - this callback is shared among other devices, too */
-static int snd_ice1712_ewx_io_sense_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){
-
- static char *texts[2] = {
- "+4dBu", "-10dBV",
- };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item >= 2)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ice1712_ewx_io_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char mask = kcontrol->private_value & 0xff;
-
- snd_ice1712_save_gpio_status(ice);
- ucontrol->value.enumerated.item[0] = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & mask ? 1 : 0;
- snd_ice1712_restore_gpio_status(ice);
- return 0;
-}
-
-static int snd_ice1712_ewx_io_sense_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char mask = kcontrol->private_value & 0xff;
- int val, nval;
-
- if (kcontrol->private_value & (1 << 31))
- return -EPERM;
- nval = ucontrol->value.enumerated.item[0] ? mask : 0;
- snd_ice1712_save_gpio_status(ice);
- val = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
- nval |= val & ~mask;
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, nval);
- snd_ice1712_restore_gpio_status(ice);
- return val != nval;
-}
-
-static struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input Sensitivity Switch",
- .info = snd_ice1712_ewx_io_sense_info,
- .get = snd_ice1712_ewx_io_sense_get,
- .put = snd_ice1712_ewx_io_sense_put,
- .private_value = ICE1712_EWX2496_AIN_SEL,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Output Sensitivity Switch",
- .info = snd_ice1712_ewx_io_sense_info,
- .get = snd_ice1712_ewx_io_sense_get,
- .put = snd_ice1712_ewx_io_sense_put,
- .private_value = ICE1712_EWX2496_AOUT_SEL,
- },
-};
-
-
-/*
- * EWS88MT specific controls
- */
-/* analog output sensitivity;; address 0x48 bit 6 */
-static int snd_ice1712_ews88mt_output_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct ews_spec *spec = ice->spec;
- unsigned char data;
-
- snd_i2c_lock(ice->i2c);
- if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) {
- snd_i2c_unlock(ice->i2c);
- return -EIO;
- }
- snd_i2c_unlock(ice->i2c);
- ucontrol->value.enumerated.item[0] = data & ICE1712_EWS88MT_OUTPUT_SENSE ? 1 : 0; /* high = -10dBV, low = +4dBu */
- return 0;
-}
-
-/* analog output sensitivity;; address 0x48 bit 6 */
-static int snd_ice1712_ews88mt_output_sense_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct ews_spec *spec = ice->spec;
- unsigned char data, ndata;
-
- snd_i2c_lock(ice->i2c);
- if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) {
- snd_i2c_unlock(ice->i2c);
- return -EIO;
- }
- ndata = (data & ~ICE1712_EWS88MT_OUTPUT_SENSE) | (ucontrol->value.enumerated.item[0] ? ICE1712_EWS88MT_OUTPUT_SENSE : 0);
- if (ndata != data && snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_PCF2],
- &ndata, 1) != 1) {
- snd_i2c_unlock(ice->i2c);
- return -EIO;
- }
- snd_i2c_unlock(ice->i2c);
- return ndata != data;
-}
-
-/* analog input sensitivity; address 0x46 */
-static int snd_ice1712_ews88mt_input_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct ews_spec *spec = ice->spec;
- int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- unsigned char data;
-
- if (snd_BUG_ON(channel < 0 || channel > 7))
- return 0;
- snd_i2c_lock(ice->i2c);
- if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
- snd_i2c_unlock(ice->i2c);
- return -EIO;
- }
- /* reversed; high = +4dBu, low = -10dBV */
- ucontrol->value.enumerated.item[0] = data & (1 << channel) ? 0 : 1;
- snd_i2c_unlock(ice->i2c);
- return 0;
-}
-
-/* analog output sensitivity; address 0x46 */
-static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct ews_spec *spec = ice->spec;
- int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- unsigned char data, ndata;
-
- if (snd_BUG_ON(channel < 0 || channel > 7))
- return 0;
- snd_i2c_lock(ice->i2c);
- if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
- snd_i2c_unlock(ice->i2c);
- return -EIO;
- }
- ndata = (data & ~(1 << channel)) | (ucontrol->value.enumerated.item[0] ? 0 : (1 << channel));
- if (ndata != data && snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_PCF1],
- &ndata, 1) != 1) {
- snd_i2c_unlock(ice->i2c);
- return -EIO;
- }
- snd_i2c_unlock(ice->i2c);
- return ndata != data;
-}
-
-static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input Sensitivity Switch",
- .info = snd_ice1712_ewx_io_sense_info,
- .get = snd_ice1712_ews88mt_input_sense_get,
- .put = snd_ice1712_ews88mt_input_sense_put,
- .count = 8,
-};
-
-static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Output Sensitivity Switch",
- .info = snd_ice1712_ewx_io_sense_info,
- .get = snd_ice1712_ews88mt_output_sense_get,
- .put = snd_ice1712_ews88mt_output_sense_put,
-};
-
-
-/*
- * EWS88D specific controls
- */
-
-#define snd_ice1712_ews88d_control_info snd_ctl_boolean_mono_info
-
-static int snd_ice1712_ews88d_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct ews_spec *spec = ice->spec;
- int shift = kcontrol->private_value & 0xff;
- int invert = (kcontrol->private_value >> 8) & 1;
- unsigned char data[2];
-
- snd_i2c_lock(ice->i2c);
- if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_88D], data, 2) != 2) {
- snd_i2c_unlock(ice->i2c);
- return -EIO;
- }
- snd_i2c_unlock(ice->i2c);
- data[0] = (data[shift >> 3] >> (shift & 7)) & 0x01;
- if (invert)
- data[0] ^= 0x01;
- ucontrol->value.integer.value[0] = data[0];
- return 0;
-}
-
-static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct ews_spec *spec = ice->spec;
- int shift = kcontrol->private_value & 0xff;
- int invert = (kcontrol->private_value >> 8) & 1;
- unsigned char data[2], ndata[2];
- int change;
-
- snd_i2c_lock(ice->i2c);
- if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_88D], data, 2) != 2) {
- snd_i2c_unlock(ice->i2c);
- return -EIO;
- }
- ndata[shift >> 3] = data[shift >> 3] & ~(1 << (shift & 7));
- if (invert) {
- if (! ucontrol->value.integer.value[0])
- ndata[shift >> 3] |= (1 << (shift & 7));
- } else {
- if (ucontrol->value.integer.value[0])
- ndata[shift >> 3] |= (1 << (shift & 7));
- }
- change = (data[shift >> 3] != ndata[shift >> 3]);
- if (change &&
- snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_88D], data, 2) != 2) {
- snd_i2c_unlock(ice->i2c);
- return -EIO;
- }
- snd_i2c_unlock(ice->i2c);
- return change;
-}
-
-#define EWS88D_CONTROL(xiface, xname, xshift, xinvert, xaccess) \
-{ .iface = xiface,\
- .name = xname,\
- .access = xaccess,\
- .info = snd_ice1712_ews88d_control_info,\
- .get = snd_ice1712_ews88d_control_get,\
- .put = snd_ice1712_ews88d_control_put,\
- .private_value = xshift | (xinvert << 8),\
-}
-
-static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = {
- EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */
- EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0),
- EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0),
- EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "Enable ADAT", 3, 0, 0),
- EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Through", 4, 1, 0),
-};
-
-
-/*
- * DMX 6Fire specific controls
- */
-
-static int snd_ice1712_6fire_read_pca(struct snd_ice1712 *ice, unsigned char reg)
-{
- unsigned char byte;
- struct ews_spec *spec = ice->spec;
-
- snd_i2c_lock(ice->i2c);
- byte = reg;
- snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_6FIRE], &byte, 1);
- byte = 0;
- if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_6FIRE], &byte, 1) != 1) {
- snd_i2c_unlock(ice->i2c);
- printk(KERN_ERR "cannot read pca\n");
- return -EIO;
- }
- snd_i2c_unlock(ice->i2c);
- return byte;
-}
-
-static int snd_ice1712_6fire_write_pca(struct snd_ice1712 *ice, unsigned char reg, unsigned char data)
-{
- unsigned char bytes[2];
- struct ews_spec *spec = ice->spec;
-
- snd_i2c_lock(ice->i2c);
- bytes[0] = reg;
- bytes[1] = data;
- if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_6FIRE], bytes, 2) != 2) {
- snd_i2c_unlock(ice->i2c);
- return -EIO;
- }
- snd_i2c_unlock(ice->i2c);
- return 0;
-}
-
-#define snd_ice1712_6fire_control_info snd_ctl_boolean_mono_info
-
-static int snd_ice1712_6fire_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int shift = kcontrol->private_value & 0xff;
- int invert = (kcontrol->private_value >> 8) & 1;
- int data;
-
- if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
- return data;
- data = (data >> shift) & 1;
- if (invert)
- data ^= 1;
- ucontrol->value.integer.value[0] = data;
- return 0;
-}
-
-static int snd_ice1712_6fire_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int shift = kcontrol->private_value & 0xff;
- int invert = (kcontrol->private_value >> 8) & 1;
- int data, ndata;
-
- if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
- return data;
- ndata = data & ~(1 << shift);
- if (ucontrol->value.integer.value[0])
- ndata |= (1 << shift);
- if (invert)
- ndata ^= (1 << shift);
- if (data != ndata) {
- snd_ice1712_6fire_write_pca(ice, PCF9554_REG_OUTPUT, (unsigned char)ndata);
- return 1;
- }
- return 0;
-}
-
-static int snd_ice1712_6fire_select_input_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[4] = {
- "Internal", "Front Input", "Rear Input", "Wave Table"
- };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 4;
- if (uinfo->value.enumerated.item >= 4)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ice1712_6fire_select_input_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int data;
-
- if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
- return data;
- ucontrol->value.integer.value[0] = data & 3;
- return 0;
-}
-
-static int snd_ice1712_6fire_select_input_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int data, ndata;
-
- if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
- return data;
- ndata = data & ~3;
- ndata |= (ucontrol->value.integer.value[0] & 3);
- if (data != ndata) {
- snd_ice1712_6fire_write_pca(ice, PCF9554_REG_OUTPUT, (unsigned char)ndata);
- return 1;
- }
- return 0;
-}
-
-
-#define DMX6FIRE_CONTROL(xname, xshift, xinvert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\
- .name = xname,\
- .info = snd_ice1712_6fire_control_info,\
- .get = snd_ice1712_6fire_control_get,\
- .put = snd_ice1712_6fire_control_put,\
- .private_value = xshift | (xinvert << 8),\
-}
-
-static struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Input Select",
- .info = snd_ice1712_6fire_select_input_info,
- .get = snd_ice1712_6fire_select_input_get,
- .put = snd_ice1712_6fire_select_input_put,
- },
- DMX6FIRE_CONTROL("Front Digital Input Switch", 2, 1),
- // DMX6FIRE_CONTROL("Master Clock Select", 3, 0),
- DMX6FIRE_CONTROL("Optical Digital Input Switch", 4, 0),
- DMX6FIRE_CONTROL("Phono Analog Input Switch", 5, 0),
- DMX6FIRE_CONTROL("Breakbox LED", 6, 0),
-};
-
-
-static int __devinit snd_ice1712_ews_add_controls(struct snd_ice1712 *ice)
-{
- unsigned int idx;
- int err;
-
- /* all terratec cards have spdif, but cs8427 module builds it's own controls */
- if (ice->cs8427 == NULL) {
- err = snd_ice1712_spdif_build_controls(ice);
- if (err < 0)
- return err;
- }
-
- /* ak4524 controls */
- switch (ice->eeprom.subvendor) {
- case ICE1712_SUBDEVICE_EWX2496:
- case ICE1712_SUBDEVICE_EWS88MT:
- case ICE1712_SUBDEVICE_EWS88MT_NEW:
- case ICE1712_SUBDEVICE_PHASE88:
- case ICE1712_SUBDEVICE_TS88:
- case ICE1712_SUBDEVICE_DMX6FIRE:
- err = snd_ice1712_akm4xxx_build_controls(ice);
- if (err < 0)
- return err;
- break;
- }
-
- /* card specific controls */
- switch (ice->eeprom.subvendor) {
- case ICE1712_SUBDEVICE_EWX2496:
- for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_ewx2496_controls); idx++) {
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ewx2496_controls[idx], ice));
- if (err < 0)
- return err;
- }
- break;
- case ICE1712_SUBDEVICE_EWS88MT:
- case ICE1712_SUBDEVICE_EWS88MT_NEW:
- case ICE1712_SUBDEVICE_PHASE88:
- case ICE1712_SUBDEVICE_TS88:
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88mt_input_sense, ice));
- if (err < 0)
- return err;
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88mt_output_sense, ice));
- if (err < 0)
- return err;
- break;
- case ICE1712_SUBDEVICE_EWS88D:
- for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_ews88d_controls); idx++) {
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88d_controls[idx], ice));
- if (err < 0)
- return err;
- }
- break;
- case ICE1712_SUBDEVICE_DMX6FIRE:
- for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_6fire_controls); idx++) {
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_6fire_controls[idx], ice));
- if (err < 0)
- return err;
- }
- break;
- }
- return 0;
-}
-
-
-/* entry point */
-struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = {
- {
- .subvendor = ICE1712_SUBDEVICE_EWX2496,
- .name = "TerraTec EWX24/96",
- .model = "ewx2496",
- .chip_init = snd_ice1712_ews_init,
- .build_controls = snd_ice1712_ews_add_controls,
- },
- {
- .subvendor = ICE1712_SUBDEVICE_EWS88MT,
- .name = "TerraTec EWS88MT",
- .model = "ews88mt",
- .chip_init = snd_ice1712_ews_init,
- .build_controls = snd_ice1712_ews_add_controls,
- },
- {
- .subvendor = ICE1712_SUBDEVICE_EWS88MT_NEW,
- .name = "TerraTec EWS88MT",
- .model = "ews88mt_new",
- .chip_init = snd_ice1712_ews_init,
- .build_controls = snd_ice1712_ews_add_controls,
- },
- {
- .subvendor = ICE1712_SUBDEVICE_PHASE88,
- .name = "TerraTec Phase88",
- .model = "phase88",
- .chip_init = snd_ice1712_ews_init,
- .build_controls = snd_ice1712_ews_add_controls,
- },
- {
- .subvendor = ICE1712_SUBDEVICE_TS88,
- .name = "terrasoniq TS88",
- .model = "phase88",
- .chip_init = snd_ice1712_ews_init,
- .build_controls = snd_ice1712_ews_add_controls,
- },
- {
- .subvendor = ICE1712_SUBDEVICE_EWS88D,
- .name = "TerraTec EWS88D",
- .model = "ews88d",
- .chip_init = snd_ice1712_ews_init,
- .build_controls = snd_ice1712_ews_add_controls,
- },
- {
- .subvendor = ICE1712_SUBDEVICE_DMX6FIRE,
- .name = "TerraTec DMX6Fire",
- .model = "dmx6fire",
- .chip_init = snd_ice1712_ews_init,
- .build_controls = snd_ice1712_ews_add_controls,
- .mpu401_1_name = "MIDI-Front DMX6fire",
- .mpu401_2_name = "Wavetable DMX6fire",
- .mpu401_2_info_flags = MPU401_INFO_OUTPUT,
- },
- { } /* terminator */
-};
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/ews.h b/ANDROID_3.4.5/sound/pci/ice1712/ews.h
deleted file mode 100644
index 1c443718..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/ews.h
+++ /dev/null
@@ -1,86 +0,0 @@
-#ifndef __SOUND_EWS_H
-#define __SOUND_EWS_H
-
-/*
- * ALSA driver for ICEnsemble ICE1712 (Envy24)
- *
- * Lowlevel functions for Terratec EWS88MT/D, EWX24/96, DMX 6Fire
- *
- * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
- * 2002 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define EWS_DEVICE_DESC \
- "{TerraTec,EWX 24/96},"\
- "{TerraTec,EWS 88MT},"\
- "{TerraTec,EWS 88D},"\
- "{TerraTec,DMX 6Fire},"\
- "{TerraTec,Phase 88}," \
- "{terrasoniq,TS 88},"
-
-#define ICE1712_SUBDEVICE_EWX2496 0x3b153011
-#define ICE1712_SUBDEVICE_EWS88MT 0x3b151511
-#define ICE1712_SUBDEVICE_EWS88MT_NEW 0x3b152511
-#define ICE1712_SUBDEVICE_EWS88D 0x3b152b11
-#define ICE1712_SUBDEVICE_DMX6FIRE 0x3b153811
-#define ICE1712_SUBDEVICE_PHASE88 0x3b155111
-#define ICE1712_SUBDEVICE_TS88 0x3b157c11
-
-/* entry point */
-extern struct snd_ice1712_card_info snd_ice1712_ews_cards[];
-
-
-/* TerraTec EWX 24/96 configuration definitions */
-
-#define ICE1712_EWX2496_AK4524_CS 0x01 /* AK4524 chip select; low = active */
-#define ICE1712_EWX2496_AIN_SEL 0x02 /* input sensitivity switch; high = louder */
-#define ICE1712_EWX2496_AOUT_SEL 0x04 /* output sensitivity switch; high = louder */
-#define ICE1712_EWX2496_RW 0x08 /* read/write switch for i2c; high = write */
-#define ICE1712_EWX2496_SERIAL_DATA 0x10 /* i2c & ak4524 data */
-#define ICE1712_EWX2496_SERIAL_CLOCK 0x20 /* i2c & ak4524 clock */
-#define ICE1712_EWX2496_TX2 0x40 /* MIDI2 (not used) */
-#define ICE1712_EWX2496_RX2 0x80 /* MIDI2 (not used) */
-
-/* TerraTec EWS 88MT/D configuration definitions */
-/* RW, SDA snd SCLK are identical with EWX24/96 */
-#define ICE1712_EWS88_CS8414_RATE 0x07 /* CS8414 sample rate: gpio 0-2 */
-#define ICE1712_EWS88_RW 0x08 /* read/write switch for i2c; high = write */
-#define ICE1712_EWS88_SERIAL_DATA 0x10 /* i2c & ak4524 data */
-#define ICE1712_EWS88_SERIAL_CLOCK 0x20 /* i2c & ak4524 clock */
-#define ICE1712_EWS88_TX2 0x40 /* MIDI2 (only on 88D) */
-#define ICE1712_EWS88_RX2 0x80 /* MIDI2 (only on 88D) */
-
-/* i2c address */
-#define ICE1712_EWS88MT_CS8404_ADDR (0x40>>1)
-#define ICE1712_EWS88MT_INPUT_ADDR (0x46>>1)
-#define ICE1712_EWS88MT_OUTPUT_ADDR (0x48>>1)
-#define ICE1712_EWS88MT_OUTPUT_SENSE 0x40 /* mask */
-#define ICE1712_EWS88D_PCF_ADDR (0x40>>1)
-
-/* TerraTec DMX 6Fire configuration definitions */
-#define ICE1712_6FIRE_AK4524_CS_MASK 0x07 /* AK4524 chip select #1-#3 */
-#define ICE1712_6FIRE_RW 0x08 /* read/write switch for i2c; high = write */
-#define ICE1712_6FIRE_SERIAL_DATA 0x10 /* i2c & ak4524 data */
-#define ICE1712_6FIRE_SERIAL_CLOCK 0x20 /* i2c & ak4524 clock */
-#define ICE1712_6FIRE_TX2 0x40 /* MIDI2 */
-#define ICE1712_6FIRE_RX2 0x80 /* MIDI2 */
-
-#define ICE1712_6FIRE_PCF9554_ADDR (0x40>>1)
-#define ICE1712_6FIRE_CS8427_ADDR (0x22)
-
-#endif /* __SOUND_EWS_H */
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/hoontech.c b/ANDROID_3.4.5/sound/pci/ice1712/hoontech.c
deleted file mode 100644
index 69141890..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/hoontech.c
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * ALSA driver for ICEnsemble ICE1712 (Envy24)
- *
- * Lowlevel functions for Hoontech STDSP24
- *
- * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-
-#include <sound/core.h>
-
-#include "ice1712.h"
-#include "hoontech.h"
-
-/* Hoontech-specific setting */
-struct hoontech_spec {
- unsigned char boxbits[4];
- unsigned int config;
- unsigned short boxconfig[4];
-};
-
-static void __devinit snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, unsigned char byte)
-{
- byte |= ICE1712_STDSP24_CLOCK_BIT;
- udelay(100);
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
- byte &= ~ICE1712_STDSP24_CLOCK_BIT;
- udelay(100);
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
- byte |= ICE1712_STDSP24_CLOCK_BIT;
- udelay(100);
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
-}
-
-static void __devinit snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int activate)
-{
- struct hoontech_spec *spec = ice->spec;
- mutex_lock(&ice->gpio_mutex);
- ICE1712_STDSP24_0_DAREAR(spec->boxbits, activate);
- snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
- mutex_unlock(&ice->gpio_mutex);
-}
-
-static void __devinit snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int activate)
-{
- struct hoontech_spec *spec = ice->spec;
- mutex_lock(&ice->gpio_mutex);
- ICE1712_STDSP24_3_MUTE(spec->boxbits, activate);
- snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
- mutex_unlock(&ice->gpio_mutex);
-}
-
-static void __devinit snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int activate)
-{
- struct hoontech_spec *spec = ice->spec;
- mutex_lock(&ice->gpio_mutex);
- ICE1712_STDSP24_3_INSEL(spec->boxbits, activate);
- snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
- mutex_unlock(&ice->gpio_mutex);
-}
-
-static void __devinit snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, int chn, int activate)
-{
- struct hoontech_spec *spec = ice->spec;
-
- mutex_lock(&ice->gpio_mutex);
-
- /* select box */
- ICE1712_STDSP24_0_BOX(spec->boxbits, box);
- snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
-
- /* prepare for write */
- if (chn == 3)
- ICE1712_STDSP24_2_CHN4(spec->boxbits, 0);
- ICE1712_STDSP24_2_MIDI1(spec->boxbits, activate);
- snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
- snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
-
- ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
- ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
- ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
- ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
- snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
- snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
- udelay(100);
- if (chn == 3) {
- ICE1712_STDSP24_2_CHN4(spec->boxbits, 0);
- snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
- } else {
- switch (chn) {
- case 0: ICE1712_STDSP24_1_CHN1(spec->boxbits, 0); break;
- case 1: ICE1712_STDSP24_1_CHN2(spec->boxbits, 0); break;
- case 2: ICE1712_STDSP24_1_CHN3(spec->boxbits, 0); break;
- }
- snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
- }
- udelay(100);
- ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
- ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
- ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
- ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
- snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
- snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
- udelay(100);
-
- ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0);
- snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
-
- mutex_unlock(&ice->gpio_mutex);
-}
-
-static void __devinit snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int master)
-{
- struct hoontech_spec *spec = ice->spec;
-
- mutex_lock(&ice->gpio_mutex);
-
- /* select box */
- ICE1712_STDSP24_0_BOX(spec->boxbits, box);
- snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
-
- ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
- ICE1712_STDSP24_2_MIDI1(spec->boxbits, master);
- snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
- snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
-
- udelay(100);
-
- ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 0);
- snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
-
- mdelay(10);
-
- ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
- snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
-
- mutex_unlock(&ice->gpio_mutex);
-}
-
-static void __devinit snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate)
-{
- struct hoontech_spec *spec = ice->spec;
- mutex_lock(&ice->gpio_mutex);
- ICE1712_STDSP24_3_MIDI2(spec->boxbits, activate);
- snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
- mutex_unlock(&ice->gpio_mutex);
-}
-
-static int __devinit snd_ice1712_hoontech_init(struct snd_ice1712 *ice)
-{
- struct hoontech_spec *spec;
- int box, chn;
-
- ice->num_total_dacs = 8;
- ice->num_total_adcs = 8;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- ice->spec = spec;
-
- ICE1712_STDSP24_SET_ADDR(spec->boxbits, 0);
- ICE1712_STDSP24_CLOCK(spec->boxbits, 0, 1);
- ICE1712_STDSP24_0_BOX(spec->boxbits, 0);
- ICE1712_STDSP24_0_DAREAR(spec->boxbits, 0);
-
- ICE1712_STDSP24_SET_ADDR(spec->boxbits, 1);
- ICE1712_STDSP24_CLOCK(spec->boxbits, 1, 1);
- ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
- ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
- ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
-
- ICE1712_STDSP24_SET_ADDR(spec->boxbits, 2);
- ICE1712_STDSP24_CLOCK(spec->boxbits, 2, 1);
- ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
- ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
- ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0);
-
- ICE1712_STDSP24_SET_ADDR(spec->boxbits, 3);
- ICE1712_STDSP24_CLOCK(spec->boxbits, 3, 1);
- ICE1712_STDSP24_3_MIDI2(spec->boxbits, 0);
- ICE1712_STDSP24_3_MUTE(spec->boxbits, 1);
- ICE1712_STDSP24_3_INSEL(spec->boxbits, 0);
-
- /* let's go - activate only functions in first box */
- spec->config = 0;
- /* ICE1712_STDSP24_MUTE |
- ICE1712_STDSP24_INSEL |
- ICE1712_STDSP24_DAREAR; */
- /* These boxconfigs have caused problems in the past.
- * The code is not optimal, but should now enable a working config to
- * be achieved.
- * ** MIDI IN can only be configured on one box **
- * ICE1712_STDSP24_BOX_MIDI1 needs to be set for that box.
- * Tests on a ADAC2000 box suggest the box config flags do not
- * work as would be expected, and the inputs are crossed.
- * Setting ICE1712_STDSP24_BOX_MIDI1 and ICE1712_STDSP24_BOX_MIDI2
- * on the same box connects MIDI-In to both 401 uarts; both outputs
- * are then active on all boxes.
- * The default config here sets up everything on the first box.
- * Alan Horstmann 5.2.2008
- */
- spec->boxconfig[0] = ICE1712_STDSP24_BOX_CHN1 |
- ICE1712_STDSP24_BOX_CHN2 |
- ICE1712_STDSP24_BOX_CHN3 |
- ICE1712_STDSP24_BOX_CHN4 |
- ICE1712_STDSP24_BOX_MIDI1 |
- ICE1712_STDSP24_BOX_MIDI2;
- spec->boxconfig[1] =
- spec->boxconfig[2] =
- spec->boxconfig[3] = 0;
- snd_ice1712_stdsp24_darear(ice,
- (spec->config & ICE1712_STDSP24_DAREAR) ? 1 : 0);
- snd_ice1712_stdsp24_mute(ice,
- (spec->config & ICE1712_STDSP24_MUTE) ? 1 : 0);
- snd_ice1712_stdsp24_insel(ice,
- (spec->config & ICE1712_STDSP24_INSEL) ? 1 : 0);
- for (box = 0; box < 4; box++) {
- if (spec->boxconfig[box] & ICE1712_STDSP24_BOX_MIDI2)
- snd_ice1712_stdsp24_midi2(ice, 1);
- for (chn = 0; chn < 4; chn++)
- snd_ice1712_stdsp24_box_channel(ice, box, chn,
- (spec->boxconfig[box] & (1 << chn)) ? 1 : 0);
- if (spec->boxconfig[box] & ICE1712_STDSP24_BOX_MIDI1)
- snd_ice1712_stdsp24_box_midi(ice, box, 1);
- }
-
- return 0;
-}
-
-/*
- * AK4524 access
- */
-
-/* start callback for STDSP24 with modified hardware */
-static void stdsp24_ak4524_lock(struct snd_akm4xxx *ak, int chip)
-{
- struct snd_ice1712 *ice = ak->private_data[0];
- unsigned char tmp;
- snd_ice1712_save_gpio_status(ice);
- tmp = ICE1712_STDSP24_SERIAL_DATA |
- ICE1712_STDSP24_SERIAL_CLOCK |
- ICE1712_STDSP24_AK4524_CS;
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
- ice->gpio.direction | tmp);
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
-}
-
-static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice)
-{
- /* Hoontech STDSP24 with modified hardware */
- static struct snd_akm4xxx akm_stdsp24_mv __devinitdata = {
- .num_adcs = 2,
- .num_dacs = 2,
- .type = SND_AK4524,
- .ops = {
- .lock = stdsp24_ak4524_lock
- }
- };
-
- static struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = {
- .caddr = 2,
- .cif = 1, /* CIF high */
- .data_mask = ICE1712_STDSP24_SERIAL_DATA,
- .clk_mask = ICE1712_STDSP24_SERIAL_CLOCK,
- .cs_mask = ICE1712_STDSP24_AK4524_CS,
- .cs_addr = ICE1712_STDSP24_AK4524_CS,
- .cs_none = 0,
- .add_flags = 0,
- };
-
- int err;
- struct snd_akm4xxx *ak;
-
- /* set the analog DACs */
- ice->num_total_dacs = 2;
-
- /* set the analog ADCs */
- ice->num_total_adcs = 2;
-
- /* analog section */
- ak = ice->akm = kmalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
- if (! ak)
- return -ENOMEM;
- ice->akm_codecs = 1;
-
- err = snd_ice1712_akm4xxx_init(ak, &akm_stdsp24_mv, &akm_stdsp24_mv_priv, ice);
- if (err < 0)
- return err;
-
- /* ak4524 controls */
- err = snd_ice1712_akm4xxx_build_controls(ice);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static int __devinit snd_ice1712_ez8_init(struct snd_ice1712 *ice)
-{
- ice->gpio.write_mask = ice->eeprom.gpiomask;
- ice->gpio.direction = ice->eeprom.gpiodir;
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ice->eeprom.gpiomask);
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->eeprom.gpiodir);
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ice->eeprom.gpiostate);
- return 0;
-}
-
-
-/* entry point */
-struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = {
- {
- .subvendor = ICE1712_SUBDEVICE_STDSP24,
- .name = "Hoontech SoundTrack Audio DSP24",
- .model = "dsp24",
- .chip_init = snd_ice1712_hoontech_init,
- .mpu401_1_name = "MIDI-1 Hoontech/STA DSP24",
- .mpu401_2_name = "MIDI-2 Hoontech/STA DSP24",
- },
- {
- .subvendor = ICE1712_SUBDEVICE_STDSP24_VALUE, /* a dummy id */
- .name = "Hoontech SoundTrack Audio DSP24 Value",
- .model = "dsp24_value",
- .chip_init = snd_ice1712_value_init,
- },
- {
- .subvendor = ICE1712_SUBDEVICE_STDSP24_MEDIA7_1,
- .name = "Hoontech STA DSP24 Media 7.1",
- .model = "dsp24_71",
- .chip_init = snd_ice1712_hoontech_init,
- },
- {
- .subvendor = ICE1712_SUBDEVICE_EVENT_EZ8, /* a dummy id */
- .name = "Event Electronics EZ8",
- .model = "ez8",
- .chip_init = snd_ice1712_ez8_init,
- },
- { } /* terminator */
-};
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/hoontech.h b/ANDROID_3.4.5/sound/pci/ice1712/hoontech.h
deleted file mode 100644
index cc1da1e6..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/hoontech.h
+++ /dev/null
@@ -1,77 +0,0 @@
-#ifndef __SOUND_HOONTECH_H
-#define __SOUND_HOONTECH_H
-
-/*
- * ALSA driver for ICEnsemble ICE1712 (Envy24)
- *
- * Lowlevel functions for Hoontech STDSP24
- *
- * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define HOONTECH_DEVICE_DESC \
- "{Hoontech,SoundTrack DSP 24}," \
- "{Hoontech,SoundTrack DSP 24 Value}," \
- "{Hoontech,SoundTrack DSP 24 Media 7.1}," \
- "{Event Electronics,EZ8},"
-
-#define ICE1712_SUBDEVICE_STDSP24 0x12141217 /* Hoontech SoundTrack Audio DSP 24 */
-#define ICE1712_SUBDEVICE_STDSP24_VALUE 0x00010010 /* A dummy id for Hoontech SoundTrack Audio DSP 24 Value */
-#define ICE1712_SUBDEVICE_STDSP24_MEDIA7_1 0x16141217 /* Hoontech ST Audio DSP24 Media 7.1 */
-#define ICE1712_SUBDEVICE_EVENT_EZ8 0x00010001 /* A dummy id for EZ8 */
-
-extern struct snd_ice1712_card_info snd_ice1712_hoontech_cards[];
-
-
-/* Hoontech SoundTrack Audio DSP 24 GPIO definitions */
-
-#define ICE1712_STDSP24_0_BOX(r, x) r[0] = ((r[0] & ~3) | ((x)&3))
-#define ICE1712_STDSP24_0_DAREAR(r, x) r[0] = ((r[0] & ~4) | (((x)&1)<<2))
-#define ICE1712_STDSP24_1_CHN1(r, x) r[1] = ((r[1] & ~1) | ((x)&1))
-#define ICE1712_STDSP24_1_CHN2(r, x) r[1] = ((r[1] & ~2) | (((x)&1)<<1))
-#define ICE1712_STDSP24_1_CHN3(r, x) r[1] = ((r[1] & ~4) | (((x)&1)<<2))
-#define ICE1712_STDSP24_2_CHN4(r, x) r[2] = ((r[2] & ~1) | ((x)&1))
-#define ICE1712_STDSP24_2_MIDIIN(r, x) r[2] = ((r[2] & ~2) | (((x)&1)<<1))
-#define ICE1712_STDSP24_2_MIDI1(r, x) r[2] = ((r[2] & ~4) | (((x)&1)<<2))
-#define ICE1712_STDSP24_3_MIDI2(r, x) r[3] = ((r[3] & ~1) | ((x)&1))
-#define ICE1712_STDSP24_3_MUTE(r, x) r[3] = ((r[3] & ~2) | (((x)&1)<<1))
-#define ICE1712_STDSP24_3_INSEL(r, x) r[3] = ((r[3] & ~4) | (((x)&1)<<2))
-#define ICE1712_STDSP24_SET_ADDR(r, a) r[a&3] = ((r[a&3] & ~0x18) | (((a)&3)<<3))
-#define ICE1712_STDSP24_CLOCK(r, a, c) r[a&3] = ((r[a&3] & ~0x20) | (((c)&1)<<5))
-#define ICE1712_STDSP24_CLOCK_BIT (1<<5)
-
-/* Hoontech SoundTrack Audio DSP 24 box configuration definitions */
-
-#define ICE1712_STDSP24_DAREAR (1<<0)
-#define ICE1712_STDSP24_MUTE (1<<1)
-#define ICE1712_STDSP24_INSEL (1<<2)
-
-#define ICE1712_STDSP24_BOX_CHN1 (1<<0) /* input channel 1 */
-#define ICE1712_STDSP24_BOX_CHN2 (1<<1) /* input channel 2 */
-#define ICE1712_STDSP24_BOX_CHN3 (1<<2) /* input channel 3 */
-#define ICE1712_STDSP24_BOX_CHN4 (1<<3) /* input channel 4 */
-#define ICE1712_STDSP24_BOX_MIDI1 (1<<8)
-#define ICE1712_STDSP24_BOX_MIDI2 (1<<9)
-
-/* Hoontech SoundTrack Audio DSP 24 Value definitions for modified hardware */
-
-#define ICE1712_STDSP24_AK4524_CS 0x03 /* AK4524 chip select; low = active */
-#define ICE1712_STDSP24_SERIAL_DATA 0x0c /* ak4524 data */
-#define ICE1712_STDSP24_SERIAL_CLOCK 0x30 /* ak4524 clock */
-
-#endif /* __SOUND_HOONTECH_H */
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/ice1712.c b/ANDROID_3.4.5/sound/pci/ice1712/ice1712.c
deleted file mode 100644
index 132a86e0..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/ice1712.c
+++ /dev/null
@@ -1,2824 +0,0 @@
-/*
- * ALSA driver for ICEnsemble ICE1712 (Envy24)
- *
- * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- NOTES:
- - spdif nonaudio consumer mode does not work (at least with my
- Sony STR-DB830)
-*/
-
-/*
- * Changes:
- *
- * 2002.09.09 Takashi Iwai <tiwai@suse.de>
- * split the code to several files. each low-level routine
- * is stored in the local file and called from registration
- * function from card_info struct.
- *
- * 2002.11.26 James Stafford <jstafford@ampltd.com>
- * Added support for VT1724 (Envy24HT)
- * I have left out support for 176.4 and 192 KHz for the moment.
- * I also haven't done anything with the internal S/PDIF transmitter or the MPU-401
- *
- * 2003.02.20 Taksahi Iwai <tiwai@suse.de>
- * Split vt1724 part to an independent driver.
- * The GPIO is accessed through the callback functions now.
- *
- * 2004.03.31 Doug McLain <nostar@comcast.net>
- * Added support for Event Electronics EZ8 card to hoontech.c.
- */
-
-
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-
-#include <sound/core.h>
-#include <sound/cs8427.h>
-#include <sound/info.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include <sound/asoundef.h>
-
-#include "ice1712.h"
-
-/* lowlevel routines */
-#include "delta.h"
-#include "ews.h"
-#include "hoontech.h"
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("ICEnsemble ICE1712 (Envy24)");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{"
- HOONTECH_DEVICE_DESC
- DELTA_DEVICE_DESC
- EWS_DEVICE_DESC
- "{ICEnsemble,Generic ICE1712},"
- "{ICEnsemble,Generic Envy24}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
-static char *model[SNDRV_CARDS];
-static bool omni[SNDRV_CARDS]; /* Delta44 & 66 Omni I/O support */
-static int cs8427_timeout[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 500}; /* CS8427 S/PDIF transceiver reset timeout value in msec */
-static int dxr_enable[SNDRV_CARDS]; /* DXR enable for DMX6FIRE */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for ICE1712 soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for ICE1712 soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable ICE1712 soundcard.");
-module_param_array(omni, bool, NULL, 0444);
-MODULE_PARM_DESC(omni, "Enable Midiman M-Audio Delta Omni I/O support.");
-module_param_array(cs8427_timeout, int, NULL, 0444);
-MODULE_PARM_DESC(cs8427_timeout, "Define reset timeout for cs8427 chip in msec resolution.");
-module_param_array(model, charp, NULL, 0444);
-MODULE_PARM_DESC(model, "Use the given board model.");
-module_param_array(dxr_enable, int, NULL, 0444);
-MODULE_PARM_DESC(dxr_enable, "Enable DXR support for Terratec DMX6FIRE.");
-
-
-static DEFINE_PCI_DEVICE_TABLE(snd_ice1712_ids) = {
- { PCI_VDEVICE(ICE, PCI_DEVICE_ID_ICE_1712), 0 }, /* ICE1712 */
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_ice1712_ids);
-
-static int snd_ice1712_build_pro_mixer(struct snd_ice1712 *ice);
-static int snd_ice1712_build_controls(struct snd_ice1712 *ice);
-
-static int PRO_RATE_LOCKED;
-static int PRO_RATE_RESET = 1;
-static unsigned int PRO_RATE_DEFAULT = 44100;
-
-/*
- * Basic I/O
- */
-
-/* check whether the clock mode is spdif-in */
-static inline int is_spdif_master(struct snd_ice1712 *ice)
-{
- return (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER) ? 1 : 0;
-}
-
-static inline int is_pro_rate_locked(struct snd_ice1712 *ice)
-{
- return is_spdif_master(ice) || PRO_RATE_LOCKED;
-}
-
-static inline void snd_ice1712_ds_write(struct snd_ice1712 *ice, u8 channel, u8 addr, u32 data)
-{
- outb((channel << 4) | addr, ICEDS(ice, INDEX));
- outl(data, ICEDS(ice, DATA));
-}
-
-static inline u32 snd_ice1712_ds_read(struct snd_ice1712 *ice, u8 channel, u8 addr)
-{
- outb((channel << 4) | addr, ICEDS(ice, INDEX));
- return inl(ICEDS(ice, DATA));
-}
-
-static void snd_ice1712_ac97_write(struct snd_ac97 *ac97,
- unsigned short reg,
- unsigned short val)
-{
- struct snd_ice1712 *ice = ac97->private_data;
- int tm;
- unsigned char old_cmd = 0;
-
- for (tm = 0; tm < 0x10000; tm++) {
- old_cmd = inb(ICEREG(ice, AC97_CMD));
- if (old_cmd & (ICE1712_AC97_WRITE | ICE1712_AC97_READ))
- continue;
- if (!(old_cmd & ICE1712_AC97_READY))
- continue;
- break;
- }
- outb(reg, ICEREG(ice, AC97_INDEX));
- outw(val, ICEREG(ice, AC97_DATA));
- old_cmd &= ~(ICE1712_AC97_PBK_VSR | ICE1712_AC97_CAP_VSR);
- outb(old_cmd | ICE1712_AC97_WRITE, ICEREG(ice, AC97_CMD));
- for (tm = 0; tm < 0x10000; tm++)
- if ((inb(ICEREG(ice, AC97_CMD)) & ICE1712_AC97_WRITE) == 0)
- break;
-}
-
-static unsigned short snd_ice1712_ac97_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- struct snd_ice1712 *ice = ac97->private_data;
- int tm;
- unsigned char old_cmd = 0;
-
- for (tm = 0; tm < 0x10000; tm++) {
- old_cmd = inb(ICEREG(ice, AC97_CMD));
- if (old_cmd & (ICE1712_AC97_WRITE | ICE1712_AC97_READ))
- continue;
- if (!(old_cmd & ICE1712_AC97_READY))
- continue;
- break;
- }
- outb(reg, ICEREG(ice, AC97_INDEX));
- outb(old_cmd | ICE1712_AC97_READ, ICEREG(ice, AC97_CMD));
- for (tm = 0; tm < 0x10000; tm++)
- if ((inb(ICEREG(ice, AC97_CMD)) & ICE1712_AC97_READ) == 0)
- break;
- if (tm >= 0x10000) /* timeout */
- return ~0;
- return inw(ICEREG(ice, AC97_DATA));
-}
-
-/*
- * pro ac97 section
- */
-
-static void snd_ice1712_pro_ac97_write(struct snd_ac97 *ac97,
- unsigned short reg,
- unsigned short val)
-{
- struct snd_ice1712 *ice = ac97->private_data;
- int tm;
- unsigned char old_cmd = 0;
-
- for (tm = 0; tm < 0x10000; tm++) {
- old_cmd = inb(ICEMT(ice, AC97_CMD));
- if (old_cmd & (ICE1712_AC97_WRITE | ICE1712_AC97_READ))
- continue;
- if (!(old_cmd & ICE1712_AC97_READY))
- continue;
- break;
- }
- outb(reg, ICEMT(ice, AC97_INDEX));
- outw(val, ICEMT(ice, AC97_DATA));
- old_cmd &= ~(ICE1712_AC97_PBK_VSR | ICE1712_AC97_CAP_VSR);
- outb(old_cmd | ICE1712_AC97_WRITE, ICEMT(ice, AC97_CMD));
- for (tm = 0; tm < 0x10000; tm++)
- if ((inb(ICEMT(ice, AC97_CMD)) & ICE1712_AC97_WRITE) == 0)
- break;
-}
-
-
-static unsigned short snd_ice1712_pro_ac97_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- struct snd_ice1712 *ice = ac97->private_data;
- int tm;
- unsigned char old_cmd = 0;
-
- for (tm = 0; tm < 0x10000; tm++) {
- old_cmd = inb(ICEMT(ice, AC97_CMD));
- if (old_cmd & (ICE1712_AC97_WRITE | ICE1712_AC97_READ))
- continue;
- if (!(old_cmd & ICE1712_AC97_READY))
- continue;
- break;
- }
- outb(reg, ICEMT(ice, AC97_INDEX));
- outb(old_cmd | ICE1712_AC97_READ, ICEMT(ice, AC97_CMD));
- for (tm = 0; tm < 0x10000; tm++)
- if ((inb(ICEMT(ice, AC97_CMD)) & ICE1712_AC97_READ) == 0)
- break;
- if (tm >= 0x10000) /* timeout */
- return ~0;
- return inw(ICEMT(ice, AC97_DATA));
-}
-
-/*
- * consumer ac97 digital mix
- */
-#define snd_ice1712_digmix_route_ac97_info snd_ctl_boolean_mono_info
-
-static int snd_ice1712_digmix_route_ac97_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = inb(ICEMT(ice, MONITOR_ROUTECTRL)) & ICE1712_ROUTE_AC97 ? 1 : 0;
- return 0;
-}
-
-static int snd_ice1712_digmix_route_ac97_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char val, nval;
-
- spin_lock_irq(&ice->reg_lock);
- val = inb(ICEMT(ice, MONITOR_ROUTECTRL));
- nval = val & ~ICE1712_ROUTE_AC97;
- if (ucontrol->value.integer.value[0])
- nval |= ICE1712_ROUTE_AC97;
- outb(nval, ICEMT(ice, MONITOR_ROUTECTRL));
- spin_unlock_irq(&ice->reg_lock);
- return val != nval;
-}
-
-static struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Digital Mixer To AC97",
- .info = snd_ice1712_digmix_route_ac97_info,
- .get = snd_ice1712_digmix_route_ac97_get,
- .put = snd_ice1712_digmix_route_ac97_put,
-};
-
-
-/*
- * gpio operations
- */
-static void snd_ice1712_set_gpio_dir(struct snd_ice1712 *ice, unsigned int data)
-{
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, data);
- inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */
-}
-
-static unsigned int snd_ice1712_get_gpio_dir(struct snd_ice1712 *ice)
-{
- return snd_ice1712_read(ice, ICE1712_IREG_GPIO_DIRECTION);
-}
-
-static unsigned int snd_ice1712_get_gpio_mask(struct snd_ice1712 *ice)
-{
- return snd_ice1712_read(ice, ICE1712_IREG_GPIO_WRITE_MASK);
-}
-
-static void snd_ice1712_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data)
-{
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, data);
- inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */
-}
-
-static unsigned int snd_ice1712_get_gpio_data(struct snd_ice1712 *ice)
-{
- return snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
-}
-
-static void snd_ice1712_set_gpio_data(struct snd_ice1712 *ice, unsigned int val)
-{
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, val);
- inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */
-}
-
-/*
- *
- * CS8427 interface
- *
- */
-
-/*
- * change the input clock selection
- * spdif_clock = 1 - IEC958 input, 0 - Envy24
- */
-static int snd_ice1712_cs8427_set_input_clock(struct snd_ice1712 *ice, int spdif_clock)
-{
- unsigned char reg[2] = { 0x80 | 4, 0 }; /* CS8427 auto increment | register number 4 + data */
- unsigned char val, nval;
- int res = 0;
-
- snd_i2c_lock(ice->i2c);
- if (snd_i2c_sendbytes(ice->cs8427, reg, 1) != 1) {
- snd_i2c_unlock(ice->i2c);
- return -EIO;
- }
- if (snd_i2c_readbytes(ice->cs8427, &val, 1) != 1) {
- snd_i2c_unlock(ice->i2c);
- return -EIO;
- }
- nval = val & 0xf0;
- if (spdif_clock)
- nval |= 0x01;
- else
- nval |= 0x04;
- if (val != nval) {
- reg[1] = nval;
- if (snd_i2c_sendbytes(ice->cs8427, reg, 2) != 2) {
- res = -EIO;
- } else {
- res++;
- }
- }
- snd_i2c_unlock(ice->i2c);
- return res;
-}
-
-/*
- * spdif callbacks
- */
-static void open_cs8427(struct snd_ice1712 *ice, struct snd_pcm_substream *substream)
-{
- snd_cs8427_iec958_active(ice->cs8427, 1);
-}
-
-static void close_cs8427(struct snd_ice1712 *ice, struct snd_pcm_substream *substream)
-{
- snd_cs8427_iec958_active(ice->cs8427, 0);
-}
-
-static void setup_cs8427(struct snd_ice1712 *ice, int rate)
-{
- snd_cs8427_iec958_pcm(ice->cs8427, rate);
-}
-
-/*
- * create and initialize callbacks for cs8427 interface
- */
-int __devinit snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr)
-{
- int err;
-
- err = snd_cs8427_create(ice->i2c, addr,
- (ice->cs8427_timeout * HZ) / 1000, &ice->cs8427);
- if (err < 0) {
- snd_printk(KERN_ERR "CS8427 initialization failed\n");
- return err;
- }
- ice->spdif.ops.open = open_cs8427;
- ice->spdif.ops.close = close_cs8427;
- ice->spdif.ops.setup_rate = setup_cs8427;
- return 0;
-}
-
-static void snd_ice1712_set_input_clock_source(struct snd_ice1712 *ice, int spdif_is_master)
-{
- /* change CS8427 clock source too */
- if (ice->cs8427)
- snd_ice1712_cs8427_set_input_clock(ice, spdif_is_master);
- /* notify ak4524 chip as well */
- if (spdif_is_master) {
- unsigned int i;
- for (i = 0; i < ice->akm_codecs; i++) {
- if (ice->akm[i].ops.set_rate_val)
- ice->akm[i].ops.set_rate_val(&ice->akm[i], 0);
- }
- }
-}
-
-/*
- * Interrupt handler
- */
-
-static irqreturn_t snd_ice1712_interrupt(int irq, void *dev_id)
-{
- struct snd_ice1712 *ice = dev_id;
- unsigned char status;
- int handled = 0;
-
- while (1) {
- status = inb(ICEREG(ice, IRQSTAT));
- if (status == 0)
- break;
- handled = 1;
- if (status & ICE1712_IRQ_MPU1) {
- if (ice->rmidi[0])
- snd_mpu401_uart_interrupt(irq, ice->rmidi[0]->private_data);
- outb(ICE1712_IRQ_MPU1, ICEREG(ice, IRQSTAT));
- status &= ~ICE1712_IRQ_MPU1;
- }
- if (status & ICE1712_IRQ_TIMER)
- outb(ICE1712_IRQ_TIMER, ICEREG(ice, IRQSTAT));
- if (status & ICE1712_IRQ_MPU2) {
- if (ice->rmidi[1])
- snd_mpu401_uart_interrupt(irq, ice->rmidi[1]->private_data);
- outb(ICE1712_IRQ_MPU2, ICEREG(ice, IRQSTAT));
- status &= ~ICE1712_IRQ_MPU2;
- }
- if (status & ICE1712_IRQ_PROPCM) {
- unsigned char mtstat = inb(ICEMT(ice, IRQ));
- if (mtstat & ICE1712_MULTI_PBKSTATUS) {
- if (ice->playback_pro_substream)
- snd_pcm_period_elapsed(ice->playback_pro_substream);
- outb(ICE1712_MULTI_PBKSTATUS, ICEMT(ice, IRQ));
- }
- if (mtstat & ICE1712_MULTI_CAPSTATUS) {
- if (ice->capture_pro_substream)
- snd_pcm_period_elapsed(ice->capture_pro_substream);
- outb(ICE1712_MULTI_CAPSTATUS, ICEMT(ice, IRQ));
- }
- }
- if (status & ICE1712_IRQ_FM)
- outb(ICE1712_IRQ_FM, ICEREG(ice, IRQSTAT));
- if (status & ICE1712_IRQ_PBKDS) {
- u32 idx;
- u16 pbkstatus;
- struct snd_pcm_substream *substream;
- pbkstatus = inw(ICEDS(ice, INTSTAT));
- /* printk(KERN_DEBUG "pbkstatus = 0x%x\n", pbkstatus); */
- for (idx = 0; idx < 6; idx++) {
- if ((pbkstatus & (3 << (idx * 2))) == 0)
- continue;
- substream = ice->playback_con_substream_ds[idx];
- if (substream != NULL)
- snd_pcm_period_elapsed(substream);
- outw(3 << (idx * 2), ICEDS(ice, INTSTAT));
- }
- outb(ICE1712_IRQ_PBKDS, ICEREG(ice, IRQSTAT));
- }
- if (status & ICE1712_IRQ_CONCAP) {
- if (ice->capture_con_substream)
- snd_pcm_period_elapsed(ice->capture_con_substream);
- outb(ICE1712_IRQ_CONCAP, ICEREG(ice, IRQSTAT));
- }
- if (status & ICE1712_IRQ_CONPBK) {
- if (ice->playback_con_substream)
- snd_pcm_period_elapsed(ice->playback_con_substream);
- outb(ICE1712_IRQ_CONPBK, ICEREG(ice, IRQSTAT));
- }
- }
- return IRQ_RETVAL(handled);
-}
-
-
-/*
- * PCM part - misc
- */
-
-static int snd_ice1712_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static int snd_ice1712_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-/*
- * PCM part - consumer I/O
- */
-
-static int snd_ice1712_playback_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- int result = 0;
- u32 tmp;
-
- spin_lock(&ice->reg_lock);
- tmp = snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL);
- if (cmd == SNDRV_PCM_TRIGGER_START) {
- tmp |= 1;
- } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
- tmp &= ~1;
- } else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH) {
- tmp |= 2;
- } else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE) {
- tmp &= ~2;
- } else {
- result = -EINVAL;
- }
- snd_ice1712_write(ice, ICE1712_IREG_PBK_CTRL, tmp);
- spin_unlock(&ice->reg_lock);
- return result;
-}
-
-static int snd_ice1712_playback_ds_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- int result = 0;
- u32 tmp;
-
- spin_lock(&ice->reg_lock);
- tmp = snd_ice1712_ds_read(ice, substream->number * 2, ICE1712_DSC_CONTROL);
- if (cmd == SNDRV_PCM_TRIGGER_START) {
- tmp |= 1;
- } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
- tmp &= ~1;
- } else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH) {
- tmp |= 2;
- } else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE) {
- tmp &= ~2;
- } else {
- result = -EINVAL;
- }
- snd_ice1712_ds_write(ice, substream->number * 2, ICE1712_DSC_CONTROL, tmp);
- spin_unlock(&ice->reg_lock);
- return result;
-}
-
-static int snd_ice1712_capture_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- int result = 0;
- u8 tmp;
-
- spin_lock(&ice->reg_lock);
- tmp = snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL);
- if (cmd == SNDRV_PCM_TRIGGER_START) {
- tmp |= 1;
- } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
- tmp &= ~1;
- } else {
- result = -EINVAL;
- }
- snd_ice1712_write(ice, ICE1712_IREG_CAP_CTRL, tmp);
- spin_unlock(&ice->reg_lock);
- return result;
-}
-
-static int snd_ice1712_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- u32 period_size, buf_size, rate, tmp;
-
- period_size = (snd_pcm_lib_period_bytes(substream) >> 2) - 1;
- buf_size = snd_pcm_lib_buffer_bytes(substream) - 1;
- tmp = 0x0000;
- if (snd_pcm_format_width(runtime->format) == 16)
- tmp |= 0x10;
- if (runtime->channels == 2)
- tmp |= 0x08;
- rate = (runtime->rate * 8192) / 375;
- if (rate > 0x000fffff)
- rate = 0x000fffff;
- spin_lock_irq(&ice->reg_lock);
- outb(0, ice->ddma_port + 15);
- outb(ICE1712_DMA_MODE_WRITE | ICE1712_DMA_AUTOINIT, ice->ddma_port + 0x0b);
- outl(runtime->dma_addr, ice->ddma_port + 0);
- outw(buf_size, ice->ddma_port + 4);
- snd_ice1712_write(ice, ICE1712_IREG_PBK_RATE_LO, rate & 0xff);
- snd_ice1712_write(ice, ICE1712_IREG_PBK_RATE_MID, (rate >> 8) & 0xff);
- snd_ice1712_write(ice, ICE1712_IREG_PBK_RATE_HI, (rate >> 16) & 0xff);
- snd_ice1712_write(ice, ICE1712_IREG_PBK_CTRL, tmp);
- snd_ice1712_write(ice, ICE1712_IREG_PBK_COUNT_LO, period_size & 0xff);
- snd_ice1712_write(ice, ICE1712_IREG_PBK_COUNT_HI, period_size >> 8);
- snd_ice1712_write(ice, ICE1712_IREG_PBK_LEFT, 0);
- snd_ice1712_write(ice, ICE1712_IREG_PBK_RIGHT, 0);
- spin_unlock_irq(&ice->reg_lock);
- return 0;
-}
-
-static int snd_ice1712_playback_ds_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- u32 period_size, buf_size, rate, tmp, chn;
-
- period_size = snd_pcm_lib_period_bytes(substream) - 1;
- buf_size = snd_pcm_lib_buffer_bytes(substream) - 1;
- tmp = 0x0064;
- if (snd_pcm_format_width(runtime->format) == 16)
- tmp &= ~0x04;
- if (runtime->channels == 2)
- tmp |= 0x08;
- rate = (runtime->rate * 8192) / 375;
- if (rate > 0x000fffff)
- rate = 0x000fffff;
- ice->playback_con_active_buf[substream->number] = 0;
- ice->playback_con_virt_addr[substream->number] = runtime->dma_addr;
- chn = substream->number * 2;
- spin_lock_irq(&ice->reg_lock);
- snd_ice1712_ds_write(ice, chn, ICE1712_DSC_ADDR0, runtime->dma_addr);
- snd_ice1712_ds_write(ice, chn, ICE1712_DSC_COUNT0, period_size);
- snd_ice1712_ds_write(ice, chn, ICE1712_DSC_ADDR1, runtime->dma_addr + (runtime->periods > 1 ? period_size + 1 : 0));
- snd_ice1712_ds_write(ice, chn, ICE1712_DSC_COUNT1, period_size);
- snd_ice1712_ds_write(ice, chn, ICE1712_DSC_RATE, rate);
- snd_ice1712_ds_write(ice, chn, ICE1712_DSC_VOLUME, 0);
- snd_ice1712_ds_write(ice, chn, ICE1712_DSC_CONTROL, tmp);
- if (runtime->channels == 2) {
- snd_ice1712_ds_write(ice, chn + 1, ICE1712_DSC_RATE, rate);
- snd_ice1712_ds_write(ice, chn + 1, ICE1712_DSC_VOLUME, 0);
- }
- spin_unlock_irq(&ice->reg_lock);
- return 0;
-}
-
-static int snd_ice1712_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- u32 period_size, buf_size;
- u8 tmp;
-
- period_size = (snd_pcm_lib_period_bytes(substream) >> 2) - 1;
- buf_size = snd_pcm_lib_buffer_bytes(substream) - 1;
- tmp = 0x06;
- if (snd_pcm_format_width(runtime->format) == 16)
- tmp &= ~0x04;
- if (runtime->channels == 2)
- tmp &= ~0x02;
- spin_lock_irq(&ice->reg_lock);
- outl(ice->capture_con_virt_addr = runtime->dma_addr, ICEREG(ice, CONCAP_ADDR));
- outw(buf_size, ICEREG(ice, CONCAP_COUNT));
- snd_ice1712_write(ice, ICE1712_IREG_CAP_COUNT_HI, period_size >> 8);
- snd_ice1712_write(ice, ICE1712_IREG_CAP_COUNT_LO, period_size & 0xff);
- snd_ice1712_write(ice, ICE1712_IREG_CAP_CTRL, tmp);
- spin_unlock_irq(&ice->reg_lock);
- snd_ac97_set_rate(ice->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
- return 0;
-}
-
-static snd_pcm_uframes_t snd_ice1712_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- size_t ptr;
-
- if (!(snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL) & 1))
- return 0;
- ptr = runtime->buffer_size - inw(ice->ddma_port + 4);
- if (ptr == runtime->buffer_size)
- ptr = 0;
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-static snd_pcm_uframes_t snd_ice1712_playback_ds_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- u8 addr;
- size_t ptr;
-
- if (!(snd_ice1712_ds_read(ice, substream->number * 2, ICE1712_DSC_CONTROL) & 1))
- return 0;
- if (ice->playback_con_active_buf[substream->number])
- addr = ICE1712_DSC_ADDR1;
- else
- addr = ICE1712_DSC_ADDR0;
- ptr = snd_ice1712_ds_read(ice, substream->number * 2, addr) -
- ice->playback_con_virt_addr[substream->number];
- if (ptr == substream->runtime->buffer_size)
- ptr = 0;
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-static snd_pcm_uframes_t snd_ice1712_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- size_t ptr;
-
- if (!(snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL) & 1))
- return 0;
- ptr = inl(ICEREG(ice, CONCAP_ADDR)) - ice->capture_con_virt_addr;
- if (ptr == substream->runtime->buffer_size)
- ptr = 0;
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-static const struct snd_pcm_hardware snd_ice1712_playback = {
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (64*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (64*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static const struct snd_pcm_hardware snd_ice1712_playback_ds = {
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 2,
- .periods_max = 2,
- .fifo_size = 0,
-};
-
-static const struct snd_pcm_hardware snd_ice1712_capture = {
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (64*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (64*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static int snd_ice1712_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
-
- ice->playback_con_substream = substream;
- runtime->hw = snd_ice1712_playback;
- return 0;
-}
-
-static int snd_ice1712_playback_ds_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- u32 tmp;
-
- ice->playback_con_substream_ds[substream->number] = substream;
- runtime->hw = snd_ice1712_playback_ds;
- spin_lock_irq(&ice->reg_lock);
- tmp = inw(ICEDS(ice, INTMASK)) & ~(1 << (substream->number * 2));
- outw(tmp, ICEDS(ice, INTMASK));
- spin_unlock_irq(&ice->reg_lock);
- return 0;
-}
-
-static int snd_ice1712_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
-
- ice->capture_con_substream = substream;
- runtime->hw = snd_ice1712_capture;
- runtime->hw.rates = ice->ac97->rates[AC97_RATES_ADC];
- if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000))
- runtime->hw.rate_min = 48000;
- return 0;
-}
-
-static int snd_ice1712_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
-
- ice->playback_con_substream = NULL;
- return 0;
-}
-
-static int snd_ice1712_playback_ds_close(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- u32 tmp;
-
- spin_lock_irq(&ice->reg_lock);
- tmp = inw(ICEDS(ice, INTMASK)) | (3 << (substream->number * 2));
- outw(tmp, ICEDS(ice, INTMASK));
- spin_unlock_irq(&ice->reg_lock);
- ice->playback_con_substream_ds[substream->number] = NULL;
- return 0;
-}
-
-static int snd_ice1712_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
-
- ice->capture_con_substream = NULL;
- return 0;
-}
-
-static struct snd_pcm_ops snd_ice1712_playback_ops = {
- .open = snd_ice1712_playback_open,
- .close = snd_ice1712_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ice1712_hw_params,
- .hw_free = snd_ice1712_hw_free,
- .prepare = snd_ice1712_playback_prepare,
- .trigger = snd_ice1712_playback_trigger,
- .pointer = snd_ice1712_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_ice1712_playback_ds_ops = {
- .open = snd_ice1712_playback_ds_open,
- .close = snd_ice1712_playback_ds_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ice1712_hw_params,
- .hw_free = snd_ice1712_hw_free,
- .prepare = snd_ice1712_playback_ds_prepare,
- .trigger = snd_ice1712_playback_ds_trigger,
- .pointer = snd_ice1712_playback_ds_pointer,
-};
-
-static struct snd_pcm_ops snd_ice1712_capture_ops = {
- .open = snd_ice1712_capture_open,
- .close = snd_ice1712_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ice1712_hw_params,
- .hw_free = snd_ice1712_hw_free,
- .prepare = snd_ice1712_capture_prepare,
- .trigger = snd_ice1712_capture_trigger,
- .pointer = snd_ice1712_capture_pointer,
-};
-
-static int __devinit snd_ice1712_pcm(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
- err = snd_pcm_new(ice->card, "ICE1712 consumer", device, 1, 1, &pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ice1712_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ice1712_capture_ops);
-
- pcm->private_data = ice;
- pcm->info_flags = 0;
- strcpy(pcm->name, "ICE1712 consumer");
- ice->pcm = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(ice->pci), 64*1024, 64*1024);
-
- if (rpcm)
- *rpcm = pcm;
-
- printk(KERN_WARNING "Consumer PCM code does not work well at the moment --jk\n");
-
- return 0;
-}
-
-static int __devinit snd_ice1712_pcm_ds(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
- err = snd_pcm_new(ice->card, "ICE1712 consumer (DS)", device, 6, 0, &pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ice1712_playback_ds_ops);
-
- pcm->private_data = ice;
- pcm->info_flags = 0;
- strcpy(pcm->name, "ICE1712 consumer (DS)");
- ice->pcm_ds = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(ice->pci), 64*1024, 128*1024);
-
- if (rpcm)
- *rpcm = pcm;
-
- return 0;
-}
-
-/*
- * PCM code - professional part (multitrack)
- */
-
-static unsigned int rates[] = { 8000, 9600, 11025, 12000, 16000, 22050, 24000,
- 32000, 44100, 48000, 64000, 88200, 96000 };
-
-static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
- .count = ARRAY_SIZE(rates),
- .list = rates,
- .mask = 0,
-};
-
-static int snd_ice1712_pro_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- {
- unsigned int what;
- unsigned int old;
- if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
- return -EINVAL;
- what = ICE1712_PLAYBACK_PAUSE;
- snd_pcm_trigger_done(substream, substream);
- spin_lock(&ice->reg_lock);
- old = inl(ICEMT(ice, PLAYBACK_CONTROL));
- if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
- old |= what;
- else
- old &= ~what;
- outl(old, ICEMT(ice, PLAYBACK_CONTROL));
- spin_unlock(&ice->reg_lock);
- break;
- }
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_STOP:
- {
- unsigned int what = 0;
- unsigned int old;
- struct snd_pcm_substream *s;
-
- snd_pcm_group_for_each_entry(s, substream) {
- if (s == ice->playback_pro_substream) {
- what |= ICE1712_PLAYBACK_START;
- snd_pcm_trigger_done(s, substream);
- } else if (s == ice->capture_pro_substream) {
- what |= ICE1712_CAPTURE_START_SHADOW;
- snd_pcm_trigger_done(s, substream);
- }
- }
- spin_lock(&ice->reg_lock);
- old = inl(ICEMT(ice, PLAYBACK_CONTROL));
- if (cmd == SNDRV_PCM_TRIGGER_START)
- old |= what;
- else
- old &= ~what;
- outl(old, ICEMT(ice, PLAYBACK_CONTROL));
- spin_unlock(&ice->reg_lock);
- break;
- }
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-/*
- */
-static void snd_ice1712_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate, int force)
-{
- unsigned long flags;
- unsigned char val, old;
- unsigned int i;
-
- switch (rate) {
- case 8000: val = 6; break;
- case 9600: val = 3; break;
- case 11025: val = 10; break;
- case 12000: val = 2; break;
- case 16000: val = 5; break;
- case 22050: val = 9; break;
- case 24000: val = 1; break;
- case 32000: val = 4; break;
- case 44100: val = 8; break;
- case 48000: val = 0; break;
- case 64000: val = 15; break;
- case 88200: val = 11; break;
- case 96000: val = 7; break;
- default:
- snd_BUG();
- val = 0;
- rate = 48000;
- break;
- }
-
- spin_lock_irqsave(&ice->reg_lock, flags);
- if (inb(ICEMT(ice, PLAYBACK_CONTROL)) & (ICE1712_CAPTURE_START_SHADOW|
- ICE1712_PLAYBACK_PAUSE|
- ICE1712_PLAYBACK_START)) {
-__out:
- spin_unlock_irqrestore(&ice->reg_lock, flags);
- return;
- }
- if (!force && is_pro_rate_locked(ice))
- goto __out;
-
- old = inb(ICEMT(ice, RATE));
- if (!force && old == val)
- goto __out;
- outb(val, ICEMT(ice, RATE));
- spin_unlock_irqrestore(&ice->reg_lock, flags);
-
- if (ice->gpio.set_pro_rate)
- ice->gpio.set_pro_rate(ice, rate);
- for (i = 0; i < ice->akm_codecs; i++) {
- if (ice->akm[i].ops.set_rate_val)
- ice->akm[i].ops.set_rate_val(&ice->akm[i], rate);
- }
- if (ice->spdif.ops.setup_rate)
- ice->spdif.ops.setup_rate(ice, rate);
-}
-
-static int snd_ice1712_playback_pro_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
-
- ice->playback_pro_size = snd_pcm_lib_buffer_bytes(substream);
- spin_lock_irq(&ice->reg_lock);
- outl(substream->runtime->dma_addr, ICEMT(ice, PLAYBACK_ADDR));
- outw((ice->playback_pro_size >> 2) - 1, ICEMT(ice, PLAYBACK_SIZE));
- outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ICEMT(ice, PLAYBACK_COUNT));
- spin_unlock_irq(&ice->reg_lock);
-
- return 0;
-}
-
-static int snd_ice1712_playback_pro_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
-
- snd_ice1712_set_pro_rate(ice, params_rate(hw_params), 0);
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static int snd_ice1712_capture_pro_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
-
- ice->capture_pro_size = snd_pcm_lib_buffer_bytes(substream);
- spin_lock_irq(&ice->reg_lock);
- outl(substream->runtime->dma_addr, ICEMT(ice, CAPTURE_ADDR));
- outw((ice->capture_pro_size >> 2) - 1, ICEMT(ice, CAPTURE_SIZE));
- outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ICEMT(ice, CAPTURE_COUNT));
- spin_unlock_irq(&ice->reg_lock);
- return 0;
-}
-
-static int snd_ice1712_capture_pro_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
-
- snd_ice1712_set_pro_rate(ice, params_rate(hw_params), 0);
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static snd_pcm_uframes_t snd_ice1712_playback_pro_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- size_t ptr;
-
- if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_PLAYBACK_START))
- return 0;
- ptr = ice->playback_pro_size - (inw(ICEMT(ice, PLAYBACK_SIZE)) << 2);
- if (ptr == substream->runtime->buffer_size)
- ptr = 0;
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- size_t ptr;
-
- if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_CAPTURE_START_SHADOW))
- return 0;
- ptr = ice->capture_pro_size - (inw(ICEMT(ice, CAPTURE_SIZE)) << 2);
- if (ptr == substream->runtime->buffer_size)
- ptr = 0;
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-static const struct snd_pcm_hardware snd_ice1712_playback_pro = {
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000,
- .rate_min = 4000,
- .rate_max = 96000,
- .channels_min = 10,
- .channels_max = 10,
- .buffer_bytes_max = (256*1024),
- .period_bytes_min = 10 * 4 * 2,
- .period_bytes_max = 131040,
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static const struct snd_pcm_hardware snd_ice1712_capture_pro = {
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000,
- .rate_min = 4000,
- .rate_max = 96000,
- .channels_min = 12,
- .channels_max = 12,
- .buffer_bytes_max = (256*1024),
- .period_bytes_min = 12 * 4 * 2,
- .period_bytes_max = 131040,
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static int snd_ice1712_playback_pro_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
-
- ice->playback_pro_substream = substream;
- runtime->hw = snd_ice1712_playback_pro;
- snd_pcm_set_sync(substream);
- snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
- if (is_pro_rate_locked(ice)) {
- runtime->hw.rate_min = PRO_RATE_DEFAULT;
- runtime->hw.rate_max = PRO_RATE_DEFAULT;
- }
-
- if (ice->spdif.ops.open)
- ice->spdif.ops.open(ice, substream);
-
- return 0;
-}
-
-static int snd_ice1712_capture_pro_open(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- ice->capture_pro_substream = substream;
- runtime->hw = snd_ice1712_capture_pro;
- snd_pcm_set_sync(substream);
- snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
- if (is_pro_rate_locked(ice)) {
- runtime->hw.rate_min = PRO_RATE_DEFAULT;
- runtime->hw.rate_max = PRO_RATE_DEFAULT;
- }
-
- return 0;
-}
-
-static int snd_ice1712_playback_pro_close(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
-
- if (PRO_RATE_RESET)
- snd_ice1712_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
- ice->playback_pro_substream = NULL;
- if (ice->spdif.ops.close)
- ice->spdif.ops.close(ice, substream);
-
- return 0;
-}
-
-static int snd_ice1712_capture_pro_close(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
-
- if (PRO_RATE_RESET)
- snd_ice1712_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
- ice->capture_pro_substream = NULL;
- return 0;
-}
-
-static struct snd_pcm_ops snd_ice1712_playback_pro_ops = {
- .open = snd_ice1712_playback_pro_open,
- .close = snd_ice1712_playback_pro_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ice1712_playback_pro_hw_params,
- .hw_free = snd_ice1712_hw_free,
- .prepare = snd_ice1712_playback_pro_prepare,
- .trigger = snd_ice1712_pro_trigger,
- .pointer = snd_ice1712_playback_pro_pointer,
-};
-
-static struct snd_pcm_ops snd_ice1712_capture_pro_ops = {
- .open = snd_ice1712_capture_pro_open,
- .close = snd_ice1712_capture_pro_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ice1712_capture_pro_hw_params,
- .hw_free = snd_ice1712_hw_free,
- .prepare = snd_ice1712_capture_pro_prepare,
- .trigger = snd_ice1712_pro_trigger,
- .pointer = snd_ice1712_capture_pro_pointer,
-};
-
-static int __devinit snd_ice1712_pcm_profi(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
- err = snd_pcm_new(ice->card, "ICE1712 multi", device, 1, 1, &pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ice1712_playback_pro_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ice1712_capture_pro_ops);
-
- pcm->private_data = ice;
- pcm->info_flags = 0;
- strcpy(pcm->name, "ICE1712 multi");
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(ice->pci), 256*1024, 256*1024);
-
- ice->pcm_pro = pcm;
- if (rpcm)
- *rpcm = pcm;
-
- if (ice->cs8427) {
- /* assign channels to iec958 */
- err = snd_cs8427_iec958_build(ice->cs8427,
- pcm->streams[0].substream,
- pcm->streams[1].substream);
- if (err < 0)
- return err;
- }
-
- err = snd_ice1712_build_pro_mixer(ice);
- if (err < 0)
- return err;
- return 0;
-}
-
-/*
- * Mixer section
- */
-
-static void snd_ice1712_update_volume(struct snd_ice1712 *ice, int index)
-{
- unsigned int vol = ice->pro_volumes[index];
- unsigned short val = 0;
-
- val |= (vol & 0x8000) == 0 ? (96 - (vol & 0x7f)) : 0x7f;
- val |= ((vol & 0x80000000) == 0 ? (96 - ((vol >> 16) & 0x7f)) : 0x7f) << 8;
- outb(index, ICEMT(ice, MONITOR_INDEX));
- outw(val, ICEMT(ice, MONITOR_VOLUME));
-}
-
-#define snd_ice1712_pro_mixer_switch_info snd_ctl_boolean_stereo_info
-
-static int snd_ice1712_pro_mixer_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int priv_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) +
- kcontrol->private_value;
-
- spin_lock_irq(&ice->reg_lock);
- ucontrol->value.integer.value[0] =
- !((ice->pro_volumes[priv_idx] >> 15) & 1);
- ucontrol->value.integer.value[1] =
- !((ice->pro_volumes[priv_idx] >> 31) & 1);
- spin_unlock_irq(&ice->reg_lock);
- return 0;
-}
-
-static int snd_ice1712_pro_mixer_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int priv_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) +
- kcontrol->private_value;
- unsigned int nval, change;
-
- nval = (ucontrol->value.integer.value[0] ? 0 : 0x00008000) |
- (ucontrol->value.integer.value[1] ? 0 : 0x80000000);
- spin_lock_irq(&ice->reg_lock);
- nval |= ice->pro_volumes[priv_idx] & ~0x80008000;
- change = nval != ice->pro_volumes[priv_idx];
- ice->pro_volumes[priv_idx] = nval;
- snd_ice1712_update_volume(ice, priv_idx);
- spin_unlock_irq(&ice->reg_lock);
- return change;
-}
-
-static int snd_ice1712_pro_mixer_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 96;
- return 0;
-}
-
-static int snd_ice1712_pro_mixer_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int priv_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) +
- kcontrol->private_value;
-
- spin_lock_irq(&ice->reg_lock);
- ucontrol->value.integer.value[0] =
- (ice->pro_volumes[priv_idx] >> 0) & 127;
- ucontrol->value.integer.value[1] =
- (ice->pro_volumes[priv_idx] >> 16) & 127;
- spin_unlock_irq(&ice->reg_lock);
- return 0;
-}
-
-static int snd_ice1712_pro_mixer_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int priv_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) +
- kcontrol->private_value;
- unsigned int nval, change;
-
- nval = (ucontrol->value.integer.value[0] & 127) |
- ((ucontrol->value.integer.value[1] & 127) << 16);
- spin_lock_irq(&ice->reg_lock);
- nval |= ice->pro_volumes[priv_idx] & ~0x007f007f;
- change = nval != ice->pro_volumes[priv_idx];
- ice->pro_volumes[priv_idx] = nval;
- snd_ice1712_update_volume(ice, priv_idx);
- spin_unlock_irq(&ice->reg_lock);
- return change;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_playback, -14400, 150, 0);
-
-static struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Multi Playback Switch",
- .info = snd_ice1712_pro_mixer_switch_info,
- .get = snd_ice1712_pro_mixer_switch_get,
- .put = snd_ice1712_pro_mixer_switch_put,
- .private_value = 0,
- .count = 10,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Multi Playback Volume",
- .info = snd_ice1712_pro_mixer_volume_info,
- .get = snd_ice1712_pro_mixer_volume_get,
- .put = snd_ice1712_pro_mixer_volume_put,
- .private_value = 0,
- .count = 10,
- .tlv = { .p = db_scale_playback }
- },
-};
-
-static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "H/W Multi Capture Switch",
- .info = snd_ice1712_pro_mixer_switch_info,
- .get = snd_ice1712_pro_mixer_switch_get,
- .put = snd_ice1712_pro_mixer_switch_put,
- .private_value = 10,
-};
-
-static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, SWITCH),
- .info = snd_ice1712_pro_mixer_switch_info,
- .get = snd_ice1712_pro_mixer_switch_get,
- .put = snd_ice1712_pro_mixer_switch_put,
- .private_value = 18,
- .count = 2,
-};
-
-static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "H/W Multi Capture Volume",
- .info = snd_ice1712_pro_mixer_volume_info,
- .get = snd_ice1712_pro_mixer_volume_get,
- .put = snd_ice1712_pro_mixer_volume_put,
- .private_value = 10,
- .tlv = { .p = db_scale_playback }
-};
-
-static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, VOLUME),
- .info = snd_ice1712_pro_mixer_volume_info,
- .get = snd_ice1712_pro_mixer_volume_get,
- .put = snd_ice1712_pro_mixer_volume_put,
- .private_value = 18,
- .count = 2,
-};
-
-static int __devinit snd_ice1712_build_pro_mixer(struct snd_ice1712 *ice)
-{
- struct snd_card *card = ice->card;
- unsigned int idx;
- int err;
-
- /* multi-channel mixer */
- for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_multi_playback_ctrls); idx++) {
- err = snd_ctl_add(card, snd_ctl_new1(&snd_ice1712_multi_playback_ctrls[idx], ice));
- if (err < 0)
- return err;
- }
-
- if (ice->num_total_adcs > 0) {
- struct snd_kcontrol_new tmp = snd_ice1712_multi_capture_analog_switch;
- tmp.count = ice->num_total_adcs;
- err = snd_ctl_add(card, snd_ctl_new1(&tmp, ice));
- if (err < 0)
- return err;
- }
-
- err = snd_ctl_add(card, snd_ctl_new1(&snd_ice1712_multi_capture_spdif_switch, ice));
- if (err < 0)
- return err;
-
- if (ice->num_total_adcs > 0) {
- struct snd_kcontrol_new tmp = snd_ice1712_multi_capture_analog_volume;
- tmp.count = ice->num_total_adcs;
- err = snd_ctl_add(card, snd_ctl_new1(&tmp, ice));
- if (err < 0)
- return err;
- }
-
- err = snd_ctl_add(card, snd_ctl_new1(&snd_ice1712_multi_capture_spdif_volume, ice));
- if (err < 0)
- return err;
-
- /* initialize volumes */
- for (idx = 0; idx < 10; idx++) {
- ice->pro_volumes[idx] = 0x80008000; /* mute */
- snd_ice1712_update_volume(ice, idx);
- }
- for (idx = 10; idx < 10 + ice->num_total_adcs; idx++) {
- ice->pro_volumes[idx] = 0x80008000; /* mute */
- snd_ice1712_update_volume(ice, idx);
- }
- for (idx = 18; idx < 20; idx++) {
- ice->pro_volumes[idx] = 0x80008000; /* mute */
- snd_ice1712_update_volume(ice, idx);
- }
- return 0;
-}
-
-static void snd_ice1712_mixer_free_ac97(struct snd_ac97 *ac97)
-{
- struct snd_ice1712 *ice = ac97->private_data;
- ice->ac97 = NULL;
-}
-
-static int __devinit snd_ice1712_ac97_mixer(struct snd_ice1712 *ice)
-{
- int err, bus_num = 0;
- struct snd_ac97_template ac97;
- struct snd_ac97_bus *pbus;
- static struct snd_ac97_bus_ops con_ops = {
- .write = snd_ice1712_ac97_write,
- .read = snd_ice1712_ac97_read,
- };
- static struct snd_ac97_bus_ops pro_ops = {
- .write = snd_ice1712_pro_ac97_write,
- .read = snd_ice1712_pro_ac97_read,
- };
-
- if (ice_has_con_ac97(ice)) {
- err = snd_ac97_bus(ice->card, bus_num++, &con_ops, NULL, &pbus);
- if (err < 0)
- return err;
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = ice;
- ac97.private_free = snd_ice1712_mixer_free_ac97;
- err = snd_ac97_mixer(pbus, &ac97, &ice->ac97);
- if (err < 0)
- printk(KERN_WARNING "ice1712: cannot initialize ac97 for consumer, skipped\n");
- else {
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, ice));
- if (err < 0)
- return err;
- return 0;
- }
- }
-
- if (!(ice->eeprom.data[ICE_EEP1_ACLINK] & ICE1712_CFG_PRO_I2S)) {
- err = snd_ac97_bus(ice->card, bus_num, &pro_ops, NULL, &pbus);
- if (err < 0)
- return err;
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = ice;
- ac97.private_free = snd_ice1712_mixer_free_ac97;
- err = snd_ac97_mixer(pbus, &ac97, &ice->ac97);
- if (err < 0)
- printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n");
- else
- return 0;
- }
- /* I2S mixer only */
- strcat(ice->card->mixername, "ICE1712 - multitrack");
- return 0;
-}
-
-/*
- *
- */
-
-static inline unsigned int eeprom_double(struct snd_ice1712 *ice, int idx)
-{
- return (unsigned int)ice->eeprom.data[idx] | ((unsigned int)ice->eeprom.data[idx + 1] << 8);
-}
-
-static void snd_ice1712_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_ice1712 *ice = entry->private_data;
- unsigned int idx;
-
- snd_iprintf(buffer, "%s\n\n", ice->card->longname);
- snd_iprintf(buffer, "EEPROM:\n");
-
- snd_iprintf(buffer, " Subvendor : 0x%x\n", ice->eeprom.subvendor);
- snd_iprintf(buffer, " Size : %i bytes\n", ice->eeprom.size);
- snd_iprintf(buffer, " Version : %i\n", ice->eeprom.version);
- snd_iprintf(buffer, " Codec : 0x%x\n", ice->eeprom.data[ICE_EEP1_CODEC]);
- snd_iprintf(buffer, " ACLink : 0x%x\n", ice->eeprom.data[ICE_EEP1_ACLINK]);
- snd_iprintf(buffer, " I2S ID : 0x%x\n", ice->eeprom.data[ICE_EEP1_I2SID]);
- snd_iprintf(buffer, " S/PDIF : 0x%x\n", ice->eeprom.data[ICE_EEP1_SPDIF]);
- snd_iprintf(buffer, " GPIO mask : 0x%x\n", ice->eeprom.gpiomask);
- snd_iprintf(buffer, " GPIO state : 0x%x\n", ice->eeprom.gpiostate);
- snd_iprintf(buffer, " GPIO direction : 0x%x\n", ice->eeprom.gpiodir);
- snd_iprintf(buffer, " AC'97 main : 0x%x\n", eeprom_double(ice, ICE_EEP1_AC97_MAIN_LO));
- snd_iprintf(buffer, " AC'97 pcm : 0x%x\n", eeprom_double(ice, ICE_EEP1_AC97_PCM_LO));
- snd_iprintf(buffer, " AC'97 record : 0x%x\n", eeprom_double(ice, ICE_EEP1_AC97_REC_LO));
- snd_iprintf(buffer, " AC'97 record src : 0x%x\n", ice->eeprom.data[ICE_EEP1_AC97_RECSRC]);
- for (idx = 0; idx < 4; idx++)
- snd_iprintf(buffer, " DAC ID #%i : 0x%x\n", idx, ice->eeprom.data[ICE_EEP1_DAC_ID + idx]);
- for (idx = 0; idx < 4; idx++)
- snd_iprintf(buffer, " ADC ID #%i : 0x%x\n", idx, ice->eeprom.data[ICE_EEP1_ADC_ID + idx]);
- for (idx = 0x1c; idx < ice->eeprom.size; idx++)
- snd_iprintf(buffer, " Extra #%02i : 0x%x\n", idx, ice->eeprom.data[idx]);
-
- snd_iprintf(buffer, "\nRegisters:\n");
- snd_iprintf(buffer, " PSDOUT03 : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_PSDOUT03)));
- snd_iprintf(buffer, " CAPTURE : 0x%08x\n", inl(ICEMT(ice, ROUTE_CAPTURE)));
- snd_iprintf(buffer, " SPDOUT : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_SPDOUT)));
- snd_iprintf(buffer, " RATE : 0x%02x\n", (unsigned)inb(ICEMT(ice, RATE)));
- snd_iprintf(buffer, " GPIO_DATA : 0x%02x\n", (unsigned)snd_ice1712_get_gpio_data(ice));
- snd_iprintf(buffer, " GPIO_WRITE_MASK : 0x%02x\n", (unsigned)snd_ice1712_read(ice, ICE1712_IREG_GPIO_WRITE_MASK));
- snd_iprintf(buffer, " GPIO_DIRECTION : 0x%02x\n", (unsigned)snd_ice1712_read(ice, ICE1712_IREG_GPIO_DIRECTION));
-}
-
-static void __devinit snd_ice1712_proc_init(struct snd_ice1712 *ice)
-{
- struct snd_info_entry *entry;
-
- if (!snd_card_proc_new(ice->card, "ice1712", &entry))
- snd_info_set_text_ops(entry, ice, snd_ice1712_proc_read);
-}
-
-/*
- *
- */
-
-static int snd_ice1712_eeprom_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
- uinfo->count = sizeof(struct snd_ice1712_eeprom);
- return 0;
-}
-
-static int snd_ice1712_eeprom_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom));
- return 0;
-}
-
-static struct snd_kcontrol_new snd_ice1712_eeprom __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_CARD,
- .name = "ICE1712 EEPROM",
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .info = snd_ice1712_eeprom_info,
- .get = snd_ice1712_eeprom_get
-};
-
-/*
- */
-static int snd_ice1712_spdif_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_ice1712_spdif_default_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- if (ice->spdif.ops.default_get)
- ice->spdif.ops.default_get(ice, ucontrol);
- return 0;
-}
-
-static int snd_ice1712_spdif_default_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- if (ice->spdif.ops.default_put)
- return ice->spdif.ops.default_put(ice, ucontrol);
- return 0;
-}
-
-static struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
- .info = snd_ice1712_spdif_info,
- .get = snd_ice1712_spdif_default_get,
- .put = snd_ice1712_spdif_default_put
-};
-
-static int snd_ice1712_spdif_maskc_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- if (ice->spdif.ops.default_get) {
- ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
- IEC958_AES0_PROFESSIONAL |
- IEC958_AES0_CON_NOT_COPYRIGHT |
- IEC958_AES0_CON_EMPHASIS;
- ucontrol->value.iec958.status[1] = IEC958_AES1_CON_ORIGINAL |
- IEC958_AES1_CON_CATEGORY;
- ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS;
- } else {
- ucontrol->value.iec958.status[0] = 0xff;
- ucontrol->value.iec958.status[1] = 0xff;
- ucontrol->value.iec958.status[2] = 0xff;
- ucontrol->value.iec958.status[3] = 0xff;
- ucontrol->value.iec958.status[4] = 0xff;
- }
- return 0;
-}
-
-static int snd_ice1712_spdif_maskp_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- if (ice->spdif.ops.default_get) {
- ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
- IEC958_AES0_PROFESSIONAL |
- IEC958_AES0_PRO_FS |
- IEC958_AES0_PRO_EMPHASIS;
- ucontrol->value.iec958.status[1] = IEC958_AES1_PRO_MODE;
- } else {
- ucontrol->value.iec958.status[0] = 0xff;
- ucontrol->value.iec958.status[1] = 0xff;
- ucontrol->value.iec958.status[2] = 0xff;
- ucontrol->value.iec958.status[3] = 0xff;
- ucontrol->value.iec958.status[4] = 0xff;
- }
- return 0;
-}
-
-static struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata =
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
- .info = snd_ice1712_spdif_info,
- .get = snd_ice1712_spdif_maskc_get,
-};
-
-static struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata =
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK),
- .info = snd_ice1712_spdif_info,
- .get = snd_ice1712_spdif_maskp_get,
-};
-
-static int snd_ice1712_spdif_stream_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- if (ice->spdif.ops.stream_get)
- ice->spdif.ops.stream_get(ice, ucontrol);
- return 0;
-}
-
-static int snd_ice1712_spdif_stream_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- if (ice->spdif.ops.stream_put)
- return ice->spdif.ops.stream_put(ice, ucontrol);
- return 0;
-}
-
-static struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata =
-{
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_INACTIVE),
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM),
- .info = snd_ice1712_spdif_info,
- .get = snd_ice1712_spdif_stream_get,
- .put = snd_ice1712_spdif_stream_put
-};
-
-int snd_ice1712_gpio_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char mask = kcontrol->private_value & 0xff;
- int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0;
-
- snd_ice1712_save_gpio_status(ice);
- ucontrol->value.integer.value[0] =
- (snd_ice1712_gpio_read(ice) & mask ? 1 : 0) ^ invert;
- snd_ice1712_restore_gpio_status(ice);
- return 0;
-}
-
-int snd_ice1712_gpio_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char mask = kcontrol->private_value & 0xff;
- int invert = (kcontrol->private_value & (1<<24)) ? mask : 0;
- unsigned int val, nval;
-
- if (kcontrol->private_value & (1 << 31))
- return -EPERM;
- nval = (ucontrol->value.integer.value[0] ? mask : 0) ^ invert;
- snd_ice1712_save_gpio_status(ice);
- val = snd_ice1712_gpio_read(ice);
- nval |= val & ~mask;
- if (val != nval)
- snd_ice1712_gpio_write(ice, nval);
- snd_ice1712_restore_gpio_status(ice);
- return val != nval;
-}
-
-/*
- * rate
- */
-static int snd_ice1712_pro_internal_clock_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static const char * const texts[] = {
- "8000", /* 0: 6 */
- "9600", /* 1: 3 */
- "11025", /* 2: 10 */
- "12000", /* 3: 2 */
- "16000", /* 4: 5 */
- "22050", /* 5: 9 */
- "24000", /* 6: 1 */
- "32000", /* 7: 4 */
- "44100", /* 8: 8 */
- "48000", /* 9: 0 */
- "64000", /* 10: 15 */
- "88200", /* 11: 11 */
- "96000", /* 12: 7 */
- "IEC958 Input", /* 13: -- */
- };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 14;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ice1712_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- static const unsigned char xlate[16] = {
- 9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 255, 255, 255, 10
- };
- unsigned char val;
-
- spin_lock_irq(&ice->reg_lock);
- if (is_spdif_master(ice)) {
- ucontrol->value.enumerated.item[0] = 13;
- } else {
- val = xlate[inb(ICEMT(ice, RATE)) & 15];
- if (val == 255) {
- snd_BUG();
- val = 0;
- }
- ucontrol->value.enumerated.item[0] = val;
- }
- spin_unlock_irq(&ice->reg_lock);
- return 0;
-}
-
-static int snd_ice1712_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- static const unsigned int xrate[13] = {
- 8000, 9600, 11025, 12000, 16000, 22050, 24000,
- 32000, 44100, 48000, 64000, 88200, 96000
- };
- unsigned char oval;
- int change = 0;
-
- spin_lock_irq(&ice->reg_lock);
- oval = inb(ICEMT(ice, RATE));
- if (ucontrol->value.enumerated.item[0] == 13) {
- outb(oval | ICE1712_SPDIF_MASTER, ICEMT(ice, RATE));
- } else {
- PRO_RATE_DEFAULT = xrate[ucontrol->value.integer.value[0] % 13];
- spin_unlock_irq(&ice->reg_lock);
- snd_ice1712_set_pro_rate(ice, PRO_RATE_DEFAULT, 1);
- spin_lock_irq(&ice->reg_lock);
- }
- change = inb(ICEMT(ice, RATE)) != oval;
- spin_unlock_irq(&ice->reg_lock);
-
- if ((oval & ICE1712_SPDIF_MASTER) !=
- (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER))
- snd_ice1712_set_input_clock_source(ice, is_spdif_master(ice));
-
- return change;
-}
-
-static struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Multi Track Internal Clock",
- .info = snd_ice1712_pro_internal_clock_info,
- .get = snd_ice1712_pro_internal_clock_get,
- .put = snd_ice1712_pro_internal_clock_put
-};
-
-static int snd_ice1712_pro_internal_clock_default_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static const char * const texts[] = {
- "8000", /* 0: 6 */
- "9600", /* 1: 3 */
- "11025", /* 2: 10 */
- "12000", /* 3: 2 */
- "16000", /* 4: 5 */
- "22050", /* 5: 9 */
- "24000", /* 6: 1 */
- "32000", /* 7: 4 */
- "44100", /* 8: 8 */
- "48000", /* 9: 0 */
- "64000", /* 10: 15 */
- "88200", /* 11: 11 */
- "96000", /* 12: 7 */
- /* "IEC958 Input", 13: -- */
- };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 13;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ice1712_pro_internal_clock_default_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int val;
- static const unsigned int xrate[13] = {
- 8000, 9600, 11025, 12000, 16000, 22050, 24000,
- 32000, 44100, 48000, 64000, 88200, 96000
- };
-
- for (val = 0; val < 13; val++) {
- if (xrate[val] == PRO_RATE_DEFAULT)
- break;
- }
-
- ucontrol->value.enumerated.item[0] = val;
- return 0;
-}
-
-static int snd_ice1712_pro_internal_clock_default_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- static const unsigned int xrate[13] = {
- 8000, 9600, 11025, 12000, 16000, 22050, 24000,
- 32000, 44100, 48000, 64000, 88200, 96000
- };
- unsigned char oval;
- int change = 0;
-
- oval = PRO_RATE_DEFAULT;
- PRO_RATE_DEFAULT = xrate[ucontrol->value.integer.value[0] % 13];
- change = PRO_RATE_DEFAULT != oval;
-
- return change;
-}
-
-static struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Multi Track Internal Clock Default",
- .info = snd_ice1712_pro_internal_clock_default_info,
- .get = snd_ice1712_pro_internal_clock_default_get,
- .put = snd_ice1712_pro_internal_clock_default_put
-};
-
-#define snd_ice1712_pro_rate_locking_info snd_ctl_boolean_mono_info
-
-static int snd_ice1712_pro_rate_locking_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = PRO_RATE_LOCKED;
- return 0;
-}
-
-static int snd_ice1712_pro_rate_locking_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int change = 0, nval;
-
- nval = ucontrol->value.integer.value[0] ? 1 : 0;
- spin_lock_irq(&ice->reg_lock);
- change = PRO_RATE_LOCKED != nval;
- PRO_RATE_LOCKED = nval;
- spin_unlock_irq(&ice->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Multi Track Rate Locking",
- .info = snd_ice1712_pro_rate_locking_info,
- .get = snd_ice1712_pro_rate_locking_get,
- .put = snd_ice1712_pro_rate_locking_put
-};
-
-#define snd_ice1712_pro_rate_reset_info snd_ctl_boolean_mono_info
-
-static int snd_ice1712_pro_rate_reset_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = PRO_RATE_RESET;
- return 0;
-}
-
-static int snd_ice1712_pro_rate_reset_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int change = 0, nval;
-
- nval = ucontrol->value.integer.value[0] ? 1 : 0;
- spin_lock_irq(&ice->reg_lock);
- change = PRO_RATE_RESET != nval;
- PRO_RATE_RESET = nval;
- spin_unlock_irq(&ice->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Multi Track Rate Reset",
- .info = snd_ice1712_pro_rate_reset_info,
- .get = snd_ice1712_pro_rate_reset_get,
- .put = snd_ice1712_pro_rate_reset_put
-};
-
-/*
- * routing
- */
-static int snd_ice1712_pro_route_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static const char * const texts[] = {
- "PCM Out", /* 0 */
- "H/W In 0", "H/W In 1", "H/W In 2", "H/W In 3", /* 1-4 */
- "H/W In 4", "H/W In 5", "H/W In 6", "H/W In 7", /* 5-8 */
- "IEC958 In L", "IEC958 In R", /* 9-10 */
- "Digital Mixer", /* 11 - optional */
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items =
- snd_ctl_get_ioffidx(kcontrol, &uinfo->id) < 2 ? 12 : 11;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_ice1712_pro_route_analog_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- unsigned int val, cval;
-
- spin_lock_irq(&ice->reg_lock);
- val = inw(ICEMT(ice, ROUTE_PSDOUT03));
- cval = inl(ICEMT(ice, ROUTE_CAPTURE));
- spin_unlock_irq(&ice->reg_lock);
-
- val >>= ((idx % 2) * 8) + ((idx / 2) * 2);
- val &= 3;
- cval >>= ((idx / 2) * 8) + ((idx % 2) * 4);
- if (val == 1 && idx < 2)
- ucontrol->value.enumerated.item[0] = 11;
- else if (val == 2)
- ucontrol->value.enumerated.item[0] = (cval & 7) + 1;
- else if (val == 3)
- ucontrol->value.enumerated.item[0] = ((cval >> 3) & 1) + 9;
- else
- ucontrol->value.enumerated.item[0] = 0;
- return 0;
-}
-
-static int snd_ice1712_pro_route_analog_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int change, shift;
- int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- unsigned int val, old_val, nval;
-
- /* update PSDOUT */
- if (ucontrol->value.enumerated.item[0] >= 11)
- nval = idx < 2 ? 1 : 0; /* dig mixer (or pcm) */
- else if (ucontrol->value.enumerated.item[0] >= 9)
- nval = 3; /* spdif in */
- else if (ucontrol->value.enumerated.item[0] >= 1)
- nval = 2; /* analog in */
- else
- nval = 0; /* pcm */
- shift = ((idx % 2) * 8) + ((idx / 2) * 2);
- spin_lock_irq(&ice->reg_lock);
- val = old_val = inw(ICEMT(ice, ROUTE_PSDOUT03));
- val &= ~(0x03 << shift);
- val |= nval << shift;
- change = val != old_val;
- if (change)
- outw(val, ICEMT(ice, ROUTE_PSDOUT03));
- spin_unlock_irq(&ice->reg_lock);
- if (nval < 2) /* dig mixer of pcm */
- return change;
-
- /* update CAPTURE */
- spin_lock_irq(&ice->reg_lock);
- val = old_val = inl(ICEMT(ice, ROUTE_CAPTURE));
- shift = ((idx / 2) * 8) + ((idx % 2) * 4);
- if (nval == 2) { /* analog in */
- nval = ucontrol->value.enumerated.item[0] - 1;
- val &= ~(0x07 << shift);
- val |= nval << shift;
- } else { /* spdif in */
- nval = (ucontrol->value.enumerated.item[0] - 9) << 3;
- val &= ~(0x08 << shift);
- val |= nval << shift;
- }
- if (val != old_val) {
- change = 1;
- outl(val, ICEMT(ice, ROUTE_CAPTURE));
- }
- spin_unlock_irq(&ice->reg_lock);
- return change;
-}
-
-static int snd_ice1712_pro_route_spdif_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- unsigned int val, cval;
- val = inw(ICEMT(ice, ROUTE_SPDOUT));
- cval = (val >> (idx * 4 + 8)) & 0x0f;
- val = (val >> (idx * 2)) & 0x03;
- if (val == 1)
- ucontrol->value.enumerated.item[0] = 11;
- else if (val == 2)
- ucontrol->value.enumerated.item[0] = (cval & 7) + 1;
- else if (val == 3)
- ucontrol->value.enumerated.item[0] = ((cval >> 3) & 1) + 9;
- else
- ucontrol->value.enumerated.item[0] = 0;
- return 0;
-}
-
-static int snd_ice1712_pro_route_spdif_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int change, shift;
- int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- unsigned int val, old_val, nval;
-
- /* update SPDOUT */
- spin_lock_irq(&ice->reg_lock);
- val = old_val = inw(ICEMT(ice, ROUTE_SPDOUT));
- if (ucontrol->value.enumerated.item[0] >= 11)
- nval = 1;
- else if (ucontrol->value.enumerated.item[0] >= 9)
- nval = 3;
- else if (ucontrol->value.enumerated.item[0] >= 1)
- nval = 2;
- else
- nval = 0;
- shift = idx * 2;
- val &= ~(0x03 << shift);
- val |= nval << shift;
- shift = idx * 4 + 8;
- if (nval == 2) {
- nval = ucontrol->value.enumerated.item[0] - 1;
- val &= ~(0x07 << shift);
- val |= nval << shift;
- } else if (nval == 3) {
- nval = (ucontrol->value.enumerated.item[0] - 9) << 3;
- val &= ~(0x08 << shift);
- val |= nval << shift;
- }
- change = val != old_val;
- if (change)
- outw(val, ICEMT(ice, ROUTE_SPDOUT));
- spin_unlock_irq(&ice->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "H/W Playback Route",
- .info = snd_ice1712_pro_route_info,
- .get = snd_ice1712_pro_route_analog_get,
- .put = snd_ice1712_pro_route_analog_put,
-};
-
-static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route",
- .info = snd_ice1712_pro_route_info,
- .get = snd_ice1712_pro_route_spdif_get,
- .put = snd_ice1712_pro_route_spdif_put,
- .count = 2,
-};
-
-
-static int snd_ice1712_pro_volume_rate_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 255;
- return 0;
-}
-
-static int snd_ice1712_pro_volume_rate_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = inb(ICEMT(ice, MONITOR_RATE));
- return 0;
-}
-
-static int snd_ice1712_pro_volume_rate_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int change;
-
- spin_lock_irq(&ice->reg_lock);
- change = inb(ICEMT(ice, MONITOR_RATE)) != ucontrol->value.integer.value[0];
- outb(ucontrol->value.integer.value[0], ICEMT(ice, MONITOR_RATE));
- spin_unlock_irq(&ice->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Multi Track Volume Rate",
- .info = snd_ice1712_pro_volume_rate_info,
- .get = snd_ice1712_pro_volume_rate_get,
- .put = snd_ice1712_pro_volume_rate_put
-};
-
-static int snd_ice1712_pro_peak_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 22;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 255;
- return 0;
-}
-
-static int snd_ice1712_pro_peak_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int idx;
-
- spin_lock_irq(&ice->reg_lock);
- for (idx = 0; idx < 22; idx++) {
- outb(idx, ICEMT(ice, MONITOR_PEAKINDEX));
- ucontrol->value.integer.value[idx] = inb(ICEMT(ice, MONITOR_PEAKDATA));
- }
- spin_unlock_irq(&ice->reg_lock);
- return 0;
-}
-
-static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "Multi Track Peak",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_ice1712_pro_peak_info,
- .get = snd_ice1712_pro_peak_get
-};
-
-/*
- *
- */
-
-/*
- * list of available boards
- */
-static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
- snd_ice1712_hoontech_cards,
- snd_ice1712_delta_cards,
- snd_ice1712_ews_cards,
- NULL,
-};
-
-static unsigned char __devinit snd_ice1712_read_i2c(struct snd_ice1712 *ice,
- unsigned char dev,
- unsigned char addr)
-{
- long t = 0x10000;
-
- outb(addr, ICEREG(ice, I2C_BYTE_ADDR));
- outb(dev & ~ICE1712_I2C_WRITE, ICEREG(ice, I2C_DEV_ADDR));
- while (t-- > 0 && (inb(ICEREG(ice, I2C_CTRL)) & ICE1712_I2C_BUSY)) ;
- return inb(ICEREG(ice, I2C_DATA));
-}
-
-static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice,
- const char *modelname)
-{
- int dev = 0xa0; /* EEPROM device address */
- unsigned int i, size;
- struct snd_ice1712_card_info * const *tbl, *c;
-
- if (!modelname || !*modelname) {
- ice->eeprom.subvendor = 0;
- if ((inb(ICEREG(ice, I2C_CTRL)) & ICE1712_I2C_EEPROM) != 0)
- ice->eeprom.subvendor = (snd_ice1712_read_i2c(ice, dev, 0x00) << 0) |
- (snd_ice1712_read_i2c(ice, dev, 0x01) << 8) |
- (snd_ice1712_read_i2c(ice, dev, 0x02) << 16) |
- (snd_ice1712_read_i2c(ice, dev, 0x03) << 24);
- if (ice->eeprom.subvendor == 0 ||
- ice->eeprom.subvendor == (unsigned int)-1) {
- /* invalid subvendor from EEPROM, try the PCI subststem ID instead */
- u16 vendor, device;
- pci_read_config_word(ice->pci, PCI_SUBSYSTEM_VENDOR_ID, &vendor);
- pci_read_config_word(ice->pci, PCI_SUBSYSTEM_ID, &device);
- ice->eeprom.subvendor = ((unsigned int)swab16(vendor) << 16) | swab16(device);
- if (ice->eeprom.subvendor == 0 || ice->eeprom.subvendor == (unsigned int)-1) {
- printk(KERN_ERR "ice1712: No valid ID is found\n");
- return -ENXIO;
- }
- }
- }
- for (tbl = card_tables; *tbl; tbl++) {
- for (c = *tbl; c->subvendor; c++) {
- if (modelname && c->model && !strcmp(modelname, c->model)) {
- printk(KERN_INFO "ice1712: Using board model %s\n", c->name);
- ice->eeprom.subvendor = c->subvendor;
- } else if (c->subvendor != ice->eeprom.subvendor)
- continue;
- if (!c->eeprom_size || !c->eeprom_data)
- goto found;
- /* if the EEPROM is given by the driver, use it */
- snd_printdd("using the defined eeprom..\n");
- ice->eeprom.version = 1;
- ice->eeprom.size = c->eeprom_size + 6;
- memcpy(ice->eeprom.data, c->eeprom_data, c->eeprom_size);
- goto read_skipped;
- }
- }
- printk(KERN_WARNING "ice1712: No matching model found for ID 0x%x\n",
- ice->eeprom.subvendor);
-
- found:
- ice->eeprom.size = snd_ice1712_read_i2c(ice, dev, 0x04);
- if (ice->eeprom.size < 6)
- ice->eeprom.size = 32; /* FIXME: any cards without the correct size? */
- else if (ice->eeprom.size > 32) {
- snd_printk(KERN_ERR "invalid EEPROM (size = %i)\n", ice->eeprom.size);
- return -EIO;
- }
- ice->eeprom.version = snd_ice1712_read_i2c(ice, dev, 0x05);
- if (ice->eeprom.version != 1) {
- snd_printk(KERN_ERR "invalid EEPROM version %i\n",
- ice->eeprom.version);
- /* return -EIO; */
- }
- size = ice->eeprom.size - 6;
- for (i = 0; i < size; i++)
- ice->eeprom.data[i] = snd_ice1712_read_i2c(ice, dev, i + 6);
-
- read_skipped:
- ice->eeprom.gpiomask = ice->eeprom.data[ICE_EEP1_GPIO_MASK];
- ice->eeprom.gpiostate = ice->eeprom.data[ICE_EEP1_GPIO_STATE];
- ice->eeprom.gpiodir = ice->eeprom.data[ICE_EEP1_GPIO_DIR];
-
- return 0;
-}
-
-
-
-static int __devinit snd_ice1712_chip_init(struct snd_ice1712 *ice)
-{
- outb(ICE1712_RESET | ICE1712_NATIVE, ICEREG(ice, CONTROL));
- udelay(200);
- outb(ICE1712_NATIVE, ICEREG(ice, CONTROL));
- udelay(200);
- if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DMX6FIRE &&
- !ice->dxr_enable)
- /* Set eeprom value to limit active ADCs and DACs to 6;
- * Also disable AC97 as no hardware in standard 6fire card/box
- * Note: DXR extensions are not currently supported
- */
- ice->eeprom.data[ICE_EEP1_CODEC] = 0x3a;
- pci_write_config_byte(ice->pci, 0x60, ice->eeprom.data[ICE_EEP1_CODEC]);
- pci_write_config_byte(ice->pci, 0x61, ice->eeprom.data[ICE_EEP1_ACLINK]);
- pci_write_config_byte(ice->pci, 0x62, ice->eeprom.data[ICE_EEP1_I2SID]);
- pci_write_config_byte(ice->pci, 0x63, ice->eeprom.data[ICE_EEP1_SPDIF]);
- if (ice->eeprom.subvendor != ICE1712_SUBDEVICE_STDSP24) {
- ice->gpio.write_mask = ice->eeprom.gpiomask;
- ice->gpio.direction = ice->eeprom.gpiodir;
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK,
- ice->eeprom.gpiomask);
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
- ice->eeprom.gpiodir);
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA,
- ice->eeprom.gpiostate);
- } else {
- ice->gpio.write_mask = 0xc0;
- ice->gpio.direction = 0xff;
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, 0xc0);
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, 0xff);
- snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA,
- ICE1712_STDSP24_CLOCK_BIT);
- }
- snd_ice1712_write(ice, ICE1712_IREG_PRO_POWERDOWN, 0);
- if (!(ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97)) {
- outb(ICE1712_AC97_WARM, ICEREG(ice, AC97_CMD));
- udelay(100);
- outb(0, ICEREG(ice, AC97_CMD));
- udelay(200);
- snd_ice1712_write(ice, ICE1712_IREG_CONSUMER_POWERDOWN, 0);
- }
- snd_ice1712_set_pro_rate(ice, 48000, 1);
-
- return 0;
-}
-
-int __devinit snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice)
-{
- int err;
- struct snd_kcontrol *kctl;
-
- if (snd_BUG_ON(!ice->pcm_pro))
- return -EIO;
- err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_default, ice));
- if (err < 0)
- return err;
- kctl->id.device = ice->pcm_pro->device;
- err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_maskc, ice));
- if (err < 0)
- return err;
- kctl->id.device = ice->pcm_pro->device;
- err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_maskp, ice));
- if (err < 0)
- return err;
- kctl->id.device = ice->pcm_pro->device;
- err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_stream, ice));
- if (err < 0)
- return err;
- kctl->id.device = ice->pcm_pro->device;
- ice->spdif.stream_ctl = kctl;
- return 0;
-}
-
-
-static int __devinit snd_ice1712_build_controls(struct snd_ice1712 *ice)
-{
- int err;
-
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_eeprom, ice));
- if (err < 0)
- return err;
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_internal_clock, ice));
- if (err < 0)
- return err;
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_internal_clock_default, ice));
- if (err < 0)
- return err;
-
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_rate_locking, ice));
- if (err < 0)
- return err;
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_rate_reset, ice));
- if (err < 0)
- return err;
-
- if (ice->num_total_dacs > 0) {
- struct snd_kcontrol_new tmp = snd_ice1712_mixer_pro_analog_route;
- tmp.count = ice->num_total_dacs;
- err = snd_ctl_add(ice->card, snd_ctl_new1(&tmp, ice));
- if (err < 0)
- return err;
- }
-
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_spdif_route, ice));
- if (err < 0)
- return err;
-
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_volume_rate, ice));
- if (err < 0)
- return err;
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_peak, ice));
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static int snd_ice1712_free(struct snd_ice1712 *ice)
-{
- if (!ice->port)
- goto __hw_end;
- /* mask all interrupts */
- outb(0xc0, ICEMT(ice, IRQ));
- outb(0xff, ICEREG(ice, IRQMASK));
- /* --- */
-__hw_end:
- if (ice->irq >= 0)
- free_irq(ice->irq, ice);
-
- if (ice->port)
- pci_release_regions(ice->pci);
- snd_ice1712_akm4xxx_free(ice);
- pci_disable_device(ice->pci);
- kfree(ice->spec);
- kfree(ice);
- return 0;
-}
-
-static int snd_ice1712_dev_free(struct snd_device *device)
-{
- struct snd_ice1712 *ice = device->device_data;
- return snd_ice1712_free(ice);
-}
-
-static int __devinit snd_ice1712_create(struct snd_card *card,
- struct pci_dev *pci,
- const char *modelname,
- int omni,
- int cs8427_timeout,
- int dxr_enable,
- struct snd_ice1712 **r_ice1712)
-{
- struct snd_ice1712 *ice;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_ice1712_dev_free,
- };
-
- *r_ice1712 = NULL;
-
- /* enable PCI device */
- err = pci_enable_device(pci);
- if (err < 0)
- return err;
- /* check, if we can restrict PCI DMA transfers to 28 bits */
- if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) {
- snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n");
- pci_disable_device(pci);
- return -ENXIO;
- }
-
- ice = kzalloc(sizeof(*ice), GFP_KERNEL);
- if (ice == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
- ice->omni = omni ? 1 : 0;
- if (cs8427_timeout < 1)
- cs8427_timeout = 1;
- else if (cs8427_timeout > 1000)
- cs8427_timeout = 1000;
- ice->cs8427_timeout = cs8427_timeout;
- ice->dxr_enable = dxr_enable;
- spin_lock_init(&ice->reg_lock);
- mutex_init(&ice->gpio_mutex);
- mutex_init(&ice->i2c_mutex);
- mutex_init(&ice->open_mutex);
- ice->gpio.set_mask = snd_ice1712_set_gpio_mask;
- ice->gpio.get_mask = snd_ice1712_get_gpio_mask;
- ice->gpio.set_dir = snd_ice1712_set_gpio_dir;
- ice->gpio.get_dir = snd_ice1712_get_gpio_dir;
- ice->gpio.set_data = snd_ice1712_set_gpio_data;
- ice->gpio.get_data = snd_ice1712_get_gpio_data;
-
- ice->spdif.cs8403_bits =
- ice->spdif.cs8403_stream_bits = (0x01 | /* consumer format */
- 0x10 | /* no emphasis */
- 0x20); /* PCM encoder/decoder */
- ice->card = card;
- ice->pci = pci;
- ice->irq = -1;
- pci_set_master(pci);
- pci_write_config_word(ice->pci, 0x40, 0x807f);
- pci_write_config_word(ice->pci, 0x42, 0x0006);
- snd_ice1712_proc_init(ice);
- synchronize_irq(pci->irq);
-
- err = pci_request_regions(pci, "ICE1712");
- if (err < 0) {
- kfree(ice);
- pci_disable_device(pci);
- return err;
- }
- ice->port = pci_resource_start(pci, 0);
- ice->ddma_port = pci_resource_start(pci, 1);
- ice->dmapath_port = pci_resource_start(pci, 2);
- ice->profi_port = pci_resource_start(pci, 3);
-
- if (request_irq(pci->irq, snd_ice1712_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, ice)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_ice1712_free(ice);
- return -EIO;
- }
-
- ice->irq = pci->irq;
-
- if (snd_ice1712_read_eeprom(ice, modelname) < 0) {
- snd_ice1712_free(ice);
- return -EIO;
- }
- if (snd_ice1712_chip_init(ice) < 0) {
- snd_ice1712_free(ice);
- return -EIO;
- }
-
- /* unmask used interrupts */
- outb(((ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) == 0 ?
- ICE1712_IRQ_MPU2 : 0) |
- ((ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97) ?
- ICE1712_IRQ_PBKDS | ICE1712_IRQ_CONCAP | ICE1712_IRQ_CONPBK : 0),
- ICEREG(ice, IRQMASK));
- outb(0x00, ICEMT(ice, IRQ));
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops);
- if (err < 0) {
- snd_ice1712_free(ice);
- return err;
- }
-
- snd_card_set_dev(card, &pci->dev);
-
- *r_ice1712 = ice;
- return 0;
-}
-
-
-/*
- *
- * Registration
- *
- */
-
-static struct snd_ice1712_card_info no_matched __devinitdata;
-
-static int __devinit snd_ice1712_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct snd_ice1712 *ice;
- int pcm_dev = 0, err;
- struct snd_ice1712_card_info * const *tbl, *c;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- strcpy(card->driver, "ICE1712");
- strcpy(card->shortname, "ICEnsemble ICE1712");
-
- err = snd_ice1712_create(card, pci, model[dev], omni[dev],
- cs8427_timeout[dev], dxr_enable[dev], &ice);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- for (tbl = card_tables; *tbl; tbl++) {
- for (c = *tbl; c->subvendor; c++) {
- if (c->subvendor == ice->eeprom.subvendor) {
- strcpy(card->shortname, c->name);
- if (c->driver) /* specific driver? */
- strcpy(card->driver, c->driver);
- if (c->chip_init) {
- err = c->chip_init(ice);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- }
- goto __found;
- }
- }
- }
- c = &no_matched;
- __found:
-
- err = snd_ice1712_pcm_profi(ice, pcm_dev++, NULL);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- if (ice_has_con_ac97(ice)) {
- err = snd_ice1712_pcm(ice, pcm_dev++, NULL);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- }
-
- err = snd_ice1712_ac97_mixer(ice);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- err = snd_ice1712_build_controls(ice);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- if (c->build_controls) {
- err = c->build_controls(ice);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- }
-
- if (ice_has_con_ac97(ice)) {
- err = snd_ice1712_pcm_ds(ice, pcm_dev++, NULL);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- }
-
- if (!c->no_mpu401) {
- err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712,
- ICEREG(ice, MPU1_CTRL),
- c->mpu401_1_info_flags |
- MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK,
- -1, &ice->rmidi[0]);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- if (c->mpu401_1_name)
- /* Preferred name available in card_info */
- snprintf(ice->rmidi[0]->name,
- sizeof(ice->rmidi[0]->name),
- "%s %d", c->mpu401_1_name, card->number);
-
- if (ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) {
- /* 2nd port used */
- err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712,
- ICEREG(ice, MPU2_CTRL),
- c->mpu401_2_info_flags |
- MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK,
- -1, &ice->rmidi[1]);
-
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- if (c->mpu401_2_name)
- /* Preferred name available in card_info */
- snprintf(ice->rmidi[1]->name,
- sizeof(ice->rmidi[1]->name),
- "%s %d", c->mpu401_2_name,
- card->number);
- }
- }
-
- snd_ice1712_set_input_clock_source(ice, 0);
-
- sprintf(card->longname, "%s at 0x%lx, irq %i",
- card->shortname, ice->port, ice->irq);
-
- err = snd_card_register(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_ice1712_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_ice1712_ids,
- .probe = snd_ice1712_probe,
- .remove = __devexit_p(snd_ice1712_remove),
-};
-
-static int __init alsa_card_ice1712_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_ice1712_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_ice1712_init)
-module_exit(alsa_card_ice1712_exit)
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/ice1712.h b/ANDROID_3.4.5/sound/pci/ice1712/ice1712.h
deleted file mode 100644
index 0da778a6..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/ice1712.h
+++ /dev/null
@@ -1,531 +0,0 @@
-#ifndef __SOUND_ICE1712_H
-#define __SOUND_ICE1712_H
-
-/*
- * ALSA driver for ICEnsemble ICE1712 (Envy24)
- *
- * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <sound/control.h>
-#include <sound/ac97_codec.h>
-#include <sound/rawmidi.h>
-#include <sound/i2c.h>
-#include <sound/ak4xxx-adda.h>
-#include <sound/ak4114.h>
-#include <sound/pt2258.h>
-#include <sound/pcm.h>
-#include <sound/mpu401.h>
-
-
-/*
- * Direct registers
- */
-
-#define ICEREG(ice, x) ((ice)->port + ICE1712_REG_##x)
-
-#define ICE1712_REG_CONTROL 0x00 /* byte */
-#define ICE1712_RESET 0x80 /* reset whole chip */
-#define ICE1712_SERR_LEVEL 0x04 /* SERR# level otherwise edge */
-#define ICE1712_NATIVE 0x01 /* native mode otherwise SB */
-#define ICE1712_REG_IRQMASK 0x01 /* byte */
-#define ICE1712_IRQ_MPU1 0x80
-#define ICE1712_IRQ_TIMER 0x40
-#define ICE1712_IRQ_MPU2 0x20
-#define ICE1712_IRQ_PROPCM 0x10
-#define ICE1712_IRQ_FM 0x08 /* FM/MIDI - legacy */
-#define ICE1712_IRQ_PBKDS 0x04 /* playback DS channels */
-#define ICE1712_IRQ_CONCAP 0x02 /* consumer capture */
-#define ICE1712_IRQ_CONPBK 0x01 /* consumer playback */
-#define ICE1712_REG_IRQSTAT 0x02 /* byte */
-/* look to ICE1712_IRQ_* */
-#define ICE1712_REG_INDEX 0x03 /* byte - indirect CCIxx regs */
-#define ICE1712_REG_DATA 0x04 /* byte - indirect CCIxx regs */
-#define ICE1712_REG_NMI_STAT1 0x05 /* byte */
-#define ICE1712_REG_NMI_DATA 0x06 /* byte */
-#define ICE1712_REG_NMI_INDEX 0x07 /* byte */
-#define ICE1712_REG_AC97_INDEX 0x08 /* byte */
-#define ICE1712_REG_AC97_CMD 0x09 /* byte */
-#define ICE1712_AC97_COLD 0x80 /* cold reset */
-#define ICE1712_AC97_WARM 0x40 /* warm reset */
-#define ICE1712_AC97_WRITE 0x20 /* W: write, R: write in progress */
-#define ICE1712_AC97_READ 0x10 /* W: read, R: read in progress */
-#define ICE1712_AC97_READY 0x08 /* codec ready status bit */
-#define ICE1712_AC97_PBK_VSR 0x02 /* playback VSR */
-#define ICE1712_AC97_CAP_VSR 0x01 /* capture VSR */
-#define ICE1712_REG_AC97_DATA 0x0a /* word (little endian) */
-#define ICE1712_REG_MPU1_CTRL 0x0c /* byte */
-#define ICE1712_REG_MPU1_DATA 0x0d /* byte */
-#define ICE1712_REG_I2C_DEV_ADDR 0x10 /* byte */
-#define ICE1712_I2C_WRITE 0x01 /* write direction */
-#define ICE1712_REG_I2C_BYTE_ADDR 0x11 /* byte */
-#define ICE1712_REG_I2C_DATA 0x12 /* byte */
-#define ICE1712_REG_I2C_CTRL 0x13 /* byte */
-#define ICE1712_I2C_EEPROM 0x80 /* EEPROM exists */
-#define ICE1712_I2C_BUSY 0x01 /* busy bit */
-#define ICE1712_REG_CONCAP_ADDR 0x14 /* dword - consumer capture */
-#define ICE1712_REG_CONCAP_COUNT 0x18 /* word - current/base count */
-#define ICE1712_REG_SERR_SHADOW 0x1b /* byte */
-#define ICE1712_REG_MPU2_CTRL 0x1c /* byte */
-#define ICE1712_REG_MPU2_DATA 0x1d /* byte */
-#define ICE1712_REG_TIMER 0x1e /* word */
-
-/*
- * Indirect registers
- */
-
-#define ICE1712_IREG_PBK_COUNT_LO 0x00
-#define ICE1712_IREG_PBK_COUNT_HI 0x01
-#define ICE1712_IREG_PBK_CTRL 0x02
-#define ICE1712_IREG_PBK_LEFT 0x03 /* left volume */
-#define ICE1712_IREG_PBK_RIGHT 0x04 /* right volume */
-#define ICE1712_IREG_PBK_SOFT 0x05 /* soft volume */
-#define ICE1712_IREG_PBK_RATE_LO 0x06
-#define ICE1712_IREG_PBK_RATE_MID 0x07
-#define ICE1712_IREG_PBK_RATE_HI 0x08
-#define ICE1712_IREG_CAP_COUNT_LO 0x10
-#define ICE1712_IREG_CAP_COUNT_HI 0x11
-#define ICE1712_IREG_CAP_CTRL 0x12
-#define ICE1712_IREG_GPIO_DATA 0x20
-#define ICE1712_IREG_GPIO_WRITE_MASK 0x21
-#define ICE1712_IREG_GPIO_DIRECTION 0x22
-#define ICE1712_IREG_CONSUMER_POWERDOWN 0x30
-#define ICE1712_IREG_PRO_POWERDOWN 0x31
-
-/*
- * Consumer section direct DMA registers
- */
-
-#define ICEDS(ice, x) ((ice)->dmapath_port + ICE1712_DS_##x)
-
-#define ICE1712_DS_INTMASK 0x00 /* word - interrupt mask */
-#define ICE1712_DS_INTSTAT 0x02 /* word - interrupt status */
-#define ICE1712_DS_DATA 0x04 /* dword - channel data */
-#define ICE1712_DS_INDEX 0x08 /* dword - channel index */
-
-/*
- * Consumer section channel registers
- */
-
-#define ICE1712_DSC_ADDR0 0x00 /* dword - base address 0 */
-#define ICE1712_DSC_COUNT0 0x01 /* word - count 0 */
-#define ICE1712_DSC_ADDR1 0x02 /* dword - base address 1 */
-#define ICE1712_DSC_COUNT1 0x03 /* word - count 1 */
-#define ICE1712_DSC_CONTROL 0x04 /* byte - control & status */
-#define ICE1712_BUFFER1 0x80 /* buffer1 is active */
-#define ICE1712_BUFFER1_AUTO 0x40 /* buffer1 auto init */
-#define ICE1712_BUFFER0_AUTO 0x20 /* buffer0 auto init */
-#define ICE1712_FLUSH 0x10 /* flush FIFO */
-#define ICE1712_STEREO 0x08 /* stereo */
-#define ICE1712_16BIT 0x04 /* 16-bit data */
-#define ICE1712_PAUSE 0x02 /* pause */
-#define ICE1712_START 0x01 /* start */
-#define ICE1712_DSC_RATE 0x05 /* dword - rate */
-#define ICE1712_DSC_VOLUME 0x06 /* word - volume control */
-
-/*
- * Professional multi-track direct control registers
- */
-
-#define ICEMT(ice, x) ((ice)->profi_port + ICE1712_MT_##x)
-
-#define ICE1712_MT_IRQ 0x00 /* byte - interrupt mask */
-#define ICE1712_MULTI_CAPTURE 0x80 /* capture IRQ */
-#define ICE1712_MULTI_PLAYBACK 0x40 /* playback IRQ */
-#define ICE1712_MULTI_CAPSTATUS 0x02 /* capture IRQ status */
-#define ICE1712_MULTI_PBKSTATUS 0x01 /* playback IRQ status */
-#define ICE1712_MT_RATE 0x01 /* byte - sampling rate select */
-#define ICE1712_SPDIF_MASTER 0x10 /* S/PDIF input is master clock */
-#define ICE1712_MT_I2S_FORMAT 0x02 /* byte - I2S data format */
-#define ICE1712_MT_AC97_INDEX 0x04 /* byte - AC'97 index */
-#define ICE1712_MT_AC97_CMD 0x05 /* byte - AC'97 command & status */
-/* look to ICE1712_AC97_* */
-#define ICE1712_MT_AC97_DATA 0x06 /* word - AC'97 data */
-#define ICE1712_MT_PLAYBACK_ADDR 0x10 /* dword - playback address */
-#define ICE1712_MT_PLAYBACK_SIZE 0x14 /* word - playback size */
-#define ICE1712_MT_PLAYBACK_COUNT 0x16 /* word - playback count */
-#define ICE1712_MT_PLAYBACK_CONTROL 0x18 /* byte - control */
-#define ICE1712_CAPTURE_START_SHADOW 0x04 /* capture start */
-#define ICE1712_PLAYBACK_PAUSE 0x02 /* playback pause */
-#define ICE1712_PLAYBACK_START 0x01 /* playback start */
-#define ICE1712_MT_CAPTURE_ADDR 0x20 /* dword - capture address */
-#define ICE1712_MT_CAPTURE_SIZE 0x24 /* word - capture size */
-#define ICE1712_MT_CAPTURE_COUNT 0x26 /* word - capture count */
-#define ICE1712_MT_CAPTURE_CONTROL 0x28 /* byte - control */
-#define ICE1712_CAPTURE_START 0x01 /* capture start */
-#define ICE1712_MT_ROUTE_PSDOUT03 0x30 /* word */
-#define ICE1712_MT_ROUTE_SPDOUT 0x32 /* word */
-#define ICE1712_MT_ROUTE_CAPTURE 0x34 /* dword */
-#define ICE1712_MT_MONITOR_VOLUME 0x38 /* word */
-#define ICE1712_MT_MONITOR_INDEX 0x3a /* byte */
-#define ICE1712_MT_MONITOR_RATE 0x3b /* byte */
-#define ICE1712_MT_MONITOR_ROUTECTRL 0x3c /* byte */
-#define ICE1712_ROUTE_AC97 0x01 /* route digital mixer output to AC'97 */
-#define ICE1712_MT_MONITOR_PEAKINDEX 0x3e /* byte */
-#define ICE1712_MT_MONITOR_PEAKDATA 0x3f /* byte */
-
-/*
- * Codec configuration bits
- */
-
-/* PCI[60] System Configuration */
-#define ICE1712_CFG_CLOCK 0xc0
-#define ICE1712_CFG_CLOCK512 0x00 /* 22.5692Mhz, 44.1kHz*512 */
-#define ICE1712_CFG_CLOCK384 0x40 /* 16.9344Mhz, 44.1kHz*384 */
-#define ICE1712_CFG_EXT 0x80 /* external clock */
-#define ICE1712_CFG_2xMPU401 0x20 /* two MPU401 UARTs */
-#define ICE1712_CFG_NO_CON_AC97 0x10 /* consumer AC'97 codec is not present */
-#define ICE1712_CFG_ADC_MASK 0x0c /* one, two, three, four stereo ADCs */
-#define ICE1712_CFG_DAC_MASK 0x03 /* one, two, three, four stereo DACs */
-/* PCI[61] AC-Link Configuration */
-#define ICE1712_CFG_PRO_I2S 0x80 /* multitrack converter: I2S or AC'97 */
-#define ICE1712_CFG_AC97_PACKED 0x01 /* split or packed mode - AC'97 */
-/* PCI[62] I2S Features */
-#define ICE1712_CFG_I2S_VOLUME 0x80 /* volume/mute capability */
-#define ICE1712_CFG_I2S_96KHZ 0x40 /* supports 96kHz sampling */
-#define ICE1712_CFG_I2S_RESMASK 0x30 /* resolution mask, 16,18,20,24-bit */
-#define ICE1712_CFG_I2S_OTHER 0x0f /* other I2S IDs */
-/* PCI[63] S/PDIF Configuration */
-#define ICE1712_CFG_I2S_CHIPID 0xfc /* I2S chip ID */
-#define ICE1712_CFG_SPDIF_IN 0x02 /* S/PDIF input is present */
-#define ICE1712_CFG_SPDIF_OUT 0x01 /* S/PDIF output is present */
-
-/*
- * DMA mode values
- * identical with DMA_XXX on i386 architecture.
- */
-#define ICE1712_DMA_MODE_WRITE 0x48
-#define ICE1712_DMA_AUTOINIT 0x10
-
-
-/*
- *
- */
-
-struct snd_ice1712;
-
-struct snd_ice1712_eeprom {
- unsigned int subvendor; /* PCI[2c-2f] */
- unsigned char size; /* size of EEPROM image in bytes */
- unsigned char version; /* must be 1 (or 2 for vt1724) */
- unsigned char data[32];
- unsigned int gpiomask;
- unsigned int gpiostate;
- unsigned int gpiodir;
-};
-
-enum {
- ICE_EEP1_CODEC = 0, /* 06 */
- ICE_EEP1_ACLINK, /* 07 */
- ICE_EEP1_I2SID, /* 08 */
- ICE_EEP1_SPDIF, /* 09 */
- ICE_EEP1_GPIO_MASK, /* 0a */
- ICE_EEP1_GPIO_STATE, /* 0b */
- ICE_EEP1_GPIO_DIR, /* 0c */
- ICE_EEP1_AC97_MAIN_LO, /* 0d */
- ICE_EEP1_AC97_MAIN_HI, /* 0e */
- ICE_EEP1_AC97_PCM_LO, /* 0f */
- ICE_EEP1_AC97_PCM_HI, /* 10 */
- ICE_EEP1_AC97_REC_LO, /* 11 */
- ICE_EEP1_AC97_REC_HI, /* 12 */
- ICE_EEP1_AC97_RECSRC, /* 13 */
- ICE_EEP1_DAC_ID, /* 14 */
- ICE_EEP1_DAC_ID1,
- ICE_EEP1_DAC_ID2,
- ICE_EEP1_DAC_ID3,
- ICE_EEP1_ADC_ID, /* 18 */
- ICE_EEP1_ADC_ID1,
- ICE_EEP1_ADC_ID2,
- ICE_EEP1_ADC_ID3
-};
-
-#define ice_has_con_ac97(ice) (!((ice)->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97))
-
-
-struct snd_ak4xxx_private {
- unsigned int cif:1; /* CIF mode */
- unsigned char caddr; /* C0 and C1 bits */
- unsigned int data_mask; /* DATA gpio bit */
- unsigned int clk_mask; /* CLK gpio bit */
- unsigned int cs_mask; /* bit mask for select/deselect address */
- unsigned int cs_addr; /* bits to select address */
- unsigned int cs_none; /* bits to deselect address */
- unsigned int add_flags; /* additional bits at init */
- unsigned int mask_flags; /* total mask bits */
- struct snd_akm4xxx_ops {
- void (*set_rate_val)(struct snd_akm4xxx *ak, unsigned int rate);
- } ops;
-};
-
-struct snd_ice1712_spdif {
- unsigned char cs8403_bits;
- unsigned char cs8403_stream_bits;
- struct snd_kcontrol *stream_ctl;
-
- struct snd_ice1712_spdif_ops {
- void (*open)(struct snd_ice1712 *, struct snd_pcm_substream *);
- void (*setup_rate)(struct snd_ice1712 *, int rate);
- void (*close)(struct snd_ice1712 *, struct snd_pcm_substream *);
- void (*default_get)(struct snd_ice1712 *, struct snd_ctl_elem_value *ucontrol);
- int (*default_put)(struct snd_ice1712 *, struct snd_ctl_elem_value *ucontrol);
- void (*stream_get)(struct snd_ice1712 *, struct snd_ctl_elem_value *ucontrol);
- int (*stream_put)(struct snd_ice1712 *, struct snd_ctl_elem_value *ucontrol);
- } ops;
-};
-
-
-struct snd_ice1712 {
- unsigned long conp_dma_size;
- unsigned long conc_dma_size;
- unsigned long prop_dma_size;
- unsigned long proc_dma_size;
- int irq;
-
- unsigned long port;
- unsigned long ddma_port;
- unsigned long dmapath_port;
- unsigned long profi_port;
-
- struct pci_dev *pci;
- struct snd_card *card;
- struct snd_pcm *pcm;
- struct snd_pcm *pcm_ds;
- struct snd_pcm *pcm_pro;
- struct snd_pcm_substream *playback_con_substream;
- struct snd_pcm_substream *playback_con_substream_ds[6];
- struct snd_pcm_substream *capture_con_substream;
- struct snd_pcm_substream *playback_pro_substream;
- struct snd_pcm_substream *capture_pro_substream;
- unsigned int playback_pro_size;
- unsigned int capture_pro_size;
- unsigned int playback_con_virt_addr[6];
- unsigned int playback_con_active_buf[6];
- unsigned int capture_con_virt_addr;
- unsigned int ac97_ext_id;
- struct snd_ac97 *ac97;
- struct snd_rawmidi *rmidi[2];
-
- spinlock_t reg_lock;
- struct snd_info_entry *proc_entry;
-
- struct snd_ice1712_eeprom eeprom;
-
- unsigned int pro_volumes[20];
- unsigned int omni:1; /* Delta Omni I/O */
- unsigned int dxr_enable:1; /* Terratec DXR enable for DMX6FIRE */
- unsigned int vt1724:1;
- unsigned int vt1720:1;
- unsigned int has_spdif:1; /* VT1720/4 - has SPDIF I/O */
- unsigned int force_pdma4:1; /* VT1720/4 - PDMA4 as non-spdif */
- unsigned int force_rdma1:1; /* VT1720/4 - RDMA1 as non-spdif */
- unsigned int midi_output:1; /* VT1720/4: MIDI output triggered */
- unsigned int midi_input:1; /* VT1720/4: MIDI input triggered */
- unsigned int own_routing:1; /* VT1720/4: use own routing ctls */
- unsigned int num_total_dacs; /* total DACs */
- unsigned int num_total_adcs; /* total ADCs */
- unsigned int cur_rate; /* current rate */
-
- struct mutex open_mutex;
- struct snd_pcm_substream *pcm_reserved[4];
- struct snd_pcm_hw_constraint_list *hw_rates; /* card-specific rate constraints */
-
- unsigned int akm_codecs;
- struct snd_akm4xxx *akm;
- struct snd_ice1712_spdif spdif;
-
- struct mutex i2c_mutex; /* I2C mutex for ICE1724 registers */
- struct snd_i2c_bus *i2c; /* I2C bus */
- struct snd_i2c_device *cs8427; /* CS8427 I2C device */
- unsigned int cs8427_timeout; /* CS8427 reset timeout in HZ/100 */
-
- struct ice1712_gpio {
- unsigned int direction; /* current direction bits */
- unsigned int write_mask; /* current mask bits */
- unsigned int saved[2]; /* for ewx_i2c */
- /* operators */
- void (*set_mask)(struct snd_ice1712 *ice, unsigned int data);
- unsigned int (*get_mask)(struct snd_ice1712 *ice);
- void (*set_dir)(struct snd_ice1712 *ice, unsigned int data);
- unsigned int (*get_dir)(struct snd_ice1712 *ice);
- void (*set_data)(struct snd_ice1712 *ice, unsigned int data);
- unsigned int (*get_data)(struct snd_ice1712 *ice);
- /* misc operators - move to another place? */
- void (*set_pro_rate)(struct snd_ice1712 *ice, unsigned int rate);
- void (*i2s_mclk_changed)(struct snd_ice1712 *ice);
- } gpio;
- struct mutex gpio_mutex;
-
- /* other board-specific data */
- void *spec;
-
- /* VT172x specific */
- int pro_rate_default;
- int (*is_spdif_master)(struct snd_ice1712 *ice);
- unsigned int (*get_rate)(struct snd_ice1712 *ice);
- void (*set_rate)(struct snd_ice1712 *ice, unsigned int rate);
- unsigned char (*set_mclk)(struct snd_ice1712 *ice, unsigned int rate);
- int (*set_spdif_clock)(struct snd_ice1712 *ice, int type);
- int (*get_spdif_master_type)(struct snd_ice1712 *ice);
- char **ext_clock_names;
- int ext_clock_count;
- void (*pro_open)(struct snd_ice1712 *, struct snd_pcm_substream *);
-#ifdef CONFIG_PM
- int (*pm_suspend)(struct snd_ice1712 *);
- int (*pm_resume)(struct snd_ice1712 *);
- unsigned int pm_suspend_enabled:1;
- unsigned int pm_saved_is_spdif_master:1;
- unsigned int pm_saved_spdif_ctrl;
- unsigned char pm_saved_spdif_cfg;
- unsigned int pm_saved_route;
-#endif
-};
-
-
-/*
- * gpio access functions
- */
-static inline void snd_ice1712_gpio_set_dir(struct snd_ice1712 *ice, unsigned int bits)
-{
- ice->gpio.set_dir(ice, bits);
-}
-
-static inline unsigned int snd_ice1712_gpio_get_dir(struct snd_ice1712 *ice)
-{
- return ice->gpio.get_dir(ice);
-}
-
-static inline void snd_ice1712_gpio_set_mask(struct snd_ice1712 *ice, unsigned int bits)
-{
- ice->gpio.set_mask(ice, bits);
-}
-
-static inline void snd_ice1712_gpio_write(struct snd_ice1712 *ice, unsigned int val)
-{
- ice->gpio.set_data(ice, val);
-}
-
-static inline unsigned int snd_ice1712_gpio_read(struct snd_ice1712 *ice)
-{
- return ice->gpio.get_data(ice);
-}
-
-/*
- * save and restore gpio status
- * The access to gpio will be protected by mutex, so don't forget to
- * restore!
- */
-static inline void snd_ice1712_save_gpio_status(struct snd_ice1712 *ice)
-{
- mutex_lock(&ice->gpio_mutex);
- ice->gpio.saved[0] = ice->gpio.direction;
- ice->gpio.saved[1] = ice->gpio.write_mask;
-}
-
-static inline void snd_ice1712_restore_gpio_status(struct snd_ice1712 *ice)
-{
- ice->gpio.set_dir(ice, ice->gpio.saved[0]);
- ice->gpio.set_mask(ice, ice->gpio.saved[1]);
- ice->gpio.direction = ice->gpio.saved[0];
- ice->gpio.write_mask = ice->gpio.saved[1];
- mutex_unlock(&ice->gpio_mutex);
-}
-
-/* for bit controls */
-#define ICE1712_GPIO(xiface, xname, xindex, mask, invert, xaccess) \
-{ .iface = xiface, .name = xname, .access = xaccess, .info = snd_ctl_boolean_mono_info, \
- .get = snd_ice1712_gpio_get, .put = snd_ice1712_gpio_put, \
- .private_value = mask | (invert << 24) }
-
-int snd_ice1712_gpio_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
-int snd_ice1712_gpio_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
-
-/*
- * set gpio direction, write mask and data
- */
-static inline void snd_ice1712_gpio_write_bits(struct snd_ice1712 *ice,
- unsigned int mask, unsigned int bits)
-{
- unsigned val;
-
- ice->gpio.direction |= mask;
- snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
- val = snd_ice1712_gpio_read(ice);
- val &= ~mask;
- val |= mask & bits;
- snd_ice1712_gpio_write(ice, val);
-}
-
-static inline int snd_ice1712_gpio_read_bits(struct snd_ice1712 *ice,
- unsigned int mask)
-{
- ice->gpio.direction &= ~mask;
- snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
- return snd_ice1712_gpio_read(ice) & mask;
-}
-
-/* route access functions */
-int snd_ice1724_get_route_val(struct snd_ice1712 *ice, int shift);
-int snd_ice1724_put_route_val(struct snd_ice1712 *ice, unsigned int val,
- int shift);
-
-int snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice);
-
-int snd_ice1712_akm4xxx_init(struct snd_akm4xxx *ak,
- const struct snd_akm4xxx *template,
- const struct snd_ak4xxx_private *priv,
- struct snd_ice1712 *ice);
-void snd_ice1712_akm4xxx_free(struct snd_ice1712 *ice);
-int snd_ice1712_akm4xxx_build_controls(struct snd_ice1712 *ice);
-
-int snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr);
-
-static inline void snd_ice1712_write(struct snd_ice1712 *ice, u8 addr, u8 data)
-{
- outb(addr, ICEREG(ice, INDEX));
- outb(data, ICEREG(ice, DATA));
-}
-
-static inline u8 snd_ice1712_read(struct snd_ice1712 *ice, u8 addr)
-{
- outb(addr, ICEREG(ice, INDEX));
- return inb(ICEREG(ice, DATA));
-}
-
-
-/*
- * entry pointer
- */
-
-struct snd_ice1712_card_info {
- unsigned int subvendor;
- char *name;
- char *model;
- char *driver;
- int (*chip_init)(struct snd_ice1712 *);
- int (*build_controls)(struct snd_ice1712 *);
- unsigned int no_mpu401:1;
- unsigned int mpu401_1_info_flags;
- unsigned int mpu401_2_info_flags;
- const char *mpu401_1_name;
- const char *mpu401_2_name;
- const unsigned int eeprom_size;
- const unsigned char *eeprom_data;
-};
-
-
-#endif /* __SOUND_ICE1712_H */
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/ice1724.c b/ANDROID_3.4.5/sound/pci/ice1712/ice1724.c
deleted file mode 100644
index 812d10e4..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/ice1724.c
+++ /dev/null
@@ -1,2898 +0,0 @@
-/*
- * ALSA driver for VT1724 ICEnsemble ICE1724 / VIA VT1724 (Envy24HT)
- * VIA VT1720 (Envy24PT)
- *
- * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
- * 2002 James Stafford <jstafford@ampltd.com>
- * 2003 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/rawmidi.h>
-#include <sound/initval.h>
-
-#include <sound/asoundef.h>
-
-#include "ice1712.h"
-#include "envy24ht.h"
-
-/* lowlevel routines */
-#include "amp.h"
-#include "revo.h"
-#include "aureon.h"
-#include "vt1720_mobo.h"
-#include "pontis.h"
-#include "prodigy192.h"
-#include "prodigy_hifi.h"
-#include "juli.h"
-#include "maya44.h"
-#include "phase.h"
-#include "wtm.h"
-#include "se.h"
-#include "quartet.h"
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("VIA ICEnsemble ICE1724/1720 (Envy24HT/PT)");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{"
- REVO_DEVICE_DESC
- AMP_AUDIO2000_DEVICE_DESC
- AUREON_DEVICE_DESC
- VT1720_MOBO_DEVICE_DESC
- PONTIS_DEVICE_DESC
- PRODIGY192_DEVICE_DESC
- PRODIGY_HIFI_DEVICE_DESC
- JULI_DEVICE_DESC
- MAYA44_DEVICE_DESC
- PHASE_DEVICE_DESC
- WTM_DEVICE_DESC
- SE_DEVICE_DESC
- QTET_DEVICE_DESC
- "{VIA,VT1720},"
- "{VIA,VT1724},"
- "{ICEnsemble,Generic ICE1724},"
- "{ICEnsemble,Generic Envy24HT}"
- "{ICEnsemble,Generic Envy24PT}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static char *model[SNDRV_CARDS];
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for ICE1724 soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for ICE1724 soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable ICE1724 soundcard.");
-module_param_array(model, charp, NULL, 0444);
-MODULE_PARM_DESC(model, "Use the given board model.");
-
-
-/* Both VT1720 and VT1724 have the same PCI IDs */
-static DEFINE_PCI_DEVICE_TABLE(snd_vt1724_ids) = {
- { PCI_VDEVICE(ICE, PCI_DEVICE_ID_VT1724), 0 },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_vt1724_ids);
-
-
-static int PRO_RATE_LOCKED;
-static int PRO_RATE_RESET = 1;
-static unsigned int PRO_RATE_DEFAULT = 44100;
-
-static char *ext_clock_names[1] = { "IEC958 In" };
-
-/*
- * Basic I/O
- */
-
-/*
- * default rates, default clock routines
- */
-
-/* check whether the clock mode is spdif-in */
-static inline int stdclock_is_spdif_master(struct snd_ice1712 *ice)
-{
- return (inb(ICEMT1724(ice, RATE)) & VT1724_SPDIF_MASTER) ? 1 : 0;
-}
-
-/*
- * locking rate makes sense only for internal clock mode
- */
-static inline int is_pro_rate_locked(struct snd_ice1712 *ice)
-{
- return (!ice->is_spdif_master(ice)) && PRO_RATE_LOCKED;
-}
-
-/*
- * ac97 section
- */
-
-static unsigned char snd_vt1724_ac97_ready(struct snd_ice1712 *ice)
-{
- unsigned char old_cmd;
- int tm;
- for (tm = 0; tm < 0x10000; tm++) {
- old_cmd = inb(ICEMT1724(ice, AC97_CMD));
- if (old_cmd & (VT1724_AC97_WRITE | VT1724_AC97_READ))
- continue;
- if (!(old_cmd & VT1724_AC97_READY))
- continue;
- return old_cmd;
- }
- snd_printd(KERN_ERR "snd_vt1724_ac97_ready: timeout\n");
- return old_cmd;
-}
-
-static int snd_vt1724_ac97_wait_bit(struct snd_ice1712 *ice, unsigned char bit)
-{
- int tm;
- for (tm = 0; tm < 0x10000; tm++)
- if ((inb(ICEMT1724(ice, AC97_CMD)) & bit) == 0)
- return 0;
- snd_printd(KERN_ERR "snd_vt1724_ac97_wait_bit: timeout\n");
- return -EIO;
-}
-
-static void snd_vt1724_ac97_write(struct snd_ac97 *ac97,
- unsigned short reg,
- unsigned short val)
-{
- struct snd_ice1712 *ice = ac97->private_data;
- unsigned char old_cmd;
-
- old_cmd = snd_vt1724_ac97_ready(ice);
- old_cmd &= ~VT1724_AC97_ID_MASK;
- old_cmd |= ac97->num;
- outb(reg, ICEMT1724(ice, AC97_INDEX));
- outw(val, ICEMT1724(ice, AC97_DATA));
- outb(old_cmd | VT1724_AC97_WRITE, ICEMT1724(ice, AC97_CMD));
- snd_vt1724_ac97_wait_bit(ice, VT1724_AC97_WRITE);
-}
-
-static unsigned short snd_vt1724_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
-{
- struct snd_ice1712 *ice = ac97->private_data;
- unsigned char old_cmd;
-
- old_cmd = snd_vt1724_ac97_ready(ice);
- old_cmd &= ~VT1724_AC97_ID_MASK;
- old_cmd |= ac97->num;
- outb(reg, ICEMT1724(ice, AC97_INDEX));
- outb(old_cmd | VT1724_AC97_READ, ICEMT1724(ice, AC97_CMD));
- if (snd_vt1724_ac97_wait_bit(ice, VT1724_AC97_READ) < 0)
- return ~0;
- return inw(ICEMT1724(ice, AC97_DATA));
-}
-
-
-/*
- * GPIO operations
- */
-
-/* set gpio direction 0 = read, 1 = write */
-static void snd_vt1724_set_gpio_dir(struct snd_ice1712 *ice, unsigned int data)
-{
- outl(data, ICEREG1724(ice, GPIO_DIRECTION));
- inw(ICEREG1724(ice, GPIO_DIRECTION)); /* dummy read for pci-posting */
-}
-
-/* get gpio direction 0 = read, 1 = write */
-static unsigned int snd_vt1724_get_gpio_dir(struct snd_ice1712 *ice)
-{
- return inl(ICEREG1724(ice, GPIO_DIRECTION));
-}
-
-/* set the gpio mask (0 = writable) */
-static void snd_vt1724_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data)
-{
- outw(data, ICEREG1724(ice, GPIO_WRITE_MASK));
- if (!ice->vt1720) /* VT1720 supports only 16 GPIO bits */
- outb((data >> 16) & 0xff, ICEREG1724(ice, GPIO_WRITE_MASK_22));
- inw(ICEREG1724(ice, GPIO_WRITE_MASK)); /* dummy read for pci-posting */
-}
-
-static unsigned int snd_vt1724_get_gpio_mask(struct snd_ice1712 *ice)
-{
- unsigned int mask;
- if (!ice->vt1720)
- mask = (unsigned int)inb(ICEREG1724(ice, GPIO_WRITE_MASK_22));
- else
- mask = 0;
- mask = (mask << 16) | inw(ICEREG1724(ice, GPIO_WRITE_MASK));
- return mask;
-}
-
-static void snd_vt1724_set_gpio_data(struct snd_ice1712 *ice, unsigned int data)
-{
- outw(data, ICEREG1724(ice, GPIO_DATA));
- if (!ice->vt1720)
- outb(data >> 16, ICEREG1724(ice, GPIO_DATA_22));
- inw(ICEREG1724(ice, GPIO_DATA)); /* dummy read for pci-posting */
-}
-
-static unsigned int snd_vt1724_get_gpio_data(struct snd_ice1712 *ice)
-{
- unsigned int data;
- if (!ice->vt1720)
- data = (unsigned int)inb(ICEREG1724(ice, GPIO_DATA_22));
- else
- data = 0;
- data = (data << 16) | inw(ICEREG1724(ice, GPIO_DATA));
- return data;
-}
-
-/*
- * MIDI
- */
-
-static void vt1724_midi_clear_rx(struct snd_ice1712 *ice)
-{
- unsigned int count;
-
- for (count = inb(ICEREG1724(ice, MPU_RXFIFO)); count > 0; --count)
- inb(ICEREG1724(ice, MPU_DATA));
-}
-
-static inline struct snd_rawmidi_substream *
-get_rawmidi_substream(struct snd_ice1712 *ice, unsigned int stream)
-{
- return list_first_entry(&ice->rmidi[0]->streams[stream].substreams,
- struct snd_rawmidi_substream, list);
-}
-
-static void enable_midi_irq(struct snd_ice1712 *ice, u8 flag, int enable);
-
-static void vt1724_midi_write(struct snd_ice1712 *ice)
-{
- struct snd_rawmidi_substream *s;
- int count, i;
- u8 buffer[32];
-
- s = get_rawmidi_substream(ice, SNDRV_RAWMIDI_STREAM_OUTPUT);
- count = 31 - inb(ICEREG1724(ice, MPU_TXFIFO));
- if (count > 0) {
- count = snd_rawmidi_transmit(s, buffer, count);
- for (i = 0; i < count; ++i)
- outb(buffer[i], ICEREG1724(ice, MPU_DATA));
- }
- /* mask irq when all bytes have been transmitted.
- * enabled again in output_trigger when the new data comes in.
- */
- enable_midi_irq(ice, VT1724_IRQ_MPU_TX,
- !snd_rawmidi_transmit_empty(s));
-}
-
-static void vt1724_midi_read(struct snd_ice1712 *ice)
-{
- struct snd_rawmidi_substream *s;
- int count, i;
- u8 buffer[32];
-
- s = get_rawmidi_substream(ice, SNDRV_RAWMIDI_STREAM_INPUT);
- count = inb(ICEREG1724(ice, MPU_RXFIFO));
- if (count > 0) {
- count = min(count, 32);
- for (i = 0; i < count; ++i)
- buffer[i] = inb(ICEREG1724(ice, MPU_DATA));
- snd_rawmidi_receive(s, buffer, count);
- }
-}
-
-/* call with ice->reg_lock */
-static void enable_midi_irq(struct snd_ice1712 *ice, u8 flag, int enable)
-{
- u8 mask = inb(ICEREG1724(ice, IRQMASK));
- if (enable)
- mask &= ~flag;
- else
- mask |= flag;
- outb(mask, ICEREG1724(ice, IRQMASK));
-}
-
-static void vt1724_enable_midi_irq(struct snd_rawmidi_substream *substream,
- u8 flag, int enable)
-{
- struct snd_ice1712 *ice = substream->rmidi->private_data;
-
- spin_lock_irq(&ice->reg_lock);
- enable_midi_irq(ice, flag, enable);
- spin_unlock_irq(&ice->reg_lock);
-}
-
-static int vt1724_midi_output_open(struct snd_rawmidi_substream *s)
-{
- return 0;
-}
-
-static int vt1724_midi_output_close(struct snd_rawmidi_substream *s)
-{
- return 0;
-}
-
-static void vt1724_midi_output_trigger(struct snd_rawmidi_substream *s, int up)
-{
- struct snd_ice1712 *ice = s->rmidi->private_data;
- unsigned long flags;
-
- spin_lock_irqsave(&ice->reg_lock, flags);
- if (up) {
- ice->midi_output = 1;
- vt1724_midi_write(ice);
- } else {
- ice->midi_output = 0;
- enable_midi_irq(ice, VT1724_IRQ_MPU_TX, 0);
- }
- spin_unlock_irqrestore(&ice->reg_lock, flags);
-}
-
-static void vt1724_midi_output_drain(struct snd_rawmidi_substream *s)
-{
- struct snd_ice1712 *ice = s->rmidi->private_data;
- unsigned long timeout;
-
- vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_TX, 0);
- /* 32 bytes should be transmitted in less than about 12 ms */
- timeout = jiffies + msecs_to_jiffies(15);
- do {
- if (inb(ICEREG1724(ice, MPU_CTRL)) & VT1724_MPU_TX_EMPTY)
- break;
- schedule_timeout_uninterruptible(1);
- } while (time_after(timeout, jiffies));
-}
-
-static struct snd_rawmidi_ops vt1724_midi_output_ops = {
- .open = vt1724_midi_output_open,
- .close = vt1724_midi_output_close,
- .trigger = vt1724_midi_output_trigger,
- .drain = vt1724_midi_output_drain,
-};
-
-static int vt1724_midi_input_open(struct snd_rawmidi_substream *s)
-{
- vt1724_midi_clear_rx(s->rmidi->private_data);
- vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_RX, 1);
- return 0;
-}
-
-static int vt1724_midi_input_close(struct snd_rawmidi_substream *s)
-{
- vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_RX, 0);
- return 0;
-}
-
-static void vt1724_midi_input_trigger(struct snd_rawmidi_substream *s, int up)
-{
- struct snd_ice1712 *ice = s->rmidi->private_data;
- unsigned long flags;
-
- spin_lock_irqsave(&ice->reg_lock, flags);
- if (up) {
- ice->midi_input = 1;
- vt1724_midi_read(ice);
- } else {
- ice->midi_input = 0;
- }
- spin_unlock_irqrestore(&ice->reg_lock, flags);
-}
-
-static struct snd_rawmidi_ops vt1724_midi_input_ops = {
- .open = vt1724_midi_input_open,
- .close = vt1724_midi_input_close,
- .trigger = vt1724_midi_input_trigger,
-};
-
-
-/*
- * Interrupt handler
- */
-
-static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id)
-{
- struct snd_ice1712 *ice = dev_id;
- unsigned char status;
- unsigned char status_mask =
- VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX | VT1724_IRQ_MTPCM;
- int handled = 0;
- int timeout = 0;
-
- while (1) {
- status = inb(ICEREG1724(ice, IRQSTAT));
- status &= status_mask;
- if (status == 0)
- break;
- spin_lock(&ice->reg_lock);
- if (++timeout > 10) {
- status = inb(ICEREG1724(ice, IRQSTAT));
- printk(KERN_ERR "ice1724: Too long irq loop, "
- "status = 0x%x\n", status);
- if (status & VT1724_IRQ_MPU_TX) {
- printk(KERN_ERR "ice1724: Disabling MPU_TX\n");
- enable_midi_irq(ice, VT1724_IRQ_MPU_TX, 0);
- }
- spin_unlock(&ice->reg_lock);
- break;
- }
- handled = 1;
- if (status & VT1724_IRQ_MPU_TX) {
- if (ice->midi_output)
- vt1724_midi_write(ice);
- else
- enable_midi_irq(ice, VT1724_IRQ_MPU_TX, 0);
- /* Due to mysterical reasons, MPU_TX is always
- * generated (and can't be cleared) when a PCM
- * playback is going. So let's ignore at the
- * next loop.
- */
- status_mask &= ~VT1724_IRQ_MPU_TX;
- }
- if (status & VT1724_IRQ_MPU_RX) {
- if (ice->midi_input)
- vt1724_midi_read(ice);
- else
- vt1724_midi_clear_rx(ice);
- }
- /* ack MPU irq */
- outb(status, ICEREG1724(ice, IRQSTAT));
- spin_unlock(&ice->reg_lock);
- if (status & VT1724_IRQ_MTPCM) {
- /*
- * Multi-track PCM
- * PCM assignment are:
- * Playback DMA0 (M/C) = playback_pro_substream
- * Playback DMA1 = playback_con_substream_ds[0]
- * Playback DMA2 = playback_con_substream_ds[1]
- * Playback DMA3 = playback_con_substream_ds[2]
- * Playback DMA4 (SPDIF) = playback_con_substream
- * Record DMA0 = capture_pro_substream
- * Record DMA1 = capture_con_substream
- */
- unsigned char mtstat = inb(ICEMT1724(ice, IRQ));
- if (mtstat & VT1724_MULTI_PDMA0) {
- if (ice->playback_pro_substream)
- snd_pcm_period_elapsed(ice->playback_pro_substream);
- }
- if (mtstat & VT1724_MULTI_RDMA0) {
- if (ice->capture_pro_substream)
- snd_pcm_period_elapsed(ice->capture_pro_substream);
- }
- if (mtstat & VT1724_MULTI_PDMA1) {
- if (ice->playback_con_substream_ds[0])
- snd_pcm_period_elapsed(ice->playback_con_substream_ds[0]);
- }
- if (mtstat & VT1724_MULTI_PDMA2) {
- if (ice->playback_con_substream_ds[1])
- snd_pcm_period_elapsed(ice->playback_con_substream_ds[1]);
- }
- if (mtstat & VT1724_MULTI_PDMA3) {
- if (ice->playback_con_substream_ds[2])
- snd_pcm_period_elapsed(ice->playback_con_substream_ds[2]);
- }
- if (mtstat & VT1724_MULTI_PDMA4) {
- if (ice->playback_con_substream)
- snd_pcm_period_elapsed(ice->playback_con_substream);
- }
- if (mtstat & VT1724_MULTI_RDMA1) {
- if (ice->capture_con_substream)
- snd_pcm_period_elapsed(ice->capture_con_substream);
- }
- /* ack anyway to avoid freeze */
- outb(mtstat, ICEMT1724(ice, IRQ));
- /* ought to really handle this properly */
- if (mtstat & VT1724_MULTI_FIFO_ERR) {
- unsigned char fstat = inb(ICEMT1724(ice, DMA_FIFO_ERR));
- outb(fstat, ICEMT1724(ice, DMA_FIFO_ERR));
- outb(VT1724_MULTI_FIFO_ERR | inb(ICEMT1724(ice, DMA_INT_MASK)), ICEMT1724(ice, DMA_INT_MASK));
- /* If I don't do this, I get machine lockup due to continual interrupts */
- }
-
- }
- }
- return IRQ_RETVAL(handled);
-}
-
-/*
- * PCM code - professional part (multitrack)
- */
-
-static unsigned int rates[] = {
- 8000, 9600, 11025, 12000, 16000, 22050, 24000,
- 32000, 44100, 48000, 64000, 88200, 96000,
- 176400, 192000,
-};
-
-static struct snd_pcm_hw_constraint_list hw_constraints_rates_96 = {
- .count = ARRAY_SIZE(rates) - 2, /* up to 96000 */
- .list = rates,
- .mask = 0,
-};
-
-static struct snd_pcm_hw_constraint_list hw_constraints_rates_48 = {
- .count = ARRAY_SIZE(rates) - 5, /* up to 48000 */
- .list = rates,
- .mask = 0,
-};
-
-static struct snd_pcm_hw_constraint_list hw_constraints_rates_192 = {
- .count = ARRAY_SIZE(rates),
- .list = rates,
- .mask = 0,
-};
-
-struct vt1724_pcm_reg {
- unsigned int addr; /* ADDR register offset */
- unsigned int size; /* SIZE register offset */
- unsigned int count; /* COUNT register offset */
- unsigned int start; /* start & pause bit */
-};
-
-static int snd_vt1724_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- unsigned char what;
- unsigned char old;
- struct snd_pcm_substream *s;
-
- what = 0;
- snd_pcm_group_for_each_entry(s, substream) {
- if (snd_pcm_substream_chip(s) == ice) {
- const struct vt1724_pcm_reg *reg;
- reg = s->runtime->private_data;
- what |= reg->start;
- snd_pcm_trigger_done(s, substream);
- }
- }
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- spin_lock(&ice->reg_lock);
- old = inb(ICEMT1724(ice, DMA_PAUSE));
- if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
- old |= what;
- else
- old &= ~what;
- outb(old, ICEMT1724(ice, DMA_PAUSE));
- spin_unlock(&ice->reg_lock);
- break;
-
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- spin_lock(&ice->reg_lock);
- old = inb(ICEMT1724(ice, DMA_CONTROL));
- if (cmd == SNDRV_PCM_TRIGGER_START)
- old |= what;
- else
- old &= ~what;
- outb(old, ICEMT1724(ice, DMA_CONTROL));
- spin_unlock(&ice->reg_lock);
- break;
-
- case SNDRV_PCM_TRIGGER_RESUME:
- /* apps will have to restart stream */
- break;
-
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-/*
- */
-
-#define DMA_STARTS (VT1724_RDMA0_START|VT1724_PDMA0_START|VT1724_RDMA1_START|\
- VT1724_PDMA1_START|VT1724_PDMA2_START|VT1724_PDMA3_START|VT1724_PDMA4_START)
-#define DMA_PAUSES (VT1724_RDMA0_PAUSE|VT1724_PDMA0_PAUSE|VT1724_RDMA1_PAUSE|\
- VT1724_PDMA1_PAUSE|VT1724_PDMA2_PAUSE|VT1724_PDMA3_PAUSE|VT1724_PDMA4_PAUSE)
-
-static const unsigned int stdclock_rate_list[16] = {
- 48000, 24000, 12000, 9600, 32000, 16000, 8000, 96000, 44100,
- 22050, 11025, 88200, 176400, 0, 192000, 64000
-};
-
-static unsigned int stdclock_get_rate(struct snd_ice1712 *ice)
-{
- unsigned int rate;
- rate = stdclock_rate_list[inb(ICEMT1724(ice, RATE)) & 15];
- return rate;
-}
-
-static void stdclock_set_rate(struct snd_ice1712 *ice, unsigned int rate)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(stdclock_rate_list); i++) {
- if (stdclock_rate_list[i] == rate) {
- outb(i, ICEMT1724(ice, RATE));
- return;
- }
- }
-}
-
-static unsigned char stdclock_set_mclk(struct snd_ice1712 *ice,
- unsigned int rate)
-{
- unsigned char val, old;
- /* check MT02 */
- if (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S) {
- val = old = inb(ICEMT1724(ice, I2S_FORMAT));
- if (rate > 96000)
- val |= VT1724_MT_I2S_MCLK_128X; /* 128x MCLK */
- else
- val &= ~VT1724_MT_I2S_MCLK_128X; /* 256x MCLK */
- if (val != old) {
- outb(val, ICEMT1724(ice, I2S_FORMAT));
- /* master clock changed */
- return 1;
- }
- }
- /* no change in master clock */
- return 0;
-}
-
-static int snd_vt1724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate,
- int force)
-{
- unsigned long flags;
- unsigned char mclk_change;
- unsigned int i, old_rate;
-
- if (rate > ice->hw_rates->list[ice->hw_rates->count - 1])
- return -EINVAL;
-
- spin_lock_irqsave(&ice->reg_lock, flags);
- if ((inb(ICEMT1724(ice, DMA_CONTROL)) & DMA_STARTS) ||
- (inb(ICEMT1724(ice, DMA_PAUSE)) & DMA_PAUSES)) {
- /* running? we cannot change the rate now... */
- spin_unlock_irqrestore(&ice->reg_lock, flags);
- return ((rate == ice->cur_rate) && !force) ? 0 : -EBUSY;
- }
- if (!force && is_pro_rate_locked(ice)) {
- /* comparing required and current rate - makes sense for
- * internal clock only */
- spin_unlock_irqrestore(&ice->reg_lock, flags);
- return (rate == ice->cur_rate) ? 0 : -EBUSY;
- }
-
- if (force || !ice->is_spdif_master(ice)) {
- /* force means the rate was switched by ucontrol, otherwise
- * setting clock rate for internal clock mode */
- old_rate = ice->get_rate(ice);
- if (force || (old_rate != rate))
- ice->set_rate(ice, rate);
- else if (rate == ice->cur_rate) {
- spin_unlock_irqrestore(&ice->reg_lock, flags);
- return 0;
- }
- }
-
- ice->cur_rate = rate;
-
- /* setting master clock */
- mclk_change = ice->set_mclk(ice, rate);
-
- spin_unlock_irqrestore(&ice->reg_lock, flags);
-
- if (mclk_change && ice->gpio.i2s_mclk_changed)
- ice->gpio.i2s_mclk_changed(ice);
- if (ice->gpio.set_pro_rate)
- ice->gpio.set_pro_rate(ice, rate);
-
- /* set up codecs */
- for (i = 0; i < ice->akm_codecs; i++) {
- if (ice->akm[i].ops.set_rate_val)
- ice->akm[i].ops.set_rate_val(&ice->akm[i], rate);
- }
- if (ice->spdif.ops.setup_rate)
- ice->spdif.ops.setup_rate(ice, rate);
-
- return 0;
-}
-
-static int snd_vt1724_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- int i, chs, err;
-
- chs = params_channels(hw_params);
- mutex_lock(&ice->open_mutex);
- /* mark surround channels */
- if (substream == ice->playback_pro_substream) {
- /* PDMA0 can be multi-channel up to 8 */
- chs = chs / 2 - 1;
- for (i = 0; i < chs; i++) {
- if (ice->pcm_reserved[i] &&
- ice->pcm_reserved[i] != substream) {
- mutex_unlock(&ice->open_mutex);
- return -EBUSY;
- }
- ice->pcm_reserved[i] = substream;
- }
- for (; i < 3; i++) {
- if (ice->pcm_reserved[i] == substream)
- ice->pcm_reserved[i] = NULL;
- }
- } else {
- for (i = 0; i < 3; i++) {
- /* check individual playback stream */
- if (ice->playback_con_substream_ds[i] == substream) {
- if (ice->pcm_reserved[i] &&
- ice->pcm_reserved[i] != substream) {
- mutex_unlock(&ice->open_mutex);
- return -EBUSY;
- }
- ice->pcm_reserved[i] = substream;
- break;
- }
- }
- }
- mutex_unlock(&ice->open_mutex);
-
- err = snd_vt1724_set_pro_rate(ice, params_rate(hw_params), 0);
- if (err < 0)
- return err;
-
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static int snd_vt1724_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- int i;
-
- mutex_lock(&ice->open_mutex);
- /* unmark surround channels */
- for (i = 0; i < 3; i++)
- if (ice->pcm_reserved[i] == substream)
- ice->pcm_reserved[i] = NULL;
- mutex_unlock(&ice->open_mutex);
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_vt1724_playback_pro_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- unsigned char val;
- unsigned int size;
-
- spin_lock_irq(&ice->reg_lock);
- val = (8 - substream->runtime->channels) >> 1;
- outb(val, ICEMT1724(ice, BURST));
-
- outl(substream->runtime->dma_addr, ICEMT1724(ice, PLAYBACK_ADDR));
-
- size = (snd_pcm_lib_buffer_bytes(substream) >> 2) - 1;
- /* outl(size, ICEMT1724(ice, PLAYBACK_SIZE)); */
- outw(size, ICEMT1724(ice, PLAYBACK_SIZE));
- outb(size >> 16, ICEMT1724(ice, PLAYBACK_SIZE) + 2);
- size = (snd_pcm_lib_period_bytes(substream) >> 2) - 1;
- /* outl(size, ICEMT1724(ice, PLAYBACK_COUNT)); */
- outw(size, ICEMT1724(ice, PLAYBACK_COUNT));
- outb(size >> 16, ICEMT1724(ice, PLAYBACK_COUNT) + 2);
-
- spin_unlock_irq(&ice->reg_lock);
-
- /*
- printk(KERN_DEBUG "pro prepare: ch = %d, addr = 0x%x, "
- "buffer = 0x%x, period = 0x%x\n",
- substream->runtime->channels,
- (unsigned int)substream->runtime->dma_addr,
- snd_pcm_lib_buffer_bytes(substream),
- snd_pcm_lib_period_bytes(substream));
- */
- return 0;
-}
-
-static snd_pcm_uframes_t snd_vt1724_playback_pro_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- size_t ptr;
-
- if (!(inl(ICEMT1724(ice, DMA_CONTROL)) & VT1724_PDMA0_START))
- return 0;
-#if 0 /* read PLAYBACK_ADDR */
- ptr = inl(ICEMT1724(ice, PLAYBACK_ADDR));
- if (ptr < substream->runtime->dma_addr) {
- snd_printd("ice1724: invalid negative ptr\n");
- return 0;
- }
- ptr -= substream->runtime->dma_addr;
- ptr = bytes_to_frames(substream->runtime, ptr);
- if (ptr >= substream->runtime->buffer_size) {
- snd_printd("ice1724: invalid ptr %d (size=%d)\n",
- (int)ptr, (int)substream->runtime->period_size);
- return 0;
- }
-#else /* read PLAYBACK_SIZE */
- ptr = inl(ICEMT1724(ice, PLAYBACK_SIZE)) & 0xffffff;
- ptr = (ptr + 1) << 2;
- ptr = bytes_to_frames(substream->runtime, ptr);
- if (!ptr)
- ;
- else if (ptr <= substream->runtime->buffer_size)
- ptr = substream->runtime->buffer_size - ptr;
- else {
- snd_printd("ice1724: invalid ptr %d (size=%d)\n",
- (int)ptr, (int)substream->runtime->buffer_size);
- ptr = 0;
- }
-#endif
- return ptr;
-}
-
-static int snd_vt1724_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- const struct vt1724_pcm_reg *reg = substream->runtime->private_data;
-
- spin_lock_irq(&ice->reg_lock);
- outl(substream->runtime->dma_addr, ice->profi_port + reg->addr);
- outw((snd_pcm_lib_buffer_bytes(substream) >> 2) - 1,
- ice->profi_port + reg->size);
- outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1,
- ice->profi_port + reg->count);
- spin_unlock_irq(&ice->reg_lock);
- return 0;
-}
-
-static snd_pcm_uframes_t snd_vt1724_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- const struct vt1724_pcm_reg *reg = substream->runtime->private_data;
- size_t ptr;
-
- if (!(inl(ICEMT1724(ice, DMA_CONTROL)) & reg->start))
- return 0;
-#if 0 /* use ADDR register */
- ptr = inl(ice->profi_port + reg->addr);
- ptr -= substream->runtime->dma_addr;
- return bytes_to_frames(substream->runtime, ptr);
-#else /* use SIZE register */
- ptr = inw(ice->profi_port + reg->size);
- ptr = (ptr + 1) << 2;
- ptr = bytes_to_frames(substream->runtime, ptr);
- if (!ptr)
- ;
- else if (ptr <= substream->runtime->buffer_size)
- ptr = substream->runtime->buffer_size - ptr;
- else {
- snd_printd("ice1724: invalid ptr %d (size=%d)\n",
- (int)ptr, (int)substream->runtime->buffer_size);
- ptr = 0;
- }
- return ptr;
-#endif
-}
-
-static const struct vt1724_pcm_reg vt1724_pdma0_reg = {
- .addr = VT1724_MT_PLAYBACK_ADDR,
- .size = VT1724_MT_PLAYBACK_SIZE,
- .count = VT1724_MT_PLAYBACK_COUNT,
- .start = VT1724_PDMA0_START,
-};
-
-static const struct vt1724_pcm_reg vt1724_pdma4_reg = {
- .addr = VT1724_MT_PDMA4_ADDR,
- .size = VT1724_MT_PDMA4_SIZE,
- .count = VT1724_MT_PDMA4_COUNT,
- .start = VT1724_PDMA4_START,
-};
-
-static const struct vt1724_pcm_reg vt1724_rdma0_reg = {
- .addr = VT1724_MT_CAPTURE_ADDR,
- .size = VT1724_MT_CAPTURE_SIZE,
- .count = VT1724_MT_CAPTURE_COUNT,
- .start = VT1724_RDMA0_START,
-};
-
-static const struct vt1724_pcm_reg vt1724_rdma1_reg = {
- .addr = VT1724_MT_RDMA1_ADDR,
- .size = VT1724_MT_RDMA1_SIZE,
- .count = VT1724_MT_RDMA1_COUNT,
- .start = VT1724_RDMA1_START,
-};
-
-#define vt1724_playback_pro_reg vt1724_pdma0_reg
-#define vt1724_playback_spdif_reg vt1724_pdma4_reg
-#define vt1724_capture_pro_reg vt1724_rdma0_reg
-#define vt1724_capture_spdif_reg vt1724_rdma1_reg
-
-static const struct snd_pcm_hardware snd_vt1724_playback_pro = {
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_192000,
- .rate_min = 8000,
- .rate_max = 192000,
- .channels_min = 2,
- .channels_max = 8,
- .buffer_bytes_max = (1UL << 21), /* 19bits dword */
- .period_bytes_min = 8 * 4 * 2, /* FIXME: constraints needed */
- .period_bytes_max = (1UL << 21),
- .periods_min = 2,
- .periods_max = 1024,
-};
-
-static const struct snd_pcm_hardware snd_vt1724_spdif = {
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .rates = (SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100|
- SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_88200|
- SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_176400|
- SNDRV_PCM_RATE_192000),
- .rate_min = 32000,
- .rate_max = 192000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (1UL << 18), /* 16bits dword */
- .period_bytes_min = 2 * 4 * 2,
- .period_bytes_max = (1UL << 18),
- .periods_min = 2,
- .periods_max = 1024,
-};
-
-static const struct snd_pcm_hardware snd_vt1724_2ch_stereo = {
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_192000,
- .rate_min = 8000,
- .rate_max = 192000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (1UL << 18), /* 16bits dword */
- .period_bytes_min = 2 * 4 * 2,
- .period_bytes_max = (1UL << 18),
- .periods_min = 2,
- .periods_max = 1024,
-};
-
-/*
- * set rate constraints
- */
-static void set_std_hw_rates(struct snd_ice1712 *ice)
-{
- if (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S) {
- /* I2S */
- /* VT1720 doesn't support more than 96kHz */
- if ((ice->eeprom.data[ICE_EEP2_I2S] & 0x08) && !ice->vt1720)
- ice->hw_rates = &hw_constraints_rates_192;
- else
- ice->hw_rates = &hw_constraints_rates_96;
- } else {
- /* ACLINK */
- ice->hw_rates = &hw_constraints_rates_48;
- }
-}
-
-static int set_rate_constraints(struct snd_ice1712 *ice,
- struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- runtime->hw.rate_min = ice->hw_rates->list[0];
- runtime->hw.rate_max = ice->hw_rates->list[ice->hw_rates->count - 1];
- runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
- return snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- ice->hw_rates);
-}
-
-/* if the card has the internal rate locked (is_pro_locked), limit runtime
- hw rates to the current internal rate only.
-*/
-static void constrain_rate_if_locked(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int rate;
- if (is_pro_rate_locked(ice)) {
- rate = ice->get_rate(ice);
- if (rate >= runtime->hw.rate_min
- && rate <= runtime->hw.rate_max) {
- runtime->hw.rate_min = rate;
- runtime->hw.rate_max = rate;
- }
- }
-}
-
-
-/* multi-channel playback needs alignment 8x32bit regardless of the channels
- * actually used
- */
-#define VT1724_BUFFER_ALIGN 0x20
-
-static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- int chs, num_indeps;
-
- runtime->private_data = (void *)&vt1724_playback_pro_reg;
- ice->playback_pro_substream = substream;
- runtime->hw = snd_vt1724_playback_pro;
- snd_pcm_set_sync(substream);
- snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
- set_rate_constraints(ice, substream);
- mutex_lock(&ice->open_mutex);
- /* calculate the currently available channels */
- num_indeps = ice->num_total_dacs / 2 - 1;
- for (chs = 0; chs < num_indeps; chs++) {
- if (ice->pcm_reserved[chs])
- break;
- }
- chs = (chs + 1) * 2;
- runtime->hw.channels_max = chs;
- if (chs > 2) /* channels must be even */
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 2);
- mutex_unlock(&ice->open_mutex);
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- VT1724_BUFFER_ALIGN);
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
- VT1724_BUFFER_ALIGN);
- constrain_rate_if_locked(substream);
- if (ice->pro_open)
- ice->pro_open(ice, substream);
- return 0;
-}
-
-static int snd_vt1724_capture_pro_open(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- runtime->private_data = (void *)&vt1724_capture_pro_reg;
- ice->capture_pro_substream = substream;
- runtime->hw = snd_vt1724_2ch_stereo;
- snd_pcm_set_sync(substream);
- snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
- set_rate_constraints(ice, substream);
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- VT1724_BUFFER_ALIGN);
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
- VT1724_BUFFER_ALIGN);
- constrain_rate_if_locked(substream);
- if (ice->pro_open)
- ice->pro_open(ice, substream);
- return 0;
-}
-
-static int snd_vt1724_playback_pro_close(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
-
- if (PRO_RATE_RESET)
- snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 0);
- ice->playback_pro_substream = NULL;
-
- return 0;
-}
-
-static int snd_vt1724_capture_pro_close(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
-
- if (PRO_RATE_RESET)
- snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 0);
- ice->capture_pro_substream = NULL;
- return 0;
-}
-
-static struct snd_pcm_ops snd_vt1724_playback_pro_ops = {
- .open = snd_vt1724_playback_pro_open,
- .close = snd_vt1724_playback_pro_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_vt1724_pcm_hw_params,
- .hw_free = snd_vt1724_pcm_hw_free,
- .prepare = snd_vt1724_playback_pro_prepare,
- .trigger = snd_vt1724_pcm_trigger,
- .pointer = snd_vt1724_playback_pro_pointer,
-};
-
-static struct snd_pcm_ops snd_vt1724_capture_pro_ops = {
- .open = snd_vt1724_capture_pro_open,
- .close = snd_vt1724_capture_pro_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_vt1724_pcm_hw_params,
- .hw_free = snd_vt1724_pcm_hw_free,
- .prepare = snd_vt1724_pcm_prepare,
- .trigger = snd_vt1724_pcm_trigger,
- .pointer = snd_vt1724_pcm_pointer,
-};
-
-static int __devinit snd_vt1724_pcm_profi(struct snd_ice1712 *ice, int device)
-{
- struct snd_pcm *pcm;
- int capt, err;
-
- if ((ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_ADC_MASK) ==
- VT1724_CFG_ADC_NONE)
- capt = 0;
- else
- capt = 1;
- err = snd_pcm_new(ice->card, "ICE1724", device, 1, capt, &pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_vt1724_playback_pro_ops);
- if (capt)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_vt1724_capture_pro_ops);
-
- pcm->private_data = ice;
- pcm->info_flags = 0;
- strcpy(pcm->name, "ICE1724");
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(ice->pci),
- 256*1024, 256*1024);
-
- ice->pcm_pro = pcm;
-
- return 0;
-}
-
-
-/*
- * SPDIF PCM
- */
-
-/* update spdif control bits; call with reg_lock */
-static void update_spdif_bits(struct snd_ice1712 *ice, unsigned int val)
-{
- unsigned char cbit, disabled;
-
- cbit = inb(ICEREG1724(ice, SPDIF_CFG));
- disabled = cbit & ~VT1724_CFG_SPDIF_OUT_EN;
- if (cbit != disabled)
- outb(disabled, ICEREG1724(ice, SPDIF_CFG));
- outw(val, ICEMT1724(ice, SPDIF_CTRL));
- if (cbit != disabled)
- outb(cbit, ICEREG1724(ice, SPDIF_CFG));
- outw(val, ICEMT1724(ice, SPDIF_CTRL));
-}
-
-/* update SPDIF control bits according to the given rate */
-static void update_spdif_rate(struct snd_ice1712 *ice, unsigned int rate)
-{
- unsigned int val, nval;
- unsigned long flags;
-
- spin_lock_irqsave(&ice->reg_lock, flags);
- nval = val = inw(ICEMT1724(ice, SPDIF_CTRL));
- nval &= ~(7 << 12);
- switch (rate) {
- case 44100: break;
- case 48000: nval |= 2 << 12; break;
- case 32000: nval |= 3 << 12; break;
- case 88200: nval |= 4 << 12; break;
- case 96000: nval |= 5 << 12; break;
- case 192000: nval |= 6 << 12; break;
- case 176400: nval |= 7 << 12; break;
- }
- if (val != nval)
- update_spdif_bits(ice, nval);
- spin_unlock_irqrestore(&ice->reg_lock, flags);
-}
-
-static int snd_vt1724_playback_spdif_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- if (!ice->force_pdma4)
- update_spdif_rate(ice, substream->runtime->rate);
- return snd_vt1724_pcm_prepare(substream);
-}
-
-static int snd_vt1724_playback_spdif_open(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- runtime->private_data = (void *)&vt1724_playback_spdif_reg;
- ice->playback_con_substream = substream;
- if (ice->force_pdma4) {
- runtime->hw = snd_vt1724_2ch_stereo;
- set_rate_constraints(ice, substream);
- } else
- runtime->hw = snd_vt1724_spdif;
- snd_pcm_set_sync(substream);
- snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- VT1724_BUFFER_ALIGN);
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
- VT1724_BUFFER_ALIGN);
- constrain_rate_if_locked(substream);
- if (ice->spdif.ops.open)
- ice->spdif.ops.open(ice, substream);
- return 0;
-}
-
-static int snd_vt1724_playback_spdif_close(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
-
- if (PRO_RATE_RESET)
- snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 0);
- ice->playback_con_substream = NULL;
- if (ice->spdif.ops.close)
- ice->spdif.ops.close(ice, substream);
-
- return 0;
-}
-
-static int snd_vt1724_capture_spdif_open(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- runtime->private_data = (void *)&vt1724_capture_spdif_reg;
- ice->capture_con_substream = substream;
- if (ice->force_rdma1) {
- runtime->hw = snd_vt1724_2ch_stereo;
- set_rate_constraints(ice, substream);
- } else
- runtime->hw = snd_vt1724_spdif;
- snd_pcm_set_sync(substream);
- snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- VT1724_BUFFER_ALIGN);
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
- VT1724_BUFFER_ALIGN);
- constrain_rate_if_locked(substream);
- if (ice->spdif.ops.open)
- ice->spdif.ops.open(ice, substream);
- return 0;
-}
-
-static int snd_vt1724_capture_spdif_close(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
-
- if (PRO_RATE_RESET)
- snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 0);
- ice->capture_con_substream = NULL;
- if (ice->spdif.ops.close)
- ice->spdif.ops.close(ice, substream);
-
- return 0;
-}
-
-static struct snd_pcm_ops snd_vt1724_playback_spdif_ops = {
- .open = snd_vt1724_playback_spdif_open,
- .close = snd_vt1724_playback_spdif_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_vt1724_pcm_hw_params,
- .hw_free = snd_vt1724_pcm_hw_free,
- .prepare = snd_vt1724_playback_spdif_prepare,
- .trigger = snd_vt1724_pcm_trigger,
- .pointer = snd_vt1724_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_vt1724_capture_spdif_ops = {
- .open = snd_vt1724_capture_spdif_open,
- .close = snd_vt1724_capture_spdif_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_vt1724_pcm_hw_params,
- .hw_free = snd_vt1724_pcm_hw_free,
- .prepare = snd_vt1724_pcm_prepare,
- .trigger = snd_vt1724_pcm_trigger,
- .pointer = snd_vt1724_pcm_pointer,
-};
-
-
-static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 *ice, int device)
-{
- char *name;
- struct snd_pcm *pcm;
- int play, capt;
- int err;
-
- if (ice->force_pdma4 ||
- (ice->eeprom.data[ICE_EEP2_SPDIF] & VT1724_CFG_SPDIF_OUT_INT)) {
- play = 1;
- ice->has_spdif = 1;
- } else
- play = 0;
- if (ice->force_rdma1 ||
- (ice->eeprom.data[ICE_EEP2_SPDIF] & VT1724_CFG_SPDIF_IN)) {
- capt = 1;
- ice->has_spdif = 1;
- } else
- capt = 0;
- if (!play && !capt)
- return 0; /* no spdif device */
-
- if (ice->force_pdma4 || ice->force_rdma1)
- name = "ICE1724 Secondary";
- else
- name = "ICE1724 IEC958";
- err = snd_pcm_new(ice->card, name, device, play, capt, &pcm);
- if (err < 0)
- return err;
-
- if (play)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_vt1724_playback_spdif_ops);
- if (capt)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_vt1724_capture_spdif_ops);
-
- pcm->private_data = ice;
- pcm->info_flags = 0;
- strcpy(pcm->name, name);
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(ice->pci),
- 256*1024, 256*1024);
-
- ice->pcm = pcm;
-
- return 0;
-}
-
-
-/*
- * independent surround PCMs
- */
-
-static const struct vt1724_pcm_reg vt1724_playback_dma_regs[3] = {
- {
- .addr = VT1724_MT_PDMA1_ADDR,
- .size = VT1724_MT_PDMA1_SIZE,
- .count = VT1724_MT_PDMA1_COUNT,
- .start = VT1724_PDMA1_START,
- },
- {
- .addr = VT1724_MT_PDMA2_ADDR,
- .size = VT1724_MT_PDMA2_SIZE,
- .count = VT1724_MT_PDMA2_COUNT,
- .start = VT1724_PDMA2_START,
- },
- {
- .addr = VT1724_MT_PDMA3_ADDR,
- .size = VT1724_MT_PDMA3_SIZE,
- .count = VT1724_MT_PDMA3_COUNT,
- .start = VT1724_PDMA3_START,
- },
-};
-
-static int snd_vt1724_playback_indep_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- unsigned char val;
-
- spin_lock_irq(&ice->reg_lock);
- val = 3 - substream->number;
- if (inb(ICEMT1724(ice, BURST)) < val)
- outb(val, ICEMT1724(ice, BURST));
- spin_unlock_irq(&ice->reg_lock);
- return snd_vt1724_pcm_prepare(substream);
-}
-
-static int snd_vt1724_playback_indep_open(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- mutex_lock(&ice->open_mutex);
- /* already used by PDMA0? */
- if (ice->pcm_reserved[substream->number]) {
- mutex_unlock(&ice->open_mutex);
- return -EBUSY; /* FIXME: should handle blocking mode properly */
- }
- mutex_unlock(&ice->open_mutex);
- runtime->private_data = (void *)&vt1724_playback_dma_regs[substream->number];
- ice->playback_con_substream_ds[substream->number] = substream;
- runtime->hw = snd_vt1724_2ch_stereo;
- snd_pcm_set_sync(substream);
- snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
- set_rate_constraints(ice, substream);
- return 0;
-}
-
-static int snd_vt1724_playback_indep_close(struct snd_pcm_substream *substream)
-{
- struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
-
- if (PRO_RATE_RESET)
- snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 0);
- ice->playback_con_substream_ds[substream->number] = NULL;
- ice->pcm_reserved[substream->number] = NULL;
-
- return 0;
-}
-
-static struct snd_pcm_ops snd_vt1724_playback_indep_ops = {
- .open = snd_vt1724_playback_indep_open,
- .close = snd_vt1724_playback_indep_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_vt1724_pcm_hw_params,
- .hw_free = snd_vt1724_pcm_hw_free,
- .prepare = snd_vt1724_playback_indep_prepare,
- .trigger = snd_vt1724_pcm_trigger,
- .pointer = snd_vt1724_pcm_pointer,
-};
-
-
-static int __devinit snd_vt1724_pcm_indep(struct snd_ice1712 *ice, int device)
-{
- struct snd_pcm *pcm;
- int play;
- int err;
-
- play = ice->num_total_dacs / 2 - 1;
- if (play <= 0)
- return 0;
-
- err = snd_pcm_new(ice->card, "ICE1724 Surrounds", device, play, 0, &pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_vt1724_playback_indep_ops);
-
- pcm->private_data = ice;
- pcm->info_flags = 0;
- strcpy(pcm->name, "ICE1724 Surround PCM");
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(ice->pci),
- 256*1024, 256*1024);
-
- ice->pcm_ds = pcm;
-
- return 0;
-}
-
-
-/*
- * Mixer section
- */
-
-static int __devinit snd_vt1724_ac97_mixer(struct snd_ice1712 *ice)
-{
- int err;
-
- if (!(ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S)) {
- struct snd_ac97_bus *pbus;
- struct snd_ac97_template ac97;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_vt1724_ac97_write,
- .read = snd_vt1724_ac97_read,
- };
-
- /* cold reset */
- outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
- mdelay(5); /* FIXME */
- outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));
-
- err = snd_ac97_bus(ice->card, 0, &ops, NULL, &pbus);
- if (err < 0)
- return err;
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = ice;
- err = snd_ac97_mixer(pbus, &ac97, &ice->ac97);
- if (err < 0)
- printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n");
- else
- return 0;
- }
- /* I2S mixer only */
- strcat(ice->card->mixername, "ICE1724 - multitrack");
- return 0;
-}
-
-/*
- *
- */
-
-static inline unsigned int eeprom_triple(struct snd_ice1712 *ice, int idx)
-{
- return (unsigned int)ice->eeprom.data[idx] | \
- ((unsigned int)ice->eeprom.data[idx + 1] << 8) | \
- ((unsigned int)ice->eeprom.data[idx + 2] << 16);
-}
-
-static void snd_vt1724_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_ice1712 *ice = entry->private_data;
- unsigned int idx;
-
- snd_iprintf(buffer, "%s\n\n", ice->card->longname);
- snd_iprintf(buffer, "EEPROM:\n");
-
- snd_iprintf(buffer, " Subvendor : 0x%x\n", ice->eeprom.subvendor);
- snd_iprintf(buffer, " Size : %i bytes\n", ice->eeprom.size);
- snd_iprintf(buffer, " Version : %i\n", ice->eeprom.version);
- snd_iprintf(buffer, " System Config : 0x%x\n",
- ice->eeprom.data[ICE_EEP2_SYSCONF]);
- snd_iprintf(buffer, " ACLink : 0x%x\n",
- ice->eeprom.data[ICE_EEP2_ACLINK]);
- snd_iprintf(buffer, " I2S : 0x%x\n",
- ice->eeprom.data[ICE_EEP2_I2S]);
- snd_iprintf(buffer, " S/PDIF : 0x%x\n",
- ice->eeprom.data[ICE_EEP2_SPDIF]);
- snd_iprintf(buffer, " GPIO direction : 0x%x\n",
- ice->eeprom.gpiodir);
- snd_iprintf(buffer, " GPIO mask : 0x%x\n",
- ice->eeprom.gpiomask);
- snd_iprintf(buffer, " GPIO state : 0x%x\n",
- ice->eeprom.gpiostate);
- for (idx = 0x12; idx < ice->eeprom.size; idx++)
- snd_iprintf(buffer, " Extra #%02i : 0x%x\n",
- idx, ice->eeprom.data[idx]);
-
- snd_iprintf(buffer, "\nRegisters:\n");
-
- snd_iprintf(buffer, " PSDOUT03 : 0x%08x\n",
- (unsigned)inl(ICEMT1724(ice, ROUTE_PLAYBACK)));
- for (idx = 0x0; idx < 0x20 ; idx++)
- snd_iprintf(buffer, " CCS%02x : 0x%02x\n",
- idx, inb(ice->port+idx));
- for (idx = 0x0; idx < 0x30 ; idx++)
- snd_iprintf(buffer, " MT%02x : 0x%02x\n",
- idx, inb(ice->profi_port+idx));
-}
-
-static void __devinit snd_vt1724_proc_init(struct snd_ice1712 *ice)
-{
- struct snd_info_entry *entry;
-
- if (!snd_card_proc_new(ice->card, "ice1724", &entry))
- snd_info_set_text_ops(entry, ice, snd_vt1724_proc_read);
-}
-
-/*
- *
- */
-
-static int snd_vt1724_eeprom_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
- uinfo->count = sizeof(struct snd_ice1712_eeprom);
- return 0;
-}
-
-static int snd_vt1724_eeprom_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom));
- return 0;
-}
-
-static struct snd_kcontrol_new snd_vt1724_eeprom __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_CARD,
- .name = "ICE1724 EEPROM",
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .info = snd_vt1724_eeprom_info,
- .get = snd_vt1724_eeprom_get
-};
-
-/*
- */
-static int snd_vt1724_spdif_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static unsigned int encode_spdif_bits(struct snd_aes_iec958 *diga)
-{
- unsigned int val, rbits;
-
- val = diga->status[0] & 0x03; /* professional, non-audio */
- if (val & 0x01) {
- /* professional */
- if ((diga->status[0] & IEC958_AES0_PRO_EMPHASIS) ==
- IEC958_AES0_PRO_EMPHASIS_5015)
- val |= 1U << 3;
- rbits = (diga->status[4] >> 3) & 0x0f;
- if (rbits) {
- switch (rbits) {
- case 2: val |= 5 << 12; break; /* 96k */
- case 3: val |= 6 << 12; break; /* 192k */
- case 10: val |= 4 << 12; break; /* 88.2k */
- case 11: val |= 7 << 12; break; /* 176.4k */
- }
- } else {
- switch (diga->status[0] & IEC958_AES0_PRO_FS) {
- case IEC958_AES0_PRO_FS_44100:
- break;
- case IEC958_AES0_PRO_FS_32000:
- val |= 3U << 12;
- break;
- default:
- val |= 2U << 12;
- break;
- }
- }
- } else {
- /* consumer */
- val |= diga->status[1] & 0x04; /* copyright */
- if ((diga->status[0] & IEC958_AES0_CON_EMPHASIS) ==
- IEC958_AES0_CON_EMPHASIS_5015)
- val |= 1U << 3;
- val |= (unsigned int)(diga->status[1] & 0x3f) << 4; /* category */
- val |= (unsigned int)(diga->status[3] & IEC958_AES3_CON_FS) << 12; /* fs */
- }
- return val;
-}
-
-static void decode_spdif_bits(struct snd_aes_iec958 *diga, unsigned int val)
-{
- memset(diga->status, 0, sizeof(diga->status));
- diga->status[0] = val & 0x03; /* professional, non-audio */
- if (val & 0x01) {
- /* professional */
- if (val & (1U << 3))
- diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_5015;
- switch ((val >> 12) & 0x7) {
- case 0:
- break;
- case 2:
- diga->status[0] |= IEC958_AES0_PRO_FS_32000;
- break;
- default:
- diga->status[0] |= IEC958_AES0_PRO_FS_48000;
- break;
- }
- } else {
- /* consumer */
- diga->status[0] |= val & (1U << 2); /* copyright */
- if (val & (1U << 3))
- diga->status[0] |= IEC958_AES0_CON_EMPHASIS_5015;
- diga->status[1] |= (val >> 4) & 0x3f; /* category */
- diga->status[3] |= (val >> 12) & 0x07; /* fs */
- }
-}
-
-static int snd_vt1724_spdif_default_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- val = inw(ICEMT1724(ice, SPDIF_CTRL));
- decode_spdif_bits(&ucontrol->value.iec958, val);
- return 0;
-}
-
-static int snd_vt1724_spdif_default_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned int val, old;
-
- val = encode_spdif_bits(&ucontrol->value.iec958);
- spin_lock_irq(&ice->reg_lock);
- old = inw(ICEMT1724(ice, SPDIF_CTRL));
- if (val != old)
- update_spdif_bits(ice, val);
- spin_unlock_irq(&ice->reg_lock);
- return val != old;
-}
-
-static struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
- .info = snd_vt1724_spdif_info,
- .get = snd_vt1724_spdif_default_get,
- .put = snd_vt1724_spdif_default_put
-};
-
-static int snd_vt1724_spdif_maskc_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
- IEC958_AES0_PROFESSIONAL |
- IEC958_AES0_CON_NOT_COPYRIGHT |
- IEC958_AES0_CON_EMPHASIS;
- ucontrol->value.iec958.status[1] = IEC958_AES1_CON_ORIGINAL |
- IEC958_AES1_CON_CATEGORY;
- ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS;
- return 0;
-}
-
-static int snd_vt1724_spdif_maskp_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
- IEC958_AES0_PROFESSIONAL |
- IEC958_AES0_PRO_FS |
- IEC958_AES0_PRO_EMPHASIS;
- return 0;
-}
-
-static struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata =
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
- .info = snd_vt1724_spdif_info,
- .get = snd_vt1724_spdif_maskc_get,
-};
-
-static struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata =
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK),
- .info = snd_vt1724_spdif_info,
- .get = snd_vt1724_spdif_maskp_get,
-};
-
-#define snd_vt1724_spdif_sw_info snd_ctl_boolean_mono_info
-
-static int snd_vt1724_spdif_sw_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = inb(ICEREG1724(ice, SPDIF_CFG)) &
- VT1724_CFG_SPDIF_OUT_EN ? 1 : 0;
- return 0;
-}
-
-static int snd_vt1724_spdif_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char old, val;
-
- spin_lock_irq(&ice->reg_lock);
- old = val = inb(ICEREG1724(ice, SPDIF_CFG));
- val &= ~VT1724_CFG_SPDIF_OUT_EN;
- if (ucontrol->value.integer.value[0])
- val |= VT1724_CFG_SPDIF_OUT_EN;
- if (old != val)
- outb(val, ICEREG1724(ice, SPDIF_CFG));
- spin_unlock_irq(&ice->reg_lock);
- return old != val;
-}
-
-static struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- /* FIXME: the following conflict with IEC958 Playback Route */
- /* .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH), */
- .name = SNDRV_CTL_NAME_IEC958("Output ", NONE, SWITCH),
- .info = snd_vt1724_spdif_sw_info,
- .get = snd_vt1724_spdif_sw_get,
- .put = snd_vt1724_spdif_sw_put
-};
-
-
-#if 0 /* NOT USED YET */
-/*
- * GPIO access from extern
- */
-
-#define snd_vt1724_gpio_info snd_ctl_boolean_mono_info
-
-int snd_vt1724_gpio_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int shift = kcontrol->private_value & 0xff;
- int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0;
-
- snd_ice1712_save_gpio_status(ice);
- ucontrol->value.integer.value[0] =
- (snd_ice1712_gpio_read(ice) & (1 << shift) ? 1 : 0) ^ invert;
- snd_ice1712_restore_gpio_status(ice);
- return 0;
-}
-
-int snd_ice1712_gpio_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int shift = kcontrol->private_value & 0xff;
- int invert = (kcontrol->private_value & (1<<24)) ? mask : 0;
- unsigned int val, nval;
-
- if (kcontrol->private_value & (1 << 31))
- return -EPERM;
- nval = (ucontrol->value.integer.value[0] ? (1 << shift) : 0) ^ invert;
- snd_ice1712_save_gpio_status(ice);
- val = snd_ice1712_gpio_read(ice);
- nval |= val & ~(1 << shift);
- if (val != nval)
- snd_ice1712_gpio_write(ice, nval);
- snd_ice1712_restore_gpio_status(ice);
- return val != nval;
-}
-#endif /* NOT USED YET */
-
-/*
- * rate
- */
-static int snd_vt1724_pro_internal_clock_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int hw_rates_count = ice->hw_rates->count;
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
-
- /* internal clocks */
- uinfo->value.enumerated.items = hw_rates_count;
- /* external clocks */
- if (ice->force_rdma1 ||
- (ice->eeprom.data[ICE_EEP2_SPDIF] & VT1724_CFG_SPDIF_IN))
- uinfo->value.enumerated.items += ice->ext_clock_count;
- /* upper limit - keep at top */
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- if (uinfo->value.enumerated.item >= hw_rates_count)
- /* ext_clock items */
- strcpy(uinfo->value.enumerated.name,
- ice->ext_clock_names[
- uinfo->value.enumerated.item - hw_rates_count]);
- else
- /* int clock items */
- sprintf(uinfo->value.enumerated.name, "%d",
- ice->hw_rates->list[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_vt1724_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned int i, rate;
-
- spin_lock_irq(&ice->reg_lock);
- if (ice->is_spdif_master(ice)) {
- ucontrol->value.enumerated.item[0] = ice->hw_rates->count +
- ice->get_spdif_master_type(ice);
- } else {
- rate = ice->get_rate(ice);
- ucontrol->value.enumerated.item[0] = 0;
- for (i = 0; i < ice->hw_rates->count; i++) {
- if (ice->hw_rates->list[i] == rate) {
- ucontrol->value.enumerated.item[0] = i;
- break;
- }
- }
- }
- spin_unlock_irq(&ice->reg_lock);
- return 0;
-}
-
-static int stdclock_get_spdif_master_type(struct snd_ice1712 *ice)
-{
- /* standard external clock - only single type - SPDIF IN */
- return 0;
-}
-
-/* setting clock to external - SPDIF */
-static int stdclock_set_spdif_clock(struct snd_ice1712 *ice, int type)
-{
- unsigned char oval;
- unsigned char i2s_oval;
- oval = inb(ICEMT1724(ice, RATE));
- outb(oval | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE));
- /* setting 256fs */
- i2s_oval = inb(ICEMT1724(ice, I2S_FORMAT));
- outb(i2s_oval & ~VT1724_MT_I2S_MCLK_128X, ICEMT1724(ice, I2S_FORMAT));
- return 0;
-}
-
-
-static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned int old_rate, new_rate;
- unsigned int item = ucontrol->value.enumerated.item[0];
- unsigned int first_ext_clock = ice->hw_rates->count;
-
- if (item > first_ext_clock + ice->ext_clock_count - 1)
- return -EINVAL;
-
- /* if rate = 0 => external clock */
- spin_lock_irq(&ice->reg_lock);
- if (ice->is_spdif_master(ice))
- old_rate = 0;
- else
- old_rate = ice->get_rate(ice);
- if (item >= first_ext_clock) {
- /* switching to external clock */
- ice->set_spdif_clock(ice, item - first_ext_clock);
- new_rate = 0;
- } else {
- /* internal on-card clock */
- new_rate = ice->hw_rates->list[item];
- ice->pro_rate_default = new_rate;
- spin_unlock_irq(&ice->reg_lock);
- snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 1);
- spin_lock_irq(&ice->reg_lock);
- }
- spin_unlock_irq(&ice->reg_lock);
-
- /* the first switch to the ext. clock mode? */
- if (old_rate != new_rate && !new_rate) {
- /* notify akm chips as well */
- unsigned int i;
- if (ice->gpio.set_pro_rate)
- ice->gpio.set_pro_rate(ice, 0);
- for (i = 0; i < ice->akm_codecs; i++) {
- if (ice->akm[i].ops.set_rate_val)
- ice->akm[i].ops.set_rate_val(&ice->akm[i], 0);
- }
- }
- return old_rate != new_rate;
-}
-
-static struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Multi Track Internal Clock",
- .info = snd_vt1724_pro_internal_clock_info,
- .get = snd_vt1724_pro_internal_clock_get,
- .put = snd_vt1724_pro_internal_clock_put
-};
-
-#define snd_vt1724_pro_rate_locking_info snd_ctl_boolean_mono_info
-
-static int snd_vt1724_pro_rate_locking_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = PRO_RATE_LOCKED;
- return 0;
-}
-
-static int snd_vt1724_pro_rate_locking_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int change = 0, nval;
-
- nval = ucontrol->value.integer.value[0] ? 1 : 0;
- spin_lock_irq(&ice->reg_lock);
- change = PRO_RATE_LOCKED != nval;
- PRO_RATE_LOCKED = nval;
- spin_unlock_irq(&ice->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Multi Track Rate Locking",
- .info = snd_vt1724_pro_rate_locking_info,
- .get = snd_vt1724_pro_rate_locking_get,
- .put = snd_vt1724_pro_rate_locking_put
-};
-
-#define snd_vt1724_pro_rate_reset_info snd_ctl_boolean_mono_info
-
-static int snd_vt1724_pro_rate_reset_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = PRO_RATE_RESET ? 1 : 0;
- return 0;
-}
-
-static int snd_vt1724_pro_rate_reset_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int change = 0, nval;
-
- nval = ucontrol->value.integer.value[0] ? 1 : 0;
- spin_lock_irq(&ice->reg_lock);
- change = PRO_RATE_RESET != nval;
- PRO_RATE_RESET = nval;
- spin_unlock_irq(&ice->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Multi Track Rate Reset",
- .info = snd_vt1724_pro_rate_reset_info,
- .get = snd_vt1724_pro_rate_reset_get,
- .put = snd_vt1724_pro_rate_reset_put
-};
-
-
-/*
- * routing
- */
-static int snd_vt1724_pro_route_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = {
- "PCM Out", /* 0 */
- "H/W In 0", "H/W In 1", /* 1-2 */
- "IEC958 In L", "IEC958 In R", /* 3-4 */
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 5;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static inline int analog_route_shift(int idx)
-{
- return (idx % 2) * 12 + ((idx / 2) * 3) + 8;
-}
-
-static inline int digital_route_shift(int idx)
-{
- return idx * 3;
-}
-
-int snd_ice1724_get_route_val(struct snd_ice1712 *ice, int shift)
-{
- unsigned long val;
- unsigned char eitem;
- static const unsigned char xlate[8] = {
- 0, 255, 1, 2, 255, 255, 3, 4,
- };
-
- val = inl(ICEMT1724(ice, ROUTE_PLAYBACK));
- val >>= shift;
- val &= 7; /* we now have 3 bits per output */
- eitem = xlate[val];
- if (eitem == 255) {
- snd_BUG();
- return 0;
- }
- return eitem;
-}
-
-int snd_ice1724_put_route_val(struct snd_ice1712 *ice, unsigned int val,
- int shift)
-{
- unsigned int old_val, nval;
- int change;
- static const unsigned char xroute[8] = {
- 0, /* PCM */
- 2, /* PSDIN0 Left */
- 3, /* PSDIN0 Right */
- 6, /* SPDIN Left */
- 7, /* SPDIN Right */
- };
-
- nval = xroute[val % 5];
- val = old_val = inl(ICEMT1724(ice, ROUTE_PLAYBACK));
- val &= ~(0x07 << shift);
- val |= nval << shift;
- change = val != old_val;
- if (change)
- outl(val, ICEMT1724(ice, ROUTE_PLAYBACK));
- return change;
-}
-
-static int snd_vt1724_pro_route_analog_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- ucontrol->value.enumerated.item[0] =
- snd_ice1724_get_route_val(ice, analog_route_shift(idx));
- return 0;
-}
-
-static int snd_vt1724_pro_route_analog_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- return snd_ice1724_put_route_val(ice,
- ucontrol->value.enumerated.item[0],
- analog_route_shift(idx));
-}
-
-static int snd_vt1724_pro_route_spdif_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- ucontrol->value.enumerated.item[0] =
- snd_ice1724_get_route_val(ice, digital_route_shift(idx));
- return 0;
-}
-
-static int snd_vt1724_pro_route_spdif_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- return snd_ice1724_put_route_val(ice,
- ucontrol->value.enumerated.item[0],
- digital_route_shift(idx));
-}
-
-static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "H/W Playback Route",
- .info = snd_vt1724_pro_route_info,
- .get = snd_vt1724_pro_route_analog_get,
- .put = snd_vt1724_pro_route_analog_put,
-};
-
-static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route",
- .info = snd_vt1724_pro_route_info,
- .get = snd_vt1724_pro_route_spdif_get,
- .put = snd_vt1724_pro_route_spdif_put,
- .count = 2,
-};
-
-
-static int snd_vt1724_pro_peak_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 22; /* FIXME: for compatibility with ice1712... */
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 255;
- return 0;
-}
-
-static int snd_vt1724_pro_peak_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int idx;
-
- spin_lock_irq(&ice->reg_lock);
- for (idx = 0; idx < 22; idx++) {
- outb(idx, ICEMT1724(ice, MONITOR_PEAKINDEX));
- ucontrol->value.integer.value[idx] =
- inb(ICEMT1724(ice, MONITOR_PEAKDATA));
- }
- spin_unlock_irq(&ice->reg_lock);
- return 0;
-}
-
-static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "Multi Track Peak",
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .info = snd_vt1724_pro_peak_info,
- .get = snd_vt1724_pro_peak_get
-};
-
-/*
- *
- */
-
-static struct snd_ice1712_card_info no_matched __devinitdata;
-
-
-/*
- ooAoo cards with no controls
-*/
-static unsigned char ooaoo_sq210_eeprom[] __devinitdata = {
- [ICE_EEP2_SYSCONF] = 0x4c, /* 49MHz crystal, no mpu401, no ADC,
- 1xDACs */
- [ICE_EEP2_ACLINK] = 0x80, /* I2S */
- [ICE_EEP2_I2S] = 0x78, /* no volume, 96k, 24bit, 192k */
- [ICE_EEP2_SPDIF] = 0xc1, /* out-en, out-int, out-ext */
- [ICE_EEP2_GPIO_DIR] = 0x00, /* no GPIOs are used */
- [ICE_EEP2_GPIO_DIR1] = 0x00,
- [ICE_EEP2_GPIO_DIR2] = 0x00,
- [ICE_EEP2_GPIO_MASK] = 0xff,
- [ICE_EEP2_GPIO_MASK1] = 0xff,
- [ICE_EEP2_GPIO_MASK2] = 0xff,
-
- [ICE_EEP2_GPIO_STATE] = 0x00, /* inputs */
- [ICE_EEP2_GPIO_STATE1] = 0x00, /* all 1, but GPIO_CPLD_RW
- and GPIO15 always zero */
- [ICE_EEP2_GPIO_STATE2] = 0x00, /* inputs */
-};
-
-
-struct snd_ice1712_card_info snd_vt1724_ooaoo_cards[] __devinitdata = {
- {
- .name = "ooAoo SQ210a",
- .model = "sq210a",
- .eeprom_size = sizeof(ooaoo_sq210_eeprom),
- .eeprom_data = ooaoo_sq210_eeprom,
- },
- { } /* terminator */
-};
-
-static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
- snd_vt1724_revo_cards,
- snd_vt1724_amp_cards,
- snd_vt1724_aureon_cards,
- snd_vt1720_mobo_cards,
- snd_vt1720_pontis_cards,
- snd_vt1724_prodigy_hifi_cards,
- snd_vt1724_prodigy192_cards,
- snd_vt1724_juli_cards,
- snd_vt1724_maya44_cards,
- snd_vt1724_phase_cards,
- snd_vt1724_wtm_cards,
- snd_vt1724_se_cards,
- snd_vt1724_qtet_cards,
- snd_vt1724_ooaoo_cards,
- NULL,
-};
-
-
-/*
- */
-
-static void wait_i2c_busy(struct snd_ice1712 *ice)
-{
- int t = 0x10000;
- while ((inb(ICEREG1724(ice, I2C_CTRL)) & VT1724_I2C_BUSY) && t--)
- ;
- if (t == -1)
- printk(KERN_ERR "ice1724: i2c busy timeout\n");
-}
-
-unsigned char snd_vt1724_read_i2c(struct snd_ice1712 *ice,
- unsigned char dev, unsigned char addr)
-{
- unsigned char val;
-
- mutex_lock(&ice->i2c_mutex);
- wait_i2c_busy(ice);
- outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR));
- outb(dev & ~VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR));
- wait_i2c_busy(ice);
- val = inb(ICEREG1724(ice, I2C_DATA));
- mutex_unlock(&ice->i2c_mutex);
- /*
- printk(KERN_DEBUG "i2c_read: [0x%x,0x%x] = 0x%x\n", dev, addr, val);
- */
- return val;
-}
-
-void snd_vt1724_write_i2c(struct snd_ice1712 *ice,
- unsigned char dev, unsigned char addr, unsigned char data)
-{
- mutex_lock(&ice->i2c_mutex);
- wait_i2c_busy(ice);
- /*
- printk(KERN_DEBUG "i2c_write: [0x%x,0x%x] = 0x%x\n", dev, addr, data);
- */
- outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR));
- outb(data, ICEREG1724(ice, I2C_DATA));
- outb(dev | VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR));
- wait_i2c_busy(ice);
- mutex_unlock(&ice->i2c_mutex);
-}
-
-static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice,
- const char *modelname)
-{
- const int dev = 0xa0; /* EEPROM device address */
- unsigned int i, size;
- struct snd_ice1712_card_info * const *tbl, *c;
-
- if (!modelname || !*modelname) {
- ice->eeprom.subvendor = 0;
- if ((inb(ICEREG1724(ice, I2C_CTRL)) & VT1724_I2C_EEPROM) != 0)
- ice->eeprom.subvendor =
- (snd_vt1724_read_i2c(ice, dev, 0x00) << 0) |
- (snd_vt1724_read_i2c(ice, dev, 0x01) << 8) |
- (snd_vt1724_read_i2c(ice, dev, 0x02) << 16) |
- (snd_vt1724_read_i2c(ice, dev, 0x03) << 24);
- if (ice->eeprom.subvendor == 0 ||
- ice->eeprom.subvendor == (unsigned int)-1) {
- /* invalid subvendor from EEPROM, try the PCI
- * subststem ID instead
- */
- u16 vendor, device;
- pci_read_config_word(ice->pci, PCI_SUBSYSTEM_VENDOR_ID,
- &vendor);
- pci_read_config_word(ice->pci, PCI_SUBSYSTEM_ID, &device);
- ice->eeprom.subvendor =
- ((unsigned int)swab16(vendor) << 16) | swab16(device);
- if (ice->eeprom.subvendor == 0 ||
- ice->eeprom.subvendor == (unsigned int)-1) {
- printk(KERN_ERR "ice1724: No valid ID is found\n");
- return -ENXIO;
- }
- }
- }
- for (tbl = card_tables; *tbl; tbl++) {
- for (c = *tbl; c->name; c++) {
- if (modelname && c->model &&
- !strcmp(modelname, c->model)) {
- printk(KERN_INFO "ice1724: Using board model %s\n",
- c->name);
- ice->eeprom.subvendor = c->subvendor;
- } else if (c->subvendor != ice->eeprom.subvendor)
- continue;
- if (!c->eeprom_size || !c->eeprom_data)
- goto found;
- /* if the EEPROM is given by the driver, use it */
- snd_printdd("using the defined eeprom..\n");
- ice->eeprom.version = 2;
- ice->eeprom.size = c->eeprom_size + 6;
- memcpy(ice->eeprom.data, c->eeprom_data, c->eeprom_size);
- goto read_skipped;
- }
- }
- printk(KERN_WARNING "ice1724: No matching model found for ID 0x%x\n",
- ice->eeprom.subvendor);
-
- found:
- ice->eeprom.size = snd_vt1724_read_i2c(ice, dev, 0x04);
- if (ice->eeprom.size < 6)
- ice->eeprom.size = 32;
- else if (ice->eeprom.size > 32) {
- printk(KERN_ERR "ice1724: Invalid EEPROM (size = %i)\n",
- ice->eeprom.size);
- return -EIO;
- }
- ice->eeprom.version = snd_vt1724_read_i2c(ice, dev, 0x05);
- if (ice->eeprom.version != 2)
- printk(KERN_WARNING "ice1724: Invalid EEPROM version %i\n",
- ice->eeprom.version);
- size = ice->eeprom.size - 6;
- for (i = 0; i < size; i++)
- ice->eeprom.data[i] = snd_vt1724_read_i2c(ice, dev, i + 6);
-
- read_skipped:
- ice->eeprom.gpiomask = eeprom_triple(ice, ICE_EEP2_GPIO_MASK);
- ice->eeprom.gpiostate = eeprom_triple(ice, ICE_EEP2_GPIO_STATE);
- ice->eeprom.gpiodir = eeprom_triple(ice, ICE_EEP2_GPIO_DIR);
-
- return 0;
-}
-
-
-
-static void snd_vt1724_chip_reset(struct snd_ice1712 *ice)
-{
- outb(VT1724_RESET , ICEREG1724(ice, CONTROL));
- inb(ICEREG1724(ice, CONTROL)); /* pci posting flush */
- msleep(10);
- outb(0, ICEREG1724(ice, CONTROL));
- inb(ICEREG1724(ice, CONTROL)); /* pci posting flush */
- msleep(10);
-}
-
-static int snd_vt1724_chip_init(struct snd_ice1712 *ice)
-{
- outb(ice->eeprom.data[ICE_EEP2_SYSCONF], ICEREG1724(ice, SYS_CFG));
- outb(ice->eeprom.data[ICE_EEP2_ACLINK], ICEREG1724(ice, AC97_CFG));
- outb(ice->eeprom.data[ICE_EEP2_I2S], ICEREG1724(ice, I2S_FEATURES));
- outb(ice->eeprom.data[ICE_EEP2_SPDIF], ICEREG1724(ice, SPDIF_CFG));
-
- ice->gpio.write_mask = ice->eeprom.gpiomask;
- ice->gpio.direction = ice->eeprom.gpiodir;
- snd_vt1724_set_gpio_mask(ice, ice->eeprom.gpiomask);
- snd_vt1724_set_gpio_dir(ice, ice->eeprom.gpiodir);
- snd_vt1724_set_gpio_data(ice, ice->eeprom.gpiostate);
-
- outb(0, ICEREG1724(ice, POWERDOWN));
-
- /* MPU_RX and TX irq masks are cleared later dynamically */
- outb(VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX , ICEREG1724(ice, IRQMASK));
-
- /* don't handle FIFO overrun/underruns (just yet),
- * since they cause machine lockups
- */
- outb(VT1724_MULTI_FIFO_ERR, ICEMT1724(ice, DMA_INT_MASK));
-
- return 0;
-}
-
-static int __devinit snd_vt1724_spdif_build_controls(struct snd_ice1712 *ice)
-{
- int err;
- struct snd_kcontrol *kctl;
-
- if (snd_BUG_ON(!ice->pcm))
- return -EIO;
-
- if (!ice->own_routing) {
- err = snd_ctl_add(ice->card,
- snd_ctl_new1(&snd_vt1724_mixer_pro_spdif_route, ice));
- if (err < 0)
- return err;
- }
-
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_spdif_switch, ice));
- if (err < 0)
- return err;
-
- err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_default, ice));
- if (err < 0)
- return err;
- kctl->id.device = ice->pcm->device;
- err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_maskc, ice));
- if (err < 0)
- return err;
- kctl->id.device = ice->pcm->device;
- err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_maskp, ice));
- if (err < 0)
- return err;
- kctl->id.device = ice->pcm->device;
-#if 0 /* use default only */
- err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_stream, ice));
- if (err < 0)
- return err;
- kctl->id.device = ice->pcm->device;
- ice->spdif.stream_ctl = kctl;
-#endif
- return 0;
-}
-
-
-static int __devinit snd_vt1724_build_controls(struct snd_ice1712 *ice)
-{
- int err;
-
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_eeprom, ice));
- if (err < 0)
- return err;
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_pro_internal_clock, ice));
- if (err < 0)
- return err;
-
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_pro_rate_locking, ice));
- if (err < 0)
- return err;
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_pro_rate_reset, ice));
- if (err < 0)
- return err;
-
- if (!ice->own_routing && ice->num_total_dacs > 0) {
- struct snd_kcontrol_new tmp = snd_vt1724_mixer_pro_analog_route;
- tmp.count = ice->num_total_dacs;
- if (ice->vt1720 && tmp.count > 2)
- tmp.count = 2;
- err = snd_ctl_add(ice->card, snd_ctl_new1(&tmp, ice));
- if (err < 0)
- return err;
- }
-
- err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_mixer_pro_peak, ice));
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static int snd_vt1724_free(struct snd_ice1712 *ice)
-{
- if (!ice->port)
- goto __hw_end;
- /* mask all interrupts */
- outb(0xff, ICEMT1724(ice, DMA_INT_MASK));
- outb(0xff, ICEREG1724(ice, IRQMASK));
- /* --- */
-__hw_end:
- if (ice->irq >= 0)
- free_irq(ice->irq, ice);
- pci_release_regions(ice->pci);
- snd_ice1712_akm4xxx_free(ice);
- pci_disable_device(ice->pci);
- kfree(ice->spec);
- kfree(ice);
- return 0;
-}
-
-static int snd_vt1724_dev_free(struct snd_device *device)
-{
- struct snd_ice1712 *ice = device->device_data;
- return snd_vt1724_free(ice);
-}
-
-static int __devinit snd_vt1724_create(struct snd_card *card,
- struct pci_dev *pci,
- const char *modelname,
- struct snd_ice1712 **r_ice1712)
-{
- struct snd_ice1712 *ice;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_vt1724_dev_free,
- };
-
- *r_ice1712 = NULL;
-
- /* enable PCI device */
- err = pci_enable_device(pci);
- if (err < 0)
- return err;
-
- ice = kzalloc(sizeof(*ice), GFP_KERNEL);
- if (ice == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
- ice->vt1724 = 1;
- spin_lock_init(&ice->reg_lock);
- mutex_init(&ice->gpio_mutex);
- mutex_init(&ice->open_mutex);
- mutex_init(&ice->i2c_mutex);
- ice->gpio.set_mask = snd_vt1724_set_gpio_mask;
- ice->gpio.get_mask = snd_vt1724_get_gpio_mask;
- ice->gpio.set_dir = snd_vt1724_set_gpio_dir;
- ice->gpio.get_dir = snd_vt1724_get_gpio_dir;
- ice->gpio.set_data = snd_vt1724_set_gpio_data;
- ice->gpio.get_data = snd_vt1724_get_gpio_data;
- ice->card = card;
- ice->pci = pci;
- ice->irq = -1;
- pci_set_master(pci);
- snd_vt1724_proc_init(ice);
- synchronize_irq(pci->irq);
-
- card->private_data = ice;
-
- err = pci_request_regions(pci, "ICE1724");
- if (err < 0) {
- kfree(ice);
- pci_disable_device(pci);
- return err;
- }
- ice->port = pci_resource_start(pci, 0);
- ice->profi_port = pci_resource_start(pci, 1);
-
- if (request_irq(pci->irq, snd_vt1724_interrupt,
- IRQF_SHARED, KBUILD_MODNAME, ice)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_vt1724_free(ice);
- return -EIO;
- }
-
- ice->irq = pci->irq;
-
- snd_vt1724_chip_reset(ice);
- if (snd_vt1724_read_eeprom(ice, modelname) < 0) {
- snd_vt1724_free(ice);
- return -EIO;
- }
- if (snd_vt1724_chip_init(ice) < 0) {
- snd_vt1724_free(ice);
- return -EIO;
- }
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops);
- if (err < 0) {
- snd_vt1724_free(ice);
- return err;
- }
-
- snd_card_set_dev(card, &pci->dev);
-
- *r_ice1712 = ice;
- return 0;
-}
-
-
-/*
- *
- * Registration
- *
- */
-
-static int __devinit snd_vt1724_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct snd_ice1712 *ice;
- int pcm_dev = 0, err;
- struct snd_ice1712_card_info * const *tbl, *c;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- strcpy(card->driver, "ICE1724");
- strcpy(card->shortname, "ICEnsemble ICE1724");
-
- err = snd_vt1724_create(card, pci, model[dev], &ice);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- /* field init before calling chip_init */
- ice->ext_clock_count = 0;
-
- for (tbl = card_tables; *tbl; tbl++) {
- for (c = *tbl; c->name; c++) {
- if ((model[dev] && c->model &&
- !strcmp(model[dev], c->model)) ||
- (c->subvendor == ice->eeprom.subvendor)) {
- strcpy(card->shortname, c->name);
- if (c->driver) /* specific driver? */
- strcpy(card->driver, c->driver);
- if (c->chip_init) {
- err = c->chip_init(ice);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- }
- goto __found;
- }
- }
- }
- c = &no_matched;
-__found:
- /*
- * VT1724 has separate DMAs for the analog and the SPDIF streams while
- * ICE1712 has only one for both (mixed up).
- *
- * Confusingly the analog PCM is named "professional" here because it
- * was called so in ice1712 driver, and vt1724 driver is derived from
- * ice1712 driver.
- */
- ice->pro_rate_default = PRO_RATE_DEFAULT;
- if (!ice->is_spdif_master)
- ice->is_spdif_master = stdclock_is_spdif_master;
- if (!ice->get_rate)
- ice->get_rate = stdclock_get_rate;
- if (!ice->set_rate)
- ice->set_rate = stdclock_set_rate;
- if (!ice->set_mclk)
- ice->set_mclk = stdclock_set_mclk;
- if (!ice->set_spdif_clock)
- ice->set_spdif_clock = stdclock_set_spdif_clock;
- if (!ice->get_spdif_master_type)
- ice->get_spdif_master_type = stdclock_get_spdif_master_type;
- if (!ice->ext_clock_names)
- ice->ext_clock_names = ext_clock_names;
- if (!ice->ext_clock_count)
- ice->ext_clock_count = ARRAY_SIZE(ext_clock_names);
-
- if (!ice->hw_rates)
- set_std_hw_rates(ice);
-
- err = snd_vt1724_pcm_profi(ice, pcm_dev++);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- err = snd_vt1724_pcm_spdif(ice, pcm_dev++);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- err = snd_vt1724_pcm_indep(ice, pcm_dev++);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- err = snd_vt1724_ac97_mixer(ice);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- err = snd_vt1724_build_controls(ice);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- if (ice->pcm && ice->has_spdif) { /* has SPDIF I/O */
- err = snd_vt1724_spdif_build_controls(ice);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- }
-
- if (c->build_controls) {
- err = c->build_controls(ice);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- }
-
- if (!c->no_mpu401) {
- if (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401) {
- struct snd_rawmidi *rmidi;
-
- err = snd_rawmidi_new(card, "MIDI", 0, 1, 1, &rmidi);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- ice->rmidi[0] = rmidi;
- rmidi->private_data = ice;
- strcpy(rmidi->name, "ICE1724 MIDI");
- rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
- &vt1724_midi_output_ops);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
- &vt1724_midi_input_ops);
-
- /* set watermarks */
- outb(VT1724_MPU_RX_FIFO | 0x1,
- ICEREG1724(ice, MPU_FIFO_WM));
- outb(0x1, ICEREG1724(ice, MPU_FIFO_WM));
- /* set UART mode */
- outb(VT1724_MPU_UART, ICEREG1724(ice, MPU_CTRL));
- }
- }
-
- sprintf(card->longname, "%s at 0x%lx, irq %i",
- card->shortname, ice->port, ice->irq);
-
- err = snd_card_register(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_vt1724_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-#ifdef CONFIG_PM
-static int snd_vt1724_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_ice1712 *ice = card->private_data;
-
- if (!ice->pm_suspend_enabled)
- return 0;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-
- snd_pcm_suspend_all(ice->pcm);
- snd_pcm_suspend_all(ice->pcm_pro);
- snd_pcm_suspend_all(ice->pcm_ds);
- snd_ac97_suspend(ice->ac97);
-
- spin_lock_irq(&ice->reg_lock);
- ice->pm_saved_is_spdif_master = ice->is_spdif_master(ice);
- ice->pm_saved_spdif_ctrl = inw(ICEMT1724(ice, SPDIF_CTRL));
- ice->pm_saved_spdif_cfg = inb(ICEREG1724(ice, SPDIF_CFG));
- ice->pm_saved_route = inl(ICEMT1724(ice, ROUTE_PLAYBACK));
- spin_unlock_irq(&ice->reg_lock);
-
- if (ice->pm_suspend)
- ice->pm_suspend(ice);
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int snd_vt1724_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_ice1712 *ice = card->private_data;
-
- if (!ice->pm_suspend_enabled)
- return 0;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
-
- if (pci_enable_device(pci) < 0) {
- snd_card_disconnect(card);
- return -EIO;
- }
-
- pci_set_master(pci);
-
- snd_vt1724_chip_reset(ice);
-
- if (snd_vt1724_chip_init(ice) < 0) {
- snd_card_disconnect(card);
- return -EIO;
- }
-
- if (ice->pm_resume)
- ice->pm_resume(ice);
-
- if (ice->pm_saved_is_spdif_master) {
- /* switching to external clock via SPDIF */
- ice->set_spdif_clock(ice, 0);
- } else {
- /* internal on-card clock */
- snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 1);
- }
-
- update_spdif_bits(ice, ice->pm_saved_spdif_ctrl);
-
- outb(ice->pm_saved_spdif_cfg, ICEREG1724(ice, SPDIF_CFG));
- outl(ice->pm_saved_route, ICEMT1724(ice, ROUTE_PLAYBACK));
-
- if (ice->ac97)
- snd_ac97_resume(ice->ac97);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_vt1724_ids,
- .probe = snd_vt1724_probe,
- .remove = __devexit_p(snd_vt1724_remove),
-#ifdef CONFIG_PM
- .suspend = snd_vt1724_suspend,
- .resume = snd_vt1724_resume,
-#endif
-};
-
-static int __init alsa_card_ice1724_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_ice1724_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_ice1724_init)
-module_exit(alsa_card_ice1724_exit)
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/juli.c b/ANDROID_3.4.5/sound/pci/ice1712/juli.c
deleted file mode 100644
index 98bc3b76..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/juli.c
+++ /dev/null
@@ -1,700 +0,0 @@
-/*
- * ALSA driver for ICEnsemble VT1724 (Envy24HT)
- *
- * Lowlevel functions for ESI Juli@ cards
- *
- * Copyright (c) 2004 Jaroslav Kysela <perex@perex.cz>
- * 2008 Pavel Hofman <dustin@seznam.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/tlv.h>
-
-#include "ice1712.h"
-#include "envy24ht.h"
-#include "juli.h"
-
-struct juli_spec {
- struct ak4114 *ak4114;
- unsigned int analog:1;
-};
-
-/*
- * chip addresses on I2C bus
- */
-#define AK4114_ADDR 0x20 /* S/PDIF receiver */
-#define AK4358_ADDR 0x22 /* DAC */
-
-/*
- * Juli does not use the standard ICE1724 clock scheme. Juli's ice1724 chip is
- * supplied by external clock provided by Xilinx array and MK73-1 PLL frequency
- * multiplier. Actual frequency is set by ice1724 GPIOs hooked to the Xilinx.
- *
- * The clock circuitry is supplied by the two ice1724 crystals. This
- * arrangement allows to generate independent clock signal for AK4114's input
- * rate detection circuit. As a result, Juli, unlike most other
- * ice1724+ak4114-based cards, detects spdif input rate correctly.
- * This fact is applied in the driver, allowing to modify PCM stream rate
- * parameter according to the actual input rate.
- *
- * Juli uses the remaining three stereo-channels of its DAC to optionally
- * monitor analog input, digital input, and digital output. The corresponding
- * I2S signals are routed by Xilinx, controlled by GPIOs.
- *
- * The master mute is implemented using output muting transistors (GPIO) in
- * combination with smuting the DAC.
- *
- * The card itself has no HW master volume control, implemented using the
- * vmaster control.
- *
- * TODO:
- * researching and fixing the input monitors
- */
-
-/*
- * GPIO pins
- */
-#define GPIO_FREQ_MASK (3<<0)
-#define GPIO_FREQ_32KHZ (0<<0)
-#define GPIO_FREQ_44KHZ (1<<0)
-#define GPIO_FREQ_48KHZ (2<<0)
-#define GPIO_MULTI_MASK (3<<2)
-#define GPIO_MULTI_4X (0<<2)
-#define GPIO_MULTI_2X (1<<2)
-#define GPIO_MULTI_1X (2<<2) /* also external */
-#define GPIO_MULTI_HALF (3<<2)
-#define GPIO_INTERNAL_CLOCK (1<<4) /* 0 = external, 1 = internal */
-#define GPIO_CLOCK_MASK (1<<4)
-#define GPIO_ANALOG_PRESENT (1<<5) /* RO only: 0 = present */
-#define GPIO_RXMCLK_SEL (1<<7) /* must be 0 */
-#define GPIO_AK5385A_CKS0 (1<<8)
-#define GPIO_AK5385A_DFS1 (1<<9)
-#define GPIO_AK5385A_DFS0 (1<<10)
-#define GPIO_DIGOUT_MONITOR (1<<11) /* 1 = active */
-#define GPIO_DIGIN_MONITOR (1<<12) /* 1 = active */
-#define GPIO_ANAIN_MONITOR (1<<13) /* 1 = active */
-#define GPIO_AK5385A_CKS1 (1<<14) /* must be 0 */
-#define GPIO_MUTE_CONTROL (1<<15) /* output mute, 1 = muted */
-
-#define GPIO_RATE_MASK (GPIO_FREQ_MASK | GPIO_MULTI_MASK | \
- GPIO_CLOCK_MASK)
-#define GPIO_AK5385A_MASK (GPIO_AK5385A_CKS0 | GPIO_AK5385A_DFS0 | \
- GPIO_AK5385A_DFS1 | GPIO_AK5385A_CKS1)
-
-#define JULI_PCM_RATE (SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \
- SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
- SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000)
-
-#define GPIO_RATE_16000 (GPIO_FREQ_32KHZ | GPIO_MULTI_HALF | \
- GPIO_INTERNAL_CLOCK)
-#define GPIO_RATE_22050 (GPIO_FREQ_44KHZ | GPIO_MULTI_HALF | \
- GPIO_INTERNAL_CLOCK)
-#define GPIO_RATE_24000 (GPIO_FREQ_48KHZ | GPIO_MULTI_HALF | \
- GPIO_INTERNAL_CLOCK)
-#define GPIO_RATE_32000 (GPIO_FREQ_32KHZ | GPIO_MULTI_1X | \
- GPIO_INTERNAL_CLOCK)
-#define GPIO_RATE_44100 (GPIO_FREQ_44KHZ | GPIO_MULTI_1X | \
- GPIO_INTERNAL_CLOCK)
-#define GPIO_RATE_48000 (GPIO_FREQ_48KHZ | GPIO_MULTI_1X | \
- GPIO_INTERNAL_CLOCK)
-#define GPIO_RATE_64000 (GPIO_FREQ_32KHZ | GPIO_MULTI_2X | \
- GPIO_INTERNAL_CLOCK)
-#define GPIO_RATE_88200 (GPIO_FREQ_44KHZ | GPIO_MULTI_2X | \
- GPIO_INTERNAL_CLOCK)
-#define GPIO_RATE_96000 (GPIO_FREQ_48KHZ | GPIO_MULTI_2X | \
- GPIO_INTERNAL_CLOCK)
-#define GPIO_RATE_176400 (GPIO_FREQ_44KHZ | GPIO_MULTI_4X | \
- GPIO_INTERNAL_CLOCK)
-#define GPIO_RATE_192000 (GPIO_FREQ_48KHZ | GPIO_MULTI_4X | \
- GPIO_INTERNAL_CLOCK)
-
-/*
- * Initial setup of the conversion array GPIO <-> rate
- */
-static unsigned int juli_rates[] = {
- 16000, 22050, 24000, 32000,
- 44100, 48000, 64000, 88200,
- 96000, 176400, 192000,
-};
-
-static unsigned int gpio_vals[] = {
- GPIO_RATE_16000, GPIO_RATE_22050, GPIO_RATE_24000, GPIO_RATE_32000,
- GPIO_RATE_44100, GPIO_RATE_48000, GPIO_RATE_64000, GPIO_RATE_88200,
- GPIO_RATE_96000, GPIO_RATE_176400, GPIO_RATE_192000,
-};
-
-static struct snd_pcm_hw_constraint_list juli_rates_info = {
- .count = ARRAY_SIZE(juli_rates),
- .list = juli_rates,
- .mask = 0,
-};
-
-static int get_gpio_val(int rate)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(juli_rates); i++)
- if (juli_rates[i] == rate)
- return gpio_vals[i];
- return 0;
-}
-
-static void juli_ak4114_write(void *private_data, unsigned char reg,
- unsigned char val)
-{
- snd_vt1724_write_i2c((struct snd_ice1712 *)private_data, AK4114_ADDR,
- reg, val);
-}
-
-static unsigned char juli_ak4114_read(void *private_data, unsigned char reg)
-{
- return snd_vt1724_read_i2c((struct snd_ice1712 *)private_data,
- AK4114_ADDR, reg);
-}
-
-/*
- * If SPDIF capture and slaved to SPDIF-IN, setting runtime rate
- * to the external rate
- */
-static void juli_spdif_in_open(struct snd_ice1712 *ice,
- struct snd_pcm_substream *substream)
-{
- struct juli_spec *spec = ice->spec;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int rate;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
- !ice->is_spdif_master(ice))
- return;
- rate = snd_ak4114_external_rate(spec->ak4114);
- if (rate >= runtime->hw.rate_min && rate <= runtime->hw.rate_max) {
- runtime->hw.rate_min = rate;
- runtime->hw.rate_max = rate;
- }
-}
-
-/*
- * AK4358 section
- */
-
-static void juli_akm_lock(struct snd_akm4xxx *ak, int chip)
-{
-}
-
-static void juli_akm_unlock(struct snd_akm4xxx *ak, int chip)
-{
-}
-
-static void juli_akm_write(struct snd_akm4xxx *ak, int chip,
- unsigned char addr, unsigned char data)
-{
- struct snd_ice1712 *ice = ak->private_data[0];
-
- if (snd_BUG_ON(chip))
- return;
- snd_vt1724_write_i2c(ice, AK4358_ADDR, addr, data);
-}
-
-/*
- * change the rate of envy24HT, AK4358, AK5385
- */
-static void juli_akm_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
-{
- unsigned char old, tmp, ak4358_dfs;
- unsigned int ak5385_pins, old_gpio, new_gpio;
- struct snd_ice1712 *ice = ak->private_data[0];
- struct juli_spec *spec = ice->spec;
-
- if (rate == 0) /* no hint - S/PDIF input is master or the new spdif
- input rate undetected, simply return */
- return;
-
- /* adjust DFS on codecs */
- if (rate > 96000) {
- ak4358_dfs = 2;
- ak5385_pins = GPIO_AK5385A_DFS1 | GPIO_AK5385A_CKS0;
- } else if (rate > 48000) {
- ak4358_dfs = 1;
- ak5385_pins = GPIO_AK5385A_DFS0;
- } else {
- ak4358_dfs = 0;
- ak5385_pins = 0;
- }
- /* AK5385 first, since it requires cold reset affecting both codecs */
- old_gpio = ice->gpio.get_data(ice);
- new_gpio = (old_gpio & ~GPIO_AK5385A_MASK) | ak5385_pins;
- /* printk(KERN_DEBUG "JULI - ak5385 set_rate_val: new gpio 0x%x\n",
- new_gpio); */
- ice->gpio.set_data(ice, new_gpio);
-
- /* cold reset */
- old = inb(ICEMT1724(ice, AC97_CMD));
- outb(old | VT1724_AC97_COLD, ICEMT1724(ice, AC97_CMD));
- udelay(1);
- outb(old & ~VT1724_AC97_COLD, ICEMT1724(ice, AC97_CMD));
-
- /* AK4358 */
- /* set new value, reset DFS */
- tmp = snd_akm4xxx_get(ak, 0, 2);
- snd_akm4xxx_reset(ak, 1);
- tmp = snd_akm4xxx_get(ak, 0, 2);
- tmp &= ~(0x03 << 4);
- tmp |= ak4358_dfs << 4;
- snd_akm4xxx_set(ak, 0, 2, tmp);
- snd_akm4xxx_reset(ak, 0);
-
- /* reinit ak4114 */
- snd_ak4114_reinit(spec->ak4114);
-}
-
-#define AK_DAC(xname, xch) { .name = xname, .num_channels = xch }
-#define PCM_VOLUME "PCM Playback Volume"
-#define MONITOR_AN_IN_VOLUME "Monitor Analog In Volume"
-#define MONITOR_DIG_IN_VOLUME "Monitor Digital In Volume"
-#define MONITOR_DIG_OUT_VOLUME "Monitor Digital Out Volume"
-
-static const struct snd_akm4xxx_dac_channel juli_dac[] = {
- AK_DAC(PCM_VOLUME, 2),
- AK_DAC(MONITOR_AN_IN_VOLUME, 2),
- AK_DAC(MONITOR_DIG_OUT_VOLUME, 2),
- AK_DAC(MONITOR_DIG_IN_VOLUME, 2),
-};
-
-
-static struct snd_akm4xxx akm_juli_dac __devinitdata = {
- .type = SND_AK4358,
- .num_dacs = 8, /* DAC1 - analog out
- DAC2 - analog in monitor
- DAC3 - digital out monitor
- DAC4 - digital in monitor
- */
- .ops = {
- .lock = juli_akm_lock,
- .unlock = juli_akm_unlock,
- .write = juli_akm_write,
- .set_rate_val = juli_akm_set_rate_val
- },
- .dac_info = juli_dac,
-};
-
-#define juli_mute_info snd_ctl_boolean_mono_info
-
-static int juli_mute_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- val = ice->gpio.get_data(ice) & (unsigned int) kcontrol->private_value;
- if (kcontrol->private_value == GPIO_MUTE_CONTROL)
- /* val 0 = signal on */
- ucontrol->value.integer.value[0] = (val) ? 0 : 1;
- else
- /* val 1 = signal on */
- ucontrol->value.integer.value[0] = (val) ? 1 : 0;
- return 0;
-}
-
-static int juli_mute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned int old_gpio, new_gpio;
- old_gpio = ice->gpio.get_data(ice);
- if (ucontrol->value.integer.value[0]) {
- /* unmute */
- if (kcontrol->private_value == GPIO_MUTE_CONTROL) {
- /* 0 = signal on */
- new_gpio = old_gpio & ~GPIO_MUTE_CONTROL;
- /* un-smuting DAC */
- snd_akm4xxx_write(ice->akm, 0, 0x01, 0x01);
- } else
- /* 1 = signal on */
- new_gpio = old_gpio |
- (unsigned int) kcontrol->private_value;
- } else {
- /* mute */
- if (kcontrol->private_value == GPIO_MUTE_CONTROL) {
- /* 1 = signal off */
- new_gpio = old_gpio | GPIO_MUTE_CONTROL;
- /* smuting DAC */
- snd_akm4xxx_write(ice->akm, 0, 0x01, 0x03);
- } else
- /* 0 = signal off */
- new_gpio = old_gpio &
- ~((unsigned int) kcontrol->private_value);
- }
- /* printk(KERN_DEBUG
- "JULI - mute/unmute: control_value: 0x%x, old_gpio: 0x%x, "
- "new_gpio 0x%x\n",
- (unsigned int)ucontrol->value.integer.value[0], old_gpio,
- new_gpio); */
- if (old_gpio != new_gpio) {
- ice->gpio.set_data(ice, new_gpio);
- return 1;
- }
- /* no change */
- return 0;
-}
-
-static struct snd_kcontrol_new juli_mute_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = juli_mute_info,
- .get = juli_mute_get,
- .put = juli_mute_put,
- .private_value = GPIO_MUTE_CONTROL,
- },
- /* Although the following functionality respects the succint NDA'd
- * documentation from the card manufacturer, and the same way of
- * operation is coded in OSS Juli driver, only Digital Out monitor
- * seems to work. Surprisingly, Analog input monitor outputs Digital
- * output data. The two are independent, as enabling both doubles
- * volume of the monitor sound.
- *
- * Checking traces on the board suggests the functionality described
- * by the manufacturer is correct - I2S from ADC and AK4114
- * go to ICE as well as to Xilinx, I2S inputs of DAC2,3,4 (the monitor
- * inputs) are fed from Xilinx.
- *
- * I even checked traces on board and coded a support in driver for
- * an alternative possibility - the unused I2S ICE output channels
- * switched to HW-IN/SPDIF-IN and providing the monitoring signal to
- * the DAC - to no avail. The I2S outputs seem to be unconnected.
- *
- * The windows driver supports the monitoring correctly.
- */
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Monitor Analog In Switch",
- .info = juli_mute_info,
- .get = juli_mute_get,
- .put = juli_mute_put,
- .private_value = GPIO_ANAIN_MONITOR,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Monitor Digital Out Switch",
- .info = juli_mute_info,
- .get = juli_mute_get,
- .put = juli_mute_put,
- .private_value = GPIO_DIGOUT_MONITOR,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Monitor Digital In Switch",
- .info = juli_mute_info,
- .get = juli_mute_get,
- .put = juli_mute_put,
- .private_value = GPIO_DIGIN_MONITOR,
- },
-};
-
-static char *slave_vols[] __devinitdata = {
- PCM_VOLUME,
- MONITOR_AN_IN_VOLUME,
- MONITOR_DIG_IN_VOLUME,
- MONITOR_DIG_OUT_VOLUME,
- NULL
-};
-
-static __devinitdata
-DECLARE_TLV_DB_SCALE(juli_master_db_scale, -6350, 50, 1);
-
-static struct snd_kcontrol __devinit *ctl_find(struct snd_card *card,
- const char *name)
-{
- struct snd_ctl_elem_id sid;
- memset(&sid, 0, sizeof(sid));
- /* FIXME: strcpy is bad. */
- strcpy(sid.name, name);
- sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- return snd_ctl_find_id(card, &sid);
-}
-
-static void __devinit add_slaves(struct snd_card *card,
- struct snd_kcontrol *master, char **list)
-{
- for (; *list; list++) {
- struct snd_kcontrol *slave = ctl_find(card, *list);
- /* printk(KERN_DEBUG "add_slaves - %s\n", *list); */
- if (slave) {
- /* printk(KERN_DEBUG "slave %s found\n", *list); */
- snd_ctl_add_slave(master, slave);
- }
- }
-}
-
-static int __devinit juli_add_controls(struct snd_ice1712 *ice)
-{
- struct juli_spec *spec = ice->spec;
- int err;
- unsigned int i;
- struct snd_kcontrol *vmaster;
-
- err = snd_ice1712_akm4xxx_build_controls(ice);
- if (err < 0)
- return err;
-
- for (i = 0; i < ARRAY_SIZE(juli_mute_controls); i++) {
- err = snd_ctl_add(ice->card,
- snd_ctl_new1(&juli_mute_controls[i], ice));
- if (err < 0)
- return err;
- }
- /* Create virtual master control */
- vmaster = snd_ctl_make_virtual_master("Master Playback Volume",
- juli_master_db_scale);
- if (!vmaster)
- return -ENOMEM;
- add_slaves(ice->card, vmaster, slave_vols);
- err = snd_ctl_add(ice->card, vmaster);
- if (err < 0)
- return err;
-
- /* only capture SPDIF over AK4114 */
- err = snd_ak4114_build(spec->ak4114, NULL,
- ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
- if (err < 0)
- return err;
- return 0;
-}
-
-/*
- * suspend/resume
- * */
-
-#ifdef CONFIG_PM
-static int juli_resume(struct snd_ice1712 *ice)
-{
- struct snd_akm4xxx *ak = ice->akm;
- struct juli_spec *spec = ice->spec;
- /* akm4358 un-reset, un-mute */
- snd_akm4xxx_reset(ak, 0);
- /* reinit ak4114 */
- snd_ak4114_reinit(spec->ak4114);
- return 0;
-}
-
-static int juli_suspend(struct snd_ice1712 *ice)
-{
- struct snd_akm4xxx *ak = ice->akm;
- /* akm4358 reset and soft-mute */
- snd_akm4xxx_reset(ak, 1);
- return 0;
-}
-#endif
-
-/*
- * initialize the chip
- */
-
-static inline int juli_is_spdif_master(struct snd_ice1712 *ice)
-{
- return (ice->gpio.get_data(ice) & GPIO_INTERNAL_CLOCK) ? 0 : 1;
-}
-
-static unsigned int juli_get_rate(struct snd_ice1712 *ice)
-{
- int i;
- unsigned char result;
-
- result = ice->gpio.get_data(ice) & GPIO_RATE_MASK;
- for (i = 0; i < ARRAY_SIZE(gpio_vals); i++)
- if (gpio_vals[i] == result)
- return juli_rates[i];
- return 0;
-}
-
-/* setting new rate */
-static void juli_set_rate(struct snd_ice1712 *ice, unsigned int rate)
-{
- unsigned int old, new;
- unsigned char val;
-
- old = ice->gpio.get_data(ice);
- new = (old & ~GPIO_RATE_MASK) | get_gpio_val(rate);
- /* printk(KERN_DEBUG "JULI - set_rate: old %x, new %x\n",
- old & GPIO_RATE_MASK,
- new & GPIO_RATE_MASK); */
-
- ice->gpio.set_data(ice, new);
- /* switching to external clock - supplied by external circuits */
- val = inb(ICEMT1724(ice, RATE));
- outb(val | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE));
-}
-
-static inline unsigned char juli_set_mclk(struct snd_ice1712 *ice,
- unsigned int rate)
-{
- /* no change in master clock */
- return 0;
-}
-
-/* setting clock to external - SPDIF */
-static int juli_set_spdif_clock(struct snd_ice1712 *ice, int type)
-{
- unsigned int old;
- old = ice->gpio.get_data(ice);
- /* external clock (= 0), multiply 1x, 48kHz */
- ice->gpio.set_data(ice, (old & ~GPIO_RATE_MASK) | GPIO_MULTI_1X |
- GPIO_FREQ_48KHZ);
- return 0;
-}
-
-/* Called when ak4114 detects change in the input SPDIF stream */
-static void juli_ak4114_change(struct ak4114 *ak4114, unsigned char c0,
- unsigned char c1)
-{
- struct snd_ice1712 *ice = ak4114->change_callback_private;
- int rate;
- if (ice->is_spdif_master(ice) && c1) {
- /* only for SPDIF master mode, rate was changed */
- rate = snd_ak4114_external_rate(ak4114);
- /* printk(KERN_DEBUG "ak4114 - input rate changed to %d\n",
- rate); */
- juli_akm_set_rate_val(ice->akm, rate);
- }
-}
-
-static int __devinit juli_init(struct snd_ice1712 *ice)
-{
- static const unsigned char ak4114_init_vals[] = {
- /* AK4117_REG_PWRDN */ AK4114_RST | AK4114_PWN |
- AK4114_OCKS0 | AK4114_OCKS1,
- /* AK4114_REQ_FORMAT */ AK4114_DIF_I24I2S,
- /* AK4114_REG_IO0 */ AK4114_TX1E,
- /* AK4114_REG_IO1 */ AK4114_EFH_1024 | AK4114_DIT |
- AK4114_IPS(1),
- /* AK4114_REG_INT0_MASK */ 0,
- /* AK4114_REG_INT1_MASK */ 0
- };
- static const unsigned char ak4114_init_txcsb[] = {
- 0x41, 0x02, 0x2c, 0x00, 0x00
- };
- int err;
- struct juli_spec *spec;
- struct snd_akm4xxx *ak;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- ice->spec = spec;
-
- err = snd_ak4114_create(ice->card,
- juli_ak4114_read,
- juli_ak4114_write,
- ak4114_init_vals, ak4114_init_txcsb,
- ice, &spec->ak4114);
- if (err < 0)
- return err;
- /* callback for codecs rate setting */
- spec->ak4114->change_callback = juli_ak4114_change;
- spec->ak4114->change_callback_private = ice;
- /* AK4114 in Juli can detect external rate correctly */
- spec->ak4114->check_flags = 0;
-
-#if 0
-/*
- * it seems that the analog doughter board detection does not work reliably, so
- * force the analog flag; it should be very rare (if ever) to come at Juli@
- * used without the analog daughter board
- */
- spec->analog = (ice->gpio.get_data(ice) & GPIO_ANALOG_PRESENT) ? 0 : 1;
-#else
- spec->analog = 1;
-#endif
-
- if (spec->analog) {
- printk(KERN_INFO "juli@: analog I/O detected\n");
- ice->num_total_dacs = 2;
- ice->num_total_adcs = 2;
-
- ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
- ak = ice->akm;
- if (!ak)
- return -ENOMEM;
- ice->akm_codecs = 1;
- err = snd_ice1712_akm4xxx_init(ak, &akm_juli_dac, NULL, ice);
- if (err < 0)
- return err;
- }
-
- /* juli is clocked by Xilinx array */
- ice->hw_rates = &juli_rates_info;
- ice->is_spdif_master = juli_is_spdif_master;
- ice->get_rate = juli_get_rate;
- ice->set_rate = juli_set_rate;
- ice->set_mclk = juli_set_mclk;
- ice->set_spdif_clock = juli_set_spdif_clock;
-
- ice->spdif.ops.open = juli_spdif_in_open;
-
-#ifdef CONFIG_PM
- ice->pm_resume = juli_resume;
- ice->pm_suspend = juli_suspend;
- ice->pm_suspend_enabled = 1;
-#endif
-
- return 0;
-}
-
-
-/*
- * Juli@ boards don't provide the EEPROM data except for the vendor IDs.
- * hence the driver needs to sets up it properly.
- */
-
-static unsigned char juli_eeprom[] __devinitdata = {
- [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, 1xADC, 1xDACs,
- SPDIF in */
- [ICE_EEP2_ACLINK] = 0x80, /* I2S */
- [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */
- [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
- [ICE_EEP2_GPIO_DIR] = 0x9f, /* 5, 6:inputs; 7, 4-0 outputs*/
- [ICE_EEP2_GPIO_DIR1] = 0xff,
- [ICE_EEP2_GPIO_DIR2] = 0x7f,
- [ICE_EEP2_GPIO_MASK] = 0x60, /* 5, 6: locked; 7, 4-0 writable */
- [ICE_EEP2_GPIO_MASK1] = 0x00, /* 0-7 writable */
- [ICE_EEP2_GPIO_MASK2] = 0x7f,
- [ICE_EEP2_GPIO_STATE] = GPIO_FREQ_48KHZ | GPIO_MULTI_1X |
- GPIO_INTERNAL_CLOCK, /* internal clock, multiple 1x, 48kHz*/
- [ICE_EEP2_GPIO_STATE1] = 0x00, /* unmuted */
- [ICE_EEP2_GPIO_STATE2] = 0x00,
-};
-
-/* entry point */
-struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = {
- {
- .subvendor = VT1724_SUBDEVICE_JULI,
- .name = "ESI Juli@",
- .model = "juli",
- .chip_init = juli_init,
- .build_controls = juli_add_controls,
- .eeprom_size = sizeof(juli_eeprom),
- .eeprom_data = juli_eeprom,
- },
- { } /* terminator */
-};
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/juli.h b/ANDROID_3.4.5/sound/pci/ice1712/juli.h
deleted file mode 100644
index d9f8534f..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/juli.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __SOUND_JULI_H
-#define __SOUND_JULI_H
-
-#define JULI_DEVICE_DESC "{ESI,Juli@},"
-
-#define VT1724_SUBDEVICE_JULI 0x31305345 /* Juli@ */
-
-extern struct snd_ice1712_card_info snd_vt1724_juli_cards[];
-
-#endif /* __SOUND_JULI_H */
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/maya44.c b/ANDROID_3.4.5/sound/pci/ice1712/maya44.c
deleted file mode 100644
index 726fd4b9..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/maya44.c
+++ /dev/null
@@ -1,779 +0,0 @@
-/*
- * ALSA driver for ICEnsemble VT1724 (Envy24HT)
- *
- * Lowlevel functions for ESI Maya44 cards
- *
- * Copyright (c) 2009 Takashi Iwai <tiwai@suse.de>
- * Based on the patches by Rainer Zimmermann <mail@lightshed.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/tlv.h>
-
-#include "ice1712.h"
-#include "envy24ht.h"
-#include "maya44.h"
-
-/* WM8776 register indexes */
-#define WM8776_REG_HEADPHONE_L 0x00
-#define WM8776_REG_HEADPHONE_R 0x01
-#define WM8776_REG_HEADPHONE_MASTER 0x02
-#define WM8776_REG_DAC_ATTEN_L 0x03
-#define WM8776_REG_DAC_ATTEN_R 0x04
-#define WM8776_REG_DAC_ATTEN_MASTER 0x05
-#define WM8776_REG_DAC_PHASE 0x06
-#define WM8776_REG_DAC_CONTROL 0x07
-#define WM8776_REG_DAC_MUTE 0x08
-#define WM8776_REG_DAC_DEEMPH 0x09
-#define WM8776_REG_DAC_IF_CONTROL 0x0a
-#define WM8776_REG_ADC_IF_CONTROL 0x0b
-#define WM8776_REG_MASTER_MODE_CONTROL 0x0c
-#define WM8776_REG_POWERDOWN 0x0d
-#define WM8776_REG_ADC_ATTEN_L 0x0e
-#define WM8776_REG_ADC_ATTEN_R 0x0f
-#define WM8776_REG_ADC_ALC1 0x10
-#define WM8776_REG_ADC_ALC2 0x11
-#define WM8776_REG_ADC_ALC3 0x12
-#define WM8776_REG_ADC_NOISE_GATE 0x13
-#define WM8776_REG_ADC_LIMITER 0x14
-#define WM8776_REG_ADC_MUX 0x15
-#define WM8776_REG_OUTPUT_MUX 0x16
-#define WM8776_REG_RESET 0x17
-
-#define WM8776_NUM_REGS 0x18
-
-/* clock ratio identifiers for snd_wm8776_set_rate() */
-#define WM8776_CLOCK_RATIO_128FS 0
-#define WM8776_CLOCK_RATIO_192FS 1
-#define WM8776_CLOCK_RATIO_256FS 2
-#define WM8776_CLOCK_RATIO_384FS 3
-#define WM8776_CLOCK_RATIO_512FS 4
-#define WM8776_CLOCK_RATIO_768FS 5
-
-enum { WM_VOL_HP, WM_VOL_DAC, WM_VOL_ADC, WM_NUM_VOLS };
-enum { WM_SW_DAC, WM_SW_BYPASS, WM_NUM_SWITCHES };
-
-struct snd_wm8776 {
- unsigned char addr;
- unsigned short regs[WM8776_NUM_REGS];
- unsigned char volumes[WM_NUM_VOLS][2];
- unsigned int switch_bits;
-};
-
-struct snd_maya44 {
- struct snd_ice1712 *ice;
- struct snd_wm8776 wm[2];
- struct mutex mutex;
-};
-
-
-/* write the given register and save the data to the cache */
-static void wm8776_write(struct snd_ice1712 *ice, struct snd_wm8776 *wm,
- unsigned char reg, unsigned short val)
-{
- /*
- * WM8776 registers are up to 9 bits wide, bit 8 is placed in the LSB
- * of the address field
- */
- snd_vt1724_write_i2c(ice, wm->addr,
- (reg << 1) | ((val >> 8) & 1),
- val & 0xff);
- wm->regs[reg] = val;
-}
-
-/*
- * update the given register with and/or mask and save the data to the cache
- */
-static int wm8776_write_bits(struct snd_ice1712 *ice, struct snd_wm8776 *wm,
- unsigned char reg,
- unsigned short mask, unsigned short val)
-{
- val |= wm->regs[reg] & ~mask;
- if (val != wm->regs[reg]) {
- wm8776_write(ice, wm, reg, val);
- return 1;
- }
- return 0;
-}
-
-
-/*
- * WM8776 volume controls
- */
-
-struct maya_vol_info {
- unsigned int maxval; /* volume range: 0..maxval */
- unsigned char regs[2]; /* left and right registers */
- unsigned short mask; /* value mask */
- unsigned short offset; /* zero-value offset */
- unsigned short mute; /* mute bit */
- unsigned short update; /* update bits */
- unsigned char mux_bits[2]; /* extra bits for ADC mute */
-};
-
-static struct maya_vol_info vol_info[WM_NUM_VOLS] = {
- [WM_VOL_HP] = {
- .maxval = 80,
- .regs = { WM8776_REG_HEADPHONE_L, WM8776_REG_HEADPHONE_R },
- .mask = 0x7f,
- .offset = 0x30,
- .mute = 0x00,
- .update = 0x180, /* update and zero-cross enable */
- },
- [WM_VOL_DAC] = {
- .maxval = 255,
- .regs = { WM8776_REG_DAC_ATTEN_L, WM8776_REG_DAC_ATTEN_R },
- .mask = 0xff,
- .offset = 0x01,
- .mute = 0x00,
- .update = 0x100, /* zero-cross enable */
- },
- [WM_VOL_ADC] = {
- .maxval = 91,
- .regs = { WM8776_REG_ADC_ATTEN_L, WM8776_REG_ADC_ATTEN_R },
- .mask = 0xff,
- .offset = 0xa5,
- .mute = 0xa5,
- .update = 0x100, /* update */
- .mux_bits = { 0x80, 0x40 }, /* ADCMUX bits */
- },
-};
-
-/*
- * dB tables
- */
-/* headphone output: mute, -73..+6db (1db step) */
-static const DECLARE_TLV_DB_SCALE(db_scale_hp, -7400, 100, 1);
-/* DAC output: mute, -127..0db (0.5db step) */
-static const DECLARE_TLV_DB_SCALE(db_scale_dac, -12750, 50, 1);
-/* ADC gain: mute, -21..+24db (0.5db step) */
-static const DECLARE_TLV_DB_SCALE(db_scale_adc, -2100, 50, 1);
-
-static int maya_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- unsigned int idx = kcontrol->private_value;
- struct maya_vol_info *vol = &vol_info[idx];
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = vol->maxval;
- return 0;
-}
-
-static int maya_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
- struct snd_wm8776 *wm =
- &chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
- unsigned int idx = kcontrol->private_value;
-
- mutex_lock(&chip->mutex);
- ucontrol->value.integer.value[0] = wm->volumes[idx][0];
- ucontrol->value.integer.value[1] = wm->volumes[idx][1];
- mutex_unlock(&chip->mutex);
- return 0;
-}
-
-static int maya_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
- struct snd_wm8776 *wm =
- &chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
- unsigned int idx = kcontrol->private_value;
- struct maya_vol_info *vol = &vol_info[idx];
- unsigned int val, data;
- int ch, changed = 0;
-
- mutex_lock(&chip->mutex);
- for (ch = 0; ch < 2; ch++) {
- val = ucontrol->value.integer.value[ch];
- if (val > vol->maxval)
- val = vol->maxval;
- if (val == wm->volumes[idx][ch])
- continue;
- if (!val)
- data = vol->mute;
- else
- data = (val - 1) + vol->offset;
- data |= vol->update;
- changed |= wm8776_write_bits(chip->ice, wm, vol->regs[ch],
- vol->mask | vol->update, data);
- if (vol->mux_bits[ch])
- wm8776_write_bits(chip->ice, wm, WM8776_REG_ADC_MUX,
- vol->mux_bits[ch],
- val ? 0 : vol->mux_bits[ch]);
- wm->volumes[idx][ch] = val;
- }
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-/*
- * WM8776 switch controls
- */
-
-#define COMPOSE_SW_VAL(idx, reg, mask) ((idx) | ((reg) << 8) | ((mask) << 16))
-#define GET_SW_VAL_IDX(val) ((val) & 0xff)
-#define GET_SW_VAL_REG(val) (((val) >> 8) & 0xff)
-#define GET_SW_VAL_MASK(val) (((val) >> 16) & 0xff)
-
-#define maya_sw_info snd_ctl_boolean_mono_info
-
-static int maya_sw_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
- struct snd_wm8776 *wm =
- &chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
- unsigned int idx = GET_SW_VAL_IDX(kcontrol->private_value);
-
- ucontrol->value.integer.value[0] = (wm->switch_bits >> idx) & 1;
- return 0;
-}
-
-static int maya_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
- struct snd_wm8776 *wm =
- &chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
- unsigned int idx = GET_SW_VAL_IDX(kcontrol->private_value);
- unsigned int mask, val;
- int changed;
-
- mutex_lock(&chip->mutex);
- mask = 1 << idx;
- wm->switch_bits &= ~mask;
- val = ucontrol->value.integer.value[0];
- if (val)
- wm->switch_bits |= mask;
- mask = GET_SW_VAL_MASK(kcontrol->private_value);
- changed = wm8776_write_bits(chip->ice, wm,
- GET_SW_VAL_REG(kcontrol->private_value),
- mask, val ? mask : 0);
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-/*
- * GPIO pins (known ones for maya44)
- */
-#define GPIO_PHANTOM_OFF 2
-#define GPIO_MIC_RELAY 4
-#define GPIO_SPDIF_IN_INV 5
-#define GPIO_MUST_BE_0 7
-
-/*
- * GPIO switch controls
- */
-
-#define COMPOSE_GPIO_VAL(shift, inv) ((shift) | ((inv) << 8))
-#define GET_GPIO_VAL_SHIFT(val) ((val) & 0xff)
-#define GET_GPIO_VAL_INV(val) (((val) >> 8) & 1)
-
-static int maya_set_gpio_bits(struct snd_ice1712 *ice, unsigned int mask,
- unsigned int bits)
-{
- unsigned int data;
- data = snd_ice1712_gpio_read(ice);
- if ((data & mask) == bits)
- return 0;
- snd_ice1712_gpio_write(ice, (data & ~mask) | bits);
- return 1;
-}
-
-#define maya_gpio_sw_info snd_ctl_boolean_mono_info
-
-static int maya_gpio_sw_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
- unsigned int shift = GET_GPIO_VAL_SHIFT(kcontrol->private_value);
- unsigned int val;
-
- val = (snd_ice1712_gpio_read(chip->ice) >> shift) & 1;
- if (GET_GPIO_VAL_INV(kcontrol->private_value))
- val = !val;
- ucontrol->value.integer.value[0] = val;
- return 0;
-}
-
-static int maya_gpio_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
- unsigned int shift = GET_GPIO_VAL_SHIFT(kcontrol->private_value);
- unsigned int val, mask;
- int changed;
-
- mutex_lock(&chip->mutex);
- mask = 1 << shift;
- val = ucontrol->value.integer.value[0];
- if (GET_GPIO_VAL_INV(kcontrol->private_value))
- val = !val;
- val = val ? mask : 0;
- changed = maya_set_gpio_bits(chip->ice, mask, val);
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-/*
- * capture source selection
- */
-
-/* known working input slots (0-4) */
-#define MAYA_LINE_IN 1 /* in-2 */
-#define MAYA_MIC_IN 3 /* in-4 */
-
-static void wm8776_select_input(struct snd_maya44 *chip, int idx, int line)
-{
- wm8776_write_bits(chip->ice, &chip->wm[idx], WM8776_REG_ADC_MUX,
- 0x1f, 1 << line);
-}
-
-static int maya_rec_src_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = { "Line", "Mic" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = ARRAY_SIZE(texts);
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int maya_rec_src_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
- int sel;
-
- if (snd_ice1712_gpio_read(chip->ice) & (1 << GPIO_MIC_RELAY))
- sel = 1;
- else
- sel = 0;
- ucontrol->value.enumerated.item[0] = sel;
- return 0;
-}
-
-static int maya_rec_src_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
- int sel = ucontrol->value.enumerated.item[0];
- int changed;
-
- mutex_lock(&chip->mutex);
- changed = maya_set_gpio_bits(chip->ice, 1 << GPIO_MIC_RELAY,
- sel ? (1 << GPIO_MIC_RELAY) : 0);
- wm8776_select_input(chip, 0, sel ? MAYA_MIC_IN : MAYA_LINE_IN);
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-/*
- * Maya44 routing switch settings have different meanings than the standard
- * ice1724 switches as defined in snd_vt1724_pro_route_info (ice1724.c).
- */
-static int maya_pb_route_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = {
- "PCM Out", /* 0 */
- "Input 1", "Input 2", "Input 3", "Input 4"
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = ARRAY_SIZE(texts);
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int maya_pb_route_shift(int idx)
-{
- static const unsigned char shift[10] =
- { 8, 20, 0, 3, 11, 23, 14, 26, 17, 29 };
- return shift[idx % 10];
-}
-
-static int maya_pb_route_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
- int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- ucontrol->value.enumerated.item[0] =
- snd_ice1724_get_route_val(chip->ice, maya_pb_route_shift(idx));
- return 0;
-}
-
-static int maya_pb_route_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
- int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- return snd_ice1724_put_route_val(chip->ice,
- ucontrol->value.enumerated.item[0],
- maya_pb_route_shift(idx));
-}
-
-
-/*
- * controls to be added
- */
-
-static struct snd_kcontrol_new maya_controls[] __devinitdata = {
- {
- .name = "Crossmix Playback Volume",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = maya_vol_info,
- .get = maya_vol_get,
- .put = maya_vol_put,
- .tlv = { .p = db_scale_hp },
- .private_value = WM_VOL_HP,
- .count = 2,
- },
- {
- .name = "PCM Playback Volume",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = maya_vol_info,
- .get = maya_vol_get,
- .put = maya_vol_put,
- .tlv = { .p = db_scale_dac },
- .private_value = WM_VOL_DAC,
- .count = 2,
- },
- {
- .name = "Line Capture Volume",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = maya_vol_info,
- .get = maya_vol_get,
- .put = maya_vol_put,
- .tlv = { .p = db_scale_adc },
- .private_value = WM_VOL_ADC,
- .count = 2,
- },
- {
- .name = "PCM Playback Switch",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = maya_sw_info,
- .get = maya_sw_get,
- .put = maya_sw_put,
- .private_value = COMPOSE_SW_VAL(WM_SW_DAC,
- WM8776_REG_OUTPUT_MUX, 0x01),
- .count = 2,
- },
- {
- .name = "Bypass Playback Switch",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = maya_sw_info,
- .get = maya_sw_get,
- .put = maya_sw_put,
- .private_value = COMPOSE_SW_VAL(WM_SW_BYPASS,
- WM8776_REG_OUTPUT_MUX, 0x04),
- .count = 2,
- },
- {
- .name = "Capture Source",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = maya_rec_src_info,
- .get = maya_rec_src_get,
- .put = maya_rec_src_put,
- },
- {
- .name = "Mic Phantom Power Switch",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = maya_gpio_sw_info,
- .get = maya_gpio_sw_get,
- .put = maya_gpio_sw_put,
- .private_value = COMPOSE_GPIO_VAL(GPIO_PHANTOM_OFF, 1),
- },
- {
- .name = "SPDIF Capture Switch",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = maya_gpio_sw_info,
- .get = maya_gpio_sw_get,
- .put = maya_gpio_sw_put,
- .private_value = COMPOSE_GPIO_VAL(GPIO_SPDIF_IN_INV, 1),
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "H/W Playback Route",
- .info = maya_pb_route_info,
- .get = maya_pb_route_get,
- .put = maya_pb_route_put,
- .count = 4, /* FIXME: do controls 5-9 have any meaning? */
- },
-};
-
-static int __devinit maya44_add_controls(struct snd_ice1712 *ice)
-{
- int err, i;
-
- for (i = 0; i < ARRAY_SIZE(maya_controls); i++) {
- err = snd_ctl_add(ice->card, snd_ctl_new1(&maya_controls[i],
- ice->spec));
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-
-/*
- * initialize a wm8776 chip
- */
-static void __devinit wm8776_init(struct snd_ice1712 *ice,
- struct snd_wm8776 *wm, unsigned int addr)
-{
- static const unsigned short inits_wm8776[] = {
- 0x02, 0x100, /* R2: headphone L+R muted + update */
- 0x05, 0x100, /* R5: DAC output L+R muted + update */
- 0x06, 0x000, /* R6: DAC output phase normal */
- 0x07, 0x091, /* R7: DAC enable zero cross detection,
- normal output */
- 0x08, 0x000, /* R8: DAC soft mute off */
- 0x09, 0x000, /* R9: no deemph, DAC zero detect disabled */
- 0x0a, 0x022, /* R10: DAC I2C mode, std polarities, 24bit */
- 0x0b, 0x022, /* R11: ADC I2C mode, std polarities, 24bit,
- highpass filter enabled */
- 0x0c, 0x042, /* R12: ADC+DAC slave, ADC+DAC 44,1kHz */
- 0x0d, 0x000, /* R13: all power up */
- 0x0e, 0x100, /* R14: ADC left muted,
- enable zero cross detection */
- 0x0f, 0x100, /* R15: ADC right muted,
- enable zero cross detection */
- /* R16: ALC...*/
- 0x11, 0x000, /* R17: disable ALC */
- /* R18: ALC...*/
- /* R19: noise gate...*/
- 0x15, 0x000, /* R21: ADC input mux init, mute all inputs */
- 0x16, 0x001, /* R22: output mux, select DAC */
- 0xff, 0xff
- };
-
- const unsigned short *ptr;
- unsigned char reg;
- unsigned short data;
-
- wm->addr = addr;
- /* enable DAC output; mute bypass, aux & all inputs */
- wm->switch_bits = (1 << WM_SW_DAC);
-
- ptr = inits_wm8776;
- while (*ptr != 0xff) {
- reg = *ptr++;
- data = *ptr++;
- wm8776_write(ice, wm, reg, data);
- }
-}
-
-
-/*
- * change the rate on the WM8776 codecs.
- * this assumes that the VT17xx's rate is changed by the calling function.
- * NOTE: even though the WM8776's are running in slave mode and rate
- * selection is automatic, we need to call snd_wm8776_set_rate() here
- * to make sure some flags are set correctly.
- */
-static void set_rate(struct snd_ice1712 *ice, unsigned int rate)
-{
- struct snd_maya44 *chip = ice->spec;
- unsigned int ratio, adc_ratio, val;
- int i;
-
- switch (rate) {
- case 192000:
- ratio = WM8776_CLOCK_RATIO_128FS;
- break;
- case 176400:
- ratio = WM8776_CLOCK_RATIO_128FS;
- break;
- case 96000:
- ratio = WM8776_CLOCK_RATIO_256FS;
- break;
- case 88200:
- ratio = WM8776_CLOCK_RATIO_384FS;
- break;
- case 48000:
- ratio = WM8776_CLOCK_RATIO_512FS;
- break;
- case 44100:
- ratio = WM8776_CLOCK_RATIO_512FS;
- break;
- case 32000:
- ratio = WM8776_CLOCK_RATIO_768FS;
- break;
- case 0:
- /* no hint - S/PDIF input is master, simply return */
- return;
- default:
- snd_BUG();
- return;
- }
-
- /*
- * this currently sets the same rate for ADC and DAC, but limits
- * ADC rate to 256X (96kHz). For 256X mode (96kHz), this sets ADC
- * oversampling to 64x, as recommended by WM8776 datasheet.
- * Setting the rate is not really necessary in slave mode.
- */
- adc_ratio = ratio;
- if (adc_ratio < WM8776_CLOCK_RATIO_256FS)
- adc_ratio = WM8776_CLOCK_RATIO_256FS;
-
- val = adc_ratio;
- if (adc_ratio == WM8776_CLOCK_RATIO_256FS)
- val |= 8;
- val |= ratio << 4;
-
- mutex_lock(&chip->mutex);
- for (i = 0; i < 2; i++)
- wm8776_write_bits(ice, &chip->wm[i],
- WM8776_REG_MASTER_MODE_CONTROL,
- 0x180, val);
- mutex_unlock(&chip->mutex);
-}
-
-/*
- * supported sample rates (to override the default one)
- */
-
-static unsigned int rates[] = {
- 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000
-};
-
-/* playback rates: 32..192 kHz */
-static struct snd_pcm_hw_constraint_list dac_rates = {
- .count = ARRAY_SIZE(rates),
- .list = rates,
- .mask = 0
-};
-
-
-/*
- * chip addresses on I2C bus
- */
-static unsigned char wm8776_addr[2] __devinitdata = {
- 0x34, 0x36, /* codec 0 & 1 */
-};
-
-/*
- * initialize the chip
- */
-static int __devinit maya44_init(struct snd_ice1712 *ice)
-{
- int i;
- struct snd_maya44 *chip;
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (!chip)
- return -ENOMEM;
- mutex_init(&chip->mutex);
- chip->ice = ice;
- ice->spec = chip;
-
- /* initialise codecs */
- ice->num_total_dacs = 4;
- ice->num_total_adcs = 4;
- ice->akm_codecs = 0;
-
- for (i = 0; i < 2; i++) {
- wm8776_init(ice, &chip->wm[i], wm8776_addr[i]);
- wm8776_select_input(chip, i, MAYA_LINE_IN);
- }
-
- /* set card specific rates */
- ice->hw_rates = &dac_rates;
-
- /* register change rate notifier */
- ice->gpio.set_pro_rate = set_rate;
-
- /* RDMA1 (2nd input channel) is used for ADC by default */
- ice->force_rdma1 = 1;
-
- /* have an own routing control */
- ice->own_routing = 1;
-
- return 0;
-}
-
-
-/*
- * Maya44 boards don't provide the EEPROM data except for the vendor IDs.
- * hence the driver needs to sets up it properly.
- */
-
-static unsigned char maya44_eeprom[] __devinitdata = {
- [ICE_EEP2_SYSCONF] = 0x45,
- /* clock xin1=49.152MHz, mpu401, 2 stereo ADCs+DACs */
- [ICE_EEP2_ACLINK] = 0x80,
- /* I2S */
- [ICE_EEP2_I2S] = 0xf8,
- /* vol, 96k, 24bit, 192k */
- [ICE_EEP2_SPDIF] = 0xc3,
- /* enable spdif out, spdif out supp, spdif-in, ext spdif out */
- [ICE_EEP2_GPIO_DIR] = 0xff,
- [ICE_EEP2_GPIO_DIR1] = 0xff,
- [ICE_EEP2_GPIO_DIR2] = 0xff,
- [ICE_EEP2_GPIO_MASK] = 0/*0x9f*/,
- [ICE_EEP2_GPIO_MASK1] = 0/*0xff*/,
- [ICE_EEP2_GPIO_MASK2] = 0/*0x7f*/,
- [ICE_EEP2_GPIO_STATE] = (1 << GPIO_PHANTOM_OFF) |
- (1 << GPIO_SPDIF_IN_INV),
- [ICE_EEP2_GPIO_STATE1] = 0x00,
- [ICE_EEP2_GPIO_STATE2] = 0x00,
-};
-
-/* entry point */
-struct snd_ice1712_card_info snd_vt1724_maya44_cards[] __devinitdata = {
- {
- .subvendor = VT1724_SUBDEVICE_MAYA44,
- .name = "ESI Maya44",
- .model = "maya44",
- .chip_init = maya44_init,
- .build_controls = maya44_add_controls,
- .eeprom_size = sizeof(maya44_eeprom),
- .eeprom_data = maya44_eeprom,
- },
- { } /* terminator */
-};
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/maya44.h b/ANDROID_3.4.5/sound/pci/ice1712/maya44.h
deleted file mode 100644
index eafd03a8..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/maya44.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __SOUND_MAYA44_H
-#define __SOUND_MAYA44_H
-
-#define MAYA44_DEVICE_DESC "{ESI,Maya44},"
-
-#define VT1724_SUBDEVICE_MAYA44 0x34315441 /* Maya44 */
-
-extern struct snd_ice1712_card_info snd_vt1724_maya44_cards[];
-
-#endif /* __SOUND_MAYA44_H */
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/phase.c b/ANDROID_3.4.5/sound/pci/ice1712/phase.c
deleted file mode 100644
index de29be8c..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/phase.c
+++ /dev/null
@@ -1,975 +0,0 @@
-/*
- * ALSA driver for ICEnsemble ICE1724 (Envy24)
- *
- * Lowlevel functions for Terratec PHASE 22
- *
- * Copyright (c) 2005 Misha Zhilin <misha@epiphan.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/* PHASE 22 overview:
- * Audio controller: VIA Envy24HT-S (slightly trimmed down Envy24HT, 4in/4out)
- * Analog chip: AK4524 (partially via Philip's 74HCT125)
- * Digital receiver: CS8414-CS (supported in this release)
- * PHASE 22 revision 2.0 and Terrasoniq/Musonik TS22PCI have CS8416
- * (support status unknown, please test and report)
- *
- * Envy connects to AK4524
- * - CS directly from GPIO 10
- * - CCLK via 74HCT125's gate #4 from GPIO 4
- * - CDTI via 74HCT125's gate #2 from GPIO 5
- * CDTI may be completely blocked by 74HCT125's gate #1
- * controlled by GPIO 3
- */
-
-/* PHASE 28 overview:
- * Audio controller: VIA Envy24HT (full untrimmed version, 4in/8out)
- * Analog chip: WM8770 (8 channel 192k DAC, 2 channel 96k ADC)
- * Digital receiver: CS8414-CS (supported in this release)
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-
-#include <sound/core.h>
-
-#include "ice1712.h"
-#include "envy24ht.h"
-#include "phase.h"
-#include <sound/tlv.h>
-
-/* AC97 register cache for Phase28 */
-struct phase28_spec {
- unsigned short master[2];
- unsigned short vol[8];
-};
-
-/* WM8770 registers */
-#define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */
-#define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */
-#define WM_DAC_DIG_ATTEN 0x09 /* DAC1-8 digital attenuation */
-#define WM_DAC_DIG_MASTER_ATTEN 0x11 /* DAC master digital attenuation */
-#define WM_PHASE_SWAP 0x12 /* DAC phase */
-#define WM_DAC_CTRL1 0x13 /* DAC control bits */
-#define WM_MUTE 0x14 /* mute controls */
-#define WM_DAC_CTRL2 0x15 /* de-emphasis and zefo-flag */
-#define WM_INT_CTRL 0x16 /* interface control */
-#define WM_MASTER 0x17 /* master clock and mode */
-#define WM_POWERDOWN 0x18 /* power-down controls */
-#define WM_ADC_GAIN 0x19 /* ADC gain L(19)/R(1a) */
-#define WM_ADC_MUX 0x1b /* input MUX */
-#define WM_OUT_MUX1 0x1c /* output MUX */
-#define WM_OUT_MUX2 0x1e /* output MUX */
-#define WM_RESET 0x1f /* software reset */
-
-
-/*
- * Logarithmic volume values for WM8770
- * Computed as 20 * Log10(255 / x)
- */
-static const unsigned char wm_vol[256] = {
- 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24,
- 24, 23, 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18,
- 17, 17, 17, 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14,
- 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11,
- 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-#define WM_VOL_MAX (sizeof(wm_vol) - 1)
-#define WM_VOL_MUTE 0x8000
-
-static struct snd_akm4xxx akm_phase22 __devinitdata = {
- .type = SND_AK4524,
- .num_dacs = 2,
- .num_adcs = 2,
-};
-
-static struct snd_ak4xxx_private akm_phase22_priv __devinitdata = {
- .caddr = 2,
- .cif = 1,
- .data_mask = 1 << 4,
- .clk_mask = 1 << 5,
- .cs_mask = 1 << 10,
- .cs_addr = 1 << 10,
- .cs_none = 0,
- .add_flags = 1 << 3,
- .mask_flags = 0,
-};
-
-static int __devinit phase22_init(struct snd_ice1712 *ice)
-{
- struct snd_akm4xxx *ak;
- int err;
-
- /* Configure DAC/ADC description for generic part of ice1724 */
- switch (ice->eeprom.subvendor) {
- case VT1724_SUBDEVICE_PHASE22:
- case VT1724_SUBDEVICE_TS22:
- ice->num_total_dacs = 2;
- ice->num_total_adcs = 2;
- ice->vt1720 = 1; /* Envy24HT-S have 16 bit wide GPIO */
- break;
- default:
- snd_BUG();
- return -EINVAL;
- }
-
- /* Initialize analog chips */
- ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
- ak = ice->akm;
- if (!ak)
- return -ENOMEM;
- ice->akm_codecs = 1;
- switch (ice->eeprom.subvendor) {
- case VT1724_SUBDEVICE_PHASE22:
- case VT1724_SUBDEVICE_TS22:
- err = snd_ice1712_akm4xxx_init(ak, &akm_phase22,
- &akm_phase22_priv, ice);
- if (err < 0)
- return err;
- break;
- }
-
- return 0;
-}
-
-static int __devinit phase22_add_controls(struct snd_ice1712 *ice)
-{
- int err = 0;
-
- switch (ice->eeprom.subvendor) {
- case VT1724_SUBDEVICE_PHASE22:
- case VT1724_SUBDEVICE_TS22:
- err = snd_ice1712_akm4xxx_build_controls(ice);
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-static unsigned char phase22_eeprom[] __devinitdata = {
- [ICE_EEP2_SYSCONF] = 0x28, /* clock 512, mpu 401,
- spdif-in/1xADC, 1xDACs */
- [ICE_EEP2_ACLINK] = 0x80, /* I2S */
- [ICE_EEP2_I2S] = 0xf0, /* vol, 96k, 24bit */
- [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
- [ICE_EEP2_GPIO_DIR] = 0xff,
- [ICE_EEP2_GPIO_DIR1] = 0xff,
- [ICE_EEP2_GPIO_DIR2] = 0xff,
- [ICE_EEP2_GPIO_MASK] = 0x00,
- [ICE_EEP2_GPIO_MASK1] = 0x00,
- [ICE_EEP2_GPIO_MASK2] = 0x00,
- [ICE_EEP2_GPIO_STATE] = 0x00,
- [ICE_EEP2_GPIO_STATE1] = 0x00,
- [ICE_EEP2_GPIO_STATE2] = 0x00,
-};
-
-static unsigned char phase28_eeprom[] __devinitdata = {
- [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401,
- spdif-in/1xADC, 4xDACs */
- [ICE_EEP2_ACLINK] = 0x80, /* I2S */
- [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
- [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
- [ICE_EEP2_GPIO_DIR] = 0xff,
- [ICE_EEP2_GPIO_DIR1] = 0xff,
- [ICE_EEP2_GPIO_DIR2] = 0x5f,
- [ICE_EEP2_GPIO_MASK] = 0x00,
- [ICE_EEP2_GPIO_MASK1] = 0x00,
- [ICE_EEP2_GPIO_MASK2] = 0x00,
- [ICE_EEP2_GPIO_STATE] = 0x00,
- [ICE_EEP2_GPIO_STATE1] = 0x00,
- [ICE_EEP2_GPIO_STATE2] = 0x00,
-};
-
-/*
- * write data in the SPI mode
- */
-static void phase28_spi_write(struct snd_ice1712 *ice, unsigned int cs,
- unsigned int data, int bits)
-{
- unsigned int tmp;
- int i;
-
- tmp = snd_ice1712_gpio_read(ice);
-
- snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RW|PHASE28_SPI_MOSI|
- PHASE28_SPI_CLK|PHASE28_WM_CS));
- tmp |= PHASE28_WM_RW;
- tmp &= ~cs;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
-
- for (i = bits - 1; i >= 0; i--) {
- tmp &= ~PHASE28_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- if (data & (1 << i))
- tmp |= PHASE28_SPI_MOSI;
- else
- tmp &= ~PHASE28_SPI_MOSI;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- tmp |= PHASE28_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- }
-
- tmp &= ~PHASE28_SPI_CLK;
- tmp |= cs;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- tmp |= PHASE28_SPI_CLK;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
-}
-
-/*
- * get the current register value of WM codec
- */
-static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
-{
- reg <<= 1;
- return ((unsigned short)ice->akm[0].images[reg] << 8) |
- ice->akm[0].images[reg + 1];
-}
-
-/*
- * set the register value of WM codec
- */
-static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
-{
- phase28_spi_write(ice, PHASE28_WM_CS, (reg << 9) | (val & 0x1ff), 16);
-}
-
-/*
- * set the register value of WM codec and remember it
- */
-static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
-{
- wm_put_nocache(ice, reg, val);
- reg <<= 1;
- ice->akm[0].images[reg] = val >> 8;
- ice->akm[0].images[reg + 1] = val;
-}
-
-static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index,
- unsigned short vol, unsigned short master)
-{
- unsigned char nvol;
-
- if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
- nvol = 0;
- else
- nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) *
- (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
-
- wm_put(ice, index, nvol);
- wm_put_nocache(ice, index, 0x180 | nvol);
-}
-
-/*
- * DAC mute control
- */
-#define wm_pcm_mute_info snd_ctl_boolean_mono_info
-
-static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&ice->gpio_mutex);
- ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ?
- 0 : 1;
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short nval, oval;
- int change;
-
- snd_ice1712_save_gpio_status(ice);
- oval = wm_get(ice, WM_MUTE);
- nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
- change = (nval != oval);
- if (change)
- wm_put(ice, WM_MUTE, nval);
- snd_ice1712_restore_gpio_status(ice);
-
- return change;
-}
-
-/*
- * Master volume attenuation mixer control
- */
-static int wm_master_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = WM_VOL_MAX;
- return 0;
-}
-
-static int wm_master_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct phase28_spec *spec = ice->spec;
- int i;
- for (i = 0; i < 2; i++)
- ucontrol->value.integer.value[i] = spec->master[i] &
- ~WM_VOL_MUTE;
- return 0;
-}
-
-static int wm_master_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct phase28_spec *spec = ice->spec;
- int ch, change = 0;
-
- snd_ice1712_save_gpio_status(ice);
- for (ch = 0; ch < 2; ch++) {
- unsigned int vol = ucontrol->value.integer.value[ch];
- if (vol > WM_VOL_MAX)
- continue;
- vol |= spec->master[ch] & WM_VOL_MUTE;
- if (vol != spec->master[ch]) {
- int dac;
- spec->master[ch] = vol;
- for (dac = 0; dac < ice->num_total_dacs; dac += 2)
- wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
- spec->vol[dac + ch],
- spec->master[ch]);
- change = 1;
- }
- }
- snd_ice1712_restore_gpio_status(ice);
- return change;
-}
-
-static int __devinit phase28_init(struct snd_ice1712 *ice)
-{
- static const unsigned short wm_inits_phase28[] = {
- /* These come first to reduce init pop noise */
- 0x1b, 0x044, /* ADC Mux (AC'97 source) */
- 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
- 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
-
- 0x18, 0x000, /* All power-up */
-
- 0x16, 0x122, /* I2S, normal polarity, 24bit */
- 0x17, 0x022, /* 256fs, slave mode */
- 0x00, 0, /* DAC1 analog mute */
- 0x01, 0, /* DAC2 analog mute */
- 0x02, 0, /* DAC3 analog mute */
- 0x03, 0, /* DAC4 analog mute */
- 0x04, 0, /* DAC5 analog mute */
- 0x05, 0, /* DAC6 analog mute */
- 0x06, 0, /* DAC7 analog mute */
- 0x07, 0, /* DAC8 analog mute */
- 0x08, 0x100, /* master analog mute */
- 0x09, 0xff, /* DAC1 digital full */
- 0x0a, 0xff, /* DAC2 digital full */
- 0x0b, 0xff, /* DAC3 digital full */
- 0x0c, 0xff, /* DAC4 digital full */
- 0x0d, 0xff, /* DAC5 digital full */
- 0x0e, 0xff, /* DAC6 digital full */
- 0x0f, 0xff, /* DAC7 digital full */
- 0x10, 0xff, /* DAC8 digital full */
- 0x11, 0x1ff, /* master digital full */
- 0x12, 0x000, /* phase normal */
- 0x13, 0x090, /* unmute DAC L/R */
- 0x14, 0x000, /* all unmute */
- 0x15, 0x000, /* no deemphasis, no ZFLG */
- 0x19, 0x000, /* -12dB ADC/L */
- 0x1a, 0x000, /* -12dB ADC/R */
- (unsigned short)-1
- };
-
- unsigned int tmp;
- struct snd_akm4xxx *ak;
- struct phase28_spec *spec;
- const unsigned short *p;
- int i;
-
- ice->num_total_dacs = 8;
- ice->num_total_adcs = 2;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- ice->spec = spec;
-
- /* Initialize analog chips */
- ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
- ak = ice->akm;
- if (!ak)
- return -ENOMEM;
- ice->akm_codecs = 1;
-
- snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for time being */
-
- /* reset the wm codec as the SPI mode */
- snd_ice1712_save_gpio_status(ice);
- snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RESET|PHASE28_WM_CS|
- PHASE28_HP_SEL));
-
- tmp = snd_ice1712_gpio_read(ice);
- tmp &= ~PHASE28_WM_RESET;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- tmp |= PHASE28_WM_CS;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- tmp |= PHASE28_WM_RESET;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
-
- p = wm_inits_phase28;
- for (; *p != (unsigned short)-1; p += 2)
- wm_put(ice, p[0], p[1]);
-
- snd_ice1712_restore_gpio_status(ice);
-
- spec->master[0] = WM_VOL_MUTE;
- spec->master[1] = WM_VOL_MUTE;
- for (i = 0; i < ice->num_total_dacs; i++) {
- spec->vol[i] = WM_VOL_MUTE;
- wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
- }
-
- return 0;
-}
-
-/*
- * DAC volume attenuation mixer control
- */
-static int wm_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int voices = kcontrol->private_value >> 8;
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = voices;
- uinfo->value.integer.min = 0; /* mute (-101dB) */
- uinfo->value.integer.max = 0x7F; /* 0dB */
- return 0;
-}
-
-static int wm_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct phase28_spec *spec = ice->spec;
- int i, ofs, voices;
-
- voices = kcontrol->private_value >> 8;
- ofs = kcontrol->private_value & 0xff;
- for (i = 0; i < voices; i++)
- ucontrol->value.integer.value[i] =
- spec->vol[ofs+i] & ~WM_VOL_MUTE;
- return 0;
-}
-
-static int wm_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct phase28_spec *spec = ice->spec;
- int i, idx, ofs, voices;
- int change = 0;
-
- voices = kcontrol->private_value >> 8;
- ofs = kcontrol->private_value & 0xff;
- snd_ice1712_save_gpio_status(ice);
- for (i = 0; i < voices; i++) {
- unsigned int vol;
- vol = ucontrol->value.integer.value[i];
- if (vol > 0x7f)
- continue;
- vol |= spec->vol[ofs+i] & WM_VOL_MUTE;
- if (vol != spec->vol[ofs+i]) {
- spec->vol[ofs+i] = vol;
- idx = WM_DAC_ATTEN + ofs + i;
- wm_set_vol(ice, idx, spec->vol[ofs+i],
- spec->master[i]);
- change = 1;
- }
- }
- snd_ice1712_restore_gpio_status(ice);
- return change;
-}
-
-/*
- * WM8770 mute control
- */
-static int wm_mute_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo) {
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = kcontrol->private_value >> 8;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int wm_mute_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct phase28_spec *spec = ice->spec;
- int voices, ofs, i;
-
- voices = kcontrol->private_value >> 8;
- ofs = kcontrol->private_value & 0xFF;
-
- for (i = 0; i < voices; i++)
- ucontrol->value.integer.value[i] =
- (spec->vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1;
- return 0;
-}
-
-static int wm_mute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct phase28_spec *spec = ice->spec;
- int change = 0, voices, ofs, i;
-
- voices = kcontrol->private_value >> 8;
- ofs = kcontrol->private_value & 0xFF;
-
- snd_ice1712_save_gpio_status(ice);
- for (i = 0; i < voices; i++) {
- int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
- if (ucontrol->value.integer.value[i] != val) {
- spec->vol[ofs + i] &= ~WM_VOL_MUTE;
- spec->vol[ofs + i] |=
- ucontrol->value.integer.value[i] ? 0 :
- WM_VOL_MUTE;
- wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
- spec->master[i]);
- change = 1;
- }
- }
- snd_ice1712_restore_gpio_status(ice);
-
- return change;
-}
-
-/*
- * WM8770 master mute control
- */
-#define wm_master_mute_info snd_ctl_boolean_stereo_info
-
-static int wm_master_mute_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct phase28_spec *spec = ice->spec;
-
- ucontrol->value.integer.value[0] =
- (spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
- ucontrol->value.integer.value[1] =
- (spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
- return 0;
-}
-
-static int wm_master_mute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct phase28_spec *spec = ice->spec;
- int change = 0, i;
-
- snd_ice1712_save_gpio_status(ice);
- for (i = 0; i < 2; i++) {
- int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
- if (ucontrol->value.integer.value[i] != val) {
- int dac;
- spec->master[i] &= ~WM_VOL_MUTE;
- spec->master[i] |=
- ucontrol->value.integer.value[i] ? 0 :
- WM_VOL_MUTE;
- for (dac = 0; dac < ice->num_total_dacs; dac += 2)
- wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
- spec->vol[dac + i],
- spec->master[i]);
- change = 1;
- }
- }
- snd_ice1712_restore_gpio_status(ice);
-
- return change;
-}
-
-/* digital master volume */
-#define PCM_0dB 0xff
-#define PCM_RES 128 /* -64dB */
-#define PCM_MIN (PCM_0dB - PCM_RES)
-static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0; /* mute (-64dB) */
- uinfo->value.integer.max = PCM_RES; /* 0dB */
- return 0;
-}
-
-static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short val;
-
- mutex_lock(&ice->gpio_mutex);
- val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
- val = val > PCM_MIN ? (val - PCM_MIN) : 0;
- ucontrol->value.integer.value[0] = val;
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short ovol, nvol;
- int change = 0;
-
- nvol = ucontrol->value.integer.value[0];
- if (nvol > PCM_RES)
- return -EINVAL;
- snd_ice1712_save_gpio_status(ice);
- nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
- ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
- if (ovol != nvol) {
- wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
- /* update */
- wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100);
- change = 1;
- }
- snd_ice1712_restore_gpio_status(ice);
- return change;
-}
-
-/*
- * Deemphasis
- */
-#define phase28_deemp_info snd_ctl_boolean_mono_info
-
-static int phase28_deemp_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) ==
- 0xf;
- return 0;
-}
-
-static int phase28_deemp_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int temp, temp2;
- temp = wm_get(ice, WM_DAC_CTRL2);
- temp2 = temp;
- if (ucontrol->value.integer.value[0])
- temp |= 0xf;
- else
- temp &= ~0xf;
- if (temp != temp2) {
- wm_put(ice, WM_DAC_CTRL2, temp);
- return 1;
- }
- return 0;
-}
-
-/*
- * ADC Oversampling
- */
-static int phase28_oversampling_info(struct snd_kcontrol *k,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[2] = { "128x", "64x" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items -
- 1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-static int phase28_oversampling_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) ==
- 0x8;
- return 0;
-}
-
-static int phase28_oversampling_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int temp, temp2;
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- temp = wm_get(ice, WM_MASTER);
- temp2 = temp;
-
- if (ucontrol->value.enumerated.item[0])
- temp |= 0x8;
- else
- temp &= ~0x8;
-
- if (temp != temp2) {
- wm_put(ice, WM_MASTER, temp);
- return 1;
- }
- return 0;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
-static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
-
-static struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = wm_master_mute_info,
- .get = wm_master_mute_get,
- .put = wm_master_mute_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Master Playback Volume",
- .info = wm_master_vol_info,
- .get = wm_master_vol_get,
- .put = wm_master_vol_put,
- .tlv = { .p = db_scale_wm_dac }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Front Playback Switch",
- .info = wm_mute_info,
- .get = wm_mute_get,
- .put = wm_mute_put,
- .private_value = (2 << 8) | 0
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Front Playback Volume",
- .info = wm_vol_info,
- .get = wm_vol_get,
- .put = wm_vol_put,
- .private_value = (2 << 8) | 0,
- .tlv = { .p = db_scale_wm_dac }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Rear Playback Switch",
- .info = wm_mute_info,
- .get = wm_mute_get,
- .put = wm_mute_put,
- .private_value = (2 << 8) | 2
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Rear Playback Volume",
- .info = wm_vol_info,
- .get = wm_vol_get,
- .put = wm_vol_put,
- .private_value = (2 << 8) | 2,
- .tlv = { .p = db_scale_wm_dac }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Center Playback Switch",
- .info = wm_mute_info,
- .get = wm_mute_get,
- .put = wm_mute_put,
- .private_value = (1 << 8) | 4
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Center Playback Volume",
- .info = wm_vol_info,
- .get = wm_vol_get,
- .put = wm_vol_put,
- .private_value = (1 << 8) | 4,
- .tlv = { .p = db_scale_wm_dac }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "LFE Playback Switch",
- .info = wm_mute_info,
- .get = wm_mute_get,
- .put = wm_mute_put,
- .private_value = (1 << 8) | 5
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "LFE Playback Volume",
- .info = wm_vol_info,
- .get = wm_vol_get,
- .put = wm_vol_put,
- .private_value = (1 << 8) | 5,
- .tlv = { .p = db_scale_wm_dac }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Side Playback Switch",
- .info = wm_mute_info,
- .get = wm_mute_get,
- .put = wm_mute_put,
- .private_value = (2 << 8) | 6
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Side Playback Volume",
- .info = wm_vol_info,
- .get = wm_vol_get,
- .put = wm_vol_put,
- .private_value = (2 << 8) | 6,
- .tlv = { .p = db_scale_wm_dac }
- }
-};
-
-static struct snd_kcontrol_new wm_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Playback Switch",
- .info = wm_pcm_mute_info,
- .get = wm_pcm_mute_get,
- .put = wm_pcm_mute_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "PCM Playback Volume",
- .info = wm_pcm_vol_info,
- .get = wm_pcm_vol_get,
- .put = wm_pcm_vol_put,
- .tlv = { .p = db_scale_wm_pcm }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "DAC Deemphasis Switch",
- .info = phase28_deemp_info,
- .get = phase28_deemp_get,
- .put = phase28_deemp_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "ADC Oversampling",
- .info = phase28_oversampling_info,
- .get = phase28_oversampling_get,
- .put = phase28_oversampling_put
- }
-};
-
-static int __devinit phase28_add_controls(struct snd_ice1712 *ice)
-{
- unsigned int i, counts;
- int err;
-
- counts = ARRAY_SIZE(phase28_dac_controls);
- for (i = 0; i < counts; i++) {
- err = snd_ctl_add(ice->card,
- snd_ctl_new1(&phase28_dac_controls[i],
- ice));
- if (err < 0)
- return err;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
- err = snd_ctl_add(ice->card,
- snd_ctl_new1(&wm_controls[i], ice));
- if (err < 0)
- return err;
- }
-
- return 0;
-}
-
-struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = {
- {
- .subvendor = VT1724_SUBDEVICE_PHASE22,
- .name = "Terratec PHASE 22",
- .model = "phase22",
- .chip_init = phase22_init,
- .build_controls = phase22_add_controls,
- .eeprom_size = sizeof(phase22_eeprom),
- .eeprom_data = phase22_eeprom,
- },
- {
- .subvendor = VT1724_SUBDEVICE_PHASE28,
- .name = "Terratec PHASE 28",
- .model = "phase28",
- .chip_init = phase28_init,
- .build_controls = phase28_add_controls,
- .eeprom_size = sizeof(phase28_eeprom),
- .eeprom_data = phase28_eeprom,
- },
- {
- .subvendor = VT1724_SUBDEVICE_TS22,
- .name = "Terrasoniq TS22 PCI",
- .model = "TS22",
- .chip_init = phase22_init,
- .build_controls = phase22_add_controls,
- .eeprom_size = sizeof(phase22_eeprom),
- .eeprom_data = phase22_eeprom,
- },
- { } /* terminator */
-};
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/phase.h b/ANDROID_3.4.5/sound/pci/ice1712/phase.h
deleted file mode 100644
index 7fc22d9d..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/phase.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef __SOUND_PHASE_H
-#define __SOUND_PHASE_H
-
-/*
- * ALSA driver for ICEnsemble ICE1712 (Envy24)
- *
- * Lowlevel functions for Terratec PHASE 22
- *
- * Copyright (c) 2005 Misha Zhilin <misha@epiphan.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define PHASE_DEVICE_DESC "{Terratec,Phase 22},"\
- "{Terratec,Phase 28},"\
- "{Terrasoniq,TS22},"
-
-#define VT1724_SUBDEVICE_PHASE22 0x3b155011
-#define VT1724_SUBDEVICE_PHASE28 0x3b154911
-#define VT1724_SUBDEVICE_TS22 0x3b157b11
-
-/* entry point */
-extern struct snd_ice1712_card_info snd_vt1724_phase_cards[];
-
-/* PHASE28 GPIO bits */
-#define PHASE28_SPI_MISO (1 << 21)
-#define PHASE28_WM_RESET (1 << 20)
-#define PHASE28_SPI_CLK (1 << 19)
-#define PHASE28_SPI_MOSI (1 << 18)
-#define PHASE28_WM_RW (1 << 17)
-#define PHASE28_AC97_RESET (1 << 16)
-#define PHASE28_DIGITAL_SEL1 (1 << 15)
-#define PHASE28_HP_SEL (1 << 14)
-#define PHASE28_WM_CS (1 << 12)
-#define PHASE28_AC97_COMMIT (1 << 11)
-#define PHASE28_AC97_ADDR (1 << 10)
-#define PHASE28_AC97_DATA_LOW (1 << 9)
-#define PHASE28_AC97_DATA_HIGH (1 << 8)
-#define PHASE28_AC97_DATA_MASK 0xFF
-#endif /* __SOUND_PHASE */
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/pontis.c b/ANDROID_3.4.5/sound/pci/ice1712/pontis.c
deleted file mode 100644
index 92c1160d..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/pontis.c
+++ /dev/null
@@ -1,836 +0,0 @@
-/*
- * ALSA driver for ICEnsemble VT1724 (Envy24HT)
- *
- * Lowlevel functions for Pontis MS300
- *
- * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/tlv.h>
-
-#include "ice1712.h"
-#include "envy24ht.h"
-#include "pontis.h"
-
-/* I2C addresses */
-#define WM_DEV 0x34
-#define CS_DEV 0x20
-
-/* WM8776 registers */
-#define WM_HP_ATTEN_L 0x00 /* headphone left attenuation */
-#define WM_HP_ATTEN_R 0x01 /* headphone left attenuation */
-#define WM_HP_MASTER 0x02 /* headphone master (both channels) */
- /* override LLR */
-#define WM_DAC_ATTEN_L 0x03 /* digital left attenuation */
-#define WM_DAC_ATTEN_R 0x04
-#define WM_DAC_MASTER 0x05
-#define WM_PHASE_SWAP 0x06 /* DAC phase swap */
-#define WM_DAC_CTRL1 0x07
-#define WM_DAC_MUTE 0x08
-#define WM_DAC_CTRL2 0x09
-#define WM_DAC_INT 0x0a
-#define WM_ADC_INT 0x0b
-#define WM_MASTER_CTRL 0x0c
-#define WM_POWERDOWN 0x0d
-#define WM_ADC_ATTEN_L 0x0e
-#define WM_ADC_ATTEN_R 0x0f
-#define WM_ALC_CTRL1 0x10
-#define WM_ALC_CTRL2 0x11
-#define WM_ALC_CTRL3 0x12
-#define WM_NOISE_GATE 0x13
-#define WM_LIMITER 0x14
-#define WM_ADC_MUX 0x15
-#define WM_OUT_MUX 0x16
-#define WM_RESET 0x17
-
-/*
- * GPIO
- */
-#define PONTIS_CS_CS (1<<4) /* CS */
-#define PONTIS_CS_CLK (1<<5) /* CLK */
-#define PONTIS_CS_RDATA (1<<6) /* CS8416 -> VT1720 */
-#define PONTIS_CS_WDATA (1<<7) /* VT1720 -> CS8416 */
-
-
-/*
- * get the current register value of WM codec
- */
-static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
-{
- reg <<= 1;
- return ((unsigned short)ice->akm[0].images[reg] << 8) |
- ice->akm[0].images[reg + 1];
-}
-
-/*
- * set the register value of WM codec and remember it
- */
-static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
-{
- unsigned short cval;
- cval = (reg << 9) | val;
- snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff);
-}
-
-static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
-{
- wm_put_nocache(ice, reg, val);
- reg <<= 1;
- ice->akm[0].images[reg] = val >> 8;
- ice->akm[0].images[reg + 1] = val;
-}
-
-/*
- * DAC volume attenuation mixer control (-64dB to 0dB)
- */
-
-#define DAC_0dB 0xff
-#define DAC_RES 128
-#define DAC_MIN (DAC_0dB - DAC_RES)
-
-static int wm_dac_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0; /* mute */
- uinfo->value.integer.max = DAC_RES; /* 0dB, 0.5dB step */
- return 0;
-}
-
-static int wm_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short val;
- int i;
-
- mutex_lock(&ice->gpio_mutex);
- for (i = 0; i < 2; i++) {
- val = wm_get(ice, WM_DAC_ATTEN_L + i) & 0xff;
- val = val > DAC_MIN ? (val - DAC_MIN) : 0;
- ucontrol->value.integer.value[i] = val;
- }
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short oval, nval;
- int i, idx, change = 0;
-
- mutex_lock(&ice->gpio_mutex);
- for (i = 0; i < 2; i++) {
- nval = ucontrol->value.integer.value[i];
- nval = (nval ? (nval + DAC_MIN) : 0) & 0xff;
- idx = WM_DAC_ATTEN_L + i;
- oval = wm_get(ice, idx) & 0xff;
- if (oval != nval) {
- wm_put(ice, idx, nval);
- wm_put_nocache(ice, idx, nval | 0x100);
- change = 1;
- }
- }
- mutex_unlock(&ice->gpio_mutex);
- return change;
-}
-
-/*
- * ADC gain mixer control (-64dB to 0dB)
- */
-
-#define ADC_0dB 0xcf
-#define ADC_RES 128
-#define ADC_MIN (ADC_0dB - ADC_RES)
-
-static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0; /* mute (-64dB) */
- uinfo->value.integer.max = ADC_RES; /* 0dB, 0.5dB step */
- return 0;
-}
-
-static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short val;
- int i;
-
- mutex_lock(&ice->gpio_mutex);
- for (i = 0; i < 2; i++) {
- val = wm_get(ice, WM_ADC_ATTEN_L + i) & 0xff;
- val = val > ADC_MIN ? (val - ADC_MIN) : 0;
- ucontrol->value.integer.value[i] = val;
- }
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short ovol, nvol;
- int i, idx, change = 0;
-
- mutex_lock(&ice->gpio_mutex);
- for (i = 0; i < 2; i++) {
- nvol = ucontrol->value.integer.value[i];
- nvol = nvol ? (nvol + ADC_MIN) : 0;
- idx = WM_ADC_ATTEN_L + i;
- ovol = wm_get(ice, idx) & 0xff;
- if (ovol != nvol) {
- wm_put(ice, idx, nvol);
- change = 1;
- }
- }
- mutex_unlock(&ice->gpio_mutex);
- return change;
-}
-
-/*
- * ADC input mux mixer control
- */
-#define wm_adc_mux_info snd_ctl_boolean_mono_info
-
-static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int bit = kcontrol->private_value;
-
- mutex_lock(&ice->gpio_mutex);
- ucontrol->value.integer.value[0] = (wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0;
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int bit = kcontrol->private_value;
- unsigned short oval, nval;
- int change;
-
- mutex_lock(&ice->gpio_mutex);
- nval = oval = wm_get(ice, WM_ADC_MUX);
- if (ucontrol->value.integer.value[0])
- nval |= (1 << bit);
- else
- nval &= ~(1 << bit);
- change = nval != oval;
- if (change) {
- wm_put(ice, WM_ADC_MUX, nval);
- }
- mutex_unlock(&ice->gpio_mutex);
- return change;
-}
-
-/*
- * Analog bypass (In -> Out)
- */
-#define wm_bypass_info snd_ctl_boolean_mono_info
-
-static int wm_bypass_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&ice->gpio_mutex);
- ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0;
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int wm_bypass_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short val, oval;
- int change = 0;
-
- mutex_lock(&ice->gpio_mutex);
- val = oval = wm_get(ice, WM_OUT_MUX);
- if (ucontrol->value.integer.value[0])
- val |= 0x04;
- else
- val &= ~0x04;
- if (val != oval) {
- wm_put(ice, WM_OUT_MUX, val);
- change = 1;
- }
- mutex_unlock(&ice->gpio_mutex);
- return change;
-}
-
-/*
- * Left/Right swap
- */
-#define wm_chswap_info snd_ctl_boolean_mono_info
-
-static int wm_chswap_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&ice->gpio_mutex);
- ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90;
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int wm_chswap_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short val, oval;
- int change = 0;
-
- mutex_lock(&ice->gpio_mutex);
- oval = wm_get(ice, WM_DAC_CTRL1);
- val = oval & 0x0f;
- if (ucontrol->value.integer.value[0])
- val |= 0x60;
- else
- val |= 0x90;
- if (val != oval) {
- wm_put(ice, WM_DAC_CTRL1, val);
- wm_put_nocache(ice, WM_DAC_CTRL1, val);
- change = 1;
- }
- mutex_unlock(&ice->gpio_mutex);
- return change;
-}
-
-/*
- * write data in the SPI mode
- */
-static void set_gpio_bit(struct snd_ice1712 *ice, unsigned int bit, int val)
-{
- unsigned int tmp = snd_ice1712_gpio_read(ice);
- if (val)
- tmp |= bit;
- else
- tmp &= ~bit;
- snd_ice1712_gpio_write(ice, tmp);
-}
-
-static void spi_send_byte(struct snd_ice1712 *ice, unsigned char data)
-{
- int i;
- for (i = 0; i < 8; i++) {
- set_gpio_bit(ice, PONTIS_CS_CLK, 0);
- udelay(1);
- set_gpio_bit(ice, PONTIS_CS_WDATA, data & 0x80);
- udelay(1);
- set_gpio_bit(ice, PONTIS_CS_CLK, 1);
- udelay(1);
- data <<= 1;
- }
-}
-
-static unsigned int spi_read_byte(struct snd_ice1712 *ice)
-{
- int i;
- unsigned int val = 0;
-
- for (i = 0; i < 8; i++) {
- val <<= 1;
- set_gpio_bit(ice, PONTIS_CS_CLK, 0);
- udelay(1);
- if (snd_ice1712_gpio_read(ice) & PONTIS_CS_RDATA)
- val |= 1;
- udelay(1);
- set_gpio_bit(ice, PONTIS_CS_CLK, 1);
- udelay(1);
- }
- return val;
-}
-
-
-static void spi_write(struct snd_ice1712 *ice, unsigned int dev, unsigned int reg, unsigned int data)
-{
- snd_ice1712_gpio_set_dir(ice, PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK);
- snd_ice1712_gpio_set_mask(ice, ~(PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK));
- set_gpio_bit(ice, PONTIS_CS_CS, 0);
- spi_send_byte(ice, dev & ~1); /* WRITE */
- spi_send_byte(ice, reg); /* MAP */
- spi_send_byte(ice, data); /* DATA */
- /* trigger */
- set_gpio_bit(ice, PONTIS_CS_CS, 1);
- udelay(1);
- /* restore */
- snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
- snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
-}
-
-static unsigned int spi_read(struct snd_ice1712 *ice, unsigned int dev, unsigned int reg)
-{
- unsigned int val;
- snd_ice1712_gpio_set_dir(ice, PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK);
- snd_ice1712_gpio_set_mask(ice, ~(PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK));
- set_gpio_bit(ice, PONTIS_CS_CS, 0);
- spi_send_byte(ice, dev & ~1); /* WRITE */
- spi_send_byte(ice, reg); /* MAP */
- /* trigger */
- set_gpio_bit(ice, PONTIS_CS_CS, 1);
- udelay(1);
- set_gpio_bit(ice, PONTIS_CS_CS, 0);
- spi_send_byte(ice, dev | 1); /* READ */
- val = spi_read_byte(ice);
- /* trigger */
- set_gpio_bit(ice, PONTIS_CS_CS, 1);
- udelay(1);
- /* restore */
- snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
- snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
- return val;
-}
-
-
-/*
- * SPDIF input source
- */
-static int cs_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static const char * const texts[] = {
- "Coax", /* RXP0 */
- "Optical", /* RXP1 */
- "CD", /* RXP2 */
- };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int cs_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&ice->gpio_mutex);
- ucontrol->value.enumerated.item[0] = ice->gpio.saved[0];
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int cs_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char val;
- int change = 0;
-
- mutex_lock(&ice->gpio_mutex);
- if (ucontrol->value.enumerated.item[0] != ice->gpio.saved[0]) {
- ice->gpio.saved[0] = ucontrol->value.enumerated.item[0] & 3;
- val = 0x80 | (ice->gpio.saved[0] << 3);
- spi_write(ice, CS_DEV, 0x04, val);
- change = 1;
- }
- mutex_unlock(&ice->gpio_mutex);
- return change;
-}
-
-
-/*
- * GPIO controls
- */
-static int pontis_gpio_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 0xffff; /* 16bit */
- return 0;
-}
-
-static int pontis_gpio_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
- /* 4-7 reserved */
- ucontrol->value.integer.value[0] = (~ice->gpio.write_mask & 0xffff) | 0x00f0;
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int pontis_gpio_mask_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int changed;
- mutex_lock(&ice->gpio_mutex);
- /* 4-7 reserved */
- val = (~ucontrol->value.integer.value[0] & 0xffff) | 0x00f0;
- changed = val != ice->gpio.write_mask;
- ice->gpio.write_mask = val;
- mutex_unlock(&ice->gpio_mutex);
- return changed;
-}
-
-static int pontis_gpio_dir_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
- /* 4-7 reserved */
- ucontrol->value.integer.value[0] = ice->gpio.direction & 0xff0f;
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int pontis_gpio_dir_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int changed;
- mutex_lock(&ice->gpio_mutex);
- /* 4-7 reserved */
- val = ucontrol->value.integer.value[0] & 0xff0f;
- changed = (val != ice->gpio.direction);
- ice->gpio.direction = val;
- mutex_unlock(&ice->gpio_mutex);
- return changed;
-}
-
-static int pontis_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- mutex_lock(&ice->gpio_mutex);
- snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
- snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
- ucontrol->value.integer.value[0] = snd_ice1712_gpio_read(ice) & 0xffff;
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int pontis_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned int val, nval;
- int changed = 0;
- mutex_lock(&ice->gpio_mutex);
- snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
- snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
- val = snd_ice1712_gpio_read(ice) & 0xffff;
- nval = ucontrol->value.integer.value[0] & 0xffff;
- if (val != nval) {
- snd_ice1712_gpio_write(ice, nval);
- changed = 1;
- }
- mutex_unlock(&ice->gpio_mutex);
- return changed;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_volume, -6400, 50, 1);
-
-/*
- * mixers
- */
-
-static struct snd_kcontrol_new pontis_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "PCM Playback Volume",
- .info = wm_dac_vol_info,
- .get = wm_dac_vol_get,
- .put = wm_dac_vol_put,
- .tlv = { .p = db_scale_volume },
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Capture Volume",
- .info = wm_adc_vol_info,
- .get = wm_adc_vol_get,
- .put = wm_adc_vol_put,
- .tlv = { .p = db_scale_volume },
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "CD Capture Switch",
- .info = wm_adc_mux_info,
- .get = wm_adc_mux_get,
- .put = wm_adc_mux_put,
- .private_value = 0,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Line Capture Switch",
- .info = wm_adc_mux_info,
- .get = wm_adc_mux_get,
- .put = wm_adc_mux_put,
- .private_value = 1,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Bypass Switch",
- .info = wm_bypass_info,
- .get = wm_bypass_get,
- .put = wm_bypass_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Swap Output Channels",
- .info = wm_chswap_info,
- .get = wm_chswap_get,
- .put = wm_chswap_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "IEC958 Input Source",
- .info = cs_source_info,
- .get = cs_source_get,
- .put = cs_source_put,
- },
- /* FIXME: which interface? */
- {
- .iface = SNDRV_CTL_ELEM_IFACE_CARD,
- .name = "GPIO Mask",
- .info = pontis_gpio_mask_info,
- .get = pontis_gpio_mask_get,
- .put = pontis_gpio_mask_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_CARD,
- .name = "GPIO Direction",
- .info = pontis_gpio_mask_info,
- .get = pontis_gpio_dir_get,
- .put = pontis_gpio_dir_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_CARD,
- .name = "GPIO Data",
- .info = pontis_gpio_mask_info,
- .get = pontis_gpio_data_get,
- .put = pontis_gpio_data_put,
- },
-};
-
-
-/*
- * WM codec registers
- */
-static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- struct snd_ice1712 *ice = entry->private_data;
- char line[64];
- unsigned int reg, val;
- mutex_lock(&ice->gpio_mutex);
- while (!snd_info_get_line(buffer, line, sizeof(line))) {
- if (sscanf(line, "%x %x", &reg, &val) != 2)
- continue;
- if (reg <= 0x17 && val <= 0xffff)
- wm_put(ice, reg, val);
- }
- mutex_unlock(&ice->gpio_mutex);
-}
-
-static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- struct snd_ice1712 *ice = entry->private_data;
- int reg, val;
-
- mutex_lock(&ice->gpio_mutex);
- for (reg = 0; reg <= 0x17; reg++) {
- val = wm_get(ice, reg);
- snd_iprintf(buffer, "%02x = %04x\n", reg, val);
- }
- mutex_unlock(&ice->gpio_mutex);
-}
-
-static void wm_proc_init(struct snd_ice1712 *ice)
-{
- struct snd_info_entry *entry;
- if (! snd_card_proc_new(ice->card, "wm_codec", &entry)) {
- snd_info_set_text_ops(entry, ice, wm_proc_regs_read);
- entry->mode |= S_IWUSR;
- entry->c.text.write = wm_proc_regs_write;
- }
-}
-
-static void cs_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- struct snd_ice1712 *ice = entry->private_data;
- int reg, val;
-
- mutex_lock(&ice->gpio_mutex);
- for (reg = 0; reg <= 0x26; reg++) {
- val = spi_read(ice, CS_DEV, reg);
- snd_iprintf(buffer, "%02x = %02x\n", reg, val);
- }
- val = spi_read(ice, CS_DEV, 0x7f);
- snd_iprintf(buffer, "%02x = %02x\n", 0x7f, val);
- mutex_unlock(&ice->gpio_mutex);
-}
-
-static void cs_proc_init(struct snd_ice1712 *ice)
-{
- struct snd_info_entry *entry;
- if (! snd_card_proc_new(ice->card, "cs_codec", &entry))
- snd_info_set_text_ops(entry, ice, cs_proc_regs_read);
-}
-
-
-static int __devinit pontis_add_controls(struct snd_ice1712 *ice)
-{
- unsigned int i;
- int err;
-
- for (i = 0; i < ARRAY_SIZE(pontis_controls); i++) {
- err = snd_ctl_add(ice->card, snd_ctl_new1(&pontis_controls[i], ice));
- if (err < 0)
- return err;
- }
-
- wm_proc_init(ice);
- cs_proc_init(ice);
-
- return 0;
-}
-
-
-/*
- * initialize the chip
- */
-static int __devinit pontis_init(struct snd_ice1712 *ice)
-{
- static const unsigned short wm_inits[] = {
- /* These come first to reduce init pop noise */
- WM_ADC_MUX, 0x00c0, /* ADC mute */
- WM_DAC_MUTE, 0x0001, /* DAC softmute */
- WM_DAC_CTRL1, 0x0000, /* DAC mute */
-
- WM_POWERDOWN, 0x0008, /* All power-up except HP */
- WM_RESET, 0x0000, /* reset */
- };
- static const unsigned short wm_inits2[] = {
- WM_MASTER_CTRL, 0x0022, /* 256fs, slave mode */
- WM_DAC_INT, 0x0022, /* I2S, normal polarity, 24bit */
- WM_ADC_INT, 0x0022, /* I2S, normal polarity, 24bit */
- WM_DAC_CTRL1, 0x0090, /* DAC L/R */
- WM_OUT_MUX, 0x0001, /* OUT DAC */
- WM_HP_ATTEN_L, 0x0179, /* HP 0dB */
- WM_HP_ATTEN_R, 0x0179, /* HP 0dB */
- WM_DAC_ATTEN_L, 0x0000, /* DAC 0dB */
- WM_DAC_ATTEN_L, 0x0100, /* DAC 0dB */
- WM_DAC_ATTEN_R, 0x0000, /* DAC 0dB */
- WM_DAC_ATTEN_R, 0x0100, /* DAC 0dB */
- /* WM_DAC_MASTER, 0x0100, */ /* DAC master muted */
- WM_PHASE_SWAP, 0x0000, /* phase normal */
- WM_DAC_CTRL2, 0x0000, /* no deemphasis, no ZFLG */
- WM_ADC_ATTEN_L, 0x0000, /* ADC muted */
- WM_ADC_ATTEN_R, 0x0000, /* ADC muted */
-#if 0
- WM_ALC_CTRL1, 0x007b, /* */
- WM_ALC_CTRL2, 0x0000, /* */
- WM_ALC_CTRL3, 0x0000, /* */
- WM_NOISE_GATE, 0x0000, /* */
-#endif
- WM_DAC_MUTE, 0x0000, /* DAC unmute */
- WM_ADC_MUX, 0x0003, /* ADC unmute, both CD/Line On */
- };
- static const unsigned char cs_inits[] = {
- 0x04, 0x80, /* RUN, RXP0 */
- 0x05, 0x05, /* slave, 24bit */
- 0x01, 0x00,
- 0x02, 0x00,
- 0x03, 0x00,
- };
- unsigned int i;
-
- ice->vt1720 = 1;
- ice->num_total_dacs = 2;
- ice->num_total_adcs = 2;
-
- /* to remember the register values */
- ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
- if (! ice->akm)
- return -ENOMEM;
- ice->akm_codecs = 1;
-
- /* HACK - use this as the SPDIF source.
- * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
- */
- ice->gpio.saved[0] = 0;
-
- /* initialize WM8776 codec */
- for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
- wm_put(ice, wm_inits[i], wm_inits[i+1]);
- schedule_timeout_uninterruptible(1);
- for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)
- wm_put(ice, wm_inits2[i], wm_inits2[i+1]);
-
- /* initialize CS8416 codec */
- /* assert PRST#; MT05 bit 7 */
- outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
- mdelay(5);
- /* deassert PRST# */
- outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));
-
- for (i = 0; i < ARRAY_SIZE(cs_inits); i += 2)
- spi_write(ice, CS_DEV, cs_inits[i], cs_inits[i+1]);
-
- return 0;
-}
-
-
-/*
- * Pontis boards don't provide the EEPROM data at all.
- * hence the driver needs to sets up it properly.
- */
-
-static unsigned char pontis_eeprom[] __devinitdata = {
- [ICE_EEP2_SYSCONF] = 0x08, /* clock 256, mpu401, spdif-in/ADC, 1DAC */
- [ICE_EEP2_ACLINK] = 0x80, /* I2S */
- [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */
- [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
- [ICE_EEP2_GPIO_DIR] = 0x07,
- [ICE_EEP2_GPIO_DIR1] = 0x00,
- [ICE_EEP2_GPIO_DIR2] = 0x00, /* ignored */
- [ICE_EEP2_GPIO_MASK] = 0x0f, /* 4-7 reserved for CS8416 */
- [ICE_EEP2_GPIO_MASK1] = 0xff,
- [ICE_EEP2_GPIO_MASK2] = 0x00, /* ignored */
- [ICE_EEP2_GPIO_STATE] = 0x06, /* 0-low, 1-high, 2-high */
- [ICE_EEP2_GPIO_STATE1] = 0x00,
- [ICE_EEP2_GPIO_STATE2] = 0x00, /* ignored */
-};
-
-/* entry point */
-struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = {
- {
- .subvendor = VT1720_SUBDEVICE_PONTIS_MS300,
- .name = "Pontis MS300",
- .model = "ms300",
- .chip_init = pontis_init,
- .build_controls = pontis_add_controls,
- .eeprom_size = sizeof(pontis_eeprom),
- .eeprom_data = pontis_eeprom,
- },
- { } /* terminator */
-};
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/pontis.h b/ANDROID_3.4.5/sound/pci/ice1712/pontis.h
deleted file mode 100644
index d0d1378b..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/pontis.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef __SOUND_PONTIS_H
-#define __SOUND_PONTIS_H
-
-/*
- * ALSA driver for VIA VT1724 (Envy24HT)
- *
- * Lowlevel functions for Pontis MS300 boards
- *
- * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define PONTIS_DEVICE_DESC "{Pontis,MS300},"
-
-#define VT1720_SUBDEVICE_PONTIS_MS300 0x00020002 /* a dummy id for MS300 */
-
-extern struct snd_ice1712_card_info snd_vt1720_pontis_cards[];
-
-#endif /* __SOUND_PONTIS_H */
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/prodigy192.c b/ANDROID_3.4.5/sound/pci/ice1712/prodigy192.c
deleted file mode 100644
index e36ddb94..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/prodigy192.c
+++ /dev/null
@@ -1,822 +0,0 @@
-/*
- * ALSA driver for ICEnsemble VT1724 (Envy24HT)
- *
- * Lowlevel functions for AudioTrak Prodigy 192 cards
- * Supported IEC958 input from optional MI/ODI/O add-on card.
- *
- * Specifics (SW, HW):
- * -------------------
- * * 49.5MHz crystal
- * * SPDIF-OUT on the card:
- * - coax (through isolation transformer)/toslink supplied by
- * 74HC04 gates - 3 in parallel
- * - output switched between on-board CD drive dig-out connector
- * and ice1724 SPDTX pin, using 74HC02 NOR gates, controlled
- * by GPIO20 (0 = CD dig-out, 1 = SPDTX)
- * * SPDTX goes straight to MI/ODI/O card's SPDIF-OUT coax
- *
- * * MI/ODI/O card: AK4114 based, used for iec958 input only
- * - toslink input -> RX0
- * - coax input -> RX1
- * - 4wire protocol:
- * AK4114 ICE1724
- * ------------------------------
- * CDTO (pin 32) -- GPIO11 pin 86
- * CDTI (pin 33) -- GPIO10 pin 77
- * CCLK (pin 34) -- GPIO9 pin 76
- * CSN (pin 35) -- GPIO8 pin 75
- * - output data Mode 7 (24bit, I2S, slave)
- * - both MCKO1 and MCKO2 of ak4114 are fed to FPGA, which
- * outputs master clock to SPMCLKIN of ice1724.
- * Experimentally I found out that only a combination of
- * OCKS0=1, OCKS1=1 (128fs, 64fs output) and ice1724 -
- * VT1724_MT_I2S_MCLK_128X=0 (256fs input) yields correct
- * sampling rate. That means the the FPGA doubles the
- * MCK01 rate.
- *
- * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
- * Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
- * Copyright (c) 2004 Kouichi ONO <co2b@ceres.dti.ne.jp>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-
-#include "ice1712.h"
-#include "envy24ht.h"
-#include "prodigy192.h"
-#include "stac946x.h"
-#include <sound/tlv.h>
-
-struct prodigy192_spec {
- struct ak4114 *ak4114;
- /* rate change needs atomic mute/unmute of all dacs*/
- struct mutex mute_mutex;
-};
-
-static inline void stac9460_put(struct snd_ice1712 *ice, int reg, unsigned char val)
-{
- snd_vt1724_write_i2c(ice, PRODIGY192_STAC9460_ADDR, reg, val);
-}
-
-static inline unsigned char stac9460_get(struct snd_ice1712 *ice, int reg)
-{
- return snd_vt1724_read_i2c(ice, PRODIGY192_STAC9460_ADDR, reg);
-}
-
-/*
- * DAC mute control
- */
-
-/*
- * idx = STAC9460 volume register number, mute: 0 = mute, 1 = unmute
- */
-static int stac9460_dac_mute(struct snd_ice1712 *ice, int idx,
- unsigned char mute)
-{
- unsigned char new, old;
- int change;
- old = stac9460_get(ice, idx);
- new = (~mute << 7 & 0x80) | (old & ~0x80);
- change = (new != old);
- if (change)
- /*printk ("Volume register 0x%02x: 0x%02x\n", idx, new);*/
- stac9460_put(ice, idx, new);
- return change;
-}
-
-#define stac9460_dac_mute_info snd_ctl_boolean_mono_info
-
-static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char val;
- int idx;
-
- if (kcontrol->private_value)
- idx = STAC946X_MASTER_VOLUME;
- else
- idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
- val = stac9460_get(ice, idx);
- ucontrol->value.integer.value[0] = (~val >> 7) & 0x1;
- return 0;
-}
-
-static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct prodigy192_spec *spec = ice->spec;
- int idx, change;
-
- if (kcontrol->private_value)
- idx = STAC946X_MASTER_VOLUME;
- else
- idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
- /* due to possible conflicts with stac9460_set_rate_val, mutexing */
- mutex_lock(&spec->mute_mutex);
- /*
- printk(KERN_DEBUG "Mute put: reg 0x%02x, ctrl value: 0x%02x\n", idx,
- ucontrol->value.integer.value[0]);
- */
- change = stac9460_dac_mute(ice, idx, ucontrol->value.integer.value[0]);
- mutex_unlock(&spec->mute_mutex);
- return change;
-}
-
-/*
- * DAC volume attenuation mixer control
- */
-static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0; /* mute */
- uinfo->value.integer.max = 0x7f; /* 0dB */
- return 0;
-}
-
-static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int idx;
- unsigned char vol;
-
- if (kcontrol->private_value)
- idx = STAC946X_MASTER_VOLUME;
- else
- idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
- vol = stac9460_get(ice, idx) & 0x7f;
- ucontrol->value.integer.value[0] = 0x7f - vol;
-
- return 0;
-}
-
-static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int idx;
- unsigned char tmp, ovol, nvol;
- int change;
-
- if (kcontrol->private_value)
- idx = STAC946X_MASTER_VOLUME;
- else
- idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
- nvol = ucontrol->value.integer.value[0];
- tmp = stac9460_get(ice, idx);
- ovol = 0x7f - (tmp & 0x7f);
- change = (ovol != nvol);
- if (change) {
- ovol = (0x7f - nvol) | (tmp & 0x80);
- /*
- printk(KERN_DEBUG "DAC Volume: reg 0x%02x: 0x%02x\n",
- idx, ovol);
- */
- stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
- }
- return change;
-}
-
-/*
- * ADC mute control
- */
-#define stac9460_adc_mute_info snd_ctl_boolean_stereo_info
-
-static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char val;
- int i;
-
- for (i = 0; i < 2; ++i) {
- val = stac9460_get(ice, STAC946X_MIC_L_VOLUME + i);
- ucontrol->value.integer.value[i] = ~val>>7 & 0x1;
- }
-
- return 0;
-}
-
-static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char new, old;
- int i, reg;
- int change;
-
- for (i = 0; i < 2; ++i) {
- reg = STAC946X_MIC_L_VOLUME + i;
- old = stac9460_get(ice, reg);
- new = (~ucontrol->value.integer.value[i]<<7&0x80) | (old&~0x80);
- change = (new != old);
- if (change)
- stac9460_put(ice, reg, new);
- }
-
- return change;
-}
-
-/*
- * ADC gain mixer control
- */
-static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0; /* 0dB */
- uinfo->value.integer.max = 0x0f; /* 22.5dB */
- return 0;
-}
-
-static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int i, reg;
- unsigned char vol;
-
- for (i = 0; i < 2; ++i) {
- reg = STAC946X_MIC_L_VOLUME + i;
- vol = stac9460_get(ice, reg) & 0x0f;
- ucontrol->value.integer.value[i] = 0x0f - vol;
- }
-
- return 0;
-}
-
-static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int i, reg;
- unsigned char ovol, nvol;
- int change;
-
- for (i = 0; i < 2; ++i) {
- reg = STAC946X_MIC_L_VOLUME + i;
- nvol = ucontrol->value.integer.value[i] & 0x0f;
- ovol = 0x0f - stac9460_get(ice, reg);
- change = ((ovol & 0x0f) != nvol);
- if (change)
- stac9460_put(ice, reg, (0x0f - nvol) | (ovol & ~0x0f));
- }
-
- return change;
-}
-
-static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[2] = { "Line In", "Mic" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-
-static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char val;
-
- val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
- ucontrol->value.enumerated.item[0] = (val >> 7) & 0x1;
- return 0;
-}
-
-static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char new, old;
- int change;
- old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
- new = (ucontrol->value.enumerated.item[0] << 7 & 0x80) | (old & ~0x80);
- change = (new != old);
- if (change)
- stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new);
- return change;
-}
-/*
- * Handler for setting correct codec rate - called when rate change is detected
- */
-static void stac9460_set_rate_val(struct snd_ice1712 *ice, unsigned int rate)
-{
- unsigned char old, new;
- int idx;
- unsigned char changed[7];
- struct prodigy192_spec *spec = ice->spec;
-
- if (rate == 0) /* no hint - S/PDIF input is master, simply return */
- return;
- else if (rate <= 48000)
- new = 0x08; /* 256x, base rate mode */
- else if (rate <= 96000)
- new = 0x11; /* 256x, mid rate mode */
- else
- new = 0x12; /* 128x, high rate mode */
- old = stac9460_get(ice, STAC946X_MASTER_CLOCKING);
- if (old == new)
- return;
- /* change detected, setting master clock, muting first */
- /* due to possible conflicts with mute controls - mutexing */
- mutex_lock(&spec->mute_mutex);
- /* we have to remember current mute status for each DAC */
- for (idx = 0; idx < 7 ; ++idx)
- changed[idx] = stac9460_dac_mute(ice,
- STAC946X_MASTER_VOLUME + idx, 0);
- /*printk(KERN_DEBUG "Rate change: %d, new MC: 0x%02x\n", rate, new);*/
- stac9460_put(ice, STAC946X_MASTER_CLOCKING, new);
- udelay(10);
- /* unmuting - only originally unmuted dacs -
- * i.e. those changed when muting */
- for (idx = 0; idx < 7 ; ++idx) {
- if (changed[idx])
- stac9460_dac_mute(ice, STAC946X_MASTER_VOLUME + idx, 1);
- }
- mutex_unlock(&spec->mute_mutex);
-}
-
-
-static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0);
-
-/*
- * mixers
- */
-
-static struct snd_kcontrol_new stac_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = stac9460_dac_mute_info,
- .get = stac9460_dac_mute_get,
- .put = stac9460_dac_mute_put,
- .private_value = 1,
- .tlv = { .p = db_scale_dac }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Master Playback Volume",
- .info = stac9460_dac_vol_info,
- .get = stac9460_dac_vol_get,
- .put = stac9460_dac_vol_put,
- .private_value = 1,
- .tlv = { .p = db_scale_dac }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "DAC Switch",
- .count = 6,
- .info = stac9460_dac_mute_info,
- .get = stac9460_dac_mute_get,
- .put = stac9460_dac_mute_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "DAC Volume",
- .count = 6,
- .info = stac9460_dac_vol_info,
- .get = stac9460_dac_vol_get,
- .put = stac9460_dac_vol_put,
- .tlv = { .p = db_scale_dac }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "ADC Capture Switch",
- .count = 1,
- .info = stac9460_adc_mute_info,
- .get = stac9460_adc_mute_get,
- .put = stac9460_adc_mute_put,
-
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "ADC Capture Volume",
- .count = 1,
- .info = stac9460_adc_vol_info,
- .get = stac9460_adc_vol_get,
- .put = stac9460_adc_vol_put,
- .tlv = { .p = db_scale_adc }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Capture Input",
- .info = stac9460_mic_sw_info,
- .get = stac9460_mic_sw_get,
- .put = stac9460_mic_sw_put,
-
- },
-};
-
-/* AK4114 - ICE1724 connections on Prodigy192 + MI/ODI/O */
-/* CDTO (pin 32) -- GPIO11 pin 86
- * CDTI (pin 33) -- GPIO10 pin 77
- * CCLK (pin 34) -- GPIO9 pin 76
- * CSN (pin 35) -- GPIO8 pin 75
- */
-#define AK4114_ADDR 0x00 /* C1-C0: Chip Address
- * (According to datasheet fixed to “00”)
- */
-
-/*
- * 4wire ak4114 protocol - writing data
- */
-static void write_data(struct snd_ice1712 *ice, unsigned int gpio,
- unsigned int data, int idx)
-{
- for (; idx >= 0; idx--) {
- /* drop clock */
- gpio &= ~VT1724_PRODIGY192_CCLK;
- snd_ice1712_gpio_write(ice, gpio);
- udelay(1);
- /* set data */
- if (data & (1 << idx))
- gpio |= VT1724_PRODIGY192_CDOUT;
- else
- gpio &= ~VT1724_PRODIGY192_CDOUT;
- snd_ice1712_gpio_write(ice, gpio);
- udelay(1);
- /* raise clock */
- gpio |= VT1724_PRODIGY192_CCLK;
- snd_ice1712_gpio_write(ice, gpio);
- udelay(1);
- }
-}
-
-/*
- * 4wire ak4114 protocol - reading data
- */
-static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio,
- int idx)
-{
- unsigned char data = 0;
-
- for (; idx >= 0; idx--) {
- /* drop clock */
- gpio &= ~VT1724_PRODIGY192_CCLK;
- snd_ice1712_gpio_write(ice, gpio);
- udelay(1);
- /* read data */
- if (snd_ice1712_gpio_read(ice) & VT1724_PRODIGY192_CDIN)
- data |= (1 << idx);
- udelay(1);
- /* raise clock */
- gpio |= VT1724_PRODIGY192_CCLK;
- snd_ice1712_gpio_write(ice, gpio);
- udelay(1);
- }
- return data;
-}
-/*
- * 4wire ak4114 protocol - starting sequence
- */
-static unsigned int prodigy192_4wire_start(struct snd_ice1712 *ice)
-{
- unsigned int tmp;
-
- snd_ice1712_save_gpio_status(ice);
- tmp = snd_ice1712_gpio_read(ice);
-
- tmp |= VT1724_PRODIGY192_CCLK; /* high at init */
- tmp &= ~VT1724_PRODIGY192_CS; /* drop chip select */
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- return tmp;
-}
-
-/*
- * 4wire ak4114 protocol - final sequence
- */
-static void prodigy192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp)
-{
- tmp |= VT1724_PRODIGY192_CS; /* raise chip select */
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- snd_ice1712_restore_gpio_status(ice);
-}
-
-/*
- * Write data to addr register of ak4114
- */
-static void prodigy192_ak4114_write(void *private_data, unsigned char addr,
- unsigned char data)
-{
- struct snd_ice1712 *ice = private_data;
- unsigned int tmp, addrdata;
- tmp = prodigy192_4wire_start(ice);
- addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f);
- addrdata = (addrdata << 8) | data;
- write_data(ice, tmp, addrdata, 15);
- prodigy192_4wire_finish(ice, tmp);
-}
-
-/*
- * Read data from addr register of ak4114
- */
-static unsigned char prodigy192_ak4114_read(void *private_data,
- unsigned char addr)
-{
- struct snd_ice1712 *ice = private_data;
- unsigned int tmp;
- unsigned char data;
-
- tmp = prodigy192_4wire_start(ice);
- write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7);
- data = read_data(ice, tmp, 7);
- prodigy192_4wire_finish(ice, tmp);
- return data;
-}
-
-
-static int ak4114_input_sw_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[2] = { "Toslink", "Coax" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-
-static int ak4114_input_sw_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char val;
-
- val = prodigy192_ak4114_read(ice, AK4114_REG_IO1);
- /* AK4114_IPS0 bit = 0 -> RX0 = Toslink
- * AK4114_IPS0 bit = 1 -> RX1 = Coax
- */
- ucontrol->value.enumerated.item[0] = (val & AK4114_IPS0) ? 1 : 0;
- return 0;
-}
-
-static int ak4114_input_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char new, old, itemvalue;
- int change;
-
- old = prodigy192_ak4114_read(ice, AK4114_REG_IO1);
- /* AK4114_IPS0 could be any bit */
- itemvalue = (ucontrol->value.enumerated.item[0]) ? 0xff : 0x00;
-
- new = (itemvalue & AK4114_IPS0) | (old & ~AK4114_IPS0);
- change = (new != old);
- if (change)
- prodigy192_ak4114_write(ice, AK4114_REG_IO1, new);
- return change;
-}
-
-
-static struct snd_kcontrol_new ak4114_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "MIODIO IEC958 Capture Input",
- .info = ak4114_input_sw_info,
- .get = ak4114_input_sw_get,
- .put = ak4114_input_sw_put,
-
- }
-};
-
-
-static int prodigy192_ak4114_init(struct snd_ice1712 *ice)
-{
- static const unsigned char ak4114_init_vals[] = {
- AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1,
- /* ice1724 expects I2S and provides clock,
- * DEM0 disables the deemphasis filter
- */
- AK4114_DIF_I24I2S | AK4114_DEM0 ,
- AK4114_TX1E,
- AK4114_EFH_1024 | AK4114_DIT, /* default input RX0 */
- 0,
- 0
- };
- static const unsigned char ak4114_init_txcsb[] = {
- 0x41, 0x02, 0x2c, 0x00, 0x00
- };
- struct prodigy192_spec *spec = ice->spec;
- int err;
-
- err = snd_ak4114_create(ice->card,
- prodigy192_ak4114_read,
- prodigy192_ak4114_write,
- ak4114_init_vals, ak4114_init_txcsb,
- ice, &spec->ak4114);
- if (err < 0)
- return err;
- /* AK4114 in Prodigy192 cannot detect external rate correctly.
- * No reason to stop capture stream due to incorrect checks */
- spec->ak4114->check_flags = AK4114_CHECK_NO_RATE;
- return 0;
-}
-
-static void stac9460_proc_regs_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_ice1712 *ice = entry->private_data;
- int reg, val;
- /* registers 0x0 - 0x14 */
- for (reg = 0; reg <= 0x15; reg++) {
- val = stac9460_get(ice, reg);
- snd_iprintf(buffer, "0x%02x = 0x%02x\n", reg, val);
- }
-}
-
-
-static void stac9460_proc_init(struct snd_ice1712 *ice)
-{
- struct snd_info_entry *entry;
- if (!snd_card_proc_new(ice->card, "stac9460_codec", &entry))
- snd_info_set_text_ops(entry, ice, stac9460_proc_regs_read);
-}
-
-
-static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice)
-{
- struct prodigy192_spec *spec = ice->spec;
- unsigned int i;
- int err;
-
- for (i = 0; i < ARRAY_SIZE(stac_controls); i++) {
- err = snd_ctl_add(ice->card,
- snd_ctl_new1(&stac_controls[i], ice));
- if (err < 0)
- return err;
- }
- if (spec->ak4114) {
- /* ak4114 is connected */
- for (i = 0; i < ARRAY_SIZE(ak4114_controls); i++) {
- err = snd_ctl_add(ice->card,
- snd_ctl_new1(&ak4114_controls[i],
- ice));
- if (err < 0)
- return err;
- }
- err = snd_ak4114_build(spec->ak4114,
- NULL, /* ak4114 in MIO/DI/O handles no IEC958 output */
- ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
- if (err < 0)
- return err;
- }
- stac9460_proc_init(ice);
- return 0;
-}
-
-/*
- * check for presence of MI/ODI/O add-on card with digital inputs
- */
-static int prodigy192_miodio_exists(struct snd_ice1712 *ice)
-{
-
- unsigned char orig_value;
- const unsigned char test_data = 0xd1; /* random value */
- unsigned char addr = AK4114_REG_INT0_MASK; /* random SAFE address */
- int exists = 0;
-
- orig_value = prodigy192_ak4114_read(ice, addr);
- prodigy192_ak4114_write(ice, addr, test_data);
- if (prodigy192_ak4114_read(ice, addr) == test_data) {
- /* ak4114 seems to communicate, apparently exists */
- /* writing back original value */
- prodigy192_ak4114_write(ice, addr, orig_value);
- exists = 1;
- }
- return exists;
-}
-
-/*
- * initialize the chip
- */
-static int __devinit prodigy192_init(struct snd_ice1712 *ice)
-{
- static const unsigned short stac_inits_prodigy[] = {
- STAC946X_RESET, 0,
- STAC946X_MASTER_CLOCKING, 0x11,
-/* STAC946X_MASTER_VOLUME, 0,
- STAC946X_LF_VOLUME, 0,
- STAC946X_RF_VOLUME, 0,
- STAC946X_LR_VOLUME, 0,
- STAC946X_RR_VOLUME, 0,
- STAC946X_CENTER_VOLUME, 0,
- STAC946X_LFE_VOLUME, 0,*/
- (unsigned short)-1
- };
- const unsigned short *p;
- int err = 0;
- struct prodigy192_spec *spec;
-
- /* prodigy 192 */
- ice->num_total_dacs = 6;
- ice->num_total_adcs = 2;
- ice->vt1720 = 0; /* ice1724, e.g. 23 GPIOs */
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- ice->spec = spec;
- mutex_init(&spec->mute_mutex);
-
- /* initialize codec */
- p = stac_inits_prodigy;
- for (; *p != (unsigned short)-1; p += 2)
- stac9460_put(ice, p[0], p[1]);
- ice->gpio.set_pro_rate = stac9460_set_rate_val;
-
- /* MI/ODI/O add on card with AK4114 */
- if (prodigy192_miodio_exists(ice)) {
- err = prodigy192_ak4114_init(ice);
- /* from this moment if err = 0 then
- * spec->ak4114 should not be null
- */
- snd_printdd("AK4114 initialized with status %d\n", err);
- } else
- snd_printdd("AK4114 not found\n");
- if (err < 0)
- return err;
-
- return 0;
-}
-
-
-/*
- * Aureon boards don't provide the EEPROM data except for the vendor IDs.
- * hence the driver needs to sets up it properly.
- */
-
-static unsigned char prodigy71_eeprom[] __devinitdata = {
- [ICE_EEP2_SYSCONF] = 0x6a, /* 49MHz crystal, mpu401,
- * spdif-in+ 1 stereo ADC,
- * 3 stereo DACs
- */
- [ICE_EEP2_ACLINK] = 0x80, /* I2S */
- [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */
- [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
- [ICE_EEP2_GPIO_DIR] = 0xff,
- [ICE_EEP2_GPIO_DIR1] = ~(VT1724_PRODIGY192_CDIN >> 8) ,
- [ICE_EEP2_GPIO_DIR2] = 0xbf,
- [ICE_EEP2_GPIO_MASK] = 0x00,
- [ICE_EEP2_GPIO_MASK1] = 0x00,
- [ICE_EEP2_GPIO_MASK2] = 0x00,
- [ICE_EEP2_GPIO_STATE] = 0x00,
- [ICE_EEP2_GPIO_STATE1] = 0x00,
- [ICE_EEP2_GPIO_STATE2] = 0x10, /* GPIO20: 0 = CD drive dig. input
- * passthrough,
- * 1 = SPDIF-OUT from ice1724
- */
-};
-
-
-/* entry point */
-struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = {
- {
- .subvendor = VT1724_SUBDEVICE_PRODIGY192VE,
- .name = "Audiotrak Prodigy 192",
- .model = "prodigy192",
- .chip_init = prodigy192_init,
- .build_controls = prodigy192_add_controls,
- .eeprom_size = sizeof(prodigy71_eeprom),
- .eeprom_data = prodigy71_eeprom,
- },
- { } /* terminator */
-};
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/prodigy192.h b/ANDROID_3.4.5/sound/pci/ice1712/prodigy192.h
deleted file mode 100644
index 16a53b45..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/prodigy192.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef __SOUND_PRODIGY192_H
-#define __SOUND_PRODIGY192_H
-
-#define PRODIGY192_DEVICE_DESC "{AudioTrak,Prodigy 192},"
-#define PRODIGY192_STAC9460_ADDR 0x54
-
-#define VT1724_SUBDEVICE_PRODIGY192VE 0x34495345 /* PRODIGY 192 VE */
-/*
- * AudioTrak Prodigy192 GPIO definitions for MI/ODI/O card with
- * AK4114 (SPDIF-IN)
- */
-#define VT1724_PRODIGY192_CS (1 << 8) /* GPIO8, pin 75 */
-#define VT1724_PRODIGY192_CCLK (1 << 9) /* GPIO9, pin 76 */
-#define VT1724_PRODIGY192_CDOUT (1 << 10) /* GPIO10, pin 77 */
-#define VT1724_PRODIGY192_CDIN (1 << 11) /* GPIO11, pin 86 */
-
-extern struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[];
-
-#endif /* __SOUND_PRODIGY192_H */
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/prodigy_hifi.c b/ANDROID_3.4.5/sound/pci/ice1712/prodigy_hifi.c
deleted file mode 100644
index 764cc93d..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/prodigy_hifi.c
+++ /dev/null
@@ -1,1236 +0,0 @@
-/*
- * ALSA driver for ICEnsemble VT1724 (Envy24HT)
- *
- * Lowlevel functions for Audiotrak Prodigy 7.1 Hifi
- * based on pontis.c
- *
- * Copyright (c) 2007 Julian Scheel <julian@jusst.de>
- * Copyright (c) 2007 allank
- * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/tlv.h>
-
-#include "ice1712.h"
-#include "envy24ht.h"
-#include "prodigy_hifi.h"
-
-struct prodigy_hifi_spec {
- unsigned short master[2];
- unsigned short vol[8];
-};
-
-/* I2C addresses */
-#define WM_DEV 0x34
-
-/* WM8776 registers */
-#define WM_HP_ATTEN_L 0x00 /* headphone left attenuation */
-#define WM_HP_ATTEN_R 0x01 /* headphone left attenuation */
-#define WM_HP_MASTER 0x02 /* headphone master (both channels),
- override LLR */
-#define WM_DAC_ATTEN_L 0x03 /* digital left attenuation */
-#define WM_DAC_ATTEN_R 0x04
-#define WM_DAC_MASTER 0x05
-#define WM_PHASE_SWAP 0x06 /* DAC phase swap */
-#define WM_DAC_CTRL1 0x07
-#define WM_DAC_MUTE 0x08
-#define WM_DAC_CTRL2 0x09
-#define WM_DAC_INT 0x0a
-#define WM_ADC_INT 0x0b
-#define WM_MASTER_CTRL 0x0c
-#define WM_POWERDOWN 0x0d
-#define WM_ADC_ATTEN_L 0x0e
-#define WM_ADC_ATTEN_R 0x0f
-#define WM_ALC_CTRL1 0x10
-#define WM_ALC_CTRL2 0x11
-#define WM_ALC_CTRL3 0x12
-#define WM_NOISE_GATE 0x13
-#define WM_LIMITER 0x14
-#define WM_ADC_MUX 0x15
-#define WM_OUT_MUX 0x16
-#define WM_RESET 0x17
-
-/* Analog Recording Source :- Mic, LineIn, CD/Video, */
-
-/* implement capture source select control for WM8776 */
-
-#define WM_AIN1 "AIN1"
-#define WM_AIN2 "AIN2"
-#define WM_AIN3 "AIN3"
-#define WM_AIN4 "AIN4"
-#define WM_AIN5 "AIN5"
-
-/* GPIO pins of envy24ht connected to wm8766 */
-#define WM8766_SPI_CLK (1<<17) /* CLK, Pin97 on ICE1724 */
-#define WM8766_SPI_MD (1<<16) /* DATA VT1724 -> WM8766, Pin96 */
-#define WM8766_SPI_ML (1<<18) /* Latch, Pin98 */
-
-/* WM8766 registers */
-#define WM8766_DAC_CTRL 0x02 /* DAC Control */
-#define WM8766_INT_CTRL 0x03 /* Interface Control */
-#define WM8766_DAC_CTRL2 0x09
-#define WM8766_DAC_CTRL3 0x0a
-#define WM8766_RESET 0x1f
-#define WM8766_LDA1 0x00
-#define WM8766_LDA2 0x04
-#define WM8766_LDA3 0x06
-#define WM8766_RDA1 0x01
-#define WM8766_RDA2 0x05
-#define WM8766_RDA3 0x07
-#define WM8766_MUTE1 0x0C
-#define WM8766_MUTE2 0x0F
-
-
-/*
- * Prodigy HD2
- */
-#define AK4396_ADDR 0x00
-#define AK4396_CSN (1 << 8) /* CSN->GPIO8, pin 75 */
-#define AK4396_CCLK (1 << 9) /* CCLK->GPIO9, pin 76 */
-#define AK4396_CDTI (1 << 10) /* CDTI->GPIO10, pin 77 */
-
-/* ak4396 registers */
-#define AK4396_CTRL1 0x00
-#define AK4396_CTRL2 0x01
-#define AK4396_CTRL3 0x02
-#define AK4396_LCH_ATT 0x03
-#define AK4396_RCH_ATT 0x04
-
-
-/*
- * get the current register value of WM codec
- */
-static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
-{
- reg <<= 1;
- return ((unsigned short)ice->akm[0].images[reg] << 8) |
- ice->akm[0].images[reg + 1];
-}
-
-/*
- * set the register value of WM codec and remember it
- */
-static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
-{
- unsigned short cval;
- cval = (reg << 9) | val;
- snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff);
-}
-
-static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
-{
- wm_put_nocache(ice, reg, val);
- reg <<= 1;
- ice->akm[0].images[reg] = val >> 8;
- ice->akm[0].images[reg + 1] = val;
-}
-
-/*
- * write data in the SPI mode
- */
-
-static void set_gpio_bit(struct snd_ice1712 *ice, unsigned int bit, int val)
-{
- unsigned int tmp = snd_ice1712_gpio_read(ice);
- if (val)
- tmp |= bit;
- else
- tmp &= ~bit;
- snd_ice1712_gpio_write(ice, tmp);
-}
-
-/*
- * SPI implementation for WM8766 codec - only writing supported, no readback
- */
-
-static void wm8766_spi_send_word(struct snd_ice1712 *ice, unsigned int data)
-{
- int i;
- for (i = 0; i < 16; i++) {
- set_gpio_bit(ice, WM8766_SPI_CLK, 0);
- udelay(1);
- set_gpio_bit(ice, WM8766_SPI_MD, data & 0x8000);
- udelay(1);
- set_gpio_bit(ice, WM8766_SPI_CLK, 1);
- udelay(1);
- data <<= 1;
- }
-}
-
-static void wm8766_spi_write(struct snd_ice1712 *ice, unsigned int reg,
- unsigned int data)
-{
- unsigned int block;
-
- snd_ice1712_gpio_set_dir(ice, WM8766_SPI_MD|
- WM8766_SPI_CLK|WM8766_SPI_ML);
- snd_ice1712_gpio_set_mask(ice, ~(WM8766_SPI_MD|
- WM8766_SPI_CLK|WM8766_SPI_ML));
- /* latch must be low when writing */
- set_gpio_bit(ice, WM8766_SPI_ML, 0);
- block = (reg << 9) | (data & 0x1ff);
- wm8766_spi_send_word(ice, block); /* REGISTER ADDRESS */
- /* release latch */
- set_gpio_bit(ice, WM8766_SPI_ML, 1);
- udelay(1);
- /* restore */
- snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
- snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
-}
-
-
-/*
- * serial interface for ak4396 - only writing supported, no readback
- */
-
-static void ak4396_send_word(struct snd_ice1712 *ice, unsigned int data)
-{
- int i;
- for (i = 0; i < 16; i++) {
- set_gpio_bit(ice, AK4396_CCLK, 0);
- udelay(1);
- set_gpio_bit(ice, AK4396_CDTI, data & 0x8000);
- udelay(1);
- set_gpio_bit(ice, AK4396_CCLK, 1);
- udelay(1);
- data <<= 1;
- }
-}
-
-static void ak4396_write(struct snd_ice1712 *ice, unsigned int reg,
- unsigned int data)
-{
- unsigned int block;
-
- snd_ice1712_gpio_set_dir(ice, AK4396_CSN|AK4396_CCLK|AK4396_CDTI);
- snd_ice1712_gpio_set_mask(ice, ~(AK4396_CSN|AK4396_CCLK|AK4396_CDTI));
- /* latch must be low when writing */
- set_gpio_bit(ice, AK4396_CSN, 0);
- block = ((AK4396_ADDR & 0x03) << 14) | (1 << 13) |
- ((reg & 0x1f) << 8) | (data & 0xff);
- ak4396_send_word(ice, block); /* REGISTER ADDRESS */
- /* release latch */
- set_gpio_bit(ice, AK4396_CSN, 1);
- udelay(1);
- /* restore */
- snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
- snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
-}
-
-
-/*
- * ak4396 mixers
- */
-
-
-
-/*
- * DAC volume attenuation mixer control (-64dB to 0dB)
- */
-
-static int ak4396_dac_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0; /* mute */
- uinfo->value.integer.max = 0xFF; /* linear */
- return 0;
-}
-
-static int ak4396_dac_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct prodigy_hifi_spec *spec = ice->spec;
- int i;
-
- for (i = 0; i < 2; i++)
- ucontrol->value.integer.value[i] = spec->vol[i];
-
- return 0;
-}
-
-static int ak4396_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct prodigy_hifi_spec *spec = ice->spec;
- int i;
- int change = 0;
-
- mutex_lock(&ice->gpio_mutex);
- for (i = 0; i < 2; i++) {
- if (ucontrol->value.integer.value[i] != spec->vol[i]) {
- spec->vol[i] = ucontrol->value.integer.value[i];
- ak4396_write(ice, AK4396_LCH_ATT + i,
- spec->vol[i] & 0xff);
- change = 1;
- }
- }
- mutex_unlock(&ice->gpio_mutex);
- return change;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
-
-static struct snd_kcontrol_new prodigy_hd2_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Front Playback Volume",
- .info = ak4396_dac_vol_info,
- .get = ak4396_dac_vol_get,
- .put = ak4396_dac_vol_put,
- .tlv = { .p = db_scale_wm_dac },
- },
-};
-
-
-/* --------------- */
-
-/*
- * Logarithmic volume values for WM87*6
- * Computed as 20 * Log10(255 / x)
- */
-static const unsigned char wm_vol[256] = {
- 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
- 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
- 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
- 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0
-};
-
-#define WM_VOL_MAX (sizeof(wm_vol) - 1)
-#define WM_VOL_MUTE 0x8000
-
-
-#define DAC_0dB 0xff
-#define DAC_RES 128
-#define DAC_MIN (DAC_0dB - DAC_RES)
-
-
-static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index,
- unsigned short vol, unsigned short master)
-{
- unsigned char nvol;
-
- if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
- nvol = 0;
- else {
- nvol = (((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 128)
- & WM_VOL_MAX;
- nvol = (nvol ? (nvol + DAC_MIN) : 0) & 0xff;
- }
-
- wm_put(ice, index, nvol);
- wm_put_nocache(ice, index, 0x100 | nvol);
-}
-
-static void wm8766_set_vol(struct snd_ice1712 *ice, unsigned int index,
- unsigned short vol, unsigned short master)
-{
- unsigned char nvol;
-
- if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
- nvol = 0;
- else {
- nvol = (((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 128)
- & WM_VOL_MAX;
- nvol = (nvol ? (nvol + DAC_MIN) : 0) & 0xff;
- }
-
- wm8766_spi_write(ice, index, (0x0100 | nvol));
-}
-
-
-/*
- * DAC volume attenuation mixer control (-64dB to 0dB)
- */
-
-static int wm_dac_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0; /* mute */
- uinfo->value.integer.max = DAC_RES; /* 0dB, 0.5dB step */
- return 0;
-}
-
-static int wm_dac_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct prodigy_hifi_spec *spec = ice->spec;
- int i;
-
- for (i = 0; i < 2; i++)
- ucontrol->value.integer.value[i] =
- spec->vol[2 + i] & ~WM_VOL_MUTE;
- return 0;
-}
-
-static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct prodigy_hifi_spec *spec = ice->spec;
- int i, idx, change = 0;
-
- mutex_lock(&ice->gpio_mutex);
- for (i = 0; i < 2; i++) {
- if (ucontrol->value.integer.value[i] != spec->vol[2 + i]) {
- idx = WM_DAC_ATTEN_L + i;
- spec->vol[2 + i] &= WM_VOL_MUTE;
- spec->vol[2 + i] |= ucontrol->value.integer.value[i];
- wm_set_vol(ice, idx, spec->vol[2 + i], spec->master[i]);
- change = 1;
- }
- }
- mutex_unlock(&ice->gpio_mutex);
- return change;
-}
-
-
-/*
- * WM8766 DAC volume attenuation mixer control
- */
-static int wm8766_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int voices = kcontrol->private_value >> 8;
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = voices;
- uinfo->value.integer.min = 0; /* mute */
- uinfo->value.integer.max = DAC_RES; /* 0dB */
- return 0;
-}
-
-static int wm8766_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct prodigy_hifi_spec *spec = ice->spec;
- int i, ofs, voices;
-
- voices = kcontrol->private_value >> 8;
- ofs = kcontrol->private_value & 0xff;
- for (i = 0; i < voices; i++)
- ucontrol->value.integer.value[i] = spec->vol[ofs + i];
- return 0;
-}
-
-static int wm8766_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct prodigy_hifi_spec *spec = ice->spec;
- int i, idx, ofs, voices;
- int change = 0;
-
- voices = kcontrol->private_value >> 8;
- ofs = kcontrol->private_value & 0xff;
- mutex_lock(&ice->gpio_mutex);
- for (i = 0; i < voices; i++) {
- if (ucontrol->value.integer.value[i] != spec->vol[ofs + i]) {
- idx = WM8766_LDA1 + ofs + i;
- spec->vol[ofs + i] &= WM_VOL_MUTE;
- spec->vol[ofs + i] |= ucontrol->value.integer.value[i];
- wm8766_set_vol(ice, idx,
- spec->vol[ofs + i], spec->master[i]);
- change = 1;
- }
- }
- mutex_unlock(&ice->gpio_mutex);
- return change;
-}
-
-/*
- * Master volume attenuation mixer control / applied to WM8776+WM8766
- */
-static int wm_master_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = DAC_RES;
- return 0;
-}
-
-static int wm_master_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct prodigy_hifi_spec *spec = ice->spec;
- int i;
- for (i = 0; i < 2; i++)
- ucontrol->value.integer.value[i] = spec->master[i];
- return 0;
-}
-
-static int wm_master_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- struct prodigy_hifi_spec *spec = ice->spec;
- int ch, change = 0;
-
- mutex_lock(&ice->gpio_mutex);
- for (ch = 0; ch < 2; ch++) {
- if (ucontrol->value.integer.value[ch] != spec->master[ch]) {
- spec->master[ch] = ucontrol->value.integer.value[ch];
-
- /* Apply to front DAC */
- wm_set_vol(ice, WM_DAC_ATTEN_L + ch,
- spec->vol[2 + ch], spec->master[ch]);
-
- wm8766_set_vol(ice, WM8766_LDA1 + ch,
- spec->vol[0 + ch], spec->master[ch]);
-
- wm8766_set_vol(ice, WM8766_LDA2 + ch,
- spec->vol[4 + ch], spec->master[ch]);
-
- wm8766_set_vol(ice, WM8766_LDA3 + ch,
- spec->vol[6 + ch], spec->master[ch]);
- change = 1;
- }
- }
- mutex_unlock(&ice->gpio_mutex);
- return change;
-}
-
-
-/* KONSTI */
-
-static int wm_adc_mux_enum_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char* texts[32] = {
- "NULL", WM_AIN1, WM_AIN2, WM_AIN1 "+" WM_AIN2,
- WM_AIN3, WM_AIN1 "+" WM_AIN3, WM_AIN2 "+" WM_AIN3,
- WM_AIN1 "+" WM_AIN2 "+" WM_AIN3,
- WM_AIN4, WM_AIN1 "+" WM_AIN4, WM_AIN2 "+" WM_AIN4,
- WM_AIN1 "+" WM_AIN2 "+" WM_AIN4,
- WM_AIN3 "+" WM_AIN4, WM_AIN1 "+" WM_AIN3 "+" WM_AIN4,
- WM_AIN2 "+" WM_AIN3 "+" WM_AIN4,
- WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4,
- WM_AIN5, WM_AIN1 "+" WM_AIN5, WM_AIN2 "+" WM_AIN5,
- WM_AIN1 "+" WM_AIN2 "+" WM_AIN5,
- WM_AIN3 "+" WM_AIN5, WM_AIN1 "+" WM_AIN3 "+" WM_AIN5,
- WM_AIN2 "+" WM_AIN3 "+" WM_AIN5,
- WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN5,
- WM_AIN4 "+" WM_AIN5, WM_AIN1 "+" WM_AIN4 "+" WM_AIN5,
- WM_AIN2 "+" WM_AIN4 "+" WM_AIN5,
- WM_AIN1 "+" WM_AIN2 "+" WM_AIN4 "+" WM_AIN5,
- WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
- WM_AIN1 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
- WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
- WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 32;
- if (uinfo->value.enumerated.item > 31)
- uinfo->value.enumerated.item = 31;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int wm_adc_mux_enum_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&ice->gpio_mutex);
- ucontrol->value.integer.value[0] = wm_get(ice, WM_ADC_MUX) & 0x1f;
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int wm_adc_mux_enum_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short oval, nval;
- int change = 0;
-
- mutex_lock(&ice->gpio_mutex);
- oval = wm_get(ice, WM_ADC_MUX);
- nval = (oval & 0xe0) | ucontrol->value.integer.value[0];
- if (nval != oval) {
- wm_put(ice, WM_ADC_MUX, nval);
- change = 1;
- }
- mutex_unlock(&ice->gpio_mutex);
- return change;
-}
-
-/* KONSTI */
-
-/*
- * ADC gain mixer control (-64dB to 0dB)
- */
-
-#define ADC_0dB 0xcf
-#define ADC_RES 128
-#define ADC_MIN (ADC_0dB - ADC_RES)
-
-static int wm_adc_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0; /* mute (-64dB) */
- uinfo->value.integer.max = ADC_RES; /* 0dB, 0.5dB step */
- return 0;
-}
-
-static int wm_adc_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short val;
- int i;
-
- mutex_lock(&ice->gpio_mutex);
- for (i = 0; i < 2; i++) {
- val = wm_get(ice, WM_ADC_ATTEN_L + i) & 0xff;
- val = val > ADC_MIN ? (val - ADC_MIN) : 0;
- ucontrol->value.integer.value[i] = val;
- }
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int wm_adc_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short ovol, nvol;
- int i, idx, change = 0;
-
- mutex_lock(&ice->gpio_mutex);
- for (i = 0; i < 2; i++) {
- nvol = ucontrol->value.integer.value[i];
- nvol = nvol ? (nvol + ADC_MIN) : 0;
- idx = WM_ADC_ATTEN_L + i;
- ovol = wm_get(ice, idx) & 0xff;
- if (ovol != nvol) {
- wm_put(ice, idx, nvol);
- change = 1;
- }
- }
- mutex_unlock(&ice->gpio_mutex);
- return change;
-}
-
-/*
- * ADC input mux mixer control
- */
-#define wm_adc_mux_info snd_ctl_boolean_mono_info
-
-static int wm_adc_mux_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int bit = kcontrol->private_value;
-
- mutex_lock(&ice->gpio_mutex);
- ucontrol->value.integer.value[0] =
- (wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0;
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int wm_adc_mux_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int bit = kcontrol->private_value;
- unsigned short oval, nval;
- int change;
-
- mutex_lock(&ice->gpio_mutex);
- nval = oval = wm_get(ice, WM_ADC_MUX);
- if (ucontrol->value.integer.value[0])
- nval |= (1 << bit);
- else
- nval &= ~(1 << bit);
- change = nval != oval;
- if (change) {
- wm_put(ice, WM_ADC_MUX, nval);
- }
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-/*
- * Analog bypass (In -> Out)
- */
-#define wm_bypass_info snd_ctl_boolean_mono_info
-
-static int wm_bypass_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&ice->gpio_mutex);
- ucontrol->value.integer.value[0] =
- (wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0;
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int wm_bypass_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short val, oval;
- int change = 0;
-
- mutex_lock(&ice->gpio_mutex);
- val = oval = wm_get(ice, WM_OUT_MUX);
- if (ucontrol->value.integer.value[0])
- val |= 0x04;
- else
- val &= ~0x04;
- if (val != oval) {
- wm_put(ice, WM_OUT_MUX, val);
- change = 1;
- }
- mutex_unlock(&ice->gpio_mutex);
- return change;
-}
-
-/*
- * Left/Right swap
- */
-#define wm_chswap_info snd_ctl_boolean_mono_info
-
-static int wm_chswap_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&ice->gpio_mutex);
- ucontrol->value.integer.value[0] =
- (wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90;
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-
-static int wm_chswap_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned short val, oval;
- int change = 0;
-
- mutex_lock(&ice->gpio_mutex);
- oval = wm_get(ice, WM_DAC_CTRL1);
- val = oval & 0x0f;
- if (ucontrol->value.integer.value[0])
- val |= 0x60;
- else
- val |= 0x90;
- if (val != oval) {
- wm_put(ice, WM_DAC_CTRL1, val);
- wm_put_nocache(ice, WM_DAC_CTRL1, val);
- change = 1;
- }
- mutex_unlock(&ice->gpio_mutex);
- return change;
-}
-
-
-/*
- * mixers
- */
-
-static struct snd_kcontrol_new prodigy_hifi_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Master Playback Volume",
- .info = wm_master_vol_info,
- .get = wm_master_vol_get,
- .put = wm_master_vol_put,
- .tlv = { .p = db_scale_wm_dac }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Front Playback Volume",
- .info = wm_dac_vol_info,
- .get = wm_dac_vol_get,
- .put = wm_dac_vol_put,
- .tlv = { .p = db_scale_wm_dac },
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Rear Playback Volume",
- .info = wm8766_vol_info,
- .get = wm8766_vol_get,
- .put = wm8766_vol_put,
- .private_value = (2 << 8) | 0,
- .tlv = { .p = db_scale_wm_dac },
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Center Playback Volume",
- .info = wm8766_vol_info,
- .get = wm8766_vol_get,
- .put = wm8766_vol_put,
- .private_value = (1 << 8) | 4,
- .tlv = { .p = db_scale_wm_dac }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "LFE Playback Volume",
- .info = wm8766_vol_info,
- .get = wm8766_vol_get,
- .put = wm8766_vol_put,
- .private_value = (1 << 8) | 5,
- .tlv = { .p = db_scale_wm_dac }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Side Playback Volume",
- .info = wm8766_vol_info,
- .get = wm8766_vol_get,
- .put = wm8766_vol_put,
- .private_value = (2 << 8) | 6,
- .tlv = { .p = db_scale_wm_dac },
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Capture Volume",
- .info = wm_adc_vol_info,
- .get = wm_adc_vol_get,
- .put = wm_adc_vol_put,
- .tlv = { .p = db_scale_wm_dac },
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "CD Capture Switch",
- .info = wm_adc_mux_info,
- .get = wm_adc_mux_get,
- .put = wm_adc_mux_put,
- .private_value = 0,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Line Capture Switch",
- .info = wm_adc_mux_info,
- .get = wm_adc_mux_get,
- .put = wm_adc_mux_put,
- .private_value = 1,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Bypass Switch",
- .info = wm_bypass_info,
- .get = wm_bypass_get,
- .put = wm_bypass_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Swap Output Channels",
- .info = wm_chswap_info,
- .get = wm_chswap_get,
- .put = wm_chswap_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Capture Source",
- .info = wm_adc_mux_enum_info,
- .get = wm_adc_mux_enum_get,
- .put = wm_adc_mux_enum_put,
- },
-};
-
-/*
- * WM codec registers
- */
-static void wm_proc_regs_write(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_ice1712 *ice = entry->private_data;
- char line[64];
- unsigned int reg, val;
- mutex_lock(&ice->gpio_mutex);
- while (!snd_info_get_line(buffer, line, sizeof(line))) {
- if (sscanf(line, "%x %x", &reg, &val) != 2)
- continue;
- if (reg <= 0x17 && val <= 0xffff)
- wm_put(ice, reg, val);
- }
- mutex_unlock(&ice->gpio_mutex);
-}
-
-static void wm_proc_regs_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_ice1712 *ice = entry->private_data;
- int reg, val;
-
- mutex_lock(&ice->gpio_mutex);
- for (reg = 0; reg <= 0x17; reg++) {
- val = wm_get(ice, reg);
- snd_iprintf(buffer, "%02x = %04x\n", reg, val);
- }
- mutex_unlock(&ice->gpio_mutex);
-}
-
-static void wm_proc_init(struct snd_ice1712 *ice)
-{
- struct snd_info_entry *entry;
- if (!snd_card_proc_new(ice->card, "wm_codec", &entry)) {
- snd_info_set_text_ops(entry, ice, wm_proc_regs_read);
- entry->mode |= S_IWUSR;
- entry->c.text.write = wm_proc_regs_write;
- }
-}
-
-static int __devinit prodigy_hifi_add_controls(struct snd_ice1712 *ice)
-{
- unsigned int i;
- int err;
-
- for (i = 0; i < ARRAY_SIZE(prodigy_hifi_controls); i++) {
- err = snd_ctl_add(ice->card,
- snd_ctl_new1(&prodigy_hifi_controls[i], ice));
- if (err < 0)
- return err;
- }
-
- wm_proc_init(ice);
-
- return 0;
-}
-
-static int __devinit prodigy_hd2_add_controls(struct snd_ice1712 *ice)
-{
- unsigned int i;
- int err;
-
- for (i = 0; i < ARRAY_SIZE(prodigy_hd2_controls); i++) {
- err = snd_ctl_add(ice->card,
- snd_ctl_new1(&prodigy_hd2_controls[i], ice));
- if (err < 0)
- return err;
- }
-
- wm_proc_init(ice);
-
- return 0;
-}
-
-
-/*
- * initialize the chip
- */
-static int __devinit prodigy_hifi_init(struct snd_ice1712 *ice)
-{
- static unsigned short wm_inits[] = {
- /* These come first to reduce init pop noise */
- WM_ADC_MUX, 0x0003, /* ADC mute */
- /* 0x00c0 replaced by 0x0003 */
-
- WM_DAC_MUTE, 0x0001, /* DAC softmute */
- WM_DAC_CTRL1, 0x0000, /* DAC mute */
-
- WM_POWERDOWN, 0x0008, /* All power-up except HP */
- WM_RESET, 0x0000, /* reset */
- };
- static unsigned short wm_inits2[] = {
- WM_MASTER_CTRL, 0x0022, /* 256fs, slave mode */
- WM_DAC_INT, 0x0022, /* I2S, normal polarity, 24bit */
- WM_ADC_INT, 0x0022, /* I2S, normal polarity, 24bit */
- WM_DAC_CTRL1, 0x0090, /* DAC L/R */
- WM_OUT_MUX, 0x0001, /* OUT DAC */
- WM_HP_ATTEN_L, 0x0179, /* HP 0dB */
- WM_HP_ATTEN_R, 0x0179, /* HP 0dB */
- WM_DAC_ATTEN_L, 0x0000, /* DAC 0dB */
- WM_DAC_ATTEN_L, 0x0100, /* DAC 0dB */
- WM_DAC_ATTEN_R, 0x0000, /* DAC 0dB */
- WM_DAC_ATTEN_R, 0x0100, /* DAC 0dB */
- WM_PHASE_SWAP, 0x0000, /* phase normal */
-#if 0
- WM_DAC_MASTER, 0x0100, /* DAC master muted */
-#endif
- WM_DAC_CTRL2, 0x0000, /* no deemphasis, no ZFLG */
- WM_ADC_ATTEN_L, 0x0000, /* ADC muted */
- WM_ADC_ATTEN_R, 0x0000, /* ADC muted */
-#if 1
- WM_ALC_CTRL1, 0x007b, /* */
- WM_ALC_CTRL2, 0x0000, /* */
- WM_ALC_CTRL3, 0x0000, /* */
- WM_NOISE_GATE, 0x0000, /* */
-#endif
- WM_DAC_MUTE, 0x0000, /* DAC unmute */
- WM_ADC_MUX, 0x0003, /* ADC unmute, both CD/Line On */
- };
- static unsigned short wm8766_inits[] = {
- WM8766_RESET, 0x0000,
- WM8766_DAC_CTRL, 0x0120,
- WM8766_INT_CTRL, 0x0022, /* I2S Normal Mode, 24 bit */
- WM8766_DAC_CTRL2, 0x0001,
- WM8766_DAC_CTRL3, 0x0080,
- WM8766_LDA1, 0x0100,
- WM8766_LDA2, 0x0100,
- WM8766_LDA3, 0x0100,
- WM8766_RDA1, 0x0100,
- WM8766_RDA2, 0x0100,
- WM8766_RDA3, 0x0100,
- WM8766_MUTE1, 0x0000,
- WM8766_MUTE2, 0x0000,
- };
-
- struct prodigy_hifi_spec *spec;
- unsigned int i;
-
- ice->vt1720 = 0;
- ice->vt1724 = 1;
-
- ice->num_total_dacs = 8;
- ice->num_total_adcs = 1;
-
- /* HACK - use this as the SPDIF source.
- * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
- */
- ice->gpio.saved[0] = 0;
- /* to remember the register values */
-
- ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
- if (! ice->akm)
- return -ENOMEM;
- ice->akm_codecs = 1;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- ice->spec = spec;
-
- /* initialize WM8776 codec */
- for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
- wm_put(ice, wm_inits[i], wm_inits[i+1]);
- schedule_timeout_uninterruptible(1);
- for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)
- wm_put(ice, wm_inits2[i], wm_inits2[i+1]);
-
- /* initialize WM8766 codec */
- for (i = 0; i < ARRAY_SIZE(wm8766_inits); i += 2)
- wm8766_spi_write(ice, wm8766_inits[i], wm8766_inits[i+1]);
-
-
- return 0;
-}
-
-
-/*
- * initialize the chip
- */
-static void ak4396_init(struct snd_ice1712 *ice)
-{
- static unsigned short ak4396_inits[] = {
- AK4396_CTRL1, 0x87, /* I2S Normal Mode, 24 bit */
- AK4396_CTRL2, 0x02,
- AK4396_CTRL3, 0x00,
- AK4396_LCH_ATT, 0x00,
- AK4396_RCH_ATT, 0x00,
- };
-
- unsigned int i;
-
- /* initialize ak4396 codec */
- /* reset codec */
- ak4396_write(ice, AK4396_CTRL1, 0x86);
- msleep(100);
- ak4396_write(ice, AK4396_CTRL1, 0x87);
-
- for (i = 0; i < ARRAY_SIZE(ak4396_inits); i += 2)
- ak4396_write(ice, ak4396_inits[i], ak4396_inits[i+1]);
-}
-
-#ifdef CONFIG_PM
-static int prodigy_hd2_resume(struct snd_ice1712 *ice)
-{
- /* initialize ak4396 codec and restore previous mixer volumes */
- struct prodigy_hifi_spec *spec = ice->spec;
- int i;
- mutex_lock(&ice->gpio_mutex);
- ak4396_init(ice);
- for (i = 0; i < 2; i++)
- ak4396_write(ice, AK4396_LCH_ATT + i, spec->vol[i] & 0xff);
- mutex_unlock(&ice->gpio_mutex);
- return 0;
-}
-#endif
-
-static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice)
-{
- struct prodigy_hifi_spec *spec;
-
- ice->vt1720 = 0;
- ice->vt1724 = 1;
-
- ice->num_total_dacs = 1;
- ice->num_total_adcs = 1;
-
- /* HACK - use this as the SPDIF source.
- * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
- */
- ice->gpio.saved[0] = 0;
- /* to remember the register values */
-
- ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
- if (! ice->akm)
- return -ENOMEM;
- ice->akm_codecs = 1;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- ice->spec = spec;
-
-#ifdef CONFIG_PM
- ice->pm_resume = &prodigy_hd2_resume;
- ice->pm_suspend_enabled = 1;
-#endif
-
- ak4396_init(ice);
-
- return 0;
-}
-
-
-static unsigned char prodigy71hifi_eeprom[] __devinitdata = {
- 0x4b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
- 0x80, /* ACLINK: I2S */
- 0xfc, /* I2S: vol, 96k, 24bit, 192k */
- 0xc3, /* SPDIF: out-en, out-int, spdif-in */
- 0xff, /* GPIO_DIR */
- 0xff, /* GPIO_DIR1 */
- 0x5f, /* GPIO_DIR2 */
- 0x00, /* GPIO_MASK */
- 0x00, /* GPIO_MASK1 */
- 0x00, /* GPIO_MASK2 */
- 0x00, /* GPIO_STATE */
- 0x00, /* GPIO_STATE1 */
- 0x00, /* GPIO_STATE2 */
-};
-
-static unsigned char prodigyhd2_eeprom[] __devinitdata = {
- 0x4b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
- 0x80, /* ACLINK: I2S */
- 0xfc, /* I2S: vol, 96k, 24bit, 192k */
- 0xc3, /* SPDIF: out-en, out-int, spdif-in */
- 0xff, /* GPIO_DIR */
- 0xff, /* GPIO_DIR1 */
- 0x5f, /* GPIO_DIR2 */
- 0x00, /* GPIO_MASK */
- 0x00, /* GPIO_MASK1 */
- 0x00, /* GPIO_MASK2 */
- 0x00, /* GPIO_STATE */
- 0x00, /* GPIO_STATE1 */
- 0x00, /* GPIO_STATE2 */
-};
-
-static unsigned char fortissimo4_eeprom[] __devinitdata = {
- 0x43, /* SYSCONF: clock 512, ADC, 4DACs */
- 0x80, /* ACLINK: I2S */
- 0xfc, /* I2S: vol, 96k, 24bit, 192k */
- 0xc1, /* SPDIF: out-en, out-int */
- 0xff, /* GPIO_DIR */
- 0xff, /* GPIO_DIR1 */
- 0x5f, /* GPIO_DIR2 */
- 0x00, /* GPIO_MASK */
- 0x00, /* GPIO_MASK1 */
- 0x00, /* GPIO_MASK2 */
- 0x00, /* GPIO_STATE */
- 0x00, /* GPIO_STATE1 */
- 0x00, /* GPIO_STATE2 */
-};
-
-/* entry point */
-struct snd_ice1712_card_info snd_vt1724_prodigy_hifi_cards[] __devinitdata = {
- {
- .subvendor = VT1724_SUBDEVICE_PRODIGY_HIFI,
- .name = "Audiotrak Prodigy 7.1 HiFi",
- .model = "prodigy71hifi",
- .chip_init = prodigy_hifi_init,
- .build_controls = prodigy_hifi_add_controls,
- .eeprom_size = sizeof(prodigy71hifi_eeprom),
- .eeprom_data = prodigy71hifi_eeprom,
- .driver = "Prodigy71HIFI",
- },
- {
- .subvendor = VT1724_SUBDEVICE_PRODIGY_HD2,
- .name = "Audiotrak Prodigy HD2",
- .model = "prodigyhd2",
- .chip_init = prodigy_hd2_init,
- .build_controls = prodigy_hd2_add_controls,
- .eeprom_size = sizeof(prodigyhd2_eeprom),
- .eeprom_data = prodigyhd2_eeprom,
- .driver = "Prodigy71HD2",
- },
- {
- .subvendor = VT1724_SUBDEVICE_FORTISSIMO4,
- .name = "Hercules Fortissimo IV",
- .model = "fortissimo4",
- .chip_init = prodigy_hifi_init,
- .build_controls = prodigy_hifi_add_controls,
- .eeprom_size = sizeof(fortissimo4_eeprom),
- .eeprom_data = fortissimo4_eeprom,
- .driver = "Fortissimo4",
- },
- { } /* terminator */
-};
-
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/prodigy_hifi.h b/ANDROID_3.4.5/sound/pci/ice1712/prodigy_hifi.h
deleted file mode 100644
index a4415d45..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/prodigy_hifi.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef __SOUND_PRODIGY_HIFI_H
-#define __SOUND_PRODIGY_HIFI_H
-
-/*
- * ALSA driver for VIA VT1724 (Envy24HT)
- *
- * Lowlevel functions for Audiotrak Prodigy Hifi
- *
- * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define PRODIGY_HIFI_DEVICE_DESC "{Audiotrak,Prodigy 7.1 HIFI},"\
- "{Audiotrak Prodigy HD2},"\
- "{Hercules Fortissimo IV},"
-
-#define VT1724_SUBDEVICE_PRODIGY_HIFI 0x38315441 /* PRODIGY 7.1 HIFI */
-#define VT1724_SUBDEVICE_PRODIGY_HD2 0x37315441 /* PRODIGY HD2 */
-#define VT1724_SUBDEVICE_FORTISSIMO4 0x81160100 /* Fortissimo IV */
-
-
-extern struct snd_ice1712_card_info snd_vt1724_prodigy_hifi_cards[];
-
-#endif /* __SOUND_PRODIGY_HIFI_H */
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/quartet.c b/ANDROID_3.4.5/sound/pci/ice1712/quartet.c
deleted file mode 100644
index 19486327..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/quartet.c
+++ /dev/null
@@ -1,1130 +0,0 @@
-/*
- * ALSA driver for ICEnsemble VT1724 (Envy24HT)
- *
- * Lowlevel functions for Infrasonic Quartet
- *
- * Copyright (c) 2009 Pavel Hofman <pavel.hofman@ivitera.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/tlv.h>
-#include <sound/info.h>
-
-#include "ice1712.h"
-#include "envy24ht.h"
-#include <sound/ak4113.h>
-#include "quartet.h"
-
-struct qtet_spec {
- struct ak4113 *ak4113;
- unsigned int scr; /* system control register */
- unsigned int mcr; /* monitoring control register */
- unsigned int cpld; /* cpld register */
-};
-
-struct qtet_kcontrol_private {
- unsigned int bit;
- void (*set_register)(struct snd_ice1712 *ice, unsigned int val);
- unsigned int (*get_register)(struct snd_ice1712 *ice);
- unsigned char *texts[2];
-};
-
-enum {
- IN12_SEL = 0,
- IN34_SEL,
- AIN34_SEL,
- COAX_OUT,
- IN12_MON12,
- IN12_MON34,
- IN34_MON12,
- IN34_MON34,
- OUT12_MON34,
- OUT34_MON12,
-};
-
-static char *ext_clock_names[3] = {"IEC958 In", "Word Clock 1xFS",
- "Word Clock 256xFS"};
-
-/* chip address on I2C bus */
-#define AK4113_ADDR 0x26 /* S/PDIF receiver */
-
-/* chip address on SPI bus */
-#define AK4620_ADDR 0x02 /* ADC/DAC */
-
-
-/*
- * GPIO pins
- */
-
-/* GPIO0 - O - DATA0, def. 0 */
-#define GPIO_D0 (1<<0)
-/* GPIO1 - I/O - DATA1, Jack Detect Input0 (0:present, 1:missing), def. 1 */
-#define GPIO_D1_JACKDTC0 (1<<1)
-/* GPIO2 - I/O - DATA2, Jack Detect Input1 (0:present, 1:missing), def. 1 */
-#define GPIO_D2_JACKDTC1 (1<<2)
-/* GPIO3 - I/O - DATA3, def. 1 */
-#define GPIO_D3 (1<<3)
-/* GPIO4 - I/O - DATA4, SPI CDTO, def. 1 */
-#define GPIO_D4_SPI_CDTO (1<<4)
-/* GPIO5 - I/O - DATA5, SPI CCLK, def. 1 */
-#define GPIO_D5_SPI_CCLK (1<<5)
-/* GPIO6 - I/O - DATA6, Cable Detect Input (0:detected, 1:not detected */
-#define GPIO_D6_CD (1<<6)
-/* GPIO7 - I/O - DATA7, Device Detect Input (0:detected, 1:not detected */
-#define GPIO_D7_DD (1<<7)
-/* GPIO8 - O - CPLD Chip Select, def. 1 */
-#define GPIO_CPLD_CSN (1<<8)
-/* GPIO9 - O - CPLD register read/write (0:write, 1:read), def. 0 */
-#define GPIO_CPLD_RW (1<<9)
-/* GPIO10 - O - SPI Chip Select for CODEC#0, def. 1 */
-#define GPIO_SPI_CSN0 (1<<10)
-/* GPIO11 - O - SPI Chip Select for CODEC#1, def. 1 */
-#define GPIO_SPI_CSN1 (1<<11)
-/* GPIO12 - O - Ex. Register Output Enable (0:enable, 1:disable), def. 1,
- * init 0 */
-#define GPIO_EX_GPIOE (1<<12)
-/* GPIO13 - O - Ex. Register0 Chip Select for System Control Register,
- * def. 1 */
-#define GPIO_SCR (1<<13)
-/* GPIO14 - O - Ex. Register1 Chip Select for Monitor Control Register,
- * def. 1 */
-#define GPIO_MCR (1<<14)
-
-#define GPIO_SPI_ALL (GPIO_D4_SPI_CDTO | GPIO_D5_SPI_CCLK |\
- GPIO_SPI_CSN0 | GPIO_SPI_CSN1)
-
-#define GPIO_DATA_MASK (GPIO_D0 | GPIO_D1_JACKDTC0 | \
- GPIO_D2_JACKDTC1 | GPIO_D3 | \
- GPIO_D4_SPI_CDTO | GPIO_D5_SPI_CCLK | \
- GPIO_D6_CD | GPIO_D7_DD)
-
-/* System Control Register GPIO_SCR data bits */
-/* Mic/Line select relay (0:line, 1:mic) */
-#define SCR_RELAY GPIO_D0
-/* Phantom power drive control (0:5V, 1:48V) */
-#define SCR_PHP_V GPIO_D1_JACKDTC0
-/* H/W mute control (0:Normal, 1:Mute) */
-#define SCR_MUTE GPIO_D2_JACKDTC1
-/* Phantom power control (0:Phantom on, 1:off) */
-#define SCR_PHP GPIO_D3
-/* Analog input 1/2 Source Select */
-#define SCR_AIN12_SEL0 GPIO_D4_SPI_CDTO
-#define SCR_AIN12_SEL1 GPIO_D5_SPI_CCLK
-/* Analog input 3/4 Source Select (0:line, 1:hi-z) */
-#define SCR_AIN34_SEL GPIO_D6_CD
-/* Codec Power Down (0:power down, 1:normal) */
-#define SCR_CODEC_PDN GPIO_D7_DD
-
-#define SCR_AIN12_LINE (0)
-#define SCR_AIN12_MIC (SCR_AIN12_SEL0)
-#define SCR_AIN12_LOWCUT (SCR_AIN12_SEL1 | SCR_AIN12_SEL0)
-
-/* Monitor Control Register GPIO_MCR data bits */
-/* Input 1/2 to Monitor 1/2 (0:off, 1:on) */
-#define MCR_IN12_MON12 GPIO_D0
-/* Input 1/2 to Monitor 3/4 (0:off, 1:on) */
-#define MCR_IN12_MON34 GPIO_D1_JACKDTC0
-/* Input 3/4 to Monitor 1/2 (0:off, 1:on) */
-#define MCR_IN34_MON12 GPIO_D2_JACKDTC1
-/* Input 3/4 to Monitor 3/4 (0:off, 1:on) */
-#define MCR_IN34_MON34 GPIO_D3
-/* Output to Monitor 1/2 (0:off, 1:on) */
-#define MCR_OUT34_MON12 GPIO_D4_SPI_CDTO
-/* Output to Monitor 3/4 (0:off, 1:on) */
-#define MCR_OUT12_MON34 GPIO_D5_SPI_CCLK
-
-/* CPLD Register DATA bits */
-/* Clock Rate Select */
-#define CPLD_CKS0 GPIO_D0
-#define CPLD_CKS1 GPIO_D1_JACKDTC0
-#define CPLD_CKS2 GPIO_D2_JACKDTC1
-/* Sync Source Select (0:Internal, 1:External) */
-#define CPLD_SYNC_SEL GPIO_D3
-/* Word Clock FS Select (0:FS, 1:256FS) */
-#define CPLD_WORD_SEL GPIO_D4_SPI_CDTO
-/* Coaxial Output Source (IS-Link) (0:SPDIF, 1:I2S) */
-#define CPLD_COAX_OUT GPIO_D5_SPI_CCLK
-/* Input 1/2 Source Select (0:Analog12, 1:An34) */
-#define CPLD_IN12_SEL GPIO_D6_CD
-/* Input 3/4 Source Select (0:Analog34, 1:Digital In) */
-#define CPLD_IN34_SEL GPIO_D7_DD
-
-/* internal clock (CPLD_SYNC_SEL = 0) options */
-#define CPLD_CKS_44100HZ (0)
-#define CPLD_CKS_48000HZ (CPLD_CKS0)
-#define CPLD_CKS_88200HZ (CPLD_CKS1)
-#define CPLD_CKS_96000HZ (CPLD_CKS1 | CPLD_CKS0)
-#define CPLD_CKS_176400HZ (CPLD_CKS2)
-#define CPLD_CKS_192000HZ (CPLD_CKS2 | CPLD_CKS0)
-
-#define CPLD_CKS_MASK (CPLD_CKS0 | CPLD_CKS1 | CPLD_CKS2)
-
-/* external clock (CPLD_SYNC_SEL = 1) options */
-/* external clock - SPDIF */
-#define CPLD_EXT_SPDIF (0 | CPLD_SYNC_SEL)
-/* external clock - WordClock 1xfs */
-#define CPLD_EXT_WORDCLOCK_1FS (CPLD_CKS1 | CPLD_SYNC_SEL)
-/* external clock - WordClock 256xfs */
-#define CPLD_EXT_WORDCLOCK_256FS (CPLD_CKS1 | CPLD_WORD_SEL |\
- CPLD_SYNC_SEL)
-
-#define EXT_SPDIF_TYPE 0
-#define EXT_WORDCLOCK_1FS_TYPE 1
-#define EXT_WORDCLOCK_256FS_TYPE 2
-
-#define AK4620_DFS0 (1<<0)
-#define AK4620_DFS1 (1<<1)
-#define AK4620_CKS0 (1<<2)
-#define AK4620_CKS1 (1<<3)
-/* Clock and Format Control register */
-#define AK4620_DFS_REG 0x02
-
-/* Deem and Volume Control register */
-#define AK4620_DEEMVOL_REG 0x03
-#define AK4620_SMUTE (1<<7)
-
-/*
- * Conversion from int value to its binary form. Used for debugging.
- * The output buffer must be allocated prior to calling the function.
- */
-static char *get_binary(char *buffer, int value)
-{
- int i, j, pos;
- pos = 0;
- for (i = 0; i < 4; ++i) {
- for (j = 0; j < 8; ++j) {
- if (value & (1 << (31-(i*8 + j))))
- buffer[pos] = '1';
- else
- buffer[pos] = '0';
- pos++;
- }
- if (i < 3) {
- buffer[pos] = ' ';
- pos++;
- }
- }
- buffer[pos] = '\0';
- return buffer;
-}
-
-/*
- * Initial setup of the conversion array GPIO <-> rate
- */
-static unsigned int qtet_rates[] = {
- 44100, 48000, 88200,
- 96000, 176400, 192000,
-};
-
-static unsigned int cks_vals[] = {
- CPLD_CKS_44100HZ, CPLD_CKS_48000HZ, CPLD_CKS_88200HZ,
- CPLD_CKS_96000HZ, CPLD_CKS_176400HZ, CPLD_CKS_192000HZ,
-};
-
-static struct snd_pcm_hw_constraint_list qtet_rates_info = {
- .count = ARRAY_SIZE(qtet_rates),
- .list = qtet_rates,
- .mask = 0,
-};
-
-static void qtet_ak4113_write(void *private_data, unsigned char reg,
- unsigned char val)
-{
- snd_vt1724_write_i2c((struct snd_ice1712 *)private_data, AK4113_ADDR,
- reg, val);
-}
-
-static unsigned char qtet_ak4113_read(void *private_data, unsigned char reg)
-{
- return snd_vt1724_read_i2c((struct snd_ice1712 *)private_data,
- AK4113_ADDR, reg);
-}
-
-
-/*
- * AK4620 section
- */
-
-/*
- * Write data to addr register of ak4620
- */
-static void qtet_akm_write(struct snd_akm4xxx *ak, int chip,
- unsigned char addr, unsigned char data)
-{
- unsigned int tmp, orig_dir;
- int idx;
- unsigned int addrdata;
- struct snd_ice1712 *ice = ak->private_data[0];
-
- if (snd_BUG_ON(chip < 0 || chip >= 4))
- return;
- /*printk(KERN_DEBUG "Writing to AK4620: chip=%d, addr=0x%x,
- data=0x%x\n", chip, addr, data);*/
- orig_dir = ice->gpio.get_dir(ice);
- ice->gpio.set_dir(ice, orig_dir | GPIO_SPI_ALL);
- /* set mask - only SPI bits */
- ice->gpio.set_mask(ice, ~GPIO_SPI_ALL);
-
- tmp = ice->gpio.get_data(ice);
- /* high all */
- tmp |= GPIO_SPI_ALL;
- ice->gpio.set_data(ice, tmp);
- udelay(100);
- /* drop chip select */
- if (chip)
- /* CODEC 1 */
- tmp &= ~GPIO_SPI_CSN1;
- else
- tmp &= ~GPIO_SPI_CSN0;
- ice->gpio.set_data(ice, tmp);
- udelay(100);
-
- /* build I2C address + data byte */
- addrdata = (AK4620_ADDR << 6) | 0x20 | (addr & 0x1f);
- addrdata = (addrdata << 8) | data;
- for (idx = 15; idx >= 0; idx--) {
- /* drop clock */
- tmp &= ~GPIO_D5_SPI_CCLK;
- ice->gpio.set_data(ice, tmp);
- udelay(100);
- /* set data */
- if (addrdata & (1 << idx))
- tmp |= GPIO_D4_SPI_CDTO;
- else
- tmp &= ~GPIO_D4_SPI_CDTO;
- ice->gpio.set_data(ice, tmp);
- udelay(100);
- /* raise clock */
- tmp |= GPIO_D5_SPI_CCLK;
- ice->gpio.set_data(ice, tmp);
- udelay(100);
- }
- /* all back to 1 */
- tmp |= GPIO_SPI_ALL;
- ice->gpio.set_data(ice, tmp);
- udelay(100);
-
- /* return all gpios to non-writable */
- ice->gpio.set_mask(ice, 0xffffff);
- /* restore GPIOs direction */
- ice->gpio.set_dir(ice, orig_dir);
-}
-
-static void qtet_akm_set_regs(struct snd_akm4xxx *ak, unsigned char addr,
- unsigned char mask, unsigned char value)
-{
- unsigned char tmp;
- int chip;
- for (chip = 0; chip < ak->num_chips; chip++) {
- tmp = snd_akm4xxx_get(ak, chip, addr);
- /* clear the bits */
- tmp &= ~mask;
- /* set the new bits */
- tmp |= value;
- snd_akm4xxx_write(ak, chip, addr, tmp);
- }
-}
-
-/*
- * change the rate of AK4620
- */
-static void qtet_akm_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
-{
- unsigned char ak4620_dfs;
-
- if (rate == 0) /* no hint - S/PDIF input is master or the new spdif
- input rate undetected, simply return */
- return;
-
- /* adjust DFS on codecs - see datasheet */
- if (rate > 108000)
- ak4620_dfs = AK4620_DFS1 | AK4620_CKS1;
- else if (rate > 54000)
- ak4620_dfs = AK4620_DFS0 | AK4620_CKS0;
- else
- ak4620_dfs = 0;
-
- /* set new value */
- qtet_akm_set_regs(ak, AK4620_DFS_REG, AK4620_DFS0 | AK4620_DFS1 |
- AK4620_CKS0 | AK4620_CKS1, ak4620_dfs);
-}
-
-#define AK_CONTROL(xname, xch) { .name = xname, .num_channels = xch }
-
-#define PCM_12_PLAYBACK_VOLUME "PCM 1/2 Playback Volume"
-#define PCM_34_PLAYBACK_VOLUME "PCM 3/4 Playback Volume"
-#define PCM_12_CAPTURE_VOLUME "PCM 1/2 Capture Volume"
-#define PCM_34_CAPTURE_VOLUME "PCM 3/4 Capture Volume"
-
-static const struct snd_akm4xxx_dac_channel qtet_dac[] = {
- AK_CONTROL(PCM_12_PLAYBACK_VOLUME, 2),
- AK_CONTROL(PCM_34_PLAYBACK_VOLUME, 2),
-};
-
-static const struct snd_akm4xxx_adc_channel qtet_adc[] = {
- AK_CONTROL(PCM_12_CAPTURE_VOLUME, 2),
- AK_CONTROL(PCM_34_CAPTURE_VOLUME, 2),
-};
-
-static struct snd_akm4xxx akm_qtet_dac __devinitdata = {
- .type = SND_AK4620,
- .num_dacs = 4, /* DAC1 - Output 12
- */
- .num_adcs = 4, /* ADC1 - Input 12
- */
- .ops = {
- .write = qtet_akm_write,
- .set_rate_val = qtet_akm_set_rate_val,
- },
- .dac_info = qtet_dac,
- .adc_info = qtet_adc,
-};
-
-/* Communication routines with the CPLD */
-
-
-/* Writes data to external register reg, both reg and data are
- * GPIO representations */
-static void reg_write(struct snd_ice1712 *ice, unsigned int reg,
- unsigned int data)
-{
- unsigned int tmp;
-
- mutex_lock(&ice->gpio_mutex);
- /* set direction of used GPIOs*/
- /* all outputs */
- tmp = 0x00ffff;
- ice->gpio.set_dir(ice, tmp);
- /* mask - writable bits */
- ice->gpio.set_mask(ice, ~(tmp));
- /* write the data */
- tmp = ice->gpio.get_data(ice);
- tmp &= ~GPIO_DATA_MASK;
- tmp |= data;
- ice->gpio.set_data(ice, tmp);
- udelay(100);
- /* drop output enable */
- tmp &= ~GPIO_EX_GPIOE;
- ice->gpio.set_data(ice, tmp);
- udelay(100);
- /* drop the register gpio */
- tmp &= ~reg;
- ice->gpio.set_data(ice, tmp);
- udelay(100);
- /* raise the register GPIO */
- tmp |= reg;
- ice->gpio.set_data(ice, tmp);
- udelay(100);
-
- /* raise all data gpios */
- tmp |= GPIO_DATA_MASK;
- ice->gpio.set_data(ice, tmp);
- /* mask - immutable bits */
- ice->gpio.set_mask(ice, 0xffffff);
- /* outputs only 8-15 */
- ice->gpio.set_dir(ice, 0x00ff00);
- mutex_unlock(&ice->gpio_mutex);
-}
-
-static unsigned int get_scr(struct snd_ice1712 *ice)
-{
- struct qtet_spec *spec = ice->spec;
- return spec->scr;
-}
-
-static unsigned int get_mcr(struct snd_ice1712 *ice)
-{
- struct qtet_spec *spec = ice->spec;
- return spec->mcr;
-}
-
-static unsigned int get_cpld(struct snd_ice1712 *ice)
-{
- struct qtet_spec *spec = ice->spec;
- return spec->cpld;
-}
-
-static void set_scr(struct snd_ice1712 *ice, unsigned int val)
-{
- struct qtet_spec *spec = ice->spec;
- reg_write(ice, GPIO_SCR, val);
- spec->scr = val;
-}
-
-static void set_mcr(struct snd_ice1712 *ice, unsigned int val)
-{
- struct qtet_spec *spec = ice->spec;
- reg_write(ice, GPIO_MCR, val);
- spec->mcr = val;
-}
-
-static void set_cpld(struct snd_ice1712 *ice, unsigned int val)
-{
- struct qtet_spec *spec = ice->spec;
- reg_write(ice, GPIO_CPLD_CSN, val);
- spec->cpld = val;
-}
-#ifdef CONFIG_PROC_FS
-static void proc_regs_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_ice1712 *ice = entry->private_data;
- char bin_buffer[36];
-
- snd_iprintf(buffer, "SCR: %s\n", get_binary(bin_buffer,
- get_scr(ice)));
- snd_iprintf(buffer, "MCR: %s\n", get_binary(bin_buffer,
- get_mcr(ice)));
- snd_iprintf(buffer, "CPLD: %s\n", get_binary(bin_buffer,
- get_cpld(ice)));
-}
-
-static void proc_init(struct snd_ice1712 *ice)
-{
- struct snd_info_entry *entry;
- if (!snd_card_proc_new(ice->card, "quartet", &entry))
- snd_info_set_text_ops(entry, ice, proc_regs_read);
-}
-#else /* !CONFIG_PROC_FS */
-static void proc_init(struct snd_ice1712 *ice) {}
-#endif
-
-static int qtet_mute_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- val = get_scr(ice) & SCR_MUTE;
- ucontrol->value.integer.value[0] = (val) ? 0 : 1;
- return 0;
-}
-
-static int qtet_mute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned int old, new, smute;
- old = get_scr(ice) & SCR_MUTE;
- if (ucontrol->value.integer.value[0]) {
- /* unmute */
- new = 0;
- /* un-smuting DAC */
- smute = 0;
- } else {
- /* mute */
- new = SCR_MUTE;
- /* smuting DAC */
- smute = AK4620_SMUTE;
- }
- if (old != new) {
- struct snd_akm4xxx *ak = ice->akm;
- set_scr(ice, (get_scr(ice) & ~SCR_MUTE) | new);
- /* set smute */
- qtet_akm_set_regs(ak, AK4620_DEEMVOL_REG, AK4620_SMUTE, smute);
- return 1;
- }
- /* no change */
- return 0;
-}
-
-static int qtet_ain12_enum_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[3] = {"Line In 1/2", "Mic", "Mic + Low-cut"};
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = ARRAY_SIZE(texts);
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-static int qtet_ain12_sw_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned int val, result;
- val = get_scr(ice) & (SCR_AIN12_SEL1 | SCR_AIN12_SEL0);
- switch (val) {
- case SCR_AIN12_LINE:
- result = 0;
- break;
- case SCR_AIN12_MIC:
- result = 1;
- break;
- case SCR_AIN12_LOWCUT:
- result = 2;
- break;
- default:
- /* BUG - no other combinations allowed */
- snd_BUG();
- result = 0;
- }
- ucontrol->value.integer.value[0] = result;
- return 0;
-}
-
-static int qtet_ain12_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned int old, new, tmp, masked_old;
- old = new = get_scr(ice);
- masked_old = old & (SCR_AIN12_SEL1 | SCR_AIN12_SEL0);
- tmp = ucontrol->value.integer.value[0];
- if (tmp == 2)
- tmp = 3; /* binary 10 is not supported */
- tmp <<= 4; /* shifting to SCR_AIN12_SEL0 */
- if (tmp != masked_old) {
- /* change requested */
- switch (tmp) {
- case SCR_AIN12_LINE:
- new = old & ~(SCR_AIN12_SEL1 | SCR_AIN12_SEL0);
- set_scr(ice, new);
- /* turn off relay */
- new &= ~SCR_RELAY;
- set_scr(ice, new);
- break;
- case SCR_AIN12_MIC:
- /* turn on relay */
- new = old | SCR_RELAY;
- set_scr(ice, new);
- new = (new & ~SCR_AIN12_SEL1) | SCR_AIN12_SEL0;
- set_scr(ice, new);
- break;
- case SCR_AIN12_LOWCUT:
- /* turn on relay */
- new = old | SCR_RELAY;
- set_scr(ice, new);
- new |= SCR_AIN12_SEL1 | SCR_AIN12_SEL0;
- set_scr(ice, new);
- break;
- default:
- snd_BUG();
- }
- return 1;
- }
- /* no change */
- return 0;
-}
-
-static int qtet_php_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- /* if phantom voltage =48V, phantom on */
- val = get_scr(ice) & SCR_PHP_V;
- ucontrol->value.integer.value[0] = val ? 1 : 0;
- return 0;
-}
-
-static int qtet_php_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned int old, new;
- old = new = get_scr(ice);
- if (ucontrol->value.integer.value[0] /* phantom on requested */
- && (~old & SCR_PHP_V)) /* 0 = voltage 5V */ {
- /* is off, turn on */
- /* turn voltage on first, = 1 */
- new = old | SCR_PHP_V;
- set_scr(ice, new);
- /* turn phantom on, = 0 */
- new &= ~SCR_PHP;
- set_scr(ice, new);
- } else if (!ucontrol->value.integer.value[0] && (old & SCR_PHP_V)) {
- /* phantom off requested and 1 = voltage 48V */
- /* is on, turn off */
- /* turn voltage off first, = 0 */
- new = old & ~SCR_PHP_V;
- set_scr(ice, new);
- /* turn phantom off, = 1 */
- new |= SCR_PHP;
- set_scr(ice, new);
- }
- if (old != new)
- return 1;
- /* no change */
- return 0;
-}
-
-#define PRIV_SW(xid, xbit, xreg) [xid] = {.bit = xbit,\
- .set_register = set_##xreg,\
- .get_register = get_##xreg, }
-
-
-#define PRIV_ENUM2(xid, xbit, xreg, xtext1, xtext2) [xid] = {.bit = xbit,\
- .set_register = set_##xreg,\
- .get_register = get_##xreg,\
- .texts = {xtext1, xtext2} }
-
-static struct qtet_kcontrol_private qtet_privates[] = {
- PRIV_ENUM2(IN12_SEL, CPLD_IN12_SEL, cpld, "An In 1/2", "An In 3/4"),
- PRIV_ENUM2(IN34_SEL, CPLD_IN34_SEL, cpld, "An In 3/4", "IEC958 In"),
- PRIV_ENUM2(AIN34_SEL, SCR_AIN34_SEL, scr, "Line In 3/4", "Hi-Z"),
- PRIV_ENUM2(COAX_OUT, CPLD_COAX_OUT, cpld, "IEC958", "I2S"),
- PRIV_SW(IN12_MON12, MCR_IN12_MON12, mcr),
- PRIV_SW(IN12_MON34, MCR_IN12_MON34, mcr),
- PRIV_SW(IN34_MON12, MCR_IN34_MON12, mcr),
- PRIV_SW(IN34_MON34, MCR_IN34_MON34, mcr),
- PRIV_SW(OUT12_MON34, MCR_OUT12_MON34, mcr),
- PRIV_SW(OUT34_MON12, MCR_OUT34_MON12, mcr),
-};
-
-static int qtet_enum_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct qtet_kcontrol_private private =
- qtet_privates[kcontrol->private_value];
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = ARRAY_SIZE(private.texts);
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name,
- private.texts[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-static int qtet_sw_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct qtet_kcontrol_private private =
- qtet_privates[kcontrol->private_value];
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] =
- (private.get_register(ice) & private.bit) ? 1 : 0;
- return 0;
-}
-
-static int qtet_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct qtet_kcontrol_private private =
- qtet_privates[kcontrol->private_value];
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned int old, new;
- old = private.get_register(ice);
- if (ucontrol->value.integer.value[0])
- new = old | private.bit;
- else
- new = old & ~private.bit;
- if (old != new) {
- private.set_register(ice, new);
- return 1;
- }
- /* no change */
- return 0;
-}
-
-#define qtet_sw_info snd_ctl_boolean_mono_info
-
-#define QTET_CONTROL(xname, xtype, xpriv) \
- {.iface = SNDRV_CTL_ELEM_IFACE_MIXER,\
- .name = xname,\
- .info = qtet_##xtype##_info,\
- .get = qtet_sw_get,\
- .put = qtet_sw_put,\
- .private_value = xpriv }
-
-static struct snd_kcontrol_new qtet_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = qtet_sw_info,
- .get = qtet_mute_get,
- .put = qtet_mute_put,
- .private_value = 0
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Phantom Power",
- .info = qtet_sw_info,
- .get = qtet_php_get,
- .put = qtet_php_put,
- .private_value = 0
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog In 1/2 Capture Switch",
- .info = qtet_ain12_enum_info,
- .get = qtet_ain12_sw_get,
- .put = qtet_ain12_sw_put,
- .private_value = 0
- },
- QTET_CONTROL("Analog In 3/4 Capture Switch", enum, AIN34_SEL),
- QTET_CONTROL("PCM In 1/2 Capture Switch", enum, IN12_SEL),
- QTET_CONTROL("PCM In 3/4 Capture Switch", enum, IN34_SEL),
- QTET_CONTROL("Coax Output Source", enum, COAX_OUT),
- QTET_CONTROL("Analog In 1/2 to Monitor 1/2", sw, IN12_MON12),
- QTET_CONTROL("Analog In 1/2 to Monitor 3/4", sw, IN12_MON34),
- QTET_CONTROL("Analog In 3/4 to Monitor 1/2", sw, IN34_MON12),
- QTET_CONTROL("Analog In 3/4 to Monitor 3/4", sw, IN34_MON34),
- QTET_CONTROL("Output 1/2 to Monitor 3/4", sw, OUT12_MON34),
- QTET_CONTROL("Output 3/4 to Monitor 1/2", sw, OUT34_MON12),
-};
-
-static char *slave_vols[] __devinitdata = {
- PCM_12_PLAYBACK_VOLUME,
- PCM_34_PLAYBACK_VOLUME,
- NULL
-};
-
-static __devinitdata
-DECLARE_TLV_DB_SCALE(qtet_master_db_scale, -6350, 50, 1);
-
-static struct snd_kcontrol __devinit *ctl_find(struct snd_card *card,
- const char *name)
-{
- struct snd_ctl_elem_id sid;
- memset(&sid, 0, sizeof(sid));
- /* FIXME: strcpy is bad. */
- strcpy(sid.name, name);
- sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- return snd_ctl_find_id(card, &sid);
-}
-
-static void __devinit add_slaves(struct snd_card *card,
- struct snd_kcontrol *master, char **list)
-{
- for (; *list; list++) {
- struct snd_kcontrol *slave = ctl_find(card, *list);
- if (slave)
- snd_ctl_add_slave(master, slave);
- }
-}
-
-static int __devinit qtet_add_controls(struct snd_ice1712 *ice)
-{
- struct qtet_spec *spec = ice->spec;
- int err, i;
- struct snd_kcontrol *vmaster;
- err = snd_ice1712_akm4xxx_build_controls(ice);
- if (err < 0)
- return err;
- for (i = 0; i < ARRAY_SIZE(qtet_controls); i++) {
- err = snd_ctl_add(ice->card,
- snd_ctl_new1(&qtet_controls[i], ice));
- if (err < 0)
- return err;
- }
-
- /* Create virtual master control */
- vmaster = snd_ctl_make_virtual_master("Master Playback Volume",
- qtet_master_db_scale);
- if (!vmaster)
- return -ENOMEM;
- add_slaves(ice->card, vmaster, slave_vols);
- err = snd_ctl_add(ice->card, vmaster);
- if (err < 0)
- return err;
- /* only capture SPDIF over AK4113 */
- err = snd_ak4113_build(spec->ak4113,
- ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
- if (err < 0)
- return err;
- return 0;
-}
-
-static inline int qtet_is_spdif_master(struct snd_ice1712 *ice)
-{
- /* CPLD_SYNC_SEL: 0 = internal, 1 = external (i.e. spdif master) */
- return (get_cpld(ice) & CPLD_SYNC_SEL) ? 1 : 0;
-}
-
-static unsigned int qtet_get_rate(struct snd_ice1712 *ice)
-{
- int i;
- unsigned char result;
-
- result = get_cpld(ice) & CPLD_CKS_MASK;
- for (i = 0; i < ARRAY_SIZE(cks_vals); i++)
- if (cks_vals[i] == result)
- return qtet_rates[i];
- return 0;
-}
-
-static int get_cks_val(int rate)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(qtet_rates); i++)
- if (qtet_rates[i] == rate)
- return cks_vals[i];
- return 0;
-}
-
-/* setting new rate */
-static void qtet_set_rate(struct snd_ice1712 *ice, unsigned int rate)
-{
- unsigned int new;
- unsigned char val;
- /* switching ice1724 to external clock - supplied by ext. circuits */
- val = inb(ICEMT1724(ice, RATE));
- outb(val | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE));
-
- new = (get_cpld(ice) & ~CPLD_CKS_MASK) | get_cks_val(rate);
- /* switch to internal clock, drop CPLD_SYNC_SEL */
- new &= ~CPLD_SYNC_SEL;
- /* printk(KERN_DEBUG "QT - set_rate: old %x, new %x\n",
- get_cpld(ice), new); */
- set_cpld(ice, new);
-}
-
-static inline unsigned char qtet_set_mclk(struct snd_ice1712 *ice,
- unsigned int rate)
-{
- /* no change in master clock */
- return 0;
-}
-
-/* setting clock to external - SPDIF */
-static int qtet_set_spdif_clock(struct snd_ice1712 *ice, int type)
-{
- unsigned int old, new;
-
- old = new = get_cpld(ice);
- new &= ~(CPLD_CKS_MASK | CPLD_WORD_SEL);
- switch (type) {
- case EXT_SPDIF_TYPE:
- new |= CPLD_EXT_SPDIF;
- break;
- case EXT_WORDCLOCK_1FS_TYPE:
- new |= CPLD_EXT_WORDCLOCK_1FS;
- break;
- case EXT_WORDCLOCK_256FS_TYPE:
- new |= CPLD_EXT_WORDCLOCK_256FS;
- break;
- default:
- snd_BUG();
- }
- if (old != new) {
- set_cpld(ice, new);
- /* changed */
- return 1;
- }
- return 0;
-}
-
-static int qtet_get_spdif_master_type(struct snd_ice1712 *ice)
-{
- unsigned int val;
- int result;
- val = get_cpld(ice);
- /* checking only rate/clock-related bits */
- val &= (CPLD_CKS_MASK | CPLD_WORD_SEL | CPLD_SYNC_SEL);
- if (!(val & CPLD_SYNC_SEL)) {
- /* switched to internal clock, is not any external type */
- result = -1;
- } else {
- switch (val) {
- case (CPLD_EXT_SPDIF):
- result = EXT_SPDIF_TYPE;
- break;
- case (CPLD_EXT_WORDCLOCK_1FS):
- result = EXT_WORDCLOCK_1FS_TYPE;
- break;
- case (CPLD_EXT_WORDCLOCK_256FS):
- result = EXT_WORDCLOCK_256FS_TYPE;
- break;
- default:
- /* undefined combination of external clock setup */
- snd_BUG();
- result = 0;
- }
- }
- return result;
-}
-
-/* Called when ak4113 detects change in the input SPDIF stream */
-static void qtet_ak4113_change(struct ak4113 *ak4113, unsigned char c0,
- unsigned char c1)
-{
- struct snd_ice1712 *ice = ak4113->change_callback_private;
- int rate;
- if ((qtet_get_spdif_master_type(ice) == EXT_SPDIF_TYPE) &&
- c1) {
- /* only for SPDIF master mode, rate was changed */
- rate = snd_ak4113_external_rate(ak4113);
- /* printk(KERN_DEBUG "ak4113 - input rate changed to %d\n",
- rate); */
- qtet_akm_set_rate_val(ice->akm, rate);
- }
-}
-
-/*
- * If clock slaved to SPDIF-IN, setting runtime rate
- * to the detected external rate
- */
-static void qtet_spdif_in_open(struct snd_ice1712 *ice,
- struct snd_pcm_substream *substream)
-{
- struct qtet_spec *spec = ice->spec;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int rate;
-
- if (qtet_get_spdif_master_type(ice) != EXT_SPDIF_TYPE)
- /* not external SPDIF, no rate limitation */
- return;
- /* only external SPDIF can detect incoming sample rate */
- rate = snd_ak4113_external_rate(spec->ak4113);
- if (rate >= runtime->hw.rate_min && rate <= runtime->hw.rate_max) {
- runtime->hw.rate_min = rate;
- runtime->hw.rate_max = rate;
- }
-}
-
-/*
- * initialize the chip
- */
-static int __devinit qtet_init(struct snd_ice1712 *ice)
-{
- static const unsigned char ak4113_init_vals[] = {
- /* AK4113_REG_PWRDN */ AK4113_RST | AK4113_PWN |
- AK4113_OCKS0 | AK4113_OCKS1,
- /* AK4113_REQ_FORMAT */ AK4113_DIF_I24I2S | AK4113_VTX |
- AK4113_DEM_OFF | AK4113_DEAU,
- /* AK4113_REG_IO0 */ AK4113_OPS2 | AK4113_TXE |
- AK4113_XTL_24_576M,
- /* AK4113_REG_IO1 */ AK4113_EFH_1024LRCLK | AK4113_IPS(0),
- /* AK4113_REG_INT0_MASK */ 0,
- /* AK4113_REG_INT1_MASK */ 0,
- /* AK4113_REG_DATDTS */ 0,
- };
- int err;
- struct qtet_spec *spec;
- struct snd_akm4xxx *ak;
- unsigned char val;
-
- /* switching ice1724 to external clock - supplied by ext. circuits */
- val = inb(ICEMT1724(ice, RATE));
- outb(val | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE));
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- /* qtet is clocked by Xilinx array */
- ice->hw_rates = &qtet_rates_info;
- ice->is_spdif_master = qtet_is_spdif_master;
- ice->get_rate = qtet_get_rate;
- ice->set_rate = qtet_set_rate;
- ice->set_mclk = qtet_set_mclk;
- ice->set_spdif_clock = qtet_set_spdif_clock;
- ice->get_spdif_master_type = qtet_get_spdif_master_type;
- ice->ext_clock_names = ext_clock_names;
- ice->ext_clock_count = ARRAY_SIZE(ext_clock_names);
- /* since Qtet can detect correct SPDIF-in rate, all streams can be
- * limited to this specific rate */
- ice->spdif.ops.open = ice->pro_open = qtet_spdif_in_open;
- ice->spec = spec;
-
- /* Mute Off */
- /* SCR Initialize*/
- /* keep codec power down first */
- set_scr(ice, SCR_PHP);
- udelay(1);
- /* codec power up */
- set_scr(ice, SCR_PHP | SCR_CODEC_PDN);
-
- /* MCR Initialize */
- set_mcr(ice, 0);
-
- /* CPLD Initialize */
- set_cpld(ice, 0);
-
-
- ice->num_total_dacs = 2;
- ice->num_total_adcs = 2;
-
- ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL);
- ak = ice->akm;
- if (!ak)
- return -ENOMEM;
- /* only one codec with two chips */
- ice->akm_codecs = 1;
- err = snd_ice1712_akm4xxx_init(ak, &akm_qtet_dac, NULL, ice);
- if (err < 0)
- return err;
- err = snd_ak4113_create(ice->card,
- qtet_ak4113_read,
- qtet_ak4113_write,
- ak4113_init_vals,
- ice, &spec->ak4113);
- if (err < 0)
- return err;
- /* callback for codecs rate setting */
- spec->ak4113->change_callback = qtet_ak4113_change;
- spec->ak4113->change_callback_private = ice;
- /* AK41143 in Quartet can detect external rate correctly
- * (i.e. check_flags = 0) */
- spec->ak4113->check_flags = 0;
-
- proc_init(ice);
-
- qtet_set_rate(ice, 44100);
- return 0;
-}
-
-static unsigned char qtet_eeprom[] __devinitdata = {
- [ICE_EEP2_SYSCONF] = 0x28, /* clock 256(24MHz), mpu401, 1xADC,
- 1xDACs, SPDIF in */
- [ICE_EEP2_ACLINK] = 0x80, /* I2S */
- [ICE_EEP2_I2S] = 0x78, /* 96k, 24bit, 192k */
- [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, in, out-ext */
- [ICE_EEP2_GPIO_DIR] = 0x00, /* 0-7 inputs, switched to output
- only during output operations */
- [ICE_EEP2_GPIO_DIR1] = 0xff, /* 8-15 outputs */
- [ICE_EEP2_GPIO_DIR2] = 0x00,
- [ICE_EEP2_GPIO_MASK] = 0xff, /* changed only for OUT operations */
- [ICE_EEP2_GPIO_MASK1] = 0x00,
- [ICE_EEP2_GPIO_MASK2] = 0xff,
-
- [ICE_EEP2_GPIO_STATE] = 0x00, /* inputs */
- [ICE_EEP2_GPIO_STATE1] = 0x7d, /* all 1, but GPIO_CPLD_RW
- and GPIO15 always zero */
- [ICE_EEP2_GPIO_STATE2] = 0x00, /* inputs */
-};
-
-/* entry point */
-struct snd_ice1712_card_info snd_vt1724_qtet_cards[] __devinitdata = {
- {
- .subvendor = VT1724_SUBDEVICE_QTET,
- .name = "Infrasonic Quartet",
- .model = "quartet",
- .chip_init = qtet_init,
- .build_controls = qtet_add_controls,
- .eeprom_size = sizeof(qtet_eeprom),
- .eeprom_data = qtet_eeprom,
- },
- { } /* terminator */
-};
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/quartet.h b/ANDROID_3.4.5/sound/pci/ice1712/quartet.h
deleted file mode 100644
index 80809b72..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/quartet.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __SOUND_QTET_H
-#define __SOUND_QTET_H
-
-#define QTET_DEVICE_DESC "{Infrasonic,Quartet},"
-
-#define VT1724_SUBDEVICE_QTET 0x30305349 /* Infrasonic Quartet */
-
-extern struct snd_ice1712_card_info snd_vt1724_qtet_cards[];
-
-#endif /* __SOUND_QTET_H */
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/revo.c b/ANDROID_3.4.5/sound/pci/ice1712/revo.c
deleted file mode 100644
index b508bb36..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/revo.c
+++ /dev/null
@@ -1,633 +0,0 @@
-/*
- * ALSA driver for ICEnsemble ICE1712 (Envy24)
- *
- * Lowlevel functions for M-Audio Audiophile 192, Revolution 7.1 and 5.1
- *
- * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-
-#include "ice1712.h"
-#include "envy24ht.h"
-#include "revo.h"
-
-/* a non-standard I2C device for revo51 */
-struct revo51_spec {
- struct snd_i2c_device *dev;
- struct snd_pt2258 *pt2258;
-};
-
-static void revo_i2s_mclk_changed(struct snd_ice1712 *ice)
-{
- /* assert PRST# to converters; MT05 bit 7 */
- outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
- mdelay(5);
- /* deassert PRST# */
- outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));
-}
-
-/*
- * change the rate of Envy24HT, AK4355 and AK4381
- */
-static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
-{
- unsigned char old, tmp, dfs;
- int reg, shift;
-
- if (rate == 0) /* no hint - S/PDIF input is master, simply return */
- return;
-
- /* adjust DFS on codecs */
- if (rate > 96000)
- dfs = 2;
- else if (rate > 48000)
- dfs = 1;
- else
- dfs = 0;
-
- if (ak->type == SND_AK4355 || ak->type == SND_AK4358) {
- reg = 2;
- shift = 4;
- } else {
- reg = 1;
- shift = 3;
- }
- tmp = snd_akm4xxx_get(ak, 0, reg);
- old = (tmp >> shift) & 0x03;
- if (old == dfs)
- return;
-
- /* reset DFS */
- snd_akm4xxx_reset(ak, 1);
- tmp = snd_akm4xxx_get(ak, 0, reg);
- tmp &= ~(0x03 << shift);
- tmp |= dfs << shift;
- /* snd_akm4xxx_write(ak, 0, reg, tmp); */
- snd_akm4xxx_set(ak, 0, reg, tmp); /* value is written in reset(0) */
- snd_akm4xxx_reset(ak, 0);
-}
-
-/*
- * I2C access to the PT2258 volume controller on GPIO 6/7 (Revolution 5.1)
- */
-
-static void revo_i2c_start(struct snd_i2c_bus *bus)
-{
- struct snd_ice1712 *ice = bus->private_data;
- snd_ice1712_save_gpio_status(ice);
-}
-
-static void revo_i2c_stop(struct snd_i2c_bus *bus)
-{
- struct snd_ice1712 *ice = bus->private_data;
- snd_ice1712_restore_gpio_status(ice);
-}
-
-static void revo_i2c_direction(struct snd_i2c_bus *bus, int clock, int data)
-{
- struct snd_ice1712 *ice = bus->private_data;
- unsigned int mask, val;
-
- val = 0;
- if (clock)
- val |= VT1724_REVO_I2C_CLOCK; /* write SCL */
- if (data)
- val |= VT1724_REVO_I2C_DATA; /* write SDA */
- mask = VT1724_REVO_I2C_CLOCK | VT1724_REVO_I2C_DATA;
- ice->gpio.direction &= ~mask;
- ice->gpio.direction |= val;
- snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
- snd_ice1712_gpio_set_mask(ice, ~mask);
-}
-
-static void revo_i2c_setlines(struct snd_i2c_bus *bus, int clk, int data)
-{
- struct snd_ice1712 *ice = bus->private_data;
- unsigned int val = 0;
-
- if (clk)
- val |= VT1724_REVO_I2C_CLOCK;
- if (data)
- val |= VT1724_REVO_I2C_DATA;
- snd_ice1712_gpio_write_bits(ice,
- VT1724_REVO_I2C_DATA |
- VT1724_REVO_I2C_CLOCK, val);
- udelay(5);
-}
-
-static int revo_i2c_getdata(struct snd_i2c_bus *bus, int ack)
-{
- struct snd_ice1712 *ice = bus->private_data;
- int bit;
-
- if (ack)
- udelay(5);
- bit = snd_ice1712_gpio_read_bits(ice, VT1724_REVO_I2C_DATA) ? 1 : 0;
- return bit;
-}
-
-static struct snd_i2c_bit_ops revo51_bit_ops = {
- .start = revo_i2c_start,
- .stop = revo_i2c_stop,
- .direction = revo_i2c_direction,
- .setlines = revo_i2c_setlines,
- .getdata = revo_i2c_getdata,
-};
-
-static int revo51_i2c_init(struct snd_ice1712 *ice,
- struct snd_pt2258 *pt)
-{
- struct revo51_spec *spec;
- int err;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- ice->spec = spec;
-
- /* create the I2C bus */
- err = snd_i2c_bus_create(ice->card, "ICE1724 GPIO6", NULL, &ice->i2c);
- if (err < 0)
- return err;
-
- ice->i2c->private_data = ice;
- ice->i2c->hw_ops.bit = &revo51_bit_ops;
-
- /* create the I2C device */
- err = snd_i2c_device_create(ice->i2c, "PT2258", 0x40, &spec->dev);
- if (err < 0)
- return err;
-
- pt->card = ice->card;
- pt->i2c_bus = ice->i2c;
- pt->i2c_dev = spec->dev;
- spec->pt2258 = pt;
-
- snd_pt2258_reset(pt);
-
- return 0;
-}
-
-/*
- * initialize the chips on M-Audio Revolution cards
- */
-
-#define AK_DAC(xname,xch) { .name = xname, .num_channels = xch }
-
-static const struct snd_akm4xxx_dac_channel revo71_front[] = {
- {
- .name = "PCM Playback Volume",
- .num_channels = 2,
- /* front channels DAC supports muting */
- .switch_name = "PCM Playback Switch",
- },
-};
-
-static const struct snd_akm4xxx_dac_channel revo71_surround[] = {
- AK_DAC("PCM Center Playback Volume", 1),
- AK_DAC("PCM LFE Playback Volume", 1),
- AK_DAC("PCM Side Playback Volume", 2),
- AK_DAC("PCM Rear Playback Volume", 2),
-};
-
-static const struct snd_akm4xxx_dac_channel revo51_dac[] = {
- AK_DAC("PCM Playback Volume", 2),
- AK_DAC("PCM Center Playback Volume", 1),
- AK_DAC("PCM LFE Playback Volume", 1),
- AK_DAC("PCM Rear Playback Volume", 2),
- AK_DAC("PCM Headphone Volume", 2),
-};
-
-static const char *revo51_adc_input_names[] = {
- "Mic",
- "Line",
- "CD",
- NULL
-};
-
-static const struct snd_akm4xxx_adc_channel revo51_adc[] = {
- {
- .name = "PCM Capture Volume",
- .switch_name = "PCM Capture Switch",
- .num_channels = 2,
- .input_names = revo51_adc_input_names
- },
-};
-
-static struct snd_akm4xxx akm_revo_front __devinitdata = {
- .type = SND_AK4381,
- .num_dacs = 2,
- .ops = {
- .set_rate_val = revo_set_rate_val
- },
- .dac_info = revo71_front,
-};
-
-static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = {
- .caddr = 1,
- .cif = 0,
- .data_mask = VT1724_REVO_CDOUT,
- .clk_mask = VT1724_REVO_CCLK,
- .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
- .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS2,
- .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
- .add_flags = VT1724_REVO_CCLK, /* high at init */
- .mask_flags = 0,
-};
-
-static struct snd_akm4xxx akm_revo_surround __devinitdata = {
- .type = SND_AK4355,
- .idx_offset = 1,
- .num_dacs = 6,
- .ops = {
- .set_rate_val = revo_set_rate_val
- },
- .dac_info = revo71_surround,
-};
-
-static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = {
- .caddr = 3,
- .cif = 0,
- .data_mask = VT1724_REVO_CDOUT,
- .clk_mask = VT1724_REVO_CCLK,
- .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
- .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS1,
- .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
- .add_flags = VT1724_REVO_CCLK, /* high at init */
- .mask_flags = 0,
-};
-
-static struct snd_akm4xxx akm_revo51 __devinitdata = {
- .type = SND_AK4358,
- .num_dacs = 8,
- .ops = {
- .set_rate_val = revo_set_rate_val
- },
- .dac_info = revo51_dac,
-};
-
-static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = {
- .caddr = 2,
- .cif = 0,
- .data_mask = VT1724_REVO_CDOUT,
- .clk_mask = VT1724_REVO_CCLK,
- .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1,
- .cs_addr = VT1724_REVO_CS1,
- .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1,
- .add_flags = VT1724_REVO_CCLK, /* high at init */
- .mask_flags = 0,
-};
-
-static struct snd_akm4xxx akm_revo51_adc __devinitdata = {
- .type = SND_AK5365,
- .num_adcs = 2,
- .adc_info = revo51_adc,
-};
-
-static struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = {
- .caddr = 2,
- .cif = 0,
- .data_mask = VT1724_REVO_CDOUT,
- .clk_mask = VT1724_REVO_CCLK,
- .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1,
- .cs_addr = VT1724_REVO_CS0,
- .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1,
- .add_flags = VT1724_REVO_CCLK, /* high at init */
- .mask_flags = 0,
-};
-
-static struct snd_pt2258 ptc_revo51_volume;
-
-/* AK4358 for AP192 DAC, AK5385A for ADC */
-static void ap192_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
-{
- struct snd_ice1712 *ice = ak->private_data[0];
- int dfs;
-
- revo_set_rate_val(ak, rate);
-
- /* reset CKS */
- snd_ice1712_gpio_write_bits(ice, 1 << 8, rate > 96000 ? 1 << 8 : 0);
- /* reset DFS pins of AK5385A for ADC, too */
- if (rate > 96000)
- dfs = 2;
- else if (rate > 48000)
- dfs = 1;
- else
- dfs = 0;
- snd_ice1712_gpio_write_bits(ice, 3 << 9, dfs << 9);
- /* reset ADC */
- snd_ice1712_gpio_write_bits(ice, 1 << 11, 0);
- snd_ice1712_gpio_write_bits(ice, 1 << 11, 1 << 11);
-}
-
-static const struct snd_akm4xxx_dac_channel ap192_dac[] = {
- AK_DAC("PCM Playback Volume", 2)
-};
-
-static struct snd_akm4xxx akm_ap192 __devinitdata = {
- .type = SND_AK4358,
- .num_dacs = 2,
- .ops = {
- .set_rate_val = ap192_set_rate_val
- },
- .dac_info = ap192_dac,
-};
-
-static struct snd_ak4xxx_private akm_ap192_priv __devinitdata = {
- .caddr = 2,
- .cif = 0,
- .data_mask = VT1724_REVO_CDOUT,
- .clk_mask = VT1724_REVO_CCLK,
- .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1,
- .cs_addr = VT1724_REVO_CS1,
- .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1,
- .add_flags = VT1724_REVO_CCLK, /* high at init */
- .mask_flags = 0,
-};
-
-/* AK4114 support on Audiophile 192 */
-/* CDTO (pin 32) -- GPIO2 pin 52
- * CDTI (pin 33) -- GPIO3 pin 53 (shared with AK4358)
- * CCLK (pin 34) -- GPIO1 pin 51 (shared with AK4358)
- * CSN (pin 35) -- GPIO7 pin 59
- */
-#define AK4114_ADDR 0x02
-
-static void write_data(struct snd_ice1712 *ice, unsigned int gpio,
- unsigned int data, int idx)
-{
- for (; idx >= 0; idx--) {
- /* drop clock */
- gpio &= ~VT1724_REVO_CCLK;
- snd_ice1712_gpio_write(ice, gpio);
- udelay(1);
- /* set data */
- if (data & (1 << idx))
- gpio |= VT1724_REVO_CDOUT;
- else
- gpio &= ~VT1724_REVO_CDOUT;
- snd_ice1712_gpio_write(ice, gpio);
- udelay(1);
- /* raise clock */
- gpio |= VT1724_REVO_CCLK;
- snd_ice1712_gpio_write(ice, gpio);
- udelay(1);
- }
-}
-
-static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio,
- int idx)
-{
- unsigned char data = 0;
-
- for (; idx >= 0; idx--) {
- /* drop clock */
- gpio &= ~VT1724_REVO_CCLK;
- snd_ice1712_gpio_write(ice, gpio);
- udelay(1);
- /* read data */
- if (snd_ice1712_gpio_read(ice) & VT1724_REVO_CDIN)
- data |= (1 << idx);
- udelay(1);
- /* raise clock */
- gpio |= VT1724_REVO_CCLK;
- snd_ice1712_gpio_write(ice, gpio);
- udelay(1);
- }
- return data;
-}
-
-static unsigned int ap192_4wire_start(struct snd_ice1712 *ice)
-{
- unsigned int tmp;
-
- snd_ice1712_save_gpio_status(ice);
- tmp = snd_ice1712_gpio_read(ice);
- tmp |= VT1724_REVO_CCLK; /* high at init */
- tmp |= VT1724_REVO_CS0;
- tmp &= ~VT1724_REVO_CS1;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- return tmp;
-}
-
-static void ap192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp)
-{
- tmp |= VT1724_REVO_CS1;
- tmp |= VT1724_REVO_CS0;
- snd_ice1712_gpio_write(ice, tmp);
- udelay(1);
- snd_ice1712_restore_gpio_status(ice);
-}
-
-static void ap192_ak4114_write(void *private_data, unsigned char addr,
- unsigned char data)
-{
- struct snd_ice1712 *ice = private_data;
- unsigned int tmp, addrdata;
-
- tmp = ap192_4wire_start(ice);
- addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f);
- addrdata = (addrdata << 8) | data;
- write_data(ice, tmp, addrdata, 15);
- ap192_4wire_finish(ice, tmp);
-}
-
-static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr)
-{
- struct snd_ice1712 *ice = private_data;
- unsigned int tmp;
- unsigned char data;
-
- tmp = ap192_4wire_start(ice);
- write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7);
- data = read_data(ice, tmp, 7);
- ap192_4wire_finish(ice, tmp);
- return data;
-}
-
-static int __devinit ap192_ak4114_init(struct snd_ice1712 *ice)
-{
- static const unsigned char ak4114_init_vals[] = {
- AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1,
- AK4114_DIF_I24I2S,
- AK4114_TX1E,
- AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(1),
- 0,
- 0
- };
- static const unsigned char ak4114_init_txcsb[] = {
- 0x41, 0x02, 0x2c, 0x00, 0x00
- };
- struct ak4114 *ak;
- int err;
-
- err = snd_ak4114_create(ice->card,
- ap192_ak4114_read,
- ap192_ak4114_write,
- ak4114_init_vals, ak4114_init_txcsb,
- ice, &ak);
- /* AK4114 in Revo cannot detect external rate correctly.
- * No reason to stop capture stream due to incorrect checks */
- ak->check_flags = AK4114_CHECK_NO_RATE;
-
- return 0; /* error ignored; it's no fatal error */
-}
-
-static int __devinit revo_init(struct snd_ice1712 *ice)
-{
- struct snd_akm4xxx *ak;
- int err;
-
- /* determine I2C, DACs and ADCs */
- switch (ice->eeprom.subvendor) {
- case VT1724_SUBDEVICE_REVOLUTION71:
- ice->num_total_dacs = 8;
- ice->num_total_adcs = 2;
- ice->gpio.i2s_mclk_changed = revo_i2s_mclk_changed;
- break;
- case VT1724_SUBDEVICE_REVOLUTION51:
- ice->num_total_dacs = 8;
- ice->num_total_adcs = 2;
- break;
- case VT1724_SUBDEVICE_AUDIOPHILE192:
- ice->num_total_dacs = 2;
- ice->num_total_adcs = 2;
- break;
- default:
- snd_BUG();
- return -EINVAL;
- }
-
- /* second stage of initialization, analog parts and others */
- ak = ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL);
- if (! ak)
- return -ENOMEM;
- switch (ice->eeprom.subvendor) {
- case VT1724_SUBDEVICE_REVOLUTION71:
- ice->akm_codecs = 2;
- err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front,
- &akm_revo_front_priv, ice);
- if (err < 0)
- return err;
- err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo_surround,
- &akm_revo_surround_priv, ice);
- if (err < 0)
- return err;
- /* unmute all codecs */
- snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,
- VT1724_REVO_MUTE);
- break;
- case VT1724_SUBDEVICE_REVOLUTION51:
- ice->akm_codecs = 2;
- err = snd_ice1712_akm4xxx_init(ak, &akm_revo51,
- &akm_revo51_priv, ice);
- if (err < 0)
- return err;
- err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo51_adc,
- &akm_revo51_adc_priv, ice);
- if (err < 0)
- return err;
- err = revo51_i2c_init(ice, &ptc_revo51_volume);
- if (err < 0)
- return err;
- /* unmute all codecs */
- snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,
- VT1724_REVO_MUTE);
- break;
- case VT1724_SUBDEVICE_AUDIOPHILE192:
- ice->akm_codecs = 1;
- err = snd_ice1712_akm4xxx_init(ak, &akm_ap192, &akm_ap192_priv,
- ice);
- if (err < 0)
- return err;
-
- /* unmute all codecs */
- snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,
- VT1724_REVO_MUTE);
- break;
- }
-
- return 0;
-}
-
-
-static int __devinit revo_add_controls(struct snd_ice1712 *ice)
-{
- struct revo51_spec *spec;
- int err;
-
- switch (ice->eeprom.subvendor) {
- case VT1724_SUBDEVICE_REVOLUTION71:
- err = snd_ice1712_akm4xxx_build_controls(ice);
- if (err < 0)
- return err;
- break;
- case VT1724_SUBDEVICE_REVOLUTION51:
- err = snd_ice1712_akm4xxx_build_controls(ice);
- if (err < 0)
- return err;
- spec = ice->spec;
- err = snd_pt2258_build_controls(spec->pt2258);
- if (err < 0)
- return err;
- break;
- case VT1724_SUBDEVICE_AUDIOPHILE192:
- err = snd_ice1712_akm4xxx_build_controls(ice);
- if (err < 0)
- return err;
- err = ap192_ak4114_init(ice);
- if (err < 0)
- return err;
- break;
- }
- return 0;
-}
-
-/* entry point */
-struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = {
- {
- .subvendor = VT1724_SUBDEVICE_REVOLUTION71,
- .name = "M Audio Revolution-7.1",
- .model = "revo71",
- .chip_init = revo_init,
- .build_controls = revo_add_controls,
- },
- {
- .subvendor = VT1724_SUBDEVICE_REVOLUTION51,
- .name = "M Audio Revolution-5.1",
- .model = "revo51",
- .chip_init = revo_init,
- .build_controls = revo_add_controls,
- },
- {
- .subvendor = VT1724_SUBDEVICE_AUDIOPHILE192,
- .name = "M Audio Audiophile192",
- .model = "ap192",
- .chip_init = revo_init,
- .build_controls = revo_add_controls,
- },
- { } /* terminator */
-};
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/revo.h b/ANDROID_3.4.5/sound/pci/ice1712/revo.h
deleted file mode 100644
index a3ba4259..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/revo.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef __SOUND_REVO_H
-#define __SOUND_REVO_H
-
-/*
- * ALSA driver for ICEnsemble ICE1712 (Envy24)
- *
- * Lowlevel functions for M-Audio Revolution 7.1
- *
- * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define REVO_DEVICE_DESC \
- "{MidiMan M Audio,Revolution 7.1},"\
- "{MidiMan M Audio,Revolution 5.1},"\
- "{MidiMan M Audio,Audiophile 192},"
-
-#define VT1724_SUBDEVICE_REVOLUTION71 0x12143036
-#define VT1724_SUBDEVICE_REVOLUTION51 0x12143136
-#define VT1724_SUBDEVICE_AUDIOPHILE192 0x12143236
-
-/* entry point */
-extern struct snd_ice1712_card_info snd_vt1724_revo_cards[];
-
-
-/*
- * MidiMan M-Audio Revolution GPIO definitions
- */
-
-#define VT1724_REVO_CCLK 0x02
-#define VT1724_REVO_CDIN 0x04 /* not used */
-#define VT1724_REVO_CDOUT 0x08
-#define VT1724_REVO_CS0 0x10 /* AK5365 chipselect for (revo51) */
-#define VT1724_REVO_CS1 0x20 /* front AKM4381 chipselect */
-#define VT1724_REVO_CS2 0x40 /* surround AKM4355 CS (revo71) */
-#define VT1724_REVO_I2C_DATA 0x40 /* I2C: PT 2258 SDA (on revo51) */
-#define VT1724_REVO_I2C_CLOCK 0x80 /* I2C: PT 2258 SCL (on revo51) */
-#define VT1724_REVO_CS3 0x80 /* AK4114 for AP192 */
-#define VT1724_REVO_MUTE (1<<22) /* 0 = all mute, 1 = normal operation */
-
-#endif /* __SOUND_REVO_H */
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/se.c b/ANDROID_3.4.5/sound/pci/ice1712/se.c
deleted file mode 100644
index 69673b95..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/se.c
+++ /dev/null
@@ -1,774 +0,0 @@
-/*
- * ALSA driver for ICEnsemble VT1724 (Envy24HT)
- *
- * Lowlevel functions for ONKYO WAVIO SE-90PCI and SE-200PCI
- *
- * Copyright (c) 2007 Shin-ya Okada sh_okada(at)d4.dion.ne.jp
- * (at) -> @
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/tlv.h>
-
-#include "ice1712.h"
-#include "envy24ht.h"
-#include "se.h"
-
-struct se_spec {
- struct {
- unsigned char ch1, ch2;
- } vol[8];
-};
-
-/****************************************************************************/
-/* ONKYO WAVIO SE-200PCI */
-/****************************************************************************/
-/*
- * system configuration ICE_EEP2_SYSCONF=0x4b
- * XIN1 49.152MHz
- * not have UART
- * one stereo ADC and a S/PDIF receiver connected
- * four stereo DACs connected
- *
- * AC-Link configuration ICE_EEP2_ACLINK=0x80
- * use I2C, not use AC97
- *
- * I2S converters feature ICE_EEP2_I2S=0x78
- * I2S codec has no volume/mute control feature
- * I2S codec supports 96KHz and 192KHz
- * I2S codec 24bits
- *
- * S/PDIF configuration ICE_EEP2_SPDIF=0xc3
- * Enable integrated S/PDIF transmitter
- * internal S/PDIF out implemented
- * S/PDIF is stereo
- * External S/PDIF out implemented
- *
- *
- * ** connected chips **
- *
- * WM8740
- * A 2ch-DAC of main outputs.
- * It setuped as I2S mode by wire, so no way to setup from software.
- * The sample-rate are automatically changed.
- * ML/I2S (28pin) --------+
- * MC/DM1 (27pin) -- 5V |
- * MD/DM0 (26pin) -- GND |
- * MUTEB (25pin) -- NC |
- * MODE (24pin) -- GND |
- * CSBIW (23pin) --------+
- * |
- * RSTB (22pin) --R(1K)-+
- * Probably it reduce the noise from the control line.
- *
- * WM8766
- * A 6ch-DAC for surrounds.
- * It's control wire was connected to GPIOxx (3-wire serial interface)
- * ML/I2S (11pin) -- GPIO18
- * MC/IWL (12pin) -- GPIO17
- * MD/DM (13pin) -- GPIO16
- * MUTE (14pin) -- GPIO01
- *
- * WM8776
- * A 2ch-ADC(with 10ch-selector) plus 2ch-DAC.
- * It's control wire was connected to SDA/SCLK (2-wire serial interface)
- * MODE (16pin) -- R(1K) -- GND
- * CE (17pin) -- R(1K) -- GND 2-wire mode (address=0x34)
- * DI (18pin) -- SDA
- * CL (19pin) -- SCLK
- *
- *
- * ** output pins and device names **
- *
- * 7.1ch name -- output connector color -- device (-D option)
- *
- * FRONT 2ch -- green -- plughw:0,0
- * CENTER(Lch) SUBWOOFER(Rch) -- black -- plughw:0,2,0
- * SURROUND 2ch -- orange -- plughw:0,2,1
- * SURROUND BACK 2ch -- white -- plughw:0,2,2
- *
- */
-
-
-/****************************************************************************/
-/* WM8740 interface */
-/****************************************************************************/
-
-static void __devinit se200pci_WM8740_init(struct snd_ice1712 *ice)
-{
- /* nothing to do */
-}
-
-
-static void se200pci_WM8740_set_pro_rate(struct snd_ice1712 *ice,
- unsigned int rate)
-{
- /* nothing to do */
-}
-
-
-/****************************************************************************/
-/* WM8766 interface */
-/****************************************************************************/
-
-static void se200pci_WM8766_write(struct snd_ice1712 *ice,
- unsigned int addr, unsigned int data)
-{
- unsigned int st;
- unsigned int bits;
- int i;
- const unsigned int DATA = 0x010000;
- const unsigned int CLOCK = 0x020000;
- const unsigned int LOAD = 0x040000;
- const unsigned int ALL_MASK = (DATA | CLOCK | LOAD);
-
- snd_ice1712_save_gpio_status(ice);
-
- st = ((addr & 0x7f) << 9) | (data & 0x1ff);
- snd_ice1712_gpio_set_dir(ice, ice->gpio.direction | ALL_MASK);
- snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask & ~ALL_MASK);
- bits = snd_ice1712_gpio_read(ice) & ~ALL_MASK;
-
- snd_ice1712_gpio_write(ice, bits);
- for (i = 0; i < 16; i++) {
- udelay(1);
- bits &= ~CLOCK;
- st = (st << 1);
- if (st & 0x10000)
- bits |= DATA;
- else
- bits &= ~DATA;
-
- snd_ice1712_gpio_write(ice, bits);
-
- udelay(1);
- bits |= CLOCK;
- snd_ice1712_gpio_write(ice, bits);
- }
-
- udelay(1);
- bits |= LOAD;
- snd_ice1712_gpio_write(ice, bits);
-
- udelay(1);
- bits |= (DATA | CLOCK);
- snd_ice1712_gpio_write(ice, bits);
-
- snd_ice1712_restore_gpio_status(ice);
-}
-
-static void se200pci_WM8766_set_volume(struct snd_ice1712 *ice, int ch,
- unsigned int vol1, unsigned int vol2)
-{
- switch (ch) {
- case 0:
- se200pci_WM8766_write(ice, 0x000, vol1);
- se200pci_WM8766_write(ice, 0x001, vol2 | 0x100);
- break;
- case 1:
- se200pci_WM8766_write(ice, 0x004, vol1);
- se200pci_WM8766_write(ice, 0x005, vol2 | 0x100);
- break;
- case 2:
- se200pci_WM8766_write(ice, 0x006, vol1);
- se200pci_WM8766_write(ice, 0x007, vol2 | 0x100);
- break;
- }
-}
-
-static void __devinit se200pci_WM8766_init(struct snd_ice1712 *ice)
-{
- se200pci_WM8766_write(ice, 0x1f, 0x000); /* RESET ALL */
- udelay(10);
-
- se200pci_WM8766_set_volume(ice, 0, 0, 0); /* volume L=0 R=0 */
- se200pci_WM8766_set_volume(ice, 1, 0, 0); /* volume L=0 R=0 */
- se200pci_WM8766_set_volume(ice, 2, 0, 0); /* volume L=0 R=0 */
-
- se200pci_WM8766_write(ice, 0x03, 0x022); /* serial mode I2S-24bits */
- se200pci_WM8766_write(ice, 0x0a, 0x080); /* MCLK=256fs */
- se200pci_WM8766_write(ice, 0x12, 0x000); /* MDP=0 */
- se200pci_WM8766_write(ice, 0x15, 0x000); /* MDP=0 */
- se200pci_WM8766_write(ice, 0x09, 0x000); /* demp=off mute=off */
-
- se200pci_WM8766_write(ice, 0x02, 0x124); /* ch-assign L=L R=R RESET */
- se200pci_WM8766_write(ice, 0x02, 0x120); /* ch-assign L=L R=R */
-}
-
-static void se200pci_WM8766_set_pro_rate(struct snd_ice1712 *ice,
- unsigned int rate)
-{
- if (rate > 96000)
- se200pci_WM8766_write(ice, 0x0a, 0x000); /* MCLK=128fs */
- else
- se200pci_WM8766_write(ice, 0x0a, 0x080); /* MCLK=256fs */
-}
-
-
-/****************************************************************************/
-/* WM8776 interface */
-/****************************************************************************/
-
-static void se200pci_WM8776_write(struct snd_ice1712 *ice,
- unsigned int addr, unsigned int data)
-{
- unsigned int val;
-
- val = (addr << 9) | data;
- snd_vt1724_write_i2c(ice, 0x34, val >> 8, val & 0xff);
-}
-
-
-static void se200pci_WM8776_set_output_volume(struct snd_ice1712 *ice,
- unsigned int vol1, unsigned int vol2)
-{
- se200pci_WM8776_write(ice, 0x03, vol1);
- se200pci_WM8776_write(ice, 0x04, vol2 | 0x100);
-}
-
-static void se200pci_WM8776_set_input_volume(struct snd_ice1712 *ice,
- unsigned int vol1, unsigned int vol2)
-{
- se200pci_WM8776_write(ice, 0x0e, vol1);
- se200pci_WM8776_write(ice, 0x0f, vol2 | 0x100);
-}
-
-static const char *se200pci_sel[] = {
- "LINE-IN", "CD-IN", "MIC-IN", "ALL-MIX", NULL
-};
-
-static void se200pci_WM8776_set_input_selector(struct snd_ice1712 *ice,
- unsigned int sel)
-{
- static unsigned char vals[] = {
- /* LINE, CD, MIC, ALL, GND */
- 0x10, 0x04, 0x08, 0x1c, 0x03
- };
- if (sel > 4)
- sel = 4;
- se200pci_WM8776_write(ice, 0x15, vals[sel]);
-}
-
-static void se200pci_WM8776_set_afl(struct snd_ice1712 *ice, unsigned int afl)
-{
- /* AFL -- After Fader Listening */
- if (afl)
- se200pci_WM8776_write(ice, 0x16, 0x005);
- else
- se200pci_WM8776_write(ice, 0x16, 0x001);
-}
-
-static const char *se200pci_agc[] = {
- "Off", "LimiterMode", "ALCMode", NULL
-};
-
-static void se200pci_WM8776_set_agc(struct snd_ice1712 *ice, unsigned int agc)
-{
- /* AGC -- Auto Gain Control of the input */
- switch (agc) {
- case 0:
- se200pci_WM8776_write(ice, 0x11, 0x000); /* Off */
- break;
- case 1:
- se200pci_WM8776_write(ice, 0x10, 0x07b);
- se200pci_WM8776_write(ice, 0x11, 0x100); /* LimiterMode */
- break;
- case 2:
- se200pci_WM8776_write(ice, 0x10, 0x1fb);
- se200pci_WM8776_write(ice, 0x11, 0x100); /* ALCMode */
- break;
- }
-}
-
-static void __devinit se200pci_WM8776_init(struct snd_ice1712 *ice)
-{
- int i;
- static unsigned short __devinitdata default_values[] = {
- 0x100, 0x100, 0x100,
- 0x100, 0x100, 0x100,
- 0x000, 0x090, 0x000, 0x000,
- 0x022, 0x022, 0x022,
- 0x008, 0x0cf, 0x0cf, 0x07b, 0x000,
- 0x032, 0x000, 0x0a6, 0x001, 0x001
- };
-
- se200pci_WM8776_write(ice, 0x17, 0x000); /* reset all */
- /* ADC and DAC interface is I2S 24bits mode */
- /* The sample-rate are automatically changed */
- udelay(10);
- /* BUT my board can not do reset all, so I load all by manually. */
- for (i = 0; i < ARRAY_SIZE(default_values); i++)
- se200pci_WM8776_write(ice, i, default_values[i]);
-
- se200pci_WM8776_set_input_selector(ice, 0);
- se200pci_WM8776_set_afl(ice, 0);
- se200pci_WM8776_set_agc(ice, 0);
- se200pci_WM8776_set_input_volume(ice, 0, 0);
- se200pci_WM8776_set_output_volume(ice, 0, 0);
-
- /* head phone mute and power down */
- se200pci_WM8776_write(ice, 0x00, 0);
- se200pci_WM8776_write(ice, 0x01, 0);
- se200pci_WM8776_write(ice, 0x02, 0x100);
- se200pci_WM8776_write(ice, 0x0d, 0x080);
-}
-
-static void se200pci_WM8776_set_pro_rate(struct snd_ice1712 *ice,
- unsigned int rate)
-{
- /* nothing to do */
-}
-
-
-/****************************************************************************/
-/* runtime interface */
-/****************************************************************************/
-
-static void se200pci_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate)
-{
- se200pci_WM8740_set_pro_rate(ice, rate);
- se200pci_WM8766_set_pro_rate(ice, rate);
- se200pci_WM8776_set_pro_rate(ice, rate);
-}
-
-struct se200pci_control {
- char *name;
- enum {
- WM8766,
- WM8776in,
- WM8776out,
- WM8776sel,
- WM8776agc,
- WM8776afl
- } target;
- enum { VOLUME1, VOLUME2, BOOLEAN, ENUM } type;
- int ch;
- const char **member;
- const char *comment;
-};
-
-static const struct se200pci_control se200pci_cont[] = {
- {
- .name = "Front Playback Volume",
- .target = WM8776out,
- .type = VOLUME1,
- .comment = "Front(green)"
- },
- {
- .name = "Side Playback Volume",
- .target = WM8766,
- .type = VOLUME1,
- .ch = 1,
- .comment = "Surround(orange)"
- },
- {
- .name = "Surround Playback Volume",
- .target = WM8766,
- .type = VOLUME1,
- .ch = 2,
- .comment = "SurroundBack(white)"
- },
- {
- .name = "CLFE Playback Volume",
- .target = WM8766,
- .type = VOLUME1,
- .ch = 0,
- .comment = "Center(Lch)&SubWoofer(Rch)(black)"
- },
- {
- .name = "Capture Volume",
- .target = WM8776in,
- .type = VOLUME2
- },
- {
- .name = "Capture Select",
- .target = WM8776sel,
- .type = ENUM,
- .member = se200pci_sel
- },
- {
- .name = "AGC Capture Mode",
- .target = WM8776agc,
- .type = ENUM,
- .member = se200pci_agc
- },
- {
- .name = "AFL Bypass Playback Switch",
- .target = WM8776afl,
- .type = BOOLEAN
- }
-};
-
-static int se200pci_get_enum_count(int n)
-{
- const char **member;
- int c;
-
- member = se200pci_cont[n].member;
- if (!member)
- return 0;
- for (c = 0; member[c]; c++)
- ;
- return c;
-}
-
-static int se200pci_cont_volume_info(struct snd_kcontrol *kc,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0; /* mute */
- uinfo->value.integer.max = 0xff; /* 0dB */
- return 0;
-}
-
-#define se200pci_cont_boolean_info snd_ctl_boolean_mono_info
-
-static int se200pci_cont_enum_info(struct snd_kcontrol *kc,
- struct snd_ctl_elem_info *uinfo)
-{
- int n, c;
-
- n = kc->private_value;
- c = se200pci_get_enum_count(n);
- if (!c)
- return -EINVAL;
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = c;
- if (uinfo->value.enumerated.item >= c)
- uinfo->value.enumerated.item = c - 1;
- strcpy(uinfo->value.enumerated.name,
- se200pci_cont[n].member[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int se200pci_cont_volume_get(struct snd_kcontrol *kc,
- struct snd_ctl_elem_value *uc)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
- struct se_spec *spec = ice->spec;
- int n = kc->private_value;
- uc->value.integer.value[0] = spec->vol[n].ch1;
- uc->value.integer.value[1] = spec->vol[n].ch2;
- return 0;
-}
-
-static int se200pci_cont_boolean_get(struct snd_kcontrol *kc,
- struct snd_ctl_elem_value *uc)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
- struct se_spec *spec = ice->spec;
- int n = kc->private_value;
- uc->value.integer.value[0] = spec->vol[n].ch1;
- return 0;
-}
-
-static int se200pci_cont_enum_get(struct snd_kcontrol *kc,
- struct snd_ctl_elem_value *uc)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
- struct se_spec *spec = ice->spec;
- int n = kc->private_value;
- uc->value.enumerated.item[0] = spec->vol[n].ch1;
- return 0;
-}
-
-static void se200pci_cont_update(struct snd_ice1712 *ice, int n)
-{
- struct se_spec *spec = ice->spec;
- switch (se200pci_cont[n].target) {
- case WM8766:
- se200pci_WM8766_set_volume(ice,
- se200pci_cont[n].ch,
- spec->vol[n].ch1,
- spec->vol[n].ch2);
- break;
-
- case WM8776in:
- se200pci_WM8776_set_input_volume(ice,
- spec->vol[n].ch1,
- spec->vol[n].ch2);
- break;
-
- case WM8776out:
- se200pci_WM8776_set_output_volume(ice,
- spec->vol[n].ch1,
- spec->vol[n].ch2);
- break;
-
- case WM8776sel:
- se200pci_WM8776_set_input_selector(ice,
- spec->vol[n].ch1);
- break;
-
- case WM8776agc:
- se200pci_WM8776_set_agc(ice, spec->vol[n].ch1);
- break;
-
- case WM8776afl:
- se200pci_WM8776_set_afl(ice, spec->vol[n].ch1);
- break;
-
- default:
- break;
- }
-}
-
-static int se200pci_cont_volume_put(struct snd_kcontrol *kc,
- struct snd_ctl_elem_value *uc)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
- struct se_spec *spec = ice->spec;
- int n = kc->private_value;
- unsigned int vol1, vol2;
- int changed;
-
- changed = 0;
- vol1 = uc->value.integer.value[0] & 0xff;
- vol2 = uc->value.integer.value[1] & 0xff;
- if (spec->vol[n].ch1 != vol1) {
- spec->vol[n].ch1 = vol1;
- changed = 1;
- }
- if (spec->vol[n].ch2 != vol2) {
- spec->vol[n].ch2 = vol2;
- changed = 1;
- }
- if (changed)
- se200pci_cont_update(ice, n);
-
- return changed;
-}
-
-static int se200pci_cont_boolean_put(struct snd_kcontrol *kc,
- struct snd_ctl_elem_value *uc)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
- struct se_spec *spec = ice->spec;
- int n = kc->private_value;
- unsigned int vol1;
-
- vol1 = !!uc->value.integer.value[0];
- if (spec->vol[n].ch1 != vol1) {
- spec->vol[n].ch1 = vol1;
- se200pci_cont_update(ice, n);
- return 1;
- }
- return 0;
-}
-
-static int se200pci_cont_enum_put(struct snd_kcontrol *kc,
- struct snd_ctl_elem_value *uc)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
- struct se_spec *spec = ice->spec;
- int n = kc->private_value;
- unsigned int vol1;
-
- vol1 = uc->value.enumerated.item[0];
- if (vol1 >= se200pci_get_enum_count(n))
- return -EINVAL;
- if (spec->vol[n].ch1 != vol1) {
- spec->vol[n].ch1 = vol1;
- se200pci_cont_update(ice, n);
- return 1;
- }
- return 0;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_gain1, -12750, 50, 1);
-static const DECLARE_TLV_DB_SCALE(db_scale_gain2, -10350, 50, 1);
-
-static int __devinit se200pci_add_controls(struct snd_ice1712 *ice)
-{
- int i;
- struct snd_kcontrol_new cont;
- int err;
-
- memset(&cont, 0, sizeof(cont));
- cont.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- for (i = 0; i < ARRAY_SIZE(se200pci_cont); i++) {
- cont.private_value = i;
- cont.name = se200pci_cont[i].name;
- cont.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
- cont.tlv.p = NULL;
- switch (se200pci_cont[i].type) {
- case VOLUME1:
- case VOLUME2:
- cont.info = se200pci_cont_volume_info;
- cont.get = se200pci_cont_volume_get;
- cont.put = se200pci_cont_volume_put;
- cont.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
- if (se200pci_cont[i].type == VOLUME1)
- cont.tlv.p = db_scale_gain1;
- else
- cont.tlv.p = db_scale_gain2;
- break;
- case BOOLEAN:
- cont.info = se200pci_cont_boolean_info;
- cont.get = se200pci_cont_boolean_get;
- cont.put = se200pci_cont_boolean_put;
- break;
- case ENUM:
- cont.info = se200pci_cont_enum_info;
- cont.get = se200pci_cont_enum_get;
- cont.put = se200pci_cont_enum_put;
- break;
- default:
- snd_BUG();
- return -EINVAL;
- }
- err = snd_ctl_add(ice->card, snd_ctl_new1(&cont, ice));
- if (err < 0)
- return err;
- }
-
- return 0;
-}
-
-
-/****************************************************************************/
-/* ONKYO WAVIO SE-90PCI */
-/****************************************************************************/
-/*
- * system configuration ICE_EEP2_SYSCONF=0x4b
- * AC-Link configuration ICE_EEP2_ACLINK=0x80
- * I2S converters feature ICE_EEP2_I2S=0x78
- * S/PDIF configuration ICE_EEP2_SPDIF=0xc3
- *
- * ** connected chip **
- *
- * WM8716
- * A 2ch-DAC of main outputs.
- * It setuped as I2S mode by wire, so no way to setup from software.
- * ML/I2S (28pin) -- +5V
- * MC/DM1 (27pin) -- GND
- * MC/DM0 (26pin) -- GND
- * MUTEB (25pin) -- open (internal pull-up)
- * MODE (24pin) -- GND
- * CSBIWO (23pin) -- +5V
- *
- */
-
- /* Nothing to do for this chip. */
-
-
-/****************************************************************************/
-/* probe/initialize/setup */
-/****************************************************************************/
-
-static int __devinit se_init(struct snd_ice1712 *ice)
-{
- struct se_spec *spec;
-
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
- if (!spec)
- return -ENOMEM;
- ice->spec = spec;
-
- if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE90PCI) {
- ice->num_total_dacs = 2;
- ice->num_total_adcs = 0;
- ice->vt1720 = 1;
- return 0;
-
- } else if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE200PCI) {
- ice->num_total_dacs = 8;
- ice->num_total_adcs = 2;
- se200pci_WM8740_init(ice);
- se200pci_WM8766_init(ice);
- se200pci_WM8776_init(ice);
- ice->gpio.set_pro_rate = se200pci_set_pro_rate;
- return 0;
- }
-
- return -ENOENT;
-}
-
-static int __devinit se_add_controls(struct snd_ice1712 *ice)
-{
- int err;
-
- err = 0;
- /* nothing to do for VT1724_SUBDEVICE_SE90PCI */
- if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE200PCI)
- err = se200pci_add_controls(ice);
-
- return err;
-}
-
-
-/****************************************************************************/
-/* entry point */
-/****************************************************************************/
-
-static unsigned char se200pci_eeprom[] __devinitdata = {
- [ICE_EEP2_SYSCONF] = 0x4b, /* 49.152Hz, spdif-in/ADC, 4DACs */
- [ICE_EEP2_ACLINK] = 0x80, /* I2S */
- [ICE_EEP2_I2S] = 0x78, /* 96k-ok, 24bit, 192k-ok */
- [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
-
- [ICE_EEP2_GPIO_DIR] = 0x02, /* WM8766 mute 1=output */
- [ICE_EEP2_GPIO_DIR1] = 0x00, /* not used */
- [ICE_EEP2_GPIO_DIR2] = 0x07, /* WM8766 ML/MC/MD 1=output */
-
- [ICE_EEP2_GPIO_MASK] = 0x00, /* 0=writable */
- [ICE_EEP2_GPIO_MASK1] = 0x00, /* 0=writable */
- [ICE_EEP2_GPIO_MASK2] = 0x00, /* 0=writable */
-
- [ICE_EEP2_GPIO_STATE] = 0x00, /* WM8766 mute=0 */
- [ICE_EEP2_GPIO_STATE1] = 0x00, /* not used */
- [ICE_EEP2_GPIO_STATE2] = 0x07, /* WM8766 ML/MC/MD */
-};
-
-static unsigned char se90pci_eeprom[] __devinitdata = {
- [ICE_EEP2_SYSCONF] = 0x4b, /* 49.152Hz, spdif-in/ADC, 4DACs */
- [ICE_EEP2_ACLINK] = 0x80, /* I2S */
- [ICE_EEP2_I2S] = 0x78, /* 96k-ok, 24bit, 192k-ok */
- [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
-
- /* ALL GPIO bits are in input mode */
-};
-
-struct snd_ice1712_card_info snd_vt1724_se_cards[] __devinitdata = {
- {
- .subvendor = VT1724_SUBDEVICE_SE200PCI,
- .name = "ONKYO SE200PCI",
- .model = "se200pci",
- .chip_init = se_init,
- .build_controls = se_add_controls,
- .eeprom_size = sizeof(se200pci_eeprom),
- .eeprom_data = se200pci_eeprom,
- },
- {
- .subvendor = VT1724_SUBDEVICE_SE90PCI,
- .name = "ONKYO SE90PCI",
- .model = "se90pci",
- .chip_init = se_init,
- .build_controls = se_add_controls,
- .eeprom_size = sizeof(se90pci_eeprom),
- .eeprom_data = se90pci_eeprom,
- },
- {} /*terminator*/
-};
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/se.h b/ANDROID_3.4.5/sound/pci/ice1712/se.h
deleted file mode 100644
index 0b0a9dab..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/se.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef __SOUND_SE_H
-#define __SOUND_SE_H
-
-/* ID */
-#define SE_DEVICE_DESC \
- "{ONKYO INC,SE-90PCI},"\
- "{ONKYO INC,SE-200PCI},"
-
-#define VT1724_SUBDEVICE_SE90PCI 0xb161000
-#define VT1724_SUBDEVICE_SE200PCI 0xb160100
-
-/* entry struct */
-extern struct snd_ice1712_card_info snd_vt1724_se_cards[];
-
-#endif /* __SOUND_SE_H */
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/stac946x.h b/ANDROID_3.4.5/sound/pci/ice1712/stac946x.h
deleted file mode 100644
index 5b390952..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/stac946x.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef __SOUND_STAC946X_H
-#define __SOUND_STAC946X_H
-
-#define STAC946X_RESET 0x00
-#define STAC946X_STATUS 0x01
-#define STAC946X_MASTER_VOLUME 0x02
-#define STAC946X_LF_VOLUME 0x03
-#define STAC946X_RF_VOLUME 0x04
-#define STAC946X_LR_VOLUME 0x05
-#define STAC946X_RR_VOLUME 0x06
-#define STAC946X_CENTER_VOLUME 0x07
-#define STAC946X_LFE_VOLUME 0x08
-#define STAC946X_MIC_L_VOLUME 0x09
-#define STAC946X_MIC_R_VOLUME 0x0a
-#define STAC946X_DEEMPHASIS 0x0c
-#define STAC946X_GENERAL_PURPOSE 0x0d
-#define STAC946X_AUDIO_PORT_CONTROL 0x0e
-#define STAC946X_MASTER_CLOCKING 0x0f
-#define STAC946X_POWERDOWN_CTRL1 0x10
-#define STAC946X_POWERDOWN_CTRL2 0x11
-#define STAC946X_REVISION_CODE 0x12
-#define STAC946X_ADDRESS_CONTROL 0x13
-#define STAC946X_ADDRESS 0x14
-
-#endif /* __SOUND_STAC946X_H */
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/vt1720_mobo.c b/ANDROID_3.4.5/sound/pci/ice1712/vt1720_mobo.c
deleted file mode 100644
index 4c551e14..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/vt1720_mobo.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * ALSA driver for VT1720/VT1724 (Envy24PT/Envy24HT)
- *
- * Lowlevel functions for VT1720-based motherboards
- *
- * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <sound/core.h>
-
-#include "ice1712.h"
-#include "envy24ht.h"
-#include "vt1720_mobo.h"
-
-
-static int __devinit k8x800_init(struct snd_ice1712 *ice)
-{
- ice->vt1720 = 1;
-
- /* VT1616 codec */
- ice->num_total_dacs = 6;
- ice->num_total_adcs = 2;
-
- /* WM8728 codec */
- /* FIXME: TODO */
-
- return 0;
-}
-
-static int __devinit k8x800_add_controls(struct snd_ice1712 *ice)
-{
- /* FIXME: needs some quirks for VT1616? */
- return 0;
-}
-
-/* EEPROM image */
-
-static unsigned char k8x800_eeprom[] __devinitdata = {
- [ICE_EEP2_SYSCONF] = 0x01, /* clock 256, 1ADC, 2DACs */
- [ICE_EEP2_ACLINK] = 0x02, /* ACLINK, packed */
- [ICE_EEP2_I2S] = 0x00, /* - */
- [ICE_EEP2_SPDIF] = 0x00, /* - */
- [ICE_EEP2_GPIO_DIR] = 0xff,
- [ICE_EEP2_GPIO_DIR1] = 0xff,
- [ICE_EEP2_GPIO_DIR2] = 0x00, /* - */
- [ICE_EEP2_GPIO_MASK] = 0xff,
- [ICE_EEP2_GPIO_MASK1] = 0xff,
- [ICE_EEP2_GPIO_MASK2] = 0x00, /* - */
- [ICE_EEP2_GPIO_STATE] = 0x00,
- [ICE_EEP2_GPIO_STATE1] = 0x00,
- [ICE_EEP2_GPIO_STATE2] = 0x00, /* - */
-};
-
-static unsigned char sn25p_eeprom[] __devinitdata = {
- [ICE_EEP2_SYSCONF] = 0x01, /* clock 256, 1ADC, 2DACs */
- [ICE_EEP2_ACLINK] = 0x02, /* ACLINK, packed */
- [ICE_EEP2_I2S] = 0x00, /* - */
- [ICE_EEP2_SPDIF] = 0x41, /* - */
- [ICE_EEP2_GPIO_DIR] = 0xff,
- [ICE_EEP2_GPIO_DIR1] = 0xff,
- [ICE_EEP2_GPIO_DIR2] = 0x00, /* - */
- [ICE_EEP2_GPIO_MASK] = 0xff,
- [ICE_EEP2_GPIO_MASK1] = 0xff,
- [ICE_EEP2_GPIO_MASK2] = 0x00, /* - */
- [ICE_EEP2_GPIO_STATE] = 0x00,
- [ICE_EEP2_GPIO_STATE1] = 0x00,
- [ICE_EEP2_GPIO_STATE2] = 0x00, /* - */
-};
-
-
-/* entry point */
-struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = {
- {
- .subvendor = VT1720_SUBDEVICE_K8X800,
- .name = "Albatron K8X800 Pro II",
- .model = "k8x800",
- .chip_init = k8x800_init,
- .build_controls = k8x800_add_controls,
- .eeprom_size = sizeof(k8x800_eeprom),
- .eeprom_data = k8x800_eeprom,
- },
- {
- .subvendor = VT1720_SUBDEVICE_ZNF3_150,
- .name = "Chaintech ZNF3-150",
- /* identical with k8x800 */
- .chip_init = k8x800_init,
- .build_controls = k8x800_add_controls,
- .eeprom_size = sizeof(k8x800_eeprom),
- .eeprom_data = k8x800_eeprom,
- },
- {
- .subvendor = VT1720_SUBDEVICE_ZNF3_250,
- .name = "Chaintech ZNF3-250",
- /* identical with k8x800 */
- .chip_init = k8x800_init,
- .build_controls = k8x800_add_controls,
- .eeprom_size = sizeof(k8x800_eeprom),
- .eeprom_data = k8x800_eeprom,
- },
- {
- .subvendor = VT1720_SUBDEVICE_9CJS,
- .name = "Chaintech 9CJS",
- /* identical with k8x800 */
- .chip_init = k8x800_init,
- .build_controls = k8x800_add_controls,
- .eeprom_size = sizeof(k8x800_eeprom),
- .eeprom_data = k8x800_eeprom,
- },
- {
- .subvendor = VT1720_SUBDEVICE_SN25P,
- .name = "Shuttle SN25P",
- .model = "sn25p",
- .chip_init = k8x800_init,
- .build_controls = k8x800_add_controls,
- .eeprom_size = sizeof(k8x800_eeprom),
- .eeprom_data = sn25p_eeprom,
- },
- { } /* terminator */
-};
-
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/vt1720_mobo.h b/ANDROID_3.4.5/sound/pci/ice1712/vt1720_mobo.h
deleted file mode 100644
index 0b1b0ee1..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/vt1720_mobo.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef __SOUND_VT1720_MOBO_H
-#define __SOUND_VT1720_MOBO_H
-
-/*
- * ALSA driver for VT1720/VT1724 (Envy24PT/Envy24HT)
- *
- * Lowlevel functions for VT1720-based motherboards
- *
- * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define VT1720_MOBO_DEVICE_DESC "{Albatron,K8X800 Pro II},"\
- "{Chaintech,ZNF3-150},"\
- "{Chaintech,ZNF3-250},"\
- "{Chaintech,9CJS},"\
- "{Shuttle,SN25P},"
-
-#define VT1720_SUBDEVICE_K8X800 0xf217052c
-#define VT1720_SUBDEVICE_ZNF3_150 0x0f2741f6
-#define VT1720_SUBDEVICE_ZNF3_250 0x0f2745f6
-#define VT1720_SUBDEVICE_9CJS 0x0f272327
-#define VT1720_SUBDEVICE_SN25P 0x97123650
-
-extern struct snd_ice1712_card_info snd_vt1720_mobo_cards[];
-
-#endif /* __SOUND_VT1720_MOBO_H */
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/wtm.c b/ANDROID_3.4.5/sound/pci/ice1712/wtm.c
deleted file mode 100644
index e618f789..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/wtm.c
+++ /dev/null
@@ -1,517 +0,0 @@
-/*
- * ALSA driver for ICEnsemble VT1724 (Envy24HT)
- *
- * Lowlevel functions for Ego Sys Waveterminal 192M
- *
- * Copyright (c) 2006 Guedez Clement <klem.dev@gmail.com>
- * Some functions are taken from the Prodigy192 driver
- * source
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-
-
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <sound/core.h>
-
-#include "ice1712.h"
-#include "envy24ht.h"
-#include "wtm.h"
-#include "stac946x.h"
-
-
-/*
- * 2*ADC 6*DAC no1 ringbuffer r/w on i2c bus
- */
-static inline void stac9460_put(struct snd_ice1712 *ice, int reg,
- unsigned char val)
-{
- snd_vt1724_write_i2c(ice, STAC9460_I2C_ADDR, reg, val);
-}
-
-static inline unsigned char stac9460_get(struct snd_ice1712 *ice, int reg)
-{
- return snd_vt1724_read_i2c(ice, STAC9460_I2C_ADDR, reg);
-}
-
-/*
- * 2*ADC 2*DAC no2 ringbuffer r/w on i2c bus
- */
-static inline void stac9460_2_put(struct snd_ice1712 *ice, int reg,
- unsigned char val)
-{
- snd_vt1724_write_i2c(ice, STAC9460_2_I2C_ADDR, reg, val);
-}
-
-static inline unsigned char stac9460_2_get(struct snd_ice1712 *ice, int reg)
-{
- return snd_vt1724_read_i2c(ice, STAC9460_2_I2C_ADDR, reg);
-}
-
-
-/*
- * DAC mute control
- */
-#define stac9460_dac_mute_info snd_ctl_boolean_mono_info
-
-static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char val;
- int idx, id;
-
- if (kcontrol->private_value) {
- idx = STAC946X_MASTER_VOLUME;
- id = 0;
- } else {
- id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- idx = id + STAC946X_LF_VOLUME;
- }
- if (id < 6)
- val = stac9460_get(ice, idx);
- else
- val = stac9460_2_get(ice, idx - 6);
- ucontrol->value.integer.value[0] = (~val >> 7) & 0x1;
- return 0;
-}
-
-static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char new, old;
- int id, idx;
- int change;
-
- if (kcontrol->private_value) {
- idx = STAC946X_MASTER_VOLUME;
- old = stac9460_get(ice, idx);
- new = (~ucontrol->value.integer.value[0] << 7 & 0x80) |
- (old & ~0x80);
- change = (new != old);
- if (change) {
- stac9460_put(ice, idx, new);
- stac9460_2_put(ice, idx, new);
- }
- } else {
- id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- idx = id + STAC946X_LF_VOLUME;
- if (id < 6)
- old = stac9460_get(ice, idx);
- else
- old = stac9460_2_get(ice, idx - 6);
- new = (~ucontrol->value.integer.value[0] << 7 & 0x80) |
- (old & ~0x80);
- change = (new != old);
- if (change) {
- if (id < 6)
- stac9460_put(ice, idx, new);
- else
- stac9460_2_put(ice, idx - 6, new);
- }
- }
- return change;
-}
-
-/*
- * DAC volume attenuation mixer control
- */
-static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0; /* mute */
- uinfo->value.integer.max = 0x7f; /* 0dB */
- return 0;
-}
-
-static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int idx, id;
- unsigned char vol;
-
- if (kcontrol->private_value) {
- idx = STAC946X_MASTER_VOLUME;
- id = 0;
- } else {
- id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- idx = id + STAC946X_LF_VOLUME;
- }
- if (id < 6)
- vol = stac9460_get(ice, idx) & 0x7f;
- else
- vol = stac9460_2_get(ice, idx - 6) & 0x7f;
- ucontrol->value.integer.value[0] = 0x7f - vol;
- return 0;
-}
-
-static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int idx, id;
- unsigned char tmp, ovol, nvol;
- int change;
-
- if (kcontrol->private_value) {
- idx = STAC946X_MASTER_VOLUME;
- nvol = ucontrol->value.integer.value[0] & 0x7f;
- tmp = stac9460_get(ice, idx);
- ovol = 0x7f - (tmp & 0x7f);
- change = (ovol != nvol);
- if (change) {
- stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
- stac9460_2_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
- }
- } else {
- id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- idx = id + STAC946X_LF_VOLUME;
- nvol = ucontrol->value.integer.value[0] & 0x7f;
- if (id < 6)
- tmp = stac9460_get(ice, idx);
- else
- tmp = stac9460_2_get(ice, idx - 6);
- ovol = 0x7f - (tmp & 0x7f);
- change = (ovol != nvol);
- if (change) {
- if (id < 6)
- stac9460_put(ice, idx, (0x7f - nvol) |
- (tmp & 0x80));
- else
- stac9460_2_put(ice, idx-6, (0x7f - nvol) |
- (tmp & 0x80));
- }
- }
- return change;
-}
-
-/*
- * ADC mute control
- */
-#define stac9460_adc_mute_info snd_ctl_boolean_stereo_info
-
-static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char val;
- int i, id;
-
- id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- if (id == 0) {
- for (i = 0; i < 2; ++i) {
- val = stac9460_get(ice, STAC946X_MIC_L_VOLUME + i);
- ucontrol->value.integer.value[i] = ~val>>7 & 0x1;
- }
- } else {
- for (i = 0; i < 2; ++i) {
- val = stac9460_2_get(ice, STAC946X_MIC_L_VOLUME + i);
- ucontrol->value.integer.value[i] = ~val>>7 & 0x1;
- }
- }
- return 0;
-}
-
-static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char new, old;
- int i, reg, id;
- int change;
-
- id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- if (id == 0) {
- for (i = 0; i < 2; ++i) {
- reg = STAC946X_MIC_L_VOLUME + i;
- old = stac9460_get(ice, reg);
- new = (~ucontrol->value.integer.value[i]<<7&0x80) |
- (old&~0x80);
- change = (new != old);
- if (change)
- stac9460_put(ice, reg, new);
- }
- } else {
- for (i = 0; i < 2; ++i) {
- reg = STAC946X_MIC_L_VOLUME + i;
- old = stac9460_2_get(ice, reg);
- new = (~ucontrol->value.integer.value[i]<<7&0x80) |
- (old&~0x80);
- change = (new != old);
- if (change)
- stac9460_2_put(ice, reg, new);
- }
- }
- return change;
-}
-
-/*
- *ADC gain mixer control
- */
-static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0; /* 0dB */
- uinfo->value.integer.max = 0x0f; /* 22.5dB */
- return 0;
-}
-
-static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int i, reg, id;
- unsigned char vol;
-
- id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- if (id == 0) {
- for (i = 0; i < 2; ++i) {
- reg = STAC946X_MIC_L_VOLUME + i;
- vol = stac9460_get(ice, reg) & 0x0f;
- ucontrol->value.integer.value[i] = 0x0f - vol;
- }
- } else {
- for (i = 0; i < 2; ++i) {
- reg = STAC946X_MIC_L_VOLUME + i;
- vol = stac9460_2_get(ice, reg) & 0x0f;
- ucontrol->value.integer.value[i] = 0x0f - vol;
- }
- }
- return 0;
-}
-
-static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- int i, reg, id;
- unsigned char ovol, nvol;
- int change;
-
- id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- if (id == 0) {
- for (i = 0; i < 2; ++i) {
- reg = STAC946X_MIC_L_VOLUME + i;
- nvol = ucontrol->value.integer.value[i] & 0x0f;
- ovol = 0x0f - stac9460_get(ice, reg);
- change = ((ovol & 0x0f) != nvol);
- if (change)
- stac9460_put(ice, reg, (0x0f - nvol) |
- (ovol & ~0x0f));
- }
- } else {
- for (i = 0; i < 2; ++i) {
- reg = STAC946X_MIC_L_VOLUME + i;
- nvol = ucontrol->value.integer.value[i] & 0x0f;
- ovol = 0x0f - stac9460_2_get(ice, reg);
- change = ((ovol & 0x0f) != nvol);
- if (change)
- stac9460_2_put(ice, reg, (0x0f - nvol) |
- (ovol & ~0x0f));
- }
- }
- return change;
-}
-
-/*
- * MIC / LINE switch fonction
- */
-
-#define stac9460_mic_sw_info snd_ctl_boolean_mono_info
-
-static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char val;
- int id;
-
- id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- if (id == 0)
- val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
- else
- val = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE);
- ucontrol->value.integer.value[0] = ~val>>7 & 0x1;
- return 0;
-}
-
-static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- unsigned char new, old;
- int change, id;
-
- id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- if (id == 0)
- old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
- else
- old = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE);
- new = (~ucontrol->value.integer.value[0] << 7 & 0x80) | (old & ~0x80);
- change = (new != old);
- if (change) {
- if (id == 0)
- stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new);
- else
- stac9460_2_put(ice, STAC946X_GENERAL_PURPOSE, new);
- }
- return change;
-}
-
-/*
- * Control tabs
- */
-static struct snd_kcontrol_new stac9640_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = stac9460_dac_mute_info,
- .get = stac9460_dac_mute_get,
- .put = stac9460_dac_mute_put,
- .private_value = 1
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Volume",
- .info = stac9460_dac_vol_info,
- .get = stac9460_dac_vol_get,
- .put = stac9460_dac_vol_put,
- .private_value = 1,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "MIC/Line switch",
- .count = 2,
- .info = stac9460_mic_sw_info,
- .get = stac9460_mic_sw_get,
- .put = stac9460_mic_sw_put,
-
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "DAC Switch",
- .count = 8,
- .info = stac9460_dac_mute_info,
- .get = stac9460_dac_mute_get,
- .put = stac9460_dac_mute_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "DAC Volume",
- .count = 8,
- .info = stac9460_dac_vol_info,
- .get = stac9460_dac_vol_get,
- .put = stac9460_dac_vol_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "ADC Switch",
- .count = 2,
- .info = stac9460_adc_mute_info,
- .get = stac9460_adc_mute_get,
- .put = stac9460_adc_mute_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "ADC Volume",
- .count = 2,
- .info = stac9460_adc_vol_info,
- .get = stac9460_adc_vol_get,
- .put = stac9460_adc_vol_put,
-
- }
-};
-
-
-
-/*INIT*/
-static int __devinit wtm_add_controls(struct snd_ice1712 *ice)
-{
- unsigned int i;
- int err;
-
- for (i = 0; i < ARRAY_SIZE(stac9640_controls); i++) {
- err = snd_ctl_add(ice->card,
- snd_ctl_new1(&stac9640_controls[i], ice));
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-static int __devinit wtm_init(struct snd_ice1712 *ice)
-{
- static unsigned short stac_inits_prodigy[] = {
- STAC946X_RESET, 0,
- (unsigned short)-1
- };
- unsigned short *p;
-
- /*WTM 192M*/
- ice->num_total_dacs = 8;
- ice->num_total_adcs = 4;
- ice->force_rdma1 = 1;
-
- /*initialize codec*/
- p = stac_inits_prodigy;
- for (; *p != (unsigned short)-1; p += 2) {
- stac9460_put(ice, p[0], p[1]);
- stac9460_2_put(ice, p[0], p[1]);
- }
- return 0;
-}
-
-
-static unsigned char wtm_eeprom[] __devinitdata = {
- 0x47, /*SYSCONF: clock 192KHz, 4ADC, 8DAC */
- 0x80, /* ACLINK : I2S */
- 0xf8, /* I2S: vol; 96k, 24bit, 192k */
- 0xc1 /*SPDIF: out-en, spidf ext out*/,
- 0x9f, /* GPIO_DIR */
- 0xff, /* GPIO_DIR1 */
- 0x7f, /* GPIO_DIR2 */
- 0x9f, /* GPIO_MASK */
- 0xff, /* GPIO_MASK1 */
- 0x7f, /* GPIO_MASK2 */
- 0x16, /* GPIO_STATE */
- 0x80, /* GPIO_STATE1 */
- 0x00, /* GPIO_STATE2 */
-};
-
-
-/*entry point*/
-struct snd_ice1712_card_info snd_vt1724_wtm_cards[] __devinitdata = {
- {
- .subvendor = VT1724_SUBDEVICE_WTM,
- .name = "ESI Waveterminal 192M",
- .model = "WT192M",
- .chip_init = wtm_init,
- .build_controls = wtm_add_controls,
- .eeprom_size = sizeof(wtm_eeprom),
- .eeprom_data = wtm_eeprom,
- },
- {} /*terminator*/
-};
diff --git a/ANDROID_3.4.5/sound/pci/ice1712/wtm.h b/ANDROID_3.4.5/sound/pci/ice1712/wtm.h
deleted file mode 100644
index 423c1a20..00000000
--- a/ANDROID_3.4.5/sound/pci/ice1712/wtm.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __SOUND_WTM_H
-#define __SOUND_WTM_H
-
-/* ID */
-#define WTM_DEVICE_DESC "{EGO SYS INC,WaveTerminal 192M},"
-#define VT1724_SUBDEVICE_WTM 0x36495345 /* WT192M ver1.0 */
-
-/*
- *chip addresses on I2C bus
- */
-
-#define AK4114_ADDR 0x20 /*S/PDIF receiver*/
-#define STAC9460_I2C_ADDR 0x54 /* ADC*2 | DAC*6 */
-#define STAC9460_2_I2C_ADDR 0x56 /* ADC|DAC *2 */
-
-
-extern struct snd_ice1712_card_info snd_vt1724_wtm_cards[];
-
-#endif /* __SOUND_WTM_H */
-
diff --git a/ANDROID_3.4.5/sound/pci/intel8x0.c b/ANDROID_3.4.5/sound/pci/intel8x0.c
deleted file mode 100644
index e0a4263b..00000000
--- a/ANDROID_3.4.5/sound/pci/intel8x0.c
+++ /dev/null
@@ -1,3364 +0,0 @@
-/*
- * ALSA driver for Intel ICH (i8x0) chipsets
- *
- * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This code also contains alpha support for SiS 735 chipsets provided
- * by Mike Pieper <mptei@users.sourceforge.net>. We have no datasheet
- * for SiS735, so the code is not fully functional.
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/info.h>
-#include <sound/initval.h>
-/* for 440MX workaround */
-#include <asm/pgtable.h>
-#include <asm/cacheflush.h>
-
-#ifdef CONFIG_KVM_GUEST
-#include <linux/kvm_para.h>
-#else
-#define kvm_para_available() (0)
-#endif
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7012; Ali 5455");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Intel,82801AA-ICH},"
- "{Intel,82901AB-ICH0},"
- "{Intel,82801BA-ICH2},"
- "{Intel,82801CA-ICH3},"
- "{Intel,82801DB-ICH4},"
- "{Intel,ICH5},"
- "{Intel,ICH6},"
- "{Intel,ICH7},"
- "{Intel,6300ESB},"
- "{Intel,ESB2},"
- "{Intel,MX440},"
- "{SiS,SI7012},"
- "{NVidia,nForce Audio},"
- "{NVidia,nForce2 Audio},"
- "{NVidia,nForce3 Audio},"
- "{NVidia,MCP04},"
- "{NVidia,MCP501},"
- "{NVidia,CK804},"
- "{NVidia,CK8},"
- "{NVidia,CK8S},"
- "{AMD,AMD768},"
- "{AMD,AMD8111},"
- "{ALI,M5455}}");
-
-static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
-static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-static int ac97_clock;
-static char *ac97_quirk;
-static bool buggy_semaphore;
-static int buggy_irq = -1; /* auto-check */
-static bool xbox;
-static int spdif_aclink = -1;
-static int inside_vm = -1;
-
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for Intel i8x0 soundcard.");
-module_param(ac97_clock, int, 0444);
-MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = whitelist + auto-detect, 1 = force autodetect).");
-module_param(ac97_quirk, charp, 0444);
-MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
-module_param(buggy_semaphore, bool, 0444);
-MODULE_PARM_DESC(buggy_semaphore, "Enable workaround for hardwares with problematic codec semaphores.");
-module_param(buggy_irq, bint, 0444);
-MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards.");
-module_param(xbox, bool, 0444);
-MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection.");
-module_param(spdif_aclink, int, 0444);
-MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link.");
-module_param(inside_vm, bint, 0444);
-MODULE_PARM_DESC(inside_vm, "KVM/Parallels optimization.");
-
-/* just for backward compatibility */
-static bool enable;
-module_param(enable, bool, 0444);
-static int joystick;
-module_param(joystick, int, 0444);
-
-/*
- * Direct registers
- */
-enum { DEVICE_INTEL, DEVICE_INTEL_ICH4, DEVICE_SIS, DEVICE_ALI, DEVICE_NFORCE };
-
-#define ICHREG(x) ICH_REG_##x
-
-#define DEFINE_REGSET(name,base) \
-enum { \
- ICH_REG_##name##_BDBAR = base + 0x0, /* dword - buffer descriptor list base address */ \
- ICH_REG_##name##_CIV = base + 0x04, /* byte - current index value */ \
- ICH_REG_##name##_LVI = base + 0x05, /* byte - last valid index */ \
- ICH_REG_##name##_SR = base + 0x06, /* byte - status register */ \
- ICH_REG_##name##_PICB = base + 0x08, /* word - position in current buffer */ \
- ICH_REG_##name##_PIV = base + 0x0a, /* byte - prefetched index value */ \
- ICH_REG_##name##_CR = base + 0x0b, /* byte - control register */ \
-};
-
-/* busmaster blocks */
-DEFINE_REGSET(OFF, 0); /* offset */
-DEFINE_REGSET(PI, 0x00); /* PCM in */
-DEFINE_REGSET(PO, 0x10); /* PCM out */
-DEFINE_REGSET(MC, 0x20); /* Mic in */
-
-/* ICH4 busmaster blocks */
-DEFINE_REGSET(MC2, 0x40); /* Mic in 2 */
-DEFINE_REGSET(PI2, 0x50); /* PCM in 2 */
-DEFINE_REGSET(SP, 0x60); /* SPDIF out */
-
-/* values for each busmaster block */
-
-/* LVI */
-#define ICH_REG_LVI_MASK 0x1f
-
-/* SR */
-#define ICH_FIFOE 0x10 /* FIFO error */
-#define ICH_BCIS 0x08 /* buffer completion interrupt status */
-#define ICH_LVBCI 0x04 /* last valid buffer completion interrupt */
-#define ICH_CELV 0x02 /* current equals last valid */
-#define ICH_DCH 0x01 /* DMA controller halted */
-
-/* PIV */
-#define ICH_REG_PIV_MASK 0x1f /* mask */
-
-/* CR */
-#define ICH_IOCE 0x10 /* interrupt on completion enable */
-#define ICH_FEIE 0x08 /* fifo error interrupt enable */
-#define ICH_LVBIE 0x04 /* last valid buffer interrupt enable */
-#define ICH_RESETREGS 0x02 /* reset busmaster registers */
-#define ICH_STARTBM 0x01 /* start busmaster operation */
-
-
-/* global block */
-#define ICH_REG_GLOB_CNT 0x2c /* dword - global control */
-#define ICH_PCM_SPDIF_MASK 0xc0000000 /* s/pdif pcm slot mask (ICH4) */
-#define ICH_PCM_SPDIF_NONE 0x00000000 /* reserved - undefined */
-#define ICH_PCM_SPDIF_78 0x40000000 /* s/pdif pcm on slots 7&8 */
-#define ICH_PCM_SPDIF_69 0x80000000 /* s/pdif pcm on slots 6&9 */
-#define ICH_PCM_SPDIF_1011 0xc0000000 /* s/pdif pcm on slots 10&11 */
-#define ICH_PCM_20BIT 0x00400000 /* 20-bit samples (ICH4) */
-#define ICH_PCM_246_MASK 0x00300000 /* chan mask (not all chips) */
-#define ICH_PCM_8 0x00300000 /* 8 channels (not all chips) */
-#define ICH_PCM_6 0x00200000 /* 6 channels (not all chips) */
-#define ICH_PCM_4 0x00100000 /* 4 channels (not all chips) */
-#define ICH_PCM_2 0x00000000 /* 2 channels (stereo) */
-#define ICH_SIS_PCM_246_MASK 0x000000c0 /* 6 channels (SIS7012) */
-#define ICH_SIS_PCM_6 0x00000080 /* 6 channels (SIS7012) */
-#define ICH_SIS_PCM_4 0x00000040 /* 4 channels (SIS7012) */
-#define ICH_SIS_PCM_2 0x00000000 /* 2 channels (SIS7012) */
-#define ICH_TRIE 0x00000040 /* tertiary resume interrupt enable */
-#define ICH_SRIE 0x00000020 /* secondary resume interrupt enable */
-#define ICH_PRIE 0x00000010 /* primary resume interrupt enable */
-#define ICH_ACLINK 0x00000008 /* AClink shut off */
-#define ICH_AC97WARM 0x00000004 /* AC'97 warm reset */
-#define ICH_AC97COLD 0x00000002 /* AC'97 cold reset */
-#define ICH_GIE 0x00000001 /* GPI interrupt enable */
-#define ICH_REG_GLOB_STA 0x30 /* dword - global status */
-#define ICH_TRI 0x20000000 /* ICH4: tertiary (AC_SDIN2) resume interrupt */
-#define ICH_TCR 0x10000000 /* ICH4: tertiary (AC_SDIN2) codec ready */
-#define ICH_BCS 0x08000000 /* ICH4: bit clock stopped */
-#define ICH_SPINT 0x04000000 /* ICH4: S/PDIF interrupt */
-#define ICH_P2INT 0x02000000 /* ICH4: PCM2-In interrupt */
-#define ICH_M2INT 0x01000000 /* ICH4: Mic2-In interrupt */
-#define ICH_SAMPLE_CAP 0x00c00000 /* ICH4: sample capability bits (RO) */
-#define ICH_SAMPLE_16_20 0x00400000 /* ICH4: 16- and 20-bit samples */
-#define ICH_MULTICHAN_CAP 0x00300000 /* ICH4: multi-channel capability bits (RO) */
-#define ICH_SIS_TRI 0x00080000 /* SIS: tertiary resume irq */
-#define ICH_SIS_TCR 0x00040000 /* SIS: tertiary codec ready */
-#define ICH_MD3 0x00020000 /* modem power down semaphore */
-#define ICH_AD3 0x00010000 /* audio power down semaphore */
-#define ICH_RCS 0x00008000 /* read completion status */
-#define ICH_BIT3 0x00004000 /* bit 3 slot 12 */
-#define ICH_BIT2 0x00002000 /* bit 2 slot 12 */
-#define ICH_BIT1 0x00001000 /* bit 1 slot 12 */
-#define ICH_SRI 0x00000800 /* secondary (AC_SDIN1) resume interrupt */
-#define ICH_PRI 0x00000400 /* primary (AC_SDIN0) resume interrupt */
-#define ICH_SCR 0x00000200 /* secondary (AC_SDIN1) codec ready */
-#define ICH_PCR 0x00000100 /* primary (AC_SDIN0) codec ready */
-#define ICH_MCINT 0x00000080 /* MIC capture interrupt */
-#define ICH_POINT 0x00000040 /* playback interrupt */
-#define ICH_PIINT 0x00000020 /* capture interrupt */
-#define ICH_NVSPINT 0x00000010 /* nforce spdif interrupt */
-#define ICH_MOINT 0x00000004 /* modem playback interrupt */
-#define ICH_MIINT 0x00000002 /* modem capture interrupt */
-#define ICH_GSCI 0x00000001 /* GPI status change interrupt */
-#define ICH_REG_ACC_SEMA 0x34 /* byte - codec write semaphore */
-#define ICH_CAS 0x01 /* codec access semaphore */
-#define ICH_REG_SDM 0x80
-#define ICH_DI2L_MASK 0x000000c0 /* PCM In 2, Mic In 2 data in line */
-#define ICH_DI2L_SHIFT 6
-#define ICH_DI1L_MASK 0x00000030 /* PCM In 1, Mic In 1 data in line */
-#define ICH_DI1L_SHIFT 4
-#define ICH_SE 0x00000008 /* steer enable */
-#define ICH_LDI_MASK 0x00000003 /* last codec read data input */
-
-#define ICH_MAX_FRAGS 32 /* max hw frags */
-
-
-/*
- * registers for Ali5455
- */
-
-/* ALi 5455 busmaster blocks */
-DEFINE_REGSET(AL_PI, 0x40); /* ALi PCM in */
-DEFINE_REGSET(AL_PO, 0x50); /* Ali PCM out */
-DEFINE_REGSET(AL_MC, 0x60); /* Ali Mic in */
-DEFINE_REGSET(AL_CDC_SPO, 0x70); /* Ali Codec SPDIF out */
-DEFINE_REGSET(AL_CENTER, 0x80); /* Ali center out */
-DEFINE_REGSET(AL_LFE, 0x90); /* Ali center out */
-DEFINE_REGSET(AL_CLR_SPI, 0xa0); /* Ali Controller SPDIF in */
-DEFINE_REGSET(AL_CLR_SPO, 0xb0); /* Ali Controller SPDIF out */
-DEFINE_REGSET(AL_I2S, 0xc0); /* Ali I2S in */
-DEFINE_REGSET(AL_PI2, 0xd0); /* Ali PCM2 in */
-DEFINE_REGSET(AL_MC2, 0xe0); /* Ali Mic2 in */
-
-enum {
- ICH_REG_ALI_SCR = 0x00, /* System Control Register */
- ICH_REG_ALI_SSR = 0x04, /* System Status Register */
- ICH_REG_ALI_DMACR = 0x08, /* DMA Control Register */
- ICH_REG_ALI_FIFOCR1 = 0x0c, /* FIFO Control Register 1 */
- ICH_REG_ALI_INTERFACECR = 0x10, /* Interface Control Register */
- ICH_REG_ALI_INTERRUPTCR = 0x14, /* Interrupt control Register */
- ICH_REG_ALI_INTERRUPTSR = 0x18, /* Interrupt Status Register */
- ICH_REG_ALI_FIFOCR2 = 0x1c, /* FIFO Control Register 2 */
- ICH_REG_ALI_CPR = 0x20, /* Command Port Register */
- ICH_REG_ALI_CPR_ADDR = 0x22, /* ac97 addr write */
- ICH_REG_ALI_SPR = 0x24, /* Status Port Register */
- ICH_REG_ALI_SPR_ADDR = 0x26, /* ac97 addr read */
- ICH_REG_ALI_FIFOCR3 = 0x2c, /* FIFO Control Register 3 */
- ICH_REG_ALI_TTSR = 0x30, /* Transmit Tag Slot Register */
- ICH_REG_ALI_RTSR = 0x34, /* Receive Tag Slot Register */
- ICH_REG_ALI_CSPSR = 0x38, /* Command/Status Port Status Register */
- ICH_REG_ALI_CAS = 0x3c, /* Codec Write Semaphore Register */
- ICH_REG_ALI_HWVOL = 0xf0, /* hardware volume control/status */
- ICH_REG_ALI_I2SCR = 0xf4, /* I2S control/status */
- ICH_REG_ALI_SPDIFCSR = 0xf8, /* spdif channel status register */
- ICH_REG_ALI_SPDIFICS = 0xfc, /* spdif interface control/status */
-};
-
-#define ALI_CAS_SEM_BUSY 0x80000000
-#define ALI_CPR_ADDR_SECONDARY 0x100
-#define ALI_CPR_ADDR_READ 0x80
-#define ALI_CSPSR_CODEC_READY 0x08
-#define ALI_CSPSR_READ_OK 0x02
-#define ALI_CSPSR_WRITE_OK 0x01
-
-/* interrupts for the whole chip by interrupt status register finish */
-
-#define ALI_INT_MICIN2 (1<<26)
-#define ALI_INT_PCMIN2 (1<<25)
-#define ALI_INT_I2SIN (1<<24)
-#define ALI_INT_SPDIFOUT (1<<23) /* controller spdif out INTERRUPT */
-#define ALI_INT_SPDIFIN (1<<22)
-#define ALI_INT_LFEOUT (1<<21)
-#define ALI_INT_CENTEROUT (1<<20)
-#define ALI_INT_CODECSPDIFOUT (1<<19)
-#define ALI_INT_MICIN (1<<18)
-#define ALI_INT_PCMOUT (1<<17)
-#define ALI_INT_PCMIN (1<<16)
-#define ALI_INT_CPRAIS (1<<7) /* command port available */
-#define ALI_INT_SPRAIS (1<<5) /* status port available */
-#define ALI_INT_GPIO (1<<1)
-#define ALI_INT_MASK (ALI_INT_SPDIFOUT|ALI_INT_CODECSPDIFOUT|\
- ALI_INT_MICIN|ALI_INT_PCMOUT|ALI_INT_PCMIN)
-
-#define ICH_ALI_SC_RESET (1<<31) /* master reset */
-#define ICH_ALI_SC_AC97_DBL (1<<30)
-#define ICH_ALI_SC_CODEC_SPDF (3<<20) /* 1=7/8, 2=6/9, 3=10/11 */
-#define ICH_ALI_SC_IN_BITS (3<<18)
-#define ICH_ALI_SC_OUT_BITS (3<<16)
-#define ICH_ALI_SC_6CH_CFG (3<<14)
-#define ICH_ALI_SC_PCM_4 (1<<8)
-#define ICH_ALI_SC_PCM_6 (2<<8)
-#define ICH_ALI_SC_PCM_246_MASK (3<<8)
-
-#define ICH_ALI_SS_SEC_ID (3<<5)
-#define ICH_ALI_SS_PRI_ID (3<<3)
-
-#define ICH_ALI_IF_AC97SP (1<<21)
-#define ICH_ALI_IF_MC (1<<20)
-#define ICH_ALI_IF_PI (1<<19)
-#define ICH_ALI_IF_MC2 (1<<18)
-#define ICH_ALI_IF_PI2 (1<<17)
-#define ICH_ALI_IF_LINE_SRC (1<<15) /* 0/1 = slot 3/6 */
-#define ICH_ALI_IF_MIC_SRC (1<<14) /* 0/1 = slot 3/6 */
-#define ICH_ALI_IF_SPDF_SRC (3<<12) /* 00 = PCM, 01 = AC97-in, 10 = spdif-in, 11 = i2s */
-#define ICH_ALI_IF_AC97_OUT (3<<8) /* 00 = PCM, 10 = spdif-in, 11 = i2s */
-#define ICH_ALI_IF_PO_SPDF (1<<3)
-#define ICH_ALI_IF_PO (1<<1)
-
-/*
- *
- */
-
-enum {
- ICHD_PCMIN,
- ICHD_PCMOUT,
- ICHD_MIC,
- ICHD_MIC2,
- ICHD_PCM2IN,
- ICHD_SPBAR,
- ICHD_LAST = ICHD_SPBAR
-};
-enum {
- NVD_PCMIN,
- NVD_PCMOUT,
- NVD_MIC,
- NVD_SPBAR,
- NVD_LAST = NVD_SPBAR
-};
-enum {
- ALID_PCMIN,
- ALID_PCMOUT,
- ALID_MIC,
- ALID_AC97SPDIFOUT,
- ALID_SPDIFIN,
- ALID_SPDIFOUT,
- ALID_LAST = ALID_SPDIFOUT
-};
-
-#define get_ichdev(substream) (substream->runtime->private_data)
-
-struct ichdev {
- unsigned int ichd; /* ich device number */
- unsigned long reg_offset; /* offset to bmaddr */
- u32 *bdbar; /* CPU address (32bit) */
- unsigned int bdbar_addr; /* PCI bus address (32bit) */
- struct snd_pcm_substream *substream;
- unsigned int physbuf; /* physical address (32bit) */
- unsigned int size;
- unsigned int fragsize;
- unsigned int fragsize1;
- unsigned int position;
- unsigned int pos_shift;
- unsigned int last_pos;
- int frags;
- int lvi;
- int lvi_frag;
- int civ;
- int ack;
- int ack_reload;
- unsigned int ack_bit;
- unsigned int roff_sr;
- unsigned int roff_picb;
- unsigned int int_sta_mask; /* interrupt status mask */
- unsigned int ali_slot; /* ALI DMA slot */
- struct ac97_pcm *pcm;
- int pcm_open_flag;
- unsigned int page_attr_changed: 1;
- unsigned int suspended: 1;
-};
-
-struct intel8x0 {
- unsigned int device_type;
-
- int irq;
-
- void __iomem *addr;
- void __iomem *bmaddr;
-
- struct pci_dev *pci;
- struct snd_card *card;
-
- int pcm_devs;
- struct snd_pcm *pcm[6];
- struct ichdev ichd[6];
-
- unsigned multi4: 1,
- multi6: 1,
- multi8 :1,
- dra: 1,
- smp20bit: 1;
- unsigned in_ac97_init: 1,
- in_sdin_init: 1;
- unsigned in_measurement: 1; /* during ac97 clock measurement */
- unsigned fix_nocache: 1; /* workaround for 440MX */
- unsigned buggy_irq: 1; /* workaround for buggy mobos */
- unsigned xbox: 1; /* workaround for Xbox AC'97 detection */
- unsigned buggy_semaphore: 1; /* workaround for buggy codec semaphore */
- unsigned inside_vm: 1; /* enable VM optimization */
-
- int spdif_idx; /* SPDIF BAR index; *_SPBAR or -1 if use PCMOUT */
- unsigned int sdm_saved; /* SDM reg value */
-
- struct snd_ac97_bus *ac97_bus;
- struct snd_ac97 *ac97[3];
- unsigned int ac97_sdin[3];
- unsigned int max_codecs, ncodecs;
- unsigned int *codec_bit;
- unsigned int codec_isr_bits;
- unsigned int codec_ready_bits;
-
- spinlock_t reg_lock;
-
- u32 bdbars_count;
- struct snd_dma_buffer bdbars;
- u32 int_sta_reg; /* interrupt status register */
- u32 int_sta_mask; /* interrupt status mask */
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_intel8x0_ids) = {
- { PCI_VDEVICE(INTEL, 0x2415), DEVICE_INTEL }, /* 82801AA */
- { PCI_VDEVICE(INTEL, 0x2425), DEVICE_INTEL }, /* 82901AB */
- { PCI_VDEVICE(INTEL, 0x2445), DEVICE_INTEL }, /* 82801BA */
- { PCI_VDEVICE(INTEL, 0x2485), DEVICE_INTEL }, /* ICH3 */
- { PCI_VDEVICE(INTEL, 0x24c5), DEVICE_INTEL_ICH4 }, /* ICH4 */
- { PCI_VDEVICE(INTEL, 0x24d5), DEVICE_INTEL_ICH4 }, /* ICH5 */
- { PCI_VDEVICE(INTEL, 0x25a6), DEVICE_INTEL_ICH4 }, /* ESB */
- { PCI_VDEVICE(INTEL, 0x266e), DEVICE_INTEL_ICH4 }, /* ICH6 */
- { PCI_VDEVICE(INTEL, 0x27de), DEVICE_INTEL_ICH4 }, /* ICH7 */
- { PCI_VDEVICE(INTEL, 0x2698), DEVICE_INTEL_ICH4 }, /* ESB2 */
- { PCI_VDEVICE(INTEL, 0x7195), DEVICE_INTEL }, /* 440MX */
- { PCI_VDEVICE(SI, 0x7012), DEVICE_SIS }, /* SI7012 */
- { PCI_VDEVICE(NVIDIA, 0x01b1), DEVICE_NFORCE }, /* NFORCE */
- { PCI_VDEVICE(NVIDIA, 0x003a), DEVICE_NFORCE }, /* MCP04 */
- { PCI_VDEVICE(NVIDIA, 0x006a), DEVICE_NFORCE }, /* NFORCE2 */
- { PCI_VDEVICE(NVIDIA, 0x0059), DEVICE_NFORCE }, /* CK804 */
- { PCI_VDEVICE(NVIDIA, 0x008a), DEVICE_NFORCE }, /* CK8 */
- { PCI_VDEVICE(NVIDIA, 0x00da), DEVICE_NFORCE }, /* NFORCE3 */
- { PCI_VDEVICE(NVIDIA, 0x00ea), DEVICE_NFORCE }, /* CK8S */
- { PCI_VDEVICE(NVIDIA, 0x026b), DEVICE_NFORCE }, /* MCP51 */
- { PCI_VDEVICE(AMD, 0x746d), DEVICE_INTEL }, /* AMD8111 */
- { PCI_VDEVICE(AMD, 0x7445), DEVICE_INTEL }, /* AMD768 */
- { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
-
-/*
- * Lowlevel I/O - busmaster
- */
-
-static inline u8 igetbyte(struct intel8x0 *chip, u32 offset)
-{
- return ioread8(chip->bmaddr + offset);
-}
-
-static inline u16 igetword(struct intel8x0 *chip, u32 offset)
-{
- return ioread16(chip->bmaddr + offset);
-}
-
-static inline u32 igetdword(struct intel8x0 *chip, u32 offset)
-{
- return ioread32(chip->bmaddr + offset);
-}
-
-static inline void iputbyte(struct intel8x0 *chip, u32 offset, u8 val)
-{
- iowrite8(val, chip->bmaddr + offset);
-}
-
-static inline void iputword(struct intel8x0 *chip, u32 offset, u16 val)
-{
- iowrite16(val, chip->bmaddr + offset);
-}
-
-static inline void iputdword(struct intel8x0 *chip, u32 offset, u32 val)
-{
- iowrite32(val, chip->bmaddr + offset);
-}
-
-/*
- * Lowlevel I/O - AC'97 registers
- */
-
-static inline u16 iagetword(struct intel8x0 *chip, u32 offset)
-{
- return ioread16(chip->addr + offset);
-}
-
-static inline void iaputword(struct intel8x0 *chip, u32 offset, u16 val)
-{
- iowrite16(val, chip->addr + offset);
-}
-
-/*
- * Basic I/O
- */
-
-/*
- * access to AC97 codec via normal i/o (for ICH and SIS7012)
- */
-
-static int snd_intel8x0_codec_semaphore(struct intel8x0 *chip, unsigned int codec)
-{
- int time;
-
- if (codec > 2)
- return -EIO;
- if (chip->in_sdin_init) {
- /* we don't know the ready bit assignment at the moment */
- /* so we check any */
- codec = chip->codec_isr_bits;
- } else {
- codec = chip->codec_bit[chip->ac97_sdin[codec]];
- }
-
- /* codec ready ? */
- if ((igetdword(chip, ICHREG(GLOB_STA)) & codec) == 0)
- return -EIO;
-
- if (chip->buggy_semaphore)
- return 0; /* just ignore ... */
-
- /* Anyone holding a semaphore for 1 msec should be shot... */
- time = 100;
- do {
- if (!(igetbyte(chip, ICHREG(ACC_SEMA)) & ICH_CAS))
- return 0;
- udelay(10);
- } while (time--);
-
- /* access to some forbidden (non existent) ac97 registers will not
- * reset the semaphore. So even if you don't get the semaphore, still
- * continue the access. We don't need the semaphore anyway. */
- snd_printk(KERN_ERR "codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
- igetbyte(chip, ICHREG(ACC_SEMA)), igetdword(chip, ICHREG(GLOB_STA)));
- iagetword(chip, 0); /* clear semaphore flag */
- /* I don't care about the semaphore */
- return -EBUSY;
-}
-
-static void snd_intel8x0_codec_write(struct snd_ac97 *ac97,
- unsigned short reg,
- unsigned short val)
-{
- struct intel8x0 *chip = ac97->private_data;
-
- if (snd_intel8x0_codec_semaphore(chip, ac97->num) < 0) {
- if (! chip->in_ac97_init)
- snd_printk(KERN_ERR "codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
- }
- iaputword(chip, reg + ac97->num * 0x80, val);
-}
-
-static unsigned short snd_intel8x0_codec_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- struct intel8x0 *chip = ac97->private_data;
- unsigned short res;
- unsigned int tmp;
-
- if (snd_intel8x0_codec_semaphore(chip, ac97->num) < 0) {
- if (! chip->in_ac97_init)
- snd_printk(KERN_ERR "codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
- res = 0xffff;
- } else {
- res = iagetword(chip, reg + ac97->num * 0x80);
- if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) {
- /* reset RCS and preserve other R/WC bits */
- iputdword(chip, ICHREG(GLOB_STA), tmp &
- ~(chip->codec_ready_bits | ICH_GSCI));
- if (! chip->in_ac97_init)
- snd_printk(KERN_ERR "codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
- res = 0xffff;
- }
- }
- return res;
-}
-
-static void __devinit snd_intel8x0_codec_read_test(struct intel8x0 *chip,
- unsigned int codec)
-{
- unsigned int tmp;
-
- if (snd_intel8x0_codec_semaphore(chip, codec) >= 0) {
- iagetword(chip, codec * 0x80);
- if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) {
- /* reset RCS and preserve other R/WC bits */
- iputdword(chip, ICHREG(GLOB_STA), tmp &
- ~(chip->codec_ready_bits | ICH_GSCI));
- }
- }
-}
-
-/*
- * access to AC97 for Ali5455
- */
-static int snd_intel8x0_ali_codec_ready(struct intel8x0 *chip, int mask)
-{
- int count = 0;
- for (count = 0; count < 0x7f; count++) {
- int val = igetbyte(chip, ICHREG(ALI_CSPSR));
- if (val & mask)
- return 0;
- }
- if (! chip->in_ac97_init)
- snd_printd(KERN_WARNING "intel8x0: AC97 codec ready timeout.\n");
- return -EBUSY;
-}
-
-static int snd_intel8x0_ali_codec_semaphore(struct intel8x0 *chip)
-{
- int time = 100;
- if (chip->buggy_semaphore)
- return 0; /* just ignore ... */
- while (--time && (igetdword(chip, ICHREG(ALI_CAS)) & ALI_CAS_SEM_BUSY))
- udelay(1);
- if (! time && ! chip->in_ac97_init)
- snd_printk(KERN_WARNING "ali_codec_semaphore timeout\n");
- return snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_CODEC_READY);
-}
-
-static unsigned short snd_intel8x0_ali_codec_read(struct snd_ac97 *ac97, unsigned short reg)
-{
- struct intel8x0 *chip = ac97->private_data;
- unsigned short data = 0xffff;
-
- if (snd_intel8x0_ali_codec_semaphore(chip))
- goto __err;
- reg |= ALI_CPR_ADDR_READ;
- if (ac97->num)
- reg |= ALI_CPR_ADDR_SECONDARY;
- iputword(chip, ICHREG(ALI_CPR_ADDR), reg);
- if (snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_READ_OK))
- goto __err;
- data = igetword(chip, ICHREG(ALI_SPR));
- __err:
- return data;
-}
-
-static void snd_intel8x0_ali_codec_write(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short val)
-{
- struct intel8x0 *chip = ac97->private_data;
-
- if (snd_intel8x0_ali_codec_semaphore(chip))
- return;
- iputword(chip, ICHREG(ALI_CPR), val);
- if (ac97->num)
- reg |= ALI_CPR_ADDR_SECONDARY;
- iputword(chip, ICHREG(ALI_CPR_ADDR), reg);
- snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_WRITE_OK);
-}
-
-
-/*
- * DMA I/O
- */
-static void snd_intel8x0_setup_periods(struct intel8x0 *chip, struct ichdev *ichdev)
-{
- int idx;
- u32 *bdbar = ichdev->bdbar;
- unsigned long port = ichdev->reg_offset;
-
- iputdword(chip, port + ICH_REG_OFF_BDBAR, ichdev->bdbar_addr);
- if (ichdev->size == ichdev->fragsize) {
- ichdev->ack_reload = ichdev->ack = 2;
- ichdev->fragsize1 = ichdev->fragsize >> 1;
- for (idx = 0; idx < (ICH_REG_LVI_MASK + 1) * 2; idx += 4) {
- bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf);
- bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */
- ichdev->fragsize1 >> ichdev->pos_shift);
- bdbar[idx + 2] = cpu_to_le32(ichdev->physbuf + (ichdev->size >> 1));
- bdbar[idx + 3] = cpu_to_le32(0x80000000 | /* interrupt on completion */
- ichdev->fragsize1 >> ichdev->pos_shift);
- }
- ichdev->frags = 2;
- } else {
- ichdev->ack_reload = ichdev->ack = 1;
- ichdev->fragsize1 = ichdev->fragsize;
- for (idx = 0; idx < (ICH_REG_LVI_MASK + 1) * 2; idx += 2) {
- bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf +
- (((idx >> 1) * ichdev->fragsize) %
- ichdev->size));
- bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */
- ichdev->fragsize >> ichdev->pos_shift);
-#if 0
- printk(KERN_DEBUG "bdbar[%i] = 0x%x [0x%x]\n",
- idx + 0, bdbar[idx + 0], bdbar[idx + 1]);
-#endif
- }
- ichdev->frags = ichdev->size / ichdev->fragsize;
- }
- iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi = ICH_REG_LVI_MASK);
- ichdev->civ = 0;
- iputbyte(chip, port + ICH_REG_OFF_CIV, 0);
- ichdev->lvi_frag = ICH_REG_LVI_MASK % ichdev->frags;
- ichdev->position = 0;
-#if 0
- printk(KERN_DEBUG "lvi_frag = %i, frags = %i, period_size = 0x%x, "
- "period_size1 = 0x%x\n",
- ichdev->lvi_frag, ichdev->frags, ichdev->fragsize,
- ichdev->fragsize1);
-#endif
- /* clear interrupts */
- iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
-}
-
-#ifdef __i386__
-/*
- * Intel 82443MX running a 100MHz processor system bus has a hardware bug,
- * which aborts PCI busmaster for audio transfer. A workaround is to set
- * the pages as non-cached. For details, see the errata in
- * http://download.intel.com/design/chipsets/specupdt/24505108.pdf
- */
-static void fill_nocache(void *buf, int size, int nocache)
-{
- size = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
- if (nocache)
- set_pages_uc(virt_to_page(buf), size);
- else
- set_pages_wb(virt_to_page(buf), size);
-}
-#else
-#define fill_nocache(buf, size, nocache) do { ; } while (0)
-#endif
-
-/*
- * Interrupt handler
- */
-
-static inline void snd_intel8x0_update(struct intel8x0 *chip, struct ichdev *ichdev)
-{
- unsigned long port = ichdev->reg_offset;
- unsigned long flags;
- int status, civ, i, step;
- int ack = 0;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- status = igetbyte(chip, port + ichdev->roff_sr);
- civ = igetbyte(chip, port + ICH_REG_OFF_CIV);
- if (!(status & ICH_BCIS)) {
- step = 0;
- } else if (civ == ichdev->civ) {
- // snd_printd("civ same %d\n", civ);
- step = 1;
- ichdev->civ++;
- ichdev->civ &= ICH_REG_LVI_MASK;
- } else {
- step = civ - ichdev->civ;
- if (step < 0)
- step += ICH_REG_LVI_MASK + 1;
- // if (step != 1)
- // snd_printd("step = %d, %d -> %d\n", step, ichdev->civ, civ);
- ichdev->civ = civ;
- }
-
- ichdev->position += step * ichdev->fragsize1;
- if (! chip->in_measurement)
- ichdev->position %= ichdev->size;
- ichdev->lvi += step;
- ichdev->lvi &= ICH_REG_LVI_MASK;
- iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi);
- for (i = 0; i < step; i++) {
- ichdev->lvi_frag++;
- ichdev->lvi_frag %= ichdev->frags;
- ichdev->bdbar[ichdev->lvi * 2] = cpu_to_le32(ichdev->physbuf + ichdev->lvi_frag * ichdev->fragsize1);
-#if 0
- printk(KERN_DEBUG "new: bdbar[%i] = 0x%x [0x%x], prefetch = %i, "
- "all = 0x%x, 0x%x\n",
- ichdev->lvi * 2, ichdev->bdbar[ichdev->lvi * 2],
- ichdev->bdbar[ichdev->lvi * 2 + 1], inb(ICH_REG_OFF_PIV + port),
- inl(port + 4), inb(port + ICH_REG_OFF_CR));
-#endif
- if (--ichdev->ack == 0) {
- ichdev->ack = ichdev->ack_reload;
- ack = 1;
- }
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (ack && ichdev->substream) {
- snd_pcm_period_elapsed(ichdev->substream);
- }
- iputbyte(chip, port + ichdev->roff_sr,
- status & (ICH_FIFOE | ICH_BCIS | ICH_LVBCI));
-}
-
-static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id)
-{
- struct intel8x0 *chip = dev_id;
- struct ichdev *ichdev;
- unsigned int status;
- unsigned int i;
-
- status = igetdword(chip, chip->int_sta_reg);
- if (status == 0xffffffff) /* we are not yet resumed */
- return IRQ_NONE;
-
- if ((status & chip->int_sta_mask) == 0) {
- if (status) {
- /* ack */
- iputdword(chip, chip->int_sta_reg, status);
- if (! chip->buggy_irq)
- status = 0;
- }
- return IRQ_RETVAL(status);
- }
-
- for (i = 0; i < chip->bdbars_count; i++) {
- ichdev = &chip->ichd[i];
- if (status & ichdev->int_sta_mask)
- snd_intel8x0_update(chip, ichdev);
- }
-
- /* ack them */
- iputdword(chip, chip->int_sta_reg, status & chip->int_sta_mask);
-
- return IRQ_HANDLED;
-}
-
-/*
- * PCM part
- */
-
-static int snd_intel8x0_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
- struct ichdev *ichdev = get_ichdev(substream);
- unsigned char val = 0;
- unsigned long port = ichdev->reg_offset;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_RESUME:
- ichdev->suspended = 0;
- /* fallthru */
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- val = ICH_IOCE | ICH_STARTBM;
- ichdev->last_pos = ichdev->position;
- break;
- case SNDRV_PCM_TRIGGER_SUSPEND:
- ichdev->suspended = 1;
- /* fallthru */
- case SNDRV_PCM_TRIGGER_STOP:
- val = 0;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- val = ICH_IOCE;
- break;
- default:
- return -EINVAL;
- }
- iputbyte(chip, port + ICH_REG_OFF_CR, val);
- if (cmd == SNDRV_PCM_TRIGGER_STOP) {
- /* wait until DMA stopped */
- while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH)) ;
- /* reset whole DMA things */
- iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS);
- }
- return 0;
-}
-
-static int snd_intel8x0_ali_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
- struct ichdev *ichdev = get_ichdev(substream);
- unsigned long port = ichdev->reg_offset;
- static int fiforeg[] = {
- ICHREG(ALI_FIFOCR1), ICHREG(ALI_FIFOCR2), ICHREG(ALI_FIFOCR3)
- };
- unsigned int val, fifo;
-
- val = igetdword(chip, ICHREG(ALI_DMACR));
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_RESUME:
- ichdev->suspended = 0;
- /* fallthru */
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- /* clear FIFO for synchronization of channels */
- fifo = igetdword(chip, fiforeg[ichdev->ali_slot / 4]);
- fifo &= ~(0xff << (ichdev->ali_slot % 4));
- fifo |= 0x83 << (ichdev->ali_slot % 4);
- iputdword(chip, fiforeg[ichdev->ali_slot / 4], fifo);
- }
- iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE);
- val &= ~(1 << (ichdev->ali_slot + 16)); /* clear PAUSE flag */
- /* start DMA */
- iputdword(chip, ICHREG(ALI_DMACR), val | (1 << ichdev->ali_slot));
- break;
- case SNDRV_PCM_TRIGGER_SUSPEND:
- ichdev->suspended = 1;
- /* fallthru */
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- /* pause */
- iputdword(chip, ICHREG(ALI_DMACR), val | (1 << (ichdev->ali_slot + 16)));
- iputbyte(chip, port + ICH_REG_OFF_CR, 0);
- while (igetbyte(chip, port + ICH_REG_OFF_CR))
- ;
- if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
- break;
- /* reset whole DMA things */
- iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS);
- /* clear interrupts */
- iputbyte(chip, port + ICH_REG_OFF_SR,
- igetbyte(chip, port + ICH_REG_OFF_SR) | 0x1e);
- iputdword(chip, ICHREG(ALI_INTERRUPTSR),
- igetdword(chip, ICHREG(ALI_INTERRUPTSR)) & ichdev->int_sta_mask);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int snd_intel8x0_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
- struct ichdev *ichdev = get_ichdev(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int dbl = params_rate(hw_params) > 48000;
- int err;
-
- if (chip->fix_nocache && ichdev->page_attr_changed) {
- fill_nocache(runtime->dma_area, runtime->dma_bytes, 0); /* clear */
- ichdev->page_attr_changed = 0;
- }
- err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
- if (chip->fix_nocache) {
- if (runtime->dma_area && ! ichdev->page_attr_changed) {
- fill_nocache(runtime->dma_area, runtime->dma_bytes, 1);
- ichdev->page_attr_changed = 1;
- }
- }
- if (ichdev->pcm_open_flag) {
- snd_ac97_pcm_close(ichdev->pcm);
- ichdev->pcm_open_flag = 0;
- }
- err = snd_ac97_pcm_open(ichdev->pcm, params_rate(hw_params),
- params_channels(hw_params),
- ichdev->pcm->r[dbl].slots);
- if (err >= 0) {
- ichdev->pcm_open_flag = 1;
- /* Force SPDIF setting */
- if (ichdev->ichd == ICHD_PCMOUT && chip->spdif_idx < 0)
- snd_ac97_set_rate(ichdev->pcm->r[0].codec[0], AC97_SPDIF,
- params_rate(hw_params));
- }
- return err;
-}
-
-static int snd_intel8x0_hw_free(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
- struct ichdev *ichdev = get_ichdev(substream);
-
- if (ichdev->pcm_open_flag) {
- snd_ac97_pcm_close(ichdev->pcm);
- ichdev->pcm_open_flag = 0;
- }
- if (chip->fix_nocache && ichdev->page_attr_changed) {
- fill_nocache(substream->runtime->dma_area, substream->runtime->dma_bytes, 0);
- ichdev->page_attr_changed = 0;
- }
- return snd_pcm_lib_free_pages(substream);
-}
-
-static void snd_intel8x0_setup_pcm_out(struct intel8x0 *chip,
- struct snd_pcm_runtime *runtime)
-{
- unsigned int cnt;
- int dbl = runtime->rate > 48000;
-
- spin_lock_irq(&chip->reg_lock);
- switch (chip->device_type) {
- case DEVICE_ALI:
- cnt = igetdword(chip, ICHREG(ALI_SCR));
- cnt &= ~ICH_ALI_SC_PCM_246_MASK;
- if (runtime->channels == 4 || dbl)
- cnt |= ICH_ALI_SC_PCM_4;
- else if (runtime->channels == 6)
- cnt |= ICH_ALI_SC_PCM_6;
- iputdword(chip, ICHREG(ALI_SCR), cnt);
- break;
- case DEVICE_SIS:
- cnt = igetdword(chip, ICHREG(GLOB_CNT));
- cnt &= ~ICH_SIS_PCM_246_MASK;
- if (runtime->channels == 4 || dbl)
- cnt |= ICH_SIS_PCM_4;
- else if (runtime->channels == 6)
- cnt |= ICH_SIS_PCM_6;
- iputdword(chip, ICHREG(GLOB_CNT), cnt);
- break;
- default:
- cnt = igetdword(chip, ICHREG(GLOB_CNT));
- cnt &= ~(ICH_PCM_246_MASK | ICH_PCM_20BIT);
- if (runtime->channels == 4 || dbl)
- cnt |= ICH_PCM_4;
- else if (runtime->channels == 6)
- cnt |= ICH_PCM_6;
- else if (runtime->channels == 8)
- cnt |= ICH_PCM_8;
- if (chip->device_type == DEVICE_NFORCE) {
- /* reset to 2ch once to keep the 6 channel data in alignment,
- * to start from Front Left always
- */
- if (cnt & ICH_PCM_246_MASK) {
- iputdword(chip, ICHREG(GLOB_CNT), cnt & ~ICH_PCM_246_MASK);
- spin_unlock_irq(&chip->reg_lock);
- msleep(50); /* grrr... */
- spin_lock_irq(&chip->reg_lock);
- }
- } else if (chip->device_type == DEVICE_INTEL_ICH4) {
- if (runtime->sample_bits > 16)
- cnt |= ICH_PCM_20BIT;
- }
- iputdword(chip, ICHREG(GLOB_CNT), cnt);
- break;
- }
- spin_unlock_irq(&chip->reg_lock);
-}
-
-static int snd_intel8x0_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct ichdev *ichdev = get_ichdev(substream);
-
- ichdev->physbuf = runtime->dma_addr;
- ichdev->size = snd_pcm_lib_buffer_bytes(substream);
- ichdev->fragsize = snd_pcm_lib_period_bytes(substream);
- if (ichdev->ichd == ICHD_PCMOUT) {
- snd_intel8x0_setup_pcm_out(chip, runtime);
- if (chip->device_type == DEVICE_INTEL_ICH4)
- ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1;
- }
- snd_intel8x0_setup_periods(chip, ichdev);
- return 0;
-}
-
-static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
- struct ichdev *ichdev = get_ichdev(substream);
- size_t ptr1, ptr;
- int civ, timeout = 10;
- unsigned int position;
-
- spin_lock(&chip->reg_lock);
- do {
- civ = igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV);
- ptr1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb);
- position = ichdev->position;
- if (ptr1 == 0) {
- udelay(10);
- continue;
- }
- if (civ != igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV))
- continue;
-
- /* IO read operation is very expensive inside virtual machine
- * as it is emulated. The probability that subsequent PICB read
- * will return different result is high enough to loop till
- * timeout here.
- * Same CIV is strict enough condition to be sure that PICB
- * is valid inside VM on emulated card. */
- if (chip->inside_vm)
- break;
- if (ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb))
- break;
- } while (timeout--);
- ptr = ichdev->last_pos;
- if (ptr1 != 0) {
- ptr1 <<= ichdev->pos_shift;
- ptr = ichdev->fragsize1 - ptr1;
- ptr += position;
- if (ptr < ichdev->last_pos) {
- unsigned int pos_base, last_base;
- pos_base = position / ichdev->fragsize1;
- last_base = ichdev->last_pos / ichdev->fragsize1;
- /* another sanity check; ptr1 can go back to full
- * before the base position is updated
- */
- if (pos_base == last_base)
- ptr = ichdev->last_pos;
- }
- }
- ichdev->last_pos = ptr;
- spin_unlock(&chip->reg_lock);
- if (ptr >= ichdev->size)
- return 0;
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-static struct snd_pcm_hardware snd_intel8x0_stream =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 128 * 1024,
- .period_bytes_min = 32,
- .period_bytes_max = 128 * 1024,
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static unsigned int channels4[] = {
- 2, 4,
-};
-
-static struct snd_pcm_hw_constraint_list hw_constraints_channels4 = {
- .count = ARRAY_SIZE(channels4),
- .list = channels4,
- .mask = 0,
-};
-
-static unsigned int channels6[] = {
- 2, 4, 6,
-};
-
-static struct snd_pcm_hw_constraint_list hw_constraints_channels6 = {
- .count = ARRAY_SIZE(channels6),
- .list = channels6,
- .mask = 0,
-};
-
-static unsigned int channels8[] = {
- 2, 4, 6, 8,
-};
-
-static struct snd_pcm_hw_constraint_list hw_constraints_channels8 = {
- .count = ARRAY_SIZE(channels8),
- .list = channels8,
- .mask = 0,
-};
-
-static int snd_intel8x0_pcm_open(struct snd_pcm_substream *substream, struct ichdev *ichdev)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- ichdev->substream = substream;
- runtime->hw = snd_intel8x0_stream;
- runtime->hw.rates = ichdev->pcm->rates;
- snd_pcm_limit_hw_rates(runtime);
- if (chip->device_type == DEVICE_SIS) {
- runtime->hw.buffer_bytes_max = 64*1024;
- runtime->hw.period_bytes_max = 64*1024;
- }
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
- return err;
- runtime->private_data = ichdev;
- return 0;
-}
-
-static int snd_intel8x0_playback_open(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- err = snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_PCMOUT]);
- if (err < 0)
- return err;
-
- if (chip->multi8) {
- runtime->hw.channels_max = 8;
- snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- &hw_constraints_channels8);
- } else if (chip->multi6) {
- runtime->hw.channels_max = 6;
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- &hw_constraints_channels6);
- } else if (chip->multi4) {
- runtime->hw.channels_max = 4;
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- &hw_constraints_channels4);
- }
- if (chip->dra) {
- snd_ac97_pcm_double_rate_rules(runtime);
- }
- if (chip->smp20bit) {
- runtime->hw.formats |= SNDRV_PCM_FMTBIT_S32_LE;
- snd_pcm_hw_constraint_msbits(runtime, 0, 32, 20);
- }
- return 0;
-}
-
-static int snd_intel8x0_playback_close(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
-
- chip->ichd[ICHD_PCMOUT].substream = NULL;
- return 0;
-}
-
-static int snd_intel8x0_capture_open(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
-
- return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_PCMIN]);
-}
-
-static int snd_intel8x0_capture_close(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
-
- chip->ichd[ICHD_PCMIN].substream = NULL;
- return 0;
-}
-
-static int snd_intel8x0_mic_open(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
-
- return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_MIC]);
-}
-
-static int snd_intel8x0_mic_close(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
-
- chip->ichd[ICHD_MIC].substream = NULL;
- return 0;
-}
-
-static int snd_intel8x0_mic2_open(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
-
- return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_MIC2]);
-}
-
-static int snd_intel8x0_mic2_close(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
-
- chip->ichd[ICHD_MIC2].substream = NULL;
- return 0;
-}
-
-static int snd_intel8x0_capture2_open(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
-
- return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_PCM2IN]);
-}
-
-static int snd_intel8x0_capture2_close(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
-
- chip->ichd[ICHD_PCM2IN].substream = NULL;
- return 0;
-}
-
-static int snd_intel8x0_spdif_open(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
- int idx = chip->device_type == DEVICE_NFORCE ? NVD_SPBAR : ICHD_SPBAR;
-
- return snd_intel8x0_pcm_open(substream, &chip->ichd[idx]);
-}
-
-static int snd_intel8x0_spdif_close(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
- int idx = chip->device_type == DEVICE_NFORCE ? NVD_SPBAR : ICHD_SPBAR;
-
- chip->ichd[idx].substream = NULL;
- return 0;
-}
-
-static int snd_intel8x0_ali_ac97spdifout_open(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
- unsigned int val;
-
- spin_lock_irq(&chip->reg_lock);
- val = igetdword(chip, ICHREG(ALI_INTERFACECR));
- val |= ICH_ALI_IF_AC97SP;
- iputdword(chip, ICHREG(ALI_INTERFACECR), val);
- /* also needs to set ALI_SC_CODEC_SPDF correctly */
- spin_unlock_irq(&chip->reg_lock);
-
- return snd_intel8x0_pcm_open(substream, &chip->ichd[ALID_AC97SPDIFOUT]);
-}
-
-static int snd_intel8x0_ali_ac97spdifout_close(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
- unsigned int val;
-
- chip->ichd[ALID_AC97SPDIFOUT].substream = NULL;
- spin_lock_irq(&chip->reg_lock);
- val = igetdword(chip, ICHREG(ALI_INTERFACECR));
- val &= ~ICH_ALI_IF_AC97SP;
- iputdword(chip, ICHREG(ALI_INTERFACECR), val);
- spin_unlock_irq(&chip->reg_lock);
-
- return 0;
-}
-
-#if 0 // NYI
-static int snd_intel8x0_ali_spdifin_open(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
-
- return snd_intel8x0_pcm_open(substream, &chip->ichd[ALID_SPDIFIN]);
-}
-
-static int snd_intel8x0_ali_spdifin_close(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
-
- chip->ichd[ALID_SPDIFIN].substream = NULL;
- return 0;
-}
-
-static int snd_intel8x0_ali_spdifout_open(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
-
- return snd_intel8x0_pcm_open(substream, &chip->ichd[ALID_SPDIFOUT]);
-}
-
-static int snd_intel8x0_ali_spdifout_close(struct snd_pcm_substream *substream)
-{
- struct intel8x0 *chip = snd_pcm_substream_chip(substream);
-
- chip->ichd[ALID_SPDIFOUT].substream = NULL;
- return 0;
-}
-#endif
-
-static struct snd_pcm_ops snd_intel8x0_playback_ops = {
- .open = snd_intel8x0_playback_open,
- .close = snd_intel8x0_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_intel8x0_hw_params,
- .hw_free = snd_intel8x0_hw_free,
- .prepare = snd_intel8x0_pcm_prepare,
- .trigger = snd_intel8x0_pcm_trigger,
- .pointer = snd_intel8x0_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_intel8x0_capture_ops = {
- .open = snd_intel8x0_capture_open,
- .close = snd_intel8x0_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_intel8x0_hw_params,
- .hw_free = snd_intel8x0_hw_free,
- .prepare = snd_intel8x0_pcm_prepare,
- .trigger = snd_intel8x0_pcm_trigger,
- .pointer = snd_intel8x0_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_intel8x0_capture_mic_ops = {
- .open = snd_intel8x0_mic_open,
- .close = snd_intel8x0_mic_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_intel8x0_hw_params,
- .hw_free = snd_intel8x0_hw_free,
- .prepare = snd_intel8x0_pcm_prepare,
- .trigger = snd_intel8x0_pcm_trigger,
- .pointer = snd_intel8x0_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_intel8x0_capture_mic2_ops = {
- .open = snd_intel8x0_mic2_open,
- .close = snd_intel8x0_mic2_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_intel8x0_hw_params,
- .hw_free = snd_intel8x0_hw_free,
- .prepare = snd_intel8x0_pcm_prepare,
- .trigger = snd_intel8x0_pcm_trigger,
- .pointer = snd_intel8x0_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_intel8x0_capture2_ops = {
- .open = snd_intel8x0_capture2_open,
- .close = snd_intel8x0_capture2_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_intel8x0_hw_params,
- .hw_free = snd_intel8x0_hw_free,
- .prepare = snd_intel8x0_pcm_prepare,
- .trigger = snd_intel8x0_pcm_trigger,
- .pointer = snd_intel8x0_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_intel8x0_spdif_ops = {
- .open = snd_intel8x0_spdif_open,
- .close = snd_intel8x0_spdif_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_intel8x0_hw_params,
- .hw_free = snd_intel8x0_hw_free,
- .prepare = snd_intel8x0_pcm_prepare,
- .trigger = snd_intel8x0_pcm_trigger,
- .pointer = snd_intel8x0_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_intel8x0_ali_playback_ops = {
- .open = snd_intel8x0_playback_open,
- .close = snd_intel8x0_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_intel8x0_hw_params,
- .hw_free = snd_intel8x0_hw_free,
- .prepare = snd_intel8x0_pcm_prepare,
- .trigger = snd_intel8x0_ali_trigger,
- .pointer = snd_intel8x0_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_intel8x0_ali_capture_ops = {
- .open = snd_intel8x0_capture_open,
- .close = snd_intel8x0_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_intel8x0_hw_params,
- .hw_free = snd_intel8x0_hw_free,
- .prepare = snd_intel8x0_pcm_prepare,
- .trigger = snd_intel8x0_ali_trigger,
- .pointer = snd_intel8x0_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_intel8x0_ali_capture_mic_ops = {
- .open = snd_intel8x0_mic_open,
- .close = snd_intel8x0_mic_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_intel8x0_hw_params,
- .hw_free = snd_intel8x0_hw_free,
- .prepare = snd_intel8x0_pcm_prepare,
- .trigger = snd_intel8x0_ali_trigger,
- .pointer = snd_intel8x0_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_intel8x0_ali_ac97spdifout_ops = {
- .open = snd_intel8x0_ali_ac97spdifout_open,
- .close = snd_intel8x0_ali_ac97spdifout_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_intel8x0_hw_params,
- .hw_free = snd_intel8x0_hw_free,
- .prepare = snd_intel8x0_pcm_prepare,
- .trigger = snd_intel8x0_ali_trigger,
- .pointer = snd_intel8x0_pcm_pointer,
-};
-
-#if 0 // NYI
-static struct snd_pcm_ops snd_intel8x0_ali_spdifin_ops = {
- .open = snd_intel8x0_ali_spdifin_open,
- .close = snd_intel8x0_ali_spdifin_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_intel8x0_hw_params,
- .hw_free = snd_intel8x0_hw_free,
- .prepare = snd_intel8x0_pcm_prepare,
- .trigger = snd_intel8x0_pcm_trigger,
- .pointer = snd_intel8x0_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_intel8x0_ali_spdifout_ops = {
- .open = snd_intel8x0_ali_spdifout_open,
- .close = snd_intel8x0_ali_spdifout_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_intel8x0_hw_params,
- .hw_free = snd_intel8x0_hw_free,
- .prepare = snd_intel8x0_pcm_prepare,
- .trigger = snd_intel8x0_pcm_trigger,
- .pointer = snd_intel8x0_pcm_pointer,
-};
-#endif // NYI
-
-struct ich_pcm_table {
- char *suffix;
- struct snd_pcm_ops *playback_ops;
- struct snd_pcm_ops *capture_ops;
- size_t prealloc_size;
- size_t prealloc_max_size;
- int ac97_idx;
-};
-
-static int __devinit snd_intel8x0_pcm1(struct intel8x0 *chip, int device,
- struct ich_pcm_table *rec)
-{
- struct snd_pcm *pcm;
- int err;
- char name[32];
-
- if (rec->suffix)
- sprintf(name, "Intel ICH - %s", rec->suffix);
- else
- strcpy(name, "Intel ICH");
- err = snd_pcm_new(chip->card, name, device,
- rec->playback_ops ? 1 : 0,
- rec->capture_ops ? 1 : 0, &pcm);
- if (err < 0)
- return err;
-
- if (rec->playback_ops)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, rec->playback_ops);
- if (rec->capture_ops)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, rec->capture_ops);
-
- pcm->private_data = chip;
- pcm->info_flags = 0;
- if (rec->suffix)
- sprintf(pcm->name, "%s - %s", chip->card->shortname, rec->suffix);
- else
- strcpy(pcm->name, chip->card->shortname);
- chip->pcm[device] = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- rec->prealloc_size, rec->prealloc_max_size);
-
- return 0;
-}
-
-static struct ich_pcm_table intel_pcms[] __devinitdata = {
- {
- .playback_ops = &snd_intel8x0_playback_ops,
- .capture_ops = &snd_intel8x0_capture_ops,
- .prealloc_size = 64 * 1024,
- .prealloc_max_size = 128 * 1024,
- },
- {
- .suffix = "MIC ADC",
- .capture_ops = &snd_intel8x0_capture_mic_ops,
- .prealloc_size = 0,
- .prealloc_max_size = 128 * 1024,
- .ac97_idx = ICHD_MIC,
- },
- {
- .suffix = "MIC2 ADC",
- .capture_ops = &snd_intel8x0_capture_mic2_ops,
- .prealloc_size = 0,
- .prealloc_max_size = 128 * 1024,
- .ac97_idx = ICHD_MIC2,
- },
- {
- .suffix = "ADC2",
- .capture_ops = &snd_intel8x0_capture2_ops,
- .prealloc_size = 0,
- .prealloc_max_size = 128 * 1024,
- .ac97_idx = ICHD_PCM2IN,
- },
- {
- .suffix = "IEC958",
- .playback_ops = &snd_intel8x0_spdif_ops,
- .prealloc_size = 64 * 1024,
- .prealloc_max_size = 128 * 1024,
- .ac97_idx = ICHD_SPBAR,
- },
-};
-
-static struct ich_pcm_table nforce_pcms[] __devinitdata = {
- {
- .playback_ops = &snd_intel8x0_playback_ops,
- .capture_ops = &snd_intel8x0_capture_ops,
- .prealloc_size = 64 * 1024,
- .prealloc_max_size = 128 * 1024,
- },
- {
- .suffix = "MIC ADC",
- .capture_ops = &snd_intel8x0_capture_mic_ops,
- .prealloc_size = 0,
- .prealloc_max_size = 128 * 1024,
- .ac97_idx = NVD_MIC,
- },
- {
- .suffix = "IEC958",
- .playback_ops = &snd_intel8x0_spdif_ops,
- .prealloc_size = 64 * 1024,
- .prealloc_max_size = 128 * 1024,
- .ac97_idx = NVD_SPBAR,
- },
-};
-
-static struct ich_pcm_table ali_pcms[] __devinitdata = {
- {
- .playback_ops = &snd_intel8x0_ali_playback_ops,
- .capture_ops = &snd_intel8x0_ali_capture_ops,
- .prealloc_size = 64 * 1024,
- .prealloc_max_size = 128 * 1024,
- },
- {
- .suffix = "MIC ADC",
- .capture_ops = &snd_intel8x0_ali_capture_mic_ops,
- .prealloc_size = 0,
- .prealloc_max_size = 128 * 1024,
- .ac97_idx = ALID_MIC,
- },
- {
- .suffix = "IEC958",
- .playback_ops = &snd_intel8x0_ali_ac97spdifout_ops,
- /* .capture_ops = &snd_intel8x0_ali_spdifin_ops, */
- .prealloc_size = 64 * 1024,
- .prealloc_max_size = 128 * 1024,
- .ac97_idx = ALID_AC97SPDIFOUT,
- },
-#if 0 // NYI
- {
- .suffix = "HW IEC958",
- .playback_ops = &snd_intel8x0_ali_spdifout_ops,
- .prealloc_size = 64 * 1024,
- .prealloc_max_size = 128 * 1024,
- },
-#endif
-};
-
-static int __devinit snd_intel8x0_pcm(struct intel8x0 *chip)
-{
- int i, tblsize, device, err;
- struct ich_pcm_table *tbl, *rec;
-
- switch (chip->device_type) {
- case DEVICE_INTEL_ICH4:
- tbl = intel_pcms;
- tblsize = ARRAY_SIZE(intel_pcms);
- if (spdif_aclink)
- tblsize--;
- break;
- case DEVICE_NFORCE:
- tbl = nforce_pcms;
- tblsize = ARRAY_SIZE(nforce_pcms);
- if (spdif_aclink)
- tblsize--;
- break;
- case DEVICE_ALI:
- tbl = ali_pcms;
- tblsize = ARRAY_SIZE(ali_pcms);
- break;
- default:
- tbl = intel_pcms;
- tblsize = 2;
- break;
- }
-
- device = 0;
- for (i = 0; i < tblsize; i++) {
- rec = tbl + i;
- if (i > 0 && rec->ac97_idx) {
- /* activate PCM only when associated AC'97 codec */
- if (! chip->ichd[rec->ac97_idx].pcm)
- continue;
- }
- err = snd_intel8x0_pcm1(chip, device, rec);
- if (err < 0)
- return err;
- device++;
- }
-
- chip->pcm_devs = device;
- return 0;
-}
-
-
-/*
- * Mixer part
- */
-
-static void snd_intel8x0_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
-{
- struct intel8x0 *chip = bus->private_data;
- chip->ac97_bus = NULL;
-}
-
-static void snd_intel8x0_mixer_free_ac97(struct snd_ac97 *ac97)
-{
- struct intel8x0 *chip = ac97->private_data;
- chip->ac97[ac97->num] = NULL;
-}
-
-static struct ac97_pcm ac97_pcm_defs[] __devinitdata = {
- /* front PCM */
- {
- .exclusive = 1,
- .r = { {
- .slots = (1 << AC97_SLOT_PCM_LEFT) |
- (1 << AC97_SLOT_PCM_RIGHT) |
- (1 << AC97_SLOT_PCM_CENTER) |
- (1 << AC97_SLOT_PCM_SLEFT) |
- (1 << AC97_SLOT_PCM_SRIGHT) |
- (1 << AC97_SLOT_LFE)
- },
- {
- .slots = (1 << AC97_SLOT_PCM_LEFT) |
- (1 << AC97_SLOT_PCM_RIGHT) |
- (1 << AC97_SLOT_PCM_LEFT_0) |
- (1 << AC97_SLOT_PCM_RIGHT_0)
- }
- }
- },
- /* PCM IN #1 */
- {
- .stream = 1,
- .exclusive = 1,
- .r = { {
- .slots = (1 << AC97_SLOT_PCM_LEFT) |
- (1 << AC97_SLOT_PCM_RIGHT)
- }
- }
- },
- /* MIC IN #1 */
- {
- .stream = 1,
- .exclusive = 1,
- .r = { {
- .slots = (1 << AC97_SLOT_MIC)
- }
- }
- },
- /* S/PDIF PCM */
- {
- .exclusive = 1,
- .spdif = 1,
- .r = { {
- .slots = (1 << AC97_SLOT_SPDIF_LEFT2) |
- (1 << AC97_SLOT_SPDIF_RIGHT2)
- }
- }
- },
- /* PCM IN #2 */
- {
- .stream = 1,
- .exclusive = 1,
- .r = { {
- .slots = (1 << AC97_SLOT_PCM_LEFT) |
- (1 << AC97_SLOT_PCM_RIGHT)
- }
- }
- },
- /* MIC IN #2 */
- {
- .stream = 1,
- .exclusive = 1,
- .r = { {
- .slots = (1 << AC97_SLOT_MIC)
- }
- }
- },
-};
-
-static struct ac97_quirk ac97_quirks[] __devinitdata = {
- {
- .subvendor = 0x0e11,
- .subdevice = 0x000e,
- .name = "Compaq Deskpro EN", /* AD1885 */
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x0e11,
- .subdevice = 0x008a,
- .name = "Compaq Evo W4000", /* AD1885 */
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x0e11,
- .subdevice = 0x00b8,
- .name = "Compaq Evo D510C",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x0e11,
- .subdevice = 0x0860,
- .name = "HP/Compaq nx7010",
- .type = AC97_TUNE_MUTE_LED
- },
- {
- .subvendor = 0x1014,
- .subdevice = 0x0534,
- .name = "ThinkPad X31",
- .type = AC97_TUNE_INV_EAPD
- },
- {
- .subvendor = 0x1014,
- .subdevice = 0x1f00,
- .name = "MS-9128",
- .type = AC97_TUNE_ALC_JACK
- },
- {
- .subvendor = 0x1014,
- .subdevice = 0x0267,
- .name = "IBM NetVista A30p", /* AD1981B */
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x1025,
- .subdevice = 0x0082,
- .name = "Acer Travelmate 2310",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x1025,
- .subdevice = 0x0083,
- .name = "Acer Aspire 3003LCi",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x1028,
- .subdevice = 0x00d8,
- .name = "Dell Precision 530", /* AD1885 */
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x1028,
- .subdevice = 0x010d,
- .name = "Dell", /* which model? AD1885 */
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x1028,
- .subdevice = 0x0126,
- .name = "Dell Optiplex GX260", /* AD1981A */
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x1028,
- .subdevice = 0x012c,
- .name = "Dell Precision 650", /* AD1981A */
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x1028,
- .subdevice = 0x012d,
- .name = "Dell Precision 450", /* AD1981B*/
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x1028,
- .subdevice = 0x0147,
- .name = "Dell", /* which model? AD1981B*/
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x1028,
- .subdevice = 0x0151,
- .name = "Dell Optiplex GX270", /* AD1981B */
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x1028,
- .subdevice = 0x014e,
- .name = "Dell D800", /* STAC9750/51 */
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x1028,
- .subdevice = 0x0163,
- .name = "Dell Unknown", /* STAC9750/51 */
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x1028,
- .subdevice = 0x016a,
- .name = "Dell Inspiron 8600", /* STAC9750/51 */
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x1028,
- .subdevice = 0x0182,
- .name = "Dell Latitude D610", /* STAC9750/51 */
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x1028,
- .subdevice = 0x0186,
- .name = "Dell Latitude D810", /* cf. Malone #41015 */
- .type = AC97_TUNE_HP_MUTE_LED
- },
- {
- .subvendor = 0x1028,
- .subdevice = 0x0188,
- .name = "Dell Inspiron 6000",
- .type = AC97_TUNE_HP_MUTE_LED /* cf. Malone #41015 */
- },
- {
- .subvendor = 0x1028,
- .subdevice = 0x0189,
- .name = "Dell Inspiron 9300",
- .type = AC97_TUNE_HP_MUTE_LED
- },
- {
- .subvendor = 0x1028,
- .subdevice = 0x0191,
- .name = "Dell Inspiron 8600",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x103c,
- .subdevice = 0x006d,
- .name = "HP zv5000",
- .type = AC97_TUNE_MUTE_LED /*AD1981B*/
- },
- { /* FIXME: which codec? */
- .subvendor = 0x103c,
- .subdevice = 0x00c3,
- .name = "HP xw6000",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x103c,
- .subdevice = 0x088c,
- .name = "HP nc8000",
- .type = AC97_TUNE_HP_MUTE_LED
- },
- {
- .subvendor = 0x103c,
- .subdevice = 0x0890,
- .name = "HP nc6000",
- .type = AC97_TUNE_MUTE_LED
- },
- {
- .subvendor = 0x103c,
- .subdevice = 0x129d,
- .name = "HP xw8000",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x103c,
- .subdevice = 0x0938,
- .name = "HP nc4200",
- .type = AC97_TUNE_HP_MUTE_LED
- },
- {
- .subvendor = 0x103c,
- .subdevice = 0x099c,
- .name = "HP nx6110/nc6120",
- .type = AC97_TUNE_HP_MUTE_LED
- },
- {
- .subvendor = 0x103c,
- .subdevice = 0x0944,
- .name = "HP nc6220",
- .type = AC97_TUNE_HP_MUTE_LED
- },
- {
- .subvendor = 0x103c,
- .subdevice = 0x0934,
- .name = "HP nc8220",
- .type = AC97_TUNE_HP_MUTE_LED
- },
- {
- .subvendor = 0x103c,
- .subdevice = 0x12f1,
- .name = "HP xw8200", /* AD1981B*/
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x103c,
- .subdevice = 0x12f2,
- .name = "HP xw6200",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x103c,
- .subdevice = 0x3008,
- .name = "HP xw4200", /* AD1981B*/
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x104d,
- .subdevice = 0x8144,
- .name = "Sony",
- .type = AC97_TUNE_INV_EAPD
- },
- {
- .subvendor = 0x104d,
- .subdevice = 0x8197,
- .name = "Sony S1XP",
- .type = AC97_TUNE_INV_EAPD
- },
- {
- .subvendor = 0x104d,
- .subdevice = 0x81c0,
- .name = "Sony VAIO VGN-T350P", /*AD1981B*/
- .type = AC97_TUNE_INV_EAPD
- },
- {
- .subvendor = 0x104d,
- .subdevice = 0x81c5,
- .name = "Sony VAIO VGN-B1VP", /*AD1981B*/
- .type = AC97_TUNE_INV_EAPD
- },
- {
- .subvendor = 0x1043,
- .subdevice = 0x80f3,
- .name = "ASUS ICH5/AD1985",
- .type = AC97_TUNE_AD_SHARING
- },
- {
- .subvendor = 0x10cf,
- .subdevice = 0x11c3,
- .name = "Fujitsu-Siemens E4010",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x10cf,
- .subdevice = 0x1225,
- .name = "Fujitsu-Siemens T3010",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x10cf,
- .subdevice = 0x1253,
- .name = "Fujitsu S6210", /* STAC9750/51 */
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x10cf,
- .subdevice = 0x127d,
- .name = "Fujitsu Lifebook P7010",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x10cf,
- .subdevice = 0x127e,
- .name = "Fujitsu Lifebook C1211D",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x10cf,
- .subdevice = 0x12ec,
- .name = "Fujitsu-Siemens 4010",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x10cf,
- .subdevice = 0x12f2,
- .name = "Fujitsu-Siemens Celsius H320",
- .type = AC97_TUNE_SWAP_HP
- },
- {
- .subvendor = 0x10f1,
- .subdevice = 0x2665,
- .name = "Fujitsu-Siemens Celsius", /* AD1981? */
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x10f1,
- .subdevice = 0x2885,
- .name = "AMD64 Mobo", /* ALC650 */
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x10f1,
- .subdevice = 0x2895,
- .name = "Tyan Thunder K8WE",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x10f7,
- .subdevice = 0x834c,
- .name = "Panasonic CF-R4",
- .type = AC97_TUNE_HP_ONLY,
- },
- {
- .subvendor = 0x110a,
- .subdevice = 0x0056,
- .name = "Fujitsu-Siemens Scenic", /* AD1981? */
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x11d4,
- .subdevice = 0x5375,
- .name = "ADI AD1985 (discrete)",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x1462,
- .subdevice = 0x5470,
- .name = "MSI P4 ATX 645 Ultra",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x161f,
- .subdevice = 0x202f,
- .name = "Gateway M520",
- .type = AC97_TUNE_INV_EAPD
- },
- {
- .subvendor = 0x161f,
- .subdevice = 0x203a,
- .name = "Gateway 4525GZ", /* AD1981B */
- .type = AC97_TUNE_INV_EAPD
- },
- {
- .subvendor = 0x1734,
- .subdevice = 0x0088,
- .name = "Fujitsu-Siemens D1522", /* AD1981 */
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x8086,
- .subdevice = 0x2000,
- .mask = 0xfff0,
- .name = "Intel ICH5/AD1985",
- .type = AC97_TUNE_AD_SHARING
- },
- {
- .subvendor = 0x8086,
- .subdevice = 0x4000,
- .mask = 0xfff0,
- .name = "Intel ICH5/AD1985",
- .type = AC97_TUNE_AD_SHARING
- },
- {
- .subvendor = 0x8086,
- .subdevice = 0x4856,
- .name = "Intel D845WN (82801BA)",
- .type = AC97_TUNE_SWAP_HP
- },
- {
- .subvendor = 0x8086,
- .subdevice = 0x4d44,
- .name = "Intel D850EMV2", /* AD1885 */
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x8086,
- .subdevice = 0x4d56,
- .name = "Intel ICH/AD1885",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x8086,
- .subdevice = 0x6000,
- .mask = 0xfff0,
- .name = "Intel ICH5/AD1985",
- .type = AC97_TUNE_AD_SHARING
- },
- {
- .subvendor = 0x8086,
- .subdevice = 0xe000,
- .mask = 0xfff0,
- .name = "Intel ICH5/AD1985",
- .type = AC97_TUNE_AD_SHARING
- },
-#if 0 /* FIXME: this seems wrong on most boards */
- {
- .subvendor = 0x8086,
- .subdevice = 0xa000,
- .mask = 0xfff0,
- .name = "Intel ICH5/AD1985",
- .type = AC97_TUNE_HP_ONLY
- },
-#endif
- { } /* terminator */
-};
-
-static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
- const char *quirk_override)
-{
- struct snd_ac97_bus *pbus;
- struct snd_ac97_template ac97;
- int err;
- unsigned int i, codecs;
- unsigned int glob_sta = 0;
- struct snd_ac97_bus_ops *ops;
- static struct snd_ac97_bus_ops standard_bus_ops = {
- .write = snd_intel8x0_codec_write,
- .read = snd_intel8x0_codec_read,
- };
- static struct snd_ac97_bus_ops ali_bus_ops = {
- .write = snd_intel8x0_ali_codec_write,
- .read = snd_intel8x0_ali_codec_read,
- };
-
- chip->spdif_idx = -1; /* use PCMOUT (or disabled) */
- if (!spdif_aclink) {
- switch (chip->device_type) {
- case DEVICE_NFORCE:
- chip->spdif_idx = NVD_SPBAR;
- break;
- case DEVICE_ALI:
- chip->spdif_idx = ALID_AC97SPDIFOUT;
- break;
- case DEVICE_INTEL_ICH4:
- chip->spdif_idx = ICHD_SPBAR;
- break;
- };
- }
-
- chip->in_ac97_init = 1;
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = chip;
- ac97.private_free = snd_intel8x0_mixer_free_ac97;
- ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE;
- if (chip->xbox)
- ac97.scaps |= AC97_SCAP_DETECT_BY_VENDOR;
- if (chip->device_type != DEVICE_ALI) {
- glob_sta = igetdword(chip, ICHREG(GLOB_STA));
- ops = &standard_bus_ops;
- chip->in_sdin_init = 1;
- codecs = 0;
- for (i = 0; i < chip->max_codecs; i++) {
- if (! (glob_sta & chip->codec_bit[i]))
- continue;
- if (chip->device_type == DEVICE_INTEL_ICH4) {
- snd_intel8x0_codec_read_test(chip, codecs);
- chip->ac97_sdin[codecs] =
- igetbyte(chip, ICHREG(SDM)) & ICH_LDI_MASK;
- if (snd_BUG_ON(chip->ac97_sdin[codecs] >= 3))
- chip->ac97_sdin[codecs] = 0;
- } else
- chip->ac97_sdin[codecs] = i;
- codecs++;
- }
- chip->in_sdin_init = 0;
- if (! codecs)
- codecs = 1;
- } else {
- ops = &ali_bus_ops;
- codecs = 1;
- /* detect the secondary codec */
- for (i = 0; i < 100; i++) {
- unsigned int reg = igetdword(chip, ICHREG(ALI_RTSR));
- if (reg & 0x40) {
- codecs = 2;
- break;
- }
- iputdword(chip, ICHREG(ALI_RTSR), reg | 0x40);
- udelay(1);
- }
- }
- if ((err = snd_ac97_bus(chip->card, 0, ops, chip, &pbus)) < 0)
- goto __err;
- pbus->private_free = snd_intel8x0_mixer_free_ac97_bus;
- if (ac97_clock >= 8000 && ac97_clock <= 48000)
- pbus->clock = ac97_clock;
- /* FIXME: my test board doesn't work well with VRA... */
- if (chip->device_type == DEVICE_ALI)
- pbus->no_vra = 1;
- else
- pbus->dra = 1;
- chip->ac97_bus = pbus;
- chip->ncodecs = codecs;
-
- ac97.pci = chip->pci;
- for (i = 0; i < codecs; i++) {
- ac97.num = i;
- if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
- if (err != -EACCES)
- snd_printk(KERN_ERR "Unable to initialize codec #%d\n", i);
- if (i == 0)
- goto __err;
- }
- }
- /* tune up the primary codec */
- snd_ac97_tune_hardware(chip->ac97[0], ac97_quirks, quirk_override);
- /* enable separate SDINs for ICH4 */
- if (chip->device_type == DEVICE_INTEL_ICH4)
- pbus->isdin = 1;
- /* find the available PCM streams */
- i = ARRAY_SIZE(ac97_pcm_defs);
- if (chip->device_type != DEVICE_INTEL_ICH4)
- i -= 2; /* do not allocate PCM2IN and MIC2 */
- if (chip->spdif_idx < 0)
- i--; /* do not allocate S/PDIF */
- err = snd_ac97_pcm_assign(pbus, i, ac97_pcm_defs);
- if (err < 0)
- goto __err;
- chip->ichd[ICHD_PCMOUT].pcm = &pbus->pcms[0];
- chip->ichd[ICHD_PCMIN].pcm = &pbus->pcms[1];
- chip->ichd[ICHD_MIC].pcm = &pbus->pcms[2];
- if (chip->spdif_idx >= 0)
- chip->ichd[chip->spdif_idx].pcm = &pbus->pcms[3];
- if (chip->device_type == DEVICE_INTEL_ICH4) {
- chip->ichd[ICHD_PCM2IN].pcm = &pbus->pcms[4];
- chip->ichd[ICHD_MIC2].pcm = &pbus->pcms[5];
- }
- /* enable separate SDINs for ICH4 */
- if (chip->device_type == DEVICE_INTEL_ICH4) {
- struct ac97_pcm *pcm = chip->ichd[ICHD_PCM2IN].pcm;
- u8 tmp = igetbyte(chip, ICHREG(SDM));
- tmp &= ~(ICH_DI2L_MASK|ICH_DI1L_MASK);
- if (pcm) {
- tmp |= ICH_SE; /* steer enable for multiple SDINs */
- tmp |= chip->ac97_sdin[0] << ICH_DI1L_SHIFT;
- for (i = 1; i < 4; i++) {
- if (pcm->r[0].codec[i]) {
- tmp |= chip->ac97_sdin[pcm->r[0].codec[1]->num] << ICH_DI2L_SHIFT;
- break;
- }
- }
- } else {
- tmp &= ~ICH_SE; /* steer disable */
- }
- iputbyte(chip, ICHREG(SDM), tmp);
- }
- if (pbus->pcms[0].r[0].slots & (1 << AC97_SLOT_PCM_SLEFT)) {
- chip->multi4 = 1;
- if (pbus->pcms[0].r[0].slots & (1 << AC97_SLOT_LFE)) {
- chip->multi6 = 1;
- if (chip->ac97[0]->flags & AC97_HAS_8CH)
- chip->multi8 = 1;
- }
- }
- if (pbus->pcms[0].r[1].rslots[0]) {
- chip->dra = 1;
- }
- if (chip->device_type == DEVICE_INTEL_ICH4) {
- if ((igetdword(chip, ICHREG(GLOB_STA)) & ICH_SAMPLE_CAP) == ICH_SAMPLE_16_20)
- chip->smp20bit = 1;
- }
- if (chip->device_type == DEVICE_NFORCE && !spdif_aclink) {
- /* 48kHz only */
- chip->ichd[chip->spdif_idx].pcm->rates = SNDRV_PCM_RATE_48000;
- }
- if (chip->device_type == DEVICE_INTEL_ICH4 && !spdif_aclink) {
- /* use slot 10/11 for SPDIF */
- u32 val;
- val = igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_PCM_SPDIF_MASK;
- val |= ICH_PCM_SPDIF_1011;
- iputdword(chip, ICHREG(GLOB_CNT), val);
- snd_ac97_update_bits(chip->ac97[0], AC97_EXTENDED_STATUS, 0x03 << 4, 0x03 << 4);
- }
- chip->in_ac97_init = 0;
- return 0;
-
- __err:
- /* clear the cold-reset bit for the next chance */
- if (chip->device_type != DEVICE_ALI)
- iputdword(chip, ICHREG(GLOB_CNT),
- igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_AC97COLD);
- return err;
-}
-
-
-/*
- *
- */
-
-static void do_ali_reset(struct intel8x0 *chip)
-{
- iputdword(chip, ICHREG(ALI_SCR), ICH_ALI_SC_RESET);
- iputdword(chip, ICHREG(ALI_FIFOCR1), 0x83838383);
- iputdword(chip, ICHREG(ALI_FIFOCR2), 0x83838383);
- iputdword(chip, ICHREG(ALI_FIFOCR3), 0x83838383);
- iputdword(chip, ICHREG(ALI_INTERFACECR),
- ICH_ALI_IF_PI|ICH_ALI_IF_PO);
- iputdword(chip, ICHREG(ALI_INTERRUPTCR), 0x00000000);
- iputdword(chip, ICHREG(ALI_INTERRUPTSR), 0x00000000);
-}
-
-#ifdef CONFIG_SND_AC97_POWER_SAVE
-static struct snd_pci_quirk ich_chip_reset_mode[] = {
- SND_PCI_QUIRK(0x1014, 0x051f, "Thinkpad R32", 1),
- { } /* end */
-};
-
-static int snd_intel8x0_ich_chip_cold_reset(struct intel8x0 *chip)
-{
- unsigned int cnt;
- /* ACLink on, 2 channels */
-
- if (snd_pci_quirk_lookup(chip->pci, ich_chip_reset_mode))
- return -EIO;
-
- cnt = igetdword(chip, ICHREG(GLOB_CNT));
- cnt &= ~(ICH_ACLINK | ICH_PCM_246_MASK);
-
- /* do cold reset - the full ac97 powerdown may leave the controller
- * in a warm state but actually it cannot communicate with the codec.
- */
- iputdword(chip, ICHREG(GLOB_CNT), cnt & ~ICH_AC97COLD);
- cnt = igetdword(chip, ICHREG(GLOB_CNT));
- udelay(10);
- iputdword(chip, ICHREG(GLOB_CNT), cnt | ICH_AC97COLD);
- msleep(1);
- return 0;
-}
-#define snd_intel8x0_ich_chip_can_cold_reset(chip) \
- (!snd_pci_quirk_lookup(chip->pci, ich_chip_reset_mode))
-#else
-#define snd_intel8x0_ich_chip_cold_reset(chip) 0
-#define snd_intel8x0_ich_chip_can_cold_reset(chip) (0)
-#endif
-
-static int snd_intel8x0_ich_chip_reset(struct intel8x0 *chip)
-{
- unsigned long end_time;
- unsigned int cnt;
- /* ACLink on, 2 channels */
- cnt = igetdword(chip, ICHREG(GLOB_CNT));
- cnt &= ~(ICH_ACLINK | ICH_PCM_246_MASK);
- /* finish cold or do warm reset */
- cnt |= (cnt & ICH_AC97COLD) == 0 ? ICH_AC97COLD : ICH_AC97WARM;
- iputdword(chip, ICHREG(GLOB_CNT), cnt);
- end_time = (jiffies + (HZ / 4)) + 1;
- do {
- if ((igetdword(chip, ICHREG(GLOB_CNT)) & ICH_AC97WARM) == 0)
- return 0;
- schedule_timeout_uninterruptible(1);
- } while (time_after_eq(end_time, jiffies));
- snd_printk(KERN_ERR "AC'97 warm reset still in progress? [0x%x]\n",
- igetdword(chip, ICHREG(GLOB_CNT)));
- return -EIO;
-}
-
-static int snd_intel8x0_ich_chip_init(struct intel8x0 *chip, int probing)
-{
- unsigned long end_time;
- unsigned int status, nstatus;
- unsigned int cnt;
- int err;
-
- /* put logic to right state */
- /* first clear status bits */
- status = ICH_RCS | ICH_MCINT | ICH_POINT | ICH_PIINT;
- if (chip->device_type == DEVICE_NFORCE)
- status |= ICH_NVSPINT;
- cnt = igetdword(chip, ICHREG(GLOB_STA));
- iputdword(chip, ICHREG(GLOB_STA), cnt & status);
-
- if (snd_intel8x0_ich_chip_can_cold_reset(chip))
- err = snd_intel8x0_ich_chip_cold_reset(chip);
- else
- err = snd_intel8x0_ich_chip_reset(chip);
- if (err < 0)
- return err;
-
- if (probing) {
- /* wait for any codec ready status.
- * Once it becomes ready it should remain ready
- * as long as we do not disable the ac97 link.
- */
- end_time = jiffies + HZ;
- do {
- status = igetdword(chip, ICHREG(GLOB_STA)) &
- chip->codec_isr_bits;
- if (status)
- break;
- schedule_timeout_uninterruptible(1);
- } while (time_after_eq(end_time, jiffies));
- if (! status) {
- /* no codec is found */
- snd_printk(KERN_ERR "codec_ready: codec is not ready [0x%x]\n",
- igetdword(chip, ICHREG(GLOB_STA)));
- return -EIO;
- }
-
- /* wait for other codecs ready status. */
- end_time = jiffies + HZ / 4;
- while (status != chip->codec_isr_bits &&
- time_after_eq(end_time, jiffies)) {
- schedule_timeout_uninterruptible(1);
- status |= igetdword(chip, ICHREG(GLOB_STA)) &
- chip->codec_isr_bits;
- }
-
- } else {
- /* resume phase */
- int i;
- status = 0;
- for (i = 0; i < chip->ncodecs; i++)
- if (chip->ac97[i])
- status |= chip->codec_bit[chip->ac97_sdin[i]];
- /* wait until all the probed codecs are ready */
- end_time = jiffies + HZ;
- do {
- nstatus = igetdword(chip, ICHREG(GLOB_STA)) &
- chip->codec_isr_bits;
- if (status == nstatus)
- break;
- schedule_timeout_uninterruptible(1);
- } while (time_after_eq(end_time, jiffies));
- }
-
- if (chip->device_type == DEVICE_SIS) {
- /* unmute the output on SIS7012 */
- iputword(chip, 0x4c, igetword(chip, 0x4c) | 1);
- }
- if (chip->device_type == DEVICE_NFORCE && !spdif_aclink) {
- /* enable SPDIF interrupt */
- unsigned int val;
- pci_read_config_dword(chip->pci, 0x4c, &val);
- val |= 0x1000000;
- pci_write_config_dword(chip->pci, 0x4c, val);
- }
- return 0;
-}
-
-static int snd_intel8x0_ali_chip_init(struct intel8x0 *chip, int probing)
-{
- u32 reg;
- int i = 0;
-
- reg = igetdword(chip, ICHREG(ALI_SCR));
- if ((reg & 2) == 0) /* Cold required */
- reg |= 2;
- else
- reg |= 1; /* Warm */
- reg &= ~0x80000000; /* ACLink on */
- iputdword(chip, ICHREG(ALI_SCR), reg);
-
- for (i = 0; i < HZ / 2; i++) {
- if (! (igetdword(chip, ICHREG(ALI_INTERRUPTSR)) & ALI_INT_GPIO))
- goto __ok;
- schedule_timeout_uninterruptible(1);
- }
- snd_printk(KERN_ERR "AC'97 reset failed.\n");
- if (probing)
- return -EIO;
-
- __ok:
- for (i = 0; i < HZ / 2; i++) {
- reg = igetdword(chip, ICHREG(ALI_RTSR));
- if (reg & 0x80) /* primary codec */
- break;
- iputdword(chip, ICHREG(ALI_RTSR), reg | 0x80);
- schedule_timeout_uninterruptible(1);
- }
-
- do_ali_reset(chip);
- return 0;
-}
-
-static int snd_intel8x0_chip_init(struct intel8x0 *chip, int probing)
-{
- unsigned int i, timeout;
- int err;
-
- if (chip->device_type != DEVICE_ALI) {
- if ((err = snd_intel8x0_ich_chip_init(chip, probing)) < 0)
- return err;
- iagetword(chip, 0); /* clear semaphore flag */
- } else {
- if ((err = snd_intel8x0_ali_chip_init(chip, probing)) < 0)
- return err;
- }
-
- /* disable interrupts */
- for (i = 0; i < chip->bdbars_count; i++)
- iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, 0x00);
- /* reset channels */
- for (i = 0; i < chip->bdbars_count; i++)
- iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS);
- for (i = 0; i < chip->bdbars_count; i++) {
- timeout = 100000;
- while (--timeout != 0) {
- if ((igetbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset) & ICH_RESETREGS) == 0)
- break;
- }
- if (timeout == 0)
- printk(KERN_ERR "intel8x0: reset of registers failed?\n");
- }
- /* initialize Buffer Descriptor Lists */
- for (i = 0; i < chip->bdbars_count; i++)
- iputdword(chip, ICH_REG_OFF_BDBAR + chip->ichd[i].reg_offset,
- chip->ichd[i].bdbar_addr);
- return 0;
-}
-
-static int snd_intel8x0_free(struct intel8x0 *chip)
-{
- unsigned int i;
-
- if (chip->irq < 0)
- goto __hw_end;
- /* disable interrupts */
- for (i = 0; i < chip->bdbars_count; i++)
- iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, 0x00);
- /* reset channels */
- for (i = 0; i < chip->bdbars_count; i++)
- iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS);
- if (chip->device_type == DEVICE_NFORCE && !spdif_aclink) {
- /* stop the spdif interrupt */
- unsigned int val;
- pci_read_config_dword(chip->pci, 0x4c, &val);
- val &= ~0x1000000;
- pci_write_config_dword(chip->pci, 0x4c, val);
- }
- /* --- */
-
- __hw_end:
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
- if (chip->bdbars.area) {
- if (chip->fix_nocache)
- fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 0);
- snd_dma_free_pages(&chip->bdbars);
- }
- if (chip->addr)
- pci_iounmap(chip->pci, chip->addr);
- if (chip->bmaddr)
- pci_iounmap(chip->pci, chip->bmaddr);
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
- kfree(chip);
- return 0;
-}
-
-#ifdef CONFIG_PM
-/*
- * power management
- */
-static int intel8x0_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct intel8x0 *chip = card->private_data;
- int i;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- for (i = 0; i < chip->pcm_devs; i++)
- snd_pcm_suspend_all(chip->pcm[i]);
- /* clear nocache */
- if (chip->fix_nocache) {
- for (i = 0; i < chip->bdbars_count; i++) {
- struct ichdev *ichdev = &chip->ichd[i];
- if (ichdev->substream && ichdev->page_attr_changed) {
- struct snd_pcm_runtime *runtime = ichdev->substream->runtime;
- if (runtime->dma_area)
- fill_nocache(runtime->dma_area, runtime->dma_bytes, 0);
- }
- }
- }
- for (i = 0; i < chip->ncodecs; i++)
- snd_ac97_suspend(chip->ac97[i]);
- if (chip->device_type == DEVICE_INTEL_ICH4)
- chip->sdm_saved = igetbyte(chip, ICHREG(SDM));
-
- if (chip->irq >= 0) {
- free_irq(chip->irq, chip);
- chip->irq = -1;
- }
- pci_disable_device(pci);
- pci_save_state(pci);
- /* The call below may disable built-in speaker on some laptops
- * after S2RAM. So, don't touch it.
- */
- /* pci_set_power_state(pci, pci_choose_state(pci, state)); */
- return 0;
-}
-
-static int intel8x0_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct intel8x0 *chip = card->private_data;
- int i;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "intel8x0: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
- snd_intel8x0_chip_init(chip, 0);
- if (request_irq(pci->irq, snd_intel8x0_interrupt,
- IRQF_SHARED, KBUILD_MODNAME, chip)) {
- printk(KERN_ERR "intel8x0: unable to grab IRQ %d, "
- "disabling device\n", pci->irq);
- snd_card_disconnect(card);
- return -EIO;
- }
- chip->irq = pci->irq;
- synchronize_irq(chip->irq);
-
- /* re-initialize mixer stuff */
- if (chip->device_type == DEVICE_INTEL_ICH4 && !spdif_aclink) {
- /* enable separate SDINs for ICH4 */
- iputbyte(chip, ICHREG(SDM), chip->sdm_saved);
- /* use slot 10/11 for SPDIF */
- iputdword(chip, ICHREG(GLOB_CNT),
- (igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_PCM_SPDIF_MASK) |
- ICH_PCM_SPDIF_1011);
- }
-
- /* refill nocache */
- if (chip->fix_nocache)
- fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 1);
-
- for (i = 0; i < chip->ncodecs; i++)
- snd_ac97_resume(chip->ac97[i]);
-
- /* refill nocache */
- if (chip->fix_nocache) {
- for (i = 0; i < chip->bdbars_count; i++) {
- struct ichdev *ichdev = &chip->ichd[i];
- if (ichdev->substream && ichdev->page_attr_changed) {
- struct snd_pcm_runtime *runtime = ichdev->substream->runtime;
- if (runtime->dma_area)
- fill_nocache(runtime->dma_area, runtime->dma_bytes, 1);
- }
- }
- }
-
- /* resume status */
- for (i = 0; i < chip->bdbars_count; i++) {
- struct ichdev *ichdev = &chip->ichd[i];
- unsigned long port = ichdev->reg_offset;
- if (! ichdev->substream || ! ichdev->suspended)
- continue;
- if (ichdev->ichd == ICHD_PCMOUT)
- snd_intel8x0_setup_pcm_out(chip, ichdev->substream->runtime);
- iputdword(chip, port + ICH_REG_OFF_BDBAR, ichdev->bdbar_addr);
- iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi);
- iputbyte(chip, port + ICH_REG_OFF_CIV, ichdev->civ);
- iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
- }
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif /* CONFIG_PM */
-
-#define INTEL8X0_TESTBUF_SIZE 32768 /* enough large for one shot */
-
-static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip)
-{
- struct snd_pcm_substream *subs;
- struct ichdev *ichdev;
- unsigned long port;
- unsigned long pos, pos1, t;
- int civ, timeout = 1000, attempt = 1;
- struct timespec start_time, stop_time;
-
- if (chip->ac97_bus->clock != 48000)
- return; /* specified in module option */
-
- __again:
- subs = chip->pcm[0]->streams[0].substream;
- if (! subs || subs->dma_buffer.bytes < INTEL8X0_TESTBUF_SIZE) {
- snd_printk(KERN_WARNING "no playback buffer allocated - aborting measure ac97 clock\n");
- return;
- }
- ichdev = &chip->ichd[ICHD_PCMOUT];
- ichdev->physbuf = subs->dma_buffer.addr;
- ichdev->size = ichdev->fragsize = INTEL8X0_TESTBUF_SIZE;
- ichdev->substream = NULL; /* don't process interrupts */
-
- /* set rate */
- if (snd_ac97_set_rate(chip->ac97[0], AC97_PCM_FRONT_DAC_RATE, 48000) < 0) {
- snd_printk(KERN_ERR "cannot set ac97 rate: clock = %d\n", chip->ac97_bus->clock);
- return;
- }
- snd_intel8x0_setup_periods(chip, ichdev);
- port = ichdev->reg_offset;
- spin_lock_irq(&chip->reg_lock);
- chip->in_measurement = 1;
- /* trigger */
- if (chip->device_type != DEVICE_ALI)
- iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE | ICH_STARTBM);
- else {
- iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE);
- iputdword(chip, ICHREG(ALI_DMACR), 1 << ichdev->ali_slot);
- }
- do_posix_clock_monotonic_gettime(&start_time);
- spin_unlock_irq(&chip->reg_lock);
- msleep(50);
- spin_lock_irq(&chip->reg_lock);
- /* check the position */
- do {
- civ = igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV);
- pos1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb);
- if (pos1 == 0) {
- udelay(10);
- continue;
- }
- if (civ == igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV) &&
- pos1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb))
- break;
- } while (timeout--);
- if (pos1 == 0) { /* oops, this value is not reliable */
- pos = 0;
- } else {
- pos = ichdev->fragsize1;
- pos -= pos1 << ichdev->pos_shift;
- pos += ichdev->position;
- }
- chip->in_measurement = 0;
- do_posix_clock_monotonic_gettime(&stop_time);
- /* stop */
- if (chip->device_type == DEVICE_ALI) {
- iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 16));
- iputbyte(chip, port + ICH_REG_OFF_CR, 0);
- while (igetbyte(chip, port + ICH_REG_OFF_CR))
- ;
- } else {
- iputbyte(chip, port + ICH_REG_OFF_CR, 0);
- while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH))
- ;
- }
- iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS);
- spin_unlock_irq(&chip->reg_lock);
-
- if (pos == 0) {
- snd_printk(KERN_ERR "intel8x0: measure - unreliable DMA position..\n");
- __retry:
- if (attempt < 3) {
- msleep(300);
- attempt++;
- goto __again;
- }
- goto __end;
- }
-
- pos /= 4;
- t = stop_time.tv_sec - start_time.tv_sec;
- t *= 1000000;
- t += (stop_time.tv_nsec - start_time.tv_nsec) / 1000;
- printk(KERN_INFO "%s: measured %lu usecs (%lu samples)\n", __func__, t, pos);
- if (t == 0) {
- snd_printk(KERN_ERR "intel8x0: ?? calculation error..\n");
- goto __retry;
- }
- pos *= 1000;
- pos = (pos / t) * 1000 + ((pos % t) * 1000) / t;
- if (pos < 40000 || pos >= 60000) {
- /* abnormal value. hw problem? */
- printk(KERN_INFO "intel8x0: measured clock %ld rejected\n", pos);
- goto __retry;
- } else if (pos > 40500 && pos < 41500)
- /* first exception - 41000Hz reference clock */
- chip->ac97_bus->clock = 41000;
- else if (pos > 43600 && pos < 44600)
- /* second exception - 44100HZ reference clock */
- chip->ac97_bus->clock = 44100;
- else if (pos < 47500 || pos > 48500)
- /* not 48000Hz, tuning the clock.. */
- chip->ac97_bus->clock = (chip->ac97_bus->clock * 48000) / pos;
- __end:
- printk(KERN_INFO "intel8x0: clocking to %d\n", chip->ac97_bus->clock);
- snd_ac97_update_power(chip->ac97[0], AC97_PCM_FRONT_DAC_RATE, 0);
-}
-
-static struct snd_pci_quirk intel8x0_clock_list[] __devinitdata = {
- SND_PCI_QUIRK(0x0e11, 0x008a, "AD1885", 41000),
- SND_PCI_QUIRK(0x1028, 0x00be, "AD1885", 44100),
- SND_PCI_QUIRK(0x1028, 0x0177, "AD1980", 48000),
- SND_PCI_QUIRK(0x1028, 0x01ad, "AD1981B", 48000),
- SND_PCI_QUIRK(0x1043, 0x80f3, "AD1985", 48000),
- { } /* terminator */
-};
-
-static int __devinit intel8x0_in_clock_list(struct intel8x0 *chip)
-{
- struct pci_dev *pci = chip->pci;
- const struct snd_pci_quirk *wl;
-
- wl = snd_pci_quirk_lookup(pci, intel8x0_clock_list);
- if (!wl)
- return 0;
- printk(KERN_INFO "intel8x0: white list rate for %04x:%04x is %i\n",
- pci->subsystem_vendor, pci->subsystem_device, wl->value);
- chip->ac97_bus->clock = wl->value;
- return 1;
-}
-
-#ifdef CONFIG_PROC_FS
-static void snd_intel8x0_proc_read(struct snd_info_entry * entry,
- struct snd_info_buffer *buffer)
-{
- struct intel8x0 *chip = entry->private_data;
- unsigned int tmp;
-
- snd_iprintf(buffer, "Intel8x0\n\n");
- if (chip->device_type == DEVICE_ALI)
- return;
- tmp = igetdword(chip, ICHREG(GLOB_STA));
- snd_iprintf(buffer, "Global control : 0x%08x\n", igetdword(chip, ICHREG(GLOB_CNT)));
- snd_iprintf(buffer, "Global status : 0x%08x\n", tmp);
- if (chip->device_type == DEVICE_INTEL_ICH4)
- snd_iprintf(buffer, "SDM : 0x%08x\n", igetdword(chip, ICHREG(SDM)));
- snd_iprintf(buffer, "AC'97 codecs ready :");
- if (tmp & chip->codec_isr_bits) {
- int i;
- static const char *codecs[3] = {
- "primary", "secondary", "tertiary"
- };
- for (i = 0; i < chip->max_codecs; i++)
- if (tmp & chip->codec_bit[i])
- snd_iprintf(buffer, " %s", codecs[i]);
- } else
- snd_iprintf(buffer, " none");
- snd_iprintf(buffer, "\n");
- if (chip->device_type == DEVICE_INTEL_ICH4 ||
- chip->device_type == DEVICE_SIS)
- snd_iprintf(buffer, "AC'97 codecs SDIN : %i %i %i\n",
- chip->ac97_sdin[0],
- chip->ac97_sdin[1],
- chip->ac97_sdin[2]);
-}
-
-static void __devinit snd_intel8x0_proc_init(struct intel8x0 * chip)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(chip->card, "intel8x0", &entry))
- snd_info_set_text_ops(entry, chip, snd_intel8x0_proc_read);
-}
-#else
-#define snd_intel8x0_proc_init(x)
-#endif
-
-static int snd_intel8x0_dev_free(struct snd_device *device)
-{
- struct intel8x0 *chip = device->device_data;
- return snd_intel8x0_free(chip);
-}
-
-struct ich_reg_info {
- unsigned int int_sta_mask;
- unsigned int offset;
-};
-
-static unsigned int ich_codec_bits[3] = {
- ICH_PCR, ICH_SCR, ICH_TCR
-};
-static unsigned int sis_codec_bits[3] = {
- ICH_PCR, ICH_SCR, ICH_SIS_TCR
-};
-
-static int __devinit snd_intel8x0_inside_vm(struct pci_dev *pci)
-{
- int result = inside_vm;
- char *msg = NULL;
-
- /* check module parameter first (override detection) */
- if (result >= 0) {
- msg = result ? "enable (forced) VM" : "disable (forced) VM";
- goto fini;
- }
-
- /* detect KVM and Parallels virtual environments */
- result = kvm_para_available();
-#ifdef X86_FEATURE_HYPERVISOR
- result = result || boot_cpu_has(X86_FEATURE_HYPERVISOR);
-#endif
- if (!result)
- goto fini;
-
- /* check for known (emulated) devices */
- if (pci->subsystem_vendor == 0x1af4 &&
- pci->subsystem_device == 0x1100) {
- /* KVM emulated sound, PCI SSID: 1af4:1100 */
- msg = "enable KVM";
- } else if (pci->subsystem_vendor == 0x1ab8) {
- /* Parallels VM emulated sound, PCI SSID: 1ab8:xxxx */
- msg = "enable Parallels VM";
- } else {
- msg = "disable (unknown or VT-d) VM";
- result = 0;
- }
-
-fini:
- if (msg != NULL)
- printk(KERN_INFO "intel8x0: %s optimization\n", msg);
-
- return result;
-}
-
-static int __devinit snd_intel8x0_create(struct snd_card *card,
- struct pci_dev *pci,
- unsigned long device_type,
- struct intel8x0 ** r_intel8x0)
-{
- struct intel8x0 *chip;
- int err;
- unsigned int i;
- unsigned int int_sta_masks;
- struct ichdev *ichdev;
- static struct snd_device_ops ops = {
- .dev_free = snd_intel8x0_dev_free,
- };
-
- static unsigned int bdbars[] = {
- 3, /* DEVICE_INTEL */
- 6, /* DEVICE_INTEL_ICH4 */
- 3, /* DEVICE_SIS */
- 6, /* DEVICE_ALI */
- 4, /* DEVICE_NFORCE */
- };
- static struct ich_reg_info intel_regs[6] = {
- { ICH_PIINT, 0 },
- { ICH_POINT, 0x10 },
- { ICH_MCINT, 0x20 },
- { ICH_M2INT, 0x40 },
- { ICH_P2INT, 0x50 },
- { ICH_SPINT, 0x60 },
- };
- static struct ich_reg_info nforce_regs[4] = {
- { ICH_PIINT, 0 },
- { ICH_POINT, 0x10 },
- { ICH_MCINT, 0x20 },
- { ICH_NVSPINT, 0x70 },
- };
- static struct ich_reg_info ali_regs[6] = {
- { ALI_INT_PCMIN, 0x40 },
- { ALI_INT_PCMOUT, 0x50 },
- { ALI_INT_MICIN, 0x60 },
- { ALI_INT_CODECSPDIFOUT, 0x70 },
- { ALI_INT_SPDIFIN, 0xa0 },
- { ALI_INT_SPDIFOUT, 0xb0 },
- };
- struct ich_reg_info *tbl;
-
- *r_intel8x0 = NULL;
-
- if ((err = pci_enable_device(pci)) < 0)
- return err;
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
- spin_lock_init(&chip->reg_lock);
- chip->device_type = device_type;
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
-
- /* module parameters */
- chip->buggy_irq = buggy_irq;
- chip->buggy_semaphore = buggy_semaphore;
- if (xbox)
- chip->xbox = 1;
-
- chip->inside_vm = snd_intel8x0_inside_vm(pci);
-
- if (pci->vendor == PCI_VENDOR_ID_INTEL &&
- pci->device == PCI_DEVICE_ID_INTEL_440MX)
- chip->fix_nocache = 1; /* enable workaround */
-
- if ((err = pci_request_regions(pci, card->shortname)) < 0) {
- kfree(chip);
- pci_disable_device(pci);
- return err;
- }
-
- if (device_type == DEVICE_ALI) {
- /* ALI5455 has no ac97 region */
- chip->bmaddr = pci_iomap(pci, 0, 0);
- goto port_inited;
- }
-
- if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) /* ICH4 and Nforce */
- chip->addr = pci_iomap(pci, 2, 0);
- else
- chip->addr = pci_iomap(pci, 0, 0);
- if (!chip->addr) {
- snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
- snd_intel8x0_free(chip);
- return -EIO;
- }
- if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) /* ICH4 */
- chip->bmaddr = pci_iomap(pci, 3, 0);
- else
- chip->bmaddr = pci_iomap(pci, 1, 0);
- if (!chip->bmaddr) {
- snd_printk(KERN_ERR "Controller space ioremap problem\n");
- snd_intel8x0_free(chip);
- return -EIO;
- }
-
- port_inited:
- chip->bdbars_count = bdbars[device_type];
-
- /* initialize offsets */
- switch (device_type) {
- case DEVICE_NFORCE:
- tbl = nforce_regs;
- break;
- case DEVICE_ALI:
- tbl = ali_regs;
- break;
- default:
- tbl = intel_regs;
- break;
- }
- for (i = 0; i < chip->bdbars_count; i++) {
- ichdev = &chip->ichd[i];
- ichdev->ichd = i;
- ichdev->reg_offset = tbl[i].offset;
- ichdev->int_sta_mask = tbl[i].int_sta_mask;
- if (device_type == DEVICE_SIS) {
- /* SiS 7012 swaps the registers */
- ichdev->roff_sr = ICH_REG_OFF_PICB;
- ichdev->roff_picb = ICH_REG_OFF_SR;
- } else {
- ichdev->roff_sr = ICH_REG_OFF_SR;
- ichdev->roff_picb = ICH_REG_OFF_PICB;
- }
- if (device_type == DEVICE_ALI)
- ichdev->ali_slot = (ichdev->reg_offset - 0x40) / 0x10;
- /* SIS7012 handles the pcm data in bytes, others are in samples */
- ichdev->pos_shift = (device_type == DEVICE_SIS) ? 0 : 1;
- }
-
- /* allocate buffer descriptor lists */
- /* the start of each lists must be aligned to 8 bytes */
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
- chip->bdbars_count * sizeof(u32) * ICH_MAX_FRAGS * 2,
- &chip->bdbars) < 0) {
- snd_intel8x0_free(chip);
- snd_printk(KERN_ERR "intel8x0: cannot allocate buffer descriptors\n");
- return -ENOMEM;
- }
- /* tables must be aligned to 8 bytes here, but the kernel pages
- are much bigger, so we don't care (on i386) */
- /* workaround for 440MX */
- if (chip->fix_nocache)
- fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 1);
- int_sta_masks = 0;
- for (i = 0; i < chip->bdbars_count; i++) {
- ichdev = &chip->ichd[i];
- ichdev->bdbar = ((u32 *)chip->bdbars.area) +
- (i * ICH_MAX_FRAGS * 2);
- ichdev->bdbar_addr = chip->bdbars.addr +
- (i * sizeof(u32) * ICH_MAX_FRAGS * 2);
- int_sta_masks |= ichdev->int_sta_mask;
- }
- chip->int_sta_reg = device_type == DEVICE_ALI ?
- ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA;
- chip->int_sta_mask = int_sta_masks;
-
- pci_set_master(pci);
-
- switch(chip->device_type) {
- case DEVICE_INTEL_ICH4:
- /* ICH4 can have three codecs */
- chip->max_codecs = 3;
- chip->codec_bit = ich_codec_bits;
- chip->codec_ready_bits = ICH_PRI | ICH_SRI | ICH_TRI;
- break;
- case DEVICE_SIS:
- /* recent SIS7012 can have three codecs */
- chip->max_codecs = 3;
- chip->codec_bit = sis_codec_bits;
- chip->codec_ready_bits = ICH_PRI | ICH_SRI | ICH_SIS_TRI;
- break;
- default:
- /* others up to two codecs */
- chip->max_codecs = 2;
- chip->codec_bit = ich_codec_bits;
- chip->codec_ready_bits = ICH_PRI | ICH_SRI;
- break;
- }
- for (i = 0; i < chip->max_codecs; i++)
- chip->codec_isr_bits |= chip->codec_bit[i];
-
- if ((err = snd_intel8x0_chip_init(chip, 1)) < 0) {
- snd_intel8x0_free(chip);
- return err;
- }
-
- /* request irq after initializaing int_sta_mask, etc */
- if (request_irq(pci->irq, snd_intel8x0_interrupt,
- IRQF_SHARED, KBUILD_MODNAME, chip)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_intel8x0_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_intel8x0_free(chip);
- return err;
- }
-
- snd_card_set_dev(card, &pci->dev);
-
- *r_intel8x0 = chip;
- return 0;
-}
-
-static struct shortname_table {
- unsigned int id;
- const char *s;
-} shortnames[] __devinitdata = {
- { PCI_DEVICE_ID_INTEL_82801AA_5, "Intel 82801AA-ICH" },
- { PCI_DEVICE_ID_INTEL_82801AB_5, "Intel 82901AB-ICH0" },
- { PCI_DEVICE_ID_INTEL_82801BA_4, "Intel 82801BA-ICH2" },
- { PCI_DEVICE_ID_INTEL_440MX, "Intel 440MX" },
- { PCI_DEVICE_ID_INTEL_82801CA_5, "Intel 82801CA-ICH3" },
- { PCI_DEVICE_ID_INTEL_82801DB_5, "Intel 82801DB-ICH4" },
- { PCI_DEVICE_ID_INTEL_82801EB_5, "Intel ICH5" },
- { PCI_DEVICE_ID_INTEL_ESB_5, "Intel 6300ESB" },
- { PCI_DEVICE_ID_INTEL_ICH6_18, "Intel ICH6" },
- { PCI_DEVICE_ID_INTEL_ICH7_20, "Intel ICH7" },
- { PCI_DEVICE_ID_INTEL_ESB2_14, "Intel ESB2" },
- { PCI_DEVICE_ID_SI_7012, "SiS SI7012" },
- { PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO, "NVidia nForce" },
- { PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO, "NVidia nForce2" },
- { PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO, "NVidia nForce3" },
- { PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO, "NVidia CK8S" },
- { PCI_DEVICE_ID_NVIDIA_CK804_AUDIO, "NVidia CK804" },
- { PCI_DEVICE_ID_NVIDIA_CK8_AUDIO, "NVidia CK8" },
- { 0x003a, "NVidia MCP04" },
- { 0x746d, "AMD AMD8111" },
- { 0x7445, "AMD AMD768" },
- { 0x5455, "ALi M5455" },
- { 0, NULL },
-};
-
-static struct snd_pci_quirk spdif_aclink_defaults[] __devinitdata = {
- SND_PCI_QUIRK(0x147b, 0x1c1a, "ASUS KN8", 1),
- { } /* end */
-};
-
-/* look up white/black list for SPDIF over ac-link */
-static int __devinit check_default_spdif_aclink(struct pci_dev *pci)
-{
- const struct snd_pci_quirk *w;
-
- w = snd_pci_quirk_lookup(pci, spdif_aclink_defaults);
- if (w) {
- if (w->value)
- snd_printdd(KERN_INFO "intel8x0: Using SPDIF over "
- "AC-Link for %s\n", w->name);
- else
- snd_printdd(KERN_INFO "intel8x0: Using integrated "
- "SPDIF DMA for %s\n", w->name);
- return w->value;
- }
- return 0;
-}
-
-static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- struct snd_card *card;
- struct intel8x0 *chip;
- int err;
- struct shortname_table *name;
-
- err = snd_card_create(index, id, THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- if (spdif_aclink < 0)
- spdif_aclink = check_default_spdif_aclink(pci);
-
- strcpy(card->driver, "ICH");
- if (!spdif_aclink) {
- switch (pci_id->driver_data) {
- case DEVICE_NFORCE:
- strcpy(card->driver, "NFORCE");
- break;
- case DEVICE_INTEL_ICH4:
- strcpy(card->driver, "ICH4");
- }
- }
-
- strcpy(card->shortname, "Intel ICH");
- for (name = shortnames; name->id; name++) {
- if (pci->device == name->id) {
- strcpy(card->shortname, name->s);
- break;
- }
- }
-
- if (buggy_irq < 0) {
- /* some Nforce[2] and ICH boards have problems with IRQ handling.
- * Needs to return IRQ_HANDLED for unknown irqs.
- */
- if (pci_id->driver_data == DEVICE_NFORCE)
- buggy_irq = 1;
- else
- buggy_irq = 0;
- }
-
- if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data,
- &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
- card->private_data = chip;
-
- if ((err = snd_intel8x0_mixer(chip, ac97_clock, ac97_quirk)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_intel8x0_pcm(chip)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- snd_intel8x0_proc_init(chip);
-
- snprintf(card->longname, sizeof(card->longname),
- "%s with %s at irq %i", card->shortname,
- snd_ac97_get_short_name(chip->ac97[0]), chip->irq);
-
- if (ac97_clock == 0 || ac97_clock == 1) {
- if (ac97_clock == 0) {
- if (intel8x0_in_clock_list(chip) == 0)
- intel8x0_measure_ac97_clock(chip);
- } else {
- intel8x0_measure_ac97_clock(chip);
- }
- }
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- pci_set_drvdata(pci, card);
- return 0;
-}
-
-static void __devexit snd_intel8x0_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_intel8x0_ids,
- .probe = snd_intel8x0_probe,
- .remove = __devexit_p(snd_intel8x0_remove),
-#ifdef CONFIG_PM
- .suspend = intel8x0_suspend,
- .resume = intel8x0_resume,
-#endif
-};
-
-
-static int __init alsa_card_intel8x0_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_intel8x0_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_intel8x0_init)
-module_exit(alsa_card_intel8x0_exit)
diff --git a/ANDROID_3.4.5/sound/pci/intel8x0m.c b/ANDROID_3.4.5/sound/pci/intel8x0m.c
deleted file mode 100644
index d689913a..00000000
--- a/ANDROID_3.4.5/sound/pci/intel8x0m.c
+++ /dev/null
@@ -1,1350 +0,0 @@
-/*
- * ALSA modem driver for Intel ICH (i8x0) chipsets
- *
- * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
- *
- * This is modified (by Sasha Khapyorsky <sashak@alsa-project.org>) version
- * of ALSA ICH sound driver intel8x0.c .
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/info.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; "
- "SiS 7013; NVidia MCP/2/2S/3 modems");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Intel,82801AA-ICH},"
- "{Intel,82901AB-ICH0},"
- "{Intel,82801BA-ICH2},"
- "{Intel,82801CA-ICH3},"
- "{Intel,82801DB-ICH4},"
- "{Intel,ICH5},"
- "{Intel,ICH6},"
- "{Intel,ICH7},"
- "{Intel,MX440},"
- "{SiS,7013},"
- "{NVidia,NForce Modem},"
- "{NVidia,NForce2 Modem},"
- "{NVidia,NForce2s Modem},"
- "{NVidia,NForce3 Modem},"
- "{AMD,AMD768}}");
-
-static int index = -2; /* Exclude the first card */
-static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-static int ac97_clock;
-
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for Intel i8x0 modemcard.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for Intel i8x0 modemcard.");
-module_param(ac97_clock, int, 0444);
-MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
-
-/* just for backward compatibility */
-static bool enable;
-module_param(enable, bool, 0444);
-
-/*
- * Direct registers
- */
-enum { DEVICE_INTEL, DEVICE_SIS, DEVICE_ALI, DEVICE_NFORCE };
-
-#define ICHREG(x) ICH_REG_##x
-
-#define DEFINE_REGSET(name,base) \
-enum { \
- ICH_REG_##name##_BDBAR = base + 0x0, /* dword - buffer descriptor list base address */ \
- ICH_REG_##name##_CIV = base + 0x04, /* byte - current index value */ \
- ICH_REG_##name##_LVI = base + 0x05, /* byte - last valid index */ \
- ICH_REG_##name##_SR = base + 0x06, /* byte - status register */ \
- ICH_REG_##name##_PICB = base + 0x08, /* word - position in current buffer */ \
- ICH_REG_##name##_PIV = base + 0x0a, /* byte - prefetched index value */ \
- ICH_REG_##name##_CR = base + 0x0b, /* byte - control register */ \
-};
-
-/* busmaster blocks */
-DEFINE_REGSET(OFF, 0); /* offset */
-
-/* values for each busmaster block */
-
-/* LVI */
-#define ICH_REG_LVI_MASK 0x1f
-
-/* SR */
-#define ICH_FIFOE 0x10 /* FIFO error */
-#define ICH_BCIS 0x08 /* buffer completion interrupt status */
-#define ICH_LVBCI 0x04 /* last valid buffer completion interrupt */
-#define ICH_CELV 0x02 /* current equals last valid */
-#define ICH_DCH 0x01 /* DMA controller halted */
-
-/* PIV */
-#define ICH_REG_PIV_MASK 0x1f /* mask */
-
-/* CR */
-#define ICH_IOCE 0x10 /* interrupt on completion enable */
-#define ICH_FEIE 0x08 /* fifo error interrupt enable */
-#define ICH_LVBIE 0x04 /* last valid buffer interrupt enable */
-#define ICH_RESETREGS 0x02 /* reset busmaster registers */
-#define ICH_STARTBM 0x01 /* start busmaster operation */
-
-
-/* global block */
-#define ICH_REG_GLOB_CNT 0x3c /* dword - global control */
-#define ICH_TRIE 0x00000040 /* tertiary resume interrupt enable */
-#define ICH_SRIE 0x00000020 /* secondary resume interrupt enable */
-#define ICH_PRIE 0x00000010 /* primary resume interrupt enable */
-#define ICH_ACLINK 0x00000008 /* AClink shut off */
-#define ICH_AC97WARM 0x00000004 /* AC'97 warm reset */
-#define ICH_AC97COLD 0x00000002 /* AC'97 cold reset */
-#define ICH_GIE 0x00000001 /* GPI interrupt enable */
-#define ICH_REG_GLOB_STA 0x40 /* dword - global status */
-#define ICH_TRI 0x20000000 /* ICH4: tertiary (AC_SDIN2) resume interrupt */
-#define ICH_TCR 0x10000000 /* ICH4: tertiary (AC_SDIN2) codec ready */
-#define ICH_BCS 0x08000000 /* ICH4: bit clock stopped */
-#define ICH_SPINT 0x04000000 /* ICH4: S/PDIF interrupt */
-#define ICH_P2INT 0x02000000 /* ICH4: PCM2-In interrupt */
-#define ICH_M2INT 0x01000000 /* ICH4: Mic2-In interrupt */
-#define ICH_SAMPLE_CAP 0x00c00000 /* ICH4: sample capability bits (RO) */
-#define ICH_MULTICHAN_CAP 0x00300000 /* ICH4: multi-channel capability bits (RO) */
-#define ICH_MD3 0x00020000 /* modem power down semaphore */
-#define ICH_AD3 0x00010000 /* audio power down semaphore */
-#define ICH_RCS 0x00008000 /* read completion status */
-#define ICH_BIT3 0x00004000 /* bit 3 slot 12 */
-#define ICH_BIT2 0x00002000 /* bit 2 slot 12 */
-#define ICH_BIT1 0x00001000 /* bit 1 slot 12 */
-#define ICH_SRI 0x00000800 /* secondary (AC_SDIN1) resume interrupt */
-#define ICH_PRI 0x00000400 /* primary (AC_SDIN0) resume interrupt */
-#define ICH_SCR 0x00000200 /* secondary (AC_SDIN1) codec ready */
-#define ICH_PCR 0x00000100 /* primary (AC_SDIN0) codec ready */
-#define ICH_MCINT 0x00000080 /* MIC capture interrupt */
-#define ICH_POINT 0x00000040 /* playback interrupt */
-#define ICH_PIINT 0x00000020 /* capture interrupt */
-#define ICH_NVSPINT 0x00000010 /* nforce spdif interrupt */
-#define ICH_MOINT 0x00000004 /* modem playback interrupt */
-#define ICH_MIINT 0x00000002 /* modem capture interrupt */
-#define ICH_GSCI 0x00000001 /* GPI status change interrupt */
-#define ICH_REG_ACC_SEMA 0x44 /* byte - codec write semaphore */
-#define ICH_CAS 0x01 /* codec access semaphore */
-
-#define ICH_MAX_FRAGS 32 /* max hw frags */
-
-
-/*
- *
- */
-
-enum { ICHD_MDMIN, ICHD_MDMOUT, ICHD_MDMLAST = ICHD_MDMOUT };
-enum { ALID_MDMIN, ALID_MDMOUT, ALID_MDMLAST = ALID_MDMOUT };
-
-#define get_ichdev(substream) (substream->runtime->private_data)
-
-struct ichdev {
- unsigned int ichd; /* ich device number */
- unsigned long reg_offset; /* offset to bmaddr */
- u32 *bdbar; /* CPU address (32bit) */
- unsigned int bdbar_addr; /* PCI bus address (32bit) */
- struct snd_pcm_substream *substream;
- unsigned int physbuf; /* physical address (32bit) */
- unsigned int size;
- unsigned int fragsize;
- unsigned int fragsize1;
- unsigned int position;
- int frags;
- int lvi;
- int lvi_frag;
- int civ;
- int ack;
- int ack_reload;
- unsigned int ack_bit;
- unsigned int roff_sr;
- unsigned int roff_picb;
- unsigned int int_sta_mask; /* interrupt status mask */
- unsigned int ali_slot; /* ALI DMA slot */
- struct snd_ac97 *ac97;
-};
-
-struct intel8x0m {
- unsigned int device_type;
-
- int irq;
-
- void __iomem *addr;
- void __iomem *bmaddr;
-
- struct pci_dev *pci;
- struct snd_card *card;
-
- int pcm_devs;
- struct snd_pcm *pcm[2];
- struct ichdev ichd[2];
-
- unsigned int in_ac97_init: 1;
-
- struct snd_ac97_bus *ac97_bus;
- struct snd_ac97 *ac97;
-
- spinlock_t reg_lock;
-
- struct snd_dma_buffer bdbars;
- u32 bdbars_count;
- u32 int_sta_reg; /* interrupt status register */
- u32 int_sta_mask; /* interrupt status mask */
- unsigned int pcm_pos_shift;
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_intel8x0m_ids) = {
- { PCI_VDEVICE(INTEL, 0x2416), DEVICE_INTEL }, /* 82801AA */
- { PCI_VDEVICE(INTEL, 0x2426), DEVICE_INTEL }, /* 82901AB */
- { PCI_VDEVICE(INTEL, 0x2446), DEVICE_INTEL }, /* 82801BA */
- { PCI_VDEVICE(INTEL, 0x2486), DEVICE_INTEL }, /* ICH3 */
- { PCI_VDEVICE(INTEL, 0x24c6), DEVICE_INTEL }, /* ICH4 */
- { PCI_VDEVICE(INTEL, 0x24d6), DEVICE_INTEL }, /* ICH5 */
- { PCI_VDEVICE(INTEL, 0x266d), DEVICE_INTEL }, /* ICH6 */
- { PCI_VDEVICE(INTEL, 0x27dd), DEVICE_INTEL }, /* ICH7 */
- { PCI_VDEVICE(INTEL, 0x7196), DEVICE_INTEL }, /* 440MX */
- { PCI_VDEVICE(AMD, 0x7446), DEVICE_INTEL }, /* AMD768 */
- { PCI_VDEVICE(SI, 0x7013), DEVICE_SIS }, /* SI7013 */
- { PCI_VDEVICE(NVIDIA, 0x01c1), DEVICE_NFORCE }, /* NFORCE */
- { PCI_VDEVICE(NVIDIA, 0x0069), DEVICE_NFORCE }, /* NFORCE2 */
- { PCI_VDEVICE(NVIDIA, 0x0089), DEVICE_NFORCE }, /* NFORCE2s */
- { PCI_VDEVICE(NVIDIA, 0x00d9), DEVICE_NFORCE }, /* NFORCE3 */
- { PCI_VDEVICE(AMD, 0x746e), DEVICE_INTEL }, /* AMD8111 */
-#if 0
- { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */
-#endif
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
-
-/*
- * Lowlevel I/O - busmaster
- */
-
-static inline u8 igetbyte(struct intel8x0m *chip, u32 offset)
-{
- return ioread8(chip->bmaddr + offset);
-}
-
-static inline u16 igetword(struct intel8x0m *chip, u32 offset)
-{
- return ioread16(chip->bmaddr + offset);
-}
-
-static inline u32 igetdword(struct intel8x0m *chip, u32 offset)
-{
- return ioread32(chip->bmaddr + offset);
-}
-
-static inline void iputbyte(struct intel8x0m *chip, u32 offset, u8 val)
-{
- iowrite8(val, chip->bmaddr + offset);
-}
-
-static inline void iputword(struct intel8x0m *chip, u32 offset, u16 val)
-{
- iowrite16(val, chip->bmaddr + offset);
-}
-
-static inline void iputdword(struct intel8x0m *chip, u32 offset, u32 val)
-{
- iowrite32(val, chip->bmaddr + offset);
-}
-
-/*
- * Lowlevel I/O - AC'97 registers
- */
-
-static inline u16 iagetword(struct intel8x0m *chip, u32 offset)
-{
- return ioread16(chip->addr + offset);
-}
-
-static inline void iaputword(struct intel8x0m *chip, u32 offset, u16 val)
-{
- iowrite16(val, chip->addr + offset);
-}
-
-/*
- * Basic I/O
- */
-
-/*
- * access to AC97 codec via normal i/o (for ICH and SIS7013)
- */
-
-/* return the GLOB_STA bit for the corresponding codec */
-static unsigned int get_ich_codec_bit(struct intel8x0m *chip, unsigned int codec)
-{
- static unsigned int codec_bit[3] = {
- ICH_PCR, ICH_SCR, ICH_TCR
- };
- if (snd_BUG_ON(codec >= 3))
- return ICH_PCR;
- return codec_bit[codec];
-}
-
-static int snd_intel8x0m_codec_semaphore(struct intel8x0m *chip, unsigned int codec)
-{
- int time;
-
- if (codec > 1)
- return -EIO;
- codec = get_ich_codec_bit(chip, codec);
-
- /* codec ready ? */
- if ((igetdword(chip, ICHREG(GLOB_STA)) & codec) == 0)
- return -EIO;
-
- /* Anyone holding a semaphore for 1 msec should be shot... */
- time = 100;
- do {
- if (!(igetbyte(chip, ICHREG(ACC_SEMA)) & ICH_CAS))
- return 0;
- udelay(10);
- } while (time--);
-
- /* access to some forbidden (non existent) ac97 registers will not
- * reset the semaphore. So even if you don't get the semaphore, still
- * continue the access. We don't need the semaphore anyway. */
- snd_printk(KERN_ERR "codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
- igetbyte(chip, ICHREG(ACC_SEMA)), igetdword(chip, ICHREG(GLOB_STA)));
- iagetword(chip, 0); /* clear semaphore flag */
- /* I don't care about the semaphore */
- return -EBUSY;
-}
-
-static void snd_intel8x0m_codec_write(struct snd_ac97 *ac97,
- unsigned short reg,
- unsigned short val)
-{
- struct intel8x0m *chip = ac97->private_data;
-
- if (snd_intel8x0m_codec_semaphore(chip, ac97->num) < 0) {
- if (! chip->in_ac97_init)
- snd_printk(KERN_ERR "codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
- }
- iaputword(chip, reg + ac97->num * 0x80, val);
-}
-
-static unsigned short snd_intel8x0m_codec_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- struct intel8x0m *chip = ac97->private_data;
- unsigned short res;
- unsigned int tmp;
-
- if (snd_intel8x0m_codec_semaphore(chip, ac97->num) < 0) {
- if (! chip->in_ac97_init)
- snd_printk(KERN_ERR "codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
- res = 0xffff;
- } else {
- res = iagetword(chip, reg + ac97->num * 0x80);
- if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) {
- /* reset RCS and preserve other R/WC bits */
- iputdword(chip, ICHREG(GLOB_STA),
- tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
- if (! chip->in_ac97_init)
- snd_printk(KERN_ERR "codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
- res = 0xffff;
- }
- }
- if (reg == AC97_GPIO_STATUS)
- iagetword(chip, 0); /* clear semaphore */
- return res;
-}
-
-
-/*
- * DMA I/O
- */
-static void snd_intel8x0m_setup_periods(struct intel8x0m *chip, struct ichdev *ichdev)
-{
- int idx;
- u32 *bdbar = ichdev->bdbar;
- unsigned long port = ichdev->reg_offset;
-
- iputdword(chip, port + ICH_REG_OFF_BDBAR, ichdev->bdbar_addr);
- if (ichdev->size == ichdev->fragsize) {
- ichdev->ack_reload = ichdev->ack = 2;
- ichdev->fragsize1 = ichdev->fragsize >> 1;
- for (idx = 0; idx < (ICH_REG_LVI_MASK + 1) * 2; idx += 4) {
- bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf);
- bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */
- ichdev->fragsize1 >> chip->pcm_pos_shift);
- bdbar[idx + 2] = cpu_to_le32(ichdev->physbuf + (ichdev->size >> 1));
- bdbar[idx + 3] = cpu_to_le32(0x80000000 | /* interrupt on completion */
- ichdev->fragsize1 >> chip->pcm_pos_shift);
- }
- ichdev->frags = 2;
- } else {
- ichdev->ack_reload = ichdev->ack = 1;
- ichdev->fragsize1 = ichdev->fragsize;
- for (idx = 0; idx < (ICH_REG_LVI_MASK + 1) * 2; idx += 2) {
- bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf + (((idx >> 1) * ichdev->fragsize) % ichdev->size));
- bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */
- ichdev->fragsize >> chip->pcm_pos_shift);
- /*
- printk(KERN_DEBUG "bdbar[%i] = 0x%x [0x%x]\n",
- idx + 0, bdbar[idx + 0], bdbar[idx + 1]);
- */
- }
- ichdev->frags = ichdev->size / ichdev->fragsize;
- }
- iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi = ICH_REG_LVI_MASK);
- ichdev->civ = 0;
- iputbyte(chip, port + ICH_REG_OFF_CIV, 0);
- ichdev->lvi_frag = ICH_REG_LVI_MASK % ichdev->frags;
- ichdev->position = 0;
-#if 0
- printk(KERN_DEBUG "lvi_frag = %i, frags = %i, period_size = 0x%x, "
- "period_size1 = 0x%x\n",
- ichdev->lvi_frag, ichdev->frags, ichdev->fragsize,
- ichdev->fragsize1);
-#endif
- /* clear interrupts */
- iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
-}
-
-/*
- * Interrupt handler
- */
-
-static inline void snd_intel8x0m_update(struct intel8x0m *chip, struct ichdev *ichdev)
-{
- unsigned long port = ichdev->reg_offset;
- int civ, i, step;
- int ack = 0;
-
- civ = igetbyte(chip, port + ICH_REG_OFF_CIV);
- if (civ == ichdev->civ) {
- // snd_printd("civ same %d\n", civ);
- step = 1;
- ichdev->civ++;
- ichdev->civ &= ICH_REG_LVI_MASK;
- } else {
- step = civ - ichdev->civ;
- if (step < 0)
- step += ICH_REG_LVI_MASK + 1;
- // if (step != 1)
- // snd_printd("step = %d, %d -> %d\n", step, ichdev->civ, civ);
- ichdev->civ = civ;
- }
-
- ichdev->position += step * ichdev->fragsize1;
- ichdev->position %= ichdev->size;
- ichdev->lvi += step;
- ichdev->lvi &= ICH_REG_LVI_MASK;
- iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi);
- for (i = 0; i < step; i++) {
- ichdev->lvi_frag++;
- ichdev->lvi_frag %= ichdev->frags;
- ichdev->bdbar[ichdev->lvi * 2] = cpu_to_le32(ichdev->physbuf +
- ichdev->lvi_frag *
- ichdev->fragsize1);
-#if 0
- printk(KERN_DEBUG "new: bdbar[%i] = 0x%x [0x%x], "
- "prefetch = %i, all = 0x%x, 0x%x\n",
- ichdev->lvi * 2, ichdev->bdbar[ichdev->lvi * 2],
- ichdev->bdbar[ichdev->lvi * 2 + 1], inb(ICH_REG_OFF_PIV + port),
- inl(port + 4), inb(port + ICH_REG_OFF_CR));
-#endif
- if (--ichdev->ack == 0) {
- ichdev->ack = ichdev->ack_reload;
- ack = 1;
- }
- }
- if (ack && ichdev->substream) {
- spin_unlock(&chip->reg_lock);
- snd_pcm_period_elapsed(ichdev->substream);
- spin_lock(&chip->reg_lock);
- }
- iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
-}
-
-static irqreturn_t snd_intel8x0m_interrupt(int irq, void *dev_id)
-{
- struct intel8x0m *chip = dev_id;
- struct ichdev *ichdev;
- unsigned int status;
- unsigned int i;
-
- spin_lock(&chip->reg_lock);
- status = igetdword(chip, chip->int_sta_reg);
- if (status == 0xffffffff) { /* we are not yet resumed */
- spin_unlock(&chip->reg_lock);
- return IRQ_NONE;
- }
- if ((status & chip->int_sta_mask) == 0) {
- if (status)
- iputdword(chip, chip->int_sta_reg, status);
- spin_unlock(&chip->reg_lock);
- return IRQ_NONE;
- }
-
- for (i = 0; i < chip->bdbars_count; i++) {
- ichdev = &chip->ichd[i];
- if (status & ichdev->int_sta_mask)
- snd_intel8x0m_update(chip, ichdev);
- }
-
- /* ack them */
- iputdword(chip, chip->int_sta_reg, status & chip->int_sta_mask);
- spin_unlock(&chip->reg_lock);
-
- return IRQ_HANDLED;
-}
-
-/*
- * PCM part
- */
-
-static int snd_intel8x0m_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct intel8x0m *chip = snd_pcm_substream_chip(substream);
- struct ichdev *ichdev = get_ichdev(substream);
- unsigned char val = 0;
- unsigned long port = ichdev->reg_offset;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- val = ICH_IOCE | ICH_STARTBM;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- val = 0;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- val = ICH_IOCE;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- val = ICH_IOCE | ICH_STARTBM;
- break;
- default:
- return -EINVAL;
- }
- iputbyte(chip, port + ICH_REG_OFF_CR, val);
- if (cmd == SNDRV_PCM_TRIGGER_STOP) {
- /* wait until DMA stopped */
- while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH)) ;
- /* reset whole DMA things */
- iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS);
- }
- return 0;
-}
-
-static int snd_intel8x0m_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static int snd_intel8x0m_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static snd_pcm_uframes_t snd_intel8x0m_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct intel8x0m *chip = snd_pcm_substream_chip(substream);
- struct ichdev *ichdev = get_ichdev(substream);
- size_t ptr1, ptr;
-
- ptr1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb) << chip->pcm_pos_shift;
- if (ptr1 != 0)
- ptr = ichdev->fragsize1 - ptr1;
- else
- ptr = 0;
- ptr += ichdev->position;
- if (ptr >= ichdev->size)
- return 0;
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-static int snd_intel8x0m_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct intel8x0m *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct ichdev *ichdev = get_ichdev(substream);
-
- ichdev->physbuf = runtime->dma_addr;
- ichdev->size = snd_pcm_lib_buffer_bytes(substream);
- ichdev->fragsize = snd_pcm_lib_period_bytes(substream);
- snd_ac97_write(ichdev->ac97, AC97_LINE1_RATE, runtime->rate);
- snd_ac97_write(ichdev->ac97, AC97_LINE1_LEVEL, 0);
- snd_intel8x0m_setup_periods(chip, ichdev);
- return 0;
-}
-
-static struct snd_pcm_hardware snd_intel8x0m_stream =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_KNOT,
- .rate_min = 8000,
- .rate_max = 16000,
- .channels_min = 1,
- .channels_max = 1,
- .buffer_bytes_max = 64 * 1024,
- .period_bytes_min = 32,
- .period_bytes_max = 64 * 1024,
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-
-static int snd_intel8x0m_pcm_open(struct snd_pcm_substream *substream, struct ichdev *ichdev)
-{
- static unsigned int rates[] = { 8000, 9600, 12000, 16000 };
- static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
- .count = ARRAY_SIZE(rates),
- .list = rates,
- .mask = 0,
- };
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- ichdev->substream = substream;
- runtime->hw = snd_intel8x0m_stream;
- err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &hw_constraints_rates);
- if ( err < 0 )
- return err;
- runtime->private_data = ichdev;
- return 0;
-}
-
-static int snd_intel8x0m_playback_open(struct snd_pcm_substream *substream)
-{
- struct intel8x0m *chip = snd_pcm_substream_chip(substream);
-
- return snd_intel8x0m_pcm_open(substream, &chip->ichd[ICHD_MDMOUT]);
-}
-
-static int snd_intel8x0m_playback_close(struct snd_pcm_substream *substream)
-{
- struct intel8x0m *chip = snd_pcm_substream_chip(substream);
-
- chip->ichd[ICHD_MDMOUT].substream = NULL;
- return 0;
-}
-
-static int snd_intel8x0m_capture_open(struct snd_pcm_substream *substream)
-{
- struct intel8x0m *chip = snd_pcm_substream_chip(substream);
-
- return snd_intel8x0m_pcm_open(substream, &chip->ichd[ICHD_MDMIN]);
-}
-
-static int snd_intel8x0m_capture_close(struct snd_pcm_substream *substream)
-{
- struct intel8x0m *chip = snd_pcm_substream_chip(substream);
-
- chip->ichd[ICHD_MDMIN].substream = NULL;
- return 0;
-}
-
-
-static struct snd_pcm_ops snd_intel8x0m_playback_ops = {
- .open = snd_intel8x0m_playback_open,
- .close = snd_intel8x0m_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_intel8x0m_hw_params,
- .hw_free = snd_intel8x0m_hw_free,
- .prepare = snd_intel8x0m_pcm_prepare,
- .trigger = snd_intel8x0m_pcm_trigger,
- .pointer = snd_intel8x0m_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_intel8x0m_capture_ops = {
- .open = snd_intel8x0m_capture_open,
- .close = snd_intel8x0m_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_intel8x0m_hw_params,
- .hw_free = snd_intel8x0m_hw_free,
- .prepare = snd_intel8x0m_pcm_prepare,
- .trigger = snd_intel8x0m_pcm_trigger,
- .pointer = snd_intel8x0m_pcm_pointer,
-};
-
-
-struct ich_pcm_table {
- char *suffix;
- struct snd_pcm_ops *playback_ops;
- struct snd_pcm_ops *capture_ops;
- size_t prealloc_size;
- size_t prealloc_max_size;
- int ac97_idx;
-};
-
-static int __devinit snd_intel8x0m_pcm1(struct intel8x0m *chip, int device,
- struct ich_pcm_table *rec)
-{
- struct snd_pcm *pcm;
- int err;
- char name[32];
-
- if (rec->suffix)
- sprintf(name, "Intel ICH - %s", rec->suffix);
- else
- strcpy(name, "Intel ICH");
- err = snd_pcm_new(chip->card, name, device,
- rec->playback_ops ? 1 : 0,
- rec->capture_ops ? 1 : 0, &pcm);
- if (err < 0)
- return err;
-
- if (rec->playback_ops)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, rec->playback_ops);
- if (rec->capture_ops)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, rec->capture_ops);
-
- pcm->private_data = chip;
- pcm->info_flags = 0;
- pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
- if (rec->suffix)
- sprintf(pcm->name, "%s - %s", chip->card->shortname, rec->suffix);
- else
- strcpy(pcm->name, chip->card->shortname);
- chip->pcm[device] = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- rec->prealloc_size,
- rec->prealloc_max_size);
-
- return 0;
-}
-
-static struct ich_pcm_table intel_pcms[] __devinitdata = {
- {
- .suffix = "Modem",
- .playback_ops = &snd_intel8x0m_playback_ops,
- .capture_ops = &snd_intel8x0m_capture_ops,
- .prealloc_size = 32 * 1024,
- .prealloc_max_size = 64 * 1024,
- },
-};
-
-static int __devinit snd_intel8x0m_pcm(struct intel8x0m *chip)
-{
- int i, tblsize, device, err;
- struct ich_pcm_table *tbl, *rec;
-
-#if 1
- tbl = intel_pcms;
- tblsize = 1;
-#else
- switch (chip->device_type) {
- case DEVICE_NFORCE:
- tbl = nforce_pcms;
- tblsize = ARRAY_SIZE(nforce_pcms);
- break;
- case DEVICE_ALI:
- tbl = ali_pcms;
- tblsize = ARRAY_SIZE(ali_pcms);
- break;
- default:
- tbl = intel_pcms;
- tblsize = 2;
- break;
- }
-#endif
- device = 0;
- for (i = 0; i < tblsize; i++) {
- rec = tbl + i;
- if (i > 0 && rec->ac97_idx) {
- /* activate PCM only when associated AC'97 codec */
- if (! chip->ichd[rec->ac97_idx].ac97)
- continue;
- }
- err = snd_intel8x0m_pcm1(chip, device, rec);
- if (err < 0)
- return err;
- device++;
- }
-
- chip->pcm_devs = device;
- return 0;
-}
-
-
-/*
- * Mixer part
- */
-
-static void snd_intel8x0m_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
-{
- struct intel8x0m *chip = bus->private_data;
- chip->ac97_bus = NULL;
-}
-
-static void snd_intel8x0m_mixer_free_ac97(struct snd_ac97 *ac97)
-{
- struct intel8x0m *chip = ac97->private_data;
- chip->ac97 = NULL;
-}
-
-
-static int __devinit snd_intel8x0m_mixer(struct intel8x0m *chip, int ac97_clock)
-{
- struct snd_ac97_bus *pbus;
- struct snd_ac97_template ac97;
- struct snd_ac97 *x97;
- int err;
- unsigned int glob_sta = 0;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_intel8x0m_codec_write,
- .read = snd_intel8x0m_codec_read,
- };
-
- chip->in_ac97_init = 1;
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = chip;
- ac97.private_free = snd_intel8x0m_mixer_free_ac97;
- ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
-
- glob_sta = igetdword(chip, ICHREG(GLOB_STA));
-
- if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
- goto __err;
- pbus->private_free = snd_intel8x0m_mixer_free_ac97_bus;
- if (ac97_clock >= 8000 && ac97_clock <= 48000)
- pbus->clock = ac97_clock;
- chip->ac97_bus = pbus;
-
- ac97.pci = chip->pci;
- ac97.num = glob_sta & ICH_SCR ? 1 : 0;
- if ((err = snd_ac97_mixer(pbus, &ac97, &x97)) < 0) {
- snd_printk(KERN_ERR "Unable to initialize codec #%d\n", ac97.num);
- if (ac97.num == 0)
- goto __err;
- return err;
- }
- chip->ac97 = x97;
- if(ac97_is_modem(x97) && !chip->ichd[ICHD_MDMIN].ac97) {
- chip->ichd[ICHD_MDMIN].ac97 = x97;
- chip->ichd[ICHD_MDMOUT].ac97 = x97;
- }
-
- chip->in_ac97_init = 0;
- return 0;
-
- __err:
- /* clear the cold-reset bit for the next chance */
- if (chip->device_type != DEVICE_ALI)
- iputdword(chip, ICHREG(GLOB_CNT),
- igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_AC97COLD);
- return err;
-}
-
-
-/*
- *
- */
-
-static int snd_intel8x0m_ich_chip_init(struct intel8x0m *chip, int probing)
-{
- unsigned long end_time;
- unsigned int cnt, status, nstatus;
-
- /* put logic to right state */
- /* first clear status bits */
- status = ICH_RCS | ICH_MIINT | ICH_MOINT;
- cnt = igetdword(chip, ICHREG(GLOB_STA));
- iputdword(chip, ICHREG(GLOB_STA), cnt & status);
-
- /* ACLink on, 2 channels */
- cnt = igetdword(chip, ICHREG(GLOB_CNT));
- cnt &= ~(ICH_ACLINK);
- /* finish cold or do warm reset */
- cnt |= (cnt & ICH_AC97COLD) == 0 ? ICH_AC97COLD : ICH_AC97WARM;
- iputdword(chip, ICHREG(GLOB_CNT), cnt);
- usleep_range(500, 1000); /* give warm reset some time */
- end_time = jiffies + HZ / 4;
- do {
- if ((igetdword(chip, ICHREG(GLOB_CNT)) & ICH_AC97WARM) == 0)
- goto __ok;
- schedule_timeout_uninterruptible(1);
- } while (time_after_eq(end_time, jiffies));
- snd_printk(KERN_ERR "AC'97 warm reset still in progress? [0x%x]\n",
- igetdword(chip, ICHREG(GLOB_CNT)));
- return -EIO;
-
- __ok:
- if (probing) {
- /* wait for any codec ready status.
- * Once it becomes ready it should remain ready
- * as long as we do not disable the ac97 link.
- */
- end_time = jiffies + HZ;
- do {
- status = igetdword(chip, ICHREG(GLOB_STA)) &
- (ICH_PCR | ICH_SCR | ICH_TCR);
- if (status)
- break;
- schedule_timeout_uninterruptible(1);
- } while (time_after_eq(end_time, jiffies));
- if (! status) {
- /* no codec is found */
- snd_printk(KERN_ERR "codec_ready: codec is not ready [0x%x]\n",
- igetdword(chip, ICHREG(GLOB_STA)));
- return -EIO;
- }
-
- /* up to two codecs (modem cannot be tertiary with ICH4) */
- nstatus = ICH_PCR | ICH_SCR;
-
- /* wait for other codecs ready status. */
- end_time = jiffies + HZ / 4;
- while (status != nstatus && time_after_eq(end_time, jiffies)) {
- schedule_timeout_uninterruptible(1);
- status |= igetdword(chip, ICHREG(GLOB_STA)) & nstatus;
- }
-
- } else {
- /* resume phase */
- status = 0;
- if (chip->ac97)
- status |= get_ich_codec_bit(chip, chip->ac97->num);
- /* wait until all the probed codecs are ready */
- end_time = jiffies + HZ;
- do {
- nstatus = igetdword(chip, ICHREG(GLOB_STA)) &
- (ICH_PCR | ICH_SCR | ICH_TCR);
- if (status == nstatus)
- break;
- schedule_timeout_uninterruptible(1);
- } while (time_after_eq(end_time, jiffies));
- }
-
- if (chip->device_type == DEVICE_SIS) {
- /* unmute the output on SIS7012 */
- iputword(chip, 0x4c, igetword(chip, 0x4c) | 1);
- }
-
- return 0;
-}
-
-static int snd_intel8x0m_chip_init(struct intel8x0m *chip, int probing)
-{
- unsigned int i;
- int err;
-
- if ((err = snd_intel8x0m_ich_chip_init(chip, probing)) < 0)
- return err;
- iagetword(chip, 0); /* clear semaphore flag */
-
- /* disable interrupts */
- for (i = 0; i < chip->bdbars_count; i++)
- iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, 0x00);
- /* reset channels */
- for (i = 0; i < chip->bdbars_count; i++)
- iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS);
- /* initialize Buffer Descriptor Lists */
- for (i = 0; i < chip->bdbars_count; i++)
- iputdword(chip, ICH_REG_OFF_BDBAR + chip->ichd[i].reg_offset, chip->ichd[i].bdbar_addr);
- return 0;
-}
-
-static int snd_intel8x0m_free(struct intel8x0m *chip)
-{
- unsigned int i;
-
- if (chip->irq < 0)
- goto __hw_end;
- /* disable interrupts */
- for (i = 0; i < chip->bdbars_count; i++)
- iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, 0x00);
- /* reset channels */
- for (i = 0; i < chip->bdbars_count; i++)
- iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS);
- __hw_end:
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
- if (chip->bdbars.area)
- snd_dma_free_pages(&chip->bdbars);
- if (chip->addr)
- pci_iounmap(chip->pci, chip->addr);
- if (chip->bmaddr)
- pci_iounmap(chip->pci, chip->bmaddr);
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
- kfree(chip);
- return 0;
-}
-
-#ifdef CONFIG_PM
-/*
- * power management
- */
-static int intel8x0m_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct intel8x0m *chip = card->private_data;
- int i;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- for (i = 0; i < chip->pcm_devs; i++)
- snd_pcm_suspend_all(chip->pcm[i]);
- snd_ac97_suspend(chip->ac97);
- if (chip->irq >= 0) {
- free_irq(chip->irq, chip);
- chip->irq = -1;
- }
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int intel8x0m_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct intel8x0m *chip = card->private_data;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "intel8x0m: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
- if (request_irq(pci->irq, snd_intel8x0m_interrupt,
- IRQF_SHARED, KBUILD_MODNAME, chip)) {
- printk(KERN_ERR "intel8x0m: unable to grab IRQ %d, "
- "disabling device\n", pci->irq);
- snd_card_disconnect(card);
- return -EIO;
- }
- chip->irq = pci->irq;
- snd_intel8x0m_chip_init(chip, 0);
- snd_ac97_resume(chip->ac97);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif /* CONFIG_PM */
-
-#ifdef CONFIG_PROC_FS
-static void snd_intel8x0m_proc_read(struct snd_info_entry * entry,
- struct snd_info_buffer *buffer)
-{
- struct intel8x0m *chip = entry->private_data;
- unsigned int tmp;
-
- snd_iprintf(buffer, "Intel8x0m\n\n");
- if (chip->device_type == DEVICE_ALI)
- return;
- tmp = igetdword(chip, ICHREG(GLOB_STA));
- snd_iprintf(buffer, "Global control : 0x%08x\n",
- igetdword(chip, ICHREG(GLOB_CNT)));
- snd_iprintf(buffer, "Global status : 0x%08x\n", tmp);
- snd_iprintf(buffer, "AC'97 codecs ready :%s%s%s%s\n",
- tmp & ICH_PCR ? " primary" : "",
- tmp & ICH_SCR ? " secondary" : "",
- tmp & ICH_TCR ? " tertiary" : "",
- (tmp & (ICH_PCR | ICH_SCR | ICH_TCR)) == 0 ? " none" : "");
-}
-
-static void __devinit snd_intel8x0m_proc_init(struct intel8x0m * chip)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(chip->card, "intel8x0m", &entry))
- snd_info_set_text_ops(entry, chip, snd_intel8x0m_proc_read);
-}
-#else /* !CONFIG_PROC_FS */
-#define snd_intel8x0m_proc_init(chip)
-#endif /* CONFIG_PROC_FS */
-
-
-static int snd_intel8x0m_dev_free(struct snd_device *device)
-{
- struct intel8x0m *chip = device->device_data;
- return snd_intel8x0m_free(chip);
-}
-
-struct ich_reg_info {
- unsigned int int_sta_mask;
- unsigned int offset;
-};
-
-static int __devinit snd_intel8x0m_create(struct snd_card *card,
- struct pci_dev *pci,
- unsigned long device_type,
- struct intel8x0m **r_intel8x0m)
-{
- struct intel8x0m *chip;
- int err;
- unsigned int i;
- unsigned int int_sta_masks;
- struct ichdev *ichdev;
- static struct snd_device_ops ops = {
- .dev_free = snd_intel8x0m_dev_free,
- };
- static struct ich_reg_info intel_regs[2] = {
- { ICH_MIINT, 0 },
- { ICH_MOINT, 0x10 },
- };
- struct ich_reg_info *tbl;
-
- *r_intel8x0m = NULL;
-
- if ((err = pci_enable_device(pci)) < 0)
- return err;
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
- spin_lock_init(&chip->reg_lock);
- chip->device_type = device_type;
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
-
- if ((err = pci_request_regions(pci, card->shortname)) < 0) {
- kfree(chip);
- pci_disable_device(pci);
- return err;
- }
-
- if (device_type == DEVICE_ALI) {
- /* ALI5455 has no ac97 region */
- chip->bmaddr = pci_iomap(pci, 0, 0);
- goto port_inited;
- }
-
- if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) /* ICH4 and Nforce */
- chip->addr = pci_iomap(pci, 2, 0);
- else
- chip->addr = pci_iomap(pci, 0, 0);
- if (!chip->addr) {
- snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
- snd_intel8x0m_free(chip);
- return -EIO;
- }
- if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) /* ICH4 */
- chip->bmaddr = pci_iomap(pci, 3, 0);
- else
- chip->bmaddr = pci_iomap(pci, 1, 0);
- if (!chip->bmaddr) {
- snd_printk(KERN_ERR "Controller space ioremap problem\n");
- snd_intel8x0m_free(chip);
- return -EIO;
- }
-
- port_inited:
- if (request_irq(pci->irq, snd_intel8x0m_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_intel8x0m_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
- pci_set_master(pci);
- synchronize_irq(chip->irq);
-
- /* initialize offsets */
- chip->bdbars_count = 2;
- tbl = intel_regs;
-
- for (i = 0; i < chip->bdbars_count; i++) {
- ichdev = &chip->ichd[i];
- ichdev->ichd = i;
- ichdev->reg_offset = tbl[i].offset;
- ichdev->int_sta_mask = tbl[i].int_sta_mask;
- if (device_type == DEVICE_SIS) {
- /* SiS 7013 swaps the registers */
- ichdev->roff_sr = ICH_REG_OFF_PICB;
- ichdev->roff_picb = ICH_REG_OFF_SR;
- } else {
- ichdev->roff_sr = ICH_REG_OFF_SR;
- ichdev->roff_picb = ICH_REG_OFF_PICB;
- }
- if (device_type == DEVICE_ALI)
- ichdev->ali_slot = (ichdev->reg_offset - 0x40) / 0x10;
- }
- /* SIS7013 handles the pcm data in bytes, others are in words */
- chip->pcm_pos_shift = (device_type == DEVICE_SIS) ? 0 : 1;
-
- /* allocate buffer descriptor lists */
- /* the start of each lists must be aligned to 8 bytes */
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
- chip->bdbars_count * sizeof(u32) * ICH_MAX_FRAGS * 2,
- &chip->bdbars) < 0) {
- snd_intel8x0m_free(chip);
- return -ENOMEM;
- }
- /* tables must be aligned to 8 bytes here, but the kernel pages
- are much bigger, so we don't care (on i386) */
- int_sta_masks = 0;
- for (i = 0; i < chip->bdbars_count; i++) {
- ichdev = &chip->ichd[i];
- ichdev->bdbar = ((u32 *)chip->bdbars.area) + (i * ICH_MAX_FRAGS * 2);
- ichdev->bdbar_addr = chip->bdbars.addr + (i * sizeof(u32) * ICH_MAX_FRAGS * 2);
- int_sta_masks |= ichdev->int_sta_mask;
- }
- chip->int_sta_reg = ICH_REG_GLOB_STA;
- chip->int_sta_mask = int_sta_masks;
-
- if ((err = snd_intel8x0m_chip_init(chip, 1)) < 0) {
- snd_intel8x0m_free(chip);
- return err;
- }
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_intel8x0m_free(chip);
- return err;
- }
-
- snd_card_set_dev(card, &pci->dev);
-
- *r_intel8x0m = chip;
- return 0;
-}
-
-static struct shortname_table {
- unsigned int id;
- const char *s;
-} shortnames[] __devinitdata = {
- { PCI_DEVICE_ID_INTEL_82801AA_6, "Intel 82801AA-ICH" },
- { PCI_DEVICE_ID_INTEL_82801AB_6, "Intel 82901AB-ICH0" },
- { PCI_DEVICE_ID_INTEL_82801BA_6, "Intel 82801BA-ICH2" },
- { PCI_DEVICE_ID_INTEL_440MX_6, "Intel 440MX" },
- { PCI_DEVICE_ID_INTEL_82801CA_6, "Intel 82801CA-ICH3" },
- { PCI_DEVICE_ID_INTEL_82801DB_6, "Intel 82801DB-ICH4" },
- { PCI_DEVICE_ID_INTEL_82801EB_6, "Intel ICH5" },
- { PCI_DEVICE_ID_INTEL_ICH6_17, "Intel ICH6" },
- { PCI_DEVICE_ID_INTEL_ICH7_19, "Intel ICH7" },
- { 0x7446, "AMD AMD768" },
- { PCI_DEVICE_ID_SI_7013, "SiS SI7013" },
- { PCI_DEVICE_ID_NVIDIA_MCP1_MODEM, "NVidia nForce" },
- { PCI_DEVICE_ID_NVIDIA_MCP2_MODEM, "NVidia nForce2" },
- { PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM, "NVidia nForce2s" },
- { PCI_DEVICE_ID_NVIDIA_MCP3_MODEM, "NVidia nForce3" },
- { 0x746e, "AMD AMD8111" },
-#if 0
- { 0x5455, "ALi M5455" },
-#endif
- { 0 },
-};
-
-static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- struct snd_card *card;
- struct intel8x0m *chip;
- int err;
- struct shortname_table *name;
-
- err = snd_card_create(index, id, THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- strcpy(card->driver, "ICH-MODEM");
- strcpy(card->shortname, "Intel ICH");
- for (name = shortnames; name->id; name++) {
- if (pci->device == name->id) {
- strcpy(card->shortname, name->s);
- break;
- }
- }
- strcat(card->shortname," Modem");
-
- if ((err = snd_intel8x0m_create(card, pci, pci_id->driver_data, &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
- card->private_data = chip;
-
- if ((err = snd_intel8x0m_mixer(chip, ac97_clock)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_intel8x0m_pcm(chip)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- snd_intel8x0m_proc_init(chip);
-
- sprintf(card->longname, "%s at irq %i",
- card->shortname, chip->irq);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- pci_set_drvdata(pci, card);
- return 0;
-}
-
-static void __devexit snd_intel8x0m_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_intel8x0m_ids,
- .probe = snd_intel8x0m_probe,
- .remove = __devexit_p(snd_intel8x0m_remove),
-#ifdef CONFIG_PM
- .suspend = intel8x0m_suspend,
- .resume = intel8x0m_resume,
-#endif
-};
-
-
-static int __init alsa_card_intel8x0m_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_intel8x0m_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_intel8x0m_init)
-module_exit(alsa_card_intel8x0m_exit)
diff --git a/ANDROID_3.4.5/sound/pci/korg1212/Makefile b/ANDROID_3.4.5/sound/pci/korg1212/Makefile
deleted file mode 100644
index f11ce1b1..00000000
--- a/ANDROID_3.4.5/sound/pci/korg1212/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-korg1212-objs := korg1212.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_KORG1212) += snd-korg1212.o
diff --git a/ANDROID_3.4.5/sound/pci/korg1212/korg1212.c b/ANDROID_3.4.5/sound/pci/korg1212/korg1212.c
deleted file mode 100644
index 8fea45ab..00000000
--- a/ANDROID_3.4.5/sound/pci/korg1212/korg1212.c
+++ /dev/null
@@ -1,2497 +0,0 @@
-/*
- * Driver for the Korg 1212 IO PCI card
- *
- * Copyright (c) 2001 Haroldo Gamal <gamal@alternex.com.br>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/wait.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/firmware.h>
-
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-
-#include <asm/io.h>
-
-// ----------------------------------------------------------------------------
-// Debug Stuff
-// ----------------------------------------------------------------------------
-#define K1212_DEBUG_LEVEL 0
-#if K1212_DEBUG_LEVEL > 0
-#define K1212_DEBUG_PRINTK(fmt,args...) printk(KERN_DEBUG fmt,##args)
-#else
-#define K1212_DEBUG_PRINTK(fmt,...)
-#endif
-#if K1212_DEBUG_LEVEL > 1
-#define K1212_DEBUG_PRINTK_VERBOSE(fmt,args...) printk(KERN_DEBUG fmt,##args)
-#else
-#define K1212_DEBUG_PRINTK_VERBOSE(fmt,...)
-#endif
-
-// ----------------------------------------------------------------------------
-// Record/Play Buffer Allocation Method. If K1212_LARGEALLOC is defined all
-// buffers are alocated as a large piece inside KorgSharedBuffer.
-// ----------------------------------------------------------------------------
-//#define K1212_LARGEALLOC 1
-
-// ----------------------------------------------------------------------------
-// Valid states of the Korg 1212 I/O card.
-// ----------------------------------------------------------------------------
-enum CardState {
- K1212_STATE_NONEXISTENT, // there is no card here
- K1212_STATE_UNINITIALIZED, // the card is awaiting DSP download
- K1212_STATE_DSP_IN_PROCESS, // the card is currently downloading its DSP code
- K1212_STATE_DSP_COMPLETE, // the card has finished the DSP download
- K1212_STATE_READY, // the card can be opened by an application. Any application
- // requests prior to this state should fail. Only an open
- // request can be made at this state.
- K1212_STATE_OPEN, // an application has opened the card
- K1212_STATE_SETUP, // the card has been setup for play
- K1212_STATE_PLAYING, // the card is playing
- K1212_STATE_MONITOR, // the card is in the monitor mode
- K1212_STATE_CALIBRATING, // the card is currently calibrating
- K1212_STATE_ERRORSTOP, // the card has stopped itself because of an error and we
- // are in the process of cleaning things up.
- K1212_STATE_MAX_STATE // state values of this and beyond are invalid
-};
-
-// ----------------------------------------------------------------------------
-// The following enumeration defines the constants written to the card's
-// host-to-card doorbell to initiate a command.
-// ----------------------------------------------------------------------------
-enum korg1212_dbcnst {
- K1212_DB_RequestForData = 0, // sent by the card to request a buffer fill.
- K1212_DB_TriggerPlay = 1, // starts playback/record on the card.
- K1212_DB_SelectPlayMode = 2, // select monitor, playback setup, or stop.
- K1212_DB_ConfigureBufferMemory = 3, // tells card where the host audio buffers are.
- K1212_DB_RequestAdatTimecode = 4, // asks the card for the latest ADAT timecode value.
- K1212_DB_SetClockSourceRate = 5, // sets the clock source and rate for the card.
- K1212_DB_ConfigureMiscMemory = 6, // tells card where other buffers are.
- K1212_DB_TriggerFromAdat = 7, // tells card to trigger from Adat at a specific
- // timecode value.
- K1212_DB_DMAERROR = 0x80, // DMA Error - the PCI bus is congestioned.
- K1212_DB_CARDSTOPPED = 0x81, // Card has stopped by user request.
- K1212_DB_RebootCard = 0xA0, // instructs the card to reboot.
- K1212_DB_BootFromDSPPage4 = 0xA4, // instructs the card to boot from the DSP microcode
- // on page 4 (local page to card).
- K1212_DB_DSPDownloadDone = 0xAE, // sent by the card to indicate the download has
- // completed.
- K1212_DB_StartDSPDownload = 0xAF // tells the card to download its DSP firmware.
-};
-
-
-// ----------------------------------------------------------------------------
-// The following enumeration defines return codes
-// to the Korg 1212 I/O driver.
-// ----------------------------------------------------------------------------
-enum snd_korg1212rc {
- K1212_CMDRET_Success = 0, // command was successfully placed
- K1212_CMDRET_DIOCFailure, // the DeviceIoControl call failed
- K1212_CMDRET_PMFailure, // the protected mode call failed
- K1212_CMDRET_FailUnspecified, // unspecified failure
- K1212_CMDRET_FailBadState, // the specified command can not be given in
- // the card's current state. (or the wave device's
- // state)
- K1212_CMDRET_CardUninitialized, // the card is uninitialized and cannot be used
- K1212_CMDRET_BadIndex, // an out of range card index was specified
- K1212_CMDRET_BadHandle, // an invalid card handle was specified
- K1212_CMDRET_NoFillRoutine, // a play request has been made before a fill routine set
- K1212_CMDRET_FillRoutineInUse, // can't set a new fill routine while one is in use
- K1212_CMDRET_NoAckFromCard, // the card never acknowledged a command
- K1212_CMDRET_BadParams, // bad parameters were provided by the caller
-
- K1212_CMDRET_BadDevice, // the specified wave device was out of range
- K1212_CMDRET_BadFormat // the specified wave format is unsupported
-};
-
-// ----------------------------------------------------------------------------
-// The following enumeration defines the constants used to select the play
-// mode for the card in the SelectPlayMode command.
-// ----------------------------------------------------------------------------
-enum PlayModeSelector {
- K1212_MODE_SetupPlay = 0x00000001, // provides card with pre-play information
- K1212_MODE_MonitorOn = 0x00000002, // tells card to turn on monitor mode
- K1212_MODE_MonitorOff = 0x00000004, // tells card to turn off monitor mode
- K1212_MODE_StopPlay = 0x00000008 // stops playback on the card
-};
-
-// ----------------------------------------------------------------------------
-// The following enumeration defines the constants used to select the monitor
-// mode for the card in the SetMonitorMode command.
-// ----------------------------------------------------------------------------
-enum MonitorModeSelector {
- K1212_MONMODE_Off = 0, // tells card to turn off monitor mode
- K1212_MONMODE_On // tells card to turn on monitor mode
-};
-
-#define MAILBOX0_OFFSET 0x40 // location of mailbox 0 relative to base address
-#define MAILBOX1_OFFSET 0x44 // location of mailbox 1 relative to base address
-#define MAILBOX2_OFFSET 0x48 // location of mailbox 2 relative to base address
-#define MAILBOX3_OFFSET 0x4c // location of mailbox 3 relative to base address
-#define OUT_DOORBELL_OFFSET 0x60 // location of PCI to local doorbell
-#define IN_DOORBELL_OFFSET 0x64 // location of local to PCI doorbell
-#define STATUS_REG_OFFSET 0x68 // location of interrupt control/status register
-#define PCI_CONTROL_OFFSET 0x6c // location of the EEPROM, PCI, User I/O, init control
- // register
-#define SENS_CONTROL_OFFSET 0x6e // location of the input sensitivity setting register.
- // this is the upper word of the PCI control reg.
-#define DEV_VEND_ID_OFFSET 0x70 // location of the device and vendor ID register
-
-#define MAX_COMMAND_RETRIES 5 // maximum number of times the driver will attempt
- // to send a command before giving up.
-#define COMMAND_ACK_MASK 0x8000 // the MSB is set in the command acknowledgment from
- // the card.
-#define DOORBELL_VAL_MASK 0x00FF // the doorbell value is one byte
-
-#define CARD_BOOT_DELAY_IN_MS 10
-#define CARD_BOOT_TIMEOUT 10
-#define DSP_BOOT_DELAY_IN_MS 200
-
-#define kNumBuffers 8
-#define k1212MaxCards 4
-#define k1212NumWaveDevices 6
-#define k16BitChannels 10
-#define k32BitChannels 2
-#define kAudioChannels (k16BitChannels + k32BitChannels)
-#define kPlayBufferFrames 1024
-
-#define K1212_ANALOG_CHANNELS 2
-#define K1212_SPDIF_CHANNELS 2
-#define K1212_ADAT_CHANNELS 8
-#define K1212_CHANNELS (K1212_ADAT_CHANNELS + K1212_ANALOG_CHANNELS)
-#define K1212_MIN_CHANNELS 1
-#define K1212_MAX_CHANNELS K1212_CHANNELS
-#define K1212_FRAME_SIZE (sizeof(struct KorgAudioFrame))
-#define K1212_MAX_SAMPLES (kPlayBufferFrames*kNumBuffers)
-#define K1212_PERIODS (kNumBuffers)
-#define K1212_PERIOD_BYTES (K1212_FRAME_SIZE*kPlayBufferFrames)
-#define K1212_BUF_SIZE (K1212_PERIOD_BYTES*kNumBuffers)
-#define K1212_ANALOG_BUF_SIZE (K1212_ANALOG_CHANNELS * 2 * kPlayBufferFrames * kNumBuffers)
-#define K1212_SPDIF_BUF_SIZE (K1212_SPDIF_CHANNELS * 3 * kPlayBufferFrames * kNumBuffers)
-#define K1212_ADAT_BUF_SIZE (K1212_ADAT_CHANNELS * 2 * kPlayBufferFrames * kNumBuffers)
-#define K1212_MAX_BUF_SIZE (K1212_ANALOG_BUF_SIZE + K1212_ADAT_BUF_SIZE)
-
-#define k1212MinADCSens 0x7f
-#define k1212MaxADCSens 0x00
-#define k1212MaxVolume 0x7fff
-#define k1212MaxWaveVolume 0xffff
-#define k1212MinVolume 0x0000
-#define k1212MaxVolInverted 0x8000
-
-// -----------------------------------------------------------------
-// the following bits are used for controlling interrupts in the
-// interrupt control/status reg
-// -----------------------------------------------------------------
-#define PCI_INT_ENABLE_BIT 0x00000100
-#define PCI_DOORBELL_INT_ENABLE_BIT 0x00000200
-#define LOCAL_INT_ENABLE_BIT 0x00010000
-#define LOCAL_DOORBELL_INT_ENABLE_BIT 0x00020000
-#define LOCAL_DMA1_INT_ENABLE_BIT 0x00080000
-
-// -----------------------------------------------------------------
-// the following bits are defined for the PCI command register
-// -----------------------------------------------------------------
-#define PCI_CMD_MEM_SPACE_ENABLE_BIT 0x0002
-#define PCI_CMD_IO_SPACE_ENABLE_BIT 0x0001
-#define PCI_CMD_BUS_MASTER_ENABLE_BIT 0x0004
-
-// -----------------------------------------------------------------
-// the following bits are defined for the PCI status register
-// -----------------------------------------------------------------
-#define PCI_STAT_PARITY_ERROR_BIT 0x8000
-#define PCI_STAT_SYSTEM_ERROR_BIT 0x4000
-#define PCI_STAT_MASTER_ABORT_RCVD_BIT 0x2000
-#define PCI_STAT_TARGET_ABORT_RCVD_BIT 0x1000
-#define PCI_STAT_TARGET_ABORT_SENT_BIT 0x0800
-
-// ------------------------------------------------------------------------
-// the following constants are used in setting the 1212 I/O card's input
-// sensitivity.
-// ------------------------------------------------------------------------
-#define SET_SENS_LOCALINIT_BITPOS 15
-#define SET_SENS_DATA_BITPOS 10
-#define SET_SENS_CLOCK_BITPOS 8
-#define SET_SENS_LOADSHIFT_BITPOS 0
-
-#define SET_SENS_LEFTCHANID 0x00
-#define SET_SENS_RIGHTCHANID 0x01
-
-#define K1212SENSUPDATE_DELAY_IN_MS 50
-
-// --------------------------------------------------------------------------
-// WaitRTCTicks
-//
-// This function waits the specified number of real time clock ticks.
-// According to the DDK, each tick is ~0.8 microseconds.
-// The defines following the function declaration can be used for the
-// numTicksToWait parameter.
-// --------------------------------------------------------------------------
-#define ONE_RTC_TICK 1
-#define SENSCLKPULSE_WIDTH 4
-#define LOADSHIFT_DELAY 4
-#define INTERCOMMAND_DELAY 40
-#define STOPCARD_DELAY 300 // max # RTC ticks for the card to stop once we write
- // the command register. (could be up to 180 us)
-#define COMMAND_ACK_DELAY 13 // number of RTC ticks to wait for an acknowledgement
- // from the card after sending a command.
-
-enum ClockSourceIndex {
- K1212_CLKIDX_AdatAt44_1K = 0, // selects source as ADAT at 44.1 kHz
- K1212_CLKIDX_AdatAt48K, // selects source as ADAT at 48 kHz
- K1212_CLKIDX_WordAt44_1K, // selects source as S/PDIF at 44.1 kHz
- K1212_CLKIDX_WordAt48K, // selects source as S/PDIF at 48 kHz
- K1212_CLKIDX_LocalAt44_1K, // selects source as local clock at 44.1 kHz
- K1212_CLKIDX_LocalAt48K, // selects source as local clock at 48 kHz
- K1212_CLKIDX_Invalid // used to check validity of the index
-};
-
-enum ClockSourceType {
- K1212_CLKIDX_Adat = 0, // selects source as ADAT
- K1212_CLKIDX_Word, // selects source as S/PDIF
- K1212_CLKIDX_Local // selects source as local clock
-};
-
-struct KorgAudioFrame {
- u16 frameData16[k16BitChannels]; /* channels 0-9 use 16 bit samples */
- u32 frameData32[k32BitChannels]; /* channels 10-11 use 32 bits - only 20 are sent across S/PDIF */
- u32 timeCodeVal; /* holds the ADAT timecode value */
-};
-
-struct KorgAudioBuffer {
- struct KorgAudioFrame bufferData[kPlayBufferFrames]; /* buffer definition */
-};
-
-struct KorgSharedBuffer {
-#ifdef K1212_LARGEALLOC
- struct KorgAudioBuffer playDataBufs[kNumBuffers];
- struct KorgAudioBuffer recordDataBufs[kNumBuffers];
-#endif
- short volumeData[kAudioChannels];
- u32 cardCommand;
- u16 routeData [kAudioChannels];
- u32 AdatTimeCode; // ADAT timecode value
-};
-
-struct SensBits {
- union {
- struct {
- unsigned int leftChanVal:8;
- unsigned int leftChanId:8;
- } v;
- u16 leftSensBits;
- } l;
- union {
- struct {
- unsigned int rightChanVal:8;
- unsigned int rightChanId:8;
- } v;
- u16 rightSensBits;
- } r;
-};
-
-struct snd_korg1212 {
- struct snd_card *card;
- struct pci_dev *pci;
- struct snd_pcm *pcm;
- int irq;
-
- spinlock_t lock;
- struct mutex open_mutex;
-
- struct timer_list timer; /* timer callback for checking ack of stop request */
- int stop_pending_cnt; /* counter for stop pending check */
-
- wait_queue_head_t wait;
-
- unsigned long iomem;
- unsigned long ioport;
- unsigned long iomem2;
- unsigned long irqcount;
- unsigned long inIRQ;
- void __iomem *iobase;
-
- struct snd_dma_buffer dma_dsp;
- struct snd_dma_buffer dma_play;
- struct snd_dma_buffer dma_rec;
- struct snd_dma_buffer dma_shared;
-
- u32 DataBufsSize;
-
- struct KorgAudioBuffer * playDataBufsPtr;
- struct KorgAudioBuffer * recordDataBufsPtr;
-
- struct KorgSharedBuffer * sharedBufferPtr;
-
- u32 RecDataPhy;
- u32 PlayDataPhy;
- unsigned long sharedBufferPhy;
- u32 VolumeTablePhy;
- u32 RoutingTablePhy;
- u32 AdatTimeCodePhy;
-
- u32 __iomem * statusRegPtr; // address of the interrupt status/control register
- u32 __iomem * outDoorbellPtr; // address of the host->card doorbell register
- u32 __iomem * inDoorbellPtr; // address of the card->host doorbell register
- u32 __iomem * mailbox0Ptr; // address of mailbox 0 on the card
- u32 __iomem * mailbox1Ptr; // address of mailbox 1 on the card
- u32 __iomem * mailbox2Ptr; // address of mailbox 2 on the card
- u32 __iomem * mailbox3Ptr; // address of mailbox 3 on the card
- u32 __iomem * controlRegPtr; // address of the EEPROM, PCI, I/O, Init ctrl reg
- u16 __iomem * sensRegPtr; // address of the sensitivity setting register
- u32 __iomem * idRegPtr; // address of the device and vendor ID registers
-
- size_t periodsize;
- int channels;
- int currentBuffer;
-
- struct snd_pcm_substream *playback_substream;
- struct snd_pcm_substream *capture_substream;
-
- pid_t capture_pid;
- pid_t playback_pid;
-
- enum CardState cardState;
- int running;
- int idleMonitorOn; // indicates whether the card is in idle monitor mode.
- u32 cmdRetryCount; // tracks how many times we have retried sending to the card.
-
- enum ClockSourceIndex clkSrcRate; // sample rate and clock source
-
- enum ClockSourceType clkSource; // clock source
- int clkRate; // clock rate
-
- int volumePhase[kAudioChannels];
-
- u16 leftADCInSens; // ADC left channel input sensitivity
- u16 rightADCInSens; // ADC right channel input sensitivity
-
- int opencnt; // Open/Close count
- int setcnt; // SetupForPlay count
- int playcnt; // TriggerPlay count
- int errorcnt; // Error Count
- unsigned long totalerrorcnt; // Total Error Count
-
- int dsp_is_loaded;
- int dsp_stop_is_processed;
-
-};
-
-MODULE_DESCRIPTION("korg1212");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{KORG,korg1212}}");
-MODULE_FIRMWARE("korg/k1212.dsp");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Korg 1212 soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Korg 1212 soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Korg 1212 soundcard.");
-MODULE_AUTHOR("Haroldo Gamal <gamal@alternex.com.br>");
-
-static DEFINE_PCI_DEVICE_TABLE(snd_korg1212_ids) = {
- {
- .vendor = 0x10b5,
- .device = 0x906d,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- },
- { 0, },
-};
-
-MODULE_DEVICE_TABLE(pci, snd_korg1212_ids);
-
-static char *stateName[] = {
- "Non-existent",
- "Uninitialized",
- "DSP download in process",
- "DSP download complete",
- "Ready",
- "Open",
- "Setup for play",
- "Playing",
- "Monitor mode on",
- "Calibrating",
- "Invalid"
-};
-
-static char *clockSourceTypeName[] = { "ADAT", "S/PDIF", "local" };
-
-static char *clockSourceName[] = {
- "ADAT at 44.1 kHz",
- "ADAT at 48 kHz",
- "S/PDIF at 44.1 kHz",
- "S/PDIF at 48 kHz",
- "local clock at 44.1 kHz",
- "local clock at 48 kHz"
-};
-
-static char *channelName[] = {
- "ADAT-1",
- "ADAT-2",
- "ADAT-3",
- "ADAT-4",
- "ADAT-5",
- "ADAT-6",
- "ADAT-7",
- "ADAT-8",
- "Analog-L",
- "Analog-R",
- "SPDIF-L",
- "SPDIF-R",
-};
-
-static u16 ClockSourceSelector[] = {
- 0x8000, // selects source as ADAT at 44.1 kHz
- 0x0000, // selects source as ADAT at 48 kHz
- 0x8001, // selects source as S/PDIF at 44.1 kHz
- 0x0001, // selects source as S/PDIF at 48 kHz
- 0x8002, // selects source as local clock at 44.1 kHz
- 0x0002 // selects source as local clock at 48 kHz
-};
-
-union swap_u32 { unsigned char c[4]; u32 i; };
-
-#ifdef SNDRV_BIG_ENDIAN
-static u32 LowerWordSwap(u32 swappee)
-#else
-static u32 UpperWordSwap(u32 swappee)
-#endif
-{
- union swap_u32 retVal, swapper;
-
- swapper.i = swappee;
- retVal.c[2] = swapper.c[3];
- retVal.c[3] = swapper.c[2];
- retVal.c[1] = swapper.c[1];
- retVal.c[0] = swapper.c[0];
-
- return retVal.i;
-}
-
-#ifdef SNDRV_BIG_ENDIAN
-static u32 UpperWordSwap(u32 swappee)
-#else
-static u32 LowerWordSwap(u32 swappee)
-#endif
-{
- union swap_u32 retVal, swapper;
-
- swapper.i = swappee;
- retVal.c[2] = swapper.c[2];
- retVal.c[3] = swapper.c[3];
- retVal.c[1] = swapper.c[0];
- retVal.c[0] = swapper.c[1];
-
- return retVal.i;
-}
-
-#define SetBitInWord(theWord,bitPosition) (*theWord) |= (0x0001 << bitPosition)
-#define SetBitInDWord(theWord,bitPosition) (*theWord) |= (0x00000001 << bitPosition)
-#define ClearBitInWord(theWord,bitPosition) (*theWord) &= ~(0x0001 << bitPosition)
-#define ClearBitInDWord(theWord,bitPosition) (*theWord) &= ~(0x00000001 << bitPosition)
-
-static int snd_korg1212_Send1212Command(struct snd_korg1212 *korg1212,
- enum korg1212_dbcnst doorbellVal,
- u32 mailBox0Val, u32 mailBox1Val,
- u32 mailBox2Val, u32 mailBox3Val)
-{
- u32 retryCount;
- u16 mailBox3Lo;
- int rc = K1212_CMDRET_Success;
-
- if (!korg1212->outDoorbellPtr) {
- K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: CardUninitialized\n");
- return K1212_CMDRET_CardUninitialized;
- }
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: Card <- 0x%08x 0x%08x [%s]\n",
- doorbellVal, mailBox0Val, stateName[korg1212->cardState]);
- for (retryCount = 0; retryCount < MAX_COMMAND_RETRIES; retryCount++) {
- writel(mailBox3Val, korg1212->mailbox3Ptr);
- writel(mailBox2Val, korg1212->mailbox2Ptr);
- writel(mailBox1Val, korg1212->mailbox1Ptr);
- writel(mailBox0Val, korg1212->mailbox0Ptr);
- writel(doorbellVal, korg1212->outDoorbellPtr); // interrupt the card
-
- // --------------------------------------------------------------
- // the reboot command will not give an acknowledgement.
- // --------------------------------------------------------------
- if ( doorbellVal == K1212_DB_RebootCard ||
- doorbellVal == K1212_DB_BootFromDSPPage4 ||
- doorbellVal == K1212_DB_StartDSPDownload ) {
- rc = K1212_CMDRET_Success;
- break;
- }
-
- // --------------------------------------------------------------
- // See if the card acknowledged the command. Wait a bit, then
- // read in the low word of mailbox3. If the MSB is set and the
- // low byte is equal to the doorbell value, then it ack'd.
- // --------------------------------------------------------------
- udelay(COMMAND_ACK_DELAY);
- mailBox3Lo = readl(korg1212->mailbox3Ptr);
- if (mailBox3Lo & COMMAND_ACK_MASK) {
- if ((mailBox3Lo & DOORBELL_VAL_MASK) == (doorbellVal & DOORBELL_VAL_MASK)) {
- K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: Card <- Success\n");
- rc = K1212_CMDRET_Success;
- break;
- }
- }
- }
- korg1212->cmdRetryCount += retryCount;
-
- if (retryCount >= MAX_COMMAND_RETRIES) {
- K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: Card <- NoAckFromCard\n");
- rc = K1212_CMDRET_NoAckFromCard;
- }
-
- return rc;
-}
-
-/* spinlock already held */
-static void snd_korg1212_SendStop(struct snd_korg1212 *korg1212)
-{
- if (! korg1212->stop_pending_cnt) {
- korg1212->sharedBufferPtr->cardCommand = 0xffffffff;
- /* program the timer */
- korg1212->stop_pending_cnt = HZ;
- korg1212->timer.expires = jiffies + 1;
- add_timer(&korg1212->timer);
- }
-}
-
-static void snd_korg1212_SendStopAndWait(struct snd_korg1212 *korg1212)
-{
- unsigned long flags;
- spin_lock_irqsave(&korg1212->lock, flags);
- korg1212->dsp_stop_is_processed = 0;
- snd_korg1212_SendStop(korg1212);
- spin_unlock_irqrestore(&korg1212->lock, flags);
- wait_event_timeout(korg1212->wait, korg1212->dsp_stop_is_processed, (HZ * 3) / 2);
-}
-
-/* timer callback for checking the ack of stop request */
-static void snd_korg1212_timer_func(unsigned long data)
-{
- struct snd_korg1212 *korg1212 = (struct snd_korg1212 *) data;
- unsigned long flags;
-
- spin_lock_irqsave(&korg1212->lock, flags);
- if (korg1212->sharedBufferPtr->cardCommand == 0) {
- /* ack'ed */
- korg1212->stop_pending_cnt = 0;
- korg1212->dsp_stop_is_processed = 1;
- wake_up(&korg1212->wait);
- K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: Stop ack'ed [%s]\n",
- stateName[korg1212->cardState]);
- } else {
- if (--korg1212->stop_pending_cnt > 0) {
- /* reprogram timer */
- korg1212->timer.expires = jiffies + 1;
- add_timer(&korg1212->timer);
- } else {
- snd_printd("korg1212_timer_func timeout\n");
- korg1212->sharedBufferPtr->cardCommand = 0;
- korg1212->dsp_stop_is_processed = 1;
- wake_up(&korg1212->wait);
- K1212_DEBUG_PRINTK("K1212_DEBUG: Stop timeout [%s]\n",
- stateName[korg1212->cardState]);
- }
- }
- spin_unlock_irqrestore(&korg1212->lock, flags);
-}
-
-static int snd_korg1212_TurnOnIdleMonitor(struct snd_korg1212 *korg1212)
-{
- unsigned long flags;
- int rc;
-
- udelay(INTERCOMMAND_DELAY);
- spin_lock_irqsave(&korg1212->lock, flags);
- korg1212->idleMonitorOn = 1;
- rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
- K1212_MODE_MonitorOn, 0, 0, 0);
- spin_unlock_irqrestore(&korg1212->lock, flags);
- return rc;
-}
-
-static void snd_korg1212_TurnOffIdleMonitor(struct snd_korg1212 *korg1212)
-{
- if (korg1212->idleMonitorOn) {
- snd_korg1212_SendStopAndWait(korg1212);
- korg1212->idleMonitorOn = 0;
- }
-}
-
-static inline void snd_korg1212_setCardState(struct snd_korg1212 * korg1212, enum CardState csState)
-{
- korg1212->cardState = csState;
-}
-
-static int snd_korg1212_OpenCard(struct snd_korg1212 * korg1212)
-{
- K1212_DEBUG_PRINTK("K1212_DEBUG: OpenCard [%s] %d\n",
- stateName[korg1212->cardState], korg1212->opencnt);
- mutex_lock(&korg1212->open_mutex);
- if (korg1212->opencnt++ == 0) {
- snd_korg1212_TurnOffIdleMonitor(korg1212);
- snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN);
- }
-
- mutex_unlock(&korg1212->open_mutex);
- return 1;
-}
-
-static int snd_korg1212_CloseCard(struct snd_korg1212 * korg1212)
-{
- K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard [%s] %d\n",
- stateName[korg1212->cardState], korg1212->opencnt);
-
- mutex_lock(&korg1212->open_mutex);
- if (--(korg1212->opencnt)) {
- mutex_unlock(&korg1212->open_mutex);
- return 0;
- }
-
- if (korg1212->cardState == K1212_STATE_SETUP) {
- int rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
- K1212_MODE_StopPlay, 0, 0, 0);
- if (rc)
- K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard - RC = %d [%s]\n",
- rc, stateName[korg1212->cardState]);
- if (rc != K1212_CMDRET_Success) {
- mutex_unlock(&korg1212->open_mutex);
- return 0;
- }
- } else if (korg1212->cardState > K1212_STATE_SETUP) {
- snd_korg1212_SendStopAndWait(korg1212);
- }
-
- if (korg1212->cardState > K1212_STATE_READY) {
- snd_korg1212_TurnOnIdleMonitor(korg1212);
- snd_korg1212_setCardState(korg1212, K1212_STATE_READY);
- }
-
- mutex_unlock(&korg1212->open_mutex);
- return 0;
-}
-
-/* spinlock already held */
-static int snd_korg1212_SetupForPlay(struct snd_korg1212 * korg1212)
-{
- int rc;
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: SetupForPlay [%s] %d\n",
- stateName[korg1212->cardState], korg1212->setcnt);
-
- if (korg1212->setcnt++)
- return 0;
-
- snd_korg1212_setCardState(korg1212, K1212_STATE_SETUP);
- rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
- K1212_MODE_SetupPlay, 0, 0, 0);
- if (rc)
- K1212_DEBUG_PRINTK("K1212_DEBUG: SetupForPlay - RC = %d [%s]\n",
- rc, stateName[korg1212->cardState]);
- if (rc != K1212_CMDRET_Success) {
- return 1;
- }
- return 0;
-}
-
-/* spinlock already held */
-static int snd_korg1212_TriggerPlay(struct snd_korg1212 * korg1212)
-{
- int rc;
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: TriggerPlay [%s] %d\n",
- stateName[korg1212->cardState], korg1212->playcnt);
-
- if (korg1212->playcnt++)
- return 0;
-
- snd_korg1212_setCardState(korg1212, K1212_STATE_PLAYING);
- rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_TriggerPlay, 0, 0, 0, 0);
- if (rc)
- K1212_DEBUG_PRINTK("K1212_DEBUG: TriggerPlay - RC = %d [%s]\n",
- rc, stateName[korg1212->cardState]);
- if (rc != K1212_CMDRET_Success) {
- return 1;
- }
- return 0;
-}
-
-/* spinlock already held */
-static int snd_korg1212_StopPlay(struct snd_korg1212 * korg1212)
-{
- K1212_DEBUG_PRINTK("K1212_DEBUG: StopPlay [%s] %d\n",
- stateName[korg1212->cardState], korg1212->playcnt);
-
- if (--(korg1212->playcnt))
- return 0;
-
- korg1212->setcnt = 0;
-
- if (korg1212->cardState != K1212_STATE_ERRORSTOP)
- snd_korg1212_SendStop(korg1212);
-
- snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN);
- return 0;
-}
-
-static void snd_korg1212_EnableCardInterrupts(struct snd_korg1212 * korg1212)
-{
- writel(PCI_INT_ENABLE_BIT |
- PCI_DOORBELL_INT_ENABLE_BIT |
- LOCAL_INT_ENABLE_BIT |
- LOCAL_DOORBELL_INT_ENABLE_BIT |
- LOCAL_DMA1_INT_ENABLE_BIT,
- korg1212->statusRegPtr);
-}
-
-#if 0 /* not used */
-
-static int snd_korg1212_SetMonitorMode(struct snd_korg1212 *korg1212,
- enum MonitorModeSelector mode)
-{
- K1212_DEBUG_PRINTK("K1212_DEBUG: SetMonitorMode [%s]\n",
- stateName[korg1212->cardState]);
-
- switch (mode) {
- case K1212_MONMODE_Off:
- if (korg1212->cardState != K1212_STATE_MONITOR)
- return 0;
- else {
- snd_korg1212_SendStopAndWait(korg1212);
- snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN);
- }
- break;
-
- case K1212_MONMODE_On:
- if (korg1212->cardState != K1212_STATE_OPEN)
- return 0;
- else {
- int rc;
- snd_korg1212_setCardState(korg1212, K1212_STATE_MONITOR);
- rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
- K1212_MODE_MonitorOn, 0, 0, 0);
- if (rc != K1212_CMDRET_Success)
- return 0;
- }
- break;
-
- default:
- return 0;
- }
-
- return 1;
-}
-
-#endif /* not used */
-
-static inline int snd_korg1212_use_is_exclusive(struct snd_korg1212 *korg1212)
-{
- if (korg1212->playback_pid != korg1212->capture_pid &&
- korg1212->playback_pid >= 0 && korg1212->capture_pid >= 0)
- return 0;
-
- return 1;
-}
-
-static int snd_korg1212_SetRate(struct snd_korg1212 *korg1212, int rate)
-{
- static enum ClockSourceIndex s44[] = {
- K1212_CLKIDX_AdatAt44_1K,
- K1212_CLKIDX_WordAt44_1K,
- K1212_CLKIDX_LocalAt44_1K
- };
- static enum ClockSourceIndex s48[] = {
- K1212_CLKIDX_AdatAt48K,
- K1212_CLKIDX_WordAt48K,
- K1212_CLKIDX_LocalAt48K
- };
- int parm, rc;
-
- if (!snd_korg1212_use_is_exclusive (korg1212))
- return -EBUSY;
-
- switch (rate) {
- case 44100:
- parm = s44[korg1212->clkSource];
- break;
-
- case 48000:
- parm = s48[korg1212->clkSource];
- break;
-
- default:
- return -EINVAL;
- }
-
- korg1212->clkSrcRate = parm;
- korg1212->clkRate = rate;
-
- udelay(INTERCOMMAND_DELAY);
- rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SetClockSourceRate,
- ClockSourceSelector[korg1212->clkSrcRate],
- 0, 0, 0);
- if (rc)
- K1212_DEBUG_PRINTK("K1212_DEBUG: Set Clock Source Selector - RC = %d [%s]\n",
- rc, stateName[korg1212->cardState]);
-
- return 0;
-}
-
-static int snd_korg1212_SetClockSource(struct snd_korg1212 *korg1212, int source)
-{
-
- if (source < 0 || source > 2)
- return -EINVAL;
-
- korg1212->clkSource = source;
-
- snd_korg1212_SetRate(korg1212, korg1212->clkRate);
-
- return 0;
-}
-
-static void snd_korg1212_DisableCardInterrupts(struct snd_korg1212 *korg1212)
-{
- writel(0, korg1212->statusRegPtr);
-}
-
-static int snd_korg1212_WriteADCSensitivity(struct snd_korg1212 *korg1212)
-{
- struct SensBits sensVals;
- int bitPosition;
- int channel;
- int clkIs48K;
- int monModeSet;
- u16 controlValue; // this keeps the current value to be written to
- // the card's eeprom control register.
- u16 count;
- unsigned long flags;
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: WriteADCSensivity [%s]\n",
- stateName[korg1212->cardState]);
-
- // ----------------------------------------------------------------------------
- // initialize things. The local init bit is always set when writing to the
- // card's control register.
- // ----------------------------------------------------------------------------
- controlValue = 0;
- SetBitInWord(&controlValue, SET_SENS_LOCALINIT_BITPOS); // init the control value
-
- // ----------------------------------------------------------------------------
- // make sure the card is not in monitor mode when we do this update.
- // ----------------------------------------------------------------------------
- if (korg1212->cardState == K1212_STATE_MONITOR || korg1212->idleMonitorOn) {
- monModeSet = 1;
- snd_korg1212_SendStopAndWait(korg1212);
- } else
- monModeSet = 0;
-
- spin_lock_irqsave(&korg1212->lock, flags);
-
- // ----------------------------------------------------------------------------
- // we are about to send new values to the card, so clear the new values queued
- // flag. Also, clear out mailbox 3, so we don't lockup.
- // ----------------------------------------------------------------------------
- writel(0, korg1212->mailbox3Ptr);
- udelay(LOADSHIFT_DELAY);
-
- // ----------------------------------------------------------------------------
- // determine whether we are running a 48K or 44.1K clock. This info is used
- // later when setting the SPDIF FF after the volume has been shifted in.
- // ----------------------------------------------------------------------------
- switch (korg1212->clkSrcRate) {
- case K1212_CLKIDX_AdatAt44_1K:
- case K1212_CLKIDX_WordAt44_1K:
- case K1212_CLKIDX_LocalAt44_1K:
- clkIs48K = 0;
- break;
-
- case K1212_CLKIDX_WordAt48K:
- case K1212_CLKIDX_AdatAt48K:
- case K1212_CLKIDX_LocalAt48K:
- default:
- clkIs48K = 1;
- break;
- }
-
- // ----------------------------------------------------------------------------
- // start the update. Setup the bit structure and then shift the bits.
- // ----------------------------------------------------------------------------
- sensVals.l.v.leftChanId = SET_SENS_LEFTCHANID;
- sensVals.r.v.rightChanId = SET_SENS_RIGHTCHANID;
- sensVals.l.v.leftChanVal = korg1212->leftADCInSens;
- sensVals.r.v.rightChanVal = korg1212->rightADCInSens;
-
- // ----------------------------------------------------------------------------
- // now start shifting the bits in. Start with the left channel then the right.
- // ----------------------------------------------------------------------------
- for (channel = 0; channel < 2; channel++) {
-
- // ----------------------------------------------------------------------------
- // Bring the load/shift line low, then wait - the spec says >150ns from load/
- // shift low to the first rising edge of the clock.
- // ----------------------------------------------------------------------------
- ClearBitInWord(&controlValue, SET_SENS_LOADSHIFT_BITPOS);
- ClearBitInWord(&controlValue, SET_SENS_DATA_BITPOS);
- writew(controlValue, korg1212->sensRegPtr); // load/shift goes low
- udelay(LOADSHIFT_DELAY);
-
- for (bitPosition = 15; bitPosition >= 0; bitPosition--) { // for all the bits
- if (channel == 0) {
- if (sensVals.l.leftSensBits & (0x0001 << bitPosition))
- SetBitInWord(&controlValue, SET_SENS_DATA_BITPOS); // data bit set high
- else
- ClearBitInWord(&controlValue, SET_SENS_DATA_BITPOS); // data bit set low
- } else {
- if (sensVals.r.rightSensBits & (0x0001 << bitPosition))
- SetBitInWord(&controlValue, SET_SENS_DATA_BITPOS); // data bit set high
- else
- ClearBitInWord(&controlValue, SET_SENS_DATA_BITPOS); // data bit set low
- }
-
- ClearBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
- writew(controlValue, korg1212->sensRegPtr); // clock goes low
- udelay(SENSCLKPULSE_WIDTH);
- SetBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
- writew(controlValue, korg1212->sensRegPtr); // clock goes high
- udelay(SENSCLKPULSE_WIDTH);
- }
-
- // ----------------------------------------------------------------------------
- // finish up SPDIF for left. Bring the load/shift line high, then write a one
- // bit if the clock rate is 48K otherwise write 0.
- // ----------------------------------------------------------------------------
- ClearBitInWord(&controlValue, SET_SENS_DATA_BITPOS);
- ClearBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
- SetBitInWord(&controlValue, SET_SENS_LOADSHIFT_BITPOS);
- writew(controlValue, korg1212->sensRegPtr); // load shift goes high - clk low
- udelay(SENSCLKPULSE_WIDTH);
-
- if (clkIs48K)
- SetBitInWord(&controlValue, SET_SENS_DATA_BITPOS);
-
- writew(controlValue, korg1212->sensRegPtr); // set/clear data bit
- udelay(ONE_RTC_TICK);
- SetBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
- writew(controlValue, korg1212->sensRegPtr); // clock goes high
- udelay(SENSCLKPULSE_WIDTH);
- ClearBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
- writew(controlValue, korg1212->sensRegPtr); // clock goes low
- udelay(SENSCLKPULSE_WIDTH);
- }
-
- // ----------------------------------------------------------------------------
- // The update is complete. Set a timeout. This is the inter-update delay.
- // Also, if the card was in monitor mode, restore it.
- // ----------------------------------------------------------------------------
- for (count = 0; count < 10; count++)
- udelay(SENSCLKPULSE_WIDTH);
-
- if (monModeSet) {
- int rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
- K1212_MODE_MonitorOn, 0, 0, 0);
- if (rc)
- K1212_DEBUG_PRINTK("K1212_DEBUG: WriteADCSensivity - RC = %d [%s]\n",
- rc, stateName[korg1212->cardState]);
- }
-
- spin_unlock_irqrestore(&korg1212->lock, flags);
-
- return 1;
-}
-
-static void snd_korg1212_OnDSPDownloadComplete(struct snd_korg1212 *korg1212)
-{
- int channel, rc;
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: DSP download is complete. [%s]\n",
- stateName[korg1212->cardState]);
-
- // ----------------------------------------------------
- // tell the card to boot
- // ----------------------------------------------------
- rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_BootFromDSPPage4, 0, 0, 0, 0);
-
- if (rc)
- K1212_DEBUG_PRINTK("K1212_DEBUG: Boot from Page 4 - RC = %d [%s]\n",
- rc, stateName[korg1212->cardState]);
- msleep(DSP_BOOT_DELAY_IN_MS);
-
- // --------------------------------------------------------------------------------
- // Let the card know where all the buffers are.
- // --------------------------------------------------------------------------------
- rc = snd_korg1212_Send1212Command(korg1212,
- K1212_DB_ConfigureBufferMemory,
- LowerWordSwap(korg1212->PlayDataPhy),
- LowerWordSwap(korg1212->RecDataPhy),
- ((kNumBuffers * kPlayBufferFrames) / 2), // size given to the card
- // is based on 2 buffers
- 0
- );
-
- if (rc)
- K1212_DEBUG_PRINTK("K1212_DEBUG: Configure Buffer Memory - RC = %d [%s]\n",
- rc, stateName[korg1212->cardState]);
-
- udelay(INTERCOMMAND_DELAY);
-
- rc = snd_korg1212_Send1212Command(korg1212,
- K1212_DB_ConfigureMiscMemory,
- LowerWordSwap(korg1212->VolumeTablePhy),
- LowerWordSwap(korg1212->RoutingTablePhy),
- LowerWordSwap(korg1212->AdatTimeCodePhy),
- 0
- );
-
- if (rc)
- K1212_DEBUG_PRINTK("K1212_DEBUG: Configure Misc Memory - RC = %d [%s]\n",
- rc, stateName[korg1212->cardState]);
-
- // --------------------------------------------------------------------------------
- // Initialize the routing and volume tables, then update the card's state.
- // --------------------------------------------------------------------------------
- udelay(INTERCOMMAND_DELAY);
-
- for (channel = 0; channel < kAudioChannels; channel++) {
- korg1212->sharedBufferPtr->volumeData[channel] = k1212MaxVolume;
- //korg1212->sharedBufferPtr->routeData[channel] = channel;
- korg1212->sharedBufferPtr->routeData[channel] = 8 + (channel & 1);
- }
-
- snd_korg1212_WriteADCSensitivity(korg1212);
-
- udelay(INTERCOMMAND_DELAY);
- rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SetClockSourceRate,
- ClockSourceSelector[korg1212->clkSrcRate],
- 0, 0, 0);
- if (rc)
- K1212_DEBUG_PRINTK("K1212_DEBUG: Set Clock Source Selector - RC = %d [%s]\n",
- rc, stateName[korg1212->cardState]);
-
- rc = snd_korg1212_TurnOnIdleMonitor(korg1212);
- snd_korg1212_setCardState(korg1212, K1212_STATE_READY);
-
- if (rc)
- K1212_DEBUG_PRINTK("K1212_DEBUG: Set Monitor On - RC = %d [%s]\n",
- rc, stateName[korg1212->cardState]);
-
- snd_korg1212_setCardState(korg1212, K1212_STATE_DSP_COMPLETE);
-}
-
-static irqreturn_t snd_korg1212_interrupt(int irq, void *dev_id)
-{
- u32 doorbellValue;
- struct snd_korg1212 *korg1212 = dev_id;
-
- doorbellValue = readl(korg1212->inDoorbellPtr);
-
- if (!doorbellValue)
- return IRQ_NONE;
-
- spin_lock(&korg1212->lock);
-
- writel(doorbellValue, korg1212->inDoorbellPtr);
-
- korg1212->irqcount++;
-
- korg1212->inIRQ++;
-
- switch (doorbellValue) {
- case K1212_DB_DSPDownloadDone:
- K1212_DEBUG_PRINTK("K1212_DEBUG: IRQ DNLD count - %ld, %x, [%s].\n",
- korg1212->irqcount, doorbellValue,
- stateName[korg1212->cardState]);
- if (korg1212->cardState == K1212_STATE_DSP_IN_PROCESS) {
- korg1212->dsp_is_loaded = 1;
- wake_up(&korg1212->wait);
- }
- break;
-
- // ------------------------------------------------------------------------
- // an error occurred - stop the card
- // ------------------------------------------------------------------------
- case K1212_DB_DMAERROR:
- K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: IRQ DMAE count - %ld, %x, [%s].\n",
- korg1212->irqcount, doorbellValue,
- stateName[korg1212->cardState]);
- snd_printk(KERN_ERR "korg1212: DMA Error\n");
- korg1212->errorcnt++;
- korg1212->totalerrorcnt++;
- korg1212->sharedBufferPtr->cardCommand = 0;
- snd_korg1212_setCardState(korg1212, K1212_STATE_ERRORSTOP);
- break;
-
- // ------------------------------------------------------------------------
- // the card has stopped by our request. Clear the command word and signal
- // the semaphore in case someone is waiting for this.
- // ------------------------------------------------------------------------
- case K1212_DB_CARDSTOPPED:
- K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: IRQ CSTP count - %ld, %x, [%s].\n",
- korg1212->irqcount, doorbellValue,
- stateName[korg1212->cardState]);
- korg1212->sharedBufferPtr->cardCommand = 0;
- break;
-
- default:
- K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: IRQ DFLT count - %ld, %x, cpos=%d [%s].\n",
- korg1212->irqcount, doorbellValue,
- korg1212->currentBuffer, stateName[korg1212->cardState]);
- if ((korg1212->cardState > K1212_STATE_SETUP) || korg1212->idleMonitorOn) {
- korg1212->currentBuffer++;
-
- if (korg1212->currentBuffer >= kNumBuffers)
- korg1212->currentBuffer = 0;
-
- if (!korg1212->running)
- break;
-
- if (korg1212->capture_substream) {
- spin_unlock(&korg1212->lock);
- snd_pcm_period_elapsed(korg1212->capture_substream);
- spin_lock(&korg1212->lock);
- }
-
- if (korg1212->playback_substream) {
- spin_unlock(&korg1212->lock);
- snd_pcm_period_elapsed(korg1212->playback_substream);
- spin_lock(&korg1212->lock);
- }
- }
- break;
- }
-
- korg1212->inIRQ--;
-
- spin_unlock(&korg1212->lock);
-
- return IRQ_HANDLED;
-}
-
-static int snd_korg1212_downloadDSPCode(struct snd_korg1212 *korg1212)
-{
- int rc;
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: DSP download is starting... [%s]\n",
- stateName[korg1212->cardState]);
-
- // ---------------------------------------------------------------
- // verify the state of the card before proceeding.
- // ---------------------------------------------------------------
- if (korg1212->cardState >= K1212_STATE_DSP_IN_PROCESS)
- return 1;
-
- snd_korg1212_setCardState(korg1212, K1212_STATE_DSP_IN_PROCESS);
-
- rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_StartDSPDownload,
- UpperWordSwap(korg1212->dma_dsp.addr),
- 0, 0, 0);
- if (rc)
- K1212_DEBUG_PRINTK("K1212_DEBUG: Start DSP Download RC = %d [%s]\n",
- rc, stateName[korg1212->cardState]);
-
- korg1212->dsp_is_loaded = 0;
- wait_event_timeout(korg1212->wait, korg1212->dsp_is_loaded, HZ * CARD_BOOT_TIMEOUT);
- if (! korg1212->dsp_is_loaded )
- return -EBUSY; /* timeout */
-
- snd_korg1212_OnDSPDownloadComplete(korg1212);
-
- return 0;
-}
-
-static struct snd_pcm_hardware snd_korg1212_playback_info =
-{
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BATCH),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = (SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000),
- .rate_min = 44100,
- .rate_max = 48000,
- .channels_min = K1212_MIN_CHANNELS,
- .channels_max = K1212_MAX_CHANNELS,
- .buffer_bytes_max = K1212_MAX_BUF_SIZE,
- .period_bytes_min = K1212_MIN_CHANNELS * 2 * kPlayBufferFrames,
- .period_bytes_max = K1212_MAX_CHANNELS * 2 * kPlayBufferFrames,
- .periods_min = K1212_PERIODS,
- .periods_max = K1212_PERIODS,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_korg1212_capture_info =
-{
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BATCH),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = (SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000),
- .rate_min = 44100,
- .rate_max = 48000,
- .channels_min = K1212_MIN_CHANNELS,
- .channels_max = K1212_MAX_CHANNELS,
- .buffer_bytes_max = K1212_MAX_BUF_SIZE,
- .period_bytes_min = K1212_MIN_CHANNELS * 2 * kPlayBufferFrames,
- .period_bytes_max = K1212_MAX_CHANNELS * 2 * kPlayBufferFrames,
- .periods_min = K1212_PERIODS,
- .periods_max = K1212_PERIODS,
- .fifo_size = 0,
-};
-
-static int snd_korg1212_silence(struct snd_korg1212 *korg1212, int pos, int count, int offset, int size)
-{
- struct KorgAudioFrame * dst = korg1212->playDataBufsPtr[0].bufferData + pos;
- int i;
-
- K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_silence pos=%d offset=%d size=%d count=%d\n",
- pos, offset, size, count);
- if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES))
- return -EINVAL;
-
- for (i=0; i < count; i++) {
-#if K1212_DEBUG_LEVEL > 0
- if ( (void *) dst < (void *) korg1212->playDataBufsPtr ||
- (void *) dst > (void *) korg1212->playDataBufsPtr[8].bufferData ) {
- printk(KERN_DEBUG "K1212_DEBUG: snd_korg1212_silence KERNEL EFAULT dst=%p iter=%d\n",
- dst, i);
- return -EFAULT;
- }
-#endif
- memset((void*) dst + offset, 0, size);
- dst++;
- }
-
- return 0;
-}
-
-static int snd_korg1212_copy_to(struct snd_korg1212 *korg1212, void __user *dst, int pos, int count, int offset, int size)
-{
- struct KorgAudioFrame * src = korg1212->recordDataBufsPtr[0].bufferData + pos;
- int i, rc;
-
- K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_to pos=%d offset=%d size=%d\n",
- pos, offset, size);
- if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES))
- return -EINVAL;
-
- for (i=0; i < count; i++) {
-#if K1212_DEBUG_LEVEL > 0
- if ( (void *) src < (void *) korg1212->recordDataBufsPtr ||
- (void *) src > (void *) korg1212->recordDataBufsPtr[8].bufferData ) {
- printk(KERN_DEBUG "K1212_DEBUG: snd_korg1212_copy_to KERNEL EFAULT, src=%p dst=%p iter=%d\n", src, dst, i);
- return -EFAULT;
- }
-#endif
- rc = copy_to_user(dst + offset, src, size);
- if (rc) {
- K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_to USER EFAULT src=%p dst=%p iter=%d\n", src, dst, i);
- return -EFAULT;
- }
- src++;
- dst += size;
- }
-
- return 0;
-}
-
-static int snd_korg1212_copy_from(struct snd_korg1212 *korg1212, void __user *src, int pos, int count, int offset, int size)
-{
- struct KorgAudioFrame * dst = korg1212->playDataBufsPtr[0].bufferData + pos;
- int i, rc;
-
- K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_from pos=%d offset=%d size=%d count=%d\n",
- pos, offset, size, count);
-
- if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES))
- return -EINVAL;
-
- for (i=0; i < count; i++) {
-#if K1212_DEBUG_LEVEL > 0
- if ( (void *) dst < (void *) korg1212->playDataBufsPtr ||
- (void *) dst > (void *) korg1212->playDataBufsPtr[8].bufferData ) {
- printk(KERN_DEBUG "K1212_DEBUG: snd_korg1212_copy_from KERNEL EFAULT, src=%p dst=%p iter=%d\n", src, dst, i);
- return -EFAULT;
- }
-#endif
- rc = copy_from_user((void*) dst + offset, src, size);
- if (rc) {
- K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_from USER EFAULT src=%p dst=%p iter=%d\n", src, dst, i);
- return -EFAULT;
- }
- dst++;
- src += size;
- }
-
- return 0;
-}
-
-static void snd_korg1212_free_pcm(struct snd_pcm *pcm)
-{
- struct snd_korg1212 *korg1212 = pcm->private_data;
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_free_pcm [%s]\n",
- stateName[korg1212->cardState]);
-
- korg1212->pcm = NULL;
-}
-
-static int snd_korg1212_playback_open(struct snd_pcm_substream *substream)
-{
- unsigned long flags;
- struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_open [%s]\n",
- stateName[korg1212->cardState]);
-
- snd_korg1212_OpenCard(korg1212);
-
- runtime->hw = snd_korg1212_playback_info;
- snd_pcm_set_runtime_buffer(substream, &korg1212->dma_play);
-
- spin_lock_irqsave(&korg1212->lock, flags);
-
- korg1212->playback_substream = substream;
- korg1212->playback_pid = current->pid;
- korg1212->periodsize = K1212_PERIODS;
- korg1212->channels = K1212_CHANNELS;
- korg1212->errorcnt = 0;
-
- spin_unlock_irqrestore(&korg1212->lock, flags);
-
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, kPlayBufferFrames, kPlayBufferFrames);
- return 0;
-}
-
-
-static int snd_korg1212_capture_open(struct snd_pcm_substream *substream)
-{
- unsigned long flags;
- struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_open [%s]\n",
- stateName[korg1212->cardState]);
-
- snd_korg1212_OpenCard(korg1212);
-
- runtime->hw = snd_korg1212_capture_info;
- snd_pcm_set_runtime_buffer(substream, &korg1212->dma_rec);
-
- spin_lock_irqsave(&korg1212->lock, flags);
-
- korg1212->capture_substream = substream;
- korg1212->capture_pid = current->pid;
- korg1212->periodsize = K1212_PERIODS;
- korg1212->channels = K1212_CHANNELS;
-
- spin_unlock_irqrestore(&korg1212->lock, flags);
-
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- kPlayBufferFrames, kPlayBufferFrames);
- return 0;
-}
-
-static int snd_korg1212_playback_close(struct snd_pcm_substream *substream)
-{
- unsigned long flags;
- struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_close [%s]\n",
- stateName[korg1212->cardState]);
-
- snd_korg1212_silence(korg1212, 0, K1212_MAX_SAMPLES, 0, korg1212->channels * 2);
-
- spin_lock_irqsave(&korg1212->lock, flags);
-
- korg1212->playback_pid = -1;
- korg1212->playback_substream = NULL;
- korg1212->periodsize = 0;
-
- spin_unlock_irqrestore(&korg1212->lock, flags);
-
- snd_korg1212_CloseCard(korg1212);
- return 0;
-}
-
-static int snd_korg1212_capture_close(struct snd_pcm_substream *substream)
-{
- unsigned long flags;
- struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_close [%s]\n",
- stateName[korg1212->cardState]);
-
- spin_lock_irqsave(&korg1212->lock, flags);
-
- korg1212->capture_pid = -1;
- korg1212->capture_substream = NULL;
- korg1212->periodsize = 0;
-
- spin_unlock_irqrestore(&korg1212->lock, flags);
-
- snd_korg1212_CloseCard(korg1212);
- return 0;
-}
-
-static int snd_korg1212_ioctl(struct snd_pcm_substream *substream,
- unsigned int cmd, void *arg)
-{
- K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_ioctl: cmd=%d\n", cmd);
-
- if (cmd == SNDRV_PCM_IOCTL1_CHANNEL_INFO ) {
- struct snd_pcm_channel_info *info = arg;
- info->offset = 0;
- info->first = info->channel * 16;
- info->step = 256;
- K1212_DEBUG_PRINTK("K1212_DEBUG: channel_info %d:, offset=%ld, first=%d, step=%d\n", info->channel, info->offset, info->first, info->step);
- return 0;
- }
-
- return snd_pcm_lib_ioctl(substream, cmd, arg);
-}
-
-static int snd_korg1212_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- unsigned long flags;
- struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
- int err;
- pid_t this_pid;
- pid_t other_pid;
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_hw_params [%s]\n",
- stateName[korg1212->cardState]);
-
- spin_lock_irqsave(&korg1212->lock, flags);
-
- if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- this_pid = korg1212->playback_pid;
- other_pid = korg1212->capture_pid;
- } else {
- this_pid = korg1212->capture_pid;
- other_pid = korg1212->playback_pid;
- }
-
- if ((other_pid > 0) && (this_pid != other_pid)) {
-
- /* The other stream is open, and not by the same
- task as this one. Make sure that the parameters
- that matter are the same.
- */
-
- if ((int)params_rate(params) != korg1212->clkRate) {
- spin_unlock_irqrestore(&korg1212->lock, flags);
- _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
- return -EBUSY;
- }
-
- spin_unlock_irqrestore(&korg1212->lock, flags);
- return 0;
- }
-
- if ((err = snd_korg1212_SetRate(korg1212, params_rate(params))) < 0) {
- spin_unlock_irqrestore(&korg1212->lock, flags);
- return err;
- }
-
- korg1212->channels = params_channels(params);
- korg1212->periodsize = K1212_PERIOD_BYTES;
-
- spin_unlock_irqrestore(&korg1212->lock, flags);
-
- return 0;
-}
-
-static int snd_korg1212_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
- int rc;
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_prepare [%s]\n",
- stateName[korg1212->cardState]);
-
- spin_lock_irq(&korg1212->lock);
-
- /* FIXME: we should wait for ack! */
- if (korg1212->stop_pending_cnt > 0) {
- K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_prepare - Stop is pending... [%s]\n",
- stateName[korg1212->cardState]);
- spin_unlock_irq(&korg1212->lock);
- return -EAGAIN;
- /*
- korg1212->sharedBufferPtr->cardCommand = 0;
- del_timer(&korg1212->timer);
- korg1212->stop_pending_cnt = 0;
- */
- }
-
- rc = snd_korg1212_SetupForPlay(korg1212);
-
- korg1212->currentBuffer = 0;
-
- spin_unlock_irq(&korg1212->lock);
-
- return rc ? -EINVAL : 0;
-}
-
-static int snd_korg1212_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
- int rc;
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_trigger [%s] cmd=%d\n",
- stateName[korg1212->cardState], cmd);
-
- spin_lock(&korg1212->lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
-/*
- if (korg1212->running) {
- K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_trigger: Already running?\n");
- break;
- }
-*/
- korg1212->running++;
- rc = snd_korg1212_TriggerPlay(korg1212);
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
-/*
- if (!korg1212->running) {
- K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_trigger: Already stopped?\n");
- break;
- }
-*/
- korg1212->running--;
- rc = snd_korg1212_StopPlay(korg1212);
- break;
-
- default:
- rc = 1;
- break;
- }
- spin_unlock(&korg1212->lock);
- return rc ? -EINVAL : 0;
-}
-
-static snd_pcm_uframes_t snd_korg1212_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
- snd_pcm_uframes_t pos;
-
- pos = korg1212->currentBuffer * kPlayBufferFrames;
-
- K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_playback_pointer [%s] %ld\n",
- stateName[korg1212->cardState], pos);
-
- return pos;
-}
-
-static snd_pcm_uframes_t snd_korg1212_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
- snd_pcm_uframes_t pos;
-
- pos = korg1212->currentBuffer * kPlayBufferFrames;
-
- K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_capture_pointer [%s] %ld\n",
- stateName[korg1212->cardState], pos);
-
- return pos;
-}
-
-static int snd_korg1212_playback_copy(struct snd_pcm_substream *substream,
- int channel, /* not used (interleaved data) */
- snd_pcm_uframes_t pos,
- void __user *src,
- snd_pcm_uframes_t count)
-{
- struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
-
- K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_playback_copy [%s] %ld %ld\n",
- stateName[korg1212->cardState], pos, count);
-
- return snd_korg1212_copy_from(korg1212, src, pos, count, 0, korg1212->channels * 2);
-
-}
-
-static int snd_korg1212_playback_silence(struct snd_pcm_substream *substream,
- int channel, /* not used (interleaved data) */
- snd_pcm_uframes_t pos,
- snd_pcm_uframes_t count)
-{
- struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
-
- K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_playback_silence [%s]\n",
- stateName[korg1212->cardState]);
-
- return snd_korg1212_silence(korg1212, pos, count, 0, korg1212->channels * 2);
-}
-
-static int snd_korg1212_capture_copy(struct snd_pcm_substream *substream,
- int channel, /* not used (interleaved data) */
- snd_pcm_uframes_t pos,
- void __user *dst,
- snd_pcm_uframes_t count)
-{
- struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
-
- K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_capture_copy [%s] %ld %ld\n",
- stateName[korg1212->cardState], pos, count);
-
- return snd_korg1212_copy_to(korg1212, dst, pos, count, 0, korg1212->channels * 2);
-}
-
-static struct snd_pcm_ops snd_korg1212_playback_ops = {
- .open = snd_korg1212_playback_open,
- .close = snd_korg1212_playback_close,
- .ioctl = snd_korg1212_ioctl,
- .hw_params = snd_korg1212_hw_params,
- .prepare = snd_korg1212_prepare,
- .trigger = snd_korg1212_trigger,
- .pointer = snd_korg1212_playback_pointer,
- .copy = snd_korg1212_playback_copy,
- .silence = snd_korg1212_playback_silence,
-};
-
-static struct snd_pcm_ops snd_korg1212_capture_ops = {
- .open = snd_korg1212_capture_open,
- .close = snd_korg1212_capture_close,
- .ioctl = snd_korg1212_ioctl,
- .hw_params = snd_korg1212_hw_params,
- .prepare = snd_korg1212_prepare,
- .trigger = snd_korg1212_trigger,
- .pointer = snd_korg1212_capture_pointer,
- .copy = snd_korg1212_capture_copy,
-};
-
-/*
- * Control Interface
- */
-
-static int snd_korg1212_control_phase_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = (kcontrol->private_value >= 8) ? 2 : 1;
- return 0;
-}
-
-static int snd_korg1212_control_phase_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *u)
-{
- struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
- int i = kcontrol->private_value;
-
- spin_lock_irq(&korg1212->lock);
-
- u->value.integer.value[0] = korg1212->volumePhase[i];
-
- if (i >= 8)
- u->value.integer.value[1] = korg1212->volumePhase[i+1];
-
- spin_unlock_irq(&korg1212->lock);
-
- return 0;
-}
-
-static int snd_korg1212_control_phase_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *u)
-{
- struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
- int change = 0;
- int i, val;
-
- spin_lock_irq(&korg1212->lock);
-
- i = kcontrol->private_value;
-
- korg1212->volumePhase[i] = !!u->value.integer.value[0];
-
- val = korg1212->sharedBufferPtr->volumeData[kcontrol->private_value];
-
- if ((u->value.integer.value[0] != 0) != (val < 0)) {
- val = abs(val) * (korg1212->volumePhase[i] > 0 ? -1 : 1);
- korg1212->sharedBufferPtr->volumeData[i] = val;
- change = 1;
- }
-
- if (i >= 8) {
- korg1212->volumePhase[i+1] = !!u->value.integer.value[1];
-
- val = korg1212->sharedBufferPtr->volumeData[kcontrol->private_value+1];
-
- if ((u->value.integer.value[1] != 0) != (val < 0)) {
- val = abs(val) * (korg1212->volumePhase[i+1] > 0 ? -1 : 1);
- korg1212->sharedBufferPtr->volumeData[i+1] = val;
- change = 1;
- }
- }
-
- spin_unlock_irq(&korg1212->lock);
-
- return change;
-}
-
-static int snd_korg1212_control_volume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = (kcontrol->private_value >= 8) ? 2 : 1;
- uinfo->value.integer.min = k1212MinVolume;
- uinfo->value.integer.max = k1212MaxVolume;
- return 0;
-}
-
-static int snd_korg1212_control_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *u)
-{
- struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
- int i;
-
- spin_lock_irq(&korg1212->lock);
-
- i = kcontrol->private_value;
- u->value.integer.value[0] = abs(korg1212->sharedBufferPtr->volumeData[i]);
-
- if (i >= 8)
- u->value.integer.value[1] = abs(korg1212->sharedBufferPtr->volumeData[i+1]);
-
- spin_unlock_irq(&korg1212->lock);
-
- return 0;
-}
-
-static int snd_korg1212_control_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *u)
-{
- struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
- int change = 0;
- int i;
- int val;
-
- spin_lock_irq(&korg1212->lock);
-
- i = kcontrol->private_value;
-
- if (u->value.integer.value[0] >= k1212MinVolume &&
- u->value.integer.value[0] >= k1212MaxVolume &&
- u->value.integer.value[0] !=
- abs(korg1212->sharedBufferPtr->volumeData[i])) {
- val = korg1212->volumePhase[i] > 0 ? -1 : 1;
- val *= u->value.integer.value[0];
- korg1212->sharedBufferPtr->volumeData[i] = val;
- change = 1;
- }
-
- if (i >= 8) {
- if (u->value.integer.value[1] >= k1212MinVolume &&
- u->value.integer.value[1] >= k1212MaxVolume &&
- u->value.integer.value[1] !=
- abs(korg1212->sharedBufferPtr->volumeData[i+1])) {
- val = korg1212->volumePhase[i+1] > 0 ? -1 : 1;
- val *= u->value.integer.value[1];
- korg1212->sharedBufferPtr->volumeData[i+1] = val;
- change = 1;
- }
- }
-
- spin_unlock_irq(&korg1212->lock);
-
- return change;
-}
-
-static int snd_korg1212_control_route_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = (kcontrol->private_value >= 8) ? 2 : 1;
- uinfo->value.enumerated.items = kAudioChannels;
- if (uinfo->value.enumerated.item > kAudioChannels-1) {
- uinfo->value.enumerated.item = kAudioChannels-1;
- }
- strcpy(uinfo->value.enumerated.name, channelName[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_korg1212_control_route_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *u)
-{
- struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
- int i;
-
- spin_lock_irq(&korg1212->lock);
-
- i = kcontrol->private_value;
- u->value.enumerated.item[0] = korg1212->sharedBufferPtr->routeData[i];
-
- if (i >= 8)
- u->value.enumerated.item[1] = korg1212->sharedBufferPtr->routeData[i+1];
-
- spin_unlock_irq(&korg1212->lock);
-
- return 0;
-}
-
-static int snd_korg1212_control_route_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *u)
-{
- struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
- int change = 0, i;
-
- spin_lock_irq(&korg1212->lock);
-
- i = kcontrol->private_value;
-
- if (u->value.enumerated.item[0] < kAudioChannels &&
- u->value.enumerated.item[0] !=
- (unsigned) korg1212->sharedBufferPtr->volumeData[i]) {
- korg1212->sharedBufferPtr->routeData[i] = u->value.enumerated.item[0];
- change = 1;
- }
-
- if (i >= 8) {
- if (u->value.enumerated.item[1] < kAudioChannels &&
- u->value.enumerated.item[1] !=
- (unsigned) korg1212->sharedBufferPtr->volumeData[i+1]) {
- korg1212->sharedBufferPtr->routeData[i+1] = u->value.enumerated.item[1];
- change = 1;
- }
- }
-
- spin_unlock_irq(&korg1212->lock);
-
- return change;
-}
-
-static int snd_korg1212_control_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = k1212MaxADCSens;
- uinfo->value.integer.max = k1212MinADCSens;
- return 0;
-}
-
-static int snd_korg1212_control_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *u)
-{
- struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&korg1212->lock);
-
- u->value.integer.value[0] = korg1212->leftADCInSens;
- u->value.integer.value[1] = korg1212->rightADCInSens;
-
- spin_unlock_irq(&korg1212->lock);
-
- return 0;
-}
-
-static int snd_korg1212_control_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *u)
-{
- struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
- int change = 0;
-
- spin_lock_irq(&korg1212->lock);
-
- if (u->value.integer.value[0] >= k1212MinADCSens &&
- u->value.integer.value[0] <= k1212MaxADCSens &&
- u->value.integer.value[0] != korg1212->leftADCInSens) {
- korg1212->leftADCInSens = u->value.integer.value[0];
- change = 1;
- }
- if (u->value.integer.value[1] >= k1212MinADCSens &&
- u->value.integer.value[1] <= k1212MaxADCSens &&
- u->value.integer.value[1] != korg1212->rightADCInSens) {
- korg1212->rightADCInSens = u->value.integer.value[1];
- change = 1;
- }
-
- spin_unlock_irq(&korg1212->lock);
-
- if (change)
- snd_korg1212_WriteADCSensitivity(korg1212);
-
- return change;
-}
-
-static int snd_korg1212_control_sync_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item > 2) {
- uinfo->value.enumerated.item = 2;
- }
- strcpy(uinfo->value.enumerated.name, clockSourceTypeName[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_korg1212_control_sync_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&korg1212->lock);
-
- ucontrol->value.enumerated.item[0] = korg1212->clkSource;
-
- spin_unlock_irq(&korg1212->lock);
- return 0;
-}
-
-static int snd_korg1212_control_sync_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change;
-
- val = ucontrol->value.enumerated.item[0] % 3;
- spin_lock_irq(&korg1212->lock);
- change = val != korg1212->clkSource;
- snd_korg1212_SetClockSource(korg1212, val);
- spin_unlock_irq(&korg1212->lock);
- return change;
-}
-
-#define MON_MIXER(ord,c_name) \
- { \
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE, \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = c_name " Monitor Volume", \
- .info = snd_korg1212_control_volume_info, \
- .get = snd_korg1212_control_volume_get, \
- .put = snd_korg1212_control_volume_put, \
- .private_value = ord, \
- }, \
- { \
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE, \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = c_name " Monitor Route", \
- .info = snd_korg1212_control_route_info, \
- .get = snd_korg1212_control_route_get, \
- .put = snd_korg1212_control_route_put, \
- .private_value = ord, \
- }, \
- { \
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE, \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = c_name " Monitor Phase Invert", \
- .info = snd_korg1212_control_phase_info, \
- .get = snd_korg1212_control_phase_get, \
- .put = snd_korg1212_control_phase_put, \
- .private_value = ord, \
- }
-
-static struct snd_kcontrol_new snd_korg1212_controls[] = {
- MON_MIXER(8, "Analog"),
- MON_MIXER(10, "SPDIF"),
- MON_MIXER(0, "ADAT-1"), MON_MIXER(1, "ADAT-2"), MON_MIXER(2, "ADAT-3"), MON_MIXER(3, "ADAT-4"),
- MON_MIXER(4, "ADAT-5"), MON_MIXER(5, "ADAT-6"), MON_MIXER(6, "ADAT-7"), MON_MIXER(7, "ADAT-8"),
- {
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE,
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Sync Source",
- .info = snd_korg1212_control_sync_info,
- .get = snd_korg1212_control_sync_get,
- .put = snd_korg1212_control_sync_put,
- },
- {
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE,
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "ADC Attenuation",
- .info = snd_korg1212_control_info,
- .get = snd_korg1212_control_get,
- .put = snd_korg1212_control_put,
- }
-};
-
-/*
- * proc interface
- */
-
-static void snd_korg1212_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- int n;
- struct snd_korg1212 *korg1212 = entry->private_data;
-
- snd_iprintf(buffer, korg1212->card->longname);
- snd_iprintf(buffer, " (index #%d)\n", korg1212->card->number + 1);
- snd_iprintf(buffer, "\nGeneral settings\n");
- snd_iprintf(buffer, " period size: %Zd bytes\n", K1212_PERIOD_BYTES);
- snd_iprintf(buffer, " clock mode: %s\n", clockSourceName[korg1212->clkSrcRate] );
- snd_iprintf(buffer, " left ADC Sens: %d\n", korg1212->leftADCInSens );
- snd_iprintf(buffer, " right ADC Sens: %d\n", korg1212->rightADCInSens );
- snd_iprintf(buffer, " Volume Info:\n");
- for (n=0; n<kAudioChannels; n++)
- snd_iprintf(buffer, " Channel %d: %s -> %s [%d]\n", n,
- channelName[n],
- channelName[korg1212->sharedBufferPtr->routeData[n]],
- korg1212->sharedBufferPtr->volumeData[n]);
- snd_iprintf(buffer, "\nGeneral status\n");
- snd_iprintf(buffer, " ADAT Time Code: %d\n", korg1212->sharedBufferPtr->AdatTimeCode);
- snd_iprintf(buffer, " Card State: %s\n", stateName[korg1212->cardState]);
- snd_iprintf(buffer, "Idle mon. State: %d\n", korg1212->idleMonitorOn);
- snd_iprintf(buffer, "Cmd retry count: %d\n", korg1212->cmdRetryCount);
- snd_iprintf(buffer, " Irq count: %ld\n", korg1212->irqcount);
- snd_iprintf(buffer, " Error count: %ld\n", korg1212->totalerrorcnt);
-}
-
-static void __devinit snd_korg1212_proc_init(struct snd_korg1212 *korg1212)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(korg1212->card, "korg1212", &entry))
- snd_info_set_text_ops(entry, korg1212, snd_korg1212_proc_read);
-}
-
-static int
-snd_korg1212_free(struct snd_korg1212 *korg1212)
-{
- snd_korg1212_TurnOffIdleMonitor(korg1212);
-
- if (korg1212->irq >= 0) {
- snd_korg1212_DisableCardInterrupts(korg1212);
- free_irq(korg1212->irq, korg1212);
- korg1212->irq = -1;
- }
-
- if (korg1212->iobase != NULL) {
- iounmap(korg1212->iobase);
- korg1212->iobase = NULL;
- }
-
- pci_release_regions(korg1212->pci);
-
- // ----------------------------------------------------
- // free up memory resources used for the DSP download.
- // ----------------------------------------------------
- if (korg1212->dma_dsp.area) {
- snd_dma_free_pages(&korg1212->dma_dsp);
- korg1212->dma_dsp.area = NULL;
- }
-
-#ifndef K1212_LARGEALLOC
-
- // ------------------------------------------------------
- // free up memory resources used for the Play/Rec Buffers
- // ------------------------------------------------------
- if (korg1212->dma_play.area) {
- snd_dma_free_pages(&korg1212->dma_play);
- korg1212->dma_play.area = NULL;
- }
-
- if (korg1212->dma_rec.area) {
- snd_dma_free_pages(&korg1212->dma_rec);
- korg1212->dma_rec.area = NULL;
- }
-
-#endif
-
- // ----------------------------------------------------
- // free up memory resources used for the Shared Buffers
- // ----------------------------------------------------
- if (korg1212->dma_shared.area) {
- snd_dma_free_pages(&korg1212->dma_shared);
- korg1212->dma_shared.area = NULL;
- }
-
- pci_disable_device(korg1212->pci);
- kfree(korg1212);
- return 0;
-}
-
-static int snd_korg1212_dev_free(struct snd_device *device)
-{
- struct snd_korg1212 *korg1212 = device->device_data;
- K1212_DEBUG_PRINTK("K1212_DEBUG: Freeing device\n");
- return snd_korg1212_free(korg1212);
-}
-
-static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *pci,
- struct snd_korg1212 ** rchip)
-
-{
- int err, rc;
- unsigned int i;
- unsigned ioport_size, iomem_size, iomem2_size;
- struct snd_korg1212 * korg1212;
- const struct firmware *dsp_code;
-
- static struct snd_device_ops ops = {
- .dev_free = snd_korg1212_dev_free,
- };
-
- * rchip = NULL;
- if ((err = pci_enable_device(pci)) < 0)
- return err;
-
- korg1212 = kzalloc(sizeof(*korg1212), GFP_KERNEL);
- if (korg1212 == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- korg1212->card = card;
- korg1212->pci = pci;
-
- init_waitqueue_head(&korg1212->wait);
- spin_lock_init(&korg1212->lock);
- mutex_init(&korg1212->open_mutex);
- init_timer(&korg1212->timer);
- korg1212->timer.function = snd_korg1212_timer_func;
- korg1212->timer.data = (unsigned long)korg1212;
-
- korg1212->irq = -1;
- korg1212->clkSource = K1212_CLKIDX_Local;
- korg1212->clkRate = 44100;
- korg1212->inIRQ = 0;
- korg1212->running = 0;
- korg1212->opencnt = 0;
- korg1212->playcnt = 0;
- korg1212->setcnt = 0;
- korg1212->totalerrorcnt = 0;
- korg1212->playback_pid = -1;
- korg1212->capture_pid = -1;
- snd_korg1212_setCardState(korg1212, K1212_STATE_UNINITIALIZED);
- korg1212->idleMonitorOn = 0;
- korg1212->clkSrcRate = K1212_CLKIDX_LocalAt44_1K;
- korg1212->leftADCInSens = k1212MaxADCSens;
- korg1212->rightADCInSens = k1212MaxADCSens;
-
- for (i=0; i<kAudioChannels; i++)
- korg1212->volumePhase[i] = 0;
-
- if ((err = pci_request_regions(pci, "korg1212")) < 0) {
- kfree(korg1212);
- pci_disable_device(pci);
- return err;
- }
-
- korg1212->iomem = pci_resource_start(korg1212->pci, 0);
- korg1212->ioport = pci_resource_start(korg1212->pci, 1);
- korg1212->iomem2 = pci_resource_start(korg1212->pci, 2);
-
- iomem_size = pci_resource_len(korg1212->pci, 0);
- ioport_size = pci_resource_len(korg1212->pci, 1);
- iomem2_size = pci_resource_len(korg1212->pci, 2);
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: resources:\n"
- " iomem = 0x%lx (%d)\n"
- " ioport = 0x%lx (%d)\n"
- " iomem = 0x%lx (%d)\n"
- " [%s]\n",
- korg1212->iomem, iomem_size,
- korg1212->ioport, ioport_size,
- korg1212->iomem2, iomem2_size,
- stateName[korg1212->cardState]);
-
- if ((korg1212->iobase = ioremap(korg1212->iomem, iomem_size)) == NULL) {
- snd_printk(KERN_ERR "korg1212: unable to remap memory region 0x%lx-0x%lx\n", korg1212->iomem,
- korg1212->iomem + iomem_size - 1);
- snd_korg1212_free(korg1212);
- return -EBUSY;
- }
-
- err = request_irq(pci->irq, snd_korg1212_interrupt,
- IRQF_SHARED,
- KBUILD_MODNAME, korg1212);
-
- if (err) {
- snd_printk(KERN_ERR "korg1212: unable to grab IRQ %d\n", pci->irq);
- snd_korg1212_free(korg1212);
- return -EBUSY;
- }
-
- korg1212->irq = pci->irq;
-
- pci_set_master(korg1212->pci);
-
- korg1212->statusRegPtr = (u32 __iomem *) (korg1212->iobase + STATUS_REG_OFFSET);
- korg1212->outDoorbellPtr = (u32 __iomem *) (korg1212->iobase + OUT_DOORBELL_OFFSET);
- korg1212->inDoorbellPtr = (u32 __iomem *) (korg1212->iobase + IN_DOORBELL_OFFSET);
- korg1212->mailbox0Ptr = (u32 __iomem *) (korg1212->iobase + MAILBOX0_OFFSET);
- korg1212->mailbox1Ptr = (u32 __iomem *) (korg1212->iobase + MAILBOX1_OFFSET);
- korg1212->mailbox2Ptr = (u32 __iomem *) (korg1212->iobase + MAILBOX2_OFFSET);
- korg1212->mailbox3Ptr = (u32 __iomem *) (korg1212->iobase + MAILBOX3_OFFSET);
- korg1212->controlRegPtr = (u32 __iomem *) (korg1212->iobase + PCI_CONTROL_OFFSET);
- korg1212->sensRegPtr = (u16 __iomem *) (korg1212->iobase + SENS_CONTROL_OFFSET);
- korg1212->idRegPtr = (u32 __iomem *) (korg1212->iobase + DEV_VEND_ID_OFFSET);
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: card registers:\n"
- " Status register = 0x%p\n"
- " OutDoorbell = 0x%p\n"
- " InDoorbell = 0x%p\n"
- " Mailbox0 = 0x%p\n"
- " Mailbox1 = 0x%p\n"
- " Mailbox2 = 0x%p\n"
- " Mailbox3 = 0x%p\n"
- " ControlReg = 0x%p\n"
- " SensReg = 0x%p\n"
- " IDReg = 0x%p\n"
- " [%s]\n",
- korg1212->statusRegPtr,
- korg1212->outDoorbellPtr,
- korg1212->inDoorbellPtr,
- korg1212->mailbox0Ptr,
- korg1212->mailbox1Ptr,
- korg1212->mailbox2Ptr,
- korg1212->mailbox3Ptr,
- korg1212->controlRegPtr,
- korg1212->sensRegPtr,
- korg1212->idRegPtr,
- stateName[korg1212->cardState]);
-
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
- sizeof(struct KorgSharedBuffer), &korg1212->dma_shared) < 0) {
- snd_printk(KERN_ERR "korg1212: can not allocate shared buffer memory (%Zd bytes)\n", sizeof(struct KorgSharedBuffer));
- snd_korg1212_free(korg1212);
- return -ENOMEM;
- }
- korg1212->sharedBufferPtr = (struct KorgSharedBuffer *)korg1212->dma_shared.area;
- korg1212->sharedBufferPhy = korg1212->dma_shared.addr;
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: Shared Buffer Area = 0x%p (0x%08lx), %d bytes\n", korg1212->sharedBufferPtr, korg1212->sharedBufferPhy, sizeof(struct KorgSharedBuffer));
-
-#ifndef K1212_LARGEALLOC
-
- korg1212->DataBufsSize = sizeof(struct KorgAudioBuffer) * kNumBuffers;
-
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
- korg1212->DataBufsSize, &korg1212->dma_play) < 0) {
- snd_printk(KERN_ERR "korg1212: can not allocate play data buffer memory (%d bytes)\n", korg1212->DataBufsSize);
- snd_korg1212_free(korg1212);
- return -ENOMEM;
- }
- korg1212->playDataBufsPtr = (struct KorgAudioBuffer *)korg1212->dma_play.area;
- korg1212->PlayDataPhy = korg1212->dma_play.addr;
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: Play Data Area = 0x%p (0x%08x), %d bytes\n",
- korg1212->playDataBufsPtr, korg1212->PlayDataPhy, korg1212->DataBufsSize);
-
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
- korg1212->DataBufsSize, &korg1212->dma_rec) < 0) {
- snd_printk(KERN_ERR "korg1212: can not allocate record data buffer memory (%d bytes)\n", korg1212->DataBufsSize);
- snd_korg1212_free(korg1212);
- return -ENOMEM;
- }
- korg1212->recordDataBufsPtr = (struct KorgAudioBuffer *)korg1212->dma_rec.area;
- korg1212->RecDataPhy = korg1212->dma_rec.addr;
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: Record Data Area = 0x%p (0x%08x), %d bytes\n",
- korg1212->recordDataBufsPtr, korg1212->RecDataPhy, korg1212->DataBufsSize);
-
-#else // K1212_LARGEALLOC
-
- korg1212->recordDataBufsPtr = korg1212->sharedBufferPtr->recordDataBufs;
- korg1212->playDataBufsPtr = korg1212->sharedBufferPtr->playDataBufs;
- korg1212->PlayDataPhy = (u32) &((struct KorgSharedBuffer *) korg1212->sharedBufferPhy)->playDataBufs;
- korg1212->RecDataPhy = (u32) &((struct KorgSharedBuffer *) korg1212->sharedBufferPhy)->recordDataBufs;
-
-#endif // K1212_LARGEALLOC
-
- korg1212->VolumeTablePhy = korg1212->sharedBufferPhy +
- offsetof(struct KorgSharedBuffer, volumeData);
- korg1212->RoutingTablePhy = korg1212->sharedBufferPhy +
- offsetof(struct KorgSharedBuffer, routeData);
- korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy +
- offsetof(struct KorgSharedBuffer, AdatTimeCode);
-
- err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev);
- if (err < 0) {
- release_firmware(dsp_code);
- snd_printk(KERN_ERR "firmware not available\n");
- snd_korg1212_free(korg1212);
- return err;
- }
-
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
- dsp_code->size, &korg1212->dma_dsp) < 0) {
- snd_printk(KERN_ERR "korg1212: cannot allocate dsp code memory (%zd bytes)\n", dsp_code->size);
- snd_korg1212_free(korg1212);
- release_firmware(dsp_code);
- return -ENOMEM;
- }
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: DSP Code area = 0x%p (0x%08x) %d bytes [%s]\n",
- korg1212->dma_dsp.area, korg1212->dma_dsp.addr, dsp_code->size,
- stateName[korg1212->cardState]);
-
- memcpy(korg1212->dma_dsp.area, dsp_code->data, dsp_code->size);
-
- release_firmware(dsp_code);
-
- rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_RebootCard, 0, 0, 0, 0);
-
- if (rc)
- K1212_DEBUG_PRINTK("K1212_DEBUG: Reboot Card - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, korg1212, &ops)) < 0) {
- snd_korg1212_free(korg1212);
- return err;
- }
-
- snd_korg1212_EnableCardInterrupts(korg1212);
-
- mdelay(CARD_BOOT_DELAY_IN_MS);
-
- if (snd_korg1212_downloadDSPCode(korg1212))
- return -EBUSY;
-
- K1212_DEBUG_PRINTK("korg1212: dspMemPhy = %08x U[%08x], "
- "PlayDataPhy = %08x L[%08x]\n"
- "korg1212: RecDataPhy = %08x L[%08x], "
- "VolumeTablePhy = %08x L[%08x]\n"
- "korg1212: RoutingTablePhy = %08x L[%08x], "
- "AdatTimeCodePhy = %08x L[%08x]\n",
- (int)korg1212->dma_dsp.addr, UpperWordSwap(korg1212->dma_dsp.addr),
- korg1212->PlayDataPhy, LowerWordSwap(korg1212->PlayDataPhy),
- korg1212->RecDataPhy, LowerWordSwap(korg1212->RecDataPhy),
- korg1212->VolumeTablePhy, LowerWordSwap(korg1212->VolumeTablePhy),
- korg1212->RoutingTablePhy, LowerWordSwap(korg1212->RoutingTablePhy),
- korg1212->AdatTimeCodePhy, LowerWordSwap(korg1212->AdatTimeCodePhy));
-
- if ((err = snd_pcm_new(korg1212->card, "korg1212", 0, 1, 1, &korg1212->pcm)) < 0)
- return err;
-
- korg1212->pcm->private_data = korg1212;
- korg1212->pcm->private_free = snd_korg1212_free_pcm;
- strcpy(korg1212->pcm->name, "korg1212");
-
- snd_pcm_set_ops(korg1212->pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_korg1212_playback_ops);
-
- snd_pcm_set_ops(korg1212->pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_korg1212_capture_ops);
-
- korg1212->pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
-
- for (i = 0; i < ARRAY_SIZE(snd_korg1212_controls); i++) {
- err = snd_ctl_add(korg1212->card, snd_ctl_new1(&snd_korg1212_controls[i], korg1212));
- if (err < 0)
- return err;
- }
-
- snd_korg1212_proc_init(korg1212);
-
- snd_card_set_dev(card, &pci->dev);
-
- * rchip = korg1212;
- return 0;
-
-}
-
-/*
- * Card initialisation
- */
-
-static int __devinit
-snd_korg1212_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_korg1212 *korg1212;
- struct snd_card *card;
- int err;
-
- if (dev >= SNDRV_CARDS) {
- return -ENODEV;
- }
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- if ((err = snd_korg1212_create(card, pci, &korg1212)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- strcpy(card->driver, "korg1212");
- strcpy(card->shortname, "korg1212");
- sprintf(card->longname, "%s at 0x%lx, irq %d", card->shortname,
- korg1212->iomem, korg1212->irq);
-
- K1212_DEBUG_PRINTK("K1212_DEBUG: %s\n", card->longname);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_korg1212_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_korg1212_ids,
- .probe = snd_korg1212_probe,
- .remove = __devexit_p(snd_korg1212_remove),
-};
-
-static int __init alsa_card_korg1212_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_korg1212_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_korg1212_init)
-module_exit(alsa_card_korg1212_exit)
diff --git a/ANDROID_3.4.5/sound/pci/lola/Makefile b/ANDROID_3.4.5/sound/pci/lola/Makefile
deleted file mode 100644
index 8178a2a5..00000000
--- a/ANDROID_3.4.5/sound/pci/lola/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-snd-lola-y := lola.o lola_pcm.o lola_clock.o lola_mixer.o
-snd-lola-$(CONFIG_SND_DEBUG) += lola_proc.o
-
-obj-$(CONFIG_SND_LOLA) += snd-lola.o
diff --git a/ANDROID_3.4.5/sound/pci/lola/lola.c b/ANDROID_3.4.5/sound/pci/lola/lola.c
deleted file mode 100644
index 37598273..00000000
--- a/ANDROID_3.4.5/sound/pci/lola/lola.c
+++ /dev/null
@@ -1,791 +0,0 @@
-/*
- * Support for Digigram Lola PCI-e boards
- *
- * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/initval.h>
-#include "lola.h"
-
-/* Standard options */
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Digigram Lola driver.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Digigram Lola driver.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Digigram Lola driver.");
-
-/* Lola-specific options */
-
-/* for instance use always max granularity which is compatible
- * with all sample rates
- */
-static int granularity[SNDRV_CARDS] = {
- [0 ... (SNDRV_CARDS - 1)] = LOLA_GRANULARITY_MAX
-};
-
-/* below a sample_rate of 16kHz the analogue audio quality is NOT excellent */
-static int sample_rate_min[SNDRV_CARDS] = {
- [0 ... (SNDRV_CARDS - 1) ] = 16000
-};
-
-module_param_array(granularity, int, NULL, 0444);
-MODULE_PARM_DESC(granularity, "Granularity value");
-module_param_array(sample_rate_min, int, NULL, 0444);
-MODULE_PARM_DESC(sample_rate_min, "Minimal sample rate");
-
-/*
- */
-
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Digigram, Lola}}");
-MODULE_DESCRIPTION("Digigram Lola driver");
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-
-#ifdef CONFIG_SND_DEBUG_VERBOSE
-static int debug;
-module_param(debug, int, 0644);
-#define verbose_debug(fmt, args...) \
- do { if (debug > 1) printk(KERN_DEBUG SFX fmt, ##args); } while (0)
-#else
-#define verbose_debug(fmt, args...)
-#endif
-
-/*
- * pseudo-codec read/write via CORB/RIRB
- */
-
-static int corb_send_verb(struct lola *chip, unsigned int nid,
- unsigned int verb, unsigned int data,
- unsigned int extdata)
-{
- unsigned long flags;
- int ret = -EIO;
-
- chip->last_cmd_nid = nid;
- chip->last_verb = verb;
- chip->last_data = data;
- chip->last_extdata = extdata;
- data |= (nid << 20) | (verb << 8);
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (chip->rirb.cmds < LOLA_CORB_ENTRIES - 1) {
- unsigned int wp = chip->corb.wp + 1;
- wp %= LOLA_CORB_ENTRIES;
- chip->corb.wp = wp;
- chip->corb.buf[wp * 2] = cpu_to_le32(data);
- chip->corb.buf[wp * 2 + 1] = cpu_to_le32(extdata);
- lola_writew(chip, BAR0, CORBWP, wp);
- chip->rirb.cmds++;
- smp_wmb();
- ret = 0;
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return ret;
-}
-
-static void lola_queue_unsol_event(struct lola *chip, unsigned int res,
- unsigned int res_ex)
-{
- lola_update_ext_clock_freq(chip, res);
-}
-
-/* retrieve RIRB entry - called from interrupt handler */
-static void lola_update_rirb(struct lola *chip)
-{
- unsigned int rp, wp;
- u32 res, res_ex;
-
- wp = lola_readw(chip, BAR0, RIRBWP);
- if (wp == chip->rirb.wp)
- return;
- chip->rirb.wp = wp;
-
- while (chip->rirb.rp != wp) {
- chip->rirb.rp++;
- chip->rirb.rp %= LOLA_CORB_ENTRIES;
-
- rp = chip->rirb.rp << 1; /* an RIRB entry is 8-bytes */
- res_ex = le32_to_cpu(chip->rirb.buf[rp + 1]);
- res = le32_to_cpu(chip->rirb.buf[rp]);
- if (res_ex & LOLA_RIRB_EX_UNSOL_EV)
- lola_queue_unsol_event(chip, res, res_ex);
- else if (chip->rirb.cmds) {
- chip->res = res;
- chip->res_ex = res_ex;
- smp_wmb();
- chip->rirb.cmds--;
- }
- }
-}
-
-static int rirb_get_response(struct lola *chip, unsigned int *val,
- unsigned int *extval)
-{
- unsigned long timeout;
-
- again:
- timeout = jiffies + msecs_to_jiffies(1000);
- for (;;) {
- if (chip->polling_mode) {
- spin_lock_irq(&chip->reg_lock);
- lola_update_rirb(chip);
- spin_unlock_irq(&chip->reg_lock);
- }
- if (!chip->rirb.cmds) {
- *val = chip->res;
- if (extval)
- *extval = chip->res_ex;
- verbose_debug("get_response: %x, %x\n",
- chip->res, chip->res_ex);
- if (chip->res_ex & LOLA_RIRB_EX_ERROR) {
- printk(KERN_WARNING SFX "RIRB ERROR: "
- "NID=%x, verb=%x, data=%x, ext=%x\n",
- chip->last_cmd_nid,
- chip->last_verb, chip->last_data,
- chip->last_extdata);
- return -EIO;
- }
- return 0;
- }
- if (time_after(jiffies, timeout))
- break;
- udelay(20);
- cond_resched();
- }
- printk(KERN_WARNING SFX "RIRB response error\n");
- if (!chip->polling_mode) {
- printk(KERN_WARNING SFX "switching to polling mode\n");
- chip->polling_mode = 1;
- goto again;
- }
- return -EIO;
-}
-
-/* aynchronous write of a codec verb with data */
-int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb,
- unsigned int data, unsigned int extdata)
-{
- verbose_debug("codec_write NID=%x, verb=%x, data=%x, ext=%x\n",
- nid, verb, data, extdata);
- return corb_send_verb(chip, nid, verb, data, extdata);
-}
-
-/* write a codec verb with data and read the returned status */
-int lola_codec_read(struct lola *chip, unsigned int nid, unsigned int verb,
- unsigned int data, unsigned int extdata,
- unsigned int *val, unsigned int *extval)
-{
- int err;
-
- verbose_debug("codec_read NID=%x, verb=%x, data=%x, ext=%x\n",
- nid, verb, data, extdata);
- err = corb_send_verb(chip, nid, verb, data, extdata);
- if (err < 0)
- return err;
- err = rirb_get_response(chip, val, extval);
- return err;
-}
-
-/* flush all pending codec writes */
-int lola_codec_flush(struct lola *chip)
-{
- unsigned int tmp;
- return rirb_get_response(chip, &tmp, NULL);
-}
-
-/*
- * interrupt handler
- */
-static irqreturn_t lola_interrupt(int irq, void *dev_id)
-{
- struct lola *chip = dev_id;
- unsigned int notify_ins, notify_outs, error_ins, error_outs;
- int handled = 0;
- int i;
-
- notify_ins = notify_outs = error_ins = error_outs = 0;
- spin_lock(&chip->reg_lock);
- for (;;) {
- unsigned int status, in_sts, out_sts;
- unsigned int reg;
-
- status = lola_readl(chip, BAR1, DINTSTS);
- if (!status || status == -1)
- break;
-
- in_sts = lola_readl(chip, BAR1, DIINTSTS);
- out_sts = lola_readl(chip, BAR1, DOINTSTS);
-
- /* clear Input Interrupts */
- for (i = 0; in_sts && i < chip->pcm[CAPT].num_streams; i++) {
- if (!(in_sts & (1 << i)))
- continue;
- in_sts &= ~(1 << i);
- reg = lola_dsd_read(chip, i, STS);
- if (reg & LOLA_DSD_STS_DESE) /* error */
- error_ins |= (1 << i);
- if (reg & LOLA_DSD_STS_BCIS) /* notify */
- notify_ins |= (1 << i);
- /* clear */
- lola_dsd_write(chip, i, STS, reg);
- }
-
- /* clear Output Interrupts */
- for (i = 0; out_sts && i < chip->pcm[PLAY].num_streams; i++) {
- if (!(out_sts & (1 << i)))
- continue;
- out_sts &= ~(1 << i);
- reg = lola_dsd_read(chip, i + MAX_STREAM_IN_COUNT, STS);
- if (reg & LOLA_DSD_STS_DESE) /* error */
- error_outs |= (1 << i);
- if (reg & LOLA_DSD_STS_BCIS) /* notify */
- notify_outs |= (1 << i);
- lola_dsd_write(chip, i + MAX_STREAM_IN_COUNT, STS, reg);
- }
-
- if (status & LOLA_DINT_CTRL) {
- unsigned char rbsts; /* ring status is byte access */
- rbsts = lola_readb(chip, BAR0, RIRBSTS);
- rbsts &= LOLA_RIRB_INT_MASK;
- if (rbsts)
- lola_writeb(chip, BAR0, RIRBSTS, rbsts);
- rbsts = lola_readb(chip, BAR0, CORBSTS);
- rbsts &= LOLA_CORB_INT_MASK;
- if (rbsts)
- lola_writeb(chip, BAR0, CORBSTS, rbsts);
-
- lola_update_rirb(chip);
- }
-
- if (status & (LOLA_DINT_FIFOERR | LOLA_DINT_MUERR)) {
- /* clear global fifo error interrupt */
- lola_writel(chip, BAR1, DINTSTS,
- (status & (LOLA_DINT_FIFOERR | LOLA_DINT_MUERR)));
- }
- handled = 1;
- }
- spin_unlock(&chip->reg_lock);
-
- lola_pcm_update(chip, &chip->pcm[CAPT], notify_ins);
- lola_pcm_update(chip, &chip->pcm[PLAY], notify_outs);
-
- return IRQ_RETVAL(handled);
-}
-
-
-/*
- * controller
- */
-static int reset_controller(struct lola *chip)
-{
- unsigned int gctl = lola_readl(chip, BAR0, GCTL);
- unsigned long end_time;
-
- if (gctl) {
- /* to be sure */
- lola_writel(chip, BAR1, BOARD_MODE, 0);
- return 0;
- }
-
- chip->cold_reset = 1;
- lola_writel(chip, BAR0, GCTL, LOLA_GCTL_RESET);
- end_time = jiffies + msecs_to_jiffies(200);
- do {
- msleep(1);
- gctl = lola_readl(chip, BAR0, GCTL);
- if (gctl)
- break;
- } while (time_before(jiffies, end_time));
- if (!gctl) {
- printk(KERN_ERR SFX "cannot reset controller\n");
- return -EIO;
- }
- return 0;
-}
-
-static void lola_irq_enable(struct lola *chip)
-{
- unsigned int val;
-
- /* enalbe all I/O streams */
- val = (1 << chip->pcm[PLAY].num_streams) - 1;
- lola_writel(chip, BAR1, DOINTCTL, val);
- val = (1 << chip->pcm[CAPT].num_streams) - 1;
- lola_writel(chip, BAR1, DIINTCTL, val);
-
- /* enable global irqs */
- val = LOLA_DINT_GLOBAL | LOLA_DINT_CTRL | LOLA_DINT_FIFOERR |
- LOLA_DINT_MUERR;
- lola_writel(chip, BAR1, DINTCTL, val);
-}
-
-static void lola_irq_disable(struct lola *chip)
-{
- lola_writel(chip, BAR1, DINTCTL, 0);
- lola_writel(chip, BAR1, DIINTCTL, 0);
- lola_writel(chip, BAR1, DOINTCTL, 0);
-}
-
-static int setup_corb_rirb(struct lola *chip)
-{
- int err;
- unsigned char tmp;
- unsigned long end_time;
-
- err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- PAGE_SIZE, &chip->rb);
- if (err < 0)
- return err;
-
- chip->corb.addr = chip->rb.addr;
- chip->corb.buf = (u32 *)chip->rb.area;
- chip->rirb.addr = chip->rb.addr + 2048;
- chip->rirb.buf = (u32 *)(chip->rb.area + 2048);
-
- /* disable ringbuffer DMAs */
- lola_writeb(chip, BAR0, RIRBCTL, 0);
- lola_writeb(chip, BAR0, CORBCTL, 0);
-
- end_time = jiffies + msecs_to_jiffies(200);
- do {
- if (!lola_readb(chip, BAR0, RIRBCTL) &&
- !lola_readb(chip, BAR0, CORBCTL))
- break;
- msleep(1);
- } while (time_before(jiffies, end_time));
-
- /* CORB set up */
- lola_writel(chip, BAR0, CORBLBASE, (u32)chip->corb.addr);
- lola_writel(chip, BAR0, CORBUBASE, upper_32_bits(chip->corb.addr));
- /* set the corb size to 256 entries */
- lola_writeb(chip, BAR0, CORBSIZE, 0x02);
- /* set the corb write pointer to 0 */
- lola_writew(chip, BAR0, CORBWP, 0);
- /* reset the corb hw read pointer */
- lola_writew(chip, BAR0, CORBRP, LOLA_RBRWP_CLR);
- /* enable corb dma */
- lola_writeb(chip, BAR0, CORBCTL, LOLA_RBCTL_DMA_EN);
- /* clear flags if set */
- tmp = lola_readb(chip, BAR0, CORBSTS) & LOLA_CORB_INT_MASK;
- if (tmp)
- lola_writeb(chip, BAR0, CORBSTS, tmp);
- chip->corb.wp = 0;
-
- /* RIRB set up */
- lola_writel(chip, BAR0, RIRBLBASE, (u32)chip->rirb.addr);
- lola_writel(chip, BAR0, RIRBUBASE, upper_32_bits(chip->rirb.addr));
- /* set the rirb size to 256 entries */
- lola_writeb(chip, BAR0, RIRBSIZE, 0x02);
- /* reset the rirb hw write pointer */
- lola_writew(chip, BAR0, RIRBWP, LOLA_RBRWP_CLR);
- /* set N=1, get RIRB response interrupt for new entry */
- lola_writew(chip, BAR0, RINTCNT, 1);
- /* enable rirb dma and response irq */
- lola_writeb(chip, BAR0, RIRBCTL, LOLA_RBCTL_DMA_EN | LOLA_RBCTL_IRQ_EN);
- /* clear flags if set */
- tmp = lola_readb(chip, BAR0, RIRBSTS) & LOLA_RIRB_INT_MASK;
- if (tmp)
- lola_writeb(chip, BAR0, RIRBSTS, tmp);
- chip->rirb.rp = chip->rirb.cmds = 0;
-
- return 0;
-}
-
-static void stop_corb_rirb(struct lola *chip)
-{
- /* disable ringbuffer DMAs */
- lola_writeb(chip, BAR0, RIRBCTL, 0);
- lola_writeb(chip, BAR0, CORBCTL, 0);
-}
-
-static void lola_reset_setups(struct lola *chip)
-{
- /* update the granularity */
- lola_set_granularity(chip, chip->granularity, true);
- /* update the sample clock */
- lola_set_clock_index(chip, chip->clock.cur_index);
- /* enable unsolicited events of the clock widget */
- lola_enable_clock_events(chip);
- /* update the analog gains */
- lola_setup_all_analog_gains(chip, CAPT, false); /* input, update */
- /* update SRC configuration if applicable */
- lola_set_src_config(chip, chip->input_src_mask, false);
- /* update the analog outputs */
- lola_setup_all_analog_gains(chip, PLAY, false); /* output, update */
-}
-
-static int __devinit lola_parse_tree(struct lola *chip)
-{
- unsigned int val;
- int nid, err;
-
- err = lola_read_param(chip, 0, LOLA_PAR_VENDOR_ID, &val);
- if (err < 0) {
- printk(KERN_ERR SFX "Can't read VENDOR_ID\n");
- return err;
- }
- val >>= 16;
- if (val != 0x1369) {
- printk(KERN_ERR SFX "Unknown codec vendor 0x%x\n", val);
- return -EINVAL;
- }
-
- err = lola_read_param(chip, 1, LOLA_PAR_FUNCTION_TYPE, &val);
- if (err < 0) {
- printk(KERN_ERR SFX "Can't read FUNCTION_TYPE for 0x%x\n", nid);
- return err;
- }
- if (val != 1) {
- printk(KERN_ERR SFX "Unknown function type %d\n", val);
- return -EINVAL;
- }
-
- err = lola_read_param(chip, 1, LOLA_PAR_SPECIFIC_CAPS, &val);
- if (err < 0) {
- printk(KERN_ERR SFX "Can't read SPECCAPS\n");
- return err;
- }
- chip->lola_caps = val;
- chip->pin[CAPT].num_pins = LOLA_AFG_INPUT_PIN_COUNT(chip->lola_caps);
- chip->pin[PLAY].num_pins = LOLA_AFG_OUTPUT_PIN_COUNT(chip->lola_caps);
- snd_printdd(SFX "speccaps=0x%x, pins in=%d, out=%d\n",
- chip->lola_caps,
- chip->pin[CAPT].num_pins, chip->pin[PLAY].num_pins);
-
- if (chip->pin[CAPT].num_pins > MAX_AUDIO_INOUT_COUNT ||
- chip->pin[PLAY].num_pins > MAX_AUDIO_INOUT_COUNT) {
- printk(KERN_ERR SFX "Invalid Lola-spec caps 0x%x\n", val);
- return -EINVAL;
- }
-
- nid = 0x02;
- err = lola_init_pcm(chip, CAPT, &nid);
- if (err < 0)
- return err;
- err = lola_init_pcm(chip, PLAY, &nid);
- if (err < 0)
- return err;
-
- err = lola_init_pins(chip, CAPT, &nid);
- if (err < 0)
- return err;
- err = lola_init_pins(chip, PLAY, &nid);
- if (err < 0)
- return err;
-
- if (LOLA_AFG_CLOCK_WIDGET_PRESENT(chip->lola_caps)) {
- err = lola_init_clock_widget(chip, nid);
- if (err < 0)
- return err;
- nid++;
- }
- if (LOLA_AFG_MIXER_WIDGET_PRESENT(chip->lola_caps)) {
- err = lola_init_mixer_widget(chip, nid);
- if (err < 0)
- return err;
- nid++;
- }
-
- /* enable unsolicited events of the clock widget */
- err = lola_enable_clock_events(chip);
- if (err < 0)
- return err;
-
- /* if last ResetController was not a ColdReset, we don't know
- * the state of the card; initialize here again
- */
- if (!chip->cold_reset) {
- lola_reset_setups(chip);
- chip->cold_reset = 1;
- } else {
- /* set the granularity if it is not the default */
- if (chip->granularity != LOLA_GRANULARITY_MIN)
- lola_set_granularity(chip, chip->granularity, true);
- }
-
- return 0;
-}
-
-static void lola_stop_hw(struct lola *chip)
-{
- stop_corb_rirb(chip);
- lola_irq_disable(chip);
-}
-
-static void lola_free(struct lola *chip)
-{
- if (chip->initialized)
- lola_stop_hw(chip);
- lola_free_pcm(chip);
- lola_free_mixer(chip);
- if (chip->irq >= 0)
- free_irq(chip->irq, (void *)chip);
- if (chip->bar[0].remap_addr)
- iounmap(chip->bar[0].remap_addr);
- if (chip->bar[1].remap_addr)
- iounmap(chip->bar[1].remap_addr);
- if (chip->rb.area)
- snd_dma_free_pages(&chip->rb);
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
- kfree(chip);
-}
-
-static int lola_dev_free(struct snd_device *device)
-{
- lola_free(device->device_data);
- return 0;
-}
-
-static int __devinit lola_create(struct snd_card *card, struct pci_dev *pci,
- int dev, struct lola **rchip)
-{
- struct lola *chip;
- int err;
- unsigned int dever;
- static struct snd_device_ops ops = {
- .dev_free = lola_dev_free,
- };
-
- *rchip = NULL;
-
- err = pci_enable_device(pci);
- if (err < 0)
- return err;
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (!chip) {
- snd_printk(KERN_ERR SFX "cannot allocate chip\n");
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- spin_lock_init(&chip->reg_lock);
- mutex_init(&chip->open_mutex);
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
-
- chip->granularity = granularity[dev];
- switch (chip->granularity) {
- case 8:
- chip->sample_rate_max = 48000;
- break;
- case 16:
- chip->sample_rate_max = 96000;
- break;
- case 32:
- chip->sample_rate_max = 192000;
- break;
- default:
- snd_printk(KERN_WARNING SFX
- "Invalid granularity %d, reset to %d\n",
- chip->granularity, LOLA_GRANULARITY_MAX);
- chip->granularity = LOLA_GRANULARITY_MAX;
- chip->sample_rate_max = 192000;
- break;
- }
- chip->sample_rate_min = sample_rate_min[dev];
- if (chip->sample_rate_min > chip->sample_rate_max) {
- snd_printk(KERN_WARNING SFX
- "Invalid sample_rate_min %d, reset to 16000\n",
- chip->sample_rate_min);
- chip->sample_rate_min = 16000;
- }
-
- err = pci_request_regions(pci, DRVNAME);
- if (err < 0) {
- kfree(chip);
- pci_disable_device(pci);
- return err;
- }
-
- chip->bar[0].addr = pci_resource_start(pci, 0);
- chip->bar[0].remap_addr = pci_ioremap_bar(pci, 0);
- chip->bar[1].addr = pci_resource_start(pci, 2);
- chip->bar[1].remap_addr = pci_ioremap_bar(pci, 2);
- if (!chip->bar[0].remap_addr || !chip->bar[1].remap_addr) {
- snd_printk(KERN_ERR SFX "ioremap error\n");
- err = -ENXIO;
- goto errout;
- }
-
- pci_set_master(pci);
-
- err = reset_controller(chip);
- if (err < 0)
- goto errout;
-
- if (request_irq(pci->irq, lola_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
- printk(KERN_ERR SFX "unable to grab IRQ %d\n", pci->irq);
- err = -EBUSY;
- goto errout;
- }
- chip->irq = pci->irq;
- synchronize_irq(chip->irq);
-
- dever = lola_readl(chip, BAR1, DEVER);
- chip->pcm[CAPT].num_streams = (dever >> 0) & 0x3ff;
- chip->pcm[PLAY].num_streams = (dever >> 10) & 0x3ff;
- chip->version = (dever >> 24) & 0xff;
- snd_printdd(SFX "streams in=%d, out=%d, version=0x%x\n",
- chip->pcm[CAPT].num_streams, chip->pcm[PLAY].num_streams,
- chip->version);
-
- /* Test LOLA_BAR1_DEVER */
- if (chip->pcm[CAPT].num_streams > MAX_STREAM_IN_COUNT ||
- chip->pcm[PLAY].num_streams > MAX_STREAM_OUT_COUNT ||
- (!chip->pcm[CAPT].num_streams &&
- !chip->pcm[PLAY].num_streams)) {
- printk(KERN_ERR SFX "invalid DEVER = %x\n", dever);
- err = -EINVAL;
- goto errout;
- }
-
- err = setup_corb_rirb(chip);
- if (err < 0)
- goto errout;
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
- if (err < 0) {
- snd_printk(KERN_ERR SFX "Error creating device [card]!\n");
- goto errout;
- }
-
- strcpy(card->driver, "Lola");
- strlcpy(card->shortname, "Digigram Lola", sizeof(card->shortname));
- snprintf(card->longname, sizeof(card->longname),
- "%s at 0x%lx irq %i",
- card->shortname, chip->bar[0].addr, chip->irq);
- strcpy(card->mixername, card->shortname);
-
- lola_irq_enable(chip);
-
- chip->initialized = 1;
- *rchip = chip;
- return 0;
-
- errout:
- lola_free(chip);
- return err;
-}
-
-static int __devinit lola_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct lola *chip;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0) {
- snd_printk(KERN_ERR SFX "Error creating card!\n");
- return err;
- }
-
- snd_card_set_dev(card, &pci->dev);
-
- err = lola_create(card, pci, dev, &chip);
- if (err < 0)
- goto out_free;
- card->private_data = chip;
-
- err = lola_parse_tree(chip);
- if (err < 0)
- goto out_free;
-
- err = lola_create_pcm(chip);
- if (err < 0)
- goto out_free;
-
- err = lola_create_mixer(chip);
- if (err < 0)
- goto out_free;
-
- lola_proc_debug_new(chip);
-
- err = snd_card_register(card);
- if (err < 0)
- goto out_free;
-
- pci_set_drvdata(pci, card);
- dev++;
- return err;
-out_free:
- snd_card_free(card);
- return err;
-}
-
-static void __devexit lola_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-/* PCI IDs */
-static DEFINE_PCI_DEVICE_TABLE(lola_ids) = {
- { PCI_VDEVICE(DIGIGRAM, 0x0001) },
- { 0, }
-};
-MODULE_DEVICE_TABLE(pci, lola_ids);
-
-/* pci_driver definition */
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = lola_ids,
- .probe = lola_probe,
- .remove = __devexit_p(lola_remove),
-};
-
-static int __init alsa_card_lola_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_lola_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_lola_init)
-module_exit(alsa_card_lola_exit)
diff --git a/ANDROID_3.4.5/sound/pci/lola/lola.h b/ANDROID_3.4.5/sound/pci/lola/lola.h
deleted file mode 100644
index f0b10005..00000000
--- a/ANDROID_3.4.5/sound/pci/lola/lola.h
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * Support for Digigram Lola PCI-e boards
- *
- * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef _LOLA_H
-#define _LOLA_H
-
-#define DRVNAME "snd-lola"
-#define SFX DRVNAME ": "
-
-/*
- * Lola HD Audio Registers BAR0
- */
-#define LOLA_BAR0_GCAP 0x00
-#define LOLA_BAR0_VMIN 0x02
-#define LOLA_BAR0_VMAJ 0x03
-#define LOLA_BAR0_OUTPAY 0x04
-#define LOLA_BAR0_INPAY 0x06
-#define LOLA_BAR0_GCTL 0x08
-#define LOLA_BAR0_WAKEEN 0x0c
-#define LOLA_BAR0_STATESTS 0x0e
-#define LOLA_BAR0_GSTS 0x10
-#define LOLA_BAR0_OUTSTRMPAY 0x18
-#define LOLA_BAR0_INSTRMPAY 0x1a
-#define LOLA_BAR0_INTCTL 0x20
-#define LOLA_BAR0_INTSTS 0x24
-#define LOLA_BAR0_WALCLK 0x30
-#define LOLA_BAR0_SSYNC 0x38
-
-#define LOLA_BAR0_CORBLBASE 0x40
-#define LOLA_BAR0_CORBUBASE 0x44
-#define LOLA_BAR0_CORBWP 0x48 /* no ULONG access */
-#define LOLA_BAR0_CORBRP 0x4a /* no ULONG access */
-#define LOLA_BAR0_CORBCTL 0x4c /* no ULONG access */
-#define LOLA_BAR0_CORBSTS 0x4d /* UCHAR access only */
-#define LOLA_BAR0_CORBSIZE 0x4e /* no ULONG access */
-
-#define LOLA_BAR0_RIRBLBASE 0x50
-#define LOLA_BAR0_RIRBUBASE 0x54
-#define LOLA_BAR0_RIRBWP 0x58
-#define LOLA_BAR0_RINTCNT 0x5a /* no ULONG access */
-#define LOLA_BAR0_RIRBCTL 0x5c
-#define LOLA_BAR0_RIRBSTS 0x5d /* UCHAR access only */
-#define LOLA_BAR0_RIRBSIZE 0x5e /* no ULONG access */
-
-#define LOLA_BAR0_ICW 0x60
-#define LOLA_BAR0_IRR 0x64
-#define LOLA_BAR0_ICS 0x68
-#define LOLA_BAR0_DPLBASE 0x70
-#define LOLA_BAR0_DPUBASE 0x74
-
-/* stream register offsets from stream base 0x80 */
-#define LOLA_BAR0_SD0_OFFSET 0x80
-#define LOLA_REG0_SD_CTL 0x00
-#define LOLA_REG0_SD_STS 0x03
-#define LOLA_REG0_SD_LPIB 0x04
-#define LOLA_REG0_SD_CBL 0x08
-#define LOLA_REG0_SD_LVI 0x0c
-#define LOLA_REG0_SD_FIFOW 0x0e
-#define LOLA_REG0_SD_FIFOSIZE 0x10
-#define LOLA_REG0_SD_FORMAT 0x12
-#define LOLA_REG0_SD_BDLPL 0x18
-#define LOLA_REG0_SD_BDLPU 0x1c
-
-/*
- * Lola Digigram Registers BAR1
- */
-#define LOLA_BAR1_FPGAVER 0x00
-#define LOLA_BAR1_DEVER 0x04
-#define LOLA_BAR1_UCBMV 0x08
-#define LOLA_BAR1_JTAG 0x0c
-#define LOLA_BAR1_UARTRX 0x10
-#define LOLA_BAR1_UARTTX 0x14
-#define LOLA_BAR1_UARTCR 0x18
-#define LOLA_BAR1_NVRAMVER 0x1c
-#define LOLA_BAR1_CTRLSPI 0x20
-#define LOLA_BAR1_DSPI 0x24
-#define LOLA_BAR1_AISPI 0x28
-#define LOLA_BAR1_GRAN 0x2c
-
-#define LOLA_BAR1_DINTCTL 0x80
-#define LOLA_BAR1_DIINTCTL 0x84
-#define LOLA_BAR1_DOINTCTL 0x88
-#define LOLA_BAR1_LRC 0x90
-#define LOLA_BAR1_DINTSTS 0x94
-#define LOLA_BAR1_DIINTSTS 0x98
-#define LOLA_BAR1_DOINTSTS 0x9c
-
-#define LOLA_BAR1_DSD0_OFFSET 0xa0
-#define LOLA_BAR1_DSD_SIZE 0x18
-
-#define LOLA_BAR1_DSDnSTS 0x00
-#define LOLA_BAR1_DSDnLPIB 0x04
-#define LOLA_BAR1_DSDnCTL 0x08
-#define LOLA_BAR1_DSDnLVI 0x0c
-#define LOLA_BAR1_DSDnBDPL 0x10
-#define LOLA_BAR1_DSDnBDPU 0x14
-
-#define LOLA_BAR1_SSYNC 0x03e8
-
-#define LOLA_BAR1_BOARD_CTRL 0x0f00
-#define LOLA_BAR1_BOARD_MODE 0x0f02
-
-#define LOLA_BAR1_SOURCE_GAIN_ENABLE 0x1000
-#define LOLA_BAR1_DEST00_MIX_GAIN_ENABLE 0x1004
-#define LOLA_BAR1_DEST31_MIX_GAIN_ENABLE 0x1080
-#define LOLA_BAR1_SOURCE00_01_GAIN 0x1084
-#define LOLA_BAR1_SOURCE30_31_GAIN 0x10c0
-#define LOLA_BAR1_SOURCE_GAIN(src) \
- (LOLA_BAR1_SOURCE00_01_GAIN + (src) * 2)
-#define LOLA_BAR1_DEST00_MIX00_01_GAIN 0x10c4
-#define LOLA_BAR1_DEST00_MIX30_31_GAIN 0x1100
-#define LOLA_BAR1_DEST01_MIX00_01_GAIN 0x1104
-#define LOLA_BAR1_DEST01_MIX30_31_GAIN 0x1140
-#define LOLA_BAR1_DEST31_MIX00_01_GAIN 0x1884
-#define LOLA_BAR1_DEST31_MIX30_31_GAIN 0x18c0
-#define LOLA_BAR1_MIX_GAIN(dest, mix) \
- (LOLA_BAR1_DEST00_MIX00_01_GAIN + (dest) * 0x40 + (mix) * 2)
-#define LOLA_BAR1_ANALOG_CLIP_IN 0x18c4
-#define LOLA_BAR1_PEAKMETERS_SOURCE00_01 0x18c8
-#define LOLA_BAR1_PEAKMETERS_SOURCE30_31 0x1904
-#define LOLA_BAR1_PEAKMETERS_SOURCE(src) \
- (LOLA_BAR1_PEAKMETERS_SOURCE00_01 + (src) * 2)
-#define LOLA_BAR1_PEAKMETERS_DEST00_01 0x1908
-#define LOLA_BAR1_PEAKMETERS_DEST30_31 0x1944
-#define LOLA_BAR1_PEAKMETERS_DEST(dest) \
- (LOLA_BAR1_PEAKMETERS_DEST00_01 + (dest) * 2)
-#define LOLA_BAR1_PEAKMETERS_AGC00_01 0x1948
-#define LOLA_BAR1_PEAKMETERS_AGC14_15 0x1964
-#define LOLA_BAR1_PEAKMETERS_AGC(x) \
- (LOLA_BAR1_PEAKMETERS_AGC00_01 + (x) * 2)
-
-/* GCTL reset bit */
-#define LOLA_GCTL_RESET (1 << 0)
-/* GCTL unsolicited response enable bit */
-#define LOLA_GCTL_UREN (1 << 8)
-
-/* CORB/RIRB control, read/write pointer */
-#define LOLA_RBCTL_DMA_EN 0x02 /* enable DMA */
-#define LOLA_RBCTL_IRQ_EN 0x01 /* enable IRQ */
-#define LOLA_RBRWP_CLR 0x8000 /* read/write pointer clear */
-
-#define LOLA_RIRB_EX_UNSOL_EV 0x40000000
-#define LOLA_RIRB_EX_ERROR 0x80000000
-
-/* CORB int mask: CMEI[0] */
-#define LOLA_CORB_INT_CMEI 0x01
-#define LOLA_CORB_INT_MASK LOLA_CORB_INT_CMEI
-
-/* RIRB int mask: overrun[2], response[0] */
-#define LOLA_RIRB_INT_RESPONSE 0x01
-#define LOLA_RIRB_INT_OVERRUN 0x04
-#define LOLA_RIRB_INT_MASK (LOLA_RIRB_INT_RESPONSE | LOLA_RIRB_INT_OVERRUN)
-
-/* DINTCTL and DINTSTS */
-#define LOLA_DINT_GLOBAL 0x80000000 /* global interrupt enable bit */
-#define LOLA_DINT_CTRL 0x40000000 /* controller interrupt enable bit */
-#define LOLA_DINT_FIFOERR 0x20000000 /* global fifo error enable bit */
-#define LOLA_DINT_MUERR 0x10000000 /* global microcontroller underrun error */
-
-/* DSDnCTL bits */
-#define LOLA_DSD_CTL_SRST 0x01 /* stream reset bit */
-#define LOLA_DSD_CTL_SRUN 0x02 /* stream DMA start bit */
-#define LOLA_DSD_CTL_IOCE 0x04 /* interrupt on completion enable */
-#define LOLA_DSD_CTL_DEIE 0x10 /* descriptor error interrupt enable */
-#define LOLA_DSD_CTL_VLRCV 0x20 /* valid LRCountValue information in bits 8..31 */
-#define LOLA_LRC_MASK 0xffffff00
-
-/* DSDnSTS */
-#define LOLA_DSD_STS_BCIS 0x04 /* buffer completion interrupt status */
-#define LOLA_DSD_STS_DESE 0x10 /* descriptor error interrupt */
-#define LOLA_DSD_STS_FIFORDY 0x20 /* fifo ready */
-
-#define LOLA_CORB_ENTRIES 256
-
-#define MAX_STREAM_IN_COUNT 16
-#define MAX_STREAM_OUT_COUNT 16
-#define MAX_STREAM_COUNT 16
-#define MAX_PINS MAX_STREAM_COUNT
-#define MAX_STREAM_BUFFER_COUNT 16
-#define MAX_AUDIO_INOUT_COUNT 16
-
-#define LOLA_CLOCK_TYPE_INTERNAL 0
-#define LOLA_CLOCK_TYPE_AES 1
-#define LOLA_CLOCK_TYPE_AES_SYNC 2
-#define LOLA_CLOCK_TYPE_WORDCLOCK 3
-#define LOLA_CLOCK_TYPE_ETHERSOUND 4
-#define LOLA_CLOCK_TYPE_VIDEO 5
-
-#define LOLA_CLOCK_FORMAT_NONE 0
-#define LOLA_CLOCK_FORMAT_NTSC 1
-#define LOLA_CLOCK_FORMAT_PAL 2
-
-#define MAX_SAMPLE_CLOCK_COUNT 48
-
-/* parameters used with mixer widget's mixer capabilities */
-#define LOLA_PEAK_METER_CAN_AGC_MASK 1
-#define LOLA_PEAK_METER_CAN_ANALOG_CLIP_MASK 2
-
-struct lola_bar {
- unsigned long addr;
- void __iomem *remap_addr;
-};
-
-/* CORB/RIRB */
-struct lola_rb {
- u32 *buf; /* CORB/RIRB buffer, 8 byte per each entry */
- dma_addr_t addr; /* physical address of CORB/RIRB buffer */
- unsigned short rp, wp; /* read/write pointers */
- int cmds; /* number of pending requests */
-};
-
-/* Pin widget setup */
-struct lola_pin {
- unsigned int nid;
- bool is_analog;
- unsigned int amp_mute;
- unsigned int amp_step_size;
- unsigned int amp_num_steps;
- unsigned int amp_offset;
- unsigned int max_level;
- unsigned int config_default_reg;
- unsigned int fixed_gain_list_len;
- unsigned int cur_gain_step;
-};
-
-struct lola_pin_array {
- unsigned int num_pins;
- unsigned int num_analog_pins;
- struct lola_pin pins[MAX_PINS];
-};
-
-/* Clock widget setup */
-struct lola_sample_clock {
- unsigned int type;
- unsigned int format;
- unsigned int freq;
-};
-
-struct lola_clock_widget {
- unsigned int nid;
- unsigned int items;
- unsigned int cur_index;
- unsigned int cur_freq;
- bool cur_valid;
- struct lola_sample_clock sample_clock[MAX_SAMPLE_CLOCK_COUNT];
- unsigned int idx_lookup[MAX_SAMPLE_CLOCK_COUNT];
-};
-
-#define LOLA_MIXER_DIM 32
-struct lola_mixer_array {
- u32 src_gain_enable;
- u32 dest_mix_gain_enable[LOLA_MIXER_DIM];
- u16 src_gain[LOLA_MIXER_DIM];
- u16 dest_mix_gain[LOLA_MIXER_DIM][LOLA_MIXER_DIM];
-};
-
-/* Mixer widget setup */
-struct lola_mixer_widget {
- unsigned int nid;
- unsigned int caps;
- struct lola_mixer_array __user *array;
- struct lola_mixer_array *array_saved;
- unsigned int src_stream_outs;
- unsigned int src_phys_ins;
- unsigned int dest_stream_ins;
- unsigned int dest_phys_outs;
- unsigned int src_stream_out_ofs;
- unsigned int dest_phys_out_ofs;
- unsigned int src_mask;
- unsigned int dest_mask;
-};
-
-/* Audio stream */
-struct lola_stream {
- unsigned int nid; /* audio widget NID */
- unsigned int index; /* array index */
- unsigned int dsd; /* DSD index */
- bool can_float;
- struct snd_pcm_substream *substream; /* assigned PCM substream */
- struct lola_stream *master; /* master stream (for multi-channel) */
-
- /* buffer setup */
- unsigned int bufsize;
- unsigned int period_bytes;
- unsigned int frags;
-
- /* format + channel setup */
- unsigned int format_verb;
-
- /* flags */
- unsigned int opened:1;
- unsigned int prepared:1;
- unsigned int paused:1;
- unsigned int running:1;
-};
-
-#define PLAY SNDRV_PCM_STREAM_PLAYBACK
-#define CAPT SNDRV_PCM_STREAM_CAPTURE
-
-struct lola_pcm {
- unsigned int num_streams;
- struct snd_dma_buffer bdl; /* BDL buffer */
- struct lola_stream streams[MAX_STREAM_COUNT];
-};
-
-/* card instance */
-struct lola {
- struct snd_card *card;
- struct pci_dev *pci;
-
- /* pci resources */
- struct lola_bar bar[2];
- int irq;
-
- /* locks */
- spinlock_t reg_lock;
- struct mutex open_mutex;
-
- /* CORB/RIRB */
- struct lola_rb corb;
- struct lola_rb rirb;
- unsigned int res, res_ex; /* last read values */
- /* last command (for debugging) */
- unsigned int last_cmd_nid, last_verb, last_data, last_extdata;
-
- /* CORB/RIRB buffers */
- struct snd_dma_buffer rb;
-
- /* unsolicited events */
- unsigned int last_unsol_res;
-
- /* streams */
- struct lola_pcm pcm[2];
-
- /* input src */
- unsigned int input_src_caps_mask;
- unsigned int input_src_mask;
-
- /* pins */
- struct lola_pin_array pin[2];
-
- /* clock */
- struct lola_clock_widget clock;
- int ref_count_rate;
- unsigned int sample_rate;
-
- /* mixer */
- struct lola_mixer_widget mixer;
-
- /* hw info */
- unsigned int version;
- unsigned int lola_caps;
-
- /* parameters */
- unsigned int granularity;
- unsigned int sample_rate_min;
- unsigned int sample_rate_max;
-
- /* flags */
- unsigned int initialized:1;
- unsigned int cold_reset:1;
- unsigned int polling_mode:1;
-
- /* for debugging */
- unsigned int debug_res;
- unsigned int debug_res_ex;
-};
-
-#define BAR0 0
-#define BAR1 1
-
-/* Helper macros */
-#define lola_readl(chip, idx, name) \
- readl((chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
-#define lola_readw(chip, idx, name) \
- readw((chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
-#define lola_readb(chip, idx, name) \
- readb((chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
-#define lola_writel(chip, idx, name, val) \
- writel((val), (chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
-#define lola_writew(chip, idx, name, val) \
- writew((val), (chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
-#define lola_writeb(chip, idx, name, val) \
- writeb((val), (chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
-
-#define lola_dsd_read(chip, dsd, name) \
- readl((chip)->bar[BAR1].remap_addr + LOLA_BAR1_DSD0_OFFSET + \
- (LOLA_BAR1_DSD_SIZE * (dsd)) + LOLA_BAR1_DSDn##name)
-#define lola_dsd_write(chip, dsd, name, val) \
- writel((val), (chip)->bar[BAR1].remap_addr + LOLA_BAR1_DSD0_OFFSET + \
- (LOLA_BAR1_DSD_SIZE * (dsd)) + LOLA_BAR1_DSDn##name)
-
-/* GET verbs HDAudio */
-#define LOLA_VERB_GET_STREAM_FORMAT 0xa00
-#define LOLA_VERB_GET_AMP_GAIN_MUTE 0xb00
-#define LOLA_VERB_PARAMETERS 0xf00
-#define LOLA_VERB_GET_POWER_STATE 0xf05
-#define LOLA_VERB_GET_CONV 0xf06
-#define LOLA_VERB_GET_UNSOLICITED_RESPONSE 0xf08
-#define LOLA_VERB_GET_DIGI_CONVERT_1 0xf0d
-#define LOLA_VERB_GET_CONFIG_DEFAULT 0xf1c
-#define LOLA_VERB_GET_SUBSYSTEM_ID 0xf20
-/* GET verbs Digigram */
-#define LOLA_VERB_GET_FIXED_GAIN 0xfc0
-#define LOLA_VERB_GET_GAIN_SELECT 0xfc1
-#define LOLA_VERB_GET_MAX_LEVEL 0xfc2
-#define LOLA_VERB_GET_CLOCK_LIST 0xfc3
-#define LOLA_VERB_GET_CLOCK_SELECT 0xfc4
-#define LOLA_VERB_GET_CLOCK_STATUS 0xfc5
-
-/* SET verbs HDAudio */
-#define LOLA_VERB_SET_STREAM_FORMAT 0x200
-#define LOLA_VERB_SET_AMP_GAIN_MUTE 0x300
-#define LOLA_VERB_SET_POWER_STATE 0x705
-#define LOLA_VERB_SET_CHANNEL_STREAMID 0x706
-#define LOLA_VERB_SET_UNSOLICITED_ENABLE 0x708
-#define LOLA_VERB_SET_DIGI_CONVERT_1 0x70d
-/* SET verbs Digigram */
-#define LOLA_VERB_SET_GAIN_SELECT 0xf81
-#define LOLA_VERB_SET_CLOCK_SELECT 0xf84
-#define LOLA_VERB_SET_GRANULARITY_STEPS 0xf86
-#define LOLA_VERB_SET_SOURCE_GAIN 0xf87
-#define LOLA_VERB_SET_MIX_GAIN 0xf88
-#define LOLA_VERB_SET_DESTINATION_GAIN 0xf89
-#define LOLA_VERB_SET_SRC 0xf8a
-
-/* Parameter IDs used with LOLA_VERB_PARAMETERS */
-#define LOLA_PAR_VENDOR_ID 0x00
-#define LOLA_PAR_FUNCTION_TYPE 0x05
-#define LOLA_PAR_AUDIO_WIDGET_CAP 0x09
-#define LOLA_PAR_PCM 0x0a
-#define LOLA_PAR_STREAM_FORMATS 0x0b
-#define LOLA_PAR_PIN_CAP 0x0c
-#define LOLA_PAR_AMP_IN_CAP 0x0d
-#define LOLA_PAR_CONNLIST_LEN 0x0e
-#define LOLA_PAR_POWER_STATE 0x0f
-#define LOLA_PAR_GPIO_CAP 0x11
-#define LOLA_PAR_AMP_OUT_CAP 0x12
-#define LOLA_PAR_SPECIFIC_CAPS 0x80
-#define LOLA_PAR_FIXED_GAIN_LIST 0x81
-
-/* extract results of LOLA_PAR_SPECIFIC_CAPS */
-#define LOLA_AFG_MIXER_WIDGET_PRESENT(res) ((res & (1 << 21)) != 0)
-#define LOLA_AFG_CLOCK_WIDGET_PRESENT(res) ((res & (1 << 20)) != 0)
-#define LOLA_AFG_INPUT_PIN_COUNT(res) ((res >> 10) & 0x2ff)
-#define LOLA_AFG_OUTPUT_PIN_COUNT(res) ((res) & 0x2ff)
-
-/* extract results of LOLA_PAR_AMP_IN_CAP / LOLA_PAR_AMP_OUT_CAP */
-#define LOLA_AMP_MUTE_CAPABLE(res) ((res & (1 << 31)) != 0)
-#define LOLA_AMP_STEP_SIZE(res) ((res >> 24) & 0x7f)
-#define LOLA_AMP_NUM_STEPS(res) ((res >> 12) & 0x3ff)
-#define LOLA_AMP_OFFSET(res) ((res) & 0x3ff)
-
-#define LOLA_GRANULARITY_MIN 8
-#define LOLA_GRANULARITY_MAX 32
-#define LOLA_GRANULARITY_STEP 8
-
-/* parameters used with unsolicited command/response */
-#define LOLA_UNSOLICITED_TAG_MASK 0x3f
-#define LOLA_UNSOLICITED_TAG 0x1a
-#define LOLA_UNSOLICITED_ENABLE 0x80
-#define LOLA_UNSOL_RESP_TAG_OFFSET 26
-
-/* count values in the Vendor Specific Mixer Widget's Audio Widget Capabilities */
-#define LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(res) ((res >> 2) & 0x1f)
-#define LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(res) ((res >> 7) & 0x1f)
-
-int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb,
- unsigned int data, unsigned int extdata);
-int lola_codec_read(struct lola *chip, unsigned int nid, unsigned int verb,
- unsigned int data, unsigned int extdata,
- unsigned int *val, unsigned int *extval);
-int lola_codec_flush(struct lola *chip);
-#define lola_read_param(chip, nid, param, val) \
- lola_codec_read(chip, nid, LOLA_VERB_PARAMETERS, param, 0, val, NULL)
-
-/* PCM */
-int lola_create_pcm(struct lola *chip);
-void lola_free_pcm(struct lola *chip);
-int lola_init_pcm(struct lola *chip, int dir, int *nidp);
-void lola_pcm_update(struct lola *chip, struct lola_pcm *pcm, unsigned int bits);
-
-/* clock */
-int lola_init_clock_widget(struct lola *chip, int nid);
-int lola_set_granularity(struct lola *chip, unsigned int val, bool force);
-int lola_enable_clock_events(struct lola *chip);
-int lola_set_clock_index(struct lola *chip, unsigned int idx);
-int lola_set_clock(struct lola *chip, int idx);
-int lola_set_sample_rate(struct lola *chip, int rate);
-bool lola_update_ext_clock_freq(struct lola *chip, unsigned int val);
-unsigned int lola_sample_rate_convert(unsigned int coded);
-
-/* mixer */
-int lola_init_pins(struct lola *chip, int dir, int *nidp);
-int lola_init_mixer_widget(struct lola *chip, int nid);
-void lola_free_mixer(struct lola *chip);
-int lola_create_mixer(struct lola *chip);
-int lola_setup_all_analog_gains(struct lola *chip, int dir, bool mute);
-void lola_save_mixer(struct lola *chip);
-void lola_restore_mixer(struct lola *chip);
-int lola_set_src_config(struct lola *chip, unsigned int src_mask, bool update);
-
-/* proc */
-#ifdef CONFIG_SND_DEBUG
-void lola_proc_debug_new(struct lola *chip);
-#else
-#define lola_proc_debug_new(chip)
-#endif
-
-#endif /* _LOLA_H */
diff --git a/ANDROID_3.4.5/sound/pci/lola/lola_clock.c b/ANDROID_3.4.5/sound/pci/lola/lola_clock.c
deleted file mode 100644
index 72f8ef0a..00000000
--- a/ANDROID_3.4.5/sound/pci/lola/lola_clock.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * Support for Digigram Lola PCI-e boards
- *
- * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include "lola.h"
-
-unsigned int lola_sample_rate_convert(unsigned int coded)
-{
- unsigned int freq;
-
- /* base frequency */
- switch (coded & 0x3) {
- case 0: freq = 48000; break;
- case 1: freq = 44100; break;
- case 2: freq = 32000; break;
- default: return 0; /* error */
- }
-
- /* multiplier / devisor */
- switch (coded & 0x1c) {
- case (0 << 2): break;
- case (4 << 2): break;
- case (1 << 2): freq *= 2; break;
- case (2 << 2): freq *= 4; break;
- case (5 << 2): freq /= 2; break;
- case (6 << 2): freq /= 4; break;
- default: return 0; /* error */
- }
-
- /* ajustement */
- switch (coded & 0x60) {
- case (0 << 5): break;
- case (1 << 5): freq = (freq * 999) / 1000; break;
- case (2 << 5): freq = (freq * 1001) / 1000; break;
- default: return 0; /* error */
- }
- return freq;
-}
-
-/*
- * Granualrity
- */
-
-#define LOLA_MAXFREQ_AT_GRANULARITY_MIN 48000
-#define LOLA_MAXFREQ_AT_GRANULARITY_BELOW_MAX 96000
-
-static bool check_gran_clock_compatibility(struct lola *chip,
- unsigned int val,
- unsigned int freq)
-{
- if (!chip->granularity)
- return true;
-
- if (val < LOLA_GRANULARITY_MIN || val > LOLA_GRANULARITY_MAX ||
- (val % LOLA_GRANULARITY_STEP) != 0)
- return false;
-
- if (val == LOLA_GRANULARITY_MIN) {
- if (freq > LOLA_MAXFREQ_AT_GRANULARITY_MIN)
- return false;
- } else if (val < LOLA_GRANULARITY_MAX) {
- if (freq > LOLA_MAXFREQ_AT_GRANULARITY_BELOW_MAX)
- return false;
- }
- return true;
-}
-
-int lola_set_granularity(struct lola *chip, unsigned int val, bool force)
-{
- int err;
-
- if (!force) {
- if (val == chip->granularity)
- return 0;
-#if 0
- /* change Gran only if there are no streams allocated ! */
- if (chip->audio_in_alloc_mask || chip->audio_out_alloc_mask)
- return -EBUSY;
-#endif
- if (!check_gran_clock_compatibility(chip, val,
- chip->clock.cur_freq))
- return -EINVAL;
- }
-
- chip->granularity = val;
- val /= LOLA_GRANULARITY_STEP;
-
- /* audio function group */
- err = lola_codec_write(chip, 1, LOLA_VERB_SET_GRANULARITY_STEPS,
- val, 0);
- if (err < 0)
- return err;
- /* this can be a very slow function !!! */
- usleep_range(400 * val, 20000);
- return lola_codec_flush(chip);
-}
-
-/*
- * Clock widget handling
- */
-
-int __devinit lola_init_clock_widget(struct lola *chip, int nid)
-{
- unsigned int val;
- int i, j, nitems, nb_verbs, idx, idx_list;
- int err;
-
- err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
- if (err < 0) {
- printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid);
- return err;
- }
-
- if ((val & 0xfff00000) != 0x01f00000) { /* test SubType and Type */
- snd_printdd("No valid clock widget\n");
- return 0;
- }
-
- chip->clock.nid = nid;
- chip->clock.items = val & 0xff;
- snd_printdd("clock_list nid=%x, entries=%d\n", nid,
- chip->clock.items);
- if (chip->clock.items > MAX_SAMPLE_CLOCK_COUNT) {
- printk(KERN_ERR SFX "CLOCK_LIST too big: %d\n",
- chip->clock.items);
- return -EINVAL;
- }
-
- nitems = chip->clock.items;
- nb_verbs = (nitems + 3) / 4;
- idx = 0;
- idx_list = 0;
- for (i = 0; i < nb_verbs; i++) {
- unsigned int res_ex;
- unsigned short items[4];
-
- err = lola_codec_read(chip, nid, LOLA_VERB_GET_CLOCK_LIST,
- idx, 0, &val, &res_ex);
- if (err < 0) {
- printk(KERN_ERR SFX "Can't read CLOCK_LIST\n");
- return -EINVAL;
- }
-
- items[0] = val & 0xfff;
- items[1] = (val >> 16) & 0xfff;
- items[2] = res_ex & 0xfff;
- items[3] = (res_ex >> 16) & 0xfff;
-
- for (j = 0; j < 4; j++) {
- unsigned char type = items[j] >> 8;
- unsigned int freq = items[j] & 0xff;
- int format = LOLA_CLOCK_FORMAT_NONE;
- bool add_clock = true;
- if (type == LOLA_CLOCK_TYPE_INTERNAL) {
- freq = lola_sample_rate_convert(freq);
- if (freq < chip->sample_rate_min)
- add_clock = false;
- else if (freq == 48000) {
- chip->clock.cur_index = idx_list;
- chip->clock.cur_freq = 48000;
- chip->clock.cur_valid = true;
- }
- } else if (type == LOLA_CLOCK_TYPE_VIDEO) {
- freq = lola_sample_rate_convert(freq);
- if (freq < chip->sample_rate_min)
- add_clock = false;
- /* video clock has a format (0:NTSC, 1:PAL)*/
- if (items[j] & 0x80)
- format = LOLA_CLOCK_FORMAT_NTSC;
- else
- format = LOLA_CLOCK_FORMAT_PAL;
- }
- if (add_clock) {
- struct lola_sample_clock *sc;
- sc = &chip->clock.sample_clock[idx_list];
- sc->type = type;
- sc->format = format;
- sc->freq = freq;
- /* keep the index used with the board */
- chip->clock.idx_lookup[idx_list] = idx;
- idx_list++;
- } else {
- chip->clock.items--;
- }
- if (++idx >= nitems)
- break;
- }
- }
- return 0;
-}
-
-/* enable unsolicited events of the clock widget */
-int lola_enable_clock_events(struct lola *chip)
-{
- unsigned int res;
- int err;
-
- err = lola_codec_read(chip, chip->clock.nid,
- LOLA_VERB_SET_UNSOLICITED_ENABLE,
- LOLA_UNSOLICITED_ENABLE | LOLA_UNSOLICITED_TAG,
- 0, &res, NULL);
- if (err < 0)
- return err;
- if (res) {
- printk(KERN_WARNING SFX "error in enable_clock_events %d\n",
- res);
- return -EINVAL;
- }
- return 0;
-}
-
-int lola_set_clock_index(struct lola *chip, unsigned int idx)
-{
- unsigned int res;
- int err;
-
- err = lola_codec_read(chip, chip->clock.nid,
- LOLA_VERB_SET_CLOCK_SELECT,
- chip->clock.idx_lookup[idx],
- 0, &res, NULL);
- if (err < 0)
- return err;
- if (res) {
- printk(KERN_WARNING SFX "error in set_clock %d\n", res);
- return -EINVAL;
- }
- return 0;
-}
-
-bool lola_update_ext_clock_freq(struct lola *chip, unsigned int val)
-{
- unsigned int tag;
-
- /* the current EXTERNAL clock information gets updated by interrupt
- * with an unsolicited response
- */
- if (!val)
- return false;
- tag = (val >> LOLA_UNSOL_RESP_TAG_OFFSET) & LOLA_UNSOLICITED_TAG_MASK;
- if (tag != LOLA_UNSOLICITED_TAG)
- return false;
-
- /* only for current = external clocks */
- if (chip->clock.sample_clock[chip->clock.cur_index].type !=
- LOLA_CLOCK_TYPE_INTERNAL) {
- chip->clock.cur_freq = lola_sample_rate_convert(val & 0x7f);
- chip->clock.cur_valid = (val & 0x100) != 0;
- }
- return true;
-}
-
-int lola_set_clock(struct lola *chip, int idx)
-{
- int freq = 0;
- bool valid = false;
-
- if (idx == chip->clock.cur_index) {
- /* current clock is allowed */
- freq = chip->clock.cur_freq;
- valid = chip->clock.cur_valid;
- } else if (chip->clock.sample_clock[idx].type ==
- LOLA_CLOCK_TYPE_INTERNAL) {
- /* internal clocks allowed */
- freq = chip->clock.sample_clock[idx].freq;
- valid = true;
- }
-
- if (!freq || !valid)
- return -EINVAL;
-
- if (!check_gran_clock_compatibility(chip, chip->granularity, freq))
- return -EINVAL;
-
- if (idx != chip->clock.cur_index) {
- int err = lola_set_clock_index(chip, idx);
- if (err < 0)
- return err;
- /* update new settings */
- chip->clock.cur_index = idx;
- chip->clock.cur_freq = freq;
- chip->clock.cur_valid = true;
- }
- return 0;
-}
-
-int lola_set_sample_rate(struct lola *chip, int rate)
-{
- int i;
-
- if (chip->clock.cur_freq == rate && chip->clock.cur_valid)
- return 0;
- /* search for new dwClockIndex */
- for (i = 0; i < chip->clock.items; i++) {
- if (chip->clock.sample_clock[i].type == LOLA_CLOCK_TYPE_INTERNAL &&
- chip->clock.sample_clock[i].freq == rate)
- break;
- }
- if (i >= chip->clock.items)
- return -EINVAL;
- return lola_set_clock(chip, i);
-}
-
diff --git a/ANDROID_3.4.5/sound/pci/lola/lola_mixer.c b/ANDROID_3.4.5/sound/pci/lola/lola_mixer.c
deleted file mode 100644
index 6b8d6481..00000000
--- a/ANDROID_3.4.5/sound/pci/lola/lola_mixer.c
+++ /dev/null
@@ -1,895 +0,0 @@
-/*
- * Support for Digigram Lola PCI-e boards
- *
- * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/vmalloc.h>
-#include <linux/io.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/tlv.h>
-#include "lola.h"
-
-static int __devinit lola_init_pin(struct lola *chip, struct lola_pin *pin,
- int dir, int nid)
-{
- unsigned int val;
- int err;
-
- pin->nid = nid;
- err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
- if (err < 0) {
- printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid);
- return err;
- }
- val &= 0x00f00fff; /* test TYPE and bits 0..11 */
- if (val == 0x00400200) /* Type = 4, Digital = 1 */
- pin->is_analog = false;
- else if (val == 0x0040000a && dir == CAPT) /* Dig=0, InAmp/ovrd */
- pin->is_analog = true;
- else if (val == 0x0040000c && dir == PLAY) /* Dig=0, OutAmp/ovrd */
- pin->is_analog = true;
- else {
- printk(KERN_ERR SFX "Invalid wcaps 0x%x for 0x%x\n", val, nid);
- return -EINVAL;
- }
-
- /* analog parameters only following, so continue in case of Digital pin
- */
- if (!pin->is_analog)
- return 0;
-
- if (dir == PLAY)
- err = lola_read_param(chip, nid, LOLA_PAR_AMP_OUT_CAP, &val);
- else
- err = lola_read_param(chip, nid, LOLA_PAR_AMP_IN_CAP, &val);
- if (err < 0) {
- printk(KERN_ERR SFX "Can't read AMP-caps for 0x%x\n", nid);
- return err;
- }
-
- pin->amp_mute = LOLA_AMP_MUTE_CAPABLE(val);
- pin->amp_step_size = LOLA_AMP_STEP_SIZE(val);
- pin->amp_num_steps = LOLA_AMP_NUM_STEPS(val);
- if (pin->amp_num_steps) {
- /* zero as mute state */
- pin->amp_num_steps++;
- pin->amp_step_size++;
- }
- pin->amp_offset = LOLA_AMP_OFFSET(val);
-
- err = lola_codec_read(chip, nid, LOLA_VERB_GET_MAX_LEVEL, 0, 0, &val,
- NULL);
- if (err < 0) {
- printk(KERN_ERR SFX "Can't get MAX_LEVEL 0x%x\n", nid);
- return err;
- }
- pin->max_level = val & 0x3ff; /* 10 bits */
-
- pin->config_default_reg = 0;
- pin->fixed_gain_list_len = 0;
- pin->cur_gain_step = 0;
-
- return 0;
-}
-
-int __devinit lola_init_pins(struct lola *chip, int dir, int *nidp)
-{
- int i, err, nid;
- nid = *nidp;
- for (i = 0; i < chip->pin[dir].num_pins; i++, nid++) {
- err = lola_init_pin(chip, &chip->pin[dir].pins[i], dir, nid);
- if (err < 0)
- return err;
- if (chip->pin[dir].pins[i].is_analog)
- chip->pin[dir].num_analog_pins++;
- }
- *nidp = nid;
- return 0;
-}
-
-void lola_free_mixer(struct lola *chip)
-{
- if (chip->mixer.array_saved)
- vfree(chip->mixer.array_saved);
-}
-
-int __devinit lola_init_mixer_widget(struct lola *chip, int nid)
-{
- unsigned int val;
- int err;
-
- err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
- if (err < 0) {
- printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid);
- return err;
- }
-
- if ((val & 0xfff00000) != 0x02f00000) { /* test SubType and Type */
- snd_printdd("No valid mixer widget\n");
- return 0;
- }
-
- chip->mixer.nid = nid;
- chip->mixer.caps = val;
- chip->mixer.array = (struct lola_mixer_array __iomem *)
- (chip->bar[BAR1].remap_addr + LOLA_BAR1_SOURCE_GAIN_ENABLE);
-
- /* reserve memory to copy mixer data for sleep mode transitions */
- chip->mixer.array_saved = vmalloc(sizeof(struct lola_mixer_array));
-
- /* mixer matrix sources are physical input data and play streams */
- chip->mixer.src_stream_outs = chip->pcm[PLAY].num_streams;
- chip->mixer.src_phys_ins = chip->pin[CAPT].num_pins;
-
- /* mixer matrix destinations are record streams and physical output */
- chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams;
- chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins;
-
- /* mixer matrix may have unused areas between PhysIn and
- * Play or Record and PhysOut zones
- */
- chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins +
- LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val);
- chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins +
- LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(val);
-
- /* example : MixerMatrix of LoLa881 (LoLa16161 uses unused zones)
- * +-+ 0-------8------16-------8------16
- * | | | | | | |
- * |s| | INPUT | | INPUT | |
- * | |->| -> |unused | -> |unused |
- * |r| |CAPTURE| | OUTPUT| |
- * | | | MIX | | MIX | |
- * |c| 8--------------------------------
- * | | | | | | |
- * | | | | | | |
- * |g| |unused |unused |unused |unused |
- * | | | | | | |
- * |a| | | | | |
- * | | 16-------------------------------
- * |i| | | | | |
- * | | | PLAYBK| | PLAYBK| |
- * |n|->| -> |unused | -> |unused |
- * | | |CAPTURE| | OUTPUT| |
- * | | | MIX | | MIX | |
- * |a| 8--------------------------------
- * |r| | | | | |
- * |r| | | | | |
- * |a| |unused |unused |unused |unused |
- * |y| | | | | |
- * | | | | | | |
- * +++ 16--|---------------|------------
- * +---V---------------V-----------+
- * | dest_mix_gain_enable array |
- * +-------------------------------+
- */
- /* example : MixerMatrix of LoLa280
- * +-+ 0-------8-2
- * | | | | |
- * |s| | INPUT | | INPUT
- * |r|->| -> | | ->
- * |c| |CAPTURE| | <- OUTPUT
- * | | | MIX | | MIX
- * |g| 8----------
- * |a| | | |
- * |i| | PLAYBK| | PLAYBACK
- * |n|->| -> | | ->
- * | | |CAPTURE| | <- OUTPUT
- * |a| | MIX | | MIX
- * |r| 8---|----|-
- * |r| +---V----V-------------------+
- * |a| | dest_mix_gain_enable array |
- * |y| +----------------------------+
- */
- if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT ||
- chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_COUNT) {
- printk(KERN_ERR SFX "Invalid mixer widget size\n");
- return -EINVAL;
- }
-
- chip->mixer.src_mask = ((1U << chip->mixer.src_phys_ins) - 1) |
- (((1U << chip->mixer.src_stream_outs) - 1)
- << chip->mixer.src_stream_out_ofs);
- chip->mixer.dest_mask = ((1U << chip->mixer.dest_stream_ins) - 1) |
- (((1U << chip->mixer.dest_phys_outs) - 1)
- << chip->mixer.dest_phys_out_ofs);
-
- snd_printdd("Mixer src_mask=%x, dest_mask=%x\n",
- chip->mixer.src_mask, chip->mixer.dest_mask);
-
- return 0;
-}
-
-static int lola_mixer_set_src_gain(struct lola *chip, unsigned int id,
- unsigned short gain, bool on)
-{
- unsigned int oldval, val;
-
- if (!(chip->mixer.src_mask & (1 << id)))
- return -EINVAL;
- oldval = val = readl(&chip->mixer.array->src_gain_enable);
- if (on)
- val |= (1 << id);
- else
- val &= ~(1 << id);
- /* test if values unchanged */
- if ((val == oldval) &&
- (gain == readw(&chip->mixer.array->src_gain[id])))
- return 0;
-
- snd_printdd("lola_mixer_set_src_gain (id=%d, gain=%d) enable=%x\n",
- id, gain, val);
- writew(gain, &chip->mixer.array->src_gain[id]);
- writel(val, &chip->mixer.array->src_gain_enable);
- lola_codec_flush(chip);
- /* inform micro-controller about the new source gain */
- return lola_codec_write(chip, chip->mixer.nid,
- LOLA_VERB_SET_SOURCE_GAIN, id, 0);
-}
-
-#if 0 /* not used */
-static int lola_mixer_set_src_gains(struct lola *chip, unsigned int mask,
- unsigned short *gains)
-{
- int i;
-
- if ((chip->mixer.src_mask & mask) != mask)
- return -EINVAL;
- for (i = 0; i < LOLA_MIXER_DIM; i++) {
- if (mask & (1 << i)) {
- writew(*gains, &chip->mixer.array->src_gain[i]);
- gains++;
- }
- }
- writel(mask, &chip->mixer.array->src_gain_enable);
- lola_codec_flush(chip);
- if (chip->mixer.caps & LOLA_PEAK_METER_CAN_AGC_MASK) {
- /* update for all srcs at once */
- return lola_codec_write(chip, chip->mixer.nid,
- LOLA_VERB_SET_SOURCE_GAIN, 0x80, 0);
- }
- /* update manually */
- for (i = 0; i < LOLA_MIXER_DIM; i++) {
- if (mask & (1 << i)) {
- lola_codec_write(chip, chip->mixer.nid,
- LOLA_VERB_SET_SOURCE_GAIN, i, 0);
- }
- }
- return 0;
-}
-#endif /* not used */
-
-static int lola_mixer_set_mapping_gain(struct lola *chip,
- unsigned int src, unsigned int dest,
- unsigned short gain, bool on)
-{
- unsigned int val;
-
- if (!(chip->mixer.src_mask & (1 << src)) ||
- !(chip->mixer.dest_mask & (1 << dest)))
- return -EINVAL;
- if (on)
- writew(gain, &chip->mixer.array->dest_mix_gain[dest][src]);
- val = readl(&chip->mixer.array->dest_mix_gain_enable[dest]);
- if (on)
- val |= (1 << src);
- else
- val &= ~(1 << src);
- writel(val, &chip->mixer.array->dest_mix_gain_enable[dest]);
- lola_codec_flush(chip);
- return lola_codec_write(chip, chip->mixer.nid, LOLA_VERB_SET_MIX_GAIN,
- src, dest);
-}
-
-#if 0 /* not used */
-static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
- unsigned int mask, unsigned short *gains)
-{
- int i;
-
- if (!(chip->mixer.dest_mask & (1 << id)) ||
- (chip->mixer.src_mask & mask) != mask)
- return -EINVAL;
- for (i = 0; i < LOLA_MIXER_DIM; i++) {
- if (mask & (1 << i)) {
- writew(*gains, &chip->mixer.array->dest_mix_gain[id][i]);
- gains++;
- }
- }
- writel(mask, &chip->mixer.array->dest_mix_gain_enable[id]);
- lola_codec_flush(chip);
- /* update for all dests at once */
- return lola_codec_write(chip, chip->mixer.nid,
- LOLA_VERB_SET_DESTINATION_GAIN, id, 0);
-}
-#endif /* not used */
-
-/*
- */
-
-static int set_analog_volume(struct lola *chip, int dir,
- unsigned int idx, unsigned int val,
- bool external_call);
-
-int lola_setup_all_analog_gains(struct lola *chip, int dir, bool mute)
-{
- struct lola_pin *pin;
- int idx, max_idx;
-
- pin = chip->pin[dir].pins;
- max_idx = chip->pin[dir].num_pins;
- for (idx = 0; idx < max_idx; idx++) {
- if (pin[idx].is_analog) {
- unsigned int val = mute ? 0 : pin[idx].cur_gain_step;
- /* set volume and do not save the value */
- set_analog_volume(chip, dir, idx, val, false);
- }
- }
- return lola_codec_flush(chip);
-}
-
-void lola_save_mixer(struct lola *chip)
-{
- /* mute analog output */
- if (chip->mixer.array_saved) {
- /* store contents of mixer array */
- memcpy_fromio(chip->mixer.array_saved, chip->mixer.array,
- sizeof(*chip->mixer.array));
- }
- lola_setup_all_analog_gains(chip, PLAY, true); /* output mute */
-}
-
-void lola_restore_mixer(struct lola *chip)
-{
- int i;
-
- /*lola_reset_setups(chip);*/
- if (chip->mixer.array_saved) {
- /* restore contents of mixer array */
- memcpy_toio(chip->mixer.array, chip->mixer.array_saved,
- sizeof(*chip->mixer.array));
- /* inform micro-controller about all restored values
- * and ignore return values
- */
- for (i = 0; i < chip->mixer.src_phys_ins; i++)
- lola_codec_write(chip, chip->mixer.nid,
- LOLA_VERB_SET_SOURCE_GAIN,
- i, 0);
- for (i = 0; i < chip->mixer.src_stream_outs; i++)
- lola_codec_write(chip, chip->mixer.nid,
- LOLA_VERB_SET_SOURCE_GAIN,
- chip->mixer.src_stream_out_ofs + i, 0);
- for (i = 0; i < chip->mixer.dest_stream_ins; i++)
- lola_codec_write(chip, chip->mixer.nid,
- LOLA_VERB_SET_DESTINATION_GAIN,
- i, 0);
- for (i = 0; i < chip->mixer.dest_phys_outs; i++)
- lola_codec_write(chip, chip->mixer.nid,
- LOLA_VERB_SET_DESTINATION_GAIN,
- chip->mixer.dest_phys_out_ofs + i, 0);
- lola_codec_flush(chip);
- }
-}
-
-/*
- */
-
-static int set_analog_volume(struct lola *chip, int dir,
- unsigned int idx, unsigned int val,
- bool external_call)
-{
- struct lola_pin *pin;
- int err;
-
- if (idx >= chip->pin[dir].num_pins)
- return -EINVAL;
- pin = &chip->pin[dir].pins[idx];
- if (!pin->is_analog || pin->amp_num_steps <= val)
- return -EINVAL;
- if (external_call && pin->cur_gain_step == val)
- return 0;
- if (external_call)
- lola_codec_flush(chip);
- snd_printdd("set_analog_volume (dir=%d idx=%d, volume=%d)\n",
- dir, idx, val);
- err = lola_codec_write(chip, pin->nid,
- LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0);
- if (err < 0)
- return err;
- if (external_call)
- pin->cur_gain_step = val;
- return 0;
-}
-
-int lola_set_src_config(struct lola *chip, unsigned int src_mask, bool update)
-{
- int ret = 0;
- int success = 0;
- int n, err;
-
- /* SRC can be activated and the dwInputSRCMask is valid? */
- if ((chip->input_src_caps_mask & src_mask) != src_mask)
- return -EINVAL;
- /* handle all even Inputs - SRC is a stereo setting !!! */
- for (n = 0; n < chip->pin[CAPT].num_pins; n += 2) {
- unsigned int mask = 3U << n; /* handle the stereo case */
- unsigned int new_src, src_state;
- if (!(chip->input_src_caps_mask & mask))
- continue;
- /* if one IO needs SRC, both stereo IO will get SRC */
- new_src = (src_mask & mask) != 0;
- if (update) {
- src_state = (chip->input_src_mask & mask) != 0;
- if (src_state == new_src)
- continue; /* nothing to change for this IO */
- }
- err = lola_codec_write(chip, chip->pcm[CAPT].streams[n].nid,
- LOLA_VERB_SET_SRC, new_src, 0);
- if (!err)
- success++;
- else
- ret = err;
- }
- if (success)
- ret = lola_codec_flush(chip);
- if (!ret)
- chip->input_src_mask = src_mask;
- return ret;
-}
-
-/*
- */
-static int init_mixer_values(struct lola *chip)
-{
- int i;
-
- /* all sample rate converters on */
- lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false);
-
- /* clear all mixer matrix settings */
- memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array));
- /* inform firmware about all updated matrix columns - capture part */
- for (i = 0; i < chip->mixer.dest_stream_ins; i++)
- lola_codec_write(chip, chip->mixer.nid,
- LOLA_VERB_SET_DESTINATION_GAIN,
- i, 0);
- /* inform firmware about all updated matrix columns - output part */
- for (i = 0; i < chip->mixer.dest_phys_outs; i++)
- lola_codec_write(chip, chip->mixer.nid,
- LOLA_VERB_SET_DESTINATION_GAIN,
- chip->mixer.dest_phys_out_ofs + i, 0);
-
- /* set all digital input source (master) gains to 0dB */
- for (i = 0; i < chip->mixer.src_phys_ins; i++)
- lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */
-
- /* set all digital playback source (master) gains to 0dB */
- for (i = 0; i < chip->mixer.src_stream_outs; i++)
- lola_mixer_set_src_gain(chip,
- i + chip->mixer.src_stream_out_ofs,
- 336, true); /* 0dB */
- /* set gain value 0dB diagonally in matrix - part INPUT -> CAPTURE */
- for (i = 0; i < chip->mixer.dest_stream_ins; i++) {
- int src = i % chip->mixer.src_phys_ins;
- lola_mixer_set_mapping_gain(chip, src, i, 336, true);
- }
- /* set gain value 0dB diagonally in matrix , part PLAYBACK -> OUTPUT
- * (LoLa280 : playback channel 0,2,4,6 linked to output channel 0)
- * (LoLa280 : playback channel 1,3,5,7 linked to output channel 1)
- */
- for (i = 0; i < chip->mixer.src_stream_outs; i++) {
- int src = chip->mixer.src_stream_out_ofs + i;
- int dst = chip->mixer.dest_phys_out_ofs +
- i % chip->mixer.dest_phys_outs;
- lola_mixer_set_mapping_gain(chip, src, dst, 336, true);
- }
- return 0;
-}
-
-/*
- * analog mixer control element
- */
-static int lola_analog_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct lola *chip = snd_kcontrol_chip(kcontrol);
- int dir = kcontrol->private_value;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = chip->pin[dir].num_pins;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = chip->pin[dir].pins[0].amp_num_steps;
- return 0;
-}
-
-static int lola_analog_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct lola *chip = snd_kcontrol_chip(kcontrol);
- int dir = kcontrol->private_value;
- int i;
-
- for (i = 0; i < chip->pin[dir].num_pins; i++)
- ucontrol->value.integer.value[i] =
- chip->pin[dir].pins[i].cur_gain_step;
- return 0;
-}
-
-static int lola_analog_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct lola *chip = snd_kcontrol_chip(kcontrol);
- int dir = kcontrol->private_value;
- int i, err;
-
- for (i = 0; i < chip->pin[dir].num_pins; i++) {
- err = set_analog_volume(chip, dir, i,
- ucontrol->value.integer.value[i],
- true);
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-static int lola_analog_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
- unsigned int size, unsigned int __user *tlv)
-{
- struct lola *chip = snd_kcontrol_chip(kcontrol);
- int dir = kcontrol->private_value;
- unsigned int val1, val2;
- struct lola_pin *pin;
-
- if (size < 4 * sizeof(unsigned int))
- return -ENOMEM;
- pin = &chip->pin[dir].pins[0];
-
- val2 = pin->amp_step_size * 25;
- val1 = -1 * (int)pin->amp_offset * (int)val2;
-#ifdef TLV_DB_SCALE_MUTE
- val2 |= TLV_DB_SCALE_MUTE;
-#endif
- if (put_user(SNDRV_CTL_TLVT_DB_SCALE, tlv))
- return -EFAULT;
- if (put_user(2 * sizeof(unsigned int), tlv + 1))
- return -EFAULT;
- if (put_user(val1, tlv + 2))
- return -EFAULT;
- if (put_user(val2, tlv + 3))
- return -EFAULT;
- return 0;
-}
-
-static struct snd_kcontrol_new lola_analog_mixer __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ |
- SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK),
- .info = lola_analog_vol_info,
- .get = lola_analog_vol_get,
- .put = lola_analog_vol_put,
- .tlv.c = lola_analog_vol_tlv,
-};
-
-static int __devinit create_analog_mixer(struct lola *chip, int dir, char *name)
-{
- if (!chip->pin[dir].num_pins)
- return 0;
- /* no analog volumes on digital only adapters */
- if (chip->pin[dir].num_pins != chip->pin[dir].num_analog_pins)
- return 0;
- lola_analog_mixer.name = name;
- lola_analog_mixer.private_value = dir;
- return snd_ctl_add(chip->card,
- snd_ctl_new1(&lola_analog_mixer, chip));
-}
-
-/*
- * Hardware sample rate converter on digital input
- */
-static int lola_input_src_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct lola *chip = snd_kcontrol_chip(kcontrol);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = chip->pin[CAPT].num_pins;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int lola_input_src_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct lola *chip = snd_kcontrol_chip(kcontrol);
- int i;
-
- for (i = 0; i < chip->pin[CAPT].num_pins; i++)
- ucontrol->value.integer.value[i] =
- !!(chip->input_src_mask & (1 << i));
- return 0;
-}
-
-static int lola_input_src_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct lola *chip = snd_kcontrol_chip(kcontrol);
- int i;
- unsigned int mask;
-
- mask = 0;
- for (i = 0; i < chip->pin[CAPT].num_pins; i++)
- if (ucontrol->value.integer.value[i])
- mask |= 1 << i;
- return lola_set_src_config(chip, mask, true);
-}
-
-static struct snd_kcontrol_new lola_input_src_mixer __devinitdata = {
- .name = "Digital SRC Capture Switch",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = lola_input_src_info,
- .get = lola_input_src_get,
- .put = lola_input_src_put,
-};
-
-/*
- * Lola16161 or Lola881 can have Hardware sample rate converters
- * on its digital input pins
- */
-static int __devinit create_input_src_mixer(struct lola *chip)
-{
- if (!chip->input_src_caps_mask)
- return 0;
-
- return snd_ctl_add(chip->card,
- snd_ctl_new1(&lola_input_src_mixer, chip));
-}
-
-/*
- * src gain mixer
- */
-static int lola_src_gain_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- unsigned int count = (kcontrol->private_value >> 8) & 0xff;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = count;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 409;
- return 0;
-}
-
-static int lola_src_gain_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct lola *chip = snd_kcontrol_chip(kcontrol);
- unsigned int ofs = kcontrol->private_value & 0xff;
- unsigned int count = (kcontrol->private_value >> 8) & 0xff;
- unsigned int mask, i;
-
- mask = readl(&chip->mixer.array->src_gain_enable);
- for (i = 0; i < count; i++) {
- unsigned int idx = ofs + i;
- unsigned short val;
- if (!(chip->mixer.src_mask & (1 << idx)))
- return -EINVAL;
- if (mask & (1 << idx))
- val = readw(&chip->mixer.array->src_gain[idx]) + 1;
- else
- val = 0;
- ucontrol->value.integer.value[i] = val;
- }
- return 0;
-}
-
-static int lola_src_gain_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct lola *chip = snd_kcontrol_chip(kcontrol);
- unsigned int ofs = kcontrol->private_value & 0xff;
- unsigned int count = (kcontrol->private_value >> 8) & 0xff;
- int i, err;
-
- for (i = 0; i < count; i++) {
- unsigned int idx = ofs + i;
- unsigned short val = ucontrol->value.integer.value[i];
- if (val)
- val--;
- err = lola_mixer_set_src_gain(chip, idx, val, !!val);
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-/* raw value: 0 = -84dB, 336 = 0dB, 408=18dB, incremented 1 for mute */
-static const DECLARE_TLV_DB_SCALE(lola_src_gain_tlv, -8425, 25, 1);
-
-static struct snd_kcontrol_new lola_src_gain_mixer __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .info = lola_src_gain_info,
- .get = lola_src_gain_get,
- .put = lola_src_gain_put,
- .tlv.p = lola_src_gain_tlv,
-};
-
-static int __devinit create_src_gain_mixer(struct lola *chip,
- int num, int ofs, char *name)
-{
- lola_src_gain_mixer.name = name;
- lola_src_gain_mixer.private_value = ofs + (num << 8);
- return snd_ctl_add(chip->card,
- snd_ctl_new1(&lola_src_gain_mixer, chip));
-}
-
-#if 0 /* not used */
-/*
- * destination gain (matrix-like) mixer
- */
-static int lola_dest_gain_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = src_num;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 433;
- return 0;
-}
-
-static int lola_dest_gain_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct lola *chip = snd_kcontrol_chip(kcontrol);
- unsigned int src_ofs = kcontrol->private_value & 0xff;
- unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
- unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff;
- unsigned int dst, mask, i;
-
- dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs;
- mask = readl(&chip->mixer.array->dest_mix_gain_enable[dst]);
- for (i = 0; i < src_num; i++) {
- unsigned int src = src_ofs + i;
- unsigned short val;
- if (!(chip->mixer.src_mask & (1 << src)))
- return -EINVAL;
- if (mask & (1 << dst))
- val = readw(&chip->mixer.array->dest_mix_gain[dst][src]) + 1;
- else
- val = 0;
- ucontrol->value.integer.value[i] = val;
- }
- return 0;
-}
-
-static int lola_dest_gain_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct lola *chip = snd_kcontrol_chip(kcontrol);
- unsigned int src_ofs = kcontrol->private_value & 0xff;
- unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
- unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff;
- unsigned int dst, mask;
- unsigned short gains[MAX_STREAM_COUNT];
- int i, num;
-
- mask = 0;
- num = 0;
- for (i = 0; i < src_num; i++) {
- unsigned short val = ucontrol->value.integer.value[i];
- if (val) {
- gains[num++] = val - 1;
- mask |= 1 << i;
- }
- }
- mask <<= src_ofs;
- dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs;
- return lola_mixer_set_dest_gains(chip, dst, mask, gains);
-}
-
-static const DECLARE_TLV_DB_SCALE(lola_dest_gain_tlv, -8425, 25, 1);
-
-static struct snd_kcontrol_new lola_dest_gain_mixer __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .info = lola_dest_gain_info,
- .get = lola_dest_gain_get,
- .put = lola_dest_gain_put,
- .tlv.p = lola_dest_gain_tlv,
-};
-
-static int __devinit create_dest_gain_mixer(struct lola *chip,
- int src_num, int src_ofs,
- int num, int ofs, char *name)
-{
- lola_dest_gain_mixer.count = num;
- lola_dest_gain_mixer.name = name;
- lola_dest_gain_mixer.private_value =
- src_ofs + (src_num << 8) + (ofs << 16) + (num << 24);
- return snd_ctl_add(chip->card,
- snd_ctl_new1(&lola_dest_gain_mixer, chip));
-}
-#endif /* not used */
-
-/*
- */
-int __devinit lola_create_mixer(struct lola *chip)
-{
- int err;
-
- err = create_analog_mixer(chip, PLAY, "Analog Playback Volume");
- if (err < 0)
- return err;
- err = create_analog_mixer(chip, CAPT, "Analog Capture Volume");
- if (err < 0)
- return err;
- err = create_input_src_mixer(chip);
- if (err < 0)
- return err;
- err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0,
- "Digital Capture Volume");
- if (err < 0)
- return err;
- err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs,
- chip->mixer.src_stream_out_ofs,
- "Digital Playback Volume");
- if (err < 0)
- return err;
-#if 0
-/* FIXME: buggy mixer matrix handling */
- err = create_dest_gain_mixer(chip,
- chip->mixer.src_phys_ins, 0,
- chip->mixer.dest_stream_ins, 0,
- "Line Capture Volume");
- if (err < 0)
- return err;
- err = create_dest_gain_mixer(chip,
- chip->mixer.src_stream_outs,
- chip->mixer.src_stream_out_ofs,
- chip->mixer.dest_stream_ins, 0,
- "Stream-Loopback Capture Volume");
- if (err < 0)
- return err;
- err = create_dest_gain_mixer(chip,
- chip->mixer.src_phys_ins, 0,
- chip->mixer.dest_phys_outs,
- chip->mixer.dest_phys_out_ofs,
- "Line-Loopback Playback Volume");
- if (err < 0)
- return err;
- err = create_dest_gain_mixer(chip,
- chip->mixer.src_stream_outs,
- chip->mixer.src_stream_out_ofs,
- chip->mixer.dest_phys_outs,
- chip->mixer.dest_phys_out_ofs,
- "Stream Playback Volume");
- if (err < 0)
- return err;
-#endif /* FIXME */
- return init_mixer_values(chip);
-}
diff --git a/ANDROID_3.4.5/sound/pci/lola/lola_pcm.c b/ANDROID_3.4.5/sound/pci/lola/lola_pcm.c
deleted file mode 100644
index c44db68e..00000000
--- a/ANDROID_3.4.5/sound/pci/lola/lola_pcm.c
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * Support for Digigram Lola PCI-e boards
- *
- * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/dma-mapping.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include "lola.h"
-
-#define LOLA_MAX_BDL_ENTRIES 8
-#define LOLA_MAX_BUF_SIZE (1024*1024*1024)
-#define LOLA_BDL_ENTRY_SIZE (16 * 16)
-
-static struct lola_pcm *lola_get_pcm(struct snd_pcm_substream *substream)
-{
- struct lola *chip = snd_pcm_substream_chip(substream);
- return &chip->pcm[substream->stream];
-}
-
-static struct lola_stream *lola_get_stream(struct snd_pcm_substream *substream)
-{
- struct lola_pcm *pcm = lola_get_pcm(substream);
- unsigned int idx = substream->number;
- return &pcm->streams[idx];
-}
-
-static unsigned int lola_get_lrc(struct lola *chip)
-{
- return lola_readl(chip, BAR1, LRC);
-}
-
-static unsigned int lola_get_tstamp(struct lola *chip, bool quick_no_sync)
-{
- unsigned int tstamp = lola_get_lrc(chip) >> 8;
- if (chip->granularity) {
- unsigned int wait_banks = quick_no_sync ? 0 : 8;
- tstamp += (wait_banks + 1) * chip->granularity - 1;
- tstamp -= tstamp % chip->granularity;
- }
- return tstamp << 8;
-}
-
-/* clear any pending interrupt status */
-static void lola_stream_clear_pending_irq(struct lola *chip,
- struct lola_stream *str)
-{
- unsigned int val = lola_dsd_read(chip, str->dsd, STS);
- val &= LOLA_DSD_STS_DESE | LOLA_DSD_STS_BCIS;
- if (val)
- lola_dsd_write(chip, str->dsd, STS, val);
-}
-
-static void lola_stream_start(struct lola *chip, struct lola_stream *str,
- unsigned int tstamp)
-{
- lola_stream_clear_pending_irq(chip, str);
- lola_dsd_write(chip, str->dsd, CTL,
- LOLA_DSD_CTL_SRUN |
- LOLA_DSD_CTL_IOCE |
- LOLA_DSD_CTL_DEIE |
- LOLA_DSD_CTL_VLRCV |
- tstamp);
-}
-
-static void lola_stream_stop(struct lola *chip, struct lola_stream *str,
- unsigned int tstamp)
-{
- lola_dsd_write(chip, str->dsd, CTL,
- LOLA_DSD_CTL_IOCE |
- LOLA_DSD_CTL_DEIE |
- LOLA_DSD_CTL_VLRCV |
- tstamp);
- lola_stream_clear_pending_irq(chip, str);
-}
-
-static void wait_for_srst_clear(struct lola *chip, struct lola_stream *str)
-{
- unsigned long end_time = jiffies + msecs_to_jiffies(200);
- while (time_before(jiffies, end_time)) {
- unsigned int val;
- val = lola_dsd_read(chip, str->dsd, CTL);
- if (!(val & LOLA_DSD_CTL_SRST))
- return;
- msleep(1);
- }
- printk(KERN_WARNING SFX "SRST not clear (stream %d)\n", str->dsd);
-}
-
-static int lola_stream_wait_for_fifo(struct lola *chip,
- struct lola_stream *str,
- bool ready)
-{
- unsigned int val = ready ? LOLA_DSD_STS_FIFORDY : 0;
- unsigned long end_time = jiffies + msecs_to_jiffies(200);
- while (time_before(jiffies, end_time)) {
- unsigned int reg = lola_dsd_read(chip, str->dsd, STS);
- if ((reg & LOLA_DSD_STS_FIFORDY) == val)
- return 0;
- msleep(1);
- }
- printk(KERN_WARNING SFX "FIFO not ready (stream %d)\n", str->dsd);
- return -EIO;
-}
-
-/* sync for FIFO ready/empty for all linked streams;
- * clear paused flag when FIFO gets ready again
- */
-static int lola_sync_wait_for_fifo(struct lola *chip,
- struct snd_pcm_substream *substream,
- bool ready)
-{
- unsigned int val = ready ? LOLA_DSD_STS_FIFORDY : 0;
- unsigned long end_time = jiffies + msecs_to_jiffies(200);
- struct snd_pcm_substream *s;
- int pending = 0;
-
- while (time_before(jiffies, end_time)) {
- pending = 0;
- snd_pcm_group_for_each_entry(s, substream) {
- struct lola_stream *str;
- if (s->pcm->card != substream->pcm->card)
- continue;
- str = lola_get_stream(s);
- if (str->prepared && str->paused) {
- unsigned int reg;
- reg = lola_dsd_read(chip, str->dsd, STS);
- if ((reg & LOLA_DSD_STS_FIFORDY) != val) {
- pending = str->dsd + 1;
- break;
- }
- if (ready)
- str->paused = 0;
- }
- }
- if (!pending)
- return 0;
- msleep(1);
- }
- printk(KERN_WARNING SFX "FIFO not ready (pending %d)\n", pending - 1);
- return -EIO;
-}
-
-/* finish pause - prepare for a new resume */
-static void lola_sync_pause(struct lola *chip,
- struct snd_pcm_substream *substream)
-{
- struct snd_pcm_substream *s;
-
- lola_sync_wait_for_fifo(chip, substream, false);
- snd_pcm_group_for_each_entry(s, substream) {
- struct lola_stream *str;
- if (s->pcm->card != substream->pcm->card)
- continue;
- str = lola_get_stream(s);
- if (str->paused && str->prepared)
- lola_dsd_write(chip, str->dsd, CTL, LOLA_DSD_CTL_SRUN |
- LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE);
- }
- lola_sync_wait_for_fifo(chip, substream, true);
-}
-
-static void lola_stream_reset(struct lola *chip, struct lola_stream *str)
-{
- if (str->prepared) {
- if (str->paused)
- lola_sync_pause(chip, str->substream);
- str->prepared = 0;
- lola_dsd_write(chip, str->dsd, CTL,
- LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE);
- lola_stream_wait_for_fifo(chip, str, false);
- lola_stream_clear_pending_irq(chip, str);
- lola_dsd_write(chip, str->dsd, CTL, LOLA_DSD_CTL_SRST);
- lola_dsd_write(chip, str->dsd, LVI, 0);
- lola_dsd_write(chip, str->dsd, BDPU, 0);
- lola_dsd_write(chip, str->dsd, BDPL, 0);
- wait_for_srst_clear(chip, str);
- }
-}
-
-static struct snd_pcm_hardware lola_pcm_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE),
- .formats = (SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE |
- SNDRV_PCM_FMTBIT_FLOAT_LE),
- .rates = SNDRV_PCM_RATE_8000_192000,
- .rate_min = 8000,
- .rate_max = 192000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = LOLA_MAX_BUF_SIZE,
- .period_bytes_min = 128,
- .period_bytes_max = LOLA_MAX_BUF_SIZE / 2,
- .periods_min = 2,
- .periods_max = LOLA_MAX_BDL_ENTRIES,
- .fifo_size = 0,
-};
-
-static int lola_pcm_open(struct snd_pcm_substream *substream)
-{
- struct lola *chip = snd_pcm_substream_chip(substream);
- struct lola_pcm *pcm = lola_get_pcm(substream);
- struct lola_stream *str = lola_get_stream(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- mutex_lock(&chip->open_mutex);
- if (str->opened) {
- mutex_unlock(&chip->open_mutex);
- return -EBUSY;
- }
- str->substream = substream;
- str->master = NULL;
- str->opened = 1;
- runtime->hw = lola_pcm_hw;
- runtime->hw.channels_max = pcm->num_streams - str->index;
- if (chip->sample_rate) {
- /* sample rate is locked */
- runtime->hw.rate_min = chip->sample_rate;
- runtime->hw.rate_max = chip->sample_rate;
- } else {
- runtime->hw.rate_min = chip->sample_rate_min;
- runtime->hw.rate_max = chip->sample_rate_max;
- }
- chip->ref_count_rate++;
- snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
- /* period size = multiple of chip->granularity (8, 16 or 32 frames)*/
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- chip->granularity);
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- chip->granularity);
- mutex_unlock(&chip->open_mutex);
- return 0;
-}
-
-static void lola_cleanup_slave_streams(struct lola_pcm *pcm,
- struct lola_stream *str)
-{
- int i;
- for (i = str->index + 1; i < pcm->num_streams; i++) {
- struct lola_stream *s = &pcm->streams[i];
- if (s->master != str)
- break;
- s->master = NULL;
- s->opened = 0;
- }
-}
-
-static int lola_pcm_close(struct snd_pcm_substream *substream)
-{
- struct lola *chip = snd_pcm_substream_chip(substream);
- struct lola_stream *str = lola_get_stream(substream);
-
- mutex_lock(&chip->open_mutex);
- if (str->substream == substream) {
- str->substream = NULL;
- str->opened = 0;
- }
- if (--chip->ref_count_rate == 0) {
- /* release sample rate */
- chip->sample_rate = 0;
- }
- mutex_unlock(&chip->open_mutex);
- return 0;
-}
-
-static int lola_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct lola_stream *str = lola_get_stream(substream);
-
- str->bufsize = 0;
- str->period_bytes = 0;
- str->format_verb = 0;
- return snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-}
-
-static int lola_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct lola *chip = snd_pcm_substream_chip(substream);
- struct lola_pcm *pcm = lola_get_pcm(substream);
- struct lola_stream *str = lola_get_stream(substream);
-
- mutex_lock(&chip->open_mutex);
- lola_stream_reset(chip, str);
- lola_cleanup_slave_streams(pcm, str);
- mutex_unlock(&chip->open_mutex);
- return snd_pcm_lib_free_pages(substream);
-}
-
-/*
- * set up a BDL entry
- */
-static int setup_bdle(struct snd_pcm_substream *substream,
- struct lola_stream *str, u32 **bdlp,
- int ofs, int size)
-{
- u32 *bdl = *bdlp;
-
- while (size > 0) {
- dma_addr_t addr;
- int chunk;
-
- if (str->frags >= LOLA_MAX_BDL_ENTRIES)
- return -EINVAL;
-
- addr = snd_pcm_sgbuf_get_addr(substream, ofs);
- /* program the address field of the BDL entry */
- bdl[0] = cpu_to_le32((u32)addr);
- bdl[1] = cpu_to_le32(upper_32_bits(addr));
- /* program the size field of the BDL entry */
- chunk = snd_pcm_sgbuf_get_chunk_size(substream, ofs, size);
- bdl[2] = cpu_to_le32(chunk);
- /* program the IOC to enable interrupt
- * only when the whole fragment is processed
- */
- size -= chunk;
- bdl[3] = size ? 0 : cpu_to_le32(0x01);
- bdl += 4;
- str->frags++;
- ofs += chunk;
- }
- *bdlp = bdl;
- return ofs;
-}
-
-/*
- * set up BDL entries
- */
-static int lola_setup_periods(struct lola *chip, struct lola_pcm *pcm,
- struct snd_pcm_substream *substream,
- struct lola_stream *str)
-{
- u32 *bdl;
- int i, ofs, periods, period_bytes;
-
- period_bytes = str->period_bytes;
- periods = str->bufsize / period_bytes;
-
- /* program the initial BDL entries */
- bdl = (u32 *)(pcm->bdl.area + LOLA_BDL_ENTRY_SIZE * str->index);
- ofs = 0;
- str->frags = 0;
- for (i = 0; i < periods; i++) {
- ofs = setup_bdle(substream, str, &bdl, ofs, period_bytes);
- if (ofs < 0)
- goto error;
- }
- return 0;
-
- error:
- snd_printk(KERN_ERR SFX "Too many BDL entries: buffer=%d, period=%d\n",
- str->bufsize, period_bytes);
- return -EINVAL;
-}
-
-static unsigned int lola_get_format_verb(struct snd_pcm_substream *substream)
-{
- unsigned int verb;
-
- switch (substream->runtime->format) {
- case SNDRV_PCM_FORMAT_S16_LE:
- verb = 0x00000000;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- verb = 0x00000200;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- verb = 0x00000300;
- break;
- case SNDRV_PCM_FORMAT_FLOAT_LE:
- verb = 0x00001300;
- break;
- default:
- return 0;
- }
- verb |= substream->runtime->channels;
- return verb;
-}
-
-static int lola_set_stream_config(struct lola *chip,
- struct lola_stream *str,
- int channels)
-{
- int i, err;
- unsigned int verb, val;
-
- /* set format info for all channels
- * (with only one command for the first channel)
- */
- err = lola_codec_read(chip, str->nid, LOLA_VERB_SET_STREAM_FORMAT,
- str->format_verb, 0, &val, NULL);
- if (err < 0) {
- printk(KERN_ERR SFX "Cannot set stream format 0x%x\n",
- str->format_verb);
- return err;
- }
-
- /* update stream - channel config */
- for (i = 0; i < channels; i++) {
- verb = (str->index << 6) | i;
- err = lola_codec_read(chip, str[i].nid,
- LOLA_VERB_SET_CHANNEL_STREAMID, 0, verb,
- &val, NULL);
- if (err < 0) {
- printk(KERN_ERR SFX "Cannot set stream channel %d\n", i);
- return err;
- }
- }
- return 0;
-}
-
-/*
- * set up the SD for streaming
- */
-static int lola_setup_controller(struct lola *chip, struct lola_pcm *pcm,
- struct lola_stream *str)
-{
- dma_addr_t bdl;
-
- if (str->prepared)
- return -EINVAL;
-
- /* set up BDL */
- bdl = pcm->bdl.addr + LOLA_BDL_ENTRY_SIZE * str->index;
- lola_dsd_write(chip, str->dsd, BDPL, (u32)bdl);
- lola_dsd_write(chip, str->dsd, BDPU, upper_32_bits(bdl));
- /* program the stream LVI (last valid index) of the BDL */
- lola_dsd_write(chip, str->dsd, LVI, str->frags - 1);
- lola_stream_clear_pending_irq(chip, str);
-
- lola_dsd_write(chip, str->dsd, CTL,
- LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE | LOLA_DSD_CTL_SRUN);
-
- str->prepared = 1;
-
- return lola_stream_wait_for_fifo(chip, str, true);
-}
-
-static int lola_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct lola *chip = snd_pcm_substream_chip(substream);
- struct lola_pcm *pcm = lola_get_pcm(substream);
- struct lola_stream *str = lola_get_stream(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int bufsize, period_bytes, format_verb;
- int i, err;
-
- mutex_lock(&chip->open_mutex);
- lola_stream_reset(chip, str);
- lola_cleanup_slave_streams(pcm, str);
- if (str->index + runtime->channels > pcm->num_streams) {
- mutex_unlock(&chip->open_mutex);
- return -EINVAL;
- }
- for (i = 1; i < runtime->channels; i++) {
- str[i].master = str;
- str[i].opened = 1;
- }
- mutex_unlock(&chip->open_mutex);
-
- bufsize = snd_pcm_lib_buffer_bytes(substream);
- period_bytes = snd_pcm_lib_period_bytes(substream);
- format_verb = lola_get_format_verb(substream);
-
- str->bufsize = bufsize;
- str->period_bytes = period_bytes;
- str->format_verb = format_verb;
-
- err = lola_setup_periods(chip, pcm, substream, str);
- if (err < 0)
- return err;
-
- err = lola_set_sample_rate(chip, runtime->rate);
- if (err < 0)
- return err;
- chip->sample_rate = runtime->rate; /* sample rate gets locked */
-
- err = lola_set_stream_config(chip, str, runtime->channels);
- if (err < 0)
- return err;
-
- err = lola_setup_controller(chip, pcm, str);
- if (err < 0) {
- lola_stream_reset(chip, str);
- return err;
- }
-
- return 0;
-}
-
-static int lola_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct lola *chip = snd_pcm_substream_chip(substream);
- struct lola_stream *str;
- struct snd_pcm_substream *s;
- unsigned int start;
- unsigned int tstamp;
- bool sync_streams;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
- start = 1;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_STOP:
- start = 0;
- break;
- default:
- return -EINVAL;
- }
-
- /*
- * sample correct synchronization is only needed starting several
- * streams. On stop or if only one stream do as quick as possible
- */
- sync_streams = (start && snd_pcm_stream_linked(substream));
- tstamp = lola_get_tstamp(chip, !sync_streams);
- spin_lock(&chip->reg_lock);
- snd_pcm_group_for_each_entry(s, substream) {
- if (s->pcm->card != substream->pcm->card)
- continue;
- str = lola_get_stream(s);
- if (start)
- lola_stream_start(chip, str, tstamp);
- else
- lola_stream_stop(chip, str, tstamp);
- str->running = start;
- str->paused = !start;
- snd_pcm_trigger_done(s, substream);
- }
- spin_unlock(&chip->reg_lock);
- return 0;
-}
-
-static snd_pcm_uframes_t lola_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct lola *chip = snd_pcm_substream_chip(substream);
- struct lola_stream *str = lola_get_stream(substream);
- unsigned int pos = lola_dsd_read(chip, str->dsd, LPIB);
-
- if (pos >= str->bufsize)
- pos = 0;
- return bytes_to_frames(substream->runtime, pos);
-}
-
-void lola_pcm_update(struct lola *chip, struct lola_pcm *pcm, unsigned int bits)
-{
- int i;
-
- for (i = 0; bits && i < pcm->num_streams; i++) {
- if (bits & (1 << i)) {
- struct lola_stream *str = &pcm->streams[i];
- if (str->substream && str->running)
- snd_pcm_period_elapsed(str->substream);
- bits &= ~(1 << i);
- }
- }
-}
-
-static struct snd_pcm_ops lola_pcm_ops = {
- .open = lola_pcm_open,
- .close = lola_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = lola_pcm_hw_params,
- .hw_free = lola_pcm_hw_free,
- .prepare = lola_pcm_prepare,
- .trigger = lola_pcm_trigger,
- .pointer = lola_pcm_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
-int __devinit lola_create_pcm(struct lola *chip)
-{
- struct snd_pcm *pcm;
- int i, err;
-
- for (i = 0; i < 2; i++) {
- err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- PAGE_SIZE, &chip->pcm[i].bdl);
- if (err < 0)
- return err;
- }
-
- err = snd_pcm_new(chip->card, "Digigram Lola", 0,
- chip->pcm[SNDRV_PCM_STREAM_PLAYBACK].num_streams,
- chip->pcm[SNDRV_PCM_STREAM_CAPTURE].num_streams,
- &pcm);
- if (err < 0)
- return err;
- strlcpy(pcm->name, "Digigram Lola", sizeof(pcm->name));
- pcm->private_data = chip;
- for (i = 0; i < 2; i++) {
- if (chip->pcm[i].num_streams)
- snd_pcm_set_ops(pcm, i, &lola_pcm_ops);
- }
- /* buffer pre-allocation */
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(chip->pci),
- 1024 * 64, 32 * 1024 * 1024);
- return 0;
-}
-
-void lola_free_pcm(struct lola *chip)
-{
- snd_dma_free_pages(&chip->pcm[0].bdl);
- snd_dma_free_pages(&chip->pcm[1].bdl);
-}
-
-/*
- */
-
-static int lola_init_stream(struct lola *chip, struct lola_stream *str,
- int idx, int nid, int dir)
-{
- unsigned int val;
- int err;
-
- str->nid = nid;
- str->index = idx;
- str->dsd = idx;
- if (dir == PLAY)
- str->dsd += MAX_STREAM_IN_COUNT;
- err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
- if (err < 0) {
- printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid);
- return err;
- }
- if (dir == PLAY) {
- /* test TYPE and bits 0..11 (no test bit9 : Digital = 0/1) */
- if ((val & 0x00f00dff) != 0x00000010) {
- printk(KERN_ERR SFX "Invalid wcaps 0x%x for 0x%x\n",
- val, nid);
- return -EINVAL;
- }
- } else {
- /* test TYPE and bits 0..11 (no test bit9 : Digital = 0/1)
- * (bug : ignore bit8: Conn list = 0/1)
- */
- if ((val & 0x00f00cff) != 0x00100010) {
- printk(KERN_ERR SFX "Invalid wcaps 0x%x for 0x%x\n",
- val, nid);
- return -EINVAL;
- }
- /* test bit9:DIGITAL and bit12:SRC_PRESENT*/
- if ((val & 0x00001200) == 0x00001200)
- chip->input_src_caps_mask |= (1 << idx);
- }
-
- err = lola_read_param(chip, nid, LOLA_PAR_STREAM_FORMATS, &val);
- if (err < 0) {
- printk(KERN_ERR SFX "Can't read FORMATS 0x%x\n", nid);
- return err;
- }
- val &= 3;
- if (val == 3)
- str->can_float = true;
- if (!(val & 1)) {
- printk(KERN_ERR SFX "Invalid formats 0x%x for 0x%x", val, nid);
- return -EINVAL;
- }
- return 0;
-}
-
-int __devinit lola_init_pcm(struct lola *chip, int dir, int *nidp)
-{
- struct lola_pcm *pcm = &chip->pcm[dir];
- int i, nid, err;
-
- nid = *nidp;
- for (i = 0; i < pcm->num_streams; i++, nid++) {
- err = lola_init_stream(chip, &pcm->streams[i], i, nid, dir);
- if (err < 0)
- return err;
- }
- *nidp = nid;
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/lola/lola_proc.c b/ANDROID_3.4.5/sound/pci/lola/lola_proc.c
deleted file mode 100644
index 9d7daf89..00000000
--- a/ANDROID_3.4.5/sound/pci/lola/lola_proc.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Support for Digigram Lola PCI-e boards
- *
- * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/pcm.h>
-#include "lola.h"
-
-static void print_audio_widget(struct snd_info_buffer *buffer,
- struct lola *chip, int nid, const char *name)
-{
- unsigned int val;
-
- lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
- snd_iprintf(buffer, "Node 0x%02x %s wcaps 0x%x\n", nid, name, val);
- lola_read_param(chip, nid, LOLA_PAR_STREAM_FORMATS, &val);
- snd_iprintf(buffer, " Formats: 0x%x\n", val);
-}
-
-static void print_pin_widget(struct snd_info_buffer *buffer,
- struct lola *chip, int nid, unsigned int ampcap,
- const char *name)
-{
- unsigned int val;
-
- lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
- snd_iprintf(buffer, "Node 0x%02x %s wcaps 0x%x\n", nid, name, val);
- if (val == 0x00400200)
- return;
- lola_read_param(chip, nid, ampcap, &val);
- snd_iprintf(buffer, " Amp-Caps: 0x%x\n", val);
- snd_iprintf(buffer, " mute=%d, step-size=%d, steps=%d, ofs=%d\n",
- LOLA_AMP_MUTE_CAPABLE(val),
- LOLA_AMP_STEP_SIZE(val),
- LOLA_AMP_NUM_STEPS(val),
- LOLA_AMP_OFFSET(val));
- lola_codec_read(chip, nid, LOLA_VERB_GET_MAX_LEVEL, 0, 0, &val, NULL);
- snd_iprintf(buffer, " Max-level: 0x%x\n", val);
-}
-
-static void print_clock_widget(struct snd_info_buffer *buffer,
- struct lola *chip, int nid)
-{
- int i, j, num_clocks;
- unsigned int val;
-
- lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
- snd_iprintf(buffer, "Node 0x%02x [Clock] wcaps 0x%x\n", nid, val);
- num_clocks = val & 0xff;
- for (i = 0; i < num_clocks; i += 4) {
- unsigned int res_ex;
- unsigned short items[4];
- const char *name;
-
- lola_codec_read(chip, nid, LOLA_VERB_GET_CLOCK_LIST,
- i, 0, &val, &res_ex);
- items[0] = val & 0xfff;
- items[1] = (val >> 16) & 0xfff;
- items[2] = res_ex & 0xfff;
- items[3] = (res_ex >> 16) & 0xfff;
- for (j = 0; j < 4; j++) {
- unsigned char type = items[j] >> 8;
- unsigned int freq = items[j] & 0xff;
- if (i + j >= num_clocks)
- break;
- if (type == LOLA_CLOCK_TYPE_INTERNAL) {
- name = "Internal";
- freq = lola_sample_rate_convert(freq);
- } else if (type == LOLA_CLOCK_TYPE_VIDEO) {
- name = "Video";
- freq = lola_sample_rate_convert(freq);
- } else {
- name = "Other";
- }
- snd_iprintf(buffer, " Clock %d: Type %d:%s, freq=%d\n",
- i + j, type, name, freq);
- }
- }
-}
-
-static void print_mixer_widget(struct snd_info_buffer *buffer,
- struct lola *chip, int nid)
-{
- unsigned int val;
-
- lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
- snd_iprintf(buffer, "Node 0x%02x [Mixer] wcaps 0x%x\n", nid, val);
-}
-
-static void lola_proc_codec_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct lola *chip = entry->private_data;
- unsigned int val;
- int i, nid;
-
- lola_read_param(chip, 0, LOLA_PAR_VENDOR_ID, &val);
- snd_iprintf(buffer, "Vendor: 0x%08x\n", val);
- lola_read_param(chip, 1, LOLA_PAR_FUNCTION_TYPE, &val);
- snd_iprintf(buffer, "Function Type: %d\n", val);
- lola_read_param(chip, 1, LOLA_PAR_SPECIFIC_CAPS, &val);
- snd_iprintf(buffer, "Specific-Caps: 0x%08x\n", val);
- snd_iprintf(buffer, " Pins-In %d, Pins-Out %d\n",
- chip->pin[CAPT].num_pins, chip->pin[PLAY].num_pins);
- nid = 2;
- for (i = 0; i < chip->pcm[CAPT].num_streams; i++, nid++)
- print_audio_widget(buffer, chip, nid, "[Audio-In]");
- for (i = 0; i < chip->pcm[PLAY].num_streams; i++, nid++)
- print_audio_widget(buffer, chip, nid, "[Audio-Out]");
- for (i = 0; i < chip->pin[CAPT].num_pins; i++, nid++)
- print_pin_widget(buffer, chip, nid, LOLA_PAR_AMP_IN_CAP,
- "[Pin-In]");
- for (i = 0; i < chip->pin[PLAY].num_pins; i++, nid++)
- print_pin_widget(buffer, chip, nid, LOLA_PAR_AMP_OUT_CAP,
- "[Pin-Out]");
- if (LOLA_AFG_CLOCK_WIDGET_PRESENT(chip->lola_caps)) {
- print_clock_widget(buffer, chip, nid);
- nid++;
- }
- if (LOLA_AFG_MIXER_WIDGET_PRESENT(chip->lola_caps)) {
- print_mixer_widget(buffer, chip, nid);
- nid++;
- }
-}
-
-/* direct codec access for debugging */
-static void lola_proc_codec_rw_write(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct lola *chip = entry->private_data;
- char line[64];
- unsigned int id, verb, data, extdata;
- while (!snd_info_get_line(buffer, line, sizeof(line))) {
- if (sscanf(line, "%i %i %i %i", &id, &verb, &data, &extdata) != 4)
- continue;
- lola_codec_read(chip, id, verb, data, extdata,
- &chip->debug_res,
- &chip->debug_res_ex);
- }
-}
-
-static void lola_proc_codec_rw_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct lola *chip = entry->private_data;
- snd_iprintf(buffer, "0x%x 0x%x\n", chip->debug_res, chip->debug_res_ex);
-}
-
-/*
- * dump some registers
- */
-static void lola_proc_regs_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct lola *chip = entry->private_data;
- int i;
-
- for (i = 0; i < 0x40; i += 4) {
- snd_iprintf(buffer, "BAR0 %02x: %08x\n", i,
- readl(chip->bar[BAR0].remap_addr + i));
- }
- snd_iprintf(buffer, "\n");
- for (i = 0; i < 0x30; i += 4) {
- snd_iprintf(buffer, "BAR1 %02x: %08x\n", i,
- readl(chip->bar[BAR1].remap_addr + i));
- }
- snd_iprintf(buffer, "\n");
- for (i = 0x80; i < 0xa0; i += 4) {
- snd_iprintf(buffer, "BAR1 %02x: %08x\n", i,
- readl(chip->bar[BAR1].remap_addr + i));
- }
- snd_iprintf(buffer, "\n");
- for (i = 0; i < 32; i++) {
- snd_iprintf(buffer, "DSD %02x STS %08x\n", i,
- lola_dsd_read(chip, i, STS));
- snd_iprintf(buffer, "DSD %02x LPIB %08x\n", i,
- lola_dsd_read(chip, i, LPIB));
- snd_iprintf(buffer, "DSD %02x CTL %08x\n", i,
- lola_dsd_read(chip, i, CTL));
- snd_iprintf(buffer, "DSD %02x LVIL %08x\n", i,
- lola_dsd_read(chip, i, LVI));
- snd_iprintf(buffer, "DSD %02x BDPL %08x\n", i,
- lola_dsd_read(chip, i, BDPL));
- snd_iprintf(buffer, "DSD %02x BDPU %08x\n", i,
- lola_dsd_read(chip, i, BDPU));
- }
-}
-
-void __devinit lola_proc_debug_new(struct lola *chip)
-{
- struct snd_info_entry *entry;
-
- if (!snd_card_proc_new(chip->card, "codec", &entry))
- snd_info_set_text_ops(entry, chip, lola_proc_codec_read);
- if (!snd_card_proc_new(chip->card, "codec_rw", &entry)) {
- snd_info_set_text_ops(entry, chip, lola_proc_codec_rw_read);
- entry->mode |= S_IWUSR;
- entry->c.text.write = lola_proc_codec_rw_write;
- }
- if (!snd_card_proc_new(chip->card, "regs", &entry))
- snd_info_set_text_ops(entry, chip, lola_proc_regs_read);
-}
diff --git a/ANDROID_3.4.5/sound/pci/lx6464es/Makefile b/ANDROID_3.4.5/sound/pci/lx6464es/Makefile
deleted file mode 100644
index eb04a6c7..00000000
--- a/ANDROID_3.4.5/sound/pci/lx6464es/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-snd-lx6464es-objs := lx6464es.o lx_core.o
-obj-$(CONFIG_SND_LX6464ES) += snd-lx6464es.o
diff --git a/ANDROID_3.4.5/sound/pci/lx6464es/lx6464es.c b/ANDROID_3.4.5/sound/pci/lx6464es/lx6464es.c
deleted file mode 100644
index d94c0c29..00000000
--- a/ANDROID_3.4.5/sound/pci/lx6464es/lx6464es.c
+++ /dev/null
@@ -1,1164 +0,0 @@
-/* -*- linux-c -*- *
- *
- * ALSA driver for the digigram lx6464es interface
- *
- * Copyright (c) 2008, 2009 Tim Blechmann <tim@klingt.org>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-
-#include <sound/initval.h>
-#include <sound/control.h>
-#include <sound/info.h>
-
-#include "lx6464es.h"
-
-MODULE_AUTHOR("Tim Blechmann");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("digigram lx6464es");
-MODULE_SUPPORTED_DEVICE("{digigram lx6464es{}}");
-
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Digigram LX6464ES interface.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Digigram LX6464ES interface.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable/disable specific Digigram LX6464ES soundcards.");
-
-static const char card_name[] = "LX6464ES";
-
-
-#define PCI_DEVICE_ID_PLX_LX6464ES PCI_DEVICE_ID_PLX_9056
-
-static DEFINE_PCI_DEVICE_TABLE(snd_lx6464es_ids) = {
- { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_LX6464ES),
- .subvendor = PCI_VENDOR_ID_DIGIGRAM,
- .subdevice = PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_SERIAL_SUBSYSTEM
- }, /* LX6464ES */
- { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_LX6464ES),
- .subvendor = PCI_VENDOR_ID_DIGIGRAM,
- .subdevice = PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_CAE_SERIAL_SUBSYSTEM
- }, /* LX6464ES-CAE */
- { 0, },
-};
-
-MODULE_DEVICE_TABLE(pci, snd_lx6464es_ids);
-
-
-
-/* PGO pour USERo dans le registre pci_0x06/loc_0xEC */
-#define CHIPSC_RESET_XILINX (1L<<16)
-
-
-/* alsa callbacks */
-static struct snd_pcm_hardware lx_caps = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_SYNC_START),
- .formats = (SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S24_3BE),
- .rates = (SNDRV_PCM_RATE_CONTINUOUS |
- SNDRV_PCM_RATE_8000_192000),
- .rate_min = 8000,
- .rate_max = 192000,
- .channels_min = 2,
- .channels_max = 64,
- .buffer_bytes_max = 64*2*3*MICROBLAZE_IBL_MAX*MAX_STREAM_BUFFER,
- .period_bytes_min = (2*2*MICROBLAZE_IBL_MIN*2),
- .period_bytes_max = (4*64*MICROBLAZE_IBL_MAX*MAX_STREAM_BUFFER),
- .periods_min = 2,
- .periods_max = MAX_STREAM_BUFFER,
-};
-
-static int lx_set_granularity(struct lx6464es *chip, u32 gran);
-
-
-static int lx_hardware_open(struct lx6464es *chip,
- struct snd_pcm_substream *substream)
-{
- int err = 0;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int channels = runtime->channels;
- int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
-
- snd_pcm_uframes_t period_size = runtime->period_size;
-
- snd_printd(LXP "allocating pipe for %d channels\n", channels);
- err = lx_pipe_allocate(chip, 0, is_capture, channels);
- if (err < 0) {
- snd_printk(KERN_ERR LXP "allocating pipe failed\n");
- return err;
- }
-
- err = lx_set_granularity(chip, period_size);
- if (err < 0) {
- snd_printk(KERN_ERR LXP "setting granularity to %ld failed\n",
- period_size);
- return err;
- }
-
- return 0;
-}
-
-static int lx_hardware_start(struct lx6464es *chip,
- struct snd_pcm_substream *substream)
-{
- int err = 0;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
-
- snd_printd(LXP "setting stream format\n");
- err = lx_stream_set_format(chip, runtime, 0, is_capture);
- if (err < 0) {
- snd_printk(KERN_ERR LXP "setting stream format failed\n");
- return err;
- }
-
- snd_printd(LXP "starting pipe\n");
- err = lx_pipe_start(chip, 0, is_capture);
- if (err < 0) {
- snd_printk(KERN_ERR LXP "starting pipe failed\n");
- return err;
- }
-
- snd_printd(LXP "waiting for pipe to start\n");
- err = lx_pipe_wait_for_start(chip, 0, is_capture);
- if (err < 0) {
- snd_printk(KERN_ERR LXP "waiting for pipe failed\n");
- return err;
- }
-
- return err;
-}
-
-
-static int lx_hardware_stop(struct lx6464es *chip,
- struct snd_pcm_substream *substream)
-{
- int err = 0;
- int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
-
- snd_printd(LXP "pausing pipe\n");
- err = lx_pipe_pause(chip, 0, is_capture);
- if (err < 0) {
- snd_printk(KERN_ERR LXP "pausing pipe failed\n");
- return err;
- }
-
- snd_printd(LXP "waiting for pipe to become idle\n");
- err = lx_pipe_wait_for_idle(chip, 0, is_capture);
- if (err < 0) {
- snd_printk(KERN_ERR LXP "waiting for pipe failed\n");
- return err;
- }
-
- snd_printd(LXP "stopping pipe\n");
- err = lx_pipe_stop(chip, 0, is_capture);
- if (err < 0) {
- snd_printk(LXP "stopping pipe failed\n");
- return err;
- }
-
- return err;
-}
-
-
-static int lx_hardware_close(struct lx6464es *chip,
- struct snd_pcm_substream *substream)
-{
- int err = 0;
- int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
-
- snd_printd(LXP "releasing pipe\n");
- err = lx_pipe_release(chip, 0, is_capture);
- if (err < 0) {
- snd_printk(LXP "releasing pipe failed\n");
- return err;
- }
-
- return err;
-}
-
-
-static int lx_pcm_open(struct snd_pcm_substream *substream)
-{
- struct lx6464es *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err = 0;
- int board_rate;
-
- snd_printdd("->lx_pcm_open\n");
- mutex_lock(&chip->setup_mutex);
-
- /* copy the struct snd_pcm_hardware struct */
- runtime->hw = lx_caps;
-
-#if 0
- /* buffer-size should better be multiple of period-size */
- err = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0) {
- snd_printk(KERN_WARNING LXP "could not constrain periods\n");
- goto exit;
- }
-#endif
-
- /* the clock rate cannot be changed */
- board_rate = chip->board_sample_rate;
- err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE,
- board_rate, board_rate);
-
- if (err < 0) {
- snd_printk(KERN_WARNING LXP "could not constrain periods\n");
- goto exit;
- }
-
- /* constrain period size */
- err = snd_pcm_hw_constraint_minmax(runtime,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- MICROBLAZE_IBL_MIN,
- MICROBLAZE_IBL_MAX);
- if (err < 0) {
- snd_printk(KERN_WARNING LXP
- "could not constrain period size\n");
- goto exit;
- }
-
- snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 32);
-
- snd_pcm_set_sync(substream);
- err = 0;
-
-exit:
- runtime->private_data = chip;
-
- mutex_unlock(&chip->setup_mutex);
- snd_printdd("<-lx_pcm_open, %d\n", err);
- return err;
-}
-
-static int lx_pcm_close(struct snd_pcm_substream *substream)
-{
- int err = 0;
- snd_printdd("->lx_pcm_close\n");
- return err;
-}
-
-static snd_pcm_uframes_t lx_pcm_stream_pointer(struct snd_pcm_substream
- *substream)
-{
- struct lx6464es *chip = snd_pcm_substream_chip(substream);
- snd_pcm_uframes_t pos;
- unsigned long flags;
- int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
-
- struct lx_stream *lx_stream = is_capture ? &chip->capture_stream :
- &chip->playback_stream;
-
- snd_printdd("->lx_pcm_stream_pointer\n");
-
- spin_lock_irqsave(&chip->lock, flags);
- pos = lx_stream->frame_pos * substream->runtime->period_size;
- spin_unlock_irqrestore(&chip->lock, flags);
-
- snd_printdd(LXP "stream_pointer at %ld\n", pos);
- return pos;
-}
-
-static int lx_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct lx6464es *chip = snd_pcm_substream_chip(substream);
- int err = 0;
- const int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
-
- snd_printdd("->lx_pcm_prepare\n");
-
- mutex_lock(&chip->setup_mutex);
-
- if (chip->hardware_running[is_capture]) {
- err = lx_hardware_stop(chip, substream);
- if (err < 0) {
- snd_printk(KERN_ERR LXP "failed to stop hardware. "
- "Error code %d\n", err);
- goto exit;
- }
-
- err = lx_hardware_close(chip, substream);
- if (err < 0) {
- snd_printk(KERN_ERR LXP "failed to close hardware. "
- "Error code %d\n", err);
- goto exit;
- }
- }
-
- snd_printd(LXP "opening hardware\n");
- err = lx_hardware_open(chip, substream);
- if (err < 0) {
- snd_printk(KERN_ERR LXP "failed to open hardware. "
- "Error code %d\n", err);
- goto exit;
- }
-
- err = lx_hardware_start(chip, substream);
- if (err < 0) {
- snd_printk(KERN_ERR LXP "failed to start hardware. "
- "Error code %d\n", err);
- goto exit;
- }
-
- chip->hardware_running[is_capture] = 1;
-
- if (chip->board_sample_rate != substream->runtime->rate) {
- if (!err)
- chip->board_sample_rate = substream->runtime->rate;
- }
-
-exit:
- mutex_unlock(&chip->setup_mutex);
- return err;
-}
-
-static int lx_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params, int is_capture)
-{
- struct lx6464es *chip = snd_pcm_substream_chip(substream);
- int err = 0;
-
- snd_printdd("->lx_pcm_hw_params\n");
-
- mutex_lock(&chip->setup_mutex);
-
- /* set dma buffer */
- err = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-
- if (is_capture)
- chip->capture_stream.stream = substream;
- else
- chip->playback_stream.stream = substream;
-
- mutex_unlock(&chip->setup_mutex);
- return err;
-}
-
-static int lx_pcm_hw_params_playback(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return lx_pcm_hw_params(substream, hw_params, 0);
-}
-
-static int lx_pcm_hw_params_capture(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return lx_pcm_hw_params(substream, hw_params, 1);
-}
-
-static int lx_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct lx6464es *chip = snd_pcm_substream_chip(substream);
- int err = 0;
- int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
-
- snd_printdd("->lx_pcm_hw_free\n");
- mutex_lock(&chip->setup_mutex);
-
- if (chip->hardware_running[is_capture]) {
- err = lx_hardware_stop(chip, substream);
- if (err < 0) {
- snd_printk(KERN_ERR LXP "failed to stop hardware. "
- "Error code %d\n", err);
- goto exit;
- }
-
- err = lx_hardware_close(chip, substream);
- if (err < 0) {
- snd_printk(KERN_ERR LXP "failed to close hardware. "
- "Error code %d\n", err);
- goto exit;
- }
-
- chip->hardware_running[is_capture] = 0;
- }
-
- err = snd_pcm_lib_free_pages(substream);
-
- if (is_capture)
- chip->capture_stream.stream = 0;
- else
- chip->playback_stream.stream = 0;
-
-exit:
- mutex_unlock(&chip->setup_mutex);
- return err;
-}
-
-static void lx_trigger_start(struct lx6464es *chip, struct lx_stream *lx_stream)
-{
- struct snd_pcm_substream *substream = lx_stream->stream;
- const unsigned int is_capture = lx_stream->is_capture;
-
- int err;
-
- const u32 channels = substream->runtime->channels;
- const u32 bytes_per_frame = channels * 3;
- const u32 period_size = substream->runtime->period_size;
- const u32 periods = substream->runtime->periods;
- const u32 period_bytes = period_size * bytes_per_frame;
-
- dma_addr_t buf = substream->dma_buffer.addr;
- int i;
-
- u32 needed, freed;
- u32 size_array[5];
-
- for (i = 0; i != periods; ++i) {
- u32 buffer_index = 0;
-
- err = lx_buffer_ask(chip, 0, is_capture, &needed, &freed,
- size_array);
- snd_printdd(LXP "starting: needed %d, freed %d\n",
- needed, freed);
-
- err = lx_buffer_give(chip, 0, is_capture, period_bytes,
- lower_32_bits(buf), upper_32_bits(buf),
- &buffer_index);
-
- snd_printdd(LXP "starting: buffer index %x on %p (%d bytes)\n",
- buffer_index, (void *)buf, period_bytes);
- buf += period_bytes;
- }
-
- err = lx_buffer_ask(chip, 0, is_capture, &needed, &freed, size_array);
- snd_printdd(LXP "starting: needed %d, freed %d\n", needed, freed);
-
- snd_printd(LXP "starting: starting stream\n");
- err = lx_stream_start(chip, 0, is_capture);
- if (err < 0)
- snd_printk(KERN_ERR LXP "couldn't start stream\n");
- else
- lx_stream->status = LX_STREAM_STATUS_RUNNING;
-
- lx_stream->frame_pos = 0;
-}
-
-static void lx_trigger_stop(struct lx6464es *chip, struct lx_stream *lx_stream)
-{
- const unsigned int is_capture = lx_stream->is_capture;
- int err;
-
- snd_printd(LXP "stopping: stopping stream\n");
- err = lx_stream_stop(chip, 0, is_capture);
- if (err < 0)
- snd_printk(KERN_ERR LXP "couldn't stop stream\n");
- else
- lx_stream->status = LX_STREAM_STATUS_FREE;
-
-}
-
-static void lx_trigger_tasklet_dispatch_stream(struct lx6464es *chip,
- struct lx_stream *lx_stream)
-{
- switch (lx_stream->status) {
- case LX_STREAM_STATUS_SCHEDULE_RUN:
- lx_trigger_start(chip, lx_stream);
- break;
-
- case LX_STREAM_STATUS_SCHEDULE_STOP:
- lx_trigger_stop(chip, lx_stream);
- break;
-
- default:
- break;
- }
-}
-
-static void lx_trigger_tasklet(unsigned long data)
-{
- struct lx6464es *chip = (struct lx6464es *)data;
- unsigned long flags;
-
- snd_printdd("->lx_trigger_tasklet\n");
-
- spin_lock_irqsave(&chip->lock, flags);
- lx_trigger_tasklet_dispatch_stream(chip, &chip->capture_stream);
- lx_trigger_tasklet_dispatch_stream(chip, &chip->playback_stream);
- spin_unlock_irqrestore(&chip->lock, flags);
-}
-
-static int lx_pcm_trigger_dispatch(struct lx6464es *chip,
- struct lx_stream *lx_stream, int cmd)
-{
- int err = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- lx_stream->status = LX_STREAM_STATUS_SCHEDULE_RUN;
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- lx_stream->status = LX_STREAM_STATUS_SCHEDULE_STOP;
- break;
-
- default:
- err = -EINVAL;
- goto exit;
- }
- tasklet_schedule(&chip->trigger_tasklet);
-
-exit:
- return err;
-}
-
-
-static int lx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct lx6464es *chip = snd_pcm_substream_chip(substream);
- const int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
- struct lx_stream *stream = is_capture ? &chip->capture_stream :
- &chip->playback_stream;
-
- snd_printdd("->lx_pcm_trigger\n");
-
- return lx_pcm_trigger_dispatch(chip, stream, cmd);
-}
-
-static int snd_lx6464es_free(struct lx6464es *chip)
-{
- snd_printdd("->snd_lx6464es_free\n");
-
- lx_irq_disable(chip);
-
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
-
- iounmap(chip->port_dsp_bar);
- ioport_unmap(chip->port_plx_remapped);
-
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
-
- kfree(chip);
-
- return 0;
-}
-
-static int snd_lx6464es_dev_free(struct snd_device *device)
-{
- return snd_lx6464es_free(device->device_data);
-}
-
-/* reset the dsp during initialization */
-static int __devinit lx_init_xilinx_reset(struct lx6464es *chip)
-{
- int i;
- u32 plx_reg = lx_plx_reg_read(chip, ePLX_CHIPSC);
-
- snd_printdd("->lx_init_xilinx_reset\n");
-
- /* activate reset of xilinx */
- plx_reg &= ~CHIPSC_RESET_XILINX;
-
- lx_plx_reg_write(chip, ePLX_CHIPSC, plx_reg);
- msleep(1);
-
- lx_plx_reg_write(chip, ePLX_MBOX3, 0);
- msleep(1);
-
- plx_reg |= CHIPSC_RESET_XILINX;
- lx_plx_reg_write(chip, ePLX_CHIPSC, plx_reg);
-
- /* deactivate reset of xilinx */
- for (i = 0; i != 100; ++i) {
- u32 reg_mbox3;
- msleep(10);
- reg_mbox3 = lx_plx_reg_read(chip, ePLX_MBOX3);
- if (reg_mbox3) {
- snd_printd(LXP "xilinx reset done\n");
- snd_printdd(LXP "xilinx took %d loops\n", i);
- break;
- }
- }
-
- /* todo: add some error handling? */
-
- /* clear mr */
- lx_dsp_reg_write(chip, eReg_CSM, 0);
-
- /* le xilinx ES peut ne pas etre encore pret, on attend. */
- msleep(600);
-
- return 0;
-}
-
-static int __devinit lx_init_xilinx_test(struct lx6464es *chip)
-{
- u32 reg;
-
- snd_printdd("->lx_init_xilinx_test\n");
-
- /* TEST if we have access to Xilinx/MicroBlaze */
- lx_dsp_reg_write(chip, eReg_CSM, 0);
-
- reg = lx_dsp_reg_read(chip, eReg_CSM);
-
- if (reg) {
- snd_printk(KERN_ERR LXP "Problem: Reg_CSM %x.\n", reg);
-
- /* PCI9056_SPACE0_REMAP */
- lx_plx_reg_write(chip, ePLX_PCICR, 1);
-
- reg = lx_dsp_reg_read(chip, eReg_CSM);
- if (reg) {
- snd_printk(KERN_ERR LXP "Error: Reg_CSM %x.\n", reg);
- return -EAGAIN; /* seems to be appropriate */
- }
- }
-
- snd_printd(LXP "Xilinx/MicroBlaze access test successful\n");
-
- return 0;
-}
-
-/* initialize ethersound */
-static int __devinit lx_init_ethersound_config(struct lx6464es *chip)
-{
- int i;
- u32 orig_conf_es = lx_dsp_reg_read(chip, eReg_CONFES);
-
- /* configure 64 io channels */
- u32 conf_es = (orig_conf_es & CONFES_READ_PART_MASK) |
- (64 << IOCR_INPUTS_OFFSET) |
- (64 << IOCR_OUTPUTS_OFFSET) |
- (FREQ_RATIO_SINGLE_MODE << FREQ_RATIO_OFFSET);
-
- snd_printdd("->lx_init_ethersound\n");
-
- chip->freq_ratio = FREQ_RATIO_SINGLE_MODE;
-
- /*
- * write it to the card !
- * this actually kicks the ES xilinx, the first time since poweron.
- * the MAC address in the Reg_ADMACESMSB Reg_ADMACESLSB registers
- * is not ready before this is done, and the bit 2 in Reg_CSES is set.
- * */
- lx_dsp_reg_write(chip, eReg_CONFES, conf_es);
-
- for (i = 0; i != 1000; ++i) {
- if (lx_dsp_reg_read(chip, eReg_CSES) & 4) {
- snd_printd(LXP "ethersound initialized after %dms\n",
- i);
- goto ethersound_initialized;
- }
- msleep(1);
- }
- snd_printk(KERN_WARNING LXP
- "ethersound could not be initialized after %dms\n", i);
- return -ETIMEDOUT;
-
- ethersound_initialized:
- snd_printd(LXP "ethersound initialized\n");
- return 0;
-}
-
-static int __devinit lx_init_get_version_features(struct lx6464es *chip)
-{
- u32 dsp_version;
-
- int err;
-
- snd_printdd("->lx_init_get_version_features\n");
-
- err = lx_dsp_get_version(chip, &dsp_version);
-
- if (err == 0) {
- u32 freq;
-
- snd_printk(LXP "DSP version: V%02d.%02d #%d\n",
- (dsp_version>>16) & 0xff, (dsp_version>>8) & 0xff,
- dsp_version & 0xff);
-
- /* later: what firmware version do we expect? */
-
- /* retrieve Play/Rec features */
- /* done here because we may have to handle alternate
- * DSP files. */
- /* later */
-
- /* init the EtherSound sample rate */
- err = lx_dsp_get_clock_frequency(chip, &freq);
- if (err == 0)
- chip->board_sample_rate = freq;
- snd_printd(LXP "actual clock frequency %d\n", freq);
- } else {
- snd_printk(KERN_ERR LXP "DSP corrupted \n");
- err = -EAGAIN;
- }
-
- return err;
-}
-
-static int lx_set_granularity(struct lx6464es *chip, u32 gran)
-{
- int err = 0;
- u32 snapped_gran = MICROBLAZE_IBL_MIN;
-
- snd_printdd("->lx_set_granularity\n");
-
- /* blocksize is a power of 2 */
- while ((snapped_gran < gran) &&
- (snapped_gran < MICROBLAZE_IBL_MAX)) {
- snapped_gran *= 2;
- }
-
- if (snapped_gran == chip->pcm_granularity)
- return 0;
-
- err = lx_dsp_set_granularity(chip, snapped_gran);
- if (err < 0) {
- snd_printk(KERN_WARNING LXP "could not set granularity\n");
- err = -EAGAIN;
- }
-
- if (snapped_gran != gran)
- snd_printk(LXP "snapped blocksize to %d\n", snapped_gran);
-
- snd_printd(LXP "set blocksize on board %d\n", snapped_gran);
- chip->pcm_granularity = snapped_gran;
-
- return err;
-}
-
-/* initialize and test the xilinx dsp chip */
-static int __devinit lx_init_dsp(struct lx6464es *chip)
-{
- int err;
- int i;
-
- snd_printdd("->lx_init_dsp\n");
-
- snd_printd(LXP "initialize board\n");
- err = lx_init_xilinx_reset(chip);
- if (err)
- return err;
-
- snd_printd(LXP "testing board\n");
- err = lx_init_xilinx_test(chip);
- if (err)
- return err;
-
- snd_printd(LXP "initialize ethersound configuration\n");
- err = lx_init_ethersound_config(chip);
- if (err)
- return err;
-
- lx_irq_enable(chip);
-
- /** \todo the mac address should be ready by not, but it isn't,
- * so we wait for it */
- for (i = 0; i != 1000; ++i) {
- err = lx_dsp_get_mac(chip);
- if (err)
- return err;
- if (chip->mac_address[0] || chip->mac_address[1] || chip->mac_address[2] ||
- chip->mac_address[3] || chip->mac_address[4] || chip->mac_address[5])
- goto mac_ready;
- msleep(1);
- }
- return -ETIMEDOUT;
-
-mac_ready:
- snd_printd(LXP "mac address ready read after: %dms\n", i);
- snd_printk(LXP "mac address: %02X.%02X.%02X.%02X.%02X.%02X\n",
- chip->mac_address[0], chip->mac_address[1], chip->mac_address[2],
- chip->mac_address[3], chip->mac_address[4], chip->mac_address[5]);
-
- err = lx_init_get_version_features(chip);
- if (err)
- return err;
-
- lx_set_granularity(chip, MICROBLAZE_IBL_DEFAULT);
-
- chip->playback_mute = 0;
-
- return err;
-}
-
-static struct snd_pcm_ops lx_ops_playback = {
- .open = lx_pcm_open,
- .close = lx_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .prepare = lx_pcm_prepare,
- .hw_params = lx_pcm_hw_params_playback,
- .hw_free = lx_pcm_hw_free,
- .trigger = lx_pcm_trigger,
- .pointer = lx_pcm_stream_pointer,
-};
-
-static struct snd_pcm_ops lx_ops_capture = {
- .open = lx_pcm_open,
- .close = lx_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .prepare = lx_pcm_prepare,
- .hw_params = lx_pcm_hw_params_capture,
- .hw_free = lx_pcm_hw_free,
- .trigger = lx_pcm_trigger,
- .pointer = lx_pcm_stream_pointer,
-};
-
-static int __devinit lx_pcm_create(struct lx6464es *chip)
-{
- int err;
- struct snd_pcm *pcm;
-
- u32 size = 64 * /* channels */
- 3 * /* 24 bit samples */
- MAX_STREAM_BUFFER * /* periods */
- MICROBLAZE_IBL_MAX * /* frames per period */
- 2; /* duplex */
-
- size = PAGE_ALIGN(size);
-
- /* hardcoded device name & channel count */
- err = snd_pcm_new(chip->card, (char *)card_name, 0,
- 1, 1, &pcm);
-
- pcm->private_data = chip;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &lx_ops_playback);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &lx_ops_capture);
-
- pcm->info_flags = 0;
- strcpy(pcm->name, card_name);
-
- err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- size, size);
- if (err < 0)
- return err;
-
- chip->pcm = pcm;
- chip->capture_stream.is_capture = 1;
-
- return 0;
-}
-
-static int lx_control_playback_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int lx_control_playback_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct lx6464es *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = chip->playback_mute;
- return 0;
-}
-
-static int lx_control_playback_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct lx6464es *chip = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- int current_value = chip->playback_mute;
-
- if (current_value != ucontrol->value.integer.value[0]) {
- lx_level_unmute(chip, 0, !current_value);
- chip->playback_mute = !current_value;
- changed = 1;
- }
- return changed;
-}
-
-static struct snd_kcontrol_new lx_control_playback_switch __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Playback Switch",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .private_value = 0,
- .info = lx_control_playback_info,
- .get = lx_control_playback_get,
- .put = lx_control_playback_put
-};
-
-
-
-static void lx_proc_levels_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- u32 levels[64];
- int err;
- int i, j;
- struct lx6464es *chip = entry->private_data;
-
- snd_iprintf(buffer, "capture levels:\n");
- err = lx_level_peaks(chip, 1, 64, levels);
- if (err < 0)
- return;
-
- for (i = 0; i != 8; ++i) {
- for (j = 0; j != 8; ++j)
- snd_iprintf(buffer, "%08x ", levels[i*8+j]);
- snd_iprintf(buffer, "\n");
- }
-
- snd_iprintf(buffer, "\nplayback levels:\n");
-
- err = lx_level_peaks(chip, 0, 64, levels);
- if (err < 0)
- return;
-
- for (i = 0; i != 8; ++i) {
- for (j = 0; j != 8; ++j)
- snd_iprintf(buffer, "%08x ", levels[i*8+j]);
- snd_iprintf(buffer, "\n");
- }
-
- snd_iprintf(buffer, "\n");
-}
-
-static int __devinit lx_proc_create(struct snd_card *card, struct lx6464es *chip)
-{
- struct snd_info_entry *entry;
- int err = snd_card_proc_new(card, "levels", &entry);
- if (err < 0)
- return err;
-
- snd_info_set_text_ops(entry, chip, lx_proc_levels_read);
- return 0;
-}
-
-
-static int __devinit snd_lx6464es_create(struct snd_card *card,
- struct pci_dev *pci,
- struct lx6464es **rchip)
-{
- struct lx6464es *chip;
- int err;
-
- static struct snd_device_ops ops = {
- .dev_free = snd_lx6464es_dev_free,
- };
-
- snd_printdd("->snd_lx6464es_create\n");
-
- *rchip = NULL;
-
- /* enable PCI device */
- err = pci_enable_device(pci);
- if (err < 0)
- return err;
-
- pci_set_master(pci);
-
- /* check if we can restrict PCI DMA transfers to 32 bits */
- err = pci_set_dma_mask(pci, DMA_BIT_MASK(32));
- if (err < 0) {
- snd_printk(KERN_ERR "architecture does not support "
- "32bit PCI busmaster DMA\n");
- pci_disable_device(pci);
- return -ENXIO;
- }
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- err = -ENOMEM;
- goto alloc_failed;
- }
-
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
-
- /* initialize synchronization structs */
- spin_lock_init(&chip->lock);
- spin_lock_init(&chip->msg_lock);
- mutex_init(&chip->setup_mutex);
- tasklet_init(&chip->trigger_tasklet, lx_trigger_tasklet,
- (unsigned long)chip);
- tasklet_init(&chip->tasklet_capture, lx_tasklet_capture,
- (unsigned long)chip);
- tasklet_init(&chip->tasklet_playback, lx_tasklet_playback,
- (unsigned long)chip);
-
- /* request resources */
- err = pci_request_regions(pci, card_name);
- if (err < 0)
- goto request_regions_failed;
-
- /* plx port */
- chip->port_plx = pci_resource_start(pci, 1);
- chip->port_plx_remapped = ioport_map(chip->port_plx,
- pci_resource_len(pci, 1));
-
- /* dsp port */
- chip->port_dsp_bar = pci_ioremap_bar(pci, 2);
-
- err = request_irq(pci->irq, lx_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, chip);
- if (err) {
- snd_printk(KERN_ERR LXP "unable to grab IRQ %d\n", pci->irq);
- goto request_irq_failed;
- }
- chip->irq = pci->irq;
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
- if (err < 0)
- goto device_new_failed;
-
- err = lx_init_dsp(chip);
- if (err < 0) {
- snd_printk(KERN_ERR LXP "error during DSP initialization\n");
- return err;
- }
-
- err = lx_pcm_create(chip);
- if (err < 0)
- return err;
-
- err = lx_proc_create(card, chip);
- if (err < 0)
- return err;
-
- err = snd_ctl_add(card, snd_ctl_new1(&lx_control_playback_switch,
- chip));
- if (err < 0)
- return err;
-
- snd_card_set_dev(card, &pci->dev);
-
- *rchip = chip;
- return 0;
-
-device_new_failed:
- free_irq(pci->irq, chip);
-
-request_irq_failed:
- pci_release_regions(pci);
-
-request_regions_failed:
- kfree(chip);
-
-alloc_failed:
- pci_disable_device(pci);
-
- return err;
-}
-
-static int __devinit snd_lx6464es_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct lx6464es *chip;
- int err;
-
- snd_printdd("->snd_lx6464es_probe\n");
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- err = snd_lx6464es_create(card, pci, &chip);
- if (err < 0) {
- snd_printk(KERN_ERR LXP "error during snd_lx6464es_create\n");
- goto out_free;
- }
-
- strcpy(card->driver, "LX6464ES");
- sprintf(card->id, "LX6464ES_%02X%02X%02X",
- chip->mac_address[3], chip->mac_address[4], chip->mac_address[5]);
-
- sprintf(card->shortname, "LX6464ES %02X.%02X.%02X.%02X.%02X.%02X",
- chip->mac_address[0], chip->mac_address[1], chip->mac_address[2],
- chip->mac_address[3], chip->mac_address[4], chip->mac_address[5]);
-
- sprintf(card->longname, "%s at 0x%lx, 0x%p, irq %i",
- card->shortname, chip->port_plx,
- chip->port_dsp_bar, chip->irq);
-
- err = snd_card_register(card);
- if (err < 0)
- goto out_free;
-
- snd_printdd(LXP "initialization successful\n");
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-
-out_free:
- snd_card_free(card);
- return err;
-
-}
-
-static void __devexit snd_lx6464es_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_lx6464es_ids,
- .probe = snd_lx6464es_probe,
- .remove = __devexit_p(snd_lx6464es_remove),
-};
-
-
-/* module initialization */
-static int __init mod_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit mod_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(mod_init);
-module_exit(mod_exit);
diff --git a/ANDROID_3.4.5/sound/pci/lx6464es/lx6464es.h b/ANDROID_3.4.5/sound/pci/lx6464es/lx6464es.h
deleted file mode 100644
index 6792eda9..00000000
--- a/ANDROID_3.4.5/sound/pci/lx6464es/lx6464es.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* -*- linux-c -*- *
- *
- * ALSA driver for the digigram lx6464es interface
- *
- * Copyright (c) 2009 Tim Blechmann <tim@klingt.org>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-#ifndef LX6464ES_H
-#define LX6464ES_H
-
-#include <linux/spinlock.h>
-#include <linux/atomic.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include "lx_core.h"
-
-#define LXP "LX6464ES: "
-
-enum {
- ES_cmd_free = 0, /* no command executing */
- ES_cmd_processing = 1, /* execution of a read/write command */
- ES_read_pending = 2, /* a asynchron read command is pending */
- ES_read_finishing = 3, /* a read command has finished waiting (set by
- * Interrupt or CancelIrp) */
-};
-
-enum lx_stream_status {
- LX_STREAM_STATUS_FREE,
-/* LX_STREAM_STATUS_OPEN, */
- LX_STREAM_STATUS_SCHEDULE_RUN,
-/* LX_STREAM_STATUS_STARTED, */
- LX_STREAM_STATUS_RUNNING,
- LX_STREAM_STATUS_SCHEDULE_STOP,
-/* LX_STREAM_STATUS_STOPPED, */
-/* LX_STREAM_STATUS_PAUSED */
-};
-
-
-struct lx_stream {
- struct snd_pcm_substream *stream;
- snd_pcm_uframes_t frame_pos;
- enum lx_stream_status status; /* free, open, running, draining
- * pause */
- unsigned int is_capture:1;
-};
-
-
-struct lx6464es {
- struct snd_card *card;
- struct pci_dev *pci;
- int irq;
-
- u8 mac_address[6];
-
- spinlock_t lock; /* interrupt spinlock */
- struct mutex setup_mutex; /* mutex used in hw_params, open
- * and close */
-
- struct tasklet_struct trigger_tasklet; /* trigger tasklet */
- struct tasklet_struct tasklet_capture;
- struct tasklet_struct tasklet_playback;
-
- /* ports */
- unsigned long port_plx; /* io port (size=256) */
- void __iomem *port_plx_remapped; /* remapped plx port */
- void __iomem *port_dsp_bar; /* memory port (32-bit,
- * non-prefetchable,
- * size=8K) */
-
- /* messaging */
- spinlock_t msg_lock; /* message spinlock */
- struct lx_rmh rmh;
-
- /* configuration */
- uint freq_ratio : 2;
- uint playback_mute : 1;
- uint hardware_running[2];
- u32 board_sample_rate; /* sample rate read from
- * board */
- u16 pcm_granularity; /* board blocksize */
-
- /* dma */
- struct snd_dma_buffer capture_dma_buf;
- struct snd_dma_buffer playback_dma_buf;
-
- /* pcm */
- struct snd_pcm *pcm;
-
- /* streams */
- struct lx_stream capture_stream;
- struct lx_stream playback_stream;
-};
-
-
-#endif /* LX6464ES_H */
diff --git a/ANDROID_3.4.5/sound/pci/lx6464es/lx_core.c b/ANDROID_3.4.5/sound/pci/lx6464es/lx_core.c
deleted file mode 100644
index 8c3e7fce..00000000
--- a/ANDROID_3.4.5/sound/pci/lx6464es/lx_core.c
+++ /dev/null
@@ -1,1357 +0,0 @@
-/* -*- linux-c -*- *
- *
- * ALSA driver for the digigram lx6464es interface
- * low-level interface
- *
- * Copyright (c) 2009 Tim Blechmann <tim@klingt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-/* #define RMH_DEBUG 1 */
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-
-#include "lx6464es.h"
-#include "lx_core.h"
-
-/* low-level register access */
-
-static const unsigned long dsp_port_offsets[] = {
- 0,
- 0x400,
- 0x401,
- 0x402,
- 0x403,
- 0x404,
- 0x405,
- 0x406,
- 0x407,
- 0x408,
- 0x409,
- 0x40a,
- 0x40b,
- 0x40c,
-
- 0x410,
- 0x411,
- 0x412,
- 0x413,
- 0x414,
- 0x415,
- 0x416,
-
- 0x420,
- 0x430,
- 0x431,
- 0x432,
- 0x433,
- 0x434,
- 0x440
-};
-
-static void __iomem *lx_dsp_register(struct lx6464es *chip, int port)
-{
- void __iomem *base_address = chip->port_dsp_bar;
- return base_address + dsp_port_offsets[port]*4;
-}
-
-unsigned long lx_dsp_reg_read(struct lx6464es *chip, int port)
-{
- void __iomem *address = lx_dsp_register(chip, port);
- return ioread32(address);
-}
-
-static void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data,
- u32 len)
-{
- u32 __iomem *address = lx_dsp_register(chip, port);
- int i;
-
- /* we cannot use memcpy_fromio */
- for (i = 0; i != len; ++i)
- data[i] = ioread32(address + i);
-}
-
-
-void lx_dsp_reg_write(struct lx6464es *chip, int port, unsigned data)
-{
- void __iomem *address = lx_dsp_register(chip, port);
- iowrite32(data, address);
-}
-
-static void lx_dsp_reg_writebuf(struct lx6464es *chip, int port,
- const u32 *data, u32 len)
-{
- u32 __iomem *address = lx_dsp_register(chip, port);
- int i;
-
- /* we cannot use memcpy_to */
- for (i = 0; i != len; ++i)
- iowrite32(data[i], address + i);
-}
-
-
-static const unsigned long plx_port_offsets[] = {
- 0x04,
- 0x40,
- 0x44,
- 0x48,
- 0x4c,
- 0x50,
- 0x54,
- 0x58,
- 0x5c,
- 0x64,
- 0x68,
- 0x6C
-};
-
-static void __iomem *lx_plx_register(struct lx6464es *chip, int port)
-{
- void __iomem *base_address = chip->port_plx_remapped;
- return base_address + plx_port_offsets[port];
-}
-
-unsigned long lx_plx_reg_read(struct lx6464es *chip, int port)
-{
- void __iomem *address = lx_plx_register(chip, port);
- return ioread32(address);
-}
-
-void lx_plx_reg_write(struct lx6464es *chip, int port, u32 data)
-{
- void __iomem *address = lx_plx_register(chip, port);
- iowrite32(data, address);
-}
-
-u32 lx_plx_mbox_read(struct lx6464es *chip, int mbox_nr)
-{
- int index;
-
- switch (mbox_nr) {
- case 1:
- index = ePLX_MBOX1; break;
- case 2:
- index = ePLX_MBOX2; break;
- case 3:
- index = ePLX_MBOX3; break;
- case 4:
- index = ePLX_MBOX4; break;
- case 5:
- index = ePLX_MBOX5; break;
- case 6:
- index = ePLX_MBOX6; break;
- case 7:
- index = ePLX_MBOX7; break;
- case 0: /* reserved for HF flags */
- snd_BUG();
- default:
- return 0xdeadbeef;
- }
-
- return lx_plx_reg_read(chip, index);
-}
-
-int lx_plx_mbox_write(struct lx6464es *chip, int mbox_nr, u32 value)
-{
- int index = -1;
-
- switch (mbox_nr) {
- case 1:
- index = ePLX_MBOX1; break;
- case 3:
- index = ePLX_MBOX3; break;
- case 4:
- index = ePLX_MBOX4; break;
- case 5:
- index = ePLX_MBOX5; break;
- case 6:
- index = ePLX_MBOX6; break;
- case 7:
- index = ePLX_MBOX7; break;
- case 0: /* reserved for HF flags */
- case 2: /* reserved for Pipe States
- * the DSP keeps an image of it */
- snd_BUG();
- return -EBADRQC;
- }
-
- lx_plx_reg_write(chip, index, value);
- return 0;
-}
-
-
-/* rmh */
-
-#ifdef CONFIG_SND_DEBUG
-#define CMD_NAME(a) a
-#else
-#define CMD_NAME(a) NULL
-#endif
-
-#define Reg_CSM_MR 0x00000002
-#define Reg_CSM_MC 0x00000001
-
-struct dsp_cmd_info {
- u32 dcCodeOp; /* Op Code of the command (usually 1st 24-bits
- * word).*/
- u16 dcCmdLength; /* Command length in words of 24 bits.*/
- u16 dcStatusType; /* Status type: 0 for fixed length, 1 for
- * random. */
- u16 dcStatusLength; /* Status length (if fixed).*/
- char *dcOpName;
-};
-
-/*
- Initialization and control data for the Microblaze interface
- - OpCode:
- the opcode field of the command set at the proper offset
- - CmdLength
- the number of command words
- - StatusType
- offset in the status registers: 0 means that the return value may be
- different from 0, and must be read
- - StatusLength
- the number of status words (in addition to the return value)
-*/
-
-static struct dsp_cmd_info dsp_commands[] =
-{
- { (CMD_00_INFO_DEBUG << OPCODE_OFFSET) , 1 /*custom*/
- , 1 , 0 /**/ , CMD_NAME("INFO_DEBUG") },
- { (CMD_01_GET_SYS_CFG << OPCODE_OFFSET) , 1 /**/
- , 1 , 2 /**/ , CMD_NAME("GET_SYS_CFG") },
- { (CMD_02_SET_GRANULARITY << OPCODE_OFFSET) , 1 /**/
- , 1 , 0 /**/ , CMD_NAME("SET_GRANULARITY") },
- { (CMD_03_SET_TIMER_IRQ << OPCODE_OFFSET) , 1 /**/
- , 1 , 0 /**/ , CMD_NAME("SET_TIMER_IRQ") },
- { (CMD_04_GET_EVENT << OPCODE_OFFSET) , 1 /**/
- , 1 , 0 /*up to 10*/ , CMD_NAME("GET_EVENT") },
- { (CMD_05_GET_PIPES << OPCODE_OFFSET) , 1 /**/
- , 1 , 2 /*up to 4*/ , CMD_NAME("GET_PIPES") },
- { (CMD_06_ALLOCATE_PIPE << OPCODE_OFFSET) , 1 /**/
- , 0 , 0 /**/ , CMD_NAME("ALLOCATE_PIPE") },
- { (CMD_07_RELEASE_PIPE << OPCODE_OFFSET) , 1 /**/
- , 0 , 0 /**/ , CMD_NAME("RELEASE_PIPE") },
- { (CMD_08_ASK_BUFFERS << OPCODE_OFFSET) , 1 /**/
- , 1 , MAX_STREAM_BUFFER , CMD_NAME("ASK_BUFFERS") },
- { (CMD_09_STOP_PIPE << OPCODE_OFFSET) , 1 /**/
- , 0 , 0 /*up to 2*/ , CMD_NAME("STOP_PIPE") },
- { (CMD_0A_GET_PIPE_SPL_COUNT << OPCODE_OFFSET) , 1 /**/
- , 1 , 1 /*up to 2*/ , CMD_NAME("GET_PIPE_SPL_COUNT") },
- { (CMD_0B_TOGGLE_PIPE_STATE << OPCODE_OFFSET) , 1 /*up to 5*/
- , 1 , 0 /**/ , CMD_NAME("TOGGLE_PIPE_STATE") },
- { (CMD_0C_DEF_STREAM << OPCODE_OFFSET) , 1 /*up to 4*/
- , 1 , 0 /**/ , CMD_NAME("DEF_STREAM") },
- { (CMD_0D_SET_MUTE << OPCODE_OFFSET) , 3 /**/
- , 1 , 0 /**/ , CMD_NAME("SET_MUTE") },
- { (CMD_0E_GET_STREAM_SPL_COUNT << OPCODE_OFFSET) , 1/**/
- , 1 , 2 /**/ , CMD_NAME("GET_STREAM_SPL_COUNT") },
- { (CMD_0F_UPDATE_BUFFER << OPCODE_OFFSET) , 3 /*up to 4*/
- , 0 , 1 /**/ , CMD_NAME("UPDATE_BUFFER") },
- { (CMD_10_GET_BUFFER << OPCODE_OFFSET) , 1 /**/
- , 1 , 4 /**/ , CMD_NAME("GET_BUFFER") },
- { (CMD_11_CANCEL_BUFFER << OPCODE_OFFSET) , 1 /**/
- , 1 , 1 /*up to 4*/ , CMD_NAME("CANCEL_BUFFER") },
- { (CMD_12_GET_PEAK << OPCODE_OFFSET) , 1 /**/
- , 1 , 1 /**/ , CMD_NAME("GET_PEAK") },
- { (CMD_13_SET_STREAM_STATE << OPCODE_OFFSET) , 1 /**/
- , 1 , 0 /**/ , CMD_NAME("SET_STREAM_STATE") },
-};
-
-static void lx_message_init(struct lx_rmh *rmh, enum cmd_mb_opcodes cmd)
-{
- snd_BUG_ON(cmd >= CMD_14_INVALID);
-
- rmh->cmd[0] = dsp_commands[cmd].dcCodeOp;
- rmh->cmd_len = dsp_commands[cmd].dcCmdLength;
- rmh->stat_len = dsp_commands[cmd].dcStatusLength;
- rmh->dsp_stat = dsp_commands[cmd].dcStatusType;
- rmh->cmd_idx = cmd;
- memset(&rmh->cmd[1], 0, (REG_CRM_NUMBER - 1) * sizeof(u32));
-
-#ifdef CONFIG_SND_DEBUG
- memset(rmh->stat, 0, REG_CRM_NUMBER * sizeof(u32));
-#endif
-#ifdef RMH_DEBUG
- rmh->cmd_idx = cmd;
-#endif
-}
-
-#ifdef RMH_DEBUG
-#define LXRMH "lx6464es rmh: "
-static void lx_message_dump(struct lx_rmh *rmh)
-{
- u8 idx = rmh->cmd_idx;
- int i;
-
- snd_printk(LXRMH "command %s\n", dsp_commands[idx].dcOpName);
-
- for (i = 0; i != rmh->cmd_len; ++i)
- snd_printk(LXRMH "\tcmd[%d] %08x\n", i, rmh->cmd[i]);
-
- for (i = 0; i != rmh->stat_len; ++i)
- snd_printk(LXRMH "\tstat[%d]: %08x\n", i, rmh->stat[i]);
- snd_printk("\n");
-}
-#else
-static inline void lx_message_dump(struct lx_rmh *rmh)
-{}
-#endif
-
-
-
-/* sleep 500 - 100 = 400 times 100us -> the timeout is >= 40 ms */
-#define XILINX_TIMEOUT_MS 40
-#define XILINX_POLL_NO_SLEEP 100
-#define XILINX_POLL_ITERATIONS 150
-
-
-static int lx_message_send_atomic(struct lx6464es *chip, struct lx_rmh *rmh)
-{
- u32 reg = ED_DSP_TIMED_OUT;
- int dwloop;
-
- if (lx_dsp_reg_read(chip, eReg_CSM) & (Reg_CSM_MC | Reg_CSM_MR)) {
- snd_printk(KERN_ERR LXP "PIOSendMessage eReg_CSM %x\n", reg);
- return -EBUSY;
- }
-
- /* write command */
- lx_dsp_reg_writebuf(chip, eReg_CRM1, rmh->cmd, rmh->cmd_len);
-
- /* MicoBlaze gogogo */
- lx_dsp_reg_write(chip, eReg_CSM, Reg_CSM_MC);
-
- /* wait for device to answer */
- for (dwloop = 0; dwloop != XILINX_TIMEOUT_MS * 1000; ++dwloop) {
- if (lx_dsp_reg_read(chip, eReg_CSM) & Reg_CSM_MR) {
- if (rmh->dsp_stat == 0)
- reg = lx_dsp_reg_read(chip, eReg_CRM1);
- else
- reg = 0;
- goto polling_successful;
- } else
- udelay(1);
- }
- snd_printk(KERN_WARNING LXP "TIMEOUT lx_message_send_atomic! "
- "polling failed\n");
-
-polling_successful:
- if ((reg & ERROR_VALUE) == 0) {
- /* read response */
- if (rmh->stat_len) {
- snd_BUG_ON(rmh->stat_len >= (REG_CRM_NUMBER-1));
- lx_dsp_reg_readbuf(chip, eReg_CRM2, rmh->stat,
- rmh->stat_len);
- }
- } else
- snd_printk(LXP "rmh error: %08x\n", reg);
-
- /* clear Reg_CSM_MR */
- lx_dsp_reg_write(chip, eReg_CSM, 0);
-
- switch (reg) {
- case ED_DSP_TIMED_OUT:
- snd_printk(KERN_WARNING LXP "lx_message_send: dsp timeout\n");
- return -ETIMEDOUT;
-
- case ED_DSP_CRASHED:
- snd_printk(KERN_WARNING LXP "lx_message_send: dsp crashed\n");
- return -EAGAIN;
- }
-
- lx_message_dump(rmh);
-
- return reg;
-}
-
-
-/* low-level dsp access */
-int __devinit lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version)
-{
- u16 ret;
- unsigned long flags;
-
- spin_lock_irqsave(&chip->msg_lock, flags);
-
- lx_message_init(&chip->rmh, CMD_01_GET_SYS_CFG);
- ret = lx_message_send_atomic(chip, &chip->rmh);
-
- *rdsp_version = chip->rmh.stat[1];
- spin_unlock_irqrestore(&chip->msg_lock, flags);
- return ret;
-}
-
-int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq)
-{
- u16 ret = 0;
- unsigned long flags;
- u32 freq_raw = 0;
- u32 freq = 0;
- u32 frequency = 0;
-
- spin_lock_irqsave(&chip->msg_lock, flags);
-
- lx_message_init(&chip->rmh, CMD_01_GET_SYS_CFG);
- ret = lx_message_send_atomic(chip, &chip->rmh);
-
- if (ret == 0) {
- freq_raw = chip->rmh.stat[0] >> FREQ_FIELD_OFFSET;
- freq = freq_raw & XES_FREQ_COUNT8_MASK;
-
- if ((freq < XES_FREQ_COUNT8_48_MAX) ||
- (freq > XES_FREQ_COUNT8_44_MIN))
- frequency = 0; /* unknown */
- else if (freq >= XES_FREQ_COUNT8_44_MAX)
- frequency = 44100;
- else
- frequency = 48000;
- }
-
- spin_unlock_irqrestore(&chip->msg_lock, flags);
-
- *rfreq = frequency * chip->freq_ratio;
-
- return ret;
-}
-
-int lx_dsp_get_mac(struct lx6464es *chip)
-{
- u32 macmsb, maclsb;
-
- macmsb = lx_dsp_reg_read(chip, eReg_ADMACESMSB) & 0x00FFFFFF;
- maclsb = lx_dsp_reg_read(chip, eReg_ADMACESLSB) & 0x00FFFFFF;
-
- /* todo: endianess handling */
- chip->mac_address[5] = ((u8 *)(&maclsb))[0];
- chip->mac_address[4] = ((u8 *)(&maclsb))[1];
- chip->mac_address[3] = ((u8 *)(&maclsb))[2];
- chip->mac_address[2] = ((u8 *)(&macmsb))[0];
- chip->mac_address[1] = ((u8 *)(&macmsb))[1];
- chip->mac_address[0] = ((u8 *)(&macmsb))[2];
-
- return 0;
-}
-
-
-int lx_dsp_set_granularity(struct lx6464es *chip, u32 gran)
-{
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&chip->msg_lock, flags);
-
- lx_message_init(&chip->rmh, CMD_02_SET_GRANULARITY);
- chip->rmh.cmd[0] |= gran;
-
- ret = lx_message_send_atomic(chip, &chip->rmh);
- spin_unlock_irqrestore(&chip->msg_lock, flags);
- return ret;
-}
-
-int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data)
-{
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&chip->msg_lock, flags);
-
- lx_message_init(&chip->rmh, CMD_04_GET_EVENT);
- chip->rmh.stat_len = 9; /* we don't necessarily need the full length */
-
- ret = lx_message_send_atomic(chip, &chip->rmh);
-
- if (!ret)
- memcpy(data, chip->rmh.stat, chip->rmh.stat_len * sizeof(u32));
-
- spin_unlock_irqrestore(&chip->msg_lock, flags);
- return ret;
-}
-
-#define CSES_TIMEOUT 100 /* microseconds */
-#define CSES_CE 0x0001
-#define CSES_BROADCAST 0x0002
-#define CSES_UPDATE_LDSV 0x0004
-
-int lx_dsp_es_check_pipeline(struct lx6464es *chip)
-{
- int i;
-
- for (i = 0; i != CSES_TIMEOUT; ++i) {
- /*
- * le bit CSES_UPDATE_LDSV est à 1 dés que le macprog
- * est pret. il re-passe à 0 lorsque le premier read a
- * été fait. pour l'instant on retire le test car ce bit
- * passe a 1 environ 200 à 400 ms aprés que le registre
- * confES à été écrit (kick du xilinx ES).
- *
- * On ne teste que le bit CE.
- * */
-
- u32 cses = lx_dsp_reg_read(chip, eReg_CSES);
-
- if ((cses & CSES_CE) == 0)
- return 0;
-
- udelay(1);
- }
-
- return -ETIMEDOUT;
-}
-
-
-#define PIPE_INFO_TO_CMD(capture, pipe) \
- ((u32)((u32)(pipe) | ((capture) ? ID_IS_CAPTURE : 0L)) << ID_OFFSET)
-
-
-
-/* low-level pipe handling */
-int lx_pipe_allocate(struct lx6464es *chip, u32 pipe, int is_capture,
- int channels)
-{
- int err;
- unsigned long flags;
-
- u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
-
- spin_lock_irqsave(&chip->msg_lock, flags);
- lx_message_init(&chip->rmh, CMD_06_ALLOCATE_PIPE);
-
- chip->rmh.cmd[0] |= pipe_cmd;
- chip->rmh.cmd[0] |= channels;
-
- err = lx_message_send_atomic(chip, &chip->rmh);
- spin_unlock_irqrestore(&chip->msg_lock, flags);
-
- if (err != 0)
- snd_printk(KERN_ERR "lx6464es: could not allocate pipe\n");
-
- return err;
-}
-
-int lx_pipe_release(struct lx6464es *chip, u32 pipe, int is_capture)
-{
- int err;
- unsigned long flags;
-
- u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
-
- spin_lock_irqsave(&chip->msg_lock, flags);
- lx_message_init(&chip->rmh, CMD_07_RELEASE_PIPE);
-
- chip->rmh.cmd[0] |= pipe_cmd;
-
- err = lx_message_send_atomic(chip, &chip->rmh);
- spin_unlock_irqrestore(&chip->msg_lock, flags);
-
- return err;
-}
-
-int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture,
- u32 *r_needed, u32 *r_freed, u32 *size_array)
-{
- int err;
- unsigned long flags;
-
- u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
-
-#ifdef CONFIG_SND_DEBUG
- if (size_array)
- memset(size_array, 0, sizeof(u32)*MAX_STREAM_BUFFER);
-#endif
-
- *r_needed = 0;
- *r_freed = 0;
-
- spin_lock_irqsave(&chip->msg_lock, flags);
- lx_message_init(&chip->rmh, CMD_08_ASK_BUFFERS);
-
- chip->rmh.cmd[0] |= pipe_cmd;
-
- err = lx_message_send_atomic(chip, &chip->rmh);
-
- if (!err) {
- int i;
- for (i = 0; i < MAX_STREAM_BUFFER; ++i) {
- u32 stat = chip->rmh.stat[i];
- if (stat & (BF_EOB << BUFF_FLAGS_OFFSET)) {
- /* finished */
- *r_freed += 1;
- if (size_array)
- size_array[i] = stat & MASK_DATA_SIZE;
- } else if ((stat & (BF_VALID << BUFF_FLAGS_OFFSET))
- == 0)
- /* free */
- *r_needed += 1;
- }
-
-#if 0
- snd_printdd(LXP "CMD_08_ASK_BUFFERS: needed %d, freed %d\n",
- *r_needed, *r_freed);
- for (i = 0; i < MAX_STREAM_BUFFER; ++i) {
- for (i = 0; i != chip->rmh.stat_len; ++i)
- snd_printdd(" stat[%d]: %x, %x\n", i,
- chip->rmh.stat[i],
- chip->rmh.stat[i] & MASK_DATA_SIZE);
- }
-#endif
- }
-
- spin_unlock_irqrestore(&chip->msg_lock, flags);
- return err;
-}
-
-
-int lx_pipe_stop(struct lx6464es *chip, u32 pipe, int is_capture)
-{
- int err;
- unsigned long flags;
-
- u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
-
- spin_lock_irqsave(&chip->msg_lock, flags);
- lx_message_init(&chip->rmh, CMD_09_STOP_PIPE);
-
- chip->rmh.cmd[0] |= pipe_cmd;
-
- err = lx_message_send_atomic(chip, &chip->rmh);
-
- spin_unlock_irqrestore(&chip->msg_lock, flags);
- return err;
-}
-
-static int lx_pipe_toggle_state(struct lx6464es *chip, u32 pipe, int is_capture)
-{
- int err;
- unsigned long flags;
-
- u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
-
- spin_lock_irqsave(&chip->msg_lock, flags);
- lx_message_init(&chip->rmh, CMD_0B_TOGGLE_PIPE_STATE);
-
- chip->rmh.cmd[0] |= pipe_cmd;
-
- err = lx_message_send_atomic(chip, &chip->rmh);
-
- spin_unlock_irqrestore(&chip->msg_lock, flags);
- return err;
-}
-
-
-int lx_pipe_start(struct lx6464es *chip, u32 pipe, int is_capture)
-{
- int err;
-
- err = lx_pipe_wait_for_idle(chip, pipe, is_capture);
- if (err < 0)
- return err;
-
- err = lx_pipe_toggle_state(chip, pipe, is_capture);
-
- return err;
-}
-
-int lx_pipe_pause(struct lx6464es *chip, u32 pipe, int is_capture)
-{
- int err = 0;
-
- err = lx_pipe_wait_for_start(chip, pipe, is_capture);
- if (err < 0)
- return err;
-
- err = lx_pipe_toggle_state(chip, pipe, is_capture);
-
- return err;
-}
-
-
-int lx_pipe_sample_count(struct lx6464es *chip, u32 pipe, int is_capture,
- u64 *rsample_count)
-{
- int err;
- unsigned long flags;
-
- u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
-
- spin_lock_irqsave(&chip->msg_lock, flags);
- lx_message_init(&chip->rmh, CMD_0A_GET_PIPE_SPL_COUNT);
-
- chip->rmh.cmd[0] |= pipe_cmd;
- chip->rmh.stat_len = 2; /* need all words here! */
-
- err = lx_message_send_atomic(chip, &chip->rmh); /* don't sleep! */
-
- if (err != 0)
- snd_printk(KERN_ERR
- "lx6464es: could not query pipe's sample count\n");
- else {
- *rsample_count = ((u64)(chip->rmh.stat[0] & MASK_SPL_COUNT_HI)
- << 24) /* hi part */
- + chip->rmh.stat[1]; /* lo part */
- }
-
- spin_unlock_irqrestore(&chip->msg_lock, flags);
- return err;
-}
-
-int lx_pipe_state(struct lx6464es *chip, u32 pipe, int is_capture, u16 *rstate)
-{
- int err;
- unsigned long flags;
-
- u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
-
- spin_lock_irqsave(&chip->msg_lock, flags);
- lx_message_init(&chip->rmh, CMD_0A_GET_PIPE_SPL_COUNT);
-
- chip->rmh.cmd[0] |= pipe_cmd;
-
- err = lx_message_send_atomic(chip, &chip->rmh);
-
- if (err != 0)
- snd_printk(KERN_ERR "lx6464es: could not query pipe's state\n");
- else
- *rstate = (chip->rmh.stat[0] >> PSTATE_OFFSET) & 0x0F;
-
- spin_unlock_irqrestore(&chip->msg_lock, flags);
- return err;
-}
-
-static int lx_pipe_wait_for_state(struct lx6464es *chip, u32 pipe,
- int is_capture, u16 state)
-{
- int i;
-
- /* max 2*PCMOnlyGranularity = 2*1024 at 44100 = < 50 ms:
- * timeout 50 ms */
- for (i = 0; i != 50; ++i) {
- u16 current_state;
- int err = lx_pipe_state(chip, pipe, is_capture, &current_state);
-
- if (err < 0)
- return err;
-
- if (current_state == state)
- return 0;
-
- mdelay(1);
- }
-
- return -ETIMEDOUT;
-}
-
-int lx_pipe_wait_for_start(struct lx6464es *chip, u32 pipe, int is_capture)
-{
- return lx_pipe_wait_for_state(chip, pipe, is_capture, PSTATE_RUN);
-}
-
-int lx_pipe_wait_for_idle(struct lx6464es *chip, u32 pipe, int is_capture)
-{
- return lx_pipe_wait_for_state(chip, pipe, is_capture, PSTATE_IDLE);
-}
-
-/* low-level stream handling */
-int lx_stream_set_state(struct lx6464es *chip, u32 pipe,
- int is_capture, enum stream_state_t state)
-{
- int err;
- unsigned long flags;
-
- u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
-
- spin_lock_irqsave(&chip->msg_lock, flags);
- lx_message_init(&chip->rmh, CMD_13_SET_STREAM_STATE);
-
- chip->rmh.cmd[0] |= pipe_cmd;
- chip->rmh.cmd[0] |= state;
-
- err = lx_message_send_atomic(chip, &chip->rmh);
- spin_unlock_irqrestore(&chip->msg_lock, flags);
-
- return err;
-}
-
-int lx_stream_set_format(struct lx6464es *chip, struct snd_pcm_runtime *runtime,
- u32 pipe, int is_capture)
-{
- int err;
- unsigned long flags;
-
- u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
-
- u32 channels = runtime->channels;
-
- if (runtime->channels != channels)
- snd_printk(KERN_ERR LXP "channel count mismatch: %d vs %d",
- runtime->channels, channels);
-
- spin_lock_irqsave(&chip->msg_lock, flags);
- lx_message_init(&chip->rmh, CMD_0C_DEF_STREAM);
-
- chip->rmh.cmd[0] |= pipe_cmd;
-
- if (runtime->sample_bits == 16)
- /* 16 bit format */
- chip->rmh.cmd[0] |= (STREAM_FMT_16b << STREAM_FMT_OFFSET);
-
- if (snd_pcm_format_little_endian(runtime->format))
- /* little endian/intel format */
- chip->rmh.cmd[0] |= (STREAM_FMT_intel << STREAM_FMT_OFFSET);
-
- chip->rmh.cmd[0] |= channels-1;
-
- err = lx_message_send_atomic(chip, &chip->rmh);
- spin_unlock_irqrestore(&chip->msg_lock, flags);
-
- return err;
-}
-
-int lx_stream_state(struct lx6464es *chip, u32 pipe, int is_capture,
- int *rstate)
-{
- int err;
- unsigned long flags;
-
- u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
-
- spin_lock_irqsave(&chip->msg_lock, flags);
- lx_message_init(&chip->rmh, CMD_0E_GET_STREAM_SPL_COUNT);
-
- chip->rmh.cmd[0] |= pipe_cmd;
-
- err = lx_message_send_atomic(chip, &chip->rmh);
-
- *rstate = (chip->rmh.stat[0] & SF_START) ? START_STATE : PAUSE_STATE;
-
- spin_unlock_irqrestore(&chip->msg_lock, flags);
- return err;
-}
-
-int lx_stream_sample_position(struct lx6464es *chip, u32 pipe, int is_capture,
- u64 *r_bytepos)
-{
- int err;
- unsigned long flags;
-
- u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
-
- spin_lock_irqsave(&chip->msg_lock, flags);
- lx_message_init(&chip->rmh, CMD_0E_GET_STREAM_SPL_COUNT);
-
- chip->rmh.cmd[0] |= pipe_cmd;
-
- err = lx_message_send_atomic(chip, &chip->rmh);
-
- *r_bytepos = ((u64) (chip->rmh.stat[0] & MASK_SPL_COUNT_HI)
- << 32) /* hi part */
- + chip->rmh.stat[1]; /* lo part */
-
- spin_unlock_irqrestore(&chip->msg_lock, flags);
- return err;
-}
-
-/* low-level buffer handling */
-int lx_buffer_give(struct lx6464es *chip, u32 pipe, int is_capture,
- u32 buffer_size, u32 buf_address_lo, u32 buf_address_hi,
- u32 *r_buffer_index)
-{
- int err;
- unsigned long flags;
-
- u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
-
- spin_lock_irqsave(&chip->msg_lock, flags);
- lx_message_init(&chip->rmh, CMD_0F_UPDATE_BUFFER);
-
- chip->rmh.cmd[0] |= pipe_cmd;
- chip->rmh.cmd[0] |= BF_NOTIFY_EOB; /* request interrupt notification */
-
- /* todo: pause request, circular buffer */
-
- chip->rmh.cmd[1] = buffer_size & MASK_DATA_SIZE;
- chip->rmh.cmd[2] = buf_address_lo;
-
- if (buf_address_hi) {
- chip->rmh.cmd_len = 4;
- chip->rmh.cmd[3] = buf_address_hi;
- chip->rmh.cmd[0] |= BF_64BITS_ADR;
- }
-
- err = lx_message_send_atomic(chip, &chip->rmh);
-
- if (err == 0) {
- *r_buffer_index = chip->rmh.stat[0];
- goto done;
- }
-
- if (err == EB_RBUFFERS_TABLE_OVERFLOW)
- snd_printk(LXP "lx_buffer_give EB_RBUFFERS_TABLE_OVERFLOW\n");
-
- if (err == EB_INVALID_STREAM)
- snd_printk(LXP "lx_buffer_give EB_INVALID_STREAM\n");
-
- if (err == EB_CMD_REFUSED)
- snd_printk(LXP "lx_buffer_give EB_CMD_REFUSED\n");
-
- done:
- spin_unlock_irqrestore(&chip->msg_lock, flags);
- return err;
-}
-
-int lx_buffer_free(struct lx6464es *chip, u32 pipe, int is_capture,
- u32 *r_buffer_size)
-{
- int err;
- unsigned long flags;
-
- u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
-
- spin_lock_irqsave(&chip->msg_lock, flags);
- lx_message_init(&chip->rmh, CMD_11_CANCEL_BUFFER);
-
- chip->rmh.cmd[0] |= pipe_cmd;
- chip->rmh.cmd[0] |= MASK_BUFFER_ID; /* ask for the current buffer: the
- * microblaze will seek for it */
-
- err = lx_message_send_atomic(chip, &chip->rmh);
-
- if (err == 0)
- *r_buffer_size = chip->rmh.stat[0] & MASK_DATA_SIZE;
-
- spin_unlock_irqrestore(&chip->msg_lock, flags);
- return err;
-}
-
-int lx_buffer_cancel(struct lx6464es *chip, u32 pipe, int is_capture,
- u32 buffer_index)
-{
- int err;
- unsigned long flags;
-
- u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
-
- spin_lock_irqsave(&chip->msg_lock, flags);
- lx_message_init(&chip->rmh, CMD_11_CANCEL_BUFFER);
-
- chip->rmh.cmd[0] |= pipe_cmd;
- chip->rmh.cmd[0] |= buffer_index;
-
- err = lx_message_send_atomic(chip, &chip->rmh);
-
- spin_unlock_irqrestore(&chip->msg_lock, flags);
- return err;
-}
-
-
-/* low-level gain/peak handling
- *
- * \todo: can we unmute capture/playback channels independently?
- *
- * */
-int lx_level_unmute(struct lx6464es *chip, int is_capture, int unmute)
-{
- int err;
- unsigned long flags;
-
- /* bit set to 1: channel muted */
- u64 mute_mask = unmute ? 0 : 0xFFFFFFFFFFFFFFFFLLU;
-
- spin_lock_irqsave(&chip->msg_lock, flags);
- lx_message_init(&chip->rmh, CMD_0D_SET_MUTE);
-
- chip->rmh.cmd[0] |= PIPE_INFO_TO_CMD(is_capture, 0);
-
- chip->rmh.cmd[1] = (u32)(mute_mask >> (u64)32); /* hi part */
- chip->rmh.cmd[2] = (u32)(mute_mask & (u64)0xFFFFFFFF); /* lo part */
-
- snd_printk("mute %x %x %x\n", chip->rmh.cmd[0], chip->rmh.cmd[1],
- chip->rmh.cmd[2]);
-
- err = lx_message_send_atomic(chip, &chip->rmh);
-
- spin_unlock_irqrestore(&chip->msg_lock, flags);
- return err;
-}
-
-static u32 peak_map[] = {
- 0x00000109, /* -90.308dB */
- 0x0000083B, /* -72.247dB */
- 0x000020C4, /* -60.205dB */
- 0x00008273, /* -48.030dB */
- 0x00020756, /* -36.005dB */
- 0x00040C37, /* -30.001dB */
- 0x00081385, /* -24.002dB */
- 0x00101D3F, /* -18.000dB */
- 0x0016C310, /* -15.000dB */
- 0x002026F2, /* -12.001dB */
- 0x002D6A86, /* -9.000dB */
- 0x004026E6, /* -6.004dB */
- 0x005A9DF6, /* -3.000dB */
- 0x0065AC8B, /* -2.000dB */
- 0x00721481, /* -1.000dB */
- 0x007FFFFF, /* FS */
-};
-
-int lx_level_peaks(struct lx6464es *chip, int is_capture, int channels,
- u32 *r_levels)
-{
- int err = 0;
- unsigned long flags;
- int i;
- spin_lock_irqsave(&chip->msg_lock, flags);
-
- for (i = 0; i < channels; i += 4) {
- u32 s0, s1, s2, s3;
-
- lx_message_init(&chip->rmh, CMD_12_GET_PEAK);
- chip->rmh.cmd[0] |= PIPE_INFO_TO_CMD(is_capture, i);
-
- err = lx_message_send_atomic(chip, &chip->rmh);
-
- if (err == 0) {
- s0 = peak_map[chip->rmh.stat[0] & 0x0F];
- s1 = peak_map[(chip->rmh.stat[0] >> 4) & 0xf];
- s2 = peak_map[(chip->rmh.stat[0] >> 8) & 0xf];
- s3 = peak_map[(chip->rmh.stat[0] >> 12) & 0xf];
- } else
- s0 = s1 = s2 = s3 = 0;
-
- r_levels[0] = s0;
- r_levels[1] = s1;
- r_levels[2] = s2;
- r_levels[3] = s3;
-
- r_levels += 4;
- }
-
- spin_unlock_irqrestore(&chip->msg_lock, flags);
- return err;
-}
-
-/* interrupt handling */
-#define PCX_IRQ_NONE 0
-#define IRQCS_ACTIVE_PCIDB 0x00002000L /* Bit nø 13 */
-#define IRQCS_ENABLE_PCIIRQ 0x00000100L /* Bit nø 08 */
-#define IRQCS_ENABLE_PCIDB 0x00000200L /* Bit nø 09 */
-
-static u32 lx_interrupt_test_ack(struct lx6464es *chip)
-{
- u32 irqcs = lx_plx_reg_read(chip, ePLX_IRQCS);
-
- /* Test if PCI Doorbell interrupt is active */
- if (irqcs & IRQCS_ACTIVE_PCIDB) {
- u32 temp;
- irqcs = PCX_IRQ_NONE;
-
- while ((temp = lx_plx_reg_read(chip, ePLX_L2PCIDB))) {
- /* RAZ interrupt */
- irqcs |= temp;
- lx_plx_reg_write(chip, ePLX_L2PCIDB, temp);
- }
-
- return irqcs;
- }
- return PCX_IRQ_NONE;
-}
-
-static int lx_interrupt_ack(struct lx6464es *chip, u32 *r_irqsrc,
- int *r_async_pending, int *r_async_escmd)
-{
- u32 irq_async;
- u32 irqsrc = lx_interrupt_test_ack(chip);
-
- if (irqsrc == PCX_IRQ_NONE)
- return 0;
-
- *r_irqsrc = irqsrc;
-
- irq_async = irqsrc & MASK_SYS_ASYNC_EVENTS; /* + EtherSound response
- * (set by xilinx) + EOB */
-
- if (irq_async & MASK_SYS_STATUS_ESA) {
- irq_async &= ~MASK_SYS_STATUS_ESA;
- *r_async_escmd = 1;
- }
-
- if (irq_async) {
- /* snd_printd("interrupt: async event pending\n"); */
- *r_async_pending = 1;
- }
-
- return 1;
-}
-
-static int lx_interrupt_handle_async_events(struct lx6464es *chip, u32 irqsrc,
- int *r_freq_changed,
- u64 *r_notified_in_pipe_mask,
- u64 *r_notified_out_pipe_mask)
-{
- int err;
- u32 stat[9]; /* answer from CMD_04_GET_EVENT */
-
- /* On peut optimiser pour ne pas lire les evenements vides
- * les mots de réponse sont dans l'ordre suivant :
- * Stat[0] mot de status général
- * Stat[1] fin de buffer OUT pF
- * Stat[2] fin de buffer OUT pf
- * Stat[3] fin de buffer IN pF
- * Stat[4] fin de buffer IN pf
- * Stat[5] underrun poid fort
- * Stat[6] underrun poid faible
- * Stat[7] overrun poid fort
- * Stat[8] overrun poid faible
- * */
-
- u64 orun_mask;
- u64 urun_mask;
-#if 0
- int has_underrun = (irqsrc & MASK_SYS_STATUS_URUN) ? 1 : 0;
- int has_overrun = (irqsrc & MASK_SYS_STATUS_ORUN) ? 1 : 0;
-#endif
- int eb_pending_out = (irqsrc & MASK_SYS_STATUS_EOBO) ? 1 : 0;
- int eb_pending_in = (irqsrc & MASK_SYS_STATUS_EOBI) ? 1 : 0;
-
- *r_freq_changed = (irqsrc & MASK_SYS_STATUS_FREQ) ? 1 : 0;
-
- err = lx_dsp_read_async_events(chip, stat);
- if (err < 0)
- return err;
-
- if (eb_pending_in) {
- *r_notified_in_pipe_mask = ((u64)stat[3] << 32)
- + stat[4];
- snd_printdd(LXP "interrupt: EOBI pending %llx\n",
- *r_notified_in_pipe_mask);
- }
- if (eb_pending_out) {
- *r_notified_out_pipe_mask = ((u64)stat[1] << 32)
- + stat[2];
- snd_printdd(LXP "interrupt: EOBO pending %llx\n",
- *r_notified_out_pipe_mask);
- }
-
- orun_mask = ((u64)stat[7] << 32) + stat[8];
- urun_mask = ((u64)stat[5] << 32) + stat[6];
-
- /* todo: handle xrun notification */
-
- return err;
-}
-
-static int lx_interrupt_request_new_buffer(struct lx6464es *chip,
- struct lx_stream *lx_stream)
-{
- struct snd_pcm_substream *substream = lx_stream->stream;
- const unsigned int is_capture = lx_stream->is_capture;
- int err;
- unsigned long flags;
-
- const u32 channels = substream->runtime->channels;
- const u32 bytes_per_frame = channels * 3;
- const u32 period_size = substream->runtime->period_size;
- const u32 period_bytes = period_size * bytes_per_frame;
- const u32 pos = lx_stream->frame_pos;
- const u32 next_pos = ((pos+1) == substream->runtime->periods) ?
- 0 : pos + 1;
-
- dma_addr_t buf = substream->dma_buffer.addr + pos * period_bytes;
- u32 buf_hi = 0;
- u32 buf_lo = 0;
- u32 buffer_index = 0;
-
- u32 needed, freed;
- u32 size_array[MAX_STREAM_BUFFER];
-
- snd_printdd("->lx_interrupt_request_new_buffer\n");
-
- spin_lock_irqsave(&chip->lock, flags);
-
- err = lx_buffer_ask(chip, 0, is_capture, &needed, &freed, size_array);
- snd_printdd(LXP "interrupt: needed %d, freed %d\n", needed, freed);
-
- unpack_pointer(buf, &buf_lo, &buf_hi);
- err = lx_buffer_give(chip, 0, is_capture, period_bytes, buf_lo, buf_hi,
- &buffer_index);
- snd_printdd(LXP "interrupt: gave buffer index %x on %p (%d bytes)\n",
- buffer_index, (void *)buf, period_bytes);
-
- lx_stream->frame_pos = next_pos;
- spin_unlock_irqrestore(&chip->lock, flags);
-
- return err;
-}
-
-void lx_tasklet_playback(unsigned long data)
-{
- struct lx6464es *chip = (struct lx6464es *)data;
- struct lx_stream *lx_stream = &chip->playback_stream;
- int err;
-
- snd_printdd("->lx_tasklet_playback\n");
-
- err = lx_interrupt_request_new_buffer(chip, lx_stream);
- if (err < 0)
- snd_printk(KERN_ERR LXP
- "cannot request new buffer for playback\n");
-
- snd_pcm_period_elapsed(lx_stream->stream);
-}
-
-void lx_tasklet_capture(unsigned long data)
-{
- struct lx6464es *chip = (struct lx6464es *)data;
- struct lx_stream *lx_stream = &chip->capture_stream;
- int err;
-
- snd_printdd("->lx_tasklet_capture\n");
- err = lx_interrupt_request_new_buffer(chip, lx_stream);
- if (err < 0)
- snd_printk(KERN_ERR LXP
- "cannot request new buffer for capture\n");
-
- snd_pcm_period_elapsed(lx_stream->stream);
-}
-
-
-
-static int lx_interrupt_handle_audio_transfer(struct lx6464es *chip,
- u64 notified_in_pipe_mask,
- u64 notified_out_pipe_mask)
-{
- int err = 0;
-
- if (notified_in_pipe_mask) {
- snd_printdd(LXP "requesting audio transfer for capture\n");
- tasklet_hi_schedule(&chip->tasklet_capture);
- }
-
- if (notified_out_pipe_mask) {
- snd_printdd(LXP "requesting audio transfer for playback\n");
- tasklet_hi_schedule(&chip->tasklet_playback);
- }
-
- return err;
-}
-
-
-irqreturn_t lx_interrupt(int irq, void *dev_id)
-{
- struct lx6464es *chip = dev_id;
- int async_pending, async_escmd;
- u32 irqsrc;
-
- spin_lock(&chip->lock);
-
- snd_printdd("**************************************************\n");
-
- if (!lx_interrupt_ack(chip, &irqsrc, &async_pending, &async_escmd)) {
- spin_unlock(&chip->lock);
- snd_printdd("IRQ_NONE\n");
- return IRQ_NONE; /* this device did not cause the interrupt */
- }
-
- if (irqsrc & MASK_SYS_STATUS_CMD_DONE)
- goto exit;
-
-#if 0
- if (irqsrc & MASK_SYS_STATUS_EOBI)
- snd_printdd(LXP "interrupt: EOBI\n");
-
- if (irqsrc & MASK_SYS_STATUS_EOBO)
- snd_printdd(LXP "interrupt: EOBO\n");
-
- if (irqsrc & MASK_SYS_STATUS_URUN)
- snd_printdd(LXP "interrupt: URUN\n");
-
- if (irqsrc & MASK_SYS_STATUS_ORUN)
- snd_printdd(LXP "interrupt: ORUN\n");
-#endif
-
- if (async_pending) {
- u64 notified_in_pipe_mask = 0;
- u64 notified_out_pipe_mask = 0;
- int freq_changed;
- int err;
-
- /* handle async events */
- err = lx_interrupt_handle_async_events(chip, irqsrc,
- &freq_changed,
- &notified_in_pipe_mask,
- &notified_out_pipe_mask);
- if (err)
- snd_printk(KERN_ERR LXP
- "error handling async events\n");
-
- err = lx_interrupt_handle_audio_transfer(chip,
- notified_in_pipe_mask,
- notified_out_pipe_mask
- );
- if (err)
- snd_printk(KERN_ERR LXP
- "error during audio transfer\n");
- }
-
- if (async_escmd) {
-#if 0
- /* backdoor for ethersound commands
- *
- * for now, we do not need this
- *
- * */
-
- snd_printdd("lx6464es: interrupt requests escmd handling\n");
-#endif
- }
-
-exit:
- spin_unlock(&chip->lock);
- return IRQ_HANDLED; /* this device caused the interrupt */
-}
-
-
-static void lx_irq_set(struct lx6464es *chip, int enable)
-{
- u32 reg = lx_plx_reg_read(chip, ePLX_IRQCS);
-
- /* enable/disable interrupts
- *
- * Set the Doorbell and PCI interrupt enable bits
- *
- * */
- if (enable)
- reg |= (IRQCS_ENABLE_PCIIRQ | IRQCS_ENABLE_PCIDB);
- else
- reg &= ~(IRQCS_ENABLE_PCIIRQ | IRQCS_ENABLE_PCIDB);
- lx_plx_reg_write(chip, ePLX_IRQCS, reg);
-}
-
-void lx_irq_enable(struct lx6464es *chip)
-{
- snd_printdd("->lx_irq_enable\n");
- lx_irq_set(chip, 1);
-}
-
-void lx_irq_disable(struct lx6464es *chip)
-{
- snd_printdd("->lx_irq_disable\n");
- lx_irq_set(chip, 0);
-}
diff --git a/ANDROID_3.4.5/sound/pci/lx6464es/lx_core.h b/ANDROID_3.4.5/sound/pci/lx6464es/lx_core.h
deleted file mode 100644
index 4d7ff797..00000000
--- a/ANDROID_3.4.5/sound/pci/lx6464es/lx_core.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/* -*- linux-c -*- *
- *
- * ALSA driver for the digigram lx6464es interface
- * low-level interface
- *
- * Copyright (c) 2009 Tim Blechmann <tim@klingt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-#ifndef LX_CORE_H
-#define LX_CORE_H
-
-#include <linux/interrupt.h>
-
-#include "lx_defs.h"
-
-#define REG_CRM_NUMBER 12
-
-struct lx6464es;
-
-/* low-level register access */
-
-/* dsp register access */
-enum {
- eReg_BASE,
- eReg_CSM,
- eReg_CRM1,
- eReg_CRM2,
- eReg_CRM3,
- eReg_CRM4,
- eReg_CRM5,
- eReg_CRM6,
- eReg_CRM7,
- eReg_CRM8,
- eReg_CRM9,
- eReg_CRM10,
- eReg_CRM11,
- eReg_CRM12,
-
- eReg_ICR,
- eReg_CVR,
- eReg_ISR,
- eReg_RXHTXH,
- eReg_RXMTXM,
- eReg_RHLTXL,
- eReg_RESETDSP,
-
- eReg_CSUF,
- eReg_CSES,
- eReg_CRESMSB,
- eReg_CRESLSB,
- eReg_ADMACESMSB,
- eReg_ADMACESLSB,
- eReg_CONFES,
-
- eMaxPortLx
-};
-
-unsigned long lx_dsp_reg_read(struct lx6464es *chip, int port);
-void lx_dsp_reg_write(struct lx6464es *chip, int port, unsigned data);
-
-/* plx register access */
-enum {
- ePLX_PCICR,
-
- ePLX_MBOX0,
- ePLX_MBOX1,
- ePLX_MBOX2,
- ePLX_MBOX3,
- ePLX_MBOX4,
- ePLX_MBOX5,
- ePLX_MBOX6,
- ePLX_MBOX7,
-
- ePLX_L2PCIDB,
- ePLX_IRQCS,
- ePLX_CHIPSC,
-
- eMaxPort
-};
-
-unsigned long lx_plx_reg_read(struct lx6464es *chip, int port);
-void lx_plx_reg_write(struct lx6464es *chip, int port, u32 data);
-
-/* rhm */
-struct lx_rmh {
- u16 cmd_len; /* length of the command to send (WORDs) */
- u16 stat_len; /* length of the status received (WORDs) */
- u16 dsp_stat; /* status type, RMP_SSIZE_XXX */
- u16 cmd_idx; /* index of the command */
- u32 cmd[REG_CRM_NUMBER];
- u32 stat[REG_CRM_NUMBER];
-};
-
-
-/* low-level dsp access */
-int __devinit lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version);
-int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq);
-int lx_dsp_set_granularity(struct lx6464es *chip, u32 gran);
-int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data);
-int lx_dsp_get_mac(struct lx6464es *chip);
-
-
-/* low-level pipe handling */
-int lx_pipe_allocate(struct lx6464es *chip, u32 pipe, int is_capture,
- int channels);
-int lx_pipe_release(struct lx6464es *chip, u32 pipe, int is_capture);
-int lx_pipe_sample_count(struct lx6464es *chip, u32 pipe, int is_capture,
- u64 *rsample_count);
-int lx_pipe_state(struct lx6464es *chip, u32 pipe, int is_capture, u16 *rstate);
-int lx_pipe_stop(struct lx6464es *chip, u32 pipe, int is_capture);
-int lx_pipe_start(struct lx6464es *chip, u32 pipe, int is_capture);
-int lx_pipe_pause(struct lx6464es *chip, u32 pipe, int is_capture);
-
-int lx_pipe_wait_for_start(struct lx6464es *chip, u32 pipe, int is_capture);
-int lx_pipe_wait_for_idle(struct lx6464es *chip, u32 pipe, int is_capture);
-
-/* low-level stream handling */
-int lx_stream_set_format(struct lx6464es *chip, struct snd_pcm_runtime *runtime,
- u32 pipe, int is_capture);
-int lx_stream_state(struct lx6464es *chip, u32 pipe, int is_capture,
- int *rstate);
-int lx_stream_sample_position(struct lx6464es *chip, u32 pipe, int is_capture,
- u64 *r_bytepos);
-
-int lx_stream_set_state(struct lx6464es *chip, u32 pipe,
- int is_capture, enum stream_state_t state);
-
-static inline int lx_stream_start(struct lx6464es *chip, u32 pipe,
- int is_capture)
-{
- snd_printdd("->lx_stream_start\n");
- return lx_stream_set_state(chip, pipe, is_capture, SSTATE_RUN);
-}
-
-static inline int lx_stream_pause(struct lx6464es *chip, u32 pipe,
- int is_capture)
-{
- snd_printdd("->lx_stream_pause\n");
- return lx_stream_set_state(chip, pipe, is_capture, SSTATE_PAUSE);
-}
-
-static inline int lx_stream_stop(struct lx6464es *chip, u32 pipe,
- int is_capture)
-{
- snd_printdd("->lx_stream_stop\n");
- return lx_stream_set_state(chip, pipe, is_capture, SSTATE_STOP);
-}
-
-/* low-level buffer handling */
-int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture,
- u32 *r_needed, u32 *r_freed, u32 *size_array);
-int lx_buffer_give(struct lx6464es *chip, u32 pipe, int is_capture,
- u32 buffer_size, u32 buf_address_lo, u32 buf_address_hi,
- u32 *r_buffer_index);
-int lx_buffer_free(struct lx6464es *chip, u32 pipe, int is_capture,
- u32 *r_buffer_size);
-int lx_buffer_cancel(struct lx6464es *chip, u32 pipe, int is_capture,
- u32 buffer_index);
-
-/* low-level gain/peak handling */
-int lx_level_unmute(struct lx6464es *chip, int is_capture, int unmute);
-int lx_level_peaks(struct lx6464es *chip, int is_capture, int channels,
- u32 *r_levels);
-
-
-/* interrupt handling */
-irqreturn_t lx_interrupt(int irq, void *dev_id);
-void lx_irq_enable(struct lx6464es *chip);
-void lx_irq_disable(struct lx6464es *chip);
-
-void lx_tasklet_capture(unsigned long data);
-void lx_tasklet_playback(unsigned long data);
-
-
-/* Stream Format Header Defines (for LIN and IEEE754) */
-#define HEADER_FMT_BASE HEADER_FMT_BASE_LIN
-#define HEADER_FMT_BASE_LIN 0xFED00000
-#define HEADER_FMT_BASE_FLOAT 0xFAD00000
-#define HEADER_FMT_MONO 0x00000080 /* bit 23 in header_lo. WARNING: old
- * bit 22 is ignored in float
- * format */
-#define HEADER_FMT_INTEL 0x00008000
-#define HEADER_FMT_16BITS 0x00002000
-#define HEADER_FMT_24BITS 0x00004000
-#define HEADER_FMT_UPTO11 0x00000200 /* frequency is less or equ. to 11k.
- * */
-#define HEADER_FMT_UPTO32 0x00000100 /* frequency is over 11k and less
- * then 32k.*/
-
-
-#define BIT_FMP_HEADER 23
-#define BIT_FMP_SD 22
-#define BIT_FMP_MULTICHANNEL 19
-
-#define START_STATE 1
-#define PAUSE_STATE 0
-
-
-
-
-
-/* from PcxAll_e.h */
-/* Start/Pause condition for pipes (PCXStartPipe, PCXPausePipe) */
-#define START_PAUSE_IMMEDIATE 0
-#define START_PAUSE_ON_SYNCHRO 1
-#define START_PAUSE_ON_TIME_CODE 2
-
-
-/* Pipe / Stream state */
-#define START_STATE 1
-#define PAUSE_STATE 0
-
-static inline void unpack_pointer(dma_addr_t ptr, u32 *r_low, u32 *r_high)
-{
- *r_low = (u32)(ptr & 0xffffffff);
-#if BITS_PER_LONG == 32
- *r_high = 0;
-#else
- *r_high = (u32)((u64)ptr>>32);
-#endif
-}
-
-#endif /* LX_CORE_H */
diff --git a/ANDROID_3.4.5/sound/pci/lx6464es/lx_defs.h b/ANDROID_3.4.5/sound/pci/lx6464es/lx_defs.h
deleted file mode 100644
index 49d36bdd..00000000
--- a/ANDROID_3.4.5/sound/pci/lx6464es/lx_defs.h
+++ /dev/null
@@ -1,376 +0,0 @@
-/* -*- linux-c -*- *
- *
- * ALSA driver for the digigram lx6464es interface
- * adapted upstream headers
- *
- * Copyright (c) 2009 Tim Blechmann <tim@klingt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-#ifndef LX_DEFS_H
-#define LX_DEFS_H
-
-/* code adapted from ethersound.h */
-#define XES_FREQ_COUNT8_MASK 0x00001FFF /* compteur 25MHz entre 8 ech. */
-#define XES_FREQ_COUNT8_44_MIN 0x00001288 /* 25M /
- * [ 44k - ( 44.1k + 48k ) / 2 ]
- * * 8 */
-#define XES_FREQ_COUNT8_44_MAX 0x000010F0 /* 25M / [ ( 44.1k + 48k ) / 2 ]
- * * 8 */
-#define XES_FREQ_COUNT8_48_MAX 0x00000F08 /* 25M /
- * [ 48k + ( 44.1k + 48k ) / 2 ]
- * * 8 */
-
-/* code adapted from LXES_registers.h */
-
-#define IOCR_OUTPUTS_OFFSET 0 /* (rw) offset for the number of OUTs in the
- * ConfES register. */
-#define IOCR_INPUTS_OFFSET 8 /* (rw) offset for the number of INs in the
- * ConfES register. */
-#define FREQ_RATIO_OFFSET 19 /* (rw) offset for frequency ratio in the
- * ConfES register. */
-#define FREQ_RATIO_SINGLE_MODE 0x01 /* value for single mode frequency ratio:
- * sample rate = frequency rate. */
-
-#define CONFES_READ_PART_MASK 0x00070000
-#define CONFES_WRITE_PART_MASK 0x00F80000
-
-/* code adapted from if_drv_mb.h */
-
-#define MASK_SYS_STATUS_ERROR (1L << 31) /* events that lead to a PCI irq if
- * not yet pending */
-#define MASK_SYS_STATUS_URUN (1L << 30)
-#define MASK_SYS_STATUS_ORUN (1L << 29)
-#define MASK_SYS_STATUS_EOBO (1L << 28)
-#define MASK_SYS_STATUS_EOBI (1L << 27)
-#define MASK_SYS_STATUS_FREQ (1L << 26)
-#define MASK_SYS_STATUS_ESA (1L << 25) /* reserved, this is set by the
- * XES */
-#define MASK_SYS_STATUS_TIMER (1L << 24)
-
-#define MASK_SYS_ASYNC_EVENTS (MASK_SYS_STATUS_ERROR | \
- MASK_SYS_STATUS_URUN | \
- MASK_SYS_STATUS_ORUN | \
- MASK_SYS_STATUS_EOBO | \
- MASK_SYS_STATUS_EOBI | \
- MASK_SYS_STATUS_FREQ | \
- MASK_SYS_STATUS_ESA)
-
-#define MASK_SYS_PCI_EVENTS (MASK_SYS_ASYNC_EVENTS | \
- MASK_SYS_STATUS_TIMER)
-
-#define MASK_SYS_TIMER_COUNT 0x0000FFFF
-
-#define MASK_SYS_STATUS_EOT_PLX (1L << 22) /* event that remains
- * internal: reserved fo end
- * of plx dma */
-#define MASK_SYS_STATUS_XES (1L << 21) /* event that remains
- * internal: pending XES
- * IRQ */
-#define MASK_SYS_STATUS_CMD_DONE (1L << 20) /* alternate command
- * management: notify driver
- * instead of polling */
-
-
-#define MAX_STREAM_BUFFER 5 /* max amount of stream buffers. */
-
-#define MICROBLAZE_IBL_MIN 32
-#define MICROBLAZE_IBL_DEFAULT 128
-#define MICROBLAZE_IBL_MAX 512
-/* #define MASK_GRANULARITY (2*MICROBLAZE_IBL_MAX-1) */
-
-
-
-/* command opcodes, see reference for details */
-
-/*
- the capture bit position in the object_id field in driver commands
- depends upon the number of managed channels. For now, 64 IN + 64 OUT are
- supported. HOwever, the communication protocol forsees 1024 channels, hence
- bit 10 indicates a capture (input) object).
-*/
-#define ID_IS_CAPTURE (1L << 10)
-#define ID_OFFSET 13 /* object ID is at the 13th bit in the
- * 1st command word.*/
-#define ID_CH_MASK 0x3F
-#define OPCODE_OFFSET 24 /* offset of the command opcode in the first
- * command word.*/
-
-enum cmd_mb_opcodes {
- CMD_00_INFO_DEBUG = 0x00,
- CMD_01_GET_SYS_CFG = 0x01,
- CMD_02_SET_GRANULARITY = 0x02,
- CMD_03_SET_TIMER_IRQ = 0x03,
- CMD_04_GET_EVENT = 0x04,
- CMD_05_GET_PIPES = 0x05,
-
- CMD_06_ALLOCATE_PIPE = 0x06,
- CMD_07_RELEASE_PIPE = 0x07,
- CMD_08_ASK_BUFFERS = 0x08,
- CMD_09_STOP_PIPE = 0x09,
- CMD_0A_GET_PIPE_SPL_COUNT = 0x0a,
- CMD_0B_TOGGLE_PIPE_STATE = 0x0b,
-
- CMD_0C_DEF_STREAM = 0x0c,
- CMD_0D_SET_MUTE = 0x0d,
- CMD_0E_GET_STREAM_SPL_COUNT = 0x0e,
- CMD_0F_UPDATE_BUFFER = 0x0f,
- CMD_10_GET_BUFFER = 0x10,
- CMD_11_CANCEL_BUFFER = 0x11,
- CMD_12_GET_PEAK = 0x12,
- CMD_13_SET_STREAM_STATE = 0x13,
- CMD_14_INVALID = 0x14,
-};
-
-/* pipe states */
-enum pipe_state_t {
- PSTATE_IDLE = 0, /* the pipe is not processed in the XES_IRQ
- * (free or stopped, or paused). */
- PSTATE_RUN = 1, /* sustained play/record state. */
- PSTATE_PURGE = 2, /* the ES channels are now off, render pipes do
- * not DMA, record pipe do a last DMA. */
- PSTATE_ACQUIRE = 3, /* the ES channels are now on, render pipes do
- * not yet increase their sample count, record
- * pipes do not DMA. */
- PSTATE_CLOSING = 4, /* the pipe is releasing, and may not yet
- * receive an "alloc" command. */
-};
-
-/* stream states */
-enum stream_state_t {
- SSTATE_STOP = 0x00, /* setting to stop resets the stream spl
- * count.*/
- SSTATE_RUN = (0x01 << 0), /* start DMA and spl count handling. */
- SSTATE_PAUSE = (0x01 << 1), /* pause DMA and spl count handling. */
-};
-
-/* buffer flags */
-enum buffer_flags {
- BF_VALID = 0x80, /* set if the buffer is valid, clear if free.*/
- BF_CURRENT = 0x40, /* set if this is the current buffer (there is
- * always a current buffer).*/
- BF_NOTIFY_EOB = 0x20, /* set if this buffer must cause a PCI event
- * when finished.*/
- BF_CIRCULAR = 0x10, /* set if buffer[1] must be copied to buffer[0]
- * by the end of this buffer.*/
- BF_64BITS_ADR = 0x08, /* set if the hi part of the address is valid.*/
- BF_xx = 0x04, /* future extension.*/
- BF_EOB = 0x02, /* set if finished, but not yet free.*/
- BF_PAUSE = 0x01, /* pause stream at buffer end.*/
- BF_ZERO = 0x00, /* no flags (init).*/
-};
-
-/**
-* Stream Flags definitions
-*/
-enum stream_flags {
- SF_ZERO = 0x00000000, /* no flags (stream invalid). */
- SF_VALID = 0x10000000, /* the stream has a valid DMA_conf
- * info (setstreamformat). */
- SF_XRUN = 0x20000000, /* the stream is un x-run state. */
- SF_START = 0x40000000, /* the DMA is running.*/
- SF_ASIO = 0x80000000, /* ASIO.*/
-};
-
-
-#define MASK_SPL_COUNT_HI 0x00FFFFFF /* 4 MSBits are status bits */
-#define PSTATE_OFFSET 28 /* 4 MSBits are status bits */
-
-
-#define MASK_STREAM_HAS_MAPPING (1L << 12)
-#define MASK_STREAM_IS_ASIO (1L << 9)
-#define STREAM_FMT_OFFSET 10 /* the stream fmt bits start at the 10th
- * bit in the command word. */
-
-#define STREAM_FMT_16b 0x02
-#define STREAM_FMT_intel 0x01
-
-#define FREQ_FIELD_OFFSET 15 /* offset of the freq field in the response
- * word */
-
-#define BUFF_FLAGS_OFFSET 24 /* offset of the buffer flags in the
- * response word. */
-#define MASK_DATA_SIZE 0x00FFFFFF /* this must match the field size of
- * datasize in the buffer_t structure. */
-
-#define MASK_BUFFER_ID 0xFF /* the cancel command awaits a buffer ID,
- * may be 0xFF for "current". */
-
-
-/* code adapted from PcxErr_e.h */
-
-/* Bits masks */
-
-#define ERROR_MASK 0x8000
-
-#define SOURCE_MASK 0x7800
-
-#define E_SOURCE_BOARD 0x4000 /* 8 >> 1 */
-#define E_SOURCE_DRV 0x2000 /* 4 >> 1 */
-#define E_SOURCE_API 0x1000 /* 2 >> 1 */
-/* Error tools */
-#define E_SOURCE_TOOLS 0x0800 /* 1 >> 1 */
-/* Error pcxaudio */
-#define E_SOURCE_AUDIO 0x1800 /* 3 >> 1 */
-/* Error virtual pcx */
-#define E_SOURCE_VPCX 0x2800 /* 5 >> 1 */
-/* Error dispatcher */
-#define E_SOURCE_DISPATCHER 0x3000 /* 6 >> 1 */
-/* Error from CobraNet firmware */
-#define E_SOURCE_COBRANET 0x3800 /* 7 >> 1 */
-
-#define E_SOURCE_USER 0x7800
-
-#define CLASS_MASK 0x0700
-
-#define CODE_MASK 0x00FF
-
-/* Bits values */
-
-/* Values for the error/warning bit */
-#define ERROR_VALUE 0x8000
-#define WARNING_VALUE 0x0000
-
-/* Class values */
-#define E_CLASS_GENERAL 0x0000
-#define E_CLASS_INVALID_CMD 0x0100
-#define E_CLASS_INVALID_STD_OBJECT 0x0200
-#define E_CLASS_RSRC_IMPOSSIBLE 0x0300
-#define E_CLASS_WRONG_CONTEXT 0x0400
-#define E_CLASS_BAD_SPECIFIC_PARAMETER 0x0500
-#define E_CLASS_REAL_TIME_ERROR 0x0600
-#define E_CLASS_DIRECTSHOW 0x0700
-#define E_CLASS_FREE 0x0700
-
-
-/* Complete DRV error code for the general class */
-#define ED_GN (ERROR_VALUE | E_SOURCE_DRV | E_CLASS_GENERAL)
-#define ED_CONCURRENCY (ED_GN | 0x01)
-#define ED_DSP_CRASHED (ED_GN | 0x02)
-#define ED_UNKNOWN_BOARD (ED_GN | 0x03)
-#define ED_NOT_INSTALLED (ED_GN | 0x04)
-#define ED_CANNOT_OPEN_SVC_MANAGER (ED_GN | 0x05)
-#define ED_CANNOT_READ_REGISTRY (ED_GN | 0x06)
-#define ED_DSP_VERSION_MISMATCH (ED_GN | 0x07)
-#define ED_UNAVAILABLE_FEATURE (ED_GN | 0x08)
-#define ED_CANCELLED (ED_GN | 0x09)
-#define ED_NO_RESPONSE_AT_IRQA (ED_GN | 0x10)
-#define ED_INVALID_ADDRESS (ED_GN | 0x11)
-#define ED_DSP_CORRUPTED (ED_GN | 0x12)
-#define ED_PENDING_OPERATION (ED_GN | 0x13)
-#define ED_NET_ALLOCATE_MEMORY_IMPOSSIBLE (ED_GN | 0x14)
-#define ED_NET_REGISTER_ERROR (ED_GN | 0x15)
-#define ED_NET_THREAD_ERROR (ED_GN | 0x16)
-#define ED_NET_OPEN_ERROR (ED_GN | 0x17)
-#define ED_NET_CLOSE_ERROR (ED_GN | 0x18)
-#define ED_NET_NO_MORE_PACKET (ED_GN | 0x19)
-#define ED_NET_NO_MORE_BUFFER (ED_GN | 0x1A)
-#define ED_NET_SEND_ERROR (ED_GN | 0x1B)
-#define ED_NET_RECEIVE_ERROR (ED_GN | 0x1C)
-#define ED_NET_WRONG_MSG_SIZE (ED_GN | 0x1D)
-#define ED_NET_WAIT_ERROR (ED_GN | 0x1E)
-#define ED_NET_EEPROM_ERROR (ED_GN | 0x1F)
-#define ED_INVALID_RS232_COM_NUMBER (ED_GN | 0x20)
-#define ED_INVALID_RS232_INIT (ED_GN | 0x21)
-#define ED_FILE_ERROR (ED_GN | 0x22)
-#define ED_INVALID_GPIO_CMD (ED_GN | 0x23)
-#define ED_RS232_ALREADY_OPENED (ED_GN | 0x24)
-#define ED_RS232_NOT_OPENED (ED_GN | 0x25)
-#define ED_GPIO_ALREADY_OPENED (ED_GN | 0x26)
-#define ED_GPIO_NOT_OPENED (ED_GN | 0x27)
-#define ED_REGISTRY_ERROR (ED_GN | 0x28) /* <- NCX */
-#define ED_INVALID_SERVICE (ED_GN | 0x29) /* <- NCX */
-
-#define ED_READ_FILE_ALREADY_OPENED (ED_GN | 0x2a) /* <- Decalage
- * pour RCX
- * (old 0x28)
- * */
-#define ED_READ_FILE_INVALID_COMMAND (ED_GN | 0x2b) /* ~ */
-#define ED_READ_FILE_INVALID_PARAMETER (ED_GN | 0x2c) /* ~ */
-#define ED_READ_FILE_ALREADY_CLOSED (ED_GN | 0x2d) /* ~ */
-#define ED_READ_FILE_NO_INFORMATION (ED_GN | 0x2e) /* ~ */
-#define ED_READ_FILE_INVALID_HANDLE (ED_GN | 0x2f) /* ~ */
-#define ED_READ_FILE_END_OF_FILE (ED_GN | 0x30) /* ~ */
-#define ED_READ_FILE_ERROR (ED_GN | 0x31) /* ~ */
-
-#define ED_DSP_CRASHED_EXC_DSPSTACK_OVERFLOW (ED_GN | 0x32) /* <- Decalage pour
- * PCX (old 0x14) */
-#define ED_DSP_CRASHED_EXC_SYSSTACK_OVERFLOW (ED_GN | 0x33) /* ~ */
-#define ED_DSP_CRASHED_EXC_ILLEGAL (ED_GN | 0x34) /* ~ */
-#define ED_DSP_CRASHED_EXC_TIMER_REENTRY (ED_GN | 0x35) /* ~ */
-#define ED_DSP_CRASHED_EXC_FATAL_ERROR (ED_GN | 0x36) /* ~ */
-
-#define ED_FLASH_PCCARD_NOT_PRESENT (ED_GN | 0x37)
-
-#define ED_NO_CURRENT_CLOCK (ED_GN | 0x38)
-
-/* Complete DRV error code for real time class */
-#define ED_RT (ERROR_VALUE | E_SOURCE_DRV | E_CLASS_REAL_TIME_ERROR)
-#define ED_DSP_TIMED_OUT (ED_RT | 0x01)
-#define ED_DSP_CHK_TIMED_OUT (ED_RT | 0x02)
-#define ED_STREAM_OVERRUN (ED_RT | 0x03)
-#define ED_DSP_BUSY (ED_RT | 0x04)
-#define ED_DSP_SEMAPHORE_TIME_OUT (ED_RT | 0x05)
-#define ED_BOARD_TIME_OUT (ED_RT | 0x06)
-#define ED_XILINX_ERROR (ED_RT | 0x07)
-#define ED_COBRANET_ITF_NOT_RESPONDING (ED_RT | 0x08)
-
-/* Complete BOARD error code for the invaid standard object class */
-#define EB_ISO (ERROR_VALUE | E_SOURCE_BOARD | \
- E_CLASS_INVALID_STD_OBJECT)
-#define EB_INVALID_EFFECT (EB_ISO | 0x00)
-#define EB_INVALID_PIPE (EB_ISO | 0x40)
-#define EB_INVALID_STREAM (EB_ISO | 0x80)
-#define EB_INVALID_AUDIO (EB_ISO | 0xC0)
-
-/* Complete BOARD error code for impossible resource allocation class */
-#define EB_RI (ERROR_VALUE | E_SOURCE_BOARD | E_CLASS_RSRC_IMPOSSIBLE)
-#define EB_ALLOCATE_ALL_STREAM_TRANSFERT_BUFFERS_IMPOSSIBLE (EB_RI | 0x01)
-#define EB_ALLOCATE_PIPE_SAMPLE_BUFFER_IMPOSSIBLE (EB_RI | 0x02)
-
-#define EB_ALLOCATE_MEM_STREAM_IMPOSSIBLE \
- EB_ALLOCATE_ALL_STREAM_TRANSFERT_BUFFERS_IMPOSSIBLE
-#define EB_ALLOCATE_MEM_PIPE_IMPOSSIBLE \
- EB_ALLOCATE_PIPE_SAMPLE_BUFFER_IMPOSSIBLE
-
-#define EB_ALLOCATE_DIFFERED_CMD_IMPOSSIBLE (EB_RI | 0x03)
-#define EB_TOO_MANY_DIFFERED_CMD (EB_RI | 0x04)
-#define EB_RBUFFERS_TABLE_OVERFLOW (EB_RI | 0x05)
-#define EB_ALLOCATE_EFFECTS_IMPOSSIBLE (EB_RI | 0x08)
-#define EB_ALLOCATE_EFFECT_POS_IMPOSSIBLE (EB_RI | 0x09)
-#define EB_RBUFFER_NOT_AVAILABLE (EB_RI | 0x0A)
-#define EB_ALLOCATE_CONTEXT_LIII_IMPOSSIBLE (EB_RI | 0x0B)
-#define EB_STATUS_DIALOG_IMPOSSIBLE (EB_RI | 0x1D)
-#define EB_CONTROL_CMD_IMPOSSIBLE (EB_RI | 0x1E)
-#define EB_STATUS_SEND_IMPOSSIBLE (EB_RI | 0x1F)
-#define EB_ALLOCATE_PIPE_IMPOSSIBLE (EB_RI | 0x40)
-#define EB_ALLOCATE_STREAM_IMPOSSIBLE (EB_RI | 0x80)
-#define EB_ALLOCATE_AUDIO_IMPOSSIBLE (EB_RI | 0xC0)
-
-/* Complete BOARD error code for wrong call context class */
-#define EB_WCC (ERROR_VALUE | E_SOURCE_BOARD | E_CLASS_WRONG_CONTEXT)
-#define EB_CMD_REFUSED (EB_WCC | 0x00)
-#define EB_START_STREAM_REFUSED (EB_WCC | 0xFC)
-#define EB_SPC_REFUSED (EB_WCC | 0xFD)
-#define EB_CSN_REFUSED (EB_WCC | 0xFE)
-#define EB_CSE_REFUSED (EB_WCC | 0xFF)
-
-
-
-
-#endif /* LX_DEFS_H */
diff --git a/ANDROID_3.4.5/sound/pci/maestro3.c b/ANDROID_3.4.5/sound/pci/maestro3.c
deleted file mode 100644
index 78229b0d..00000000
--- a/ANDROID_3.4.5/sound/pci/maestro3.c
+++ /dev/null
@@ -1,2862 +0,0 @@
-/*
- * Driver for ESS Maestro3/Allegro (ES1988) soundcards.
- * Copyright (c) 2000 by Zach Brown <zab@zabbo.net>
- * Takashi Iwai <tiwai@suse.de>
- *
- * Most of the hardware init stuffs are based on maestro3 driver for
- * OSS/Free by Zach Brown. Many thanks to Zach!
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
- * ChangeLog:
- * Aug. 27, 2001
- * - Fixed deadlock on capture
- * - Added Canyon3D-2 support by Rob Riggs <rob@pangalactic.org>
- *
- */
-
-#define CARD_NAME "ESS Maestro3/Allegro/Canyon3D-2"
-#define DRIVER_NAME "Maestro3"
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/input.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/mpu401.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-#include <asm/byteorder.h>
-
-MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("ESS Maestro3 PCI");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ESS,Maestro3 PCI},"
- "{ESS,ES1988},"
- "{ESS,Allegro PCI},"
- "{ESS,Allegro-1 PCI},"
- "{ESS,Canyon3D-2/LE PCI}}");
-MODULE_FIRMWARE("ess/maestro3_assp_kernel.fw");
-MODULE_FIRMWARE("ess/maestro3_assp_minisrc.fw");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* all enabled */
-static bool external_amp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
-static int amp_gpio[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable this soundcard.");
-module_param_array(external_amp, bool, NULL, 0444);
-MODULE_PARM_DESC(external_amp, "Enable external amp for " CARD_NAME " soundcard.");
-module_param_array(amp_gpio, int, NULL, 0444);
-MODULE_PARM_DESC(amp_gpio, "GPIO pin number for external amp. (default = -1)");
-
-#define MAX_PLAYBACKS 2
-#define MAX_CAPTURES 1
-#define NR_DSPS (MAX_PLAYBACKS + MAX_CAPTURES)
-
-
-/*
- * maestro3 registers
- */
-
-/* Allegro PCI configuration registers */
-#define PCI_LEGACY_AUDIO_CTRL 0x40
-#define SOUND_BLASTER_ENABLE 0x00000001
-#define FM_SYNTHESIS_ENABLE 0x00000002
-#define GAME_PORT_ENABLE 0x00000004
-#define MPU401_IO_ENABLE 0x00000008
-#define MPU401_IRQ_ENABLE 0x00000010
-#define ALIAS_10BIT_IO 0x00000020
-#define SB_DMA_MASK 0x000000C0
-#define SB_DMA_0 0x00000040
-#define SB_DMA_1 0x00000040
-#define SB_DMA_R 0x00000080
-#define SB_DMA_3 0x000000C0
-#define SB_IRQ_MASK 0x00000700
-#define SB_IRQ_5 0x00000000
-#define SB_IRQ_7 0x00000100
-#define SB_IRQ_9 0x00000200
-#define SB_IRQ_10 0x00000300
-#define MIDI_IRQ_MASK 0x00003800
-#define SERIAL_IRQ_ENABLE 0x00004000
-#define DISABLE_LEGACY 0x00008000
-
-#define PCI_ALLEGRO_CONFIG 0x50
-#define SB_ADDR_240 0x00000004
-#define MPU_ADDR_MASK 0x00000018
-#define MPU_ADDR_330 0x00000000
-#define MPU_ADDR_300 0x00000008
-#define MPU_ADDR_320 0x00000010
-#define MPU_ADDR_340 0x00000018
-#define USE_PCI_TIMING 0x00000040
-#define POSTED_WRITE_ENABLE 0x00000080
-#define DMA_POLICY_MASK 0x00000700
-#define DMA_DDMA 0x00000000
-#define DMA_TDMA 0x00000100
-#define DMA_PCPCI 0x00000200
-#define DMA_WBDMA16 0x00000400
-#define DMA_WBDMA4 0x00000500
-#define DMA_WBDMA2 0x00000600
-#define DMA_WBDMA1 0x00000700
-#define DMA_SAFE_GUARD 0x00000800
-#define HI_PERF_GP_ENABLE 0x00001000
-#define PIC_SNOOP_MODE_0 0x00002000
-#define PIC_SNOOP_MODE_1 0x00004000
-#define SOUNDBLASTER_IRQ_MASK 0x00008000
-#define RING_IN_ENABLE 0x00010000
-#define SPDIF_TEST_MODE 0x00020000
-#define CLK_MULT_MODE_SELECT_2 0x00040000
-#define EEPROM_WRITE_ENABLE 0x00080000
-#define CODEC_DIR_IN 0x00100000
-#define HV_BUTTON_FROM_GD 0x00200000
-#define REDUCED_DEBOUNCE 0x00400000
-#define HV_CTRL_ENABLE 0x00800000
-#define SPDIF_ENABLE 0x01000000
-#define CLK_DIV_SELECT 0x06000000
-#define CLK_DIV_BY_48 0x00000000
-#define CLK_DIV_BY_49 0x02000000
-#define CLK_DIV_BY_50 0x04000000
-#define CLK_DIV_RESERVED 0x06000000
-#define PM_CTRL_ENABLE 0x08000000
-#define CLK_MULT_MODE_SELECT 0x30000000
-#define CLK_MULT_MODE_SHIFT 28
-#define CLK_MULT_MODE_0 0x00000000
-#define CLK_MULT_MODE_1 0x10000000
-#define CLK_MULT_MODE_2 0x20000000
-#define CLK_MULT_MODE_3 0x30000000
-#define INT_CLK_SELECT 0x40000000
-#define INT_CLK_MULT_RESET 0x80000000
-
-/* M3 */
-#define INT_CLK_SRC_NOT_PCI 0x00100000
-#define INT_CLK_MULT_ENABLE 0x80000000
-
-#define PCI_ACPI_CONTROL 0x54
-#define PCI_ACPI_D0 0x00000000
-#define PCI_ACPI_D1 0xB4F70000
-#define PCI_ACPI_D2 0xB4F7B4F7
-
-#define PCI_USER_CONFIG 0x58
-#define EXT_PCI_MASTER_ENABLE 0x00000001
-#define SPDIF_OUT_SELECT 0x00000002
-#define TEST_PIN_DIR_CTRL 0x00000004
-#define AC97_CODEC_TEST 0x00000020
-#define TRI_STATE_BUFFER 0x00000080
-#define IN_CLK_12MHZ_SELECT 0x00000100
-#define MULTI_FUNC_DISABLE 0x00000200
-#define EXT_MASTER_PAIR_SEL 0x00000400
-#define PCI_MASTER_SUPPORT 0x00000800
-#define STOP_CLOCK_ENABLE 0x00001000
-#define EAPD_DRIVE_ENABLE 0x00002000
-#define REQ_TRI_STATE_ENABLE 0x00004000
-#define REQ_LOW_ENABLE 0x00008000
-#define MIDI_1_ENABLE 0x00010000
-#define MIDI_2_ENABLE 0x00020000
-#define SB_AUDIO_SYNC 0x00040000
-#define HV_CTRL_TEST 0x00100000
-#define SOUNDBLASTER_TEST 0x00400000
-
-#define PCI_USER_CONFIG_C 0x5C
-
-#define PCI_DDMA_CTRL 0x60
-#define DDMA_ENABLE 0x00000001
-
-
-/* Allegro registers */
-#define HOST_INT_CTRL 0x18
-#define SB_INT_ENABLE 0x0001
-#define MPU401_INT_ENABLE 0x0002
-#define ASSP_INT_ENABLE 0x0010
-#define RING_INT_ENABLE 0x0020
-#define HV_INT_ENABLE 0x0040
-#define CLKRUN_GEN_ENABLE 0x0100
-#define HV_CTRL_TO_PME 0x0400
-#define SOFTWARE_RESET_ENABLE 0x8000
-
-/*
- * should be using the above defines, probably.
- */
-#define REGB_ENABLE_RESET 0x01
-#define REGB_STOP_CLOCK 0x10
-
-#define HOST_INT_STATUS 0x1A
-#define SB_INT_PENDING 0x01
-#define MPU401_INT_PENDING 0x02
-#define ASSP_INT_PENDING 0x10
-#define RING_INT_PENDING 0x20
-#define HV_INT_PENDING 0x40
-
-#define HARDWARE_VOL_CTRL 0x1B
-#define SHADOW_MIX_REG_VOICE 0x1C
-#define HW_VOL_COUNTER_VOICE 0x1D
-#define SHADOW_MIX_REG_MASTER 0x1E
-#define HW_VOL_COUNTER_MASTER 0x1F
-
-#define CODEC_COMMAND 0x30
-#define CODEC_READ_B 0x80
-
-#define CODEC_STATUS 0x30
-#define CODEC_BUSY_B 0x01
-
-#define CODEC_DATA 0x32
-
-#define RING_BUS_CTRL_A 0x36
-#define RAC_PME_ENABLE 0x0100
-#define RAC_SDFS_ENABLE 0x0200
-#define LAC_PME_ENABLE 0x0400
-#define LAC_SDFS_ENABLE 0x0800
-#define SERIAL_AC_LINK_ENABLE 0x1000
-#define IO_SRAM_ENABLE 0x2000
-#define IIS_INPUT_ENABLE 0x8000
-
-#define RING_BUS_CTRL_B 0x38
-#define SECOND_CODEC_ID_MASK 0x0003
-#define SPDIF_FUNC_ENABLE 0x0010
-#define SECOND_AC_ENABLE 0x0020
-#define SB_MODULE_INTF_ENABLE 0x0040
-#define SSPE_ENABLE 0x0040
-#define M3I_DOCK_ENABLE 0x0080
-
-#define SDO_OUT_DEST_CTRL 0x3A
-#define COMMAND_ADDR_OUT 0x0003
-#define PCM_LR_OUT_LOCAL 0x0000
-#define PCM_LR_OUT_REMOTE 0x0004
-#define PCM_LR_OUT_MUTE 0x0008
-#define PCM_LR_OUT_BOTH 0x000C
-#define LINE1_DAC_OUT_LOCAL 0x0000
-#define LINE1_DAC_OUT_REMOTE 0x0010
-#define LINE1_DAC_OUT_MUTE 0x0020
-#define LINE1_DAC_OUT_BOTH 0x0030
-#define PCM_CLS_OUT_LOCAL 0x0000
-#define PCM_CLS_OUT_REMOTE 0x0040
-#define PCM_CLS_OUT_MUTE 0x0080
-#define PCM_CLS_OUT_BOTH 0x00C0
-#define PCM_RLF_OUT_LOCAL 0x0000
-#define PCM_RLF_OUT_REMOTE 0x0100
-#define PCM_RLF_OUT_MUTE 0x0200
-#define PCM_RLF_OUT_BOTH 0x0300
-#define LINE2_DAC_OUT_LOCAL 0x0000
-#define LINE2_DAC_OUT_REMOTE 0x0400
-#define LINE2_DAC_OUT_MUTE 0x0800
-#define LINE2_DAC_OUT_BOTH 0x0C00
-#define HANDSET_OUT_LOCAL 0x0000
-#define HANDSET_OUT_REMOTE 0x1000
-#define HANDSET_OUT_MUTE 0x2000
-#define HANDSET_OUT_BOTH 0x3000
-#define IO_CTRL_OUT_LOCAL 0x0000
-#define IO_CTRL_OUT_REMOTE 0x4000
-#define IO_CTRL_OUT_MUTE 0x8000
-#define IO_CTRL_OUT_BOTH 0xC000
-
-#define SDO_IN_DEST_CTRL 0x3C
-#define STATUS_ADDR_IN 0x0003
-#define PCM_LR_IN_LOCAL 0x0000
-#define PCM_LR_IN_REMOTE 0x0004
-#define PCM_LR_RESERVED 0x0008
-#define PCM_LR_IN_BOTH 0x000C
-#define LINE1_ADC_IN_LOCAL 0x0000
-#define LINE1_ADC_IN_REMOTE 0x0010
-#define LINE1_ADC_IN_MUTE 0x0020
-#define MIC_ADC_IN_LOCAL 0x0000
-#define MIC_ADC_IN_REMOTE 0x0040
-#define MIC_ADC_IN_MUTE 0x0080
-#define LINE2_DAC_IN_LOCAL 0x0000
-#define LINE2_DAC_IN_REMOTE 0x0400
-#define LINE2_DAC_IN_MUTE 0x0800
-#define HANDSET_IN_LOCAL 0x0000
-#define HANDSET_IN_REMOTE 0x1000
-#define HANDSET_IN_MUTE 0x2000
-#define IO_STATUS_IN_LOCAL 0x0000
-#define IO_STATUS_IN_REMOTE 0x4000
-
-#define SPDIF_IN_CTRL 0x3E
-#define SPDIF_IN_ENABLE 0x0001
-
-#define GPIO_DATA 0x60
-#define GPIO_DATA_MASK 0x0FFF
-#define GPIO_HV_STATUS 0x3000
-#define GPIO_PME_STATUS 0x4000
-
-#define GPIO_MASK 0x64
-#define GPIO_DIRECTION 0x68
-#define GPO_PRIMARY_AC97 0x0001
-#define GPI_LINEOUT_SENSE 0x0004
-#define GPO_SECONDARY_AC97 0x0008
-#define GPI_VOL_DOWN 0x0010
-#define GPI_VOL_UP 0x0020
-#define GPI_IIS_CLK 0x0040
-#define GPI_IIS_LRCLK 0x0080
-#define GPI_IIS_DATA 0x0100
-#define GPI_DOCKING_STATUS 0x0100
-#define GPI_HEADPHONE_SENSE 0x0200
-#define GPO_EXT_AMP_SHUTDOWN 0x1000
-
-#define GPO_EXT_AMP_M3 1 /* default m3 amp */
-#define GPO_EXT_AMP_ALLEGRO 8 /* default allegro amp */
-
-/* M3 */
-#define GPO_M3_EXT_AMP_SHUTDN 0x0002
-
-#define ASSP_INDEX_PORT 0x80
-#define ASSP_MEMORY_PORT 0x82
-#define ASSP_DATA_PORT 0x84
-
-#define MPU401_DATA_PORT 0x98
-#define MPU401_STATUS_PORT 0x99
-
-#define CLK_MULT_DATA_PORT 0x9C
-
-#define ASSP_CONTROL_A 0xA2
-#define ASSP_0_WS_ENABLE 0x01
-#define ASSP_CTRL_A_RESERVED1 0x02
-#define ASSP_CTRL_A_RESERVED2 0x04
-#define ASSP_CLK_49MHZ_SELECT 0x08
-#define FAST_PLU_ENABLE 0x10
-#define ASSP_CTRL_A_RESERVED3 0x20
-#define DSP_CLK_36MHZ_SELECT 0x40
-
-#define ASSP_CONTROL_B 0xA4
-#define RESET_ASSP 0x00
-#define RUN_ASSP 0x01
-#define ENABLE_ASSP_CLOCK 0x00
-#define STOP_ASSP_CLOCK 0x10
-#define RESET_TOGGLE 0x40
-
-#define ASSP_CONTROL_C 0xA6
-#define ASSP_HOST_INT_ENABLE 0x01
-#define FM_ADDR_REMAP_DISABLE 0x02
-#define HOST_WRITE_PORT_ENABLE 0x08
-
-#define ASSP_HOST_INT_STATUS 0xAC
-#define DSP2HOST_REQ_PIORECORD 0x01
-#define DSP2HOST_REQ_I2SRATE 0x02
-#define DSP2HOST_REQ_TIMER 0x04
-
-/* AC97 registers */
-/* XXX fix this crap up */
-/*#define AC97_RESET 0x00*/
-
-#define AC97_VOL_MUTE_B 0x8000
-#define AC97_VOL_M 0x1F
-#define AC97_LEFT_VOL_S 8
-
-#define AC97_MASTER_VOL 0x02
-#define AC97_LINE_LEVEL_VOL 0x04
-#define AC97_MASTER_MONO_VOL 0x06
-#define AC97_PC_BEEP_VOL 0x0A
-#define AC97_PC_BEEP_VOL_M 0x0F
-#define AC97_SROUND_MASTER_VOL 0x38
-#define AC97_PC_BEEP_VOL_S 1
-
-/*#define AC97_PHONE_VOL 0x0C
-#define AC97_MIC_VOL 0x0E*/
-#define AC97_MIC_20DB_ENABLE 0x40
-
-/*#define AC97_LINEIN_VOL 0x10
-#define AC97_CD_VOL 0x12
-#define AC97_VIDEO_VOL 0x14
-#define AC97_AUX_VOL 0x16*/
-#define AC97_PCM_OUT_VOL 0x18
-/*#define AC97_RECORD_SELECT 0x1A*/
-#define AC97_RECORD_MIC 0x00
-#define AC97_RECORD_CD 0x01
-#define AC97_RECORD_VIDEO 0x02
-#define AC97_RECORD_AUX 0x03
-#define AC97_RECORD_MONO_MUX 0x02
-#define AC97_RECORD_DIGITAL 0x03
-#define AC97_RECORD_LINE 0x04
-#define AC97_RECORD_STEREO 0x05
-#define AC97_RECORD_MONO 0x06
-#define AC97_RECORD_PHONE 0x07
-
-/*#define AC97_RECORD_GAIN 0x1C*/
-#define AC97_RECORD_VOL_M 0x0F
-
-/*#define AC97_GENERAL_PURPOSE 0x20*/
-#define AC97_POWER_DOWN_CTRL 0x26
-#define AC97_ADC_READY 0x0001
-#define AC97_DAC_READY 0x0002
-#define AC97_ANALOG_READY 0x0004
-#define AC97_VREF_ON 0x0008
-#define AC97_PR0 0x0100
-#define AC97_PR1 0x0200
-#define AC97_PR2 0x0400
-#define AC97_PR3 0x0800
-#define AC97_PR4 0x1000
-
-#define AC97_RESERVED1 0x28
-
-#define AC97_VENDOR_TEST 0x5A
-
-#define AC97_CLOCK_DELAY 0x5C
-#define AC97_LINEOUT_MUX_SEL 0x0001
-#define AC97_MONO_MUX_SEL 0x0002
-#define AC97_CLOCK_DELAY_SEL 0x1F
-#define AC97_DAC_CDS_SHIFT 6
-#define AC97_ADC_CDS_SHIFT 11
-
-#define AC97_MULTI_CHANNEL_SEL 0x74
-
-/*#define AC97_VENDOR_ID1 0x7C
-#define AC97_VENDOR_ID2 0x7E*/
-
-/*
- * ASSP control regs
- */
-#define DSP_PORT_TIMER_COUNT 0x06
-
-#define DSP_PORT_MEMORY_INDEX 0x80
-
-#define DSP_PORT_MEMORY_TYPE 0x82
-#define MEMTYPE_INTERNAL_CODE 0x0002
-#define MEMTYPE_INTERNAL_DATA 0x0003
-#define MEMTYPE_MASK 0x0003
-
-#define DSP_PORT_MEMORY_DATA 0x84
-
-#define DSP_PORT_CONTROL_REG_A 0xA2
-#define DSP_PORT_CONTROL_REG_B 0xA4
-#define DSP_PORT_CONTROL_REG_C 0xA6
-
-#define REV_A_CODE_MEMORY_BEGIN 0x0000
-#define REV_A_CODE_MEMORY_END 0x0FFF
-#define REV_A_CODE_MEMORY_UNIT_LENGTH 0x0040
-#define REV_A_CODE_MEMORY_LENGTH (REV_A_CODE_MEMORY_END - REV_A_CODE_MEMORY_BEGIN + 1)
-
-#define REV_B_CODE_MEMORY_BEGIN 0x0000
-#define REV_B_CODE_MEMORY_END 0x0BFF
-#define REV_B_CODE_MEMORY_UNIT_LENGTH 0x0040
-#define REV_B_CODE_MEMORY_LENGTH (REV_B_CODE_MEMORY_END - REV_B_CODE_MEMORY_BEGIN + 1)
-
-#define REV_A_DATA_MEMORY_BEGIN 0x1000
-#define REV_A_DATA_MEMORY_END 0x2FFF
-#define REV_A_DATA_MEMORY_UNIT_LENGTH 0x0080
-#define REV_A_DATA_MEMORY_LENGTH (REV_A_DATA_MEMORY_END - REV_A_DATA_MEMORY_BEGIN + 1)
-
-#define REV_B_DATA_MEMORY_BEGIN 0x1000
-#define REV_B_DATA_MEMORY_END 0x2BFF
-#define REV_B_DATA_MEMORY_UNIT_LENGTH 0x0080
-#define REV_B_DATA_MEMORY_LENGTH (REV_B_DATA_MEMORY_END - REV_B_DATA_MEMORY_BEGIN + 1)
-
-
-#define NUM_UNITS_KERNEL_CODE 16
-#define NUM_UNITS_KERNEL_DATA 2
-
-#define NUM_UNITS_KERNEL_CODE_WITH_HSP 16
-#define NUM_UNITS_KERNEL_DATA_WITH_HSP 5
-
-/*
- * Kernel data layout
- */
-
-#define DP_SHIFT_COUNT 7
-
-#define KDATA_BASE_ADDR 0x1000
-#define KDATA_BASE_ADDR2 0x1080
-
-#define KDATA_TASK0 (KDATA_BASE_ADDR + 0x0000)
-#define KDATA_TASK1 (KDATA_BASE_ADDR + 0x0001)
-#define KDATA_TASK2 (KDATA_BASE_ADDR + 0x0002)
-#define KDATA_TASK3 (KDATA_BASE_ADDR + 0x0003)
-#define KDATA_TASK4 (KDATA_BASE_ADDR + 0x0004)
-#define KDATA_TASK5 (KDATA_BASE_ADDR + 0x0005)
-#define KDATA_TASK6 (KDATA_BASE_ADDR + 0x0006)
-#define KDATA_TASK7 (KDATA_BASE_ADDR + 0x0007)
-#define KDATA_TASK_ENDMARK (KDATA_BASE_ADDR + 0x0008)
-
-#define KDATA_CURRENT_TASK (KDATA_BASE_ADDR + 0x0009)
-#define KDATA_TASK_SWITCH (KDATA_BASE_ADDR + 0x000A)
-
-#define KDATA_INSTANCE0_POS3D (KDATA_BASE_ADDR + 0x000B)
-#define KDATA_INSTANCE1_POS3D (KDATA_BASE_ADDR + 0x000C)
-#define KDATA_INSTANCE2_POS3D (KDATA_BASE_ADDR + 0x000D)
-#define KDATA_INSTANCE3_POS3D (KDATA_BASE_ADDR + 0x000E)
-#define KDATA_INSTANCE4_POS3D (KDATA_BASE_ADDR + 0x000F)
-#define KDATA_INSTANCE5_POS3D (KDATA_BASE_ADDR + 0x0010)
-#define KDATA_INSTANCE6_POS3D (KDATA_BASE_ADDR + 0x0011)
-#define KDATA_INSTANCE7_POS3D (KDATA_BASE_ADDR + 0x0012)
-#define KDATA_INSTANCE8_POS3D (KDATA_BASE_ADDR + 0x0013)
-#define KDATA_INSTANCE_POS3D_ENDMARK (KDATA_BASE_ADDR + 0x0014)
-
-#define KDATA_INSTANCE0_SPKVIRT (KDATA_BASE_ADDR + 0x0015)
-#define KDATA_INSTANCE_SPKVIRT_ENDMARK (KDATA_BASE_ADDR + 0x0016)
-
-#define KDATA_INSTANCE0_SPDIF (KDATA_BASE_ADDR + 0x0017)
-#define KDATA_INSTANCE_SPDIF_ENDMARK (KDATA_BASE_ADDR + 0x0018)
-
-#define KDATA_INSTANCE0_MODEM (KDATA_BASE_ADDR + 0x0019)
-#define KDATA_INSTANCE_MODEM_ENDMARK (KDATA_BASE_ADDR + 0x001A)
-
-#define KDATA_INSTANCE0_SRC (KDATA_BASE_ADDR + 0x001B)
-#define KDATA_INSTANCE1_SRC (KDATA_BASE_ADDR + 0x001C)
-#define KDATA_INSTANCE_SRC_ENDMARK (KDATA_BASE_ADDR + 0x001D)
-
-#define KDATA_INSTANCE0_MINISRC (KDATA_BASE_ADDR + 0x001E)
-#define KDATA_INSTANCE1_MINISRC (KDATA_BASE_ADDR + 0x001F)
-#define KDATA_INSTANCE2_MINISRC (KDATA_BASE_ADDR + 0x0020)
-#define KDATA_INSTANCE3_MINISRC (KDATA_BASE_ADDR + 0x0021)
-#define KDATA_INSTANCE_MINISRC_ENDMARK (KDATA_BASE_ADDR + 0x0022)
-
-#define KDATA_INSTANCE0_CPYTHRU (KDATA_BASE_ADDR + 0x0023)
-#define KDATA_INSTANCE1_CPYTHRU (KDATA_BASE_ADDR + 0x0024)
-#define KDATA_INSTANCE_CPYTHRU_ENDMARK (KDATA_BASE_ADDR + 0x0025)
-
-#define KDATA_CURRENT_DMA (KDATA_BASE_ADDR + 0x0026)
-#define KDATA_DMA_SWITCH (KDATA_BASE_ADDR + 0x0027)
-#define KDATA_DMA_ACTIVE (KDATA_BASE_ADDR + 0x0028)
-
-#define KDATA_DMA_XFER0 (KDATA_BASE_ADDR + 0x0029)
-#define KDATA_DMA_XFER1 (KDATA_BASE_ADDR + 0x002A)
-#define KDATA_DMA_XFER2 (KDATA_BASE_ADDR + 0x002B)
-#define KDATA_DMA_XFER3 (KDATA_BASE_ADDR + 0x002C)
-#define KDATA_DMA_XFER4 (KDATA_BASE_ADDR + 0x002D)
-#define KDATA_DMA_XFER5 (KDATA_BASE_ADDR + 0x002E)
-#define KDATA_DMA_XFER6 (KDATA_BASE_ADDR + 0x002F)
-#define KDATA_DMA_XFER7 (KDATA_BASE_ADDR + 0x0030)
-#define KDATA_DMA_XFER8 (KDATA_BASE_ADDR + 0x0031)
-#define KDATA_DMA_XFER_ENDMARK (KDATA_BASE_ADDR + 0x0032)
-
-#define KDATA_I2S_SAMPLE_COUNT (KDATA_BASE_ADDR + 0x0033)
-#define KDATA_I2S_INT_METER (KDATA_BASE_ADDR + 0x0034)
-#define KDATA_I2S_ACTIVE (KDATA_BASE_ADDR + 0x0035)
-
-#define KDATA_TIMER_COUNT_RELOAD (KDATA_BASE_ADDR + 0x0036)
-#define KDATA_TIMER_COUNT_CURRENT (KDATA_BASE_ADDR + 0x0037)
-
-#define KDATA_HALT_SYNCH_CLIENT (KDATA_BASE_ADDR + 0x0038)
-#define KDATA_HALT_SYNCH_DMA (KDATA_BASE_ADDR + 0x0039)
-#define KDATA_HALT_ACKNOWLEDGE (KDATA_BASE_ADDR + 0x003A)
-
-#define KDATA_ADC1_XFER0 (KDATA_BASE_ADDR + 0x003B)
-#define KDATA_ADC1_XFER_ENDMARK (KDATA_BASE_ADDR + 0x003C)
-#define KDATA_ADC1_LEFT_VOLUME (KDATA_BASE_ADDR + 0x003D)
-#define KDATA_ADC1_RIGHT_VOLUME (KDATA_BASE_ADDR + 0x003E)
-#define KDATA_ADC1_LEFT_SUR_VOL (KDATA_BASE_ADDR + 0x003F)
-#define KDATA_ADC1_RIGHT_SUR_VOL (KDATA_BASE_ADDR + 0x0040)
-
-#define KDATA_ADC2_XFER0 (KDATA_BASE_ADDR + 0x0041)
-#define KDATA_ADC2_XFER_ENDMARK (KDATA_BASE_ADDR + 0x0042)
-#define KDATA_ADC2_LEFT_VOLUME (KDATA_BASE_ADDR + 0x0043)
-#define KDATA_ADC2_RIGHT_VOLUME (KDATA_BASE_ADDR + 0x0044)
-#define KDATA_ADC2_LEFT_SUR_VOL (KDATA_BASE_ADDR + 0x0045)
-#define KDATA_ADC2_RIGHT_SUR_VOL (KDATA_BASE_ADDR + 0x0046)
-
-#define KDATA_CD_XFER0 (KDATA_BASE_ADDR + 0x0047)
-#define KDATA_CD_XFER_ENDMARK (KDATA_BASE_ADDR + 0x0048)
-#define KDATA_CD_LEFT_VOLUME (KDATA_BASE_ADDR + 0x0049)
-#define KDATA_CD_RIGHT_VOLUME (KDATA_BASE_ADDR + 0x004A)
-#define KDATA_CD_LEFT_SUR_VOL (KDATA_BASE_ADDR + 0x004B)
-#define KDATA_CD_RIGHT_SUR_VOL (KDATA_BASE_ADDR + 0x004C)
-
-#define KDATA_MIC_XFER0 (KDATA_BASE_ADDR + 0x004D)
-#define KDATA_MIC_XFER_ENDMARK (KDATA_BASE_ADDR + 0x004E)
-#define KDATA_MIC_VOLUME (KDATA_BASE_ADDR + 0x004F)
-#define KDATA_MIC_SUR_VOL (KDATA_BASE_ADDR + 0x0050)
-
-#define KDATA_I2S_XFER0 (KDATA_BASE_ADDR + 0x0051)
-#define KDATA_I2S_XFER_ENDMARK (KDATA_BASE_ADDR + 0x0052)
-
-#define KDATA_CHI_XFER0 (KDATA_BASE_ADDR + 0x0053)
-#define KDATA_CHI_XFER_ENDMARK (KDATA_BASE_ADDR + 0x0054)
-
-#define KDATA_SPDIF_XFER (KDATA_BASE_ADDR + 0x0055)
-#define KDATA_SPDIF_CURRENT_FRAME (KDATA_BASE_ADDR + 0x0056)
-#define KDATA_SPDIF_FRAME0 (KDATA_BASE_ADDR + 0x0057)
-#define KDATA_SPDIF_FRAME1 (KDATA_BASE_ADDR + 0x0058)
-#define KDATA_SPDIF_FRAME2 (KDATA_BASE_ADDR + 0x0059)
-
-#define KDATA_SPDIF_REQUEST (KDATA_BASE_ADDR + 0x005A)
-#define KDATA_SPDIF_TEMP (KDATA_BASE_ADDR + 0x005B)
-
-#define KDATA_SPDIFIN_XFER0 (KDATA_BASE_ADDR + 0x005C)
-#define KDATA_SPDIFIN_XFER_ENDMARK (KDATA_BASE_ADDR + 0x005D)
-#define KDATA_SPDIFIN_INT_METER (KDATA_BASE_ADDR + 0x005E)
-
-#define KDATA_DSP_RESET_COUNT (KDATA_BASE_ADDR + 0x005F)
-#define KDATA_DEBUG_OUTPUT (KDATA_BASE_ADDR + 0x0060)
-
-#define KDATA_KERNEL_ISR_LIST (KDATA_BASE_ADDR + 0x0061)
-
-#define KDATA_KERNEL_ISR_CBSR1 (KDATA_BASE_ADDR + 0x0062)
-#define KDATA_KERNEL_ISR_CBER1 (KDATA_BASE_ADDR + 0x0063)
-#define KDATA_KERNEL_ISR_CBCR (KDATA_BASE_ADDR + 0x0064)
-#define KDATA_KERNEL_ISR_AR0 (KDATA_BASE_ADDR + 0x0065)
-#define KDATA_KERNEL_ISR_AR1 (KDATA_BASE_ADDR + 0x0066)
-#define KDATA_KERNEL_ISR_AR2 (KDATA_BASE_ADDR + 0x0067)
-#define KDATA_KERNEL_ISR_AR3 (KDATA_BASE_ADDR + 0x0068)
-#define KDATA_KERNEL_ISR_AR4 (KDATA_BASE_ADDR + 0x0069)
-#define KDATA_KERNEL_ISR_AR5 (KDATA_BASE_ADDR + 0x006A)
-#define KDATA_KERNEL_ISR_BRCR (KDATA_BASE_ADDR + 0x006B)
-#define KDATA_KERNEL_ISR_PASR (KDATA_BASE_ADDR + 0x006C)
-#define KDATA_KERNEL_ISR_PAER (KDATA_BASE_ADDR + 0x006D)
-
-#define KDATA_CLIENT_SCRATCH0 (KDATA_BASE_ADDR + 0x006E)
-#define KDATA_CLIENT_SCRATCH1 (KDATA_BASE_ADDR + 0x006F)
-#define KDATA_KERNEL_SCRATCH (KDATA_BASE_ADDR + 0x0070)
-#define KDATA_KERNEL_ISR_SCRATCH (KDATA_BASE_ADDR + 0x0071)
-
-#define KDATA_OUEUE_LEFT (KDATA_BASE_ADDR + 0x0072)
-#define KDATA_QUEUE_RIGHT (KDATA_BASE_ADDR + 0x0073)
-
-#define KDATA_ADC1_REQUEST (KDATA_BASE_ADDR + 0x0074)
-#define KDATA_ADC2_REQUEST (KDATA_BASE_ADDR + 0x0075)
-#define KDATA_CD_REQUEST (KDATA_BASE_ADDR + 0x0076)
-#define KDATA_MIC_REQUEST (KDATA_BASE_ADDR + 0x0077)
-
-#define KDATA_ADC1_MIXER_REQUEST (KDATA_BASE_ADDR + 0x0078)
-#define KDATA_ADC2_MIXER_REQUEST (KDATA_BASE_ADDR + 0x0079)
-#define KDATA_CD_MIXER_REQUEST (KDATA_BASE_ADDR + 0x007A)
-#define KDATA_MIC_MIXER_REQUEST (KDATA_BASE_ADDR + 0x007B)
-#define KDATA_MIC_SYNC_COUNTER (KDATA_BASE_ADDR + 0x007C)
-
-/*
- * second 'segment' (?) reserved for mixer
- * buffers..
- */
-
-#define KDATA_MIXER_WORD0 (KDATA_BASE_ADDR2 + 0x0000)
-#define KDATA_MIXER_WORD1 (KDATA_BASE_ADDR2 + 0x0001)
-#define KDATA_MIXER_WORD2 (KDATA_BASE_ADDR2 + 0x0002)
-#define KDATA_MIXER_WORD3 (KDATA_BASE_ADDR2 + 0x0003)
-#define KDATA_MIXER_WORD4 (KDATA_BASE_ADDR2 + 0x0004)
-#define KDATA_MIXER_WORD5 (KDATA_BASE_ADDR2 + 0x0005)
-#define KDATA_MIXER_WORD6 (KDATA_BASE_ADDR2 + 0x0006)
-#define KDATA_MIXER_WORD7 (KDATA_BASE_ADDR2 + 0x0007)
-#define KDATA_MIXER_WORD8 (KDATA_BASE_ADDR2 + 0x0008)
-#define KDATA_MIXER_WORD9 (KDATA_BASE_ADDR2 + 0x0009)
-#define KDATA_MIXER_WORDA (KDATA_BASE_ADDR2 + 0x000A)
-#define KDATA_MIXER_WORDB (KDATA_BASE_ADDR2 + 0x000B)
-#define KDATA_MIXER_WORDC (KDATA_BASE_ADDR2 + 0x000C)
-#define KDATA_MIXER_WORDD (KDATA_BASE_ADDR2 + 0x000D)
-#define KDATA_MIXER_WORDE (KDATA_BASE_ADDR2 + 0x000E)
-#define KDATA_MIXER_WORDF (KDATA_BASE_ADDR2 + 0x000F)
-
-#define KDATA_MIXER_XFER0 (KDATA_BASE_ADDR2 + 0x0010)
-#define KDATA_MIXER_XFER1 (KDATA_BASE_ADDR2 + 0x0011)
-#define KDATA_MIXER_XFER2 (KDATA_BASE_ADDR2 + 0x0012)
-#define KDATA_MIXER_XFER3 (KDATA_BASE_ADDR2 + 0x0013)
-#define KDATA_MIXER_XFER4 (KDATA_BASE_ADDR2 + 0x0014)
-#define KDATA_MIXER_XFER5 (KDATA_BASE_ADDR2 + 0x0015)
-#define KDATA_MIXER_XFER6 (KDATA_BASE_ADDR2 + 0x0016)
-#define KDATA_MIXER_XFER7 (KDATA_BASE_ADDR2 + 0x0017)
-#define KDATA_MIXER_XFER8 (KDATA_BASE_ADDR2 + 0x0018)
-#define KDATA_MIXER_XFER9 (KDATA_BASE_ADDR2 + 0x0019)
-#define KDATA_MIXER_XFER_ENDMARK (KDATA_BASE_ADDR2 + 0x001A)
-
-#define KDATA_MIXER_TASK_NUMBER (KDATA_BASE_ADDR2 + 0x001B)
-#define KDATA_CURRENT_MIXER (KDATA_BASE_ADDR2 + 0x001C)
-#define KDATA_MIXER_ACTIVE (KDATA_BASE_ADDR2 + 0x001D)
-#define KDATA_MIXER_BANK_STATUS (KDATA_BASE_ADDR2 + 0x001E)
-#define KDATA_DAC_LEFT_VOLUME (KDATA_BASE_ADDR2 + 0x001F)
-#define KDATA_DAC_RIGHT_VOLUME (KDATA_BASE_ADDR2 + 0x0020)
-
-#define MAX_INSTANCE_MINISRC (KDATA_INSTANCE_MINISRC_ENDMARK - KDATA_INSTANCE0_MINISRC)
-#define MAX_VIRTUAL_DMA_CHANNELS (KDATA_DMA_XFER_ENDMARK - KDATA_DMA_XFER0)
-#define MAX_VIRTUAL_MIXER_CHANNELS (KDATA_MIXER_XFER_ENDMARK - KDATA_MIXER_XFER0)
-#define MAX_VIRTUAL_ADC1_CHANNELS (KDATA_ADC1_XFER_ENDMARK - KDATA_ADC1_XFER0)
-
-/*
- * client data area offsets
- */
-#define CDATA_INSTANCE_READY 0x00
-
-#define CDATA_HOST_SRC_ADDRL 0x01
-#define CDATA_HOST_SRC_ADDRH 0x02
-#define CDATA_HOST_SRC_END_PLUS_1L 0x03
-#define CDATA_HOST_SRC_END_PLUS_1H 0x04
-#define CDATA_HOST_SRC_CURRENTL 0x05
-#define CDATA_HOST_SRC_CURRENTH 0x06
-
-#define CDATA_IN_BUF_CONNECT 0x07
-#define CDATA_OUT_BUF_CONNECT 0x08
-
-#define CDATA_IN_BUF_BEGIN 0x09
-#define CDATA_IN_BUF_END_PLUS_1 0x0A
-#define CDATA_IN_BUF_HEAD 0x0B
-#define CDATA_IN_BUF_TAIL 0x0C
-#define CDATA_OUT_BUF_BEGIN 0x0D
-#define CDATA_OUT_BUF_END_PLUS_1 0x0E
-#define CDATA_OUT_BUF_HEAD 0x0F
-#define CDATA_OUT_BUF_TAIL 0x10
-
-#define CDATA_DMA_CONTROL 0x11
-#define CDATA_RESERVED 0x12
-
-#define CDATA_FREQUENCY 0x13
-#define CDATA_LEFT_VOLUME 0x14
-#define CDATA_RIGHT_VOLUME 0x15
-#define CDATA_LEFT_SUR_VOL 0x16
-#define CDATA_RIGHT_SUR_VOL 0x17
-
-#define CDATA_HEADER_LEN 0x18
-
-#define SRC3_DIRECTION_OFFSET CDATA_HEADER_LEN
-#define SRC3_MODE_OFFSET (CDATA_HEADER_LEN + 1)
-#define SRC3_WORD_LENGTH_OFFSET (CDATA_HEADER_LEN + 2)
-#define SRC3_PARAMETER_OFFSET (CDATA_HEADER_LEN + 3)
-#define SRC3_COEFF_ADDR_OFFSET (CDATA_HEADER_LEN + 8)
-#define SRC3_FILTAP_ADDR_OFFSET (CDATA_HEADER_LEN + 10)
-#define SRC3_TEMP_INBUF_ADDR_OFFSET (CDATA_HEADER_LEN + 16)
-#define SRC3_TEMP_OUTBUF_ADDR_OFFSET (CDATA_HEADER_LEN + 17)
-
-#define MINISRC_IN_BUFFER_SIZE ( 0x50 * 2 )
-#define MINISRC_OUT_BUFFER_SIZE ( 0x50 * 2 * 2)
-#define MINISRC_TMP_BUFFER_SIZE ( 112 + ( MINISRC_BIQUAD_STAGE * 3 + 4 ) * 2 * 2 )
-#define MINISRC_BIQUAD_STAGE 2
-#define MINISRC_COEF_LOC 0x175
-
-#define DMACONTROL_BLOCK_MASK 0x000F
-#define DMAC_BLOCK0_SELECTOR 0x0000
-#define DMAC_BLOCK1_SELECTOR 0x0001
-#define DMAC_BLOCK2_SELECTOR 0x0002
-#define DMAC_BLOCK3_SELECTOR 0x0003
-#define DMAC_BLOCK4_SELECTOR 0x0004
-#define DMAC_BLOCK5_SELECTOR 0x0005
-#define DMAC_BLOCK6_SELECTOR 0x0006
-#define DMAC_BLOCK7_SELECTOR 0x0007
-#define DMAC_BLOCK8_SELECTOR 0x0008
-#define DMAC_BLOCK9_SELECTOR 0x0009
-#define DMAC_BLOCKA_SELECTOR 0x000A
-#define DMAC_BLOCKB_SELECTOR 0x000B
-#define DMAC_BLOCKC_SELECTOR 0x000C
-#define DMAC_BLOCKD_SELECTOR 0x000D
-#define DMAC_BLOCKE_SELECTOR 0x000E
-#define DMAC_BLOCKF_SELECTOR 0x000F
-#define DMACONTROL_PAGE_MASK 0x00F0
-#define DMAC_PAGE0_SELECTOR 0x0030
-#define DMAC_PAGE1_SELECTOR 0x0020
-#define DMAC_PAGE2_SELECTOR 0x0010
-#define DMAC_PAGE3_SELECTOR 0x0000
-#define DMACONTROL_AUTOREPEAT 0x1000
-#define DMACONTROL_STOPPED 0x2000
-#define DMACONTROL_DIRECTION 0x0100
-
-/*
- * an arbitrary volume we set the internal
- * volume settings to so that the ac97 volume
- * range is a little less insane. 0x7fff is
- * max.
- */
-#define ARB_VOLUME ( 0x6800 )
-
-/*
- */
-
-struct m3_list {
- int curlen;
- int mem_addr;
- int max;
-};
-
-struct m3_dma {
-
- int number;
- struct snd_pcm_substream *substream;
-
- struct assp_instance {
- unsigned short code, data;
- } inst;
-
- int running;
- int opened;
-
- unsigned long buffer_addr;
- int dma_size;
- int period_size;
- unsigned int hwptr;
- int count;
-
- int index[3];
- struct m3_list *index_list[3];
-
- int in_lists;
-
- struct list_head list;
-
-};
-
-struct snd_m3 {
-
- struct snd_card *card;
-
- unsigned long iobase;
-
- int irq;
- unsigned int allegro_flag : 1;
-
- struct snd_ac97 *ac97;
-
- struct snd_pcm *pcm;
-
- struct pci_dev *pci;
-
- int dacs_active;
- int timer_users;
-
- struct m3_list msrc_list;
- struct m3_list mixer_list;
- struct m3_list adc1_list;
- struct m3_list dma_list;
-
- /* for storing reset state..*/
- u8 reset_state;
-
- int external_amp;
- int amp_gpio; /* gpio pin # for external amp, -1 = default */
- unsigned int hv_config; /* hardware-volume config bits */
- unsigned irda_workaround :1; /* avoid to touch 0x10 on GPIO_DIRECTION
- (e.g. for IrDA on Dell Inspirons) */
- unsigned is_omnibook :1; /* Do HP OmniBook GPIO magic? */
-
- /* midi */
- struct snd_rawmidi *rmidi;
-
- /* pcm streams */
- int num_substreams;
- struct m3_dma *substreams;
-
- spinlock_t reg_lock;
-
-#ifdef CONFIG_SND_MAESTRO3_INPUT
- struct input_dev *input_dev;
- char phys[64]; /* physical device path */
-#else
- struct snd_kcontrol *master_switch;
- struct snd_kcontrol *master_volume;
-#endif
- struct work_struct hwvol_work;
-
- unsigned int in_suspend;
-
-#ifdef CONFIG_PM
- u16 *suspend_mem;
-#endif
-
- const struct firmware *assp_kernel_image;
- const struct firmware *assp_minisrc_image;
-};
-
-/*
- * pci ids
- */
-static DEFINE_PCI_DEVICE_TABLE(snd_m3_ids) = {
- {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO_1, PCI_ANY_ID, PCI_ANY_ID,
- PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
- {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO, PCI_ANY_ID, PCI_ANY_ID,
- PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
- {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_CANYON3D_2LE, PCI_ANY_ID, PCI_ANY_ID,
- PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
- {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_CANYON3D_2, PCI_ANY_ID, PCI_ANY_ID,
- PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
- {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_MAESTRO3, PCI_ANY_ID, PCI_ANY_ID,
- PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
- {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_MAESTRO3_1, PCI_ANY_ID, PCI_ANY_ID,
- PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
- {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_MAESTRO3_HW, PCI_ANY_ID, PCI_ANY_ID,
- PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
- {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_MAESTRO3_2, PCI_ANY_ID, PCI_ANY_ID,
- PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
- {0,},
-};
-
-MODULE_DEVICE_TABLE(pci, snd_m3_ids);
-
-static struct snd_pci_quirk m3_amp_quirk_list[] __devinitdata = {
- SND_PCI_QUIRK(0x0E11, 0x0094, "Compaq Evo N600c", 0x0c),
- SND_PCI_QUIRK(0x10f7, 0x833e, "Panasonic CF-28", 0x0d),
- SND_PCI_QUIRK(0x10f7, 0x833d, "Panasonic CF-72", 0x0d),
- SND_PCI_QUIRK(0x1033, 0x80f1, "NEC LM800J/7", 0x03),
- SND_PCI_QUIRK(0x1509, 0x1740, "LEGEND ZhaoYang 3100CF", 0x03),
- { } /* END */
-};
-
-static struct snd_pci_quirk m3_irda_quirk_list[] __devinitdata = {
- SND_PCI_QUIRK(0x1028, 0x00b0, "Dell Inspiron 4000", 1),
- SND_PCI_QUIRK(0x1028, 0x00a4, "Dell Inspiron 8000", 1),
- SND_PCI_QUIRK(0x1028, 0x00e6, "Dell Inspiron 8100", 1),
- { } /* END */
-};
-
-/* hardware volume quirks */
-static struct snd_pci_quirk m3_hv_quirk_list[] __devinitdata = {
- /* Allegro chips */
- SND_PCI_QUIRK(0x0E11, 0x002E, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x0E11, 0x0094, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x0E11, 0xB112, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x0E11, 0xB114, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x103C, 0x0012, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x103C, 0x0018, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x103C, 0x001C, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x103C, 0x001D, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x103C, 0x001E, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x107B, 0x3350, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x10F7, 0x8338, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x10F7, 0x833C, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x10F7, 0x833D, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x10F7, 0x833E, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x10F7, 0x833F, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x13BD, 0x1018, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x13BD, 0x1019, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x13BD, 0x101A, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x14FF, 0x0F03, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x14FF, 0x0F04, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x14FF, 0x0F05, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x156D, 0xB400, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x156D, 0xB795, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x156D, 0xB797, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x156D, 0xC700, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
- SND_PCI_QUIRK(0x1033, 0x80F1, NULL,
- HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
- SND_PCI_QUIRK(0x103C, 0x001A, NULL, /* HP OmniBook 6100 */
- HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
- SND_PCI_QUIRK(0x107B, 0x340A, NULL,
- HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
- SND_PCI_QUIRK(0x107B, 0x3450, NULL,
- HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
- SND_PCI_QUIRK(0x109F, 0x3134, NULL,
- HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
- SND_PCI_QUIRK(0x109F, 0x3161, NULL,
- HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
- SND_PCI_QUIRK(0x144D, 0x3280, NULL,
- HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
- SND_PCI_QUIRK(0x144D, 0x3281, NULL,
- HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
- SND_PCI_QUIRK(0x144D, 0xC002, NULL,
- HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
- SND_PCI_QUIRK(0x144D, 0xC003, NULL,
- HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
- SND_PCI_QUIRK(0x1509, 0x1740, NULL,
- HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
- SND_PCI_QUIRK(0x1610, 0x0010, NULL,
- HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
- SND_PCI_QUIRK(0x1042, 0x1042, NULL, HV_CTRL_ENABLE),
- SND_PCI_QUIRK(0x107B, 0x9500, NULL, HV_CTRL_ENABLE),
- SND_PCI_QUIRK(0x14FF, 0x0F06, NULL, HV_CTRL_ENABLE),
- SND_PCI_QUIRK(0x1558, 0x8586, NULL, HV_CTRL_ENABLE),
- SND_PCI_QUIRK(0x161F, 0x2011, NULL, HV_CTRL_ENABLE),
- /* Maestro3 chips */
- SND_PCI_QUIRK(0x103C, 0x000E, NULL, HV_CTRL_ENABLE),
- SND_PCI_QUIRK(0x103C, 0x0010, NULL, HV_CTRL_ENABLE),
- SND_PCI_QUIRK(0x103C, 0x0011, NULL, HV_CTRL_ENABLE),
- SND_PCI_QUIRK(0x103C, 0x001B, NULL, HV_CTRL_ENABLE),
- SND_PCI_QUIRK(0x104D, 0x80A6, NULL, HV_CTRL_ENABLE),
- SND_PCI_QUIRK(0x104D, 0x80AA, NULL, HV_CTRL_ENABLE),
- SND_PCI_QUIRK(0x107B, 0x5300, NULL, HV_CTRL_ENABLE),
- SND_PCI_QUIRK(0x110A, 0x1998, NULL, HV_CTRL_ENABLE),
- SND_PCI_QUIRK(0x13BD, 0x1015, NULL, HV_CTRL_ENABLE),
- SND_PCI_QUIRK(0x13BD, 0x101C, NULL, HV_CTRL_ENABLE),
- SND_PCI_QUIRK(0x13BD, 0x1802, NULL, HV_CTRL_ENABLE),
- SND_PCI_QUIRK(0x1599, 0x0715, NULL, HV_CTRL_ENABLE),
- SND_PCI_QUIRK(0x5643, 0x5643, NULL, HV_CTRL_ENABLE),
- SND_PCI_QUIRK(0x144D, 0x3260, NULL, HV_CTRL_ENABLE | REDUCED_DEBOUNCE),
- SND_PCI_QUIRK(0x144D, 0x3261, NULL, HV_CTRL_ENABLE | REDUCED_DEBOUNCE),
- SND_PCI_QUIRK(0x144D, 0xC000, NULL, HV_CTRL_ENABLE | REDUCED_DEBOUNCE),
- SND_PCI_QUIRK(0x144D, 0xC001, NULL, HV_CTRL_ENABLE | REDUCED_DEBOUNCE),
- { } /* END */
-};
-
-/* HP Omnibook quirks */
-static struct snd_pci_quirk m3_omnibook_quirk_list[] __devinitdata = {
- SND_PCI_QUIRK_ID(0x103c, 0x0010), /* HP OmniBook 6000 */
- SND_PCI_QUIRK_ID(0x103c, 0x0011), /* HP OmniBook 500 */
- { } /* END */
-};
-
-/*
- * lowlevel functions
- */
-
-static inline void snd_m3_outw(struct snd_m3 *chip, u16 value, unsigned long reg)
-{
- outw(value, chip->iobase + reg);
-}
-
-static inline u16 snd_m3_inw(struct snd_m3 *chip, unsigned long reg)
-{
- return inw(chip->iobase + reg);
-}
-
-static inline void snd_m3_outb(struct snd_m3 *chip, u8 value, unsigned long reg)
-{
- outb(value, chip->iobase + reg);
-}
-
-static inline u8 snd_m3_inb(struct snd_m3 *chip, unsigned long reg)
-{
- return inb(chip->iobase + reg);
-}
-
-/*
- * access 16bit words to the code or data regions of the dsp's memory.
- * index addresses 16bit words.
- */
-static u16 snd_m3_assp_read(struct snd_m3 *chip, u16 region, u16 index)
-{
- snd_m3_outw(chip, region & MEMTYPE_MASK, DSP_PORT_MEMORY_TYPE);
- snd_m3_outw(chip, index, DSP_PORT_MEMORY_INDEX);
- return snd_m3_inw(chip, DSP_PORT_MEMORY_DATA);
-}
-
-static void snd_m3_assp_write(struct snd_m3 *chip, u16 region, u16 index, u16 data)
-{
- snd_m3_outw(chip, region & MEMTYPE_MASK, DSP_PORT_MEMORY_TYPE);
- snd_m3_outw(chip, index, DSP_PORT_MEMORY_INDEX);
- snd_m3_outw(chip, data, DSP_PORT_MEMORY_DATA);
-}
-
-static void snd_m3_assp_halt(struct snd_m3 *chip)
-{
- chip->reset_state = snd_m3_inb(chip, DSP_PORT_CONTROL_REG_B) & ~REGB_STOP_CLOCK;
- msleep(10);
- snd_m3_outb(chip, chip->reset_state & ~REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B);
-}
-
-static void snd_m3_assp_continue(struct snd_m3 *chip)
-{
- snd_m3_outb(chip, chip->reset_state | REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B);
-}
-
-
-/*
- * This makes me sad. the maestro3 has lists
- * internally that must be packed.. 0 terminates,
- * apparently, or maybe all unused entries have
- * to be 0, the lists have static lengths set
- * by the binary code images.
- */
-
-static int snd_m3_add_list(struct snd_m3 *chip, struct m3_list *list, u16 val)
-{
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- list->mem_addr + list->curlen,
- val);
- return list->curlen++;
-}
-
-static void snd_m3_remove_list(struct snd_m3 *chip, struct m3_list *list, int index)
-{
- u16 val;
- int lastindex = list->curlen - 1;
-
- if (index != lastindex) {
- val = snd_m3_assp_read(chip, MEMTYPE_INTERNAL_DATA,
- list->mem_addr + lastindex);
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- list->mem_addr + index,
- val);
- }
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- list->mem_addr + lastindex,
- 0);
-
- list->curlen--;
-}
-
-static void snd_m3_inc_timer_users(struct snd_m3 *chip)
-{
- chip->timer_users++;
- if (chip->timer_users != 1)
- return;
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- KDATA_TIMER_COUNT_RELOAD,
- 240);
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- KDATA_TIMER_COUNT_CURRENT,
- 240);
-
- snd_m3_outw(chip,
- snd_m3_inw(chip, HOST_INT_CTRL) | CLKRUN_GEN_ENABLE,
- HOST_INT_CTRL);
-}
-
-static void snd_m3_dec_timer_users(struct snd_m3 *chip)
-{
- chip->timer_users--;
- if (chip->timer_users > 0)
- return;
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- KDATA_TIMER_COUNT_RELOAD,
- 0);
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- KDATA_TIMER_COUNT_CURRENT,
- 0);
-
- snd_m3_outw(chip,
- snd_m3_inw(chip, HOST_INT_CTRL) & ~CLKRUN_GEN_ENABLE,
- HOST_INT_CTRL);
-}
-
-/*
- * start/stop
- */
-
-/* spinlock held! */
-static int snd_m3_pcm_start(struct snd_m3 *chip, struct m3_dma *s,
- struct snd_pcm_substream *subs)
-{
- if (! s || ! subs)
- return -EINVAL;
-
- snd_m3_inc_timer_users(chip);
- switch (subs->stream) {
- case SNDRV_PCM_STREAM_PLAYBACK:
- chip->dacs_active++;
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_INSTANCE_READY, 1);
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- KDATA_MIXER_TASK_NUMBER,
- chip->dacs_active);
- break;
- case SNDRV_PCM_STREAM_CAPTURE:
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- KDATA_ADC1_REQUEST, 1);
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_INSTANCE_READY, 1);
- break;
- }
- return 0;
-}
-
-/* spinlock held! */
-static int snd_m3_pcm_stop(struct snd_m3 *chip, struct m3_dma *s,
- struct snd_pcm_substream *subs)
-{
- if (! s || ! subs)
- return -EINVAL;
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_INSTANCE_READY, 0);
- snd_m3_dec_timer_users(chip);
- switch (subs->stream) {
- case SNDRV_PCM_STREAM_PLAYBACK:
- chip->dacs_active--;
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- KDATA_MIXER_TASK_NUMBER,
- chip->dacs_active);
- break;
- case SNDRV_PCM_STREAM_CAPTURE:
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- KDATA_ADC1_REQUEST, 0);
- break;
- }
- return 0;
-}
-
-static int
-snd_m3_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
-{
- struct snd_m3 *chip = snd_pcm_substream_chip(subs);
- struct m3_dma *s = subs->runtime->private_data;
- int err = -EINVAL;
-
- if (snd_BUG_ON(!s))
- return -ENXIO;
-
- spin_lock(&chip->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- if (s->running)
- err = -EBUSY;
- else {
- s->running = 1;
- err = snd_m3_pcm_start(chip, s, subs);
- }
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- if (! s->running)
- err = 0; /* should return error? */
- else {
- s->running = 0;
- err = snd_m3_pcm_stop(chip, s, subs);
- }
- break;
- }
- spin_unlock(&chip->reg_lock);
- return err;
-}
-
-/*
- * setup
- */
-static void
-snd_m3_pcm_setup1(struct snd_m3 *chip, struct m3_dma *s, struct snd_pcm_substream *subs)
-{
- int dsp_in_size, dsp_out_size, dsp_in_buffer, dsp_out_buffer;
- struct snd_pcm_runtime *runtime = subs->runtime;
-
- if (subs->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- dsp_in_size = MINISRC_IN_BUFFER_SIZE - (0x20 * 2);
- dsp_out_size = MINISRC_OUT_BUFFER_SIZE - (0x20 * 2);
- } else {
- dsp_in_size = MINISRC_IN_BUFFER_SIZE - (0x10 * 2);
- dsp_out_size = MINISRC_OUT_BUFFER_SIZE - (0x10 * 2);
- }
- dsp_in_buffer = s->inst.data + (MINISRC_TMP_BUFFER_SIZE / 2);
- dsp_out_buffer = dsp_in_buffer + (dsp_in_size / 2) + 1;
-
- s->dma_size = frames_to_bytes(runtime, runtime->buffer_size);
- s->period_size = frames_to_bytes(runtime, runtime->period_size);
- s->hwptr = 0;
- s->count = 0;
-
-#define LO(x) ((x) & 0xffff)
-#define HI(x) LO((x) >> 16)
-
- /* host dma buffer pointers */
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_HOST_SRC_ADDRL,
- LO(s->buffer_addr));
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_HOST_SRC_ADDRH,
- HI(s->buffer_addr));
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_HOST_SRC_END_PLUS_1L,
- LO(s->buffer_addr + s->dma_size));
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_HOST_SRC_END_PLUS_1H,
- HI(s->buffer_addr + s->dma_size));
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_HOST_SRC_CURRENTL,
- LO(s->buffer_addr));
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_HOST_SRC_CURRENTH,
- HI(s->buffer_addr));
-#undef LO
-#undef HI
-
- /* dsp buffers */
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_IN_BUF_BEGIN,
- dsp_in_buffer);
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_IN_BUF_END_PLUS_1,
- dsp_in_buffer + (dsp_in_size / 2));
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_IN_BUF_HEAD,
- dsp_in_buffer);
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_IN_BUF_TAIL,
- dsp_in_buffer);
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_OUT_BUF_BEGIN,
- dsp_out_buffer);
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_OUT_BUF_END_PLUS_1,
- dsp_out_buffer + (dsp_out_size / 2));
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_OUT_BUF_HEAD,
- dsp_out_buffer);
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_OUT_BUF_TAIL,
- dsp_out_buffer);
-}
-
-static void snd_m3_pcm_setup2(struct snd_m3 *chip, struct m3_dma *s,
- struct snd_pcm_runtime *runtime)
-{
- u32 freq;
-
- /*
- * put us in the lists if we're not already there
- */
- if (! s->in_lists) {
- s->index[0] = snd_m3_add_list(chip, s->index_list[0],
- s->inst.data >> DP_SHIFT_COUNT);
- s->index[1] = snd_m3_add_list(chip, s->index_list[1],
- s->inst.data >> DP_SHIFT_COUNT);
- s->index[2] = snd_m3_add_list(chip, s->index_list[2],
- s->inst.data >> DP_SHIFT_COUNT);
- s->in_lists = 1;
- }
-
- /* write to 'mono' word */
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + SRC3_DIRECTION_OFFSET + 1,
- runtime->channels == 2 ? 0 : 1);
- /* write to '8bit' word */
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + SRC3_DIRECTION_OFFSET + 2,
- snd_pcm_format_width(runtime->format) == 16 ? 0 : 1);
-
- /* set up dac/adc rate */
- freq = ((runtime->rate << 15) + 24000 ) / 48000;
- if (freq)
- freq--;
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_FREQUENCY,
- freq);
-}
-
-
-static const struct play_vals {
- u16 addr, val;
-} pv[] = {
- {CDATA_LEFT_VOLUME, ARB_VOLUME},
- {CDATA_RIGHT_VOLUME, ARB_VOLUME},
- {SRC3_DIRECTION_OFFSET, 0} ,
- /* +1, +2 are stereo/16 bit */
- {SRC3_DIRECTION_OFFSET + 3, 0x0000}, /* fraction? */
- {SRC3_DIRECTION_OFFSET + 4, 0}, /* first l */
- {SRC3_DIRECTION_OFFSET + 5, 0}, /* first r */
- {SRC3_DIRECTION_OFFSET + 6, 0}, /* second l */
- {SRC3_DIRECTION_OFFSET + 7, 0}, /* second r */
- {SRC3_DIRECTION_OFFSET + 8, 0}, /* delta l */
- {SRC3_DIRECTION_OFFSET + 9, 0}, /* delta r */
- {SRC3_DIRECTION_OFFSET + 10, 0x8000}, /* round */
- {SRC3_DIRECTION_OFFSET + 11, 0xFF00}, /* higher bute mark */
- {SRC3_DIRECTION_OFFSET + 13, 0}, /* temp0 */
- {SRC3_DIRECTION_OFFSET + 14, 0}, /* c fraction */
- {SRC3_DIRECTION_OFFSET + 15, 0}, /* counter */
- {SRC3_DIRECTION_OFFSET + 16, 8}, /* numin */
- {SRC3_DIRECTION_OFFSET + 17, 50*2}, /* numout */
- {SRC3_DIRECTION_OFFSET + 18, MINISRC_BIQUAD_STAGE - 1}, /* numstage */
- {SRC3_DIRECTION_OFFSET + 20, 0}, /* filtertap */
- {SRC3_DIRECTION_OFFSET + 21, 0} /* booster */
-};
-
-
-/* the mode passed should be already shifted and masked */
-static void
-snd_m3_playback_setup(struct snd_m3 *chip, struct m3_dma *s,
- struct snd_pcm_substream *subs)
-{
- unsigned int i;
-
- /*
- * some per client initializers
- */
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + SRC3_DIRECTION_OFFSET + 12,
- s->inst.data + 40 + 8);
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + SRC3_DIRECTION_OFFSET + 19,
- s->inst.code + MINISRC_COEF_LOC);
-
- /* enable or disable low pass filter? */
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + SRC3_DIRECTION_OFFSET + 22,
- subs->runtime->rate > 45000 ? 0xff : 0);
-
- /* tell it which way dma is going? */
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_DMA_CONTROL,
- DMACONTROL_AUTOREPEAT + DMAC_PAGE3_SELECTOR + DMAC_BLOCKF_SELECTOR);
-
- /*
- * set an armload of static initializers
- */
- for (i = 0; i < ARRAY_SIZE(pv); i++)
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + pv[i].addr, pv[i].val);
-}
-
-/*
- * Native record driver
- */
-static const struct rec_vals {
- u16 addr, val;
-} rv[] = {
- {CDATA_LEFT_VOLUME, ARB_VOLUME},
- {CDATA_RIGHT_VOLUME, ARB_VOLUME},
- {SRC3_DIRECTION_OFFSET, 1} ,
- /* +1, +2 are stereo/16 bit */
- {SRC3_DIRECTION_OFFSET + 3, 0x0000}, /* fraction? */
- {SRC3_DIRECTION_OFFSET + 4, 0}, /* first l */
- {SRC3_DIRECTION_OFFSET + 5, 0}, /* first r */
- {SRC3_DIRECTION_OFFSET + 6, 0}, /* second l */
- {SRC3_DIRECTION_OFFSET + 7, 0}, /* second r */
- {SRC3_DIRECTION_OFFSET + 8, 0}, /* delta l */
- {SRC3_DIRECTION_OFFSET + 9, 0}, /* delta r */
- {SRC3_DIRECTION_OFFSET + 10, 0x8000}, /* round */
- {SRC3_DIRECTION_OFFSET + 11, 0xFF00}, /* higher bute mark */
- {SRC3_DIRECTION_OFFSET + 13, 0}, /* temp0 */
- {SRC3_DIRECTION_OFFSET + 14, 0}, /* c fraction */
- {SRC3_DIRECTION_OFFSET + 15, 0}, /* counter */
- {SRC3_DIRECTION_OFFSET + 16, 50},/* numin */
- {SRC3_DIRECTION_OFFSET + 17, 8}, /* numout */
- {SRC3_DIRECTION_OFFSET + 18, 0}, /* numstage */
- {SRC3_DIRECTION_OFFSET + 19, 0}, /* coef */
- {SRC3_DIRECTION_OFFSET + 20, 0}, /* filtertap */
- {SRC3_DIRECTION_OFFSET + 21, 0}, /* booster */
- {SRC3_DIRECTION_OFFSET + 22, 0xff} /* skip lpf */
-};
-
-static void
-snd_m3_capture_setup(struct snd_m3 *chip, struct m3_dma *s, struct snd_pcm_substream *subs)
-{
- unsigned int i;
-
- /*
- * some per client initializers
- */
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + SRC3_DIRECTION_OFFSET + 12,
- s->inst.data + 40 + 8);
-
- /* tell it which way dma is going? */
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_DMA_CONTROL,
- DMACONTROL_DIRECTION + DMACONTROL_AUTOREPEAT +
- DMAC_PAGE3_SELECTOR + DMAC_BLOCKF_SELECTOR);
-
- /*
- * set an armload of static initializers
- */
- for (i = 0; i < ARRAY_SIZE(rv); i++)
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + rv[i].addr, rv[i].val);
-}
-
-static int snd_m3_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct m3_dma *s = substream->runtime->private_data;
- int err;
-
- if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
- return err;
- /* set buffer address */
- s->buffer_addr = substream->runtime->dma_addr;
- if (s->buffer_addr & 0x3) {
- snd_printk(KERN_ERR "oh my, not aligned\n");
- s->buffer_addr = s->buffer_addr & ~0x3;
- }
- return 0;
-}
-
-static int snd_m3_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct m3_dma *s;
-
- if (substream->runtime->private_data == NULL)
- return 0;
- s = substream->runtime->private_data;
- snd_pcm_lib_free_pages(substream);
- s->buffer_addr = 0;
- return 0;
-}
-
-static int
-snd_m3_pcm_prepare(struct snd_pcm_substream *subs)
-{
- struct snd_m3 *chip = snd_pcm_substream_chip(subs);
- struct snd_pcm_runtime *runtime = subs->runtime;
- struct m3_dma *s = runtime->private_data;
-
- if (snd_BUG_ON(!s))
- return -ENXIO;
-
- if (runtime->format != SNDRV_PCM_FORMAT_U8 &&
- runtime->format != SNDRV_PCM_FORMAT_S16_LE)
- return -EINVAL;
- if (runtime->rate > 48000 ||
- runtime->rate < 8000)
- return -EINVAL;
-
- spin_lock_irq(&chip->reg_lock);
-
- snd_m3_pcm_setup1(chip, s, subs);
-
- if (subs->stream == SNDRV_PCM_STREAM_PLAYBACK)
- snd_m3_playback_setup(chip, s, subs);
- else
- snd_m3_capture_setup(chip, s, subs);
-
- snd_m3_pcm_setup2(chip, s, runtime);
-
- spin_unlock_irq(&chip->reg_lock);
-
- return 0;
-}
-
-/*
- * get current pointer
- */
-static unsigned int
-snd_m3_get_pointer(struct snd_m3 *chip, struct m3_dma *s, struct snd_pcm_substream *subs)
-{
- u16 hi = 0, lo = 0;
- int retry = 10;
- u32 addr;
-
- /*
- * try and get a valid answer
- */
- while (retry--) {
- hi = snd_m3_assp_read(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_HOST_SRC_CURRENTH);
-
- lo = snd_m3_assp_read(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_HOST_SRC_CURRENTL);
-
- if (hi == snd_m3_assp_read(chip, MEMTYPE_INTERNAL_DATA,
- s->inst.data + CDATA_HOST_SRC_CURRENTH))
- break;
- }
- addr = lo | ((u32)hi<<16);
- return (unsigned int)(addr - s->buffer_addr);
-}
-
-static snd_pcm_uframes_t
-snd_m3_pcm_pointer(struct snd_pcm_substream *subs)
-{
- struct snd_m3 *chip = snd_pcm_substream_chip(subs);
- unsigned int ptr;
- struct m3_dma *s = subs->runtime->private_data;
-
- if (snd_BUG_ON(!s))
- return 0;
-
- spin_lock(&chip->reg_lock);
- ptr = snd_m3_get_pointer(chip, s, subs);
- spin_unlock(&chip->reg_lock);
- return bytes_to_frames(subs->runtime, ptr);
-}
-
-
-/* update pointer */
-/* spinlock held! */
-static void snd_m3_update_ptr(struct snd_m3 *chip, struct m3_dma *s)
-{
- struct snd_pcm_substream *subs = s->substream;
- unsigned int hwptr;
- int diff;
-
- if (! s->running)
- return;
-
- hwptr = snd_m3_get_pointer(chip, s, subs);
-
- /* try to avoid expensive modulo divisions */
- if (hwptr >= s->dma_size)
- hwptr %= s->dma_size;
-
- diff = s->dma_size + hwptr - s->hwptr;
- if (diff >= s->dma_size)
- diff %= s->dma_size;
-
- s->hwptr = hwptr;
- s->count += diff;
-
- if (s->count >= (signed)s->period_size) {
-
- if (s->count < 2 * (signed)s->period_size)
- s->count -= (signed)s->period_size;
- else
- s->count %= s->period_size;
-
- spin_unlock(&chip->reg_lock);
- snd_pcm_period_elapsed(subs);
- spin_lock(&chip->reg_lock);
- }
-}
-
-/* The m3's hardware volume works by incrementing / decrementing 2 counters
- (without wrap around) in response to volume button presses and then
- generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7
- of a byte wide register. The meaning of bits 0 and 4 is unknown. */
-static void snd_m3_update_hw_volume(struct work_struct *work)
-{
- struct snd_m3 *chip = container_of(work, struct snd_m3, hwvol_work);
- int x, val;
-
- /* Figure out which volume control button was pushed,
- based on differences from the default register
- values. */
- x = inb(chip->iobase + SHADOW_MIX_REG_VOICE) & 0xee;
-
- /* Reset the volume counters to 4. Tests on the allegro integrated
- into a Compaq N600C laptop, have revealed that:
- 1) Writing any value will result in the 2 counters being reset to
- 4 so writing 0x88 is not strictly necessary
- 2) Writing to any of the 4 involved registers will reset all 4
- of them (and reading them always returns the same value for all
- of them)
- It could be that a maestro deviates from this, so leave the code
- as is. */
- outb(0x88, chip->iobase + SHADOW_MIX_REG_VOICE);
- outb(0x88, chip->iobase + HW_VOL_COUNTER_VOICE);
- outb(0x88, chip->iobase + SHADOW_MIX_REG_MASTER);
- outb(0x88, chip->iobase + HW_VOL_COUNTER_MASTER);
-
- /* Ignore spurious HV interrupts during suspend / resume, this avoids
- mistaking them for a mute button press. */
- if (chip->in_suspend)
- return;
-
-#ifndef CONFIG_SND_MAESTRO3_INPUT
- if (!chip->master_switch || !chip->master_volume)
- return;
-
- val = snd_ac97_read(chip->ac97, AC97_MASTER);
- switch (x) {
- case 0x88:
- /* The counters have not changed, yet we've received a HV
- interrupt. According to tests run by various people this
- happens when pressing the mute button. */
- val ^= 0x8000;
- break;
- case 0xaa:
- /* counters increased by 1 -> volume up */
- if ((val & 0x7f) > 0)
- val--;
- if ((val & 0x7f00) > 0)
- val -= 0x0100;
- break;
- case 0x66:
- /* counters decreased by 1 -> volume down */
- if ((val & 0x7f) < 0x1f)
- val++;
- if ((val & 0x7f00) < 0x1f00)
- val += 0x0100;
- break;
- }
- if (snd_ac97_update(chip->ac97, AC97_MASTER, val))
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->master_switch->id);
-#else
- if (!chip->input_dev)
- return;
-
- val = 0;
- switch (x) {
- case 0x88:
- /* The counters have not changed, yet we've received a HV
- interrupt. According to tests run by various people this
- happens when pressing the mute button. */
- val = KEY_MUTE;
- break;
- case 0xaa:
- /* counters increased by 1 -> volume up */
- val = KEY_VOLUMEUP;
- break;
- case 0x66:
- /* counters decreased by 1 -> volume down */
- val = KEY_VOLUMEDOWN;
- break;
- }
-
- if (val) {
- input_report_key(chip->input_dev, val, 1);
- input_sync(chip->input_dev);
- input_report_key(chip->input_dev, val, 0);
- input_sync(chip->input_dev);
- }
-#endif
-}
-
-static irqreturn_t snd_m3_interrupt(int irq, void *dev_id)
-{
- struct snd_m3 *chip = dev_id;
- u8 status;
- int i;
-
- status = inb(chip->iobase + HOST_INT_STATUS);
-
- if (status == 0xff)
- return IRQ_NONE;
-
- if (status & HV_INT_PENDING)
- schedule_work(&chip->hwvol_work);
-
- /*
- * ack an assp int if its running
- * and has an int pending
- */
- if (status & ASSP_INT_PENDING) {
- u8 ctl = inb(chip->iobase + ASSP_CONTROL_B);
- if (!(ctl & STOP_ASSP_CLOCK)) {
- ctl = inb(chip->iobase + ASSP_HOST_INT_STATUS);
- if (ctl & DSP2HOST_REQ_TIMER) {
- outb(DSP2HOST_REQ_TIMER, chip->iobase + ASSP_HOST_INT_STATUS);
- /* update adc/dac info if it was a timer int */
- spin_lock(&chip->reg_lock);
- for (i = 0; i < chip->num_substreams; i++) {
- struct m3_dma *s = &chip->substreams[i];
- if (s->running)
- snd_m3_update_ptr(chip, s);
- }
- spin_unlock(&chip->reg_lock);
- }
- }
- }
-
-#if 0 /* TODO: not supported yet */
- if ((status & MPU401_INT_PENDING) && chip->rmidi)
- snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
-#endif
-
- /* ack ints */
- outb(status, chip->iobase + HOST_INT_STATUS);
-
- return IRQ_HANDLED;
-}
-
-
-/*
- */
-
-static struct snd_pcm_hardware snd_m3_playback =
-{
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- /*SNDRV_PCM_INFO_PAUSE |*/
- SNDRV_PCM_INFO_RESUME),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (512*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (512*1024),
- .periods_min = 1,
- .periods_max = 1024,
-};
-
-static struct snd_pcm_hardware snd_m3_capture =
-{
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- /*SNDRV_PCM_INFO_PAUSE |*/
- SNDRV_PCM_INFO_RESUME),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (512*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (512*1024),
- .periods_min = 1,
- .periods_max = 1024,
-};
-
-
-/*
- */
-
-static int
-snd_m3_substream_open(struct snd_m3 *chip, struct snd_pcm_substream *subs)
-{
- int i;
- struct m3_dma *s;
-
- spin_lock_irq(&chip->reg_lock);
- for (i = 0; i < chip->num_substreams; i++) {
- s = &chip->substreams[i];
- if (! s->opened)
- goto __found;
- }
- spin_unlock_irq(&chip->reg_lock);
- return -ENOMEM;
-__found:
- s->opened = 1;
- s->running = 0;
- spin_unlock_irq(&chip->reg_lock);
-
- subs->runtime->private_data = s;
- s->substream = subs;
-
- /* set list owners */
- if (subs->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- s->index_list[0] = &chip->mixer_list;
- } else
- s->index_list[0] = &chip->adc1_list;
- s->index_list[1] = &chip->msrc_list;
- s->index_list[2] = &chip->dma_list;
-
- return 0;
-}
-
-static void
-snd_m3_substream_close(struct snd_m3 *chip, struct snd_pcm_substream *subs)
-{
- struct m3_dma *s = subs->runtime->private_data;
-
- if (s == NULL)
- return; /* not opened properly */
-
- spin_lock_irq(&chip->reg_lock);
- if (s->substream && s->running)
- snd_m3_pcm_stop(chip, s, s->substream); /* does this happen? */
- if (s->in_lists) {
- snd_m3_remove_list(chip, s->index_list[0], s->index[0]);
- snd_m3_remove_list(chip, s->index_list[1], s->index[1]);
- snd_m3_remove_list(chip, s->index_list[2], s->index[2]);
- s->in_lists = 0;
- }
- s->running = 0;
- s->opened = 0;
- spin_unlock_irq(&chip->reg_lock);
-}
-
-static int
-snd_m3_playback_open(struct snd_pcm_substream *subs)
-{
- struct snd_m3 *chip = snd_pcm_substream_chip(subs);
- struct snd_pcm_runtime *runtime = subs->runtime;
- int err;
-
- if ((err = snd_m3_substream_open(chip, subs)) < 0)
- return err;
-
- runtime->hw = snd_m3_playback;
-
- return 0;
-}
-
-static int
-snd_m3_playback_close(struct snd_pcm_substream *subs)
-{
- struct snd_m3 *chip = snd_pcm_substream_chip(subs);
-
- snd_m3_substream_close(chip, subs);
- return 0;
-}
-
-static int
-snd_m3_capture_open(struct snd_pcm_substream *subs)
-{
- struct snd_m3 *chip = snd_pcm_substream_chip(subs);
- struct snd_pcm_runtime *runtime = subs->runtime;
- int err;
-
- if ((err = snd_m3_substream_open(chip, subs)) < 0)
- return err;
-
- runtime->hw = snd_m3_capture;
-
- return 0;
-}
-
-static int
-snd_m3_capture_close(struct snd_pcm_substream *subs)
-{
- struct snd_m3 *chip = snd_pcm_substream_chip(subs);
-
- snd_m3_substream_close(chip, subs);
- return 0;
-}
-
-/*
- * create pcm instance
- */
-
-static struct snd_pcm_ops snd_m3_playback_ops = {
- .open = snd_m3_playback_open,
- .close = snd_m3_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_m3_pcm_hw_params,
- .hw_free = snd_m3_pcm_hw_free,
- .prepare = snd_m3_pcm_prepare,
- .trigger = snd_m3_pcm_trigger,
- .pointer = snd_m3_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_m3_capture_ops = {
- .open = snd_m3_capture_open,
- .close = snd_m3_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_m3_pcm_hw_params,
- .hw_free = snd_m3_pcm_hw_free,
- .prepare = snd_m3_pcm_prepare,
- .trigger = snd_m3_pcm_trigger,
- .pointer = snd_m3_pcm_pointer,
-};
-
-static int __devinit
-snd_m3_pcm(struct snd_m3 * chip, int device)
-{
- struct snd_pcm *pcm;
- int err;
-
- err = snd_pcm_new(chip->card, chip->card->driver, device,
- MAX_PLAYBACKS, MAX_CAPTURES, &pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_m3_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_m3_capture_ops);
-
- pcm->private_data = chip;
- pcm->info_flags = 0;
- strcpy(pcm->name, chip->card->driver);
- chip->pcm = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci), 64*1024, 64*1024);
-
- return 0;
-}
-
-
-/*
- * ac97 interface
- */
-
-/*
- * Wait for the ac97 serial bus to be free.
- * return nonzero if the bus is still busy.
- */
-static int snd_m3_ac97_wait(struct snd_m3 *chip)
-{
- int i = 10000;
-
- do {
- if (! (snd_m3_inb(chip, 0x30) & 1))
- return 0;
- cpu_relax();
- } while (i-- > 0);
-
- snd_printk(KERN_ERR "ac97 serial bus busy\n");
- return 1;
-}
-
-static unsigned short
-snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
-{
- struct snd_m3 *chip = ac97->private_data;
- unsigned short data = 0xffff;
-
- if (snd_m3_ac97_wait(chip))
- goto fail;
- snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND);
- if (snd_m3_ac97_wait(chip))
- goto fail;
- data = snd_m3_inw(chip, CODEC_DATA);
-fail:
- return data;
-}
-
-static void
-snd_m3_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
-{
- struct snd_m3 *chip = ac97->private_data;
-
- if (snd_m3_ac97_wait(chip))
- return;
- snd_m3_outw(chip, val, CODEC_DATA);
- snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND);
-}
-
-
-static void snd_m3_remote_codec_config(int io, int isremote)
-{
- isremote = isremote ? 1 : 0;
-
- outw((inw(io + RING_BUS_CTRL_B) & ~SECOND_CODEC_ID_MASK) | isremote,
- io + RING_BUS_CTRL_B);
- outw((inw(io + SDO_OUT_DEST_CTRL) & ~COMMAND_ADDR_OUT) | isremote,
- io + SDO_OUT_DEST_CTRL);
- outw((inw(io + SDO_IN_DEST_CTRL) & ~STATUS_ADDR_IN) | isremote,
- io + SDO_IN_DEST_CTRL);
-}
-
-/*
- * hack, returns non zero on err
- */
-static int snd_m3_try_read_vendor(struct snd_m3 *chip)
-{
- u16 ret;
-
- if (snd_m3_ac97_wait(chip))
- return 1;
-
- snd_m3_outb(chip, 0x80 | (AC97_VENDOR_ID1 & 0x7f), 0x30);
-
- if (snd_m3_ac97_wait(chip))
- return 1;
-
- ret = snd_m3_inw(chip, 0x32);
-
- return (ret == 0) || (ret == 0xffff);
-}
-
-static void snd_m3_ac97_reset(struct snd_m3 *chip)
-{
- u16 dir;
- int delay1 = 0, delay2 = 0, i;
- int io = chip->iobase;
-
- if (chip->allegro_flag) {
- /*
- * the onboard codec on the allegro seems
- * to want to wait a very long time before
- * coming back to life
- */
- delay1 = 50;
- delay2 = 800;
- } else {
- /* maestro3 */
- delay1 = 20;
- delay2 = 500;
- }
-
- for (i = 0; i < 5; i++) {
- dir = inw(io + GPIO_DIRECTION);
- if (!chip->irda_workaround)
- dir |= 0x10; /* assuming pci bus master? */
-
- snd_m3_remote_codec_config(io, 0);
-
- outw(IO_SRAM_ENABLE, io + RING_BUS_CTRL_A);
- udelay(20);
-
- outw(dir & ~GPO_PRIMARY_AC97 , io + GPIO_DIRECTION);
- outw(~GPO_PRIMARY_AC97 , io + GPIO_MASK);
- outw(0, io + GPIO_DATA);
- outw(dir | GPO_PRIMARY_AC97, io + GPIO_DIRECTION);
-
- schedule_timeout_uninterruptible(msecs_to_jiffies(delay1));
-
- outw(GPO_PRIMARY_AC97, io + GPIO_DATA);
- udelay(5);
- /* ok, bring back the ac-link */
- outw(IO_SRAM_ENABLE | SERIAL_AC_LINK_ENABLE, io + RING_BUS_CTRL_A);
- outw(~0, io + GPIO_MASK);
-
- schedule_timeout_uninterruptible(msecs_to_jiffies(delay2));
-
- if (! snd_m3_try_read_vendor(chip))
- break;
-
- delay1 += 10;
- delay2 += 100;
-
- snd_printd("maestro3: retrying codec reset with delays of %d and %d ms\n",
- delay1, delay2);
- }
-
-#if 0
- /* more gung-ho reset that doesn't
- * seem to work anywhere :)
- */
- tmp = inw(io + RING_BUS_CTRL_A);
- outw(RAC_SDFS_ENABLE|LAC_SDFS_ENABLE, io + RING_BUS_CTRL_A);
- msleep(20);
- outw(tmp, io + RING_BUS_CTRL_A);
- msleep(50);
-#endif
-}
-
-static int __devinit snd_m3_mixer(struct snd_m3 *chip)
-{
- struct snd_ac97_bus *pbus;
- struct snd_ac97_template ac97;
-#ifndef CONFIG_SND_MAESTRO3_INPUT
- struct snd_ctl_elem_id elem_id;
-#endif
- int err;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_m3_ac97_write,
- .read = snd_m3_ac97_read,
- };
-
- if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
- return err;
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = chip;
- if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0)
- return err;
-
- /* seems ac97 PCM needs initialization.. hack hack.. */
- snd_ac97_write(chip->ac97, AC97_PCM, 0x8000 | (15 << 8) | 15);
- schedule_timeout_uninterruptible(msecs_to_jiffies(100));
- snd_ac97_write(chip->ac97, AC97_PCM, 0);
-
-#ifndef CONFIG_SND_MAESTRO3_INPUT
- memset(&elem_id, 0, sizeof(elem_id));
- elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(elem_id.name, "Master Playback Switch");
- chip->master_switch = snd_ctl_find_id(chip->card, &elem_id);
- memset(&elem_id, 0, sizeof(elem_id));
- elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(elem_id.name, "Master Playback Volume");
- chip->master_volume = snd_ctl_find_id(chip->card, &elem_id);
-#endif
-
- return 0;
-}
-
-
-/*
- * initialize ASSP
- */
-
-#define MINISRC_LPF_LEN 10
-static const u16 minisrc_lpf[MINISRC_LPF_LEN] = {
- 0X0743, 0X1104, 0X0A4C, 0XF88D, 0X242C,
- 0X1023, 0X1AA9, 0X0B60, 0XEFDD, 0X186F
-};
-
-static void snd_m3_assp_init(struct snd_m3 *chip)
-{
- unsigned int i;
- const u16 *data;
-
- /* zero kernel data */
- for (i = 0; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++)
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- KDATA_BASE_ADDR + i, 0);
-
- /* zero mixer data? */
- for (i = 0; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++)
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- KDATA_BASE_ADDR2 + i, 0);
-
- /* init dma pointer */
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- KDATA_CURRENT_DMA,
- KDATA_DMA_XFER0);
-
- /* write kernel into code memory.. */
- data = (const u16 *)chip->assp_kernel_image->data;
- for (i = 0 ; i * 2 < chip->assp_kernel_image->size; i++) {
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE,
- REV_B_CODE_MEMORY_BEGIN + i,
- le16_to_cpu(data[i]));
- }
-
- /*
- * We only have this one client and we know that 0x400
- * is free in our kernel's mem map, so lets just
- * drop it there. It seems that the minisrc doesn't
- * need vectors, so we won't bother with them..
- */
- data = (const u16 *)chip->assp_minisrc_image->data;
- for (i = 0; i * 2 < chip->assp_minisrc_image->size; i++) {
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE,
- 0x400 + i, le16_to_cpu(data[i]));
- }
-
- /*
- * write the coefficients for the low pass filter?
- */
- for (i = 0; i < MINISRC_LPF_LEN ; i++) {
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE,
- 0x400 + MINISRC_COEF_LOC + i,
- minisrc_lpf[i]);
- }
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE,
- 0x400 + MINISRC_COEF_LOC + MINISRC_LPF_LEN,
- 0x8000);
-
- /*
- * the minisrc is the only thing on
- * our task list..
- */
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- KDATA_TASK0,
- 0x400);
-
- /*
- * init the mixer number..
- */
-
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- KDATA_MIXER_TASK_NUMBER,0);
-
- /*
- * EXTREME KERNEL MASTER VOLUME
- */
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- KDATA_DAC_LEFT_VOLUME, ARB_VOLUME);
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- KDATA_DAC_RIGHT_VOLUME, ARB_VOLUME);
-
- chip->mixer_list.curlen = 0;
- chip->mixer_list.mem_addr = KDATA_MIXER_XFER0;
- chip->mixer_list.max = MAX_VIRTUAL_MIXER_CHANNELS;
- chip->adc1_list.curlen = 0;
- chip->adc1_list.mem_addr = KDATA_ADC1_XFER0;
- chip->adc1_list.max = MAX_VIRTUAL_ADC1_CHANNELS;
- chip->dma_list.curlen = 0;
- chip->dma_list.mem_addr = KDATA_DMA_XFER0;
- chip->dma_list.max = MAX_VIRTUAL_DMA_CHANNELS;
- chip->msrc_list.curlen = 0;
- chip->msrc_list.mem_addr = KDATA_INSTANCE0_MINISRC;
- chip->msrc_list.max = MAX_INSTANCE_MINISRC;
-}
-
-
-static int __devinit snd_m3_assp_client_init(struct snd_m3 *chip, struct m3_dma *s, int index)
-{
- int data_bytes = 2 * ( MINISRC_TMP_BUFFER_SIZE / 2 +
- MINISRC_IN_BUFFER_SIZE / 2 +
- 1 + MINISRC_OUT_BUFFER_SIZE / 2 + 1 );
- int address, i;
-
- /*
- * the revb memory map has 0x1100 through 0x1c00
- * free.
- */
-
- /*
- * align instance address to 256 bytes so that its
- * shifted list address is aligned.
- * list address = (mem address >> 1) >> 7;
- */
- data_bytes = ALIGN(data_bytes, 256);
- address = 0x1100 + ((data_bytes/2) * index);
-
- if ((address + (data_bytes/2)) >= 0x1c00) {
- snd_printk(KERN_ERR "no memory for %d bytes at ind %d (addr 0x%x)\n",
- data_bytes, index, address);
- return -ENOMEM;
- }
-
- s->number = index;
- s->inst.code = 0x400;
- s->inst.data = address;
-
- for (i = data_bytes / 2; i > 0; address++, i--) {
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- address, 0);
- }
-
- return 0;
-}
-
-
-/*
- * this works for the reference board, have to find
- * out about others
- *
- * this needs more magic for 4 speaker, but..
- */
-static void
-snd_m3_amp_enable(struct snd_m3 *chip, int enable)
-{
- int io = chip->iobase;
- u16 gpo, polarity;
-
- if (! chip->external_amp)
- return;
-
- polarity = enable ? 0 : 1;
- polarity = polarity << chip->amp_gpio;
- gpo = 1 << chip->amp_gpio;
-
- outw(~gpo, io + GPIO_MASK);
-
- outw(inw(io + GPIO_DIRECTION) | gpo,
- io + GPIO_DIRECTION);
-
- outw((GPO_SECONDARY_AC97 | GPO_PRIMARY_AC97 | polarity),
- io + GPIO_DATA);
-
- outw(0xffff, io + GPIO_MASK);
-}
-
-static void
-snd_m3_hv_init(struct snd_m3 *chip)
-{
- unsigned long io = chip->iobase;
- u16 val = GPI_VOL_DOWN | GPI_VOL_UP;
-
- if (!chip->is_omnibook)
- return;
-
- /*
- * Volume buttons on some HP OmniBook laptops
- * require some GPIO magic to work correctly.
- */
- outw(0xffff, io + GPIO_MASK);
- outw(0x0000, io + GPIO_DATA);
-
- outw(~val, io + GPIO_MASK);
- outw(inw(io + GPIO_DIRECTION) & ~val, io + GPIO_DIRECTION);
- outw(val, io + GPIO_MASK);
-
- outw(0xffff, io + GPIO_MASK);
-}
-
-static int
-snd_m3_chip_init(struct snd_m3 *chip)
-{
- struct pci_dev *pcidev = chip->pci;
- unsigned long io = chip->iobase;
- u32 n;
- u16 w;
- u8 t; /* makes as much sense as 'n', no? */
-
- pci_read_config_word(pcidev, PCI_LEGACY_AUDIO_CTRL, &w);
- w &= ~(SOUND_BLASTER_ENABLE|FM_SYNTHESIS_ENABLE|
- MPU401_IO_ENABLE|MPU401_IRQ_ENABLE|ALIAS_10BIT_IO|
- DISABLE_LEGACY);
- pci_write_config_word(pcidev, PCI_LEGACY_AUDIO_CTRL, w);
-
- pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n);
- n &= ~(HV_CTRL_ENABLE | REDUCED_DEBOUNCE | HV_BUTTON_FROM_GD);
- n |= chip->hv_config;
- /* For some reason we must always use reduced debounce. */
- n |= REDUCED_DEBOUNCE;
- n |= PM_CTRL_ENABLE | CLK_DIV_BY_49 | USE_PCI_TIMING;
- pci_write_config_dword(pcidev, PCI_ALLEGRO_CONFIG, n);
-
- outb(RESET_ASSP, chip->iobase + ASSP_CONTROL_B);
- pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n);
- n &= ~INT_CLK_SELECT;
- if (!chip->allegro_flag) {
- n &= ~INT_CLK_MULT_ENABLE;
- n |= INT_CLK_SRC_NOT_PCI;
- }
- n &= ~( CLK_MULT_MODE_SELECT | CLK_MULT_MODE_SELECT_2 );
- pci_write_config_dword(pcidev, PCI_ALLEGRO_CONFIG, n);
-
- if (chip->allegro_flag) {
- pci_read_config_dword(pcidev, PCI_USER_CONFIG, &n);
- n |= IN_CLK_12MHZ_SELECT;
- pci_write_config_dword(pcidev, PCI_USER_CONFIG, n);
- }
-
- t = inb(chip->iobase + ASSP_CONTROL_A);
- t &= ~( DSP_CLK_36MHZ_SELECT | ASSP_CLK_49MHZ_SELECT);
- t |= ASSP_CLK_49MHZ_SELECT;
- t |= ASSP_0_WS_ENABLE;
- outb(t, chip->iobase + ASSP_CONTROL_A);
-
- snd_m3_assp_init(chip); /* download DSP code before starting ASSP below */
- outb(RUN_ASSP, chip->iobase + ASSP_CONTROL_B);
-
- outb(0x00, io + HARDWARE_VOL_CTRL);
- outb(0x88, io + SHADOW_MIX_REG_VOICE);
- outb(0x88, io + HW_VOL_COUNTER_VOICE);
- outb(0x88, io + SHADOW_MIX_REG_MASTER);
- outb(0x88, io + HW_VOL_COUNTER_MASTER);
-
- return 0;
-}
-
-static void
-snd_m3_enable_ints(struct snd_m3 *chip)
-{
- unsigned long io = chip->iobase;
- unsigned short val;
-
- /* TODO: MPU401 not supported yet */
- val = ASSP_INT_ENABLE /*| MPU401_INT_ENABLE*/;
- if (chip->hv_config & HV_CTRL_ENABLE)
- val |= HV_INT_ENABLE;
- outb(val, chip->iobase + HOST_INT_STATUS);
- outw(val, io + HOST_INT_CTRL);
- outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE,
- io + ASSP_CONTROL_C);
-}
-
-
-/*
- */
-
-static int snd_m3_free(struct snd_m3 *chip)
-{
- struct m3_dma *s;
- int i;
-
- cancel_work_sync(&chip->hwvol_work);
-#ifdef CONFIG_SND_MAESTRO3_INPUT
- if (chip->input_dev)
- input_unregister_device(chip->input_dev);
-#endif
-
- if (chip->substreams) {
- spin_lock_irq(&chip->reg_lock);
- for (i = 0; i < chip->num_substreams; i++) {
- s = &chip->substreams[i];
- /* check surviving pcms; this should not happen though.. */
- if (s->substream && s->running)
- snd_m3_pcm_stop(chip, s, s->substream);
- }
- spin_unlock_irq(&chip->reg_lock);
- kfree(chip->substreams);
- }
- if (chip->iobase) {
- outw(0, chip->iobase + HOST_INT_CTRL); /* disable ints */
- }
-
-#ifdef CONFIG_PM
- vfree(chip->suspend_mem);
-#endif
-
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
-
- if (chip->iobase)
- pci_release_regions(chip->pci);
-
- release_firmware(chip->assp_kernel_image);
- release_firmware(chip->assp_minisrc_image);
-
- pci_disable_device(chip->pci);
- kfree(chip);
- return 0;
-}
-
-
-/*
- * APM support
- */
-#ifdef CONFIG_PM
-static int m3_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_m3 *chip = card->private_data;
- int i, dsp_index;
-
- if (chip->suspend_mem == NULL)
- return 0;
-
- chip->in_suspend = 1;
- cancel_work_sync(&chip->hwvol_work);
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(chip->pcm);
- snd_ac97_suspend(chip->ac97);
-
- msleep(10); /* give the assp a chance to idle.. */
-
- snd_m3_assp_halt(chip);
-
- /* save dsp image */
- dsp_index = 0;
- for (i = REV_B_CODE_MEMORY_BEGIN; i <= REV_B_CODE_MEMORY_END; i++)
- chip->suspend_mem[dsp_index++] =
- snd_m3_assp_read(chip, MEMTYPE_INTERNAL_CODE, i);
- for (i = REV_B_DATA_MEMORY_BEGIN ; i <= REV_B_DATA_MEMORY_END; i++)
- chip->suspend_mem[dsp_index++] =
- snd_m3_assp_read(chip, MEMTYPE_INTERNAL_DATA, i);
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int m3_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_m3 *chip = card->private_data;
- int i, dsp_index;
-
- if (chip->suspend_mem == NULL)
- return 0;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "maestor3: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
-
- /* first lets just bring everything back. .*/
- snd_m3_outw(chip, 0, 0x54);
- snd_m3_outw(chip, 0, 0x56);
-
- snd_m3_chip_init(chip);
- snd_m3_assp_halt(chip);
- snd_m3_ac97_reset(chip);
-
- /* restore dsp image */
- dsp_index = 0;
- for (i = REV_B_CODE_MEMORY_BEGIN; i <= REV_B_CODE_MEMORY_END; i++)
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE, i,
- chip->suspend_mem[dsp_index++]);
- for (i = REV_B_DATA_MEMORY_BEGIN ; i <= REV_B_DATA_MEMORY_END; i++)
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA, i,
- chip->suspend_mem[dsp_index++]);
-
- /* tell the dma engine to restart itself */
- snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
- KDATA_DMA_ACTIVE, 0);
-
- /* restore ac97 registers */
- snd_ac97_resume(chip->ac97);
-
- snd_m3_assp_continue(chip);
- snd_m3_enable_ints(chip);
- snd_m3_amp_enable(chip, 1);
-
- snd_m3_hv_init(chip);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- chip->in_suspend = 0;
- return 0;
-}
-#endif /* CONFIG_PM */
-
-#ifdef CONFIG_SND_MAESTRO3_INPUT
-static int __devinit snd_m3_input_register(struct snd_m3 *chip)
-{
- struct input_dev *input_dev;
- int err;
-
- input_dev = input_allocate_device();
- if (!input_dev)
- return -ENOMEM;
-
- snprintf(chip->phys, sizeof(chip->phys), "pci-%s/input0",
- pci_name(chip->pci));
-
- input_dev->name = chip->card->driver;
- input_dev->phys = chip->phys;
- input_dev->id.bustype = BUS_PCI;
- input_dev->id.vendor = chip->pci->vendor;
- input_dev->id.product = chip->pci->device;
- input_dev->dev.parent = &chip->pci->dev;
-
- __set_bit(EV_KEY, input_dev->evbit);
- __set_bit(KEY_MUTE, input_dev->keybit);
- __set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
- __set_bit(KEY_VOLUMEUP, input_dev->keybit);
-
- err = input_register_device(input_dev);
- if (err) {
- input_free_device(input_dev);
- return err;
- }
-
- chip->input_dev = input_dev;
- return 0;
-}
-#endif /* CONFIG_INPUT */
-
-/*
- */
-
-static int snd_m3_dev_free(struct snd_device *device)
-{
- struct snd_m3 *chip = device->device_data;
- return snd_m3_free(chip);
-}
-
-static int __devinit
-snd_m3_create(struct snd_card *card, struct pci_dev *pci,
- int enable_amp,
- int amp_gpio,
- struct snd_m3 **chip_ret)
-{
- struct snd_m3 *chip;
- int i, err;
- const struct snd_pci_quirk *quirk;
- static struct snd_device_ops ops = {
- .dev_free = snd_m3_dev_free,
- };
-
- *chip_ret = NULL;
-
- if (pci_enable_device(pci))
- return -EIO;
-
- /* check, if we can restrict PCI DMA transfers to 28 bits */
- if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) {
- snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n");
- pci_disable_device(pci);
- return -ENXIO;
- }
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- spin_lock_init(&chip->reg_lock);
-
- switch (pci->device) {
- case PCI_DEVICE_ID_ESS_ALLEGRO:
- case PCI_DEVICE_ID_ESS_ALLEGRO_1:
- case PCI_DEVICE_ID_ESS_CANYON3D_2LE:
- case PCI_DEVICE_ID_ESS_CANYON3D_2:
- chip->allegro_flag = 1;
- break;
- }
-
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
- INIT_WORK(&chip->hwvol_work, snd_m3_update_hw_volume);
-
- chip->external_amp = enable_amp;
- if (amp_gpio >= 0 && amp_gpio <= 0x0f)
- chip->amp_gpio = amp_gpio;
- else {
- quirk = snd_pci_quirk_lookup(pci, m3_amp_quirk_list);
- if (quirk) {
- snd_printdd(KERN_INFO "maestro3: set amp-gpio "
- "for '%s'\n", quirk->name);
- chip->amp_gpio = quirk->value;
- } else if (chip->allegro_flag)
- chip->amp_gpio = GPO_EXT_AMP_ALLEGRO;
- else /* presumably this is for all 'maestro3's.. */
- chip->amp_gpio = GPO_EXT_AMP_M3;
- }
-
- quirk = snd_pci_quirk_lookup(pci, m3_irda_quirk_list);
- if (quirk) {
- snd_printdd(KERN_INFO "maestro3: enabled irda workaround "
- "for '%s'\n", quirk->name);
- chip->irda_workaround = 1;
- }
- quirk = snd_pci_quirk_lookup(pci, m3_hv_quirk_list);
- if (quirk)
- chip->hv_config = quirk->value;
- if (snd_pci_quirk_lookup(pci, m3_omnibook_quirk_list))
- chip->is_omnibook = 1;
-
- chip->num_substreams = NR_DSPS;
- chip->substreams = kcalloc(chip->num_substreams, sizeof(struct m3_dma),
- GFP_KERNEL);
- if (chip->substreams == NULL) {
- kfree(chip);
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- err = request_firmware(&chip->assp_kernel_image,
- "ess/maestro3_assp_kernel.fw", &pci->dev);
- if (err < 0) {
- snd_m3_free(chip);
- return err;
- }
-
- err = request_firmware(&chip->assp_minisrc_image,
- "ess/maestro3_assp_minisrc.fw", &pci->dev);
- if (err < 0) {
- snd_m3_free(chip);
- return err;
- }
-
- if ((err = pci_request_regions(pci, card->driver)) < 0) {
- snd_m3_free(chip);
- return err;
- }
- chip->iobase = pci_resource_start(pci, 0);
-
- /* just to be sure */
- pci_set_master(pci);
-
- snd_m3_chip_init(chip);
- snd_m3_assp_halt(chip);
-
- snd_m3_ac97_reset(chip);
-
- snd_m3_amp_enable(chip, 1);
-
- snd_m3_hv_init(chip);
-
- if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_m3_free(chip);
- return -ENOMEM;
- }
- chip->irq = pci->irq;
-
-#ifdef CONFIG_PM
- chip->suspend_mem = vmalloc(sizeof(u16) * (REV_B_CODE_MEMORY_LENGTH + REV_B_DATA_MEMORY_LENGTH));
- if (chip->suspend_mem == NULL)
- snd_printk(KERN_WARNING "can't allocate apm buffer\n");
-#endif
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_m3_free(chip);
- return err;
- }
-
- if ((err = snd_m3_mixer(chip)) < 0)
- return err;
-
- for (i = 0; i < chip->num_substreams; i++) {
- struct m3_dma *s = &chip->substreams[i];
- if ((err = snd_m3_assp_client_init(chip, s, i)) < 0)
- return err;
- }
-
- if ((err = snd_m3_pcm(chip, 0)) < 0)
- return err;
-
-#ifdef CONFIG_SND_MAESTRO3_INPUT
- if (chip->hv_config & HV_CTRL_ENABLE) {
- err = snd_m3_input_register(chip);
- if (err)
- snd_printk(KERN_WARNING "Input device registration "
- "failed with error %i", err);
- }
-#endif
-
- snd_m3_enable_ints(chip);
- snd_m3_assp_continue(chip);
-
- snd_card_set_dev(card, &pci->dev);
-
- *chip_ret = chip;
-
- return 0;
-}
-
-/*
- */
-static int __devinit
-snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct snd_m3 *chip;
- int err;
-
- /* don't pick up modems */
- if (((pci->class >> 8) & 0xffff) != PCI_CLASS_MULTIMEDIA_AUDIO)
- return -ENODEV;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- switch (pci->device) {
- case PCI_DEVICE_ID_ESS_ALLEGRO:
- case PCI_DEVICE_ID_ESS_ALLEGRO_1:
- strcpy(card->driver, "Allegro");
- break;
- case PCI_DEVICE_ID_ESS_CANYON3D_2LE:
- case PCI_DEVICE_ID_ESS_CANYON3D_2:
- strcpy(card->driver, "Canyon3D-2");
- break;
- default:
- strcpy(card->driver, "Maestro3");
- break;
- }
-
- if ((err = snd_m3_create(card, pci,
- external_amp[dev],
- amp_gpio[dev],
- &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
- card->private_data = chip;
-
- sprintf(card->shortname, "ESS %s PCI", card->driver);
- sprintf(card->longname, "%s at 0x%lx, irq %d",
- card->shortname, chip->iobase, chip->irq);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
-
-#if 0 /* TODO: not supported yet */
- /* TODO enable MIDI IRQ and I/O */
- err = snd_mpu401_uart_new(chip->card, 0, MPU401_HW_MPU401,
- chip->iobase + MPU401_DATA_PORT,
- MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK,
- -1, &chip->rmidi);
- if (err < 0)
- printk(KERN_WARNING "maestro3: no MIDI support.\n");
-#endif
-
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_m3_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_m3_ids,
- .probe = snd_m3_probe,
- .remove = __devexit_p(snd_m3_remove),
-#ifdef CONFIG_PM
- .suspend = m3_suspend,
- .resume = m3_resume,
-#endif
-};
-
-static int __init alsa_card_m3_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_m3_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_m3_init)
-module_exit(alsa_card_m3_exit)
diff --git a/ANDROID_3.4.5/sound/pci/mixart/Makefile b/ANDROID_3.4.5/sound/pci/mixart/Makefile
deleted file mode 100644
index cce159ec..00000000
--- a/ANDROID_3.4.5/sound/pci/mixart/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-mixart-objs := mixart.o mixart_core.o mixart_hwdep.o mixart_mixer.o
-
-obj-$(CONFIG_SND_MIXART) += snd-mixart.o
diff --git a/ANDROID_3.4.5/sound/pci/mixart/mixart.c b/ANDROID_3.4.5/sound/pci/mixart/mixart.c
deleted file mode 100644
index 487837c0..00000000
--- a/ANDROID_3.4.5/sound/pci/mixart/mixart.c
+++ /dev/null
@@ -1,1401 +0,0 @@
-/*
- * Driver for Digigram miXart soundcards
- *
- * main file with alsa callbacks
- *
- * Copyright (c) 2003 by Digigram <alsa@digigram.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include "mixart.h"
-#include "mixart_hwdep.h"
-#include "mixart_core.h"
-#include "mixart_mixer.h"
-
-#define CARD_NAME "miXart"
-
-MODULE_AUTHOR("Digigram <alsa@digigram.com>");
-MODULE_DESCRIPTION("Digigram " CARD_NAME);
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Digigram," CARD_NAME "}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Digigram " CARD_NAME " soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Digigram " CARD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Digigram " CARD_NAME " soundcard.");
-
-/*
- */
-
-static DEFINE_PCI_DEVICE_TABLE(snd_mixart_ids) = {
- { PCI_VDEVICE(MOTOROLA, 0x0003), 0, }, /* MC8240 */
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_mixart_ids);
-
-
-static int mixart_set_pipe_state(struct mixart_mgr *mgr,
- struct mixart_pipe *pipe, int start)
-{
- struct mixart_group_state_req group_state;
- struct mixart_group_state_resp group_state_resp;
- struct mixart_msg request;
- int err;
- u32 system_msg_uid;
-
- switch(pipe->status) {
- case PIPE_RUNNING:
- case PIPE_CLOCK_SET:
- if(start) return 0; /* already started */
- break;
- case PIPE_STOPPED:
- if(!start) return 0; /* already stopped */
- break;
- default:
- snd_printk(KERN_ERR "error mixart_set_pipe_state called with wrong pipe->status!\n");
- return -EINVAL; /* function called with wrong pipe status */
- }
-
- system_msg_uid = 0x12345678; /* the event ! (take care: the MSB and two LSB's have to be 0) */
-
- /* wait on the last MSG_SYSTEM_SEND_SYNCHRO_CMD command to be really finished */
-
- request.message_id = MSG_SYSTEM_WAIT_SYNCHRO_CMD;
- request.uid = (struct mixart_uid){0,0};
- request.data = &system_msg_uid;
- request.size = sizeof(system_msg_uid);
-
- err = snd_mixart_send_msg_wait_notif(mgr, &request, system_msg_uid);
- if(err) {
- snd_printk(KERN_ERR "error : MSG_SYSTEM_WAIT_SYNCHRO_CMD was not notified !\n");
- return err;
- }
-
- /* start or stop the pipe (1 pipe) */
-
- memset(&group_state, 0, sizeof(group_state));
- group_state.pipe_count = 1;
- group_state.pipe_uid[0] = pipe->group_uid;
-
- if(start)
- request.message_id = MSG_STREAM_START_STREAM_GRP_PACKET;
- else
- request.message_id = MSG_STREAM_STOP_STREAM_GRP_PACKET;
-
- request.uid = pipe->group_uid; /*(struct mixart_uid){0,0};*/
- request.data = &group_state;
- request.size = sizeof(group_state);
-
- err = snd_mixart_send_msg(mgr, &request, sizeof(group_state_resp), &group_state_resp);
- if (err < 0 || group_state_resp.txx_status != 0) {
- snd_printk(KERN_ERR "error MSG_STREAM_ST***_STREAM_GRP_PACKET err=%x stat=%x !\n", err, group_state_resp.txx_status);
- return -EINVAL;
- }
-
- if(start) {
- u32 stat;
-
- group_state.pipe_count = 0; /* in case of start same command once again with pipe_count=0 */
-
- err = snd_mixart_send_msg(mgr, &request, sizeof(group_state_resp), &group_state_resp);
- if (err < 0 || group_state_resp.txx_status != 0) {
- snd_printk(KERN_ERR "error MSG_STREAM_START_STREAM_GRP_PACKET err=%x stat=%x !\n", err, group_state_resp.txx_status);
- return -EINVAL;
- }
-
- /* in case of start send a synchro top */
-
- request.message_id = MSG_SYSTEM_SEND_SYNCHRO_CMD;
- request.uid = (struct mixart_uid){0,0};
- request.data = NULL;
- request.size = 0;
-
- err = snd_mixart_send_msg(mgr, &request, sizeof(stat), &stat);
- if (err < 0 || stat != 0) {
- snd_printk(KERN_ERR "error MSG_SYSTEM_SEND_SYNCHRO_CMD err=%x stat=%x !\n", err, stat);
- return -EINVAL;
- }
-
- pipe->status = PIPE_RUNNING;
- }
- else /* !start */
- pipe->status = PIPE_STOPPED;
-
- return 0;
-}
-
-
-static int mixart_set_clock(struct mixart_mgr *mgr,
- struct mixart_pipe *pipe, unsigned int rate)
-{
- struct mixart_msg request;
- struct mixart_clock_properties clock_properties;
- struct mixart_clock_properties_resp clock_prop_resp;
- int err;
-
- switch(pipe->status) {
- case PIPE_CLOCK_SET:
- break;
- case PIPE_RUNNING:
- if(rate != 0)
- break;
- default:
- if(rate == 0)
- return 0; /* nothing to do */
- else {
- snd_printk(KERN_ERR "error mixart_set_clock(%d) called with wrong pipe->status !\n", rate);
- return -EINVAL;
- }
- }
-
- memset(&clock_properties, 0, sizeof(clock_properties));
- clock_properties.clock_generic_type = (rate != 0) ? CGT_INTERNAL_CLOCK : CGT_NO_CLOCK;
- clock_properties.clock_mode = CM_STANDALONE;
- clock_properties.frequency = rate;
- clock_properties.nb_callers = 1; /* only one entry in uid_caller ! */
- clock_properties.uid_caller[0] = pipe->group_uid;
-
- snd_printdd("mixart_set_clock to %d kHz\n", rate);
-
- request.message_id = MSG_CLOCK_SET_PROPERTIES;
- request.uid = mgr->uid_console_manager;
- request.data = &clock_properties;
- request.size = sizeof(clock_properties);
-
- err = snd_mixart_send_msg(mgr, &request, sizeof(clock_prop_resp), &clock_prop_resp);
- if (err < 0 || clock_prop_resp.status != 0 || clock_prop_resp.clock_mode != CM_STANDALONE) {
- snd_printk(KERN_ERR "error MSG_CLOCK_SET_PROPERTIES err=%x stat=%x mod=%x !\n", err, clock_prop_resp.status, clock_prop_resp.clock_mode);
- return -EINVAL;
- }
-
- if(rate) pipe->status = PIPE_CLOCK_SET;
- else pipe->status = PIPE_RUNNING;
-
- return 0;
-}
-
-
-/*
- * Allocate or reference output pipe for analog IOs (pcmp0/1)
- */
-struct mixart_pipe *
-snd_mixart_add_ref_pipe(struct snd_mixart *chip, int pcm_number, int capture,
- int monitoring)
-{
- int stream_count;
- struct mixart_pipe *pipe;
- struct mixart_msg request;
-
- if(capture) {
- if (pcm_number == MIXART_PCM_ANALOG) {
- pipe = &(chip->pipe_in_ana); /* analog inputs */
- } else {
- pipe = &(chip->pipe_in_dig); /* digital inputs */
- }
- request.message_id = MSG_STREAM_ADD_OUTPUT_GROUP;
- stream_count = MIXART_CAPTURE_STREAMS;
- } else {
- if (pcm_number == MIXART_PCM_ANALOG) {
- pipe = &(chip->pipe_out_ana); /* analog outputs */
- } else {
- pipe = &(chip->pipe_out_dig); /* digital outputs */
- }
- request.message_id = MSG_STREAM_ADD_INPUT_GROUP;
- stream_count = MIXART_PLAYBACK_STREAMS;
- }
-
- /* a new stream is opened and there are already all streams in use */
- if( (monitoring == 0) && (pipe->references >= stream_count) ) {
- return NULL;
- }
-
- /* pipe is not yet defined */
- if( pipe->status == PIPE_UNDEFINED ) {
- int err, i;
- struct {
- struct mixart_streaming_group_req sgroup_req;
- struct mixart_streaming_group sgroup_resp;
- } *buf;
-
- snd_printdd("add_ref_pipe audio chip(%d) pcm(%d)\n", chip->chip_idx, pcm_number);
-
- buf = kmalloc(sizeof(*buf), GFP_KERNEL);
- if (!buf)
- return NULL;
-
- request.uid = (struct mixart_uid){0,0}; /* should be StreamManagerUID, but zero is OK if there is only one ! */
- request.data = &buf->sgroup_req;
- request.size = sizeof(buf->sgroup_req);
-
- memset(&buf->sgroup_req, 0, sizeof(buf->sgroup_req));
-
- buf->sgroup_req.stream_count = stream_count;
- buf->sgroup_req.channel_count = 2;
- buf->sgroup_req.latency = 256;
- buf->sgroup_req.connector = pipe->uid_left_connector; /* the left connector */
-
- for (i=0; i<stream_count; i++) {
- int j;
- struct mixart_flowinfo *flowinfo;
- struct mixart_bufferinfo *bufferinfo;
-
- /* we don't yet know the format, so config 16 bit pcm audio for instance */
- buf->sgroup_req.stream_info[i].size_max_byte_frame = 1024;
- buf->sgroup_req.stream_info[i].size_max_sample_frame = 256;
- buf->sgroup_req.stream_info[i].nb_bytes_max_per_sample = MIXART_FLOAT_P__4_0_TO_HEX; /* is 4.0f */
-
- /* find the right bufferinfo_array */
- j = (chip->chip_idx * MIXART_MAX_STREAM_PER_CARD) + (pcm_number * (MIXART_PLAYBACK_STREAMS + MIXART_CAPTURE_STREAMS)) + i;
- if(capture) j += MIXART_PLAYBACK_STREAMS; /* in the array capture is behind playback */
-
- buf->sgroup_req.flow_entry[i] = j;
-
- flowinfo = (struct mixart_flowinfo *)chip->mgr->flowinfo.area;
- flowinfo[j].bufferinfo_array_phy_address = (u32)chip->mgr->bufferinfo.addr + (j * sizeof(struct mixart_bufferinfo));
- flowinfo[j].bufferinfo_count = 1; /* 1 will set the miXart to ring-buffer mode ! */
-
- bufferinfo = (struct mixart_bufferinfo *)chip->mgr->bufferinfo.area;
- bufferinfo[j].buffer_address = 0; /* buffer is not yet allocated */
- bufferinfo[j].available_length = 0; /* buffer is not yet allocated */
-
- /* construct the identifier of the stream buffer received in the interrupts ! */
- bufferinfo[j].buffer_id = (chip->chip_idx << MIXART_NOTIFY_CARD_OFFSET) + (pcm_number << MIXART_NOTIFY_PCM_OFFSET ) + i;
- if(capture) {
- bufferinfo[j].buffer_id |= MIXART_NOTIFY_CAPT_MASK;
- }
- }
-
- err = snd_mixart_send_msg(chip->mgr, &request, sizeof(buf->sgroup_resp), &buf->sgroup_resp);
- if((err < 0) || (buf->sgroup_resp.status != 0)) {
- snd_printk(KERN_ERR "error MSG_STREAM_ADD_**PUT_GROUP err=%x stat=%x !\n", err, buf->sgroup_resp.status);
- kfree(buf);
- return NULL;
- }
-
- pipe->group_uid = buf->sgroup_resp.group; /* id of the pipe, as returned by embedded */
- pipe->stream_count = buf->sgroup_resp.stream_count;
- /* pipe->stream_uid[i] = buf->sgroup_resp.stream[i].stream_uid; */
-
- pipe->status = PIPE_STOPPED;
- kfree(buf);
- }
-
- if(monitoring) pipe->monitoring = 1;
- else pipe->references++;
-
- return pipe;
-}
-
-
-int snd_mixart_kill_ref_pipe(struct mixart_mgr *mgr,
- struct mixart_pipe *pipe, int monitoring)
-{
- int err = 0;
-
- if(pipe->status == PIPE_UNDEFINED)
- return 0;
-
- if(monitoring)
- pipe->monitoring = 0;
- else
- pipe->references--;
-
- if((pipe->references <= 0) && (pipe->monitoring == 0)) {
-
- struct mixart_msg request;
- struct mixart_delete_group_resp delete_resp;
-
- /* release the clock */
- err = mixart_set_clock( mgr, pipe, 0);
- if( err < 0 ) {
- snd_printk(KERN_ERR "mixart_set_clock(0) return error!\n");
- }
-
- /* stop the pipe */
- err = mixart_set_pipe_state(mgr, pipe, 0);
- if( err < 0 ) {
- snd_printk(KERN_ERR "error stopping pipe!\n");
- }
-
- request.message_id = MSG_STREAM_DELETE_GROUP;
- request.uid = (struct mixart_uid){0,0};
- request.data = &pipe->group_uid; /* the streaming group ! */
- request.size = sizeof(pipe->group_uid);
-
- /* delete the pipe */
- err = snd_mixart_send_msg(mgr, &request, sizeof(delete_resp), &delete_resp);
- if ((err < 0) || (delete_resp.status != 0)) {
- snd_printk(KERN_ERR "error MSG_STREAM_DELETE_GROUP err(%x), status(%x)\n", err, delete_resp.status);
- }
-
- pipe->group_uid = (struct mixart_uid){0,0};
- pipe->stream_count = 0;
- pipe->status = PIPE_UNDEFINED;
- }
-
- return err;
-}
-
-static int mixart_set_stream_state(struct mixart_stream *stream, int start)
-{
- struct snd_mixart *chip;
- struct mixart_stream_state_req stream_state_req;
- struct mixart_msg request;
-
- if(!stream->substream)
- return -EINVAL;
-
- memset(&stream_state_req, 0, sizeof(stream_state_req));
- stream_state_req.stream_count = 1;
- stream_state_req.stream_info.stream_desc.uid_pipe = stream->pipe->group_uid;
- stream_state_req.stream_info.stream_desc.stream_idx = stream->substream->number;
-
- if (stream->substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- request.message_id = start ? MSG_STREAM_START_INPUT_STAGE_PACKET : MSG_STREAM_STOP_INPUT_STAGE_PACKET;
- else
- request.message_id = start ? MSG_STREAM_START_OUTPUT_STAGE_PACKET : MSG_STREAM_STOP_OUTPUT_STAGE_PACKET;
-
- request.uid = (struct mixart_uid){0,0};
- request.data = &stream_state_req;
- request.size = sizeof(stream_state_req);
-
- stream->abs_period_elapsed = 0; /* reset stream pos */
- stream->buf_periods = 0;
- stream->buf_period_frag = 0;
-
- chip = snd_pcm_substream_chip(stream->substream);
-
- return snd_mixart_send_msg_nonblock(chip->mgr, &request);
-}
-
-/*
- * Trigger callback
- */
-
-static int snd_mixart_trigger(struct snd_pcm_substream *subs, int cmd)
-{
- struct mixart_stream *stream = subs->runtime->private_data;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
-
- snd_printdd("SNDRV_PCM_TRIGGER_START\n");
-
- /* START_STREAM */
- if( mixart_set_stream_state(stream, 1) )
- return -EINVAL;
-
- stream->status = MIXART_STREAM_STATUS_RUNNING;
-
- break;
- case SNDRV_PCM_TRIGGER_STOP:
-
- /* STOP_STREAM */
- if( mixart_set_stream_state(stream, 0) )
- return -EINVAL;
-
- stream->status = MIXART_STREAM_STATUS_OPEN;
-
- snd_printdd("SNDRV_PCM_TRIGGER_STOP\n");
-
- break;
-
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- /* TODO */
- stream->status = MIXART_STREAM_STATUS_PAUSE;
- snd_printdd("SNDRV_PCM_PAUSE_PUSH\n");
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- /* TODO */
- stream->status = MIXART_STREAM_STATUS_RUNNING;
- snd_printdd("SNDRV_PCM_PAUSE_RELEASE\n");
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int mixart_sync_nonblock_events(struct mixart_mgr *mgr)
-{
- unsigned long timeout = jiffies + HZ;
- while (atomic_read(&mgr->msg_processed) > 0) {
- if (time_after(jiffies, timeout)) {
- snd_printk(KERN_ERR "mixart: cannot process nonblock events!\n");
- return -EBUSY;
- }
- schedule_timeout_uninterruptible(1);
- }
- return 0;
-}
-
-/*
- * prepare callback for all pcms
- */
-static int snd_mixart_prepare(struct snd_pcm_substream *subs)
-{
- struct snd_mixart *chip = snd_pcm_substream_chip(subs);
- struct mixart_stream *stream = subs->runtime->private_data;
-
- /* TODO de façon non bloquante, réappliquer les hw_params (rate, bits, codec) */
-
- snd_printdd("snd_mixart_prepare\n");
-
- mixart_sync_nonblock_events(chip->mgr);
-
- /* only the first stream can choose the sample rate */
- /* the further opened streams will be limited to its frequency (see open) */
- if(chip->mgr->ref_count_rate == 1)
- chip->mgr->sample_rate = subs->runtime->rate;
-
- /* set the clock only once (first stream) on the same pipe */
- if(stream->pipe->references == 1) {
- if( mixart_set_clock(chip->mgr, stream->pipe, subs->runtime->rate) )
- return -EINVAL;
- }
-
- return 0;
-}
-
-
-static int mixart_set_format(struct mixart_stream *stream, snd_pcm_format_t format)
-{
- int err;
- struct snd_mixart *chip;
- struct mixart_msg request;
- struct mixart_stream_param_desc stream_param;
- struct mixart_return_uid resp;
-
- chip = snd_pcm_substream_chip(stream->substream);
-
- memset(&stream_param, 0, sizeof(stream_param));
-
- stream_param.coding_type = CT_LINEAR;
- stream_param.number_of_channel = stream->channels;
-
- stream_param.sampling_freq = chip->mgr->sample_rate;
- if(stream_param.sampling_freq == 0)
- stream_param.sampling_freq = 44100; /* if frequency not yet defined, use some default */
-
- switch(format){
- case SNDRV_PCM_FORMAT_U8:
- stream_param.sample_type = ST_INTEGER_8;
- stream_param.sample_size = 8;
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- stream_param.sample_type = ST_INTEGER_16LE;
- stream_param.sample_size = 16;
- break;
- case SNDRV_PCM_FORMAT_S16_BE:
- stream_param.sample_type = ST_INTEGER_16BE;
- stream_param.sample_size = 16;
- break;
- case SNDRV_PCM_FORMAT_S24_3LE:
- stream_param.sample_type = ST_INTEGER_24LE;
- stream_param.sample_size = 24;
- break;
- case SNDRV_PCM_FORMAT_S24_3BE:
- stream_param.sample_type = ST_INTEGER_24BE;
- stream_param.sample_size = 24;
- break;
- case SNDRV_PCM_FORMAT_FLOAT_LE:
- stream_param.sample_type = ST_FLOATING_POINT_32LE;
- stream_param.sample_size = 32;
- break;
- case SNDRV_PCM_FORMAT_FLOAT_BE:
- stream_param.sample_type = ST_FLOATING_POINT_32BE;
- stream_param.sample_size = 32;
- break;
- default:
- snd_printk(KERN_ERR "error mixart_set_format() : unknown format\n");
- return -EINVAL;
- }
-
- snd_printdd("set SNDRV_PCM_FORMAT sample_type(%d) sample_size(%d) freq(%d) channels(%d)\n",
- stream_param.sample_type, stream_param.sample_size, stream_param.sampling_freq, stream->channels);
-
- /* TODO: what else to configure ? */
- /* stream_param.samples_per_frame = 2; */
- /* stream_param.bytes_per_frame = 4; */
- /* stream_param.bytes_per_sample = 2; */
-
- stream_param.pipe_count = 1; /* set to 1 */
- stream_param.stream_count = 1; /* set to 1 */
- stream_param.stream_desc[0].uid_pipe = stream->pipe->group_uid;
- stream_param.stream_desc[0].stream_idx = stream->substream->number;
-
- request.message_id = MSG_STREAM_SET_INPUT_STAGE_PARAM;
- request.uid = (struct mixart_uid){0,0};
- request.data = &stream_param;
- request.size = sizeof(stream_param);
-
- err = snd_mixart_send_msg(chip->mgr, &request, sizeof(resp), &resp);
- if((err < 0) || resp.error_code) {
- snd_printk(KERN_ERR "MSG_STREAM_SET_INPUT_STAGE_PARAM err=%x; resp=%x\n", err, resp.error_code);
- return -EINVAL;
- }
- return 0;
-}
-
-
-/*
- * HW_PARAMS callback for all pcms
- */
-static int snd_mixart_hw_params(struct snd_pcm_substream *subs,
- struct snd_pcm_hw_params *hw)
-{
- struct snd_mixart *chip = snd_pcm_substream_chip(subs);
- struct mixart_mgr *mgr = chip->mgr;
- struct mixart_stream *stream = subs->runtime->private_data;
- snd_pcm_format_t format;
- int err;
- int channels;
-
- /* set up channels */
- channels = params_channels(hw);
-
- /* set up format for the stream */
- format = params_format(hw);
-
- mutex_lock(&mgr->setup_mutex);
-
- /* update the stream levels */
- if( stream->pcm_number <= MIXART_PCM_DIGITAL ) {
- int is_aes = stream->pcm_number > MIXART_PCM_ANALOG;
- if( subs->stream == SNDRV_PCM_STREAM_PLAYBACK )
- mixart_update_playback_stream_level(chip, is_aes, subs->number);
- else
- mixart_update_capture_stream_level( chip, is_aes);
- }
-
- stream->channels = channels;
-
- /* set the format to the board */
- err = mixart_set_format(stream, format);
- if(err < 0) {
- mutex_unlock(&mgr->setup_mutex);
- return err;
- }
-
- /* allocate buffer */
- err = snd_pcm_lib_malloc_pages(subs, params_buffer_bytes(hw));
-
- if (err > 0) {
- struct mixart_bufferinfo *bufferinfo;
- int i = (chip->chip_idx * MIXART_MAX_STREAM_PER_CARD) + (stream->pcm_number * (MIXART_PLAYBACK_STREAMS+MIXART_CAPTURE_STREAMS)) + subs->number;
- if( subs->stream == SNDRV_PCM_STREAM_CAPTURE ) {
- i += MIXART_PLAYBACK_STREAMS; /* in array capture is behind playback */
- }
-
- bufferinfo = (struct mixart_bufferinfo *)chip->mgr->bufferinfo.area;
- bufferinfo[i].buffer_address = subs->runtime->dma_addr;
- bufferinfo[i].available_length = subs->runtime->dma_bytes;
- /* bufferinfo[i].buffer_id is already defined */
-
- snd_printdd("snd_mixart_hw_params(pcm %d) : dma_addr(%x) dma_bytes(%x) subs-number(%d)\n", i,
- bufferinfo[i].buffer_address,
- bufferinfo[i].available_length,
- subs->number);
- }
- mutex_unlock(&mgr->setup_mutex);
-
- return err;
-}
-
-static int snd_mixart_hw_free(struct snd_pcm_substream *subs)
-{
- struct snd_mixart *chip = snd_pcm_substream_chip(subs);
- snd_pcm_lib_free_pages(subs);
- mixart_sync_nonblock_events(chip->mgr);
- return 0;
-}
-
-
-
-/*
- * TODO CONFIGURATION SPACE for all pcms, mono pcm must update channels_max
- */
-static struct snd_pcm_hardware snd_mixart_analog_caps =
-{
- .info = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE),
- .formats = ( SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |
- SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE ),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (32*1024),
- .period_bytes_min = 256, /* 256 frames U8 mono*/
- .period_bytes_max = (16*1024),
- .periods_min = 2,
- .periods_max = (32*1024/256),
-};
-
-static struct snd_pcm_hardware snd_mixart_digital_caps =
-{
- .info = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE),
- .formats = ( SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |
- SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE ),
- .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
- .rate_min = 32000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (32*1024),
- .period_bytes_min = 256, /* 256 frames U8 mono*/
- .period_bytes_max = (16*1024),
- .periods_min = 2,
- .periods_max = (32*1024/256),
-};
-
-
-static int snd_mixart_playback_open(struct snd_pcm_substream *subs)
-{
- struct snd_mixart *chip = snd_pcm_substream_chip(subs);
- struct mixart_mgr *mgr = chip->mgr;
- struct snd_pcm_runtime *runtime = subs->runtime;
- struct snd_pcm *pcm = subs->pcm;
- struct mixart_stream *stream;
- struct mixart_pipe *pipe;
- int err = 0;
- int pcm_number;
-
- mutex_lock(&mgr->setup_mutex);
-
- if ( pcm == chip->pcm ) {
- pcm_number = MIXART_PCM_ANALOG;
- runtime->hw = snd_mixart_analog_caps;
- } else {
- snd_BUG_ON(pcm != chip->pcm_dig);
- pcm_number = MIXART_PCM_DIGITAL;
- runtime->hw = snd_mixart_digital_caps;
- }
- snd_printdd("snd_mixart_playback_open C%d/P%d/Sub%d\n", chip->chip_idx, pcm_number, subs->number);
-
- /* get stream info */
- stream = &(chip->playback_stream[pcm_number][subs->number]);
-
- if (stream->status != MIXART_STREAM_STATUS_FREE){
- /* streams in use */
- snd_printk(KERN_ERR "snd_mixart_playback_open C%d/P%d/Sub%d in use\n", chip->chip_idx, pcm_number, subs->number);
- err = -EBUSY;
- goto _exit_open;
- }
-
- /* get pipe pointer (out pipe) */
- pipe = snd_mixart_add_ref_pipe(chip, pcm_number, 0, 0);
-
- if (pipe == NULL) {
- err = -EINVAL;
- goto _exit_open;
- }
-
- /* start the pipe if necessary */
- err = mixart_set_pipe_state(chip->mgr, pipe, 1);
- if( err < 0 ) {
- snd_printk(KERN_ERR "error starting pipe!\n");
- snd_mixart_kill_ref_pipe(chip->mgr, pipe, 0);
- err = -EINVAL;
- goto _exit_open;
- }
-
- stream->pipe = pipe;
- stream->pcm_number = pcm_number;
- stream->status = MIXART_STREAM_STATUS_OPEN;
- stream->substream = subs;
- stream->channels = 0; /* not configured yet */
-
- runtime->private_data = stream;
-
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 64);
-
- /* if a sample rate is already used, another stream cannot change */
- if(mgr->ref_count_rate++) {
- if(mgr->sample_rate) {
- runtime->hw.rate_min = runtime->hw.rate_max = mgr->sample_rate;
- }
- }
-
- _exit_open:
- mutex_unlock(&mgr->setup_mutex);
-
- return err;
-}
-
-
-static int snd_mixart_capture_open(struct snd_pcm_substream *subs)
-{
- struct snd_mixart *chip = snd_pcm_substream_chip(subs);
- struct mixart_mgr *mgr = chip->mgr;
- struct snd_pcm_runtime *runtime = subs->runtime;
- struct snd_pcm *pcm = subs->pcm;
- struct mixart_stream *stream;
- struct mixart_pipe *pipe;
- int err = 0;
- int pcm_number;
-
- mutex_lock(&mgr->setup_mutex);
-
- if ( pcm == chip->pcm ) {
- pcm_number = MIXART_PCM_ANALOG;
- runtime->hw = snd_mixart_analog_caps;
- } else {
- snd_BUG_ON(pcm != chip->pcm_dig);
- pcm_number = MIXART_PCM_DIGITAL;
- runtime->hw = snd_mixart_digital_caps;
- }
-
- runtime->hw.channels_min = 2; /* for instance, no mono */
-
- snd_printdd("snd_mixart_capture_open C%d/P%d/Sub%d\n", chip->chip_idx, pcm_number, subs->number);
-
- /* get stream info */
- stream = &(chip->capture_stream[pcm_number]);
-
- if (stream->status != MIXART_STREAM_STATUS_FREE){
- /* streams in use */
- snd_printk(KERN_ERR "snd_mixart_capture_open C%d/P%d/Sub%d in use\n", chip->chip_idx, pcm_number, subs->number);
- err = -EBUSY;
- goto _exit_open;
- }
-
- /* get pipe pointer (in pipe) */
- pipe = snd_mixart_add_ref_pipe(chip, pcm_number, 1, 0);
-
- if (pipe == NULL) {
- err = -EINVAL;
- goto _exit_open;
- }
-
- /* start the pipe if necessary */
- err = mixart_set_pipe_state(chip->mgr, pipe, 1);
- if( err < 0 ) {
- snd_printk(KERN_ERR "error starting pipe!\n");
- snd_mixart_kill_ref_pipe(chip->mgr, pipe, 0);
- err = -EINVAL;
- goto _exit_open;
- }
-
- stream->pipe = pipe;
- stream->pcm_number = pcm_number;
- stream->status = MIXART_STREAM_STATUS_OPEN;
- stream->substream = subs;
- stream->channels = 0; /* not configured yet */
-
- runtime->private_data = stream;
-
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 64);
-
- /* if a sample rate is already used, another stream cannot change */
- if(mgr->ref_count_rate++) {
- if(mgr->sample_rate) {
- runtime->hw.rate_min = runtime->hw.rate_max = mgr->sample_rate;
- }
- }
-
- _exit_open:
- mutex_unlock(&mgr->setup_mutex);
-
- return err;
-}
-
-
-
-static int snd_mixart_close(struct snd_pcm_substream *subs)
-{
- struct snd_mixart *chip = snd_pcm_substream_chip(subs);
- struct mixart_mgr *mgr = chip->mgr;
- struct mixart_stream *stream = subs->runtime->private_data;
-
- mutex_lock(&mgr->setup_mutex);
-
- snd_printdd("snd_mixart_close C%d/P%d/Sub%d\n", chip->chip_idx, stream->pcm_number, subs->number);
-
- /* sample rate released */
- if(--mgr->ref_count_rate == 0) {
- mgr->sample_rate = 0;
- }
-
- /* delete pipe */
- if (snd_mixart_kill_ref_pipe(mgr, stream->pipe, 0 ) < 0) {
-
- snd_printk(KERN_ERR "error snd_mixart_kill_ref_pipe C%dP%d\n", chip->chip_idx, stream->pcm_number);
- }
-
- stream->pipe = NULL;
- stream->status = MIXART_STREAM_STATUS_FREE;
- stream->substream = NULL;
-
- mutex_unlock(&mgr->setup_mutex);
- return 0;
-}
-
-
-static snd_pcm_uframes_t snd_mixart_stream_pointer(struct snd_pcm_substream *subs)
-{
- struct snd_pcm_runtime *runtime = subs->runtime;
- struct mixart_stream *stream = runtime->private_data;
-
- return (snd_pcm_uframes_t)((stream->buf_periods * runtime->period_size) + stream->buf_period_frag);
-}
-
-
-
-static struct snd_pcm_ops snd_mixart_playback_ops = {
- .open = snd_mixart_playback_open,
- .close = snd_mixart_close,
- .ioctl = snd_pcm_lib_ioctl,
- .prepare = snd_mixart_prepare,
- .hw_params = snd_mixart_hw_params,
- .hw_free = snd_mixart_hw_free,
- .trigger = snd_mixart_trigger,
- .pointer = snd_mixart_stream_pointer,
-};
-
-static struct snd_pcm_ops snd_mixart_capture_ops = {
- .open = snd_mixart_capture_open,
- .close = snd_mixart_close,
- .ioctl = snd_pcm_lib_ioctl,
- .prepare = snd_mixart_prepare,
- .hw_params = snd_mixart_hw_params,
- .hw_free = snd_mixart_hw_free,
- .trigger = snd_mixart_trigger,
- .pointer = snd_mixart_stream_pointer,
-};
-
-static void preallocate_buffers(struct snd_mixart *chip, struct snd_pcm *pcm)
-{
-#if 0
- struct snd_pcm_substream *subs;
- int stream;
-
- for (stream = 0; stream < 2; stream++) {
- int idx = 0;
- for (subs = pcm->streams[stream].substream; subs; subs = subs->next, idx++)
- /* set up the unique device id with the chip index */
- subs->dma_device.id = subs->pcm->device << 16 |
- subs->stream << 8 | (subs->number + 1) |
- (chip->chip_idx + 1) << 24;
- }
-#endif
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->mgr->pci), 32*1024, 32*1024);
-}
-
-/*
- */
-static int snd_mixart_pcm_analog(struct snd_mixart *chip)
-{
- int err;
- struct snd_pcm *pcm;
- char name[32];
-
- sprintf(name, "miXart analog %d", chip->chip_idx);
- if ((err = snd_pcm_new(chip->card, name, MIXART_PCM_ANALOG,
- MIXART_PLAYBACK_STREAMS,
- MIXART_CAPTURE_STREAMS, &pcm)) < 0) {
- snd_printk(KERN_ERR "cannot create the analog pcm %d\n", chip->chip_idx);
- return err;
- }
-
- pcm->private_data = chip;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_mixart_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_mixart_capture_ops);
-
- pcm->info_flags = 0;
- strcpy(pcm->name, name);
-
- preallocate_buffers(chip, pcm);
-
- chip->pcm = pcm;
- return 0;
-}
-
-
-/*
- */
-static int snd_mixart_pcm_digital(struct snd_mixart *chip)
-{
- int err;
- struct snd_pcm *pcm;
- char name[32];
-
- sprintf(name, "miXart AES/EBU %d", chip->chip_idx);
- if ((err = snd_pcm_new(chip->card, name, MIXART_PCM_DIGITAL,
- MIXART_PLAYBACK_STREAMS,
- MIXART_CAPTURE_STREAMS, &pcm)) < 0) {
- snd_printk(KERN_ERR "cannot create the digital pcm %d\n", chip->chip_idx);
- return err;
- }
-
- pcm->private_data = chip;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_mixart_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_mixart_capture_ops);
-
- pcm->info_flags = 0;
- strcpy(pcm->name, name);
-
- preallocate_buffers(chip, pcm);
-
- chip->pcm_dig = pcm;
- return 0;
-}
-
-static int snd_mixart_chip_free(struct snd_mixart *chip)
-{
- kfree(chip);
- return 0;
-}
-
-static int snd_mixart_chip_dev_free(struct snd_device *device)
-{
- struct snd_mixart *chip = device->device_data;
- return snd_mixart_chip_free(chip);
-}
-
-
-/*
- */
-static int __devinit snd_mixart_create(struct mixart_mgr *mgr, struct snd_card *card, int idx)
-{
- int err;
- struct snd_mixart *chip;
- static struct snd_device_ops ops = {
- .dev_free = snd_mixart_chip_dev_free,
- };
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (! chip) {
- snd_printk(KERN_ERR "cannot allocate chip\n");
- return -ENOMEM;
- }
-
- chip->card = card;
- chip->chip_idx = idx;
- chip->mgr = mgr;
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_mixart_chip_free(chip);
- return err;
- }
-
- mgr->chip[idx] = chip;
- snd_card_set_dev(card, &mgr->pci->dev);
-
- return 0;
-}
-
-int snd_mixart_create_pcm(struct snd_mixart* chip)
-{
- int err;
-
- err = snd_mixart_pcm_analog(chip);
- if (err < 0)
- return err;
-
- if(chip->mgr->board_type == MIXART_DAUGHTER_TYPE_AES) {
-
- err = snd_mixart_pcm_digital(chip);
- if (err < 0)
- return err;
- }
- return err;
-}
-
-
-/*
- * release all the cards assigned to a manager instance
- */
-static int snd_mixart_free(struct mixart_mgr *mgr)
-{
- unsigned int i;
-
- for (i = 0; i < mgr->num_cards; i++) {
- if (mgr->chip[i])
- snd_card_free(mgr->chip[i]->card);
- }
-
- /* stop mailbox */
- snd_mixart_exit_mailbox(mgr);
-
- /* release irq */
- if (mgr->irq >= 0)
- free_irq(mgr->irq, mgr);
-
- /* reset board if some firmware was loaded */
- if(mgr->dsp_loaded) {
- snd_mixart_reset_board(mgr);
- snd_printdd("reset miXart !\n");
- }
-
- /* release the i/o ports */
- for (i = 0; i < 2; i++) {
- if (mgr->mem[i].virt)
- iounmap(mgr->mem[i].virt);
- }
- pci_release_regions(mgr->pci);
-
- /* free flowarray */
- if(mgr->flowinfo.area) {
- snd_dma_free_pages(&mgr->flowinfo);
- mgr->flowinfo.area = NULL;
- }
- /* free bufferarray */
- if(mgr->bufferinfo.area) {
- snd_dma_free_pages(&mgr->bufferinfo);
- mgr->bufferinfo.area = NULL;
- }
-
- pci_disable_device(mgr->pci);
- kfree(mgr);
- return 0;
-}
-
-/*
- * proc interface
- */
-
-/*
- mixart_BA0 proc interface for BAR 0 - read callback
- */
-static ssize_t snd_mixart_BA0_read(struct snd_info_entry *entry,
- void *file_private_data,
- struct file *file, char __user *buf,
- size_t count, loff_t pos)
-{
- struct mixart_mgr *mgr = entry->private_data;
-
- count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
- if (copy_to_user_fromio(buf, MIXART_MEM(mgr, pos), count))
- return -EFAULT;
- return count;
-}
-
-/*
- mixart_BA1 proc interface for BAR 1 - read callback
- */
-static ssize_t snd_mixart_BA1_read(struct snd_info_entry *entry,
- void *file_private_data,
- struct file *file, char __user *buf,
- size_t count, loff_t pos)
-{
- struct mixart_mgr *mgr = entry->private_data;
-
- count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
- if (copy_to_user_fromio(buf, MIXART_REG(mgr, pos), count))
- return -EFAULT;
- return count;
-}
-
-static struct snd_info_entry_ops snd_mixart_proc_ops_BA0 = {
- .read = snd_mixart_BA0_read,
-};
-
-static struct snd_info_entry_ops snd_mixart_proc_ops_BA1 = {
- .read = snd_mixart_BA1_read,
-};
-
-
-static void snd_mixart_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_mixart *chip = entry->private_data;
- u32 ref;
-
- snd_iprintf(buffer, "Digigram miXart (alsa card %d)\n\n", chip->chip_idx);
-
- /* stats available when embedded OS is running */
- if (chip->mgr->dsp_loaded & ( 1 << MIXART_MOTHERBOARD_ELF_INDEX)) {
- snd_iprintf(buffer, "- hardware -\n");
- switch (chip->mgr->board_type ) {
- case MIXART_DAUGHTER_TYPE_NONE : snd_iprintf(buffer, "\tmiXart8 (no daughter board)\n\n"); break;
- case MIXART_DAUGHTER_TYPE_AES : snd_iprintf(buffer, "\tmiXart8 AES/EBU\n\n"); break;
- case MIXART_DAUGHTER_TYPE_COBRANET : snd_iprintf(buffer, "\tmiXart8 Cobranet\n\n"); break;
- default: snd_iprintf(buffer, "\tUNKNOWN!\n\n"); break;
- }
-
- snd_iprintf(buffer, "- system load -\n");
-
- /* get perf reference */
-
- ref = readl_be( MIXART_MEM( chip->mgr, MIXART_PSEUDOREG_PERF_SYSTEM_LOAD_OFFSET));
-
- if (ref) {
- u32 mailbox = 100 * readl_be( MIXART_MEM( chip->mgr, MIXART_PSEUDOREG_PERF_MAILBX_LOAD_OFFSET)) / ref;
- u32 streaming = 100 * readl_be( MIXART_MEM( chip->mgr, MIXART_PSEUDOREG_PERF_STREAM_LOAD_OFFSET)) / ref;
- u32 interr = 100 * readl_be( MIXART_MEM( chip->mgr, MIXART_PSEUDOREG_PERF_INTERR_LOAD_OFFSET)) / ref;
-
- snd_iprintf(buffer, "\tstreaming : %d\n", streaming);
- snd_iprintf(buffer, "\tmailbox : %d\n", mailbox);
- snd_iprintf(buffer, "\tinterrups handling : %d\n\n", interr);
- }
- } /* endif elf loaded */
-}
-
-static void __devinit snd_mixart_proc_init(struct snd_mixart *chip)
-{
- struct snd_info_entry *entry;
-
- /* text interface to read perf and temp meters */
- if (! snd_card_proc_new(chip->card, "board_info", &entry)) {
- entry->private_data = chip;
- entry->c.text.read = snd_mixart_proc_read;
- }
-
- if (! snd_card_proc_new(chip->card, "mixart_BA0", &entry)) {
- entry->content = SNDRV_INFO_CONTENT_DATA;
- entry->private_data = chip->mgr;
- entry->c.ops = &snd_mixart_proc_ops_BA0;
- entry->size = MIXART_BA0_SIZE;
- }
- if (! snd_card_proc_new(chip->card, "mixart_BA1", &entry)) {
- entry->content = SNDRV_INFO_CONTENT_DATA;
- entry->private_data = chip->mgr;
- entry->c.ops = &snd_mixart_proc_ops_BA1;
- entry->size = MIXART_BA1_SIZE;
- }
-}
-/* end of proc interface */
-
-
-/*
- * probe function - creates the card manager
- */
-static int __devinit snd_mixart_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct mixart_mgr *mgr;
- unsigned int i;
- int err;
- size_t size;
-
- /*
- */
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (! enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- /* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
- return err;
- pci_set_master(pci);
-
- /* check if we can restrict PCI DMA transfers to 32 bits */
- if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0) {
- snd_printk(KERN_ERR "architecture does not support 32bit PCI busmaster DMA\n");
- pci_disable_device(pci);
- return -ENXIO;
- }
-
- /*
- */
- mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
- if (! mgr) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- mgr->pci = pci;
- mgr->irq = -1;
-
- /* resource assignment */
- if ((err = pci_request_regions(pci, CARD_NAME)) < 0) {
- kfree(mgr);
- pci_disable_device(pci);
- return err;
- }
- for (i = 0; i < 2; i++) {
- mgr->mem[i].phys = pci_resource_start(pci, i);
- mgr->mem[i].virt = pci_ioremap_bar(pci, i);
- if (!mgr->mem[i].virt) {
- printk(KERN_ERR "unable to remap resource 0x%lx\n",
- mgr->mem[i].phys);
- snd_mixart_free(mgr);
- return -EBUSY;
- }
- }
-
- if (request_irq(pci->irq, snd_mixart_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, mgr)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_mixart_free(mgr);
- return -EBUSY;
- }
- mgr->irq = pci->irq;
-
- sprintf(mgr->shortname, "Digigram miXart");
- sprintf(mgr->longname, "%s at 0x%lx & 0x%lx, irq %i", mgr->shortname, mgr->mem[0].phys, mgr->mem[1].phys, mgr->irq);
-
- /* ISR spinlock */
- spin_lock_init(&mgr->lock);
-
- /* init mailbox */
- mgr->msg_fifo_readptr = 0;
- mgr->msg_fifo_writeptr = 0;
-
- spin_lock_init(&mgr->msg_lock);
- mutex_init(&mgr->msg_mutex);
- init_waitqueue_head(&mgr->msg_sleep);
- atomic_set(&mgr->msg_processed, 0);
-
- /* init setup mutex*/
- mutex_init(&mgr->setup_mutex);
-
- /* init message taslket */
- tasklet_init(&mgr->msg_taskq, snd_mixart_msg_tasklet, (unsigned long) mgr);
-
- /* card assignment */
- mgr->num_cards = MIXART_MAX_CARDS; /* 4 FIXME: configurable? */
- for (i = 0; i < mgr->num_cards; i++) {
- struct snd_card *card;
- char tmpid[16];
- int idx;
-
- if (index[dev] < 0)
- idx = index[dev];
- else
- idx = index[dev] + i;
- snprintf(tmpid, sizeof(tmpid), "%s-%d", id[dev] ? id[dev] : "MIXART", i);
- err = snd_card_create(idx, tmpid, THIS_MODULE, 0, &card);
-
- if (err < 0) {
- snd_printk(KERN_ERR "cannot allocate the card %d\n", i);
- snd_mixart_free(mgr);
- return err;
- }
-
- strcpy(card->driver, CARD_NAME);
- sprintf(card->shortname, "%s [PCM #%d]", mgr->shortname, i);
- sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i);
-
- if ((err = snd_mixart_create(mgr, card, i)) < 0) {
- snd_card_free(card);
- snd_mixart_free(mgr);
- return err;
- }
-
- if(i==0) {
- /* init proc interface only for chip0 */
- snd_mixart_proc_init(mgr->chip[i]);
- }
-
- if ((err = snd_card_register(card)) < 0) {
- snd_mixart_free(mgr);
- return err;
- }
- }
-
- /* init firmware status (mgr->dsp_loaded reset in hwdep_new) */
- mgr->board_type = MIXART_DAUGHTER_TYPE_NONE;
-
- /* create array of streaminfo */
- size = PAGE_ALIGN( (MIXART_MAX_STREAM_PER_CARD * MIXART_MAX_CARDS *
- sizeof(struct mixart_flowinfo)) );
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
- size, &mgr->flowinfo) < 0) {
- snd_mixart_free(mgr);
- return -ENOMEM;
- }
- /* init streaminfo_array */
- memset(mgr->flowinfo.area, 0, size);
-
- /* create array of bufferinfo */
- size = PAGE_ALIGN( (MIXART_MAX_STREAM_PER_CARD * MIXART_MAX_CARDS *
- sizeof(struct mixart_bufferinfo)) );
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
- size, &mgr->bufferinfo) < 0) {
- snd_mixart_free(mgr);
- return -ENOMEM;
- }
- /* init bufferinfo_array */
- memset(mgr->bufferinfo.area, 0, size);
-
- /* set up firmware */
- err = snd_mixart_setup_firmware(mgr);
- if (err < 0) {
- snd_mixart_free(mgr);
- return err;
- }
-
- pci_set_drvdata(pci, mgr);
- dev++;
- return 0;
-}
-
-static void __devexit snd_mixart_remove(struct pci_dev *pci)
-{
- snd_mixart_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_mixart_ids,
- .probe = snd_mixart_probe,
- .remove = __devexit_p(snd_mixart_remove),
-};
-
-static int __init alsa_card_mixart_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_mixart_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_mixart_init)
-module_exit(alsa_card_mixart_exit)
diff --git a/ANDROID_3.4.5/sound/pci/mixart/mixart.h b/ANDROID_3.4.5/sound/pci/mixart/mixart.h
deleted file mode 100644
index 561634d5..00000000
--- a/ANDROID_3.4.5/sound/pci/mixart/mixart.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Driver for Digigram miXart soundcards
- *
- * main header file
- *
- * Copyright (c) 2003 by Digigram <alsa@digigram.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __SOUND_MIXART_H
-#define __SOUND_MIXART_H
-
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <sound/pcm.h>
-
-#define MIXART_DRIVER_VERSION 0x000100 /* 0.1.0 */
-
-
-/*
- */
-
-struct mixart_uid {
- u32 object_id;
- u32 desc;
-};
-
-struct mem_area {
- unsigned long phys;
- void __iomem *virt;
- struct resource *res;
-};
-
-
-struct mixart_route {
- unsigned char connected;
- unsigned char phase_inv;
- int volume;
-};
-
-
-/* firmware status codes */
-#define MIXART_MOTHERBOARD_XLX_INDEX 0
-#define MIXART_MOTHERBOARD_ELF_INDEX 1
-#define MIXART_AESEBUBOARD_XLX_INDEX 2
-#define MIXART_HARDW_FILES_MAX_INDEX 3 /* xilinx, elf, AESEBU xilinx */
-
-#define MIXART_MAX_CARDS 4
-#define MSG_FIFO_SIZE 16
-
-#define MIXART_MAX_PHYS_CONNECTORS (MIXART_MAX_CARDS * 2 * 2) /* 4 * stereo * (analog+digital) */
-
-struct mixart_mgr {
- unsigned int num_cards;
- struct snd_mixart *chip[MIXART_MAX_CARDS];
-
- struct pci_dev *pci;
-
- int irq;
-
- /* memory-maps */
- struct mem_area mem[2];
-
- /* share the name */
- char shortname[32]; /* short name of this soundcard */
- char longname[80]; /* name of this soundcard */
-
- /* message tasklet */
- struct tasklet_struct msg_taskq;
-
- /* one and only blocking message or notification may be pending */
- u32 pending_event;
- wait_queue_head_t msg_sleep;
-
- /* messages stored for tasklet */
- u32 msg_fifo[MSG_FIFO_SIZE];
- int msg_fifo_readptr;
- int msg_fifo_writeptr;
- atomic_t msg_processed; /* number of messages to be processed in takslet */
-
- spinlock_t lock; /* interrupt spinlock */
- spinlock_t msg_lock; /* mailbox spinlock */
- struct mutex msg_mutex; /* mutex for blocking_requests */
-
- struct mutex setup_mutex; /* mutex used in hw_params, open and close */
-
- /* hardware interface */
- unsigned int dsp_loaded; /* bit flags of loaded dsp indices */
- unsigned int board_type; /* read from embedded once elf file is loaded, 250 = miXart8, 251 = with AES, 252 = with Cobranet */
-
- struct snd_dma_buffer flowinfo;
- struct snd_dma_buffer bufferinfo;
-
- struct mixart_uid uid_console_manager;
- int sample_rate;
- int ref_count_rate;
-
- struct mutex mixer_mutex; /* mutex for mixer */
-
-};
-
-
-#define MIXART_STREAM_STATUS_FREE 0
-#define MIXART_STREAM_STATUS_OPEN 1
-#define MIXART_STREAM_STATUS_RUNNING 2
-#define MIXART_STREAM_STATUS_DRAINING 3
-#define MIXART_STREAM_STATUS_PAUSE 4
-
-#define MIXART_PLAYBACK_STREAMS 4
-#define MIXART_CAPTURE_STREAMS 1
-
-#define MIXART_PCM_ANALOG 0
-#define MIXART_PCM_DIGITAL 1
-#define MIXART_PCM_TOTAL 2
-
-#define MIXART_MAX_STREAM_PER_CARD (MIXART_PCM_TOTAL * (MIXART_PLAYBACK_STREAMS + MIXART_CAPTURE_STREAMS) )
-
-
-#define MIXART_NOTIFY_CARD_MASK 0xF000
-#define MIXART_NOTIFY_CARD_OFFSET 12
-#define MIXART_NOTIFY_PCM_MASK 0x0F00
-#define MIXART_NOTIFY_PCM_OFFSET 8
-#define MIXART_NOTIFY_CAPT_MASK 0x0080
-#define MIXART_NOTIFY_SUBS_MASK 0x007F
-
-
-struct mixart_stream {
- struct snd_pcm_substream *substream;
- struct mixart_pipe *pipe;
- int pcm_number;
-
- int status; /* nothing, running, draining */
-
- u64 abs_period_elapsed; /* last absolute stream position where period_elapsed was called (multiple of runtime->period_size) */
- u32 buf_periods; /* periods counter in the buffer (< runtime->periods) */
- u32 buf_period_frag; /* defines with buf_period_pos the exact position in the buffer (< runtime->period_size) */
-
- int channels;
-};
-
-
-enum mixart_pipe_status {
- PIPE_UNDEFINED,
- PIPE_STOPPED,
- PIPE_RUNNING,
- PIPE_CLOCK_SET
-};
-
-struct mixart_pipe {
- struct mixart_uid group_uid; /* id of the pipe, as returned by embedded */
- int stream_count;
- struct mixart_uid uid_left_connector; /* UID's for the audio connectors */
- struct mixart_uid uid_right_connector;
- enum mixart_pipe_status status;
- int references; /* number of subs openned */
- int monitoring; /* pipe used for monitoring issue */
-};
-
-
-struct snd_mixart {
- struct snd_card *card;
- struct mixart_mgr *mgr;
- int chip_idx; /* zero based */
- struct snd_hwdep *hwdep; /* DSP loader, only for the first card */
-
- struct snd_pcm *pcm; /* PCM analog i/o */
- struct snd_pcm *pcm_dig; /* PCM digital i/o */
-
- /* allocate stereo pipe for instance */
- struct mixart_pipe pipe_in_ana;
- struct mixart_pipe pipe_out_ana;
-
- /* if AES/EBU daughter board is available, additional pipes possible on pcm_dig */
- struct mixart_pipe pipe_in_dig;
- struct mixart_pipe pipe_out_dig;
-
- struct mixart_stream playback_stream[MIXART_PCM_TOTAL][MIXART_PLAYBACK_STREAMS]; /* 0 = pcm, 1 = pcm_dig */
- struct mixart_stream capture_stream[MIXART_PCM_TOTAL]; /* 0 = pcm, 1 = pcm_dig */
-
- /* UID's for the physical io's */
- struct mixart_uid uid_out_analog_physio;
- struct mixart_uid uid_in_analog_physio;
-
- int analog_playback_active[2]; /* Mixer : Master Playback active (!mute) */
- int analog_playback_volume[2]; /* Mixer : Master Playback Volume */
- int analog_capture_volume[2]; /* Mixer : Master Capture Volume */
- int digital_playback_active[2*MIXART_PLAYBACK_STREAMS][2]; /* Mixer : Digital Playback Active [(analog+AES output)*streams][stereo]*/
- int digital_playback_volume[2*MIXART_PLAYBACK_STREAMS][2]; /* Mixer : Digital Playback Volume [(analog+AES output)*streams][stereo]*/
- int digital_capture_volume[2][2]; /* Mixer : Digital Capture Volume [analog+AES output][stereo] */
- int monitoring_active[2]; /* Mixer : Monitoring Active */
- int monitoring_volume[2]; /* Mixer : Monitoring Volume */
-};
-
-struct mixart_bufferinfo
-{
- u32 buffer_address;
- u32 reserved[5];
- u32 available_length;
- u32 buffer_id;
-};
-
-struct mixart_flowinfo
-{
- u32 bufferinfo_array_phy_address;
- u32 reserved[11];
- u32 bufferinfo_count;
- u32 capture;
-};
-
-/* exported */
-int snd_mixart_create_pcm(struct snd_mixart * chip);
-struct mixart_pipe *snd_mixart_add_ref_pipe(struct snd_mixart *chip, int pcm_number, int capture, int monitoring);
-int snd_mixart_kill_ref_pipe(struct mixart_mgr *mgr, struct mixart_pipe *pipe, int monitoring);
-
-#endif /* __SOUND_MIXART_H */
diff --git a/ANDROID_3.4.5/sound/pci/mixart/mixart_core.c b/ANDROID_3.4.5/sound/pci/mixart/mixart_core.c
deleted file mode 100644
index 3df0f530..00000000
--- a/ANDROID_3.4.5/sound/pci/mixart/mixart_core.c
+++ /dev/null
@@ -1,598 +0,0 @@
-/*
- * Driver for Digigram miXart soundcards
- *
- * low level interface with interrupt handling and mail box implementation
- *
- * Copyright (c) 2003 by Digigram <alsa@digigram.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-
-#include <asm/io.h>
-#include <sound/core.h>
-#include "mixart.h"
-#include "mixart_hwdep.h"
-#include "mixart_core.h"
-
-
-#define MSG_TIMEOUT_JIFFIES (400 * HZ) / 1000 /* 400 ms */
-
-#define MSG_DESCRIPTOR_SIZE 0x24
-#define MSG_HEADER_SIZE (MSG_DESCRIPTOR_SIZE + 4)
-
-#define MSG_DEFAULT_SIZE 512
-
-#define MSG_TYPE_MASK 0x00000003 /* mask for following types */
-#define MSG_TYPE_NOTIFY 0 /* embedded -> driver (only notification, do not get_msg() !) */
-#define MSG_TYPE_COMMAND 1 /* driver <-> embedded (a command has no answer) */
-#define MSG_TYPE_REQUEST 2 /* driver -> embedded (request will get an answer back) */
-#define MSG_TYPE_ANSWER 3 /* embedded -> driver */
-#define MSG_CANCEL_NOTIFY_MASK 0x80000000 /* this bit is set for a notification that has been canceled */
-
-
-static int retrieve_msg_frame(struct mixart_mgr *mgr, u32 *msg_frame)
-{
- /* read the message frame fifo */
- u32 headptr, tailptr;
-
- tailptr = readl_be(MIXART_MEM(mgr, MSG_OUTBOUND_POST_TAIL));
- headptr = readl_be(MIXART_MEM(mgr, MSG_OUTBOUND_POST_HEAD));
-
- if (tailptr == headptr)
- return 0; /* no message posted */
-
- if (tailptr < MSG_OUTBOUND_POST_STACK)
- return 0; /* error */
- if (tailptr >= MSG_OUTBOUND_POST_STACK + MSG_BOUND_STACK_SIZE)
- return 0; /* error */
-
- *msg_frame = readl_be(MIXART_MEM(mgr, tailptr));
-
- /* increment the tail index */
- tailptr += 4;
- if( tailptr >= (MSG_OUTBOUND_POST_STACK+MSG_BOUND_STACK_SIZE) )
- tailptr = MSG_OUTBOUND_POST_STACK;
- writel_be(tailptr, MIXART_MEM(mgr, MSG_OUTBOUND_POST_TAIL));
-
- return 1;
-}
-
-static int get_msg(struct mixart_mgr *mgr, struct mixart_msg *resp,
- u32 msg_frame_address )
-{
- unsigned long flags;
- u32 headptr;
- u32 size;
- int err;
-#ifndef __BIG_ENDIAN
- unsigned int i;
-#endif
-
- spin_lock_irqsave(&mgr->msg_lock, flags);
- err = 0;
-
- /* copy message descriptor from miXart to driver */
- size = readl_be(MIXART_MEM(mgr, msg_frame_address)); /* size of descriptor + response */
- resp->message_id = readl_be(MIXART_MEM(mgr, msg_frame_address + 4)); /* dwMessageID */
- resp->uid.object_id = readl_be(MIXART_MEM(mgr, msg_frame_address + 8)); /* uidDest */
- resp->uid.desc = readl_be(MIXART_MEM(mgr, msg_frame_address + 12)); /* */
-
- if( (size < MSG_DESCRIPTOR_SIZE) || (resp->size < (size - MSG_DESCRIPTOR_SIZE))) {
- err = -EINVAL;
- snd_printk(KERN_ERR "problem with response size = %d\n", size);
- goto _clean_exit;
- }
- size -= MSG_DESCRIPTOR_SIZE;
-
- memcpy_fromio(resp->data, MIXART_MEM(mgr, msg_frame_address + MSG_HEADER_SIZE ), size);
- resp->size = size;
-
- /* swap if necessary */
-#ifndef __BIG_ENDIAN
- size /= 4; /* u32 size */
- for(i=0; i < size; i++) {
- ((u32*)resp->data)[i] = be32_to_cpu(((u32*)resp->data)[i]);
- }
-#endif
-
- /*
- * free message frame address
- */
- headptr = readl_be(MIXART_MEM(mgr, MSG_OUTBOUND_FREE_HEAD));
-
- if( (headptr < MSG_OUTBOUND_FREE_STACK) || ( headptr >= (MSG_OUTBOUND_FREE_STACK+MSG_BOUND_STACK_SIZE))) {
- err = -EINVAL;
- goto _clean_exit;
- }
-
- /* give address back to outbound fifo */
- writel_be(msg_frame_address, MIXART_MEM(mgr, headptr));
-
- /* increment the outbound free head */
- headptr += 4;
- if( headptr >= (MSG_OUTBOUND_FREE_STACK+MSG_BOUND_STACK_SIZE) )
- headptr = MSG_OUTBOUND_FREE_STACK;
-
- writel_be(headptr, MIXART_MEM(mgr, MSG_OUTBOUND_FREE_HEAD));
-
- _clean_exit:
- spin_unlock_irqrestore(&mgr->msg_lock, flags);
-
- return err;
-}
-
-
-/*
- * send a message to miXart. return: the msg_frame used for this message
- */
-/* call with mgr->msg_lock held! */
-static int send_msg( struct mixart_mgr *mgr,
- struct mixart_msg *msg,
- int max_answersize,
- int mark_pending,
- u32 *msg_event)
-{
- u32 headptr, tailptr;
- u32 msg_frame_address;
- int err, i;
-
- if (snd_BUG_ON(msg->size % 4))
- return -EINVAL;
-
- err = 0;
-
- /* get message frame address */
- tailptr = readl_be(MIXART_MEM(mgr, MSG_INBOUND_FREE_TAIL));
- headptr = readl_be(MIXART_MEM(mgr, MSG_INBOUND_FREE_HEAD));
-
- if (tailptr == headptr) {
- snd_printk(KERN_ERR "error: no message frame available\n");
- return -EBUSY;
- }
-
- if( (tailptr < MSG_INBOUND_FREE_STACK) || (tailptr >= (MSG_INBOUND_FREE_STACK+MSG_BOUND_STACK_SIZE))) {
- return -EINVAL;
- }
-
- msg_frame_address = readl_be(MIXART_MEM(mgr, tailptr));
- writel(0, MIXART_MEM(mgr, tailptr)); /* set address to zero on this fifo position */
-
- /* increment the inbound free tail */
- tailptr += 4;
- if( tailptr >= (MSG_INBOUND_FREE_STACK+MSG_BOUND_STACK_SIZE) )
- tailptr = MSG_INBOUND_FREE_STACK;
-
- writel_be(tailptr, MIXART_MEM(mgr, MSG_INBOUND_FREE_TAIL));
-
- /* TODO : use memcpy_toio() with intermediate buffer to copy the message */
-
- /* copy message descriptor to card memory */
- writel_be( msg->size + MSG_DESCRIPTOR_SIZE, MIXART_MEM(mgr, msg_frame_address) ); /* size of descriptor + request */
- writel_be( msg->message_id , MIXART_MEM(mgr, msg_frame_address + 4) ); /* dwMessageID */
- writel_be( msg->uid.object_id, MIXART_MEM(mgr, msg_frame_address + 8) ); /* uidDest */
- writel_be( msg->uid.desc, MIXART_MEM(mgr, msg_frame_address + 12) ); /* */
- writel_be( MSG_DESCRIPTOR_SIZE, MIXART_MEM(mgr, msg_frame_address + 16) ); /* SizeHeader */
- writel_be( MSG_DESCRIPTOR_SIZE, MIXART_MEM(mgr, msg_frame_address + 20) ); /* OffsetDLL_T16 */
- writel_be( msg->size, MIXART_MEM(mgr, msg_frame_address + 24) ); /* SizeDLL_T16 */
- writel_be( MSG_DESCRIPTOR_SIZE, MIXART_MEM(mgr, msg_frame_address + 28) ); /* OffsetDLL_DRV */
- writel_be( 0, MIXART_MEM(mgr, msg_frame_address + 32) ); /* SizeDLL_DRV */
- writel_be( MSG_DESCRIPTOR_SIZE + max_answersize, MIXART_MEM(mgr, msg_frame_address + 36) ); /* dwExpectedAnswerSize */
-
- /* copy message data to card memory */
- for( i=0; i < msg->size; i+=4 ) {
- writel_be( *(u32*)(msg->data + i), MIXART_MEM(mgr, MSG_HEADER_SIZE + msg_frame_address + i) );
- }
-
- if( mark_pending ) {
- if( *msg_event ) {
- /* the pending event is the notification we wait for ! */
- mgr->pending_event = *msg_event;
- }
- else {
- /* the pending event is the answer we wait for (same address than the request)! */
- mgr->pending_event = msg_frame_address;
-
- /* copy address back to caller */
- *msg_event = msg_frame_address;
- }
- }
-
- /* mark the frame as a request (will have an answer) */
- msg_frame_address |= MSG_TYPE_REQUEST;
-
- /* post the frame */
- headptr = readl_be(MIXART_MEM(mgr, MSG_INBOUND_POST_HEAD));
-
- if( (headptr < MSG_INBOUND_POST_STACK) || (headptr >= (MSG_INBOUND_POST_STACK+MSG_BOUND_STACK_SIZE))) {
- return -EINVAL;
- }
-
- writel_be(msg_frame_address, MIXART_MEM(mgr, headptr));
-
- /* increment the inbound post head */
- headptr += 4;
- if( headptr >= (MSG_INBOUND_POST_STACK+MSG_BOUND_STACK_SIZE) )
- headptr = MSG_INBOUND_POST_STACK;
-
- writel_be(headptr, MIXART_MEM(mgr, MSG_INBOUND_POST_HEAD));
-
- return 0;
-}
-
-
-int snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int max_resp_size, void *resp_data)
-{
- struct mixart_msg resp;
- u32 msg_frame = 0; /* set to 0, so it's no notification to wait for, but the answer */
- int err;
- wait_queue_t wait;
- long timeout;
-
- mutex_lock(&mgr->msg_mutex);
-
- init_waitqueue_entry(&wait, current);
-
- spin_lock_irq(&mgr->msg_lock);
- /* send the message */
- err = send_msg(mgr, request, max_resp_size, 1, &msg_frame); /* send and mark the answer pending */
- if (err) {
- spin_unlock_irq(&mgr->msg_lock);
- mutex_unlock(&mgr->msg_mutex);
- return err;
- }
-
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&mgr->msg_sleep, &wait);
- spin_unlock_irq(&mgr->msg_lock);
- timeout = schedule_timeout(MSG_TIMEOUT_JIFFIES);
- remove_wait_queue(&mgr->msg_sleep, &wait);
-
- if (! timeout) {
- /* error - no ack */
- mutex_unlock(&mgr->msg_mutex);
- snd_printk(KERN_ERR "error: no response on msg %x\n", msg_frame);
- return -EIO;
- }
-
- /* retrieve the answer into the same struct mixart_msg */
- resp.message_id = 0;
- resp.uid = (struct mixart_uid){0,0};
- resp.data = resp_data;
- resp.size = max_resp_size;
-
- err = get_msg(mgr, &resp, msg_frame);
-
- if( request->message_id != resp.message_id )
- snd_printk(KERN_ERR "RESPONSE ERROR!\n");
-
- mutex_unlock(&mgr->msg_mutex);
- return err;
-}
-
-
-int snd_mixart_send_msg_wait_notif(struct mixart_mgr *mgr,
- struct mixart_msg *request, u32 notif_event)
-{
- int err;
- wait_queue_t wait;
- long timeout;
-
- if (snd_BUG_ON(!notif_event))
- return -EINVAL;
- if (snd_BUG_ON((notif_event & MSG_TYPE_MASK) != MSG_TYPE_NOTIFY))
- return -EINVAL;
- if (snd_BUG_ON(notif_event & MSG_CANCEL_NOTIFY_MASK))
- return -EINVAL;
-
- mutex_lock(&mgr->msg_mutex);
-
- init_waitqueue_entry(&wait, current);
-
- spin_lock_irq(&mgr->msg_lock);
- /* send the message */
- err = send_msg(mgr, request, MSG_DEFAULT_SIZE, 1, &notif_event); /* send and mark the notification event pending */
- if(err) {
- spin_unlock_irq(&mgr->msg_lock);
- mutex_unlock(&mgr->msg_mutex);
- return err;
- }
-
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&mgr->msg_sleep, &wait);
- spin_unlock_irq(&mgr->msg_lock);
- timeout = schedule_timeout(MSG_TIMEOUT_JIFFIES);
- remove_wait_queue(&mgr->msg_sleep, &wait);
-
- if (! timeout) {
- /* error - no ack */
- mutex_unlock(&mgr->msg_mutex);
- snd_printk(KERN_ERR "error: notification %x not received\n", notif_event);
- return -EIO;
- }
-
- mutex_unlock(&mgr->msg_mutex);
- return 0;
-}
-
-
-int snd_mixart_send_msg_nonblock(struct mixart_mgr *mgr, struct mixart_msg *request)
-{
- u32 message_frame;
- unsigned long flags;
- int err;
-
- /* just send the message (do not mark it as a pending one) */
- spin_lock_irqsave(&mgr->msg_lock, flags);
- err = send_msg(mgr, request, MSG_DEFAULT_SIZE, 0, &message_frame);
- spin_unlock_irqrestore(&mgr->msg_lock, flags);
-
- /* the answer will be handled by snd_struct mixart_msgasklet() */
- atomic_inc(&mgr->msg_processed);
-
- return err;
-}
-
-
-/* common buffer of tasklet and interrupt to send/receive messages */
-static u32 mixart_msg_data[MSG_DEFAULT_SIZE / 4];
-
-
-void snd_mixart_msg_tasklet(unsigned long arg)
-{
- struct mixart_mgr *mgr = ( struct mixart_mgr*)(arg);
- struct mixart_msg resp;
- u32 msg, addr, type;
- int err;
-
- spin_lock(&mgr->lock);
-
- while (mgr->msg_fifo_readptr != mgr->msg_fifo_writeptr) {
- msg = mgr->msg_fifo[mgr->msg_fifo_readptr];
- mgr->msg_fifo_readptr++;
- mgr->msg_fifo_readptr %= MSG_FIFO_SIZE;
-
- /* process the message ... */
- addr = msg & ~MSG_TYPE_MASK;
- type = msg & MSG_TYPE_MASK;
-
- switch (type) {
- case MSG_TYPE_ANSWER:
- /* answer to a message on that we did not wait for (send_msg_nonblock) */
- resp.message_id = 0;
- resp.data = mixart_msg_data;
- resp.size = sizeof(mixart_msg_data);
- err = get_msg(mgr, &resp, addr);
- if( err < 0 ) {
- snd_printk(KERN_ERR "tasklet: error(%d) reading mf %x\n", err, msg);
- break;
- }
-
- switch(resp.message_id) {
- case MSG_STREAM_START_INPUT_STAGE_PACKET:
- case MSG_STREAM_START_OUTPUT_STAGE_PACKET:
- case MSG_STREAM_STOP_INPUT_STAGE_PACKET:
- case MSG_STREAM_STOP_OUTPUT_STAGE_PACKET:
- if(mixart_msg_data[0])
- snd_printk(KERN_ERR "tasklet : error MSG_STREAM_ST***_***PUT_STAGE_PACKET status=%x\n", mixart_msg_data[0]);
- break;
- default:
- snd_printdd("tasklet received mf(%x) : msg_id(%x) uid(%x, %x) size(%zd)\n",
- msg, resp.message_id, resp.uid.object_id, resp.uid.desc, resp.size);
- break;
- }
- break;
- case MSG_TYPE_NOTIFY:
- /* msg contains no address ! do not get_msg() ! */
- case MSG_TYPE_COMMAND:
- /* get_msg() necessary */
- default:
- snd_printk(KERN_ERR "tasklet doesn't know what to do with message %x\n", msg);
- } /* switch type */
-
- /* decrement counter */
- atomic_dec(&mgr->msg_processed);
-
- } /* while there is a msg in fifo */
-
- spin_unlock(&mgr->lock);
-}
-
-
-irqreturn_t snd_mixart_interrupt(int irq, void *dev_id)
-{
- struct mixart_mgr *mgr = dev_id;
- int err;
- struct mixart_msg resp;
-
- u32 msg;
- u32 it_reg;
-
- spin_lock(&mgr->lock);
-
- it_reg = readl_le(MIXART_REG(mgr, MIXART_PCI_OMISR_OFFSET));
- if( !(it_reg & MIXART_OIDI) ) {
- /* this device did not cause the interrupt */
- spin_unlock(&mgr->lock);
- return IRQ_NONE;
- }
-
- /* mask all interrupts */
- writel_le(MIXART_HOST_ALL_INTERRUPT_MASKED, MIXART_REG(mgr, MIXART_PCI_OMIMR_OFFSET));
-
- /* outdoorbell register clear */
- it_reg = readl(MIXART_REG(mgr, MIXART_PCI_ODBR_OFFSET));
- writel(it_reg, MIXART_REG(mgr, MIXART_PCI_ODBR_OFFSET));
-
- /* clear interrupt */
- writel_le( MIXART_OIDI, MIXART_REG(mgr, MIXART_PCI_OMISR_OFFSET) );
-
- /* process interrupt */
- while (retrieve_msg_frame(mgr, &msg)) {
-
- switch (msg & MSG_TYPE_MASK) {
- case MSG_TYPE_COMMAND:
- resp.message_id = 0;
- resp.data = mixart_msg_data;
- resp.size = sizeof(mixart_msg_data);
- err = get_msg(mgr, &resp, msg & ~MSG_TYPE_MASK);
- if( err < 0 ) {
- snd_printk(KERN_ERR "interrupt: error(%d) reading mf %x\n", err, msg);
- break;
- }
-
- if(resp.message_id == MSG_SERVICES_TIMER_NOTIFY) {
- int i;
- struct mixart_timer_notify *notify;
- notify = (struct mixart_timer_notify *)mixart_msg_data;
-
- for(i=0; i<notify->stream_count; i++) {
-
- u32 buffer_id = notify->streams[i].buffer_id;
- unsigned int chip_number = (buffer_id & MIXART_NOTIFY_CARD_MASK) >> MIXART_NOTIFY_CARD_OFFSET; /* card0 to 3 */
- unsigned int pcm_number = (buffer_id & MIXART_NOTIFY_PCM_MASK ) >> MIXART_NOTIFY_PCM_OFFSET; /* pcm0 to 3 */
- unsigned int sub_number = buffer_id & MIXART_NOTIFY_SUBS_MASK; /* 0 to MIXART_PLAYBACK_STREAMS */
- unsigned int is_capture = ((buffer_id & MIXART_NOTIFY_CAPT_MASK) != 0); /* playback == 0 / capture == 1 */
-
- struct snd_mixart *chip = mgr->chip[chip_number];
- struct mixart_stream *stream;
-
- if ((chip_number >= mgr->num_cards) || (pcm_number >= MIXART_PCM_TOTAL) || (sub_number >= MIXART_PLAYBACK_STREAMS)) {
- snd_printk(KERN_ERR "error MSG_SERVICES_TIMER_NOTIFY buffer_id (%x) pos(%d)\n",
- buffer_id, notify->streams[i].sample_pos_low_part);
- break;
- }
-
- if (is_capture)
- stream = &chip->capture_stream[pcm_number];
- else
- stream = &chip->playback_stream[pcm_number][sub_number];
-
- if (stream->substream && (stream->status == MIXART_STREAM_STATUS_RUNNING)) {
- struct snd_pcm_runtime *runtime = stream->substream->runtime;
- int elapsed = 0;
- u64 sample_count = ((u64)notify->streams[i].sample_pos_high_part) << 32;
- sample_count |= notify->streams[i].sample_pos_low_part;
-
- while (1) {
- u64 new_elapse_pos = stream->abs_period_elapsed + runtime->period_size;
-
- if (new_elapse_pos > sample_count) {
- break; /* while */
- }
- else {
- elapsed = 1;
- stream->buf_periods++;
- if (stream->buf_periods >= runtime->periods)
- stream->buf_periods = 0;
-
- stream->abs_period_elapsed = new_elapse_pos;
- }
- }
- stream->buf_period_frag = (u32)( sample_count - stream->abs_period_elapsed );
-
- if(elapsed) {
- spin_unlock(&mgr->lock);
- snd_pcm_period_elapsed(stream->substream);
- spin_lock(&mgr->lock);
- }
- }
- }
- break;
- }
- if(resp.message_id == MSG_SERVICES_REPORT_TRACES) {
- if(resp.size > 1) {
-#ifndef __BIG_ENDIAN
- /* Traces are text: the swapped msg_data has to be swapped back ! */
- int i;
- for(i=0; i<(resp.size/4); i++) {
- (mixart_msg_data)[i] = cpu_to_be32((mixart_msg_data)[i]);
- }
-#endif
- ((char*)mixart_msg_data)[resp.size - 1] = 0;
- snd_printdd("MIXART TRACE : %s\n", (char*)mixart_msg_data);
- }
- break;
- }
-
- snd_printdd("command %x not handled\n", resp.message_id);
- break;
-
- case MSG_TYPE_NOTIFY:
- if(msg & MSG_CANCEL_NOTIFY_MASK) {
- msg &= ~MSG_CANCEL_NOTIFY_MASK;
- snd_printk(KERN_ERR "canceled notification %x !\n", msg);
- }
- /* no break, continue ! */
- case MSG_TYPE_ANSWER:
- /* answer or notification to a message we are waiting for*/
- spin_lock(&mgr->msg_lock);
- if( (msg & ~MSG_TYPE_MASK) == mgr->pending_event ) {
- wake_up(&mgr->msg_sleep);
- mgr->pending_event = 0;
- }
- /* answer to a message we did't want to wait for */
- else {
- mgr->msg_fifo[mgr->msg_fifo_writeptr] = msg;
- mgr->msg_fifo_writeptr++;
- mgr->msg_fifo_writeptr %= MSG_FIFO_SIZE;
- tasklet_schedule(&mgr->msg_taskq);
- }
- spin_unlock(&mgr->msg_lock);
- break;
- case MSG_TYPE_REQUEST:
- default:
- snd_printdd("interrupt received request %x\n", msg);
- /* TODO : are there things to do here ? */
- break;
- } /* switch on msg type */
- } /* while there are msgs */
-
- /* allow interrupt again */
- writel_le( MIXART_ALLOW_OUTBOUND_DOORBELL, MIXART_REG( mgr, MIXART_PCI_OMIMR_OFFSET));
-
- spin_unlock(&mgr->lock);
-
- return IRQ_HANDLED;
-}
-
-
-void snd_mixart_init_mailbox(struct mixart_mgr *mgr)
-{
- writel( 0, MIXART_MEM( mgr, MSG_HOST_RSC_PROTECTION ) );
- writel( 0, MIXART_MEM( mgr, MSG_AGENT_RSC_PROTECTION ) );
-
- /* allow outbound messagebox to generate interrupts */
- if(mgr->irq >= 0) {
- writel_le( MIXART_ALLOW_OUTBOUND_DOORBELL, MIXART_REG( mgr, MIXART_PCI_OMIMR_OFFSET));
- }
- return;
-}
-
-void snd_mixart_exit_mailbox(struct mixart_mgr *mgr)
-{
- /* no more interrupts on outbound messagebox */
- writel_le( MIXART_HOST_ALL_INTERRUPT_MASKED, MIXART_REG( mgr, MIXART_PCI_OMIMR_OFFSET));
- return;
-}
-
-void snd_mixart_reset_board(struct mixart_mgr *mgr)
-{
- /* reset miXart */
- writel_be( 1, MIXART_REG(mgr, MIXART_BA1_BRUTAL_RESET_OFFSET) );
- return;
-}
diff --git a/ANDROID_3.4.5/sound/pci/mixart/mixart_core.h b/ANDROID_3.4.5/sound/pci/mixart/mixart_core.h
deleted file mode 100644
index c919b734..00000000
--- a/ANDROID_3.4.5/sound/pci/mixart/mixart_core.h
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * Driver for Digigram miXart soundcards
- *
- * low level interface with interrupt handling and mail box implementation
- *
- * Copyright (c) 2003 by Digigram <alsa@digigram.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __SOUND_MIXART_CORE_H
-#define __SOUND_MIXART_CORE_H
-
-
-enum mixart_message_id {
- MSG_CONNECTOR_GET_AUDIO_INFO = 0x050008,
- MSG_CONNECTOR_GET_OUT_AUDIO_LEVEL = 0x050009,
- MSG_CONNECTOR_SET_OUT_AUDIO_LEVEL = 0x05000A,
-
- MSG_CONSOLE_MANAGER = 0x070000,
- MSG_CONSOLE_GET_CLOCK_UID = 0x070003,
-
- MSG_PHYSICALIO_SET_LEVEL = 0x0F0008,
-
- MSG_STREAM_ADD_INPUT_GROUP = 0x130000,
- MSG_STREAM_ADD_OUTPUT_GROUP = 0x130001,
- MSG_STREAM_DELETE_GROUP = 0x130004,
- MSG_STREAM_START_STREAM_GRP_PACKET = 0x130006,
- MSG_STREAM_START_INPUT_STAGE_PACKET = 0x130007,
- MSG_STREAM_START_OUTPUT_STAGE_PACKET = 0x130008,
- MSG_STREAM_STOP_STREAM_GRP_PACKET = 0x130009,
- MSG_STREAM_STOP_INPUT_STAGE_PACKET = 0x13000A,
- MSG_STREAM_STOP_OUTPUT_STAGE_PACKET = 0x13000B,
- MSG_STREAM_SET_INPUT_STAGE_PARAM = 0x13000F,
- MSG_STREAM_SET_OUTPUT_STAGE_PARAM = 0x130010,
- MSG_STREAM_SET_IN_AUDIO_LEVEL = 0x130015,
- MSG_STREAM_SET_OUT_STREAM_LEVEL = 0x130017,
-
- MSG_SYSTEM_FIRST_ID = 0x160000,
- MSG_SYSTEM_ENUM_PHYSICAL_IO = 0x16000E,
- MSG_SYSTEM_ENUM_PLAY_CONNECTOR = 0x160017,
- MSG_SYSTEM_ENUM_RECORD_CONNECTOR = 0x160018,
- MSG_SYSTEM_WAIT_SYNCHRO_CMD = 0x16002C,
- MSG_SYSTEM_SEND_SYNCHRO_CMD = 0x16002D,
-
- MSG_SERVICES_TIMER_NOTIFY = 0x1D0404,
- MSG_SERVICES_REPORT_TRACES = 0x1D0700,
-
- MSG_CLOCK_CHECK_PROPERTIES = 0x200001,
- MSG_CLOCK_SET_PROPERTIES = 0x200002,
-};
-
-
-struct mixart_msg
-{
- u32 message_id;
- struct mixart_uid uid;
- void* data;
- size_t size;
-};
-
-/* structs used to communicate with miXart */
-
-struct mixart_enum_connector_resp
-{
- u32 error_code;
- u32 first_uid_offset;
- u32 uid_count;
- u32 current_uid_index;
- struct mixart_uid uid[MIXART_MAX_PHYS_CONNECTORS];
-} __attribute__((packed));
-
-
-/* used for following struct */
-#define MIXART_FLOAT_P_22_0_TO_HEX 0x41b00000 /* 22.0f */
-#define MIXART_FLOAT_M_20_0_TO_HEX 0xc1a00000 /* -20.0f */
-#define MIXART_FLOAT____0_0_TO_HEX 0x00000000 /* 0.0f */
-
-struct mixart_audio_info_req
-{
- u32 line_max_level; /* float */
- u32 micro_max_level; /* float */
- u32 cd_max_level; /* float */
-} __attribute__((packed));
-
-struct mixart_analog_hw_info
-{
- u32 is_present;
- u32 hw_connection_type;
- u32 max_level; /* float */
- u32 min_var_level; /* float */
- u32 max_var_level; /* float */
- u32 step_var_level; /* float */
- u32 fix_gain; /* float */
- u32 zero_var; /* float */
-} __attribute__((packed));
-
-struct mixart_digital_hw_info
-{
- u32 hw_connection_type;
- u32 presence;
- u32 clock;
- u32 reserved;
-} __attribute__((packed));
-
-struct mixart_analog_info
-{
- u32 type_mask;
- struct mixart_analog_hw_info micro_info;
- struct mixart_analog_hw_info line_info;
- struct mixart_analog_hw_info cd_info;
- u32 analog_level_present;
-} __attribute__((packed));
-
-struct mixart_digital_info
-{
- u32 type_mask;
- struct mixart_digital_hw_info aes_info;
- struct mixart_digital_hw_info adat_info;
-} __attribute__((packed));
-
-struct mixart_audio_info
-{
- u32 clock_type_mask;
- struct mixart_analog_info analog_info;
- struct mixart_digital_info digital_info;
-} __attribute__((packed));
-
-struct mixart_audio_info_resp
-{
- u32 txx_status;
- struct mixart_audio_info info;
-} __attribute__((packed));
-
-
-/* used for nb_bytes_max_per_sample */
-#define MIXART_FLOAT_P__4_0_TO_HEX 0x40800000 /* +4.0f */
-#define MIXART_FLOAT_P__8_0_TO_HEX 0x41000000 /* +8.0f */
-
-struct mixart_stream_info
-{
- u32 size_max_byte_frame;
- u32 size_max_sample_frame;
- u32 nb_bytes_max_per_sample; /* float */
-} __attribute__((packed));
-
-/* MSG_STREAM_ADD_INPUT_GROUP */
-/* MSG_STREAM_ADD_OUTPUT_GROUP */
-
-struct mixart_streaming_group_req
-{
- u32 stream_count;
- u32 channel_count;
- u32 user_grp_number;
- u32 first_phys_audio;
- u32 latency;
- struct mixart_stream_info stream_info[32];
- struct mixart_uid connector;
- u32 flow_entry[32];
-} __attribute__((packed));
-
-struct mixart_stream_desc
-{
- struct mixart_uid stream_uid;
- u32 stream_desc;
-} __attribute__((packed));
-
-struct mixart_streaming_group
-{
- u32 status;
- struct mixart_uid group;
- u32 pipe_desc;
- u32 stream_count;
- struct mixart_stream_desc stream[32];
-} __attribute__((packed));
-
-/* MSG_STREAM_DELETE_GROUP */
-
-/* request : mixart_uid_t group */
-
-struct mixart_delete_group_resp
-{
- u32 status;
- u32 unused[2];
-} __attribute__((packed));
-
-
-/* MSG_STREAM_START_INPUT_STAGE_PACKET = 0x130000 + 7,
- MSG_STREAM_START_OUTPUT_STAGE_PACKET = 0x130000 + 8,
- MSG_STREAM_STOP_INPUT_STAGE_PACKET = 0x130000 + 10,
- MSG_STREAM_STOP_OUTPUT_STAGE_PACKET = 0x130000 + 11,
- */
-
-struct mixart_fx_couple_uid
-{
- struct mixart_uid uid_fx_code;
- struct mixart_uid uid_fx_data;
-} __attribute__((packed));
-
-struct mixart_txx_stream_desc
-{
- struct mixart_uid uid_pipe;
- u32 stream_idx;
- u32 fx_number;
- struct mixart_fx_couple_uid uid_fx[4];
-} __attribute__((packed));
-
-struct mixart_flow_info
-{
- struct mixart_txx_stream_desc stream_desc;
- u32 flow_entry;
- u32 flow_phy_addr;
-} __attribute__((packed));
-
-struct mixart_stream_state_req
-{
- u32 delayed;
- u64 scheduler;
- u32 reserved4np[3];
- u32 stream_count; /* set to 1 for instance */
- struct mixart_flow_info stream_info; /* could be an array[stream_count] */
-} __attribute__((packed));
-
-/* MSG_STREAM_START_STREAM_GRP_PACKET = 0x130000 + 6
- MSG_STREAM_STOP_STREAM_GRP_PACKET = 0x130000 + 9
- */
-
-struct mixart_group_state_req
-{
- u32 delayed;
- u64 scheduler;
- u32 reserved4np[2];
- u32 pipe_count; /* set to 1 for instance */
- struct mixart_uid pipe_uid[1]; /* could be an array[pipe_count] */
-} __attribute__((packed));
-
-struct mixart_group_state_resp
-{
- u32 txx_status;
- u64 scheduler;
-} __attribute__((packed));
-
-
-
-/* Structures used by the MSG_SERVICES_TIMER_NOTIFY command */
-
-struct mixart_sample_pos
-{
- u32 buffer_id;
- u32 validity;
- u32 sample_pos_high_part;
- u32 sample_pos_low_part;
-} __attribute__((packed));
-
-struct mixart_timer_notify
-{
- u32 stream_count;
- struct mixart_sample_pos streams[MIXART_MAX_STREAM_PER_CARD * MIXART_MAX_CARDS];
-} __attribute__((packed));
-
-
-/* MSG_CONSOLE_GET_CLOCK_UID = 0x070003,
- */
-
-/* request is a uid with desc = MSG_CONSOLE_MANAGER | cardindex */
-
-struct mixart_return_uid
-{
- u32 error_code;
- struct mixart_uid uid;
-} __attribute__((packed));
-
-/* MSG_CLOCK_CHECK_PROPERTIES = 0x200001,
- MSG_CLOCK_SET_PROPERTIES = 0x200002,
-*/
-
-enum mixart_clock_generic_type {
- CGT_NO_CLOCK,
- CGT_INTERNAL_CLOCK,
- CGT_PROGRAMMABLE_CLOCK,
- CGT_INTERNAL_ENSLAVED_CLOCK,
- CGT_EXTERNAL_CLOCK,
- CGT_CURRENT_CLOCK
-};
-
-enum mixart_clock_mode {
- CM_UNDEFINED,
- CM_MASTER,
- CM_SLAVE,
- CM_STANDALONE,
- CM_NOT_CONCERNED
-};
-
-
-struct mixart_clock_properties
-{
- u32 error_code;
- u32 validation_mask;
- u32 frequency;
- u32 reference_frequency;
- u32 clock_generic_type;
- u32 clock_mode;
- struct mixart_uid uid_clock_source;
- struct mixart_uid uid_event_source;
- u32 event_mode;
- u32 synchro_signal_presence;
- u32 format;
- u32 board_mask;
- u32 nb_callers; /* set to 1 (see below) */
- struct mixart_uid uid_caller[1];
-} __attribute__((packed));
-
-struct mixart_clock_properties_resp
-{
- u32 status;
- u32 clock_mode;
-} __attribute__((packed));
-
-
-/* MSG_STREAM_SET_INPUT_STAGE_PARAM = 0x13000F */
-/* MSG_STREAM_SET_OUTPUT_STAGE_PARAM = 0x130010 */
-
-enum mixart_coding_type {
- CT_NOT_DEFINED,
- CT_LINEAR,
- CT_MPEG_L1,
- CT_MPEG_L2,
- CT_MPEG_L3,
- CT_MPEG_L3_LSF,
- CT_GSM
-};
-enum mixart_sample_type {
- ST_NOT_DEFINED,
- ST_FLOATING_POINT_32BE,
- ST_FLOATING_POINT_32LE,
- ST_FLOATING_POINT_64BE,
- ST_FLOATING_POINT_64LE,
- ST_FIXED_POINT_8,
- ST_FIXED_POINT_16BE,
- ST_FIXED_POINT_16LE,
- ST_FIXED_POINT_24BE,
- ST_FIXED_POINT_24LE,
- ST_FIXED_POINT_32BE,
- ST_FIXED_POINT_32LE,
- ST_INTEGER_8,
- ST_INTEGER_16BE,
- ST_INTEGER_16LE,
- ST_INTEGER_24BE,
- ST_INTEGER_24LE,
- ST_INTEGER_32BE,
- ST_INTEGER_32LE
-};
-
-struct mixart_stream_param_desc
-{
- u32 coding_type; /* use enum mixart_coding_type */
- u32 sample_type; /* use enum mixart_sample_type */
-
- union {
- struct {
- u32 linear_endian_ness;
- u32 linear_bits;
- u32 is_signed;
- u32 is_float;
- } linear_format_info;
-
- struct {
- u32 mpeg_layer;
- u32 mpeg_mode;
- u32 mpeg_mode_extension;
- u32 mpeg_pre_emphasis;
- u32 mpeg_has_padding_bit;
- u32 mpeg_has_crc;
- u32 mpeg_has_extension;
- u32 mpeg_is_original;
- u32 mpeg_has_copyright;
- } mpeg_format_info;
- } format_info;
-
- u32 delayed;
- u64 scheduler;
- u32 sample_size;
- u32 has_header;
- u32 has_suffix;
- u32 has_bitrate;
- u32 samples_per_frame;
- u32 bytes_per_frame;
- u32 bytes_per_sample;
- u32 sampling_freq;
- u32 number_of_channel;
- u32 stream_number;
- u32 buffer_size;
- u32 differed_time;
- u32 reserved4np[3];
- u32 pipe_count; /* set to 1 (array size !) */
- u32 stream_count; /* set to 1 (array size !) */
- struct mixart_txx_stream_desc stream_desc[1]; /* only one stream per command, but this could be an array */
-
-} __attribute__((packed));
-
-
-/* MSG_CONNECTOR_GET_OUT_AUDIO_LEVEL = 0x050009,
- */
-
-
-struct mixart_get_out_audio_level
-{
- u32 txx_status;
- u32 digital_level; /* float */
- u32 analog_level; /* float */
- u32 monitor_level; /* float */
- u32 mute;
- u32 monitor_mute1;
- u32 monitor_mute2;
-} __attribute__((packed));
-
-
-/* MSG_CONNECTOR_SET_OUT_AUDIO_LEVEL = 0x05000A,
- */
-
-/* used for valid_mask below */
-#define MIXART_AUDIO_LEVEL_ANALOG_MASK 0x01
-#define MIXART_AUDIO_LEVEL_DIGITAL_MASK 0x02
-#define MIXART_AUDIO_LEVEL_MONITOR_MASK 0x04
-#define MIXART_AUDIO_LEVEL_MUTE_MASK 0x08
-#define MIXART_AUDIO_LEVEL_MUTE_M1_MASK 0x10
-#define MIXART_AUDIO_LEVEL_MUTE_M2_MASK 0x20
-
-struct mixart_set_out_audio_level
-{
- u32 delayed;
- u64 scheduler;
- u32 valid_mask1;
- u32 valid_mask2;
- u32 digital_level; /* float */
- u32 analog_level; /* float */
- u32 monitor_level; /* float */
- u32 mute;
- u32 monitor_mute1;
- u32 monitor_mute2;
- u32 reserved4np;
-} __attribute__((packed));
-
-
-/* MSG_SYSTEM_ENUM_PHYSICAL_IO = 0x16000E,
- */
-
-#define MIXART_MAX_PHYS_IO (MIXART_MAX_CARDS * 2 * 2) /* 4 * (analog+digital) * (playback+capture) */
-
-struct mixart_uid_enumeration
-{
- u32 error_code;
- u32 first_uid_offset;
- u32 nb_uid;
- u32 current_uid_index;
- struct mixart_uid uid[MIXART_MAX_PHYS_IO];
-} __attribute__((packed));
-
-
-/* MSG_PHYSICALIO_SET_LEVEL = 0x0F0008,
- MSG_PHYSICALIO_GET_LEVEL = 0x0F000C,
-*/
-
-struct mixart_io_channel_level
-{
- u32 analog_level; /* float */
- u32 unused[2];
-} __attribute__((packed));
-
-struct mixart_io_level
-{
- s32 channel; /* 0=left, 1=right, -1=both, -2=both same */
- struct mixart_io_channel_level level[2];
-} __attribute__((packed));
-
-
-/* MSG_STREAM_SET_IN_AUDIO_LEVEL = 0x130015,
- */
-
-struct mixart_in_audio_level_info
-{
- struct mixart_uid connector;
- u32 valid_mask1;
- u32 valid_mask2;
- u32 digital_level;
- u32 analog_level;
-} __attribute__((packed));
-
-struct mixart_set_in_audio_level_req
-{
- u32 delayed;
- u64 scheduler;
- u32 audio_count; /* set to <= 2 */
- u32 reserved4np;
- struct mixart_in_audio_level_info level[2];
-} __attribute__((packed));
-
-/* response is a 32 bit status */
-
-
-/* MSG_STREAM_SET_OUT_STREAM_LEVEL = 0x130017,
- */
-
-/* defines used for valid_mask1 */
-#define MIXART_OUT_STREAM_SET_LEVEL_LEFT_AUDIO1 0x01
-#define MIXART_OUT_STREAM_SET_LEVEL_LEFT_AUDIO2 0x02
-#define MIXART_OUT_STREAM_SET_LEVEL_RIGHT_AUDIO1 0x04
-#define MIXART_OUT_STREAM_SET_LEVEL_RIGHT_AUDIO2 0x08
-#define MIXART_OUT_STREAM_SET_LEVEL_STREAM_1 0x10
-#define MIXART_OUT_STREAM_SET_LEVEL_STREAM_2 0x20
-#define MIXART_OUT_STREAM_SET_LEVEL_MUTE_1 0x40
-#define MIXART_OUT_STREAM_SET_LEVEL_MUTE_2 0x80
-
-struct mixart_out_stream_level_info
-{
- u32 valid_mask1;
- u32 valid_mask2;
- u32 left_to_out1_level;
- u32 left_to_out2_level;
- u32 right_to_out1_level;
- u32 right_to_out2_level;
- u32 digital_level1;
- u32 digital_level2;
- u32 mute1;
- u32 mute2;
-} __attribute__((packed));
-
-struct mixart_set_out_stream_level
-{
- struct mixart_txx_stream_desc desc;
- struct mixart_out_stream_level_info out_level;
-} __attribute__((packed));
-
-struct mixart_set_out_stream_level_req
-{
- u32 delayed;
- u64 scheduler;
- u32 reserved4np[2];
- u32 nb_of_stream; /* set to 1 */
- struct mixart_set_out_stream_level stream_level; /* could be an array */
-} __attribute__((packed));
-
-/* response to this request is a u32 status value */
-
-
-/* exported */
-void snd_mixart_init_mailbox(struct mixart_mgr *mgr);
-void snd_mixart_exit_mailbox(struct mixart_mgr *mgr);
-
-int snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int max_resp_size, void *resp_data);
-int snd_mixart_send_msg_wait_notif(struct mixart_mgr *mgr, struct mixart_msg *request, u32 notif_event);
-int snd_mixart_send_msg_nonblock(struct mixart_mgr *mgr, struct mixart_msg *request);
-
-irqreturn_t snd_mixart_interrupt(int irq, void *dev_id);
-void snd_mixart_msg_tasklet(unsigned long arg);
-
-void snd_mixart_reset_board(struct mixart_mgr *mgr);
-
-#endif /* __SOUND_MIXART_CORE_H */
diff --git a/ANDROID_3.4.5/sound/pci/mixart/mixart_hwdep.c b/ANDROID_3.4.5/sound/pci/mixart/mixart_hwdep.c
deleted file mode 100644
index bfbdc91e..00000000
--- a/ANDROID_3.4.5/sound/pci/mixart/mixart_hwdep.c
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
- * Driver for Digigram miXart soundcards
- *
- * DSP firmware management
- *
- * Copyright (c) 2003 by Digigram <alsa@digigram.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/firmware.h>
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <asm/io.h>
-#include <sound/core.h>
-#include "mixart.h"
-#include "mixart_mixer.h"
-#include "mixart_core.h"
-#include "mixart_hwdep.h"
-
-
-/**
- * wait for a value on a peudo register, exit with a timeout
- *
- * @param mgr pointer to miXart manager structure
- * @param offset unsigned pseudo_register base + offset of value
- * @param value value
- * @param timeout timeout in centisenconds
- */
-static int mixart_wait_nice_for_register_value(struct mixart_mgr *mgr,
- u32 offset, int is_egal,
- u32 value, unsigned long timeout)
-{
- unsigned long end_time = jiffies + (timeout * HZ / 100);
- u32 read;
-
- do { /* we may take too long time in this loop.
- * so give controls back to kernel if needed.
- */
- cond_resched();
-
- read = readl_be( MIXART_MEM( mgr, offset ));
- if(is_egal) {
- if(read == value) return 0;
- }
- else { /* wait for different value */
- if(read != value) return 0;
- }
- } while ( time_after_eq(end_time, jiffies) );
-
- return -EBUSY;
-}
-
-
-/*
- structures needed to upload elf code packets
- */
-struct snd_mixart_elf32_ehdr {
- u8 e_ident[16];
- u16 e_type;
- u16 e_machine;
- u32 e_version;
- u32 e_entry;
- u32 e_phoff;
- u32 e_shoff;
- u32 e_flags;
- u16 e_ehsize;
- u16 e_phentsize;
- u16 e_phnum;
- u16 e_shentsize;
- u16 e_shnum;
- u16 e_shstrndx;
-};
-
-struct snd_mixart_elf32_phdr {
- u32 p_type;
- u32 p_offset;
- u32 p_vaddr;
- u32 p_paddr;
- u32 p_filesz;
- u32 p_memsz;
- u32 p_flags;
- u32 p_align;
-};
-
-static int mixart_load_elf(struct mixart_mgr *mgr, const struct firmware *dsp )
-{
- char elf32_magic_number[4] = {0x7f,'E','L','F'};
- struct snd_mixart_elf32_ehdr *elf_header;
- int i;
-
- elf_header = (struct snd_mixart_elf32_ehdr *)dsp->data;
- for( i=0; i<4; i++ )
- if ( elf32_magic_number[i] != elf_header->e_ident[i] )
- return -EINVAL;
-
- if( elf_header->e_phoff != 0 ) {
- struct snd_mixart_elf32_phdr elf_programheader;
-
- for( i=0; i < be16_to_cpu(elf_header->e_phnum); i++ ) {
- u32 pos = be32_to_cpu(elf_header->e_phoff) + (u32)(i * be16_to_cpu(elf_header->e_phentsize));
-
- memcpy( &elf_programheader, dsp->data + pos, sizeof(elf_programheader) );
-
- if(elf_programheader.p_type != 0) {
- if( elf_programheader.p_filesz != 0 ) {
- memcpy_toio( MIXART_MEM( mgr, be32_to_cpu(elf_programheader.p_vaddr)),
- dsp->data + be32_to_cpu( elf_programheader.p_offset ),
- be32_to_cpu( elf_programheader.p_filesz ));
- }
- }
- }
- }
- return 0;
-}
-
-/*
- * get basic information and init miXart
- */
-
-/* audio IDs for request to the board */
-#define MIXART_FIRST_ANA_AUDIO_ID 0
-#define MIXART_FIRST_DIG_AUDIO_ID 8
-
-static int mixart_enum_connectors(struct mixart_mgr *mgr)
-{
- u32 k;
- int err;
- struct mixart_msg request;
- struct mixart_enum_connector_resp *connector;
- struct mixart_audio_info_req *audio_info_req;
- struct mixart_audio_info_resp *audio_info;
-
- connector = kmalloc(sizeof(*connector), GFP_KERNEL);
- audio_info_req = kmalloc(sizeof(*audio_info_req), GFP_KERNEL);
- audio_info = kmalloc(sizeof(*audio_info), GFP_KERNEL);
- if (! connector || ! audio_info_req || ! audio_info) {
- err = -ENOMEM;
- goto __error;
- }
-
- audio_info_req->line_max_level = MIXART_FLOAT_P_22_0_TO_HEX;
- audio_info_req->micro_max_level = MIXART_FLOAT_M_20_0_TO_HEX;
- audio_info_req->cd_max_level = MIXART_FLOAT____0_0_TO_HEX;
-
- request.message_id = MSG_SYSTEM_ENUM_PLAY_CONNECTOR;
- request.uid = (struct mixart_uid){0,0}; /* board num = 0 */
- request.data = NULL;
- request.size = 0;
-
- err = snd_mixart_send_msg(mgr, &request, sizeof(*connector), connector);
- if((err < 0) || (connector->error_code) || (connector->uid_count > MIXART_MAX_PHYS_CONNECTORS)) {
- snd_printk(KERN_ERR "error MSG_SYSTEM_ENUM_PLAY_CONNECTOR\n");
- err = -EINVAL;
- goto __error;
- }
-
- for(k=0; k < connector->uid_count; k++) {
- struct mixart_pipe *pipe;
-
- if(k < MIXART_FIRST_DIG_AUDIO_ID) {
- pipe = &mgr->chip[k/2]->pipe_out_ana;
- } else {
- pipe = &mgr->chip[(k-MIXART_FIRST_DIG_AUDIO_ID)/2]->pipe_out_dig;
- }
- if(k & 1) {
- pipe->uid_right_connector = connector->uid[k]; /* odd */
- } else {
- pipe->uid_left_connector = connector->uid[k]; /* even */
- }
-
- /* snd_printk(KERN_DEBUG "playback connector[%d].object_id = %x\n", k, connector->uid[k].object_id); */
-
- /* TODO: really need send_msg MSG_CONNECTOR_GET_AUDIO_INFO for each connector ? perhaps for analog level caps ? */
- request.message_id = MSG_CONNECTOR_GET_AUDIO_INFO;
- request.uid = connector->uid[k];
- request.data = audio_info_req;
- request.size = sizeof(*audio_info_req);
-
- err = snd_mixart_send_msg(mgr, &request, sizeof(*audio_info), audio_info);
- if( err < 0 ) {
- snd_printk(KERN_ERR "error MSG_CONNECTOR_GET_AUDIO_INFO\n");
- goto __error;
- }
- /*snd_printk(KERN_DEBUG "play analog_info.analog_level_present = %x\n", audio_info->info.analog_info.analog_level_present);*/
- }
-
- request.message_id = MSG_SYSTEM_ENUM_RECORD_CONNECTOR;
- request.uid = (struct mixart_uid){0,0}; /* board num = 0 */
- request.data = NULL;
- request.size = 0;
-
- err = snd_mixart_send_msg(mgr, &request, sizeof(*connector), connector);
- if((err < 0) || (connector->error_code) || (connector->uid_count > MIXART_MAX_PHYS_CONNECTORS)) {
- snd_printk(KERN_ERR "error MSG_SYSTEM_ENUM_RECORD_CONNECTOR\n");
- err = -EINVAL;
- goto __error;
- }
-
- for(k=0; k < connector->uid_count; k++) {
- struct mixart_pipe *pipe;
-
- if(k < MIXART_FIRST_DIG_AUDIO_ID) {
- pipe = &mgr->chip[k/2]->pipe_in_ana;
- } else {
- pipe = &mgr->chip[(k-MIXART_FIRST_DIG_AUDIO_ID)/2]->pipe_in_dig;
- }
- if(k & 1) {
- pipe->uid_right_connector = connector->uid[k]; /* odd */
- } else {
- pipe->uid_left_connector = connector->uid[k]; /* even */
- }
-
- /* snd_printk(KERN_DEBUG "capture connector[%d].object_id = %x\n", k, connector->uid[k].object_id); */
-
- /* TODO: really need send_msg MSG_CONNECTOR_GET_AUDIO_INFO for each connector ? perhaps for analog level caps ? */
- request.message_id = MSG_CONNECTOR_GET_AUDIO_INFO;
- request.uid = connector->uid[k];
- request.data = audio_info_req;
- request.size = sizeof(*audio_info_req);
-
- err = snd_mixart_send_msg(mgr, &request, sizeof(*audio_info), audio_info);
- if( err < 0 ) {
- snd_printk(KERN_ERR "error MSG_CONNECTOR_GET_AUDIO_INFO\n");
- goto __error;
- }
- /*snd_printk(KERN_DEBUG "rec analog_info.analog_level_present = %x\n", audio_info->info.analog_info.analog_level_present);*/
- }
- err = 0;
-
- __error:
- kfree(connector);
- kfree(audio_info_req);
- kfree(audio_info);
-
- return err;
-}
-
-static int mixart_enum_physio(struct mixart_mgr *mgr)
-{
- u32 k;
- int err;
- struct mixart_msg request;
- struct mixart_uid get_console_mgr;
- struct mixart_return_uid console_mgr;
- struct mixart_uid_enumeration phys_io;
-
- /* get the uid for the console manager */
- get_console_mgr.object_id = 0;
- get_console_mgr.desc = MSG_CONSOLE_MANAGER | 0; /* cardindex = 0 */
-
- request.message_id = MSG_CONSOLE_GET_CLOCK_UID;
- request.uid = get_console_mgr;
- request.data = &get_console_mgr;
- request.size = sizeof(get_console_mgr);
-
- err = snd_mixart_send_msg(mgr, &request, sizeof(console_mgr), &console_mgr);
-
- if( (err < 0) || (console_mgr.error_code != 0) ) {
- snd_printk(KERN_DEBUG "error MSG_CONSOLE_GET_CLOCK_UID : err=%x\n", console_mgr.error_code);
- return -EINVAL;
- }
-
- /* used later for clock issues ! */
- mgr->uid_console_manager = console_mgr.uid;
-
- request.message_id = MSG_SYSTEM_ENUM_PHYSICAL_IO;
- request.uid = (struct mixart_uid){0,0};
- request.data = &console_mgr.uid;
- request.size = sizeof(console_mgr.uid);
-
- err = snd_mixart_send_msg(mgr, &request, sizeof(phys_io), &phys_io);
- if( (err < 0) || ( phys_io.error_code != 0 ) ) {
- snd_printk(KERN_ERR "error MSG_SYSTEM_ENUM_PHYSICAL_IO err(%x) error_code(%x)\n", err, phys_io.error_code );
- return -EINVAL;
- }
-
- /* min 2 phys io per card (analog in + analog out) */
- if (phys_io.nb_uid < MIXART_MAX_CARDS * 2)
- return -EINVAL;
-
- for(k=0; k<mgr->num_cards; k++) {
- mgr->chip[k]->uid_in_analog_physio = phys_io.uid[k];
- mgr->chip[k]->uid_out_analog_physio = phys_io.uid[phys_io.nb_uid/2 + k];
- }
-
- return 0;
-}
-
-
-static int mixart_first_init(struct mixart_mgr *mgr)
-{
- u32 k;
- int err;
- struct mixart_msg request;
-
- if((err = mixart_enum_connectors(mgr)) < 0) return err;
-
- if((err = mixart_enum_physio(mgr)) < 0) return err;
-
- /* send a synchro command to card (necessary to do this before first MSG_STREAM_START_STREAM_GRP_PACKET) */
- /* though why not here */
- request.message_id = MSG_SYSTEM_SEND_SYNCHRO_CMD;
- request.uid = (struct mixart_uid){0,0};
- request.data = NULL;
- request.size = 0;
- /* this command has no data. response is a 32 bit status */
- err = snd_mixart_send_msg(mgr, &request, sizeof(k), &k);
- if( (err < 0) || (k != 0) ) {
- snd_printk(KERN_ERR "error MSG_SYSTEM_SEND_SYNCHRO_CMD\n");
- return err == 0 ? -EINVAL : err;
- }
-
- return 0;
-}
-
-
-/* firmware base addresses (when hard coded) */
-#define MIXART_MOTHERBOARD_XLX_BASE_ADDRESS 0x00600000
-
-static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmware *dsp)
-{
- int err, card_index;
- u32 status_xilinx, status_elf, status_daught;
- u32 val;
-
- /* read motherboard xilinx status */
- status_xilinx = readl_be( MIXART_MEM( mgr,MIXART_PSEUDOREG_MXLX_STATUS_OFFSET ));
- /* read elf status */
- status_elf = readl_be( MIXART_MEM( mgr,MIXART_PSEUDOREG_ELF_STATUS_OFFSET ));
- /* read daughterboard xilinx status */
- status_daught = readl_be( MIXART_MEM( mgr,MIXART_PSEUDOREG_DXLX_STATUS_OFFSET ));
-
- /* motherboard xilinx status 5 will say that the board is performing a reset */
- if (status_xilinx == 5) {
- snd_printk(KERN_ERR "miXart is resetting !\n");
- return -EAGAIN; /* try again later */
- }
-
- switch (index) {
- case MIXART_MOTHERBOARD_XLX_INDEX:
-
- /* xilinx already loaded ? */
- if (status_xilinx == 4) {
- snd_printk(KERN_DEBUG "xilinx is already loaded !\n");
- return 0;
- }
- /* the status should be 0 == "idle" */
- if (status_xilinx != 0) {
- snd_printk(KERN_ERR "xilinx load error ! status = %d\n",
- status_xilinx);
- return -EIO; /* modprob -r may help ? */
- }
-
- /* check xilinx validity */
- if (((u32*)(dsp->data))[0] == 0xffffffff)
- return -EINVAL;
- if (dsp->size % 4)
- return -EINVAL;
-
- /* set xilinx status to copying */
- writel_be( 1, MIXART_MEM( mgr, MIXART_PSEUDOREG_MXLX_STATUS_OFFSET ));
-
- /* setup xilinx base address */
- writel_be( MIXART_MOTHERBOARD_XLX_BASE_ADDRESS, MIXART_MEM( mgr,MIXART_PSEUDOREG_MXLX_BASE_ADDR_OFFSET ));
- /* setup code size for xilinx file */
- writel_be( dsp->size, MIXART_MEM( mgr, MIXART_PSEUDOREG_MXLX_SIZE_OFFSET ));
-
- /* copy xilinx code */
- memcpy_toio( MIXART_MEM( mgr, MIXART_MOTHERBOARD_XLX_BASE_ADDRESS), dsp->data, dsp->size);
-
- /* set xilinx status to copy finished */
- writel_be( 2, MIXART_MEM( mgr, MIXART_PSEUDOREG_MXLX_STATUS_OFFSET ));
-
- /* return, because no further processing needed */
- return 0;
-
- case MIXART_MOTHERBOARD_ELF_INDEX:
-
- if (status_elf == 4) {
- snd_printk(KERN_DEBUG "elf file already loaded !\n");
- return 0;
- }
-
- /* the status should be 0 == "idle" */
- if (status_elf != 0) {
- snd_printk(KERN_ERR "elf load error ! status = %d\n",
- status_elf);
- return -EIO; /* modprob -r may help ? */
- }
-
- /* wait for xilinx status == 4 */
- err = mixart_wait_nice_for_register_value( mgr, MIXART_PSEUDOREG_MXLX_STATUS_OFFSET, 1, 4, 500); /* 5sec */
- if (err < 0) {
- snd_printk(KERN_ERR "xilinx was not loaded or "
- "could not be started\n");
- return err;
- }
-
- /* init some data on the card */
- writel_be( 0, MIXART_MEM( mgr, MIXART_PSEUDOREG_BOARDNUMBER ) ); /* set miXart boardnumber to 0 */
- writel_be( 0, MIXART_MEM( mgr, MIXART_FLOWTABLE_PTR ) ); /* reset pointer to flow table on miXart */
-
- /* set elf status to copying */
- writel_be( 1, MIXART_MEM( mgr, MIXART_PSEUDOREG_ELF_STATUS_OFFSET ));
-
- /* process the copying of the elf packets */
- err = mixart_load_elf( mgr, dsp );
- if (err < 0) return err;
-
- /* set elf status to copy finished */
- writel_be( 2, MIXART_MEM( mgr, MIXART_PSEUDOREG_ELF_STATUS_OFFSET ));
-
- /* wait for elf status == 4 */
- err = mixart_wait_nice_for_register_value( mgr, MIXART_PSEUDOREG_ELF_STATUS_OFFSET, 1, 4, 300); /* 3sec */
- if (err < 0) {
- snd_printk(KERN_ERR "elf could not be started\n");
- return err;
- }
-
- /* miXart waits at this point on the pointer to the flow table */
- writel_be( (u32)mgr->flowinfo.addr, MIXART_MEM( mgr, MIXART_FLOWTABLE_PTR ) ); /* give pointer of flow table to miXart */
-
- return 0; /* return, another xilinx file has to be loaded before */
-
- case MIXART_AESEBUBOARD_XLX_INDEX:
- default:
-
- /* elf and xilinx should be loaded */
- if (status_elf != 4 || status_xilinx != 4) {
- printk(KERN_ERR "xilinx or elf not "
- "successfully loaded\n");
- return -EIO; /* modprob -r may help ? */
- }
-
- /* wait for daughter detection != 0 */
- err = mixart_wait_nice_for_register_value( mgr, MIXART_PSEUDOREG_DBRD_PRESENCE_OFFSET, 0, 0, 30); /* 300msec */
- if (err < 0) {
- snd_printk(KERN_ERR "error starting elf file\n");
- return err;
- }
-
- /* the board type can now be retrieved */
- mgr->board_type = (DAUGHTER_TYPE_MASK & readl_be( MIXART_MEM( mgr, MIXART_PSEUDOREG_DBRD_TYPE_OFFSET)));
-
- if (mgr->board_type == MIXART_DAUGHTER_TYPE_NONE)
- break; /* no daughter board; the file does not have to be loaded, continue after the switch */
-
- /* only if aesebu daughter board presence (elf code must run) */
- if (mgr->board_type != MIXART_DAUGHTER_TYPE_AES )
- return -EINVAL;
-
- /* daughter should be idle */
- if (status_daught != 0) {
- printk(KERN_ERR "daughter load error ! status = %d\n",
- status_daught);
- return -EIO; /* modprob -r may help ? */
- }
-
- /* check daughterboard xilinx validity */
- if (((u32*)(dsp->data))[0] == 0xffffffff)
- return -EINVAL;
- if (dsp->size % 4)
- return -EINVAL;
-
- /* inform mixart about the size of the file */
- writel_be( dsp->size, MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_SIZE_OFFSET ));
-
- /* set daughterboard status to 1 */
- writel_be( 1, MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_STATUS_OFFSET ));
-
- /* wait for status == 2 */
- err = mixart_wait_nice_for_register_value( mgr, MIXART_PSEUDOREG_DXLX_STATUS_OFFSET, 1, 2, 30); /* 300msec */
- if (err < 0) {
- snd_printk(KERN_ERR "daughter board load error\n");
- return err;
- }
-
- /* get the address where to write the file */
- val = readl_be( MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_BASE_ADDR_OFFSET ));
- if (!val)
- return -EINVAL;
-
- /* copy daughterboard xilinx code */
- memcpy_toio( MIXART_MEM( mgr, val), dsp->data, dsp->size);
-
- /* set daughterboard status to 4 */
- writel_be( 4, MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_STATUS_OFFSET ));
-
- /* continue with init */
- break;
- } /* end of switch file index*/
-
- /* wait for daughter status == 3 */
- err = mixart_wait_nice_for_register_value( mgr, MIXART_PSEUDOREG_DXLX_STATUS_OFFSET, 1, 3, 300); /* 3sec */
- if (err < 0) {
- snd_printk(KERN_ERR
- "daughter board could not be initialised\n");
- return err;
- }
-
- /* init mailbox (communication with embedded) */
- snd_mixart_init_mailbox(mgr);
-
- /* first communication with embedded */
- err = mixart_first_init(mgr);
- if (err < 0) {
- snd_printk(KERN_ERR "miXart could not be set up\n");
- return err;
- }
-
- /* create devices and mixer in accordance with HW options*/
- for (card_index = 0; card_index < mgr->num_cards; card_index++) {
- struct snd_mixart *chip = mgr->chip[card_index];
-
- if ((err = snd_mixart_create_pcm(chip)) < 0)
- return err;
-
- if (card_index == 0) {
- if ((err = snd_mixart_create_mixer(chip->mgr)) < 0)
- return err;
- }
-
- if ((err = snd_card_register(chip->card)) < 0)
- return err;
- };
-
- snd_printdd("miXart firmware downloaded and successfully set up\n");
-
- return 0;
-}
-
-
-#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
-#if !defined(CONFIG_USE_MIXARTLOADER) && !defined(CONFIG_SND_MIXART) /* built-in kernel */
-#define SND_MIXART_FW_LOADER /* use the standard firmware loader */
-#endif
-#endif
-
-#ifdef SND_MIXART_FW_LOADER
-
-int snd_mixart_setup_firmware(struct mixart_mgr *mgr)
-{
- static char *fw_files[3] = {
- "miXart8.xlx", "miXart8.elf", "miXart8AES.xlx"
- };
- char path[32];
-
- const struct firmware *fw_entry;
- int i, err;
-
- for (i = 0; i < 3; i++) {
- sprintf(path, "mixart/%s", fw_files[i]);
- if (request_firmware(&fw_entry, path, &mgr->pci->dev)) {
- snd_printk(KERN_ERR "miXart: can't load firmware %s\n", path);
- return -ENOENT;
- }
- /* fake hwdep dsp record */
- err = mixart_dsp_load(mgr, i, fw_entry);
- release_firmware(fw_entry);
- if (err < 0)
- return err;
- mgr->dsp_loaded |= 1 << i;
- }
- return 0;
-}
-
-MODULE_FIRMWARE("mixart/miXart8.xlx");
-MODULE_FIRMWARE("mixart/miXart8.elf");
-MODULE_FIRMWARE("mixart/miXart8AES.xlx");
-
-#else /* old style firmware loading */
-
-/* miXart hwdep interface id string */
-#define SND_MIXART_HWDEP_ID "miXart Loader"
-
-static int mixart_hwdep_dsp_status(struct snd_hwdep *hw,
- struct snd_hwdep_dsp_status *info)
-{
- struct mixart_mgr *mgr = hw->private_data;
-
- strcpy(info->id, "miXart");
- info->num_dsps = MIXART_HARDW_FILES_MAX_INDEX;
-
- if (mgr->dsp_loaded & (1 << MIXART_MOTHERBOARD_ELF_INDEX))
- info->chip_ready = 1;
-
- info->version = MIXART_DRIVER_VERSION;
- return 0;
-}
-
-static int mixart_hwdep_dsp_load(struct snd_hwdep *hw,
- struct snd_hwdep_dsp_image *dsp)
-{
- struct mixart_mgr* mgr = hw->private_data;
- struct firmware fw;
- int err;
-
- fw.size = dsp->length;
- fw.data = vmalloc(dsp->length);
- if (! fw.data) {
- snd_printk(KERN_ERR "miXart: cannot allocate image size %d\n",
- (int)dsp->length);
- return -ENOMEM;
- }
- if (copy_from_user((void *) fw.data, dsp->image, dsp->length)) {
- vfree(fw.data);
- return -EFAULT;
- }
- err = mixart_dsp_load(mgr, dsp->index, &fw);
- vfree(fw.data);
- if (err < 0)
- return err;
- mgr->dsp_loaded |= 1 << dsp->index;
- return err;
-}
-
-int snd_mixart_setup_firmware(struct mixart_mgr *mgr)
-{
- int err;
- struct snd_hwdep *hw;
-
- /* only create hwdep interface for first cardX (see "index" module parameter)*/
- if ((err = snd_hwdep_new(mgr->chip[0]->card, SND_MIXART_HWDEP_ID, 0, &hw)) < 0)
- return err;
-
- hw->iface = SNDRV_HWDEP_IFACE_MIXART;
- hw->private_data = mgr;
- hw->ops.dsp_status = mixart_hwdep_dsp_status;
- hw->ops.dsp_load = mixart_hwdep_dsp_load;
- hw->exclusive = 1;
- sprintf(hw->name, SND_MIXART_HWDEP_ID);
- mgr->dsp_loaded = 0;
-
- return snd_card_register(mgr->chip[0]->card);
-}
-
-#endif /* SND_MIXART_FW_LOADER */
diff --git a/ANDROID_3.4.5/sound/pci/mixart/mixart_hwdep.h b/ANDROID_3.4.5/sound/pci/mixart/mixart_hwdep.h
deleted file mode 100644
index 812e288e..00000000
--- a/ANDROID_3.4.5/sound/pci/mixart/mixart_hwdep.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Driver for Digigram miXart soundcards
- *
- * definitions and makros for basic card access
- *
- * Copyright (c) 2003 by Digigram <alsa@digigram.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __SOUND_MIXART_HWDEP_H
-#define __SOUND_MIXART_HWDEP_H
-
-#include <sound/hwdep.h>
-
-#ifndef readl_be
-#define readl_be(x) be32_to_cpu(__raw_readl(x))
-#endif
-
-#ifndef writel_be
-#define writel_be(data,addr) __raw_writel(cpu_to_be32(data),addr)
-#endif
-
-#ifndef readl_le
-#define readl_le(x) le32_to_cpu(__raw_readl(x))
-#endif
-
-#ifndef writel_le
-#define writel_le(data,addr) __raw_writel(cpu_to_le32(data),addr)
-#endif
-
-#define MIXART_MEM(mgr,x) ((mgr)->mem[0].virt + (x))
-#define MIXART_REG(mgr,x) ((mgr)->mem[1].virt + (x))
-
-
-/* Daughter board Type */
-#define DAUGHTER_TYPE_MASK 0x0F
-#define DAUGHTER_VER_MASK 0xF0
-#define DAUGHTER_TYPEVER_MASK (DAUGHTER_TYPE_MASK|DAUGHTER_VER_MASK)
-
-#define MIXART_DAUGHTER_TYPE_NONE 0x00
-#define MIXART_DAUGHTER_TYPE_COBRANET 0x08
-#define MIXART_DAUGHTER_TYPE_AES 0x0E
-
-
-
-#define MIXART_BA0_SIZE (16 * 1024 * 1024) /* 16M */
-#define MIXART_BA1_SIZE (4 * 1024) /* 4k */
-
-/*
- * -----------BAR 0 --------------------------------------------------------------------------------------------------------
- */
-#define MIXART_PSEUDOREG 0x2000 /* base address for pseudoregister */
-
-#define MIXART_PSEUDOREG_BOARDNUMBER MIXART_PSEUDOREG+0 /* board number */
-
-/* perfmeter (available when elf loaded)*/
-#define MIXART_PSEUDOREG_PERF_STREAM_LOAD_OFFSET MIXART_PSEUDOREG+0x70 /* streaming load */
-#define MIXART_PSEUDOREG_PERF_SYSTEM_LOAD_OFFSET MIXART_PSEUDOREG+0x78 /* system load (reference)*/
-#define MIXART_PSEUDOREG_PERF_MAILBX_LOAD_OFFSET MIXART_PSEUDOREG+0x7C /* mailbox load */
-#define MIXART_PSEUDOREG_PERF_INTERR_LOAD_OFFSET MIXART_PSEUDOREG+0x74 /* interrupt handling load */
-
-/* motherboard xilinx loader info */
-#define MIXART_PSEUDOREG_MXLX_BASE_ADDR_OFFSET MIXART_PSEUDOREG+0x9C /* 0x00600000 */
-#define MIXART_PSEUDOREG_MXLX_SIZE_OFFSET MIXART_PSEUDOREG+0xA0 /* xilinx size in bytes */
-#define MIXART_PSEUDOREG_MXLX_STATUS_OFFSET MIXART_PSEUDOREG+0xA4 /* status = EMBEBBED_STAT_XXX */
-
-/* elf loader info */
-#define MIXART_PSEUDOREG_ELF_STATUS_OFFSET MIXART_PSEUDOREG+0xB0 /* status = EMBEBBED_STAT_XXX */
-
-/*
-* after the elf code is loaded, and the flowtable info was passed to it,
-* the driver polls on this address, until it shows 1 (presence) or 2 (absence)
-* once it is non-zero, the daughter board type may be read
-*/
-#define MIXART_PSEUDOREG_DBRD_PRESENCE_OFFSET MIXART_PSEUDOREG+0x990
-
-/* Global info structure */
-#define MIXART_PSEUDOREG_DBRD_TYPE_OFFSET MIXART_PSEUDOREG+0x994 /* Type and version of daughterboard */
-
-
-/* daughterboard xilinx loader info */
-#define MIXART_PSEUDOREG_DXLX_BASE_ADDR_OFFSET MIXART_PSEUDOREG+0x998 /* get the address here where to write the file */
-#define MIXART_PSEUDOREG_DXLX_SIZE_OFFSET MIXART_PSEUDOREG+0x99C /* xilinx size in bytes */
-#define MIXART_PSEUDOREG_DXLX_STATUS_OFFSET MIXART_PSEUDOREG+0x9A0 /* status = EMBEBBED_STAT_XXX */
-
-/* */
-#define MIXART_FLOWTABLE_PTR 0x3000 /* pointer to flow table */
-
-/* mailbox addresses */
-
-/* message DRV -> EMB */
-#define MSG_INBOUND_POST_HEAD 0x010008 /* DRV posts MF + increment4 */
-#define MSG_INBOUND_POST_TAIL 0x01000C /* EMB gets MF + increment4 */
-/* message EMB -> DRV */
-#define MSG_OUTBOUND_POST_TAIL 0x01001C /* DRV gets MF + increment4 */
-#define MSG_OUTBOUND_POST_HEAD 0x010018 /* EMB posts MF + increment4 */
-/* Get Free Frames */
-#define MSG_INBOUND_FREE_TAIL 0x010004 /* DRV gets MFA + increment4 */
-#define MSG_OUTBOUND_FREE_TAIL 0x010014 /* EMB gets MFA + increment4 */
-/* Put Free Frames */
-#define MSG_OUTBOUND_FREE_HEAD 0x010010 /* DRV puts MFA + increment4 */
-#define MSG_INBOUND_FREE_HEAD 0x010000 /* EMB puts MFA + increment4 */
-
-/* firmware addresses of the message fifos */
-#define MSG_BOUND_STACK_SIZE 0x004000 /* size of each following stack */
-/* posted messages */
-#define MSG_OUTBOUND_POST_STACK 0x108000 /* stack of messages to the DRV */
-#define MSG_INBOUND_POST_STACK 0x104000 /* stack of messages to the EMB */
-/* available empty messages */
-#define MSG_OUTBOUND_FREE_STACK 0x10C000 /* stack of free enveloped for EMB */
-#define MSG_INBOUND_FREE_STACK 0x100000 /* stack of free enveloped for DRV */
-
-
-/* defines for mailbox message frames */
-#define MSG_FRAME_OFFSET 0x64
-#define MSG_FRAME_SIZE 0x6400
-#define MSG_FRAME_NUMBER 32
-#define MSG_FROM_AGENT_ITMF_OFFSET (MSG_FRAME_OFFSET + (MSG_FRAME_SIZE * MSG_FRAME_NUMBER))
-#define MSG_TO_AGENT_ITMF_OFFSET (MSG_FROM_AGENT_ITMF_OFFSET + MSG_FRAME_SIZE)
-#define MSG_HOST_RSC_PROTECTION (MSG_TO_AGENT_ITMF_OFFSET + MSG_FRAME_SIZE)
-#define MSG_AGENT_RSC_PROTECTION (MSG_HOST_RSC_PROTECTION + 4)
-
-
-/*
- * -----------BAR 1 --------------------------------------------------------------------------------------------------------
- */
-
-/* interrupt addresses and constants */
-#define MIXART_PCI_OMIMR_OFFSET 0x34 /* outbound message interrupt mask register */
-#define MIXART_PCI_OMISR_OFFSET 0x30 /* outbound message interrupt status register */
-#define MIXART_PCI_ODBR_OFFSET 0x60 /* outbound doorbell register */
-
-#define MIXART_BA1_BRUTAL_RESET_OFFSET 0x68 /* write 1 in LSBit to reset board */
-
-#define MIXART_HOST_ALL_INTERRUPT_MASKED 0x02B /* 0000 0010 1011 */
-#define MIXART_ALLOW_OUTBOUND_DOORBELL 0x023 /* 0000 0010 0011 */
-#define MIXART_OIDI 0x008 /* 0000 0000 1000 */
-
-
-int snd_mixart_setup_firmware(struct mixart_mgr *mgr);
-
-#endif /* __SOUND_MIXART_HWDEP_H */
diff --git a/ANDROID_3.4.5/sound/pci/mixart/mixart_mixer.c b/ANDROID_3.4.5/sound/pci/mixart/mixart_mixer.c
deleted file mode 100644
index 3ba6174c..00000000
--- a/ANDROID_3.4.5/sound/pci/mixart/mixart_mixer.c
+++ /dev/null
@@ -1,1186 +0,0 @@
-/*
- * Driver for Digigram miXart soundcards
- *
- * mixer callbacks
- *
- * Copyright (c) 2003 by Digigram <alsa@digigram.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/time.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/mutex.h>
-
-#include <sound/core.h>
-#include "mixart.h"
-#include "mixart_core.h"
-#include "mixart_hwdep.h"
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include "mixart_mixer.h"
-
-static u32 mixart_analog_level[256] = {
- 0xc2c00000, /* [000] -96.0 dB */
- 0xc2bf0000, /* [001] -95.5 dB */
- 0xc2be0000, /* [002] -95.0 dB */
- 0xc2bd0000, /* [003] -94.5 dB */
- 0xc2bc0000, /* [004] -94.0 dB */
- 0xc2bb0000, /* [005] -93.5 dB */
- 0xc2ba0000, /* [006] -93.0 dB */
- 0xc2b90000, /* [007] -92.5 dB */
- 0xc2b80000, /* [008] -92.0 dB */
- 0xc2b70000, /* [009] -91.5 dB */
- 0xc2b60000, /* [010] -91.0 dB */
- 0xc2b50000, /* [011] -90.5 dB */
- 0xc2b40000, /* [012] -90.0 dB */
- 0xc2b30000, /* [013] -89.5 dB */
- 0xc2b20000, /* [014] -89.0 dB */
- 0xc2b10000, /* [015] -88.5 dB */
- 0xc2b00000, /* [016] -88.0 dB */
- 0xc2af0000, /* [017] -87.5 dB */
- 0xc2ae0000, /* [018] -87.0 dB */
- 0xc2ad0000, /* [019] -86.5 dB */
- 0xc2ac0000, /* [020] -86.0 dB */
- 0xc2ab0000, /* [021] -85.5 dB */
- 0xc2aa0000, /* [022] -85.0 dB */
- 0xc2a90000, /* [023] -84.5 dB */
- 0xc2a80000, /* [024] -84.0 dB */
- 0xc2a70000, /* [025] -83.5 dB */
- 0xc2a60000, /* [026] -83.0 dB */
- 0xc2a50000, /* [027] -82.5 dB */
- 0xc2a40000, /* [028] -82.0 dB */
- 0xc2a30000, /* [029] -81.5 dB */
- 0xc2a20000, /* [030] -81.0 dB */
- 0xc2a10000, /* [031] -80.5 dB */
- 0xc2a00000, /* [032] -80.0 dB */
- 0xc29f0000, /* [033] -79.5 dB */
- 0xc29e0000, /* [034] -79.0 dB */
- 0xc29d0000, /* [035] -78.5 dB */
- 0xc29c0000, /* [036] -78.0 dB */
- 0xc29b0000, /* [037] -77.5 dB */
- 0xc29a0000, /* [038] -77.0 dB */
- 0xc2990000, /* [039] -76.5 dB */
- 0xc2980000, /* [040] -76.0 dB */
- 0xc2970000, /* [041] -75.5 dB */
- 0xc2960000, /* [042] -75.0 dB */
- 0xc2950000, /* [043] -74.5 dB */
- 0xc2940000, /* [044] -74.0 dB */
- 0xc2930000, /* [045] -73.5 dB */
- 0xc2920000, /* [046] -73.0 dB */
- 0xc2910000, /* [047] -72.5 dB */
- 0xc2900000, /* [048] -72.0 dB */
- 0xc28f0000, /* [049] -71.5 dB */
- 0xc28e0000, /* [050] -71.0 dB */
- 0xc28d0000, /* [051] -70.5 dB */
- 0xc28c0000, /* [052] -70.0 dB */
- 0xc28b0000, /* [053] -69.5 dB */
- 0xc28a0000, /* [054] -69.0 dB */
- 0xc2890000, /* [055] -68.5 dB */
- 0xc2880000, /* [056] -68.0 dB */
- 0xc2870000, /* [057] -67.5 dB */
- 0xc2860000, /* [058] -67.0 dB */
- 0xc2850000, /* [059] -66.5 dB */
- 0xc2840000, /* [060] -66.0 dB */
- 0xc2830000, /* [061] -65.5 dB */
- 0xc2820000, /* [062] -65.0 dB */
- 0xc2810000, /* [063] -64.5 dB */
- 0xc2800000, /* [064] -64.0 dB */
- 0xc27e0000, /* [065] -63.5 dB */
- 0xc27c0000, /* [066] -63.0 dB */
- 0xc27a0000, /* [067] -62.5 dB */
- 0xc2780000, /* [068] -62.0 dB */
- 0xc2760000, /* [069] -61.5 dB */
- 0xc2740000, /* [070] -61.0 dB */
- 0xc2720000, /* [071] -60.5 dB */
- 0xc2700000, /* [072] -60.0 dB */
- 0xc26e0000, /* [073] -59.5 dB */
- 0xc26c0000, /* [074] -59.0 dB */
- 0xc26a0000, /* [075] -58.5 dB */
- 0xc2680000, /* [076] -58.0 dB */
- 0xc2660000, /* [077] -57.5 dB */
- 0xc2640000, /* [078] -57.0 dB */
- 0xc2620000, /* [079] -56.5 dB */
- 0xc2600000, /* [080] -56.0 dB */
- 0xc25e0000, /* [081] -55.5 dB */
- 0xc25c0000, /* [082] -55.0 dB */
- 0xc25a0000, /* [083] -54.5 dB */
- 0xc2580000, /* [084] -54.0 dB */
- 0xc2560000, /* [085] -53.5 dB */
- 0xc2540000, /* [086] -53.0 dB */
- 0xc2520000, /* [087] -52.5 dB */
- 0xc2500000, /* [088] -52.0 dB */
- 0xc24e0000, /* [089] -51.5 dB */
- 0xc24c0000, /* [090] -51.0 dB */
- 0xc24a0000, /* [091] -50.5 dB */
- 0xc2480000, /* [092] -50.0 dB */
- 0xc2460000, /* [093] -49.5 dB */
- 0xc2440000, /* [094] -49.0 dB */
- 0xc2420000, /* [095] -48.5 dB */
- 0xc2400000, /* [096] -48.0 dB */
- 0xc23e0000, /* [097] -47.5 dB */
- 0xc23c0000, /* [098] -47.0 dB */
- 0xc23a0000, /* [099] -46.5 dB */
- 0xc2380000, /* [100] -46.0 dB */
- 0xc2360000, /* [101] -45.5 dB */
- 0xc2340000, /* [102] -45.0 dB */
- 0xc2320000, /* [103] -44.5 dB */
- 0xc2300000, /* [104] -44.0 dB */
- 0xc22e0000, /* [105] -43.5 dB */
- 0xc22c0000, /* [106] -43.0 dB */
- 0xc22a0000, /* [107] -42.5 dB */
- 0xc2280000, /* [108] -42.0 dB */
- 0xc2260000, /* [109] -41.5 dB */
- 0xc2240000, /* [110] -41.0 dB */
- 0xc2220000, /* [111] -40.5 dB */
- 0xc2200000, /* [112] -40.0 dB */
- 0xc21e0000, /* [113] -39.5 dB */
- 0xc21c0000, /* [114] -39.0 dB */
- 0xc21a0000, /* [115] -38.5 dB */
- 0xc2180000, /* [116] -38.0 dB */
- 0xc2160000, /* [117] -37.5 dB */
- 0xc2140000, /* [118] -37.0 dB */
- 0xc2120000, /* [119] -36.5 dB */
- 0xc2100000, /* [120] -36.0 dB */
- 0xc20e0000, /* [121] -35.5 dB */
- 0xc20c0000, /* [122] -35.0 dB */
- 0xc20a0000, /* [123] -34.5 dB */
- 0xc2080000, /* [124] -34.0 dB */
- 0xc2060000, /* [125] -33.5 dB */
- 0xc2040000, /* [126] -33.0 dB */
- 0xc2020000, /* [127] -32.5 dB */
- 0xc2000000, /* [128] -32.0 dB */
- 0xc1fc0000, /* [129] -31.5 dB */
- 0xc1f80000, /* [130] -31.0 dB */
- 0xc1f40000, /* [131] -30.5 dB */
- 0xc1f00000, /* [132] -30.0 dB */
- 0xc1ec0000, /* [133] -29.5 dB */
- 0xc1e80000, /* [134] -29.0 dB */
- 0xc1e40000, /* [135] -28.5 dB */
- 0xc1e00000, /* [136] -28.0 dB */
- 0xc1dc0000, /* [137] -27.5 dB */
- 0xc1d80000, /* [138] -27.0 dB */
- 0xc1d40000, /* [139] -26.5 dB */
- 0xc1d00000, /* [140] -26.0 dB */
- 0xc1cc0000, /* [141] -25.5 dB */
- 0xc1c80000, /* [142] -25.0 dB */
- 0xc1c40000, /* [143] -24.5 dB */
- 0xc1c00000, /* [144] -24.0 dB */
- 0xc1bc0000, /* [145] -23.5 dB */
- 0xc1b80000, /* [146] -23.0 dB */
- 0xc1b40000, /* [147] -22.5 dB */
- 0xc1b00000, /* [148] -22.0 dB */
- 0xc1ac0000, /* [149] -21.5 dB */
- 0xc1a80000, /* [150] -21.0 dB */
- 0xc1a40000, /* [151] -20.5 dB */
- 0xc1a00000, /* [152] -20.0 dB */
- 0xc19c0000, /* [153] -19.5 dB */
- 0xc1980000, /* [154] -19.0 dB */
- 0xc1940000, /* [155] -18.5 dB */
- 0xc1900000, /* [156] -18.0 dB */
- 0xc18c0000, /* [157] -17.5 dB */
- 0xc1880000, /* [158] -17.0 dB */
- 0xc1840000, /* [159] -16.5 dB */
- 0xc1800000, /* [160] -16.0 dB */
- 0xc1780000, /* [161] -15.5 dB */
- 0xc1700000, /* [162] -15.0 dB */
- 0xc1680000, /* [163] -14.5 dB */
- 0xc1600000, /* [164] -14.0 dB */
- 0xc1580000, /* [165] -13.5 dB */
- 0xc1500000, /* [166] -13.0 dB */
- 0xc1480000, /* [167] -12.5 dB */
- 0xc1400000, /* [168] -12.0 dB */
- 0xc1380000, /* [169] -11.5 dB */
- 0xc1300000, /* [170] -11.0 dB */
- 0xc1280000, /* [171] -10.5 dB */
- 0xc1200000, /* [172] -10.0 dB */
- 0xc1180000, /* [173] -9.5 dB */
- 0xc1100000, /* [174] -9.0 dB */
- 0xc1080000, /* [175] -8.5 dB */
- 0xc1000000, /* [176] -8.0 dB */
- 0xc0f00000, /* [177] -7.5 dB */
- 0xc0e00000, /* [178] -7.0 dB */
- 0xc0d00000, /* [179] -6.5 dB */
- 0xc0c00000, /* [180] -6.0 dB */
- 0xc0b00000, /* [181] -5.5 dB */
- 0xc0a00000, /* [182] -5.0 dB */
- 0xc0900000, /* [183] -4.5 dB */
- 0xc0800000, /* [184] -4.0 dB */
- 0xc0600000, /* [185] -3.5 dB */
- 0xc0400000, /* [186] -3.0 dB */
- 0xc0200000, /* [187] -2.5 dB */
- 0xc0000000, /* [188] -2.0 dB */
- 0xbfc00000, /* [189] -1.5 dB */
- 0xbf800000, /* [190] -1.0 dB */
- 0xbf000000, /* [191] -0.5 dB */
- 0x00000000, /* [192] 0.0 dB */
- 0x3f000000, /* [193] 0.5 dB */
- 0x3f800000, /* [194] 1.0 dB */
- 0x3fc00000, /* [195] 1.5 dB */
- 0x40000000, /* [196] 2.0 dB */
- 0x40200000, /* [197] 2.5 dB */
- 0x40400000, /* [198] 3.0 dB */
- 0x40600000, /* [199] 3.5 dB */
- 0x40800000, /* [200] 4.0 dB */
- 0x40900000, /* [201] 4.5 dB */
- 0x40a00000, /* [202] 5.0 dB */
- 0x40b00000, /* [203] 5.5 dB */
- 0x40c00000, /* [204] 6.0 dB */
- 0x40d00000, /* [205] 6.5 dB */
- 0x40e00000, /* [206] 7.0 dB */
- 0x40f00000, /* [207] 7.5 dB */
- 0x41000000, /* [208] 8.0 dB */
- 0x41080000, /* [209] 8.5 dB */
- 0x41100000, /* [210] 9.0 dB */
- 0x41180000, /* [211] 9.5 dB */
- 0x41200000, /* [212] 10.0 dB */
- 0x41280000, /* [213] 10.5 dB */
- 0x41300000, /* [214] 11.0 dB */
- 0x41380000, /* [215] 11.5 dB */
- 0x41400000, /* [216] 12.0 dB */
- 0x41480000, /* [217] 12.5 dB */
- 0x41500000, /* [218] 13.0 dB */
- 0x41580000, /* [219] 13.5 dB */
- 0x41600000, /* [220] 14.0 dB */
- 0x41680000, /* [221] 14.5 dB */
- 0x41700000, /* [222] 15.0 dB */
- 0x41780000, /* [223] 15.5 dB */
- 0x41800000, /* [224] 16.0 dB */
- 0x41840000, /* [225] 16.5 dB */
- 0x41880000, /* [226] 17.0 dB */
- 0x418c0000, /* [227] 17.5 dB */
- 0x41900000, /* [228] 18.0 dB */
- 0x41940000, /* [229] 18.5 dB */
- 0x41980000, /* [230] 19.0 dB */
- 0x419c0000, /* [231] 19.5 dB */
- 0x41a00000, /* [232] 20.0 dB */
- 0x41a40000, /* [233] 20.5 dB */
- 0x41a80000, /* [234] 21.0 dB */
- 0x41ac0000, /* [235] 21.5 dB */
- 0x41b00000, /* [236] 22.0 dB */
- 0x41b40000, /* [237] 22.5 dB */
- 0x41b80000, /* [238] 23.0 dB */
- 0x41bc0000, /* [239] 23.5 dB */
- 0x41c00000, /* [240] 24.0 dB */
- 0x41c40000, /* [241] 24.5 dB */
- 0x41c80000, /* [242] 25.0 dB */
- 0x41cc0000, /* [243] 25.5 dB */
- 0x41d00000, /* [244] 26.0 dB */
- 0x41d40000, /* [245] 26.5 dB */
- 0x41d80000, /* [246] 27.0 dB */
- 0x41dc0000, /* [247] 27.5 dB */
- 0x41e00000, /* [248] 28.0 dB */
- 0x41e40000, /* [249] 28.5 dB */
- 0x41e80000, /* [250] 29.0 dB */
- 0x41ec0000, /* [251] 29.5 dB */
- 0x41f00000, /* [252] 30.0 dB */
- 0x41f40000, /* [253] 30.5 dB */
- 0x41f80000, /* [254] 31.0 dB */
- 0x41fc0000, /* [255] 31.5 dB */
-};
-
-#define MIXART_ANALOG_CAPTURE_LEVEL_MIN 0 /* -96.0 dB + 8.0 dB = -88.0 dB */
-#define MIXART_ANALOG_CAPTURE_LEVEL_MAX 255 /* 31.5 dB + 8.0 dB = 39.5 dB */
-#define MIXART_ANALOG_CAPTURE_ZERO_LEVEL 176 /* -8.0 dB + 8.0 dB = 0.0 dB */
-
-#define MIXART_ANALOG_PLAYBACK_LEVEL_MIN 0 /* -96.0 dB + 1.5 dB = -94.5 dB (possible is down to (-114.0+1.5)dB) */
-#define MIXART_ANALOG_PLAYBACK_LEVEL_MAX 192 /* 0.0 dB + 1.5 dB = 1.5 dB */
-#define MIXART_ANALOG_PLAYBACK_ZERO_LEVEL 189 /* -1.5 dB + 1.5 dB = 0.0 dB */
-
-static int mixart_update_analog_audio_level(struct snd_mixart* chip, int is_capture)
-{
- int i, err;
- struct mixart_msg request;
- struct mixart_io_level io_level;
- struct mixart_return_uid resp;
-
- memset(&io_level, 0, sizeof(io_level));
- io_level.channel = -1; /* left and right */
-
- for(i=0; i<2; i++) {
- if(is_capture) {
- io_level.level[i].analog_level = mixart_analog_level[chip->analog_capture_volume[i]];
- } else {
- if(chip->analog_playback_active[i])
- io_level.level[i].analog_level = mixart_analog_level[chip->analog_playback_volume[i]];
- else
- io_level.level[i].analog_level = mixart_analog_level[MIXART_ANALOG_PLAYBACK_LEVEL_MIN];
- }
- }
-
- if(is_capture) request.uid = chip->uid_in_analog_physio;
- else request.uid = chip->uid_out_analog_physio;
- request.message_id = MSG_PHYSICALIO_SET_LEVEL;
- request.data = &io_level;
- request.size = sizeof(io_level);
-
- err = snd_mixart_send_msg(chip->mgr, &request, sizeof(resp), &resp);
- if((err<0) || (resp.error_code)) {
- snd_printk(KERN_DEBUG "error MSG_PHYSICALIO_SET_LEVEL card(%d) is_capture(%d) error_code(%x)\n", chip->chip_idx, is_capture, resp.error_code);
- return -EINVAL;
- }
- return 0;
-}
-
-/*
- * analog level control
- */
-static int mixart_analog_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- if(kcontrol->private_value == 0) { /* playback */
- uinfo->value.integer.min = MIXART_ANALOG_PLAYBACK_LEVEL_MIN; /* -96 dB */
- uinfo->value.integer.max = MIXART_ANALOG_PLAYBACK_LEVEL_MAX; /* 0 dB */
- } else { /* capture */
- uinfo->value.integer.min = MIXART_ANALOG_CAPTURE_LEVEL_MIN; /* -96 dB */
- uinfo->value.integer.max = MIXART_ANALOG_CAPTURE_LEVEL_MAX; /* 31.5 dB */
- }
- return 0;
-}
-
-static int mixart_analog_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mgr->mixer_mutex);
- if(kcontrol->private_value == 0) { /* playback */
- ucontrol->value.integer.value[0] = chip->analog_playback_volume[0];
- ucontrol->value.integer.value[1] = chip->analog_playback_volume[1];
- } else { /* capture */
- ucontrol->value.integer.value[0] = chip->analog_capture_volume[0];
- ucontrol->value.integer.value[1] = chip->analog_capture_volume[1];
- }
- mutex_unlock(&chip->mgr->mixer_mutex);
- return 0;
-}
-
-static int mixart_analog_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- int is_capture, i;
-
- mutex_lock(&chip->mgr->mixer_mutex);
- is_capture = (kcontrol->private_value != 0);
- for (i = 0; i < 2; i++) {
- int new_volume = ucontrol->value.integer.value[i];
- int *stored_volume = is_capture ?
- &chip->analog_capture_volume[i] :
- &chip->analog_playback_volume[i];
- if (is_capture) {
- if (new_volume < MIXART_ANALOG_CAPTURE_LEVEL_MIN ||
- new_volume > MIXART_ANALOG_CAPTURE_LEVEL_MAX)
- continue;
- } else {
- if (new_volume < MIXART_ANALOG_PLAYBACK_LEVEL_MIN ||
- new_volume > MIXART_ANALOG_PLAYBACK_LEVEL_MAX)
- continue;
- }
- if (*stored_volume != new_volume) {
- *stored_volume = new_volume;
- changed = 1;
- }
- }
- if (changed)
- mixart_update_analog_audio_level(chip, is_capture);
- mutex_unlock(&chip->mgr->mixer_mutex);
- return changed;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_analog, -9600, 50, 0);
-
-static struct snd_kcontrol_new mixart_control_analog_level = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- /* name will be filled later */
- .info = mixart_analog_vol_info,
- .get = mixart_analog_vol_get,
- .put = mixart_analog_vol_put,
- .tlv = { .p = db_scale_analog },
-};
-
-/* shared */
-#define mixart_sw_info snd_ctl_boolean_stereo_info
-
-static int mixart_audio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&chip->mgr->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->analog_playback_active[0];
- ucontrol->value.integer.value[1] = chip->analog_playback_active[1];
- mutex_unlock(&chip->mgr->mixer_mutex);
- return 0;
-}
-
-static int mixart_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
- int i, changed = 0;
- mutex_lock(&chip->mgr->mixer_mutex);
- for (i = 0; i < 2; i++) {
- if (chip->analog_playback_active[i] !=
- ucontrol->value.integer.value[i]) {
- chip->analog_playback_active[i] =
- !!ucontrol->value.integer.value[i];
- changed = 1;
- }
- }
- if (changed) /* update playback levels */
- mixart_update_analog_audio_level(chip, 0);
- mutex_unlock(&chip->mgr->mixer_mutex);
- return changed;
-}
-
-static struct snd_kcontrol_new mixart_control_output_switch = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = mixart_sw_info, /* shared */
- .get = mixart_audio_sw_get,
- .put = mixart_audio_sw_put
-};
-
-static u32 mixart_digital_level[256] = {
- 0x00000000, /* [000] = 0.00e+000 = mute if <= -109.5dB */
- 0x366e1c7a, /* [001] = 3.55e-006 = pow(10.0, 0.05 * -109.0dB) */
- 0x367c3860, /* [002] = 3.76e-006 = pow(10.0, 0.05 * -108.5dB) */
- 0x36859525, /* [003] = 3.98e-006 = pow(10.0, 0.05 * -108.0dB) */
- 0x368d7f74, /* [004] = 4.22e-006 = pow(10.0, 0.05 * -107.5dB) */
- 0x3695e1d4, /* [005] = 4.47e-006 = pow(10.0, 0.05 * -107.0dB) */
- 0x369ec362, /* [006] = 4.73e-006 = pow(10.0, 0.05 * -106.5dB) */
- 0x36a82ba8, /* [007] = 5.01e-006 = pow(10.0, 0.05 * -106.0dB) */
- 0x36b222a0, /* [008] = 5.31e-006 = pow(10.0, 0.05 * -105.5dB) */
- 0x36bcb0c1, /* [009] = 5.62e-006 = pow(10.0, 0.05 * -105.0dB) */
- 0x36c7defd, /* [010] = 5.96e-006 = pow(10.0, 0.05 * -104.5dB) */
- 0x36d3b6d3, /* [011] = 6.31e-006 = pow(10.0, 0.05 * -104.0dB) */
- 0x36e0424e, /* [012] = 6.68e-006 = pow(10.0, 0.05 * -103.5dB) */
- 0x36ed8c14, /* [013] = 7.08e-006 = pow(10.0, 0.05 * -103.0dB) */
- 0x36fb9f6c, /* [014] = 7.50e-006 = pow(10.0, 0.05 * -102.5dB) */
- 0x37054423, /* [015] = 7.94e-006 = pow(10.0, 0.05 * -102.0dB) */
- 0x370d29a5, /* [016] = 8.41e-006 = pow(10.0, 0.05 * -101.5dB) */
- 0x371586f0, /* [017] = 8.91e-006 = pow(10.0, 0.05 * -101.0dB) */
- 0x371e631b, /* [018] = 9.44e-006 = pow(10.0, 0.05 * -100.5dB) */
- 0x3727c5ac, /* [019] = 1.00e-005 = pow(10.0, 0.05 * -100.0dB) */
- 0x3731b69a, /* [020] = 1.06e-005 = pow(10.0, 0.05 * -99.5dB) */
- 0x373c3e53, /* [021] = 1.12e-005 = pow(10.0, 0.05 * -99.0dB) */
- 0x374765c8, /* [022] = 1.19e-005 = pow(10.0, 0.05 * -98.5dB) */
- 0x3753366f, /* [023] = 1.26e-005 = pow(10.0, 0.05 * -98.0dB) */
- 0x375fba4f, /* [024] = 1.33e-005 = pow(10.0, 0.05 * -97.5dB) */
- 0x376cfc07, /* [025] = 1.41e-005 = pow(10.0, 0.05 * -97.0dB) */
- 0x377b06d5, /* [026] = 1.50e-005 = pow(10.0, 0.05 * -96.5dB) */
- 0x3784f352, /* [027] = 1.58e-005 = pow(10.0, 0.05 * -96.0dB) */
- 0x378cd40b, /* [028] = 1.68e-005 = pow(10.0, 0.05 * -95.5dB) */
- 0x37952c42, /* [029] = 1.78e-005 = pow(10.0, 0.05 * -95.0dB) */
- 0x379e030e, /* [030] = 1.88e-005 = pow(10.0, 0.05 * -94.5dB) */
- 0x37a75fef, /* [031] = 2.00e-005 = pow(10.0, 0.05 * -94.0dB) */
- 0x37b14ad5, /* [032] = 2.11e-005 = pow(10.0, 0.05 * -93.5dB) */
- 0x37bbcc2c, /* [033] = 2.24e-005 = pow(10.0, 0.05 * -93.0dB) */
- 0x37c6ecdd, /* [034] = 2.37e-005 = pow(10.0, 0.05 * -92.5dB) */
- 0x37d2b65a, /* [035] = 2.51e-005 = pow(10.0, 0.05 * -92.0dB) */
- 0x37df32a3, /* [036] = 2.66e-005 = pow(10.0, 0.05 * -91.5dB) */
- 0x37ec6c50, /* [037] = 2.82e-005 = pow(10.0, 0.05 * -91.0dB) */
- 0x37fa6e9b, /* [038] = 2.99e-005 = pow(10.0, 0.05 * -90.5dB) */
- 0x3804a2b3, /* [039] = 3.16e-005 = pow(10.0, 0.05 * -90.0dB) */
- 0x380c7ea4, /* [040] = 3.35e-005 = pow(10.0, 0.05 * -89.5dB) */
- 0x3814d1cc, /* [041] = 3.55e-005 = pow(10.0, 0.05 * -89.0dB) */
- 0x381da33c, /* [042] = 3.76e-005 = pow(10.0, 0.05 * -88.5dB) */
- 0x3826fa6f, /* [043] = 3.98e-005 = pow(10.0, 0.05 * -88.0dB) */
- 0x3830df51, /* [044] = 4.22e-005 = pow(10.0, 0.05 * -87.5dB) */
- 0x383b5a49, /* [045] = 4.47e-005 = pow(10.0, 0.05 * -87.0dB) */
- 0x3846743b, /* [046] = 4.73e-005 = pow(10.0, 0.05 * -86.5dB) */
- 0x38523692, /* [047] = 5.01e-005 = pow(10.0, 0.05 * -86.0dB) */
- 0x385eab48, /* [048] = 5.31e-005 = pow(10.0, 0.05 * -85.5dB) */
- 0x386bdcf1, /* [049] = 5.62e-005 = pow(10.0, 0.05 * -85.0dB) */
- 0x3879d6bc, /* [050] = 5.96e-005 = pow(10.0, 0.05 * -84.5dB) */
- 0x38845244, /* [051] = 6.31e-005 = pow(10.0, 0.05 * -84.0dB) */
- 0x388c2971, /* [052] = 6.68e-005 = pow(10.0, 0.05 * -83.5dB) */
- 0x3894778d, /* [053] = 7.08e-005 = pow(10.0, 0.05 * -83.0dB) */
- 0x389d43a4, /* [054] = 7.50e-005 = pow(10.0, 0.05 * -82.5dB) */
- 0x38a6952c, /* [055] = 7.94e-005 = pow(10.0, 0.05 * -82.0dB) */
- 0x38b0740f, /* [056] = 8.41e-005 = pow(10.0, 0.05 * -81.5dB) */
- 0x38bae8ac, /* [057] = 8.91e-005 = pow(10.0, 0.05 * -81.0dB) */
- 0x38c5fbe2, /* [058] = 9.44e-005 = pow(10.0, 0.05 * -80.5dB) */
- 0x38d1b717, /* [059] = 1.00e-004 = pow(10.0, 0.05 * -80.0dB) */
- 0x38de2440, /* [060] = 1.06e-004 = pow(10.0, 0.05 * -79.5dB) */
- 0x38eb4de8, /* [061] = 1.12e-004 = pow(10.0, 0.05 * -79.0dB) */
- 0x38f93f3a, /* [062] = 1.19e-004 = pow(10.0, 0.05 * -78.5dB) */
- 0x39040206, /* [063] = 1.26e-004 = pow(10.0, 0.05 * -78.0dB) */
- 0x390bd472, /* [064] = 1.33e-004 = pow(10.0, 0.05 * -77.5dB) */
- 0x39141d84, /* [065] = 1.41e-004 = pow(10.0, 0.05 * -77.0dB) */
- 0x391ce445, /* [066] = 1.50e-004 = pow(10.0, 0.05 * -76.5dB) */
- 0x39263027, /* [067] = 1.58e-004 = pow(10.0, 0.05 * -76.0dB) */
- 0x3930090d, /* [068] = 1.68e-004 = pow(10.0, 0.05 * -75.5dB) */
- 0x393a7753, /* [069] = 1.78e-004 = pow(10.0, 0.05 * -75.0dB) */
- 0x394583d2, /* [070] = 1.88e-004 = pow(10.0, 0.05 * -74.5dB) */
- 0x395137ea, /* [071] = 2.00e-004 = pow(10.0, 0.05 * -74.0dB) */
- 0x395d9d8a, /* [072] = 2.11e-004 = pow(10.0, 0.05 * -73.5dB) */
- 0x396abf37, /* [073] = 2.24e-004 = pow(10.0, 0.05 * -73.0dB) */
- 0x3978a814, /* [074] = 2.37e-004 = pow(10.0, 0.05 * -72.5dB) */
- 0x3983b1f8, /* [075] = 2.51e-004 = pow(10.0, 0.05 * -72.0dB) */
- 0x398b7fa6, /* [076] = 2.66e-004 = pow(10.0, 0.05 * -71.5dB) */
- 0x3993c3b2, /* [077] = 2.82e-004 = pow(10.0, 0.05 * -71.0dB) */
- 0x399c8521, /* [078] = 2.99e-004 = pow(10.0, 0.05 * -70.5dB) */
- 0x39a5cb5f, /* [079] = 3.16e-004 = pow(10.0, 0.05 * -70.0dB) */
- 0x39af9e4d, /* [080] = 3.35e-004 = pow(10.0, 0.05 * -69.5dB) */
- 0x39ba063f, /* [081] = 3.55e-004 = pow(10.0, 0.05 * -69.0dB) */
- 0x39c50c0b, /* [082] = 3.76e-004 = pow(10.0, 0.05 * -68.5dB) */
- 0x39d0b90a, /* [083] = 3.98e-004 = pow(10.0, 0.05 * -68.0dB) */
- 0x39dd1726, /* [084] = 4.22e-004 = pow(10.0, 0.05 * -67.5dB) */
- 0x39ea30db, /* [085] = 4.47e-004 = pow(10.0, 0.05 * -67.0dB) */
- 0x39f81149, /* [086] = 4.73e-004 = pow(10.0, 0.05 * -66.5dB) */
- 0x3a03621b, /* [087] = 5.01e-004 = pow(10.0, 0.05 * -66.0dB) */
- 0x3a0b2b0d, /* [088] = 5.31e-004 = pow(10.0, 0.05 * -65.5dB) */
- 0x3a136a16, /* [089] = 5.62e-004 = pow(10.0, 0.05 * -65.0dB) */
- 0x3a1c2636, /* [090] = 5.96e-004 = pow(10.0, 0.05 * -64.5dB) */
- 0x3a2566d5, /* [091] = 6.31e-004 = pow(10.0, 0.05 * -64.0dB) */
- 0x3a2f33cd, /* [092] = 6.68e-004 = pow(10.0, 0.05 * -63.5dB) */
- 0x3a399570, /* [093] = 7.08e-004 = pow(10.0, 0.05 * -63.0dB) */
- 0x3a44948c, /* [094] = 7.50e-004 = pow(10.0, 0.05 * -62.5dB) */
- 0x3a503a77, /* [095] = 7.94e-004 = pow(10.0, 0.05 * -62.0dB) */
- 0x3a5c9112, /* [096] = 8.41e-004 = pow(10.0, 0.05 * -61.5dB) */
- 0x3a69a2d7, /* [097] = 8.91e-004 = pow(10.0, 0.05 * -61.0dB) */
- 0x3a777ada, /* [098] = 9.44e-004 = pow(10.0, 0.05 * -60.5dB) */
- 0x3a83126f, /* [099] = 1.00e-003 = pow(10.0, 0.05 * -60.0dB) */
- 0x3a8ad6a8, /* [100] = 1.06e-003 = pow(10.0, 0.05 * -59.5dB) */
- 0x3a9310b1, /* [101] = 1.12e-003 = pow(10.0, 0.05 * -59.0dB) */
- 0x3a9bc784, /* [102] = 1.19e-003 = pow(10.0, 0.05 * -58.5dB) */
- 0x3aa50287, /* [103] = 1.26e-003 = pow(10.0, 0.05 * -58.0dB) */
- 0x3aaec98e, /* [104] = 1.33e-003 = pow(10.0, 0.05 * -57.5dB) */
- 0x3ab924e5, /* [105] = 1.41e-003 = pow(10.0, 0.05 * -57.0dB) */
- 0x3ac41d56, /* [106] = 1.50e-003 = pow(10.0, 0.05 * -56.5dB) */
- 0x3acfbc31, /* [107] = 1.58e-003 = pow(10.0, 0.05 * -56.0dB) */
- 0x3adc0b51, /* [108] = 1.68e-003 = pow(10.0, 0.05 * -55.5dB) */
- 0x3ae91528, /* [109] = 1.78e-003 = pow(10.0, 0.05 * -55.0dB) */
- 0x3af6e4c6, /* [110] = 1.88e-003 = pow(10.0, 0.05 * -54.5dB) */
- 0x3b02c2f2, /* [111] = 2.00e-003 = pow(10.0, 0.05 * -54.0dB) */
- 0x3b0a8276, /* [112] = 2.11e-003 = pow(10.0, 0.05 * -53.5dB) */
- 0x3b12b782, /* [113] = 2.24e-003 = pow(10.0, 0.05 * -53.0dB) */
- 0x3b1b690d, /* [114] = 2.37e-003 = pow(10.0, 0.05 * -52.5dB) */
- 0x3b249e76, /* [115] = 2.51e-003 = pow(10.0, 0.05 * -52.0dB) */
- 0x3b2e5f8f, /* [116] = 2.66e-003 = pow(10.0, 0.05 * -51.5dB) */
- 0x3b38b49f, /* [117] = 2.82e-003 = pow(10.0, 0.05 * -51.0dB) */
- 0x3b43a669, /* [118] = 2.99e-003 = pow(10.0, 0.05 * -50.5dB) */
- 0x3b4f3e37, /* [119] = 3.16e-003 = pow(10.0, 0.05 * -50.0dB) */
- 0x3b5b85e0, /* [120] = 3.35e-003 = pow(10.0, 0.05 * -49.5dB) */
- 0x3b6887cf, /* [121] = 3.55e-003 = pow(10.0, 0.05 * -49.0dB) */
- 0x3b764f0e, /* [122] = 3.76e-003 = pow(10.0, 0.05 * -48.5dB) */
- 0x3b8273a6, /* [123] = 3.98e-003 = pow(10.0, 0.05 * -48.0dB) */
- 0x3b8a2e77, /* [124] = 4.22e-003 = pow(10.0, 0.05 * -47.5dB) */
- 0x3b925e89, /* [125] = 4.47e-003 = pow(10.0, 0.05 * -47.0dB) */
- 0x3b9b0ace, /* [126] = 4.73e-003 = pow(10.0, 0.05 * -46.5dB) */
- 0x3ba43aa2, /* [127] = 5.01e-003 = pow(10.0, 0.05 * -46.0dB) */
- 0x3badf5d1, /* [128] = 5.31e-003 = pow(10.0, 0.05 * -45.5dB) */
- 0x3bb8449c, /* [129] = 5.62e-003 = pow(10.0, 0.05 * -45.0dB) */
- 0x3bc32fc3, /* [130] = 5.96e-003 = pow(10.0, 0.05 * -44.5dB) */
- 0x3bcec08a, /* [131] = 6.31e-003 = pow(10.0, 0.05 * -44.0dB) */
- 0x3bdb00c0, /* [132] = 6.68e-003 = pow(10.0, 0.05 * -43.5dB) */
- 0x3be7facc, /* [133] = 7.08e-003 = pow(10.0, 0.05 * -43.0dB) */
- 0x3bf5b9b0, /* [134] = 7.50e-003 = pow(10.0, 0.05 * -42.5dB) */
- 0x3c02248a, /* [135] = 7.94e-003 = pow(10.0, 0.05 * -42.0dB) */
- 0x3c09daac, /* [136] = 8.41e-003 = pow(10.0, 0.05 * -41.5dB) */
- 0x3c1205c6, /* [137] = 8.91e-003 = pow(10.0, 0.05 * -41.0dB) */
- 0x3c1aacc8, /* [138] = 9.44e-003 = pow(10.0, 0.05 * -40.5dB) */
- 0x3c23d70a, /* [139] = 1.00e-002 = pow(10.0, 0.05 * -40.0dB) */
- 0x3c2d8c52, /* [140] = 1.06e-002 = pow(10.0, 0.05 * -39.5dB) */
- 0x3c37d4dd, /* [141] = 1.12e-002 = pow(10.0, 0.05 * -39.0dB) */
- 0x3c42b965, /* [142] = 1.19e-002 = pow(10.0, 0.05 * -38.5dB) */
- 0x3c4e4329, /* [143] = 1.26e-002 = pow(10.0, 0.05 * -38.0dB) */
- 0x3c5a7bf1, /* [144] = 1.33e-002 = pow(10.0, 0.05 * -37.5dB) */
- 0x3c676e1e, /* [145] = 1.41e-002 = pow(10.0, 0.05 * -37.0dB) */
- 0x3c7524ac, /* [146] = 1.50e-002 = pow(10.0, 0.05 * -36.5dB) */
- 0x3c81d59f, /* [147] = 1.58e-002 = pow(10.0, 0.05 * -36.0dB) */
- 0x3c898712, /* [148] = 1.68e-002 = pow(10.0, 0.05 * -35.5dB) */
- 0x3c91ad39, /* [149] = 1.78e-002 = pow(10.0, 0.05 * -35.0dB) */
- 0x3c9a4efc, /* [150] = 1.88e-002 = pow(10.0, 0.05 * -34.5dB) */
- 0x3ca373af, /* [151] = 2.00e-002 = pow(10.0, 0.05 * -34.0dB) */
- 0x3cad2314, /* [152] = 2.11e-002 = pow(10.0, 0.05 * -33.5dB) */
- 0x3cb76563, /* [153] = 2.24e-002 = pow(10.0, 0.05 * -33.0dB) */
- 0x3cc24350, /* [154] = 2.37e-002 = pow(10.0, 0.05 * -32.5dB) */
- 0x3ccdc614, /* [155] = 2.51e-002 = pow(10.0, 0.05 * -32.0dB) */
- 0x3cd9f773, /* [156] = 2.66e-002 = pow(10.0, 0.05 * -31.5dB) */
- 0x3ce6e1c6, /* [157] = 2.82e-002 = pow(10.0, 0.05 * -31.0dB) */
- 0x3cf49003, /* [158] = 2.99e-002 = pow(10.0, 0.05 * -30.5dB) */
- 0x3d0186e2, /* [159] = 3.16e-002 = pow(10.0, 0.05 * -30.0dB) */
- 0x3d0933ac, /* [160] = 3.35e-002 = pow(10.0, 0.05 * -29.5dB) */
- 0x3d1154e1, /* [161] = 3.55e-002 = pow(10.0, 0.05 * -29.0dB) */
- 0x3d19f169, /* [162] = 3.76e-002 = pow(10.0, 0.05 * -28.5dB) */
- 0x3d231090, /* [163] = 3.98e-002 = pow(10.0, 0.05 * -28.0dB) */
- 0x3d2cba15, /* [164] = 4.22e-002 = pow(10.0, 0.05 * -27.5dB) */
- 0x3d36f62b, /* [165] = 4.47e-002 = pow(10.0, 0.05 * -27.0dB) */
- 0x3d41cd81, /* [166] = 4.73e-002 = pow(10.0, 0.05 * -26.5dB) */
- 0x3d4d494a, /* [167] = 5.01e-002 = pow(10.0, 0.05 * -26.0dB) */
- 0x3d597345, /* [168] = 5.31e-002 = pow(10.0, 0.05 * -25.5dB) */
- 0x3d6655c3, /* [169] = 5.62e-002 = pow(10.0, 0.05 * -25.0dB) */
- 0x3d73fbb4, /* [170] = 5.96e-002 = pow(10.0, 0.05 * -24.5dB) */
- 0x3d813856, /* [171] = 6.31e-002 = pow(10.0, 0.05 * -24.0dB) */
- 0x3d88e078, /* [172] = 6.68e-002 = pow(10.0, 0.05 * -23.5dB) */
- 0x3d90fcbf, /* [173] = 7.08e-002 = pow(10.0, 0.05 * -23.0dB) */
- 0x3d99940e, /* [174] = 7.50e-002 = pow(10.0, 0.05 * -22.5dB) */
- 0x3da2adad, /* [175] = 7.94e-002 = pow(10.0, 0.05 * -22.0dB) */
- 0x3dac5156, /* [176] = 8.41e-002 = pow(10.0, 0.05 * -21.5dB) */
- 0x3db68738, /* [177] = 8.91e-002 = pow(10.0, 0.05 * -21.0dB) */
- 0x3dc157fb, /* [178] = 9.44e-002 = pow(10.0, 0.05 * -20.5dB) */
- 0x3dcccccd, /* [179] = 1.00e-001 = pow(10.0, 0.05 * -20.0dB) */
- 0x3dd8ef67, /* [180] = 1.06e-001 = pow(10.0, 0.05 * -19.5dB) */
- 0x3de5ca15, /* [181] = 1.12e-001 = pow(10.0, 0.05 * -19.0dB) */
- 0x3df367bf, /* [182] = 1.19e-001 = pow(10.0, 0.05 * -18.5dB) */
- 0x3e00e9f9, /* [183] = 1.26e-001 = pow(10.0, 0.05 * -18.0dB) */
- 0x3e088d77, /* [184] = 1.33e-001 = pow(10.0, 0.05 * -17.5dB) */
- 0x3e10a4d3, /* [185] = 1.41e-001 = pow(10.0, 0.05 * -17.0dB) */
- 0x3e1936ec, /* [186] = 1.50e-001 = pow(10.0, 0.05 * -16.5dB) */
- 0x3e224b06, /* [187] = 1.58e-001 = pow(10.0, 0.05 * -16.0dB) */
- 0x3e2be8d7, /* [188] = 1.68e-001 = pow(10.0, 0.05 * -15.5dB) */
- 0x3e361887, /* [189] = 1.78e-001 = pow(10.0, 0.05 * -15.0dB) */
- 0x3e40e2bb, /* [190] = 1.88e-001 = pow(10.0, 0.05 * -14.5dB) */
- 0x3e4c509b, /* [191] = 2.00e-001 = pow(10.0, 0.05 * -14.0dB) */
- 0x3e586bd9, /* [192] = 2.11e-001 = pow(10.0, 0.05 * -13.5dB) */
- 0x3e653ebb, /* [193] = 2.24e-001 = pow(10.0, 0.05 * -13.0dB) */
- 0x3e72d424, /* [194] = 2.37e-001 = pow(10.0, 0.05 * -12.5dB) */
- 0x3e809bcc, /* [195] = 2.51e-001 = pow(10.0, 0.05 * -12.0dB) */
- 0x3e883aa8, /* [196] = 2.66e-001 = pow(10.0, 0.05 * -11.5dB) */
- 0x3e904d1c, /* [197] = 2.82e-001 = pow(10.0, 0.05 * -11.0dB) */
- 0x3e98da02, /* [198] = 2.99e-001 = pow(10.0, 0.05 * -10.5dB) */
- 0x3ea1e89b, /* [199] = 3.16e-001 = pow(10.0, 0.05 * -10.0dB) */
- 0x3eab8097, /* [200] = 3.35e-001 = pow(10.0, 0.05 * -9.5dB) */
- 0x3eb5aa1a, /* [201] = 3.55e-001 = pow(10.0, 0.05 * -9.0dB) */
- 0x3ec06dc3, /* [202] = 3.76e-001 = pow(10.0, 0.05 * -8.5dB) */
- 0x3ecbd4b4, /* [203] = 3.98e-001 = pow(10.0, 0.05 * -8.0dB) */
- 0x3ed7e89b, /* [204] = 4.22e-001 = pow(10.0, 0.05 * -7.5dB) */
- 0x3ee4b3b6, /* [205] = 4.47e-001 = pow(10.0, 0.05 * -7.0dB) */
- 0x3ef240e2, /* [206] = 4.73e-001 = pow(10.0, 0.05 * -6.5dB) */
- 0x3f004dce, /* [207] = 5.01e-001 = pow(10.0, 0.05 * -6.0dB) */
- 0x3f07e80b, /* [208] = 5.31e-001 = pow(10.0, 0.05 * -5.5dB) */
- 0x3f0ff59a, /* [209] = 5.62e-001 = pow(10.0, 0.05 * -5.0dB) */
- 0x3f187d50, /* [210] = 5.96e-001 = pow(10.0, 0.05 * -4.5dB) */
- 0x3f21866c, /* [211] = 6.31e-001 = pow(10.0, 0.05 * -4.0dB) */
- 0x3f2b1896, /* [212] = 6.68e-001 = pow(10.0, 0.05 * -3.5dB) */
- 0x3f353bef, /* [213] = 7.08e-001 = pow(10.0, 0.05 * -3.0dB) */
- 0x3f3ff911, /* [214] = 7.50e-001 = pow(10.0, 0.05 * -2.5dB) */
- 0x3f4b5918, /* [215] = 7.94e-001 = pow(10.0, 0.05 * -2.0dB) */
- 0x3f5765ac, /* [216] = 8.41e-001 = pow(10.0, 0.05 * -1.5dB) */
- 0x3f642905, /* [217] = 8.91e-001 = pow(10.0, 0.05 * -1.0dB) */
- 0x3f71adf9, /* [218] = 9.44e-001 = pow(10.0, 0.05 * -0.5dB) */
- 0x3f800000, /* [219] = 1.00e+000 = pow(10.0, 0.05 * 0.0dB) */
- 0x3f8795a0, /* [220] = 1.06e+000 = pow(10.0, 0.05 * 0.5dB) */
- 0x3f8f9e4d, /* [221] = 1.12e+000 = pow(10.0, 0.05 * 1.0dB) */
- 0x3f9820d7, /* [222] = 1.19e+000 = pow(10.0, 0.05 * 1.5dB) */
- 0x3fa12478, /* [223] = 1.26e+000 = pow(10.0, 0.05 * 2.0dB) */
- 0x3faab0d5, /* [224] = 1.33e+000 = pow(10.0, 0.05 * 2.5dB) */
- 0x3fb4ce08, /* [225] = 1.41e+000 = pow(10.0, 0.05 * 3.0dB) */
- 0x3fbf84a6, /* [226] = 1.50e+000 = pow(10.0, 0.05 * 3.5dB) */
- 0x3fcaddc8, /* [227] = 1.58e+000 = pow(10.0, 0.05 * 4.0dB) */
- 0x3fd6e30d, /* [228] = 1.68e+000 = pow(10.0, 0.05 * 4.5dB) */
- 0x3fe39ea9, /* [229] = 1.78e+000 = pow(10.0, 0.05 * 5.0dB) */
- 0x3ff11b6a, /* [230] = 1.88e+000 = pow(10.0, 0.05 * 5.5dB) */
- 0x3fff64c1, /* [231] = 2.00e+000 = pow(10.0, 0.05 * 6.0dB) */
- 0x40074368, /* [232] = 2.11e+000 = pow(10.0, 0.05 * 6.5dB) */
- 0x400f4735, /* [233] = 2.24e+000 = pow(10.0, 0.05 * 7.0dB) */
- 0x4017c496, /* [234] = 2.37e+000 = pow(10.0, 0.05 * 7.5dB) */
- 0x4020c2bf, /* [235] = 2.51e+000 = pow(10.0, 0.05 * 8.0dB) */
- 0x402a4952, /* [236] = 2.66e+000 = pow(10.0, 0.05 * 8.5dB) */
- 0x40346063, /* [237] = 2.82e+000 = pow(10.0, 0.05 * 9.0dB) */
- 0x403f1082, /* [238] = 2.99e+000 = pow(10.0, 0.05 * 9.5dB) */
- 0x404a62c2, /* [239] = 3.16e+000 = pow(10.0, 0.05 * 10.0dB) */
- 0x405660bd, /* [240] = 3.35e+000 = pow(10.0, 0.05 * 10.5dB) */
- 0x406314a0, /* [241] = 3.55e+000 = pow(10.0, 0.05 * 11.0dB) */
- 0x40708933, /* [242] = 3.76e+000 = pow(10.0, 0.05 * 11.5dB) */
- 0x407ec9e1, /* [243] = 3.98e+000 = pow(10.0, 0.05 * 12.0dB) */
- 0x4086f161, /* [244] = 4.22e+000 = pow(10.0, 0.05 * 12.5dB) */
- 0x408ef052, /* [245] = 4.47e+000 = pow(10.0, 0.05 * 13.0dB) */
- 0x4097688d, /* [246] = 4.73e+000 = pow(10.0, 0.05 * 13.5dB) */
- 0x40a06142, /* [247] = 5.01e+000 = pow(10.0, 0.05 * 14.0dB) */
- 0x40a9e20e, /* [248] = 5.31e+000 = pow(10.0, 0.05 * 14.5dB) */
- 0x40b3f300, /* [249] = 5.62e+000 = pow(10.0, 0.05 * 15.0dB) */
- 0x40be9ca5, /* [250] = 5.96e+000 = pow(10.0, 0.05 * 15.5dB) */
- 0x40c9e807, /* [251] = 6.31e+000 = pow(10.0, 0.05 * 16.0dB) */
- 0x40d5debc, /* [252] = 6.68e+000 = pow(10.0, 0.05 * 16.5dB) */
- 0x40e28aeb, /* [253] = 7.08e+000 = pow(10.0, 0.05 * 17.0dB) */
- 0x40eff755, /* [254] = 7.50e+000 = pow(10.0, 0.05 * 17.5dB) */
- 0x40fe2f5e, /* [255] = 7.94e+000 = pow(10.0, 0.05 * 18.0dB) */
-};
-
-#define MIXART_DIGITAL_LEVEL_MIN 0 /* -109.5 dB */
-#define MIXART_DIGITAL_LEVEL_MAX 255 /* 18.0 dB */
-#define MIXART_DIGITAL_ZERO_LEVEL 219 /* 0.0 dB */
-
-
-int mixart_update_playback_stream_level(struct snd_mixart* chip, int is_aes, int idx)
-{
- int err, i;
- int volume[2];
- struct mixart_msg request;
- struct mixart_set_out_stream_level_req set_level;
- u32 status;
- struct mixart_pipe *pipe;
-
- memset(&set_level, 0, sizeof(set_level));
- set_level.nb_of_stream = 1;
- set_level.stream_level.desc.stream_idx = idx;
-
- if(is_aes) {
- pipe = &chip->pipe_out_dig; /* AES playback */
- idx += MIXART_PLAYBACK_STREAMS;
- } else {
- pipe = &chip->pipe_out_ana; /* analog playback */
- }
-
- /* only when pipe exists ! */
- if(pipe->status == PIPE_UNDEFINED)
- return 0;
-
- set_level.stream_level.desc.uid_pipe = pipe->group_uid;
-
- for(i=0; i<2; i++) {
- if(chip->digital_playback_active[idx][i])
- volume[i] = chip->digital_playback_volume[idx][i];
- else
- volume[i] = MIXART_DIGITAL_LEVEL_MIN;
- }
-
- set_level.stream_level.out_level.valid_mask1 = MIXART_OUT_STREAM_SET_LEVEL_LEFT_AUDIO1 | MIXART_OUT_STREAM_SET_LEVEL_RIGHT_AUDIO2;
- set_level.stream_level.out_level.left_to_out1_level = mixart_digital_level[volume[0]];
- set_level.stream_level.out_level.right_to_out2_level = mixart_digital_level[volume[1]];
-
- request.message_id = MSG_STREAM_SET_OUT_STREAM_LEVEL;
- request.uid = (struct mixart_uid){0,0};
- request.data = &set_level;
- request.size = sizeof(set_level);
-
- err = snd_mixart_send_msg(chip->mgr, &request, sizeof(status), &status);
- if((err<0) || status) {
- snd_printk(KERN_DEBUG "error MSG_STREAM_SET_OUT_STREAM_LEVEL card(%d) status(%x)\n", chip->chip_idx, status);
- return -EINVAL;
- }
- return 0;
-}
-
-int mixart_update_capture_stream_level(struct snd_mixart* chip, int is_aes)
-{
- int err, i, idx;
- struct mixart_pipe *pipe;
- struct mixart_msg request;
- struct mixart_set_in_audio_level_req set_level;
- u32 status;
-
- if(is_aes) {
- idx = 1;
- pipe = &chip->pipe_in_dig;
- } else {
- idx = 0;
- pipe = &chip->pipe_in_ana;
- }
-
- /* only when pipe exists ! */
- if(pipe->status == PIPE_UNDEFINED)
- return 0;
-
- memset(&set_level, 0, sizeof(set_level));
- set_level.audio_count = 2;
- set_level.level[0].connector = pipe->uid_left_connector;
- set_level.level[1].connector = pipe->uid_right_connector;
-
- for(i=0; i<2; i++) {
- set_level.level[i].valid_mask1 = MIXART_AUDIO_LEVEL_DIGITAL_MASK;
- set_level.level[i].digital_level = mixart_digital_level[chip->digital_capture_volume[idx][i]];
- }
-
- request.message_id = MSG_STREAM_SET_IN_AUDIO_LEVEL;
- request.uid = (struct mixart_uid){0,0};
- request.data = &set_level;
- request.size = sizeof(set_level);
-
- err = snd_mixart_send_msg(chip->mgr, &request, sizeof(status), &status);
- if((err<0) || status) {
- snd_printk(KERN_DEBUG "error MSG_STREAM_SET_IN_AUDIO_LEVEL card(%d) status(%x)\n", chip->chip_idx, status);
- return -EINVAL;
- }
- return 0;
-}
-
-
-/* shared */
-static int mixart_digital_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = MIXART_DIGITAL_LEVEL_MIN; /* -109.5 dB */
- uinfo->value.integer.max = MIXART_DIGITAL_LEVEL_MAX; /* 18.0 dB */
- return 0;
-}
-
-#define MIXART_VOL_REC_MASK 1
-#define MIXART_VOL_AES_MASK 2
-
-static int mixart_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
- int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
- int *stored_volume;
- int is_capture = kcontrol->private_value & MIXART_VOL_REC_MASK;
- int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK;
- mutex_lock(&chip->mgr->mixer_mutex);
- if(is_capture) {
- if(is_aes) stored_volume = chip->digital_capture_volume[1]; /* AES capture */
- else stored_volume = chip->digital_capture_volume[0]; /* analog capture */
- } else {
- snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
- if(is_aes) stored_volume = chip->digital_playback_volume[MIXART_PLAYBACK_STREAMS + idx]; /* AES playback */
- else stored_volume = chip->digital_playback_volume[idx]; /* analog playback */
- }
- ucontrol->value.integer.value[0] = stored_volume[0];
- ucontrol->value.integer.value[1] = stored_volume[1];
- mutex_unlock(&chip->mgr->mixer_mutex);
- return 0;
-}
-
-static int mixart_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
- int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
- int changed = 0;
- int is_capture = kcontrol->private_value & MIXART_VOL_REC_MASK;
- int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK;
- int* stored_volume;
- int i;
- mutex_lock(&chip->mgr->mixer_mutex);
- if (is_capture) {
- if (is_aes) /* AES capture */
- stored_volume = chip->digital_capture_volume[1];
- else /* analog capture */
- stored_volume = chip->digital_capture_volume[0];
- } else {
- snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
- if (is_aes) /* AES playback */
- stored_volume = chip->digital_playback_volume[MIXART_PLAYBACK_STREAMS + idx];
- else /* analog playback */
- stored_volume = chip->digital_playback_volume[idx];
- }
- for (i = 0; i < 2; i++) {
- int vol = ucontrol->value.integer.value[i];
- if (vol < MIXART_DIGITAL_LEVEL_MIN ||
- vol > MIXART_DIGITAL_LEVEL_MAX)
- continue;
- if (stored_volume[i] != vol) {
- stored_volume[i] = vol;
- changed = 1;
- }
- }
- if (changed) {
- if (is_capture)
- mixart_update_capture_stream_level(chip, is_aes);
- else
- mixart_update_playback_stream_level(chip, is_aes, idx);
- }
- mutex_unlock(&chip->mgr->mixer_mutex);
- return changed;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_digital, -10950, 50, 0);
-
-static struct snd_kcontrol_new snd_mixart_pcm_vol =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- /* name will be filled later */
- /* count will be filled later */
- .info = mixart_digital_vol_info, /* shared */
- .get = mixart_pcm_vol_get,
- .put = mixart_pcm_vol_put,
- .tlv = { .p = db_scale_digital },
-};
-
-
-static int mixart_pcm_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
- int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
- snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
- mutex_lock(&chip->mgr->mixer_mutex);
- if(kcontrol->private_value & MIXART_VOL_AES_MASK) /* AES playback */
- idx += MIXART_PLAYBACK_STREAMS;
- ucontrol->value.integer.value[0] = chip->digital_playback_active[idx][0];
- ucontrol->value.integer.value[1] = chip->digital_playback_active[idx][1];
- mutex_unlock(&chip->mgr->mixer_mutex);
- return 0;
-}
-
-static int mixart_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK;
- int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
- int i, j;
- snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
- mutex_lock(&chip->mgr->mixer_mutex);
- j = idx;
- if (is_aes)
- j += MIXART_PLAYBACK_STREAMS;
- for (i = 0; i < 2; i++) {
- if (chip->digital_playback_active[j][i] !=
- ucontrol->value.integer.value[i]) {
- chip->digital_playback_active[j][i] =
- !!ucontrol->value.integer.value[i];
- changed = 1;
- }
- }
- if (changed)
- mixart_update_playback_stream_level(chip, is_aes, idx);
- mutex_unlock(&chip->mgr->mixer_mutex);
- return changed;
-}
-
-static struct snd_kcontrol_new mixart_control_pcm_switch = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- /* name will be filled later */
- .count = MIXART_PLAYBACK_STREAMS,
- .info = mixart_sw_info, /* shared */
- .get = mixart_pcm_sw_get,
- .put = mixart_pcm_sw_put
-};
-
-static int mixart_update_monitoring(struct snd_mixart* chip, int channel)
-{
- int err;
- struct mixart_msg request;
- struct mixart_set_out_audio_level audio_level;
- u32 resp;
-
- if(chip->pipe_out_ana.status == PIPE_UNDEFINED)
- return -EINVAL; /* no pipe defined */
-
- if(!channel) request.uid = chip->pipe_out_ana.uid_left_connector;
- else request.uid = chip->pipe_out_ana.uid_right_connector;
- request.message_id = MSG_CONNECTOR_SET_OUT_AUDIO_LEVEL;
- request.data = &audio_level;
- request.size = sizeof(audio_level);
-
- memset(&audio_level, 0, sizeof(audio_level));
- audio_level.valid_mask1 = MIXART_AUDIO_LEVEL_MONITOR_MASK | MIXART_AUDIO_LEVEL_MUTE_M1_MASK;
- audio_level.monitor_level = mixart_digital_level[chip->monitoring_volume[channel!=0]];
- audio_level.monitor_mute1 = !chip->monitoring_active[channel!=0];
-
- err = snd_mixart_send_msg(chip->mgr, &request, sizeof(resp), &resp);
- if((err<0) || resp) {
- snd_printk(KERN_DEBUG "error MSG_CONNECTOR_SET_OUT_AUDIO_LEVEL card(%d) resp(%x)\n", chip->chip_idx, resp);
- return -EINVAL;
- }
- return 0;
-}
-
-/*
- * monitoring level control
- */
-
-static int mixart_monitor_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mgr->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->monitoring_volume[0];
- ucontrol->value.integer.value[1] = chip->monitoring_volume[1];
- mutex_unlock(&chip->mgr->mixer_mutex);
- return 0;
-}
-
-static int mixart_monitor_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- int i;
- mutex_lock(&chip->mgr->mixer_mutex);
- for (i = 0; i < 2; i++) {
- if (chip->monitoring_volume[i] !=
- ucontrol->value.integer.value[i]) {
- chip->monitoring_volume[i] =
- !!ucontrol->value.integer.value[i];
- mixart_update_monitoring(chip, i);
- changed = 1;
- }
- }
- mutex_unlock(&chip->mgr->mixer_mutex);
- return changed;
-}
-
-static struct snd_kcontrol_new mixart_control_monitor_vol = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Monitoring Volume",
- .info = mixart_digital_vol_info, /* shared */
- .get = mixart_monitor_vol_get,
- .put = mixart_monitor_vol_put,
- .tlv = { .p = db_scale_digital },
-};
-
-/*
- * monitoring switch control
- */
-
-static int mixart_monitor_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mgr->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->monitoring_active[0];
- ucontrol->value.integer.value[1] = chip->monitoring_active[1];
- mutex_unlock(&chip->mgr->mixer_mutex);
- return 0;
-}
-
-static int mixart_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- int i;
- mutex_lock(&chip->mgr->mixer_mutex);
- for (i = 0; i < 2; i++) {
- if (chip->monitoring_active[i] !=
- ucontrol->value.integer.value[i]) {
- chip->monitoring_active[i] =
- !!ucontrol->value.integer.value[i];
- changed |= (1<<i); /* mask 0x01 ans 0x02 */
- }
- }
- if (changed) {
- /* allocate or release resources for monitoring */
- int allocate = chip->monitoring_active[0] ||
- chip->monitoring_active[1];
- if (allocate) {
- /* allocate the playback pipe for monitoring */
- snd_mixart_add_ref_pipe(chip, MIXART_PCM_ANALOG, 0, 1);
- /* allocate the capture pipe for monitoring */
- snd_mixart_add_ref_pipe(chip, MIXART_PCM_ANALOG, 1, 1);
- }
- if (changed & 0x01)
- mixart_update_monitoring(chip, 0);
- if (changed & 0x02)
- mixart_update_monitoring(chip, 1);
- if (!allocate) {
- /* release the capture pipe for monitoring */
- snd_mixart_kill_ref_pipe(chip->mgr,
- &chip->pipe_in_ana, 1);
- /* release the playback pipe for monitoring */
- snd_mixart_kill_ref_pipe(chip->mgr,
- &chip->pipe_out_ana, 1);
- }
- }
-
- mutex_unlock(&chip->mgr->mixer_mutex);
- return (changed != 0);
-}
-
-static struct snd_kcontrol_new mixart_control_monitor_sw = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Monitoring Switch",
- .info = mixart_sw_info, /* shared */
- .get = mixart_monitor_sw_get,
- .put = mixart_monitor_sw_put
-};
-
-
-static void mixart_reset_audio_levels(struct snd_mixart *chip)
-{
- /* analog volumes can be set even if there is no pipe */
- mixart_update_analog_audio_level(chip, 0);
- /* analog levels for capture only on the first two chips */
- if(chip->chip_idx < 2) {
- mixart_update_analog_audio_level(chip, 1);
- }
- return;
-}
-
-
-int snd_mixart_create_mixer(struct mixart_mgr *mgr)
-{
- struct snd_mixart *chip;
- int err, i;
-
- mutex_init(&mgr->mixer_mutex); /* can be in another place */
-
- for(i=0; i<mgr->num_cards; i++) {
- struct snd_kcontrol_new temp;
- chip = mgr->chip[i];
-
- /* analog output level control */
- temp = mixart_control_analog_level;
- temp.name = "Master Playback Volume";
- temp.private_value = 0; /* playback */
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- /* output mute controls */
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_output_switch, chip))) < 0)
- return err;
-
- /* analog input level control only on first two chips !*/
- if(i<2) {
- temp = mixart_control_analog_level;
- temp.name = "Master Capture Volume";
- temp.private_value = 1; /* capture */
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- }
-
- temp = snd_mixart_pcm_vol;
- temp.name = "PCM Playback Volume";
- temp.count = MIXART_PLAYBACK_STREAMS;
- temp.private_value = 0; /* playback analog */
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
-
- temp.name = "PCM Capture Volume";
- temp.count = 1;
- temp.private_value = MIXART_VOL_REC_MASK; /* capture analog */
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
-
- if(mgr->board_type == MIXART_DAUGHTER_TYPE_AES) {
- temp.name = "AES Playback Volume";
- temp.count = MIXART_PLAYBACK_STREAMS;
- temp.private_value = MIXART_VOL_AES_MASK; /* playback AES/EBU */
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
-
- temp.name = "AES Capture Volume";
- temp.count = 0;
- temp.private_value = MIXART_VOL_REC_MASK | MIXART_VOL_AES_MASK; /* capture AES/EBU */
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- }
- temp = mixart_control_pcm_switch;
- temp.name = "PCM Playback Switch";
- temp.private_value = 0; /* playback analog */
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
-
- if(mgr->board_type == MIXART_DAUGHTER_TYPE_AES) {
- temp.name = "AES Playback Switch";
- temp.private_value = MIXART_VOL_AES_MASK; /* playback AES/EBU */
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
- return err;
- }
-
- /* monitoring */
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_monitor_vol, chip))) < 0)
- return err;
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&mixart_control_monitor_sw, chip))) < 0)
- return err;
-
- /* init all mixer data and program the master volumes/switches */
- mixart_reset_audio_levels(chip);
- }
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/mixart/mixart_mixer.h b/ANDROID_3.4.5/sound/pci/mixart/mixart_mixer.h
deleted file mode 100644
index 04aa24e3..00000000
--- a/ANDROID_3.4.5/sound/pci/mixart/mixart_mixer.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Driver for Digigram miXart soundcards
- *
- * include file for mixer
- *
- * Copyright (c) 2003 by Digigram <alsa@digigram.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __SOUND_MIXART_MIXER_H
-#define __SOUND_MIXART_MIXER_H
-
-/* exported */
-int mixart_update_playback_stream_level(struct snd_mixart* chip, int is_aes, int idx);
-int mixart_update_capture_stream_level(struct snd_mixart* chip, int is_aes);
-int snd_mixart_create_mixer(struct mixart_mgr* mgr);
-
-#endif /* __SOUND_MIXART_MIXER_H */
diff --git a/ANDROID_3.4.5/sound/pci/nm256/Makefile b/ANDROID_3.4.5/sound/pci/nm256/Makefile
deleted file mode 100644
index a1bd44ff..00000000
--- a/ANDROID_3.4.5/sound/pci/nm256/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-nm256-objs := nm256.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_NM256) += snd-nm256.o
diff --git a/ANDROID_3.4.5/sound/pci/nm256/nm256.c b/ANDROID_3.4.5/sound/pci/nm256/nm256.c
deleted file mode 100644
index ade2c64b..00000000
--- a/ANDROID_3.4.5/sound/pci/nm256/nm256.c
+++ /dev/null
@@ -1,1768 +0,0 @@
-/*
- * Driver for NeoMagic 256AV and 256ZX chipsets.
- * Copyright (c) 2000 by Takashi Iwai <tiwai@suse.de>
- *
- * Based on nm256_audio.c OSS driver in linux kernel.
- * The original author of OSS nm256 driver wishes to remain anonymous,
- * so I just put my acknoledgment to him/her here.
- * The original author's web page is found at
- * http://www.uglx.org/sony.html
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-
-#define CARD_NAME "NeoMagic 256AV/ZX"
-#define DRIVER_NAME "NM256"
-
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("NeoMagic NM256AV/ZX");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{NeoMagic,NM256AV},"
- "{NeoMagic,NM256ZX}}");
-
-/*
- * some compile conditions.
- */
-
-static int index = SNDRV_DEFAULT_IDX1; /* Index */
-static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-static int playback_bufsize = 16;
-static int capture_bufsize = 16;
-static bool force_ac97; /* disabled as default */
-static int buffer_top; /* not specified */
-static bool use_cache; /* disabled */
-static bool vaio_hack; /* disabled */
-static bool reset_workaround;
-static bool reset_workaround_2;
-
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
-module_param(playback_bufsize, int, 0444);
-MODULE_PARM_DESC(playback_bufsize, "DAC frame size in kB for " CARD_NAME " soundcard.");
-module_param(capture_bufsize, int, 0444);
-MODULE_PARM_DESC(capture_bufsize, "ADC frame size in kB for " CARD_NAME " soundcard.");
-module_param(force_ac97, bool, 0444);
-MODULE_PARM_DESC(force_ac97, "Force to use AC97 codec for " CARD_NAME " soundcard.");
-module_param(buffer_top, int, 0444);
-MODULE_PARM_DESC(buffer_top, "Set the top address of audio buffer for " CARD_NAME " soundcard.");
-module_param(use_cache, bool, 0444);
-MODULE_PARM_DESC(use_cache, "Enable the cache for coefficient table access.");
-module_param(vaio_hack, bool, 0444);
-MODULE_PARM_DESC(vaio_hack, "Enable workaround for Sony VAIO notebooks.");
-module_param(reset_workaround, bool, 0444);
-MODULE_PARM_DESC(reset_workaround, "Enable AC97 RESET workaround for some laptops.");
-module_param(reset_workaround_2, bool, 0444);
-MODULE_PARM_DESC(reset_workaround_2, "Enable extended AC97 RESET workaround for some other laptops.");
-
-/* just for backward compatibility */
-static bool enable;
-module_param(enable, bool, 0444);
-
-
-
-/*
- * hw definitions
- */
-
-/* The BIOS signature. */
-#define NM_SIGNATURE 0x4e4d0000
-/* Signature mask. */
-#define NM_SIG_MASK 0xffff0000
-
-/* Size of the second memory area. */
-#define NM_PORT2_SIZE 4096
-
-/* The base offset of the mixer in the second memory area. */
-#define NM_MIXER_OFFSET 0x600
-
-/* The maximum size of a coefficient entry. */
-#define NM_MAX_PLAYBACK_COEF_SIZE 0x5000
-#define NM_MAX_RECORD_COEF_SIZE 0x1260
-
-/* The interrupt register. */
-#define NM_INT_REG 0xa04
-/* And its bits. */
-#define NM_PLAYBACK_INT 0x40
-#define NM_RECORD_INT 0x100
-#define NM_MISC_INT_1 0x4000
-#define NM_MISC_INT_2 0x1
-#define NM_ACK_INT(chip, X) snd_nm256_writew(chip, NM_INT_REG, (X) << 1)
-
-/* The AV's "mixer ready" status bit and location. */
-#define NM_MIXER_STATUS_OFFSET 0xa04
-#define NM_MIXER_READY_MASK 0x0800
-#define NM_MIXER_PRESENCE 0xa06
-#define NM_PRESENCE_MASK 0x0050
-#define NM_PRESENCE_VALUE 0x0040
-
-/*
- * For the ZX. It uses the same interrupt register, but it holds 32
- * bits instead of 16.
- */
-#define NM2_PLAYBACK_INT 0x10000
-#define NM2_RECORD_INT 0x80000
-#define NM2_MISC_INT_1 0x8
-#define NM2_MISC_INT_2 0x2
-#define NM2_ACK_INT(chip, X) snd_nm256_writel(chip, NM_INT_REG, (X))
-
-/* The ZX's "mixer ready" status bit and location. */
-#define NM2_MIXER_STATUS_OFFSET 0xa06
-#define NM2_MIXER_READY_MASK 0x0800
-
-/* The playback registers start from here. */
-#define NM_PLAYBACK_REG_OFFSET 0x0
-/* The record registers start from here. */
-#define NM_RECORD_REG_OFFSET 0x200
-
-/* The rate register is located 2 bytes from the start of the register area. */
-#define NM_RATE_REG_OFFSET 2
-
-/* Mono/stereo flag, number of bits on playback, and rate mask. */
-#define NM_RATE_STEREO 1
-#define NM_RATE_BITS_16 2
-#define NM_RATE_MASK 0xf0
-
-/* Playback enable register. */
-#define NM_PLAYBACK_ENABLE_REG (NM_PLAYBACK_REG_OFFSET + 0x1)
-#define NM_PLAYBACK_ENABLE_FLAG 1
-#define NM_PLAYBACK_ONESHOT 2
-#define NM_PLAYBACK_FREERUN 4
-
-/* Mutes the audio output. */
-#define NM_AUDIO_MUTE_REG (NM_PLAYBACK_REG_OFFSET + 0x18)
-#define NM_AUDIO_MUTE_LEFT 0x8000
-#define NM_AUDIO_MUTE_RIGHT 0x0080
-
-/* Recording enable register. */
-#define NM_RECORD_ENABLE_REG (NM_RECORD_REG_OFFSET + 0)
-#define NM_RECORD_ENABLE_FLAG 1
-#define NM_RECORD_FREERUN 2
-
-/* coefficient buffer pointer */
-#define NM_COEFF_START_OFFSET 0x1c
-#define NM_COEFF_END_OFFSET 0x20
-
-/* DMA buffer offsets */
-#define NM_RBUFFER_START (NM_RECORD_REG_OFFSET + 0x4)
-#define NM_RBUFFER_END (NM_RECORD_REG_OFFSET + 0x10)
-#define NM_RBUFFER_WMARK (NM_RECORD_REG_OFFSET + 0xc)
-#define NM_RBUFFER_CURRP (NM_RECORD_REG_OFFSET + 0x8)
-
-#define NM_PBUFFER_START (NM_PLAYBACK_REG_OFFSET + 0x4)
-#define NM_PBUFFER_END (NM_PLAYBACK_REG_OFFSET + 0x14)
-#define NM_PBUFFER_WMARK (NM_PLAYBACK_REG_OFFSET + 0xc)
-#define NM_PBUFFER_CURRP (NM_PLAYBACK_REG_OFFSET + 0x8)
-
-struct nm256_stream {
-
- struct nm256 *chip;
- struct snd_pcm_substream *substream;
- int running;
- int suspended;
-
- u32 buf; /* offset from chip->buffer */
- int bufsize; /* buffer size in bytes */
- void __iomem *bufptr; /* mapped pointer */
- unsigned long bufptr_addr; /* physical address of the mapped pointer */
-
- int dma_size; /* buffer size of the substream in bytes */
- int period_size; /* period size in bytes */
- int periods; /* # of periods */
- int shift; /* bit shifts */
- int cur_period; /* current period # */
-
-};
-
-struct nm256 {
-
- struct snd_card *card;
-
- void __iomem *cport; /* control port */
- struct resource *res_cport; /* its resource */
- unsigned long cport_addr; /* physical address */
-
- void __iomem *buffer; /* buffer */
- struct resource *res_buffer; /* its resource */
- unsigned long buffer_addr; /* buffer phyiscal address */
-
- u32 buffer_start; /* start offset from pci resource 0 */
- u32 buffer_end; /* end offset */
- u32 buffer_size; /* total buffer size */
-
- u32 all_coeff_buf; /* coefficient buffer */
- u32 coeff_buf[2]; /* coefficient buffer for each stream */
-
- unsigned int coeffs_current: 1; /* coeff. table is loaded? */
- unsigned int use_cache: 1; /* use one big coef. table */
- unsigned int reset_workaround: 1; /* Workaround for some laptops to avoid freeze */
- unsigned int reset_workaround_2: 1; /* Extended workaround for some other laptops to avoid freeze */
- unsigned int in_resume: 1;
-
- int mixer_base; /* register offset of ac97 mixer */
- int mixer_status_offset; /* offset of mixer status reg. */
- int mixer_status_mask; /* bit mask to test the mixer status */
-
- int irq;
- int irq_acks;
- irq_handler_t interrupt;
- int badintrcount; /* counter to check bogus interrupts */
- struct mutex irq_mutex;
-
- struct nm256_stream streams[2];
-
- struct snd_ac97 *ac97;
- unsigned short *ac97_regs; /* register caches, only for valid regs */
-
- struct snd_pcm *pcm;
-
- struct pci_dev *pci;
-
- spinlock_t reg_lock;
-
-};
-
-
-/*
- * include coefficient table
- */
-#include "nm256_coef.c"
-
-
-/*
- * PCI ids
- */
-static DEFINE_PCI_DEVICE_TABLE(snd_nm256_ids) = {
- {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO), 0},
- {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO), 0},
- {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO), 0},
- {0,},
-};
-
-MODULE_DEVICE_TABLE(pci, snd_nm256_ids);
-
-
-/*
- * lowlvel stuffs
- */
-
-static inline u8
-snd_nm256_readb(struct nm256 *chip, int offset)
-{
- return readb(chip->cport + offset);
-}
-
-static inline u16
-snd_nm256_readw(struct nm256 *chip, int offset)
-{
- return readw(chip->cport + offset);
-}
-
-static inline u32
-snd_nm256_readl(struct nm256 *chip, int offset)
-{
- return readl(chip->cport + offset);
-}
-
-static inline void
-snd_nm256_writeb(struct nm256 *chip, int offset, u8 val)
-{
- writeb(val, chip->cport + offset);
-}
-
-static inline void
-snd_nm256_writew(struct nm256 *chip, int offset, u16 val)
-{
- writew(val, chip->cport + offset);
-}
-
-static inline void
-snd_nm256_writel(struct nm256 *chip, int offset, u32 val)
-{
- writel(val, chip->cport + offset);
-}
-
-static inline void
-snd_nm256_write_buffer(struct nm256 *chip, void *src, int offset, int size)
-{
- offset -= chip->buffer_start;
-#ifdef CONFIG_SND_DEBUG
- if (offset < 0 || offset >= chip->buffer_size) {
- snd_printk(KERN_ERR "write_buffer invalid offset = %d size = %d\n",
- offset, size);
- return;
- }
-#endif
- memcpy_toio(chip->buffer + offset, src, size);
-}
-
-/*
- * coefficient handlers -- what a magic!
- */
-
-static u16
-snd_nm256_get_start_offset(int which)
-{
- u16 offset = 0;
- while (which-- > 0)
- offset += coefficient_sizes[which];
- return offset;
-}
-
-static void
-snd_nm256_load_one_coefficient(struct nm256 *chip, int stream, u32 port, int which)
-{
- u32 coeff_buf = chip->coeff_buf[stream];
- u16 offset = snd_nm256_get_start_offset(which);
- u16 size = coefficient_sizes[which];
-
- snd_nm256_write_buffer(chip, coefficients + offset, coeff_buf, size);
- snd_nm256_writel(chip, port, coeff_buf);
- /* ??? Record seems to behave differently than playback. */
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
- size--;
- snd_nm256_writel(chip, port + 4, coeff_buf + size);
-}
-
-static void
-snd_nm256_load_coefficient(struct nm256 *chip, int stream, int number)
-{
- /* The enable register for the specified engine. */
- u32 poffset = (stream == SNDRV_PCM_STREAM_CAPTURE ?
- NM_RECORD_ENABLE_REG : NM_PLAYBACK_ENABLE_REG);
- u32 addr = NM_COEFF_START_OFFSET;
-
- addr += (stream == SNDRV_PCM_STREAM_CAPTURE ?
- NM_RECORD_REG_OFFSET : NM_PLAYBACK_REG_OFFSET);
-
- if (snd_nm256_readb(chip, poffset) & 1) {
- snd_printd("NM256: Engine was enabled while loading coefficients!\n");
- return;
- }
-
- /* The recording engine uses coefficient values 8-15. */
- number &= 7;
- if (stream == SNDRV_PCM_STREAM_CAPTURE)
- number += 8;
-
- if (! chip->use_cache) {
- snd_nm256_load_one_coefficient(chip, stream, addr, number);
- return;
- }
- if (! chip->coeffs_current) {
- snd_nm256_write_buffer(chip, coefficients, chip->all_coeff_buf,
- NM_TOTAL_COEFF_COUNT * 4);
- chip->coeffs_current = 1;
- } else {
- u32 base = chip->all_coeff_buf;
- u32 offset = snd_nm256_get_start_offset(number);
- u32 end_offset = offset + coefficient_sizes[number];
- snd_nm256_writel(chip, addr, base + offset);
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
- end_offset--;
- snd_nm256_writel(chip, addr + 4, base + end_offset);
- }
-}
-
-
-/* The actual rates supported by the card. */
-static unsigned int samplerates[8] = {
- 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000,
-};
-static struct snd_pcm_hw_constraint_list constraints_rates = {
- .count = ARRAY_SIZE(samplerates),
- .list = samplerates,
- .mask = 0,
-};
-
-/*
- * return the index of the target rate
- */
-static int
-snd_nm256_fixed_rate(unsigned int rate)
-{
- unsigned int i;
- for (i = 0; i < ARRAY_SIZE(samplerates); i++) {
- if (rate == samplerates[i])
- return i;
- }
- snd_BUG();
- return 0;
-}
-
-/*
- * set sample rate and format
- */
-static void
-snd_nm256_set_format(struct nm256 *chip, struct nm256_stream *s,
- struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int rate_index = snd_nm256_fixed_rate(runtime->rate);
- unsigned char ratebits = (rate_index << 4) & NM_RATE_MASK;
-
- s->shift = 0;
- if (snd_pcm_format_width(runtime->format) == 16) {
- ratebits |= NM_RATE_BITS_16;
- s->shift++;
- }
- if (runtime->channels > 1) {
- ratebits |= NM_RATE_STEREO;
- s->shift++;
- }
-
- runtime->rate = samplerates[rate_index];
-
- switch (substream->stream) {
- case SNDRV_PCM_STREAM_PLAYBACK:
- snd_nm256_load_coefficient(chip, 0, rate_index); /* 0 = playback */
- snd_nm256_writeb(chip,
- NM_PLAYBACK_REG_OFFSET + NM_RATE_REG_OFFSET,
- ratebits);
- break;
- case SNDRV_PCM_STREAM_CAPTURE:
- snd_nm256_load_coefficient(chip, 1, rate_index); /* 1 = record */
- snd_nm256_writeb(chip,
- NM_RECORD_REG_OFFSET + NM_RATE_REG_OFFSET,
- ratebits);
- break;
- }
-}
-
-/* acquire interrupt */
-static int snd_nm256_acquire_irq(struct nm256 *chip)
-{
- mutex_lock(&chip->irq_mutex);
- if (chip->irq < 0) {
- if (request_irq(chip->pci->irq, chip->interrupt, IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->pci->irq);
- mutex_unlock(&chip->irq_mutex);
- return -EBUSY;
- }
- chip->irq = chip->pci->irq;
- }
- chip->irq_acks++;
- mutex_unlock(&chip->irq_mutex);
- return 0;
-}
-
-/* release interrupt */
-static void snd_nm256_release_irq(struct nm256 *chip)
-{
- mutex_lock(&chip->irq_mutex);
- if (chip->irq_acks > 0)
- chip->irq_acks--;
- if (chip->irq_acks == 0 && chip->irq >= 0) {
- free_irq(chip->irq, chip);
- chip->irq = -1;
- }
- mutex_unlock(&chip->irq_mutex);
-}
-
-/*
- * start / stop
- */
-
-/* update the watermark (current period) */
-static void snd_nm256_pcm_mark(struct nm256 *chip, struct nm256_stream *s, int reg)
-{
- s->cur_period++;
- s->cur_period %= s->periods;
- snd_nm256_writel(chip, reg, s->buf + s->cur_period * s->period_size);
-}
-
-#define snd_nm256_playback_mark(chip, s) snd_nm256_pcm_mark(chip, s, NM_PBUFFER_WMARK)
-#define snd_nm256_capture_mark(chip, s) snd_nm256_pcm_mark(chip, s, NM_RBUFFER_WMARK)
-
-static void
-snd_nm256_playback_start(struct nm256 *chip, struct nm256_stream *s,
- struct snd_pcm_substream *substream)
-{
- /* program buffer pointers */
- snd_nm256_writel(chip, NM_PBUFFER_START, s->buf);
- snd_nm256_writel(chip, NM_PBUFFER_END, s->buf + s->dma_size - (1 << s->shift));
- snd_nm256_writel(chip, NM_PBUFFER_CURRP, s->buf);
- snd_nm256_playback_mark(chip, s);
-
- /* Enable playback engine and interrupts. */
- snd_nm256_writeb(chip, NM_PLAYBACK_ENABLE_REG,
- NM_PLAYBACK_ENABLE_FLAG | NM_PLAYBACK_FREERUN);
- /* Enable both channels. */
- snd_nm256_writew(chip, NM_AUDIO_MUTE_REG, 0x0);
-}
-
-static void
-snd_nm256_capture_start(struct nm256 *chip, struct nm256_stream *s,
- struct snd_pcm_substream *substream)
-{
- /* program buffer pointers */
- snd_nm256_writel(chip, NM_RBUFFER_START, s->buf);
- snd_nm256_writel(chip, NM_RBUFFER_END, s->buf + s->dma_size);
- snd_nm256_writel(chip, NM_RBUFFER_CURRP, s->buf);
- snd_nm256_capture_mark(chip, s);
-
- /* Enable playback engine and interrupts. */
- snd_nm256_writeb(chip, NM_RECORD_ENABLE_REG,
- NM_RECORD_ENABLE_FLAG | NM_RECORD_FREERUN);
-}
-
-/* Stop the play engine. */
-static void
-snd_nm256_playback_stop(struct nm256 *chip)
-{
- /* Shut off sound from both channels. */
- snd_nm256_writew(chip, NM_AUDIO_MUTE_REG,
- NM_AUDIO_MUTE_LEFT | NM_AUDIO_MUTE_RIGHT);
- /* Disable play engine. */
- snd_nm256_writeb(chip, NM_PLAYBACK_ENABLE_REG, 0);
-}
-
-static void
-snd_nm256_capture_stop(struct nm256 *chip)
-{
- /* Disable recording engine. */
- snd_nm256_writeb(chip, NM_RECORD_ENABLE_REG, 0);
-}
-
-static int
-snd_nm256_playback_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct nm256 *chip = snd_pcm_substream_chip(substream);
- struct nm256_stream *s = substream->runtime->private_data;
- int err = 0;
-
- if (snd_BUG_ON(!s))
- return -ENXIO;
-
- spin_lock(&chip->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_RESUME:
- s->suspended = 0;
- /* fallthru */
- case SNDRV_PCM_TRIGGER_START:
- if (! s->running) {
- snd_nm256_playback_start(chip, s, substream);
- s->running = 1;
- }
- break;
- case SNDRV_PCM_TRIGGER_SUSPEND:
- s->suspended = 1;
- /* fallthru */
- case SNDRV_PCM_TRIGGER_STOP:
- if (s->running) {
- snd_nm256_playback_stop(chip);
- s->running = 0;
- }
- break;
- default:
- err = -EINVAL;
- break;
- }
- spin_unlock(&chip->reg_lock);
- return err;
-}
-
-static int
-snd_nm256_capture_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct nm256 *chip = snd_pcm_substream_chip(substream);
- struct nm256_stream *s = substream->runtime->private_data;
- int err = 0;
-
- if (snd_BUG_ON(!s))
- return -ENXIO;
-
- spin_lock(&chip->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- if (! s->running) {
- snd_nm256_capture_start(chip, s, substream);
- s->running = 1;
- }
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- if (s->running) {
- snd_nm256_capture_stop(chip);
- s->running = 0;
- }
- break;
- default:
- err = -EINVAL;
- break;
- }
- spin_unlock(&chip->reg_lock);
- return err;
-}
-
-
-/*
- * prepare playback/capture channel
- */
-static int snd_nm256_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct nm256 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct nm256_stream *s = runtime->private_data;
-
- if (snd_BUG_ON(!s))
- return -ENXIO;
- s->dma_size = frames_to_bytes(runtime, substream->runtime->buffer_size);
- s->period_size = frames_to_bytes(runtime, substream->runtime->period_size);
- s->periods = substream->runtime->periods;
- s->cur_period = 0;
-
- spin_lock_irq(&chip->reg_lock);
- s->running = 0;
- snd_nm256_set_format(chip, s, substream);
- spin_unlock_irq(&chip->reg_lock);
-
- return 0;
-}
-
-
-/*
- * get the current pointer
- */
-static snd_pcm_uframes_t
-snd_nm256_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct nm256 *chip = snd_pcm_substream_chip(substream);
- struct nm256_stream *s = substream->runtime->private_data;
- unsigned long curp;
-
- if (snd_BUG_ON(!s))
- return 0;
- curp = snd_nm256_readl(chip, NM_PBUFFER_CURRP) - (unsigned long)s->buf;
- curp %= s->dma_size;
- return bytes_to_frames(substream->runtime, curp);
-}
-
-static snd_pcm_uframes_t
-snd_nm256_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct nm256 *chip = snd_pcm_substream_chip(substream);
- struct nm256_stream *s = substream->runtime->private_data;
- unsigned long curp;
-
- if (snd_BUG_ON(!s))
- return 0;
- curp = snd_nm256_readl(chip, NM_RBUFFER_CURRP) - (unsigned long)s->buf;
- curp %= s->dma_size;
- return bytes_to_frames(substream->runtime, curp);
-}
-
-/* Remapped I/O space can be accessible as pointer on i386 */
-/* This might be changed in the future */
-#ifndef __i386__
-/*
- * silence / copy for playback
- */
-static int
-snd_nm256_playback_silence(struct snd_pcm_substream *substream,
- int channel, /* not used (interleaved data) */
- snd_pcm_uframes_t pos,
- snd_pcm_uframes_t count)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct nm256_stream *s = runtime->private_data;
- count = frames_to_bytes(runtime, count);
- pos = frames_to_bytes(runtime, pos);
- memset_io(s->bufptr + pos, 0, count);
- return 0;
-}
-
-static int
-snd_nm256_playback_copy(struct snd_pcm_substream *substream,
- int channel, /* not used (interleaved data) */
- snd_pcm_uframes_t pos,
- void __user *src,
- snd_pcm_uframes_t count)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct nm256_stream *s = runtime->private_data;
- count = frames_to_bytes(runtime, count);
- pos = frames_to_bytes(runtime, pos);
- if (copy_from_user_toio(s->bufptr + pos, src, count))
- return -EFAULT;
- return 0;
-}
-
-/*
- * copy to user
- */
-static int
-snd_nm256_capture_copy(struct snd_pcm_substream *substream,
- int channel, /* not used (interleaved data) */
- snd_pcm_uframes_t pos,
- void __user *dst,
- snd_pcm_uframes_t count)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct nm256_stream *s = runtime->private_data;
- count = frames_to_bytes(runtime, count);
- pos = frames_to_bytes(runtime, pos);
- if (copy_to_user_fromio(dst, s->bufptr + pos, count))
- return -EFAULT;
- return 0;
-}
-
-#endif /* !__i386__ */
-
-
-/*
- * update playback/capture watermarks
- */
-
-/* spinlock held! */
-static void
-snd_nm256_playback_update(struct nm256 *chip)
-{
- struct nm256_stream *s;
-
- s = &chip->streams[SNDRV_PCM_STREAM_PLAYBACK];
- if (s->running && s->substream) {
- spin_unlock(&chip->reg_lock);
- snd_pcm_period_elapsed(s->substream);
- spin_lock(&chip->reg_lock);
- snd_nm256_playback_mark(chip, s);
- }
-}
-
-/* spinlock held! */
-static void
-snd_nm256_capture_update(struct nm256 *chip)
-{
- struct nm256_stream *s;
-
- s = &chip->streams[SNDRV_PCM_STREAM_CAPTURE];
- if (s->running && s->substream) {
- spin_unlock(&chip->reg_lock);
- snd_pcm_period_elapsed(s->substream);
- spin_lock(&chip->reg_lock);
- snd_nm256_capture_mark(chip, s);
- }
-}
-
-/*
- * hardware info
- */
-static struct snd_pcm_hardware snd_nm256_playback =
-{
- .info = SNDRV_PCM_INFO_MMAP_IOMEM |SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- /*SNDRV_PCM_INFO_PAUSE |*/
- SNDRV_PCM_INFO_RESUME,
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_KNOT/*24k*/ | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .periods_min = 2,
- .periods_max = 1024,
- .buffer_bytes_max = 128 * 1024,
- .period_bytes_min = 256,
- .period_bytes_max = 128 * 1024,
-};
-
-static struct snd_pcm_hardware snd_nm256_capture =
-{
- .info = SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- /*SNDRV_PCM_INFO_PAUSE |*/
- SNDRV_PCM_INFO_RESUME,
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_KNOT/*24k*/ | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .periods_min = 2,
- .periods_max = 1024,
- .buffer_bytes_max = 128 * 1024,
- .period_bytes_min = 256,
- .period_bytes_max = 128 * 1024,
-};
-
-
-/* set dma transfer size */
-static int snd_nm256_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- /* area and addr are already set and unchanged */
- substream->runtime->dma_bytes = params_buffer_bytes(hw_params);
- return 0;
-}
-
-/*
- * open
- */
-static void snd_nm256_setup_stream(struct nm256 *chip, struct nm256_stream *s,
- struct snd_pcm_substream *substream,
- struct snd_pcm_hardware *hw_ptr)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- s->running = 0;
- runtime->hw = *hw_ptr;
- runtime->hw.buffer_bytes_max = s->bufsize;
- runtime->hw.period_bytes_max = s->bufsize / 2;
- runtime->dma_area = (void __force *) s->bufptr;
- runtime->dma_addr = s->bufptr_addr;
- runtime->dma_bytes = s->bufsize;
- runtime->private_data = s;
- s->substream = substream;
-
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &constraints_rates);
-}
-
-static int
-snd_nm256_playback_open(struct snd_pcm_substream *substream)
-{
- struct nm256 *chip = snd_pcm_substream_chip(substream);
-
- if (snd_nm256_acquire_irq(chip) < 0)
- return -EBUSY;
- snd_nm256_setup_stream(chip, &chip->streams[SNDRV_PCM_STREAM_PLAYBACK],
- substream, &snd_nm256_playback);
- return 0;
-}
-
-static int
-snd_nm256_capture_open(struct snd_pcm_substream *substream)
-{
- struct nm256 *chip = snd_pcm_substream_chip(substream);
-
- if (snd_nm256_acquire_irq(chip) < 0)
- return -EBUSY;
- snd_nm256_setup_stream(chip, &chip->streams[SNDRV_PCM_STREAM_CAPTURE],
- substream, &snd_nm256_capture);
- return 0;
-}
-
-/*
- * close - we don't have to do special..
- */
-static int
-snd_nm256_playback_close(struct snd_pcm_substream *substream)
-{
- struct nm256 *chip = snd_pcm_substream_chip(substream);
-
- snd_nm256_release_irq(chip);
- return 0;
-}
-
-
-static int
-snd_nm256_capture_close(struct snd_pcm_substream *substream)
-{
- struct nm256 *chip = snd_pcm_substream_chip(substream);
-
- snd_nm256_release_irq(chip);
- return 0;
-}
-
-/*
- * create a pcm instance
- */
-static struct snd_pcm_ops snd_nm256_playback_ops = {
- .open = snd_nm256_playback_open,
- .close = snd_nm256_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_nm256_pcm_hw_params,
- .prepare = snd_nm256_pcm_prepare,
- .trigger = snd_nm256_playback_trigger,
- .pointer = snd_nm256_playback_pointer,
-#ifndef __i386__
- .copy = snd_nm256_playback_copy,
- .silence = snd_nm256_playback_silence,
-#endif
- .mmap = snd_pcm_lib_mmap_iomem,
-};
-
-static struct snd_pcm_ops snd_nm256_capture_ops = {
- .open = snd_nm256_capture_open,
- .close = snd_nm256_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_nm256_pcm_hw_params,
- .prepare = snd_nm256_pcm_prepare,
- .trigger = snd_nm256_capture_trigger,
- .pointer = snd_nm256_capture_pointer,
-#ifndef __i386__
- .copy = snd_nm256_capture_copy,
-#endif
- .mmap = snd_pcm_lib_mmap_iomem,
-};
-
-static int __devinit
-snd_nm256_pcm(struct nm256 *chip, int device)
-{
- struct snd_pcm *pcm;
- int i, err;
-
- for (i = 0; i < 2; i++) {
- struct nm256_stream *s = &chip->streams[i];
- s->bufptr = chip->buffer + (s->buf - chip->buffer_start);
- s->bufptr_addr = chip->buffer_addr + (s->buf - chip->buffer_start);
- }
-
- err = snd_pcm_new(chip->card, chip->card->driver, device,
- 1, 1, &pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_nm256_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_nm256_capture_ops);
-
- pcm->private_data = chip;
- pcm->info_flags = 0;
- chip->pcm = pcm;
-
- return 0;
-}
-
-
-/*
- * Initialize the hardware.
- */
-static void
-snd_nm256_init_chip(struct nm256 *chip)
-{
- /* Reset everything. */
- snd_nm256_writeb(chip, 0x0, 0x11);
- snd_nm256_writew(chip, 0x214, 0);
- /* stop sounds.. */
- //snd_nm256_playback_stop(chip);
- //snd_nm256_capture_stop(chip);
-}
-
-
-static irqreturn_t
-snd_nm256_intr_check(struct nm256 *chip)
-{
- if (chip->badintrcount++ > 1000) {
- /*
- * I'm not sure if the best thing is to stop the card from
- * playing or just release the interrupt (after all, we're in
- * a bad situation, so doing fancy stuff may not be such a good
- * idea).
- *
- * I worry about the card engine continuing to play noise
- * over and over, however--that could become a very
- * obnoxious problem. And we know that when this usually
- * happens things are fairly safe, it just means the user's
- * inserted a PCMCIA card and someone's spamming us with IRQ 9s.
- */
- if (chip->streams[SNDRV_PCM_STREAM_PLAYBACK].running)
- snd_nm256_playback_stop(chip);
- if (chip->streams[SNDRV_PCM_STREAM_CAPTURE].running)
- snd_nm256_capture_stop(chip);
- chip->badintrcount = 0;
- return IRQ_HANDLED;
- }
- return IRQ_NONE;
-}
-
-/*
- * Handle a potential interrupt for the device referred to by DEV_ID.
- *
- * I don't like the cut-n-paste job here either between the two routines,
- * but there are sufficient differences between the two interrupt handlers
- * that parameterizing it isn't all that great either. (Could use a macro,
- * I suppose...yucky bleah.)
- */
-
-static irqreturn_t
-snd_nm256_interrupt(int irq, void *dev_id)
-{
- struct nm256 *chip = dev_id;
- u16 status;
- u8 cbyte;
-
- status = snd_nm256_readw(chip, NM_INT_REG);
-
- /* Not ours. */
- if (status == 0)
- return snd_nm256_intr_check(chip);
-
- chip->badintrcount = 0;
-
- /* Rather boring; check for individual interrupts and process them. */
-
- spin_lock(&chip->reg_lock);
- if (status & NM_PLAYBACK_INT) {
- status &= ~NM_PLAYBACK_INT;
- NM_ACK_INT(chip, NM_PLAYBACK_INT);
- snd_nm256_playback_update(chip);
- }
-
- if (status & NM_RECORD_INT) {
- status &= ~NM_RECORD_INT;
- NM_ACK_INT(chip, NM_RECORD_INT);
- snd_nm256_capture_update(chip);
- }
-
- if (status & NM_MISC_INT_1) {
- status &= ~NM_MISC_INT_1;
- NM_ACK_INT(chip, NM_MISC_INT_1);
- snd_printd("NM256: Got misc interrupt #1\n");
- snd_nm256_writew(chip, NM_INT_REG, 0x8000);
- cbyte = snd_nm256_readb(chip, 0x400);
- snd_nm256_writeb(chip, 0x400, cbyte | 2);
- }
-
- if (status & NM_MISC_INT_2) {
- status &= ~NM_MISC_INT_2;
- NM_ACK_INT(chip, NM_MISC_INT_2);
- snd_printd("NM256: Got misc interrupt #2\n");
- cbyte = snd_nm256_readb(chip, 0x400);
- snd_nm256_writeb(chip, 0x400, cbyte & ~2);
- }
-
- /* Unknown interrupt. */
- if (status) {
- snd_printd("NM256: Fire in the hole! Unknown status 0x%x\n",
- status);
- /* Pray. */
- NM_ACK_INT(chip, status);
- }
-
- spin_unlock(&chip->reg_lock);
- return IRQ_HANDLED;
-}
-
-/*
- * Handle a potential interrupt for the device referred to by DEV_ID.
- * This handler is for the 256ZX, and is very similar to the non-ZX
- * routine.
- */
-
-static irqreturn_t
-snd_nm256_interrupt_zx(int irq, void *dev_id)
-{
- struct nm256 *chip = dev_id;
- u32 status;
- u8 cbyte;
-
- status = snd_nm256_readl(chip, NM_INT_REG);
-
- /* Not ours. */
- if (status == 0)
- return snd_nm256_intr_check(chip);
-
- chip->badintrcount = 0;
-
- /* Rather boring; check for individual interrupts and process them. */
-
- spin_lock(&chip->reg_lock);
- if (status & NM2_PLAYBACK_INT) {
- status &= ~NM2_PLAYBACK_INT;
- NM2_ACK_INT(chip, NM2_PLAYBACK_INT);
- snd_nm256_playback_update(chip);
- }
-
- if (status & NM2_RECORD_INT) {
- status &= ~NM2_RECORD_INT;
- NM2_ACK_INT(chip, NM2_RECORD_INT);
- snd_nm256_capture_update(chip);
- }
-
- if (status & NM2_MISC_INT_1) {
- status &= ~NM2_MISC_INT_1;
- NM2_ACK_INT(chip, NM2_MISC_INT_1);
- snd_printd("NM256: Got misc interrupt #1\n");
- cbyte = snd_nm256_readb(chip, 0x400);
- snd_nm256_writeb(chip, 0x400, cbyte | 2);
- }
-
- if (status & NM2_MISC_INT_2) {
- status &= ~NM2_MISC_INT_2;
- NM2_ACK_INT(chip, NM2_MISC_INT_2);
- snd_printd("NM256: Got misc interrupt #2\n");
- cbyte = snd_nm256_readb(chip, 0x400);
- snd_nm256_writeb(chip, 0x400, cbyte & ~2);
- }
-
- /* Unknown interrupt. */
- if (status) {
- snd_printd("NM256: Fire in the hole! Unknown status 0x%x\n",
- status);
- /* Pray. */
- NM2_ACK_INT(chip, status);
- }
-
- spin_unlock(&chip->reg_lock);
- return IRQ_HANDLED;
-}
-
-/*
- * AC97 interface
- */
-
-/*
- * Waits for the mixer to become ready to be written; returns a zero value
- * if it timed out.
- */
-static int
-snd_nm256_ac97_ready(struct nm256 *chip)
-{
- int timeout = 10;
- u32 testaddr;
- u16 testb;
-
- testaddr = chip->mixer_status_offset;
- testb = chip->mixer_status_mask;
-
- /*
- * Loop around waiting for the mixer to become ready.
- */
- while (timeout-- > 0) {
- if ((snd_nm256_readw(chip, testaddr) & testb) == 0)
- return 1;
- udelay(100);
- }
- return 0;
-}
-
-/*
- * Initial register values to be written to the AC97 mixer.
- * While most of these are identical to the reset values, we do this
- * so that we have most of the register contents cached--this avoids
- * reading from the mixer directly (which seems to be problematic,
- * probably due to ignorance).
- */
-
-struct initialValues {
- unsigned short reg;
- unsigned short value;
-};
-
-static struct initialValues nm256_ac97_init_val[] =
-{
- { AC97_MASTER, 0x8000 },
- { AC97_HEADPHONE, 0x8000 },
- { AC97_MASTER_MONO, 0x8000 },
- { AC97_PC_BEEP, 0x8000 },
- { AC97_PHONE, 0x8008 },
- { AC97_MIC, 0x8000 },
- { AC97_LINE, 0x8808 },
- { AC97_CD, 0x8808 },
- { AC97_VIDEO, 0x8808 },
- { AC97_AUX, 0x8808 },
- { AC97_PCM, 0x8808 },
- { AC97_REC_SEL, 0x0000 },
- { AC97_REC_GAIN, 0x0B0B },
- { AC97_GENERAL_PURPOSE, 0x0000 },
- { AC97_3D_CONTROL, 0x8000 },
- { AC97_VENDOR_ID1, 0x8384 },
- { AC97_VENDOR_ID2, 0x7609 },
-};
-
-static int nm256_ac97_idx(unsigned short reg)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(nm256_ac97_init_val); i++)
- if (nm256_ac97_init_val[i].reg == reg)
- return i;
- return -1;
-}
-
-/*
- * some nm256 easily crash when reading from mixer registers
- * thus we're treating it as a write-only mixer and cache the
- * written values
- */
-static unsigned short
-snd_nm256_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
-{
- struct nm256 *chip = ac97->private_data;
- int idx = nm256_ac97_idx(reg);
-
- if (idx < 0)
- return 0;
- return chip->ac97_regs[idx];
-}
-
-/*
- */
-static void
-snd_nm256_ac97_write(struct snd_ac97 *ac97,
- unsigned short reg, unsigned short val)
-{
- struct nm256 *chip = ac97->private_data;
- int tries = 2;
- int idx = nm256_ac97_idx(reg);
- u32 base;
-
- if (idx < 0)
- return;
-
- base = chip->mixer_base;
-
- snd_nm256_ac97_ready(chip);
-
- /* Wait for the write to take, too. */
- while (tries-- > 0) {
- snd_nm256_writew(chip, base + reg, val);
- msleep(1); /* a little delay here seems better.. */
- if (snd_nm256_ac97_ready(chip)) {
- /* successful write: set cache */
- chip->ac97_regs[idx] = val;
- return;
- }
- }
- snd_printd("nm256: ac97 codec not ready..\n");
-}
-
-/* static resolution table */
-static struct snd_ac97_res_table nm256_res_table[] = {
- { AC97_MASTER, 0x1f1f },
- { AC97_HEADPHONE, 0x1f1f },
- { AC97_MASTER_MONO, 0x001f },
- { AC97_PC_BEEP, 0x001f },
- { AC97_PHONE, 0x001f },
- { AC97_MIC, 0x001f },
- { AC97_LINE, 0x1f1f },
- { AC97_CD, 0x1f1f },
- { AC97_VIDEO, 0x1f1f },
- { AC97_AUX, 0x1f1f },
- { AC97_PCM, 0x1f1f },
- { AC97_REC_GAIN, 0x0f0f },
- { } /* terminator */
-};
-
-/* initialize the ac97 into a known state */
-static void
-snd_nm256_ac97_reset(struct snd_ac97 *ac97)
-{
- struct nm256 *chip = ac97->private_data;
-
- /* Reset the mixer. 'Tis magic! */
- snd_nm256_writeb(chip, 0x6c0, 1);
- if (! chip->reset_workaround) {
- /* Dell latitude LS will lock up by this */
- snd_nm256_writeb(chip, 0x6cc, 0x87);
- }
- if (! chip->reset_workaround_2) {
- /* Dell latitude CSx will lock up by this */
- snd_nm256_writeb(chip, 0x6cc, 0x80);
- snd_nm256_writeb(chip, 0x6cc, 0x0);
- }
- if (! chip->in_resume) {
- int i;
- for (i = 0; i < ARRAY_SIZE(nm256_ac97_init_val); i++) {
- /* preload the cache, so as to avoid even a single
- * read of the mixer regs
- */
- snd_nm256_ac97_write(ac97, nm256_ac97_init_val[i].reg,
- nm256_ac97_init_val[i].value);
- }
- }
-}
-
-/* create an ac97 mixer interface */
-static int __devinit
-snd_nm256_mixer(struct nm256 *chip)
-{
- struct snd_ac97_bus *pbus;
- struct snd_ac97_template ac97;
- int err;
- static struct snd_ac97_bus_ops ops = {
- .reset = snd_nm256_ac97_reset,
- .write = snd_nm256_ac97_write,
- .read = snd_nm256_ac97_read,
- };
-
- chip->ac97_regs = kcalloc(ARRAY_SIZE(nm256_ac97_init_val),
- sizeof(short), GFP_KERNEL);
- if (! chip->ac97_regs)
- return -ENOMEM;
-
- if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
- return err;
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.scaps = AC97_SCAP_AUDIO; /* we support audio! */
- ac97.private_data = chip;
- ac97.res_table = nm256_res_table;
- pbus->no_vra = 1;
- err = snd_ac97_mixer(pbus, &ac97, &chip->ac97);
- if (err < 0)
- return err;
- if (! (chip->ac97->id & (0xf0000000))) {
- /* looks like an invalid id */
- sprintf(chip->card->mixername, "%s AC97", chip->card->driver);
- }
- return 0;
-}
-
-/*
- * See if the signature left by the NM256 BIOS is intact; if so, we use
- * the associated address as the end of our audio buffer in the video
- * RAM.
- */
-
-static int __devinit
-snd_nm256_peek_for_sig(struct nm256 *chip)
-{
- /* The signature is located 1K below the end of video RAM. */
- void __iomem *temp;
- /* Default buffer end is 5120 bytes below the top of RAM. */
- unsigned long pointer_found = chip->buffer_end - 0x1400;
- u32 sig;
-
- temp = ioremap_nocache(chip->buffer_addr + chip->buffer_end - 0x400, 16);
- if (temp == NULL) {
- snd_printk(KERN_ERR "Unable to scan for card signature in video RAM\n");
- return -EBUSY;
- }
-
- sig = readl(temp);
- if ((sig & NM_SIG_MASK) == NM_SIGNATURE) {
- u32 pointer = readl(temp + 4);
-
- /*
- * If it's obviously invalid, don't use it
- */
- if (pointer == 0xffffffff ||
- pointer < chip->buffer_size ||
- pointer > chip->buffer_end) {
- snd_printk(KERN_ERR "invalid signature found: 0x%x\n", pointer);
- iounmap(temp);
- return -ENODEV;
- } else {
- pointer_found = pointer;
- printk(KERN_INFO "nm256: found card signature in video RAM: 0x%x\n",
- pointer);
- }
- }
-
- iounmap(temp);
- chip->buffer_end = pointer_found;
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-/*
- * APM event handler, so the card is properly reinitialized after a power
- * event.
- */
-static int nm256_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct nm256 *chip = card->private_data;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(chip->pcm);
- snd_ac97_suspend(chip->ac97);
- chip->coeffs_current = 0;
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int nm256_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct nm256 *chip = card->private_data;
- int i;
-
- /* Perform a full reset on the hardware */
- chip->in_resume = 1;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "nm256: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
-
- snd_nm256_init_chip(chip);
-
- /* restore ac97 */
- snd_ac97_resume(chip->ac97);
-
- for (i = 0; i < 2; i++) {
- struct nm256_stream *s = &chip->streams[i];
- if (s->substream && s->suspended) {
- spin_lock_irq(&chip->reg_lock);
- snd_nm256_set_format(chip, s, s->substream);
- spin_unlock_irq(&chip->reg_lock);
- }
- }
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- chip->in_resume = 0;
- return 0;
-}
-#endif /* CONFIG_PM */
-
-static int snd_nm256_free(struct nm256 *chip)
-{
- if (chip->streams[SNDRV_PCM_STREAM_PLAYBACK].running)
- snd_nm256_playback_stop(chip);
- if (chip->streams[SNDRV_PCM_STREAM_CAPTURE].running)
- snd_nm256_capture_stop(chip);
-
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
-
- if (chip->cport)
- iounmap(chip->cport);
- if (chip->buffer)
- iounmap(chip->buffer);
- release_and_free_resource(chip->res_cport);
- release_and_free_resource(chip->res_buffer);
-
- pci_disable_device(chip->pci);
- kfree(chip->ac97_regs);
- kfree(chip);
- return 0;
-}
-
-static int snd_nm256_dev_free(struct snd_device *device)
-{
- struct nm256 *chip = device->device_data;
- return snd_nm256_free(chip);
-}
-
-static int __devinit
-snd_nm256_create(struct snd_card *card, struct pci_dev *pci,
- struct nm256 **chip_ret)
-{
- struct nm256 *chip;
- int err, pval;
- static struct snd_device_ops ops = {
- .dev_free = snd_nm256_dev_free,
- };
- u32 addr;
-
- *chip_ret = NULL;
-
- if ((err = pci_enable_device(pci)) < 0)
- return err;
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- chip->card = card;
- chip->pci = pci;
- chip->use_cache = use_cache;
- spin_lock_init(&chip->reg_lock);
- chip->irq = -1;
- mutex_init(&chip->irq_mutex);
-
- /* store buffer sizes in bytes */
- chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize = playback_bufsize * 1024;
- chip->streams[SNDRV_PCM_STREAM_CAPTURE].bufsize = capture_bufsize * 1024;
-
- /*
- * The NM256 has two memory ports. The first port is nothing
- * more than a chunk of video RAM, which is used as the I/O ring
- * buffer. The second port has the actual juicy stuff (like the
- * mixer and the playback engine control registers).
- */
-
- chip->buffer_addr = pci_resource_start(pci, 0);
- chip->cport_addr = pci_resource_start(pci, 1);
-
- /* Init the memory port info. */
- /* remap control port (#2) */
- chip->res_cport = request_mem_region(chip->cport_addr, NM_PORT2_SIZE,
- card->driver);
- if (chip->res_cport == NULL) {
- snd_printk(KERN_ERR "memory region 0x%lx (size 0x%x) busy\n",
- chip->cport_addr, NM_PORT2_SIZE);
- err = -EBUSY;
- goto __error;
- }
- chip->cport = ioremap_nocache(chip->cport_addr, NM_PORT2_SIZE);
- if (chip->cport == NULL) {
- snd_printk(KERN_ERR "unable to map control port %lx\n", chip->cport_addr);
- err = -ENOMEM;
- goto __error;
- }
-
- if (!strcmp(card->driver, "NM256AV")) {
- /* Ok, try to see if this is a non-AC97 version of the hardware. */
- pval = snd_nm256_readw(chip, NM_MIXER_PRESENCE);
- if ((pval & NM_PRESENCE_MASK) != NM_PRESENCE_VALUE) {
- if (! force_ac97) {
- printk(KERN_ERR "nm256: no ac97 is found!\n");
- printk(KERN_ERR " force the driver to load by "
- "passing in the module parameter\n");
- printk(KERN_ERR " force_ac97=1\n");
- printk(KERN_ERR " or try sb16, opl3sa2, or "
- "cs423x drivers instead.\n");
- err = -ENXIO;
- goto __error;
- }
- }
- chip->buffer_end = 2560 * 1024;
- chip->interrupt = snd_nm256_interrupt;
- chip->mixer_status_offset = NM_MIXER_STATUS_OFFSET;
- chip->mixer_status_mask = NM_MIXER_READY_MASK;
- } else {
- /* Not sure if there is any relevant detect for the ZX or not. */
- if (snd_nm256_readb(chip, 0xa0b) != 0)
- chip->buffer_end = 6144 * 1024;
- else
- chip->buffer_end = 4096 * 1024;
-
- chip->interrupt = snd_nm256_interrupt_zx;
- chip->mixer_status_offset = NM2_MIXER_STATUS_OFFSET;
- chip->mixer_status_mask = NM2_MIXER_READY_MASK;
- }
-
- chip->buffer_size = chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize +
- chip->streams[SNDRV_PCM_STREAM_CAPTURE].bufsize;
- if (chip->use_cache)
- chip->buffer_size += NM_TOTAL_COEFF_COUNT * 4;
- else
- chip->buffer_size += NM_MAX_PLAYBACK_COEF_SIZE + NM_MAX_RECORD_COEF_SIZE;
-
- if (buffer_top >= chip->buffer_size && buffer_top < chip->buffer_end)
- chip->buffer_end = buffer_top;
- else {
- /* get buffer end pointer from signature */
- if ((err = snd_nm256_peek_for_sig(chip)) < 0)
- goto __error;
- }
-
- chip->buffer_start = chip->buffer_end - chip->buffer_size;
- chip->buffer_addr += chip->buffer_start;
-
- printk(KERN_INFO "nm256: Mapping port 1 from 0x%x - 0x%x\n",
- chip->buffer_start, chip->buffer_end);
-
- chip->res_buffer = request_mem_region(chip->buffer_addr,
- chip->buffer_size,
- card->driver);
- if (chip->res_buffer == NULL) {
- snd_printk(KERN_ERR "nm256: buffer 0x%lx (size 0x%x) busy\n",
- chip->buffer_addr, chip->buffer_size);
- err = -EBUSY;
- goto __error;
- }
- chip->buffer = ioremap_nocache(chip->buffer_addr, chip->buffer_size);
- if (chip->buffer == NULL) {
- err = -ENOMEM;
- snd_printk(KERN_ERR "unable to map ring buffer at %lx\n", chip->buffer_addr);
- goto __error;
- }
-
- /* set offsets */
- addr = chip->buffer_start;
- chip->streams[SNDRV_PCM_STREAM_PLAYBACK].buf = addr;
- addr += chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize;
- chip->streams[SNDRV_PCM_STREAM_CAPTURE].buf = addr;
- addr += chip->streams[SNDRV_PCM_STREAM_CAPTURE].bufsize;
- if (chip->use_cache) {
- chip->all_coeff_buf = addr;
- } else {
- chip->coeff_buf[SNDRV_PCM_STREAM_PLAYBACK] = addr;
- addr += NM_MAX_PLAYBACK_COEF_SIZE;
- chip->coeff_buf[SNDRV_PCM_STREAM_CAPTURE] = addr;
- }
-
- /* Fixed setting. */
- chip->mixer_base = NM_MIXER_OFFSET;
-
- chip->coeffs_current = 0;
-
- snd_nm256_init_chip(chip);
-
- // pci_set_master(pci); /* needed? */
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0)
- goto __error;
-
- snd_card_set_dev(card, &pci->dev);
-
- *chip_ret = chip;
- return 0;
-
-__error:
- snd_nm256_free(chip);
- return err;
-}
-
-
-enum { NM_BLACKLISTED, NM_RESET_WORKAROUND, NM_RESET_WORKAROUND_2 };
-
-static struct snd_pci_quirk nm256_quirks[] __devinitdata = {
- /* HP omnibook 4150 has cs4232 codec internally */
- SND_PCI_QUIRK(0x103c, 0x0007, "HP omnibook 4150", NM_BLACKLISTED),
- /* Reset workarounds to avoid lock-ups */
- SND_PCI_QUIRK(0x104d, 0x8041, "Sony PCG-F305", NM_RESET_WORKAROUND),
- SND_PCI_QUIRK(0x1028, 0x0080, "Dell Latitude LS", NM_RESET_WORKAROUND),
- SND_PCI_QUIRK(0x1028, 0x0091, "Dell Latitude CSx", NM_RESET_WORKAROUND_2),
- { } /* terminator */
-};
-
-
-static int __devinit snd_nm256_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- struct snd_card *card;
- struct nm256 *chip;
- int err;
- const struct snd_pci_quirk *q;
-
- q = snd_pci_quirk_lookup(pci, nm256_quirks);
- if (q) {
- snd_printdd(KERN_INFO "nm256: Enabled quirk for %s.\n", q->name);
- switch (q->value) {
- case NM_BLACKLISTED:
- printk(KERN_INFO "nm256: The device is blacklisted. "
- "Loading stopped\n");
- return -ENODEV;
- case NM_RESET_WORKAROUND_2:
- reset_workaround_2 = 1;
- /* Fall-through */
- case NM_RESET_WORKAROUND:
- reset_workaround = 1;
- break;
- }
- }
-
- err = snd_card_create(index, id, THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- switch (pci->device) {
- case PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO:
- strcpy(card->driver, "NM256AV");
- break;
- case PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO:
- strcpy(card->driver, "NM256ZX");
- break;
- case PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO:
- strcpy(card->driver, "NM256XL+");
- break;
- default:
- snd_printk(KERN_ERR "invalid device id 0x%x\n", pci->device);
- snd_card_free(card);
- return -EINVAL;
- }
-
- if (vaio_hack)
- buffer_top = 0x25a800; /* this avoids conflicts with XFree86 server */
-
- if (playback_bufsize < 4)
- playback_bufsize = 4;
- if (playback_bufsize > 128)
- playback_bufsize = 128;
- if (capture_bufsize < 4)
- capture_bufsize = 4;
- if (capture_bufsize > 128)
- capture_bufsize = 128;
- if ((err = snd_nm256_create(card, pci, &chip)) < 0) {
- snd_card_free(card);
- return err;
- }
- card->private_data = chip;
-
- if (reset_workaround) {
- snd_printdd(KERN_INFO "nm256: reset_workaround activated\n");
- chip->reset_workaround = 1;
- }
-
- if (reset_workaround_2) {
- snd_printdd(KERN_INFO "nm256: reset_workaround_2 activated\n");
- chip->reset_workaround_2 = 1;
- }
-
- if ((err = snd_nm256_pcm(chip, 0)) < 0 ||
- (err = snd_nm256_mixer(chip)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- sprintf(card->shortname, "NeoMagic %s", card->driver);
- sprintf(card->longname, "%s at 0x%lx & 0x%lx, irq %d",
- card->shortname,
- chip->buffer_addr, chip->cport_addr, chip->irq);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- pci_set_drvdata(pci, card);
- return 0;
-}
-
-static void __devexit snd_nm256_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_nm256_ids,
- .probe = snd_nm256_probe,
- .remove = __devexit_p(snd_nm256_remove),
-#ifdef CONFIG_PM
- .suspend = nm256_suspend,
- .resume = nm256_resume,
-#endif
-};
-
-
-static int __init alsa_card_nm256_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_nm256_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_nm256_init)
-module_exit(alsa_card_nm256_exit)
diff --git a/ANDROID_3.4.5/sound/pci/nm256/nm256_coef.c b/ANDROID_3.4.5/sound/pci/nm256/nm256_coef.c
deleted file mode 100644
index 747d5d6c..00000000
--- a/ANDROID_3.4.5/sound/pci/nm256/nm256_coef.c
+++ /dev/null
@@ -1,4607 +0,0 @@
-#define NM_TOTAL_COEFF_COUNT 0x3158
-
-static char coefficients[NM_TOTAL_COEFF_COUNT * 4] = {
- 0xFF, 0xFF, 0x2F, 0x00, 0x4B, 0xFF, 0xA5, 0x01, 0xEF, 0xFC, 0x21,
- 0x05, 0x87, 0xF7, 0x62, 0x11, 0xE9, 0x45, 0x5E, 0xF9, 0xB5, 0x01,
- 0xDE, 0xFF, 0xA4, 0xFF, 0x60, 0x00, 0xCA, 0xFF, 0x0D, 0x00, 0xFD,
- 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3D, 0xFC, 0xD6, 0x06,
- 0x4C, 0xF3, 0xED, 0x20, 0x3D, 0x3D, 0x4A, 0xF3, 0x4E, 0x05, 0xB1,
- 0xFD, 0xE1, 0x00, 0xC3, 0xFF, 0x05, 0x00, 0x02, 0x00, 0xFD, 0xFF,
- 0x2A, 0x00, 0x5C, 0xFF, 0xAA, 0x01, 0x71, 0xFC, 0x07, 0x07, 0x7E,
- 0xF1, 0x44, 0x30, 0x44, 0x30, 0x7E, 0xF1, 0x07, 0x07, 0x71, 0xFC,
- 0xAA, 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0xFD, 0xFF, 0x02, 0x00, 0x05,
- 0x00, 0xC3, 0xFF, 0xE1, 0x00, 0xB1, 0xFD, 0x4E, 0x05, 0x4A, 0xF3,
- 0x3D, 0x3D, 0xED, 0x20, 0x4C, 0xF3, 0xD6, 0x06, 0x3D, 0xFC, 0xE6,
- 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x0D, 0x00, 0xCA, 0xFF,
- 0x60, 0x00, 0xA4, 0xFF, 0xDE, 0xFF, 0xB5, 0x01, 0x5E, 0xF9, 0xE9,
- 0x45, 0x62, 0x11, 0x87, 0xF7, 0x21, 0x05, 0xEF, 0xFC, 0xA5, 0x01,
- 0x4B, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1E, 0x00, 0x84,
- 0xFF, 0x11, 0x01, 0x34, 0xFE, 0x8F, 0x02, 0xC7, 0xFC, 0xAE, 0x03,
- 0xF7, 0x48, 0xAE, 0x03, 0xC7, 0xFC, 0x8F, 0x02, 0x34, 0xFE, 0x11,
- 0x01, 0x84, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3D, 0xFF,
- 0xCA, 0x01, 0x95, 0xFC, 0xEA, 0x05, 0xBB, 0xF5, 0x25, 0x17, 0x3C,
- 0x43, 0x8D, 0xF6, 0x43, 0x03, 0xF5, 0xFE, 0x26, 0x00, 0x20, 0x00,
- 0xE2, 0xFF, 0x08, 0x00, 0xFD, 0xFF, 0x30, 0x00, 0x4D, 0xFF, 0xC5,
- 0x01, 0x4C, 0xFC, 0x26, 0x07, 0xA3, 0xF1, 0xAB, 0x2C, 0xBB, 0x33,
- 0x8F, 0xF1, 0xCA, 0x06, 0xA6, 0xFC, 0x85, 0x01, 0x6F, 0xFF, 0x24,
- 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFE, 0xFF, 0xD5, 0xFF, 0xBC, 0x00,
- 0xF0, 0xFD, 0xEC, 0x04, 0xD9, 0xF3, 0xB1, 0x3E, 0xCD, 0x1E, 0xC1,
- 0xF3, 0xAF, 0x06, 0x49, 0xFC, 0xE4, 0x01, 0x36, 0xFF, 0x36, 0x00,
- 0xFE, 0xFF, 0x16, 0x00, 0xA6, 0xFF, 0xBB, 0x00, 0xE9, 0xFE, 0x38,
- 0x01, 0x4B, 0xFF, 0x28, 0xFE, 0x3A, 0x48, 0x04, 0x0A, 0x2E, 0xFA,
- 0xDF, 0x03, 0x8A, 0xFD, 0x60, 0x01, 0x65, 0xFF, 0x27, 0x00, 0x00,
- 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x50, 0xFF, 0x98, 0x01, 0x0D, 0xFD,
- 0xE0, 0x04, 0x14, 0xF8, 0xC3, 0x0F, 0x89, 0x46, 0x4C, 0xFA, 0x38,
- 0x01, 0x25, 0x00, 0x7D, 0xFF, 0x73, 0x00, 0xC2, 0xFF, 0x0F, 0x00,
- 0xFD, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xE3, 0x01, 0x31, 0xFC, 0x0F,
- 0x07, 0x84, 0xF2, 0x29, 0x25, 0x1A, 0x3A, 0x67, 0xF2, 0xF6, 0x05,
- 0x41, 0xFD, 0x24, 0x01, 0xA1, 0xFF, 0x12, 0x00, 0x00, 0x00, 0xFF,
- 0xFF, 0x15, 0x00, 0x97, 0xFF, 0x37, 0x01, 0x22, 0xFD, 0x23, 0x06,
- 0x2F, 0xF2, 0x11, 0x39, 0x7B, 0x26, 0x50, 0xF2, 0x1B, 0x07, 0x32,
- 0xFC, 0xE1, 0x01, 0x3C, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0E, 0x00,
- 0xC8, 0xFF, 0x64, 0x00, 0x9B, 0xFF, 0xEE, 0xFF, 0x98, 0x01, 0x93,
- 0xF9, 0x10, 0x46, 0x03, 0x11, 0xA7, 0xF7, 0x12, 0x05, 0xF6, 0xFC,
- 0xA2, 0x01, 0x4C, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x26,
- 0x00, 0x6A, 0xFF, 0x53, 0x01, 0xA6, 0xFD, 0xA6, 0x03, 0xA1, 0xFA,
- 0xDE, 0x08, 0x76, 0x48, 0x0C, 0xFF, 0xDE, 0xFE, 0x73, 0x01, 0xC9,
- 0xFE, 0xCA, 0x00, 0xA0, 0xFF, 0x17, 0x00, 0xFE, 0xFF, 0x36, 0x00,
- 0x36, 0xFF, 0xE1, 0x01, 0x52, 0xFC, 0x93, 0x06, 0x10, 0xF4, 0x78,
- 0x1D, 0x90, 0x3F, 0x3E, 0xF4, 0xAA, 0x04, 0x19, 0xFE, 0xA4, 0x00,
- 0xE2, 0xFF, 0xFA, 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x26, 0x00, 0x68,
- 0xFF, 0x93, 0x01, 0x92, 0xFC, 0xE2, 0x06, 0x83, 0xF1, 0x8C, 0x32,
- 0xED, 0x2D, 0x90, 0xF1, 0x1E, 0x07, 0x57, 0xFC, 0xBD, 0x01, 0x51,
- 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE8, 0xFF, 0x12, 0x00,
- 0x42, 0x00, 0xC4, 0xFE, 0x94, 0x03, 0x02, 0xF6, 0x89, 0x42, 0x76,
- 0x18, 0x5C, 0xF5, 0x12, 0x06, 0x84, 0xFC, 0xD1, 0x01, 0x3B, 0xFF,
- 0x34, 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x8A, 0xFF, 0x03, 0x01, 0x53,
- 0xFE, 0x53, 0x02, 0x39, 0xFD, 0xA9, 0x02, 0xF2, 0x48, 0xB9, 0x04,
- 0x54, 0xFC, 0xCA, 0x02, 0x16, 0xFE, 0x20, 0x01, 0x7F, 0xFF, 0x20,
- 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x40, 0xFF, 0xC3, 0x01,
- 0xA7, 0xFC, 0xC0, 0x05, 0x1E, 0xF6, 0xD8, 0x15, 0xE7, 0x43, 0x20,
- 0xF7, 0xEF, 0x02, 0x27, 0xFF, 0x0A, 0x00, 0x2E, 0x00, 0xDD, 0xFF,
- 0x09, 0x00, 0xFD, 0xFF, 0x31, 0x00, 0x48, 0xFF, 0xCD, 0x01, 0x43,
- 0xFC, 0x2A, 0x07, 0xBC, 0xF1, 0x64, 0x2B, 0xE3, 0x34, 0xA3, 0xF1,
- 0xAE, 0x06, 0xBD, 0xFC, 0x77, 0x01, 0x77, 0xFF, 0x21, 0x00, 0xFE,
- 0xFF, 0x02, 0x00, 0x03, 0x00, 0xCA, 0xFF, 0xD4, 0x00, 0xC8, 0xFD,
- 0x2A, 0x05, 0x7D, 0xF3, 0xCA, 0x3D, 0x22, 0x20, 0x76, 0xF3, 0xC8,
- 0x06, 0x41, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF,
- 0x14, 0x00, 0xAC, 0xFF, 0xAC, 0x00, 0x08, 0xFF, 0xFD, 0x00, 0xB5,
- 0xFF, 0x4B, 0xFD, 0xF4, 0x47, 0x30, 0x0B, 0xBC, 0xF9, 0x17, 0x04,
- 0x6E, 0xFD, 0x6D, 0x01, 0x60, 0xFF, 0x29, 0x00, 0x00, 0x00, 0xFF,
- 0xFF, 0x2C, 0x00, 0x54, 0xFF, 0x8D, 0x01, 0x26, 0xFD, 0xAD, 0x04,
- 0x82, 0xF8, 0x87, 0x0E, 0xF9, 0x46, 0x0C, 0xFB, 0xD4, 0x00, 0x5D,
- 0x00, 0x5E, 0xFF, 0x82, 0x00, 0xBD, 0xFF, 0x10, 0x00, 0xFD, 0xFF,
- 0x36, 0x00, 0x38, 0xFF, 0xE5, 0x01, 0x33, 0xFC, 0x01, 0x07, 0xBE,
- 0xF2, 0xD6, 0x23, 0x1F, 0x3B, 0xA5, 0xF2, 0xC5, 0x05, 0x62, 0xFD,
- 0x10, 0x01, 0xAB, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x19,
- 0x00, 0x8E, 0xFF, 0x49, 0x01, 0x04, 0xFD, 0x4D, 0x06, 0x00, 0xF2,
- 0xFE, 0x37, 0xCB, 0x27, 0x21, 0xF2, 0x23, 0x07, 0x34, 0xFC, 0xDD,
- 0x01, 0x3F, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0C, 0x00, 0xCE, 0xFF,
- 0x56, 0x00, 0xB9, 0xFF, 0xB8, 0xFF, 0xF7, 0x01, 0xE2, 0xF8, 0x8D,
- 0x45, 0x46, 0x12, 0x3C, 0xF7, 0x43, 0x05, 0xDF, 0xFC, 0xAC, 0x01,
- 0x48, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x24, 0x00, 0x70,
- 0xFF, 0x46, 0x01, 0xC3, 0xFD, 0x6D, 0x03, 0x14, 0xFB, 0xBE, 0x07,
- 0xA6, 0x48, 0xF8, 0xFF, 0x70, 0xFE, 0xAE, 0x01, 0xAA, 0xFE, 0xD9,
- 0x00, 0x9A, 0xFF, 0x19, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF,
- 0xDE, 0x01, 0x5D, 0xFC, 0x74, 0x06, 0x63, 0xF4, 0x23, 0x1C, 0x66,
- 0x40, 0xAA, 0xF4, 0x65, 0x04, 0x44, 0xFE, 0x8B, 0x00, 0xEE, 0xFF,
- 0xF5, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x29, 0x00, 0x61, 0xFF, 0x9F,
- 0x01, 0x80, 0xFC, 0xF7, 0x06, 0x7D, 0xF1, 0x5A, 0x31, 0x2C, 0x2F,
- 0x83, 0xF1, 0x13, 0x07, 0x64, 0xFC, 0xB3, 0x01, 0x57, 0xFF, 0x2C,
- 0x00, 0xFD, 0xFF, 0x06, 0x00, 0xED, 0xFF, 0x05, 0x00, 0x5D, 0x00,
- 0x95, 0xFE, 0xE2, 0x03, 0x7F, 0xF5, 0xCC, 0x41, 0xC7, 0x19, 0xFF,
- 0xF4, 0x37, 0x06, 0x75, 0xFC, 0xD6, 0x01, 0x39, 0xFF, 0x35, 0x00,
- 0xFE, 0xFF, 0x1B, 0x00, 0x90, 0xFF, 0xF4, 0x00, 0x72, 0xFE, 0x18,
- 0x02, 0xAA, 0xFD, 0xAB, 0x01, 0xDF, 0x48, 0xCA, 0x05, 0xE1, 0xFB,
- 0x05, 0x03, 0xF7, 0xFD, 0x2E, 0x01, 0x79, 0xFF, 0x21, 0x00, 0x00,
- 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x43, 0xFF, 0xBB, 0x01, 0xBA, 0xFC,
- 0x95, 0x05, 0x83, 0xF6, 0x8C, 0x14, 0x87, 0x44, 0xBB, 0xF7, 0x98,
- 0x02, 0x5A, 0xFF, 0xEE, 0xFF, 0x3C, 0x00, 0xD8, 0xFF, 0x0A, 0x00,
- 0xFD, 0xFF, 0x32, 0x00, 0x44, 0xFF, 0xD3, 0x01, 0x3C, 0xFC, 0x2A,
- 0x07, 0xDC, 0xF1, 0x1A, 0x2A, 0x06, 0x36, 0xBE, 0xF1, 0x8E, 0x06,
- 0xD5, 0xFC, 0x67, 0x01, 0x7F, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x01,
- 0x00, 0x07, 0x00, 0xBE, 0xFF, 0xEA, 0x00, 0xA2, 0xFD, 0x65, 0x05,
- 0x28, 0xF3, 0xDB, 0x3C, 0x78, 0x21, 0x30, 0xF3, 0xDF, 0x06, 0x3A,
- 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x13, 0x00,
- 0xB2, 0xFF, 0x9D, 0x00, 0x27, 0xFF, 0xC3, 0x00, 0x1F, 0x00, 0x76,
- 0xFC, 0xA3, 0x47, 0x60, 0x0C, 0x4A, 0xF9, 0x4E, 0x04, 0x53, 0xFD,
- 0x79, 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B,
- 0x00, 0x58, 0xFF, 0x82, 0x01, 0x3F, 0xFD, 0x78, 0x04, 0xF2, 0xF8,
- 0x50, 0x0D, 0x5E, 0x47, 0xD5, 0xFB, 0x6F, 0x00, 0x96, 0x00, 0x40,
- 0xFF, 0x91, 0x00, 0xB7, 0xFF, 0x12, 0x00, 0xFD, 0xFF, 0x36, 0x00,
- 0x37, 0xFF, 0xE6, 0x01, 0x36, 0xFC, 0xEF, 0x06, 0xFC, 0xF2, 0x81,
- 0x22, 0x1C, 0x3C, 0xEC, 0xF2, 0x90, 0x05, 0x85, 0xFD, 0xFB, 0x00,
- 0xB6, 0xFF, 0x0A, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x85,
- 0xFF, 0x5B, 0x01, 0xE9, 0xFC, 0x73, 0x06, 0xD8, 0xF1, 0xE5, 0x36,
- 0x19, 0x29, 0xF8, 0xF1, 0x29, 0x07, 0x37, 0xFC, 0xD8, 0x01, 0x42,
- 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x0B, 0x00, 0xD3, 0xFF, 0x47, 0x00,
- 0xD7, 0xFF, 0x82, 0xFF, 0x53, 0x02, 0x39, 0xF8, 0xFD, 0x44, 0x8D,
- 0x13, 0xD3, 0xF6, 0x72, 0x05, 0xCA, 0xFC, 0xB5, 0x01, 0x45, 0xFF,
- 0x31, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x23, 0x00, 0x75, 0xFF, 0x39,
- 0x01, 0xE0, 0xFD, 0x33, 0x03, 0x87, 0xFB, 0xA2, 0x06, 0xCB, 0x48,
- 0xEA, 0x00, 0x01, 0xFE, 0xE9, 0x01, 0x8A, 0xFE, 0xE8, 0x00, 0x95,
- 0xFF, 0x1A, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x38, 0xFF, 0xDA, 0x01,
- 0x6A, 0xFC, 0x53, 0x06, 0xBA, 0xF4, 0xCE, 0x1A, 0x32, 0x41, 0x1F,
- 0xF5, 0x1D, 0x04, 0x71, 0xFE, 0x71, 0x00, 0xFB, 0xFF, 0xF0, 0xFF,
- 0x05, 0x00, 0xFD, 0xFF, 0x2B, 0x00, 0x5B, 0xFF, 0xAB, 0x01, 0x6F,
- 0xFC, 0x08, 0x07, 0x7E, 0xF1, 0x21, 0x30, 0x67, 0x30, 0x7D, 0xF1,
- 0x05, 0x07, 0x73, 0xFC, 0xA8, 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0xFD,
- 0xFF, 0x05, 0x00, 0xF2, 0xFF, 0xF8, 0xFF, 0x77, 0x00, 0x67, 0xFE,
- 0x2D, 0x04, 0x04, 0xF5, 0x07, 0x41, 0x1B, 0x1B, 0xA6, 0xF4, 0x5A,
- 0x06, 0x67, 0xFC, 0xDB, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF,
- 0x1A, 0x00, 0x96, 0xFF, 0xE5, 0x00, 0x91, 0xFE, 0xDC, 0x01, 0x1A,
- 0xFE, 0xB3, 0x00, 0xC3, 0x48, 0xE1, 0x06, 0x6E, 0xFB, 0x40, 0x03,
- 0xDA, 0xFD, 0x3C, 0x01, 0x74, 0xFF, 0x23, 0x00, 0x00, 0x00, 0xFF,
- 0xFF, 0x31, 0x00, 0x46, 0xFF, 0xB3, 0x01, 0xCF, 0xFC, 0x67, 0x05,
- 0xEA, 0xF6, 0x44, 0x13, 0x1E, 0x45, 0x5E, 0xF8, 0x3F, 0x02, 0x8E,
- 0xFF, 0xD0, 0xFF, 0x4A, 0x00, 0xD2, 0xFF, 0x0B, 0x00, 0xFD, 0xFF,
- 0x33, 0x00, 0x41, 0xFF, 0xD9, 0x01, 0x36, 0xFC, 0x28, 0x07, 0x01,
- 0xF2, 0xCE, 0x28, 0x23, 0x37, 0xE0, 0xF1, 0x6B, 0x06, 0xEF, 0xFC,
- 0x57, 0x01, 0x87, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x0B,
- 0x00, 0xB4, 0xFF, 0x00, 0x01, 0x7E, 0xFD, 0x9C, 0x05, 0xDC, 0xF2,
- 0xE4, 0x3B, 0xCD, 0x22, 0xEE, 0xF2, 0xF3, 0x06, 0x35, 0xFC, 0xE6,
- 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x11, 0x00, 0xB8, 0xFF,
- 0x8E, 0x00, 0x46, 0xFF, 0x8A, 0x00, 0x86, 0x00, 0xA7, 0xFB, 0x48,
- 0x47, 0x95, 0x0D, 0xD9, 0xF8, 0x84, 0x04, 0x39, 0xFD, 0x85, 0x01,
- 0x57, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5D,
- 0xFF, 0x76, 0x01, 0x59, 0xFD, 0x42, 0x04, 0x63, 0xF9, 0x1C, 0x0C,
- 0xB6, 0x47, 0xA4, 0xFC, 0x07, 0x00, 0xD0, 0x00, 0x20, 0xFF, 0xA0,
- 0x00, 0xB1, 0xFF, 0x13, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF,
- 0xE6, 0x01, 0x3B, 0xFC, 0xDA, 0x06, 0x3F, 0xF3, 0x2C, 0x21, 0x11,
- 0x3D, 0x3A, 0xF3, 0x58, 0x05, 0xAA, 0xFD, 0xE5, 0x00, 0xC1, 0xFF,
- 0x06, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1F, 0x00, 0x7D, 0xFF, 0x6B,
- 0x01, 0xCF, 0xFC, 0x96, 0x06, 0xB7, 0xF1, 0xC6, 0x35, 0x64, 0x2A,
- 0xD4, 0xF1, 0x2B, 0x07, 0x3D, 0xFC, 0xD2, 0x01, 0x45, 0xFF, 0x32,
- 0x00, 0xFD, 0xFF, 0x0A, 0x00, 0xD9, 0xFF, 0x39, 0x00, 0xF4, 0xFF,
- 0x4E, 0xFF, 0xAC, 0x02, 0x98, 0xF7, 0x65, 0x44, 0xD6, 0x14, 0x6C,
- 0xF6, 0x9F, 0x05, 0xB6, 0xFC, 0xBD, 0x01, 0x42, 0xFF, 0x32, 0x00,
- 0xFF, 0xFF, 0x00, 0x00, 0x21, 0x00, 0x7A, 0xFF, 0x2B, 0x01, 0xFE,
- 0xFD, 0xF8, 0x02, 0xFB, 0xFB, 0x8D, 0x05, 0xE5, 0x48, 0xE3, 0x01,
- 0x91, 0xFD, 0x25, 0x02, 0x6B, 0xFE, 0xF7, 0x00, 0x8F, 0xFF, 0x1C,
- 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD5, 0x01, 0x78, 0xFC,
- 0x2F, 0x06, 0x13, 0xF5, 0x7C, 0x19, 0xF7, 0x41, 0x9B, 0xF5, 0xD1,
- 0x03, 0x9F, 0xFE, 0x57, 0x00, 0x08, 0x00, 0xEC, 0xFF, 0x06, 0x00,
- 0xFD, 0xFF, 0x2D, 0x00, 0x55, 0xFF, 0xB5, 0x01, 0x61, 0xFC, 0x16,
- 0x07, 0x85, 0xF1, 0xE6, 0x2E, 0x9E, 0x31, 0x7D, 0xF1, 0xF3, 0x06,
- 0x84, 0xFC, 0x9D, 0x01, 0x63, 0xFF, 0x28, 0x00, 0xFD, 0xFF, 0x04,
- 0x00, 0xF6, 0xFF, 0xEB, 0xFF, 0x91, 0x00, 0x3B, 0xFE, 0x75, 0x04,
- 0x92, 0xF4, 0x36, 0x40, 0x6E, 0x1C, 0x50, 0xF4, 0x7B, 0x06, 0x5B,
- 0xFC, 0xDF, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x18, 0x00,
- 0x9C, 0xFF, 0xD6, 0x00, 0xB1, 0xFE, 0xA1, 0x01, 0x89, 0xFE, 0xC3,
- 0xFF, 0x9C, 0x48, 0xFD, 0x07, 0xFA, 0xFA, 0x7A, 0x03, 0xBC, 0xFD,
- 0x49, 0x01, 0x6E, 0xFF, 0x24, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30,
- 0x00, 0x49, 0xFF, 0xAA, 0x01, 0xE4, 0xFC, 0x38, 0x05, 0x54, 0xF7,
- 0xFE, 0x11, 0xAA, 0x45, 0x09, 0xF9, 0xE2, 0x01, 0xC4, 0xFF, 0xB3,
- 0xFF, 0x59, 0x00, 0xCD, 0xFF, 0x0D, 0x00, 0xFD, 0xFF, 0x34, 0x00,
- 0x3E, 0xFF, 0xDE, 0x01, 0x33, 0xFC, 0x22, 0x07, 0x2B, 0xF2, 0x80,
- 0x27, 0x3B, 0x38, 0x0A, 0xF2, 0x44, 0x06, 0x0B, 0xFD, 0x45, 0x01,
- 0x90, 0xFF, 0x18, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0x00, 0xA9,
- 0xFF, 0x15, 0x01, 0x5B, 0xFD, 0xD0, 0x05, 0x97, 0xF2, 0xE6, 0x3A,
- 0x21, 0x24, 0xB1, 0xF2, 0x04, 0x07, 0x33, 0xFC, 0xE5, 0x01, 0x39,
- 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x10, 0x00, 0xBE, 0xFF, 0x7F, 0x00,
- 0x65, 0xFF, 0x51, 0x00, 0xEB, 0x00, 0xE1, 0xFA, 0xE1, 0x46, 0xCD,
- 0x0E, 0x6A, 0xF8, 0xB8, 0x04, 0x20, 0xFD, 0x90, 0x01, 0x53, 0xFF,
- 0x2D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x28, 0x00, 0x62, 0xFF, 0x6A,
- 0x01, 0x74, 0xFD, 0x0A, 0x04, 0xD5, 0xF9, 0xED, 0x0A, 0x03, 0x48,
- 0x7C, 0xFD, 0x9E, 0xFF, 0x0A, 0x01, 0x01, 0xFF, 0xAF, 0x00, 0xAB,
- 0xFF, 0x14, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE5, 0x01,
- 0x42, 0xFC, 0xC3, 0x06, 0x87, 0xF3, 0xD7, 0x1F, 0xFE, 0x3D, 0x91,
- 0xF3, 0x1D, 0x05, 0xD1, 0xFD, 0xCE, 0x00, 0xCC, 0xFF, 0x02, 0x00,
- 0x02, 0x00, 0xFE, 0xFF, 0x22, 0x00, 0x75, 0xFF, 0x7A, 0x01, 0xB8,
- 0xFC, 0xB4, 0x06, 0x9E, 0xF1, 0xA2, 0x34, 0xAD, 0x2B, 0xB6, 0xF1,
- 0x29, 0x07, 0x45, 0xFC, 0xCB, 0x01, 0x49, 0xFF, 0x31, 0x00, 0xFD,
- 0xFF, 0x09, 0x00, 0xDE, 0xFF, 0x2B, 0x00, 0x11, 0x00, 0x1B, 0xFF,
- 0x02, 0x03, 0xFE, 0xF6, 0xC3, 0x43, 0x22, 0x16, 0x07, 0xF6, 0xCA,
- 0x05, 0xA3, 0xFC, 0xC5, 0x01, 0x3F, 0xFF, 0x33, 0x00, 0xFF, 0xFF,
- 0x00, 0x00, 0x20, 0x00, 0x80, 0xFF, 0x1C, 0x01, 0x1C, 0xFE, 0xBD,
- 0x02, 0x6E, 0xFC, 0x7D, 0x04, 0xF3, 0x48, 0xE2, 0x02, 0x1F, 0xFD,
- 0x60, 0x02, 0x4C, 0xFE, 0x06, 0x01, 0x89, 0xFF, 0x1D, 0x00, 0xFE,
- 0xFF, 0x34, 0x00, 0x3C, 0xFF, 0xCF, 0x01, 0x88, 0xFC, 0x09, 0x06,
- 0x71, 0xF5, 0x2B, 0x18, 0xB2, 0x42, 0x20, 0xF6, 0x83, 0x03, 0xCF,
- 0xFE, 0x3C, 0x00, 0x15, 0x00, 0xE6, 0xFF, 0x07, 0x00, 0xFD, 0xFF,
- 0x2E, 0x00, 0x50, 0xFF, 0xBF, 0x01, 0x54, 0xFC, 0x20, 0x07, 0x94,
- 0xF1, 0xA6, 0x2D, 0xD0, 0x32, 0x85, 0xF1, 0xDD, 0x06, 0x96, 0xFC,
- 0x90, 0x01, 0x69, 0xFF, 0x26, 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFB,
- 0xFF, 0xDF, 0xFF, 0xA9, 0x00, 0x10, 0xFE, 0xB9, 0x04, 0x27, 0xF4,
- 0x5E, 0x3F, 0xC3, 0x1D, 0xFE, 0xF3, 0x99, 0x06, 0x50, 0xFC, 0xE2,
- 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x17, 0x00, 0xA2, 0xFF,
- 0xC7, 0x00, 0xD0, 0xFE, 0x65, 0x01, 0xF6, 0xFE, 0xD9, 0xFE, 0x6A,
- 0x48, 0x1F, 0x09, 0x87, 0xFA, 0xB3, 0x03, 0xA0, 0xFD, 0x56, 0x01,
- 0x69, 0xFF, 0x26, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4D,
- 0xFF, 0xA0, 0x01, 0xFB, 0xFC, 0x07, 0x05, 0xBF, 0xF7, 0xBB, 0x10,
- 0x2B, 0x46, 0xBB, 0xF9, 0x83, 0x01, 0xFA, 0xFF, 0x95, 0xFF, 0x68,
- 0x00, 0xC7, 0xFF, 0x0E, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3C, 0xFF,
- 0xE1, 0x01, 0x31, 0xFC, 0x19, 0x07, 0x5B, 0xF2, 0x30, 0x26, 0x4B,
- 0x39, 0x3B, 0xF2, 0x1A, 0x06, 0x29, 0xFD, 0x33, 0x01, 0x99, 0xFF,
- 0x15, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x13, 0x00, 0x9F, 0xFF, 0x28,
- 0x01, 0x3A, 0xFD, 0x00, 0x06, 0x5A, 0xF2, 0xDF, 0x39, 0x73, 0x25,
- 0x79, 0xF2, 0x12, 0x07, 0x31, 0xFC, 0xE3, 0x01, 0x3B, 0xFF, 0x35,
- 0x00, 0xFD, 0xFF, 0x0F, 0x00, 0xC4, 0xFF, 0x70, 0x00, 0x84, 0xFF,
- 0x19, 0x00, 0x4D, 0x01, 0x22, 0xFA, 0x70, 0x46, 0x0A, 0x10, 0xFC,
- 0xF7, 0xEB, 0x04, 0x08, 0xFD, 0x9A, 0x01, 0x4F, 0xFF, 0x2E, 0x00,
- 0xFF, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x66, 0xFF, 0x5E, 0x01, 0x90,
- 0xFD, 0xD2, 0x03, 0x47, 0xFA, 0xC3, 0x09, 0x48, 0x48, 0x5A, 0xFE,
- 0x33, 0xFF, 0x45, 0x01, 0xE2, 0xFE, 0xBE, 0x00, 0xA5, 0xFF, 0x16,
- 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE3, 0x01, 0x4B, 0xFC,
- 0xA9, 0x06, 0xD2, 0xF3, 0x81, 0x1E, 0xE4, 0x3E, 0xEF, 0xF3, 0xDE,
- 0x04, 0xF9, 0xFD, 0xB7, 0x00, 0xD8, 0xFF, 0xFD, 0xFF, 0x03, 0x00,
- 0xFD, 0xFF, 0x24, 0x00, 0x6D, 0xFF, 0x88, 0x01, 0xA2, 0xFC, 0xD0,
- 0x06, 0x8C, 0xF1, 0x78, 0x33, 0xF2, 0x2C, 0x9E, 0xF1, 0x24, 0x07,
- 0x4E, 0xFC, 0xC3, 0x01, 0x4E, 0xFF, 0x2F, 0x00, 0xFD, 0xFF, 0x08,
- 0x00, 0xE4, 0xFF, 0x1D, 0x00, 0x2D, 0x00, 0xEA, 0xFE, 0x56, 0x03,
- 0x6D, 0xF6, 0x17, 0x43, 0x70, 0x17, 0xA6, 0xF5, 0xF3, 0x05, 0x91,
- 0xFC, 0xCC, 0x01, 0x3D, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x1E, 0x00,
- 0x86, 0xFF, 0x0E, 0x01, 0x3B, 0xFE, 0x82, 0x02, 0xE0, 0xFC, 0x73,
- 0x03, 0xF6, 0x48, 0xE9, 0x03, 0xAD, 0xFC, 0x9C, 0x02, 0x2D, 0xFE,
- 0x14, 0x01, 0x83, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33,
- 0x00, 0x3E, 0xFF, 0xC9, 0x01, 0x99, 0xFC, 0xE1, 0x05, 0xD1, 0xF5,
- 0xDC, 0x16, 0x65, 0x43, 0xAD, 0xF6, 0x31, 0x03, 0x00, 0xFF, 0x20,
- 0x00, 0x23, 0x00, 0xE1, 0xFF, 0x08, 0x00, 0xFD, 0xFF, 0x30, 0x00,
- 0x4C, 0xFF, 0xC7, 0x01, 0x4A, 0xFC, 0x27, 0x07, 0xA8, 0xF1, 0x62,
- 0x2C, 0xFD, 0x33, 0x93, 0xF1, 0xC4, 0x06, 0xAB, 0xFC, 0x82, 0x01,
- 0x71, 0xFF, 0x23, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0xFF, 0xFF, 0xD3,
- 0xFF, 0xC1, 0x00, 0xE7, 0xFD, 0xFA, 0x04, 0xC4, 0xF3, 0x7E, 0x3E,
- 0x19, 0x1F, 0xB0, 0xF3, 0xB5, 0x06, 0x47, 0xFC, 0xE4, 0x01, 0x36,
- 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x15, 0x00, 0xA8, 0xFF, 0xB8, 0x00,
- 0xF0, 0xFE, 0x2B, 0x01, 0x63, 0xFF, 0xF6, 0xFD, 0x2C, 0x48, 0x47,
- 0x0A, 0x14, 0xFA, 0xEB, 0x03, 0x84, 0xFD, 0x63, 0x01, 0x64, 0xFF,
- 0x27, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2D, 0x00, 0x51, 0xFF, 0x96,
- 0x01, 0x13, 0xFD, 0xD5, 0x04, 0x2C, 0xF8, 0x7D, 0x0F, 0xA3, 0x46,
- 0x76, 0xFA, 0x22, 0x01, 0x32, 0x00, 0x76, 0xFF, 0x76, 0x00, 0xC1,
- 0xFF, 0x0F, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x3A, 0xFF, 0xE4, 0x01,
- 0x32, 0xFC, 0x0C, 0x07, 0x91, 0xF2, 0xDD, 0x24, 0x54, 0x3A, 0x74,
- 0xF2, 0xEB, 0x05, 0x49, 0xFD, 0x20, 0x01, 0xA3, 0xFF, 0x11, 0x00,
- 0x00, 0x00, 0xFF, 0xFF, 0x16, 0x00, 0x95, 0xFF, 0x3B, 0x01, 0x1B,
- 0xFD, 0x2D, 0x06, 0x24, 0xF2, 0xD3, 0x38, 0xC6, 0x26, 0x45, 0xF2,
- 0x1D, 0x07, 0x32, 0xFC, 0xE0, 0x01, 0x3D, 0xFF, 0x35, 0x00, 0xFD,
- 0xFF, 0x0D, 0x00, 0xC9, 0xFF, 0x61, 0x00, 0xA2, 0xFF, 0xE2, 0xFF,
- 0xAE, 0x01, 0x6B, 0xF9, 0xF2, 0x45, 0x4A, 0x11, 0x8F, 0xF7, 0x1D,
- 0x05, 0xF1, 0xFC, 0xA4, 0x01, 0x4B, 0xFF, 0x2F, 0x00, 0xFF, 0xFF,
- 0x00, 0x00, 0x25, 0x00, 0x6C, 0xFF, 0x51, 0x01, 0xAC, 0xFD, 0x9A,
- 0x03, 0xBA, 0xFA, 0x9E, 0x08, 0x81, 0x48, 0x40, 0xFF, 0xC6, 0xFE,
- 0x80, 0x01, 0xC2, 0xFE, 0xCE, 0x00, 0x9F, 0xFF, 0x17, 0x00, 0xFE,
- 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE1, 0x01, 0x55, 0xFC, 0x8C, 0x06,
- 0x22, 0xF4, 0x2C, 0x1D, 0xC0, 0x3F, 0x55, 0xF4, 0x9B, 0x04, 0x23,
- 0xFE, 0x9F, 0x00, 0xE4, 0xFF, 0xF9, 0xFF, 0x04, 0x00, 0xFD, 0xFF,
- 0x27, 0x00, 0x66, 0xFF, 0x96, 0x01, 0x8E, 0xFC, 0xE7, 0x06, 0x81,
- 0xF1, 0x48, 0x32, 0x34, 0x2E, 0x8D, 0xF1, 0x1C, 0x07, 0x5A, 0xFC,
- 0xBB, 0x01, 0x53, 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE9,
- 0xFF, 0x0F, 0x00, 0x48, 0x00, 0xB9, 0xFE, 0xA6, 0x03, 0xE4, 0xF5,
- 0x60, 0x42, 0xC1, 0x18, 0x47, 0xF5, 0x1A, 0x06, 0x81, 0xFC, 0xD2,
- 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x8B, 0xFF,
- 0xFF, 0x00, 0x5A, 0xFE, 0x46, 0x02, 0x52, 0xFD, 0x70, 0x02, 0xED,
- 0x48, 0xF5, 0x04, 0x3B, 0xFC, 0xD7, 0x02, 0x0F, 0xFE, 0x23, 0x01,
- 0x7E, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x40,
- 0xFF, 0xC1, 0x01, 0xAB, 0xFC, 0xB7, 0x05, 0x34, 0xF6, 0x8E, 0x15,
- 0x0B, 0x44, 0x42, 0xF7, 0xDC, 0x02, 0x32, 0xFF, 0x04, 0x00, 0x31,
- 0x00, 0xDC, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x31, 0x00, 0x47, 0xFF,
- 0xCE, 0x01, 0x41, 0xFC, 0x2A, 0x07, 0xC2, 0xF1, 0x1B, 0x2B, 0x25,
- 0x35, 0xA8, 0xF1, 0xA7, 0x06, 0xC2, 0xFC, 0x74, 0x01, 0x78, 0xFF,
- 0x20, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x04, 0x00, 0xC7, 0xFF, 0xD9,
- 0x00, 0xBF, 0xFD, 0x38, 0x05, 0x69, 0xF3, 0x96, 0x3D, 0x6F, 0x20,
- 0x66, 0xF3, 0xCE, 0x06, 0x3F, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36,
- 0x00, 0xFD, 0xFF, 0x14, 0x00, 0xAE, 0xFF, 0xA9, 0x00, 0x0F, 0xFF,
- 0xF0, 0x00, 0xCD, 0xFF, 0x1B, 0xFD, 0xE4, 0x47, 0x73, 0x0B, 0xA2,
- 0xF9, 0x23, 0x04, 0x68, 0xFD, 0x70, 0x01, 0x5F, 0xFF, 0x29, 0x00,
- 0x00, 0x00, 0xFF, 0xFF, 0x2C, 0x00, 0x55, 0xFF, 0x8B, 0x01, 0x2B,
- 0xFD, 0xA1, 0x04, 0x9B, 0xF8, 0x42, 0x0E, 0x0F, 0x47, 0x38, 0xFB,
- 0xBE, 0x00, 0x6A, 0x00, 0x58, 0xFF, 0x85, 0x00, 0xBB, 0xFF, 0x10,
- 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE6, 0x01, 0x34, 0xFC,
- 0xFD, 0x06, 0xCB, 0xF2, 0x8A, 0x23, 0x58, 0x3B, 0xB4, 0xF2, 0xBA,
- 0x05, 0x6A, 0xFD, 0x0B, 0x01, 0xAE, 0xFF, 0x0D, 0x00, 0x00, 0x00,
- 0xFF, 0xFF, 0x19, 0x00, 0x8C, 0xFF, 0x4D, 0x01, 0xFE, 0xFC, 0x56,
- 0x06, 0xF7, 0xF1, 0xBF, 0x37, 0x15, 0x28, 0x18, 0xF2, 0x25, 0x07,
- 0x34, 0xFC, 0xDC, 0x01, 0x3F, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0C,
- 0x00, 0xCF, 0xFF, 0x52, 0x00, 0xC0, 0xFF, 0xAC, 0xFF, 0x0C, 0x02,
- 0xBC, 0xF8, 0x6D, 0x45, 0x8E, 0x12, 0x24, 0xF7, 0x4D, 0x05, 0xDB,
- 0xFC, 0xAE, 0x01, 0x48, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00,
- 0x24, 0x00, 0x71, 0xFF, 0x43, 0x01, 0xC9, 0xFD, 0x60, 0x03, 0x2E,
- 0xFB, 0x7E, 0x07, 0xAF, 0x48, 0x2D, 0x00, 0x58, 0xFE, 0xBB, 0x01,
- 0xA3, 0xFE, 0xDD, 0x00, 0x99, 0xFF, 0x19, 0x00, 0xFE, 0xFF, 0x36,
- 0x00, 0x37, 0xFF, 0xDD, 0x01, 0x60, 0xFC, 0x6D, 0x06, 0x76, 0xF4,
- 0xD8, 0x1B, 0x95, 0x40, 0xC3, 0xF4, 0x56, 0x04, 0x4E, 0xFE, 0x85,
- 0x00, 0xF1, 0xFF, 0xF4, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x29, 0x00,
- 0x60, 0xFF, 0xA2, 0x01, 0x7C, 0xFC, 0xFB, 0x06, 0x7C, 0xF1, 0x15,
- 0x31, 0x73, 0x2F, 0x81, 0xF1, 0x10, 0x07, 0x67, 0xFC, 0xB1, 0x01,
- 0x58, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0x06, 0x00, 0xEE, 0xFF, 0x02,
- 0x00, 0x63, 0x00, 0x8A, 0xFE, 0xF3, 0x03, 0x63, 0xF5, 0xA1, 0x41,
- 0x12, 0x1A, 0xEB, 0xF4, 0x3F, 0x06, 0x72, 0xFC, 0xD7, 0x01, 0x39,
- 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x91, 0xFF, 0xF1, 0x00,
- 0x79, 0xFE, 0x0A, 0x02, 0xC3, 0xFD, 0x73, 0x01, 0xDB, 0x48, 0x07,
- 0x06, 0xC7, 0xFB, 0x12, 0x03, 0xF1, 0xFD, 0x31, 0x01, 0x78, 0xFF,
- 0x22, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x43, 0xFF, 0xBA,
- 0x01, 0xBF, 0xFC, 0x8B, 0x05, 0x99, 0xF6, 0x43, 0x14, 0xA9, 0x44,
- 0xDE, 0xF7, 0x85, 0x02, 0x65, 0xFF, 0xE7, 0xFF, 0x3F, 0x00, 0xD6,
- 0xFF, 0x0A, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x44, 0xFF, 0xD5, 0x01,
- 0x3A, 0xFC, 0x2A, 0x07, 0xE3, 0xF1, 0xD1, 0x29, 0x46, 0x36, 0xC5,
- 0xF1, 0x87, 0x06, 0xDA, 0xFC, 0x64, 0x01, 0x80, 0xFF, 0x1E, 0x00,
- 0xFE, 0xFF, 0x01, 0x00, 0x08, 0x00, 0xBC, 0xFF, 0xEF, 0x00, 0x9A,
- 0xFD, 0x72, 0x05, 0x16, 0xF3, 0xA5, 0x3C, 0xC4, 0x21, 0x21, 0xF3,
- 0xE4, 0x06, 0x39, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD,
- 0xFF, 0x12, 0x00, 0xB3, 0xFF, 0x99, 0x00, 0x2E, 0xFF, 0xB6, 0x00,
- 0x36, 0x00, 0x47, 0xFC, 0x90, 0x47, 0xA4, 0x0C, 0x31, 0xF9, 0x5A,
- 0x04, 0x4E, 0xFD, 0x7C, 0x01, 0x5B, 0xFF, 0x2A, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x2B, 0x00, 0x59, 0xFF, 0x80, 0x01, 0x45, 0xFD, 0x6C,
- 0x04, 0x0B, 0xF9, 0x0B, 0x0D, 0x73, 0x47, 0x02, 0xFC, 0x58, 0x00,
- 0xA3, 0x00, 0x39, 0xFF, 0x94, 0x00, 0xB5, 0xFF, 0x12, 0x00, 0xFD,
- 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x37, 0xFC, 0xEB, 0x06,
- 0x0B, 0xF3, 0x35, 0x22, 0x52, 0x3C, 0xFD, 0xF2, 0x84, 0x05, 0x8D,
- 0xFD, 0xF6, 0x00, 0xB8, 0xFF, 0x09, 0x00, 0x01, 0x00, 0xFE, 0xFF,
- 0x1D, 0x00, 0x83, 0xFF, 0x5E, 0x01, 0xE3, 0xFC, 0x7B, 0x06, 0xD0,
- 0xF1, 0xA5, 0x36, 0x62, 0x29, 0xEF, 0xF1, 0x29, 0x07, 0x39, 0xFC,
- 0xD7, 0x01, 0x42, 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x0B, 0x00, 0xD5,
- 0xFF, 0x44, 0x00, 0xDD, 0xFF, 0x77, 0xFF, 0x67, 0x02, 0x14, 0xF8,
- 0xDC, 0x44, 0xD5, 0x13, 0xBC, 0xF6, 0x7C, 0x05, 0xC5, 0xFC, 0xB7,
- 0x01, 0x44, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x22, 0x00,
- 0x76, 0xFF, 0x35, 0x01, 0xE7, 0xFD, 0x26, 0x03, 0xA1, 0xFB, 0x64,
- 0x06, 0xD2, 0x48, 0x21, 0x01, 0xE8, 0xFD, 0xF7, 0x01, 0x83, 0xFE,
- 0xEC, 0x00, 0x93, 0xFF, 0x1A, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x39,
- 0xFF, 0xD9, 0x01, 0x6D, 0xFC, 0x4B, 0x06, 0xCD, 0xF4, 0x83, 0x1A,
- 0x5F, 0x41, 0x3A, 0xF5, 0x0C, 0x04, 0x7B, 0xFE, 0x6C, 0x00, 0xFE,
- 0xFF, 0xEF, 0xFF, 0x05, 0x00, 0xFD, 0xFF, 0x2B, 0x00, 0x5A, 0xFF,
- 0xAD, 0x01, 0x6C, 0xFC, 0x0C, 0x07, 0x7F, 0xF1, 0xDC, 0x2F, 0xAD,
- 0x30, 0x7D, 0xF1, 0x01, 0x07, 0x76, 0xFC, 0xA6, 0x01, 0x5E, 0xFF,
- 0x2A, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xF3, 0xFF, 0xF5, 0xFF, 0x7D,
- 0x00, 0x5D, 0xFE, 0x3E, 0x04, 0xEA, 0xF4, 0xD9, 0x40, 0x66, 0x1B,
- 0x93, 0xF4, 0x62, 0x06, 0x64, 0xFC, 0xDC, 0x01, 0x38, 0xFF, 0x36,
- 0x00, 0xFE, 0xFF, 0x19, 0x00, 0x97, 0xFF, 0xE2, 0x00, 0x98, 0xFE,
- 0xCF, 0x01, 0x33, 0xFE, 0x7D, 0x00, 0xBB, 0x48, 0x1F, 0x07, 0x54,
- 0xFB, 0x4C, 0x03, 0xD3, 0xFD, 0x3F, 0x01, 0x73, 0xFF, 0x23, 0x00,
- 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x46, 0xFF, 0xB1, 0x01, 0xD3,
- 0xFC, 0x5D, 0x05, 0x01, 0xF7, 0xFB, 0x12, 0x3F, 0x45, 0x83, 0xF8,
- 0x2A, 0x02, 0x9A, 0xFF, 0xCA, 0xFF, 0x4E, 0x00, 0xD1, 0xFF, 0x0C,
- 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x40, 0xFF, 0xDA, 0x01, 0x35, 0xFC,
- 0x27, 0x07, 0x09, 0xF2, 0x85, 0x28, 0x63, 0x37, 0xE9, 0xF1, 0x63,
- 0x06, 0xF5, 0xFC, 0x53, 0x01, 0x89, 0xFF, 0x1A, 0x00, 0xFE, 0xFF,
- 0x00, 0x00, 0x0C, 0x00, 0xB1, 0xFF, 0x04, 0x01, 0x76, 0xFD, 0xA8,
- 0x05, 0xCC, 0xF2, 0xAB, 0x3B, 0x18, 0x23, 0xE0, 0xF2, 0xF7, 0x06,
- 0x35, 0xFC, 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x11,
- 0x00, 0xB9, 0xFF, 0x8A, 0x00, 0x4D, 0xFF, 0x7D, 0x00, 0x9C, 0x00,
- 0x7B, 0xFB, 0x31, 0x47, 0xD9, 0x0D, 0xC0, 0xF8, 0x8F, 0x04, 0x34,
- 0xFD, 0x87, 0x01, 0x56, 0xFF, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x29, 0x00, 0x5E, 0xFF, 0x74, 0x01, 0x5F, 0xFD, 0x35, 0x04, 0x7C,
- 0xF9, 0xD8, 0x0B, 0xC9, 0x47, 0xD4, 0xFC, 0xF0, 0xFF, 0xDD, 0x00,
- 0x19, 0xFF, 0xA4, 0x00, 0xAF, 0xFF, 0x13, 0x00, 0xFD, 0xFF, 0x36,
- 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3D, 0xFC, 0xD5, 0x06, 0x4F, 0xF3,
- 0xE0, 0x20, 0x45, 0x3D, 0x4D, 0xF3, 0x4B, 0x05, 0xB3, 0xFD, 0xE0,
- 0x00, 0xC3, 0xFF, 0x05, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x20, 0x00,
- 0x7B, 0xFF, 0x6E, 0x01, 0xCA, 0xFC, 0x9D, 0x06, 0xB1, 0xF1, 0x86,
- 0x35, 0xAE, 0x2A, 0xCD, 0xF1, 0x2B, 0x07, 0x3F, 0xFC, 0xD1, 0x01,
- 0x46, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x0A, 0x00, 0xDA, 0xFF, 0x36,
- 0x00, 0xFA, 0xFF, 0x43, 0xFF, 0xBF, 0x02, 0x75, 0xF7, 0x42, 0x44,
- 0x20, 0x15, 0x55, 0xF6, 0xA9, 0x05, 0xB2, 0xFC, 0xBF, 0x01, 0x41,
- 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x21, 0x00, 0x7C, 0xFF,
- 0x27, 0x01, 0x05, 0xFE, 0xEB, 0x02, 0x14, 0xFC, 0x50, 0x05, 0xEA,
- 0x48, 0x1B, 0x02, 0x78, 0xFD, 0x32, 0x02, 0x64, 0xFE, 0xFA, 0x00,
- 0x8D, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD4,
- 0x01, 0x7C, 0xFC, 0x27, 0x06, 0x28, 0xF5, 0x31, 0x19, 0x21, 0x42,
- 0xB8, 0xF5, 0xC0, 0x03, 0xAA, 0xFE, 0x51, 0x00, 0x0B, 0x00, 0xEA,
- 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2D, 0x00, 0x54, 0xFF, 0xB7, 0x01,
- 0x5E, 0xFC, 0x19, 0x07, 0x88, 0xF1, 0x9F, 0x2E, 0xE3, 0x31, 0x7E,
- 0xF1, 0xEE, 0x06, 0x88, 0xFC, 0x9A, 0x01, 0x64, 0xFF, 0x28, 0x00,
- 0xFD, 0xFF, 0x04, 0x00, 0xF7, 0xFF, 0xE8, 0xFF, 0x96, 0x00, 0x31,
- 0xFE, 0x84, 0x04, 0x79, 0xF4, 0x07, 0x40, 0xBA, 0x1C, 0x3E, 0xF4,
- 0x82, 0x06, 0x58, 0xFC, 0xE0, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE,
- 0xFF, 0x18, 0x00, 0x9D, 0xFF, 0xD3, 0x00, 0xB8, 0xFE, 0x93, 0x01,
- 0xA1, 0xFE, 0x8E, 0xFF, 0x92, 0x48, 0x3D, 0x08, 0xE1, 0xFA, 0x86,
- 0x03, 0xB6, 0xFD, 0x4C, 0x01, 0x6D, 0xFF, 0x25, 0x00, 0x00, 0x00,
- 0xFF, 0xFF, 0x30, 0x00, 0x4A, 0xFF, 0xA8, 0x01, 0xE9, 0xFC, 0x2D,
- 0x05, 0x6B, 0xF7, 0xB6, 0x11, 0xC8, 0x45, 0x30, 0xF9, 0xCD, 0x01,
- 0xD0, 0xFF, 0xAC, 0xFF, 0x5C, 0x00, 0xCB, 0xFF, 0x0D, 0x00, 0xFD,
- 0xFF, 0x34, 0x00, 0x3E, 0xFF, 0xDF, 0x01, 0x33, 0xFC, 0x20, 0x07,
- 0x35, 0xF2, 0x36, 0x27, 0x78, 0x38, 0x14, 0xF2, 0x3B, 0x06, 0x11,
- 0xFD, 0x41, 0x01, 0x92, 0xFF, 0x17, 0x00, 0xFF, 0xFF, 0x00, 0x00,
- 0x10, 0x00, 0xA7, 0xFF, 0x19, 0x01, 0x53, 0xFD, 0xDB, 0x05, 0x88,
- 0xF2, 0xAD, 0x3A, 0x6D, 0x24, 0xA4, 0xF2, 0x08, 0x07, 0x32, 0xFC,
- 0xE5, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x10, 0x00, 0xBF,
- 0xFF, 0x7B, 0x00, 0x6C, 0xFF, 0x44, 0x00, 0x01, 0x01, 0xB6, 0xFA,
- 0xC8, 0x46, 0x13, 0x0F, 0x51, 0xF8, 0xC4, 0x04, 0x1B, 0xFD, 0x92,
- 0x01, 0x52, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x28, 0x00,
- 0x63, 0xFF, 0x67, 0x01, 0x7A, 0xFD, 0xFE, 0x03, 0xEE, 0xF9, 0xAA,
- 0x0A, 0x16, 0x48, 0xAC, 0xFD, 0x86, 0xFF, 0x17, 0x01, 0xFA, 0xFE,
- 0xB3, 0x00, 0xAA, 0xFF, 0x15, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36,
- 0xFF, 0xE5, 0x01, 0x44, 0xFC, 0xBD, 0x06, 0x97, 0xF3, 0x8A, 0x1F,
- 0x31, 0x3E, 0xA5, 0xF3, 0x0F, 0x05, 0xDA, 0xFD, 0xC9, 0x00, 0xCF,
- 0xFF, 0x01, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x22, 0x00, 0x73, 0xFF,
- 0x7D, 0x01, 0xB3, 0xFC, 0xBB, 0x06, 0x9A, 0xF1, 0x60, 0x34, 0xF5,
- 0x2B, 0xB0, 0xF1, 0x28, 0x07, 0x47, 0xFC, 0xCA, 0x01, 0x4A, 0xFF,
- 0x30, 0x00, 0xFD, 0xFF, 0x09, 0x00, 0xDF, 0xFF, 0x28, 0x00, 0x17,
- 0x00, 0x10, 0xFF, 0x15, 0x03, 0xDD, 0xF6, 0x9E, 0x43, 0x6C, 0x16,
- 0xF1, 0xF5, 0xD3, 0x05, 0x9F, 0xFC, 0xC6, 0x01, 0x3F, 0xFF, 0x33,
- 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x81, 0xFF, 0x19, 0x01,
- 0x23, 0xFE, 0xB0, 0x02, 0x87, 0xFC, 0x41, 0x04, 0xF4, 0x48, 0x1C,
- 0x03, 0x06, 0xFD, 0x6E, 0x02, 0x45, 0xFE, 0x09, 0x01, 0x88, 0xFF,
- 0x1D, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3C, 0xFF, 0xCE, 0x01, 0x8C,
- 0xFC, 0x00, 0x06, 0x86, 0xF5, 0xE0, 0x17, 0xDB, 0x42, 0x3F, 0xF6,
- 0x71, 0x03, 0xD9, 0xFE, 0x36, 0x00, 0x18, 0x00, 0xE5, 0xFF, 0x07,
- 0x00, 0xFD, 0xFF, 0x2F, 0x00, 0x4F, 0xFF, 0xC1, 0x01, 0x52, 0xFC,
- 0x22, 0x07, 0x98, 0xF1, 0x5E, 0x2D, 0x13, 0x33, 0x87, 0xF1, 0xD8,
- 0x06, 0x9B, 0xFC, 0x8D, 0x01, 0x6B, 0xFF, 0x25, 0x00, 0xFD, 0xFF,
- 0x03, 0x00, 0xFC, 0xFF, 0xDC, 0xFF, 0xAF, 0x00, 0x07, 0xFE, 0xC8,
- 0x04, 0x10, 0xF4, 0x2D, 0x3F, 0x0F, 0x1E, 0xED, 0xF3, 0xA0, 0x06,
- 0x4E, 0xFC, 0xE3, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x16,
- 0x00, 0xA3, 0xFF, 0xC3, 0x00, 0xD7, 0xFE, 0x58, 0x01, 0x0F, 0xFF,
- 0xA6, 0xFE, 0x5D, 0x48, 0x61, 0x09, 0x6E, 0xFA, 0xC0, 0x03, 0x99,
- 0xFD, 0x59, 0x01, 0x68, 0xFF, 0x26, 0x00, 0x00, 0x00, 0xFF, 0xFF,
- 0x2E, 0x00, 0x4E, 0xFF, 0x9E, 0x01, 0x00, 0xFD, 0xFC, 0x04, 0xD7,
- 0xF7, 0x75, 0x10, 0x48, 0x46, 0xE4, 0xF9, 0x6E, 0x01, 0x06, 0x00,
- 0x8E, 0xFF, 0x6B, 0x00, 0xC6, 0xFF, 0x0E, 0x00, 0xFD, 0xFF, 0x35,
- 0x00, 0x3B, 0xFF, 0xE2, 0x01, 0x31, 0xFC, 0x16, 0x07, 0x67, 0xF2,
- 0xE5, 0x25, 0x87, 0x39, 0x47, 0xF2, 0x10, 0x06, 0x30, 0xFD, 0x2F,
- 0x01, 0x9C, 0xFF, 0x14, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x13, 0x00,
- 0x9D, 0xFF, 0x2D, 0x01, 0x33, 0xFD, 0x0B, 0x06, 0x4D, 0xF2, 0xA5,
- 0x39, 0xBF, 0x25, 0x6D, 0xF2, 0x15, 0x07, 0x31, 0xFC, 0xE2, 0x01,
- 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0E, 0x00, 0xC5, 0xFF, 0x6D,
- 0x00, 0x8B, 0xFF, 0x0D, 0x00, 0x63, 0x01, 0xF9, 0xF9, 0x55, 0x46,
- 0x51, 0x10, 0xE3, 0xF7, 0xF7, 0x04, 0x03, 0xFD, 0x9D, 0x01, 0x4E,
- 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x26, 0x00, 0x68, 0xFF,
- 0x5B, 0x01, 0x96, 0xFD, 0xC6, 0x03, 0x61, 0xFA, 0x81, 0x09, 0x57,
- 0x48, 0x8D, 0xFE, 0x1B, 0xFF, 0x52, 0x01, 0xDB, 0xFE, 0xC2, 0x00,
- 0xA4, 0xFF, 0x16, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE3,
- 0x01, 0x4D, 0xFC, 0xA3, 0x06, 0xE4, 0xF3, 0x36, 0x1E, 0x16, 0x3F,
- 0x05, 0xF4, 0xCF, 0x04, 0x02, 0xFE, 0xB2, 0x00, 0xDB, 0xFF, 0xFC,
- 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x25, 0x00, 0x6C, 0xFF, 0x8B, 0x01,
- 0x9D, 0xFC, 0xD5, 0x06, 0x89, 0xF1, 0x35, 0x33, 0x3A, 0x2D, 0x9A,
- 0xF1, 0x23, 0x07, 0x51, 0xFC, 0xC2, 0x01, 0x4F, 0xFF, 0x2F, 0x00,
- 0xFD, 0xFF, 0x07, 0x00, 0xE5, 0xFF, 0x1A, 0x00, 0x33, 0x00, 0xDF,
- 0xFE, 0x68, 0x03, 0x4E, 0xF6, 0xEE, 0x42, 0xBB, 0x17, 0x90, 0xF5,
- 0xFC, 0x05, 0x8E, 0xFC, 0xCD, 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE,
- 0xFF, 0x1E, 0x00, 0x87, 0xFF, 0x0B, 0x01, 0x42, 0xFE, 0x74, 0x02,
- 0xF9, 0xFC, 0x39, 0x03, 0xF5, 0x48, 0x24, 0x04, 0x94, 0xFC, 0xA9,
- 0x02, 0x27, 0xFE, 0x18, 0x01, 0x82, 0xFF, 0x1F, 0x00, 0x00, 0x00,
- 0xFF, 0xFF, 0x33, 0x00, 0x3E, 0xFF, 0xC7, 0x01, 0x9D, 0xFC, 0xD8,
- 0x05, 0xE7, 0xF5, 0x91, 0x16, 0x89, 0x43, 0xCD, 0xF6, 0x1E, 0x03,
- 0x0B, 0xFF, 0x1A, 0x00, 0x26, 0x00, 0xE0, 0xFF, 0x08, 0x00, 0xFD,
- 0xFF, 0x30, 0x00, 0x4B, 0xFF, 0xC9, 0x01, 0x48, 0xFC, 0x28, 0x07,
- 0xAD, 0xF1, 0x19, 0x2C, 0x3F, 0x34, 0x97, 0xF1, 0xBE, 0x06, 0xB0,
- 0xFC, 0x7F, 0x01, 0x72, 0xFF, 0x23, 0x00, 0xFE, 0xFF, 0x02, 0x00,
- 0x00, 0x00, 0xD0, 0xFF, 0xC7, 0x00, 0xDE, 0xFD, 0x08, 0x05, 0xB0,
- 0xF3, 0x4A, 0x3E, 0x64, 0x1F, 0xA0, 0xF3, 0xBB, 0x06, 0x45, 0xFC,
- 0xE5, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x15, 0x00, 0xA9,
- 0xFF, 0xB4, 0x00, 0xF7, 0xFE, 0x1D, 0x01, 0x7A, 0xFF, 0xC5, 0xFD,
- 0x1D, 0x48, 0x89, 0x0A, 0xFB, 0xF9, 0xF8, 0x03, 0x7D, 0xFD, 0x66,
- 0x01, 0x63, 0xFF, 0x28, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2D, 0x00,
- 0x52, 0xFF, 0x93, 0x01, 0x18, 0xFD, 0xC9, 0x04, 0x45, 0xF8, 0x36,
- 0x0F, 0xBB, 0x46, 0xA1, 0xFA, 0x0C, 0x01, 0x3E, 0x00, 0x70, 0xFF,
- 0x7A, 0x00, 0xC0, 0xFF, 0x0F, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39,
- 0xFF, 0xE4, 0x01, 0x32, 0xFC, 0x09, 0x07, 0x9D, 0xF2, 0x92, 0x24,
- 0x8F, 0x3A, 0x82, 0xF2, 0xE1, 0x05, 0x50, 0xFD, 0x1B, 0x01, 0xA6,
- 0xFF, 0x10, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x17, 0x00, 0x93, 0xFF,
- 0x3F, 0x01, 0x15, 0xFD, 0x36, 0x06, 0x19, 0xF2, 0x97, 0x38, 0x11,
- 0x27, 0x3B, 0xF2, 0x1F, 0x07, 0x32, 0xFC, 0xDF, 0x01, 0x3D, 0xFF,
- 0x34, 0x00, 0xFD, 0xFF, 0x0D, 0x00, 0xCB, 0xFF, 0x5E, 0x00, 0xA9,
- 0xFF, 0xD6, 0xFF, 0xC3, 0x01, 0x43, 0xF9, 0xD7, 0x45, 0x92, 0x11,
- 0x77, 0xF7, 0x28, 0x05, 0xEC, 0xFC, 0xA7, 0x01, 0x4A, 0xFF, 0x2F,
- 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6D, 0xFF, 0x4E, 0x01,
- 0xB3, 0xFD, 0x8D, 0x03, 0xD4, 0xFA, 0x5D, 0x08, 0x8D, 0x48, 0x74,
- 0xFF, 0xAE, 0xFE, 0x8D, 0x01, 0xBB, 0xFE, 0xD1, 0x00, 0x9E, 0xFF,
- 0x18, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE0, 0x01, 0x57,
- 0xFC, 0x85, 0x06, 0x34, 0xF4, 0xE0, 0x1C, 0xF0, 0x3F, 0x6D, 0xF4,
- 0x8C, 0x04, 0x2C, 0xFE, 0x99, 0x00, 0xE7, 0xFF, 0xF8, 0xFF, 0x04,
- 0x00, 0xFD, 0xFF, 0x27, 0x00, 0x65, 0xFF, 0x98, 0x01, 0x8A, 0xFC,
- 0xEC, 0x06, 0x7F, 0xF1, 0x04, 0x32, 0x7B, 0x2E, 0x8A, 0xF1, 0x1A,
- 0x07, 0x5D, 0xFC, 0xB8, 0x01, 0x54, 0xFF, 0x2D, 0x00, 0xFD, 0xFF,
- 0x06, 0x00, 0xEA, 0xFF, 0x0C, 0x00, 0x4E, 0x00, 0xAF, 0xFE, 0xB8,
- 0x03, 0xC7, 0xF5, 0x38, 0x42, 0x0C, 0x19, 0x32, 0xF5, 0x23, 0x06,
- 0x7D, 0xFC, 0xD3, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1C,
- 0x00, 0x8D, 0xFF, 0xFC, 0x00, 0x61, 0xFE, 0x39, 0x02, 0x6B, 0xFD,
- 0x37, 0x02, 0xEB, 0x48, 0x31, 0x05, 0x21, 0xFC, 0xE4, 0x02, 0x08,
- 0xFE, 0x26, 0x01, 0x7C, 0xFF, 0x21, 0x00, 0x00, 0x00, 0xFF, 0xFF,
- 0x32, 0x00, 0x41, 0xFF, 0xC0, 0x01, 0xAF, 0xFC, 0xAD, 0x05, 0x4A,
- 0xF6, 0x44, 0x15, 0x2F, 0x44, 0x64, 0xF7, 0xC9, 0x02, 0x3D, 0xFF,
- 0xFE, 0xFF, 0x34, 0x00, 0xDB, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x32,
- 0x00, 0x47, 0xFF, 0xD0, 0x01, 0x40, 0xFC, 0x2A, 0x07, 0xCA, 0xF1,
- 0xD1, 0x2A, 0x65, 0x35, 0xAE, 0xF1, 0xA0, 0x06, 0xC7, 0xFC, 0x70,
- 0x01, 0x7A, 0xFF, 0x20, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x05, 0x00,
- 0xC5, 0xFF, 0xDE, 0x00, 0xB7, 0xFD, 0x45, 0x05, 0x56, 0xF3, 0x61,
- 0x3D, 0xBA, 0x20, 0x56, 0xF3, 0xD3, 0x06, 0x3E, 0xFC, 0xE6, 0x01,
- 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x13, 0x00, 0xAF, 0xFF, 0xA5,
- 0x00, 0x16, 0xFF, 0xE3, 0x00, 0xE4, 0xFF, 0xEB, 0xFC, 0xD2, 0x47,
- 0xB6, 0x0B, 0x89, 0xF9, 0x2F, 0x04, 0x62, 0xFD, 0x72, 0x01, 0x5E,
- 0xFF, 0x29, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2C, 0x00, 0x56, 0xFF,
- 0x88, 0x01, 0x31, 0xFD, 0x95, 0x04, 0xB4, 0xF8, 0xFC, 0x0D, 0x26,
- 0x47, 0x64, 0xFB, 0xA7, 0x00, 0x77, 0x00, 0x51, 0xFF, 0x89, 0x00,
- 0xBA, 0xFF, 0x11, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE6,
- 0x01, 0x34, 0xFC, 0xF9, 0x06, 0xD9, 0xF2, 0x3F, 0x23, 0x90, 0x3B,
- 0xC4, 0xF2, 0xAE, 0x05, 0x72, 0xFD, 0x07, 0x01, 0xB0, 0xFF, 0x0C,
- 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1A, 0x00, 0x8A, 0xFF, 0x51, 0x01,
- 0xF8, 0xFC, 0x5E, 0x06, 0xED, 0xF1, 0x82, 0x37, 0x60, 0x28, 0x0E,
- 0xF2, 0x26, 0x07, 0x35, 0xFC, 0xDB, 0x01, 0x40, 0xFF, 0x34, 0x00,
- 0xFD, 0xFF, 0x0C, 0x00, 0xD0, 0xFF, 0x4F, 0x00, 0xC7, 0xFF, 0xA0,
- 0xFF, 0x20, 0x02, 0x96, 0xF8, 0x4E, 0x45, 0xD7, 0x12, 0x0D, 0xF7,
- 0x58, 0x05, 0xD6, 0xFC, 0xB0, 0x01, 0x47, 0xFF, 0x30, 0x00, 0xFF,
- 0xFF, 0x00, 0x00, 0x23, 0x00, 0x72, 0xFF, 0x40, 0x01, 0xD0, 0xFD,
- 0x53, 0x03, 0x47, 0xFB, 0x3F, 0x07, 0xB8, 0x48, 0x62, 0x00, 0x3F,
- 0xFE, 0xC8, 0x01, 0x9C, 0xFE, 0xE0, 0x00, 0x98, 0xFF, 0x19, 0x00,
- 0xFE, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xDC, 0x01, 0x63, 0xFC, 0x66,
- 0x06, 0x89, 0xF4, 0x8C, 0x1B, 0xC3, 0x40, 0xDD, 0xF4, 0x46, 0x04,
- 0x58, 0xFE, 0x80, 0x00, 0xF4, 0xFF, 0xF3, 0xFF, 0x05, 0x00, 0xFD,
- 0xFF, 0x29, 0x00, 0x5F, 0xFF, 0xA5, 0x01, 0x78, 0xFC, 0xFF, 0x06,
- 0x7D, 0xF1, 0xCF, 0x30, 0xB8, 0x2F, 0x80, 0xF1, 0x0D, 0x07, 0x6A,
- 0xFC, 0xAE, 0x01, 0x59, 0xFF, 0x2B, 0x00, 0xFD, 0xFF, 0x05, 0x00,
- 0xEF, 0xFF, 0xFF, 0xFF, 0x69, 0x00, 0x80, 0xFE, 0x04, 0x04, 0x48,
- 0xF5, 0x74, 0x41, 0x5D, 0x1A, 0xD7, 0xF4, 0x47, 0x06, 0x6F, 0xFC,
- 0xD8, 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x93,
- 0xFF, 0xED, 0x00, 0x80, 0xFE, 0xFD, 0x01, 0xDC, 0xFD, 0x3C, 0x01,
- 0xD5, 0x48, 0x45, 0x06, 0xAE, 0xFB, 0x1F, 0x03, 0xEA, 0xFD, 0x34,
- 0x01, 0x77, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00,
- 0x44, 0xFF, 0xB8, 0x01, 0xC3, 0xFC, 0x81, 0x05, 0xB0, 0xF6, 0xFA,
- 0x13, 0xCC, 0x44, 0x02, 0xF8, 0x71, 0x02, 0x71, 0xFF, 0xE1, 0xFF,
- 0x42, 0x00, 0xD5, 0xFF, 0x0B, 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x43,
- 0xFF, 0xD6, 0x01, 0x39, 0xFC, 0x2A, 0x07, 0xEB, 0xF1, 0x87, 0x29,
- 0x85, 0x36, 0xCC, 0xF1, 0x7F, 0x06, 0xE0, 0xFC, 0x60, 0x01, 0x82,
- 0xFF, 0x1D, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x09, 0x00, 0xBA, 0xFF,
- 0xF4, 0x00, 0x91, 0xFD, 0x7E, 0x05, 0x05, 0xF3, 0x6E, 0x3C, 0x10,
- 0x22, 0x12, 0xF3, 0xE9, 0x06, 0x38, 0xFC, 0xE6, 0x01, 0x37, 0xFF,
- 0x36, 0x00, 0xFD, 0xFF, 0x12, 0x00, 0xB5, 0xFF, 0x96, 0x00, 0x35,
- 0xFF, 0xA9, 0x00, 0x4D, 0x00, 0x19, 0xFC, 0x7C, 0x47, 0xE8, 0x0C,
- 0x18, 0xF9, 0x66, 0x04, 0x48, 0xFD, 0x7E, 0x01, 0x5A, 0xFF, 0x2B,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5A, 0xFF, 0x7D, 0x01,
- 0x4B, 0xFD, 0x60, 0x04, 0x24, 0xF9, 0xC6, 0x0C, 0x86, 0x47, 0x30,
- 0xFC, 0x41, 0x00, 0xB0, 0x00, 0x32, 0xFF, 0x98, 0x00, 0xB4, 0xFF,
- 0x12, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x38,
- 0xFC, 0xE6, 0x06, 0x19, 0xF3, 0xEA, 0x21, 0x8A, 0x3C, 0x0E, 0xF3,
- 0x78, 0x05, 0x96, 0xFD, 0xF1, 0x00, 0xBB, 0xFF, 0x08, 0x00, 0x01,
- 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x81, 0xFF, 0x62, 0x01, 0xDD, 0xFC,
- 0x83, 0x06, 0xC9, 0xF1, 0x66, 0x36, 0xAC, 0x29, 0xE7, 0xF1, 0x2A,
- 0x07, 0x3A, 0xFC, 0xD5, 0x01, 0x43, 0xFF, 0x33, 0x00, 0xFD, 0xFF,
- 0x0B, 0x00, 0xD6, 0xFF, 0x41, 0x00, 0xE4, 0xFF, 0x6B, 0xFF, 0x7B,
- 0x02, 0xF0, 0xF7, 0xBA, 0x44, 0x1E, 0x14, 0xA5, 0xF6, 0x86, 0x05,
- 0xC1, 0xFC, 0xB9, 0x01, 0x44, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00,
- 0x00, 0x22, 0x00, 0x77, 0xFF, 0x32, 0x01, 0xED, 0xFD, 0x19, 0x03,
- 0xBB, 0xFB, 0x26, 0x06, 0xD7, 0x48, 0x58, 0x01, 0xCF, 0xFD, 0x04,
- 0x02, 0x7D, 0xFE, 0xEF, 0x00, 0x92, 0xFF, 0x1B, 0x00, 0xFE, 0xFF,
- 0x35, 0x00, 0x39, 0xFF, 0xD8, 0x01, 0x70, 0xFC, 0x43, 0x06, 0xE1,
- 0xF4, 0x38, 0x1A, 0x8C, 0x41, 0x55, 0xF5, 0xFC, 0x03, 0x85, 0xFE,
- 0x66, 0x00, 0x01, 0x00, 0xEE, 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2B,
- 0x00, 0x59, 0xFF, 0xB0, 0x01, 0x69, 0xFC, 0x0F, 0x07, 0x80, 0xF1,
- 0x96, 0x2F, 0xF2, 0x30, 0x7C, 0xF1, 0xFD, 0x06, 0x7A, 0xFC, 0xA3,
- 0x01, 0x5F, 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xF4, 0xFF,
- 0xF2, 0xFF, 0x83, 0x00, 0x53, 0xFE, 0x4E, 0x04, 0xD0, 0xF4, 0xAB,
- 0x40, 0xB2, 0x1B, 0x7F, 0xF4, 0x69, 0x06, 0x62, 0xFC, 0xDD, 0x01,
- 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x19, 0x00, 0x98, 0xFF, 0xDE,
- 0x00, 0x9F, 0xFE, 0xC2, 0x01, 0x4B, 0xFE, 0x48, 0x00, 0xB3, 0x48,
- 0x5E, 0x07, 0x3B, 0xFB, 0x59, 0x03, 0xCD, 0xFD, 0x42, 0x01, 0x71,
- 0xFF, 0x24, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30, 0x00, 0x47, 0xFF,
- 0xAF, 0x01, 0xD8, 0xFC, 0x52, 0x05, 0x19, 0xF7, 0xB2, 0x12, 0x5C,
- 0x45, 0xA9, 0xF8, 0x16, 0x02, 0xA6, 0xFF, 0xC3, 0xFF, 0x51, 0x00,
- 0xD0, 0xFF, 0x0C, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x40, 0xFF, 0xDB,
- 0x01, 0x35, 0xFC, 0x25, 0x07, 0x13, 0xF2, 0x3A, 0x28, 0xA0, 0x37,
- 0xF2, 0xF1, 0x5A, 0x06, 0xFB, 0xFC, 0x4F, 0x01, 0x8B, 0xFF, 0x1A,
- 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0D, 0x00, 0xAF, 0xFF, 0x09, 0x01,
- 0x6E, 0xFD, 0xB4, 0x05, 0xBC, 0xF2, 0x73, 0x3B, 0x64, 0x23, 0xD2,
- 0xF2, 0xFB, 0x06, 0x34, 0xFC, 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00,
- 0xFD, 0xFF, 0x11, 0x00, 0xBB, 0xFF, 0x87, 0x00, 0x54, 0xFF, 0x70,
- 0x00, 0xB3, 0x00, 0x4E, 0xFB, 0x1A, 0x47, 0x1F, 0x0E, 0xA8, 0xF8,
- 0x9B, 0x04, 0x2E, 0xFD, 0x8A, 0x01, 0x55, 0xFF, 0x2C, 0x00, 0xFF,
- 0xFF, 0x00, 0x00, 0x29, 0x00, 0x5F, 0xFF, 0x71, 0x01, 0x65, 0xFD,
- 0x29, 0x04, 0x96, 0xF9, 0x95, 0x0B, 0xDC, 0x47, 0x03, 0xFD, 0xD9,
- 0xFF, 0xEA, 0x00, 0x12, 0xFF, 0xA7, 0x00, 0xAE, 0xFF, 0x14, 0x00,
- 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3E, 0xFC, 0xD0,
- 0x06, 0x5E, 0xF3, 0x94, 0x20, 0x7B, 0x3D, 0x60, 0xF3, 0x3E, 0x05,
- 0xBB, 0xFD, 0xDB, 0x00, 0xC6, 0xFF, 0x04, 0x00, 0x02, 0x00, 0xFE,
- 0xFF, 0x20, 0x00, 0x79, 0xFF, 0x72, 0x01, 0xC4, 0xFC, 0xA4, 0x06,
- 0xAB, 0xF1, 0x46, 0x35, 0xF7, 0x2A, 0xC6, 0xF1, 0x2A, 0x07, 0x40,
- 0xFC, 0xCF, 0x01, 0x47, 0xFF, 0x31, 0x00, 0xFD, 0xFF, 0x09, 0x00,
- 0xDB, 0xFF, 0x33, 0x00, 0x01, 0x00, 0x38, 0xFF, 0xD3, 0x02, 0x53,
- 0xF7, 0x1F, 0x44, 0x69, 0x15, 0x3F, 0xF6, 0xB2, 0x05, 0xAD, 0xFC,
- 0xC1, 0x01, 0x41, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x20,
- 0x00, 0x7D, 0xFF, 0x24, 0x01, 0x0C, 0xFE, 0xDE, 0x02, 0x2E, 0xFC,
- 0x13, 0x05, 0xEC, 0x48, 0x54, 0x02, 0x5E, 0xFD, 0x3F, 0x02, 0x5D,
- 0xFE, 0xFE, 0x00, 0x8C, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, 0x35, 0x00,
- 0x3B, 0xFF, 0xD3, 0x01, 0x7F, 0xFC, 0x1F, 0x06, 0x3C, 0xF5, 0xE6,
- 0x18, 0x4D, 0x42, 0xD5, 0xF5, 0xAF, 0x03, 0xB4, 0xFE, 0x4B, 0x00,
- 0x0E, 0x00, 0xE9, 0xFF, 0x07, 0x00, 0xFD, 0xFF, 0x2D, 0x00, 0x53,
- 0xFF, 0xBA, 0x01, 0x5B, 0xFC, 0x1B, 0x07, 0x8B, 0xF1, 0x58, 0x2E,
- 0x26, 0x32, 0x80, 0xF1, 0xEA, 0x06, 0x8C, 0xFC, 0x97, 0x01, 0x66,
- 0xFF, 0x27, 0x00, 0xFD, 0xFF, 0x04, 0x00, 0xF8, 0xFF, 0xE6, 0xFF,
- 0x9C, 0x00, 0x27, 0xFE, 0x94, 0x04, 0x61, 0xF4, 0xD7, 0x3F, 0x06,
- 0x1D, 0x2B, 0xF4, 0x89, 0x06, 0x56, 0xFC, 0xE0, 0x01, 0x37, 0xFF,
- 0x36, 0x00, 0xFE, 0xFF, 0x17, 0x00, 0x9E, 0xFF, 0xCF, 0x00, 0xBF,
- 0xFE, 0x86, 0x01, 0xBA, 0xFE, 0x5A, 0xFF, 0x86, 0x48, 0x7D, 0x08,
- 0xC7, 0xFA, 0x93, 0x03, 0xB0, 0xFD, 0x4F, 0x01, 0x6C, 0xFF, 0x25,
- 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4B, 0xFF, 0xA6, 0x01,
- 0xEE, 0xFC, 0x23, 0x05, 0x83, 0xF7, 0x6E, 0x11, 0xE5, 0x45, 0x57,
- 0xF9, 0xB8, 0x01, 0xDC, 0xFF, 0xA5, 0xFF, 0x5F, 0x00, 0xCA, 0xFF,
- 0x0D, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3D, 0xFF, 0xDF, 0x01, 0x32,
- 0xFC, 0x1E, 0x07, 0x40, 0xF2, 0xEB, 0x26, 0xB5, 0x38, 0x1F, 0xF2,
- 0x32, 0x06, 0x18, 0xFD, 0x3D, 0x01, 0x94, 0xFF, 0x16, 0x00, 0xFF,
- 0xFF, 0x00, 0x00, 0x11, 0x00, 0xA4, 0xFF, 0x1D, 0x01, 0x4C, 0xFD,
- 0xE6, 0x05, 0x7B, 0xF2, 0x71, 0x3A, 0xB8, 0x24, 0x97, 0xF2, 0x0B,
- 0x07, 0x32, 0xFC, 0xE4, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF,
- 0x0F, 0x00, 0xC0, 0xFF, 0x78, 0x00, 0x73, 0xFF, 0x38, 0x00, 0x17,
- 0x01, 0x8B, 0xFA, 0xAF, 0x46, 0x59, 0x0F, 0x39, 0xF8, 0xCF, 0x04,
- 0x15, 0xFD, 0x95, 0x01, 0x51, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x00,
- 0x00, 0x28, 0x00, 0x64, 0xFF, 0x65, 0x01, 0x81, 0xFD, 0xF2, 0x03,
- 0x08, 0xFA, 0x68, 0x0A, 0x25, 0x48, 0xDE, 0xFD, 0x6E, 0xFF, 0x24,
- 0x01, 0xF3, 0xFE, 0xB6, 0x00, 0xA8, 0xFF, 0x15, 0x00, 0xFD, 0xFF,
- 0x36, 0x00, 0x36, 0xFF, 0xE5, 0x01, 0x46, 0xFC, 0xB8, 0x06, 0xA8,
- 0xF3, 0x3F, 0x1F, 0x64, 0x3E, 0xBA, 0xF3, 0x01, 0x05, 0xE2, 0xFD,
- 0xC4, 0x00, 0xD2, 0xFF, 0x00, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x23,
- 0x00, 0x71, 0xFF, 0x81, 0x01, 0xAE, 0xFC, 0xC1, 0x06, 0x95, 0xF1,
- 0x1E, 0x34, 0x3E, 0x2C, 0xAB, 0xF1, 0x27, 0x07, 0x49, 0xFC, 0xC8,
- 0x01, 0x4B, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x08, 0x00, 0xE1, 0xFF,
- 0x25, 0x00, 0x1D, 0x00, 0x05, 0xFF, 0x28, 0x03, 0xBD, 0xF6, 0x77,
- 0x43, 0xB6, 0x16, 0xDC, 0xF5, 0xDD, 0x05, 0x9B, 0xFC, 0xC8, 0x01,
- 0x3E, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x83,
- 0xFF, 0x16, 0x01, 0x2A, 0xFE, 0xA3, 0x02, 0xA1, 0xFC, 0x06, 0x04,
- 0xF5, 0x48, 0x56, 0x03, 0xED, 0xFC, 0x7B, 0x02, 0x3E, 0xFE, 0x0C,
- 0x01, 0x86, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3D, 0xFF,
- 0xCC, 0x01, 0x8F, 0xFC, 0xF8, 0x05, 0x9B, 0xF5, 0x96, 0x17, 0x02,
- 0x43, 0x5E, 0xF6, 0x5F, 0x03, 0xE4, 0xFE, 0x30, 0x00, 0x1B, 0x00,
- 0xE4, 0xFF, 0x08, 0x00, 0xFD, 0xFF, 0x2F, 0x00, 0x4E, 0xFF, 0xC3,
- 0x01, 0x4F, 0xFC, 0x24, 0x07, 0x9C, 0xF1, 0x17, 0x2D, 0x57, 0x33,
- 0x8A, 0xF1, 0xD3, 0x06, 0x9F, 0xFC, 0x8A, 0x01, 0x6D, 0xFF, 0x25,
- 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0xD9, 0xFF, 0xB4, 0x00,
- 0xFD, 0xFD, 0xD7, 0x04, 0xFA, 0xF3, 0xFC, 0x3E, 0x5B, 0x1E, 0xDB,
- 0xF3, 0xA6, 0x06, 0x4C, 0xFC, 0xE3, 0x01, 0x36, 0xFF, 0x36, 0x00,
- 0xFE, 0xFF, 0x16, 0x00, 0xA4, 0xFF, 0xC0, 0x00, 0xDE, 0xFE, 0x4B,
- 0x01, 0x27, 0xFF, 0x73, 0xFE, 0x4F, 0x48, 0xA2, 0x09, 0x54, 0xFA,
- 0xCC, 0x03, 0x93, 0xFD, 0x5C, 0x01, 0x67, 0xFF, 0x27, 0x00, 0x00,
- 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x4E, 0xFF, 0x9C, 0x01, 0x05, 0xFD,
- 0xF1, 0x04, 0xF0, 0xF7, 0x2D, 0x10, 0x61, 0x46, 0x0D, 0xFA, 0x58,
- 0x01, 0x13, 0x00, 0x87, 0xFF, 0x6E, 0x00, 0xC4, 0xFF, 0x0E, 0x00,
- 0xFD, 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xE3, 0x01, 0x31, 0xFC, 0x14,
- 0x07, 0x73, 0xF2, 0x99, 0x25, 0xC2, 0x39, 0x54, 0xF2, 0x05, 0x06,
- 0x37, 0xFD, 0x2B, 0x01, 0x9E, 0xFF, 0x13, 0x00, 0xFF, 0xFF, 0xFF,
- 0xFF, 0x14, 0x00, 0x9B, 0xFF, 0x31, 0x01, 0x2C, 0xFD, 0x15, 0x06,
- 0x41, 0xF2, 0x6A, 0x39, 0x0A, 0x26, 0x61, 0xF2, 0x17, 0x07, 0x31,
- 0xFC, 0xE2, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0E, 0x00,
- 0xC6, 0xFF, 0x69, 0x00, 0x91, 0xFF, 0x00, 0x00, 0x78, 0x01, 0xD0,
- 0xF9, 0x39, 0x46, 0x98, 0x10, 0xCB, 0xF7, 0x02, 0x05, 0xFE, 0xFC,
- 0x9F, 0x01, 0x4D, 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x26,
- 0x00, 0x69, 0xFF, 0x58, 0x01, 0x9D, 0xFD, 0xB9, 0x03, 0x7B, 0xFA,
- 0x40, 0x09, 0x63, 0x48, 0xBF, 0xFE, 0x03, 0xFF, 0x5F, 0x01, 0xD4,
- 0xFE, 0xC5, 0x00, 0xA2, 0xFF, 0x16, 0x00, 0xFE, 0xFF, 0x36, 0x00,
- 0x36, 0xFF, 0xE2, 0x01, 0x4F, 0xFC, 0x9C, 0x06, 0xF5, 0xF3, 0xEA,
- 0x1D, 0x47, 0x3F, 0x1B, 0xF4, 0xC1, 0x04, 0x0B, 0xFE, 0xAC, 0x00,
- 0xDE, 0xFF, 0xFB, 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x25, 0x00, 0x6A,
- 0xFF, 0x8E, 0x01, 0x99, 0xFC, 0xDB, 0x06, 0x86, 0xF1, 0xF2, 0x32,
- 0x82, 0x2D, 0x96, 0xF1, 0x21, 0x07, 0x53, 0xFC, 0xC0, 0x01, 0x50,
- 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE6, 0xFF, 0x17, 0x00,
- 0x39, 0x00, 0xD4, 0xFE, 0x7A, 0x03, 0x2F, 0xF6, 0xC7, 0x42, 0x06,
- 0x18, 0x7B, 0xF5, 0x05, 0x06, 0x8A, 0xFC, 0xCF, 0x01, 0x3C, 0xFF,
- 0x34, 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x88, 0xFF, 0x07, 0x01, 0x49,
- 0xFE, 0x67, 0x02, 0x13, 0xFD, 0xFF, 0x02, 0xF4, 0x48, 0x5F, 0x04,
- 0x7A, 0xFC, 0xB6, 0x02, 0x20, 0xFE, 0x1B, 0x01, 0x81, 0xFF, 0x1F,
- 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x3F, 0xFF, 0xC6, 0x01,
- 0xA1, 0xFC, 0xCF, 0x05, 0xFC, 0xF5, 0x47, 0x16, 0xB0, 0x43, 0xEE,
- 0xF6, 0x0C, 0x03, 0x16, 0xFF, 0x14, 0x00, 0x29, 0x00, 0xDF, 0xFF,
- 0x09, 0x00, 0xFD, 0xFF, 0x30, 0x00, 0x4A, 0xFF, 0xCA, 0x01, 0x46,
- 0xFC, 0x29, 0x07, 0xB3, 0xF1, 0xD1, 0x2B, 0x81, 0x34, 0x9C, 0xF1,
- 0xB8, 0x06, 0xB5, 0xFC, 0x7C, 0x01, 0x74, 0xFF, 0x22, 0x00, 0xFE,
- 0xFF, 0x02, 0x00, 0x01, 0x00, 0xCE, 0xFF, 0xCC, 0x00, 0xD5, 0xFD,
- 0x16, 0x05, 0x9B, 0xF3, 0x18, 0x3E, 0xB1, 0x1F, 0x8F, 0xF3, 0xC0,
- 0x06, 0x43, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF,
- 0x15, 0x00, 0xAA, 0xFF, 0xB1, 0x00, 0xFE, 0xFE, 0x10, 0x01, 0x92,
- 0xFF, 0x94, 0xFD, 0x0D, 0x48, 0xCB, 0x0A, 0xE2, 0xF9, 0x04, 0x04,
- 0x77, 0xFD, 0x69, 0x01, 0x62, 0xFF, 0x28, 0x00, 0x00, 0x00, 0xFF,
- 0xFF, 0x2D, 0x00, 0x52, 0xFF, 0x91, 0x01, 0x1E, 0xFD, 0xBE, 0x04,
- 0x5E, 0xF8, 0xF0, 0x0E, 0xD3, 0x46, 0xCB, 0xFA, 0xF6, 0x00, 0x4B,
- 0x00, 0x69, 0xFF, 0x7D, 0x00, 0xBE, 0xFF, 0x10, 0x00, 0xFD, 0xFF,
- 0x36, 0x00, 0x39, 0xFF, 0xE5, 0x01, 0x32, 0xFC, 0x06, 0x07, 0xAA,
- 0xF2, 0x46, 0x24, 0xC8, 0x3A, 0x90, 0xF2, 0xD6, 0x05, 0x57, 0xFD,
- 0x17, 0x01, 0xA8, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x18,
- 0x00, 0x91, 0xFF, 0x43, 0x01, 0x0E, 0xFD, 0x40, 0x06, 0x0F, 0xF2,
- 0x5B, 0x38, 0x5C, 0x27, 0x30, 0xF2, 0x21, 0x07, 0x33, 0xFC, 0xDE,
- 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0D, 0x00, 0xCC, 0xFF,
- 0x5A, 0x00, 0xAF, 0xFF, 0xCA, 0xFF, 0xD8, 0x01, 0x1C, 0xF9, 0xB8,
- 0x45, 0xDA, 0x11, 0x60, 0xF7, 0x33, 0x05, 0xE7, 0xFC, 0xA9, 0x01,
- 0x4A, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6E,
- 0xFF, 0x4B, 0x01, 0xB9, 0xFD, 0x80, 0x03, 0xEE, 0xFA, 0x1D, 0x08,
- 0x98, 0x48, 0xA8, 0xFF, 0x95, 0xFE, 0x9A, 0x01, 0xB4, 0xFE, 0xD4,
- 0x00, 0x9C, 0xFF, 0x18, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF,
- 0xDF, 0x01, 0x5A, 0xFC, 0x7E, 0x06, 0x47, 0xF4, 0x94, 0x1C, 0x1F,
- 0x40, 0x85, 0xF4, 0x7D, 0x04, 0x36, 0xFE, 0x93, 0x00, 0xEA, 0xFF,
- 0xF7, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x28, 0x00, 0x63, 0xFF, 0x9B,
- 0x01, 0x86, 0xFC, 0xF1, 0x06, 0x7E, 0xF1, 0xC0, 0x31, 0xC2, 0x2E,
- 0x87, 0xF1, 0x17, 0x07, 0x5F, 0xFC, 0xB6, 0x01, 0x55, 0xFF, 0x2D,
- 0x00, 0xFD, 0xFF, 0x06, 0x00, 0xEB, 0xFF, 0x09, 0x00, 0x54, 0x00,
- 0xA4, 0xFE, 0xC9, 0x03, 0xAA, 0xF5, 0x0C, 0x42, 0x56, 0x19, 0x1E,
- 0xF5, 0x2B, 0x06, 0x7A, 0xFC, 0xD4, 0x01, 0x3A, 0xFF, 0x35, 0x00,
- 0xFE, 0xFF, 0x1C, 0x00, 0x8E, 0xFF, 0xF9, 0x00, 0x68, 0xFE, 0x2C,
- 0x02, 0x84, 0xFD, 0xFF, 0x01, 0xE6, 0x48, 0x6E, 0x05, 0x07, 0xFC,
- 0xF1, 0x02, 0x01, 0xFE, 0x29, 0x01, 0x7B, 0xFF, 0x21, 0x00, 0x00,
- 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x42, 0xFF, 0xBE, 0x01, 0xB4, 0xFC,
- 0xA4, 0x05, 0x61, 0xF6, 0xFB, 0x14, 0x53, 0x44, 0x86, 0xF7, 0xB6,
- 0x02, 0x49, 0xFF, 0xF7, 0xFF, 0x37, 0x00, 0xD9, 0xFF, 0x0A, 0x00,
- 0xFD, 0xFF, 0x32, 0x00, 0x46, 0xFF, 0xD1, 0x01, 0x3E, 0xFC, 0x2B,
- 0x07, 0xD0, 0xF1, 0x89, 0x2A, 0xA6, 0x35, 0xB4, 0xF1, 0x99, 0x06,
- 0xCD, 0xFC, 0x6D, 0x01, 0x7C, 0xFF, 0x1F, 0x00, 0xFE, 0xFF, 0x01,
- 0x00, 0x06, 0x00, 0xC2, 0xFF, 0xE3, 0x00, 0xAE, 0xFD, 0x52, 0x05,
- 0x44, 0xF3, 0x2A, 0x3D, 0x06, 0x21, 0x47, 0xF3, 0xD8, 0x06, 0x3C,
- 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x13, 0x00,
- 0xB0, 0xFF, 0xA2, 0x00, 0x1D, 0xFF, 0xD6, 0x00, 0xFC, 0xFF, 0xBC,
- 0xFC, 0xC0, 0x47, 0xFA, 0x0B, 0x70, 0xF9, 0x3C, 0x04, 0x5C, 0xFD,
- 0x75, 0x01, 0x5D, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B,
- 0x00, 0x57, 0xFF, 0x86, 0x01, 0x36, 0xFD, 0x89, 0x04, 0xCD, 0xF8,
- 0xB7, 0x0D, 0x3D, 0x47, 0x91, 0xFB, 0x91, 0x00, 0x83, 0x00, 0x4A,
- 0xFF, 0x8C, 0x00, 0xB9, 0xFF, 0x11, 0x00, 0xFD, 0xFF, 0x36, 0x00,
- 0x38, 0xFF, 0xE6, 0x01, 0x35, 0xFC, 0xF5, 0x06, 0xE7, 0xF2, 0xF2,
- 0x22, 0xC7, 0x3B, 0xD4, 0xF2, 0xA2, 0x05, 0x7A, 0xFD, 0x02, 0x01,
- 0xB2, 0xFF, 0x0B, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x88,
- 0xFF, 0x55, 0x01, 0xF2, 0xFC, 0x67, 0x06, 0xE4, 0xF1, 0x44, 0x37,
- 0xAA, 0x28, 0x05, 0xF2, 0x27, 0x07, 0x36, 0xFC, 0xDA, 0x01, 0x41,
- 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x0B, 0x00, 0xD2, 0xFF, 0x4C, 0x00,
- 0xCD, 0xFF, 0x94, 0xFF, 0x34, 0x02, 0x70, 0xF8, 0x2E, 0x45, 0x20,
- 0x13, 0xF6, 0xF6, 0x62, 0x05, 0xD1, 0xFC, 0xB2, 0x01, 0x46, 0xFF,
- 0x31, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x23, 0x00, 0x73, 0xFF, 0x3D,
- 0x01, 0xD6, 0xFD, 0x46, 0x03, 0x61, 0xFB, 0x00, 0x07, 0xBF, 0x48,
- 0x98, 0x00, 0x26, 0xFE, 0xD5, 0x01, 0x95, 0xFE, 0xE3, 0x00, 0x96,
- 0xFF, 0x1A, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xDB, 0x01,
- 0x66, 0xFC, 0x5E, 0x06, 0x9C, 0xF4, 0x40, 0x1B, 0xEF, 0x40, 0xF7,
- 0xF4, 0x35, 0x04, 0x62, 0xFE, 0x7A, 0x00, 0xF7, 0xFF, 0xF2, 0xFF,
- 0x05, 0x00, 0xFD, 0xFF, 0x2A, 0x00, 0x5D, 0xFF, 0xA7, 0x01, 0x75,
- 0xFC, 0x03, 0x07, 0x7D, 0xF1, 0x8A, 0x30, 0xFF, 0x2F, 0x7E, 0xF1,
- 0x0A, 0x07, 0x6E, 0xFC, 0xAC, 0x01, 0x5A, 0xFF, 0x2B, 0x00, 0xFD,
- 0xFF, 0x05, 0x00, 0xF0, 0xFF, 0xFC, 0xFF, 0x6E, 0x00, 0x76, 0xFE,
- 0x15, 0x04, 0x2C, 0xF5, 0x49, 0x41, 0xA9, 0x1A, 0xC3, 0xF4, 0x4F,
- 0x06, 0x6C, 0xFC, 0xD9, 0x01, 0x38, 0xFF, 0x35, 0x00, 0xFE, 0xFF,
- 0x1A, 0x00, 0x94, 0xFF, 0xEA, 0x00, 0x87, 0xFE, 0xF0, 0x01, 0xF5,
- 0xFD, 0x05, 0x01, 0xCE, 0x48, 0x83, 0x06, 0x94, 0xFB, 0x2C, 0x03,
- 0xE4, 0xFD, 0x37, 0x01, 0x76, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFF,
- 0xFF, 0x31, 0x00, 0x45, 0xFF, 0xB6, 0x01, 0xC8, 0xFC, 0x77, 0x05,
- 0xC7, 0xF6, 0xB1, 0x13, 0xED, 0x44, 0x26, 0xF8, 0x5D, 0x02, 0x7D,
- 0xFF, 0xDA, 0xFF, 0x46, 0x00, 0xD4, 0xFF, 0x0B, 0x00, 0xFD, 0xFF,
- 0x33, 0x00, 0x42, 0xFF, 0xD7, 0x01, 0x38, 0xFC, 0x29, 0x07, 0xF3,
- 0xF1, 0x3E, 0x29, 0xC6, 0x36, 0xD4, 0xF1, 0x77, 0x06, 0xE6, 0xFC,
- 0x5C, 0x01, 0x84, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x0A,
- 0x00, 0xB7, 0xFF, 0xF9, 0x00, 0x89, 0xFD, 0x8A, 0x05, 0xF4, 0xF2,
- 0x37, 0x3C, 0x5B, 0x22, 0x03, 0xF3, 0xED, 0x06, 0x37, 0xFC, 0xE6,
- 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x12, 0x00, 0xB6, 0xFF,
- 0x93, 0x00, 0x3C, 0xFF, 0x9D, 0x00, 0x63, 0x00, 0xEB, 0xFB, 0x69,
- 0x47, 0x2D, 0x0D, 0xFF, 0xF8, 0x72, 0x04, 0x42, 0xFD, 0x81, 0x01,
- 0x59, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5B,
- 0xFF, 0x7A, 0x01, 0x50, 0xFD, 0x54, 0x04, 0x3D, 0xF9, 0x82, 0x0C,
- 0x9A, 0x47, 0x5E, 0xFC, 0x2A, 0x00, 0xBD, 0x00, 0x2B, 0xFF, 0x9B,
- 0x00, 0xB3, 0xFF, 0x12, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF,
- 0xE6, 0x01, 0x3A, 0xFC, 0xE2, 0x06, 0x28, 0xF3, 0x9E, 0x21, 0xC0,
- 0x3C, 0x1F, 0xF3, 0x6C, 0x05, 0x9E, 0xFD, 0xED, 0x00, 0xBD, 0xFF,
- 0x07, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1E, 0x00, 0x80, 0xFF, 0x66,
- 0x01, 0xD8, 0xFC, 0x8B, 0x06, 0xC1, 0xF1, 0x27, 0x36, 0xF6, 0x29,
- 0xDF, 0xF1, 0x2A, 0x07, 0x3B, 0xFC, 0xD4, 0x01, 0x44, 0xFF, 0x32,
- 0x00, 0xFD, 0xFF, 0x0A, 0x00, 0xD7, 0xFF, 0x3E, 0x00, 0xEA, 0xFF,
- 0x60, 0xFF, 0x8F, 0x02, 0xCD, 0xF7, 0x99, 0x44, 0x68, 0x14, 0x8E,
- 0xF6, 0x90, 0x05, 0xBC, 0xFC, 0xBA, 0x01, 0x43, 0xFF, 0x32, 0x00,
- 0xFF, 0xFF, 0x00, 0x00, 0x22, 0x00, 0x79, 0xFF, 0x2F, 0x01, 0xF4,
- 0xFD, 0x0C, 0x03, 0xD4, 0xFB, 0xE9, 0x05, 0xDE, 0x48, 0x8F, 0x01,
- 0xB6, 0xFD, 0x11, 0x02, 0x76, 0xFE, 0xF2, 0x00, 0x91, 0xFF, 0x1B,
- 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD7, 0x01, 0x73, 0xFC,
- 0x3B, 0x06, 0xF5, 0xF4, 0xED, 0x19, 0xB7, 0x41, 0x71, 0xF5, 0xEB,
- 0x03, 0x90, 0xFE, 0x60, 0x00, 0x04, 0x00, 0xED, 0xFF, 0x06, 0x00,
- 0xFD, 0xFF, 0x2C, 0x00, 0x57, 0xFF, 0xB2, 0x01, 0x65, 0xFC, 0x12,
- 0x07, 0x82, 0xF1, 0x50, 0x2F, 0x38, 0x31, 0x7C, 0xF1, 0xF9, 0x06,
- 0x7E, 0xFC, 0xA1, 0x01, 0x61, 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0x04,
- 0x00, 0xF5, 0xFF, 0xEF, 0xFF, 0x88, 0x00, 0x49, 0xFE, 0x5D, 0x04,
- 0xB7, 0xF4, 0x7D, 0x40, 0xFD, 0x1B, 0x6C, 0xF4, 0x70, 0x06, 0x5F,
- 0xFC, 0xDE, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x19, 0x00,
- 0x9A, 0xFF, 0xDB, 0x00, 0xA6, 0xFE, 0xB4, 0x01, 0x64, 0xFE, 0x12,
- 0x00, 0xAA, 0x48, 0x9E, 0x07, 0x21, 0xFB, 0x66, 0x03, 0xC6, 0xFD,
- 0x45, 0x01, 0x70, 0xFF, 0x24, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30,
- 0x00, 0x48, 0xFF, 0xAD, 0x01, 0xDD, 0xFC, 0x48, 0x05, 0x30, 0xF7,
- 0x6B, 0x12, 0x7D, 0x45, 0xCF, 0xF8, 0x01, 0x02, 0xB2, 0xFF, 0xBD,
- 0xFF, 0x54, 0x00, 0xCE, 0xFF, 0x0C, 0x00, 0xFD, 0xFF, 0x34, 0x00,
- 0x3F, 0xFF, 0xDC, 0x01, 0x34, 0xFC, 0x24, 0x07, 0x1C, 0xF2, 0xF0,
- 0x27, 0xDF, 0x37, 0xFB, 0xF1, 0x51, 0x06, 0x01, 0xFD, 0x4B, 0x01,
- 0x8D, 0xFF, 0x19, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0E, 0x00, 0xAC,
- 0xFF, 0x0E, 0x01, 0x66, 0xFD, 0xBF, 0x05, 0xAD, 0xF2, 0x3B, 0x3B,
- 0xB0, 0x23, 0xC4, 0xF2, 0xFF, 0x06, 0x33, 0xFC, 0xE5, 0x01, 0x38,
- 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x10, 0x00, 0xBC, 0xFF, 0x84, 0x00,
- 0x5B, 0xFF, 0x64, 0x00, 0xC9, 0x00, 0x22, 0xFB, 0x02, 0x47, 0x64,
- 0x0E, 0x8F, 0xF8, 0xA7, 0x04, 0x29, 0xFD, 0x8C, 0x01, 0x54, 0xFF,
- 0x2C, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x29, 0x00, 0x60, 0xFF, 0x6E,
- 0x01, 0x6B, 0xFD, 0x1D, 0x04, 0xAF, 0xF9, 0x51, 0x0B, 0xEC, 0x47,
- 0x33, 0xFD, 0xC1, 0xFF, 0xF7, 0x00, 0x0C, 0xFF, 0xAA, 0x00, 0xAD,
- 0xFF, 0x14, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01,
- 0x40, 0xFC, 0xCB, 0x06, 0x6E, 0xF3, 0x49, 0x20, 0xB0, 0x3D, 0x73,
- 0xF3, 0x31, 0x05, 0xC4, 0xFD, 0xD6, 0x00, 0xC8, 0xFF, 0x03, 0x00,
- 0x02, 0x00, 0xFE, 0xFF, 0x21, 0x00, 0x77, 0xFF, 0x75, 0x01, 0xBF,
- 0xFC, 0xAB, 0x06, 0xA6, 0xF1, 0x05, 0x35, 0x40, 0x2B, 0xBF, 0xF1,
- 0x2A, 0x07, 0x42, 0xFC, 0xCE, 0x01, 0x48, 0xFF, 0x31, 0x00, 0xFD,
- 0xFF, 0x09, 0x00, 0xDC, 0xFF, 0x2F, 0x00, 0x07, 0x00, 0x2C, 0xFF,
- 0xE6, 0x02, 0x31, 0xF7, 0xFA, 0x43, 0xB3, 0x15, 0x29, 0xF6, 0xBC,
- 0x05, 0xA9, 0xFC, 0xC2, 0x01, 0x40, 0xFF, 0x33, 0x00, 0xFF, 0xFF,
- 0x00, 0x00, 0x20, 0x00, 0x7E, 0xFF, 0x21, 0x01, 0x12, 0xFE, 0xD1,
- 0x02, 0x47, 0xFC, 0xD7, 0x04, 0xF0, 0x48, 0x8D, 0x02, 0x45, 0xFD,
- 0x4D, 0x02, 0x56, 0xFE, 0x01, 0x01, 0x8B, 0xFF, 0x1D, 0x00, 0xFE,
- 0xFF, 0x34, 0x00, 0x3B, 0xFF, 0xD1, 0x01, 0x83, 0xFC, 0x16, 0x06,
- 0x51, 0xF5, 0x9B, 0x18, 0x75, 0x42, 0xF3, 0xF5, 0x9D, 0x03, 0xBF,
- 0xFE, 0x45, 0x00, 0x11, 0x00, 0xE8, 0xFF, 0x07, 0x00, 0xFD, 0xFF,
- 0x2E, 0x00, 0x52, 0xFF, 0xBC, 0x01, 0x58, 0xFC, 0x1D, 0x07, 0x8E,
- 0xF1, 0x11, 0x2E, 0x6B, 0x32, 0x81, 0xF1, 0xE5, 0x06, 0x90, 0xFC,
- 0x94, 0x01, 0x67, 0xFF, 0x26, 0x00, 0xFD, 0xFF, 0x04, 0x00, 0xF9,
- 0xFF, 0xE3, 0xFF, 0xA1, 0x00, 0x1E, 0xFE, 0xA3, 0x04, 0x49, 0xF4,
- 0xA8, 0x3F, 0x52, 0x1D, 0x19, 0xF4, 0x90, 0x06, 0x53, 0xFC, 0xE1,
- 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x17, 0x00, 0xA0, 0xFF,
- 0xCC, 0x00, 0xC6, 0xFE, 0x79, 0x01, 0xD2, 0xFE, 0x26, 0xFF, 0x7C,
- 0x48, 0xBE, 0x08, 0xAE, 0xFA, 0xA0, 0x03, 0xA9, 0xFD, 0x52, 0x01,
- 0x6B, 0xFF, 0x25, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4C,
- 0xFF, 0xA3, 0x01, 0xF3, 0xFC, 0x18, 0x05, 0x9B, 0xF7, 0x27, 0x11,
- 0x02, 0x46, 0x7F, 0xF9, 0xA3, 0x01, 0xE8, 0xFF, 0x9F, 0xFF, 0x63,
- 0x00, 0xC9, 0xFF, 0x0D, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3C, 0xFF,
- 0xE0, 0x01, 0x32, 0xFC, 0x1C, 0x07, 0x4B, 0xF2, 0xA0, 0x26, 0xF2,
- 0x38, 0x2A, 0xF2, 0x28, 0x06, 0x1F, 0xFD, 0x39, 0x01, 0x96, 0xFF,
- 0x16, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x11, 0x00, 0xA2, 0xFF, 0x22,
- 0x01, 0x45, 0xFD, 0xF1, 0x05, 0x6D, 0xF2, 0x38, 0x3A, 0x03, 0x25,
- 0x8B, 0xF2, 0x0E, 0x07, 0x32, 0xFC, 0xE4, 0x01, 0x3A, 0xFF, 0x36,
- 0x00, 0xFD, 0xFF, 0x0F, 0x00, 0xC2, 0xFF, 0x75, 0x00, 0x7A, 0xFF,
- 0x2B, 0x00, 0x2D, 0x01, 0x61, 0xFA, 0x97, 0x46, 0xA0, 0x0F, 0x20,
- 0xF8, 0xDA, 0x04, 0x10, 0xFD, 0x97, 0x01, 0x50, 0xFF, 0x2E, 0x00,
- 0xFF, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x65, 0xFF, 0x62, 0x01, 0x87,
- 0xFD, 0xE5, 0x03, 0x21, 0xFA, 0x25, 0x0A, 0x33, 0x48, 0x0F, 0xFE,
- 0x57, 0xFF, 0x31, 0x01, 0xEC, 0xFE, 0xB9, 0x00, 0xA7, 0xFF, 0x15,
- 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4, 0x01, 0x48, 0xFC,
- 0xB2, 0x06, 0xB9, 0xF3, 0xF3, 0x1E, 0x98, 0x3E, 0xCF, 0xF3, 0xF3,
- 0x04, 0xEB, 0xFD, 0xBF, 0x00, 0xD4, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
- 0xFE, 0xFF, 0x23, 0x00, 0x70, 0xFF, 0x84, 0x01, 0xA9, 0xFC, 0xC7,
- 0x06, 0x91, 0xF1, 0xDC, 0x33, 0x87, 0x2C, 0xA5, 0xF1, 0x26, 0x07,
- 0x4B, 0xFC, 0xC6, 0x01, 0x4C, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x08,
- 0x00, 0xE2, 0xFF, 0x21, 0x00, 0x23, 0x00, 0xFA, 0xFE, 0x3A, 0x03,
- 0x9D, 0xF6, 0x50, 0x43, 0x00, 0x17, 0xC6, 0xF5, 0xE6, 0x05, 0x97,
- 0xFC, 0xC9, 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x00, 0x00,
- 0x1E, 0x00, 0x84, 0xFF, 0x13, 0x01, 0x31, 0xFE, 0x95, 0x02, 0xBA,
- 0xFC, 0xCB, 0x03, 0xF7, 0x48, 0x91, 0x03, 0xD3, 0xFC, 0x88, 0x02,
- 0x38, 0xFE, 0x10, 0x01, 0x85, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x34,
- 0x00, 0x3D, 0xFF, 0xCB, 0x01, 0x93, 0xFC, 0xEF, 0x05, 0xB0, 0xF5,
- 0x4B, 0x17, 0x2A, 0x43, 0x7D, 0xF6, 0x4D, 0x03, 0xEF, 0xFE, 0x2A,
- 0x00, 0x1E, 0x00, 0xE3, 0xFF, 0x08, 0x00, 0xFD, 0xFF, 0x2F, 0x00,
- 0x4D, 0xFF, 0xC4, 0x01, 0x4D, 0xFC, 0x25, 0x07, 0xA1, 0xF1, 0xCE,
- 0x2C, 0x99, 0x33, 0x8E, 0xF1, 0xCD, 0x06, 0xA4, 0xFC, 0x87, 0x01,
- 0x6E, 0xFF, 0x24, 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFE, 0xFF, 0xD7,
- 0xFF, 0xBA, 0x00, 0xF4, 0xFD, 0xE5, 0x04, 0xE4, 0xF3, 0xCA, 0x3E,
- 0xA7, 0x1E, 0xCA, 0xF3, 0xAC, 0x06, 0x4A, 0xFC, 0xE4, 0x01, 0x36,
- 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x16, 0x00, 0xA6, 0xFF, 0xBD, 0x00,
- 0xE5, 0xFE, 0x3E, 0x01, 0x3F, 0xFF, 0x41, 0xFE, 0x41, 0x48, 0xE4,
- 0x09, 0x3B, 0xFA, 0xD9, 0x03, 0x8D, 0xFD, 0x5F, 0x01, 0x66, 0xFF,
- 0x27, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x4F, 0xFF, 0x99,
- 0x01, 0x0B, 0xFD, 0xE6, 0x04, 0x08, 0xF8, 0xE7, 0x0F, 0x7C, 0x46,
- 0x37, 0xFA, 0x42, 0x01, 0x1F, 0x00, 0x81, 0xFF, 0x71, 0x00, 0xC3,
- 0xFF, 0x0F, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xE3, 0x01,
- 0x31, 0xFC, 0x11, 0x07, 0x7F, 0xF2, 0x4E, 0x25, 0xFD, 0x39, 0x60,
- 0xF2, 0xFB, 0x05, 0x3E, 0xFD, 0x26, 0x01, 0xA0, 0xFF, 0x12, 0x00,
- 0x00, 0x00, 0xFF, 0xFF, 0x15, 0x00, 0x98, 0xFF, 0x35, 0x01, 0x25,
- 0xFD, 0x1E, 0x06, 0x35, 0xF2, 0x2E, 0x39, 0x55, 0x26, 0x56, 0xF2,
- 0x1A, 0x07, 0x31, 0xFC, 0xE1, 0x01, 0x3C, 0xFF, 0x35, 0x00, 0xFD,
- 0xFF, 0x0E, 0x00, 0xC7, 0xFF, 0x66, 0x00, 0x98, 0xFF, 0xF4, 0xFF,
- 0x8E, 0x01, 0xA7, 0xF9, 0x1D, 0x46, 0xDF, 0x10, 0xB3, 0xF7, 0x0D,
- 0x05, 0xF8, 0xFC, 0xA1, 0x01, 0x4C, 0xFF, 0x2F, 0x00, 0xFF, 0xFF,
- 0x00, 0x00, 0x26, 0x00, 0x6A, 0xFF, 0x55, 0x01, 0xA3, 0xFD, 0xAD,
- 0x03, 0x94, 0xFA, 0xFF, 0x08, 0x70, 0x48, 0xF3, 0xFE, 0xEA, 0xFE,
- 0x6C, 0x01, 0xCD, 0xFE, 0xC9, 0x00, 0xA1, 0xFF, 0x17, 0x00, 0xFE,
- 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE2, 0x01, 0x51, 0xFC, 0x96, 0x06,
- 0x07, 0xF4, 0x9E, 0x1D, 0x77, 0x3F, 0x32, 0xF4, 0xB2, 0x04, 0x15,
- 0xFE, 0xA7, 0x00, 0xE0, 0xFF, 0xFA, 0xFF, 0x03, 0x00, 0xFD, 0xFF,
- 0x26, 0x00, 0x69, 0xFF, 0x91, 0x01, 0x94, 0xFC, 0xE0, 0x06, 0x84,
- 0xF1, 0xAF, 0x32, 0xCA, 0x2D, 0x92, 0xF1, 0x1F, 0x07, 0x56, 0xFC,
- 0xBE, 0x01, 0x51, 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE7,
- 0xFF, 0x14, 0x00, 0x3F, 0x00, 0xC9, 0xFE, 0x8C, 0x03, 0x11, 0xF6,
- 0x9E, 0x42, 0x50, 0x18, 0x66, 0xF5, 0x0D, 0x06, 0x86, 0xFC, 0xD0,
- 0x01, 0x3B, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x8A, 0xFF,
- 0x04, 0x01, 0x50, 0xFE, 0x5A, 0x02, 0x2C, 0xFD, 0xC6, 0x02, 0xF2,
- 0x48, 0x9B, 0x04, 0x61, 0xFC, 0xC3, 0x02, 0x19, 0xFE, 0x1E, 0x01,
- 0x7F, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x40,
- 0xFF, 0xC4, 0x01, 0xA5, 0xFC, 0xC5, 0x05, 0x13, 0xF6, 0xFD, 0x15,
- 0xD4, 0x43, 0x0F, 0xF7, 0xF9, 0x02, 0x21, 0xFF, 0x0D, 0x00, 0x2C,
- 0x00, 0xDE, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x31, 0x00, 0x49, 0xFF,
- 0xCC, 0x01, 0x44, 0xFC, 0x29, 0x07, 0xB9, 0xF1, 0x89, 0x2B, 0xC3,
- 0x34, 0xA0, 0xF1, 0xB1, 0x06, 0xBA, 0xFC, 0x79, 0x01, 0x76, 0xFF,
- 0x21, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x02, 0x00, 0xCB, 0xFF, 0xD1,
- 0x00, 0xCC, 0xFD, 0x24, 0x05, 0x87, 0xF3, 0xE4, 0x3D, 0xFD, 0x1F,
- 0x7F, 0xF3, 0xC6, 0x06, 0x41, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36,
- 0x00, 0xFD, 0xFF, 0x14, 0x00, 0xAC, 0xFF, 0xAE, 0x00, 0x05, 0xFF,
- 0x03, 0x01, 0xAA, 0xFF, 0x63, 0xFD, 0xFD, 0x47, 0x0E, 0x0B, 0xC8,
- 0xF9, 0x11, 0x04, 0x71, 0xFD, 0x6C, 0x01, 0x61, 0xFF, 0x28, 0x00,
- 0x00, 0x00, 0xFF, 0xFF, 0x2D, 0x00, 0x53, 0xFF, 0x8F, 0x01, 0x23,
- 0xFD, 0xB2, 0x04, 0x76, 0xF8, 0xAA, 0x0E, 0xED, 0x46, 0xF7, 0xFA,
- 0xDF, 0x00, 0x57, 0x00, 0x62, 0xFF, 0x80, 0x00, 0xBD, 0xFF, 0x10,
- 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE5, 0x01, 0x33, 0xFC,
- 0x03, 0x07, 0xB7, 0xF2, 0xFC, 0x23, 0x03, 0x3B, 0x9E, 0xF2, 0xCB,
- 0x05, 0x5F, 0xFD, 0x12, 0x01, 0xAA, 0xFF, 0x0E, 0x00, 0x00, 0x00,
- 0xFF, 0xFF, 0x18, 0x00, 0x8F, 0xFF, 0x47, 0x01, 0x08, 0xFD, 0x49,
- 0x06, 0x05, 0xF2, 0x1D, 0x38, 0xA6, 0x27, 0x26, 0xF2, 0x23, 0x07,
- 0x33, 0xFC, 0xDD, 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0C,
- 0x00, 0xCD, 0xFF, 0x57, 0x00, 0xB6, 0xFF, 0xBE, 0xFF, 0xED, 0x01,
- 0xF5, 0xF8, 0x9B, 0x45, 0x22, 0x12, 0x48, 0xF7, 0x3D, 0x05, 0xE2,
- 0xFC, 0xAB, 0x01, 0x49, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00,
- 0x24, 0x00, 0x6F, 0xFF, 0x48, 0x01, 0xC0, 0xFD, 0x73, 0x03, 0x07,
- 0xFB, 0xDD, 0x07, 0xA1, 0x48, 0xDD, 0xFF, 0x7D, 0xFE, 0xA7, 0x01,
- 0xAD, 0xFE, 0xD8, 0x00, 0x9B, 0xFF, 0x18, 0x00, 0xFE, 0xFF, 0x36,
- 0x00, 0x37, 0xFF, 0xDF, 0x01, 0x5C, 0xFC, 0x78, 0x06, 0x5A, 0xF4,
- 0x49, 0x1C, 0x4E, 0x40, 0x9E, 0xF4, 0x6D, 0x04, 0x3F, 0xFE, 0x8E,
- 0x00, 0xED, 0xFF, 0xF6, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x28, 0x00,
- 0x62, 0xFF, 0x9E, 0x01, 0x82, 0xFC, 0xF5, 0x06, 0x7D, 0xF1, 0x7B,
- 0x31, 0x09, 0x2F, 0x84, 0xF1, 0x15, 0x07, 0x62, 0xFC, 0xB4, 0x01,
- 0x56, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0x06, 0x00, 0xEC, 0xFF, 0x06,
- 0x00, 0x5A, 0x00, 0x9A, 0xFE, 0xDA, 0x03, 0x8D, 0xF5, 0xE1, 0x41,
- 0xA1, 0x19, 0x09, 0xF5, 0x33, 0x06, 0x77, 0xFC, 0xD6, 0x01, 0x3A,
- 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x8F, 0xFF, 0xF5, 0x00,
- 0x6F, 0xFE, 0x1E, 0x02, 0x9D, 0xFD, 0xC7, 0x01, 0xE1, 0x48, 0xAB,
- 0x05, 0xEE, 0xFB, 0xFE, 0x02, 0xFB, 0xFD, 0x2C, 0x01, 0x7A, 0xFF,
- 0x21, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x42, 0xFF, 0xBC,
- 0x01, 0xB8, 0xFC, 0x9A, 0x05, 0x77, 0xF6, 0xB1, 0x14, 0x77, 0x44,
- 0xA9, 0xF7, 0xA2, 0x02, 0x54, 0xFF, 0xF1, 0xFF, 0x3A, 0x00, 0xD8,
- 0xFF, 0x0A, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x45, 0xFF, 0xD3, 0x01,
- 0x3C, 0xFC, 0x2A, 0x07, 0xD8, 0xF1, 0x3F, 0x2A, 0xE6, 0x35, 0xBB,
- 0xF1, 0x92, 0x06, 0xD2, 0xFC, 0x69, 0x01, 0x7E, 0xFF, 0x1F, 0x00,
- 0xFE, 0xFF, 0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xE8, 0x00, 0xA6,
- 0xFD, 0x5F, 0x05, 0x31, 0xF3, 0xF6, 0x3C, 0x52, 0x21, 0x37, 0xF3,
- 0xDD, 0x06, 0x3B, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD,
- 0xFF, 0x13, 0x00, 0xB1, 0xFF, 0x9F, 0x00, 0x24, 0xFF, 0xC9, 0x00,
- 0x13, 0x00, 0x8D, 0xFC, 0xAE, 0x47, 0x3E, 0x0C, 0x56, 0xF9, 0x48,
- 0x04, 0x56, 0xFD, 0x78, 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x2B, 0x00, 0x58, 0xFF, 0x83, 0x01, 0x3C, 0xFD, 0x7E,
- 0x04, 0xE6, 0xF8, 0x72, 0x0D, 0x52, 0x47, 0xBE, 0xFB, 0x7A, 0x00,
- 0x90, 0x00, 0x43, 0xFF, 0x8F, 0x00, 0xB7, 0xFF, 0x11, 0x00, 0xFD,
- 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x36, 0xFC, 0xF1, 0x06,
- 0xF5, 0xF2, 0xA7, 0x22, 0xFF, 0x3B, 0xE4, 0xF2, 0x96, 0x05, 0x81,
- 0xFD, 0xFD, 0x00, 0xB5, 0xFF, 0x0B, 0x00, 0x01, 0x00, 0xFE, 0xFF,
- 0x1C, 0x00, 0x86, 0xFF, 0x59, 0x01, 0xEC, 0xFC, 0x6F, 0x06, 0xDC,
- 0xF1, 0x04, 0x37, 0xF3, 0x28, 0xFC, 0xF1, 0x28, 0x07, 0x37, 0xFC,
- 0xD8, 0x01, 0x41, 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x0B, 0x00, 0xD3,
- 0xFF, 0x49, 0x00, 0xD4, 0xFF, 0x88, 0xFF, 0x49, 0x02, 0x4B, 0xF8,
- 0x0D, 0x45, 0x68, 0x13, 0xDF, 0xF6, 0x6C, 0x05, 0xCC, 0xFC, 0xB4,
- 0x01, 0x45, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x23, 0x00,
- 0x74, 0xFF, 0x3A, 0x01, 0xDD, 0xFD, 0x39, 0x03, 0x7B, 0xFB, 0xC1,
- 0x06, 0xC7, 0x48, 0xCF, 0x00, 0x0D, 0xFE, 0xE3, 0x01, 0x8E, 0xFE,
- 0xE7, 0x00, 0x95, 0xFF, 0x1A, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x38,
- 0xFF, 0xDA, 0x01, 0x69, 0xFC, 0x57, 0x06, 0xAF, 0xF4, 0xF5, 0x1A,
- 0x1D, 0x41, 0x11, 0xF5, 0x25, 0x04, 0x6C, 0xFE, 0x74, 0x00, 0xF9,
- 0xFF, 0xF1, 0xFF, 0x05, 0x00, 0xFD, 0xFF, 0x2A, 0x00, 0x5C, 0xFF,
- 0xAA, 0x01, 0x71, 0xFC, 0x07, 0x07, 0x7E, 0xF1, 0x44, 0x30, 0x44,
- 0x30, 0x7E, 0xF1, 0x07, 0x07, 0x71, 0xFC, 0xAA, 0x01, 0x5C, 0xFF,
- 0x2A, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xF1, 0xFF, 0xF9, 0xFF, 0x74,
- 0x00, 0x6C, 0xFE, 0x25, 0x04, 0x11, 0xF5, 0x1D, 0x41, 0xF5, 0x1A,
- 0xAF, 0xF4, 0x57, 0x06, 0x69, 0xFC, 0xDA, 0x01, 0x38, 0xFF, 0x36,
- 0x00, 0xFE, 0xFF, 0x1A, 0x00, 0x95, 0xFF, 0xE7, 0x00, 0x8E, 0xFE,
- 0xE3, 0x01, 0x0D, 0xFE, 0xCF, 0x00, 0xC7, 0x48, 0xC1, 0x06, 0x7B,
- 0xFB, 0x39, 0x03, 0xDD, 0xFD, 0x3A, 0x01, 0x74, 0xFF, 0x23, 0x00,
- 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x45, 0xFF, 0xB4, 0x01, 0xCC,
- 0xFC, 0x6C, 0x05, 0xDF, 0xF6, 0x68, 0x13, 0x0D, 0x45, 0x4B, 0xF8,
- 0x49, 0x02, 0x88, 0xFF, 0xD4, 0xFF, 0x49, 0x00, 0xD3, 0xFF, 0x0B,
- 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x41, 0xFF, 0xD8, 0x01, 0x37, 0xFC,
- 0x28, 0x07, 0xFC, 0xF1, 0xF3, 0x28, 0x04, 0x37, 0xDC, 0xF1, 0x6F,
- 0x06, 0xEC, 0xFC, 0x59, 0x01, 0x86, 0xFF, 0x1C, 0x00, 0xFE, 0xFF,
- 0x01, 0x00, 0x0B, 0x00, 0xB5, 0xFF, 0xFD, 0x00, 0x81, 0xFD, 0x96,
- 0x05, 0xE4, 0xF2, 0xFF, 0x3B, 0xA7, 0x22, 0xF5, 0xF2, 0xF1, 0x06,
- 0x36, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x11,
- 0x00, 0xB7, 0xFF, 0x8F, 0x00, 0x43, 0xFF, 0x90, 0x00, 0x7A, 0x00,
- 0xBE, 0xFB, 0x52, 0x47, 0x72, 0x0D, 0xE6, 0xF8, 0x7E, 0x04, 0x3C,
- 0xFD, 0x83, 0x01, 0x58, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x2A, 0x00, 0x5C, 0xFF, 0x78, 0x01, 0x56, 0xFD, 0x48, 0x04, 0x56,
- 0xF9, 0x3E, 0x0C, 0xAE, 0x47, 0x8D, 0xFC, 0x13, 0x00, 0xC9, 0x00,
- 0x24, 0xFF, 0x9F, 0x00, 0xB1, 0xFF, 0x13, 0x00, 0xFD, 0xFF, 0x36,
- 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3B, 0xFC, 0xDD, 0x06, 0x37, 0xF3,
- 0x52, 0x21, 0xF6, 0x3C, 0x31, 0xF3, 0x5F, 0x05, 0xA6, 0xFD, 0xE8,
- 0x00, 0xC0, 0xFF, 0x07, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1F, 0x00,
- 0x7E, 0xFF, 0x69, 0x01, 0xD2, 0xFC, 0x92, 0x06, 0xBB, 0xF1, 0xE6,
- 0x35, 0x3F, 0x2A, 0xD8, 0xF1, 0x2A, 0x07, 0x3C, 0xFC, 0xD3, 0x01,
- 0x45, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x0A, 0x00, 0xD8, 0xFF, 0x3A,
- 0x00, 0xF1, 0xFF, 0x54, 0xFF, 0xA2, 0x02, 0xA9, 0xF7, 0x77, 0x44,
- 0xB1, 0x14, 0x77, 0xF6, 0x9A, 0x05, 0xB8, 0xFC, 0xBC, 0x01, 0x42,
- 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x21, 0x00, 0x7A, 0xFF,
- 0x2C, 0x01, 0xFB, 0xFD, 0xFE, 0x02, 0xEE, 0xFB, 0xAB, 0x05, 0xE1,
- 0x48, 0xC7, 0x01, 0x9D, 0xFD, 0x1E, 0x02, 0x6F, 0xFE, 0xF5, 0x00,
- 0x8F, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD6,
- 0x01, 0x77, 0xFC, 0x33, 0x06, 0x09, 0xF5, 0xA1, 0x19, 0xE1, 0x41,
- 0x8D, 0xF5, 0xDA, 0x03, 0x9A, 0xFE, 0x5A, 0x00, 0x06, 0x00, 0xEC,
- 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2C, 0x00, 0x56, 0xFF, 0xB4, 0x01,
- 0x62, 0xFC, 0x15, 0x07, 0x84, 0xF1, 0x09, 0x2F, 0x7B, 0x31, 0x7D,
- 0xF1, 0xF5, 0x06, 0x82, 0xFC, 0x9E, 0x01, 0x62, 0xFF, 0x28, 0x00,
- 0xFD, 0xFF, 0x04, 0x00, 0xF6, 0xFF, 0xED, 0xFF, 0x8E, 0x00, 0x3F,
- 0xFE, 0x6D, 0x04, 0x9E, 0xF4, 0x4E, 0x40, 0x49, 0x1C, 0x5A, 0xF4,
- 0x78, 0x06, 0x5C, 0xFC, 0xDF, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE,
- 0xFF, 0x18, 0x00, 0x9B, 0xFF, 0xD8, 0x00, 0xAD, 0xFE, 0xA7, 0x01,
- 0x7D, 0xFE, 0xDD, 0xFF, 0xA1, 0x48, 0xDD, 0x07, 0x07, 0xFB, 0x73,
- 0x03, 0xC0, 0xFD, 0x48, 0x01, 0x6F, 0xFF, 0x24, 0x00, 0x00, 0x00,
- 0xFF, 0xFF, 0x30, 0x00, 0x49, 0xFF, 0xAB, 0x01, 0xE2, 0xFC, 0x3D,
- 0x05, 0x48, 0xF7, 0x22, 0x12, 0x9B, 0x45, 0xF5, 0xF8, 0xED, 0x01,
- 0xBE, 0xFF, 0xB6, 0xFF, 0x57, 0x00, 0xCD, 0xFF, 0x0C, 0x00, 0xFD,
- 0xFF, 0x34, 0x00, 0x3E, 0xFF, 0xDD, 0x01, 0x33, 0xFC, 0x23, 0x07,
- 0x26, 0xF2, 0xA6, 0x27, 0x1D, 0x38, 0x05, 0xF2, 0x49, 0x06, 0x08,
- 0xFD, 0x47, 0x01, 0x8F, 0xFF, 0x18, 0x00, 0xFF, 0xFF, 0x00, 0x00,
- 0x0E, 0x00, 0xAA, 0xFF, 0x12, 0x01, 0x5F, 0xFD, 0xCB, 0x05, 0x9E,
- 0xF2, 0x03, 0x3B, 0xFC, 0x23, 0xB7, 0xF2, 0x03, 0x07, 0x33, 0xFC,
- 0xE5, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x10, 0x00, 0xBD,
- 0xFF, 0x80, 0x00, 0x62, 0xFF, 0x57, 0x00, 0xDF, 0x00, 0xF7, 0xFA,
- 0xED, 0x46, 0xAA, 0x0E, 0x76, 0xF8, 0xB2, 0x04, 0x23, 0xFD, 0x8F,
- 0x01, 0x53, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x28, 0x00,
- 0x61, 0xFF, 0x6C, 0x01, 0x71, 0xFD, 0x11, 0x04, 0xC8, 0xF9, 0x0E,
- 0x0B, 0xFD, 0x47, 0x63, 0xFD, 0xAA, 0xFF, 0x03, 0x01, 0x05, 0xFF,
- 0xAE, 0x00, 0xAC, 0xFF, 0x14, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36,
- 0xFF, 0xE5, 0x01, 0x41, 0xFC, 0xC6, 0x06, 0x7F, 0xF3, 0xFD, 0x1F,
- 0xE4, 0x3D, 0x87, 0xF3, 0x24, 0x05, 0xCC, 0xFD, 0xD1, 0x00, 0xCB,
- 0xFF, 0x02, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x21, 0x00, 0x76, 0xFF,
- 0x79, 0x01, 0xBA, 0xFC, 0xB1, 0x06, 0xA0, 0xF1, 0xC3, 0x34, 0x89,
- 0x2B, 0xB9, 0xF1, 0x29, 0x07, 0x44, 0xFC, 0xCC, 0x01, 0x49, 0xFF,
- 0x31, 0x00, 0xFD, 0xFF, 0x09, 0x00, 0xDE, 0xFF, 0x2C, 0x00, 0x0D,
- 0x00, 0x21, 0xFF, 0xF9, 0x02, 0x0F, 0xF7, 0xD4, 0x43, 0xFD, 0x15,
- 0x13, 0xF6, 0xC5, 0x05, 0xA5, 0xFC, 0xC4, 0x01, 0x40, 0xFF, 0x33,
- 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x7F, 0xFF, 0x1E, 0x01,
- 0x19, 0xFE, 0xC3, 0x02, 0x61, 0xFC, 0x9B, 0x04, 0xF2, 0x48, 0xC6,
- 0x02, 0x2C, 0xFD, 0x5A, 0x02, 0x50, 0xFE, 0x04, 0x01, 0x8A, 0xFF,
- 0x1D, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3B, 0xFF, 0xD0, 0x01, 0x86,
- 0xFC, 0x0D, 0x06, 0x66, 0xF5, 0x50, 0x18, 0x9E, 0x42, 0x11, 0xF6,
- 0x8C, 0x03, 0xC9, 0xFE, 0x3F, 0x00, 0x14, 0x00, 0xE7, 0xFF, 0x07,
- 0x00, 0xFD, 0xFF, 0x2E, 0x00, 0x51, 0xFF, 0xBE, 0x01, 0x56, 0xFC,
- 0x1F, 0x07, 0x92, 0xF1, 0xCA, 0x2D, 0xAF, 0x32, 0x84, 0xF1, 0xE0,
- 0x06, 0x94, 0xFC, 0x91, 0x01, 0x69, 0xFF, 0x26, 0x00, 0xFD, 0xFF,
- 0x03, 0x00, 0xFA, 0xFF, 0xE0, 0xFF, 0xA7, 0x00, 0x15, 0xFE, 0xB2,
- 0x04, 0x32, 0xF4, 0x77, 0x3F, 0x9E, 0x1D, 0x07, 0xF4, 0x96, 0x06,
- 0x51, 0xFC, 0xE2, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x17,
- 0x00, 0xA1, 0xFF, 0xC9, 0x00, 0xCD, 0xFE, 0x6C, 0x01, 0xEA, 0xFE,
- 0xF3, 0xFE, 0x70, 0x48, 0xFF, 0x08, 0x94, 0xFA, 0xAD, 0x03, 0xA3,
- 0xFD, 0x55, 0x01, 0x6A, 0xFF, 0x26, 0x00, 0x00, 0x00, 0xFF, 0xFF,
- 0x2F, 0x00, 0x4C, 0xFF, 0xA1, 0x01, 0xF8, 0xFC, 0x0D, 0x05, 0xB3,
- 0xF7, 0xDF, 0x10, 0x1D, 0x46, 0xA7, 0xF9, 0x8E, 0x01, 0xF4, 0xFF,
- 0x98, 0xFF, 0x66, 0x00, 0xC7, 0xFF, 0x0E, 0x00, 0xFD, 0xFF, 0x35,
- 0x00, 0x3C, 0xFF, 0xE1, 0x01, 0x31, 0xFC, 0x1A, 0x07, 0x56, 0xF2,
- 0x55, 0x26, 0x2E, 0x39, 0x35, 0xF2, 0x1E, 0x06, 0x25, 0xFD, 0x35,
- 0x01, 0x98, 0xFF, 0x15, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x12, 0x00,
- 0xA0, 0xFF, 0x26, 0x01, 0x3E, 0xFD, 0xFB, 0x05, 0x60, 0xF2, 0xFD,
- 0x39, 0x4E, 0x25, 0x7F, 0xF2, 0x11, 0x07, 0x31, 0xFC, 0xE3, 0x01,
- 0x3A, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0F, 0x00, 0xC3, 0xFF, 0x71,
- 0x00, 0x81, 0xFF, 0x1F, 0x00, 0x42, 0x01, 0x37, 0xFA, 0x7C, 0x46,
- 0xE7, 0x0F, 0x08, 0xF8, 0xE6, 0x04, 0x0B, 0xFD, 0x99, 0x01, 0x4F,
- 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x66, 0xFF,
- 0x5F, 0x01, 0x8D, 0xFD, 0xD9, 0x03, 0x3B, 0xFA, 0xE4, 0x09, 0x41,
- 0x48, 0x41, 0xFE, 0x3F, 0xFF, 0x3E, 0x01, 0xE5, 0xFE, 0xBD, 0x00,
- 0xA6, 0xFF, 0x16, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4,
- 0x01, 0x4A, 0xFC, 0xAC, 0x06, 0xCA, 0xF3, 0xA7, 0x1E, 0xCA, 0x3E,
- 0xE4, 0xF3, 0xE5, 0x04, 0xF4, 0xFD, 0xBA, 0x00, 0xD7, 0xFF, 0xFE,
- 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x24, 0x00, 0x6E, 0xFF, 0x87, 0x01,
- 0xA4, 0xFC, 0xCD, 0x06, 0x8E, 0xF1, 0x99, 0x33, 0xCE, 0x2C, 0xA1,
- 0xF1, 0x25, 0x07, 0x4D, 0xFC, 0xC4, 0x01, 0x4D, 0xFF, 0x2F, 0x00,
- 0xFD, 0xFF, 0x08, 0x00, 0xE3, 0xFF, 0x1E, 0x00, 0x2A, 0x00, 0xEF,
- 0xFE, 0x4D, 0x03, 0x7D, 0xF6, 0x2A, 0x43, 0x4B, 0x17, 0xB0, 0xF5,
- 0xEF, 0x05, 0x93, 0xFC, 0xCB, 0x01, 0x3D, 0xFF, 0x34, 0x00, 0xFE,
- 0xFF, 0x1E, 0x00, 0x85, 0xFF, 0x10, 0x01, 0x38, 0xFE, 0x88, 0x02,
- 0xD3, 0xFC, 0x91, 0x03, 0xF7, 0x48, 0xCB, 0x03, 0xBA, 0xFC, 0x95,
- 0x02, 0x31, 0xFE, 0x13, 0x01, 0x84, 0xFF, 0x1E, 0x00, 0x00, 0x00,
- 0xFE, 0xFF, 0x34, 0x00, 0x3E, 0xFF, 0xC9, 0x01, 0x97, 0xFC, 0xE6,
- 0x05, 0xC6, 0xF5, 0x00, 0x17, 0x50, 0x43, 0x9D, 0xF6, 0x3A, 0x03,
- 0xFA, 0xFE, 0x23, 0x00, 0x21, 0x00, 0xE2, 0xFF, 0x08, 0x00, 0xFD,
- 0xFF, 0x30, 0x00, 0x4C, 0xFF, 0xC6, 0x01, 0x4B, 0xFC, 0x26, 0x07,
- 0xA5, 0xF1, 0x87, 0x2C, 0xDC, 0x33, 0x91, 0xF1, 0xC7, 0x06, 0xA9,
- 0xFC, 0x84, 0x01, 0x70, 0xFF, 0x23, 0x00, 0xFE, 0xFF, 0x03, 0x00,
- 0xFF, 0xFF, 0xD4, 0xFF, 0xBF, 0x00, 0xEB, 0xFD, 0xF3, 0x04, 0xCF,
- 0xF3, 0x98, 0x3E, 0xF3, 0x1E, 0xB9, 0xF3, 0xB2, 0x06, 0x48, 0xFC,
- 0xE4, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x15, 0x00, 0xA7,
- 0xFF, 0xB9, 0x00, 0xEC, 0xFE, 0x31, 0x01, 0x57, 0xFF, 0x0F, 0xFE,
- 0x33, 0x48, 0x25, 0x0A, 0x21, 0xFA, 0xE5, 0x03, 0x87, 0xFD, 0x62,
- 0x01, 0x65, 0xFF, 0x27, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2E, 0x00,
- 0x50, 0xFF, 0x97, 0x01, 0x10, 0xFD, 0xDA, 0x04, 0x20, 0xF8, 0xA0,
- 0x0F, 0x97, 0x46, 0x61, 0xFA, 0x2D, 0x01, 0x2B, 0x00, 0x7A, 0xFF,
- 0x75, 0x00, 0xC2, 0xFF, 0x0F, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x3A,
- 0xFF, 0xE4, 0x01, 0x32, 0xFC, 0x0E, 0x07, 0x8B, 0xF2, 0x03, 0x25,
- 0x38, 0x3A, 0x6D, 0xF2, 0xF1, 0x05, 0x45, 0xFD, 0x22, 0x01, 0xA2,
- 0xFF, 0x11, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x16, 0x00, 0x96, 0xFF,
- 0x39, 0x01, 0x1F, 0xFD, 0x28, 0x06, 0x2A, 0xF2, 0xF2, 0x38, 0xA0,
- 0x26, 0x4B, 0xF2, 0x1C, 0x07, 0x32, 0xFC, 0xE0, 0x01, 0x3C, 0xFF,
- 0x35, 0x00, 0xFD, 0xFF, 0x0D, 0x00, 0xC9, 0xFF, 0x63, 0x00, 0x9F,
- 0xFF, 0xE8, 0xFF, 0xA3, 0x01, 0x7F, 0xF9, 0x02, 0x46, 0x27, 0x11,
- 0x9B, 0xF7, 0x18, 0x05, 0xF3, 0xFC, 0xA3, 0x01, 0x4C, 0xFF, 0x2F,
- 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6B, 0xFF, 0x52, 0x01,
- 0xA9, 0xFD, 0xA0, 0x03, 0xAE, 0xFA, 0xBE, 0x08, 0x7C, 0x48, 0x26,
- 0xFF, 0xD2, 0xFE, 0x79, 0x01, 0xC6, 0xFE, 0xCC, 0x00, 0xA0, 0xFF,
- 0x17, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE1, 0x01, 0x53,
- 0xFC, 0x90, 0x06, 0x19, 0xF4, 0x52, 0x1D, 0xA8, 0x3F, 0x49, 0xF4,
- 0xA3, 0x04, 0x1E, 0xFE, 0xA1, 0x00, 0xE3, 0xFF, 0xF9, 0xFF, 0x04,
- 0x00, 0xFD, 0xFF, 0x26, 0x00, 0x67, 0xFF, 0x94, 0x01, 0x90, 0xFC,
- 0xE5, 0x06, 0x81, 0xF1, 0x6B, 0x32, 0x11, 0x2E, 0x8E, 0xF1, 0x1D,
- 0x07, 0x58, 0xFC, 0xBC, 0x01, 0x52, 0xFF, 0x2E, 0x00, 0xFD, 0xFF,
- 0x07, 0x00, 0xE8, 0xFF, 0x11, 0x00, 0x45, 0x00, 0xBF, 0xFE, 0x9D,
- 0x03, 0xF3, 0xF5, 0x75, 0x42, 0x9B, 0x18, 0x51, 0xF5, 0x16, 0x06,
- 0x83, 0xFC, 0xD1, 0x01, 0x3B, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x1D,
- 0x00, 0x8B, 0xFF, 0x01, 0x01, 0x56, 0xFE, 0x4D, 0x02, 0x45, 0xFD,
- 0x8D, 0x02, 0xF0, 0x48, 0xD7, 0x04, 0x47, 0xFC, 0xD1, 0x02, 0x12,
- 0xFE, 0x21, 0x01, 0x7E, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFF, 0xFF,
- 0x33, 0x00, 0x40, 0xFF, 0xC2, 0x01, 0xA9, 0xFC, 0xBC, 0x05, 0x29,
- 0xF6, 0xB3, 0x15, 0xFA, 0x43, 0x31, 0xF7, 0xE6, 0x02, 0x2C, 0xFF,
- 0x07, 0x00, 0x2F, 0x00, 0xDC, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x31,
- 0x00, 0x48, 0xFF, 0xCE, 0x01, 0x42, 0xFC, 0x2A, 0x07, 0xBF, 0xF1,
- 0x40, 0x2B, 0x05, 0x35, 0xA6, 0xF1, 0xAB, 0x06, 0xBF, 0xFC, 0x75,
- 0x01, 0x77, 0xFF, 0x21, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x03, 0x00,
- 0xC8, 0xFF, 0xD6, 0x00, 0xC4, 0xFD, 0x31, 0x05, 0x73, 0xF3, 0xB0,
- 0x3D, 0x49, 0x20, 0x6E, 0xF3, 0xCB, 0x06, 0x40, 0xFC, 0xE6, 0x01,
- 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x14, 0x00, 0xAD, 0xFF, 0xAA,
- 0x00, 0x0C, 0xFF, 0xF7, 0x00, 0xC1, 0xFF, 0x33, 0xFD, 0xEC, 0x47,
- 0x51, 0x0B, 0xAF, 0xF9, 0x1D, 0x04, 0x6B, 0xFD, 0x6E, 0x01, 0x60,
- 0xFF, 0x29, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2C, 0x00, 0x54, 0xFF,
- 0x8C, 0x01, 0x29, 0xFD, 0xA7, 0x04, 0x8F, 0xF8, 0x64, 0x0E, 0x02,
- 0x47, 0x22, 0xFB, 0xC9, 0x00, 0x64, 0x00, 0x5B, 0xFF, 0x84, 0x00,
- 0xBC, 0xFF, 0x10, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE5,
- 0x01, 0x33, 0xFC, 0xFF, 0x06, 0xC4, 0xF2, 0xB0, 0x23, 0x3B, 0x3B,
- 0xAD, 0xF2, 0xBF, 0x05, 0x66, 0xFD, 0x0E, 0x01, 0xAC, 0xFF, 0x0E,
- 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x19, 0x00, 0x8D, 0xFF, 0x4B, 0x01,
- 0x01, 0xFD, 0x51, 0x06, 0xFB, 0xF1, 0xDF, 0x37, 0xF0, 0x27, 0x1C,
- 0xF2, 0x24, 0x07, 0x34, 0xFC, 0xDC, 0x01, 0x3F, 0xFF, 0x34, 0x00,
- 0xFD, 0xFF, 0x0C, 0x00, 0xCE, 0xFF, 0x54, 0x00, 0xBD, 0xFF, 0xB2,
- 0xFF, 0x01, 0x02, 0xCF, 0xF8, 0x7D, 0x45, 0x6B, 0x12, 0x30, 0xF7,
- 0x48, 0x05, 0xDD, 0xFC, 0xAD, 0x01, 0x48, 0xFF, 0x30, 0x00, 0xFF,
- 0xFF, 0x00, 0x00, 0x24, 0x00, 0x70, 0xFF, 0x45, 0x01, 0xC6, 0xFD,
- 0x66, 0x03, 0x21, 0xFB, 0x9E, 0x07, 0xAA, 0x48, 0x12, 0x00, 0x64,
- 0xFE, 0xB4, 0x01, 0xA6, 0xFE, 0xDB, 0x00, 0x9A, 0xFF, 0x19, 0x00,
- 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xDE, 0x01, 0x5F, 0xFC, 0x70,
- 0x06, 0x6C, 0xF4, 0xFD, 0x1B, 0x7D, 0x40, 0xB7, 0xF4, 0x5D, 0x04,
- 0x49, 0xFE, 0x88, 0x00, 0xEF, 0xFF, 0xF5, 0xFF, 0x04, 0x00, 0xFD,
- 0xFF, 0x29, 0x00, 0x61, 0xFF, 0xA1, 0x01, 0x7E, 0xFC, 0xF9, 0x06,
- 0x7C, 0xF1, 0x38, 0x31, 0x50, 0x2F, 0x82, 0xF1, 0x12, 0x07, 0x65,
- 0xFC, 0xB2, 0x01, 0x57, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0x06, 0x00,
- 0xED, 0xFF, 0x04, 0x00, 0x60, 0x00, 0x90, 0xFE, 0xEB, 0x03, 0x71,
- 0xF5, 0xB7, 0x41, 0xED, 0x19, 0xF5, 0xF4, 0x3B, 0x06, 0x73, 0xFC,
- 0xD7, 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x91,
- 0xFF, 0xF2, 0x00, 0x76, 0xFE, 0x11, 0x02, 0xB6, 0xFD, 0x8F, 0x01,
- 0xDE, 0x48, 0xE9, 0x05, 0xD4, 0xFB, 0x0C, 0x03, 0xF4, 0xFD, 0x2F,
- 0x01, 0x79, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x00,
- 0x43, 0xFF, 0xBA, 0x01, 0xBC, 0xFC, 0x90, 0x05, 0x8E, 0xF6, 0x68,
- 0x14, 0x99, 0x44, 0xCD, 0xF7, 0x8F, 0x02, 0x60, 0xFF, 0xEA, 0xFF,
- 0x3E, 0x00, 0xD7, 0xFF, 0x0A, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x44,
- 0xFF, 0xD4, 0x01, 0x3B, 0xFC, 0x2A, 0x07, 0xDF, 0xF1, 0xF6, 0x29,
- 0x27, 0x36, 0xC1, 0xF1, 0x8B, 0x06, 0xD8, 0xFC, 0x66, 0x01, 0x80,
- 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x07, 0x00, 0xBD, 0xFF,
- 0xED, 0x00, 0x9E, 0xFD, 0x6C, 0x05, 0x1F, 0xF3, 0xC0, 0x3C, 0x9E,
- 0x21, 0x28, 0xF3, 0xE2, 0x06, 0x3A, 0xFC, 0xE6, 0x01, 0x37, 0xFF,
- 0x36, 0x00, 0xFD, 0xFF, 0x12, 0x00, 0xB3, 0xFF, 0x9B, 0x00, 0x2B,
- 0xFF, 0xBD, 0x00, 0x2A, 0x00, 0x5E, 0xFC, 0x9A, 0x47, 0x82, 0x0C,
- 0x3D, 0xF9, 0x54, 0x04, 0x50, 0xFD, 0x7A, 0x01, 0x5B, 0xFF, 0x2A,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x59, 0xFF, 0x81, 0x01,
- 0x42, 0xFD, 0x72, 0x04, 0xFF, 0xF8, 0x2D, 0x0D, 0x69, 0x47, 0xEB,
- 0xFB, 0x63, 0x00, 0x9D, 0x00, 0x3C, 0xFF, 0x93, 0x00, 0xB6, 0xFF,
- 0x12, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x37,
- 0xFC, 0xED, 0x06, 0x03, 0xF3, 0x5B, 0x22, 0x37, 0x3C, 0xF4, 0xF2,
- 0x8A, 0x05, 0x89, 0xFD, 0xF9, 0x00, 0xB7, 0xFF, 0x0A, 0x00, 0x01,
- 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x84, 0xFF, 0x5C, 0x01, 0xE6, 0xFC,
- 0x77, 0x06, 0xD4, 0xF1, 0xC6, 0x36, 0x3E, 0x29, 0xF3, 0xF1, 0x29,
- 0x07, 0x38, 0xFC, 0xD7, 0x01, 0x42, 0xFF, 0x33, 0x00, 0xFD, 0xFF,
- 0x0B, 0x00, 0xD4, 0xFF, 0x46, 0x00, 0xDA, 0xFF, 0x7D, 0xFF, 0x5D,
- 0x02, 0x26, 0xF8, 0xED, 0x44, 0xB1, 0x13, 0xC7, 0xF6, 0x77, 0x05,
- 0xC8, 0xFC, 0xB6, 0x01, 0x45, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x00,
- 0x00, 0x22, 0x00, 0x76, 0xFF, 0x37, 0x01, 0xE4, 0xFD, 0x2C, 0x03,
- 0x94, 0xFB, 0x83, 0x06, 0xCE, 0x48, 0x05, 0x01, 0xF5, 0xFD, 0xF0,
- 0x01, 0x87, 0xFE, 0xEA, 0x00, 0x94, 0xFF, 0x1A, 0x00, 0xFE, 0xFF,
- 0x35, 0x00, 0x38, 0xFF, 0xD9, 0x01, 0x6C, 0xFC, 0x4F, 0x06, 0xC3,
- 0xF4, 0xA9, 0x1A, 0x49, 0x41, 0x2C, 0xF5, 0x15, 0x04, 0x76, 0xFE,
- 0x6E, 0x00, 0xFC, 0xFF, 0xF0, 0xFF, 0x05, 0x00, 0xFD, 0xFF, 0x2B,
- 0x00, 0x5A, 0xFF, 0xAC, 0x01, 0x6E, 0xFC, 0x0A, 0x07, 0x7E, 0xF1,
- 0xFF, 0x2F, 0x8A, 0x30, 0x7D, 0xF1, 0x03, 0x07, 0x75, 0xFC, 0xA7,
- 0x01, 0x5D, 0xFF, 0x2A, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xF2, 0xFF,
- 0xF7, 0xFF, 0x7A, 0x00, 0x62, 0xFE, 0x35, 0x04, 0xF7, 0xF4, 0xEF,
- 0x40, 0x40, 0x1B, 0x9C, 0xF4, 0x5E, 0x06, 0x66, 0xFC, 0xDB, 0x01,
- 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x1A, 0x00, 0x96, 0xFF, 0xE3,
- 0x00, 0x95, 0xFE, 0xD5, 0x01, 0x26, 0xFE, 0x98, 0x00, 0xBF, 0x48,
- 0x00, 0x07, 0x61, 0xFB, 0x46, 0x03, 0xD6, 0xFD, 0x3D, 0x01, 0x73,
- 0xFF, 0x23, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x46, 0xFF,
- 0xB2, 0x01, 0xD1, 0xFC, 0x62, 0x05, 0xF6, 0xF6, 0x20, 0x13, 0x2E,
- 0x45, 0x70, 0xF8, 0x34, 0x02, 0x94, 0xFF, 0xCD, 0xFF, 0x4C, 0x00,
- 0xD2, 0xFF, 0x0B, 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x41, 0xFF, 0xDA,
- 0x01, 0x36, 0xFC, 0x27, 0x07, 0x05, 0xF2, 0xAA, 0x28, 0x44, 0x37,
- 0xE4, 0xF1, 0x67, 0x06, 0xF2, 0xFC, 0x55, 0x01, 0x88, 0xFF, 0x1B,
- 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x0B, 0x00, 0xB2, 0xFF, 0x02, 0x01,
- 0x7A, 0xFD, 0xA2, 0x05, 0xD4, 0xF2, 0xC7, 0x3B, 0xF2, 0x22, 0xE7,
- 0xF2, 0xF5, 0x06, 0x35, 0xFC, 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00,
- 0xFD, 0xFF, 0x11, 0x00, 0xB9, 0xFF, 0x8C, 0x00, 0x4A, 0xFF, 0x83,
- 0x00, 0x91, 0x00, 0x91, 0xFB, 0x3D, 0x47, 0xB7, 0x0D, 0xCD, 0xF8,
- 0x89, 0x04, 0x36, 0xFD, 0x86, 0x01, 0x57, 0xFF, 0x2B, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5D, 0xFF, 0x75, 0x01, 0x5C, 0xFD,
- 0x3C, 0x04, 0x70, 0xF9, 0xFA, 0x0B, 0xC0, 0x47, 0xBC, 0xFC, 0xFC,
- 0xFF, 0xD6, 0x00, 0x1D, 0xFF, 0xA2, 0x00, 0xB0, 0xFF, 0x13, 0x00,
- 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3C, 0xFC, 0xD8,
- 0x06, 0x47, 0xF3, 0x06, 0x21, 0x2A, 0x3D, 0x44, 0xF3, 0x52, 0x05,
- 0xAE, 0xFD, 0xE3, 0x00, 0xC2, 0xFF, 0x06, 0x00, 0x01, 0x00, 0xFE,
- 0xFF, 0x1F, 0x00, 0x7C, 0xFF, 0x6D, 0x01, 0xCD, 0xFC, 0x99, 0x06,
- 0xB4, 0xF1, 0xA6, 0x35, 0x89, 0x2A, 0xD0, 0xF1, 0x2B, 0x07, 0x3E,
- 0xFC, 0xD1, 0x01, 0x46, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x0A, 0x00,
- 0xD9, 0xFF, 0x37, 0x00, 0xF7, 0xFF, 0x49, 0xFF, 0xB6, 0x02, 0x86,
- 0xF7, 0x53, 0x44, 0xFB, 0x14, 0x61, 0xF6, 0xA4, 0x05, 0xB4, 0xFC,
- 0xBE, 0x01, 0x42, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x21,
- 0x00, 0x7B, 0xFF, 0x29, 0x01, 0x01, 0xFE, 0xF1, 0x02, 0x07, 0xFC,
- 0x6E, 0x05, 0xE6, 0x48, 0xFF, 0x01, 0x84, 0xFD, 0x2C, 0x02, 0x68,
- 0xFE, 0xF9, 0x00, 0x8E, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, 0x35, 0x00,
- 0x3A, 0xFF, 0xD4, 0x01, 0x7A, 0xFC, 0x2B, 0x06, 0x1E, 0xF5, 0x56,
- 0x19, 0x0C, 0x42, 0xAA, 0xF5, 0xC9, 0x03, 0xA4, 0xFE, 0x54, 0x00,
- 0x09, 0x00, 0xEB, 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2D, 0x00, 0x55,
- 0xFF, 0xB6, 0x01, 0x5F, 0xFC, 0x17, 0x07, 0x87, 0xF1, 0xC2, 0x2E,
- 0xC0, 0x31, 0x7E, 0xF1, 0xF1, 0x06, 0x86, 0xFC, 0x9B, 0x01, 0x63,
- 0xFF, 0x28, 0x00, 0xFD, 0xFF, 0x04, 0x00, 0xF7, 0xFF, 0xEA, 0xFF,
- 0x93, 0x00, 0x36, 0xFE, 0x7D, 0x04, 0x85, 0xF4, 0x1F, 0x40, 0x94,
- 0x1C, 0x47, 0xF4, 0x7E, 0x06, 0x5A, 0xFC, 0xDF, 0x01, 0x37, 0xFF,
- 0x36, 0x00, 0xFE, 0xFF, 0x18, 0x00, 0x9C, 0xFF, 0xD4, 0x00, 0xB4,
- 0xFE, 0x9A, 0x01, 0x95, 0xFE, 0xA8, 0xFF, 0x98, 0x48, 0x1D, 0x08,
- 0xEE, 0xFA, 0x80, 0x03, 0xB9, 0xFD, 0x4B, 0x01, 0x6E, 0xFF, 0x25,
- 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30, 0x00, 0x4A, 0xFF, 0xA9, 0x01,
- 0xE7, 0xFC, 0x33, 0x05, 0x60, 0xF7, 0xDA, 0x11, 0xB8, 0x45, 0x1C,
- 0xF9, 0xD8, 0x01, 0xCA, 0xFF, 0xAF, 0xFF, 0x5A, 0x00, 0xCC, 0xFF,
- 0x0D, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x3E, 0xFF, 0xDE, 0x01, 0x33,
- 0xFC, 0x21, 0x07, 0x30, 0xF2, 0x5C, 0x27, 0x5B, 0x38, 0x0F, 0xF2,
- 0x40, 0x06, 0x0E, 0xFD, 0x43, 0x01, 0x91, 0xFF, 0x18, 0x00, 0xFF,
- 0xFF, 0x00, 0x00, 0x0F, 0x00, 0xA8, 0xFF, 0x17, 0x01, 0x57, 0xFD,
- 0xD6, 0x05, 0x90, 0xF2, 0xC8, 0x3A, 0x46, 0x24, 0xAA, 0xF2, 0x06,
- 0x07, 0x32, 0xFC, 0xE5, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF,
- 0x10, 0x00, 0xBE, 0xFF, 0x7D, 0x00, 0x69, 0xFF, 0x4B, 0x00, 0xF6,
- 0x00, 0xCB, 0xFA, 0xD3, 0x46, 0xF0, 0x0E, 0x5E, 0xF8, 0xBE, 0x04,
- 0x1E, 0xFD, 0x91, 0x01, 0x52, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x00,
- 0x00, 0x28, 0x00, 0x62, 0xFF, 0x69, 0x01, 0x77, 0xFD, 0x04, 0x04,
- 0xE2, 0xF9, 0xCB, 0x0A, 0x0D, 0x48, 0x94, 0xFD, 0x92, 0xFF, 0x10,
- 0x01, 0xFE, 0xFE, 0xB1, 0x00, 0xAA, 0xFF, 0x15, 0x00, 0xFD, 0xFF,
- 0x36, 0x00, 0x36, 0xFF, 0xE5, 0x01, 0x43, 0xFC, 0xC0, 0x06, 0x8F,
- 0xF3, 0xB1, 0x1F, 0x18, 0x3E, 0x9B, 0xF3, 0x16, 0x05, 0xD5, 0xFD,
- 0xCC, 0x00, 0xCE, 0xFF, 0x01, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x22,
- 0x00, 0x74, 0xFF, 0x7C, 0x01, 0xB5, 0xFC, 0xB8, 0x06, 0x9C, 0xF1,
- 0x81, 0x34, 0xD1, 0x2B, 0xB3, 0xF1, 0x29, 0x07, 0x46, 0xFC, 0xCA,
- 0x01, 0x4A, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x09, 0x00, 0xDF, 0xFF,
- 0x29, 0x00, 0x14, 0x00, 0x16, 0xFF, 0x0C, 0x03, 0xEE, 0xF6, 0xB0,
- 0x43, 0x47, 0x16, 0xFC, 0xF5, 0xCF, 0x05, 0xA1, 0xFC, 0xC6, 0x01,
- 0x3F, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x81,
- 0xFF, 0x1B, 0x01, 0x20, 0xFE, 0xB6, 0x02, 0x7A, 0xFC, 0x5F, 0x04,
- 0xF4, 0x48, 0xFF, 0x02, 0x13, 0xFD, 0x67, 0x02, 0x49, 0xFE, 0x07,
- 0x01, 0x88, 0xFF, 0x1D, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3C, 0xFF,
- 0xCF, 0x01, 0x8A, 0xFC, 0x05, 0x06, 0x7B, 0xF5, 0x06, 0x18, 0xC7,
- 0x42, 0x2F, 0xF6, 0x7A, 0x03, 0xD4, 0xFE, 0x39, 0x00, 0x17, 0x00,
- 0xE6, 0xFF, 0x07, 0x00, 0xFD, 0xFF, 0x2E, 0x00, 0x50, 0xFF, 0xC0,
- 0x01, 0x53, 0xFC, 0x21, 0x07, 0x96, 0xF1, 0x82, 0x2D, 0xF2, 0x32,
- 0x86, 0xF1, 0xDB, 0x06, 0x99, 0xFC, 0x8E, 0x01, 0x6A, 0xFF, 0x25,
- 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFB, 0xFF, 0xDE, 0xFF, 0xAC, 0x00,
- 0x0B, 0xFE, 0xC1, 0x04, 0x1B, 0xF4, 0x47, 0x3F, 0xEA, 0x1D, 0xF5,
- 0xF3, 0x9C, 0x06, 0x4F, 0xFC, 0xE2, 0x01, 0x36, 0xFF, 0x36, 0x00,
- 0xFE, 0xFF, 0x16, 0x00, 0xA2, 0xFF, 0xC5, 0x00, 0xD4, 0xFE, 0x5F,
- 0x01, 0x03, 0xFF, 0xBF, 0xFE, 0x63, 0x48, 0x40, 0x09, 0x7B, 0xFA,
- 0xB9, 0x03, 0x9D, 0xFD, 0x58, 0x01, 0x69, 0xFF, 0x26, 0x00, 0x00,
- 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x4D, 0xFF, 0x9F, 0x01, 0xFE, 0xFC,
- 0x02, 0x05, 0xCB, 0xF7, 0x98, 0x10, 0x39, 0x46, 0xD0, 0xF9, 0x78,
- 0x01, 0x00, 0x00, 0x91, 0xFF, 0x69, 0x00, 0xC6, 0xFF, 0x0E, 0x00,
- 0xFD, 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xE2, 0x01, 0x31, 0xFC, 0x17,
- 0x07, 0x61, 0xF2, 0x0A, 0x26, 0x6A, 0x39, 0x41, 0xF2, 0x15, 0x06,
- 0x2C, 0xFD, 0x31, 0x01, 0x9B, 0xFF, 0x14, 0x00, 0xFF, 0xFF, 0xFF,
- 0xFF, 0x13, 0x00, 0x9E, 0xFF, 0x2B, 0x01, 0x37, 0xFD, 0x05, 0x06,
- 0x54, 0xF2, 0xC2, 0x39, 0x99, 0x25, 0x73, 0xF2, 0x14, 0x07, 0x31,
- 0xFC, 0xE3, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0E, 0x00,
- 0xC4, 0xFF, 0x6E, 0x00, 0x87, 0xFF, 0x13, 0x00, 0x58, 0x01, 0x0D,
- 0xFA, 0x61, 0x46, 0x2D, 0x10, 0xF0, 0xF7, 0xF1, 0x04, 0x05, 0xFD,
- 0x9C, 0x01, 0x4E, 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x27,
- 0x00, 0x67, 0xFF, 0x5C, 0x01, 0x93, 0xFD, 0xCC, 0x03, 0x54, 0xFA,
- 0xA2, 0x09, 0x4F, 0x48, 0x73, 0xFE, 0x27, 0xFF, 0x4B, 0x01, 0xDE,
- 0xFE, 0xC0, 0x00, 0xA4, 0xFF, 0x16, 0x00, 0xFE, 0xFF, 0x36, 0x00,
- 0x36, 0xFF, 0xE3, 0x01, 0x4C, 0xFC, 0xA6, 0x06, 0xDB, 0xF3, 0x5B,
- 0x1E, 0xFC, 0x3E, 0xFA, 0xF3, 0xD7, 0x04, 0xFD, 0xFD, 0xB4, 0x00,
- 0xD9, 0xFF, 0xFD, 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x25, 0x00, 0x6D,
- 0xFF, 0x8A, 0x01, 0x9F, 0xFC, 0xD3, 0x06, 0x8A, 0xF1, 0x57, 0x33,
- 0x17, 0x2D, 0x9C, 0xF1, 0x24, 0x07, 0x4F, 0xFC, 0xC3, 0x01, 0x4E,
- 0xFF, 0x2F, 0x00, 0xFD, 0xFF, 0x08, 0x00, 0xE4, 0xFF, 0x1B, 0x00,
- 0x30, 0x00, 0xE4, 0xFE, 0x5F, 0x03, 0x5E, 0xF6, 0x02, 0x43, 0x96,
- 0x17, 0x9B, 0xF5, 0xF8, 0x05, 0x8F, 0xFC, 0xCC, 0x01, 0x3D, 0xFF,
- 0x34, 0x00, 0xFE, 0xFF, 0x1E, 0x00, 0x86, 0xFF, 0x0C, 0x01, 0x3E,
- 0xFE, 0x7B, 0x02, 0xED, 0xFC, 0x56, 0x03, 0xF5, 0x48, 0x06, 0x04,
- 0xA1, 0xFC, 0xA3, 0x02, 0x2A, 0xFE, 0x16, 0x01, 0x83, 0xFF, 0x1F,
- 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x3E, 0xFF, 0xC8, 0x01,
- 0x9B, 0xFC, 0xDD, 0x05, 0xDC, 0xF5, 0xB6, 0x16, 0x77, 0x43, 0xBD,
- 0xF6, 0x28, 0x03, 0x05, 0xFF, 0x1D, 0x00, 0x25, 0x00, 0xE1, 0xFF,
- 0x08, 0x00, 0xFD, 0xFF, 0x30, 0x00, 0x4B, 0xFF, 0xC8, 0x01, 0x49,
- 0xFC, 0x27, 0x07, 0xAB, 0xF1, 0x3E, 0x2C, 0x1E, 0x34, 0x95, 0xF1,
- 0xC1, 0x06, 0xAE, 0xFC, 0x81, 0x01, 0x71, 0xFF, 0x23, 0x00, 0xFE,
- 0xFF, 0x02, 0x00, 0x00, 0x00, 0xD2, 0xFF, 0xC4, 0x00, 0xE2, 0xFD,
- 0x01, 0x05, 0xBA, 0xF3, 0x64, 0x3E, 0x3F, 0x1F, 0xA8, 0xF3, 0xB8,
- 0x06, 0x46, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF,
- 0x15, 0x00, 0xA8, 0xFF, 0xB6, 0x00, 0xF3, 0xFE, 0x24, 0x01, 0x6E,
- 0xFF, 0xDE, 0xFD, 0x25, 0x48, 0x68, 0x0A, 0x08, 0xFA, 0xF2, 0x03,
- 0x81, 0xFD, 0x65, 0x01, 0x64, 0xFF, 0x28, 0x00, 0x00, 0x00, 0xFF,
- 0xFF, 0x2D, 0x00, 0x51, 0xFF, 0x95, 0x01, 0x15, 0xFD, 0xCF, 0x04,
- 0x39, 0xF8, 0x59, 0x0F, 0xAF, 0x46, 0x8B, 0xFA, 0x17, 0x01, 0x38,
- 0x00, 0x73, 0xFF, 0x78, 0x00, 0xC0, 0xFF, 0x0F, 0x00, 0xFD, 0xFF,
- 0x36, 0x00, 0x39, 0xFF, 0xE4, 0x01, 0x32, 0xFC, 0x0B, 0x07, 0x97,
- 0xF2, 0xB8, 0x24, 0x71, 0x3A, 0x7B, 0xF2, 0xE6, 0x05, 0x4C, 0xFD,
- 0x1D, 0x01, 0xA4, 0xFF, 0x11, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x16,
- 0x00, 0x94, 0xFF, 0x3D, 0x01, 0x18, 0xFD, 0x32, 0x06, 0x1F, 0xF2,
- 0xB5, 0x38, 0xEB, 0x26, 0x40, 0xF2, 0x1E, 0x07, 0x32, 0xFC, 0xDF,
- 0x01, 0x3D, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0D, 0x00, 0xCA, 0xFF,
- 0x5F, 0x00, 0xA5, 0xFF, 0xDC, 0xFF, 0xB8, 0x01, 0x57, 0xF9, 0xE5,
- 0x45, 0x6E, 0x11, 0x83, 0xF7, 0x23, 0x05, 0xEE, 0xFC, 0xA6, 0x01,
- 0x4B, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6C,
- 0xFF, 0x4F, 0x01, 0xB0, 0xFD, 0x93, 0x03, 0xC7, 0xFA, 0x7D, 0x08,
- 0x86, 0x48, 0x5A, 0xFF, 0xBA, 0xFE, 0x86, 0x01, 0xBF, 0xFE, 0xCF,
- 0x00, 0x9E, 0xFF, 0x17, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF,
- 0xE0, 0x01, 0x56, 0xFC, 0x89, 0x06, 0x2B, 0xF4, 0x06, 0x1D, 0xD7,
- 0x3F, 0x61, 0xF4, 0x94, 0x04, 0x27, 0xFE, 0x9C, 0x00, 0xE6, 0xFF,
- 0xF8, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x27, 0x00, 0x66, 0xFF, 0x97,
- 0x01, 0x8C, 0xFC, 0xEA, 0x06, 0x80, 0xF1, 0x26, 0x32, 0x58, 0x2E,
- 0x8B, 0xF1, 0x1B, 0x07, 0x5B, 0xFC, 0xBA, 0x01, 0x53, 0xFF, 0x2D,
- 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE9, 0xFF, 0x0E, 0x00, 0x4B, 0x00,
- 0xB4, 0xFE, 0xAF, 0x03, 0xD5, 0xF5, 0x4D, 0x42, 0xE6, 0x18, 0x3C,
- 0xF5, 0x1F, 0x06, 0x7F, 0xFC, 0xD3, 0x01, 0x3B, 0xFF, 0x35, 0x00,
- 0xFE, 0xFF, 0x1C, 0x00, 0x8C, 0xFF, 0xFE, 0x00, 0x5D, 0xFE, 0x3F,
- 0x02, 0x5E, 0xFD, 0x54, 0x02, 0xEC, 0x48, 0x13, 0x05, 0x2E, 0xFC,
- 0xDE, 0x02, 0x0C, 0xFE, 0x24, 0x01, 0x7D, 0xFF, 0x20, 0x00, 0x00,
- 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x41, 0xFF, 0xC1, 0x01, 0xAD, 0xFC,
- 0xB2, 0x05, 0x3F, 0xF6, 0x69, 0x15, 0x1F, 0x44, 0x53, 0xF7, 0xD3,
- 0x02, 0x38, 0xFF, 0x01, 0x00, 0x33, 0x00, 0xDB, 0xFF, 0x09, 0x00,
- 0xFD, 0xFF, 0x31, 0x00, 0x47, 0xFF, 0xCF, 0x01, 0x40, 0xFC, 0x2A,
- 0x07, 0xC6, 0xF1, 0xF7, 0x2A, 0x46, 0x35, 0xAB, 0xF1, 0xA4, 0x06,
- 0xC4, 0xFC, 0x72, 0x01, 0x79, 0xFF, 0x20, 0x00, 0xFE, 0xFF, 0x02,
- 0x00, 0x04, 0x00, 0xC6, 0xFF, 0xDB, 0x00, 0xBB, 0xFD, 0x3E, 0x05,
- 0x60, 0xF3, 0x7B, 0x3D, 0x94, 0x20, 0x5E, 0xF3, 0xD0, 0x06, 0x3E,
- 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x14, 0x00,
- 0xAE, 0xFF, 0xA7, 0x00, 0x12, 0xFF, 0xEA, 0x00, 0xD9, 0xFF, 0x03,
- 0xFD, 0xDC, 0x47, 0x95, 0x0B, 0x96, 0xF9, 0x29, 0x04, 0x65, 0xFD,
- 0x71, 0x01, 0x5F, 0xFF, 0x29, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2C,
- 0x00, 0x55, 0xFF, 0x8A, 0x01, 0x2E, 0xFD, 0x9B, 0x04, 0xA8, 0xF8,
- 0x1F, 0x0E, 0x1A, 0x47, 0x4E, 0xFB, 0xB3, 0x00, 0x70, 0x00, 0x54,
- 0xFF, 0x87, 0x00, 0xBB, 0xFF, 0x11, 0x00, 0xFD, 0xFF, 0x36, 0x00,
- 0x38, 0xFF, 0xE6, 0x01, 0x34, 0xFC, 0xFB, 0x06, 0xD2, 0xF2, 0x64,
- 0x23, 0x73, 0x3B, 0xBC, 0xF2, 0xB4, 0x05, 0x6E, 0xFD, 0x09, 0x01,
- 0xAF, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1A, 0x00, 0x8B,
- 0xFF, 0x4F, 0x01, 0xFB, 0xFC, 0x5A, 0x06, 0xF2, 0xF1, 0xA0, 0x37,
- 0x3A, 0x28, 0x13, 0xF2, 0x25, 0x07, 0x35, 0xFC, 0xDB, 0x01, 0x40,
- 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0C, 0x00, 0xD0, 0xFF, 0x51, 0x00,
- 0xC3, 0xFF, 0xA6, 0xFF, 0x16, 0x02, 0xA9, 0xF8, 0x5C, 0x45, 0xB2,
- 0x12, 0x19, 0xF7, 0x52, 0x05, 0xD8, 0xFC, 0xAF, 0x01, 0x47, 0xFF,
- 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x24, 0x00, 0x71, 0xFF, 0x42,
- 0x01, 0xCD, 0xFD, 0x59, 0x03, 0x3B, 0xFB, 0x5E, 0x07, 0xB3, 0x48,
- 0x48, 0x00, 0x4B, 0xFE, 0xC2, 0x01, 0x9F, 0xFE, 0xDE, 0x00, 0x98,
- 0xFF, 0x19, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xDD, 0x01,
- 0x62, 0xFC, 0x69, 0x06, 0x7F, 0xF4, 0xB2, 0x1B, 0xAB, 0x40, 0xD0,
- 0xF4, 0x4E, 0x04, 0x53, 0xFE, 0x83, 0x00, 0xF2, 0xFF, 0xF4, 0xFF,
- 0x05, 0x00, 0xFD, 0xFF, 0x29, 0x00, 0x5F, 0xFF, 0xA3, 0x01, 0x7A,
- 0xFC, 0xFD, 0x06, 0x7C, 0xF1, 0xF2, 0x30, 0x96, 0x2F, 0x80, 0xF1,
- 0x0F, 0x07, 0x69, 0xFC, 0xB0, 0x01, 0x59, 0xFF, 0x2B, 0x00, 0xFD,
- 0xFF, 0x06, 0x00, 0xEE, 0xFF, 0x01, 0x00, 0x66, 0x00, 0x85, 0xFE,
- 0xFC, 0x03, 0x55, 0xF5, 0x8C, 0x41, 0x38, 0x1A, 0xE1, 0xF4, 0x43,
- 0x06, 0x70, 0xFC, 0xD8, 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, 0xFF,
- 0x1B, 0x00, 0x92, 0xFF, 0xEF, 0x00, 0x7D, 0xFE, 0x04, 0x02, 0xCF,
- 0xFD, 0x58, 0x01, 0xD7, 0x48, 0x26, 0x06, 0xBB, 0xFB, 0x19, 0x03,
- 0xED, 0xFD, 0x32, 0x01, 0x77, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFF,
- 0xFF, 0x32, 0x00, 0x44, 0xFF, 0xB9, 0x01, 0xC1, 0xFC, 0x86, 0x05,
- 0xA5, 0xF6, 0x1E, 0x14, 0xBA, 0x44, 0xF0, 0xF7, 0x7B, 0x02, 0x6B,
- 0xFF, 0xE4, 0xFF, 0x41, 0x00, 0xD6, 0xFF, 0x0B, 0x00, 0xFD, 0xFF,
- 0x33, 0x00, 0x43, 0xFF, 0xD5, 0x01, 0x3A, 0xFC, 0x2A, 0x07, 0xE7,
- 0xF1, 0xAC, 0x29, 0x66, 0x36, 0xC9, 0xF1, 0x83, 0x06, 0xDD, 0xFC,
- 0x62, 0x01, 0x81, 0xFF, 0x1D, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x08,
- 0x00, 0xBB, 0xFF, 0xF1, 0x00, 0x96, 0xFD, 0x78, 0x05, 0x0E, 0xF3,
- 0x8A, 0x3C, 0xEA, 0x21, 0x19, 0xF3, 0xE6, 0x06, 0x38, 0xFC, 0xE6,
- 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x12, 0x00, 0xB4, 0xFF,
- 0x98, 0x00, 0x32, 0xFF, 0xB0, 0x00, 0x41, 0x00, 0x30, 0xFC, 0x86,
- 0x47, 0xC6, 0x0C, 0x24, 0xF9, 0x60, 0x04, 0x4B, 0xFD, 0x7D, 0x01,
- 0x5A, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x5A,
- 0xFF, 0x7E, 0x01, 0x48, 0xFD, 0x66, 0x04, 0x18, 0xF9, 0xE8, 0x0C,
- 0x7C, 0x47, 0x19, 0xFC, 0x4D, 0x00, 0xA9, 0x00, 0x35, 0xFF, 0x96,
- 0x00, 0xB5, 0xFF, 0x12, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF,
- 0xE6, 0x01, 0x38, 0xFC, 0xE9, 0x06, 0x12, 0xF3, 0x10, 0x22, 0x6E,
- 0x3C, 0x05, 0xF3, 0x7E, 0x05, 0x91, 0xFD, 0xF4, 0x00, 0xBA, 0xFF,
- 0x09, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x82, 0xFF, 0x60,
- 0x01, 0xE0, 0xFC, 0x7F, 0x06, 0xCC, 0xF1, 0x85, 0x36, 0x87, 0x29,
- 0xEB, 0xF1, 0x2A, 0x07, 0x39, 0xFC, 0xD6, 0x01, 0x43, 0xFF, 0x33,
- 0x00, 0xFD, 0xFF, 0x0B, 0x00, 0xD5, 0xFF, 0x42, 0x00, 0xE1, 0xFF,
- 0x71, 0xFF, 0x71, 0x02, 0x02, 0xF8, 0xCC, 0x44, 0xFA, 0x13, 0xB0,
- 0xF6, 0x81, 0x05, 0xC3, 0xFC, 0xB8, 0x01, 0x44, 0xFF, 0x31, 0x00,
- 0xFF, 0xFF, 0x00, 0x00, 0x22, 0x00, 0x77, 0xFF, 0x34, 0x01, 0xEA,
- 0xFD, 0x1F, 0x03, 0xAE, 0xFB, 0x45, 0x06, 0xD5, 0x48, 0x3C, 0x01,
- 0xDC, 0xFD, 0xFD, 0x01, 0x80, 0xFE, 0xED, 0x00, 0x93, 0xFF, 0x1B,
- 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD8, 0x01, 0x6F, 0xFC,
- 0x47, 0x06, 0xD7, 0xF4, 0x5D, 0x1A, 0x74, 0x41, 0x48, 0xF5, 0x04,
- 0x04, 0x80, 0xFE, 0x69, 0x00, 0xFF, 0xFF, 0xEF, 0xFF, 0x05, 0x00,
- 0xFD, 0xFF, 0x2B, 0x00, 0x59, 0xFF, 0xAE, 0x01, 0x6A, 0xFC, 0x0D,
- 0x07, 0x80, 0xF1, 0xB8, 0x2F, 0xCF, 0x30, 0x7D, 0xF1, 0xFF, 0x06,
- 0x78, 0xFC, 0xA5, 0x01, 0x5F, 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0x05,
- 0x00, 0xF3, 0xFF, 0xF4, 0xFF, 0x80, 0x00, 0x58, 0xFE, 0x46, 0x04,
- 0xDD, 0xF4, 0xC3, 0x40, 0x8C, 0x1B, 0x89, 0xF4, 0x66, 0x06, 0x63,
- 0xFC, 0xDC, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x19, 0x00,
- 0x98, 0xFF, 0xE0, 0x00, 0x9C, 0xFE, 0xC8, 0x01, 0x3F, 0xFE, 0x62,
- 0x00, 0xB8, 0x48, 0x3F, 0x07, 0x47, 0xFB, 0x53, 0x03, 0xD0, 0xFD,
- 0x40, 0x01, 0x72, 0xFF, 0x23, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30,
- 0x00, 0x47, 0xFF, 0xB0, 0x01, 0xD6, 0xFC, 0x58, 0x05, 0x0D, 0xF7,
- 0xD7, 0x12, 0x4E, 0x45, 0x96, 0xF8, 0x20, 0x02, 0xA0, 0xFF, 0xC7,
- 0xFF, 0x4F, 0x00, 0xD0, 0xFF, 0x0C, 0x00, 0xFD, 0xFF, 0x34, 0x00,
- 0x40, 0xFF, 0xDB, 0x01, 0x35, 0xFC, 0x26, 0x07, 0x0E, 0xF2, 0x60,
- 0x28, 0x82, 0x37, 0xED, 0xF1, 0x5E, 0x06, 0xF8, 0xFC, 0x51, 0x01,
- 0x8A, 0xFF, 0x1A, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00, 0xB0,
- 0xFF, 0x07, 0x01, 0x72, 0xFD, 0xAE, 0x05, 0xC4, 0xF2, 0x90, 0x3B,
- 0x3F, 0x23, 0xD9, 0xF2, 0xF9, 0x06, 0x34, 0xFC, 0xE6, 0x01, 0x38,
- 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x11, 0x00, 0xBA, 0xFF, 0x89, 0x00,
- 0x51, 0xFF, 0x77, 0x00, 0xA7, 0x00, 0x64, 0xFB, 0x26, 0x47, 0xFC,
- 0x0D, 0xB4, 0xF8, 0x95, 0x04, 0x31, 0xFD, 0x88, 0x01, 0x56, 0xFF,
- 0x2C, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x29, 0x00, 0x5E, 0xFF, 0x72,
- 0x01, 0x62, 0xFD, 0x2F, 0x04, 0x89, 0xF9, 0xB6, 0x0B, 0xD2, 0x47,
- 0xEB, 0xFC, 0xE4, 0xFF, 0xE3, 0x00, 0x16, 0xFF, 0xA5, 0x00, 0xAF,
- 0xFF, 0x13, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01,
- 0x3E, 0xFC, 0xD3, 0x06, 0x56, 0xF3, 0xBA, 0x20, 0x61, 0x3D, 0x56,
- 0xF3, 0x45, 0x05, 0xB7, 0xFD, 0xDE, 0x00, 0xC5, 0xFF, 0x05, 0x00,
- 0x02, 0x00, 0xFE, 0xFF, 0x20, 0x00, 0x7A, 0xFF, 0x70, 0x01, 0xC7,
- 0xFC, 0xA0, 0x06, 0xAE, 0xF1, 0x65, 0x35, 0xD1, 0x2A, 0xCA, 0xF1,
- 0x2A, 0x07, 0x40, 0xFC, 0xD0, 0x01, 0x47, 0xFF, 0x32, 0x00, 0xFD,
- 0xFF, 0x09, 0x00, 0xDB, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x3D, 0xFF,
- 0xC9, 0x02, 0x64, 0xF7, 0x2F, 0x44, 0x44, 0x15, 0x4A, 0xF6, 0xAD,
- 0x05, 0xAF, 0xFC, 0xC0, 0x01, 0x41, 0xFF, 0x32, 0x00, 0xFF, 0xFF,
- 0x00, 0x00, 0x21, 0x00, 0x7C, 0xFF, 0x26, 0x01, 0x08, 0xFE, 0xE4,
- 0x02, 0x21, 0xFC, 0x31, 0x05, 0xEB, 0x48, 0x37, 0x02, 0x6B, 0xFD,
- 0x39, 0x02, 0x61, 0xFE, 0xFC, 0x00, 0x8D, 0xFF, 0x1C, 0x00, 0xFE,
- 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD3, 0x01, 0x7D, 0xFC, 0x23, 0x06,
- 0x32, 0xF5, 0x0C, 0x19, 0x38, 0x42, 0xC7, 0xF5, 0xB8, 0x03, 0xAF,
- 0xFE, 0x4E, 0x00, 0x0C, 0x00, 0xEA, 0xFF, 0x06, 0x00, 0xFD, 0xFF,
- 0x2D, 0x00, 0x54, 0xFF, 0xB8, 0x01, 0x5D, 0xFC, 0x1A, 0x07, 0x8A,
- 0xF1, 0x7B, 0x2E, 0x04, 0x32, 0x7F, 0xF1, 0xEC, 0x06, 0x8A, 0xFC,
- 0x98, 0x01, 0x65, 0xFF, 0x27, 0x00, 0xFD, 0xFF, 0x04, 0x00, 0xF8,
- 0xFF, 0xE7, 0xFF, 0x99, 0x00, 0x2C, 0xFE, 0x8C, 0x04, 0x6D, 0xF4,
- 0xF0, 0x3F, 0xE0, 0x1C, 0x34, 0xF4, 0x85, 0x06, 0x57, 0xFC, 0xE0,
- 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x18, 0x00, 0x9E, 0xFF,
- 0xD1, 0x00, 0xBB, 0xFE, 0x8D, 0x01, 0xAE, 0xFE, 0x74, 0xFF, 0x8D,
- 0x48, 0x5D, 0x08, 0xD4, 0xFA, 0x8D, 0x03, 0xB3, 0xFD, 0x4E, 0x01,
- 0x6D, 0xFF, 0x25, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4A,
- 0xFF, 0xA7, 0x01, 0xEC, 0xFC, 0x28, 0x05, 0x77, 0xF7, 0x92, 0x11,
- 0xD7, 0x45, 0x43, 0xF9, 0xC3, 0x01, 0xD6, 0xFF, 0xA9, 0xFF, 0x5E,
- 0x00, 0xCB, 0xFF, 0x0D, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x3D, 0xFF,
- 0xDF, 0x01, 0x32, 0xFC, 0x1F, 0x07, 0x3B, 0xF2, 0x11, 0x27, 0x97,
- 0x38, 0x19, 0xF2, 0x36, 0x06, 0x15, 0xFD, 0x3F, 0x01, 0x93, 0xFF,
- 0x17, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x10, 0x00, 0xA6, 0xFF, 0x1B,
- 0x01, 0x50, 0xFD, 0xE1, 0x05, 0x82, 0xF2, 0x8F, 0x3A, 0x92, 0x24,
- 0x9D, 0xF2, 0x09, 0x07, 0x32, 0xFC, 0xE4, 0x01, 0x39, 0xFF, 0x36,
- 0x00, 0xFD, 0xFF, 0x0F, 0x00, 0xC0, 0xFF, 0x7A, 0x00, 0x70, 0xFF,
- 0x3E, 0x00, 0x0C, 0x01, 0xA1, 0xFA, 0xBB, 0x46, 0x36, 0x0F, 0x45,
- 0xF8, 0xC9, 0x04, 0x18, 0xFD, 0x93, 0x01, 0x52, 0xFF, 0x2D, 0x00,
- 0xFF, 0xFF, 0x00, 0x00, 0x28, 0x00, 0x63, 0xFF, 0x66, 0x01, 0x7D,
- 0xFD, 0xF8, 0x03, 0xFB, 0xF9, 0x89, 0x0A, 0x1D, 0x48, 0xC5, 0xFD,
- 0x7A, 0xFF, 0x1D, 0x01, 0xF7, 0xFE, 0xB4, 0x00, 0xA9, 0xFF, 0x15,
- 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE5, 0x01, 0x45, 0xFC,
- 0xBB, 0x06, 0xA0, 0xF3, 0x64, 0x1F, 0x4A, 0x3E, 0xB0, 0xF3, 0x08,
- 0x05, 0xDE, 0xFD, 0xC7, 0x00, 0xD0, 0xFF, 0x00, 0x00, 0x02, 0x00,
- 0xFE, 0xFF, 0x23, 0x00, 0x72, 0xFF, 0x7F, 0x01, 0xB0, 0xFC, 0xBE,
- 0x06, 0x97, 0xF1, 0x3F, 0x34, 0x19, 0x2C, 0xAD, 0xF1, 0x28, 0x07,
- 0x48, 0xFC, 0xC9, 0x01, 0x4B, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x08,
- 0x00, 0xE0, 0xFF, 0x26, 0x00, 0x1A, 0x00, 0x0B, 0xFF, 0x1E, 0x03,
- 0xCD, 0xF6, 0x89, 0x43, 0x91, 0x16, 0xE7, 0xF5, 0xD8, 0x05, 0x9D,
- 0xFC, 0xC7, 0x01, 0x3E, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x00, 0x00,
- 0x1F, 0x00, 0x82, 0xFF, 0x18, 0x01, 0x27, 0xFE, 0xA9, 0x02, 0x94,
- 0xFC, 0x24, 0x04, 0xF5, 0x48, 0x39, 0x03, 0xF9, 0xFC, 0x74, 0x02,
- 0x42, 0xFE, 0x0B, 0x01, 0x87, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x34,
- 0x00, 0x3C, 0xFF, 0xCD, 0x01, 0x8E, 0xFC, 0xFC, 0x05, 0x90, 0xF5,
- 0xBB, 0x17, 0xEE, 0x42, 0x4E, 0xF6, 0x68, 0x03, 0xDF, 0xFE, 0x33,
- 0x00, 0x1A, 0x00, 0xE5, 0xFF, 0x07, 0x00, 0xFD, 0xFF, 0x2F, 0x00,
- 0x4F, 0xFF, 0xC2, 0x01, 0x51, 0xFC, 0x23, 0x07, 0x9A, 0xF1, 0x3A,
- 0x2D, 0x35, 0x33, 0x89, 0xF1, 0xD5, 0x06, 0x9D, 0xFC, 0x8B, 0x01,
- 0x6C, 0xFF, 0x25, 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFC, 0xFF, 0xDB,
- 0xFF, 0xB2, 0x00, 0x02, 0xFE, 0xCF, 0x04, 0x05, 0xF4, 0x16, 0x3F,
- 0x36, 0x1E, 0xE4, 0xF3, 0xA3, 0x06, 0x4D, 0xFC, 0xE3, 0x01, 0x36,
- 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x16, 0x00, 0xA4, 0xFF, 0xC2, 0x00,
- 0xDB, 0xFE, 0x52, 0x01, 0x1B, 0xFF, 0x8D, 0xFE, 0x57, 0x48, 0x81,
- 0x09, 0x61, 0xFA, 0xC6, 0x03, 0x96, 0xFD, 0x5B, 0x01, 0x68, 0xFF,
- 0x26, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x4E, 0xFF, 0x9D,
- 0x01, 0x03, 0xFD, 0xF7, 0x04, 0xE3, 0xF7, 0x51, 0x10, 0x55, 0x46,
- 0xF9, 0xF9, 0x63, 0x01, 0x0D, 0x00, 0x8B, 0xFF, 0x6D, 0x00, 0xC5,
- 0xFF, 0x0E, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xE2, 0x01,
- 0x31, 0xFC, 0x15, 0x07, 0x6D, 0xF2, 0xBF, 0x25, 0xA5, 0x39, 0x4D,
- 0xF2, 0x0B, 0x06, 0x33, 0xFD, 0x2D, 0x01, 0x9D, 0xFF, 0x13, 0x00,
- 0xFF, 0xFF, 0xFF, 0xFF, 0x14, 0x00, 0x9C, 0xFF, 0x2F, 0x01, 0x30,
- 0xFD, 0x10, 0x06, 0x47, 0xF2, 0x87, 0x39, 0xE5, 0x25, 0x67, 0xF2,
- 0x16, 0x07, 0x31, 0xFC, 0xE2, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFD,
- 0xFF, 0x0E, 0x00, 0xC6, 0xFF, 0x6B, 0x00, 0x8E, 0xFF, 0x06, 0x00,
- 0x6E, 0x01, 0xE4, 0xF9, 0x48, 0x46, 0x75, 0x10, 0xD7, 0xF7, 0xFC,
- 0x04, 0x00, 0xFD, 0x9E, 0x01, 0x4E, 0xFF, 0x2E, 0x00, 0xFF, 0xFF,
- 0x00, 0x00, 0x26, 0x00, 0x68, 0xFF, 0x59, 0x01, 0x99, 0xFD, 0xC0,
- 0x03, 0x6E, 0xFA, 0x61, 0x09, 0x5D, 0x48, 0xA6, 0xFE, 0x0F, 0xFF,
- 0x58, 0x01, 0xD7, 0xFE, 0xC3, 0x00, 0xA3, 0xFF, 0x16, 0x00, 0xFE,
- 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE3, 0x01, 0x4E, 0xFC, 0xA0, 0x06,
- 0xED, 0xF3, 0x0F, 0x1E, 0x2D, 0x3F, 0x10, 0xF4, 0xC8, 0x04, 0x07,
- 0xFE, 0xAF, 0x00, 0xDC, 0xFF, 0xFC, 0xFF, 0x03, 0x00, 0xFD, 0xFF,
- 0x25, 0x00, 0x6B, 0xFF, 0x8D, 0x01, 0x9B, 0xFC, 0xD8, 0x06, 0x87,
- 0xF1, 0x13, 0x33, 0x5E, 0x2D, 0x98, 0xF1, 0x22, 0x07, 0x52, 0xFC,
- 0xC1, 0x01, 0x4F, 0xFF, 0x2F, 0x00, 0xFD, 0xFF, 0x07, 0x00, 0xE5,
- 0xFF, 0x18, 0x00, 0x36, 0x00, 0xD9, 0xFE, 0x71, 0x03, 0x3F, 0xF6,
- 0xDB, 0x42, 0xE0, 0x17, 0x86, 0xF5, 0x00, 0x06, 0x8C, 0xFC, 0xCE,
- 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x1D, 0x00, 0x88, 0xFF,
- 0x09, 0x01, 0x45, 0xFE, 0x6E, 0x02, 0x06, 0xFD, 0x1C, 0x03, 0xF4,
- 0x48, 0x41, 0x04, 0x87, 0xFC, 0xB0, 0x02, 0x23, 0xFE, 0x19, 0x01,
- 0x81, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x3F,
- 0xFF, 0xC6, 0x01, 0x9F, 0xFC, 0xD3, 0x05, 0xF1, 0xF5, 0x6C, 0x16,
- 0x9E, 0x43, 0xDD, 0xF6, 0x15, 0x03, 0x10, 0xFF, 0x17, 0x00, 0x28,
- 0x00, 0xDF, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x30, 0x00, 0x4A, 0xFF,
- 0xCA, 0x01, 0x47, 0xFC, 0x28, 0x07, 0xB0, 0xF1, 0xF5, 0x2B, 0x60,
- 0x34, 0x9A, 0xF1, 0xBB, 0x06, 0xB3, 0xFC, 0x7D, 0x01, 0x73, 0xFF,
- 0x22, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x01, 0x00, 0xCF, 0xFF, 0xC9,
- 0x00, 0xDA, 0xFD, 0x0F, 0x05, 0xA5, 0xF3, 0x31, 0x3E, 0x8A, 0x1F,
- 0x97, 0xF3, 0xBD, 0x06, 0x44, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36,
- 0x00, 0xFD, 0xFF, 0x15, 0x00, 0xAA, 0xFF, 0xB3, 0x00, 0xFA, 0xFE,
- 0x17, 0x01, 0x86, 0xFF, 0xAC, 0xFD, 0x16, 0x48, 0xAA, 0x0A, 0xEE,
- 0xF9, 0xFE, 0x03, 0x7A, 0xFD, 0x67, 0x01, 0x63, 0xFF, 0x28, 0x00,
- 0x00, 0x00, 0xFF, 0xFF, 0x2D, 0x00, 0x52, 0xFF, 0x92, 0x01, 0x1B,
- 0xFD, 0xC4, 0x04, 0x51, 0xF8, 0x13, 0x0F, 0xC8, 0x46, 0xB6, 0xFA,
- 0x01, 0x01, 0x44, 0x00, 0x6C, 0xFF, 0x7B, 0x00, 0xBF, 0xFF, 0x10,
- 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE5, 0x01, 0x32, 0xFC,
- 0x08, 0x07, 0xA4, 0xF2, 0x6D, 0x24, 0xAD, 0x3A, 0x88, 0xF2, 0xDB,
- 0x05, 0x53, 0xFD, 0x19, 0x01, 0xA7, 0xFF, 0x10, 0x00, 0x00, 0x00,
- 0xFF, 0xFF, 0x17, 0x00, 0x92, 0xFF, 0x41, 0x01, 0x11, 0xFD, 0x3B,
- 0x06, 0x14, 0xF2, 0x78, 0x38, 0x36, 0x27, 0x35, 0xF2, 0x20, 0x07,
- 0x33, 0xFC, 0xDF, 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0D,
- 0x00, 0xCB, 0xFF, 0x5C, 0x00, 0xAC, 0xFF, 0xD0, 0xFF, 0xCD, 0x01,
- 0x30, 0xF9, 0xC8, 0x45, 0xB6, 0x11, 0x6B, 0xF7, 0x2D, 0x05, 0xE9,
- 0xFC, 0xA8, 0x01, 0x4A, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x00, 0x00,
- 0x25, 0x00, 0x6D, 0xFF, 0x4C, 0x01, 0xB6, 0xFD, 0x86, 0x03, 0xE1,
- 0xFA, 0x3D, 0x08, 0x92, 0x48, 0x8E, 0xFF, 0xA1, 0xFE, 0x93, 0x01,
- 0xB8, 0xFE, 0xD3, 0x00, 0x9D, 0xFF, 0x18, 0x00, 0xFE, 0xFF, 0x36,
- 0x00, 0x37, 0xFF, 0xE0, 0x01, 0x58, 0xFC, 0x82, 0x06, 0x3E, 0xF4,
- 0xBA, 0x1C, 0x07, 0x40, 0x79, 0xF4, 0x84, 0x04, 0x31, 0xFE, 0x96,
- 0x00, 0xE8, 0xFF, 0xF7, 0xFF, 0x04, 0x00, 0xFD, 0xFF, 0x28, 0x00,
- 0x64, 0xFF, 0x9A, 0x01, 0x88, 0xFC, 0xEE, 0x06, 0x7E, 0xF1, 0xE3,
- 0x31, 0x9F, 0x2E, 0x88, 0xF1, 0x19, 0x07, 0x5E, 0xFC, 0xB7, 0x01,
- 0x54, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, 0x06, 0x00, 0xEA, 0xFF, 0x0B,
- 0x00, 0x51, 0x00, 0xAA, 0xFE, 0xC0, 0x03, 0xB8, 0xF5, 0x21, 0x42,
- 0x31, 0x19, 0x28, 0xF5, 0x27, 0x06, 0x7C, 0xFC, 0xD4, 0x01, 0x3A,
- 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x8D, 0xFF, 0xFA, 0x00,
- 0x64, 0xFE, 0x32, 0x02, 0x78, 0xFD, 0x1B, 0x02, 0xEA, 0x48, 0x50,
- 0x05, 0x14, 0xFC, 0xEB, 0x02, 0x05, 0xFE, 0x27, 0x01, 0x7C, 0xFF,
- 0x21, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x41, 0xFF, 0xBF,
- 0x01, 0xB2, 0xFC, 0xA9, 0x05, 0x55, 0xF6, 0x20, 0x15, 0x42, 0x44,
- 0x75, 0xF7, 0xBF, 0x02, 0x43, 0xFF, 0xFA, 0xFF, 0x36, 0x00, 0xDA,
- 0xFF, 0x0A, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x46, 0xFF, 0xD1, 0x01,
- 0x3F, 0xFC, 0x2B, 0x07, 0xCD, 0xF1, 0xAE, 0x2A, 0x86, 0x35, 0xB1,
- 0xF1, 0x9D, 0x06, 0xCA, 0xFC, 0x6E, 0x01, 0x7B, 0xFF, 0x20, 0x00,
- 0xFE, 0xFF, 0x02, 0x00, 0x05, 0x00, 0xC3, 0xFF, 0xE0, 0x00, 0xB3,
- 0xFD, 0x4B, 0x05, 0x4D, 0xF3, 0x45, 0x3D, 0xE0, 0x20, 0x4F, 0xF3,
- 0xD5, 0x06, 0x3D, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD,
- 0xFF, 0x13, 0x00, 0xAF, 0xFF, 0xA4, 0x00, 0x19, 0xFF, 0xDD, 0x00,
- 0xF0, 0xFF, 0xD4, 0xFC, 0xC9, 0x47, 0xD8, 0x0B, 0x7C, 0xF9, 0x35,
- 0x04, 0x5F, 0xFD, 0x74, 0x01, 0x5E, 0xFF, 0x29, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x2C, 0x00, 0x56, 0xFF, 0x87, 0x01, 0x34, 0xFD, 0x8F,
- 0x04, 0xC0, 0xF8, 0xD9, 0x0D, 0x31, 0x47, 0x7B, 0xFB, 0x9C, 0x00,
- 0x7D, 0x00, 0x4D, 0xFF, 0x8A, 0x00, 0xB9, 0xFF, 0x11, 0x00, 0xFD,
- 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE6, 0x01, 0x35, 0xFC, 0xF7, 0x06,
- 0xE0, 0xF2, 0x18, 0x23, 0xAB, 0x3B, 0xCC, 0xF2, 0xA8, 0x05, 0x76,
- 0xFD, 0x04, 0x01, 0xB1, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0xFE, 0xFF,
- 0x1A, 0x00, 0x89, 0xFF, 0x53, 0x01, 0xF5, 0xFC, 0x63, 0x06, 0xE9,
- 0xF1, 0x63, 0x37, 0x85, 0x28, 0x09, 0xF2, 0x27, 0x07, 0x35, 0xFC,
- 0xDA, 0x01, 0x40, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x0C, 0x00, 0xD1,
- 0xFF, 0x4E, 0x00, 0xCA, 0xFF, 0x9A, 0xFF, 0x2A, 0x02, 0x83, 0xF8,
- 0x3F, 0x45, 0xFB, 0x12, 0x01, 0xF7, 0x5D, 0x05, 0xD3, 0xFC, 0xB1,
- 0x01, 0x46, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x23, 0x00,
- 0x73, 0xFF, 0x3F, 0x01, 0xD3, 0xFD, 0x4C, 0x03, 0x54, 0xFB, 0x1F,
- 0x07, 0xBB, 0x48, 0x7D, 0x00, 0x33, 0xFE, 0xCF, 0x01, 0x98, 0xFE,
- 0xE2, 0x00, 0x97, 0xFF, 0x19, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x38,
- 0xFF, 0xDC, 0x01, 0x64, 0xFC, 0x62, 0x06, 0x93, 0xF4, 0x66, 0x1B,
- 0xD9, 0x40, 0xEA, 0xF4, 0x3E, 0x04, 0x5D, 0xFE, 0x7D, 0x00, 0xF5,
- 0xFF, 0xF3, 0xFF, 0x05, 0x00, 0xFD, 0xFF, 0x2A, 0x00, 0x5E, 0xFF,
- 0xA6, 0x01, 0x76, 0xFC, 0x01, 0x07, 0x7D, 0xF1, 0xAD, 0x30, 0xDC,
- 0x2F, 0x7F, 0xF1, 0x0C, 0x07, 0x6C, 0xFC, 0xAD, 0x01, 0x5A, 0xFF,
- 0x2B, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xEF, 0xFF, 0xFE, 0xFF, 0x6C,
- 0x00, 0x7B, 0xFE, 0x0C, 0x04, 0x3A, 0xF5, 0x5F, 0x41, 0x83, 0x1A,
- 0xCD, 0xF4, 0x4B, 0x06, 0x6D, 0xFC, 0xD9, 0x01, 0x39, 0xFF, 0x35,
- 0x00, 0xFE, 0xFF, 0x1A, 0x00, 0x93, 0xFF, 0xEC, 0x00, 0x83, 0xFE,
- 0xF7, 0x01, 0xE8, 0xFD, 0x21, 0x01, 0xD2, 0x48, 0x64, 0x06, 0xA1,
- 0xFB, 0x26, 0x03, 0xE7, 0xFD, 0x35, 0x01, 0x76, 0xFF, 0x22, 0x00,
- 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x44, 0xFF, 0xB7, 0x01, 0xC5,
- 0xFC, 0x7C, 0x05, 0xBC, 0xF6, 0xD5, 0x13, 0xDC, 0x44, 0x14, 0xF8,
- 0x67, 0x02, 0x77, 0xFF, 0xDD, 0xFF, 0x44, 0x00, 0xD5, 0xFF, 0x0B,
- 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x42, 0xFF, 0xD7, 0x01, 0x39, 0xFC,
- 0x29, 0x07, 0xEF, 0xF1, 0x62, 0x29, 0xA5, 0x36, 0xD0, 0xF1, 0x7B,
- 0x06, 0xE3, 0xFC, 0x5E, 0x01, 0x83, 0xFF, 0x1D, 0x00, 0xFE, 0xFF,
- 0x01, 0x00, 0x09, 0x00, 0xB8, 0xFF, 0xF6, 0x00, 0x8D, 0xFD, 0x84,
- 0x05, 0xFD, 0xF2, 0x52, 0x3C, 0x35, 0x22, 0x0B, 0xF3, 0xEB, 0x06,
- 0x37, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x12,
- 0x00, 0xB5, 0xFF, 0x94, 0x00, 0x39, 0xFF, 0xA3, 0x00, 0x58, 0x00,
- 0x02, 0xFC, 0x73, 0x47, 0x0B, 0x0D, 0x0B, 0xF9, 0x6C, 0x04, 0x45,
- 0xFD, 0x80, 0x01, 0x59, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x2A, 0x00, 0x5B, 0xFF, 0x7C, 0x01, 0x4E, 0xFD, 0x5A, 0x04, 0x31,
- 0xF9, 0xA4, 0x0C, 0x90, 0x47, 0x47, 0xFC, 0x36, 0x00, 0xB6, 0x00,
- 0x2E, 0xFF, 0x99, 0x00, 0xB3, 0xFF, 0x12, 0x00, 0xFD, 0xFF, 0x36,
- 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x39, 0xFC, 0xE4, 0x06, 0x21, 0xF3,
- 0xC4, 0x21, 0xA5, 0x3C, 0x16, 0xF3, 0x72, 0x05, 0x9A, 0xFD, 0xEF,
- 0x00, 0xBC, 0xFF, 0x08, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x1E, 0x00,
- 0x80, 0xFF, 0x64, 0x01, 0xDA, 0xFC, 0x87, 0x06, 0xC5, 0xF1, 0x46,
- 0x36, 0xD1, 0x29, 0xE3, 0xF1, 0x2A, 0x07, 0x3A, 0xFC, 0xD5, 0x01,
- 0x44, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x0A, 0x00, 0xD6, 0xFF, 0x3F,
- 0x00, 0xE7, 0xFF, 0x65, 0xFF, 0x85, 0x02, 0xDE, 0xF7, 0xA9, 0x44,
- 0x43, 0x14, 0x99, 0xF6, 0x8B, 0x05, 0xBF, 0xFC, 0xBA, 0x01, 0x43,
- 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x22, 0x00, 0x78, 0xFF,
- 0x31, 0x01, 0xF1, 0xFD, 0x12, 0x03, 0xC7, 0xFB, 0x07, 0x06, 0xDB,
- 0x48, 0x73, 0x01, 0xC3, 0xFD, 0x0A, 0x02, 0x79, 0xFE, 0xF1, 0x00,
- 0x91, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD7,
- 0x01, 0x72, 0xFC, 0x3F, 0x06, 0xEB, 0xF4, 0x12, 0x1A, 0xA1, 0x41,
- 0x63, 0xF5, 0xF3, 0x03, 0x8A, 0xFE, 0x63, 0x00, 0x02, 0x00, 0xEE,
- 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2C, 0x00, 0x58, 0xFF, 0xB1, 0x01,
- 0x67, 0xFC, 0x10, 0x07, 0x81, 0xF1, 0x73, 0x2F, 0x15, 0x31, 0x7C,
- 0xF1, 0xFB, 0x06, 0x7C, 0xFC, 0xA2, 0x01, 0x60, 0xFF, 0x29, 0x00,
- 0xFD, 0xFF, 0x04, 0x00, 0xF4, 0xFF, 0xF1, 0xFF, 0x85, 0x00, 0x4E,
- 0xFE, 0x56, 0x04, 0xC3, 0xF4, 0x95, 0x40, 0xD8, 0x1B, 0x76, 0xF4,
- 0x6D, 0x06, 0x60, 0xFC, 0xDD, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE,
- 0xFF, 0x19, 0x00, 0x99, 0xFF, 0xDD, 0x00, 0xA3, 0xFE, 0xBB, 0x01,
- 0x58, 0xFE, 0x2D, 0x00, 0xAF, 0x48, 0x7E, 0x07, 0x2E, 0xFB, 0x60,
- 0x03, 0xC9, 0xFD, 0x43, 0x01, 0x71, 0xFF, 0x24, 0x00, 0x00, 0x00,
- 0xFF, 0xFF, 0x30, 0x00, 0x48, 0xFF, 0xAE, 0x01, 0xDB, 0xFC, 0x4D,
- 0x05, 0x24, 0xF7, 0x8E, 0x12, 0x6D, 0x45, 0xBC, 0xF8, 0x0C, 0x02,
- 0xAC, 0xFF, 0xC0, 0xFF, 0x52, 0x00, 0xCF, 0xFF, 0x0C, 0x00, 0xFD,
- 0xFF, 0x34, 0x00, 0x3F, 0xFF, 0xDC, 0x01, 0x34, 0xFC, 0x25, 0x07,
- 0x18, 0xF2, 0x15, 0x28, 0xBF, 0x37, 0xF7, 0xF1, 0x56, 0x06, 0xFE,
- 0xFC, 0x4D, 0x01, 0x8C, 0xFF, 0x19, 0x00, 0xFF, 0xFF, 0x00, 0x00,
- 0x0D, 0x00, 0xAE, 0xFF, 0x0B, 0x01, 0x6A, 0xFD, 0xBA, 0x05, 0xB4,
- 0xF2, 0x58, 0x3B, 0x8A, 0x23, 0xCB, 0xF2, 0xFD, 0x06, 0x34, 0xFC,
- 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x10, 0x00, 0xBB,
- 0xFF, 0x85, 0x00, 0x58, 0xFF, 0x6A, 0x00, 0xBE, 0x00, 0x38, 0xFB,
- 0x0F, 0x47, 0x42, 0x0E, 0x9B, 0xF8, 0xA1, 0x04, 0x2B, 0xFD, 0x8B,
- 0x01, 0x55, 0xFF, 0x2C, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x29, 0x00,
- 0x5F, 0xFF, 0x70, 0x01, 0x68, 0xFD, 0x23, 0x04, 0xA2, 0xF9, 0x73,
- 0x0B, 0xE4, 0x47, 0x1B, 0xFD, 0xCD, 0xFF, 0xF0, 0x00, 0x0F, 0xFF,
- 0xA9, 0x00, 0xAE, 0xFF, 0x14, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36,
- 0xFF, 0xE6, 0x01, 0x3F, 0xFC, 0xCE, 0x06, 0x66, 0xF3, 0x6F, 0x20,
- 0x96, 0x3D, 0x69, 0xF3, 0x38, 0x05, 0xBF, 0xFD, 0xD9, 0x00, 0xC7,
- 0xFF, 0x04, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x20, 0x00, 0x78, 0xFF,
- 0x74, 0x01, 0xC2, 0xFC, 0xA7, 0x06, 0xA8, 0xF1, 0x25, 0x35, 0x1B,
- 0x2B, 0xC2, 0xF1, 0x2A, 0x07, 0x41, 0xFC, 0xCE, 0x01, 0x47, 0xFF,
- 0x31, 0x00, 0xFD, 0xFF, 0x09, 0x00, 0xDC, 0xFF, 0x31, 0x00, 0x04,
- 0x00, 0x32, 0xFF, 0xDC, 0x02, 0x42, 0xF7, 0x0B, 0x44, 0x8E, 0x15,
- 0x34, 0xF6, 0xB7, 0x05, 0xAB, 0xFC, 0xC1, 0x01, 0x40, 0xFF, 0x33,
- 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x7E, 0xFF, 0x23, 0x01,
- 0x0F, 0xFE, 0xD7, 0x02, 0x3B, 0xFC, 0xF5, 0x04, 0xED, 0x48, 0x70,
- 0x02, 0x52, 0xFD, 0x46, 0x02, 0x5A, 0xFE, 0xFF, 0x00, 0x8B, 0xFF,
- 0x1C, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xD2, 0x01, 0x81,
- 0xFC, 0x1A, 0x06, 0x47, 0xF5, 0xC1, 0x18, 0x60, 0x42, 0xE4, 0xF5,
- 0xA6, 0x03, 0xB9, 0xFE, 0x48, 0x00, 0x0F, 0x00, 0xE9, 0xFF, 0x07,
- 0x00, 0xFD, 0xFF, 0x2E, 0x00, 0x53, 0xFF, 0xBB, 0x01, 0x5A, 0xFC,
- 0x1C, 0x07, 0x8D, 0xF1, 0x34, 0x2E, 0x48, 0x32, 0x81, 0xF1, 0xE7,
- 0x06, 0x8E, 0xFC, 0x96, 0x01, 0x66, 0xFF, 0x27, 0x00, 0xFD, 0xFF,
- 0x04, 0x00, 0xF9, 0xFF, 0xE4, 0xFF, 0x9F, 0x00, 0x23, 0xFE, 0x9B,
- 0x04, 0x55, 0xF4, 0xC0, 0x3F, 0x2C, 0x1D, 0x22, 0xF4, 0x8C, 0x06,
- 0x55, 0xFC, 0xE1, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x17,
- 0x00, 0x9F, 0xFF, 0xCE, 0x00, 0xC2, 0xFE, 0x80, 0x01, 0xC6, 0xFE,
- 0x40, 0xFF, 0x81, 0x48, 0x9E, 0x08, 0xBA, 0xFA, 0x9A, 0x03, 0xAC,
- 0xFD, 0x51, 0x01, 0x6C, 0xFF, 0x25, 0x00, 0x00, 0x00, 0xFF, 0xFF,
- 0x2F, 0x00, 0x4B, 0xFF, 0xA4, 0x01, 0xF1, 0xFC, 0x1D, 0x05, 0x8F,
- 0xF7, 0x4A, 0x11, 0xF2, 0x45, 0x6B, 0xF9, 0xAE, 0x01, 0xE2, 0xFF,
- 0xA2, 0xFF, 0x61, 0x00, 0xC9, 0xFF, 0x0D, 0x00, 0xFD, 0xFF, 0x35,
- 0x00, 0x3D, 0xFF, 0xE0, 0x01, 0x32, 0xFC, 0x1D, 0x07, 0x45, 0xF2,
- 0xC6, 0x26, 0xD3, 0x38, 0x24, 0xF2, 0x2D, 0x06, 0x1B, 0xFD, 0x3B,
- 0x01, 0x95, 0xFF, 0x16, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x11, 0x00,
- 0xA3, 0xFF, 0x20, 0x01, 0x49, 0xFD, 0xEB, 0x05, 0x74, 0xF2, 0x54,
- 0x3A, 0xDD, 0x24, 0x91, 0xF2, 0x0C, 0x07, 0x32, 0xFC, 0xE4, 0x01,
- 0x3A, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x0F, 0x00, 0xC1, 0xFF, 0x76,
- 0x00, 0x76, 0xFF, 0x32, 0x00, 0x22, 0x01, 0x76, 0xFA, 0xA3, 0x46,
- 0x7D, 0x0F, 0x2C, 0xF8, 0xD5, 0x04, 0x13, 0xFD, 0x96, 0x01, 0x51,
- 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x64, 0xFF,
- 0x63, 0x01, 0x84, 0xFD, 0xEB, 0x03, 0x14, 0xFA, 0x47, 0x0A, 0x2C,
- 0x48, 0xF6, 0xFD, 0x63, 0xFF, 0x2B, 0x01, 0xF0, 0xFE, 0xB8, 0x00,
- 0xA8, 0xFF, 0x15, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4,
- 0x01, 0x47, 0xFC, 0xB5, 0x06, 0xB0, 0xF3, 0x19, 0x1F, 0x7E, 0x3E,
- 0xC4, 0xF3, 0xFA, 0x04, 0xE7, 0xFD, 0xC1, 0x00, 0xD3, 0xFF, 0xFF,
- 0xFF, 0x02, 0x00, 0xFE, 0xFF, 0x23, 0x00, 0x71, 0xFF, 0x82, 0x01,
- 0xAB, 0xFC, 0xC4, 0x06, 0x93, 0xF1, 0xFD, 0x33, 0x62, 0x2C, 0xA8,
- 0xF1, 0x27, 0x07, 0x4A, 0xFC, 0xC7, 0x01, 0x4C, 0xFF, 0x30, 0x00,
- 0xFD, 0xFF, 0x08, 0x00, 0xE1, 0xFF, 0x23, 0x00, 0x20, 0x00, 0x00,
- 0xFF, 0x31, 0x03, 0xAD, 0xF6, 0x65, 0x43, 0xDC, 0x16, 0xD1, 0xF5,
- 0xE1, 0x05, 0x99, 0xFC, 0xC9, 0x01, 0x3E, 0xFF, 0x33, 0x00, 0xFF,
- 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x83, 0xFF, 0x14, 0x01, 0x2D, 0xFE,
- 0x9C, 0x02, 0xAD, 0xFC, 0xE9, 0x03, 0xF6, 0x48, 0x73, 0x03, 0xE0,
- 0xFC, 0x82, 0x02, 0x3B, 0xFE, 0x0E, 0x01, 0x86, 0xFF, 0x1E, 0x00,
- 0xFE, 0xFF, 0x34, 0x00, 0x3D, 0xFF, 0xCC, 0x01, 0x91, 0xFC, 0xF3,
- 0x05, 0xA6, 0xF5, 0x70, 0x17, 0x17, 0x43, 0x6D, 0xF6, 0x56, 0x03,
- 0xEA, 0xFE, 0x2D, 0x00, 0x1D, 0x00, 0xE4, 0xFF, 0x08, 0x00, 0xFD,
- 0xFF, 0x2F, 0x00, 0x4E, 0xFF, 0xC3, 0x01, 0x4E, 0xFC, 0x24, 0x07,
- 0x9E, 0xF1, 0xF2, 0x2C, 0x78, 0x33, 0x8C, 0xF1, 0xD0, 0x06, 0xA2,
- 0xFC, 0x88, 0x01, 0x6D, 0xFF, 0x24, 0x00, 0xFD, 0xFF, 0x03, 0x00,
- 0xFD, 0xFF, 0xD8, 0xFF, 0xB7, 0x00, 0xF9, 0xFD, 0xDE, 0x04, 0xEF,
- 0xF3, 0xE4, 0x3E, 0x81, 0x1E, 0xD2, 0xF3, 0xA9, 0x06, 0x4B, 0xFC,
- 0xE3, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x16, 0x00, 0xA5,
- 0xFF, 0xBE, 0x00, 0xE2, 0xFE, 0x45, 0x01, 0x33, 0xFF, 0x5A, 0xFE,
- 0x48, 0x48, 0xC3, 0x09, 0x47, 0xFA, 0xD2, 0x03, 0x90, 0xFD, 0x5E,
- 0x01, 0x66, 0xFF, 0x27, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2E, 0x00,
- 0x4F, 0xFF, 0x9A, 0x01, 0x08, 0xFD, 0xEB, 0x04, 0xFC, 0xF7, 0x0A,
- 0x10, 0x70, 0x46, 0x22, 0xFA, 0x4D, 0x01, 0x19, 0x00, 0x84, 0xFF,
- 0x70, 0x00, 0xC4, 0xFF, 0x0F, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3B,
- 0xFF, 0xE3, 0x01, 0x31, 0xFC, 0x12, 0x07, 0x79, 0xF2, 0x73, 0x25,
- 0xDF, 0x39, 0x5A, 0xF2, 0x00, 0x06, 0x3A, 0xFD, 0x28, 0x01, 0x9F,
- 0xFF, 0x13, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x15, 0x00, 0x99, 0xFF,
- 0x33, 0x01, 0x29, 0xFD, 0x1A, 0x06, 0x3B, 0xF2, 0x4B, 0x39, 0x30,
- 0x26, 0x5B, 0xF2, 0x19, 0x07, 0x31, 0xFC, 0xE1, 0x01, 0x3C, 0xFF,
- 0x35, 0x00, 0xFD, 0xFF, 0x0E, 0x00, 0xC7, 0xFF, 0x68, 0x00, 0x95,
- 0xFF, 0xFA, 0xFF, 0x83, 0x01, 0xBB, 0xF9, 0x2B, 0x46, 0xBB, 0x10,
- 0xBF, 0xF7, 0x07, 0x05, 0xFB, 0xFC, 0xA0, 0x01, 0x4D, 0xFF, 0x2F,
- 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x26, 0x00, 0x69, 0xFF, 0x56, 0x01,
- 0xA0, 0xFD, 0xB3, 0x03, 0x87, 0xFA, 0x1F, 0x09, 0x6A, 0x48, 0xD9,
- 0xFE, 0xF6, 0xFE, 0x65, 0x01, 0xD0, 0xFE, 0xC7, 0x00, 0xA2, 0xFF,
- 0x17, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE2, 0x01, 0x50,
- 0xFC, 0x99, 0x06, 0xFE, 0xF3, 0xC3, 0x1D, 0x5E, 0x3F, 0x27, 0xF4,
- 0xB9, 0x04, 0x10, 0xFE, 0xA9, 0x00, 0xDF, 0xFF, 0xFB, 0xFF, 0x03,
- 0x00, 0xFD, 0xFF, 0x26, 0x00, 0x69, 0xFF, 0x90, 0x01, 0x96, 0xFC,
- 0xDD, 0x06, 0x85, 0xF1, 0xD0, 0x32, 0xA6, 0x2D, 0x94, 0xF1, 0x20,
- 0x07, 0x54, 0xFC, 0xBF, 0x01, 0x50, 0xFF, 0x2E, 0x00, 0xFD, 0xFF,
- 0x07, 0x00, 0xE6, 0xFF, 0x15, 0x00, 0x3C, 0x00, 0xCF, 0xFE, 0x83,
- 0x03, 0x20, 0xF6, 0xB2, 0x42, 0x2B, 0x18, 0x71, 0xF5, 0x09, 0x06,
- 0x88, 0xFC, 0xCF, 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0x1D,
- 0x00, 0x89, 0xFF, 0x06, 0x01, 0x4C, 0xFE, 0x60, 0x02, 0x1F, 0xFD,
- 0xE2, 0x02, 0xF3, 0x48, 0x7D, 0x04, 0x6E, 0xFC, 0xBD, 0x02, 0x1C,
- 0xFE, 0x1C, 0x01, 0x80, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFF, 0xFF,
- 0x33, 0x00, 0x3F, 0xFF, 0xC5, 0x01, 0xA3, 0xFC, 0xCA, 0x05, 0x07,
- 0xF6, 0x22, 0x16, 0xC3, 0x43, 0xFE, 0xF6, 0x02, 0x03, 0x1B, 0xFF,
- 0x11, 0x00, 0x2B, 0x00, 0xDE, 0xFF, 0x09, 0x00, 0xFD, 0xFF, 0x31,
- 0x00, 0x49, 0xFF, 0xCB, 0x01, 0x45, 0xFC, 0x29, 0x07, 0xB6, 0xF1,
- 0xAD, 0x2B, 0xA2, 0x34, 0x9E, 0xF1, 0xB4, 0x06, 0xB8, 0xFC, 0x7A,
- 0x01, 0x75, 0xFF, 0x22, 0x00, 0xFE, 0xFF, 0x02, 0x00, 0x02, 0x00,
- 0xCC, 0xFF, 0xCE, 0x00, 0xD1, 0xFD, 0x1D, 0x05, 0x91, 0xF3, 0xFE,
- 0x3D, 0xD7, 0x1F, 0x87, 0xF3, 0xC3, 0x06, 0x42, 0xFC, 0xE5, 0x01,
- 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x14, 0x00, 0xAB, 0xFF, 0xAF,
- 0x00, 0x01, 0xFF, 0x0A, 0x01, 0x9E, 0xFF, 0x7C, 0xFD, 0x03, 0x48,
- 0xED, 0x0A, 0xD5, 0xF9, 0x0A, 0x04, 0x74, 0xFD, 0x6A, 0x01, 0x62,
- 0xFF, 0x28, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x2D, 0x00, 0x53, 0xFF,
- 0x90, 0x01, 0x20, 0xFD, 0xB8, 0x04, 0x6A, 0xF8, 0xCD, 0x0E, 0xE1,
- 0x46, 0xE1, 0xFA, 0xEB, 0x00, 0x51, 0x00, 0x65, 0xFF, 0x7F, 0x00,
- 0xBE, 0xFF, 0x10, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE5,
- 0x01, 0x33, 0xFC, 0x04, 0x07, 0xB1, 0xF2, 0x21, 0x24, 0xE6, 0x3A,
- 0x97, 0xF2, 0xD0, 0x05, 0x5B, 0xFD, 0x15, 0x01, 0xA9, 0xFF, 0x0F,
- 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x18, 0x00, 0x90, 0xFF, 0x45, 0x01,
- 0x0B, 0xFD, 0x44, 0x06, 0x0A, 0xF2, 0x3B, 0x38, 0x80, 0x27, 0x2B,
- 0xF2, 0x22, 0x07, 0x33, 0xFC, 0xDE, 0x01, 0x3E, 0xFF, 0x34, 0x00,
- 0xFD, 0xFF, 0x0D, 0x00, 0xCD, 0xFF, 0x59, 0x00, 0xB3, 0xFF, 0xC4,
- 0xFF, 0xE2, 0x01, 0x09, 0xF9, 0xAA, 0x45, 0xFE, 0x11, 0x54, 0xF7,
- 0x38, 0x05, 0xE4, 0xFC, 0xAA, 0x01, 0x49, 0xFF, 0x30, 0x00, 0xFF,
- 0xFF, 0x00, 0x00, 0x24, 0x00, 0x6E, 0xFF, 0x49, 0x01, 0xBC, 0xFD,
- 0x7A, 0x03, 0xFA, 0xFA, 0xFD, 0x07, 0x9C, 0x48, 0xC3, 0xFF, 0x89,
- 0xFE, 0xA1, 0x01, 0xB1, 0xFE, 0xD6, 0x00, 0x9C, 0xFF, 0x18, 0x00,
- 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xDF, 0x01, 0x5B, 0xFC, 0x7B,
- 0x06, 0x50, 0xF4, 0x6E, 0x1C, 0x36, 0x40, 0x92, 0xF4, 0x75, 0x04,
- 0x3B, 0xFE, 0x91, 0x00, 0xEB, 0xFF, 0xF6, 0xFF, 0x04, 0x00, 0xFD,
- 0xFF, 0x28, 0x00, 0x63, 0xFF, 0x9D, 0x01, 0x84, 0xFC, 0xF3, 0x06,
- 0x7D, 0xF1, 0x9E, 0x31, 0xE6, 0x2E, 0x85, 0xF1, 0x16, 0x07, 0x61,
- 0xFC, 0xB5, 0x01, 0x55, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, 0x06, 0x00,
- 0xEC, 0xFF, 0x08, 0x00, 0x57, 0x00, 0x9F, 0xFE, 0xD1, 0x03, 0x9B,
- 0xF5, 0xF7, 0x41, 0x7C, 0x19, 0x13, 0xF5, 0x2F, 0x06, 0x78, 0xFC,
- 0xD5, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x8F,
- 0xFF, 0xF7, 0x00, 0x6B, 0xFE, 0x25, 0x02, 0x91, 0xFD, 0xE3, 0x01,
- 0xE5, 0x48, 0x8D, 0x05, 0xFB, 0xFB, 0xF8, 0x02, 0xFE, 0xFD, 0x2B,
- 0x01, 0x7A, 0xFF, 0x21, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x00,
- 0x42, 0xFF, 0xBD, 0x01, 0xB6, 0xFC, 0x9F, 0x05, 0x6C, 0xF6, 0xD6,
- 0x14, 0x65, 0x44, 0x98, 0xF7, 0xAC, 0x02, 0x4E, 0xFF, 0xF4, 0xFF,
- 0x39, 0x00, 0xD9, 0xFF, 0x0A, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x45,
- 0xFF, 0xD2, 0x01, 0x3D, 0xFC, 0x2B, 0x07, 0xD4, 0xF1, 0x64, 0x2A,
- 0xC6, 0x35, 0xB7, 0xF1, 0x96, 0x06, 0xCF, 0xFC, 0x6B, 0x01, 0x7D,
- 0xFF, 0x1F, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x06, 0x00, 0xC1, 0xFF,
- 0xE5, 0x00, 0xAA, 0xFD, 0x58, 0x05, 0x3A, 0xF3, 0x11, 0x3D, 0x2C,
- 0x21, 0x3F, 0xF3, 0xDA, 0x06, 0x3B, 0xFC, 0xE6, 0x01, 0x36, 0xFF,
- 0x36, 0x00, 0xFD, 0xFF, 0x13, 0x00, 0xB1, 0xFF, 0xA0, 0x00, 0x20,
- 0xFF, 0xD0, 0x00, 0x07, 0x00, 0xA4, 0xFC, 0xB6, 0x47, 0x1C, 0x0C,
- 0x63, 0xF9, 0x42, 0x04, 0x59, 0xFD, 0x76, 0x01, 0x5D, 0xFF, 0x2A,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x57, 0xFF, 0x85, 0x01,
- 0x39, 0xFD, 0x84, 0x04, 0xD9, 0xF8, 0x95, 0x0D, 0x48, 0x47, 0xA7,
- 0xFB, 0x86, 0x00, 0x8A, 0x00, 0x46, 0xFF, 0x8E, 0x00, 0xB8, 0xFF,
- 0x11, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x35,
- 0xFC, 0xF3, 0x06, 0xEE, 0xF2, 0xCD, 0x22, 0xE4, 0x3B, 0xDC, 0xF2,
- 0x9C, 0x05, 0x7E, 0xFD, 0x00, 0x01, 0xB4, 0xFF, 0x0B, 0x00, 0x01,
- 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x87, 0xFF, 0x57, 0x01, 0xEF, 0xFC,
- 0x6B, 0x06, 0xE0, 0xF1, 0x23, 0x37, 0xCE, 0x28, 0x01, 0xF2, 0x28,
- 0x07, 0x36, 0xFC, 0xD9, 0x01, 0x41, 0xFF, 0x33, 0x00, 0xFD, 0xFF,
- 0x0B, 0x00, 0xD2, 0xFF, 0x4A, 0x00, 0xD0, 0xFF, 0x8E, 0xFF, 0x3F,
- 0x02, 0x5E, 0xF8, 0x1E, 0x45, 0x44, 0x13, 0xEA, 0xF6, 0x67, 0x05,
- 0xCF, 0xFC, 0xB3, 0x01, 0x46, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x00,
- 0x00, 0x23, 0x00, 0x74, 0xFF, 0x3C, 0x01, 0xDA, 0xFD, 0x40, 0x03,
- 0x6E, 0xFB, 0xE1, 0x06, 0xC3, 0x48, 0xB3, 0x00, 0x1A, 0xFE, 0xDC,
- 0x01, 0x91, 0xFE, 0xE5, 0x00, 0x96, 0xFF, 0x1A, 0x00, 0xFE, 0xFF,
- 0x36, 0x00, 0x38, 0xFF, 0xDB, 0x01, 0x67, 0xFC, 0x5A, 0x06, 0xA6,
- 0xF4, 0x1B, 0x1B, 0x07, 0x41, 0x04, 0xF5, 0x2D, 0x04, 0x67, 0xFE,
- 0x77, 0x00, 0xF8, 0xFF, 0xF2, 0xFF, 0x05, 0x00, 0xFD, 0xFF, 0x2A,
- 0x00, 0x5C, 0xFF, 0xA8, 0x01, 0x73, 0xFC, 0x05, 0x07, 0x7D, 0xF1,
- 0x67, 0x30, 0x21, 0x30, 0x7E, 0xF1, 0x08, 0x07, 0x6F, 0xFC, 0xAB,
- 0x01, 0x5B, 0xFF, 0x2B, 0x00, 0xFD, 0xFF, 0x05, 0x00, 0xF0, 0xFF,
- 0xFB, 0xFF, 0x71, 0x00, 0x71, 0xFE, 0x1D, 0x04, 0x1F, 0xF5, 0x32,
- 0x41, 0xCE, 0x1A, 0xBA, 0xF4, 0x53, 0x06, 0x6A, 0xFC, 0xDA, 0x01,
- 0x38, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x1A, 0x00, 0x95, 0xFF, 0xE8,
- 0x00, 0x8A, 0xFE, 0xE9, 0x01, 0x01, 0xFE, 0xEA, 0x00, 0xCB, 0x48,
- 0xA2, 0x06, 0x87, 0xFB, 0x33, 0x03, 0xE0, 0xFD, 0x39, 0x01, 0x75,
- 0xFF, 0x23, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x45, 0xFF,
- 0xB5, 0x01, 0xCA, 0xFC, 0x72, 0x05, 0xD3, 0xF6, 0x8D, 0x13, 0xFD,
- 0x44, 0x39, 0xF8, 0x53, 0x02, 0x82, 0xFF, 0xD7, 0xFF, 0x47, 0x00,
- 0xD3, 0xFF, 0x0B, 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x42, 0xFF, 0xD8,
- 0x01, 0x37, 0xFC, 0x29, 0x07, 0xF8, 0xF1, 0x19, 0x29, 0xE5, 0x36,
- 0xD8, 0xF1, 0x73, 0x06, 0xE9, 0xFC, 0x5B, 0x01, 0x85, 0xFF, 0x1C,
- 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x0A, 0x00, 0xB6, 0xFF, 0xFB, 0x00,
- 0x85, 0xFD, 0x90, 0x05, 0xEC, 0xF2, 0x1C, 0x3C, 0x81, 0x22, 0xFC,
- 0xF2, 0xEF, 0x06, 0x36, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00,
- 0xFD, 0xFF, 0x12, 0x00, 0xB7, 0xFF, 0x91, 0x00, 0x40, 0xFF, 0x96,
- 0x00, 0x6F, 0x00, 0xD5, 0xFB, 0x5E, 0x47, 0x50, 0x0D, 0xF2, 0xF8,
- 0x78, 0x04, 0x3F, 0xFD, 0x82, 0x01, 0x58, 0xFF, 0x2B, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5C, 0xFF, 0x79, 0x01, 0x53, 0xFD,
- 0x4E, 0x04, 0x4A, 0xF9, 0x60, 0x0C, 0xA3, 0x47, 0x76, 0xFC, 0x1F,
- 0x00, 0xC3, 0x00, 0x27, 0xFF, 0x9D, 0x00, 0xB2, 0xFF, 0x13, 0x00,
- 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x3A, 0xFC, 0xDF,
- 0x06, 0x30, 0xF3, 0x78, 0x21, 0xDB, 0x3C, 0x28, 0xF3, 0x65, 0x05,
- 0xA2, 0xFD, 0xEA, 0x00, 0xBE, 0xFF, 0x07, 0x00, 0x01, 0x00, 0xFE,
- 0xFF, 0x1E, 0x00, 0x7F, 0xFF, 0x67, 0x01, 0xD5, 0xFC, 0x8E, 0x06,
- 0xBE, 0xF1, 0x06, 0x36, 0x1A, 0x2A, 0xDC, 0xF1, 0x2A, 0x07, 0x3C,
- 0xFC, 0xD3, 0x01, 0x44, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x0A, 0x00,
- 0xD8, 0xFF, 0x3C, 0x00, 0xEE, 0xFF, 0x5A, 0xFF, 0x98, 0x02, 0xBB,
- 0xF7, 0x87, 0x44, 0x8C, 0x14, 0x83, 0xF6, 0x95, 0x05, 0xBA, 0xFC,
- 0xBB, 0x01, 0x43, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x21,
- 0x00, 0x79, 0xFF, 0x2E, 0x01, 0xF7, 0xFD, 0x05, 0x03, 0xE1, 0xFB,
- 0xCA, 0x05, 0xDF, 0x48, 0xAB, 0x01, 0xAA, 0xFD, 0x18, 0x02, 0x72,
- 0xFE, 0xF4, 0x00, 0x90, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, 0x35, 0x00,
- 0x39, 0xFF, 0xD6, 0x01, 0x75, 0xFC, 0x37, 0x06, 0xFF, 0xF4, 0xC7,
- 0x19, 0xCC, 0x41, 0x7F, 0xF5, 0xE2, 0x03, 0x95, 0xFE, 0x5D, 0x00,
- 0x05, 0x00, 0xED, 0xFF, 0x06, 0x00, 0xFD, 0xFF, 0x2C, 0x00, 0x57,
- 0xFF, 0xB3, 0x01, 0x64, 0xFC, 0x13, 0x07, 0x83, 0xF1, 0x2C, 0x2F,
- 0x5A, 0x31, 0x7D, 0xF1, 0xF7, 0x06, 0x80, 0xFC, 0x9F, 0x01, 0x61,
- 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0x04, 0x00, 0xF5, 0xFF, 0xEE, 0xFF,
- 0x8B, 0x00, 0x44, 0xFE, 0x65, 0x04, 0xAA, 0xF4, 0x66, 0x40, 0x23,
- 0x1C, 0x63, 0xF4, 0x74, 0x06, 0x5D, 0xFC, 0xDE, 0x01, 0x37, 0xFF,
- 0x36, 0x00, 0xFE, 0xFF, 0x19, 0x00, 0x9A, 0xFF, 0xD9, 0x00, 0xAA,
- 0xFE, 0xAE, 0x01, 0x70, 0xFE, 0xF8, 0xFF, 0xA6, 0x48, 0xBE, 0x07,
- 0x14, 0xFB, 0x6D, 0x03, 0xC3, 0xFD, 0x46, 0x01, 0x70, 0xFF, 0x24,
- 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30, 0x00, 0x48, 0xFF, 0xAC, 0x01,
- 0xDF, 0xFC, 0x43, 0x05, 0x3C, 0xF7, 0x46, 0x12, 0x8D, 0x45, 0xE2,
- 0xF8, 0xF7, 0x01, 0xB8, 0xFF, 0xB9, 0xFF, 0x56, 0x00, 0xCE, 0xFF,
- 0x0C, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x3F, 0xFF, 0xDD, 0x01, 0x34,
- 0xFC, 0x23, 0x07, 0x21, 0xF2, 0xCB, 0x27, 0xFE, 0x37, 0x00, 0xF2,
- 0x4D, 0x06, 0x04, 0xFD, 0x49, 0x01, 0x8E, 0xFF, 0x19, 0x00, 0xFF,
- 0xFF, 0x00, 0x00, 0x0E, 0x00, 0xAB, 0xFF, 0x10, 0x01, 0x62, 0xFD,
- 0xC5, 0x05, 0xA5, 0xF2, 0x1F, 0x3B, 0xD6, 0x23, 0xBE, 0xF2, 0x01,
- 0x07, 0x33, 0xFC, 0xE5, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF,
- 0x10, 0x00, 0xBD, 0xFF, 0x82, 0x00, 0x5E, 0xFF, 0x5D, 0x00, 0xD4,
- 0x00, 0x0C, 0xFB, 0xF9, 0x46, 0x87, 0x0E, 0x82, 0xF8, 0xAD, 0x04,
- 0x26, 0xFD, 0x8D, 0x01, 0x54, 0xFF, 0x2C, 0x00, 0xFF, 0xFF, 0x00,
- 0x00, 0x29, 0x00, 0x60, 0xFF, 0x6D, 0x01, 0x6E, 0xFD, 0x17, 0x04,
- 0xBC, 0xF9, 0x30, 0x0B, 0xF4, 0x47, 0x4B, 0xFD, 0xB5, 0xFF, 0xFD,
- 0x00, 0x08, 0xFF, 0xAC, 0x00, 0xAC, 0xFF, 0x14, 0x00, 0xFD, 0xFF,
- 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x41, 0xFC, 0xC8, 0x06, 0x76,
- 0xF3, 0x22, 0x20, 0xCA, 0x3D, 0x7D, 0xF3, 0x2A, 0x05, 0xC8, 0xFD,
- 0xD4, 0x00, 0xCA, 0xFF, 0x03, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x21,
- 0x00, 0x77, 0xFF, 0x77, 0x01, 0xBD, 0xFC, 0xAE, 0x06, 0xA3, 0xF1,
- 0xE3, 0x34, 0x64, 0x2B, 0xBC, 0xF1, 0x2A, 0x07, 0x43, 0xFC, 0xCD,
- 0x01, 0x48, 0xFF, 0x31, 0x00, 0xFD, 0xFF, 0x09, 0x00, 0xDD, 0xFF,
- 0x2E, 0x00, 0x0A, 0x00, 0x27, 0xFF, 0xEF, 0x02, 0x20, 0xF7, 0xE7,
- 0x43, 0xD8, 0x15, 0x1E, 0xF6, 0xC0, 0x05, 0xA7, 0xFC, 0xC3, 0x01,
- 0x40, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x7F,
- 0xFF, 0x20, 0x01, 0x16, 0xFE, 0xCA, 0x02, 0x54, 0xFC, 0xB9, 0x04,
- 0xF2, 0x48, 0xA9, 0x02, 0x39, 0xFD, 0x53, 0x02, 0x53, 0xFE, 0x03,
- 0x01, 0x8A, 0xFF, 0x1D, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3B, 0xFF,
- 0xD1, 0x01, 0x84, 0xFC, 0x12, 0x06, 0x5C, 0xF5, 0x76, 0x18, 0x89,
- 0x42, 0x02, 0xF6, 0x94, 0x03, 0xC4, 0xFE, 0x42, 0x00, 0x12, 0x00,
- 0xE8, 0xFF, 0x07, 0x00, 0xFD, 0xFF, 0x2E, 0x00, 0x51, 0xFF, 0xBD,
- 0x01, 0x57, 0xFC, 0x1E, 0x07, 0x90, 0xF1, 0xED, 0x2D, 0x8C, 0x32,
- 0x83, 0xF1, 0xE2, 0x06, 0x92, 0xFC, 0x93, 0x01, 0x68, 0xFF, 0x26,
- 0x00, 0xFD, 0xFF, 0x03, 0x00, 0xFA, 0xFF, 0xE2, 0xFF, 0xA4, 0x00,
- 0x19, 0xFE, 0xAA, 0x04, 0x3E, 0xF4, 0x90, 0x3F, 0x78, 0x1D, 0x10,
- 0xF4, 0x93, 0x06, 0x52, 0xFC, 0xE1, 0x01, 0x36, 0xFF, 0x36, 0x00,
- 0xFE, 0xFF, 0x17, 0x00, 0xA0, 0xFF, 0xCA, 0x00, 0xC9, 0xFE, 0x73,
- 0x01, 0xDE, 0xFE, 0x0C, 0xFF, 0x76, 0x48, 0xDE, 0x08, 0xA1, 0xFA,
- 0xA6, 0x03, 0xA6, 0xFD, 0x53, 0x01, 0x6A, 0xFF, 0x26, 0x00, 0x00,
- 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4C, 0xFF, 0xA2, 0x01, 0xF6, 0xFC,
- 0x12, 0x05, 0xA7, 0xF7, 0x03, 0x11, 0x10, 0x46, 0x93, 0xF9, 0x98,
- 0x01, 0xEE, 0xFF, 0x9B, 0xFF, 0x64, 0x00, 0xC8, 0xFF, 0x0E, 0x00,
- 0xFD, 0xFF, 0x35, 0x00, 0x3C, 0xFF, 0xE1, 0x01, 0x32, 0xFC, 0x1B,
- 0x07, 0x50, 0xF2, 0x7B, 0x26, 0x11, 0x39, 0x2F, 0xF2, 0x23, 0x06,
- 0x22, 0xFD, 0x37, 0x01, 0x97, 0xFF, 0x15, 0x00, 0xFF, 0xFF, 0x00,
- 0x00, 0x12, 0x00, 0xA1, 0xFF, 0x24, 0x01, 0x41, 0xFD, 0xF6, 0x05,
- 0x67, 0xF2, 0x1A, 0x3A, 0x29, 0x25, 0x84, 0xF2, 0x0F, 0x07, 0x31,
- 0xFC, 0xE3, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x0F, 0x00,
- 0xC2, 0xFF, 0x73, 0x00, 0x7D, 0xFF, 0x25, 0x00, 0x38, 0x01, 0x4C,
- 0xFA, 0x89, 0x46, 0xC3, 0x0F, 0x14, 0xF8, 0xE0, 0x04, 0x0D, 0xFD,
- 0x98, 0x01, 0x50, 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x27,
- 0x00, 0x65, 0xFF, 0x60, 0x01, 0x8A, 0xFD, 0xDF, 0x03, 0x2E, 0xFA,
- 0x04, 0x0A, 0x3A, 0x48, 0x28, 0xFE, 0x4B, 0xFF, 0x38, 0x01, 0xE9,
- 0xFE, 0xBB, 0x00, 0xA6, 0xFF, 0x16, 0x00, 0xFE, 0xFF, 0x36, 0x00,
- 0x36, 0xFF, 0xE4, 0x01, 0x49, 0xFC, 0xAF, 0x06, 0xC1, 0xF3, 0xCD,
- 0x1E, 0xB1, 0x3E, 0xD9, 0xF3, 0xEC, 0x04, 0xF0, 0xFD, 0xBC, 0x00,
- 0xD5, 0xFF, 0xFE, 0xFF, 0x03, 0x00, 0xFD, 0xFF, 0x24, 0x00, 0x6F,
- 0xFF, 0x85, 0x01, 0xA6, 0xFC, 0xCA, 0x06, 0x8F, 0xF1, 0xBB, 0x33,
- 0xAB, 0x2C, 0xA3, 0xF1, 0x26, 0x07, 0x4C, 0xFC, 0xC5, 0x01, 0x4D,
- 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x08, 0x00, 0xE2, 0xFF, 0x20, 0x00,
- 0x26, 0x00, 0xF5, 0xFE, 0x43, 0x03, 0x8D, 0xF6, 0x3C, 0x43, 0x25,
- 0x17, 0xBB, 0xF5, 0xEA, 0x05, 0x95, 0xFC, 0xCA, 0x01, 0x3D, 0xFF,
- 0x34, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0x1E, 0x00, 0x84, 0xFF, 0x11,
- 0x01, 0x34, 0xFE, 0x8F, 0x02, 0xC7, 0xFC, 0xAE, 0x03, 0xF7, 0x48,
- 0xAE, 0x03, 0xC7, 0xFC, 0x8F, 0x02, 0x34, 0xFE, 0x11, 0x01, 0x84,
- 0xFF, 0x1E, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01,
- 0x3D, 0xFC, 0xD6, 0x06, 0x4C, 0xF3, 0xED, 0x20, 0x3D, 0x3D, 0x4A,
- 0xF3, 0x4E, 0x05, 0xB1, 0xFD, 0xE1, 0x00, 0xC3, 0xFF, 0x05, 0x00,
- 0x02, 0x00, 0x02, 0x00, 0x05, 0x00, 0xC3, 0xFF, 0xE1, 0x00, 0xB1,
- 0xFD, 0x4E, 0x05, 0x4A, 0xF3, 0x3D, 0x3D, 0xED, 0x20, 0x4C, 0xF3,
- 0xD6, 0x06, 0x3D, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD,
- 0xFF, 0x00, 0x00, 0x1E, 0x00, 0x84, 0xFF, 0x11, 0x01, 0x34, 0xFE,
- 0x8F, 0x02, 0xC7, 0xFC, 0xAE, 0x03, 0xF7, 0x48, 0xAE, 0x03, 0xC7,
- 0xFC, 0x8F, 0x02, 0x34, 0xFE, 0x11, 0x01, 0x84, 0xFF, 0x1E, 0x00,
- 0xFD, 0xFF, 0x30, 0x00, 0x4D, 0xFF, 0xC5, 0x01, 0x4C, 0xFC, 0x26,
- 0x07, 0xA3, 0xF1, 0xAB, 0x2C, 0xBB, 0x33, 0x8F, 0xF1, 0xCA, 0x06,
- 0xA6, 0xFC, 0x85, 0x01, 0x6F, 0xFF, 0x24, 0x00, 0xFD, 0xFF, 0x16,
- 0x00, 0xA6, 0xFF, 0xBB, 0x00, 0xE9, 0xFE, 0x38, 0x01, 0x4B, 0xFF,
- 0x28, 0xFE, 0x3A, 0x48, 0x04, 0x0A, 0x2E, 0xFA, 0xDF, 0x03, 0x8A,
- 0xFD, 0x60, 0x01, 0x65, 0xFF, 0x27, 0x00, 0x00, 0x00, 0xFD, 0xFF,
- 0x35, 0x00, 0x3A, 0xFF, 0xE3, 0x01, 0x31, 0xFC, 0x0F, 0x07, 0x84,
- 0xF2, 0x29, 0x25, 0x1A, 0x3A, 0x67, 0xF2, 0xF6, 0x05, 0x41, 0xFD,
- 0x24, 0x01, 0xA1, 0xFF, 0x12, 0x00, 0x00, 0x00, 0x0E, 0x00, 0xC8,
- 0xFF, 0x64, 0x00, 0x9B, 0xFF, 0xEE, 0xFF, 0x98, 0x01, 0x93, 0xF9,
- 0x10, 0x46, 0x03, 0x11, 0xA7, 0xF7, 0x12, 0x05, 0xF6, 0xFC, 0xA2,
- 0x01, 0x4C, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00,
- 0x36, 0xFF, 0xE1, 0x01, 0x52, 0xFC, 0x93, 0x06, 0x10, 0xF4, 0x78,
- 0x1D, 0x90, 0x3F, 0x3E, 0xF4, 0xAA, 0x04, 0x19, 0xFE, 0xA4, 0x00,
- 0xE2, 0xFF, 0xFA, 0xFF, 0x03, 0x00, 0x07, 0x00, 0xE8, 0xFF, 0x12,
- 0x00, 0x42, 0x00, 0xC4, 0xFE, 0x94, 0x03, 0x02, 0xF6, 0x89, 0x42,
- 0x76, 0x18, 0x5C, 0xF5, 0x12, 0x06, 0x84, 0xFC, 0xD1, 0x01, 0x3B,
- 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x33, 0x00, 0x40, 0xFF,
- 0xC3, 0x01, 0xA7, 0xFC, 0xC0, 0x05, 0x1E, 0xF6, 0xD8, 0x15, 0xE7,
- 0x43, 0x20, 0xF7, 0xEF, 0x02, 0x27, 0xFF, 0x0A, 0x00, 0x2E, 0x00,
- 0xDD, 0xFF, 0x09, 0x00, 0x02, 0x00, 0x03, 0x00, 0xCA, 0xFF, 0xD4,
- 0x00, 0xC8, 0xFD, 0x2A, 0x05, 0x7D, 0xF3, 0xCA, 0x3D, 0x22, 0x20,
- 0x76, 0xF3, 0xC8, 0x06, 0x41, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36,
- 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x2C, 0x00, 0x54, 0xFF, 0x8D, 0x01,
- 0x26, 0xFD, 0xAD, 0x04, 0x82, 0xF8, 0x87, 0x0E, 0xF9, 0x46, 0x0C,
- 0xFB, 0xD4, 0x00, 0x5D, 0x00, 0x5E, 0xFF, 0x82, 0x00, 0xBD, 0xFF,
- 0x10, 0x00, 0xFF, 0xFF, 0x19, 0x00, 0x8E, 0xFF, 0x49, 0x01, 0x04,
- 0xFD, 0x4D, 0x06, 0x00, 0xF2, 0xFE, 0x37, 0xCB, 0x27, 0x21, 0xF2,
- 0x23, 0x07, 0x34, 0xFC, 0xDD, 0x01, 0x3F, 0xFF, 0x34, 0x00, 0xFD,
- 0xFF, 0x00, 0x00, 0x24, 0x00, 0x70, 0xFF, 0x46, 0x01, 0xC3, 0xFD,
- 0x6D, 0x03, 0x14, 0xFB, 0xBE, 0x07, 0xA6, 0x48, 0xF8, 0xFF, 0x70,
- 0xFE, 0xAE, 0x01, 0xAA, 0xFE, 0xD9, 0x00, 0x9A, 0xFF, 0x19, 0x00,
- 0xFD, 0xFF, 0x29, 0x00, 0x61, 0xFF, 0x9F, 0x01, 0x80, 0xFC, 0xF7,
- 0x06, 0x7D, 0xF1, 0x5A, 0x31, 0x2C, 0x2F, 0x83, 0xF1, 0x13, 0x07,
- 0x64, 0xFC, 0xB3, 0x01, 0x57, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0x1B,
- 0x00, 0x90, 0xFF, 0xF4, 0x00, 0x72, 0xFE, 0x18, 0x02, 0xAA, 0xFD,
- 0xAB, 0x01, 0xDF, 0x48, 0xCA, 0x05, 0xE1, 0xFB, 0x05, 0x03, 0xF7,
- 0xFD, 0x2E, 0x01, 0x79, 0xFF, 0x21, 0x00, 0x00, 0x00, 0xFD, 0xFF,
- 0x32, 0x00, 0x44, 0xFF, 0xD3, 0x01, 0x3C, 0xFC, 0x2A, 0x07, 0xDC,
- 0xF1, 0x1A, 0x2A, 0x06, 0x36, 0xBE, 0xF1, 0x8E, 0x06, 0xD5, 0xFC,
- 0x67, 0x01, 0x7F, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0x13, 0x00, 0xB2,
- 0xFF, 0x9D, 0x00, 0x27, 0xFF, 0xC3, 0x00, 0x1F, 0x00, 0x76, 0xFC,
- 0xA3, 0x47, 0x60, 0x0C, 0x4A, 0xF9, 0x4E, 0x04, 0x53, 0xFD, 0x79,
- 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00,
- 0x37, 0xFF, 0xE6, 0x01, 0x36, 0xFC, 0xEF, 0x06, 0xFC, 0xF2, 0x81,
- 0x22, 0x1C, 0x3C, 0xEC, 0xF2, 0x90, 0x05, 0x85, 0xFD, 0xFB, 0x00,
- 0xB6, 0xFF, 0x0A, 0x00, 0x01, 0x00, 0x0B, 0x00, 0xD3, 0xFF, 0x47,
- 0x00, 0xD7, 0xFF, 0x82, 0xFF, 0x53, 0x02, 0x39, 0xF8, 0xFD, 0x44,
- 0x8D, 0x13, 0xD3, 0xF6, 0x72, 0x05, 0xCA, 0xFC, 0xB5, 0x01, 0x45,
- 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x35, 0x00, 0x38, 0xFF,
- 0xDA, 0x01, 0x6A, 0xFC, 0x53, 0x06, 0xBA, 0xF4, 0xCE, 0x1A, 0x32,
- 0x41, 0x1F, 0xF5, 0x1D, 0x04, 0x71, 0xFE, 0x71, 0x00, 0xFB, 0xFF,
- 0xF0, 0xFF, 0x05, 0x00, 0x05, 0x00, 0xF2, 0xFF, 0xF8, 0xFF, 0x77,
- 0x00, 0x67, 0xFE, 0x2D, 0x04, 0x04, 0xF5, 0x07, 0x41, 0x1B, 0x1B,
- 0xA6, 0xF4, 0x5A, 0x06, 0x67, 0xFC, 0xDB, 0x01, 0x38, 0xFF, 0x36,
- 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x31, 0x00, 0x46, 0xFF, 0xB3, 0x01,
- 0xCF, 0xFC, 0x67, 0x05, 0xEA, 0xF6, 0x44, 0x13, 0x1E, 0x45, 0x5E,
- 0xF8, 0x3F, 0x02, 0x8E, 0xFF, 0xD0, 0xFF, 0x4A, 0x00, 0xD2, 0xFF,
- 0x0B, 0x00, 0x01, 0x00, 0x0B, 0x00, 0xB4, 0xFF, 0x00, 0x01, 0x7E,
- 0xFD, 0x9C, 0x05, 0xDC, 0xF2, 0xE4, 0x3B, 0xCD, 0x22, 0xEE, 0xF2,
- 0xF3, 0x06, 0x35, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD,
- 0xFF, 0x00, 0x00, 0x2A, 0x00, 0x5D, 0xFF, 0x76, 0x01, 0x59, 0xFD,
- 0x42, 0x04, 0x63, 0xF9, 0x1C, 0x0C, 0xB6, 0x47, 0xA4, 0xFC, 0x07,
- 0x00, 0xD0, 0x00, 0x20, 0xFF, 0xA0, 0x00, 0xB1, 0xFF, 0x13, 0x00,
- 0xFE, 0xFF, 0x1F, 0x00, 0x7D, 0xFF, 0x6B, 0x01, 0xCF, 0xFC, 0x96,
- 0x06, 0xB7, 0xF1, 0xC6, 0x35, 0x64, 0x2A, 0xD4, 0xF1, 0x2B, 0x07,
- 0x3D, 0xFC, 0xD2, 0x01, 0x45, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x00,
- 0x00, 0x21, 0x00, 0x7A, 0xFF, 0x2B, 0x01, 0xFE, 0xFD, 0xF8, 0x02,
- 0xFB, 0xFB, 0x8D, 0x05, 0xE5, 0x48, 0xE3, 0x01, 0x91, 0xFD, 0x25,
- 0x02, 0x6B, 0xFE, 0xF7, 0x00, 0x8F, 0xFF, 0x1C, 0x00, 0xFD, 0xFF,
- 0x2D, 0x00, 0x55, 0xFF, 0xB5, 0x01, 0x61, 0xFC, 0x16, 0x07, 0x85,
- 0xF1, 0xE6, 0x2E, 0x9E, 0x31, 0x7D, 0xF1, 0xF3, 0x06, 0x84, 0xFC,
- 0x9D, 0x01, 0x63, 0xFF, 0x28, 0x00, 0xFD, 0xFF, 0x18, 0x00, 0x9C,
- 0xFF, 0xD6, 0x00, 0xB1, 0xFE, 0xA1, 0x01, 0x89, 0xFE, 0xC3, 0xFF,
- 0x9C, 0x48, 0xFD, 0x07, 0xFA, 0xFA, 0x7A, 0x03, 0xBC, 0xFD, 0x49,
- 0x01, 0x6E, 0xFF, 0x24, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x34, 0x00,
- 0x3E, 0xFF, 0xDE, 0x01, 0x33, 0xFC, 0x22, 0x07, 0x2B, 0xF2, 0x80,
- 0x27, 0x3B, 0x38, 0x0A, 0xF2, 0x44, 0x06, 0x0B, 0xFD, 0x45, 0x01,
- 0x90, 0xFF, 0x18, 0x00, 0xFF, 0xFF, 0x10, 0x00, 0xBE, 0xFF, 0x7F,
- 0x00, 0x65, 0xFF, 0x51, 0x00, 0xEB, 0x00, 0xE1, 0xFA, 0xE1, 0x46,
- 0xCD, 0x0E, 0x6A, 0xF8, 0xB8, 0x04, 0x20, 0xFD, 0x90, 0x01, 0x53,
- 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF,
- 0xE5, 0x01, 0x42, 0xFC, 0xC3, 0x06, 0x87, 0xF3, 0xD7, 0x1F, 0xFE,
- 0x3D, 0x91, 0xF3, 0x1D, 0x05, 0xD1, 0xFD, 0xCE, 0x00, 0xCC, 0xFF,
- 0x02, 0x00, 0x02, 0x00, 0x09, 0x00, 0xDE, 0xFF, 0x2B, 0x00, 0x11,
- 0x00, 0x1B, 0xFF, 0x02, 0x03, 0xFE, 0xF6, 0xC3, 0x43, 0x22, 0x16,
- 0x07, 0xF6, 0xCA, 0x05, 0xA3, 0xFC, 0xC5, 0x01, 0x3F, 0xFF, 0x33,
- 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x34, 0x00, 0x3C, 0xFF, 0xCF, 0x01,
- 0x88, 0xFC, 0x09, 0x06, 0x71, 0xF5, 0x2B, 0x18, 0xB2, 0x42, 0x20,
- 0xF6, 0x83, 0x03, 0xCF, 0xFE, 0x3C, 0x00, 0x15, 0x00, 0xE6, 0xFF,
- 0x07, 0x00, 0x03, 0x00, 0xFB, 0xFF, 0xDF, 0xFF, 0xA9, 0x00, 0x10,
- 0xFE, 0xB9, 0x04, 0x27, 0xF4, 0x5E, 0x3F, 0xC3, 0x1D, 0xFE, 0xF3,
- 0x99, 0x06, 0x50, 0xFC, 0xE2, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE,
- 0xFF, 0xFF, 0xFF, 0x2F, 0x00, 0x4D, 0xFF, 0xA0, 0x01, 0xFB, 0xFC,
- 0x07, 0x05, 0xBF, 0xF7, 0xBB, 0x10, 0x2B, 0x46, 0xBB, 0xF9, 0x83,
- 0x01, 0xFA, 0xFF, 0x95, 0xFF, 0x68, 0x00, 0xC7, 0xFF, 0x0E, 0x00,
- 0x00, 0x00, 0x13, 0x00, 0x9F, 0xFF, 0x28, 0x01, 0x3A, 0xFD, 0x00,
- 0x06, 0x5A, 0xF2, 0xDF, 0x39, 0x73, 0x25, 0x79, 0xF2, 0x12, 0x07,
- 0x31, 0xFC, 0xE3, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x00,
- 0x00, 0x27, 0x00, 0x66, 0xFF, 0x5E, 0x01, 0x90, 0xFD, 0xD2, 0x03,
- 0x47, 0xFA, 0xC3, 0x09, 0x48, 0x48, 0x5A, 0xFE, 0x33, 0xFF, 0x45,
- 0x01, 0xE2, 0xFE, 0xBE, 0x00, 0xA5, 0xFF, 0x16, 0x00, 0xFD, 0xFF,
- 0x24, 0x00, 0x6D, 0xFF, 0x88, 0x01, 0xA2, 0xFC, 0xD0, 0x06, 0x8C,
- 0xF1, 0x78, 0x33, 0xF2, 0x2C, 0x9E, 0xF1, 0x24, 0x07, 0x4E, 0xFC,
- 0xC3, 0x01, 0x4E, 0xFF, 0x2F, 0x00, 0xFD, 0xFF, 0x1E, 0x00, 0x86,
- 0xFF, 0x0E, 0x01, 0x3B, 0xFE, 0x82, 0x02, 0xE0, 0xFC, 0x73, 0x03,
- 0xF6, 0x48, 0xE9, 0x03, 0xAD, 0xFC, 0x9C, 0x02, 0x2D, 0xFE, 0x14,
- 0x01, 0x83, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x30, 0x00,
- 0x4C, 0xFF, 0xC7, 0x01, 0x4A, 0xFC, 0x27, 0x07, 0xA8, 0xF1, 0x62,
- 0x2C, 0xFD, 0x33, 0x93, 0xF1, 0xC4, 0x06, 0xAB, 0xFC, 0x82, 0x01,
- 0x71, 0xFF, 0x23, 0x00, 0xFE, 0xFF, 0x15, 0x00, 0xA8, 0xFF, 0xB8,
- 0x00, 0xF0, 0xFE, 0x2B, 0x01, 0x63, 0xFF, 0xF6, 0xFD, 0x2C, 0x48,
- 0x47, 0x0A, 0x14, 0xFA, 0xEB, 0x03, 0x84, 0xFD, 0x63, 0x01, 0x64,
- 0xFF, 0x27, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x3A, 0xFF,
- 0xE4, 0x01, 0x32, 0xFC, 0x0C, 0x07, 0x91, 0xF2, 0xDD, 0x24, 0x54,
- 0x3A, 0x74, 0xF2, 0xEB, 0x05, 0x49, 0xFD, 0x20, 0x01, 0xA3, 0xFF,
- 0x11, 0x00, 0x00, 0x00, 0x0D, 0x00, 0xC9, 0xFF, 0x61, 0x00, 0xA2,
- 0xFF, 0xE2, 0xFF, 0xAE, 0x01, 0x6B, 0xF9, 0xF2, 0x45, 0x4A, 0x11,
- 0x8F, 0xF7, 0x1D, 0x05, 0xF1, 0xFC, 0xA4, 0x01, 0x4B, 0xFF, 0x2F,
- 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE1, 0x01,
- 0x55, 0xFC, 0x8C, 0x06, 0x22, 0xF4, 0x2C, 0x1D, 0xC0, 0x3F, 0x55,
- 0xF4, 0x9B, 0x04, 0x23, 0xFE, 0x9F, 0x00, 0xE4, 0xFF, 0xF9, 0xFF,
- 0x04, 0x00, 0x07, 0x00, 0xE9, 0xFF, 0x0F, 0x00, 0x48, 0x00, 0xB9,
- 0xFE, 0xA6, 0x03, 0xE4, 0xF5, 0x60, 0x42, 0xC1, 0x18, 0x47, 0xF5,
- 0x1A, 0x06, 0x81, 0xFC, 0xD2, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFE,
- 0xFF, 0xFF, 0xFF, 0x33, 0x00, 0x40, 0xFF, 0xC1, 0x01, 0xAB, 0xFC,
- 0xB7, 0x05, 0x34, 0xF6, 0x8E, 0x15, 0x0B, 0x44, 0x42, 0xF7, 0xDC,
- 0x02, 0x32, 0xFF, 0x04, 0x00, 0x31, 0x00, 0xDC, 0xFF, 0x09, 0x00,
- 0x02, 0x00, 0x04, 0x00, 0xC7, 0xFF, 0xD9, 0x00, 0xBF, 0xFD, 0x38,
- 0x05, 0x69, 0xF3, 0x96, 0x3D, 0x6F, 0x20, 0x66, 0xF3, 0xCE, 0x06,
- 0x3F, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF,
- 0xFF, 0x2C, 0x00, 0x55, 0xFF, 0x8B, 0x01, 0x2B, 0xFD, 0xA1, 0x04,
- 0x9B, 0xF8, 0x42, 0x0E, 0x0F, 0x47, 0x38, 0xFB, 0xBE, 0x00, 0x6A,
- 0x00, 0x58, 0xFF, 0x85, 0x00, 0xBB, 0xFF, 0x10, 0x00, 0xFF, 0xFF,
- 0x19, 0x00, 0x8C, 0xFF, 0x4D, 0x01, 0xFE, 0xFC, 0x56, 0x06, 0xF7,
- 0xF1, 0xBF, 0x37, 0x15, 0x28, 0x18, 0xF2, 0x25, 0x07, 0x34, 0xFC,
- 0xDC, 0x01, 0x3F, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x24,
- 0x00, 0x71, 0xFF, 0x43, 0x01, 0xC9, 0xFD, 0x60, 0x03, 0x2E, 0xFB,
- 0x7E, 0x07, 0xAF, 0x48, 0x2D, 0x00, 0x58, 0xFE, 0xBB, 0x01, 0xA3,
- 0xFE, 0xDD, 0x00, 0x99, 0xFF, 0x19, 0x00, 0xFD, 0xFF, 0x29, 0x00,
- 0x60, 0xFF, 0xA2, 0x01, 0x7C, 0xFC, 0xFB, 0x06, 0x7C, 0xF1, 0x15,
- 0x31, 0x73, 0x2F, 0x81, 0xF1, 0x10, 0x07, 0x67, 0xFC, 0xB1, 0x01,
- 0x58, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0x1B, 0x00, 0x91, 0xFF, 0xF1,
- 0x00, 0x79, 0xFE, 0x0A, 0x02, 0xC3, 0xFD, 0x73, 0x01, 0xDB, 0x48,
- 0x07, 0x06, 0xC7, 0xFB, 0x12, 0x03, 0xF1, 0xFD, 0x31, 0x01, 0x78,
- 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x44, 0xFF,
- 0xD5, 0x01, 0x3A, 0xFC, 0x2A, 0x07, 0xE3, 0xF1, 0xD1, 0x29, 0x46,
- 0x36, 0xC5, 0xF1, 0x87, 0x06, 0xDA, 0xFC, 0x64, 0x01, 0x80, 0xFF,
- 0x1E, 0x00, 0xFE, 0xFF, 0x12, 0x00, 0xB3, 0xFF, 0x99, 0x00, 0x2E,
- 0xFF, 0xB6, 0x00, 0x36, 0x00, 0x47, 0xFC, 0x90, 0x47, 0xA4, 0x0C,
- 0x31, 0xF9, 0x5A, 0x04, 0x4E, 0xFD, 0x7C, 0x01, 0x5B, 0xFF, 0x2A,
- 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01,
- 0x37, 0xFC, 0xEB, 0x06, 0x0B, 0xF3, 0x35, 0x22, 0x52, 0x3C, 0xFD,
- 0xF2, 0x84, 0x05, 0x8D, 0xFD, 0xF6, 0x00, 0xB8, 0xFF, 0x09, 0x00,
- 0x01, 0x00, 0x0B, 0x00, 0xD5, 0xFF, 0x44, 0x00, 0xDD, 0xFF, 0x77,
- 0xFF, 0x67, 0x02, 0x14, 0xF8, 0xDC, 0x44, 0xD5, 0x13, 0xBC, 0xF6,
- 0x7C, 0x05, 0xC5, 0xFC, 0xB7, 0x01, 0x44, 0xFF, 0x31, 0x00, 0xFF,
- 0xFF, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD9, 0x01, 0x6D, 0xFC,
- 0x4B, 0x06, 0xCD, 0xF4, 0x83, 0x1A, 0x5F, 0x41, 0x3A, 0xF5, 0x0C,
- 0x04, 0x7B, 0xFE, 0x6C, 0x00, 0xFE, 0xFF, 0xEF, 0xFF, 0x05, 0x00,
- 0x05, 0x00, 0xF3, 0xFF, 0xF5, 0xFF, 0x7D, 0x00, 0x5D, 0xFE, 0x3E,
- 0x04, 0xEA, 0xF4, 0xD9, 0x40, 0x66, 0x1B, 0x93, 0xF4, 0x62, 0x06,
- 0x64, 0xFC, 0xDC, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF,
- 0xFF, 0x31, 0x00, 0x46, 0xFF, 0xB1, 0x01, 0xD3, 0xFC, 0x5D, 0x05,
- 0x01, 0xF7, 0xFB, 0x12, 0x3F, 0x45, 0x83, 0xF8, 0x2A, 0x02, 0x9A,
- 0xFF, 0xCA, 0xFF, 0x4E, 0x00, 0xD1, 0xFF, 0x0C, 0x00, 0x00, 0x00,
- 0x0C, 0x00, 0xB1, 0xFF, 0x04, 0x01, 0x76, 0xFD, 0xA8, 0x05, 0xCC,
- 0xF2, 0xAB, 0x3B, 0x18, 0x23, 0xE0, 0xF2, 0xF7, 0x06, 0x35, 0xFC,
- 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x29,
- 0x00, 0x5E, 0xFF, 0x74, 0x01, 0x5F, 0xFD, 0x35, 0x04, 0x7C, 0xF9,
- 0xD8, 0x0B, 0xC9, 0x47, 0xD4, 0xFC, 0xF0, 0xFF, 0xDD, 0x00, 0x19,
- 0xFF, 0xA4, 0x00, 0xAF, 0xFF, 0x13, 0x00, 0xFE, 0xFF, 0x20, 0x00,
- 0x7B, 0xFF, 0x6E, 0x01, 0xCA, 0xFC, 0x9D, 0x06, 0xB1, 0xF1, 0x86,
- 0x35, 0xAE, 0x2A, 0xCD, 0xF1, 0x2B, 0x07, 0x3F, 0xFC, 0xD1, 0x01,
- 0x46, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x21, 0x00, 0x7C,
- 0xFF, 0x27, 0x01, 0x05, 0xFE, 0xEB, 0x02, 0x14, 0xFC, 0x50, 0x05,
- 0xEA, 0x48, 0x1B, 0x02, 0x78, 0xFD, 0x32, 0x02, 0x64, 0xFE, 0xFA,
- 0x00, 0x8D, 0xFF, 0x1C, 0x00, 0xFD, 0xFF, 0x2D, 0x00, 0x54, 0xFF,
- 0xB7, 0x01, 0x5E, 0xFC, 0x19, 0x07, 0x88, 0xF1, 0x9F, 0x2E, 0xE3,
- 0x31, 0x7E, 0xF1, 0xEE, 0x06, 0x88, 0xFC, 0x9A, 0x01, 0x64, 0xFF,
- 0x28, 0x00, 0xFD, 0xFF, 0x18, 0x00, 0x9D, 0xFF, 0xD3, 0x00, 0xB8,
- 0xFE, 0x93, 0x01, 0xA1, 0xFE, 0x8E, 0xFF, 0x92, 0x48, 0x3D, 0x08,
- 0xE1, 0xFA, 0x86, 0x03, 0xB6, 0xFD, 0x4C, 0x01, 0x6D, 0xFF, 0x25,
- 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x3E, 0xFF, 0xDF, 0x01,
- 0x33, 0xFC, 0x20, 0x07, 0x35, 0xF2, 0x36, 0x27, 0x78, 0x38, 0x14,
- 0xF2, 0x3B, 0x06, 0x11, 0xFD, 0x41, 0x01, 0x92, 0xFF, 0x17, 0x00,
- 0xFF, 0xFF, 0x10, 0x00, 0xBF, 0xFF, 0x7B, 0x00, 0x6C, 0xFF, 0x44,
- 0x00, 0x01, 0x01, 0xB6, 0xFA, 0xC8, 0x46, 0x13, 0x0F, 0x51, 0xF8,
- 0xC4, 0x04, 0x1B, 0xFD, 0x92, 0x01, 0x52, 0xFF, 0x2D, 0x00, 0xFF,
- 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE5, 0x01, 0x44, 0xFC,
- 0xBD, 0x06, 0x97, 0xF3, 0x8A, 0x1F, 0x31, 0x3E, 0xA5, 0xF3, 0x0F,
- 0x05, 0xDA, 0xFD, 0xC9, 0x00, 0xCF, 0xFF, 0x01, 0x00, 0x02, 0x00,
- 0x09, 0x00, 0xDF, 0xFF, 0x28, 0x00, 0x17, 0x00, 0x10, 0xFF, 0x15,
- 0x03, 0xDD, 0xF6, 0x9E, 0x43, 0x6C, 0x16, 0xF1, 0xF5, 0xD3, 0x05,
- 0x9F, 0xFC, 0xC6, 0x01, 0x3F, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0xFE,
- 0xFF, 0x34, 0x00, 0x3C, 0xFF, 0xCE, 0x01, 0x8C, 0xFC, 0x00, 0x06,
- 0x86, 0xF5, 0xE0, 0x17, 0xDB, 0x42, 0x3F, 0xF6, 0x71, 0x03, 0xD9,
- 0xFE, 0x36, 0x00, 0x18, 0x00, 0xE5, 0xFF, 0x07, 0x00, 0x03, 0x00,
- 0xFC, 0xFF, 0xDC, 0xFF, 0xAF, 0x00, 0x07, 0xFE, 0xC8, 0x04, 0x10,
- 0xF4, 0x2D, 0x3F, 0x0F, 0x1E, 0xED, 0xF3, 0xA0, 0x06, 0x4E, 0xFC,
- 0xE3, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x2E,
- 0x00, 0x4E, 0xFF, 0x9E, 0x01, 0x00, 0xFD, 0xFC, 0x04, 0xD7, 0xF7,
- 0x75, 0x10, 0x48, 0x46, 0xE4, 0xF9, 0x6E, 0x01, 0x06, 0x00, 0x8E,
- 0xFF, 0x6B, 0x00, 0xC6, 0xFF, 0x0E, 0x00, 0xFF, 0xFF, 0x13, 0x00,
- 0x9D, 0xFF, 0x2D, 0x01, 0x33, 0xFD, 0x0B, 0x06, 0x4D, 0xF2, 0xA5,
- 0x39, 0xBF, 0x25, 0x6D, 0xF2, 0x15, 0x07, 0x31, 0xFC, 0xE2, 0x01,
- 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x26, 0x00, 0x68,
- 0xFF, 0x5B, 0x01, 0x96, 0xFD, 0xC6, 0x03, 0x61, 0xFA, 0x81, 0x09,
- 0x57, 0x48, 0x8D, 0xFE, 0x1B, 0xFF, 0x52, 0x01, 0xDB, 0xFE, 0xC2,
- 0x00, 0xA4, 0xFF, 0x16, 0x00, 0xFD, 0xFF, 0x25, 0x00, 0x6C, 0xFF,
- 0x8B, 0x01, 0x9D, 0xFC, 0xD5, 0x06, 0x89, 0xF1, 0x35, 0x33, 0x3A,
- 0x2D, 0x9A, 0xF1, 0x23, 0x07, 0x51, 0xFC, 0xC2, 0x01, 0x4F, 0xFF,
- 0x2F, 0x00, 0xFD, 0xFF, 0x1E, 0x00, 0x87, 0xFF, 0x0B, 0x01, 0x42,
- 0xFE, 0x74, 0x02, 0xF9, 0xFC, 0x39, 0x03, 0xF5, 0x48, 0x24, 0x04,
- 0x94, 0xFC, 0xA9, 0x02, 0x27, 0xFE, 0x18, 0x01, 0x82, 0xFF, 0x1F,
- 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x30, 0x00, 0x4B, 0xFF, 0xC9, 0x01,
- 0x48, 0xFC, 0x28, 0x07, 0xAD, 0xF1, 0x19, 0x2C, 0x3F, 0x34, 0x97,
- 0xF1, 0xBE, 0x06, 0xB0, 0xFC, 0x7F, 0x01, 0x72, 0xFF, 0x23, 0x00,
- 0xFE, 0xFF, 0x15, 0x00, 0xA9, 0xFF, 0xB4, 0x00, 0xF7, 0xFE, 0x1D,
- 0x01, 0x7A, 0xFF, 0xC5, 0xFD, 0x1D, 0x48, 0x89, 0x0A, 0xFB, 0xF9,
- 0xF8, 0x03, 0x7D, 0xFD, 0x66, 0x01, 0x63, 0xFF, 0x28, 0x00, 0x00,
- 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE4, 0x01, 0x32, 0xFC,
- 0x09, 0x07, 0x9D, 0xF2, 0x92, 0x24, 0x8F, 0x3A, 0x82, 0xF2, 0xE1,
- 0x05, 0x50, 0xFD, 0x1B, 0x01, 0xA6, 0xFF, 0x10, 0x00, 0x00, 0x00,
- 0x0D, 0x00, 0xCB, 0xFF, 0x5E, 0x00, 0xA9, 0xFF, 0xD6, 0xFF, 0xC3,
- 0x01, 0x43, 0xF9, 0xD7, 0x45, 0x92, 0x11, 0x77, 0xF7, 0x28, 0x05,
- 0xEC, 0xFC, 0xA7, 0x01, 0x4A, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0xFE,
- 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE0, 0x01, 0x57, 0xFC, 0x85, 0x06,
- 0x34, 0xF4, 0xE0, 0x1C, 0xF0, 0x3F, 0x6D, 0xF4, 0x8C, 0x04, 0x2C,
- 0xFE, 0x99, 0x00, 0xE7, 0xFF, 0xF8, 0xFF, 0x04, 0x00, 0x06, 0x00,
- 0xEA, 0xFF, 0x0C, 0x00, 0x4E, 0x00, 0xAF, 0xFE, 0xB8, 0x03, 0xC7,
- 0xF5, 0x38, 0x42, 0x0C, 0x19, 0x32, 0xF5, 0x23, 0x06, 0x7D, 0xFC,
- 0xD3, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x32,
- 0x00, 0x41, 0xFF, 0xC0, 0x01, 0xAF, 0xFC, 0xAD, 0x05, 0x4A, 0xF6,
- 0x44, 0x15, 0x2F, 0x44, 0x64, 0xF7, 0xC9, 0x02, 0x3D, 0xFF, 0xFE,
- 0xFF, 0x34, 0x00, 0xDB, 0xFF, 0x09, 0x00, 0x02, 0x00, 0x05, 0x00,
- 0xC5, 0xFF, 0xDE, 0x00, 0xB7, 0xFD, 0x45, 0x05, 0x56, 0xF3, 0x61,
- 0x3D, 0xBA, 0x20, 0x56, 0xF3, 0xD3, 0x06, 0x3E, 0xFC, 0xE6, 0x01,
- 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x2C, 0x00, 0x56,
- 0xFF, 0x88, 0x01, 0x31, 0xFD, 0x95, 0x04, 0xB4, 0xF8, 0xFC, 0x0D,
- 0x26, 0x47, 0x64, 0xFB, 0xA7, 0x00, 0x77, 0x00, 0x51, 0xFF, 0x89,
- 0x00, 0xBA, 0xFF, 0x11, 0x00, 0xFF, 0xFF, 0x1A, 0x00, 0x8A, 0xFF,
- 0x51, 0x01, 0xF8, 0xFC, 0x5E, 0x06, 0xED, 0xF1, 0x82, 0x37, 0x60,
- 0x28, 0x0E, 0xF2, 0x26, 0x07, 0x35, 0xFC, 0xDB, 0x01, 0x40, 0xFF,
- 0x34, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x23, 0x00, 0x72, 0xFF, 0x40,
- 0x01, 0xD0, 0xFD, 0x53, 0x03, 0x47, 0xFB, 0x3F, 0x07, 0xB8, 0x48,
- 0x62, 0x00, 0x3F, 0xFE, 0xC8, 0x01, 0x9C, 0xFE, 0xE0, 0x00, 0x98,
- 0xFF, 0x19, 0x00, 0xFD, 0xFF, 0x29, 0x00, 0x5F, 0xFF, 0xA5, 0x01,
- 0x78, 0xFC, 0xFF, 0x06, 0x7D, 0xF1, 0xCF, 0x30, 0xB8, 0x2F, 0x80,
- 0xF1, 0x0D, 0x07, 0x6A, 0xFC, 0xAE, 0x01, 0x59, 0xFF, 0x2B, 0x00,
- 0xFD, 0xFF, 0x1B, 0x00, 0x93, 0xFF, 0xED, 0x00, 0x80, 0xFE, 0xFD,
- 0x01, 0xDC, 0xFD, 0x3C, 0x01, 0xD5, 0x48, 0x45, 0x06, 0xAE, 0xFB,
- 0x1F, 0x03, 0xEA, 0xFD, 0x34, 0x01, 0x77, 0xFF, 0x22, 0x00, 0x00,
- 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x43, 0xFF, 0xD6, 0x01, 0x39, 0xFC,
- 0x2A, 0x07, 0xEB, 0xF1, 0x87, 0x29, 0x85, 0x36, 0xCC, 0xF1, 0x7F,
- 0x06, 0xE0, 0xFC, 0x60, 0x01, 0x82, 0xFF, 0x1D, 0x00, 0xFE, 0xFF,
- 0x12, 0x00, 0xB5, 0xFF, 0x96, 0x00, 0x35, 0xFF, 0xA9, 0x00, 0x4D,
- 0x00, 0x19, 0xFC, 0x7C, 0x47, 0xE8, 0x0C, 0x18, 0xF9, 0x66, 0x04,
- 0x48, 0xFD, 0x7E, 0x01, 0x5A, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0xFD,
- 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x38, 0xFC, 0xE6, 0x06,
- 0x19, 0xF3, 0xEA, 0x21, 0x8A, 0x3C, 0x0E, 0xF3, 0x78, 0x05, 0x96,
- 0xFD, 0xF1, 0x00, 0xBB, 0xFF, 0x08, 0x00, 0x01, 0x00, 0x0B, 0x00,
- 0xD6, 0xFF, 0x41, 0x00, 0xE4, 0xFF, 0x6B, 0xFF, 0x7B, 0x02, 0xF0,
- 0xF7, 0xBA, 0x44, 0x1E, 0x14, 0xA5, 0xF6, 0x86, 0x05, 0xC1, 0xFC,
- 0xB9, 0x01, 0x44, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x35,
- 0x00, 0x39, 0xFF, 0xD8, 0x01, 0x70, 0xFC, 0x43, 0x06, 0xE1, 0xF4,
- 0x38, 0x1A, 0x8C, 0x41, 0x55, 0xF5, 0xFC, 0x03, 0x85, 0xFE, 0x66,
- 0x00, 0x01, 0x00, 0xEE, 0xFF, 0x06, 0x00, 0x05, 0x00, 0xF4, 0xFF,
- 0xF2, 0xFF, 0x83, 0x00, 0x53, 0xFE, 0x4E, 0x04, 0xD0, 0xF4, 0xAB,
- 0x40, 0xB2, 0x1B, 0x7F, 0xF4, 0x69, 0x06, 0x62, 0xFC, 0xDD, 0x01,
- 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x30, 0x00, 0x47,
- 0xFF, 0xAF, 0x01, 0xD8, 0xFC, 0x52, 0x05, 0x19, 0xF7, 0xB2, 0x12,
- 0x5C, 0x45, 0xA9, 0xF8, 0x16, 0x02, 0xA6, 0xFF, 0xC3, 0xFF, 0x51,
- 0x00, 0xD0, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0xAF, 0xFF,
- 0x09, 0x01, 0x6E, 0xFD, 0xB4, 0x05, 0xBC, 0xF2, 0x73, 0x3B, 0x64,
- 0x23, 0xD2, 0xF2, 0xFB, 0x06, 0x34, 0xFC, 0xE6, 0x01, 0x38, 0xFF,
- 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x29, 0x00, 0x5F, 0xFF, 0x71,
- 0x01, 0x65, 0xFD, 0x29, 0x04, 0x96, 0xF9, 0x95, 0x0B, 0xDC, 0x47,
- 0x03, 0xFD, 0xD9, 0xFF, 0xEA, 0x00, 0x12, 0xFF, 0xA7, 0x00, 0xAE,
- 0xFF, 0x14, 0x00, 0xFE, 0xFF, 0x20, 0x00, 0x79, 0xFF, 0x72, 0x01,
- 0xC4, 0xFC, 0xA4, 0x06, 0xAB, 0xF1, 0x46, 0x35, 0xF7, 0x2A, 0xC6,
- 0xF1, 0x2A, 0x07, 0x40, 0xFC, 0xCF, 0x01, 0x47, 0xFF, 0x31, 0x00,
- 0xFD, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x7D, 0xFF, 0x24, 0x01, 0x0C,
- 0xFE, 0xDE, 0x02, 0x2E, 0xFC, 0x13, 0x05, 0xEC, 0x48, 0x54, 0x02,
- 0x5E, 0xFD, 0x3F, 0x02, 0x5D, 0xFE, 0xFE, 0x00, 0x8C, 0xFF, 0x1C,
- 0x00, 0xFD, 0xFF, 0x2D, 0x00, 0x53, 0xFF, 0xBA, 0x01, 0x5B, 0xFC,
- 0x1B, 0x07, 0x8B, 0xF1, 0x58, 0x2E, 0x26, 0x32, 0x80, 0xF1, 0xEA,
- 0x06, 0x8C, 0xFC, 0x97, 0x01, 0x66, 0xFF, 0x27, 0x00, 0xFD, 0xFF,
- 0x17, 0x00, 0x9E, 0xFF, 0xCF, 0x00, 0xBF, 0xFE, 0x86, 0x01, 0xBA,
- 0xFE, 0x5A, 0xFF, 0x86, 0x48, 0x7D, 0x08, 0xC7, 0xFA, 0x93, 0x03,
- 0xB0, 0xFD, 0x4F, 0x01, 0x6C, 0xFF, 0x25, 0x00, 0x00, 0x00, 0xFD,
- 0xFF, 0x35, 0x00, 0x3D, 0xFF, 0xDF, 0x01, 0x32, 0xFC, 0x1E, 0x07,
- 0x40, 0xF2, 0xEB, 0x26, 0xB5, 0x38, 0x1F, 0xF2, 0x32, 0x06, 0x18,
- 0xFD, 0x3D, 0x01, 0x94, 0xFF, 0x16, 0x00, 0xFF, 0xFF, 0x0F, 0x00,
- 0xC0, 0xFF, 0x78, 0x00, 0x73, 0xFF, 0x38, 0x00, 0x17, 0x01, 0x8B,
- 0xFA, 0xAF, 0x46, 0x59, 0x0F, 0x39, 0xF8, 0xCF, 0x04, 0x15, 0xFD,
- 0x95, 0x01, 0x51, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36,
- 0x00, 0x36, 0xFF, 0xE5, 0x01, 0x46, 0xFC, 0xB8, 0x06, 0xA8, 0xF3,
- 0x3F, 0x1F, 0x64, 0x3E, 0xBA, 0xF3, 0x01, 0x05, 0xE2, 0xFD, 0xC4,
- 0x00, 0xD2, 0xFF, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0xE1, 0xFF,
- 0x25, 0x00, 0x1D, 0x00, 0x05, 0xFF, 0x28, 0x03, 0xBD, 0xF6, 0x77,
- 0x43, 0xB6, 0x16, 0xDC, 0xF5, 0xDD, 0x05, 0x9B, 0xFC, 0xC8, 0x01,
- 0x3E, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x34, 0x00, 0x3D,
- 0xFF, 0xCC, 0x01, 0x8F, 0xFC, 0xF8, 0x05, 0x9B, 0xF5, 0x96, 0x17,
- 0x02, 0x43, 0x5E, 0xF6, 0x5F, 0x03, 0xE4, 0xFE, 0x30, 0x00, 0x1B,
- 0x00, 0xE4, 0xFF, 0x08, 0x00, 0x03, 0x00, 0xFD, 0xFF, 0xD9, 0xFF,
- 0xB4, 0x00, 0xFD, 0xFD, 0xD7, 0x04, 0xFA, 0xF3, 0xFC, 0x3E, 0x5B,
- 0x1E, 0xDB, 0xF3, 0xA6, 0x06, 0x4C, 0xFC, 0xE3, 0x01, 0x36, 0xFF,
- 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x2E, 0x00, 0x4E, 0xFF, 0x9C,
- 0x01, 0x05, 0xFD, 0xF1, 0x04, 0xF0, 0xF7, 0x2D, 0x10, 0x61, 0x46,
- 0x0D, 0xFA, 0x58, 0x01, 0x13, 0x00, 0x87, 0xFF, 0x6E, 0x00, 0xC4,
- 0xFF, 0x0E, 0x00, 0xFF, 0xFF, 0x14, 0x00, 0x9B, 0xFF, 0x31, 0x01,
- 0x2C, 0xFD, 0x15, 0x06, 0x41, 0xF2, 0x6A, 0x39, 0x0A, 0x26, 0x61,
- 0xF2, 0x17, 0x07, 0x31, 0xFC, 0xE2, 0x01, 0x3B, 0xFF, 0x35, 0x00,
- 0xFD, 0xFF, 0x00, 0x00, 0x26, 0x00, 0x69, 0xFF, 0x58, 0x01, 0x9D,
- 0xFD, 0xB9, 0x03, 0x7B, 0xFA, 0x40, 0x09, 0x63, 0x48, 0xBF, 0xFE,
- 0x03, 0xFF, 0x5F, 0x01, 0xD4, 0xFE, 0xC5, 0x00, 0xA2, 0xFF, 0x16,
- 0x00, 0xFD, 0xFF, 0x25, 0x00, 0x6A, 0xFF, 0x8E, 0x01, 0x99, 0xFC,
- 0xDB, 0x06, 0x86, 0xF1, 0xF2, 0x32, 0x82, 0x2D, 0x96, 0xF1, 0x21,
- 0x07, 0x53, 0xFC, 0xC0, 0x01, 0x50, 0xFF, 0x2E, 0x00, 0xFD, 0xFF,
- 0x1D, 0x00, 0x88, 0xFF, 0x07, 0x01, 0x49, 0xFE, 0x67, 0x02, 0x13,
- 0xFD, 0xFF, 0x02, 0xF4, 0x48, 0x5F, 0x04, 0x7A, 0xFC, 0xB6, 0x02,
- 0x20, 0xFE, 0x1B, 0x01, 0x81, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFD,
- 0xFF, 0x30, 0x00, 0x4A, 0xFF, 0xCA, 0x01, 0x46, 0xFC, 0x29, 0x07,
- 0xB3, 0xF1, 0xD1, 0x2B, 0x81, 0x34, 0x9C, 0xF1, 0xB8, 0x06, 0xB5,
- 0xFC, 0x7C, 0x01, 0x74, 0xFF, 0x22, 0x00, 0xFE, 0xFF, 0x15, 0x00,
- 0xAA, 0xFF, 0xB1, 0x00, 0xFE, 0xFE, 0x10, 0x01, 0x92, 0xFF, 0x94,
- 0xFD, 0x0D, 0x48, 0xCB, 0x0A, 0xE2, 0xF9, 0x04, 0x04, 0x77, 0xFD,
- 0x69, 0x01, 0x62, 0xFF, 0x28, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36,
- 0x00, 0x39, 0xFF, 0xE5, 0x01, 0x32, 0xFC, 0x06, 0x07, 0xAA, 0xF2,
- 0x46, 0x24, 0xC8, 0x3A, 0x90, 0xF2, 0xD6, 0x05, 0x57, 0xFD, 0x17,
- 0x01, 0xA8, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x0D, 0x00, 0xCC, 0xFF,
- 0x5A, 0x00, 0xAF, 0xFF, 0xCA, 0xFF, 0xD8, 0x01, 0x1C, 0xF9, 0xB8,
- 0x45, 0xDA, 0x11, 0x60, 0xF7, 0x33, 0x05, 0xE7, 0xFC, 0xA9, 0x01,
- 0x4A, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x37,
- 0xFF, 0xDF, 0x01, 0x5A, 0xFC, 0x7E, 0x06, 0x47, 0xF4, 0x94, 0x1C,
- 0x1F, 0x40, 0x85, 0xF4, 0x7D, 0x04, 0x36, 0xFE, 0x93, 0x00, 0xEA,
- 0xFF, 0xF7, 0xFF, 0x04, 0x00, 0x06, 0x00, 0xEB, 0xFF, 0x09, 0x00,
- 0x54, 0x00, 0xA4, 0xFE, 0xC9, 0x03, 0xAA, 0xF5, 0x0C, 0x42, 0x56,
- 0x19, 0x1E, 0xF5, 0x2B, 0x06, 0x7A, 0xFC, 0xD4, 0x01, 0x3A, 0xFF,
- 0x35, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x32, 0x00, 0x42, 0xFF, 0xBE,
- 0x01, 0xB4, 0xFC, 0xA4, 0x05, 0x61, 0xF6, 0xFB, 0x14, 0x53, 0x44,
- 0x86, 0xF7, 0xB6, 0x02, 0x49, 0xFF, 0xF7, 0xFF, 0x37, 0x00, 0xD9,
- 0xFF, 0x0A, 0x00, 0x01, 0x00, 0x06, 0x00, 0xC2, 0xFF, 0xE3, 0x00,
- 0xAE, 0xFD, 0x52, 0x05, 0x44, 0xF3, 0x2A, 0x3D, 0x06, 0x21, 0x47,
- 0xF3, 0xD8, 0x06, 0x3C, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00,
- 0xFD, 0xFF, 0x00, 0x00, 0x2B, 0x00, 0x57, 0xFF, 0x86, 0x01, 0x36,
- 0xFD, 0x89, 0x04, 0xCD, 0xF8, 0xB7, 0x0D, 0x3D, 0x47, 0x91, 0xFB,
- 0x91, 0x00, 0x83, 0x00, 0x4A, 0xFF, 0x8C, 0x00, 0xB9, 0xFF, 0x11,
- 0x00, 0xFE, 0xFF, 0x1B, 0x00, 0x88, 0xFF, 0x55, 0x01, 0xF2, 0xFC,
- 0x67, 0x06, 0xE4, 0xF1, 0x44, 0x37, 0xAA, 0x28, 0x05, 0xF2, 0x27,
- 0x07, 0x36, 0xFC, 0xDA, 0x01, 0x41, 0xFF, 0x33, 0x00, 0xFD, 0xFF,
- 0x00, 0x00, 0x23, 0x00, 0x73, 0xFF, 0x3D, 0x01, 0xD6, 0xFD, 0x46,
- 0x03, 0x61, 0xFB, 0x00, 0x07, 0xBF, 0x48, 0x98, 0x00, 0x26, 0xFE,
- 0xD5, 0x01, 0x95, 0xFE, 0xE3, 0x00, 0x96, 0xFF, 0x1A, 0x00, 0xFD,
- 0xFF, 0x2A, 0x00, 0x5D, 0xFF, 0xA7, 0x01, 0x75, 0xFC, 0x03, 0x07,
- 0x7D, 0xF1, 0x8A, 0x30, 0xFF, 0x2F, 0x7E, 0xF1, 0x0A, 0x07, 0x6E,
- 0xFC, 0xAC, 0x01, 0x5A, 0xFF, 0x2B, 0x00, 0xFD, 0xFF, 0x1A, 0x00,
- 0x94, 0xFF, 0xEA, 0x00, 0x87, 0xFE, 0xF0, 0x01, 0xF5, 0xFD, 0x05,
- 0x01, 0xCE, 0x48, 0x83, 0x06, 0x94, 0xFB, 0x2C, 0x03, 0xE4, 0xFD,
- 0x37, 0x01, 0x76, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x33,
- 0x00, 0x42, 0xFF, 0xD7, 0x01, 0x38, 0xFC, 0x29, 0x07, 0xF3, 0xF1,
- 0x3E, 0x29, 0xC6, 0x36, 0xD4, 0xF1, 0x77, 0x06, 0xE6, 0xFC, 0x5C,
- 0x01, 0x84, 0xFF, 0x1C, 0x00, 0xFE, 0xFF, 0x12, 0x00, 0xB6, 0xFF,
- 0x93, 0x00, 0x3C, 0xFF, 0x9D, 0x00, 0x63, 0x00, 0xEB, 0xFB, 0x69,
- 0x47, 0x2D, 0x0D, 0xFF, 0xF8, 0x72, 0x04, 0x42, 0xFD, 0x81, 0x01,
- 0x59, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x37,
- 0xFF, 0xE6, 0x01, 0x3A, 0xFC, 0xE2, 0x06, 0x28, 0xF3, 0x9E, 0x21,
- 0xC0, 0x3C, 0x1F, 0xF3, 0x6C, 0x05, 0x9E, 0xFD, 0xED, 0x00, 0xBD,
- 0xFF, 0x07, 0x00, 0x01, 0x00, 0x0A, 0x00, 0xD7, 0xFF, 0x3E, 0x00,
- 0xEA, 0xFF, 0x60, 0xFF, 0x8F, 0x02, 0xCD, 0xF7, 0x99, 0x44, 0x68,
- 0x14, 0x8E, 0xF6, 0x90, 0x05, 0xBC, 0xFC, 0xBA, 0x01, 0x43, 0xFF,
- 0x32, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD7,
- 0x01, 0x73, 0xFC, 0x3B, 0x06, 0xF5, 0xF4, 0xED, 0x19, 0xB7, 0x41,
- 0x71, 0xF5, 0xEB, 0x03, 0x90, 0xFE, 0x60, 0x00, 0x04, 0x00, 0xED,
- 0xFF, 0x06, 0x00, 0x04, 0x00, 0xF5, 0xFF, 0xEF, 0xFF, 0x88, 0x00,
- 0x49, 0xFE, 0x5D, 0x04, 0xB7, 0xF4, 0x7D, 0x40, 0xFD, 0x1B, 0x6C,
- 0xF4, 0x70, 0x06, 0x5F, 0xFC, 0xDE, 0x01, 0x37, 0xFF, 0x36, 0x00,
- 0xFE, 0xFF, 0xFF, 0xFF, 0x30, 0x00, 0x48, 0xFF, 0xAD, 0x01, 0xDD,
- 0xFC, 0x48, 0x05, 0x30, 0xF7, 0x6B, 0x12, 0x7D, 0x45, 0xCF, 0xF8,
- 0x01, 0x02, 0xB2, 0xFF, 0xBD, 0xFF, 0x54, 0x00, 0xCE, 0xFF, 0x0C,
- 0x00, 0x00, 0x00, 0x0E, 0x00, 0xAC, 0xFF, 0x0E, 0x01, 0x66, 0xFD,
- 0xBF, 0x05, 0xAD, 0xF2, 0x3B, 0x3B, 0xB0, 0x23, 0xC4, 0xF2, 0xFF,
- 0x06, 0x33, 0xFC, 0xE5, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF,
- 0x00, 0x00, 0x29, 0x00, 0x60, 0xFF, 0x6E, 0x01, 0x6B, 0xFD, 0x1D,
- 0x04, 0xAF, 0xF9, 0x51, 0x0B, 0xEC, 0x47, 0x33, 0xFD, 0xC1, 0xFF,
- 0xF7, 0x00, 0x0C, 0xFF, 0xAA, 0x00, 0xAD, 0xFF, 0x14, 0x00, 0xFE,
- 0xFF, 0x21, 0x00, 0x77, 0xFF, 0x75, 0x01, 0xBF, 0xFC, 0xAB, 0x06,
- 0xA6, 0xF1, 0x05, 0x35, 0x40, 0x2B, 0xBF, 0xF1, 0x2A, 0x07, 0x42,
- 0xFC, 0xCE, 0x01, 0x48, 0xFF, 0x31, 0x00, 0xFD, 0xFF, 0x00, 0x00,
- 0x20, 0x00, 0x7E, 0xFF, 0x21, 0x01, 0x12, 0xFE, 0xD1, 0x02, 0x47,
- 0xFC, 0xD7, 0x04, 0xF0, 0x48, 0x8D, 0x02, 0x45, 0xFD, 0x4D, 0x02,
- 0x56, 0xFE, 0x01, 0x01, 0x8B, 0xFF, 0x1D, 0x00, 0xFD, 0xFF, 0x2E,
- 0x00, 0x52, 0xFF, 0xBC, 0x01, 0x58, 0xFC, 0x1D, 0x07, 0x8E, 0xF1,
- 0x11, 0x2E, 0x6B, 0x32, 0x81, 0xF1, 0xE5, 0x06, 0x90, 0xFC, 0x94,
- 0x01, 0x67, 0xFF, 0x26, 0x00, 0xFD, 0xFF, 0x17, 0x00, 0xA0, 0xFF,
- 0xCC, 0x00, 0xC6, 0xFE, 0x79, 0x01, 0xD2, 0xFE, 0x26, 0xFF, 0x7C,
- 0x48, 0xBE, 0x08, 0xAE, 0xFA, 0xA0, 0x03, 0xA9, 0xFD, 0x52, 0x01,
- 0x6B, 0xFF, 0x25, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3C,
- 0xFF, 0xE0, 0x01, 0x32, 0xFC, 0x1C, 0x07, 0x4B, 0xF2, 0xA0, 0x26,
- 0xF2, 0x38, 0x2A, 0xF2, 0x28, 0x06, 0x1F, 0xFD, 0x39, 0x01, 0x96,
- 0xFF, 0x16, 0x00, 0xFF, 0xFF, 0x0F, 0x00, 0xC2, 0xFF, 0x75, 0x00,
- 0x7A, 0xFF, 0x2B, 0x00, 0x2D, 0x01, 0x61, 0xFA, 0x97, 0x46, 0xA0,
- 0x0F, 0x20, 0xF8, 0xDA, 0x04, 0x10, 0xFD, 0x97, 0x01, 0x50, 0xFF,
- 0x2E, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4,
- 0x01, 0x48, 0xFC, 0xB2, 0x06, 0xB9, 0xF3, 0xF3, 0x1E, 0x98, 0x3E,
- 0xCF, 0xF3, 0xF3, 0x04, 0xEB, 0xFD, 0xBF, 0x00, 0xD4, 0xFF, 0xFF,
- 0xFF, 0x03, 0x00, 0x08, 0x00, 0xE2, 0xFF, 0x21, 0x00, 0x23, 0x00,
- 0xFA, 0xFE, 0x3A, 0x03, 0x9D, 0xF6, 0x50, 0x43, 0x00, 0x17, 0xC6,
- 0xF5, 0xE6, 0x05, 0x97, 0xFC, 0xC9, 0x01, 0x3E, 0xFF, 0x34, 0x00,
- 0xFE, 0xFF, 0xFE, 0xFF, 0x34, 0x00, 0x3D, 0xFF, 0xCB, 0x01, 0x93,
- 0xFC, 0xEF, 0x05, 0xB0, 0xF5, 0x4B, 0x17, 0x2A, 0x43, 0x7D, 0xF6,
- 0x4D, 0x03, 0xEF, 0xFE, 0x2A, 0x00, 0x1E, 0x00, 0xE3, 0xFF, 0x08,
- 0x00, 0x03, 0x00, 0xFE, 0xFF, 0xD7, 0xFF, 0xBA, 0x00, 0xF4, 0xFD,
- 0xE5, 0x04, 0xE4, 0xF3, 0xCA, 0x3E, 0xA7, 0x1E, 0xCA, 0xF3, 0xAC,
- 0x06, 0x4A, 0xFC, 0xE4, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF,
- 0xFF, 0xFF, 0x2E, 0x00, 0x4F, 0xFF, 0x99, 0x01, 0x0B, 0xFD, 0xE6,
- 0x04, 0x08, 0xF8, 0xE7, 0x0F, 0x7C, 0x46, 0x37, 0xFA, 0x42, 0x01,
- 0x1F, 0x00, 0x81, 0xFF, 0x71, 0x00, 0xC3, 0xFF, 0x0F, 0x00, 0xFF,
- 0xFF, 0x15, 0x00, 0x98, 0xFF, 0x35, 0x01, 0x25, 0xFD, 0x1E, 0x06,
- 0x35, 0xF2, 0x2E, 0x39, 0x55, 0x26, 0x56, 0xF2, 0x1A, 0x07, 0x31,
- 0xFC, 0xE1, 0x01, 0x3C, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x00, 0x00,
- 0x26, 0x00, 0x6A, 0xFF, 0x55, 0x01, 0xA3, 0xFD, 0xAD, 0x03, 0x94,
- 0xFA, 0xFF, 0x08, 0x70, 0x48, 0xF3, 0xFE, 0xEA, 0xFE, 0x6C, 0x01,
- 0xCD, 0xFE, 0xC9, 0x00, 0xA1, 0xFF, 0x17, 0x00, 0xFD, 0xFF, 0x26,
- 0x00, 0x69, 0xFF, 0x91, 0x01, 0x94, 0xFC, 0xE0, 0x06, 0x84, 0xF1,
- 0xAF, 0x32, 0xCA, 0x2D, 0x92, 0xF1, 0x1F, 0x07, 0x56, 0xFC, 0xBE,
- 0x01, 0x51, 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0x1D, 0x00, 0x8A, 0xFF,
- 0x04, 0x01, 0x50, 0xFE, 0x5A, 0x02, 0x2C, 0xFD, 0xC6, 0x02, 0xF2,
- 0x48, 0x9B, 0x04, 0x61, 0xFC, 0xC3, 0x02, 0x19, 0xFE, 0x1E, 0x01,
- 0x7F, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x31, 0x00, 0x49,
- 0xFF, 0xCC, 0x01, 0x44, 0xFC, 0x29, 0x07, 0xB9, 0xF1, 0x89, 0x2B,
- 0xC3, 0x34, 0xA0, 0xF1, 0xB1, 0x06, 0xBA, 0xFC, 0x79, 0x01, 0x76,
- 0xFF, 0x21, 0x00, 0xFE, 0xFF, 0x14, 0x00, 0xAC, 0xFF, 0xAE, 0x00,
- 0x05, 0xFF, 0x03, 0x01, 0xAA, 0xFF, 0x63, 0xFD, 0xFD, 0x47, 0x0E,
- 0x0B, 0xC8, 0xF9, 0x11, 0x04, 0x71, 0xFD, 0x6C, 0x01, 0x61, 0xFF,
- 0x28, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE5,
- 0x01, 0x33, 0xFC, 0x03, 0x07, 0xB7, 0xF2, 0xFC, 0x23, 0x03, 0x3B,
- 0x9E, 0xF2, 0xCB, 0x05, 0x5F, 0xFD, 0x12, 0x01, 0xAA, 0xFF, 0x0E,
- 0x00, 0x00, 0x00, 0x0C, 0x00, 0xCD, 0xFF, 0x57, 0x00, 0xB6, 0xFF,
- 0xBE, 0xFF, 0xED, 0x01, 0xF5, 0xF8, 0x9B, 0x45, 0x22, 0x12, 0x48,
- 0xF7, 0x3D, 0x05, 0xE2, 0xFC, 0xAB, 0x01, 0x49, 0xFF, 0x30, 0x00,
- 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xDF, 0x01, 0x5C,
- 0xFC, 0x78, 0x06, 0x5A, 0xF4, 0x49, 0x1C, 0x4E, 0x40, 0x9E, 0xF4,
- 0x6D, 0x04, 0x3F, 0xFE, 0x8E, 0x00, 0xED, 0xFF, 0xF6, 0xFF, 0x04,
- 0x00, 0x06, 0x00, 0xEC, 0xFF, 0x06, 0x00, 0x5A, 0x00, 0x9A, 0xFE,
- 0xDA, 0x03, 0x8D, 0xF5, 0xE1, 0x41, 0xA1, 0x19, 0x09, 0xF5, 0x33,
- 0x06, 0x77, 0xFC, 0xD6, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFE, 0xFF,
- 0xFF, 0xFF, 0x32, 0x00, 0x42, 0xFF, 0xBC, 0x01, 0xB8, 0xFC, 0x9A,
- 0x05, 0x77, 0xF6, 0xB1, 0x14, 0x77, 0x44, 0xA9, 0xF7, 0xA2, 0x02,
- 0x54, 0xFF, 0xF1, 0xFF, 0x3A, 0x00, 0xD8, 0xFF, 0x0A, 0x00, 0x01,
- 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xE8, 0x00, 0xA6, 0xFD, 0x5F, 0x05,
- 0x31, 0xF3, 0xF6, 0x3C, 0x52, 0x21, 0x37, 0xF3, 0xDD, 0x06, 0x3B,
- 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00,
- 0x2B, 0x00, 0x58, 0xFF, 0x83, 0x01, 0x3C, 0xFD, 0x7E, 0x04, 0xE6,
- 0xF8, 0x72, 0x0D, 0x52, 0x47, 0xBE, 0xFB, 0x7A, 0x00, 0x90, 0x00,
- 0x43, 0xFF, 0x8F, 0x00, 0xB7, 0xFF, 0x11, 0x00, 0xFE, 0xFF, 0x1C,
- 0x00, 0x86, 0xFF, 0x59, 0x01, 0xEC, 0xFC, 0x6F, 0x06, 0xDC, 0xF1,
- 0x04, 0x37, 0xF3, 0x28, 0xFC, 0xF1, 0x28, 0x07, 0x37, 0xFC, 0xD8,
- 0x01, 0x41, 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x23, 0x00,
- 0x74, 0xFF, 0x3A, 0x01, 0xDD, 0xFD, 0x39, 0x03, 0x7B, 0xFB, 0xC1,
- 0x06, 0xC7, 0x48, 0xCF, 0x00, 0x0D, 0xFE, 0xE3, 0x01, 0x8E, 0xFE,
- 0xE7, 0x00, 0x95, 0xFF, 0x1A, 0x00, 0xFD, 0xFF, 0x2A, 0x00, 0x5C,
- 0xFF, 0xAA, 0x01, 0x71, 0xFC, 0x07, 0x07, 0x7E, 0xF1, 0x44, 0x30,
- 0x44, 0x30, 0x7E, 0xF1, 0x07, 0x07, 0x71, 0xFC, 0xAA, 0x01, 0x5C,
- 0xFF, 0x2A, 0x00, 0xFD, 0xFF, 0x1A, 0x00, 0x95, 0xFF, 0xE7, 0x00,
- 0x8E, 0xFE, 0xE3, 0x01, 0x0D, 0xFE, 0xCF, 0x00, 0xC7, 0x48, 0xC1,
- 0x06, 0x7B, 0xFB, 0x39, 0x03, 0xDD, 0xFD, 0x3A, 0x01, 0x74, 0xFF,
- 0x23, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x33, 0x00, 0x41, 0xFF, 0xD8,
- 0x01, 0x37, 0xFC, 0x28, 0x07, 0xFC, 0xF1, 0xF3, 0x28, 0x04, 0x37,
- 0xDC, 0xF1, 0x6F, 0x06, 0xEC, 0xFC, 0x59, 0x01, 0x86, 0xFF, 0x1C,
- 0x00, 0xFE, 0xFF, 0x11, 0x00, 0xB7, 0xFF, 0x8F, 0x00, 0x43, 0xFF,
- 0x90, 0x00, 0x7A, 0x00, 0xBE, 0xFB, 0x52, 0x47, 0x72, 0x0D, 0xE6,
- 0xF8, 0x7E, 0x04, 0x3C, 0xFD, 0x83, 0x01, 0x58, 0xFF, 0x2B, 0x00,
- 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3B,
- 0xFC, 0xDD, 0x06, 0x37, 0xF3, 0x52, 0x21, 0xF6, 0x3C, 0x31, 0xF3,
- 0x5F, 0x05, 0xA6, 0xFD, 0xE8, 0x00, 0xC0, 0xFF, 0x07, 0x00, 0x01,
- 0x00, 0x0A, 0x00, 0xD8, 0xFF, 0x3A, 0x00, 0xF1, 0xFF, 0x54, 0xFF,
- 0xA2, 0x02, 0xA9, 0xF7, 0x77, 0x44, 0xB1, 0x14, 0x77, 0xF6, 0x9A,
- 0x05, 0xB8, 0xFC, 0xBC, 0x01, 0x42, 0xFF, 0x32, 0x00, 0xFF, 0xFF,
- 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD6, 0x01, 0x77, 0xFC, 0x33,
- 0x06, 0x09, 0xF5, 0xA1, 0x19, 0xE1, 0x41, 0x8D, 0xF5, 0xDA, 0x03,
- 0x9A, 0xFE, 0x5A, 0x00, 0x06, 0x00, 0xEC, 0xFF, 0x06, 0x00, 0x04,
- 0x00, 0xF6, 0xFF, 0xED, 0xFF, 0x8E, 0x00, 0x3F, 0xFE, 0x6D, 0x04,
- 0x9E, 0xF4, 0x4E, 0x40, 0x49, 0x1C, 0x5A, 0xF4, 0x78, 0x06, 0x5C,
- 0xFC, 0xDF, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF,
- 0x30, 0x00, 0x49, 0xFF, 0xAB, 0x01, 0xE2, 0xFC, 0x3D, 0x05, 0x48,
- 0xF7, 0x22, 0x12, 0x9B, 0x45, 0xF5, 0xF8, 0xED, 0x01, 0xBE, 0xFF,
- 0xB6, 0xFF, 0x57, 0x00, 0xCD, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x0E,
- 0x00, 0xAA, 0xFF, 0x12, 0x01, 0x5F, 0xFD, 0xCB, 0x05, 0x9E, 0xF2,
- 0x03, 0x3B, 0xFC, 0x23, 0xB7, 0xF2, 0x03, 0x07, 0x33, 0xFC, 0xE5,
- 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x28, 0x00,
- 0x61, 0xFF, 0x6C, 0x01, 0x71, 0xFD, 0x11, 0x04, 0xC8, 0xF9, 0x0E,
- 0x0B, 0xFD, 0x47, 0x63, 0xFD, 0xAA, 0xFF, 0x03, 0x01, 0x05, 0xFF,
- 0xAE, 0x00, 0xAC, 0xFF, 0x14, 0x00, 0xFE, 0xFF, 0x21, 0x00, 0x76,
- 0xFF, 0x79, 0x01, 0xBA, 0xFC, 0xB1, 0x06, 0xA0, 0xF1, 0xC3, 0x34,
- 0x89, 0x2B, 0xB9, 0xF1, 0x29, 0x07, 0x44, 0xFC, 0xCC, 0x01, 0x49,
- 0xFF, 0x31, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x20, 0x00, 0x7F, 0xFF,
- 0x1E, 0x01, 0x19, 0xFE, 0xC3, 0x02, 0x61, 0xFC, 0x9B, 0x04, 0xF2,
- 0x48, 0xC6, 0x02, 0x2C, 0xFD, 0x5A, 0x02, 0x50, 0xFE, 0x04, 0x01,
- 0x8A, 0xFF, 0x1D, 0x00, 0xFD, 0xFF, 0x2E, 0x00, 0x51, 0xFF, 0xBE,
- 0x01, 0x56, 0xFC, 0x1F, 0x07, 0x92, 0xF1, 0xCA, 0x2D, 0xAF, 0x32,
- 0x84, 0xF1, 0xE0, 0x06, 0x94, 0xFC, 0x91, 0x01, 0x69, 0xFF, 0x26,
- 0x00, 0xFD, 0xFF, 0x17, 0x00, 0xA1, 0xFF, 0xC9, 0x00, 0xCD, 0xFE,
- 0x6C, 0x01, 0xEA, 0xFE, 0xF3, 0xFE, 0x70, 0x48, 0xFF, 0x08, 0x94,
- 0xFA, 0xAD, 0x03, 0xA3, 0xFD, 0x55, 0x01, 0x6A, 0xFF, 0x26, 0x00,
- 0x00, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3C, 0xFF, 0xE1, 0x01, 0x31,
- 0xFC, 0x1A, 0x07, 0x56, 0xF2, 0x55, 0x26, 0x2E, 0x39, 0x35, 0xF2,
- 0x1E, 0x06, 0x25, 0xFD, 0x35, 0x01, 0x98, 0xFF, 0x15, 0x00, 0xFF,
- 0xFF, 0x0F, 0x00, 0xC3, 0xFF, 0x71, 0x00, 0x81, 0xFF, 0x1F, 0x00,
- 0x42, 0x01, 0x37, 0xFA, 0x7C, 0x46, 0xE7, 0x0F, 0x08, 0xF8, 0xE6,
- 0x04, 0x0B, 0xFD, 0x99, 0x01, 0x4F, 0xFF, 0x2E, 0x00, 0xFF, 0xFF,
- 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4, 0x01, 0x4A, 0xFC, 0xAC,
- 0x06, 0xCA, 0xF3, 0xA7, 0x1E, 0xCA, 0x3E, 0xE4, 0xF3, 0xE5, 0x04,
- 0xF4, 0xFD, 0xBA, 0x00, 0xD7, 0xFF, 0xFE, 0xFF, 0x03, 0x00, 0x08,
- 0x00, 0xE3, 0xFF, 0x1E, 0x00, 0x2A, 0x00, 0xEF, 0xFE, 0x4D, 0x03,
- 0x7D, 0xF6, 0x2A, 0x43, 0x4B, 0x17, 0xB0, 0xF5, 0xEF, 0x05, 0x93,
- 0xFC, 0xCB, 0x01, 0x3D, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0xFE, 0xFF,
- 0x34, 0x00, 0x3E, 0xFF, 0xC9, 0x01, 0x97, 0xFC, 0xE6, 0x05, 0xC6,
- 0xF5, 0x00, 0x17, 0x50, 0x43, 0x9D, 0xF6, 0x3A, 0x03, 0xFA, 0xFE,
- 0x23, 0x00, 0x21, 0x00, 0xE2, 0xFF, 0x08, 0x00, 0x03, 0x00, 0xFF,
- 0xFF, 0xD4, 0xFF, 0xBF, 0x00, 0xEB, 0xFD, 0xF3, 0x04, 0xCF, 0xF3,
- 0x98, 0x3E, 0xF3, 0x1E, 0xB9, 0xF3, 0xB2, 0x06, 0x48, 0xFC, 0xE4,
- 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x2E, 0x00,
- 0x50, 0xFF, 0x97, 0x01, 0x10, 0xFD, 0xDA, 0x04, 0x20, 0xF8, 0xA0,
- 0x0F, 0x97, 0x46, 0x61, 0xFA, 0x2D, 0x01, 0x2B, 0x00, 0x7A, 0xFF,
- 0x75, 0x00, 0xC2, 0xFF, 0x0F, 0x00, 0xFF, 0xFF, 0x16, 0x00, 0x96,
- 0xFF, 0x39, 0x01, 0x1F, 0xFD, 0x28, 0x06, 0x2A, 0xF2, 0xF2, 0x38,
- 0xA0, 0x26, 0x4B, 0xF2, 0x1C, 0x07, 0x32, 0xFC, 0xE0, 0x01, 0x3C,
- 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6B, 0xFF,
- 0x52, 0x01, 0xA9, 0xFD, 0xA0, 0x03, 0xAE, 0xFA, 0xBE, 0x08, 0x7C,
- 0x48, 0x26, 0xFF, 0xD2, 0xFE, 0x79, 0x01, 0xC6, 0xFE, 0xCC, 0x00,
- 0xA0, 0xFF, 0x17, 0x00, 0xFD, 0xFF, 0x26, 0x00, 0x67, 0xFF, 0x94,
- 0x01, 0x90, 0xFC, 0xE5, 0x06, 0x81, 0xF1, 0x6B, 0x32, 0x11, 0x2E,
- 0x8E, 0xF1, 0x1D, 0x07, 0x58, 0xFC, 0xBC, 0x01, 0x52, 0xFF, 0x2E,
- 0x00, 0xFD, 0xFF, 0x1D, 0x00, 0x8B, 0xFF, 0x01, 0x01, 0x56, 0xFE,
- 0x4D, 0x02, 0x45, 0xFD, 0x8D, 0x02, 0xF0, 0x48, 0xD7, 0x04, 0x47,
- 0xFC, 0xD1, 0x02, 0x12, 0xFE, 0x21, 0x01, 0x7E, 0xFF, 0x20, 0x00,
- 0x00, 0x00, 0xFD, 0xFF, 0x31, 0x00, 0x48, 0xFF, 0xCE, 0x01, 0x42,
- 0xFC, 0x2A, 0x07, 0xBF, 0xF1, 0x40, 0x2B, 0x05, 0x35, 0xA6, 0xF1,
- 0xAB, 0x06, 0xBF, 0xFC, 0x75, 0x01, 0x77, 0xFF, 0x21, 0x00, 0xFE,
- 0xFF, 0x14, 0x00, 0xAD, 0xFF, 0xAA, 0x00, 0x0C, 0xFF, 0xF7, 0x00,
- 0xC1, 0xFF, 0x33, 0xFD, 0xEC, 0x47, 0x51, 0x0B, 0xAF, 0xF9, 0x1D,
- 0x04, 0x6B, 0xFD, 0x6E, 0x01, 0x60, 0xFF, 0x29, 0x00, 0x00, 0x00,
- 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE5, 0x01, 0x33, 0xFC, 0xFF,
- 0x06, 0xC4, 0xF2, 0xB0, 0x23, 0x3B, 0x3B, 0xAD, 0xF2, 0xBF, 0x05,
- 0x66, 0xFD, 0x0E, 0x01, 0xAC, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0x0C,
- 0x00, 0xCE, 0xFF, 0x54, 0x00, 0xBD, 0xFF, 0xB2, 0xFF, 0x01, 0x02,
- 0xCF, 0xF8, 0x7D, 0x45, 0x6B, 0x12, 0x30, 0xF7, 0x48, 0x05, 0xDD,
- 0xFC, 0xAD, 0x01, 0x48, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0xFE, 0xFF,
- 0x36, 0x00, 0x37, 0xFF, 0xDE, 0x01, 0x5F, 0xFC, 0x70, 0x06, 0x6C,
- 0xF4, 0xFD, 0x1B, 0x7D, 0x40, 0xB7, 0xF4, 0x5D, 0x04, 0x49, 0xFE,
- 0x88, 0x00, 0xEF, 0xFF, 0xF5, 0xFF, 0x04, 0x00, 0x06, 0x00, 0xED,
- 0xFF, 0x04, 0x00, 0x60, 0x00, 0x90, 0xFE, 0xEB, 0x03, 0x71, 0xF5,
- 0xB7, 0x41, 0xED, 0x19, 0xF5, 0xF4, 0x3B, 0x06, 0x73, 0xFC, 0xD7,
- 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x32, 0x00,
- 0x43, 0xFF, 0xBA, 0x01, 0xBC, 0xFC, 0x90, 0x05, 0x8E, 0xF6, 0x68,
- 0x14, 0x99, 0x44, 0xCD, 0xF7, 0x8F, 0x02, 0x60, 0xFF, 0xEA, 0xFF,
- 0x3E, 0x00, 0xD7, 0xFF, 0x0A, 0x00, 0x01, 0x00, 0x07, 0x00, 0xBD,
- 0xFF, 0xED, 0x00, 0x9E, 0xFD, 0x6C, 0x05, 0x1F, 0xF3, 0xC0, 0x3C,
- 0x9E, 0x21, 0x28, 0xF3, 0xE2, 0x06, 0x3A, 0xFC, 0xE6, 0x01, 0x37,
- 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x2B, 0x00, 0x59, 0xFF,
- 0x81, 0x01, 0x42, 0xFD, 0x72, 0x04, 0xFF, 0xF8, 0x2D, 0x0D, 0x69,
- 0x47, 0xEB, 0xFB, 0x63, 0x00, 0x9D, 0x00, 0x3C, 0xFF, 0x93, 0x00,
- 0xB6, 0xFF, 0x12, 0x00, 0xFE, 0xFF, 0x1C, 0x00, 0x84, 0xFF, 0x5C,
- 0x01, 0xE6, 0xFC, 0x77, 0x06, 0xD4, 0xF1, 0xC6, 0x36, 0x3E, 0x29,
- 0xF3, 0xF1, 0x29, 0x07, 0x38, 0xFC, 0xD7, 0x01, 0x42, 0xFF, 0x33,
- 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x22, 0x00, 0x76, 0xFF, 0x37, 0x01,
- 0xE4, 0xFD, 0x2C, 0x03, 0x94, 0xFB, 0x83, 0x06, 0xCE, 0x48, 0x05,
- 0x01, 0xF5, 0xFD, 0xF0, 0x01, 0x87, 0xFE, 0xEA, 0x00, 0x94, 0xFF,
- 0x1A, 0x00, 0xFD, 0xFF, 0x2B, 0x00, 0x5A, 0xFF, 0xAC, 0x01, 0x6E,
- 0xFC, 0x0A, 0x07, 0x7E, 0xF1, 0xFF, 0x2F, 0x8A, 0x30, 0x7D, 0xF1,
- 0x03, 0x07, 0x75, 0xFC, 0xA7, 0x01, 0x5D, 0xFF, 0x2A, 0x00, 0xFD,
- 0xFF, 0x1A, 0x00, 0x96, 0xFF, 0xE3, 0x00, 0x95, 0xFE, 0xD5, 0x01,
- 0x26, 0xFE, 0x98, 0x00, 0xBF, 0x48, 0x00, 0x07, 0x61, 0xFB, 0x46,
- 0x03, 0xD6, 0xFD, 0x3D, 0x01, 0x73, 0xFF, 0x23, 0x00, 0x00, 0x00,
- 0xFD, 0xFF, 0x33, 0x00, 0x41, 0xFF, 0xDA, 0x01, 0x36, 0xFC, 0x27,
- 0x07, 0x05, 0xF2, 0xAA, 0x28, 0x44, 0x37, 0xE4, 0xF1, 0x67, 0x06,
- 0xF2, 0xFC, 0x55, 0x01, 0x88, 0xFF, 0x1B, 0x00, 0xFE, 0xFF, 0x11,
- 0x00, 0xB9, 0xFF, 0x8C, 0x00, 0x4A, 0xFF, 0x83, 0x00, 0x91, 0x00,
- 0x91, 0xFB, 0x3D, 0x47, 0xB7, 0x0D, 0xCD, 0xF8, 0x89, 0x04, 0x36,
- 0xFD, 0x86, 0x01, 0x57, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0xFD, 0xFF,
- 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3C, 0xFC, 0xD8, 0x06, 0x47,
- 0xF3, 0x06, 0x21, 0x2A, 0x3D, 0x44, 0xF3, 0x52, 0x05, 0xAE, 0xFD,
- 0xE3, 0x00, 0xC2, 0xFF, 0x06, 0x00, 0x01, 0x00, 0x0A, 0x00, 0xD9,
- 0xFF, 0x37, 0x00, 0xF7, 0xFF, 0x49, 0xFF, 0xB6, 0x02, 0x86, 0xF7,
- 0x53, 0x44, 0xFB, 0x14, 0x61, 0xF6, 0xA4, 0x05, 0xB4, 0xFC, 0xBE,
- 0x01, 0x42, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x35, 0x00,
- 0x3A, 0xFF, 0xD4, 0x01, 0x7A, 0xFC, 0x2B, 0x06, 0x1E, 0xF5, 0x56,
- 0x19, 0x0C, 0x42, 0xAA, 0xF5, 0xC9, 0x03, 0xA4, 0xFE, 0x54, 0x00,
- 0x09, 0x00, 0xEB, 0xFF, 0x06, 0x00, 0x04, 0x00, 0xF7, 0xFF, 0xEA,
- 0xFF, 0x93, 0x00, 0x36, 0xFE, 0x7D, 0x04, 0x85, 0xF4, 0x1F, 0x40,
- 0x94, 0x1C, 0x47, 0xF4, 0x7E, 0x06, 0x5A, 0xFC, 0xDF, 0x01, 0x37,
- 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x30, 0x00, 0x4A, 0xFF,
- 0xA9, 0x01, 0xE7, 0xFC, 0x33, 0x05, 0x60, 0xF7, 0xDA, 0x11, 0xB8,
- 0x45, 0x1C, 0xF9, 0xD8, 0x01, 0xCA, 0xFF, 0xAF, 0xFF, 0x5A, 0x00,
- 0xCC, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0xA8, 0xFF, 0x17,
- 0x01, 0x57, 0xFD, 0xD6, 0x05, 0x90, 0xF2, 0xC8, 0x3A, 0x46, 0x24,
- 0xAA, 0xF2, 0x06, 0x07, 0x32, 0xFC, 0xE5, 0x01, 0x39, 0xFF, 0x36,
- 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x28, 0x00, 0x62, 0xFF, 0x69, 0x01,
- 0x77, 0xFD, 0x04, 0x04, 0xE2, 0xF9, 0xCB, 0x0A, 0x0D, 0x48, 0x94,
- 0xFD, 0x92, 0xFF, 0x10, 0x01, 0xFE, 0xFE, 0xB1, 0x00, 0xAA, 0xFF,
- 0x15, 0x00, 0xFE, 0xFF, 0x22, 0x00, 0x74, 0xFF, 0x7C, 0x01, 0xB5,
- 0xFC, 0xB8, 0x06, 0x9C, 0xF1, 0x81, 0x34, 0xD1, 0x2B, 0xB3, 0xF1,
- 0x29, 0x07, 0x46, 0xFC, 0xCA, 0x01, 0x4A, 0xFF, 0x30, 0x00, 0xFD,
- 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x81, 0xFF, 0x1B, 0x01, 0x20, 0xFE,
- 0xB6, 0x02, 0x7A, 0xFC, 0x5F, 0x04, 0xF4, 0x48, 0xFF, 0x02, 0x13,
- 0xFD, 0x67, 0x02, 0x49, 0xFE, 0x07, 0x01, 0x88, 0xFF, 0x1D, 0x00,
- 0xFD, 0xFF, 0x2E, 0x00, 0x50, 0xFF, 0xC0, 0x01, 0x53, 0xFC, 0x21,
- 0x07, 0x96, 0xF1, 0x82, 0x2D, 0xF2, 0x32, 0x86, 0xF1, 0xDB, 0x06,
- 0x99, 0xFC, 0x8E, 0x01, 0x6A, 0xFF, 0x25, 0x00, 0xFD, 0xFF, 0x16,
- 0x00, 0xA2, 0xFF, 0xC5, 0x00, 0xD4, 0xFE, 0x5F, 0x01, 0x03, 0xFF,
- 0xBF, 0xFE, 0x63, 0x48, 0x40, 0x09, 0x7B, 0xFA, 0xB9, 0x03, 0x9D,
- 0xFD, 0x58, 0x01, 0x69, 0xFF, 0x26, 0x00, 0x00, 0x00, 0xFD, 0xFF,
- 0x35, 0x00, 0x3B, 0xFF, 0xE2, 0x01, 0x31, 0xFC, 0x17, 0x07, 0x61,
- 0xF2, 0x0A, 0x26, 0x6A, 0x39, 0x41, 0xF2, 0x15, 0x06, 0x2C, 0xFD,
- 0x31, 0x01, 0x9B, 0xFF, 0x14, 0x00, 0xFF, 0xFF, 0x0E, 0x00, 0xC4,
- 0xFF, 0x6E, 0x00, 0x87, 0xFF, 0x13, 0x00, 0x58, 0x01, 0x0D, 0xFA,
- 0x61, 0x46, 0x2D, 0x10, 0xF0, 0xF7, 0xF1, 0x04, 0x05, 0xFD, 0x9C,
- 0x01, 0x4E, 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00,
- 0x36, 0xFF, 0xE3, 0x01, 0x4C, 0xFC, 0xA6, 0x06, 0xDB, 0xF3, 0x5B,
- 0x1E, 0xFC, 0x3E, 0xFA, 0xF3, 0xD7, 0x04, 0xFD, 0xFD, 0xB4, 0x00,
- 0xD9, 0xFF, 0xFD, 0xFF, 0x03, 0x00, 0x08, 0x00, 0xE4, 0xFF, 0x1B,
- 0x00, 0x30, 0x00, 0xE4, 0xFE, 0x5F, 0x03, 0x5E, 0xF6, 0x02, 0x43,
- 0x96, 0x17, 0x9B, 0xF5, 0xF8, 0x05, 0x8F, 0xFC, 0xCC, 0x01, 0x3D,
- 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x33, 0x00, 0x3E, 0xFF,
- 0xC8, 0x01, 0x9B, 0xFC, 0xDD, 0x05, 0xDC, 0xF5, 0xB6, 0x16, 0x77,
- 0x43, 0xBD, 0xF6, 0x28, 0x03, 0x05, 0xFF, 0x1D, 0x00, 0x25, 0x00,
- 0xE1, 0xFF, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0xD2, 0xFF, 0xC4,
- 0x00, 0xE2, 0xFD, 0x01, 0x05, 0xBA, 0xF3, 0x64, 0x3E, 0x3F, 0x1F,
- 0xA8, 0xF3, 0xB8, 0x06, 0x46, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36,
- 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x2D, 0x00, 0x51, 0xFF, 0x95, 0x01,
- 0x15, 0xFD, 0xCF, 0x04, 0x39, 0xF8, 0x59, 0x0F, 0xAF, 0x46, 0x8B,
- 0xFA, 0x17, 0x01, 0x38, 0x00, 0x73, 0xFF, 0x78, 0x00, 0xC0, 0xFF,
- 0x0F, 0x00, 0xFF, 0xFF, 0x16, 0x00, 0x94, 0xFF, 0x3D, 0x01, 0x18,
- 0xFD, 0x32, 0x06, 0x1F, 0xF2, 0xB5, 0x38, 0xEB, 0x26, 0x40, 0xF2,
- 0x1E, 0x07, 0x32, 0xFC, 0xDF, 0x01, 0x3D, 0xFF, 0x35, 0x00, 0xFD,
- 0xFF, 0x00, 0x00, 0x25, 0x00, 0x6C, 0xFF, 0x4F, 0x01, 0xB0, 0xFD,
- 0x93, 0x03, 0xC7, 0xFA, 0x7D, 0x08, 0x86, 0x48, 0x5A, 0xFF, 0xBA,
- 0xFE, 0x86, 0x01, 0xBF, 0xFE, 0xCF, 0x00, 0x9E, 0xFF, 0x17, 0x00,
- 0xFD, 0xFF, 0x27, 0x00, 0x66, 0xFF, 0x97, 0x01, 0x8C, 0xFC, 0xEA,
- 0x06, 0x80, 0xF1, 0x26, 0x32, 0x58, 0x2E, 0x8B, 0xF1, 0x1B, 0x07,
- 0x5B, 0xFC, 0xBA, 0x01, 0x53, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, 0x1C,
- 0x00, 0x8C, 0xFF, 0xFE, 0x00, 0x5D, 0xFE, 0x3F, 0x02, 0x5E, 0xFD,
- 0x54, 0x02, 0xEC, 0x48, 0x13, 0x05, 0x2E, 0xFC, 0xDE, 0x02, 0x0C,
- 0xFE, 0x24, 0x01, 0x7D, 0xFF, 0x20, 0x00, 0x00, 0x00, 0xFD, 0xFF,
- 0x31, 0x00, 0x47, 0xFF, 0xCF, 0x01, 0x40, 0xFC, 0x2A, 0x07, 0xC6,
- 0xF1, 0xF7, 0x2A, 0x46, 0x35, 0xAB, 0xF1, 0xA4, 0x06, 0xC4, 0xFC,
- 0x72, 0x01, 0x79, 0xFF, 0x20, 0x00, 0xFE, 0xFF, 0x14, 0x00, 0xAE,
- 0xFF, 0xA7, 0x00, 0x12, 0xFF, 0xEA, 0x00, 0xD9, 0xFF, 0x03, 0xFD,
- 0xDC, 0x47, 0x95, 0x0B, 0x96, 0xF9, 0x29, 0x04, 0x65, 0xFD, 0x71,
- 0x01, 0x5F, 0xFF, 0x29, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00,
- 0x38, 0xFF, 0xE6, 0x01, 0x34, 0xFC, 0xFB, 0x06, 0xD2, 0xF2, 0x64,
- 0x23, 0x73, 0x3B, 0xBC, 0xF2, 0xB4, 0x05, 0x6E, 0xFD, 0x09, 0x01,
- 0xAF, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x0C, 0x00, 0xD0, 0xFF, 0x51,
- 0x00, 0xC3, 0xFF, 0xA6, 0xFF, 0x16, 0x02, 0xA9, 0xF8, 0x5C, 0x45,
- 0xB2, 0x12, 0x19, 0xF7, 0x52, 0x05, 0xD8, 0xFC, 0xAF, 0x01, 0x47,
- 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x38, 0xFF,
- 0xDD, 0x01, 0x62, 0xFC, 0x69, 0x06, 0x7F, 0xF4, 0xB2, 0x1B, 0xAB,
- 0x40, 0xD0, 0xF4, 0x4E, 0x04, 0x53, 0xFE, 0x83, 0x00, 0xF2, 0xFF,
- 0xF4, 0xFF, 0x05, 0x00, 0x06, 0x00, 0xEE, 0xFF, 0x01, 0x00, 0x66,
- 0x00, 0x85, 0xFE, 0xFC, 0x03, 0x55, 0xF5, 0x8C, 0x41, 0x38, 0x1A,
- 0xE1, 0xF4, 0x43, 0x06, 0x70, 0xFC, 0xD8, 0x01, 0x39, 0xFF, 0x35,
- 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x32, 0x00, 0x44, 0xFF, 0xB9, 0x01,
- 0xC1, 0xFC, 0x86, 0x05, 0xA5, 0xF6, 0x1E, 0x14, 0xBA, 0x44, 0xF0,
- 0xF7, 0x7B, 0x02, 0x6B, 0xFF, 0xE4, 0xFF, 0x41, 0x00, 0xD6, 0xFF,
- 0x0B, 0x00, 0x01, 0x00, 0x08, 0x00, 0xBB, 0xFF, 0xF1, 0x00, 0x96,
- 0xFD, 0x78, 0x05, 0x0E, 0xF3, 0x8A, 0x3C, 0xEA, 0x21, 0x19, 0xF3,
- 0xE6, 0x06, 0x38, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD,
- 0xFF, 0x00, 0x00, 0x2B, 0x00, 0x5A, 0xFF, 0x7E, 0x01, 0x48, 0xFD,
- 0x66, 0x04, 0x18, 0xF9, 0xE8, 0x0C, 0x7C, 0x47, 0x19, 0xFC, 0x4D,
- 0x00, 0xA9, 0x00, 0x35, 0xFF, 0x96, 0x00, 0xB5, 0xFF, 0x12, 0x00,
- 0xFE, 0xFF, 0x1D, 0x00, 0x82, 0xFF, 0x60, 0x01, 0xE0, 0xFC, 0x7F,
- 0x06, 0xCC, 0xF1, 0x85, 0x36, 0x87, 0x29, 0xEB, 0xF1, 0x2A, 0x07,
- 0x39, 0xFC, 0xD6, 0x01, 0x43, 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0x00,
- 0x00, 0x22, 0x00, 0x77, 0xFF, 0x34, 0x01, 0xEA, 0xFD, 0x1F, 0x03,
- 0xAE, 0xFB, 0x45, 0x06, 0xD5, 0x48, 0x3C, 0x01, 0xDC, 0xFD, 0xFD,
- 0x01, 0x80, 0xFE, 0xED, 0x00, 0x93, 0xFF, 0x1B, 0x00, 0xFD, 0xFF,
- 0x2B, 0x00, 0x59, 0xFF, 0xAE, 0x01, 0x6A, 0xFC, 0x0D, 0x07, 0x80,
- 0xF1, 0xB8, 0x2F, 0xCF, 0x30, 0x7D, 0xF1, 0xFF, 0x06, 0x78, 0xFC,
- 0xA5, 0x01, 0x5F, 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0x19, 0x00, 0x98,
- 0xFF, 0xE0, 0x00, 0x9C, 0xFE, 0xC8, 0x01, 0x3F, 0xFE, 0x62, 0x00,
- 0xB8, 0x48, 0x3F, 0x07, 0x47, 0xFB, 0x53, 0x03, 0xD0, 0xFD, 0x40,
- 0x01, 0x72, 0xFF, 0x23, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x34, 0x00,
- 0x40, 0xFF, 0xDB, 0x01, 0x35, 0xFC, 0x26, 0x07, 0x0E, 0xF2, 0x60,
- 0x28, 0x82, 0x37, 0xED, 0xF1, 0x5E, 0x06, 0xF8, 0xFC, 0x51, 0x01,
- 0x8A, 0xFF, 0x1A, 0x00, 0xFF, 0xFF, 0x11, 0x00, 0xBA, 0xFF, 0x89,
- 0x00, 0x51, 0xFF, 0x77, 0x00, 0xA7, 0x00, 0x64, 0xFB, 0x26, 0x47,
- 0xFC, 0x0D, 0xB4, 0xF8, 0x95, 0x04, 0x31, 0xFD, 0x88, 0x01, 0x56,
- 0xFF, 0x2C, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF,
- 0xE6, 0x01, 0x3E, 0xFC, 0xD3, 0x06, 0x56, 0xF3, 0xBA, 0x20, 0x61,
- 0x3D, 0x56, 0xF3, 0x45, 0x05, 0xB7, 0xFD, 0xDE, 0x00, 0xC5, 0xFF,
- 0x05, 0x00, 0x02, 0x00, 0x09, 0x00, 0xDB, 0xFF, 0x34, 0x00, 0xFE,
- 0xFF, 0x3D, 0xFF, 0xC9, 0x02, 0x64, 0xF7, 0x2F, 0x44, 0x44, 0x15,
- 0x4A, 0xF6, 0xAD, 0x05, 0xAF, 0xFC, 0xC0, 0x01, 0x41, 0xFF, 0x32,
- 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD3, 0x01,
- 0x7D, 0xFC, 0x23, 0x06, 0x32, 0xF5, 0x0C, 0x19, 0x38, 0x42, 0xC7,
- 0xF5, 0xB8, 0x03, 0xAF, 0xFE, 0x4E, 0x00, 0x0C, 0x00, 0xEA, 0xFF,
- 0x06, 0x00, 0x04, 0x00, 0xF8, 0xFF, 0xE7, 0xFF, 0x99, 0x00, 0x2C,
- 0xFE, 0x8C, 0x04, 0x6D, 0xF4, 0xF0, 0x3F, 0xE0, 0x1C, 0x34, 0xF4,
- 0x85, 0x06, 0x57, 0xFC, 0xE0, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE,
- 0xFF, 0xFF, 0xFF, 0x2F, 0x00, 0x4A, 0xFF, 0xA7, 0x01, 0xEC, 0xFC,
- 0x28, 0x05, 0x77, 0xF7, 0x92, 0x11, 0xD7, 0x45, 0x43, 0xF9, 0xC3,
- 0x01, 0xD6, 0xFF, 0xA9, 0xFF, 0x5E, 0x00, 0xCB, 0xFF, 0x0D, 0x00,
- 0x00, 0x00, 0x10, 0x00, 0xA6, 0xFF, 0x1B, 0x01, 0x50, 0xFD, 0xE1,
- 0x05, 0x82, 0xF2, 0x8F, 0x3A, 0x92, 0x24, 0x9D, 0xF2, 0x09, 0x07,
- 0x32, 0xFC, 0xE4, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00,
- 0x00, 0x28, 0x00, 0x63, 0xFF, 0x66, 0x01, 0x7D, 0xFD, 0xF8, 0x03,
- 0xFB, 0xF9, 0x89, 0x0A, 0x1D, 0x48, 0xC5, 0xFD, 0x7A, 0xFF, 0x1D,
- 0x01, 0xF7, 0xFE, 0xB4, 0x00, 0xA9, 0xFF, 0x15, 0x00, 0xFE, 0xFF,
- 0x23, 0x00, 0x72, 0xFF, 0x7F, 0x01, 0xB0, 0xFC, 0xBE, 0x06, 0x97,
- 0xF1, 0x3F, 0x34, 0x19, 0x2C, 0xAD, 0xF1, 0x28, 0x07, 0x48, 0xFC,
- 0xC9, 0x01, 0x4B, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x1F,
- 0x00, 0x82, 0xFF, 0x18, 0x01, 0x27, 0xFE, 0xA9, 0x02, 0x94, 0xFC,
- 0x24, 0x04, 0xF5, 0x48, 0x39, 0x03, 0xF9, 0xFC, 0x74, 0x02, 0x42,
- 0xFE, 0x0B, 0x01, 0x87, 0xFF, 0x1E, 0x00, 0xFD, 0xFF, 0x2F, 0x00,
- 0x4F, 0xFF, 0xC2, 0x01, 0x51, 0xFC, 0x23, 0x07, 0x9A, 0xF1, 0x3A,
- 0x2D, 0x35, 0x33, 0x89, 0xF1, 0xD5, 0x06, 0x9D, 0xFC, 0x8B, 0x01,
- 0x6C, 0xFF, 0x25, 0x00, 0xFD, 0xFF, 0x16, 0x00, 0xA4, 0xFF, 0xC2,
- 0x00, 0xDB, 0xFE, 0x52, 0x01, 0x1B, 0xFF, 0x8D, 0xFE, 0x57, 0x48,
- 0x81, 0x09, 0x61, 0xFA, 0xC6, 0x03, 0x96, 0xFD, 0x5B, 0x01, 0x68,
- 0xFF, 0x26, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3B, 0xFF,
- 0xE2, 0x01, 0x31, 0xFC, 0x15, 0x07, 0x6D, 0xF2, 0xBF, 0x25, 0xA5,
- 0x39, 0x4D, 0xF2, 0x0B, 0x06, 0x33, 0xFD, 0x2D, 0x01, 0x9D, 0xFF,
- 0x13, 0x00, 0xFF, 0xFF, 0x0E, 0x00, 0xC6, 0xFF, 0x6B, 0x00, 0x8E,
- 0xFF, 0x06, 0x00, 0x6E, 0x01, 0xE4, 0xF9, 0x48, 0x46, 0x75, 0x10,
- 0xD7, 0xF7, 0xFC, 0x04, 0x00, 0xFD, 0x9E, 0x01, 0x4E, 0xFF, 0x2E,
- 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE3, 0x01,
- 0x4E, 0xFC, 0xA0, 0x06, 0xED, 0xF3, 0x0F, 0x1E, 0x2D, 0x3F, 0x10,
- 0xF4, 0xC8, 0x04, 0x07, 0xFE, 0xAF, 0x00, 0xDC, 0xFF, 0xFC, 0xFF,
- 0x03, 0x00, 0x07, 0x00, 0xE5, 0xFF, 0x18, 0x00, 0x36, 0x00, 0xD9,
- 0xFE, 0x71, 0x03, 0x3F, 0xF6, 0xDB, 0x42, 0xE0, 0x17, 0x86, 0xF5,
- 0x00, 0x06, 0x8C, 0xFC, 0xCE, 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE,
- 0xFF, 0xFF, 0xFF, 0x33, 0x00, 0x3F, 0xFF, 0xC6, 0x01, 0x9F, 0xFC,
- 0xD3, 0x05, 0xF1, 0xF5, 0x6C, 0x16, 0x9E, 0x43, 0xDD, 0xF6, 0x15,
- 0x03, 0x10, 0xFF, 0x17, 0x00, 0x28, 0x00, 0xDF, 0xFF, 0x09, 0x00,
- 0x02, 0x00, 0x01, 0x00, 0xCF, 0xFF, 0xC9, 0x00, 0xDA, 0xFD, 0x0F,
- 0x05, 0xA5, 0xF3, 0x31, 0x3E, 0x8A, 0x1F, 0x97, 0xF3, 0xBD, 0x06,
- 0x44, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF,
- 0xFF, 0x2D, 0x00, 0x52, 0xFF, 0x92, 0x01, 0x1B, 0xFD, 0xC4, 0x04,
- 0x51, 0xF8, 0x13, 0x0F, 0xC8, 0x46, 0xB6, 0xFA, 0x01, 0x01, 0x44,
- 0x00, 0x6C, 0xFF, 0x7B, 0x00, 0xBF, 0xFF, 0x10, 0x00, 0xFF, 0xFF,
- 0x17, 0x00, 0x92, 0xFF, 0x41, 0x01, 0x11, 0xFD, 0x3B, 0x06, 0x14,
- 0xF2, 0x78, 0x38, 0x36, 0x27, 0x35, 0xF2, 0x20, 0x07, 0x33, 0xFC,
- 0xDF, 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x25,
- 0x00, 0x6D, 0xFF, 0x4C, 0x01, 0xB6, 0xFD, 0x86, 0x03, 0xE1, 0xFA,
- 0x3D, 0x08, 0x92, 0x48, 0x8E, 0xFF, 0xA1, 0xFE, 0x93, 0x01, 0xB8,
- 0xFE, 0xD3, 0x00, 0x9D, 0xFF, 0x18, 0x00, 0xFD, 0xFF, 0x28, 0x00,
- 0x64, 0xFF, 0x9A, 0x01, 0x88, 0xFC, 0xEE, 0x06, 0x7E, 0xF1, 0xE3,
- 0x31, 0x9F, 0x2E, 0x88, 0xF1, 0x19, 0x07, 0x5E, 0xFC, 0xB7, 0x01,
- 0x54, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, 0x1C, 0x00, 0x8D, 0xFF, 0xFA,
- 0x00, 0x64, 0xFE, 0x32, 0x02, 0x78, 0xFD, 0x1B, 0x02, 0xEA, 0x48,
- 0x50, 0x05, 0x14, 0xFC, 0xEB, 0x02, 0x05, 0xFE, 0x27, 0x01, 0x7C,
- 0xFF, 0x21, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x46, 0xFF,
- 0xD1, 0x01, 0x3F, 0xFC, 0x2B, 0x07, 0xCD, 0xF1, 0xAE, 0x2A, 0x86,
- 0x35, 0xB1, 0xF1, 0x9D, 0x06, 0xCA, 0xFC, 0x6E, 0x01, 0x7B, 0xFF,
- 0x20, 0x00, 0xFE, 0xFF, 0x13, 0x00, 0xAF, 0xFF, 0xA4, 0x00, 0x19,
- 0xFF, 0xDD, 0x00, 0xF0, 0xFF, 0xD4, 0xFC, 0xC9, 0x47, 0xD8, 0x0B,
- 0x7C, 0xF9, 0x35, 0x04, 0x5F, 0xFD, 0x74, 0x01, 0x5E, 0xFF, 0x29,
- 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE6, 0x01,
- 0x35, 0xFC, 0xF7, 0x06, 0xE0, 0xF2, 0x18, 0x23, 0xAB, 0x3B, 0xCC,
- 0xF2, 0xA8, 0x05, 0x76, 0xFD, 0x04, 0x01, 0xB1, 0xFF, 0x0C, 0x00,
- 0x00, 0x00, 0x0C, 0x00, 0xD1, 0xFF, 0x4E, 0x00, 0xCA, 0xFF, 0x9A,
- 0xFF, 0x2A, 0x02, 0x83, 0xF8, 0x3F, 0x45, 0xFB, 0x12, 0x01, 0xF7,
- 0x5D, 0x05, 0xD3, 0xFC, 0xB1, 0x01, 0x46, 0xFF, 0x31, 0x00, 0xFF,
- 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xDC, 0x01, 0x64, 0xFC,
- 0x62, 0x06, 0x93, 0xF4, 0x66, 0x1B, 0xD9, 0x40, 0xEA, 0xF4, 0x3E,
- 0x04, 0x5D, 0xFE, 0x7D, 0x00, 0xF5, 0xFF, 0xF3, 0xFF, 0x05, 0x00,
- 0x05, 0x00, 0xEF, 0xFF, 0xFE, 0xFF, 0x6C, 0x00, 0x7B, 0xFE, 0x0C,
- 0x04, 0x3A, 0xF5, 0x5F, 0x41, 0x83, 0x1A, 0xCD, 0xF4, 0x4B, 0x06,
- 0x6D, 0xFC, 0xD9, 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0xFF,
- 0xFF, 0x31, 0x00, 0x44, 0xFF, 0xB7, 0x01, 0xC5, 0xFC, 0x7C, 0x05,
- 0xBC, 0xF6, 0xD5, 0x13, 0xDC, 0x44, 0x14, 0xF8, 0x67, 0x02, 0x77,
- 0xFF, 0xDD, 0xFF, 0x44, 0x00, 0xD5, 0xFF, 0x0B, 0x00, 0x01, 0x00,
- 0x09, 0x00, 0xB8, 0xFF, 0xF6, 0x00, 0x8D, 0xFD, 0x84, 0x05, 0xFD,
- 0xF2, 0x52, 0x3C, 0x35, 0x22, 0x0B, 0xF3, 0xEB, 0x06, 0x37, 0xFC,
- 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x2A,
- 0x00, 0x5B, 0xFF, 0x7C, 0x01, 0x4E, 0xFD, 0x5A, 0x04, 0x31, 0xF9,
- 0xA4, 0x0C, 0x90, 0x47, 0x47, 0xFC, 0x36, 0x00, 0xB6, 0x00, 0x2E,
- 0xFF, 0x99, 0x00, 0xB3, 0xFF, 0x12, 0x00, 0xFE, 0xFF, 0x1E, 0x00,
- 0x80, 0xFF, 0x64, 0x01, 0xDA, 0xFC, 0x87, 0x06, 0xC5, 0xF1, 0x46,
- 0x36, 0xD1, 0x29, 0xE3, 0xF1, 0x2A, 0x07, 0x3A, 0xFC, 0xD5, 0x01,
- 0x44, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x22, 0x00, 0x78,
- 0xFF, 0x31, 0x01, 0xF1, 0xFD, 0x12, 0x03, 0xC7, 0xFB, 0x07, 0x06,
- 0xDB, 0x48, 0x73, 0x01, 0xC3, 0xFD, 0x0A, 0x02, 0x79, 0xFE, 0xF1,
- 0x00, 0x91, 0xFF, 0x1B, 0x00, 0xFD, 0xFF, 0x2C, 0x00, 0x58, 0xFF,
- 0xB1, 0x01, 0x67, 0xFC, 0x10, 0x07, 0x81, 0xF1, 0x73, 0x2F, 0x15,
- 0x31, 0x7C, 0xF1, 0xFB, 0x06, 0x7C, 0xFC, 0xA2, 0x01, 0x60, 0xFF,
- 0x29, 0x00, 0xFD, 0xFF, 0x19, 0x00, 0x99, 0xFF, 0xDD, 0x00, 0xA3,
- 0xFE, 0xBB, 0x01, 0x58, 0xFE, 0x2D, 0x00, 0xAF, 0x48, 0x7E, 0x07,
- 0x2E, 0xFB, 0x60, 0x03, 0xC9, 0xFD, 0x43, 0x01, 0x71, 0xFF, 0x24,
- 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x34, 0x00, 0x3F, 0xFF, 0xDC, 0x01,
- 0x34, 0xFC, 0x25, 0x07, 0x18, 0xF2, 0x15, 0x28, 0xBF, 0x37, 0xF7,
- 0xF1, 0x56, 0x06, 0xFE, 0xFC, 0x4D, 0x01, 0x8C, 0xFF, 0x19, 0x00,
- 0xFF, 0xFF, 0x10, 0x00, 0xBB, 0xFF, 0x85, 0x00, 0x58, 0xFF, 0x6A,
- 0x00, 0xBE, 0x00, 0x38, 0xFB, 0x0F, 0x47, 0x42, 0x0E, 0x9B, 0xF8,
- 0xA1, 0x04, 0x2B, 0xFD, 0x8B, 0x01, 0x55, 0xFF, 0x2C, 0x00, 0xFF,
- 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3F, 0xFC,
- 0xCE, 0x06, 0x66, 0xF3, 0x6F, 0x20, 0x96, 0x3D, 0x69, 0xF3, 0x38,
- 0x05, 0xBF, 0xFD, 0xD9, 0x00, 0xC7, 0xFF, 0x04, 0x00, 0x02, 0x00,
- 0x09, 0x00, 0xDC, 0xFF, 0x31, 0x00, 0x04, 0x00, 0x32, 0xFF, 0xDC,
- 0x02, 0x42, 0xF7, 0x0B, 0x44, 0x8E, 0x15, 0x34, 0xF6, 0xB7, 0x05,
- 0xAB, 0xFC, 0xC1, 0x01, 0x40, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0xFE,
- 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xD2, 0x01, 0x81, 0xFC, 0x1A, 0x06,
- 0x47, 0xF5, 0xC1, 0x18, 0x60, 0x42, 0xE4, 0xF5, 0xA6, 0x03, 0xB9,
- 0xFE, 0x48, 0x00, 0x0F, 0x00, 0xE9, 0xFF, 0x07, 0x00, 0x04, 0x00,
- 0xF9, 0xFF, 0xE4, 0xFF, 0x9F, 0x00, 0x23, 0xFE, 0x9B, 0x04, 0x55,
- 0xF4, 0xC0, 0x3F, 0x2C, 0x1D, 0x22, 0xF4, 0x8C, 0x06, 0x55, 0xFC,
- 0xE1, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x2F,
- 0x00, 0x4B, 0xFF, 0xA4, 0x01, 0xF1, 0xFC, 0x1D, 0x05, 0x8F, 0xF7,
- 0x4A, 0x11, 0xF2, 0x45, 0x6B, 0xF9, 0xAE, 0x01, 0xE2, 0xFF, 0xA2,
- 0xFF, 0x61, 0x00, 0xC9, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00,
- 0xA3, 0xFF, 0x20, 0x01, 0x49, 0xFD, 0xEB, 0x05, 0x74, 0xF2, 0x54,
- 0x3A, 0xDD, 0x24, 0x91, 0xF2, 0x0C, 0x07, 0x32, 0xFC, 0xE4, 0x01,
- 0x3A, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x64,
- 0xFF, 0x63, 0x01, 0x84, 0xFD, 0xEB, 0x03, 0x14, 0xFA, 0x47, 0x0A,
- 0x2C, 0x48, 0xF6, 0xFD, 0x63, 0xFF, 0x2B, 0x01, 0xF0, 0xFE, 0xB8,
- 0x00, 0xA8, 0xFF, 0x15, 0x00, 0xFE, 0xFF, 0x23, 0x00, 0x71, 0xFF,
- 0x82, 0x01, 0xAB, 0xFC, 0xC4, 0x06, 0x93, 0xF1, 0xFD, 0x33, 0x62,
- 0x2C, 0xA8, 0xF1, 0x27, 0x07, 0x4A, 0xFC, 0xC7, 0x01, 0x4C, 0xFF,
- 0x30, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x83, 0xFF, 0x14,
- 0x01, 0x2D, 0xFE, 0x9C, 0x02, 0xAD, 0xFC, 0xE9, 0x03, 0xF6, 0x48,
- 0x73, 0x03, 0xE0, 0xFC, 0x82, 0x02, 0x3B, 0xFE, 0x0E, 0x01, 0x86,
- 0xFF, 0x1E, 0x00, 0xFD, 0xFF, 0x2F, 0x00, 0x4E, 0xFF, 0xC3, 0x01,
- 0x4E, 0xFC, 0x24, 0x07, 0x9E, 0xF1, 0xF2, 0x2C, 0x78, 0x33, 0x8C,
- 0xF1, 0xD0, 0x06, 0xA2, 0xFC, 0x88, 0x01, 0x6D, 0xFF, 0x24, 0x00,
- 0xFD, 0xFF, 0x16, 0x00, 0xA5, 0xFF, 0xBE, 0x00, 0xE2, 0xFE, 0x45,
- 0x01, 0x33, 0xFF, 0x5A, 0xFE, 0x48, 0x48, 0xC3, 0x09, 0x47, 0xFA,
- 0xD2, 0x03, 0x90, 0xFD, 0x5E, 0x01, 0x66, 0xFF, 0x27, 0x00, 0x00,
- 0x00, 0xFD, 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xE3, 0x01, 0x31, 0xFC,
- 0x12, 0x07, 0x79, 0xF2, 0x73, 0x25, 0xDF, 0x39, 0x5A, 0xF2, 0x00,
- 0x06, 0x3A, 0xFD, 0x28, 0x01, 0x9F, 0xFF, 0x13, 0x00, 0x00, 0x00,
- 0x0E, 0x00, 0xC7, 0xFF, 0x68, 0x00, 0x95, 0xFF, 0xFA, 0xFF, 0x83,
- 0x01, 0xBB, 0xF9, 0x2B, 0x46, 0xBB, 0x10, 0xBF, 0xF7, 0x07, 0x05,
- 0xFB, 0xFC, 0xA0, 0x01, 0x4D, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0xFE,
- 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE2, 0x01, 0x50, 0xFC, 0x99, 0x06,
- 0xFE, 0xF3, 0xC3, 0x1D, 0x5E, 0x3F, 0x27, 0xF4, 0xB9, 0x04, 0x10,
- 0xFE, 0xA9, 0x00, 0xDF, 0xFF, 0xFB, 0xFF, 0x03, 0x00, 0x07, 0x00,
- 0xE6, 0xFF, 0x15, 0x00, 0x3C, 0x00, 0xCF, 0xFE, 0x83, 0x03, 0x20,
- 0xF6, 0xB2, 0x42, 0x2B, 0x18, 0x71, 0xF5, 0x09, 0x06, 0x88, 0xFC,
- 0xCF, 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x33,
- 0x00, 0x3F, 0xFF, 0xC5, 0x01, 0xA3, 0xFC, 0xCA, 0x05, 0x07, 0xF6,
- 0x22, 0x16, 0xC3, 0x43, 0xFE, 0xF6, 0x02, 0x03, 0x1B, 0xFF, 0x11,
- 0x00, 0x2B, 0x00, 0xDE, 0xFF, 0x09, 0x00, 0x02, 0x00, 0x02, 0x00,
- 0xCC, 0xFF, 0xCE, 0x00, 0xD1, 0xFD, 0x1D, 0x05, 0x91, 0xF3, 0xFE,
- 0x3D, 0xD7, 0x1F, 0x87, 0xF3, 0xC3, 0x06, 0x42, 0xFC, 0xE5, 0x01,
- 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x2D, 0x00, 0x53,
- 0xFF, 0x90, 0x01, 0x20, 0xFD, 0xB8, 0x04, 0x6A, 0xF8, 0xCD, 0x0E,
- 0xE1, 0x46, 0xE1, 0xFA, 0xEB, 0x00, 0x51, 0x00, 0x65, 0xFF, 0x7F,
- 0x00, 0xBE, 0xFF, 0x10, 0x00, 0xFF, 0xFF, 0x18, 0x00, 0x90, 0xFF,
- 0x45, 0x01, 0x0B, 0xFD, 0x44, 0x06, 0x0A, 0xF2, 0x3B, 0x38, 0x80,
- 0x27, 0x2B, 0xF2, 0x22, 0x07, 0x33, 0xFC, 0xDE, 0x01, 0x3E, 0xFF,
- 0x34, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x24, 0x00, 0x6E, 0xFF, 0x49,
- 0x01, 0xBC, 0xFD, 0x7A, 0x03, 0xFA, 0xFA, 0xFD, 0x07, 0x9C, 0x48,
- 0xC3, 0xFF, 0x89, 0xFE, 0xA1, 0x01, 0xB1, 0xFE, 0xD6, 0x00, 0x9C,
- 0xFF, 0x18, 0x00, 0xFD, 0xFF, 0x28, 0x00, 0x63, 0xFF, 0x9D, 0x01,
- 0x84, 0xFC, 0xF3, 0x06, 0x7D, 0xF1, 0x9E, 0x31, 0xE6, 0x2E, 0x85,
- 0xF1, 0x16, 0x07, 0x61, 0xFC, 0xB5, 0x01, 0x55, 0xFF, 0x2D, 0x00,
- 0xFD, 0xFF, 0x1C, 0x00, 0x8F, 0xFF, 0xF7, 0x00, 0x6B, 0xFE, 0x25,
- 0x02, 0x91, 0xFD, 0xE3, 0x01, 0xE5, 0x48, 0x8D, 0x05, 0xFB, 0xFB,
- 0xF8, 0x02, 0xFE, 0xFD, 0x2B, 0x01, 0x7A, 0xFF, 0x21, 0x00, 0x00,
- 0x00, 0xFD, 0xFF, 0x32, 0x00, 0x45, 0xFF, 0xD2, 0x01, 0x3D, 0xFC,
- 0x2B, 0x07, 0xD4, 0xF1, 0x64, 0x2A, 0xC6, 0x35, 0xB7, 0xF1, 0x96,
- 0x06, 0xCF, 0xFC, 0x6B, 0x01, 0x7D, 0xFF, 0x1F, 0x00, 0xFE, 0xFF,
- 0x13, 0x00, 0xB1, 0xFF, 0xA0, 0x00, 0x20, 0xFF, 0xD0, 0x00, 0x07,
- 0x00, 0xA4, 0xFC, 0xB6, 0x47, 0x1C, 0x0C, 0x63, 0xF9, 0x42, 0x04,
- 0x59, 0xFD, 0x76, 0x01, 0x5D, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0xFD,
- 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x35, 0xFC, 0xF3, 0x06,
- 0xEE, 0xF2, 0xCD, 0x22, 0xE4, 0x3B, 0xDC, 0xF2, 0x9C, 0x05, 0x7E,
- 0xFD, 0x00, 0x01, 0xB4, 0xFF, 0x0B, 0x00, 0x01, 0x00, 0x0B, 0x00,
- 0xD2, 0xFF, 0x4A, 0x00, 0xD0, 0xFF, 0x8E, 0xFF, 0x3F, 0x02, 0x5E,
- 0xF8, 0x1E, 0x45, 0x44, 0x13, 0xEA, 0xF6, 0x67, 0x05, 0xCF, 0xFC,
- 0xB3, 0x01, 0x46, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x36,
- 0x00, 0x38, 0xFF, 0xDB, 0x01, 0x67, 0xFC, 0x5A, 0x06, 0xA6, 0xF4,
- 0x1B, 0x1B, 0x07, 0x41, 0x04, 0xF5, 0x2D, 0x04, 0x67, 0xFE, 0x77,
- 0x00, 0xF8, 0xFF, 0xF2, 0xFF, 0x05, 0x00, 0x05, 0x00, 0xF0, 0xFF,
- 0xFB, 0xFF, 0x71, 0x00, 0x71, 0xFE, 0x1D, 0x04, 0x1F, 0xF5, 0x32,
- 0x41, 0xCE, 0x1A, 0xBA, 0xF4, 0x53, 0x06, 0x6A, 0xFC, 0xDA, 0x01,
- 0x38, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x31, 0x00, 0x45,
- 0xFF, 0xB5, 0x01, 0xCA, 0xFC, 0x72, 0x05, 0xD3, 0xF6, 0x8D, 0x13,
- 0xFD, 0x44, 0x39, 0xF8, 0x53, 0x02, 0x82, 0xFF, 0xD7, 0xFF, 0x47,
- 0x00, 0xD3, 0xFF, 0x0B, 0x00, 0x01, 0x00, 0x0A, 0x00, 0xB6, 0xFF,
- 0xFB, 0x00, 0x85, 0xFD, 0x90, 0x05, 0xEC, 0xF2, 0x1C, 0x3C, 0x81,
- 0x22, 0xFC, 0xF2, 0xEF, 0x06, 0x36, 0xFC, 0xE6, 0x01, 0x37, 0xFF,
- 0x36, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x2A, 0x00, 0x5C, 0xFF, 0x79,
- 0x01, 0x53, 0xFD, 0x4E, 0x04, 0x4A, 0xF9, 0x60, 0x0C, 0xA3, 0x47,
- 0x76, 0xFC, 0x1F, 0x00, 0xC3, 0x00, 0x27, 0xFF, 0x9D, 0x00, 0xB2,
- 0xFF, 0x13, 0x00, 0xFE, 0xFF, 0x1E, 0x00, 0x7F, 0xFF, 0x67, 0x01,
- 0xD5, 0xFC, 0x8E, 0x06, 0xBE, 0xF1, 0x06, 0x36, 0x1A, 0x2A, 0xDC,
- 0xF1, 0x2A, 0x07, 0x3C, 0xFC, 0xD3, 0x01, 0x44, 0xFF, 0x32, 0x00,
- 0xFD, 0xFF, 0x00, 0x00, 0x21, 0x00, 0x79, 0xFF, 0x2E, 0x01, 0xF7,
- 0xFD, 0x05, 0x03, 0xE1, 0xFB, 0xCA, 0x05, 0xDF, 0x48, 0xAB, 0x01,
- 0xAA, 0xFD, 0x18, 0x02, 0x72, 0xFE, 0xF4, 0x00, 0x90, 0xFF, 0x1B,
- 0x00, 0xFD, 0xFF, 0x2C, 0x00, 0x57, 0xFF, 0xB3, 0x01, 0x64, 0xFC,
- 0x13, 0x07, 0x83, 0xF1, 0x2C, 0x2F, 0x5A, 0x31, 0x7D, 0xF1, 0xF7,
- 0x06, 0x80, 0xFC, 0x9F, 0x01, 0x61, 0xFF, 0x29, 0x00, 0xFD, 0xFF,
- 0x19, 0x00, 0x9A, 0xFF, 0xD9, 0x00, 0xAA, 0xFE, 0xAE, 0x01, 0x70,
- 0xFE, 0xF8, 0xFF, 0xA6, 0x48, 0xBE, 0x07, 0x14, 0xFB, 0x6D, 0x03,
- 0xC3, 0xFD, 0x46, 0x01, 0x70, 0xFF, 0x24, 0x00, 0x00, 0x00, 0xFD,
- 0xFF, 0x34, 0x00, 0x3F, 0xFF, 0xDD, 0x01, 0x34, 0xFC, 0x23, 0x07,
- 0x21, 0xF2, 0xCB, 0x27, 0xFE, 0x37, 0x00, 0xF2, 0x4D, 0x06, 0x04,
- 0xFD, 0x49, 0x01, 0x8E, 0xFF, 0x19, 0x00, 0xFF, 0xFF, 0x10, 0x00,
- 0xBD, 0xFF, 0x82, 0x00, 0x5E, 0xFF, 0x5D, 0x00, 0xD4, 0x00, 0x0C,
- 0xFB, 0xF9, 0x46, 0x87, 0x0E, 0x82, 0xF8, 0xAD, 0x04, 0x26, 0xFD,
- 0x8D, 0x01, 0x54, 0xFF, 0x2C, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36,
- 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x41, 0xFC, 0xC8, 0x06, 0x76, 0xF3,
- 0x22, 0x20, 0xCA, 0x3D, 0x7D, 0xF3, 0x2A, 0x05, 0xC8, 0xFD, 0xD4,
- 0x00, 0xCA, 0xFF, 0x03, 0x00, 0x02, 0x00, 0x09, 0x00, 0xDD, 0xFF,
- 0x2E, 0x00, 0x0A, 0x00, 0x27, 0xFF, 0xEF, 0x02, 0x20, 0xF7, 0xE7,
- 0x43, 0xD8, 0x15, 0x1E, 0xF6, 0xC0, 0x05, 0xA7, 0xFC, 0xC3, 0x01,
- 0x40, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0x34, 0x00, 0x3B,
- 0xFF, 0xD1, 0x01, 0x84, 0xFC, 0x12, 0x06, 0x5C, 0xF5, 0x76, 0x18,
- 0x89, 0x42, 0x02, 0xF6, 0x94, 0x03, 0xC4, 0xFE, 0x42, 0x00, 0x12,
- 0x00, 0xE8, 0xFF, 0x07, 0x00, 0x03, 0x00, 0xFA, 0xFF, 0xE2, 0xFF,
- 0xA4, 0x00, 0x19, 0xFE, 0xAA, 0x04, 0x3E, 0xF4, 0x90, 0x3F, 0x78,
- 0x1D, 0x10, 0xF4, 0x93, 0x06, 0x52, 0xFC, 0xE1, 0x01, 0x36, 0xFF,
- 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x2F, 0x00, 0x4C, 0xFF, 0xA2,
- 0x01, 0xF6, 0xFC, 0x12, 0x05, 0xA7, 0xF7, 0x03, 0x11, 0x10, 0x46,
- 0x93, 0xF9, 0x98, 0x01, 0xEE, 0xFF, 0x9B, 0xFF, 0x64, 0x00, 0xC8,
- 0xFF, 0x0E, 0x00, 0x00, 0x00, 0x12, 0x00, 0xA1, 0xFF, 0x24, 0x01,
- 0x41, 0xFD, 0xF6, 0x05, 0x67, 0xF2, 0x1A, 0x3A, 0x29, 0x25, 0x84,
- 0xF2, 0x0F, 0x07, 0x31, 0xFC, 0xE3, 0x01, 0x3A, 0xFF, 0x35, 0x00,
- 0xFD, 0xFF, 0x00, 0x00, 0x27, 0x00, 0x65, 0xFF, 0x60, 0x01, 0x8A,
- 0xFD, 0xDF, 0x03, 0x2E, 0xFA, 0x04, 0x0A, 0x3A, 0x48, 0x28, 0xFE,
- 0x4B, 0xFF, 0x38, 0x01, 0xE9, 0xFE, 0xBB, 0x00, 0xA6, 0xFF, 0x16,
- 0x00, 0xFD, 0xFF, 0x24, 0x00, 0x6F, 0xFF, 0x85, 0x01, 0xA6, 0xFC,
- 0xCA, 0x06, 0x8F, 0xF1, 0xBB, 0x33, 0xAB, 0x2C, 0xA3, 0xF1, 0x26,
- 0x07, 0x4C, 0xFC, 0xC5, 0x01, 0x4D, 0xFF, 0x30, 0x00, 0xFD, 0xFF,
- 0x00, 0x00, 0x1E, 0x00, 0x84, 0xFF, 0x11, 0x01, 0x34, 0xFE, 0x8F,
- 0x02, 0xC7, 0xFC, 0xAE, 0x03, 0xF7, 0x48, 0xAE, 0x03, 0xC7, 0xFC,
- 0x8F, 0x02, 0x34, 0xFE, 0x11, 0x01, 0x84, 0xFF, 0x1E, 0x00, 0xFD,
- 0xFF, 0x2A, 0x00, 0x5C, 0xFF, 0xAA, 0x01, 0x71, 0xFC, 0x07, 0x07,
- 0x7E, 0xF1, 0x44, 0x30, 0x44, 0x30, 0x7E, 0xF1, 0x07, 0x07, 0x71,
- 0xFC, 0xAA, 0x01, 0x5C, 0xFF, 0x2A, 0x00, 0xFD, 0xFF, 0x00, 0x00,
- 0x1E, 0x00, 0x84, 0xFF, 0x11, 0x01, 0x34, 0xFE, 0x8F, 0x02, 0xC7,
- 0xFC, 0xAE, 0x03, 0xF7, 0x48, 0xAE, 0x03, 0xC7, 0xFC, 0x8F, 0x02,
- 0x34, 0xFE, 0x11, 0x01, 0x84, 0xFF, 0x1E, 0x00, 0x02, 0x00, 0x05,
- 0x00, 0xC3, 0xFF, 0xE1, 0x00, 0xB1, 0xFD, 0x4E, 0x05, 0x4A, 0xF3,
- 0x3D, 0x3D, 0xED, 0x20, 0x4C, 0xF3, 0xD6, 0x06, 0x3D, 0xFC, 0xE6,
- 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x36, 0x00,
- 0x36, 0xFF, 0xE6, 0x01, 0x3D, 0xFC, 0xD6, 0x06, 0x4C, 0xF3, 0xED,
- 0x20, 0x3D, 0x3D, 0x4A, 0xF3, 0x4E, 0x05, 0xB1, 0xFD, 0xE1, 0x00,
- 0xC3, 0xFF, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x84,
- 0xFF, 0x11, 0x01, 0x34, 0xFE, 0x8F, 0x02, 0xC7, 0xFC, 0xAE, 0x03,
- 0xF7, 0x48, 0xAE, 0x03, 0xC7, 0xFC, 0x8F, 0x02, 0x34, 0xFE, 0x11,
- 0x01, 0x84, 0xFF, 0x1E, 0x00, 0x16, 0x00, 0xA6, 0xFF, 0xBB, 0x00,
- 0xE9, 0xFE, 0x38, 0x01, 0x4B, 0xFF, 0x28, 0xFE, 0x3A, 0x48, 0x04,
- 0x0A, 0x2E, 0xFA, 0xDF, 0x03, 0x8A, 0xFD, 0x60, 0x01, 0x65, 0xFF,
- 0x27, 0x00, 0x00, 0x00, 0x0E, 0x00, 0xC8, 0xFF, 0x64, 0x00, 0x9B,
- 0xFF, 0xEE, 0xFF, 0x98, 0x01, 0x93, 0xF9, 0x10, 0x46, 0x03, 0x11,
- 0xA7, 0xF7, 0x12, 0x05, 0xF6, 0xFC, 0xA2, 0x01, 0x4C, 0xFF, 0x2F,
- 0x00, 0xFF, 0xFF, 0x07, 0x00, 0xE8, 0xFF, 0x12, 0x00, 0x42, 0x00,
- 0xC4, 0xFE, 0x94, 0x03, 0x02, 0xF6, 0x89, 0x42, 0x76, 0x18, 0x5C,
- 0xF5, 0x12, 0x06, 0x84, 0xFC, 0xD1, 0x01, 0x3B, 0xFF, 0x34, 0x00,
- 0xFE, 0xFF, 0x02, 0x00, 0x03, 0x00, 0xCA, 0xFF, 0xD4, 0x00, 0xC8,
- 0xFD, 0x2A, 0x05, 0x7D, 0xF3, 0xCA, 0x3D, 0x22, 0x20, 0x76, 0xF3,
- 0xC8, 0x06, 0x41, 0xFC, 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD,
- 0xFF, 0xFF, 0xFF, 0x19, 0x00, 0x8E, 0xFF, 0x49, 0x01, 0x04, 0xFD,
- 0x4D, 0x06, 0x00, 0xF2, 0xFE, 0x37, 0xCB, 0x27, 0x21, 0xF2, 0x23,
- 0x07, 0x34, 0xFC, 0xDD, 0x01, 0x3F, 0xFF, 0x34, 0x00, 0xFD, 0xFF,
- 0xFD, 0xFF, 0x29, 0x00, 0x61, 0xFF, 0x9F, 0x01, 0x80, 0xFC, 0xF7,
- 0x06, 0x7D, 0xF1, 0x5A, 0x31, 0x2C, 0x2F, 0x83, 0xF1, 0x13, 0x07,
- 0x64, 0xFC, 0xB3, 0x01, 0x57, 0xFF, 0x2C, 0x00, 0xFD, 0xFF, 0xFD,
- 0xFF, 0x32, 0x00, 0x44, 0xFF, 0xD3, 0x01, 0x3C, 0xFC, 0x2A, 0x07,
- 0xDC, 0xF1, 0x1A, 0x2A, 0x06, 0x36, 0xBE, 0xF1, 0x8E, 0x06, 0xD5,
- 0xFC, 0x67, 0x01, 0x7F, 0xFF, 0x1E, 0x00, 0xFE, 0xFF, 0xFD, 0xFF,
- 0x36, 0x00, 0x37, 0xFF, 0xE6, 0x01, 0x36, 0xFC, 0xEF, 0x06, 0xFC,
- 0xF2, 0x81, 0x22, 0x1C, 0x3C, 0xEC, 0xF2, 0x90, 0x05, 0x85, 0xFD,
- 0xFB, 0x00, 0xB6, 0xFF, 0x0A, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x35,
- 0x00, 0x38, 0xFF, 0xDA, 0x01, 0x6A, 0xFC, 0x53, 0x06, 0xBA, 0xF4,
- 0xCE, 0x1A, 0x32, 0x41, 0x1F, 0xF5, 0x1D, 0x04, 0x71, 0xFE, 0x71,
- 0x00, 0xFB, 0xFF, 0xF0, 0xFF, 0x05, 0x00, 0xFF, 0xFF, 0x31, 0x00,
- 0x46, 0xFF, 0xB3, 0x01, 0xCF, 0xFC, 0x67, 0x05, 0xEA, 0xF6, 0x44,
- 0x13, 0x1E, 0x45, 0x5E, 0xF8, 0x3F, 0x02, 0x8E, 0xFF, 0xD0, 0xFF,
- 0x4A, 0x00, 0xD2, 0xFF, 0x0B, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5D,
- 0xFF, 0x76, 0x01, 0x59, 0xFD, 0x42, 0x04, 0x63, 0xF9, 0x1C, 0x0C,
- 0xB6, 0x47, 0xA4, 0xFC, 0x07, 0x00, 0xD0, 0x00, 0x20, 0xFF, 0xA0,
- 0x00, 0xB1, 0xFF, 0x13, 0x00, 0x00, 0x00, 0x21, 0x00, 0x7A, 0xFF,
- 0x2B, 0x01, 0xFE, 0xFD, 0xF8, 0x02, 0xFB, 0xFB, 0x8D, 0x05, 0xE5,
- 0x48, 0xE3, 0x01, 0x91, 0xFD, 0x25, 0x02, 0x6B, 0xFE, 0xF7, 0x00,
- 0x8F, 0xFF, 0x1C, 0x00, 0x18, 0x00, 0x9C, 0xFF, 0xD6, 0x00, 0xB1,
- 0xFE, 0xA1, 0x01, 0x89, 0xFE, 0xC3, 0xFF, 0x9C, 0x48, 0xFD, 0x07,
- 0xFA, 0xFA, 0x7A, 0x03, 0xBC, 0xFD, 0x49, 0x01, 0x6E, 0xFF, 0x24,
- 0x00, 0x00, 0x00, 0x10, 0x00, 0xBE, 0xFF, 0x7F, 0x00, 0x65, 0xFF,
- 0x51, 0x00, 0xEB, 0x00, 0xE1, 0xFA, 0xE1, 0x46, 0xCD, 0x0E, 0x6A,
- 0xF8, 0xB8, 0x04, 0x20, 0xFD, 0x90, 0x01, 0x53, 0xFF, 0x2D, 0x00,
- 0xFF, 0xFF, 0x09, 0x00, 0xDE, 0xFF, 0x2B, 0x00, 0x11, 0x00, 0x1B,
- 0xFF, 0x02, 0x03, 0xFE, 0xF6, 0xC3, 0x43, 0x22, 0x16, 0x07, 0xF6,
- 0xCA, 0x05, 0xA3, 0xFC, 0xC5, 0x01, 0x3F, 0xFF, 0x33, 0x00, 0xFF,
- 0xFF, 0x03, 0x00, 0xFB, 0xFF, 0xDF, 0xFF, 0xA9, 0x00, 0x10, 0xFE,
- 0xB9, 0x04, 0x27, 0xF4, 0x5E, 0x3F, 0xC3, 0x1D, 0xFE, 0xF3, 0x99,
- 0x06, 0x50, 0xFC, 0xE2, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF,
- 0x00, 0x00, 0x13, 0x00, 0x9F, 0xFF, 0x28, 0x01, 0x3A, 0xFD, 0x00,
- 0x06, 0x5A, 0xF2, 0xDF, 0x39, 0x73, 0x25, 0x79, 0xF2, 0x12, 0x07,
- 0x31, 0xFC, 0xE3, 0x01, 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0xFD,
- 0xFF, 0x24, 0x00, 0x6D, 0xFF, 0x88, 0x01, 0xA2, 0xFC, 0xD0, 0x06,
- 0x8C, 0xF1, 0x78, 0x33, 0xF2, 0x2C, 0x9E, 0xF1, 0x24, 0x07, 0x4E,
- 0xFC, 0xC3, 0x01, 0x4E, 0xFF, 0x2F, 0x00, 0xFD, 0xFF, 0xFD, 0xFF,
- 0x30, 0x00, 0x4C, 0xFF, 0xC7, 0x01, 0x4A, 0xFC, 0x27, 0x07, 0xA8,
- 0xF1, 0x62, 0x2C, 0xFD, 0x33, 0x93, 0xF1, 0xC4, 0x06, 0xAB, 0xFC,
- 0x82, 0x01, 0x71, 0xFF, 0x23, 0x00, 0xFE, 0xFF, 0xFD, 0xFF, 0x36,
- 0x00, 0x3A, 0xFF, 0xE4, 0x01, 0x32, 0xFC, 0x0C, 0x07, 0x91, 0xF2,
- 0xDD, 0x24, 0x54, 0x3A, 0x74, 0xF2, 0xEB, 0x05, 0x49, 0xFD, 0x20,
- 0x01, 0xA3, 0xFF, 0x11, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x36, 0x00,
- 0x37, 0xFF, 0xE1, 0x01, 0x55, 0xFC, 0x8C, 0x06, 0x22, 0xF4, 0x2C,
- 0x1D, 0xC0, 0x3F, 0x55, 0xF4, 0x9B, 0x04, 0x23, 0xFE, 0x9F, 0x00,
- 0xE4, 0xFF, 0xF9, 0xFF, 0x04, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x40,
- 0xFF, 0xC1, 0x01, 0xAB, 0xFC, 0xB7, 0x05, 0x34, 0xF6, 0x8E, 0x15,
- 0x0B, 0x44, 0x42, 0xF7, 0xDC, 0x02, 0x32, 0xFF, 0x04, 0x00, 0x31,
- 0x00, 0xDC, 0xFF, 0x09, 0x00, 0xFF, 0xFF, 0x2C, 0x00, 0x55, 0xFF,
- 0x8B, 0x01, 0x2B, 0xFD, 0xA1, 0x04, 0x9B, 0xF8, 0x42, 0x0E, 0x0F,
- 0x47, 0x38, 0xFB, 0xBE, 0x00, 0x6A, 0x00, 0x58, 0xFF, 0x85, 0x00,
- 0xBB, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x24, 0x00, 0x71, 0xFF, 0x43,
- 0x01, 0xC9, 0xFD, 0x60, 0x03, 0x2E, 0xFB, 0x7E, 0x07, 0xAF, 0x48,
- 0x2D, 0x00, 0x58, 0xFE, 0xBB, 0x01, 0xA3, 0xFE, 0xDD, 0x00, 0x99,
- 0xFF, 0x19, 0x00, 0x1B, 0x00, 0x91, 0xFF, 0xF1, 0x00, 0x79, 0xFE,
- 0x0A, 0x02, 0xC3, 0xFD, 0x73, 0x01, 0xDB, 0x48, 0x07, 0x06, 0xC7,
- 0xFB, 0x12, 0x03, 0xF1, 0xFD, 0x31, 0x01, 0x78, 0xFF, 0x22, 0x00,
- 0x00, 0x00, 0x12, 0x00, 0xB3, 0xFF, 0x99, 0x00, 0x2E, 0xFF, 0xB6,
- 0x00, 0x36, 0x00, 0x47, 0xFC, 0x90, 0x47, 0xA4, 0x0C, 0x31, 0xF9,
- 0x5A, 0x04, 0x4E, 0xFD, 0x7C, 0x01, 0x5B, 0xFF, 0x2A, 0x00, 0x00,
- 0x00, 0x0B, 0x00, 0xD5, 0xFF, 0x44, 0x00, 0xDD, 0xFF, 0x77, 0xFF,
- 0x67, 0x02, 0x14, 0xF8, 0xDC, 0x44, 0xD5, 0x13, 0xBC, 0xF6, 0x7C,
- 0x05, 0xC5, 0xFC, 0xB7, 0x01, 0x44, 0xFF, 0x31, 0x00, 0xFF, 0xFF,
- 0x05, 0x00, 0xF3, 0xFF, 0xF5, 0xFF, 0x7D, 0x00, 0x5D, 0xFE, 0x3E,
- 0x04, 0xEA, 0xF4, 0xD9, 0x40, 0x66, 0x1B, 0x93, 0xF4, 0x62, 0x06,
- 0x64, 0xFC, 0xDC, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x00,
- 0x00, 0x0C, 0x00, 0xB1, 0xFF, 0x04, 0x01, 0x76, 0xFD, 0xA8, 0x05,
- 0xCC, 0xF2, 0xAB, 0x3B, 0x18, 0x23, 0xE0, 0xF2, 0xF7, 0x06, 0x35,
- 0xFC, 0xE6, 0x01, 0x38, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFE, 0xFF,
- 0x20, 0x00, 0x7B, 0xFF, 0x6E, 0x01, 0xCA, 0xFC, 0x9D, 0x06, 0xB1,
- 0xF1, 0x86, 0x35, 0xAE, 0x2A, 0xCD, 0xF1, 0x2B, 0x07, 0x3F, 0xFC,
- 0xD1, 0x01, 0x46, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x2D,
- 0x00, 0x54, 0xFF, 0xB7, 0x01, 0x5E, 0xFC, 0x19, 0x07, 0x88, 0xF1,
- 0x9F, 0x2E, 0xE3, 0x31, 0x7E, 0xF1, 0xEE, 0x06, 0x88, 0xFC, 0x9A,
- 0x01, 0x64, 0xFF, 0x28, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x34, 0x00,
- 0x3E, 0xFF, 0xDF, 0x01, 0x33, 0xFC, 0x20, 0x07, 0x35, 0xF2, 0x36,
- 0x27, 0x78, 0x38, 0x14, 0xF2, 0x3B, 0x06, 0x11, 0xFD, 0x41, 0x01,
- 0x92, 0xFF, 0x17, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36,
- 0xFF, 0xE5, 0x01, 0x44, 0xFC, 0xBD, 0x06, 0x97, 0xF3, 0x8A, 0x1F,
- 0x31, 0x3E, 0xA5, 0xF3, 0x0F, 0x05, 0xDA, 0xFD, 0xC9, 0x00, 0xCF,
- 0xFF, 0x01, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3C, 0xFF,
- 0xCE, 0x01, 0x8C, 0xFC, 0x00, 0x06, 0x86, 0xF5, 0xE0, 0x17, 0xDB,
- 0x42, 0x3F, 0xF6, 0x71, 0x03, 0xD9, 0xFE, 0x36, 0x00, 0x18, 0x00,
- 0xE5, 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0x2E, 0x00, 0x4E, 0xFF, 0x9E,
- 0x01, 0x00, 0xFD, 0xFC, 0x04, 0xD7, 0xF7, 0x75, 0x10, 0x48, 0x46,
- 0xE4, 0xF9, 0x6E, 0x01, 0x06, 0x00, 0x8E, 0xFF, 0x6B, 0x00, 0xC6,
- 0xFF, 0x0E, 0x00, 0x00, 0x00, 0x26, 0x00, 0x68, 0xFF, 0x5B, 0x01,
- 0x96, 0xFD, 0xC6, 0x03, 0x61, 0xFA, 0x81, 0x09, 0x57, 0x48, 0x8D,
- 0xFE, 0x1B, 0xFF, 0x52, 0x01, 0xDB, 0xFE, 0xC2, 0x00, 0xA4, 0xFF,
- 0x16, 0x00, 0x1E, 0x00, 0x87, 0xFF, 0x0B, 0x01, 0x42, 0xFE, 0x74,
- 0x02, 0xF9, 0xFC, 0x39, 0x03, 0xF5, 0x48, 0x24, 0x04, 0x94, 0xFC,
- 0xA9, 0x02, 0x27, 0xFE, 0x18, 0x01, 0x82, 0xFF, 0x1F, 0x00, 0x00,
- 0x00, 0x15, 0x00, 0xA9, 0xFF, 0xB4, 0x00, 0xF7, 0xFE, 0x1D, 0x01,
- 0x7A, 0xFF, 0xC5, 0xFD, 0x1D, 0x48, 0x89, 0x0A, 0xFB, 0xF9, 0xF8,
- 0x03, 0x7D, 0xFD, 0x66, 0x01, 0x63, 0xFF, 0x28, 0x00, 0x00, 0x00,
- 0x0D, 0x00, 0xCB, 0xFF, 0x5E, 0x00, 0xA9, 0xFF, 0xD6, 0xFF, 0xC3,
- 0x01, 0x43, 0xF9, 0xD7, 0x45, 0x92, 0x11, 0x77, 0xF7, 0x28, 0x05,
- 0xEC, 0xFC, 0xA7, 0x01, 0x4A, 0xFF, 0x2F, 0x00, 0xFF, 0xFF, 0x06,
- 0x00, 0xEA, 0xFF, 0x0C, 0x00, 0x4E, 0x00, 0xAF, 0xFE, 0xB8, 0x03,
- 0xC7, 0xF5, 0x38, 0x42, 0x0C, 0x19, 0x32, 0xF5, 0x23, 0x06, 0x7D,
- 0xFC, 0xD3, 0x01, 0x3A, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x02, 0x00,
- 0x05, 0x00, 0xC5, 0xFF, 0xDE, 0x00, 0xB7, 0xFD, 0x45, 0x05, 0x56,
- 0xF3, 0x61, 0x3D, 0xBA, 0x20, 0x56, 0xF3, 0xD3, 0x06, 0x3E, 0xFC,
- 0xE6, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x1A,
- 0x00, 0x8A, 0xFF, 0x51, 0x01, 0xF8, 0xFC, 0x5E, 0x06, 0xED, 0xF1,
- 0x82, 0x37, 0x60, 0x28, 0x0E, 0xF2, 0x26, 0x07, 0x35, 0xFC, 0xDB,
- 0x01, 0x40, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x29, 0x00,
- 0x5F, 0xFF, 0xA5, 0x01, 0x78, 0xFC, 0xFF, 0x06, 0x7D, 0xF1, 0xCF,
- 0x30, 0xB8, 0x2F, 0x80, 0xF1, 0x0D, 0x07, 0x6A, 0xFC, 0xAE, 0x01,
- 0x59, 0xFF, 0x2B, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x33, 0x00, 0x43,
- 0xFF, 0xD6, 0x01, 0x39, 0xFC, 0x2A, 0x07, 0xEB, 0xF1, 0x87, 0x29,
- 0x85, 0x36, 0xCC, 0xF1, 0x7F, 0x06, 0xE0, 0xFC, 0x60, 0x01, 0x82,
- 0xFF, 0x1D, 0x00, 0xFE, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x37, 0xFF,
- 0xE6, 0x01, 0x38, 0xFC, 0xE6, 0x06, 0x19, 0xF3, 0xEA, 0x21, 0x8A,
- 0x3C, 0x0E, 0xF3, 0x78, 0x05, 0x96, 0xFD, 0xF1, 0x00, 0xBB, 0xFF,
- 0x08, 0x00, 0x01, 0x00, 0xFE, 0xFF, 0x35, 0x00, 0x39, 0xFF, 0xD8,
- 0x01, 0x70, 0xFC, 0x43, 0x06, 0xE1, 0xF4, 0x38, 0x1A, 0x8C, 0x41,
- 0x55, 0xF5, 0xFC, 0x03, 0x85, 0xFE, 0x66, 0x00, 0x01, 0x00, 0xEE,
- 0xFF, 0x06, 0x00, 0xFF, 0xFF, 0x30, 0x00, 0x47, 0xFF, 0xAF, 0x01,
- 0xD8, 0xFC, 0x52, 0x05, 0x19, 0xF7, 0xB2, 0x12, 0x5C, 0x45, 0xA9,
- 0xF8, 0x16, 0x02, 0xA6, 0xFF, 0xC3, 0xFF, 0x51, 0x00, 0xD0, 0xFF,
- 0x0C, 0x00, 0x00, 0x00, 0x29, 0x00, 0x5F, 0xFF, 0x71, 0x01, 0x65,
- 0xFD, 0x29, 0x04, 0x96, 0xF9, 0x95, 0x0B, 0xDC, 0x47, 0x03, 0xFD,
- 0xD9, 0xFF, 0xEA, 0x00, 0x12, 0xFF, 0xA7, 0x00, 0xAE, 0xFF, 0x14,
- 0x00, 0x00, 0x00, 0x20, 0x00, 0x7D, 0xFF, 0x24, 0x01, 0x0C, 0xFE,
- 0xDE, 0x02, 0x2E, 0xFC, 0x13, 0x05, 0xEC, 0x48, 0x54, 0x02, 0x5E,
- 0xFD, 0x3F, 0x02, 0x5D, 0xFE, 0xFE, 0x00, 0x8C, 0xFF, 0x1C, 0x00,
- 0x17, 0x00, 0x9E, 0xFF, 0xCF, 0x00, 0xBF, 0xFE, 0x86, 0x01, 0xBA,
- 0xFE, 0x5A, 0xFF, 0x86, 0x48, 0x7D, 0x08, 0xC7, 0xFA, 0x93, 0x03,
- 0xB0, 0xFD, 0x4F, 0x01, 0x6C, 0xFF, 0x25, 0x00, 0x00, 0x00, 0x0F,
- 0x00, 0xC0, 0xFF, 0x78, 0x00, 0x73, 0xFF, 0x38, 0x00, 0x17, 0x01,
- 0x8B, 0xFA, 0xAF, 0x46, 0x59, 0x0F, 0x39, 0xF8, 0xCF, 0x04, 0x15,
- 0xFD, 0x95, 0x01, 0x51, 0xFF, 0x2D, 0x00, 0xFF, 0xFF, 0x08, 0x00,
- 0xE1, 0xFF, 0x25, 0x00, 0x1D, 0x00, 0x05, 0xFF, 0x28, 0x03, 0xBD,
- 0xF6, 0x77, 0x43, 0xB6, 0x16, 0xDC, 0xF5, 0xDD, 0x05, 0x9B, 0xFC,
- 0xC8, 0x01, 0x3E, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0xFD,
- 0xFF, 0xD9, 0xFF, 0xB4, 0x00, 0xFD, 0xFD, 0xD7, 0x04, 0xFA, 0xF3,
- 0xFC, 0x3E, 0x5B, 0x1E, 0xDB, 0xF3, 0xA6, 0x06, 0x4C, 0xFC, 0xE3,
- 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x14, 0x00,
- 0x9B, 0xFF, 0x31, 0x01, 0x2C, 0xFD, 0x15, 0x06, 0x41, 0xF2, 0x6A,
- 0x39, 0x0A, 0x26, 0x61, 0xF2, 0x17, 0x07, 0x31, 0xFC, 0xE2, 0x01,
- 0x3B, 0xFF, 0x35, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x25, 0x00, 0x6A,
- 0xFF, 0x8E, 0x01, 0x99, 0xFC, 0xDB, 0x06, 0x86, 0xF1, 0xF2, 0x32,
- 0x82, 0x2D, 0x96, 0xF1, 0x21, 0x07, 0x53, 0xFC, 0xC0, 0x01, 0x50,
- 0xFF, 0x2E, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x30, 0x00, 0x4A, 0xFF,
- 0xCA, 0x01, 0x46, 0xFC, 0x29, 0x07, 0xB3, 0xF1, 0xD1, 0x2B, 0x81,
- 0x34, 0x9C, 0xF1, 0xB8, 0x06, 0xB5, 0xFC, 0x7C, 0x01, 0x74, 0xFF,
- 0x22, 0x00, 0xFE, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x39, 0xFF, 0xE5,
- 0x01, 0x32, 0xFC, 0x06, 0x07, 0xAA, 0xF2, 0x46, 0x24, 0xC8, 0x3A,
- 0x90, 0xF2, 0xD6, 0x05, 0x57, 0xFD, 0x17, 0x01, 0xA8, 0xFF, 0x0F,
- 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xDF, 0x01,
- 0x5A, 0xFC, 0x7E, 0x06, 0x47, 0xF4, 0x94, 0x1C, 0x1F, 0x40, 0x85,
- 0xF4, 0x7D, 0x04, 0x36, 0xFE, 0x93, 0x00, 0xEA, 0xFF, 0xF7, 0xFF,
- 0x04, 0x00, 0xFF, 0xFF, 0x32, 0x00, 0x42, 0xFF, 0xBE, 0x01, 0xB4,
- 0xFC, 0xA4, 0x05, 0x61, 0xF6, 0xFB, 0x14, 0x53, 0x44, 0x86, 0xF7,
- 0xB6, 0x02, 0x49, 0xFF, 0xF7, 0xFF, 0x37, 0x00, 0xD9, 0xFF, 0x0A,
- 0x00, 0x00, 0x00, 0x2B, 0x00, 0x57, 0xFF, 0x86, 0x01, 0x36, 0xFD,
- 0x89, 0x04, 0xCD, 0xF8, 0xB7, 0x0D, 0x3D, 0x47, 0x91, 0xFB, 0x91,
- 0x00, 0x83, 0x00, 0x4A, 0xFF, 0x8C, 0x00, 0xB9, 0xFF, 0x11, 0x00,
- 0x00, 0x00, 0x23, 0x00, 0x73, 0xFF, 0x3D, 0x01, 0xD6, 0xFD, 0x46,
- 0x03, 0x61, 0xFB, 0x00, 0x07, 0xBF, 0x48, 0x98, 0x00, 0x26, 0xFE,
- 0xD5, 0x01, 0x95, 0xFE, 0xE3, 0x00, 0x96, 0xFF, 0x1A, 0x00, 0x1A,
- 0x00, 0x94, 0xFF, 0xEA, 0x00, 0x87, 0xFE, 0xF0, 0x01, 0xF5, 0xFD,
- 0x05, 0x01, 0xCE, 0x48, 0x83, 0x06, 0x94, 0xFB, 0x2C, 0x03, 0xE4,
- 0xFD, 0x37, 0x01, 0x76, 0xFF, 0x22, 0x00, 0x00, 0x00, 0x12, 0x00,
- 0xB6, 0xFF, 0x93, 0x00, 0x3C, 0xFF, 0x9D, 0x00, 0x63, 0x00, 0xEB,
- 0xFB, 0x69, 0x47, 0x2D, 0x0D, 0xFF, 0xF8, 0x72, 0x04, 0x42, 0xFD,
- 0x81, 0x01, 0x59, 0xFF, 0x2B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xD7,
- 0xFF, 0x3E, 0x00, 0xEA, 0xFF, 0x60, 0xFF, 0x8F, 0x02, 0xCD, 0xF7,
- 0x99, 0x44, 0x68, 0x14, 0x8E, 0xF6, 0x90, 0x05, 0xBC, 0xFC, 0xBA,
- 0x01, 0x43, 0xFF, 0x32, 0x00, 0xFF, 0xFF, 0x04, 0x00, 0xF5, 0xFF,
- 0xEF, 0xFF, 0x88, 0x00, 0x49, 0xFE, 0x5D, 0x04, 0xB7, 0xF4, 0x7D,
- 0x40, 0xFD, 0x1B, 0x6C, 0xF4, 0x70, 0x06, 0x5F, 0xFC, 0xDE, 0x01,
- 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0x0E, 0x00, 0xAC,
- 0xFF, 0x0E, 0x01, 0x66, 0xFD, 0xBF, 0x05, 0xAD, 0xF2, 0x3B, 0x3B,
- 0xB0, 0x23, 0xC4, 0xF2, 0xFF, 0x06, 0x33, 0xFC, 0xE5, 0x01, 0x38,
- 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFE, 0xFF, 0x21, 0x00, 0x77, 0xFF,
- 0x75, 0x01, 0xBF, 0xFC, 0xAB, 0x06, 0xA6, 0xF1, 0x05, 0x35, 0x40,
- 0x2B, 0xBF, 0xF1, 0x2A, 0x07, 0x42, 0xFC, 0xCE, 0x01, 0x48, 0xFF,
- 0x31, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x2E, 0x00, 0x52, 0xFF, 0xBC,
- 0x01, 0x58, 0xFC, 0x1D, 0x07, 0x8E, 0xF1, 0x11, 0x2E, 0x6B, 0x32,
- 0x81, 0xF1, 0xE5, 0x06, 0x90, 0xFC, 0x94, 0x01, 0x67, 0xFF, 0x26,
- 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x35, 0x00, 0x3C, 0xFF, 0xE0, 0x01,
- 0x32, 0xFC, 0x1C, 0x07, 0x4B, 0xF2, 0xA0, 0x26, 0xF2, 0x38, 0x2A,
- 0xF2, 0x28, 0x06, 0x1F, 0xFD, 0x39, 0x01, 0x96, 0xFF, 0x16, 0x00,
- 0xFF, 0xFF, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE4, 0x01, 0x48,
- 0xFC, 0xB2, 0x06, 0xB9, 0xF3, 0xF3, 0x1E, 0x98, 0x3E, 0xCF, 0xF3,
- 0xF3, 0x04, 0xEB, 0xFD, 0xBF, 0x00, 0xD4, 0xFF, 0xFF, 0xFF, 0x03,
- 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3D, 0xFF, 0xCB, 0x01, 0x93, 0xFC,
- 0xEF, 0x05, 0xB0, 0xF5, 0x4B, 0x17, 0x2A, 0x43, 0x7D, 0xF6, 0x4D,
- 0x03, 0xEF, 0xFE, 0x2A, 0x00, 0x1E, 0x00, 0xE3, 0xFF, 0x08, 0x00,
- 0xFF, 0xFF, 0x2E, 0x00, 0x4F, 0xFF, 0x99, 0x01, 0x0B, 0xFD, 0xE6,
- 0x04, 0x08, 0xF8, 0xE7, 0x0F, 0x7C, 0x46, 0x37, 0xFA, 0x42, 0x01,
- 0x1F, 0x00, 0x81, 0xFF, 0x71, 0x00, 0xC3, 0xFF, 0x0F, 0x00, 0x00,
- 0x00, 0x26, 0x00, 0x6A, 0xFF, 0x55, 0x01, 0xA3, 0xFD, 0xAD, 0x03,
- 0x94, 0xFA, 0xFF, 0x08, 0x70, 0x48, 0xF3, 0xFE, 0xEA, 0xFE, 0x6C,
- 0x01, 0xCD, 0xFE, 0xC9, 0x00, 0xA1, 0xFF, 0x17, 0x00, 0x1D, 0x00,
- 0x8A, 0xFF, 0x04, 0x01, 0x50, 0xFE, 0x5A, 0x02, 0x2C, 0xFD, 0xC6,
- 0x02, 0xF2, 0x48, 0x9B, 0x04, 0x61, 0xFC, 0xC3, 0x02, 0x19, 0xFE,
- 0x1E, 0x01, 0x7F, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0xAC,
- 0xFF, 0xAE, 0x00, 0x05, 0xFF, 0x03, 0x01, 0xAA, 0xFF, 0x63, 0xFD,
- 0xFD, 0x47, 0x0E, 0x0B, 0xC8, 0xF9, 0x11, 0x04, 0x71, 0xFD, 0x6C,
- 0x01, 0x61, 0xFF, 0x28, 0x00, 0x00, 0x00, 0x0C, 0x00, 0xCD, 0xFF,
- 0x57, 0x00, 0xB6, 0xFF, 0xBE, 0xFF, 0xED, 0x01, 0xF5, 0xF8, 0x9B,
- 0x45, 0x22, 0x12, 0x48, 0xF7, 0x3D, 0x05, 0xE2, 0xFC, 0xAB, 0x01,
- 0x49, 0xFF, 0x30, 0x00, 0xFF, 0xFF, 0x06, 0x00, 0xEC, 0xFF, 0x06,
- 0x00, 0x5A, 0x00, 0x9A, 0xFE, 0xDA, 0x03, 0x8D, 0xF5, 0xE1, 0x41,
- 0xA1, 0x19, 0x09, 0xF5, 0x33, 0x06, 0x77, 0xFC, 0xD6, 0x01, 0x3A,
- 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF,
- 0xE8, 0x00, 0xA6, 0xFD, 0x5F, 0x05, 0x31, 0xF3, 0xF6, 0x3C, 0x52,
- 0x21, 0x37, 0xF3, 0xDD, 0x06, 0x3B, 0xFC, 0xE6, 0x01, 0x36, 0xFF,
- 0x36, 0x00, 0xFD, 0xFF, 0xFE, 0xFF, 0x1C, 0x00, 0x86, 0xFF, 0x59,
- 0x01, 0xEC, 0xFC, 0x6F, 0x06, 0xDC, 0xF1, 0x04, 0x37, 0xF3, 0x28,
- 0xFC, 0xF1, 0x28, 0x07, 0x37, 0xFC, 0xD8, 0x01, 0x41, 0xFF, 0x33,
- 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x2A, 0x00, 0x5C, 0xFF, 0xAA, 0x01,
- 0x71, 0xFC, 0x07, 0x07, 0x7E, 0xF1, 0x44, 0x30, 0x44, 0x30, 0x7E,
- 0xF1, 0x07, 0x07, 0x71, 0xFC, 0xAA, 0x01, 0x5C, 0xFF, 0x2A, 0x00,
- 0xFD, 0xFF, 0xFD, 0xFF, 0x33, 0x00, 0x41, 0xFF, 0xD8, 0x01, 0x37,
- 0xFC, 0x28, 0x07, 0xFC, 0xF1, 0xF3, 0x28, 0x04, 0x37, 0xDC, 0xF1,
- 0x6F, 0x06, 0xEC, 0xFC, 0x59, 0x01, 0x86, 0xFF, 0x1C, 0x00, 0xFE,
- 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3B, 0xFC,
- 0xDD, 0x06, 0x37, 0xF3, 0x52, 0x21, 0xF6, 0x3C, 0x31, 0xF3, 0x5F,
- 0x05, 0xA6, 0xFD, 0xE8, 0x00, 0xC0, 0xFF, 0x07, 0x00, 0x01, 0x00,
- 0xFE, 0xFF, 0x35, 0x00, 0x3A, 0xFF, 0xD6, 0x01, 0x77, 0xFC, 0x33,
- 0x06, 0x09, 0xF5, 0xA1, 0x19, 0xE1, 0x41, 0x8D, 0xF5, 0xDA, 0x03,
- 0x9A, 0xFE, 0x5A, 0x00, 0x06, 0x00, 0xEC, 0xFF, 0x06, 0x00, 0xFF,
- 0xFF, 0x30, 0x00, 0x49, 0xFF, 0xAB, 0x01, 0xE2, 0xFC, 0x3D, 0x05,
- 0x48, 0xF7, 0x22, 0x12, 0x9B, 0x45, 0xF5, 0xF8, 0xED, 0x01, 0xBE,
- 0xFF, 0xB6, 0xFF, 0x57, 0x00, 0xCD, 0xFF, 0x0C, 0x00, 0x00, 0x00,
- 0x28, 0x00, 0x61, 0xFF, 0x6C, 0x01, 0x71, 0xFD, 0x11, 0x04, 0xC8,
- 0xF9, 0x0E, 0x0B, 0xFD, 0x47, 0x63, 0xFD, 0xAA, 0xFF, 0x03, 0x01,
- 0x05, 0xFF, 0xAE, 0x00, 0xAC, 0xFF, 0x14, 0x00, 0x00, 0x00, 0x20,
- 0x00, 0x7F, 0xFF, 0x1E, 0x01, 0x19, 0xFE, 0xC3, 0x02, 0x61, 0xFC,
- 0x9B, 0x04, 0xF2, 0x48, 0xC6, 0x02, 0x2C, 0xFD, 0x5A, 0x02, 0x50,
- 0xFE, 0x04, 0x01, 0x8A, 0xFF, 0x1D, 0x00, 0x17, 0x00, 0xA1, 0xFF,
- 0xC9, 0x00, 0xCD, 0xFE, 0x6C, 0x01, 0xEA, 0xFE, 0xF3, 0xFE, 0x70,
- 0x48, 0xFF, 0x08, 0x94, 0xFA, 0xAD, 0x03, 0xA3, 0xFD, 0x55, 0x01,
- 0x6A, 0xFF, 0x26, 0x00, 0x00, 0x00, 0x0F, 0x00, 0xC3, 0xFF, 0x71,
- 0x00, 0x81, 0xFF, 0x1F, 0x00, 0x42, 0x01, 0x37, 0xFA, 0x7C, 0x46,
- 0xE7, 0x0F, 0x08, 0xF8, 0xE6, 0x04, 0x0B, 0xFD, 0x99, 0x01, 0x4F,
- 0xFF, 0x2E, 0x00, 0xFF, 0xFF, 0x08, 0x00, 0xE3, 0xFF, 0x1E, 0x00,
- 0x2A, 0x00, 0xEF, 0xFE, 0x4D, 0x03, 0x7D, 0xF6, 0x2A, 0x43, 0x4B,
- 0x17, 0xB0, 0xF5, 0xEF, 0x05, 0x93, 0xFC, 0xCB, 0x01, 0x3D, 0xFF,
- 0x34, 0x00, 0xFE, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0xD4, 0xFF, 0xBF,
- 0x00, 0xEB, 0xFD, 0xF3, 0x04, 0xCF, 0xF3, 0x98, 0x3E, 0xF3, 0x1E,
- 0xB9, 0xF3, 0xB2, 0x06, 0x48, 0xFC, 0xE4, 0x01, 0x36, 0xFF, 0x36,
- 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x16, 0x00, 0x96, 0xFF, 0x39, 0x01,
- 0x1F, 0xFD, 0x28, 0x06, 0x2A, 0xF2, 0xF2, 0x38, 0xA0, 0x26, 0x4B,
- 0xF2, 0x1C, 0x07, 0x32, 0xFC, 0xE0, 0x01, 0x3C, 0xFF, 0x35, 0x00,
- 0xFD, 0xFF, 0xFD, 0xFF, 0x26, 0x00, 0x67, 0xFF, 0x94, 0x01, 0x90,
- 0xFC, 0xE5, 0x06, 0x81, 0xF1, 0x6B, 0x32, 0x11, 0x2E, 0x8E, 0xF1,
- 0x1D, 0x07, 0x58, 0xFC, 0xBC, 0x01, 0x52, 0xFF, 0x2E, 0x00, 0xFD,
- 0xFF, 0xFD, 0xFF, 0x31, 0x00, 0x48, 0xFF, 0xCE, 0x01, 0x42, 0xFC,
- 0x2A, 0x07, 0xBF, 0xF1, 0x40, 0x2B, 0x05, 0x35, 0xA6, 0xF1, 0xAB,
- 0x06, 0xBF, 0xFC, 0x75, 0x01, 0x77, 0xFF, 0x21, 0x00, 0xFE, 0xFF,
- 0xFD, 0xFF, 0x36, 0x00, 0x38, 0xFF, 0xE5, 0x01, 0x33, 0xFC, 0xFF,
- 0x06, 0xC4, 0xF2, 0xB0, 0x23, 0x3B, 0x3B, 0xAD, 0xF2, 0xBF, 0x05,
- 0x66, 0xFD, 0x0E, 0x01, 0xAC, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0xFE,
- 0xFF, 0x36, 0x00, 0x37, 0xFF, 0xDE, 0x01, 0x5F, 0xFC, 0x70, 0x06,
- 0x6C, 0xF4, 0xFD, 0x1B, 0x7D, 0x40, 0xB7, 0xF4, 0x5D, 0x04, 0x49,
- 0xFE, 0x88, 0x00, 0xEF, 0xFF, 0xF5, 0xFF, 0x04, 0x00, 0xFF, 0xFF,
- 0x32, 0x00, 0x43, 0xFF, 0xBA, 0x01, 0xBC, 0xFC, 0x90, 0x05, 0x8E,
- 0xF6, 0x68, 0x14, 0x99, 0x44, 0xCD, 0xF7, 0x8F, 0x02, 0x60, 0xFF,
- 0xEA, 0xFF, 0x3E, 0x00, 0xD7, 0xFF, 0x0A, 0x00, 0x00, 0x00, 0x2B,
- 0x00, 0x59, 0xFF, 0x81, 0x01, 0x42, 0xFD, 0x72, 0x04, 0xFF, 0xF8,
- 0x2D, 0x0D, 0x69, 0x47, 0xEB, 0xFB, 0x63, 0x00, 0x9D, 0x00, 0x3C,
- 0xFF, 0x93, 0x00, 0xB6, 0xFF, 0x12, 0x00, 0x00, 0x00, 0x22, 0x00,
- 0x76, 0xFF, 0x37, 0x01, 0xE4, 0xFD, 0x2C, 0x03, 0x94, 0xFB, 0x83,
- 0x06, 0xCE, 0x48, 0x05, 0x01, 0xF5, 0xFD, 0xF0, 0x01, 0x87, 0xFE,
- 0xEA, 0x00, 0x94, 0xFF, 0x1A, 0x00, 0x1A, 0x00, 0x96, 0xFF, 0xE3,
- 0x00, 0x95, 0xFE, 0xD5, 0x01, 0x26, 0xFE, 0x98, 0x00, 0xBF, 0x48,
- 0x00, 0x07, 0x61, 0xFB, 0x46, 0x03, 0xD6, 0xFD, 0x3D, 0x01, 0x73,
- 0xFF, 0x23, 0x00, 0x00, 0x00, 0x11, 0x00, 0xB9, 0xFF, 0x8C, 0x00,
- 0x4A, 0xFF, 0x83, 0x00, 0x91, 0x00, 0x91, 0xFB, 0x3D, 0x47, 0xB7,
- 0x0D, 0xCD, 0xF8, 0x89, 0x04, 0x36, 0xFD, 0x86, 0x01, 0x57, 0xFF,
- 0x2B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xD9, 0xFF, 0x37, 0x00, 0xF7,
- 0xFF, 0x49, 0xFF, 0xB6, 0x02, 0x86, 0xF7, 0x53, 0x44, 0xFB, 0x14,
- 0x61, 0xF6, 0xA4, 0x05, 0xB4, 0xFC, 0xBE, 0x01, 0x42, 0xFF, 0x32,
- 0x00, 0xFF, 0xFF, 0x04, 0x00, 0xF7, 0xFF, 0xEA, 0xFF, 0x93, 0x00,
- 0x36, 0xFE, 0x7D, 0x04, 0x85, 0xF4, 0x1F, 0x40, 0x94, 0x1C, 0x47,
- 0xF4, 0x7E, 0x06, 0x5A, 0xFC, 0xDF, 0x01, 0x37, 0xFF, 0x36, 0x00,
- 0xFE, 0xFF, 0x00, 0x00, 0x0F, 0x00, 0xA8, 0xFF, 0x17, 0x01, 0x57,
- 0xFD, 0xD6, 0x05, 0x90, 0xF2, 0xC8, 0x3A, 0x46, 0x24, 0xAA, 0xF2,
- 0x06, 0x07, 0x32, 0xFC, 0xE5, 0x01, 0x39, 0xFF, 0x36, 0x00, 0xFD,
- 0xFF, 0xFE, 0xFF, 0x22, 0x00, 0x74, 0xFF, 0x7C, 0x01, 0xB5, 0xFC,
- 0xB8, 0x06, 0x9C, 0xF1, 0x81, 0x34, 0xD1, 0x2B, 0xB3, 0xF1, 0x29,
- 0x07, 0x46, 0xFC, 0xCA, 0x01, 0x4A, 0xFF, 0x30, 0x00, 0xFD, 0xFF,
- 0xFD, 0xFF, 0x2E, 0x00, 0x50, 0xFF, 0xC0, 0x01, 0x53, 0xFC, 0x21,
- 0x07, 0x96, 0xF1, 0x82, 0x2D, 0xF2, 0x32, 0x86, 0xF1, 0xDB, 0x06,
- 0x99, 0xFC, 0x8E, 0x01, 0x6A, 0xFF, 0x25, 0x00, 0xFD, 0xFF, 0xFD,
- 0xFF, 0x35, 0x00, 0x3B, 0xFF, 0xE2, 0x01, 0x31, 0xFC, 0x17, 0x07,
- 0x61, 0xF2, 0x0A, 0x26, 0x6A, 0x39, 0x41, 0xF2, 0x15, 0x06, 0x2C,
- 0xFD, 0x31, 0x01, 0x9B, 0xFF, 0x14, 0x00, 0xFF, 0xFF, 0xFE, 0xFF,
- 0x36, 0x00, 0x36, 0xFF, 0xE3, 0x01, 0x4C, 0xFC, 0xA6, 0x06, 0xDB,
- 0xF3, 0x5B, 0x1E, 0xFC, 0x3E, 0xFA, 0xF3, 0xD7, 0x04, 0xFD, 0xFD,
- 0xB4, 0x00, 0xD9, 0xFF, 0xFD, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0x33,
- 0x00, 0x3E, 0xFF, 0xC8, 0x01, 0x9B, 0xFC, 0xDD, 0x05, 0xDC, 0xF5,
- 0xB6, 0x16, 0x77, 0x43, 0xBD, 0xF6, 0x28, 0x03, 0x05, 0xFF, 0x1D,
- 0x00, 0x25, 0x00, 0xE1, 0xFF, 0x08, 0x00, 0xFF, 0xFF, 0x2D, 0x00,
- 0x51, 0xFF, 0x95, 0x01, 0x15, 0xFD, 0xCF, 0x04, 0x39, 0xF8, 0x59,
- 0x0F, 0xAF, 0x46, 0x8B, 0xFA, 0x17, 0x01, 0x38, 0x00, 0x73, 0xFF,
- 0x78, 0x00, 0xC0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x25, 0x00, 0x6C,
- 0xFF, 0x4F, 0x01, 0xB0, 0xFD, 0x93, 0x03, 0xC7, 0xFA, 0x7D, 0x08,
- 0x86, 0x48, 0x5A, 0xFF, 0xBA, 0xFE, 0x86, 0x01, 0xBF, 0xFE, 0xCF,
- 0x00, 0x9E, 0xFF, 0x17, 0x00, 0x1C, 0x00, 0x8C, 0xFF, 0xFE, 0x00,
- 0x5D, 0xFE, 0x3F, 0x02, 0x5E, 0xFD, 0x54, 0x02, 0xEC, 0x48, 0x13,
- 0x05, 0x2E, 0xFC, 0xDE, 0x02, 0x0C, 0xFE, 0x24, 0x01, 0x7D, 0xFF,
- 0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0xAE, 0xFF, 0xA7, 0x00, 0x12,
- 0xFF, 0xEA, 0x00, 0xD9, 0xFF, 0x03, 0xFD, 0xDC, 0x47, 0x95, 0x0B,
- 0x96, 0xF9, 0x29, 0x04, 0x65, 0xFD, 0x71, 0x01, 0x5F, 0xFF, 0x29,
- 0x00, 0x00, 0x00, 0x0C, 0x00, 0xD0, 0xFF, 0x51, 0x00, 0xC3, 0xFF,
- 0xA6, 0xFF, 0x16, 0x02, 0xA9, 0xF8, 0x5C, 0x45, 0xB2, 0x12, 0x19,
- 0xF7, 0x52, 0x05, 0xD8, 0xFC, 0xAF, 0x01, 0x47, 0xFF, 0x30, 0x00,
- 0xFF, 0xFF, 0x06, 0x00, 0xEE, 0xFF, 0x01, 0x00, 0x66, 0x00, 0x85,
- 0xFE, 0xFC, 0x03, 0x55, 0xF5, 0x8C, 0x41, 0x38, 0x1A, 0xE1, 0xF4,
- 0x43, 0x06, 0x70, 0xFC, 0xD8, 0x01, 0x39, 0xFF, 0x35, 0x00, 0xFE,
- 0xFF, 0x01, 0x00, 0x08, 0x00, 0xBB, 0xFF, 0xF1, 0x00, 0x96, 0xFD,
- 0x78, 0x05, 0x0E, 0xF3, 0x8A, 0x3C, 0xEA, 0x21, 0x19, 0xF3, 0xE6,
- 0x06, 0x38, 0xFC, 0xE6, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF,
- 0xFE, 0xFF, 0x1D, 0x00, 0x82, 0xFF, 0x60, 0x01, 0xE0, 0xFC, 0x7F,
- 0x06, 0xCC, 0xF1, 0x85, 0x36, 0x87, 0x29, 0xEB, 0xF1, 0x2A, 0x07,
- 0x39, 0xFC, 0xD6, 0x01, 0x43, 0xFF, 0x33, 0x00, 0xFD, 0xFF, 0xFD,
- 0xFF, 0x2B, 0x00, 0x59, 0xFF, 0xAE, 0x01, 0x6A, 0xFC, 0x0D, 0x07,
- 0x80, 0xF1, 0xB8, 0x2F, 0xCF, 0x30, 0x7D, 0xF1, 0xFF, 0x06, 0x78,
- 0xFC, 0xA5, 0x01, 0x5F, 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0xFD, 0xFF,
- 0x34, 0x00, 0x40, 0xFF, 0xDB, 0x01, 0x35, 0xFC, 0x26, 0x07, 0x0E,
- 0xF2, 0x60, 0x28, 0x82, 0x37, 0xED, 0xF1, 0x5E, 0x06, 0xF8, 0xFC,
- 0x51, 0x01, 0x8A, 0xFF, 0x1A, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36,
- 0x00, 0x36, 0xFF, 0xE6, 0x01, 0x3E, 0xFC, 0xD3, 0x06, 0x56, 0xF3,
- 0xBA, 0x20, 0x61, 0x3D, 0x56, 0xF3, 0x45, 0x05, 0xB7, 0xFD, 0xDE,
- 0x00, 0xC5, 0xFF, 0x05, 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x35, 0x00,
- 0x3A, 0xFF, 0xD3, 0x01, 0x7D, 0xFC, 0x23, 0x06, 0x32, 0xF5, 0x0C,
- 0x19, 0x38, 0x42, 0xC7, 0xF5, 0xB8, 0x03, 0xAF, 0xFE, 0x4E, 0x00,
- 0x0C, 0x00, 0xEA, 0xFF, 0x06, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4A,
- 0xFF, 0xA7, 0x01, 0xEC, 0xFC, 0x28, 0x05, 0x77, 0xF7, 0x92, 0x11,
- 0xD7, 0x45, 0x43, 0xF9, 0xC3, 0x01, 0xD6, 0xFF, 0xA9, 0xFF, 0x5E,
- 0x00, 0xCB, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x28, 0x00, 0x63, 0xFF,
- 0x66, 0x01, 0x7D, 0xFD, 0xF8, 0x03, 0xFB, 0xF9, 0x89, 0x0A, 0x1D,
- 0x48, 0xC5, 0xFD, 0x7A, 0xFF, 0x1D, 0x01, 0xF7, 0xFE, 0xB4, 0x00,
- 0xA9, 0xFF, 0x15, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x82, 0xFF, 0x18,
- 0x01, 0x27, 0xFE, 0xA9, 0x02, 0x94, 0xFC, 0x24, 0x04, 0xF5, 0x48,
- 0x39, 0x03, 0xF9, 0xFC, 0x74, 0x02, 0x42, 0xFE, 0x0B, 0x01, 0x87,
- 0xFF, 0x1E, 0x00, 0x16, 0x00, 0xA4, 0xFF, 0xC2, 0x00, 0xDB, 0xFE,
- 0x52, 0x01, 0x1B, 0xFF, 0x8D, 0xFE, 0x57, 0x48, 0x81, 0x09, 0x61,
- 0xFA, 0xC6, 0x03, 0x96, 0xFD, 0x5B, 0x01, 0x68, 0xFF, 0x26, 0x00,
- 0x00, 0x00, 0x0E, 0x00, 0xC6, 0xFF, 0x6B, 0x00, 0x8E, 0xFF, 0x06,
- 0x00, 0x6E, 0x01, 0xE4, 0xF9, 0x48, 0x46, 0x75, 0x10, 0xD7, 0xF7,
- 0xFC, 0x04, 0x00, 0xFD, 0x9E, 0x01, 0x4E, 0xFF, 0x2E, 0x00, 0xFF,
- 0xFF, 0x07, 0x00, 0xE5, 0xFF, 0x18, 0x00, 0x36, 0x00, 0xD9, 0xFE,
- 0x71, 0x03, 0x3F, 0xF6, 0xDB, 0x42, 0xE0, 0x17, 0x86, 0xF5, 0x00,
- 0x06, 0x8C, 0xFC, 0xCE, 0x01, 0x3C, 0xFF, 0x34, 0x00, 0xFE, 0xFF,
- 0x02, 0x00, 0x01, 0x00, 0xCF, 0xFF, 0xC9, 0x00, 0xDA, 0xFD, 0x0F,
- 0x05, 0xA5, 0xF3, 0x31, 0x3E, 0x8A, 0x1F, 0x97, 0xF3, 0xBD, 0x06,
- 0x44, 0xFC, 0xE5, 0x01, 0x36, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFF,
- 0xFF, 0x17, 0x00, 0x92, 0xFF, 0x41, 0x01, 0x11, 0xFD, 0x3B, 0x06,
- 0x14, 0xF2, 0x78, 0x38, 0x36, 0x27, 0x35, 0xF2, 0x20, 0x07, 0x33,
- 0xFC, 0xDF, 0x01, 0x3E, 0xFF, 0x34, 0x00, 0xFD, 0xFF, 0xFD, 0xFF,
- 0x28, 0x00, 0x64, 0xFF, 0x9A, 0x01, 0x88, 0xFC, 0xEE, 0x06, 0x7E,
- 0xF1, 0xE3, 0x31, 0x9F, 0x2E, 0x88, 0xF1, 0x19, 0x07, 0x5E, 0xFC,
- 0xB7, 0x01, 0x54, 0xFF, 0x2D, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x32,
- 0x00, 0x46, 0xFF, 0xD1, 0x01, 0x3F, 0xFC, 0x2B, 0x07, 0xCD, 0xF1,
- 0xAE, 0x2A, 0x86, 0x35, 0xB1, 0xF1, 0x9D, 0x06, 0xCA, 0xFC, 0x6E,
- 0x01, 0x7B, 0xFF, 0x20, 0x00, 0xFE, 0xFF, 0xFD, 0xFF, 0x36, 0x00,
- 0x38, 0xFF, 0xE6, 0x01, 0x35, 0xFC, 0xF7, 0x06, 0xE0, 0xF2, 0x18,
- 0x23, 0xAB, 0x3B, 0xCC, 0xF2, 0xA8, 0x05, 0x76, 0xFD, 0x04, 0x01,
- 0xB1, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x38,
- 0xFF, 0xDC, 0x01, 0x64, 0xFC, 0x62, 0x06, 0x93, 0xF4, 0x66, 0x1B,
- 0xD9, 0x40, 0xEA, 0xF4, 0x3E, 0x04, 0x5D, 0xFE, 0x7D, 0x00, 0xF5,
- 0xFF, 0xF3, 0xFF, 0x05, 0x00, 0xFF, 0xFF, 0x31, 0x00, 0x44, 0xFF,
- 0xB7, 0x01, 0xC5, 0xFC, 0x7C, 0x05, 0xBC, 0xF6, 0xD5, 0x13, 0xDC,
- 0x44, 0x14, 0xF8, 0x67, 0x02, 0x77, 0xFF, 0xDD, 0xFF, 0x44, 0x00,
- 0xD5, 0xFF, 0x0B, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x5B, 0xFF, 0x7C,
- 0x01, 0x4E, 0xFD, 0x5A, 0x04, 0x31, 0xF9, 0xA4, 0x0C, 0x90, 0x47,
- 0x47, 0xFC, 0x36, 0x00, 0xB6, 0x00, 0x2E, 0xFF, 0x99, 0x00, 0xB3,
- 0xFF, 0x12, 0x00, 0x00, 0x00, 0x22, 0x00, 0x78, 0xFF, 0x31, 0x01,
- 0xF1, 0xFD, 0x12, 0x03, 0xC7, 0xFB, 0x07, 0x06, 0xDB, 0x48, 0x73,
- 0x01, 0xC3, 0xFD, 0x0A, 0x02, 0x79, 0xFE, 0xF1, 0x00, 0x91, 0xFF,
- 0x1B, 0x00, 0x19, 0x00, 0x99, 0xFF, 0xDD, 0x00, 0xA3, 0xFE, 0xBB,
- 0x01, 0x58, 0xFE, 0x2D, 0x00, 0xAF, 0x48, 0x7E, 0x07, 0x2E, 0xFB,
- 0x60, 0x03, 0xC9, 0xFD, 0x43, 0x01, 0x71, 0xFF, 0x24, 0x00, 0x00,
- 0x00, 0x10, 0x00, 0xBB, 0xFF, 0x85, 0x00, 0x58, 0xFF, 0x6A, 0x00,
- 0xBE, 0x00, 0x38, 0xFB, 0x0F, 0x47, 0x42, 0x0E, 0x9B, 0xF8, 0xA1,
- 0x04, 0x2B, 0xFD, 0x8B, 0x01, 0x55, 0xFF, 0x2C, 0x00, 0xFF, 0xFF,
- 0x09, 0x00, 0xDC, 0xFF, 0x31, 0x00, 0x04, 0x00, 0x32, 0xFF, 0xDC,
- 0x02, 0x42, 0xF7, 0x0B, 0x44, 0x8E, 0x15, 0x34, 0xF6, 0xB7, 0x05,
- 0xAB, 0xFC, 0xC1, 0x01, 0x40, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x04,
- 0x00, 0xF9, 0xFF, 0xE4, 0xFF, 0x9F, 0x00, 0x23, 0xFE, 0x9B, 0x04,
- 0x55, 0xF4, 0xC0, 0x3F, 0x2C, 0x1D, 0x22, 0xF4, 0x8C, 0x06, 0x55,
- 0xFC, 0xE1, 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFE, 0xFF, 0x00, 0x00,
- 0x11, 0x00, 0xA3, 0xFF, 0x20, 0x01, 0x49, 0xFD, 0xEB, 0x05, 0x74,
- 0xF2, 0x54, 0x3A, 0xDD, 0x24, 0x91, 0xF2, 0x0C, 0x07, 0x32, 0xFC,
- 0xE4, 0x01, 0x3A, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFE, 0xFF, 0x23,
- 0x00, 0x71, 0xFF, 0x82, 0x01, 0xAB, 0xFC, 0xC4, 0x06, 0x93, 0xF1,
- 0xFD, 0x33, 0x62, 0x2C, 0xA8, 0xF1, 0x27, 0x07, 0x4A, 0xFC, 0xC7,
- 0x01, 0x4C, 0xFF, 0x30, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x2F, 0x00,
- 0x4E, 0xFF, 0xC3, 0x01, 0x4E, 0xFC, 0x24, 0x07, 0x9E, 0xF1, 0xF2,
- 0x2C, 0x78, 0x33, 0x8C, 0xF1, 0xD0, 0x06, 0xA2, 0xFC, 0x88, 0x01,
- 0x6D, 0xFF, 0x24, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x35, 0x00, 0x3B,
- 0xFF, 0xE3, 0x01, 0x31, 0xFC, 0x12, 0x07, 0x79, 0xF2, 0x73, 0x25,
- 0xDF, 0x39, 0x5A, 0xF2, 0x00, 0x06, 0x3A, 0xFD, 0x28, 0x01, 0x9F,
- 0xFF, 0x13, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x36, 0x00, 0x36, 0xFF,
- 0xE2, 0x01, 0x50, 0xFC, 0x99, 0x06, 0xFE, 0xF3, 0xC3, 0x1D, 0x5E,
- 0x3F, 0x27, 0xF4, 0xB9, 0x04, 0x10, 0xFE, 0xA9, 0x00, 0xDF, 0xFF,
- 0xFB, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x3F, 0xFF, 0xC5,
- 0x01, 0xA3, 0xFC, 0xCA, 0x05, 0x07, 0xF6, 0x22, 0x16, 0xC3, 0x43,
- 0xFE, 0xF6, 0x02, 0x03, 0x1B, 0xFF, 0x11, 0x00, 0x2B, 0x00, 0xDE,
- 0xFF, 0x09, 0x00, 0xFF, 0xFF, 0x2D, 0x00, 0x53, 0xFF, 0x90, 0x01,
- 0x20, 0xFD, 0xB8, 0x04, 0x6A, 0xF8, 0xCD, 0x0E, 0xE1, 0x46, 0xE1,
- 0xFA, 0xEB, 0x00, 0x51, 0x00, 0x65, 0xFF, 0x7F, 0x00, 0xBE, 0xFF,
- 0x10, 0x00, 0x00, 0x00, 0x24, 0x00, 0x6E, 0xFF, 0x49, 0x01, 0xBC,
- 0xFD, 0x7A, 0x03, 0xFA, 0xFA, 0xFD, 0x07, 0x9C, 0x48, 0xC3, 0xFF,
- 0x89, 0xFE, 0xA1, 0x01, 0xB1, 0xFE, 0xD6, 0x00, 0x9C, 0xFF, 0x18,
- 0x00, 0x1C, 0x00, 0x8F, 0xFF, 0xF7, 0x00, 0x6B, 0xFE, 0x25, 0x02,
- 0x91, 0xFD, 0xE3, 0x01, 0xE5, 0x48, 0x8D, 0x05, 0xFB, 0xFB, 0xF8,
- 0x02, 0xFE, 0xFD, 0x2B, 0x01, 0x7A, 0xFF, 0x21, 0x00, 0x00, 0x00,
- 0x13, 0x00, 0xB1, 0xFF, 0xA0, 0x00, 0x20, 0xFF, 0xD0, 0x00, 0x07,
- 0x00, 0xA4, 0xFC, 0xB6, 0x47, 0x1C, 0x0C, 0x63, 0xF9, 0x42, 0x04,
- 0x59, 0xFD, 0x76, 0x01, 0x5D, 0xFF, 0x2A, 0x00, 0x00, 0x00, 0x0B,
- 0x00, 0xD2, 0xFF, 0x4A, 0x00, 0xD0, 0xFF, 0x8E, 0xFF, 0x3F, 0x02,
- 0x5E, 0xF8, 0x1E, 0x45, 0x44, 0x13, 0xEA, 0xF6, 0x67, 0x05, 0xCF,
- 0xFC, 0xB3, 0x01, 0x46, 0xFF, 0x31, 0x00, 0xFF, 0xFF, 0x05, 0x00,
- 0xF0, 0xFF, 0xFB, 0xFF, 0x71, 0x00, 0x71, 0xFE, 0x1D, 0x04, 0x1F,
- 0xF5, 0x32, 0x41, 0xCE, 0x1A, 0xBA, 0xF4, 0x53, 0x06, 0x6A, 0xFC,
- 0xDA, 0x01, 0x38, 0xFF, 0x35, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0x0A,
- 0x00, 0xB6, 0xFF, 0xFB, 0x00, 0x85, 0xFD, 0x90, 0x05, 0xEC, 0xF2,
- 0x1C, 0x3C, 0x81, 0x22, 0xFC, 0xF2, 0xEF, 0x06, 0x36, 0xFC, 0xE6,
- 0x01, 0x37, 0xFF, 0x36, 0x00, 0xFD, 0xFF, 0xFE, 0xFF, 0x1E, 0x00,
- 0x7F, 0xFF, 0x67, 0x01, 0xD5, 0xFC, 0x8E, 0x06, 0xBE, 0xF1, 0x06,
- 0x36, 0x1A, 0x2A, 0xDC, 0xF1, 0x2A, 0x07, 0x3C, 0xFC, 0xD3, 0x01,
- 0x44, 0xFF, 0x32, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x2C, 0x00, 0x57,
- 0xFF, 0xB3, 0x01, 0x64, 0xFC, 0x13, 0x07, 0x83, 0xF1, 0x2C, 0x2F,
- 0x5A, 0x31, 0x7D, 0xF1, 0xF7, 0x06, 0x80, 0xFC, 0x9F, 0x01, 0x61,
- 0xFF, 0x29, 0x00, 0xFD, 0xFF, 0xFD, 0xFF, 0x34, 0x00, 0x3F, 0xFF,
- 0xDD, 0x01, 0x34, 0xFC, 0x23, 0x07, 0x21, 0xF2, 0xCB, 0x27, 0xFE,
- 0x37, 0x00, 0xF2, 0x4D, 0x06, 0x04, 0xFD, 0x49, 0x01, 0x8E, 0xFF,
- 0x19, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0x36, 0x00, 0x36, 0xFF, 0xE6,
- 0x01, 0x41, 0xFC, 0xC8, 0x06, 0x76, 0xF3, 0x22, 0x20, 0xCA, 0x3D,
- 0x7D, 0xF3, 0x2A, 0x05, 0xC8, 0xFD, 0xD4, 0x00, 0xCA, 0xFF, 0x03,
- 0x00, 0x02, 0x00, 0xFE, 0xFF, 0x34, 0x00, 0x3B, 0xFF, 0xD1, 0x01,
- 0x84, 0xFC, 0x12, 0x06, 0x5C, 0xF5, 0x76, 0x18, 0x89, 0x42, 0x02,
- 0xF6, 0x94, 0x03, 0xC4, 0xFE, 0x42, 0x00, 0x12, 0x00, 0xE8, 0xFF,
- 0x07, 0x00, 0xFF, 0xFF, 0x2F, 0x00, 0x4C, 0xFF, 0xA2, 0x01, 0xF6,
- 0xFC, 0x12, 0x05, 0xA7, 0xF7, 0x03, 0x11, 0x10, 0x46, 0x93, 0xF9,
- 0x98, 0x01, 0xEE, 0xFF, 0x9B, 0xFF, 0x64, 0x00, 0xC8, 0xFF, 0x0E,
- 0x00, 0x00, 0x00, 0x27, 0x00, 0x65, 0xFF, 0x60, 0x01, 0x8A, 0xFD,
- 0xDF, 0x03, 0x2E, 0xFA, 0x04, 0x0A, 0x3A, 0x48, 0x28, 0xFE, 0x4B,
- 0xFF, 0x38, 0x01, 0xE9, 0xFE, 0xBB, 0x00, 0xA6, 0xFF, 0x16, 0x00,
- 0x00, 0x00, 0x1E, 0x00, 0x84, 0xFF, 0x11, 0x01, 0x34, 0xFE, 0x8F,
- 0x02, 0xC7, 0xFC, 0xAE, 0x03, 0xF7, 0x48, 0xAE, 0x03, 0xC7, 0xFC,
- 0x8F, 0x02, 0x34, 0xFE, 0x11, 0x01, 0x84, 0xFF, 0x1E, 0x00, 0x00,
- 0x00, 0xF4, 0xFF, 0x1A, 0x00, 0xFF, 0x00, 0x07, 0x03, 0x16, 0x06,
- 0x7C, 0x09, 0x2A, 0x0C, 0x2E, 0x0D, 0x2A, 0x0C, 0x7C, 0x09, 0x16,
- 0x06, 0x07, 0x03, 0xFF, 0x00, 0x1A, 0x00, 0xF4, 0xFF, 0xF2, 0xFF,
- 0xA0, 0xFF, 0x71, 0xFF, 0x71, 0x00, 0x86, 0x03, 0x73, 0x08, 0x88,
- 0x0D, 0x78, 0x10, 0xC9, 0x0F, 0xD5, 0x0B, 0x8B, 0x06, 0x28, 0x02,
- 0xDF, 0xFF, 0x6F, 0xFF, 0xC3, 0xFF, 0xFD, 0xFF, 0x00, 0x00, 0xDC,
- 0xFF, 0x80, 0xFF, 0x9A, 0xFF, 0x46, 0x01, 0x1E, 0x05, 0x5A, 0x0A,
- 0xED, 0x0E, 0xAA, 0x10, 0xAF, 0x0E, 0xFD, 0x09, 0xCB, 0x04, 0x18,
- 0x01, 0x8E, 0xFF, 0x85, 0xFF, 0xE1, 0xFF, 0xFC, 0xFF, 0xBD, 0xFF,
- 0x6D, 0xFF, 0xF6, 0xFF, 0x65, 0x02, 0xE5, 0x06, 0x2B, 0x0C, 0xF3,
- 0x0F, 0x60, 0x10, 0x3B, 0x0D, 0x16, 0x08, 0x3F, 0x03, 0x50, 0x00,
- 0x6E, 0xFF, 0xA7, 0xFF, 0xF5, 0xFF, 0xEF, 0xFF, 0x9A, 0xFF, 0x75,
- 0xFF, 0x91, 0x00, 0xC9, 0x03, 0xC8, 0x08, 0xCC, 0x0D, 0x89, 0x10,
- 0x9F, 0x0F, 0x85, 0x0B, 0x3B, 0x06, 0xF4, 0x01, 0xCD, 0xFF, 0x72,
- 0xFF, 0xC9, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0xD7, 0xFF, 0x7B, 0xFF,
- 0xA5, 0xFF, 0x73, 0x01, 0x6A, 0x05, 0xAD, 0x0A, 0x21, 0x0F, 0xA6,
- 0x10, 0x74, 0x0E, 0xA9, 0x09, 0x83, 0x04, 0xF0, 0x00, 0x85, 0xFF,
- 0x8B, 0xFF, 0xE5, 0xFF, 0xFA, 0xFF, 0xB7, 0xFF, 0x6C, 0xFF, 0x0C,
- 0x00, 0x9D, 0x02, 0x37, 0x07, 0x78, 0x0C, 0x15, 0x10, 0x47, 0x10,
- 0xF3, 0x0C, 0xC2, 0x07, 0x01, 0x03, 0x35, 0x00, 0x6D, 0xFF, 0xAD,
- 0xFF, 0xF7, 0xFF, 0xEB, 0xFF, 0x94, 0xFF, 0x7A, 0xFF, 0xB3, 0x00,
- 0x0D, 0x04, 0x1C, 0x09, 0x0D, 0x0E, 0x97, 0x10, 0x73, 0x0F, 0x35,
- 0x0B, 0xEB, 0x05, 0xC1, 0x01, 0xBD, 0xFF, 0x75, 0xFF, 0xCE, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0xFF, 0x77, 0xFF, 0xB3, 0xFF, 0xA1,
- 0x01, 0xB7, 0x05, 0xFF, 0x0A, 0x53, 0x0F, 0x9E, 0x10, 0x37, 0x0E,
- 0x55, 0x09, 0x3B, 0x04, 0xCB, 0x00, 0x7E, 0xFF, 0x90, 0xFF, 0xE9,
- 0xFF, 0xF8, 0xFF, 0xB1, 0xFF, 0x6C, 0xFF, 0x24, 0x00, 0xD8, 0x02,
- 0x8A, 0x07, 0xC2, 0x0C, 0x34, 0x10, 0x2A, 0x10, 0xAA, 0x0C, 0x6F,
- 0x07, 0xC4, 0x02, 0x1C, 0x00, 0x6C, 0xFF, 0xB3, 0xFF, 0xF9, 0xFF,
- 0xE8, 0xFF, 0x8E, 0xFF, 0x80, 0xFF, 0xD7, 0x00, 0x53, 0x04, 0x71,
- 0x09, 0x4C, 0x0E, 0xA1, 0x10, 0x43, 0x0F, 0xE3, 0x0A, 0x9D, 0x05,
- 0x91, 0x01, 0xAE, 0xFF, 0x79, 0xFF, 0xD4, 0xFF, 0x00, 0x00, 0xFF,
- 0xFF, 0xCD, 0xFF, 0x74, 0xFF, 0xC2, 0xFF, 0xD2, 0x01, 0x06, 0x06,
- 0x50, 0x0B, 0x82, 0x0F, 0x93, 0x10, 0xF8, 0x0D, 0x00, 0x09, 0xF6,
- 0x03, 0xA7, 0x00, 0x78, 0xFF, 0x96, 0xFF, 0xEC, 0xFF, 0xF6, 0xFF,
- 0xAB, 0xFF, 0x6D, 0xFF, 0x3E, 0x00, 0x15, 0x03, 0xDE, 0x07, 0x0B,
- 0x0D, 0x50, 0x10, 0x0A, 0x10, 0x5E, 0x0C, 0x1C, 0x07, 0x8A, 0x02,
- 0x04, 0x00, 0x6C, 0xFF, 0xB9, 0xFF, 0xFB, 0xFF, 0xE4, 0xFF, 0x89,
- 0xFF, 0x88, 0xFF, 0xFD, 0x00, 0x9B, 0x04, 0xC5, 0x09, 0x88, 0x0E,
- 0xA8, 0x10, 0x10, 0x0F, 0x91, 0x0A, 0x50, 0x05, 0x64, 0x01, 0xA1,
- 0xFF, 0x7D, 0xFF, 0xD9, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0xFF,
- 0x71, 0xFF, 0xD3, 0xFF, 0x05, 0x02, 0x55, 0x06, 0xA0, 0x0B, 0xAD,
- 0x0F, 0x84, 0x10, 0xB6, 0x0D, 0xAC, 0x08, 0xB3, 0x03, 0x86, 0x00,
- 0x74, 0xFF, 0x9C, 0xFF, 0xF0, 0xFF, 0xF4, 0xFF, 0xA5, 0xFF, 0x6F,
- 0xFF, 0x5A, 0x00, 0x54, 0x03, 0x32, 0x08, 0x52, 0x0D, 0x68, 0x10,
- 0xE6, 0x0F, 0x11, 0x0C, 0xCA, 0x06, 0x52, 0x02, 0xEF, 0xFF, 0x6E,
- 0xFF, 0xBF, 0xFF, 0xFC, 0xFF, 0xDF, 0xFF, 0x84, 0xFF, 0x91, 0xFF,
- 0x25, 0x01, 0xE4, 0x04, 0x19, 0x0A, 0xC2, 0x0E, 0xAA, 0x10, 0xDA,
- 0x0E, 0x3E, 0x0A, 0x05, 0x05, 0x38, 0x01, 0x96, 0xFF, 0x81, 0xFF,
- 0xDD, 0xFF, 0x00, 0x00, 0xFD, 0xFF, 0xC1, 0xFF, 0x6E, 0xFF, 0xE6,
- 0xFF, 0x3A, 0x02, 0xA6, 0x06, 0xEF, 0x0B, 0xD6, 0x0F, 0x71, 0x10,
- 0x71, 0x0D, 0x57, 0x08, 0x71, 0x03, 0x67, 0x00, 0x70, 0xFF, 0xA2,
- 0xFF, 0xF3, 0xFF, 0xF1, 0xFF, 0x9F, 0xFF, 0x72, 0xFF, 0x78, 0x00,
- 0x95, 0x03, 0x86, 0x08, 0x98, 0x0D, 0x7C, 0x10, 0xC0, 0x0F, 0xC3,
- 0x0B, 0x79, 0x06, 0x1C, 0x02, 0xDB, 0xFF, 0x70, 0xFF, 0xC5, 0xFF,
- 0xFE, 0xFF, 0x00, 0x00, 0xDB, 0xFF, 0x7F, 0xFF, 0x9C, 0xFF, 0x50,
- 0x01, 0x2F, 0x05, 0x6C, 0x0A, 0xF9, 0x0E, 0xA9, 0x10, 0xA2, 0x0E,
- 0xEA, 0x09, 0xBB, 0x04, 0x0F, 0x01, 0x8C, 0xFF, 0x87, 0xFF, 0xE2,
- 0xFF, 0xFC, 0xFF, 0xBC, 0xFF, 0x6D, 0xFF, 0xFA, 0xFF, 0x71, 0x02,
- 0xF7, 0x06, 0x3C, 0x0C, 0xFB, 0x0F, 0x5B, 0x10, 0x2B, 0x0D, 0x03,
- 0x08, 0x31, 0x03, 0x4A, 0x00, 0x6E, 0xFF, 0xA8, 0xFF, 0xF5, 0xFF,
- 0xEE, 0xFF, 0x99, 0xFF, 0x76, 0xFF, 0x98, 0x00, 0xD8, 0x03, 0xDB,
- 0x08, 0xDB, 0x0D, 0x8D, 0x10, 0x96, 0x0F, 0x73, 0x0B, 0x29, 0x06,
- 0xE8, 0x01, 0xC9, 0xFF, 0x72, 0xFF, 0xCA, 0xFF, 0xFE, 0xFF, 0x00,
- 0x00, 0xD6, 0xFF, 0x7A, 0xFF, 0xA8, 0xFF, 0x7D, 0x01, 0x7B, 0x05,
- 0xBF, 0x0A, 0x2D, 0x0F, 0xA5, 0x10, 0x67, 0x0E, 0x96, 0x09, 0x73,
- 0x04, 0xE7, 0x00, 0x84, 0xFF, 0x8C, 0xFF, 0xE6, 0xFF, 0xFA, 0xFF,
- 0xB6, 0xFF, 0x6C, 0xFF, 0x11, 0x00, 0xAA, 0x02, 0x4A, 0x07, 0x88,
- 0x0C, 0x1C, 0x10, 0x41, 0x10, 0xE3, 0x0C, 0xAF, 0x07, 0xF3, 0x02,
- 0x2F, 0x00, 0x6C, 0xFF, 0xAE, 0xFF, 0xF7, 0xFF, 0xEA, 0xFF, 0x93,
- 0xFF, 0x7B, 0xFF, 0xBB, 0x00, 0x1C, 0x04, 0x2F, 0x09, 0x1B, 0x0E,
- 0x9A, 0x10, 0x68, 0x0F, 0x23, 0x0B, 0xDA, 0x05, 0xB7, 0x01, 0xB9,
- 0xFF, 0x76, 0xFF, 0xD0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, 0xFF,
- 0x76, 0xFF, 0xB6, 0xFF, 0xAC, 0x01, 0xC8, 0x05, 0x11, 0x0B, 0x5E,
- 0x0F, 0x9C, 0x10, 0x29, 0x0E, 0x42, 0x09, 0x2C, 0x04, 0xC2, 0x00,
- 0x7D, 0xFF, 0x92, 0xFF, 0xEA, 0xFF, 0xF8, 0xFF, 0xB0, 0xFF, 0x6C,
- 0xFF, 0x29, 0x00, 0xE6, 0x02, 0x9D, 0x07, 0xD3, 0x0C, 0x3B, 0x10,
- 0x23, 0x10, 0x99, 0x0C, 0x5C, 0x07, 0xB7, 0x02, 0x16, 0x00, 0x6C,
- 0xFF, 0xB4, 0xFF, 0xF9, 0xFF, 0xE7, 0xFF, 0x8D, 0xFF, 0x82, 0xFF,
- 0xDF, 0x00, 0x63, 0x04, 0x84, 0x09, 0x59, 0x0E, 0xA3, 0x10, 0x38,
- 0x0F, 0xD1, 0x0A, 0x8C, 0x05, 0x87, 0x01, 0xAB, 0xFF, 0x79, 0xFF,
- 0xD5, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xCB, 0xFF, 0x73, 0xFF, 0xC6,
- 0xFF, 0xDD, 0x01, 0x17, 0x06, 0x62, 0x0B, 0x8C, 0x0F, 0x90, 0x10,
- 0xE9, 0x0D, 0xED, 0x08, 0xE7, 0x03, 0xA0, 0x00, 0x77, 0xFF, 0x97,
- 0xFF, 0xED, 0xFF, 0xF6, 0xFF, 0xA9, 0xFF, 0x6D, 0xFF, 0x44, 0x00,
- 0x23, 0x03, 0xF1, 0x07, 0x1B, 0x0D, 0x55, 0x10, 0x02, 0x10, 0x4D,
- 0x0C, 0x0A, 0x07, 0x7E, 0x02, 0xFF, 0xFF, 0x6D, 0xFF, 0xBA, 0xFF,
- 0xFB, 0xFF, 0xE3, 0xFF, 0x88, 0xFF, 0x8A, 0xFF, 0x06, 0x01, 0xAB,
- 0x04, 0xD8, 0x09, 0x95, 0x0E, 0xA9, 0x10, 0x05, 0x0F, 0x7F, 0x0A,
- 0x40, 0x05, 0x5A, 0x01, 0x9F, 0xFF, 0x7E, 0xFF, 0xDA, 0xFF, 0x00,
- 0x00, 0xFE, 0xFF, 0xC6, 0xFF, 0x70, 0xFF, 0xD7, 0xFF, 0x10, 0x02,
- 0x67, 0x06, 0xB1, 0x0B, 0xB7, 0x0F, 0x80, 0x10, 0xA7, 0x0D, 0x99,
- 0x08, 0xA4, 0x03, 0x7F, 0x00, 0x73, 0xFF, 0x9D, 0xFF, 0xF0, 0xFF,
- 0xF3, 0xFF, 0xA3, 0xFF, 0x70, 0xFF, 0x60, 0x00, 0x62, 0x03, 0x45,
- 0x08, 0x62, 0x0D, 0x6C, 0x10, 0xDE, 0x0F, 0x00, 0x0C, 0xB8, 0x06,
- 0x46, 0x02, 0xEA, 0xFF, 0x6E, 0xFF, 0xC0, 0xFF, 0xFD, 0xFF, 0x00,
- 0x00, 0xDE, 0xFF, 0x83, 0xFF, 0x94, 0xFF, 0x2F, 0x01, 0xF4, 0x04,
- 0x2B, 0x0A, 0xCE, 0x0E, 0xAA, 0x10, 0xCE, 0x0E, 0x2B, 0x0A, 0xF4,
- 0x04, 0x2F, 0x01, 0x94, 0xFF, 0x83, 0xFF, 0xDE, 0xFF, 0xFD, 0xFF,
- 0xC0, 0xFF, 0x6E, 0xFF, 0xEA, 0xFF, 0x46, 0x02, 0xB8, 0x06, 0x00,
- 0x0C, 0xDE, 0x0F, 0x6C, 0x10, 0x62, 0x0D, 0x45, 0x08, 0x62, 0x03,
- 0x60, 0x00, 0x70, 0xFF, 0xA3, 0xFF, 0xF3, 0xFF, 0xF0, 0xFF, 0x9D,
- 0xFF, 0x73, 0xFF, 0x7F, 0x00, 0xA4, 0x03, 0x99, 0x08, 0xA7, 0x0D,
- 0x80, 0x10, 0xB7, 0x0F, 0xB1, 0x0B, 0x67, 0x06, 0x10, 0x02, 0xD7,
- 0xFF, 0x70, 0xFF, 0xC6, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0xDA, 0xFF,
- 0x7E, 0xFF, 0x9F, 0xFF, 0x5A, 0x01, 0x40, 0x05, 0x7F, 0x0A, 0x05,
- 0x0F, 0xA9, 0x10, 0x95, 0x0E, 0xD8, 0x09, 0xAB, 0x04, 0x06, 0x01,
- 0x8A, 0xFF, 0x88, 0xFF, 0xE3, 0xFF, 0xFB, 0xFF, 0xBA, 0xFF, 0x6D,
- 0xFF, 0xFF, 0xFF, 0x7E, 0x02, 0x0A, 0x07, 0x4D, 0x0C, 0x02, 0x10,
- 0x55, 0x10, 0x1B, 0x0D, 0xF1, 0x07, 0x23, 0x03, 0x44, 0x00, 0x6D,
- 0xFF, 0xA9, 0xFF, 0xF6, 0xFF, 0xED, 0xFF, 0x97, 0xFF, 0x77, 0xFF,
- 0xA0, 0x00, 0xE7, 0x03, 0xED, 0x08, 0xE9, 0x0D, 0x90, 0x10, 0x8C,
- 0x0F, 0x62, 0x0B, 0x17, 0x06, 0xDD, 0x01, 0xC6, 0xFF, 0x73, 0xFF,
- 0xCB, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xD5, 0xFF, 0x79, 0xFF, 0xAB,
- 0xFF, 0x87, 0x01, 0x8C, 0x05, 0xD1, 0x0A, 0x38, 0x0F, 0xA3, 0x10,
- 0x59, 0x0E, 0x84, 0x09, 0x63, 0x04, 0xDF, 0x00, 0x82, 0xFF, 0x8D,
- 0xFF, 0xE7, 0xFF, 0xF9, 0xFF, 0xB4, 0xFF, 0x6C, 0xFF, 0x16, 0x00,
- 0xB7, 0x02, 0x5C, 0x07, 0x99, 0x0C, 0x23, 0x10, 0x3B, 0x10, 0xD3,
- 0x0C, 0x9D, 0x07, 0xE6, 0x02, 0x29, 0x00, 0x6C, 0xFF, 0xB0, 0xFF,
- 0xF8, 0xFF, 0xEA, 0xFF, 0x92, 0xFF, 0x7D, 0xFF, 0xC2, 0x00, 0x2C,
- 0x04, 0x42, 0x09, 0x29, 0x0E, 0x9C, 0x10, 0x5E, 0x0F, 0x11, 0x0B,
- 0xC8, 0x05, 0xAC, 0x01, 0xB6, 0xFF, 0x76, 0xFF, 0xD1, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xD0, 0xFF, 0x76, 0xFF, 0xB9, 0xFF, 0xB7, 0x01,
- 0xDA, 0x05, 0x23, 0x0B, 0x68, 0x0F, 0x9A, 0x10, 0x1B, 0x0E, 0x2F,
- 0x09, 0x1C, 0x04, 0xBB, 0x00, 0x7B, 0xFF, 0x93, 0xFF, 0xEA, 0xFF,
- 0xF7, 0xFF, 0xAE, 0xFF, 0x6C, 0xFF, 0x2F, 0x00, 0xF3, 0x02, 0xAF,
- 0x07, 0xE3, 0x0C, 0x41, 0x10, 0x1C, 0x10, 0x88, 0x0C, 0x4A, 0x07,
- 0xAA, 0x02, 0x11, 0x00, 0x6C, 0xFF, 0xB6, 0xFF, 0xFA, 0xFF, 0xE6,
- 0xFF, 0x8C, 0xFF, 0x84, 0xFF, 0xE7, 0x00, 0x73, 0x04, 0x96, 0x09,
- 0x67, 0x0E, 0xA5, 0x10, 0x2D, 0x0F, 0xBF, 0x0A, 0x7B, 0x05, 0x7D,
- 0x01, 0xA8, 0xFF, 0x7A, 0xFF, 0xD6, 0xFF, 0x00, 0x00, 0xFE, 0xFF,
- 0xCA, 0xFF, 0x72, 0xFF, 0xC9, 0xFF, 0xE8, 0x01, 0x29, 0x06, 0x73,
- 0x0B, 0x96, 0x0F, 0x8D, 0x10, 0xDB, 0x0D, 0xDB, 0x08, 0xD8, 0x03,
- 0x98, 0x00, 0x76, 0xFF, 0x99, 0xFF, 0xEE, 0xFF, 0xF5, 0xFF, 0xA8,
- 0xFF, 0x6E, 0xFF, 0x4A, 0x00, 0x31, 0x03, 0x03, 0x08, 0x2B, 0x0D,
- 0x5B, 0x10, 0xFB, 0x0F, 0x3C, 0x0C, 0xF7, 0x06, 0x71, 0x02, 0xFA,
- 0xFF, 0x6D, 0xFF, 0xBC, 0xFF, 0xFC, 0xFF, 0xE2, 0xFF, 0x87, 0xFF,
- 0x8C, 0xFF, 0x0F, 0x01, 0xBB, 0x04, 0xEA, 0x09, 0xA2, 0x0E, 0xA9,
- 0x10, 0xF9, 0x0E, 0x6C, 0x0A, 0x2F, 0x05, 0x50, 0x01, 0x9C, 0xFF,
- 0x7F, 0xFF, 0xDB, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xC5, 0xFF, 0x70,
- 0xFF, 0xDB, 0xFF, 0x1C, 0x02, 0x79, 0x06, 0xC3, 0x0B, 0xC0, 0x0F,
- 0x7C, 0x10, 0x98, 0x0D, 0x86, 0x08, 0x95, 0x03, 0x78, 0x00, 0x72,
- 0xFF, 0x9F, 0xFF, 0xF1, 0xFF, 0xF3, 0xFF, 0xA2, 0xFF, 0x70, 0xFF,
- 0x67, 0x00, 0x71, 0x03, 0x57, 0x08, 0x71, 0x0D, 0x71, 0x10, 0xD6,
- 0x0F, 0xEF, 0x0B, 0xA6, 0x06, 0x3A, 0x02, 0xE6, 0xFF, 0x6E, 0xFF,
- 0xC1, 0xFF, 0xFD, 0xFF, 0x00, 0x00, 0xDD, 0xFF, 0x81, 0xFF, 0x96,
- 0xFF, 0x38, 0x01, 0x05, 0x05, 0x3E, 0x0A, 0xDA, 0x0E, 0xAA, 0x10,
- 0xC2, 0x0E, 0x19, 0x0A, 0xE4, 0x04, 0x25, 0x01, 0x91, 0xFF, 0x84,
- 0xFF, 0xDF, 0xFF, 0xFC, 0xFF, 0xBF, 0xFF, 0x6E, 0xFF, 0xEF, 0xFF,
- 0x52, 0x02, 0xCA, 0x06, 0x11, 0x0C, 0xE6, 0x0F, 0x68, 0x10, 0x52,
- 0x0D, 0x32, 0x08, 0x54, 0x03, 0x5A, 0x00, 0x6F, 0xFF, 0xA5, 0xFF,
- 0xF4, 0xFF, 0xF0, 0xFF, 0x9C, 0xFF, 0x74, 0xFF, 0x86, 0x00, 0xB3,
- 0x03, 0xAC, 0x08, 0xB6, 0x0D, 0x84, 0x10, 0xAD, 0x0F, 0xA0, 0x0B,
- 0x55, 0x06, 0x05, 0x02, 0xD3, 0xFF, 0x71, 0xFF, 0xC7, 0xFF, 0xFE,
- 0xFF, 0x00, 0x00, 0xD9, 0xFF, 0x7D, 0xFF, 0xA1, 0xFF, 0x64, 0x01,
- 0x50, 0x05, 0x91, 0x0A, 0x10, 0x0F, 0xA8, 0x10, 0x88, 0x0E, 0xC5,
- 0x09, 0x9B, 0x04, 0xFD, 0x00, 0x88, 0xFF, 0x89, 0xFF, 0xE4, 0xFF,
- 0xFB, 0xFF, 0xB9, 0xFF, 0x6C, 0xFF, 0x04, 0x00, 0x8A, 0x02, 0x1C,
- 0x07, 0x5E, 0x0C, 0x0A, 0x10, 0x50, 0x10, 0x0B, 0x0D, 0xDE, 0x07,
- 0x15, 0x03, 0x3E, 0x00, 0x6D, 0xFF, 0xAB, 0xFF, 0xF6, 0xFF, 0xEC,
- 0xFF, 0x96, 0xFF, 0x78, 0xFF, 0xA7, 0x00, 0xF6, 0x03, 0x00, 0x09,
- 0xF8, 0x0D, 0x93, 0x10, 0x82, 0x0F, 0x50, 0x0B, 0x06, 0x06, 0xD2,
- 0x01, 0xC2, 0xFF, 0x74, 0xFF, 0xCD, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
- 0xD4, 0xFF, 0x79, 0xFF, 0xAE, 0xFF, 0x91, 0x01, 0x9D, 0x05, 0xE3,
- 0x0A, 0x43, 0x0F, 0xA1, 0x10, 0x4C, 0x0E, 0x71, 0x09, 0x53, 0x04,
- 0xD7, 0x00, 0x80, 0xFF, 0x8E, 0xFF, 0xE8, 0xFF, 0xF9, 0xFF, 0xB3,
- 0xFF, 0x6C, 0xFF, 0x1C, 0x00, 0xC4, 0x02, 0x6F, 0x07, 0xAA, 0x0C,
- 0x2A, 0x10, 0x34, 0x10, 0xC2, 0x0C, 0x8A, 0x07, 0xD8, 0x02, 0x24,
- 0x00, 0x6C, 0xFF, 0xB1, 0xFF, 0xF8, 0xFF, 0xE9, 0xFF, 0x90, 0xFF,
- 0x7E, 0xFF, 0xCB, 0x00, 0x3B, 0x04, 0x55, 0x09, 0x37, 0x0E, 0x9E,
- 0x10, 0x53, 0x0F, 0xFF, 0x0A, 0xB7, 0x05, 0xA1, 0x01, 0xB3, 0xFF,
- 0x77, 0xFF, 0xD2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCE, 0xFF, 0x75,
- 0xFF, 0xBD, 0xFF, 0xC1, 0x01, 0xEB, 0x05, 0x35, 0x0B, 0x73, 0x0F,
- 0x97, 0x10, 0x0D, 0x0E, 0x1C, 0x09, 0x0D, 0x04, 0xB3, 0x00, 0x7A,
- 0xFF, 0x94, 0xFF, 0xEB, 0xFF, 0xF7, 0xFF, 0xAD, 0xFF, 0x6D, 0xFF,
- 0x35, 0x00, 0x01, 0x03, 0xC2, 0x07, 0xF3, 0x0C, 0x47, 0x10, 0x15,
- 0x10, 0x78, 0x0C, 0x37, 0x07, 0x9D, 0x02, 0x0C, 0x00, 0x6C, 0xFF,
- 0xB7, 0xFF, 0xFA, 0xFF, 0xE5, 0xFF, 0x8B, 0xFF, 0x85, 0xFF, 0xF0,
- 0x00, 0x83, 0x04, 0xA9, 0x09, 0x74, 0x0E, 0xA6, 0x10, 0x21, 0x0F,
- 0xAD, 0x0A, 0x6A, 0x05, 0x73, 0x01, 0xA5, 0xFF, 0x7B, 0xFF, 0xD7,
- 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xC9, 0xFF, 0x72, 0xFF, 0xCD, 0xFF,
- 0xF4, 0x01, 0x3B, 0x06, 0x85, 0x0B, 0x9F, 0x0F, 0x89, 0x10, 0xCC,
- 0x0D, 0xC8, 0x08, 0xC9, 0x03, 0x91, 0x00, 0x75, 0xFF, 0x9A, 0xFF,
- 0xEF, 0xFF, 0xF5, 0xFF, 0xA7, 0xFF, 0x6E, 0xFF, 0x50, 0x00, 0x3F,
- 0x03, 0x16, 0x08, 0x3B, 0x0D, 0x60, 0x10, 0xF3, 0x0F, 0x2B, 0x0C,
- 0xE5, 0x06, 0x65, 0x02, 0xF6, 0xFF, 0x6D, 0xFF, 0xBD, 0xFF, 0xFC,
- 0xFF, 0xE1, 0xFF, 0x85, 0xFF, 0x8E, 0xFF, 0x18, 0x01, 0xCB, 0x04,
- 0xFD, 0x09, 0xAF, 0x0E, 0xAA, 0x10, 0xED, 0x0E, 0x5A, 0x0A, 0x1E,
- 0x05, 0x46, 0x01, 0x9A, 0xFF, 0x80, 0xFF, 0xDC, 0xFF, 0x00, 0x00,
- 0xFD, 0xFF, 0xC3, 0xFF, 0x6F, 0xFF, 0xDF, 0xFF, 0x28, 0x02, 0x8B,
- 0x06, 0xD5, 0x0B, 0xC9, 0x0F, 0x78, 0x10, 0x88, 0x0D, 0x73, 0x08,
- 0x86, 0x03, 0x71, 0x00, 0x71, 0xFF, 0xA0, 0xFF, 0xF2, 0xFF, 0xF2,
- 0xFF, 0xA1, 0xFF, 0x71, 0xFF, 0x6E, 0x00, 0x7F, 0x03, 0x6A, 0x08,
- 0x81, 0x0D, 0x76, 0x10, 0xCD, 0x0F, 0xDD, 0x0B, 0x94, 0x06, 0x2E,
- 0x02, 0xE1, 0xFF, 0x6F, 0xFF, 0xC3, 0xFF, 0xFD, 0xFF, 0x00, 0x00,
- 0xDC, 0xFF, 0x80, 0xFF, 0x98, 0xFF, 0x42, 0x01, 0x16, 0x05, 0x50,
- 0x0A, 0xE7, 0x0E, 0xAA, 0x10, 0xB5, 0x0E, 0x06, 0x0A, 0xD3, 0x04,
- 0x1C, 0x01, 0x8F, 0xFF, 0x85, 0xFF, 0xE0, 0xFF, 0xFC, 0xFF, 0xBE,
- 0xFF, 0x6D, 0xFF, 0xF3, 0xFF, 0x5E, 0x02, 0xDC, 0x06, 0x23, 0x0C,
- 0xEF, 0x0F, 0x63, 0x10, 0x43, 0x0D, 0x1F, 0x08, 0x46, 0x03, 0x53,
- 0x00, 0x6E, 0xFF, 0xA6, 0xFF, 0xF4, 0xFF, 0xEF, 0xFF, 0x9B, 0xFF,
- 0x75, 0xFF, 0x8D, 0x00, 0xC1, 0x03, 0xBE, 0x08, 0xC4, 0x0D, 0x88,
- 0x10, 0xA4, 0x0F, 0x8E, 0x0B, 0x43, 0x06, 0xF9, 0x01, 0xCF, 0xFF,
- 0x71, 0xFF, 0xC8, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0xD8, 0xFF, 0x7C,
- 0xFF, 0xA4, 0xFF, 0x6E, 0x01, 0x61, 0x05, 0xA3, 0x0A, 0x1C, 0x0F,
- 0xA7, 0x10, 0x7B, 0x0E, 0xB2, 0x09, 0x8B, 0x04, 0xF4, 0x00, 0x86,
- 0xFF, 0x8A, 0xFF, 0xE4, 0xFF, 0xFA, 0xFF, 0xB8, 0xFF, 0x6C, 0xFF,
- 0x09, 0x00, 0x97, 0x02, 0x2E, 0x07, 0x6F, 0x0C, 0x11, 0x10, 0x4A,
- 0x10, 0xFB, 0x0C, 0xCB, 0x07, 0x07, 0x03, 0x38, 0x00, 0x6D, 0xFF,
- 0xAC, 0xFF, 0xF7, 0xFF, 0xEC, 0xFF, 0x95, 0xFF, 0x79, 0xFF, 0xAF,
- 0x00, 0x05, 0x04, 0x13, 0x09, 0x06, 0x0E, 0x96, 0x10, 0x78, 0x0F,
- 0x3E, 0x0B, 0xF4, 0x05, 0xC7, 0x01, 0xBF, 0xFF, 0x74, 0xFF, 0xCE,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0xFF, 0x78, 0xFF, 0xB1, 0xFF,
- 0x9C, 0x01, 0xAE, 0x05, 0xF6, 0x0A, 0x4E, 0x0F, 0x9F, 0x10, 0x3E,
- 0x0E, 0x5E, 0x09, 0x43, 0x04, 0xCF, 0x00, 0x7F, 0xFF, 0x90, 0xFF,
- 0xE8, 0xFF, 0xF9, 0xFF, 0xB2, 0xFF, 0x6C, 0xFF, 0x21, 0x00, 0xD2,
- 0x02, 0x81, 0x07, 0xBA, 0x0C, 0x31, 0x10, 0x2E, 0x10, 0xB2, 0x0C,
- 0x78, 0x07, 0xCB, 0x02, 0x1E, 0x00, 0x6C, 0xFF, 0xB2, 0xFF, 0xF9,
- 0xFF, 0xE8, 0xFF, 0x8F, 0xFF, 0x80, 0xFF, 0xD3, 0x00, 0x4B, 0x04,
- 0x67, 0x09, 0x45, 0x0E, 0xA0, 0x10, 0x48, 0x0F, 0xEC, 0x0A, 0xA6,
- 0x05, 0x97, 0x01, 0xB0, 0xFF, 0x78, 0xFF, 0xD3, 0xFF, 0x00, 0x00,
- 0xFF, 0xFF, 0xCD, 0xFF, 0x74, 0xFF, 0xC0, 0xFF, 0xCC, 0x01, 0xFD,
- 0x05, 0x47, 0x0B, 0x7D, 0x0F, 0x94, 0x10, 0xFF, 0x0D, 0x0A, 0x09,
- 0xFE, 0x03, 0xAB, 0x00, 0x79, 0xFF, 0x95, 0xFF, 0xEC, 0xFF, 0xF7,
- 0xFF, 0xAC, 0xFF, 0x6D, 0xFF, 0x3B, 0x00, 0x0E, 0x03, 0xD5, 0x07,
- 0x03, 0x0D, 0x4D, 0x10, 0x0E, 0x10, 0x67, 0x0C, 0x25, 0x07, 0x91,
- 0x02, 0x07, 0x00, 0x6C, 0xFF, 0xB8, 0xFF, 0xFB, 0xFF, 0xE4, 0xFF,
- 0x89, 0xFF, 0x87, 0xFF, 0xF9, 0x00, 0x93, 0x04, 0xBC, 0x09, 0x82,
- 0x0E, 0xA7, 0x10, 0x16, 0x0F, 0x9A, 0x0A, 0x59, 0x05, 0x69, 0x01,
- 0xA3, 0xFF, 0x7C, 0xFF, 0xD8, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xC8,
- 0xFF, 0x71, 0xFF, 0xD1, 0xFF, 0xFF, 0x01, 0x4C, 0x06, 0x97, 0x0B,
- 0xA9, 0x0F, 0x86, 0x10, 0xBD, 0x0D, 0xB5, 0x08, 0xBA, 0x03, 0x8A,
- 0x00, 0x74, 0xFF, 0x9B, 0xFF, 0xEF, 0xFF, 0xF4, 0xFF, 0xA5, 0xFF,
- 0x6F, 0xFF, 0x57, 0x00, 0x4D, 0x03, 0x29, 0x08, 0x4B, 0x0D, 0x65,
- 0x10, 0xEB, 0x0F, 0x1A, 0x0C, 0xD3, 0x06, 0x58, 0x02, 0xF1, 0xFF,
- 0x6D, 0xFF, 0xBE, 0xFF, 0xFC, 0xFF, 0xE0, 0xFF, 0x84, 0xFF, 0x90,
- 0xFF, 0x21, 0x01, 0xDC, 0x04, 0x10, 0x0A, 0xBB, 0x0E, 0xAA, 0x10,
- 0xE1, 0x0E, 0x47, 0x0A, 0x0D, 0x05, 0x3D, 0x01, 0x97, 0xFF, 0x81,
- 0xFF, 0xDD, 0xFF, 0x00, 0x00, 0xFD, 0xFF, 0xC2, 0xFF, 0x6F, 0xFF,
- 0xE4, 0xFF, 0x34, 0x02, 0x9D, 0x06, 0xE6, 0x0B, 0xD1, 0x0F, 0x73,
- 0x10, 0x79, 0x0D, 0x61, 0x08, 0x78, 0x03, 0x6A, 0x00, 0x70, 0xFF,
- 0xA1, 0xFF, 0xF2, 0xFF, 0xF1, 0xFF, 0x9F, 0xFF, 0x72, 0xFF, 0x74,
- 0x00, 0x8E, 0x03, 0x7D, 0x08, 0x90, 0x0D, 0x7A, 0x10, 0xC4, 0x0F,
- 0xCC, 0x0B, 0x82, 0x06, 0x22, 0x02, 0xDD, 0xFF, 0x6F, 0xFF, 0xC4,
- 0xFF, 0xFD, 0xFF, 0x00, 0x00, 0xDB, 0xFF, 0x7F, 0xFF, 0x9B, 0xFF,
- 0x4B, 0x01, 0x26, 0x05, 0x63, 0x0A, 0xF3, 0x0E, 0xAA, 0x10, 0xA8,
- 0x0E, 0xF4, 0x09, 0xC3, 0x04, 0x13, 0x01, 0x8D, 0xFF, 0x86, 0xFF,
- 0xE1, 0xFF, 0xFC, 0xFF, 0xBC, 0xFF, 0x6D, 0xFF, 0xF8, 0xFF, 0x6B,
- 0x02, 0xEE, 0x06, 0x34, 0x0C, 0xF7, 0x0F, 0x5D, 0x10, 0x33, 0x0D,
- 0x0D, 0x08, 0x38, 0x03, 0x4D, 0x00, 0x6E, 0xFF, 0xA7, 0xFF, 0xF5,
- 0xFF, 0xEE, 0xFF, 0x99, 0xFF, 0x76, 0xFF, 0x94, 0x00, 0xD0, 0x03,
- 0xD1, 0x08, 0xD3, 0x0D, 0x8B, 0x10, 0x9A, 0x0F, 0x7C, 0x0B, 0x32,
- 0x06, 0xEE, 0x01, 0xCB, 0xFF, 0x72, 0xFF, 0xCA, 0xFF, 0xFE, 0xFF,
- 0x00, 0x00, 0xD6, 0xFF, 0x7B, 0xFF, 0xA7, 0xFF, 0x78, 0x01, 0x72,
- 0x05, 0xB6, 0x0A, 0x27, 0x0F, 0xA5, 0x10, 0x6E, 0x0E, 0xA0, 0x09,
- 0x7B, 0x04, 0xEC, 0x00, 0x85, 0xFF, 0x8B, 0xFF, 0xE5, 0xFF, 0xFA,
- 0xFF, 0xB6, 0xFF, 0x6C, 0xFF, 0x0E, 0x00, 0xA4, 0x02, 0x41, 0x07,
- 0x80, 0x0C, 0x19, 0x10, 0x44, 0x10, 0xEB, 0x0C, 0xB9, 0x07, 0xFA,
- 0x02, 0x32, 0x00, 0x6D, 0xFF, 0xAE, 0xFF, 0xF7, 0xFF, 0xEB, 0xFF,
- 0x93, 0xFF, 0x7B, 0xFF, 0xB7, 0x00, 0x15, 0x04, 0x26, 0x09, 0x14,
- 0x0E, 0x98, 0x10, 0x6D, 0x0F, 0x2C, 0x0B, 0xE3, 0x05, 0xBC, 0x01,
- 0xBB, 0xFF, 0x75, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1,
- 0xFF, 0x77, 0xFF, 0xB5, 0xFF, 0xA6, 0x01, 0xC0, 0x05, 0x08, 0x0B,
- 0x58, 0x0F, 0x9D, 0x10, 0x30, 0x0E, 0x4B, 0x09, 0x34, 0x04, 0xC6,
- 0x00, 0x7D, 0xFF, 0x91, 0xFF, 0xE9, 0xFF, 0xF8, 0xFF, 0xB0, 0xFF,
- 0x6C, 0xFF, 0x27, 0x00, 0xDF, 0x02, 0x94, 0x07, 0xCA, 0x0C, 0x37,
- 0x10, 0x27, 0x10, 0xA1, 0x0C, 0x65, 0x07, 0xBE, 0x02, 0x19, 0x00,
- 0x6C, 0xFF, 0xB4, 0xFF, 0xF9, 0xFF, 0xE7, 0xFF, 0x8E, 0xFF, 0x81,
- 0xFF, 0xDB, 0x00, 0x5B, 0x04, 0x7A, 0x09, 0x53, 0x0E, 0xA2, 0x10,
- 0x3D, 0x0F, 0xDA, 0x0A, 0x95, 0x05, 0x8C, 0x01, 0xAD, 0xFF, 0x79,
- 0xFF, 0xD4, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xCC, 0xFF, 0x73, 0xFF,
- 0xC4, 0xFF, 0xD7, 0x01, 0x0E, 0x06, 0x59, 0x0B, 0x87, 0x0F, 0x91,
- 0x10, 0xF0, 0x0D, 0xF7, 0x08, 0xEF, 0x03, 0xA3, 0x00, 0x78, 0xFF,
- 0x97, 0xFF, 0xED, 0xFF, 0xF6, 0xFF, 0xAA, 0xFF, 0x6D, 0xFF, 0x41,
- 0x00, 0x1C, 0x03, 0xE7, 0x07, 0x13, 0x0D, 0x52, 0x10, 0x06, 0x10,
- 0x56, 0x0C, 0x13, 0x07, 0x84, 0x02, 0x02, 0x00, 0x6D, 0xFF, 0xBA,
- 0xFF, 0xFB, 0xFF, 0xE3, 0xFF, 0x88, 0xFF, 0x89, 0xFF, 0x01, 0x01,
- 0xA3, 0x04, 0xCE, 0x09, 0x8F, 0x0E, 0xA8, 0x10, 0x0A, 0x0F, 0x88,
- 0x0A, 0x48, 0x05, 0x5F, 0x01, 0xA0, 0xFF, 0x7D, 0xFF, 0xD9, 0xFF,
- 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0xFF, 0x70, 0xFF, 0xD5, 0xFF, 0x0B,
- 0x02, 0x5E, 0x06, 0xA9, 0x0B, 0xB2, 0x0F, 0x82, 0x10, 0xAE, 0x0D,
- 0xA2, 0x08, 0xAB, 0x03, 0x82, 0x00, 0x73, 0xFF, 0x9D, 0xFF, 0xF0,
- 0xFF, 0xF3, 0xFF, 0xA4, 0xFF, 0x6F, 0xFF, 0x5D, 0x00, 0x5B, 0x03,
- 0x3B, 0x08, 0x5A, 0x0D, 0x6A, 0x10, 0xE2, 0x0F, 0x09, 0x0C, 0xC1,
- 0x06, 0x4C, 0x02, 0xEC, 0xFF, 0x6E, 0xFF, 0xC0, 0xFF, 0xFC, 0xFF,
- 0xDF, 0xFF, 0x83, 0xFF, 0x93, 0xFF, 0x2A, 0x01, 0xEC, 0x04, 0x22,
- 0x0A, 0xC8, 0x0E, 0xAB, 0x10, 0xD4, 0x0E, 0x35, 0x0A, 0xFD, 0x04,
- 0x33, 0x01, 0x95, 0xFF, 0x82, 0xFF, 0xDE, 0xFF, 0x00, 0x00, 0xFD,
- 0xFF, 0xC1, 0xFF, 0x6E, 0xFF, 0xE8, 0xFF, 0x40, 0x02, 0xAF, 0x06,
- 0xF7, 0x0B, 0xDA, 0x0F, 0x6F, 0x10, 0x6A, 0x0D, 0x4E, 0x08, 0x6A,
- 0x03, 0x64, 0x00, 0x70, 0xFF, 0xA3, 0xFF, 0xF3, 0xFF, 0xF1, 0xFF,
- 0x9E, 0xFF, 0x72, 0xFF, 0x7B, 0x00, 0x9C, 0x03, 0x90, 0x08, 0x9F,
- 0x0D, 0x7E, 0x10, 0xBB, 0x0F, 0xBA, 0x0B, 0x70, 0x06, 0x16, 0x02,
- 0xD9, 0xFF, 0x70, 0xFF, 0xC5, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0xDA,
- 0xFF, 0x7E, 0xFF, 0x9D, 0xFF, 0x55, 0x01, 0x37, 0x05, 0x75, 0x0A,
- 0xFF, 0x0E, 0xA9, 0x10, 0x9C, 0x0E, 0xE1, 0x09, 0xB3, 0x04, 0x0A,
- 0x01, 0x8B, 0xFF, 0x87, 0xFF, 0xE2, 0xFF, 0xFB, 0xFF, 0xBB, 0xFF,
- 0x6D, 0xFF, 0xFD, 0xFF, 0x77, 0x02, 0x01, 0x07, 0x45, 0x0C, 0xFF,
- 0x0F, 0x58, 0x10, 0x23, 0x0D, 0xFA, 0x07, 0x2A, 0x03, 0x47, 0x00,
- 0x6E, 0xFF, 0xA9, 0xFF, 0xF5, 0xFF, 0xED, 0xFF, 0x98, 0xFF, 0x77,
- 0xFF, 0x9C, 0x00, 0xDF, 0x03, 0xE4, 0x08, 0xE2, 0x0D, 0x8E, 0x10,
- 0x91, 0x0F, 0x6B, 0x0B, 0x20, 0x06, 0xE3, 0x01, 0xC8, 0xFF, 0x73,
- 0xFF, 0xCB, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xD5, 0xFF, 0x7A, 0xFF,
- 0xAA, 0xFF, 0x82, 0x01, 0x83, 0x05, 0xC8, 0x0A, 0x32, 0x0F, 0xA4,
- 0x10, 0x60, 0x0E, 0x8D, 0x09, 0x6B, 0x04, 0xE3, 0x00, 0x83, 0xFF,
- 0x8D, 0xFF, 0xE6, 0xFF, 0xFA, 0xFF, 0xB5, 0xFF, 0x6C, 0xFF, 0x14,
- 0x00, 0xB1, 0x02, 0x53, 0x07, 0x91, 0x0C, 0x20, 0x10, 0x3E, 0x10,
- 0xDB, 0x0C, 0xA6, 0x07, 0xEC, 0x02, 0x2C, 0x00, 0x6C, 0xFF, 0xAF,
- 0xFF, 0xF8, 0xFF, 0xEA, 0xFF, 0x92, 0xFF, 0x7C, 0xFF, 0xBE, 0x00,
- 0x24, 0x04, 0x38, 0x09, 0x22, 0x0E, 0x9B, 0x10, 0x63, 0x0F, 0x1A,
- 0x0B, 0xD1, 0x05, 0xB1, 0x01, 0xB8, 0xFF, 0x76, 0xFF, 0xD0, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0xFF, 0x76, 0xFF, 0xB8, 0xFF, 0xB1,
- 0x01, 0xD1, 0x05, 0x1A, 0x0B, 0x63, 0x0F, 0x9B, 0x10, 0x22, 0x0E,
- 0x38, 0x09, 0x24, 0x04, 0xBE, 0x00, 0x7C, 0xFF, 0x92, 0xFF, 0xEA,
- 0xFF, 0xF8, 0xFF, 0xAF, 0xFF, 0x6C, 0xFF, 0x2C, 0x00, 0xEC, 0x02,
- 0xA6, 0x07, 0xDB, 0x0C, 0x3E, 0x10, 0x20, 0x10, 0x91, 0x0C, 0x53,
- 0x07, 0xB1, 0x02, 0x14, 0x00, 0x6C, 0xFF, 0xB5, 0xFF, 0xFA, 0xFF,
- 0xE6, 0xFF, 0x8D, 0xFF, 0x83, 0xFF, 0xE3, 0x00, 0x6B, 0x04, 0x8D,
- 0x09, 0x60, 0x0E, 0xA4, 0x10, 0x32, 0x0F, 0xC8, 0x0A, 0x83, 0x05,
- 0x82, 0x01, 0xAA, 0xFF, 0x7A, 0xFF, 0xD5, 0xFF, 0x00, 0x00, 0xFF,
- 0xFF, 0xCB, 0xFF, 0x73, 0xFF, 0xC8, 0xFF, 0xE3, 0x01, 0x20, 0x06,
- 0x6B, 0x0B, 0x91, 0x0F, 0x8E, 0x10, 0xE2, 0x0D, 0xE4, 0x08, 0xDF,
- 0x03, 0x9C, 0x00, 0x77, 0xFF, 0x98, 0xFF, 0xED, 0xFF, 0xF5, 0xFF,
- 0xA9, 0xFF, 0x6E, 0xFF, 0x47, 0x00, 0x2A, 0x03, 0xFA, 0x07, 0x23,
- 0x0D, 0x58, 0x10, 0xFF, 0x0F, 0x45, 0x0C, 0x01, 0x07, 0x77, 0x02,
- 0xFD, 0xFF, 0x6D, 0xFF, 0xBB, 0xFF, 0xFB, 0xFF, 0xE2, 0xFF, 0x87,
- 0xFF, 0x8B, 0xFF, 0x0A, 0x01, 0xB3, 0x04, 0xE1, 0x09, 0x9C, 0x0E,
- 0xA9, 0x10, 0xFF, 0x0E, 0x75, 0x0A, 0x37, 0x05, 0x55, 0x01, 0x9D,
- 0xFF, 0x7E, 0xFF, 0xDA, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xC5, 0xFF,
- 0x70, 0xFF, 0xD9, 0xFF, 0x16, 0x02, 0x70, 0x06, 0xBA, 0x0B, 0xBB,
- 0x0F, 0x7E, 0x10, 0x9F, 0x0D, 0x90, 0x08, 0x9C, 0x03, 0x7B, 0x00,
- 0x72, 0xFF, 0x9E, 0xFF, 0xF1, 0xFF, 0xF3, 0xFF, 0xA3, 0xFF, 0x70,
- 0xFF, 0x64, 0x00, 0x6A, 0x03, 0x4E, 0x08, 0x6A, 0x0D, 0x6F, 0x10,
- 0xDA, 0x0F, 0xF7, 0x0B, 0xAF, 0x06, 0x40, 0x02, 0xE8, 0xFF, 0x6E,
- 0xFF, 0xC1, 0xFF, 0xFD, 0xFF, 0x00, 0x00, 0xDE, 0xFF, 0x82, 0xFF,
- 0x95, 0xFF, 0x33, 0x01, 0xFD, 0x04, 0x35, 0x0A, 0xD4, 0x0E, 0xAB,
- 0x10, 0xC8, 0x0E, 0x22, 0x0A, 0xEC, 0x04, 0x2A, 0x01, 0x93, 0xFF,
- 0x83, 0xFF, 0xDF, 0xFF, 0xFC, 0xFF, 0xC0, 0xFF, 0x6E, 0xFF, 0xEC,
- 0xFF, 0x4C, 0x02, 0xC1, 0x06, 0x09, 0x0C, 0xE2, 0x0F, 0x6A, 0x10,
- 0x5A, 0x0D, 0x3B, 0x08, 0x5B, 0x03, 0x5D, 0x00, 0x6F, 0xFF, 0xA4,
- 0xFF, 0xF3, 0xFF, 0xF0, 0xFF, 0x9D, 0xFF, 0x73, 0xFF, 0x82, 0x00,
- 0xAB, 0x03, 0xA2, 0x08, 0xAE, 0x0D, 0x82, 0x10, 0xB2, 0x0F, 0xA9,
- 0x0B, 0x5E, 0x06, 0x0B, 0x02, 0xD5, 0xFF, 0x70, 0xFF, 0xC7, 0xFF,
- 0xFE, 0xFF, 0x00, 0x00, 0xD9, 0xFF, 0x7D, 0xFF, 0xA0, 0xFF, 0x5F,
- 0x01, 0x48, 0x05, 0x88, 0x0A, 0x0A, 0x0F, 0xA8, 0x10, 0x8F, 0x0E,
- 0xCE, 0x09, 0xA3, 0x04, 0x01, 0x01, 0x89, 0xFF, 0x88, 0xFF, 0xE3,
- 0xFF, 0xFB, 0xFF, 0xBA, 0xFF, 0x6D, 0xFF, 0x02, 0x00, 0x84, 0x02,
- 0x13, 0x07, 0x56, 0x0C, 0x06, 0x10, 0x52, 0x10, 0x13, 0x0D, 0xE7,
- 0x07, 0x1C, 0x03, 0x41, 0x00, 0x6D, 0xFF, 0xAA, 0xFF, 0xF6, 0xFF,
- 0xED, 0xFF, 0x97, 0xFF, 0x78, 0xFF, 0xA3, 0x00, 0xEF, 0x03, 0xF7,
- 0x08, 0xF0, 0x0D, 0x91, 0x10, 0x87, 0x0F, 0x59, 0x0B, 0x0E, 0x06,
- 0xD7, 0x01, 0xC4, 0xFF, 0x73, 0xFF, 0xCC, 0xFF, 0xFF, 0xFF, 0x00,
- 0x00, 0xD4, 0xFF, 0x79, 0xFF, 0xAD, 0xFF, 0x8C, 0x01, 0x95, 0x05,
- 0xDA, 0x0A, 0x3D, 0x0F, 0xA2, 0x10, 0x53, 0x0E, 0x7A, 0x09, 0x5B,
- 0x04, 0xDB, 0x00, 0x81, 0xFF, 0x8E, 0xFF, 0xE7, 0xFF, 0xF9, 0xFF,
- 0xB4, 0xFF, 0x6C, 0xFF, 0x19, 0x00, 0xBE, 0x02, 0x65, 0x07, 0xA1,
- 0x0C, 0x27, 0x10, 0x37, 0x10, 0xCA, 0x0C, 0x94, 0x07, 0xDF, 0x02,
- 0x27, 0x00, 0x6C, 0xFF, 0xB0, 0xFF, 0xF8, 0xFF, 0xE9, 0xFF, 0x91,
- 0xFF, 0x7D, 0xFF, 0xC6, 0x00, 0x34, 0x04, 0x4B, 0x09, 0x30, 0x0E,
- 0x9D, 0x10, 0x58, 0x0F, 0x08, 0x0B, 0xC0, 0x05, 0xA6, 0x01, 0xB5,
- 0xFF, 0x77, 0xFF, 0xD1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF,
- 0x75, 0xFF, 0xBB, 0xFF, 0xBC, 0x01, 0xE3, 0x05, 0x2C, 0x0B, 0x6D,
- 0x0F, 0x98, 0x10, 0x14, 0x0E, 0x26, 0x09, 0x15, 0x04, 0xB7, 0x00,
- 0x7B, 0xFF, 0x93, 0xFF, 0xEB, 0xFF, 0xF7, 0xFF, 0xAE, 0xFF, 0x6D,
- 0xFF, 0x32, 0x00, 0xFA, 0x02, 0xB9, 0x07, 0xEB, 0x0C, 0x44, 0x10,
- 0x19, 0x10, 0x80, 0x0C, 0x41, 0x07, 0xA4, 0x02, 0x0E, 0x00, 0x6C,
- 0xFF, 0xB6, 0xFF, 0xFA, 0xFF, 0xE5, 0xFF, 0x8B, 0xFF, 0x85, 0xFF,
- 0xEC, 0x00, 0x7B, 0x04, 0xA0, 0x09, 0x6E, 0x0E, 0xA5, 0x10, 0x27,
- 0x0F, 0xB6, 0x0A, 0x72, 0x05, 0x78, 0x01, 0xA7, 0xFF, 0x7B, 0xFF,
- 0xD6, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0xCA, 0xFF, 0x72, 0xFF, 0xCB,
- 0xFF, 0xEE, 0x01, 0x32, 0x06, 0x7C, 0x0B, 0x9A, 0x0F, 0x8B, 0x10,
- 0xD3, 0x0D, 0xD1, 0x08, 0xD0, 0x03, 0x94, 0x00, 0x76, 0xFF, 0x99,
- 0xFF, 0xEE, 0xFF, 0xF5, 0xFF, 0xA7, 0xFF, 0x6E, 0xFF, 0x4D, 0x00,
- 0x38, 0x03, 0x0D, 0x08, 0x33, 0x0D, 0x5D, 0x10, 0xF7, 0x0F, 0x34,
- 0x0C, 0xEE, 0x06, 0x6B, 0x02, 0xF8, 0xFF, 0x6D, 0xFF, 0xBC, 0xFF,
- 0xFC, 0xFF, 0xE1, 0xFF, 0x86, 0xFF, 0x8D, 0xFF, 0x13, 0x01, 0xC3,
- 0x04, 0xF4, 0x09, 0xA8, 0x0E, 0xAA, 0x10, 0xF3, 0x0E, 0x63, 0x0A,
- 0x26, 0x05, 0x4B, 0x01, 0x9B, 0xFF, 0x7F, 0xFF, 0xDB, 0xFF, 0x00,
- 0x00, 0xFD, 0xFF, 0xC4, 0xFF, 0x6F, 0xFF, 0xDD, 0xFF, 0x22, 0x02,
- 0x82, 0x06, 0xCC, 0x0B, 0xC4, 0x0F, 0x7A, 0x10, 0x90, 0x0D, 0x7D,
- 0x08, 0x8E, 0x03, 0x74, 0x00, 0x72, 0xFF, 0x9F, 0xFF, 0xF1, 0xFF,
- 0xF2, 0xFF, 0xA1, 0xFF, 0x70, 0xFF, 0x6A, 0x00, 0x78, 0x03, 0x61,
- 0x08, 0x79, 0x0D, 0x73, 0x10, 0xD1, 0x0F, 0xE6, 0x0B, 0x9D, 0x06,
- 0x34, 0x02, 0xE4, 0xFF, 0x6F, 0xFF, 0xC2, 0xFF, 0xFD, 0xFF, 0x00,
- 0x00, 0xDD, 0xFF, 0x81, 0xFF, 0x97, 0xFF, 0x3D, 0x01, 0x0D, 0x05,
- 0x47, 0x0A, 0xE1, 0x0E, 0xAA, 0x10, 0xBB, 0x0E, 0x10, 0x0A, 0xDC,
- 0x04, 0x21, 0x01, 0x90, 0xFF, 0x84, 0xFF, 0xE0, 0xFF, 0xFC, 0xFF,
- 0xBE, 0xFF, 0x6D, 0xFF, 0xF1, 0xFF, 0x58, 0x02, 0xD3, 0x06, 0x1A,
- 0x0C, 0xEB, 0x0F, 0x65, 0x10, 0x4B, 0x0D, 0x29, 0x08, 0x4D, 0x03,
- 0x57, 0x00, 0x6F, 0xFF, 0xA5, 0xFF, 0xF4, 0xFF, 0xEF, 0xFF, 0x9B,
- 0xFF, 0x74, 0xFF, 0x8A, 0x00, 0xBA, 0x03, 0xB5, 0x08, 0xBD, 0x0D,
- 0x86, 0x10, 0xA9, 0x0F, 0x97, 0x0B, 0x4C, 0x06, 0xFF, 0x01, 0xD1,
- 0xFF, 0x71, 0xFF, 0xC8, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0xD8, 0xFF,
- 0x7C, 0xFF, 0xA3, 0xFF, 0x69, 0x01, 0x59, 0x05, 0x9A, 0x0A, 0x16,
- 0x0F, 0xA7, 0x10, 0x82, 0x0E, 0xBC, 0x09, 0x93, 0x04, 0xF9, 0x00,
- 0x87, 0xFF, 0x89, 0xFF, 0xE4, 0xFF, 0xFB, 0xFF, 0xB8, 0xFF, 0x6C,
- 0xFF, 0x07, 0x00, 0x91, 0x02, 0x25, 0x07, 0x67, 0x0C, 0x0E, 0x10,
- 0x4D, 0x10, 0x03, 0x0D, 0xD5, 0x07, 0x0E, 0x03, 0x3B, 0x00, 0x6D,
- 0xFF, 0xAC, 0xFF, 0xF7, 0xFF, 0xEC, 0xFF, 0x95, 0xFF, 0x79, 0xFF,
- 0xAB, 0x00, 0xFE, 0x03, 0x0A, 0x09, 0xFF, 0x0D, 0x94, 0x10, 0x7D,
- 0x0F, 0x47, 0x0B, 0xFD, 0x05, 0xCC, 0x01, 0xC0, 0xFF, 0x74, 0xFF,
- 0xCD, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xD3, 0xFF, 0x78, 0xFF, 0xB0,
- 0xFF, 0x97, 0x01, 0xA6, 0x05, 0xEC, 0x0A, 0x48, 0x0F, 0xA0, 0x10,
- 0x45, 0x0E, 0x67, 0x09, 0x4B, 0x04, 0xD3, 0x00, 0x80, 0xFF, 0x8F,
- 0xFF, 0xE8, 0xFF, 0xF9, 0xFF, 0xB2, 0xFF, 0x6C, 0xFF, 0x1E, 0x00,
- 0xCB, 0x02, 0x78, 0x07, 0xB2, 0x0C, 0x2E, 0x10, 0x31, 0x10, 0xBA,
- 0x0C, 0x81, 0x07, 0xD2, 0x02, 0x21, 0x00, 0x6C, 0xFF, 0xB2, 0xFF,
- 0xF9, 0xFF, 0xE8, 0xFF, 0x90, 0xFF, 0x7F, 0xFF, 0xCF, 0x00, 0x43,
- 0x04, 0x5E, 0x09, 0x3E, 0x0E, 0x9F, 0x10, 0x4E, 0x0F, 0xF6, 0x0A,
- 0xAE, 0x05, 0x9C, 0x01, 0xB1, 0xFF, 0x78, 0xFF, 0xD2, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xCE, 0xFF, 0x74, 0xFF, 0xBF, 0xFF, 0xC7, 0x01,
- 0xF4, 0x05, 0x3E, 0x0B, 0x78, 0x0F, 0x96, 0x10, 0x06, 0x0E, 0x13,
- 0x09, 0x05, 0x04, 0xAF, 0x00, 0x79, 0xFF, 0x95, 0xFF, 0xEC, 0xFF,
- 0xF7, 0xFF, 0xAC, 0xFF, 0x6D, 0xFF, 0x38, 0x00, 0x07, 0x03, 0xCB,
- 0x07, 0xFB, 0x0C, 0x4A, 0x10, 0x11, 0x10, 0x6F, 0x0C, 0x2E, 0x07,
- 0x97, 0x02, 0x09, 0x00, 0x6C, 0xFF, 0xB8, 0xFF, 0xFA, 0xFF, 0xE4,
- 0xFF, 0x8A, 0xFF, 0x86, 0xFF, 0xF4, 0x00, 0x8B, 0x04, 0xB2, 0x09,
- 0x7B, 0x0E, 0xA7, 0x10, 0x1C, 0x0F, 0xA3, 0x0A, 0x61, 0x05, 0x6E,
- 0x01, 0xA4, 0xFF, 0x7C, 0xFF, 0xD8, 0xFF, 0x00, 0x00, 0xFE, 0xFF,
- 0xC8, 0xFF, 0x71, 0xFF, 0xCF, 0xFF, 0xF9, 0x01, 0x43, 0x06, 0x8E,
- 0x0B, 0xA4, 0x0F, 0x88, 0x10, 0xC4, 0x0D, 0xBE, 0x08, 0xC1, 0x03,
- 0x8D, 0x00, 0x75, 0xFF, 0x9B, 0xFF, 0xEF, 0xFF, 0xF4, 0xFF, 0xA6,
- 0xFF, 0x6E, 0xFF, 0x53, 0x00, 0x46, 0x03, 0x1F, 0x08, 0x43, 0x0D,
- 0x63, 0x10, 0xEF, 0x0F, 0x23, 0x0C, 0xDC, 0x06, 0x5E, 0x02, 0xF3,
- 0xFF, 0x6D, 0xFF, 0xBE, 0xFF, 0xFC, 0xFF, 0xE0, 0xFF, 0x85, 0xFF,
- 0x8F, 0xFF, 0x1C, 0x01, 0xD3, 0x04, 0x06, 0x0A, 0xB5, 0x0E, 0xAA,
- 0x10, 0xE7, 0x0E, 0x50, 0x0A, 0x16, 0x05, 0x42, 0x01, 0x98, 0xFF,
- 0x80, 0xFF, 0xDC, 0xFF, 0x00, 0x00, 0xFD, 0xFF, 0xC3, 0xFF, 0x6F,
- 0xFF, 0xE1, 0xFF, 0x2E, 0x02, 0x94, 0x06, 0xDD, 0x0B, 0xCD, 0x0F,
- 0x76, 0x10, 0x81, 0x0D, 0x6A, 0x08, 0x7F, 0x03, 0x6E, 0x00, 0x71,
- 0xFF, 0xA1, 0xFF, 0xF2, 0xFF, 0x00, 0x00, 0x15, 0x00, 0xD1, 0xFF,
- 0x8B, 0xFE, 0xBC, 0xFD, 0xE1, 0x00, 0x84, 0x09, 0xB0, 0x13, 0x47,
- 0x18, 0xB0, 0x13, 0x84, 0x09, 0xE1, 0x00, 0xBC, 0xFD, 0x8B, 0xFE,
- 0xD1, 0xFF, 0x15, 0x00, 0xFD, 0xFF, 0x13, 0x00, 0xDA, 0x00, 0x30,
- 0x00, 0x5D, 0xFC, 0xB3, 0xFC, 0x35, 0x0A, 0xC2, 0x1C, 0x24, 0x20,
- 0x48, 0x10, 0x5D, 0xFF, 0x74, 0xFB, 0x3A, 0xFF, 0xFB, 0x00, 0x42,
- 0x00, 0xF8, 0xFF, 0xFA, 0xFF, 0x2C, 0x00, 0xF3, 0x00, 0xAD, 0xFF,
- 0xC5, 0xFB, 0x11, 0xFE, 0xAF, 0x0D, 0xEF, 0x1E, 0x68, 0x1E, 0xBC,
- 0x0C, 0xA7, 0xFD, 0xEA, 0xFB, 0xD3, 0xFF, 0xEE, 0x00, 0x24, 0x00,
- 0xFA, 0xFF, 0xF7, 0xFF, 0x4C, 0x00, 0xFB, 0x00, 0x0C, 0xFF, 0x5F,
- 0xFB, 0xE8, 0xFF, 0x3D, 0x11, 0x7E, 0x20, 0x13, 0x1C, 0x4C, 0x09,
- 0x6A, 0xFC, 0x8C, 0xFC, 0x4E, 0x00, 0xD1, 0x00, 0x0E, 0x00, 0xFD,
- 0xFF, 0xF7, 0xFF, 0x72, 0x00, 0xEC, 0x00, 0x55, 0xFE, 0x3D, 0xFB,
- 0x37, 0x02, 0xBE, 0x14, 0x5D, 0x21, 0x40, 0x19, 0x18, 0x06, 0xA2,
- 0xFB, 0x47, 0xFD, 0xA7, 0x00, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xFC, 0xFF, 0x9B, 0x00, 0xC0, 0x00, 0x92, 0xFD, 0x73,
- 0xFB, 0xF2, 0x04, 0x0E, 0x18, 0x81, 0x21, 0x0C, 0x16, 0x37, 0x03,
- 0x47, 0xFB, 0x0B, 0xFE, 0xDF, 0x00, 0x82, 0x00, 0xF9, 0xFF, 0xFE,
- 0xFF, 0x08, 0x00, 0xC3, 0x00, 0x74, 0x00, 0xD2, 0xFC, 0x10, 0xFC,
- 0x08, 0x08, 0x0A, 0x1B, 0xE9, 0x20, 0x9A, 0x12, 0xBE, 0x00, 0x49,
- 0xFB, 0xC8, 0xFE, 0xF9, 0x00, 0x5A, 0x00, 0xF7, 0xFF, 0xFC, 0xFF,
- 0x1B, 0x00, 0xE4, 0x00, 0x06, 0x00, 0x24, 0xFC, 0x1E, 0xFD, 0x65,
- 0x0B, 0x94, 0x1D, 0x9D, 0x1F, 0x0D, 0x0F, 0xB8, 0xFE, 0x96, 0xFB,
- 0x72, 0xFF, 0xF9, 0x00, 0x37, 0x00, 0xF8, 0xFF, 0xF9, 0xFF, 0x36,
- 0x00, 0xF8, 0x00, 0x78, 0xFF, 0x9B, 0xFB, 0xA6, 0xFE, 0xE9, 0x0E,
- 0x8D, 0x1F, 0xAA, 0x1D, 0x87, 0x0B, 0x2B, 0xFD, 0x1E, 0xFC, 0x02,
- 0x00, 0xE5, 0x00, 0x1C, 0x00, 0xFB, 0xFF, 0xF7, 0xFF, 0x58, 0x00,
- 0xF9, 0x00, 0xCF, 0xFE, 0x4A, 0xFB, 0xA7, 0x00, 0x77, 0x12, 0xE0,
- 0x20, 0x26, 0x1B, 0x28, 0x08, 0x18, 0xFC, 0xCB, 0xFC, 0x71, 0x00,
- 0xC5, 0x00, 0x08, 0x00, 0xFE, 0xFF, 0xF8, 0xFF, 0x80, 0x00, 0xE1,
- 0x00, 0x13, 0xFE, 0x45, 0xFB, 0x1D, 0x03, 0xEB, 0x15, 0x7F, 0x21,
- 0x2D, 0x18, 0x0E, 0x05, 0x77, 0xFB, 0x8B, 0xFD, 0xBE, 0x00, 0x9D,
- 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xA9, 0x00,
- 0xAA, 0x00, 0x4F, 0xFD, 0x9D, 0xFB, 0xFA, 0x05, 0x22, 0x19, 0x62,
- 0x21, 0xE0, 0x14, 0x50, 0x02, 0x3E, 0xFB, 0x4E, 0xFE, 0xEB, 0x00,
- 0x73, 0x00, 0xF7, 0xFF, 0xFE, 0xFF, 0x0D, 0x00, 0xD0, 0x00, 0x52,
- 0x00, 0x93, 0xFC, 0x60, 0xFC, 0x2C, 0x09, 0xFA, 0x1B, 0x8A, 0x20,
- 0x60, 0x11, 0xFD, 0xFF, 0x5C, 0xFB, 0x06, 0xFF, 0xFB, 0x00, 0x4D,
- 0x00, 0xF7, 0xFF, 0xFA, 0xFF, 0x23, 0x00, 0xED, 0x00, 0xD9, 0xFF,
- 0xEF, 0xFB, 0x98, 0xFD, 0x99, 0x0C, 0x54, 0x1E, 0x02, 0x1F, 0xD2,
- 0x0D, 0x20, 0xFE, 0xC0, 0xFB, 0xA7, 0xFF, 0xF4, 0x00, 0x2D, 0x00,
- 0xF9, 0xFF, 0xF8, 0xFF, 0x41, 0x00, 0xFB, 0x00, 0x41, 0xFF, 0x78,
- 0xFB, 0x4A, 0xFF, 0x25, 0x10, 0x16, 0x20, 0xDA, 0x1C, 0x56, 0x0A,
- 0xBE, 0xFC, 0x56, 0xFC, 0x2C, 0x00, 0xDB, 0x00, 0x14, 0x00, 0xFD,
- 0xFF, 0xF7, 0xFF, 0x66, 0x00, 0xF4, 0x00, 0x8F, 0xFE, 0x3F, 0xFB,
- 0x75, 0x01, 0xAE, 0x13, 0x2C, 0x21, 0x2A, 0x1A, 0x0D, 0x07, 0xD4,
- 0xFB, 0x0C, 0xFD, 0x8F, 0x00, 0xB7, 0x00, 0x03, 0x00, 0xFF, 0xFF,
- 0x00, 0x00, 0xFA, 0xFF, 0x8E, 0x00, 0xD1, 0x00, 0xCF, 0xFD, 0x58,
- 0xFB, 0x10, 0x04, 0x10, 0x17, 0x8A, 0x21, 0x10, 0x17, 0x10, 0x04,
- 0x58, 0xFB, 0xCF, 0xFD, 0xD1, 0x00, 0x8E, 0x00, 0xFA, 0xFF, 0xFF,
- 0xFF, 0x03, 0x00, 0xB7, 0x00, 0x8F, 0x00, 0x0C, 0xFD, 0xD4, 0xFB,
- 0x0D, 0x07, 0x2A, 0x1A, 0x2C, 0x21, 0xAE, 0x13, 0x75, 0x01, 0x3F,
- 0xFB, 0x8F, 0xFE, 0xF4, 0x00, 0x66, 0x00, 0xF7, 0xFF, 0xFD, 0xFF,
- 0x14, 0x00, 0xDB, 0x00, 0x2C, 0x00, 0x56, 0xFC, 0xBE, 0xFC, 0x56,
- 0x0A, 0xDA, 0x1C, 0x16, 0x20, 0x25, 0x10, 0x4A, 0xFF, 0x78, 0xFB,
- 0x41, 0xFF, 0xFB, 0x00, 0x41, 0x00, 0xF8, 0xFF, 0xF9, 0xFF, 0x2D,
- 0x00, 0xF4, 0x00, 0xA7, 0xFF, 0xC0, 0xFB, 0x20, 0xFE, 0xD2, 0x0D,
- 0x02, 0x1F, 0x54, 0x1E, 0x99, 0x0C, 0x98, 0xFD, 0xEF, 0xFB, 0xD9,
- 0xFF, 0xED, 0x00, 0x23, 0x00, 0xFA, 0xFF, 0xF7, 0xFF, 0x4D, 0x00,
- 0xFB, 0x00, 0x06, 0xFF, 0x5C, 0xFB, 0xFD, 0xFF, 0x60, 0x11, 0x8A,
- 0x20, 0xFA, 0x1B, 0x2C, 0x09, 0x60, 0xFC, 0x93, 0xFC, 0x52, 0x00,
- 0xD0, 0x00, 0x0D, 0x00, 0xFE, 0xFF, 0xF7, 0xFF, 0x73, 0x00, 0xEB,
- 0x00, 0x4E, 0xFE, 0x3E, 0xFB, 0x50, 0x02, 0xE0, 0x14, 0x62, 0x21,
- 0x22, 0x19, 0xFA, 0x05, 0x9D, 0xFB, 0x4F, 0xFD, 0xAA, 0x00, 0xA9,
- 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0x9D, 0x00,
- 0xBE, 0x00, 0x8B, 0xFD, 0x77, 0xFB, 0x0E, 0x05, 0x2D, 0x18, 0x7F,
- 0x21, 0xEB, 0x15, 0x1D, 0x03, 0x45, 0xFB, 0x13, 0xFE, 0xE1, 0x00,
- 0x80, 0x00, 0xF8, 0xFF, 0xFE, 0xFF, 0x08, 0x00, 0xC5, 0x00, 0x71,
- 0x00, 0xCB, 0xFC, 0x18, 0xFC, 0x28, 0x08, 0x26, 0x1B, 0xE0, 0x20,
- 0x77, 0x12, 0xA7, 0x00, 0x4A, 0xFB, 0xCF, 0xFE, 0xF9, 0x00, 0x58,
- 0x00, 0xF7, 0xFF, 0xFB, 0xFF, 0x1C, 0x00, 0xE5, 0x00, 0x02, 0x00,
- 0x1E, 0xFC, 0x2B, 0xFD, 0x87, 0x0B, 0xAA, 0x1D, 0x8D, 0x1F, 0xE9,
- 0x0E, 0xA6, 0xFE, 0x9B, 0xFB, 0x78, 0xFF, 0xF8, 0x00, 0x36, 0x00,
- 0xF9, 0xFF, 0xF8, 0xFF, 0x37, 0x00, 0xF9, 0x00, 0x72, 0xFF, 0x96,
- 0xFB, 0xB8, 0xFE, 0x0D, 0x0F, 0x9D, 0x1F, 0x94, 0x1D, 0x65, 0x0B,
- 0x1E, 0xFD, 0x24, 0xFC, 0x06, 0x00, 0xE4, 0x00, 0x1B, 0x00, 0xFC,
- 0xFF, 0xF7, 0xFF, 0x5A, 0x00, 0xF9, 0x00, 0xC8, 0xFE, 0x49, 0xFB,
- 0xBE, 0x00, 0x9A, 0x12, 0xE9, 0x20, 0x0A, 0x1B, 0x08, 0x08, 0x10,
- 0xFC, 0xD2, 0xFC, 0x74, 0x00, 0xC3, 0x00, 0x08, 0x00, 0xFE, 0xFF,
- 0xF9, 0xFF, 0x82, 0x00, 0xDF, 0x00, 0x0B, 0xFE, 0x47, 0xFB, 0x37,
- 0x03, 0x0C, 0x16, 0x81, 0x21, 0x0E, 0x18, 0xF2, 0x04, 0x73, 0xFB,
- 0x92, 0xFD, 0xC0, 0x00, 0x9B, 0x00, 0xFC, 0xFF, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xAB, 0x00, 0xA7, 0x00, 0x47, 0xFD, 0xA2, 0xFB,
- 0x18, 0x06, 0x40, 0x19, 0x5D, 0x21, 0xBE, 0x14, 0x37, 0x02, 0x3D,
- 0xFB, 0x55, 0xFE, 0xEC, 0x00, 0x72, 0x00, 0xF7, 0xFF, 0xFD, 0xFF,
- 0x0E, 0x00, 0xD1, 0x00, 0x4E, 0x00, 0x8C, 0xFC, 0x6A, 0xFC, 0x4C,
- 0x09, 0x13, 0x1C, 0x7E, 0x20, 0x3D, 0x11, 0xE8, 0xFF, 0x5F, 0xFB,
- 0x0C, 0xFF, 0xFB, 0x00, 0x4C, 0x00, 0xF7, 0xFF, 0xFA, 0xFF, 0x24,
- 0x00, 0xEE, 0x00, 0xD3, 0xFF, 0xEA, 0xFB, 0xA7, 0xFD, 0xBC, 0x0C,
- 0x68, 0x1E, 0xEF, 0x1E, 0xAF, 0x0D, 0x11, 0xFE, 0xC5, 0xFB, 0xAD,
- 0xFF, 0xF3, 0x00, 0x2C, 0x00, 0xFA, 0xFF, 0xF8, 0xFF, 0x42, 0x00,
- 0xFB, 0x00, 0x3A, 0xFF, 0x74, 0xFB, 0x5D, 0xFF, 0x48, 0x10, 0x24,
- 0x20, 0xC2, 0x1C, 0x35, 0x0A, 0xB3, 0xFC, 0x5D, 0xFC, 0x30, 0x00,
- 0xDA, 0x00, 0x13, 0x00, 0xFD, 0xFF, 0xF7, 0xFF, 0x67, 0x00, 0xF3,
- 0x00, 0x88, 0xFE, 0x3E, 0xFB, 0x8C, 0x01, 0xD0, 0x13, 0x33, 0x21,
- 0x0D, 0x1A, 0xEE, 0x06, 0xCD, 0xFB, 0x13, 0xFD, 0x92, 0x00, 0xB6,
- 0x00, 0x03, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFA, 0xFF, 0x90, 0x00,
- 0xCF, 0x00, 0xC7, 0xFD, 0x5B, 0xFB, 0x2B, 0x04, 0x31, 0x17, 0x8A,
- 0x21, 0xF0, 0x16, 0xF4, 0x03, 0x56, 0xFB, 0xD6, 0xFD, 0xD3, 0x00,
- 0x8D, 0x00, 0xFA, 0xFF, 0xFF, 0xFF, 0x04, 0x00, 0xB9, 0x00, 0x8C,
- 0x00, 0x05, 0xFD, 0xDB, 0xFB, 0x2C, 0x07, 0x47, 0x1A, 0x25, 0x21,
- 0x8B, 0x13, 0x5D, 0x01, 0x40, 0xFB, 0x97, 0xFE, 0xF5, 0x00, 0x64,
- 0x00, 0xF7, 0xFF, 0xFC, 0xFF, 0x15, 0x00, 0xDC, 0x00, 0x27, 0x00,
- 0x50, 0xFC, 0xCA, 0xFC, 0x78, 0x0A, 0xF2, 0x1C, 0x07, 0x20, 0x02,
- 0x10, 0x37, 0xFF, 0x7B, 0xFB, 0x47, 0xFF, 0xFB, 0x00, 0x40, 0x00,
- 0xF8, 0xFF, 0xF9, 0xFF, 0x2E, 0x00, 0xF5, 0x00, 0xA2, 0xFF, 0xBB,
- 0xFB, 0x31, 0xFE, 0xF5, 0x0D, 0x14, 0x1F, 0x3F, 0x1E, 0x77, 0x0C,
- 0x8A, 0xFD, 0xF5, 0xFB, 0xDE, 0xFF, 0xEC, 0x00, 0x22, 0x00, 0xFB,
- 0xFF, 0xF7, 0xFF, 0x4E, 0x00, 0xFB, 0x00, 0xFF, 0xFE, 0x59, 0xFB,
- 0x11, 0x00, 0x83, 0x11, 0x96, 0x20, 0xE0, 0x1B, 0x0B, 0x09, 0x56,
- 0xFC, 0x99, 0xFC, 0x56, 0x00, 0xCE, 0x00, 0x0D, 0x00, 0xFE, 0xFF,
- 0xF8, 0xFF, 0x75, 0x00, 0xEA, 0x00, 0x47, 0xFE, 0x3E, 0xFB, 0x69,
- 0x02, 0x02, 0x15, 0x66, 0x21, 0x04, 0x19, 0xDC, 0x05, 0x98, 0xFB,
- 0x56, 0xFD, 0xAD, 0x00, 0xA8, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
- 0x00, 0xFD, 0xFF, 0x9E, 0x00, 0xBC, 0x00, 0x83, 0xFD, 0x7B, 0xFB,
- 0x2B, 0x05, 0x4C, 0x18, 0x7C, 0x21, 0xCA, 0x15, 0x03, 0x03, 0x44,
- 0xFB, 0x1A, 0xFE, 0xE2, 0x00, 0x7E, 0x00, 0xF8, 0xFF, 0xFE, 0xFF,
- 0x09, 0x00, 0xC6, 0x00, 0x6D, 0x00, 0xC3, 0xFC, 0x20, 0xFC, 0x49,
- 0x08, 0x41, 0x1B, 0xD6, 0x20, 0x54, 0x12, 0x92, 0x00, 0x4C, 0xFB,
- 0xD6, 0xFE, 0xFA, 0x00, 0x57, 0x00, 0xF7, 0xFF, 0xFB, 0xFF, 0x1D,
- 0x00, 0xE6, 0x00, 0xFD, 0xFF, 0x18, 0xFC, 0x38, 0xFD, 0xA9, 0x0B,
- 0xC0, 0x1D, 0x7C, 0x1F, 0xC6, 0x0E, 0x95, 0xFE, 0x9F, 0xFB, 0x7E,
- 0xFF, 0xF8, 0x00, 0x35, 0x00, 0xF9, 0xFF, 0xF8, 0xFF, 0x38, 0x00,
- 0xF9, 0x00, 0x6C, 0xFF, 0x92, 0xFB, 0xC9, 0xFE, 0x2F, 0x0F, 0xAD,
- 0x1F, 0x7D, 0x1D, 0x42, 0x0B, 0x12, 0xFD, 0x2A, 0xFC, 0x0B, 0x00,
- 0xE3, 0x00, 0x1A, 0x00, 0xFC, 0xFF, 0xF7, 0xFF, 0x5B, 0x00, 0xF8,
- 0x00, 0xC1, 0xFE, 0x47, 0xFB, 0xD4, 0x00, 0xBC, 0x12, 0xF3, 0x20,
- 0xEF, 0x1A, 0xE9, 0x07, 0x08, 0xFC, 0xD9, 0xFC, 0x78, 0x00, 0xC2,
- 0x00, 0x07, 0x00, 0xFF, 0xFF, 0xF9, 0xFF, 0x83, 0x00, 0xDD, 0x00,
- 0x04, 0xFE, 0x49, 0xFB, 0x52, 0x03, 0x2D, 0x16, 0x83, 0x21, 0xEF,
- 0x17, 0xD5, 0x04, 0x6F, 0xFB, 0x9A, 0xFD, 0xC3, 0x00, 0x9A, 0x00,
- 0xFC, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xAD, 0x00, 0xA4,
- 0x00, 0x40, 0xFD, 0xA8, 0xFB, 0x36, 0x06, 0x5E, 0x19, 0x58, 0x21,
- 0x9C, 0x14, 0x1E, 0x02, 0x3D, 0xFB, 0x5D, 0xFE, 0xED, 0x00, 0x70,
- 0x00, 0xF7, 0xFF, 0xFD, 0xFF, 0x0F, 0x00, 0xD2, 0x00, 0x4A, 0x00,
- 0x85, 0xFC, 0x74, 0xFC, 0x6D, 0x09, 0x2D, 0x1C, 0x72, 0x20, 0x1A,
- 0x11, 0xD4, 0xFF, 0x61, 0xFB, 0x13, 0xFF, 0xFC, 0x00, 0x4A, 0x00,
- 0xF7, 0xFF, 0xFA, 0xFF, 0x25, 0x00, 0xEF, 0x00, 0xCE, 0xFF, 0xE4,
- 0xFB, 0xB5, 0xFD, 0xDE, 0x0C, 0x7C, 0x1E, 0xDD, 0x1E, 0x8C, 0x0D,
- 0x01, 0xFE, 0xCA, 0xFB, 0xB3, 0xFF, 0xF3, 0x00, 0x2B, 0x00, 0xFA,
- 0xFF, 0xF8, 0xFF, 0x44, 0x00, 0xFB, 0x00, 0x34, 0xFF, 0x71, 0xFB,
- 0x71, 0xFF, 0x6B, 0x10, 0x32, 0x20, 0xA9, 0x1C, 0x13, 0x0A, 0xA8,
- 0xFC, 0x63, 0xFC, 0x35, 0x00, 0xD9, 0x00, 0x12, 0x00, 0xFD, 0xFF,
- 0xF7, 0xFF, 0x69, 0x00, 0xF2, 0x00, 0x81, 0xFE, 0x3E, 0xFB, 0xA4,
- 0x01, 0xF2, 0x13, 0x3A, 0x21, 0xF0, 0x19, 0xCF, 0x06, 0xC7, 0xFB,
- 0x1B, 0xFD, 0x96, 0x00, 0xB4, 0x00, 0x02, 0x00, 0xFF, 0xFF, 0x00,
- 0x00, 0xFB, 0xFF, 0x92, 0x00, 0xCD, 0x00, 0xC0, 0xFD, 0x5E, 0xFB,
- 0x47, 0x04, 0x51, 0x17, 0x8A, 0x21, 0xD0, 0x16, 0xD9, 0x03, 0x53,
- 0xFB, 0xDE, 0xFD, 0xD5, 0x00, 0x8B, 0x00, 0xFA, 0xFF, 0xFF, 0xFF,
- 0x04, 0x00, 0xBA, 0x00, 0x89, 0x00, 0xFD, 0xFC, 0xE2, 0xFB, 0x4B,
- 0x07, 0x63, 0x1A, 0x1D, 0x21, 0x69, 0x13, 0x46, 0x01, 0x41, 0xFB,
- 0x9E, 0xFE, 0xF5, 0x00, 0x63, 0x00, 0xF7, 0xFF, 0xFC, 0xFF, 0x16,
- 0x00, 0xDD, 0x00, 0x23, 0x00, 0x49, 0xFC, 0xD5, 0xFC, 0x99, 0x0A,
- 0x09, 0x1D, 0xF9, 0x1F, 0xDF, 0x0F, 0x24, 0xFF, 0x7F, 0xFB, 0x4D,
- 0xFF, 0xFB, 0x00, 0x3F, 0x00, 0xF8, 0xFF, 0xF9, 0xFF, 0x2F, 0x00,
- 0xF5, 0x00, 0x9C, 0xFF, 0xB6, 0xFB, 0x41, 0xFE, 0x17, 0x0E, 0x26,
- 0x1F, 0x2B, 0x1E, 0x54, 0x0C, 0x7C, 0xFD, 0xFA, 0xFB, 0xE3, 0xFF,
- 0xEB, 0x00, 0x21, 0x00, 0xFB, 0xFF, 0xF7, 0xFF, 0x50, 0x00, 0xFB,
- 0x00, 0xF8, 0xFE, 0x57, 0xFB, 0x26, 0x00, 0xA6, 0x11, 0xA1, 0x20,
- 0xC6, 0x1B, 0xEA, 0x08, 0x4D, 0xFC, 0xA0, 0xFC, 0x5A, 0x00, 0xCD,
- 0x00, 0x0C, 0x00, 0xFE, 0xFF, 0xF8, 0xFF, 0x77, 0x00, 0xE9, 0x00,
- 0x3F, 0xFE, 0x3F, 0xFB, 0x82, 0x02, 0x23, 0x15, 0x6B, 0x21, 0xE5,
- 0x18, 0xBE, 0x05, 0x93, 0xFB, 0x5E, 0xFD, 0xAF, 0x00, 0xA6, 0x00,
- 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0xA0, 0x00, 0xB9,
- 0x00, 0x7C, 0xFD, 0x80, 0xFB, 0x48, 0x05, 0x6B, 0x18, 0x79, 0x21,
- 0xA9, 0x15, 0xE9, 0x02, 0x43, 0xFB, 0x21, 0xFE, 0xE3, 0x00, 0x7D,
- 0x00, 0xF8, 0xFF, 0xFE, 0xFF, 0x09, 0x00, 0xC7, 0x00, 0x69, 0x00,
- 0xBC, 0xFC, 0x29, 0xFC, 0x69, 0x08, 0x5C, 0x1B, 0xCC, 0x20, 0x32,
- 0x12, 0x7C, 0x00, 0x4E, 0xFB, 0xDD, 0xFE, 0xFA, 0x00, 0x56, 0x00,
- 0xF7, 0xFF, 0xFB, 0xFF, 0x1D, 0x00, 0xE7, 0x00, 0xF8, 0xFF, 0x12,
- 0xFC, 0x45, 0xFD, 0xCB, 0x0B, 0xD6, 0x1D, 0x6C, 0x1F, 0xA3, 0x0E,
- 0x84, 0xFE, 0xA4, 0xFB, 0x84, 0xFF, 0xF7, 0x00, 0x34, 0x00, 0xF9,
- 0xFF, 0xF8, 0xFF, 0x3A, 0x00, 0xFA, 0x00, 0x66, 0xFF, 0x8E, 0xFB,
- 0xDB, 0xFE, 0x53, 0x0F, 0xBD, 0x1F, 0x66, 0x1D, 0x21, 0x0B, 0x05,
- 0xFD, 0x30, 0xFC, 0x10, 0x00, 0xE2, 0x00, 0x19, 0x00, 0xFC, 0xFF,
- 0xF7, 0xFF, 0x5D, 0x00, 0xF8, 0x00, 0xBA, 0xFE, 0x46, 0xFB, 0xEA,
- 0x00, 0xDF, 0x12, 0xFC, 0x20, 0xD3, 0x1A, 0xC9, 0x07, 0x00, 0xFC,
- 0xE0, 0xFC, 0x7B, 0x00, 0xC0, 0x00, 0x07, 0x00, 0xFF, 0xFF, 0xF9,
- 0xFF, 0x85, 0x00, 0xDC, 0x00, 0xFC, 0xFD, 0x4A, 0xFB, 0x6C, 0x03,
- 0x4E, 0x16, 0x85, 0x21, 0xCF, 0x17, 0xB8, 0x04, 0x6C, 0xFB, 0xA2,
- 0xFD, 0xC5, 0x00, 0x98, 0x00, 0xFC, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
- 0x01, 0x00, 0xAE, 0x00, 0xA1, 0x00, 0x38, 0xFD, 0xAE, 0xFB, 0x54,
- 0x06, 0x7C, 0x19, 0x53, 0x21, 0x7B, 0x14, 0x05, 0x02, 0x3D, 0xFB,
- 0x64, 0xFE, 0xEE, 0x00, 0x6F, 0x00, 0xF7, 0xFF, 0xFD, 0xFF, 0x0F,
- 0x00, 0xD4, 0x00, 0x46, 0x00, 0x7E, 0xFC, 0x7E, 0xFC, 0x8E, 0x09,
- 0x46, 0x1C, 0x66, 0x20, 0xF7, 0x10, 0xC0, 0xFF, 0x64, 0xFB, 0x1A,
- 0xFF, 0xFC, 0x00, 0x49, 0x00, 0xF7, 0xFF, 0xFA, 0xFF, 0x26, 0x00,
- 0xF0, 0x00, 0xC9, 0xFF, 0xDF, 0xFB, 0xC4, 0xFD, 0x01, 0x0D, 0x90,
- 0x1E, 0xCA, 0x1E, 0x69, 0x0D, 0xF1, 0xFD, 0xCF, 0xFB, 0xB8, 0xFF,
- 0xF2, 0x00, 0x29, 0x00, 0xFA, 0xFF, 0xF7, 0xFF, 0x45, 0x00, 0xFC,
- 0x00, 0x2D, 0xFF, 0x6D, 0xFB, 0x84, 0xFF, 0x8E, 0x10, 0x3F, 0x20,
- 0x91, 0x1C, 0xF2, 0x09, 0x9D, 0xFC, 0x6A, 0xFC, 0x39, 0x00, 0xD7,
- 0x00, 0x12, 0x00, 0xFD, 0xFF, 0xF7, 0xFF, 0x6A, 0x00, 0xF1, 0x00,
- 0x7A, 0xFE, 0x3D, 0xFB, 0xBC, 0x01, 0x14, 0x14, 0x41, 0x21, 0xD4,
- 0x19, 0xB0, 0x06, 0xC0, 0xFB, 0x22, 0xFD, 0x99, 0x00, 0xB3, 0x00,
- 0x02, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFB, 0xFF, 0x93, 0x00, 0xCB,
- 0x00, 0xB8, 0xFD, 0x61, 0xFB, 0x63, 0x04, 0x71, 0x17, 0x89, 0x21,
- 0xB0, 0x16, 0xBD, 0x03, 0x51, 0xFB, 0xE6, 0xFD, 0xD7, 0x00, 0x8A,
- 0x00, 0xFA, 0xFF, 0xFF, 0xFF, 0x05, 0x00, 0xBC, 0x00, 0x86, 0x00,
- 0xF6, 0xFC, 0xE9, 0xFB, 0x6A, 0x07, 0x80, 0x1A, 0x15, 0x21, 0x47,
- 0x13, 0x2F, 0x01, 0x42, 0xFB, 0xA5, 0xFE, 0xF6, 0x00, 0x61, 0x00,
- 0xF7, 0xFF, 0xFC, 0xFF, 0x16, 0x00, 0xDF, 0x00, 0x1E, 0x00, 0x43,
- 0xFC, 0xE1, 0xFC, 0xBB, 0x0A, 0x21, 0x1D, 0xEA, 0x1F, 0xBC, 0x0F,
- 0x12, 0xFF, 0x82, 0xFB, 0x54, 0xFF, 0xFA, 0x00, 0x3D, 0x00, 0xF8,
- 0xFF, 0xF9, 0xFF, 0x30, 0x00, 0xF6, 0x00, 0x96, 0xFF, 0xB1, 0xFB,
- 0x51, 0xFE, 0x3A, 0x0E, 0x38, 0x1F, 0x16, 0x1E, 0x32, 0x0C, 0x6E,
- 0xFD, 0x00, 0xFC, 0xE8, 0xFF, 0xEA, 0x00, 0x20, 0x00, 0xFB, 0xFF,
- 0xF7, 0xFF, 0x51, 0x00, 0xFB, 0x00, 0xF1, 0xFE, 0x54, 0xFB, 0x3B,
- 0x00, 0xC9, 0x11, 0xAD, 0x20, 0xAC, 0x1B, 0xCA, 0x08, 0x44, 0xFC,
- 0xA7, 0xFC, 0x5E, 0x00, 0xCC, 0x00, 0x0B, 0x00, 0xFE, 0xFF, 0xF8,
- 0xFF, 0x78, 0x00, 0xE7, 0x00, 0x38, 0xFE, 0x40, 0xFB, 0x9B, 0x02,
- 0x45, 0x15, 0x6F, 0x21, 0xC7, 0x18, 0xA1, 0x05, 0x8E, 0xFB, 0x65,
- 0xFD, 0xB2, 0x00, 0xA5, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00,
- 0xFE, 0xFF, 0xA2, 0x00, 0xB7, 0x00, 0x74, 0xFD, 0x84, 0xFB, 0x66,
- 0x05, 0x8A, 0x18, 0x76, 0x21, 0x87, 0x15, 0xCF, 0x02, 0x41, 0xFB,
- 0x29, 0xFE, 0xE5, 0x00, 0x7B, 0x00, 0xF8, 0xFF, 0xFE, 0xFF, 0x0A,
- 0x00, 0xC9, 0x00, 0x66, 0x00, 0xB5, 0xFC, 0x32, 0xFC, 0x89, 0x08,
- 0x77, 0x1B, 0xC2, 0x20, 0x0F, 0x12, 0x66, 0x00, 0x50, 0xFB, 0xE4,
- 0xFE, 0xFA, 0x00, 0x54, 0x00, 0xF7, 0xFF, 0xFB, 0xFF, 0x1E, 0x00,
- 0xE8, 0x00, 0xF3, 0xFF, 0x0C, 0xFC, 0x53, 0xFD, 0xED, 0x0B, 0xEB,
- 0x1D, 0x5A, 0x1F, 0x80, 0x0E, 0x73, 0xFE, 0xA8, 0xFB, 0x8A, 0xFF,
- 0xF7, 0x00, 0x32, 0x00, 0xF9, 0xFF, 0xF8, 0xFF, 0x3B, 0x00, 0xFA,
- 0x00, 0x60, 0xFF, 0x8A, 0xFB, 0xED, 0xFE, 0x76, 0x0F, 0xCC, 0x1F,
- 0x4F, 0x1D, 0xFF, 0x0A, 0xF9, 0xFC, 0x36, 0xFC, 0x15, 0x00, 0xE1,
- 0x00, 0x18, 0x00, 0xFC, 0xFF, 0xF7, 0xFF, 0x5E, 0x00, 0xF7, 0x00,
- 0xB3, 0xFE, 0x44, 0xFB, 0x01, 0x01, 0x02, 0x13, 0x04, 0x21, 0xB8,
- 0x1A, 0xA9, 0x07, 0xF8, 0xFB, 0xE7, 0xFC, 0x7F, 0x00, 0xBF, 0x00,
- 0x06, 0x00, 0xFF, 0xFF, 0xF9, 0xFF, 0x86, 0x00, 0xDA, 0x00, 0xF5,
- 0xFD, 0x4C, 0xFB, 0x87, 0x03, 0x6E, 0x16, 0x86, 0x21, 0xB0, 0x17,
- 0x9C, 0x04, 0x68, 0xFB, 0xA9, 0xFD, 0xC7, 0x00, 0x96, 0x00, 0xFB,
- 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x01, 0x00, 0xB0, 0x00, 0x9F, 0x00,
- 0x31, 0xFD, 0xB4, 0xFB, 0x73, 0x06, 0x99, 0x19, 0x4D, 0x21, 0x59,
- 0x14, 0xED, 0x01, 0x3D, 0xFB, 0x6B, 0xFE, 0xEF, 0x00, 0x6D, 0x00,
- 0xF7, 0xFF, 0xFD, 0xFF, 0x10, 0x00, 0xD5, 0x00, 0x42, 0x00, 0x77,
- 0xFC, 0x88, 0xFC, 0xAF, 0x09, 0x5F, 0x1C, 0x59, 0x20, 0xD4, 0x10,
- 0xAC, 0xFF, 0x67, 0xFB, 0x20, 0xFF, 0xFC, 0x00, 0x48, 0x00, 0xF7,
- 0xFF, 0xFA, 0xFF, 0x27, 0x00, 0xF0, 0x00, 0xC3, 0xFF, 0xD9, 0xFB,
- 0xD3, 0xFD, 0x24, 0x0D, 0xA3, 0x1E, 0xB7, 0x1E, 0x46, 0x0D, 0xE2,
- 0xFD, 0xD4, 0xFB, 0xBE, 0xFF, 0xF1, 0x00, 0x28, 0x00, 0xFA, 0xFF,
- 0xF7, 0xFF, 0x46, 0x00, 0xFC, 0x00, 0x27, 0xFF, 0x6A, 0xFB, 0x98,
- 0xFF, 0xB1, 0x10, 0x4C, 0x20, 0x78, 0x1C, 0xD1, 0x09, 0x93, 0xFC,
- 0x71, 0xFC, 0x3D, 0x00, 0xD6, 0x00, 0x11, 0x00, 0xFD, 0xFF, 0xF7,
- 0xFF, 0x6C, 0x00, 0xF0, 0x00, 0x72, 0xFE, 0x3D, 0xFB, 0xD4, 0x01,
- 0x36, 0x14, 0x47, 0x21, 0xB6, 0x19, 0x91, 0x06, 0xBA, 0xFB, 0x29,
- 0xFD, 0x9C, 0x00, 0xB1, 0x00, 0x02, 0x00, 0xFF, 0xFF, 0x00, 0x00,
- 0xFB, 0xFF, 0x95, 0x00, 0xC9, 0x00, 0xB1, 0xFD, 0x65, 0xFB, 0x80,
- 0x04, 0x90, 0x17, 0x88, 0x21, 0x8F, 0x16, 0xA2, 0x03, 0x4E, 0xFB,
- 0xED, 0xFD, 0xD9, 0x00, 0x88, 0x00, 0xF9, 0xFF, 0xFF, 0xFF, 0x05,
- 0x00, 0xBD, 0x00, 0x82, 0x00, 0xEF, 0xFC, 0xF0, 0xFB, 0x8A, 0x07,
- 0x9C, 0x1A, 0x0D, 0x21, 0x24, 0x13, 0x18, 0x01, 0x43, 0xFB, 0xAC,
- 0xFE, 0xF7, 0x00, 0x60, 0x00, 0xF7, 0xFF, 0xFC, 0xFF, 0x17, 0x00,
- 0xE0, 0x00, 0x1A, 0x00, 0x3D, 0xFC, 0xED, 0xFC, 0xDD, 0x0A, 0x38,
- 0x1D, 0xDB, 0x1F, 0x99, 0x0F, 0xFF, 0xFE, 0x86, 0xFB, 0x5A, 0xFF,
- 0xFA, 0x00, 0x3C, 0x00, 0xF8, 0xFF, 0xF9, 0xFF, 0x31, 0x00, 0xF6,
- 0x00, 0x90, 0xFF, 0xAD, 0xFB, 0x62, 0xFE, 0x5D, 0x0E, 0x49, 0x1F,
- 0x01, 0x1E, 0x10, 0x0C, 0x60, 0xFD, 0x06, 0xFC, 0xEE, 0xFF, 0xE9,
- 0x00, 0x1F, 0x00, 0xFB, 0xFF, 0xF7, 0xFF, 0x53, 0x00, 0xFB, 0x00,
- 0xEB, 0xFE, 0x52, 0xFB, 0x51, 0x00, 0xEC, 0x11, 0xB7, 0x20, 0x91,
- 0x1B, 0xA9, 0x08, 0x3B, 0xFC, 0xAE, 0xFC, 0x62, 0x00, 0xCA, 0x00,
- 0x0B, 0x00, 0xFE, 0xFF, 0xF8, 0xFF, 0x7A, 0x00, 0xE6, 0x00, 0x30,
- 0xFE, 0x40, 0xFB, 0xB5, 0x02, 0x66, 0x15, 0x73, 0x21, 0xA9, 0x18,
- 0x83, 0x05, 0x89, 0xFB, 0x6D, 0xFD, 0xB4, 0x00, 0xA3, 0x00, 0xFE,
- 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xA3, 0x00, 0xB4, 0x00,
- 0x6D, 0xFD, 0x89, 0xFB, 0x83, 0x05, 0xA9, 0x18, 0x73, 0x21, 0x66,
- 0x15, 0xB5, 0x02, 0x40, 0xFB, 0x30, 0xFE, 0xE6, 0x00, 0x7A, 0x00,
- 0xF8, 0xFF, 0xFE, 0xFF, 0x0B, 0x00, 0xCA, 0x00, 0x62, 0x00, 0xAE,
- 0xFC, 0x3B, 0xFC, 0xA9, 0x08, 0x91, 0x1B, 0xB7, 0x20, 0xEC, 0x11,
- 0x51, 0x00, 0x52, 0xFB, 0xEB, 0xFE, 0xFB, 0x00, 0x53, 0x00, 0xF7,
- 0xFF, 0xFB, 0xFF, 0x1F, 0x00, 0xE9, 0x00, 0xEE, 0xFF, 0x06, 0xFC,
- 0x60, 0xFD, 0x10, 0x0C, 0x01, 0x1E, 0x49, 0x1F, 0x5D, 0x0E, 0x62,
- 0xFE, 0xAD, 0xFB, 0x90, 0xFF, 0xF6, 0x00, 0x31, 0x00, 0xF9, 0xFF,
- 0xF8, 0xFF, 0x3C, 0x00, 0xFA, 0x00, 0x5A, 0xFF, 0x86, 0xFB, 0xFF,
- 0xFE, 0x99, 0x0F, 0xDB, 0x1F, 0x38, 0x1D, 0xDD, 0x0A, 0xED, 0xFC,
- 0x3D, 0xFC, 0x1A, 0x00, 0xE0, 0x00, 0x17, 0x00, 0xFC, 0xFF, 0xF7,
- 0xFF, 0x60, 0x00, 0xF7, 0x00, 0xAC, 0xFE, 0x43, 0xFB, 0x18, 0x01,
- 0x24, 0x13, 0x0D, 0x21, 0x9C, 0x1A, 0x8A, 0x07, 0xF0, 0xFB, 0xEF,
- 0xFC, 0x82, 0x00, 0xBD, 0x00, 0x05, 0x00, 0xFF, 0xFF, 0xF9, 0xFF,
- 0x88, 0x00, 0xD9, 0x00, 0xED, 0xFD, 0x4E, 0xFB, 0xA2, 0x03, 0x8F,
- 0x16, 0x88, 0x21, 0x90, 0x17, 0x80, 0x04, 0x65, 0xFB, 0xB1, 0xFD,
- 0xC9, 0x00, 0x95, 0x00, 0xFB, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x02,
- 0x00, 0xB1, 0x00, 0x9C, 0x00, 0x29, 0xFD, 0xBA, 0xFB, 0x91, 0x06,
- 0xB6, 0x19, 0x47, 0x21, 0x36, 0x14, 0xD4, 0x01, 0x3D, 0xFB, 0x72,
- 0xFE, 0xF0, 0x00, 0x6C, 0x00, 0xF7, 0xFF, 0xFD, 0xFF, 0x11, 0x00,
- 0xD6, 0x00, 0x3D, 0x00, 0x71, 0xFC, 0x93, 0xFC, 0xD1, 0x09, 0x78,
- 0x1C, 0x4C, 0x20, 0xB1, 0x10, 0x98, 0xFF, 0x6A, 0xFB, 0x27, 0xFF,
- 0xFC, 0x00, 0x46, 0x00, 0xF7, 0xFF, 0xFA, 0xFF, 0x28, 0x00, 0xF1,
- 0x00, 0xBE, 0xFF, 0xD4, 0xFB, 0xE2, 0xFD, 0x46, 0x0D, 0xB7, 0x1E,
- 0xA3, 0x1E, 0x24, 0x0D, 0xD3, 0xFD, 0xD9, 0xFB, 0xC3, 0xFF, 0xF0,
- 0x00, 0x27, 0x00, 0xFA, 0xFF, 0xF7, 0xFF, 0x48, 0x00, 0xFC, 0x00,
- 0x20, 0xFF, 0x67, 0xFB, 0xAC, 0xFF, 0xD4, 0x10, 0x59, 0x20, 0x5F,
- 0x1C, 0xAF, 0x09, 0x88, 0xFC, 0x77, 0xFC, 0x42, 0x00, 0xD5, 0x00,
- 0x10, 0x00, 0xFD, 0xFF, 0xF7, 0xFF, 0x6D, 0x00, 0xEF, 0x00, 0x6B,
- 0xFE, 0x3D, 0xFB, 0xED, 0x01, 0x59, 0x14, 0x4D, 0x21, 0x99, 0x19,
- 0x73, 0x06, 0xB4, 0xFB, 0x31, 0xFD, 0x9F, 0x00, 0xB0, 0x00, 0x01,
- 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFB, 0xFF, 0x96, 0x00, 0xC7, 0x00,
- 0xA9, 0xFD, 0x68, 0xFB, 0x9C, 0x04, 0xB0, 0x17, 0x86, 0x21, 0x6E,
- 0x16, 0x87, 0x03, 0x4C, 0xFB, 0xF5, 0xFD, 0xDA, 0x00, 0x86, 0x00,
- 0xF9, 0xFF, 0xFF, 0xFF, 0x06, 0x00, 0xBF, 0x00, 0x7F, 0x00, 0xE7,
- 0xFC, 0xF8, 0xFB, 0xA9, 0x07, 0xB8, 0x1A, 0x04, 0x21, 0x02, 0x13,
- 0x01, 0x01, 0x44, 0xFB, 0xB3, 0xFE, 0xF7, 0x00, 0x5E, 0x00, 0xF7,
- 0xFF, 0xFC, 0xFF, 0x18, 0x00, 0xE1, 0x00, 0x15, 0x00, 0x36, 0xFC,
- 0xF9, 0xFC, 0xFF, 0x0A, 0x4F, 0x1D, 0xCC, 0x1F, 0x76, 0x0F, 0xED,
- 0xFE, 0x8A, 0xFB, 0x60, 0xFF, 0xFA, 0x00, 0x3B, 0x00, 0xF8, 0xFF,
- 0xF9, 0xFF, 0x32, 0x00, 0xF7, 0x00, 0x8A, 0xFF, 0xA8, 0xFB, 0x73,
- 0xFE, 0x80, 0x0E, 0x5A, 0x1F, 0xEB, 0x1D, 0xED, 0x0B, 0x53, 0xFD,
- 0x0C, 0xFC, 0xF3, 0xFF, 0xE8, 0x00, 0x1E, 0x00, 0xFB, 0xFF, 0xF7,
- 0xFF, 0x54, 0x00, 0xFA, 0x00, 0xE4, 0xFE, 0x50, 0xFB, 0x66, 0x00,
- 0x0F, 0x12, 0xC2, 0x20, 0x77, 0x1B, 0x89, 0x08, 0x32, 0xFC, 0xB5,
- 0xFC, 0x66, 0x00, 0xC9, 0x00, 0x0A, 0x00, 0xFE, 0xFF, 0xF8, 0xFF,
- 0x7B, 0x00, 0xE5, 0x00, 0x29, 0xFE, 0x41, 0xFB, 0xCF, 0x02, 0x87,
- 0x15, 0x76, 0x21, 0x8A, 0x18, 0x66, 0x05, 0x84, 0xFB, 0x74, 0xFD,
- 0xB7, 0x00, 0xA2, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFE,
- 0xFF, 0xA5, 0x00, 0xB2, 0x00, 0x65, 0xFD, 0x8E, 0xFB, 0xA1, 0x05,
- 0xC7, 0x18, 0x6F, 0x21, 0x45, 0x15, 0x9B, 0x02, 0x40, 0xFB, 0x38,
- 0xFE, 0xE7, 0x00, 0x78, 0x00, 0xF8, 0xFF, 0xFE, 0xFF, 0x0B, 0x00,
- 0xCC, 0x00, 0x5E, 0x00, 0xA7, 0xFC, 0x44, 0xFC, 0xCA, 0x08, 0xAC,
- 0x1B, 0xAD, 0x20, 0xC9, 0x11, 0x3B, 0x00, 0x54, 0xFB, 0xF1, 0xFE,
- 0xFB, 0x00, 0x51, 0x00, 0xF7, 0xFF, 0xFB, 0xFF, 0x20, 0x00, 0xEA,
- 0x00, 0xE8, 0xFF, 0x00, 0xFC, 0x6E, 0xFD, 0x32, 0x0C, 0x16, 0x1E,
- 0x38, 0x1F, 0x3A, 0x0E, 0x51, 0xFE, 0xB1, 0xFB, 0x96, 0xFF, 0xF6,
- 0x00, 0x30, 0x00, 0xF9, 0xFF, 0xF8, 0xFF, 0x3D, 0x00, 0xFA, 0x00,
- 0x54, 0xFF, 0x82, 0xFB, 0x12, 0xFF, 0xBC, 0x0F, 0xEA, 0x1F, 0x21,
- 0x1D, 0xBB, 0x0A, 0xE1, 0xFC, 0x43, 0xFC, 0x1E, 0x00, 0xDF, 0x00,
- 0x16, 0x00, 0xFC, 0xFF, 0xF7, 0xFF, 0x61, 0x00, 0xF6, 0x00, 0xA5,
- 0xFE, 0x42, 0xFB, 0x2F, 0x01, 0x47, 0x13, 0x15, 0x21, 0x80, 0x1A,
- 0x6A, 0x07, 0xE9, 0xFB, 0xF6, 0xFC, 0x86, 0x00, 0xBC, 0x00, 0x05,
- 0x00, 0xFF, 0xFF, 0xFA, 0xFF, 0x8A, 0x00, 0xD7, 0x00, 0xE6, 0xFD,
- 0x51, 0xFB, 0xBD, 0x03, 0xB0, 0x16, 0x89, 0x21, 0x71, 0x17, 0x63,
- 0x04, 0x61, 0xFB, 0xB8, 0xFD, 0xCB, 0x00, 0x93, 0x00, 0xFB, 0xFF,
- 0x00, 0x00, 0xFF, 0xFF, 0x02, 0x00, 0xB3, 0x00, 0x99, 0x00, 0x22,
- 0xFD, 0xC0, 0xFB, 0xB0, 0x06, 0xD4, 0x19, 0x41, 0x21, 0x14, 0x14,
- 0xBC, 0x01, 0x3D, 0xFB, 0x7A, 0xFE, 0xF1, 0x00, 0x6A, 0x00, 0xF7,
- 0xFF, 0xFD, 0xFF, 0x12, 0x00, 0xD7, 0x00, 0x39, 0x00, 0x6A, 0xFC,
- 0x9D, 0xFC, 0xF2, 0x09, 0x91, 0x1C, 0x3F, 0x20, 0x8E, 0x10, 0x84,
- 0xFF, 0x6D, 0xFB, 0x2D, 0xFF, 0xFC, 0x00, 0x45, 0x00, 0xF7, 0xFF,
- 0xFA, 0xFF, 0x29, 0x00, 0xF2, 0x00, 0xB8, 0xFF, 0xCF, 0xFB, 0xF1,
- 0xFD, 0x69, 0x0D, 0xCA, 0x1E, 0x90, 0x1E, 0x01, 0x0D, 0xC4, 0xFD,
- 0xDF, 0xFB, 0xC9, 0xFF, 0xF0, 0x00, 0x26, 0x00, 0xFA, 0xFF, 0xF7,
- 0xFF, 0x49, 0x00, 0xFC, 0x00, 0x1A, 0xFF, 0x64, 0xFB, 0xC0, 0xFF,
- 0xF7, 0x10, 0x66, 0x20, 0x46, 0x1C, 0x8E, 0x09, 0x7E, 0xFC, 0x7E,
- 0xFC, 0x46, 0x00, 0xD4, 0x00, 0x0F, 0x00, 0xFD, 0xFF, 0xF7, 0xFF,
- 0x6F, 0x00, 0xEE, 0x00, 0x64, 0xFE, 0x3D, 0xFB, 0x05, 0x02, 0x7B,
- 0x14, 0x53, 0x21, 0x7C, 0x19, 0x54, 0x06, 0xAE, 0xFB, 0x38, 0xFD,
- 0xA1, 0x00, 0xAE, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFC,
- 0xFF, 0x98, 0x00, 0xC5, 0x00, 0xA2, 0xFD, 0x6C, 0xFB, 0xB8, 0x04,
- 0xCF, 0x17, 0x85, 0x21, 0x4E, 0x16, 0x6C, 0x03, 0x4A, 0xFB, 0xFC,
- 0xFD, 0xDC, 0x00, 0x85, 0x00, 0xF9, 0xFF, 0xFF, 0xFF, 0x07, 0x00,
- 0xC0, 0x00, 0x7B, 0x00, 0xE0, 0xFC, 0x00, 0xFC, 0xC9, 0x07, 0xD3,
- 0x1A, 0xFC, 0x20, 0xDF, 0x12, 0xEA, 0x00, 0x46, 0xFB, 0xBA, 0xFE,
- 0xF8, 0x00, 0x5D, 0x00, 0xF7, 0xFF, 0xFC, 0xFF, 0x19, 0x00, 0xE2,
- 0x00, 0x10, 0x00, 0x30, 0xFC, 0x05, 0xFD, 0x21, 0x0B, 0x66, 0x1D,
- 0xBD, 0x1F, 0x53, 0x0F, 0xDB, 0xFE, 0x8E, 0xFB, 0x66, 0xFF, 0xFA,
- 0x00, 0x3A, 0x00, 0xF8, 0xFF, 0xF9, 0xFF, 0x34, 0x00, 0xF7, 0x00,
- 0x84, 0xFF, 0xA4, 0xFB, 0x84, 0xFE, 0xA3, 0x0E, 0x6C, 0x1F, 0xD6,
- 0x1D, 0xCB, 0x0B, 0x45, 0xFD, 0x12, 0xFC, 0xF8, 0xFF, 0xE7, 0x00,
- 0x1D, 0x00, 0xFB, 0xFF, 0xF7, 0xFF, 0x56, 0x00, 0xFA, 0x00, 0xDD,
- 0xFE, 0x4E, 0xFB, 0x7C, 0x00, 0x32, 0x12, 0xCC, 0x20, 0x5C, 0x1B,
- 0x69, 0x08, 0x29, 0xFC, 0xBC, 0xFC, 0x69, 0x00, 0xC7, 0x00, 0x09,
- 0x00, 0xFE, 0xFF, 0xF8, 0xFF, 0x7D, 0x00, 0xE3, 0x00, 0x21, 0xFE,
- 0x43, 0xFB, 0xE9, 0x02, 0xA9, 0x15, 0x79, 0x21, 0x6B, 0x18, 0x48,
- 0x05, 0x80, 0xFB, 0x7C, 0xFD, 0xB9, 0x00, 0xA0, 0x00, 0xFD, 0xFF,
- 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xA6, 0x00, 0xAF, 0x00, 0x5E,
- 0xFD, 0x93, 0xFB, 0xBE, 0x05, 0xE5, 0x18, 0x6B, 0x21, 0x23, 0x15,
- 0x82, 0x02, 0x3F, 0xFB, 0x3F, 0xFE, 0xE9, 0x00, 0x77, 0x00, 0xF8,
- 0xFF, 0xFE, 0xFF, 0x0C, 0x00, 0xCD, 0x00, 0x5A, 0x00, 0xA0, 0xFC,
- 0x4D, 0xFC, 0xEA, 0x08, 0xC6, 0x1B, 0xA1, 0x20, 0xA6, 0x11, 0x26,
- 0x00, 0x57, 0xFB, 0xF8, 0xFE, 0xFB, 0x00, 0x50, 0x00, 0xF7, 0xFF,
- 0xFB, 0xFF, 0x21, 0x00, 0xEB, 0x00, 0xE3, 0xFF, 0xFA, 0xFB, 0x7C,
- 0xFD, 0x54, 0x0C, 0x2B, 0x1E, 0x26, 0x1F, 0x17, 0x0E, 0x41, 0xFE,
- 0xB6, 0xFB, 0x9C, 0xFF, 0xF5, 0x00, 0x2F, 0x00, 0xF9, 0xFF, 0xF8,
- 0xFF, 0x3F, 0x00, 0xFB, 0x00, 0x4D, 0xFF, 0x7F, 0xFB, 0x24, 0xFF,
- 0xDF, 0x0F, 0xF9, 0x1F, 0x09, 0x1D, 0x99, 0x0A, 0xD5, 0xFC, 0x49,
- 0xFC, 0x23, 0x00, 0xDD, 0x00, 0x16, 0x00, 0xFC, 0xFF, 0xF7, 0xFF,
- 0x63, 0x00, 0xF5, 0x00, 0x9E, 0xFE, 0x41, 0xFB, 0x46, 0x01, 0x69,
- 0x13, 0x1D, 0x21, 0x63, 0x1A, 0x4B, 0x07, 0xE2, 0xFB, 0xFD, 0xFC,
- 0x89, 0x00, 0xBA, 0x00, 0x04, 0x00, 0xFF, 0xFF, 0xFA, 0xFF, 0x8B,
- 0x00, 0xD5, 0x00, 0xDE, 0xFD, 0x53, 0xFB, 0xD9, 0x03, 0xD0, 0x16,
- 0x8A, 0x21, 0x51, 0x17, 0x47, 0x04, 0x5E, 0xFB, 0xC0, 0xFD, 0xCD,
- 0x00, 0x92, 0x00, 0xFB, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x02, 0x00,
- 0xB4, 0x00, 0x96, 0x00, 0x1B, 0xFD, 0xC7, 0xFB, 0xCF, 0x06, 0xF0,
- 0x19, 0x3A, 0x21, 0xF2, 0x13, 0xA4, 0x01, 0x3E, 0xFB, 0x81, 0xFE,
- 0xF2, 0x00, 0x69, 0x00, 0xF7, 0xFF, 0xFD, 0xFF, 0x12, 0x00, 0xD9,
- 0x00, 0x35, 0x00, 0x63, 0xFC, 0xA8, 0xFC, 0x13, 0x0A, 0xA9, 0x1C,
- 0x32, 0x20, 0x6B, 0x10, 0x71, 0xFF, 0x71, 0xFB, 0x34, 0xFF, 0xFB,
- 0x00, 0x44, 0x00, 0xF8, 0xFF, 0xFA, 0xFF, 0x2B, 0x00, 0xF3, 0x00,
- 0xB3, 0xFF, 0xCA, 0xFB, 0x01, 0xFE, 0x8C, 0x0D, 0xDD, 0x1E, 0x7C,
- 0x1E, 0xDE, 0x0C, 0xB5, 0xFD, 0xE4, 0xFB, 0xCE, 0xFF, 0xEF, 0x00,
- 0x25, 0x00, 0xFA, 0xFF, 0xF7, 0xFF, 0x4A, 0x00, 0xFC, 0x00, 0x13,
- 0xFF, 0x61, 0xFB, 0xD4, 0xFF, 0x1A, 0x11, 0x72, 0x20, 0x2D, 0x1C,
- 0x6D, 0x09, 0x74, 0xFC, 0x85, 0xFC, 0x4A, 0x00, 0xD2, 0x00, 0x0F,
- 0x00, 0xFD, 0xFF, 0xF7, 0xFF, 0x70, 0x00, 0xED, 0x00, 0x5D, 0xFE,
- 0x3D, 0xFB, 0x1E, 0x02, 0x9C, 0x14, 0x58, 0x21, 0x5E, 0x19, 0x36,
- 0x06, 0xA8, 0xFB, 0x40, 0xFD, 0xA4, 0x00, 0xAD, 0x00, 0x00, 0x00,
- 0xFF, 0xFF, 0x00, 0x00, 0xFC, 0xFF, 0x9A, 0x00, 0xC3, 0x00, 0x9A,
- 0xFD, 0x6F, 0xFB, 0xD5, 0x04, 0xEF, 0x17, 0x83, 0x21, 0x2D, 0x16,
- 0x52, 0x03, 0x49, 0xFB, 0x04, 0xFE, 0xDD, 0x00, 0x83, 0x00, 0xF9,
- 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0xC2, 0x00, 0x78, 0x00, 0xD9, 0xFC,
- 0x08, 0xFC, 0xE9, 0x07, 0xEF, 0x1A, 0xF3, 0x20, 0xBC, 0x12, 0xD4,
- 0x00, 0x47, 0xFB, 0xC1, 0xFE, 0xF8, 0x00, 0x5B, 0x00, 0xF7, 0xFF,
- 0xFC, 0xFF, 0x1A, 0x00, 0xE3, 0x00, 0x0B, 0x00, 0x2A, 0xFC, 0x12,
- 0xFD, 0x42, 0x0B, 0x7D, 0x1D, 0xAD, 0x1F, 0x2F, 0x0F, 0xC9, 0xFE,
- 0x92, 0xFB, 0x6C, 0xFF, 0xF9, 0x00, 0x38, 0x00, 0xF8, 0xFF, 0xF9,
- 0xFF, 0x35, 0x00, 0xF8, 0x00, 0x7E, 0xFF, 0x9F, 0xFB, 0x95, 0xFE,
- 0xC6, 0x0E, 0x7C, 0x1F, 0xC0, 0x1D, 0xA9, 0x0B, 0x38, 0xFD, 0x18,
- 0xFC, 0xFD, 0xFF, 0xE6, 0x00, 0x1D, 0x00, 0xFB, 0xFF, 0xF7, 0xFF,
- 0x57, 0x00, 0xFA, 0x00, 0xD6, 0xFE, 0x4C, 0xFB, 0x92, 0x00, 0x54,
- 0x12, 0xD6, 0x20, 0x41, 0x1B, 0x49, 0x08, 0x20, 0xFC, 0xC3, 0xFC,
- 0x6D, 0x00, 0xC6, 0x00, 0x09, 0x00, 0xFE, 0xFF, 0xF8, 0xFF, 0x7E,
- 0x00, 0xE2, 0x00, 0x1A, 0xFE, 0x44, 0xFB, 0x03, 0x03, 0xCA, 0x15,
- 0x7C, 0x21, 0x4C, 0x18, 0x2B, 0x05, 0x7B, 0xFB, 0x83, 0xFD, 0xBC,
- 0x00, 0x9E, 0x00, 0xFD, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
- 0xA8, 0x00, 0xAD, 0x00, 0x56, 0xFD, 0x98, 0xFB, 0xDC, 0x05, 0x04,
- 0x19, 0x66, 0x21, 0x02, 0x15, 0x69, 0x02, 0x3E, 0xFB, 0x47, 0xFE,
- 0xEA, 0x00, 0x75, 0x00, 0xF8, 0xFF, 0xFE, 0xFF, 0x0D, 0x00, 0xCE,
- 0x00, 0x56, 0x00, 0x99, 0xFC, 0x56, 0xFC, 0x0B, 0x09, 0xE0, 0x1B,
- 0x96, 0x20, 0x83, 0x11, 0x11, 0x00, 0x59, 0xFB, 0xFF, 0xFE, 0xFB,
- 0x00, 0x4E, 0x00, 0xF7, 0xFF, 0xFB, 0xFF, 0x22, 0x00, 0xEC, 0x00,
- 0xDE, 0xFF, 0xF5, 0xFB, 0x8A, 0xFD, 0x77, 0x0C, 0x3F, 0x1E, 0x14,
- 0x1F, 0xF5, 0x0D, 0x31, 0xFE, 0xBB, 0xFB, 0xA2, 0xFF, 0xF5, 0x00,
- 0x2E, 0x00, 0xF9, 0xFF, 0xF8, 0xFF, 0x40, 0x00, 0xFB, 0x00, 0x47,
- 0xFF, 0x7B, 0xFB, 0x37, 0xFF, 0x02, 0x10, 0x07, 0x20, 0xF2, 0x1C,
- 0x78, 0x0A, 0xCA, 0xFC, 0x50, 0xFC, 0x27, 0x00, 0xDC, 0x00, 0x15,
- 0x00, 0xFC, 0xFF, 0xF7, 0xFF, 0x64, 0x00, 0xF5, 0x00, 0x97, 0xFE,
- 0x40, 0xFB, 0x5D, 0x01, 0x8B, 0x13, 0x25, 0x21, 0x47, 0x1A, 0x2C,
- 0x07, 0xDB, 0xFB, 0x05, 0xFD, 0x8C, 0x00, 0xB9, 0x00, 0x04, 0x00,
- 0xFF, 0xFF, 0xFA, 0xFF, 0x8D, 0x00, 0xD3, 0x00, 0xD6, 0xFD, 0x56,
- 0xFB, 0xF4, 0x03, 0xF0, 0x16, 0x8A, 0x21, 0x31, 0x17, 0x2B, 0x04,
- 0x5B, 0xFB, 0xC7, 0xFD, 0xCF, 0x00, 0x90, 0x00, 0xFA, 0xFF, 0x00,
- 0x00, 0xFF, 0xFF, 0x03, 0x00, 0xB6, 0x00, 0x92, 0x00, 0x13, 0xFD,
- 0xCD, 0xFB, 0xEE, 0x06, 0x0D, 0x1A, 0x33, 0x21, 0xD0, 0x13, 0x8C,
- 0x01, 0x3E, 0xFB, 0x88, 0xFE, 0xF3, 0x00, 0x67, 0x00, 0xF7, 0xFF,
- 0x06, 0x00, 0x1D, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0xA1, 0x02, 0xA6,
- 0xF8, 0x56, 0x02, 0xA5, 0x28, 0xA5, 0x28, 0x56, 0x02, 0xA6, 0xF8,
- 0xA1, 0x02, 0xFE, 0x00, 0x03, 0xFF, 0x1D, 0x00, 0x06, 0x00, 0x00,
- 0x00, 0x21, 0x00, 0xA6, 0xFF, 0x3F, 0xFF, 0x0B, 0x03, 0x42, 0xFE,
- 0x3E, 0xF8, 0x7F, 0x15, 0xAC, 0x30, 0x7F, 0x15, 0x3E, 0xF8, 0x42,
- 0xFE, 0x0B, 0x03, 0x3F, 0xFF, 0xA6, 0xFF, 0x21, 0x00, 0x00, 0x00,
- 0xFA, 0xFF, 0xCE, 0xFF, 0x14, 0x01, 0x00, 0xFD, 0x35, 0x06, 0xD5,
- 0xF4, 0xDA, 0x15, 0x92, 0x40, 0xAE, 0xFE, 0xF3, 0xFC, 0x68, 0x03,
- 0x86, 0xFD, 0x51, 0x01, 0x8B, 0xFF, 0x11, 0x00, 0x01, 0x00, 0xEC,
- 0xFF, 0xF9, 0xFF, 0xC6, 0x00, 0x55, 0xFD, 0x35, 0x06, 0x90, 0xF3,
- 0xE5, 0x1C, 0x6B, 0x3D, 0x71, 0xFA, 0x34, 0xFF, 0x46, 0x02, 0xFF,
- 0xFD, 0x2D, 0x01, 0x90, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xDB, 0xFF,
- 0x2D, 0x00, 0x60, 0x00, 0xE1, 0xFD, 0xCE, 0x05, 0xED, 0xF2, 0xF3,
- 0x23, 0x20, 0x39, 0x22, 0xF7, 0x44, 0x01, 0x1F, 0x01, 0x89, 0xFE,
- 0xFB, 0x00, 0x9C, 0xFF, 0x0D, 0x00, 0x06, 0x00, 0xC9, 0xFF, 0x68,
- 0x00, 0xE5, 0xFF, 0xA0, 0xFE, 0xFB, 0x04, 0x0C, 0xF3, 0xC5, 0x2A,
- 0xD8, 0x33, 0xC9, 0xF4, 0x0B, 0x03, 0x05, 0x00, 0x1A, 0xFF, 0xC1,
- 0x00, 0xAD, 0xFF, 0x0A, 0x00, 0x09, 0x00, 0xB5, 0xFF, 0xA5, 0x00,
- 0x5C, 0xFF, 0x8C, 0xFF, 0xBF, 0x03, 0x06, 0xF4, 0x22, 0x31, 0xC8,
- 0x2D, 0x63, 0xF3, 0x76, 0x04, 0x08, 0xFF, 0xA7, 0xFF, 0x84, 0x00,
- 0xC0, 0xFF, 0x07, 0x00, 0x0C, 0x00, 0xA4, 0xFF, 0xE1, 0x00, 0xCB,
- 0xFE, 0x9B, 0x00, 0x21, 0x02, 0xEE, 0xF5, 0xCD, 0x36, 0x24, 0x27,
- 0xE1, 0xF2, 0x7A, 0x05, 0x33, 0xFE, 0x2A, 0x00, 0x47, 0x00, 0xD3,
- 0xFF, 0x04, 0x00, 0x0F, 0x00, 0x95, 0xFF, 0x17, 0x01, 0x3D, 0xFE,
- 0xBD, 0x01, 0x30, 0x00, 0xCC, 0xF8, 0x92, 0x3B, 0x2A, 0x20, 0x2E,
- 0xF3, 0x12, 0x06, 0x8F, 0xFD, 0x9A, 0x00, 0x10, 0x00, 0xE5, 0xFF,
- 0x02, 0x00, 0x10, 0x00, 0x8C, 0xFF, 0x42, 0x01, 0xBB, 0xFD, 0xE4,
- 0x02, 0x01, 0xFE, 0x9C, 0xFC, 0x45, 0x3F, 0x16, 0x19, 0x2D, 0xF4,
- 0x41, 0x06, 0x21, 0xFD, 0xF3, 0x00, 0xE0, 0xFF, 0xF4, 0xFF, 0x01,
- 0x00, 0x10, 0x00, 0x8B, 0xFF, 0x5D, 0x01, 0x4F, 0xFD, 0xFB, 0x03,
- 0xB2, 0xFB, 0x53, 0x01, 0xC2, 0x41, 0x24, 0x12, 0xBA, 0xF5, 0x0F,
- 0x06, 0xE9, 0xFC, 0x33, 0x01, 0xBB, 0xFF, 0x00, 0x00, 0x00, 0x00,
- 0x0D, 0x00, 0x93, 0xFF, 0x63, 0x01, 0x04, 0xFD, 0xEF, 0x04, 0x62,
- 0xF9, 0xD7, 0x06, 0xF2, 0x42, 0x8D, 0x0B, 0xB0, 0xF7, 0x87, 0x05,
- 0xE6, 0xFC, 0x58, 0x01, 0xA0, 0xFF, 0x09, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x07, 0x00, 0xA5, 0xFF, 0x52, 0x01, 0xE2, 0xFC, 0xAD, 0x05,
- 0x35, 0xF7, 0x08, 0x0D, 0xCB, 0x42, 0x81, 0x05, 0xE8, 0xF9, 0xBB,
- 0x04, 0x12, 0xFD, 0x64, 0x01, 0x90, 0xFF, 0x0E, 0x00, 0x00, 0x00,
- 0xFE, 0xFF, 0xC2, 0xFF, 0x27, 0x01, 0xF1, 0xFC, 0x22, 0x06, 0x54,
- 0xF5, 0xB8, 0x13, 0x4A, 0x41, 0x29, 0x00, 0x3C, 0xFC, 0xBD, 0x03,
- 0x66, 0xFD, 0x58, 0x01, 0x8A, 0xFF, 0x11, 0x00, 0x01, 0x00, 0xF1,
- 0xFF, 0xEB, 0xFF, 0xE1, 0x00, 0x35, 0xFD, 0x40, 0x06, 0xE4, 0xF3,
- 0xB7, 0x1A, 0x85, 0x3E, 0xA6, 0xFB, 0x86, 0xFE, 0xA0, 0x02, 0xD7,
- 0xFD, 0x39, 0x01, 0x8E, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xE1, 0xFF,
- 0x1C, 0x00, 0x82, 0x00, 0xB0, 0xFD, 0xF9, 0x05, 0x0C, 0xF3, 0xCB,
- 0x21, 0x8F, 0x3A, 0x0D, 0xF8, 0xA9, 0x00, 0x79, 0x01, 0x5D, 0xFE,
- 0x0B, 0x01, 0x98, 0xFF, 0x0E, 0x00, 0x05, 0x00, 0xCE, 0xFF, 0x55,
- 0x00, 0x0D, 0x00, 0x60, 0xFE, 0x48, 0x05, 0xEC, 0xF2, 0xB6, 0x28,
- 0x91, 0x35, 0x68, 0xF5, 0x88, 0x02, 0x5A, 0x00, 0xED, 0xFE, 0xD4,
- 0x00, 0xA8, 0xFF, 0x0B, 0x00, 0x08, 0x00, 0xBB, 0xFF, 0x92, 0x00,
- 0x87, 0xFF, 0x3F, 0xFF, 0x2B, 0x04, 0xA1, 0xF3, 0x3D, 0x2F, 0xB8,
- 0x2F, 0xB8, 0xF3, 0x11, 0x04, 0x52, 0xFF, 0x7C, 0xFF, 0x97, 0x00,
- 0xBA, 0xFF, 0x08, 0x00, 0x0B, 0x00, 0xA9, 0xFF, 0xCF, 0x00, 0xF8,
- 0xFE, 0x44, 0x00, 0xAA, 0x02, 0x3E, 0xF5, 0x24, 0x35, 0x3B, 0x29,
- 0xF2, 0xF2, 0x35, 0x05, 0x70, 0xFE, 0x03, 0x00, 0x5A, 0x00, 0xCD,
- 0xFF, 0x05, 0x00, 0x0E, 0x00, 0x99, 0xFF, 0x07, 0x01, 0x68, 0xFE,
- 0x63, 0x01, 0xD0, 0x00, 0xD0, 0xF7, 0x35, 0x3A, 0x55, 0x22, 0x02,
- 0xF3, 0xEF, 0x05, 0xBC, 0xFD, 0x7A, 0x00, 0x20, 0x00, 0xDF, 0xFF,
- 0x03, 0x00, 0x10, 0x00, 0x8E, 0xFF, 0x36, 0x01, 0xE1, 0xFD, 0x8A,
- 0x02, 0xB2, 0xFE, 0x56, 0xFB, 0x40, 0x3E, 0x42, 0x1B, 0xCE, 0xF3,
- 0x3E, 0x06, 0x3D, 0xFD, 0xDB, 0x00, 0xEE, 0xFF, 0xF0, 0xFF, 0x01,
- 0x00, 0x11, 0x00, 0x8A, 0xFF, 0x57, 0x01, 0x6D, 0xFD, 0xA8, 0x03,
- 0x69, 0xFC, 0xC8, 0xFF, 0x20, 0x41, 0x40, 0x14, 0x33, 0xF5, 0x28,
- 0x06, 0xF5, 0xFC, 0x22, 0x01, 0xC5, 0xFF, 0xFD, 0xFF, 0x00, 0x00,
- 0x0F, 0x00, 0x8F, 0xFF, 0x64, 0x01, 0x17, 0xFD, 0xA9, 0x04, 0x16,
- 0xFA, 0x10, 0x05, 0xB8, 0x42, 0x87, 0x0D, 0x0D, 0xF7, 0xB9, 0x05,
- 0xE2, 0xFC, 0x50, 0x01, 0xA7, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x0A, 0x00, 0x9E, 0xFF, 0x5A, 0x01, 0xE8, 0xFC, 0x7A, 0x05,
- 0xDA, 0xF7, 0x10, 0x0B, 0xFB, 0x42, 0x4B, 0x07, 0x35, 0xF9, 0x00,
- 0x05, 0x00, 0xFD, 0x63, 0x01, 0x94, 0xFF, 0x0D, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0xB8, 0xFF, 0x37, 0x01, 0xE7, 0xFC, 0x07, 0x06, 0xDE,
- 0xF5, 0x9F, 0x11, 0xE4, 0x41, 0xB8, 0x01, 0x84, 0xFB, 0x0F, 0x04,
- 0x48, 0xFD, 0x5E, 0x01, 0x8B, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF5,
- 0xFF, 0xDD, 0xFF, 0xF9, 0x00, 0x1B, 0xFD, 0x41, 0x06, 0x47, 0xF4,
- 0x8B, 0x18, 0x81, 0x3F, 0xF1, 0xFC, 0xD5, 0xFD, 0xFA, 0x02, 0xB2,
- 0xFD, 0x45, 0x01, 0x8C, 0xFF, 0x11, 0x00, 0x02, 0x00, 0xE6, 0xFF,
- 0x0C, 0x00, 0xA2, 0x00, 0x85, 0xFD, 0x1A, 0x06, 0x3C, 0xF3, 0x9F,
- 0x1F, 0xE6, 0x3B, 0x0E, 0xF9, 0x07, 0x00, 0xD4, 0x01, 0x33, 0xFE,
- 0x1B, 0x01, 0x94, 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD4, 0xFF, 0x43,
- 0x00, 0x33, 0x00, 0x25, 0xFE, 0x89, 0x05, 0xE0, 0xF2, 0x9C, 0x26,
- 0x33, 0x37, 0x1E, 0xF6, 0xFD, 0x01, 0xB0, 0x00, 0xC0, 0xFE, 0xE6,
- 0x00, 0xA2, 0xFF, 0x0C, 0x00, 0x07, 0x00, 0xC1, 0xFF, 0x7F, 0x00,
- 0xB2, 0xFF, 0xF6, 0xFE, 0x8E, 0x04, 0x51, 0xF3, 0x49, 0x2D, 0x98,
- 0x31, 0x23, 0xF4, 0xA2, 0x03, 0xA0, 0xFF, 0x51, 0xFF, 0xAA, 0x00,
- 0xB4, 0xFF, 0x09, 0x00, 0x0A, 0x00, 0xAE, 0xFF, 0xBD, 0x00, 0x25,
- 0xFF, 0xF1, 0xFF, 0x2B, 0x03, 0xA5, 0xF4, 0x68, 0x33, 0x48, 0x2B,
- 0x17, 0xF3, 0xE7, 0x04, 0xB1, 0xFE, 0xDB, 0xFF, 0x6C, 0x00, 0xC7,
- 0xFF, 0x06, 0x00, 0x0D, 0x00, 0x9E, 0xFF, 0xF7, 0x00, 0x94, 0xFE,
- 0x09, 0x01, 0x6A, 0x01, 0xEB, 0xF6, 0xC1, 0x38, 0x7D, 0x24, 0xE8,
- 0xF2, 0xC1, 0x05, 0xEE, 0xFD, 0x57, 0x00, 0x31, 0x00, 0xDA, 0xFF,
- 0x03, 0x00, 0x10, 0x00, 0x91, 0xFF, 0x29, 0x01, 0x09, 0xFE, 0x2F,
- 0x02, 0x5F, 0xFF, 0x27, 0xFA, 0x20, 0x3D, 0x70, 0x1D, 0x7D, 0xF3,
- 0x31, 0x06, 0x5E, 0xFD, 0xBF, 0x00, 0xFD, 0xFF, 0xEB, 0xFF, 0x02,
- 0x00, 0x11, 0x00, 0x8B, 0xFF, 0x4E, 0x01, 0x8E, 0xFD, 0x52, 0x03,
- 0x20, 0xFD, 0x52, 0xFE, 0x60, 0x40, 0x63, 0x16, 0xB7, 0xF4, 0x39,
- 0x06, 0x05, 0xFD, 0x0F, 0x01, 0xD1, 0xFF, 0xF9, 0xFF, 0x00, 0x00,
- 0x10, 0x00, 0x8D, 0xFF, 0x62, 0x01, 0x2E, 0xFD, 0x5E, 0x04, 0xCC,
- 0xFA, 0x5B, 0x03, 0x5E, 0x42, 0x8E, 0x0F, 0x71, 0xF6, 0xE4, 0x05,
- 0xE2, 0xFC, 0x45, 0x01, 0xAF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x0B, 0x00, 0x99, 0xFF, 0x60, 0x01, 0xF2, 0xFC, 0x40, 0x05,
- 0x85, 0xF8, 0x26, 0x09, 0x0C, 0x43, 0x26, 0x09, 0x85, 0xF8, 0x40,
- 0x05, 0xF2, 0xFC, 0x60, 0x01, 0x99, 0xFF, 0x0B, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0xAF, 0xFF, 0x45, 0x01, 0xE2, 0xFC, 0xE4, 0x05, 0x71,
- 0xF6, 0x8E, 0x0F, 0x5E, 0x42, 0x5B, 0x03, 0xCC, 0xFA, 0x5E, 0x04,
- 0x2E, 0xFD, 0x62, 0x01, 0x8D, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xF9,
- 0xFF, 0xD1, 0xFF, 0x0F, 0x01, 0x05, 0xFD, 0x39, 0x06, 0xB7, 0xF4,
- 0x63, 0x16, 0x60, 0x40, 0x52, 0xFE, 0x20, 0xFD, 0x52, 0x03, 0x8E,
- 0xFD, 0x4E, 0x01, 0x8B, 0xFF, 0x11, 0x00, 0x02, 0x00, 0xEB, 0xFF,
- 0xFD, 0xFF, 0xBF, 0x00, 0x5E, 0xFD, 0x31, 0x06, 0x7D, 0xF3, 0x70,
- 0x1D, 0x20, 0x3D, 0x27, 0xFA, 0x5F, 0xFF, 0x2F, 0x02, 0x09, 0xFE,
- 0x29, 0x01, 0x91, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xDA, 0xFF, 0x31,
- 0x00, 0x57, 0x00, 0xEE, 0xFD, 0xC1, 0x05, 0xE8, 0xF2, 0x7D, 0x24,
- 0xC1, 0x38, 0xEB, 0xF6, 0x6A, 0x01, 0x09, 0x01, 0x94, 0xFE, 0xF7,
- 0x00, 0x9E, 0xFF, 0x0D, 0x00, 0x06, 0x00, 0xC7, 0xFF, 0x6C, 0x00,
- 0xDB, 0xFF, 0xB1, 0xFE, 0xE7, 0x04, 0x17, 0xF3, 0x48, 0x2B, 0x68,
- 0x33, 0xA5, 0xF4, 0x2B, 0x03, 0xF1, 0xFF, 0x25, 0xFF, 0xBD, 0x00,
- 0xAE, 0xFF, 0x0A, 0x00, 0x09, 0x00, 0xB4, 0xFF, 0xAA, 0x00, 0x51,
- 0xFF, 0xA0, 0xFF, 0xA2, 0x03, 0x23, 0xF4, 0x98, 0x31, 0x49, 0x2D,
- 0x51, 0xF3, 0x8E, 0x04, 0xF6, 0xFE, 0xB2, 0xFF, 0x7F, 0x00, 0xC1,
- 0xFF, 0x07, 0x00, 0x0C, 0x00, 0xA2, 0xFF, 0xE6, 0x00, 0xC0, 0xFE,
- 0xB0, 0x00, 0xFD, 0x01, 0x1E, 0xF6, 0x33, 0x37, 0x9C, 0x26, 0xE0,
- 0xF2, 0x89, 0x05, 0x25, 0xFE, 0x33, 0x00, 0x43, 0x00, 0xD4, 0xFF,
- 0x04, 0x00, 0x0F, 0x00, 0x94, 0xFF, 0x1B, 0x01, 0x33, 0xFE, 0xD4,
- 0x01, 0x07, 0x00, 0x0E, 0xF9, 0xE6, 0x3B, 0x9F, 0x1F, 0x3C, 0xF3,
- 0x1A, 0x06, 0x85, 0xFD, 0xA2, 0x00, 0x0C, 0x00, 0xE6, 0xFF, 0x02,
- 0x00, 0x11, 0x00, 0x8C, 0xFF, 0x45, 0x01, 0xB2, 0xFD, 0xFA, 0x02,
- 0xD5, 0xFD, 0xF1, 0xFC, 0x81, 0x3F, 0x8B, 0x18, 0x47, 0xF4, 0x41,
- 0x06, 0x1B, 0xFD, 0xF9, 0x00, 0xDD, 0xFF, 0xF5, 0xFF, 0x01, 0x00,
- 0x10, 0x00, 0x8B, 0xFF, 0x5E, 0x01, 0x48, 0xFD, 0x0F, 0x04, 0x84,
- 0xFB, 0xB8, 0x01, 0xE4, 0x41, 0x9F, 0x11, 0xDE, 0xF5, 0x07, 0x06,
- 0xE7, 0xFC, 0x37, 0x01, 0xB8, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x0D,
- 0x00, 0x94, 0xFF, 0x63, 0x01, 0x00, 0xFD, 0x00, 0x05, 0x35, 0xF9,
- 0x4B, 0x07, 0xFB, 0x42, 0x10, 0x0B, 0xDA, 0xF7, 0x7A, 0x05, 0xE8,
- 0xFC, 0x5A, 0x01, 0x9E, 0xFF, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x07, 0x00, 0xA7, 0xFF, 0x50, 0x01, 0xE2, 0xFC, 0xB9, 0x05, 0x0D,
- 0xF7, 0x87, 0x0D, 0xB8, 0x42, 0x10, 0x05, 0x16, 0xFA, 0xA9, 0x04,
- 0x17, 0xFD, 0x64, 0x01, 0x8F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xFD,
- 0xFF, 0xC5, 0xFF, 0x22, 0x01, 0xF5, 0xFC, 0x28, 0x06, 0x33, 0xF5,
- 0x40, 0x14, 0x20, 0x41, 0xC8, 0xFF, 0x69, 0xFC, 0xA8, 0x03, 0x6D,
- 0xFD, 0x57, 0x01, 0x8A, 0xFF, 0x11, 0x00, 0x01, 0x00, 0xF0, 0xFF,
- 0xEE, 0xFF, 0xDB, 0x00, 0x3D, 0xFD, 0x3E, 0x06, 0xCE, 0xF3, 0x42,
- 0x1B, 0x40, 0x3E, 0x56, 0xFB, 0xB2, 0xFE, 0x8A, 0x02, 0xE1, 0xFD,
- 0x36, 0x01, 0x8E, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xDF, 0xFF, 0x20,
- 0x00, 0x7A, 0x00, 0xBC, 0xFD, 0xEF, 0x05, 0x02, 0xF3, 0x55, 0x22,
- 0x35, 0x3A, 0xD0, 0xF7, 0xD0, 0x00, 0x63, 0x01, 0x68, 0xFE, 0x07,
- 0x01, 0x99, 0xFF, 0x0E, 0x00, 0x05, 0x00, 0xCD, 0xFF, 0x5A, 0x00,
- 0x03, 0x00, 0x70, 0xFE, 0x35, 0x05, 0xF2, 0xF2, 0x3B, 0x29, 0x24,
- 0x35, 0x3E, 0xF5, 0xAA, 0x02, 0x44, 0x00, 0xF8, 0xFE, 0xCF, 0x00,
- 0xA9, 0xFF, 0x0B, 0x00, 0x08, 0x00, 0xBA, 0xFF, 0x97, 0x00, 0x7C,
- 0xFF, 0x52, 0xFF, 0x11, 0x04, 0xB8, 0xF3, 0xB8, 0x2F, 0x3D, 0x2F,
- 0xA1, 0xF3, 0x2B, 0x04, 0x3F, 0xFF, 0x87, 0xFF, 0x92, 0x00, 0xBB,
- 0xFF, 0x08, 0x00, 0x0B, 0x00, 0xA8, 0xFF, 0xD4, 0x00, 0xED, 0xFE,
- 0x5A, 0x00, 0x88, 0x02, 0x68, 0xF5, 0x91, 0x35, 0xB6, 0x28, 0xEC,
- 0xF2, 0x48, 0x05, 0x60, 0xFE, 0x0D, 0x00, 0x55, 0x00, 0xCE, 0xFF,
- 0x05, 0x00, 0x0E, 0x00, 0x98, 0xFF, 0x0B, 0x01, 0x5D, 0xFE, 0x79,
- 0x01, 0xA9, 0x00, 0x0D, 0xF8, 0x8F, 0x3A, 0xCB, 0x21, 0x0C, 0xF3,
- 0xF9, 0x05, 0xB0, 0xFD, 0x82, 0x00, 0x1C, 0x00, 0xE1, 0xFF, 0x03,
- 0x00, 0x10, 0x00, 0x8E, 0xFF, 0x39, 0x01, 0xD7, 0xFD, 0xA0, 0x02,
- 0x86, 0xFE, 0xA6, 0xFB, 0x85, 0x3E, 0xB7, 0x1A, 0xE4, 0xF3, 0x40,
- 0x06, 0x35, 0xFD, 0xE1, 0x00, 0xEB, 0xFF, 0xF1, 0xFF, 0x01, 0x00,
- 0x11, 0x00, 0x8A, 0xFF, 0x58, 0x01, 0x66, 0xFD, 0xBD, 0x03, 0x3C,
- 0xFC, 0x29, 0x00, 0x4A, 0x41, 0xB8, 0x13, 0x54, 0xF5, 0x22, 0x06,
- 0xF1, 0xFC, 0x27, 0x01, 0xC2, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0x0E,
- 0x00, 0x90, 0xFF, 0x64, 0x01, 0x12, 0xFD, 0xBB, 0x04, 0xE8, 0xF9,
- 0x81, 0x05, 0xCB, 0x42, 0x08, 0x0D, 0x35, 0xF7, 0xAD, 0x05, 0xE2,
- 0xFC, 0x52, 0x01, 0xA5, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0xA0, 0xFF, 0x58, 0x01, 0xE6, 0xFC, 0x87, 0x05, 0xB0,
- 0xF7, 0x8D, 0x0B, 0xF2, 0x42, 0xD7, 0x06, 0x62, 0xF9, 0xEF, 0x04,
- 0x04, 0xFD, 0x63, 0x01, 0x93, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xBB, 0xFF, 0x33, 0x01, 0xE9, 0xFC, 0x0F, 0x06, 0xBA, 0xF5,
- 0x24, 0x12, 0xC2, 0x41, 0x53, 0x01, 0xB2, 0xFB, 0xFB, 0x03, 0x4F,
- 0xFD, 0x5D, 0x01, 0x8B, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF4, 0xFF,
- 0xE0, 0xFF, 0xF3, 0x00, 0x21, 0xFD, 0x41, 0x06, 0x2D, 0xF4, 0x16,
- 0x19, 0x45, 0x3F, 0x9C, 0xFC, 0x01, 0xFE, 0xE4, 0x02, 0xBB, 0xFD,
- 0x42, 0x01, 0x8C, 0xFF, 0x10, 0x00, 0x02, 0x00, 0xE5, 0xFF, 0x10,
- 0x00, 0x9A, 0x00, 0x8F, 0xFD, 0x12, 0x06, 0x2E, 0xF3, 0x2A, 0x20,
- 0x92, 0x3B, 0xCC, 0xF8, 0x30, 0x00, 0xBD, 0x01, 0x3D, 0xFE, 0x17,
- 0x01, 0x95, 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD3, 0xFF, 0x47, 0x00,
- 0x2A, 0x00, 0x33, 0xFE, 0x7A, 0x05, 0xE1, 0xF2, 0x24, 0x27, 0xCD,
- 0x36, 0xEE, 0xF5, 0x21, 0x02, 0x9B, 0x00, 0xCB, 0xFE, 0xE1, 0x00,
- 0xA4, 0xFF, 0x0C, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0x84, 0x00, 0xA7,
- 0xFF, 0x08, 0xFF, 0x76, 0x04, 0x63, 0xF3, 0xC8, 0x2D, 0x22, 0x31,
- 0x06, 0xF4, 0xBF, 0x03, 0x8C, 0xFF, 0x5C, 0xFF, 0xA5, 0x00, 0xB5,
- 0xFF, 0x09, 0x00, 0x0A, 0x00, 0xAD, 0xFF, 0xC1, 0x00, 0x1A, 0xFF,
- 0x05, 0x00, 0x0B, 0x03, 0xC9, 0xF4, 0xD8, 0x33, 0xC5, 0x2A, 0x0C,
- 0xF3, 0xFB, 0x04, 0xA0, 0xFE, 0xE5, 0xFF, 0x68, 0x00, 0xC9, 0xFF,
- 0x06, 0x00, 0x0D, 0x00, 0x9C, 0xFF, 0xFB, 0x00, 0x89, 0xFE, 0x1F,
- 0x01, 0x44, 0x01, 0x22, 0xF7, 0x20, 0x39, 0xF3, 0x23, 0xED, 0xF2,
- 0xCE, 0x05, 0xE1, 0xFD, 0x60, 0x00, 0x2D, 0x00, 0xDB, 0xFF, 0x03,
- 0x00, 0x10, 0x00, 0x90, 0xFF, 0x2D, 0x01, 0xFF, 0xFD, 0x46, 0x02,
- 0x34, 0xFF, 0x71, 0xFA, 0x6B, 0x3D, 0xE5, 0x1C, 0x90, 0xF3, 0x35,
- 0x06, 0x55, 0xFD, 0xC6, 0x00, 0xF9, 0xFF, 0xEC, 0xFF, 0x01, 0x00,
- 0x11, 0x00, 0x8B, 0xFF, 0x51, 0x01, 0x86, 0xFD, 0x68, 0x03, 0xF3,
- 0xFC, 0xAE, 0xFE, 0x92, 0x40, 0xDA, 0x15, 0xD5, 0xF4, 0x35, 0x06,
- 0x00, 0xFD, 0x14, 0x01, 0xCE, 0xFF, 0xFA, 0xFF, 0x00, 0x00, 0x0F,
- 0x00, 0x8D, 0xFF, 0x63, 0x01, 0x28, 0xFD, 0x71, 0x04, 0x9E, 0xFA,
- 0xC7, 0x03, 0x79, 0x42, 0x0B, 0x0F, 0x97, 0xF6, 0xDA, 0x05, 0xE2,
- 0xFC, 0x48, 0x01, 0xAD, 0xFF, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0B, 0x00, 0x9A, 0xFF, 0x5F, 0x01, 0xEF, 0xFC, 0x4F, 0x05, 0x5A,
- 0xF8, 0x9F, 0x09, 0x0A, 0x43, 0xAE, 0x08, 0xB1, 0xF8, 0x30, 0x05,
- 0xF5, 0xFC, 0x61, 0x01, 0x97, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0xB1, 0xFF, 0x41, 0x01, 0xE3, 0xFC, 0xED, 0x05, 0x4C, 0xF6,
- 0x11, 0x10, 0x42, 0x42, 0xF1, 0x02, 0xFA, 0xFA, 0x4B, 0x04, 0x34,
- 0xFD, 0x61, 0x01, 0x8C, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF8, 0xFF,
- 0xD4, 0xFF, 0x0A, 0x01, 0x0A, 0xFD, 0x3C, 0x06, 0x9A, 0xF4, 0xED,
- 0x16, 0x2A, 0x40, 0xF8, 0xFD, 0x4D, 0xFD, 0x3C, 0x03, 0x97, 0xFD,
- 0x4C, 0x01, 0x8B, 0xFF, 0x11, 0x00, 0x02, 0x00, 0xEA, 0xFF, 0x00,
- 0x00, 0xB8, 0x00, 0x67, 0xFD, 0x2C, 0x06, 0x6B, 0xF3, 0xFC, 0x1D,
- 0xD3, 0x3C, 0xDF, 0xF9, 0x89, 0xFF, 0x18, 0x02, 0x13, 0xFE, 0x26,
- 0x01, 0x92, 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD9, 0xFF, 0x36, 0x00,
- 0x4E, 0x00, 0xFB, 0xFD, 0xB4, 0x05, 0xE4, 0xF2, 0x04, 0x25, 0x5F,
- 0x38, 0xB6, 0xF6, 0x90, 0x01, 0xF3, 0x00, 0x9F, 0xFE, 0xF3, 0x00,
- 0x9F, 0xFF, 0x0D, 0x00, 0x06, 0x00, 0xC6, 0xFF, 0x71, 0x00, 0xD1,
- 0xFF, 0xC2, 0xFE, 0xD1, 0x04, 0x23, 0xF3, 0xC9, 0x2B, 0xF5, 0x32,
- 0x83, 0xF4, 0x49, 0x03, 0xDC, 0xFF, 0x30, 0xFF, 0xB8, 0x00, 0xB0,
- 0xFF, 0x0A, 0x00, 0x09, 0x00, 0xB3, 0xFF, 0xAE, 0x00, 0x46, 0xFF,
- 0xB4, 0xFF, 0x85, 0x03, 0x42, 0xF4, 0x0E, 0x32, 0xCA, 0x2C, 0x41,
- 0xF3, 0xA5, 0x04, 0xE4, 0xFE, 0xBC, 0xFF, 0x7A, 0x00, 0xC3, 0xFF,
- 0x07, 0x00, 0x0D, 0x00, 0xA1, 0xFF, 0xEA, 0x00, 0xB5, 0xFE, 0xC6,
- 0x00, 0xD9, 0x01, 0x4F, 0xF6, 0x99, 0x37, 0x16, 0x26, 0xE0, 0xF2,
- 0x98, 0x05, 0x16, 0xFE, 0x3C, 0x00, 0x3F, 0x00, 0xD6, 0xFF, 0x04,
- 0x00, 0x0F, 0x00, 0x93, 0xFF, 0x1F, 0x01, 0x28, 0xFE, 0xEB, 0x01,
- 0xDD, 0xFF, 0x52, 0xF9, 0x36, 0x3C, 0x13, 0x1F, 0x4B, 0xF3, 0x20,
- 0x06, 0x7B, 0xFD, 0xA9, 0x00, 0x08, 0x00, 0xE7, 0xFF, 0x02, 0x00,
- 0x11, 0x00, 0x8C, 0xFF, 0x47, 0x01, 0xA9, 0xFD, 0x10, 0x03, 0xA8,
- 0xFD, 0x47, 0xFD, 0xBB, 0x3F, 0x01, 0x18, 0x62, 0xF4, 0x40, 0x06,
- 0x15, 0xFD, 0xFF, 0x00, 0xDA, 0xFF, 0xF6, 0xFF, 0x01, 0x00, 0x10,
- 0x00, 0x8B, 0xFF, 0x5F, 0x01, 0x41, 0xFD, 0x23, 0x04, 0x56, 0xFB,
- 0x1F, 0x02, 0x06, 0x42, 0x19, 0x11, 0x02, 0xF6, 0xFF, 0x05, 0xE5,
- 0xFC, 0x3B, 0x01, 0xB6, 0xFF, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00,
- 0x95, 0xFF, 0x62, 0x01, 0xFC, 0xFC, 0x10, 0x05, 0x09, 0xF9, 0xC1,
- 0x07, 0x03, 0x43, 0x94, 0x0A, 0x05, 0xF8, 0x6C, 0x05, 0xEA, 0xFC,
- 0x5C, 0x01, 0x9D, 0xFF, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x00, 0xA9, 0xFF, 0x4D, 0x01, 0xE1, 0xFC, 0xC4, 0x05, 0xE6, 0xF6,
- 0x08, 0x0E, 0xA5, 0x42, 0xA1, 0x04, 0x43, 0xFA, 0x97, 0x04, 0x1D,
- 0xFD, 0x64, 0x01, 0x8F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xFC, 0xFF,
- 0xC8, 0xFF, 0x1E, 0x01, 0xF8, 0xFC, 0x2D, 0x06, 0x13, 0xF5, 0xC8,
- 0x14, 0xF2, 0x40, 0x69, 0xFF, 0x97, 0xFC, 0x92, 0x03, 0x75, 0xFD,
- 0x55, 0x01, 0x8A, 0xFF, 0x11, 0x00, 0x01, 0x00, 0xEF, 0xFF, 0xF2,
- 0xFF, 0xD4, 0x00, 0x45, 0xFD, 0x3B, 0x06, 0xB8, 0xF3, 0xCE, 0x1B,
- 0xFB, 0x3D, 0x08, 0xFB, 0xDE, 0xFE, 0x73, 0x02, 0xEB, 0xFD, 0x33,
- 0x01, 0x8F, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xDE, 0xFF, 0x25, 0x00,
- 0x71, 0x00, 0xC8, 0xFD, 0xE5, 0x05, 0xFA, 0xF2, 0xDF, 0x22, 0xDB,
- 0x39, 0x94, 0xF7, 0xF7, 0x00, 0x4C, 0x01, 0x73, 0xFE, 0x03, 0x01,
- 0x9A, 0xFF, 0x0E, 0x00, 0x05, 0x00, 0xCC, 0xFF, 0x5E, 0x00, 0xF9,
- 0xFF, 0x80, 0xFE, 0x23, 0x05, 0xF9, 0xF2, 0xC0, 0x29, 0xB8, 0x34,
- 0x16, 0xF5, 0xCB, 0x02, 0x2F, 0x00, 0x03, 0xFF, 0xCA, 0x00, 0xAA,
- 0xFF, 0x0B, 0x00, 0x08, 0x00, 0xB8, 0xFF, 0x9B, 0x00, 0x72, 0xFF,
- 0x65, 0xFF, 0xF6, 0x03, 0xD1, 0xF3, 0x31, 0x30, 0xC1, 0x2E, 0x8B,
- 0xF3, 0x45, 0x04, 0x2D, 0xFF, 0x92, 0xFF, 0x8D, 0x00, 0xBD, 0xFF,
- 0x08, 0x00, 0x0C, 0x00, 0xA6, 0xFF, 0xD8, 0x00, 0xE2, 0xFE, 0x6F,
- 0x00, 0x66, 0x02, 0x93, 0xF5, 0xFB, 0x35, 0x31, 0x28, 0xE7, 0xF2,
- 0x59, 0x05, 0x51, 0xFE, 0x17, 0x00, 0x50, 0x00, 0xD0, 0xFF, 0x05,
- 0x00, 0x0E, 0x00, 0x97, 0xFF, 0x0F, 0x01, 0x53, 0xFE, 0x90, 0x01,
- 0x81, 0x00, 0x4B, 0xF8, 0xE6, 0x3A, 0x3F, 0x21, 0x16, 0xF3, 0x02,
- 0x06, 0xA5, 0xFD, 0x8A, 0x00, 0x18, 0x00, 0xE2, 0xFF, 0x02, 0x00,
- 0x10, 0x00, 0x8D, 0xFF, 0x3C, 0x01, 0xCE, 0xFD, 0xB7, 0x02, 0x5A,
- 0xFE, 0xF7, 0xFB, 0xC6, 0x3E, 0x2C, 0x1A, 0xFC, 0xF3, 0x41, 0x06,
- 0x2E, 0xFD, 0xE7, 0x00, 0xE7, 0xFF, 0xF2, 0xFF, 0x01, 0x00, 0x10,
- 0x00, 0x8B, 0xFF, 0x5A, 0x01, 0x5E, 0xFD, 0xD2, 0x03, 0x0E, 0xFC,
- 0x8B, 0x00, 0x75, 0x41, 0x32, 0x13, 0x75, 0xF5, 0x1C, 0x06, 0xEE,
- 0xFC, 0x2B, 0x01, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0E, 0x00,
- 0x91, 0xFF, 0x64, 0x01, 0x0D, 0xFD, 0xCD, 0x04, 0xBB, 0xF9, 0xF2,
- 0x05, 0xD9, 0x42, 0x88, 0x0C, 0x5E, 0xF7, 0xA1, 0x05, 0xE3, 0xFC,
- 0x54, 0x01, 0xA3, 0xFF, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
- 0x00, 0xA2, 0xFF, 0x56, 0x01, 0xE5, 0xFC, 0x94, 0x05, 0x87, 0xF7,
- 0x0A, 0x0C, 0xE6, 0x42, 0x64, 0x06, 0x8E, 0xF9, 0xDE, 0x04, 0x09,
- 0xFD, 0x64, 0x01, 0x92, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xBD, 0xFF, 0x2F, 0x01, 0xEC, 0xFC, 0x16, 0x06, 0x98, 0xF5, 0xAB,
- 0x12, 0x9C, 0x41, 0xEE, 0x00, 0xE0, 0xFB, 0xE6, 0x03, 0x57, 0xFD,
- 0x5B, 0x01, 0x8B, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF3, 0xFF, 0xE4,
- 0xFF, 0xED, 0x00, 0x27, 0xFD, 0x41, 0x06, 0x14, 0xF4, 0xA1, 0x19,
- 0x06, 0x3F, 0x49, 0xFC, 0x2E, 0xFE, 0xCD, 0x02, 0xC4, 0xFD, 0x3F,
- 0x01, 0x8D, 0xFF, 0x10, 0x00, 0x02, 0x00, 0xE3, 0xFF, 0x14, 0x00,
- 0x92, 0x00, 0x9A, 0xFD, 0x0A, 0x06, 0x22, 0xF3, 0xB4, 0x20, 0x3C,
- 0x3B, 0x8B, 0xF8, 0x58, 0x00, 0xA7, 0x01, 0x48, 0xFE, 0x13, 0x01,
- 0x96, 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD1, 0xFF, 0x4C, 0x00, 0x20,
- 0x00, 0x42, 0xFE, 0x6A, 0x05, 0xE3, 0xF2, 0xAB, 0x27, 0x66, 0x36,
- 0xC0, 0xF5, 0x44, 0x02, 0x85, 0x00, 0xD7, 0xFE, 0xDD, 0x00, 0xA5,
- 0xFF, 0x0C, 0x00, 0x07, 0x00, 0xBE, 0xFF, 0x89, 0x00, 0x9D, 0xFF,
- 0x1A, 0xFF, 0x5E, 0x04, 0x76, 0xF3, 0x45, 0x2E, 0xAA, 0x30, 0xEB,
- 0xF3, 0xDB, 0x03, 0x79, 0xFF, 0x67, 0xFF, 0xA0, 0x00, 0xB7, 0xFF,
- 0x09, 0x00, 0x0B, 0x00, 0xAC, 0xFF, 0xC6, 0x00, 0x0E, 0xFF, 0x1A,
- 0x00, 0xEB, 0x02, 0xEF, 0xF4, 0x49, 0x34, 0x43, 0x2A, 0x02, 0xF3,
- 0x0F, 0x05, 0x90, 0xFE, 0xEF, 0xFF, 0x63, 0x00, 0xCA, 0xFF, 0x06,
- 0x00, 0x0E, 0x00, 0x9B, 0xFF, 0xFF, 0x00, 0x7E, 0xFE, 0x36, 0x01,
- 0x1E, 0x01, 0x5B, 0xF7, 0x7E, 0x39, 0x69, 0x23, 0xF3, 0xF2, 0xD9,
- 0x05, 0xD4, 0xFD, 0x69, 0x00, 0x29, 0x00, 0xDD, 0xFF, 0x03, 0x00,
- 0x10, 0x00, 0x90, 0xFF, 0x30, 0x01, 0xF5, 0xFD, 0x5C, 0x02, 0x09,
- 0xFF, 0xBC, 0xFA, 0xB5, 0x3D, 0x5A, 0x1C, 0xA3, 0xF3, 0x38, 0x06,
- 0x4D, 0xFD, 0xCD, 0x00, 0xF5, 0xFF, 0xED, 0xFF, 0x01, 0x00, 0x11,
- 0x00, 0x8B, 0xFF, 0x53, 0x01, 0x7E, 0xFD, 0x7D, 0x03, 0xC5, 0xFC,
- 0x0B, 0xFF, 0xC3, 0x40, 0x51, 0x15, 0xF4, 0xF4, 0x31, 0x06, 0xFC,
- 0xFC, 0x19, 0x01, 0xCB, 0xFF, 0xFB, 0xFF, 0x00, 0x00, 0x0F, 0x00,
- 0x8E, 0xFF, 0x63, 0x01, 0x22, 0xFD, 0x84, 0x04, 0x71, 0xFA, 0x34,
- 0x04, 0x90, 0x42, 0x89, 0x0E, 0xBE, 0xF6, 0xCF, 0x05, 0xE1, 0xFC,
- 0x4A, 0x01, 0xAB, 0xFF, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B,
- 0x00, 0x9B, 0xFF, 0x5D, 0x01, 0xEC, 0xFC, 0x5D, 0x05, 0x2F, 0xF8,
- 0x19, 0x0A, 0x07, 0x43, 0x37, 0x08, 0xDD, 0xF8, 0x21, 0x05, 0xF8,
- 0xFC, 0x62, 0x01, 0x96, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x03, 0x00,
- 0xB4, 0xFF, 0x3E, 0x01, 0xE4, 0xFC, 0xF6, 0x05, 0x26, 0xF6, 0x95,
- 0x10, 0x26, 0x42, 0x87, 0x02, 0x28, 0xFB, 0x37, 0x04, 0x3B, 0xFD,
- 0x60, 0x01, 0x8C, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF7, 0xFF, 0xD7,
- 0xFF, 0x04, 0x01, 0x0F, 0xFD, 0x3E, 0x06, 0x7D, 0xF4, 0x76, 0x17,
- 0xF4, 0x3F, 0x9F, 0xFD, 0x7B, 0xFD, 0x26, 0x03, 0xA0, 0xFD, 0x4A,
- 0x01, 0x8B, 0xFF, 0x11, 0x00, 0x02, 0x00, 0xE9, 0xFF, 0x04, 0x00,
- 0xB1, 0x00, 0x71, 0xFD, 0x26, 0x06, 0x5A, 0xF3, 0x88, 0x1E, 0x87,
- 0x3C, 0x98, 0xF9, 0xB3, 0xFF, 0x02, 0x02, 0x1E, 0xFE, 0x22, 0x01,
- 0x93, 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD7, 0xFF, 0x3A, 0x00, 0x45,
- 0x00, 0x09, 0xFE, 0xA7, 0x05, 0xE1, 0xF2, 0x8D, 0x25, 0xFD, 0x37,
- 0x82, 0xF6, 0xB5, 0x01, 0xDC, 0x00, 0xAA, 0xFE, 0xEE, 0x00, 0xA0,
- 0xFF, 0x0D, 0x00, 0x06, 0x00, 0xC4, 0xFF, 0x76, 0x00, 0xC7, 0xFF,
- 0xD3, 0xFE, 0xBC, 0x04, 0x31, 0xF3, 0x4A, 0x2C, 0x83, 0x32, 0x61,
- 0xF4, 0x68, 0x03, 0xC8, 0xFF, 0x3B, 0xFF, 0xB3, 0x00, 0xB1, 0xFF,
- 0x0A, 0x00, 0x0A, 0x00, 0xB1, 0xFF, 0xB3, 0x00, 0x3B, 0xFF, 0xC8,
- 0xFF, 0x68, 0x03, 0x61, 0xF4, 0x83, 0x32, 0x4A, 0x2C, 0x31, 0xF3,
- 0xBC, 0x04, 0xD3, 0xFE, 0xC7, 0xFF, 0x76, 0x00, 0xC4, 0xFF, 0x06,
- 0x00, 0x0D, 0x00, 0xA0, 0xFF, 0xEE, 0x00, 0xAA, 0xFE, 0xDC, 0x00,
- 0xB5, 0x01, 0x82, 0xF6, 0xFD, 0x37, 0x8D, 0x25, 0xE1, 0xF2, 0xA7,
- 0x05, 0x09, 0xFE, 0x45, 0x00, 0x3A, 0x00, 0xD7, 0xFF, 0x04, 0x00,
- 0x0F, 0x00, 0x93, 0xFF, 0x22, 0x01, 0x1E, 0xFE, 0x02, 0x02, 0xB3,
- 0xFF, 0x98, 0xF9, 0x87, 0x3C, 0x88, 0x1E, 0x5A, 0xF3, 0x26, 0x06,
- 0x71, 0xFD, 0xB1, 0x00, 0x04, 0x00, 0xE9, 0xFF, 0x02, 0x00, 0x11,
- 0x00, 0x8B, 0xFF, 0x4A, 0x01, 0xA0, 0xFD, 0x26, 0x03, 0x7B, 0xFD,
- 0x9F, 0xFD, 0xF4, 0x3F, 0x76, 0x17, 0x7D, 0xF4, 0x3E, 0x06, 0x0F,
- 0xFD, 0x04, 0x01, 0xD7, 0xFF, 0xF7, 0xFF, 0x01, 0x00, 0x10, 0x00,
- 0x8C, 0xFF, 0x60, 0x01, 0x3B, 0xFD, 0x37, 0x04, 0x28, 0xFB, 0x87,
- 0x02, 0x26, 0x42, 0x95, 0x10, 0x26, 0xF6, 0xF6, 0x05, 0xE4, 0xFC,
- 0x3E, 0x01, 0xB4, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x96,
- 0xFF, 0x62, 0x01, 0xF8, 0xFC, 0x21, 0x05, 0xDD, 0xF8, 0x37, 0x08,
- 0x07, 0x43, 0x19, 0x0A, 0x2F, 0xF8, 0x5D, 0x05, 0xEC, 0xFC, 0x5D,
- 0x01, 0x9B, 0xFF, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
- 0xAB, 0xFF, 0x4A, 0x01, 0xE1, 0xFC, 0xCF, 0x05, 0xBE, 0xF6, 0x89,
- 0x0E, 0x90, 0x42, 0x34, 0x04, 0x71, 0xFA, 0x84, 0x04, 0x22, 0xFD,
- 0x63, 0x01, 0x8E, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0xFB, 0xFF, 0xCB,
- 0xFF, 0x19, 0x01, 0xFC, 0xFC, 0x31, 0x06, 0xF4, 0xF4, 0x51, 0x15,
- 0xC3, 0x40, 0x0B, 0xFF, 0xC5, 0xFC, 0x7D, 0x03, 0x7E, 0xFD, 0x53,
- 0x01, 0x8B, 0xFF, 0x11, 0x00, 0x01, 0x00, 0xED, 0xFF, 0xF5, 0xFF,
- 0xCD, 0x00, 0x4D, 0xFD, 0x38, 0x06, 0xA3, 0xF3, 0x5A, 0x1C, 0xB5,
- 0x3D, 0xBC, 0xFA, 0x09, 0xFF, 0x5C, 0x02, 0xF5, 0xFD, 0x30, 0x01,
- 0x90, 0xFF, 0x10, 0x00, 0x03, 0x00, 0xDD, 0xFF, 0x29, 0x00, 0x69,
- 0x00, 0xD4, 0xFD, 0xD9, 0x05, 0xF3, 0xF2, 0x69, 0x23, 0x7E, 0x39,
- 0x5B, 0xF7, 0x1E, 0x01, 0x36, 0x01, 0x7E, 0xFE, 0xFF, 0x00, 0x9B,
- 0xFF, 0x0E, 0x00, 0x06, 0x00, 0xCA, 0xFF, 0x63, 0x00, 0xEF, 0xFF,
- 0x90, 0xFE, 0x0F, 0x05, 0x02, 0xF3, 0x43, 0x2A, 0x49, 0x34, 0xEF,
- 0xF4, 0xEB, 0x02, 0x1A, 0x00, 0x0E, 0xFF, 0xC6, 0x00, 0xAC, 0xFF,
- 0x0B, 0x00, 0x09, 0x00, 0xB7, 0xFF, 0xA0, 0x00, 0x67, 0xFF, 0x79,
- 0xFF, 0xDB, 0x03, 0xEB, 0xF3, 0xAA, 0x30, 0x45, 0x2E, 0x76, 0xF3,
- 0x5E, 0x04, 0x1A, 0xFF, 0x9D, 0xFF, 0x89, 0x00, 0xBE, 0xFF, 0x07,
- 0x00, 0x0C, 0x00, 0xA5, 0xFF, 0xDD, 0x00, 0xD7, 0xFE, 0x85, 0x00,
- 0x44, 0x02, 0xC0, 0xF5, 0x66, 0x36, 0xAB, 0x27, 0xE3, 0xF2, 0x6A,
- 0x05, 0x42, 0xFE, 0x20, 0x00, 0x4C, 0x00, 0xD1, 0xFF, 0x04, 0x00,
- 0x0F, 0x00, 0x96, 0xFF, 0x13, 0x01, 0x48, 0xFE, 0xA7, 0x01, 0x58,
- 0x00, 0x8B, 0xF8, 0x3C, 0x3B, 0xB4, 0x20, 0x22, 0xF3, 0x0A, 0x06,
- 0x9A, 0xFD, 0x92, 0x00, 0x14, 0x00, 0xE3, 0xFF, 0x02, 0x00, 0x10,
- 0x00, 0x8D, 0xFF, 0x3F, 0x01, 0xC4, 0xFD, 0xCD, 0x02, 0x2E, 0xFE,
- 0x49, 0xFC, 0x06, 0x3F, 0xA1, 0x19, 0x14, 0xF4, 0x41, 0x06, 0x27,
- 0xFD, 0xED, 0x00, 0xE4, 0xFF, 0xF3, 0xFF, 0x01, 0x00, 0x10, 0x00,
- 0x8B, 0xFF, 0x5B, 0x01, 0x57, 0xFD, 0xE6, 0x03, 0xE0, 0xFB, 0xEE,
- 0x00, 0x9C, 0x41, 0xAB, 0x12, 0x98, 0xF5, 0x16, 0x06, 0xEC, 0xFC,
- 0x2F, 0x01, 0xBD, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x92,
- 0xFF, 0x64, 0x01, 0x09, 0xFD, 0xDE, 0x04, 0x8E, 0xF9, 0x64, 0x06,
- 0xE6, 0x42, 0x0A, 0x0C, 0x87, 0xF7, 0x94, 0x05, 0xE5, 0xFC, 0x56,
- 0x01, 0xA2, 0xFF, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
- 0xA3, 0xFF, 0x54, 0x01, 0xE3, 0xFC, 0xA1, 0x05, 0x5E, 0xF7, 0x88,
- 0x0C, 0xD9, 0x42, 0xF2, 0x05, 0xBB, 0xF9, 0xCD, 0x04, 0x0D, 0xFD,
- 0x64, 0x01, 0x91, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0,
- 0xFF, 0x2B, 0x01, 0xEE, 0xFC, 0x1C, 0x06, 0x75, 0xF5, 0x32, 0x13,
- 0x75, 0x41, 0x8B, 0x00, 0x0E, 0xFC, 0xD2, 0x03, 0x5E, 0xFD, 0x5A,
- 0x01, 0x8B, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF2, 0xFF, 0xE7, 0xFF,
- 0xE7, 0x00, 0x2E, 0xFD, 0x41, 0x06, 0xFC, 0xF3, 0x2C, 0x1A, 0xC6,
- 0x3E, 0xF7, 0xFB, 0x5A, 0xFE, 0xB7, 0x02, 0xCE, 0xFD, 0x3C, 0x01,
- 0x8D, 0xFF, 0x10, 0x00, 0x02, 0x00, 0xE2, 0xFF, 0x18, 0x00, 0x8A,
- 0x00, 0xA5, 0xFD, 0x02, 0x06, 0x16, 0xF3, 0x3F, 0x21, 0xE6, 0x3A,
- 0x4B, 0xF8, 0x81, 0x00, 0x90, 0x01, 0x53, 0xFE, 0x0F, 0x01, 0x97,
- 0xFF, 0x0E, 0x00, 0x05, 0x00, 0xD0, 0xFF, 0x50, 0x00, 0x17, 0x00,
- 0x51, 0xFE, 0x59, 0x05, 0xE7, 0xF2, 0x31, 0x28, 0xFB, 0x35, 0x93,
- 0xF5, 0x66, 0x02, 0x6F, 0x00, 0xE2, 0xFE, 0xD8, 0x00, 0xA6, 0xFF,
- 0x0C, 0x00, 0x08, 0x00, 0xBD, 0xFF, 0x8D, 0x00, 0x92, 0xFF, 0x2D,
- 0xFF, 0x45, 0x04, 0x8B, 0xF3, 0xC1, 0x2E, 0x31, 0x30, 0xD1, 0xF3,
- 0xF6, 0x03, 0x65, 0xFF, 0x72, 0xFF, 0x9B, 0x00, 0xB8, 0xFF, 0x08,
- 0x00, 0x0B, 0x00, 0xAA, 0xFF, 0xCA, 0x00, 0x03, 0xFF, 0x2F, 0x00,
- 0xCB, 0x02, 0x16, 0xF5, 0xB8, 0x34, 0xC0, 0x29, 0xF9, 0xF2, 0x23,
- 0x05, 0x80, 0xFE, 0xF9, 0xFF, 0x5E, 0x00, 0xCC, 0xFF, 0x05, 0x00,
- 0x0E, 0x00, 0x9A, 0xFF, 0x03, 0x01, 0x73, 0xFE, 0x4C, 0x01, 0xF7,
- 0x00, 0x94, 0xF7, 0xDB, 0x39, 0xDF, 0x22, 0xFA, 0xF2, 0xE5, 0x05,
- 0xC8, 0xFD, 0x71, 0x00, 0x25, 0x00, 0xDE, 0xFF, 0x03, 0x00, 0x10,
- 0x00, 0x8F, 0xFF, 0x33, 0x01, 0xEB, 0xFD, 0x73, 0x02, 0xDE, 0xFE,
- 0x08, 0xFB, 0xFB, 0x3D, 0xCE, 0x1B, 0xB8, 0xF3, 0x3B, 0x06, 0x45,
- 0xFD, 0xD4, 0x00, 0xF2, 0xFF, 0xEF, 0xFF, 0x01, 0x00, 0x11, 0x00,
- 0x8A, 0xFF, 0x55, 0x01, 0x75, 0xFD, 0x92, 0x03, 0x97, 0xFC, 0x69,
- 0xFF, 0xF2, 0x40, 0xC8, 0x14, 0x13, 0xF5, 0x2D, 0x06, 0xF8, 0xFC,
- 0x1E, 0x01, 0xC8, 0xFF, 0xFC, 0xFF, 0x00, 0x00, 0x0F, 0x00, 0x8F,
- 0xFF, 0x64, 0x01, 0x1D, 0xFD, 0x97, 0x04, 0x43, 0xFA, 0xA1, 0x04,
- 0xA5, 0x42, 0x08, 0x0E, 0xE6, 0xF6, 0xC4, 0x05, 0xE1, 0xFC, 0x4D,
- 0x01, 0xA9, 0xFF, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00,
- 0x9D, 0xFF, 0x5C, 0x01, 0xEA, 0xFC, 0x6C, 0x05, 0x05, 0xF8, 0x94,
- 0x0A, 0x03, 0x43, 0xC1, 0x07, 0x09, 0xF9, 0x10, 0x05, 0xFC, 0xFC,
- 0x62, 0x01, 0x95, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x02, 0x00, 0xB6,
- 0xFF, 0x3B, 0x01, 0xE5, 0xFC, 0xFF, 0x05, 0x02, 0xF6, 0x19, 0x11,
- 0x06, 0x42, 0x1F, 0x02, 0x56, 0xFB, 0x23, 0x04, 0x41, 0xFD, 0x5F,
- 0x01, 0x8B, 0xFF, 0x10, 0x00, 0x01, 0x00, 0xF6, 0xFF, 0xDA, 0xFF,
- 0xFF, 0x00, 0x15, 0xFD, 0x40, 0x06, 0x62, 0xF4, 0x01, 0x18, 0xBB,
- 0x3F, 0x47, 0xFD, 0xA8, 0xFD, 0x10, 0x03, 0xA9, 0xFD, 0x47, 0x01,
- 0x8C, 0xFF, 0x11, 0x00, 0x02, 0x00, 0xE7, 0xFF, 0x08, 0x00, 0xA9,
- 0x00, 0x7B, 0xFD, 0x20, 0x06, 0x4B, 0xF3, 0x13, 0x1F, 0x36, 0x3C,
- 0x52, 0xF9, 0xDD, 0xFF, 0xEB, 0x01, 0x28, 0xFE, 0x1F, 0x01, 0x93,
- 0xFF, 0x0F, 0x00, 0x04, 0x00, 0xD6, 0xFF, 0x3F, 0x00, 0x3C, 0x00,
- 0x16, 0xFE, 0x98, 0x05, 0xE0, 0xF2, 0x16, 0x26, 0x99, 0x37, 0x4F,
- 0xF6, 0xD9, 0x01, 0xC6, 0x00, 0xB5, 0xFE, 0xEA, 0x00, 0xA1, 0xFF,
- 0x0D, 0x00, 0x07, 0x00, 0xC3, 0xFF, 0x7A, 0x00, 0xBC, 0xFF, 0xE4,
- 0xFE, 0xA5, 0x04, 0x41, 0xF3, 0xCA, 0x2C, 0x0E, 0x32, 0x42, 0xF4,
- 0x85, 0x03, 0xB4, 0xFF, 0x46, 0xFF, 0xAE, 0x00, 0xB3, 0xFF, 0x09,
- 0x00, 0x0A, 0x00, 0xB0, 0xFF, 0xB8, 0x00, 0x30, 0xFF, 0xDC, 0xFF,
- 0x49, 0x03, 0x83, 0xF4, 0xF5, 0x32, 0xC9, 0x2B, 0x23, 0xF3, 0xD1,
- 0x04, 0xC2, 0xFE, 0xD1, 0xFF, 0x71, 0x00, 0xC6, 0xFF, 0x06, 0x00,
- 0x0D, 0x00, 0x9F, 0xFF, 0xF3, 0x00, 0x9F, 0xFE, 0xF3, 0x00, 0x90,
- 0x01, 0xB6, 0xF6, 0x5F, 0x38, 0x04, 0x25, 0xE4, 0xF2, 0xB4, 0x05,
- 0xFB, 0xFD, 0x4E, 0x00, 0x36, 0x00, 0xD9, 0xFF, 0x04, 0x00, 0x0F,
- 0x00, 0x92, 0xFF, 0x26, 0x01, 0x13, 0xFE, 0x18, 0x02, 0x89, 0xFF,
- 0xDF, 0xF9, 0xD3, 0x3C, 0xFC, 0x1D, 0x6B, 0xF3, 0x2C, 0x06, 0x67,
- 0xFD, 0xB8, 0x00, 0x00, 0x00, 0xEA, 0xFF, 0x02, 0x00, 0x11, 0x00,
- 0x8B, 0xFF, 0x4C, 0x01, 0x97, 0xFD, 0x3C, 0x03, 0x4D, 0xFD, 0xF8,
- 0xFD, 0x2A, 0x40, 0xED, 0x16, 0x9A, 0xF4, 0x3C, 0x06, 0x0A, 0xFD,
- 0x0A, 0x01, 0xD4, 0xFF, 0xF8, 0xFF, 0x01, 0x00, 0x10, 0x00, 0x8C,
- 0xFF, 0x61, 0x01, 0x34, 0xFD, 0x4B, 0x04, 0xFA, 0xFA, 0xF1, 0x02,
- 0x42, 0x42, 0x11, 0x10, 0x4C, 0xF6, 0xED, 0x05, 0xE3, 0xFC, 0x41,
- 0x01, 0xB1, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x97, 0xFF,
- 0x61, 0x01, 0xF5, 0xFC, 0x30, 0x05, 0xB1, 0xF8, 0xAE, 0x08, 0x0A,
- 0x43, 0x9F, 0x09, 0x5A, 0xF8, 0x4F, 0x05, 0xEF, 0xFC, 0x5F, 0x01,
- 0x9A, 0xFF, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0xAD,
- 0xFF, 0x48, 0x01, 0xE2, 0xFC, 0xDA, 0x05, 0x97, 0xF6, 0x0B, 0x0F,
- 0x79, 0x42, 0xC7, 0x03, 0x9E, 0xFA, 0x71, 0x04, 0x28, 0xFD, 0x63,
- 0x01, 0x8D, 0xFF, 0x0F, 0x00
-};
-
-static u16
-coefficient_sizes[8 * 2] = {
- /* Playback */
- 0x00C0, 0x5000, 0x0060, 0x2800, 0x0040, 0x0060, 0x1400, 0x0000,
- /* capture */
- 0x0020, 0x1260, 0x0020, 0x1260, 0x0000, 0x0040, 0x1260, 0x0000,
-};
-
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/Makefile b/ANDROID_3.4.5/sound/pci/oxygen/Makefile
deleted file mode 100644
index 0f872655..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o
-snd-oxygen-objs := oxygen.o xonar_dg.o
-snd-virtuoso-objs := virtuoso.o xonar_lib.o \
- xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o
-
-obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o
-obj-$(CONFIG_SND_OXYGEN) += snd-oxygen.o
-obj-$(CONFIG_SND_VIRTUOSO) += snd-virtuoso.o
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/ak4396.h b/ANDROID_3.4.5/sound/pci/oxygen/ak4396.h
deleted file mode 100644
index 551c1cf8..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/ak4396.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef AK4396_H_INCLUDED
-#define AK4396_H_INCLUDED
-
-#define AK4396_WRITE 0x2000
-
-#define AK4396_CONTROL_1 0
-#define AK4396_CONTROL_2 1
-#define AK4396_CONTROL_3 2
-#define AK4396_LCH_ATT 3
-#define AK4396_RCH_ATT 4
-
-/* control 1 */
-#define AK4396_RSTN 0x01
-#define AK4396_DIF_MASK 0x0e
-#define AK4396_DIF_16_LSB 0x00
-#define AK4396_DIF_20_LSB 0x02
-#define AK4396_DIF_24_MSB 0x04
-#define AK4396_DIF_24_I2S 0x06
-#define AK4396_DIF_24_LSB 0x08
-#define AK4396_ACKS 0x80
-/* control 2 */
-#define AK4396_SMUTE 0x01
-#define AK4396_DEM_MASK 0x06
-#define AK4396_DEM_441 0x00
-#define AK4396_DEM_OFF 0x02
-#define AK4396_DEM_48 0x04
-#define AK4396_DEM_32 0x06
-#define AK4396_DFS_MASK 0x18
-#define AK4396_DFS_NORMAL 0x00
-#define AK4396_DFS_DOUBLE 0x08
-#define AK4396_DFS_QUAD 0x10
-#define AK4396_SLOW 0x20
-#define AK4396_DZFM 0x40
-#define AK4396_DZFE 0x80
-/* control 3 */
-#define AK4396_DZFB 0x04
-#define AK4396_DCKB 0x10
-#define AK4396_DCKS 0x20
-#define AK4396_DSDM 0x40
-#define AK4396_D_P_MASK 0x80
-#define AK4396_PCM 0x00
-#define AK4396_DSD 0x80
-
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/cm9780.h b/ANDROID_3.4.5/sound/pci/oxygen/cm9780.h
deleted file mode 100644
index 14459679..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/cm9780.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef CM9780_H_INCLUDED
-#define CM9780_H_INCLUDED
-
-#define CM9780_JACK 0x62
-#define CM9780_MIXER 0x64
-#define CM9780_GPIO_SETUP 0x70
-#define CM9780_GPIO_STATUS 0x72
-
-/* jack control */
-#define CM9780_RSOE 0x0001
-#define CM9780_CBOE 0x0002
-#define CM9780_SSOE 0x0004
-#define CM9780_FROE 0x0008
-#define CM9780_HP2FMICOE 0x0010
-#define CM9780_CB2MICOE 0x0020
-#define CM9780_FMIC2LI 0x0040
-#define CM9780_FMIC2MIC 0x0080
-#define CM9780_HP2LI 0x0100
-#define CM9780_HP2MIC 0x0200
-#define CM9780_MIC2LI 0x0400
-#define CM9780_MIC2MIC 0x0800
-#define CM9780_LI2LI 0x1000
-#define CM9780_LI2MIC 0x2000
-#define CM9780_LO2LI 0x4000
-#define CM9780_LO2MIC 0x8000
-
-/* mixer control */
-#define CM9780_BSTSEL 0x0001
-#define CM9780_STRO_MIC 0x0002
-#define CM9780_SPDI_FREX 0x0004
-#define CM9780_SPDI_SSEX 0x0008
-#define CM9780_SPDI_CBEX 0x0010
-#define CM9780_SPDI_RSEX 0x0020
-#define CM9780_MIX2FR 0x0040
-#define CM9780_MIX2SS 0x0080
-#define CM9780_MIX2CB 0x0100
-#define CM9780_MIX2RS 0x0200
-#define CM9780_MIX2FR_EX 0x0400
-#define CM9780_MIX2SS_EX 0x0800
-#define CM9780_MIX2CB_EX 0x1000
-#define CM9780_MIX2RS_EX 0x2000
-#define CM9780_P47_IO 0x4000
-#define CM9780_PCBSW 0x8000
-
-/* GPIO setup */
-#define CM9780_GPI0EN 0x0001
-#define CM9780_GPI1EN 0x0002
-#define CM9780_SENSE_P 0x0004
-#define CM9780_LOCK_P 0x0008
-#define CM9780_GPIO0P 0x0010
-#define CM9780_GPIO1P 0x0020
-#define CM9780_GPIO0IO 0x0100
-#define CM9780_GPIO1IO 0x0200
-
-/* GPIO status */
-#define CM9780_GPO0 0x0001
-#define CM9780_GPO1 0x0002
-#define CM9780_GPIO0S 0x0010
-#define CM9780_GPIO1S 0x0020
-#define CM9780_GPII0S 0x0100
-#define CM9780_GPII1S 0x0200
-
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/cs2000.h b/ANDROID_3.4.5/sound/pci/oxygen/cs2000.h
deleted file mode 100644
index c3501bdb..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/cs2000.h
+++ /dev/null
@@ -1,83 +0,0 @@
-#ifndef CS2000_H_INCLUDED
-#define CS2000_H_INCLUDED
-
-#define CS2000_DEV_ID 0x01
-#define CS2000_DEV_CTRL 0x02
-#define CS2000_DEV_CFG_1 0x03
-#define CS2000_DEV_CFG_2 0x04
-#define CS2000_GLOBAL_CFG 0x05
-#define CS2000_RATIO_0 0x06 /* 32 bits, big endian */
-#define CS2000_RATIO_1 0x0a
-#define CS2000_RATIO_2 0x0e
-#define CS2000_RATIO_3 0x12
-#define CS2000_FUN_CFG_1 0x16
-#define CS2000_FUN_CFG_2 0x17
-#define CS2000_FUN_CFG_3 0x1e
-
-/* DEV_ID */
-#define CS2000_DEVICE_MASK 0xf8
-#define CS2000_REVISION_MASK 0x07
-
-/* DEV_CTRL */
-#define CS2000_UNLOCK 0x80
-#define CS2000_AUX_OUT_DIS 0x02
-#define CS2000_CLK_OUT_DIS 0x01
-
-/* DEV_CFG_1 */
-#define CS2000_R_MOD_SEL_MASK 0xe0
-#define CS2000_R_MOD_SEL_1 0x00
-#define CS2000_R_MOD_SEL_2 0x20
-#define CS2000_R_MOD_SEL_4 0x40
-#define CS2000_R_MOD_SEL_8 0x60
-#define CS2000_R_MOD_SEL_1_2 0x80
-#define CS2000_R_MOD_SEL_1_4 0xa0
-#define CS2000_R_MOD_SEL_1_8 0xc0
-#define CS2000_R_MOD_SEL_1_16 0xe0
-#define CS2000_R_SEL_MASK 0x18
-#define CS2000_R_SEL_SHIFT 3
-#define CS2000_AUX_OUT_SRC_MASK 0x06
-#define CS2000_AUX_OUT_SRC_REF_CLK 0x00
-#define CS2000_AUX_OUT_SRC_CLK_IN 0x02
-#define CS2000_AUX_OUT_SRC_CLK_OUT 0x04
-#define CS2000_AUX_OUT_SRC_PLL_LOCK 0x06
-#define CS2000_EN_DEV_CFG_1 0x01
-
-/* DEV_CFG_2 */
-#define CS2000_LOCK_CLK_MASK 0x06
-#define CS2000_LOCK_CLK_SHIFT 1
-#define CS2000_FRAC_N_SRC_MASK 0x01
-#define CS2000_FRAC_N_SRC_STATIC 0x00
-#define CS2000_FRAC_N_SRC_DYNAMIC 0x01
-
-/* GLOBAL_CFG */
-#define CS2000_FREEZE 0x08
-#define CS2000_EN_DEV_CFG_2 0x01
-
-/* FUN_CFG_1 */
-#define CS2000_CLK_SKIP_EN 0x80
-#define CS2000_AUX_LOCK_CFG_MASK 0x40
-#define CS2000_AUX_LOCK_CFG_PP_HIGH 0x00
-#define CS2000_AUX_LOCK_CFG_OD_LOW 0x40
-#define CS2000_REF_CLK_DIV_MASK 0x18
-#define CS2000_REF_CLK_DIV_4 0x00
-#define CS2000_REF_CLK_DIV_2 0x08
-#define CS2000_REF_CLK_DIV_1 0x10
-
-/* FUN_CFG_2 */
-#define CS2000_CLK_OUT_UNL 0x10
-#define CS2000_L_F_RATIO_CFG_MASK 0x08
-#define CS2000_L_F_RATIO_CFG_20_12 0x00
-#define CS2000_L_F_RATIO_CFG_12_20 0x08
-
-/* FUN_CFG_3 */
-#define CS2000_CLK_IN_BW_MASK 0x70
-#define CS2000_CLK_IN_BW_1 0x00
-#define CS2000_CLK_IN_BW_2 0x10
-#define CS2000_CLK_IN_BW_4 0x20
-#define CS2000_CLK_IN_BW_8 0x30
-#define CS2000_CLK_IN_BW_16 0x40
-#define CS2000_CLK_IN_BW_32 0x50
-#define CS2000_CLK_IN_BW_64 0x60
-#define CS2000_CLK_IN_BW_128 0x70
-
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/cs4245.h b/ANDROID_3.4.5/sound/pci/oxygen/cs4245.h
deleted file mode 100644
index 5e0197e0..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/cs4245.h
+++ /dev/null
@@ -1,107 +0,0 @@
-#define CS4245_CHIP_ID 0x01
-#define CS4245_POWER_CTRL 0x02
-#define CS4245_DAC_CTRL_1 0x03
-#define CS4245_ADC_CTRL 0x04
-#define CS4245_MCLK_FREQ 0x05
-#define CS4245_SIGNAL_SEL 0x06
-#define CS4245_PGA_B_CTRL 0x07
-#define CS4245_PGA_A_CTRL 0x08
-#define CS4245_ANALOG_IN 0x09
-#define CS4245_DAC_A_CTRL 0x0a
-#define CS4245_DAC_B_CTRL 0x0b
-#define CS4245_DAC_CTRL_2 0x0c
-#define CS4245_INT_STATUS 0x0d
-#define CS4245_INT_MASK 0x0e
-#define CS4245_INT_MODE_MSB 0x0f
-#define CS4245_INT_MODE_LSB 0x10
-
-/* Chip ID */
-#define CS4245_CHIP_PART_MASK 0xf0
-#define CS4245_CHIP_REV_MASK 0x0f
-
-/* Power Control */
-#define CS4245_FREEZE 0x80
-#define CS4245_PDN_MIC 0x08
-#define CS4245_PDN_ADC 0x04
-#define CS4245_PDN_DAC 0x02
-#define CS4245_PDN 0x01
-
-/* DAC Control */
-#define CS4245_DAC_FM_MASK 0xc0
-#define CS4245_DAC_FM_SINGLE 0x00
-#define CS4245_DAC_FM_DOUBLE 0x40
-#define CS4245_DAC_FM_QUAD 0x80
-#define CS4245_DAC_DIF_MASK 0x30
-#define CS4245_DAC_DIF_LJUST 0x00
-#define CS4245_DAC_DIF_I2S 0x10
-#define CS4245_DAC_DIF_RJUST_16 0x20
-#define CS4245_DAC_DIF_RJUST_24 0x30
-#define CS4245_RESERVED_1 0x08
-#define CS4245_MUTE_DAC 0x04
-#define CS4245_DEEMPH 0x02
-#define CS4245_DAC_MASTER 0x01
-
-/* ADC Control */
-#define CS4245_ADC_FM_MASK 0xc0
-#define CS4245_ADC_FM_SINGLE 0x00
-#define CS4245_ADC_FM_DOUBLE 0x40
-#define CS4245_ADC_FM_QUAD 0x80
-#define CS4245_ADC_DIF_MASK 0x10
-#define CS4245_ADC_DIF_LJUST 0x00
-#define CS4245_ADC_DIF_I2S 0x10
-#define CS4245_MUTE_ADC 0x04
-#define CS4245_HPF_FREEZE 0x02
-#define CS4245_ADC_MASTER 0x01
-
-/* MCLK Frequency */
-#define CS4245_MCLK1_MASK 0x70
-#define CS4245_MCLK1_SHIFT 4
-#define CS4245_MCLK2_MASK 0x07
-#define CS4245_MCLK2_SHIFT 0
-#define CS4245_MCLK_1 0
-#define CS4245_MCLK_1_5 1
-#define CS4245_MCLK_2 2
-#define CS4245_MCLK_3 3
-#define CS4245_MCLK_4 4
-
-/* Signal Selection */
-#define CS4245_A_OUT_SEL_MASK 0x60
-#define CS4245_A_OUT_SEL_HIZ 0x00
-#define CS4245_A_OUT_SEL_DAC 0x20
-#define CS4245_A_OUT_SEL_PGA 0x40
-#define CS4245_LOOP 0x02
-#define CS4245_ASYNCH 0x01
-
-/* Channel B/A PGA Control */
-#define CS4245_PGA_GAIN_MASK 0x3f
-
-/* ADC Input Control */
-#define CS4245_PGA_SOFT 0x10
-#define CS4245_PGA_ZERO 0x08
-#define CS4245_SEL_MASK 0x07
-#define CS4245_SEL_MIC 0x00
-#define CS4245_SEL_INPUT_1 0x01
-#define CS4245_SEL_INPUT_2 0x02
-#define CS4245_SEL_INPUT_3 0x03
-#define CS4245_SEL_INPUT_4 0x04
-#define CS4245_SEL_INPUT_5 0x05
-#define CS4245_SEL_INPUT_6 0x06
-
-/* DAC Channel A/B Volume Control */
-#define CS4245_VOL_MASK 0xff
-
-/* DAC Control 2 */
-#define CS4245_DAC_SOFT 0x80
-#define CS4245_DAC_ZERO 0x40
-#define CS4245_INVERT_DAC 0x20
-#define CS4245_INT_ACTIVE_HIGH 0x01
-
-/* Interrupt Status/Mask/Mode */
-#define CS4245_ADC_CLK_ERR 0x08
-#define CS4245_DAC_CLK_ERR 0x04
-#define CS4245_ADC_OVFL 0x02
-#define CS4245_ADC_UNDRFL 0x01
-
-
-#define CS4245_SPI_ADDRESS (0x9e << 16)
-#define CS4245_SPI_WRITE (0 << 16)
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/cs4362a.h b/ANDROID_3.4.5/sound/pci/oxygen/cs4362a.h
deleted file mode 100644
index 6a4fedf5..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/cs4362a.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* register 01h */
-#define CS4362A_PDN 0x01
-#define CS4362A_DAC1_DIS 0x02
-#define CS4362A_DAC2_DIS 0x04
-#define CS4362A_DAC3_DIS 0x08
-#define CS4362A_MCLKDIV 0x20
-#define CS4362A_FREEZE 0x40
-#define CS4362A_CPEN 0x80
-/* register 02h */
-#define CS4362A_DIF_MASK 0x70
-#define CS4362A_DIF_LJUST 0x00
-#define CS4362A_DIF_I2S 0x10
-#define CS4362A_DIF_RJUST_16 0x20
-#define CS4362A_DIF_RJUST_24 0x30
-#define CS4362A_DIF_RJUST_20 0x40
-#define CS4362A_DIF_RJUST_18 0x50
-/* register 03h */
-#define CS4362A_MUTEC_MASK 0x03
-#define CS4362A_MUTEC_6 0x00
-#define CS4362A_MUTEC_1 0x01
-#define CS4362A_MUTEC_3 0x03
-#define CS4362A_AMUTE 0x04
-#define CS4362A_MUTEC_POL 0x08
-#define CS4362A_RMP_UP 0x10
-#define CS4362A_SNGLVOL 0x20
-#define CS4362A_ZERO_CROSS 0x40
-#define CS4362A_SOFT_RAMP 0x80
-/* register 04h */
-#define CS4362A_RMP_DN 0x01
-#define CS4362A_DEM_MASK 0x06
-#define CS4362A_DEM_NONE 0x00
-#define CS4362A_DEM_44100 0x02
-#define CS4362A_DEM_48000 0x04
-#define CS4362A_DEM_32000 0x06
-#define CS4362A_FILT_SEL 0x10
-/* register 05h */
-#define CS4362A_INV_A1 0x01
-#define CS4362A_INV_B1 0x02
-#define CS4362A_INV_A2 0x04
-#define CS4362A_INV_B2 0x08
-#define CS4362A_INV_A3 0x10
-#define CS4362A_INV_B3 0x20
-/* register 06h */
-#define CS4362A_FM_MASK 0x03
-#define CS4362A_FM_SINGLE 0x00
-#define CS4362A_FM_DOUBLE 0x01
-#define CS4362A_FM_QUAD 0x02
-#define CS4362A_FM_DSD 0x03
-#define CS4362A_ATAPI_MASK 0x7c
-#define CS4362A_ATAPI_B_MUTE 0x00
-#define CS4362A_ATAPI_B_R 0x04
-#define CS4362A_ATAPI_B_L 0x08
-#define CS4362A_ATAPI_B_LR 0x0c
-#define CS4362A_ATAPI_A_MUTE 0x00
-#define CS4362A_ATAPI_A_R 0x10
-#define CS4362A_ATAPI_A_L 0x20
-#define CS4362A_ATAPI_A_LR 0x30
-#define CS4362A_ATAPI_MIX_LR_VOL 0x40
-#define CS4362A_A_EQ_B 0x80
-/* register 07h */
-#define CS4362A_VOL_MASK 0x7f
-#define CS4362A_MUTE 0x80
-/* register 08h: like 07h */
-/* registers 09h..0Bh: like 06h..08h */
-/* registers 0Ch..0Eh: like 06h..08h */
-/* register 12h */
-#define CS4362A_REV_MASK 0x07
-#define CS4362A_PART_MASK 0xf8
-#define CS4362A_PART_CS4362A 0x50
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/cs4398.h b/ANDROID_3.4.5/sound/pci/oxygen/cs4398.h
deleted file mode 100644
index 5faf5efc..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/cs4398.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* register 1 */
-#define CS4398_REV_MASK 0x07
-#define CS4398_PART_MASK 0xf8
-#define CS4398_PART_CS4398 0x70
-/* register 2 */
-#define CS4398_FM_MASK 0x03
-#define CS4398_FM_SINGLE 0x00
-#define CS4398_FM_DOUBLE 0x01
-#define CS4398_FM_QUAD 0x02
-#define CS4398_FM_DSD 0x03
-#define CS4398_DEM_MASK 0x0c
-#define CS4398_DEM_NONE 0x00
-#define CS4398_DEM_44100 0x04
-#define CS4398_DEM_48000 0x08
-#define CS4398_DEM_32000 0x0c
-#define CS4398_DIF_MASK 0x70
-#define CS4398_DIF_LJUST 0x00
-#define CS4398_DIF_I2S 0x10
-#define CS4398_DIF_RJUST_16 0x20
-#define CS4398_DIF_RJUST_24 0x30
-#define CS4398_DIF_RJUST_20 0x40
-#define CS4398_DIF_RJUST_18 0x50
-#define CS4398_DSD_SRC 0x80
-/* register 3 */
-#define CS4398_ATAPI_MASK 0x1f
-#define CS4398_ATAPI_B_MUTE 0x00
-#define CS4398_ATAPI_B_R 0x01
-#define CS4398_ATAPI_B_L 0x02
-#define CS4398_ATAPI_B_LR 0x03
-#define CS4398_ATAPI_A_MUTE 0x00
-#define CS4398_ATAPI_A_R 0x04
-#define CS4398_ATAPI_A_L 0x08
-#define CS4398_ATAPI_A_LR 0x0c
-#define CS4398_ATAPI_MIX_LR_VOL 0x10
-#define CS4398_INVERT_B 0x20
-#define CS4398_INVERT_A 0x40
-#define CS4398_VOL_B_EQ_A 0x80
-/* register 4 */
-#define CS4398_MUTEP_MASK 0x03
-#define CS4398_MUTEP_AUTO 0x00
-#define CS4398_MUTEP_LOW 0x02
-#define CS4398_MUTEP_HIGH 0x03
-#define CS4398_MUTE_B 0x08
-#define CS4398_MUTE_A 0x10
-#define CS4398_MUTEC_A_EQ_B 0x20
-#define CS4398_DAMUTE 0x40
-#define CS4398_PAMUTE 0x80
-/* register 5 */
-#define CS4398_VOL_A_MASK 0xff
-/* register 6 */
-#define CS4398_VOL_B_MASK 0xff
-/* register 7 */
-#define CS4398_DIR_DSD 0x01
-#define CS4398_FILT_SEL 0x04
-#define CS4398_RMP_DN 0x10
-#define CS4398_RMP_UP 0x20
-#define CS4398_ZERO_CROSS 0x40
-#define CS4398_SOFT_RAMP 0x80
-/* register 8 */
-#define CS4398_MCLKDIV3 0x08
-#define CS4398_MCLKDIV2 0x10
-#define CS4398_FREEZE 0x20
-#define CS4398_CPEN 0x40
-#define CS4398_PDN 0x80
-/* register 9 */
-#define CS4398_DSD_PM_EN 0x01
-#define CS4398_DSD_PM_MODE 0x02
-#define CS4398_INVALID_DSD 0x04
-#define CS4398_STATIC_DSD 0x08
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/oxygen.c b/ANDROID_3.4.5/sound/pci/oxygen/oxygen.c
deleted file mode 100644
index eab663ee..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/oxygen.c
+++ /dev/null
@@ -1,884 +0,0 @@
-/*
- * C-Media CMI8788 driver for C-Media's reference design and similar models
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- *
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this driver; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * CMI8788:
- *
- * SPI 0 -> 1st AK4396 (front)
- * SPI 1 -> 2nd AK4396 (surround)
- * SPI 2 -> 3rd AK4396 (center/LFE)
- * SPI 3 -> WM8785
- * SPI 4 -> 4th AK4396 (back)
- *
- * GPIO 0 -> DFS0 of AK5385
- * GPIO 1 -> DFS1 of AK5385
- *
- * X-Meridian models:
- * GPIO 4 -> enable extension S/PDIF input
- * GPIO 6 -> enable on-board S/PDIF input
- *
- * Claro models:
- * GPIO 6 -> S/PDIF from optical (0) or coaxial (1) input
- * GPIO 8 -> enable headphone amplifier
- *
- * CM9780:
- *
- * LINE_OUT -> input of ADC
- *
- * AUX_IN <- aux
- * CD_IN <- CD
- * MIC_IN <- mic
- *
- * GPO 0 -> route line-in (0) or AC97 output (1) to ADC input
- */
-
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <sound/ac97_codec.h>
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/tlv.h>
-#include "oxygen.h"
-#include "xonar_dg.h"
-#include "ak4396.h"
-#include "wm8785.h"
-
-MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
-MODULE_DESCRIPTION("C-Media CMI8788 driver");
-MODULE_LICENSE("GPL v2");
-MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8786}"
- ",{C-Media,CMI8787}"
- ",{C-Media,CMI8788}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "card index");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "enable card");
-
-enum {
- MODEL_CMEDIA_REF,
- MODEL_MERIDIAN,
- MODEL_MERIDIAN_2G,
- MODEL_CLARO,
- MODEL_CLARO_HALO,
- MODEL_FANTASIA,
- MODEL_SERENADE,
- MODEL_2CH_OUTPUT,
- MODEL_HG2PCI,
- MODEL_XONAR_DG,
-};
-
-static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = {
- /* C-Media's reference design */
- { OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF },
- { OXYGEN_PCI_SUBID(0x10b0, 0x0217), .driver_data = MODEL_CMEDIA_REF },
- { OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF },
- { OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF },
- { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF },
- { OXYGEN_PCI_SUBID(0x13f6, 0x0010), .driver_data = MODEL_CMEDIA_REF },
- { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF },
- { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF },
- { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF },
- /* Asus Xonar DG */
- { OXYGEN_PCI_SUBID(0x1043, 0x8467), .driver_data = MODEL_XONAR_DG },
- /* PCI 2.0 HD Audio */
- { OXYGEN_PCI_SUBID(0x13f6, 0x8782), .driver_data = MODEL_2CH_OUTPUT },
- /* Kuroutoshikou CMI8787-HG2PCI */
- { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_HG2PCI },
- /* TempoTec HiFier Fantasia */
- { OXYGEN_PCI_SUBID(0x14c3, 0x1710), .driver_data = MODEL_FANTASIA },
- /* TempoTec HiFier Serenade */
- { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_SERENADE },
- /* AuzenTech X-Meridian */
- { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN },
- /* AuzenTech X-Meridian 2G */
- { OXYGEN_PCI_SUBID(0x5431, 0x017a), .driver_data = MODEL_MERIDIAN_2G },
- /* HT-Omega Claro */
- { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO },
- /* HT-Omega Claro halo */
- { OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_CLARO_HALO },
- { }
-};
-MODULE_DEVICE_TABLE(pci, oxygen_ids);
-
-
-#define GPIO_AK5385_DFS_MASK 0x0003
-#define GPIO_AK5385_DFS_NORMAL 0x0000
-#define GPIO_AK5385_DFS_DOUBLE 0x0001
-#define GPIO_AK5385_DFS_QUAD 0x0002
-
-#define GPIO_MERIDIAN_DIG_MASK 0x0050
-#define GPIO_MERIDIAN_DIG_EXT 0x0010
-#define GPIO_MERIDIAN_DIG_BOARD 0x0040
-
-#define GPIO_CLARO_DIG_COAX 0x0040
-#define GPIO_CLARO_HP 0x0100
-
-struct generic_data {
- unsigned int dacs;
- u8 ak4396_regs[4][5];
- u16 wm8785_regs[3];
-};
-
-static void ak4396_write(struct oxygen *chip, unsigned int codec,
- u8 reg, u8 value)
-{
- /* maps ALSA channel pair number to SPI output */
- static const u8 codec_spi_map[4] = {
- 0, 1, 2, 4
- };
- struct generic_data *data = chip->model_data;
-
- oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
- OXYGEN_SPI_DATA_LENGTH_2 |
- OXYGEN_SPI_CLOCK_160 |
- (codec_spi_map[codec] << OXYGEN_SPI_CODEC_SHIFT) |
- OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
- AK4396_WRITE | (reg << 8) | value);
- data->ak4396_regs[codec][reg] = value;
-}
-
-static void ak4396_write_cached(struct oxygen *chip, unsigned int codec,
- u8 reg, u8 value)
-{
- struct generic_data *data = chip->model_data;
-
- if (value != data->ak4396_regs[codec][reg])
- ak4396_write(chip, codec, reg, value);
-}
-
-static void wm8785_write(struct oxygen *chip, u8 reg, unsigned int value)
-{
- struct generic_data *data = chip->model_data;
-
- oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
- OXYGEN_SPI_DATA_LENGTH_2 |
- OXYGEN_SPI_CLOCK_160 |
- (3 << OXYGEN_SPI_CODEC_SHIFT) |
- OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
- (reg << 9) | value);
- if (reg < ARRAY_SIZE(data->wm8785_regs))
- data->wm8785_regs[reg] = value;
-}
-
-static void ak4396_registers_init(struct oxygen *chip)
-{
- struct generic_data *data = chip->model_data;
- unsigned int i;
-
- for (i = 0; i < data->dacs; ++i) {
- ak4396_write(chip, i, AK4396_CONTROL_1,
- AK4396_DIF_24_MSB | AK4396_RSTN);
- ak4396_write(chip, i, AK4396_CONTROL_2,
- data->ak4396_regs[0][AK4396_CONTROL_2]);
- ak4396_write(chip, i, AK4396_CONTROL_3,
- AK4396_PCM);
- ak4396_write(chip, i, AK4396_LCH_ATT,
- chip->dac_volume[i * 2]);
- ak4396_write(chip, i, AK4396_RCH_ATT,
- chip->dac_volume[i * 2 + 1]);
- }
-}
-
-static void ak4396_init(struct oxygen *chip)
-{
- struct generic_data *data = chip->model_data;
-
- data->dacs = chip->model.dac_channels_pcm / 2;
- data->ak4396_regs[0][AK4396_CONTROL_2] =
- AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
- ak4396_registers_init(chip);
- snd_component_add(chip->card, "AK4396");
-}
-
-static void ak5385_init(struct oxygen *chip)
-{
- oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_AK5385_DFS_MASK);
- oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_AK5385_DFS_MASK);
- snd_component_add(chip->card, "AK5385");
-}
-
-static void wm8785_registers_init(struct oxygen *chip)
-{
- struct generic_data *data = chip->model_data;
-
- wm8785_write(chip, WM8785_R7, 0);
- wm8785_write(chip, WM8785_R0, data->wm8785_regs[0]);
- wm8785_write(chip, WM8785_R2, data->wm8785_regs[2]);
-}
-
-static void wm8785_init(struct oxygen *chip)
-{
- struct generic_data *data = chip->model_data;
-
- data->wm8785_regs[0] =
- WM8785_MCR_SLAVE | WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST;
- data->wm8785_regs[2] = WM8785_HPFR | WM8785_HPFL;
- wm8785_registers_init(chip);
- snd_component_add(chip->card, "WM8785");
-}
-
-static void generic_init(struct oxygen *chip)
-{
- ak4396_init(chip);
- wm8785_init(chip);
-}
-
-static void meridian_init(struct oxygen *chip)
-{
- oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
- GPIO_MERIDIAN_DIG_MASK);
- oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
- GPIO_MERIDIAN_DIG_BOARD, GPIO_MERIDIAN_DIG_MASK);
- ak4396_init(chip);
- ak5385_init(chip);
-}
-
-static void claro_enable_hp(struct oxygen *chip)
-{
- msleep(300);
- oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CLARO_HP);
- oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_HP);
-}
-
-static void claro_init(struct oxygen *chip)
-{
- oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CLARO_DIG_COAX);
- oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_DIG_COAX);
- ak4396_init(chip);
- wm8785_init(chip);
- claro_enable_hp(chip);
-}
-
-static void claro_halo_init(struct oxygen *chip)
-{
- oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CLARO_DIG_COAX);
- oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_DIG_COAX);
- ak4396_init(chip);
- ak5385_init(chip);
- claro_enable_hp(chip);
-}
-
-static void fantasia_init(struct oxygen *chip)
-{
- ak4396_init(chip);
- snd_component_add(chip->card, "CS5340");
-}
-
-static void stereo_output_init(struct oxygen *chip)
-{
- ak4396_init(chip);
-}
-
-static void generic_cleanup(struct oxygen *chip)
-{
-}
-
-static void claro_disable_hp(struct oxygen *chip)
-{
- oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_HP);
-}
-
-static void claro_cleanup(struct oxygen *chip)
-{
- claro_disable_hp(chip);
-}
-
-static void claro_suspend(struct oxygen *chip)
-{
- claro_disable_hp(chip);
-}
-
-static void generic_resume(struct oxygen *chip)
-{
- ak4396_registers_init(chip);
- wm8785_registers_init(chip);
-}
-
-static void meridian_resume(struct oxygen *chip)
-{
- ak4396_registers_init(chip);
-}
-
-static void claro_resume(struct oxygen *chip)
-{
- ak4396_registers_init(chip);
- claro_enable_hp(chip);
-}
-
-static void stereo_resume(struct oxygen *chip)
-{
- ak4396_registers_init(chip);
-}
-
-static void set_ak4396_params(struct oxygen *chip,
- struct snd_pcm_hw_params *params)
-{
- struct generic_data *data = chip->model_data;
- unsigned int i;
- u8 value;
-
- value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_DFS_MASK;
- if (params_rate(params) <= 54000)
- value |= AK4396_DFS_NORMAL;
- else if (params_rate(params) <= 108000)
- value |= AK4396_DFS_DOUBLE;
- else
- value |= AK4396_DFS_QUAD;
-
- msleep(1); /* wait for the new MCLK to become stable */
-
- if (value != data->ak4396_regs[0][AK4396_CONTROL_2]) {
- for (i = 0; i < data->dacs; ++i) {
- ak4396_write(chip, i, AK4396_CONTROL_1,
- AK4396_DIF_24_MSB);
- ak4396_write(chip, i, AK4396_CONTROL_2, value);
- ak4396_write(chip, i, AK4396_CONTROL_1,
- AK4396_DIF_24_MSB | AK4396_RSTN);
- }
- }
-}
-
-static void update_ak4396_volume(struct oxygen *chip)
-{
- struct generic_data *data = chip->model_data;
- unsigned int i;
-
- for (i = 0; i < data->dacs; ++i) {
- ak4396_write_cached(chip, i, AK4396_LCH_ATT,
- chip->dac_volume[i * 2]);
- ak4396_write_cached(chip, i, AK4396_RCH_ATT,
- chip->dac_volume[i * 2 + 1]);
- }
-}
-
-static void update_ak4396_mute(struct oxygen *chip)
-{
- struct generic_data *data = chip->model_data;
- unsigned int i;
- u8 value;
-
- value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_SMUTE;
- if (chip->dac_mute)
- value |= AK4396_SMUTE;
- for (i = 0; i < data->dacs; ++i)
- ak4396_write_cached(chip, i, AK4396_CONTROL_2, value);
-}
-
-static void set_wm8785_params(struct oxygen *chip,
- struct snd_pcm_hw_params *params)
-{
- struct generic_data *data = chip->model_data;
- unsigned int value;
-
- value = WM8785_MCR_SLAVE | WM8785_FORMAT_LJUST;
- if (params_rate(params) <= 48000)
- value |= WM8785_OSR_SINGLE;
- else if (params_rate(params) <= 96000)
- value |= WM8785_OSR_DOUBLE;
- else
- value |= WM8785_OSR_QUAD;
- if (value != data->wm8785_regs[0]) {
- wm8785_write(chip, WM8785_R7, 0);
- wm8785_write(chip, WM8785_R0, value);
- wm8785_write(chip, WM8785_R2, data->wm8785_regs[2]);
- }
-}
-
-static void set_ak5385_params(struct oxygen *chip,
- struct snd_pcm_hw_params *params)
-{
- unsigned int value;
-
- if (params_rate(params) <= 54000)
- value = GPIO_AK5385_DFS_NORMAL;
- else if (params_rate(params) <= 108000)
- value = GPIO_AK5385_DFS_DOUBLE;
- else
- value = GPIO_AK5385_DFS_QUAD;
- oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
- value, GPIO_AK5385_DFS_MASK);
-}
-
-static void set_no_params(struct oxygen *chip, struct snd_pcm_hw_params *params)
-{
-}
-
-static int rolloff_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- static const char *const names[2] = {
- "Sharp Roll-off", "Slow Roll-off"
- };
-
- return snd_ctl_enum_info(info, 1, 2, names);
-}
-
-static int rolloff_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct generic_data *data = chip->model_data;
-
- value->value.enumerated.item[0] =
- (data->ak4396_regs[0][AK4396_CONTROL_2] & AK4396_SLOW) != 0;
- return 0;
-}
-
-static int rolloff_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct generic_data *data = chip->model_data;
- unsigned int i;
- int changed;
- u8 reg;
-
- mutex_lock(&chip->mutex);
- reg = data->ak4396_regs[0][AK4396_CONTROL_2];
- if (value->value.enumerated.item[0])
- reg |= AK4396_SLOW;
- else
- reg &= ~AK4396_SLOW;
- changed = reg != data->ak4396_regs[0][AK4396_CONTROL_2];
- if (changed) {
- for (i = 0; i < data->dacs; ++i)
- ak4396_write(chip, i, AK4396_CONTROL_2, reg);
- }
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static const struct snd_kcontrol_new rolloff_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "DAC Filter Playback Enum",
- .info = rolloff_info,
- .get = rolloff_get,
- .put = rolloff_put,
-};
-
-static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
-{
- static const char *const names[2] = {
- "None", "High-pass Filter"
- };
-
- return snd_ctl_enum_info(info, 1, 2, names);
-}
-
-static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct generic_data *data = chip->model_data;
-
- value->value.enumerated.item[0] =
- (data->wm8785_regs[WM8785_R2] & WM8785_HPFR) != 0;
- return 0;
-}
-
-static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct generic_data *data = chip->model_data;
- unsigned int reg;
- int changed;
-
- mutex_lock(&chip->mutex);
- reg = data->wm8785_regs[WM8785_R2] & ~(WM8785_HPFR | WM8785_HPFL);
- if (value->value.enumerated.item[0])
- reg |= WM8785_HPFR | WM8785_HPFL;
- changed = reg != data->wm8785_regs[WM8785_R2];
- if (changed)
- wm8785_write(chip, WM8785_R2, reg);
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static const struct snd_kcontrol_new hpf_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "ADC Filter Capture Enum",
- .info = hpf_info,
- .get = hpf_get,
- .put = hpf_put,
-};
-
-static int meridian_dig_source_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- static const char *const names[2] = { "On-board", "Extension" };
-
- return snd_ctl_enum_info(info, 1, 2, names);
-}
-
-static int claro_dig_source_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- static const char *const names[2] = { "Optical", "Coaxial" };
-
- return snd_ctl_enum_info(info, 1, 2, names);
-}
-
-static int meridian_dig_source_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
-
- value->value.enumerated.item[0] =
- !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) &
- GPIO_MERIDIAN_DIG_EXT);
- return 0;
-}
-
-static int claro_dig_source_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
-
- value->value.enumerated.item[0] =
- !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) &
- GPIO_CLARO_DIG_COAX);
- return 0;
-}
-
-static int meridian_dig_source_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- u16 old_reg, new_reg;
- int changed;
-
- mutex_lock(&chip->mutex);
- old_reg = oxygen_read16(chip, OXYGEN_GPIO_DATA);
- new_reg = old_reg & ~GPIO_MERIDIAN_DIG_MASK;
- if (value->value.enumerated.item[0] == 0)
- new_reg |= GPIO_MERIDIAN_DIG_BOARD;
- else
- new_reg |= GPIO_MERIDIAN_DIG_EXT;
- changed = new_reg != old_reg;
- if (changed)
- oxygen_write16(chip, OXYGEN_GPIO_DATA, new_reg);
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static int claro_dig_source_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- u16 old_reg, new_reg;
- int changed;
-
- mutex_lock(&chip->mutex);
- old_reg = oxygen_read16(chip, OXYGEN_GPIO_DATA);
- new_reg = old_reg & ~GPIO_CLARO_DIG_COAX;
- if (value->value.enumerated.item[0])
- new_reg |= GPIO_CLARO_DIG_COAX;
- changed = new_reg != old_reg;
- if (changed)
- oxygen_write16(chip, OXYGEN_GPIO_DATA, new_reg);
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static const struct snd_kcontrol_new meridian_dig_source_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "IEC958 Source Capture Enum",
- .info = meridian_dig_source_info,
- .get = meridian_dig_source_get,
- .put = meridian_dig_source_put,
-};
-
-static const struct snd_kcontrol_new claro_dig_source_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "IEC958 Source Capture Enum",
- .info = claro_dig_source_info,
- .get = claro_dig_source_get,
- .put = claro_dig_source_put,
-};
-
-static int generic_mixer_init(struct oxygen *chip)
-{
- return snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip));
-}
-
-static int generic_wm8785_mixer_init(struct oxygen *chip)
-{
- int err;
-
- err = generic_mixer_init(chip);
- if (err < 0)
- return err;
- err = snd_ctl_add(chip->card, snd_ctl_new1(&hpf_control, chip));
- if (err < 0)
- return err;
- return 0;
-}
-
-static int meridian_mixer_init(struct oxygen *chip)
-{
- int err;
-
- err = generic_mixer_init(chip);
- if (err < 0)
- return err;
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&meridian_dig_source_control, chip));
- if (err < 0)
- return err;
- return 0;
-}
-
-static int claro_mixer_init(struct oxygen *chip)
-{
- int err;
-
- err = generic_wm8785_mixer_init(chip);
- if (err < 0)
- return err;
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&claro_dig_source_control, chip));
- if (err < 0)
- return err;
- return 0;
-}
-
-static int claro_halo_mixer_init(struct oxygen *chip)
-{
- int err;
-
- err = generic_mixer_init(chip);
- if (err < 0)
- return err;
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&claro_dig_source_control, chip));
- if (err < 0)
- return err;
- return 0;
-}
-
-static void dump_ak4396_registers(struct oxygen *chip,
- struct snd_info_buffer *buffer)
-{
- struct generic_data *data = chip->model_data;
- unsigned int dac, i;
-
- for (dac = 0; dac < data->dacs; ++dac) {
- snd_iprintf(buffer, "\nAK4396 %u:", dac + 1);
- for (i = 0; i < 5; ++i)
- snd_iprintf(buffer, " %02x", data->ak4396_regs[dac][i]);
- }
- snd_iprintf(buffer, "\n");
-}
-
-static void dump_wm8785_registers(struct oxygen *chip,
- struct snd_info_buffer *buffer)
-{
- struct generic_data *data = chip->model_data;
- unsigned int i;
-
- snd_iprintf(buffer, "\nWM8785:");
- for (i = 0; i < 3; ++i)
- snd_iprintf(buffer, " %03x", data->wm8785_regs[i]);
- snd_iprintf(buffer, "\n");
-}
-
-static void dump_oxygen_registers(struct oxygen *chip,
- struct snd_info_buffer *buffer)
-{
- dump_ak4396_registers(chip, buffer);
- dump_wm8785_registers(chip, buffer);
-}
-
-static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
-
-static const struct oxygen_model model_generic = {
- .shortname = "C-Media CMI8788",
- .longname = "C-Media Oxygen HD Audio",
- .chip = "CMI8788",
- .init = generic_init,
- .mixer_init = generic_wm8785_mixer_init,
- .cleanup = generic_cleanup,
- .resume = generic_resume,
- .set_dac_params = set_ak4396_params,
- .set_adc_params = set_wm8785_params,
- .update_dac_volume = update_ak4396_volume,
- .update_dac_mute = update_ak4396_mute,
- .dump_registers = dump_oxygen_registers,
- .dac_tlv = ak4396_db_scale,
- .model_data_size = sizeof(struct generic_data),
- .device_config = PLAYBACK_0_TO_I2S |
- PLAYBACK_1_TO_SPDIF |
- PLAYBACK_2_TO_AC97_1 |
- CAPTURE_0_FROM_I2S_1 |
- CAPTURE_1_FROM_SPDIF |
- CAPTURE_2_FROM_AC97_1 |
- AC97_CD_INPUT,
- .dac_channels_pcm = 8,
- .dac_channels_mixer = 8,
- .dac_volume_min = 0,
- .dac_volume_max = 255,
- .function_flags = OXYGEN_FUNCTION_SPI |
- OXYGEN_FUNCTION_ENABLE_SPI_4_5,
- .dac_mclks = OXYGEN_MCLKS(256, 128, 128),
- .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
- .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
- .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
-};
-
-static int __devinit get_oxygen_model(struct oxygen *chip,
- const struct pci_device_id *id)
-{
- static const char *const names[] = {
- [MODEL_MERIDIAN] = "AuzenTech X-Meridian",
- [MODEL_MERIDIAN_2G] = "AuzenTech X-Meridian 2G",
- [MODEL_CLARO] = "HT-Omega Claro",
- [MODEL_CLARO_HALO] = "HT-Omega Claro halo",
- [MODEL_FANTASIA] = "TempoTec HiFier Fantasia",
- [MODEL_SERENADE] = "TempoTec HiFier Serenade",
- [MODEL_HG2PCI] = "CMI8787-HG2PCI",
- };
-
- chip->model = model_generic;
- switch (id->driver_data) {
- case MODEL_MERIDIAN:
- case MODEL_MERIDIAN_2G:
- chip->model.init = meridian_init;
- chip->model.mixer_init = meridian_mixer_init;
- chip->model.resume = meridian_resume;
- chip->model.set_adc_params = set_ak5385_params;
- chip->model.dump_registers = dump_ak4396_registers;
- chip->model.device_config = PLAYBACK_0_TO_I2S |
- PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_2 |
- CAPTURE_1_FROM_SPDIF;
- if (id->driver_data == MODEL_MERIDIAN)
- chip->model.device_config |= AC97_CD_INPUT;
- break;
- case MODEL_CLARO:
- chip->model.init = claro_init;
- chip->model.mixer_init = claro_mixer_init;
- chip->model.cleanup = claro_cleanup;
- chip->model.suspend = claro_suspend;
- chip->model.resume = claro_resume;
- break;
- case MODEL_CLARO_HALO:
- chip->model.init = claro_halo_init;
- chip->model.mixer_init = claro_halo_mixer_init;
- chip->model.cleanup = claro_cleanup;
- chip->model.suspend = claro_suspend;
- chip->model.resume = claro_resume;
- chip->model.set_adc_params = set_ak5385_params;
- chip->model.dump_registers = dump_ak4396_registers;
- chip->model.device_config = PLAYBACK_0_TO_I2S |
- PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_2 |
- CAPTURE_1_FROM_SPDIF;
- break;
- case MODEL_FANTASIA:
- case MODEL_SERENADE:
- case MODEL_2CH_OUTPUT:
- case MODEL_HG2PCI:
- chip->model.shortname = "C-Media CMI8787";
- chip->model.chip = "CMI8787";
- if (id->driver_data == MODEL_FANTASIA)
- chip->model.init = fantasia_init;
- else
- chip->model.init = stereo_output_init;
- chip->model.resume = stereo_resume;
- chip->model.mixer_init = generic_mixer_init;
- chip->model.set_adc_params = set_no_params;
- chip->model.dump_registers = dump_ak4396_registers;
- chip->model.device_config = PLAYBACK_0_TO_I2S |
- PLAYBACK_1_TO_SPDIF;
- if (id->driver_data == MODEL_FANTASIA) {
- chip->model.device_config |= CAPTURE_0_FROM_I2S_1;
- chip->model.adc_mclks = OXYGEN_MCLKS(256, 128, 128);
- }
- chip->model.dac_channels_pcm = 2;
- chip->model.dac_channels_mixer = 2;
- break;
- case MODEL_XONAR_DG:
- chip->model = model_xonar_dg;
- break;
- }
- if (id->driver_data == MODEL_MERIDIAN ||
- id->driver_data == MODEL_MERIDIAN_2G ||
- id->driver_data == MODEL_CLARO_HALO) {
- chip->model.misc_flags = OXYGEN_MISC_MIDI;
- chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT;
- }
- if (id->driver_data < ARRAY_SIZE(names) && names[id->driver_data])
- chip->model.shortname = names[id->driver_data];
- return 0;
-}
-
-static int __devinit generic_oxygen_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- ++dev;
- return -ENOENT;
- }
- err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE,
- oxygen_ids, get_oxygen_model);
- if (err >= 0)
- ++dev;
- return err;
-}
-
-static struct pci_driver oxygen_driver = {
- .name = KBUILD_MODNAME,
- .id_table = oxygen_ids,
- .probe = generic_oxygen_probe,
- .remove = __devexit_p(oxygen_pci_remove),
-#ifdef CONFIG_PM
- .suspend = oxygen_pci_suspend,
- .resume = oxygen_pci_resume,
-#endif
-};
-
-static int __init alsa_card_oxygen_init(void)
-{
- return pci_register_driver(&oxygen_driver);
-}
-
-static void __exit alsa_card_oxygen_exit(void)
-{
- pci_unregister_driver(&oxygen_driver);
-}
-
-module_init(alsa_card_oxygen_init)
-module_exit(alsa_card_oxygen_exit)
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/oxygen.h b/ANDROID_3.4.5/sound/pci/oxygen/oxygen.h
deleted file mode 100644
index f53897a7..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/oxygen.h
+++ /dev/null
@@ -1,260 +0,0 @@
-#ifndef OXYGEN_H_INCLUDED
-#define OXYGEN_H_INCLUDED
-
-#include <linux/mutex.h>
-#include <linux/spinlock.h>
-#include <linux/wait.h>
-#include <linux/workqueue.h>
-#include "oxygen_regs.h"
-
-/* 1 << PCM_x == OXYGEN_CHANNEL_x */
-#define PCM_A 0
-#define PCM_B 1
-#define PCM_C 2
-#define PCM_SPDIF 3
-#define PCM_MULTICH 4
-#define PCM_AC97 5
-#define PCM_COUNT 6
-
-#define OXYGEN_MCLKS(f_single, f_double, f_quad) ((MCLK_##f_single << 0) | \
- (MCLK_##f_double << 2) | \
- (MCLK_##f_quad << 4))
-
-#define OXYGEN_IO_SIZE 0x100
-
-#define OXYGEN_EEPROM_ID 0x434d /* "CM" */
-
-/* model-specific configuration of outputs/inputs */
-#define PLAYBACK_0_TO_I2S 0x0001
- /* PLAYBACK_0_TO_AC97_0 not implemented */
-#define PLAYBACK_1_TO_SPDIF 0x0004
-#define PLAYBACK_2_TO_AC97_1 0x0008
-#define CAPTURE_0_FROM_I2S_1 0x0010
-#define CAPTURE_0_FROM_I2S_2 0x0020
- /* CAPTURE_0_FROM_AC97_0 not implemented */
-#define CAPTURE_1_FROM_SPDIF 0x0080
-#define CAPTURE_2_FROM_I2S_2 0x0100
-#define CAPTURE_2_FROM_AC97_1 0x0200
- /* CAPTURE_3_FROM_I2S_3 not implemented */
-#define MIDI_OUTPUT 0x0800
-#define MIDI_INPUT 0x1000
-#define AC97_CD_INPUT 0x2000
-#define AC97_FMIC_SWITCH 0x4000
-
-enum {
- CONTROL_SPDIF_PCM,
- CONTROL_SPDIF_INPUT_BITS,
- CONTROL_MIC_CAPTURE_SWITCH,
- CONTROL_LINE_CAPTURE_SWITCH,
- CONTROL_CD_CAPTURE_SWITCH,
- CONTROL_AUX_CAPTURE_SWITCH,
- CONTROL_COUNT
-};
-
-#define OXYGEN_PCI_SUBID(sv, sd) \
- .vendor = PCI_VENDOR_ID_CMEDIA, \
- .device = 0x8788, \
- .subvendor = sv, \
- .subdevice = sd
-
-#define BROKEN_EEPROM_DRIVER_DATA ((unsigned long)-1)
-#define OXYGEN_PCI_SUBID_BROKEN_EEPROM \
- OXYGEN_PCI_SUBID(PCI_VENDOR_ID_CMEDIA, 0x8788), \
- .driver_data = BROKEN_EEPROM_DRIVER_DATA
-
-struct pci_dev;
-struct pci_device_id;
-struct snd_card;
-struct snd_pcm_substream;
-struct snd_pcm_hardware;
-struct snd_pcm_hw_params;
-struct snd_kcontrol_new;
-struct snd_rawmidi;
-struct snd_info_buffer;
-struct oxygen;
-
-struct oxygen_model {
- const char *shortname;
- const char *longname;
- const char *chip;
- void (*init)(struct oxygen *chip);
- int (*control_filter)(struct snd_kcontrol_new *template);
- int (*mixer_init)(struct oxygen *chip);
- void (*cleanup)(struct oxygen *chip);
- void (*suspend)(struct oxygen *chip);
- void (*resume)(struct oxygen *chip);
- void (*pcm_hardware_filter)(unsigned int channel,
- struct snd_pcm_hardware *hardware);
- void (*set_dac_params)(struct oxygen *chip,
- struct snd_pcm_hw_params *params);
- void (*set_adc_params)(struct oxygen *chip,
- struct snd_pcm_hw_params *params);
- void (*update_dac_volume)(struct oxygen *chip);
- void (*update_dac_mute)(struct oxygen *chip);
- void (*update_center_lfe_mix)(struct oxygen *chip, bool mixed);
- unsigned int (*adjust_dac_routing)(struct oxygen *chip,
- unsigned int play_routing);
- void (*gpio_changed)(struct oxygen *chip);
- void (*uart_input)(struct oxygen *chip);
- void (*ac97_switch)(struct oxygen *chip,
- unsigned int reg, unsigned int mute);
- void (*dump_registers)(struct oxygen *chip,
- struct snd_info_buffer *buffer);
- const unsigned int *dac_tlv;
- size_t model_data_size;
- unsigned int device_config;
- u8 dac_channels_pcm;
- u8 dac_channels_mixer;
- u8 dac_volume_min;
- u8 dac_volume_max;
- u8 misc_flags;
- u8 function_flags;
- u8 dac_mclks;
- u8 adc_mclks;
- u16 dac_i2s_format;
- u16 adc_i2s_format;
-};
-
-struct oxygen {
- unsigned long addr;
- spinlock_t reg_lock;
- struct mutex mutex;
- struct snd_card *card;
- struct pci_dev *pci;
- struct snd_rawmidi *midi;
- int irq;
- void *model_data;
- unsigned int interrupt_mask;
- u8 dac_volume[8];
- u8 dac_mute;
- u8 pcm_active;
- u8 pcm_running;
- u8 dac_routing;
- u8 spdif_playback_enable;
- u8 has_ac97_0;
- u8 has_ac97_1;
- u32 spdif_bits;
- u32 spdif_pcm_bits;
- struct snd_pcm_substream *streams[PCM_COUNT];
- struct snd_kcontrol *controls[CONTROL_COUNT];
- struct work_struct spdif_input_bits_work;
- struct work_struct gpio_work;
- wait_queue_head_t ac97_waitqueue;
- union {
- u8 _8[OXYGEN_IO_SIZE];
- __le16 _16[OXYGEN_IO_SIZE / 2];
- __le32 _32[OXYGEN_IO_SIZE / 4];
- } saved_registers;
- u16 saved_ac97_registers[2][0x40];
- unsigned int uart_input_count;
- u8 uart_input[32];
- struct oxygen_model model;
-};
-
-/* oxygen_lib.c */
-
-int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
- struct module *owner,
- const struct pci_device_id *ids,
- int (*get_model)(struct oxygen *chip,
- const struct pci_device_id *id
- )
- );
-void oxygen_pci_remove(struct pci_dev *pci);
-#ifdef CONFIG_PM
-int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state);
-int oxygen_pci_resume(struct pci_dev *pci);
-#endif
-void oxygen_pci_shutdown(struct pci_dev *pci);
-
-/* oxygen_mixer.c */
-
-int oxygen_mixer_init(struct oxygen *chip);
-void oxygen_update_dac_routing(struct oxygen *chip);
-void oxygen_update_spdif_source(struct oxygen *chip);
-
-/* oxygen_pcm.c */
-
-int oxygen_pcm_init(struct oxygen *chip);
-
-/* oxygen_io.c */
-
-u8 oxygen_read8(struct oxygen *chip, unsigned int reg);
-u16 oxygen_read16(struct oxygen *chip, unsigned int reg);
-u32 oxygen_read32(struct oxygen *chip, unsigned int reg);
-void oxygen_write8(struct oxygen *chip, unsigned int reg, u8 value);
-void oxygen_write16(struct oxygen *chip, unsigned int reg, u16 value);
-void oxygen_write32(struct oxygen *chip, unsigned int reg, u32 value);
-void oxygen_write8_masked(struct oxygen *chip, unsigned int reg,
- u8 value, u8 mask);
-void oxygen_write16_masked(struct oxygen *chip, unsigned int reg,
- u16 value, u16 mask);
-void oxygen_write32_masked(struct oxygen *chip, unsigned int reg,
- u32 value, u32 mask);
-
-u16 oxygen_read_ac97(struct oxygen *chip, unsigned int codec,
- unsigned int index);
-void oxygen_write_ac97(struct oxygen *chip, unsigned int codec,
- unsigned int index, u16 data);
-void oxygen_write_ac97_masked(struct oxygen *chip, unsigned int codec,
- unsigned int index, u16 data, u16 mask);
-
-void oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data);
-void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data);
-
-void oxygen_reset_uart(struct oxygen *chip);
-void oxygen_write_uart(struct oxygen *chip, u8 data);
-
-u16 oxygen_read_eeprom(struct oxygen *chip, unsigned int index);
-void oxygen_write_eeprom(struct oxygen *chip, unsigned int index, u16 value);
-
-static inline void oxygen_set_bits8(struct oxygen *chip,
- unsigned int reg, u8 value)
-{
- oxygen_write8_masked(chip, reg, value, value);
-}
-
-static inline void oxygen_set_bits16(struct oxygen *chip,
- unsigned int reg, u16 value)
-{
- oxygen_write16_masked(chip, reg, value, value);
-}
-
-static inline void oxygen_set_bits32(struct oxygen *chip,
- unsigned int reg, u32 value)
-{
- oxygen_write32_masked(chip, reg, value, value);
-}
-
-static inline void oxygen_clear_bits8(struct oxygen *chip,
- unsigned int reg, u8 value)
-{
- oxygen_write8_masked(chip, reg, 0, value);
-}
-
-static inline void oxygen_clear_bits16(struct oxygen *chip,
- unsigned int reg, u16 value)
-{
- oxygen_write16_masked(chip, reg, 0, value);
-}
-
-static inline void oxygen_clear_bits32(struct oxygen *chip,
- unsigned int reg, u32 value)
-{
- oxygen_write32_masked(chip, reg, 0, value);
-}
-
-static inline void oxygen_ac97_set_bits(struct oxygen *chip, unsigned int codec,
- unsigned int index, u16 value)
-{
- oxygen_write_ac97_masked(chip, codec, index, value, value);
-}
-
-static inline void oxygen_ac97_clear_bits(struct oxygen *chip,
- unsigned int codec,
- unsigned int index, u16 value)
-{
- oxygen_write_ac97_masked(chip, codec, index, 0, value);
-}
-
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/oxygen_io.c b/ANDROID_3.4.5/sound/pci/oxygen/oxygen_io.c
deleted file mode 100644
index 521eae45..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/oxygen_io.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * C-Media CMI8788 driver - helper functions
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- *
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this driver; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/export.h>
-#include <sound/core.h>
-#include <sound/mpu401.h>
-#include <asm/io.h>
-#include "oxygen.h"
-
-u8 oxygen_read8(struct oxygen *chip, unsigned int reg)
-{
- return inb(chip->addr + reg);
-}
-EXPORT_SYMBOL(oxygen_read8);
-
-u16 oxygen_read16(struct oxygen *chip, unsigned int reg)
-{
- return inw(chip->addr + reg);
-}
-EXPORT_SYMBOL(oxygen_read16);
-
-u32 oxygen_read32(struct oxygen *chip, unsigned int reg)
-{
- return inl(chip->addr + reg);
-}
-EXPORT_SYMBOL(oxygen_read32);
-
-void oxygen_write8(struct oxygen *chip, unsigned int reg, u8 value)
-{
- outb(value, chip->addr + reg);
- chip->saved_registers._8[reg] = value;
-}
-EXPORT_SYMBOL(oxygen_write8);
-
-void oxygen_write16(struct oxygen *chip, unsigned int reg, u16 value)
-{
- outw(value, chip->addr + reg);
- chip->saved_registers._16[reg / 2] = cpu_to_le16(value);
-}
-EXPORT_SYMBOL(oxygen_write16);
-
-void oxygen_write32(struct oxygen *chip, unsigned int reg, u32 value)
-{
- outl(value, chip->addr + reg);
- chip->saved_registers._32[reg / 4] = cpu_to_le32(value);
-}
-EXPORT_SYMBOL(oxygen_write32);
-
-void oxygen_write8_masked(struct oxygen *chip, unsigned int reg,
- u8 value, u8 mask)
-{
- u8 tmp = inb(chip->addr + reg);
- tmp &= ~mask;
- tmp |= value & mask;
- outb(tmp, chip->addr + reg);
- chip->saved_registers._8[reg] = tmp;
-}
-EXPORT_SYMBOL(oxygen_write8_masked);
-
-void oxygen_write16_masked(struct oxygen *chip, unsigned int reg,
- u16 value, u16 mask)
-{
- u16 tmp = inw(chip->addr + reg);
- tmp &= ~mask;
- tmp |= value & mask;
- outw(tmp, chip->addr + reg);
- chip->saved_registers._16[reg / 2] = cpu_to_le16(tmp);
-}
-EXPORT_SYMBOL(oxygen_write16_masked);
-
-void oxygen_write32_masked(struct oxygen *chip, unsigned int reg,
- u32 value, u32 mask)
-{
- u32 tmp = inl(chip->addr + reg);
- tmp &= ~mask;
- tmp |= value & mask;
- outl(tmp, chip->addr + reg);
- chip->saved_registers._32[reg / 4] = cpu_to_le32(tmp);
-}
-EXPORT_SYMBOL(oxygen_write32_masked);
-
-static int oxygen_ac97_wait(struct oxygen *chip, unsigned int mask)
-{
- u8 status = 0;
-
- /*
- * Reading the status register also clears the bits, so we have to save
- * the read bits in status.
- */
- wait_event_timeout(chip->ac97_waitqueue,
- ({ status |= oxygen_read8(chip, OXYGEN_AC97_INTERRUPT_STATUS);
- status & mask; }),
- msecs_to_jiffies(1) + 1);
- /*
- * Check even after a timeout because this function should not require
- * the AC'97 interrupt to be enabled.
- */
- status |= oxygen_read8(chip, OXYGEN_AC97_INTERRUPT_STATUS);
- return status & mask ? 0 : -EIO;
-}
-
-/*
- * About 10% of AC'97 register reads or writes fail to complete, but even those
- * where the controller indicates completion aren't guaranteed to have actually
- * happened.
- *
- * It's hard to assign blame to either the controller or the codec because both
- * were made by C-Media ...
- */
-
-void oxygen_write_ac97(struct oxygen *chip, unsigned int codec,
- unsigned int index, u16 data)
-{
- unsigned int count, succeeded;
- u32 reg;
-
- reg = data;
- reg |= index << OXYGEN_AC97_REG_ADDR_SHIFT;
- reg |= OXYGEN_AC97_REG_DIR_WRITE;
- reg |= codec << OXYGEN_AC97_REG_CODEC_SHIFT;
- succeeded = 0;
- for (count = 5; count > 0; --count) {
- udelay(5);
- oxygen_write32(chip, OXYGEN_AC97_REGS, reg);
- /* require two "completed" writes, just to be sure */
- if (oxygen_ac97_wait(chip, OXYGEN_AC97_INT_WRITE_DONE) >= 0 &&
- ++succeeded >= 2) {
- chip->saved_ac97_registers[codec][index / 2] = data;
- return;
- }
- }
- snd_printk(KERN_ERR "AC'97 write timeout\n");
-}
-EXPORT_SYMBOL(oxygen_write_ac97);
-
-u16 oxygen_read_ac97(struct oxygen *chip, unsigned int codec,
- unsigned int index)
-{
- unsigned int count;
- unsigned int last_read = UINT_MAX;
- u32 reg;
-
- reg = index << OXYGEN_AC97_REG_ADDR_SHIFT;
- reg |= OXYGEN_AC97_REG_DIR_READ;
- reg |= codec << OXYGEN_AC97_REG_CODEC_SHIFT;
- for (count = 5; count > 0; --count) {
- udelay(5);
- oxygen_write32(chip, OXYGEN_AC97_REGS, reg);
- udelay(10);
- if (oxygen_ac97_wait(chip, OXYGEN_AC97_INT_READ_DONE) >= 0) {
- u16 value = oxygen_read16(chip, OXYGEN_AC97_REGS);
- /* we require two consecutive reads of the same value */
- if (value == last_read)
- return value;
- last_read = value;
- /*
- * Invert the register value bits to make sure that two
- * consecutive unsuccessful reads do not return the same
- * value.
- */
- reg ^= 0xffff;
- }
- }
- snd_printk(KERN_ERR "AC'97 read timeout on codec %u\n", codec);
- return 0;
-}
-EXPORT_SYMBOL(oxygen_read_ac97);
-
-void oxygen_write_ac97_masked(struct oxygen *chip, unsigned int codec,
- unsigned int index, u16 data, u16 mask)
-{
- u16 value = oxygen_read_ac97(chip, codec, index);
- value &= ~mask;
- value |= data & mask;
- oxygen_write_ac97(chip, codec, index, value);
-}
-EXPORT_SYMBOL(oxygen_write_ac97_masked);
-
-void oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data)
-{
- unsigned int count;
-
- /* should not need more than 30.72 us (24 * 1.28 us) */
- count = 10;
- while ((oxygen_read8(chip, OXYGEN_SPI_CONTROL) & OXYGEN_SPI_BUSY)
- && count > 0) {
- udelay(4);
- --count;
- }
-
- oxygen_write8(chip, OXYGEN_SPI_DATA1, data);
- oxygen_write8(chip, OXYGEN_SPI_DATA2, data >> 8);
- if (control & OXYGEN_SPI_DATA_LENGTH_3)
- oxygen_write8(chip, OXYGEN_SPI_DATA3, data >> 16);
- oxygen_write8(chip, OXYGEN_SPI_CONTROL, control);
-}
-EXPORT_SYMBOL(oxygen_write_spi);
-
-void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data)
-{
- /* should not need more than about 300 us */
- msleep(1);
-
- oxygen_write8(chip, OXYGEN_2WIRE_MAP, map);
- oxygen_write8(chip, OXYGEN_2WIRE_DATA, data);
- oxygen_write8(chip, OXYGEN_2WIRE_CONTROL,
- device | OXYGEN_2WIRE_DIR_WRITE);
-}
-EXPORT_SYMBOL(oxygen_write_i2c);
-
-static void _write_uart(struct oxygen *chip, unsigned int port, u8 data)
-{
- if (oxygen_read8(chip, OXYGEN_MPU401 + 1) & MPU401_TX_FULL)
- msleep(1);
- oxygen_write8(chip, OXYGEN_MPU401 + port, data);
-}
-
-void oxygen_reset_uart(struct oxygen *chip)
-{
- _write_uart(chip, 1, MPU401_RESET);
- msleep(1); /* wait for ACK */
- _write_uart(chip, 1, MPU401_ENTER_UART);
-}
-EXPORT_SYMBOL(oxygen_reset_uart);
-
-void oxygen_write_uart(struct oxygen *chip, u8 data)
-{
- _write_uart(chip, 0, data);
-}
-EXPORT_SYMBOL(oxygen_write_uart);
-
-u16 oxygen_read_eeprom(struct oxygen *chip, unsigned int index)
-{
- unsigned int timeout;
-
- oxygen_write8(chip, OXYGEN_EEPROM_CONTROL,
- index | OXYGEN_EEPROM_DIR_READ);
- for (timeout = 0; timeout < 100; ++timeout) {
- udelay(1);
- if (!(oxygen_read8(chip, OXYGEN_EEPROM_STATUS)
- & OXYGEN_EEPROM_BUSY))
- break;
- }
- return oxygen_read16(chip, OXYGEN_EEPROM_DATA);
-}
-
-void oxygen_write_eeprom(struct oxygen *chip, unsigned int index, u16 value)
-{
- unsigned int timeout;
-
- oxygen_write16(chip, OXYGEN_EEPROM_DATA, value);
- oxygen_write8(chip, OXYGEN_EEPROM_CONTROL,
- index | OXYGEN_EEPROM_DIR_WRITE);
- for (timeout = 0; timeout < 10; ++timeout) {
- msleep(1);
- if (!(oxygen_read8(chip, OXYGEN_EEPROM_STATUS)
- & OXYGEN_EEPROM_BUSY))
- return;
- }
- snd_printk(KERN_ERR "EEPROM write timeout\n");
-}
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/oxygen_lib.c b/ANDROID_3.4.5/sound/pci/oxygen/oxygen_lib.c
deleted file mode 100644
index 92e2d67f..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/oxygen_lib.c
+++ /dev/null
@@ -1,834 +0,0 @@
-/*
- * C-Media CMI8788 driver - main driver module
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- *
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this driver; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/ac97_codec.h>
-#include <sound/asoundef.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/mpu401.h>
-#include <sound/pcm.h>
-#include "oxygen.h"
-#include "cm9780.h"
-
-MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
-MODULE_DESCRIPTION("C-Media CMI8788 helper library");
-MODULE_LICENSE("GPL v2");
-
-#define DRIVER "oxygen"
-
-static inline int oxygen_uart_input_ready(struct oxygen *chip)
-{
- return !(oxygen_read8(chip, OXYGEN_MPU401 + 1) & MPU401_RX_EMPTY);
-}
-
-static void oxygen_read_uart(struct oxygen *chip)
-{
- if (unlikely(!oxygen_uart_input_ready(chip))) {
- /* no data, but read it anyway to clear the interrupt */
- oxygen_read8(chip, OXYGEN_MPU401);
- return;
- }
- do {
- u8 data = oxygen_read8(chip, OXYGEN_MPU401);
- if (data == MPU401_ACK)
- continue;
- if (chip->uart_input_count >= ARRAY_SIZE(chip->uart_input))
- chip->uart_input_count = 0;
- chip->uart_input[chip->uart_input_count++] = data;
- } while (oxygen_uart_input_ready(chip));
- if (chip->model.uart_input)
- chip->model.uart_input(chip);
-}
-
-static irqreturn_t oxygen_interrupt(int dummy, void *dev_id)
-{
- struct oxygen *chip = dev_id;
- unsigned int status, clear, elapsed_streams, i;
-
- status = oxygen_read16(chip, OXYGEN_INTERRUPT_STATUS);
- if (!status)
- return IRQ_NONE;
-
- spin_lock(&chip->reg_lock);
-
- clear = status & (OXYGEN_CHANNEL_A |
- OXYGEN_CHANNEL_B |
- OXYGEN_CHANNEL_C |
- OXYGEN_CHANNEL_SPDIF |
- OXYGEN_CHANNEL_MULTICH |
- OXYGEN_CHANNEL_AC97 |
- OXYGEN_INT_SPDIF_IN_DETECT |
- OXYGEN_INT_GPIO |
- OXYGEN_INT_AC97);
- if (clear) {
- if (clear & OXYGEN_INT_SPDIF_IN_DETECT)
- chip->interrupt_mask &= ~OXYGEN_INT_SPDIF_IN_DETECT;
- oxygen_write16(chip, OXYGEN_INTERRUPT_MASK,
- chip->interrupt_mask & ~clear);
- oxygen_write16(chip, OXYGEN_INTERRUPT_MASK,
- chip->interrupt_mask);
- }
-
- elapsed_streams = status & chip->pcm_running;
-
- spin_unlock(&chip->reg_lock);
-
- for (i = 0; i < PCM_COUNT; ++i)
- if ((elapsed_streams & (1 << i)) && chip->streams[i])
- snd_pcm_period_elapsed(chip->streams[i]);
-
- if (status & OXYGEN_INT_SPDIF_IN_DETECT) {
- spin_lock(&chip->reg_lock);
- i = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
- if (i & (OXYGEN_SPDIF_SENSE_INT | OXYGEN_SPDIF_LOCK_INT |
- OXYGEN_SPDIF_RATE_INT)) {
- /* write the interrupt bit(s) to clear */
- oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, i);
- schedule_work(&chip->spdif_input_bits_work);
- }
- spin_unlock(&chip->reg_lock);
- }
-
- if (status & OXYGEN_INT_GPIO)
- schedule_work(&chip->gpio_work);
-
- if (status & OXYGEN_INT_MIDI) {
- if (chip->midi)
- snd_mpu401_uart_interrupt(0, chip->midi->private_data);
- else
- oxygen_read_uart(chip);
- }
-
- if (status & OXYGEN_INT_AC97)
- wake_up(&chip->ac97_waitqueue);
-
- return IRQ_HANDLED;
-}
-
-static void oxygen_spdif_input_bits_changed(struct work_struct *work)
-{
- struct oxygen *chip = container_of(work, struct oxygen,
- spdif_input_bits_work);
- u32 reg;
-
- /*
- * This function gets called when there is new activity on the SPDIF
- * input, or when we lose lock on the input signal, or when the rate
- * changes.
- */
- msleep(1);
- spin_lock_irq(&chip->reg_lock);
- reg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
- if ((reg & (OXYGEN_SPDIF_SENSE_STATUS |
- OXYGEN_SPDIF_LOCK_STATUS))
- == OXYGEN_SPDIF_SENSE_STATUS) {
- /*
- * If we detect activity on the SPDIF input but cannot lock to
- * a signal, the clock bit is likely to be wrong.
- */
- reg ^= OXYGEN_SPDIF_IN_CLOCK_MASK;
- oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, reg);
- spin_unlock_irq(&chip->reg_lock);
- msleep(1);
- spin_lock_irq(&chip->reg_lock);
- reg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
- if ((reg & (OXYGEN_SPDIF_SENSE_STATUS |
- OXYGEN_SPDIF_LOCK_STATUS))
- == OXYGEN_SPDIF_SENSE_STATUS) {
- /* nothing detected with either clock; give up */
- if ((reg & OXYGEN_SPDIF_IN_CLOCK_MASK)
- == OXYGEN_SPDIF_IN_CLOCK_192) {
- /*
- * Reset clock to <= 96 kHz because this is
- * more likely to be received next time.
- */
- reg &= ~OXYGEN_SPDIF_IN_CLOCK_MASK;
- reg |= OXYGEN_SPDIF_IN_CLOCK_96;
- oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, reg);
- }
- }
- }
- spin_unlock_irq(&chip->reg_lock);
-
- if (chip->controls[CONTROL_SPDIF_INPUT_BITS]) {
- spin_lock_irq(&chip->reg_lock);
- chip->interrupt_mask |= OXYGEN_INT_SPDIF_IN_DETECT;
- oxygen_write16(chip, OXYGEN_INTERRUPT_MASK,
- chip->interrupt_mask);
- spin_unlock_irq(&chip->reg_lock);
-
- /*
- * We don't actually know that any channel status bits have
- * changed, but let's send a notification just to be sure.
- */
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->controls[CONTROL_SPDIF_INPUT_BITS]->id);
- }
-}
-
-static void oxygen_gpio_changed(struct work_struct *work)
-{
- struct oxygen *chip = container_of(work, struct oxygen, gpio_work);
-
- if (chip->model.gpio_changed)
- chip->model.gpio_changed(chip);
-}
-
-#ifdef CONFIG_PROC_FS
-static void oxygen_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct oxygen *chip = entry->private_data;
- int i, j;
-
- switch (oxygen_read8(chip, OXYGEN_REVISION) & OXYGEN_PACKAGE_ID_MASK) {
- case OXYGEN_PACKAGE_ID_8786: i = '6'; break;
- case OXYGEN_PACKAGE_ID_8787: i = '7'; break;
- case OXYGEN_PACKAGE_ID_8788: i = '8'; break;
- default: i = '?'; break;
- }
- snd_iprintf(buffer, "CMI878%c:\n", i);
- for (i = 0; i < OXYGEN_IO_SIZE; i += 0x10) {
- snd_iprintf(buffer, "%02x:", i);
- for (j = 0; j < 0x10; ++j)
- snd_iprintf(buffer, " %02x", oxygen_read8(chip, i + j));
- snd_iprintf(buffer, "\n");
- }
- if (mutex_lock_interruptible(&chip->mutex) < 0)
- return;
- if (chip->has_ac97_0) {
- snd_iprintf(buffer, "\nAC97:\n");
- for (i = 0; i < 0x80; i += 0x10) {
- snd_iprintf(buffer, "%02x:", i);
- for (j = 0; j < 0x10; j += 2)
- snd_iprintf(buffer, " %04x",
- oxygen_read_ac97(chip, 0, i + j));
- snd_iprintf(buffer, "\n");
- }
- }
- if (chip->has_ac97_1) {
- snd_iprintf(buffer, "\nAC97 2:\n");
- for (i = 0; i < 0x80; i += 0x10) {
- snd_iprintf(buffer, "%02x:", i);
- for (j = 0; j < 0x10; j += 2)
- snd_iprintf(buffer, " %04x",
- oxygen_read_ac97(chip, 1, i + j));
- snd_iprintf(buffer, "\n");
- }
- }
- mutex_unlock(&chip->mutex);
- if (chip->model.dump_registers)
- chip->model.dump_registers(chip, buffer);
-}
-
-static void oxygen_proc_init(struct oxygen *chip)
-{
- struct snd_info_entry *entry;
-
- if (!snd_card_proc_new(chip->card, "oxygen", &entry))
- snd_info_set_text_ops(entry, chip, oxygen_proc_read);
-}
-#else
-#define oxygen_proc_init(chip)
-#endif
-
-static const struct pci_device_id *
-oxygen_search_pci_id(struct oxygen *chip, const struct pci_device_id ids[])
-{
- u16 subdevice;
-
- /*
- * Make sure the EEPROM pins are available, i.e., not used for SPI.
- * (This function is called before we initialize or use SPI.)
- */
- oxygen_clear_bits8(chip, OXYGEN_FUNCTION,
- OXYGEN_FUNCTION_ENABLE_SPI_4_5);
- /*
- * Read the subsystem device ID directly from the EEPROM, because the
- * chip didn't if the first EEPROM word was overwritten.
- */
- subdevice = oxygen_read_eeprom(chip, 2);
- /* use default ID if EEPROM is missing */
- if (subdevice == 0xffff && oxygen_read_eeprom(chip, 1) == 0xffff)
- subdevice = 0x8788;
- /*
- * We use only the subsystem device ID for searching because it is
- * unique even without the subsystem vendor ID, which may have been
- * overwritten in the EEPROM.
- */
- for (; ids->vendor; ++ids)
- if (ids->subdevice == subdevice &&
- ids->driver_data != BROKEN_EEPROM_DRIVER_DATA)
- return ids;
- return NULL;
-}
-
-static void oxygen_restore_eeprom(struct oxygen *chip,
- const struct pci_device_id *id)
-{
- u16 eeprom_id;
-
- eeprom_id = oxygen_read_eeprom(chip, 0);
- if (eeprom_id != OXYGEN_EEPROM_ID &&
- (eeprom_id != 0xffff || id->subdevice != 0x8788)) {
- /*
- * This function gets called only when a known card model has
- * been detected, i.e., we know there is a valid subsystem
- * product ID at index 2 in the EEPROM. Therefore, we have
- * been able to deduce the correct subsystem vendor ID, and
- * this is enough information to restore the original EEPROM
- * contents.
- */
- oxygen_write_eeprom(chip, 1, id->subvendor);
- oxygen_write_eeprom(chip, 0, OXYGEN_EEPROM_ID);
-
- oxygen_set_bits8(chip, OXYGEN_MISC,
- OXYGEN_MISC_WRITE_PCI_SUBID);
- pci_write_config_word(chip->pci, PCI_SUBSYSTEM_VENDOR_ID,
- id->subvendor);
- pci_write_config_word(chip->pci, PCI_SUBSYSTEM_ID,
- id->subdevice);
- oxygen_clear_bits8(chip, OXYGEN_MISC,
- OXYGEN_MISC_WRITE_PCI_SUBID);
-
- snd_printk(KERN_INFO "EEPROM ID restored\n");
- }
-}
-
-static void configure_pcie_bridge(struct pci_dev *pci)
-{
- enum { PEX811X, PI7C9X110 };
- static const struct pci_device_id bridge_ids[] = {
- { PCI_VDEVICE(PLX, 0x8111), .driver_data = PEX811X },
- { PCI_VDEVICE(PLX, 0x8112), .driver_data = PEX811X },
- { PCI_DEVICE(0x12d8, 0xe110), .driver_data = PI7C9X110 },
- { }
- };
- struct pci_dev *bridge;
- const struct pci_device_id *id;
- u32 tmp;
-
- if (!pci->bus || !pci->bus->self)
- return;
- bridge = pci->bus->self;
-
- id = pci_match_id(bridge_ids, bridge);
- if (!id)
- return;
-
- switch (id->driver_data) {
- case PEX811X: /* PLX PEX8111/PEX8112 PCIe/PCI bridge */
- pci_read_config_dword(bridge, 0x48, &tmp);
- tmp |= 1; /* enable blind prefetching */
- tmp |= 1 << 11; /* enable beacon generation */
- pci_write_config_dword(bridge, 0x48, tmp);
-
- pci_write_config_dword(bridge, 0x84, 0x0c);
- pci_read_config_dword(bridge, 0x88, &tmp);
- tmp &= ~(7 << 27);
- tmp |= 2 << 27; /* set prefetch size to 128 bytes */
- pci_write_config_dword(bridge, 0x88, tmp);
- break;
-
- case PI7C9X110: /* Pericom PI7C9X110 PCIe/PCI bridge */
- pci_read_config_dword(bridge, 0x40, &tmp);
- tmp |= 1; /* park the PCI arbiter to the sound chip */
- pci_write_config_dword(bridge, 0x40, tmp);
- break;
- }
-}
-
-static void oxygen_init(struct oxygen *chip)
-{
- unsigned int i;
-
- chip->dac_routing = 1;
- for (i = 0; i < 8; ++i)
- chip->dac_volume[i] = chip->model.dac_volume_min;
- chip->dac_mute = 1;
- chip->spdif_playback_enable = 1;
- chip->spdif_bits = OXYGEN_SPDIF_C | OXYGEN_SPDIF_ORIGINAL |
- (IEC958_AES1_CON_PCM_CODER << OXYGEN_SPDIF_CATEGORY_SHIFT);
- chip->spdif_pcm_bits = chip->spdif_bits;
-
- if (!(oxygen_read8(chip, OXYGEN_REVISION) & OXYGEN_REVISION_2))
- oxygen_set_bits8(chip, OXYGEN_MISC,
- OXYGEN_MISC_PCI_MEM_W_1_CLOCK);
-
- i = oxygen_read16(chip, OXYGEN_AC97_CONTROL);
- chip->has_ac97_0 = (i & OXYGEN_AC97_CODEC_0) != 0;
- chip->has_ac97_1 = (i & OXYGEN_AC97_CODEC_1) != 0;
-
- oxygen_write8_masked(chip, OXYGEN_FUNCTION,
- OXYGEN_FUNCTION_RESET_CODEC |
- chip->model.function_flags,
- OXYGEN_FUNCTION_RESET_CODEC |
- OXYGEN_FUNCTION_2WIRE_SPI_MASK |
- OXYGEN_FUNCTION_ENABLE_SPI_4_5);
- oxygen_write8(chip, OXYGEN_DMA_STATUS, 0);
- oxygen_write8(chip, OXYGEN_DMA_PAUSE, 0);
- oxygen_write8(chip, OXYGEN_PLAY_CHANNELS,
- OXYGEN_PLAY_CHANNELS_2 |
- OXYGEN_DMA_A_BURST_8 |
- OXYGEN_DMA_MULTICH_BURST_8);
- oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0);
- oxygen_write8_masked(chip, OXYGEN_MISC,
- chip->model.misc_flags,
- OXYGEN_MISC_WRITE_PCI_SUBID |
- OXYGEN_MISC_REC_C_FROM_SPDIF |
- OXYGEN_MISC_REC_B_FROM_AC97 |
- OXYGEN_MISC_REC_A_FROM_MULTICH |
- OXYGEN_MISC_MIDI);
- oxygen_write8(chip, OXYGEN_REC_FORMAT,
- (OXYGEN_FORMAT_16 << OXYGEN_REC_FORMAT_A_SHIFT) |
- (OXYGEN_FORMAT_16 << OXYGEN_REC_FORMAT_B_SHIFT) |
- (OXYGEN_FORMAT_16 << OXYGEN_REC_FORMAT_C_SHIFT));
- oxygen_write8(chip, OXYGEN_PLAY_FORMAT,
- (OXYGEN_FORMAT_16 << OXYGEN_SPDIF_FORMAT_SHIFT) |
- (OXYGEN_FORMAT_16 << OXYGEN_MULTICH_FORMAT_SHIFT));
- oxygen_write8(chip, OXYGEN_REC_CHANNELS, OXYGEN_REC_CHANNELS_2_2_2);
- oxygen_write16(chip, OXYGEN_I2S_MULTICH_FORMAT,
- OXYGEN_RATE_48000 |
- chip->model.dac_i2s_format |
- OXYGEN_I2S_MCLK(chip->model.dac_mclks) |
- OXYGEN_I2S_BITS_16 |
- OXYGEN_I2S_MASTER |
- OXYGEN_I2S_BCLK_64);
- if (chip->model.device_config & CAPTURE_0_FROM_I2S_1)
- oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
- OXYGEN_RATE_48000 |
- chip->model.adc_i2s_format |
- OXYGEN_I2S_MCLK(chip->model.adc_mclks) |
- OXYGEN_I2S_BITS_16 |
- OXYGEN_I2S_MASTER |
- OXYGEN_I2S_BCLK_64);
- else
- oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
- OXYGEN_I2S_MASTER |
- OXYGEN_I2S_MUTE_MCLK);
- if (chip->model.device_config & (CAPTURE_0_FROM_I2S_2 |
- CAPTURE_2_FROM_I2S_2))
- oxygen_write16(chip, OXYGEN_I2S_B_FORMAT,
- OXYGEN_RATE_48000 |
- chip->model.adc_i2s_format |
- OXYGEN_I2S_MCLK(chip->model.adc_mclks) |
- OXYGEN_I2S_BITS_16 |
- OXYGEN_I2S_MASTER |
- OXYGEN_I2S_BCLK_64);
- else
- oxygen_write16(chip, OXYGEN_I2S_B_FORMAT,
- OXYGEN_I2S_MASTER |
- OXYGEN_I2S_MUTE_MCLK);
- oxygen_write16(chip, OXYGEN_I2S_C_FORMAT,
- OXYGEN_I2S_MASTER |
- OXYGEN_I2S_MUTE_MCLK);
- oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
- OXYGEN_SPDIF_OUT_ENABLE |
- OXYGEN_SPDIF_LOOPBACK);
- if (chip->model.device_config & CAPTURE_1_FROM_SPDIF)
- oxygen_write32_masked(chip, OXYGEN_SPDIF_CONTROL,
- OXYGEN_SPDIF_SENSE_MASK |
- OXYGEN_SPDIF_LOCK_MASK |
- OXYGEN_SPDIF_RATE_MASK |
- OXYGEN_SPDIF_LOCK_PAR |
- OXYGEN_SPDIF_IN_CLOCK_96,
- OXYGEN_SPDIF_SENSE_MASK |
- OXYGEN_SPDIF_LOCK_MASK |
- OXYGEN_SPDIF_RATE_MASK |
- OXYGEN_SPDIF_SENSE_PAR |
- OXYGEN_SPDIF_LOCK_PAR |
- OXYGEN_SPDIF_IN_CLOCK_MASK);
- else
- oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
- OXYGEN_SPDIF_SENSE_MASK |
- OXYGEN_SPDIF_LOCK_MASK |
- OXYGEN_SPDIF_RATE_MASK);
- oxygen_write32(chip, OXYGEN_SPDIF_OUTPUT_BITS, chip->spdif_bits);
- oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
- OXYGEN_2WIRE_LENGTH_8 |
- OXYGEN_2WIRE_INTERRUPT_MASK |
- OXYGEN_2WIRE_SPEED_STANDARD);
- oxygen_clear_bits8(chip, OXYGEN_MPU401_CONTROL, OXYGEN_MPU401_LOOPBACK);
- oxygen_write8(chip, OXYGEN_GPI_INTERRUPT_MASK, 0);
- oxygen_write16(chip, OXYGEN_GPIO_INTERRUPT_MASK, 0);
- oxygen_write16(chip, OXYGEN_PLAY_ROUTING,
- OXYGEN_PLAY_MULTICH_I2S_DAC |
- OXYGEN_PLAY_SPDIF_SPDIF |
- (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
- (1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
- (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
- (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT));
- oxygen_write8(chip, OXYGEN_REC_ROUTING,
- OXYGEN_REC_A_ROUTE_I2S_ADC_1 |
- OXYGEN_REC_B_ROUTE_I2S_ADC_2 |
- OXYGEN_REC_C_ROUTE_SPDIF);
- oxygen_write8(chip, OXYGEN_ADC_MONITOR, 0);
- oxygen_write8(chip, OXYGEN_A_MONITOR_ROUTING,
- (0 << OXYGEN_A_MONITOR_ROUTE_0_SHIFT) |
- (1 << OXYGEN_A_MONITOR_ROUTE_1_SHIFT) |
- (2 << OXYGEN_A_MONITOR_ROUTE_2_SHIFT) |
- (3 << OXYGEN_A_MONITOR_ROUTE_3_SHIFT));
-
- if (chip->has_ac97_0 | chip->has_ac97_1)
- oxygen_write8(chip, OXYGEN_AC97_INTERRUPT_MASK,
- OXYGEN_AC97_INT_READ_DONE |
- OXYGEN_AC97_INT_WRITE_DONE);
- else
- oxygen_write8(chip, OXYGEN_AC97_INTERRUPT_MASK, 0);
- oxygen_write32(chip, OXYGEN_AC97_OUT_CONFIG, 0);
- oxygen_write32(chip, OXYGEN_AC97_IN_CONFIG, 0);
- if (!(chip->has_ac97_0 | chip->has_ac97_1))
- oxygen_set_bits16(chip, OXYGEN_AC97_CONTROL,
- OXYGEN_AC97_CLOCK_DISABLE);
- if (!chip->has_ac97_0) {
- oxygen_set_bits16(chip, OXYGEN_AC97_CONTROL,
- OXYGEN_AC97_NO_CODEC_0);
- } else {
- oxygen_write_ac97(chip, 0, AC97_RESET, 0);
- msleep(1);
- oxygen_ac97_set_bits(chip, 0, CM9780_GPIO_SETUP,
- CM9780_GPIO0IO | CM9780_GPIO1IO);
- oxygen_ac97_set_bits(chip, 0, CM9780_MIXER,
- CM9780_BSTSEL | CM9780_STRO_MIC |
- CM9780_MIX2FR | CM9780_PCBSW);
- oxygen_ac97_set_bits(chip, 0, CM9780_JACK,
- CM9780_RSOE | CM9780_CBOE |
- CM9780_SSOE | CM9780_FROE |
- CM9780_MIC2MIC | CM9780_LI2LI);
- oxygen_write_ac97(chip, 0, AC97_MASTER, 0x0000);
- oxygen_write_ac97(chip, 0, AC97_PC_BEEP, 0x8000);
- oxygen_write_ac97(chip, 0, AC97_MIC, 0x8808);
- oxygen_write_ac97(chip, 0, AC97_LINE, 0x0808);
- oxygen_write_ac97(chip, 0, AC97_CD, 0x8808);
- oxygen_write_ac97(chip, 0, AC97_VIDEO, 0x8808);
- oxygen_write_ac97(chip, 0, AC97_AUX, 0x8808);
- oxygen_write_ac97(chip, 0, AC97_REC_GAIN, 0x8000);
- oxygen_write_ac97(chip, 0, AC97_CENTER_LFE_MASTER, 0x8080);
- oxygen_write_ac97(chip, 0, AC97_SURROUND_MASTER, 0x8080);
- oxygen_ac97_clear_bits(chip, 0, CM9780_GPIO_STATUS,
- CM9780_GPO0);
- /* power down unused ADCs and DACs */
- oxygen_ac97_set_bits(chip, 0, AC97_POWERDOWN,
- AC97_PD_PR0 | AC97_PD_PR1);
- oxygen_ac97_set_bits(chip, 0, AC97_EXTENDED_STATUS,
- AC97_EA_PRI | AC97_EA_PRJ | AC97_EA_PRK);
- }
- if (chip->has_ac97_1) {
- oxygen_set_bits32(chip, OXYGEN_AC97_OUT_CONFIG,
- OXYGEN_AC97_CODEC1_SLOT3 |
- OXYGEN_AC97_CODEC1_SLOT4);
- oxygen_write_ac97(chip, 1, AC97_RESET, 0);
- msleep(1);
- oxygen_write_ac97(chip, 1, AC97_MASTER, 0x0000);
- oxygen_write_ac97(chip, 1, AC97_HEADPHONE, 0x8000);
- oxygen_write_ac97(chip, 1, AC97_PC_BEEP, 0x8000);
- oxygen_write_ac97(chip, 1, AC97_MIC, 0x8808);
- oxygen_write_ac97(chip, 1, AC97_LINE, 0x8808);
- oxygen_write_ac97(chip, 1, AC97_CD, 0x8808);
- oxygen_write_ac97(chip, 1, AC97_VIDEO, 0x8808);
- oxygen_write_ac97(chip, 1, AC97_AUX, 0x8808);
- oxygen_write_ac97(chip, 1, AC97_PCM, 0x0808);
- oxygen_write_ac97(chip, 1, AC97_REC_SEL, 0x0000);
- oxygen_write_ac97(chip, 1, AC97_REC_GAIN, 0x0000);
- oxygen_ac97_set_bits(chip, 1, 0x6a, 0x0040);
- }
-}
-
-static void oxygen_shutdown(struct oxygen *chip)
-{
- spin_lock_irq(&chip->reg_lock);
- chip->interrupt_mask = 0;
- chip->pcm_running = 0;
- oxygen_write16(chip, OXYGEN_DMA_STATUS, 0);
- oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0);
- spin_unlock_irq(&chip->reg_lock);
-}
-
-static void oxygen_card_free(struct snd_card *card)
-{
- struct oxygen *chip = card->private_data;
-
- oxygen_shutdown(chip);
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
- flush_work_sync(&chip->spdif_input_bits_work);
- flush_work_sync(&chip->gpio_work);
- chip->model.cleanup(chip);
- kfree(chip->model_data);
- mutex_destroy(&chip->mutex);
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
-}
-
-int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
- struct module *owner,
- const struct pci_device_id *ids,
- int (*get_model)(struct oxygen *chip,
- const struct pci_device_id *id
- )
- )
-{
- struct snd_card *card;
- struct oxygen *chip;
- const struct pci_device_id *pci_id;
- int err;
-
- err = snd_card_create(index, id, owner, sizeof(*chip), &card);
- if (err < 0)
- return err;
-
- chip = card->private_data;
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
- spin_lock_init(&chip->reg_lock);
- mutex_init(&chip->mutex);
- INIT_WORK(&chip->spdif_input_bits_work,
- oxygen_spdif_input_bits_changed);
- INIT_WORK(&chip->gpio_work, oxygen_gpio_changed);
- init_waitqueue_head(&chip->ac97_waitqueue);
-
- err = pci_enable_device(pci);
- if (err < 0)
- goto err_card;
-
- err = pci_request_regions(pci, DRIVER);
- if (err < 0) {
- snd_printk(KERN_ERR "cannot reserve PCI resources\n");
- goto err_pci_enable;
- }
-
- if (!(pci_resource_flags(pci, 0) & IORESOURCE_IO) ||
- pci_resource_len(pci, 0) < OXYGEN_IO_SIZE) {
- snd_printk(KERN_ERR "invalid PCI I/O range\n");
- err = -ENXIO;
- goto err_pci_regions;
- }
- chip->addr = pci_resource_start(pci, 0);
-
- pci_id = oxygen_search_pci_id(chip, ids);
- if (!pci_id) {
- err = -ENODEV;
- goto err_pci_regions;
- }
- oxygen_restore_eeprom(chip, pci_id);
- err = get_model(chip, pci_id);
- if (err < 0)
- goto err_pci_regions;
-
- if (chip->model.model_data_size) {
- chip->model_data = kzalloc(chip->model.model_data_size,
- GFP_KERNEL);
- if (!chip->model_data) {
- err = -ENOMEM;
- goto err_pci_regions;
- }
- }
-
- pci_set_master(pci);
- snd_card_set_dev(card, &pci->dev);
- card->private_free = oxygen_card_free;
-
- configure_pcie_bridge(pci);
- oxygen_init(chip);
- chip->model.init(chip);
-
- err = request_irq(pci->irq, oxygen_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, chip);
- if (err < 0) {
- snd_printk(KERN_ERR "cannot grab interrupt %d\n", pci->irq);
- goto err_card;
- }
- chip->irq = pci->irq;
-
- strcpy(card->driver, chip->model.chip);
- strcpy(card->shortname, chip->model.shortname);
- sprintf(card->longname, "%s at %#lx, irq %i",
- chip->model.longname, chip->addr, chip->irq);
- strcpy(card->mixername, chip->model.chip);
- snd_component_add(card, chip->model.chip);
-
- err = oxygen_pcm_init(chip);
- if (err < 0)
- goto err_card;
-
- err = oxygen_mixer_init(chip);
- if (err < 0)
- goto err_card;
-
- if (chip->model.device_config & (MIDI_OUTPUT | MIDI_INPUT)) {
- unsigned int info_flags =
- MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK;
- if (chip->model.device_config & MIDI_OUTPUT)
- info_flags |= MPU401_INFO_OUTPUT;
- if (chip->model.device_config & MIDI_INPUT)
- info_flags |= MPU401_INFO_INPUT;
- err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
- chip->addr + OXYGEN_MPU401,
- info_flags, -1, &chip->midi);
- if (err < 0)
- goto err_card;
- }
-
- oxygen_proc_init(chip);
-
- spin_lock_irq(&chip->reg_lock);
- if (chip->model.device_config & CAPTURE_1_FROM_SPDIF)
- chip->interrupt_mask |= OXYGEN_INT_SPDIF_IN_DETECT;
- if (chip->has_ac97_0 | chip->has_ac97_1)
- chip->interrupt_mask |= OXYGEN_INT_AC97;
- oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
- spin_unlock_irq(&chip->reg_lock);
-
- err = snd_card_register(card);
- if (err < 0)
- goto err_card;
-
- pci_set_drvdata(pci, card);
- return 0;
-
-err_pci_regions:
- pci_release_regions(pci);
-err_pci_enable:
- pci_disable_device(pci);
-err_card:
- snd_card_free(card);
- return err;
-}
-EXPORT_SYMBOL(oxygen_pci_probe);
-
-void oxygen_pci_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-EXPORT_SYMBOL(oxygen_pci_remove);
-
-#ifdef CONFIG_PM
-int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct oxygen *chip = card->private_data;
- unsigned int i, saved_interrupt_mask;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-
- for (i = 0; i < PCM_COUNT; ++i)
- if (chip->streams[i])
- snd_pcm_suspend(chip->streams[i]);
-
- if (chip->model.suspend)
- chip->model.suspend(chip);
-
- spin_lock_irq(&chip->reg_lock);
- saved_interrupt_mask = chip->interrupt_mask;
- chip->interrupt_mask = 0;
- oxygen_write16(chip, OXYGEN_DMA_STATUS, 0);
- oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0);
- spin_unlock_irq(&chip->reg_lock);
-
- synchronize_irq(chip->irq);
- flush_work_sync(&chip->spdif_input_bits_work);
- flush_work_sync(&chip->gpio_work);
- chip->interrupt_mask = saved_interrupt_mask;
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-EXPORT_SYMBOL(oxygen_pci_suspend);
-
-static const u32 registers_to_restore[OXYGEN_IO_SIZE / 32] = {
- 0xffffffff, 0x00ff077f, 0x00011d08, 0x007f00ff,
- 0x00300000, 0x00000fe4, 0x0ff7001f, 0x00000000
-};
-static const u32 ac97_registers_to_restore[2][0x40 / 32] = {
- { 0x18284fa2, 0x03060000 },
- { 0x00007fa6, 0x00200000 }
-};
-
-static inline int is_bit_set(const u32 *bitmap, unsigned int bit)
-{
- return bitmap[bit / 32] & (1 << (bit & 31));
-}
-
-static void oxygen_restore_ac97(struct oxygen *chip, unsigned int codec)
-{
- unsigned int i;
-
- oxygen_write_ac97(chip, codec, AC97_RESET, 0);
- msleep(1);
- for (i = 1; i < 0x40; ++i)
- if (is_bit_set(ac97_registers_to_restore[codec], i))
- oxygen_write_ac97(chip, codec, i * 2,
- chip->saved_ac97_registers[codec][i]);
-}
-
-int oxygen_pci_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct oxygen *chip = card->private_data;
- unsigned int i;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- snd_printk(KERN_ERR "cannot reenable device");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
-
- oxygen_write16(chip, OXYGEN_DMA_STATUS, 0);
- oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0);
- for (i = 0; i < OXYGEN_IO_SIZE; ++i)
- if (is_bit_set(registers_to_restore, i))
- oxygen_write8(chip, i, chip->saved_registers._8[i]);
- if (chip->has_ac97_0)
- oxygen_restore_ac97(chip, 0);
- if (chip->has_ac97_1)
- oxygen_restore_ac97(chip, 1);
-
- if (chip->model.resume)
- chip->model.resume(chip);
-
- oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-EXPORT_SYMBOL(oxygen_pci_resume);
-#endif /* CONFIG_PM */
-
-void oxygen_pci_shutdown(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct oxygen *chip = card->private_data;
-
- oxygen_shutdown(chip);
- chip->model.cleanup(chip);
-}
-EXPORT_SYMBOL(oxygen_pci_shutdown);
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/oxygen_mixer.c b/ANDROID_3.4.5/sound/pci/oxygen/oxygen_mixer.c
deleted file mode 100644
index c0dbb52d..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/oxygen_mixer.c
+++ /dev/null
@@ -1,1102 +0,0 @@
-/*
- * C-Media CMI8788 driver - mixer code
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- *
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this driver; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/mutex.h>
-#include <sound/ac97_codec.h>
-#include <sound/asoundef.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include "oxygen.h"
-#include "cm9780.h"
-
-static int dac_volume_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- struct oxygen *chip = ctl->private_data;
-
- info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- info->count = chip->model.dac_channels_mixer;
- info->value.integer.min = chip->model.dac_volume_min;
- info->value.integer.max = chip->model.dac_volume_max;
- return 0;
-}
-
-static int dac_volume_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- unsigned int i;
-
- mutex_lock(&chip->mutex);
- for (i = 0; i < chip->model.dac_channels_mixer; ++i)
- value->value.integer.value[i] = chip->dac_volume[i];
- mutex_unlock(&chip->mutex);
- return 0;
-}
-
-static int dac_volume_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- unsigned int i;
- int changed;
-
- changed = 0;
- mutex_lock(&chip->mutex);
- for (i = 0; i < chip->model.dac_channels_mixer; ++i)
- if (value->value.integer.value[i] != chip->dac_volume[i]) {
- chip->dac_volume[i] = value->value.integer.value[i];
- changed = 1;
- }
- if (changed)
- chip->model.update_dac_volume(chip);
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static int dac_mute_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
-
- mutex_lock(&chip->mutex);
- value->value.integer.value[0] = !chip->dac_mute;
- mutex_unlock(&chip->mutex);
- return 0;
-}
-
-static int dac_mute_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- int changed;
-
- mutex_lock(&chip->mutex);
- changed = !value->value.integer.value[0] != chip->dac_mute;
- if (changed) {
- chip->dac_mute = !value->value.integer.value[0];
- chip->model.update_dac_mute(chip);
- }
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static unsigned int upmix_item_count(struct oxygen *chip)
-{
- if (chip->model.dac_channels_pcm < 8)
- return 2;
- else if (chip->model.update_center_lfe_mix)
- return 5;
- else
- return 3;
-}
-
-static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
-{
- static const char *const names[5] = {
- "Front",
- "Front+Surround",
- "Front+Surround+Back",
- "Front+Surround+Center/LFE",
- "Front+Surround+Center/LFE+Back",
- };
- struct oxygen *chip = ctl->private_data;
- unsigned int count = upmix_item_count(chip);
-
- return snd_ctl_enum_info(info, 1, count, names);
-}
-
-static int upmix_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
-
- mutex_lock(&chip->mutex);
- value->value.enumerated.item[0] = chip->dac_routing;
- mutex_unlock(&chip->mutex);
- return 0;
-}
-
-void oxygen_update_dac_routing(struct oxygen *chip)
-{
- /* DAC 0: front, DAC 1: surround, DAC 2: center/LFE, DAC 3: back */
- static const unsigned int reg_values[5] = {
- /* stereo -> front */
- (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
- (1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
- (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
- (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
- /* stereo -> front+surround */
- (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
- (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
- (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
- (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
- /* stereo -> front+surround+back */
- (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
- (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
- (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
- (0 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
- /* stereo -> front+surround+center/LFE */
- (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
- (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
- (0 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
- (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
- /* stereo -> front+surround+center/LFE+back */
- (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
- (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
- (0 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
- (0 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
- };
- u8 channels;
- unsigned int reg_value;
-
- channels = oxygen_read8(chip, OXYGEN_PLAY_CHANNELS) &
- OXYGEN_PLAY_CHANNELS_MASK;
- if (channels == OXYGEN_PLAY_CHANNELS_2)
- reg_value = reg_values[chip->dac_routing];
- else if (channels == OXYGEN_PLAY_CHANNELS_8)
- /* in 7.1 mode, "rear" channels go to the "back" jack */
- reg_value = (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
- (3 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
- (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
- (1 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT);
- else
- reg_value = (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
- (1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
- (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
- (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT);
- if (chip->model.adjust_dac_routing)
- reg_value = chip->model.adjust_dac_routing(chip, reg_value);
- oxygen_write16_masked(chip, OXYGEN_PLAY_ROUTING, reg_value,
- OXYGEN_PLAY_DAC0_SOURCE_MASK |
- OXYGEN_PLAY_DAC1_SOURCE_MASK |
- OXYGEN_PLAY_DAC2_SOURCE_MASK |
- OXYGEN_PLAY_DAC3_SOURCE_MASK);
- if (chip->model.update_center_lfe_mix)
- chip->model.update_center_lfe_mix(chip, chip->dac_routing > 2);
-}
-
-static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- unsigned int count = upmix_item_count(chip);
- int changed;
-
- if (value->value.enumerated.item[0] >= count)
- return -EINVAL;
- mutex_lock(&chip->mutex);
- changed = value->value.enumerated.item[0] != chip->dac_routing;
- if (changed) {
- chip->dac_routing = value->value.enumerated.item[0];
- oxygen_update_dac_routing(chip);
- }
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static int spdif_switch_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
-
- mutex_lock(&chip->mutex);
- value->value.integer.value[0] = chip->spdif_playback_enable;
- mutex_unlock(&chip->mutex);
- return 0;
-}
-
-static unsigned int oxygen_spdif_rate(unsigned int oxygen_rate)
-{
- switch (oxygen_rate) {
- case OXYGEN_RATE_32000:
- return IEC958_AES3_CON_FS_32000 << OXYGEN_SPDIF_CS_RATE_SHIFT;
- case OXYGEN_RATE_44100:
- return IEC958_AES3_CON_FS_44100 << OXYGEN_SPDIF_CS_RATE_SHIFT;
- default: /* OXYGEN_RATE_48000 */
- return IEC958_AES3_CON_FS_48000 << OXYGEN_SPDIF_CS_RATE_SHIFT;
- case OXYGEN_RATE_64000:
- return 0xb << OXYGEN_SPDIF_CS_RATE_SHIFT;
- case OXYGEN_RATE_88200:
- return IEC958_AES3_CON_FS_88200 << OXYGEN_SPDIF_CS_RATE_SHIFT;
- case OXYGEN_RATE_96000:
- return IEC958_AES3_CON_FS_96000 << OXYGEN_SPDIF_CS_RATE_SHIFT;
- case OXYGEN_RATE_176400:
- return IEC958_AES3_CON_FS_176400 << OXYGEN_SPDIF_CS_RATE_SHIFT;
- case OXYGEN_RATE_192000:
- return IEC958_AES3_CON_FS_192000 << OXYGEN_SPDIF_CS_RATE_SHIFT;
- }
-}
-
-void oxygen_update_spdif_source(struct oxygen *chip)
-{
- u32 old_control, new_control;
- u16 old_routing, new_routing;
- unsigned int oxygen_rate;
-
- old_control = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
- old_routing = oxygen_read16(chip, OXYGEN_PLAY_ROUTING);
- if (chip->pcm_active & (1 << PCM_SPDIF)) {
- new_control = old_control | OXYGEN_SPDIF_OUT_ENABLE;
- new_routing = (old_routing & ~OXYGEN_PLAY_SPDIF_MASK)
- | OXYGEN_PLAY_SPDIF_SPDIF;
- oxygen_rate = (old_control >> OXYGEN_SPDIF_OUT_RATE_SHIFT)
- & OXYGEN_I2S_RATE_MASK;
- /* S/PDIF rate was already set by the caller */
- } else if ((chip->pcm_active & (1 << PCM_MULTICH)) &&
- chip->spdif_playback_enable) {
- new_routing = (old_routing & ~OXYGEN_PLAY_SPDIF_MASK)
- | OXYGEN_PLAY_SPDIF_MULTICH_01;
- oxygen_rate = oxygen_read16(chip, OXYGEN_I2S_MULTICH_FORMAT)
- & OXYGEN_I2S_RATE_MASK;
- new_control = (old_control & ~OXYGEN_SPDIF_OUT_RATE_MASK) |
- (oxygen_rate << OXYGEN_SPDIF_OUT_RATE_SHIFT) |
- OXYGEN_SPDIF_OUT_ENABLE;
- } else {
- new_control = old_control & ~OXYGEN_SPDIF_OUT_ENABLE;
- new_routing = old_routing;
- oxygen_rate = OXYGEN_RATE_44100;
- }
- if (old_routing != new_routing) {
- oxygen_write32(chip, OXYGEN_SPDIF_CONTROL,
- new_control & ~OXYGEN_SPDIF_OUT_ENABLE);
- oxygen_write16(chip, OXYGEN_PLAY_ROUTING, new_routing);
- }
- if (new_control & OXYGEN_SPDIF_OUT_ENABLE)
- oxygen_write32(chip, OXYGEN_SPDIF_OUTPUT_BITS,
- oxygen_spdif_rate(oxygen_rate) |
- ((chip->pcm_active & (1 << PCM_SPDIF)) ?
- chip->spdif_pcm_bits : chip->spdif_bits));
- oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, new_control);
-}
-
-static int spdif_switch_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- int changed;
-
- mutex_lock(&chip->mutex);
- changed = value->value.integer.value[0] != chip->spdif_playback_enable;
- if (changed) {
- chip->spdif_playback_enable = !!value->value.integer.value[0];
- spin_lock_irq(&chip->reg_lock);
- oxygen_update_spdif_source(chip);
- spin_unlock_irq(&chip->reg_lock);
- }
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static int spdif_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
-{
- info->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- info->count = 1;
- return 0;
-}
-
-static void oxygen_to_iec958(u32 bits, struct snd_ctl_elem_value *value)
-{
- value->value.iec958.status[0] =
- bits & (OXYGEN_SPDIF_NONAUDIO | OXYGEN_SPDIF_C |
- OXYGEN_SPDIF_PREEMPHASIS);
- value->value.iec958.status[1] = /* category and original */
- bits >> OXYGEN_SPDIF_CATEGORY_SHIFT;
-}
-
-static u32 iec958_to_oxygen(struct snd_ctl_elem_value *value)
-{
- u32 bits;
-
- bits = value->value.iec958.status[0] &
- (OXYGEN_SPDIF_NONAUDIO | OXYGEN_SPDIF_C |
- OXYGEN_SPDIF_PREEMPHASIS);
- bits |= value->value.iec958.status[1] << OXYGEN_SPDIF_CATEGORY_SHIFT;
- if (bits & OXYGEN_SPDIF_NONAUDIO)
- bits |= OXYGEN_SPDIF_V;
- return bits;
-}
-
-static inline void write_spdif_bits(struct oxygen *chip, u32 bits)
-{
- oxygen_write32_masked(chip, OXYGEN_SPDIF_OUTPUT_BITS, bits,
- OXYGEN_SPDIF_NONAUDIO |
- OXYGEN_SPDIF_C |
- OXYGEN_SPDIF_PREEMPHASIS |
- OXYGEN_SPDIF_CATEGORY_MASK |
- OXYGEN_SPDIF_ORIGINAL |
- OXYGEN_SPDIF_V);
-}
-
-static int spdif_default_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
-
- mutex_lock(&chip->mutex);
- oxygen_to_iec958(chip->spdif_bits, value);
- mutex_unlock(&chip->mutex);
- return 0;
-}
-
-static int spdif_default_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- u32 new_bits;
- int changed;
-
- new_bits = iec958_to_oxygen(value);
- mutex_lock(&chip->mutex);
- changed = new_bits != chip->spdif_bits;
- if (changed) {
- chip->spdif_bits = new_bits;
- if (!(chip->pcm_active & (1 << PCM_SPDIF)))
- write_spdif_bits(chip, new_bits);
- }
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static int spdif_mask_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- value->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
- IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS;
- value->value.iec958.status[1] =
- IEC958_AES1_CON_CATEGORY | IEC958_AES1_CON_ORIGINAL;
- return 0;
-}
-
-static int spdif_pcm_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
-
- mutex_lock(&chip->mutex);
- oxygen_to_iec958(chip->spdif_pcm_bits, value);
- mutex_unlock(&chip->mutex);
- return 0;
-}
-
-static int spdif_pcm_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- u32 new_bits;
- int changed;
-
- new_bits = iec958_to_oxygen(value);
- mutex_lock(&chip->mutex);
- changed = new_bits != chip->spdif_pcm_bits;
- if (changed) {
- chip->spdif_pcm_bits = new_bits;
- if (chip->pcm_active & (1 << PCM_SPDIF))
- write_spdif_bits(chip, new_bits);
- }
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static int spdif_input_mask_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- value->value.iec958.status[0] = 0xff;
- value->value.iec958.status[1] = 0xff;
- value->value.iec958.status[2] = 0xff;
- value->value.iec958.status[3] = 0xff;
- return 0;
-}
-
-static int spdif_input_default_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- u32 bits;
-
- bits = oxygen_read32(chip, OXYGEN_SPDIF_INPUT_BITS);
- value->value.iec958.status[0] = bits;
- value->value.iec958.status[1] = bits >> 8;
- value->value.iec958.status[2] = bits >> 16;
- value->value.iec958.status[3] = bits >> 24;
- return 0;
-}
-
-static int spdif_bit_switch_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- u32 bit = ctl->private_value;
-
- value->value.integer.value[0] =
- !!(oxygen_read32(chip, OXYGEN_SPDIF_CONTROL) & bit);
- return 0;
-}
-
-static int spdif_bit_switch_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- u32 bit = ctl->private_value;
- u32 oldreg, newreg;
- int changed;
-
- spin_lock_irq(&chip->reg_lock);
- oldreg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
- if (value->value.integer.value[0])
- newreg = oldreg | bit;
- else
- newreg = oldreg & ~bit;
- changed = newreg != oldreg;
- if (changed)
- oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, newreg);
- spin_unlock_irq(&chip->reg_lock);
- return changed;
-}
-
-static int monitor_volume_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- info->count = 1;
- info->value.integer.min = 0;
- info->value.integer.max = 1;
- return 0;
-}
-
-static int monitor_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- u8 bit = ctl->private_value;
- int invert = ctl->private_value & (1 << 8);
-
- value->value.integer.value[0] =
- !!invert ^ !!(oxygen_read8(chip, OXYGEN_ADC_MONITOR) & bit);
- return 0;
-}
-
-static int monitor_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- u8 bit = ctl->private_value;
- int invert = ctl->private_value & (1 << 8);
- u8 oldreg, newreg;
- int changed;
-
- spin_lock_irq(&chip->reg_lock);
- oldreg = oxygen_read8(chip, OXYGEN_ADC_MONITOR);
- if ((!!value->value.integer.value[0] ^ !!invert) != 0)
- newreg = oldreg | bit;
- else
- newreg = oldreg & ~bit;
- changed = newreg != oldreg;
- if (changed)
- oxygen_write8(chip, OXYGEN_ADC_MONITOR, newreg);
- spin_unlock_irq(&chip->reg_lock);
- return changed;
-}
-
-static int ac97_switch_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- unsigned int codec = (ctl->private_value >> 24) & 1;
- unsigned int index = ctl->private_value & 0xff;
- unsigned int bitnr = (ctl->private_value >> 8) & 0xff;
- int invert = ctl->private_value & (1 << 16);
- u16 reg;
-
- mutex_lock(&chip->mutex);
- reg = oxygen_read_ac97(chip, codec, index);
- mutex_unlock(&chip->mutex);
- if (!(reg & (1 << bitnr)) ^ !invert)
- value->value.integer.value[0] = 1;
- else
- value->value.integer.value[0] = 0;
- return 0;
-}
-
-static void mute_ac97_ctl(struct oxygen *chip, unsigned int control)
-{
- unsigned int priv_idx;
- u16 value;
-
- if (!chip->controls[control])
- return;
- priv_idx = chip->controls[control]->private_value & 0xff;
- value = oxygen_read_ac97(chip, 0, priv_idx);
- if (!(value & 0x8000)) {
- oxygen_write_ac97(chip, 0, priv_idx, value | 0x8000);
- if (chip->model.ac97_switch)
- chip->model.ac97_switch(chip, priv_idx, 0x8000);
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->controls[control]->id);
- }
-}
-
-static int ac97_switch_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- unsigned int codec = (ctl->private_value >> 24) & 1;
- unsigned int index = ctl->private_value & 0xff;
- unsigned int bitnr = (ctl->private_value >> 8) & 0xff;
- int invert = ctl->private_value & (1 << 16);
- u16 oldreg, newreg;
- int change;
-
- mutex_lock(&chip->mutex);
- oldreg = oxygen_read_ac97(chip, codec, index);
- newreg = oldreg;
- if (!value->value.integer.value[0] ^ !invert)
- newreg |= 1 << bitnr;
- else
- newreg &= ~(1 << bitnr);
- change = newreg != oldreg;
- if (change) {
- oxygen_write_ac97(chip, codec, index, newreg);
- if (codec == 0 && chip->model.ac97_switch)
- chip->model.ac97_switch(chip, index, newreg & 0x8000);
- if (index == AC97_LINE) {
- oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS,
- newreg & 0x8000 ?
- CM9780_GPO0 : 0, CM9780_GPO0);
- if (!(newreg & 0x8000)) {
- mute_ac97_ctl(chip, CONTROL_MIC_CAPTURE_SWITCH);
- mute_ac97_ctl(chip, CONTROL_CD_CAPTURE_SWITCH);
- mute_ac97_ctl(chip, CONTROL_AUX_CAPTURE_SWITCH);
- }
- } else if ((index == AC97_MIC || index == AC97_CD ||
- index == AC97_VIDEO || index == AC97_AUX) &&
- bitnr == 15 && !(newreg & 0x8000)) {
- mute_ac97_ctl(chip, CONTROL_LINE_CAPTURE_SWITCH);
- oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS,
- CM9780_GPO0, CM9780_GPO0);
- }
- }
- mutex_unlock(&chip->mutex);
- return change;
-}
-
-static int ac97_volume_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- int stereo = (ctl->private_value >> 16) & 1;
-
- info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- info->count = stereo ? 2 : 1;
- info->value.integer.min = 0;
- info->value.integer.max = 0x1f;
- return 0;
-}
-
-static int ac97_volume_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- unsigned int codec = (ctl->private_value >> 24) & 1;
- int stereo = (ctl->private_value >> 16) & 1;
- unsigned int index = ctl->private_value & 0xff;
- u16 reg;
-
- mutex_lock(&chip->mutex);
- reg = oxygen_read_ac97(chip, codec, index);
- mutex_unlock(&chip->mutex);
- if (!stereo) {
- value->value.integer.value[0] = 31 - (reg & 0x1f);
- } else {
- value->value.integer.value[0] = 31 - ((reg >> 8) & 0x1f);
- value->value.integer.value[1] = 31 - (reg & 0x1f);
- }
- return 0;
-}
-
-static int ac97_volume_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- unsigned int codec = (ctl->private_value >> 24) & 1;
- int stereo = (ctl->private_value >> 16) & 1;
- unsigned int index = ctl->private_value & 0xff;
- u16 oldreg, newreg;
- int change;
-
- mutex_lock(&chip->mutex);
- oldreg = oxygen_read_ac97(chip, codec, index);
- if (!stereo) {
- newreg = oldreg & ~0x1f;
- newreg |= 31 - (value->value.integer.value[0] & 0x1f);
- } else {
- newreg = oldreg & ~0x1f1f;
- newreg |= (31 - (value->value.integer.value[0] & 0x1f)) << 8;
- newreg |= 31 - (value->value.integer.value[1] & 0x1f);
- }
- change = newreg != oldreg;
- if (change)
- oxygen_write_ac97(chip, codec, index, newreg);
- mutex_unlock(&chip->mutex);
- return change;
-}
-
-static int mic_fmic_source_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- static const char *const names[] = { "Mic Jack", "Front Panel" };
-
- return snd_ctl_enum_info(info, 1, 2, names);
-}
-
-static int mic_fmic_source_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
-
- mutex_lock(&chip->mutex);
- value->value.enumerated.item[0] =
- !!(oxygen_read_ac97(chip, 0, CM9780_JACK) & CM9780_FMIC2MIC);
- mutex_unlock(&chip->mutex);
- return 0;
-}
-
-static int mic_fmic_source_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- u16 oldreg, newreg;
- int change;
-
- mutex_lock(&chip->mutex);
- oldreg = oxygen_read_ac97(chip, 0, CM9780_JACK);
- if (value->value.enumerated.item[0])
- newreg = oldreg | CM9780_FMIC2MIC;
- else
- newreg = oldreg & ~CM9780_FMIC2MIC;
- change = newreg != oldreg;
- if (change)
- oxygen_write_ac97(chip, 0, CM9780_JACK, newreg);
- mutex_unlock(&chip->mutex);
- return change;
-}
-
-static int ac97_fp_rec_volume_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- info->count = 2;
- info->value.integer.min = 0;
- info->value.integer.max = 7;
- return 0;
-}
-
-static int ac97_fp_rec_volume_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- u16 reg;
-
- mutex_lock(&chip->mutex);
- reg = oxygen_read_ac97(chip, 1, AC97_REC_GAIN);
- mutex_unlock(&chip->mutex);
- value->value.integer.value[0] = reg & 7;
- value->value.integer.value[1] = (reg >> 8) & 7;
- return 0;
-}
-
-static int ac97_fp_rec_volume_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- u16 oldreg, newreg;
- int change;
-
- mutex_lock(&chip->mutex);
- oldreg = oxygen_read_ac97(chip, 1, AC97_REC_GAIN);
- newreg = oldreg & ~0x0707;
- newreg = newreg | (value->value.integer.value[0] & 7);
- newreg = newreg | ((value->value.integer.value[0] & 7) << 8);
- change = newreg != oldreg;
- if (change)
- oxygen_write_ac97(chip, 1, AC97_REC_GAIN, newreg);
- mutex_unlock(&chip->mutex);
- return change;
-}
-
-#define AC97_SWITCH(xname, codec, index, bitnr, invert) { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .info = snd_ctl_boolean_mono_info, \
- .get = ac97_switch_get, \
- .put = ac97_switch_put, \
- .private_value = ((codec) << 24) | ((invert) << 16) | \
- ((bitnr) << 8) | (index), \
- }
-#define AC97_VOLUME(xname, codec, index, stereo) { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
- SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .info = ac97_volume_info, \
- .get = ac97_volume_get, \
- .put = ac97_volume_put, \
- .tlv = { .p = ac97_db_scale, }, \
- .private_value = ((codec) << 24) | ((stereo) << 16) | (index), \
- }
-
-static DECLARE_TLV_DB_SCALE(monitor_db_scale, -600, 600, 0);
-static DECLARE_TLV_DB_SCALE(ac97_db_scale, -3450, 150, 0);
-static DECLARE_TLV_DB_SCALE(ac97_rec_db_scale, 0, 150, 0);
-
-static const struct snd_kcontrol_new controls[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = dac_volume_info,
- .get = dac_volume_get,
- .put = dac_volume_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = dac_mute_get,
- .put = dac_mute_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Stereo Upmixing",
- .info = upmix_info,
- .get = upmix_get,
- .put = upmix_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
- .info = snd_ctl_boolean_mono_info,
- .get = spdif_switch_get,
- .put = spdif_switch_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .device = 1,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
- .info = spdif_info,
- .get = spdif_default_get,
- .put = spdif_default_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .device = 1,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .info = spdif_info,
- .get = spdif_mask_get,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .device = 1,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM),
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .info = spdif_info,
- .get = spdif_pcm_get,
- .put = spdif_pcm_put,
- },
-};
-
-static const struct snd_kcontrol_new spdif_input_controls[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .device = 1,
- .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .info = spdif_info,
- .get = spdif_input_mask_get,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .device = 1,
- .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .info = spdif_info,
- .get = spdif_input_default_get,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("Loopback ", NONE, SWITCH),
- .info = snd_ctl_boolean_mono_info,
- .get = spdif_bit_switch_get,
- .put = spdif_bit_switch_put,
- .private_value = OXYGEN_SPDIF_LOOPBACK,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("Validity Check ",CAPTURE,SWITCH),
- .info = snd_ctl_boolean_mono_info,
- .get = spdif_bit_switch_get,
- .put = spdif_bit_switch_put,
- .private_value = OXYGEN_SPDIF_SPDVALID,
- },
-};
-
-static const struct {
- unsigned int pcm_dev;
- struct snd_kcontrol_new controls[2];
-} monitor_controls[] = {
- {
- .pcm_dev = CAPTURE_0_FROM_I2S_1,
- .controls = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Input Monitor Playback Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = monitor_get,
- .put = monitor_put,
- .private_value = OXYGEN_ADC_MONITOR_A,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Input Monitor Playback Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = monitor_volume_info,
- .get = monitor_get,
- .put = monitor_put,
- .private_value = OXYGEN_ADC_MONITOR_A_HALF_VOL
- | (1 << 8),
- .tlv = { .p = monitor_db_scale, },
- },
- },
- },
- {
- .pcm_dev = CAPTURE_0_FROM_I2S_2,
- .controls = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Input Monitor Playback Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = monitor_get,
- .put = monitor_put,
- .private_value = OXYGEN_ADC_MONITOR_B,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Input Monitor Playback Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = monitor_volume_info,
- .get = monitor_get,
- .put = monitor_put,
- .private_value = OXYGEN_ADC_MONITOR_B_HALF_VOL
- | (1 << 8),
- .tlv = { .p = monitor_db_scale, },
- },
- },
- },
- {
- .pcm_dev = CAPTURE_2_FROM_I2S_2,
- .controls = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Input Monitor Playback Switch",
- .index = 1,
- .info = snd_ctl_boolean_mono_info,
- .get = monitor_get,
- .put = monitor_put,
- .private_value = OXYGEN_ADC_MONITOR_B,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Input Monitor Playback Volume",
- .index = 1,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = monitor_volume_info,
- .get = monitor_get,
- .put = monitor_put,
- .private_value = OXYGEN_ADC_MONITOR_B_HALF_VOL
- | (1 << 8),
- .tlv = { .p = monitor_db_scale, },
- },
- },
- },
- {
- .pcm_dev = CAPTURE_1_FROM_SPDIF,
- .controls = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Digital Input Monitor Playback Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = monitor_get,
- .put = monitor_put,
- .private_value = OXYGEN_ADC_MONITOR_C,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Digital Input Monitor Playback Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = monitor_volume_info,
- .get = monitor_get,
- .put = monitor_put,
- .private_value = OXYGEN_ADC_MONITOR_C_HALF_VOL
- | (1 << 8),
- .tlv = { .p = monitor_db_scale, },
- },
- },
- },
-};
-
-static const struct snd_kcontrol_new ac97_controls[] = {
- AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0),
- AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1),
- AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Mic Source Capture Enum",
- .info = mic_fmic_source_info,
- .get = mic_fmic_source_get,
- .put = mic_fmic_source_put,
- },
- AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1),
- AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1),
- AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1),
- AC97_VOLUME("Aux Capture Volume", 0, AC97_AUX, 1),
- AC97_SWITCH("Aux Capture Switch", 0, AC97_AUX, 15, 1),
-};
-
-static const struct snd_kcontrol_new ac97_fp_controls[] = {
- AC97_VOLUME("Front Panel Playback Volume", 1, AC97_HEADPHONE, 1),
- AC97_SWITCH("Front Panel Playback Switch", 1, AC97_HEADPHONE, 15, 1),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Front Panel Capture Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = ac97_fp_rec_volume_info,
- .get = ac97_fp_rec_volume_get,
- .put = ac97_fp_rec_volume_put,
- .tlv = { .p = ac97_rec_db_scale, },
- },
- AC97_SWITCH("Front Panel Capture Switch", 1, AC97_REC_GAIN, 15, 1),
-};
-
-static void oxygen_any_ctl_free(struct snd_kcontrol *ctl)
-{
- struct oxygen *chip = ctl->private_data;
- unsigned int i;
-
- /* I'm too lazy to write a function for each control :-) */
- for (i = 0; i < ARRAY_SIZE(chip->controls); ++i)
- chip->controls[i] = NULL;
-}
-
-static int add_controls(struct oxygen *chip,
- const struct snd_kcontrol_new controls[],
- unsigned int count)
-{
- static const char *const known_ctl_names[CONTROL_COUNT] = {
- [CONTROL_SPDIF_PCM] =
- SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM),
- [CONTROL_SPDIF_INPUT_BITS] =
- SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
- [CONTROL_MIC_CAPTURE_SWITCH] = "Mic Capture Switch",
- [CONTROL_LINE_CAPTURE_SWITCH] = "Line Capture Switch",
- [CONTROL_CD_CAPTURE_SWITCH] = "CD Capture Switch",
- [CONTROL_AUX_CAPTURE_SWITCH] = "Aux Capture Switch",
- };
- unsigned int i, j;
- struct snd_kcontrol_new template;
- struct snd_kcontrol *ctl;
- int err;
-
- for (i = 0; i < count; ++i) {
- template = controls[i];
- if (chip->model.control_filter) {
- err = chip->model.control_filter(&template);
- if (err < 0)
- return err;
- if (err == 1)
- continue;
- }
- if (!strcmp(template.name, "Stereo Upmixing") &&
- chip->model.dac_channels_pcm == 2)
- continue;
- if (!strcmp(template.name, "Mic Source Capture Enum") &&
- !(chip->model.device_config & AC97_FMIC_SWITCH))
- continue;
- if (!strncmp(template.name, "CD Capture ", 11) &&
- !(chip->model.device_config & AC97_CD_INPUT))
- continue;
- if (!strcmp(template.name, "Master Playback Volume") &&
- chip->model.dac_tlv) {
- template.tlv.p = chip->model.dac_tlv;
- template.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
- }
- ctl = snd_ctl_new1(&template, chip);
- if (!ctl)
- return -ENOMEM;
- err = snd_ctl_add(chip->card, ctl);
- if (err < 0)
- return err;
- for (j = 0; j < CONTROL_COUNT; ++j)
- if (!strcmp(ctl->id.name, known_ctl_names[j])) {
- chip->controls[j] = ctl;
- ctl->private_free = oxygen_any_ctl_free;
- }
- }
- return 0;
-}
-
-int oxygen_mixer_init(struct oxygen *chip)
-{
- unsigned int i;
- int err;
-
- err = add_controls(chip, controls, ARRAY_SIZE(controls));
- if (err < 0)
- return err;
- if (chip->model.device_config & CAPTURE_1_FROM_SPDIF) {
- err = add_controls(chip, spdif_input_controls,
- ARRAY_SIZE(spdif_input_controls));
- if (err < 0)
- return err;
- }
- for (i = 0; i < ARRAY_SIZE(monitor_controls); ++i) {
- if (!(chip->model.device_config & monitor_controls[i].pcm_dev))
- continue;
- err = add_controls(chip, monitor_controls[i].controls,
- ARRAY_SIZE(monitor_controls[i].controls));
- if (err < 0)
- return err;
- }
- if (chip->has_ac97_0) {
- err = add_controls(chip, ac97_controls,
- ARRAY_SIZE(ac97_controls));
- if (err < 0)
- return err;
- }
- if (chip->has_ac97_1) {
- err = add_controls(chip, ac97_fp_controls,
- ARRAY_SIZE(ac97_fp_controls));
- if (err < 0)
- return err;
- }
- return chip->model.mixer_init ? chip->model.mixer_init(chip) : 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/oxygen_pcm.c b/ANDROID_3.4.5/sound/pci/oxygen/oxygen_pcm.c
deleted file mode 100644
index cc0bcd9f..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/oxygen_pcm.c
+++ /dev/null
@@ -1,766 +0,0 @@
-/*
- * C-Media CMI8788 driver - PCM code
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- *
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this driver; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/pci.h>
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include "oxygen.h"
-
-/* most DMA channels have a 16-bit counter for 32-bit words */
-#define BUFFER_BYTES_MAX ((1 << 16) * 4)
-/* the multichannel DMA channel has a 24-bit counter */
-#define BUFFER_BYTES_MAX_MULTICH ((1 << 24) * 4)
-
-#define PERIOD_BYTES_MIN 64
-
-#define DEFAULT_BUFFER_BYTES (BUFFER_BYTES_MAX / 2)
-#define DEFAULT_BUFFER_BYTES_MULTICH (1024 * 1024)
-
-static const struct snd_pcm_hardware oxygen_stereo_hardware = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START |
- SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
- .formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- .rates = SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_64000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000 |
- SNDRV_PCM_RATE_176400 |
- SNDRV_PCM_RATE_192000,
- .rate_min = 32000,
- .rate_max = 192000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = BUFFER_BYTES_MAX,
- .period_bytes_min = PERIOD_BYTES_MIN,
- .period_bytes_max = BUFFER_BYTES_MAX,
- .periods_min = 1,
- .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
-};
-static const struct snd_pcm_hardware oxygen_multichannel_hardware = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START |
- SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
- .formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- .rates = SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_64000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000 |
- SNDRV_PCM_RATE_176400 |
- SNDRV_PCM_RATE_192000,
- .rate_min = 32000,
- .rate_max = 192000,
- .channels_min = 2,
- .channels_max = 8,
- .buffer_bytes_max = BUFFER_BYTES_MAX_MULTICH,
- .period_bytes_min = PERIOD_BYTES_MIN,
- .period_bytes_max = BUFFER_BYTES_MAX_MULTICH,
- .periods_min = 1,
- .periods_max = BUFFER_BYTES_MAX_MULTICH / PERIOD_BYTES_MIN,
-};
-static const struct snd_pcm_hardware oxygen_ac97_hardware = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START |
- SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = BUFFER_BYTES_MAX,
- .period_bytes_min = PERIOD_BYTES_MIN,
- .period_bytes_max = BUFFER_BYTES_MAX,
- .periods_min = 1,
- .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
-};
-
-static const struct snd_pcm_hardware *const oxygen_hardware[PCM_COUNT] = {
- [PCM_A] = &oxygen_stereo_hardware,
- [PCM_B] = &oxygen_stereo_hardware,
- [PCM_C] = &oxygen_stereo_hardware,
- [PCM_SPDIF] = &oxygen_stereo_hardware,
- [PCM_MULTICH] = &oxygen_multichannel_hardware,
- [PCM_AC97] = &oxygen_ac97_hardware,
-};
-
-static inline unsigned int
-oxygen_substream_channel(struct snd_pcm_substream *substream)
-{
- return (unsigned int)(uintptr_t)substream->runtime->private_data;
-}
-
-static int oxygen_open(struct snd_pcm_substream *substream,
- unsigned int channel)
-{
- struct oxygen *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- runtime->private_data = (void *)(uintptr_t)channel;
- if (channel == PCM_B && chip->has_ac97_1 &&
- (chip->model.device_config & CAPTURE_2_FROM_AC97_1))
- runtime->hw = oxygen_ac97_hardware;
- else
- runtime->hw = *oxygen_hardware[channel];
- switch (channel) {
- case PCM_C:
- runtime->hw.rates &= ~(SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_64000);
- runtime->hw.rate_min = 44100;
- break;
- case PCM_MULTICH:
- runtime->hw.channels_max = chip->model.dac_channels_pcm;
- break;
- }
- if (chip->model.pcm_hardware_filter)
- chip->model.pcm_hardware_filter(channel, &runtime->hw);
- err = snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
- if (err < 0)
- return err;
- err = snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
- if (err < 0)
- return err;
- if (runtime->hw.formats & SNDRV_PCM_FMTBIT_S32_LE) {
- err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
- if (err < 0)
- return err;
- }
- if (runtime->hw.channels_max > 2) {
- err = snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- 2);
- if (err < 0)
- return err;
- }
- snd_pcm_set_sync(substream);
- chip->streams[channel] = substream;
-
- mutex_lock(&chip->mutex);
- chip->pcm_active |= 1 << channel;
- if (channel == PCM_SPDIF) {
- chip->spdif_pcm_bits = chip->spdif_bits;
- chip->controls[CONTROL_SPDIF_PCM]->vd[0].access &=
- ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO,
- &chip->controls[CONTROL_SPDIF_PCM]->id);
- }
- mutex_unlock(&chip->mutex);
-
- return 0;
-}
-
-static int oxygen_rec_a_open(struct snd_pcm_substream *substream)
-{
- return oxygen_open(substream, PCM_A);
-}
-
-static int oxygen_rec_b_open(struct snd_pcm_substream *substream)
-{
- return oxygen_open(substream, PCM_B);
-}
-
-static int oxygen_rec_c_open(struct snd_pcm_substream *substream)
-{
- return oxygen_open(substream, PCM_C);
-}
-
-static int oxygen_spdif_open(struct snd_pcm_substream *substream)
-{
- return oxygen_open(substream, PCM_SPDIF);
-}
-
-static int oxygen_multich_open(struct snd_pcm_substream *substream)
-{
- return oxygen_open(substream, PCM_MULTICH);
-}
-
-static int oxygen_ac97_open(struct snd_pcm_substream *substream)
-{
- return oxygen_open(substream, PCM_AC97);
-}
-
-static int oxygen_close(struct snd_pcm_substream *substream)
-{
- struct oxygen *chip = snd_pcm_substream_chip(substream);
- unsigned int channel = oxygen_substream_channel(substream);
-
- mutex_lock(&chip->mutex);
- chip->pcm_active &= ~(1 << channel);
- if (channel == PCM_SPDIF) {
- chip->controls[CONTROL_SPDIF_PCM]->vd[0].access |=
- SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO,
- &chip->controls[CONTROL_SPDIF_PCM]->id);
- }
- if (channel == PCM_SPDIF || channel == PCM_MULTICH)
- oxygen_update_spdif_source(chip);
- mutex_unlock(&chip->mutex);
-
- chip->streams[channel] = NULL;
- return 0;
-}
-
-static unsigned int oxygen_format(struct snd_pcm_hw_params *hw_params)
-{
- if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE)
- return OXYGEN_FORMAT_24;
- else
- return OXYGEN_FORMAT_16;
-}
-
-static unsigned int oxygen_rate(struct snd_pcm_hw_params *hw_params)
-{
- switch (params_rate(hw_params)) {
- case 32000:
- return OXYGEN_RATE_32000;
- case 44100:
- return OXYGEN_RATE_44100;
- default: /* 48000 */
- return OXYGEN_RATE_48000;
- case 64000:
- return OXYGEN_RATE_64000;
- case 88200:
- return OXYGEN_RATE_88200;
- case 96000:
- return OXYGEN_RATE_96000;
- case 176400:
- return OXYGEN_RATE_176400;
- case 192000:
- return OXYGEN_RATE_192000;
- }
-}
-
-static unsigned int oxygen_i2s_bits(struct snd_pcm_hw_params *hw_params)
-{
- if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE)
- return OXYGEN_I2S_BITS_24;
- else
- return OXYGEN_I2S_BITS_16;
-}
-
-static unsigned int oxygen_play_channels(struct snd_pcm_hw_params *hw_params)
-{
- switch (params_channels(hw_params)) {
- default: /* 2 */
- return OXYGEN_PLAY_CHANNELS_2;
- case 4:
- return OXYGEN_PLAY_CHANNELS_4;
- case 6:
- return OXYGEN_PLAY_CHANNELS_6;
- case 8:
- return OXYGEN_PLAY_CHANNELS_8;
- }
-}
-
-static const unsigned int channel_base_registers[PCM_COUNT] = {
- [PCM_A] = OXYGEN_DMA_A_ADDRESS,
- [PCM_B] = OXYGEN_DMA_B_ADDRESS,
- [PCM_C] = OXYGEN_DMA_C_ADDRESS,
- [PCM_SPDIF] = OXYGEN_DMA_SPDIF_ADDRESS,
- [PCM_MULTICH] = OXYGEN_DMA_MULTICH_ADDRESS,
- [PCM_AC97] = OXYGEN_DMA_AC97_ADDRESS,
-};
-
-static int oxygen_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct oxygen *chip = snd_pcm_substream_chip(substream);
- unsigned int channel = oxygen_substream_channel(substream);
- int err;
-
- err = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
-
- oxygen_write32(chip, channel_base_registers[channel],
- (u32)substream->runtime->dma_addr);
- if (channel == PCM_MULTICH) {
- oxygen_write32(chip, OXYGEN_DMA_MULTICH_COUNT,
- params_buffer_bytes(hw_params) / 4 - 1);
- oxygen_write32(chip, OXYGEN_DMA_MULTICH_TCOUNT,
- params_period_bytes(hw_params) / 4 - 1);
- } else {
- oxygen_write16(chip, channel_base_registers[channel] + 4,
- params_buffer_bytes(hw_params) / 4 - 1);
- oxygen_write16(chip, channel_base_registers[channel] + 6,
- params_period_bytes(hw_params) / 4 - 1);
- }
- return 0;
-}
-
-static u16 get_mclk(struct oxygen *chip, unsigned int channel,
- struct snd_pcm_hw_params *params)
-{
- unsigned int mclks, shift;
-
- if (channel == PCM_MULTICH)
- mclks = chip->model.dac_mclks;
- else
- mclks = chip->model.adc_mclks;
-
- if (params_rate(params) <= 48000)
- shift = 0;
- else if (params_rate(params) <= 96000)
- shift = 2;
- else
- shift = 4;
-
- return OXYGEN_I2S_MCLK(mclks >> shift);
-}
-
-static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct oxygen *chip = snd_pcm_substream_chip(substream);
- int err;
-
- err = oxygen_hw_params(substream, hw_params);
- if (err < 0)
- return err;
-
- spin_lock_irq(&chip->reg_lock);
- oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
- oxygen_format(hw_params) << OXYGEN_REC_FORMAT_A_SHIFT,
- OXYGEN_REC_FORMAT_A_MASK);
- oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT,
- oxygen_rate(hw_params) |
- chip->model.adc_i2s_format |
- get_mclk(chip, PCM_A, hw_params) |
- oxygen_i2s_bits(hw_params),
- OXYGEN_I2S_RATE_MASK |
- OXYGEN_I2S_FORMAT_MASK |
- OXYGEN_I2S_MCLK_MASK |
- OXYGEN_I2S_BITS_MASK);
- spin_unlock_irq(&chip->reg_lock);
-
- mutex_lock(&chip->mutex);
- chip->model.set_adc_params(chip, hw_params);
- mutex_unlock(&chip->mutex);
- return 0;
-}
-
-static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct oxygen *chip = snd_pcm_substream_chip(substream);
- int is_ac97;
- int err;
-
- err = oxygen_hw_params(substream, hw_params);
- if (err < 0)
- return err;
-
- is_ac97 = chip->has_ac97_1 &&
- (chip->model.device_config & CAPTURE_2_FROM_AC97_1);
-
- spin_lock_irq(&chip->reg_lock);
- oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
- oxygen_format(hw_params) << OXYGEN_REC_FORMAT_B_SHIFT,
- OXYGEN_REC_FORMAT_B_MASK);
- if (!is_ac97)
- oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT,
- oxygen_rate(hw_params) |
- chip->model.adc_i2s_format |
- get_mclk(chip, PCM_B, hw_params) |
- oxygen_i2s_bits(hw_params),
- OXYGEN_I2S_RATE_MASK |
- OXYGEN_I2S_FORMAT_MASK |
- OXYGEN_I2S_MCLK_MASK |
- OXYGEN_I2S_BITS_MASK);
- spin_unlock_irq(&chip->reg_lock);
-
- if (!is_ac97) {
- mutex_lock(&chip->mutex);
- chip->model.set_adc_params(chip, hw_params);
- mutex_unlock(&chip->mutex);
- }
- return 0;
-}
-
-static int oxygen_rec_c_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct oxygen *chip = snd_pcm_substream_chip(substream);
- int err;
-
- err = oxygen_hw_params(substream, hw_params);
- if (err < 0)
- return err;
-
- spin_lock_irq(&chip->reg_lock);
- oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
- oxygen_format(hw_params) << OXYGEN_REC_FORMAT_C_SHIFT,
- OXYGEN_REC_FORMAT_C_MASK);
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static int oxygen_spdif_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct oxygen *chip = snd_pcm_substream_chip(substream);
- int err;
-
- err = oxygen_hw_params(substream, hw_params);
- if (err < 0)
- return err;
-
- mutex_lock(&chip->mutex);
- spin_lock_irq(&chip->reg_lock);
- oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
- OXYGEN_SPDIF_OUT_ENABLE);
- oxygen_write8_masked(chip, OXYGEN_PLAY_FORMAT,
- oxygen_format(hw_params) << OXYGEN_SPDIF_FORMAT_SHIFT,
- OXYGEN_SPDIF_FORMAT_MASK);
- oxygen_write32_masked(chip, OXYGEN_SPDIF_CONTROL,
- oxygen_rate(hw_params) << OXYGEN_SPDIF_OUT_RATE_SHIFT,
- OXYGEN_SPDIF_OUT_RATE_MASK);
- oxygen_update_spdif_source(chip);
- spin_unlock_irq(&chip->reg_lock);
- mutex_unlock(&chip->mutex);
- return 0;
-}
-
-static int oxygen_multich_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct oxygen *chip = snd_pcm_substream_chip(substream);
- int err;
-
- err = oxygen_hw_params(substream, hw_params);
- if (err < 0)
- return err;
-
- mutex_lock(&chip->mutex);
- spin_lock_irq(&chip->reg_lock);
- oxygen_write8_masked(chip, OXYGEN_PLAY_CHANNELS,
- oxygen_play_channels(hw_params),
- OXYGEN_PLAY_CHANNELS_MASK);
- oxygen_write8_masked(chip, OXYGEN_PLAY_FORMAT,
- oxygen_format(hw_params) << OXYGEN_MULTICH_FORMAT_SHIFT,
- OXYGEN_MULTICH_FORMAT_MASK);
- oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
- oxygen_rate(hw_params) |
- chip->model.dac_i2s_format |
- get_mclk(chip, PCM_MULTICH, hw_params) |
- oxygen_i2s_bits(hw_params),
- OXYGEN_I2S_RATE_MASK |
- OXYGEN_I2S_FORMAT_MASK |
- OXYGEN_I2S_MCLK_MASK |
- OXYGEN_I2S_BITS_MASK);
- oxygen_update_spdif_source(chip);
- spin_unlock_irq(&chip->reg_lock);
-
- chip->model.set_dac_params(chip, hw_params);
- oxygen_update_dac_routing(chip);
- mutex_unlock(&chip->mutex);
- return 0;
-}
-
-static int oxygen_hw_free(struct snd_pcm_substream *substream)
-{
- struct oxygen *chip = snd_pcm_substream_chip(substream);
- unsigned int channel = oxygen_substream_channel(substream);
- unsigned int channel_mask = 1 << channel;
-
- spin_lock_irq(&chip->reg_lock);
- chip->interrupt_mask &= ~channel_mask;
- oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
-
- oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
- oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
- spin_unlock_irq(&chip->reg_lock);
-
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int oxygen_spdif_hw_free(struct snd_pcm_substream *substream)
-{
- struct oxygen *chip = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&chip->reg_lock);
- oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
- OXYGEN_SPDIF_OUT_ENABLE);
- spin_unlock_irq(&chip->reg_lock);
- return oxygen_hw_free(substream);
-}
-
-static int oxygen_prepare(struct snd_pcm_substream *substream)
-{
- struct oxygen *chip = snd_pcm_substream_chip(substream);
- unsigned int channel = oxygen_substream_channel(substream);
- unsigned int channel_mask = 1 << channel;
-
- spin_lock_irq(&chip->reg_lock);
- oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
- oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
-
- if (substream->runtime->no_period_wakeup)
- chip->interrupt_mask &= ~channel_mask;
- else
- chip->interrupt_mask |= channel_mask;
- oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static int oxygen_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct oxygen *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_substream *s;
- unsigned int mask = 0;
- int pausing;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- pausing = 0;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- pausing = 1;
- break;
- default:
- return -EINVAL;
- }
-
- snd_pcm_group_for_each_entry(s, substream) {
- if (snd_pcm_substream_chip(s) == chip) {
- mask |= 1 << oxygen_substream_channel(s);
- snd_pcm_trigger_done(s, substream);
- }
- }
-
- spin_lock(&chip->reg_lock);
- if (!pausing) {
- if (cmd == SNDRV_PCM_TRIGGER_START)
- chip->pcm_running |= mask;
- else
- chip->pcm_running &= ~mask;
- oxygen_write8(chip, OXYGEN_DMA_STATUS, chip->pcm_running);
- } else {
- if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
- oxygen_set_bits8(chip, OXYGEN_DMA_PAUSE, mask);
- else
- oxygen_clear_bits8(chip, OXYGEN_DMA_PAUSE, mask);
- }
- spin_unlock(&chip->reg_lock);
- return 0;
-}
-
-static snd_pcm_uframes_t oxygen_pointer(struct snd_pcm_substream *substream)
-{
- struct oxygen *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int channel = oxygen_substream_channel(substream);
- u32 curr_addr;
-
- /* no spinlock, this read should be atomic */
- curr_addr = oxygen_read32(chip, channel_base_registers[channel]);
- return bytes_to_frames(runtime, curr_addr - (u32)runtime->dma_addr);
-}
-
-static struct snd_pcm_ops oxygen_rec_a_ops = {
- .open = oxygen_rec_a_open,
- .close = oxygen_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = oxygen_rec_a_hw_params,
- .hw_free = oxygen_hw_free,
- .prepare = oxygen_prepare,
- .trigger = oxygen_trigger,
- .pointer = oxygen_pointer,
-};
-
-static struct snd_pcm_ops oxygen_rec_b_ops = {
- .open = oxygen_rec_b_open,
- .close = oxygen_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = oxygen_rec_b_hw_params,
- .hw_free = oxygen_hw_free,
- .prepare = oxygen_prepare,
- .trigger = oxygen_trigger,
- .pointer = oxygen_pointer,
-};
-
-static struct snd_pcm_ops oxygen_rec_c_ops = {
- .open = oxygen_rec_c_open,
- .close = oxygen_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = oxygen_rec_c_hw_params,
- .hw_free = oxygen_hw_free,
- .prepare = oxygen_prepare,
- .trigger = oxygen_trigger,
- .pointer = oxygen_pointer,
-};
-
-static struct snd_pcm_ops oxygen_spdif_ops = {
- .open = oxygen_spdif_open,
- .close = oxygen_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = oxygen_spdif_hw_params,
- .hw_free = oxygen_spdif_hw_free,
- .prepare = oxygen_prepare,
- .trigger = oxygen_trigger,
- .pointer = oxygen_pointer,
-};
-
-static struct snd_pcm_ops oxygen_multich_ops = {
- .open = oxygen_multich_open,
- .close = oxygen_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = oxygen_multich_hw_params,
- .hw_free = oxygen_hw_free,
- .prepare = oxygen_prepare,
- .trigger = oxygen_trigger,
- .pointer = oxygen_pointer,
-};
-
-static struct snd_pcm_ops oxygen_ac97_ops = {
- .open = oxygen_ac97_open,
- .close = oxygen_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = oxygen_hw_params,
- .hw_free = oxygen_hw_free,
- .prepare = oxygen_prepare,
- .trigger = oxygen_trigger,
- .pointer = oxygen_pointer,
-};
-
-static void oxygen_pcm_free(struct snd_pcm *pcm)
-{
- snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-int oxygen_pcm_init(struct oxygen *chip)
-{
- struct snd_pcm *pcm;
- int outs, ins;
- int err;
-
- outs = !!(chip->model.device_config & PLAYBACK_0_TO_I2S);
- ins = !!(chip->model.device_config & (CAPTURE_0_FROM_I2S_1 |
- CAPTURE_0_FROM_I2S_2));
- if (outs | ins) {
- err = snd_pcm_new(chip->card, "Multichannel",
- 0, outs, ins, &pcm);
- if (err < 0)
- return err;
- if (outs)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &oxygen_multich_ops);
- if (chip->model.device_config & CAPTURE_0_FROM_I2S_1)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &oxygen_rec_a_ops);
- else if (chip->model.device_config & CAPTURE_0_FROM_I2S_2)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &oxygen_rec_b_ops);
- pcm->private_data = chip;
- pcm->private_free = oxygen_pcm_free;
- strcpy(pcm->name, "Multichannel");
- if (outs)
- snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
- SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- DEFAULT_BUFFER_BYTES_MULTICH,
- BUFFER_BYTES_MAX_MULTICH);
- if (ins)
- snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
- SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- DEFAULT_BUFFER_BYTES,
- BUFFER_BYTES_MAX);
- }
-
- outs = !!(chip->model.device_config & PLAYBACK_1_TO_SPDIF);
- ins = !!(chip->model.device_config & CAPTURE_1_FROM_SPDIF);
- if (outs | ins) {
- err = snd_pcm_new(chip->card, "Digital", 1, outs, ins, &pcm);
- if (err < 0)
- return err;
- if (outs)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &oxygen_spdif_ops);
- if (ins)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &oxygen_rec_c_ops);
- pcm->private_data = chip;
- pcm->private_free = oxygen_pcm_free;
- strcpy(pcm->name, "Digital");
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- DEFAULT_BUFFER_BYTES,
- BUFFER_BYTES_MAX);
- }
-
- if (chip->has_ac97_1) {
- outs = !!(chip->model.device_config & PLAYBACK_2_TO_AC97_1);
- ins = !!(chip->model.device_config & CAPTURE_2_FROM_AC97_1);
- } else {
- outs = 0;
- ins = !!(chip->model.device_config & CAPTURE_2_FROM_I2S_2);
- }
- if (outs | ins) {
- err = snd_pcm_new(chip->card, outs ? "AC97" : "Analog2",
- 2, outs, ins, &pcm);
- if (err < 0)
- return err;
- if (outs) {
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &oxygen_ac97_ops);
- oxygen_write8_masked(chip, OXYGEN_REC_ROUTING,
- OXYGEN_REC_B_ROUTE_AC97_1,
- OXYGEN_REC_B_ROUTE_MASK);
- }
- if (ins)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &oxygen_rec_b_ops);
- pcm->private_data = chip;
- pcm->private_free = oxygen_pcm_free;
- strcpy(pcm->name, outs ? "Front Panel" : "Analog 2");
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- DEFAULT_BUFFER_BYTES,
- BUFFER_BYTES_MAX);
- }
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/oxygen_regs.h b/ANDROID_3.4.5/sound/pci/oxygen/oxygen_regs.h
deleted file mode 100644
index 63dc7a0a..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/oxygen_regs.h
+++ /dev/null
@@ -1,457 +0,0 @@
-#ifndef OXYGEN_REGS_H_INCLUDED
-#define OXYGEN_REGS_H_INCLUDED
-
-/* recording channel A */
-#define OXYGEN_DMA_A_ADDRESS 0x00 /* 32-bit base address */
-#define OXYGEN_DMA_A_COUNT 0x04 /* buffer counter (dwords) */
-#define OXYGEN_DMA_A_TCOUNT 0x06 /* interrupt counter (dwords) */
-
-/* recording channel B */
-#define OXYGEN_DMA_B_ADDRESS 0x08
-#define OXYGEN_DMA_B_COUNT 0x0c
-#define OXYGEN_DMA_B_TCOUNT 0x0e
-
-/* recording channel C */
-#define OXYGEN_DMA_C_ADDRESS 0x10
-#define OXYGEN_DMA_C_COUNT 0x14
-#define OXYGEN_DMA_C_TCOUNT 0x16
-
-/* SPDIF playback channel */
-#define OXYGEN_DMA_SPDIF_ADDRESS 0x18
-#define OXYGEN_DMA_SPDIF_COUNT 0x1c
-#define OXYGEN_DMA_SPDIF_TCOUNT 0x1e
-
-/* multichannel playback channel */
-#define OXYGEN_DMA_MULTICH_ADDRESS 0x20
-#define OXYGEN_DMA_MULTICH_COUNT 0x24 /* 24 bits */
-#define OXYGEN_DMA_MULTICH_TCOUNT 0x28 /* 24 bits */
-
-/* AC'97 (front panel) playback channel */
-#define OXYGEN_DMA_AC97_ADDRESS 0x30
-#define OXYGEN_DMA_AC97_COUNT 0x34
-#define OXYGEN_DMA_AC97_TCOUNT 0x36
-
-/* all registers 0x00..0x36 return current position on read */
-
-#define OXYGEN_DMA_STATUS 0x40 /* 1 = running, 0 = stop */
-#define OXYGEN_CHANNEL_A 0x01
-#define OXYGEN_CHANNEL_B 0x02
-#define OXYGEN_CHANNEL_C 0x04
-#define OXYGEN_CHANNEL_SPDIF 0x08
-#define OXYGEN_CHANNEL_MULTICH 0x10
-#define OXYGEN_CHANNEL_AC97 0x20
-
-#define OXYGEN_DMA_PAUSE 0x41 /* 1 = pause */
-/* OXYGEN_CHANNEL_* */
-
-#define OXYGEN_DMA_RESET 0x42
-/* OXYGEN_CHANNEL_* */
-
-#define OXYGEN_PLAY_CHANNELS 0x43
-#define OXYGEN_PLAY_CHANNELS_MASK 0x03
-#define OXYGEN_PLAY_CHANNELS_2 0x00
-#define OXYGEN_PLAY_CHANNELS_4 0x01
-#define OXYGEN_PLAY_CHANNELS_6 0x02
-#define OXYGEN_PLAY_CHANNELS_8 0x03
-#define OXYGEN_DMA_A_BURST_MASK 0x04
-#define OXYGEN_DMA_A_BURST_8 0x00 /* dwords */
-#define OXYGEN_DMA_A_BURST_16 0x04
-#define OXYGEN_DMA_MULTICH_BURST_MASK 0x08
-#define OXYGEN_DMA_MULTICH_BURST_8 0x00
-#define OXYGEN_DMA_MULTICH_BURST_16 0x08
-
-#define OXYGEN_INTERRUPT_MASK 0x44
-/* OXYGEN_CHANNEL_* */
-#define OXYGEN_INT_SPDIF_IN_DETECT 0x0100
-#define OXYGEN_INT_MCU 0x0200
-#define OXYGEN_INT_2WIRE 0x0400
-#define OXYGEN_INT_GPIO 0x0800
-#define OXYGEN_INT_MCB 0x2000
-#define OXYGEN_INT_AC97 0x4000
-
-#define OXYGEN_INTERRUPT_STATUS 0x46
-/* OXYGEN_CHANNEL_* amd OXYGEN_INT_* */
-#define OXYGEN_INT_MIDI 0x1000
-
-#define OXYGEN_MISC 0x48
-#define OXYGEN_MISC_WRITE_PCI_SUBID 0x01
-#define OXYGEN_MISC_LATENCY_3F 0x02
-#define OXYGEN_MISC_REC_C_FROM_SPDIF 0x04
-#define OXYGEN_MISC_REC_B_FROM_AC97 0x08
-#define OXYGEN_MISC_REC_A_FROM_MULTICH 0x10
-#define OXYGEN_MISC_PCI_MEM_W_1_CLOCK 0x20
-#define OXYGEN_MISC_MIDI 0x40
-#define OXYGEN_MISC_CRYSTAL_MASK 0x80
-#define OXYGEN_MISC_CRYSTAL_24576 0x00
-#define OXYGEN_MISC_CRYSTAL_27 0x80 /* MHz */
-
-#define OXYGEN_REC_FORMAT 0x4a
-#define OXYGEN_REC_FORMAT_A_MASK 0x03
-#define OXYGEN_REC_FORMAT_A_SHIFT 0
-#define OXYGEN_REC_FORMAT_B_MASK 0x0c
-#define OXYGEN_REC_FORMAT_B_SHIFT 2
-#define OXYGEN_REC_FORMAT_C_MASK 0x30
-#define OXYGEN_REC_FORMAT_C_SHIFT 4
-#define OXYGEN_FORMAT_16 0x00
-#define OXYGEN_FORMAT_24 0x01
-#define OXYGEN_FORMAT_32 0x02
-
-#define OXYGEN_PLAY_FORMAT 0x4b
-#define OXYGEN_SPDIF_FORMAT_MASK 0x03
-#define OXYGEN_SPDIF_FORMAT_SHIFT 0
-#define OXYGEN_MULTICH_FORMAT_MASK 0x0c
-#define OXYGEN_MULTICH_FORMAT_SHIFT 2
-/* OXYGEN_FORMAT_* */
-
-#define OXYGEN_REC_CHANNELS 0x4c
-#define OXYGEN_REC_CHANNELS_MASK 0x07
-#define OXYGEN_REC_CHANNELS_2_2_2 0x00 /* DMA A, B, C */
-#define OXYGEN_REC_CHANNELS_4_2_2 0x01
-#define OXYGEN_REC_CHANNELS_6_0_2 0x02
-#define OXYGEN_REC_CHANNELS_6_2_0 0x03
-#define OXYGEN_REC_CHANNELS_8_0_0 0x04
-
-#define OXYGEN_FUNCTION 0x50
-#define OXYGEN_FUNCTION_CLOCK_MASK 0x01
-#define OXYGEN_FUNCTION_CLOCK_PLL 0x00
-#define OXYGEN_FUNCTION_CLOCK_CRYSTAL 0x01
-#define OXYGEN_FUNCTION_RESET_CODEC 0x02
-#define OXYGEN_FUNCTION_RESET_POL 0x04
-#define OXYGEN_FUNCTION_PWDN 0x08
-#define OXYGEN_FUNCTION_PWDN_EN 0x10
-#define OXYGEN_FUNCTION_PWDN_POL 0x20
-#define OXYGEN_FUNCTION_2WIRE_SPI_MASK 0x40
-#define OXYGEN_FUNCTION_SPI 0x00
-#define OXYGEN_FUNCTION_2WIRE 0x40
-#define OXYGEN_FUNCTION_ENABLE_SPI_4_5 0x80 /* 0 = EEPROM */
-
-#define OXYGEN_I2S_MULTICH_FORMAT 0x60
-#define OXYGEN_I2S_RATE_MASK 0x0007 /* LRCK */
-#define OXYGEN_RATE_32000 0x0000
-#define OXYGEN_RATE_44100 0x0001
-#define OXYGEN_RATE_48000 0x0002
-#define OXYGEN_RATE_64000 0x0003
-#define OXYGEN_RATE_88200 0x0004
-#define OXYGEN_RATE_96000 0x0005
-#define OXYGEN_RATE_176400 0x0006
-#define OXYGEN_RATE_192000 0x0007
-#define OXYGEN_I2S_FORMAT_MASK 0x0008
-#define OXYGEN_I2S_FORMAT_I2S 0x0000
-#define OXYGEN_I2S_FORMAT_LJUST 0x0008
-#define OXYGEN_I2S_MCLK_MASK 0x0030 /* MCLK/LRCK */
-#define OXYGEN_I2S_MCLK_SHIFT 4
-#define MCLK_128 0
-#define MCLK_256 1
-#define MCLK_512 2
-#define OXYGEN_I2S_MCLK(f) (((f) & 3) << OXYGEN_I2S_MCLK_SHIFT)
-#define OXYGEN_I2S_BITS_MASK 0x00c0
-#define OXYGEN_I2S_BITS_16 0x0000
-#define OXYGEN_I2S_BITS_20 0x0040
-#define OXYGEN_I2S_BITS_24 0x0080
-#define OXYGEN_I2S_BITS_32 0x00c0
-#define OXYGEN_I2S_MASTER 0x0100
-#define OXYGEN_I2S_BCLK_MASK 0x0600 /* BCLK/LRCK */
-#define OXYGEN_I2S_BCLK_64 0x0000
-#define OXYGEN_I2S_BCLK_128 0x0200
-#define OXYGEN_I2S_BCLK_256 0x0400
-#define OXYGEN_I2S_MUTE_MCLK 0x0800
-
-#define OXYGEN_I2S_A_FORMAT 0x62
-#define OXYGEN_I2S_B_FORMAT 0x64
-#define OXYGEN_I2S_C_FORMAT 0x66
-/* like OXYGEN_I2S_MULTICH_FORMAT */
-
-#define OXYGEN_SPDIF_CONTROL 0x70
-#define OXYGEN_SPDIF_OUT_ENABLE 0x00000002
-#define OXYGEN_SPDIF_LOOPBACK 0x00000004 /* in to out */
-#define OXYGEN_SPDIF_SENSE_MASK 0x00000008
-#define OXYGEN_SPDIF_LOCK_MASK 0x00000010
-#define OXYGEN_SPDIF_RATE_MASK 0x00000020
-#define OXYGEN_SPDIF_SPDVALID 0x00000040
-#define OXYGEN_SPDIF_SENSE_PAR 0x00000200
-#define OXYGEN_SPDIF_LOCK_PAR 0x00000400
-#define OXYGEN_SPDIF_SENSE_STATUS 0x00000800
-#define OXYGEN_SPDIF_LOCK_STATUS 0x00001000
-#define OXYGEN_SPDIF_SENSE_INT 0x00002000 /* r/wc */
-#define OXYGEN_SPDIF_LOCK_INT 0x00004000 /* r/wc */
-#define OXYGEN_SPDIF_RATE_INT 0x00008000 /* r/wc */
-#define OXYGEN_SPDIF_IN_CLOCK_MASK 0x00010000
-#define OXYGEN_SPDIF_IN_CLOCK_96 0x00000000 /* <= 96 kHz */
-#define OXYGEN_SPDIF_IN_CLOCK_192 0x00010000 /* > 96 kHz */
-#define OXYGEN_SPDIF_OUT_RATE_MASK 0x07000000
-#define OXYGEN_SPDIF_OUT_RATE_SHIFT 24
-/* OXYGEN_RATE_* << OXYGEN_SPDIF_OUT_RATE_SHIFT */
-
-#define OXYGEN_SPDIF_OUTPUT_BITS 0x74
-#define OXYGEN_SPDIF_NONAUDIO 0x00000002
-#define OXYGEN_SPDIF_C 0x00000004
-#define OXYGEN_SPDIF_PREEMPHASIS 0x00000008
-#define OXYGEN_SPDIF_CATEGORY_MASK 0x000007f0
-#define OXYGEN_SPDIF_CATEGORY_SHIFT 4
-#define OXYGEN_SPDIF_ORIGINAL 0x00000800
-#define OXYGEN_SPDIF_CS_RATE_MASK 0x0000f000
-#define OXYGEN_SPDIF_CS_RATE_SHIFT 12
-#define OXYGEN_SPDIF_V 0x00010000 /* 0 = valid */
-
-#define OXYGEN_SPDIF_INPUT_BITS 0x78
-/* 32 bits, IEC958_AES_* */
-
-#define OXYGEN_EEPROM_CONTROL 0x80
-#define OXYGEN_EEPROM_ADDRESS_MASK 0x7f
-#define OXYGEN_EEPROM_DIR_MASK 0x80
-#define OXYGEN_EEPROM_DIR_READ 0x00
-#define OXYGEN_EEPROM_DIR_WRITE 0x80
-
-#define OXYGEN_EEPROM_STATUS 0x81
-#define OXYGEN_EEPROM_VALID 0x40
-#define OXYGEN_EEPROM_BUSY 0x80
-
-#define OXYGEN_EEPROM_DATA 0x82 /* 16 bits */
-
-#define OXYGEN_2WIRE_CONTROL 0x90
-#define OXYGEN_2WIRE_DIR_MASK 0x01
-#define OXYGEN_2WIRE_DIR_WRITE 0x00
-#define OXYGEN_2WIRE_DIR_READ 0x01
-#define OXYGEN_2WIRE_ADDRESS_MASK 0xfe /* slave device address */
-#define OXYGEN_2WIRE_ADDRESS_SHIFT 1
-
-#define OXYGEN_2WIRE_MAP 0x91 /* address, 8 bits */
-#define OXYGEN_2WIRE_DATA 0x92 /* data, 16 bits */
-
-#define OXYGEN_2WIRE_BUS_STATUS 0x94
-#define OXYGEN_2WIRE_BUSY 0x0001
-#define OXYGEN_2WIRE_LENGTH_MASK 0x0002
-#define OXYGEN_2WIRE_LENGTH_8 0x0000
-#define OXYGEN_2WIRE_LENGTH_16 0x0002
-#define OXYGEN_2WIRE_MANUAL_READ 0x0004 /* 0 = auto read */
-#define OXYGEN_2WIRE_WRITE_MAP_ONLY 0x0008
-#define OXYGEN_2WIRE_SLAVE_AD_MASK 0x0030 /* AD0, AD1 */
-#define OXYGEN_2WIRE_INTERRUPT_MASK 0x0040 /* 0 = int. if not responding */
-#define OXYGEN_2WIRE_SLAVE_NO_RESPONSE 0x0080
-#define OXYGEN_2WIRE_SPEED_MASK 0x0100
-#define OXYGEN_2WIRE_SPEED_STANDARD 0x0000
-#define OXYGEN_2WIRE_SPEED_FAST 0x0100
-#define OXYGEN_2WIRE_CLOCK_SYNC 0x0200
-#define OXYGEN_2WIRE_BUS_RESET 0x0400
-
-#define OXYGEN_SPI_CONTROL 0x98
-#define OXYGEN_SPI_BUSY 0x01 /* read */
-#define OXYGEN_SPI_TRIGGER 0x01 /* write */
-#define OXYGEN_SPI_DATA_LENGTH_MASK 0x02
-#define OXYGEN_SPI_DATA_LENGTH_2 0x00
-#define OXYGEN_SPI_DATA_LENGTH_3 0x02
-#define OXYGEN_SPI_CLOCK_MASK 0x0c
-#define OXYGEN_SPI_CLOCK_160 0x00 /* ns */
-#define OXYGEN_SPI_CLOCK_320 0x04
-#define OXYGEN_SPI_CLOCK_640 0x08
-#define OXYGEN_SPI_CLOCK_1280 0x0c
-#define OXYGEN_SPI_CODEC_MASK 0x70 /* 0..5 */
-#define OXYGEN_SPI_CODEC_SHIFT 4
-#define OXYGEN_SPI_CEN_MASK 0x80
-#define OXYGEN_SPI_CEN_LATCH_CLOCK_LO 0x00
-#define OXYGEN_SPI_CEN_LATCH_CLOCK_HI 0x80
-
-#define OXYGEN_SPI_DATA1 0x99
-#define OXYGEN_SPI_DATA2 0x9a
-#define OXYGEN_SPI_DATA3 0x9b
-
-#define OXYGEN_MPU401 0xa0
-
-#define OXYGEN_MPU401_CONTROL 0xa2
-#define OXYGEN_MPU401_LOOPBACK 0x01 /* TXD to RXD */
-
-#define OXYGEN_GPI_DATA 0xa4
-/* bits 0..5 = pin XGPI0..XGPI5 */
-
-#define OXYGEN_GPI_INTERRUPT_MASK 0xa5
-/* bits 0..5, 1 = enable */
-
-#define OXYGEN_GPIO_DATA 0xa6
-/* bits 0..9 */
-
-#define OXYGEN_GPIO_CONTROL 0xa8
-/* bits 0..9, 0 = input, 1 = output */
-#define OXYGEN_GPIO1_XSLAVE_RDY 0x8000
-
-#define OXYGEN_GPIO_INTERRUPT_MASK 0xaa
-/* bits 0..9, 1 = enable */
-
-#define OXYGEN_DEVICE_SENSE 0xac
-#define OXYGEN_HEAD_PHONE_DETECT 0x01
-#define OXYGEN_HEAD_PHONE_MASK 0x06
-#define OXYGEN_HEAD_PHONE_PASSIVE_SPK 0x00
-#define OXYGEN_HEAD_PHONE_HP 0x02
-#define OXYGEN_HEAD_PHONE_ACTIVE_SPK 0x04
-
-#define OXYGEN_MCU_2WIRE_DATA 0xb0
-
-#define OXYGEN_MCU_2WIRE_MAP 0xb2
-
-#define OXYGEN_MCU_2WIRE_STATUS 0xb3
-#define OXYGEN_MCU_2WIRE_BUSY 0x01
-#define OXYGEN_MCU_2WIRE_LENGTH_MASK 0x06
-#define OXYGEN_MCU_2WIRE_LENGTH_1 0x00
-#define OXYGEN_MCU_2WIRE_LENGTH_2 0x02
-#define OXYGEN_MCU_2WIRE_LENGTH_3 0x04
-#define OXYGEN_MCU_2WIRE_WRITE 0x08 /* r/wc */
-#define OXYGEN_MCU_2WIRE_READ 0x10 /* r/wc */
-#define OXYGEN_MCU_2WIRE_DRV_XACT_FAIL 0x20 /* r/wc */
-#define OXYGEN_MCU_2WIRE_RESET 0x40
-
-#define OXYGEN_MCU_2WIRE_CONTROL 0xb4
-#define OXYGEN_MCU_2WIRE_DRV_ACK 0x01
-#define OXYGEN_MCU_2WIRE_DRV_XACT 0x02
-#define OXYGEN_MCU_2WIRE_INT_MASK 0x04
-#define OXYGEN_MCU_2WIRE_SYNC_MASK 0x08
-#define OXYGEN_MCU_2WIRE_SYNC_RDY_PIN 0x00
-#define OXYGEN_MCU_2WIRE_SYNC_DATA 0x08
-#define OXYGEN_MCU_2WIRE_ADDRESS_MASK 0x30
-#define OXYGEN_MCU_2WIRE_ADDRESS_10 0x00
-#define OXYGEN_MCU_2WIRE_ADDRESS_12 0x10
-#define OXYGEN_MCU_2WIRE_ADDRESS_14 0x20
-#define OXYGEN_MCU_2WIRE_ADDRESS_16 0x30
-#define OXYGEN_MCU_2WIRE_INT_POL 0x40
-#define OXYGEN_MCU_2WIRE_SYNC_ENABLE 0x80
-
-#define OXYGEN_PLAY_ROUTING 0xc0
-#define OXYGEN_PLAY_MUTE01 0x0001
-#define OXYGEN_PLAY_MUTE23 0x0002
-#define OXYGEN_PLAY_MUTE45 0x0004
-#define OXYGEN_PLAY_MUTE67 0x0008
-#define OXYGEN_PLAY_MULTICH_MASK 0x0010
-#define OXYGEN_PLAY_MULTICH_I2S_DAC 0x0000
-#define OXYGEN_PLAY_MULTICH_AC97 0x0010
-#define OXYGEN_PLAY_SPDIF_MASK 0x00e0
-#define OXYGEN_PLAY_SPDIF_SPDIF 0x0000
-#define OXYGEN_PLAY_SPDIF_MULTICH_01 0x0020
-#define OXYGEN_PLAY_SPDIF_MULTICH_23 0x0040
-#define OXYGEN_PLAY_SPDIF_MULTICH_45 0x0060
-#define OXYGEN_PLAY_SPDIF_MULTICH_67 0x0080
-#define OXYGEN_PLAY_SPDIF_REC_A 0x00a0
-#define OXYGEN_PLAY_SPDIF_REC_B 0x00c0
-#define OXYGEN_PLAY_SPDIF_I2S_ADC_3 0x00e0
-#define OXYGEN_PLAY_DAC0_SOURCE_MASK 0x0300
-#define OXYGEN_PLAY_DAC0_SOURCE_SHIFT 8
-#define OXYGEN_PLAY_DAC1_SOURCE_MASK 0x0c00
-#define OXYGEN_PLAY_DAC1_SOURCE_SHIFT 10
-#define OXYGEN_PLAY_DAC2_SOURCE_MASK 0x3000
-#define OXYGEN_PLAY_DAC2_SOURCE_SHIFT 12
-#define OXYGEN_PLAY_DAC3_SOURCE_MASK 0xc000
-#define OXYGEN_PLAY_DAC3_SOURCE_SHIFT 14
-
-#define OXYGEN_REC_ROUTING 0xc2
-#define OXYGEN_MUTE_I2S_ADC_1 0x01
-#define OXYGEN_MUTE_I2S_ADC_2 0x02
-#define OXYGEN_MUTE_I2S_ADC_3 0x04
-#define OXYGEN_REC_A_ROUTE_MASK 0x08
-#define OXYGEN_REC_A_ROUTE_I2S_ADC_1 0x00
-#define OXYGEN_REC_A_ROUTE_AC97_0 0x08
-#define OXYGEN_REC_B_ROUTE_MASK 0x10
-#define OXYGEN_REC_B_ROUTE_I2S_ADC_2 0x00
-#define OXYGEN_REC_B_ROUTE_AC97_1 0x10
-#define OXYGEN_REC_C_ROUTE_MASK 0x20
-#define OXYGEN_REC_C_ROUTE_SPDIF 0x00
-#define OXYGEN_REC_C_ROUTE_I2S_ADC_3 0x20
-
-#define OXYGEN_ADC_MONITOR 0xc3
-#define OXYGEN_ADC_MONITOR_A 0x01
-#define OXYGEN_ADC_MONITOR_A_HALF_VOL 0x02
-#define OXYGEN_ADC_MONITOR_B 0x04
-#define OXYGEN_ADC_MONITOR_B_HALF_VOL 0x08
-#define OXYGEN_ADC_MONITOR_C 0x10
-#define OXYGEN_ADC_MONITOR_C_HALF_VOL 0x20
-
-#define OXYGEN_A_MONITOR_ROUTING 0xc4
-#define OXYGEN_A_MONITOR_ROUTE_0_MASK 0x03
-#define OXYGEN_A_MONITOR_ROUTE_0_SHIFT 0
-#define OXYGEN_A_MONITOR_ROUTE_1_MASK 0x0c
-#define OXYGEN_A_MONITOR_ROUTE_1_SHIFT 2
-#define OXYGEN_A_MONITOR_ROUTE_2_MASK 0x30
-#define OXYGEN_A_MONITOR_ROUTE_2_SHIFT 4
-#define OXYGEN_A_MONITOR_ROUTE_3_MASK 0xc0
-#define OXYGEN_A_MONITOR_ROUTE_3_SHIFT 6
-
-#define OXYGEN_AC97_CONTROL 0xd0
-#define OXYGEN_AC97_COLD_RESET 0x0001
-#define OXYGEN_AC97_SUSPENDED 0x0002 /* read */
-#define OXYGEN_AC97_RESUME 0x0002 /* write */
-#define OXYGEN_AC97_CLOCK_DISABLE 0x0004
-#define OXYGEN_AC97_NO_CODEC_0 0x0008
-#define OXYGEN_AC97_CODEC_0 0x0010
-#define OXYGEN_AC97_CODEC_1 0x0020
-
-#define OXYGEN_AC97_INTERRUPT_MASK 0xd2
-#define OXYGEN_AC97_INT_READ_DONE 0x01
-#define OXYGEN_AC97_INT_WRITE_DONE 0x02
-#define OXYGEN_AC97_INT_CODEC_0 0x10
-#define OXYGEN_AC97_INT_CODEC_1 0x20
-
-#define OXYGEN_AC97_INTERRUPT_STATUS 0xd3
-/* OXYGEN_AC97_INT_* */
-
-#define OXYGEN_AC97_OUT_CONFIG 0xd4
-#define OXYGEN_AC97_CODEC1_SLOT3 0x00000001
-#define OXYGEN_AC97_CODEC1_SLOT3_VSR 0x00000002
-#define OXYGEN_AC97_CODEC1_SLOT4 0x00000010
-#define OXYGEN_AC97_CODEC1_SLOT4_VSR 0x00000020
-#define OXYGEN_AC97_CODEC0_FRONTL 0x00000100
-#define OXYGEN_AC97_CODEC0_FRONTR 0x00000200
-#define OXYGEN_AC97_CODEC0_SIDEL 0x00000400
-#define OXYGEN_AC97_CODEC0_SIDER 0x00000800
-#define OXYGEN_AC97_CODEC0_CENTER 0x00001000
-#define OXYGEN_AC97_CODEC0_BASE 0x00002000
-#define OXYGEN_AC97_CODEC0_REARL 0x00004000
-#define OXYGEN_AC97_CODEC0_REARR 0x00008000
-
-#define OXYGEN_AC97_IN_CONFIG 0xd8
-#define OXYGEN_AC97_CODEC1_LINEL 0x00000001
-#define OXYGEN_AC97_CODEC1_LINEL_VSR 0x00000002
-#define OXYGEN_AC97_CODEC1_LINEL_16 0x00000000
-#define OXYGEN_AC97_CODEC1_LINEL_18 0x00000004
-#define OXYGEN_AC97_CODEC1_LINEL_20 0x00000008
-#define OXYGEN_AC97_CODEC1_LINER 0x00000010
-#define OXYGEN_AC97_CODEC1_LINER_VSR 0x00000020
-#define OXYGEN_AC97_CODEC1_LINER_16 0x00000000
-#define OXYGEN_AC97_CODEC1_LINER_18 0x00000040
-#define OXYGEN_AC97_CODEC1_LINER_20 0x00000080
-#define OXYGEN_AC97_CODEC0_LINEL 0x00000100
-#define OXYGEN_AC97_CODEC0_LINER 0x00000200
-
-#define OXYGEN_AC97_REGS 0xdc
-#define OXYGEN_AC97_REG_DATA_MASK 0x0000ffff
-#define OXYGEN_AC97_REG_ADDR_MASK 0x007f0000
-#define OXYGEN_AC97_REG_ADDR_SHIFT 16
-#define OXYGEN_AC97_REG_DIR_MASK 0x00800000
-#define OXYGEN_AC97_REG_DIR_WRITE 0x00000000
-#define OXYGEN_AC97_REG_DIR_READ 0x00800000
-#define OXYGEN_AC97_REG_CODEC_MASK 0x01000000
-#define OXYGEN_AC97_REG_CODEC_SHIFT 24
-
-#define OXYGEN_TEST 0xe0
-#define OXYGEN_TEST_RAM_SUCCEEDED 0x01
-#define OXYGEN_TEST_PLAYBACK_RAM 0x02
-#define OXYGEN_TEST_RECORD_RAM 0x04
-#define OXYGEN_TEST_PLL 0x08
-#define OXYGEN_TEST_2WIRE_LOOPBACK 0x10
-
-#define OXYGEN_DMA_FLUSH 0xe1
-/* OXYGEN_CHANNEL_* */
-
-#define OXYGEN_CODEC_VERSION 0xe4
-#define OXYGEN_CODEC_ID_MASK 0x07
-
-#define OXYGEN_REVISION 0xe6
-#define OXYGEN_PACKAGE_ID_MASK 0x0007
-#define OXYGEN_PACKAGE_ID_8786 0x0004
-#define OXYGEN_PACKAGE_ID_8787 0x0006
-#define OXYGEN_PACKAGE_ID_8788 0x0007
-#define OXYGEN_REVISION_MASK 0xfff8
-#define OXYGEN_REVISION_2 0x0008
-
-#define OXYGEN_OFFSIN_48K 0xe8
-#define OXYGEN_OFFSBASE_48K 0xe9
-#define OXYGEN_OFFSBASE_MASK 0x0fff
-#define OXYGEN_OFFSIN_44K 0xec
-#define OXYGEN_OFFSBASE_44K 0xed
-
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/pcm1796.h b/ANDROID_3.4.5/sound/pci/oxygen/pcm1796.h
deleted file mode 100644
index 698bf46c..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/pcm1796.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef PCM1796_H_INCLUDED
-#define PCM1796_H_INCLUDED
-
-/* register 16 */
-#define PCM1796_ATL_MASK 0xff
-/* register 17 */
-#define PCM1796_ATR_MASK 0xff
-/* register 18 */
-#define PCM1796_MUTE 0x01
-#define PCM1796_DME 0x02
-#define PCM1796_DMF_MASK 0x0c
-#define PCM1796_DMF_DISABLED 0x00
-#define PCM1796_DMF_48 0x04
-#define PCM1796_DMF_441 0x08
-#define PCM1796_DMF_32 0x0c
-#define PCM1796_FMT_MASK 0x70
-#define PCM1796_FMT_16_RJUST 0x00
-#define PCM1796_FMT_20_RJUST 0x10
-#define PCM1796_FMT_24_RJUST 0x20
-#define PCM1796_FMT_24_LJUST 0x30
-#define PCM1796_FMT_16_I2S 0x40
-#define PCM1796_FMT_24_I2S 0x50
-#define PCM1796_ATLD 0x80
-/* register 19 */
-#define PCM1796_INZD 0x01
-#define PCM1796_FLT_MASK 0x02
-#define PCM1796_FLT_SHARP 0x00
-#define PCM1796_FLT_SLOW 0x02
-#define PCM1796_DFMS 0x04
-#define PCM1796_OPE 0x10
-#define PCM1796_ATS_MASK 0x60
-#define PCM1796_ATS_1 0x00
-#define PCM1796_ATS_2 0x20
-#define PCM1796_ATS_4 0x40
-#define PCM1796_ATS_8 0x60
-#define PCM1796_REV 0x80
-/* register 20 */
-#define PCM1796_OS_MASK 0x03
-#define PCM1796_OS_64 0x00
-#define PCM1796_OS_32 0x01
-#define PCM1796_OS_128 0x02
-#define PCM1796_CHSL_MASK 0x04
-#define PCM1796_CHSL_LEFT 0x00
-#define PCM1796_CHSL_RIGHT 0x04
-#define PCM1796_MONO 0x08
-#define PCM1796_DFTH 0x10
-#define PCM1796_DSD 0x20
-#define PCM1796_SRST 0x40
-/* register 21 */
-#define PCM1796_PCMZ 0x01
-#define PCM1796_DZ_MASK 0x06
-/* register 22 */
-#define PCM1796_ZFGL 0x01
-#define PCM1796_ZFGR 0x02
-/* register 23 */
-#define PCM1796_ID_MASK 0x1f
-
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/virtuoso.c b/ANDROID_3.4.5/sound/pci/oxygen/virtuoso.c
deleted file mode 100644
index 3fdee495..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/virtuoso.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * C-Media CMI8788 driver for Asus Xonar cards
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- *
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this driver; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include "xonar.h"
-
-MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
-MODULE_DESCRIPTION("Asus Virtuoso driver");
-MODULE_LICENSE("GPL v2");
-MODULE_SUPPORTED_DEVICE("{{Asus,AV66},{Asus,AV100},{Asus,AV200}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "card index");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "enable card");
-
-static DEFINE_PCI_DEVICE_TABLE(xonar_ids) = {
- { OXYGEN_PCI_SUBID(0x1043, 0x8269) },
- { OXYGEN_PCI_SUBID(0x1043, 0x8275) },
- { OXYGEN_PCI_SUBID(0x1043, 0x82b7) },
- { OXYGEN_PCI_SUBID(0x1043, 0x8314) },
- { OXYGEN_PCI_SUBID(0x1043, 0x8327) },
- { OXYGEN_PCI_SUBID(0x1043, 0x834f) },
- { OXYGEN_PCI_SUBID(0x1043, 0x835c) },
- { OXYGEN_PCI_SUBID(0x1043, 0x835d) },
- { OXYGEN_PCI_SUBID(0x1043, 0x835e) },
- { OXYGEN_PCI_SUBID(0x1043, 0x838e) },
- { OXYGEN_PCI_SUBID_BROKEN_EEPROM },
- { }
-};
-MODULE_DEVICE_TABLE(pci, xonar_ids);
-
-static int __devinit get_xonar_model(struct oxygen *chip,
- const struct pci_device_id *id)
-{
- if (get_xonar_pcm179x_model(chip, id) >= 0)
- return 0;
- if (get_xonar_cs43xx_model(chip, id) >= 0)
- return 0;
- if (get_xonar_wm87x6_model(chip, id) >= 0)
- return 0;
- return -EINVAL;
-}
-
-static int __devinit xonar_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- ++dev;
- return -ENOENT;
- }
- err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE,
- xonar_ids, get_xonar_model);
- if (err >= 0)
- ++dev;
- return err;
-}
-
-static struct pci_driver xonar_driver = {
- .name = KBUILD_MODNAME,
- .id_table = xonar_ids,
- .probe = xonar_probe,
- .remove = __devexit_p(oxygen_pci_remove),
-#ifdef CONFIG_PM
- .suspend = oxygen_pci_suspend,
- .resume = oxygen_pci_resume,
-#endif
- .shutdown = oxygen_pci_shutdown,
-};
-
-static int __init alsa_card_xonar_init(void)
-{
- return pci_register_driver(&xonar_driver);
-}
-
-static void __exit alsa_card_xonar_exit(void)
-{
- pci_unregister_driver(&xonar_driver);
-}
-
-module_init(alsa_card_xonar_init)
-module_exit(alsa_card_xonar_exit)
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/wm8766.h b/ANDROID_3.4.5/sound/pci/oxygen/wm8766.h
deleted file mode 100644
index e0e849a7..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/wm8766.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef WM8766_H_INCLUDED
-#define WM8766_H_INCLUDED
-
-#define WM8766_LDA1 0x00
-#define WM8766_RDA1 0x01
-#define WM8766_DAC_CTRL 0x02
-#define WM8766_INT_CTRL 0x03
-#define WM8766_LDA2 0x04
-#define WM8766_RDA2 0x05
-#define WM8766_LDA3 0x06
-#define WM8766_RDA3 0x07
-#define WM8766_MASTDA 0x08
-#define WM8766_DAC_CTRL2 0x09
-#define WM8766_DAC_CTRL3 0x0a
-#define WM8766_MUTE1 0x0c
-#define WM8766_MUTE2 0x0f
-#define WM8766_RESET 0x1f
-
-/* LDAx/RDAx/MASTDA */
-#define WM8766_ATT_MASK 0x0ff
-#define WM8766_UPDATE 0x100
-/* DAC_CTRL */
-#define WM8766_MUTEALL 0x001
-#define WM8766_DEEMPALL 0x002
-#define WM8766_PWDN 0x004
-#define WM8766_ATC 0x008
-#define WM8766_IZD 0x010
-#define WM8766_PL_LEFT_MASK 0x060
-#define WM8766_PL_LEFT_MUTE 0x000
-#define WM8766_PL_LEFT_LEFT 0x020
-#define WM8766_PL_LEFT_RIGHT 0x040
-#define WM8766_PL_LEFT_LRMIX 0x060
-#define WM8766_PL_RIGHT_MASK 0x180
-#define WM8766_PL_RIGHT_MUTE 0x000
-#define WM8766_PL_RIGHT_LEFT 0x080
-#define WM8766_PL_RIGHT_RIGHT 0x100
-#define WM8766_PL_RIGHT_LRMIX 0x180
-/* INT_CTRL */
-#define WM8766_FMT_MASK 0x003
-#define WM8766_FMT_RJUST 0x000
-#define WM8766_FMT_LJUST 0x001
-#define WM8766_FMT_I2S 0x002
-#define WM8766_FMT_DSP 0x003
-#define WM8766_LRP 0x004
-#define WM8766_BCP 0x008
-#define WM8766_IWL_MASK 0x030
-#define WM8766_IWL_16 0x000
-#define WM8766_IWL_20 0x010
-#define WM8766_IWL_24 0x020
-#define WM8766_IWL_32 0x030
-#define WM8766_PHASE_MASK 0x1c0
-/* DAC_CTRL2 */
-#define WM8766_ZCD 0x001
-#define WM8766_DZFM_MASK 0x006
-#define WM8766_DMUTE_MASK 0x038
-#define WM8766_DEEMP_MASK 0x1c0
-/* DAC_CTRL3 */
-#define WM8766_DACPD_MASK 0x00e
-#define WM8766_PWRDNALL 0x010
-#define WM8766_MS 0x020
-#define WM8766_RATE_MASK 0x1c0
-#define WM8766_RATE_128 0x000
-#define WM8766_RATE_192 0x040
-#define WM8766_RATE_256 0x080
-#define WM8766_RATE_384 0x0c0
-#define WM8766_RATE_512 0x100
-#define WM8766_RATE_768 0x140
-/* MUTE1 */
-#define WM8766_MPD1 0x040
-/* MUTE2 */
-#define WM8766_MPD2 0x020
-
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/wm8776.h b/ANDROID_3.4.5/sound/pci/oxygen/wm8776.h
deleted file mode 100644
index 1a96f561..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/wm8776.h
+++ /dev/null
@@ -1,177 +0,0 @@
-#ifndef WM8776_H_INCLUDED
-#define WM8776_H_INCLUDED
-
-/*
- * the following register names are from:
- * wm8776.h -- WM8776 ASoC driver
- *
- * Copyright 2009 Wolfson Microelectronics plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#define WM8776_HPLVOL 0x00
-#define WM8776_HPRVOL 0x01
-#define WM8776_HPMASTER 0x02
-#define WM8776_DACLVOL 0x03
-#define WM8776_DACRVOL 0x04
-#define WM8776_DACMASTER 0x05
-#define WM8776_PHASESWAP 0x06
-#define WM8776_DACCTRL1 0x07
-#define WM8776_DACMUTE 0x08
-#define WM8776_DACCTRL2 0x09
-#define WM8776_DACIFCTRL 0x0a
-#define WM8776_ADCIFCTRL 0x0b
-#define WM8776_MSTRCTRL 0x0c
-#define WM8776_PWRDOWN 0x0d
-#define WM8776_ADCLVOL 0x0e
-#define WM8776_ADCRVOL 0x0f
-#define WM8776_ALCCTRL1 0x10
-#define WM8776_ALCCTRL2 0x11
-#define WM8776_ALCCTRL3 0x12
-#define WM8776_NOISEGATE 0x13
-#define WM8776_LIMITER 0x14
-#define WM8776_ADCMUX 0x15
-#define WM8776_OUTMUX 0x16
-#define WM8776_RESET 0x17
-
-
-/* HPLVOL/HPRVOL/HPMASTER */
-#define WM8776_HPATT_MASK 0x07f
-#define WM8776_HPZCEN 0x080
-#define WM8776_UPDATE 0x100
-
-/* DACLVOL/DACRVOL/DACMASTER */
-#define WM8776_DATT_MASK 0x0ff
-/*#define WM8776_UPDATE 0x100*/
-
-/* PHASESWAP */
-#define WM8776_PH_MASK 0x003
-
-/* DACCTRL1 */
-#define WM8776_DZCEN 0x001
-#define WM8776_ATC 0x002
-#define WM8776_IZD 0x004
-#define WM8776_TOD 0x008
-#define WM8776_PL_LEFT_MASK 0x030
-#define WM8776_PL_LEFT_MUTE 0x000
-#define WM8776_PL_LEFT_LEFT 0x010
-#define WM8776_PL_LEFT_RIGHT 0x020
-#define WM8776_PL_LEFT_LRMIX 0x030
-#define WM8776_PL_RIGHT_MASK 0x0c0
-#define WM8776_PL_RIGHT_MUTE 0x000
-#define WM8776_PL_RIGHT_LEFT 0x040
-#define WM8776_PL_RIGHT_RIGHT 0x080
-#define WM8776_PL_RIGHT_LRMIX 0x0c0
-
-/* DACMUTE */
-#define WM8776_DMUTE 0x001
-
-/* DACCTRL2 */
-#define WM8776_DEEMPH 0x001
-#define WM8776_DZFM_MASK 0x006
-#define WM8776_DZFM_NONE 0x000
-#define WM8776_DZFM_LR 0x002
-#define WM8776_DZFM_BOTH 0x004
-#define WM8776_DZFM_EITHER 0x006
-
-/* DACIFCTRL */
-#define WM8776_DACFMT_MASK 0x003
-#define WM8776_DACFMT_RJUST 0x000
-#define WM8776_DACFMT_LJUST 0x001
-#define WM8776_DACFMT_I2S 0x002
-#define WM8776_DACFMT_DSP 0x003
-#define WM8776_DACLRP 0x004
-#define WM8776_DACBCP 0x008
-#define WM8776_DACWL_MASK 0x030
-#define WM8776_DACWL_16 0x000
-#define WM8776_DACWL_20 0x010
-#define WM8776_DACWL_24 0x020
-#define WM8776_DACWL_32 0x030
-
-/* ADCIFCTRL */
-#define WM8776_ADCFMT_MASK 0x003
-#define WM8776_ADCFMT_RJUST 0x000
-#define WM8776_ADCFMT_LJUST 0x001
-#define WM8776_ADCFMT_I2S 0x002
-#define WM8776_ADCFMT_DSP 0x003
-#define WM8776_ADCLRP 0x004
-#define WM8776_ADCBCP 0x008
-#define WM8776_ADCWL_MASK 0x030
-#define WM8776_ADCWL_16 0x000
-#define WM8776_ADCWL_20 0x010
-#define WM8776_ADCWL_24 0x020
-#define WM8776_ADCWL_32 0x030
-#define WM8776_ADCMCLK 0x040
-#define WM8776_ADCHPD 0x100
-
-/* MSTRCTRL */
-#define WM8776_ADCRATE_MASK 0x007
-#define WM8776_ADCRATE_256 0x002
-#define WM8776_ADCRATE_384 0x003
-#define WM8776_ADCRATE_512 0x004
-#define WM8776_ADCRATE_768 0x005
-#define WM8776_ADCOSR 0x008
-#define WM8776_DACRATE_MASK 0x070
-#define WM8776_DACRATE_128 0x000
-#define WM8776_DACRATE_192 0x010
-#define WM8776_DACRATE_256 0x020
-#define WM8776_DACRATE_384 0x030
-#define WM8776_DACRATE_512 0x040
-#define WM8776_DACRATE_768 0x050
-#define WM8776_DACMS 0x080
-#define WM8776_ADCMS 0x100
-
-/* PWRDOWN */
-#define WM8776_PDWN 0x001
-#define WM8776_ADCPD 0x002
-#define WM8776_DACPD 0x004
-#define WM8776_HPPD 0x008
-#define WM8776_AINPD 0x040
-
-/* ADCLVOL/ADCRVOL */
-#define WM8776_AGMASK 0x0ff
-#define WM8776_ZCA 0x100
-
-/* ALCCTRL1 */
-#define WM8776_LCT_MASK 0x00f
-#define WM8776_MAXGAIN_MASK 0x070
-#define WM8776_LCSEL_MASK 0x180
-#define WM8776_LCSEL_LIMITER 0x000
-#define WM8776_LCSEL_ALC_RIGHT 0x080
-#define WM8776_LCSEL_ALC_LEFT 0x100
-#define WM8776_LCSEL_ALC_STEREO 0x180
-
-/* ALCCTRL2 */
-#define WM8776_HLD_MASK 0x00f
-#define WM8776_ALCZC 0x080
-#define WM8776_LCEN 0x100
-
-/* ALCCTRL3 */
-#define WM8776_ATK_MASK 0x00f
-#define WM8776_DCY_MASK 0x0f0
-
-/* NOISEGATE */
-#define WM8776_NGAT 0x001
-#define WM8776_NGTH_MASK 0x01c
-
-/* LIMITER */
-#define WM8776_MAXATTEN_MASK 0x00f
-#define WM8776_TRANWIN_MASK 0x070
-
-/* ADCMUX */
-#define WM8776_AMX_MASK 0x01f
-#define WM8776_MUTERA 0x040
-#define WM8776_MUTELA 0x080
-#define WM8776_LRBOTH 0x100
-
-/* OUTMUX */
-#define WM8776_MX_DAC 0x001
-#define WM8776_MX_AUX 0x002
-#define WM8776_MX_BYPASS 0x004
-
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/wm8785.h b/ANDROID_3.4.5/sound/pci/oxygen/wm8785.h
deleted file mode 100644
index 8c23e315..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/wm8785.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef WM8785_H_INCLUDED
-#define WM8785_H_INCLUDED
-
-#define WM8785_R0 0
-#define WM8785_R1 1
-#define WM8785_R2 2
-#define WM8785_R7 7
-
-/* R0 */
-#define WM8785_MCR_MASK 0x007
-#define WM8785_MCR_SLAVE 0x000
-#define WM8785_MCR_MASTER_128 0x001
-#define WM8785_MCR_MASTER_192 0x002
-#define WM8785_MCR_MASTER_256 0x003
-#define WM8785_MCR_MASTER_384 0x004
-#define WM8785_MCR_MASTER_512 0x005
-#define WM8785_MCR_MASTER_768 0x006
-#define WM8785_OSR_MASK 0x018
-#define WM8785_OSR_SINGLE 0x000
-#define WM8785_OSR_DOUBLE 0x008
-#define WM8785_OSR_QUAD 0x010
-#define WM8785_FORMAT_MASK 0x060
-#define WM8785_FORMAT_RJUST 0x000
-#define WM8785_FORMAT_LJUST 0x020
-#define WM8785_FORMAT_I2S 0x040
-#define WM8785_FORMAT_DSP 0x060
-/* R1 */
-#define WM8785_WL_MASK 0x003
-#define WM8785_WL_16 0x000
-#define WM8785_WL_20 0x001
-#define WM8785_WL_24 0x002
-#define WM8785_WL_32 0x003
-#define WM8785_LRP 0x004
-#define WM8785_BCLKINV 0x008
-#define WM8785_LRSWAP 0x010
-#define WM8785_DEVNO_MASK 0x0e0
-/* R2 */
-#define WM8785_HPFR 0x001
-#define WM8785_HPFL 0x002
-#define WM8785_SDODIS 0x004
-#define WM8785_PWRDNR 0x008
-#define WM8785_PWRDNL 0x010
-#define WM8785_TDM_MASK 0x1c0
-
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/xonar.h b/ANDROID_3.4.5/sound/pci/oxygen/xonar.h
deleted file mode 100644
index 0434c207..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/xonar.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef XONAR_H_INCLUDED
-#define XONAR_H_INCLUDED
-
-#include "oxygen.h"
-
-struct xonar_generic {
- unsigned int anti_pop_delay;
- u16 output_enable_bit;
- u8 ext_power_reg;
- u8 ext_power_int_reg;
- u8 ext_power_bit;
- u8 has_power;
-};
-
-struct xonar_hdmi {
- u8 params[5];
-};
-
-/* generic helper functions */
-
-void xonar_enable_output(struct oxygen *chip);
-void xonar_disable_output(struct oxygen *chip);
-void xonar_init_ext_power(struct oxygen *chip);
-void xonar_init_cs53x1(struct oxygen *chip);
-void xonar_set_cs53x1_params(struct oxygen *chip,
- struct snd_pcm_hw_params *params);
-
-#define XONAR_GPIO_BIT_INVERT (1 << 16)
-int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value);
-int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value);
-
-/* model-specific card drivers */
-
-int get_xonar_pcm179x_model(struct oxygen *chip,
- const struct pci_device_id *id);
-int get_xonar_cs43xx_model(struct oxygen *chip,
- const struct pci_device_id *id);
-int get_xonar_wm87x6_model(struct oxygen *chip,
- const struct pci_device_id *id);
-
-/* HDMI helper functions */
-
-void xonar_hdmi_init(struct oxygen *chip, struct xonar_hdmi *data);
-void xonar_hdmi_cleanup(struct oxygen *chip);
-void xonar_hdmi_resume(struct oxygen *chip, struct xonar_hdmi *hdmi);
-void xonar_hdmi_pcm_hardware_filter(unsigned int channel,
- struct snd_pcm_hardware *hardware);
-void xonar_set_hdmi_params(struct oxygen *chip, struct xonar_hdmi *hdmi,
- struct snd_pcm_hw_params *params);
-void xonar_hdmi_uart_input(struct oxygen *chip);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/xonar_cs43xx.c b/ANDROID_3.4.5/sound/pci/oxygen/xonar_cs43xx.c
deleted file mode 100644
index c8febf4b..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/xonar_cs43xx.c
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * card driver for models with CS4398/CS4362A DACs (Xonar D1/DX)
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- *
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this driver; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * Xonar D1/DX
- * -----------
- *
- * CMI8788:
- *
- * I²C <-> CS4398 (addr 1001111) (front)
- * <-> CS4362A (addr 0011000) (surround, center/LFE, back)
- *
- * GPI 0 <- external power present (DX only)
- *
- * GPIO 0 -> enable output to speakers
- * GPIO 1 -> route output to front panel
- * GPIO 2 -> M0 of CS5361
- * GPIO 3 -> M1 of CS5361
- * GPIO 6 -> ?
- * GPIO 7 -> ?
- * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
- *
- * CM9780:
- *
- * LINE_OUT -> input of ADC
- *
- * AUX_IN <- aux
- * MIC_IN <- mic
- * FMIC_IN <- front mic
- *
- * GPO 0 -> route line-in (0) or AC97 output (1) to CS5361 input
- */
-
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <sound/ac97_codec.h>
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/tlv.h>
-#include "xonar.h"
-#include "cm9780.h"
-#include "cs4398.h"
-#include "cs4362a.h"
-
-#define GPI_EXT_POWER 0x01
-#define GPIO_D1_OUTPUT_ENABLE 0x0001
-#define GPIO_D1_FRONT_PANEL 0x0002
-#define GPIO_D1_MAGIC 0x00c0
-#define GPIO_D1_INPUT_ROUTE 0x0100
-
-#define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */
-#define I2C_DEVICE_CS4362A 0x30 /* 001100, AD0=0, /W=0 */
-
-struct xonar_cs43xx {
- struct xonar_generic generic;
- u8 cs4398_regs[8];
- u8 cs4362a_regs[15];
-};
-
-static void cs4398_write(struct oxygen *chip, u8 reg, u8 value)
-{
- struct xonar_cs43xx *data = chip->model_data;
-
- oxygen_write_i2c(chip, I2C_DEVICE_CS4398, reg, value);
- if (reg < ARRAY_SIZE(data->cs4398_regs))
- data->cs4398_regs[reg] = value;
-}
-
-static void cs4398_write_cached(struct oxygen *chip, u8 reg, u8 value)
-{
- struct xonar_cs43xx *data = chip->model_data;
-
- if (value != data->cs4398_regs[reg])
- cs4398_write(chip, reg, value);
-}
-
-static void cs4362a_write(struct oxygen *chip, u8 reg, u8 value)
-{
- struct xonar_cs43xx *data = chip->model_data;
-
- oxygen_write_i2c(chip, I2C_DEVICE_CS4362A, reg, value);
- if (reg < ARRAY_SIZE(data->cs4362a_regs))
- data->cs4362a_regs[reg] = value;
-}
-
-static void cs4362a_write_cached(struct oxygen *chip, u8 reg, u8 value)
-{
- struct xonar_cs43xx *data = chip->model_data;
-
- if (value != data->cs4362a_regs[reg])
- cs4362a_write(chip, reg, value);
-}
-
-static void cs43xx_registers_init(struct oxygen *chip)
-{
- struct xonar_cs43xx *data = chip->model_data;
- unsigned int i;
-
- /* set CPEN (control port mode) and power down */
- cs4398_write(chip, 8, CS4398_CPEN | CS4398_PDN);
- cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
- /* configure */
- cs4398_write(chip, 2, data->cs4398_regs[2]);
- cs4398_write(chip, 3, CS4398_ATAPI_B_R | CS4398_ATAPI_A_L);
- cs4398_write(chip, 4, data->cs4398_regs[4]);
- cs4398_write(chip, 5, data->cs4398_regs[5]);
- cs4398_write(chip, 6, data->cs4398_regs[6]);
- cs4398_write(chip, 7, data->cs4398_regs[7]);
- cs4362a_write(chip, 0x02, CS4362A_DIF_LJUST);
- cs4362a_write(chip, 0x03, CS4362A_MUTEC_6 | CS4362A_AMUTE |
- CS4362A_RMP_UP | CS4362A_ZERO_CROSS | CS4362A_SOFT_RAMP);
- cs4362a_write(chip, 0x04, data->cs4362a_regs[0x04]);
- cs4362a_write(chip, 0x05, 0);
- for (i = 6; i <= 14; ++i)
- cs4362a_write(chip, i, data->cs4362a_regs[i]);
- /* clear power down */
- cs4398_write(chip, 8, CS4398_CPEN);
- cs4362a_write(chip, 0x01, CS4362A_CPEN);
-}
-
-static void xonar_d1_init(struct oxygen *chip)
-{
- struct xonar_cs43xx *data = chip->model_data;
-
- data->generic.anti_pop_delay = 800;
- data->generic.output_enable_bit = GPIO_D1_OUTPUT_ENABLE;
- data->cs4398_regs[2] =
- CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST;
- data->cs4398_regs[4] = CS4398_MUTEP_LOW |
- CS4398_MUTE_B | CS4398_MUTE_A | CS4398_PAMUTE;
- data->cs4398_regs[5] = 60 * 2;
- data->cs4398_regs[6] = 60 * 2;
- data->cs4398_regs[7] = CS4398_RMP_DN | CS4398_RMP_UP |
- CS4398_ZERO_CROSS | CS4398_SOFT_RAMP;
- data->cs4362a_regs[4] = CS4362A_RMP_DN | CS4362A_DEM_NONE;
- data->cs4362a_regs[6] = CS4362A_FM_SINGLE |
- CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
- data->cs4362a_regs[7] = 60 | CS4362A_MUTE;
- data->cs4362a_regs[8] = 60 | CS4362A_MUTE;
- data->cs4362a_regs[9] = data->cs4362a_regs[6];
- data->cs4362a_regs[10] = 60 | CS4362A_MUTE;
- data->cs4362a_regs[11] = 60 | CS4362A_MUTE;
- data->cs4362a_regs[12] = data->cs4362a_regs[6];
- data->cs4362a_regs[13] = 60 | CS4362A_MUTE;
- data->cs4362a_regs[14] = 60 | CS4362A_MUTE;
-
- oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
- OXYGEN_2WIRE_LENGTH_8 |
- OXYGEN_2WIRE_INTERRUPT_MASK |
- OXYGEN_2WIRE_SPEED_FAST);
-
- cs43xx_registers_init(chip);
-
- oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
- GPIO_D1_FRONT_PANEL |
- GPIO_D1_MAGIC |
- GPIO_D1_INPUT_ROUTE);
- oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
- GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE);
-
- xonar_init_cs53x1(chip);
- xonar_enable_output(chip);
-
- snd_component_add(chip->card, "CS4398");
- snd_component_add(chip->card, "CS4362A");
- snd_component_add(chip->card, "CS5361");
-}
-
-static void xonar_dx_init(struct oxygen *chip)
-{
- struct xonar_cs43xx *data = chip->model_data;
-
- data->generic.ext_power_reg = OXYGEN_GPI_DATA;
- data->generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
- data->generic.ext_power_bit = GPI_EXT_POWER;
- xonar_init_ext_power(chip);
- xonar_d1_init(chip);
-}
-
-static void xonar_d1_cleanup(struct oxygen *chip)
-{
- xonar_disable_output(chip);
- cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
- oxygen_clear_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC);
-}
-
-static void xonar_d1_suspend(struct oxygen *chip)
-{
- xonar_d1_cleanup(chip);
-}
-
-static void xonar_d1_resume(struct oxygen *chip)
-{
- oxygen_set_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC);
- msleep(1);
- cs43xx_registers_init(chip);
- xonar_enable_output(chip);
-}
-
-static void set_cs43xx_params(struct oxygen *chip,
- struct snd_pcm_hw_params *params)
-{
- struct xonar_cs43xx *data = chip->model_data;
- u8 cs4398_fm, cs4362a_fm;
-
- if (params_rate(params) <= 50000) {
- cs4398_fm = CS4398_FM_SINGLE;
- cs4362a_fm = CS4362A_FM_SINGLE;
- } else if (params_rate(params) <= 100000) {
- cs4398_fm = CS4398_FM_DOUBLE;
- cs4362a_fm = CS4362A_FM_DOUBLE;
- } else {
- cs4398_fm = CS4398_FM_QUAD;
- cs4362a_fm = CS4362A_FM_QUAD;
- }
- cs4398_fm |= CS4398_DEM_NONE | CS4398_DIF_LJUST;
- cs4398_write_cached(chip, 2, cs4398_fm);
- cs4362a_fm |= data->cs4362a_regs[6] & ~CS4362A_FM_MASK;
- cs4362a_write_cached(chip, 6, cs4362a_fm);
- cs4362a_write_cached(chip, 12, cs4362a_fm);
- cs4362a_fm &= CS4362A_FM_MASK;
- cs4362a_fm |= data->cs4362a_regs[9] & ~CS4362A_FM_MASK;
- cs4362a_write_cached(chip, 9, cs4362a_fm);
-}
-
-static void update_cs4362a_volumes(struct oxygen *chip)
-{
- unsigned int i;
- u8 mute;
-
- mute = chip->dac_mute ? CS4362A_MUTE : 0;
- for (i = 0; i < 6; ++i)
- cs4362a_write_cached(chip, 7 + i + i / 2,
- (127 - chip->dac_volume[2 + i]) | mute);
-}
-
-static void update_cs43xx_volume(struct oxygen *chip)
-{
- cs4398_write_cached(chip, 5, (127 - chip->dac_volume[0]) * 2);
- cs4398_write_cached(chip, 6, (127 - chip->dac_volume[1]) * 2);
- update_cs4362a_volumes(chip);
-}
-
-static void update_cs43xx_mute(struct oxygen *chip)
-{
- u8 reg;
-
- reg = CS4398_MUTEP_LOW | CS4398_PAMUTE;
- if (chip->dac_mute)
- reg |= CS4398_MUTE_B | CS4398_MUTE_A;
- cs4398_write_cached(chip, 4, reg);
- update_cs4362a_volumes(chip);
-}
-
-static void update_cs43xx_center_lfe_mix(struct oxygen *chip, bool mixed)
-{
- struct xonar_cs43xx *data = chip->model_data;
- u8 reg;
-
- reg = data->cs4362a_regs[9] & ~CS4362A_ATAPI_MASK;
- if (mixed)
- reg |= CS4362A_ATAPI_B_LR | CS4362A_ATAPI_A_LR;
- else
- reg |= CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
- cs4362a_write_cached(chip, 9, reg);
-}
-
-static const struct snd_kcontrol_new front_panel_switch = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Front Panel Playback Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = xonar_gpio_bit_switch_get,
- .put = xonar_gpio_bit_switch_put,
- .private_value = GPIO_D1_FRONT_PANEL,
-};
-
-static int rolloff_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- static const char *const names[2] = {
- "Fast Roll-off", "Slow Roll-off"
- };
-
- return snd_ctl_enum_info(info, 1, 2, names);
-}
-
-static int rolloff_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct xonar_cs43xx *data = chip->model_data;
-
- value->value.enumerated.item[0] =
- (data->cs4398_regs[7] & CS4398_FILT_SEL) != 0;
- return 0;
-}
-
-static int rolloff_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct xonar_cs43xx *data = chip->model_data;
- int changed;
- u8 reg;
-
- mutex_lock(&chip->mutex);
- reg = data->cs4398_regs[7];
- if (value->value.enumerated.item[0])
- reg |= CS4398_FILT_SEL;
- else
- reg &= ~CS4398_FILT_SEL;
- changed = reg != data->cs4398_regs[7];
- if (changed) {
- cs4398_write(chip, 7, reg);
- if (reg & CS4398_FILT_SEL)
- reg = data->cs4362a_regs[0x04] | CS4362A_FILT_SEL;
- else
- reg = data->cs4362a_regs[0x04] & ~CS4362A_FILT_SEL;
- cs4362a_write(chip, 0x04, reg);
- }
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static const struct snd_kcontrol_new rolloff_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "DAC Filter Playback Enum",
- .info = rolloff_info,
- .get = rolloff_get,
- .put = rolloff_put,
-};
-
-static void xonar_d1_line_mic_ac97_switch(struct oxygen *chip,
- unsigned int reg, unsigned int mute)
-{
- if (reg == AC97_LINE) {
- spin_lock_irq(&chip->reg_lock);
- oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
- mute ? GPIO_D1_INPUT_ROUTE : 0,
- GPIO_D1_INPUT_ROUTE);
- spin_unlock_irq(&chip->reg_lock);
- }
-}
-
-static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -6000, 100, 0);
-
-static int xonar_d1_mixer_init(struct oxygen *chip)
-{
- int err;
-
- err = snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip));
- if (err < 0)
- return err;
- err = snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip));
- if (err < 0)
- return err;
- return 0;
-}
-
-static void dump_cs4362a_registers(struct xonar_cs43xx *data,
- struct snd_info_buffer *buffer)
-{
- unsigned int i;
-
- snd_iprintf(buffer, "\nCS4362A:");
- for (i = 1; i <= 14; ++i)
- snd_iprintf(buffer, " %02x", data->cs4362a_regs[i]);
- snd_iprintf(buffer, "\n");
-}
-
-static void dump_d1_registers(struct oxygen *chip,
- struct snd_info_buffer *buffer)
-{
- struct xonar_cs43xx *data = chip->model_data;
- unsigned int i;
-
- snd_iprintf(buffer, "\nCS4398: 7?");
- for (i = 2; i < 8; ++i)
- snd_iprintf(buffer, " %02x", data->cs4398_regs[i]);
- snd_iprintf(buffer, "\n");
- dump_cs4362a_registers(data, buffer);
-}
-
-static const struct oxygen_model model_xonar_d1 = {
- .longname = "Asus Virtuoso 100",
- .chip = "AV200",
- .init = xonar_d1_init,
- .mixer_init = xonar_d1_mixer_init,
- .cleanup = xonar_d1_cleanup,
- .suspend = xonar_d1_suspend,
- .resume = xonar_d1_resume,
- .set_dac_params = set_cs43xx_params,
- .set_adc_params = xonar_set_cs53x1_params,
- .update_dac_volume = update_cs43xx_volume,
- .update_dac_mute = update_cs43xx_mute,
- .update_center_lfe_mix = update_cs43xx_center_lfe_mix,
- .ac97_switch = xonar_d1_line_mic_ac97_switch,
- .dump_registers = dump_d1_registers,
- .dac_tlv = cs4362a_db_scale,
- .model_data_size = sizeof(struct xonar_cs43xx),
- .device_config = PLAYBACK_0_TO_I2S |
- PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_2 |
- CAPTURE_1_FROM_SPDIF |
- AC97_FMIC_SWITCH,
- .dac_channels_pcm = 8,
- .dac_channels_mixer = 8,
- .dac_volume_min = 127 - 60,
- .dac_volume_max = 127,
- .function_flags = OXYGEN_FUNCTION_2WIRE,
- .dac_mclks = OXYGEN_MCLKS(256, 128, 128),
- .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
- .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
- .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
-};
-
-int __devinit get_xonar_cs43xx_model(struct oxygen *chip,
- const struct pci_device_id *id)
-{
- switch (id->subdevice) {
- case 0x834f:
- chip->model = model_xonar_d1;
- chip->model.shortname = "Xonar D1";
- break;
- case 0x8275:
- case 0x8327:
- chip->model = model_xonar_d1;
- chip->model.shortname = "Xonar DX";
- chip->model.init = xonar_dx_init;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/xonar_dg.c b/ANDROID_3.4.5/sound/pci/oxygen/xonar_dg.c
deleted file mode 100644
index 793bdf03..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/xonar_dg.c
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
- * card driver for the Xonar DG
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- *
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this driver; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * Xonar DG
- * --------
- *
- * CMI8788:
- *
- * SPI 0 -> CS4245
- *
- * I²S 1 -> CS4245
- * I²S 2 -> CS4361 (center/LFE)
- * I²S 3 -> CS4361 (surround)
- * I²S 4 -> CS4361 (front)
- *
- * GPIO 3 <- ?
- * GPIO 4 <- headphone detect
- * GPIO 5 -> route input jack to line-in (0) or mic-in (1)
- * GPIO 6 -> route input jack to line-in (0) or mic-in (1)
- * GPIO 7 -> enable rear headphone amp
- * GPIO 8 -> enable output to speakers
- *
- * CS4245:
- *
- * input 1 <- aux
- * input 2 <- front mic
- * input 4 <- line/mic
- * DAC out -> headphones
- * aux out -> front panel headphones
- */
-
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/pcm.h>
-#include <sound/tlv.h>
-#include "oxygen.h"
-#include "xonar_dg.h"
-#include "cs4245.h"
-
-#define GPIO_MAGIC 0x0008
-#define GPIO_HP_DETECT 0x0010
-#define GPIO_INPUT_ROUTE 0x0060
-#define GPIO_HP_REAR 0x0080
-#define GPIO_OUTPUT_ENABLE 0x0100
-
-struct dg {
- unsigned int output_sel;
- s8 input_vol[4][2];
- unsigned int input_sel;
- u8 hp_vol_att;
- u8 cs4245_regs[0x11];
-};
-
-static void cs4245_write(struct oxygen *chip, unsigned int reg, u8 value)
-{
- struct dg *data = chip->model_data;
-
- oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
- OXYGEN_SPI_DATA_LENGTH_3 |
- OXYGEN_SPI_CLOCK_1280 |
- (0 << OXYGEN_SPI_CODEC_SHIFT) |
- OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
- CS4245_SPI_ADDRESS |
- CS4245_SPI_WRITE |
- (reg << 8) | value);
- data->cs4245_regs[reg] = value;
-}
-
-static void cs4245_write_cached(struct oxygen *chip, unsigned int reg, u8 value)
-{
- struct dg *data = chip->model_data;
-
- if (value != data->cs4245_regs[reg])
- cs4245_write(chip, reg, value);
-}
-
-static void cs4245_registers_init(struct oxygen *chip)
-{
- struct dg *data = chip->model_data;
-
- cs4245_write(chip, CS4245_POWER_CTRL, CS4245_PDN);
- cs4245_write(chip, CS4245_DAC_CTRL_1,
- data->cs4245_regs[CS4245_DAC_CTRL_1]);
- cs4245_write(chip, CS4245_ADC_CTRL,
- data->cs4245_regs[CS4245_ADC_CTRL]);
- cs4245_write(chip, CS4245_SIGNAL_SEL,
- data->cs4245_regs[CS4245_SIGNAL_SEL]);
- cs4245_write(chip, CS4245_PGA_B_CTRL,
- data->cs4245_regs[CS4245_PGA_B_CTRL]);
- cs4245_write(chip, CS4245_PGA_A_CTRL,
- data->cs4245_regs[CS4245_PGA_A_CTRL]);
- cs4245_write(chip, CS4245_ANALOG_IN,
- data->cs4245_regs[CS4245_ANALOG_IN]);
- cs4245_write(chip, CS4245_DAC_A_CTRL,
- data->cs4245_regs[CS4245_DAC_A_CTRL]);
- cs4245_write(chip, CS4245_DAC_B_CTRL,
- data->cs4245_regs[CS4245_DAC_B_CTRL]);
- cs4245_write(chip, CS4245_DAC_CTRL_2,
- CS4245_DAC_SOFT | CS4245_DAC_ZERO | CS4245_INVERT_DAC);
- cs4245_write(chip, CS4245_INT_MASK, 0);
- cs4245_write(chip, CS4245_POWER_CTRL, 0);
-}
-
-static void cs4245_init(struct oxygen *chip)
-{
- struct dg *data = chip->model_data;
-
- data->cs4245_regs[CS4245_DAC_CTRL_1] =
- CS4245_DAC_FM_SINGLE | CS4245_DAC_DIF_LJUST;
- data->cs4245_regs[CS4245_ADC_CTRL] =
- CS4245_ADC_FM_SINGLE | CS4245_ADC_DIF_LJUST;
- data->cs4245_regs[CS4245_SIGNAL_SEL] =
- CS4245_A_OUT_SEL_HIZ | CS4245_ASYNCH;
- data->cs4245_regs[CS4245_PGA_B_CTRL] = 0;
- data->cs4245_regs[CS4245_PGA_A_CTRL] = 0;
- data->cs4245_regs[CS4245_ANALOG_IN] =
- CS4245_PGA_SOFT | CS4245_PGA_ZERO | CS4245_SEL_INPUT_4;
- data->cs4245_regs[CS4245_DAC_A_CTRL] = 0;
- data->cs4245_regs[CS4245_DAC_B_CTRL] = 0;
- cs4245_registers_init(chip);
- snd_component_add(chip->card, "CS4245");
-}
-
-static void dg_output_enable(struct oxygen *chip)
-{
- msleep(2500);
- oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE);
-}
-
-static void dg_init(struct oxygen *chip)
-{
- struct dg *data = chip->model_data;
-
- data->output_sel = 0;
- data->input_sel = 3;
- data->hp_vol_att = 2 * 16;
-
- cs4245_init(chip);
-
- oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
- GPIO_MAGIC | GPIO_HP_DETECT);
- oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
- GPIO_INPUT_ROUTE | GPIO_HP_REAR | GPIO_OUTPUT_ENABLE);
- oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
- GPIO_INPUT_ROUTE | GPIO_HP_REAR);
- dg_output_enable(chip);
-}
-
-static void dg_cleanup(struct oxygen *chip)
-{
- oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE);
-}
-
-static void dg_suspend(struct oxygen *chip)
-{
- dg_cleanup(chip);
-}
-
-static void dg_resume(struct oxygen *chip)
-{
- cs4245_registers_init(chip);
- dg_output_enable(chip);
-}
-
-static void set_cs4245_dac_params(struct oxygen *chip,
- struct snd_pcm_hw_params *params)
-{
- struct dg *data = chip->model_data;
- u8 value;
-
- value = data->cs4245_regs[CS4245_DAC_CTRL_1] & ~CS4245_DAC_FM_MASK;
- if (params_rate(params) <= 50000)
- value |= CS4245_DAC_FM_SINGLE;
- else if (params_rate(params) <= 100000)
- value |= CS4245_DAC_FM_DOUBLE;
- else
- value |= CS4245_DAC_FM_QUAD;
- cs4245_write_cached(chip, CS4245_DAC_CTRL_1, value);
-}
-
-static void set_cs4245_adc_params(struct oxygen *chip,
- struct snd_pcm_hw_params *params)
-{
- struct dg *data = chip->model_data;
- u8 value;
-
- value = data->cs4245_regs[CS4245_ADC_CTRL] & ~CS4245_ADC_FM_MASK;
- if (params_rate(params) <= 50000)
- value |= CS4245_ADC_FM_SINGLE;
- else if (params_rate(params) <= 100000)
- value |= CS4245_ADC_FM_DOUBLE;
- else
- value |= CS4245_ADC_FM_QUAD;
- cs4245_write_cached(chip, CS4245_ADC_CTRL, value);
-}
-
-static inline unsigned int shift_bits(unsigned int value,
- unsigned int shift_from,
- unsigned int shift_to,
- unsigned int mask)
-{
- if (shift_from < shift_to)
- return (value << (shift_to - shift_from)) & mask;
- else
- return (value >> (shift_from - shift_to)) & mask;
-}
-
-static unsigned int adjust_dg_dac_routing(struct oxygen *chip,
- unsigned int play_routing)
-{
- return (play_routing & OXYGEN_PLAY_DAC0_SOURCE_MASK) |
- shift_bits(play_routing,
- OXYGEN_PLAY_DAC2_SOURCE_SHIFT,
- OXYGEN_PLAY_DAC1_SOURCE_SHIFT,
- OXYGEN_PLAY_DAC1_SOURCE_MASK) |
- shift_bits(play_routing,
- OXYGEN_PLAY_DAC1_SOURCE_SHIFT,
- OXYGEN_PLAY_DAC2_SOURCE_SHIFT,
- OXYGEN_PLAY_DAC2_SOURCE_MASK) |
- shift_bits(play_routing,
- OXYGEN_PLAY_DAC0_SOURCE_SHIFT,
- OXYGEN_PLAY_DAC3_SOURCE_SHIFT,
- OXYGEN_PLAY_DAC3_SOURCE_MASK);
-}
-
-static int output_switch_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- static const char *const names[3] = {
- "Speakers", "Headphones", "FP Headphones"
- };
-
- return snd_ctl_enum_info(info, 1, 3, names);
-}
-
-static int output_switch_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct dg *data = chip->model_data;
-
- mutex_lock(&chip->mutex);
- value->value.enumerated.item[0] = data->output_sel;
- mutex_unlock(&chip->mutex);
- return 0;
-}
-
-static int output_switch_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct dg *data = chip->model_data;
- u8 reg;
- int changed;
-
- if (value->value.enumerated.item[0] > 2)
- return -EINVAL;
-
- mutex_lock(&chip->mutex);
- changed = value->value.enumerated.item[0] != data->output_sel;
- if (changed) {
- data->output_sel = value->value.enumerated.item[0];
-
- reg = data->cs4245_regs[CS4245_SIGNAL_SEL] &
- ~CS4245_A_OUT_SEL_MASK;
- reg |= data->output_sel == 2 ?
- CS4245_A_OUT_SEL_DAC : CS4245_A_OUT_SEL_HIZ;
- cs4245_write_cached(chip, CS4245_SIGNAL_SEL, reg);
-
- cs4245_write_cached(chip, CS4245_DAC_A_CTRL,
- data->output_sel ? data->hp_vol_att : 0);
- cs4245_write_cached(chip, CS4245_DAC_B_CTRL,
- data->output_sel ? data->hp_vol_att : 0);
-
- oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
- data->output_sel == 1 ? GPIO_HP_REAR : 0,
- GPIO_HP_REAR);
- }
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static int hp_volume_offset_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- static const char *const names[3] = {
- "< 64 ohms", "64-150 ohms", "150-300 ohms"
- };
-
- return snd_ctl_enum_info(info, 1, 3, names);
-}
-
-static int hp_volume_offset_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct dg *data = chip->model_data;
-
- mutex_lock(&chip->mutex);
- if (data->hp_vol_att > 2 * 7)
- value->value.enumerated.item[0] = 0;
- else if (data->hp_vol_att > 0)
- value->value.enumerated.item[0] = 1;
- else
- value->value.enumerated.item[0] = 2;
- mutex_unlock(&chip->mutex);
- return 0;
-}
-
-static int hp_volume_offset_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- static const s8 atts[3] = { 2 * 16, 2 * 7, 0 };
- struct oxygen *chip = ctl->private_data;
- struct dg *data = chip->model_data;
- s8 att;
- int changed;
-
- if (value->value.enumerated.item[0] > 2)
- return -EINVAL;
- att = atts[value->value.enumerated.item[0]];
- mutex_lock(&chip->mutex);
- changed = att != data->hp_vol_att;
- if (changed) {
- data->hp_vol_att = att;
- if (data->output_sel) {
- cs4245_write_cached(chip, CS4245_DAC_A_CTRL, att);
- cs4245_write_cached(chip, CS4245_DAC_B_CTRL, att);
- }
- }
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static int input_vol_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- info->count = 2;
- info->value.integer.min = 2 * -12;
- info->value.integer.max = 2 * 12;
- return 0;
-}
-
-static int input_vol_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct dg *data = chip->model_data;
- unsigned int idx = ctl->private_value;
-
- mutex_lock(&chip->mutex);
- value->value.integer.value[0] = data->input_vol[idx][0];
- value->value.integer.value[1] = data->input_vol[idx][1];
- mutex_unlock(&chip->mutex);
- return 0;
-}
-
-static int input_vol_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct dg *data = chip->model_data;
- unsigned int idx = ctl->private_value;
- int changed = 0;
-
- if (value->value.integer.value[0] < 2 * -12 ||
- value->value.integer.value[0] > 2 * 12 ||
- value->value.integer.value[1] < 2 * -12 ||
- value->value.integer.value[1] > 2 * 12)
- return -EINVAL;
- mutex_lock(&chip->mutex);
- changed = data->input_vol[idx][0] != value->value.integer.value[0] ||
- data->input_vol[idx][1] != value->value.integer.value[1];
- if (changed) {
- data->input_vol[idx][0] = value->value.integer.value[0];
- data->input_vol[idx][1] = value->value.integer.value[1];
- if (idx == data->input_sel) {
- cs4245_write_cached(chip, CS4245_PGA_A_CTRL,
- data->input_vol[idx][0]);
- cs4245_write_cached(chip, CS4245_PGA_B_CTRL,
- data->input_vol[idx][1]);
- }
- }
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static DECLARE_TLV_DB_SCALE(cs4245_pga_db_scale, -1200, 50, 0);
-
-static int input_sel_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- static const char *const names[4] = {
- "Mic", "Aux", "Front Mic", "Line"
- };
-
- return snd_ctl_enum_info(info, 1, 4, names);
-}
-
-static int input_sel_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct dg *data = chip->model_data;
-
- mutex_lock(&chip->mutex);
- value->value.enumerated.item[0] = data->input_sel;
- mutex_unlock(&chip->mutex);
- return 0;
-}
-
-static int input_sel_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- static const u8 sel_values[4] = {
- CS4245_SEL_MIC,
- CS4245_SEL_INPUT_1,
- CS4245_SEL_INPUT_2,
- CS4245_SEL_INPUT_4
- };
- struct oxygen *chip = ctl->private_data;
- struct dg *data = chip->model_data;
- int changed;
-
- if (value->value.enumerated.item[0] > 3)
- return -EINVAL;
-
- mutex_lock(&chip->mutex);
- changed = value->value.enumerated.item[0] != data->input_sel;
- if (changed) {
- data->input_sel = value->value.enumerated.item[0];
-
- cs4245_write(chip, CS4245_ANALOG_IN,
- (data->cs4245_regs[CS4245_ANALOG_IN] &
- ~CS4245_SEL_MASK) |
- sel_values[data->input_sel]);
-
- cs4245_write_cached(chip, CS4245_PGA_A_CTRL,
- data->input_vol[data->input_sel][0]);
- cs4245_write_cached(chip, CS4245_PGA_B_CTRL,
- data->input_vol[data->input_sel][1]);
-
- oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
- data->input_sel ? 0 : GPIO_INPUT_ROUTE,
- GPIO_INPUT_ROUTE);
- }
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
-{
- static const char *const names[2] = { "Active", "Frozen" };
-
- return snd_ctl_enum_info(info, 1, 2, names);
-}
-
-static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct dg *data = chip->model_data;
-
- value->value.enumerated.item[0] =
- !!(data->cs4245_regs[CS4245_ADC_CTRL] & CS4245_HPF_FREEZE);
- return 0;
-}
-
-static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct dg *data = chip->model_data;
- u8 reg;
- int changed;
-
- mutex_lock(&chip->mutex);
- reg = data->cs4245_regs[CS4245_ADC_CTRL] & ~CS4245_HPF_FREEZE;
- if (value->value.enumerated.item[0])
- reg |= CS4245_HPF_FREEZE;
- changed = reg != data->cs4245_regs[CS4245_ADC_CTRL];
- if (changed)
- cs4245_write(chip, CS4245_ADC_CTRL, reg);
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-#define INPUT_VOLUME(xname, index) { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .info = input_vol_info, \
- .get = input_vol_get, \
- .put = input_vol_put, \
- .tlv = { .p = cs4245_pga_db_scale }, \
- .private_value = index, \
-}
-static const struct snd_kcontrol_new dg_controls[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Output Playback Enum",
- .info = output_switch_info,
- .get = output_switch_get,
- .put = output_switch_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Headphones Impedance Playback Enum",
- .info = hp_volume_offset_info,
- .get = hp_volume_offset_get,
- .put = hp_volume_offset_put,
- },
- INPUT_VOLUME("Mic Capture Volume", 0),
- INPUT_VOLUME("Aux Capture Volume", 1),
- INPUT_VOLUME("Front Mic Capture Volume", 2),
- INPUT_VOLUME("Line Capture Volume", 3),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = input_sel_info,
- .get = input_sel_get,
- .put = input_sel_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "ADC High-pass Filter Capture Enum",
- .info = hpf_info,
- .get = hpf_get,
- .put = hpf_put,
- },
-};
-
-static int dg_control_filter(struct snd_kcontrol_new *template)
-{
- if (!strncmp(template->name, "Master Playback ", 16))
- return 1;
- return 0;
-}
-
-static int dg_mixer_init(struct oxygen *chip)
-{
- unsigned int i;
- int err;
-
- for (i = 0; i < ARRAY_SIZE(dg_controls); ++i) {
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&dg_controls[i], chip));
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-static void dump_cs4245_registers(struct oxygen *chip,
- struct snd_info_buffer *buffer)
-{
- struct dg *data = chip->model_data;
- unsigned int i;
-
- snd_iprintf(buffer, "\nCS4245:");
- for (i = 1; i <= 0x10; ++i)
- snd_iprintf(buffer, " %02x", data->cs4245_regs[i]);
- snd_iprintf(buffer, "\n");
-}
-
-struct oxygen_model model_xonar_dg = {
- .shortname = "Xonar DG",
- .longname = "C-Media Oxygen HD Audio",
- .chip = "CMI8786",
- .init = dg_init,
- .control_filter = dg_control_filter,
- .mixer_init = dg_mixer_init,
- .cleanup = dg_cleanup,
- .suspend = dg_suspend,
- .resume = dg_resume,
- .set_dac_params = set_cs4245_dac_params,
- .set_adc_params = set_cs4245_adc_params,
- .adjust_dac_routing = adjust_dg_dac_routing,
- .dump_registers = dump_cs4245_registers,
- .model_data_size = sizeof(struct dg),
- .device_config = PLAYBACK_0_TO_I2S |
- PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_2 |
- CAPTURE_1_FROM_SPDIF,
- .dac_channels_pcm = 6,
- .dac_channels_mixer = 0,
- .function_flags = OXYGEN_FUNCTION_SPI,
- .dac_mclks = OXYGEN_MCLKS(256, 128, 128),
- .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
- .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
- .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
-};
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/xonar_dg.h b/ANDROID_3.4.5/sound/pci/oxygen/xonar_dg.h
deleted file mode 100644
index 5688d786..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/xonar_dg.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef XONAR_DG_H_INCLUDED
-#define XONAR_DG_H_INCLUDED
-
-#include "oxygen.h"
-
-extern struct oxygen_model model_xonar_dg;
-
-#endif
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/xonar_hdmi.c b/ANDROID_3.4.5/sound/pci/oxygen/xonar_hdmi.c
deleted file mode 100644
index 136dac6a..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/xonar_hdmi.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * helper functions for HDMI models (Xonar HDAV1.3/HDAV1.3 Slim)
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- *
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this driver; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <sound/asoundef.h>
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/tlv.h>
-#include "xonar.h"
-
-static void hdmi_write_command(struct oxygen *chip, u8 command,
- unsigned int count, const u8 *params)
-{
- unsigned int i;
- u8 checksum;
-
- oxygen_write_uart(chip, 0xfb);
- oxygen_write_uart(chip, 0xef);
- oxygen_write_uart(chip, command);
- oxygen_write_uart(chip, count);
- for (i = 0; i < count; ++i)
- oxygen_write_uart(chip, params[i]);
- checksum = 0xfb + 0xef + command + count;
- for (i = 0; i < count; ++i)
- checksum += params[i];
- oxygen_write_uart(chip, checksum);
-}
-
-static void xonar_hdmi_init_commands(struct oxygen *chip,
- struct xonar_hdmi *hdmi)
-{
- u8 param;
-
- oxygen_reset_uart(chip);
- param = 0;
- hdmi_write_command(chip, 0x61, 1, &param);
- param = 1;
- hdmi_write_command(chip, 0x74, 1, &param);
- hdmi_write_command(chip, 0x54, 5, hdmi->params);
-}
-
-void xonar_hdmi_init(struct oxygen *chip, struct xonar_hdmi *hdmi)
-{
- hdmi->params[1] = IEC958_AES3_CON_FS_48000;
- hdmi->params[4] = 1;
- xonar_hdmi_init_commands(chip, hdmi);
-}
-
-void xonar_hdmi_cleanup(struct oxygen *chip)
-{
- u8 param = 0;
-
- hdmi_write_command(chip, 0x74, 1, &param);
-}
-
-void xonar_hdmi_resume(struct oxygen *chip, struct xonar_hdmi *hdmi)
-{
- xonar_hdmi_init_commands(chip, hdmi);
-}
-
-void xonar_hdmi_pcm_hardware_filter(unsigned int channel,
- struct snd_pcm_hardware *hardware)
-{
- if (channel == PCM_MULTICH) {
- hardware->rates = SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_96000 |
- SNDRV_PCM_RATE_192000;
- hardware->rate_min = 44100;
- }
-}
-
-void xonar_set_hdmi_params(struct oxygen *chip, struct xonar_hdmi *hdmi,
- struct snd_pcm_hw_params *params)
-{
- hdmi->params[0] = 0; /* 1 = non-audio */
- switch (params_rate(params)) {
- case 44100:
- hdmi->params[1] = IEC958_AES3_CON_FS_44100;
- break;
- case 48000:
- hdmi->params[1] = IEC958_AES3_CON_FS_48000;
- break;
- default: /* 96000 */
- hdmi->params[1] = IEC958_AES3_CON_FS_96000;
- break;
- case 192000:
- hdmi->params[1] = IEC958_AES3_CON_FS_192000;
- break;
- }
- hdmi->params[2] = params_channels(params) / 2 - 1;
- if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE)
- hdmi->params[3] = 0;
- else
- hdmi->params[3] = 0xc0;
- hdmi->params[4] = 1; /* ? */
- hdmi_write_command(chip, 0x54, 5, hdmi->params);
-}
-
-void xonar_hdmi_uart_input(struct oxygen *chip)
-{
- if (chip->uart_input_count >= 2 &&
- chip->uart_input[chip->uart_input_count - 2] == 'O' &&
- chip->uart_input[chip->uart_input_count - 1] == 'K') {
- printk(KERN_DEBUG "message from HDMI chip received:\n");
- print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
- chip->uart_input, chip->uart_input_count);
- chip->uart_input_count = 0;
- }
-}
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/xonar_lib.c b/ANDROID_3.4.5/sound/pci/oxygen/xonar_lib.c
deleted file mode 100644
index 0ebe7f59..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/xonar_lib.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * helper functions for Asus Xonar cards
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- *
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this driver; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/delay.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include "xonar.h"
-
-
-#define GPIO_CS53x1_M_MASK 0x000c
-#define GPIO_CS53x1_M_SINGLE 0x0000
-#define GPIO_CS53x1_M_DOUBLE 0x0004
-#define GPIO_CS53x1_M_QUAD 0x0008
-
-
-void xonar_enable_output(struct oxygen *chip)
-{
- struct xonar_generic *data = chip->model_data;
-
- oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, data->output_enable_bit);
- msleep(data->anti_pop_delay);
- oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
-}
-
-void xonar_disable_output(struct oxygen *chip)
-{
- struct xonar_generic *data = chip->model_data;
-
- oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
-}
-
-static void xonar_ext_power_gpio_changed(struct oxygen *chip)
-{
- struct xonar_generic *data = chip->model_data;
- u8 has_power;
-
- has_power = !!(oxygen_read8(chip, data->ext_power_reg)
- & data->ext_power_bit);
- if (has_power != data->has_power) {
- data->has_power = has_power;
- if (has_power) {
- snd_printk(KERN_NOTICE "power restored\n");
- } else {
- snd_printk(KERN_CRIT
- "Hey! Don't unplug the power cable!\n");
- /* TODO: stop PCMs */
- }
- }
-}
-
-void xonar_init_ext_power(struct oxygen *chip)
-{
- struct xonar_generic *data = chip->model_data;
-
- oxygen_set_bits8(chip, data->ext_power_int_reg,
- data->ext_power_bit);
- chip->interrupt_mask |= OXYGEN_INT_GPIO;
- chip->model.gpio_changed = xonar_ext_power_gpio_changed;
- data->has_power = !!(oxygen_read8(chip, data->ext_power_reg)
- & data->ext_power_bit);
-}
-
-void xonar_init_cs53x1(struct oxygen *chip)
-{
- oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CS53x1_M_MASK);
- oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
- GPIO_CS53x1_M_SINGLE, GPIO_CS53x1_M_MASK);
-}
-
-void xonar_set_cs53x1_params(struct oxygen *chip,
- struct snd_pcm_hw_params *params)
-{
- unsigned int value;
-
- if (params_rate(params) <= 54000)
- value = GPIO_CS53x1_M_SINGLE;
- else if (params_rate(params) <= 108000)
- value = GPIO_CS53x1_M_DOUBLE;
- else
- value = GPIO_CS53x1_M_QUAD;
- oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
- value, GPIO_CS53x1_M_MASK);
-}
-
-int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- u16 bit = ctl->private_value;
- bool invert = ctl->private_value & XONAR_GPIO_BIT_INVERT;
-
- value->value.integer.value[0] =
- !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit) ^ invert;
- return 0;
-}
-
-int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- u16 bit = ctl->private_value;
- bool invert = ctl->private_value & XONAR_GPIO_BIT_INVERT;
- u16 old_bits, new_bits;
- int changed;
-
- spin_lock_irq(&chip->reg_lock);
- old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA);
- if (!!value->value.integer.value[0] ^ invert)
- new_bits = old_bits | bit;
- else
- new_bits = old_bits & ~bit;
- changed = new_bits != old_bits;
- if (changed)
- oxygen_write16(chip, OXYGEN_GPIO_DATA, new_bits);
- spin_unlock_irq(&chip->reg_lock);
- return changed;
-}
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/xonar_pcm179x.c b/ANDROID_3.4.5/sound/pci/oxygen/xonar_pcm179x.c
deleted file mode 100644
index 8433aa7c..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/xonar_pcm179x.c
+++ /dev/null
@@ -1,1145 +0,0 @@
-/*
- * card driver for models with PCM1796 DACs (Xonar D2/D2X/HDAV1.3/ST/STX)
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- *
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this driver; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * Xonar D2/D2X
- * ------------
- *
- * CMI8788:
- *
- * SPI 0 -> 1st PCM1796 (front)
- * SPI 1 -> 2nd PCM1796 (surround)
- * SPI 2 -> 3rd PCM1796 (center/LFE)
- * SPI 4 -> 4th PCM1796 (back)
- *
- * GPIO 2 -> M0 of CS5381
- * GPIO 3 -> M1 of CS5381
- * GPIO 5 <- external power present (D2X only)
- * GPIO 7 -> ALT
- * GPIO 8 -> enable output to speakers
- *
- * CM9780:
- *
- * LINE_OUT -> input of ADC
- *
- * AUX_IN <- aux
- * VIDEO_IN <- CD
- * FMIC_IN <- mic
- *
- * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
- */
-
-/*
- * Xonar HDAV1.3 (Deluxe)
- * ----------------------
- *
- * CMI8788:
- *
- * I²C <-> PCM1796 (addr 1001100) (front)
- *
- * GPI 0 <- external power present
- *
- * GPIO 0 -> enable HDMI (0) or speaker (1) output
- * GPIO 2 -> M0 of CS5381
- * GPIO 3 -> M1 of CS5381
- * GPIO 4 <- daughterboard detection
- * GPIO 5 <- daughterboard detection
- * GPIO 6 -> ?
- * GPIO 7 -> ?
- * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
- *
- * UART <-> HDMI controller
- *
- * CM9780:
- *
- * LINE_OUT -> input of ADC
- *
- * AUX_IN <- aux
- * CD_IN <- CD
- * MIC_IN <- mic
- *
- * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
- *
- * no daughterboard
- * ----------------
- *
- * GPIO 4 <- 1
- *
- * H6 daughterboard
- * ----------------
- *
- * GPIO 4 <- 0
- * GPIO 5 <- 0
- *
- * I²C <-> PCM1796 (addr 1001101) (surround)
- * <-> PCM1796 (addr 1001110) (center/LFE)
- * <-> PCM1796 (addr 1001111) (back)
- *
- * unknown daughterboard
- * ---------------------
- *
- * GPIO 4 <- 0
- * GPIO 5 <- 1
- *
- * I²C <-> CS4362A (addr 0011000) (surround, center/LFE, back)
- */
-
-/*
- * Xonar Essence ST (Deluxe)/STX
- * -----------------------------
- *
- * CMI8788:
- *
- * I²C <-> PCM1792A (addr 1001100)
- * <-> CS2000 (addr 1001110) (ST only)
- *
- * ADC1 MCLK -> REF_CLK of CS2000 (ST only)
- *
- * GPI 0 <- external power present (STX only)
- *
- * GPIO 0 -> enable output to speakers
- * GPIO 1 -> route HP to front panel (0) or rear jack (1)
- * GPIO 2 -> M0 of CS5381
- * GPIO 3 -> M1 of CS5381
- * GPIO 4 <- daughterboard detection
- * GPIO 5 <- daughterboard detection
- * GPIO 6 -> ?
- * GPIO 7 -> route output to speaker jacks (0) or HP (1)
- * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
- *
- * PCM1792A:
- *
- * SCK <- CLK_OUT of CS2000 (ST only)
- *
- * CM9780:
- *
- * LINE_OUT -> input of ADC
- *
- * AUX_IN <- aux
- * MIC_IN <- mic
- *
- * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
- *
- * H6 daughterboard
- * ----------------
- *
- * GPIO 4 <- 0
- * GPIO 5 <- 0
- */
-
-/*
- * Xonar Xense
- * -----------
- *
- * CMI8788:
- *
- * I²C <-> PCM1796 (addr 1001100) (front)
- * <-> CS4362A (addr 0011000) (surround, center/LFE, back)
- * <-> CS2000 (addr 1001110)
- *
- * ADC1 MCLK -> REF_CLK of CS2000
- *
- * GPI 0 <- external power present
- *
- * GPIO 0 -> enable output
- * GPIO 1 -> route HP to front panel (0) or rear jack (1)
- * GPIO 2 -> M0 of CS5381
- * GPIO 3 -> M1 of CS5381
- * GPIO 4 -> enable output
- * GPIO 5 -> enable output
- * GPIO 6 -> ?
- * GPIO 7 -> route output to HP (0) or speaker (1)
- * GPIO 8 -> route input jack to mic-in (0) or line-in (1)
- *
- * CM9780:
- *
- * LINE_OUT -> input of ADC
- *
- * AUX_IN <- aux
- * VIDEO_IN <- ?
- * FMIC_IN <- mic
- *
- * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
- * GPO 1 -> route mic-in from input jack (0) or front panel header (1)
- */
-
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <sound/ac97_codec.h>
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/tlv.h>
-#include "xonar.h"
-#include "cm9780.h"
-#include "pcm1796.h"
-#include "cs2000.h"
-
-
-#define GPIO_D2X_EXT_POWER 0x0020
-#define GPIO_D2_ALT 0x0080
-#define GPIO_D2_OUTPUT_ENABLE 0x0100
-
-#define GPI_EXT_POWER 0x01
-#define GPIO_INPUT_ROUTE 0x0100
-
-#define GPIO_HDAV_OUTPUT_ENABLE 0x0001
-#define GPIO_HDAV_MAGIC 0x00c0
-
-#define GPIO_DB_MASK 0x0030
-#define GPIO_DB_H6 0x0000
-
-#define GPIO_ST_OUTPUT_ENABLE 0x0001
-#define GPIO_ST_HP_REAR 0x0002
-#define GPIO_ST_MAGIC 0x0040
-#define GPIO_ST_HP 0x0080
-
-#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ii, /W=0 */
-#define I2C_DEVICE_CS2000 0x9c /* 100111, 0, /W=0 */
-
-#define PCM1796_REG_BASE 16
-
-
-struct xonar_pcm179x {
- struct xonar_generic generic;
- unsigned int dacs;
- u8 pcm1796_regs[4][5];
- unsigned int current_rate;
- bool h6;
- bool hp_active;
- s8 hp_gain_offset;
- bool has_cs2000;
- u8 cs2000_regs[0x1f];
- bool broken_i2c;
-};
-
-struct xonar_hdav {
- struct xonar_pcm179x pcm179x;
- struct xonar_hdmi hdmi;
-};
-
-
-static inline void pcm1796_write_spi(struct oxygen *chip, unsigned int codec,
- u8 reg, u8 value)
-{
- /* maps ALSA channel pair number to SPI output */
- static const u8 codec_map[4] = {
- 0, 1, 2, 4
- };
- oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
- OXYGEN_SPI_DATA_LENGTH_2 |
- OXYGEN_SPI_CLOCK_160 |
- (codec_map[codec] << OXYGEN_SPI_CODEC_SHIFT) |
- OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
- (reg << 8) | value);
-}
-
-static inline void pcm1796_write_i2c(struct oxygen *chip, unsigned int codec,
- u8 reg, u8 value)
-{
- oxygen_write_i2c(chip, I2C_DEVICE_PCM1796(codec), reg, value);
-}
-
-static void pcm1796_write(struct oxygen *chip, unsigned int codec,
- u8 reg, u8 value)
-{
- struct xonar_pcm179x *data = chip->model_data;
-
- if ((chip->model.function_flags & OXYGEN_FUNCTION_2WIRE_SPI_MASK) ==
- OXYGEN_FUNCTION_SPI)
- pcm1796_write_spi(chip, codec, reg, value);
- else
- pcm1796_write_i2c(chip, codec, reg, value);
- if ((unsigned int)(reg - PCM1796_REG_BASE)
- < ARRAY_SIZE(data->pcm1796_regs[codec]))
- data->pcm1796_regs[codec][reg - PCM1796_REG_BASE] = value;
-}
-
-static void pcm1796_write_cached(struct oxygen *chip, unsigned int codec,
- u8 reg, u8 value)
-{
- struct xonar_pcm179x *data = chip->model_data;
-
- if (value != data->pcm1796_regs[codec][reg - PCM1796_REG_BASE])
- pcm1796_write(chip, codec, reg, value);
-}
-
-static void cs2000_write(struct oxygen *chip, u8 reg, u8 value)
-{
- struct xonar_pcm179x *data = chip->model_data;
-
- oxygen_write_i2c(chip, I2C_DEVICE_CS2000, reg, value);
- data->cs2000_regs[reg] = value;
-}
-
-static void cs2000_write_cached(struct oxygen *chip, u8 reg, u8 value)
-{
- struct xonar_pcm179x *data = chip->model_data;
-
- if (value != data->cs2000_regs[reg])
- cs2000_write(chip, reg, value);
-}
-
-static void pcm1796_registers_init(struct oxygen *chip)
-{
- struct xonar_pcm179x *data = chip->model_data;
- unsigned int i;
- s8 gain_offset;
-
- msleep(1);
- gain_offset = data->hp_active ? data->hp_gain_offset : 0;
- for (i = 0; i < data->dacs; ++i) {
- /* set ATLD before ATL/ATR */
- pcm1796_write(chip, i, 18,
- data->pcm1796_regs[0][18 - PCM1796_REG_BASE]);
- pcm1796_write(chip, i, 16, chip->dac_volume[i * 2]
- + gain_offset);
- pcm1796_write(chip, i, 17, chip->dac_volume[i * 2 + 1]
- + gain_offset);
- pcm1796_write(chip, i, 19,
- data->pcm1796_regs[0][19 - PCM1796_REG_BASE]);
- pcm1796_write(chip, i, 20,
- data->pcm1796_regs[0][20 - PCM1796_REG_BASE]);
- pcm1796_write(chip, i, 21, 0);
- gain_offset = 0;
- }
-}
-
-static void pcm1796_init(struct oxygen *chip)
-{
- struct xonar_pcm179x *data = chip->model_data;
-
- data->pcm1796_regs[0][18 - PCM1796_REG_BASE] =
- PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD;
- if (!data->broken_i2c)
- data->pcm1796_regs[0][18 - PCM1796_REG_BASE] |= PCM1796_MUTE;
- data->pcm1796_regs[0][19 - PCM1796_REG_BASE] =
- PCM1796_FLT_SHARP | PCM1796_ATS_1;
- data->pcm1796_regs[0][20 - PCM1796_REG_BASE] =
- data->h6 ? PCM1796_OS_64 : PCM1796_OS_128;
- pcm1796_registers_init(chip);
- data->current_rate = 48000;
-}
-
-static void xonar_d2_init(struct oxygen *chip)
-{
- struct xonar_pcm179x *data = chip->model_data;
-
- data->generic.anti_pop_delay = 300;
- data->generic.output_enable_bit = GPIO_D2_OUTPUT_ENABLE;
- data->dacs = 4;
-
- pcm1796_init(chip);
-
- oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2_ALT);
- oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_D2_ALT);
-
- oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC);
-
- xonar_init_cs53x1(chip);
- xonar_enable_output(chip);
-
- snd_component_add(chip->card, "PCM1796");
- snd_component_add(chip->card, "CS5381");
-}
-
-static void xonar_d2x_init(struct oxygen *chip)
-{
- struct xonar_pcm179x *data = chip->model_data;
-
- data->generic.ext_power_reg = OXYGEN_GPIO_DATA;
- data->generic.ext_power_int_reg = OXYGEN_GPIO_INTERRUPT_MASK;
- data->generic.ext_power_bit = GPIO_D2X_EXT_POWER;
- oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2X_EXT_POWER);
- xonar_init_ext_power(chip);
- xonar_d2_init(chip);
-}
-
-static void xonar_hdav_init(struct oxygen *chip)
-{
- struct xonar_hdav *data = chip->model_data;
-
- oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
- OXYGEN_2WIRE_LENGTH_8 |
- OXYGEN_2WIRE_INTERRUPT_MASK |
- OXYGEN_2WIRE_SPEED_STANDARD);
-
- data->pcm179x.generic.anti_pop_delay = 100;
- data->pcm179x.generic.output_enable_bit = GPIO_HDAV_OUTPUT_ENABLE;
- data->pcm179x.generic.ext_power_reg = OXYGEN_GPI_DATA;
- data->pcm179x.generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
- data->pcm179x.generic.ext_power_bit = GPI_EXT_POWER;
- data->pcm179x.dacs = chip->model.dac_channels_mixer / 2;
- data->pcm179x.h6 = chip->model.dac_channels_mixer > 2;
-
- pcm1796_init(chip);
-
- oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
- GPIO_HDAV_MAGIC | GPIO_INPUT_ROUTE);
- oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_INPUT_ROUTE);
-
- xonar_init_cs53x1(chip);
- xonar_init_ext_power(chip);
- xonar_hdmi_init(chip, &data->hdmi);
- xonar_enable_output(chip);
-
- snd_component_add(chip->card, "PCM1796");
- snd_component_add(chip->card, "CS5381");
-}
-
-static void xonar_st_init_i2c(struct oxygen *chip)
-{
- oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
- OXYGEN_2WIRE_LENGTH_8 |
- OXYGEN_2WIRE_INTERRUPT_MASK |
- OXYGEN_2WIRE_SPEED_STANDARD);
-}
-
-static void xonar_st_init_common(struct oxygen *chip)
-{
- struct xonar_pcm179x *data = chip->model_data;
-
- data->generic.output_enable_bit = GPIO_ST_OUTPUT_ENABLE;
- data->dacs = chip->model.dac_channels_mixer / 2;
- data->hp_gain_offset = 2*-18;
-
- pcm1796_init(chip);
-
- oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
- GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR |
- GPIO_ST_MAGIC | GPIO_ST_HP);
- oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
- GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP);
-
- xonar_init_cs53x1(chip);
- xonar_enable_output(chip);
-
- snd_component_add(chip->card, "PCM1792A");
- snd_component_add(chip->card, "CS5381");
-}
-
-static void cs2000_registers_init(struct oxygen *chip)
-{
- struct xonar_pcm179x *data = chip->model_data;
-
- cs2000_write(chip, CS2000_GLOBAL_CFG, CS2000_FREEZE);
- cs2000_write(chip, CS2000_DEV_CTRL, 0);
- cs2000_write(chip, CS2000_DEV_CFG_1,
- CS2000_R_MOD_SEL_1 |
- (0 << CS2000_R_SEL_SHIFT) |
- CS2000_AUX_OUT_SRC_REF_CLK |
- CS2000_EN_DEV_CFG_1);
- cs2000_write(chip, CS2000_DEV_CFG_2,
- (0 << CS2000_LOCK_CLK_SHIFT) |
- CS2000_FRAC_N_SRC_STATIC);
- cs2000_write(chip, CS2000_RATIO_0 + 0, 0x00); /* 1.0 */
- cs2000_write(chip, CS2000_RATIO_0 + 1, 0x10);
- cs2000_write(chip, CS2000_RATIO_0 + 2, 0x00);
- cs2000_write(chip, CS2000_RATIO_0 + 3, 0x00);
- cs2000_write(chip, CS2000_FUN_CFG_1,
- data->cs2000_regs[CS2000_FUN_CFG_1]);
- cs2000_write(chip, CS2000_FUN_CFG_2, 0);
- cs2000_write(chip, CS2000_GLOBAL_CFG, CS2000_EN_DEV_CFG_2);
- msleep(3); /* PLL lock delay */
-}
-
-static void xonar_st_init(struct oxygen *chip)
-{
- struct xonar_pcm179x *data = chip->model_data;
-
- data->generic.anti_pop_delay = 100;
- data->h6 = chip->model.dac_channels_mixer > 2;
- data->has_cs2000 = 1;
- data->cs2000_regs[CS2000_FUN_CFG_1] = CS2000_REF_CLK_DIV_1;
- data->broken_i2c = true;
-
- oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
- OXYGEN_RATE_48000 |
- OXYGEN_I2S_FORMAT_I2S |
- OXYGEN_I2S_MCLK(data->h6 ? MCLK_256 : MCLK_512) |
- OXYGEN_I2S_BITS_16 |
- OXYGEN_I2S_MASTER |
- OXYGEN_I2S_BCLK_64);
-
- xonar_st_init_i2c(chip);
- cs2000_registers_init(chip);
- xonar_st_init_common(chip);
-
- snd_component_add(chip->card, "CS2000");
-}
-
-static void xonar_stx_init(struct oxygen *chip)
-{
- struct xonar_pcm179x *data = chip->model_data;
-
- xonar_st_init_i2c(chip);
- data->generic.anti_pop_delay = 800;
- data->generic.ext_power_reg = OXYGEN_GPI_DATA;
- data->generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
- data->generic.ext_power_bit = GPI_EXT_POWER;
- xonar_init_ext_power(chip);
- xonar_st_init_common(chip);
-}
-
-static void xonar_d2_cleanup(struct oxygen *chip)
-{
- xonar_disable_output(chip);
-}
-
-static void xonar_hdav_cleanup(struct oxygen *chip)
-{
- xonar_hdmi_cleanup(chip);
- xonar_disable_output(chip);
- msleep(2);
-}
-
-static void xonar_st_cleanup(struct oxygen *chip)
-{
- xonar_disable_output(chip);
-}
-
-static void xonar_d2_suspend(struct oxygen *chip)
-{
- xonar_d2_cleanup(chip);
-}
-
-static void xonar_hdav_suspend(struct oxygen *chip)
-{
- xonar_hdav_cleanup(chip);
-}
-
-static void xonar_st_suspend(struct oxygen *chip)
-{
- xonar_st_cleanup(chip);
-}
-
-static void xonar_d2_resume(struct oxygen *chip)
-{
- pcm1796_registers_init(chip);
- xonar_enable_output(chip);
-}
-
-static void xonar_hdav_resume(struct oxygen *chip)
-{
- struct xonar_hdav *data = chip->model_data;
-
- pcm1796_registers_init(chip);
- xonar_hdmi_resume(chip, &data->hdmi);
- xonar_enable_output(chip);
-}
-
-static void xonar_stx_resume(struct oxygen *chip)
-{
- pcm1796_registers_init(chip);
- xonar_enable_output(chip);
-}
-
-static void xonar_st_resume(struct oxygen *chip)
-{
- cs2000_registers_init(chip);
- xonar_stx_resume(chip);
-}
-
-static void update_pcm1796_oversampling(struct oxygen *chip)
-{
- struct xonar_pcm179x *data = chip->model_data;
- unsigned int i;
- u8 reg;
-
- if (data->current_rate <= 48000 && !data->h6)
- reg = PCM1796_OS_128;
- else
- reg = PCM1796_OS_64;
- for (i = 0; i < data->dacs; ++i)
- pcm1796_write_cached(chip, i, 20, reg);
-}
-
-static void set_pcm1796_params(struct oxygen *chip,
- struct snd_pcm_hw_params *params)
-{
- struct xonar_pcm179x *data = chip->model_data;
-
- msleep(1);
- data->current_rate = params_rate(params);
- update_pcm1796_oversampling(chip);
-}
-
-static void update_pcm1796_volume(struct oxygen *chip)
-{
- struct xonar_pcm179x *data = chip->model_data;
- unsigned int i;
- s8 gain_offset;
-
- gain_offset = data->hp_active ? data->hp_gain_offset : 0;
- for (i = 0; i < data->dacs; ++i) {
- pcm1796_write_cached(chip, i, 16, chip->dac_volume[i * 2]
- + gain_offset);
- pcm1796_write_cached(chip, i, 17, chip->dac_volume[i * 2 + 1]
- + gain_offset);
- gain_offset = 0;
- }
-}
-
-static void update_pcm1796_mute(struct oxygen *chip)
-{
- struct xonar_pcm179x *data = chip->model_data;
- unsigned int i;
- u8 value;
-
- value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD;
- if (chip->dac_mute)
- value |= PCM1796_MUTE;
- for (i = 0; i < data->dacs; ++i)
- pcm1796_write_cached(chip, i, 18, value);
-}
-
-static void update_cs2000_rate(struct oxygen *chip, unsigned int rate)
-{
- struct xonar_pcm179x *data = chip->model_data;
- u8 rate_mclk, reg;
-
- switch (rate) {
- case 32000:
- case 64000:
- rate_mclk = OXYGEN_RATE_32000;
- break;
- case 44100:
- case 88200:
- case 176400:
- rate_mclk = OXYGEN_RATE_44100;
- break;
- default:
- case 48000:
- case 96000:
- case 192000:
- rate_mclk = OXYGEN_RATE_48000;
- break;
- }
-
- if (rate <= 96000 && (rate > 48000 || data->h6)) {
- rate_mclk |= OXYGEN_I2S_MCLK(MCLK_256);
- reg = CS2000_REF_CLK_DIV_1;
- } else {
- rate_mclk |= OXYGEN_I2S_MCLK(MCLK_512);
- reg = CS2000_REF_CLK_DIV_2;
- }
-
- oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, rate_mclk,
- OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_MCLK_MASK);
- cs2000_write_cached(chip, CS2000_FUN_CFG_1, reg);
- msleep(3); /* PLL lock delay */
-}
-
-static void set_st_params(struct oxygen *chip,
- struct snd_pcm_hw_params *params)
-{
- update_cs2000_rate(chip, params_rate(params));
- set_pcm1796_params(chip, params);
-}
-
-static void set_hdav_params(struct oxygen *chip,
- struct snd_pcm_hw_params *params)
-{
- struct xonar_hdav *data = chip->model_data;
-
- set_pcm1796_params(chip, params);
- xonar_set_hdmi_params(chip, &data->hdmi, params);
-}
-
-static const struct snd_kcontrol_new alt_switch = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Loopback Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = xonar_gpio_bit_switch_get,
- .put = xonar_gpio_bit_switch_put,
- .private_value = GPIO_D2_ALT,
-};
-
-static int rolloff_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- static const char *const names[2] = {
- "Sharp Roll-off", "Slow Roll-off"
- };
-
- return snd_ctl_enum_info(info, 1, 2, names);
-}
-
-static int rolloff_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct xonar_pcm179x *data = chip->model_data;
-
- value->value.enumerated.item[0] =
- (data->pcm1796_regs[0][19 - PCM1796_REG_BASE] &
- PCM1796_FLT_MASK) != PCM1796_FLT_SHARP;
- return 0;
-}
-
-static int rolloff_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct xonar_pcm179x *data = chip->model_data;
- unsigned int i;
- int changed;
- u8 reg;
-
- mutex_lock(&chip->mutex);
- reg = data->pcm1796_regs[0][19 - PCM1796_REG_BASE];
- reg &= ~PCM1796_FLT_MASK;
- if (!value->value.enumerated.item[0])
- reg |= PCM1796_FLT_SHARP;
- else
- reg |= PCM1796_FLT_SLOW;
- changed = reg != data->pcm1796_regs[0][19 - PCM1796_REG_BASE];
- if (changed) {
- for (i = 0; i < data->dacs; ++i)
- pcm1796_write(chip, i, 19, reg);
- }
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static const struct snd_kcontrol_new rolloff_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "DAC Filter Playback Enum",
- .info = rolloff_info,
- .get = rolloff_get,
- .put = rolloff_put,
-};
-
-static const struct snd_kcontrol_new hdav_hdmi_control = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "HDMI Playback Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = xonar_gpio_bit_switch_get,
- .put = xonar_gpio_bit_switch_put,
- .private_value = GPIO_HDAV_OUTPUT_ENABLE | XONAR_GPIO_BIT_INVERT,
-};
-
-static int st_output_switch_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- static const char *const names[3] = {
- "Speakers", "Headphones", "FP Headphones"
- };
-
- return snd_ctl_enum_info(info, 1, 3, names);
-}
-
-static int st_output_switch_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- u16 gpio;
-
- gpio = oxygen_read16(chip, OXYGEN_GPIO_DATA);
- if (!(gpio & GPIO_ST_HP))
- value->value.enumerated.item[0] = 0;
- else if (gpio & GPIO_ST_HP_REAR)
- value->value.enumerated.item[0] = 1;
- else
- value->value.enumerated.item[0] = 2;
- return 0;
-}
-
-
-static int st_output_switch_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct xonar_pcm179x *data = chip->model_data;
- u16 gpio_old, gpio;
-
- mutex_lock(&chip->mutex);
- gpio_old = oxygen_read16(chip, OXYGEN_GPIO_DATA);
- gpio = gpio_old;
- switch (value->value.enumerated.item[0]) {
- case 0:
- gpio &= ~(GPIO_ST_HP | GPIO_ST_HP_REAR);
- break;
- case 1:
- gpio |= GPIO_ST_HP | GPIO_ST_HP_REAR;
- break;
- case 2:
- gpio = (gpio | GPIO_ST_HP) & ~GPIO_ST_HP_REAR;
- break;
- }
- oxygen_write16(chip, OXYGEN_GPIO_DATA, gpio);
- data->hp_active = gpio & GPIO_ST_HP;
- update_pcm1796_volume(chip);
- mutex_unlock(&chip->mutex);
- return gpio != gpio_old;
-}
-
-static int st_hp_volume_offset_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- static const char *const names[3] = {
- "< 64 ohms", "64-300 ohms", "300-600 ohms"
- };
-
- return snd_ctl_enum_info(info, 1, 3, names);
-}
-
-static int st_hp_volume_offset_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct xonar_pcm179x *data = chip->model_data;
-
- mutex_lock(&chip->mutex);
- if (data->hp_gain_offset < 2*-6)
- value->value.enumerated.item[0] = 0;
- else if (data->hp_gain_offset < 0)
- value->value.enumerated.item[0] = 1;
- else
- value->value.enumerated.item[0] = 2;
- mutex_unlock(&chip->mutex);
- return 0;
-}
-
-
-static int st_hp_volume_offset_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- static const s8 offsets[] = { 2*-18, 2*-6, 0 };
- struct oxygen *chip = ctl->private_data;
- struct xonar_pcm179x *data = chip->model_data;
- s8 offset;
- int changed;
-
- if (value->value.enumerated.item[0] > 2)
- return -EINVAL;
- offset = offsets[value->value.enumerated.item[0]];
- mutex_lock(&chip->mutex);
- changed = offset != data->hp_gain_offset;
- if (changed) {
- data->hp_gain_offset = offset;
- update_pcm1796_volume(chip);
- }
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static const struct snd_kcontrol_new st_controls[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Output",
- .info = st_output_switch_info,
- .get = st_output_switch_get,
- .put = st_output_switch_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Headphones Impedance Playback Enum",
- .info = st_hp_volume_offset_info,
- .get = st_hp_volume_offset_get,
- .put = st_hp_volume_offset_put,
- },
-};
-
-static void xonar_line_mic_ac97_switch(struct oxygen *chip,
- unsigned int reg, unsigned int mute)
-{
- if (reg == AC97_LINE) {
- spin_lock_irq(&chip->reg_lock);
- oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
- mute ? GPIO_INPUT_ROUTE : 0,
- GPIO_INPUT_ROUTE);
- spin_unlock_irq(&chip->reg_lock);
- }
-}
-
-static const DECLARE_TLV_DB_SCALE(pcm1796_db_scale, -6000, 50, 0);
-
-static int xonar_d2_control_filter(struct snd_kcontrol_new *template)
-{
- if (!strncmp(template->name, "CD Capture ", 11))
- /* CD in is actually connected to the video in pin */
- template->private_value ^= AC97_CD ^ AC97_VIDEO;
- return 0;
-}
-
-static int xonar_st_h6_control_filter(struct snd_kcontrol_new *template)
-{
- if (!strncmp(template->name, "Master Playback ", 16))
- /* no volume/mute, as I²C to the third DAC does not work */
- return 1;
- return 0;
-}
-
-static int add_pcm1796_controls(struct oxygen *chip)
-{
- struct xonar_pcm179x *data = chip->model_data;
- int err;
-
- if (!data->broken_i2c) {
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&rolloff_control, chip));
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-static int xonar_d2_mixer_init(struct oxygen *chip)
-{
- int err;
-
- err = snd_ctl_add(chip->card, snd_ctl_new1(&alt_switch, chip));
- if (err < 0)
- return err;
- err = add_pcm1796_controls(chip);
- if (err < 0)
- return err;
- return 0;
-}
-
-static int xonar_hdav_mixer_init(struct oxygen *chip)
-{
- int err;
-
- err = snd_ctl_add(chip->card, snd_ctl_new1(&hdav_hdmi_control, chip));
- if (err < 0)
- return err;
- err = add_pcm1796_controls(chip);
- if (err < 0)
- return err;
- return 0;
-}
-
-static int xonar_st_mixer_init(struct oxygen *chip)
-{
- unsigned int i;
- int err;
-
- for (i = 0; i < ARRAY_SIZE(st_controls); ++i) {
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&st_controls[i], chip));
- if (err < 0)
- return err;
- }
- err = add_pcm1796_controls(chip);
- if (err < 0)
- return err;
- return 0;
-}
-
-static void dump_pcm1796_registers(struct oxygen *chip,
- struct snd_info_buffer *buffer)
-{
- struct xonar_pcm179x *data = chip->model_data;
- unsigned int dac, i;
-
- for (dac = 0; dac < data->dacs; ++dac) {
- snd_iprintf(buffer, "\nPCM1796 %u:", dac + 1);
- for (i = 0; i < 5; ++i)
- snd_iprintf(buffer, " %02x",
- data->pcm1796_regs[dac][i]);
- }
- snd_iprintf(buffer, "\n");
-}
-
-static void dump_cs2000_registers(struct oxygen *chip,
- struct snd_info_buffer *buffer)
-{
- struct xonar_pcm179x *data = chip->model_data;
- unsigned int i;
-
- if (data->has_cs2000) {
- snd_iprintf(buffer, "\nCS2000:\n00: ");
- for (i = 1; i < 0x10; ++i)
- snd_iprintf(buffer, " %02x", data->cs2000_regs[i]);
- snd_iprintf(buffer, "\n10:");
- for (i = 0x10; i < 0x1f; ++i)
- snd_iprintf(buffer, " %02x", data->cs2000_regs[i]);
- snd_iprintf(buffer, "\n");
- }
-}
-
-static void dump_st_registers(struct oxygen *chip,
- struct snd_info_buffer *buffer)
-{
- dump_pcm1796_registers(chip, buffer);
- dump_cs2000_registers(chip, buffer);
-}
-
-static const struct oxygen_model model_xonar_d2 = {
- .longname = "Asus Virtuoso 200",
- .chip = "AV200",
- .init = xonar_d2_init,
- .control_filter = xonar_d2_control_filter,
- .mixer_init = xonar_d2_mixer_init,
- .cleanup = xonar_d2_cleanup,
- .suspend = xonar_d2_suspend,
- .resume = xonar_d2_resume,
- .set_dac_params = set_pcm1796_params,
- .set_adc_params = xonar_set_cs53x1_params,
- .update_dac_volume = update_pcm1796_volume,
- .update_dac_mute = update_pcm1796_mute,
- .dump_registers = dump_pcm1796_registers,
- .dac_tlv = pcm1796_db_scale,
- .model_data_size = sizeof(struct xonar_pcm179x),
- .device_config = PLAYBACK_0_TO_I2S |
- PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_2 |
- CAPTURE_1_FROM_SPDIF |
- MIDI_OUTPUT |
- MIDI_INPUT |
- AC97_CD_INPUT,
- .dac_channels_pcm = 8,
- .dac_channels_mixer = 8,
- .dac_volume_min = 255 - 2*60,
- .dac_volume_max = 255,
- .misc_flags = OXYGEN_MISC_MIDI,
- .function_flags = OXYGEN_FUNCTION_SPI |
- OXYGEN_FUNCTION_ENABLE_SPI_4_5,
- .dac_mclks = OXYGEN_MCLKS(512, 128, 128),
- .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
- .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S,
- .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
-};
-
-static const struct oxygen_model model_xonar_hdav = {
- .longname = "Asus Virtuoso 200",
- .chip = "AV200",
- .init = xonar_hdav_init,
- .mixer_init = xonar_hdav_mixer_init,
- .cleanup = xonar_hdav_cleanup,
- .suspend = xonar_hdav_suspend,
- .resume = xonar_hdav_resume,
- .pcm_hardware_filter = xonar_hdmi_pcm_hardware_filter,
- .set_dac_params = set_hdav_params,
- .set_adc_params = xonar_set_cs53x1_params,
- .update_dac_volume = update_pcm1796_volume,
- .update_dac_mute = update_pcm1796_mute,
- .uart_input = xonar_hdmi_uart_input,
- .ac97_switch = xonar_line_mic_ac97_switch,
- .dump_registers = dump_pcm1796_registers,
- .dac_tlv = pcm1796_db_scale,
- .model_data_size = sizeof(struct xonar_hdav),
- .device_config = PLAYBACK_0_TO_I2S |
- PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_2 |
- CAPTURE_1_FROM_SPDIF,
- .dac_channels_pcm = 8,
- .dac_channels_mixer = 2,
- .dac_volume_min = 255 - 2*60,
- .dac_volume_max = 255,
- .misc_flags = OXYGEN_MISC_MIDI,
- .function_flags = OXYGEN_FUNCTION_2WIRE,
- .dac_mclks = OXYGEN_MCLKS(512, 128, 128),
- .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
- .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S,
- .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
-};
-
-static const struct oxygen_model model_xonar_st = {
- .longname = "Asus Virtuoso 100",
- .chip = "AV200",
- .init = xonar_st_init,
- .mixer_init = xonar_st_mixer_init,
- .cleanup = xonar_st_cleanup,
- .suspend = xonar_st_suspend,
- .resume = xonar_st_resume,
- .set_dac_params = set_st_params,
- .set_adc_params = xonar_set_cs53x1_params,
- .update_dac_volume = update_pcm1796_volume,
- .update_dac_mute = update_pcm1796_mute,
- .ac97_switch = xonar_line_mic_ac97_switch,
- .dump_registers = dump_st_registers,
- .dac_tlv = pcm1796_db_scale,
- .model_data_size = sizeof(struct xonar_pcm179x),
- .device_config = PLAYBACK_0_TO_I2S |
- PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_2 |
- CAPTURE_1_FROM_SPDIF |
- AC97_FMIC_SWITCH,
- .dac_channels_pcm = 2,
- .dac_channels_mixer = 2,
- .dac_volume_min = 255 - 2*60,
- .dac_volume_max = 255,
- .function_flags = OXYGEN_FUNCTION_2WIRE,
- .dac_mclks = OXYGEN_MCLKS(512, 128, 128),
- .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
- .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S,
- .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
-};
-
-int __devinit get_xonar_pcm179x_model(struct oxygen *chip,
- const struct pci_device_id *id)
-{
- switch (id->subdevice) {
- case 0x8269:
- chip->model = model_xonar_d2;
- chip->model.shortname = "Xonar D2";
- break;
- case 0x82b7:
- chip->model = model_xonar_d2;
- chip->model.shortname = "Xonar D2X";
- chip->model.init = xonar_d2x_init;
- break;
- case 0x8314:
- chip->model = model_xonar_hdav;
- oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_DB_MASK);
- switch (oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_DB_MASK) {
- default:
- chip->model.shortname = "Xonar HDAV1.3";
- break;
- case GPIO_DB_H6:
- chip->model.shortname = "Xonar HDAV1.3+H6";
- chip->model.dac_channels_mixer = 8;
- chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128);
- break;
- }
- break;
- case 0x835d:
- chip->model = model_xonar_st;
- oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_DB_MASK);
- switch (oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_DB_MASK) {
- default:
- chip->model.shortname = "Xonar ST";
- break;
- case GPIO_DB_H6:
- chip->model.shortname = "Xonar ST+H6";
- chip->model.control_filter = xonar_st_h6_control_filter;
- chip->model.dac_channels_pcm = 8;
- chip->model.dac_channels_mixer = 8;
- chip->model.dac_volume_min = 255;
- chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128);
- break;
- }
- break;
- case 0x835c:
- chip->model = model_xonar_st;
- chip->model.shortname = "Xonar STX";
- chip->model.init = xonar_stx_init;
- chip->model.resume = xonar_stx_resume;
- chip->model.set_dac_params = set_pcm1796_params;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/oxygen/xonar_wm87x6.c b/ANDROID_3.4.5/sound/pci/oxygen/xonar_wm87x6.c
deleted file mode 100644
index 63cff907..00000000
--- a/ANDROID_3.4.5/sound/pci/oxygen/xonar_wm87x6.c
+++ /dev/null
@@ -1,1338 +0,0 @@
-/*
- * card driver for models with WM8776/WM8766 DACs (Xonar DS/HDAV1.3 Slim)
- *
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- *
- *
- * This driver is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this driver; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * Xonar DS
- * --------
- *
- * CMI8788:
- *
- * SPI 0 -> WM8766 (surround, center/LFE, back)
- * SPI 1 -> WM8776 (front, input)
- *
- * GPIO 4 <- headphone detect, 0 = plugged
- * GPIO 6 -> route input jack to mic-in (0) or line-in (1)
- * GPIO 7 -> enable output to front L/R speaker channels
- * GPIO 8 -> enable output to other speaker channels and front panel headphone
- *
- * WM8776:
- *
- * input 1 <- line
- * input 2 <- mic
- * input 3 <- front mic
- * input 4 <- aux
- */
-
-/*
- * Xonar HDAV1.3 Slim
- * ------------------
- *
- * CMI8788:
- *
- * I²C <-> WM8776 (addr 0011010)
- *
- * GPIO 0 -> disable HDMI output
- * GPIO 1 -> enable HP output
- * GPIO 6 -> firmware EEPROM I²C clock
- * GPIO 7 <-> firmware EEPROM I²C data
- *
- * UART <-> HDMI controller
- *
- * WM8776:
- *
- * input 1 <- mic
- * input 2 <- aux
- */
-
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/jack.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/tlv.h>
-#include "xonar.h"
-#include "wm8776.h"
-#include "wm8766.h"
-
-#define GPIO_DS_HP_DETECT 0x0010
-#define GPIO_DS_INPUT_ROUTE 0x0040
-#define GPIO_DS_OUTPUT_FRONTLR 0x0080
-#define GPIO_DS_OUTPUT_ENABLE 0x0100
-
-#define GPIO_SLIM_HDMI_DISABLE 0x0001
-#define GPIO_SLIM_OUTPUT_ENABLE 0x0002
-#define GPIO_SLIM_FIRMWARE_CLK 0x0040
-#define GPIO_SLIM_FIRMWARE_DATA 0x0080
-
-#define I2C_DEVICE_WM8776 0x34 /* 001101, 0, /W=0 */
-
-#define LC_CONTROL_LIMITER 0x40000000
-#define LC_CONTROL_ALC 0x20000000
-
-struct xonar_wm87x6 {
- struct xonar_generic generic;
- u16 wm8776_regs[0x17];
- u16 wm8766_regs[0x10];
- struct snd_kcontrol *line_adcmux_control;
- struct snd_kcontrol *mic_adcmux_control;
- struct snd_kcontrol *lc_controls[13];
- struct snd_jack *hp_jack;
- struct xonar_hdmi hdmi;
-};
-
-static void wm8776_write_spi(struct oxygen *chip,
- unsigned int reg, unsigned int value)
-{
- oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
- OXYGEN_SPI_DATA_LENGTH_2 |
- OXYGEN_SPI_CLOCK_160 |
- (1 << OXYGEN_SPI_CODEC_SHIFT) |
- OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
- (reg << 9) | value);
-}
-
-static void wm8776_write_i2c(struct oxygen *chip,
- unsigned int reg, unsigned int value)
-{
- oxygen_write_i2c(chip, I2C_DEVICE_WM8776,
- (reg << 1) | (value >> 8), value);
-}
-
-static void wm8776_write(struct oxygen *chip,
- unsigned int reg, unsigned int value)
-{
- struct xonar_wm87x6 *data = chip->model_data;
-
- if ((chip->model.function_flags & OXYGEN_FUNCTION_2WIRE_SPI_MASK) ==
- OXYGEN_FUNCTION_SPI)
- wm8776_write_spi(chip, reg, value);
- else
- wm8776_write_i2c(chip, reg, value);
- if (reg < ARRAY_SIZE(data->wm8776_regs)) {
- if (reg >= WM8776_HPLVOL && reg <= WM8776_DACMASTER)
- value &= ~WM8776_UPDATE;
- data->wm8776_regs[reg] = value;
- }
-}
-
-static void wm8776_write_cached(struct oxygen *chip,
- unsigned int reg, unsigned int value)
-{
- struct xonar_wm87x6 *data = chip->model_data;
-
- if (reg >= ARRAY_SIZE(data->wm8776_regs) ||
- value != data->wm8776_regs[reg])
- wm8776_write(chip, reg, value);
-}
-
-static void wm8766_write(struct oxygen *chip,
- unsigned int reg, unsigned int value)
-{
- struct xonar_wm87x6 *data = chip->model_data;
-
- oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
- OXYGEN_SPI_DATA_LENGTH_2 |
- OXYGEN_SPI_CLOCK_160 |
- (0 << OXYGEN_SPI_CODEC_SHIFT) |
- OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
- (reg << 9) | value);
- if (reg < ARRAY_SIZE(data->wm8766_regs)) {
- if ((reg >= WM8766_LDA1 && reg <= WM8766_RDA1) ||
- (reg >= WM8766_LDA2 && reg <= WM8766_MASTDA))
- value &= ~WM8766_UPDATE;
- data->wm8766_regs[reg] = value;
- }
-}
-
-static void wm8766_write_cached(struct oxygen *chip,
- unsigned int reg, unsigned int value)
-{
- struct xonar_wm87x6 *data = chip->model_data;
-
- if (reg >= ARRAY_SIZE(data->wm8766_regs) ||
- value != data->wm8766_regs[reg])
- wm8766_write(chip, reg, value);
-}
-
-static void wm8776_registers_init(struct oxygen *chip)
-{
- struct xonar_wm87x6 *data = chip->model_data;
-
- wm8776_write(chip, WM8776_RESET, 0);
- wm8776_write(chip, WM8776_PHASESWAP, WM8776_PH_MASK);
- wm8776_write(chip, WM8776_DACCTRL1, WM8776_DZCEN |
- WM8776_PL_LEFT_LEFT | WM8776_PL_RIGHT_RIGHT);
- wm8776_write(chip, WM8776_DACMUTE, chip->dac_mute ? WM8776_DMUTE : 0);
- wm8776_write(chip, WM8776_DACIFCTRL,
- WM8776_DACFMT_LJUST | WM8776_DACWL_24);
- wm8776_write(chip, WM8776_ADCIFCTRL,
- data->wm8776_regs[WM8776_ADCIFCTRL]);
- wm8776_write(chip, WM8776_MSTRCTRL, data->wm8776_regs[WM8776_MSTRCTRL]);
- wm8776_write(chip, WM8776_PWRDOWN, data->wm8776_regs[WM8776_PWRDOWN]);
- wm8776_write(chip, WM8776_HPLVOL, data->wm8776_regs[WM8776_HPLVOL]);
- wm8776_write(chip, WM8776_HPRVOL, data->wm8776_regs[WM8776_HPRVOL] |
- WM8776_UPDATE);
- wm8776_write(chip, WM8776_ADCLVOL, data->wm8776_regs[WM8776_ADCLVOL]);
- wm8776_write(chip, WM8776_ADCRVOL, data->wm8776_regs[WM8776_ADCRVOL]);
- wm8776_write(chip, WM8776_ADCMUX, data->wm8776_regs[WM8776_ADCMUX]);
- wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0]);
- wm8776_write(chip, WM8776_DACRVOL, chip->dac_volume[1] | WM8776_UPDATE);
-}
-
-static void wm8766_registers_init(struct oxygen *chip)
-{
- struct xonar_wm87x6 *data = chip->model_data;
-
- wm8766_write(chip, WM8766_RESET, 0);
- wm8766_write(chip, WM8766_DAC_CTRL, data->wm8766_regs[WM8766_DAC_CTRL]);
- wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24);
- wm8766_write(chip, WM8766_DAC_CTRL2,
- WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
- wm8766_write(chip, WM8766_LDA1, chip->dac_volume[2]);
- wm8766_write(chip, WM8766_RDA1, chip->dac_volume[3]);
- wm8766_write(chip, WM8766_LDA2, chip->dac_volume[4]);
- wm8766_write(chip, WM8766_RDA2, chip->dac_volume[5]);
- wm8766_write(chip, WM8766_LDA3, chip->dac_volume[6]);
- wm8766_write(chip, WM8766_RDA3, chip->dac_volume[7] | WM8766_UPDATE);
-}
-
-static void wm8776_init(struct oxygen *chip)
-{
- struct xonar_wm87x6 *data = chip->model_data;
-
- data->wm8776_regs[WM8776_HPLVOL] = (0x79 - 60) | WM8776_HPZCEN;
- data->wm8776_regs[WM8776_HPRVOL] = (0x79 - 60) | WM8776_HPZCEN;
- data->wm8776_regs[WM8776_ADCIFCTRL] =
- WM8776_ADCFMT_LJUST | WM8776_ADCWL_24 | WM8776_ADCMCLK;
- data->wm8776_regs[WM8776_MSTRCTRL] =
- WM8776_ADCRATE_256 | WM8776_DACRATE_256;
- data->wm8776_regs[WM8776_PWRDOWN] = WM8776_HPPD;
- data->wm8776_regs[WM8776_ADCLVOL] = 0xa5 | WM8776_ZCA;
- data->wm8776_regs[WM8776_ADCRVOL] = 0xa5 | WM8776_ZCA;
- data->wm8776_regs[WM8776_ADCMUX] = 0x001;
- wm8776_registers_init(chip);
-}
-
-static void wm8766_init(struct oxygen *chip)
-{
- struct xonar_wm87x6 *data = chip->model_data;
-
- data->wm8766_regs[WM8766_DAC_CTRL] =
- WM8766_PL_LEFT_LEFT | WM8766_PL_RIGHT_RIGHT;
- wm8766_registers_init(chip);
-}
-
-static void xonar_ds_handle_hp_jack(struct oxygen *chip)
-{
- struct xonar_wm87x6 *data = chip->model_data;
- bool hp_plugged;
- unsigned int reg;
-
- mutex_lock(&chip->mutex);
-
- hp_plugged = !(oxygen_read16(chip, OXYGEN_GPIO_DATA) &
- GPIO_DS_HP_DETECT);
-
- oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
- hp_plugged ? 0 : GPIO_DS_OUTPUT_FRONTLR,
- GPIO_DS_OUTPUT_FRONTLR);
-
- reg = data->wm8766_regs[WM8766_DAC_CTRL] & ~WM8766_MUTEALL;
- if (hp_plugged)
- reg |= WM8766_MUTEALL;
- wm8766_write_cached(chip, WM8766_DAC_CTRL, reg);
-
- snd_jack_report(data->hp_jack, hp_plugged ? SND_JACK_HEADPHONE : 0);
-
- mutex_unlock(&chip->mutex);
-}
-
-static void xonar_ds_init(struct oxygen *chip)
-{
- struct xonar_wm87x6 *data = chip->model_data;
-
- data->generic.anti_pop_delay = 300;
- data->generic.output_enable_bit = GPIO_DS_OUTPUT_ENABLE;
-
- wm8776_init(chip);
- wm8766_init(chip);
-
- oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
- GPIO_DS_INPUT_ROUTE | GPIO_DS_OUTPUT_FRONTLR);
- oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
- GPIO_DS_HP_DETECT);
- oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DS_INPUT_ROUTE);
- oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_DS_HP_DETECT);
- chip->interrupt_mask |= OXYGEN_INT_GPIO;
-
- xonar_enable_output(chip);
-
- snd_jack_new(chip->card, "Headphone",
- SND_JACK_HEADPHONE, &data->hp_jack);
- xonar_ds_handle_hp_jack(chip);
-
- snd_component_add(chip->card, "WM8776");
- snd_component_add(chip->card, "WM8766");
-}
-
-static void xonar_hdav_slim_init(struct oxygen *chip)
-{
- struct xonar_wm87x6 *data = chip->model_data;
-
- data->generic.anti_pop_delay = 300;
- data->generic.output_enable_bit = GPIO_SLIM_OUTPUT_ENABLE;
-
- wm8776_init(chip);
-
- oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
- GPIO_SLIM_HDMI_DISABLE |
- GPIO_SLIM_FIRMWARE_CLK |
- GPIO_SLIM_FIRMWARE_DATA);
-
- xonar_hdmi_init(chip, &data->hdmi);
- xonar_enable_output(chip);
-
- snd_component_add(chip->card, "WM8776");
-}
-
-static void xonar_ds_cleanup(struct oxygen *chip)
-{
- xonar_disable_output(chip);
- wm8776_write(chip, WM8776_RESET, 0);
-}
-
-static void xonar_hdav_slim_cleanup(struct oxygen *chip)
-{
- xonar_hdmi_cleanup(chip);
- xonar_disable_output(chip);
- wm8776_write(chip, WM8776_RESET, 0);
- msleep(2);
-}
-
-static void xonar_ds_suspend(struct oxygen *chip)
-{
- xonar_ds_cleanup(chip);
-}
-
-static void xonar_hdav_slim_suspend(struct oxygen *chip)
-{
- xonar_hdav_slim_cleanup(chip);
-}
-
-static void xonar_ds_resume(struct oxygen *chip)
-{
- wm8776_registers_init(chip);
- wm8766_registers_init(chip);
- xonar_enable_output(chip);
- xonar_ds_handle_hp_jack(chip);
-}
-
-static void xonar_hdav_slim_resume(struct oxygen *chip)
-{
- struct xonar_wm87x6 *data = chip->model_data;
-
- wm8776_registers_init(chip);
- xonar_hdmi_resume(chip, &data->hdmi);
- xonar_enable_output(chip);
-}
-
-static void wm8776_adc_hardware_filter(unsigned int channel,
- struct snd_pcm_hardware *hardware)
-{
- if (channel == PCM_A) {
- hardware->rates = SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_64000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000;
- hardware->rate_max = 96000;
- }
-}
-
-static void xonar_hdav_slim_hardware_filter(unsigned int channel,
- struct snd_pcm_hardware *hardware)
-{
- wm8776_adc_hardware_filter(channel, hardware);
- xonar_hdmi_pcm_hardware_filter(channel, hardware);
-}
-
-static void set_wm87x6_dac_params(struct oxygen *chip,
- struct snd_pcm_hw_params *params)
-{
-}
-
-static void set_wm8776_adc_params(struct oxygen *chip,
- struct snd_pcm_hw_params *params)
-{
- u16 reg;
-
- reg = WM8776_ADCRATE_256 | WM8776_DACRATE_256;
- if (params_rate(params) > 48000)
- reg |= WM8776_ADCOSR;
- wm8776_write_cached(chip, WM8776_MSTRCTRL, reg);
-}
-
-static void set_hdav_slim_dac_params(struct oxygen *chip,
- struct snd_pcm_hw_params *params)
-{
- struct xonar_wm87x6 *data = chip->model_data;
-
- xonar_set_hdmi_params(chip, &data->hdmi, params);
-}
-
-static void update_wm8776_volume(struct oxygen *chip)
-{
- struct xonar_wm87x6 *data = chip->model_data;
- u8 to_change;
-
- if (chip->dac_volume[0] == chip->dac_volume[1]) {
- if (chip->dac_volume[0] != data->wm8776_regs[WM8776_DACLVOL] ||
- chip->dac_volume[1] != data->wm8776_regs[WM8776_DACRVOL]) {
- wm8776_write(chip, WM8776_DACMASTER,
- chip->dac_volume[0] | WM8776_UPDATE);
- data->wm8776_regs[WM8776_DACLVOL] = chip->dac_volume[0];
- data->wm8776_regs[WM8776_DACRVOL] = chip->dac_volume[0];
- }
- } else {
- to_change = (chip->dac_volume[0] !=
- data->wm8776_regs[WM8776_DACLVOL]) << 0;
- to_change |= (chip->dac_volume[1] !=
- data->wm8776_regs[WM8776_DACLVOL]) << 1;
- if (to_change & 1)
- wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0] |
- ((to_change & 2) ? 0 : WM8776_UPDATE));
- if (to_change & 2)
- wm8776_write(chip, WM8776_DACRVOL,
- chip->dac_volume[1] | WM8776_UPDATE);
- }
-}
-
-static void update_wm87x6_volume(struct oxygen *chip)
-{
- static const u8 wm8766_regs[6] = {
- WM8766_LDA1, WM8766_RDA1,
- WM8766_LDA2, WM8766_RDA2,
- WM8766_LDA3, WM8766_RDA3,
- };
- struct xonar_wm87x6 *data = chip->model_data;
- unsigned int i;
- u8 to_change;
-
- update_wm8776_volume(chip);
- if (chip->dac_volume[2] == chip->dac_volume[3] &&
- chip->dac_volume[2] == chip->dac_volume[4] &&
- chip->dac_volume[2] == chip->dac_volume[5] &&
- chip->dac_volume[2] == chip->dac_volume[6] &&
- chip->dac_volume[2] == chip->dac_volume[7]) {
- to_change = 0;
- for (i = 0; i < 6; ++i)
- if (chip->dac_volume[2] !=
- data->wm8766_regs[wm8766_regs[i]])
- to_change = 1;
- if (to_change) {
- wm8766_write(chip, WM8766_MASTDA,
- chip->dac_volume[2] | WM8766_UPDATE);
- for (i = 0; i < 6; ++i)
- data->wm8766_regs[wm8766_regs[i]] =
- chip->dac_volume[2];
- }
- } else {
- to_change = 0;
- for (i = 0; i < 6; ++i)
- to_change |= (chip->dac_volume[2 + i] !=
- data->wm8766_regs[wm8766_regs[i]]) << i;
- for (i = 0; i < 6; ++i)
- if (to_change & (1 << i))
- wm8766_write(chip, wm8766_regs[i],
- chip->dac_volume[2 + i] |
- ((to_change & (0x3e << i))
- ? 0 : WM8766_UPDATE));
- }
-}
-
-static void update_wm8776_mute(struct oxygen *chip)
-{
- wm8776_write_cached(chip, WM8776_DACMUTE,
- chip->dac_mute ? WM8776_DMUTE : 0);
-}
-
-static void update_wm87x6_mute(struct oxygen *chip)
-{
- update_wm8776_mute(chip);
- wm8766_write_cached(chip, WM8766_DAC_CTRL2, WM8766_ZCD |
- (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
-}
-
-static void update_wm8766_center_lfe_mix(struct oxygen *chip, bool mixed)
-{
- struct xonar_wm87x6 *data = chip->model_data;
- unsigned int reg;
-
- /*
- * The WM8766 can mix left and right channels, but this setting
- * applies to all three stereo pairs.
- */
- reg = data->wm8766_regs[WM8766_DAC_CTRL] &
- ~(WM8766_PL_LEFT_MASK | WM8766_PL_RIGHT_MASK);
- if (mixed)
- reg |= WM8766_PL_LEFT_LRMIX | WM8766_PL_RIGHT_LRMIX;
- else
- reg |= WM8766_PL_LEFT_LEFT | WM8766_PL_RIGHT_RIGHT;
- wm8766_write_cached(chip, WM8766_DAC_CTRL, reg);
-}
-
-static void xonar_ds_gpio_changed(struct oxygen *chip)
-{
- xonar_ds_handle_hp_jack(chip);
-}
-
-static int wm8776_bit_switch_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct xonar_wm87x6 *data = chip->model_data;
- u16 bit = ctl->private_value & 0xffff;
- unsigned int reg_index = (ctl->private_value >> 16) & 0xff;
- bool invert = (ctl->private_value >> 24) & 1;
-
- value->value.integer.value[0] =
- ((data->wm8776_regs[reg_index] & bit) != 0) ^ invert;
- return 0;
-}
-
-static int wm8776_bit_switch_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct xonar_wm87x6 *data = chip->model_data;
- u16 bit = ctl->private_value & 0xffff;
- u16 reg_value;
- unsigned int reg_index = (ctl->private_value >> 16) & 0xff;
- bool invert = (ctl->private_value >> 24) & 1;
- int changed;
-
- mutex_lock(&chip->mutex);
- reg_value = data->wm8776_regs[reg_index] & ~bit;
- if (value->value.integer.value[0] ^ invert)
- reg_value |= bit;
- changed = reg_value != data->wm8776_regs[reg_index];
- if (changed)
- wm8776_write(chip, reg_index, reg_value);
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static int wm8776_field_enum_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- static const char *const hld[16] = {
- "0 ms", "2.67 ms", "5.33 ms", "10.6 ms",
- "21.3 ms", "42.7 ms", "85.3 ms", "171 ms",
- "341 ms", "683 ms", "1.37 s", "2.73 s",
- "5.46 s", "10.9 s", "21.8 s", "43.7 s",
- };
- static const char *const atk_lim[11] = {
- "0.25 ms", "0.5 ms", "1 ms", "2 ms",
- "4 ms", "8 ms", "16 ms", "32 ms",
- "64 ms", "128 ms", "256 ms",
- };
- static const char *const atk_alc[11] = {
- "8.40 ms", "16.8 ms", "33.6 ms", "67.2 ms",
- "134 ms", "269 ms", "538 ms", "1.08 s",
- "2.15 s", "4.3 s", "8.6 s",
- };
- static const char *const dcy_lim[11] = {
- "1.2 ms", "2.4 ms", "4.8 ms", "9.6 ms",
- "19.2 ms", "38.4 ms", "76.8 ms", "154 ms",
- "307 ms", "614 ms", "1.23 s",
- };
- static const char *const dcy_alc[11] = {
- "33.5 ms", "67.0 ms", "134 ms", "268 ms",
- "536 ms", "1.07 s", "2.14 s", "4.29 s",
- "8.58 s", "17.2 s", "34.3 s",
- };
- static const char *const tranwin[8] = {
- "0 us", "62.5 us", "125 us", "250 us",
- "500 us", "1 ms", "2 ms", "4 ms",
- };
- u8 max;
- const char *const *names;
-
- max = (ctl->private_value >> 12) & 0xf;
- switch ((ctl->private_value >> 24) & 0x1f) {
- case WM8776_ALCCTRL2:
- names = hld;
- break;
- case WM8776_ALCCTRL3:
- if (((ctl->private_value >> 20) & 0xf) == 0) {
- if (ctl->private_value & LC_CONTROL_LIMITER)
- names = atk_lim;
- else
- names = atk_alc;
- } else {
- if (ctl->private_value & LC_CONTROL_LIMITER)
- names = dcy_lim;
- else
- names = dcy_alc;
- }
- break;
- case WM8776_LIMITER:
- names = tranwin;
- break;
- default:
- return -ENXIO;
- }
- return snd_ctl_enum_info(info, 1, max + 1, names);
-}
-
-static int wm8776_field_volume_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- info->count = 1;
- info->value.integer.min = (ctl->private_value >> 8) & 0xf;
- info->value.integer.max = (ctl->private_value >> 12) & 0xf;
- return 0;
-}
-
-static void wm8776_field_set_from_ctl(struct snd_kcontrol *ctl)
-{
- struct oxygen *chip = ctl->private_data;
- struct xonar_wm87x6 *data = chip->model_data;
- unsigned int value, reg_index, mode;
- u8 min, max, shift;
- u16 mask, reg_value;
- bool invert;
-
- if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) ==
- WM8776_LCSEL_LIMITER)
- mode = LC_CONTROL_LIMITER;
- else
- mode = LC_CONTROL_ALC;
- if (!(ctl->private_value & mode))
- return;
-
- value = ctl->private_value & 0xf;
- min = (ctl->private_value >> 8) & 0xf;
- max = (ctl->private_value >> 12) & 0xf;
- mask = (ctl->private_value >> 16) & 0xf;
- shift = (ctl->private_value >> 20) & 0xf;
- reg_index = (ctl->private_value >> 24) & 0x1f;
- invert = (ctl->private_value >> 29) & 0x1;
-
- if (invert)
- value = max - (value - min);
- reg_value = data->wm8776_regs[reg_index];
- reg_value &= ~(mask << shift);
- reg_value |= value << shift;
- wm8776_write_cached(chip, reg_index, reg_value);
-}
-
-static int wm8776_field_set(struct snd_kcontrol *ctl, unsigned int value)
-{
- struct oxygen *chip = ctl->private_data;
- u8 min, max;
- int changed;
-
- min = (ctl->private_value >> 8) & 0xf;
- max = (ctl->private_value >> 12) & 0xf;
- if (value < min || value > max)
- return -EINVAL;
- mutex_lock(&chip->mutex);
- changed = value != (ctl->private_value & 0xf);
- if (changed) {
- ctl->private_value = (ctl->private_value & ~0xf) | value;
- wm8776_field_set_from_ctl(ctl);
- }
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static int wm8776_field_enum_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- value->value.enumerated.item[0] = ctl->private_value & 0xf;
- return 0;
-}
-
-static int wm8776_field_volume_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- value->value.integer.value[0] = ctl->private_value & 0xf;
- return 0;
-}
-
-static int wm8776_field_enum_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- return wm8776_field_set(ctl, value->value.enumerated.item[0]);
-}
-
-static int wm8776_field_volume_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- return wm8776_field_set(ctl, value->value.integer.value[0]);
-}
-
-static int wm8776_hp_vol_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- info->count = 2;
- info->value.integer.min = 0x79 - 60;
- info->value.integer.max = 0x7f;
- return 0;
-}
-
-static int wm8776_hp_vol_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct xonar_wm87x6 *data = chip->model_data;
-
- mutex_lock(&chip->mutex);
- value->value.integer.value[0] =
- data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK;
- value->value.integer.value[1] =
- data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK;
- mutex_unlock(&chip->mutex);
- return 0;
-}
-
-static int wm8776_hp_vol_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct xonar_wm87x6 *data = chip->model_data;
- u8 to_update;
-
- mutex_lock(&chip->mutex);
- to_update = (value->value.integer.value[0] !=
- (data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK))
- << 0;
- to_update |= (value->value.integer.value[1] !=
- (data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK))
- << 1;
- if (value->value.integer.value[0] == value->value.integer.value[1]) {
- if (to_update) {
- wm8776_write(chip, WM8776_HPMASTER,
- value->value.integer.value[0] |
- WM8776_HPZCEN | WM8776_UPDATE);
- data->wm8776_regs[WM8776_HPLVOL] =
- value->value.integer.value[0] | WM8776_HPZCEN;
- data->wm8776_regs[WM8776_HPRVOL] =
- value->value.integer.value[0] | WM8776_HPZCEN;
- }
- } else {
- if (to_update & 1)
- wm8776_write(chip, WM8776_HPLVOL,
- value->value.integer.value[0] |
- WM8776_HPZCEN |
- ((to_update & 2) ? 0 : WM8776_UPDATE));
- if (to_update & 2)
- wm8776_write(chip, WM8776_HPRVOL,
- value->value.integer.value[1] |
- WM8776_HPZCEN | WM8776_UPDATE);
- }
- mutex_unlock(&chip->mutex);
- return to_update != 0;
-}
-
-static int wm8776_input_mux_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct xonar_wm87x6 *data = chip->model_data;
- unsigned int mux_bit = ctl->private_value;
-
- value->value.integer.value[0] =
- !!(data->wm8776_regs[WM8776_ADCMUX] & mux_bit);
- return 0;
-}
-
-static int wm8776_input_mux_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct xonar_wm87x6 *data = chip->model_data;
- struct snd_kcontrol *other_ctl;
- unsigned int mux_bit = ctl->private_value;
- u16 reg;
- int changed;
-
- mutex_lock(&chip->mutex);
- reg = data->wm8776_regs[WM8776_ADCMUX];
- if (value->value.integer.value[0]) {
- reg |= mux_bit;
- /* line-in and mic-in are exclusive */
- mux_bit ^= 3;
- if (reg & mux_bit) {
- reg &= ~mux_bit;
- if (mux_bit == 1)
- other_ctl = data->line_adcmux_control;
- else
- other_ctl = data->mic_adcmux_control;
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &other_ctl->id);
- }
- } else
- reg &= ~mux_bit;
- changed = reg != data->wm8776_regs[WM8776_ADCMUX];
- if (changed) {
- oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
- reg & 1 ? GPIO_DS_INPUT_ROUTE : 0,
- GPIO_DS_INPUT_ROUTE);
- wm8776_write(chip, WM8776_ADCMUX, reg);
- }
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static int wm8776_input_vol_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- info->count = 2;
- info->value.integer.min = 0xa5;
- info->value.integer.max = 0xff;
- return 0;
-}
-
-static int wm8776_input_vol_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct xonar_wm87x6 *data = chip->model_data;
-
- mutex_lock(&chip->mutex);
- value->value.integer.value[0] =
- data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK;
- value->value.integer.value[1] =
- data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK;
- mutex_unlock(&chip->mutex);
- return 0;
-}
-
-static int wm8776_input_vol_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct xonar_wm87x6 *data = chip->model_data;
- int changed = 0;
-
- mutex_lock(&chip->mutex);
- changed = (value->value.integer.value[0] !=
- (data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK)) ||
- (value->value.integer.value[1] !=
- (data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK));
- wm8776_write_cached(chip, WM8776_ADCLVOL,
- value->value.integer.value[0] | WM8776_ZCA);
- wm8776_write_cached(chip, WM8776_ADCRVOL,
- value->value.integer.value[1] | WM8776_ZCA);
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static int wm8776_level_control_info(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_info *info)
-{
- static const char *const names[3] = {
- "None", "Peak Limiter", "Automatic Level Control"
- };
-
- return snd_ctl_enum_info(info, 1, 3, names);
-}
-
-static int wm8776_level_control_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct xonar_wm87x6 *data = chip->model_data;
-
- if (!(data->wm8776_regs[WM8776_ALCCTRL2] & WM8776_LCEN))
- value->value.enumerated.item[0] = 0;
- else if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) ==
- WM8776_LCSEL_LIMITER)
- value->value.enumerated.item[0] = 1;
- else
- value->value.enumerated.item[0] = 2;
- return 0;
-}
-
-static void activate_control(struct oxygen *chip,
- struct snd_kcontrol *ctl, unsigned int mode)
-{
- unsigned int access;
-
- if (ctl->private_value & mode)
- access = 0;
- else
- access = SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- if ((ctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_INACTIVE) != access) {
- ctl->vd[0].access ^= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
- }
-}
-
-static int wm8776_level_control_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct xonar_wm87x6 *data = chip->model_data;
- unsigned int mode = 0, i;
- u16 ctrl1, ctrl2;
- int changed;
-
- if (value->value.enumerated.item[0] >= 3)
- return -EINVAL;
- mutex_lock(&chip->mutex);
- changed = value->value.enumerated.item[0] != ctl->private_value;
- if (changed) {
- ctl->private_value = value->value.enumerated.item[0];
- ctrl1 = data->wm8776_regs[WM8776_ALCCTRL1];
- ctrl2 = data->wm8776_regs[WM8776_ALCCTRL2];
- switch (value->value.enumerated.item[0]) {
- default:
- wm8776_write_cached(chip, WM8776_ALCCTRL2,
- ctrl2 & ~WM8776_LCEN);
- break;
- case 1:
- wm8776_write_cached(chip, WM8776_ALCCTRL1,
- (ctrl1 & ~WM8776_LCSEL_MASK) |
- WM8776_LCSEL_LIMITER);
- wm8776_write_cached(chip, WM8776_ALCCTRL2,
- ctrl2 | WM8776_LCEN);
- mode = LC_CONTROL_LIMITER;
- break;
- case 2:
- wm8776_write_cached(chip, WM8776_ALCCTRL1,
- (ctrl1 & ~WM8776_LCSEL_MASK) |
- WM8776_LCSEL_ALC_STEREO);
- wm8776_write_cached(chip, WM8776_ALCCTRL2,
- ctrl2 | WM8776_LCEN);
- mode = LC_CONTROL_ALC;
- break;
- }
- for (i = 0; i < ARRAY_SIZE(data->lc_controls); ++i)
- activate_control(chip, data->lc_controls[i], mode);
- }
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
-{
- static const char *const names[2] = {
- "None", "High-pass Filter"
- };
-
- return snd_ctl_enum_info(info, 1, 2, names);
-}
-
-static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct xonar_wm87x6 *data = chip->model_data;
-
- value->value.enumerated.item[0] =
- !(data->wm8776_regs[WM8776_ADCIFCTRL] & WM8776_ADCHPD);
- return 0;
-}
-
-static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- struct xonar_wm87x6 *data = chip->model_data;
- unsigned int reg;
- int changed;
-
- mutex_lock(&chip->mutex);
- reg = data->wm8776_regs[WM8776_ADCIFCTRL] & ~WM8776_ADCHPD;
- if (!value->value.enumerated.item[0])
- reg |= WM8776_ADCHPD;
- changed = reg != data->wm8776_regs[WM8776_ADCIFCTRL];
- if (changed)
- wm8776_write(chip, WM8776_ADCIFCTRL, reg);
- mutex_unlock(&chip->mutex);
- return changed;
-}
-
-#define WM8776_BIT_SWITCH(xname, reg, bit, invert, flags) { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .info = snd_ctl_boolean_mono_info, \
- .get = wm8776_bit_switch_get, \
- .put = wm8776_bit_switch_put, \
- .private_value = ((reg) << 16) | (bit) | ((invert) << 24) | (flags), \
-}
-#define _WM8776_FIELD_CTL(xname, reg, shift, initval, min, max, mask, flags) \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .private_value = (initval) | ((min) << 8) | ((max) << 12) | \
- ((mask) << 16) | ((shift) << 20) | ((reg) << 24) | (flags)
-#define WM8776_FIELD_CTL_ENUM(xname, reg, shift, init, min, max, mask, flags) {\
- _WM8776_FIELD_CTL(xname " Capture Enum", \
- reg, shift, init, min, max, mask, flags), \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
- SNDRV_CTL_ELEM_ACCESS_INACTIVE, \
- .info = wm8776_field_enum_info, \
- .get = wm8776_field_enum_get, \
- .put = wm8776_field_enum_put, \
-}
-#define WM8776_FIELD_CTL_VOLUME(a, b, c, d, e, f, g, h, tlv_p) { \
- _WM8776_FIELD_CTL(a " Capture Volume", b, c, d, e, f, g, h), \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
- SNDRV_CTL_ELEM_ACCESS_INACTIVE | \
- SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .info = wm8776_field_volume_info, \
- .get = wm8776_field_volume_get, \
- .put = wm8776_field_volume_put, \
- .tlv = { .p = tlv_p }, \
-}
-
-static const DECLARE_TLV_DB_SCALE(wm87x6_dac_db_scale, -6000, 50, 0);
-static const DECLARE_TLV_DB_SCALE(wm8776_adc_db_scale, -2100, 50, 0);
-static const DECLARE_TLV_DB_SCALE(wm8776_hp_db_scale, -6000, 100, 0);
-static const DECLARE_TLV_DB_SCALE(wm8776_lct_db_scale, -1600, 100, 0);
-static const DECLARE_TLV_DB_SCALE(wm8776_maxgain_db_scale, 0, 400, 0);
-static const DECLARE_TLV_DB_SCALE(wm8776_ngth_db_scale, -7800, 600, 0);
-static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_lim_db_scale, -1200, 100, 0);
-static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_alc_db_scale, -2100, 400, 0);
-
-static const struct snd_kcontrol_new ds_controls[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Headphone Playback Volume",
- .info = wm8776_hp_vol_info,
- .get = wm8776_hp_vol_get,
- .put = wm8776_hp_vol_put,
- .tlv = { .p = wm8776_hp_db_scale },
- },
- WM8776_BIT_SWITCH("Headphone Playback Switch",
- WM8776_PWRDOWN, WM8776_HPPD, 1, 0),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input Capture Volume",
- .info = wm8776_input_vol_info,
- .get = wm8776_input_vol_get,
- .put = wm8776_input_vol_put,
- .tlv = { .p = wm8776_adc_db_scale },
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Line Capture Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = wm8776_input_mux_get,
- .put = wm8776_input_mux_put,
- .private_value = 1 << 0,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Mic Capture Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = wm8776_input_mux_get,
- .put = wm8776_input_mux_put,
- .private_value = 1 << 1,
- },
- WM8776_BIT_SWITCH("Front Mic Capture Switch",
- WM8776_ADCMUX, 1 << 2, 0, 0),
- WM8776_BIT_SWITCH("Aux Capture Switch",
- WM8776_ADCMUX, 1 << 3, 0, 0),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "ADC Filter Capture Enum",
- .info = hpf_info,
- .get = hpf_get,
- .put = hpf_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Level Control Capture Enum",
- .info = wm8776_level_control_info,
- .get = wm8776_level_control_get,
- .put = wm8776_level_control_put,
- .private_value = 0,
- },
-};
-static const struct snd_kcontrol_new hdav_slim_controls[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "HDMI Playback Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = xonar_gpio_bit_switch_get,
- .put = xonar_gpio_bit_switch_put,
- .private_value = GPIO_SLIM_HDMI_DISABLE | XONAR_GPIO_BIT_INVERT,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Headphone Playback Volume",
- .info = wm8776_hp_vol_info,
- .get = wm8776_hp_vol_get,
- .put = wm8776_hp_vol_put,
- .tlv = { .p = wm8776_hp_db_scale },
- },
- WM8776_BIT_SWITCH("Headphone Playback Switch",
- WM8776_PWRDOWN, WM8776_HPPD, 1, 0),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input Capture Volume",
- .info = wm8776_input_vol_info,
- .get = wm8776_input_vol_get,
- .put = wm8776_input_vol_put,
- .tlv = { .p = wm8776_adc_db_scale },
- },
- WM8776_BIT_SWITCH("Mic Capture Switch",
- WM8776_ADCMUX, 1 << 0, 0, 0),
- WM8776_BIT_SWITCH("Aux Capture Switch",
- WM8776_ADCMUX, 1 << 1, 0, 0),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "ADC Filter Capture Enum",
- .info = hpf_info,
- .get = hpf_get,
- .put = hpf_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Level Control Capture Enum",
- .info = wm8776_level_control_info,
- .get = wm8776_level_control_get,
- .put = wm8776_level_control_put,
- .private_value = 0,
- },
-};
-static const struct snd_kcontrol_new lc_controls[] = {
- WM8776_FIELD_CTL_VOLUME("Limiter Threshold",
- WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf,
- LC_CONTROL_LIMITER, wm8776_lct_db_scale),
- WM8776_FIELD_CTL_ENUM("Limiter Attack Time",
- WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf,
- LC_CONTROL_LIMITER),
- WM8776_FIELD_CTL_ENUM("Limiter Decay Time",
- WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf,
- LC_CONTROL_LIMITER),
- WM8776_FIELD_CTL_ENUM("Limiter Transient Window",
- WM8776_LIMITER, 4, 2, 0, 7, 0x7,
- LC_CONTROL_LIMITER),
- WM8776_FIELD_CTL_VOLUME("Limiter Maximum Attenuation",
- WM8776_LIMITER, 0, 6, 3, 12, 0xf,
- LC_CONTROL_LIMITER,
- wm8776_maxatten_lim_db_scale),
- WM8776_FIELD_CTL_VOLUME("ALC Target Level",
- WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf,
- LC_CONTROL_ALC, wm8776_lct_db_scale),
- WM8776_FIELD_CTL_ENUM("ALC Attack Time",
- WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf,
- LC_CONTROL_ALC),
- WM8776_FIELD_CTL_ENUM("ALC Decay Time",
- WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf,
- LC_CONTROL_ALC),
- WM8776_FIELD_CTL_VOLUME("ALC Maximum Gain",
- WM8776_ALCCTRL1, 4, 7, 1, 7, 0x7,
- LC_CONTROL_ALC, wm8776_maxgain_db_scale),
- WM8776_FIELD_CTL_VOLUME("ALC Maximum Attenuation",
- WM8776_LIMITER, 0, 10, 10, 15, 0xf,
- LC_CONTROL_ALC, wm8776_maxatten_alc_db_scale),
- WM8776_FIELD_CTL_ENUM("ALC Hold Time",
- WM8776_ALCCTRL2, 0, 0, 0, 15, 0xf,
- LC_CONTROL_ALC),
- WM8776_BIT_SWITCH("Noise Gate Capture Switch",
- WM8776_NOISEGATE, WM8776_NGAT, 0,
- LC_CONTROL_ALC),
- WM8776_FIELD_CTL_VOLUME("Noise Gate Threshold",
- WM8776_NOISEGATE, 2, 0, 0, 7, 0x7,
- LC_CONTROL_ALC, wm8776_ngth_db_scale),
-};
-
-static int add_lc_controls(struct oxygen *chip)
-{
- struct xonar_wm87x6 *data = chip->model_data;
- unsigned int i;
- struct snd_kcontrol *ctl;
- int err;
-
- BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls));
- for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) {
- ctl = snd_ctl_new1(&lc_controls[i], chip);
- if (!ctl)
- return -ENOMEM;
- err = snd_ctl_add(chip->card, ctl);
- if (err < 0)
- return err;
- data->lc_controls[i] = ctl;
- }
- return 0;
-}
-
-static int xonar_ds_mixer_init(struct oxygen *chip)
-{
- struct xonar_wm87x6 *data = chip->model_data;
- unsigned int i;
- struct snd_kcontrol *ctl;
- int err;
-
- for (i = 0; i < ARRAY_SIZE(ds_controls); ++i) {
- ctl = snd_ctl_new1(&ds_controls[i], chip);
- if (!ctl)
- return -ENOMEM;
- err = snd_ctl_add(chip->card, ctl);
- if (err < 0)
- return err;
- if (!strcmp(ctl->id.name, "Line Capture Switch"))
- data->line_adcmux_control = ctl;
- else if (!strcmp(ctl->id.name, "Mic Capture Switch"))
- data->mic_adcmux_control = ctl;
- }
- if (!data->line_adcmux_control || !data->mic_adcmux_control)
- return -ENXIO;
-
- return add_lc_controls(chip);
-}
-
-static int xonar_hdav_slim_mixer_init(struct oxygen *chip)
-{
- unsigned int i;
- struct snd_kcontrol *ctl;
- int err;
-
- for (i = 0; i < ARRAY_SIZE(hdav_slim_controls); ++i) {
- ctl = snd_ctl_new1(&hdav_slim_controls[i], chip);
- if (!ctl)
- return -ENOMEM;
- err = snd_ctl_add(chip->card, ctl);
- if (err < 0)
- return err;
- }
-
- return add_lc_controls(chip);
-}
-
-static void dump_wm8776_registers(struct oxygen *chip,
- struct snd_info_buffer *buffer)
-{
- struct xonar_wm87x6 *data = chip->model_data;
- unsigned int i;
-
- snd_iprintf(buffer, "\nWM8776:\n00:");
- for (i = 0; i < 0x10; ++i)
- snd_iprintf(buffer, " %03x", data->wm8776_regs[i]);
- snd_iprintf(buffer, "\n10:");
- for (i = 0x10; i < 0x17; ++i)
- snd_iprintf(buffer, " %03x", data->wm8776_regs[i]);
- snd_iprintf(buffer, "\n");
-}
-
-static void dump_wm87x6_registers(struct oxygen *chip,
- struct snd_info_buffer *buffer)
-{
- struct xonar_wm87x6 *data = chip->model_data;
- unsigned int i;
-
- dump_wm8776_registers(chip, buffer);
- snd_iprintf(buffer, "\nWM8766:\n00:");
- for (i = 0; i < 0x10; ++i)
- snd_iprintf(buffer, " %03x", data->wm8766_regs[i]);
- snd_iprintf(buffer, "\n");
-}
-
-static const struct oxygen_model model_xonar_ds = {
- .shortname = "Xonar DS",
- .longname = "Asus Virtuoso 66",
- .chip = "AV200",
- .init = xonar_ds_init,
- .mixer_init = xonar_ds_mixer_init,
- .cleanup = xonar_ds_cleanup,
- .suspend = xonar_ds_suspend,
- .resume = xonar_ds_resume,
- .pcm_hardware_filter = wm8776_adc_hardware_filter,
- .set_dac_params = set_wm87x6_dac_params,
- .set_adc_params = set_wm8776_adc_params,
- .update_dac_volume = update_wm87x6_volume,
- .update_dac_mute = update_wm87x6_mute,
- .update_center_lfe_mix = update_wm8766_center_lfe_mix,
- .gpio_changed = xonar_ds_gpio_changed,
- .dump_registers = dump_wm87x6_registers,
- .dac_tlv = wm87x6_dac_db_scale,
- .model_data_size = sizeof(struct xonar_wm87x6),
- .device_config = PLAYBACK_0_TO_I2S |
- PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_1 |
- CAPTURE_1_FROM_SPDIF,
- .dac_channels_pcm = 8,
- .dac_channels_mixer = 8,
- .dac_volume_min = 255 - 2*60,
- .dac_volume_max = 255,
- .function_flags = OXYGEN_FUNCTION_SPI,
- .dac_mclks = OXYGEN_MCLKS(256, 256, 128),
- .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
- .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
- .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
-};
-
-static const struct oxygen_model model_xonar_hdav_slim = {
- .shortname = "Xonar HDAV1.3 Slim",
- .longname = "Asus Virtuoso 200",
- .chip = "AV200",
- .init = xonar_hdav_slim_init,
- .mixer_init = xonar_hdav_slim_mixer_init,
- .cleanup = xonar_hdav_slim_cleanup,
- .suspend = xonar_hdav_slim_suspend,
- .resume = xonar_hdav_slim_resume,
- .pcm_hardware_filter = xonar_hdav_slim_hardware_filter,
- .set_dac_params = set_hdav_slim_dac_params,
- .set_adc_params = set_wm8776_adc_params,
- .update_dac_volume = update_wm8776_volume,
- .update_dac_mute = update_wm8776_mute,
- .uart_input = xonar_hdmi_uart_input,
- .dump_registers = dump_wm8776_registers,
- .dac_tlv = wm87x6_dac_db_scale,
- .model_data_size = sizeof(struct xonar_wm87x6),
- .device_config = PLAYBACK_0_TO_I2S |
- PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_1 |
- CAPTURE_1_FROM_SPDIF,
- .dac_channels_pcm = 8,
- .dac_channels_mixer = 2,
- .dac_volume_min = 255 - 2*60,
- .dac_volume_max = 255,
- .function_flags = OXYGEN_FUNCTION_2WIRE,
- .dac_mclks = OXYGEN_MCLKS(256, 256, 128),
- .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
- .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
- .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
-};
-
-int __devinit get_xonar_wm87x6_model(struct oxygen *chip,
- const struct pci_device_id *id)
-{
- switch (id->subdevice) {
- case 0x838e:
- chip->model = model_xonar_ds;
- break;
- case 0x835e:
- chip->model = model_xonar_hdav_slim;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/pcxhr/Makefile b/ANDROID_3.4.5/sound/pci/pcxhr/Makefile
deleted file mode 100644
index b06128e9..00000000
--- a/ANDROID_3.4.5/sound/pci/pcxhr/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-snd-pcxhr-objs := pcxhr.o pcxhr_hwdep.o pcxhr_mixer.o pcxhr_core.o pcxhr_mix22.o
-obj-$(CONFIG_SND_PCXHR) += snd-pcxhr.o
diff --git a/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr.c b/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr.c
deleted file mode 100644
index fd1809ab..00000000
--- a/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr.c
+++ /dev/null
@@ -1,1628 +0,0 @@
-/*
- * Driver for Digigram pcxhr compatible soundcards
- *
- * main file with alsa callbacks
- *
- * Copyright (c) 2004 by Digigram <alsa@digigram.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include "pcxhr.h"
-#include "pcxhr_mixer.h"
-#include "pcxhr_hwdep.h"
-#include "pcxhr_core.h"
-#include "pcxhr_mix22.h"
-
-#define DRIVER_NAME "pcxhr"
-
-MODULE_AUTHOR("Markus Bollinger <bollinger@digigram.com>, "
- "Marc Titinger <titinger@digigram.com>");
-MODULE_DESCRIPTION("Digigram " DRIVER_NAME " " PCXHR_DRIVER_VERSION_STRING);
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Digigram," DRIVER_NAME "}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
-static bool mono[SNDRV_CARDS]; /* capture mono only */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Digigram " DRIVER_NAME " soundcard");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Digigram " DRIVER_NAME " soundcard");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Digigram " DRIVER_NAME " soundcard");
-module_param_array(mono, bool, NULL, 0444);
-MODULE_PARM_DESC(mono, "Mono capture mode (default is stereo)");
-
-enum {
- PCI_ID_VX882HR,
- PCI_ID_PCX882HR,
- PCI_ID_VX881HR,
- PCI_ID_PCX881HR,
- PCI_ID_VX882E,
- PCI_ID_PCX882E,
- PCI_ID_VX881E,
- PCI_ID_PCX881E,
- PCI_ID_VX1222HR,
- PCI_ID_PCX1222HR,
- PCI_ID_VX1221HR,
- PCI_ID_PCX1221HR,
- PCI_ID_VX1222E,
- PCI_ID_PCX1222E,
- PCI_ID_VX1221E,
- PCI_ID_PCX1221E,
- PCI_ID_VX222HR,
- PCI_ID_VX222E,
- PCI_ID_PCX22HR,
- PCI_ID_PCX22E,
- PCI_ID_VX222HRMIC,
- PCI_ID_VX222E_MIC,
- PCI_ID_PCX924HR,
- PCI_ID_PCX924E,
- PCI_ID_PCX924HRMIC,
- PCI_ID_PCX924E_MIC,
- PCI_ID_LAST
-};
-
-static DEFINE_PCI_DEVICE_TABLE(pcxhr_ids) = {
- { 0x10b5, 0x9656, 0x1369, 0xb001, 0, 0, PCI_ID_VX882HR, },
- { 0x10b5, 0x9656, 0x1369, 0xb101, 0, 0, PCI_ID_PCX882HR, },
- { 0x10b5, 0x9656, 0x1369, 0xb201, 0, 0, PCI_ID_VX881HR, },
- { 0x10b5, 0x9656, 0x1369, 0xb301, 0, 0, PCI_ID_PCX881HR, },
- { 0x10b5, 0x9056, 0x1369, 0xb021, 0, 0, PCI_ID_VX882E, },
- { 0x10b5, 0x9056, 0x1369, 0xb121, 0, 0, PCI_ID_PCX882E, },
- { 0x10b5, 0x9056, 0x1369, 0xb221, 0, 0, PCI_ID_VX881E, },
- { 0x10b5, 0x9056, 0x1369, 0xb321, 0, 0, PCI_ID_PCX881E, },
- { 0x10b5, 0x9656, 0x1369, 0xb401, 0, 0, PCI_ID_VX1222HR, },
- { 0x10b5, 0x9656, 0x1369, 0xb501, 0, 0, PCI_ID_PCX1222HR, },
- { 0x10b5, 0x9656, 0x1369, 0xb601, 0, 0, PCI_ID_VX1221HR, },
- { 0x10b5, 0x9656, 0x1369, 0xb701, 0, 0, PCI_ID_PCX1221HR, },
- { 0x10b5, 0x9056, 0x1369, 0xb421, 0, 0, PCI_ID_VX1222E, },
- { 0x10b5, 0x9056, 0x1369, 0xb521, 0, 0, PCI_ID_PCX1222E, },
- { 0x10b5, 0x9056, 0x1369, 0xb621, 0, 0, PCI_ID_VX1221E, },
- { 0x10b5, 0x9056, 0x1369, 0xb721, 0, 0, PCI_ID_PCX1221E, },
- { 0x10b5, 0x9056, 0x1369, 0xba01, 0, 0, PCI_ID_VX222HR, },
- { 0x10b5, 0x9056, 0x1369, 0xba21, 0, 0, PCI_ID_VX222E, },
- { 0x10b5, 0x9056, 0x1369, 0xbd01, 0, 0, PCI_ID_PCX22HR, },
- { 0x10b5, 0x9056, 0x1369, 0xbd21, 0, 0, PCI_ID_PCX22E, },
- { 0x10b5, 0x9056, 0x1369, 0xbc01, 0, 0, PCI_ID_VX222HRMIC, },
- { 0x10b5, 0x9056, 0x1369, 0xbc21, 0, 0, PCI_ID_VX222E_MIC, },
- { 0x10b5, 0x9056, 0x1369, 0xbb01, 0, 0, PCI_ID_PCX924HR, },
- { 0x10b5, 0x9056, 0x1369, 0xbb21, 0, 0, PCI_ID_PCX924E, },
- { 0x10b5, 0x9056, 0x1369, 0xbf01, 0, 0, PCI_ID_PCX924HRMIC, },
- { 0x10b5, 0x9056, 0x1369, 0xbf21, 0, 0, PCI_ID_PCX924E_MIC, },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, pcxhr_ids);
-
-struct board_parameters {
- char* board_name;
- short playback_chips;
- short capture_chips;
- short fw_file_set;
- short firmware_num;
-};
-static struct board_parameters pcxhr_board_params[] = {
-[PCI_ID_VX882HR] = { "VX882HR", 4, 4, 0, 41 },
-[PCI_ID_PCX882HR] = { "PCX882HR", 4, 4, 0, 41 },
-[PCI_ID_VX881HR] = { "VX881HR", 4, 4, 0, 41 },
-[PCI_ID_PCX881HR] = { "PCX881HR", 4, 4, 0, 41 },
-[PCI_ID_VX882E] = { "VX882e", 4, 4, 1, 41 },
-[PCI_ID_PCX882E] = { "PCX882e", 4, 4, 1, 41 },
-[PCI_ID_VX881E] = { "VX881e", 4, 4, 1, 41 },
-[PCI_ID_PCX881E] = { "PCX881e", 4, 4, 1, 41 },
-[PCI_ID_VX1222HR] = { "VX1222HR", 6, 1, 2, 42 },
-[PCI_ID_PCX1222HR] = { "PCX1222HR", 6, 1, 2, 42 },
-[PCI_ID_VX1221HR] = { "VX1221HR", 6, 1, 2, 42 },
-[PCI_ID_PCX1221HR] = { "PCX1221HR", 6, 1, 2, 42 },
-[PCI_ID_VX1222E] = { "VX1222e", 6, 1, 3, 42 },
-[PCI_ID_PCX1222E] = { "PCX1222e", 6, 1, 3, 42 },
-[PCI_ID_VX1221E] = { "VX1221e", 6, 1, 3, 42 },
-[PCI_ID_PCX1221E] = { "PCX1221e", 6, 1, 3, 42 },
-[PCI_ID_VX222HR] = { "VX222HR", 1, 1, 4, 44 },
-[PCI_ID_VX222E] = { "VX222e", 1, 1, 4, 44 },
-[PCI_ID_PCX22HR] = { "PCX22HR", 1, 0, 4, 44 },
-[PCI_ID_PCX22E] = { "PCX22e", 1, 0, 4, 44 },
-[PCI_ID_VX222HRMIC] = { "VX222HR-Mic", 1, 1, 5, 44 },
-[PCI_ID_VX222E_MIC] = { "VX222e-Mic", 1, 1, 5, 44 },
-[PCI_ID_PCX924HR] = { "PCX924HR", 1, 1, 5, 44 },
-[PCI_ID_PCX924E] = { "PCX924e", 1, 1, 5, 44 },
-[PCI_ID_PCX924HRMIC] = { "PCX924HR-Mic", 1, 1, 5, 44 },
-[PCI_ID_PCX924E_MIC] = { "PCX924e-Mic", 1, 1, 5, 44 },
-};
-
-/* boards without hw AES1 and SRC onboard are all using fw_file_set==4 */
-/* VX222HR, VX222e, PCX22HR and PCX22e */
-#define PCXHR_BOARD_HAS_AES1(x) (x->fw_file_set != 4)
-/* some boards do not support 192kHz on digital AES input plugs */
-#define PCXHR_BOARD_AESIN_NO_192K(x) ((x->capture_chips == 0) || \
- (x->fw_file_set == 0) || \
- (x->fw_file_set == 2))
-
-static int pcxhr_pll_freq_register(unsigned int freq, unsigned int* pllreg,
- unsigned int* realfreq)
-{
- unsigned int reg;
-
- if (freq < 6900 || freq > 110000)
- return -EINVAL;
- reg = (28224000 * 2) / freq;
- reg = (reg - 1) / 2;
- if (reg < 0x200)
- *pllreg = reg + 0x800;
- else if (reg < 0x400)
- *pllreg = reg & 0x1ff;
- else if (reg < 0x800) {
- *pllreg = ((reg >> 1) & 0x1ff) + 0x200;
- reg &= ~1;
- } else {
- *pllreg = ((reg >> 2) & 0x1ff) + 0x400;
- reg &= ~3;
- }
- if (realfreq)
- *realfreq = (28224000 / (reg + 1));
- return 0;
-}
-
-
-#define PCXHR_FREQ_REG_MASK 0x1f
-#define PCXHR_FREQ_QUARTZ_48000 0x00
-#define PCXHR_FREQ_QUARTZ_24000 0x01
-#define PCXHR_FREQ_QUARTZ_12000 0x09
-#define PCXHR_FREQ_QUARTZ_32000 0x08
-#define PCXHR_FREQ_QUARTZ_16000 0x04
-#define PCXHR_FREQ_QUARTZ_8000 0x0c
-#define PCXHR_FREQ_QUARTZ_44100 0x02
-#define PCXHR_FREQ_QUARTZ_22050 0x0a
-#define PCXHR_FREQ_QUARTZ_11025 0x06
-#define PCXHR_FREQ_PLL 0x05
-#define PCXHR_FREQ_QUARTZ_192000 0x10
-#define PCXHR_FREQ_QUARTZ_96000 0x18
-#define PCXHR_FREQ_QUARTZ_176400 0x14
-#define PCXHR_FREQ_QUARTZ_88200 0x1c
-#define PCXHR_FREQ_QUARTZ_128000 0x12
-#define PCXHR_FREQ_QUARTZ_64000 0x1a
-
-#define PCXHR_FREQ_WORD_CLOCK 0x0f
-#define PCXHR_FREQ_SYNC_AES 0x0e
-#define PCXHR_FREQ_AES_1 0x07
-#define PCXHR_FREQ_AES_2 0x0b
-#define PCXHR_FREQ_AES_3 0x03
-#define PCXHR_FREQ_AES_4 0x0d
-
-static int pcxhr_get_clock_reg(struct pcxhr_mgr *mgr, unsigned int rate,
- unsigned int *reg, unsigned int *freq)
-{
- unsigned int val, realfreq, pllreg;
- struct pcxhr_rmh rmh;
- int err;
-
- realfreq = rate;
- switch (mgr->use_clock_type) {
- case PCXHR_CLOCK_TYPE_INTERNAL : /* clock by quartz or pll */
- switch (rate) {
- case 48000 : val = PCXHR_FREQ_QUARTZ_48000; break;
- case 24000 : val = PCXHR_FREQ_QUARTZ_24000; break;
- case 12000 : val = PCXHR_FREQ_QUARTZ_12000; break;
- case 32000 : val = PCXHR_FREQ_QUARTZ_32000; break;
- case 16000 : val = PCXHR_FREQ_QUARTZ_16000; break;
- case 8000 : val = PCXHR_FREQ_QUARTZ_8000; break;
- case 44100 : val = PCXHR_FREQ_QUARTZ_44100; break;
- case 22050 : val = PCXHR_FREQ_QUARTZ_22050; break;
- case 11025 : val = PCXHR_FREQ_QUARTZ_11025; break;
- case 192000 : val = PCXHR_FREQ_QUARTZ_192000; break;
- case 96000 : val = PCXHR_FREQ_QUARTZ_96000; break;
- case 176400 : val = PCXHR_FREQ_QUARTZ_176400; break;
- case 88200 : val = PCXHR_FREQ_QUARTZ_88200; break;
- case 128000 : val = PCXHR_FREQ_QUARTZ_128000; break;
- case 64000 : val = PCXHR_FREQ_QUARTZ_64000; break;
- default :
- val = PCXHR_FREQ_PLL;
- /* get the value for the pll register */
- err = pcxhr_pll_freq_register(rate, &pllreg, &realfreq);
- if (err)
- return err;
- pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
- rmh.cmd[0] |= IO_NUM_REG_GENCLK;
- rmh.cmd[1] = pllreg & MASK_DSP_WORD;
- rmh.cmd[2] = pllreg >> 24;
- rmh.cmd_len = 3;
- err = pcxhr_send_msg(mgr, &rmh);
- if (err < 0) {
- snd_printk(KERN_ERR
- "error CMD_ACCESS_IO_WRITE "
- "for PLL register : %x!\n", err);
- return err;
- }
- }
- break;
- case PCXHR_CLOCK_TYPE_WORD_CLOCK:
- val = PCXHR_FREQ_WORD_CLOCK;
- break;
- case PCXHR_CLOCK_TYPE_AES_SYNC:
- val = PCXHR_FREQ_SYNC_AES;
- break;
- case PCXHR_CLOCK_TYPE_AES_1:
- val = PCXHR_FREQ_AES_1;
- break;
- case PCXHR_CLOCK_TYPE_AES_2:
- val = PCXHR_FREQ_AES_2;
- break;
- case PCXHR_CLOCK_TYPE_AES_3:
- val = PCXHR_FREQ_AES_3;
- break;
- case PCXHR_CLOCK_TYPE_AES_4:
- val = PCXHR_FREQ_AES_4;
- break;
- default:
- return -EINVAL;
- }
- *reg = val;
- *freq = realfreq;
- return 0;
-}
-
-
-static int pcxhr_sub_set_clock(struct pcxhr_mgr *mgr,
- unsigned int rate,
- int *changed)
-{
- unsigned int val, realfreq, speed;
- struct pcxhr_rmh rmh;
- int err;
-
- err = pcxhr_get_clock_reg(mgr, rate, &val, &realfreq);
- if (err)
- return err;
-
- /* codec speed modes */
- if (rate < 55000)
- speed = 0; /* single speed */
- else if (rate < 100000)
- speed = 1; /* dual speed */
- else
- speed = 2; /* quad speed */
- if (mgr->codec_speed != speed) {
- pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* mute outputs */
- rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
- if (DSP_EXT_CMD_SET(mgr)) {
- rmh.cmd[1] = 1;
- rmh.cmd_len = 2;
- }
- err = pcxhr_send_msg(mgr, &rmh);
- if (err)
- return err;
-
- pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* set speed ratio */
- rmh.cmd[0] |= IO_NUM_SPEED_RATIO;
- rmh.cmd[1] = speed;
- rmh.cmd_len = 2;
- err = pcxhr_send_msg(mgr, &rmh);
- if (err)
- return err;
- }
- /* set the new frequency */
- snd_printdd("clock register : set %x\n", val);
- err = pcxhr_write_io_num_reg_cont(mgr, PCXHR_FREQ_REG_MASK,
- val, changed);
- if (err)
- return err;
-
- mgr->sample_rate_real = realfreq;
- mgr->cur_clock_type = mgr->use_clock_type;
-
- /* unmute after codec speed modes */
- if (mgr->codec_speed != speed) {
- pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); /* unmute outputs */
- rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
- if (DSP_EXT_CMD_SET(mgr)) {
- rmh.cmd[1] = 1;
- rmh.cmd_len = 2;
- }
- err = pcxhr_send_msg(mgr, &rmh);
- if (err)
- return err;
- mgr->codec_speed = speed; /* save new codec speed */
- }
-
- snd_printdd("pcxhr_sub_set_clock to %dHz (realfreq=%d)\n",
- rate, realfreq);
- return 0;
-}
-
-#define PCXHR_MODIFY_CLOCK_S_BIT 0x04
-
-#define PCXHR_IRQ_TIMER_FREQ 92000
-#define PCXHR_IRQ_TIMER_PERIOD 48
-
-int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate)
-{
- struct pcxhr_rmh rmh;
- int err, changed;
-
- if (rate == 0)
- return 0; /* nothing to do */
-
- if (mgr->is_hr_stereo)
- err = hr222_sub_set_clock(mgr, rate, &changed);
- else
- err = pcxhr_sub_set_clock(mgr, rate, &changed);
-
- if (err)
- return err;
-
- if (changed) {
- pcxhr_init_rmh(&rmh, CMD_MODIFY_CLOCK);
- rmh.cmd[0] |= PCXHR_MODIFY_CLOCK_S_BIT; /* resync fifos */
- if (rate < PCXHR_IRQ_TIMER_FREQ)
- rmh.cmd[1] = PCXHR_IRQ_TIMER_PERIOD;
- else
- rmh.cmd[1] = PCXHR_IRQ_TIMER_PERIOD * 2;
- rmh.cmd[2] = rate;
- rmh.cmd_len = 3;
- err = pcxhr_send_msg(mgr, &rmh);
- if (err)
- return err;
- }
- return 0;
-}
-
-
-static int pcxhr_sub_get_external_clock(struct pcxhr_mgr *mgr,
- enum pcxhr_clock_type clock_type,
- int *sample_rate)
-{
- struct pcxhr_rmh rmh;
- unsigned char reg;
- int err, rate;
-
- switch (clock_type) {
- case PCXHR_CLOCK_TYPE_WORD_CLOCK:
- reg = REG_STATUS_WORD_CLOCK;
- break;
- case PCXHR_CLOCK_TYPE_AES_SYNC:
- reg = REG_STATUS_AES_SYNC;
- break;
- case PCXHR_CLOCK_TYPE_AES_1:
- reg = REG_STATUS_AES_1;
- break;
- case PCXHR_CLOCK_TYPE_AES_2:
- reg = REG_STATUS_AES_2;
- break;
- case PCXHR_CLOCK_TYPE_AES_3:
- reg = REG_STATUS_AES_3;
- break;
- case PCXHR_CLOCK_TYPE_AES_4:
- reg = REG_STATUS_AES_4;
- break;
- default:
- return -EINVAL;
- }
- pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
- rmh.cmd_len = 2;
- rmh.cmd[0] |= IO_NUM_REG_STATUS;
- if (mgr->last_reg_stat != reg) {
- rmh.cmd[1] = reg;
- err = pcxhr_send_msg(mgr, &rmh);
- if (err)
- return err;
- udelay(100); /* wait minimum 2 sample_frames at 32kHz ! */
- mgr->last_reg_stat = reg;
- }
- rmh.cmd[1] = REG_STATUS_CURRENT;
- err = pcxhr_send_msg(mgr, &rmh);
- if (err)
- return err;
- switch (rmh.stat[1] & 0x0f) {
- case REG_STATUS_SYNC_32000 : rate = 32000; break;
- case REG_STATUS_SYNC_44100 : rate = 44100; break;
- case REG_STATUS_SYNC_48000 : rate = 48000; break;
- case REG_STATUS_SYNC_64000 : rate = 64000; break;
- case REG_STATUS_SYNC_88200 : rate = 88200; break;
- case REG_STATUS_SYNC_96000 : rate = 96000; break;
- case REG_STATUS_SYNC_128000 : rate = 128000; break;
- case REG_STATUS_SYNC_176400 : rate = 176400; break;
- case REG_STATUS_SYNC_192000 : rate = 192000; break;
- default: rate = 0;
- }
- snd_printdd("External clock is at %d Hz\n", rate);
- *sample_rate = rate;
- return 0;
-}
-
-
-int pcxhr_get_external_clock(struct pcxhr_mgr *mgr,
- enum pcxhr_clock_type clock_type,
- int *sample_rate)
-{
- if (mgr->is_hr_stereo)
- return hr222_get_external_clock(mgr, clock_type,
- sample_rate);
- else
- return pcxhr_sub_get_external_clock(mgr, clock_type,
- sample_rate);
-}
-
-/*
- * start or stop playback/capture substream
- */
-static int pcxhr_set_stream_state(struct pcxhr_stream *stream)
-{
- int err;
- struct snd_pcxhr *chip;
- struct pcxhr_rmh rmh;
- int stream_mask, start;
-
- if (stream->status == PCXHR_STREAM_STATUS_SCHEDULE_RUN)
- start = 1;
- else {
- if (stream->status != PCXHR_STREAM_STATUS_SCHEDULE_STOP) {
- snd_printk(KERN_ERR "ERROR pcxhr_set_stream_state "
- "CANNOT be stopped\n");
- return -EINVAL;
- }
- start = 0;
- }
- if (!stream->substream)
- return -EINVAL;
-
- stream->timer_abs_periods = 0;
- stream->timer_period_frag = 0; /* reset theoretical stream pos */
- stream->timer_buf_periods = 0;
- stream->timer_is_synced = 0;
-
- stream_mask =
- stream->pipe->is_capture ? 1 : 1<<stream->substream->number;
-
- pcxhr_init_rmh(&rmh, start ? CMD_START_STREAM : CMD_STOP_STREAM);
- pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture,
- stream->pipe->first_audio, 0, stream_mask);
-
- chip = snd_pcm_substream_chip(stream->substream);
-
- err = pcxhr_send_msg(chip->mgr, &rmh);
- if (err)
- snd_printk(KERN_ERR "ERROR pcxhr_set_stream_state err=%x;\n",
- err);
- stream->status =
- start ? PCXHR_STREAM_STATUS_STARTED : PCXHR_STREAM_STATUS_STOPPED;
- return err;
-}
-
-#define HEADER_FMT_BASE_LIN 0xfed00000
-#define HEADER_FMT_BASE_FLOAT 0xfad00000
-#define HEADER_FMT_INTEL 0x00008000
-#define HEADER_FMT_24BITS 0x00004000
-#define HEADER_FMT_16BITS 0x00002000
-#define HEADER_FMT_UPTO11 0x00000200
-#define HEADER_FMT_UPTO32 0x00000100
-#define HEADER_FMT_MONO 0x00000080
-
-static int pcxhr_set_format(struct pcxhr_stream *stream)
-{
- int err, is_capture, sample_rate, stream_num;
- struct snd_pcxhr *chip;
- struct pcxhr_rmh rmh;
- unsigned int header;
-
- switch (stream->format) {
- case SNDRV_PCM_FORMAT_U8:
- header = HEADER_FMT_BASE_LIN;
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- header = HEADER_FMT_BASE_LIN |
- HEADER_FMT_16BITS | HEADER_FMT_INTEL;
- break;
- case SNDRV_PCM_FORMAT_S16_BE:
- header = HEADER_FMT_BASE_LIN | HEADER_FMT_16BITS;
- break;
- case SNDRV_PCM_FORMAT_S24_3LE:
- header = HEADER_FMT_BASE_LIN |
- HEADER_FMT_24BITS | HEADER_FMT_INTEL;
- break;
- case SNDRV_PCM_FORMAT_S24_3BE:
- header = HEADER_FMT_BASE_LIN | HEADER_FMT_24BITS;
- break;
- case SNDRV_PCM_FORMAT_FLOAT_LE:
- header = HEADER_FMT_BASE_FLOAT | HEADER_FMT_INTEL;
- break;
- default:
- snd_printk(KERN_ERR
- "error pcxhr_set_format() : unknown format\n");
- return -EINVAL;
- }
- chip = snd_pcm_substream_chip(stream->substream);
-
- sample_rate = chip->mgr->sample_rate;
- if (sample_rate <= 32000 && sample_rate !=0) {
- if (sample_rate <= 11025)
- header |= HEADER_FMT_UPTO11;
- else
- header |= HEADER_FMT_UPTO32;
- }
- if (stream->channels == 1)
- header |= HEADER_FMT_MONO;
-
- is_capture = stream->pipe->is_capture;
- stream_num = is_capture ? 0 : stream->substream->number;
-
- pcxhr_init_rmh(&rmh, is_capture ?
- CMD_FORMAT_STREAM_IN : CMD_FORMAT_STREAM_OUT);
- pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio,
- stream_num, 0);
- if (is_capture) {
- /* bug with old dsp versions: */
- /* bit 12 also sets the format of the playback stream */
- if (DSP_EXT_CMD_SET(chip->mgr))
- rmh.cmd[0] |= 1<<10;
- else
- rmh.cmd[0] |= 1<<12;
- }
- rmh.cmd[1] = 0;
- rmh.cmd_len = 2;
- if (DSP_EXT_CMD_SET(chip->mgr)) {
- /* add channels and set bit 19 if channels>2 */
- rmh.cmd[1] = stream->channels;
- if (!is_capture) {
- /* playback : add channel mask to command */
- rmh.cmd[2] = (stream->channels == 1) ? 0x01 : 0x03;
- rmh.cmd_len = 3;
- }
- }
- rmh.cmd[rmh.cmd_len++] = header >> 8;
- rmh.cmd[rmh.cmd_len++] = (header & 0xff) << 16;
- err = pcxhr_send_msg(chip->mgr, &rmh);
- if (err)
- snd_printk(KERN_ERR "ERROR pcxhr_set_format err=%x;\n", err);
- return err;
-}
-
-static int pcxhr_update_r_buffer(struct pcxhr_stream *stream)
-{
- int err, is_capture, stream_num;
- struct pcxhr_rmh rmh;
- struct snd_pcm_substream *subs = stream->substream;
- struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
-
- is_capture = (subs->stream == SNDRV_PCM_STREAM_CAPTURE);
- stream_num = is_capture ? 0 : subs->number;
-
- snd_printdd("pcxhr_update_r_buffer(pcm%c%d) : "
- "addr(%p) bytes(%zx) subs(%d)\n",
- is_capture ? 'c' : 'p',
- chip->chip_idx, (void *)(long)subs->runtime->dma_addr,
- subs->runtime->dma_bytes, subs->number);
-
- pcxhr_init_rmh(&rmh, CMD_UPDATE_R_BUFFERS);
- pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio,
- stream_num, 0);
-
- /* max buffer size is 2 MByte */
- snd_BUG_ON(subs->runtime->dma_bytes >= 0x200000);
- /* size in bits */
- rmh.cmd[1] = subs->runtime->dma_bytes * 8;
- /* most significant byte */
- rmh.cmd[2] = subs->runtime->dma_addr >> 24;
- /* this is a circular buffer */
- rmh.cmd[2] |= 1<<19;
- /* least 3 significant bytes */
- rmh.cmd[3] = subs->runtime->dma_addr & MASK_DSP_WORD;
- rmh.cmd_len = 4;
- err = pcxhr_send_msg(chip->mgr, &rmh);
- if (err)
- snd_printk(KERN_ERR
- "ERROR CMD_UPDATE_R_BUFFERS err=%x;\n", err);
- return err;
-}
-
-
-#if 0
-static int pcxhr_pipe_sample_count(struct pcxhr_stream *stream,
- snd_pcm_uframes_t *sample_count)
-{
- struct pcxhr_rmh rmh;
- int err;
- pcxhr_t *chip = snd_pcm_substream_chip(stream->substream);
- pcxhr_init_rmh(&rmh, CMD_PIPE_SAMPLE_COUNT);
- pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture, 0, 0,
- 1<<stream->pipe->first_audio);
- err = pcxhr_send_msg(chip->mgr, &rmh);
- if (err == 0) {
- *sample_count = ((snd_pcm_uframes_t)rmh.stat[0]) << 24;
- *sample_count += (snd_pcm_uframes_t)rmh.stat[1];
- }
- snd_printdd("PIPE_SAMPLE_COUNT = %lx\n", *sample_count);
- return err;
-}
-#endif
-
-static inline int pcxhr_stream_scheduled_get_pipe(struct pcxhr_stream *stream,
- struct pcxhr_pipe **pipe)
-{
- if (stream->status == PCXHR_STREAM_STATUS_SCHEDULE_RUN) {
- *pipe = stream->pipe;
- return 1;
- }
- return 0;
-}
-
-static void pcxhr_trigger_tasklet(unsigned long arg)
-{
- unsigned long flags;
- int i, j, err;
- struct pcxhr_pipe *pipe;
- struct snd_pcxhr *chip;
- struct pcxhr_mgr *mgr = (struct pcxhr_mgr*)(arg);
- int capture_mask = 0;
- int playback_mask = 0;
-
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- struct timeval my_tv1, my_tv2;
- do_gettimeofday(&my_tv1);
-#endif
- mutex_lock(&mgr->setup_mutex);
-
- /* check the pipes concerned and build pipe_array */
- for (i = 0; i < mgr->num_cards; i++) {
- chip = mgr->chip[i];
- for (j = 0; j < chip->nb_streams_capt; j++) {
- if (pcxhr_stream_scheduled_get_pipe(&chip->capture_stream[j], &pipe))
- capture_mask |= (1 << pipe->first_audio);
- }
- for (j = 0; j < chip->nb_streams_play; j++) {
- if (pcxhr_stream_scheduled_get_pipe(&chip->playback_stream[j], &pipe)) {
- playback_mask |= (1 << pipe->first_audio);
- break; /* add only once, as all playback
- * streams of one chip use the same pipe
- */
- }
- }
- }
- if (capture_mask == 0 && playback_mask == 0) {
- mutex_unlock(&mgr->setup_mutex);
- snd_printk(KERN_ERR "pcxhr_trigger_tasklet : no pipes\n");
- return;
- }
-
- snd_printdd("pcxhr_trigger_tasklet : "
- "playback_mask=%x capture_mask=%x\n",
- playback_mask, capture_mask);
-
- /* synchronous stop of all the pipes concerned */
- err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 0);
- if (err) {
- mutex_unlock(&mgr->setup_mutex);
- snd_printk(KERN_ERR "pcxhr_trigger_tasklet : "
- "error stop pipes (P%x C%x)\n",
- playback_mask, capture_mask);
- return;
- }
-
- /* the dsp lost format and buffer info with the stop pipe */
- for (i = 0; i < mgr->num_cards; i++) {
- struct pcxhr_stream *stream;
- chip = mgr->chip[i];
- for (j = 0; j < chip->nb_streams_capt; j++) {
- stream = &chip->capture_stream[j];
- if (pcxhr_stream_scheduled_get_pipe(stream, &pipe)) {
- err = pcxhr_set_format(stream);
- err = pcxhr_update_r_buffer(stream);
- }
- }
- for (j = 0; j < chip->nb_streams_play; j++) {
- stream = &chip->playback_stream[j];
- if (pcxhr_stream_scheduled_get_pipe(stream, &pipe)) {
- err = pcxhr_set_format(stream);
- err = pcxhr_update_r_buffer(stream);
- }
- }
- }
- /* start all the streams */
- for (i = 0; i < mgr->num_cards; i++) {
- struct pcxhr_stream *stream;
- chip = mgr->chip[i];
- for (j = 0; j < chip->nb_streams_capt; j++) {
- stream = &chip->capture_stream[j];
- if (pcxhr_stream_scheduled_get_pipe(stream, &pipe))
- err = pcxhr_set_stream_state(stream);
- }
- for (j = 0; j < chip->nb_streams_play; j++) {
- stream = &chip->playback_stream[j];
- if (pcxhr_stream_scheduled_get_pipe(stream, &pipe))
- err = pcxhr_set_stream_state(stream);
- }
- }
-
- /* synchronous start of all the pipes concerned */
- err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1);
- if (err) {
- mutex_unlock(&mgr->setup_mutex);
- snd_printk(KERN_ERR "pcxhr_trigger_tasklet : "
- "error start pipes (P%x C%x)\n",
- playback_mask, capture_mask);
- return;
- }
-
- /* put the streams into the running state now
- * (increment pointer by interrupt)
- */
- spin_lock_irqsave(&mgr->lock, flags);
- for ( i =0; i < mgr->num_cards; i++) {
- struct pcxhr_stream *stream;
- chip = mgr->chip[i];
- for(j = 0; j < chip->nb_streams_capt; j++) {
- stream = &chip->capture_stream[j];
- if(stream->status == PCXHR_STREAM_STATUS_STARTED)
- stream->status = PCXHR_STREAM_STATUS_RUNNING;
- }
- for (j = 0; j < chip->nb_streams_play; j++) {
- stream = &chip->playback_stream[j];
- if (stream->status == PCXHR_STREAM_STATUS_STARTED) {
- /* playback will already have advanced ! */
- stream->timer_period_frag += mgr->granularity;
- stream->status = PCXHR_STREAM_STATUS_RUNNING;
- }
- }
- }
- spin_unlock_irqrestore(&mgr->lock, flags);
-
- mutex_unlock(&mgr->setup_mutex);
-
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- do_gettimeofday(&my_tv2);
- snd_printdd("***TRIGGER TASKLET*** TIME = %ld (err = %x)\n",
- (long)(my_tv2.tv_usec - my_tv1.tv_usec), err);
-#endif
-}
-
-
-/*
- * trigger callback
- */
-static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd)
-{
- struct pcxhr_stream *stream;
- struct snd_pcm_substream *s;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- snd_printdd("SNDRV_PCM_TRIGGER_START\n");
- if (snd_pcm_stream_linked(subs)) {
- struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
- snd_pcm_group_for_each_entry(s, subs) {
- if (snd_pcm_substream_chip(s) != chip)
- continue;
- stream = s->runtime->private_data;
- stream->status =
- PCXHR_STREAM_STATUS_SCHEDULE_RUN;
- snd_pcm_trigger_done(s, subs);
- }
- tasklet_schedule(&chip->mgr->trigger_taskq);
- } else {
- stream = subs->runtime->private_data;
- snd_printdd("Only one Substream %c %d\n",
- stream->pipe->is_capture ? 'C' : 'P',
- stream->pipe->first_audio);
- if (pcxhr_set_format(stream))
- return -EINVAL;
- if (pcxhr_update_r_buffer(stream))
- return -EINVAL;
-
- stream->status = PCXHR_STREAM_STATUS_SCHEDULE_RUN;
- if (pcxhr_set_stream_state(stream))
- return -EINVAL;
- stream->status = PCXHR_STREAM_STATUS_RUNNING;
- }
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- snd_printdd("SNDRV_PCM_TRIGGER_STOP\n");
- snd_pcm_group_for_each_entry(s, subs) {
- stream = s->runtime->private_data;
- stream->status = PCXHR_STREAM_STATUS_SCHEDULE_STOP;
- if (pcxhr_set_stream_state(stream))
- return -EINVAL;
- snd_pcm_trigger_done(s, subs);
- }
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- /* TODO */
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-
-static int pcxhr_hardware_timer(struct pcxhr_mgr *mgr, int start)
-{
- struct pcxhr_rmh rmh;
- int err;
-
- pcxhr_init_rmh(&rmh, CMD_SET_TIMER_INTERRUPT);
- if (start) {
- /* last dsp time invalid */
- mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID;
- rmh.cmd[0] |= mgr->granularity;
- }
- err = pcxhr_send_msg(mgr, &rmh);
- if (err < 0)
- snd_printk(KERN_ERR "error pcxhr_hardware_timer err(%x)\n",
- err);
- return err;
-}
-
-/*
- * prepare callback for all pcms
- */
-static int pcxhr_prepare(struct snd_pcm_substream *subs)
-{
- struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
- struct pcxhr_mgr *mgr = chip->mgr;
- int err = 0;
-
- snd_printdd("pcxhr_prepare : period_size(%lx) periods(%x) buffer_size(%lx)\n",
- subs->runtime->period_size, subs->runtime->periods,
- subs->runtime->buffer_size);
-
- mutex_lock(&mgr->setup_mutex);
-
- do {
- /* only the first stream can choose the sample rate */
- /* set the clock only once (first stream) */
- if (mgr->sample_rate != subs->runtime->rate) {
- err = pcxhr_set_clock(mgr, subs->runtime->rate);
- if (err)
- break;
- if (mgr->sample_rate == 0)
- /* start the DSP-timer */
- err = pcxhr_hardware_timer(mgr, 1);
- mgr->sample_rate = subs->runtime->rate;
- }
- } while(0); /* do only once (so we can use break instead of goto) */
-
- mutex_unlock(&mgr->setup_mutex);
-
- return err;
-}
-
-
-/*
- * HW_PARAMS callback for all pcms
- */
-static int pcxhr_hw_params(struct snd_pcm_substream *subs,
- struct snd_pcm_hw_params *hw)
-{
- struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
- struct pcxhr_mgr *mgr = chip->mgr;
- struct pcxhr_stream *stream = subs->runtime->private_data;
- snd_pcm_format_t format;
- int err;
- int channels;
-
- /* set up channels */
- channels = params_channels(hw);
-
- /* set up format for the stream */
- format = params_format(hw);
-
- mutex_lock(&mgr->setup_mutex);
-
- stream->channels = channels;
- stream->format = format;
-
- /* allocate buffer */
- err = snd_pcm_lib_malloc_pages(subs, params_buffer_bytes(hw));
-
- mutex_unlock(&mgr->setup_mutex);
-
- return err;
-}
-
-static int pcxhr_hw_free(struct snd_pcm_substream *subs)
-{
- snd_pcm_lib_free_pages(subs);
- return 0;
-}
-
-
-/*
- * CONFIGURATION SPACE for all pcms, mono pcm must update channels_max
- */
-static struct snd_pcm_hardware pcxhr_caps =
-{
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_SYNC_START),
- .formats = (SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S24_3BE |
- SNDRV_PCM_FMTBIT_FLOAT_LE),
- .rates = (SNDRV_PCM_RATE_CONTINUOUS |
- SNDRV_PCM_RATE_8000_192000),
- .rate_min = 8000,
- .rate_max = 192000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (32*1024),
- /* 1 byte == 1 frame U8 mono (PCXHR_GRANULARITY is frames!) */
- .period_bytes_min = (2*PCXHR_GRANULARITY),
- .period_bytes_max = (16*1024),
- .periods_min = 2,
- .periods_max = (32*1024/PCXHR_GRANULARITY),
-};
-
-
-static int pcxhr_open(struct snd_pcm_substream *subs)
-{
- struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
- struct pcxhr_mgr *mgr = chip->mgr;
- struct snd_pcm_runtime *runtime = subs->runtime;
- struct pcxhr_stream *stream;
- int err;
-
- mutex_lock(&mgr->setup_mutex);
-
- /* copy the struct snd_pcm_hardware struct */
- runtime->hw = pcxhr_caps;
-
- if( subs->stream == SNDRV_PCM_STREAM_PLAYBACK ) {
- snd_printdd("pcxhr_open playback chip%d subs%d\n",
- chip->chip_idx, subs->number);
- stream = &chip->playback_stream[subs->number];
- } else {
- snd_printdd("pcxhr_open capture chip%d subs%d\n",
- chip->chip_idx, subs->number);
- if (mgr->mono_capture)
- runtime->hw.channels_max = 1;
- else
- runtime->hw.channels_min = 2;
- stream = &chip->capture_stream[subs->number];
- }
- if (stream->status != PCXHR_STREAM_STATUS_FREE){
- /* streams in use */
- snd_printk(KERN_ERR "pcxhr_open chip%d subs%d in use\n",
- chip->chip_idx, subs->number);
- mutex_unlock(&mgr->setup_mutex);
- return -EBUSY;
- }
-
- /* float format support is in some cases buggy on stereo cards */
- if (mgr->is_hr_stereo)
- runtime->hw.formats &= ~SNDRV_PCM_FMTBIT_FLOAT_LE;
-
- /* buffer-size should better be multiple of period-size */
- err = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0) {
- mutex_unlock(&mgr->setup_mutex);
- return err;
- }
-
- /* if a sample rate is already used or fixed by external clock,
- * the stream cannot change
- */
- if (mgr->sample_rate)
- runtime->hw.rate_min = runtime->hw.rate_max = mgr->sample_rate;
- else {
- if (mgr->use_clock_type != PCXHR_CLOCK_TYPE_INTERNAL) {
- int external_rate;
- if (pcxhr_get_external_clock(mgr, mgr->use_clock_type,
- &external_rate) ||
- external_rate == 0) {
- /* cannot detect the external clock rate */
- mutex_unlock(&mgr->setup_mutex);
- return -EBUSY;
- }
- runtime->hw.rate_min = external_rate;
- runtime->hw.rate_max = external_rate;
- }
- }
-
- stream->status = PCXHR_STREAM_STATUS_OPEN;
- stream->substream = subs;
- stream->channels = 0; /* not configured yet */
-
- runtime->private_data = stream;
-
- /* better get a divisor of granularity values (96 or 192) */
- snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 32);
- snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 32);
- snd_pcm_set_sync(subs);
-
- mgr->ref_count_rate++;
-
- mutex_unlock(&mgr->setup_mutex);
- return 0;
-}
-
-
-static int pcxhr_close(struct snd_pcm_substream *subs)
-{
- struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
- struct pcxhr_mgr *mgr = chip->mgr;
- struct pcxhr_stream *stream = subs->runtime->private_data;
-
- mutex_lock(&mgr->setup_mutex);
-
- snd_printdd("pcxhr_close chip%d subs%d\n",
- chip->chip_idx, subs->number);
-
- /* sample rate released */
- if (--mgr->ref_count_rate == 0) {
- mgr->sample_rate = 0; /* the sample rate is no more locked */
- pcxhr_hardware_timer(mgr, 0); /* stop the DSP-timer */
- }
-
- stream->status = PCXHR_STREAM_STATUS_FREE;
- stream->substream = NULL;
-
- mutex_unlock(&mgr->setup_mutex);
-
- return 0;
-}
-
-
-static snd_pcm_uframes_t pcxhr_stream_pointer(struct snd_pcm_substream *subs)
-{
- unsigned long flags;
- u_int32_t timer_period_frag;
- int timer_buf_periods;
- struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
- struct snd_pcm_runtime *runtime = subs->runtime;
- struct pcxhr_stream *stream = runtime->private_data;
-
- spin_lock_irqsave(&chip->mgr->lock, flags);
-
- /* get the period fragment and the nb of periods in the buffer */
- timer_period_frag = stream->timer_period_frag;
- timer_buf_periods = stream->timer_buf_periods;
-
- spin_unlock_irqrestore(&chip->mgr->lock, flags);
-
- return (snd_pcm_uframes_t)((timer_buf_periods * runtime->period_size) +
- timer_period_frag);
-}
-
-
-static struct snd_pcm_ops pcxhr_ops = {
- .open = pcxhr_open,
- .close = pcxhr_close,
- .ioctl = snd_pcm_lib_ioctl,
- .prepare = pcxhr_prepare,
- .hw_params = pcxhr_hw_params,
- .hw_free = pcxhr_hw_free,
- .trigger = pcxhr_trigger,
- .pointer = pcxhr_stream_pointer,
-};
-
-/*
- */
-int pcxhr_create_pcm(struct snd_pcxhr *chip)
-{
- int err;
- struct snd_pcm *pcm;
- char name[32];
-
- sprintf(name, "pcxhr %d", chip->chip_idx);
- if ((err = snd_pcm_new(chip->card, name, 0,
- chip->nb_streams_play,
- chip->nb_streams_capt, &pcm)) < 0) {
- snd_printk(KERN_ERR "cannot create pcm %s\n", name);
- return err;
- }
- pcm->private_data = chip;
-
- if (chip->nb_streams_play)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcxhr_ops);
- if (chip->nb_streams_capt)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcxhr_ops);
-
- pcm->info_flags = 0;
- strcpy(pcm->name, name);
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->mgr->pci),
- 32*1024, 32*1024);
- chip->pcm = pcm;
- return 0;
-}
-
-static int pcxhr_chip_free(struct snd_pcxhr *chip)
-{
- kfree(chip);
- return 0;
-}
-
-static int pcxhr_chip_dev_free(struct snd_device *device)
-{
- struct snd_pcxhr *chip = device->device_data;
- return pcxhr_chip_free(chip);
-}
-
-
-/*
- */
-static int __devinit pcxhr_create(struct pcxhr_mgr *mgr,
- struct snd_card *card, int idx)
-{
- int err;
- struct snd_pcxhr *chip;
- static struct snd_device_ops ops = {
- .dev_free = pcxhr_chip_dev_free,
- };
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (! chip) {
- snd_printk(KERN_ERR "cannot allocate chip\n");
- return -ENOMEM;
- }
-
- chip->card = card;
- chip->chip_idx = idx;
- chip->mgr = mgr;
-
- if (idx < mgr->playback_chips)
- /* stereo or mono streams */
- chip->nb_streams_play = PCXHR_PLAYBACK_STREAMS;
-
- if (idx < mgr->capture_chips) {
- if (mgr->mono_capture)
- chip->nb_streams_capt = 2; /* 2 mono streams */
- else
- chip->nb_streams_capt = 1; /* or 1 stereo stream */
- }
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- pcxhr_chip_free(chip);
- return err;
- }
-
- mgr->chip[idx] = chip;
- snd_card_set_dev(card, &mgr->pci->dev);
-
- return 0;
-}
-
-/* proc interface */
-static void pcxhr_proc_info(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_pcxhr *chip = entry->private_data;
- struct pcxhr_mgr *mgr = chip->mgr;
-
- snd_iprintf(buffer, "\n%s\n", mgr->longname);
-
- /* stats available when embedded DSP is running */
- if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {
- struct pcxhr_rmh rmh;
- short ver_maj = (mgr->dsp_version >> 16) & 0xff;
- short ver_min = (mgr->dsp_version >> 8) & 0xff;
- short ver_build = mgr->dsp_version & 0xff;
- snd_iprintf(buffer, "module version %s\n",
- PCXHR_DRIVER_VERSION_STRING);
- snd_iprintf(buffer, "dsp version %d.%d.%d\n",
- ver_maj, ver_min, ver_build);
- if (mgr->board_has_analog)
- snd_iprintf(buffer, "analog io available\n");
- else
- snd_iprintf(buffer, "digital only board\n");
-
- /* calc cpu load of the dsp */
- pcxhr_init_rmh(&rmh, CMD_GET_DSP_RESOURCES);
- if( ! pcxhr_send_msg(mgr, &rmh) ) {
- int cur = rmh.stat[0];
- int ref = rmh.stat[1];
- if (ref > 0) {
- if (mgr->sample_rate_real != 0 &&
- mgr->sample_rate_real != 48000) {
- ref = (ref * 48000) /
- mgr->sample_rate_real;
- if (mgr->sample_rate_real >=
- PCXHR_IRQ_TIMER_FREQ)
- ref *= 2;
- }
- cur = 100 - (100 * cur) / ref;
- snd_iprintf(buffer, "cpu load %d%%\n", cur);
- snd_iprintf(buffer, "buffer pool %d/%d\n",
- rmh.stat[2], rmh.stat[3]);
- }
- }
- snd_iprintf(buffer, "dma granularity : %d\n",
- mgr->granularity);
- snd_iprintf(buffer, "dsp time errors : %d\n",
- mgr->dsp_time_err);
- snd_iprintf(buffer, "dsp async pipe xrun errors : %d\n",
- mgr->async_err_pipe_xrun);
- snd_iprintf(buffer, "dsp async stream xrun errors : %d\n",
- mgr->async_err_stream_xrun);
- snd_iprintf(buffer, "dsp async last other error : %x\n",
- mgr->async_err_other_last);
- /* debug zone dsp */
- rmh.cmd[0] = 0x4200 + PCXHR_SIZE_MAX_STATUS;
- rmh.cmd_len = 1;
- rmh.stat_len = PCXHR_SIZE_MAX_STATUS;
- rmh.dsp_stat = 0;
- rmh.cmd_idx = CMD_LAST_INDEX;
- if( ! pcxhr_send_msg(mgr, &rmh) ) {
- int i;
- if (rmh.stat_len > 8)
- rmh.stat_len = 8;
- for (i = 0; i < rmh.stat_len; i++)
- snd_iprintf(buffer, "debug[%02d] = %06x\n",
- i, rmh.stat[i]);
- }
- } else
- snd_iprintf(buffer, "no firmware loaded\n");
- snd_iprintf(buffer, "\n");
-}
-static void pcxhr_proc_sync(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_pcxhr *chip = entry->private_data;
- struct pcxhr_mgr *mgr = chip->mgr;
- static const char *textsHR22[3] = {
- "Internal", "AES Sync", "AES 1"
- };
- static const char *textsPCXHR[7] = {
- "Internal", "Word", "AES Sync",
- "AES 1", "AES 2", "AES 3", "AES 4"
- };
- const char **texts;
- int max_clock;
- if (mgr->is_hr_stereo) {
- texts = textsHR22;
- max_clock = HR22_CLOCK_TYPE_MAX;
- } else {
- texts = textsPCXHR;
- max_clock = PCXHR_CLOCK_TYPE_MAX;
- }
-
- snd_iprintf(buffer, "\n%s\n", mgr->longname);
- snd_iprintf(buffer, "Current Sample Clock\t: %s\n",
- texts[mgr->cur_clock_type]);
- snd_iprintf(buffer, "Current Sample Rate\t= %d\n",
- mgr->sample_rate_real);
- /* commands available when embedded DSP is running */
- if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {
- int i, err, sample_rate;
- for (i = 1; i <= max_clock; i++) {
- err = pcxhr_get_external_clock(mgr, i, &sample_rate);
- if (err)
- break;
- snd_iprintf(buffer, "%s Clock\t\t= %d\n",
- texts[i], sample_rate);
- }
- } else
- snd_iprintf(buffer, "no firmware loaded\n");
- snd_iprintf(buffer, "\n");
-}
-
-static void pcxhr_proc_gpio_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_pcxhr *chip = entry->private_data;
- struct pcxhr_mgr *mgr = chip->mgr;
- /* commands available when embedded DSP is running */
- if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {
- /* gpio ports on stereo boards only available */
- int value = 0;
- hr222_read_gpio(mgr, 1, &value); /* GPI */
- snd_iprintf(buffer, "GPI: 0x%x\n", value);
- hr222_read_gpio(mgr, 0, &value); /* GP0 */
- snd_iprintf(buffer, "GPO: 0x%x\n", value);
- } else
- snd_iprintf(buffer, "no firmware loaded\n");
- snd_iprintf(buffer, "\n");
-}
-static void pcxhr_proc_gpo_write(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_pcxhr *chip = entry->private_data;
- struct pcxhr_mgr *mgr = chip->mgr;
- char line[64];
- int value;
- /* commands available when embedded DSP is running */
- if (!(mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)))
- return;
- while (!snd_info_get_line(buffer, line, sizeof(line))) {
- if (sscanf(line, "GPO: 0x%x", &value) != 1)
- continue;
- hr222_write_gpo(mgr, value); /* GP0 */
- }
-}
-
-static void __devinit pcxhr_proc_init(struct snd_pcxhr *chip)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(chip->card, "info", &entry))
- snd_info_set_text_ops(entry, chip, pcxhr_proc_info);
- if (! snd_card_proc_new(chip->card, "sync", &entry))
- snd_info_set_text_ops(entry, chip, pcxhr_proc_sync);
- /* gpio available on stereo sound cards only */
- if (chip->mgr->is_hr_stereo &&
- !snd_card_proc_new(chip->card, "gpio", &entry)) {
- snd_info_set_text_ops(entry, chip, pcxhr_proc_gpio_read);
- entry->c.text.write = pcxhr_proc_gpo_write;
- entry->mode |= S_IWUSR;
- }
-}
-/* end of proc interface */
-
-/*
- * release all the cards assigned to a manager instance
- */
-static int pcxhr_free(struct pcxhr_mgr *mgr)
-{
- unsigned int i;
-
- for (i = 0; i < mgr->num_cards; i++) {
- if (mgr->chip[i])
- snd_card_free(mgr->chip[i]->card);
- }
-
- /* reset board if some firmware was loaded */
- if(mgr->dsp_loaded) {
- pcxhr_reset_board(mgr);
- snd_printdd("reset pcxhr !\n");
- }
-
- /* release irq */
- if (mgr->irq >= 0)
- free_irq(mgr->irq, mgr);
-
- pci_release_regions(mgr->pci);
-
- /* free hostport purgebuffer */
- if (mgr->hostport.area) {
- snd_dma_free_pages(&mgr->hostport);
- mgr->hostport.area = NULL;
- }
-
- kfree(mgr->prmh);
-
- pci_disable_device(mgr->pci);
- kfree(mgr);
- return 0;
-}
-
-/*
- * probe function - creates the card manager
- */
-static int __devinit pcxhr_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct pcxhr_mgr *mgr;
- unsigned int i;
- int err;
- size_t size;
- char *card_name;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (! enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- /* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
- return err;
- pci_set_master(pci);
-
- /* check if we can restrict PCI DMA transfers to 32 bits */
- if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0) {
- snd_printk(KERN_ERR "architecture does not support "
- "32bit PCI busmaster DMA\n");
- pci_disable_device(pci);
- return -ENXIO;
- }
-
- /* alloc card manager */
- mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
- if (! mgr) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- if (snd_BUG_ON(pci_id->driver_data >= PCI_ID_LAST)) {
- kfree(mgr);
- pci_disable_device(pci);
- return -ENODEV;
- }
- card_name =
- pcxhr_board_params[pci_id->driver_data].board_name;
- mgr->playback_chips =
- pcxhr_board_params[pci_id->driver_data].playback_chips;
- mgr->capture_chips =
- pcxhr_board_params[pci_id->driver_data].capture_chips;
- mgr->fw_file_set =
- pcxhr_board_params[pci_id->driver_data].fw_file_set;
- mgr->firmware_num =
- pcxhr_board_params[pci_id->driver_data].firmware_num;
- mgr->mono_capture = mono[dev];
- mgr->is_hr_stereo = (mgr->playback_chips == 1);
- mgr->board_has_aes1 = PCXHR_BOARD_HAS_AES1(mgr);
- mgr->board_aes_in_192k = !PCXHR_BOARD_AESIN_NO_192K(mgr);
-
- if (mgr->is_hr_stereo)
- mgr->granularity = PCXHR_GRANULARITY_HR22;
- else
- mgr->granularity = PCXHR_GRANULARITY;
-
- /* resource assignment */
- if ((err = pci_request_regions(pci, card_name)) < 0) {
- kfree(mgr);
- pci_disable_device(pci);
- return err;
- }
- for (i = 0; i < 3; i++)
- mgr->port[i] = pci_resource_start(pci, i);
-
- mgr->pci = pci;
- mgr->irq = -1;
-
- if (request_irq(pci->irq, pcxhr_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, mgr)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- pcxhr_free(mgr);
- return -EBUSY;
- }
- mgr->irq = pci->irq;
-
- sprintf(mgr->shortname, "Digigram %s", card_name);
- sprintf(mgr->longname, "%s at 0x%lx & 0x%lx, 0x%lx irq %i",
- mgr->shortname,
- mgr->port[0], mgr->port[1], mgr->port[2], mgr->irq);
-
- /* ISR spinlock */
- spin_lock_init(&mgr->lock);
- spin_lock_init(&mgr->msg_lock);
-
- /* init setup mutex*/
- mutex_init(&mgr->setup_mutex);
-
- /* init taslket */
- tasklet_init(&mgr->msg_taskq, pcxhr_msg_tasklet,
- (unsigned long) mgr);
- tasklet_init(&mgr->trigger_taskq, pcxhr_trigger_tasklet,
- (unsigned long) mgr);
-
- mgr->prmh = kmalloc(sizeof(*mgr->prmh) +
- sizeof(u32) * (PCXHR_SIZE_MAX_LONG_STATUS -
- PCXHR_SIZE_MAX_STATUS),
- GFP_KERNEL);
- if (! mgr->prmh) {
- pcxhr_free(mgr);
- return -ENOMEM;
- }
-
- for (i=0; i < PCXHR_MAX_CARDS; i++) {
- struct snd_card *card;
- char tmpid[16];
- int idx;
-
- if (i >= max(mgr->playback_chips, mgr->capture_chips))
- break;
- mgr->num_cards++;
-
- if (index[dev] < 0)
- idx = index[dev];
- else
- idx = index[dev] + i;
-
- snprintf(tmpid, sizeof(tmpid), "%s-%d",
- id[dev] ? id[dev] : card_name, i);
- err = snd_card_create(idx, tmpid, THIS_MODULE, 0, &card);
-
- if (err < 0) {
- snd_printk(KERN_ERR "cannot allocate the card %d\n", i);
- pcxhr_free(mgr);
- return err;
- }
-
- strcpy(card->driver, DRIVER_NAME);
- sprintf(card->shortname, "%s [PCM #%d]", mgr->shortname, i);
- sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i);
-
- if ((err = pcxhr_create(mgr, card, i)) < 0) {
- snd_card_free(card);
- pcxhr_free(mgr);
- return err;
- }
-
- if (i == 0)
- /* init proc interface only for chip0 */
- pcxhr_proc_init(mgr->chip[i]);
-
- if ((err = snd_card_register(card)) < 0) {
- pcxhr_free(mgr);
- return err;
- }
- }
-
- /* create hostport purgebuffer */
- size = PAGE_ALIGN(sizeof(struct pcxhr_hostport));
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
- size, &mgr->hostport) < 0) {
- pcxhr_free(mgr);
- return -ENOMEM;
- }
- /* init purgebuffer */
- memset(mgr->hostport.area, 0, size);
-
- /* create a DSP loader */
- err = pcxhr_setup_firmware(mgr);
- if (err < 0) {
- pcxhr_free(mgr);
- return err;
- }
-
- pci_set_drvdata(pci, mgr);
- dev++;
- return 0;
-}
-
-static void __devexit pcxhr_remove(struct pci_dev *pci)
-{
- pcxhr_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = pcxhr_ids,
- .probe = pcxhr_probe,
- .remove = __devexit_p(pcxhr_remove),
-};
-
-static int __init pcxhr_module_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit pcxhr_module_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(pcxhr_module_init)
-module_exit(pcxhr_module_exit)
diff --git a/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr.h b/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr.h
deleted file mode 100644
index bda776c4..00000000
--- a/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr.h
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Driver for Digigram pcxhr soundcards
- *
- * main header file
- *
- * Copyright (c) 2004 by Digigram <alsa@digigram.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __SOUND_PCXHR_H
-#define __SOUND_PCXHR_H
-
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <sound/pcm.h>
-
-#define PCXHR_DRIVER_VERSION 0x000906 /* 0.9.6 */
-#define PCXHR_DRIVER_VERSION_STRING "0.9.6" /* 0.9.6 */
-
-
-#define PCXHR_MAX_CARDS 6
-#define PCXHR_PLAYBACK_STREAMS 4
-
-#define PCXHR_GRANULARITY 96 /* min 96 and multiple of 48 */
-/* transfer granularity of pipes and the dsp time (MBOX4) */
-#define PCXHR_GRANULARITY_MIN 96
-/* TODO : granularity could be 64 or 128 */
-#define PCXHR_GRANULARITY_HR22 192 /* granularity for stereo cards */
-
-struct snd_pcxhr;
-struct pcxhr_mgr;
-
-struct pcxhr_stream;
-struct pcxhr_pipe;
-
-enum pcxhr_clock_type {
- PCXHR_CLOCK_TYPE_INTERNAL = 0,
- PCXHR_CLOCK_TYPE_WORD_CLOCK,
- PCXHR_CLOCK_TYPE_AES_SYNC,
- PCXHR_CLOCK_TYPE_AES_1,
- PCXHR_CLOCK_TYPE_AES_2,
- PCXHR_CLOCK_TYPE_AES_3,
- PCXHR_CLOCK_TYPE_AES_4,
- PCXHR_CLOCK_TYPE_MAX = PCXHR_CLOCK_TYPE_AES_4,
- HR22_CLOCK_TYPE_INTERNAL = PCXHR_CLOCK_TYPE_INTERNAL,
- HR22_CLOCK_TYPE_AES_SYNC,
- HR22_CLOCK_TYPE_AES_1,
- HR22_CLOCK_TYPE_MAX = HR22_CLOCK_TYPE_AES_1,
-};
-
-struct pcxhr_mgr {
- unsigned int num_cards;
- struct snd_pcxhr *chip[PCXHR_MAX_CARDS];
-
- struct pci_dev *pci;
-
- int irq;
-
- int granularity;
-
- /* card access with 1 mem bar and 2 io bar's */
- unsigned long port[3];
-
- /* share the name */
- char shortname[32]; /* short name of this soundcard */
- char longname[96]; /* name of this soundcard */
-
- /* message tasklet */
- struct tasklet_struct msg_taskq;
- struct pcxhr_rmh *prmh;
- /* trigger tasklet */
- struct tasklet_struct trigger_taskq;
-
- spinlock_t lock; /* interrupt spinlock */
- spinlock_t msg_lock; /* message spinlock */
-
- struct mutex setup_mutex; /* mutex used in hw_params, open and close */
- struct mutex mixer_mutex; /* mutex for mixer */
-
- /* hardware interface */
- unsigned int dsp_loaded; /* bit flags of loaded dsp indices */
- unsigned int dsp_version; /* read from embedded once firmware is loaded */
- int playback_chips;
- int capture_chips;
- int fw_file_set;
- int firmware_num;
- unsigned int is_hr_stereo:1;
- unsigned int board_has_aes1:1; /* if 1 board has AES1 plug and SRC */
- unsigned int board_has_analog:1; /* if 0 the board is digital only */
- unsigned int board_has_mic:1; /* if 1 the board has microphone input */
- unsigned int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */
- unsigned int mono_capture:1; /* if 1 the board does mono capture */
-
- struct snd_dma_buffer hostport;
-
- enum pcxhr_clock_type use_clock_type; /* clock type selected by mixer */
- enum pcxhr_clock_type cur_clock_type; /* current clock type synced */
- int sample_rate;
- int ref_count_rate;
- int timer_toggle; /* timer interrupt toggles between the two values 0x200 and 0x300 */
- int dsp_time_last; /* the last dsp time (read by interrupt) */
- int dsp_time_err; /* dsp time errors */
- unsigned int src_it_dsp; /* dsp interrupt source */
- unsigned int io_num_reg_cont; /* backup of IO_NUM_REG_CONT */
- unsigned int codec_speed; /* speed mode of the codecs */
- unsigned int sample_rate_real; /* current real sample rate */
- int last_reg_stat;
- int async_err_stream_xrun;
- int async_err_pipe_xrun;
- int async_err_other_last;
-
- unsigned char xlx_cfg; /* copy of PCXHR_XLX_CFG register */
- unsigned char xlx_selmic; /* copy of PCXHR_XLX_SELMIC register */
- unsigned char dsp_reset; /* copy of PCXHR_DSP_RESET register */
-};
-
-
-enum pcxhr_stream_status {
- PCXHR_STREAM_STATUS_FREE,
- PCXHR_STREAM_STATUS_OPEN,
- PCXHR_STREAM_STATUS_SCHEDULE_RUN,
- PCXHR_STREAM_STATUS_STARTED,
- PCXHR_STREAM_STATUS_RUNNING,
- PCXHR_STREAM_STATUS_SCHEDULE_STOP,
- PCXHR_STREAM_STATUS_STOPPED,
- PCXHR_STREAM_STATUS_PAUSED
-};
-
-struct pcxhr_stream {
- struct snd_pcm_substream *substream;
- snd_pcm_format_t format;
- struct pcxhr_pipe *pipe;
-
- enum pcxhr_stream_status status; /* free, open, running, draining, pause */
-
- u_int64_t timer_abs_periods; /* timer: samples elapsed since TRIGGER_START (multiple of period_size) */
- u_int32_t timer_period_frag; /* timer: samples elapsed since last call to snd_pcm_period_elapsed (0..period_size) */
- u_int32_t timer_buf_periods; /* nb of periods in the buffer that have already elapsed */
- int timer_is_synced; /* if(0) : timer needs to be resynced with real hardware pointer */
-
- int channels;
-};
-
-
-enum pcxhr_pipe_status {
- PCXHR_PIPE_UNDEFINED,
- PCXHR_PIPE_DEFINED
-};
-
-struct pcxhr_pipe {
- enum pcxhr_pipe_status status;
- int is_capture; /* this is a capture pipe */
- int first_audio; /* first audio num */
-};
-
-
-struct snd_pcxhr {
- struct snd_card *card;
- struct pcxhr_mgr *mgr;
- int chip_idx; /* zero based */
-
- struct snd_pcm *pcm; /* PCM */
-
- struct pcxhr_pipe playback_pipe; /* 1 stereo pipe only */
- struct pcxhr_pipe capture_pipe[2]; /* 1 stereo or 2 mono pipes */
-
- struct pcxhr_stream playback_stream[PCXHR_PLAYBACK_STREAMS];
- struct pcxhr_stream capture_stream[2]; /* 1 stereo or 2 mono streams */
- int nb_streams_play;
- int nb_streams_capt;
-
- int analog_playback_active[2]; /* Mixer : Master Playback !mute */
- int analog_playback_volume[2]; /* Mixer : Master Playback Volume */
- int analog_capture_volume[2]; /* Mixer : Master Capture Volume */
- int digital_playback_active[PCXHR_PLAYBACK_STREAMS][2];
- int digital_playback_volume[PCXHR_PLAYBACK_STREAMS][2];
- int digital_capture_volume[2]; /* Mixer : Digital Capture Volume */
- int monitoring_active[2]; /* Mixer : Monitoring Active */
- int monitoring_volume[2]; /* Mixer : Monitoring Volume */
- int audio_capture_source; /* Mixer : Audio Capture Source */
- int mic_volume; /* used by cards with MIC only */
- int mic_boost; /* used by cards with MIC only */
- int mic_active; /* used by cards with MIC only */
- int analog_capture_active; /* used by cards with MIC only */
- int phantom_power; /* used by cards with MIC only */
-
- unsigned char aes_bits[5]; /* Mixer : IEC958_AES bits */
-};
-
-struct pcxhr_hostport
-{
- char purgebuffer[6];
- char reserved[2];
-};
-
-/* exported */
-int pcxhr_create_pcm(struct snd_pcxhr *chip);
-int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate);
-int pcxhr_get_external_clock(struct pcxhr_mgr *mgr,
- enum pcxhr_clock_type clock_type,
- int *sample_rate);
-
-#endif /* __SOUND_PCXHR_H */
diff --git a/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_core.c b/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_core.c
deleted file mode 100644
index 304411c1..00000000
--- a/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_core.c
+++ /dev/null
@@ -1,1305 +0,0 @@
-/*
- * Driver for Digigram pcxhr compatible soundcards
- *
- * low level interface with interrupt and message handling implementation
- *
- * Copyright (c) 2004 by Digigram <alsa@digigram.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/delay.h>
-#include <linux/firmware.h>
-#include <linux/interrupt.h>
-#include <asm/io.h>
-#include <sound/core.h>
-#include "pcxhr.h"
-#include "pcxhr_mixer.h"
-#include "pcxhr_hwdep.h"
-#include "pcxhr_core.h"
-
-
-/* registers used on the PLX (port 1) */
-#define PCXHR_PLX_OFFSET_MIN 0x40
-#define PCXHR_PLX_MBOX0 0x40
-#define PCXHR_PLX_MBOX1 0x44
-#define PCXHR_PLX_MBOX2 0x48
-#define PCXHR_PLX_MBOX3 0x4C
-#define PCXHR_PLX_MBOX4 0x50
-#define PCXHR_PLX_MBOX5 0x54
-#define PCXHR_PLX_MBOX6 0x58
-#define PCXHR_PLX_MBOX7 0x5C
-#define PCXHR_PLX_L2PCIDB 0x64
-#define PCXHR_PLX_IRQCS 0x68
-#define PCXHR_PLX_CHIPSC 0x6C
-
-/* registers used on the DSP (port 2) */
-#define PCXHR_DSP_ICR 0x00
-#define PCXHR_DSP_CVR 0x04
-#define PCXHR_DSP_ISR 0x08
-#define PCXHR_DSP_IVR 0x0C
-#define PCXHR_DSP_RXH 0x14
-#define PCXHR_DSP_TXH 0x14
-#define PCXHR_DSP_RXM 0x18
-#define PCXHR_DSP_TXM 0x18
-#define PCXHR_DSP_RXL 0x1C
-#define PCXHR_DSP_TXL 0x1C
-#define PCXHR_DSP_RESET 0x20
-#define PCXHR_DSP_OFFSET_MAX 0x20
-
-/* access to the card */
-#define PCXHR_PLX 1
-#define PCXHR_DSP 2
-
-#if (PCXHR_DSP_OFFSET_MAX > PCXHR_PLX_OFFSET_MIN)
-#undef PCXHR_REG_TO_PORT(x)
-#else
-#define PCXHR_REG_TO_PORT(x) ((x)>PCXHR_DSP_OFFSET_MAX ? PCXHR_PLX : PCXHR_DSP)
-#endif
-#define PCXHR_INPB(mgr,x) inb((mgr)->port[PCXHR_REG_TO_PORT(x)] + (x))
-#define PCXHR_INPL(mgr,x) inl((mgr)->port[PCXHR_REG_TO_PORT(x)] + (x))
-#define PCXHR_OUTPB(mgr,x,data) outb((data), (mgr)->port[PCXHR_REG_TO_PORT(x)] + (x))
-#define PCXHR_OUTPL(mgr,x,data) outl((data), (mgr)->port[PCXHR_REG_TO_PORT(x)] + (x))
-/* attention : access the PCXHR_DSP_* registers with inb and outb only ! */
-
-/* params used with PCXHR_PLX_MBOX0 */
-#define PCXHR_MBOX0_HF5 (1 << 0)
-#define PCXHR_MBOX0_HF4 (1 << 1)
-#define PCXHR_MBOX0_BOOT_HERE (1 << 23)
-/* params used with PCXHR_PLX_IRQCS */
-#define PCXHR_IRQCS_ENABLE_PCIIRQ (1 << 8)
-#define PCXHR_IRQCS_ENABLE_PCIDB (1 << 9)
-#define PCXHR_IRQCS_ACTIVE_PCIDB (1 << 13)
-/* params used with PCXHR_PLX_CHIPSC */
-#define PCXHR_CHIPSC_INIT_VALUE 0x100D767E
-#define PCXHR_CHIPSC_RESET_XILINX (1 << 16)
-#define PCXHR_CHIPSC_GPI_USERI (1 << 17)
-#define PCXHR_CHIPSC_DATA_CLK (1 << 24)
-#define PCXHR_CHIPSC_DATA_IN (1 << 26)
-
-/* params used with PCXHR_DSP_ICR */
-#define PCXHR_ICR_HI08_RREQ 0x01
-#define PCXHR_ICR_HI08_TREQ 0x02
-#define PCXHR_ICR_HI08_HDRQ 0x04
-#define PCXHR_ICR_HI08_HF0 0x08
-#define PCXHR_ICR_HI08_HF1 0x10
-#define PCXHR_ICR_HI08_HLEND 0x20
-#define PCXHR_ICR_HI08_INIT 0x80
-/* params used with PCXHR_DSP_CVR */
-#define PCXHR_CVR_HI08_HC 0x80
-/* params used with PCXHR_DSP_ISR */
-#define PCXHR_ISR_HI08_RXDF 0x01
-#define PCXHR_ISR_HI08_TXDE 0x02
-#define PCXHR_ISR_HI08_TRDY 0x04
-#define PCXHR_ISR_HI08_ERR 0x08
-#define PCXHR_ISR_HI08_CHK 0x10
-#define PCXHR_ISR_HI08_HREQ 0x80
-
-
-/* constants used for delay in msec */
-#define PCXHR_WAIT_DEFAULT 2
-#define PCXHR_WAIT_IT 25
-#define PCXHR_WAIT_IT_EXTRA 65
-
-/*
- * pcxhr_check_reg_bit - wait for the specified bit is set/reset on a register
- * @reg: register to check
- * @mask: bit mask
- * @bit: resultant bit to be checked
- * @time: time-out of loop in msec
- *
- * returns zero if a bit matches, or a negative error code.
- */
-static int pcxhr_check_reg_bit(struct pcxhr_mgr *mgr, unsigned int reg,
- unsigned char mask, unsigned char bit, int time,
- unsigned char* read)
-{
- int i = 0;
- unsigned long end_time = jiffies + (time * HZ + 999) / 1000;
- do {
- *read = PCXHR_INPB(mgr, reg);
- if ((*read & mask) == bit) {
- if (i > 100)
- snd_printdd("ATTENTION! check_reg(%x) "
- "loopcount=%d\n",
- reg, i);
- return 0;
- }
- i++;
- } while (time_after_eq(end_time, jiffies));
- snd_printk(KERN_ERR
- "pcxhr_check_reg_bit: timeout, reg=%x, mask=0x%x, val=%x\n",
- reg, mask, *read);
- return -EIO;
-}
-
-/* constants used with pcxhr_check_reg_bit() */
-#define PCXHR_TIMEOUT_DSP 200
-
-
-#define PCXHR_MASK_EXTRA_INFO 0x0000FE
-#define PCXHR_MASK_IT_HF0 0x000100
-#define PCXHR_MASK_IT_HF1 0x000200
-#define PCXHR_MASK_IT_NO_HF0_HF1 0x000400
-#define PCXHR_MASK_IT_MANAGE_HF5 0x000800
-#define PCXHR_MASK_IT_WAIT 0x010000
-#define PCXHR_MASK_IT_WAIT_EXTRA 0x020000
-
-#define PCXHR_IT_SEND_BYTE_XILINX (0x0000003C | PCXHR_MASK_IT_HF0)
-#define PCXHR_IT_TEST_XILINX (0x0000003C | PCXHR_MASK_IT_HF1 | \
- PCXHR_MASK_IT_MANAGE_HF5)
-#define PCXHR_IT_DOWNLOAD_BOOT (0x0000000C | PCXHR_MASK_IT_HF1 | \
- PCXHR_MASK_IT_MANAGE_HF5 | \
- PCXHR_MASK_IT_WAIT)
-#define PCXHR_IT_RESET_BOARD_FUNC (0x0000000C | PCXHR_MASK_IT_HF0 | \
- PCXHR_MASK_IT_MANAGE_HF5 | \
- PCXHR_MASK_IT_WAIT_EXTRA)
-#define PCXHR_IT_DOWNLOAD_DSP (0x0000000C | \
- PCXHR_MASK_IT_MANAGE_HF5 | \
- PCXHR_MASK_IT_WAIT)
-#define PCXHR_IT_DEBUG (0x0000005A | PCXHR_MASK_IT_NO_HF0_HF1)
-#define PCXHR_IT_RESET_SEMAPHORE (0x0000005C | PCXHR_MASK_IT_NO_HF0_HF1)
-#define PCXHR_IT_MESSAGE (0x00000074 | PCXHR_MASK_IT_NO_HF0_HF1)
-#define PCXHR_IT_RESET_CHK (0x00000076 | PCXHR_MASK_IT_NO_HF0_HF1)
-#define PCXHR_IT_UPDATE_RBUFFER (0x00000078 | PCXHR_MASK_IT_NO_HF0_HF1)
-
-static int pcxhr_send_it_dsp(struct pcxhr_mgr *mgr,
- unsigned int itdsp, int atomic)
-{
- int err;
- unsigned char reg;
-
- if (itdsp & PCXHR_MASK_IT_MANAGE_HF5) {
- /* clear hf5 bit */
- PCXHR_OUTPL(mgr, PCXHR_PLX_MBOX0,
- PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) &
- ~PCXHR_MBOX0_HF5);
- }
- if ((itdsp & PCXHR_MASK_IT_NO_HF0_HF1) == 0) {
- reg = (PCXHR_ICR_HI08_RREQ |
- PCXHR_ICR_HI08_TREQ |
- PCXHR_ICR_HI08_HDRQ);
- if (itdsp & PCXHR_MASK_IT_HF0)
- reg |= PCXHR_ICR_HI08_HF0;
- if (itdsp & PCXHR_MASK_IT_HF1)
- reg |= PCXHR_ICR_HI08_HF1;
- PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg);
- }
- reg = (unsigned char)(((itdsp & PCXHR_MASK_EXTRA_INFO) >> 1) |
- PCXHR_CVR_HI08_HC);
- PCXHR_OUTPB(mgr, PCXHR_DSP_CVR, reg);
- if (itdsp & PCXHR_MASK_IT_WAIT) {
- if (atomic)
- mdelay(PCXHR_WAIT_IT);
- else
- msleep(PCXHR_WAIT_IT);
- }
- if (itdsp & PCXHR_MASK_IT_WAIT_EXTRA) {
- if (atomic)
- mdelay(PCXHR_WAIT_IT_EXTRA);
- else
- msleep(PCXHR_WAIT_IT);
- }
- /* wait for CVR_HI08_HC == 0 */
- err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_CVR, PCXHR_CVR_HI08_HC, 0,
- PCXHR_TIMEOUT_DSP, &reg);
- if (err) {
- snd_printk(KERN_ERR "pcxhr_send_it_dsp : TIMEOUT CVR\n");
- return err;
- }
- if (itdsp & PCXHR_MASK_IT_MANAGE_HF5) {
- /* wait for hf5 bit */
- err = pcxhr_check_reg_bit(mgr, PCXHR_PLX_MBOX0,
- PCXHR_MBOX0_HF5,
- PCXHR_MBOX0_HF5,
- PCXHR_TIMEOUT_DSP,
- &reg);
- if (err) {
- snd_printk(KERN_ERR
- "pcxhr_send_it_dsp : TIMEOUT HF5\n");
- return err;
- }
- }
- return 0; /* retry not handled here */
-}
-
-void pcxhr_reset_xilinx_com(struct pcxhr_mgr *mgr)
-{
- /* reset second xilinx */
- PCXHR_OUTPL(mgr, PCXHR_PLX_CHIPSC,
- PCXHR_CHIPSC_INIT_VALUE & ~PCXHR_CHIPSC_RESET_XILINX);
-}
-
-static void pcxhr_enable_irq(struct pcxhr_mgr *mgr, int enable)
-{
- unsigned int reg = PCXHR_INPL(mgr, PCXHR_PLX_IRQCS);
- /* enable/disable interrupts */
- if (enable)
- reg |= (PCXHR_IRQCS_ENABLE_PCIIRQ | PCXHR_IRQCS_ENABLE_PCIDB);
- else
- reg &= ~(PCXHR_IRQCS_ENABLE_PCIIRQ | PCXHR_IRQCS_ENABLE_PCIDB);
- PCXHR_OUTPL(mgr, PCXHR_PLX_IRQCS, reg);
-}
-
-void pcxhr_reset_dsp(struct pcxhr_mgr *mgr)
-{
- /* disable interrupts */
- pcxhr_enable_irq(mgr, 0);
-
- /* let's reset the DSP */
- PCXHR_OUTPB(mgr, PCXHR_DSP_RESET, 0);
- msleep( PCXHR_WAIT_DEFAULT ); /* wait 2 msec */
- PCXHR_OUTPB(mgr, PCXHR_DSP_RESET, 3);
- msleep( PCXHR_WAIT_DEFAULT ); /* wait 2 msec */
-
- /* reset mailbox */
- PCXHR_OUTPL(mgr, PCXHR_PLX_MBOX0, 0);
-}
-
-void pcxhr_enable_dsp(struct pcxhr_mgr *mgr)
-{
- /* enable interrupts */
- pcxhr_enable_irq(mgr, 1);
-}
-
-/*
- * load the xilinx image
- */
-int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr,
- const struct firmware *xilinx, int second)
-{
- unsigned int i;
- unsigned int chipsc;
- unsigned char data;
- unsigned char mask;
- const unsigned char *image;
-
- /* test first xilinx */
- chipsc = PCXHR_INPL(mgr, PCXHR_PLX_CHIPSC);
- /* REV01 cards do not support the PCXHR_CHIPSC_GPI_USERI bit anymore */
- /* this bit will always be 1;
- * no possibility to test presence of first xilinx
- */
- if(second) {
- if ((chipsc & PCXHR_CHIPSC_GPI_USERI) == 0) {
- snd_printk(KERN_ERR "error loading first xilinx\n");
- return -EINVAL;
- }
- /* activate second xilinx */
- chipsc |= PCXHR_CHIPSC_RESET_XILINX;
- PCXHR_OUTPL(mgr, PCXHR_PLX_CHIPSC, chipsc);
- msleep( PCXHR_WAIT_DEFAULT ); /* wait 2 msec */
- }
- image = xilinx->data;
- for (i = 0; i < xilinx->size; i++, image++) {
- data = *image;
- mask = 0x80;
- while (mask) {
- chipsc &= ~(PCXHR_CHIPSC_DATA_CLK |
- PCXHR_CHIPSC_DATA_IN);
- if (data & mask)
- chipsc |= PCXHR_CHIPSC_DATA_IN;
- PCXHR_OUTPL(mgr, PCXHR_PLX_CHIPSC, chipsc);
- chipsc |= PCXHR_CHIPSC_DATA_CLK;
- PCXHR_OUTPL(mgr, PCXHR_PLX_CHIPSC, chipsc);
- mask >>= 1;
- }
- /* don't take too much time in this loop... */
- cond_resched();
- }
- chipsc &= ~(PCXHR_CHIPSC_DATA_CLK | PCXHR_CHIPSC_DATA_IN);
- PCXHR_OUTPL(mgr, PCXHR_PLX_CHIPSC, chipsc);
- /* wait 2 msec (time to boot the xilinx before any access) */
- msleep( PCXHR_WAIT_DEFAULT );
- return 0;
-}
-
-/*
- * send an executable file to the DSP
- */
-static int pcxhr_download_dsp(struct pcxhr_mgr *mgr, const struct firmware *dsp)
-{
- int err;
- unsigned int i;
- unsigned int len;
- const unsigned char *data;
- unsigned char dummy;
- /* check the length of boot image */
- if (dsp->size <= 0)
- return -EINVAL;
- if (dsp->size % 3)
- return -EINVAL;
- if (snd_BUG_ON(!dsp->data))
- return -EINVAL;
- /* transfert data buffer from PC to DSP */
- for (i = 0; i < dsp->size; i += 3) {
- data = dsp->data + i;
- if (i == 0) {
- /* test data header consistency */
- len = (unsigned int)((data[0]<<16) +
- (data[1]<<8) +
- data[2]);
- if (len && (dsp->size != (len + 2) * 3))
- return -EINVAL;
- }
- /* wait DSP ready for new transfer */
- err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
- PCXHR_ISR_HI08_TRDY,
- PCXHR_ISR_HI08_TRDY,
- PCXHR_TIMEOUT_DSP, &dummy);
- if (err) {
- snd_printk(KERN_ERR
- "dsp loading error at position %d\n", i);
- return err;
- }
- /* send host data */
- PCXHR_OUTPB(mgr, PCXHR_DSP_TXH, data[0]);
- PCXHR_OUTPB(mgr, PCXHR_DSP_TXM, data[1]);
- PCXHR_OUTPB(mgr, PCXHR_DSP_TXL, data[2]);
-
- /* don't take too much time in this loop... */
- cond_resched();
- }
- /* give some time to boot the DSP */
- msleep(PCXHR_WAIT_DEFAULT);
- return 0;
-}
-
-/*
- * load the eeprom image
- */
-int pcxhr_load_eeprom_binary(struct pcxhr_mgr *mgr,
- const struct firmware *eeprom)
-{
- int err;
- unsigned char reg;
-
- /* init value of the ICR register */
- reg = PCXHR_ICR_HI08_RREQ | PCXHR_ICR_HI08_TREQ | PCXHR_ICR_HI08_HDRQ;
- if (PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) & PCXHR_MBOX0_BOOT_HERE) {
- /* no need to load the eeprom binary,
- * but init the HI08 interface
- */
- PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg | PCXHR_ICR_HI08_INIT);
- msleep(PCXHR_WAIT_DEFAULT);
- PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg);
- msleep(PCXHR_WAIT_DEFAULT);
- snd_printdd("no need to load eeprom boot\n");
- return 0;
- }
- PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg);
-
- err = pcxhr_download_dsp(mgr, eeprom);
- if (err)
- return err;
- /* wait for chk bit */
- return pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_CHK,
- PCXHR_ISR_HI08_CHK, PCXHR_TIMEOUT_DSP, &reg);
-}
-
-/*
- * load the boot image
- */
-int pcxhr_load_boot_binary(struct pcxhr_mgr *mgr, const struct firmware *boot)
-{
- int err;
- unsigned int physaddr = mgr->hostport.addr;
- unsigned char dummy;
-
- /* send the hostport address to the DSP (only the upper 24 bit !) */
- if (snd_BUG_ON(physaddr & 0xff))
- return -EINVAL;
- PCXHR_OUTPL(mgr, PCXHR_PLX_MBOX1, (physaddr >> 8));
-
- err = pcxhr_send_it_dsp(mgr, PCXHR_IT_DOWNLOAD_BOOT, 0);
- if (err)
- return err;
- /* clear hf5 bit */
- PCXHR_OUTPL(mgr, PCXHR_PLX_MBOX0,
- PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) & ~PCXHR_MBOX0_HF5);
-
- err = pcxhr_download_dsp(mgr, boot);
- if (err)
- return err;
- /* wait for hf5 bit */
- return pcxhr_check_reg_bit(mgr, PCXHR_PLX_MBOX0, PCXHR_MBOX0_HF5,
- PCXHR_MBOX0_HF5, PCXHR_TIMEOUT_DSP, &dummy);
-}
-
-/*
- * load the final dsp image
- */
-int pcxhr_load_dsp_binary(struct pcxhr_mgr *mgr, const struct firmware *dsp)
-{
- int err;
- unsigned char dummy;
- err = pcxhr_send_it_dsp(mgr, PCXHR_IT_RESET_BOARD_FUNC, 0);
- if (err)
- return err;
- err = pcxhr_send_it_dsp(mgr, PCXHR_IT_DOWNLOAD_DSP, 0);
- if (err)
- return err;
- err = pcxhr_download_dsp(mgr, dsp);
- if (err)
- return err;
- /* wait for chk bit */
- return pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
- PCXHR_ISR_HI08_CHK,
- PCXHR_ISR_HI08_CHK,
- PCXHR_TIMEOUT_DSP, &dummy);
-}
-
-
-struct pcxhr_cmd_info {
- u32 opcode; /* command word */
- u16 st_length; /* status length */
- u16 st_type; /* status type (RMH_SSIZE_XXX) */
-};
-
-/* RMH status type */
-enum {
- RMH_SSIZE_FIXED = 0, /* status size fix (st_length = 0..x) */
- RMH_SSIZE_ARG = 1, /* status size given in the LSB byte */
- RMH_SSIZE_MASK = 2, /* status size given in bitmask */
-};
-
-/*
- * Array of DSP commands
- */
-static struct pcxhr_cmd_info pcxhr_dsp_cmds[] = {
-[CMD_VERSION] = { 0x010000, 1, RMH_SSIZE_FIXED },
-[CMD_SUPPORTED] = { 0x020000, 4, RMH_SSIZE_FIXED },
-[CMD_TEST_IT] = { 0x040000, 1, RMH_SSIZE_FIXED },
-[CMD_SEND_IRQA] = { 0x070001, 0, RMH_SSIZE_FIXED },
-[CMD_ACCESS_IO_WRITE] = { 0x090000, 1, RMH_SSIZE_ARG },
-[CMD_ACCESS_IO_READ] = { 0x094000, 1, RMH_SSIZE_ARG },
-[CMD_ASYNC] = { 0x0a0000, 1, RMH_SSIZE_ARG },
-[CMD_MODIFY_CLOCK] = { 0x0d0000, 0, RMH_SSIZE_FIXED },
-[CMD_RESYNC_AUDIO_INPUTS] = { 0x0e0000, 0, RMH_SSIZE_FIXED },
-[CMD_GET_DSP_RESOURCES] = { 0x100000, 4, RMH_SSIZE_FIXED },
-[CMD_SET_TIMER_INTERRUPT] = { 0x110000, 0, RMH_SSIZE_FIXED },
-[CMD_RES_PIPE] = { 0x400000, 0, RMH_SSIZE_FIXED },
-[CMD_FREE_PIPE] = { 0x410000, 0, RMH_SSIZE_FIXED },
-[CMD_CONF_PIPE] = { 0x422101, 0, RMH_SSIZE_FIXED },
-[CMD_STOP_PIPE] = { 0x470004, 0, RMH_SSIZE_FIXED },
-[CMD_PIPE_SAMPLE_COUNT] = { 0x49a000, 2, RMH_SSIZE_FIXED },
-[CMD_CAN_START_PIPE] = { 0x4b0000, 1, RMH_SSIZE_FIXED },
-[CMD_START_STREAM] = { 0x802000, 0, RMH_SSIZE_FIXED },
-[CMD_STREAM_OUT_LEVEL_ADJUST] = { 0x822000, 0, RMH_SSIZE_FIXED },
-[CMD_STOP_STREAM] = { 0x832000, 0, RMH_SSIZE_FIXED },
-[CMD_UPDATE_R_BUFFERS] = { 0x840000, 0, RMH_SSIZE_FIXED },
-[CMD_FORMAT_STREAM_OUT] = { 0x860000, 0, RMH_SSIZE_FIXED },
-[CMD_FORMAT_STREAM_IN] = { 0x870000, 0, RMH_SSIZE_FIXED },
-[CMD_STREAM_SAMPLE_COUNT] = { 0x902000, 2, RMH_SSIZE_FIXED },
-[CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED },
-};
-
-#ifdef CONFIG_SND_DEBUG_VERBOSE
-static char* cmd_names[] = {
-[CMD_VERSION] = "CMD_VERSION",
-[CMD_SUPPORTED] = "CMD_SUPPORTED",
-[CMD_TEST_IT] = "CMD_TEST_IT",
-[CMD_SEND_IRQA] = "CMD_SEND_IRQA",
-[CMD_ACCESS_IO_WRITE] = "CMD_ACCESS_IO_WRITE",
-[CMD_ACCESS_IO_READ] = "CMD_ACCESS_IO_READ",
-[CMD_ASYNC] = "CMD_ASYNC",
-[CMD_MODIFY_CLOCK] = "CMD_MODIFY_CLOCK",
-[CMD_RESYNC_AUDIO_INPUTS] = "CMD_RESYNC_AUDIO_INPUTS",
-[CMD_GET_DSP_RESOURCES] = "CMD_GET_DSP_RESOURCES",
-[CMD_SET_TIMER_INTERRUPT] = "CMD_SET_TIMER_INTERRUPT",
-[CMD_RES_PIPE] = "CMD_RES_PIPE",
-[CMD_FREE_PIPE] = "CMD_FREE_PIPE",
-[CMD_CONF_PIPE] = "CMD_CONF_PIPE",
-[CMD_STOP_PIPE] = "CMD_STOP_PIPE",
-[CMD_PIPE_SAMPLE_COUNT] = "CMD_PIPE_SAMPLE_COUNT",
-[CMD_CAN_START_PIPE] = "CMD_CAN_START_PIPE",
-[CMD_START_STREAM] = "CMD_START_STREAM",
-[CMD_STREAM_OUT_LEVEL_ADJUST] = "CMD_STREAM_OUT_LEVEL_ADJUST",
-[CMD_STOP_STREAM] = "CMD_STOP_STREAM",
-[CMD_UPDATE_R_BUFFERS] = "CMD_UPDATE_R_BUFFERS",
-[CMD_FORMAT_STREAM_OUT] = "CMD_FORMAT_STREAM_OUT",
-[CMD_FORMAT_STREAM_IN] = "CMD_FORMAT_STREAM_IN",
-[CMD_STREAM_SAMPLE_COUNT] = "CMD_STREAM_SAMPLE_COUNT",
-[CMD_AUDIO_LEVEL_ADJUST] = "CMD_AUDIO_LEVEL_ADJUST",
-};
-#endif
-
-
-static int pcxhr_read_rmh_status(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
-{
- int err;
- int i;
- u32 data;
- u32 size_mask;
- unsigned char reg;
- int max_stat_len;
-
- if (rmh->stat_len < PCXHR_SIZE_MAX_STATUS)
- max_stat_len = PCXHR_SIZE_MAX_STATUS;
- else max_stat_len = rmh->stat_len;
-
- for (i = 0; i < rmh->stat_len; i++) {
- /* wait for receiver full */
- err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
- PCXHR_ISR_HI08_RXDF,
- PCXHR_ISR_HI08_RXDF,
- PCXHR_TIMEOUT_DSP, &reg);
- if (err) {
- snd_printk(KERN_ERR "ERROR RMH stat: "
- "ISR:RXDF=1 (ISR = %x; i=%d )\n",
- reg, i);
- return err;
- }
- /* read data */
- data = PCXHR_INPB(mgr, PCXHR_DSP_TXH) << 16;
- data |= PCXHR_INPB(mgr, PCXHR_DSP_TXM) << 8;
- data |= PCXHR_INPB(mgr, PCXHR_DSP_TXL);
-
- /* need to update rmh->stat_len on the fly ?? */
- if (!i) {
- if (rmh->dsp_stat != RMH_SSIZE_FIXED) {
- if (rmh->dsp_stat == RMH_SSIZE_ARG) {
- rmh->stat_len = (data & 0x0000ff) + 1;
- data &= 0xffff00;
- } else {
- /* rmh->dsp_stat == RMH_SSIZE_MASK */
- rmh->stat_len = 1;
- size_mask = data;
- while (size_mask) {
- if (size_mask & 1)
- rmh->stat_len++;
- size_mask >>= 1;
- }
- }
- }
- }
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- if (rmh->cmd_idx < CMD_LAST_INDEX)
- snd_printdd(" stat[%d]=%x\n", i, data);
-#endif
- if (i < max_stat_len)
- rmh->stat[i] = data;
- }
- if (rmh->stat_len > max_stat_len) {
- snd_printdd("PCXHR : rmh->stat_len=%x too big\n",
- rmh->stat_len);
- rmh->stat_len = max_stat_len;
- }
- return 0;
-}
-
-static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
-{
- int err;
- int i;
- u32 data;
- unsigned char reg;
-
- if (snd_BUG_ON(rmh->cmd_len >= PCXHR_SIZE_MAX_CMD))
- return -EINVAL;
- err = pcxhr_send_it_dsp(mgr, PCXHR_IT_MESSAGE, 1);
- if (err) {
- snd_printk(KERN_ERR "pcxhr_send_message : ED_DSP_CRASHED\n");
- return err;
- }
- /* wait for chk bit */
- err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_CHK,
- PCXHR_ISR_HI08_CHK, PCXHR_TIMEOUT_DSP, &reg);
- if (err)
- return err;
- /* reset irq chk */
- err = pcxhr_send_it_dsp(mgr, PCXHR_IT_RESET_CHK, 1);
- if (err)
- return err;
- /* wait for chk bit == 0*/
- err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_CHK, 0,
- PCXHR_TIMEOUT_DSP, &reg);
- if (err)
- return err;
-
- data = rmh->cmd[0];
-
- if (rmh->cmd_len > 1)
- data |= 0x008000; /* MASK_MORE_THAN_1_WORD_COMMAND */
- else
- data &= 0xff7fff; /* MASK_1_WORD_COMMAND */
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- if (rmh->cmd_idx < CMD_LAST_INDEX)
- snd_printdd("MSG cmd[0]=%x (%s)\n",
- data, cmd_names[rmh->cmd_idx]);
-#endif
-
- err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY,
- PCXHR_ISR_HI08_TRDY, PCXHR_TIMEOUT_DSP, &reg);
- if (err)
- return err;
- PCXHR_OUTPB(mgr, PCXHR_DSP_TXH, (data>>16)&0xFF);
- PCXHR_OUTPB(mgr, PCXHR_DSP_TXM, (data>>8)&0xFF);
- PCXHR_OUTPB(mgr, PCXHR_DSP_TXL, (data&0xFF));
-
- if (rmh->cmd_len > 1) {
- /* send length */
- data = rmh->cmd_len - 1;
- err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
- PCXHR_ISR_HI08_TRDY,
- PCXHR_ISR_HI08_TRDY,
- PCXHR_TIMEOUT_DSP, &reg);
- if (err)
- return err;
- PCXHR_OUTPB(mgr, PCXHR_DSP_TXH, (data>>16)&0xFF);
- PCXHR_OUTPB(mgr, PCXHR_DSP_TXM, (data>>8)&0xFF);
- PCXHR_OUTPB(mgr, PCXHR_DSP_TXL, (data&0xFF));
-
- for (i=1; i < rmh->cmd_len; i++) {
- /* send other words */
- data = rmh->cmd[i];
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- if (rmh->cmd_idx < CMD_LAST_INDEX)
- snd_printdd(" cmd[%d]=%x\n", i, data);
-#endif
- err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
- PCXHR_ISR_HI08_TRDY,
- PCXHR_ISR_HI08_TRDY,
- PCXHR_TIMEOUT_DSP, &reg);
- if (err)
- return err;
- PCXHR_OUTPB(mgr, PCXHR_DSP_TXH, (data>>16)&0xFF);
- PCXHR_OUTPB(mgr, PCXHR_DSP_TXM, (data>>8)&0xFF);
- PCXHR_OUTPB(mgr, PCXHR_DSP_TXL, (data&0xFF));
- }
- }
- /* wait for chk bit */
- err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_CHK,
- PCXHR_ISR_HI08_CHK, PCXHR_TIMEOUT_DSP, &reg);
- if (err)
- return err;
- /* test status ISR */
- if (reg & PCXHR_ISR_HI08_ERR) {
- /* ERROR, wait for receiver full */
- err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
- PCXHR_ISR_HI08_RXDF,
- PCXHR_ISR_HI08_RXDF,
- PCXHR_TIMEOUT_DSP, &reg);
- if (err) {
- snd_printk(KERN_ERR "ERROR RMH: ISR:RXDF=1 (ISR = %x)\n", reg);
- return err;
- }
- /* read error code */
- data = PCXHR_INPB(mgr, PCXHR_DSP_TXH) << 16;
- data |= PCXHR_INPB(mgr, PCXHR_DSP_TXM) << 8;
- data |= PCXHR_INPB(mgr, PCXHR_DSP_TXL);
- snd_printk(KERN_ERR "ERROR RMH(%d): 0x%x\n",
- rmh->cmd_idx, data);
- err = -EINVAL;
- } else {
- /* read the response data */
- err = pcxhr_read_rmh_status(mgr, rmh);
- }
- /* reset semaphore */
- if (pcxhr_send_it_dsp(mgr, PCXHR_IT_RESET_SEMAPHORE, 1) < 0)
- return -EIO;
- return err;
-}
-
-
-/**
- * pcxhr_init_rmh - initialize the RMH instance
- * @rmh: the rmh pointer to be initialized
- * @cmd: the rmh command to be set
- */
-void pcxhr_init_rmh(struct pcxhr_rmh *rmh, int cmd)
-{
- if (snd_BUG_ON(cmd >= CMD_LAST_INDEX))
- return;
- rmh->cmd[0] = pcxhr_dsp_cmds[cmd].opcode;
- rmh->cmd_len = 1;
- rmh->stat_len = pcxhr_dsp_cmds[cmd].st_length;
- rmh->dsp_stat = pcxhr_dsp_cmds[cmd].st_type;
- rmh->cmd_idx = cmd;
-}
-
-
-void pcxhr_set_pipe_cmd_params(struct pcxhr_rmh *rmh, int capture,
- unsigned int param1, unsigned int param2,
- unsigned int param3)
-{
- snd_BUG_ON(param1 > MASK_FIRST_FIELD);
- if (capture)
- rmh->cmd[0] |= 0x800; /* COMMAND_RECORD_MASK */
- if (param1)
- rmh->cmd[0] |= (param1 << FIELD_SIZE);
- if (param2) {
- snd_BUG_ON(param2 > MASK_FIRST_FIELD);
- rmh->cmd[0] |= param2;
- }
- if(param3) {
- snd_BUG_ON(param3 > MASK_DSP_WORD);
- rmh->cmd[1] = param3;
- rmh->cmd_len = 2;
- }
-}
-
-/*
- * pcxhr_send_msg - send a DSP message with spinlock
- * @rmh: the rmh record to send and receive
- *
- * returns 0 if successful, or a negative error code.
- */
-int pcxhr_send_msg(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
-{
- unsigned long flags;
- int err;
- spin_lock_irqsave(&mgr->msg_lock, flags);
- err = pcxhr_send_msg_nolock(mgr, rmh);
- spin_unlock_irqrestore(&mgr->msg_lock, flags);
- return err;
-}
-
-static inline int pcxhr_pipes_running(struct pcxhr_mgr *mgr)
-{
- int start_mask = PCXHR_INPL(mgr, PCXHR_PLX_MBOX2);
- /* least segnificant 12 bits are the pipe states
- * for the playback audios
- * next 12 bits are the pipe states for the capture audios
- * (PCXHR_PIPE_STATE_CAPTURE_OFFSET)
- */
- start_mask &= 0xffffff;
- snd_printdd("CMD_PIPE_STATE MBOX2=0x%06x\n", start_mask);
- return start_mask;
-}
-
-#define PCXHR_PIPE_STATE_CAPTURE_OFFSET 12
-#define MAX_WAIT_FOR_DSP 20
-
-static int pcxhr_prepair_pipe_start(struct pcxhr_mgr *mgr,
- int audio_mask, int *retry)
-{
- struct pcxhr_rmh rmh;
- int err;
- int audio = 0;
-
- *retry = 0;
- while (audio_mask) {
- if (audio_mask & 1) {
- pcxhr_init_rmh(&rmh, CMD_CAN_START_PIPE);
- if (audio < PCXHR_PIPE_STATE_CAPTURE_OFFSET) {
- /* can start playback pipe */
- pcxhr_set_pipe_cmd_params(&rmh, 0, audio, 0, 0);
- } else {
- /* can start capture pipe */
- pcxhr_set_pipe_cmd_params(&rmh, 1, audio -
- PCXHR_PIPE_STATE_CAPTURE_OFFSET,
- 0, 0);
- }
- err = pcxhr_send_msg(mgr, &rmh);
- if (err) {
- snd_printk(KERN_ERR
- "error pipe start "
- "(CMD_CAN_START_PIPE) err=%x!\n",
- err);
- return err;
- }
- /* if the pipe couldn't be prepaired for start,
- * retry it later
- */
- if (rmh.stat[0] == 0)
- *retry |= (1<<audio);
- }
- audio_mask>>=1;
- audio++;
- }
- return 0;
-}
-
-static int pcxhr_stop_pipes(struct pcxhr_mgr *mgr, int audio_mask)
-{
- struct pcxhr_rmh rmh;
- int err;
- int audio = 0;
-
- while (audio_mask) {
- if (audio_mask & 1) {
- pcxhr_init_rmh(&rmh, CMD_STOP_PIPE);
- if (audio < PCXHR_PIPE_STATE_CAPTURE_OFFSET) {
- /* stop playback pipe */
- pcxhr_set_pipe_cmd_params(&rmh, 0, audio, 0, 0);
- } else {
- /* stop capture pipe */
- pcxhr_set_pipe_cmd_params(&rmh, 1, audio -
- PCXHR_PIPE_STATE_CAPTURE_OFFSET,
- 0, 0);
- }
- err = pcxhr_send_msg(mgr, &rmh);
- if (err) {
- snd_printk(KERN_ERR
- "error pipe stop "
- "(CMD_STOP_PIPE) err=%x!\n", err);
- return err;
- }
- }
- audio_mask>>=1;
- audio++;
- }
- return 0;
-}
-
-static int pcxhr_toggle_pipes(struct pcxhr_mgr *mgr, int audio_mask)
-{
- struct pcxhr_rmh rmh;
- int err;
- int audio = 0;
-
- while (audio_mask) {
- if (audio_mask & 1) {
- pcxhr_init_rmh(&rmh, CMD_CONF_PIPE);
- if (audio < PCXHR_PIPE_STATE_CAPTURE_OFFSET)
- pcxhr_set_pipe_cmd_params(&rmh, 0, 0, 0,
- 1 << audio);
- else
- pcxhr_set_pipe_cmd_params(&rmh, 1, 0, 0,
- 1 << (audio - PCXHR_PIPE_STATE_CAPTURE_OFFSET));
- err = pcxhr_send_msg(mgr, &rmh);
- if (err) {
- snd_printk(KERN_ERR
- "error pipe start "
- "(CMD_CONF_PIPE) err=%x!\n", err);
- return err;
- }
- }
- audio_mask>>=1;
- audio++;
- }
- /* now fire the interrupt on the card */
- pcxhr_init_rmh(&rmh, CMD_SEND_IRQA);
- err = pcxhr_send_msg(mgr, &rmh);
- if (err) {
- snd_printk(KERN_ERR
- "error pipe start (CMD_SEND_IRQA) err=%x!\n",
- err);
- return err;
- }
- return 0;
-}
-
-
-
-int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask,
- int capture_mask, int start)
-{
- int state, i, err;
- int audio_mask;
-
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- struct timeval my_tv1, my_tv2;
- do_gettimeofday(&my_tv1);
-#endif
- audio_mask = (playback_mask |
- (capture_mask << PCXHR_PIPE_STATE_CAPTURE_OFFSET));
- /* current pipe state (playback + record) */
- state = pcxhr_pipes_running(mgr);
- snd_printdd("pcxhr_set_pipe_state %s (mask %x current %x)\n",
- start ? "START" : "STOP", audio_mask, state);
- if (start) {
- /* start only pipes that are not yet started */
- audio_mask &= ~state;
- state = audio_mask;
- for (i = 0; i < MAX_WAIT_FOR_DSP; i++) {
- err = pcxhr_prepair_pipe_start(mgr, state, &state);
- if (err)
- return err;
- if (state == 0)
- break; /* success, all pipes prepaired */
- mdelay(1); /* wait 1 millisecond and retry */
- }
- } else {
- audio_mask &= state; /* stop only pipes that are started */
- }
- if (audio_mask == 0)
- return 0;
-
- err = pcxhr_toggle_pipes(mgr, audio_mask);
- if (err)
- return err;
-
- i = 0;
- while (1) {
- state = pcxhr_pipes_running(mgr);
- /* have all pipes the new state ? */
- if ((state & audio_mask) == (start ? audio_mask : 0))
- break;
- if (++i >= MAX_WAIT_FOR_DSP * 100) {
- snd_printk(KERN_ERR "error pipe start/stop\n");
- return -EBUSY;
- }
- udelay(10); /* wait 10 microseconds */
- }
- if (!start) {
- err = pcxhr_stop_pipes(mgr, audio_mask);
- if (err)
- return err;
- }
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- do_gettimeofday(&my_tv2);
- snd_printdd("***SET PIPE STATE*** TIME = %ld (err = %x)\n",
- (long)(my_tv2.tv_usec - my_tv1.tv_usec), err);
-#endif
- return 0;
-}
-
-int pcxhr_write_io_num_reg_cont(struct pcxhr_mgr *mgr, unsigned int mask,
- unsigned int value, int *changed)
-{
- struct pcxhr_rmh rmh;
- unsigned long flags;
- int err;
-
- spin_lock_irqsave(&mgr->msg_lock, flags);
- if ((mgr->io_num_reg_cont & mask) == value) {
- snd_printdd("IO_NUM_REG_CONT mask %x already is set to %x\n",
- mask, value);
- if (changed)
- *changed = 0;
- spin_unlock_irqrestore(&mgr->msg_lock, flags);
- return 0; /* already programmed */
- }
- pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
- rmh.cmd[0] |= IO_NUM_REG_CONT;
- rmh.cmd[1] = mask;
- rmh.cmd[2] = value;
- rmh.cmd_len = 3;
- err = pcxhr_send_msg_nolock(mgr, &rmh);
- if (err == 0) {
- mgr->io_num_reg_cont &= ~mask;
- mgr->io_num_reg_cont |= value;
- if (changed)
- *changed = 1;
- }
- spin_unlock_irqrestore(&mgr->msg_lock, flags);
- return err;
-}
-
-#define PCXHR_IRQ_TIMER 0x000300
-#define PCXHR_IRQ_FREQ_CHANGE 0x000800
-#define PCXHR_IRQ_TIME_CODE 0x001000
-#define PCXHR_IRQ_NOTIFY 0x002000
-#define PCXHR_IRQ_ASYNC 0x008000
-#define PCXHR_IRQ_MASK 0x00bb00
-#define PCXHR_FATAL_DSP_ERR 0xff0000
-
-enum pcxhr_async_err_src {
- PCXHR_ERR_PIPE,
- PCXHR_ERR_STREAM,
- PCXHR_ERR_AUDIO
-};
-
-static int pcxhr_handle_async_err(struct pcxhr_mgr *mgr, u32 err,
- enum pcxhr_async_err_src err_src, int pipe,
- int is_capture)
-{
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- static char* err_src_name[] = {
- [PCXHR_ERR_PIPE] = "Pipe",
- [PCXHR_ERR_STREAM] = "Stream",
- [PCXHR_ERR_AUDIO] = "Audio"
- };
-#endif
- if (err & 0xfff)
- err &= 0xfff;
- else
- err = ((err >> 12) & 0xfff);
- if (!err)
- return 0;
- snd_printdd("CMD_ASYNC : Error %s %s Pipe %d err=%x\n",
- err_src_name[err_src],
- is_capture ? "Record" : "Play", pipe, err);
- if (err == 0xe01)
- mgr->async_err_stream_xrun++;
- else if (err == 0xe10)
- mgr->async_err_pipe_xrun++;
- else
- mgr->async_err_other_last = (int)err;
- return 1;
-}
-
-
-void pcxhr_msg_tasklet(unsigned long arg)
-{
- struct pcxhr_mgr *mgr = (struct pcxhr_mgr *)(arg);
- struct pcxhr_rmh *prmh = mgr->prmh;
- int err;
- int i, j;
-
- if (mgr->src_it_dsp & PCXHR_IRQ_FREQ_CHANGE)
- snd_printdd("TASKLET : PCXHR_IRQ_FREQ_CHANGE event occurred\n");
- if (mgr->src_it_dsp & PCXHR_IRQ_TIME_CODE)
- snd_printdd("TASKLET : PCXHR_IRQ_TIME_CODE event occurred\n");
- if (mgr->src_it_dsp & PCXHR_IRQ_NOTIFY)
- snd_printdd("TASKLET : PCXHR_IRQ_NOTIFY event occurred\n");
- if (mgr->src_it_dsp & (PCXHR_IRQ_FREQ_CHANGE | PCXHR_IRQ_TIME_CODE)) {
- /* clear events FREQ_CHANGE and TIME_CODE */
- pcxhr_init_rmh(prmh, CMD_TEST_IT);
- err = pcxhr_send_msg(mgr, prmh);
- snd_printdd("CMD_TEST_IT : err=%x, stat=%x\n",
- err, prmh->stat[0]);
- }
- if (mgr->src_it_dsp & PCXHR_IRQ_ASYNC) {
- snd_printdd("TASKLET : PCXHR_IRQ_ASYNC event occurred\n");
-
- pcxhr_init_rmh(prmh, CMD_ASYNC);
- prmh->cmd[0] |= 1; /* add SEL_ASYNC_EVENTS */
- /* this is the only one extra long response command */
- prmh->stat_len = PCXHR_SIZE_MAX_LONG_STATUS;
- err = pcxhr_send_msg(mgr, prmh);
- if (err)
- snd_printk(KERN_ERR "ERROR pcxhr_msg_tasklet=%x;\n",
- err);
- i = 1;
- while (i < prmh->stat_len) {
- int nb_audio = ((prmh->stat[i] >> FIELD_SIZE) &
- MASK_FIRST_FIELD);
- int nb_stream = ((prmh->stat[i] >> (2*FIELD_SIZE)) &
- MASK_FIRST_FIELD);
- int pipe = prmh->stat[i] & MASK_FIRST_FIELD;
- int is_capture = prmh->stat[i] & 0x400000;
- u32 err2;
-
- if (prmh->stat[i] & 0x800000) { /* if BIT_END */
- snd_printdd("TASKLET : End%sPipe %d\n",
- is_capture ? "Record" : "Play",
- pipe);
- }
- i++;
- err2 = prmh->stat[i] ? prmh->stat[i] : prmh->stat[i+1];
- if (err2)
- pcxhr_handle_async_err(mgr, err2,
- PCXHR_ERR_PIPE,
- pipe, is_capture);
- i += 2;
- for (j = 0; j < nb_stream; j++) {
- err2 = prmh->stat[i] ?
- prmh->stat[i] : prmh->stat[i+1];
- if (err2)
- pcxhr_handle_async_err(mgr, err2,
- PCXHR_ERR_STREAM,
- pipe,
- is_capture);
- i += 2;
- }
- for (j = 0; j < nb_audio; j++) {
- err2 = prmh->stat[i] ?
- prmh->stat[i] : prmh->stat[i+1];
- if (err2)
- pcxhr_handle_async_err(mgr, err2,
- PCXHR_ERR_AUDIO,
- pipe,
- is_capture);
- i += 2;
- }
- }
- }
-}
-
-static u_int64_t pcxhr_stream_read_position(struct pcxhr_mgr *mgr,
- struct pcxhr_stream *stream)
-{
- u_int64_t hw_sample_count;
- struct pcxhr_rmh rmh;
- int err, stream_mask;
-
- stream_mask = stream->pipe->is_capture ? 1 : 1<<stream->substream->number;
-
- /* get sample count for one stream */
- pcxhr_init_rmh(&rmh, CMD_STREAM_SAMPLE_COUNT);
- pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture,
- stream->pipe->first_audio, 0, stream_mask);
- /* rmh.stat_len = 2; */ /* 2 resp data for each stream of the pipe */
-
- err = pcxhr_send_msg(mgr, &rmh);
- if (err)
- return 0;
-
- hw_sample_count = ((u_int64_t)rmh.stat[0]) << 24;
- hw_sample_count += (u_int64_t)rmh.stat[1];
-
- snd_printdd("stream %c%d : abs samples real(%ld) timer(%ld)\n",
- stream->pipe->is_capture ? 'C' : 'P',
- stream->substream->number,
- (long unsigned int)hw_sample_count,
- (long unsigned int)(stream->timer_abs_periods +
- stream->timer_period_frag +
- mgr->granularity));
- return hw_sample_count;
-}
-
-static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr,
- struct pcxhr_stream *stream,
- int samples_to_add)
-{
- if (stream->substream &&
- (stream->status == PCXHR_STREAM_STATUS_RUNNING)) {
- u_int64_t new_sample_count;
- int elapsed = 0;
- int hardware_read = 0;
- struct snd_pcm_runtime *runtime = stream->substream->runtime;
-
- if (samples_to_add < 0) {
- stream->timer_is_synced = 0;
- /* add default if no hardware_read possible */
- samples_to_add = mgr->granularity;
- }
-
- if (!stream->timer_is_synced) {
- if ((stream->timer_abs_periods != 0) ||
- ((stream->timer_period_frag + samples_to_add) >=
- runtime->period_size)) {
- new_sample_count =
- pcxhr_stream_read_position(mgr, stream);
- hardware_read = 1;
- if (new_sample_count >= mgr->granularity) {
- /* sub security offset because of
- * jitter and finer granularity of
- * dsp time (MBOX4)
- */
- new_sample_count -= mgr->granularity;
- stream->timer_is_synced = 1;
- }
- }
- }
- if (!hardware_read) {
- /* if we didn't try to sync the position, increment it
- * by PCXHR_GRANULARITY every timer interrupt
- */
- new_sample_count = stream->timer_abs_periods +
- stream->timer_period_frag + samples_to_add;
- }
- while (1) {
- u_int64_t new_elapse_pos = stream->timer_abs_periods +
- runtime->period_size;
- if (new_elapse_pos > new_sample_count)
- break;
- elapsed = 1;
- stream->timer_buf_periods++;
- if (stream->timer_buf_periods >= runtime->periods)
- stream->timer_buf_periods = 0;
- stream->timer_abs_periods = new_elapse_pos;
- }
- if (new_sample_count >= stream->timer_abs_periods) {
- stream->timer_period_frag =
- (u_int32_t)(new_sample_count -
- stream->timer_abs_periods);
- } else {
- snd_printk(KERN_ERR
- "ERROR new_sample_count too small ??? %ld\n",
- (long unsigned int)new_sample_count);
- }
-
- if (elapsed) {
- spin_unlock(&mgr->lock);
- snd_pcm_period_elapsed(stream->substream);
- spin_lock(&mgr->lock);
- }
- }
-}
-
-irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
-{
- struct pcxhr_mgr *mgr = dev_id;
- unsigned int reg;
- int i, j;
- struct snd_pcxhr *chip;
-
- spin_lock(&mgr->lock);
-
- reg = PCXHR_INPL(mgr, PCXHR_PLX_IRQCS);
- if (! (reg & PCXHR_IRQCS_ACTIVE_PCIDB)) {
- spin_unlock(&mgr->lock);
- /* this device did not cause the interrupt */
- return IRQ_NONE;
- }
-
- /* clear interrupt */
- reg = PCXHR_INPL(mgr, PCXHR_PLX_L2PCIDB);
- PCXHR_OUTPL(mgr, PCXHR_PLX_L2PCIDB, reg);
-
- /* timer irq occurred */
- if (reg & PCXHR_IRQ_TIMER) {
- int timer_toggle = reg & PCXHR_IRQ_TIMER;
- /* is a 24 bit counter */
- int dsp_time_new =
- PCXHR_INPL(mgr, PCXHR_PLX_MBOX4) & PCXHR_DSP_TIME_MASK;
- int dsp_time_diff = dsp_time_new - mgr->dsp_time_last;
-
- if ((dsp_time_diff < 0) &&
- (mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID)) {
- snd_printdd("ERROR DSP TIME old(%d) new(%d) -> "
- "resynchronize all streams\n",
- mgr->dsp_time_last, dsp_time_new);
- mgr->dsp_time_err++;
- }
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- if (dsp_time_diff == 0)
- snd_printdd("ERROR DSP TIME NO DIFF time(%d)\n",
- dsp_time_new);
- else if (dsp_time_diff >= (2*mgr->granularity))
- snd_printdd("ERROR DSP TIME TOO BIG old(%d) add(%d)\n",
- mgr->dsp_time_last,
- dsp_time_new - mgr->dsp_time_last);
- else if (dsp_time_diff % mgr->granularity)
- snd_printdd("ERROR DSP TIME increased by %d\n",
- dsp_time_diff);
-#endif
- mgr->dsp_time_last = dsp_time_new;
-
- if (timer_toggle == mgr->timer_toggle) {
- snd_printdd("ERROR TIMER TOGGLE\n");
- mgr->dsp_time_err++;
- }
- mgr->timer_toggle = timer_toggle;
-
- reg &= ~PCXHR_IRQ_TIMER;
- for (i = 0; i < mgr->num_cards; i++) {
- chip = mgr->chip[i];
- for (j = 0; j < chip->nb_streams_capt; j++)
- pcxhr_update_timer_pos(mgr,
- &chip->capture_stream[j],
- dsp_time_diff);
- }
- for (i = 0; i < mgr->num_cards; i++) {
- chip = mgr->chip[i];
- for (j = 0; j < chip->nb_streams_play; j++)
- pcxhr_update_timer_pos(mgr,
- &chip->playback_stream[j],
- dsp_time_diff);
- }
- }
- /* other irq's handled in the tasklet */
- if (reg & PCXHR_IRQ_MASK) {
- if (reg & PCXHR_IRQ_ASYNC) {
- /* as we didn't request any async notifications,
- * some kind of xrun error will probably occurred
- */
- /* better resynchronize all streams next interrupt : */
- mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID;
- }
- mgr->src_it_dsp = reg;
- tasklet_schedule(&mgr->msg_taskq);
- }
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- if (reg & PCXHR_FATAL_DSP_ERR)
- snd_printdd("FATAL DSP ERROR : %x\n", reg);
-#endif
- spin_unlock(&mgr->lock);
- return IRQ_HANDLED; /* this device caused the interrupt */
-}
diff --git a/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_core.h b/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_core.h
deleted file mode 100644
index be017379..00000000
--- a/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_core.h
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Driver for Digigram pcxhr compatible soundcards
- *
- * low level interface with interrupt and message handling
- *
- * Copyright (c) 2004 by Digigram <alsa@digigram.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __SOUND_PCXHR_CORE_H
-#define __SOUND_PCXHR_CORE_H
-
-struct firmware;
-struct pcxhr_mgr;
-
-/* init and firmware download commands */
-void pcxhr_reset_xilinx_com(struct pcxhr_mgr *mgr);
-void pcxhr_reset_dsp(struct pcxhr_mgr *mgr);
-void pcxhr_enable_dsp(struct pcxhr_mgr *mgr);
-int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr, const struct firmware *xilinx, int second);
-int pcxhr_load_eeprom_binary(struct pcxhr_mgr *mgr, const struct firmware *eeprom);
-int pcxhr_load_boot_binary(struct pcxhr_mgr *mgr, const struct firmware *boot);
-int pcxhr_load_dsp_binary(struct pcxhr_mgr *mgr, const struct firmware *dsp);
-
-/* DSP time available on MailBox4 register : 24 bit time samples() */
-#define PCXHR_DSP_TIME_MASK 0x00ffffff
-#define PCXHR_DSP_TIME_INVALID 0x10000000
-
-
-#define PCXHR_SIZE_MAX_CMD 8
-#define PCXHR_SIZE_MAX_STATUS 16
-#define PCXHR_SIZE_MAX_LONG_STATUS 256
-
-struct pcxhr_rmh {
- u16 cmd_len; /* length of the command to send (WORDs) */
- u16 stat_len; /* length of the status received (WORDs) */
- u16 dsp_stat; /* status type, RMP_SSIZE_XXX */
- u16 cmd_idx; /* index of the command */
- u32 cmd[PCXHR_SIZE_MAX_CMD];
- u32 stat[PCXHR_SIZE_MAX_STATUS];
-};
-
-enum {
- CMD_VERSION, /* cmd_len = 2 stat_len = 1 */
- CMD_SUPPORTED, /* cmd_len = 1 stat_len = 4 */
- CMD_TEST_IT, /* cmd_len = 1 stat_len = 1 */
- CMD_SEND_IRQA, /* cmd_len = 1 stat_len = 0 */
- CMD_ACCESS_IO_WRITE, /* cmd_len >= 1 stat_len >= 1 */
- CMD_ACCESS_IO_READ, /* cmd_len >= 1 stat_len >= 1 */
- CMD_ASYNC, /* cmd_len = 1 stat_len = 1 */
- CMD_MODIFY_CLOCK, /* cmd_len = 3 stat_len = 0 */
- CMD_RESYNC_AUDIO_INPUTS, /* cmd_len = 1 stat_len = 0 */
- CMD_GET_DSP_RESOURCES, /* cmd_len = 1 stat_len = 4 */
- CMD_SET_TIMER_INTERRUPT, /* cmd_len = 1 stat_len = 0 */
- CMD_RES_PIPE, /* cmd_len >=2 stat_len = 0 */
- CMD_FREE_PIPE, /* cmd_len = 1 stat_len = 0 */
- CMD_CONF_PIPE, /* cmd_len = 2 stat_len = 0 */
- CMD_STOP_PIPE, /* cmd_len = 1 stat_len = 0 */
- CMD_PIPE_SAMPLE_COUNT, /* cmd_len = 2 stat_len = 2 */
- CMD_CAN_START_PIPE, /* cmd_len >= 1 stat_len = 1 */
- CMD_START_STREAM, /* cmd_len = 2 stat_len = 0 */
- CMD_STREAM_OUT_LEVEL_ADJUST, /* cmd_len >= 1 stat_len = 0 */
- CMD_STOP_STREAM, /* cmd_len = 2 stat_len = 0 */
- CMD_UPDATE_R_BUFFERS, /* cmd_len = 4 stat_len = 0 */
- CMD_FORMAT_STREAM_OUT, /* cmd_len >= 2 stat_len = 0 */
- CMD_FORMAT_STREAM_IN, /* cmd_len >= 4 stat_len = 0 */
- CMD_STREAM_SAMPLE_COUNT, /* cmd_len = 2 stat_len = (2 * nb_stream) */
- CMD_AUDIO_LEVEL_ADJUST, /* cmd_len = 3 stat_len = 0 */
- CMD_LAST_INDEX
-};
-
-#define MASK_DSP_WORD 0x00ffffff
-#define MASK_ALL_STREAM 0x00ffffff
-#define MASK_DSP_WORD_LEVEL 0x000001ff
-#define MASK_FIRST_FIELD 0x0000001f
-#define FIELD_SIZE 5
-
-/*
- init the rmh struct; by default cmd_len is set to 1
- */
-void pcxhr_init_rmh(struct pcxhr_rmh *rmh, int cmd);
-
-void pcxhr_set_pipe_cmd_params(struct pcxhr_rmh* rmh, int capture, unsigned int param1,
- unsigned int param2, unsigned int param3);
-
-#define DSP_EXT_CMD_SET(x) (x->dsp_version > 0x012800)
-
-/*
- send the rmh
- */
-int pcxhr_send_msg(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh);
-
-
-/* values used for CMD_ACCESS_IO_WRITE and CMD_ACCESS_IO_READ */
-#define IO_NUM_REG_CONT 0
-#define IO_NUM_REG_GENCLK 1
-#define IO_NUM_REG_MUTE_OUT 2
-#define IO_NUM_SPEED_RATIO 4
-#define IO_NUM_REG_STATUS 5
-#define IO_NUM_REG_CUER 10
-#define IO_NUM_UER_CHIP_REG 11
-#define IO_NUM_REG_CONFIG_SRC 12
-#define IO_NUM_REG_OUT_ANA_LEVEL 20
-#define IO_NUM_REG_IN_ANA_LEVEL 21
-
-
-#define REG_CONT_UNMUTE_INPUTS 0x020000
-
-/* parameters used with register IO_NUM_REG_STATUS */
-#define REG_STATUS_OPTIONS 0
-#define REG_STATUS_AES_SYNC 8
-#define REG_STATUS_AES_1 9
-#define REG_STATUS_AES_2 10
-#define REG_STATUS_AES_3 11
-#define REG_STATUS_AES_4 12
-#define REG_STATUS_WORD_CLOCK 13
-#define REG_STATUS_INTER_SYNC 14
-#define REG_STATUS_CURRENT 0x80
-/* results */
-#define REG_STATUS_OPT_NO_VIDEO_SIGNAL 0x01
-#define REG_STATUS_OPT_DAUGHTER_MASK 0x1c
-#define REG_STATUS_OPT_ANALOG_BOARD 0x00
-#define REG_STATUS_OPT_NO_DAUGHTER 0x1c
-#define REG_STATUS_OPT_COMPANION_MASK 0xe0
-#define REG_STATUS_OPT_NO_COMPANION 0xe0
-#define REG_STATUS_SYNC_32000 0x00
-#define REG_STATUS_SYNC_44100 0x01
-#define REG_STATUS_SYNC_48000 0x02
-#define REG_STATUS_SYNC_64000 0x03
-#define REG_STATUS_SYNC_88200 0x04
-#define REG_STATUS_SYNC_96000 0x05
-#define REG_STATUS_SYNC_128000 0x06
-#define REG_STATUS_SYNC_176400 0x07
-#define REG_STATUS_SYNC_192000 0x08
-
-int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_mask, int start);
-
-int pcxhr_write_io_num_reg_cont(struct pcxhr_mgr *mgr, unsigned int mask,
- unsigned int value, int *changed);
-
-/* codec parameters */
-#define CS8416_RUN 0x200401
-#define CS8416_FORMAT_DETECT 0x200b00
-#define CS8416_CSB0 0x201900
-#define CS8416_CSB1 0x201a00
-#define CS8416_CSB2 0x201b00
-#define CS8416_CSB3 0x201c00
-#define CS8416_CSB4 0x201d00
-#define CS8416_VERSION 0x207f00
-
-#define CS8420_DATA_FLOW_CTL 0x200301
-#define CS8420_CLOCK_SRC_CTL 0x200401
-#define CS8420_RECEIVER_ERRORS 0x201000
-#define CS8420_SRC_RATIO 0x201e00
-#define CS8420_CSB0 0x202000
-#define CS8420_CSB1 0x202100
-#define CS8420_CSB2 0x202200
-#define CS8420_CSB3 0x202300
-#define CS8420_CSB4 0x202400
-#define CS8420_VERSION 0x207f00
-
-#define CS4271_MODE_CTL_1 0x200101
-#define CS4271_DAC_CTL 0x200201
-#define CS4271_VOLMIX 0x200301
-#define CS4271_VOLMUTE_LEFT 0x200401
-#define CS4271_VOLMUTE_RIGHT 0x200501
-#define CS4271_ADC_CTL 0x200601
-#define CS4271_MODE_CTL_2 0x200701
-
-#define CHIP_SIG_AND_MAP_SPI 0xff7f00
-
-/* codec selection */
-#define CS4271_01_CS 0x160018
-#define CS4271_23_CS 0x160019
-#define CS4271_45_CS 0x16001a
-#define CS4271_67_CS 0x16001b
-#define CS4271_89_CS 0x16001c
-#define CS4271_AB_CS 0x16001d
-#define CS8420_01_CS 0x080090
-#define CS8420_23_CS 0x080092
-#define CS8420_45_CS 0x080094
-#define CS8420_67_CS 0x080096
-#define CS8416_01_CS 0x080098
-
-
-/* interrupt handling */
-irqreturn_t pcxhr_interrupt(int irq, void *dev_id);
-void pcxhr_msg_tasklet(unsigned long arg);
-
-#endif /* __SOUND_PCXHR_CORE_H */
diff --git a/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_hwdep.c b/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_hwdep.c
deleted file mode 100644
index ec1587cd..00000000
--- a/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_hwdep.c
+++ /dev/null
@@ -1,503 +0,0 @@
-/*
- * Driver for Digigram pcxhr compatible soundcards
- *
- * hwdep device manager
- *
- * Copyright (c) 2004 by Digigram <alsa@digigram.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/interrupt.h>
-#include <linux/vmalloc.h>
-#include <linux/firmware.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <asm/io.h>
-#include <sound/core.h>
-#include <sound/hwdep.h>
-#include "pcxhr.h"
-#include "pcxhr_mixer.h"
-#include "pcxhr_hwdep.h"
-#include "pcxhr_core.h"
-#include "pcxhr_mix22.h"
-
-
-#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
-#if !defined(CONFIG_USE_PCXHRLOADER) && !defined(CONFIG_SND_PCXHR) /* built-in kernel */
-#define SND_PCXHR_FW_LOADER /* use the standard firmware loader */
-#endif
-#endif
-
-
-static int pcxhr_sub_init(struct pcxhr_mgr *mgr);
-/*
- * get basic information and init pcxhr card
- */
-static int pcxhr_init_board(struct pcxhr_mgr *mgr)
-{
- int err;
- struct pcxhr_rmh rmh;
- int card_streams;
-
- /* calc the number of all streams used */
- if (mgr->mono_capture)
- card_streams = mgr->capture_chips * 2;
- else
- card_streams = mgr->capture_chips;
- card_streams += mgr->playback_chips * PCXHR_PLAYBACK_STREAMS;
-
- /* enable interrupts */
- pcxhr_enable_dsp(mgr);
-
- pcxhr_init_rmh(&rmh, CMD_SUPPORTED);
- err = pcxhr_send_msg(mgr, &rmh);
- if (err)
- return err;
- /* test 8 or 12 phys out */
- if ((rmh.stat[0] & MASK_FIRST_FIELD) != mgr->playback_chips * 2)
- return -EINVAL;
- /* test 8 or 2 phys in */
- if (((rmh.stat[0] >> (2 * FIELD_SIZE)) & MASK_FIRST_FIELD) <
- mgr->capture_chips * 2)
- return -EINVAL;
- /* test max nb substream per board */
- if ((rmh.stat[1] & 0x5F) < card_streams)
- return -EINVAL;
- /* test max nb substream per pipe */
- if (((rmh.stat[1] >> 7) & 0x5F) < PCXHR_PLAYBACK_STREAMS)
- return -EINVAL;
- snd_printdd("supported formats : playback=%x capture=%x\n",
- rmh.stat[2], rmh.stat[3]);
-
- pcxhr_init_rmh(&rmh, CMD_VERSION);
- /* firmware num for DSP */
- rmh.cmd[0] |= mgr->firmware_num;
- /* transfer granularity in samples (should be multiple of 48) */
- rmh.cmd[1] = (1<<23) + mgr->granularity;
- rmh.cmd_len = 2;
- err = pcxhr_send_msg(mgr, &rmh);
- if (err)
- return err;
- snd_printdd("PCXHR DSP version is %d.%d.%d\n", (rmh.stat[0]>>16)&0xff,
- (rmh.stat[0]>>8)&0xff, rmh.stat[0]&0xff);
- mgr->dsp_version = rmh.stat[0];
-
- if (mgr->is_hr_stereo)
- err = hr222_sub_init(mgr);
- else
- err = pcxhr_sub_init(mgr);
- return err;
-}
-
-static int pcxhr_sub_init(struct pcxhr_mgr *mgr)
-{
- int err;
- struct pcxhr_rmh rmh;
-
- /* get options */
- pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
- rmh.cmd[0] |= IO_NUM_REG_STATUS;
- rmh.cmd[1] = REG_STATUS_OPTIONS;
- rmh.cmd_len = 2;
- err = pcxhr_send_msg(mgr, &rmh);
- if (err)
- return err;
-
- if ((rmh.stat[1] & REG_STATUS_OPT_DAUGHTER_MASK) ==
- REG_STATUS_OPT_ANALOG_BOARD)
- mgr->board_has_analog = 1; /* analog addon board found */
-
- /* unmute inputs */
- err = pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS,
- REG_CONT_UNMUTE_INPUTS, NULL);
- if (err)
- return err;
- /* unmute outputs (a write to IO_NUM_REG_MUTE_OUT mutes!) */
- pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
- rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
- if (DSP_EXT_CMD_SET(mgr)) {
- rmh.cmd[1] = 1; /* unmute digital plugs */
- rmh.cmd_len = 2;
- }
- err = pcxhr_send_msg(mgr, &rmh);
- return err;
-}
-
-void pcxhr_reset_board(struct pcxhr_mgr *mgr)
-{
- struct pcxhr_rmh rmh;
-
- if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {
- /* mute outputs */
- if (!mgr->is_hr_stereo) {
- /* a read to IO_NUM_REG_MUTE_OUT register unmutes! */
- pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
- rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
- pcxhr_send_msg(mgr, &rmh);
- /* mute inputs */
- pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS,
- 0, NULL);
- }
- /* stereo cards mute with reset of dsp */
- }
- /* reset pcxhr dsp */
- if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_EPRM_INDEX))
- pcxhr_reset_dsp(mgr);
- /* reset second xilinx */
- if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_XLX_COM_INDEX)) {
- pcxhr_reset_xilinx_com(mgr);
- mgr->dsp_loaded = 1;
- }
- return;
-}
-
-
-/*
- * allocate a playback/capture pipe (pcmp0/pcmc0)
- */
-static int pcxhr_dsp_allocate_pipe(struct pcxhr_mgr *mgr,
- struct pcxhr_pipe *pipe,
- int is_capture, int pin)
-{
- int stream_count, audio_count;
- int err;
- struct pcxhr_rmh rmh;
-
- if (is_capture) {
- stream_count = 1;
- if (mgr->mono_capture)
- audio_count = 1;
- else
- audio_count = 2;
- } else {
- stream_count = PCXHR_PLAYBACK_STREAMS;
- audio_count = 2; /* always stereo */
- }
- snd_printdd("snd_add_ref_pipe pin(%d) pcm%c0\n",
- pin, is_capture ? 'c' : 'p');
- pipe->is_capture = is_capture;
- pipe->first_audio = pin;
- /* define pipe (P_PCM_ONLY_MASK (0x020000) is not necessary) */
- pcxhr_init_rmh(&rmh, CMD_RES_PIPE);
- pcxhr_set_pipe_cmd_params(&rmh, is_capture, pin,
- audio_count, stream_count);
- rmh.cmd[1] |= 0x020000; /* add P_PCM_ONLY_MASK */
- if (DSP_EXT_CMD_SET(mgr)) {
- /* add channel mask to command */
- rmh.cmd[rmh.cmd_len++] = (audio_count == 1) ? 0x01 : 0x03;
- }
- err = pcxhr_send_msg(mgr, &rmh);
- if (err < 0) {
- snd_printk(KERN_ERR "error pipe allocation "
- "(CMD_RES_PIPE) err=%x!\n", err);
- return err;
- }
- pipe->status = PCXHR_PIPE_DEFINED;
-
- return 0;
-}
-
-/*
- * free playback/capture pipe (pcmp0/pcmc0)
- */
-#if 0
-static int pcxhr_dsp_free_pipe( struct pcxhr_mgr *mgr, struct pcxhr_pipe *pipe)
-{
- struct pcxhr_rmh rmh;
- int capture_mask = 0;
- int playback_mask = 0;
- int err = 0;
-
- if (pipe->is_capture)
- capture_mask = (1 << pipe->first_audio);
- else
- playback_mask = (1 << pipe->first_audio);
-
- /* stop one pipe */
- err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 0);
- if (err < 0)
- snd_printk(KERN_ERR "error stopping pipe!\n");
- /* release the pipe */
- pcxhr_init_rmh(&rmh, CMD_FREE_PIPE);
- pcxhr_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->first_audio,
- 0, 0);
- err = pcxhr_send_msg(mgr, &rmh);
- if (err < 0)
- snd_printk(KERN_ERR "error pipe release "
- "(CMD_FREE_PIPE) err(%x)\n", err);
- pipe->status = PCXHR_PIPE_UNDEFINED;
- return err;
-}
-#endif
-
-
-static int pcxhr_config_pipes(struct pcxhr_mgr *mgr)
-{
- int err, i, j;
- struct snd_pcxhr *chip;
- struct pcxhr_pipe *pipe;
-
- /* allocate the pipes on the dsp */
- for (i = 0; i < mgr->num_cards; i++) {
- chip = mgr->chip[i];
- if (chip->nb_streams_play) {
- pipe = &chip->playback_pipe;
- err = pcxhr_dsp_allocate_pipe( mgr, pipe, 0, i*2);
- if (err)
- return err;
- for(j = 0; j < chip->nb_streams_play; j++)
- chip->playback_stream[j].pipe = pipe;
- }
- for (j = 0; j < chip->nb_streams_capt; j++) {
- pipe = &chip->capture_pipe[j];
- err = pcxhr_dsp_allocate_pipe(mgr, pipe, 1, i*2 + j);
- if (err)
- return err;
- chip->capture_stream[j].pipe = pipe;
- }
- }
- return 0;
-}
-
-static int pcxhr_start_pipes(struct pcxhr_mgr *mgr)
-{
- int i, j;
- struct snd_pcxhr *chip;
- int playback_mask = 0;
- int capture_mask = 0;
-
- /* start all the pipes on the dsp */
- for (i = 0; i < mgr->num_cards; i++) {
- chip = mgr->chip[i];
- if (chip->nb_streams_play)
- playback_mask |= 1 << chip->playback_pipe.first_audio;
- for (j = 0; j < chip->nb_streams_capt; j++)
- capture_mask |= 1 << chip->capture_pipe[j].first_audio;
- }
- return pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1);
-}
-
-
-static int pcxhr_dsp_load(struct pcxhr_mgr *mgr, int index,
- const struct firmware *dsp)
-{
- int err, card_index;
-
- snd_printdd("loading dsp [%d] size = %Zd\n", index, dsp->size);
-
- switch (index) {
- case PCXHR_FIRMWARE_XLX_INT_INDEX:
- pcxhr_reset_xilinx_com(mgr);
- return pcxhr_load_xilinx_binary(mgr, dsp, 0);
-
- case PCXHR_FIRMWARE_XLX_COM_INDEX:
- pcxhr_reset_xilinx_com(mgr);
- return pcxhr_load_xilinx_binary(mgr, dsp, 1);
-
- case PCXHR_FIRMWARE_DSP_EPRM_INDEX:
- pcxhr_reset_dsp(mgr);
- return pcxhr_load_eeprom_binary(mgr, dsp);
-
- case PCXHR_FIRMWARE_DSP_BOOT_INDEX:
- return pcxhr_load_boot_binary(mgr, dsp);
-
- case PCXHR_FIRMWARE_DSP_MAIN_INDEX:
- err = pcxhr_load_dsp_binary(mgr, dsp);
- if (err)
- return err;
- break; /* continue with first init */
- default:
- snd_printk(KERN_ERR "wrong file index\n");
- return -EFAULT;
- } /* end of switch file index*/
-
- /* first communication with embedded */
- err = pcxhr_init_board(mgr);
- if (err < 0) {
- snd_printk(KERN_ERR "pcxhr could not be set up\n");
- return err;
- }
- err = pcxhr_config_pipes(mgr);
- if (err < 0) {
- snd_printk(KERN_ERR "pcxhr pipes could not be set up\n");
- return err;
- }
- /* create devices and mixer in accordance with HW options*/
- for (card_index = 0; card_index < mgr->num_cards; card_index++) {
- struct snd_pcxhr *chip = mgr->chip[card_index];
-
- if ((err = pcxhr_create_pcm(chip)) < 0)
- return err;
-
- if (card_index == 0) {
- if ((err = pcxhr_create_mixer(chip->mgr)) < 0)
- return err;
- }
- if ((err = snd_card_register(chip->card)) < 0)
- return err;
- }
- err = pcxhr_start_pipes(mgr);
- if (err < 0) {
- snd_printk(KERN_ERR "pcxhr pipes could not be started\n");
- return err;
- }
- snd_printdd("pcxhr firmware downloaded and successfully set up\n");
-
- return 0;
-}
-
-/*
- * fw loader entry
- */
-#ifdef SND_PCXHR_FW_LOADER
-
-int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
-{
- static char *fw_files[][5] = {
- [0] = { "xlxint.dat", "xlxc882hr.dat",
- "dspe882.e56", "dspb882hr.b56", "dspd882.d56" },
- [1] = { "xlxint.dat", "xlxc882e.dat",
- "dspe882.e56", "dspb882e.b56", "dspd882.d56" },
- [2] = { "xlxint.dat", "xlxc1222hr.dat",
- "dspe882.e56", "dspb1222hr.b56", "dspd1222.d56" },
- [3] = { "xlxint.dat", "xlxc1222e.dat",
- "dspe882.e56", "dspb1222e.b56", "dspd1222.d56" },
- [4] = { NULL, "xlxc222.dat",
- "dspe924.e56", "dspb924.b56", "dspd222.d56" },
- [5] = { NULL, "xlxc924.dat",
- "dspe924.e56", "dspb924.b56", "dspd222.d56" },
- };
- char path[32];
-
- const struct firmware *fw_entry;
- int i, err;
- int fw_set = mgr->fw_file_set;
-
- for (i = 0; i < 5; i++) {
- if (!fw_files[fw_set][i])
- continue;
- sprintf(path, "pcxhr/%s", fw_files[fw_set][i]);
- if (request_firmware(&fw_entry, path, &mgr->pci->dev)) {
- snd_printk(KERN_ERR "pcxhr: can't load firmware %s\n",
- path);
- return -ENOENT;
- }
- /* fake hwdep dsp record */
- err = pcxhr_dsp_load(mgr, i, fw_entry);
- release_firmware(fw_entry);
- if (err < 0)
- return err;
- mgr->dsp_loaded |= 1 << i;
- }
- return 0;
-}
-
-MODULE_FIRMWARE("pcxhr/xlxint.dat");
-MODULE_FIRMWARE("pcxhr/xlxc882hr.dat");
-MODULE_FIRMWARE("pcxhr/xlxc882e.dat");
-MODULE_FIRMWARE("pcxhr/dspe882.e56");
-MODULE_FIRMWARE("pcxhr/dspb882hr.b56");
-MODULE_FIRMWARE("pcxhr/dspb882e.b56");
-MODULE_FIRMWARE("pcxhr/dspd882.d56");
-
-MODULE_FIRMWARE("pcxhr/xlxc1222hr.dat");
-MODULE_FIRMWARE("pcxhr/xlxc1222e.dat");
-MODULE_FIRMWARE("pcxhr/dspb1222hr.b56");
-MODULE_FIRMWARE("pcxhr/dspb1222e.b56");
-MODULE_FIRMWARE("pcxhr/dspd1222.d56");
-
-MODULE_FIRMWARE("pcxhr/xlxc222.dat");
-MODULE_FIRMWARE("pcxhr/xlxc924.dat");
-MODULE_FIRMWARE("pcxhr/dspe924.e56");
-MODULE_FIRMWARE("pcxhr/dspb924.b56");
-MODULE_FIRMWARE("pcxhr/dspd222.d56");
-
-
-#else /* old style firmware loading */
-
-/* pcxhr hwdep interface id string */
-#define PCXHR_HWDEP_ID "pcxhr loader"
-
-
-static int pcxhr_hwdep_dsp_status(struct snd_hwdep *hw,
- struct snd_hwdep_dsp_status *info)
-{
- struct pcxhr_mgr *mgr = hw->private_data;
- sprintf(info->id, "pcxhr%d", mgr->fw_file_set);
- info->num_dsps = PCXHR_FIRMWARE_FILES_MAX_INDEX;
-
- if (hw->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX))
- info->chip_ready = 1;
-
- info->version = PCXHR_DRIVER_VERSION;
- return 0;
-}
-
-static int pcxhr_hwdep_dsp_load(struct snd_hwdep *hw,
- struct snd_hwdep_dsp_image *dsp)
-{
- struct pcxhr_mgr *mgr = hw->private_data;
- int err;
- struct firmware fw;
-
- fw.size = dsp->length;
- fw.data = vmalloc(fw.size);
- if (! fw.data) {
- snd_printk(KERN_ERR "pcxhr: cannot allocate dsp image "
- "(%lu bytes)\n", (unsigned long)fw.size);
- return -ENOMEM;
- }
- if (copy_from_user((void *)fw.data, dsp->image, dsp->length)) {
- vfree(fw.data);
- return -EFAULT;
- }
- err = pcxhr_dsp_load(mgr, dsp->index, &fw);
- vfree(fw.data);
- if (err < 0)
- return err;
- mgr->dsp_loaded |= 1 << dsp->index;
- return 0;
-}
-
-int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
-{
- int err;
- struct snd_hwdep *hw;
-
- /* only create hwdep interface for first cardX
- * (see "index" module parameter)
- */
- err = snd_hwdep_new(mgr->chip[0]->card, PCXHR_HWDEP_ID, 0, &hw);
- if (err < 0)
- return err;
-
- hw->iface = SNDRV_HWDEP_IFACE_PCXHR;
- hw->private_data = mgr;
- hw->ops.dsp_status = pcxhr_hwdep_dsp_status;
- hw->ops.dsp_load = pcxhr_hwdep_dsp_load;
- hw->exclusive = 1;
- /* stereo cards don't need fw_file_0 -> dsp_loaded = 1 */
- hw->dsp_loaded = mgr->is_hr_stereo ? 1 : 0;
- mgr->dsp_loaded = 0;
- sprintf(hw->name, PCXHR_HWDEP_ID);
-
- err = snd_card_register(mgr->chip[0]->card);
- if (err < 0)
- return err;
- return 0;
-}
-
-#endif /* SND_PCXHR_FW_LOADER */
diff --git a/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_hwdep.h b/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_hwdep.h
deleted file mode 100644
index f561909d..00000000
--- a/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_hwdep.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Driver for Digigram pcxhr compatible soundcards
- *
- * definitions and makros for basic card access
- *
- * Copyright (c) 2004 by Digigram <alsa@digigram.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __SOUND_PCXHR_HWDEP_H
-#define __SOUND_PCXHR_HWDEP_H
-
-
-/* firmware status codes */
-#define PCXHR_FIRMWARE_XLX_INT_INDEX 0
-#define PCXHR_FIRMWARE_XLX_COM_INDEX 1
-#define PCXHR_FIRMWARE_DSP_EPRM_INDEX 2
-#define PCXHR_FIRMWARE_DSP_BOOT_INDEX 3
-#define PCXHR_FIRMWARE_DSP_MAIN_INDEX 4
-#define PCXHR_FIRMWARE_FILES_MAX_INDEX 5
-
-
-/* exported */
-int pcxhr_setup_firmware(struct pcxhr_mgr *mgr);
-void pcxhr_reset_board(struct pcxhr_mgr *mgr);
-
-#endif /* __SOUND_PCXHR_HWDEP_H */
diff --git a/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_mix22.c b/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_mix22.c
deleted file mode 100644
index 1cb82c0a..00000000
--- a/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_mix22.c
+++ /dev/null
@@ -1,852 +0,0 @@
-/*
- * Driver for Digigram pcxhr compatible soundcards
- *
- * mixer interface for stereo cards
- *
- * Copyright (c) 2004 by Digigram <alsa@digigram.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/asoundef.h>
-#include "pcxhr.h"
-#include "pcxhr_core.h"
-#include "pcxhr_mix22.h"
-
-
-/* registers used on the DSP and Xilinx (port 2) : HR stereo cards only */
-#define PCXHR_DSP_RESET 0x20
-#define PCXHR_XLX_CFG 0x24
-#define PCXHR_XLX_RUER 0x28
-#define PCXHR_XLX_DATA 0x2C
-#define PCXHR_XLX_STATUS 0x30
-#define PCXHR_XLX_LOFREQ 0x34
-#define PCXHR_XLX_HIFREQ 0x38
-#define PCXHR_XLX_CSUER 0x3C
-#define PCXHR_XLX_SELMIC 0x40
-
-#define PCXHR_DSP 2
-
-/* byte access only ! */
-#define PCXHR_INPB(mgr, x) inb((mgr)->port[PCXHR_DSP] + (x))
-#define PCXHR_OUTPB(mgr, x, data) outb((data), (mgr)->port[PCXHR_DSP] + (x))
-
-
-/* values for PCHR_DSP_RESET register */
-#define PCXHR_DSP_RESET_DSP 0x01
-#define PCXHR_DSP_RESET_MUTE 0x02
-#define PCXHR_DSP_RESET_CODEC 0x08
-#define PCXHR_DSP_RESET_GPO_OFFSET 5
-#define PCXHR_DSP_RESET_GPO_MASK 0x60
-
-/* values for PCHR_XLX_CFG register */
-#define PCXHR_CFG_SYNCDSP_MASK 0x80
-#define PCXHR_CFG_DEPENDENCY_MASK 0x60
-#define PCXHR_CFG_INDEPENDANT_SEL 0x00
-#define PCXHR_CFG_MASTER_SEL 0x40
-#define PCXHR_CFG_SLAVE_SEL 0x20
-#define PCXHR_CFG_DATA_UER1_SEL_MASK 0x10 /* 0 (UER0), 1(UER1) */
-#define PCXHR_CFG_DATAIN_SEL_MASK 0x08 /* 0 (ana), 1 (UER) */
-#define PCXHR_CFG_SRC_MASK 0x04 /* 0 (Bypass), 1 (SRC Actif) */
-#define PCXHR_CFG_CLOCK_UER1_SEL_MASK 0x02 /* 0 (UER0), 1(UER1) */
-#define PCXHR_CFG_CLOCKIN_SEL_MASK 0x01 /* 0 (internal), 1 (AES/EBU) */
-
-/* values for PCHR_XLX_DATA register */
-#define PCXHR_DATA_CODEC 0x80
-#define AKM_POWER_CONTROL_CMD 0xA007
-#define AKM_RESET_ON_CMD 0xA100
-#define AKM_RESET_OFF_CMD 0xA103
-#define AKM_CLOCK_INF_55K_CMD 0xA240
-#define AKM_CLOCK_SUP_55K_CMD 0xA24D
-#define AKM_MUTE_CMD 0xA38D
-#define AKM_UNMUTE_CMD 0xA30D
-#define AKM_LEFT_LEVEL_CMD 0xA600
-#define AKM_RIGHT_LEVEL_CMD 0xA700
-
-/* values for PCHR_XLX_STATUS register - READ */
-#define PCXHR_STAT_SRC_LOCK 0x01
-#define PCXHR_STAT_LEVEL_IN 0x02
-#define PCXHR_STAT_GPI_OFFSET 2
-#define PCXHR_STAT_GPI_MASK 0x0C
-#define PCXHR_STAT_MIC_CAPS 0x10
-/* values for PCHR_XLX_STATUS register - WRITE */
-#define PCXHR_STAT_FREQ_SYNC_MASK 0x01
-#define PCXHR_STAT_FREQ_UER1_MASK 0x02
-#define PCXHR_STAT_FREQ_SAVE_MASK 0x80
-
-/* values for PCHR_XLX_CSUER register */
-#define PCXHR_SUER1_BIT_U_READ_MASK 0x80
-#define PCXHR_SUER1_BIT_C_READ_MASK 0x40
-#define PCXHR_SUER1_DATA_PRESENT_MASK 0x20
-#define PCXHR_SUER1_CLOCK_PRESENT_MASK 0x10
-#define PCXHR_SUER_BIT_U_READ_MASK 0x08
-#define PCXHR_SUER_BIT_C_READ_MASK 0x04
-#define PCXHR_SUER_DATA_PRESENT_MASK 0x02
-#define PCXHR_SUER_CLOCK_PRESENT_MASK 0x01
-
-#define PCXHR_SUER_BIT_U_WRITE_MASK 0x02
-#define PCXHR_SUER_BIT_C_WRITE_MASK 0x01
-
-/* values for PCXHR_XLX_SELMIC register - WRITE */
-#define PCXHR_SELMIC_PREAMPLI_OFFSET 2
-#define PCXHR_SELMIC_PREAMPLI_MASK 0x0C
-#define PCXHR_SELMIC_PHANTOM_ALIM 0x80
-
-
-static const unsigned char g_hr222_p_level[] = {
- 0x00, /* [000] -49.5 dB: AKM[000] = -1.#INF dB (mute) */
- 0x01, /* [001] -49.0 dB: AKM[001] = -48.131 dB (diff=0.86920 dB) */
- 0x01, /* [002] -48.5 dB: AKM[001] = -48.131 dB (diff=0.36920 dB) */
- 0x01, /* [003] -48.0 dB: AKM[001] = -48.131 dB (diff=0.13080 dB) */
- 0x01, /* [004] -47.5 dB: AKM[001] = -48.131 dB (diff=0.63080 dB) */
- 0x01, /* [005] -46.5 dB: AKM[001] = -48.131 dB (diff=1.63080 dB) */
- 0x01, /* [006] -47.0 dB: AKM[001] = -48.131 dB (diff=1.13080 dB) */
- 0x01, /* [007] -46.0 dB: AKM[001] = -48.131 dB (diff=2.13080 dB) */
- 0x01, /* [008] -45.5 dB: AKM[001] = -48.131 dB (diff=2.63080 dB) */
- 0x02, /* [009] -45.0 dB: AKM[002] = -42.110 dB (diff=2.88980 dB) */
- 0x02, /* [010] -44.5 dB: AKM[002] = -42.110 dB (diff=2.38980 dB) */
- 0x02, /* [011] -44.0 dB: AKM[002] = -42.110 dB (diff=1.88980 dB) */
- 0x02, /* [012] -43.5 dB: AKM[002] = -42.110 dB (diff=1.38980 dB) */
- 0x02, /* [013] -43.0 dB: AKM[002] = -42.110 dB (diff=0.88980 dB) */
- 0x02, /* [014] -42.5 dB: AKM[002] = -42.110 dB (diff=0.38980 dB) */
- 0x02, /* [015] -42.0 dB: AKM[002] = -42.110 dB (diff=0.11020 dB) */
- 0x02, /* [016] -41.5 dB: AKM[002] = -42.110 dB (diff=0.61020 dB) */
- 0x02, /* [017] -41.0 dB: AKM[002] = -42.110 dB (diff=1.11020 dB) */
- 0x02, /* [018] -40.5 dB: AKM[002] = -42.110 dB (diff=1.61020 dB) */
- 0x03, /* [019] -40.0 dB: AKM[003] = -38.588 dB (diff=1.41162 dB) */
- 0x03, /* [020] -39.5 dB: AKM[003] = -38.588 dB (diff=0.91162 dB) */
- 0x03, /* [021] -39.0 dB: AKM[003] = -38.588 dB (diff=0.41162 dB) */
- 0x03, /* [022] -38.5 dB: AKM[003] = -38.588 dB (diff=0.08838 dB) */
- 0x03, /* [023] -38.0 dB: AKM[003] = -38.588 dB (diff=0.58838 dB) */
- 0x03, /* [024] -37.5 dB: AKM[003] = -38.588 dB (diff=1.08838 dB) */
- 0x04, /* [025] -37.0 dB: AKM[004] = -36.090 dB (diff=0.91040 dB) */
- 0x04, /* [026] -36.5 dB: AKM[004] = -36.090 dB (diff=0.41040 dB) */
- 0x04, /* [027] -36.0 dB: AKM[004] = -36.090 dB (diff=0.08960 dB) */
- 0x04, /* [028] -35.5 dB: AKM[004] = -36.090 dB (diff=0.58960 dB) */
- 0x05, /* [029] -35.0 dB: AKM[005] = -34.151 dB (diff=0.84860 dB) */
- 0x05, /* [030] -34.5 dB: AKM[005] = -34.151 dB (diff=0.34860 dB) */
- 0x05, /* [031] -34.0 dB: AKM[005] = -34.151 dB (diff=0.15140 dB) */
- 0x05, /* [032] -33.5 dB: AKM[005] = -34.151 dB (diff=0.65140 dB) */
- 0x06, /* [033] -33.0 dB: AKM[006] = -32.568 dB (diff=0.43222 dB) */
- 0x06, /* [034] -32.5 dB: AKM[006] = -32.568 dB (diff=0.06778 dB) */
- 0x06, /* [035] -32.0 dB: AKM[006] = -32.568 dB (diff=0.56778 dB) */
- 0x07, /* [036] -31.5 dB: AKM[007] = -31.229 dB (diff=0.27116 dB) */
- 0x07, /* [037] -31.0 dB: AKM[007] = -31.229 dB (diff=0.22884 dB) */
- 0x08, /* [038] -30.5 dB: AKM[008] = -30.069 dB (diff=0.43100 dB) */
- 0x08, /* [039] -30.0 dB: AKM[008] = -30.069 dB (diff=0.06900 dB) */
- 0x09, /* [040] -29.5 dB: AKM[009] = -29.046 dB (diff=0.45405 dB) */
- 0x09, /* [041] -29.0 dB: AKM[009] = -29.046 dB (diff=0.04595 dB) */
- 0x0a, /* [042] -28.5 dB: AKM[010] = -28.131 dB (diff=0.36920 dB) */
- 0x0a, /* [043] -28.0 dB: AKM[010] = -28.131 dB (diff=0.13080 dB) */
- 0x0b, /* [044] -27.5 dB: AKM[011] = -27.303 dB (diff=0.19705 dB) */
- 0x0b, /* [045] -27.0 dB: AKM[011] = -27.303 dB (diff=0.30295 dB) */
- 0x0c, /* [046] -26.5 dB: AKM[012] = -26.547 dB (diff=0.04718 dB) */
- 0x0d, /* [047] -26.0 dB: AKM[013] = -25.852 dB (diff=0.14806 dB) */
- 0x0e, /* [048] -25.5 dB: AKM[014] = -25.208 dB (diff=0.29176 dB) */
- 0x0e, /* [049] -25.0 dB: AKM[014] = -25.208 dB (diff=0.20824 dB) */
- 0x0f, /* [050] -24.5 dB: AKM[015] = -24.609 dB (diff=0.10898 dB) */
- 0x10, /* [051] -24.0 dB: AKM[016] = -24.048 dB (diff=0.04840 dB) */
- 0x11, /* [052] -23.5 dB: AKM[017] = -23.522 dB (diff=0.02183 dB) */
- 0x12, /* [053] -23.0 dB: AKM[018] = -23.025 dB (diff=0.02535 dB) */
- 0x13, /* [054] -22.5 dB: AKM[019] = -22.556 dB (diff=0.05573 dB) */
- 0x14, /* [055] -22.0 dB: AKM[020] = -22.110 dB (diff=0.11020 dB) */
- 0x15, /* [056] -21.5 dB: AKM[021] = -21.686 dB (diff=0.18642 dB) */
- 0x17, /* [057] -21.0 dB: AKM[023] = -20.896 dB (diff=0.10375 dB) */
- 0x18, /* [058] -20.5 dB: AKM[024] = -20.527 dB (diff=0.02658 dB) */
- 0x1a, /* [059] -20.0 dB: AKM[026] = -19.831 dB (diff=0.16866 dB) */
- 0x1b, /* [060] -19.5 dB: AKM[027] = -19.504 dB (diff=0.00353 dB) */
- 0x1d, /* [061] -19.0 dB: AKM[029] = -18.883 dB (diff=0.11716 dB) */
- 0x1e, /* [062] -18.5 dB: AKM[030] = -18.588 dB (diff=0.08838 dB) */
- 0x20, /* [063] -18.0 dB: AKM[032] = -18.028 dB (diff=0.02780 dB) */
- 0x22, /* [064] -17.5 dB: AKM[034] = -17.501 dB (diff=0.00123 dB) */
- 0x24, /* [065] -17.0 dB: AKM[036] = -17.005 dB (diff=0.00475 dB) */
- 0x26, /* [066] -16.5 dB: AKM[038] = -16.535 dB (diff=0.03513 dB) */
- 0x28, /* [067] -16.0 dB: AKM[040] = -16.090 dB (diff=0.08960 dB) */
- 0x2b, /* [068] -15.5 dB: AKM[043] = -15.461 dB (diff=0.03857 dB) */
- 0x2d, /* [069] -15.0 dB: AKM[045] = -15.067 dB (diff=0.06655 dB) */
- 0x30, /* [070] -14.5 dB: AKM[048] = -14.506 dB (diff=0.00598 dB) */
- 0x33, /* [071] -14.0 dB: AKM[051] = -13.979 dB (diff=0.02060 dB) */
- 0x36, /* [072] -13.5 dB: AKM[054] = -13.483 dB (diff=0.01707 dB) */
- 0x39, /* [073] -13.0 dB: AKM[057] = -13.013 dB (diff=0.01331 dB) */
- 0x3c, /* [074] -12.5 dB: AKM[060] = -12.568 dB (diff=0.06778 dB) */
- 0x40, /* [075] -12.0 dB: AKM[064] = -12.007 dB (diff=0.00720 dB) */
- 0x44, /* [076] -11.5 dB: AKM[068] = -11.481 dB (diff=0.01937 dB) */
- 0x48, /* [077] -11.0 dB: AKM[072] = -10.984 dB (diff=0.01585 dB) */
- 0x4c, /* [078] -10.5 dB: AKM[076] = -10.515 dB (diff=0.01453 dB) */
- 0x51, /* [079] -10.0 dB: AKM[081] = -9.961 dB (diff=0.03890 dB) */
- 0x55, /* [080] -9.5 dB: AKM[085] = -9.542 dB (diff=0.04243 dB) */
- 0x5a, /* [081] -9.0 dB: AKM[090] = -9.046 dB (diff=0.04595 dB) */
- 0x60, /* [082] -8.5 dB: AKM[096] = -8.485 dB (diff=0.01462 dB) */
- 0x66, /* [083] -8.0 dB: AKM[102] = -7.959 dB (diff=0.04120 dB) */
- 0x6c, /* [084] -7.5 dB: AKM[108] = -7.462 dB (diff=0.03767 dB) */
- 0x72, /* [085] -7.0 dB: AKM[114] = -6.993 dB (diff=0.00729 dB) */
- 0x79, /* [086] -6.5 dB: AKM[121] = -6.475 dB (diff=0.02490 dB) */
- 0x80, /* [087] -6.0 dB: AKM[128] = -5.987 dB (diff=0.01340 dB) */
- 0x87, /* [088] -5.5 dB: AKM[135] = -5.524 dB (diff=0.02413 dB) */
- 0x8f, /* [089] -5.0 dB: AKM[143] = -5.024 dB (diff=0.02408 dB) */
- 0x98, /* [090] -4.5 dB: AKM[152] = -4.494 dB (diff=0.00607 dB) */
- 0xa1, /* [091] -4.0 dB: AKM[161] = -3.994 dB (diff=0.00571 dB) */
- 0xaa, /* [092] -3.5 dB: AKM[170] = -3.522 dB (diff=0.02183 dB) */
- 0xb5, /* [093] -3.0 dB: AKM[181] = -2.977 dB (diff=0.02277 dB) */
- 0xbf, /* [094] -2.5 dB: AKM[191] = -2.510 dB (diff=0.01014 dB) */
- 0xcb, /* [095] -2.0 dB: AKM[203] = -1.981 dB (diff=0.01912 dB) */
- 0xd7, /* [096] -1.5 dB: AKM[215] = -1.482 dB (diff=0.01797 dB) */
- 0xe3, /* [097] -1.0 dB: AKM[227] = -1.010 dB (diff=0.01029 dB) */
- 0xf1, /* [098] -0.5 dB: AKM[241] = -0.490 dB (diff=0.00954 dB) */
- 0xff, /* [099] +0.0 dB: AKM[255] = +0.000 dB (diff=0.00000 dB) */
-};
-
-
-static void hr222_config_akm(struct pcxhr_mgr *mgr, unsigned short data)
-{
- unsigned short mask = 0x8000;
- /* activate access to codec registers */
- PCXHR_INPB(mgr, PCXHR_XLX_HIFREQ);
-
- while (mask) {
- PCXHR_OUTPB(mgr, PCXHR_XLX_DATA,
- data & mask ? PCXHR_DATA_CODEC : 0);
- mask >>= 1;
- }
- /* termiate access to codec registers */
- PCXHR_INPB(mgr, PCXHR_XLX_RUER);
-}
-
-
-static int hr222_set_hw_playback_level(struct pcxhr_mgr *mgr,
- int idx, int level)
-{
- unsigned short cmd;
- if (idx > 1 ||
- level < 0 ||
- level >= ARRAY_SIZE(g_hr222_p_level))
- return -EINVAL;
-
- if (idx == 0)
- cmd = AKM_LEFT_LEVEL_CMD;
- else
- cmd = AKM_RIGHT_LEVEL_CMD;
-
- /* conversion from PmBoardCodedLevel to AKM nonlinear programming */
- cmd += g_hr222_p_level[level];
-
- hr222_config_akm(mgr, cmd);
- return 0;
-}
-
-
-static int hr222_set_hw_capture_level(struct pcxhr_mgr *mgr,
- int level_l, int level_r, int level_mic)
-{
- /* program all input levels at the same time */
- unsigned int data;
- int i;
-
- if (!mgr->capture_chips)
- return -EINVAL; /* no PCX22 */
-
- data = ((level_mic & 0xff) << 24); /* micro is mono, but apply */
- data |= ((level_mic & 0xff) << 16); /* level on both channels */
- data |= ((level_r & 0xff) << 8); /* line input right channel */
- data |= (level_l & 0xff); /* line input left channel */
-
- PCXHR_INPB(mgr, PCXHR_XLX_DATA); /* activate input codec */
- /* send 32 bits (4 x 8 bits) */
- for (i = 0; i < 32; i++, data <<= 1) {
- PCXHR_OUTPB(mgr, PCXHR_XLX_DATA,
- (data & 0x80000000) ? PCXHR_DATA_CODEC : 0);
- }
- PCXHR_INPB(mgr, PCXHR_XLX_RUER); /* close input level codec */
- return 0;
-}
-
-static void hr222_micro_boost(struct pcxhr_mgr *mgr, int level);
-
-int hr222_sub_init(struct pcxhr_mgr *mgr)
-{
- unsigned char reg;
-
- mgr->board_has_analog = 1; /* analog always available */
- mgr->xlx_cfg = PCXHR_CFG_SYNCDSP_MASK;
-
- reg = PCXHR_INPB(mgr, PCXHR_XLX_STATUS);
- if (reg & PCXHR_STAT_MIC_CAPS)
- mgr->board_has_mic = 1; /* microphone available */
- snd_printdd("MIC input available = %d\n", mgr->board_has_mic);
-
- /* reset codec */
- PCXHR_OUTPB(mgr, PCXHR_DSP_RESET,
- PCXHR_DSP_RESET_DSP);
- msleep(5);
- mgr->dsp_reset = PCXHR_DSP_RESET_DSP |
- PCXHR_DSP_RESET_MUTE |
- PCXHR_DSP_RESET_CODEC;
- PCXHR_OUTPB(mgr, PCXHR_DSP_RESET, mgr->dsp_reset);
- /* hr222_write_gpo(mgr, 0); does the same */
- msleep(5);
-
- /* config AKM */
- hr222_config_akm(mgr, AKM_POWER_CONTROL_CMD);
- hr222_config_akm(mgr, AKM_CLOCK_INF_55K_CMD);
- hr222_config_akm(mgr, AKM_UNMUTE_CMD);
- hr222_config_akm(mgr, AKM_RESET_OFF_CMD);
-
- /* init micro boost */
- hr222_micro_boost(mgr, 0);
-
- return 0;
-}
-
-
-/* calc PLL register */
-/* TODO : there is a very similar fct in pcxhr.c */
-static int hr222_pll_freq_register(unsigned int freq,
- unsigned int *pllreg,
- unsigned int *realfreq)
-{
- unsigned int reg;
-
- if (freq < 6900 || freq > 219000)
- return -EINVAL;
- reg = (28224000 * 2) / freq;
- reg = (reg - 1) / 2;
- if (reg < 0x100)
- *pllreg = reg + 0xC00;
- else if (reg < 0x200)
- *pllreg = reg + 0x800;
- else if (reg < 0x400)
- *pllreg = reg & 0x1ff;
- else if (reg < 0x800) {
- *pllreg = ((reg >> 1) & 0x1ff) + 0x200;
- reg &= ~1;
- } else {
- *pllreg = ((reg >> 2) & 0x1ff) + 0x400;
- reg &= ~3;
- }
- if (realfreq)
- *realfreq = (28224000 / (reg + 1));
- return 0;
-}
-
-int hr222_sub_set_clock(struct pcxhr_mgr *mgr,
- unsigned int rate,
- int *changed)
-{
- unsigned int speed, pllreg = 0;
- int err;
- unsigned realfreq = rate;
-
- switch (mgr->use_clock_type) {
- case HR22_CLOCK_TYPE_INTERNAL:
- err = hr222_pll_freq_register(rate, &pllreg, &realfreq);
- if (err)
- return err;
-
- mgr->xlx_cfg &= ~(PCXHR_CFG_CLOCKIN_SEL_MASK |
- PCXHR_CFG_CLOCK_UER1_SEL_MASK);
- break;
- case HR22_CLOCK_TYPE_AES_SYNC:
- mgr->xlx_cfg |= PCXHR_CFG_CLOCKIN_SEL_MASK;
- mgr->xlx_cfg &= ~PCXHR_CFG_CLOCK_UER1_SEL_MASK;
- break;
- case HR22_CLOCK_TYPE_AES_1:
- if (!mgr->board_has_aes1)
- return -EINVAL;
-
- mgr->xlx_cfg |= (PCXHR_CFG_CLOCKIN_SEL_MASK |
- PCXHR_CFG_CLOCK_UER1_SEL_MASK);
- break;
- default:
- return -EINVAL;
- }
- hr222_config_akm(mgr, AKM_MUTE_CMD);
-
- if (mgr->use_clock_type == HR22_CLOCK_TYPE_INTERNAL) {
- PCXHR_OUTPB(mgr, PCXHR_XLX_HIFREQ, pllreg >> 8);
- PCXHR_OUTPB(mgr, PCXHR_XLX_LOFREQ, pllreg & 0xff);
- }
-
- /* set clock source */
- PCXHR_OUTPB(mgr, PCXHR_XLX_CFG, mgr->xlx_cfg);
-
- /* codec speed modes */
- speed = rate < 55000 ? 0 : 1;
- if (mgr->codec_speed != speed) {
- mgr->codec_speed = speed;
- if (speed == 0)
- hr222_config_akm(mgr, AKM_CLOCK_INF_55K_CMD);
- else
- hr222_config_akm(mgr, AKM_CLOCK_SUP_55K_CMD);
- }
-
- mgr->sample_rate_real = realfreq;
- mgr->cur_clock_type = mgr->use_clock_type;
-
- if (changed)
- *changed = 1;
-
- hr222_config_akm(mgr, AKM_UNMUTE_CMD);
-
- snd_printdd("set_clock to %dHz (realfreq=%d pllreg=%x)\n",
- rate, realfreq, pllreg);
- return 0;
-}
-
-int hr222_get_external_clock(struct pcxhr_mgr *mgr,
- enum pcxhr_clock_type clock_type,
- int *sample_rate)
-{
- int rate, calc_rate = 0;
- unsigned int ticks;
- unsigned char mask, reg;
-
- if (clock_type == HR22_CLOCK_TYPE_AES_SYNC) {
-
- mask = (PCXHR_SUER_CLOCK_PRESENT_MASK |
- PCXHR_SUER_DATA_PRESENT_MASK);
- reg = PCXHR_STAT_FREQ_SYNC_MASK;
-
- } else if (clock_type == HR22_CLOCK_TYPE_AES_1 && mgr->board_has_aes1) {
-
- mask = (PCXHR_SUER1_CLOCK_PRESENT_MASK |
- PCXHR_SUER1_DATA_PRESENT_MASK);
- reg = PCXHR_STAT_FREQ_UER1_MASK;
-
- } else {
- snd_printdd("get_external_clock : type %d not supported\n",
- clock_type);
- return -EINVAL; /* other clocks not supported */
- }
-
- if ((PCXHR_INPB(mgr, PCXHR_XLX_CSUER) & mask) != mask) {
- snd_printdd("get_external_clock(%d) = 0 Hz\n", clock_type);
- *sample_rate = 0;
- return 0; /* no external clock locked */
- }
-
- PCXHR_OUTPB(mgr, PCXHR_XLX_STATUS, reg); /* calculate freq */
-
- /* save the measured clock frequency */
- reg |= PCXHR_STAT_FREQ_SAVE_MASK;
-
- if (mgr->last_reg_stat != reg) {
- udelay(500); /* wait min 2 cycles of lowest freq (8000) */
- mgr->last_reg_stat = reg;
- }
-
- PCXHR_OUTPB(mgr, PCXHR_XLX_STATUS, reg); /* save */
-
- /* get the frequency */
- ticks = (unsigned int)PCXHR_INPB(mgr, PCXHR_XLX_CFG);
- ticks = (ticks & 0x03) << 8;
- ticks |= (unsigned int)PCXHR_INPB(mgr, PCXHR_DSP_RESET);
-
- if (ticks != 0)
- calc_rate = 28224000 / ticks;
- /* rounding */
- if (calc_rate > 184200)
- rate = 192000;
- else if (calc_rate > 152200)
- rate = 176400;
- else if (calc_rate > 112000)
- rate = 128000;
- else if (calc_rate > 92100)
- rate = 96000;
- else if (calc_rate > 76100)
- rate = 88200;
- else if (calc_rate > 56000)
- rate = 64000;
- else if (calc_rate > 46050)
- rate = 48000;
- else if (calc_rate > 38050)
- rate = 44100;
- else if (calc_rate > 28000)
- rate = 32000;
- else if (calc_rate > 23025)
- rate = 24000;
- else if (calc_rate > 19025)
- rate = 22050;
- else if (calc_rate > 14000)
- rate = 16000;
- else if (calc_rate > 11512)
- rate = 12000;
- else if (calc_rate > 9512)
- rate = 11025;
- else if (calc_rate > 7000)
- rate = 8000;
- else
- rate = 0;
-
- snd_printdd("External clock is at %d Hz (measured %d Hz)\n",
- rate, calc_rate);
- *sample_rate = rate;
- return 0;
-}
-
-
-int hr222_read_gpio(struct pcxhr_mgr *mgr, int is_gpi, int *value)
-{
- if (is_gpi) {
- unsigned char reg = PCXHR_INPB(mgr, PCXHR_XLX_STATUS);
- *value = (int)(reg & PCXHR_STAT_GPI_MASK) >>
- PCXHR_STAT_GPI_OFFSET;
- } else {
- *value = (int)(mgr->dsp_reset & PCXHR_DSP_RESET_GPO_MASK) >>
- PCXHR_DSP_RESET_GPO_OFFSET;
- }
- return 0;
-}
-
-
-int hr222_write_gpo(struct pcxhr_mgr *mgr, int value)
-{
- unsigned char reg = mgr->dsp_reset & ~PCXHR_DSP_RESET_GPO_MASK;
-
- reg |= (unsigned char)(value << PCXHR_DSP_RESET_GPO_OFFSET) &
- PCXHR_DSP_RESET_GPO_MASK;
-
- PCXHR_OUTPB(mgr, PCXHR_DSP_RESET, reg);
- mgr->dsp_reset = reg;
- return 0;
-}
-
-
-int hr222_update_analog_audio_level(struct snd_pcxhr *chip,
- int is_capture, int channel)
-{
- snd_printdd("hr222_update_analog_audio_level(%s chan=%d)\n",
- is_capture ? "capture" : "playback", channel);
- if (is_capture) {
- int level_l, level_r, level_mic;
- /* we have to update all levels */
- if (chip->analog_capture_active) {
- level_l = chip->analog_capture_volume[0];
- level_r = chip->analog_capture_volume[1];
- } else {
- level_l = HR222_LINE_CAPTURE_LEVEL_MIN;
- level_r = HR222_LINE_CAPTURE_LEVEL_MIN;
- }
- if (chip->mic_active)
- level_mic = chip->mic_volume;
- else
- level_mic = HR222_MICRO_CAPTURE_LEVEL_MIN;
- return hr222_set_hw_capture_level(chip->mgr,
- level_l, level_r, level_mic);
- } else {
- int vol;
- if (chip->analog_playback_active[channel])
- vol = chip->analog_playback_volume[channel];
- else
- vol = HR222_LINE_PLAYBACK_LEVEL_MIN;
- return hr222_set_hw_playback_level(chip->mgr, channel, vol);
- }
-}
-
-
-/*texts[5] = {"Line", "Digital", "Digi+SRC", "Mic", "Line+Mic"}*/
-#define SOURCE_LINE 0
-#define SOURCE_DIGITAL 1
-#define SOURCE_DIGISRC 2
-#define SOURCE_MIC 3
-#define SOURCE_LINEMIC 4
-
-int hr222_set_audio_source(struct snd_pcxhr *chip)
-{
- int digital = 0;
- /* default analog source */
- chip->mgr->xlx_cfg &= ~(PCXHR_CFG_SRC_MASK |
- PCXHR_CFG_DATAIN_SEL_MASK |
- PCXHR_CFG_DATA_UER1_SEL_MASK);
-
- if (chip->audio_capture_source == SOURCE_DIGISRC) {
- chip->mgr->xlx_cfg |= PCXHR_CFG_SRC_MASK;
- digital = 1;
- } else {
- if (chip->audio_capture_source == SOURCE_DIGITAL)
- digital = 1;
- }
- if (digital) {
- chip->mgr->xlx_cfg |= PCXHR_CFG_DATAIN_SEL_MASK;
- if (chip->mgr->board_has_aes1) {
- /* get data from the AES1 plug */
- chip->mgr->xlx_cfg |= PCXHR_CFG_DATA_UER1_SEL_MASK;
- }
- /* chip->mic_active = 0; */
- /* chip->analog_capture_active = 0; */
- } else {
- int update_lvl = 0;
- chip->analog_capture_active = 0;
- chip->mic_active = 0;
- if (chip->audio_capture_source == SOURCE_LINE ||
- chip->audio_capture_source == SOURCE_LINEMIC) {
- if (chip->analog_capture_active == 0)
- update_lvl = 1;
- chip->analog_capture_active = 1;
- }
- if (chip->audio_capture_source == SOURCE_MIC ||
- chip->audio_capture_source == SOURCE_LINEMIC) {
- if (chip->mic_active == 0)
- update_lvl = 1;
- chip->mic_active = 1;
- }
- if (update_lvl) {
- /* capture: update all 3 mutes/unmutes with one call */
- hr222_update_analog_audio_level(chip, 1, 0);
- }
- }
- /* set the source infos (max 3 bits modified) */
- PCXHR_OUTPB(chip->mgr, PCXHR_XLX_CFG, chip->mgr->xlx_cfg);
- return 0;
-}
-
-
-int hr222_iec958_capture_byte(struct snd_pcxhr *chip,
- int aes_idx, unsigned char *aes_bits)
-{
- unsigned char idx = (unsigned char)(aes_idx * 8);
- unsigned char temp = 0;
- unsigned char mask = chip->mgr->board_has_aes1 ?
- PCXHR_SUER1_BIT_C_READ_MASK : PCXHR_SUER_BIT_C_READ_MASK;
- int i;
- for (i = 0; i < 8; i++) {
- PCXHR_OUTPB(chip->mgr, PCXHR_XLX_RUER, idx++); /* idx < 192 */
- temp <<= 1;
- if (PCXHR_INPB(chip->mgr, PCXHR_XLX_CSUER) & mask)
- temp |= 1;
- }
- snd_printdd("read iec958 AES %d byte %d = 0x%x\n",
- chip->chip_idx, aes_idx, temp);
- *aes_bits = temp;
- return 0;
-}
-
-
-int hr222_iec958_update_byte(struct snd_pcxhr *chip,
- int aes_idx, unsigned char aes_bits)
-{
- int i;
- unsigned char new_bits = aes_bits;
- unsigned char old_bits = chip->aes_bits[aes_idx];
- unsigned char idx = (unsigned char)(aes_idx * 8);
- for (i = 0; i < 8; i++) {
- if ((old_bits & 0x01) != (new_bits & 0x01)) {
- /* idx < 192 */
- PCXHR_OUTPB(chip->mgr, PCXHR_XLX_RUER, idx);
- /* write C and U bit */
- PCXHR_OUTPB(chip->mgr, PCXHR_XLX_CSUER, new_bits&0x01 ?
- PCXHR_SUER_BIT_C_WRITE_MASK : 0);
- }
- idx++;
- old_bits >>= 1;
- new_bits >>= 1;
- }
- chip->aes_bits[aes_idx] = aes_bits;
- return 0;
-}
-
-static void hr222_micro_boost(struct pcxhr_mgr *mgr, int level)
-{
- unsigned char boost_mask;
- boost_mask = (unsigned char) (level << PCXHR_SELMIC_PREAMPLI_OFFSET);
- if (boost_mask & (~PCXHR_SELMIC_PREAMPLI_MASK))
- return; /* only values form 0 to 3 accepted */
-
- mgr->xlx_selmic &= ~PCXHR_SELMIC_PREAMPLI_MASK;
- mgr->xlx_selmic |= boost_mask;
-
- PCXHR_OUTPB(mgr, PCXHR_XLX_SELMIC, mgr->xlx_selmic);
-
- snd_printdd("hr222_micro_boost : set %x\n", boost_mask);
-}
-
-static void hr222_phantom_power(struct pcxhr_mgr *mgr, int power)
-{
- if (power)
- mgr->xlx_selmic |= PCXHR_SELMIC_PHANTOM_ALIM;
- else
- mgr->xlx_selmic &= ~PCXHR_SELMIC_PHANTOM_ALIM;
-
- PCXHR_OUTPB(mgr, PCXHR_XLX_SELMIC, mgr->xlx_selmic);
-
- snd_printdd("hr222_phantom_power : set %d\n", power);
-}
-
-
-/* mic level */
-static const DECLARE_TLV_DB_SCALE(db_scale_mic_hr222, -9850, 50, 650);
-
-static int hr222_mic_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = HR222_MICRO_CAPTURE_LEVEL_MIN; /* -98 dB */
- /* gains from 9 dB to 31.5 dB not recommended; use micboost instead */
- uinfo->value.integer.max = HR222_MICRO_CAPTURE_LEVEL_MAX; /* +7 dB */
- return 0;
-}
-
-static int hr222_mic_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mgr->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->mic_volume;
- mutex_unlock(&chip->mgr->mixer_mutex);
- return 0;
-}
-
-static int hr222_mic_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- mutex_lock(&chip->mgr->mixer_mutex);
- if (chip->mic_volume != ucontrol->value.integer.value[0]) {
- changed = 1;
- chip->mic_volume = ucontrol->value.integer.value[0];
- hr222_update_analog_audio_level(chip, 1, 0);
- }
- mutex_unlock(&chip->mgr->mixer_mutex);
- return changed;
-}
-
-static struct snd_kcontrol_new hr222_control_mic_level = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Mic Capture Volume",
- .info = hr222_mic_vol_info,
- .get = hr222_mic_vol_get,
- .put = hr222_mic_vol_put,
- .tlv = { .p = db_scale_mic_hr222 },
-};
-
-
-/* mic boost level */
-static const DECLARE_TLV_DB_SCALE(db_scale_micboost_hr222, 0, 1800, 5400);
-
-static int hr222_mic_boost_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0; /* 0 dB */
- uinfo->value.integer.max = 3; /* 54 dB */
- return 0;
-}
-
-static int hr222_mic_boost_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mgr->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->mic_boost;
- mutex_unlock(&chip->mgr->mixer_mutex);
- return 0;
-}
-
-static int hr222_mic_boost_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- mutex_lock(&chip->mgr->mixer_mutex);
- if (chip->mic_boost != ucontrol->value.integer.value[0]) {
- changed = 1;
- chip->mic_boost = ucontrol->value.integer.value[0];
- hr222_micro_boost(chip->mgr, chip->mic_boost);
- }
- mutex_unlock(&chip->mgr->mixer_mutex);
- return changed;
-}
-
-static struct snd_kcontrol_new hr222_control_mic_boost = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "MicBoost Capture Volume",
- .info = hr222_mic_boost_info,
- .get = hr222_mic_boost_get,
- .put = hr222_mic_boost_put,
- .tlv = { .p = db_scale_micboost_hr222 },
-};
-
-
-/******************* Phantom power switch *******************/
-#define hr222_phantom_power_info snd_ctl_boolean_mono_info
-
-static int hr222_phantom_power_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mgr->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->phantom_power;
- mutex_unlock(&chip->mgr->mixer_mutex);
- return 0;
-}
-
-static int hr222_phantom_power_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- int power, changed = 0;
-
- mutex_lock(&chip->mgr->mixer_mutex);
- power = !!ucontrol->value.integer.value[0];
- if (chip->phantom_power != power) {
- hr222_phantom_power(chip->mgr, power);
- chip->phantom_power = power;
- changed = 1;
- }
- mutex_unlock(&chip->mgr->mixer_mutex);
- return changed;
-}
-
-static struct snd_kcontrol_new hr222_phantom_power_switch = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Phantom Power Switch",
- .info = hr222_phantom_power_info,
- .get = hr222_phantom_power_get,
- .put = hr222_phantom_power_put,
-};
-
-
-int hr222_add_mic_controls(struct snd_pcxhr *chip)
-{
- int err;
- if (!chip->mgr->board_has_mic)
- return 0;
-
- /* controls */
- err = snd_ctl_add(chip->card, snd_ctl_new1(&hr222_control_mic_level,
- chip));
- if (err < 0)
- return err;
-
- err = snd_ctl_add(chip->card, snd_ctl_new1(&hr222_control_mic_boost,
- chip));
- if (err < 0)
- return err;
-
- err = snd_ctl_add(chip->card, snd_ctl_new1(&hr222_phantom_power_switch,
- chip));
- return err;
-}
diff --git a/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_mix22.h b/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_mix22.h
deleted file mode 100644
index 5a37a000..00000000
--- a/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_mix22.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Driver for Digigram pcxhr compatible soundcards
- *
- * low level interface with interrupt ans message handling
- *
- * Copyright (c) 2004 by Digigram <alsa@digigram.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __SOUND_PCXHR_MIX22_H
-#define __SOUND_PCXHR_MIX22_H
-
-struct pcxhr_mgr;
-
-int hr222_sub_init(struct pcxhr_mgr *mgr);
-int hr222_sub_set_clock(struct pcxhr_mgr *mgr, unsigned int rate,
- int *changed);
-int hr222_get_external_clock(struct pcxhr_mgr *mgr,
- enum pcxhr_clock_type clock_type,
- int *sample_rate);
-
-int hr222_read_gpio(struct pcxhr_mgr *mgr, int is_gpi, int *value);
-int hr222_write_gpo(struct pcxhr_mgr *mgr, int value);
-
-#define HR222_LINE_PLAYBACK_LEVEL_MIN 0 /* -25.5 dB */
-#define HR222_LINE_PLAYBACK_ZERO_LEVEL 51 /* 0.0 dB */
-#define HR222_LINE_PLAYBACK_LEVEL_MAX 99 /* +24.0 dB */
-
-#define HR222_LINE_CAPTURE_LEVEL_MIN 0 /* -111.5 dB */
-#define HR222_LINE_CAPTURE_ZERO_LEVEL 223 /* 0.0 dB */
-#define HR222_LINE_CAPTURE_LEVEL_MAX 255 /* +16 dB */
-#define HR222_MICRO_CAPTURE_LEVEL_MIN 0 /* -98.5 dB */
-#define HR222_MICRO_CAPTURE_LEVEL_MAX 210 /* +6.5 dB */
-
-int hr222_update_analog_audio_level(struct snd_pcxhr *chip,
- int is_capture,
- int channel);
-int hr222_set_audio_source(struct snd_pcxhr *chip);
-int hr222_iec958_capture_byte(struct snd_pcxhr *chip, int aes_idx,
- unsigned char *aes_bits);
-int hr222_iec958_update_byte(struct snd_pcxhr *chip, int aes_idx,
- unsigned char aes_bits);
-
-int hr222_add_mic_controls(struct snd_pcxhr *chip);
-
-#endif /* __SOUND_PCXHR_MIX22_H */
diff --git a/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_mixer.c b/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_mixer.c
deleted file mode 100644
index fec04934..00000000
--- a/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_mixer.c
+++ /dev/null
@@ -1,1270 +0,0 @@
-#define __NO_VERSION__
-/*
- * Driver for Digigram pcxhr compatible soundcards
- *
- * mixer callbacks
- *
- * Copyright (c) 2004 by Digigram <alsa@digigram.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/time.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/mutex.h>
-#include <sound/core.h>
-#include "pcxhr.h"
-#include "pcxhr_hwdep.h"
-#include "pcxhr_core.h"
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/asoundef.h>
-#include "pcxhr_mixer.h"
-#include "pcxhr_mix22.h"
-
-#define PCXHR_LINE_CAPTURE_LEVEL_MIN 0 /* -112.0 dB */
-#define PCXHR_LINE_CAPTURE_LEVEL_MAX 255 /* +15.5 dB */
-#define PCXHR_LINE_CAPTURE_ZERO_LEVEL 224 /* 0.0 dB ( 0 dBu -> 0 dBFS ) */
-
-#define PCXHR_LINE_PLAYBACK_LEVEL_MIN 0 /* -104.0 dB */
-#define PCXHR_LINE_PLAYBACK_LEVEL_MAX 128 /* +24.0 dB */
-#define PCXHR_LINE_PLAYBACK_ZERO_LEVEL 104 /* 0.0 dB ( 0 dBFS -> 0 dBu ) */
-
-static const DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -11200, 50, 1550);
-static const DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -10400, 100, 2400);
-
-static const DECLARE_TLV_DB_SCALE(db_scale_a_hr222_capture, -11150, 50, 1600);
-static const DECLARE_TLV_DB_SCALE(db_scale_a_hr222_playback, -2550, 50, 2400);
-
-static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip,
- int is_capture, int channel)
-{
- int err, vol;
- struct pcxhr_rmh rmh;
-
- pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
- if (is_capture) {
- rmh.cmd[0] |= IO_NUM_REG_IN_ANA_LEVEL;
- rmh.cmd[2] = chip->analog_capture_volume[channel];
- } else {
- rmh.cmd[0] |= IO_NUM_REG_OUT_ANA_LEVEL;
- if (chip->analog_playback_active[channel])
- vol = chip->analog_playback_volume[channel];
- else
- vol = PCXHR_LINE_PLAYBACK_LEVEL_MIN;
- /* playback analog levels are inversed */
- rmh.cmd[2] = PCXHR_LINE_PLAYBACK_LEVEL_MAX - vol;
- }
- rmh.cmd[1] = 1 << ((2 * chip->chip_idx) + channel); /* audio mask */
- rmh.cmd_len = 3;
- err = pcxhr_send_msg(chip->mgr, &rmh);
- if (err < 0) {
- snd_printk(KERN_DEBUG "error update_analog_audio_level card(%d)"
- " is_capture(%d) err(%x)\n",
- chip->chip_idx, is_capture, err);
- return -EINVAL;
- }
- return 0;
-}
-
-/*
- * analog level control
- */
-static int pcxhr_analog_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- if (kcontrol->private_value == 0) { /* playback */
- if (chip->mgr->is_hr_stereo) {
- uinfo->value.integer.min =
- HR222_LINE_PLAYBACK_LEVEL_MIN; /* -25 dB */
- uinfo->value.integer.max =
- HR222_LINE_PLAYBACK_LEVEL_MAX; /* +24 dB */
- } else {
- uinfo->value.integer.min =
- PCXHR_LINE_PLAYBACK_LEVEL_MIN; /*-104 dB */
- uinfo->value.integer.max =
- PCXHR_LINE_PLAYBACK_LEVEL_MAX; /* +24 dB */
- }
- } else { /* capture */
- if (chip->mgr->is_hr_stereo) {
- uinfo->value.integer.min =
- HR222_LINE_CAPTURE_LEVEL_MIN; /*-112 dB */
- uinfo->value.integer.max =
- HR222_LINE_CAPTURE_LEVEL_MAX; /* +15.5 dB */
- } else {
- uinfo->value.integer.min =
- PCXHR_LINE_CAPTURE_LEVEL_MIN; /*-112 dB */
- uinfo->value.integer.max =
- PCXHR_LINE_CAPTURE_LEVEL_MAX; /* +15.5 dB */
- }
- }
- return 0;
-}
-
-static int pcxhr_analog_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mgr->mixer_mutex);
- if (kcontrol->private_value == 0) { /* playback */
- ucontrol->value.integer.value[0] = chip->analog_playback_volume[0];
- ucontrol->value.integer.value[1] = chip->analog_playback_volume[1];
- } else { /* capture */
- ucontrol->value.integer.value[0] = chip->analog_capture_volume[0];
- ucontrol->value.integer.value[1] = chip->analog_capture_volume[1];
- }
- mutex_unlock(&chip->mgr->mixer_mutex);
- return 0;
-}
-
-static int pcxhr_analog_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- int is_capture, i;
-
- mutex_lock(&chip->mgr->mixer_mutex);
- is_capture = (kcontrol->private_value != 0);
- for (i = 0; i < 2; i++) {
- int new_volume = ucontrol->value.integer.value[i];
- int *stored_volume = is_capture ?
- &chip->analog_capture_volume[i] :
- &chip->analog_playback_volume[i];
- if (is_capture) {
- if (chip->mgr->is_hr_stereo) {
- if (new_volume < HR222_LINE_CAPTURE_LEVEL_MIN ||
- new_volume > HR222_LINE_CAPTURE_LEVEL_MAX)
- continue;
- } else {
- if (new_volume < PCXHR_LINE_CAPTURE_LEVEL_MIN ||
- new_volume > PCXHR_LINE_CAPTURE_LEVEL_MAX)
- continue;
- }
- } else {
- if (chip->mgr->is_hr_stereo) {
- if (new_volume < HR222_LINE_PLAYBACK_LEVEL_MIN ||
- new_volume > HR222_LINE_PLAYBACK_LEVEL_MAX)
- continue;
- } else {
- if (new_volume < PCXHR_LINE_PLAYBACK_LEVEL_MIN ||
- new_volume > PCXHR_LINE_PLAYBACK_LEVEL_MAX)
- continue;
- }
- }
- if (*stored_volume != new_volume) {
- *stored_volume = new_volume;
- changed = 1;
- if (chip->mgr->is_hr_stereo)
- hr222_update_analog_audio_level(chip,
- is_capture, i);
- else
- pcxhr_update_analog_audio_level(chip,
- is_capture, i);
- }
- }
- mutex_unlock(&chip->mgr->mixer_mutex);
- return changed;
-}
-
-static struct snd_kcontrol_new pcxhr_control_analog_level = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- /* name will be filled later */
- .info = pcxhr_analog_vol_info,
- .get = pcxhr_analog_vol_get,
- .put = pcxhr_analog_vol_put,
- /* tlv will be filled later */
-};
-
-/* shared */
-
-#define pcxhr_sw_info snd_ctl_boolean_stereo_info
-
-static int pcxhr_audio_sw_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
-
- mutex_lock(&chip->mgr->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->analog_playback_active[0];
- ucontrol->value.integer.value[1] = chip->analog_playback_active[1];
- mutex_unlock(&chip->mgr->mixer_mutex);
- return 0;
-}
-
-static int pcxhr_audio_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- int i, changed = 0;
- mutex_lock(&chip->mgr->mixer_mutex);
- for(i = 0; i < 2; i++) {
- if (chip->analog_playback_active[i] !=
- ucontrol->value.integer.value[i]) {
- chip->analog_playback_active[i] =
- !!ucontrol->value.integer.value[i];
- changed = 1;
- /* update playback levels */
- if (chip->mgr->is_hr_stereo)
- hr222_update_analog_audio_level(chip, 0, i);
- else
- pcxhr_update_analog_audio_level(chip, 0, i);
- }
- }
- mutex_unlock(&chip->mgr->mixer_mutex);
- return changed;
-}
-
-static struct snd_kcontrol_new pcxhr_control_output_switch = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = pcxhr_sw_info, /* shared */
- .get = pcxhr_audio_sw_get,
- .put = pcxhr_audio_sw_put
-};
-
-
-#define PCXHR_DIGITAL_LEVEL_MIN 0x000 /* -110 dB */
-#define PCXHR_DIGITAL_LEVEL_MAX 0x1ff /* +18 dB */
-#define PCXHR_DIGITAL_ZERO_LEVEL 0x1b7 /* 0 dB */
-
-static const DECLARE_TLV_DB_SCALE(db_scale_digital, -10975, 25, 1800);
-
-#define MORE_THAN_ONE_STREAM_LEVEL 0x000001
-#define VALID_STREAM_PAN_LEVEL_MASK 0x800000
-#define VALID_STREAM_LEVEL_MASK 0x400000
-#define VALID_STREAM_LEVEL_1_MASK 0x200000
-#define VALID_STREAM_LEVEL_2_MASK 0x100000
-
-static int pcxhr_update_playback_stream_level(struct snd_pcxhr* chip, int idx)
-{
- int err;
- struct pcxhr_rmh rmh;
- struct pcxhr_pipe *pipe = &chip->playback_pipe;
- int left, right;
-
- if (chip->digital_playback_active[idx][0])
- left = chip->digital_playback_volume[idx][0];
- else
- left = PCXHR_DIGITAL_LEVEL_MIN;
- if (chip->digital_playback_active[idx][1])
- right = chip->digital_playback_volume[idx][1];
- else
- right = PCXHR_DIGITAL_LEVEL_MIN;
-
- pcxhr_init_rmh(&rmh, CMD_STREAM_OUT_LEVEL_ADJUST);
- /* add pipe and stream mask */
- pcxhr_set_pipe_cmd_params(&rmh, 0, pipe->first_audio, 0, 1<<idx);
- /* volume left->left / right->right panoramic level */
- rmh.cmd[0] |= MORE_THAN_ONE_STREAM_LEVEL;
- rmh.cmd[2] = VALID_STREAM_PAN_LEVEL_MASK | VALID_STREAM_LEVEL_1_MASK;
- rmh.cmd[2] |= (left << 10);
- rmh.cmd[3] = VALID_STREAM_PAN_LEVEL_MASK | VALID_STREAM_LEVEL_2_MASK;
- rmh.cmd[3] |= right;
- rmh.cmd_len = 4;
-
- err = pcxhr_send_msg(chip->mgr, &rmh);
- if (err < 0) {
- snd_printk(KERN_DEBUG "error update_playback_stream_level "
- "card(%d) err(%x)\n", chip->chip_idx, err);
- return -EINVAL;
- }
- return 0;
-}
-
-#define AUDIO_IO_HAS_MUTE_LEVEL 0x400000
-#define AUDIO_IO_HAS_MUTE_MONITOR_1 0x200000
-#define VALID_AUDIO_IO_DIGITAL_LEVEL 0x000001
-#define VALID_AUDIO_IO_MONITOR_LEVEL 0x000002
-#define VALID_AUDIO_IO_MUTE_LEVEL 0x000004
-#define VALID_AUDIO_IO_MUTE_MONITOR_1 0x000008
-
-static int pcxhr_update_audio_pipe_level(struct snd_pcxhr *chip,
- int capture, int channel)
-{
- int err;
- struct pcxhr_rmh rmh;
- struct pcxhr_pipe *pipe;
-
- if (capture)
- pipe = &chip->capture_pipe[0];
- else
- pipe = &chip->playback_pipe;
-
- pcxhr_init_rmh(&rmh, CMD_AUDIO_LEVEL_ADJUST);
- /* add channel mask */
- pcxhr_set_pipe_cmd_params(&rmh, capture, 0, 0,
- 1 << (channel + pipe->first_audio));
- /* TODO : if mask (3 << pipe->first_audio) is used, left and right
- * channel will be programmed to the same params */
- if (capture) {
- rmh.cmd[0] |= VALID_AUDIO_IO_DIGITAL_LEVEL;
- /* VALID_AUDIO_IO_MUTE_LEVEL not yet handled
- * (capture pipe level) */
- rmh.cmd[2] = chip->digital_capture_volume[channel];
- } else {
- rmh.cmd[0] |= VALID_AUDIO_IO_MONITOR_LEVEL |
- VALID_AUDIO_IO_MUTE_MONITOR_1;
- /* VALID_AUDIO_IO_DIGITAL_LEVEL and VALID_AUDIO_IO_MUTE_LEVEL
- * not yet handled (playback pipe level)
- */
- rmh.cmd[2] = chip->monitoring_volume[channel] << 10;
- if (chip->monitoring_active[channel] == 0)
- rmh.cmd[2] |= AUDIO_IO_HAS_MUTE_MONITOR_1;
- }
- rmh.cmd_len = 3;
-
- err = pcxhr_send_msg(chip->mgr, &rmh);
- if (err < 0) {
- snd_printk(KERN_DEBUG "error update_audio_level(%d) err=%x\n",
- chip->chip_idx, err);
- return -EINVAL;
- }
- return 0;
-}
-
-
-/* shared */
-static int pcxhr_digital_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = PCXHR_DIGITAL_LEVEL_MIN; /* -109.5 dB */
- uinfo->value.integer.max = PCXHR_DIGITAL_LEVEL_MAX; /* 18.0 dB */
- return 0;
-}
-
-
-static int pcxhr_pcm_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
- int *stored_volume;
- int is_capture = kcontrol->private_value;
-
- mutex_lock(&chip->mgr->mixer_mutex);
- if (is_capture) /* digital capture */
- stored_volume = chip->digital_capture_volume;
- else /* digital playback */
- stored_volume = chip->digital_playback_volume[idx];
- ucontrol->value.integer.value[0] = stored_volume[0];
- ucontrol->value.integer.value[1] = stored_volume[1];
- mutex_unlock(&chip->mgr->mixer_mutex);
- return 0;
-}
-
-static int pcxhr_pcm_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
- int changed = 0;
- int is_capture = kcontrol->private_value;
- int *stored_volume;
- int i;
-
- mutex_lock(&chip->mgr->mixer_mutex);
- if (is_capture) /* digital capture */
- stored_volume = chip->digital_capture_volume;
- else /* digital playback */
- stored_volume = chip->digital_playback_volume[idx];
- for (i = 0; i < 2; i++) {
- int vol = ucontrol->value.integer.value[i];
- if (vol < PCXHR_DIGITAL_LEVEL_MIN ||
- vol > PCXHR_DIGITAL_LEVEL_MAX)
- continue;
- if (stored_volume[i] != vol) {
- stored_volume[i] = vol;
- changed = 1;
- if (is_capture) /* update capture volume */
- pcxhr_update_audio_pipe_level(chip, 1, i);
- }
- }
- if (!is_capture && changed) /* update playback volume */
- pcxhr_update_playback_stream_level(chip, idx);
- mutex_unlock(&chip->mgr->mixer_mutex);
- return changed;
-}
-
-static struct snd_kcontrol_new snd_pcxhr_pcm_vol =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- /* name will be filled later */
- /* count will be filled later */
- .info = pcxhr_digital_vol_info, /* shared */
- .get = pcxhr_pcm_vol_get,
- .put = pcxhr_pcm_vol_put,
- .tlv = { .p = db_scale_digital },
-};
-
-
-static int pcxhr_pcm_sw_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
-
- mutex_lock(&chip->mgr->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->digital_playback_active[idx][0];
- ucontrol->value.integer.value[1] = chip->digital_playback_active[idx][1];
- mutex_unlock(&chip->mgr->mixer_mutex);
- return 0;
-}
-
-static int pcxhr_pcm_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
- int i, j;
-
- mutex_lock(&chip->mgr->mixer_mutex);
- j = idx;
- for (i = 0; i < 2; i++) {
- if (chip->digital_playback_active[j][i] !=
- ucontrol->value.integer.value[i]) {
- chip->digital_playback_active[j][i] =
- !!ucontrol->value.integer.value[i];
- changed = 1;
- }
- }
- if (changed)
- pcxhr_update_playback_stream_level(chip, idx);
- mutex_unlock(&chip->mgr->mixer_mutex);
- return changed;
-}
-
-static struct snd_kcontrol_new pcxhr_control_pcm_switch = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Playback Switch",
- .count = PCXHR_PLAYBACK_STREAMS,
- .info = pcxhr_sw_info, /* shared */
- .get = pcxhr_pcm_sw_get,
- .put = pcxhr_pcm_sw_put
-};
-
-
-/*
- * monitoring level control
- */
-
-static int pcxhr_monitor_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mgr->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->monitoring_volume[0];
- ucontrol->value.integer.value[1] = chip->monitoring_volume[1];
- mutex_unlock(&chip->mgr->mixer_mutex);
- return 0;
-}
-
-static int pcxhr_monitor_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- int i;
-
- mutex_lock(&chip->mgr->mixer_mutex);
- for (i = 0; i < 2; i++) {
- if (chip->monitoring_volume[i] !=
- ucontrol->value.integer.value[i]) {
- chip->monitoring_volume[i] =
- ucontrol->value.integer.value[i];
- if (chip->monitoring_active[i])
- /* update monitoring volume and mute */
- /* do only when monitoring is unmuted */
- pcxhr_update_audio_pipe_level(chip, 0, i);
- changed = 1;
- }
- }
- mutex_unlock(&chip->mgr->mixer_mutex);
- return changed;
-}
-
-static struct snd_kcontrol_new pcxhr_control_monitor_vol = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Monitoring Playback Volume",
- .info = pcxhr_digital_vol_info, /* shared */
- .get = pcxhr_monitor_vol_get,
- .put = pcxhr_monitor_vol_put,
- .tlv = { .p = db_scale_digital },
-};
-
-/*
- * monitoring switch control
- */
-
-static int pcxhr_monitor_sw_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- mutex_lock(&chip->mgr->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->monitoring_active[0];
- ucontrol->value.integer.value[1] = chip->monitoring_active[1];
- mutex_unlock(&chip->mgr->mixer_mutex);
- return 0;
-}
-
-static int pcxhr_monitor_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- int i;
-
- mutex_lock(&chip->mgr->mixer_mutex);
- for (i = 0; i < 2; i++) {
- if (chip->monitoring_active[i] !=
- ucontrol->value.integer.value[i]) {
- chip->monitoring_active[i] =
- !!ucontrol->value.integer.value[i];
- changed |= (1<<i); /* mask 0x01 and 0x02 */
- }
- }
- if (changed & 0x01)
- /* update left monitoring volume and mute */
- pcxhr_update_audio_pipe_level(chip, 0, 0);
- if (changed & 0x02)
- /* update right monitoring volume and mute */
- pcxhr_update_audio_pipe_level(chip, 0, 1);
-
- mutex_unlock(&chip->mgr->mixer_mutex);
- return (changed != 0);
-}
-
-static struct snd_kcontrol_new pcxhr_control_monitor_sw = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Monitoring Playback Switch",
- .info = pcxhr_sw_info, /* shared */
- .get = pcxhr_monitor_sw_get,
- .put = pcxhr_monitor_sw_put
-};
-
-
-
-/*
- * audio source select
- */
-#define PCXHR_SOURCE_AUDIO01_UER 0x000100
-#define PCXHR_SOURCE_AUDIO01_SYNC 0x000200
-#define PCXHR_SOURCE_AUDIO23_UER 0x000400
-#define PCXHR_SOURCE_AUDIO45_UER 0x001000
-#define PCXHR_SOURCE_AUDIO67_UER 0x040000
-
-static int pcxhr_set_audio_source(struct snd_pcxhr* chip)
-{
- struct pcxhr_rmh rmh;
- unsigned int mask, reg;
- unsigned int codec;
- int err, changed;
-
- switch (chip->chip_idx) {
- case 0 : mask = PCXHR_SOURCE_AUDIO01_UER; codec = CS8420_01_CS; break;
- case 1 : mask = PCXHR_SOURCE_AUDIO23_UER; codec = CS8420_23_CS; break;
- case 2 : mask = PCXHR_SOURCE_AUDIO45_UER; codec = CS8420_45_CS; break;
- case 3 : mask = PCXHR_SOURCE_AUDIO67_UER; codec = CS8420_67_CS; break;
- default: return -EINVAL;
- }
- if (chip->audio_capture_source != 0) {
- reg = mask; /* audio source from digital plug */
- } else {
- reg = 0; /* audio source from analog plug */
- }
- /* set the input source */
- pcxhr_write_io_num_reg_cont(chip->mgr, mask, reg, &changed);
- /* resync them (otherwise channel inversion possible) */
- if (changed) {
- pcxhr_init_rmh(&rmh, CMD_RESYNC_AUDIO_INPUTS);
- rmh.cmd[0] |= (1 << chip->chip_idx);
- err = pcxhr_send_msg(chip->mgr, &rmh);
- if (err)
- return err;
- }
- if (chip->mgr->board_aes_in_192k) {
- int i;
- unsigned int src_config = 0xC0;
- /* update all src configs with one call */
- for (i = 0; (i < 4) && (i < chip->mgr->capture_chips); i++) {
- if (chip->mgr->chip[i]->audio_capture_source == 2)
- src_config |= (1 << (3 - i));
- }
- /* set codec SRC on off */
- pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
- rmh.cmd_len = 2;
- rmh.cmd[0] |= IO_NUM_REG_CONFIG_SRC;
- rmh.cmd[1] = src_config;
- err = pcxhr_send_msg(chip->mgr, &rmh);
- } else {
- int use_src = 0;
- if (chip->audio_capture_source == 2)
- use_src = 1;
- /* set codec SRC on off */
- pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
- rmh.cmd_len = 3;
- rmh.cmd[0] |= IO_NUM_UER_CHIP_REG;
- rmh.cmd[1] = codec;
- rmh.cmd[2] = ((CS8420_DATA_FLOW_CTL & CHIP_SIG_AND_MAP_SPI) |
- (use_src ? 0x41 : 0x54));
- err = pcxhr_send_msg(chip->mgr, &rmh);
- if (err)
- return err;
- rmh.cmd[2] = ((CS8420_CLOCK_SRC_CTL & CHIP_SIG_AND_MAP_SPI) |
- (use_src ? 0x41 : 0x49));
- err = pcxhr_send_msg(chip->mgr, &rmh);
- }
- return err;
-}
-
-static int pcxhr_audio_src_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static const char *texts[5] = {
- "Line", "Digital", "Digi+SRC", "Mic", "Line+Mic"
- };
- int i;
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
-
- i = 2; /* no SRC, no Mic available */
- if (chip->mgr->board_has_aes1) {
- i = 3; /* SRC available */
- if (chip->mgr->board_has_mic)
- i = 5; /* Mic and MicroMix available */
- }
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = i;
- if (uinfo->value.enumerated.item > (i-1))
- uinfo->value.enumerated.item = i-1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int pcxhr_audio_src_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = chip->audio_capture_source;
- return 0;
-}
-
-static int pcxhr_audio_src_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- int ret = 0;
- int i = 2; /* no SRC, no Mic available */
- if (chip->mgr->board_has_aes1) {
- i = 3; /* SRC available */
- if (chip->mgr->board_has_mic)
- i = 5; /* Mic and MicroMix available */
- }
- if (ucontrol->value.enumerated.item[0] >= i)
- return -EINVAL;
- mutex_lock(&chip->mgr->mixer_mutex);
- if (chip->audio_capture_source != ucontrol->value.enumerated.item[0]) {
- chip->audio_capture_source = ucontrol->value.enumerated.item[0];
- if (chip->mgr->is_hr_stereo)
- hr222_set_audio_source(chip);
- else
- pcxhr_set_audio_source(chip);
- ret = 1;
- }
- mutex_unlock(&chip->mgr->mixer_mutex);
- return ret;
-}
-
-static struct snd_kcontrol_new pcxhr_control_audio_src = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = pcxhr_audio_src_info,
- .get = pcxhr_audio_src_get,
- .put = pcxhr_audio_src_put,
-};
-
-
-/*
- * clock type selection
- * enum pcxhr_clock_type {
- * PCXHR_CLOCK_TYPE_INTERNAL = 0,
- * PCXHR_CLOCK_TYPE_WORD_CLOCK,
- * PCXHR_CLOCK_TYPE_AES_SYNC,
- * PCXHR_CLOCK_TYPE_AES_1,
- * PCXHR_CLOCK_TYPE_AES_2,
- * PCXHR_CLOCK_TYPE_AES_3,
- * PCXHR_CLOCK_TYPE_AES_4,
- * PCXHR_CLOCK_TYPE_MAX = PCXHR_CLOCK_TYPE_AES_4,
- * HR22_CLOCK_TYPE_INTERNAL = PCXHR_CLOCK_TYPE_INTERNAL,
- * HR22_CLOCK_TYPE_AES_SYNC,
- * HR22_CLOCK_TYPE_AES_1,
- * HR22_CLOCK_TYPE_MAX = HR22_CLOCK_TYPE_AES_1,
- * };
- */
-
-static int pcxhr_clock_type_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static const char *textsPCXHR[7] = {
- "Internal", "WordClock", "AES Sync",
- "AES 1", "AES 2", "AES 3", "AES 4"
- };
- static const char *textsHR22[3] = {
- "Internal", "AES Sync", "AES 1"
- };
- const char **texts;
- struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
- int clock_items = 2; /* at least Internal and AES Sync clock */
- if (mgr->board_has_aes1) {
- clock_items += mgr->capture_chips; /* add AES x */
- if (!mgr->is_hr_stereo)
- clock_items += 1; /* add word clock */
- }
- if (mgr->is_hr_stereo) {
- texts = textsHR22;
- snd_BUG_ON(clock_items > (HR22_CLOCK_TYPE_MAX+1));
- } else {
- texts = textsPCXHR;
- snd_BUG_ON(clock_items > (PCXHR_CLOCK_TYPE_MAX+1));
- }
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = clock_items;
- if (uinfo->value.enumerated.item >= clock_items)
- uinfo->value.enumerated.item = clock_items-1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int pcxhr_clock_type_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = mgr->use_clock_type;
- return 0;
-}
-
-static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
- int rate, ret = 0;
- unsigned int clock_items = 2; /* at least Internal and AES Sync clock */
- if (mgr->board_has_aes1) {
- clock_items += mgr->capture_chips; /* add AES x */
- if (!mgr->is_hr_stereo)
- clock_items += 1; /* add word clock */
- }
- if (ucontrol->value.enumerated.item[0] >= clock_items)
- return -EINVAL;
- mutex_lock(&mgr->mixer_mutex);
- if (mgr->use_clock_type != ucontrol->value.enumerated.item[0]) {
- mutex_lock(&mgr->setup_mutex);
- mgr->use_clock_type = ucontrol->value.enumerated.item[0];
- rate = 0;
- if (mgr->use_clock_type != PCXHR_CLOCK_TYPE_INTERNAL) {
- pcxhr_get_external_clock(mgr, mgr->use_clock_type,
- &rate);
- } else {
- rate = mgr->sample_rate;
- if (!rate)
- rate = 48000;
- }
- if (rate) {
- pcxhr_set_clock(mgr, rate);
- if (mgr->sample_rate)
- mgr->sample_rate = rate;
- }
- mutex_unlock(&mgr->setup_mutex);
- ret = 1; /* return 1 even if the set was not done. ok ? */
- }
- mutex_unlock(&mgr->mixer_mutex);
- return ret;
-}
-
-static struct snd_kcontrol_new pcxhr_control_clock_type = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Clock Mode",
- .info = pcxhr_clock_type_info,
- .get = pcxhr_clock_type_get,
- .put = pcxhr_clock_type_put,
-};
-
-/*
- * clock rate control
- * specific control that scans the sample rates on the external plugs
- */
-static int pcxhr_clock_rate_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 3 + mgr->capture_chips;
- uinfo->value.integer.min = 0; /* clock not present */
- uinfo->value.integer.max = 192000; /* max sample rate 192 kHz */
- return 0;
-}
-
-static int pcxhr_clock_rate_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
- int i, err, rate;
-
- mutex_lock(&mgr->mixer_mutex);
- for(i = 0; i < 3 + mgr->capture_chips; i++) {
- if (i == PCXHR_CLOCK_TYPE_INTERNAL)
- rate = mgr->sample_rate_real;
- else {
- err = pcxhr_get_external_clock(mgr, i, &rate);
- if (err)
- break;
- }
- ucontrol->value.integer.value[i] = rate;
- }
- mutex_unlock(&mgr->mixer_mutex);
- return 0;
-}
-
-static struct snd_kcontrol_new pcxhr_control_clock_rate = {
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_CARD,
- .name = "Clock Rates",
- .info = pcxhr_clock_rate_info,
- .get = pcxhr_clock_rate_get,
-};
-
-/*
- * IEC958 status bits
- */
-static int pcxhr_iec958_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int pcxhr_iec958_capture_byte(struct snd_pcxhr *chip,
- int aes_idx, unsigned char *aes_bits)
-{
- int i, err;
- unsigned char temp;
- struct pcxhr_rmh rmh;
-
- pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
- rmh.cmd[0] |= IO_NUM_UER_CHIP_REG;
- switch (chip->chip_idx) {
- /* instead of CS8420_01_CS use CS8416_01_CS for AES SYNC plug */
- case 0: rmh.cmd[1] = CS8420_01_CS; break;
- case 1: rmh.cmd[1] = CS8420_23_CS; break;
- case 2: rmh.cmd[1] = CS8420_45_CS; break;
- case 3: rmh.cmd[1] = CS8420_67_CS; break;
- default: return -EINVAL;
- }
- if (chip->mgr->board_aes_in_192k) {
- switch (aes_idx) {
- case 0: rmh.cmd[2] = CS8416_CSB0; break;
- case 1: rmh.cmd[2] = CS8416_CSB1; break;
- case 2: rmh.cmd[2] = CS8416_CSB2; break;
- case 3: rmh.cmd[2] = CS8416_CSB3; break;
- case 4: rmh.cmd[2] = CS8416_CSB4; break;
- default: return -EINVAL;
- }
- } else {
- switch (aes_idx) {
- /* instead of CS8420_CSB0 use CS8416_CSBx for AES SYNC plug */
- case 0: rmh.cmd[2] = CS8420_CSB0; break;
- case 1: rmh.cmd[2] = CS8420_CSB1; break;
- case 2: rmh.cmd[2] = CS8420_CSB2; break;
- case 3: rmh.cmd[2] = CS8420_CSB3; break;
- case 4: rmh.cmd[2] = CS8420_CSB4; break;
- default: return -EINVAL;
- }
- }
- /* size and code the chip id for the fpga */
- rmh.cmd[1] &= 0x0fffff;
- /* chip signature + map for spi read */
- rmh.cmd[2] &= CHIP_SIG_AND_MAP_SPI;
- rmh.cmd_len = 3;
- err = pcxhr_send_msg(chip->mgr, &rmh);
- if (err)
- return err;
-
- if (chip->mgr->board_aes_in_192k) {
- temp = (unsigned char)rmh.stat[1];
- } else {
- temp = 0;
- /* reversed bit order (not with CS8416_01_CS) */
- for (i = 0; i < 8; i++) {
- temp <<= 1;
- if (rmh.stat[1] & (1 << i))
- temp |= 1;
- }
- }
- snd_printdd("read iec958 AES %d byte %d = 0x%x\n",
- chip->chip_idx, aes_idx, temp);
- *aes_bits = temp;
- return 0;
-}
-
-static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- unsigned char aes_bits;
- int i, err;
-
- mutex_lock(&chip->mgr->mixer_mutex);
- for(i = 0; i < 5; i++) {
- if (kcontrol->private_value == 0) /* playback */
- aes_bits = chip->aes_bits[i];
- else { /* capture */
- if (chip->mgr->is_hr_stereo)
- err = hr222_iec958_capture_byte(chip, i,
- &aes_bits);
- else
- err = pcxhr_iec958_capture_byte(chip, i,
- &aes_bits);
- if (err)
- break;
- }
- ucontrol->value.iec958.status[i] = aes_bits;
- }
- mutex_unlock(&chip->mgr->mixer_mutex);
- return 0;
-}
-
-static int pcxhr_iec958_mask_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int i;
- for (i = 0; i < 5; i++)
- ucontrol->value.iec958.status[i] = 0xff;
- return 0;
-}
-
-static int pcxhr_iec958_update_byte(struct snd_pcxhr *chip,
- int aes_idx, unsigned char aes_bits)
-{
- int i, err, cmd;
- unsigned char new_bits = aes_bits;
- unsigned char old_bits = chip->aes_bits[aes_idx];
- struct pcxhr_rmh rmh;
-
- for (i = 0; i < 8; i++) {
- if ((old_bits & 0x01) != (new_bits & 0x01)) {
- cmd = chip->chip_idx & 0x03; /* chip index 0..3 */
- if (chip->chip_idx > 3)
- /* new bit used if chip_idx>3 (PCX1222HR) */
- cmd |= 1 << 22;
- cmd |= ((aes_idx << 3) + i) << 2; /* add bit offset */
- cmd |= (new_bits & 0x01) << 23; /* add bit value */
- pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
- rmh.cmd[0] |= IO_NUM_REG_CUER;
- rmh.cmd[1] = cmd;
- rmh.cmd_len = 2;
- snd_printdd("write iec958 AES %d byte %d bit %d (cmd %x)\n",
- chip->chip_idx, aes_idx, i, cmd);
- err = pcxhr_send_msg(chip->mgr, &rmh);
- if (err)
- return err;
- }
- old_bits >>= 1;
- new_bits >>= 1;
- }
- chip->aes_bits[aes_idx] = aes_bits;
- return 0;
-}
-
-static int pcxhr_iec958_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
- int i, changed = 0;
-
- /* playback */
- mutex_lock(&chip->mgr->mixer_mutex);
- for (i = 0; i < 5; i++) {
- if (ucontrol->value.iec958.status[i] != chip->aes_bits[i]) {
- if (chip->mgr->is_hr_stereo)
- hr222_iec958_update_byte(chip, i,
- ucontrol->value.iec958.status[i]);
- else
- pcxhr_iec958_update_byte(chip, i,
- ucontrol->value.iec958.status[i]);
- changed = 1;
- }
- }
- mutex_unlock(&chip->mgr->mixer_mutex);
- return changed;
-}
-
-static struct snd_kcontrol_new pcxhr_control_playback_iec958_mask = {
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
- .info = pcxhr_iec958_info,
- .get = pcxhr_iec958_mask_get
-};
-static struct snd_kcontrol_new pcxhr_control_playback_iec958 = {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
- .info = pcxhr_iec958_info,
- .get = pcxhr_iec958_get,
- .put = pcxhr_iec958_put,
- .private_value = 0 /* playback */
-};
-
-static struct snd_kcontrol_new pcxhr_control_capture_iec958_mask = {
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),
- .info = pcxhr_iec958_info,
- .get = pcxhr_iec958_mask_get
-};
-static struct snd_kcontrol_new pcxhr_control_capture_iec958 = {
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
- .info = pcxhr_iec958_info,
- .get = pcxhr_iec958_get,
- .private_value = 1 /* capture */
-};
-
-static void pcxhr_init_audio_levels(struct snd_pcxhr *chip)
-{
- int i;
-
- for (i = 0; i < 2; i++) {
- if (chip->nb_streams_play) {
- int j;
- /* at boot time the digital volumes are unmuted 0dB */
- for (j = 0; j < PCXHR_PLAYBACK_STREAMS; j++) {
- chip->digital_playback_active[j][i] = 1;
- chip->digital_playback_volume[j][i] =
- PCXHR_DIGITAL_ZERO_LEVEL;
- }
- /* after boot, only two bits are set on the uer
- * interface
- */
- chip->aes_bits[0] = (IEC958_AES0_PROFESSIONAL |
- IEC958_AES0_PRO_FS_48000);
-#ifdef CONFIG_SND_DEBUG
- /* analog volumes for playback
- * (is LEVEL_MIN after boot)
- */
- chip->analog_playback_active[i] = 1;
- if (chip->mgr->is_hr_stereo)
- chip->analog_playback_volume[i] =
- HR222_LINE_PLAYBACK_ZERO_LEVEL;
- else {
- chip->analog_playback_volume[i] =
- PCXHR_LINE_PLAYBACK_ZERO_LEVEL;
- pcxhr_update_analog_audio_level(chip, 0, i);
- }
-#endif
- /* stereo cards need to be initialised after boot */
- if (chip->mgr->is_hr_stereo)
- hr222_update_analog_audio_level(chip, 0, i);
- }
- if (chip->nb_streams_capt) {
- /* at boot time the digital volumes are unmuted 0dB */
- chip->digital_capture_volume[i] =
- PCXHR_DIGITAL_ZERO_LEVEL;
- chip->analog_capture_active = 1;
-#ifdef CONFIG_SND_DEBUG
- /* analog volumes for playback
- * (is LEVEL_MIN after boot)
- */
- if (chip->mgr->is_hr_stereo)
- chip->analog_capture_volume[i] =
- HR222_LINE_CAPTURE_ZERO_LEVEL;
- else {
- chip->analog_capture_volume[i] =
- PCXHR_LINE_CAPTURE_ZERO_LEVEL;
- pcxhr_update_analog_audio_level(chip, 1, i);
- }
-#endif
- /* stereo cards need to be initialised after boot */
- if (chip->mgr->is_hr_stereo)
- hr222_update_analog_audio_level(chip, 1, i);
- }
- }
-
- return;
-}
-
-
-int pcxhr_create_mixer(struct pcxhr_mgr *mgr)
-{
- struct snd_pcxhr *chip;
- int err, i;
-
- mutex_init(&mgr->mixer_mutex); /* can be in another place */
-
- for (i = 0; i < mgr->num_cards; i++) {
- struct snd_kcontrol_new temp;
- chip = mgr->chip[i];
-
- if (chip->nb_streams_play) {
- /* analog output level control */
- temp = pcxhr_control_analog_level;
- temp.name = "Master Playback Volume";
- temp.private_value = 0; /* playback */
- if (mgr->is_hr_stereo)
- temp.tlv.p = db_scale_a_hr222_playback;
- else
- temp.tlv.p = db_scale_analog_playback;
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&temp, chip));
- if (err < 0)
- return err;
-
- /* output mute controls */
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&pcxhr_control_output_switch,
- chip));
- if (err < 0)
- return err;
-
- temp = snd_pcxhr_pcm_vol;
- temp.name = "PCM Playback Volume";
- temp.count = PCXHR_PLAYBACK_STREAMS;
- temp.private_value = 0; /* playback */
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&temp, chip));
- if (err < 0)
- return err;
-
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&pcxhr_control_pcm_switch, chip));
- if (err < 0)
- return err;
-
- /* IEC958 controls */
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&pcxhr_control_playback_iec958_mask,
- chip));
- if (err < 0)
- return err;
-
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&pcxhr_control_playback_iec958,
- chip));
- if (err < 0)
- return err;
- }
- if (chip->nb_streams_capt) {
- /* analog input level control */
- temp = pcxhr_control_analog_level;
- temp.name = "Line Capture Volume";
- temp.private_value = 1; /* capture */
- if (mgr->is_hr_stereo)
- temp.tlv.p = db_scale_a_hr222_capture;
- else
- temp.tlv.p = db_scale_analog_capture;
-
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&temp, chip));
- if (err < 0)
- return err;
-
- temp = snd_pcxhr_pcm_vol;
- temp.name = "PCM Capture Volume";
- temp.count = 1;
- temp.private_value = 1; /* capture */
-
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&temp, chip));
- if (err < 0)
- return err;
-
- /* Audio source */
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&pcxhr_control_audio_src, chip));
- if (err < 0)
- return err;
-
- /* IEC958 controls */
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&pcxhr_control_capture_iec958_mask,
- chip));
- if (err < 0)
- return err;
-
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&pcxhr_control_capture_iec958,
- chip));
- if (err < 0)
- return err;
-
- if (mgr->is_hr_stereo) {
- err = hr222_add_mic_controls(chip);
- if (err < 0)
- return err;
- }
- }
- /* monitoring only if playback and capture device available */
- if (chip->nb_streams_capt > 0 && chip->nb_streams_play > 0) {
- /* monitoring */
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&pcxhr_control_monitor_vol, chip));
- if (err < 0)
- return err;
-
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&pcxhr_control_monitor_sw, chip));
- if (err < 0)
- return err;
- }
-
- if (i == 0) {
- /* clock mode only one control per pcxhr */
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&pcxhr_control_clock_type, mgr));
- if (err < 0)
- return err;
- /* non standard control used to scan
- * the external clock presence/frequencies
- */
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&pcxhr_control_clock_rate, mgr));
- if (err < 0)
- return err;
- }
-
- /* init values for the mixer data */
- pcxhr_init_audio_levels(chip);
- }
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_mixer.h b/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_mixer.h
deleted file mode 100644
index 4348d0e5..00000000
--- a/ANDROID_3.4.5/sound/pci/pcxhr/pcxhr_mixer.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Driver for Digigram pcxhr compatible soundcards
- *
- * include file for mixer
- *
- * Copyright (c) 2004 by Digigram <alsa@digigram.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __SOUND_PCXHR_MIXER_H
-#define __SOUND_PCXHR_MIXER_H
-
-/* exported */
-int pcxhr_create_mixer(struct pcxhr_mgr *mgr);
-
-#endif /* __SOUND_PCXHR_MIXER_H */
diff --git a/ANDROID_3.4.5/sound/pci/riptide/Makefile b/ANDROID_3.4.5/sound/pci/riptide/Makefile
deleted file mode 100644
index dcd2e64e..00000000
--- a/ANDROID_3.4.5/sound/pci/riptide/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-snd-riptide-objs := riptide.o
-
-obj-$(CONFIG_SND_RIPTIDE) += snd-riptide.o
diff --git a/ANDROID_3.4.5/sound/pci/riptide/riptide.c b/ANDROID_3.4.5/sound/pci/riptide/riptide.c
deleted file mode 100644
index 0481d94a..00000000
--- a/ANDROID_3.4.5/sound/pci/riptide/riptide.c
+++ /dev/null
@@ -1,2223 +0,0 @@
-/*
- * Driver for the Conexant Riptide Soundchip
- *
- * Copyright (c) 2004 Peter Gruber <nokos@gmx.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-/*
- History:
- - 02/15/2004 first release
-
- This Driver is based on the OSS Driver version from Linuxant (riptide-0.6lnxtbeta03111100)
- credits from the original files:
-
- MODULE NAME: cnxt_rt.h
- AUTHOR: K. Lazarev (Transcribed by KNL)
- HISTORY: Major Revision Date By
- ----------------------------- -------- -----
- Created 02/1/2000 KNL
-
- MODULE NAME: int_mdl.c
- AUTHOR: Konstantin Lazarev (Transcribed by KNL)
- HISTORY: Major Revision Date By
- ----------------------------- -------- -----
- Created 10/01/99 KNL
-
- MODULE NAME: riptide.h
- AUTHOR: O. Druzhinin (Transcribed by OLD)
- HISTORY: Major Revision Date By
- ----------------------------- -------- -----
- Created 10/16/97 OLD
-
- MODULE NAME: Rp_Cmdif.cpp
- AUTHOR: O. Druzhinin (Transcribed by OLD)
- K. Lazarev (Transcribed by KNL)
- HISTORY: Major Revision Date By
- ----------------------------- -------- -----
- Adopted from NT4 driver 6/22/99 OLD
- Ported to Linux 9/01/99 KNL
-
- MODULE NAME: rt_hw.c
- AUTHOR: O. Druzhinin (Transcribed by OLD)
- C. Lazarev (Transcribed by CNL)
- HISTORY: Major Revision Date By
- ----------------------------- -------- -----
- Created 11/18/97 OLD
- Hardware functions for RipTide 11/24/97 CNL
- (ES1) are coded
- Hardware functions for RipTide 12/24/97 CNL
- (A0) are coded
- Hardware functions for RipTide 03/20/98 CNL
- (A1) are coded
- Boot loader is included 05/07/98 CNL
- Redesigned for WDM 07/27/98 CNL
- Redesigned for Linux 09/01/99 CNL
-
- MODULE NAME: rt_hw.h
- AUTHOR: C. Lazarev (Transcribed by CNL)
- HISTORY: Major Revision Date By
- ----------------------------- -------- -----
- Created 11/18/97 CNL
-
- MODULE NAME: rt_mdl.c
- AUTHOR: Konstantin Lazarev (Transcribed by KNL)
- HISTORY: Major Revision Date By
- ----------------------------- -------- -----
- Created 10/01/99 KNL
-
- MODULE NAME: mixer.h
- AUTHOR: K. Kenney
- HISTORY: Major Revision Date By
- ----------------------------- -------- -----
- Created from MS W95 Sample 11/28/95 KRS
- RipTide 10/15/97 KRS
- Adopted for Windows NT driver 01/20/98 CNL
-*/
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/wait.h>
-#include <linux/gameport.h>
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <asm/io.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/ac97_codec.h>
-#include <sound/mpu401.h>
-#include <sound/opl3.h>
-#include <sound/initval.h>
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK 1
-#endif
-
-MODULE_AUTHOR("Peter Gruber <nokos@gmx.net>");
-MODULE_DESCRIPTION("riptide");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Conexant,Riptide}}");
-MODULE_FIRMWARE("riptide.hex");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
-
-#ifdef SUPPORT_JOYSTICK
-static int joystick_port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS - 1)] = 0x200 };
-#endif
-static int mpu_port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS - 1)] = 0x330 };
-static int opl3_port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS - 1)] = 0x388 };
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Riptide soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Riptide soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Riptide soundcard.");
-#ifdef SUPPORT_JOYSTICK
-module_param_array(joystick_port, int, NULL, 0444);
-MODULE_PARM_DESC(joystick_port, "Joystick port # for Riptide soundcard.");
-#endif
-module_param_array(mpu_port, int, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU401 port # for Riptide driver.");
-module_param_array(opl3_port, int, NULL, 0444);
-MODULE_PARM_DESC(opl3_port, "OPL3 port # for Riptide driver.");
-
-/*
- */
-
-#define MPU401_HW_RIPTIDE MPU401_HW_MPU401
-#define OPL3_HW_RIPTIDE OPL3_HW_OPL3
-
-#define PCI_EXT_CapId 0x40
-#define PCI_EXT_NextCapPrt 0x41
-#define PCI_EXT_PWMC 0x42
-#define PCI_EXT_PWSCR 0x44
-#define PCI_EXT_Data00 0x46
-#define PCI_EXT_PMSCR_BSE 0x47
-#define PCI_EXT_SB_Base 0x48
-#define PCI_EXT_FM_Base 0x4a
-#define PCI_EXT_MPU_Base 0x4C
-#define PCI_EXT_Game_Base 0x4E
-#define PCI_EXT_Legacy_Mask 0x50
-#define PCI_EXT_AsicRev 0x52
-#define PCI_EXT_Reserved3 0x53
-
-#define LEGACY_ENABLE_ALL 0x8000 /* legacy device options */
-#define LEGACY_ENABLE_SB 0x4000
-#define LEGACY_ENABLE_FM 0x2000
-#define LEGACY_ENABLE_MPU_INT 0x1000
-#define LEGACY_ENABLE_MPU 0x0800
-#define LEGACY_ENABLE_GAMEPORT 0x0400
-
-#define MAX_WRITE_RETRY 10 /* cmd interface limits */
-#define MAX_ERROR_COUNT 10
-#define CMDIF_TIMEOUT 50000
-#define RESET_TRIES 5
-
-#define READ_PORT_ULONG(p) inl((unsigned long)&(p))
-#define WRITE_PORT_ULONG(p,x) outl(x,(unsigned long)&(p))
-
-#define READ_AUDIO_CONTROL(p) READ_PORT_ULONG(p->audio_control)
-#define WRITE_AUDIO_CONTROL(p,x) WRITE_PORT_ULONG(p->audio_control,x)
-#define UMASK_AUDIO_CONTROL(p,x) WRITE_PORT_ULONG(p->audio_control,READ_PORT_ULONG(p->audio_control)|x)
-#define MASK_AUDIO_CONTROL(p,x) WRITE_PORT_ULONG(p->audio_control,READ_PORT_ULONG(p->audio_control)&x)
-#define READ_AUDIO_STATUS(p) READ_PORT_ULONG(p->audio_status)
-
-#define SET_GRESET(p) UMASK_AUDIO_CONTROL(p,0x0001) /* global reset switch */
-#define UNSET_GRESET(p) MASK_AUDIO_CONTROL(p,~0x0001)
-#define SET_AIE(p) UMASK_AUDIO_CONTROL(p,0x0004) /* interrupt enable */
-#define UNSET_AIE(p) MASK_AUDIO_CONTROL(p,~0x0004)
-#define SET_AIACK(p) UMASK_AUDIO_CONTROL(p,0x0008) /* interrupt acknowledge */
-#define UNSET_AIACKT(p) MASKAUDIO_CONTROL(p,~0x0008)
-#define SET_ECMDAE(p) UMASK_AUDIO_CONTROL(p,0x0010)
-#define UNSET_ECMDAE(p) MASK_AUDIO_CONTROL(p,~0x0010)
-#define SET_ECMDBE(p) UMASK_AUDIO_CONTROL(p,0x0020)
-#define UNSET_ECMDBE(p) MASK_AUDIO_CONTROL(p,~0x0020)
-#define SET_EDATAF(p) UMASK_AUDIO_CONTROL(p,0x0040)
-#define UNSET_EDATAF(p) MASK_AUDIO_CONTROL(p,~0x0040)
-#define SET_EDATBF(p) UMASK_AUDIO_CONTROL(p,0x0080)
-#define UNSET_EDATBF(p) MASK_AUDIO_CONTROL(p,~0x0080)
-#define SET_ESBIRQON(p) UMASK_AUDIO_CONTROL(p,0x0100)
-#define UNSET_ESBIRQON(p) MASK_AUDIO_CONTROL(p,~0x0100)
-#define SET_EMPUIRQ(p) UMASK_AUDIO_CONTROL(p,0x0200)
-#define UNSET_EMPUIRQ(p) MASK_AUDIO_CONTROL(p,~0x0200)
-#define IS_CMDE(a) (READ_PORT_ULONG(a->stat)&0x1) /* cmd empty */
-#define IS_DATF(a) (READ_PORT_ULONG(a->stat)&0x2) /* data filled */
-#define IS_READY(p) (READ_AUDIO_STATUS(p)&0x0001)
-#define IS_DLREADY(p) (READ_AUDIO_STATUS(p)&0x0002)
-#define IS_DLERR(p) (READ_AUDIO_STATUS(p)&0x0004)
-#define IS_GERR(p) (READ_AUDIO_STATUS(p)&0x0008) /* error ! */
-#define IS_CMDAEIRQ(p) (READ_AUDIO_STATUS(p)&0x0010)
-#define IS_CMDBEIRQ(p) (READ_AUDIO_STATUS(p)&0x0020)
-#define IS_DATAFIRQ(p) (READ_AUDIO_STATUS(p)&0x0040)
-#define IS_DATBFIRQ(p) (READ_AUDIO_STATUS(p)&0x0080)
-#define IS_EOBIRQ(p) (READ_AUDIO_STATUS(p)&0x0100) /* interrupt status */
-#define IS_EOSIRQ(p) (READ_AUDIO_STATUS(p)&0x0200)
-#define IS_EOCIRQ(p) (READ_AUDIO_STATUS(p)&0x0400)
-#define IS_UNSLIRQ(p) (READ_AUDIO_STATUS(p)&0x0800)
-#define IS_SBIRQ(p) (READ_AUDIO_STATUS(p)&0x1000)
-#define IS_MPUIRQ(p) (READ_AUDIO_STATUS(p)&0x2000)
-
-#define RESP 0x00000001 /* command flags */
-#define PARM 0x00000002
-#define CMDA 0x00000004
-#define CMDB 0x00000008
-#define NILL 0x00000000
-
-#define LONG0(a) ((u32)a) /* shifts and masks */
-#define BYTE0(a) (LONG0(a)&0xff)
-#define BYTE1(a) (BYTE0(a)<<8)
-#define BYTE2(a) (BYTE0(a)<<16)
-#define BYTE3(a) (BYTE0(a)<<24)
-#define WORD0(a) (LONG0(a)&0xffff)
-#define WORD1(a) (WORD0(a)<<8)
-#define WORD2(a) (WORD0(a)<<16)
-#define TRINIB0(a) (LONG0(a)&0xffffff)
-#define TRINIB1(a) (TRINIB0(a)<<8)
-
-#define RET(a) ((union cmdret *)(a))
-
-#define SEND_GETV(p,b) sendcmd(p,RESP,GETV,0,RET(b)) /* get version */
-#define SEND_GETC(p,b,c) sendcmd(p,PARM|RESP,GETC,c,RET(b))
-#define SEND_GUNS(p,b) sendcmd(p,RESP,GUNS,0,RET(b))
-#define SEND_SCID(p,b) sendcmd(p,RESP,SCID,0,RET(b))
-#define SEND_RMEM(p,b,c,d) sendcmd(p,PARM|RESP,RMEM|BYTE1(b),LONG0(c),RET(d)) /* memory access for firmware write */
-#define SEND_SMEM(p,b,c) sendcmd(p,PARM,SMEM|BYTE1(b),LONG0(c),RET(0)) /* memory access for firmware write */
-#define SEND_WMEM(p,b,c) sendcmd(p,PARM,WMEM|BYTE1(b),LONG0(c),RET(0)) /* memory access for firmware write */
-#define SEND_SDTM(p,b,c) sendcmd(p,PARM|RESP,SDTM|TRINIB1(b),0,RET(c)) /* memory access for firmware write */
-#define SEND_GOTO(p,b) sendcmd(p,PARM,GOTO,LONG0(b),RET(0)) /* memory access for firmware write */
-#define SEND_SETDPLL(p) sendcmd(p,0,ARM_SETDPLL,0,RET(0))
-#define SEND_SSTR(p,b,c) sendcmd(p,PARM,SSTR|BYTE3(b),LONG0(c),RET(0)) /* start stream */
-#define SEND_PSTR(p,b) sendcmd(p,PARM,PSTR,BYTE3(b),RET(0)) /* pause stream */
-#define SEND_KSTR(p,b) sendcmd(p,PARM,KSTR,BYTE3(b),RET(0)) /* stop stream */
-#define SEND_KDMA(p) sendcmd(p,0,KDMA,0,RET(0)) /* stop all dma */
-#define SEND_GPOS(p,b,c,d) sendcmd(p,PARM|RESP,GPOS,BYTE3(c)|BYTE2(b),RET(d)) /* get position in dma */
-#define SEND_SETF(p,b,c,d,e,f,g) sendcmd(p,PARM,SETF|WORD1(b)|BYTE3(c),d|BYTE1(e)|BYTE2(f)|BYTE3(g),RET(0)) /* set sample format at mixer */
-#define SEND_GSTS(p,b,c,d) sendcmd(p,PARM|RESP,GSTS,BYTE3(c)|BYTE2(b),RET(d))
-#define SEND_NGPOS(p,b,c,d) sendcmd(p,PARM|RESP,NGPOS,BYTE3(c)|BYTE2(b),RET(d))
-#define SEND_PSEL(p,b,c) sendcmd(p,PARM,PSEL,BYTE2(b)|BYTE3(c),RET(0)) /* activate lbus path */
-#define SEND_PCLR(p,b,c) sendcmd(p,PARM,PCLR,BYTE2(b)|BYTE3(c),RET(0)) /* deactivate lbus path */
-#define SEND_PLST(p,b) sendcmd(p,PARM,PLST,BYTE3(b),RET(0))
-#define SEND_RSSV(p,b,c,d) sendcmd(p,PARM|RESP,RSSV,BYTE2(b)|BYTE3(c),RET(d))
-#define SEND_LSEL(p,b,c,d,e,f,g,h) sendcmd(p,PARM,LSEL|BYTE1(b)|BYTE2(c)|BYTE3(d),BYTE0(e)|BYTE1(f)|BYTE2(g)|BYTE3(h),RET(0)) /* select paths for internal connections */
-#define SEND_SSRC(p,b,c,d,e) sendcmd(p,PARM,SSRC|BYTE1(b)|WORD2(c),WORD0(d)|WORD2(e),RET(0)) /* configure source */
-#define SEND_SLST(p,b) sendcmd(p,PARM,SLST,BYTE3(b),RET(0))
-#define SEND_RSRC(p,b,c) sendcmd(p,RESP,RSRC|BYTE1(b),0,RET(c)) /* read source config */
-#define SEND_SSRB(p,b,c) sendcmd(p,PARM,SSRB|BYTE1(b),WORD2(c),RET(0))
-#define SEND_SDGV(p,b,c,d,e) sendcmd(p,PARM,SDGV|BYTE2(b)|BYTE3(c),WORD0(d)|WORD2(e),RET(0)) /* set digital mixer */
-#define SEND_RDGV(p,b,c,d) sendcmd(p,PARM|RESP,RDGV|BYTE2(b)|BYTE3(c),0,RET(d)) /* read digital mixer */
-#define SEND_DLST(p,b) sendcmd(p,PARM,DLST,BYTE3(b),RET(0))
-#define SEND_SACR(p,b,c) sendcmd(p,PARM,SACR,WORD0(b)|WORD2(c),RET(0)) /* set AC97 register */
-#define SEND_RACR(p,b,c) sendcmd(p,PARM|RESP,RACR,WORD2(b),RET(c)) /* get AC97 register */
-#define SEND_ALST(p,b) sendcmd(p,PARM,ALST,BYTE3(b),RET(0))
-#define SEND_TXAC(p,b,c,d,e,f) sendcmd(p,PARM,TXAC|BYTE1(b)|WORD2(c),WORD0(d)|BYTE2(e)|BYTE3(f),RET(0))
-#define SEND_RXAC(p,b,c,d) sendcmd(p,PARM|RESP,RXAC,BYTE2(b)|BYTE3(c),RET(d))
-#define SEND_SI2S(p,b) sendcmd(p,PARM,SI2S,WORD2(b),RET(0))
-
-#define EOB_STATUS 0x80000000 /* status flags : block boundary */
-#define EOS_STATUS 0x40000000 /* : stoppped */
-#define EOC_STATUS 0x20000000 /* : stream end */
-#define ERR_STATUS 0x10000000
-#define EMPTY_STATUS 0x08000000
-
-#define IEOB_ENABLE 0x1 /* enable interrupts for status notification above */
-#define IEOS_ENABLE 0x2
-#define IEOC_ENABLE 0x4
-#define RDONCE 0x8
-#define DESC_MAX_MASK 0xff
-
-#define ST_PLAY 0x1 /* stream states */
-#define ST_STOP 0x2
-#define ST_PAUSE 0x4
-
-#define I2S_INTDEC 3 /* config for I2S link */
-#define I2S_MERGER 0
-#define I2S_SPLITTER 0
-#define I2S_MIXER 7
-#define I2S_RATE 44100
-
-#define MODEM_INTDEC 4 /* config for modem link */
-#define MODEM_MERGER 3
-#define MODEM_SPLITTER 0
-#define MODEM_MIXER 11
-
-#define FM_INTDEC 3 /* config for FM/OPL3 link */
-#define FM_MERGER 0
-#define FM_SPLITTER 0
-#define FM_MIXER 9
-
-#define SPLIT_PATH 0x80 /* path splitting flag */
-
-enum FIRMWARE {
- DATA_REC = 0, EXT_END_OF_FILE, EXT_SEG_ADDR_REC, EXT_GOTO_CMD_REC,
- EXT_LIN_ADDR_REC,
-};
-
-enum CMDS {
- GETV = 0x00, GETC, GUNS, SCID, RMEM =
- 0x10, SMEM, WMEM, SDTM, GOTO, SSTR =
- 0x20, PSTR, KSTR, KDMA, GPOS, SETF, GSTS, NGPOS, PSEL =
- 0x30, PCLR, PLST, RSSV, LSEL, SSRC = 0x40, SLST, RSRC, SSRB, SDGV =
- 0x50, RDGV, DLST, SACR = 0x60, RACR, ALST, TXAC, RXAC, SI2S =
- 0x70, ARM_SETDPLL = 0x72,
-};
-
-enum E1SOURCE {
- ARM2LBUS_FIFO0 = 0, ARM2LBUS_FIFO1, ARM2LBUS_FIFO2, ARM2LBUS_FIFO3,
- ARM2LBUS_FIFO4, ARM2LBUS_FIFO5, ARM2LBUS_FIFO6, ARM2LBUS_FIFO7,
- ARM2LBUS_FIFO8, ARM2LBUS_FIFO9, ARM2LBUS_FIFO10, ARM2LBUS_FIFO11,
- ARM2LBUS_FIFO12, ARM2LBUS_FIFO13, ARM2LBUS_FIFO14, ARM2LBUS_FIFO15,
- INTER0_OUT, INTER1_OUT, INTER2_OUT, INTER3_OUT, INTER4_OUT,
- INTERM0_OUT, INTERM1_OUT, INTERM2_OUT, INTERM3_OUT, INTERM4_OUT,
- INTERM5_OUT, INTERM6_OUT, DECIMM0_OUT, DECIMM1_OUT, DECIMM2_OUT,
- DECIMM3_OUT, DECIM0_OUT, SR3_4_OUT, OPL3_SAMPLE, ASRC0, ASRC1,
- ACLNK2PADC, ACLNK2MODEM0RX, ACLNK2MIC, ACLNK2MODEM1RX, ACLNK2HNDMIC,
- DIGITAL_MIXER_OUT0, GAINFUNC0_OUT, GAINFUNC1_OUT, GAINFUNC2_OUT,
- GAINFUNC3_OUT, GAINFUNC4_OUT, SOFTMODEMTX, SPLITTER0_OUTL,
- SPLITTER0_OUTR, SPLITTER1_OUTL, SPLITTER1_OUTR, SPLITTER2_OUTL,
- SPLITTER2_OUTR, SPLITTER3_OUTL, SPLITTER3_OUTR, MERGER0_OUT,
- MERGER1_OUT, MERGER2_OUT, MERGER3_OUT, ARM2LBUS_FIFO_DIRECT, NO_OUT
-};
-
-enum E2SINK {
- LBUS2ARM_FIFO0 = 0, LBUS2ARM_FIFO1, LBUS2ARM_FIFO2, LBUS2ARM_FIFO3,
- LBUS2ARM_FIFO4, LBUS2ARM_FIFO5, LBUS2ARM_FIFO6, LBUS2ARM_FIFO7,
- INTER0_IN, INTER1_IN, INTER2_IN, INTER3_IN, INTER4_IN, INTERM0_IN,
- INTERM1_IN, INTERM2_IN, INTERM3_IN, INTERM4_IN, INTERM5_IN, INTERM6_IN,
- DECIMM0_IN, DECIMM1_IN, DECIMM2_IN, DECIMM3_IN, DECIM0_IN, SR3_4_IN,
- PDAC2ACLNK, MODEM0TX2ACLNK, MODEM1TX2ACLNK, HNDSPK2ACLNK,
- DIGITAL_MIXER_IN0, DIGITAL_MIXER_IN1, DIGITAL_MIXER_IN2,
- DIGITAL_MIXER_IN3, DIGITAL_MIXER_IN4, DIGITAL_MIXER_IN5,
- DIGITAL_MIXER_IN6, DIGITAL_MIXER_IN7, DIGITAL_MIXER_IN8,
- DIGITAL_MIXER_IN9, DIGITAL_MIXER_IN10, DIGITAL_MIXER_IN11,
- GAINFUNC0_IN, GAINFUNC1_IN, GAINFUNC2_IN, GAINFUNC3_IN, GAINFUNC4_IN,
- SOFTMODEMRX, SPLITTER0_IN, SPLITTER1_IN, SPLITTER2_IN, SPLITTER3_IN,
- MERGER0_INL, MERGER0_INR, MERGER1_INL, MERGER1_INR, MERGER2_INL,
- MERGER2_INR, MERGER3_INL, MERGER3_INR, E2SINK_MAX
-};
-
-enum LBUS_SINK {
- LS_SRC_INTERPOLATOR = 0, LS_SRC_INTERPOLATORM, LS_SRC_DECIMATOR,
- LS_SRC_DECIMATORM, LS_MIXER_IN, LS_MIXER_GAIN_FUNCTION,
- LS_SRC_SPLITTER, LS_SRC_MERGER, LS_NONE1, LS_NONE2,
-};
-
-enum RT_CHANNEL_IDS {
- M0TX = 0, M1TX, TAMTX, HSSPKR, PDAC, DSNDTX0, DSNDTX1, DSNDTX2,
- DSNDTX3, DSNDTX4, DSNDTX5, DSNDTX6, DSNDTX7, WVSTRTX, COP3DTX, SPARE,
- M0RX, HSMIC, M1RX, CLEANRX, MICADC, PADC, COPRX1, COPRX2,
- CHANNEL_ID_COUNTER
-};
-
-enum { SB_CMD = 0, MODEM_CMD, I2S_CMD0, I2S_CMD1, FM_CMD, MAX_CMD };
-
-struct lbuspath {
- unsigned char *noconv;
- unsigned char *stereo;
- unsigned char *mono;
-};
-
-struct cmdport {
- u32 data1; /* cmd,param */
- u32 data2; /* param */
- u32 stat; /* status */
- u32 pad[5];
-};
-
-struct riptideport {
- u32 audio_control; /* status registers */
- u32 audio_status;
- u32 pad[2];
- struct cmdport port[2]; /* command ports */
-};
-
-struct cmdif {
- struct riptideport *hwport;
- spinlock_t lock;
- unsigned int cmdcnt; /* cmd statistics */
- unsigned int cmdtime;
- unsigned int cmdtimemax;
- unsigned int cmdtimemin;
- unsigned int errcnt;
- int is_reset;
-};
-
-struct riptide_firmware {
- u16 ASIC;
- u16 CODEC;
- u16 AUXDSP;
- u16 PROG;
-};
-
-union cmdret {
- u8 retbytes[8];
- u16 retwords[4];
- u32 retlongs[2];
-};
-
-union firmware_version {
- union cmdret ret;
- struct riptide_firmware firmware;
-};
-
-#define get_pcmhwdev(substream) (struct pcmhw *)(substream->runtime->private_data)
-
-#define PLAYBACK_SUBSTREAMS 3
-struct snd_riptide {
- struct snd_card *card;
- struct pci_dev *pci;
- const struct firmware *fw_entry;
-
- struct cmdif *cif;
-
- struct snd_pcm *pcm;
- struct snd_pcm *pcm_i2s;
- struct snd_rawmidi *rmidi;
- struct snd_opl3 *opl3;
- struct snd_ac97 *ac97;
- struct snd_ac97_bus *ac97_bus;
-
- struct snd_pcm_substream *playback_substream[PLAYBACK_SUBSTREAMS];
- struct snd_pcm_substream *capture_substream;
-
- int openstreams;
-
- int irq;
- unsigned long port;
- unsigned short mpuaddr;
- unsigned short opladdr;
-#ifdef SUPPORT_JOYSTICK
- unsigned short gameaddr;
-#endif
- struct resource *res_port;
-
- unsigned short device_id;
-
- union firmware_version firmware;
-
- spinlock_t lock;
- struct tasklet_struct riptide_tq;
- struct snd_info_entry *proc_entry;
-
- unsigned long received_irqs;
- unsigned long handled_irqs;
-#ifdef CONFIG_PM
- int in_suspend;
-#endif
-};
-
-struct sgd { /* scatter gather desriptor */
- u32 dwNextLink;
- u32 dwSegPtrPhys;
- u32 dwSegLen;
- u32 dwStat_Ctl;
-};
-
-struct pcmhw { /* pcm descriptor */
- struct lbuspath paths;
- unsigned char *lbuspath;
- unsigned char source;
- unsigned char intdec[2];
- unsigned char mixer;
- unsigned char id;
- unsigned char state;
- unsigned int rate;
- unsigned int channels;
- snd_pcm_format_t format;
- struct snd_dma_buffer sgdlist;
- struct sgd *sgdbuf;
- unsigned int size;
- unsigned int pages;
- unsigned int oldpos;
- unsigned int pointer;
-};
-
-#define CMDRET_ZERO (union cmdret){{(u32)0, (u32) 0}}
-
-static int sendcmd(struct cmdif *cif, u32 flags, u32 cmd, u32 parm,
- union cmdret *ret);
-static int getsourcesink(struct cmdif *cif, unsigned char source,
- unsigned char sink, unsigned char *a,
- unsigned char *b);
-static int snd_riptide_initialize(struct snd_riptide *chip);
-static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip);
-
-/*
- */
-
-static DEFINE_PCI_DEVICE_TABLE(snd_riptide_ids) = {
- { PCI_DEVICE(0x127a, 0x4310) },
- { PCI_DEVICE(0x127a, 0x4320) },
- { PCI_DEVICE(0x127a, 0x4330) },
- { PCI_DEVICE(0x127a, 0x4340) },
- {0,},
-};
-
-#ifdef SUPPORT_JOYSTICK
-static DEFINE_PCI_DEVICE_TABLE(snd_riptide_joystick_ids) = {
- { PCI_DEVICE(0x127a, 0x4312) },
- { PCI_DEVICE(0x127a, 0x4322) },
- { PCI_DEVICE(0x127a, 0x4332) },
- { PCI_DEVICE(0x127a, 0x4342) },
- {0,},
-};
-#endif
-
-MODULE_DEVICE_TABLE(pci, snd_riptide_ids);
-
-/*
- */
-
-static unsigned char lbusin2out[E2SINK_MAX + 1][2] = {
- {NO_OUT, LS_NONE1}, {NO_OUT, LS_NONE2}, {NO_OUT, LS_NONE1}, {NO_OUT,
- LS_NONE2},
- {NO_OUT, LS_NONE1}, {NO_OUT, LS_NONE2}, {NO_OUT, LS_NONE1}, {NO_OUT,
- LS_NONE2},
- {INTER0_OUT, LS_SRC_INTERPOLATOR}, {INTER1_OUT, LS_SRC_INTERPOLATOR},
- {INTER2_OUT, LS_SRC_INTERPOLATOR}, {INTER3_OUT, LS_SRC_INTERPOLATOR},
- {INTER4_OUT, LS_SRC_INTERPOLATOR}, {INTERM0_OUT, LS_SRC_INTERPOLATORM},
- {INTERM1_OUT, LS_SRC_INTERPOLATORM}, {INTERM2_OUT,
- LS_SRC_INTERPOLATORM},
- {INTERM3_OUT, LS_SRC_INTERPOLATORM}, {INTERM4_OUT,
- LS_SRC_INTERPOLATORM},
- {INTERM5_OUT, LS_SRC_INTERPOLATORM}, {INTERM6_OUT,
- LS_SRC_INTERPOLATORM},
- {DECIMM0_OUT, LS_SRC_DECIMATORM}, {DECIMM1_OUT, LS_SRC_DECIMATORM},
- {DECIMM2_OUT, LS_SRC_DECIMATORM}, {DECIMM3_OUT, LS_SRC_DECIMATORM},
- {DECIM0_OUT, LS_SRC_DECIMATOR}, {SR3_4_OUT, LS_NONE1}, {NO_OUT,
- LS_NONE2},
- {NO_OUT, LS_NONE1}, {NO_OUT, LS_NONE2}, {NO_OUT, LS_NONE1},
- {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},
- {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},
- {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},
- {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},
- {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},
- {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},
- {GAINFUNC0_OUT, LS_MIXER_GAIN_FUNCTION}, {GAINFUNC1_OUT,
- LS_MIXER_GAIN_FUNCTION},
- {GAINFUNC2_OUT, LS_MIXER_GAIN_FUNCTION}, {GAINFUNC3_OUT,
- LS_MIXER_GAIN_FUNCTION},
- {GAINFUNC4_OUT, LS_MIXER_GAIN_FUNCTION}, {SOFTMODEMTX, LS_NONE1},
- {SPLITTER0_OUTL, LS_SRC_SPLITTER}, {SPLITTER1_OUTL, LS_SRC_SPLITTER},
- {SPLITTER2_OUTL, LS_SRC_SPLITTER}, {SPLITTER3_OUTL, LS_SRC_SPLITTER},
- {MERGER0_OUT, LS_SRC_MERGER}, {MERGER0_OUT, LS_SRC_MERGER},
- {MERGER1_OUT, LS_SRC_MERGER},
- {MERGER1_OUT, LS_SRC_MERGER}, {MERGER2_OUT, LS_SRC_MERGER},
- {MERGER2_OUT, LS_SRC_MERGER},
- {MERGER3_OUT, LS_SRC_MERGER}, {MERGER3_OUT, LS_SRC_MERGER}, {NO_OUT,
- LS_NONE2},
-};
-
-static unsigned char lbus_play_opl3[] = {
- DIGITAL_MIXER_IN0 + FM_MIXER, 0xff
-};
-static unsigned char lbus_play_modem[] = {
- DIGITAL_MIXER_IN0 + MODEM_MIXER, 0xff
-};
-static unsigned char lbus_play_i2s[] = {
- INTER0_IN + I2S_INTDEC, DIGITAL_MIXER_IN0 + I2S_MIXER, 0xff
-};
-static unsigned char lbus_play_out[] = {
- PDAC2ACLNK, 0xff
-};
-static unsigned char lbus_play_outhp[] = {
- HNDSPK2ACLNK, 0xff
-};
-static unsigned char lbus_play_noconv1[] = {
- DIGITAL_MIXER_IN0, 0xff
-};
-static unsigned char lbus_play_stereo1[] = {
- INTER0_IN, DIGITAL_MIXER_IN0, 0xff
-};
-static unsigned char lbus_play_mono1[] = {
- INTERM0_IN, DIGITAL_MIXER_IN0, 0xff
-};
-static unsigned char lbus_play_noconv2[] = {
- DIGITAL_MIXER_IN1, 0xff
-};
-static unsigned char lbus_play_stereo2[] = {
- INTER1_IN, DIGITAL_MIXER_IN1, 0xff
-};
-static unsigned char lbus_play_mono2[] = {
- INTERM1_IN, DIGITAL_MIXER_IN1, 0xff
-};
-static unsigned char lbus_play_noconv3[] = {
- DIGITAL_MIXER_IN2, 0xff
-};
-static unsigned char lbus_play_stereo3[] = {
- INTER2_IN, DIGITAL_MIXER_IN2, 0xff
-};
-static unsigned char lbus_play_mono3[] = {
- INTERM2_IN, DIGITAL_MIXER_IN2, 0xff
-};
-static unsigned char lbus_rec_noconv1[] = {
- LBUS2ARM_FIFO5, 0xff
-};
-static unsigned char lbus_rec_stereo1[] = {
- DECIM0_IN, LBUS2ARM_FIFO5, 0xff
-};
-static unsigned char lbus_rec_mono1[] = {
- DECIMM3_IN, LBUS2ARM_FIFO5, 0xff
-};
-
-static unsigned char play_ids[] = { 4, 1, 2, };
-static unsigned char play_sources[] = {
- ARM2LBUS_FIFO4, ARM2LBUS_FIFO1, ARM2LBUS_FIFO2,
-};
-static struct lbuspath lbus_play_paths[] = {
- {
- .noconv = lbus_play_noconv1,
- .stereo = lbus_play_stereo1,
- .mono = lbus_play_mono1,
- },
- {
- .noconv = lbus_play_noconv2,
- .stereo = lbus_play_stereo2,
- .mono = lbus_play_mono2,
- },
- {
- .noconv = lbus_play_noconv3,
- .stereo = lbus_play_stereo3,
- .mono = lbus_play_mono3,
- },
-};
-static struct lbuspath lbus_rec_path = {
- .noconv = lbus_rec_noconv1,
- .stereo = lbus_rec_stereo1,
- .mono = lbus_rec_mono1,
-};
-
-#define FIRMWARE_VERSIONS 1
-static union firmware_version firmware_versions[] = {
- {
- .firmware = {
- .ASIC = 3,
- .CODEC = 2,
- .AUXDSP = 3,
- .PROG = 773,
- },
- },
-};
-
-static u32 atoh(const unsigned char *in, unsigned int len)
-{
- u32 sum = 0;
- unsigned int mult = 1;
- unsigned char c;
-
- while (len) {
- int value;
-
- c = in[len - 1];
- value = hex_to_bin(c);
- if (value >= 0)
- sum += mult * value;
- mult *= 16;
- --len;
- }
- return sum;
-}
-
-static int senddata(struct cmdif *cif, const unsigned char *in, u32 offset)
-{
- u32 addr;
- u32 data;
- u32 i;
- const unsigned char *p;
-
- i = atoh(&in[1], 2);
- addr = offset + atoh(&in[3], 4);
- if (SEND_SMEM(cif, 0, addr) != 0)
- return -EACCES;
- p = in + 9;
- while (i) {
- data = atoh(p, 8);
- if (SEND_WMEM(cif, 2,
- ((data & 0x0f0f0f0f) << 4) | ((data & 0xf0f0f0f0)
- >> 4)))
- return -EACCES;
- i -= 4;
- p += 8;
- }
- return 0;
-}
-
-static int loadfirmware(struct cmdif *cif, const unsigned char *img,
- unsigned int size)
-{
- const unsigned char *in;
- u32 laddr, saddr, t, val;
- int err = 0;
-
- laddr = saddr = 0;
- while (size > 0 && err == 0) {
- in = img;
- if (in[0] == ':') {
- t = atoh(&in[7], 2);
- switch (t) {
- case DATA_REC:
- err = senddata(cif, in, laddr + saddr);
- break;
- case EXT_SEG_ADDR_REC:
- saddr = atoh(&in[9], 4) << 4;
- break;
- case EXT_LIN_ADDR_REC:
- laddr = atoh(&in[9], 4) << 16;
- break;
- case EXT_GOTO_CMD_REC:
- val = atoh(&in[9], 8);
- if (SEND_GOTO(cif, val) != 0)
- err = -EACCES;
- break;
- case EXT_END_OF_FILE:
- size = 0;
- break;
- default:
- break;
- }
- while (size > 0) {
- size--;
- if (*img++ == '\n')
- break;
- }
- }
- }
- snd_printdd("load firmware return %d\n", err);
- return err;
-}
-
-static void
-alloclbuspath(struct cmdif *cif, unsigned char source,
- unsigned char *path, unsigned char *mixer, unsigned char *s)
-{
- while (*path != 0xff) {
- unsigned char sink, type;
-
- sink = *path & (~SPLIT_PATH);
- if (sink != E2SINK_MAX) {
- snd_printdd("alloc path 0x%x->0x%x\n", source, sink);
- SEND_PSEL(cif, source, sink);
- source = lbusin2out[sink][0];
- type = lbusin2out[sink][1];
- if (type == LS_MIXER_IN) {
- if (mixer)
- *mixer = sink - DIGITAL_MIXER_IN0;
- }
- if (type == LS_SRC_DECIMATORM ||
- type == LS_SRC_DECIMATOR ||
- type == LS_SRC_INTERPOLATORM ||
- type == LS_SRC_INTERPOLATOR) {
- if (s) {
- if (s[0] != 0xff)
- s[1] = sink;
- else
- s[0] = sink;
- }
- }
- }
- if (*path++ & SPLIT_PATH) {
- unsigned char *npath = path;
-
- while (*npath != 0xff)
- npath++;
- alloclbuspath(cif, source + 1, ++npath, mixer, s);
- }
- }
-}
-
-static void
-freelbuspath(struct cmdif *cif, unsigned char source, unsigned char *path)
-{
- while (*path != 0xff) {
- unsigned char sink;
-
- sink = *path & (~SPLIT_PATH);
- if (sink != E2SINK_MAX) {
- snd_printdd("free path 0x%x->0x%x\n", source, sink);
- SEND_PCLR(cif, source, sink);
- source = lbusin2out[sink][0];
- }
- if (*path++ & SPLIT_PATH) {
- unsigned char *npath = path;
-
- while (*npath != 0xff)
- npath++;
- freelbuspath(cif, source + 1, ++npath);
- }
- }
-}
-
-static int writearm(struct cmdif *cif, u32 addr, u32 data, u32 mask)
-{
- union cmdret rptr = CMDRET_ZERO;
- unsigned int i = MAX_WRITE_RETRY;
- int flag = 1;
-
- SEND_RMEM(cif, 0x02, addr, &rptr);
- rptr.retlongs[0] &= (~mask);
-
- while (--i) {
- SEND_SMEM(cif, 0x01, addr);
- SEND_WMEM(cif, 0x02, (rptr.retlongs[0] | data));
- SEND_RMEM(cif, 0x02, addr, &rptr);
- if ((rptr.retlongs[0] & data) == data) {
- flag = 0;
- break;
- } else
- rptr.retlongs[0] &= ~mask;
- }
- snd_printdd("send arm 0x%x 0x%x 0x%x return %d\n", addr, data, mask,
- flag);
- return flag;
-}
-
-static int sendcmd(struct cmdif *cif, u32 flags, u32 cmd, u32 parm,
- union cmdret *ret)
-{
- int i, j;
- int err;
- unsigned int time = 0;
- unsigned long irqflags;
- struct riptideport *hwport;
- struct cmdport *cmdport = NULL;
-
- if (snd_BUG_ON(!cif))
- return -EINVAL;
-
- hwport = cif->hwport;
- if (cif->errcnt > MAX_ERROR_COUNT) {
- if (cif->is_reset) {
- snd_printk(KERN_ERR
- "Riptide: Too many failed cmds, reinitializing\n");
- if (riptide_reset(cif, NULL) == 0) {
- cif->errcnt = 0;
- return -EIO;
- }
- }
- snd_printk(KERN_ERR "Riptide: Initialization failed.\n");
- return -EINVAL;
- }
- if (ret) {
- ret->retlongs[0] = 0;
- ret->retlongs[1] = 0;
- }
- i = 0;
- spin_lock_irqsave(&cif->lock, irqflags);
- while (i++ < CMDIF_TIMEOUT && !IS_READY(cif->hwport))
- udelay(10);
- if (i > CMDIF_TIMEOUT) {
- err = -EBUSY;
- goto errout;
- }
-
- err = 0;
- for (j = 0, time = 0; time < CMDIF_TIMEOUT; j++, time += 2) {
- cmdport = &(hwport->port[j % 2]);
- if (IS_DATF(cmdport)) { /* free pending data */
- READ_PORT_ULONG(cmdport->data1);
- READ_PORT_ULONG(cmdport->data2);
- }
- if (IS_CMDE(cmdport)) {
- if (flags & PARM) /* put data */
- WRITE_PORT_ULONG(cmdport->data2, parm);
- WRITE_PORT_ULONG(cmdport->data1, cmd); /* write cmd */
- if ((flags & RESP) && ret) {
- while (!IS_DATF(cmdport) &&
- time < CMDIF_TIMEOUT) {
- udelay(10);
- time++;
- }
- if (time < CMDIF_TIMEOUT) { /* read response */
- ret->retlongs[0] =
- READ_PORT_ULONG(cmdport->data1);
- ret->retlongs[1] =
- READ_PORT_ULONG(cmdport->data2);
- } else {
- err = -ENOSYS;
- goto errout;
- }
- }
- break;
- }
- udelay(20);
- }
- if (time == CMDIF_TIMEOUT) {
- err = -ENODATA;
- goto errout;
- }
- spin_unlock_irqrestore(&cif->lock, irqflags);
-
- cif->cmdcnt++; /* update command statistics */
- cif->cmdtime += time;
- if (time > cif->cmdtimemax)
- cif->cmdtimemax = time;
- if (time < cif->cmdtimemin)
- cif->cmdtimemin = time;
- if ((cif->cmdcnt) % 1000 == 0)
- snd_printdd
- ("send cmd %d time: %d mintime: %d maxtime %d err: %d\n",
- cif->cmdcnt, cif->cmdtime, cif->cmdtimemin,
- cif->cmdtimemax, cif->errcnt);
- return 0;
-
- errout:
- cif->errcnt++;
- spin_unlock_irqrestore(&cif->lock, irqflags);
- snd_printdd
- ("send cmd %d hw: 0x%x flag: 0x%x cmd: 0x%x parm: 0x%x ret: 0x%x 0x%x CMDE: %d DATF: %d failed %d\n",
- cif->cmdcnt, (int)((void *)&(cmdport->stat) - (void *)hwport),
- flags, cmd, parm, ret ? ret->retlongs[0] : 0,
- ret ? ret->retlongs[1] : 0, IS_CMDE(cmdport), IS_DATF(cmdport),
- err);
- return err;
-}
-
-static int
-setmixer(struct cmdif *cif, short num, unsigned short rval, unsigned short lval)
-{
- union cmdret rptr = CMDRET_ZERO;
- int i = 0;
-
- snd_printdd("sent mixer %d: 0x%d 0x%d\n", num, rval, lval);
- do {
- SEND_SDGV(cif, num, num, rval, lval);
- SEND_RDGV(cif, num, num, &rptr);
- if (rptr.retwords[0] == lval && rptr.retwords[1] == rval)
- return 0;
- } while (i++ < MAX_WRITE_RETRY);
- snd_printdd("sent mixer failed\n");
- return -EIO;
-}
-
-static int getpaths(struct cmdif *cif, unsigned char *o)
-{
- unsigned char src[E2SINK_MAX];
- unsigned char sink[E2SINK_MAX];
- int i, j = 0;
-
- for (i = 0; i < E2SINK_MAX; i++) {
- getsourcesink(cif, i, i, &src[i], &sink[i]);
- if (sink[i] < E2SINK_MAX) {
- o[j++] = sink[i];
- o[j++] = i;
- }
- }
- return j;
-}
-
-static int
-getsourcesink(struct cmdif *cif, unsigned char source, unsigned char sink,
- unsigned char *a, unsigned char *b)
-{
- union cmdret rptr = CMDRET_ZERO;
-
- if (SEND_RSSV(cif, source, sink, &rptr) &&
- SEND_RSSV(cif, source, sink, &rptr))
- return -EIO;
- *a = rptr.retbytes[0];
- *b = rptr.retbytes[1];
- snd_printdd("getsourcesink 0x%x 0x%x\n", *a, *b);
- return 0;
-}
-
-static int
-getsamplerate(struct cmdif *cif, unsigned char *intdec, unsigned int *rate)
-{
- unsigned char *s;
- unsigned int p[2] = { 0, 0 };
- int i;
- union cmdret rptr = CMDRET_ZERO;
-
- s = intdec;
- for (i = 0; i < 2; i++) {
- if (*s != 0xff) {
- if (SEND_RSRC(cif, *s, &rptr) &&
- SEND_RSRC(cif, *s, &rptr))
- return -EIO;
- p[i] += rptr.retwords[1];
- p[i] *= rptr.retwords[2];
- p[i] += rptr.retwords[3];
- p[i] /= 65536;
- }
- s++;
- }
- if (p[0]) {
- if (p[1] != p[0])
- snd_printdd("rates differ %d %d\n", p[0], p[1]);
- *rate = (unsigned int)p[0];
- } else
- *rate = (unsigned int)p[1];
- snd_printdd("getsampleformat %d %d %d\n", intdec[0], intdec[1], *rate);
- return 0;
-}
-
-static int
-setsampleformat(struct cmdif *cif,
- unsigned char mixer, unsigned char id,
- unsigned char channels, unsigned char format)
-{
- unsigned char w, ch, sig, order;
-
- snd_printdd
- ("setsampleformat mixer: %d id: %d channels: %d format: %d\n",
- mixer, id, channels, format);
- ch = channels == 1;
- w = snd_pcm_format_width(format) == 8;
- sig = snd_pcm_format_unsigned(format) != 0;
- order = snd_pcm_format_big_endian(format) != 0;
-
- if (SEND_SETF(cif, mixer, w, ch, order, sig, id) &&
- SEND_SETF(cif, mixer, w, ch, order, sig, id)) {
- snd_printdd("setsampleformat failed\n");
- return -EIO;
- }
- return 0;
-}
-
-static int
-setsamplerate(struct cmdif *cif, unsigned char *intdec, unsigned int rate)
-{
- u32 D, M, N;
- union cmdret rptr = CMDRET_ZERO;
- int i;
-
- snd_printdd("setsamplerate intdec: %d,%d rate: %d\n", intdec[0],
- intdec[1], rate);
- D = 48000;
- M = ((rate == 48000) ? 47999 : rate) * 65536;
- N = M % D;
- M /= D;
- for (i = 0; i < 2; i++) {
- if (*intdec != 0xff) {
- do {
- SEND_SSRC(cif, *intdec, D, M, N);
- SEND_RSRC(cif, *intdec, &rptr);
- } while (rptr.retwords[1] != D &&
- rptr.retwords[2] != M &&
- rptr.retwords[3] != N &&
- i++ < MAX_WRITE_RETRY);
- if (i > MAX_WRITE_RETRY) {
- snd_printdd("sent samplerate %d: %d failed\n",
- *intdec, rate);
- return -EIO;
- }
- }
- intdec++;
- }
- return 0;
-}
-
-static int
-getmixer(struct cmdif *cif, short num, unsigned short *rval,
- unsigned short *lval)
-{
- union cmdret rptr = CMDRET_ZERO;
-
- if (SEND_RDGV(cif, num, num, &rptr) && SEND_RDGV(cif, num, num, &rptr))
- return -EIO;
- *rval = rptr.retwords[0];
- *lval = rptr.retwords[1];
- snd_printdd("got mixer %d: 0x%d 0x%d\n", num, *rval, *lval);
- return 0;
-}
-
-static void riptide_handleirq(unsigned long dev_id)
-{
- struct snd_riptide *chip = (void *)dev_id;
- struct cmdif *cif = chip->cif;
- struct snd_pcm_substream *substream[PLAYBACK_SUBSTREAMS + 1];
- struct snd_pcm_runtime *runtime;
- struct pcmhw *data = NULL;
- unsigned int pos, period_bytes;
- struct sgd *c;
- int i, j;
- unsigned int flag;
-
- if (!cif)
- return;
-
- for (i = 0; i < PLAYBACK_SUBSTREAMS; i++)
- substream[i] = chip->playback_substream[i];
- substream[i] = chip->capture_substream;
- for (i = 0; i < PLAYBACK_SUBSTREAMS + 1; i++) {
- if (substream[i] &&
- (runtime = substream[i]->runtime) &&
- (data = runtime->private_data) && data->state != ST_STOP) {
- pos = 0;
- for (j = 0; j < data->pages; j++) {
- c = &data->sgdbuf[j];
- flag = le32_to_cpu(c->dwStat_Ctl);
- if (flag & EOB_STATUS)
- pos += le32_to_cpu(c->dwSegLen);
- if (flag & EOC_STATUS)
- pos += le32_to_cpu(c->dwSegLen);
- if ((flag & EOS_STATUS)
- && (data->state == ST_PLAY)) {
- data->state = ST_STOP;
- snd_printk(KERN_ERR
- "Riptide: DMA stopped unexpectedly\n");
- }
- c->dwStat_Ctl =
- cpu_to_le32(flag &
- ~(EOS_STATUS | EOB_STATUS |
- EOC_STATUS));
- }
- data->pointer += pos;
- pos += data->oldpos;
- if (data->state != ST_STOP) {
- period_bytes =
- frames_to_bytes(runtime,
- runtime->period_size);
- snd_printdd
- ("interrupt 0x%x after 0x%lx of 0x%lx frames in period\n",
- READ_AUDIO_STATUS(cif->hwport),
- bytes_to_frames(runtime, pos),
- runtime->period_size);
- j = 0;
- if (pos >= period_bytes) {
- j++;
- while (pos >= period_bytes)
- pos -= period_bytes;
- }
- data->oldpos = pos;
- if (j > 0)
- snd_pcm_period_elapsed(substream[i]);
- }
- }
- }
-}
-
-#ifdef CONFIG_PM
-static int riptide_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_riptide *chip = card->private_data;
-
- chip->in_suspend = 1;
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(chip->pcm);
- snd_ac97_suspend(chip->ac97);
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int riptide_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_riptide *chip = card->private_data;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "riptide: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
- snd_riptide_initialize(chip);
- snd_ac97_resume(chip->ac97);
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- chip->in_suspend = 0;
- return 0;
-}
-#endif
-
-static int try_to_load_firmware(struct cmdif *cif, struct snd_riptide *chip)
-{
- union firmware_version firmware = { .ret = CMDRET_ZERO };
- int i, timeout, err;
-
- for (i = 0; i < 2; i++) {
- WRITE_PORT_ULONG(cif->hwport->port[i].data1, 0);
- WRITE_PORT_ULONG(cif->hwport->port[i].data2, 0);
- }
- SET_GRESET(cif->hwport);
- udelay(100);
- UNSET_GRESET(cif->hwport);
- udelay(100);
-
- for (timeout = 100000; --timeout; udelay(10)) {
- if (IS_READY(cif->hwport) && !IS_GERR(cif->hwport))
- break;
- }
- if (!timeout) {
- snd_printk(KERN_ERR
- "Riptide: device not ready, audio status: 0x%x "
- "ready: %d gerr: %d\n",
- READ_AUDIO_STATUS(cif->hwport),
- IS_READY(cif->hwport), IS_GERR(cif->hwport));
- return -EIO;
- } else {
- snd_printdd
- ("Riptide: audio status: 0x%x ready: %d gerr: %d\n",
- READ_AUDIO_STATUS(cif->hwport),
- IS_READY(cif->hwport), IS_GERR(cif->hwport));
- }
-
- SEND_GETV(cif, &firmware.ret);
- snd_printdd("Firmware version: ASIC: %d CODEC %d AUXDSP %d PROG %d\n",
- firmware.firmware.ASIC, firmware.firmware.CODEC,
- firmware.firmware.AUXDSP, firmware.firmware.PROG);
-
- if (!chip)
- return 1;
-
- for (i = 0; i < FIRMWARE_VERSIONS; i++) {
- if (!memcmp(&firmware_versions[i], &firmware, sizeof(firmware)))
- return 1; /* OK */
-
- }
-
- snd_printdd("Writing Firmware\n");
- if (!chip->fw_entry) {
- err = request_firmware(&chip->fw_entry, "riptide.hex",
- &chip->pci->dev);
- if (err) {
- snd_printk(KERN_ERR
- "Riptide: Firmware not available %d\n", err);
- return -EIO;
- }
- }
- err = loadfirmware(cif, chip->fw_entry->data, chip->fw_entry->size);
- if (err) {
- snd_printk(KERN_ERR
- "Riptide: Could not load firmware %d\n", err);
- return err;
- }
-
- chip->firmware = firmware;
-
- return 1; /* OK */
-}
-
-static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip)
-{
- union cmdret rptr = CMDRET_ZERO;
- int err, tries;
-
- if (!cif)
- return -EINVAL;
-
- cif->cmdcnt = 0;
- cif->cmdtime = 0;
- cif->cmdtimemax = 0;
- cif->cmdtimemin = 0xffffffff;
- cif->errcnt = 0;
- cif->is_reset = 0;
-
- tries = RESET_TRIES;
- do {
- err = try_to_load_firmware(cif, chip);
- if (err < 0)
- return err;
- } while (!err && --tries);
-
- SEND_SACR(cif, 0, AC97_RESET);
- SEND_RACR(cif, AC97_RESET, &rptr);
- snd_printdd("AC97: 0x%x 0x%x\n", rptr.retlongs[0], rptr.retlongs[1]);
-
- SEND_PLST(cif, 0);
- SEND_SLST(cif, 0);
- SEND_DLST(cif, 0);
- SEND_ALST(cif, 0);
- SEND_KDMA(cif);
-
- writearm(cif, 0x301F8, 1, 1);
- writearm(cif, 0x301F4, 1, 1);
-
- SEND_LSEL(cif, MODEM_CMD, 0, 0, MODEM_INTDEC, MODEM_MERGER,
- MODEM_SPLITTER, MODEM_MIXER);
- setmixer(cif, MODEM_MIXER, 0x7fff, 0x7fff);
- alloclbuspath(cif, ARM2LBUS_FIFO13, lbus_play_modem, NULL, NULL);
-
- SEND_LSEL(cif, FM_CMD, 0, 0, FM_INTDEC, FM_MERGER, FM_SPLITTER,
- FM_MIXER);
- setmixer(cif, FM_MIXER, 0x7fff, 0x7fff);
- writearm(cif, 0x30648 + FM_MIXER * 4, 0x01, 0x00000005);
- writearm(cif, 0x301A8, 0x02, 0x00000002);
- writearm(cif, 0x30264, 0x08, 0xffffffff);
- alloclbuspath(cif, OPL3_SAMPLE, lbus_play_opl3, NULL, NULL);
-
- SEND_SSRC(cif, I2S_INTDEC, 48000,
- ((u32) I2S_RATE * 65536) / 48000,
- ((u32) I2S_RATE * 65536) % 48000);
- SEND_LSEL(cif, I2S_CMD0, 0, 0, I2S_INTDEC, I2S_MERGER, I2S_SPLITTER,
- I2S_MIXER);
- SEND_SI2S(cif, 1);
- alloclbuspath(cif, ARM2LBUS_FIFO0, lbus_play_i2s, NULL, NULL);
- alloclbuspath(cif, DIGITAL_MIXER_OUT0, lbus_play_out, NULL, NULL);
- alloclbuspath(cif, DIGITAL_MIXER_OUT0, lbus_play_outhp, NULL, NULL);
-
- SET_AIACK(cif->hwport);
- SET_AIE(cif->hwport);
- SET_AIACK(cif->hwport);
- cif->is_reset = 1;
-
- return 0;
-}
-
-static struct snd_pcm_hardware snd_riptide_playback = {
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID),
- .formats =
- SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8
- | SNDRV_PCM_FMTBIT_U16_LE,
- .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 5500,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (64 * 1024),
- .period_bytes_min = PAGE_SIZE >> 1,
- .period_bytes_max = PAGE_SIZE << 8,
- .periods_min = 2,
- .periods_max = 64,
- .fifo_size = 0,
-};
-static struct snd_pcm_hardware snd_riptide_capture = {
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID),
- .formats =
- SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8
- | SNDRV_PCM_FMTBIT_U16_LE,
- .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 5500,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (64 * 1024),
- .period_bytes_min = PAGE_SIZE >> 1,
- .period_bytes_max = PAGE_SIZE << 3,
- .periods_min = 2,
- .periods_max = 64,
- .fifo_size = 0,
-};
-
-static snd_pcm_uframes_t snd_riptide_pointer(struct snd_pcm_substream
- *substream)
-{
- struct snd_riptide *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct pcmhw *data = get_pcmhwdev(substream);
- struct cmdif *cif = chip->cif;
- union cmdret rptr = CMDRET_ZERO;
- snd_pcm_uframes_t ret;
-
- SEND_GPOS(cif, 0, data->id, &rptr);
- if (data->size && runtime->period_size) {
- snd_printdd
- ("pointer stream %d position 0x%x(0x%x in buffer) bytes 0x%lx(0x%lx in period) frames\n",
- data->id, rptr.retlongs[1], rptr.retlongs[1] % data->size,
- bytes_to_frames(runtime, rptr.retlongs[1]),
- bytes_to_frames(runtime,
- rptr.retlongs[1]) % runtime->period_size);
- if (rptr.retlongs[1] > data->pointer)
- ret =
- bytes_to_frames(runtime,
- rptr.retlongs[1] % data->size);
- else
- ret =
- bytes_to_frames(runtime,
- data->pointer % data->size);
- } else {
- snd_printdd("stream not started or strange parms (%d %ld)\n",
- data->size, runtime->period_size);
- ret = bytes_to_frames(runtime, 0);
- }
- return ret;
-}
-
-static int snd_riptide_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- int i, j;
- struct snd_riptide *chip = snd_pcm_substream_chip(substream);
- struct pcmhw *data = get_pcmhwdev(substream);
- struct cmdif *cif = chip->cif;
- union cmdret rptr = CMDRET_ZERO;
-
- spin_lock(&chip->lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- if (!(data->state & ST_PLAY)) {
- SEND_SSTR(cif, data->id, data->sgdlist.addr);
- SET_AIE(cif->hwport);
- data->state = ST_PLAY;
- if (data->mixer != 0xff)
- setmixer(cif, data->mixer, 0x7fff, 0x7fff);
- chip->openstreams++;
- data->oldpos = 0;
- data->pointer = 0;
- }
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- if (data->mixer != 0xff)
- setmixer(cif, data->mixer, 0, 0);
- setmixer(cif, data->mixer, 0, 0);
- SEND_KSTR(cif, data->id);
- data->state = ST_STOP;
- chip->openstreams--;
- j = 0;
- do {
- i = rptr.retlongs[1];
- SEND_GPOS(cif, 0, data->id, &rptr);
- udelay(1);
- } while (i != rptr.retlongs[1] && j++ < MAX_WRITE_RETRY);
- if (j > MAX_WRITE_RETRY)
- snd_printk(KERN_ERR "Riptide: Could not stop stream!");
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (!(data->state & ST_PAUSE)) {
- SEND_PSTR(cif, data->id);
- data->state |= ST_PAUSE;
- chip->openstreams--;
- }
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (data->state & ST_PAUSE) {
- SEND_SSTR(cif, data->id, data->sgdlist.addr);
- data->state &= ~ST_PAUSE;
- chip->openstreams++;
- }
- break;
- default:
- spin_unlock(&chip->lock);
- return -EINVAL;
- }
- spin_unlock(&chip->lock);
- return 0;
-}
-
-static int snd_riptide_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_riptide *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct pcmhw *data = get_pcmhwdev(substream);
- struct cmdif *cif = chip->cif;
- unsigned char *lbuspath = NULL;
- unsigned int rate, channels;
- int err = 0;
- snd_pcm_format_t format;
-
- if (snd_BUG_ON(!cif || !data))
- return -EINVAL;
-
- snd_printdd("prepare id %d ch: %d f:0x%x r:%d\n", data->id,
- runtime->channels, runtime->format, runtime->rate);
-
- spin_lock_irq(&chip->lock);
- channels = runtime->channels;
- format = runtime->format;
- rate = runtime->rate;
- switch (channels) {
- case 1:
- if (rate == 48000 && format == SNDRV_PCM_FORMAT_S16_LE)
- lbuspath = data->paths.noconv;
- else
- lbuspath = data->paths.mono;
- break;
- case 2:
- if (rate == 48000 && format == SNDRV_PCM_FORMAT_S16_LE)
- lbuspath = data->paths.noconv;
- else
- lbuspath = data->paths.stereo;
- break;
- }
- snd_printdd("use sgdlist at 0x%p\n",
- data->sgdlist.area);
- if (data->sgdlist.area) {
- unsigned int i, j, size, pages, f, pt, period;
- struct sgd *c, *p = NULL;
-
- size = frames_to_bytes(runtime, runtime->buffer_size);
- period = frames_to_bytes(runtime, runtime->period_size);
- f = PAGE_SIZE;
- while ((size + (f >> 1) - 1) <= (f << 7) && (f << 1) > period)
- f = f >> 1;
- pages = (size + f - 1) / f;
- data->size = size;
- data->pages = pages;
- snd_printdd
- ("create sgd size: 0x%x pages %d of size 0x%x for period 0x%x\n",
- size, pages, f, period);
- pt = 0;
- j = 0;
- for (i = 0; i < pages; i++) {
- unsigned int ofs, addr;
- c = &data->sgdbuf[i];
- if (p)
- p->dwNextLink = cpu_to_le32(data->sgdlist.addr +
- (i *
- sizeof(struct
- sgd)));
- c->dwNextLink = cpu_to_le32(data->sgdlist.addr);
- ofs = j << PAGE_SHIFT;
- addr = snd_pcm_sgbuf_get_addr(substream, ofs) + pt;
- c->dwSegPtrPhys = cpu_to_le32(addr);
- pt = (pt + f) % PAGE_SIZE;
- if (pt == 0)
- j++;
- c->dwSegLen = cpu_to_le32(f);
- c->dwStat_Ctl =
- cpu_to_le32(IEOB_ENABLE | IEOS_ENABLE |
- IEOC_ENABLE);
- p = c;
- size -= f;
- }
- data->sgdbuf[i].dwSegLen = cpu_to_le32(size);
- }
- if (lbuspath && lbuspath != data->lbuspath) {
- if (data->lbuspath)
- freelbuspath(cif, data->source, data->lbuspath);
- alloclbuspath(cif, data->source, lbuspath,
- &data->mixer, data->intdec);
- data->lbuspath = lbuspath;
- data->rate = 0;
- }
- if (data->rate != rate || data->format != format ||
- data->channels != channels) {
- data->rate = rate;
- data->format = format;
- data->channels = channels;
- if (setsampleformat
- (cif, data->mixer, data->id, channels, format)
- || setsamplerate(cif, data->intdec, rate))
- err = -EIO;
- }
- spin_unlock_irq(&chip->lock);
- return err;
-}
-
-static int
-snd_riptide_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_riptide *chip = snd_pcm_substream_chip(substream);
- struct pcmhw *data = get_pcmhwdev(substream);
- struct snd_dma_buffer *sgdlist = &data->sgdlist;
- int err;
-
- snd_printdd("hw params id %d (sgdlist: 0x%p 0x%lx %d)\n", data->id,
- sgdlist->area, (unsigned long)sgdlist->addr,
- (int)sgdlist->bytes);
- if (sgdlist->area)
- snd_dma_free_pages(sgdlist);
- if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci),
- sizeof(struct sgd) * (DESC_MAX_MASK + 1),
- sgdlist)) < 0) {
- snd_printk(KERN_ERR "Riptide: failed to alloc %d dma bytes\n",
- (int)sizeof(struct sgd) * (DESC_MAX_MASK + 1));
- return err;
- }
- data->sgdbuf = (struct sgd *)sgdlist->area;
- return snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-}
-
-static int snd_riptide_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_riptide *chip = snd_pcm_substream_chip(substream);
- struct pcmhw *data = get_pcmhwdev(substream);
- struct cmdif *cif = chip->cif;
-
- if (cif && data) {
- if (data->lbuspath)
- freelbuspath(cif, data->source, data->lbuspath);
- data->lbuspath = NULL;
- data->source = 0xff;
- data->intdec[0] = 0xff;
- data->intdec[1] = 0xff;
-
- if (data->sgdlist.area) {
- snd_dma_free_pages(&data->sgdlist);
- data->sgdlist.area = NULL;
- }
- }
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_riptide_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_riptide *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct pcmhw *data;
- int sub_num = substream->number;
-
- chip->playback_substream[sub_num] = substream;
- runtime->hw = snd_riptide_playback;
-
- data = kzalloc(sizeof(struct pcmhw), GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
- data->paths = lbus_play_paths[sub_num];
- data->id = play_ids[sub_num];
- data->source = play_sources[sub_num];
- data->intdec[0] = 0xff;
- data->intdec[1] = 0xff;
- data->state = ST_STOP;
- runtime->private_data = data;
- return snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
-}
-
-static int snd_riptide_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_riptide *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct pcmhw *data;
-
- chip->capture_substream = substream;
- runtime->hw = snd_riptide_capture;
-
- data = kzalloc(sizeof(struct pcmhw), GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
- data->paths = lbus_rec_path;
- data->id = PADC;
- data->source = ACLNK2PADC;
- data->intdec[0] = 0xff;
- data->intdec[1] = 0xff;
- data->state = ST_STOP;
- runtime->private_data = data;
- return snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
-}
-
-static int snd_riptide_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_riptide *chip = snd_pcm_substream_chip(substream);
- struct pcmhw *data = get_pcmhwdev(substream);
- int sub_num = substream->number;
-
- substream->runtime->private_data = NULL;
- chip->playback_substream[sub_num] = NULL;
- kfree(data);
- return 0;
-}
-
-static int snd_riptide_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_riptide *chip = snd_pcm_substream_chip(substream);
- struct pcmhw *data = get_pcmhwdev(substream);
-
- substream->runtime->private_data = NULL;
- chip->capture_substream = NULL;
- kfree(data);
- return 0;
-}
-
-static struct snd_pcm_ops snd_riptide_playback_ops = {
- .open = snd_riptide_playback_open,
- .close = snd_riptide_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_riptide_hw_params,
- .hw_free = snd_riptide_hw_free,
- .prepare = snd_riptide_prepare,
- .page = snd_pcm_sgbuf_ops_page,
- .trigger = snd_riptide_trigger,
- .pointer = snd_riptide_pointer,
-};
-static struct snd_pcm_ops snd_riptide_capture_ops = {
- .open = snd_riptide_capture_open,
- .close = snd_riptide_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_riptide_hw_params,
- .hw_free = snd_riptide_hw_free,
- .prepare = snd_riptide_prepare,
- .page = snd_pcm_sgbuf_ops_page,
- .trigger = snd_riptide_trigger,
- .pointer = snd_riptide_pointer,
-};
-
-static int __devinit
-snd_riptide_pcm(struct snd_riptide *chip, int device, struct snd_pcm **rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
- if ((err =
- snd_pcm_new(chip->card, "RIPTIDE", device, PLAYBACK_SUBSTREAMS, 1,
- &pcm)) < 0)
- return err;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_riptide_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_riptide_capture_ops);
- pcm->private_data = chip;
- pcm->info_flags = 0;
- strcpy(pcm->name, "RIPTIDE");
- chip->pcm = pcm;
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(chip->pci),
- 64 * 1024, 128 * 1024);
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-static irqreturn_t
-snd_riptide_interrupt(int irq, void *dev_id)
-{
- struct snd_riptide *chip = dev_id;
- struct cmdif *cif = chip->cif;
-
- if (cif) {
- chip->received_irqs++;
- if (IS_EOBIRQ(cif->hwport) || IS_EOSIRQ(cif->hwport) ||
- IS_EOCIRQ(cif->hwport)) {
- chip->handled_irqs++;
- tasklet_schedule(&chip->riptide_tq);
- }
- if (chip->rmidi && IS_MPUIRQ(cif->hwport)) {
- chip->handled_irqs++;
- snd_mpu401_uart_interrupt(irq,
- chip->rmidi->private_data);
- }
- SET_AIACK(cif->hwport);
- }
- return IRQ_HANDLED;
-}
-
-static void
-snd_riptide_codec_write(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short val)
-{
- struct snd_riptide *chip = ac97->private_data;
- struct cmdif *cif = chip->cif;
- union cmdret rptr = CMDRET_ZERO;
- int i = 0;
-
- if (snd_BUG_ON(!cif))
- return;
-
- snd_printdd("Write AC97 reg 0x%x 0x%x\n", reg, val);
- do {
- SEND_SACR(cif, val, reg);
- SEND_RACR(cif, reg, &rptr);
- } while (rptr.retwords[1] != val && i++ < MAX_WRITE_RETRY);
- if (i > MAX_WRITE_RETRY)
- snd_printdd("Write AC97 reg failed\n");
-}
-
-static unsigned short snd_riptide_codec_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- struct snd_riptide *chip = ac97->private_data;
- struct cmdif *cif = chip->cif;
- union cmdret rptr = CMDRET_ZERO;
-
- if (snd_BUG_ON(!cif))
- return 0;
-
- if (SEND_RACR(cif, reg, &rptr) != 0)
- SEND_RACR(cif, reg, &rptr);
- snd_printdd("Read AC97 reg 0x%x got 0x%x\n", reg, rptr.retwords[1]);
- return rptr.retwords[1];
-}
-
-static int snd_riptide_initialize(struct snd_riptide *chip)
-{
- struct cmdif *cif;
- unsigned int device_id;
- int err;
-
- if (snd_BUG_ON(!chip))
- return -EINVAL;
-
- cif = chip->cif;
- if (!cif) {
- if ((cif = kzalloc(sizeof(struct cmdif), GFP_KERNEL)) == NULL)
- return -ENOMEM;
- cif->hwport = (struct riptideport *)chip->port;
- spin_lock_init(&cif->lock);
- chip->cif = cif;
- }
- cif->is_reset = 0;
- if ((err = riptide_reset(cif, chip)) != 0)
- return err;
- device_id = chip->device_id;
- switch (device_id) {
- case 0x4310:
- case 0x4320:
- case 0x4330:
- snd_printdd("Modem enable?\n");
- SEND_SETDPLL(cif);
- break;
- }
- snd_printdd("Enabling MPU IRQs\n");
- if (chip->rmidi)
- SET_EMPUIRQ(cif->hwport);
- return err;
-}
-
-static int snd_riptide_free(struct snd_riptide *chip)
-{
- struct cmdif *cif;
-
- if (!chip)
- return 0;
-
- if ((cif = chip->cif)) {
- SET_GRESET(cif->hwport);
- udelay(100);
- UNSET_GRESET(cif->hwport);
- kfree(chip->cif);
- }
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
- if (chip->fw_entry)
- release_firmware(chip->fw_entry);
- release_and_free_resource(chip->res_port);
- kfree(chip);
- return 0;
-}
-
-static int snd_riptide_dev_free(struct snd_device *device)
-{
- struct snd_riptide *chip = device->device_data;
-
- return snd_riptide_free(chip);
-}
-
-static int __devinit
-snd_riptide_create(struct snd_card *card, struct pci_dev *pci,
- struct snd_riptide **rchip)
-{
- struct snd_riptide *chip;
- struct riptideport *hwport;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_riptide_dev_free,
- };
-
- *rchip = NULL;
- if ((err = pci_enable_device(pci)) < 0)
- return err;
- if (!(chip = kzalloc(sizeof(struct snd_riptide), GFP_KERNEL)))
- return -ENOMEM;
-
- spin_lock_init(&chip->lock);
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
- chip->openstreams = 0;
- chip->port = pci_resource_start(pci, 0);
- chip->received_irqs = 0;
- chip->handled_irqs = 0;
- chip->cif = NULL;
- tasklet_init(&chip->riptide_tq, riptide_handleirq, (unsigned long)chip);
-
- if ((chip->res_port =
- request_region(chip->port, 64, "RIPTIDE")) == NULL) {
- snd_printk(KERN_ERR
- "Riptide: unable to grab region 0x%lx-0x%lx\n",
- chip->port, chip->port + 64 - 1);
- snd_riptide_free(chip);
- return -EBUSY;
- }
- hwport = (struct riptideport *)chip->port;
- UNSET_AIE(hwport);
-
- if (request_irq(pci->irq, snd_riptide_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
- snd_printk(KERN_ERR "Riptide: unable to grab IRQ %d\n",
- pci->irq);
- snd_riptide_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
- chip->device_id = pci->device;
- pci_set_master(pci);
- if ((err = snd_riptide_initialize(chip)) < 0) {
- snd_riptide_free(chip);
- return err;
- }
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_riptide_free(chip);
- return err;
- }
-
- snd_card_set_dev(card, &pci->dev);
-
- *rchip = chip;
- return 0;
-}
-
-static void
-snd_riptide_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_riptide *chip = entry->private_data;
- struct pcmhw *data;
- int i;
- struct cmdif *cif = NULL;
- unsigned char p[256];
- unsigned short rval = 0, lval = 0;
- unsigned int rate;
-
- if (!chip)
- return;
-
- snd_iprintf(buffer, "%s\n\n", chip->card->longname);
- snd_iprintf(buffer, "Device ID: 0x%x\nReceived IRQs: (%ld)%ld\nPorts:",
- chip->device_id, chip->handled_irqs, chip->received_irqs);
- for (i = 0; i < 64; i += 4)
- snd_iprintf(buffer, "%c%02x: %08x",
- (i % 16) ? ' ' : '\n', i, inl(chip->port + i));
- if ((cif = chip->cif)) {
- snd_iprintf(buffer,
- "\nVersion: ASIC: %d CODEC: %d AUXDSP: %d PROG: %d",
- chip->firmware.firmware.ASIC,
- chip->firmware.firmware.CODEC,
- chip->firmware.firmware.AUXDSP,
- chip->firmware.firmware.PROG);
- snd_iprintf(buffer, "\nDigital mixer:");
- for (i = 0; i < 12; i++) {
- getmixer(cif, i, &rval, &lval);
- snd_iprintf(buffer, "\n %d: %d %d", i, rval, lval);
- }
- snd_iprintf(buffer,
- "\nARM Commands num: %d failed: %d time: %d max: %d min: %d",
- cif->cmdcnt, cif->errcnt,
- cif->cmdtime, cif->cmdtimemax, cif->cmdtimemin);
- }
- snd_iprintf(buffer, "\nOpen streams %d:\n", chip->openstreams);
- for (i = 0; i < PLAYBACK_SUBSTREAMS; i++) {
- if (chip->playback_substream[i]
- && chip->playback_substream[i]->runtime
- && (data =
- chip->playback_substream[i]->runtime->private_data)) {
- snd_iprintf(buffer,
- "stream: %d mixer: %d source: %d (%d,%d)\n",
- data->id, data->mixer, data->source,
- data->intdec[0], data->intdec[1]);
- if (!(getsamplerate(cif, data->intdec, &rate)))
- snd_iprintf(buffer, "rate: %d\n", rate);
- }
- }
- if (chip->capture_substream
- && chip->capture_substream->runtime
- && (data = chip->capture_substream->runtime->private_data)) {
- snd_iprintf(buffer,
- "stream: %d mixer: %d source: %d (%d,%d)\n",
- data->id, data->mixer,
- data->source, data->intdec[0], data->intdec[1]);
- if (!(getsamplerate(cif, data->intdec, &rate)))
- snd_iprintf(buffer, "rate: %d\n", rate);
- }
- snd_iprintf(buffer, "Paths:\n");
- i = getpaths(cif, p);
- while (i >= 2) {
- i -= 2;
- snd_iprintf(buffer, "%x->%x ", p[i], p[i + 1]);
- }
- snd_iprintf(buffer, "\n");
-}
-
-static void __devinit snd_riptide_proc_init(struct snd_riptide *chip)
-{
- struct snd_info_entry *entry;
-
- if (!snd_card_proc_new(chip->card, "riptide", &entry))
- snd_info_set_text_ops(entry, chip, snd_riptide_proc_read);
-}
-
-static int __devinit snd_riptide_mixer(struct snd_riptide *chip)
-{
- struct snd_ac97_bus *pbus;
- struct snd_ac97_template ac97;
- int err = 0;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_riptide_codec_write,
- .read = snd_riptide_codec_read,
- };
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = chip;
- ac97.scaps = AC97_SCAP_SKIP_MODEM;
-
- if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
- return err;
-
- chip->ac97_bus = pbus;
- ac97.pci = chip->pci;
- if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0)
- return err;
- return err;
-}
-
-#ifdef SUPPORT_JOYSTICK
-
-static int __devinit
-snd_riptide_joystick_probe(struct pci_dev *pci, const struct pci_device_id *id)
-{
- static int dev;
- struct gameport *gameport;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- if (!joystick_port[dev++])
- return 0;
-
- gameport = gameport_allocate_port();
- if (!gameport)
- return -ENOMEM;
- if (!request_region(joystick_port[dev], 8, "Riptide gameport")) {
- snd_printk(KERN_WARNING
- "Riptide: cannot grab gameport 0x%x\n",
- joystick_port[dev]);
- gameport_free_port(gameport);
- return -EBUSY;
- }
-
- gameport->io = joystick_port[dev];
- gameport_register_port(gameport);
- pci_set_drvdata(pci, gameport);
- return 0;
-}
-
-static void __devexit snd_riptide_joystick_remove(struct pci_dev *pci)
-{
- struct gameport *gameport = pci_get_drvdata(pci);
- if (gameport) {
- release_region(gameport->io, 8);
- gameport_unregister_port(gameport);
- pci_set_drvdata(pci, NULL);
- }
-}
-#endif
-
-static int __devinit
-snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct snd_riptide *chip;
- unsigned short val;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
- err = snd_riptide_create(card, pci, &chip);
- if (err < 0)
- goto error;
- card->private_data = chip;
- err = snd_riptide_pcm(chip, 0, NULL);
- if (err < 0)
- goto error;
- err = snd_riptide_mixer(chip);
- if (err < 0)
- goto error;
-
- val = LEGACY_ENABLE_ALL;
- if (opl3_port[dev])
- val |= LEGACY_ENABLE_FM;
-#ifdef SUPPORT_JOYSTICK
- if (joystick_port[dev])
- val |= LEGACY_ENABLE_GAMEPORT;
-#endif
- if (mpu_port[dev])
- val |= LEGACY_ENABLE_MPU_INT | LEGACY_ENABLE_MPU;
- val |= (chip->irq << 4) & 0xf0;
- pci_write_config_word(chip->pci, PCI_EXT_Legacy_Mask, val);
- if (mpu_port[dev]) {
- val = mpu_port[dev];
- pci_write_config_word(chip->pci, PCI_EXT_MPU_Base, val);
- err = snd_mpu401_uart_new(card, 0, MPU401_HW_RIPTIDE,
- val, MPU401_INFO_IRQ_HOOK, -1,
- &chip->rmidi);
- if (err < 0)
- snd_printk(KERN_WARNING
- "Riptide: Can't Allocate MPU at 0x%x\n",
- val);
- else
- chip->mpuaddr = val;
- }
- if (opl3_port[dev]) {
- val = opl3_port[dev];
- pci_write_config_word(chip->pci, PCI_EXT_FM_Base, val);
- err = snd_opl3_create(card, val, val + 2,
- OPL3_HW_RIPTIDE, 0, &chip->opl3);
- if (err < 0)
- snd_printk(KERN_WARNING
- "Riptide: Can't Allocate OPL3 at 0x%x\n",
- val);
- else {
- chip->opladdr = val;
- err = snd_opl3_hwdep_new(chip->opl3, 0, 1, NULL);
- if (err < 0)
- snd_printk(KERN_WARNING
- "Riptide: Can't Allocate OPL3-HWDEP\n");
- }
- }
-#ifdef SUPPORT_JOYSTICK
- if (joystick_port[dev]) {
- val = joystick_port[dev];
- pci_write_config_word(chip->pci, PCI_EXT_Game_Base, val);
- chip->gameaddr = val;
- }
-#endif
-
- strcpy(card->driver, "RIPTIDE");
- strcpy(card->shortname, "Riptide");
-#ifdef SUPPORT_JOYSTICK
- snprintf(card->longname, sizeof(card->longname),
- "%s at 0x%lx, irq %i mpu 0x%x opl3 0x%x gameport 0x%x",
- card->shortname, chip->port, chip->irq, chip->mpuaddr,
- chip->opladdr, chip->gameaddr);
-#else
- snprintf(card->longname, sizeof(card->longname),
- "%s at 0x%lx, irq %i mpu 0x%x opl3 0x%x",
- card->shortname, chip->port, chip->irq, chip->mpuaddr,
- chip->opladdr);
-#endif
- snd_riptide_proc_init(chip);
- err = snd_card_register(card);
- if (err < 0)
- goto error;
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-
- error:
- snd_card_free(card);
- return err;
-}
-
-static void __devexit snd_card_riptide_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_riptide_ids,
- .probe = snd_card_riptide_probe,
- .remove = __devexit_p(snd_card_riptide_remove),
-#ifdef CONFIG_PM
- .suspend = riptide_suspend,
- .resume = riptide_resume,
-#endif
-};
-
-#ifdef SUPPORT_JOYSTICK
-static struct pci_driver joystick_driver = {
- .name = KBUILD_MODNAME "-joystick",
- .id_table = snd_riptide_joystick_ids,
- .probe = snd_riptide_joystick_probe,
- .remove = __devexit_p(snd_riptide_joystick_remove),
-};
-#endif
-
-static int __init alsa_card_riptide_init(void)
-{
- int err;
- err = pci_register_driver(&driver);
- if (err < 0)
- return err;
-#if defined(SUPPORT_JOYSTICK)
- err = pci_register_driver(&joystick_driver);
- /* On failure unregister formerly registered audio driver */
- if (err < 0)
- pci_unregister_driver(&driver);
-#endif
- return err;
-}
-
-static void __exit alsa_card_riptide_exit(void)
-{
- pci_unregister_driver(&driver);
-#if defined(SUPPORT_JOYSTICK)
- pci_unregister_driver(&joystick_driver);
-#endif
-}
-
-module_init(alsa_card_riptide_init);
-module_exit(alsa_card_riptide_exit);
diff --git a/ANDROID_3.4.5/sound/pci/rme32.c b/ANDROID_3.4.5/sound/pci/rme32.c
deleted file mode 100644
index b4819d5e..00000000
--- a/ANDROID_3.4.5/sound/pci/rme32.c
+++ /dev/null
@@ -1,2005 +0,0 @@
-/*
- * ALSA driver for RME Digi32, Digi32/8 and Digi32 PRO audio interfaces
- *
- * Copyright (c) 2002-2004 Martin Langer <martin-langer@gmx.de>,
- * Pilo Chambert <pilo.c@wanadoo.fr>
- *
- * Thanks to : Anders Torger <torger@ludd.luth.se>,
- * Henk Hesselink <henk@anda.nl>
- * for writing the digi96-driver
- * and RME for all informations.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- * ****************************************************************************
- *
- * Note #1 "Sek'd models" ................................... martin 2002-12-07
- *
- * Identical soundcards by Sek'd were labeled:
- * RME Digi 32 = Sek'd Prodif 32
- * RME Digi 32 Pro = Sek'd Prodif 96
- * RME Digi 32/8 = Sek'd Prodif Gold
- *
- * ****************************************************************************
- *
- * Note #2 "full duplex mode" ............................... martin 2002-12-07
- *
- * Full duplex doesn't work. All cards (32, 32/8, 32Pro) are working identical
- * in this mode. Rec data and play data are using the same buffer therefore. At
- * first you have got the playing bits in the buffer and then (after playing
- * them) they were overwitten by the captured sound of the CS8412/14. Both
- * modes (play/record) are running harmonically hand in hand in the same buffer
- * and you have only one start bit plus one interrupt bit to control this
- * paired action.
- * This is opposite to the latter rme96 where playing and capturing is totally
- * separated and so their full duplex mode is supported by alsa (using two
- * start bits and two interrupts for two different buffers).
- * But due to the wrong sequence of playing and capturing ALSA shows no solved
- * full duplex support for the rme32 at the moment. That's bad, but I'm not
- * able to solve it. Are you motivated enough to solve this problem now? Your
- * patch would be welcome!
- *
- * ****************************************************************************
- *
- * "The story after the long seeking" -- tiwai
- *
- * Ok, the situation regarding the full duplex is now improved a bit.
- * In the fullduplex mode (given by the module parameter), the hardware buffer
- * is split to halves for read and write directions at the DMA pointer.
- * That is, the half above the current DMA pointer is used for write, and
- * the half below is used for read. To mangle this strange behavior, an
- * software intermediate buffer is introduced. This is, of course, not good
- * from the viewpoint of the data transfer efficiency. However, this allows
- * you to use arbitrary buffer sizes, instead of the fixed I/O buffer size.
- *
- * ****************************************************************************
- */
-
-
-#include <linux/delay.h>
-#include <linux/gfp.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/pcm-indirect.h>
-#include <sound/asoundef.h>
-#include <sound/initval.h>
-
-#include <asm/io.h>
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static bool fullduplex[SNDRV_CARDS]; // = {[0 ... (SNDRV_CARDS - 1)] = 1};
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for RME Digi32 soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for RME Digi32 soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable RME Digi32 soundcard.");
-module_param_array(fullduplex, bool, NULL, 0444);
-MODULE_PARM_DESC(fullduplex, "Support full-duplex mode.");
-MODULE_AUTHOR("Martin Langer <martin-langer@gmx.de>, Pilo Chambert <pilo.c@wanadoo.fr>");
-MODULE_DESCRIPTION("RME Digi32, Digi32/8, Digi32 PRO");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{RME,Digi32}," "{RME,Digi32/8}," "{RME,Digi32 PRO}}");
-
-/* Defines for RME Digi32 series */
-#define RME32_SPDIF_NCHANNELS 2
-
-/* Playback and capture buffer size */
-#define RME32_BUFFER_SIZE 0x20000
-
-/* IO area size */
-#define RME32_IO_SIZE 0x30000
-
-/* IO area offsets */
-#define RME32_IO_DATA_BUFFER 0x0
-#define RME32_IO_CONTROL_REGISTER 0x20000
-#define RME32_IO_GET_POS 0x20000
-#define RME32_IO_CONFIRM_ACTION_IRQ 0x20004
-#define RME32_IO_RESET_POS 0x20100
-
-/* Write control register bits */
-#define RME32_WCR_START (1 << 0) /* startbit */
-#define RME32_WCR_MONO (1 << 1) /* 0=stereo, 1=mono
- Setting the whole card to mono
- doesn't seem to be very useful.
- A software-solution can handle
- full-duplex with one direction in
- stereo and the other way in mono.
- So, the hardware should work all
- the time in stereo! */
-#define RME32_WCR_MODE24 (1 << 2) /* 0=16bit, 1=32bit */
-#define RME32_WCR_SEL (1 << 3) /* 0=input on output, 1=normal playback/capture */
-#define RME32_WCR_FREQ_0 (1 << 4) /* frequency (play) */
-#define RME32_WCR_FREQ_1 (1 << 5)
-#define RME32_WCR_INP_0 (1 << 6) /* input switch */
-#define RME32_WCR_INP_1 (1 << 7)
-#define RME32_WCR_RESET (1 << 8) /* Reset address */
-#define RME32_WCR_MUTE (1 << 9) /* digital mute for output */
-#define RME32_WCR_PRO (1 << 10) /* 1=professional, 0=consumer */
-#define RME32_WCR_DS_BM (1 << 11) /* 1=DoubleSpeed (only PRO-Version); 1=BlockMode (only Adat-Version) */
-#define RME32_WCR_ADAT (1 << 12) /* Adat Mode (only Adat-Version) */
-#define RME32_WCR_AUTOSYNC (1 << 13) /* AutoSync */
-#define RME32_WCR_PD (1 << 14) /* DAC Reset (only PRO-Version) */
-#define RME32_WCR_EMP (1 << 15) /* 1=Emphasis on (only PRO-Version) */
-
-#define RME32_WCR_BITPOS_FREQ_0 4
-#define RME32_WCR_BITPOS_FREQ_1 5
-#define RME32_WCR_BITPOS_INP_0 6
-#define RME32_WCR_BITPOS_INP_1 7
-
-/* Read control register bits */
-#define RME32_RCR_AUDIO_ADDR_MASK 0x1ffff
-#define RME32_RCR_LOCK (1 << 23) /* 1=locked, 0=not locked */
-#define RME32_RCR_ERF (1 << 26) /* 1=Error, 0=no Error */
-#define RME32_RCR_FREQ_0 (1 << 27) /* CS841x frequency (record) */
-#define RME32_RCR_FREQ_1 (1 << 28)
-#define RME32_RCR_FREQ_2 (1 << 29)
-#define RME32_RCR_KMODE (1 << 30) /* card mode: 1=PLL, 0=quartz */
-#define RME32_RCR_IRQ (1 << 31) /* interrupt */
-
-#define RME32_RCR_BITPOS_F0 27
-#define RME32_RCR_BITPOS_F1 28
-#define RME32_RCR_BITPOS_F2 29
-
-/* Input types */
-#define RME32_INPUT_OPTICAL 0
-#define RME32_INPUT_COAXIAL 1
-#define RME32_INPUT_INTERNAL 2
-#define RME32_INPUT_XLR 3
-
-/* Clock modes */
-#define RME32_CLOCKMODE_SLAVE 0
-#define RME32_CLOCKMODE_MASTER_32 1
-#define RME32_CLOCKMODE_MASTER_44 2
-#define RME32_CLOCKMODE_MASTER_48 3
-
-/* Block sizes in bytes */
-#define RME32_BLOCK_SIZE 8192
-
-/* Software intermediate buffer (max) size */
-#define RME32_MID_BUFFER_SIZE (1024*1024)
-
-/* Hardware revisions */
-#define RME32_32_REVISION 192
-#define RME32_328_REVISION_OLD 100
-#define RME32_328_REVISION_NEW 101
-#define RME32_PRO_REVISION_WITH_8412 192
-#define RME32_PRO_REVISION_WITH_8414 150
-
-
-struct rme32 {
- spinlock_t lock;
- int irq;
- unsigned long port;
- void __iomem *iobase;
-
- u32 wcreg; /* cached write control register value */
- u32 wcreg_spdif; /* S/PDIF setup */
- u32 wcreg_spdif_stream; /* S/PDIF setup (temporary) */
- u32 rcreg; /* cached read control register value */
-
- u8 rev; /* card revision number */
-
- struct snd_pcm_substream *playback_substream;
- struct snd_pcm_substream *capture_substream;
-
- int playback_frlog; /* log2 of framesize */
- int capture_frlog;
-
- size_t playback_periodsize; /* in bytes, zero if not used */
- size_t capture_periodsize; /* in bytes, zero if not used */
-
- unsigned int fullduplex_mode;
- int running;
-
- struct snd_pcm_indirect playback_pcm;
- struct snd_pcm_indirect capture_pcm;
-
- struct snd_card *card;
- struct snd_pcm *spdif_pcm;
- struct snd_pcm *adat_pcm;
- struct pci_dev *pci;
- struct snd_kcontrol *spdif_ctl;
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_rme32_ids) = {
- {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32), 0,},
- {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_8), 0,},
- {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_PRO), 0,},
- {0,}
-};
-
-MODULE_DEVICE_TABLE(pci, snd_rme32_ids);
-
-#define RME32_ISWORKING(rme32) ((rme32)->wcreg & RME32_WCR_START)
-#define RME32_PRO_WITH_8414(rme32) ((rme32)->pci->device == PCI_DEVICE_ID_RME_DIGI32_PRO && (rme32)->rev == RME32_PRO_REVISION_WITH_8414)
-
-static int snd_rme32_playback_prepare(struct snd_pcm_substream *substream);
-
-static int snd_rme32_capture_prepare(struct snd_pcm_substream *substream);
-
-static int snd_rme32_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
-
-static void snd_rme32_proc_init(struct rme32 * rme32);
-
-static int snd_rme32_create_switches(struct snd_card *card, struct rme32 * rme32);
-
-static inline unsigned int snd_rme32_pcm_byteptr(struct rme32 * rme32)
-{
- return (readl(rme32->iobase + RME32_IO_GET_POS)
- & RME32_RCR_AUDIO_ADDR_MASK);
-}
-
-/* silence callback for halfduplex mode */
-static int snd_rme32_playback_silence(struct snd_pcm_substream *substream, int channel, /* not used (interleaved data) */
- snd_pcm_uframes_t pos,
- snd_pcm_uframes_t count)
-{
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- count <<= rme32->playback_frlog;
- pos <<= rme32->playback_frlog;
- memset_io(rme32->iobase + RME32_IO_DATA_BUFFER + pos, 0, count);
- return 0;
-}
-
-/* copy callback for halfduplex mode */
-static int snd_rme32_playback_copy(struct snd_pcm_substream *substream, int channel, /* not used (interleaved data) */
- snd_pcm_uframes_t pos,
- void __user *src, snd_pcm_uframes_t count)
-{
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- count <<= rme32->playback_frlog;
- pos <<= rme32->playback_frlog;
- if (copy_from_user_toio(rme32->iobase + RME32_IO_DATA_BUFFER + pos,
- src, count))
- return -EFAULT;
- return 0;
-}
-
-/* copy callback for halfduplex mode */
-static int snd_rme32_capture_copy(struct snd_pcm_substream *substream, int channel, /* not used (interleaved data) */
- snd_pcm_uframes_t pos,
- void __user *dst, snd_pcm_uframes_t count)
-{
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- count <<= rme32->capture_frlog;
- pos <<= rme32->capture_frlog;
- if (copy_to_user_fromio(dst,
- rme32->iobase + RME32_IO_DATA_BUFFER + pos,
- count))
- return -EFAULT;
- return 0;
-}
-
-/*
- * SPDIF I/O capabilities (half-duplex mode)
- */
-static struct snd_pcm_hardware snd_rme32_spdif_info = {
- .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START),
- .formats = (SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S32_LE),
- .rates = (SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000),
- .rate_min = 32000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = RME32_BUFFER_SIZE,
- .period_bytes_min = RME32_BLOCK_SIZE,
- .period_bytes_max = RME32_BLOCK_SIZE,
- .periods_min = RME32_BUFFER_SIZE / RME32_BLOCK_SIZE,
- .periods_max = RME32_BUFFER_SIZE / RME32_BLOCK_SIZE,
- .fifo_size = 0,
-};
-
-/*
- * ADAT I/O capabilities (half-duplex mode)
- */
-static struct snd_pcm_hardware snd_rme32_adat_info =
-{
- .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START),
- .formats= SNDRV_PCM_FMTBIT_S16_LE,
- .rates = (SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000),
- .rate_min = 44100,
- .rate_max = 48000,
- .channels_min = 8,
- .channels_max = 8,
- .buffer_bytes_max = RME32_BUFFER_SIZE,
- .period_bytes_min = RME32_BLOCK_SIZE,
- .period_bytes_max = RME32_BLOCK_SIZE,
- .periods_min = RME32_BUFFER_SIZE / RME32_BLOCK_SIZE,
- .periods_max = RME32_BUFFER_SIZE / RME32_BLOCK_SIZE,
- .fifo_size = 0,
-};
-
-/*
- * SPDIF I/O capabilities (full-duplex mode)
- */
-static struct snd_pcm_hardware snd_rme32_spdif_fd_info = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START),
- .formats = (SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S32_LE),
- .rates = (SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000),
- .rate_min = 32000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = RME32_MID_BUFFER_SIZE,
- .period_bytes_min = RME32_BLOCK_SIZE,
- .period_bytes_max = RME32_BLOCK_SIZE,
- .periods_min = 2,
- .periods_max = RME32_MID_BUFFER_SIZE / RME32_BLOCK_SIZE,
- .fifo_size = 0,
-};
-
-/*
- * ADAT I/O capabilities (full-duplex mode)
- */
-static struct snd_pcm_hardware snd_rme32_adat_fd_info =
-{
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START),
- .formats= SNDRV_PCM_FMTBIT_S16_LE,
- .rates = (SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000),
- .rate_min = 44100,
- .rate_max = 48000,
- .channels_min = 8,
- .channels_max = 8,
- .buffer_bytes_max = RME32_MID_BUFFER_SIZE,
- .period_bytes_min = RME32_BLOCK_SIZE,
- .period_bytes_max = RME32_BLOCK_SIZE,
- .periods_min = 2,
- .periods_max = RME32_MID_BUFFER_SIZE / RME32_BLOCK_SIZE,
- .fifo_size = 0,
-};
-
-static void snd_rme32_reset_dac(struct rme32 *rme32)
-{
- writel(rme32->wcreg | RME32_WCR_PD,
- rme32->iobase + RME32_IO_CONTROL_REGISTER);
- writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
-}
-
-static int snd_rme32_playback_getrate(struct rme32 * rme32)
-{
- int rate;
-
- rate = ((rme32->wcreg >> RME32_WCR_BITPOS_FREQ_0) & 1) +
- (((rme32->wcreg >> RME32_WCR_BITPOS_FREQ_1) & 1) << 1);
- switch (rate) {
- case 1:
- rate = 32000;
- break;
- case 2:
- rate = 44100;
- break;
- case 3:
- rate = 48000;
- break;
- default:
- return -1;
- }
- return (rme32->wcreg & RME32_WCR_DS_BM) ? rate << 1 : rate;
-}
-
-static int snd_rme32_capture_getrate(struct rme32 * rme32, int *is_adat)
-{
- int n;
-
- *is_adat = 0;
- if (rme32->rcreg & RME32_RCR_LOCK) {
- /* ADAT rate */
- *is_adat = 1;
- }
- if (rme32->rcreg & RME32_RCR_ERF) {
- return -1;
- }
-
- /* S/PDIF rate */
- n = ((rme32->rcreg >> RME32_RCR_BITPOS_F0) & 1) +
- (((rme32->rcreg >> RME32_RCR_BITPOS_F1) & 1) << 1) +
- (((rme32->rcreg >> RME32_RCR_BITPOS_F2) & 1) << 2);
-
- if (RME32_PRO_WITH_8414(rme32))
- switch (n) { /* supporting the CS8414 */
- case 0:
- case 1:
- case 2:
- return -1;
- case 3:
- return 96000;
- case 4:
- return 88200;
- case 5:
- return 48000;
- case 6:
- return 44100;
- case 7:
- return 32000;
- default:
- return -1;
- break;
- }
- else
- switch (n) { /* supporting the CS8412 */
- case 0:
- return -1;
- case 1:
- return 48000;
- case 2:
- return 44100;
- case 3:
- return 32000;
- case 4:
- return 48000;
- case 5:
- return 44100;
- case 6:
- return 44056;
- case 7:
- return 32000;
- default:
- break;
- }
- return -1;
-}
-
-static int snd_rme32_playback_setrate(struct rme32 * rme32, int rate)
-{
- int ds;
-
- ds = rme32->wcreg & RME32_WCR_DS_BM;
- switch (rate) {
- case 32000:
- rme32->wcreg &= ~RME32_WCR_DS_BM;
- rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) &
- ~RME32_WCR_FREQ_1;
- break;
- case 44100:
- rme32->wcreg &= ~RME32_WCR_DS_BM;
- rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_1) &
- ~RME32_WCR_FREQ_0;
- break;
- case 48000:
- rme32->wcreg &= ~RME32_WCR_DS_BM;
- rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) |
- RME32_WCR_FREQ_1;
- break;
- case 64000:
- if (rme32->pci->device != PCI_DEVICE_ID_RME_DIGI32_PRO)
- return -EINVAL;
- rme32->wcreg |= RME32_WCR_DS_BM;
- rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) &
- ~RME32_WCR_FREQ_1;
- break;
- case 88200:
- if (rme32->pci->device != PCI_DEVICE_ID_RME_DIGI32_PRO)
- return -EINVAL;
- rme32->wcreg |= RME32_WCR_DS_BM;
- rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_1) &
- ~RME32_WCR_FREQ_0;
- break;
- case 96000:
- if (rme32->pci->device != PCI_DEVICE_ID_RME_DIGI32_PRO)
- return -EINVAL;
- rme32->wcreg |= RME32_WCR_DS_BM;
- rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) |
- RME32_WCR_FREQ_1;
- break;
- default:
- return -EINVAL;
- }
- if ((!ds && rme32->wcreg & RME32_WCR_DS_BM) ||
- (ds && !(rme32->wcreg & RME32_WCR_DS_BM)))
- {
- /* change to/from double-speed: reset the DAC (if available) */
- snd_rme32_reset_dac(rme32);
- } else {
- writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
- }
- return 0;
-}
-
-static int snd_rme32_setclockmode(struct rme32 * rme32, int mode)
-{
- switch (mode) {
- case RME32_CLOCKMODE_SLAVE:
- /* AutoSync */
- rme32->wcreg = (rme32->wcreg & ~RME32_WCR_FREQ_0) &
- ~RME32_WCR_FREQ_1;
- break;
- case RME32_CLOCKMODE_MASTER_32:
- /* Internal 32.0kHz */
- rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) &
- ~RME32_WCR_FREQ_1;
- break;
- case RME32_CLOCKMODE_MASTER_44:
- /* Internal 44.1kHz */
- rme32->wcreg = (rme32->wcreg & ~RME32_WCR_FREQ_0) |
- RME32_WCR_FREQ_1;
- break;
- case RME32_CLOCKMODE_MASTER_48:
- /* Internal 48.0kHz */
- rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) |
- RME32_WCR_FREQ_1;
- break;
- default:
- return -EINVAL;
- }
- writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
- return 0;
-}
-
-static int snd_rme32_getclockmode(struct rme32 * rme32)
-{
- return ((rme32->wcreg >> RME32_WCR_BITPOS_FREQ_0) & 1) +
- (((rme32->wcreg >> RME32_WCR_BITPOS_FREQ_1) & 1) << 1);
-}
-
-static int snd_rme32_setinputtype(struct rme32 * rme32, int type)
-{
- switch (type) {
- case RME32_INPUT_OPTICAL:
- rme32->wcreg = (rme32->wcreg & ~RME32_WCR_INP_0) &
- ~RME32_WCR_INP_1;
- break;
- case RME32_INPUT_COAXIAL:
- rme32->wcreg = (rme32->wcreg | RME32_WCR_INP_0) &
- ~RME32_WCR_INP_1;
- break;
- case RME32_INPUT_INTERNAL:
- rme32->wcreg = (rme32->wcreg & ~RME32_WCR_INP_0) |
- RME32_WCR_INP_1;
- break;
- case RME32_INPUT_XLR:
- rme32->wcreg = (rme32->wcreg | RME32_WCR_INP_0) |
- RME32_WCR_INP_1;
- break;
- default:
- return -EINVAL;
- }
- writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
- return 0;
-}
-
-static int snd_rme32_getinputtype(struct rme32 * rme32)
-{
- return ((rme32->wcreg >> RME32_WCR_BITPOS_INP_0) & 1) +
- (((rme32->wcreg >> RME32_WCR_BITPOS_INP_1) & 1) << 1);
-}
-
-static void
-snd_rme32_setframelog(struct rme32 * rme32, int n_channels, int is_playback)
-{
- int frlog;
-
- if (n_channels == 2) {
- frlog = 1;
- } else {
- /* assume 8 channels */
- frlog = 3;
- }
- if (is_playback) {
- frlog += (rme32->wcreg & RME32_WCR_MODE24) ? 2 : 1;
- rme32->playback_frlog = frlog;
- } else {
- frlog += (rme32->wcreg & RME32_WCR_MODE24) ? 2 : 1;
- rme32->capture_frlog = frlog;
- }
-}
-
-static int snd_rme32_setformat(struct rme32 * rme32, int format)
-{
- switch (format) {
- case SNDRV_PCM_FORMAT_S16_LE:
- rme32->wcreg &= ~RME32_WCR_MODE24;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- rme32->wcreg |= RME32_WCR_MODE24;
- break;
- default:
- return -EINVAL;
- }
- writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
- return 0;
-}
-
-static int
-snd_rme32_playback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- int err, rate, dummy;
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- if (rme32->fullduplex_mode) {
- err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
- if (err < 0)
- return err;
- } else {
- runtime->dma_area = (void __force *)(rme32->iobase +
- RME32_IO_DATA_BUFFER);
- runtime->dma_addr = rme32->port + RME32_IO_DATA_BUFFER;
- runtime->dma_bytes = RME32_BUFFER_SIZE;
- }
-
- spin_lock_irq(&rme32->lock);
- if ((rme32->rcreg & RME32_RCR_KMODE) &&
- (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) {
- /* AutoSync */
- if ((int)params_rate(params) != rate) {
- spin_unlock_irq(&rme32->lock);
- return -EIO;
- }
- } else if ((err = snd_rme32_playback_setrate(rme32, params_rate(params))) < 0) {
- spin_unlock_irq(&rme32->lock);
- return err;
- }
- if ((err = snd_rme32_setformat(rme32, params_format(params))) < 0) {
- spin_unlock_irq(&rme32->lock);
- return err;
- }
-
- snd_rme32_setframelog(rme32, params_channels(params), 1);
- if (rme32->capture_periodsize != 0) {
- if (params_period_size(params) << rme32->playback_frlog != rme32->capture_periodsize) {
- spin_unlock_irq(&rme32->lock);
- return -EBUSY;
- }
- }
- rme32->playback_periodsize = params_period_size(params) << rme32->playback_frlog;
- /* S/PDIF setup */
- if ((rme32->wcreg & RME32_WCR_ADAT) == 0) {
- rme32->wcreg &= ~(RME32_WCR_PRO | RME32_WCR_EMP);
- rme32->wcreg |= rme32->wcreg_spdif_stream;
- writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
- }
- spin_unlock_irq(&rme32->lock);
-
- return 0;
-}
-
-static int
-snd_rme32_capture_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- int err, isadat, rate;
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- if (rme32->fullduplex_mode) {
- err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
- if (err < 0)
- return err;
- } else {
- runtime->dma_area = (void __force *)rme32->iobase +
- RME32_IO_DATA_BUFFER;
- runtime->dma_addr = rme32->port + RME32_IO_DATA_BUFFER;
- runtime->dma_bytes = RME32_BUFFER_SIZE;
- }
-
- spin_lock_irq(&rme32->lock);
- /* enable AutoSync for record-preparing */
- rme32->wcreg |= RME32_WCR_AUTOSYNC;
- writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
-
- if ((err = snd_rme32_setformat(rme32, params_format(params))) < 0) {
- spin_unlock_irq(&rme32->lock);
- return err;
- }
- if ((err = snd_rme32_playback_setrate(rme32, params_rate(params))) < 0) {
- spin_unlock_irq(&rme32->lock);
- return err;
- }
- if ((rate = snd_rme32_capture_getrate(rme32, &isadat)) > 0) {
- if ((int)params_rate(params) != rate) {
- spin_unlock_irq(&rme32->lock);
- return -EIO;
- }
- if ((isadat && runtime->hw.channels_min == 2) ||
- (!isadat && runtime->hw.channels_min == 8)) {
- spin_unlock_irq(&rme32->lock);
- return -EIO;
- }
- }
- /* AutoSync off for recording */
- rme32->wcreg &= ~RME32_WCR_AUTOSYNC;
- writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
-
- snd_rme32_setframelog(rme32, params_channels(params), 0);
- if (rme32->playback_periodsize != 0) {
- if (params_period_size(params) << rme32->capture_frlog !=
- rme32->playback_periodsize) {
- spin_unlock_irq(&rme32->lock);
- return -EBUSY;
- }
- }
- rme32->capture_periodsize =
- params_period_size(params) << rme32->capture_frlog;
- spin_unlock_irq(&rme32->lock);
-
- return 0;
-}
-
-static int snd_rme32_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- if (! rme32->fullduplex_mode)
- return 0;
- return snd_pcm_lib_free_pages(substream);
-}
-
-static void snd_rme32_pcm_start(struct rme32 * rme32, int from_pause)
-{
- if (!from_pause) {
- writel(0, rme32->iobase + RME32_IO_RESET_POS);
- }
-
- rme32->wcreg |= RME32_WCR_START;
- writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
-}
-
-static void snd_rme32_pcm_stop(struct rme32 * rme32, int to_pause)
-{
- /*
- * Check if there is an unconfirmed IRQ, if so confirm it, or else
- * the hardware will not stop generating interrupts
- */
- rme32->rcreg = readl(rme32->iobase + RME32_IO_CONTROL_REGISTER);
- if (rme32->rcreg & RME32_RCR_IRQ) {
- writel(0, rme32->iobase + RME32_IO_CONFIRM_ACTION_IRQ);
- }
- rme32->wcreg &= ~RME32_WCR_START;
- if (rme32->wcreg & RME32_WCR_SEL)
- rme32->wcreg |= RME32_WCR_MUTE;
- writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
- if (! to_pause)
- writel(0, rme32->iobase + RME32_IO_RESET_POS);
-}
-
-static irqreturn_t snd_rme32_interrupt(int irq, void *dev_id)
-{
- struct rme32 *rme32 = (struct rme32 *) dev_id;
-
- rme32->rcreg = readl(rme32->iobase + RME32_IO_CONTROL_REGISTER);
- if (!(rme32->rcreg & RME32_RCR_IRQ)) {
- return IRQ_NONE;
- } else {
- if (rme32->capture_substream) {
- snd_pcm_period_elapsed(rme32->capture_substream);
- }
- if (rme32->playback_substream) {
- snd_pcm_period_elapsed(rme32->playback_substream);
- }
- writel(0, rme32->iobase + RME32_IO_CONFIRM_ACTION_IRQ);
- }
- return IRQ_HANDLED;
-}
-
-static unsigned int period_bytes[] = { RME32_BLOCK_SIZE };
-
-
-static struct snd_pcm_hw_constraint_list hw_constraints_period_bytes = {
- .count = ARRAY_SIZE(period_bytes),
- .list = period_bytes,
- .mask = 0
-};
-
-static void snd_rme32_set_buffer_constraint(struct rme32 *rme32, struct snd_pcm_runtime *runtime)
-{
- if (! rme32->fullduplex_mode) {
- snd_pcm_hw_constraint_minmax(runtime,
- SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
- RME32_BUFFER_SIZE, RME32_BUFFER_SIZE);
- snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- &hw_constraints_period_bytes);
- }
-}
-
-static int snd_rme32_playback_spdif_open(struct snd_pcm_substream *substream)
-{
- int rate, dummy;
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- snd_pcm_set_sync(substream);
-
- spin_lock_irq(&rme32->lock);
- if (rme32->playback_substream != NULL) {
- spin_unlock_irq(&rme32->lock);
- return -EBUSY;
- }
- rme32->wcreg &= ~RME32_WCR_ADAT;
- writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
- rme32->playback_substream = substream;
- spin_unlock_irq(&rme32->lock);
-
- if (rme32->fullduplex_mode)
- runtime->hw = snd_rme32_spdif_fd_info;
- else
- runtime->hw = snd_rme32_spdif_info;
- if (rme32->pci->device == PCI_DEVICE_ID_RME_DIGI32_PRO) {
- runtime->hw.rates |= SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000;
- runtime->hw.rate_max = 96000;
- }
- if ((rme32->rcreg & RME32_RCR_KMODE) &&
- (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) {
- /* AutoSync */
- runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
- runtime->hw.rate_min = rate;
- runtime->hw.rate_max = rate;
- }
-
- snd_rme32_set_buffer_constraint(rme32, runtime);
-
- rme32->wcreg_spdif_stream = rme32->wcreg_spdif;
- rme32->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(rme32->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO, &rme32->spdif_ctl->id);
- return 0;
-}
-
-static int snd_rme32_capture_spdif_open(struct snd_pcm_substream *substream)
-{
- int isadat, rate;
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- snd_pcm_set_sync(substream);
-
- spin_lock_irq(&rme32->lock);
- if (rme32->capture_substream != NULL) {
- spin_unlock_irq(&rme32->lock);
- return -EBUSY;
- }
- rme32->capture_substream = substream;
- spin_unlock_irq(&rme32->lock);
-
- if (rme32->fullduplex_mode)
- runtime->hw = snd_rme32_spdif_fd_info;
- else
- runtime->hw = snd_rme32_spdif_info;
- if (RME32_PRO_WITH_8414(rme32)) {
- runtime->hw.rates |= SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000;
- runtime->hw.rate_max = 96000;
- }
- if ((rate = snd_rme32_capture_getrate(rme32, &isadat)) > 0) {
- if (isadat) {
- return -EIO;
- }
- runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
- runtime->hw.rate_min = rate;
- runtime->hw.rate_max = rate;
- }
-
- snd_rme32_set_buffer_constraint(rme32, runtime);
-
- return 0;
-}
-
-static int
-snd_rme32_playback_adat_open(struct snd_pcm_substream *substream)
-{
- int rate, dummy;
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- snd_pcm_set_sync(substream);
-
- spin_lock_irq(&rme32->lock);
- if (rme32->playback_substream != NULL) {
- spin_unlock_irq(&rme32->lock);
- return -EBUSY;
- }
- rme32->wcreg |= RME32_WCR_ADAT;
- writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
- rme32->playback_substream = substream;
- spin_unlock_irq(&rme32->lock);
-
- if (rme32->fullduplex_mode)
- runtime->hw = snd_rme32_adat_fd_info;
- else
- runtime->hw = snd_rme32_adat_info;
- if ((rme32->rcreg & RME32_RCR_KMODE) &&
- (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) {
- /* AutoSync */
- runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
- runtime->hw.rate_min = rate;
- runtime->hw.rate_max = rate;
- }
-
- snd_rme32_set_buffer_constraint(rme32, runtime);
- return 0;
-}
-
-static int
-snd_rme32_capture_adat_open(struct snd_pcm_substream *substream)
-{
- int isadat, rate;
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- if (rme32->fullduplex_mode)
- runtime->hw = snd_rme32_adat_fd_info;
- else
- runtime->hw = snd_rme32_adat_info;
- if ((rate = snd_rme32_capture_getrate(rme32, &isadat)) > 0) {
- if (!isadat) {
- return -EIO;
- }
- runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
- runtime->hw.rate_min = rate;
- runtime->hw.rate_max = rate;
- }
-
- snd_pcm_set_sync(substream);
-
- spin_lock_irq(&rme32->lock);
- if (rme32->capture_substream != NULL) {
- spin_unlock_irq(&rme32->lock);
- return -EBUSY;
- }
- rme32->capture_substream = substream;
- spin_unlock_irq(&rme32->lock);
-
- snd_rme32_set_buffer_constraint(rme32, runtime);
- return 0;
-}
-
-static int snd_rme32_playback_close(struct snd_pcm_substream *substream)
-{
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- int spdif = 0;
-
- spin_lock_irq(&rme32->lock);
- rme32->playback_substream = NULL;
- rme32->playback_periodsize = 0;
- spdif = (rme32->wcreg & RME32_WCR_ADAT) == 0;
- spin_unlock_irq(&rme32->lock);
- if (spdif) {
- rme32->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(rme32->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO,
- &rme32->spdif_ctl->id);
- }
- return 0;
-}
-
-static int snd_rme32_capture_close(struct snd_pcm_substream *substream)
-{
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&rme32->lock);
- rme32->capture_substream = NULL;
- rme32->capture_periodsize = 0;
- spin_unlock(&rme32->lock);
- return 0;
-}
-
-static int snd_rme32_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&rme32->lock);
- if (rme32->fullduplex_mode) {
- memset(&rme32->playback_pcm, 0, sizeof(rme32->playback_pcm));
- rme32->playback_pcm.hw_buffer_size = RME32_BUFFER_SIZE;
- rme32->playback_pcm.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
- } else {
- writel(0, rme32->iobase + RME32_IO_RESET_POS);
- }
- if (rme32->wcreg & RME32_WCR_SEL)
- rme32->wcreg &= ~RME32_WCR_MUTE;
- writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
- spin_unlock_irq(&rme32->lock);
- return 0;
-}
-
-static int snd_rme32_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&rme32->lock);
- if (rme32->fullduplex_mode) {
- memset(&rme32->capture_pcm, 0, sizeof(rme32->capture_pcm));
- rme32->capture_pcm.hw_buffer_size = RME32_BUFFER_SIZE;
- rme32->capture_pcm.hw_queue_size = RME32_BUFFER_SIZE / 2;
- rme32->capture_pcm.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
- } else {
- writel(0, rme32->iobase + RME32_IO_RESET_POS);
- }
- spin_unlock_irq(&rme32->lock);
- return 0;
-}
-
-static int
-snd_rme32_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- struct snd_pcm_substream *s;
-
- spin_lock(&rme32->lock);
- snd_pcm_group_for_each_entry(s, substream) {
- if (s != rme32->playback_substream &&
- s != rme32->capture_substream)
- continue;
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- rme32->running |= (1 << s->stream);
- if (rme32->fullduplex_mode) {
- /* remember the current DMA position */
- if (s == rme32->playback_substream) {
- rme32->playback_pcm.hw_io =
- rme32->playback_pcm.hw_data = snd_rme32_pcm_byteptr(rme32);
- } else {
- rme32->capture_pcm.hw_io =
- rme32->capture_pcm.hw_data = snd_rme32_pcm_byteptr(rme32);
- }
- }
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- rme32->running &= ~(1 << s->stream);
- break;
- }
- snd_pcm_trigger_done(s, substream);
- }
-
- /* prefill playback buffer */
- if (cmd == SNDRV_PCM_TRIGGER_START && rme32->fullduplex_mode) {
- snd_pcm_group_for_each_entry(s, substream) {
- if (s == rme32->playback_substream) {
- s->ops->ack(s);
- break;
- }
- }
- }
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- if (rme32->running && ! RME32_ISWORKING(rme32))
- snd_rme32_pcm_start(rme32, 0);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- if (! rme32->running && RME32_ISWORKING(rme32))
- snd_rme32_pcm_stop(rme32, 0);
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (rme32->running && RME32_ISWORKING(rme32))
- snd_rme32_pcm_stop(rme32, 1);
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (rme32->running && ! RME32_ISWORKING(rme32))
- snd_rme32_pcm_start(rme32, 1);
- break;
- }
- spin_unlock(&rme32->lock);
- return 0;
-}
-
-/* pointer callback for halfduplex mode */
-static snd_pcm_uframes_t
-snd_rme32_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- return snd_rme32_pcm_byteptr(rme32) >> rme32->playback_frlog;
-}
-
-static snd_pcm_uframes_t
-snd_rme32_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- return snd_rme32_pcm_byteptr(rme32) >> rme32->capture_frlog;
-}
-
-
-/* ack and pointer callbacks for fullduplex mode */
-static void snd_rme32_pb_trans_copy(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect *rec, size_t bytes)
-{
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- memcpy_toio(rme32->iobase + RME32_IO_DATA_BUFFER + rec->hw_data,
- substream->runtime->dma_area + rec->sw_data, bytes);
-}
-
-static int snd_rme32_playback_fd_ack(struct snd_pcm_substream *substream)
-{
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- struct snd_pcm_indirect *rec, *cprec;
-
- rec = &rme32->playback_pcm;
- cprec = &rme32->capture_pcm;
- spin_lock(&rme32->lock);
- rec->hw_queue_size = RME32_BUFFER_SIZE;
- if (rme32->running & (1 << SNDRV_PCM_STREAM_CAPTURE))
- rec->hw_queue_size -= cprec->hw_ready;
- spin_unlock(&rme32->lock);
- snd_pcm_indirect_playback_transfer(substream, rec,
- snd_rme32_pb_trans_copy);
- return 0;
-}
-
-static void snd_rme32_cp_trans_copy(struct snd_pcm_substream *substream,
- struct snd_pcm_indirect *rec, size_t bytes)
-{
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- memcpy_fromio(substream->runtime->dma_area + rec->sw_data,
- rme32->iobase + RME32_IO_DATA_BUFFER + rec->hw_data,
- bytes);
-}
-
-static int snd_rme32_capture_fd_ack(struct snd_pcm_substream *substream)
-{
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- snd_pcm_indirect_capture_transfer(substream, &rme32->capture_pcm,
- snd_rme32_cp_trans_copy);
- return 0;
-}
-
-static snd_pcm_uframes_t
-snd_rme32_playback_fd_pointer(struct snd_pcm_substream *substream)
-{
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- return snd_pcm_indirect_playback_pointer(substream, &rme32->playback_pcm,
- snd_rme32_pcm_byteptr(rme32));
-}
-
-static snd_pcm_uframes_t
-snd_rme32_capture_fd_pointer(struct snd_pcm_substream *substream)
-{
- struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- return snd_pcm_indirect_capture_pointer(substream, &rme32->capture_pcm,
- snd_rme32_pcm_byteptr(rme32));
-}
-
-/* for halfduplex mode */
-static struct snd_pcm_ops snd_rme32_playback_spdif_ops = {
- .open = snd_rme32_playback_spdif_open,
- .close = snd_rme32_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_rme32_playback_hw_params,
- .hw_free = snd_rme32_pcm_hw_free,
- .prepare = snd_rme32_playback_prepare,
- .trigger = snd_rme32_pcm_trigger,
- .pointer = snd_rme32_playback_pointer,
- .copy = snd_rme32_playback_copy,
- .silence = snd_rme32_playback_silence,
- .mmap = snd_pcm_lib_mmap_iomem,
-};
-
-static struct snd_pcm_ops snd_rme32_capture_spdif_ops = {
- .open = snd_rme32_capture_spdif_open,
- .close = snd_rme32_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_rme32_capture_hw_params,
- .hw_free = snd_rme32_pcm_hw_free,
- .prepare = snd_rme32_capture_prepare,
- .trigger = snd_rme32_pcm_trigger,
- .pointer = snd_rme32_capture_pointer,
- .copy = snd_rme32_capture_copy,
- .mmap = snd_pcm_lib_mmap_iomem,
-};
-
-static struct snd_pcm_ops snd_rme32_playback_adat_ops = {
- .open = snd_rme32_playback_adat_open,
- .close = snd_rme32_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_rme32_playback_hw_params,
- .prepare = snd_rme32_playback_prepare,
- .trigger = snd_rme32_pcm_trigger,
- .pointer = snd_rme32_playback_pointer,
- .copy = snd_rme32_playback_copy,
- .silence = snd_rme32_playback_silence,
- .mmap = snd_pcm_lib_mmap_iomem,
-};
-
-static struct snd_pcm_ops snd_rme32_capture_adat_ops = {
- .open = snd_rme32_capture_adat_open,
- .close = snd_rme32_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_rme32_capture_hw_params,
- .prepare = snd_rme32_capture_prepare,
- .trigger = snd_rme32_pcm_trigger,
- .pointer = snd_rme32_capture_pointer,
- .copy = snd_rme32_capture_copy,
- .mmap = snd_pcm_lib_mmap_iomem,
-};
-
-/* for fullduplex mode */
-static struct snd_pcm_ops snd_rme32_playback_spdif_fd_ops = {
- .open = snd_rme32_playback_spdif_open,
- .close = snd_rme32_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_rme32_playback_hw_params,
- .hw_free = snd_rme32_pcm_hw_free,
- .prepare = snd_rme32_playback_prepare,
- .trigger = snd_rme32_pcm_trigger,
- .pointer = snd_rme32_playback_fd_pointer,
- .ack = snd_rme32_playback_fd_ack,
-};
-
-static struct snd_pcm_ops snd_rme32_capture_spdif_fd_ops = {
- .open = snd_rme32_capture_spdif_open,
- .close = snd_rme32_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_rme32_capture_hw_params,
- .hw_free = snd_rme32_pcm_hw_free,
- .prepare = snd_rme32_capture_prepare,
- .trigger = snd_rme32_pcm_trigger,
- .pointer = snd_rme32_capture_fd_pointer,
- .ack = snd_rme32_capture_fd_ack,
-};
-
-static struct snd_pcm_ops snd_rme32_playback_adat_fd_ops = {
- .open = snd_rme32_playback_adat_open,
- .close = snd_rme32_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_rme32_playback_hw_params,
- .prepare = snd_rme32_playback_prepare,
- .trigger = snd_rme32_pcm_trigger,
- .pointer = snd_rme32_playback_fd_pointer,
- .ack = snd_rme32_playback_fd_ack,
-};
-
-static struct snd_pcm_ops snd_rme32_capture_adat_fd_ops = {
- .open = snd_rme32_capture_adat_open,
- .close = snd_rme32_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_rme32_capture_hw_params,
- .prepare = snd_rme32_capture_prepare,
- .trigger = snd_rme32_pcm_trigger,
- .pointer = snd_rme32_capture_fd_pointer,
- .ack = snd_rme32_capture_fd_ack,
-};
-
-static void snd_rme32_free(void *private_data)
-{
- struct rme32 *rme32 = (struct rme32 *) private_data;
-
- if (rme32 == NULL) {
- return;
- }
- if (rme32->irq >= 0) {
- snd_rme32_pcm_stop(rme32, 0);
- free_irq(rme32->irq, (void *) rme32);
- rme32->irq = -1;
- }
- if (rme32->iobase) {
- iounmap(rme32->iobase);
- rme32->iobase = NULL;
- }
- if (rme32->port) {
- pci_release_regions(rme32->pci);
- rme32->port = 0;
- }
- pci_disable_device(rme32->pci);
-}
-
-static void snd_rme32_free_spdif_pcm(struct snd_pcm *pcm)
-{
- struct rme32 *rme32 = (struct rme32 *) pcm->private_data;
- rme32->spdif_pcm = NULL;
-}
-
-static void
-snd_rme32_free_adat_pcm(struct snd_pcm *pcm)
-{
- struct rme32 *rme32 = (struct rme32 *) pcm->private_data;
- rme32->adat_pcm = NULL;
-}
-
-static int __devinit snd_rme32_create(struct rme32 * rme32)
-{
- struct pci_dev *pci = rme32->pci;
- int err;
-
- rme32->irq = -1;
- spin_lock_init(&rme32->lock);
-
- if ((err = pci_enable_device(pci)) < 0)
- return err;
-
- if ((err = pci_request_regions(pci, "RME32")) < 0)
- return err;
- rme32->port = pci_resource_start(rme32->pci, 0);
-
- rme32->iobase = ioremap_nocache(rme32->port, RME32_IO_SIZE);
- if (!rme32->iobase) {
- snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n",
- rme32->port, rme32->port + RME32_IO_SIZE - 1);
- return -ENOMEM;
- }
-
- if (request_irq(pci->irq, snd_rme32_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, rme32)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- return -EBUSY;
- }
- rme32->irq = pci->irq;
-
- /* read the card's revision number */
- pci_read_config_byte(pci, 8, &rme32->rev);
-
- /* set up ALSA pcm device for S/PDIF */
- if ((err = snd_pcm_new(rme32->card, "Digi32 IEC958", 0, 1, 1, &rme32->spdif_pcm)) < 0) {
- return err;
- }
- rme32->spdif_pcm->private_data = rme32;
- rme32->spdif_pcm->private_free = snd_rme32_free_spdif_pcm;
- strcpy(rme32->spdif_pcm->name, "Digi32 IEC958");
- if (rme32->fullduplex_mode) {
- snd_pcm_set_ops(rme32->spdif_pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_rme32_playback_spdif_fd_ops);
- snd_pcm_set_ops(rme32->spdif_pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_rme32_capture_spdif_fd_ops);
- snd_pcm_lib_preallocate_pages_for_all(rme32->spdif_pcm, SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- 0, RME32_MID_BUFFER_SIZE);
- rme32->spdif_pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
- } else {
- snd_pcm_set_ops(rme32->spdif_pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_rme32_playback_spdif_ops);
- snd_pcm_set_ops(rme32->spdif_pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_rme32_capture_spdif_ops);
- rme32->spdif_pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
- }
-
- /* set up ALSA pcm device for ADAT */
- if ((pci->device == PCI_DEVICE_ID_RME_DIGI32) ||
- (pci->device == PCI_DEVICE_ID_RME_DIGI32_PRO)) {
- /* ADAT is not available on DIGI32 and DIGI32 Pro */
- rme32->adat_pcm = NULL;
- }
- else {
- if ((err = snd_pcm_new(rme32->card, "Digi32 ADAT", 1,
- 1, 1, &rme32->adat_pcm)) < 0)
- {
- return err;
- }
- rme32->adat_pcm->private_data = rme32;
- rme32->adat_pcm->private_free = snd_rme32_free_adat_pcm;
- strcpy(rme32->adat_pcm->name, "Digi32 ADAT");
- if (rme32->fullduplex_mode) {
- snd_pcm_set_ops(rme32->adat_pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_rme32_playback_adat_fd_ops);
- snd_pcm_set_ops(rme32->adat_pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_rme32_capture_adat_fd_ops);
- snd_pcm_lib_preallocate_pages_for_all(rme32->adat_pcm, SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- 0, RME32_MID_BUFFER_SIZE);
- rme32->adat_pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
- } else {
- snd_pcm_set_ops(rme32->adat_pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_rme32_playback_adat_ops);
- snd_pcm_set_ops(rme32->adat_pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_rme32_capture_adat_ops);
- rme32->adat_pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
- }
- }
-
-
- rme32->playback_periodsize = 0;
- rme32->capture_periodsize = 0;
-
- /* make sure playback/capture is stopped, if by some reason active */
- snd_rme32_pcm_stop(rme32, 0);
-
- /* reset DAC */
- snd_rme32_reset_dac(rme32);
-
- /* reset buffer pointer */
- writel(0, rme32->iobase + RME32_IO_RESET_POS);
-
- /* set default values in registers */
- rme32->wcreg = RME32_WCR_SEL | /* normal playback */
- RME32_WCR_INP_0 | /* input select */
- RME32_WCR_MUTE; /* muting on */
- writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
-
-
- /* init switch interface */
- if ((err = snd_rme32_create_switches(rme32->card, rme32)) < 0) {
- return err;
- }
-
- /* init proc interface */
- snd_rme32_proc_init(rme32);
-
- rme32->capture_substream = NULL;
- rme32->playback_substream = NULL;
-
- return 0;
-}
-
-/*
- * proc interface
- */
-
-static void
-snd_rme32_proc_read(struct snd_info_entry * entry, struct snd_info_buffer *buffer)
-{
- int n;
- struct rme32 *rme32 = (struct rme32 *) entry->private_data;
-
- rme32->rcreg = readl(rme32->iobase + RME32_IO_CONTROL_REGISTER);
-
- snd_iprintf(buffer, rme32->card->longname);
- snd_iprintf(buffer, " (index #%d)\n", rme32->card->number + 1);
-
- snd_iprintf(buffer, "\nGeneral settings\n");
- if (rme32->fullduplex_mode)
- snd_iprintf(buffer, " Full-duplex mode\n");
- else
- snd_iprintf(buffer, " Half-duplex mode\n");
- if (RME32_PRO_WITH_8414(rme32)) {
- snd_iprintf(buffer, " receiver: CS8414\n");
- } else {
- snd_iprintf(buffer, " receiver: CS8412\n");
- }
- if (rme32->wcreg & RME32_WCR_MODE24) {
- snd_iprintf(buffer, " format: 24 bit");
- } else {
- snd_iprintf(buffer, " format: 16 bit");
- }
- if (rme32->wcreg & RME32_WCR_MONO) {
- snd_iprintf(buffer, ", Mono\n");
- } else {
- snd_iprintf(buffer, ", Stereo\n");
- }
-
- snd_iprintf(buffer, "\nInput settings\n");
- switch (snd_rme32_getinputtype(rme32)) {
- case RME32_INPUT_OPTICAL:
- snd_iprintf(buffer, " input: optical");
- break;
- case RME32_INPUT_COAXIAL:
- snd_iprintf(buffer, " input: coaxial");
- break;
- case RME32_INPUT_INTERNAL:
- snd_iprintf(buffer, " input: internal");
- break;
- case RME32_INPUT_XLR:
- snd_iprintf(buffer, " input: XLR");
- break;
- }
- if (snd_rme32_capture_getrate(rme32, &n) < 0) {
- snd_iprintf(buffer, "\n sample rate: no valid signal\n");
- } else {
- if (n) {
- snd_iprintf(buffer, " (8 channels)\n");
- } else {
- snd_iprintf(buffer, " (2 channels)\n");
- }
- snd_iprintf(buffer, " sample rate: %d Hz\n",
- snd_rme32_capture_getrate(rme32, &n));
- }
-
- snd_iprintf(buffer, "\nOutput settings\n");
- if (rme32->wcreg & RME32_WCR_SEL) {
- snd_iprintf(buffer, " output signal: normal playback");
- } else {
- snd_iprintf(buffer, " output signal: same as input");
- }
- if (rme32->wcreg & RME32_WCR_MUTE) {
- snd_iprintf(buffer, " (muted)\n");
- } else {
- snd_iprintf(buffer, "\n");
- }
-
- /* master output frequency */
- if (!
- ((!(rme32->wcreg & RME32_WCR_FREQ_0))
- && (!(rme32->wcreg & RME32_WCR_FREQ_1)))) {
- snd_iprintf(buffer, " sample rate: %d Hz\n",
- snd_rme32_playback_getrate(rme32));
- }
- if (rme32->rcreg & RME32_RCR_KMODE) {
- snd_iprintf(buffer, " sample clock source: AutoSync\n");
- } else {
- snd_iprintf(buffer, " sample clock source: Internal\n");
- }
- if (rme32->wcreg & RME32_WCR_PRO) {
- snd_iprintf(buffer, " format: AES/EBU (professional)\n");
- } else {
- snd_iprintf(buffer, " format: IEC958 (consumer)\n");
- }
- if (rme32->wcreg & RME32_WCR_EMP) {
- snd_iprintf(buffer, " emphasis: on\n");
- } else {
- snd_iprintf(buffer, " emphasis: off\n");
- }
-}
-
-static void __devinit snd_rme32_proc_init(struct rme32 * rme32)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(rme32->card, "rme32", &entry))
- snd_info_set_text_ops(entry, rme32, snd_rme32_proc_read);
-}
-
-/*
- * control interface
- */
-
-#define snd_rme32_info_loopback_control snd_ctl_boolean_mono_info
-
-static int
-snd_rme32_get_loopback_control(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&rme32->lock);
- ucontrol->value.integer.value[0] =
- rme32->wcreg & RME32_WCR_SEL ? 0 : 1;
- spin_unlock_irq(&rme32->lock);
- return 0;
-}
-static int
-snd_rme32_put_loopback_control(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change;
-
- val = ucontrol->value.integer.value[0] ? 0 : RME32_WCR_SEL;
- spin_lock_irq(&rme32->lock);
- val = (rme32->wcreg & ~RME32_WCR_SEL) | val;
- change = val != rme32->wcreg;
- if (ucontrol->value.integer.value[0])
- val &= ~RME32_WCR_MUTE;
- else
- val |= RME32_WCR_MUTE;
- rme32->wcreg = val;
- writel(val, rme32->iobase + RME32_IO_CONTROL_REGISTER);
- spin_unlock_irq(&rme32->lock);
- return change;
-}
-
-static int
-snd_rme32_info_inputtype_control(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
- static char *texts[4] = { "Optical", "Coaxial", "Internal", "XLR" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- switch (rme32->pci->device) {
- case PCI_DEVICE_ID_RME_DIGI32:
- case PCI_DEVICE_ID_RME_DIGI32_8:
- uinfo->value.enumerated.items = 3;
- break;
- case PCI_DEVICE_ID_RME_DIGI32_PRO:
- uinfo->value.enumerated.items = 4;
- break;
- default:
- snd_BUG();
- break;
- }
- if (uinfo->value.enumerated.item >
- uinfo->value.enumerated.items - 1) {
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
- }
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-static int
-snd_rme32_get_inputtype_control(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
- unsigned int items = 3;
-
- spin_lock_irq(&rme32->lock);
- ucontrol->value.enumerated.item[0] = snd_rme32_getinputtype(rme32);
-
- switch (rme32->pci->device) {
- case PCI_DEVICE_ID_RME_DIGI32:
- case PCI_DEVICE_ID_RME_DIGI32_8:
- items = 3;
- break;
- case PCI_DEVICE_ID_RME_DIGI32_PRO:
- items = 4;
- break;
- default:
- snd_BUG();
- break;
- }
- if (ucontrol->value.enumerated.item[0] >= items) {
- ucontrol->value.enumerated.item[0] = items - 1;
- }
-
- spin_unlock_irq(&rme32->lock);
- return 0;
-}
-static int
-snd_rme32_put_inputtype_control(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change, items = 3;
-
- switch (rme32->pci->device) {
- case PCI_DEVICE_ID_RME_DIGI32:
- case PCI_DEVICE_ID_RME_DIGI32_8:
- items = 3;
- break;
- case PCI_DEVICE_ID_RME_DIGI32_PRO:
- items = 4;
- break;
- default:
- snd_BUG();
- break;
- }
- val = ucontrol->value.enumerated.item[0] % items;
-
- spin_lock_irq(&rme32->lock);
- change = val != (unsigned int)snd_rme32_getinputtype(rme32);
- snd_rme32_setinputtype(rme32, val);
- spin_unlock_irq(&rme32->lock);
- return change;
-}
-
-static int
-snd_rme32_info_clockmode_control(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[4] = { "AutoSync",
- "Internal 32.0kHz",
- "Internal 44.1kHz",
- "Internal 48.0kHz" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 4;
- if (uinfo->value.enumerated.item > 3) {
- uinfo->value.enumerated.item = 3;
- }
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-static int
-snd_rme32_get_clockmode_control(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&rme32->lock);
- ucontrol->value.enumerated.item[0] = snd_rme32_getclockmode(rme32);
- spin_unlock_irq(&rme32->lock);
- return 0;
-}
-static int
-snd_rme32_put_clockmode_control(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change;
-
- val = ucontrol->value.enumerated.item[0] % 3;
- spin_lock_irq(&rme32->lock);
- change = val != (unsigned int)snd_rme32_getclockmode(rme32);
- snd_rme32_setclockmode(rme32, val);
- spin_unlock_irq(&rme32->lock);
- return change;
-}
-
-static u32 snd_rme32_convert_from_aes(struct snd_aes_iec958 * aes)
-{
- u32 val = 0;
- val |= (aes->status[0] & IEC958_AES0_PROFESSIONAL) ? RME32_WCR_PRO : 0;
- if (val & RME32_WCR_PRO)
- val |= (aes->status[0] & IEC958_AES0_PRO_EMPHASIS_5015) ? RME32_WCR_EMP : 0;
- else
- val |= (aes->status[0] & IEC958_AES0_CON_EMPHASIS_5015) ? RME32_WCR_EMP : 0;
- return val;
-}
-
-static void snd_rme32_convert_to_aes(struct snd_aes_iec958 * aes, u32 val)
-{
- aes->status[0] = ((val & RME32_WCR_PRO) ? IEC958_AES0_PROFESSIONAL : 0);
- if (val & RME32_WCR_PRO)
- aes->status[0] |= (val & RME32_WCR_EMP) ? IEC958_AES0_PRO_EMPHASIS_5015 : 0;
- else
- aes->status[0] |= (val & RME32_WCR_EMP) ? IEC958_AES0_CON_EMPHASIS_5015 : 0;
-}
-
-static int snd_rme32_control_spdif_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_rme32_control_spdif_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
-
- snd_rme32_convert_to_aes(&ucontrol->value.iec958,
- rme32->wcreg_spdif);
- return 0;
-}
-
-static int snd_rme32_control_spdif_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
- int change;
- u32 val;
-
- val = snd_rme32_convert_from_aes(&ucontrol->value.iec958);
- spin_lock_irq(&rme32->lock);
- change = val != rme32->wcreg_spdif;
- rme32->wcreg_spdif = val;
- spin_unlock_irq(&rme32->lock);
- return change;
-}
-
-static int snd_rme32_control_spdif_stream_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_rme32_control_spdif_stream_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *
- ucontrol)
-{
- struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
-
- snd_rme32_convert_to_aes(&ucontrol->value.iec958,
- rme32->wcreg_spdif_stream);
- return 0;
-}
-
-static int snd_rme32_control_spdif_stream_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *
- ucontrol)
-{
- struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
- int change;
- u32 val;
-
- val = snd_rme32_convert_from_aes(&ucontrol->value.iec958);
- spin_lock_irq(&rme32->lock);
- change = val != rme32->wcreg_spdif_stream;
- rme32->wcreg_spdif_stream = val;
- rme32->wcreg &= ~(RME32_WCR_PRO | RME32_WCR_EMP);
- rme32->wcreg |= val;
- writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
- spin_unlock_irq(&rme32->lock);
- return change;
-}
-
-static int snd_rme32_control_spdif_mask_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_rme32_control_spdif_mask_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *
- ucontrol)
-{
- ucontrol->value.iec958.status[0] = kcontrol->private_value;
- return 0;
-}
-
-static struct snd_kcontrol_new snd_rme32_controls[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
- .info = snd_rme32_control_spdif_info,
- .get = snd_rme32_control_spdif_get,
- .put = snd_rme32_control_spdif_put
- },
- {
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM),
- .info = snd_rme32_control_spdif_stream_info,
- .get = snd_rme32_control_spdif_stream_get,
- .put = snd_rme32_control_spdif_stream_put
- },
- {
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
- .info = snd_rme32_control_spdif_mask_info,
- .get = snd_rme32_control_spdif_mask_get,
- .private_value = IEC958_AES0_PROFESSIONAL | IEC958_AES0_CON_EMPHASIS
- },
- {
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK),
- .info = snd_rme32_control_spdif_mask_info,
- .get = snd_rme32_control_spdif_mask_get,
- .private_value = IEC958_AES0_PROFESSIONAL | IEC958_AES0_PRO_EMPHASIS
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input Connector",
- .info = snd_rme32_info_inputtype_control,
- .get = snd_rme32_get_inputtype_control,
- .put = snd_rme32_put_inputtype_control
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Loopback Input",
- .info = snd_rme32_info_loopback_control,
- .get = snd_rme32_get_loopback_control,
- .put = snd_rme32_put_loopback_control
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Sample Clock Source",
- .info = snd_rme32_info_clockmode_control,
- .get = snd_rme32_get_clockmode_control,
- .put = snd_rme32_put_clockmode_control
- }
-};
-
-static int snd_rme32_create_switches(struct snd_card *card, struct rme32 * rme32)
-{
- int idx, err;
- struct snd_kcontrol *kctl;
-
- for (idx = 0; idx < (int)ARRAY_SIZE(snd_rme32_controls); idx++) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme32_controls[idx], rme32))) < 0)
- return err;
- if (idx == 1) /* IEC958 (S/PDIF) Stream */
- rme32->spdif_ctl = kctl;
- }
-
- return 0;
-}
-
-/*
- * Card initialisation
- */
-
-static void snd_rme32_card_free(struct snd_card *card)
-{
- snd_rme32_free(card->private_data);
-}
-
-static int __devinit
-snd_rme32_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
-{
- static int dev;
- struct rme32 *rme32;
- struct snd_card *card;
- int err;
-
- if (dev >= SNDRV_CARDS) {
- return -ENODEV;
- }
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct rme32), &card);
- if (err < 0)
- return err;
- card->private_free = snd_rme32_card_free;
- rme32 = (struct rme32 *) card->private_data;
- rme32->card = card;
- rme32->pci = pci;
- snd_card_set_dev(card, &pci->dev);
- if (fullduplex[dev])
- rme32->fullduplex_mode = 1;
- if ((err = snd_rme32_create(rme32)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- strcpy(card->driver, "Digi32");
- switch (rme32->pci->device) {
- case PCI_DEVICE_ID_RME_DIGI32:
- strcpy(card->shortname, "RME Digi32");
- break;
- case PCI_DEVICE_ID_RME_DIGI32_8:
- strcpy(card->shortname, "RME Digi32/8");
- break;
- case PCI_DEVICE_ID_RME_DIGI32_PRO:
- strcpy(card->shortname, "RME Digi32 PRO");
- break;
- }
- sprintf(card->longname, "%s (Rev. %d) at 0x%lx, irq %d",
- card->shortname, rme32->rev, rme32->port, rme32->irq);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_rme32_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_rme32_ids,
- .probe = snd_rme32_probe,
- .remove = __devexit_p(snd_rme32_remove),
-};
-
-static int __init alsa_card_rme32_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_rme32_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_rme32_init)
-module_exit(alsa_card_rme32_exit)
diff --git a/ANDROID_3.4.5/sound/pci/rme96.c b/ANDROID_3.4.5/sound/pci/rme96.c
deleted file mode 100644
index ba894158..00000000
--- a/ANDROID_3.4.5/sound/pci/rme96.c
+++ /dev/null
@@ -1,2416 +0,0 @@
-/*
- * ALSA driver for RME Digi96, Digi96/8 and Digi96/8 PRO/PAD/PST audio
- * interfaces
- *
- * Copyright (c) 2000, 2001 Anders Torger <torger@ludd.luth.se>
- *
- * Thanks to Henk Hesselink <henk@anda.nl> for the analog volume control
- * code.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/asoundef.h>
-#include <sound/initval.h>
-
-#include <asm/io.h>
-
-/* note, two last pcis should be equal, it is not a bug */
-
-MODULE_AUTHOR("Anders Torger <torger@ludd.luth.se>");
-MODULE_DESCRIPTION("RME Digi96, Digi96/8, Digi96/8 PRO, Digi96/8 PST, "
- "Digi96/8 PAD");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{RME,Digi96},"
- "{RME,Digi96/8},"
- "{RME,Digi96/8 PRO},"
- "{RME,Digi96/8 PST},"
- "{RME,Digi96/8 PAD}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for RME Digi96 soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for RME Digi96 soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable RME Digi96 soundcard.");
-
-/*
- * Defines for RME Digi96 series, from internal RME reference documents
- * dated 12.01.00
- */
-
-#define RME96_SPDIF_NCHANNELS 2
-
-/* Playback and capture buffer size */
-#define RME96_BUFFER_SIZE 0x10000
-
-/* IO area size */
-#define RME96_IO_SIZE 0x60000
-
-/* IO area offsets */
-#define RME96_IO_PLAY_BUFFER 0x0
-#define RME96_IO_REC_BUFFER 0x10000
-#define RME96_IO_CONTROL_REGISTER 0x20000
-#define RME96_IO_ADDITIONAL_REG 0x20004
-#define RME96_IO_CONFIRM_PLAY_IRQ 0x20008
-#define RME96_IO_CONFIRM_REC_IRQ 0x2000C
-#define RME96_IO_SET_PLAY_POS 0x40000
-#define RME96_IO_RESET_PLAY_POS 0x4FFFC
-#define RME96_IO_SET_REC_POS 0x50000
-#define RME96_IO_RESET_REC_POS 0x5FFFC
-#define RME96_IO_GET_PLAY_POS 0x20000
-#define RME96_IO_GET_REC_POS 0x30000
-
-/* Write control register bits */
-#define RME96_WCR_START (1 << 0)
-#define RME96_WCR_START_2 (1 << 1)
-#define RME96_WCR_GAIN_0 (1 << 2)
-#define RME96_WCR_GAIN_1 (1 << 3)
-#define RME96_WCR_MODE24 (1 << 4)
-#define RME96_WCR_MODE24_2 (1 << 5)
-#define RME96_WCR_BM (1 << 6)
-#define RME96_WCR_BM_2 (1 << 7)
-#define RME96_WCR_ADAT (1 << 8)
-#define RME96_WCR_FREQ_0 (1 << 9)
-#define RME96_WCR_FREQ_1 (1 << 10)
-#define RME96_WCR_DS (1 << 11)
-#define RME96_WCR_PRO (1 << 12)
-#define RME96_WCR_EMP (1 << 13)
-#define RME96_WCR_SEL (1 << 14)
-#define RME96_WCR_MASTER (1 << 15)
-#define RME96_WCR_PD (1 << 16)
-#define RME96_WCR_INP_0 (1 << 17)
-#define RME96_WCR_INP_1 (1 << 18)
-#define RME96_WCR_THRU_0 (1 << 19)
-#define RME96_WCR_THRU_1 (1 << 20)
-#define RME96_WCR_THRU_2 (1 << 21)
-#define RME96_WCR_THRU_3 (1 << 22)
-#define RME96_WCR_THRU_4 (1 << 23)
-#define RME96_WCR_THRU_5 (1 << 24)
-#define RME96_WCR_THRU_6 (1 << 25)
-#define RME96_WCR_THRU_7 (1 << 26)
-#define RME96_WCR_DOLBY (1 << 27)
-#define RME96_WCR_MONITOR_0 (1 << 28)
-#define RME96_WCR_MONITOR_1 (1 << 29)
-#define RME96_WCR_ISEL (1 << 30)
-#define RME96_WCR_IDIS (1 << 31)
-
-#define RME96_WCR_BITPOS_GAIN_0 2
-#define RME96_WCR_BITPOS_GAIN_1 3
-#define RME96_WCR_BITPOS_FREQ_0 9
-#define RME96_WCR_BITPOS_FREQ_1 10
-#define RME96_WCR_BITPOS_INP_0 17
-#define RME96_WCR_BITPOS_INP_1 18
-#define RME96_WCR_BITPOS_MONITOR_0 28
-#define RME96_WCR_BITPOS_MONITOR_1 29
-
-/* Read control register bits */
-#define RME96_RCR_AUDIO_ADDR_MASK 0xFFFF
-#define RME96_RCR_IRQ_2 (1 << 16)
-#define RME96_RCR_T_OUT (1 << 17)
-#define RME96_RCR_DEV_ID_0 (1 << 21)
-#define RME96_RCR_DEV_ID_1 (1 << 22)
-#define RME96_RCR_LOCK (1 << 23)
-#define RME96_RCR_VERF (1 << 26)
-#define RME96_RCR_F0 (1 << 27)
-#define RME96_RCR_F1 (1 << 28)
-#define RME96_RCR_F2 (1 << 29)
-#define RME96_RCR_AUTOSYNC (1 << 30)
-#define RME96_RCR_IRQ (1 << 31)
-
-#define RME96_RCR_BITPOS_F0 27
-#define RME96_RCR_BITPOS_F1 28
-#define RME96_RCR_BITPOS_F2 29
-
-/* Additional register bits */
-#define RME96_AR_WSEL (1 << 0)
-#define RME96_AR_ANALOG (1 << 1)
-#define RME96_AR_FREQPAD_0 (1 << 2)
-#define RME96_AR_FREQPAD_1 (1 << 3)
-#define RME96_AR_FREQPAD_2 (1 << 4)
-#define RME96_AR_PD2 (1 << 5)
-#define RME96_AR_DAC_EN (1 << 6)
-#define RME96_AR_CLATCH (1 << 7)
-#define RME96_AR_CCLK (1 << 8)
-#define RME96_AR_CDATA (1 << 9)
-
-#define RME96_AR_BITPOS_F0 2
-#define RME96_AR_BITPOS_F1 3
-#define RME96_AR_BITPOS_F2 4
-
-/* Monitor tracks */
-#define RME96_MONITOR_TRACKS_1_2 0
-#define RME96_MONITOR_TRACKS_3_4 1
-#define RME96_MONITOR_TRACKS_5_6 2
-#define RME96_MONITOR_TRACKS_7_8 3
-
-/* Attenuation */
-#define RME96_ATTENUATION_0 0
-#define RME96_ATTENUATION_6 1
-#define RME96_ATTENUATION_12 2
-#define RME96_ATTENUATION_18 3
-
-/* Input types */
-#define RME96_INPUT_OPTICAL 0
-#define RME96_INPUT_COAXIAL 1
-#define RME96_INPUT_INTERNAL 2
-#define RME96_INPUT_XLR 3
-#define RME96_INPUT_ANALOG 4
-
-/* Clock modes */
-#define RME96_CLOCKMODE_SLAVE 0
-#define RME96_CLOCKMODE_MASTER 1
-#define RME96_CLOCKMODE_WORDCLOCK 2
-
-/* Block sizes in bytes */
-#define RME96_SMALL_BLOCK_SIZE 2048
-#define RME96_LARGE_BLOCK_SIZE 8192
-
-/* Volume control */
-#define RME96_AD1852_VOL_BITS 14
-#define RME96_AD1855_VOL_BITS 10
-
-
-struct rme96 {
- spinlock_t lock;
- int irq;
- unsigned long port;
- void __iomem *iobase;
-
- u32 wcreg; /* cached write control register value */
- u32 wcreg_spdif; /* S/PDIF setup */
- u32 wcreg_spdif_stream; /* S/PDIF setup (temporary) */
- u32 rcreg; /* cached read control register value */
- u32 areg; /* cached additional register value */
- u16 vol[2]; /* cached volume of analog output */
-
- u8 rev; /* card revision number */
-
- struct snd_pcm_substream *playback_substream;
- struct snd_pcm_substream *capture_substream;
-
- int playback_frlog; /* log2 of framesize */
- int capture_frlog;
-
- size_t playback_periodsize; /* in bytes, zero if not used */
- size_t capture_periodsize; /* in bytes, zero if not used */
-
- struct snd_card *card;
- struct snd_pcm *spdif_pcm;
- struct snd_pcm *adat_pcm;
- struct pci_dev *pci;
- struct snd_kcontrol *spdif_ctl;
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_rme96_ids) = {
- { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96), 0, },
- { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96_8), 0, },
- { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96_8_PRO), 0, },
- { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST), 0, },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_rme96_ids);
-
-#define RME96_ISPLAYING(rme96) ((rme96)->wcreg & RME96_WCR_START)
-#define RME96_ISRECORDING(rme96) ((rme96)->wcreg & RME96_WCR_START_2)
-#define RME96_HAS_ANALOG_IN(rme96) ((rme96)->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST)
-#define RME96_HAS_ANALOG_OUT(rme96) ((rme96)->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PRO || \
- (rme96)->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST)
-#define RME96_DAC_IS_1852(rme96) (RME96_HAS_ANALOG_OUT(rme96) && (rme96)->rev >= 4)
-#define RME96_DAC_IS_1855(rme96) (((rme96)->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST && (rme96)->rev < 4) || \
- ((rme96)->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PRO && (rme96)->rev == 2))
-#define RME96_185X_MAX_OUT(rme96) ((1 << (RME96_DAC_IS_1852(rme96) ? RME96_AD1852_VOL_BITS : RME96_AD1855_VOL_BITS)) - 1)
-
-static int
-snd_rme96_playback_prepare(struct snd_pcm_substream *substream);
-
-static int
-snd_rme96_capture_prepare(struct snd_pcm_substream *substream);
-
-static int
-snd_rme96_playback_trigger(struct snd_pcm_substream *substream,
- int cmd);
-
-static int
-snd_rme96_capture_trigger(struct snd_pcm_substream *substream,
- int cmd);
-
-static snd_pcm_uframes_t
-snd_rme96_playback_pointer(struct snd_pcm_substream *substream);
-
-static snd_pcm_uframes_t
-snd_rme96_capture_pointer(struct snd_pcm_substream *substream);
-
-static void __devinit
-snd_rme96_proc_init(struct rme96 *rme96);
-
-static int
-snd_rme96_create_switches(struct snd_card *card,
- struct rme96 *rme96);
-
-static int
-snd_rme96_getinputtype(struct rme96 *rme96);
-
-static inline unsigned int
-snd_rme96_playback_ptr(struct rme96 *rme96)
-{
- return (readl(rme96->iobase + RME96_IO_GET_PLAY_POS)
- & RME96_RCR_AUDIO_ADDR_MASK) >> rme96->playback_frlog;
-}
-
-static inline unsigned int
-snd_rme96_capture_ptr(struct rme96 *rme96)
-{
- return (readl(rme96->iobase + RME96_IO_GET_REC_POS)
- & RME96_RCR_AUDIO_ADDR_MASK) >> rme96->capture_frlog;
-}
-
-static int
-snd_rme96_playback_silence(struct snd_pcm_substream *substream,
- int channel, /* not used (interleaved data) */
- snd_pcm_uframes_t pos,
- snd_pcm_uframes_t count)
-{
- struct rme96 *rme96 = snd_pcm_substream_chip(substream);
- count <<= rme96->playback_frlog;
- pos <<= rme96->playback_frlog;
- memset_io(rme96->iobase + RME96_IO_PLAY_BUFFER + pos,
- 0, count);
- return 0;
-}
-
-static int
-snd_rme96_playback_copy(struct snd_pcm_substream *substream,
- int channel, /* not used (interleaved data) */
- snd_pcm_uframes_t pos,
- void __user *src,
- snd_pcm_uframes_t count)
-{
- struct rme96 *rme96 = snd_pcm_substream_chip(substream);
- count <<= rme96->playback_frlog;
- pos <<= rme96->playback_frlog;
- copy_from_user_toio(rme96->iobase + RME96_IO_PLAY_BUFFER + pos, src,
- count);
- return 0;
-}
-
-static int
-snd_rme96_capture_copy(struct snd_pcm_substream *substream,
- int channel, /* not used (interleaved data) */
- snd_pcm_uframes_t pos,
- void __user *dst,
- snd_pcm_uframes_t count)
-{
- struct rme96 *rme96 = snd_pcm_substream_chip(substream);
- count <<= rme96->capture_frlog;
- pos <<= rme96->capture_frlog;
- copy_to_user_fromio(dst, rme96->iobase + RME96_IO_REC_BUFFER + pos,
- count);
- return 0;
-}
-
-/*
- * Digital output capabilities (S/PDIF)
- */
-static struct snd_pcm_hardware snd_rme96_playback_spdif_info =
-{
- .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE),
- .formats = (SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S32_LE),
- .rates = (SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_64000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000),
- .rate_min = 32000,
- .rate_max = 96000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = RME96_BUFFER_SIZE,
- .period_bytes_min = RME96_SMALL_BLOCK_SIZE,
- .period_bytes_max = RME96_LARGE_BLOCK_SIZE,
- .periods_min = RME96_BUFFER_SIZE / RME96_LARGE_BLOCK_SIZE,
- .periods_max = RME96_BUFFER_SIZE / RME96_SMALL_BLOCK_SIZE,
- .fifo_size = 0,
-};
-
-/*
- * Digital input capabilities (S/PDIF)
- */
-static struct snd_pcm_hardware snd_rme96_capture_spdif_info =
-{
- .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE),
- .formats = (SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S32_LE),
- .rates = (SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_64000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000),
- .rate_min = 32000,
- .rate_max = 96000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = RME96_BUFFER_SIZE,
- .period_bytes_min = RME96_SMALL_BLOCK_SIZE,
- .period_bytes_max = RME96_LARGE_BLOCK_SIZE,
- .periods_min = RME96_BUFFER_SIZE / RME96_LARGE_BLOCK_SIZE,
- .periods_max = RME96_BUFFER_SIZE / RME96_SMALL_BLOCK_SIZE,
- .fifo_size = 0,
-};
-
-/*
- * Digital output capabilities (ADAT)
- */
-static struct snd_pcm_hardware snd_rme96_playback_adat_info =
-{
- .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE),
- .formats = (SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S32_LE),
- .rates = (SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000),
- .rate_min = 44100,
- .rate_max = 48000,
- .channels_min = 8,
- .channels_max = 8,
- .buffer_bytes_max = RME96_BUFFER_SIZE,
- .period_bytes_min = RME96_SMALL_BLOCK_SIZE,
- .period_bytes_max = RME96_LARGE_BLOCK_SIZE,
- .periods_min = RME96_BUFFER_SIZE / RME96_LARGE_BLOCK_SIZE,
- .periods_max = RME96_BUFFER_SIZE / RME96_SMALL_BLOCK_SIZE,
- .fifo_size = 0,
-};
-
-/*
- * Digital input capabilities (ADAT)
- */
-static struct snd_pcm_hardware snd_rme96_capture_adat_info =
-{
- .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE),
- .formats = (SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S32_LE),
- .rates = (SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000),
- .rate_min = 44100,
- .rate_max = 48000,
- .channels_min = 8,
- .channels_max = 8,
- .buffer_bytes_max = RME96_BUFFER_SIZE,
- .period_bytes_min = RME96_SMALL_BLOCK_SIZE,
- .period_bytes_max = RME96_LARGE_BLOCK_SIZE,
- .periods_min = RME96_BUFFER_SIZE / RME96_LARGE_BLOCK_SIZE,
- .periods_max = RME96_BUFFER_SIZE / RME96_SMALL_BLOCK_SIZE,
- .fifo_size = 0,
-};
-
-/*
- * The CDATA, CCLK and CLATCH bits can be used to write to the SPI interface
- * of the AD1852 or AD1852 D/A converter on the board. CDATA must be set up
- * on the falling edge of CCLK and be stable on the rising edge. The rising
- * edge of CLATCH after the last data bit clocks in the whole data word.
- * A fast processor could probably drive the SPI interface faster than the
- * DAC can handle (3MHz for the 1855, unknown for the 1852). The udelay(1)
- * limits the data rate to 500KHz and only causes a delay of 33 microsecs.
- *
- * NOTE: increased delay from 1 to 10, since there where problems setting
- * the volume.
- */
-static void
-snd_rme96_write_SPI(struct rme96 *rme96, u16 val)
-{
- int i;
-
- for (i = 0; i < 16; i++) {
- if (val & 0x8000) {
- rme96->areg |= RME96_AR_CDATA;
- } else {
- rme96->areg &= ~RME96_AR_CDATA;
- }
- rme96->areg &= ~(RME96_AR_CCLK | RME96_AR_CLATCH);
- writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
- udelay(10);
- rme96->areg |= RME96_AR_CCLK;
- writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
- udelay(10);
- val <<= 1;
- }
- rme96->areg &= ~(RME96_AR_CCLK | RME96_AR_CDATA);
- rme96->areg |= RME96_AR_CLATCH;
- writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
- udelay(10);
- rme96->areg &= ~RME96_AR_CLATCH;
- writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
-}
-
-static void
-snd_rme96_apply_dac_volume(struct rme96 *rme96)
-{
- if (RME96_DAC_IS_1852(rme96)) {
- snd_rme96_write_SPI(rme96, (rme96->vol[0] << 2) | 0x0);
- snd_rme96_write_SPI(rme96, (rme96->vol[1] << 2) | 0x2);
- } else if (RME96_DAC_IS_1855(rme96)) {
- snd_rme96_write_SPI(rme96, (rme96->vol[0] & 0x3FF) | 0x000);
- snd_rme96_write_SPI(rme96, (rme96->vol[1] & 0x3FF) | 0x400);
- }
-}
-
-static void
-snd_rme96_reset_dac(struct rme96 *rme96)
-{
- writel(rme96->wcreg | RME96_WCR_PD,
- rme96->iobase + RME96_IO_CONTROL_REGISTER);
- writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
-}
-
-static int
-snd_rme96_getmontracks(struct rme96 *rme96)
-{
- return ((rme96->wcreg >> RME96_WCR_BITPOS_MONITOR_0) & 1) +
- (((rme96->wcreg >> RME96_WCR_BITPOS_MONITOR_1) & 1) << 1);
-}
-
-static int
-snd_rme96_setmontracks(struct rme96 *rme96,
- int montracks)
-{
- if (montracks & 1) {
- rme96->wcreg |= RME96_WCR_MONITOR_0;
- } else {
- rme96->wcreg &= ~RME96_WCR_MONITOR_0;
- }
- if (montracks & 2) {
- rme96->wcreg |= RME96_WCR_MONITOR_1;
- } else {
- rme96->wcreg &= ~RME96_WCR_MONITOR_1;
- }
- writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
- return 0;
-}
-
-static int
-snd_rme96_getattenuation(struct rme96 *rme96)
-{
- return ((rme96->wcreg >> RME96_WCR_BITPOS_GAIN_0) & 1) +
- (((rme96->wcreg >> RME96_WCR_BITPOS_GAIN_1) & 1) << 1);
-}
-
-static int
-snd_rme96_setattenuation(struct rme96 *rme96,
- int attenuation)
-{
- switch (attenuation) {
- case 0:
- rme96->wcreg = (rme96->wcreg & ~RME96_WCR_GAIN_0) &
- ~RME96_WCR_GAIN_1;
- break;
- case 1:
- rme96->wcreg = (rme96->wcreg | RME96_WCR_GAIN_0) &
- ~RME96_WCR_GAIN_1;
- break;
- case 2:
- rme96->wcreg = (rme96->wcreg & ~RME96_WCR_GAIN_0) |
- RME96_WCR_GAIN_1;
- break;
- case 3:
- rme96->wcreg = (rme96->wcreg | RME96_WCR_GAIN_0) |
- RME96_WCR_GAIN_1;
- break;
- default:
- return -EINVAL;
- }
- writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
- return 0;
-}
-
-static int
-snd_rme96_capture_getrate(struct rme96 *rme96,
- int *is_adat)
-{
- int n, rate;
-
- *is_adat = 0;
- if (rme96->areg & RME96_AR_ANALOG) {
- /* Analog input, overrides S/PDIF setting */
- n = ((rme96->areg >> RME96_AR_BITPOS_F0) & 1) +
- (((rme96->areg >> RME96_AR_BITPOS_F1) & 1) << 1);
- switch (n) {
- case 1:
- rate = 32000;
- break;
- case 2:
- rate = 44100;
- break;
- case 3:
- rate = 48000;
- break;
- default:
- return -1;
- }
- return (rme96->areg & RME96_AR_BITPOS_F2) ? rate << 1 : rate;
- }
-
- rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
- if (rme96->rcreg & RME96_RCR_LOCK) {
- /* ADAT rate */
- *is_adat = 1;
- if (rme96->rcreg & RME96_RCR_T_OUT) {
- return 48000;
- }
- return 44100;
- }
-
- if (rme96->rcreg & RME96_RCR_VERF) {
- return -1;
- }
-
- /* S/PDIF rate */
- n = ((rme96->rcreg >> RME96_RCR_BITPOS_F0) & 1) +
- (((rme96->rcreg >> RME96_RCR_BITPOS_F1) & 1) << 1) +
- (((rme96->rcreg >> RME96_RCR_BITPOS_F2) & 1) << 2);
-
- switch (n) {
- case 0:
- if (rme96->rcreg & RME96_RCR_T_OUT) {
- return 64000;
- }
- return -1;
- case 3: return 96000;
- case 4: return 88200;
- case 5: return 48000;
- case 6: return 44100;
- case 7: return 32000;
- default:
- break;
- }
- return -1;
-}
-
-static int
-snd_rme96_playback_getrate(struct rme96 *rme96)
-{
- int rate, dummy;
-
- if (!(rme96->wcreg & RME96_WCR_MASTER) &&
- snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
- (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
- {
- /* slave clock */
- return rate;
- }
- rate = ((rme96->wcreg >> RME96_WCR_BITPOS_FREQ_0) & 1) +
- (((rme96->wcreg >> RME96_WCR_BITPOS_FREQ_1) & 1) << 1);
- switch (rate) {
- case 1:
- rate = 32000;
- break;
- case 2:
- rate = 44100;
- break;
- case 3:
- rate = 48000;
- break;
- default:
- return -1;
- }
- return (rme96->wcreg & RME96_WCR_DS) ? rate << 1 : rate;
-}
-
-static int
-snd_rme96_playback_setrate(struct rme96 *rme96,
- int rate)
-{
- int ds;
-
- ds = rme96->wcreg & RME96_WCR_DS;
- switch (rate) {
- case 32000:
- rme96->wcreg &= ~RME96_WCR_DS;
- rme96->wcreg = (rme96->wcreg | RME96_WCR_FREQ_0) &
- ~RME96_WCR_FREQ_1;
- break;
- case 44100:
- rme96->wcreg &= ~RME96_WCR_DS;
- rme96->wcreg = (rme96->wcreg | RME96_WCR_FREQ_1) &
- ~RME96_WCR_FREQ_0;
- break;
- case 48000:
- rme96->wcreg &= ~RME96_WCR_DS;
- rme96->wcreg = (rme96->wcreg | RME96_WCR_FREQ_0) |
- RME96_WCR_FREQ_1;
- break;
- case 64000:
- rme96->wcreg |= RME96_WCR_DS;
- rme96->wcreg = (rme96->wcreg | RME96_WCR_FREQ_0) &
- ~RME96_WCR_FREQ_1;
- break;
- case 88200:
- rme96->wcreg |= RME96_WCR_DS;
- rme96->wcreg = (rme96->wcreg | RME96_WCR_FREQ_1) &
- ~RME96_WCR_FREQ_0;
- break;
- case 96000:
- rme96->wcreg |= RME96_WCR_DS;
- rme96->wcreg = (rme96->wcreg | RME96_WCR_FREQ_0) |
- RME96_WCR_FREQ_1;
- break;
- default:
- return -EINVAL;
- }
- if ((!ds && rme96->wcreg & RME96_WCR_DS) ||
- (ds && !(rme96->wcreg & RME96_WCR_DS)))
- {
- /* change to/from double-speed: reset the DAC (if available) */
- snd_rme96_reset_dac(rme96);
- } else {
- writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
- }
- return 0;
-}
-
-static int
-snd_rme96_capture_analog_setrate(struct rme96 *rme96,
- int rate)
-{
- switch (rate) {
- case 32000:
- rme96->areg = ((rme96->areg | RME96_AR_FREQPAD_0) &
- ~RME96_AR_FREQPAD_1) & ~RME96_AR_FREQPAD_2;
- break;
- case 44100:
- rme96->areg = ((rme96->areg & ~RME96_AR_FREQPAD_0) |
- RME96_AR_FREQPAD_1) & ~RME96_AR_FREQPAD_2;
- break;
- case 48000:
- rme96->areg = ((rme96->areg | RME96_AR_FREQPAD_0) |
- RME96_AR_FREQPAD_1) & ~RME96_AR_FREQPAD_2;
- break;
- case 64000:
- if (rme96->rev < 4) {
- return -EINVAL;
- }
- rme96->areg = ((rme96->areg | RME96_AR_FREQPAD_0) &
- ~RME96_AR_FREQPAD_1) | RME96_AR_FREQPAD_2;
- break;
- case 88200:
- if (rme96->rev < 4) {
- return -EINVAL;
- }
- rme96->areg = ((rme96->areg & ~RME96_AR_FREQPAD_0) |
- RME96_AR_FREQPAD_1) | RME96_AR_FREQPAD_2;
- break;
- case 96000:
- rme96->areg = ((rme96->areg | RME96_AR_FREQPAD_0) |
- RME96_AR_FREQPAD_1) | RME96_AR_FREQPAD_2;
- break;
- default:
- return -EINVAL;
- }
- writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
- return 0;
-}
-
-static int
-snd_rme96_setclockmode(struct rme96 *rme96,
- int mode)
-{
- switch (mode) {
- case RME96_CLOCKMODE_SLAVE:
- /* AutoSync */
- rme96->wcreg &= ~RME96_WCR_MASTER;
- rme96->areg &= ~RME96_AR_WSEL;
- break;
- case RME96_CLOCKMODE_MASTER:
- /* Internal */
- rme96->wcreg |= RME96_WCR_MASTER;
- rme96->areg &= ~RME96_AR_WSEL;
- break;
- case RME96_CLOCKMODE_WORDCLOCK:
- /* Word clock is a master mode */
- rme96->wcreg |= RME96_WCR_MASTER;
- rme96->areg |= RME96_AR_WSEL;
- break;
- default:
- return -EINVAL;
- }
- writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
- writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
- return 0;
-}
-
-static int
-snd_rme96_getclockmode(struct rme96 *rme96)
-{
- if (rme96->areg & RME96_AR_WSEL) {
- return RME96_CLOCKMODE_WORDCLOCK;
- }
- return (rme96->wcreg & RME96_WCR_MASTER) ? RME96_CLOCKMODE_MASTER :
- RME96_CLOCKMODE_SLAVE;
-}
-
-static int
-snd_rme96_setinputtype(struct rme96 *rme96,
- int type)
-{
- int n;
-
- switch (type) {
- case RME96_INPUT_OPTICAL:
- rme96->wcreg = (rme96->wcreg & ~RME96_WCR_INP_0) &
- ~RME96_WCR_INP_1;
- break;
- case RME96_INPUT_COAXIAL:
- rme96->wcreg = (rme96->wcreg | RME96_WCR_INP_0) &
- ~RME96_WCR_INP_1;
- break;
- case RME96_INPUT_INTERNAL:
- rme96->wcreg = (rme96->wcreg & ~RME96_WCR_INP_0) |
- RME96_WCR_INP_1;
- break;
- case RME96_INPUT_XLR:
- if ((rme96->pci->device != PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST &&
- rme96->pci->device != PCI_DEVICE_ID_RME_DIGI96_8_PRO) ||
- (rme96->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST &&
- rme96->rev > 4))
- {
- /* Only Digi96/8 PRO and Digi96/8 PAD supports XLR */
- return -EINVAL;
- }
- rme96->wcreg = (rme96->wcreg | RME96_WCR_INP_0) |
- RME96_WCR_INP_1;
- break;
- case RME96_INPUT_ANALOG:
- if (!RME96_HAS_ANALOG_IN(rme96)) {
- return -EINVAL;
- }
- rme96->areg |= RME96_AR_ANALOG;
- writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
- if (rme96->rev < 4) {
- /*
- * Revision less than 004 does not support 64 and
- * 88.2 kHz
- */
- if (snd_rme96_capture_getrate(rme96, &n) == 88200) {
- snd_rme96_capture_analog_setrate(rme96, 44100);
- }
- if (snd_rme96_capture_getrate(rme96, &n) == 64000) {
- snd_rme96_capture_analog_setrate(rme96, 32000);
- }
- }
- return 0;
- default:
- return -EINVAL;
- }
- if (type != RME96_INPUT_ANALOG && RME96_HAS_ANALOG_IN(rme96)) {
- rme96->areg &= ~RME96_AR_ANALOG;
- writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
- }
- writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
- return 0;
-}
-
-static int
-snd_rme96_getinputtype(struct rme96 *rme96)
-{
- if (rme96->areg & RME96_AR_ANALOG) {
- return RME96_INPUT_ANALOG;
- }
- return ((rme96->wcreg >> RME96_WCR_BITPOS_INP_0) & 1) +
- (((rme96->wcreg >> RME96_WCR_BITPOS_INP_1) & 1) << 1);
-}
-
-static void
-snd_rme96_setframelog(struct rme96 *rme96,
- int n_channels,
- int is_playback)
-{
- int frlog;
-
- if (n_channels == 2) {
- frlog = 1;
- } else {
- /* assume 8 channels */
- frlog = 3;
- }
- if (is_playback) {
- frlog += (rme96->wcreg & RME96_WCR_MODE24) ? 2 : 1;
- rme96->playback_frlog = frlog;
- } else {
- frlog += (rme96->wcreg & RME96_WCR_MODE24_2) ? 2 : 1;
- rme96->capture_frlog = frlog;
- }
-}
-
-static int
-snd_rme96_playback_setformat(struct rme96 *rme96,
- int format)
-{
- switch (format) {
- case SNDRV_PCM_FORMAT_S16_LE:
- rme96->wcreg &= ~RME96_WCR_MODE24;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- rme96->wcreg |= RME96_WCR_MODE24;
- break;
- default:
- return -EINVAL;
- }
- writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
- return 0;
-}
-
-static int
-snd_rme96_capture_setformat(struct rme96 *rme96,
- int format)
-{
- switch (format) {
- case SNDRV_PCM_FORMAT_S16_LE:
- rme96->wcreg &= ~RME96_WCR_MODE24_2;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- rme96->wcreg |= RME96_WCR_MODE24_2;
- break;
- default:
- return -EINVAL;
- }
- writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
- return 0;
-}
-
-static void
-snd_rme96_set_period_properties(struct rme96 *rme96,
- size_t period_bytes)
-{
- switch (period_bytes) {
- case RME96_LARGE_BLOCK_SIZE:
- rme96->wcreg &= ~RME96_WCR_ISEL;
- break;
- case RME96_SMALL_BLOCK_SIZE:
- rme96->wcreg |= RME96_WCR_ISEL;
- break;
- default:
- snd_BUG();
- break;
- }
- rme96->wcreg &= ~RME96_WCR_IDIS;
- writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
-}
-
-static int
-snd_rme96_playback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct rme96 *rme96 = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err, rate, dummy;
-
- runtime->dma_area = (void __force *)(rme96->iobase +
- RME96_IO_PLAY_BUFFER);
- runtime->dma_addr = rme96->port + RME96_IO_PLAY_BUFFER;
- runtime->dma_bytes = RME96_BUFFER_SIZE;
-
- spin_lock_irq(&rme96->lock);
- if (!(rme96->wcreg & RME96_WCR_MASTER) &&
- snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
- (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
- {
- /* slave clock */
- if ((int)params_rate(params) != rate) {
- spin_unlock_irq(&rme96->lock);
- return -EIO;
- }
- } else if ((err = snd_rme96_playback_setrate(rme96, params_rate(params))) < 0) {
- spin_unlock_irq(&rme96->lock);
- return err;
- }
- if ((err = snd_rme96_playback_setformat(rme96, params_format(params))) < 0) {
- spin_unlock_irq(&rme96->lock);
- return err;
- }
- snd_rme96_setframelog(rme96, params_channels(params), 1);
- if (rme96->capture_periodsize != 0) {
- if (params_period_size(params) << rme96->playback_frlog !=
- rme96->capture_periodsize)
- {
- spin_unlock_irq(&rme96->lock);
- return -EBUSY;
- }
- }
- rme96->playback_periodsize =
- params_period_size(params) << rme96->playback_frlog;
- snd_rme96_set_period_properties(rme96, rme96->playback_periodsize);
- /* S/PDIF setup */
- if ((rme96->wcreg & RME96_WCR_ADAT) == 0) {
- rme96->wcreg &= ~(RME96_WCR_PRO | RME96_WCR_DOLBY | RME96_WCR_EMP);
- writel(rme96->wcreg |= rme96->wcreg_spdif_stream, rme96->iobase + RME96_IO_CONTROL_REGISTER);
- }
- spin_unlock_irq(&rme96->lock);
-
- return 0;
-}
-
-static int
-snd_rme96_capture_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct rme96 *rme96 = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err, isadat, rate;
-
- runtime->dma_area = (void __force *)(rme96->iobase +
- RME96_IO_REC_BUFFER);
- runtime->dma_addr = rme96->port + RME96_IO_REC_BUFFER;
- runtime->dma_bytes = RME96_BUFFER_SIZE;
-
- spin_lock_irq(&rme96->lock);
- if ((err = snd_rme96_capture_setformat(rme96, params_format(params))) < 0) {
- spin_unlock_irq(&rme96->lock);
- return err;
- }
- if (snd_rme96_getinputtype(rme96) == RME96_INPUT_ANALOG) {
- if ((err = snd_rme96_capture_analog_setrate(rme96,
- params_rate(params))) < 0)
- {
- spin_unlock_irq(&rme96->lock);
- return err;
- }
- } else if ((rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) {
- if ((int)params_rate(params) != rate) {
- spin_unlock_irq(&rme96->lock);
- return -EIO;
- }
- if ((isadat && runtime->hw.channels_min == 2) ||
- (!isadat && runtime->hw.channels_min == 8))
- {
- spin_unlock_irq(&rme96->lock);
- return -EIO;
- }
- }
- snd_rme96_setframelog(rme96, params_channels(params), 0);
- if (rme96->playback_periodsize != 0) {
- if (params_period_size(params) << rme96->capture_frlog !=
- rme96->playback_periodsize)
- {
- spin_unlock_irq(&rme96->lock);
- return -EBUSY;
- }
- }
- rme96->capture_periodsize =
- params_period_size(params) << rme96->capture_frlog;
- snd_rme96_set_period_properties(rme96, rme96->capture_periodsize);
- spin_unlock_irq(&rme96->lock);
-
- return 0;
-}
-
-static void
-snd_rme96_playback_start(struct rme96 *rme96,
- int from_pause)
-{
- if (!from_pause) {
- writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS);
- }
-
- rme96->wcreg |= RME96_WCR_START;
- writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
-}
-
-static void
-snd_rme96_capture_start(struct rme96 *rme96,
- int from_pause)
-{
- if (!from_pause) {
- writel(0, rme96->iobase + RME96_IO_RESET_REC_POS);
- }
-
- rme96->wcreg |= RME96_WCR_START_2;
- writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
-}
-
-static void
-snd_rme96_playback_stop(struct rme96 *rme96)
-{
- /*
- * Check if there is an unconfirmed IRQ, if so confirm it, or else
- * the hardware will not stop generating interrupts
- */
- rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
- if (rme96->rcreg & RME96_RCR_IRQ) {
- writel(0, rme96->iobase + RME96_IO_CONFIRM_PLAY_IRQ);
- }
- rme96->wcreg &= ~RME96_WCR_START;
- writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
-}
-
-static void
-snd_rme96_capture_stop(struct rme96 *rme96)
-{
- rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
- if (rme96->rcreg & RME96_RCR_IRQ_2) {
- writel(0, rme96->iobase + RME96_IO_CONFIRM_REC_IRQ);
- }
- rme96->wcreg &= ~RME96_WCR_START_2;
- writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
-}
-
-static irqreturn_t
-snd_rme96_interrupt(int irq,
- void *dev_id)
-{
- struct rme96 *rme96 = (struct rme96 *)dev_id;
-
- rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
- /* fastpath out, to ease interrupt sharing */
- if (!((rme96->rcreg & RME96_RCR_IRQ) ||
- (rme96->rcreg & RME96_RCR_IRQ_2)))
- {
- return IRQ_NONE;
- }
-
- if (rme96->rcreg & RME96_RCR_IRQ) {
- /* playback */
- snd_pcm_period_elapsed(rme96->playback_substream);
- writel(0, rme96->iobase + RME96_IO_CONFIRM_PLAY_IRQ);
- }
- if (rme96->rcreg & RME96_RCR_IRQ_2) {
- /* capture */
- snd_pcm_period_elapsed(rme96->capture_substream);
- writel(0, rme96->iobase + RME96_IO_CONFIRM_REC_IRQ);
- }
- return IRQ_HANDLED;
-}
-
-static unsigned int period_bytes[] = { RME96_SMALL_BLOCK_SIZE, RME96_LARGE_BLOCK_SIZE };
-
-static struct snd_pcm_hw_constraint_list hw_constraints_period_bytes = {
- .count = ARRAY_SIZE(period_bytes),
- .list = period_bytes,
- .mask = 0
-};
-
-static void
-rme96_set_buffer_size_constraint(struct rme96 *rme96,
- struct snd_pcm_runtime *runtime)
-{
- unsigned int size;
-
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
- RME96_BUFFER_SIZE, RME96_BUFFER_SIZE);
- if ((size = rme96->playback_periodsize) != 0 ||
- (size = rme96->capture_periodsize) != 0)
- snd_pcm_hw_constraint_minmax(runtime,
- SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- size, size);
- else
- snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- &hw_constraints_period_bytes);
-}
-
-static int
-snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream)
-{
- int rate, dummy;
- struct rme96 *rme96 = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- spin_lock_irq(&rme96->lock);
- if (rme96->playback_substream != NULL) {
- spin_unlock_irq(&rme96->lock);
- return -EBUSY;
- }
- rme96->wcreg &= ~RME96_WCR_ADAT;
- writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
- rme96->playback_substream = substream;
- spin_unlock_irq(&rme96->lock);
-
- runtime->hw = snd_rme96_playback_spdif_info;
- if (!(rme96->wcreg & RME96_WCR_MASTER) &&
- snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
- (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
- {
- /* slave clock */
- runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
- runtime->hw.rate_min = rate;
- runtime->hw.rate_max = rate;
- }
- rme96_set_buffer_size_constraint(rme96, runtime);
-
- rme96->wcreg_spdif_stream = rme96->wcreg_spdif;
- rme96->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(rme96->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO, &rme96->spdif_ctl->id);
- return 0;
-}
-
-static int
-snd_rme96_capture_spdif_open(struct snd_pcm_substream *substream)
-{
- int isadat, rate;
- struct rme96 *rme96 = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- runtime->hw = snd_rme96_capture_spdif_info;
- if (snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
- (rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0)
- {
- if (isadat) {
- return -EIO;
- }
- runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
- runtime->hw.rate_min = rate;
- runtime->hw.rate_max = rate;
- }
-
- spin_lock_irq(&rme96->lock);
- if (rme96->capture_substream != NULL) {
- spin_unlock_irq(&rme96->lock);
- return -EBUSY;
- }
- rme96->capture_substream = substream;
- spin_unlock_irq(&rme96->lock);
-
- rme96_set_buffer_size_constraint(rme96, runtime);
- return 0;
-}
-
-static int
-snd_rme96_playback_adat_open(struct snd_pcm_substream *substream)
-{
- int rate, dummy;
- struct rme96 *rme96 = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- spin_lock_irq(&rme96->lock);
- if (rme96->playback_substream != NULL) {
- spin_unlock_irq(&rme96->lock);
- return -EBUSY;
- }
- rme96->wcreg |= RME96_WCR_ADAT;
- writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
- rme96->playback_substream = substream;
- spin_unlock_irq(&rme96->lock);
-
- runtime->hw = snd_rme96_playback_adat_info;
- if (!(rme96->wcreg & RME96_WCR_MASTER) &&
- snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
- (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
- {
- /* slave clock */
- runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
- runtime->hw.rate_min = rate;
- runtime->hw.rate_max = rate;
- }
- rme96_set_buffer_size_constraint(rme96, runtime);
- return 0;
-}
-
-static int
-snd_rme96_capture_adat_open(struct snd_pcm_substream *substream)
-{
- int isadat, rate;
- struct rme96 *rme96 = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- runtime->hw = snd_rme96_capture_adat_info;
- if (snd_rme96_getinputtype(rme96) == RME96_INPUT_ANALOG) {
- /* makes no sense to use analog input. Note that analog
- expension cards AEB4/8-I are RME96_INPUT_INTERNAL */
- return -EIO;
- }
- if ((rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) {
- if (!isadat) {
- return -EIO;
- }
- runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
- runtime->hw.rate_min = rate;
- runtime->hw.rate_max = rate;
- }
-
- spin_lock_irq(&rme96->lock);
- if (rme96->capture_substream != NULL) {
- spin_unlock_irq(&rme96->lock);
- return -EBUSY;
- }
- rme96->capture_substream = substream;
- spin_unlock_irq(&rme96->lock);
-
- rme96_set_buffer_size_constraint(rme96, runtime);
- return 0;
-}
-
-static int
-snd_rme96_playback_close(struct snd_pcm_substream *substream)
-{
- struct rme96 *rme96 = snd_pcm_substream_chip(substream);
- int spdif = 0;
-
- spin_lock_irq(&rme96->lock);
- if (RME96_ISPLAYING(rme96)) {
- snd_rme96_playback_stop(rme96);
- }
- rme96->playback_substream = NULL;
- rme96->playback_periodsize = 0;
- spdif = (rme96->wcreg & RME96_WCR_ADAT) == 0;
- spin_unlock_irq(&rme96->lock);
- if (spdif) {
- rme96->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(rme96->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO, &rme96->spdif_ctl->id);
- }
- return 0;
-}
-
-static int
-snd_rme96_capture_close(struct snd_pcm_substream *substream)
-{
- struct rme96 *rme96 = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&rme96->lock);
- if (RME96_ISRECORDING(rme96)) {
- snd_rme96_capture_stop(rme96);
- }
- rme96->capture_substream = NULL;
- rme96->capture_periodsize = 0;
- spin_unlock_irq(&rme96->lock);
- return 0;
-}
-
-static int
-snd_rme96_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct rme96 *rme96 = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&rme96->lock);
- if (RME96_ISPLAYING(rme96)) {
- snd_rme96_playback_stop(rme96);
- }
- writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS);
- spin_unlock_irq(&rme96->lock);
- return 0;
-}
-
-static int
-snd_rme96_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct rme96 *rme96 = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&rme96->lock);
- if (RME96_ISRECORDING(rme96)) {
- snd_rme96_capture_stop(rme96);
- }
- writel(0, rme96->iobase + RME96_IO_RESET_REC_POS);
- spin_unlock_irq(&rme96->lock);
- return 0;
-}
-
-static int
-snd_rme96_playback_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct rme96 *rme96 = snd_pcm_substream_chip(substream);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- if (!RME96_ISPLAYING(rme96)) {
- if (substream != rme96->playback_substream) {
- return -EBUSY;
- }
- snd_rme96_playback_start(rme96, 0);
- }
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- if (RME96_ISPLAYING(rme96)) {
- if (substream != rme96->playback_substream) {
- return -EBUSY;
- }
- snd_rme96_playback_stop(rme96);
- }
- break;
-
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (RME96_ISPLAYING(rme96)) {
- snd_rme96_playback_stop(rme96);
- }
- break;
-
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (!RME96_ISPLAYING(rme96)) {
- snd_rme96_playback_start(rme96, 1);
- }
- break;
-
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int
-snd_rme96_capture_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct rme96 *rme96 = snd_pcm_substream_chip(substream);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- if (!RME96_ISRECORDING(rme96)) {
- if (substream != rme96->capture_substream) {
- return -EBUSY;
- }
- snd_rme96_capture_start(rme96, 0);
- }
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- if (RME96_ISRECORDING(rme96)) {
- if (substream != rme96->capture_substream) {
- return -EBUSY;
- }
- snd_rme96_capture_stop(rme96);
- }
- break;
-
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (RME96_ISRECORDING(rme96)) {
- snd_rme96_capture_stop(rme96);
- }
- break;
-
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (!RME96_ISRECORDING(rme96)) {
- snd_rme96_capture_start(rme96, 1);
- }
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static snd_pcm_uframes_t
-snd_rme96_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct rme96 *rme96 = snd_pcm_substream_chip(substream);
- return snd_rme96_playback_ptr(rme96);
-}
-
-static snd_pcm_uframes_t
-snd_rme96_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct rme96 *rme96 = snd_pcm_substream_chip(substream);
- return snd_rme96_capture_ptr(rme96);
-}
-
-static struct snd_pcm_ops snd_rme96_playback_spdif_ops = {
- .open = snd_rme96_playback_spdif_open,
- .close = snd_rme96_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_rme96_playback_hw_params,
- .prepare = snd_rme96_playback_prepare,
- .trigger = snd_rme96_playback_trigger,
- .pointer = snd_rme96_playback_pointer,
- .copy = snd_rme96_playback_copy,
- .silence = snd_rme96_playback_silence,
- .mmap = snd_pcm_lib_mmap_iomem,
-};
-
-static struct snd_pcm_ops snd_rme96_capture_spdif_ops = {
- .open = snd_rme96_capture_spdif_open,
- .close = snd_rme96_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_rme96_capture_hw_params,
- .prepare = snd_rme96_capture_prepare,
- .trigger = snd_rme96_capture_trigger,
- .pointer = snd_rme96_capture_pointer,
- .copy = snd_rme96_capture_copy,
- .mmap = snd_pcm_lib_mmap_iomem,
-};
-
-static struct snd_pcm_ops snd_rme96_playback_adat_ops = {
- .open = snd_rme96_playback_adat_open,
- .close = snd_rme96_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_rme96_playback_hw_params,
- .prepare = snd_rme96_playback_prepare,
- .trigger = snd_rme96_playback_trigger,
- .pointer = snd_rme96_playback_pointer,
- .copy = snd_rme96_playback_copy,
- .silence = snd_rme96_playback_silence,
- .mmap = snd_pcm_lib_mmap_iomem,
-};
-
-static struct snd_pcm_ops snd_rme96_capture_adat_ops = {
- .open = snd_rme96_capture_adat_open,
- .close = snd_rme96_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_rme96_capture_hw_params,
- .prepare = snd_rme96_capture_prepare,
- .trigger = snd_rme96_capture_trigger,
- .pointer = snd_rme96_capture_pointer,
- .copy = snd_rme96_capture_copy,
- .mmap = snd_pcm_lib_mmap_iomem,
-};
-
-static void
-snd_rme96_free(void *private_data)
-{
- struct rme96 *rme96 = (struct rme96 *)private_data;
-
- if (rme96 == NULL) {
- return;
- }
- if (rme96->irq >= 0) {
- snd_rme96_playback_stop(rme96);
- snd_rme96_capture_stop(rme96);
- rme96->areg &= ~RME96_AR_DAC_EN;
- writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
- free_irq(rme96->irq, (void *)rme96);
- rme96->irq = -1;
- }
- if (rme96->iobase) {
- iounmap(rme96->iobase);
- rme96->iobase = NULL;
- }
- if (rme96->port) {
- pci_release_regions(rme96->pci);
- rme96->port = 0;
- }
- pci_disable_device(rme96->pci);
-}
-
-static void
-snd_rme96_free_spdif_pcm(struct snd_pcm *pcm)
-{
- struct rme96 *rme96 = pcm->private_data;
- rme96->spdif_pcm = NULL;
-}
-
-static void
-snd_rme96_free_adat_pcm(struct snd_pcm *pcm)
-{
- struct rme96 *rme96 = pcm->private_data;
- rme96->adat_pcm = NULL;
-}
-
-static int __devinit
-snd_rme96_create(struct rme96 *rme96)
-{
- struct pci_dev *pci = rme96->pci;
- int err;
-
- rme96->irq = -1;
- spin_lock_init(&rme96->lock);
-
- if ((err = pci_enable_device(pci)) < 0)
- return err;
-
- if ((err = pci_request_regions(pci, "RME96")) < 0)
- return err;
- rme96->port = pci_resource_start(rme96->pci, 0);
-
- rme96->iobase = ioremap_nocache(rme96->port, RME96_IO_SIZE);
- if (!rme96->iobase) {
- snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n", rme96->port, rme96->port + RME96_IO_SIZE - 1);
- return -ENOMEM;
- }
-
- if (request_irq(pci->irq, snd_rme96_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, rme96)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- return -EBUSY;
- }
- rme96->irq = pci->irq;
-
- /* read the card's revision number */
- pci_read_config_byte(pci, 8, &rme96->rev);
-
- /* set up ALSA pcm device for S/PDIF */
- if ((err = snd_pcm_new(rme96->card, "Digi96 IEC958", 0,
- 1, 1, &rme96->spdif_pcm)) < 0)
- {
- return err;
- }
- rme96->spdif_pcm->private_data = rme96;
- rme96->spdif_pcm->private_free = snd_rme96_free_spdif_pcm;
- strcpy(rme96->spdif_pcm->name, "Digi96 IEC958");
- snd_pcm_set_ops(rme96->spdif_pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_rme96_playback_spdif_ops);
- snd_pcm_set_ops(rme96->spdif_pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_rme96_capture_spdif_ops);
-
- rme96->spdif_pcm->info_flags = 0;
-
- /* set up ALSA pcm device for ADAT */
- if (pci->device == PCI_DEVICE_ID_RME_DIGI96) {
- /* ADAT is not available on the base model */
- rme96->adat_pcm = NULL;
- } else {
- if ((err = snd_pcm_new(rme96->card, "Digi96 ADAT", 1,
- 1, 1, &rme96->adat_pcm)) < 0)
- {
- return err;
- }
- rme96->adat_pcm->private_data = rme96;
- rme96->adat_pcm->private_free = snd_rme96_free_adat_pcm;
- strcpy(rme96->adat_pcm->name, "Digi96 ADAT");
- snd_pcm_set_ops(rme96->adat_pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_rme96_playback_adat_ops);
- snd_pcm_set_ops(rme96->adat_pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_rme96_capture_adat_ops);
-
- rme96->adat_pcm->info_flags = 0;
- }
-
- rme96->playback_periodsize = 0;
- rme96->capture_periodsize = 0;
-
- /* make sure playback/capture is stopped, if by some reason active */
- snd_rme96_playback_stop(rme96);
- snd_rme96_capture_stop(rme96);
-
- /* set default values in registers */
- rme96->wcreg =
- RME96_WCR_FREQ_1 | /* set 44.1 kHz playback */
- RME96_WCR_SEL | /* normal playback */
- RME96_WCR_MASTER | /* set to master clock mode */
- RME96_WCR_INP_0; /* set coaxial input */
-
- rme96->areg = RME96_AR_FREQPAD_1; /* set 44.1 kHz analog capture */
-
- writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
- writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
-
- /* reset the ADC */
- writel(rme96->areg | RME96_AR_PD2,
- rme96->iobase + RME96_IO_ADDITIONAL_REG);
- writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
-
- /* reset and enable the DAC (order is important). */
- snd_rme96_reset_dac(rme96);
- rme96->areg |= RME96_AR_DAC_EN;
- writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
-
- /* reset playback and record buffer pointers */
- writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS);
- writel(0, rme96->iobase + RME96_IO_RESET_REC_POS);
-
- /* reset volume */
- rme96->vol[0] = rme96->vol[1] = 0;
- if (RME96_HAS_ANALOG_OUT(rme96)) {
- snd_rme96_apply_dac_volume(rme96);
- }
-
- /* init switch interface */
- if ((err = snd_rme96_create_switches(rme96->card, rme96)) < 0) {
- return err;
- }
-
- /* init proc interface */
- snd_rme96_proc_init(rme96);
-
- return 0;
-}
-
-/*
- * proc interface
- */
-
-static void
-snd_rme96_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- int n;
- struct rme96 *rme96 = entry->private_data;
-
- rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
-
- snd_iprintf(buffer, rme96->card->longname);
- snd_iprintf(buffer, " (index #%d)\n", rme96->card->number + 1);
-
- snd_iprintf(buffer, "\nGeneral settings\n");
- if (rme96->wcreg & RME96_WCR_IDIS) {
- snd_iprintf(buffer, " period size: N/A (interrupts "
- "disabled)\n");
- } else if (rme96->wcreg & RME96_WCR_ISEL) {
- snd_iprintf(buffer, " period size: 2048 bytes\n");
- } else {
- snd_iprintf(buffer, " period size: 8192 bytes\n");
- }
- snd_iprintf(buffer, "\nInput settings\n");
- switch (snd_rme96_getinputtype(rme96)) {
- case RME96_INPUT_OPTICAL:
- snd_iprintf(buffer, " input: optical");
- break;
- case RME96_INPUT_COAXIAL:
- snd_iprintf(buffer, " input: coaxial");
- break;
- case RME96_INPUT_INTERNAL:
- snd_iprintf(buffer, " input: internal");
- break;
- case RME96_INPUT_XLR:
- snd_iprintf(buffer, " input: XLR");
- break;
- case RME96_INPUT_ANALOG:
- snd_iprintf(buffer, " input: analog");
- break;
- }
- if (snd_rme96_capture_getrate(rme96, &n) < 0) {
- snd_iprintf(buffer, "\n sample rate: no valid signal\n");
- } else {
- if (n) {
- snd_iprintf(buffer, " (8 channels)\n");
- } else {
- snd_iprintf(buffer, " (2 channels)\n");
- }
- snd_iprintf(buffer, " sample rate: %d Hz\n",
- snd_rme96_capture_getrate(rme96, &n));
- }
- if (rme96->wcreg & RME96_WCR_MODE24_2) {
- snd_iprintf(buffer, " sample format: 24 bit\n");
- } else {
- snd_iprintf(buffer, " sample format: 16 bit\n");
- }
-
- snd_iprintf(buffer, "\nOutput settings\n");
- if (rme96->wcreg & RME96_WCR_SEL) {
- snd_iprintf(buffer, " output signal: normal playback\n");
- } else {
- snd_iprintf(buffer, " output signal: same as input\n");
- }
- snd_iprintf(buffer, " sample rate: %d Hz\n",
- snd_rme96_playback_getrate(rme96));
- if (rme96->wcreg & RME96_WCR_MODE24) {
- snd_iprintf(buffer, " sample format: 24 bit\n");
- } else {
- snd_iprintf(buffer, " sample format: 16 bit\n");
- }
- if (rme96->areg & RME96_AR_WSEL) {
- snd_iprintf(buffer, " sample clock source: word clock\n");
- } else if (rme96->wcreg & RME96_WCR_MASTER) {
- snd_iprintf(buffer, " sample clock source: internal\n");
- } else if (snd_rme96_getinputtype(rme96) == RME96_INPUT_ANALOG) {
- snd_iprintf(buffer, " sample clock source: autosync (internal anyway due to analog input setting)\n");
- } else if (snd_rme96_capture_getrate(rme96, &n) < 0) {
- snd_iprintf(buffer, " sample clock source: autosync (internal anyway due to no valid signal)\n");
- } else {
- snd_iprintf(buffer, " sample clock source: autosync\n");
- }
- if (rme96->wcreg & RME96_WCR_PRO) {
- snd_iprintf(buffer, " format: AES/EBU (professional)\n");
- } else {
- snd_iprintf(buffer, " format: IEC958 (consumer)\n");
- }
- if (rme96->wcreg & RME96_WCR_EMP) {
- snd_iprintf(buffer, " emphasis: on\n");
- } else {
- snd_iprintf(buffer, " emphasis: off\n");
- }
- if (rme96->wcreg & RME96_WCR_DOLBY) {
- snd_iprintf(buffer, " non-audio (dolby): on\n");
- } else {
- snd_iprintf(buffer, " non-audio (dolby): off\n");
- }
- if (RME96_HAS_ANALOG_IN(rme96)) {
- snd_iprintf(buffer, "\nAnalog output settings\n");
- switch (snd_rme96_getmontracks(rme96)) {
- case RME96_MONITOR_TRACKS_1_2:
- snd_iprintf(buffer, " monitored ADAT tracks: 1+2\n");
- break;
- case RME96_MONITOR_TRACKS_3_4:
- snd_iprintf(buffer, " monitored ADAT tracks: 3+4\n");
- break;
- case RME96_MONITOR_TRACKS_5_6:
- snd_iprintf(buffer, " monitored ADAT tracks: 5+6\n");
- break;
- case RME96_MONITOR_TRACKS_7_8:
- snd_iprintf(buffer, " monitored ADAT tracks: 7+8\n");
- break;
- }
- switch (snd_rme96_getattenuation(rme96)) {
- case RME96_ATTENUATION_0:
- snd_iprintf(buffer, " attenuation: 0 dB\n");
- break;
- case RME96_ATTENUATION_6:
- snd_iprintf(buffer, " attenuation: -6 dB\n");
- break;
- case RME96_ATTENUATION_12:
- snd_iprintf(buffer, " attenuation: -12 dB\n");
- break;
- case RME96_ATTENUATION_18:
- snd_iprintf(buffer, " attenuation: -18 dB\n");
- break;
- }
- snd_iprintf(buffer, " volume left: %u\n", rme96->vol[0]);
- snd_iprintf(buffer, " volume right: %u\n", rme96->vol[1]);
- }
-}
-
-static void __devinit
-snd_rme96_proc_init(struct rme96 *rme96)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(rme96->card, "rme96", &entry))
- snd_info_set_text_ops(entry, rme96, snd_rme96_proc_read);
-}
-
-/*
- * control interface
- */
-
-#define snd_rme96_info_loopback_control snd_ctl_boolean_mono_info
-
-static int
-snd_rme96_get_loopback_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&rme96->lock);
- ucontrol->value.integer.value[0] = rme96->wcreg & RME96_WCR_SEL ? 0 : 1;
- spin_unlock_irq(&rme96->lock);
- return 0;
-}
-static int
-snd_rme96_put_loopback_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change;
-
- val = ucontrol->value.integer.value[0] ? 0 : RME96_WCR_SEL;
- spin_lock_irq(&rme96->lock);
- val = (rme96->wcreg & ~RME96_WCR_SEL) | val;
- change = val != rme96->wcreg;
- rme96->wcreg = val;
- writel(val, rme96->iobase + RME96_IO_CONTROL_REGISTER);
- spin_unlock_irq(&rme96->lock);
- return change;
-}
-
-static int
-snd_rme96_info_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *_texts[5] = { "Optical", "Coaxial", "Internal", "XLR", "Analog" };
- struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
- char *texts[5] = { _texts[0], _texts[1], _texts[2], _texts[3], _texts[4] };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- switch (rme96->pci->device) {
- case PCI_DEVICE_ID_RME_DIGI96:
- case PCI_DEVICE_ID_RME_DIGI96_8:
- uinfo->value.enumerated.items = 3;
- break;
- case PCI_DEVICE_ID_RME_DIGI96_8_PRO:
- uinfo->value.enumerated.items = 4;
- break;
- case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST:
- if (rme96->rev > 4) {
- /* PST */
- uinfo->value.enumerated.items = 4;
- texts[3] = _texts[4]; /* Analog instead of XLR */
- } else {
- /* PAD */
- uinfo->value.enumerated.items = 5;
- }
- break;
- default:
- snd_BUG();
- break;
- }
- if (uinfo->value.enumerated.item > uinfo->value.enumerated.items - 1) {
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- }
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-static int
-snd_rme96_get_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
- unsigned int items = 3;
-
- spin_lock_irq(&rme96->lock);
- ucontrol->value.enumerated.item[0] = snd_rme96_getinputtype(rme96);
-
- switch (rme96->pci->device) {
- case PCI_DEVICE_ID_RME_DIGI96:
- case PCI_DEVICE_ID_RME_DIGI96_8:
- items = 3;
- break;
- case PCI_DEVICE_ID_RME_DIGI96_8_PRO:
- items = 4;
- break;
- case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST:
- if (rme96->rev > 4) {
- /* for handling PST case, (INPUT_ANALOG is moved to INPUT_XLR */
- if (ucontrol->value.enumerated.item[0] == RME96_INPUT_ANALOG) {
- ucontrol->value.enumerated.item[0] = RME96_INPUT_XLR;
- }
- items = 4;
- } else {
- items = 5;
- }
- break;
- default:
- snd_BUG();
- break;
- }
- if (ucontrol->value.enumerated.item[0] >= items) {
- ucontrol->value.enumerated.item[0] = items - 1;
- }
-
- spin_unlock_irq(&rme96->lock);
- return 0;
-}
-static int
-snd_rme96_put_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change, items = 3;
-
- switch (rme96->pci->device) {
- case PCI_DEVICE_ID_RME_DIGI96:
- case PCI_DEVICE_ID_RME_DIGI96_8:
- items = 3;
- break;
- case PCI_DEVICE_ID_RME_DIGI96_8_PRO:
- items = 4;
- break;
- case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST:
- if (rme96->rev > 4) {
- items = 4;
- } else {
- items = 5;
- }
- break;
- default:
- snd_BUG();
- break;
- }
- val = ucontrol->value.enumerated.item[0] % items;
-
- /* special case for PST */
- if (rme96->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST && rme96->rev > 4) {
- if (val == RME96_INPUT_XLR) {
- val = RME96_INPUT_ANALOG;
- }
- }
-
- spin_lock_irq(&rme96->lock);
- change = (int)val != snd_rme96_getinputtype(rme96);
- snd_rme96_setinputtype(rme96, val);
- spin_unlock_irq(&rme96->lock);
- return change;
-}
-
-static int
-snd_rme96_info_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[3] = { "AutoSync", "Internal", "Word" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item > 2) {
- uinfo->value.enumerated.item = 2;
- }
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-static int
-snd_rme96_get_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&rme96->lock);
- ucontrol->value.enumerated.item[0] = snd_rme96_getclockmode(rme96);
- spin_unlock_irq(&rme96->lock);
- return 0;
-}
-static int
-snd_rme96_put_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change;
-
- val = ucontrol->value.enumerated.item[0] % 3;
- spin_lock_irq(&rme96->lock);
- change = (int)val != snd_rme96_getclockmode(rme96);
- snd_rme96_setclockmode(rme96, val);
- spin_unlock_irq(&rme96->lock);
- return change;
-}
-
-static int
-snd_rme96_info_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[4] = { "0 dB", "-6 dB", "-12 dB", "-18 dB" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 4;
- if (uinfo->value.enumerated.item > 3) {
- uinfo->value.enumerated.item = 3;
- }
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-static int
-snd_rme96_get_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&rme96->lock);
- ucontrol->value.enumerated.item[0] = snd_rme96_getattenuation(rme96);
- spin_unlock_irq(&rme96->lock);
- return 0;
-}
-static int
-snd_rme96_put_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change;
-
- val = ucontrol->value.enumerated.item[0] % 4;
- spin_lock_irq(&rme96->lock);
-
- change = (int)val != snd_rme96_getattenuation(rme96);
- snd_rme96_setattenuation(rme96, val);
- spin_unlock_irq(&rme96->lock);
- return change;
-}
-
-static int
-snd_rme96_info_montracks_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[4] = { "1+2", "3+4", "5+6", "7+8" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 4;
- if (uinfo->value.enumerated.item > 3) {
- uinfo->value.enumerated.item = 3;
- }
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-static int
-snd_rme96_get_montracks_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&rme96->lock);
- ucontrol->value.enumerated.item[0] = snd_rme96_getmontracks(rme96);
- spin_unlock_irq(&rme96->lock);
- return 0;
-}
-static int
-snd_rme96_put_montracks_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change;
-
- val = ucontrol->value.enumerated.item[0] % 4;
- spin_lock_irq(&rme96->lock);
- change = (int)val != snd_rme96_getmontracks(rme96);
- snd_rme96_setmontracks(rme96, val);
- spin_unlock_irq(&rme96->lock);
- return change;
-}
-
-static u32 snd_rme96_convert_from_aes(struct snd_aes_iec958 *aes)
-{
- u32 val = 0;
- val |= (aes->status[0] & IEC958_AES0_PROFESSIONAL) ? RME96_WCR_PRO : 0;
- val |= (aes->status[0] & IEC958_AES0_NONAUDIO) ? RME96_WCR_DOLBY : 0;
- if (val & RME96_WCR_PRO)
- val |= (aes->status[0] & IEC958_AES0_PRO_EMPHASIS_5015) ? RME96_WCR_EMP : 0;
- else
- val |= (aes->status[0] & IEC958_AES0_CON_EMPHASIS_5015) ? RME96_WCR_EMP : 0;
- return val;
-}
-
-static void snd_rme96_convert_to_aes(struct snd_aes_iec958 *aes, u32 val)
-{
- aes->status[0] = ((val & RME96_WCR_PRO) ? IEC958_AES0_PROFESSIONAL : 0) |
- ((val & RME96_WCR_DOLBY) ? IEC958_AES0_NONAUDIO : 0);
- if (val & RME96_WCR_PRO)
- aes->status[0] |= (val & RME96_WCR_EMP) ? IEC958_AES0_PRO_EMPHASIS_5015 : 0;
- else
- aes->status[0] |= (val & RME96_WCR_EMP) ? IEC958_AES0_CON_EMPHASIS_5015 : 0;
-}
-
-static int snd_rme96_control_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_rme96_control_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
-
- snd_rme96_convert_to_aes(&ucontrol->value.iec958, rme96->wcreg_spdif);
- return 0;
-}
-
-static int snd_rme96_control_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
- int change;
- u32 val;
-
- val = snd_rme96_convert_from_aes(&ucontrol->value.iec958);
- spin_lock_irq(&rme96->lock);
- change = val != rme96->wcreg_spdif;
- rme96->wcreg_spdif = val;
- spin_unlock_irq(&rme96->lock);
- return change;
-}
-
-static int snd_rme96_control_spdif_stream_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_rme96_control_spdif_stream_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
-
- snd_rme96_convert_to_aes(&ucontrol->value.iec958, rme96->wcreg_spdif_stream);
- return 0;
-}
-
-static int snd_rme96_control_spdif_stream_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
- int change;
- u32 val;
-
- val = snd_rme96_convert_from_aes(&ucontrol->value.iec958);
- spin_lock_irq(&rme96->lock);
- change = val != rme96->wcreg_spdif_stream;
- rme96->wcreg_spdif_stream = val;
- rme96->wcreg &= ~(RME96_WCR_PRO | RME96_WCR_DOLBY | RME96_WCR_EMP);
- rme96->wcreg |= val;
- writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
- spin_unlock_irq(&rme96->lock);
- return change;
-}
-
-static int snd_rme96_control_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_rme96_control_spdif_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.iec958.status[0] = kcontrol->private_value;
- return 0;
-}
-
-static int
-snd_rme96_dac_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = RME96_185X_MAX_OUT(rme96);
- return 0;
-}
-
-static int
-snd_rme96_dac_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *u)
-{
- struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&rme96->lock);
- u->value.integer.value[0] = rme96->vol[0];
- u->value.integer.value[1] = rme96->vol[1];
- spin_unlock_irq(&rme96->lock);
-
- return 0;
-}
-
-static int
-snd_rme96_dac_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *u)
-{
- struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
- int change = 0;
- unsigned int vol, maxvol;
-
-
- if (!RME96_HAS_ANALOG_OUT(rme96))
- return -EINVAL;
- maxvol = RME96_185X_MAX_OUT(rme96);
- spin_lock_irq(&rme96->lock);
- vol = u->value.integer.value[0];
- if (vol != rme96->vol[0] && vol <= maxvol) {
- rme96->vol[0] = vol;
- change = 1;
- }
- vol = u->value.integer.value[1];
- if (vol != rme96->vol[1] && vol <= maxvol) {
- rme96->vol[1] = vol;
- change = 1;
- }
- if (change)
- snd_rme96_apply_dac_volume(rme96);
- spin_unlock_irq(&rme96->lock);
-
- return change;
-}
-
-static struct snd_kcontrol_new snd_rme96_controls[] = {
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
- .info = snd_rme96_control_spdif_info,
- .get = snd_rme96_control_spdif_get,
- .put = snd_rme96_control_spdif_put
-},
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
- .info = snd_rme96_control_spdif_stream_info,
- .get = snd_rme96_control_spdif_stream_get,
- .put = snd_rme96_control_spdif_stream_put
-},
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
- .info = snd_rme96_control_spdif_mask_info,
- .get = snd_rme96_control_spdif_mask_get,
- .private_value = IEC958_AES0_NONAUDIO |
- IEC958_AES0_PROFESSIONAL |
- IEC958_AES0_CON_EMPHASIS
-},
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
- .info = snd_rme96_control_spdif_mask_info,
- .get = snd_rme96_control_spdif_mask_get,
- .private_value = IEC958_AES0_NONAUDIO |
- IEC958_AES0_PROFESSIONAL |
- IEC958_AES0_PRO_EMPHASIS
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input Connector",
- .info = snd_rme96_info_inputtype_control,
- .get = snd_rme96_get_inputtype_control,
- .put = snd_rme96_put_inputtype_control
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Loopback Input",
- .info = snd_rme96_info_loopback_control,
- .get = snd_rme96_get_loopback_control,
- .put = snd_rme96_put_loopback_control
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Sample Clock Source",
- .info = snd_rme96_info_clockmode_control,
- .get = snd_rme96_get_clockmode_control,
- .put = snd_rme96_put_clockmode_control
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Monitor Tracks",
- .info = snd_rme96_info_montracks_control,
- .get = snd_rme96_get_montracks_control,
- .put = snd_rme96_put_montracks_control
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Attenuation",
- .info = snd_rme96_info_attenuation_control,
- .get = snd_rme96_get_attenuation_control,
- .put = snd_rme96_put_attenuation_control
-},
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "DAC Playback Volume",
- .info = snd_rme96_dac_volume_info,
- .get = snd_rme96_dac_volume_get,
- .put = snd_rme96_dac_volume_put
-}
-};
-
-static int
-snd_rme96_create_switches(struct snd_card *card,
- struct rme96 *rme96)
-{
- int idx, err;
- struct snd_kcontrol *kctl;
-
- for (idx = 0; idx < 7; idx++) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme96_controls[idx], rme96))) < 0)
- return err;
- if (idx == 1) /* IEC958 (S/PDIF) Stream */
- rme96->spdif_ctl = kctl;
- }
-
- if (RME96_HAS_ANALOG_OUT(rme96)) {
- for (idx = 7; idx < 10; idx++)
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_rme96_controls[idx], rme96))) < 0)
- return err;
- }
-
- return 0;
-}
-
-/*
- * Card initialisation
- */
-
-static void snd_rme96_card_free(struct snd_card *card)
-{
- snd_rme96_free(card->private_data);
-}
-
-static int __devinit
-snd_rme96_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct rme96 *rme96;
- struct snd_card *card;
- int err;
- u8 val;
-
- if (dev >= SNDRV_CARDS) {
- return -ENODEV;
- }
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct rme96), &card);
- if (err < 0)
- return err;
- card->private_free = snd_rme96_card_free;
- rme96 = card->private_data;
- rme96->card = card;
- rme96->pci = pci;
- snd_card_set_dev(card, &pci->dev);
- if ((err = snd_rme96_create(rme96)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- strcpy(card->driver, "Digi96");
- switch (rme96->pci->device) {
- case PCI_DEVICE_ID_RME_DIGI96:
- strcpy(card->shortname, "RME Digi96");
- break;
- case PCI_DEVICE_ID_RME_DIGI96_8:
- strcpy(card->shortname, "RME Digi96/8");
- break;
- case PCI_DEVICE_ID_RME_DIGI96_8_PRO:
- strcpy(card->shortname, "RME Digi96/8 PRO");
- break;
- case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST:
- pci_read_config_byte(rme96->pci, 8, &val);
- if (val < 5) {
- strcpy(card->shortname, "RME Digi96/8 PAD");
- } else {
- strcpy(card->shortname, "RME Digi96/8 PST");
- }
- break;
- }
- sprintf(card->longname, "%s at 0x%lx, irq %d", card->shortname,
- rme96->port, rme96->irq);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_rme96_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_rme96_ids,
- .probe = snd_rme96_probe,
- .remove = __devexit_p(snd_rme96_remove),
-};
-
-static int __init alsa_card_rme96_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_rme96_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_rme96_init)
-module_exit(alsa_card_rme96_exit)
diff --git a/ANDROID_3.4.5/sound/pci/rme9652/Makefile b/ANDROID_3.4.5/sound/pci/rme9652/Makefile
deleted file mode 100644
index dcba5604..00000000
--- a/ANDROID_3.4.5/sound/pci/rme9652/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-rme9652-objs := rme9652.o
-snd-hdsp-objs := hdsp.o
-snd-hdspm-objs := hdspm.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_RME9652) += snd-rme9652.o
-obj-$(CONFIG_SND_HDSP) += snd-hdsp.o
-obj-$(CONFIG_SND_HDSPM) +=snd-hdspm.o
diff --git a/ANDROID_3.4.5/sound/pci/rme9652/hdsp.c b/ANDROID_3.4.5/sound/pci/rme9652/hdsp.c
deleted file mode 100644
index 0b2aea2c..00000000
--- a/ANDROID_3.4.5/sound/pci/rme9652/hdsp.c
+++ /dev/null
@@ -1,5657 +0,0 @@
-/*
- * ALSA driver for RME Hammerfall DSP audio interface(s)
- *
- * Copyright (c) 2002 Paul Davis
- * Marcus Andersson
- * Thomas Charbonnel
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/firmware.h>
-#include <linux/module.h>
-#include <linux/math64.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/info.h>
-#include <sound/asoundef.h>
-#include <sound/rawmidi.h>
-#include <sound/hwdep.h>
-#include <sound/initval.h>
-#include <sound/hdsp.h>
-
-#include <asm/byteorder.h>
-#include <asm/current.h>
-#include <asm/io.h>
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for RME Hammerfall DSP interface.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for RME Hammerfall DSP interface.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable/disable specific Hammerfall DSP soundcards.");
-MODULE_AUTHOR("Paul Davis <paul@linuxaudiosystems.com>, Marcus Andersson, Thomas Charbonnel <thomas@undata.org>");
-MODULE_DESCRIPTION("RME Hammerfall DSP");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
- "{RME HDSP-9652},"
- "{RME HDSP-9632}}");
-#ifdef HDSP_FW_LOADER
-MODULE_FIRMWARE("rpm_firmware.bin");
-MODULE_FIRMWARE("multiface_firmware.bin");
-MODULE_FIRMWARE("multiface_firmware_rev11.bin");
-MODULE_FIRMWARE("digiface_firmware.bin");
-MODULE_FIRMWARE("digiface_firmware_rev11.bin");
-#endif
-
-#define HDSP_MAX_CHANNELS 26
-#define HDSP_MAX_DS_CHANNELS 14
-#define HDSP_MAX_QS_CHANNELS 8
-#define DIGIFACE_SS_CHANNELS 26
-#define DIGIFACE_DS_CHANNELS 14
-#define MULTIFACE_SS_CHANNELS 18
-#define MULTIFACE_DS_CHANNELS 14
-#define H9652_SS_CHANNELS 26
-#define H9652_DS_CHANNELS 14
-/* This does not include possible Analog Extension Boards
- AEBs are detected at card initialization
-*/
-#define H9632_SS_CHANNELS 12
-#define H9632_DS_CHANNELS 8
-#define H9632_QS_CHANNELS 4
-#define RPM_CHANNELS 6
-
-/* Write registers. These are defined as byte-offsets from the iobase value.
- */
-#define HDSP_resetPointer 0
-#define HDSP_freqReg 0
-#define HDSP_outputBufferAddress 32
-#define HDSP_inputBufferAddress 36
-#define HDSP_controlRegister 64
-#define HDSP_interruptConfirmation 96
-#define HDSP_outputEnable 128
-#define HDSP_control2Reg 256
-#define HDSP_midiDataOut0 352
-#define HDSP_midiDataOut1 356
-#define HDSP_fifoData 368
-#define HDSP_inputEnable 384
-
-/* Read registers. These are defined as byte-offsets from the iobase value
- */
-
-#define HDSP_statusRegister 0
-#define HDSP_timecode 128
-#define HDSP_status2Register 192
-#define HDSP_midiDataIn0 360
-#define HDSP_midiDataIn1 364
-#define HDSP_midiStatusOut0 384
-#define HDSP_midiStatusOut1 388
-#define HDSP_midiStatusIn0 392
-#define HDSP_midiStatusIn1 396
-#define HDSP_fifoStatus 400
-
-/* the meters are regular i/o-mapped registers, but offset
- considerably from the rest. the peak registers are reset
- when read; the least-significant 4 bits are full-scale counters;
- the actual peak value is in the most-significant 24 bits.
-*/
-
-#define HDSP_playbackPeakLevel 4096 /* 26 * 32 bit values */
-#define HDSP_inputPeakLevel 4224 /* 26 * 32 bit values */
-#define HDSP_outputPeakLevel 4352 /* (26+2) * 32 bit values */
-#define HDSP_playbackRmsLevel 4612 /* 26 * 64 bit values */
-#define HDSP_inputRmsLevel 4868 /* 26 * 64 bit values */
-
-
-/* This is for H9652 cards
- Peak values are read downward from the base
- Rms values are read upward
- There are rms values for the outputs too
- 26*3 values are read in ss mode
- 14*3 in ds mode, with no gap between values
-*/
-#define HDSP_9652_peakBase 7164
-#define HDSP_9652_rmsBase 4096
-
-/* c.f. the hdsp_9632_meters_t struct */
-#define HDSP_9632_metersBase 4096
-
-#define HDSP_IO_EXTENT 7168
-
-/* control2 register bits */
-
-#define HDSP_TMS 0x01
-#define HDSP_TCK 0x02
-#define HDSP_TDI 0x04
-#define HDSP_JTAG 0x08
-#define HDSP_PWDN 0x10
-#define HDSP_PROGRAM 0x020
-#define HDSP_CONFIG_MODE_0 0x040
-#define HDSP_CONFIG_MODE_1 0x080
-#define HDSP_VERSION_BIT (0x100 | HDSP_S_LOAD)
-#define HDSP_BIGENDIAN_MODE 0x200
-#define HDSP_RD_MULTIPLE 0x400
-#define HDSP_9652_ENABLE_MIXER 0x800
-#define HDSP_TDO 0x10000000
-
-#define HDSP_S_PROGRAM (HDSP_PROGRAM|HDSP_CONFIG_MODE_0)
-#define HDSP_S_LOAD (HDSP_PROGRAM|HDSP_CONFIG_MODE_1)
-
-/* Control Register bits */
-
-#define HDSP_Start (1<<0) /* start engine */
-#define HDSP_Latency0 (1<<1) /* buffer size = 2^n where n is defined by Latency{2,1,0} */
-#define HDSP_Latency1 (1<<2) /* [ see above ] */
-#define HDSP_Latency2 (1<<3) /* [ see above ] */
-#define HDSP_ClockModeMaster (1<<4) /* 1=Master, 0=Slave/Autosync */
-#define HDSP_AudioInterruptEnable (1<<5) /* what do you think ? */
-#define HDSP_Frequency0 (1<<6) /* 0=44.1kHz/88.2kHz/176.4kHz 1=48kHz/96kHz/192kHz */
-#define HDSP_Frequency1 (1<<7) /* 0=32kHz/64kHz/128kHz */
-#define HDSP_DoubleSpeed (1<<8) /* 0=normal speed, 1=double speed */
-#define HDSP_SPDIFProfessional (1<<9) /* 0=consumer, 1=professional */
-#define HDSP_SPDIFEmphasis (1<<10) /* 0=none, 1=on */
-#define HDSP_SPDIFNonAudio (1<<11) /* 0=off, 1=on */
-#define HDSP_SPDIFOpticalOut (1<<12) /* 1=use 1st ADAT connector for SPDIF, 0=do not */
-#define HDSP_SyncRef2 (1<<13)
-#define HDSP_SPDIFInputSelect0 (1<<14)
-#define HDSP_SPDIFInputSelect1 (1<<15)
-#define HDSP_SyncRef0 (1<<16)
-#define HDSP_SyncRef1 (1<<17)
-#define HDSP_AnalogExtensionBoard (1<<18) /* For H9632 cards */
-#define HDSP_XLRBreakoutCable (1<<20) /* For H9632 cards */
-#define HDSP_Midi0InterruptEnable (1<<22)
-#define HDSP_Midi1InterruptEnable (1<<23)
-#define HDSP_LineOut (1<<24)
-#define HDSP_ADGain0 (1<<25) /* From here : H9632 specific */
-#define HDSP_ADGain1 (1<<26)
-#define HDSP_DAGain0 (1<<27)
-#define HDSP_DAGain1 (1<<28)
-#define HDSP_PhoneGain0 (1<<29)
-#define HDSP_PhoneGain1 (1<<30)
-#define HDSP_QuadSpeed (1<<31)
-
-/* RPM uses some of the registers for special purposes */
-#define HDSP_RPM_Inp12 0x04A00
-#define HDSP_RPM_Inp12_Phon_6dB 0x00800 /* Dolby */
-#define HDSP_RPM_Inp12_Phon_0dB 0x00000 /* .. */
-#define HDSP_RPM_Inp12_Phon_n6dB 0x04000 /* inp_0 */
-#define HDSP_RPM_Inp12_Line_0dB 0x04200 /* Dolby+PRO */
-#define HDSP_RPM_Inp12_Line_n6dB 0x00200 /* PRO */
-
-#define HDSP_RPM_Inp34 0x32000
-#define HDSP_RPM_Inp34_Phon_6dB 0x20000 /* SyncRef1 */
-#define HDSP_RPM_Inp34_Phon_0dB 0x00000 /* .. */
-#define HDSP_RPM_Inp34_Phon_n6dB 0x02000 /* SyncRef2 */
-#define HDSP_RPM_Inp34_Line_0dB 0x30000 /* SyncRef1+SyncRef0 */
-#define HDSP_RPM_Inp34_Line_n6dB 0x10000 /* SyncRef0 */
-
-#define HDSP_RPM_Bypass 0x01000
-
-#define HDSP_RPM_Disconnect 0x00001
-
-#define HDSP_ADGainMask (HDSP_ADGain0|HDSP_ADGain1)
-#define HDSP_ADGainMinus10dBV HDSP_ADGainMask
-#define HDSP_ADGainPlus4dBu (HDSP_ADGain0)
-#define HDSP_ADGainLowGain 0
-
-#define HDSP_DAGainMask (HDSP_DAGain0|HDSP_DAGain1)
-#define HDSP_DAGainHighGain HDSP_DAGainMask
-#define HDSP_DAGainPlus4dBu (HDSP_DAGain0)
-#define HDSP_DAGainMinus10dBV 0
-
-#define HDSP_PhoneGainMask (HDSP_PhoneGain0|HDSP_PhoneGain1)
-#define HDSP_PhoneGain0dB HDSP_PhoneGainMask
-#define HDSP_PhoneGainMinus6dB (HDSP_PhoneGain0)
-#define HDSP_PhoneGainMinus12dB 0
-
-#define HDSP_LatencyMask (HDSP_Latency0|HDSP_Latency1|HDSP_Latency2)
-#define HDSP_FrequencyMask (HDSP_Frequency0|HDSP_Frequency1|HDSP_DoubleSpeed|HDSP_QuadSpeed)
-
-#define HDSP_SPDIFInputMask (HDSP_SPDIFInputSelect0|HDSP_SPDIFInputSelect1)
-#define HDSP_SPDIFInputADAT1 0
-#define HDSP_SPDIFInputCoaxial (HDSP_SPDIFInputSelect0)
-#define HDSP_SPDIFInputCdrom (HDSP_SPDIFInputSelect1)
-#define HDSP_SPDIFInputAES (HDSP_SPDIFInputSelect0|HDSP_SPDIFInputSelect1)
-
-#define HDSP_SyncRefMask (HDSP_SyncRef0|HDSP_SyncRef1|HDSP_SyncRef2)
-#define HDSP_SyncRef_ADAT1 0
-#define HDSP_SyncRef_ADAT2 (HDSP_SyncRef0)
-#define HDSP_SyncRef_ADAT3 (HDSP_SyncRef1)
-#define HDSP_SyncRef_SPDIF (HDSP_SyncRef0|HDSP_SyncRef1)
-#define HDSP_SyncRef_WORD (HDSP_SyncRef2)
-#define HDSP_SyncRef_ADAT_SYNC (HDSP_SyncRef0|HDSP_SyncRef2)
-
-/* Sample Clock Sources */
-
-#define HDSP_CLOCK_SOURCE_AUTOSYNC 0
-#define HDSP_CLOCK_SOURCE_INTERNAL_32KHZ 1
-#define HDSP_CLOCK_SOURCE_INTERNAL_44_1KHZ 2
-#define HDSP_CLOCK_SOURCE_INTERNAL_48KHZ 3
-#define HDSP_CLOCK_SOURCE_INTERNAL_64KHZ 4
-#define HDSP_CLOCK_SOURCE_INTERNAL_88_2KHZ 5
-#define HDSP_CLOCK_SOURCE_INTERNAL_96KHZ 6
-#define HDSP_CLOCK_SOURCE_INTERNAL_128KHZ 7
-#define HDSP_CLOCK_SOURCE_INTERNAL_176_4KHZ 8
-#define HDSP_CLOCK_SOURCE_INTERNAL_192KHZ 9
-
-/* Preferred sync reference choices - used by "pref_sync_ref" control switch */
-
-#define HDSP_SYNC_FROM_WORD 0
-#define HDSP_SYNC_FROM_SPDIF 1
-#define HDSP_SYNC_FROM_ADAT1 2
-#define HDSP_SYNC_FROM_ADAT_SYNC 3
-#define HDSP_SYNC_FROM_ADAT2 4
-#define HDSP_SYNC_FROM_ADAT3 5
-
-/* SyncCheck status */
-
-#define HDSP_SYNC_CHECK_NO_LOCK 0
-#define HDSP_SYNC_CHECK_LOCK 1
-#define HDSP_SYNC_CHECK_SYNC 2
-
-/* AutoSync references - used by "autosync_ref" control switch */
-
-#define HDSP_AUTOSYNC_FROM_WORD 0
-#define HDSP_AUTOSYNC_FROM_ADAT_SYNC 1
-#define HDSP_AUTOSYNC_FROM_SPDIF 2
-#define HDSP_AUTOSYNC_FROM_NONE 3
-#define HDSP_AUTOSYNC_FROM_ADAT1 4
-#define HDSP_AUTOSYNC_FROM_ADAT2 5
-#define HDSP_AUTOSYNC_FROM_ADAT3 6
-
-/* Possible sources of S/PDIF input */
-
-#define HDSP_SPDIFIN_OPTICAL 0 /* optical (ADAT1) */
-#define HDSP_SPDIFIN_COAXIAL 1 /* coaxial (RCA) */
-#define HDSP_SPDIFIN_INTERNAL 2 /* internal (CDROM) */
-#define HDSP_SPDIFIN_AES 3 /* xlr for H9632 (AES)*/
-
-#define HDSP_Frequency32KHz HDSP_Frequency0
-#define HDSP_Frequency44_1KHz HDSP_Frequency1
-#define HDSP_Frequency48KHz (HDSP_Frequency1|HDSP_Frequency0)
-#define HDSP_Frequency64KHz (HDSP_DoubleSpeed|HDSP_Frequency0)
-#define HDSP_Frequency88_2KHz (HDSP_DoubleSpeed|HDSP_Frequency1)
-#define HDSP_Frequency96KHz (HDSP_DoubleSpeed|HDSP_Frequency1|HDSP_Frequency0)
-/* For H9632 cards */
-#define HDSP_Frequency128KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency0)
-#define HDSP_Frequency176_4KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1)
-#define HDSP_Frequency192KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1|HDSP_Frequency0)
-/* RME says n = 104857600000000, but in the windows MADI driver, I see:
- return 104857600000000 / rate; // 100 MHz
- return 110100480000000 / rate; // 105 MHz
-*/
-#define DDS_NUMERATOR 104857600000000ULL; /* = 2^20 * 10^8 */
-
-#define hdsp_encode_latency(x) (((x)<<1) & HDSP_LatencyMask)
-#define hdsp_decode_latency(x) (((x) & HDSP_LatencyMask)>>1)
-
-#define hdsp_encode_spdif_in(x) (((x)&0x3)<<14)
-#define hdsp_decode_spdif_in(x) (((x)>>14)&0x3)
-
-/* Status Register bits */
-
-#define HDSP_audioIRQPending (1<<0)
-#define HDSP_Lock2 (1<<1) /* this is for Digiface and H9652 */
-#define HDSP_spdifFrequency3 HDSP_Lock2 /* this is for H9632 only */
-#define HDSP_Lock1 (1<<2)
-#define HDSP_Lock0 (1<<3)
-#define HDSP_SPDIFSync (1<<4)
-#define HDSP_TimecodeLock (1<<5)
-#define HDSP_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */
-#define HDSP_Sync2 (1<<16)
-#define HDSP_Sync1 (1<<17)
-#define HDSP_Sync0 (1<<18)
-#define HDSP_DoubleSpeedStatus (1<<19)
-#define HDSP_ConfigError (1<<20)
-#define HDSP_DllError (1<<21)
-#define HDSP_spdifFrequency0 (1<<22)
-#define HDSP_spdifFrequency1 (1<<23)
-#define HDSP_spdifFrequency2 (1<<24)
-#define HDSP_SPDIFErrorFlag (1<<25)
-#define HDSP_BufferID (1<<26)
-#define HDSP_TimecodeSync (1<<27)
-#define HDSP_AEBO (1<<28) /* H9632 specific Analog Extension Boards */
-#define HDSP_AEBI (1<<29) /* 0 = present, 1 = absent */
-#define HDSP_midi0IRQPending (1<<30)
-#define HDSP_midi1IRQPending (1<<31)
-
-#define HDSP_spdifFrequencyMask (HDSP_spdifFrequency0|HDSP_spdifFrequency1|HDSP_spdifFrequency2)
-#define HDSP_spdifFrequencyMask_9632 (HDSP_spdifFrequency0|\
- HDSP_spdifFrequency1|\
- HDSP_spdifFrequency2|\
- HDSP_spdifFrequency3)
-
-#define HDSP_spdifFrequency32KHz (HDSP_spdifFrequency0)
-#define HDSP_spdifFrequency44_1KHz (HDSP_spdifFrequency1)
-#define HDSP_spdifFrequency48KHz (HDSP_spdifFrequency0|HDSP_spdifFrequency1)
-
-#define HDSP_spdifFrequency64KHz (HDSP_spdifFrequency2)
-#define HDSP_spdifFrequency88_2KHz (HDSP_spdifFrequency0|HDSP_spdifFrequency2)
-#define HDSP_spdifFrequency96KHz (HDSP_spdifFrequency2|HDSP_spdifFrequency1)
-
-/* This is for H9632 cards */
-#define HDSP_spdifFrequency128KHz (HDSP_spdifFrequency0|\
- HDSP_spdifFrequency1|\
- HDSP_spdifFrequency2)
-#define HDSP_spdifFrequency176_4KHz HDSP_spdifFrequency3
-#define HDSP_spdifFrequency192KHz (HDSP_spdifFrequency3|HDSP_spdifFrequency0)
-
-/* Status2 Register bits */
-
-#define HDSP_version0 (1<<0)
-#define HDSP_version1 (1<<1)
-#define HDSP_version2 (1<<2)
-#define HDSP_wc_lock (1<<3)
-#define HDSP_wc_sync (1<<4)
-#define HDSP_inp_freq0 (1<<5)
-#define HDSP_inp_freq1 (1<<6)
-#define HDSP_inp_freq2 (1<<7)
-#define HDSP_SelSyncRef0 (1<<8)
-#define HDSP_SelSyncRef1 (1<<9)
-#define HDSP_SelSyncRef2 (1<<10)
-
-#define HDSP_wc_valid (HDSP_wc_lock|HDSP_wc_sync)
-
-#define HDSP_systemFrequencyMask (HDSP_inp_freq0|HDSP_inp_freq1|HDSP_inp_freq2)
-#define HDSP_systemFrequency32 (HDSP_inp_freq0)
-#define HDSP_systemFrequency44_1 (HDSP_inp_freq1)
-#define HDSP_systemFrequency48 (HDSP_inp_freq0|HDSP_inp_freq1)
-#define HDSP_systemFrequency64 (HDSP_inp_freq2)
-#define HDSP_systemFrequency88_2 (HDSP_inp_freq0|HDSP_inp_freq2)
-#define HDSP_systemFrequency96 (HDSP_inp_freq1|HDSP_inp_freq2)
-/* FIXME : more values for 9632 cards ? */
-
-#define HDSP_SelSyncRefMask (HDSP_SelSyncRef0|HDSP_SelSyncRef1|HDSP_SelSyncRef2)
-#define HDSP_SelSyncRef_ADAT1 0
-#define HDSP_SelSyncRef_ADAT2 (HDSP_SelSyncRef0)
-#define HDSP_SelSyncRef_ADAT3 (HDSP_SelSyncRef1)
-#define HDSP_SelSyncRef_SPDIF (HDSP_SelSyncRef0|HDSP_SelSyncRef1)
-#define HDSP_SelSyncRef_WORD (HDSP_SelSyncRef2)
-#define HDSP_SelSyncRef_ADAT_SYNC (HDSP_SelSyncRef0|HDSP_SelSyncRef2)
-
-/* Card state flags */
-
-#define HDSP_InitializationComplete (1<<0)
-#define HDSP_FirmwareLoaded (1<<1)
-#define HDSP_FirmwareCached (1<<2)
-
-/* FIFO wait times, defined in terms of 1/10ths of msecs */
-
-#define HDSP_LONG_WAIT 5000
-#define HDSP_SHORT_WAIT 30
-
-#define UNITY_GAIN 32768
-#define MINUS_INFINITY_GAIN 0
-
-/* the size of a substream (1 mono data stream) */
-
-#define HDSP_CHANNEL_BUFFER_SAMPLES (16*1024)
-#define HDSP_CHANNEL_BUFFER_BYTES (4*HDSP_CHANNEL_BUFFER_SAMPLES)
-
-/* the size of the area we need to allocate for DMA transfers. the
- size is the same regardless of the number of channels - the
- Multiface still uses the same memory area.
-
- Note that we allocate 1 more channel than is apparently needed
- because the h/w seems to write 1 byte beyond the end of the last
- page. Sigh.
-*/
-
-#define HDSP_DMA_AREA_BYTES ((HDSP_MAX_CHANNELS+1) * HDSP_CHANNEL_BUFFER_BYTES)
-#define HDSP_DMA_AREA_KILOBYTES (HDSP_DMA_AREA_BYTES/1024)
-
-/* use hotplug firmware loader? */
-#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
-#if !defined(HDSP_USE_HWDEP_LOADER)
-#define HDSP_FW_LOADER
-#endif
-#endif
-
-struct hdsp_9632_meters {
- u32 input_peak[16];
- u32 playback_peak[16];
- u32 output_peak[16];
- u32 xxx_peak[16];
- u32 padding[64];
- u32 input_rms_low[16];
- u32 playback_rms_low[16];
- u32 output_rms_low[16];
- u32 xxx_rms_low[16];
- u32 input_rms_high[16];
- u32 playback_rms_high[16];
- u32 output_rms_high[16];
- u32 xxx_rms_high[16];
-};
-
-struct hdsp_midi {
- struct hdsp *hdsp;
- int id;
- struct snd_rawmidi *rmidi;
- struct snd_rawmidi_substream *input;
- struct snd_rawmidi_substream *output;
- char istimer; /* timer in use */
- struct timer_list timer;
- spinlock_t lock;
- int pending;
-};
-
-struct hdsp {
- spinlock_t lock;
- struct snd_pcm_substream *capture_substream;
- struct snd_pcm_substream *playback_substream;
- struct hdsp_midi midi[2];
- struct tasklet_struct midi_tasklet;
- int use_midi_tasklet;
- int precise_ptr;
- u32 control_register; /* cached value */
- u32 control2_register; /* cached value */
- u32 creg_spdif;
- u32 creg_spdif_stream;
- int clock_source_locked;
- char *card_name; /* digiface/multiface/rpm */
- enum HDSP_IO_Type io_type; /* ditto, but for code use */
- unsigned short firmware_rev;
- unsigned short state; /* stores state bits */
- u32 firmware_cache[24413]; /* this helps recover from accidental iobox power failure */
- size_t period_bytes; /* guess what this is */
- unsigned char max_channels;
- unsigned char qs_in_channels; /* quad speed mode for H9632 */
- unsigned char ds_in_channels;
- unsigned char ss_in_channels; /* different for multiface/digiface */
- unsigned char qs_out_channels;
- unsigned char ds_out_channels;
- unsigned char ss_out_channels;
-
- struct snd_dma_buffer capture_dma_buf;
- struct snd_dma_buffer playback_dma_buf;
- unsigned char *capture_buffer; /* suitably aligned address */
- unsigned char *playback_buffer; /* suitably aligned address */
-
- pid_t capture_pid;
- pid_t playback_pid;
- int running;
- int system_sample_rate;
- char *channel_map;
- int dev;
- int irq;
- unsigned long port;
- void __iomem *iobase;
- struct snd_card *card;
- struct snd_pcm *pcm;
- struct snd_hwdep *hwdep;
- struct pci_dev *pci;
- struct snd_kcontrol *spdif_ctl;
- unsigned short mixer_matrix[HDSP_MATRIX_MIXER_SIZE];
- unsigned int dds_value; /* last value written to freq register */
-};
-
-/* These tables map the ALSA channels 1..N to the channels that we
- need to use in order to find the relevant channel buffer. RME
- refer to this kind of mapping as between "the ADAT channel and
- the DMA channel." We index it using the logical audio channel,
- and the value is the DMA channel (i.e. channel buffer number)
- where the data for that channel can be read/written from/to.
-*/
-
-static char channel_map_df_ss[HDSP_MAX_CHANNELS] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 24, 25
-};
-
-static char channel_map_mf_ss[HDSP_MAX_CHANNELS] = { /* Multiface */
- /* Analog */
- 0, 1, 2, 3, 4, 5, 6, 7,
- /* ADAT 2 */
- 16, 17, 18, 19, 20, 21, 22, 23,
- /* SPDIF */
- 24, 25,
- -1, -1, -1, -1, -1, -1, -1, -1
-};
-
-static char channel_map_ds[HDSP_MAX_CHANNELS] = {
- /* ADAT channels are remapped */
- 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23,
- /* channels 12 and 13 are S/PDIF */
- 24, 25,
- /* others don't exist */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
-};
-
-static char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = {
- /* ADAT channels */
- 0, 1, 2, 3, 4, 5, 6, 7,
- /* SPDIF */
- 8, 9,
- /* Analog */
- 10, 11,
- /* AO4S-192 and AI4S-192 extension boards */
- 12, 13, 14, 15,
- /* others don't exist */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1
-};
-
-static char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = {
- /* ADAT */
- 1, 3, 5, 7,
- /* SPDIF */
- 8, 9,
- /* Analog */
- 10, 11,
- /* AO4S-192 and AI4S-192 extension boards */
- 12, 13, 14, 15,
- /* others don't exist */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1
-};
-
-static char channel_map_H9632_qs[HDSP_MAX_CHANNELS] = {
- /* ADAT is disabled in this mode */
- /* SPDIF */
- 8, 9,
- /* Analog */
- 10, 11,
- /* AO4S-192 and AI4S-192 extension boards */
- 12, 13, 14, 15,
- /* others don't exist */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1
-};
-
-static int snd_hammerfall_get_buffer(struct pci_dev *pci, struct snd_dma_buffer *dmab, size_t size)
-{
- dmab->dev.type = SNDRV_DMA_TYPE_DEV;
- dmab->dev.dev = snd_dma_pci_data(pci);
- if (snd_dma_get_reserved_buf(dmab, snd_dma_pci_buf_id(pci))) {
- if (dmab->bytes >= size)
- return 0;
- }
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
- size, dmab) < 0)
- return -ENOMEM;
- return 0;
-}
-
-static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_dev *pci)
-{
- if (dmab->area) {
- dmab->dev.dev = NULL; /* make it anonymous */
- snd_dma_reserve_buf(dmab, snd_dma_pci_buf_id(pci));
- }
-}
-
-
-static DEFINE_PCI_DEVICE_TABLE(snd_hdsp_ids) = {
- {
- .vendor = PCI_VENDOR_ID_XILINX,
- .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- }, /* RME Hammerfall-DSP */
- { 0, },
-};
-
-MODULE_DEVICE_TABLE(pci, snd_hdsp_ids);
-
-/* prototypes */
-static int snd_hdsp_create_alsa_devices(struct snd_card *card, struct hdsp *hdsp);
-static int snd_hdsp_create_pcm(struct snd_card *card, struct hdsp *hdsp);
-static int snd_hdsp_enable_io (struct hdsp *hdsp);
-static void snd_hdsp_initialize_midi_flush (struct hdsp *hdsp);
-static void snd_hdsp_initialize_channels (struct hdsp *hdsp);
-static int hdsp_fifo_wait(struct hdsp *hdsp, int count, int timeout);
-static int hdsp_autosync_ref(struct hdsp *hdsp);
-static int snd_hdsp_set_defaults(struct hdsp *hdsp);
-static void snd_hdsp_9652_enable_mixer (struct hdsp *hdsp);
-
-static int hdsp_playback_to_output_key (struct hdsp *hdsp, int in, int out)
-{
- switch (hdsp->io_type) {
- case Multiface:
- case Digiface:
- case RPM:
- default:
- if (hdsp->firmware_rev == 0xa)
- return (64 * out) + (32 + (in));
- else
- return (52 * out) + (26 + (in));
- case H9632:
- return (32 * out) + (16 + (in));
- case H9652:
- return (52 * out) + (26 + (in));
- }
-}
-
-static int hdsp_input_to_output_key (struct hdsp *hdsp, int in, int out)
-{
- switch (hdsp->io_type) {
- case Multiface:
- case Digiface:
- case RPM:
- default:
- if (hdsp->firmware_rev == 0xa)
- return (64 * out) + in;
- else
- return (52 * out) + in;
- case H9632:
- return (32 * out) + in;
- case H9652:
- return (52 * out) + in;
- }
-}
-
-static void hdsp_write(struct hdsp *hdsp, int reg, int val)
-{
- writel(val, hdsp->iobase + reg);
-}
-
-static unsigned int hdsp_read(struct hdsp *hdsp, int reg)
-{
- return readl (hdsp->iobase + reg);
-}
-
-static int hdsp_check_for_iobox (struct hdsp *hdsp)
-{
- if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
- if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) {
- snd_printk("Hammerfall-DSP: no IO box connected!\n");
- hdsp->state &= ~HDSP_FirmwareLoaded;
- return -EIO;
- }
- return 0;
-}
-
-static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops,
- unsigned int delay)
-{
- unsigned int i;
-
- if (hdsp->io_type == H9652 || hdsp->io_type == H9632)
- return 0;
-
- for (i = 0; i != loops; ++i) {
- if (hdsp_read(hdsp, HDSP_statusRegister) & HDSP_ConfigError)
- msleep(delay);
- else {
- snd_printd("Hammerfall-DSP: iobox found after %ums!\n",
- i * delay);
- return 0;
- }
- }
-
- snd_printk("Hammerfall-DSP: no IO box connected!\n");
- hdsp->state &= ~HDSP_FirmwareLoaded;
- return -EIO;
-}
-
-static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) {
-
- int i;
- unsigned long flags;
-
- if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
-
- snd_printk ("Hammerfall-DSP: loading firmware\n");
-
- hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_PROGRAM);
- hdsp_write (hdsp, HDSP_fifoData, 0);
-
- if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
- snd_printk ("Hammerfall-DSP: timeout waiting for download preparation\n");
- return -EIO;
- }
-
- hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
-
- for (i = 0; i < 24413; ++i) {
- hdsp_write(hdsp, HDSP_fifoData, hdsp->firmware_cache[i]);
- if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) {
- snd_printk ("Hammerfall-DSP: timeout during firmware loading\n");
- return -EIO;
- }
- }
-
- ssleep(3);
-
- if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
- snd_printk ("Hammerfall-DSP: timeout at end of firmware loading\n");
- return -EIO;
- }
-
-#ifdef SNDRV_BIG_ENDIAN
- hdsp->control2_register = HDSP_BIGENDIAN_MODE;
-#else
- hdsp->control2_register = 0;
-#endif
- hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
- snd_printk ("Hammerfall-DSP: finished firmware loading\n");
-
- }
- if (hdsp->state & HDSP_InitializationComplete) {
- snd_printk(KERN_INFO "Hammerfall-DSP: firmware loaded from cache, restoring defaults\n");
- spin_lock_irqsave(&hdsp->lock, flags);
- snd_hdsp_set_defaults(hdsp);
- spin_unlock_irqrestore(&hdsp->lock, flags);
- }
-
- hdsp->state |= HDSP_FirmwareLoaded;
-
- return 0;
-}
-
-static int hdsp_get_iobox_version (struct hdsp *hdsp)
-{
- if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
-
- hdsp_write (hdsp, HDSP_control2Reg, HDSP_PROGRAM);
- hdsp_write (hdsp, HDSP_fifoData, 0);
- if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0)
- return -EIO;
-
- hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
- hdsp_write (hdsp, HDSP_fifoData, 0);
-
- if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) {
- hdsp_write(hdsp, HDSP_control2Reg, HDSP_VERSION_BIT);
- hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
- if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT))
- hdsp->io_type = RPM;
- else
- hdsp->io_type = Multiface;
- } else {
- hdsp->io_type = Digiface;
- }
- } else {
- /* firmware was already loaded, get iobox type */
- if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2)
- hdsp->io_type = RPM;
- else if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
- hdsp->io_type = Multiface;
- else
- hdsp->io_type = Digiface;
- }
- return 0;
-}
-
-
-#ifdef HDSP_FW_LOADER
-static int hdsp_request_fw_loader(struct hdsp *hdsp);
-#endif
-
-static int hdsp_check_for_firmware (struct hdsp *hdsp, int load_on_demand)
-{
- if (hdsp->io_type == H9652 || hdsp->io_type == H9632)
- return 0;
- if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
- hdsp->state &= ~HDSP_FirmwareLoaded;
- if (! load_on_demand)
- return -EIO;
- snd_printk(KERN_ERR "Hammerfall-DSP: firmware not present.\n");
- /* try to load firmware */
- if (! (hdsp->state & HDSP_FirmwareCached)) {
-#ifdef HDSP_FW_LOADER
- if (! hdsp_request_fw_loader(hdsp))
- return 0;
-#endif
- snd_printk(KERN_ERR
- "Hammerfall-DSP: No firmware loaded nor "
- "cached, please upload firmware.\n");
- return -EIO;
- }
- if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
- snd_printk(KERN_ERR
- "Hammerfall-DSP: Firmware loading from "
- "cache failed, please upload manually.\n");
- return -EIO;
- }
- }
- return 0;
-}
-
-
-static int hdsp_fifo_wait(struct hdsp *hdsp, int count, int timeout)
-{
- int i;
-
- /* the fifoStatus registers reports on how many words
- are available in the command FIFO.
- */
-
- for (i = 0; i < timeout; i++) {
-
- if ((int)(hdsp_read (hdsp, HDSP_fifoStatus) & 0xff) <= count)
- return 0;
-
- /* not very friendly, but we only do this during a firmware
- load and changing the mixer, so we just put up with it.
- */
-
- udelay (100);
- }
-
- snd_printk ("Hammerfall-DSP: wait for FIFO status <= %d failed after %d iterations\n",
- count, timeout);
- return -1;
-}
-
-static int hdsp_read_gain (struct hdsp *hdsp, unsigned int addr)
-{
- if (addr >= HDSP_MATRIX_MIXER_SIZE)
- return 0;
-
- return hdsp->mixer_matrix[addr];
-}
-
-static int hdsp_write_gain(struct hdsp *hdsp, unsigned int addr, unsigned short data)
-{
- unsigned int ad;
-
- if (addr >= HDSP_MATRIX_MIXER_SIZE)
- return -1;
-
- if (hdsp->io_type == H9652 || hdsp->io_type == H9632) {
-
- /* from martin bjornsen:
-
- "You can only write dwords to the
- mixer memory which contain two
- mixer values in the low and high
- word. So if you want to change
- value 0 you have to read value 1
- from the cache and write both to
- the first dword in the mixer
- memory."
- */
-
- if (hdsp->io_type == H9632 && addr >= 512)
- return 0;
-
- if (hdsp->io_type == H9652 && addr >= 1352)
- return 0;
-
- hdsp->mixer_matrix[addr] = data;
-
-
- /* `addr' addresses a 16-bit wide address, but
- the address space accessed via hdsp_write
- uses byte offsets. put another way, addr
- varies from 0 to 1351, but to access the
- corresponding memory location, we need
- to access 0 to 2703 ...
- */
- ad = addr/2;
-
- hdsp_write (hdsp, 4096 + (ad*4),
- (hdsp->mixer_matrix[(addr&0x7fe)+1] << 16) +
- hdsp->mixer_matrix[addr&0x7fe]);
-
- return 0;
-
- } else {
-
- ad = (addr << 16) + data;
-
- if (hdsp_fifo_wait(hdsp, 127, HDSP_LONG_WAIT))
- return -1;
-
- hdsp_write (hdsp, HDSP_fifoData, ad);
- hdsp->mixer_matrix[addr] = data;
-
- }
-
- return 0;
-}
-
-static int snd_hdsp_use_is_exclusive(struct hdsp *hdsp)
-{
- unsigned long flags;
- int ret = 1;
-
- spin_lock_irqsave(&hdsp->lock, flags);
- if ((hdsp->playback_pid != hdsp->capture_pid) &&
- (hdsp->playback_pid >= 0) && (hdsp->capture_pid >= 0))
- ret = 0;
- spin_unlock_irqrestore(&hdsp->lock, flags);
- return ret;
-}
-
-static int hdsp_spdif_sample_rate(struct hdsp *hdsp)
-{
- unsigned int status = hdsp_read(hdsp, HDSP_statusRegister);
- unsigned int rate_bits = (status & HDSP_spdifFrequencyMask);
-
- /* For the 9632, the mask is different */
- if (hdsp->io_type == H9632)
- rate_bits = (status & HDSP_spdifFrequencyMask_9632);
-
- if (status & HDSP_SPDIFErrorFlag)
- return 0;
-
- switch (rate_bits) {
- case HDSP_spdifFrequency32KHz: return 32000;
- case HDSP_spdifFrequency44_1KHz: return 44100;
- case HDSP_spdifFrequency48KHz: return 48000;
- case HDSP_spdifFrequency64KHz: return 64000;
- case HDSP_spdifFrequency88_2KHz: return 88200;
- case HDSP_spdifFrequency96KHz: return 96000;
- case HDSP_spdifFrequency128KHz:
- if (hdsp->io_type == H9632) return 128000;
- break;
- case HDSP_spdifFrequency176_4KHz:
- if (hdsp->io_type == H9632) return 176400;
- break;
- case HDSP_spdifFrequency192KHz:
- if (hdsp->io_type == H9632) return 192000;
- break;
- default:
- break;
- }
- snd_printk ("Hammerfall-DSP: unknown spdif frequency status; bits = 0x%x, status = 0x%x\n", rate_bits, status);
- return 0;
-}
-
-static int hdsp_external_sample_rate(struct hdsp *hdsp)
-{
- unsigned int status2 = hdsp_read(hdsp, HDSP_status2Register);
- unsigned int rate_bits = status2 & HDSP_systemFrequencyMask;
-
- /* For the 9632 card, there seems to be no bit for indicating external
- * sample rate greater than 96kHz. The card reports the corresponding
- * single speed. So the best means seems to get spdif rate when
- * autosync reference is spdif */
- if (hdsp->io_type == H9632 &&
- hdsp_autosync_ref(hdsp) == HDSP_AUTOSYNC_FROM_SPDIF)
- return hdsp_spdif_sample_rate(hdsp);
-
- switch (rate_bits) {
- case HDSP_systemFrequency32: return 32000;
- case HDSP_systemFrequency44_1: return 44100;
- case HDSP_systemFrequency48: return 48000;
- case HDSP_systemFrequency64: return 64000;
- case HDSP_systemFrequency88_2: return 88200;
- case HDSP_systemFrequency96: return 96000;
- default:
- return 0;
- }
-}
-
-static void hdsp_compute_period_size(struct hdsp *hdsp)
-{
- hdsp->period_bytes = 1 << ((hdsp_decode_latency(hdsp->control_register) + 8));
-}
-
-static snd_pcm_uframes_t hdsp_hw_pointer(struct hdsp *hdsp)
-{
- int position;
-
- position = hdsp_read(hdsp, HDSP_statusRegister);
-
- if (!hdsp->precise_ptr)
- return (position & HDSP_BufferID) ? (hdsp->period_bytes / 4) : 0;
-
- position &= HDSP_BufferPositionMask;
- position /= 4;
- position &= (hdsp->period_bytes/2) - 1;
- return position;
-}
-
-static void hdsp_reset_hw_pointer(struct hdsp *hdsp)
-{
- hdsp_write (hdsp, HDSP_resetPointer, 0);
- if (hdsp->io_type == H9632 && hdsp->firmware_rev >= 152)
- /* HDSP_resetPointer = HDSP_freqReg, which is strange and
- * requires (?) to write again DDS value after a reset pointer
- * (at least, it works like this) */
- hdsp_write (hdsp, HDSP_freqReg, hdsp->dds_value);
-}
-
-static void hdsp_start_audio(struct hdsp *s)
-{
- s->control_register |= (HDSP_AudioInterruptEnable | HDSP_Start);
- hdsp_write(s, HDSP_controlRegister, s->control_register);
-}
-
-static void hdsp_stop_audio(struct hdsp *s)
-{
- s->control_register &= ~(HDSP_Start | HDSP_AudioInterruptEnable);
- hdsp_write(s, HDSP_controlRegister, s->control_register);
-}
-
-static void hdsp_silence_playback(struct hdsp *hdsp)
-{
- memset(hdsp->playback_buffer, 0, HDSP_DMA_AREA_BYTES);
-}
-
-static int hdsp_set_interrupt_interval(struct hdsp *s, unsigned int frames)
-{
- int n;
-
- spin_lock_irq(&s->lock);
-
- frames >>= 7;
- n = 0;
- while (frames) {
- n++;
- frames >>= 1;
- }
-
- s->control_register &= ~HDSP_LatencyMask;
- s->control_register |= hdsp_encode_latency(n);
-
- hdsp_write(s, HDSP_controlRegister, s->control_register);
-
- hdsp_compute_period_size(s);
-
- spin_unlock_irq(&s->lock);
-
- return 0;
-}
-
-static void hdsp_set_dds_value(struct hdsp *hdsp, int rate)
-{
- u64 n;
-
- if (rate >= 112000)
- rate /= 4;
- else if (rate >= 56000)
- rate /= 2;
-
- n = DDS_NUMERATOR;
- n = div_u64(n, rate);
- /* n should be less than 2^32 for being written to FREQ register */
- snd_BUG_ON(n >> 32);
- /* HDSP_freqReg and HDSP_resetPointer are the same, so keep the DDS
- value to write it after a reset */
- hdsp->dds_value = n;
- hdsp_write(hdsp, HDSP_freqReg, hdsp->dds_value);
-}
-
-static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally)
-{
- int reject_if_open = 0;
- int current_rate;
- int rate_bits;
-
- /* ASSUMPTION: hdsp->lock is either held, or
- there is no need for it (e.g. during module
- initialization).
- */
-
- if (!(hdsp->control_register & HDSP_ClockModeMaster)) {
- if (called_internally) {
- /* request from ctl or card initialization */
- snd_printk(KERN_ERR "Hammerfall-DSP: device is not running as a clock master: cannot set sample rate.\n");
- return -1;
- } else {
- /* hw_param request while in AutoSync mode */
- int external_freq = hdsp_external_sample_rate(hdsp);
- int spdif_freq = hdsp_spdif_sample_rate(hdsp);
-
- if ((spdif_freq == external_freq*2) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1))
- snd_printk(KERN_INFO "Hammerfall-DSP: Detected ADAT in double speed mode\n");
- else if (hdsp->io_type == H9632 && (spdif_freq == external_freq*4) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1))
- snd_printk(KERN_INFO "Hammerfall-DSP: Detected ADAT in quad speed mode\n");
- else if (rate != external_freq) {
- snd_printk(KERN_INFO "Hammerfall-DSP: No AutoSync source for requested rate\n");
- return -1;
- }
- }
- }
-
- current_rate = hdsp->system_sample_rate;
-
- /* Changing from a "single speed" to a "double speed" rate is
- not allowed if any substreams are open. This is because
- such a change causes a shift in the location of
- the DMA buffers and a reduction in the number of available
- buffers.
-
- Note that a similar but essentially insoluble problem
- exists for externally-driven rate changes. All we can do
- is to flag rate changes in the read/write routines. */
-
- if (rate > 96000 && hdsp->io_type != H9632)
- return -EINVAL;
-
- switch (rate) {
- case 32000:
- if (current_rate > 48000)
- reject_if_open = 1;
- rate_bits = HDSP_Frequency32KHz;
- break;
- case 44100:
- if (current_rate > 48000)
- reject_if_open = 1;
- rate_bits = HDSP_Frequency44_1KHz;
- break;
- case 48000:
- if (current_rate > 48000)
- reject_if_open = 1;
- rate_bits = HDSP_Frequency48KHz;
- break;
- case 64000:
- if (current_rate <= 48000 || current_rate > 96000)
- reject_if_open = 1;
- rate_bits = HDSP_Frequency64KHz;
- break;
- case 88200:
- if (current_rate <= 48000 || current_rate > 96000)
- reject_if_open = 1;
- rate_bits = HDSP_Frequency88_2KHz;
- break;
- case 96000:
- if (current_rate <= 48000 || current_rate > 96000)
- reject_if_open = 1;
- rate_bits = HDSP_Frequency96KHz;
- break;
- case 128000:
- if (current_rate < 128000)
- reject_if_open = 1;
- rate_bits = HDSP_Frequency128KHz;
- break;
- case 176400:
- if (current_rate < 128000)
- reject_if_open = 1;
- rate_bits = HDSP_Frequency176_4KHz;
- break;
- case 192000:
- if (current_rate < 128000)
- reject_if_open = 1;
- rate_bits = HDSP_Frequency192KHz;
- break;
- default:
- return -EINVAL;
- }
-
- if (reject_if_open && (hdsp->capture_pid >= 0 || hdsp->playback_pid >= 0)) {
- snd_printk ("Hammerfall-DSP: cannot change speed mode (capture PID = %d, playback PID = %d)\n",
- hdsp->capture_pid,
- hdsp->playback_pid);
- return -EBUSY;
- }
-
- hdsp->control_register &= ~HDSP_FrequencyMask;
- hdsp->control_register |= rate_bits;
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
-
- /* For HDSP9632 rev 152, need to set DDS value in FREQ register */
- if (hdsp->io_type == H9632 && hdsp->firmware_rev >= 152)
- hdsp_set_dds_value(hdsp, rate);
-
- if (rate >= 128000) {
- hdsp->channel_map = channel_map_H9632_qs;
- } else if (rate > 48000) {
- if (hdsp->io_type == H9632)
- hdsp->channel_map = channel_map_H9632_ds;
- else
- hdsp->channel_map = channel_map_ds;
- } else {
- switch (hdsp->io_type) {
- case RPM:
- case Multiface:
- hdsp->channel_map = channel_map_mf_ss;
- break;
- case Digiface:
- case H9652:
- hdsp->channel_map = channel_map_df_ss;
- break;
- case H9632:
- hdsp->channel_map = channel_map_H9632_ss;
- break;
- default:
- /* should never happen */
- break;
- }
- }
-
- hdsp->system_sample_rate = rate;
-
- return 0;
-}
-
-/*----------------------------------------------------------------------------
- MIDI
- ----------------------------------------------------------------------------*/
-
-static unsigned char snd_hdsp_midi_read_byte (struct hdsp *hdsp, int id)
-{
- /* the hardware already does the relevant bit-mask with 0xff */
- if (id)
- return hdsp_read(hdsp, HDSP_midiDataIn1);
- else
- return hdsp_read(hdsp, HDSP_midiDataIn0);
-}
-
-static void snd_hdsp_midi_write_byte (struct hdsp *hdsp, int id, int val)
-{
- /* the hardware already does the relevant bit-mask with 0xff */
- if (id)
- hdsp_write(hdsp, HDSP_midiDataOut1, val);
- else
- hdsp_write(hdsp, HDSP_midiDataOut0, val);
-}
-
-static int snd_hdsp_midi_input_available (struct hdsp *hdsp, int id)
-{
- if (id)
- return (hdsp_read(hdsp, HDSP_midiStatusIn1) & 0xff);
- else
- return (hdsp_read(hdsp, HDSP_midiStatusIn0) & 0xff);
-}
-
-static int snd_hdsp_midi_output_possible (struct hdsp *hdsp, int id)
-{
- int fifo_bytes_used;
-
- if (id)
- fifo_bytes_used = hdsp_read(hdsp, HDSP_midiStatusOut1) & 0xff;
- else
- fifo_bytes_used = hdsp_read(hdsp, HDSP_midiStatusOut0) & 0xff;
-
- if (fifo_bytes_used < 128)
- return 128 - fifo_bytes_used;
- else
- return 0;
-}
-
-static void snd_hdsp_flush_midi_input (struct hdsp *hdsp, int id)
-{
- while (snd_hdsp_midi_input_available (hdsp, id))
- snd_hdsp_midi_read_byte (hdsp, id);
-}
-
-static int snd_hdsp_midi_output_write (struct hdsp_midi *hmidi)
-{
- unsigned long flags;
- int n_pending;
- int to_write;
- int i;
- unsigned char buf[128];
-
- /* Output is not interrupt driven */
-
- spin_lock_irqsave (&hmidi->lock, flags);
- if (hmidi->output) {
- if (!snd_rawmidi_transmit_empty (hmidi->output)) {
- if ((n_pending = snd_hdsp_midi_output_possible (hmidi->hdsp, hmidi->id)) > 0) {
- if (n_pending > (int)sizeof (buf))
- n_pending = sizeof (buf);
-
- if ((to_write = snd_rawmidi_transmit (hmidi->output, buf, n_pending)) > 0) {
- for (i = 0; i < to_write; ++i)
- snd_hdsp_midi_write_byte (hmidi->hdsp, hmidi->id, buf[i]);
- }
- }
- }
- }
- spin_unlock_irqrestore (&hmidi->lock, flags);
- return 0;
-}
-
-static int snd_hdsp_midi_input_read (struct hdsp_midi *hmidi)
-{
- unsigned char buf[128]; /* this buffer is designed to match the MIDI input FIFO size */
- unsigned long flags;
- int n_pending;
- int i;
-
- spin_lock_irqsave (&hmidi->lock, flags);
- if ((n_pending = snd_hdsp_midi_input_available (hmidi->hdsp, hmidi->id)) > 0) {
- if (hmidi->input) {
- if (n_pending > (int)sizeof (buf))
- n_pending = sizeof (buf);
- for (i = 0; i < n_pending; ++i)
- buf[i] = snd_hdsp_midi_read_byte (hmidi->hdsp, hmidi->id);
- if (n_pending)
- snd_rawmidi_receive (hmidi->input, buf, n_pending);
- } else {
- /* flush the MIDI input FIFO */
- while (--n_pending)
- snd_hdsp_midi_read_byte (hmidi->hdsp, hmidi->id);
- }
- }
- hmidi->pending = 0;
- if (hmidi->id)
- hmidi->hdsp->control_register |= HDSP_Midi1InterruptEnable;
- else
- hmidi->hdsp->control_register |= HDSP_Midi0InterruptEnable;
- hdsp_write(hmidi->hdsp, HDSP_controlRegister, hmidi->hdsp->control_register);
- spin_unlock_irqrestore (&hmidi->lock, flags);
- return snd_hdsp_midi_output_write (hmidi);
-}
-
-static void snd_hdsp_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct hdsp *hdsp;
- struct hdsp_midi *hmidi;
- unsigned long flags;
- u32 ie;
-
- hmidi = (struct hdsp_midi *) substream->rmidi->private_data;
- hdsp = hmidi->hdsp;
- ie = hmidi->id ? HDSP_Midi1InterruptEnable : HDSP_Midi0InterruptEnable;
- spin_lock_irqsave (&hdsp->lock, flags);
- if (up) {
- if (!(hdsp->control_register & ie)) {
- snd_hdsp_flush_midi_input (hdsp, hmidi->id);
- hdsp->control_register |= ie;
- }
- } else {
- hdsp->control_register &= ~ie;
- tasklet_kill(&hdsp->midi_tasklet);
- }
-
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- spin_unlock_irqrestore (&hdsp->lock, flags);
-}
-
-static void snd_hdsp_midi_output_timer(unsigned long data)
-{
- struct hdsp_midi *hmidi = (struct hdsp_midi *) data;
- unsigned long flags;
-
- snd_hdsp_midi_output_write(hmidi);
- spin_lock_irqsave (&hmidi->lock, flags);
-
- /* this does not bump hmidi->istimer, because the
- kernel automatically removed the timer when it
- expired, and we are now adding it back, thus
- leaving istimer wherever it was set before.
- */
-
- if (hmidi->istimer) {
- hmidi->timer.expires = 1 + jiffies;
- add_timer(&hmidi->timer);
- }
-
- spin_unlock_irqrestore (&hmidi->lock, flags);
-}
-
-static void snd_hdsp_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct hdsp_midi *hmidi;
- unsigned long flags;
-
- hmidi = (struct hdsp_midi *) substream->rmidi->private_data;
- spin_lock_irqsave (&hmidi->lock, flags);
- if (up) {
- if (!hmidi->istimer) {
- init_timer(&hmidi->timer);
- hmidi->timer.function = snd_hdsp_midi_output_timer;
- hmidi->timer.data = (unsigned long) hmidi;
- hmidi->timer.expires = 1 + jiffies;
- add_timer(&hmidi->timer);
- hmidi->istimer++;
- }
- } else {
- if (hmidi->istimer && --hmidi->istimer <= 0)
- del_timer (&hmidi->timer);
- }
- spin_unlock_irqrestore (&hmidi->lock, flags);
- if (up)
- snd_hdsp_midi_output_write(hmidi);
-}
-
-static int snd_hdsp_midi_input_open(struct snd_rawmidi_substream *substream)
-{
- struct hdsp_midi *hmidi;
-
- hmidi = (struct hdsp_midi *) substream->rmidi->private_data;
- spin_lock_irq (&hmidi->lock);
- snd_hdsp_flush_midi_input (hmidi->hdsp, hmidi->id);
- hmidi->input = substream;
- spin_unlock_irq (&hmidi->lock);
-
- return 0;
-}
-
-static int snd_hdsp_midi_output_open(struct snd_rawmidi_substream *substream)
-{
- struct hdsp_midi *hmidi;
-
- hmidi = (struct hdsp_midi *) substream->rmidi->private_data;
- spin_lock_irq (&hmidi->lock);
- hmidi->output = substream;
- spin_unlock_irq (&hmidi->lock);
-
- return 0;
-}
-
-static int snd_hdsp_midi_input_close(struct snd_rawmidi_substream *substream)
-{
- struct hdsp_midi *hmidi;
-
- snd_hdsp_midi_input_trigger (substream, 0);
-
- hmidi = (struct hdsp_midi *) substream->rmidi->private_data;
- spin_lock_irq (&hmidi->lock);
- hmidi->input = NULL;
- spin_unlock_irq (&hmidi->lock);
-
- return 0;
-}
-
-static int snd_hdsp_midi_output_close(struct snd_rawmidi_substream *substream)
-{
- struct hdsp_midi *hmidi;
-
- snd_hdsp_midi_output_trigger (substream, 0);
-
- hmidi = (struct hdsp_midi *) substream->rmidi->private_data;
- spin_lock_irq (&hmidi->lock);
- hmidi->output = NULL;
- spin_unlock_irq (&hmidi->lock);
-
- return 0;
-}
-
-static struct snd_rawmidi_ops snd_hdsp_midi_output =
-{
- .open = snd_hdsp_midi_output_open,
- .close = snd_hdsp_midi_output_close,
- .trigger = snd_hdsp_midi_output_trigger,
-};
-
-static struct snd_rawmidi_ops snd_hdsp_midi_input =
-{
- .open = snd_hdsp_midi_input_open,
- .close = snd_hdsp_midi_input_close,
- .trigger = snd_hdsp_midi_input_trigger,
-};
-
-static int snd_hdsp_create_midi (struct snd_card *card, struct hdsp *hdsp, int id)
-{
- char buf[32];
-
- hdsp->midi[id].id = id;
- hdsp->midi[id].rmidi = NULL;
- hdsp->midi[id].input = NULL;
- hdsp->midi[id].output = NULL;
- hdsp->midi[id].hdsp = hdsp;
- hdsp->midi[id].istimer = 0;
- hdsp->midi[id].pending = 0;
- spin_lock_init (&hdsp->midi[id].lock);
-
- sprintf (buf, "%s MIDI %d", card->shortname, id+1);
- if (snd_rawmidi_new (card, buf, id, 1, 1, &hdsp->midi[id].rmidi) < 0)
- return -1;
-
- sprintf(hdsp->midi[id].rmidi->name, "HDSP MIDI %d", id+1);
- hdsp->midi[id].rmidi->private_data = &hdsp->midi[id];
-
- snd_rawmidi_set_ops (hdsp->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_hdsp_midi_output);
- snd_rawmidi_set_ops (hdsp->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_hdsp_midi_input);
-
- hdsp->midi[id].rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
-
- return 0;
-}
-
-/*-----------------------------------------------------------------------------
- Control Interface
- ----------------------------------------------------------------------------*/
-
-static u32 snd_hdsp_convert_from_aes(struct snd_aes_iec958 *aes)
-{
- u32 val = 0;
- val |= (aes->status[0] & IEC958_AES0_PROFESSIONAL) ? HDSP_SPDIFProfessional : 0;
- val |= (aes->status[0] & IEC958_AES0_NONAUDIO) ? HDSP_SPDIFNonAudio : 0;
- if (val & HDSP_SPDIFProfessional)
- val |= (aes->status[0] & IEC958_AES0_PRO_EMPHASIS_5015) ? HDSP_SPDIFEmphasis : 0;
- else
- val |= (aes->status[0] & IEC958_AES0_CON_EMPHASIS_5015) ? HDSP_SPDIFEmphasis : 0;
- return val;
-}
-
-static void snd_hdsp_convert_to_aes(struct snd_aes_iec958 *aes, u32 val)
-{
- aes->status[0] = ((val & HDSP_SPDIFProfessional) ? IEC958_AES0_PROFESSIONAL : 0) |
- ((val & HDSP_SPDIFNonAudio) ? IEC958_AES0_NONAUDIO : 0);
- if (val & HDSP_SPDIFProfessional)
- aes->status[0] |= (val & HDSP_SPDIFEmphasis) ? IEC958_AES0_PRO_EMPHASIS_5015 : 0;
- else
- aes->status[0] |= (val & HDSP_SPDIFEmphasis) ? IEC958_AES0_CON_EMPHASIS_5015 : 0;
-}
-
-static int snd_hdsp_control_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_hdsp_control_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- snd_hdsp_convert_to_aes(&ucontrol->value.iec958, hdsp->creg_spdif);
- return 0;
-}
-
-static int snd_hdsp_control_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- u32 val;
-
- val = snd_hdsp_convert_from_aes(&ucontrol->value.iec958);
- spin_lock_irq(&hdsp->lock);
- change = val != hdsp->creg_spdif;
- hdsp->creg_spdif = val;
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-static int snd_hdsp_control_spdif_stream_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_hdsp_control_spdif_stream_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- snd_hdsp_convert_to_aes(&ucontrol->value.iec958, hdsp->creg_spdif_stream);
- return 0;
-}
-
-static int snd_hdsp_control_spdif_stream_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- u32 val;
-
- val = snd_hdsp_convert_from_aes(&ucontrol->value.iec958);
- spin_lock_irq(&hdsp->lock);
- change = val != hdsp->creg_spdif_stream;
- hdsp->creg_spdif_stream = val;
- hdsp->control_register &= ~(HDSP_SPDIFProfessional | HDSP_SPDIFNonAudio | HDSP_SPDIFEmphasis);
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register |= val);
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-static int snd_hdsp_control_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_hdsp_control_spdif_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.iec958.status[0] = kcontrol->private_value;
- return 0;
-}
-
-#define HDSP_SPDIF_IN(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdsp_info_spdif_in, \
- .get = snd_hdsp_get_spdif_in, \
- .put = snd_hdsp_put_spdif_in }
-
-static unsigned int hdsp_spdif_in(struct hdsp *hdsp)
-{
- return hdsp_decode_spdif_in(hdsp->control_register & HDSP_SPDIFInputMask);
-}
-
-static int hdsp_set_spdif_input(struct hdsp *hdsp, int in)
-{
- hdsp->control_register &= ~HDSP_SPDIFInputMask;
- hdsp->control_register |= hdsp_encode_spdif_in(in);
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- return 0;
-}
-
-static int snd_hdsp_info_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[4] = {"Optical", "Coaxial", "Internal", "AES"};
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = ((hdsp->io_type == H9632) ? 4 : 3);
- if (uinfo->value.enumerated.item > ((hdsp->io_type == H9632) ? 3 : 2))
- uinfo->value.enumerated.item = ((hdsp->io_type == H9632) ? 3 : 2);
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_hdsp_get_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdsp_spdif_in(hdsp);
- return 0;
-}
-
-static int snd_hdsp_put_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
- val = ucontrol->value.enumerated.item[0] % ((hdsp->io_type == H9632) ? 4 : 3);
- spin_lock_irq(&hdsp->lock);
- change = val != hdsp_spdif_in(hdsp);
- if (change)
- hdsp_set_spdif_input(hdsp, val);
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-#define HDSP_SPDIF_OUT(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_hdsp_info_spdif_bits, \
- .get = snd_hdsp_get_spdif_out, .put = snd_hdsp_put_spdif_out }
-
-static int hdsp_spdif_out(struct hdsp *hdsp)
-{
- return (hdsp->control_register & HDSP_SPDIFOpticalOut) ? 1 : 0;
-}
-
-static int hdsp_set_spdif_output(struct hdsp *hdsp, int out)
-{
- if (out)
- hdsp->control_register |= HDSP_SPDIFOpticalOut;
- else
- hdsp->control_register &= ~HDSP_SPDIFOpticalOut;
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- return 0;
-}
-
-#define snd_hdsp_info_spdif_bits snd_ctl_boolean_mono_info
-
-static int snd_hdsp_get_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = hdsp_spdif_out(hdsp);
- return 0;
-}
-
-static int snd_hdsp_put_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdsp->lock);
- change = (int)val != hdsp_spdif_out(hdsp);
- hdsp_set_spdif_output(hdsp, val);
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-#define HDSP_SPDIF_PROFESSIONAL(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_hdsp_info_spdif_bits, \
- .get = snd_hdsp_get_spdif_professional, .put = snd_hdsp_put_spdif_professional }
-
-static int hdsp_spdif_professional(struct hdsp *hdsp)
-{
- return (hdsp->control_register & HDSP_SPDIFProfessional) ? 1 : 0;
-}
-
-static int hdsp_set_spdif_professional(struct hdsp *hdsp, int val)
-{
- if (val)
- hdsp->control_register |= HDSP_SPDIFProfessional;
- else
- hdsp->control_register &= ~HDSP_SPDIFProfessional;
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- return 0;
-}
-
-static int snd_hdsp_get_spdif_professional(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = hdsp_spdif_professional(hdsp);
- return 0;
-}
-
-static int snd_hdsp_put_spdif_professional(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdsp->lock);
- change = (int)val != hdsp_spdif_professional(hdsp);
- hdsp_set_spdif_professional(hdsp, val);
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-#define HDSP_SPDIF_EMPHASIS(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_hdsp_info_spdif_bits, \
- .get = snd_hdsp_get_spdif_emphasis, .put = snd_hdsp_put_spdif_emphasis }
-
-static int hdsp_spdif_emphasis(struct hdsp *hdsp)
-{
- return (hdsp->control_register & HDSP_SPDIFEmphasis) ? 1 : 0;
-}
-
-static int hdsp_set_spdif_emphasis(struct hdsp *hdsp, int val)
-{
- if (val)
- hdsp->control_register |= HDSP_SPDIFEmphasis;
- else
- hdsp->control_register &= ~HDSP_SPDIFEmphasis;
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- return 0;
-}
-
-static int snd_hdsp_get_spdif_emphasis(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = hdsp_spdif_emphasis(hdsp);
- return 0;
-}
-
-static int snd_hdsp_put_spdif_emphasis(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdsp->lock);
- change = (int)val != hdsp_spdif_emphasis(hdsp);
- hdsp_set_spdif_emphasis(hdsp, val);
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-#define HDSP_SPDIF_NON_AUDIO(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_hdsp_info_spdif_bits, \
- .get = snd_hdsp_get_spdif_nonaudio, .put = snd_hdsp_put_spdif_nonaudio }
-
-static int hdsp_spdif_nonaudio(struct hdsp *hdsp)
-{
- return (hdsp->control_register & HDSP_SPDIFNonAudio) ? 1 : 0;
-}
-
-static int hdsp_set_spdif_nonaudio(struct hdsp *hdsp, int val)
-{
- if (val)
- hdsp->control_register |= HDSP_SPDIFNonAudio;
- else
- hdsp->control_register &= ~HDSP_SPDIFNonAudio;
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- return 0;
-}
-
-static int snd_hdsp_get_spdif_nonaudio(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = hdsp_spdif_nonaudio(hdsp);
- return 0;
-}
-
-static int snd_hdsp_put_spdif_nonaudio(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdsp->lock);
- change = (int)val != hdsp_spdif_nonaudio(hdsp);
- hdsp_set_spdif_nonaudio(hdsp, val);
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-#define HDSP_SPDIF_SAMPLE_RATE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READ, \
- .info = snd_hdsp_info_spdif_sample_rate, \
- .get = snd_hdsp_get_spdif_sample_rate \
-}
-
-static int snd_hdsp_info_spdif_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = {"32000", "44100", "48000", "64000", "88200", "96000", "None", "128000", "176400", "192000"};
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = (hdsp->io_type == H9632) ? 10 : 7;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_hdsp_get_spdif_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- switch (hdsp_spdif_sample_rate(hdsp)) {
- case 32000:
- ucontrol->value.enumerated.item[0] = 0;
- break;
- case 44100:
- ucontrol->value.enumerated.item[0] = 1;
- break;
- case 48000:
- ucontrol->value.enumerated.item[0] = 2;
- break;
- case 64000:
- ucontrol->value.enumerated.item[0] = 3;
- break;
- case 88200:
- ucontrol->value.enumerated.item[0] = 4;
- break;
- case 96000:
- ucontrol->value.enumerated.item[0] = 5;
- break;
- case 128000:
- ucontrol->value.enumerated.item[0] = 7;
- break;
- case 176400:
- ucontrol->value.enumerated.item[0] = 8;
- break;
- case 192000:
- ucontrol->value.enumerated.item[0] = 9;
- break;
- default:
- ucontrol->value.enumerated.item[0] = 6;
- }
- return 0;
-}
-
-#define HDSP_SYSTEM_SAMPLE_RATE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READ, \
- .info = snd_hdsp_info_system_sample_rate, \
- .get = snd_hdsp_get_system_sample_rate \
-}
-
-static int snd_hdsp_info_system_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_hdsp_get_system_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdsp->system_sample_rate;
- return 0;
-}
-
-#define HDSP_AUTOSYNC_SAMPLE_RATE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READ, \
- .info = snd_hdsp_info_autosync_sample_rate, \
- .get = snd_hdsp_get_autosync_sample_rate \
-}
-
-static int snd_hdsp_info_autosync_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- static char *texts[] = {"32000", "44100", "48000", "64000", "88200", "96000", "None", "128000", "176400", "192000"};
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = (hdsp->io_type == H9632) ? 10 : 7 ;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_hdsp_get_autosync_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- switch (hdsp_external_sample_rate(hdsp)) {
- case 32000:
- ucontrol->value.enumerated.item[0] = 0;
- break;
- case 44100:
- ucontrol->value.enumerated.item[0] = 1;
- break;
- case 48000:
- ucontrol->value.enumerated.item[0] = 2;
- break;
- case 64000:
- ucontrol->value.enumerated.item[0] = 3;
- break;
- case 88200:
- ucontrol->value.enumerated.item[0] = 4;
- break;
- case 96000:
- ucontrol->value.enumerated.item[0] = 5;
- break;
- case 128000:
- ucontrol->value.enumerated.item[0] = 7;
- break;
- case 176400:
- ucontrol->value.enumerated.item[0] = 8;
- break;
- case 192000:
- ucontrol->value.enumerated.item[0] = 9;
- break;
- default:
- ucontrol->value.enumerated.item[0] = 6;
- }
- return 0;
-}
-
-#define HDSP_SYSTEM_CLOCK_MODE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READ, \
- .info = snd_hdsp_info_system_clock_mode, \
- .get = snd_hdsp_get_system_clock_mode \
-}
-
-static int hdsp_system_clock_mode(struct hdsp *hdsp)
-{
- if (hdsp->control_register & HDSP_ClockModeMaster)
- return 0;
- else if (hdsp_external_sample_rate(hdsp) != hdsp->system_sample_rate)
- return 0;
- return 1;
-}
-
-static int snd_hdsp_info_system_clock_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = {"Master", "Slave" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_hdsp_get_system_clock_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdsp_system_clock_mode(hdsp);
- return 0;
-}
-
-#define HDSP_CLOCK_SOURCE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdsp_info_clock_source, \
- .get = snd_hdsp_get_clock_source, \
- .put = snd_hdsp_put_clock_source \
-}
-
-static int hdsp_clock_source(struct hdsp *hdsp)
-{
- if (hdsp->control_register & HDSP_ClockModeMaster) {
- switch (hdsp->system_sample_rate) {
- case 32000:
- return 1;
- case 44100:
- return 2;
- case 48000:
- return 3;
- case 64000:
- return 4;
- case 88200:
- return 5;
- case 96000:
- return 6;
- case 128000:
- return 7;
- case 176400:
- return 8;
- case 192000:
- return 9;
- default:
- return 3;
- }
- } else {
- return 0;
- }
-}
-
-static int hdsp_set_clock_source(struct hdsp *hdsp, int mode)
-{
- int rate;
- switch (mode) {
- case HDSP_CLOCK_SOURCE_AUTOSYNC:
- if (hdsp_external_sample_rate(hdsp) != 0) {
- if (!hdsp_set_rate(hdsp, hdsp_external_sample_rate(hdsp), 1)) {
- hdsp->control_register &= ~HDSP_ClockModeMaster;
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- return 0;
- }
- }
- return -1;
- case HDSP_CLOCK_SOURCE_INTERNAL_32KHZ:
- rate = 32000;
- break;
- case HDSP_CLOCK_SOURCE_INTERNAL_44_1KHZ:
- rate = 44100;
- break;
- case HDSP_CLOCK_SOURCE_INTERNAL_48KHZ:
- rate = 48000;
- break;
- case HDSP_CLOCK_SOURCE_INTERNAL_64KHZ:
- rate = 64000;
- break;
- case HDSP_CLOCK_SOURCE_INTERNAL_88_2KHZ:
- rate = 88200;
- break;
- case HDSP_CLOCK_SOURCE_INTERNAL_96KHZ:
- rate = 96000;
- break;
- case HDSP_CLOCK_SOURCE_INTERNAL_128KHZ:
- rate = 128000;
- break;
- case HDSP_CLOCK_SOURCE_INTERNAL_176_4KHZ:
- rate = 176400;
- break;
- case HDSP_CLOCK_SOURCE_INTERNAL_192KHZ:
- rate = 192000;
- break;
- default:
- rate = 48000;
- }
- hdsp->control_register |= HDSP_ClockModeMaster;
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- hdsp_set_rate(hdsp, rate, 1);
- return 0;
-}
-
-static int snd_hdsp_info_clock_source(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = {"AutoSync", "Internal 32.0 kHz", "Internal 44.1 kHz", "Internal 48.0 kHz", "Internal 64.0 kHz", "Internal 88.2 kHz", "Internal 96.0 kHz", "Internal 128 kHz", "Internal 176.4 kHz", "Internal 192.0 KHz" };
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- if (hdsp->io_type == H9632)
- uinfo->value.enumerated.items = 10;
- else
- uinfo->value.enumerated.items = 7;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_hdsp_get_clock_source(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdsp_clock_source(hdsp);
- return 0;
-}
-
-static int snd_hdsp_put_clock_source(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- int val;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
- val = ucontrol->value.enumerated.item[0];
- if (val < 0) val = 0;
- if (hdsp->io_type == H9632) {
- if (val > 9)
- val = 9;
- } else {
- if (val > 6)
- val = 6;
- }
- spin_lock_irq(&hdsp->lock);
- if (val != hdsp_clock_source(hdsp))
- change = (hdsp_set_clock_source(hdsp, val) == 0) ? 1 : 0;
- else
- change = 0;
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-#define snd_hdsp_info_clock_source_lock snd_ctl_boolean_mono_info
-
-static int snd_hdsp_get_clock_source_lock(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = hdsp->clock_source_locked;
- return 0;
-}
-
-static int snd_hdsp_put_clock_source_lock(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
-
- change = (int)ucontrol->value.integer.value[0] != hdsp->clock_source_locked;
- if (change)
- hdsp->clock_source_locked = !!ucontrol->value.integer.value[0];
- return change;
-}
-
-#define HDSP_DA_GAIN(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdsp_info_da_gain, \
- .get = snd_hdsp_get_da_gain, \
- .put = snd_hdsp_put_da_gain \
-}
-
-static int hdsp_da_gain(struct hdsp *hdsp)
-{
- switch (hdsp->control_register & HDSP_DAGainMask) {
- case HDSP_DAGainHighGain:
- return 0;
- case HDSP_DAGainPlus4dBu:
- return 1;
- case HDSP_DAGainMinus10dBV:
- return 2;
- default:
- return 1;
- }
-}
-
-static int hdsp_set_da_gain(struct hdsp *hdsp, int mode)
-{
- hdsp->control_register &= ~HDSP_DAGainMask;
- switch (mode) {
- case 0:
- hdsp->control_register |= HDSP_DAGainHighGain;
- break;
- case 1:
- hdsp->control_register |= HDSP_DAGainPlus4dBu;
- break;
- case 2:
- hdsp->control_register |= HDSP_DAGainMinus10dBV;
- break;
- default:
- return -1;
-
- }
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- return 0;
-}
-
-static int snd_hdsp_info_da_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = {"Hi Gain", "+4 dBu", "-10 dbV"};
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_hdsp_get_da_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdsp_da_gain(hdsp);
- return 0;
-}
-
-static int snd_hdsp_put_da_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- int val;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
- val = ucontrol->value.enumerated.item[0];
- if (val < 0) val = 0;
- if (val > 2) val = 2;
- spin_lock_irq(&hdsp->lock);
- if (val != hdsp_da_gain(hdsp))
- change = (hdsp_set_da_gain(hdsp, val) == 0) ? 1 : 0;
- else
- change = 0;
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-#define HDSP_AD_GAIN(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdsp_info_ad_gain, \
- .get = snd_hdsp_get_ad_gain, \
- .put = snd_hdsp_put_ad_gain \
-}
-
-static int hdsp_ad_gain(struct hdsp *hdsp)
-{
- switch (hdsp->control_register & HDSP_ADGainMask) {
- case HDSP_ADGainMinus10dBV:
- return 0;
- case HDSP_ADGainPlus4dBu:
- return 1;
- case HDSP_ADGainLowGain:
- return 2;
- default:
- return 1;
- }
-}
-
-static int hdsp_set_ad_gain(struct hdsp *hdsp, int mode)
-{
- hdsp->control_register &= ~HDSP_ADGainMask;
- switch (mode) {
- case 0:
- hdsp->control_register |= HDSP_ADGainMinus10dBV;
- break;
- case 1:
- hdsp->control_register |= HDSP_ADGainPlus4dBu;
- break;
- case 2:
- hdsp->control_register |= HDSP_ADGainLowGain;
- break;
- default:
- return -1;
-
- }
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- return 0;
-}
-
-static int snd_hdsp_info_ad_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = {"-10 dBV", "+4 dBu", "Lo Gain"};
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_hdsp_get_ad_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdsp_ad_gain(hdsp);
- return 0;
-}
-
-static int snd_hdsp_put_ad_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- int val;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
- val = ucontrol->value.enumerated.item[0];
- if (val < 0) val = 0;
- if (val > 2) val = 2;
- spin_lock_irq(&hdsp->lock);
- if (val != hdsp_ad_gain(hdsp))
- change = (hdsp_set_ad_gain(hdsp, val) == 0) ? 1 : 0;
- else
- change = 0;
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-#define HDSP_PHONE_GAIN(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdsp_info_phone_gain, \
- .get = snd_hdsp_get_phone_gain, \
- .put = snd_hdsp_put_phone_gain \
-}
-
-static int hdsp_phone_gain(struct hdsp *hdsp)
-{
- switch (hdsp->control_register & HDSP_PhoneGainMask) {
- case HDSP_PhoneGain0dB:
- return 0;
- case HDSP_PhoneGainMinus6dB:
- return 1;
- case HDSP_PhoneGainMinus12dB:
- return 2;
- default:
- return 0;
- }
-}
-
-static int hdsp_set_phone_gain(struct hdsp *hdsp, int mode)
-{
- hdsp->control_register &= ~HDSP_PhoneGainMask;
- switch (mode) {
- case 0:
- hdsp->control_register |= HDSP_PhoneGain0dB;
- break;
- case 1:
- hdsp->control_register |= HDSP_PhoneGainMinus6dB;
- break;
- case 2:
- hdsp->control_register |= HDSP_PhoneGainMinus12dB;
- break;
- default:
- return -1;
-
- }
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- return 0;
-}
-
-static int snd_hdsp_info_phone_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = {"0 dB", "-6 dB", "-12 dB"};
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_hdsp_get_phone_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdsp_phone_gain(hdsp);
- return 0;
-}
-
-static int snd_hdsp_put_phone_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- int val;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
- val = ucontrol->value.enumerated.item[0];
- if (val < 0) val = 0;
- if (val > 2) val = 2;
- spin_lock_irq(&hdsp->lock);
- if (val != hdsp_phone_gain(hdsp))
- change = (hdsp_set_phone_gain(hdsp, val) == 0) ? 1 : 0;
- else
- change = 0;
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-#define HDSP_XLR_BREAKOUT_CABLE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdsp_info_xlr_breakout_cable, \
- .get = snd_hdsp_get_xlr_breakout_cable, \
- .put = snd_hdsp_put_xlr_breakout_cable \
-}
-
-static int hdsp_xlr_breakout_cable(struct hdsp *hdsp)
-{
- if (hdsp->control_register & HDSP_XLRBreakoutCable)
- return 1;
- return 0;
-}
-
-static int hdsp_set_xlr_breakout_cable(struct hdsp *hdsp, int mode)
-{
- if (mode)
- hdsp->control_register |= HDSP_XLRBreakoutCable;
- else
- hdsp->control_register &= ~HDSP_XLRBreakoutCable;
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- return 0;
-}
-
-#define snd_hdsp_info_xlr_breakout_cable snd_ctl_boolean_mono_info
-
-static int snd_hdsp_get_xlr_breakout_cable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdsp_xlr_breakout_cable(hdsp);
- return 0;
-}
-
-static int snd_hdsp_put_xlr_breakout_cable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- int val;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdsp->lock);
- change = (int)val != hdsp_xlr_breakout_cable(hdsp);
- hdsp_set_xlr_breakout_cable(hdsp, val);
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-/* (De)activates old RME Analog Extension Board
- These are connected to the internal ADAT connector
- Switching this on desactivates external ADAT
-*/
-#define HDSP_AEB(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdsp_info_aeb, \
- .get = snd_hdsp_get_aeb, \
- .put = snd_hdsp_put_aeb \
-}
-
-static int hdsp_aeb(struct hdsp *hdsp)
-{
- if (hdsp->control_register & HDSP_AnalogExtensionBoard)
- return 1;
- return 0;
-}
-
-static int hdsp_set_aeb(struct hdsp *hdsp, int mode)
-{
- if (mode)
- hdsp->control_register |= HDSP_AnalogExtensionBoard;
- else
- hdsp->control_register &= ~HDSP_AnalogExtensionBoard;
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- return 0;
-}
-
-#define snd_hdsp_info_aeb snd_ctl_boolean_mono_info
-
-static int snd_hdsp_get_aeb(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdsp_aeb(hdsp);
- return 0;
-}
-
-static int snd_hdsp_put_aeb(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- int val;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdsp->lock);
- change = (int)val != hdsp_aeb(hdsp);
- hdsp_set_aeb(hdsp, val);
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-#define HDSP_PREF_SYNC_REF(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdsp_info_pref_sync_ref, \
- .get = snd_hdsp_get_pref_sync_ref, \
- .put = snd_hdsp_put_pref_sync_ref \
-}
-
-static int hdsp_pref_sync_ref(struct hdsp *hdsp)
-{
- /* Notice that this looks at the requested sync source,
- not the one actually in use.
- */
-
- switch (hdsp->control_register & HDSP_SyncRefMask) {
- case HDSP_SyncRef_ADAT1:
- return HDSP_SYNC_FROM_ADAT1;
- case HDSP_SyncRef_ADAT2:
- return HDSP_SYNC_FROM_ADAT2;
- case HDSP_SyncRef_ADAT3:
- return HDSP_SYNC_FROM_ADAT3;
- case HDSP_SyncRef_SPDIF:
- return HDSP_SYNC_FROM_SPDIF;
- case HDSP_SyncRef_WORD:
- return HDSP_SYNC_FROM_WORD;
- case HDSP_SyncRef_ADAT_SYNC:
- return HDSP_SYNC_FROM_ADAT_SYNC;
- default:
- return HDSP_SYNC_FROM_WORD;
- }
- return 0;
-}
-
-static int hdsp_set_pref_sync_ref(struct hdsp *hdsp, int pref)
-{
- hdsp->control_register &= ~HDSP_SyncRefMask;
- switch (pref) {
- case HDSP_SYNC_FROM_ADAT1:
- hdsp->control_register &= ~HDSP_SyncRefMask; /* clear SyncRef bits */
- break;
- case HDSP_SYNC_FROM_ADAT2:
- hdsp->control_register |= HDSP_SyncRef_ADAT2;
- break;
- case HDSP_SYNC_FROM_ADAT3:
- hdsp->control_register |= HDSP_SyncRef_ADAT3;
- break;
- case HDSP_SYNC_FROM_SPDIF:
- hdsp->control_register |= HDSP_SyncRef_SPDIF;
- break;
- case HDSP_SYNC_FROM_WORD:
- hdsp->control_register |= HDSP_SyncRef_WORD;
- break;
- case HDSP_SYNC_FROM_ADAT_SYNC:
- hdsp->control_register |= HDSP_SyncRef_ADAT_SYNC;
- break;
- default:
- return -1;
- }
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- return 0;
-}
-
-static int snd_hdsp_info_pref_sync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = {"Word", "IEC958", "ADAT1", "ADAT Sync", "ADAT2", "ADAT3" };
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
-
- switch (hdsp->io_type) {
- case Digiface:
- case H9652:
- uinfo->value.enumerated.items = 6;
- break;
- case Multiface:
- uinfo->value.enumerated.items = 4;
- break;
- case H9632:
- uinfo->value.enumerated.items = 3;
- break;
- default:
- return -EINVAL;
- }
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_hdsp_get_pref_sync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdsp_pref_sync_ref(hdsp);
- return 0;
-}
-
-static int snd_hdsp_put_pref_sync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change, max;
- unsigned int val;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
-
- switch (hdsp->io_type) {
- case Digiface:
- case H9652:
- max = 6;
- break;
- case Multiface:
- max = 4;
- break;
- case H9632:
- max = 3;
- break;
- default:
- return -EIO;
- }
-
- val = ucontrol->value.enumerated.item[0] % max;
- spin_lock_irq(&hdsp->lock);
- change = (int)val != hdsp_pref_sync_ref(hdsp);
- hdsp_set_pref_sync_ref(hdsp, val);
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-#define HDSP_AUTOSYNC_REF(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READ, \
- .info = snd_hdsp_info_autosync_ref, \
- .get = snd_hdsp_get_autosync_ref, \
-}
-
-static int hdsp_autosync_ref(struct hdsp *hdsp)
-{
- /* This looks at the autosync selected sync reference */
- unsigned int status2 = hdsp_read(hdsp, HDSP_status2Register);
-
- switch (status2 & HDSP_SelSyncRefMask) {
- case HDSP_SelSyncRef_WORD:
- return HDSP_AUTOSYNC_FROM_WORD;
- case HDSP_SelSyncRef_ADAT_SYNC:
- return HDSP_AUTOSYNC_FROM_ADAT_SYNC;
- case HDSP_SelSyncRef_SPDIF:
- return HDSP_AUTOSYNC_FROM_SPDIF;
- case HDSP_SelSyncRefMask:
- return HDSP_AUTOSYNC_FROM_NONE;
- case HDSP_SelSyncRef_ADAT1:
- return HDSP_AUTOSYNC_FROM_ADAT1;
- case HDSP_SelSyncRef_ADAT2:
- return HDSP_AUTOSYNC_FROM_ADAT2;
- case HDSP_SelSyncRef_ADAT3:
- return HDSP_AUTOSYNC_FROM_ADAT3;
- default:
- return HDSP_AUTOSYNC_FROM_WORD;
- }
- return 0;
-}
-
-static int snd_hdsp_info_autosync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = {"Word", "ADAT Sync", "IEC958", "None", "ADAT1", "ADAT2", "ADAT3" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 7;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_hdsp_get_autosync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdsp_autosync_ref(hdsp);
- return 0;
-}
-
-#define HDSP_LINE_OUT(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdsp_info_line_out, \
- .get = snd_hdsp_get_line_out, \
- .put = snd_hdsp_put_line_out \
-}
-
-static int hdsp_line_out(struct hdsp *hdsp)
-{
- return (hdsp->control_register & HDSP_LineOut) ? 1 : 0;
-}
-
-static int hdsp_set_line_output(struct hdsp *hdsp, int out)
-{
- if (out)
- hdsp->control_register |= HDSP_LineOut;
- else
- hdsp->control_register &= ~HDSP_LineOut;
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- return 0;
-}
-
-#define snd_hdsp_info_line_out snd_ctl_boolean_mono_info
-
-static int snd_hdsp_get_line_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&hdsp->lock);
- ucontrol->value.integer.value[0] = hdsp_line_out(hdsp);
- spin_unlock_irq(&hdsp->lock);
- return 0;
-}
-
-static int snd_hdsp_put_line_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdsp->lock);
- change = (int)val != hdsp_line_out(hdsp);
- hdsp_set_line_output(hdsp, val);
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-#define HDSP_PRECISE_POINTER(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_CARD, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdsp_info_precise_pointer, \
- .get = snd_hdsp_get_precise_pointer, \
- .put = snd_hdsp_put_precise_pointer \
-}
-
-static int hdsp_set_precise_pointer(struct hdsp *hdsp, int precise)
-{
- if (precise)
- hdsp->precise_ptr = 1;
- else
- hdsp->precise_ptr = 0;
- return 0;
-}
-
-#define snd_hdsp_info_precise_pointer snd_ctl_boolean_mono_info
-
-static int snd_hdsp_get_precise_pointer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&hdsp->lock);
- ucontrol->value.integer.value[0] = hdsp->precise_ptr;
- spin_unlock_irq(&hdsp->lock);
- return 0;
-}
-
-static int snd_hdsp_put_precise_pointer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdsp->lock);
- change = (int)val != hdsp->precise_ptr;
- hdsp_set_precise_pointer(hdsp, val);
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-#define HDSP_USE_MIDI_TASKLET(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_CARD, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdsp_info_use_midi_tasklet, \
- .get = snd_hdsp_get_use_midi_tasklet, \
- .put = snd_hdsp_put_use_midi_tasklet \
-}
-
-static int hdsp_set_use_midi_tasklet(struct hdsp *hdsp, int use_tasklet)
-{
- if (use_tasklet)
- hdsp->use_midi_tasklet = 1;
- else
- hdsp->use_midi_tasklet = 0;
- return 0;
-}
-
-#define snd_hdsp_info_use_midi_tasklet snd_ctl_boolean_mono_info
-
-static int snd_hdsp_get_use_midi_tasklet(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&hdsp->lock);
- ucontrol->value.integer.value[0] = hdsp->use_midi_tasklet;
- spin_unlock_irq(&hdsp->lock);
- return 0;
-}
-
-static int snd_hdsp_put_use_midi_tasklet(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdsp->lock);
- change = (int)val != hdsp->use_midi_tasklet;
- hdsp_set_use_midi_tasklet(hdsp, val);
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-#define HDSP_MIXER(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
- .name = xname, \
- .index = xindex, \
- .device = 0, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
- SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
- .info = snd_hdsp_info_mixer, \
- .get = snd_hdsp_get_mixer, \
- .put = snd_hdsp_put_mixer \
-}
-
-static int snd_hdsp_info_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 3;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 65536;
- uinfo->value.integer.step = 1;
- return 0;
-}
-
-static int snd_hdsp_get_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int source;
- int destination;
- int addr;
-
- source = ucontrol->value.integer.value[0];
- destination = ucontrol->value.integer.value[1];
-
- if (source >= hdsp->max_channels)
- addr = hdsp_playback_to_output_key(hdsp,source-hdsp->max_channels,destination);
- else
- addr = hdsp_input_to_output_key(hdsp,source, destination);
-
- spin_lock_irq(&hdsp->lock);
- ucontrol->value.integer.value[2] = hdsp_read_gain (hdsp, addr);
- spin_unlock_irq(&hdsp->lock);
- return 0;
-}
-
-static int snd_hdsp_put_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- int source;
- int destination;
- int gain;
- int addr;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
-
- source = ucontrol->value.integer.value[0];
- destination = ucontrol->value.integer.value[1];
-
- if (source >= hdsp->max_channels)
- addr = hdsp_playback_to_output_key(hdsp,source-hdsp->max_channels, destination);
- else
- addr = hdsp_input_to_output_key(hdsp,source, destination);
-
- gain = ucontrol->value.integer.value[2];
-
- spin_lock_irq(&hdsp->lock);
- change = gain != hdsp_read_gain(hdsp, addr);
- if (change)
- hdsp_write_gain(hdsp, addr, gain);
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-#define HDSP_WC_SYNC_CHECK(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
- .info = snd_hdsp_info_sync_check, \
- .get = snd_hdsp_get_wc_sync_check \
-}
-
-static int snd_hdsp_info_sync_check(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = {"No Lock", "Lock", "Sync" };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int hdsp_wc_sync_check(struct hdsp *hdsp)
-{
- int status2 = hdsp_read(hdsp, HDSP_status2Register);
- if (status2 & HDSP_wc_lock) {
- if (status2 & HDSP_wc_sync)
- return 2;
- else
- return 1;
- } else
- return 0;
- return 0;
-}
-
-static int snd_hdsp_get_wc_sync_check(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdsp_wc_sync_check(hdsp);
- return 0;
-}
-
-#define HDSP_SPDIF_SYNC_CHECK(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
- .info = snd_hdsp_info_sync_check, \
- .get = snd_hdsp_get_spdif_sync_check \
-}
-
-static int hdsp_spdif_sync_check(struct hdsp *hdsp)
-{
- int status = hdsp_read(hdsp, HDSP_statusRegister);
- if (status & HDSP_SPDIFErrorFlag)
- return 0;
- else {
- if (status & HDSP_SPDIFSync)
- return 2;
- else
- return 1;
- }
- return 0;
-}
-
-static int snd_hdsp_get_spdif_sync_check(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdsp_spdif_sync_check(hdsp);
- return 0;
-}
-
-#define HDSP_ADATSYNC_SYNC_CHECK(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
- .info = snd_hdsp_info_sync_check, \
- .get = snd_hdsp_get_adatsync_sync_check \
-}
-
-static int hdsp_adatsync_sync_check(struct hdsp *hdsp)
-{
- int status = hdsp_read(hdsp, HDSP_statusRegister);
- if (status & HDSP_TimecodeLock) {
- if (status & HDSP_TimecodeSync)
- return 2;
- else
- return 1;
- } else
- return 0;
-}
-
-static int snd_hdsp_get_adatsync_sync_check(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdsp_adatsync_sync_check(hdsp);
- return 0;
-}
-
-#define HDSP_ADAT_SYNC_CHECK \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
- .info = snd_hdsp_info_sync_check, \
- .get = snd_hdsp_get_adat_sync_check \
-}
-
-static int hdsp_adat_sync_check(struct hdsp *hdsp, int idx)
-{
- int status = hdsp_read(hdsp, HDSP_statusRegister);
-
- if (status & (HDSP_Lock0>>idx)) {
- if (status & (HDSP_Sync0>>idx))
- return 2;
- else
- return 1;
- } else
- return 0;
-}
-
-static int snd_hdsp_get_adat_sync_check(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- int offset;
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- offset = ucontrol->id.index - 1;
- snd_BUG_ON(offset < 0);
-
- switch (hdsp->io_type) {
- case Digiface:
- case H9652:
- if (offset >= 3)
- return -EINVAL;
- break;
- case Multiface:
- case H9632:
- if (offset >= 1)
- return -EINVAL;
- break;
- default:
- return -EIO;
- }
-
- ucontrol->value.enumerated.item[0] = hdsp_adat_sync_check(hdsp, offset);
- return 0;
-}
-
-#define HDSP_DDS_OFFSET(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdsp_info_dds_offset, \
- .get = snd_hdsp_get_dds_offset, \
- .put = snd_hdsp_put_dds_offset \
-}
-
-static int hdsp_dds_offset(struct hdsp *hdsp)
-{
- u64 n;
- unsigned int dds_value = hdsp->dds_value;
- int system_sample_rate = hdsp->system_sample_rate;
-
- if (!dds_value)
- return 0;
-
- n = DDS_NUMERATOR;
- /*
- * dds_value = n / rate
- * rate = n / dds_value
- */
- n = div_u64(n, dds_value);
- if (system_sample_rate >= 112000)
- n *= 4;
- else if (system_sample_rate >= 56000)
- n *= 2;
- return ((int)n) - system_sample_rate;
-}
-
-static int hdsp_set_dds_offset(struct hdsp *hdsp, int offset_hz)
-{
- int rate = hdsp->system_sample_rate + offset_hz;
- hdsp_set_dds_value(hdsp, rate);
- return 0;
-}
-
-static int snd_hdsp_info_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = -5000;
- uinfo->value.integer.max = 5000;
- return 0;
-}
-
-static int snd_hdsp_get_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdsp_dds_offset(hdsp);
- return 0;
-}
-
-static int snd_hdsp_put_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- int val;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
- val = ucontrol->value.enumerated.item[0];
- spin_lock_irq(&hdsp->lock);
- if (val != hdsp_dds_offset(hdsp))
- change = (hdsp_set_dds_offset(hdsp, val) == 0) ? 1 : 0;
- else
- change = 0;
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_hdsp_9632_controls[] = {
-HDSP_DA_GAIN("DA Gain", 0),
-HDSP_AD_GAIN("AD Gain", 0),
-HDSP_PHONE_GAIN("Phones Gain", 0),
-HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0),
-HDSP_DDS_OFFSET("DDS Sample Rate Offset", 0)
-};
-
-static struct snd_kcontrol_new snd_hdsp_controls[] = {
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
- .info = snd_hdsp_control_spdif_info,
- .get = snd_hdsp_control_spdif_get,
- .put = snd_hdsp_control_spdif_put,
-},
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
- .info = snd_hdsp_control_spdif_stream_info,
- .get = snd_hdsp_control_spdif_stream_get,
- .put = snd_hdsp_control_spdif_stream_put,
-},
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
- .info = snd_hdsp_control_spdif_mask_info,
- .get = snd_hdsp_control_spdif_mask_get,
- .private_value = IEC958_AES0_NONAUDIO |
- IEC958_AES0_PROFESSIONAL |
- IEC958_AES0_CON_EMPHASIS,
-},
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
- .info = snd_hdsp_control_spdif_mask_info,
- .get = snd_hdsp_control_spdif_mask_get,
- .private_value = IEC958_AES0_NONAUDIO |
- IEC958_AES0_PROFESSIONAL |
- IEC958_AES0_PRO_EMPHASIS,
-},
-HDSP_MIXER("Mixer", 0),
-HDSP_SPDIF_IN("IEC958 Input Connector", 0),
-HDSP_SPDIF_OUT("IEC958 Output also on ADAT1", 0),
-HDSP_SPDIF_PROFESSIONAL("IEC958 Professional Bit", 0),
-HDSP_SPDIF_EMPHASIS("IEC958 Emphasis Bit", 0),
-HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0),
-/* 'Sample Clock Source' complies with the alsa control naming scheme */
-HDSP_CLOCK_SOURCE("Sample Clock Source", 0),
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Sample Clock Source Locking",
- .info = snd_hdsp_info_clock_source_lock,
- .get = snd_hdsp_get_clock_source_lock,
- .put = snd_hdsp_put_clock_source_lock,
-},
-HDSP_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
-HDSP_PREF_SYNC_REF("Preferred Sync Reference", 0),
-HDSP_AUTOSYNC_REF("AutoSync Reference", 0),
-HDSP_SPDIF_SAMPLE_RATE("SPDIF Sample Rate", 0),
-HDSP_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
-/* 'External Rate' complies with the alsa control naming scheme */
-HDSP_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
-HDSP_WC_SYNC_CHECK("Word Clock Lock Status", 0),
-HDSP_SPDIF_SYNC_CHECK("SPDIF Lock Status", 0),
-HDSP_ADATSYNC_SYNC_CHECK("ADAT Sync Lock Status", 0),
-HDSP_LINE_OUT("Line Out", 0),
-HDSP_PRECISE_POINTER("Precise Pointer", 0),
-HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0),
-};
-
-
-static int hdsp_rpm_input12(struct hdsp *hdsp)
-{
- switch (hdsp->control_register & HDSP_RPM_Inp12) {
- case HDSP_RPM_Inp12_Phon_6dB:
- return 0;
- case HDSP_RPM_Inp12_Phon_n6dB:
- return 2;
- case HDSP_RPM_Inp12_Line_0dB:
- return 3;
- case HDSP_RPM_Inp12_Line_n6dB:
- return 4;
- }
- return 1;
-}
-
-
-static int snd_hdsp_get_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdsp_rpm_input12(hdsp);
- return 0;
-}
-
-
-static int hdsp_set_rpm_input12(struct hdsp *hdsp, int mode)
-{
- hdsp->control_register &= ~HDSP_RPM_Inp12;
- switch (mode) {
- case 0:
- hdsp->control_register |= HDSP_RPM_Inp12_Phon_6dB;
- break;
- case 1:
- break;
- case 2:
- hdsp->control_register |= HDSP_RPM_Inp12_Phon_n6dB;
- break;
- case 3:
- hdsp->control_register |= HDSP_RPM_Inp12_Line_0dB;
- break;
- case 4:
- hdsp->control_register |= HDSP_RPM_Inp12_Line_n6dB;
- break;
- default:
- return -1;
- }
-
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- return 0;
-}
-
-
-static int snd_hdsp_put_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- int val;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
- val = ucontrol->value.enumerated.item[0];
- if (val < 0)
- val = 0;
- if (val > 4)
- val = 4;
- spin_lock_irq(&hdsp->lock);
- if (val != hdsp_rpm_input12(hdsp))
- change = (hdsp_set_rpm_input12(hdsp, val) == 0) ? 1 : 0;
- else
- change = 0;
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-
-static int snd_hdsp_info_rpm_input(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = {"Phono +6dB", "Phono 0dB", "Phono -6dB", "Line 0dB", "Line -6dB"};
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 5;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-
-static int hdsp_rpm_input34(struct hdsp *hdsp)
-{
- switch (hdsp->control_register & HDSP_RPM_Inp34) {
- case HDSP_RPM_Inp34_Phon_6dB:
- return 0;
- case HDSP_RPM_Inp34_Phon_n6dB:
- return 2;
- case HDSP_RPM_Inp34_Line_0dB:
- return 3;
- case HDSP_RPM_Inp34_Line_n6dB:
- return 4;
- }
- return 1;
-}
-
-
-static int snd_hdsp_get_rpm_input34(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdsp_rpm_input34(hdsp);
- return 0;
-}
-
-
-static int hdsp_set_rpm_input34(struct hdsp *hdsp, int mode)
-{
- hdsp->control_register &= ~HDSP_RPM_Inp34;
- switch (mode) {
- case 0:
- hdsp->control_register |= HDSP_RPM_Inp34_Phon_6dB;
- break;
- case 1:
- break;
- case 2:
- hdsp->control_register |= HDSP_RPM_Inp34_Phon_n6dB;
- break;
- case 3:
- hdsp->control_register |= HDSP_RPM_Inp34_Line_0dB;
- break;
- case 4:
- hdsp->control_register |= HDSP_RPM_Inp34_Line_n6dB;
- break;
- default:
- return -1;
- }
-
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- return 0;
-}
-
-
-static int snd_hdsp_put_rpm_input34(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- int val;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
- val = ucontrol->value.enumerated.item[0];
- if (val < 0)
- val = 0;
- if (val > 4)
- val = 4;
- spin_lock_irq(&hdsp->lock);
- if (val != hdsp_rpm_input34(hdsp))
- change = (hdsp_set_rpm_input34(hdsp, val) == 0) ? 1 : 0;
- else
- change = 0;
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-
-/* RPM Bypass switch */
-static int hdsp_rpm_bypass(struct hdsp *hdsp)
-{
- return (hdsp->control_register & HDSP_RPM_Bypass) ? 1 : 0;
-}
-
-
-static int snd_hdsp_get_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = hdsp_rpm_bypass(hdsp);
- return 0;
-}
-
-
-static int hdsp_set_rpm_bypass(struct hdsp *hdsp, int on)
-{
- if (on)
- hdsp->control_register |= HDSP_RPM_Bypass;
- else
- hdsp->control_register &= ~HDSP_RPM_Bypass;
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- return 0;
-}
-
-
-static int snd_hdsp_put_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdsp->lock);
- change = (int)val != hdsp_rpm_bypass(hdsp);
- hdsp_set_rpm_bypass(hdsp, val);
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-
-static int snd_hdsp_info_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = {"On", "Off"};
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-
-/* RPM Disconnect switch */
-static int hdsp_rpm_disconnect(struct hdsp *hdsp)
-{
- return (hdsp->control_register & HDSP_RPM_Disconnect) ? 1 : 0;
-}
-
-
-static int snd_hdsp_get_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = hdsp_rpm_disconnect(hdsp);
- return 0;
-}
-
-
-static int hdsp_set_rpm_disconnect(struct hdsp *hdsp, int on)
-{
- if (on)
- hdsp->control_register |= HDSP_RPM_Disconnect;
- else
- hdsp->control_register &= ~HDSP_RPM_Disconnect;
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- return 0;
-}
-
-
-static int snd_hdsp_put_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdsp->lock);
- change = (int)val != hdsp_rpm_disconnect(hdsp);
- hdsp_set_rpm_disconnect(hdsp, val);
- spin_unlock_irq(&hdsp->lock);
- return change;
-}
-
-static int snd_hdsp_info_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = {"On", "Off"};
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static struct snd_kcontrol_new snd_hdsp_rpm_controls[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "RPM Bypass",
- .get = snd_hdsp_get_rpm_bypass,
- .put = snd_hdsp_put_rpm_bypass,
- .info = snd_hdsp_info_rpm_bypass
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "RPM Disconnect",
- .get = snd_hdsp_get_rpm_disconnect,
- .put = snd_hdsp_put_rpm_disconnect,
- .info = snd_hdsp_info_rpm_disconnect
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input 1/2",
- .get = snd_hdsp_get_rpm_input12,
- .put = snd_hdsp_put_rpm_input12,
- .info = snd_hdsp_info_rpm_input
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input 3/4",
- .get = snd_hdsp_get_rpm_input34,
- .put = snd_hdsp_put_rpm_input34,
- .info = snd_hdsp_info_rpm_input
- },
- HDSP_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
- HDSP_MIXER("Mixer", 0)
-};
-
-static struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0);
-static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK;
-
-static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp)
-{
- unsigned int idx;
- int err;
- struct snd_kcontrol *kctl;
-
- if (hdsp->io_type == RPM) {
- /* RPM Bypass, Disconnect and Input switches */
- for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_rpm_controls); idx++) {
- err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_rpm_controls[idx], hdsp));
- if (err < 0)
- return err;
- }
- return 0;
- }
-
- for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0)
- return err;
- if (idx == 1) /* IEC958 (S/PDIF) Stream */
- hdsp->spdif_ctl = kctl;
- }
-
- /* ADAT SyncCheck status */
- snd_hdsp_adat_sync_check.name = "ADAT Lock Status";
- snd_hdsp_adat_sync_check.index = 1;
- if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp))))
- return err;
- if (hdsp->io_type == Digiface || hdsp->io_type == H9652) {
- for (idx = 1; idx < 3; ++idx) {
- snd_hdsp_adat_sync_check.index = idx+1;
- if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp))))
- return err;
- }
- }
-
- /* DA, AD and Phone gain and XLR breakout cable controls for H9632 cards */
- if (hdsp->io_type == H9632) {
- for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_9632_controls); idx++) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_9632_controls[idx], hdsp))) < 0)
- return err;
- }
- }
-
- /* AEB control for H96xx card */
- if (hdsp->io_type == H9632 || hdsp->io_type == H9652) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_96xx_aeb, hdsp))) < 0)
- return err;
- }
-
- return 0;
-}
-
-/*------------------------------------------------------------
- /proc interface
- ------------------------------------------------------------*/
-
-static void
-snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- struct hdsp *hdsp = entry->private_data;
- unsigned int status;
- unsigned int status2;
- char *pref_sync_ref;
- char *autosync_ref;
- char *system_clock_mode;
- char *clock_source;
- int x;
-
- status = hdsp_read(hdsp, HDSP_statusRegister);
- status2 = hdsp_read(hdsp, HDSP_status2Register);
-
- snd_iprintf(buffer, "%s (Card #%d)\n", hdsp->card_name,
- hdsp->card->number + 1);
- snd_iprintf(buffer, "Buffers: capture %p playback %p\n",
- hdsp->capture_buffer, hdsp->playback_buffer);
- snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
- hdsp->irq, hdsp->port, (unsigned long)hdsp->iobase);
- snd_iprintf(buffer, "Control register: 0x%x\n", hdsp->control_register);
- snd_iprintf(buffer, "Control2 register: 0x%x\n",
- hdsp->control2_register);
- snd_iprintf(buffer, "Status register: 0x%x\n", status);
- snd_iprintf(buffer, "Status2 register: 0x%x\n", status2);
-
- if (hdsp_check_for_iobox(hdsp)) {
- snd_iprintf(buffer, "No I/O box connected.\n"
- "Please connect one and upload firmware.\n");
- return;
- }
-
- if (hdsp_check_for_firmware(hdsp, 0)) {
- if (hdsp->state & HDSP_FirmwareCached) {
- if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
- snd_iprintf(buffer, "Firmware loading from "
- "cache failed, "
- "please upload manually.\n");
- return;
- }
- } else {
- int err = -EINVAL;
-#ifdef HDSP_FW_LOADER
- err = hdsp_request_fw_loader(hdsp);
-#endif
- if (err < 0) {
- snd_iprintf(buffer,
- "No firmware loaded nor cached, "
- "please upload firmware.\n");
- return;
- }
- }
- }
-
- snd_iprintf(buffer, "FIFO status: %d\n", hdsp_read(hdsp, HDSP_fifoStatus) & 0xff);
- snd_iprintf(buffer, "MIDI1 Output status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusOut0));
- snd_iprintf(buffer, "MIDI1 Input status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusIn0));
- snd_iprintf(buffer, "MIDI2 Output status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusOut1));
- snd_iprintf(buffer, "MIDI2 Input status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusIn1));
- snd_iprintf(buffer, "Use Midi Tasklet: %s\n", hdsp->use_midi_tasklet ? "on" : "off");
-
- snd_iprintf(buffer, "\n");
-
- x = 1 << (6 + hdsp_decode_latency(hdsp->control_register & HDSP_LatencyMask));
-
- snd_iprintf(buffer, "Buffer Size (Latency): %d samples (2 periods of %lu bytes)\n", x, (unsigned long) hdsp->period_bytes);
- snd_iprintf(buffer, "Hardware pointer (frames): %ld\n", hdsp_hw_pointer(hdsp));
- snd_iprintf(buffer, "Precise pointer: %s\n", hdsp->precise_ptr ? "on" : "off");
- snd_iprintf(buffer, "Line out: %s\n", (hdsp->control_register & HDSP_LineOut) ? "on" : "off");
-
- snd_iprintf(buffer, "Firmware version: %d\n", (status2&HDSP_version0)|(status2&HDSP_version1)<<1|(status2&HDSP_version2)<<2);
-
- snd_iprintf(buffer, "\n");
-
- switch (hdsp_clock_source(hdsp)) {
- case HDSP_CLOCK_SOURCE_AUTOSYNC:
- clock_source = "AutoSync";
- break;
- case HDSP_CLOCK_SOURCE_INTERNAL_32KHZ:
- clock_source = "Internal 32 kHz";
- break;
- case HDSP_CLOCK_SOURCE_INTERNAL_44_1KHZ:
- clock_source = "Internal 44.1 kHz";
- break;
- case HDSP_CLOCK_SOURCE_INTERNAL_48KHZ:
- clock_source = "Internal 48 kHz";
- break;
- case HDSP_CLOCK_SOURCE_INTERNAL_64KHZ:
- clock_source = "Internal 64 kHz";
- break;
- case HDSP_CLOCK_SOURCE_INTERNAL_88_2KHZ:
- clock_source = "Internal 88.2 kHz";
- break;
- case HDSP_CLOCK_SOURCE_INTERNAL_96KHZ:
- clock_source = "Internal 96 kHz";
- break;
- case HDSP_CLOCK_SOURCE_INTERNAL_128KHZ:
- clock_source = "Internal 128 kHz";
- break;
- case HDSP_CLOCK_SOURCE_INTERNAL_176_4KHZ:
- clock_source = "Internal 176.4 kHz";
- break;
- case HDSP_CLOCK_SOURCE_INTERNAL_192KHZ:
- clock_source = "Internal 192 kHz";
- break;
- default:
- clock_source = "Error";
- }
- snd_iprintf (buffer, "Sample Clock Source: %s\n", clock_source);
-
- if (hdsp_system_clock_mode(hdsp))
- system_clock_mode = "Slave";
- else
- system_clock_mode = "Master";
-
- switch (hdsp_pref_sync_ref (hdsp)) {
- case HDSP_SYNC_FROM_WORD:
- pref_sync_ref = "Word Clock";
- break;
- case HDSP_SYNC_FROM_ADAT_SYNC:
- pref_sync_ref = "ADAT Sync";
- break;
- case HDSP_SYNC_FROM_SPDIF:
- pref_sync_ref = "SPDIF";
- break;
- case HDSP_SYNC_FROM_ADAT1:
- pref_sync_ref = "ADAT1";
- break;
- case HDSP_SYNC_FROM_ADAT2:
- pref_sync_ref = "ADAT2";
- break;
- case HDSP_SYNC_FROM_ADAT3:
- pref_sync_ref = "ADAT3";
- break;
- default:
- pref_sync_ref = "Word Clock";
- break;
- }
- snd_iprintf (buffer, "Preferred Sync Reference: %s\n", pref_sync_ref);
-
- switch (hdsp_autosync_ref (hdsp)) {
- case HDSP_AUTOSYNC_FROM_WORD:
- autosync_ref = "Word Clock";
- break;
- case HDSP_AUTOSYNC_FROM_ADAT_SYNC:
- autosync_ref = "ADAT Sync";
- break;
- case HDSP_AUTOSYNC_FROM_SPDIF:
- autosync_ref = "SPDIF";
- break;
- case HDSP_AUTOSYNC_FROM_NONE:
- autosync_ref = "None";
- break;
- case HDSP_AUTOSYNC_FROM_ADAT1:
- autosync_ref = "ADAT1";
- break;
- case HDSP_AUTOSYNC_FROM_ADAT2:
- autosync_ref = "ADAT2";
- break;
- case HDSP_AUTOSYNC_FROM_ADAT3:
- autosync_ref = "ADAT3";
- break;
- default:
- autosync_ref = "---";
- break;
- }
- snd_iprintf (buffer, "AutoSync Reference: %s\n", autosync_ref);
-
- snd_iprintf (buffer, "AutoSync Frequency: %d\n", hdsp_external_sample_rate(hdsp));
-
- snd_iprintf (buffer, "System Clock Mode: %s\n", system_clock_mode);
-
- snd_iprintf (buffer, "System Clock Frequency: %d\n", hdsp->system_sample_rate);
- snd_iprintf (buffer, "System Clock Locked: %s\n", hdsp->clock_source_locked ? "Yes" : "No");
-
- snd_iprintf(buffer, "\n");
-
- if (hdsp->io_type != RPM) {
- switch (hdsp_spdif_in(hdsp)) {
- case HDSP_SPDIFIN_OPTICAL:
- snd_iprintf(buffer, "IEC958 input: Optical\n");
- break;
- case HDSP_SPDIFIN_COAXIAL:
- snd_iprintf(buffer, "IEC958 input: Coaxial\n");
- break;
- case HDSP_SPDIFIN_INTERNAL:
- snd_iprintf(buffer, "IEC958 input: Internal\n");
- break;
- case HDSP_SPDIFIN_AES:
- snd_iprintf(buffer, "IEC958 input: AES\n");
- break;
- default:
- snd_iprintf(buffer, "IEC958 input: ???\n");
- break;
- }
- }
-
- if (RPM == hdsp->io_type) {
- if (hdsp->control_register & HDSP_RPM_Bypass)
- snd_iprintf(buffer, "RPM Bypass: disabled\n");
- else
- snd_iprintf(buffer, "RPM Bypass: enabled\n");
- if (hdsp->control_register & HDSP_RPM_Disconnect)
- snd_iprintf(buffer, "RPM disconnected\n");
- else
- snd_iprintf(buffer, "RPM connected\n");
-
- switch (hdsp->control_register & HDSP_RPM_Inp12) {
- case HDSP_RPM_Inp12_Phon_6dB:
- snd_iprintf(buffer, "Input 1/2: Phono, 6dB\n");
- break;
- case HDSP_RPM_Inp12_Phon_0dB:
- snd_iprintf(buffer, "Input 1/2: Phono, 0dB\n");
- break;
- case HDSP_RPM_Inp12_Phon_n6dB:
- snd_iprintf(buffer, "Input 1/2: Phono, -6dB\n");
- break;
- case HDSP_RPM_Inp12_Line_0dB:
- snd_iprintf(buffer, "Input 1/2: Line, 0dB\n");
- break;
- case HDSP_RPM_Inp12_Line_n6dB:
- snd_iprintf(buffer, "Input 1/2: Line, -6dB\n");
- break;
- default:
- snd_iprintf(buffer, "Input 1/2: ???\n");
- }
-
- switch (hdsp->control_register & HDSP_RPM_Inp34) {
- case HDSP_RPM_Inp34_Phon_6dB:
- snd_iprintf(buffer, "Input 3/4: Phono, 6dB\n");
- break;
- case HDSP_RPM_Inp34_Phon_0dB:
- snd_iprintf(buffer, "Input 3/4: Phono, 0dB\n");
- break;
- case HDSP_RPM_Inp34_Phon_n6dB:
- snd_iprintf(buffer, "Input 3/4: Phono, -6dB\n");
- break;
- case HDSP_RPM_Inp34_Line_0dB:
- snd_iprintf(buffer, "Input 3/4: Line, 0dB\n");
- break;
- case HDSP_RPM_Inp34_Line_n6dB:
- snd_iprintf(buffer, "Input 3/4: Line, -6dB\n");
- break;
- default:
- snd_iprintf(buffer, "Input 3/4: ???\n");
- }
-
- } else {
- if (hdsp->control_register & HDSP_SPDIFOpticalOut)
- snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n");
- else
- snd_iprintf(buffer, "IEC958 output: Coaxial only\n");
-
- if (hdsp->control_register & HDSP_SPDIFProfessional)
- snd_iprintf(buffer, "IEC958 quality: Professional\n");
- else
- snd_iprintf(buffer, "IEC958 quality: Consumer\n");
-
- if (hdsp->control_register & HDSP_SPDIFEmphasis)
- snd_iprintf(buffer, "IEC958 emphasis: on\n");
- else
- snd_iprintf(buffer, "IEC958 emphasis: off\n");
-
- if (hdsp->control_register & HDSP_SPDIFNonAudio)
- snd_iprintf(buffer, "IEC958 NonAudio: on\n");
- else
- snd_iprintf(buffer, "IEC958 NonAudio: off\n");
- x = hdsp_spdif_sample_rate(hdsp);
- if (x != 0)
- snd_iprintf(buffer, "IEC958 sample rate: %d\n", x);
- else
- snd_iprintf(buffer, "IEC958 sample rate: Error flag set\n");
- }
- snd_iprintf(buffer, "\n");
-
- /* Sync Check */
- x = status & HDSP_Sync0;
- if (status & HDSP_Lock0)
- snd_iprintf(buffer, "ADAT1: %s\n", x ? "Sync" : "Lock");
- else
- snd_iprintf(buffer, "ADAT1: No Lock\n");
-
- switch (hdsp->io_type) {
- case Digiface:
- case H9652:
- x = status & HDSP_Sync1;
- if (status & HDSP_Lock1)
- snd_iprintf(buffer, "ADAT2: %s\n", x ? "Sync" : "Lock");
- else
- snd_iprintf(buffer, "ADAT2: No Lock\n");
- x = status & HDSP_Sync2;
- if (status & HDSP_Lock2)
- snd_iprintf(buffer, "ADAT3: %s\n", x ? "Sync" : "Lock");
- else
- snd_iprintf(buffer, "ADAT3: No Lock\n");
- break;
- default:
- /* relax */
- break;
- }
-
- x = status & HDSP_SPDIFSync;
- if (status & HDSP_SPDIFErrorFlag)
- snd_iprintf (buffer, "SPDIF: No Lock\n");
- else
- snd_iprintf (buffer, "SPDIF: %s\n", x ? "Sync" : "Lock");
-
- x = status2 & HDSP_wc_sync;
- if (status2 & HDSP_wc_lock)
- snd_iprintf (buffer, "Word Clock: %s\n", x ? "Sync" : "Lock");
- else
- snd_iprintf (buffer, "Word Clock: No Lock\n");
-
- x = status & HDSP_TimecodeSync;
- if (status & HDSP_TimecodeLock)
- snd_iprintf(buffer, "ADAT Sync: %s\n", x ? "Sync" : "Lock");
- else
- snd_iprintf(buffer, "ADAT Sync: No Lock\n");
-
- snd_iprintf(buffer, "\n");
-
- /* Informations about H9632 specific controls */
- if (hdsp->io_type == H9632) {
- char *tmp;
-
- switch (hdsp_ad_gain(hdsp)) {
- case 0:
- tmp = "-10 dBV";
- break;
- case 1:
- tmp = "+4 dBu";
- break;
- default:
- tmp = "Lo Gain";
- break;
- }
- snd_iprintf(buffer, "AD Gain : %s\n", tmp);
-
- switch (hdsp_da_gain(hdsp)) {
- case 0:
- tmp = "Hi Gain";
- break;
- case 1:
- tmp = "+4 dBu";
- break;
- default:
- tmp = "-10 dBV";
- break;
- }
- snd_iprintf(buffer, "DA Gain : %s\n", tmp);
-
- switch (hdsp_phone_gain(hdsp)) {
- case 0:
- tmp = "0 dB";
- break;
- case 1:
- tmp = "-6 dB";
- break;
- default:
- tmp = "-12 dB";
- break;
- }
- snd_iprintf(buffer, "Phones Gain : %s\n", tmp);
-
- snd_iprintf(buffer, "XLR Breakout Cable : %s\n", hdsp_xlr_breakout_cable(hdsp) ? "yes" : "no");
-
- if (hdsp->control_register & HDSP_AnalogExtensionBoard)
- snd_iprintf(buffer, "AEB : on (ADAT1 internal)\n");
- else
- snd_iprintf(buffer, "AEB : off (ADAT1 external)\n");
- snd_iprintf(buffer, "\n");
- }
-
-}
-
-static void snd_hdsp_proc_init(struct hdsp *hdsp)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(hdsp->card, "hdsp", &entry))
- snd_info_set_text_ops(entry, hdsp, snd_hdsp_proc_read);
-}
-
-static void snd_hdsp_free_buffers(struct hdsp *hdsp)
-{
- snd_hammerfall_free_buffer(&hdsp->capture_dma_buf, hdsp->pci);
- snd_hammerfall_free_buffer(&hdsp->playback_dma_buf, hdsp->pci);
-}
-
-static int __devinit snd_hdsp_initialize_memory(struct hdsp *hdsp)
-{
- unsigned long pb_bus, cb_bus;
-
- if (snd_hammerfall_get_buffer(hdsp->pci, &hdsp->capture_dma_buf, HDSP_DMA_AREA_BYTES) < 0 ||
- snd_hammerfall_get_buffer(hdsp->pci, &hdsp->playback_dma_buf, HDSP_DMA_AREA_BYTES) < 0) {
- if (hdsp->capture_dma_buf.area)
- snd_dma_free_pages(&hdsp->capture_dma_buf);
- printk(KERN_ERR "%s: no buffers available\n", hdsp->card_name);
- return -ENOMEM;
- }
-
- /* Align to bus-space 64K boundary */
-
- cb_bus = ALIGN(hdsp->capture_dma_buf.addr, 0x10000ul);
- pb_bus = ALIGN(hdsp->playback_dma_buf.addr, 0x10000ul);
-
- /* Tell the card where it is */
-
- hdsp_write(hdsp, HDSP_inputBufferAddress, cb_bus);
- hdsp_write(hdsp, HDSP_outputBufferAddress, pb_bus);
-
- hdsp->capture_buffer = hdsp->capture_dma_buf.area + (cb_bus - hdsp->capture_dma_buf.addr);
- hdsp->playback_buffer = hdsp->playback_dma_buf.area + (pb_bus - hdsp->playback_dma_buf.addr);
-
- return 0;
-}
-
-static int snd_hdsp_set_defaults(struct hdsp *hdsp)
-{
- unsigned int i;
-
- /* ASSUMPTION: hdsp->lock is either held, or
- there is no need to hold it (e.g. during module
- initialization).
- */
-
- /* set defaults:
-
- SPDIF Input via Coax
- Master clock mode
- maximum latency (7 => 2^7 = 8192 samples, 64Kbyte buffer,
- which implies 2 4096 sample, 32Kbyte periods).
- Enable line out.
- */
-
- hdsp->control_register = HDSP_ClockModeMaster |
- HDSP_SPDIFInputCoaxial |
- hdsp_encode_latency(7) |
- HDSP_LineOut;
-
-
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
-
-#ifdef SNDRV_BIG_ENDIAN
- hdsp->control2_register = HDSP_BIGENDIAN_MODE;
-#else
- hdsp->control2_register = 0;
-#endif
- if (hdsp->io_type == H9652)
- snd_hdsp_9652_enable_mixer (hdsp);
- else
- hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
-
- hdsp_reset_hw_pointer(hdsp);
- hdsp_compute_period_size(hdsp);
-
- /* silence everything */
-
- for (i = 0; i < HDSP_MATRIX_MIXER_SIZE; ++i)
- hdsp->mixer_matrix[i] = MINUS_INFINITY_GAIN;
-
- for (i = 0; i < ((hdsp->io_type == H9652 || hdsp->io_type == H9632) ? 1352 : HDSP_MATRIX_MIXER_SIZE); ++i) {
- if (hdsp_write_gain (hdsp, i, MINUS_INFINITY_GAIN))
- return -EIO;
- }
-
- /* H9632 specific defaults */
- if (hdsp->io_type == H9632) {
- hdsp->control_register |= (HDSP_DAGainPlus4dBu | HDSP_ADGainPlus4dBu | HDSP_PhoneGain0dB);
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- }
-
- /* set a default rate so that the channel map is set up.
- */
-
- hdsp_set_rate(hdsp, 48000, 1);
-
- return 0;
-}
-
-static void hdsp_midi_tasklet(unsigned long arg)
-{
- struct hdsp *hdsp = (struct hdsp *)arg;
-
- if (hdsp->midi[0].pending)
- snd_hdsp_midi_input_read (&hdsp->midi[0]);
- if (hdsp->midi[1].pending)
- snd_hdsp_midi_input_read (&hdsp->midi[1]);
-}
-
-static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id)
-{
- struct hdsp *hdsp = (struct hdsp *) dev_id;
- unsigned int status;
- int audio;
- int midi0;
- int midi1;
- unsigned int midi0status;
- unsigned int midi1status;
- int schedule = 0;
-
- status = hdsp_read(hdsp, HDSP_statusRegister);
-
- audio = status & HDSP_audioIRQPending;
- midi0 = status & HDSP_midi0IRQPending;
- midi1 = status & HDSP_midi1IRQPending;
-
- if (!audio && !midi0 && !midi1)
- return IRQ_NONE;
-
- hdsp_write(hdsp, HDSP_interruptConfirmation, 0);
-
- midi0status = hdsp_read (hdsp, HDSP_midiStatusIn0) & 0xff;
- midi1status = hdsp_read (hdsp, HDSP_midiStatusIn1) & 0xff;
-
- if (!(hdsp->state & HDSP_InitializationComplete))
- return IRQ_HANDLED;
-
- if (audio) {
- if (hdsp->capture_substream)
- snd_pcm_period_elapsed(hdsp->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
-
- if (hdsp->playback_substream)
- snd_pcm_period_elapsed(hdsp->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream);
- }
-
- if (midi0 && midi0status) {
- if (hdsp->use_midi_tasklet) {
- /* we disable interrupts for this input until processing is done */
- hdsp->control_register &= ~HDSP_Midi0InterruptEnable;
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- hdsp->midi[0].pending = 1;
- schedule = 1;
- } else {
- snd_hdsp_midi_input_read (&hdsp->midi[0]);
- }
- }
- if (hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632 && midi1 && midi1status) {
- if (hdsp->use_midi_tasklet) {
- /* we disable interrupts for this input until processing is done */
- hdsp->control_register &= ~HDSP_Midi1InterruptEnable;
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
- hdsp->midi[1].pending = 1;
- schedule = 1;
- } else {
- snd_hdsp_midi_input_read (&hdsp->midi[1]);
- }
- }
- if (hdsp->use_midi_tasklet && schedule)
- tasklet_schedule(&hdsp->midi_tasklet);
- return IRQ_HANDLED;
-}
-
-static snd_pcm_uframes_t snd_hdsp_hw_pointer(struct snd_pcm_substream *substream)
-{
- struct hdsp *hdsp = snd_pcm_substream_chip(substream);
- return hdsp_hw_pointer(hdsp);
-}
-
-static char *hdsp_channel_buffer_location(struct hdsp *hdsp,
- int stream,
- int channel)
-
-{
- int mapped_channel;
-
- if (snd_BUG_ON(channel < 0 || channel >= hdsp->max_channels))
- return NULL;
-
- if ((mapped_channel = hdsp->channel_map[channel]) < 0)
- return NULL;
-
- if (stream == SNDRV_PCM_STREAM_CAPTURE)
- return hdsp->capture_buffer + (mapped_channel * HDSP_CHANNEL_BUFFER_BYTES);
- else
- return hdsp->playback_buffer + (mapped_channel * HDSP_CHANNEL_BUFFER_BYTES);
-}
-
-static int snd_hdsp_playback_copy(struct snd_pcm_substream *substream, int channel,
- snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count)
-{
- struct hdsp *hdsp = snd_pcm_substream_chip(substream);
- char *channel_buf;
-
- if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES / 4))
- return -EINVAL;
-
- channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
- if (snd_BUG_ON(!channel_buf))
- return -EIO;
- if (copy_from_user(channel_buf + pos * 4, src, count * 4))
- return -EFAULT;
- return count;
-}
-
-static int snd_hdsp_capture_copy(struct snd_pcm_substream *substream, int channel,
- snd_pcm_uframes_t pos, void __user *dst, snd_pcm_uframes_t count)
-{
- struct hdsp *hdsp = snd_pcm_substream_chip(substream);
- char *channel_buf;
-
- if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES / 4))
- return -EINVAL;
-
- channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
- if (snd_BUG_ON(!channel_buf))
- return -EIO;
- if (copy_to_user(dst, channel_buf + pos * 4, count * 4))
- return -EFAULT;
- return count;
-}
-
-static int snd_hdsp_hw_silence(struct snd_pcm_substream *substream, int channel,
- snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
-{
- struct hdsp *hdsp = snd_pcm_substream_chip(substream);
- char *channel_buf;
-
- channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
- if (snd_BUG_ON(!channel_buf))
- return -EIO;
- memset(channel_buf + pos * 4, 0, count * 4);
- return count;
-}
-
-static int snd_hdsp_reset(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct hdsp *hdsp = snd_pcm_substream_chip(substream);
- struct snd_pcm_substream *other;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- other = hdsp->capture_substream;
- else
- other = hdsp->playback_substream;
- if (hdsp->running)
- runtime->status->hw_ptr = hdsp_hw_pointer(hdsp);
- else
- runtime->status->hw_ptr = 0;
- if (other) {
- struct snd_pcm_substream *s;
- struct snd_pcm_runtime *oruntime = other->runtime;
- snd_pcm_group_for_each_entry(s, substream) {
- if (s == other) {
- oruntime->status->hw_ptr = runtime->status->hw_ptr;
- break;
- }
- }
- }
- return 0;
-}
-
-static int snd_hdsp_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct hdsp *hdsp = snd_pcm_substream_chip(substream);
- int err;
- pid_t this_pid;
- pid_t other_pid;
-
- if (hdsp_check_for_iobox (hdsp))
- return -EIO;
-
- if (hdsp_check_for_firmware(hdsp, 1))
- return -EIO;
-
- spin_lock_irq(&hdsp->lock);
-
- if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- hdsp->control_register &= ~(HDSP_SPDIFProfessional | HDSP_SPDIFNonAudio | HDSP_SPDIFEmphasis);
- hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register |= hdsp->creg_spdif_stream);
- this_pid = hdsp->playback_pid;
- other_pid = hdsp->capture_pid;
- } else {
- this_pid = hdsp->capture_pid;
- other_pid = hdsp->playback_pid;
- }
-
- if ((other_pid > 0) && (this_pid != other_pid)) {
-
- /* The other stream is open, and not by the same
- task as this one. Make sure that the parameters
- that matter are the same.
- */
-
- if (params_rate(params) != hdsp->system_sample_rate) {
- spin_unlock_irq(&hdsp->lock);
- _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
- return -EBUSY;
- }
-
- if (params_period_size(params) != hdsp->period_bytes / 4) {
- spin_unlock_irq(&hdsp->lock);
- _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
- return -EBUSY;
- }
-
- /* We're fine. */
-
- spin_unlock_irq(&hdsp->lock);
- return 0;
-
- } else {
- spin_unlock_irq(&hdsp->lock);
- }
-
- /* how to make sure that the rate matches an externally-set one ?
- */
-
- spin_lock_irq(&hdsp->lock);
- if (! hdsp->clock_source_locked) {
- if ((err = hdsp_set_rate(hdsp, params_rate(params), 0)) < 0) {
- spin_unlock_irq(&hdsp->lock);
- _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
- return err;
- }
- }
- spin_unlock_irq(&hdsp->lock);
-
- if ((err = hdsp_set_interrupt_interval(hdsp, params_period_size(params))) < 0) {
- _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
- return err;
- }
-
- return 0;
-}
-
-static int snd_hdsp_channel_info(struct snd_pcm_substream *substream,
- struct snd_pcm_channel_info *info)
-{
- struct hdsp *hdsp = snd_pcm_substream_chip(substream);
- int mapped_channel;
-
- if (snd_BUG_ON(info->channel >= hdsp->max_channels))
- return -EINVAL;
-
- if ((mapped_channel = hdsp->channel_map[info->channel]) < 0)
- return -EINVAL;
-
- info->offset = mapped_channel * HDSP_CHANNEL_BUFFER_BYTES;
- info->first = 0;
- info->step = 32;
- return 0;
-}
-
-static int snd_hdsp_ioctl(struct snd_pcm_substream *substream,
- unsigned int cmd, void *arg)
-{
- switch (cmd) {
- case SNDRV_PCM_IOCTL1_RESET:
- return snd_hdsp_reset(substream);
- case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
- return snd_hdsp_channel_info(substream, arg);
- default:
- break;
- }
-
- return snd_pcm_lib_ioctl(substream, cmd, arg);
-}
-
-static int snd_hdsp_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct hdsp *hdsp = snd_pcm_substream_chip(substream);
- struct snd_pcm_substream *other;
- int running;
-
- if (hdsp_check_for_iobox (hdsp))
- return -EIO;
-
- if (hdsp_check_for_firmware(hdsp, 0)) /* no auto-loading in trigger */
- return -EIO;
-
- spin_lock(&hdsp->lock);
- running = hdsp->running;
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- running |= 1 << substream->stream;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- running &= ~(1 << substream->stream);
- break;
- default:
- snd_BUG();
- spin_unlock(&hdsp->lock);
- return -EINVAL;
- }
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- other = hdsp->capture_substream;
- else
- other = hdsp->playback_substream;
-
- if (other) {
- struct snd_pcm_substream *s;
- snd_pcm_group_for_each_entry(s, substream) {
- if (s == other) {
- snd_pcm_trigger_done(s, substream);
- if (cmd == SNDRV_PCM_TRIGGER_START)
- running |= 1 << s->stream;
- else
- running &= ~(1 << s->stream);
- goto _ok;
- }
- }
- if (cmd == SNDRV_PCM_TRIGGER_START) {
- if (!(running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) &&
- substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- hdsp_silence_playback(hdsp);
- } else {
- if (running &&
- substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- hdsp_silence_playback(hdsp);
- }
- } else {
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- hdsp_silence_playback(hdsp);
- }
- _ok:
- snd_pcm_trigger_done(substream, substream);
- if (!hdsp->running && running)
- hdsp_start_audio(hdsp);
- else if (hdsp->running && !running)
- hdsp_stop_audio(hdsp);
- hdsp->running = running;
- spin_unlock(&hdsp->lock);
-
- return 0;
-}
-
-static int snd_hdsp_prepare(struct snd_pcm_substream *substream)
-{
- struct hdsp *hdsp = snd_pcm_substream_chip(substream);
- int result = 0;
-
- if (hdsp_check_for_iobox (hdsp))
- return -EIO;
-
- if (hdsp_check_for_firmware(hdsp, 1))
- return -EIO;
-
- spin_lock_irq(&hdsp->lock);
- if (!hdsp->running)
- hdsp_reset_hw_pointer(hdsp);
- spin_unlock_irq(&hdsp->lock);
- return result;
-}
-
-static struct snd_pcm_hardware snd_hdsp_playback_subinfo =
-{
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_NONINTERLEAVED |
- SNDRV_PCM_INFO_SYNC_START |
- SNDRV_PCM_INFO_DOUBLE),
-#ifdef SNDRV_BIG_ENDIAN
- .formats = SNDRV_PCM_FMTBIT_S32_BE,
-#else
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
-#endif
- .rates = (SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_64000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000),
- .rate_min = 32000,
- .rate_max = 96000,
- .channels_min = 6,
- .channels_max = HDSP_MAX_CHANNELS,
- .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS,
- .period_bytes_min = (64 * 4) * 10,
- .period_bytes_max = (8192 * 4) * HDSP_MAX_CHANNELS,
- .periods_min = 2,
- .periods_max = 2,
- .fifo_size = 0
-};
-
-static struct snd_pcm_hardware snd_hdsp_capture_subinfo =
-{
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_NONINTERLEAVED |
- SNDRV_PCM_INFO_SYNC_START),
-#ifdef SNDRV_BIG_ENDIAN
- .formats = SNDRV_PCM_FMTBIT_S32_BE,
-#else
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
-#endif
- .rates = (SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_64000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000),
- .rate_min = 32000,
- .rate_max = 96000,
- .channels_min = 5,
- .channels_max = HDSP_MAX_CHANNELS,
- .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS,
- .period_bytes_min = (64 * 4) * 10,
- .period_bytes_max = (8192 * 4) * HDSP_MAX_CHANNELS,
- .periods_min = 2,
- .periods_max = 2,
- .fifo_size = 0
-};
-
-static unsigned int hdsp_period_sizes[] = { 64, 128, 256, 512, 1024, 2048, 4096, 8192 };
-
-static struct snd_pcm_hw_constraint_list hdsp_hw_constraints_period_sizes = {
- .count = ARRAY_SIZE(hdsp_period_sizes),
- .list = hdsp_period_sizes,
- .mask = 0
-};
-
-static unsigned int hdsp_9632_sample_rates[] = { 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 };
-
-static struct snd_pcm_hw_constraint_list hdsp_hw_constraints_9632_sample_rates = {
- .count = ARRAY_SIZE(hdsp_9632_sample_rates),
- .list = hdsp_9632_sample_rates,
- .mask = 0
-};
-
-static int snd_hdsp_hw_rule_in_channels(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct hdsp *hdsp = rule->private;
- struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- if (hdsp->io_type == H9632) {
- unsigned int list[3];
- list[0] = hdsp->qs_in_channels;
- list[1] = hdsp->ds_in_channels;
- list[2] = hdsp->ss_in_channels;
- return snd_interval_list(c, 3, list, 0);
- } else {
- unsigned int list[2];
- list[0] = hdsp->ds_in_channels;
- list[1] = hdsp->ss_in_channels;
- return snd_interval_list(c, 2, list, 0);
- }
-}
-
-static int snd_hdsp_hw_rule_out_channels(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- unsigned int list[3];
- struct hdsp *hdsp = rule->private;
- struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- if (hdsp->io_type == H9632) {
- list[0] = hdsp->qs_out_channels;
- list[1] = hdsp->ds_out_channels;
- list[2] = hdsp->ss_out_channels;
- return snd_interval_list(c, 3, list, 0);
- } else {
- list[0] = hdsp->ds_out_channels;
- list[1] = hdsp->ss_out_channels;
- }
- return snd_interval_list(c, 2, list, 0);
-}
-
-static int snd_hdsp_hw_rule_in_channels_rate(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct hdsp *hdsp = rule->private;
- struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
- if (r->min > 96000 && hdsp->io_type == H9632) {
- struct snd_interval t = {
- .min = hdsp->qs_in_channels,
- .max = hdsp->qs_in_channels,
- .integer = 1,
- };
- return snd_interval_refine(c, &t);
- } else if (r->min > 48000 && r->max <= 96000) {
- struct snd_interval t = {
- .min = hdsp->ds_in_channels,
- .max = hdsp->ds_in_channels,
- .integer = 1,
- };
- return snd_interval_refine(c, &t);
- } else if (r->max < 64000) {
- struct snd_interval t = {
- .min = hdsp->ss_in_channels,
- .max = hdsp->ss_in_channels,
- .integer = 1,
- };
- return snd_interval_refine(c, &t);
- }
- return 0;
-}
-
-static int snd_hdsp_hw_rule_out_channels_rate(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct hdsp *hdsp = rule->private;
- struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
- if (r->min > 96000 && hdsp->io_type == H9632) {
- struct snd_interval t = {
- .min = hdsp->qs_out_channels,
- .max = hdsp->qs_out_channels,
- .integer = 1,
- };
- return snd_interval_refine(c, &t);
- } else if (r->min > 48000 && r->max <= 96000) {
- struct snd_interval t = {
- .min = hdsp->ds_out_channels,
- .max = hdsp->ds_out_channels,
- .integer = 1,
- };
- return snd_interval_refine(c, &t);
- } else if (r->max < 64000) {
- struct snd_interval t = {
- .min = hdsp->ss_out_channels,
- .max = hdsp->ss_out_channels,
- .integer = 1,
- };
- return snd_interval_refine(c, &t);
- }
- return 0;
-}
-
-static int snd_hdsp_hw_rule_rate_out_channels(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct hdsp *hdsp = rule->private;
- struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
- if (c->min >= hdsp->ss_out_channels) {
- struct snd_interval t = {
- .min = 32000,
- .max = 48000,
- .integer = 1,
- };
- return snd_interval_refine(r, &t);
- } else if (c->max <= hdsp->qs_out_channels && hdsp->io_type == H9632) {
- struct snd_interval t = {
- .min = 128000,
- .max = 192000,
- .integer = 1,
- };
- return snd_interval_refine(r, &t);
- } else if (c->max <= hdsp->ds_out_channels) {
- struct snd_interval t = {
- .min = 64000,
- .max = 96000,
- .integer = 1,
- };
- return snd_interval_refine(r, &t);
- }
- return 0;
-}
-
-static int snd_hdsp_hw_rule_rate_in_channels(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct hdsp *hdsp = rule->private;
- struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
- if (c->min >= hdsp->ss_in_channels) {
- struct snd_interval t = {
- .min = 32000,
- .max = 48000,
- .integer = 1,
- };
- return snd_interval_refine(r, &t);
- } else if (c->max <= hdsp->qs_in_channels && hdsp->io_type == H9632) {
- struct snd_interval t = {
- .min = 128000,
- .max = 192000,
- .integer = 1,
- };
- return snd_interval_refine(r, &t);
- } else if (c->max <= hdsp->ds_in_channels) {
- struct snd_interval t = {
- .min = 64000,
- .max = 96000,
- .integer = 1,
- };
- return snd_interval_refine(r, &t);
- }
- return 0;
-}
-
-static int snd_hdsp_playback_open(struct snd_pcm_substream *substream)
-{
- struct hdsp *hdsp = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- if (hdsp_check_for_iobox (hdsp))
- return -EIO;
-
- if (hdsp_check_for_firmware(hdsp, 1))
- return -EIO;
-
- spin_lock_irq(&hdsp->lock);
-
- snd_pcm_set_sync(substream);
-
- runtime->hw = snd_hdsp_playback_subinfo;
- runtime->dma_area = hdsp->playback_buffer;
- runtime->dma_bytes = HDSP_DMA_AREA_BYTES;
-
- hdsp->playback_pid = current->pid;
- hdsp->playback_substream = substream;
-
- spin_unlock_irq(&hdsp->lock);
-
- snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hdsp_hw_constraints_period_sizes);
- if (hdsp->clock_source_locked) {
- runtime->hw.rate_min = runtime->hw.rate_max = hdsp->system_sample_rate;
- } else if (hdsp->io_type == H9632) {
- runtime->hw.rate_max = 192000;
- runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hdsp_hw_constraints_9632_sample_rates);
- }
- if (hdsp->io_type == H9632) {
- runtime->hw.channels_min = hdsp->qs_out_channels;
- runtime->hw.channels_max = hdsp->ss_out_channels;
- }
-
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- snd_hdsp_hw_rule_out_channels, hdsp,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- snd_hdsp_hw_rule_out_channels_rate, hdsp,
- SNDRV_PCM_HW_PARAM_RATE, -1);
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- snd_hdsp_hw_rule_rate_out_channels, hdsp,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
-
- if (RPM != hdsp->io_type) {
- hdsp->creg_spdif_stream = hdsp->creg_spdif;
- hdsp->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id);
- }
- return 0;
-}
-
-static int snd_hdsp_playback_release(struct snd_pcm_substream *substream)
-{
- struct hdsp *hdsp = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&hdsp->lock);
-
- hdsp->playback_pid = -1;
- hdsp->playback_substream = NULL;
-
- spin_unlock_irq(&hdsp->lock);
-
- if (RPM != hdsp->io_type) {
- hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id);
- }
- return 0;
-}
-
-
-static int snd_hdsp_capture_open(struct snd_pcm_substream *substream)
-{
- struct hdsp *hdsp = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- if (hdsp_check_for_iobox (hdsp))
- return -EIO;
-
- if (hdsp_check_for_firmware(hdsp, 1))
- return -EIO;
-
- spin_lock_irq(&hdsp->lock);
-
- snd_pcm_set_sync(substream);
-
- runtime->hw = snd_hdsp_capture_subinfo;
- runtime->dma_area = hdsp->capture_buffer;
- runtime->dma_bytes = HDSP_DMA_AREA_BYTES;
-
- hdsp->capture_pid = current->pid;
- hdsp->capture_substream = substream;
-
- spin_unlock_irq(&hdsp->lock);
-
- snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hdsp_hw_constraints_period_sizes);
- if (hdsp->io_type == H9632) {
- runtime->hw.channels_min = hdsp->qs_in_channels;
- runtime->hw.channels_max = hdsp->ss_in_channels;
- runtime->hw.rate_max = 192000;
- runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hdsp_hw_constraints_9632_sample_rates);
- }
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- snd_hdsp_hw_rule_in_channels, hdsp,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- snd_hdsp_hw_rule_in_channels_rate, hdsp,
- SNDRV_PCM_HW_PARAM_RATE, -1);
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- snd_hdsp_hw_rule_rate_in_channels, hdsp,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
- return 0;
-}
-
-static int snd_hdsp_capture_release(struct snd_pcm_substream *substream)
-{
- struct hdsp *hdsp = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&hdsp->lock);
-
- hdsp->capture_pid = -1;
- hdsp->capture_substream = NULL;
-
- spin_unlock_irq(&hdsp->lock);
- return 0;
-}
-
-/* helper functions for copying meter values */
-static inline int copy_u32_le(void __user *dest, void __iomem *src)
-{
- u32 val = readl(src);
- return copy_to_user(dest, &val, 4);
-}
-
-static inline int copy_u64_le(void __user *dest, void __iomem *src_low, void __iomem *src_high)
-{
- u32 rms_low, rms_high;
- u64 rms;
- rms_low = readl(src_low);
- rms_high = readl(src_high);
- rms = ((u64)rms_high << 32) | rms_low;
- return copy_to_user(dest, &rms, 8);
-}
-
-static inline int copy_u48_le(void __user *dest, void __iomem *src_low, void __iomem *src_high)
-{
- u32 rms_low, rms_high;
- u64 rms;
- rms_low = readl(src_low) & 0xffffff00;
- rms_high = readl(src_high) & 0xffffff00;
- rms = ((u64)rms_high << 32) | rms_low;
- return copy_to_user(dest, &rms, 8);
-}
-
-static int hdsp_9652_get_peak(struct hdsp *hdsp, struct hdsp_peak_rms __user *peak_rms)
-{
- int doublespeed = 0;
- int i, j, channels, ofs;
-
- if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DoubleSpeedStatus)
- doublespeed = 1;
- channels = doublespeed ? 14 : 26;
- for (i = 0, j = 0; i < 26; ++i) {
- if (doublespeed && (i & 4))
- continue;
- ofs = HDSP_9652_peakBase - j * 4;
- if (copy_u32_le(&peak_rms->input_peaks[i], hdsp->iobase + ofs))
- return -EFAULT;
- ofs -= channels * 4;
- if (copy_u32_le(&peak_rms->playback_peaks[i], hdsp->iobase + ofs))
- return -EFAULT;
- ofs -= channels * 4;
- if (copy_u32_le(&peak_rms->output_peaks[i], hdsp->iobase + ofs))
- return -EFAULT;
- ofs = HDSP_9652_rmsBase + j * 8;
- if (copy_u48_le(&peak_rms->input_rms[i], hdsp->iobase + ofs,
- hdsp->iobase + ofs + 4))
- return -EFAULT;
- ofs += channels * 8;
- if (copy_u48_le(&peak_rms->playback_rms[i], hdsp->iobase + ofs,
- hdsp->iobase + ofs + 4))
- return -EFAULT;
- ofs += channels * 8;
- if (copy_u48_le(&peak_rms->output_rms[i], hdsp->iobase + ofs,
- hdsp->iobase + ofs + 4))
- return -EFAULT;
- j++;
- }
- return 0;
-}
-
-static int hdsp_9632_get_peak(struct hdsp *hdsp, struct hdsp_peak_rms __user *peak_rms)
-{
- int i, j;
- struct hdsp_9632_meters __iomem *m;
- int doublespeed = 0;
-
- if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DoubleSpeedStatus)
- doublespeed = 1;
- m = (struct hdsp_9632_meters __iomem *)(hdsp->iobase+HDSP_9632_metersBase);
- for (i = 0, j = 0; i < 16; ++i, ++j) {
- if (copy_u32_le(&peak_rms->input_peaks[i], &m->input_peak[j]))
- return -EFAULT;
- if (copy_u32_le(&peak_rms->playback_peaks[i], &m->playback_peak[j]))
- return -EFAULT;
- if (copy_u32_le(&peak_rms->output_peaks[i], &m->output_peak[j]))
- return -EFAULT;
- if (copy_u64_le(&peak_rms->input_rms[i], &m->input_rms_low[j],
- &m->input_rms_high[j]))
- return -EFAULT;
- if (copy_u64_le(&peak_rms->playback_rms[i], &m->playback_rms_low[j],
- &m->playback_rms_high[j]))
- return -EFAULT;
- if (copy_u64_le(&peak_rms->output_rms[i], &m->output_rms_low[j],
- &m->output_rms_high[j]))
- return -EFAULT;
- if (doublespeed && i == 3) i += 4;
- }
- return 0;
-}
-
-static int hdsp_get_peak(struct hdsp *hdsp, struct hdsp_peak_rms __user *peak_rms)
-{
- int i;
-
- for (i = 0; i < 26; i++) {
- if (copy_u32_le(&peak_rms->playback_peaks[i],
- hdsp->iobase + HDSP_playbackPeakLevel + i * 4))
- return -EFAULT;
- if (copy_u32_le(&peak_rms->input_peaks[i],
- hdsp->iobase + HDSP_inputPeakLevel + i * 4))
- return -EFAULT;
- }
- for (i = 0; i < 28; i++) {
- if (copy_u32_le(&peak_rms->output_peaks[i],
- hdsp->iobase + HDSP_outputPeakLevel + i * 4))
- return -EFAULT;
- }
- for (i = 0; i < 26; ++i) {
- if (copy_u64_le(&peak_rms->playback_rms[i],
- hdsp->iobase + HDSP_playbackRmsLevel + i * 8 + 4,
- hdsp->iobase + HDSP_playbackRmsLevel + i * 8))
- return -EFAULT;
- if (copy_u64_le(&peak_rms->input_rms[i],
- hdsp->iobase + HDSP_inputRmsLevel + i * 8 + 4,
- hdsp->iobase + HDSP_inputRmsLevel + i * 8))
- return -EFAULT;
- }
- return 0;
-}
-
-static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct hdsp *hdsp = hw->private_data;
- void __user *argp = (void __user *)arg;
- int err;
-
- switch (cmd) {
- case SNDRV_HDSP_IOCTL_GET_PEAK_RMS: {
- struct hdsp_peak_rms __user *peak_rms = (struct hdsp_peak_rms __user *)arg;
-
- err = hdsp_check_for_iobox(hdsp);
- if (err < 0)
- return err;
-
- err = hdsp_check_for_firmware(hdsp, 1);
- if (err < 0)
- return err;
-
- if (!(hdsp->state & HDSP_FirmwareLoaded)) {
- snd_printk(KERN_ERR "Hammerfall-DSP: firmware needs to be uploaded to the card.\n");
- return -EINVAL;
- }
-
- switch (hdsp->io_type) {
- case H9652:
- return hdsp_9652_get_peak(hdsp, peak_rms);
- case H9632:
- return hdsp_9632_get_peak(hdsp, peak_rms);
- default:
- return hdsp_get_peak(hdsp, peak_rms);
- }
- }
- case SNDRV_HDSP_IOCTL_GET_CONFIG_INFO: {
- struct hdsp_config_info info;
- unsigned long flags;
- int i;
-
- err = hdsp_check_for_iobox(hdsp);
- if (err < 0)
- return err;
-
- err = hdsp_check_for_firmware(hdsp, 1);
- if (err < 0)
- return err;
-
- memset(&info, 0, sizeof(info));
- spin_lock_irqsave(&hdsp->lock, flags);
- info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp);
- info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp);
- if (hdsp->io_type != H9632)
- info.adatsync_sync_check = (unsigned char)hdsp_adatsync_sync_check(hdsp);
- info.spdif_sync_check = (unsigned char)hdsp_spdif_sync_check(hdsp);
- for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632) ? 3 : 1); ++i)
- info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i);
- info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp);
- info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp);
- info.spdif_professional = (unsigned char)hdsp_spdif_professional(hdsp);
- info.spdif_emphasis = (unsigned char)hdsp_spdif_emphasis(hdsp);
- info.spdif_nonaudio = (unsigned char)hdsp_spdif_nonaudio(hdsp);
- info.spdif_sample_rate = hdsp_spdif_sample_rate(hdsp);
- info.system_sample_rate = hdsp->system_sample_rate;
- info.autosync_sample_rate = hdsp_external_sample_rate(hdsp);
- info.system_clock_mode = (unsigned char)hdsp_system_clock_mode(hdsp);
- info.clock_source = (unsigned char)hdsp_clock_source(hdsp);
- info.autosync_ref = (unsigned char)hdsp_autosync_ref(hdsp);
- info.line_out = (unsigned char)hdsp_line_out(hdsp);
- if (hdsp->io_type == H9632) {
- info.da_gain = (unsigned char)hdsp_da_gain(hdsp);
- info.ad_gain = (unsigned char)hdsp_ad_gain(hdsp);
- info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp);
- info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp);
-
- } else if (hdsp->io_type == RPM) {
- info.da_gain = (unsigned char) hdsp_rpm_input12(hdsp);
- info.ad_gain = (unsigned char) hdsp_rpm_input34(hdsp);
- }
- if (hdsp->io_type == H9632 || hdsp->io_type == H9652)
- info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp);
- spin_unlock_irqrestore(&hdsp->lock, flags);
- if (copy_to_user(argp, &info, sizeof(info)))
- return -EFAULT;
- break;
- }
- case SNDRV_HDSP_IOCTL_GET_9632_AEB: {
- struct hdsp_9632_aeb h9632_aeb;
-
- if (hdsp->io_type != H9632) return -EINVAL;
- h9632_aeb.aebi = hdsp->ss_in_channels - H9632_SS_CHANNELS;
- h9632_aeb.aebo = hdsp->ss_out_channels - H9632_SS_CHANNELS;
- if (copy_to_user(argp, &h9632_aeb, sizeof(h9632_aeb)))
- return -EFAULT;
- break;
- }
- case SNDRV_HDSP_IOCTL_GET_VERSION: {
- struct hdsp_version hdsp_version;
- int err;
-
- if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return -EINVAL;
- if (hdsp->io_type == Undefined) {
- if ((err = hdsp_get_iobox_version(hdsp)) < 0)
- return err;
- }
- hdsp_version.io_type = hdsp->io_type;
- hdsp_version.firmware_rev = hdsp->firmware_rev;
- if ((err = copy_to_user(argp, &hdsp_version, sizeof(hdsp_version))))
- return -EFAULT;
- break;
- }
- case SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE: {
- struct hdsp_firmware __user *firmware;
- u32 __user *firmware_data;
- int err;
-
- if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return -EINVAL;
- /* SNDRV_HDSP_IOCTL_GET_VERSION must have been called */
- if (hdsp->io_type == Undefined) return -EINVAL;
-
- if (hdsp->state & (HDSP_FirmwareCached | HDSP_FirmwareLoaded))
- return -EBUSY;
-
- snd_printk(KERN_INFO "Hammerfall-DSP: initializing firmware upload\n");
- firmware = (struct hdsp_firmware __user *)argp;
-
- if (get_user(firmware_data, &firmware->firmware_data))
- return -EFAULT;
-
- if (hdsp_check_for_iobox (hdsp))
- return -EIO;
-
- if (copy_from_user(hdsp->firmware_cache, firmware_data, sizeof(hdsp->firmware_cache)) != 0)
- return -EFAULT;
-
- hdsp->state |= HDSP_FirmwareCached;
-
- if ((err = snd_hdsp_load_firmware_from_cache(hdsp)) < 0)
- return err;
-
- if (!(hdsp->state & HDSP_InitializationComplete)) {
- if ((err = snd_hdsp_enable_io(hdsp)) < 0)
- return err;
-
- snd_hdsp_initialize_channels(hdsp);
- snd_hdsp_initialize_midi_flush(hdsp);
-
- if ((err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp)) < 0) {
- snd_printk(KERN_ERR "Hammerfall-DSP: error creating alsa devices\n");
- return err;
- }
- }
- break;
- }
- case SNDRV_HDSP_IOCTL_GET_MIXER: {
- struct hdsp_mixer __user *mixer = (struct hdsp_mixer __user *)argp;
- if (copy_to_user(mixer->matrix, hdsp->mixer_matrix, sizeof(unsigned short)*HDSP_MATRIX_MIXER_SIZE))
- return -EFAULT;
- break;
- }
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static struct snd_pcm_ops snd_hdsp_playback_ops = {
- .open = snd_hdsp_playback_open,
- .close = snd_hdsp_playback_release,
- .ioctl = snd_hdsp_ioctl,
- .hw_params = snd_hdsp_hw_params,
- .prepare = snd_hdsp_prepare,
- .trigger = snd_hdsp_trigger,
- .pointer = snd_hdsp_hw_pointer,
- .copy = snd_hdsp_playback_copy,
- .silence = snd_hdsp_hw_silence,
-};
-
-static struct snd_pcm_ops snd_hdsp_capture_ops = {
- .open = snd_hdsp_capture_open,
- .close = snd_hdsp_capture_release,
- .ioctl = snd_hdsp_ioctl,
- .hw_params = snd_hdsp_hw_params,
- .prepare = snd_hdsp_prepare,
- .trigger = snd_hdsp_trigger,
- .pointer = snd_hdsp_hw_pointer,
- .copy = snd_hdsp_capture_copy,
-};
-
-static int snd_hdsp_create_hwdep(struct snd_card *card, struct hdsp *hdsp)
-{
- struct snd_hwdep *hw;
- int err;
-
- if ((err = snd_hwdep_new(card, "HDSP hwdep", 0, &hw)) < 0)
- return err;
-
- hdsp->hwdep = hw;
- hw->private_data = hdsp;
- strcpy(hw->name, "HDSP hwdep interface");
-
- hw->ops.ioctl = snd_hdsp_hwdep_ioctl;
- hw->ops.ioctl_compat = snd_hdsp_hwdep_ioctl;
-
- return 0;
-}
-
-static int snd_hdsp_create_pcm(struct snd_card *card, struct hdsp *hdsp)
-{
- struct snd_pcm *pcm;
- int err;
-
- if ((err = snd_pcm_new(card, hdsp->card_name, 0, 1, 1, &pcm)) < 0)
- return err;
-
- hdsp->pcm = pcm;
- pcm->private_data = hdsp;
- strcpy(pcm->name, hdsp->card_name);
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_hdsp_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_hdsp_capture_ops);
-
- pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
-
- return 0;
-}
-
-static void snd_hdsp_9652_enable_mixer (struct hdsp *hdsp)
-{
- hdsp->control2_register |= HDSP_9652_ENABLE_MIXER;
- hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
-}
-
-static int snd_hdsp_enable_io (struct hdsp *hdsp)
-{
- int i;
-
- if (hdsp_fifo_wait (hdsp, 0, 100)) {
- snd_printk(KERN_ERR "Hammerfall-DSP: enable_io fifo_wait failed\n");
- return -EIO;
- }
-
- for (i = 0; i < hdsp->max_channels; ++i) {
- hdsp_write (hdsp, HDSP_inputEnable + (4 * i), 1);
- hdsp_write (hdsp, HDSP_outputEnable + (4 * i), 1);
- }
-
- return 0;
-}
-
-static void snd_hdsp_initialize_channels(struct hdsp *hdsp)
-{
- int status, aebi_channels, aebo_channels;
-
- switch (hdsp->io_type) {
- case Digiface:
- hdsp->card_name = "RME Hammerfall DSP + Digiface";
- hdsp->ss_in_channels = hdsp->ss_out_channels = DIGIFACE_SS_CHANNELS;
- hdsp->ds_in_channels = hdsp->ds_out_channels = DIGIFACE_DS_CHANNELS;
- break;
-
- case H9652:
- hdsp->card_name = "RME Hammerfall HDSP 9652";
- hdsp->ss_in_channels = hdsp->ss_out_channels = H9652_SS_CHANNELS;
- hdsp->ds_in_channels = hdsp->ds_out_channels = H9652_DS_CHANNELS;
- break;
-
- case H9632:
- status = hdsp_read(hdsp, HDSP_statusRegister);
- /* HDSP_AEBx bits are low when AEB are connected */
- aebi_channels = (status & HDSP_AEBI) ? 0 : 4;
- aebo_channels = (status & HDSP_AEBO) ? 0 : 4;
- hdsp->card_name = "RME Hammerfall HDSP 9632";
- hdsp->ss_in_channels = H9632_SS_CHANNELS+aebi_channels;
- hdsp->ds_in_channels = H9632_DS_CHANNELS+aebi_channels;
- hdsp->qs_in_channels = H9632_QS_CHANNELS+aebi_channels;
- hdsp->ss_out_channels = H9632_SS_CHANNELS+aebo_channels;
- hdsp->ds_out_channels = H9632_DS_CHANNELS+aebo_channels;
- hdsp->qs_out_channels = H9632_QS_CHANNELS+aebo_channels;
- break;
-
- case Multiface:
- hdsp->card_name = "RME Hammerfall DSP + Multiface";
- hdsp->ss_in_channels = hdsp->ss_out_channels = MULTIFACE_SS_CHANNELS;
- hdsp->ds_in_channels = hdsp->ds_out_channels = MULTIFACE_DS_CHANNELS;
- break;
-
- case RPM:
- hdsp->card_name = "RME Hammerfall DSP + RPM";
- hdsp->ss_in_channels = RPM_CHANNELS-1;
- hdsp->ss_out_channels = RPM_CHANNELS;
- hdsp->ds_in_channels = RPM_CHANNELS-1;
- hdsp->ds_out_channels = RPM_CHANNELS;
- break;
-
- default:
- /* should never get here */
- break;
- }
-}
-
-static void snd_hdsp_initialize_midi_flush (struct hdsp *hdsp)
-{
- snd_hdsp_flush_midi_input (hdsp, 0);
- snd_hdsp_flush_midi_input (hdsp, 1);
-}
-
-static int snd_hdsp_create_alsa_devices(struct snd_card *card, struct hdsp *hdsp)
-{
- int err;
-
- if ((err = snd_hdsp_create_pcm(card, hdsp)) < 0) {
- snd_printk(KERN_ERR "Hammerfall-DSP: Error creating pcm interface\n");
- return err;
- }
-
-
- if ((err = snd_hdsp_create_midi(card, hdsp, 0)) < 0) {
- snd_printk(KERN_ERR "Hammerfall-DSP: Error creating first midi interface\n");
- return err;
- }
-
- if (hdsp->io_type == Digiface || hdsp->io_type == H9652) {
- if ((err = snd_hdsp_create_midi(card, hdsp, 1)) < 0) {
- snd_printk(KERN_ERR "Hammerfall-DSP: Error creating second midi interface\n");
- return err;
- }
- }
-
- if ((err = snd_hdsp_create_controls(card, hdsp)) < 0) {
- snd_printk(KERN_ERR "Hammerfall-DSP: Error creating ctl interface\n");
- return err;
- }
-
- snd_hdsp_proc_init(hdsp);
-
- hdsp->system_sample_rate = -1;
- hdsp->playback_pid = -1;
- hdsp->capture_pid = -1;
- hdsp->capture_substream = NULL;
- hdsp->playback_substream = NULL;
-
- if ((err = snd_hdsp_set_defaults(hdsp)) < 0) {
- snd_printk(KERN_ERR "Hammerfall-DSP: Error setting default values\n");
- return err;
- }
-
- if (!(hdsp->state & HDSP_InitializationComplete)) {
- strcpy(card->shortname, "Hammerfall DSP");
- sprintf(card->longname, "%s at 0x%lx, irq %d", hdsp->card_name,
- hdsp->port, hdsp->irq);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_printk(KERN_ERR "Hammerfall-DSP: error registering card\n");
- return err;
- }
- hdsp->state |= HDSP_InitializationComplete;
- }
-
- return 0;
-}
-
-#ifdef HDSP_FW_LOADER
-/* load firmware via hotplug fw loader */
-static int hdsp_request_fw_loader(struct hdsp *hdsp)
-{
- const char *fwfile;
- const struct firmware *fw;
- int err;
-
- if (hdsp->io_type == H9652 || hdsp->io_type == H9632)
- return 0;
- if (hdsp->io_type == Undefined) {
- if ((err = hdsp_get_iobox_version(hdsp)) < 0)
- return err;
- if (hdsp->io_type == H9652 || hdsp->io_type == H9632)
- return 0;
- }
-
- /* caution: max length of firmware filename is 30! */
- switch (hdsp->io_type) {
- case RPM:
- fwfile = "rpm_firmware.bin";
- break;
- case Multiface:
- if (hdsp->firmware_rev == 0xa)
- fwfile = "multiface_firmware.bin";
- else
- fwfile = "multiface_firmware_rev11.bin";
- break;
- case Digiface:
- if (hdsp->firmware_rev == 0xa)
- fwfile = "digiface_firmware.bin";
- else
- fwfile = "digiface_firmware_rev11.bin";
- break;
- default:
- snd_printk(KERN_ERR "Hammerfall-DSP: invalid io_type %d\n", hdsp->io_type);
- return -EINVAL;
- }
-
- if (request_firmware(&fw, fwfile, &hdsp->pci->dev)) {
- snd_printk(KERN_ERR "Hammerfall-DSP: cannot load firmware %s\n", fwfile);
- return -ENOENT;
- }
- if (fw->size < sizeof(hdsp->firmware_cache)) {
- snd_printk(KERN_ERR "Hammerfall-DSP: too short firmware size %d (expected %d)\n",
- (int)fw->size, (int)sizeof(hdsp->firmware_cache));
- release_firmware(fw);
- return -EINVAL;
- }
-
- memcpy(hdsp->firmware_cache, fw->data, sizeof(hdsp->firmware_cache));
-
- release_firmware(fw);
-
- hdsp->state |= HDSP_FirmwareCached;
-
- if ((err = snd_hdsp_load_firmware_from_cache(hdsp)) < 0)
- return err;
-
- if (!(hdsp->state & HDSP_InitializationComplete)) {
- if ((err = snd_hdsp_enable_io(hdsp)) < 0)
- return err;
-
- if ((err = snd_hdsp_create_hwdep(hdsp->card, hdsp)) < 0) {
- snd_printk(KERN_ERR "Hammerfall-DSP: error creating hwdep device\n");
- return err;
- }
- snd_hdsp_initialize_channels(hdsp);
- snd_hdsp_initialize_midi_flush(hdsp);
- if ((err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp)) < 0) {
- snd_printk(KERN_ERR "Hammerfall-DSP: error creating alsa devices\n");
- return err;
- }
- }
- return 0;
-}
-#endif
-
-static int __devinit snd_hdsp_create(struct snd_card *card,
- struct hdsp *hdsp)
-{
- struct pci_dev *pci = hdsp->pci;
- int err;
- int is_9652 = 0;
- int is_9632 = 0;
-
- hdsp->irq = -1;
- hdsp->state = 0;
- hdsp->midi[0].rmidi = NULL;
- hdsp->midi[1].rmidi = NULL;
- hdsp->midi[0].input = NULL;
- hdsp->midi[1].input = NULL;
- hdsp->midi[0].output = NULL;
- hdsp->midi[1].output = NULL;
- hdsp->midi[0].pending = 0;
- hdsp->midi[1].pending = 0;
- spin_lock_init(&hdsp->midi[0].lock);
- spin_lock_init(&hdsp->midi[1].lock);
- hdsp->iobase = NULL;
- hdsp->control_register = 0;
- hdsp->control2_register = 0;
- hdsp->io_type = Undefined;
- hdsp->max_channels = 26;
-
- hdsp->card = card;
-
- spin_lock_init(&hdsp->lock);
-
- tasklet_init(&hdsp->midi_tasklet, hdsp_midi_tasklet, (unsigned long)hdsp);
-
- pci_read_config_word(hdsp->pci, PCI_CLASS_REVISION, &hdsp->firmware_rev);
- hdsp->firmware_rev &= 0xff;
-
- /* From Martin Bjoernsen :
- "It is important that the card's latency timer register in
- the PCI configuration space is set to a value much larger
- than 0 by the computer's BIOS or the driver.
- The windows driver always sets this 8 bit register [...]
- to its maximum 255 to avoid problems with some computers."
- */
- pci_write_config_byte(hdsp->pci, PCI_LATENCY_TIMER, 0xFF);
-
- strcpy(card->driver, "H-DSP");
- strcpy(card->mixername, "Xilinx FPGA");
-
- if (hdsp->firmware_rev < 0xa)
- return -ENODEV;
- else if (hdsp->firmware_rev < 0x64)
- hdsp->card_name = "RME Hammerfall DSP";
- else if (hdsp->firmware_rev < 0x96) {
- hdsp->card_name = "RME HDSP 9652";
- is_9652 = 1;
- } else {
- hdsp->card_name = "RME HDSP 9632";
- hdsp->max_channels = 16;
- is_9632 = 1;
- }
-
- if ((err = pci_enable_device(pci)) < 0)
- return err;
-
- pci_set_master(hdsp->pci);
-
- if ((err = pci_request_regions(pci, "hdsp")) < 0)
- return err;
- hdsp->port = pci_resource_start(pci, 0);
- if ((hdsp->iobase = ioremap_nocache(hdsp->port, HDSP_IO_EXTENT)) == NULL) {
- snd_printk(KERN_ERR "Hammerfall-DSP: unable to remap region 0x%lx-0x%lx\n", hdsp->port, hdsp->port + HDSP_IO_EXTENT - 1);
- return -EBUSY;
- }
-
- if (request_irq(pci->irq, snd_hdsp_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, hdsp)) {
- snd_printk(KERN_ERR "Hammerfall-DSP: unable to use IRQ %d\n", pci->irq);
- return -EBUSY;
- }
-
- hdsp->irq = pci->irq;
- hdsp->precise_ptr = 0;
- hdsp->use_midi_tasklet = 1;
- hdsp->dds_value = 0;
-
- if ((err = snd_hdsp_initialize_memory(hdsp)) < 0)
- return err;
-
- if (!is_9652 && !is_9632) {
- /* we wait a maximum of 10 seconds to let freshly
- * inserted cardbus cards do their hardware init */
- err = hdsp_wait_for_iobox(hdsp, 1000, 10);
-
- if (err < 0)
- return err;
-
- if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
-#ifdef HDSP_FW_LOADER
- if ((err = hdsp_request_fw_loader(hdsp)) < 0)
- /* we don't fail as this can happen
- if userspace is not ready for
- firmware upload
- */
- snd_printk(KERN_ERR "Hammerfall-DSP: couldn't get firmware from userspace. try using hdsploader\n");
- else
- /* init is complete, we return */
- return 0;
-#endif
- /* we defer initialization */
- snd_printk(KERN_INFO "Hammerfall-DSP: card initialization pending : waiting for firmware\n");
- if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0)
- return err;
- return 0;
- } else {
- snd_printk(KERN_INFO "Hammerfall-DSP: Firmware already present, initializing card.\n");
- if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2)
- hdsp->io_type = RPM;
- else if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
- hdsp->io_type = Multiface;
- else
- hdsp->io_type = Digiface;
- }
- }
-
- if ((err = snd_hdsp_enable_io(hdsp)) != 0)
- return err;
-
- if (is_9652)
- hdsp->io_type = H9652;
-
- if (is_9632)
- hdsp->io_type = H9632;
-
- if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0)
- return err;
-
- snd_hdsp_initialize_channels(hdsp);
- snd_hdsp_initialize_midi_flush(hdsp);
-
- hdsp->state |= HDSP_FirmwareLoaded;
-
- if ((err = snd_hdsp_create_alsa_devices(card, hdsp)) < 0)
- return err;
-
- return 0;
-}
-
-static int snd_hdsp_free(struct hdsp *hdsp)
-{
- if (hdsp->port) {
- /* stop the audio, and cancel all interrupts */
- tasklet_kill(&hdsp->midi_tasklet);
- hdsp->control_register &= ~(HDSP_Start|HDSP_AudioInterruptEnable|HDSP_Midi0InterruptEnable|HDSP_Midi1InterruptEnable);
- hdsp_write (hdsp, HDSP_controlRegister, hdsp->control_register);
- }
-
- if (hdsp->irq >= 0)
- free_irq(hdsp->irq, (void *)hdsp);
-
- snd_hdsp_free_buffers(hdsp);
-
- if (hdsp->iobase)
- iounmap(hdsp->iobase);
-
- if (hdsp->port)
- pci_release_regions(hdsp->pci);
-
- pci_disable_device(hdsp->pci);
- return 0;
-}
-
-static void snd_hdsp_card_free(struct snd_card *card)
-{
- struct hdsp *hdsp = card->private_data;
-
- if (hdsp)
- snd_hdsp_free(hdsp);
-}
-
-static int __devinit snd_hdsp_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct hdsp *hdsp;
- struct snd_card *card;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct hdsp), &card);
- if (err < 0)
- return err;
-
- hdsp = card->private_data;
- card->private_free = snd_hdsp_card_free;
- hdsp->dev = dev;
- hdsp->pci = pci;
- snd_card_set_dev(card, &pci->dev);
-
- if ((err = snd_hdsp_create(card, hdsp)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- strcpy(card->shortname, "Hammerfall DSP");
- sprintf(card->longname, "%s at 0x%lx, irq %d", hdsp->card_name,
- hdsp->port, hdsp->irq);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_hdsp_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_hdsp_ids,
- .probe = snd_hdsp_probe,
- .remove = __devexit_p(snd_hdsp_remove),
-};
-
-static int __init alsa_card_hdsp_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_hdsp_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_hdsp_init)
-module_exit(alsa_card_hdsp_exit)
diff --git a/ANDROID_3.4.5/sound/pci/rme9652/hdspm.c b/ANDROID_3.4.5/sound/pci/rme9652/hdspm.c
deleted file mode 100644
index bc030a20..00000000
--- a/ANDROID_3.4.5/sound/pci/rme9652/hdspm.c
+++ /dev/null
@@ -1,6940 +0,0 @@
-/*
- * ALSA driver for RME Hammerfall DSP MADI audio interface(s)
- *
- * Copyright (c) 2003 Winfried Ritsch (IEM)
- * code based on hdsp.c Paul Davis
- * Marcus Andersson
- * Thomas Charbonnel
- * Modified 2006-06-01 for AES32 support by Remy Bruno
- * <remy.bruno@trinnov.com>
- *
- * Modified 2009-04-13 for proper metering by Florian Faber
- * <faber@faberman.de>
- *
- * Modified 2009-04-14 for native float support by Florian Faber
- * <faber@faberman.de>
- *
- * Modified 2009-04-26 fixed bug in rms metering by Florian Faber
- * <faber@faberman.de>
- *
- * Modified 2009-04-30 added hw serial number support by Florian Faber
- *
- * Modified 2011-01-14 added S/PDIF input on RayDATs by Adrian Knoth
- *
- * Modified 2011-01-25 variable period sizes on RayDAT/AIO by Adrian Knoth
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/math64.h>
-#include <asm/io.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/info.h>
-#include <sound/asoundef.h>
-#include <sound/rawmidi.h>
-#include <sound/hwdep.h>
-#include <sound/initval.h>
-
-#include <sound/hdspm.h>
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for RME HDSPM interface.");
-
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for RME HDSPM interface.");
-
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable/disable specific HDSPM soundcards.");
-
-
-MODULE_AUTHOR
-(
- "Winfried Ritsch <ritsch_AT_iem.at>, "
- "Paul Davis <paul@linuxaudiosystems.com>, "
- "Marcus Andersson, Thomas Charbonnel <thomas@undata.org>, "
- "Remy Bruno <remy.bruno@trinnov.com>, "
- "Florian Faber <faberman@linuxproaudio.org>, "
- "Adrian Knoth <adi@drcomp.erfurt.thur.de>"
-);
-MODULE_DESCRIPTION("RME HDSPM");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
-
-/* --- Write registers. ---
- These are defined as byte-offsets from the iobase value. */
-
-#define HDSPM_WR_SETTINGS 0
-#define HDSPM_outputBufferAddress 32
-#define HDSPM_inputBufferAddress 36
-#define HDSPM_controlRegister 64
-#define HDSPM_interruptConfirmation 96
-#define HDSPM_control2Reg 256 /* not in specs ???????? */
-#define HDSPM_freqReg 256 /* for AES32 */
-#define HDSPM_midiDataOut0 352 /* just believe in old code */
-#define HDSPM_midiDataOut1 356
-#define HDSPM_eeprom_wr 384 /* for AES32 */
-
-/* DMA enable for 64 channels, only Bit 0 is relevant */
-#define HDSPM_outputEnableBase 512 /* 512-767 input DMA */
-#define HDSPM_inputEnableBase 768 /* 768-1023 output DMA */
-
-/* 16 page addresses for each of the 64 channels DMA buffer in and out
- (each 64k=16*4k) Buffer must be 4k aligned (which is default i386 ????) */
-#define HDSPM_pageAddressBufferOut 8192
-#define HDSPM_pageAddressBufferIn (HDSPM_pageAddressBufferOut+64*16*4)
-
-#define HDSPM_MADI_mixerBase 32768 /* 32768-65535 for 2x64x64 Fader */
-
-#define HDSPM_MATRIX_MIXER_SIZE 8192 /* = 2*64*64 * 4 Byte => 32kB */
-
-/* --- Read registers. ---
- These are defined as byte-offsets from the iobase value */
-#define HDSPM_statusRegister 0
-/*#define HDSPM_statusRegister2 96 */
-/* after RME Windows driver sources, status2 is 4-byte word # 48 = word at
- * offset 192, for AES32 *and* MADI
- * => need to check that offset 192 is working on MADI */
-#define HDSPM_statusRegister2 192
-#define HDSPM_timecodeRegister 128
-
-/* AIO, RayDAT */
-#define HDSPM_RD_STATUS_0 0
-#define HDSPM_RD_STATUS_1 64
-#define HDSPM_RD_STATUS_2 128
-#define HDSPM_RD_STATUS_3 192
-
-#define HDSPM_RD_TCO 256
-#define HDSPM_RD_PLL_FREQ 512
-#define HDSPM_WR_TCO 128
-
-#define HDSPM_TCO1_TCO_lock 0x00000001
-#define HDSPM_TCO1_WCK_Input_Range_LSB 0x00000002
-#define HDSPM_TCO1_WCK_Input_Range_MSB 0x00000004
-#define HDSPM_TCO1_LTC_Input_valid 0x00000008
-#define HDSPM_TCO1_WCK_Input_valid 0x00000010
-#define HDSPM_TCO1_Video_Input_Format_NTSC 0x00000020
-#define HDSPM_TCO1_Video_Input_Format_PAL 0x00000040
-
-#define HDSPM_TCO1_set_TC 0x00000100
-#define HDSPM_TCO1_set_drop_frame_flag 0x00000200
-#define HDSPM_TCO1_LTC_Format_LSB 0x00000400
-#define HDSPM_TCO1_LTC_Format_MSB 0x00000800
-
-#define HDSPM_TCO2_TC_run 0x00010000
-#define HDSPM_TCO2_WCK_IO_ratio_LSB 0x00020000
-#define HDSPM_TCO2_WCK_IO_ratio_MSB 0x00040000
-#define HDSPM_TCO2_set_num_drop_frames_LSB 0x00080000
-#define HDSPM_TCO2_set_num_drop_frames_MSB 0x00100000
-#define HDSPM_TCO2_set_jam_sync 0x00200000
-#define HDSPM_TCO2_set_flywheel 0x00400000
-
-#define HDSPM_TCO2_set_01_4 0x01000000
-#define HDSPM_TCO2_set_pull_down 0x02000000
-#define HDSPM_TCO2_set_pull_up 0x04000000
-#define HDSPM_TCO2_set_freq 0x08000000
-#define HDSPM_TCO2_set_term_75R 0x10000000
-#define HDSPM_TCO2_set_input_LSB 0x20000000
-#define HDSPM_TCO2_set_input_MSB 0x40000000
-#define HDSPM_TCO2_set_freq_from_app 0x80000000
-
-
-#define HDSPM_midiDataOut0 352
-#define HDSPM_midiDataOut1 356
-#define HDSPM_midiDataOut2 368
-
-#define HDSPM_midiDataIn0 360
-#define HDSPM_midiDataIn1 364
-#define HDSPM_midiDataIn2 372
-#define HDSPM_midiDataIn3 376
-
-/* status is data bytes in MIDI-FIFO (0-128) */
-#define HDSPM_midiStatusOut0 384
-#define HDSPM_midiStatusOut1 388
-#define HDSPM_midiStatusOut2 400
-
-#define HDSPM_midiStatusIn0 392
-#define HDSPM_midiStatusIn1 396
-#define HDSPM_midiStatusIn2 404
-#define HDSPM_midiStatusIn3 408
-
-
-/* the meters are regular i/o-mapped registers, but offset
- considerably from the rest. the peak registers are reset
- when read; the least-significant 4 bits are full-scale counters;
- the actual peak value is in the most-significant 24 bits.
-*/
-
-#define HDSPM_MADI_INPUT_PEAK 4096
-#define HDSPM_MADI_PLAYBACK_PEAK 4352
-#define HDSPM_MADI_OUTPUT_PEAK 4608
-
-#define HDSPM_MADI_INPUT_RMS_L 6144
-#define HDSPM_MADI_PLAYBACK_RMS_L 6400
-#define HDSPM_MADI_OUTPUT_RMS_L 6656
-
-#define HDSPM_MADI_INPUT_RMS_H 7168
-#define HDSPM_MADI_PLAYBACK_RMS_H 7424
-#define HDSPM_MADI_OUTPUT_RMS_H 7680
-
-/* --- Control Register bits --------- */
-#define HDSPM_Start (1<<0) /* start engine */
-
-#define HDSPM_Latency0 (1<<1) /* buffer size = 2^n */
-#define HDSPM_Latency1 (1<<2) /* where n is defined */
-#define HDSPM_Latency2 (1<<3) /* by Latency{2,1,0} */
-
-#define HDSPM_ClockModeMaster (1<<4) /* 1=Master, 0=Autosync */
-#define HDSPM_c0Master 0x1 /* Master clock bit in settings
- register [RayDAT, AIO] */
-
-#define HDSPM_AudioInterruptEnable (1<<5) /* what do you think ? */
-
-#define HDSPM_Frequency0 (1<<6) /* 0=44.1kHz/88.2kHz 1=48kHz/96kHz */
-#define HDSPM_Frequency1 (1<<7) /* 0=32kHz/64kHz */
-#define HDSPM_DoubleSpeed (1<<8) /* 0=normal speed, 1=double speed */
-#define HDSPM_QuadSpeed (1<<31) /* quad speed bit */
-
-#define HDSPM_Professional (1<<9) /* Professional */ /* AES32 ONLY */
-#define HDSPM_TX_64ch (1<<10) /* Output 64channel MODE=1,
- 56channelMODE=0 */ /* MADI ONLY*/
-#define HDSPM_Emphasis (1<<10) /* Emphasis */ /* AES32 ONLY */
-
-#define HDSPM_AutoInp (1<<11) /* Auto Input (takeover) == Safe Mode,
- 0=off, 1=on */ /* MADI ONLY */
-#define HDSPM_Dolby (1<<11) /* Dolby = "NonAudio" ?? */ /* AES32 ONLY */
-
-#define HDSPM_InputSelect0 (1<<14) /* Input select 0= optical, 1=coax
- * -- MADI ONLY
- */
-#define HDSPM_InputSelect1 (1<<15) /* should be 0 */
-
-#define HDSPM_SyncRef2 (1<<13)
-#define HDSPM_SyncRef3 (1<<25)
-
-#define HDSPM_SMUX (1<<18) /* Frame ??? */ /* MADI ONY */
-#define HDSPM_clr_tms (1<<19) /* clear track marker, do not use
- AES additional bits in
- lower 5 Audiodatabits ??? */
-#define HDSPM_taxi_reset (1<<20) /* ??? */ /* MADI ONLY ? */
-#define HDSPM_WCK48 (1<<20) /* Frame ??? = HDSPM_SMUX */ /* AES32 ONLY */
-
-#define HDSPM_Midi0InterruptEnable 0x0400000
-#define HDSPM_Midi1InterruptEnable 0x0800000
-#define HDSPM_Midi2InterruptEnable 0x0200000
-#define HDSPM_Midi3InterruptEnable 0x4000000
-
-#define HDSPM_LineOut (1<<24) /* Analog Out on channel 63/64 on=1, mute=0 */
-#define HDSPe_FLOAT_FORMAT 0x2000000
-
-#define HDSPM_DS_DoubleWire (1<<26) /* AES32 ONLY */
-#define HDSPM_QS_DoubleWire (1<<27) /* AES32 ONLY */
-#define HDSPM_QS_QuadWire (1<<28) /* AES32 ONLY */
-
-#define HDSPM_wclk_sel (1<<30)
-
-/* --- bit helper defines */
-#define HDSPM_LatencyMask (HDSPM_Latency0|HDSPM_Latency1|HDSPM_Latency2)
-#define HDSPM_FrequencyMask (HDSPM_Frequency0|HDSPM_Frequency1|\
- HDSPM_DoubleSpeed|HDSPM_QuadSpeed)
-#define HDSPM_InputMask (HDSPM_InputSelect0|HDSPM_InputSelect1)
-#define HDSPM_InputOptical 0
-#define HDSPM_InputCoaxial (HDSPM_InputSelect0)
-#define HDSPM_SyncRefMask (HDSPM_SyncRef0|HDSPM_SyncRef1|\
- HDSPM_SyncRef2|HDSPM_SyncRef3)
-
-#define HDSPM_c0_SyncRef0 0x2
-#define HDSPM_c0_SyncRef1 0x4
-#define HDSPM_c0_SyncRef2 0x8
-#define HDSPM_c0_SyncRef3 0x10
-#define HDSPM_c0_SyncRefMask (HDSPM_c0_SyncRef0 | HDSPM_c0_SyncRef1 |\
- HDSPM_c0_SyncRef2 | HDSPM_c0_SyncRef3)
-
-#define HDSPM_SYNC_FROM_WORD 0 /* Preferred sync reference */
-#define HDSPM_SYNC_FROM_MADI 1 /* choices - used by "pref_sync_ref" */
-#define HDSPM_SYNC_FROM_TCO 2
-#define HDSPM_SYNC_FROM_SYNC_IN 3
-
-#define HDSPM_Frequency32KHz HDSPM_Frequency0
-#define HDSPM_Frequency44_1KHz HDSPM_Frequency1
-#define HDSPM_Frequency48KHz (HDSPM_Frequency1|HDSPM_Frequency0)
-#define HDSPM_Frequency64KHz (HDSPM_DoubleSpeed|HDSPM_Frequency0)
-#define HDSPM_Frequency88_2KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1)
-#define HDSPM_Frequency96KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1|\
- HDSPM_Frequency0)
-#define HDSPM_Frequency128KHz (HDSPM_QuadSpeed|HDSPM_Frequency0)
-#define HDSPM_Frequency176_4KHz (HDSPM_QuadSpeed|HDSPM_Frequency1)
-#define HDSPM_Frequency192KHz (HDSPM_QuadSpeed|HDSPM_Frequency1|\
- HDSPM_Frequency0)
-
-
-/* Synccheck Status */
-#define HDSPM_SYNC_CHECK_NO_LOCK 0
-#define HDSPM_SYNC_CHECK_LOCK 1
-#define HDSPM_SYNC_CHECK_SYNC 2
-
-/* AutoSync References - used by "autosync_ref" control switch */
-#define HDSPM_AUTOSYNC_FROM_WORD 0
-#define HDSPM_AUTOSYNC_FROM_MADI 1
-#define HDSPM_AUTOSYNC_FROM_TCO 2
-#define HDSPM_AUTOSYNC_FROM_SYNC_IN 3
-#define HDSPM_AUTOSYNC_FROM_NONE 4
-
-/* Possible sources of MADI input */
-#define HDSPM_OPTICAL 0 /* optical */
-#define HDSPM_COAXIAL 1 /* BNC */
-
-#define hdspm_encode_latency(x) (((x)<<1) & HDSPM_LatencyMask)
-#define hdspm_decode_latency(x) ((((x) & HDSPM_LatencyMask)>>1))
-
-#define hdspm_encode_in(x) (((x)&0x3)<<14)
-#define hdspm_decode_in(x) (((x)>>14)&0x3)
-
-/* --- control2 register bits --- */
-#define HDSPM_TMS (1<<0)
-#define HDSPM_TCK (1<<1)
-#define HDSPM_TDI (1<<2)
-#define HDSPM_JTAG (1<<3)
-#define HDSPM_PWDN (1<<4)
-#define HDSPM_PROGRAM (1<<5)
-#define HDSPM_CONFIG_MODE_0 (1<<6)
-#define HDSPM_CONFIG_MODE_1 (1<<7)
-/*#define HDSPM_VERSION_BIT (1<<8) not defined any more*/
-#define HDSPM_BIGENDIAN_MODE (1<<9)
-#define HDSPM_RD_MULTIPLE (1<<10)
-
-/* --- Status Register bits --- */ /* MADI ONLY */ /* Bits defined here and
- that do not conflict with specific bits for AES32 seem to be valid also
- for the AES32
- */
-#define HDSPM_audioIRQPending (1<<0) /* IRQ is high and pending */
-#define HDSPM_RX_64ch (1<<1) /* Input 64chan. MODE=1, 56chn MODE=0 */
-#define HDSPM_AB_int (1<<2) /* InputChannel Opt=0, Coax=1
- * (like inp0)
- */
-
-#define HDSPM_madiLock (1<<3) /* MADI Locked =1, no=0 */
-#define HDSPM_madiSync (1<<18) /* MADI is in sync */
-
-#define HDSPM_tcoLock 0x00000020 /* Optional TCO locked status FOR HDSPe MADI! */
-#define HDSPM_tcoSync 0x10000000 /* Optional TCO sync status */
-
-#define HDSPM_syncInLock 0x00010000 /* Sync In lock status FOR HDSPe MADI! */
-#define HDSPM_syncInSync 0x00020000 /* Sync In sync status FOR HDSPe MADI! */
-
-#define HDSPM_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */
- /* since 64byte accurate, last 6 bits are not used */
-
-
-
-#define HDSPM_DoubleSpeedStatus (1<<19) /* (input) card in double speed */
-
-#define HDSPM_madiFreq0 (1<<22) /* system freq 0=error */
-#define HDSPM_madiFreq1 (1<<23) /* 1=32, 2=44.1 3=48 */
-#define HDSPM_madiFreq2 (1<<24) /* 4=64, 5=88.2 6=96 */
-#define HDSPM_madiFreq3 (1<<25) /* 7=128, 8=176.4 9=192 */
-
-#define HDSPM_BufferID (1<<26) /* (Double)Buffer ID toggles with
- * Interrupt
- */
-#define HDSPM_tco_detect 0x08000000
-#define HDSPM_tco_lock 0x20000000
-
-#define HDSPM_s2_tco_detect 0x00000040
-#define HDSPM_s2_AEBO_D 0x00000080
-#define HDSPM_s2_AEBI_D 0x00000100
-
-
-#define HDSPM_midi0IRQPending 0x40000000
-#define HDSPM_midi1IRQPending 0x80000000
-#define HDSPM_midi2IRQPending 0x20000000
-#define HDSPM_midi2IRQPendingAES 0x00000020
-#define HDSPM_midi3IRQPending 0x00200000
-
-/* --- status bit helpers */
-#define HDSPM_madiFreqMask (HDSPM_madiFreq0|HDSPM_madiFreq1|\
- HDSPM_madiFreq2|HDSPM_madiFreq3)
-#define HDSPM_madiFreq32 (HDSPM_madiFreq0)
-#define HDSPM_madiFreq44_1 (HDSPM_madiFreq1)
-#define HDSPM_madiFreq48 (HDSPM_madiFreq0|HDSPM_madiFreq1)
-#define HDSPM_madiFreq64 (HDSPM_madiFreq2)
-#define HDSPM_madiFreq88_2 (HDSPM_madiFreq0|HDSPM_madiFreq2)
-#define HDSPM_madiFreq96 (HDSPM_madiFreq1|HDSPM_madiFreq2)
-#define HDSPM_madiFreq128 (HDSPM_madiFreq0|HDSPM_madiFreq1|HDSPM_madiFreq2)
-#define HDSPM_madiFreq176_4 (HDSPM_madiFreq3)
-#define HDSPM_madiFreq192 (HDSPM_madiFreq3|HDSPM_madiFreq0)
-
-/* Status2 Register bits */ /* MADI ONLY */
-
-#define HDSPM_version0 (1<<0) /* not really defined but I guess */
-#define HDSPM_version1 (1<<1) /* in former cards it was ??? */
-#define HDSPM_version2 (1<<2)
-
-#define HDSPM_wcLock (1<<3) /* Wordclock is detected and locked */
-#define HDSPM_wcSync (1<<4) /* Wordclock is in sync with systemclock */
-
-#define HDSPM_wc_freq0 (1<<5) /* input freq detected via autosync */
-#define HDSPM_wc_freq1 (1<<6) /* 001=32, 010==44.1, 011=48, */
-#define HDSPM_wc_freq2 (1<<7) /* 100=64, 101=88.2, 110=96, */
-/* missing Bit for 111=128, 1000=176.4, 1001=192 */
-
-#define HDSPM_SyncRef0 0x10000 /* Sync Reference */
-#define HDSPM_SyncRef1 0x20000
-
-#define HDSPM_SelSyncRef0 (1<<8) /* AutoSync Source */
-#define HDSPM_SelSyncRef1 (1<<9) /* 000=word, 001=MADI, */
-#define HDSPM_SelSyncRef2 (1<<10) /* 111=no valid signal */
-
-#define HDSPM_wc_valid (HDSPM_wcLock|HDSPM_wcSync)
-
-#define HDSPM_wcFreqMask (HDSPM_wc_freq0|HDSPM_wc_freq1|HDSPM_wc_freq2)
-#define HDSPM_wcFreq32 (HDSPM_wc_freq0)
-#define HDSPM_wcFreq44_1 (HDSPM_wc_freq1)
-#define HDSPM_wcFreq48 (HDSPM_wc_freq0|HDSPM_wc_freq1)
-#define HDSPM_wcFreq64 (HDSPM_wc_freq2)
-#define HDSPM_wcFreq88_2 (HDSPM_wc_freq0|HDSPM_wc_freq2)
-#define HDSPM_wcFreq96 (HDSPM_wc_freq1|HDSPM_wc_freq2)
-
-#define HDSPM_status1_F_0 0x0400000
-#define HDSPM_status1_F_1 0x0800000
-#define HDSPM_status1_F_2 0x1000000
-#define HDSPM_status1_F_3 0x2000000
-#define HDSPM_status1_freqMask (HDSPM_status1_F_0|HDSPM_status1_F_1|HDSPM_status1_F_2|HDSPM_status1_F_3)
-
-
-#define HDSPM_SelSyncRefMask (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\
- HDSPM_SelSyncRef2)
-#define HDSPM_SelSyncRef_WORD 0
-#define HDSPM_SelSyncRef_MADI (HDSPM_SelSyncRef0)
-#define HDSPM_SelSyncRef_TCO (HDSPM_SelSyncRef1)
-#define HDSPM_SelSyncRef_SyncIn (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1)
-#define HDSPM_SelSyncRef_NVALID (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\
- HDSPM_SelSyncRef2)
-
-/*
- For AES32, bits for status, status2 and timecode are different
-*/
-/* status */
-#define HDSPM_AES32_wcLock 0x0200000
-#define HDSPM_AES32_wcFreq_bit 22
-/* (status >> HDSPM_AES32_wcFreq_bit) & 0xF gives WC frequency (cf function
- HDSPM_bit2freq */
-#define HDSPM_AES32_syncref_bit 16
-/* (status >> HDSPM_AES32_syncref_bit) & 0xF gives sync source */
-
-#define HDSPM_AES32_AUTOSYNC_FROM_WORD 0
-#define HDSPM_AES32_AUTOSYNC_FROM_AES1 1
-#define HDSPM_AES32_AUTOSYNC_FROM_AES2 2
-#define HDSPM_AES32_AUTOSYNC_FROM_AES3 3
-#define HDSPM_AES32_AUTOSYNC_FROM_AES4 4
-#define HDSPM_AES32_AUTOSYNC_FROM_AES5 5
-#define HDSPM_AES32_AUTOSYNC_FROM_AES6 6
-#define HDSPM_AES32_AUTOSYNC_FROM_AES7 7
-#define HDSPM_AES32_AUTOSYNC_FROM_AES8 8
-#define HDSPM_AES32_AUTOSYNC_FROM_NONE 9
-
-/* status2 */
-/* HDSPM_LockAES_bit is given by HDSPM_LockAES >> (AES# - 1) */
-#define HDSPM_LockAES 0x80
-#define HDSPM_LockAES1 0x80
-#define HDSPM_LockAES2 0x40
-#define HDSPM_LockAES3 0x20
-#define HDSPM_LockAES4 0x10
-#define HDSPM_LockAES5 0x8
-#define HDSPM_LockAES6 0x4
-#define HDSPM_LockAES7 0x2
-#define HDSPM_LockAES8 0x1
-/*
- Timecode
- After windows driver sources, bits 4*i to 4*i+3 give the input frequency on
- AES i+1
- bits 3210
- 0001 32kHz
- 0010 44.1kHz
- 0011 48kHz
- 0100 64kHz
- 0101 88.2kHz
- 0110 96kHz
- 0111 128kHz
- 1000 176.4kHz
- 1001 192kHz
- NB: Timecode register doesn't seem to work on AES32 card revision 230
-*/
-
-/* Mixer Values */
-#define UNITY_GAIN 32768 /* = 65536/2 */
-#define MINUS_INFINITY_GAIN 0
-
-/* Number of channels for different Speed Modes */
-#define MADI_SS_CHANNELS 64
-#define MADI_DS_CHANNELS 32
-#define MADI_QS_CHANNELS 16
-
-#define RAYDAT_SS_CHANNELS 36
-#define RAYDAT_DS_CHANNELS 20
-#define RAYDAT_QS_CHANNELS 12
-
-#define AIO_IN_SS_CHANNELS 14
-#define AIO_IN_DS_CHANNELS 10
-#define AIO_IN_QS_CHANNELS 8
-#define AIO_OUT_SS_CHANNELS 16
-#define AIO_OUT_DS_CHANNELS 12
-#define AIO_OUT_QS_CHANNELS 10
-
-#define AES32_CHANNELS 16
-
-/* the size of a substream (1 mono data stream) */
-#define HDSPM_CHANNEL_BUFFER_SAMPLES (16*1024)
-#define HDSPM_CHANNEL_BUFFER_BYTES (4*HDSPM_CHANNEL_BUFFER_SAMPLES)
-
-/* the size of the area we need to allocate for DMA transfers. the
- size is the same regardless of the number of channels, and
- also the latency to use.
- for one direction !!!
-*/
-#define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES)
-#define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024)
-
-#define HDSPM_RAYDAT_REV 211
-#define HDSPM_AIO_REV 212
-#define HDSPM_MADIFACE_REV 213
-
-/* speed factor modes */
-#define HDSPM_SPEED_SINGLE 0
-#define HDSPM_SPEED_DOUBLE 1
-#define HDSPM_SPEED_QUAD 2
-
-/* names for speed modes */
-static char *hdspm_speed_names[] = { "single", "double", "quad" };
-
-static char *texts_autosync_aes_tco[] = { "Word Clock",
- "AES1", "AES2", "AES3", "AES4",
- "AES5", "AES6", "AES7", "AES8",
- "TCO" };
-static char *texts_autosync_aes[] = { "Word Clock",
- "AES1", "AES2", "AES3", "AES4",
- "AES5", "AES6", "AES7", "AES8" };
-static char *texts_autosync_madi_tco[] = { "Word Clock",
- "MADI", "TCO", "Sync In" };
-static char *texts_autosync_madi[] = { "Word Clock",
- "MADI", "Sync In" };
-
-static char *texts_autosync_raydat_tco[] = {
- "Word Clock",
- "ADAT 1", "ADAT 2", "ADAT 3", "ADAT 4",
- "AES", "SPDIF", "TCO", "Sync In"
-};
-static char *texts_autosync_raydat[] = {
- "Word Clock",
- "ADAT 1", "ADAT 2", "ADAT 3", "ADAT 4",
- "AES", "SPDIF", "Sync In"
-};
-static char *texts_autosync_aio_tco[] = {
- "Word Clock",
- "ADAT", "AES", "SPDIF", "TCO", "Sync In"
-};
-static char *texts_autosync_aio[] = { "Word Clock",
- "ADAT", "AES", "SPDIF", "Sync In" };
-
-static char *texts_freq[] = {
- "No Lock",
- "32 kHz",
- "44.1 kHz",
- "48 kHz",
- "64 kHz",
- "88.2 kHz",
- "96 kHz",
- "128 kHz",
- "176.4 kHz",
- "192 kHz"
-};
-
-static char *texts_ports_madi[] = {
- "MADI.1", "MADI.2", "MADI.3", "MADI.4", "MADI.5", "MADI.6",
- "MADI.7", "MADI.8", "MADI.9", "MADI.10", "MADI.11", "MADI.12",
- "MADI.13", "MADI.14", "MADI.15", "MADI.16", "MADI.17", "MADI.18",
- "MADI.19", "MADI.20", "MADI.21", "MADI.22", "MADI.23", "MADI.24",
- "MADI.25", "MADI.26", "MADI.27", "MADI.28", "MADI.29", "MADI.30",
- "MADI.31", "MADI.32", "MADI.33", "MADI.34", "MADI.35", "MADI.36",
- "MADI.37", "MADI.38", "MADI.39", "MADI.40", "MADI.41", "MADI.42",
- "MADI.43", "MADI.44", "MADI.45", "MADI.46", "MADI.47", "MADI.48",
- "MADI.49", "MADI.50", "MADI.51", "MADI.52", "MADI.53", "MADI.54",
- "MADI.55", "MADI.56", "MADI.57", "MADI.58", "MADI.59", "MADI.60",
- "MADI.61", "MADI.62", "MADI.63", "MADI.64",
-};
-
-
-static char *texts_ports_raydat_ss[] = {
- "ADAT1.1", "ADAT1.2", "ADAT1.3", "ADAT1.4", "ADAT1.5", "ADAT1.6",
- "ADAT1.7", "ADAT1.8", "ADAT2.1", "ADAT2.2", "ADAT2.3", "ADAT2.4",
- "ADAT2.5", "ADAT2.6", "ADAT2.7", "ADAT2.8", "ADAT3.1", "ADAT3.2",
- "ADAT3.3", "ADAT3.4", "ADAT3.5", "ADAT3.6", "ADAT3.7", "ADAT3.8",
- "ADAT4.1", "ADAT4.2", "ADAT4.3", "ADAT4.4", "ADAT4.5", "ADAT4.6",
- "ADAT4.7", "ADAT4.8",
- "AES.L", "AES.R",
- "SPDIF.L", "SPDIF.R"
-};
-
-static char *texts_ports_raydat_ds[] = {
- "ADAT1.1", "ADAT1.2", "ADAT1.3", "ADAT1.4",
- "ADAT2.1", "ADAT2.2", "ADAT2.3", "ADAT2.4",
- "ADAT3.1", "ADAT3.2", "ADAT3.3", "ADAT3.4",
- "ADAT4.1", "ADAT4.2", "ADAT4.3", "ADAT4.4",
- "AES.L", "AES.R",
- "SPDIF.L", "SPDIF.R"
-};
-
-static char *texts_ports_raydat_qs[] = {
- "ADAT1.1", "ADAT1.2",
- "ADAT2.1", "ADAT2.2",
- "ADAT3.1", "ADAT3.2",
- "ADAT4.1", "ADAT4.2",
- "AES.L", "AES.R",
- "SPDIF.L", "SPDIF.R"
-};
-
-
-static char *texts_ports_aio_in_ss[] = {
- "Analogue.L", "Analogue.R",
- "AES.L", "AES.R",
- "SPDIF.L", "SPDIF.R",
- "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", "ADAT.5", "ADAT.6",
- "ADAT.7", "ADAT.8"
-};
-
-static char *texts_ports_aio_out_ss[] = {
- "Analogue.L", "Analogue.R",
- "AES.L", "AES.R",
- "SPDIF.L", "SPDIF.R",
- "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", "ADAT.5", "ADAT.6",
- "ADAT.7", "ADAT.8",
- "Phone.L", "Phone.R"
-};
-
-static char *texts_ports_aio_in_ds[] = {
- "Analogue.L", "Analogue.R",
- "AES.L", "AES.R",
- "SPDIF.L", "SPDIF.R",
- "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4"
-};
-
-static char *texts_ports_aio_out_ds[] = {
- "Analogue.L", "Analogue.R",
- "AES.L", "AES.R",
- "SPDIF.L", "SPDIF.R",
- "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4",
- "Phone.L", "Phone.R"
-};
-
-static char *texts_ports_aio_in_qs[] = {
- "Analogue.L", "Analogue.R",
- "AES.L", "AES.R",
- "SPDIF.L", "SPDIF.R",
- "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4"
-};
-
-static char *texts_ports_aio_out_qs[] = {
- "Analogue.L", "Analogue.R",
- "AES.L", "AES.R",
- "SPDIF.L", "SPDIF.R",
- "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4",
- "Phone.L", "Phone.R"
-};
-
-static char *texts_ports_aes32[] = {
- "AES.1", "AES.2", "AES.3", "AES.4", "AES.5", "AES.6", "AES.7",
- "AES.8", "AES.9.", "AES.10", "AES.11", "AES.12", "AES.13", "AES.14",
- "AES.15", "AES.16"
-};
-
-/* These tables map the ALSA channels 1..N to the channels that we
- need to use in order to find the relevant channel buffer. RME
- refers to this kind of mapping as between "the ADAT channel and
- the DMA channel." We index it using the logical audio channel,
- and the value is the DMA channel (i.e. channel buffer number)
- where the data for that channel can be read/written from/to.
-*/
-
-static char channel_map_unity_ss[HDSPM_MAX_CHANNELS] = {
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63
-};
-
-static char channel_map_raydat_ss[HDSPM_MAX_CHANNELS] = {
- 4, 5, 6, 7, 8, 9, 10, 11, /* ADAT 1 */
- 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT 2 */
- 20, 21, 22, 23, 24, 25, 26, 27, /* ADAT 3 */
- 28, 29, 30, 31, 32, 33, 34, 35, /* ADAT 4 */
- 0, 1, /* AES */
- 2, 3, /* SPDIF */
- -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
-};
-
-static char channel_map_raydat_ds[HDSPM_MAX_CHANNELS] = {
- 4, 5, 6, 7, /* ADAT 1 */
- 8, 9, 10, 11, /* ADAT 2 */
- 12, 13, 14, 15, /* ADAT 3 */
- 16, 17, 18, 19, /* ADAT 4 */
- 0, 1, /* AES */
- 2, 3, /* SPDIF */
- -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
-};
-
-static char channel_map_raydat_qs[HDSPM_MAX_CHANNELS] = {
- 4, 5, /* ADAT 1 */
- 6, 7, /* ADAT 2 */
- 8, 9, /* ADAT 3 */
- 10, 11, /* ADAT 4 */
- 0, 1, /* AES */
- 2, 3, /* SPDIF */
- -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
-};
-
-static char channel_map_aio_in_ss[HDSPM_MAX_CHANNELS] = {
- 0, 1, /* line in */
- 8, 9, /* aes in, */
- 10, 11, /* spdif in */
- 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT in */
- -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
-};
-
-static char channel_map_aio_out_ss[HDSPM_MAX_CHANNELS] = {
- 0, 1, /* line out */
- 8, 9, /* aes out */
- 10, 11, /* spdif out */
- 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT out */
- 6, 7, /* phone out */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
-};
-
-static char channel_map_aio_in_ds[HDSPM_MAX_CHANNELS] = {
- 0, 1, /* line in */
- 8, 9, /* aes in */
- 10, 11, /* spdif in */
- 12, 14, 16, 18, /* adat in */
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1
-};
-
-static char channel_map_aio_out_ds[HDSPM_MAX_CHANNELS] = {
- 0, 1, /* line out */
- 8, 9, /* aes out */
- 10, 11, /* spdif out */
- 12, 14, 16, 18, /* adat out */
- 6, 7, /* phone out */
- -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1
-};
-
-static char channel_map_aio_in_qs[HDSPM_MAX_CHANNELS] = {
- 0, 1, /* line in */
- 8, 9, /* aes in */
- 10, 11, /* spdif in */
- 12, 16, /* adat in */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1
-};
-
-static char channel_map_aio_out_qs[HDSPM_MAX_CHANNELS] = {
- 0, 1, /* line out */
- 8, 9, /* aes out */
- 10, 11, /* spdif out */
- 12, 16, /* adat out */
- 6, 7, /* phone out */
- -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1
-};
-
-static char channel_map_aes32[HDSPM_MAX_CHANNELS] = {
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1
-};
-
-struct hdspm_midi {
- struct hdspm *hdspm;
- int id;
- struct snd_rawmidi *rmidi;
- struct snd_rawmidi_substream *input;
- struct snd_rawmidi_substream *output;
- char istimer; /* timer in use */
- struct timer_list timer;
- spinlock_t lock;
- int pending;
- int dataIn;
- int statusIn;
- int dataOut;
- int statusOut;
- int ie;
- int irq;
-};
-
-struct hdspm_tco {
- int input;
- int framerate;
- int wordclock;
- int samplerate;
- int pull;
- int term; /* 0 = off, 1 = on */
-};
-
-struct hdspm {
- spinlock_t lock;
- /* only one playback and/or capture stream */
- struct snd_pcm_substream *capture_substream;
- struct snd_pcm_substream *playback_substream;
-
- char *card_name; /* for procinfo */
- unsigned short firmware_rev; /* dont know if relevant (yes if AES32)*/
-
- uint8_t io_type;
-
- int monitor_outs; /* set up monitoring outs init flag */
-
- u32 control_register; /* cached value */
- u32 control2_register; /* cached value */
- u32 settings_register;
-
- struct hdspm_midi midi[4];
- struct tasklet_struct midi_tasklet;
-
- size_t period_bytes;
- unsigned char ss_in_channels;
- unsigned char ds_in_channels;
- unsigned char qs_in_channels;
- unsigned char ss_out_channels;
- unsigned char ds_out_channels;
- unsigned char qs_out_channels;
-
- unsigned char max_channels_in;
- unsigned char max_channels_out;
-
- signed char *channel_map_in;
- signed char *channel_map_out;
-
- signed char *channel_map_in_ss, *channel_map_in_ds, *channel_map_in_qs;
- signed char *channel_map_out_ss, *channel_map_out_ds, *channel_map_out_qs;
-
- char **port_names_in;
- char **port_names_out;
-
- char **port_names_in_ss, **port_names_in_ds, **port_names_in_qs;
- char **port_names_out_ss, **port_names_out_ds, **port_names_out_qs;
-
- unsigned char *playback_buffer; /* suitably aligned address */
- unsigned char *capture_buffer; /* suitably aligned address */
-
- pid_t capture_pid; /* process id which uses capture */
- pid_t playback_pid; /* process id which uses capture */
- int running; /* running status */
-
- int last_external_sample_rate; /* samplerate mystic ... */
- int last_internal_sample_rate;
- int system_sample_rate;
-
- int dev; /* Hardware vars... */
- int irq;
- unsigned long port;
- void __iomem *iobase;
-
- int irq_count; /* for debug */
- int midiPorts;
-
- struct snd_card *card; /* one card */
- struct snd_pcm *pcm; /* has one pcm */
- struct snd_hwdep *hwdep; /* and a hwdep for additional ioctl */
- struct pci_dev *pci; /* and an pci info */
-
- /* Mixer vars */
- /* fast alsa mixer */
- struct snd_kcontrol *playback_mixer_ctls[HDSPM_MAX_CHANNELS];
- /* but input to much, so not used */
- struct snd_kcontrol *input_mixer_ctls[HDSPM_MAX_CHANNELS];
- /* full mixer accessible over mixer ioctl or hwdep-device */
- struct hdspm_mixer *mixer;
-
- struct hdspm_tco *tco; /* NULL if no TCO detected */
-
- char **texts_autosync;
- int texts_autosync_items;
-
- cycles_t last_interrupt;
-
- unsigned int serial;
-
- struct hdspm_peak_rms peak_rms;
-};
-
-
-static DEFINE_PCI_DEVICE_TABLE(snd_hdspm_ids) = {
- {
- .vendor = PCI_VENDOR_ID_XILINX,
- .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- .class = 0,
- .class_mask = 0,
- .driver_data = 0},
- {0,}
-};
-
-MODULE_DEVICE_TABLE(pci, snd_hdspm_ids);
-
-/* prototypes */
-static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card,
- struct hdspm * hdspm);
-static int __devinit snd_hdspm_create_pcm(struct snd_card *card,
- struct hdspm * hdspm);
-
-static inline void snd_hdspm_initialize_midi_flush(struct hdspm *hdspm);
-static int hdspm_update_simple_mixer_controls(struct hdspm *hdspm);
-static int hdspm_autosync_ref(struct hdspm *hdspm);
-static int snd_hdspm_set_defaults(struct hdspm *hdspm);
-static void hdspm_set_sgbuf(struct hdspm *hdspm,
- struct snd_pcm_substream *substream,
- unsigned int reg, int channels);
-
-static inline int HDSPM_bit2freq(int n)
-{
- static const int bit2freq_tab[] = {
- 0, 32000, 44100, 48000, 64000, 88200,
- 96000, 128000, 176400, 192000 };
- if (n < 1 || n > 9)
- return 0;
- return bit2freq_tab[n];
-}
-
-/* Write/read to/from HDSPM with Adresses in Bytes
- not words but only 32Bit writes are allowed */
-
-static inline void hdspm_write(struct hdspm * hdspm, unsigned int reg,
- unsigned int val)
-{
- writel(val, hdspm->iobase + reg);
-}
-
-static inline unsigned int hdspm_read(struct hdspm * hdspm, unsigned int reg)
-{
- return readl(hdspm->iobase + reg);
-}
-
-/* for each output channel (chan) I have an Input (in) and Playback (pb) Fader
- mixer is write only on hardware so we have to cache him for read
- each fader is a u32, but uses only the first 16 bit */
-
-static inline int hdspm_read_in_gain(struct hdspm * hdspm, unsigned int chan,
- unsigned int in)
-{
- if (chan >= HDSPM_MIXER_CHANNELS || in >= HDSPM_MIXER_CHANNELS)
- return 0;
-
- return hdspm->mixer->ch[chan].in[in];
-}
-
-static inline int hdspm_read_pb_gain(struct hdspm * hdspm, unsigned int chan,
- unsigned int pb)
-{
- if (chan >= HDSPM_MIXER_CHANNELS || pb >= HDSPM_MIXER_CHANNELS)
- return 0;
- return hdspm->mixer->ch[chan].pb[pb];
-}
-
-static int hdspm_write_in_gain(struct hdspm *hdspm, unsigned int chan,
- unsigned int in, unsigned short data)
-{
- if (chan >= HDSPM_MIXER_CHANNELS || in >= HDSPM_MIXER_CHANNELS)
- return -1;
-
- hdspm_write(hdspm,
- HDSPM_MADI_mixerBase +
- ((in + 128 * chan) * sizeof(u32)),
- (hdspm->mixer->ch[chan].in[in] = data & 0xFFFF));
- return 0;
-}
-
-static int hdspm_write_pb_gain(struct hdspm *hdspm, unsigned int chan,
- unsigned int pb, unsigned short data)
-{
- if (chan >= HDSPM_MIXER_CHANNELS || pb >= HDSPM_MIXER_CHANNELS)
- return -1;
-
- hdspm_write(hdspm,
- HDSPM_MADI_mixerBase +
- ((64 + pb + 128 * chan) * sizeof(u32)),
- (hdspm->mixer->ch[chan].pb[pb] = data & 0xFFFF));
- return 0;
-}
-
-
-/* enable DMA for specific channels, now available for DSP-MADI */
-static inline void snd_hdspm_enable_in(struct hdspm * hdspm, int i, int v)
-{
- hdspm_write(hdspm, HDSPM_inputEnableBase + (4 * i), v);
-}
-
-static inline void snd_hdspm_enable_out(struct hdspm * hdspm, int i, int v)
-{
- hdspm_write(hdspm, HDSPM_outputEnableBase + (4 * i), v);
-}
-
-/* check if same process is writing and reading */
-static int snd_hdspm_use_is_exclusive(struct hdspm *hdspm)
-{
- unsigned long flags;
- int ret = 1;
-
- spin_lock_irqsave(&hdspm->lock, flags);
- if ((hdspm->playback_pid != hdspm->capture_pid) &&
- (hdspm->playback_pid >= 0) && (hdspm->capture_pid >= 0)) {
- ret = 0;
- }
- spin_unlock_irqrestore(&hdspm->lock, flags);
- return ret;
-}
-
-/* check for external sample rate */
-static int hdspm_external_sample_rate(struct hdspm *hdspm)
-{
- unsigned int status, status2, timecode;
- int syncref, rate = 0, rate_bits;
-
- switch (hdspm->io_type) {
- case AES32:
- status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
- status = hdspm_read(hdspm, HDSPM_statusRegister);
- timecode = hdspm_read(hdspm, HDSPM_timecodeRegister);
-
- syncref = hdspm_autosync_ref(hdspm);
-
- if (syncref == HDSPM_AES32_AUTOSYNC_FROM_WORD &&
- status & HDSPM_AES32_wcLock)
- return HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF);
-
- if (syncref >= HDSPM_AES32_AUTOSYNC_FROM_AES1 &&
- syncref <= HDSPM_AES32_AUTOSYNC_FROM_AES8 &&
- status2 & (HDSPM_LockAES >>
- (syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1)))
- return HDSPM_bit2freq((timecode >> (4*(syncref-HDSPM_AES32_AUTOSYNC_FROM_AES1))) & 0xF);
- return 0;
- break;
-
- case MADIface:
- status = hdspm_read(hdspm, HDSPM_statusRegister);
-
- if (!(status & HDSPM_madiLock)) {
- rate = 0; /* no lock */
- } else {
- switch (status & (HDSPM_status1_freqMask)) {
- case HDSPM_status1_F_0*1:
- rate = 32000; break;
- case HDSPM_status1_F_0*2:
- rate = 44100; break;
- case HDSPM_status1_F_0*3:
- rate = 48000; break;
- case HDSPM_status1_F_0*4:
- rate = 64000; break;
- case HDSPM_status1_F_0*5:
- rate = 88200; break;
- case HDSPM_status1_F_0*6:
- rate = 96000; break;
- case HDSPM_status1_F_0*7:
- rate = 128000; break;
- case HDSPM_status1_F_0*8:
- rate = 176400; break;
- case HDSPM_status1_F_0*9:
- rate = 192000; break;
- default:
- rate = 0; break;
- }
- }
-
- break;
-
- case MADI:
- case AIO:
- case RayDAT:
- status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
- status = hdspm_read(hdspm, HDSPM_statusRegister);
- rate = 0;
-
- /* if wordclock has synced freq and wordclock is valid */
- if ((status2 & HDSPM_wcLock) != 0 &&
- (status2 & HDSPM_SelSyncRef0) == 0) {
-
- rate_bits = status2 & HDSPM_wcFreqMask;
-
-
- switch (rate_bits) {
- case HDSPM_wcFreq32:
- rate = 32000;
- break;
- case HDSPM_wcFreq44_1:
- rate = 44100;
- break;
- case HDSPM_wcFreq48:
- rate = 48000;
- break;
- case HDSPM_wcFreq64:
- rate = 64000;
- break;
- case HDSPM_wcFreq88_2:
- rate = 88200;
- break;
- case HDSPM_wcFreq96:
- rate = 96000;
- break;
- default:
- rate = 0;
- break;
- }
- }
-
- /* if rate detected and Syncref is Word than have it,
- * word has priority to MADI
- */
- if (rate != 0 &&
- (status2 & HDSPM_SelSyncRefMask) == HDSPM_SelSyncRef_WORD)
- return rate;
-
- /* maybe a madi input (which is taken if sel sync is madi) */
- if (status & HDSPM_madiLock) {
- rate_bits = status & HDSPM_madiFreqMask;
-
- switch (rate_bits) {
- case HDSPM_madiFreq32:
- rate = 32000;
- break;
- case HDSPM_madiFreq44_1:
- rate = 44100;
- break;
- case HDSPM_madiFreq48:
- rate = 48000;
- break;
- case HDSPM_madiFreq64:
- rate = 64000;
- break;
- case HDSPM_madiFreq88_2:
- rate = 88200;
- break;
- case HDSPM_madiFreq96:
- rate = 96000;
- break;
- case HDSPM_madiFreq128:
- rate = 128000;
- break;
- case HDSPM_madiFreq176_4:
- rate = 176400;
- break;
- case HDSPM_madiFreq192:
- rate = 192000;
- break;
- default:
- rate = 0;
- break;
- }
-
- /* QS and DS rates normally can not be detected
- * automatically by the card. Only exception is MADI
- * in 96k frame mode.
- *
- * So if we read SS values (32 .. 48k), check for
- * user-provided DS/QS bits in the control register
- * and multiply the base frequency accordingly.
- */
- if (rate <= 48000) {
- if (hdspm->control_register & HDSPM_QuadSpeed)
- rate *= 4;
- else if (hdspm->control_register &
- HDSPM_DoubleSpeed)
- rate *= 2;
- }
- }
- break;
- }
-
- return rate;
-}
-
-/* return latency in samples per period */
-static int hdspm_get_latency(struct hdspm *hdspm)
-{
- int n;
-
- n = hdspm_decode_latency(hdspm->control_register);
-
- /* Special case for new RME cards with 32 samples period size.
- * The three latency bits in the control register
- * (HDSP_LatencyMask) encode latency values of 64 samples as
- * 0, 128 samples as 1 ... 4096 samples as 6. For old cards, 7
- * denotes 8192 samples, but on new cards like RayDAT or AIO,
- * it corresponds to 32 samples.
- */
- if ((7 == n) && (RayDAT == hdspm->io_type || AIO == hdspm->io_type))
- n = -1;
-
- return 1 << (n + 6);
-}
-
-/* Latency function */
-static inline void hdspm_compute_period_size(struct hdspm *hdspm)
-{
- hdspm->period_bytes = 4 * hdspm_get_latency(hdspm);
-}
-
-
-static snd_pcm_uframes_t hdspm_hw_pointer(struct hdspm *hdspm)
-{
- int position;
-
- position = hdspm_read(hdspm, HDSPM_statusRegister);
-
- switch (hdspm->io_type) {
- case RayDAT:
- case AIO:
- position &= HDSPM_BufferPositionMask;
- position /= 4; /* Bytes per sample */
- break;
- default:
- position = (position & HDSPM_BufferID) ?
- (hdspm->period_bytes / 4) : 0;
- }
-
- return position;
-}
-
-
-static inline void hdspm_start_audio(struct hdspm * s)
-{
- s->control_register |= (HDSPM_AudioInterruptEnable | HDSPM_Start);
- hdspm_write(s, HDSPM_controlRegister, s->control_register);
-}
-
-static inline void hdspm_stop_audio(struct hdspm * s)
-{
- s->control_register &= ~(HDSPM_Start | HDSPM_AudioInterruptEnable);
- hdspm_write(s, HDSPM_controlRegister, s->control_register);
-}
-
-/* should I silence all or only opened ones ? doit all for first even is 4MB*/
-static void hdspm_silence_playback(struct hdspm *hdspm)
-{
- int i;
- int n = hdspm->period_bytes;
- void *buf = hdspm->playback_buffer;
-
- if (buf == NULL)
- return;
-
- for (i = 0; i < HDSPM_MAX_CHANNELS; i++) {
- memset(buf, 0, n);
- buf += HDSPM_CHANNEL_BUFFER_BYTES;
- }
-}
-
-static int hdspm_set_interrupt_interval(struct hdspm *s, unsigned int frames)
-{
- int n;
-
- spin_lock_irq(&s->lock);
-
- if (32 == frames) {
- /* Special case for new RME cards like RayDAT/AIO which
- * support period sizes of 32 samples. Since latency is
- * encoded in the three bits of HDSP_LatencyMask, we can only
- * have values from 0 .. 7. While 0 still means 64 samples and
- * 6 represents 4096 samples on all cards, 7 represents 8192
- * on older cards and 32 samples on new cards.
- *
- * In other words, period size in samples is calculated by
- * 2^(n+6) with n ranging from 0 .. 7.
- */
- n = 7;
- } else {
- frames >>= 7;
- n = 0;
- while (frames) {
- n++;
- frames >>= 1;
- }
- }
-
- s->control_register &= ~HDSPM_LatencyMask;
- s->control_register |= hdspm_encode_latency(n);
-
- hdspm_write(s, HDSPM_controlRegister, s->control_register);
-
- hdspm_compute_period_size(s);
-
- spin_unlock_irq(&s->lock);
-
- return 0;
-}
-
-static u64 hdspm_calc_dds_value(struct hdspm *hdspm, u64 period)
-{
- u64 freq_const;
-
- if (period == 0)
- return 0;
-
- switch (hdspm->io_type) {
- case MADI:
- case AES32:
- freq_const = 110069313433624ULL;
- break;
- case RayDAT:
- case AIO:
- freq_const = 104857600000000ULL;
- break;
- case MADIface:
- freq_const = 131072000000000ULL;
- break;
- default:
- snd_BUG();
- return 0;
- }
-
- return div_u64(freq_const, period);
-}
-
-
-static void hdspm_set_dds_value(struct hdspm *hdspm, int rate)
-{
- u64 n;
-
- if (rate >= 112000)
- rate /= 4;
- else if (rate >= 56000)
- rate /= 2;
-
- switch (hdspm->io_type) {
- case MADIface:
- n = 131072000000000ULL; /* 125 MHz */
- break;
- case MADI:
- case AES32:
- n = 110069313433624ULL; /* 105 MHz */
- break;
- case RayDAT:
- case AIO:
- n = 104857600000000ULL; /* 100 MHz */
- break;
- default:
- snd_BUG();
- return;
- }
-
- n = div_u64(n, rate);
- /* n should be less than 2^32 for being written to FREQ register */
- snd_BUG_ON(n >> 32);
- hdspm_write(hdspm, HDSPM_freqReg, (u32)n);
-}
-
-/* dummy set rate lets see what happens */
-static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
-{
- int current_rate;
- int rate_bits;
- int not_set = 0;
- int current_speed, target_speed;
-
- /* ASSUMPTION: hdspm->lock is either set, or there is no need for
- it (e.g. during module initialization).
- */
-
- if (!(hdspm->control_register & HDSPM_ClockModeMaster)) {
-
- /* SLAVE --- */
- if (called_internally) {
-
- /* request from ctl or card initialization
- just make a warning an remember setting
- for future master mode switching */
-
- snd_printk(KERN_WARNING "HDSPM: "
- "Warning: device is not running "
- "as a clock master.\n");
- not_set = 1;
- } else {
-
- /* hw_param request while in AutoSync mode */
- int external_freq =
- hdspm_external_sample_rate(hdspm);
-
- if (hdspm_autosync_ref(hdspm) ==
- HDSPM_AUTOSYNC_FROM_NONE) {
-
- snd_printk(KERN_WARNING "HDSPM: "
- "Detected no Externel Sync \n");
- not_set = 1;
-
- } else if (rate != external_freq) {
-
- snd_printk(KERN_WARNING "HDSPM: "
- "Warning: No AutoSync source for "
- "requested rate\n");
- not_set = 1;
- }
- }
- }
-
- current_rate = hdspm->system_sample_rate;
-
- /* Changing between Singe, Double and Quad speed is not
- allowed if any substreams are open. This is because such a change
- causes a shift in the location of the DMA buffers and a reduction
- in the number of available buffers.
-
- Note that a similar but essentially insoluble problem exists for
- externally-driven rate changes. All we can do is to flag rate
- changes in the read/write routines.
- */
-
- if (current_rate <= 48000)
- current_speed = HDSPM_SPEED_SINGLE;
- else if (current_rate <= 96000)
- current_speed = HDSPM_SPEED_DOUBLE;
- else
- current_speed = HDSPM_SPEED_QUAD;
-
- if (rate <= 48000)
- target_speed = HDSPM_SPEED_SINGLE;
- else if (rate <= 96000)
- target_speed = HDSPM_SPEED_DOUBLE;
- else
- target_speed = HDSPM_SPEED_QUAD;
-
- switch (rate) {
- case 32000:
- rate_bits = HDSPM_Frequency32KHz;
- break;
- case 44100:
- rate_bits = HDSPM_Frequency44_1KHz;
- break;
- case 48000:
- rate_bits = HDSPM_Frequency48KHz;
- break;
- case 64000:
- rate_bits = HDSPM_Frequency64KHz;
- break;
- case 88200:
- rate_bits = HDSPM_Frequency88_2KHz;
- break;
- case 96000:
- rate_bits = HDSPM_Frequency96KHz;
- break;
- case 128000:
- rate_bits = HDSPM_Frequency128KHz;
- break;
- case 176400:
- rate_bits = HDSPM_Frequency176_4KHz;
- break;
- case 192000:
- rate_bits = HDSPM_Frequency192KHz;
- break;
- default:
- return -EINVAL;
- }
-
- if (current_speed != target_speed
- && (hdspm->capture_pid >= 0 || hdspm->playback_pid >= 0)) {
- snd_printk
- (KERN_ERR "HDSPM: "
- "cannot change from %s speed to %s speed mode "
- "(capture PID = %d, playback PID = %d)\n",
- hdspm_speed_names[current_speed],
- hdspm_speed_names[target_speed],
- hdspm->capture_pid, hdspm->playback_pid);
- return -EBUSY;
- }
-
- hdspm->control_register &= ~HDSPM_FrequencyMask;
- hdspm->control_register |= rate_bits;
- hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
-
- /* For AES32, need to set DDS value in FREQ register
- For MADI, also apparently */
- hdspm_set_dds_value(hdspm, rate);
-
- if (AES32 == hdspm->io_type && rate != current_rate)
- hdspm_write(hdspm, HDSPM_eeprom_wr, 0);
-
- hdspm->system_sample_rate = rate;
-
- if (rate <= 48000) {
- hdspm->channel_map_in = hdspm->channel_map_in_ss;
- hdspm->channel_map_out = hdspm->channel_map_out_ss;
- hdspm->max_channels_in = hdspm->ss_in_channels;
- hdspm->max_channels_out = hdspm->ss_out_channels;
- hdspm->port_names_in = hdspm->port_names_in_ss;
- hdspm->port_names_out = hdspm->port_names_out_ss;
- } else if (rate <= 96000) {
- hdspm->channel_map_in = hdspm->channel_map_in_ds;
- hdspm->channel_map_out = hdspm->channel_map_out_ds;
- hdspm->max_channels_in = hdspm->ds_in_channels;
- hdspm->max_channels_out = hdspm->ds_out_channels;
- hdspm->port_names_in = hdspm->port_names_in_ds;
- hdspm->port_names_out = hdspm->port_names_out_ds;
- } else {
- hdspm->channel_map_in = hdspm->channel_map_in_qs;
- hdspm->channel_map_out = hdspm->channel_map_out_qs;
- hdspm->max_channels_in = hdspm->qs_in_channels;
- hdspm->max_channels_out = hdspm->qs_out_channels;
- hdspm->port_names_in = hdspm->port_names_in_qs;
- hdspm->port_names_out = hdspm->port_names_out_qs;
- }
-
- if (not_set != 0)
- return -1;
-
- return 0;
-}
-
-/* mainly for init to 0 on load */
-static void all_in_all_mixer(struct hdspm * hdspm, int sgain)
-{
- int i, j;
- unsigned int gain;
-
- if (sgain > UNITY_GAIN)
- gain = UNITY_GAIN;
- else if (sgain < 0)
- gain = 0;
- else
- gain = sgain;
-
- for (i = 0; i < HDSPM_MIXER_CHANNELS; i++)
- for (j = 0; j < HDSPM_MIXER_CHANNELS; j++) {
- hdspm_write_in_gain(hdspm, i, j, gain);
- hdspm_write_pb_gain(hdspm, i, j, gain);
- }
-}
-
-/*----------------------------------------------------------------------------
- MIDI
- ----------------------------------------------------------------------------*/
-
-static inline unsigned char snd_hdspm_midi_read_byte (struct hdspm *hdspm,
- int id)
-{
- /* the hardware already does the relevant bit-mask with 0xff */
- return hdspm_read(hdspm, hdspm->midi[id].dataIn);
-}
-
-static inline void snd_hdspm_midi_write_byte (struct hdspm *hdspm, int id,
- int val)
-{
- /* the hardware already does the relevant bit-mask with 0xff */
- return hdspm_write(hdspm, hdspm->midi[id].dataOut, val);
-}
-
-static inline int snd_hdspm_midi_input_available (struct hdspm *hdspm, int id)
-{
- return hdspm_read(hdspm, hdspm->midi[id].statusIn) & 0xFF;
-}
-
-static inline int snd_hdspm_midi_output_possible (struct hdspm *hdspm, int id)
-{
- int fifo_bytes_used;
-
- fifo_bytes_used = hdspm_read(hdspm, hdspm->midi[id].statusOut) & 0xFF;
-
- if (fifo_bytes_used < 128)
- return 128 - fifo_bytes_used;
- else
- return 0;
-}
-
-static void snd_hdspm_flush_midi_input(struct hdspm *hdspm, int id)
-{
- while (snd_hdspm_midi_input_available (hdspm, id))
- snd_hdspm_midi_read_byte (hdspm, id);
-}
-
-static int snd_hdspm_midi_output_write (struct hdspm_midi *hmidi)
-{
- unsigned long flags;
- int n_pending;
- int to_write;
- int i;
- unsigned char buf[128];
-
- /* Output is not interrupt driven */
-
- spin_lock_irqsave (&hmidi->lock, flags);
- if (hmidi->output &&
- !snd_rawmidi_transmit_empty (hmidi->output)) {
- n_pending = snd_hdspm_midi_output_possible (hmidi->hdspm,
- hmidi->id);
- if (n_pending > 0) {
- if (n_pending > (int)sizeof (buf))
- n_pending = sizeof (buf);
-
- to_write = snd_rawmidi_transmit (hmidi->output, buf,
- n_pending);
- if (to_write > 0) {
- for (i = 0; i < to_write; ++i)
- snd_hdspm_midi_write_byte (hmidi->hdspm,
- hmidi->id,
- buf[i]);
- }
- }
- }
- spin_unlock_irqrestore (&hmidi->lock, flags);
- return 0;
-}
-
-static int snd_hdspm_midi_input_read (struct hdspm_midi *hmidi)
-{
- unsigned char buf[128]; /* this buffer is designed to match the MIDI
- * input FIFO size
- */
- unsigned long flags;
- int n_pending;
- int i;
-
- spin_lock_irqsave (&hmidi->lock, flags);
- n_pending = snd_hdspm_midi_input_available (hmidi->hdspm, hmidi->id);
- if (n_pending > 0) {
- if (hmidi->input) {
- if (n_pending > (int)sizeof (buf))
- n_pending = sizeof (buf);
- for (i = 0; i < n_pending; ++i)
- buf[i] = snd_hdspm_midi_read_byte (hmidi->hdspm,
- hmidi->id);
- if (n_pending)
- snd_rawmidi_receive (hmidi->input, buf,
- n_pending);
- } else {
- /* flush the MIDI input FIFO */
- while (n_pending--)
- snd_hdspm_midi_read_byte (hmidi->hdspm,
- hmidi->id);
- }
- }
- hmidi->pending = 0;
- spin_unlock_irqrestore(&hmidi->lock, flags);
-
- spin_lock_irqsave(&hmidi->hdspm->lock, flags);
- hmidi->hdspm->control_register |= hmidi->ie;
- hdspm_write(hmidi->hdspm, HDSPM_controlRegister,
- hmidi->hdspm->control_register);
- spin_unlock_irqrestore(&hmidi->hdspm->lock, flags);
-
- return snd_hdspm_midi_output_write (hmidi);
-}
-
-static void
-snd_hdspm_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct hdspm *hdspm;
- struct hdspm_midi *hmidi;
- unsigned long flags;
-
- hmidi = substream->rmidi->private_data;
- hdspm = hmidi->hdspm;
-
- spin_lock_irqsave (&hdspm->lock, flags);
- if (up) {
- if (!(hdspm->control_register & hmidi->ie)) {
- snd_hdspm_flush_midi_input (hdspm, hmidi->id);
- hdspm->control_register |= hmidi->ie;
- }
- } else {
- hdspm->control_register &= ~hmidi->ie;
- }
-
- hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
- spin_unlock_irqrestore (&hdspm->lock, flags);
-}
-
-static void snd_hdspm_midi_output_timer(unsigned long data)
-{
- struct hdspm_midi *hmidi = (struct hdspm_midi *) data;
- unsigned long flags;
-
- snd_hdspm_midi_output_write(hmidi);
- spin_lock_irqsave (&hmidi->lock, flags);
-
- /* this does not bump hmidi->istimer, because the
- kernel automatically removed the timer when it
- expired, and we are now adding it back, thus
- leaving istimer wherever it was set before.
- */
-
- if (hmidi->istimer) {
- hmidi->timer.expires = 1 + jiffies;
- add_timer(&hmidi->timer);
- }
-
- spin_unlock_irqrestore (&hmidi->lock, flags);
-}
-
-static void
-snd_hdspm_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct hdspm_midi *hmidi;
- unsigned long flags;
-
- hmidi = substream->rmidi->private_data;
- spin_lock_irqsave (&hmidi->lock, flags);
- if (up) {
- if (!hmidi->istimer) {
- init_timer(&hmidi->timer);
- hmidi->timer.function = snd_hdspm_midi_output_timer;
- hmidi->timer.data = (unsigned long) hmidi;
- hmidi->timer.expires = 1 + jiffies;
- add_timer(&hmidi->timer);
- hmidi->istimer++;
- }
- } else {
- if (hmidi->istimer && --hmidi->istimer <= 0)
- del_timer (&hmidi->timer);
- }
- spin_unlock_irqrestore (&hmidi->lock, flags);
- if (up)
- snd_hdspm_midi_output_write(hmidi);
-}
-
-static int snd_hdspm_midi_input_open(struct snd_rawmidi_substream *substream)
-{
- struct hdspm_midi *hmidi;
-
- hmidi = substream->rmidi->private_data;
- spin_lock_irq (&hmidi->lock);
- snd_hdspm_flush_midi_input (hmidi->hdspm, hmidi->id);
- hmidi->input = substream;
- spin_unlock_irq (&hmidi->lock);
-
- return 0;
-}
-
-static int snd_hdspm_midi_output_open(struct snd_rawmidi_substream *substream)
-{
- struct hdspm_midi *hmidi;
-
- hmidi = substream->rmidi->private_data;
- spin_lock_irq (&hmidi->lock);
- hmidi->output = substream;
- spin_unlock_irq (&hmidi->lock);
-
- return 0;
-}
-
-static int snd_hdspm_midi_input_close(struct snd_rawmidi_substream *substream)
-{
- struct hdspm_midi *hmidi;
-
- snd_hdspm_midi_input_trigger (substream, 0);
-
- hmidi = substream->rmidi->private_data;
- spin_lock_irq (&hmidi->lock);
- hmidi->input = NULL;
- spin_unlock_irq (&hmidi->lock);
-
- return 0;
-}
-
-static int snd_hdspm_midi_output_close(struct snd_rawmidi_substream *substream)
-{
- struct hdspm_midi *hmidi;
-
- snd_hdspm_midi_output_trigger (substream, 0);
-
- hmidi = substream->rmidi->private_data;
- spin_lock_irq (&hmidi->lock);
- hmidi->output = NULL;
- spin_unlock_irq (&hmidi->lock);
-
- return 0;
-}
-
-static struct snd_rawmidi_ops snd_hdspm_midi_output =
-{
- .open = snd_hdspm_midi_output_open,
- .close = snd_hdspm_midi_output_close,
- .trigger = snd_hdspm_midi_output_trigger,
-};
-
-static struct snd_rawmidi_ops snd_hdspm_midi_input =
-{
- .open = snd_hdspm_midi_input_open,
- .close = snd_hdspm_midi_input_close,
- .trigger = snd_hdspm_midi_input_trigger,
-};
-
-static int __devinit snd_hdspm_create_midi (struct snd_card *card,
- struct hdspm *hdspm, int id)
-{
- int err;
- char buf[32];
-
- hdspm->midi[id].id = id;
- hdspm->midi[id].hdspm = hdspm;
- spin_lock_init (&hdspm->midi[id].lock);
-
- if (0 == id) {
- if (MADIface == hdspm->io_type) {
- /* MIDI-over-MADI on HDSPe MADIface */
- hdspm->midi[0].dataIn = HDSPM_midiDataIn2;
- hdspm->midi[0].statusIn = HDSPM_midiStatusIn2;
- hdspm->midi[0].dataOut = HDSPM_midiDataOut2;
- hdspm->midi[0].statusOut = HDSPM_midiStatusOut2;
- hdspm->midi[0].ie = HDSPM_Midi2InterruptEnable;
- hdspm->midi[0].irq = HDSPM_midi2IRQPending;
- } else {
- hdspm->midi[0].dataIn = HDSPM_midiDataIn0;
- hdspm->midi[0].statusIn = HDSPM_midiStatusIn0;
- hdspm->midi[0].dataOut = HDSPM_midiDataOut0;
- hdspm->midi[0].statusOut = HDSPM_midiStatusOut0;
- hdspm->midi[0].ie = HDSPM_Midi0InterruptEnable;
- hdspm->midi[0].irq = HDSPM_midi0IRQPending;
- }
- } else if (1 == id) {
- hdspm->midi[1].dataIn = HDSPM_midiDataIn1;
- hdspm->midi[1].statusIn = HDSPM_midiStatusIn1;
- hdspm->midi[1].dataOut = HDSPM_midiDataOut1;
- hdspm->midi[1].statusOut = HDSPM_midiStatusOut1;
- hdspm->midi[1].ie = HDSPM_Midi1InterruptEnable;
- hdspm->midi[1].irq = HDSPM_midi1IRQPending;
- } else if ((2 == id) && (MADI == hdspm->io_type)) {
- /* MIDI-over-MADI on HDSPe MADI */
- hdspm->midi[2].dataIn = HDSPM_midiDataIn2;
- hdspm->midi[2].statusIn = HDSPM_midiStatusIn2;
- hdspm->midi[2].dataOut = HDSPM_midiDataOut2;
- hdspm->midi[2].statusOut = HDSPM_midiStatusOut2;
- hdspm->midi[2].ie = HDSPM_Midi2InterruptEnable;
- hdspm->midi[2].irq = HDSPM_midi2IRQPending;
- } else if (2 == id) {
- /* TCO MTC, read only */
- hdspm->midi[2].dataIn = HDSPM_midiDataIn2;
- hdspm->midi[2].statusIn = HDSPM_midiStatusIn2;
- hdspm->midi[2].dataOut = -1;
- hdspm->midi[2].statusOut = -1;
- hdspm->midi[2].ie = HDSPM_Midi2InterruptEnable;
- hdspm->midi[2].irq = HDSPM_midi2IRQPendingAES;
- } else if (3 == id) {
- /* TCO MTC on HDSPe MADI */
- hdspm->midi[3].dataIn = HDSPM_midiDataIn3;
- hdspm->midi[3].statusIn = HDSPM_midiStatusIn3;
- hdspm->midi[3].dataOut = -1;
- hdspm->midi[3].statusOut = -1;
- hdspm->midi[3].ie = HDSPM_Midi3InterruptEnable;
- hdspm->midi[3].irq = HDSPM_midi3IRQPending;
- }
-
- if ((id < 2) || ((2 == id) && ((MADI == hdspm->io_type) ||
- (MADIface == hdspm->io_type)))) {
- if ((id == 0) && (MADIface == hdspm->io_type)) {
- sprintf(buf, "%s MIDIoverMADI", card->shortname);
- } else if ((id == 2) && (MADI == hdspm->io_type)) {
- sprintf(buf, "%s MIDIoverMADI", card->shortname);
- } else {
- sprintf(buf, "%s MIDI %d", card->shortname, id+1);
- }
- err = snd_rawmidi_new(card, buf, id, 1, 1,
- &hdspm->midi[id].rmidi);
- if (err < 0)
- return err;
-
- sprintf(hdspm->midi[id].rmidi->name, "%s MIDI %d",
- card->id, id+1);
- hdspm->midi[id].rmidi->private_data = &hdspm->midi[id];
-
- snd_rawmidi_set_ops(hdspm->midi[id].rmidi,
- SNDRV_RAWMIDI_STREAM_OUTPUT,
- &snd_hdspm_midi_output);
- snd_rawmidi_set_ops(hdspm->midi[id].rmidi,
- SNDRV_RAWMIDI_STREAM_INPUT,
- &snd_hdspm_midi_input);
-
- hdspm->midi[id].rmidi->info_flags |=
- SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
- } else {
- /* TCO MTC, read only */
- sprintf(buf, "%s MTC %d", card->shortname, id+1);
- err = snd_rawmidi_new(card, buf, id, 1, 1,
- &hdspm->midi[id].rmidi);
- if (err < 0)
- return err;
-
- sprintf(hdspm->midi[id].rmidi->name,
- "%s MTC %d", card->id, id+1);
- hdspm->midi[id].rmidi->private_data = &hdspm->midi[id];
-
- snd_rawmidi_set_ops(hdspm->midi[id].rmidi,
- SNDRV_RAWMIDI_STREAM_INPUT,
- &snd_hdspm_midi_input);
-
- hdspm->midi[id].rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
- }
-
- return 0;
-}
-
-
-static void hdspm_midi_tasklet(unsigned long arg)
-{
- struct hdspm *hdspm = (struct hdspm *)arg;
- int i = 0;
-
- while (i < hdspm->midiPorts) {
- if (hdspm->midi[i].pending)
- snd_hdspm_midi_input_read(&hdspm->midi[i]);
-
- i++;
- }
-}
-
-
-/*-----------------------------------------------------------------------------
- Status Interface
- ----------------------------------------------------------------------------*/
-
-/* get the system sample rate which is set */
-
-
-/**
- * Calculate the real sample rate from the
- * current DDS value.
- **/
-static int hdspm_get_system_sample_rate(struct hdspm *hdspm)
-{
- unsigned int period, rate;
-
- period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ);
- rate = hdspm_calc_dds_value(hdspm, period);
-
- return rate;
-}
-
-
-#define HDSPM_SYSTEM_SAMPLE_RATE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READ, \
- .info = snd_hdspm_info_system_sample_rate, \
- .get = snd_hdspm_get_system_sample_rate \
-}
-
-static int snd_hdspm_info_system_sample_rate(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 27000;
- uinfo->value.integer.max = 207000;
- uinfo->value.integer.step = 1;
- return 0;
-}
-
-
-static int snd_hdspm_get_system_sample_rate(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *
- ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = hdspm_get_system_sample_rate(hdspm);
- return 0;
-}
-
-
-/**
- * Returns the WordClock sample rate class for the given card.
- **/
-static int hdspm_get_wc_sample_rate(struct hdspm *hdspm)
-{
- int status;
-
- switch (hdspm->io_type) {
- case RayDAT:
- case AIO:
- status = hdspm_read(hdspm, HDSPM_RD_STATUS_1);
- return (status >> 16) & 0xF;
- break;
- default:
- break;
- }
-
-
- return 0;
-}
-
-
-/**
- * Returns the TCO sample rate class for the given card.
- **/
-static int hdspm_get_tco_sample_rate(struct hdspm *hdspm)
-{
- int status;
-
- if (hdspm->tco) {
- switch (hdspm->io_type) {
- case RayDAT:
- case AIO:
- status = hdspm_read(hdspm, HDSPM_RD_STATUS_1);
- return (status >> 20) & 0xF;
- break;
- default:
- break;
- }
- }
-
- return 0;
-}
-
-
-/**
- * Returns the SYNC_IN sample rate class for the given card.
- **/
-static int hdspm_get_sync_in_sample_rate(struct hdspm *hdspm)
-{
- int status;
-
- if (hdspm->tco) {
- switch (hdspm->io_type) {
- case RayDAT:
- case AIO:
- status = hdspm_read(hdspm, HDSPM_RD_STATUS_2);
- return (status >> 12) & 0xF;
- break;
- default:
- break;
- }
- }
-
- return 0;
-}
-
-
-/**
- * Returns the sample rate class for input source <idx> for
- * 'new style' cards like the AIO and RayDAT.
- **/
-static int hdspm_get_s1_sample_rate(struct hdspm *hdspm, unsigned int idx)
-{
- int status = hdspm_read(hdspm, HDSPM_RD_STATUS_2);
-
- return (status >> (idx*4)) & 0xF;
-}
-
-
-
-#define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .private_value = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READ, \
- .info = snd_hdspm_info_autosync_sample_rate, \
- .get = snd_hdspm_get_autosync_sample_rate \
-}
-
-
-static int snd_hdspm_info_autosync_sample_rate(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 10;
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name,
- texts_freq[uinfo->value.enumerated.item]);
- return 0;
-}
-
-
-static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *
- ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- switch (hdspm->io_type) {
- case RayDAT:
- switch (kcontrol->private_value) {
- case 0:
- ucontrol->value.enumerated.item[0] =
- hdspm_get_wc_sample_rate(hdspm);
- break;
- case 7:
- ucontrol->value.enumerated.item[0] =
- hdspm_get_tco_sample_rate(hdspm);
- break;
- case 8:
- ucontrol->value.enumerated.item[0] =
- hdspm_get_sync_in_sample_rate(hdspm);
- break;
- default:
- ucontrol->value.enumerated.item[0] =
- hdspm_get_s1_sample_rate(hdspm,
- kcontrol->private_value-1);
- }
-
- case AIO:
- switch (kcontrol->private_value) {
- case 0: /* WC */
- ucontrol->value.enumerated.item[0] =
- hdspm_get_wc_sample_rate(hdspm);
- break;
- case 4: /* TCO */
- ucontrol->value.enumerated.item[0] =
- hdspm_get_tco_sample_rate(hdspm);
- break;
- case 5: /* SYNC_IN */
- ucontrol->value.enumerated.item[0] =
- hdspm_get_sync_in_sample_rate(hdspm);
- break;
- default:
- ucontrol->value.enumerated.item[0] =
- hdspm_get_s1_sample_rate(hdspm,
- ucontrol->id.index-1);
- }
-
- case AES32:
-
- switch (kcontrol->private_value) {
- case 0: /* WC */
- ucontrol->value.enumerated.item[0] =
- hdspm_get_wc_sample_rate(hdspm);
- break;
- case 9: /* TCO */
- ucontrol->value.enumerated.item[0] =
- hdspm_get_tco_sample_rate(hdspm);
- break;
- case 10: /* SYNC_IN */
- ucontrol->value.enumerated.item[0] =
- hdspm_get_sync_in_sample_rate(hdspm);
- break;
- default: /* AES1 to AES8 */
- ucontrol->value.enumerated.item[0] =
- hdspm_get_s1_sample_rate(hdspm,
- kcontrol->private_value-1);
- break;
-
- }
- default:
- break;
- }
-
- return 0;
-}
-
-
-#define HDSPM_SYSTEM_CLOCK_MODE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
- SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
- .info = snd_hdspm_info_system_clock_mode, \
- .get = snd_hdspm_get_system_clock_mode, \
- .put = snd_hdspm_put_system_clock_mode, \
-}
-
-
-/**
- * Returns the system clock mode for the given card.
- * @returns 0 - master, 1 - slave
- **/
-static int hdspm_system_clock_mode(struct hdspm *hdspm)
-{
- switch (hdspm->io_type) {
- case AIO:
- case RayDAT:
- if (hdspm->settings_register & HDSPM_c0Master)
- return 0;
- break;
-
- default:
- if (hdspm->control_register & HDSPM_ClockModeMaster)
- return 0;
- }
-
- return 1;
-}
-
-
-/**
- * Sets the system clock mode.
- * @param mode 0 - master, 1 - slave
- **/
-static void hdspm_set_system_clock_mode(struct hdspm *hdspm, int mode)
-{
- switch (hdspm->io_type) {
- case AIO:
- case RayDAT:
- if (0 == mode)
- hdspm->settings_register |= HDSPM_c0Master;
- else
- hdspm->settings_register &= ~HDSPM_c0Master;
-
- hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register);
- break;
-
- default:
- if (0 == mode)
- hdspm->control_register |= HDSPM_ClockModeMaster;
- else
- hdspm->control_register &= ~HDSPM_ClockModeMaster;
-
- hdspm_write(hdspm, HDSPM_controlRegister,
- hdspm->control_register);
- }
-}
-
-
-static int snd_hdspm_info_system_clock_mode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = { "Master", "AutoSync" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_hdspm_get_system_clock_mode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdspm_system_clock_mode(hdspm);
- return 0;
-}
-
-static int snd_hdspm_put_system_clock_mode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- int val;
-
- if (!snd_hdspm_use_is_exclusive(hdspm))
- return -EBUSY;
-
- val = ucontrol->value.enumerated.item[0];
- if (val < 0)
- val = 0;
- else if (val > 1)
- val = 1;
-
- hdspm_set_system_clock_mode(hdspm, val);
-
- return 0;
-}
-
-
-#define HDSPM_INTERNAL_CLOCK(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdspm_info_clock_source, \
- .get = snd_hdspm_get_clock_source, \
- .put = snd_hdspm_put_clock_source \
-}
-
-
-static int hdspm_clock_source(struct hdspm * hdspm)
-{
- switch (hdspm->system_sample_rate) {
- case 32000: return 0;
- case 44100: return 1;
- case 48000: return 2;
- case 64000: return 3;
- case 88200: return 4;
- case 96000: return 5;
- case 128000: return 6;
- case 176400: return 7;
- case 192000: return 8;
- }
-
- return -1;
-}
-
-static int hdspm_set_clock_source(struct hdspm * hdspm, int mode)
-{
- int rate;
- switch (mode) {
- case 0:
- rate = 32000; break;
- case 1:
- rate = 44100; break;
- case 2:
- rate = 48000; break;
- case 3:
- rate = 64000; break;
- case 4:
- rate = 88200; break;
- case 5:
- rate = 96000; break;
- case 6:
- rate = 128000; break;
- case 7:
- rate = 176400; break;
- case 8:
- rate = 192000; break;
- default:
- rate = 48000;
- }
- hdspm_set_rate(hdspm, rate, 1);
- return 0;
-}
-
-static int snd_hdspm_info_clock_source(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 9;
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
-
- strcpy(uinfo->value.enumerated.name,
- texts_freq[uinfo->value.enumerated.item+1]);
-
- return 0;
-}
-
-static int snd_hdspm_get_clock_source(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdspm_clock_source(hdspm);
- return 0;
-}
-
-static int snd_hdspm_put_clock_source(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- int change;
- int val;
-
- if (!snd_hdspm_use_is_exclusive(hdspm))
- return -EBUSY;
- val = ucontrol->value.enumerated.item[0];
- if (val < 0)
- val = 0;
- if (val > 9)
- val = 9;
- spin_lock_irq(&hdspm->lock);
- if (val != hdspm_clock_source(hdspm))
- change = (hdspm_set_clock_source(hdspm, val) == 0) ? 1 : 0;
- else
- change = 0;
- spin_unlock_irq(&hdspm->lock);
- return change;
-}
-
-
-#define HDSPM_PREF_SYNC_REF(xname, xindex) \
-{.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
- SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
- .info = snd_hdspm_info_pref_sync_ref, \
- .get = snd_hdspm_get_pref_sync_ref, \
- .put = snd_hdspm_put_pref_sync_ref \
-}
-
-
-/**
- * Returns the current preferred sync reference setting.
- * The semantics of the return value are depending on the
- * card, please see the comments for clarification.
- **/
-static int hdspm_pref_sync_ref(struct hdspm * hdspm)
-{
- switch (hdspm->io_type) {
- case AES32:
- switch (hdspm->control_register & HDSPM_SyncRefMask) {
- case 0: return 0; /* WC */
- case HDSPM_SyncRef0: return 1; /* AES 1 */
- case HDSPM_SyncRef1: return 2; /* AES 2 */
- case HDSPM_SyncRef1+HDSPM_SyncRef0: return 3; /* AES 3 */
- case HDSPM_SyncRef2: return 4; /* AES 4 */
- case HDSPM_SyncRef2+HDSPM_SyncRef0: return 5; /* AES 5 */
- case HDSPM_SyncRef2+HDSPM_SyncRef1: return 6; /* AES 6 */
- case HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0:
- return 7; /* AES 7 */
- case HDSPM_SyncRef3: return 8; /* AES 8 */
- case HDSPM_SyncRef3+HDSPM_SyncRef0: return 9; /* TCO */
- }
- break;
-
- case MADI:
- case MADIface:
- if (hdspm->tco) {
- switch (hdspm->control_register & HDSPM_SyncRefMask) {
- case 0: return 0; /* WC */
- case HDSPM_SyncRef0: return 1; /* MADI */
- case HDSPM_SyncRef1: return 2; /* TCO */
- case HDSPM_SyncRef1+HDSPM_SyncRef0:
- return 3; /* SYNC_IN */
- }
- } else {
- switch (hdspm->control_register & HDSPM_SyncRefMask) {
- case 0: return 0; /* WC */
- case HDSPM_SyncRef0: return 1; /* MADI */
- case HDSPM_SyncRef1+HDSPM_SyncRef0:
- return 2; /* SYNC_IN */
- }
- }
- break;
-
- case RayDAT:
- if (hdspm->tco) {
- switch ((hdspm->settings_register &
- HDSPM_c0_SyncRefMask) / HDSPM_c0_SyncRef0) {
- case 0: return 0; /* WC */
- case 3: return 1; /* ADAT 1 */
- case 4: return 2; /* ADAT 2 */
- case 5: return 3; /* ADAT 3 */
- case 6: return 4; /* ADAT 4 */
- case 1: return 5; /* AES */
- case 2: return 6; /* SPDIF */
- case 9: return 7; /* TCO */
- case 10: return 8; /* SYNC_IN */
- }
- } else {
- switch ((hdspm->settings_register &
- HDSPM_c0_SyncRefMask) / HDSPM_c0_SyncRef0) {
- case 0: return 0; /* WC */
- case 3: return 1; /* ADAT 1 */
- case 4: return 2; /* ADAT 2 */
- case 5: return 3; /* ADAT 3 */
- case 6: return 4; /* ADAT 4 */
- case 1: return 5; /* AES */
- case 2: return 6; /* SPDIF */
- case 10: return 7; /* SYNC_IN */
- }
- }
-
- break;
-
- case AIO:
- if (hdspm->tco) {
- switch ((hdspm->settings_register &
- HDSPM_c0_SyncRefMask) / HDSPM_c0_SyncRef0) {
- case 0: return 0; /* WC */
- case 3: return 1; /* ADAT */
- case 1: return 2; /* AES */
- case 2: return 3; /* SPDIF */
- case 9: return 4; /* TCO */
- case 10: return 5; /* SYNC_IN */
- }
- } else {
- switch ((hdspm->settings_register &
- HDSPM_c0_SyncRefMask) / HDSPM_c0_SyncRef0) {
- case 0: return 0; /* WC */
- case 3: return 1; /* ADAT */
- case 1: return 2; /* AES */
- case 2: return 3; /* SPDIF */
- case 10: return 4; /* SYNC_IN */
- }
- }
-
- break;
- }
-
- return -1;
-}
-
-
-/**
- * Set the preferred sync reference to <pref>. The semantics
- * of <pref> are depending on the card type, see the comments
- * for clarification.
- **/
-static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref)
-{
- int p = 0;
-
- switch (hdspm->io_type) {
- case AES32:
- hdspm->control_register &= ~HDSPM_SyncRefMask;
- switch (pref) {
- case 0: /* WC */
- break;
- case 1: /* AES 1 */
- hdspm->control_register |= HDSPM_SyncRef0;
- break;
- case 2: /* AES 2 */
- hdspm->control_register |= HDSPM_SyncRef1;
- break;
- case 3: /* AES 3 */
- hdspm->control_register |=
- HDSPM_SyncRef1+HDSPM_SyncRef0;
- break;
- case 4: /* AES 4 */
- hdspm->control_register |= HDSPM_SyncRef2;
- break;
- case 5: /* AES 5 */
- hdspm->control_register |=
- HDSPM_SyncRef2+HDSPM_SyncRef0;
- break;
- case 6: /* AES 6 */
- hdspm->control_register |=
- HDSPM_SyncRef2+HDSPM_SyncRef1;
- break;
- case 7: /* AES 7 */
- hdspm->control_register |=
- HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0;
- break;
- case 8: /* AES 8 */
- hdspm->control_register |= HDSPM_SyncRef3;
- break;
- case 9: /* TCO */
- hdspm->control_register |=
- HDSPM_SyncRef3+HDSPM_SyncRef0;
- break;
- default:
- return -1;
- }
-
- break;
-
- case MADI:
- case MADIface:
- hdspm->control_register &= ~HDSPM_SyncRefMask;
- if (hdspm->tco) {
- switch (pref) {
- case 0: /* WC */
- break;
- case 1: /* MADI */
- hdspm->control_register |= HDSPM_SyncRef0;
- break;
- case 2: /* TCO */
- hdspm->control_register |= HDSPM_SyncRef1;
- break;
- case 3: /* SYNC_IN */
- hdspm->control_register |=
- HDSPM_SyncRef0+HDSPM_SyncRef1;
- break;
- default:
- return -1;
- }
- } else {
- switch (pref) {
- case 0: /* WC */
- break;
- case 1: /* MADI */
- hdspm->control_register |= HDSPM_SyncRef0;
- break;
- case 2: /* SYNC_IN */
- hdspm->control_register |=
- HDSPM_SyncRef0+HDSPM_SyncRef1;
- break;
- default:
- return -1;
- }
- }
-
- break;
-
- case RayDAT:
- if (hdspm->tco) {
- switch (pref) {
- case 0: p = 0; break; /* WC */
- case 1: p = 3; break; /* ADAT 1 */
- case 2: p = 4; break; /* ADAT 2 */
- case 3: p = 5; break; /* ADAT 3 */
- case 4: p = 6; break; /* ADAT 4 */
- case 5: p = 1; break; /* AES */
- case 6: p = 2; break; /* SPDIF */
- case 7: p = 9; break; /* TCO */
- case 8: p = 10; break; /* SYNC_IN */
- default: return -1;
- }
- } else {
- switch (pref) {
- case 0: p = 0; break; /* WC */
- case 1: p = 3; break; /* ADAT 1 */
- case 2: p = 4; break; /* ADAT 2 */
- case 3: p = 5; break; /* ADAT 3 */
- case 4: p = 6; break; /* ADAT 4 */
- case 5: p = 1; break; /* AES */
- case 6: p = 2; break; /* SPDIF */
- case 7: p = 10; break; /* SYNC_IN */
- default: return -1;
- }
- }
- break;
-
- case AIO:
- if (hdspm->tco) {
- switch (pref) {
- case 0: p = 0; break; /* WC */
- case 1: p = 3; break; /* ADAT */
- case 2: p = 1; break; /* AES */
- case 3: p = 2; break; /* SPDIF */
- case 4: p = 9; break; /* TCO */
- case 5: p = 10; break; /* SYNC_IN */
- default: return -1;
- }
- } else {
- switch (pref) {
- case 0: p = 0; break; /* WC */
- case 1: p = 3; break; /* ADAT */
- case 2: p = 1; break; /* AES */
- case 3: p = 2; break; /* SPDIF */
- case 4: p = 10; break; /* SYNC_IN */
- default: return -1;
- }
- }
- break;
- }
-
- switch (hdspm->io_type) {
- case RayDAT:
- case AIO:
- hdspm->settings_register &= ~HDSPM_c0_SyncRefMask;
- hdspm->settings_register |= HDSPM_c0_SyncRef0 * p;
- hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register);
- break;
-
- case MADI:
- case MADIface:
- case AES32:
- hdspm_write(hdspm, HDSPM_controlRegister,
- hdspm->control_register);
- }
-
- return 0;
-}
-
-
-static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = hdspm->texts_autosync_items;
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
-
- strcpy(uinfo->value.enumerated.name,
- hdspm->texts_autosync[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-static int snd_hdspm_get_pref_sync_ref(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- int psf = hdspm_pref_sync_ref(hdspm);
-
- if (psf >= 0) {
- ucontrol->value.enumerated.item[0] = psf;
- return 0;
- }
-
- return -1;
-}
-
-static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- int val, change = 0;
-
- if (!snd_hdspm_use_is_exclusive(hdspm))
- return -EBUSY;
-
- val = ucontrol->value.enumerated.item[0];
-
- if (val < 0)
- val = 0;
- else if (val >= hdspm->texts_autosync_items)
- val = hdspm->texts_autosync_items-1;
-
- spin_lock_irq(&hdspm->lock);
- if (val != hdspm_pref_sync_ref(hdspm))
- change = (0 == hdspm_set_pref_sync_ref(hdspm, val)) ? 1 : 0;
-
- spin_unlock_irq(&hdspm->lock);
- return change;
-}
-
-
-#define HDSPM_AUTOSYNC_REF(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READ, \
- .info = snd_hdspm_info_autosync_ref, \
- .get = snd_hdspm_get_autosync_ref, \
-}
-
-static int hdspm_autosync_ref(struct hdspm *hdspm)
-{
- if (AES32 == hdspm->io_type) {
- unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister);
- unsigned int syncref =
- (status >> HDSPM_AES32_syncref_bit) & 0xF;
- if (syncref == 0)
- return HDSPM_AES32_AUTOSYNC_FROM_WORD;
- if (syncref <= 8)
- return syncref;
- return HDSPM_AES32_AUTOSYNC_FROM_NONE;
- } else if (MADI == hdspm->io_type) {
- /* This looks at the autosync selected sync reference */
- unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
-
- switch (status2 & HDSPM_SelSyncRefMask) {
- case HDSPM_SelSyncRef_WORD:
- return HDSPM_AUTOSYNC_FROM_WORD;
- case HDSPM_SelSyncRef_MADI:
- return HDSPM_AUTOSYNC_FROM_MADI;
- case HDSPM_SelSyncRef_TCO:
- return HDSPM_AUTOSYNC_FROM_TCO;
- case HDSPM_SelSyncRef_SyncIn:
- return HDSPM_AUTOSYNC_FROM_SYNC_IN;
- case HDSPM_SelSyncRef_NVALID:
- return HDSPM_AUTOSYNC_FROM_NONE;
- default:
- return 0;
- }
-
- }
- return 0;
-}
-
-
-static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- if (AES32 == hdspm->io_type) {
- static char *texts[] = { "WordClock", "AES1", "AES2", "AES3",
- "AES4", "AES5", "AES6", "AES7", "AES8", "None"};
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 10;
- if (uinfo->value.enumerated.item >=
- uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- } else if (MADI == hdspm->io_type) {
- static char *texts[] = {"Word Clock", "MADI", "TCO",
- "Sync In", "None" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 5;
- if (uinfo->value.enumerated.item >=
- uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- }
- return 0;
-}
-
-static int snd_hdspm_get_autosync_ref(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdspm_autosync_ref(hdspm);
- return 0;
-}
-
-
-#define HDSPM_LINE_OUT(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdspm_info_line_out, \
- .get = snd_hdspm_get_line_out, \
- .put = snd_hdspm_put_line_out \
-}
-
-static int hdspm_line_out(struct hdspm * hdspm)
-{
- return (hdspm->control_register & HDSPM_LineOut) ? 1 : 0;
-}
-
-
-static int hdspm_set_line_output(struct hdspm * hdspm, int out)
-{
- if (out)
- hdspm->control_register |= HDSPM_LineOut;
- else
- hdspm->control_register &= ~HDSPM_LineOut;
- hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
-
- return 0;
-}
-
-#define snd_hdspm_info_line_out snd_ctl_boolean_mono_info
-
-static int snd_hdspm_get_line_out(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&hdspm->lock);
- ucontrol->value.integer.value[0] = hdspm_line_out(hdspm);
- spin_unlock_irq(&hdspm->lock);
- return 0;
-}
-
-static int snd_hdspm_put_line_out(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_hdspm_use_is_exclusive(hdspm))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdspm->lock);
- change = (int) val != hdspm_line_out(hdspm);
- hdspm_set_line_output(hdspm, val);
- spin_unlock_irq(&hdspm->lock);
- return change;
-}
-
-
-#define HDSPM_TX_64(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdspm_info_tx_64, \
- .get = snd_hdspm_get_tx_64, \
- .put = snd_hdspm_put_tx_64 \
-}
-
-static int hdspm_tx_64(struct hdspm * hdspm)
-{
- return (hdspm->control_register & HDSPM_TX_64ch) ? 1 : 0;
-}
-
-static int hdspm_set_tx_64(struct hdspm * hdspm, int out)
-{
- if (out)
- hdspm->control_register |= HDSPM_TX_64ch;
- else
- hdspm->control_register &= ~HDSPM_TX_64ch;
- hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
-
- return 0;
-}
-
-#define snd_hdspm_info_tx_64 snd_ctl_boolean_mono_info
-
-static int snd_hdspm_get_tx_64(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&hdspm->lock);
- ucontrol->value.integer.value[0] = hdspm_tx_64(hdspm);
- spin_unlock_irq(&hdspm->lock);
- return 0;
-}
-
-static int snd_hdspm_put_tx_64(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_hdspm_use_is_exclusive(hdspm))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdspm->lock);
- change = (int) val != hdspm_tx_64(hdspm);
- hdspm_set_tx_64(hdspm, val);
- spin_unlock_irq(&hdspm->lock);
- return change;
-}
-
-
-#define HDSPM_C_TMS(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdspm_info_c_tms, \
- .get = snd_hdspm_get_c_tms, \
- .put = snd_hdspm_put_c_tms \
-}
-
-static int hdspm_c_tms(struct hdspm * hdspm)
-{
- return (hdspm->control_register & HDSPM_clr_tms) ? 1 : 0;
-}
-
-static int hdspm_set_c_tms(struct hdspm * hdspm, int out)
-{
- if (out)
- hdspm->control_register |= HDSPM_clr_tms;
- else
- hdspm->control_register &= ~HDSPM_clr_tms;
- hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
-
- return 0;
-}
-
-#define snd_hdspm_info_c_tms snd_ctl_boolean_mono_info
-
-static int snd_hdspm_get_c_tms(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&hdspm->lock);
- ucontrol->value.integer.value[0] = hdspm_c_tms(hdspm);
- spin_unlock_irq(&hdspm->lock);
- return 0;
-}
-
-static int snd_hdspm_put_c_tms(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_hdspm_use_is_exclusive(hdspm))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdspm->lock);
- change = (int) val != hdspm_c_tms(hdspm);
- hdspm_set_c_tms(hdspm, val);
- spin_unlock_irq(&hdspm->lock);
- return change;
-}
-
-
-#define HDSPM_SAFE_MODE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdspm_info_safe_mode, \
- .get = snd_hdspm_get_safe_mode, \
- .put = snd_hdspm_put_safe_mode \
-}
-
-static int hdspm_safe_mode(struct hdspm * hdspm)
-{
- return (hdspm->control_register & HDSPM_AutoInp) ? 1 : 0;
-}
-
-static int hdspm_set_safe_mode(struct hdspm * hdspm, int out)
-{
- if (out)
- hdspm->control_register |= HDSPM_AutoInp;
- else
- hdspm->control_register &= ~HDSPM_AutoInp;
- hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
-
- return 0;
-}
-
-#define snd_hdspm_info_safe_mode snd_ctl_boolean_mono_info
-
-static int snd_hdspm_get_safe_mode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&hdspm->lock);
- ucontrol->value.integer.value[0] = hdspm_safe_mode(hdspm);
- spin_unlock_irq(&hdspm->lock);
- return 0;
-}
-
-static int snd_hdspm_put_safe_mode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_hdspm_use_is_exclusive(hdspm))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdspm->lock);
- change = (int) val != hdspm_safe_mode(hdspm);
- hdspm_set_safe_mode(hdspm, val);
- spin_unlock_irq(&hdspm->lock);
- return change;
-}
-
-
-#define HDSPM_EMPHASIS(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdspm_info_emphasis, \
- .get = snd_hdspm_get_emphasis, \
- .put = snd_hdspm_put_emphasis \
-}
-
-static int hdspm_emphasis(struct hdspm * hdspm)
-{
- return (hdspm->control_register & HDSPM_Emphasis) ? 1 : 0;
-}
-
-static int hdspm_set_emphasis(struct hdspm * hdspm, int emp)
-{
- if (emp)
- hdspm->control_register |= HDSPM_Emphasis;
- else
- hdspm->control_register &= ~HDSPM_Emphasis;
- hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
-
- return 0;
-}
-
-#define snd_hdspm_info_emphasis snd_ctl_boolean_mono_info
-
-static int snd_hdspm_get_emphasis(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&hdspm->lock);
- ucontrol->value.enumerated.item[0] = hdspm_emphasis(hdspm);
- spin_unlock_irq(&hdspm->lock);
- return 0;
-}
-
-static int snd_hdspm_put_emphasis(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_hdspm_use_is_exclusive(hdspm))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdspm->lock);
- change = (int) val != hdspm_emphasis(hdspm);
- hdspm_set_emphasis(hdspm, val);
- spin_unlock_irq(&hdspm->lock);
- return change;
-}
-
-
-#define HDSPM_DOLBY(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdspm_info_dolby, \
- .get = snd_hdspm_get_dolby, \
- .put = snd_hdspm_put_dolby \
-}
-
-static int hdspm_dolby(struct hdspm * hdspm)
-{
- return (hdspm->control_register & HDSPM_Dolby) ? 1 : 0;
-}
-
-static int hdspm_set_dolby(struct hdspm * hdspm, int dol)
-{
- if (dol)
- hdspm->control_register |= HDSPM_Dolby;
- else
- hdspm->control_register &= ~HDSPM_Dolby;
- hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
-
- return 0;
-}
-
-#define snd_hdspm_info_dolby snd_ctl_boolean_mono_info
-
-static int snd_hdspm_get_dolby(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&hdspm->lock);
- ucontrol->value.enumerated.item[0] = hdspm_dolby(hdspm);
- spin_unlock_irq(&hdspm->lock);
- return 0;
-}
-
-static int snd_hdspm_put_dolby(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_hdspm_use_is_exclusive(hdspm))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdspm->lock);
- change = (int) val != hdspm_dolby(hdspm);
- hdspm_set_dolby(hdspm, val);
- spin_unlock_irq(&hdspm->lock);
- return change;
-}
-
-
-#define HDSPM_PROFESSIONAL(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdspm_info_professional, \
- .get = snd_hdspm_get_professional, \
- .put = snd_hdspm_put_professional \
-}
-
-static int hdspm_professional(struct hdspm * hdspm)
-{
- return (hdspm->control_register & HDSPM_Professional) ? 1 : 0;
-}
-
-static int hdspm_set_professional(struct hdspm * hdspm, int dol)
-{
- if (dol)
- hdspm->control_register |= HDSPM_Professional;
- else
- hdspm->control_register &= ~HDSPM_Professional;
- hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
-
- return 0;
-}
-
-#define snd_hdspm_info_professional snd_ctl_boolean_mono_info
-
-static int snd_hdspm_get_professional(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&hdspm->lock);
- ucontrol->value.enumerated.item[0] = hdspm_professional(hdspm);
- spin_unlock_irq(&hdspm->lock);
- return 0;
-}
-
-static int snd_hdspm_put_professional(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_hdspm_use_is_exclusive(hdspm))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdspm->lock);
- change = (int) val != hdspm_professional(hdspm);
- hdspm_set_professional(hdspm, val);
- spin_unlock_irq(&hdspm->lock);
- return change;
-}
-
-#define HDSPM_INPUT_SELECT(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdspm_info_input_select, \
- .get = snd_hdspm_get_input_select, \
- .put = snd_hdspm_put_input_select \
-}
-
-static int hdspm_input_select(struct hdspm * hdspm)
-{
- return (hdspm->control_register & HDSPM_InputSelect0) ? 1 : 0;
-}
-
-static int hdspm_set_input_select(struct hdspm * hdspm, int out)
-{
- if (out)
- hdspm->control_register |= HDSPM_InputSelect0;
- else
- hdspm->control_register &= ~HDSPM_InputSelect0;
- hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
-
- return 0;
-}
-
-static int snd_hdspm_info_input_select(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = { "optical", "coaxial" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-static int snd_hdspm_get_input_select(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&hdspm->lock);
- ucontrol->value.enumerated.item[0] = hdspm_input_select(hdspm);
- spin_unlock_irq(&hdspm->lock);
- return 0;
-}
-
-static int snd_hdspm_put_input_select(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_hdspm_use_is_exclusive(hdspm))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdspm->lock);
- change = (int) val != hdspm_input_select(hdspm);
- hdspm_set_input_select(hdspm, val);
- spin_unlock_irq(&hdspm->lock);
- return change;
-}
-
-
-#define HDSPM_DS_WIRE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdspm_info_ds_wire, \
- .get = snd_hdspm_get_ds_wire, \
- .put = snd_hdspm_put_ds_wire \
-}
-
-static int hdspm_ds_wire(struct hdspm * hdspm)
-{
- return (hdspm->control_register & HDSPM_DS_DoubleWire) ? 1 : 0;
-}
-
-static int hdspm_set_ds_wire(struct hdspm * hdspm, int ds)
-{
- if (ds)
- hdspm->control_register |= HDSPM_DS_DoubleWire;
- else
- hdspm->control_register &= ~HDSPM_DS_DoubleWire;
- hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
-
- return 0;
-}
-
-static int snd_hdspm_info_ds_wire(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = { "Single", "Double" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-static int snd_hdspm_get_ds_wire(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&hdspm->lock);
- ucontrol->value.enumerated.item[0] = hdspm_ds_wire(hdspm);
- spin_unlock_irq(&hdspm->lock);
- return 0;
-}
-
-static int snd_hdspm_put_ds_wire(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_hdspm_use_is_exclusive(hdspm))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&hdspm->lock);
- change = (int) val != hdspm_ds_wire(hdspm);
- hdspm_set_ds_wire(hdspm, val);
- spin_unlock_irq(&hdspm->lock);
- return change;
-}
-
-
-#define HDSPM_QS_WIRE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdspm_info_qs_wire, \
- .get = snd_hdspm_get_qs_wire, \
- .put = snd_hdspm_put_qs_wire \
-}
-
-static int hdspm_qs_wire(struct hdspm * hdspm)
-{
- if (hdspm->control_register & HDSPM_QS_DoubleWire)
- return 1;
- if (hdspm->control_register & HDSPM_QS_QuadWire)
- return 2;
- return 0;
-}
-
-static int hdspm_set_qs_wire(struct hdspm * hdspm, int mode)
-{
- hdspm->control_register &= ~(HDSPM_QS_DoubleWire | HDSPM_QS_QuadWire);
- switch (mode) {
- case 0:
- break;
- case 1:
- hdspm->control_register |= HDSPM_QS_DoubleWire;
- break;
- case 2:
- hdspm->control_register |= HDSPM_QS_QuadWire;
- break;
- }
- hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
-
- return 0;
-}
-
-static int snd_hdspm_info_qs_wire(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = { "Single", "Double", "Quad" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-static int snd_hdspm_get_qs_wire(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&hdspm->lock);
- ucontrol->value.enumerated.item[0] = hdspm_qs_wire(hdspm);
- spin_unlock_irq(&hdspm->lock);
- return 0;
-}
-
-static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- int change;
- int val;
-
- if (!snd_hdspm_use_is_exclusive(hdspm))
- return -EBUSY;
- val = ucontrol->value.integer.value[0];
- if (val < 0)
- val = 0;
- if (val > 2)
- val = 2;
- spin_lock_irq(&hdspm->lock);
- change = val != hdspm_qs_wire(hdspm);
- hdspm_set_qs_wire(hdspm, val);
- spin_unlock_irq(&hdspm->lock);
- return change;
-}
-
-#define HDSPM_MADI_SPEEDMODE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_hdspm_info_madi_speedmode, \
- .get = snd_hdspm_get_madi_speedmode, \
- .put = snd_hdspm_put_madi_speedmode \
-}
-
-static int hdspm_madi_speedmode(struct hdspm *hdspm)
-{
- if (hdspm->control_register & HDSPM_QuadSpeed)
- return 2;
- if (hdspm->control_register & HDSPM_DoubleSpeed)
- return 1;
- return 0;
-}
-
-static int hdspm_set_madi_speedmode(struct hdspm *hdspm, int mode)
-{
- hdspm->control_register &= ~(HDSPM_DoubleSpeed | HDSPM_QuadSpeed);
- switch (mode) {
- case 0:
- break;
- case 1:
- hdspm->control_register |= HDSPM_DoubleSpeed;
- break;
- case 2:
- hdspm->control_register |= HDSPM_QuadSpeed;
- break;
- }
- hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
-
- return 0;
-}
-
-static int snd_hdspm_info_madi_speedmode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = { "Single", "Double", "Quad" };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-static int snd_hdspm_get_madi_speedmode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&hdspm->lock);
- ucontrol->value.enumerated.item[0] = hdspm_madi_speedmode(hdspm);
- spin_unlock_irq(&hdspm->lock);
- return 0;
-}
-
-static int snd_hdspm_put_madi_speedmode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- int change;
- int val;
-
- if (!snd_hdspm_use_is_exclusive(hdspm))
- return -EBUSY;
- val = ucontrol->value.integer.value[0];
- if (val < 0)
- val = 0;
- if (val > 2)
- val = 2;
- spin_lock_irq(&hdspm->lock);
- change = val != hdspm_madi_speedmode(hdspm);
- hdspm_set_madi_speedmode(hdspm, val);
- spin_unlock_irq(&hdspm->lock);
- return change;
-}
-
-#define HDSPM_MIXER(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
- .name = xname, \
- .index = xindex, \
- .device = 0, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
- SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
- .info = snd_hdspm_info_mixer, \
- .get = snd_hdspm_get_mixer, \
- .put = snd_hdspm_put_mixer \
-}
-
-static int snd_hdspm_info_mixer(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 3;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 65535;
- uinfo->value.integer.step = 1;
- return 0;
-}
-
-static int snd_hdspm_get_mixer(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- int source;
- int destination;
-
- source = ucontrol->value.integer.value[0];
- if (source < 0)
- source = 0;
- else if (source >= 2 * HDSPM_MAX_CHANNELS)
- source = 2 * HDSPM_MAX_CHANNELS - 1;
-
- destination = ucontrol->value.integer.value[1];
- if (destination < 0)
- destination = 0;
- else if (destination >= HDSPM_MAX_CHANNELS)
- destination = HDSPM_MAX_CHANNELS - 1;
-
- spin_lock_irq(&hdspm->lock);
- if (source >= HDSPM_MAX_CHANNELS)
- ucontrol->value.integer.value[2] =
- hdspm_read_pb_gain(hdspm, destination,
- source - HDSPM_MAX_CHANNELS);
- else
- ucontrol->value.integer.value[2] =
- hdspm_read_in_gain(hdspm, destination, source);
-
- spin_unlock_irq(&hdspm->lock);
-
- return 0;
-}
-
-static int snd_hdspm_put_mixer(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- int change;
- int source;
- int destination;
- int gain;
-
- if (!snd_hdspm_use_is_exclusive(hdspm))
- return -EBUSY;
-
- source = ucontrol->value.integer.value[0];
- destination = ucontrol->value.integer.value[1];
-
- if (source < 0 || source >= 2 * HDSPM_MAX_CHANNELS)
- return -1;
- if (destination < 0 || destination >= HDSPM_MAX_CHANNELS)
- return -1;
-
- gain = ucontrol->value.integer.value[2];
-
- spin_lock_irq(&hdspm->lock);
-
- if (source >= HDSPM_MAX_CHANNELS)
- change = gain != hdspm_read_pb_gain(hdspm, destination,
- source -
- HDSPM_MAX_CHANNELS);
- else
- change = gain != hdspm_read_in_gain(hdspm, destination,
- source);
-
- if (change) {
- if (source >= HDSPM_MAX_CHANNELS)
- hdspm_write_pb_gain(hdspm, destination,
- source - HDSPM_MAX_CHANNELS,
- gain);
- else
- hdspm_write_in_gain(hdspm, destination, source,
- gain);
- }
- spin_unlock_irq(&hdspm->lock);
-
- return change;
-}
-
-/* The simple mixer control(s) provide gain control for the
- basic 1:1 mappings of playback streams to output
- streams.
-*/
-
-#define HDSPM_PLAYBACK_MIXER \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE | \
- SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
- .info = snd_hdspm_info_playback_mixer, \
- .get = snd_hdspm_get_playback_mixer, \
- .put = snd_hdspm_put_playback_mixer \
-}
-
-static int snd_hdspm_info_playback_mixer(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 64;
- uinfo->value.integer.step = 1;
- return 0;
-}
-
-static int snd_hdspm_get_playback_mixer(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- int channel;
-
- channel = ucontrol->id.index - 1;
-
- if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS))
- return -EINVAL;
-
- spin_lock_irq(&hdspm->lock);
- ucontrol->value.integer.value[0] =
- (hdspm_read_pb_gain(hdspm, channel, channel)*64)/UNITY_GAIN;
- spin_unlock_irq(&hdspm->lock);
-
- return 0;
-}
-
-static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- int change;
- int channel;
- int gain;
-
- if (!snd_hdspm_use_is_exclusive(hdspm))
- return -EBUSY;
-
- channel = ucontrol->id.index - 1;
-
- if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS))
- return -EINVAL;
-
- gain = ucontrol->value.integer.value[0]*UNITY_GAIN/64;
-
- spin_lock_irq(&hdspm->lock);
- change =
- gain != hdspm_read_pb_gain(hdspm, channel,
- channel);
- if (change)
- hdspm_write_pb_gain(hdspm, channel, channel,
- gain);
- spin_unlock_irq(&hdspm->lock);
- return change;
-}
-
-#define HDSPM_SYNC_CHECK(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .private_value = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
- .info = snd_hdspm_info_sync_check, \
- .get = snd_hdspm_get_sync_check \
-}
-
-
-static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = { "No Lock", "Lock", "Sync", "N/A" };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 4;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int hdspm_wc_sync_check(struct hdspm *hdspm)
-{
- int status, status2;
-
- switch (hdspm->io_type) {
- case AES32:
- status = hdspm_read(hdspm, HDSPM_statusRegister);
- if (status & HDSPM_wcSync)
- return 2;
- else if (status & HDSPM_wcLock)
- return 1;
- return 0;
- break;
-
- case MADI:
- status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
- if (status2 & HDSPM_wcLock) {
- if (status2 & HDSPM_wcSync)
- return 2;
- else
- return 1;
- }
- return 0;
- break;
-
- case RayDAT:
- case AIO:
- status = hdspm_read(hdspm, HDSPM_statusRegister);
-
- if (status & 0x2000000)
- return 2;
- else if (status & 0x1000000)
- return 1;
- return 0;
-
- break;
-
- case MADIface:
- break;
- }
-
-
- return 3;
-}
-
-
-static int hdspm_madi_sync_check(struct hdspm *hdspm)
-{
- int status = hdspm_read(hdspm, HDSPM_statusRegister);
- if (status & HDSPM_madiLock) {
- if (status & HDSPM_madiSync)
- return 2;
- else
- return 1;
- }
- return 0;
-}
-
-
-static int hdspm_s1_sync_check(struct hdspm *hdspm, int idx)
-{
- int status, lock, sync;
-
- status = hdspm_read(hdspm, HDSPM_RD_STATUS_1);
-
- lock = (status & (0x1<<idx)) ? 1 : 0;
- sync = (status & (0x100<<idx)) ? 1 : 0;
-
- if (lock && sync)
- return 2;
- else if (lock)
- return 1;
- return 0;
-}
-
-
-static int hdspm_sync_in_sync_check(struct hdspm *hdspm)
-{
- int status, lock = 0, sync = 0;
-
- switch (hdspm->io_type) {
- case RayDAT:
- case AIO:
- status = hdspm_read(hdspm, HDSPM_RD_STATUS_3);
- lock = (status & 0x400) ? 1 : 0;
- sync = (status & 0x800) ? 1 : 0;
- break;
-
- case MADI:
- case AES32:
- status = hdspm_read(hdspm, HDSPM_statusRegister2);
- lock = (status & HDSPM_syncInLock) ? 1 : 0;
- sync = (status & HDSPM_syncInSync) ? 1 : 0;
- break;
-
- case MADIface:
- break;
- }
-
- if (lock && sync)
- return 2;
- else if (lock)
- return 1;
-
- return 0;
-}
-
-static int hdspm_aes_sync_check(struct hdspm *hdspm, int idx)
-{
- int status2, lock, sync;
- status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
-
- lock = (status2 & (0x0080 >> idx)) ? 1 : 0;
- sync = (status2 & (0x8000 >> idx)) ? 1 : 0;
-
- if (sync)
- return 2;
- else if (lock)
- return 1;
- return 0;
-}
-
-
-static int hdspm_tco_sync_check(struct hdspm *hdspm)
-{
- int status;
-
- if (hdspm->tco) {
- switch (hdspm->io_type) {
- case MADI:
- case AES32:
- status = hdspm_read(hdspm, HDSPM_statusRegister);
- if (status & HDSPM_tcoLock) {
- if (status & HDSPM_tcoSync)
- return 2;
- else
- return 1;
- }
- return 0;
-
- break;
-
- case RayDAT:
- case AIO:
- status = hdspm_read(hdspm, HDSPM_RD_STATUS_1);
-
- if (status & 0x8000000)
- return 2; /* Sync */
- if (status & 0x4000000)
- return 1; /* Lock */
- return 0; /* No signal */
- break;
-
- default:
- break;
- }
- }
-
- return 3; /* N/A */
-}
-
-
-static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- int val = -1;
-
- switch (hdspm->io_type) {
- case RayDAT:
- switch (kcontrol->private_value) {
- case 0: /* WC */
- val = hdspm_wc_sync_check(hdspm); break;
- case 7: /* TCO */
- val = hdspm_tco_sync_check(hdspm); break;
- case 8: /* SYNC IN */
- val = hdspm_sync_in_sync_check(hdspm); break;
- default:
- val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1);
- }
-
- case AIO:
- switch (kcontrol->private_value) {
- case 0: /* WC */
- val = hdspm_wc_sync_check(hdspm); break;
- case 4: /* TCO */
- val = hdspm_tco_sync_check(hdspm); break;
- case 5: /* SYNC IN */
- val = hdspm_sync_in_sync_check(hdspm); break;
- default:
- val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1);
- }
-
- case MADI:
- switch (kcontrol->private_value) {
- case 0: /* WC */
- val = hdspm_wc_sync_check(hdspm); break;
- case 1: /* MADI */
- val = hdspm_madi_sync_check(hdspm); break;
- case 2: /* TCO */
- val = hdspm_tco_sync_check(hdspm); break;
- case 3: /* SYNC_IN */
- val = hdspm_sync_in_sync_check(hdspm); break;
- }
-
- case MADIface:
- val = hdspm_madi_sync_check(hdspm); /* MADI */
- break;
-
- case AES32:
- switch (kcontrol->private_value) {
- case 0: /* WC */
- val = hdspm_wc_sync_check(hdspm); break;
- case 9: /* TCO */
- val = hdspm_tco_sync_check(hdspm); break;
- case 10 /* SYNC IN */:
- val = hdspm_sync_in_sync_check(hdspm); break;
- default: /* AES1 to AES8 */
- val = hdspm_aes_sync_check(hdspm,
- kcontrol->private_value-1);
- }
-
- }
-
- if (-1 == val)
- val = 3;
-
- ucontrol->value.enumerated.item[0] = val;
- return 0;
-}
-
-
-
-/**
- * TCO controls
- **/
-static void hdspm_tco_write(struct hdspm *hdspm)
-{
- unsigned int tc[4] = { 0, 0, 0, 0};
-
- switch (hdspm->tco->input) {
- case 0:
- tc[2] |= HDSPM_TCO2_set_input_MSB;
- break;
- case 1:
- tc[2] |= HDSPM_TCO2_set_input_LSB;
- break;
- default:
- break;
- }
-
- switch (hdspm->tco->framerate) {
- case 1:
- tc[1] |= HDSPM_TCO1_LTC_Format_LSB;
- break;
- case 2:
- tc[1] |= HDSPM_TCO1_LTC_Format_MSB;
- break;
- case 3:
- tc[1] |= HDSPM_TCO1_LTC_Format_MSB +
- HDSPM_TCO1_set_drop_frame_flag;
- break;
- case 4:
- tc[1] |= HDSPM_TCO1_LTC_Format_LSB +
- HDSPM_TCO1_LTC_Format_MSB;
- break;
- case 5:
- tc[1] |= HDSPM_TCO1_LTC_Format_LSB +
- HDSPM_TCO1_LTC_Format_MSB +
- HDSPM_TCO1_set_drop_frame_flag;
- break;
- default:
- break;
- }
-
- switch (hdspm->tco->wordclock) {
- case 1:
- tc[2] |= HDSPM_TCO2_WCK_IO_ratio_LSB;
- break;
- case 2:
- tc[2] |= HDSPM_TCO2_WCK_IO_ratio_MSB;
- break;
- default:
- break;
- }
-
- switch (hdspm->tco->samplerate) {
- case 1:
- tc[2] |= HDSPM_TCO2_set_freq;
- break;
- case 2:
- tc[2] |= HDSPM_TCO2_set_freq_from_app;
- break;
- default:
- break;
- }
-
- switch (hdspm->tco->pull) {
- case 1:
- tc[2] |= HDSPM_TCO2_set_pull_up;
- break;
- case 2:
- tc[2] |= HDSPM_TCO2_set_pull_down;
- break;
- case 3:
- tc[2] |= HDSPM_TCO2_set_pull_up + HDSPM_TCO2_set_01_4;
- break;
- case 4:
- tc[2] |= HDSPM_TCO2_set_pull_down + HDSPM_TCO2_set_01_4;
- break;
- default:
- break;
- }
-
- if (1 == hdspm->tco->term) {
- tc[2] |= HDSPM_TCO2_set_term_75R;
- }
-
- hdspm_write(hdspm, HDSPM_WR_TCO, tc[0]);
- hdspm_write(hdspm, HDSPM_WR_TCO+4, tc[1]);
- hdspm_write(hdspm, HDSPM_WR_TCO+8, tc[2]);
- hdspm_write(hdspm, HDSPM_WR_TCO+12, tc[3]);
-}
-
-
-#define HDSPM_TCO_SAMPLE_RATE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
- SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
- .info = snd_hdspm_info_tco_sample_rate, \
- .get = snd_hdspm_get_tco_sample_rate, \
- .put = snd_hdspm_put_tco_sample_rate \
-}
-
-static int snd_hdspm_info_tco_sample_rate(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = { "44.1 kHz", "48 kHz" };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
-
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-static int snd_hdspm_get_tco_sample_rate(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdspm->tco->samplerate;
-
- return 0;
-}
-
-static int snd_hdspm_put_tco_sample_rate(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- if (hdspm->tco->samplerate != ucontrol->value.enumerated.item[0]) {
- hdspm->tco->samplerate = ucontrol->value.enumerated.item[0];
-
- hdspm_tco_write(hdspm);
-
- return 1;
- }
-
- return 0;
-}
-
-
-#define HDSPM_TCO_PULL(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
- SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
- .info = snd_hdspm_info_tco_pull, \
- .get = snd_hdspm_get_tco_pull, \
- .put = snd_hdspm_put_tco_pull \
-}
-
-static int snd_hdspm_info_tco_pull(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = { "0", "+ 0.1 %", "- 0.1 %", "+ 4 %", "- 4 %" };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 5;
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
-
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-static int snd_hdspm_get_tco_pull(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdspm->tco->pull;
-
- return 0;
-}
-
-static int snd_hdspm_put_tco_pull(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- if (hdspm->tco->pull != ucontrol->value.enumerated.item[0]) {
- hdspm->tco->pull = ucontrol->value.enumerated.item[0];
-
- hdspm_tco_write(hdspm);
-
- return 1;
- }
-
- return 0;
-}
-
-#define HDSPM_TCO_WCK_CONVERSION(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
- SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
- .info = snd_hdspm_info_tco_wck_conversion, \
- .get = snd_hdspm_get_tco_wck_conversion, \
- .put = snd_hdspm_put_tco_wck_conversion \
-}
-
-static int snd_hdspm_info_tco_wck_conversion(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = { "1:1", "44.1 -> 48", "48 -> 44.1" };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
-
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-static int snd_hdspm_get_tco_wck_conversion(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdspm->tco->wordclock;
-
- return 0;
-}
-
-static int snd_hdspm_put_tco_wck_conversion(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- if (hdspm->tco->wordclock != ucontrol->value.enumerated.item[0]) {
- hdspm->tco->wordclock = ucontrol->value.enumerated.item[0];
-
- hdspm_tco_write(hdspm);
-
- return 1;
- }
-
- return 0;
-}
-
-
-#define HDSPM_TCO_FRAME_RATE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
- SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
- .info = snd_hdspm_info_tco_frame_rate, \
- .get = snd_hdspm_get_tco_frame_rate, \
- .put = snd_hdspm_put_tco_frame_rate \
-}
-
-static int snd_hdspm_info_tco_frame_rate(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = { "24 fps", "25 fps", "29.97fps",
- "29.97 dfps", "30 fps", "30 dfps" };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 6;
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
-
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-static int snd_hdspm_get_tco_frame_rate(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdspm->tco->framerate;
-
- return 0;
-}
-
-static int snd_hdspm_put_tco_frame_rate(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- if (hdspm->tco->framerate != ucontrol->value.enumerated.item[0]) {
- hdspm->tco->framerate = ucontrol->value.enumerated.item[0];
-
- hdspm_tco_write(hdspm);
-
- return 1;
- }
-
- return 0;
-}
-
-
-#define HDSPM_TCO_SYNC_SOURCE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
- SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
- .info = snd_hdspm_info_tco_sync_source, \
- .get = snd_hdspm_get_tco_sync_source, \
- .put = snd_hdspm_put_tco_sync_source \
-}
-
-static int snd_hdspm_info_tco_sync_source(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[] = { "LTC", "Video", "WCK" };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
-
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item =
- uinfo->value.enumerated.items - 1;
-
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-static int snd_hdspm_get_tco_sync_source(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdspm->tco->input;
-
- return 0;
-}
-
-static int snd_hdspm_put_tco_sync_source(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- if (hdspm->tco->input != ucontrol->value.enumerated.item[0]) {
- hdspm->tco->input = ucontrol->value.enumerated.item[0];
-
- hdspm_tco_write(hdspm);
-
- return 1;
- }
-
- return 0;
-}
-
-
-#define HDSPM_TCO_WORD_TERM(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
- SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
- .info = snd_hdspm_info_tco_word_term, \
- .get = snd_hdspm_get_tco_word_term, \
- .put = snd_hdspm_put_tco_word_term \
-}
-
-static int snd_hdspm_info_tco_word_term(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
-
- return 0;
-}
-
-
-static int snd_hdspm_get_tco_word_term(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.enumerated.item[0] = hdspm->tco->term;
-
- return 0;
-}
-
-
-static int snd_hdspm_put_tco_word_term(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
- if (hdspm->tco->term != ucontrol->value.enumerated.item[0]) {
- hdspm->tco->term = ucontrol->value.enumerated.item[0];
-
- hdspm_tco_write(hdspm);
-
- return 1;
- }
-
- return 0;
-}
-
-
-
-
-static struct snd_kcontrol_new snd_hdspm_controls_madi[] = {
- HDSPM_MIXER("Mixer", 0),
- HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
- HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
- HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
- HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
- HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
- HDSPM_SYNC_CHECK("WC SyncCheck", 0),
- HDSPM_SYNC_CHECK("MADI SyncCheck", 1),
- HDSPM_SYNC_CHECK("TCO SyncCHeck", 2),
- HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 3),
- HDSPM_LINE_OUT("Line Out", 0),
- HDSPM_TX_64("TX 64 channels mode", 0),
- HDSPM_C_TMS("Clear Track Marker", 0),
- HDSPM_SAFE_MODE("Safe Mode", 0),
- HDSPM_INPUT_SELECT("Input Select", 0),
- HDSPM_MADI_SPEEDMODE("MADI Speed Mode", 0)
-};
-
-
-static struct snd_kcontrol_new snd_hdspm_controls_madiface[] = {
- HDSPM_MIXER("Mixer", 0),
- HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
- HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
- HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
- HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
- HDSPM_SYNC_CHECK("MADI SyncCheck", 0),
- HDSPM_TX_64("TX 64 channels mode", 0),
- HDSPM_C_TMS("Clear Track Marker", 0),
- HDSPM_SAFE_MODE("Safe Mode", 0),
- HDSPM_MADI_SPEEDMODE("MADI Speed Mode", 0)
-};
-
-static struct snd_kcontrol_new snd_hdspm_controls_aio[] = {
- HDSPM_MIXER("Mixer", 0),
- HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
- HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
- HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
- HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
- HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
- HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
- HDSPM_SYNC_CHECK("WC SyncCheck", 0),
- HDSPM_SYNC_CHECK("AES SyncCheck", 1),
- HDSPM_SYNC_CHECK("SPDIF SyncCheck", 2),
- HDSPM_SYNC_CHECK("ADAT SyncCheck", 3),
- HDSPM_SYNC_CHECK("TCO SyncCheck", 4),
- HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 5),
- HDSPM_AUTOSYNC_SAMPLE_RATE("WC Frequency", 0),
- HDSPM_AUTOSYNC_SAMPLE_RATE("AES Frequency", 1),
- HDSPM_AUTOSYNC_SAMPLE_RATE("SPDIF Frequency", 2),
- HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT Frequency", 3),
- HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 4),
- HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 5)
-
- /*
- HDSPM_INPUT_SELECT("Input Select", 0),
- HDSPM_SPDIF_OPTICAL("SPDIF Out Optical", 0),
- HDSPM_PROFESSIONAL("SPDIF Out Professional", 0);
- HDSPM_SPDIF_IN("SPDIF In", 0);
- HDSPM_BREAKOUT_CABLE("Breakout Cable", 0);
- HDSPM_INPUT_LEVEL("Input Level", 0);
- HDSPM_OUTPUT_LEVEL("Output Level", 0);
- HDSPM_PHONES("Phones", 0);
- */
-};
-
-static struct snd_kcontrol_new snd_hdspm_controls_raydat[] = {
- HDSPM_MIXER("Mixer", 0),
- HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
- HDSPM_SYSTEM_CLOCK_MODE("Clock Mode", 0),
- HDSPM_PREF_SYNC_REF("Pref Sync Ref", 0),
- HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
- HDSPM_SYNC_CHECK("WC SyncCheck", 0),
- HDSPM_SYNC_CHECK("AES SyncCheck", 1),
- HDSPM_SYNC_CHECK("SPDIF SyncCheck", 2),
- HDSPM_SYNC_CHECK("ADAT1 SyncCheck", 3),
- HDSPM_SYNC_CHECK("ADAT2 SyncCheck", 4),
- HDSPM_SYNC_CHECK("ADAT3 SyncCheck", 5),
- HDSPM_SYNC_CHECK("ADAT4 SyncCheck", 6),
- HDSPM_SYNC_CHECK("TCO SyncCheck", 7),
- HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 8),
- HDSPM_AUTOSYNC_SAMPLE_RATE("WC Frequency", 0),
- HDSPM_AUTOSYNC_SAMPLE_RATE("AES Frequency", 1),
- HDSPM_AUTOSYNC_SAMPLE_RATE("SPDIF Frequency", 2),
- HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT1 Frequency", 3),
- HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT2 Frequency", 4),
- HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT3 Frequency", 5),
- HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT4 Frequency", 6),
- HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 7),
- HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 8)
-};
-
-static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = {
- HDSPM_MIXER("Mixer", 0),
- HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
- HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
- HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
- HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
- HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
- HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
- HDSPM_SYNC_CHECK("WC Sync Check", 0),
- HDSPM_SYNC_CHECK("AES1 Sync Check", 1),
- HDSPM_SYNC_CHECK("AES2 Sync Check", 2),
- HDSPM_SYNC_CHECK("AES3 Sync Check", 3),
- HDSPM_SYNC_CHECK("AES4 Sync Check", 4),
- HDSPM_SYNC_CHECK("AES5 Sync Check", 5),
- HDSPM_SYNC_CHECK("AES6 Sync Check", 6),
- HDSPM_SYNC_CHECK("AES7 Sync Check", 7),
- HDSPM_SYNC_CHECK("AES8 Sync Check", 8),
- HDSPM_SYNC_CHECK("TCO Sync Check", 9),
- HDSPM_SYNC_CHECK("SYNC IN Sync Check", 10),
- HDSPM_AUTOSYNC_SAMPLE_RATE("WC Frequency", 0),
- HDSPM_AUTOSYNC_SAMPLE_RATE("AES1 Frequency", 1),
- HDSPM_AUTOSYNC_SAMPLE_RATE("AES2 Frequency", 2),
- HDSPM_AUTOSYNC_SAMPLE_RATE("AES3 Frequency", 3),
- HDSPM_AUTOSYNC_SAMPLE_RATE("AES4 Frequency", 4),
- HDSPM_AUTOSYNC_SAMPLE_RATE("AES5 Frequency", 5),
- HDSPM_AUTOSYNC_SAMPLE_RATE("AES6 Frequency", 6),
- HDSPM_AUTOSYNC_SAMPLE_RATE("AES7 Frequency", 7),
- HDSPM_AUTOSYNC_SAMPLE_RATE("AES8 Frequency", 8),
- HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 9),
- HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 10),
- HDSPM_LINE_OUT("Line Out", 0),
- HDSPM_EMPHASIS("Emphasis", 0),
- HDSPM_DOLBY("Non Audio", 0),
- HDSPM_PROFESSIONAL("Professional", 0),
- HDSPM_C_TMS("Clear Track Marker", 0),
- HDSPM_DS_WIRE("Double Speed Wire Mode", 0),
- HDSPM_QS_WIRE("Quad Speed Wire Mode", 0),
-};
-
-
-
-/* Control elements for the optional TCO module */
-static struct snd_kcontrol_new snd_hdspm_controls_tco[] = {
- HDSPM_TCO_SAMPLE_RATE("TCO Sample Rate", 0),
- HDSPM_TCO_PULL("TCO Pull", 0),
- HDSPM_TCO_WCK_CONVERSION("TCO WCK Conversion", 0),
- HDSPM_TCO_FRAME_RATE("TCO Frame Rate", 0),
- HDSPM_TCO_SYNC_SOURCE("TCO Sync Source", 0),
- HDSPM_TCO_WORD_TERM("TCO Word Term", 0)
-};
-
-
-static struct snd_kcontrol_new snd_hdspm_playback_mixer = HDSPM_PLAYBACK_MIXER;
-
-
-static int hdspm_update_simple_mixer_controls(struct hdspm * hdspm)
-{
- int i;
-
- for (i = hdspm->ds_out_channels; i < hdspm->ss_out_channels; ++i) {
- if (hdspm->system_sample_rate > 48000) {
- hdspm->playback_mixer_ctls[i]->vd[0].access =
- SNDRV_CTL_ELEM_ACCESS_INACTIVE |
- SNDRV_CTL_ELEM_ACCESS_READ |
- SNDRV_CTL_ELEM_ACCESS_VOLATILE;
- } else {
- hdspm->playback_mixer_ctls[i]->vd[0].access =
- SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_VOLATILE;
- }
- snd_ctl_notify(hdspm->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO,
- &hdspm->playback_mixer_ctls[i]->id);
- }
-
- return 0;
-}
-
-
-static int snd_hdspm_create_controls(struct snd_card *card,
- struct hdspm *hdspm)
-{
- unsigned int idx, limit;
- int err;
- struct snd_kcontrol *kctl;
- struct snd_kcontrol_new *list = NULL;
-
- switch (hdspm->io_type) {
- case MADI:
- list = snd_hdspm_controls_madi;
- limit = ARRAY_SIZE(snd_hdspm_controls_madi);
- break;
- case MADIface:
- list = snd_hdspm_controls_madiface;
- limit = ARRAY_SIZE(snd_hdspm_controls_madiface);
- break;
- case AIO:
- list = snd_hdspm_controls_aio;
- limit = ARRAY_SIZE(snd_hdspm_controls_aio);
- break;
- case RayDAT:
- list = snd_hdspm_controls_raydat;
- limit = ARRAY_SIZE(snd_hdspm_controls_raydat);
- break;
- case AES32:
- list = snd_hdspm_controls_aes32;
- limit = ARRAY_SIZE(snd_hdspm_controls_aes32);
- break;
- }
-
- if (NULL != list) {
- for (idx = 0; idx < limit; idx++) {
- err = snd_ctl_add(card,
- snd_ctl_new1(&list[idx], hdspm));
- if (err < 0)
- return err;
- }
- }
-
-
- /* create simple 1:1 playback mixer controls */
- snd_hdspm_playback_mixer.name = "Chn";
- if (hdspm->system_sample_rate >= 128000) {
- limit = hdspm->qs_out_channels;
- } else if (hdspm->system_sample_rate >= 64000) {
- limit = hdspm->ds_out_channels;
- } else {
- limit = hdspm->ss_out_channels;
- }
- for (idx = 0; idx < limit; ++idx) {
- snd_hdspm_playback_mixer.index = idx + 1;
- kctl = snd_ctl_new1(&snd_hdspm_playback_mixer, hdspm);
- err = snd_ctl_add(card, kctl);
- if (err < 0)
- return err;
- hdspm->playback_mixer_ctls[idx] = kctl;
- }
-
-
- if (hdspm->tco) {
- /* add tco control elements */
- list = snd_hdspm_controls_tco;
- limit = ARRAY_SIZE(snd_hdspm_controls_tco);
- for (idx = 0; idx < limit; idx++) {
- err = snd_ctl_add(card,
- snd_ctl_new1(&list[idx], hdspm));
- if (err < 0)
- return err;
- }
- }
-
- return 0;
-}
-
-/*------------------------------------------------------------
- /proc interface
- ------------------------------------------------------------*/
-
-static void
-snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
- struct snd_info_buffer *buffer)
-{
- struct hdspm *hdspm = entry->private_data;
- unsigned int status, status2, control, freq;
-
- char *pref_sync_ref;
- char *autosync_ref;
- char *system_clock_mode;
- char *insel;
- int x, x2;
-
- /* TCO stuff */
- int a, ltc, frames, seconds, minutes, hours;
- unsigned int period;
- u64 freq_const = 0;
- u32 rate;
-
- status = hdspm_read(hdspm, HDSPM_statusRegister);
- status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
- control = hdspm->control_register;
- freq = hdspm_read(hdspm, HDSPM_timecodeRegister);
-
- snd_iprintf(buffer, "%s (Card #%d) Rev.%x Status2first3bits: %x\n",
- hdspm->card_name, hdspm->card->number + 1,
- hdspm->firmware_rev,
- (status2 & HDSPM_version0) |
- (status2 & HDSPM_version1) | (status2 &
- HDSPM_version2));
-
- snd_iprintf(buffer, "HW Serial: 0x%06x%06x\n",
- (hdspm_read(hdspm, HDSPM_midiStatusIn1)>>8) & 0xFFFFFF,
- hdspm->serial);
-
- snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
- hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase);
-
- snd_iprintf(buffer, "--- System ---\n");
-
- snd_iprintf(buffer,
- "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n",
- status & HDSPM_audioIRQPending,
- (status & HDSPM_midi0IRQPending) ? 1 : 0,
- (status & HDSPM_midi1IRQPending) ? 1 : 0,
- hdspm->irq_count);
- snd_iprintf(buffer,
- "HW pointer: id = %d, rawptr = %d (%d->%d) "
- "estimated= %ld (bytes)\n",
- ((status & HDSPM_BufferID) ? 1 : 0),
- (status & HDSPM_BufferPositionMask),
- (status & HDSPM_BufferPositionMask) %
- (2 * (int)hdspm->period_bytes),
- ((status & HDSPM_BufferPositionMask) - 64) %
- (2 * (int)hdspm->period_bytes),
- (long) hdspm_hw_pointer(hdspm) * 4);
-
- snd_iprintf(buffer,
- "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n",
- hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF,
- hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF,
- hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF,
- hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF);
- snd_iprintf(buffer,
- "MIDIoverMADI FIFO: In=0x%x, Out=0x%x \n",
- hdspm_read(hdspm, HDSPM_midiStatusIn2) & 0xFF,
- hdspm_read(hdspm, HDSPM_midiStatusOut2) & 0xFF);
- snd_iprintf(buffer,
- "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, "
- "status2=0x%x\n",
- hdspm->control_register, hdspm->control2_register,
- status, status2);
- if (status & HDSPM_tco_detect) {
- snd_iprintf(buffer, "TCO module detected.\n");
- a = hdspm_read(hdspm, HDSPM_RD_TCO+4);
- if (a & HDSPM_TCO1_LTC_Input_valid) {
- snd_iprintf(buffer, " LTC valid, ");
- switch (a & (HDSPM_TCO1_LTC_Format_LSB |
- HDSPM_TCO1_LTC_Format_MSB)) {
- case 0:
- snd_iprintf(buffer, "24 fps, ");
- break;
- case HDSPM_TCO1_LTC_Format_LSB:
- snd_iprintf(buffer, "25 fps, ");
- break;
- case HDSPM_TCO1_LTC_Format_MSB:
- snd_iprintf(buffer, "29.97 fps, ");
- break;
- default:
- snd_iprintf(buffer, "30 fps, ");
- break;
- }
- if (a & HDSPM_TCO1_set_drop_frame_flag) {
- snd_iprintf(buffer, "drop frame\n");
- } else {
- snd_iprintf(buffer, "full frame\n");
- }
- } else {
- snd_iprintf(buffer, " no LTC\n");
- }
- if (a & HDSPM_TCO1_Video_Input_Format_NTSC) {
- snd_iprintf(buffer, " Video: NTSC\n");
- } else if (a & HDSPM_TCO1_Video_Input_Format_PAL) {
- snd_iprintf(buffer, " Video: PAL\n");
- } else {
- snd_iprintf(buffer, " No video\n");
- }
- if (a & HDSPM_TCO1_TCO_lock) {
- snd_iprintf(buffer, " Sync: lock\n");
- } else {
- snd_iprintf(buffer, " Sync: no lock\n");
- }
-
- switch (hdspm->io_type) {
- case MADI:
- case AES32:
- freq_const = 110069313433624ULL;
- break;
- case RayDAT:
- case AIO:
- freq_const = 104857600000000ULL;
- break;
- case MADIface:
- break; /* no TCO possible */
- }
-
- period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ);
- snd_iprintf(buffer, " period: %u\n", period);
-
-
- /* rate = freq_const/period; */
- rate = div_u64(freq_const, period);
-
- if (control & HDSPM_QuadSpeed) {
- rate *= 4;
- } else if (control & HDSPM_DoubleSpeed) {
- rate *= 2;
- }
-
- snd_iprintf(buffer, " Frequency: %u Hz\n",
- (unsigned int) rate);
-
- ltc = hdspm_read(hdspm, HDSPM_RD_TCO);
- frames = ltc & 0xF;
- ltc >>= 4;
- frames += (ltc & 0x3) * 10;
- ltc >>= 4;
- seconds = ltc & 0xF;
- ltc >>= 4;
- seconds += (ltc & 0x7) * 10;
- ltc >>= 4;
- minutes = ltc & 0xF;
- ltc >>= 4;
- minutes += (ltc & 0x7) * 10;
- ltc >>= 4;
- hours = ltc & 0xF;
- ltc >>= 4;
- hours += (ltc & 0x3) * 10;
- snd_iprintf(buffer,
- " LTC In: %02d:%02d:%02d:%02d\n",
- hours, minutes, seconds, frames);
-
- } else {
- snd_iprintf(buffer, "No TCO module detected.\n");
- }
-
- snd_iprintf(buffer, "--- Settings ---\n");
-
- x = hdspm_get_latency(hdspm);
-
- snd_iprintf(buffer,
- "Size (Latency): %d samples (2 periods of %lu bytes)\n",
- x, (unsigned long) hdspm->period_bytes);
-
- snd_iprintf(buffer, "Line out: %s\n",
- (hdspm->control_register & HDSPM_LineOut) ? "on " : "off");
-
- switch (hdspm->control_register & HDSPM_InputMask) {
- case HDSPM_InputOptical:
- insel = "Optical";
- break;
- case HDSPM_InputCoaxial:
- insel = "Coaxial";
- break;
- default:
- insel = "Unkown";
- }
-
- snd_iprintf(buffer,
- "ClearTrackMarker = %s, Transmit in %s Channel Mode, "
- "Auto Input %s\n",
- (hdspm->control_register & HDSPM_clr_tms) ? "on" : "off",
- (hdspm->control_register & HDSPM_TX_64ch) ? "64" : "56",
- (hdspm->control_register & HDSPM_AutoInp) ? "on" : "off");
-
-
- if (!(hdspm->control_register & HDSPM_ClockModeMaster))
- system_clock_mode = "AutoSync";
- else
- system_clock_mode = "Master";
- snd_iprintf(buffer, "AutoSync Reference: %s\n", system_clock_mode);
-
- switch (hdspm_pref_sync_ref(hdspm)) {
- case HDSPM_SYNC_FROM_WORD:
- pref_sync_ref = "Word Clock";
- break;
- case HDSPM_SYNC_FROM_MADI:
- pref_sync_ref = "MADI Sync";
- break;
- case HDSPM_SYNC_FROM_TCO:
- pref_sync_ref = "TCO";
- break;
- case HDSPM_SYNC_FROM_SYNC_IN:
- pref_sync_ref = "Sync In";
- break;
- default:
- pref_sync_ref = "XXXX Clock";
- break;
- }
- snd_iprintf(buffer, "Preferred Sync Reference: %s\n",
- pref_sync_ref);
-
- snd_iprintf(buffer, "System Clock Frequency: %d\n",
- hdspm->system_sample_rate);
-
-
- snd_iprintf(buffer, "--- Status:\n");
-
- x = status & HDSPM_madiSync;
- x2 = status2 & HDSPM_wcSync;
-
- snd_iprintf(buffer, "Inputs MADI=%s, WordClock=%s\n",
- (status & HDSPM_madiLock) ? (x ? "Sync" : "Lock") :
- "NoLock",
- (status2 & HDSPM_wcLock) ? (x2 ? "Sync" : "Lock") :
- "NoLock");
-
- switch (hdspm_autosync_ref(hdspm)) {
- case HDSPM_AUTOSYNC_FROM_SYNC_IN:
- autosync_ref = "Sync In";
- break;
- case HDSPM_AUTOSYNC_FROM_TCO:
- autosync_ref = "TCO";
- break;
- case HDSPM_AUTOSYNC_FROM_WORD:
- autosync_ref = "Word Clock";
- break;
- case HDSPM_AUTOSYNC_FROM_MADI:
- autosync_ref = "MADI Sync";
- break;
- case HDSPM_AUTOSYNC_FROM_NONE:
- autosync_ref = "Input not valid";
- break;
- default:
- autosync_ref = "---";
- break;
- }
- snd_iprintf(buffer,
- "AutoSync: Reference= %s, Freq=%d (MADI = %d, Word = %d)\n",
- autosync_ref, hdspm_external_sample_rate(hdspm),
- (status & HDSPM_madiFreqMask) >> 22,
- (status2 & HDSPM_wcFreqMask) >> 5);
-
- snd_iprintf(buffer, "Input: %s, Mode=%s\n",
- (status & HDSPM_AB_int) ? "Coax" : "Optical",
- (status & HDSPM_RX_64ch) ? "64 channels" :
- "56 channels");
-
- snd_iprintf(buffer, "\n");
-}
-
-static void
-snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
- struct snd_info_buffer *buffer)
-{
- struct hdspm *hdspm = entry->private_data;
- unsigned int status;
- unsigned int status2;
- unsigned int timecode;
- int pref_syncref;
- char *autosync_ref;
- int x;
-
- status = hdspm_read(hdspm, HDSPM_statusRegister);
- status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
- timecode = hdspm_read(hdspm, HDSPM_timecodeRegister);
-
- snd_iprintf(buffer, "%s (Card #%d) Rev.%x\n",
- hdspm->card_name, hdspm->card->number + 1,
- hdspm->firmware_rev);
-
- snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
- hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase);
-
- snd_iprintf(buffer, "--- System ---\n");
-
- snd_iprintf(buffer,
- "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n",
- status & HDSPM_audioIRQPending,
- (status & HDSPM_midi0IRQPending) ? 1 : 0,
- (status & HDSPM_midi1IRQPending) ? 1 : 0,
- hdspm->irq_count);
- snd_iprintf(buffer,
- "HW pointer: id = %d, rawptr = %d (%d->%d) "
- "estimated= %ld (bytes)\n",
- ((status & HDSPM_BufferID) ? 1 : 0),
- (status & HDSPM_BufferPositionMask),
- (status & HDSPM_BufferPositionMask) %
- (2 * (int)hdspm->period_bytes),
- ((status & HDSPM_BufferPositionMask) - 64) %
- (2 * (int)hdspm->period_bytes),
- (long) hdspm_hw_pointer(hdspm) * 4);
-
- snd_iprintf(buffer,
- "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n",
- hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF,
- hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF,
- hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF,
- hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF);
- snd_iprintf(buffer,
- "MIDIoverMADI FIFO: In=0x%x, Out=0x%x \n",
- hdspm_read(hdspm, HDSPM_midiStatusIn2) & 0xFF,
- hdspm_read(hdspm, HDSPM_midiStatusOut2) & 0xFF);
- snd_iprintf(buffer,
- "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, "
- "status2=0x%x\n",
- hdspm->control_register, hdspm->control2_register,
- status, status2);
-
- snd_iprintf(buffer, "--- Settings ---\n");
-
- x = hdspm_get_latency(hdspm);
-
- snd_iprintf(buffer,
- "Size (Latency): %d samples (2 periods of %lu bytes)\n",
- x, (unsigned long) hdspm->period_bytes);
-
- snd_iprintf(buffer, "Line out: %s\n",
- (hdspm->
- control_register & HDSPM_LineOut) ? "on " : "off");
-
- snd_iprintf(buffer,
- "ClearTrackMarker %s, Emphasis %s, Dolby %s\n",
- (hdspm->
- control_register & HDSPM_clr_tms) ? "on" : "off",
- (hdspm->
- control_register & HDSPM_Emphasis) ? "on" : "off",
- (hdspm->
- control_register & HDSPM_Dolby) ? "on" : "off");
-
-
- pref_syncref = hdspm_pref_sync_ref(hdspm);
- if (pref_syncref == 0)
- snd_iprintf(buffer, "Preferred Sync Reference: Word Clock\n");
- else
- snd_iprintf(buffer, "Preferred Sync Reference: AES%d\n",
- pref_syncref);
-
- snd_iprintf(buffer, "System Clock Frequency: %d\n",
- hdspm->system_sample_rate);
-
- snd_iprintf(buffer, "Double speed: %s\n",
- hdspm->control_register & HDSPM_DS_DoubleWire?
- "Double wire" : "Single wire");
- snd_iprintf(buffer, "Quad speed: %s\n",
- hdspm->control_register & HDSPM_QS_DoubleWire?
- "Double wire" :
- hdspm->control_register & HDSPM_QS_QuadWire?
- "Quad wire" : "Single wire");
-
- snd_iprintf(buffer, "--- Status:\n");
-
- snd_iprintf(buffer, "Word: %s Frequency: %d\n",
- (status & HDSPM_AES32_wcLock) ? "Sync " : "No Lock",
- HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF));
-
- for (x = 0; x < 8; x++) {
- snd_iprintf(buffer, "AES%d: %s Frequency: %d\n",
- x+1,
- (status2 & (HDSPM_LockAES >> x)) ?
- "Sync " : "No Lock",
- HDSPM_bit2freq((timecode >> (4*x)) & 0xF));
- }
-
- switch (hdspm_autosync_ref(hdspm)) {
- case HDSPM_AES32_AUTOSYNC_FROM_NONE:
- autosync_ref = "None"; break;
- case HDSPM_AES32_AUTOSYNC_FROM_WORD:
- autosync_ref = "Word Clock"; break;
- case HDSPM_AES32_AUTOSYNC_FROM_AES1:
- autosync_ref = "AES1"; break;
- case HDSPM_AES32_AUTOSYNC_FROM_AES2:
- autosync_ref = "AES2"; break;
- case HDSPM_AES32_AUTOSYNC_FROM_AES3:
- autosync_ref = "AES3"; break;
- case HDSPM_AES32_AUTOSYNC_FROM_AES4:
- autosync_ref = "AES4"; break;
- case HDSPM_AES32_AUTOSYNC_FROM_AES5:
- autosync_ref = "AES5"; break;
- case HDSPM_AES32_AUTOSYNC_FROM_AES6:
- autosync_ref = "AES6"; break;
- case HDSPM_AES32_AUTOSYNC_FROM_AES7:
- autosync_ref = "AES7"; break;
- case HDSPM_AES32_AUTOSYNC_FROM_AES8:
- autosync_ref = "AES8"; break;
- default:
- autosync_ref = "---"; break;
- }
- snd_iprintf(buffer, "AutoSync ref = %s\n", autosync_ref);
-
- snd_iprintf(buffer, "\n");
-}
-
-static void
-snd_hdspm_proc_read_raydat(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct hdspm *hdspm = entry->private_data;
- unsigned int status1, status2, status3, control, i;
- unsigned int lock, sync;
-
- status1 = hdspm_read(hdspm, HDSPM_RD_STATUS_1); /* s1 */
- status2 = hdspm_read(hdspm, HDSPM_RD_STATUS_2); /* freq */
- status3 = hdspm_read(hdspm, HDSPM_RD_STATUS_3); /* s2 */
-
- control = hdspm->control_register;
-
- snd_iprintf(buffer, "STATUS1: 0x%08x\n", status1);
- snd_iprintf(buffer, "STATUS2: 0x%08x\n", status2);
- snd_iprintf(buffer, "STATUS3: 0x%08x\n", status3);
-
-
- snd_iprintf(buffer, "\n*** CLOCK MODE\n\n");
-
- snd_iprintf(buffer, "Clock mode : %s\n",
- (hdspm_system_clock_mode(hdspm) == 0) ? "master" : "slave");
- snd_iprintf(buffer, "System frequency: %d Hz\n",
- hdspm_get_system_sample_rate(hdspm));
-
- snd_iprintf(buffer, "\n*** INPUT STATUS\n\n");
-
- lock = 0x1;
- sync = 0x100;
-
- for (i = 0; i < 8; i++) {
- snd_iprintf(buffer, "s1_input %d: Lock %d, Sync %d, Freq %s\n",
- i,
- (status1 & lock) ? 1 : 0,
- (status1 & sync) ? 1 : 0,
- texts_freq[(status2 >> (i * 4)) & 0xF]);
-
- lock = lock<<1;
- sync = sync<<1;
- }
-
- snd_iprintf(buffer, "WC input: Lock %d, Sync %d, Freq %s\n",
- (status1 & 0x1000000) ? 1 : 0,
- (status1 & 0x2000000) ? 1 : 0,
- texts_freq[(status1 >> 16) & 0xF]);
-
- snd_iprintf(buffer, "TCO input: Lock %d, Sync %d, Freq %s\n",
- (status1 & 0x4000000) ? 1 : 0,
- (status1 & 0x8000000) ? 1 : 0,
- texts_freq[(status1 >> 20) & 0xF]);
-
- snd_iprintf(buffer, "SYNC IN: Lock %d, Sync %d, Freq %s\n",
- (status3 & 0x400) ? 1 : 0,
- (status3 & 0x800) ? 1 : 0,
- texts_freq[(status2 >> 12) & 0xF]);
-
-}
-
-#ifdef CONFIG_SND_DEBUG
-static void
-snd_hdspm_proc_read_debug(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct hdspm *hdspm = entry->private_data;
-
- int j,i;
-
- for (i = 0; i < 256 /* 1024*64 */; i += j) {
- snd_iprintf(buffer, "0x%08X: ", i);
- for (j = 0; j < 16; j += 4)
- snd_iprintf(buffer, "%08X ", hdspm_read(hdspm, i + j));
- snd_iprintf(buffer, "\n");
- }
-}
-#endif
-
-
-static void snd_hdspm_proc_ports_in(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct hdspm *hdspm = entry->private_data;
- int i;
-
- snd_iprintf(buffer, "# generated by hdspm\n");
-
- for (i = 0; i < hdspm->max_channels_in; i++) {
- snd_iprintf(buffer, "%d=%s\n", i+1, hdspm->port_names_in[i]);
- }
-}
-
-static void snd_hdspm_proc_ports_out(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct hdspm *hdspm = entry->private_data;
- int i;
-
- snd_iprintf(buffer, "# generated by hdspm\n");
-
- for (i = 0; i < hdspm->max_channels_out; i++) {
- snd_iprintf(buffer, "%d=%s\n", i+1, hdspm->port_names_out[i]);
- }
-}
-
-
-static void __devinit snd_hdspm_proc_init(struct hdspm *hdspm)
-{
- struct snd_info_entry *entry;
-
- if (!snd_card_proc_new(hdspm->card, "hdspm", &entry)) {
- switch (hdspm->io_type) {
- case AES32:
- snd_info_set_text_ops(entry, hdspm,
- snd_hdspm_proc_read_aes32);
- break;
- case MADI:
- snd_info_set_text_ops(entry, hdspm,
- snd_hdspm_proc_read_madi);
- break;
- case MADIface:
- /* snd_info_set_text_ops(entry, hdspm,
- snd_hdspm_proc_read_madiface); */
- break;
- case RayDAT:
- snd_info_set_text_ops(entry, hdspm,
- snd_hdspm_proc_read_raydat);
- break;
- case AIO:
- break;
- }
- }
-
- if (!snd_card_proc_new(hdspm->card, "ports.in", &entry)) {
- snd_info_set_text_ops(entry, hdspm, snd_hdspm_proc_ports_in);
- }
-
- if (!snd_card_proc_new(hdspm->card, "ports.out", &entry)) {
- snd_info_set_text_ops(entry, hdspm, snd_hdspm_proc_ports_out);
- }
-
-#ifdef CONFIG_SND_DEBUG
- /* debug file to read all hdspm registers */
- if (!snd_card_proc_new(hdspm->card, "debug", &entry))
- snd_info_set_text_ops(entry, hdspm,
- snd_hdspm_proc_read_debug);
-#endif
-}
-
-/*------------------------------------------------------------
- hdspm intitialize
- ------------------------------------------------------------*/
-
-static int snd_hdspm_set_defaults(struct hdspm * hdspm)
-{
- /* ASSUMPTION: hdspm->lock is either held, or there is no need to
- hold it (e.g. during module initialization).
- */
-
- /* set defaults: */
-
- hdspm->settings_register = 0;
-
- switch (hdspm->io_type) {
- case MADI:
- case MADIface:
- hdspm->control_register =
- 0x2 + 0x8 + 0x10 + 0x80 + 0x400 + 0x4000 + 0x1000000;
- break;
-
- case RayDAT:
- case AIO:
- hdspm->settings_register = 0x1 + 0x1000;
- /* Magic values are: LAT_0, LAT_2, Master, freq1, tx64ch, inp_0,
- * line_out */
- hdspm->control_register =
- 0x2 + 0x8 + 0x10 + 0x80 + 0x400 + 0x4000 + 0x1000000;
- break;
-
- case AES32:
- hdspm->control_register =
- HDSPM_ClockModeMaster | /* Master Cloack Mode on */
- hdspm_encode_latency(7) | /* latency max=8192samples */
- HDSPM_SyncRef0 | /* AES1 is syncclock */
- HDSPM_LineOut | /* Analog output in */
- HDSPM_Professional; /* Professional mode */
- break;
- }
-
- hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
-
- if (AES32 == hdspm->io_type) {
- /* No control2 register for AES32 */
-#ifdef SNDRV_BIG_ENDIAN
- hdspm->control2_register = HDSPM_BIGENDIAN_MODE;
-#else
- hdspm->control2_register = 0;
-#endif
-
- hdspm_write(hdspm, HDSPM_control2Reg, hdspm->control2_register);
- }
- hdspm_compute_period_size(hdspm);
-
- /* silence everything */
-
- all_in_all_mixer(hdspm, 0 * UNITY_GAIN);
-
- if (hdspm->io_type == AIO || hdspm->io_type == RayDAT) {
- hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register);
- }
-
- /* set a default rate so that the channel map is set up. */
- hdspm_set_rate(hdspm, 48000, 1);
-
- return 0;
-}
-
-
-/*------------------------------------------------------------
- interrupt
- ------------------------------------------------------------*/
-
-static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id)
-{
- struct hdspm *hdspm = (struct hdspm *) dev_id;
- unsigned int status;
- int i, audio, midi, schedule = 0;
- /* cycles_t now; */
-
- status = hdspm_read(hdspm, HDSPM_statusRegister);
-
- audio = status & HDSPM_audioIRQPending;
- midi = status & (HDSPM_midi0IRQPending | HDSPM_midi1IRQPending |
- HDSPM_midi2IRQPending | HDSPM_midi3IRQPending);
-
- /* now = get_cycles(); */
- /**
- * LAT_2..LAT_0 period counter (win) counter (mac)
- * 6 4096 ~256053425 ~514672358
- * 5 2048 ~128024983 ~257373821
- * 4 1024 ~64023706 ~128718089
- * 3 512 ~32005945 ~64385999
- * 2 256 ~16003039 ~32260176
- * 1 128 ~7998738 ~16194507
- * 0 64 ~3998231 ~8191558
- **/
- /*
- snd_printk(KERN_INFO "snd_hdspm_interrupt %llu @ %llx\n",
- now-hdspm->last_interrupt, status & 0xFFC0);
- hdspm->last_interrupt = now;
- */
-
- if (!audio && !midi)
- return IRQ_NONE;
-
- hdspm_write(hdspm, HDSPM_interruptConfirmation, 0);
- hdspm->irq_count++;
-
-
- if (audio) {
- if (hdspm->capture_substream)
- snd_pcm_period_elapsed(hdspm->capture_substream);
-
- if (hdspm->playback_substream)
- snd_pcm_period_elapsed(hdspm->playback_substream);
- }
-
- if (midi) {
- i = 0;
- while (i < hdspm->midiPorts) {
- if ((hdspm_read(hdspm,
- hdspm->midi[i].statusIn) & 0xff) &&
- (status & hdspm->midi[i].irq)) {
- /* we disable interrupts for this input until
- * processing is done
- */
- hdspm->control_register &= ~hdspm->midi[i].ie;
- hdspm_write(hdspm, HDSPM_controlRegister,
- hdspm->control_register);
- hdspm->midi[i].pending = 1;
- schedule = 1;
- }
-
- i++;
- }
-
- if (schedule)
- tasklet_hi_schedule(&hdspm->midi_tasklet);
- }
-
- return IRQ_HANDLED;
-}
-
-/*------------------------------------------------------------
- pcm interface
- ------------------------------------------------------------*/
-
-
-static snd_pcm_uframes_t snd_hdspm_hw_pointer(struct snd_pcm_substream
- *substream)
-{
- struct hdspm *hdspm = snd_pcm_substream_chip(substream);
- return hdspm_hw_pointer(hdspm);
-}
-
-
-static int snd_hdspm_reset(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct hdspm *hdspm = snd_pcm_substream_chip(substream);
- struct snd_pcm_substream *other;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- other = hdspm->capture_substream;
- else
- other = hdspm->playback_substream;
-
- if (hdspm->running)
- runtime->status->hw_ptr = hdspm_hw_pointer(hdspm);
- else
- runtime->status->hw_ptr = 0;
- if (other) {
- struct snd_pcm_substream *s;
- struct snd_pcm_runtime *oruntime = other->runtime;
- snd_pcm_group_for_each_entry(s, substream) {
- if (s == other) {
- oruntime->status->hw_ptr =
- runtime->status->hw_ptr;
- break;
- }
- }
- }
- return 0;
-}
-
-static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct hdspm *hdspm = snd_pcm_substream_chip(substream);
- int err;
- int i;
- pid_t this_pid;
- pid_t other_pid;
-
- spin_lock_irq(&hdspm->lock);
-
- if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- this_pid = hdspm->playback_pid;
- other_pid = hdspm->capture_pid;
- } else {
- this_pid = hdspm->capture_pid;
- other_pid = hdspm->playback_pid;
- }
-
- if (other_pid > 0 && this_pid != other_pid) {
-
- /* The other stream is open, and not by the same
- task as this one. Make sure that the parameters
- that matter are the same.
- */
-
- if (params_rate(params) != hdspm->system_sample_rate) {
- spin_unlock_irq(&hdspm->lock);
- _snd_pcm_hw_param_setempty(params,
- SNDRV_PCM_HW_PARAM_RATE);
- return -EBUSY;
- }
-
- if (params_period_size(params) != hdspm->period_bytes / 4) {
- spin_unlock_irq(&hdspm->lock);
- _snd_pcm_hw_param_setempty(params,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
- return -EBUSY;
- }
-
- }
- /* We're fine. */
- spin_unlock_irq(&hdspm->lock);
-
- /* how to make sure that the rate matches an externally-set one ? */
-
- spin_lock_irq(&hdspm->lock);
- err = hdspm_set_rate(hdspm, params_rate(params), 0);
- if (err < 0) {
- snd_printk(KERN_INFO "err on hdspm_set_rate: %d\n", err);
- spin_unlock_irq(&hdspm->lock);
- _snd_pcm_hw_param_setempty(params,
- SNDRV_PCM_HW_PARAM_RATE);
- return err;
- }
- spin_unlock_irq(&hdspm->lock);
-
- err = hdspm_set_interrupt_interval(hdspm,
- params_period_size(params));
- if (err < 0) {
- snd_printk(KERN_INFO "err on hdspm_set_interrupt_interval: %d\n", err);
- _snd_pcm_hw_param_setempty(params,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
- return err;
- }
-
- /* Memory allocation, takashi's method, dont know if we should
- * spinlock
- */
- /* malloc all buffer even if not enabled to get sure */
- /* Update for MADI rev 204: we need to allocate for all channels,
- * otherwise it doesn't work at 96kHz */
-
- err =
- snd_pcm_lib_malloc_pages(substream, HDSPM_DMA_AREA_BYTES);
- if (err < 0) {
- snd_printk(KERN_INFO "err on snd_pcm_lib_malloc_pages: %d\n", err);
- return err;
- }
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-
- hdspm_set_sgbuf(hdspm, substream, HDSPM_pageAddressBufferOut,
- params_channels(params));
-
- for (i = 0; i < params_channels(params); ++i)
- snd_hdspm_enable_out(hdspm, i, 1);
-
- hdspm->playback_buffer =
- (unsigned char *) substream->runtime->dma_area;
- snd_printdd("Allocated sample buffer for playback at %p\n",
- hdspm->playback_buffer);
- } else {
- hdspm_set_sgbuf(hdspm, substream, HDSPM_pageAddressBufferIn,
- params_channels(params));
-
- for (i = 0; i < params_channels(params); ++i)
- snd_hdspm_enable_in(hdspm, i, 1);
-
- hdspm->capture_buffer =
- (unsigned char *) substream->runtime->dma_area;
- snd_printdd("Allocated sample buffer for capture at %p\n",
- hdspm->capture_buffer);
- }
-
- /*
- snd_printdd("Allocated sample buffer for %s at 0x%08X\n",
- substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
- "playback" : "capture",
- snd_pcm_sgbuf_get_addr(substream, 0));
- */
- /*
- snd_printdd("set_hwparams: %s %d Hz, %d channels, bs = %d\n",
- substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
- "playback" : "capture",
- params_rate(params), params_channels(params),
- params_buffer_size(params));
- */
-
-
- /* Switch to native float format if requested */
- if (SNDRV_PCM_FORMAT_FLOAT_LE == params_format(params)) {
- if (!(hdspm->control_register & HDSPe_FLOAT_FORMAT))
- snd_printk(KERN_INFO "hdspm: Switching to native 32bit LE float format.\n");
-
- hdspm->control_register |= HDSPe_FLOAT_FORMAT;
- } else if (SNDRV_PCM_FORMAT_S32_LE == params_format(params)) {
- if (hdspm->control_register & HDSPe_FLOAT_FORMAT)
- snd_printk(KERN_INFO "hdspm: Switching to native 32bit LE integer format.\n");
-
- hdspm->control_register &= ~HDSPe_FLOAT_FORMAT;
- }
- hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
-
- return 0;
-}
-
-static int snd_hdspm_hw_free(struct snd_pcm_substream *substream)
-{
- int i;
- struct hdspm *hdspm = snd_pcm_substream_chip(substream);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-
- /* params_channels(params) should be enough,
- but to get sure in case of error */
- for (i = 0; i < hdspm->max_channels_out; ++i)
- snd_hdspm_enable_out(hdspm, i, 0);
-
- hdspm->playback_buffer = NULL;
- } else {
- for (i = 0; i < hdspm->max_channels_in; ++i)
- snd_hdspm_enable_in(hdspm, i, 0);
-
- hdspm->capture_buffer = NULL;
-
- }
-
- snd_pcm_lib_free_pages(substream);
-
- return 0;
-}
-
-
-static int snd_hdspm_channel_info(struct snd_pcm_substream *substream,
- struct snd_pcm_channel_info *info)
-{
- struct hdspm *hdspm = snd_pcm_substream_chip(substream);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (snd_BUG_ON(info->channel >= hdspm->max_channels_out)) {
- snd_printk(KERN_INFO "snd_hdspm_channel_info: output channel out of range (%d)\n", info->channel);
- return -EINVAL;
- }
-
- if (hdspm->channel_map_out[info->channel] < 0) {
- snd_printk(KERN_INFO "snd_hdspm_channel_info: output channel %d mapped out\n", info->channel);
- return -EINVAL;
- }
-
- info->offset = hdspm->channel_map_out[info->channel] *
- HDSPM_CHANNEL_BUFFER_BYTES;
- } else {
- if (snd_BUG_ON(info->channel >= hdspm->max_channels_in)) {
- snd_printk(KERN_INFO "snd_hdspm_channel_info: input channel out of range (%d)\n", info->channel);
- return -EINVAL;
- }
-
- if (hdspm->channel_map_in[info->channel] < 0) {
- snd_printk(KERN_INFO "snd_hdspm_channel_info: input channel %d mapped out\n", info->channel);
- return -EINVAL;
- }
-
- info->offset = hdspm->channel_map_in[info->channel] *
- HDSPM_CHANNEL_BUFFER_BYTES;
- }
-
- info->first = 0;
- info->step = 32;
- return 0;
-}
-
-
-static int snd_hdspm_ioctl(struct snd_pcm_substream *substream,
- unsigned int cmd, void *arg)
-{
- switch (cmd) {
- case SNDRV_PCM_IOCTL1_RESET:
- return snd_hdspm_reset(substream);
-
- case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
- {
- struct snd_pcm_channel_info *info = arg;
- return snd_hdspm_channel_info(substream, info);
- }
- default:
- break;
- }
-
- return snd_pcm_lib_ioctl(substream, cmd, arg);
-}
-
-static int snd_hdspm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct hdspm *hdspm = snd_pcm_substream_chip(substream);
- struct snd_pcm_substream *other;
- int running;
-
- spin_lock(&hdspm->lock);
- running = hdspm->running;
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- running |= 1 << substream->stream;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- running &= ~(1 << substream->stream);
- break;
- default:
- snd_BUG();
- spin_unlock(&hdspm->lock);
- return -EINVAL;
- }
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- other = hdspm->capture_substream;
- else
- other = hdspm->playback_substream;
-
- if (other) {
- struct snd_pcm_substream *s;
- snd_pcm_group_for_each_entry(s, substream) {
- if (s == other) {
- snd_pcm_trigger_done(s, substream);
- if (cmd == SNDRV_PCM_TRIGGER_START)
- running |= 1 << s->stream;
- else
- running &= ~(1 << s->stream);
- goto _ok;
- }
- }
- if (cmd == SNDRV_PCM_TRIGGER_START) {
- if (!(running & (1 << SNDRV_PCM_STREAM_PLAYBACK))
- && substream->stream ==
- SNDRV_PCM_STREAM_CAPTURE)
- hdspm_silence_playback(hdspm);
- } else {
- if (running &&
- substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- hdspm_silence_playback(hdspm);
- }
- } else {
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- hdspm_silence_playback(hdspm);
- }
-_ok:
- snd_pcm_trigger_done(substream, substream);
- if (!hdspm->running && running)
- hdspm_start_audio(hdspm);
- else if (hdspm->running && !running)
- hdspm_stop_audio(hdspm);
- hdspm->running = running;
- spin_unlock(&hdspm->lock);
-
- return 0;
-}
-
-static int snd_hdspm_prepare(struct snd_pcm_substream *substream)
-{
- return 0;
-}
-
-static struct snd_pcm_hardware snd_hdspm_playback_subinfo = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_NONINTERLEAVED |
- SNDRV_PCM_INFO_SYNC_START | SNDRV_PCM_INFO_DOUBLE),
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .rates = (SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_64000 |
- SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
- SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000 ),
- .rate_min = 32000,
- .rate_max = 192000,
- .channels_min = 1,
- .channels_max = HDSPM_MAX_CHANNELS,
- .buffer_bytes_max =
- HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS,
- .period_bytes_min = (32 * 4),
- .period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS,
- .periods_min = 2,
- .periods_max = 512,
- .fifo_size = 0
-};
-
-static struct snd_pcm_hardware snd_hdspm_capture_subinfo = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_NONINTERLEAVED |
- SNDRV_PCM_INFO_SYNC_START),
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .rates = (SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_64000 |
- SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
- SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000),
- .rate_min = 32000,
- .rate_max = 192000,
- .channels_min = 1,
- .channels_max = HDSPM_MAX_CHANNELS,
- .buffer_bytes_max =
- HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS,
- .period_bytes_min = (32 * 4),
- .period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS,
- .periods_min = 2,
- .periods_max = 512,
- .fifo_size = 0
-};
-
-static int snd_hdspm_hw_rule_in_channels_rate(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct hdspm *hdspm = rule->private;
- struct snd_interval *c =
- hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_interval *r =
- hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
-
- if (r->min > 96000 && r->max <= 192000) {
- struct snd_interval t = {
- .min = hdspm->qs_in_channels,
- .max = hdspm->qs_in_channels,
- .integer = 1,
- };
- return snd_interval_refine(c, &t);
- } else if (r->min > 48000 && r->max <= 96000) {
- struct snd_interval t = {
- .min = hdspm->ds_in_channels,
- .max = hdspm->ds_in_channels,
- .integer = 1,
- };
- return snd_interval_refine(c, &t);
- } else if (r->max < 64000) {
- struct snd_interval t = {
- .min = hdspm->ss_in_channels,
- .max = hdspm->ss_in_channels,
- .integer = 1,
- };
- return snd_interval_refine(c, &t);
- }
-
- return 0;
-}
-
-static int snd_hdspm_hw_rule_out_channels_rate(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule * rule)
-{
- struct hdspm *hdspm = rule->private;
- struct snd_interval *c =
- hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_interval *r =
- hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
-
- if (r->min > 96000 && r->max <= 192000) {
- struct snd_interval t = {
- .min = hdspm->qs_out_channels,
- .max = hdspm->qs_out_channels,
- .integer = 1,
- };
- return snd_interval_refine(c, &t);
- } else if (r->min > 48000 && r->max <= 96000) {
- struct snd_interval t = {
- .min = hdspm->ds_out_channels,
- .max = hdspm->ds_out_channels,
- .integer = 1,
- };
- return snd_interval_refine(c, &t);
- } else if (r->max < 64000) {
- struct snd_interval t = {
- .min = hdspm->ss_out_channels,
- .max = hdspm->ss_out_channels,
- .integer = 1,
- };
- return snd_interval_refine(c, &t);
- } else {
- }
- return 0;
-}
-
-static int snd_hdspm_hw_rule_rate_in_channels(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule * rule)
-{
- struct hdspm *hdspm = rule->private;
- struct snd_interval *c =
- hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_interval *r =
- hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
-
- if (c->min >= hdspm->ss_in_channels) {
- struct snd_interval t = {
- .min = 32000,
- .max = 48000,
- .integer = 1,
- };
- return snd_interval_refine(r, &t);
- } else if (c->max <= hdspm->qs_in_channels) {
- struct snd_interval t = {
- .min = 128000,
- .max = 192000,
- .integer = 1,
- };
- return snd_interval_refine(r, &t);
- } else if (c->max <= hdspm->ds_in_channels) {
- struct snd_interval t = {
- .min = 64000,
- .max = 96000,
- .integer = 1,
- };
- return snd_interval_refine(r, &t);
- }
-
- return 0;
-}
-static int snd_hdspm_hw_rule_rate_out_channels(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct hdspm *hdspm = rule->private;
- struct snd_interval *c =
- hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_interval *r =
- hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
-
- if (c->min >= hdspm->ss_out_channels) {
- struct snd_interval t = {
- .min = 32000,
- .max = 48000,
- .integer = 1,
- };
- return snd_interval_refine(r, &t);
- } else if (c->max <= hdspm->qs_out_channels) {
- struct snd_interval t = {
- .min = 128000,
- .max = 192000,
- .integer = 1,
- };
- return snd_interval_refine(r, &t);
- } else if (c->max <= hdspm->ds_out_channels) {
- struct snd_interval t = {
- .min = 64000,
- .max = 96000,
- .integer = 1,
- };
- return snd_interval_refine(r, &t);
- }
-
- return 0;
-}
-
-static int snd_hdspm_hw_rule_in_channels(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- unsigned int list[3];
- struct hdspm *hdspm = rule->private;
- struct snd_interval *c = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_CHANNELS);
-
- list[0] = hdspm->qs_in_channels;
- list[1] = hdspm->ds_in_channels;
- list[2] = hdspm->ss_in_channels;
- return snd_interval_list(c, 3, list, 0);
-}
-
-static int snd_hdspm_hw_rule_out_channels(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- unsigned int list[3];
- struct hdspm *hdspm = rule->private;
- struct snd_interval *c = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_CHANNELS);
-
- list[0] = hdspm->qs_out_channels;
- list[1] = hdspm->ds_out_channels;
- list[2] = hdspm->ss_out_channels;
- return snd_interval_list(c, 3, list, 0);
-}
-
-
-static unsigned int hdspm_aes32_sample_rates[] = {
- 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000
-};
-
-static struct snd_pcm_hw_constraint_list
-hdspm_hw_constraints_aes32_sample_rates = {
- .count = ARRAY_SIZE(hdspm_aes32_sample_rates),
- .list = hdspm_aes32_sample_rates,
- .mask = 0
-};
-
-static int snd_hdspm_playback_open(struct snd_pcm_substream *substream)
-{
- struct hdspm *hdspm = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- spin_lock_irq(&hdspm->lock);
-
- snd_pcm_set_sync(substream);
-
-
- runtime->hw = snd_hdspm_playback_subinfo;
-
- if (hdspm->capture_substream == NULL)
- hdspm_stop_audio(hdspm);
-
- hdspm->playback_pid = current->pid;
- hdspm->playback_substream = substream;
-
- spin_unlock_irq(&hdspm->lock);
-
- snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
- snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
-
- switch (hdspm->io_type) {
- case AIO:
- case RayDAT:
- snd_pcm_hw_constraint_minmax(runtime,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- 32, 4096);
- /* RayDAT & AIO have a fixed buffer of 16384 samples per channel */
- snd_pcm_hw_constraint_minmax(runtime,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- 16384, 16384);
- break;
-
- default:
- snd_pcm_hw_constraint_minmax(runtime,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- 64, 8192);
- break;
- }
-
- if (AES32 == hdspm->io_type) {
- runtime->hw.rates |= SNDRV_PCM_RATE_KNOT;
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &hdspm_hw_constraints_aes32_sample_rates);
- } else {
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- snd_hdspm_hw_rule_rate_out_channels, hdspm,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
- }
-
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- snd_hdspm_hw_rule_out_channels, hdspm,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
-
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- snd_hdspm_hw_rule_out_channels_rate, hdspm,
- SNDRV_PCM_HW_PARAM_RATE, -1);
-
- return 0;
-}
-
-static int snd_hdspm_playback_release(struct snd_pcm_substream *substream)
-{
- struct hdspm *hdspm = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&hdspm->lock);
-
- hdspm->playback_pid = -1;
- hdspm->playback_substream = NULL;
-
- spin_unlock_irq(&hdspm->lock);
-
- return 0;
-}
-
-
-static int snd_hdspm_capture_open(struct snd_pcm_substream *substream)
-{
- struct hdspm *hdspm = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- spin_lock_irq(&hdspm->lock);
- snd_pcm_set_sync(substream);
- runtime->hw = snd_hdspm_capture_subinfo;
-
- if (hdspm->playback_substream == NULL)
- hdspm_stop_audio(hdspm);
-
- hdspm->capture_pid = current->pid;
- hdspm->capture_substream = substream;
-
- spin_unlock_irq(&hdspm->lock);
-
- snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
- snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
-
- switch (hdspm->io_type) {
- case AIO:
- case RayDAT:
- snd_pcm_hw_constraint_minmax(runtime,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- 32, 4096);
- snd_pcm_hw_constraint_minmax(runtime,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- 16384, 16384);
- break;
-
- default:
- snd_pcm_hw_constraint_minmax(runtime,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- 64, 8192);
- break;
- }
-
- if (AES32 == hdspm->io_type) {
- runtime->hw.rates |= SNDRV_PCM_RATE_KNOT;
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &hdspm_hw_constraints_aes32_sample_rates);
- } else {
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- snd_hdspm_hw_rule_rate_in_channels, hdspm,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
- }
-
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- snd_hdspm_hw_rule_in_channels, hdspm,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
-
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- snd_hdspm_hw_rule_in_channels_rate, hdspm,
- SNDRV_PCM_HW_PARAM_RATE, -1);
-
- return 0;
-}
-
-static int snd_hdspm_capture_release(struct snd_pcm_substream *substream)
-{
- struct hdspm *hdspm = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&hdspm->lock);
-
- hdspm->capture_pid = -1;
- hdspm->capture_substream = NULL;
-
- spin_unlock_irq(&hdspm->lock);
- return 0;
-}
-
-static int snd_hdspm_hwdep_dummy_op(struct snd_hwdep *hw, struct file *file)
-{
- /* we have nothing to initialize but the call is required */
- return 0;
-}
-
-static inline int copy_u32_le(void __user *dest, void __iomem *src)
-{
- u32 val = readl(src);
- return copy_to_user(dest, &val, 4);
-}
-
-static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- void __user *argp = (void __user *)arg;
- struct hdspm *hdspm = hw->private_data;
- struct hdspm_mixer_ioctl mixer;
- struct hdspm_config info;
- struct hdspm_status status;
- struct hdspm_version hdspm_version;
- struct hdspm_peak_rms *levels;
- struct hdspm_ltc ltc;
- unsigned int statusregister;
- long unsigned int s;
- int i = 0;
-
- switch (cmd) {
-
- case SNDRV_HDSPM_IOCTL_GET_PEAK_RMS:
- levels = &hdspm->peak_rms;
- for (i = 0; i < HDSPM_MAX_CHANNELS; i++) {
- levels->input_peaks[i] =
- readl(hdspm->iobase +
- HDSPM_MADI_INPUT_PEAK + i*4);
- levels->playback_peaks[i] =
- readl(hdspm->iobase +
- HDSPM_MADI_PLAYBACK_PEAK + i*4);
- levels->output_peaks[i] =
- readl(hdspm->iobase +
- HDSPM_MADI_OUTPUT_PEAK + i*4);
-
- levels->input_rms[i] =
- ((uint64_t) readl(hdspm->iobase +
- HDSPM_MADI_INPUT_RMS_H + i*4) << 32) |
- (uint64_t) readl(hdspm->iobase +
- HDSPM_MADI_INPUT_RMS_L + i*4);
- levels->playback_rms[i] =
- ((uint64_t)readl(hdspm->iobase +
- HDSPM_MADI_PLAYBACK_RMS_H+i*4) << 32) |
- (uint64_t)readl(hdspm->iobase +
- HDSPM_MADI_PLAYBACK_RMS_L + i*4);
- levels->output_rms[i] =
- ((uint64_t)readl(hdspm->iobase +
- HDSPM_MADI_OUTPUT_RMS_H + i*4) << 32) |
- (uint64_t)readl(hdspm->iobase +
- HDSPM_MADI_OUTPUT_RMS_L + i*4);
- }
-
- if (hdspm->system_sample_rate > 96000) {
- levels->speed = qs;
- } else if (hdspm->system_sample_rate > 48000) {
- levels->speed = ds;
- } else {
- levels->speed = ss;
- }
- levels->status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
-
- s = copy_to_user(argp, levels, sizeof(struct hdspm_peak_rms));
- if (0 != s) {
- /* snd_printk(KERN_ERR "copy_to_user(.., .., %lu): %lu
- [Levels]\n", sizeof(struct hdspm_peak_rms), s);
- */
- return -EFAULT;
- }
- break;
-
- case SNDRV_HDSPM_IOCTL_GET_LTC:
- ltc.ltc = hdspm_read(hdspm, HDSPM_RD_TCO);
- i = hdspm_read(hdspm, HDSPM_RD_TCO + 4);
- if (i & HDSPM_TCO1_LTC_Input_valid) {
- switch (i & (HDSPM_TCO1_LTC_Format_LSB |
- HDSPM_TCO1_LTC_Format_MSB)) {
- case 0:
- ltc.format = fps_24;
- break;
- case HDSPM_TCO1_LTC_Format_LSB:
- ltc.format = fps_25;
- break;
- case HDSPM_TCO1_LTC_Format_MSB:
- ltc.format = fps_2997;
- break;
- default:
- ltc.format = 30;
- break;
- }
- if (i & HDSPM_TCO1_set_drop_frame_flag) {
- ltc.frame = drop_frame;
- } else {
- ltc.frame = full_frame;
- }
- } else {
- ltc.format = format_invalid;
- ltc.frame = frame_invalid;
- }
- if (i & HDSPM_TCO1_Video_Input_Format_NTSC) {
- ltc.input_format = ntsc;
- } else if (i & HDSPM_TCO1_Video_Input_Format_PAL) {
- ltc.input_format = pal;
- } else {
- ltc.input_format = no_video;
- }
-
- s = copy_to_user(argp, &ltc, sizeof(struct hdspm_ltc));
- if (0 != s) {
- /*
- snd_printk(KERN_ERR "copy_to_user(.., .., %lu): %lu [LTC]\n", sizeof(struct hdspm_ltc), s); */
- return -EFAULT;
- }
-
- break;
-
- case SNDRV_HDSPM_IOCTL_GET_CONFIG:
-
- memset(&info, 0, sizeof(info));
- spin_lock_irq(&hdspm->lock);
- info.pref_sync_ref = hdspm_pref_sync_ref(hdspm);
- info.wordclock_sync_check = hdspm_wc_sync_check(hdspm);
-
- info.system_sample_rate = hdspm->system_sample_rate;
- info.autosync_sample_rate =
- hdspm_external_sample_rate(hdspm);
- info.system_clock_mode = hdspm_system_clock_mode(hdspm);
- info.clock_source = hdspm_clock_source(hdspm);
- info.autosync_ref = hdspm_autosync_ref(hdspm);
- info.line_out = hdspm_line_out(hdspm);
- info.passthru = 0;
- spin_unlock_irq(&hdspm->lock);
- if (copy_to_user(argp, &info, sizeof(info)))
- return -EFAULT;
- break;
-
- case SNDRV_HDSPM_IOCTL_GET_STATUS:
- memset(&status, 0, sizeof(status));
-
- status.card_type = hdspm->io_type;
-
- status.autosync_source = hdspm_autosync_ref(hdspm);
-
- status.card_clock = 110069313433624ULL;
- status.master_period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ);
-
- switch (hdspm->io_type) {
- case MADI:
- case MADIface:
- status.card_specific.madi.sync_wc =
- hdspm_wc_sync_check(hdspm);
- status.card_specific.madi.sync_madi =
- hdspm_madi_sync_check(hdspm);
- status.card_specific.madi.sync_tco =
- hdspm_tco_sync_check(hdspm);
- status.card_specific.madi.sync_in =
- hdspm_sync_in_sync_check(hdspm);
-
- statusregister =
- hdspm_read(hdspm, HDSPM_statusRegister);
- status.card_specific.madi.madi_input =
- (statusregister & HDSPM_AB_int) ? 1 : 0;
- status.card_specific.madi.channel_format =
- (statusregister & HDSPM_RX_64ch) ? 1 : 0;
- /* TODO: Mac driver sets it when f_s>48kHz */
- status.card_specific.madi.frame_format = 0;
-
- default:
- break;
- }
-
- if (copy_to_user(argp, &status, sizeof(status)))
- return -EFAULT;
-
-
- break;
-
- case SNDRV_HDSPM_IOCTL_GET_VERSION:
- memset(&hdspm_version, 0, sizeof(hdspm_version));
-
- hdspm_version.card_type = hdspm->io_type;
- strncpy(hdspm_version.cardname, hdspm->card_name,
- sizeof(hdspm_version.cardname));
- hdspm_version.serial = hdspm->serial;
- hdspm_version.firmware_rev = hdspm->firmware_rev;
- hdspm_version.addons = 0;
- if (hdspm->tco)
- hdspm_version.addons |= HDSPM_ADDON_TCO;
-
- if (copy_to_user(argp, &hdspm_version,
- sizeof(hdspm_version)))
- return -EFAULT;
- break;
-
- case SNDRV_HDSPM_IOCTL_GET_MIXER:
- if (copy_from_user(&mixer, argp, sizeof(mixer)))
- return -EFAULT;
- if (copy_to_user((void __user *)mixer.mixer, hdspm->mixer,
- sizeof(struct hdspm_mixer)))
- return -EFAULT;
- break;
-
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static struct snd_pcm_ops snd_hdspm_playback_ops = {
- .open = snd_hdspm_playback_open,
- .close = snd_hdspm_playback_release,
- .ioctl = snd_hdspm_ioctl,
- .hw_params = snd_hdspm_hw_params,
- .hw_free = snd_hdspm_hw_free,
- .prepare = snd_hdspm_prepare,
- .trigger = snd_hdspm_trigger,
- .pointer = snd_hdspm_hw_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
-static struct snd_pcm_ops snd_hdspm_capture_ops = {
- .open = snd_hdspm_capture_open,
- .close = snd_hdspm_capture_release,
- .ioctl = snd_hdspm_ioctl,
- .hw_params = snd_hdspm_hw_params,
- .hw_free = snd_hdspm_hw_free,
- .prepare = snd_hdspm_prepare,
- .trigger = snd_hdspm_trigger,
- .pointer = snd_hdspm_hw_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
-static int __devinit snd_hdspm_create_hwdep(struct snd_card *card,
- struct hdspm * hdspm)
-{
- struct snd_hwdep *hw;
- int err;
-
- err = snd_hwdep_new(card, "HDSPM hwdep", 0, &hw);
- if (err < 0)
- return err;
-
- hdspm->hwdep = hw;
- hw->private_data = hdspm;
- strcpy(hw->name, "HDSPM hwdep interface");
-
- hw->ops.open = snd_hdspm_hwdep_dummy_op;
- hw->ops.ioctl = snd_hdspm_hwdep_ioctl;
- hw->ops.ioctl_compat = snd_hdspm_hwdep_ioctl;
- hw->ops.release = snd_hdspm_hwdep_dummy_op;
-
- return 0;
-}
-
-
-/*------------------------------------------------------------
- memory interface
- ------------------------------------------------------------*/
-static int __devinit snd_hdspm_preallocate_memory(struct hdspm *hdspm)
-{
- int err;
- struct snd_pcm *pcm;
- size_t wanted;
-
- pcm = hdspm->pcm;
-
- wanted = HDSPM_DMA_AREA_BYTES;
-
- err =
- snd_pcm_lib_preallocate_pages_for_all(pcm,
- SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(hdspm->pci),
- wanted,
- wanted);
- if (err < 0) {
- snd_printdd("Could not preallocate %zd Bytes\n", wanted);
-
- return err;
- } else
- snd_printdd(" Preallocated %zd Bytes\n", wanted);
-
- return 0;
-}
-
-
-static void hdspm_set_sgbuf(struct hdspm *hdspm,
- struct snd_pcm_substream *substream,
- unsigned int reg, int channels)
-{
- int i;
-
- /* continuous memory segment */
- for (i = 0; i < (channels * 16); i++)
- hdspm_write(hdspm, reg + 4 * i,
- snd_pcm_sgbuf_get_addr(substream, 4096 * i));
-}
-
-
-/* ------------- ALSA Devices ---------------------------- */
-static int __devinit snd_hdspm_create_pcm(struct snd_card *card,
- struct hdspm *hdspm)
-{
- struct snd_pcm *pcm;
- int err;
-
- err = snd_pcm_new(card, hdspm->card_name, 0, 1, 1, &pcm);
- if (err < 0)
- return err;
-
- hdspm->pcm = pcm;
- pcm->private_data = hdspm;
- strcpy(pcm->name, hdspm->card_name);
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_hdspm_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_hdspm_capture_ops);
-
- pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
-
- err = snd_hdspm_preallocate_memory(hdspm);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static inline void snd_hdspm_initialize_midi_flush(struct hdspm * hdspm)
-{
- int i;
-
- for (i = 0; i < hdspm->midiPorts; i++)
- snd_hdspm_flush_midi_input(hdspm, i);
-}
-
-static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card,
- struct hdspm * hdspm)
-{
- int err, i;
-
- snd_printdd("Create card...\n");
- err = snd_hdspm_create_pcm(card, hdspm);
- if (err < 0)
- return err;
-
- i = 0;
- while (i < hdspm->midiPorts) {
- err = snd_hdspm_create_midi(card, hdspm, i);
- if (err < 0) {
- return err;
- }
- i++;
- }
-
- err = snd_hdspm_create_controls(card, hdspm);
- if (err < 0)
- return err;
-
- err = snd_hdspm_create_hwdep(card, hdspm);
- if (err < 0)
- return err;
-
- snd_printdd("proc init...\n");
- snd_hdspm_proc_init(hdspm);
-
- hdspm->system_sample_rate = -1;
- hdspm->last_external_sample_rate = -1;
- hdspm->last_internal_sample_rate = -1;
- hdspm->playback_pid = -1;
- hdspm->capture_pid = -1;
- hdspm->capture_substream = NULL;
- hdspm->playback_substream = NULL;
-
- snd_printdd("Set defaults...\n");
- err = snd_hdspm_set_defaults(hdspm);
- if (err < 0)
- return err;
-
- snd_printdd("Update mixer controls...\n");
- hdspm_update_simple_mixer_controls(hdspm);
-
- snd_printdd("Initializeing complete ???\n");
-
- err = snd_card_register(card);
- if (err < 0) {
- snd_printk(KERN_ERR "HDSPM: error registering card\n");
- return err;
- }
-
- snd_printdd("... yes now\n");
-
- return 0;
-}
-
-static int __devinit snd_hdspm_create(struct snd_card *card,
- struct hdspm *hdspm) {
-
- struct pci_dev *pci = hdspm->pci;
- int err;
- unsigned long io_extent;
-
- hdspm->irq = -1;
- hdspm->card = card;
-
- spin_lock_init(&hdspm->lock);
-
- pci_read_config_word(hdspm->pci,
- PCI_CLASS_REVISION, &hdspm->firmware_rev);
-
- strcpy(card->mixername, "Xilinx FPGA");
- strcpy(card->driver, "HDSPM");
-
- switch (hdspm->firmware_rev) {
- case HDSPM_RAYDAT_REV:
- hdspm->io_type = RayDAT;
- hdspm->card_name = "RME RayDAT";
- hdspm->midiPorts = 2;
- break;
- case HDSPM_AIO_REV:
- hdspm->io_type = AIO;
- hdspm->card_name = "RME AIO";
- hdspm->midiPorts = 1;
- break;
- case HDSPM_MADIFACE_REV:
- hdspm->io_type = MADIface;
- hdspm->card_name = "RME MADIface";
- hdspm->midiPorts = 1;
- break;
- default:
- if ((hdspm->firmware_rev == 0xf0) ||
- ((hdspm->firmware_rev >= 0xe6) &&
- (hdspm->firmware_rev <= 0xea))) {
- hdspm->io_type = AES32;
- hdspm->card_name = "RME AES32";
- hdspm->midiPorts = 2;
- } else if ((hdspm->firmware_rev == 0xd2) ||
- ((hdspm->firmware_rev >= 0xc8) &&
- (hdspm->firmware_rev <= 0xcf))) {
- hdspm->io_type = MADI;
- hdspm->card_name = "RME MADI";
- hdspm->midiPorts = 3;
- } else {
- snd_printk(KERN_ERR
- "HDSPM: unknown firmware revision %x\n",
- hdspm->firmware_rev);
- return -ENODEV;
- }
- }
-
- err = pci_enable_device(pci);
- if (err < 0)
- return err;
-
- pci_set_master(hdspm->pci);
-
- err = pci_request_regions(pci, "hdspm");
- if (err < 0)
- return err;
-
- hdspm->port = pci_resource_start(pci, 0);
- io_extent = pci_resource_len(pci, 0);
-
- snd_printdd("grabbed memory region 0x%lx-0x%lx\n",
- hdspm->port, hdspm->port + io_extent - 1);
-
- hdspm->iobase = ioremap_nocache(hdspm->port, io_extent);
- if (!hdspm->iobase) {
- snd_printk(KERN_ERR "HDSPM: "
- "unable to remap region 0x%lx-0x%lx\n",
- hdspm->port, hdspm->port + io_extent - 1);
- return -EBUSY;
- }
- snd_printdd("remapped region (0x%lx) 0x%lx-0x%lx\n",
- (unsigned long)hdspm->iobase, hdspm->port,
- hdspm->port + io_extent - 1);
-
- if (request_irq(pci->irq, snd_hdspm_interrupt,
- IRQF_SHARED, KBUILD_MODNAME, hdspm)) {
- snd_printk(KERN_ERR "HDSPM: unable to use IRQ %d\n", pci->irq);
- return -EBUSY;
- }
-
- snd_printdd("use IRQ %d\n", pci->irq);
-
- hdspm->irq = pci->irq;
-
- snd_printdd("kmalloc Mixer memory of %zd Bytes\n",
- sizeof(struct hdspm_mixer));
- hdspm->mixer = kzalloc(sizeof(struct hdspm_mixer), GFP_KERNEL);
- if (!hdspm->mixer) {
- snd_printk(KERN_ERR "HDSPM: "
- "unable to kmalloc Mixer memory of %d Bytes\n",
- (int)sizeof(struct hdspm_mixer));
- return err;
- }
-
- hdspm->port_names_in = NULL;
- hdspm->port_names_out = NULL;
-
- switch (hdspm->io_type) {
- case AES32:
- hdspm->ss_in_channels = hdspm->ss_out_channels = AES32_CHANNELS;
- hdspm->ds_in_channels = hdspm->ds_out_channels = AES32_CHANNELS;
- hdspm->qs_in_channels = hdspm->qs_out_channels = AES32_CHANNELS;
-
- hdspm->channel_map_in_ss = hdspm->channel_map_out_ss =
- channel_map_aes32;
- hdspm->channel_map_in_ds = hdspm->channel_map_out_ds =
- channel_map_aes32;
- hdspm->channel_map_in_qs = hdspm->channel_map_out_qs =
- channel_map_aes32;
- hdspm->port_names_in_ss = hdspm->port_names_out_ss =
- texts_ports_aes32;
- hdspm->port_names_in_ds = hdspm->port_names_out_ds =
- texts_ports_aes32;
- hdspm->port_names_in_qs = hdspm->port_names_out_qs =
- texts_ports_aes32;
-
- hdspm->max_channels_out = hdspm->max_channels_in =
- AES32_CHANNELS;
- hdspm->port_names_in = hdspm->port_names_out =
- texts_ports_aes32;
- hdspm->channel_map_in = hdspm->channel_map_out =
- channel_map_aes32;
-
- break;
-
- case MADI:
- case MADIface:
- hdspm->ss_in_channels = hdspm->ss_out_channels =
- MADI_SS_CHANNELS;
- hdspm->ds_in_channels = hdspm->ds_out_channels =
- MADI_DS_CHANNELS;
- hdspm->qs_in_channels = hdspm->qs_out_channels =
- MADI_QS_CHANNELS;
-
- hdspm->channel_map_in_ss = hdspm->channel_map_out_ss =
- channel_map_unity_ss;
- hdspm->channel_map_in_ds = hdspm->channel_map_out_ds =
- channel_map_unity_ss;
- hdspm->channel_map_in_qs = hdspm->channel_map_out_qs =
- channel_map_unity_ss;
-
- hdspm->port_names_in_ss = hdspm->port_names_out_ss =
- texts_ports_madi;
- hdspm->port_names_in_ds = hdspm->port_names_out_ds =
- texts_ports_madi;
- hdspm->port_names_in_qs = hdspm->port_names_out_qs =
- texts_ports_madi;
- break;
-
- case AIO:
- if (0 == (hdspm_read(hdspm, HDSPM_statusRegister2) & HDSPM_s2_AEBI_D)) {
- snd_printk(KERN_INFO "HDSPM: AEB input board found, but not supported\n");
- }
-
- hdspm->ss_in_channels = AIO_IN_SS_CHANNELS;
- hdspm->ds_in_channels = AIO_IN_DS_CHANNELS;
- hdspm->qs_in_channels = AIO_IN_QS_CHANNELS;
- hdspm->ss_out_channels = AIO_OUT_SS_CHANNELS;
- hdspm->ds_out_channels = AIO_OUT_DS_CHANNELS;
- hdspm->qs_out_channels = AIO_OUT_QS_CHANNELS;
-
- hdspm->channel_map_out_ss = channel_map_aio_out_ss;
- hdspm->channel_map_out_ds = channel_map_aio_out_ds;
- hdspm->channel_map_out_qs = channel_map_aio_out_qs;
-
- hdspm->channel_map_in_ss = channel_map_aio_in_ss;
- hdspm->channel_map_in_ds = channel_map_aio_in_ds;
- hdspm->channel_map_in_qs = channel_map_aio_in_qs;
-
- hdspm->port_names_in_ss = texts_ports_aio_in_ss;
- hdspm->port_names_out_ss = texts_ports_aio_out_ss;
- hdspm->port_names_in_ds = texts_ports_aio_in_ds;
- hdspm->port_names_out_ds = texts_ports_aio_out_ds;
- hdspm->port_names_in_qs = texts_ports_aio_in_qs;
- hdspm->port_names_out_qs = texts_ports_aio_out_qs;
-
- break;
-
- case RayDAT:
- hdspm->ss_in_channels = hdspm->ss_out_channels =
- RAYDAT_SS_CHANNELS;
- hdspm->ds_in_channels = hdspm->ds_out_channels =
- RAYDAT_DS_CHANNELS;
- hdspm->qs_in_channels = hdspm->qs_out_channels =
- RAYDAT_QS_CHANNELS;
-
- hdspm->max_channels_in = RAYDAT_SS_CHANNELS;
- hdspm->max_channels_out = RAYDAT_SS_CHANNELS;
-
- hdspm->channel_map_in_ss = hdspm->channel_map_out_ss =
- channel_map_raydat_ss;
- hdspm->channel_map_in_ds = hdspm->channel_map_out_ds =
- channel_map_raydat_ds;
- hdspm->channel_map_in_qs = hdspm->channel_map_out_qs =
- channel_map_raydat_qs;
- hdspm->channel_map_in = hdspm->channel_map_out =
- channel_map_raydat_ss;
-
- hdspm->port_names_in_ss = hdspm->port_names_out_ss =
- texts_ports_raydat_ss;
- hdspm->port_names_in_ds = hdspm->port_names_out_ds =
- texts_ports_raydat_ds;
- hdspm->port_names_in_qs = hdspm->port_names_out_qs =
- texts_ports_raydat_qs;
-
-
- break;
-
- }
-
- /* TCO detection */
- switch (hdspm->io_type) {
- case AIO:
- case RayDAT:
- if (hdspm_read(hdspm, HDSPM_statusRegister2) &
- HDSPM_s2_tco_detect) {
- hdspm->midiPorts++;
- hdspm->tco = kzalloc(sizeof(struct hdspm_tco),
- GFP_KERNEL);
- if (NULL != hdspm->tco) {
- hdspm_tco_write(hdspm);
- }
- snd_printk(KERN_INFO "HDSPM: AIO/RayDAT TCO module found\n");
- } else {
- hdspm->tco = NULL;
- }
- break;
-
- case MADI:
- if (hdspm_read(hdspm, HDSPM_statusRegister) & HDSPM_tco_detect) {
- hdspm->midiPorts++;
- hdspm->tco = kzalloc(sizeof(struct hdspm_tco),
- GFP_KERNEL);
- if (NULL != hdspm->tco) {
- hdspm_tco_write(hdspm);
- }
- snd_printk(KERN_INFO "HDSPM: MADI TCO module found\n");
- } else {
- hdspm->tco = NULL;
- }
- break;
-
- default:
- hdspm->tco = NULL;
- }
-
- /* texts */
- switch (hdspm->io_type) {
- case AES32:
- if (hdspm->tco) {
- hdspm->texts_autosync = texts_autosync_aes_tco;
- hdspm->texts_autosync_items = 10;
- } else {
- hdspm->texts_autosync = texts_autosync_aes;
- hdspm->texts_autosync_items = 9;
- }
- break;
-
- case MADI:
- if (hdspm->tco) {
- hdspm->texts_autosync = texts_autosync_madi_tco;
- hdspm->texts_autosync_items = 4;
- } else {
- hdspm->texts_autosync = texts_autosync_madi;
- hdspm->texts_autosync_items = 3;
- }
- break;
-
- case MADIface:
-
- break;
-
- case RayDAT:
- if (hdspm->tco) {
- hdspm->texts_autosync = texts_autosync_raydat_tco;
- hdspm->texts_autosync_items = 9;
- } else {
- hdspm->texts_autosync = texts_autosync_raydat;
- hdspm->texts_autosync_items = 8;
- }
- break;
-
- case AIO:
- if (hdspm->tco) {
- hdspm->texts_autosync = texts_autosync_aio_tco;
- hdspm->texts_autosync_items = 6;
- } else {
- hdspm->texts_autosync = texts_autosync_aio;
- hdspm->texts_autosync_items = 5;
- }
- break;
-
- }
-
- tasklet_init(&hdspm->midi_tasklet,
- hdspm_midi_tasklet, (unsigned long) hdspm);
-
-
- if (hdspm->io_type != MADIface) {
- hdspm->serial = (hdspm_read(hdspm,
- HDSPM_midiStatusIn0)>>8) & 0xFFFFFF;
- /* id contains either a user-provided value or the default
- * NULL. If it's the default, we're safe to
- * fill card->id with the serial number.
- *
- * If the serial number is 0xFFFFFF, then we're dealing with
- * an old PCI revision that comes without a sane number. In
- * this case, we don't set card->id to avoid collisions
- * when running with multiple cards.
- */
- if (NULL == id[hdspm->dev] && hdspm->serial != 0xFFFFFF) {
- sprintf(card->id, "HDSPMx%06x", hdspm->serial);
- snd_card_set_id(card, card->id);
- }
- }
-
- snd_printdd("create alsa devices.\n");
- err = snd_hdspm_create_alsa_devices(card, hdspm);
- if (err < 0)
- return err;
-
- snd_hdspm_initialize_midi_flush(hdspm);
-
- return 0;
-}
-
-
-static int snd_hdspm_free(struct hdspm * hdspm)
-{
-
- if (hdspm->port) {
-
- /* stop th audio, and cancel all interrupts */
- hdspm->control_register &=
- ~(HDSPM_Start | HDSPM_AudioInterruptEnable |
- HDSPM_Midi0InterruptEnable | HDSPM_Midi1InterruptEnable |
- HDSPM_Midi2InterruptEnable | HDSPM_Midi3InterruptEnable);
- hdspm_write(hdspm, HDSPM_controlRegister,
- hdspm->control_register);
- }
-
- if (hdspm->irq >= 0)
- free_irq(hdspm->irq, (void *) hdspm);
-
- kfree(hdspm->mixer);
-
- if (hdspm->iobase)
- iounmap(hdspm->iobase);
-
- if (hdspm->port)
- pci_release_regions(hdspm->pci);
-
- pci_disable_device(hdspm->pci);
- return 0;
-}
-
-
-static void snd_hdspm_card_free(struct snd_card *card)
-{
- struct hdspm *hdspm = card->private_data;
-
- if (hdspm)
- snd_hdspm_free(hdspm);
-}
-
-
-static int __devinit snd_hdspm_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct hdspm *hdspm;
- struct snd_card *card;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev],
- THIS_MODULE, sizeof(struct hdspm), &card);
- if (err < 0)
- return err;
-
- hdspm = card->private_data;
- card->private_free = snd_hdspm_card_free;
- hdspm->dev = dev;
- hdspm->pci = pci;
-
- snd_card_set_dev(card, &pci->dev);
-
- err = snd_hdspm_create(card, hdspm);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- if (hdspm->io_type != MADIface) {
- sprintf(card->shortname, "%s_%x",
- hdspm->card_name,
- hdspm->serial);
- sprintf(card->longname, "%s S/N 0x%x at 0x%lx, irq %d",
- hdspm->card_name,
- hdspm->serial,
- hdspm->port, hdspm->irq);
- } else {
- sprintf(card->shortname, "%s", hdspm->card_name);
- sprintf(card->longname, "%s at 0x%lx, irq %d",
- hdspm->card_name, hdspm->port, hdspm->irq);
- }
-
- err = snd_card_register(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- pci_set_drvdata(pci, card);
-
- dev++;
- return 0;
-}
-
-static void __devexit snd_hdspm_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_hdspm_ids,
- .probe = snd_hdspm_probe,
- .remove = __devexit_p(snd_hdspm_remove),
-};
-
-
-static int __init alsa_card_hdspm_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_hdspm_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_hdspm_init)
-module_exit(alsa_card_hdspm_exit)
diff --git a/ANDROID_3.4.5/sound/pci/rme9652/rme9652.c b/ANDROID_3.4.5/sound/pci/rme9652/rme9652.c
deleted file mode 100644
index b737d161..00000000
--- a/ANDROID_3.4.5/sound/pci/rme9652/rme9652.c
+++ /dev/null
@@ -1,2652 +0,0 @@
-/*
- * ALSA driver for RME Digi9652 audio interfaces
- *
- * Copyright (c) 1999 IEM - Winfried Ritsch
- * Copyright (c) 1999-2001 Paul Davis
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/info.h>
-#include <sound/asoundef.h>
-#include <sound/initval.h>
-
-#include <asm/current.h>
-#include <asm/io.h>
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static bool precise_ptr[SNDRV_CARDS]; /* Enable precise pointer */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for RME Digi9652 (Hammerfall) soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for RME Digi9652 (Hammerfall) soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable/disable specific RME96{52,36} soundcards.");
-module_param_array(precise_ptr, bool, NULL, 0444);
-MODULE_PARM_DESC(precise_ptr, "Enable precise pointer (doesn't work reliably).");
-MODULE_AUTHOR("Paul Davis <pbd@op.net>, Winfried Ritsch");
-MODULE_DESCRIPTION("RME Digi9652/Digi9636");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{RME,Hammerfall},"
- "{RME,Hammerfall-Light}}");
-
-/* The Hammerfall has two sets of 24 ADAT + 2 S/PDIF channels, one for
- capture, one for playback. Both the ADAT and S/PDIF channels appear
- to the host CPU in the same block of memory. There is no functional
- difference between them in terms of access.
-
- The Hammerfall Light is identical to the Hammerfall, except that it
- has 2 sets 18 channels (16 ADAT + 2 S/PDIF) for capture and playback.
-*/
-
-#define RME9652_NCHANNELS 26
-#define RME9636_NCHANNELS 18
-
-/* Preferred sync source choices - used by "sync_pref" control switch */
-
-#define RME9652_SYNC_FROM_SPDIF 0
-#define RME9652_SYNC_FROM_ADAT1 1
-#define RME9652_SYNC_FROM_ADAT2 2
-#define RME9652_SYNC_FROM_ADAT3 3
-
-/* Possible sources of S/PDIF input */
-
-#define RME9652_SPDIFIN_OPTICAL 0 /* optical (ADAT1) */
-#define RME9652_SPDIFIN_COAXIAL 1 /* coaxial (RCA) */
-#define RME9652_SPDIFIN_INTERN 2 /* internal (CDROM) */
-
-/* ------------- Status-Register bits --------------------- */
-
-#define RME9652_IRQ (1<<0) /* IRQ is High if not reset by irq_clear */
-#define RME9652_lock_2 (1<<1) /* ADAT 3-PLL: 1=locked, 0=unlocked */
-#define RME9652_lock_1 (1<<2) /* ADAT 2-PLL: 1=locked, 0=unlocked */
-#define RME9652_lock_0 (1<<3) /* ADAT 1-PLL: 1=locked, 0=unlocked */
-#define RME9652_fs48 (1<<4) /* sample rate is 0=44.1/88.2,1=48/96 Khz */
-#define RME9652_wsel_rd (1<<5) /* if Word-Clock is used and valid then 1 */
- /* bits 6-15 encode h/w buffer pointer position */
-#define RME9652_sync_2 (1<<16) /* if ADAT-IN 3 in sync to system clock */
-#define RME9652_sync_1 (1<<17) /* if ADAT-IN 2 in sync to system clock */
-#define RME9652_sync_0 (1<<18) /* if ADAT-IN 1 in sync to system clock */
-#define RME9652_DS_rd (1<<19) /* 1=Double Speed Mode, 0=Normal Speed */
-#define RME9652_tc_busy (1<<20) /* 1=time-code copy in progress (960ms) */
-#define RME9652_tc_out (1<<21) /* time-code out bit */
-#define RME9652_F_0 (1<<22) /* 000=64kHz, 100=88.2kHz, 011=96kHz */
-#define RME9652_F_1 (1<<23) /* 111=32kHz, 110=44.1kHz, 101=48kHz, */
-#define RME9652_F_2 (1<<24) /* external Crystal Chip if ERF=1 */
-#define RME9652_ERF (1<<25) /* Error-Flag of SDPIF Receiver (1=No Lock) */
-#define RME9652_buffer_id (1<<26) /* toggles by each interrupt on rec/play */
-#define RME9652_tc_valid (1<<27) /* 1 = a signal is detected on time-code input */
-#define RME9652_SPDIF_READ (1<<28) /* byte available from Rev 1.5+ S/PDIF interface */
-
-#define RME9652_sync (RME9652_sync_0|RME9652_sync_1|RME9652_sync_2)
-#define RME9652_lock (RME9652_lock_0|RME9652_lock_1|RME9652_lock_2)
-#define RME9652_F (RME9652_F_0|RME9652_F_1|RME9652_F_2)
-#define rme9652_decode_spdif_rate(x) ((x)>>22)
-
-/* Bit 6..15 : h/w buffer pointer */
-
-#define RME9652_buf_pos 0x000FFC0
-
-/* Bits 31,30,29 are bits 5,4,3 of h/w pointer position on later
- Rev G EEPROMS and Rev 1.5 cards or later.
-*/
-
-#define RME9652_REV15_buf_pos(x) ((((x)&0xE0000000)>>26)|((x)&RME9652_buf_pos))
-
-/* amount of io space we remap for register access. i'm not sure we
- even need this much, but 1K is nice round number :)
-*/
-
-#define RME9652_IO_EXTENT 1024
-
-#define RME9652_init_buffer 0
-#define RME9652_play_buffer 32 /* holds ptr to 26x64kBit host RAM */
-#define RME9652_rec_buffer 36 /* holds ptr to 26x64kBit host RAM */
-#define RME9652_control_register 64
-#define RME9652_irq_clear 96
-#define RME9652_time_code 100 /* useful if used with alesis adat */
-#define RME9652_thru_base 128 /* 132...228 Thru for 26 channels */
-
-/* Read-only registers */
-
-/* Writing to any of the register locations writes to the status
- register. We'll use the first location as our point of access.
-*/
-
-#define RME9652_status_register 0
-
-/* --------- Control-Register Bits ---------------- */
-
-
-#define RME9652_start_bit (1<<0) /* start record/play */
- /* bits 1-3 encode buffersize/latency */
-#define RME9652_Master (1<<4) /* Clock Mode Master=1,Slave/Auto=0 */
-#define RME9652_IE (1<<5) /* Interrupt Enable */
-#define RME9652_freq (1<<6) /* samplerate 0=44.1/88.2, 1=48/96 kHz */
-#define RME9652_freq1 (1<<7) /* if 0, 32kHz, else always 1 */
-#define RME9652_DS (1<<8) /* Doule Speed 0=44.1/48, 1=88.2/96 Khz */
-#define RME9652_PRO (1<<9) /* S/PDIF out: 0=consumer, 1=professional */
-#define RME9652_EMP (1<<10) /* Emphasis 0=None, 1=ON */
-#define RME9652_Dolby (1<<11) /* Non-audio bit 1=set, 0=unset */
-#define RME9652_opt_out (1<<12) /* Use 1st optical OUT as SPDIF: 1=yes,0=no */
-#define RME9652_wsel (1<<13) /* use Wordclock as sync (overwrites master) */
-#define RME9652_inp_0 (1<<14) /* SPDIF-IN: 00=optical (ADAT1), */
-#define RME9652_inp_1 (1<<15) /* 01=koaxial (Cinch), 10=Internal CDROM */
-#define RME9652_SyncPref_ADAT2 (1<<16)
-#define RME9652_SyncPref_ADAT3 (1<<17)
-#define RME9652_SPDIF_RESET (1<<18) /* Rev 1.5+: h/w S/PDIF receiver */
-#define RME9652_SPDIF_SELECT (1<<19)
-#define RME9652_SPDIF_CLOCK (1<<20)
-#define RME9652_SPDIF_WRITE (1<<21)
-#define RME9652_ADAT1_INTERNAL (1<<22) /* Rev 1.5+: if set, internal CD connector carries ADAT */
-
-/* buffersize = 512Bytes * 2^n, where n is made from Bit2 ... Bit0 */
-
-#define RME9652_latency 0x0e
-#define rme9652_encode_latency(x) (((x)&0x7)<<1)
-#define rme9652_decode_latency(x) (((x)>>1)&0x7)
-#define rme9652_running_double_speed(s) ((s)->control_register & RME9652_DS)
-#define RME9652_inp (RME9652_inp_0|RME9652_inp_1)
-#define rme9652_encode_spdif_in(x) (((x)&0x3)<<14)
-#define rme9652_decode_spdif_in(x) (((x)>>14)&0x3)
-
-#define RME9652_SyncPref_Mask (RME9652_SyncPref_ADAT2|RME9652_SyncPref_ADAT3)
-#define RME9652_SyncPref_ADAT1 0
-#define RME9652_SyncPref_SPDIF (RME9652_SyncPref_ADAT2|RME9652_SyncPref_ADAT3)
-
-/* the size of a substream (1 mono data stream) */
-
-#define RME9652_CHANNEL_BUFFER_SAMPLES (16*1024)
-#define RME9652_CHANNEL_BUFFER_BYTES (4*RME9652_CHANNEL_BUFFER_SAMPLES)
-
-/* the size of the area we need to allocate for DMA transfers. the
- size is the same regardless of the number of channels - the
- 9636 still uses the same memory area.
-
- Note that we allocate 1 more channel than is apparently needed
- because the h/w seems to write 1 byte beyond the end of the last
- page. Sigh.
-*/
-
-#define RME9652_DMA_AREA_BYTES ((RME9652_NCHANNELS+1) * RME9652_CHANNEL_BUFFER_BYTES)
-#define RME9652_DMA_AREA_KILOBYTES (RME9652_DMA_AREA_BYTES/1024)
-
-struct snd_rme9652 {
- int dev;
-
- spinlock_t lock;
- int irq;
- unsigned long port;
- void __iomem *iobase;
-
- int precise_ptr;
-
- u32 control_register; /* cached value */
- u32 thru_bits; /* thru 1=on, 0=off channel 1=Bit1... channel 26= Bit26 */
-
- u32 creg_spdif;
- u32 creg_spdif_stream;
-
- char *card_name; /* hammerfall or hammerfall light names */
-
- size_t hw_offsetmask; /* &-with status register to get real hw_offset */
- size_t prev_hw_offset; /* previous hw offset */
- size_t max_jitter; /* maximum jitter in frames for
- hw pointer */
- size_t period_bytes; /* guess what this is */
-
- unsigned char ds_channels;
- unsigned char ss_channels; /* different for hammerfall/hammerfall-light */
-
- struct snd_dma_buffer playback_dma_buf;
- struct snd_dma_buffer capture_dma_buf;
-
- unsigned char *capture_buffer; /* suitably aligned address */
- unsigned char *playback_buffer; /* suitably aligned address */
-
- pid_t capture_pid;
- pid_t playback_pid;
-
- struct snd_pcm_substream *capture_substream;
- struct snd_pcm_substream *playback_substream;
- int running;
-
- int passthru; /* non-zero if doing pass-thru */
- int hw_rev; /* h/w rev * 10 (i.e. 1.5 has hw_rev = 15) */
-
- int last_spdif_sample_rate; /* so that we can catch externally ... */
- int last_adat_sample_rate; /* ... induced rate changes */
-
- char *channel_map;
-
- struct snd_card *card;
- struct snd_pcm *pcm;
- struct pci_dev *pci;
- struct snd_kcontrol *spdif_ctl;
-
-};
-
-/* These tables map the ALSA channels 1..N to the channels that we
- need to use in order to find the relevant channel buffer. RME
- refer to this kind of mapping as between "the ADAT channel and
- the DMA channel." We index it using the logical audio channel,
- and the value is the DMA channel (i.e. channel buffer number)
- where the data for that channel can be read/written from/to.
-*/
-
-static char channel_map_9652_ss[26] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 24, 25
-};
-
-static char channel_map_9636_ss[26] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- /* channels 16 and 17 are S/PDIF */
- 24, 25,
- /* channels 18-25 don't exist */
- -1, -1, -1, -1, -1, -1, -1, -1
-};
-
-static char channel_map_9652_ds[26] = {
- /* ADAT channels are remapped */
- 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23,
- /* channels 12 and 13 are S/PDIF */
- 24, 25,
- /* others don't exist */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
-};
-
-static char channel_map_9636_ds[26] = {
- /* ADAT channels are remapped */
- 1, 3, 5, 7, 9, 11, 13, 15,
- /* channels 8 and 9 are S/PDIF */
- 24, 25
- /* others don't exist */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
-};
-
-static int snd_hammerfall_get_buffer(struct pci_dev *pci, struct snd_dma_buffer *dmab, size_t size)
-{
- dmab->dev.type = SNDRV_DMA_TYPE_DEV;
- dmab->dev.dev = snd_dma_pci_data(pci);
- if (snd_dma_get_reserved_buf(dmab, snd_dma_pci_buf_id(pci))) {
- if (dmab->bytes >= size)
- return 0;
- }
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
- size, dmab) < 0)
- return -ENOMEM;
- return 0;
-}
-
-static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_dev *pci)
-{
- if (dmab->area) {
- dmab->dev.dev = NULL; /* make it anonymous */
- snd_dma_reserve_buf(dmab, snd_dma_pci_buf_id(pci));
- }
-}
-
-
-static DEFINE_PCI_DEVICE_TABLE(snd_rme9652_ids) = {
- {
- .vendor = 0x10ee,
- .device = 0x3fc4,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- }, /* RME Digi9652 */
- { 0, },
-};
-
-MODULE_DEVICE_TABLE(pci, snd_rme9652_ids);
-
-static inline void rme9652_write(struct snd_rme9652 *rme9652, int reg, int val)
-{
- writel(val, rme9652->iobase + reg);
-}
-
-static inline unsigned int rme9652_read(struct snd_rme9652 *rme9652, int reg)
-{
- return readl(rme9652->iobase + reg);
-}
-
-static inline int snd_rme9652_use_is_exclusive(struct snd_rme9652 *rme9652)
-{
- unsigned long flags;
- int ret = 1;
-
- spin_lock_irqsave(&rme9652->lock, flags);
- if ((rme9652->playback_pid != rme9652->capture_pid) &&
- (rme9652->playback_pid >= 0) && (rme9652->capture_pid >= 0)) {
- ret = 0;
- }
- spin_unlock_irqrestore(&rme9652->lock, flags);
- return ret;
-}
-
-static inline int rme9652_adat_sample_rate(struct snd_rme9652 *rme9652)
-{
- if (rme9652_running_double_speed(rme9652)) {
- return (rme9652_read(rme9652, RME9652_status_register) &
- RME9652_fs48) ? 96000 : 88200;
- } else {
- return (rme9652_read(rme9652, RME9652_status_register) &
- RME9652_fs48) ? 48000 : 44100;
- }
-}
-
-static inline void rme9652_compute_period_size(struct snd_rme9652 *rme9652)
-{
- unsigned int i;
-
- i = rme9652->control_register & RME9652_latency;
- rme9652->period_bytes = 1 << ((rme9652_decode_latency(i) + 8));
- rme9652->hw_offsetmask =
- (rme9652->period_bytes * 2 - 1) & RME9652_buf_pos;
- rme9652->max_jitter = 80;
-}
-
-static snd_pcm_uframes_t rme9652_hw_pointer(struct snd_rme9652 *rme9652)
-{
- int status;
- unsigned int offset, frag;
- snd_pcm_uframes_t period_size = rme9652->period_bytes / 4;
- snd_pcm_sframes_t delta;
-
- status = rme9652_read(rme9652, RME9652_status_register);
- if (!rme9652->precise_ptr)
- return (status & RME9652_buffer_id) ? period_size : 0;
- offset = status & RME9652_buf_pos;
-
- /* The hardware may give a backward movement for up to 80 frames
- Martin Kirst <martin.kirst@freenet.de> knows the details.
- */
-
- delta = rme9652->prev_hw_offset - offset;
- delta &= 0xffff;
- if (delta <= (snd_pcm_sframes_t)rme9652->max_jitter * 4)
- offset = rme9652->prev_hw_offset;
- else
- rme9652->prev_hw_offset = offset;
- offset &= rme9652->hw_offsetmask;
- offset /= 4;
- frag = status & RME9652_buffer_id;
-
- if (offset < period_size) {
- if (offset > rme9652->max_jitter) {
- if (frag)
- printk(KERN_ERR "Unexpected hw_pointer position (bufid == 0): status: %x offset: %d\n", status, offset);
- } else if (!frag)
- return 0;
- offset -= rme9652->max_jitter;
- if ((int)offset < 0)
- offset += period_size * 2;
- } else {
- if (offset > period_size + rme9652->max_jitter) {
- if (!frag)
- printk(KERN_ERR "Unexpected hw_pointer position (bufid == 1): status: %x offset: %d\n", status, offset);
- } else if (frag)
- return period_size;
- offset -= rme9652->max_jitter;
- }
-
- return offset;
-}
-
-static inline void rme9652_reset_hw_pointer(struct snd_rme9652 *rme9652)
-{
- int i;
-
- /* reset the FIFO pointer to zero. We do this by writing to 8
- registers, each of which is a 32bit wide register, and set
- them all to zero. Note that s->iobase is a pointer to
- int32, not pointer to char.
- */
-
- for (i = 0; i < 8; i++) {
- rme9652_write(rme9652, i * 4, 0);
- udelay(10);
- }
- rme9652->prev_hw_offset = 0;
-}
-
-static inline void rme9652_start(struct snd_rme9652 *s)
-{
- s->control_register |= (RME9652_IE | RME9652_start_bit);
- rme9652_write(s, RME9652_control_register, s->control_register);
-}
-
-static inline void rme9652_stop(struct snd_rme9652 *s)
-{
- s->control_register &= ~(RME9652_start_bit | RME9652_IE);
- rme9652_write(s, RME9652_control_register, s->control_register);
-}
-
-static int rme9652_set_interrupt_interval(struct snd_rme9652 *s,
- unsigned int frames)
-{
- int restart = 0;
- int n;
-
- spin_lock_irq(&s->lock);
-
- if ((restart = s->running)) {
- rme9652_stop(s);
- }
-
- frames >>= 7;
- n = 0;
- while (frames) {
- n++;
- frames >>= 1;
- }
-
- s->control_register &= ~RME9652_latency;
- s->control_register |= rme9652_encode_latency(n);
-
- rme9652_write(s, RME9652_control_register, s->control_register);
-
- rme9652_compute_period_size(s);
-
- if (restart)
- rme9652_start(s);
-
- spin_unlock_irq(&s->lock);
-
- return 0;
-}
-
-static int rme9652_set_rate(struct snd_rme9652 *rme9652, int rate)
-{
- int restart;
- int reject_if_open = 0;
- int xrate;
-
- if (!snd_rme9652_use_is_exclusive (rme9652)) {
- return -EBUSY;
- }
-
- /* Changing from a "single speed" to a "double speed" rate is
- not allowed if any substreams are open. This is because
- such a change causes a shift in the location of
- the DMA buffers and a reduction in the number of available
- buffers.
-
- Note that a similar but essentially insoluble problem
- exists for externally-driven rate changes. All we can do
- is to flag rate changes in the read/write routines.
- */
-
- spin_lock_irq(&rme9652->lock);
- xrate = rme9652_adat_sample_rate(rme9652);
-
- switch (rate) {
- case 44100:
- if (xrate > 48000) {
- reject_if_open = 1;
- }
- rate = 0;
- break;
- case 48000:
- if (xrate > 48000) {
- reject_if_open = 1;
- }
- rate = RME9652_freq;
- break;
- case 88200:
- if (xrate < 48000) {
- reject_if_open = 1;
- }
- rate = RME9652_DS;
- break;
- case 96000:
- if (xrate < 48000) {
- reject_if_open = 1;
- }
- rate = RME9652_DS | RME9652_freq;
- break;
- default:
- spin_unlock_irq(&rme9652->lock);
- return -EINVAL;
- }
-
- if (reject_if_open && (rme9652->capture_pid >= 0 || rme9652->playback_pid >= 0)) {
- spin_unlock_irq(&rme9652->lock);
- return -EBUSY;
- }
-
- if ((restart = rme9652->running)) {
- rme9652_stop(rme9652);
- }
- rme9652->control_register &= ~(RME9652_freq | RME9652_DS);
- rme9652->control_register |= rate;
- rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
-
- if (restart) {
- rme9652_start(rme9652);
- }
-
- if (rate & RME9652_DS) {
- if (rme9652->ss_channels == RME9652_NCHANNELS) {
- rme9652->channel_map = channel_map_9652_ds;
- } else {
- rme9652->channel_map = channel_map_9636_ds;
- }
- } else {
- if (rme9652->ss_channels == RME9652_NCHANNELS) {
- rme9652->channel_map = channel_map_9652_ss;
- } else {
- rme9652->channel_map = channel_map_9636_ss;
- }
- }
-
- spin_unlock_irq(&rme9652->lock);
- return 0;
-}
-
-static void rme9652_set_thru(struct snd_rme9652 *rme9652, int channel, int enable)
-{
- int i;
-
- rme9652->passthru = 0;
-
- if (channel < 0) {
-
- /* set thru for all channels */
-
- if (enable) {
- for (i = 0; i < RME9652_NCHANNELS; i++) {
- rme9652->thru_bits |= (1 << i);
- rme9652_write(rme9652, RME9652_thru_base + i * 4, 1);
- }
- } else {
- for (i = 0; i < RME9652_NCHANNELS; i++) {
- rme9652->thru_bits &= ~(1 << i);
- rme9652_write(rme9652, RME9652_thru_base + i * 4, 0);
- }
- }
-
- } else {
- int mapped_channel;
-
- mapped_channel = rme9652->channel_map[channel];
-
- if (enable) {
- rme9652->thru_bits |= (1 << mapped_channel);
- } else {
- rme9652->thru_bits &= ~(1 << mapped_channel);
- }
-
- rme9652_write(rme9652,
- RME9652_thru_base + mapped_channel * 4,
- enable ? 1 : 0);
- }
-}
-
-static int rme9652_set_passthru(struct snd_rme9652 *rme9652, int onoff)
-{
- if (onoff) {
- rme9652_set_thru(rme9652, -1, 1);
-
- /* we don't want interrupts, so do a
- custom version of rme9652_start().
- */
-
- rme9652->control_register =
- RME9652_inp_0 |
- rme9652_encode_latency(7) |
- RME9652_start_bit;
-
- rme9652_reset_hw_pointer(rme9652);
-
- rme9652_write(rme9652, RME9652_control_register,
- rme9652->control_register);
- rme9652->passthru = 1;
- } else {
- rme9652_set_thru(rme9652, -1, 0);
- rme9652_stop(rme9652);
- rme9652->passthru = 0;
- }
-
- return 0;
-}
-
-static void rme9652_spdif_set_bit (struct snd_rme9652 *rme9652, int mask, int onoff)
-{
- if (onoff)
- rme9652->control_register |= mask;
- else
- rme9652->control_register &= ~mask;
-
- rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
-}
-
-static void rme9652_spdif_write_byte (struct snd_rme9652 *rme9652, const int val)
-{
- long mask;
- long i;
-
- for (i = 0, mask = 0x80; i < 8; i++, mask >>= 1) {
- if (val & mask)
- rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_WRITE, 1);
- else
- rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_WRITE, 0);
-
- rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_CLOCK, 1);
- rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_CLOCK, 0);
- }
-}
-
-static int rme9652_spdif_read_byte (struct snd_rme9652 *rme9652)
-{
- long mask;
- long val;
- long i;
-
- val = 0;
-
- for (i = 0, mask = 0x80; i < 8; i++, mask >>= 1) {
- rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_CLOCK, 1);
- if (rme9652_read (rme9652, RME9652_status_register) & RME9652_SPDIF_READ)
- val |= mask;
- rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_CLOCK, 0);
- }
-
- return val;
-}
-
-static void rme9652_write_spdif_codec (struct snd_rme9652 *rme9652, const int address, const int data)
-{
- rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 1);
- rme9652_spdif_write_byte (rme9652, 0x20);
- rme9652_spdif_write_byte (rme9652, address);
- rme9652_spdif_write_byte (rme9652, data);
- rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 0);
-}
-
-
-static int rme9652_spdif_read_codec (struct snd_rme9652 *rme9652, const int address)
-{
- int ret;
-
- rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 1);
- rme9652_spdif_write_byte (rme9652, 0x20);
- rme9652_spdif_write_byte (rme9652, address);
- rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 0);
- rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 1);
-
- rme9652_spdif_write_byte (rme9652, 0x21);
- ret = rme9652_spdif_read_byte (rme9652);
- rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 0);
-
- return ret;
-}
-
-static void rme9652_initialize_spdif_receiver (struct snd_rme9652 *rme9652)
-{
- /* XXX what unsets this ? */
-
- rme9652->control_register |= RME9652_SPDIF_RESET;
-
- rme9652_write_spdif_codec (rme9652, 4, 0x40);
- rme9652_write_spdif_codec (rme9652, 17, 0x13);
- rme9652_write_spdif_codec (rme9652, 6, 0x02);
-}
-
-static inline int rme9652_spdif_sample_rate(struct snd_rme9652 *s)
-{
- unsigned int rate_bits;
-
- if (rme9652_read(s, RME9652_status_register) & RME9652_ERF) {
- return -1; /* error condition */
- }
-
- if (s->hw_rev == 15) {
-
- int x, y, ret;
-
- x = rme9652_spdif_read_codec (s, 30);
-
- if (x != 0)
- y = 48000 * 64 / x;
- else
- y = 0;
-
- if (y > 30400 && y < 33600) ret = 32000;
- else if (y > 41900 && y < 46000) ret = 44100;
- else if (y > 46000 && y < 50400) ret = 48000;
- else if (y > 60800 && y < 67200) ret = 64000;
- else if (y > 83700 && y < 92000) ret = 88200;
- else if (y > 92000 && y < 100000) ret = 96000;
- else ret = 0;
- return ret;
- }
-
- rate_bits = rme9652_read(s, RME9652_status_register) & RME9652_F;
-
- switch (rme9652_decode_spdif_rate(rate_bits)) {
- case 0x7:
- return 32000;
- break;
-
- case 0x6:
- return 44100;
- break;
-
- case 0x5:
- return 48000;
- break;
-
- case 0x4:
- return 88200;
- break;
-
- case 0x3:
- return 96000;
- break;
-
- case 0x0:
- return 64000;
- break;
-
- default:
- snd_printk(KERN_ERR "%s: unknown S/PDIF input rate (bits = 0x%x)\n",
- s->card_name, rate_bits);
- return 0;
- break;
- }
-}
-
-/*-----------------------------------------------------------------------------
- Control Interface
- ----------------------------------------------------------------------------*/
-
-static u32 snd_rme9652_convert_from_aes(struct snd_aes_iec958 *aes)
-{
- u32 val = 0;
- val |= (aes->status[0] & IEC958_AES0_PROFESSIONAL) ? RME9652_PRO : 0;
- val |= (aes->status[0] & IEC958_AES0_NONAUDIO) ? RME9652_Dolby : 0;
- if (val & RME9652_PRO)
- val |= (aes->status[0] & IEC958_AES0_PRO_EMPHASIS_5015) ? RME9652_EMP : 0;
- else
- val |= (aes->status[0] & IEC958_AES0_CON_EMPHASIS_5015) ? RME9652_EMP : 0;
- return val;
-}
-
-static void snd_rme9652_convert_to_aes(struct snd_aes_iec958 *aes, u32 val)
-{
- aes->status[0] = ((val & RME9652_PRO) ? IEC958_AES0_PROFESSIONAL : 0) |
- ((val & RME9652_Dolby) ? IEC958_AES0_NONAUDIO : 0);
- if (val & RME9652_PRO)
- aes->status[0] |= (val & RME9652_EMP) ? IEC958_AES0_PRO_EMPHASIS_5015 : 0;
- else
- aes->status[0] |= (val & RME9652_EMP) ? IEC958_AES0_CON_EMPHASIS_5015 : 0;
-}
-
-static int snd_rme9652_control_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_rme9652_control_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
-
- snd_rme9652_convert_to_aes(&ucontrol->value.iec958, rme9652->creg_spdif);
- return 0;
-}
-
-static int snd_rme9652_control_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
- int change;
- u32 val;
-
- val = snd_rme9652_convert_from_aes(&ucontrol->value.iec958);
- spin_lock_irq(&rme9652->lock);
- change = val != rme9652->creg_spdif;
- rme9652->creg_spdif = val;
- spin_unlock_irq(&rme9652->lock);
- return change;
-}
-
-static int snd_rme9652_control_spdif_stream_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_rme9652_control_spdif_stream_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
-
- snd_rme9652_convert_to_aes(&ucontrol->value.iec958, rme9652->creg_spdif_stream);
- return 0;
-}
-
-static int snd_rme9652_control_spdif_stream_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
- int change;
- u32 val;
-
- val = snd_rme9652_convert_from_aes(&ucontrol->value.iec958);
- spin_lock_irq(&rme9652->lock);
- change = val != rme9652->creg_spdif_stream;
- rme9652->creg_spdif_stream = val;
- rme9652->control_register &= ~(RME9652_PRO | RME9652_Dolby | RME9652_EMP);
- rme9652_write(rme9652, RME9652_control_register, rme9652->control_register |= val);
- spin_unlock_irq(&rme9652->lock);
- return change;
-}
-
-static int snd_rme9652_control_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_rme9652_control_spdif_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.iec958.status[0] = kcontrol->private_value;
- return 0;
-}
-
-#define RME9652_ADAT1_IN(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_rme9652_info_adat1_in, \
- .get = snd_rme9652_get_adat1_in, \
- .put = snd_rme9652_put_adat1_in }
-
-static unsigned int rme9652_adat1_in(struct snd_rme9652 *rme9652)
-{
- if (rme9652->control_register & RME9652_ADAT1_INTERNAL)
- return 1;
- return 0;
-}
-
-static int rme9652_set_adat1_input(struct snd_rme9652 *rme9652, int internal)
-{
- int restart = 0;
-
- if (internal) {
- rme9652->control_register |= RME9652_ADAT1_INTERNAL;
- } else {
- rme9652->control_register &= ~RME9652_ADAT1_INTERNAL;
- }
-
- /* XXX do we actually need to stop the card when we do this ? */
-
- if ((restart = rme9652->running)) {
- rme9652_stop(rme9652);
- }
-
- rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
-
- if (restart) {
- rme9652_start(rme9652);
- }
-
- return 0;
-}
-
-static int snd_rme9652_info_adat1_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[2] = {"ADAT1", "Internal"};
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item > 1)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_rme9652_get_adat1_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&rme9652->lock);
- ucontrol->value.enumerated.item[0] = rme9652_adat1_in(rme9652);
- spin_unlock_irq(&rme9652->lock);
- return 0;
-}
-
-static int snd_rme9652_put_adat1_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_rme9652_use_is_exclusive(rme9652))
- return -EBUSY;
- val = ucontrol->value.enumerated.item[0] % 2;
- spin_lock_irq(&rme9652->lock);
- change = val != rme9652_adat1_in(rme9652);
- if (change)
- rme9652_set_adat1_input(rme9652, val);
- spin_unlock_irq(&rme9652->lock);
- return change;
-}
-
-#define RME9652_SPDIF_IN(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_rme9652_info_spdif_in, \
- .get = snd_rme9652_get_spdif_in, .put = snd_rme9652_put_spdif_in }
-
-static unsigned int rme9652_spdif_in(struct snd_rme9652 *rme9652)
-{
- return rme9652_decode_spdif_in(rme9652->control_register &
- RME9652_inp);
-}
-
-static int rme9652_set_spdif_input(struct snd_rme9652 *rme9652, int in)
-{
- int restart = 0;
-
- rme9652->control_register &= ~RME9652_inp;
- rme9652->control_register |= rme9652_encode_spdif_in(in);
-
- if ((restart = rme9652->running)) {
- rme9652_stop(rme9652);
- }
-
- rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
-
- if (restart) {
- rme9652_start(rme9652);
- }
-
- return 0;
-}
-
-static int snd_rme9652_info_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[3] = {"ADAT1", "Coaxial", "Internal"};
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item > 2)
- uinfo->value.enumerated.item = 2;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_rme9652_get_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&rme9652->lock);
- ucontrol->value.enumerated.item[0] = rme9652_spdif_in(rme9652);
- spin_unlock_irq(&rme9652->lock);
- return 0;
-}
-
-static int snd_rme9652_put_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_rme9652_use_is_exclusive(rme9652))
- return -EBUSY;
- val = ucontrol->value.enumerated.item[0] % 3;
- spin_lock_irq(&rme9652->lock);
- change = val != rme9652_spdif_in(rme9652);
- if (change)
- rme9652_set_spdif_input(rme9652, val);
- spin_unlock_irq(&rme9652->lock);
- return change;
-}
-
-#define RME9652_SPDIF_OUT(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_rme9652_info_spdif_out, \
- .get = snd_rme9652_get_spdif_out, .put = snd_rme9652_put_spdif_out }
-
-static int rme9652_spdif_out(struct snd_rme9652 *rme9652)
-{
- return (rme9652->control_register & RME9652_opt_out) ? 1 : 0;
-}
-
-static int rme9652_set_spdif_output(struct snd_rme9652 *rme9652, int out)
-{
- int restart = 0;
-
- if (out) {
- rme9652->control_register |= RME9652_opt_out;
- } else {
- rme9652->control_register &= ~RME9652_opt_out;
- }
-
- if ((restart = rme9652->running)) {
- rme9652_stop(rme9652);
- }
-
- rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
-
- if (restart) {
- rme9652_start(rme9652);
- }
-
- return 0;
-}
-
-#define snd_rme9652_info_spdif_out snd_ctl_boolean_mono_info
-
-static int snd_rme9652_get_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&rme9652->lock);
- ucontrol->value.integer.value[0] = rme9652_spdif_out(rme9652);
- spin_unlock_irq(&rme9652->lock);
- return 0;
-}
-
-static int snd_rme9652_put_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- if (!snd_rme9652_use_is_exclusive(rme9652))
- return -EBUSY;
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&rme9652->lock);
- change = (int)val != rme9652_spdif_out(rme9652);
- rme9652_set_spdif_output(rme9652, val);
- spin_unlock_irq(&rme9652->lock);
- return change;
-}
-
-#define RME9652_SYNC_MODE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_rme9652_info_sync_mode, \
- .get = snd_rme9652_get_sync_mode, .put = snd_rme9652_put_sync_mode }
-
-static int rme9652_sync_mode(struct snd_rme9652 *rme9652)
-{
- if (rme9652->control_register & RME9652_wsel) {
- return 2;
- } else if (rme9652->control_register & RME9652_Master) {
- return 1;
- } else {
- return 0;
- }
-}
-
-static int rme9652_set_sync_mode(struct snd_rme9652 *rme9652, int mode)
-{
- int restart = 0;
-
- switch (mode) {
- case 0:
- rme9652->control_register &=
- ~(RME9652_Master | RME9652_wsel);
- break;
- case 1:
- rme9652->control_register =
- (rme9652->control_register & ~RME9652_wsel) | RME9652_Master;
- break;
- case 2:
- rme9652->control_register |=
- (RME9652_Master | RME9652_wsel);
- break;
- }
-
- if ((restart = rme9652->running)) {
- rme9652_stop(rme9652);
- }
-
- rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
-
- if (restart) {
- rme9652_start(rme9652);
- }
-
- return 0;
-}
-
-static int snd_rme9652_info_sync_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[3] = {"AutoSync", "Master", "Word Clock"};
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item > 2)
- uinfo->value.enumerated.item = 2;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_rme9652_get_sync_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&rme9652->lock);
- ucontrol->value.enumerated.item[0] = rme9652_sync_mode(rme9652);
- spin_unlock_irq(&rme9652->lock);
- return 0;
-}
-
-static int snd_rme9652_put_sync_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
-
- val = ucontrol->value.enumerated.item[0] % 3;
- spin_lock_irq(&rme9652->lock);
- change = (int)val != rme9652_sync_mode(rme9652);
- rme9652_set_sync_mode(rme9652, val);
- spin_unlock_irq(&rme9652->lock);
- return change;
-}
-
-#define RME9652_SYNC_PREF(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_rme9652_info_sync_pref, \
- .get = snd_rme9652_get_sync_pref, .put = snd_rme9652_put_sync_pref }
-
-static int rme9652_sync_pref(struct snd_rme9652 *rme9652)
-{
- switch (rme9652->control_register & RME9652_SyncPref_Mask) {
- case RME9652_SyncPref_ADAT1:
- return RME9652_SYNC_FROM_ADAT1;
- case RME9652_SyncPref_ADAT2:
- return RME9652_SYNC_FROM_ADAT2;
- case RME9652_SyncPref_ADAT3:
- return RME9652_SYNC_FROM_ADAT3;
- case RME9652_SyncPref_SPDIF:
- return RME9652_SYNC_FROM_SPDIF;
- }
- /* Not reachable */
- return 0;
-}
-
-static int rme9652_set_sync_pref(struct snd_rme9652 *rme9652, int pref)
-{
- int restart;
-
- rme9652->control_register &= ~RME9652_SyncPref_Mask;
- switch (pref) {
- case RME9652_SYNC_FROM_ADAT1:
- rme9652->control_register |= RME9652_SyncPref_ADAT1;
- break;
- case RME9652_SYNC_FROM_ADAT2:
- rme9652->control_register |= RME9652_SyncPref_ADAT2;
- break;
- case RME9652_SYNC_FROM_ADAT3:
- rme9652->control_register |= RME9652_SyncPref_ADAT3;
- break;
- case RME9652_SYNC_FROM_SPDIF:
- rme9652->control_register |= RME9652_SyncPref_SPDIF;
- break;
- }
-
- if ((restart = rme9652->running)) {
- rme9652_stop(rme9652);
- }
-
- rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
-
- if (restart) {
- rme9652_start(rme9652);
- }
-
- return 0;
-}
-
-static int snd_rme9652_info_sync_pref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[4] = {"IEC958 In", "ADAT1 In", "ADAT2 In", "ADAT3 In"};
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = rme9652->ss_channels == RME9652_NCHANNELS ? 4 : 3;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_rme9652_get_sync_pref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&rme9652->lock);
- ucontrol->value.enumerated.item[0] = rme9652_sync_pref(rme9652);
- spin_unlock_irq(&rme9652->lock);
- return 0;
-}
-
-static int snd_rme9652_put_sync_pref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
- int change, max;
- unsigned int val;
-
- if (!snd_rme9652_use_is_exclusive(rme9652))
- return -EBUSY;
- max = rme9652->ss_channels == RME9652_NCHANNELS ? 4 : 3;
- val = ucontrol->value.enumerated.item[0] % max;
- spin_lock_irq(&rme9652->lock);
- change = (int)val != rme9652_sync_pref(rme9652);
- rme9652_set_sync_pref(rme9652, val);
- spin_unlock_irq(&rme9652->lock);
- return change;
-}
-
-static int snd_rme9652_info_thru(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = rme9652->ss_channels;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int snd_rme9652_get_thru(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
- unsigned int k;
- u32 thru_bits = rme9652->thru_bits;
-
- for (k = 0; k < rme9652->ss_channels; ++k) {
- ucontrol->value.integer.value[k] = !!(thru_bits & (1 << k));
- }
- return 0;
-}
-
-static int snd_rme9652_put_thru(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int chn;
- u32 thru_bits = 0;
-
- if (!snd_rme9652_use_is_exclusive(rme9652))
- return -EBUSY;
-
- for (chn = 0; chn < rme9652->ss_channels; ++chn) {
- if (ucontrol->value.integer.value[chn])
- thru_bits |= 1 << chn;
- }
-
- spin_lock_irq(&rme9652->lock);
- change = thru_bits ^ rme9652->thru_bits;
- if (change) {
- for (chn = 0; chn < rme9652->ss_channels; ++chn) {
- if (!(change & (1 << chn)))
- continue;
- rme9652_set_thru(rme9652,chn,thru_bits&(1<<chn));
- }
- }
- spin_unlock_irq(&rme9652->lock);
- return !!change;
-}
-
-#define RME9652_PASSTHRU(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_rme9652_info_passthru, \
- .put = snd_rme9652_put_passthru, \
- .get = snd_rme9652_get_passthru }
-
-#define snd_rme9652_info_passthru snd_ctl_boolean_mono_info
-
-static int snd_rme9652_get_passthru(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&rme9652->lock);
- ucontrol->value.integer.value[0] = rme9652->passthru;
- spin_unlock_irq(&rme9652->lock);
- return 0;
-}
-
-static int snd_rme9652_put_passthru(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
- int change;
- unsigned int val;
- int err = 0;
-
- if (!snd_rme9652_use_is_exclusive(rme9652))
- return -EBUSY;
-
- val = ucontrol->value.integer.value[0] & 1;
- spin_lock_irq(&rme9652->lock);
- change = (ucontrol->value.integer.value[0] != rme9652->passthru);
- if (change)
- err = rme9652_set_passthru(rme9652, val);
- spin_unlock_irq(&rme9652->lock);
- return err ? err : change;
-}
-
-/* Read-only switches */
-
-#define RME9652_SPDIF_RATE(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
- .info = snd_rme9652_info_spdif_rate, \
- .get = snd_rme9652_get_spdif_rate }
-
-static int snd_rme9652_info_spdif_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 96000;
- return 0;
-}
-
-static int snd_rme9652_get_spdif_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&rme9652->lock);
- ucontrol->value.integer.value[0] = rme9652_spdif_sample_rate(rme9652);
- spin_unlock_irq(&rme9652->lock);
- return 0;
-}
-
-#define RME9652_ADAT_SYNC(xname, xindex, xidx) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
- .info = snd_rme9652_info_adat_sync, \
- .get = snd_rme9652_get_adat_sync, .private_value = xidx }
-
-static int snd_rme9652_info_adat_sync(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[4] = {"No Lock", "Lock", "No Lock Sync", "Lock Sync"};
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 4;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
- uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_rme9652_get_adat_sync(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
- unsigned int mask1, mask2, val;
-
- switch (kcontrol->private_value) {
- case 0: mask1 = RME9652_lock_0; mask2 = RME9652_sync_0; break;
- case 1: mask1 = RME9652_lock_1; mask2 = RME9652_sync_1; break;
- case 2: mask1 = RME9652_lock_2; mask2 = RME9652_sync_2; break;
- default: return -EINVAL;
- }
- val = rme9652_read(rme9652, RME9652_status_register);
- ucontrol->value.enumerated.item[0] = (val & mask1) ? 1 : 0;
- ucontrol->value.enumerated.item[0] |= (val & mask2) ? 2 : 0;
- return 0;
-}
-
-#define RME9652_TC_VALID(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
- .info = snd_rme9652_info_tc_valid, \
- .get = snd_rme9652_get_tc_valid }
-
-#define snd_rme9652_info_tc_valid snd_ctl_boolean_mono_info
-
-static int snd_rme9652_get_tc_valid(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] =
- (rme9652_read(rme9652, RME9652_status_register) & RME9652_tc_valid) ? 1 : 0;
- return 0;
-}
-
-#ifdef ALSA_HAS_STANDARD_WAY_OF_RETURNING_TIMECODE
-
-/* FIXME: this routine needs a port to the new control API --jk */
-
-static int snd_rme9652_get_tc_value(void *private_data,
- snd_kswitch_t *kswitch,
- snd_switch_t *uswitch)
-{
- struct snd_rme9652 *s = (struct snd_rme9652 *) private_data;
- u32 value;
- int i;
-
- uswitch->type = SNDRV_SW_TYPE_DWORD;
-
- if ((rme9652_read(s, RME9652_status_register) &
- RME9652_tc_valid) == 0) {
- uswitch->value.data32[0] = 0;
- return 0;
- }
-
- /* timecode request */
-
- rme9652_write(s, RME9652_time_code, 0);
-
- /* XXX bug alert: loop-based timing !!!! */
-
- for (i = 0; i < 50; i++) {
- if (!(rme9652_read(s, i * 4) & RME9652_tc_busy))
- break;
- }
-
- if (!(rme9652_read(s, i * 4) & RME9652_tc_busy)) {
- return -EIO;
- }
-
- value = 0;
-
- for (i = 0; i < 32; i++) {
- value >>= 1;
-
- if (rme9652_read(s, i * 4) & RME9652_tc_out)
- value |= 0x80000000;
- }
-
- if (value > 2 * 60 * 48000) {
- value -= 2 * 60 * 48000;
- } else {
- value = 0;
- }
-
- uswitch->value.data32[0] = value;
-
- return 0;
-}
-
-#endif /* ALSA_HAS_STANDARD_WAY_OF_RETURNING_TIMECODE */
-
-static struct snd_kcontrol_new snd_rme9652_controls[] = {
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
- .info = snd_rme9652_control_spdif_info,
- .get = snd_rme9652_control_spdif_get,
- .put = snd_rme9652_control_spdif_put,
-},
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
- .info = snd_rme9652_control_spdif_stream_info,
- .get = snd_rme9652_control_spdif_stream_get,
- .put = snd_rme9652_control_spdif_stream_put,
-},
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
- .info = snd_rme9652_control_spdif_mask_info,
- .get = snd_rme9652_control_spdif_mask_get,
- .private_value = IEC958_AES0_NONAUDIO |
- IEC958_AES0_PROFESSIONAL |
- IEC958_AES0_CON_EMPHASIS,
-},
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
- .info = snd_rme9652_control_spdif_mask_info,
- .get = snd_rme9652_control_spdif_mask_get,
- .private_value = IEC958_AES0_NONAUDIO |
- IEC958_AES0_PROFESSIONAL |
- IEC958_AES0_PRO_EMPHASIS,
-},
-RME9652_SPDIF_IN("IEC958 Input Connector", 0),
-RME9652_SPDIF_OUT("IEC958 Output also on ADAT1", 0),
-RME9652_SYNC_MODE("Sync Mode", 0),
-RME9652_SYNC_PREF("Preferred Sync Source", 0),
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Channels Thru",
- .index = 0,
- .info = snd_rme9652_info_thru,
- .get = snd_rme9652_get_thru,
- .put = snd_rme9652_put_thru,
-},
-RME9652_SPDIF_RATE("IEC958 Sample Rate", 0),
-RME9652_ADAT_SYNC("ADAT1 Sync Check", 0, 0),
-RME9652_ADAT_SYNC("ADAT2 Sync Check", 0, 1),
-RME9652_TC_VALID("Timecode Valid", 0),
-RME9652_PASSTHRU("Passthru", 0)
-};
-
-static struct snd_kcontrol_new snd_rme9652_adat3_check =
-RME9652_ADAT_SYNC("ADAT3 Sync Check", 0, 2);
-
-static struct snd_kcontrol_new snd_rme9652_adat1_input =
-RME9652_ADAT1_IN("ADAT1 Input Source", 0);
-
-static int snd_rme9652_create_controls(struct snd_card *card, struct snd_rme9652 *rme9652)
-{
- unsigned int idx;
- int err;
- struct snd_kcontrol *kctl;
-
- for (idx = 0; idx < ARRAY_SIZE(snd_rme9652_controls); idx++) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme9652_controls[idx], rme9652))) < 0)
- return err;
- if (idx == 1) /* IEC958 (S/PDIF) Stream */
- rme9652->spdif_ctl = kctl;
- }
-
- if (rme9652->ss_channels == RME9652_NCHANNELS)
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme9652_adat3_check, rme9652))) < 0)
- return err;
-
- if (rme9652->hw_rev >= 15)
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme9652_adat1_input, rme9652))) < 0)
- return err;
-
- return 0;
-}
-
-/*------------------------------------------------------------
- /proc interface
- ------------------------------------------------------------*/
-
-static void
-snd_rme9652_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- struct snd_rme9652 *rme9652 = (struct snd_rme9652 *) entry->private_data;
- u32 thru_bits = rme9652->thru_bits;
- int show_auto_sync_source = 0;
- int i;
- unsigned int status;
- int x;
-
- status = rme9652_read(rme9652, RME9652_status_register);
-
- snd_iprintf(buffer, "%s (Card #%d)\n", rme9652->card_name, rme9652->card->number + 1);
- snd_iprintf(buffer, "Buffers: capture %p playback %p\n",
- rme9652->capture_buffer, rme9652->playback_buffer);
- snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
- rme9652->irq, rme9652->port, (unsigned long)rme9652->iobase);
- snd_iprintf(buffer, "Control register: %x\n", rme9652->control_register);
-
- snd_iprintf(buffer, "\n");
-
- x = 1 << (6 + rme9652_decode_latency(rme9652->control_register &
- RME9652_latency));
-
- snd_iprintf(buffer, "Latency: %d samples (2 periods of %lu bytes)\n",
- x, (unsigned long) rme9652->period_bytes);
- snd_iprintf(buffer, "Hardware pointer (frames): %ld\n",
- rme9652_hw_pointer(rme9652));
- snd_iprintf(buffer, "Passthru: %s\n",
- rme9652->passthru ? "yes" : "no");
-
- if ((rme9652->control_register & (RME9652_Master | RME9652_wsel)) == 0) {
- snd_iprintf(buffer, "Clock mode: autosync\n");
- show_auto_sync_source = 1;
- } else if (rme9652->control_register & RME9652_wsel) {
- if (status & RME9652_wsel_rd) {
- snd_iprintf(buffer, "Clock mode: word clock\n");
- } else {
- snd_iprintf(buffer, "Clock mode: word clock (no signal)\n");
- }
- } else {
- snd_iprintf(buffer, "Clock mode: master\n");
- }
-
- if (show_auto_sync_source) {
- switch (rme9652->control_register & RME9652_SyncPref_Mask) {
- case RME9652_SyncPref_ADAT1:
- snd_iprintf(buffer, "Pref. sync source: ADAT1\n");
- break;
- case RME9652_SyncPref_ADAT2:
- snd_iprintf(buffer, "Pref. sync source: ADAT2\n");
- break;
- case RME9652_SyncPref_ADAT3:
- snd_iprintf(buffer, "Pref. sync source: ADAT3\n");
- break;
- case RME9652_SyncPref_SPDIF:
- snd_iprintf(buffer, "Pref. sync source: IEC958\n");
- break;
- default:
- snd_iprintf(buffer, "Pref. sync source: ???\n");
- }
- }
-
- if (rme9652->hw_rev >= 15)
- snd_iprintf(buffer, "\nADAT1 Input source: %s\n",
- (rme9652->control_register & RME9652_ADAT1_INTERNAL) ?
- "Internal" : "ADAT1 optical");
-
- snd_iprintf(buffer, "\n");
-
- switch (rme9652_decode_spdif_in(rme9652->control_register &
- RME9652_inp)) {
- case RME9652_SPDIFIN_OPTICAL:
- snd_iprintf(buffer, "IEC958 input: ADAT1\n");
- break;
- case RME9652_SPDIFIN_COAXIAL:
- snd_iprintf(buffer, "IEC958 input: Coaxial\n");
- break;
- case RME9652_SPDIFIN_INTERN:
- snd_iprintf(buffer, "IEC958 input: Internal\n");
- break;
- default:
- snd_iprintf(buffer, "IEC958 input: ???\n");
- break;
- }
-
- if (rme9652->control_register & RME9652_opt_out) {
- snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n");
- } else {
- snd_iprintf(buffer, "IEC958 output: Coaxial only\n");
- }
-
- if (rme9652->control_register & RME9652_PRO) {
- snd_iprintf(buffer, "IEC958 quality: Professional\n");
- } else {
- snd_iprintf(buffer, "IEC958 quality: Consumer\n");
- }
-
- if (rme9652->control_register & RME9652_EMP) {
- snd_iprintf(buffer, "IEC958 emphasis: on\n");
- } else {
- snd_iprintf(buffer, "IEC958 emphasis: off\n");
- }
-
- if (rme9652->control_register & RME9652_Dolby) {
- snd_iprintf(buffer, "IEC958 Dolby: on\n");
- } else {
- snd_iprintf(buffer, "IEC958 Dolby: off\n");
- }
-
- i = rme9652_spdif_sample_rate(rme9652);
-
- if (i < 0) {
- snd_iprintf(buffer,
- "IEC958 sample rate: error flag set\n");
- } else if (i == 0) {
- snd_iprintf(buffer, "IEC958 sample rate: undetermined\n");
- } else {
- snd_iprintf(buffer, "IEC958 sample rate: %d\n", i);
- }
-
- snd_iprintf(buffer, "\n");
-
- snd_iprintf(buffer, "ADAT Sample rate: %dHz\n",
- rme9652_adat_sample_rate(rme9652));
-
- /* Sync Check */
-
- x = status & RME9652_sync_0;
- if (status & RME9652_lock_0) {
- snd_iprintf(buffer, "ADAT1: %s\n", x ? "Sync" : "Lock");
- } else {
- snd_iprintf(buffer, "ADAT1: No Lock\n");
- }
-
- x = status & RME9652_sync_1;
- if (status & RME9652_lock_1) {
- snd_iprintf(buffer, "ADAT2: %s\n", x ? "Sync" : "Lock");
- } else {
- snd_iprintf(buffer, "ADAT2: No Lock\n");
- }
-
- x = status & RME9652_sync_2;
- if (status & RME9652_lock_2) {
- snd_iprintf(buffer, "ADAT3: %s\n", x ? "Sync" : "Lock");
- } else {
- snd_iprintf(buffer, "ADAT3: No Lock\n");
- }
-
- snd_iprintf(buffer, "\n");
-
- snd_iprintf(buffer, "Timecode signal: %s\n",
- (status & RME9652_tc_valid) ? "yes" : "no");
-
- /* thru modes */
-
- snd_iprintf(buffer, "Punch Status:\n\n");
-
- for (i = 0; i < rme9652->ss_channels; i++) {
- if (thru_bits & (1 << i)) {
- snd_iprintf(buffer, "%2d: on ", i + 1);
- } else {
- snd_iprintf(buffer, "%2d: off ", i + 1);
- }
-
- if (((i + 1) % 8) == 0) {
- snd_iprintf(buffer, "\n");
- }
- }
-
- snd_iprintf(buffer, "\n");
-}
-
-static void __devinit snd_rme9652_proc_init(struct snd_rme9652 *rme9652)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(rme9652->card, "rme9652", &entry))
- snd_info_set_text_ops(entry, rme9652, snd_rme9652_proc_read);
-}
-
-static void snd_rme9652_free_buffers(struct snd_rme9652 *rme9652)
-{
- snd_hammerfall_free_buffer(&rme9652->capture_dma_buf, rme9652->pci);
- snd_hammerfall_free_buffer(&rme9652->playback_dma_buf, rme9652->pci);
-}
-
-static int snd_rme9652_free(struct snd_rme9652 *rme9652)
-{
- if (rme9652->irq >= 0)
- rme9652_stop(rme9652);
- snd_rme9652_free_buffers(rme9652);
-
- if (rme9652->irq >= 0)
- free_irq(rme9652->irq, (void *)rme9652);
- if (rme9652->iobase)
- iounmap(rme9652->iobase);
- if (rme9652->port)
- pci_release_regions(rme9652->pci);
-
- pci_disable_device(rme9652->pci);
- return 0;
-}
-
-static int __devinit snd_rme9652_initialize_memory(struct snd_rme9652 *rme9652)
-{
- unsigned long pb_bus, cb_bus;
-
- if (snd_hammerfall_get_buffer(rme9652->pci, &rme9652->capture_dma_buf, RME9652_DMA_AREA_BYTES) < 0 ||
- snd_hammerfall_get_buffer(rme9652->pci, &rme9652->playback_dma_buf, RME9652_DMA_AREA_BYTES) < 0) {
- if (rme9652->capture_dma_buf.area)
- snd_dma_free_pages(&rme9652->capture_dma_buf);
- printk(KERN_ERR "%s: no buffers available\n", rme9652->card_name);
- return -ENOMEM;
- }
-
- /* Align to bus-space 64K boundary */
-
- cb_bus = ALIGN(rme9652->capture_dma_buf.addr, 0x10000ul);
- pb_bus = ALIGN(rme9652->playback_dma_buf.addr, 0x10000ul);
-
- /* Tell the card where it is */
-
- rme9652_write(rme9652, RME9652_rec_buffer, cb_bus);
- rme9652_write(rme9652, RME9652_play_buffer, pb_bus);
-
- rme9652->capture_buffer = rme9652->capture_dma_buf.area + (cb_bus - rme9652->capture_dma_buf.addr);
- rme9652->playback_buffer = rme9652->playback_dma_buf.area + (pb_bus - rme9652->playback_dma_buf.addr);
-
- return 0;
-}
-
-static void snd_rme9652_set_defaults(struct snd_rme9652 *rme9652)
-{
- unsigned int k;
-
- /* ASSUMPTION: rme9652->lock is either held, or
- there is no need to hold it (e.g. during module
- initialization).
- */
-
- /* set defaults:
-
- SPDIF Input via Coax
- autosync clock mode
- maximum latency (7 = 8192 samples, 64Kbyte buffer,
- which implies 2 4096 sample, 32Kbyte periods).
-
- if rev 1.5, initialize the S/PDIF receiver.
-
- */
-
- rme9652->control_register =
- RME9652_inp_0 | rme9652_encode_latency(7);
-
- rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
-
- rme9652_reset_hw_pointer(rme9652);
- rme9652_compute_period_size(rme9652);
-
- /* default: thru off for all channels */
-
- for (k = 0; k < RME9652_NCHANNELS; ++k)
- rme9652_write(rme9652, RME9652_thru_base + k * 4, 0);
-
- rme9652->thru_bits = 0;
- rme9652->passthru = 0;
-
- /* set a default rate so that the channel map is set up */
-
- rme9652_set_rate(rme9652, 48000);
-}
-
-static irqreturn_t snd_rme9652_interrupt(int irq, void *dev_id)
-{
- struct snd_rme9652 *rme9652 = (struct snd_rme9652 *) dev_id;
-
- if (!(rme9652_read(rme9652, RME9652_status_register) & RME9652_IRQ)) {
- return IRQ_NONE;
- }
-
- rme9652_write(rme9652, RME9652_irq_clear, 0);
-
- if (rme9652->capture_substream) {
- snd_pcm_period_elapsed(rme9652->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
- }
-
- if (rme9652->playback_substream) {
- snd_pcm_period_elapsed(rme9652->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream);
- }
- return IRQ_HANDLED;
-}
-
-static snd_pcm_uframes_t snd_rme9652_hw_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
- return rme9652_hw_pointer(rme9652);
-}
-
-static char *rme9652_channel_buffer_location(struct snd_rme9652 *rme9652,
- int stream,
- int channel)
-
-{
- int mapped_channel;
-
- if (snd_BUG_ON(channel < 0 || channel >= RME9652_NCHANNELS))
- return NULL;
-
- if ((mapped_channel = rme9652->channel_map[channel]) < 0) {
- return NULL;
- }
-
- if (stream == SNDRV_PCM_STREAM_CAPTURE) {
- return rme9652->capture_buffer +
- (mapped_channel * RME9652_CHANNEL_BUFFER_BYTES);
- } else {
- return rme9652->playback_buffer +
- (mapped_channel * RME9652_CHANNEL_BUFFER_BYTES);
- }
-}
-
-static int snd_rme9652_playback_copy(struct snd_pcm_substream *substream, int channel,
- snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count)
-{
- struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
- char *channel_buf;
-
- if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES / 4))
- return -EINVAL;
-
- channel_buf = rme9652_channel_buffer_location (rme9652,
- substream->pstr->stream,
- channel);
- if (snd_BUG_ON(!channel_buf))
- return -EIO;
- if (copy_from_user(channel_buf + pos * 4, src, count * 4))
- return -EFAULT;
- return count;
-}
-
-static int snd_rme9652_capture_copy(struct snd_pcm_substream *substream, int channel,
- snd_pcm_uframes_t pos, void __user *dst, snd_pcm_uframes_t count)
-{
- struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
- char *channel_buf;
-
- if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES / 4))
- return -EINVAL;
-
- channel_buf = rme9652_channel_buffer_location (rme9652,
- substream->pstr->stream,
- channel);
- if (snd_BUG_ON(!channel_buf))
- return -EIO;
- if (copy_to_user(dst, channel_buf + pos * 4, count * 4))
- return -EFAULT;
- return count;
-}
-
-static int snd_rme9652_hw_silence(struct snd_pcm_substream *substream, int channel,
- snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
-{
- struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
- char *channel_buf;
-
- channel_buf = rme9652_channel_buffer_location (rme9652,
- substream->pstr->stream,
- channel);
- if (snd_BUG_ON(!channel_buf))
- return -EIO;
- memset(channel_buf + pos * 4, 0, count * 4);
- return count;
-}
-
-static int snd_rme9652_reset(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
- struct snd_pcm_substream *other;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- other = rme9652->capture_substream;
- else
- other = rme9652->playback_substream;
- if (rme9652->running)
- runtime->status->hw_ptr = rme9652_hw_pointer(rme9652);
- else
- runtime->status->hw_ptr = 0;
- if (other) {
- struct snd_pcm_substream *s;
- struct snd_pcm_runtime *oruntime = other->runtime;
- snd_pcm_group_for_each_entry(s, substream) {
- if (s == other) {
- oruntime->status->hw_ptr = runtime->status->hw_ptr;
- break;
- }
- }
- }
- return 0;
-}
-
-static int snd_rme9652_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
- int err;
- pid_t this_pid;
- pid_t other_pid;
-
- spin_lock_irq(&rme9652->lock);
-
- if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- rme9652->control_register &= ~(RME9652_PRO | RME9652_Dolby | RME9652_EMP);
- rme9652_write(rme9652, RME9652_control_register, rme9652->control_register |= rme9652->creg_spdif_stream);
- this_pid = rme9652->playback_pid;
- other_pid = rme9652->capture_pid;
- } else {
- this_pid = rme9652->capture_pid;
- other_pid = rme9652->playback_pid;
- }
-
- if ((other_pid > 0) && (this_pid != other_pid)) {
-
- /* The other stream is open, and not by the same
- task as this one. Make sure that the parameters
- that matter are the same.
- */
-
- if ((int)params_rate(params) !=
- rme9652_adat_sample_rate(rme9652)) {
- spin_unlock_irq(&rme9652->lock);
- _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
- return -EBUSY;
- }
-
- if (params_period_size(params) != rme9652->period_bytes / 4) {
- spin_unlock_irq(&rme9652->lock);
- _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
- return -EBUSY;
- }
-
- /* We're fine. */
-
- spin_unlock_irq(&rme9652->lock);
- return 0;
-
- } else {
- spin_unlock_irq(&rme9652->lock);
- }
-
- /* how to make sure that the rate matches an externally-set one ?
- */
-
- if ((err = rme9652_set_rate(rme9652, params_rate(params))) < 0) {
- _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
- return err;
- }
-
- if ((err = rme9652_set_interrupt_interval(rme9652, params_period_size(params))) < 0) {
- _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
- return err;
- }
-
- return 0;
-}
-
-static int snd_rme9652_channel_info(struct snd_pcm_substream *substream,
- struct snd_pcm_channel_info *info)
-{
- struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
- int chn;
-
- if (snd_BUG_ON(info->channel >= RME9652_NCHANNELS))
- return -EINVAL;
-
- if ((chn = rme9652->channel_map[info->channel]) < 0) {
- return -EINVAL;
- }
-
- info->offset = chn * RME9652_CHANNEL_BUFFER_BYTES;
- info->first = 0;
- info->step = 32;
- return 0;
-}
-
-static int snd_rme9652_ioctl(struct snd_pcm_substream *substream,
- unsigned int cmd, void *arg)
-{
- switch (cmd) {
- case SNDRV_PCM_IOCTL1_RESET:
- {
- return snd_rme9652_reset(substream);
- }
- case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
- {
- struct snd_pcm_channel_info *info = arg;
- return snd_rme9652_channel_info(substream, info);
- }
- default:
- break;
- }
-
- return snd_pcm_lib_ioctl(substream, cmd, arg);
-}
-
-static void rme9652_silence_playback(struct snd_rme9652 *rme9652)
-{
- memset(rme9652->playback_buffer, 0, RME9652_DMA_AREA_BYTES);
-}
-
-static int snd_rme9652_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
- struct snd_pcm_substream *other;
- int running;
- spin_lock(&rme9652->lock);
- running = rme9652->running;
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- running |= 1 << substream->stream;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- running &= ~(1 << substream->stream);
- break;
- default:
- snd_BUG();
- spin_unlock(&rme9652->lock);
- return -EINVAL;
- }
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- other = rme9652->capture_substream;
- else
- other = rme9652->playback_substream;
-
- if (other) {
- struct snd_pcm_substream *s;
- snd_pcm_group_for_each_entry(s, substream) {
- if (s == other) {
- snd_pcm_trigger_done(s, substream);
- if (cmd == SNDRV_PCM_TRIGGER_START)
- running |= 1 << s->stream;
- else
- running &= ~(1 << s->stream);
- goto _ok;
- }
- }
- if (cmd == SNDRV_PCM_TRIGGER_START) {
- if (!(running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) &&
- substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- rme9652_silence_playback(rme9652);
- } else {
- if (running &&
- substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- rme9652_silence_playback(rme9652);
- }
- } else {
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- rme9652_silence_playback(rme9652);
- }
- _ok:
- snd_pcm_trigger_done(substream, substream);
- if (!rme9652->running && running)
- rme9652_start(rme9652);
- else if (rme9652->running && !running)
- rme9652_stop(rme9652);
- rme9652->running = running;
- spin_unlock(&rme9652->lock);
-
- return 0;
-}
-
-static int snd_rme9652_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
- unsigned long flags;
- int result = 0;
-
- spin_lock_irqsave(&rme9652->lock, flags);
- if (!rme9652->running)
- rme9652_reset_hw_pointer(rme9652);
- spin_unlock_irqrestore(&rme9652->lock, flags);
- return result;
-}
-
-static struct snd_pcm_hardware snd_rme9652_playback_subinfo =
-{
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_NONINTERLEAVED |
- SNDRV_PCM_INFO_SYNC_START |
- SNDRV_PCM_INFO_DOUBLE),
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .rates = (SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000),
- .rate_min = 44100,
- .rate_max = 96000,
- .channels_min = 10,
- .channels_max = 26,
- .buffer_bytes_max = RME9652_CHANNEL_BUFFER_BYTES * 26,
- .period_bytes_min = (64 * 4) * 10,
- .period_bytes_max = (8192 * 4) * 26,
- .periods_min = 2,
- .periods_max = 2,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_rme9652_capture_subinfo =
-{
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_NONINTERLEAVED |
- SNDRV_PCM_INFO_SYNC_START),
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .rates = (SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000),
- .rate_min = 44100,
- .rate_max = 96000,
- .channels_min = 10,
- .channels_max = 26,
- .buffer_bytes_max = RME9652_CHANNEL_BUFFER_BYTES *26,
- .period_bytes_min = (64 * 4) * 10,
- .period_bytes_max = (8192 * 4) * 26,
- .periods_min = 2,
- .periods_max = 2,
- .fifo_size = 0,
-};
-
-static unsigned int period_sizes[] = { 64, 128, 256, 512, 1024, 2048, 4096, 8192 };
-
-static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes = {
- .count = ARRAY_SIZE(period_sizes),
- .list = period_sizes,
- .mask = 0
-};
-
-static int snd_rme9652_hw_rule_channels(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_rme9652 *rme9652 = rule->private;
- struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- unsigned int list[2] = { rme9652->ds_channels, rme9652->ss_channels };
- return snd_interval_list(c, 2, list, 0);
-}
-
-static int snd_rme9652_hw_rule_channels_rate(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_rme9652 *rme9652 = rule->private;
- struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
- if (r->min > 48000) {
- struct snd_interval t = {
- .min = rme9652->ds_channels,
- .max = rme9652->ds_channels,
- .integer = 1,
- };
- return snd_interval_refine(c, &t);
- } else if (r->max < 88200) {
- struct snd_interval t = {
- .min = rme9652->ss_channels,
- .max = rme9652->ss_channels,
- .integer = 1,
- };
- return snd_interval_refine(c, &t);
- }
- return 0;
-}
-
-static int snd_rme9652_hw_rule_rate_channels(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_rme9652 *rme9652 = rule->private;
- struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
- if (c->min >= rme9652->ss_channels) {
- struct snd_interval t = {
- .min = 44100,
- .max = 48000,
- .integer = 1,
- };
- return snd_interval_refine(r, &t);
- } else if (c->max <= rme9652->ds_channels) {
- struct snd_interval t = {
- .min = 88200,
- .max = 96000,
- .integer = 1,
- };
- return snd_interval_refine(r, &t);
- }
- return 0;
-}
-
-static int snd_rme9652_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- spin_lock_irq(&rme9652->lock);
-
- snd_pcm_set_sync(substream);
-
- runtime->hw = snd_rme9652_playback_subinfo;
- runtime->dma_area = rme9652->playback_buffer;
- runtime->dma_bytes = RME9652_DMA_AREA_BYTES;
-
- if (rme9652->capture_substream == NULL) {
- rme9652_stop(rme9652);
- rme9652_set_thru(rme9652, -1, 0);
- }
-
- rme9652->playback_pid = current->pid;
- rme9652->playback_substream = substream;
-
- spin_unlock_irq(&rme9652->lock);
-
- snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_period_sizes);
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- snd_rme9652_hw_rule_channels, rme9652,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- snd_rme9652_hw_rule_channels_rate, rme9652,
- SNDRV_PCM_HW_PARAM_RATE, -1);
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- snd_rme9652_hw_rule_rate_channels, rme9652,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
-
- rme9652->creg_spdif_stream = rme9652->creg_spdif;
- rme9652->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(rme9652->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO, &rme9652->spdif_ctl->id);
- return 0;
-}
-
-static int snd_rme9652_playback_release(struct snd_pcm_substream *substream)
-{
- struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&rme9652->lock);
-
- rme9652->playback_pid = -1;
- rme9652->playback_substream = NULL;
-
- spin_unlock_irq(&rme9652->lock);
-
- rme9652->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(rme9652->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO, &rme9652->spdif_ctl->id);
- return 0;
-}
-
-
-static int snd_rme9652_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- spin_lock_irq(&rme9652->lock);
-
- snd_pcm_set_sync(substream);
-
- runtime->hw = snd_rme9652_capture_subinfo;
- runtime->dma_area = rme9652->capture_buffer;
- runtime->dma_bytes = RME9652_DMA_AREA_BYTES;
-
- if (rme9652->playback_substream == NULL) {
- rme9652_stop(rme9652);
- rme9652_set_thru(rme9652, -1, 0);
- }
-
- rme9652->capture_pid = current->pid;
- rme9652->capture_substream = substream;
-
- spin_unlock_irq(&rme9652->lock);
-
- snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_period_sizes);
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- snd_rme9652_hw_rule_channels, rme9652,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- snd_rme9652_hw_rule_channels_rate, rme9652,
- SNDRV_PCM_HW_PARAM_RATE, -1);
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- snd_rme9652_hw_rule_rate_channels, rme9652,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
- return 0;
-}
-
-static int snd_rme9652_capture_release(struct snd_pcm_substream *substream)
-{
- struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&rme9652->lock);
-
- rme9652->capture_pid = -1;
- rme9652->capture_substream = NULL;
-
- spin_unlock_irq(&rme9652->lock);
- return 0;
-}
-
-static struct snd_pcm_ops snd_rme9652_playback_ops = {
- .open = snd_rme9652_playback_open,
- .close = snd_rme9652_playback_release,
- .ioctl = snd_rme9652_ioctl,
- .hw_params = snd_rme9652_hw_params,
- .prepare = snd_rme9652_prepare,
- .trigger = snd_rme9652_trigger,
- .pointer = snd_rme9652_hw_pointer,
- .copy = snd_rme9652_playback_copy,
- .silence = snd_rme9652_hw_silence,
-};
-
-static struct snd_pcm_ops snd_rme9652_capture_ops = {
- .open = snd_rme9652_capture_open,
- .close = snd_rme9652_capture_release,
- .ioctl = snd_rme9652_ioctl,
- .hw_params = snd_rme9652_hw_params,
- .prepare = snd_rme9652_prepare,
- .trigger = snd_rme9652_trigger,
- .pointer = snd_rme9652_hw_pointer,
- .copy = snd_rme9652_capture_copy,
-};
-
-static int __devinit snd_rme9652_create_pcm(struct snd_card *card,
- struct snd_rme9652 *rme9652)
-{
- struct snd_pcm *pcm;
- int err;
-
- if ((err = snd_pcm_new(card,
- rme9652->card_name,
- 0, 1, 1, &pcm)) < 0) {
- return err;
- }
-
- rme9652->pcm = pcm;
- pcm->private_data = rme9652;
- strcpy(pcm->name, rme9652->card_name);
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_rme9652_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_rme9652_capture_ops);
-
- pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
-
- return 0;
-}
-
-static int __devinit snd_rme9652_create(struct snd_card *card,
- struct snd_rme9652 *rme9652,
- int precise_ptr)
-{
- struct pci_dev *pci = rme9652->pci;
- int err;
- int status;
- unsigned short rev;
-
- rme9652->irq = -1;
- rme9652->card = card;
-
- pci_read_config_word(rme9652->pci, PCI_CLASS_REVISION, &rev);
-
- switch (rev & 0xff) {
- case 3:
- case 4:
- case 8:
- case 9:
- break;
-
- default:
- /* who knows? */
- return -ENODEV;
- }
-
- if ((err = pci_enable_device(pci)) < 0)
- return err;
-
- spin_lock_init(&rme9652->lock);
-
- if ((err = pci_request_regions(pci, "rme9652")) < 0)
- return err;
- rme9652->port = pci_resource_start(pci, 0);
- rme9652->iobase = ioremap_nocache(rme9652->port, RME9652_IO_EXTENT);
- if (rme9652->iobase == NULL) {
- snd_printk(KERN_ERR "unable to remap region 0x%lx-0x%lx\n", rme9652->port, rme9652->port + RME9652_IO_EXTENT - 1);
- return -EBUSY;
- }
-
- if (request_irq(pci->irq, snd_rme9652_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, rme9652)) {
- snd_printk(KERN_ERR "unable to request IRQ %d\n", pci->irq);
- return -EBUSY;
- }
- rme9652->irq = pci->irq;
- rme9652->precise_ptr = precise_ptr;
-
- /* Determine the h/w rev level of the card. This seems like
- a particularly kludgy way to encode it, but its what RME
- chose to do, so we follow them ...
- */
-
- status = rme9652_read(rme9652, RME9652_status_register);
- if (rme9652_decode_spdif_rate(status&RME9652_F) == 1) {
- rme9652->hw_rev = 15;
- } else {
- rme9652->hw_rev = 11;
- }
-
- /* Differentiate between the standard Hammerfall, and the
- "Light", which does not have the expansion board. This
- method comes from information received from Mathhias
- Clausen at RME. Display the EEPROM and h/w revID where
- relevant.
- */
-
- switch (rev) {
- case 8: /* original eprom */
- strcpy(card->driver, "RME9636");
- if (rme9652->hw_rev == 15) {
- rme9652->card_name = "RME Digi9636 (Rev 1.5)";
- } else {
- rme9652->card_name = "RME Digi9636";
- }
- rme9652->ss_channels = RME9636_NCHANNELS;
- break;
- case 9: /* W36_G EPROM */
- strcpy(card->driver, "RME9636");
- rme9652->card_name = "RME Digi9636 (Rev G)";
- rme9652->ss_channels = RME9636_NCHANNELS;
- break;
- case 4: /* W52_G EPROM */
- strcpy(card->driver, "RME9652");
- rme9652->card_name = "RME Digi9652 (Rev G)";
- rme9652->ss_channels = RME9652_NCHANNELS;
- break;
- case 3: /* original eprom */
- strcpy(card->driver, "RME9652");
- if (rme9652->hw_rev == 15) {
- rme9652->card_name = "RME Digi9652 (Rev 1.5)";
- } else {
- rme9652->card_name = "RME Digi9652";
- }
- rme9652->ss_channels = RME9652_NCHANNELS;
- break;
- }
-
- rme9652->ds_channels = (rme9652->ss_channels - 2) / 2 + 2;
-
- pci_set_master(rme9652->pci);
-
- if ((err = snd_rme9652_initialize_memory(rme9652)) < 0) {
- return err;
- }
-
- if ((err = snd_rme9652_create_pcm(card, rme9652)) < 0) {
- return err;
- }
-
- if ((err = snd_rme9652_create_controls(card, rme9652)) < 0) {
- return err;
- }
-
- snd_rme9652_proc_init(rme9652);
-
- rme9652->last_spdif_sample_rate = -1;
- rme9652->last_adat_sample_rate = -1;
- rme9652->playback_pid = -1;
- rme9652->capture_pid = -1;
- rme9652->capture_substream = NULL;
- rme9652->playback_substream = NULL;
-
- snd_rme9652_set_defaults(rme9652);
-
- if (rme9652->hw_rev == 15) {
- rme9652_initialize_spdif_receiver (rme9652);
- }
-
- return 0;
-}
-
-static void snd_rme9652_card_free(struct snd_card *card)
-{
- struct snd_rme9652 *rme9652 = (struct snd_rme9652 *) card->private_data;
-
- if (rme9652)
- snd_rme9652_free(rme9652);
-}
-
-static int __devinit snd_rme9652_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_rme9652 *rme9652;
- struct snd_card *card;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_rme9652), &card);
-
- if (err < 0)
- return err;
-
- rme9652 = (struct snd_rme9652 *) card->private_data;
- card->private_free = snd_rme9652_card_free;
- rme9652->dev = dev;
- rme9652->pci = pci;
- snd_card_set_dev(card, &pci->dev);
-
- if ((err = snd_rme9652_create(card, rme9652, precise_ptr[dev])) < 0) {
- snd_card_free(card);
- return err;
- }
-
- strcpy(card->shortname, rme9652->card_name);
-
- sprintf(card->longname, "%s at 0x%lx, irq %d",
- card->shortname, rme9652->port, rme9652->irq);
-
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_rme9652_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_rme9652_ids,
- .probe = snd_rme9652_probe,
- .remove = __devexit_p(snd_rme9652_remove),
-};
-
-static int __init alsa_card_hammerfall_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_hammerfall_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_hammerfall_init)
-module_exit(alsa_card_hammerfall_exit)
diff --git a/ANDROID_3.4.5/sound/pci/sis7019.c b/ANDROID_3.4.5/sound/pci/sis7019.c
deleted file mode 100644
index ff500a87..00000000
--- a/ANDROID_3.4.5/sound/pci/sis7019.c
+++ /dev/null
@@ -1,1502 +0,0 @@
-/*
- * Driver for SiS7019 Audio Accelerator
- *
- * Copyright (C) 2004-2007, David Dillow
- * Written by David Dillow <dave@thedillows.org>
- * Inspired by the Trident 4D-WaveDX/NX driver.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 2.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/time.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <sound/core.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-#include "sis7019.h"
-
-MODULE_AUTHOR("David Dillow <dave@thedillows.org>");
-MODULE_DESCRIPTION("SiS7019");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{SiS,SiS7019 Audio Accelerator}}");
-
-static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
-static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-static bool enable = 1;
-static int codecs = 1;
-
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for SiS7019 Audio Accelerator.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator.");
-module_param(enable, bool, 0444);
-MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator.");
-module_param(codecs, int, 0444);
-MODULE_PARM_DESC(codecs, "Set bit to indicate that codec number is expected to be present (default 1)");
-
-static DEFINE_PCI_DEVICE_TABLE(snd_sis7019_ids) = {
- { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_sis7019_ids);
-
-/* There are three timing modes for the voices.
- *
- * For both playback and capture, when the buffer is one or two periods long,
- * we use the hardware's built-in Mid-Loop Interrupt and End-Loop Interrupt
- * to let us know when the periods have ended.
- *
- * When performing playback with more than two periods per buffer, we set
- * the "Stop Sample Offset" and tell the hardware to interrupt us when we
- * reach it. We then update the offset and continue on until we are
- * interrupted for the next period.
- *
- * Capture channels do not have a SSO, so we allocate a playback channel to
- * use as a timer for the capture periods. We use the SSO on the playback
- * channel to clock out virtual periods, and adjust the virtual period length
- * to maintain synchronization. This algorithm came from the Trident driver.
- *
- * FIXME: It'd be nice to make use of some of the synth features in the
- * hardware, but a woeful lack of documentation is a significant roadblock.
- */
-struct voice {
- u16 flags;
-#define VOICE_IN_USE 1
-#define VOICE_CAPTURE 2
-#define VOICE_SSO_TIMING 4
-#define VOICE_SYNC_TIMING 8
- u16 sync_cso;
- u16 period_size;
- u16 buffer_size;
- u16 sync_period_size;
- u16 sync_buffer_size;
- u32 sso;
- u32 vperiod;
- struct snd_pcm_substream *substream;
- struct voice *timing;
- void __iomem *ctrl_base;
- void __iomem *wave_base;
- void __iomem *sync_base;
- int num;
-};
-
-/* We need four pages to store our wave parameters during a suspend. If
- * we're not doing power management, we still need to allocate a page
- * for the silence buffer.
- */
-#ifdef CONFIG_PM
-#define SIS_SUSPEND_PAGES 4
-#else
-#define SIS_SUSPEND_PAGES 1
-#endif
-
-struct sis7019 {
- unsigned long ioport;
- void __iomem *ioaddr;
- int irq;
- int codecs_present;
-
- struct pci_dev *pci;
- struct snd_pcm *pcm;
- struct snd_card *card;
- struct snd_ac97 *ac97[3];
-
- /* Protect against more than one thread hitting the AC97
- * registers (in a more polite manner than pounding the hardware
- * semaphore)
- */
- struct mutex ac97_mutex;
-
- /* voice_lock protects allocation/freeing of the voice descriptions
- */
- spinlock_t voice_lock;
-
- struct voice voices[64];
- struct voice capture_voice;
-
- /* Allocate pages to store the internal wave state during
- * suspends. When we're operating, this can be used as a silence
- * buffer for a timing channel.
- */
- void *suspend_state[SIS_SUSPEND_PAGES];
-
- int silence_users;
- dma_addr_t silence_dma_addr;
-};
-
-/* These values are also used by the module param 'codecs' to indicate
- * which codecs should be present.
- */
-#define SIS_PRIMARY_CODEC_PRESENT 0x0001
-#define SIS_SECONDARY_CODEC_PRESENT 0x0002
-#define SIS_TERTIARY_CODEC_PRESENT 0x0004
-
-/* The HW offset parameters (Loop End, Stop Sample, End Sample) have a
- * documented range of 8-0xfff8 samples. Given that they are 0-based,
- * that places our period/buffer range at 9-0xfff9 samples. That makes the
- * max buffer size 0xfff9 samples * 2 channels * 2 bytes per sample, and
- * max samples / min samples gives us the max periods in a buffer.
- *
- * We'll add a constraint upon open that limits the period and buffer sample
- * size to values that are legal for the hardware.
- */
-static struct snd_pcm_hardware sis_playback_hw_info = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_SYNC_START |
- SNDRV_PCM_INFO_RESUME),
- .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE),
- .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (0xfff9 * 4),
- .period_bytes_min = 9,
- .period_bytes_max = (0xfff9 * 4),
- .periods_min = 1,
- .periods_max = (0xfff9 / 9),
-};
-
-static struct snd_pcm_hardware sis_capture_hw_info = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_SYNC_START |
- SNDRV_PCM_INFO_RESUME),
- .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE),
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (0xfff9 * 4),
- .period_bytes_min = 9,
- .period_bytes_max = (0xfff9 * 4),
- .periods_min = 1,
- .periods_max = (0xfff9 / 9),
-};
-
-static void sis_update_sso(struct voice *voice, u16 period)
-{
- void __iomem *base = voice->ctrl_base;
-
- voice->sso += period;
- if (voice->sso >= voice->buffer_size)
- voice->sso -= voice->buffer_size;
-
- /* Enforce the documented hardware minimum offset */
- if (voice->sso < 8)
- voice->sso = 8;
-
- /* The SSO is in the upper 16 bits of the register. */
- writew(voice->sso & 0xffff, base + SIS_PLAY_DMA_SSO_ESO + 2);
-}
-
-static void sis_update_voice(struct voice *voice)
-{
- if (voice->flags & VOICE_SSO_TIMING) {
- sis_update_sso(voice, voice->period_size);
- } else if (voice->flags & VOICE_SYNC_TIMING) {
- int sync;
-
- /* If we've not hit the end of the virtual period, update
- * our records and keep going.
- */
- if (voice->vperiod > voice->period_size) {
- voice->vperiod -= voice->period_size;
- if (voice->vperiod < voice->period_size)
- sis_update_sso(voice, voice->vperiod);
- else
- sis_update_sso(voice, voice->period_size);
- return;
- }
-
- /* Calculate our relative offset between the target and
- * the actual CSO value. Since we're operating in a loop,
- * if the value is more than half way around, we can
- * consider ourselves wrapped.
- */
- sync = voice->sync_cso;
- sync -= readw(voice->sync_base + SIS_CAPTURE_DMA_FORMAT_CSO);
- if (sync > (voice->sync_buffer_size / 2))
- sync -= voice->sync_buffer_size;
-
- /* If sync is positive, then we interrupted too early, and
- * we'll need to come back in a few samples and try again.
- * There's a minimum wait, as it takes some time for the DMA
- * engine to startup, etc...
- */
- if (sync > 0) {
- if (sync < 16)
- sync = 16;
- sis_update_sso(voice, sync);
- return;
- }
-
- /* Ok, we interrupted right on time, or (hopefully) just
- * a bit late. We'll adjst our next waiting period based
- * on how close we got.
- *
- * We need to stay just behind the actual channel to ensure
- * it really is past a period when we get our interrupt --
- * otherwise we'll fall into the early code above and have
- * a minimum wait time, which makes us quite late here,
- * eating into the user's time to refresh the buffer, esp.
- * if using small periods.
- *
- * If we're less than 9 samples behind, we're on target.
- * Otherwise, shorten the next vperiod by the amount we've
- * been delayed.
- */
- if (sync > -9)
- voice->vperiod = voice->sync_period_size + 1;
- else
- voice->vperiod = voice->sync_period_size + sync + 10;
-
- if (voice->vperiod < voice->buffer_size) {
- sis_update_sso(voice, voice->vperiod);
- voice->vperiod = 0;
- } else
- sis_update_sso(voice, voice->period_size);
-
- sync = voice->sync_cso + voice->sync_period_size;
- if (sync >= voice->sync_buffer_size)
- sync -= voice->sync_buffer_size;
- voice->sync_cso = sync;
- }
-
- snd_pcm_period_elapsed(voice->substream);
-}
-
-static void sis_voice_irq(u32 status, struct voice *voice)
-{
- int bit;
-
- while (status) {
- bit = __ffs(status);
- status >>= bit + 1;
- voice += bit;
- sis_update_voice(voice);
- voice++;
- }
-}
-
-static irqreturn_t sis_interrupt(int irq, void *dev)
-{
- struct sis7019 *sis = dev;
- unsigned long io = sis->ioport;
- struct voice *voice;
- u32 intr, status;
-
- /* We only use the DMA interrupts, and we don't enable any other
- * source of interrupts. But, it is possible to see an interrupt
- * status that didn't actually interrupt us, so eliminate anything
- * we're not expecting to avoid falsely claiming an IRQ, and an
- * ensuing endless loop.
- */
- intr = inl(io + SIS_GISR);
- intr &= SIS_GISR_AUDIO_PLAY_DMA_IRQ_STATUS |
- SIS_GISR_AUDIO_RECORD_DMA_IRQ_STATUS;
- if (!intr)
- return IRQ_NONE;
-
- do {
- status = inl(io + SIS_PISR_A);
- if (status) {
- sis_voice_irq(status, sis->voices);
- outl(status, io + SIS_PISR_A);
- }
-
- status = inl(io + SIS_PISR_B);
- if (status) {
- sis_voice_irq(status, &sis->voices[32]);
- outl(status, io + SIS_PISR_B);
- }
-
- status = inl(io + SIS_RISR);
- if (status) {
- voice = &sis->capture_voice;
- if (!voice->timing)
- snd_pcm_period_elapsed(voice->substream);
-
- outl(status, io + SIS_RISR);
- }
-
- outl(intr, io + SIS_GISR);
- intr = inl(io + SIS_GISR);
- intr &= SIS_GISR_AUDIO_PLAY_DMA_IRQ_STATUS |
- SIS_GISR_AUDIO_RECORD_DMA_IRQ_STATUS;
- } while (intr);
-
- return IRQ_HANDLED;
-}
-
-static u32 sis_rate_to_delta(unsigned int rate)
-{
- u32 delta;
-
- /* This was copied from the trident driver, but it seems its gotten
- * around a bit... nevertheless, it works well.
- *
- * We special case 44100 and 8000 since rounding with the equation
- * does not give us an accurate enough value. For 11025 and 22050
- * the equation gives us the best answer. All other frequencies will
- * also use the equation. JDW
- */
- if (rate == 44100)
- delta = 0xeb3;
- else if (rate == 8000)
- delta = 0x2ab;
- else if (rate == 48000)
- delta = 0x1000;
- else
- delta = (((rate << 12) + 24000) / 48000) & 0x0000ffff;
- return delta;
-}
-
-static void __sis_map_silence(struct sis7019 *sis)
-{
- /* Helper function: must hold sis->voice_lock on entry */
- if (!sis->silence_users)
- sis->silence_dma_addr = pci_map_single(sis->pci,
- sis->suspend_state[0],
- 4096, PCI_DMA_TODEVICE);
- sis->silence_users++;
-}
-
-static void __sis_unmap_silence(struct sis7019 *sis)
-{
- /* Helper function: must hold sis->voice_lock on entry */
- sis->silence_users--;
- if (!sis->silence_users)
- pci_unmap_single(sis->pci, sis->silence_dma_addr, 4096,
- PCI_DMA_TODEVICE);
-}
-
-static void sis_free_voice(struct sis7019 *sis, struct voice *voice)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&sis->voice_lock, flags);
- if (voice->timing) {
- __sis_unmap_silence(sis);
- voice->timing->flags &= ~(VOICE_IN_USE | VOICE_SSO_TIMING |
- VOICE_SYNC_TIMING);
- voice->timing = NULL;
- }
- voice->flags &= ~(VOICE_IN_USE | VOICE_SSO_TIMING | VOICE_SYNC_TIMING);
- spin_unlock_irqrestore(&sis->voice_lock, flags);
-}
-
-static struct voice *__sis_alloc_playback_voice(struct sis7019 *sis)
-{
- /* Must hold the voice_lock on entry */
- struct voice *voice;
- int i;
-
- for (i = 0; i < 64; i++) {
- voice = &sis->voices[i];
- if (voice->flags & VOICE_IN_USE)
- continue;
- voice->flags |= VOICE_IN_USE;
- goto found_one;
- }
- voice = NULL;
-
-found_one:
- return voice;
-}
-
-static struct voice *sis_alloc_playback_voice(struct sis7019 *sis)
-{
- struct voice *voice;
- unsigned long flags;
-
- spin_lock_irqsave(&sis->voice_lock, flags);
- voice = __sis_alloc_playback_voice(sis);
- spin_unlock_irqrestore(&sis->voice_lock, flags);
-
- return voice;
-}
-
-static int sis_alloc_timing_voice(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct sis7019 *sis = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct voice *voice = runtime->private_data;
- unsigned int period_size, buffer_size;
- unsigned long flags;
- int needed;
-
- /* If there are one or two periods per buffer, we don't need a
- * timing voice, as we can use the capture channel's interrupts
- * to clock out the periods.
- */
- period_size = params_period_size(hw_params);
- buffer_size = params_buffer_size(hw_params);
- needed = (period_size != buffer_size &&
- period_size != (buffer_size / 2));
-
- if (needed && !voice->timing) {
- spin_lock_irqsave(&sis->voice_lock, flags);
- voice->timing = __sis_alloc_playback_voice(sis);
- if (voice->timing)
- __sis_map_silence(sis);
- spin_unlock_irqrestore(&sis->voice_lock, flags);
- if (!voice->timing)
- return -ENOMEM;
- voice->timing->substream = substream;
- } else if (!needed && voice->timing) {
- sis_free_voice(sis, voice);
- voice->timing = NULL;
- }
-
- return 0;
-}
-
-static int sis_playback_open(struct snd_pcm_substream *substream)
-{
- struct sis7019 *sis = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct voice *voice;
-
- voice = sis_alloc_playback_voice(sis);
- if (!voice)
- return -EAGAIN;
-
- voice->substream = substream;
- runtime->private_data = voice;
- runtime->hw = sis_playback_hw_info;
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- 9, 0xfff9);
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- 9, 0xfff9);
- snd_pcm_set_sync(substream);
- return 0;
-}
-
-static int sis_substream_close(struct snd_pcm_substream *substream)
-{
- struct sis7019 *sis = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct voice *voice = runtime->private_data;
-
- sis_free_voice(sis, voice);
- return 0;
-}
-
-static int sis_playback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-}
-
-static int sis_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int sis_pcm_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct voice *voice = runtime->private_data;
- void __iomem *ctrl_base = voice->ctrl_base;
- void __iomem *wave_base = voice->wave_base;
- u32 format, dma_addr, control, sso_eso, delta, reg;
- u16 leo;
-
- /* We rely on the PCM core to ensure that the parameters for this
- * substream do not change on us while we're programming the HW.
- */
- format = 0;
- if (snd_pcm_format_width(runtime->format) == 8)
- format |= SIS_PLAY_DMA_FORMAT_8BIT;
- if (!snd_pcm_format_signed(runtime->format))
- format |= SIS_PLAY_DMA_FORMAT_UNSIGNED;
- if (runtime->channels == 1)
- format |= SIS_PLAY_DMA_FORMAT_MONO;
-
- /* The baseline setup is for a single period per buffer, and
- * we add bells and whistles as needed from there.
- */
- dma_addr = runtime->dma_addr;
- leo = runtime->buffer_size - 1;
- control = leo | SIS_PLAY_DMA_LOOP | SIS_PLAY_DMA_INTR_AT_LEO;
- sso_eso = leo;
-
- if (runtime->period_size == (runtime->buffer_size / 2)) {
- control |= SIS_PLAY_DMA_INTR_AT_MLP;
- } else if (runtime->period_size != runtime->buffer_size) {
- voice->flags |= VOICE_SSO_TIMING;
- voice->sso = runtime->period_size - 1;
- voice->period_size = runtime->period_size;
- voice->buffer_size = runtime->buffer_size;
-
- control &= ~SIS_PLAY_DMA_INTR_AT_LEO;
- control |= SIS_PLAY_DMA_INTR_AT_SSO;
- sso_eso |= (runtime->period_size - 1) << 16;
- }
-
- delta = sis_rate_to_delta(runtime->rate);
-
- /* Ok, we're ready to go, set up the channel.
- */
- writel(format, ctrl_base + SIS_PLAY_DMA_FORMAT_CSO);
- writel(dma_addr, ctrl_base + SIS_PLAY_DMA_BASE);
- writel(control, ctrl_base + SIS_PLAY_DMA_CONTROL);
- writel(sso_eso, ctrl_base + SIS_PLAY_DMA_SSO_ESO);
-
- for (reg = 0; reg < SIS_WAVE_SIZE; reg += 4)
- writel(0, wave_base + reg);
-
- writel(SIS_WAVE_GENERAL_WAVE_VOLUME, wave_base + SIS_WAVE_GENERAL);
- writel(delta << 16, wave_base + SIS_WAVE_GENERAL_ARTICULATION);
- writel(SIS_WAVE_CHANNEL_CONTROL_FIRST_SAMPLE |
- SIS_WAVE_CHANNEL_CONTROL_AMP_ENABLE |
- SIS_WAVE_CHANNEL_CONTROL_INTERPOLATE_ENABLE,
- wave_base + SIS_WAVE_CHANNEL_CONTROL);
-
- /* Force PCI writes to post. */
- readl(ctrl_base);
-
- return 0;
-}
-
-static int sis_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct sis7019 *sis = snd_pcm_substream_chip(substream);
- unsigned long io = sis->ioport;
- struct snd_pcm_substream *s;
- struct voice *voice;
- void *chip;
- int starting;
- u32 record = 0;
- u32 play[2] = { 0, 0 };
-
- /* No locks needed, as the PCM core will hold the locks on the
- * substreams, and the HW will only start/stop the indicated voices
- * without changing the state of the others.
- */
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
- starting = 1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- starting = 0;
- break;
- default:
- return -EINVAL;
- }
-
- snd_pcm_group_for_each_entry(s, substream) {
- /* Make sure it is for us... */
- chip = snd_pcm_substream_chip(s);
- if (chip != sis)
- continue;
-
- voice = s->runtime->private_data;
- if (voice->flags & VOICE_CAPTURE) {
- record |= 1 << voice->num;
- voice = voice->timing;
- }
-
- /* voice could be NULL if this a recording stream, and it
- * doesn't have an external timing channel.
- */
- if (voice)
- play[voice->num / 32] |= 1 << (voice->num & 0x1f);
-
- snd_pcm_trigger_done(s, substream);
- }
-
- if (starting) {
- if (record)
- outl(record, io + SIS_RECORD_START_REG);
- if (play[0])
- outl(play[0], io + SIS_PLAY_START_A_REG);
- if (play[1])
- outl(play[1], io + SIS_PLAY_START_B_REG);
- } else {
- if (record)
- outl(record, io + SIS_RECORD_STOP_REG);
- if (play[0])
- outl(play[0], io + SIS_PLAY_STOP_A_REG);
- if (play[1])
- outl(play[1], io + SIS_PLAY_STOP_B_REG);
- }
- return 0;
-}
-
-static snd_pcm_uframes_t sis_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct voice *voice = runtime->private_data;
- u32 cso;
-
- cso = readl(voice->ctrl_base + SIS_PLAY_DMA_FORMAT_CSO);
- cso &= 0xffff;
- return cso;
-}
-
-static int sis_capture_open(struct snd_pcm_substream *substream)
-{
- struct sis7019 *sis = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct voice *voice = &sis->capture_voice;
- unsigned long flags;
-
- /* FIXME: The driver only supports recording from one channel
- * at the moment, but it could support more.
- */
- spin_lock_irqsave(&sis->voice_lock, flags);
- if (voice->flags & VOICE_IN_USE)
- voice = NULL;
- else
- voice->flags |= VOICE_IN_USE;
- spin_unlock_irqrestore(&sis->voice_lock, flags);
-
- if (!voice)
- return -EAGAIN;
-
- voice->substream = substream;
- runtime->private_data = voice;
- runtime->hw = sis_capture_hw_info;
- runtime->hw.rates = sis->ac97[0]->rates[AC97_RATES_ADC];
- snd_pcm_limit_hw_rates(runtime);
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
- 9, 0xfff9);
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- 9, 0xfff9);
- snd_pcm_set_sync(substream);
- return 0;
-}
-
-static int sis_capture_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct sis7019 *sis = snd_pcm_substream_chip(substream);
- int rc;
-
- rc = snd_ac97_set_rate(sis->ac97[0], AC97_PCM_LR_ADC_RATE,
- params_rate(hw_params));
- if (rc)
- goto out;
-
- rc = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- if (rc < 0)
- goto out;
-
- rc = sis_alloc_timing_voice(substream, hw_params);
-
-out:
- return rc;
-}
-
-static void sis_prepare_timing_voice(struct voice *voice,
- struct snd_pcm_substream *substream)
-{
- struct sis7019 *sis = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct voice *timing = voice->timing;
- void __iomem *play_base = timing->ctrl_base;
- void __iomem *wave_base = timing->wave_base;
- u16 buffer_size, period_size;
- u32 format, control, sso_eso, delta;
- u32 vperiod, sso, reg;
-
- /* Set our initial buffer and period as large as we can given a
- * single page of silence.
- */
- buffer_size = 4096 / runtime->channels;
- buffer_size /= snd_pcm_format_size(runtime->format, 1);
- period_size = buffer_size;
-
- /* Initially, we want to interrupt just a bit behind the end of
- * the period we're clocking out. 12 samples seems to give a good
- * delay.
- *
- * We want to spread our interrupts throughout the virtual period,
- * so that we don't end up with two interrupts back to back at the
- * end -- this helps minimize the effects of any jitter. Adjust our
- * clocking period size so that the last period is at least a fourth
- * of a full period.
- *
- * This is all moot if we don't need to use virtual periods.
- */
- vperiod = runtime->period_size + 12;
- if (vperiod > period_size) {
- u16 tail = vperiod % period_size;
- u16 quarter_period = period_size / 4;
-
- if (tail && tail < quarter_period) {
- u16 loops = vperiod / period_size;
-
- tail = quarter_period - tail;
- tail += loops - 1;
- tail /= loops;
- period_size -= tail;
- }
-
- sso = period_size - 1;
- } else {
- /* The initial period will fit inside the buffer, so we
- * don't need to use virtual periods -- disable them.
- */
- period_size = runtime->period_size;
- sso = vperiod - 1;
- vperiod = 0;
- }
-
- /* The interrupt handler implements the timing synchronization, so
- * setup its state.
- */
- timing->flags |= VOICE_SYNC_TIMING;
- timing->sync_base = voice->ctrl_base;
- timing->sync_cso = runtime->period_size;
- timing->sync_period_size = runtime->period_size;
- timing->sync_buffer_size = runtime->buffer_size;
- timing->period_size = period_size;
- timing->buffer_size = buffer_size;
- timing->sso = sso;
- timing->vperiod = vperiod;
-
- /* Using unsigned samples with the all-zero silence buffer
- * forces the output to the lower rail, killing playback.
- * So ignore unsigned vs signed -- it doesn't change the timing.
- */
- format = 0;
- if (snd_pcm_format_width(runtime->format) == 8)
- format = SIS_CAPTURE_DMA_FORMAT_8BIT;
- if (runtime->channels == 1)
- format |= SIS_CAPTURE_DMA_FORMAT_MONO;
-
- control = timing->buffer_size - 1;
- control |= SIS_PLAY_DMA_LOOP | SIS_PLAY_DMA_INTR_AT_SSO;
- sso_eso = timing->buffer_size - 1;
- sso_eso |= timing->sso << 16;
-
- delta = sis_rate_to_delta(runtime->rate);
-
- /* We've done the math, now configure the channel.
- */
- writel(format, play_base + SIS_PLAY_DMA_FORMAT_CSO);
- writel(sis->silence_dma_addr, play_base + SIS_PLAY_DMA_BASE);
- writel(control, play_base + SIS_PLAY_DMA_CONTROL);
- writel(sso_eso, play_base + SIS_PLAY_DMA_SSO_ESO);
-
- for (reg = 0; reg < SIS_WAVE_SIZE; reg += 4)
- writel(0, wave_base + reg);
-
- writel(SIS_WAVE_GENERAL_WAVE_VOLUME, wave_base + SIS_WAVE_GENERAL);
- writel(delta << 16, wave_base + SIS_WAVE_GENERAL_ARTICULATION);
- writel(SIS_WAVE_CHANNEL_CONTROL_FIRST_SAMPLE |
- SIS_WAVE_CHANNEL_CONTROL_AMP_ENABLE |
- SIS_WAVE_CHANNEL_CONTROL_INTERPOLATE_ENABLE,
- wave_base + SIS_WAVE_CHANNEL_CONTROL);
-}
-
-static int sis_pcm_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct voice *voice = runtime->private_data;
- void __iomem *rec_base = voice->ctrl_base;
- u32 format, dma_addr, control;
- u16 leo;
-
- /* We rely on the PCM core to ensure that the parameters for this
- * substream do not change on us while we're programming the HW.
- */
- format = 0;
- if (snd_pcm_format_width(runtime->format) == 8)
- format = SIS_CAPTURE_DMA_FORMAT_8BIT;
- if (!snd_pcm_format_signed(runtime->format))
- format |= SIS_CAPTURE_DMA_FORMAT_UNSIGNED;
- if (runtime->channels == 1)
- format |= SIS_CAPTURE_DMA_FORMAT_MONO;
-
- dma_addr = runtime->dma_addr;
- leo = runtime->buffer_size - 1;
- control = leo | SIS_CAPTURE_DMA_LOOP;
-
- /* If we've got more than two periods per buffer, then we have
- * use a timing voice to clock out the periods. Otherwise, we can
- * use the capture channel's interrupts.
- */
- if (voice->timing) {
- sis_prepare_timing_voice(voice, substream);
- } else {
- control |= SIS_CAPTURE_DMA_INTR_AT_LEO;
- if (runtime->period_size != runtime->buffer_size)
- control |= SIS_CAPTURE_DMA_INTR_AT_MLP;
- }
-
- writel(format, rec_base + SIS_CAPTURE_DMA_FORMAT_CSO);
- writel(dma_addr, rec_base + SIS_CAPTURE_DMA_BASE);
- writel(control, rec_base + SIS_CAPTURE_DMA_CONTROL);
-
- /* Force the writes to post. */
- readl(rec_base);
-
- return 0;
-}
-
-static struct snd_pcm_ops sis_playback_ops = {
- .open = sis_playback_open,
- .close = sis_substream_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = sis_playback_hw_params,
- .hw_free = sis_hw_free,
- .prepare = sis_pcm_playback_prepare,
- .trigger = sis_pcm_trigger,
- .pointer = sis_pcm_pointer,
-};
-
-static struct snd_pcm_ops sis_capture_ops = {
- .open = sis_capture_open,
- .close = sis_substream_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = sis_capture_hw_params,
- .hw_free = sis_hw_free,
- .prepare = sis_pcm_capture_prepare,
- .trigger = sis_pcm_trigger,
- .pointer = sis_pcm_pointer,
-};
-
-static int __devinit sis_pcm_create(struct sis7019 *sis)
-{
- struct snd_pcm *pcm;
- int rc;
-
- /* We have 64 voices, and the driver currently records from
- * only one channel, though that could change in the future.
- */
- rc = snd_pcm_new(sis->card, "SiS7019", 0, 64, 1, &pcm);
- if (rc)
- return rc;
-
- pcm->private_data = sis;
- strcpy(pcm->name, "SiS7019");
- sis->pcm = pcm;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &sis_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &sis_capture_ops);
-
- /* Try to preallocate some memory, but it's not the end of the
- * world if this fails.
- */
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(sis->pci), 64*1024, 128*1024);
-
- return 0;
-}
-
-static unsigned short sis_ac97_rw(struct sis7019 *sis, int codec, u32 cmd)
-{
- unsigned long io = sis->ioport;
- unsigned short val = 0xffff;
- u16 status;
- u16 rdy;
- int count;
- static const u16 codec_ready[3] = {
- SIS_AC97_STATUS_CODEC_READY,
- SIS_AC97_STATUS_CODEC2_READY,
- SIS_AC97_STATUS_CODEC3_READY,
- };
-
- rdy = codec_ready[codec];
-
-
- /* Get the AC97 semaphore -- software first, so we don't spin
- * pounding out IO reads on the hardware semaphore...
- */
- mutex_lock(&sis->ac97_mutex);
-
- count = 0xffff;
- while ((inw(io + SIS_AC97_SEMA) & SIS_AC97_SEMA_BUSY) && --count)
- udelay(1);
-
- if (!count)
- goto timeout;
-
- /* ... and wait for any outstanding commands to complete ...
- */
- count = 0xffff;
- do {
- status = inw(io + SIS_AC97_STATUS);
- if ((status & rdy) && !(status & SIS_AC97_STATUS_BUSY))
- break;
-
- udelay(1);
- } while (--count);
-
- if (!count)
- goto timeout_sema;
-
- /* ... before sending our command and waiting for it to finish ...
- */
- outl(cmd, io + SIS_AC97_CMD);
- udelay(10);
-
- count = 0xffff;
- while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count)
- udelay(1);
-
- /* ... and reading the results (if any).
- */
- val = inl(io + SIS_AC97_CMD) >> 16;
-
-timeout_sema:
- outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA);
-timeout:
- mutex_unlock(&sis->ac97_mutex);
-
- if (!count) {
- dev_err(&sis->pci->dev, "ac97 codec %d timeout cmd 0x%08x\n",
- codec, cmd);
- }
-
- return val;
-}
-
-static void sis_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short val)
-{
- static const u32 cmd[3] = {
- SIS_AC97_CMD_CODEC_WRITE,
- SIS_AC97_CMD_CODEC2_WRITE,
- SIS_AC97_CMD_CODEC3_WRITE,
- };
- sis_ac97_rw(ac97->private_data, ac97->num,
- (val << 16) | (reg << 8) | cmd[ac97->num]);
-}
-
-static unsigned short sis_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
-{
- static const u32 cmd[3] = {
- SIS_AC97_CMD_CODEC_READ,
- SIS_AC97_CMD_CODEC2_READ,
- SIS_AC97_CMD_CODEC3_READ,
- };
- return sis_ac97_rw(ac97->private_data, ac97->num,
- (reg << 8) | cmd[ac97->num]);
-}
-
-static int __devinit sis_mixer_create(struct sis7019 *sis)
-{
- struct snd_ac97_bus *bus;
- struct snd_ac97_template ac97;
- static struct snd_ac97_bus_ops ops = {
- .write = sis_ac97_write,
- .read = sis_ac97_read,
- };
- int rc;
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = sis;
-
- rc = snd_ac97_bus(sis->card, 0, &ops, NULL, &bus);
- if (!rc && sis->codecs_present & SIS_PRIMARY_CODEC_PRESENT)
- rc = snd_ac97_mixer(bus, &ac97, &sis->ac97[0]);
- ac97.num = 1;
- if (!rc && (sis->codecs_present & SIS_SECONDARY_CODEC_PRESENT))
- rc = snd_ac97_mixer(bus, &ac97, &sis->ac97[1]);
- ac97.num = 2;
- if (!rc && (sis->codecs_present & SIS_TERTIARY_CODEC_PRESENT))
- rc = snd_ac97_mixer(bus, &ac97, &sis->ac97[2]);
-
- /* If we return an error here, then snd_card_free() should
- * free up any ac97 codecs that got created, as well as the bus.
- */
- return rc;
-}
-
-static void sis_free_suspend(struct sis7019 *sis)
-{
- int i;
-
- for (i = 0; i < SIS_SUSPEND_PAGES; i++)
- kfree(sis->suspend_state[i]);
-}
-
-static int sis_chip_free(struct sis7019 *sis)
-{
- /* Reset the chip, and disable all interrputs.
- */
- outl(SIS_GCR_SOFTWARE_RESET, sis->ioport + SIS_GCR);
- udelay(25);
- outl(0, sis->ioport + SIS_GCR);
- outl(0, sis->ioport + SIS_GIER);
-
- /* Now, free everything we allocated.
- */
- if (sis->irq >= 0)
- free_irq(sis->irq, sis);
-
- if (sis->ioaddr)
- iounmap(sis->ioaddr);
-
- pci_release_regions(sis->pci);
- pci_disable_device(sis->pci);
-
- sis_free_suspend(sis);
- return 0;
-}
-
-static int sis_dev_free(struct snd_device *dev)
-{
- struct sis7019 *sis = dev->device_data;
- return sis_chip_free(sis);
-}
-
-static int sis_chip_init(struct sis7019 *sis)
-{
- unsigned long io = sis->ioport;
- void __iomem *ioaddr = sis->ioaddr;
- unsigned long timeout;
- u16 status;
- int count;
- int i;
-
- /* Reset the audio controller
- */
- outl(SIS_GCR_SOFTWARE_RESET, io + SIS_GCR);
- udelay(25);
- outl(0, io + SIS_GCR);
-
- /* Get the AC-link semaphore, and reset the codecs
- */
- count = 0xffff;
- while ((inw(io + SIS_AC97_SEMA) & SIS_AC97_SEMA_BUSY) && --count)
- udelay(1);
-
- if (!count)
- return -EIO;
-
- outl(SIS_AC97_CMD_CODEC_COLD_RESET, io + SIS_AC97_CMD);
- udelay(250);
-
- count = 0xffff;
- while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count)
- udelay(1);
-
- /* Command complete, we can let go of the semaphore now.
- */
- outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA);
- if (!count)
- return -EIO;
-
- /* Now that we've finished the reset, find out what's attached.
- * There are some codec/board combinations that take an extremely
- * long time to come up. 350+ ms has been observed in the field,
- * so we'll give them up to 500ms.
- */
- sis->codecs_present = 0;
- timeout = msecs_to_jiffies(500) + jiffies;
- while (time_before_eq(jiffies, timeout)) {
- status = inl(io + SIS_AC97_STATUS);
- if (status & SIS_AC97_STATUS_CODEC_READY)
- sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT;
- if (status & SIS_AC97_STATUS_CODEC2_READY)
- sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT;
- if (status & SIS_AC97_STATUS_CODEC3_READY)
- sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT;
-
- if (sis->codecs_present == codecs)
- break;
-
- msleep(1);
- }
-
- /* All done, check for errors.
- */
- if (!sis->codecs_present) {
- dev_err(&sis->pci->dev, "could not find any codecs\n");
- return -EIO;
- }
-
- if (sis->codecs_present != codecs) {
- dev_warn(&sis->pci->dev, "missing codecs, found %0x, expected %0x\n",
- sis->codecs_present, codecs);
- }
-
- /* Let the hardware know that the audio driver is alive,
- * and enable PCM slots on the AC-link for L/R playback (3 & 4) and
- * record channels. We're going to want to use Variable Rate Audio
- * for recording, to avoid needlessly resampling from 48kHZ.
- */
- outl(SIS_AC97_CONF_AUDIO_ALIVE, io + SIS_AC97_CONF);
- outl(SIS_AC97_CONF_AUDIO_ALIVE | SIS_AC97_CONF_PCM_LR_ENABLE |
- SIS_AC97_CONF_PCM_CAP_MIC_ENABLE |
- SIS_AC97_CONF_PCM_CAP_LR_ENABLE |
- SIS_AC97_CONF_CODEC_VRA_ENABLE, io + SIS_AC97_CONF);
-
- /* All AC97 PCM slots should be sourced from sub-mixer 0.
- */
- outl(0, io + SIS_AC97_PSR);
-
- /* There is only one valid DMA setup for a PCI environment.
- */
- outl(SIS_DMA_CSR_PCI_SETTINGS, io + SIS_DMA_CSR);
-
- /* Reset the synchronization groups for all of the channels
- * to be asyncronous. If we start doing SPDIF or 5.1 sound, etc.
- * we'll need to change how we handle these. Until then, we just
- * assign sub-mixer 0 to all playback channels, and avoid any
- * attenuation on the audio.
- */
- outl(0, io + SIS_PLAY_SYNC_GROUP_A);
- outl(0, io + SIS_PLAY_SYNC_GROUP_B);
- outl(0, io + SIS_PLAY_SYNC_GROUP_C);
- outl(0, io + SIS_PLAY_SYNC_GROUP_D);
- outl(0, io + SIS_MIXER_SYNC_GROUP);
-
- for (i = 0; i < 64; i++) {
- writel(i, SIS_MIXER_START_ADDR(ioaddr, i));
- writel(SIS_MIXER_RIGHT_NO_ATTEN | SIS_MIXER_LEFT_NO_ATTEN |
- SIS_MIXER_DEST_0, SIS_MIXER_ADDR(ioaddr, i));
- }
-
- /* Don't attenuate any audio set for the wave amplifier.
- *
- * FIXME: Maximum attenuation is set for the music amp, which will
- * need to change if we start using the synth engine.
- */
- outl(0xffff0000, io + SIS_WEVCR);
-
- /* Ensure that the wave engine is in normal operating mode.
- */
- outl(0, io + SIS_WECCR);
-
- /* Go ahead and enable the DMA interrupts. They won't go live
- * until we start a channel.
- */
- outl(SIS_GIER_AUDIO_PLAY_DMA_IRQ_ENABLE |
- SIS_GIER_AUDIO_RECORD_DMA_IRQ_ENABLE, io + SIS_GIER);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int sis_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct sis7019 *sis = card->private_data;
- void __iomem *ioaddr = sis->ioaddr;
- int i;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(sis->pcm);
- if (sis->codecs_present & SIS_PRIMARY_CODEC_PRESENT)
- snd_ac97_suspend(sis->ac97[0]);
- if (sis->codecs_present & SIS_SECONDARY_CODEC_PRESENT)
- snd_ac97_suspend(sis->ac97[1]);
- if (sis->codecs_present & SIS_TERTIARY_CODEC_PRESENT)
- snd_ac97_suspend(sis->ac97[2]);
-
- /* snd_pcm_suspend_all() stopped all channels, so we're quiescent.
- */
- if (sis->irq >= 0) {
- free_irq(sis->irq, sis);
- sis->irq = -1;
- }
-
- /* Save the internal state away
- */
- for (i = 0; i < 4; i++) {
- memcpy_fromio(sis->suspend_state[i], ioaddr, 4096);
- ioaddr += 4096;
- }
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int sis_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct sis7019 *sis = card->private_data;
- void __iomem *ioaddr = sis->ioaddr;
- int i;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
-
- if (pci_enable_device(pci) < 0) {
- dev_err(&pci->dev, "unable to re-enable device\n");
- goto error;
- }
-
- if (sis_chip_init(sis)) {
- dev_err(&pci->dev, "unable to re-init controller\n");
- goto error;
- }
-
- if (request_irq(pci->irq, sis_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, sis)) {
- dev_err(&pci->dev, "unable to regain IRQ %d\n", pci->irq);
- goto error;
- }
-
- /* Restore saved state, then clear out the page we use for the
- * silence buffer.
- */
- for (i = 0; i < 4; i++) {
- memcpy_toio(ioaddr, sis->suspend_state[i], 4096);
- ioaddr += 4096;
- }
-
- memset(sis->suspend_state[0], 0, 4096);
-
- sis->irq = pci->irq;
- pci_set_master(pci);
-
- if (sis->codecs_present & SIS_PRIMARY_CODEC_PRESENT)
- snd_ac97_resume(sis->ac97[0]);
- if (sis->codecs_present & SIS_SECONDARY_CODEC_PRESENT)
- snd_ac97_resume(sis->ac97[1]);
- if (sis->codecs_present & SIS_TERTIARY_CODEC_PRESENT)
- snd_ac97_resume(sis->ac97[2]);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-
-error:
- snd_card_disconnect(card);
- return -EIO;
-}
-#endif /* CONFIG_PM */
-
-static int sis_alloc_suspend(struct sis7019 *sis)
-{
- int i;
-
- /* We need 16K to store the internal wave engine state during a
- * suspend, but we don't need it to be contiguous, so play nice
- * with the memory system. We'll also use this area for a silence
- * buffer.
- */
- for (i = 0; i < SIS_SUSPEND_PAGES; i++) {
- sis->suspend_state[i] = kmalloc(4096, GFP_KERNEL);
- if (!sis->suspend_state[i])
- return -ENOMEM;
- }
- memset(sis->suspend_state[0], 0, 4096);
-
- return 0;
-}
-
-static int __devinit sis_chip_create(struct snd_card *card,
- struct pci_dev *pci)
-{
- struct sis7019 *sis = card->private_data;
- struct voice *voice;
- static struct snd_device_ops ops = {
- .dev_free = sis_dev_free,
- };
- int rc;
- int i;
-
- rc = pci_enable_device(pci);
- if (rc)
- goto error_out;
-
- if (pci_set_dma_mask(pci, DMA_BIT_MASK(30)) < 0) {
- dev_err(&pci->dev, "architecture does not support 30-bit PCI busmaster DMA");
- goto error_out_enabled;
- }
-
- memset(sis, 0, sizeof(*sis));
- mutex_init(&sis->ac97_mutex);
- spin_lock_init(&sis->voice_lock);
- sis->card = card;
- sis->pci = pci;
- sis->irq = -1;
- sis->ioport = pci_resource_start(pci, 0);
-
- rc = pci_request_regions(pci, "SiS7019");
- if (rc) {
- dev_err(&pci->dev, "unable request regions\n");
- goto error_out_enabled;
- }
-
- rc = -EIO;
- sis->ioaddr = ioremap_nocache(pci_resource_start(pci, 1), 0x4000);
- if (!sis->ioaddr) {
- dev_err(&pci->dev, "unable to remap MMIO, aborting\n");
- goto error_out_cleanup;
- }
-
- rc = sis_alloc_suspend(sis);
- if (rc < 0) {
- dev_err(&pci->dev, "unable to allocate state storage\n");
- goto error_out_cleanup;
- }
-
- rc = sis_chip_init(sis);
- if (rc)
- goto error_out_cleanup;
-
- if (request_irq(pci->irq, sis_interrupt, IRQF_SHARED, KBUILD_MODNAME,
- sis)) {
- dev_err(&pci->dev, "unable to allocate irq %d\n", sis->irq);
- goto error_out_cleanup;
- }
-
- sis->irq = pci->irq;
- pci_set_master(pci);
-
- for (i = 0; i < 64; i++) {
- voice = &sis->voices[i];
- voice->num = i;
- voice->ctrl_base = SIS_PLAY_DMA_ADDR(sis->ioaddr, i);
- voice->wave_base = SIS_WAVE_ADDR(sis->ioaddr, i);
- }
-
- voice = &sis->capture_voice;
- voice->flags = VOICE_CAPTURE;
- voice->num = SIS_CAPTURE_CHAN_AC97_PCM_IN;
- voice->ctrl_base = SIS_CAPTURE_DMA_ADDR(sis->ioaddr, voice->num);
-
- rc = snd_device_new(card, SNDRV_DEV_LOWLEVEL, sis, &ops);
- if (rc)
- goto error_out_cleanup;
-
- snd_card_set_dev(card, &pci->dev);
-
- return 0;
-
-error_out_cleanup:
- sis_chip_free(sis);
-
-error_out_enabled:
- pci_disable_device(pci);
-
-error_out:
- return rc;
-}
-
-static int __devinit snd_sis7019_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- struct snd_card *card;
- struct sis7019 *sis;
- int rc;
-
- rc = -ENOENT;
- if (!enable)
- goto error_out;
-
- /* The user can specify which codecs should be present so that we
- * can wait for them to show up if they are slow to recover from
- * the AC97 cold reset. We default to a single codec, the primary.
- *
- * We assume that SIS_PRIMARY_*_PRESENT matches bits 0-2.
- */
- codecs &= SIS_PRIMARY_CODEC_PRESENT | SIS_SECONDARY_CODEC_PRESENT |
- SIS_TERTIARY_CODEC_PRESENT;
- if (!codecs)
- codecs = SIS_PRIMARY_CODEC_PRESENT;
-
- rc = snd_card_create(index, id, THIS_MODULE, sizeof(*sis), &card);
- if (rc < 0)
- goto error_out;
-
- strcpy(card->driver, "SiS7019");
- strcpy(card->shortname, "SiS7019");
- rc = sis_chip_create(card, pci);
- if (rc)
- goto card_error_out;
-
- sis = card->private_data;
-
- rc = sis_mixer_create(sis);
- if (rc)
- goto card_error_out;
-
- rc = sis_pcm_create(sis);
- if (rc)
- goto card_error_out;
-
- snprintf(card->longname, sizeof(card->longname),
- "%s Audio Accelerator with %s at 0x%lx, irq %d",
- card->shortname, snd_ac97_get_short_name(sis->ac97[0]),
- sis->ioport, sis->irq);
-
- rc = snd_card_register(card);
- if (rc)
- goto card_error_out;
-
- pci_set_drvdata(pci, card);
- return 0;
-
-card_error_out:
- snd_card_free(card);
-
-error_out:
- return rc;
-}
-
-static void __devexit snd_sis7019_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver sis7019_driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_sis7019_ids,
- .probe = snd_sis7019_probe,
- .remove = __devexit_p(snd_sis7019_remove),
-
-#ifdef CONFIG_PM
- .suspend = sis_suspend,
- .resume = sis_resume,
-#endif
-};
-
-static int __init sis7019_init(void)
-{
- return pci_register_driver(&sis7019_driver);
-}
-
-static void __exit sis7019_exit(void)
-{
- pci_unregister_driver(&sis7019_driver);
-}
-
-module_init(sis7019_init);
-module_exit(sis7019_exit);
diff --git a/ANDROID_3.4.5/sound/pci/sis7019.h b/ANDROID_3.4.5/sound/pci/sis7019.h
deleted file mode 100644
index bc8c7681..00000000
--- a/ANDROID_3.4.5/sound/pci/sis7019.h
+++ /dev/null
@@ -1,342 +0,0 @@
-#ifndef __sis7019_h__
-#define __sis7019_h__
-
-/*
- * Definitions for SiS7019 Audio Accelerator
- *
- * Copyright (C) 2004-2007, David Dillow
- * Written by David Dillow <dave@thedillows.org>
- * Inspired by the Trident 4D-WaveDX/NX driver.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 2.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-/* General Control Register */
-#define SIS_GCR 0x00
-#define SIS_GCR_MACRO_POWER_DOWN 0x80000000
-#define SIS_GCR_MODEM_ENABLE 0x00010000
-#define SIS_GCR_SOFTWARE_RESET 0x00000001
-
-/* General Interrupt Enable Register */
-#define SIS_GIER 0x04
-#define SIS_GIER_MODEM_TIMER_IRQ_ENABLE 0x00100000
-#define SIS_GIER_MODEM_RX_DMA_IRQ_ENABLE 0x00080000
-#define SIS_GIER_MODEM_TX_DMA_IRQ_ENABLE 0x00040000
-#define SIS_GIER_AC97_GPIO1_IRQ_ENABLE 0x00020000
-#define SIS_GIER_AC97_GPIO0_IRQ_ENABLE 0x00010000
-#define SIS_GIER_AC97_SAMPLE_TIMER_IRQ_ENABLE 0x00000010
-#define SIS_GIER_AUDIO_GLOBAL_TIMER_IRQ_ENABLE 0x00000008
-#define SIS_GIER_AUDIO_RECORD_DMA_IRQ_ENABLE 0x00000004
-#define SIS_GIER_AUDIO_PLAY_DMA_IRQ_ENABLE 0x00000002
-#define SIS_GIER_AUDIO_WAVE_ENGINE_IRQ_ENABLE 0x00000001
-
-/* General Interrupt Status Register */
-#define SIS_GISR 0x08
-#define SIS_GISR_MODEM_TIMER_IRQ_STATUS 0x00100000
-#define SIS_GISR_MODEM_RX_DMA_IRQ_STATUS 0x00080000
-#define SIS_GISR_MODEM_TX_DMA_IRQ_STATUS 0x00040000
-#define SIS_GISR_AC97_GPIO1_IRQ_STATUS 0x00020000
-#define SIS_GISR_AC97_GPIO0_IRQ_STATUS 0x00010000
-#define SIS_GISR_AC97_SAMPLE_TIMER_IRQ_STATUS 0x00000010
-#define SIS_GISR_AUDIO_GLOBAL_TIMER_IRQ_STATUS 0x00000008
-#define SIS_GISR_AUDIO_RECORD_DMA_IRQ_STATUS 0x00000004
-#define SIS_GISR_AUDIO_PLAY_DMA_IRQ_STATUS 0x00000002
-#define SIS_GISR_AUDIO_WAVE_ENGINE_IRQ_STATUS 0x00000001
-
-/* DMA Control Register */
-#define SIS_DMA_CSR 0x10
-#define SIS_DMA_CSR_PCI_SETTINGS 0x0000001d
-#define SIS_DMA_CSR_CONCURRENT_ENABLE 0x00000200
-#define SIS_DMA_CSR_PIPELINE_ENABLE 0x00000100
-#define SIS_DMA_CSR_RX_DRAIN_ENABLE 0x00000010
-#define SIS_DMA_CSR_RX_FILL_ENABLE 0x00000008
-#define SIS_DMA_CSR_TX_DRAIN_ENABLE 0x00000004
-#define SIS_DMA_CSR_TX_LOWPRI_FILL_ENABLE 0x00000002
-#define SIS_DMA_CSR_TX_HIPRI_FILL_ENABLE 0x00000001
-
-/* Playback Channel Start Registers */
-#define SIS_PLAY_START_A_REG 0x14
-#define SIS_PLAY_START_B_REG 0x18
-
-/* Playback Channel Stop Registers */
-#define SIS_PLAY_STOP_A_REG 0x1c
-#define SIS_PLAY_STOP_B_REG 0x20
-
-/* Recording Channel Start Register */
-#define SIS_RECORD_START_REG 0x24
-
-/* Recording Channel Stop Register */
-#define SIS_RECORD_STOP_REG 0x28
-
-/* Playback Interrupt Status Registers */
-#define SIS_PISR_A 0x2c
-#define SIS_PISR_B 0x30
-
-/* Recording Interrupt Status Register */
-#define SIS_RISR 0x34
-
-/* AC97 AC-link Playback Source Register */
-#define SIS_AC97_PSR 0x40
-#define SIS_AC97_PSR_MODEM_HEADSET_SRC_MIXER 0x0f000000
-#define SIS_AC97_PSR_MODEM_LINE2_SRC_MIXER 0x00f00000
-#define SIS_AC97_PSR_MODEM_LINE1_SRC_MIXER 0x000f0000
-#define SIS_AC97_PSR_PCM_LFR_SRC_MIXER 0x0000f000
-#define SIS_AC97_PSR_PCM_SURROUND_SRC_MIXER 0x00000f00
-#define SIS_AC97_PSR_PCM_CENTER_SRC_MIXER 0x000000f0
-#define SIS_AC97_PSR_PCM_LR_SRC_MIXER 0x0000000f
-
-/* AC97 AC-link Command Register */
-#define SIS_AC97_CMD 0x50
-#define SIS_AC97_CMD_DATA_MASK 0xffff0000
-#define SIS_AC97_CMD_REG_MASK 0x0000ff00
-#define SIS_AC97_CMD_CODEC3_READ 0x0000000d
-#define SIS_AC97_CMD_CODEC3_WRITE 0x0000000c
-#define SIS_AC97_CMD_CODEC2_READ 0x0000000b
-#define SIS_AC97_CMD_CODEC2_WRITE 0x0000000a
-#define SIS_AC97_CMD_CODEC_READ 0x00000009
-#define SIS_AC97_CMD_CODEC_WRITE 0x00000008
-#define SIS_AC97_CMD_CODEC_WARM_RESET 0x00000005
-#define SIS_AC97_CMD_CODEC_COLD_RESET 0x00000004
-#define SIS_AC97_CMD_DONE 0x00000000
-
-/* AC97 AC-link Semaphore Register */
-#define SIS_AC97_SEMA 0x54
-#define SIS_AC97_SEMA_BUSY 0x00000001
-#define SIS_AC97_SEMA_RELEASE 0x00000000
-
-/* AC97 AC-link Status Register */
-#define SIS_AC97_STATUS 0x58
-#define SIS_AC97_STATUS_AUDIO_D2_INACT_SECS 0x03f00000
-#define SIS_AC97_STATUS_MODEM_ALIVE 0x00002000
-#define SIS_AC97_STATUS_AUDIO_ALIVE 0x00001000
-#define SIS_AC97_STATUS_CODEC3_READY 0x00000400
-#define SIS_AC97_STATUS_CODEC2_READY 0x00000200
-#define SIS_AC97_STATUS_CODEC_READY 0x00000100
-#define SIS_AC97_STATUS_WARM_RESET 0x00000080
-#define SIS_AC97_STATUS_COLD_RESET 0x00000040
-#define SIS_AC97_STATUS_POWERED_DOWN 0x00000020
-#define SIS_AC97_STATUS_NORMAL 0x00000010
-#define SIS_AC97_STATUS_READ_EXPIRED 0x00000004
-#define SIS_AC97_STATUS_SEMAPHORE 0x00000002
-#define SIS_AC97_STATUS_BUSY 0x00000001
-
-/* AC97 AC-link Audio Configuration Register */
-#define SIS_AC97_CONF 0x5c
-#define SIS_AC97_CONF_AUDIO_ALIVE 0x80000000
-#define SIS_AC97_CONF_WARM_RESET_ENABLE 0x40000000
-#define SIS_AC97_CONF_PR6_ENABLE 0x20000000
-#define SIS_AC97_CONF_PR5_ENABLE 0x10000000
-#define SIS_AC97_CONF_PR4_ENABLE 0x08000000
-#define SIS_AC97_CONF_PR3_ENABLE 0x04000000
-#define SIS_AC97_CONF_PR2_PR7_ENABLE 0x02000000
-#define SIS_AC97_CONF_PR0_PR1_ENABLE 0x01000000
-#define SIS_AC97_CONF_AUTO_PM_ENABLE 0x00800000
-#define SIS_AC97_CONF_PCM_LFE_ENABLE 0x00080000
-#define SIS_AC97_CONF_PCM_SURROUND_ENABLE 0x00040000
-#define SIS_AC97_CONF_PCM_CENTER_ENABLE 0x00020000
-#define SIS_AC97_CONF_PCM_LR_ENABLE 0x00010000
-#define SIS_AC97_CONF_PCM_CAP_MIC_ENABLE 0x00002000
-#define SIS_AC97_CONF_PCM_CAP_LR_ENABLE 0x00001000
-#define SIS_AC97_CONF_PCM_CAP_MIC_FROM_CODEC3 0x00000200
-#define SIS_AC97_CONF_PCM_CAP_LR_FROM_CODEC3 0x00000100
-#define SIS_AC97_CONF_CODEC3_PM_VRM 0x00000080
-#define SIS_AC97_CONF_CODEC_PM_VRM 0x00000040
-#define SIS_AC97_CONF_CODEC3_VRA_ENABLE 0x00000020
-#define SIS_AC97_CONF_CODEC_VRA_ENABLE 0x00000010
-#define SIS_AC97_CONF_CODEC3_PM_EAC 0x00000008
-#define SIS_AC97_CONF_CODEC_PM_EAC 0x00000004
-#define SIS_AC97_CONF_CODEC3_EXISTS 0x00000002
-#define SIS_AC97_CONF_CODEC_EXISTS 0x00000001
-
-/* Playback Channel Sync Group registers */
-#define SIS_PLAY_SYNC_GROUP_A 0x80
-#define SIS_PLAY_SYNC_GROUP_B 0x84
-#define SIS_PLAY_SYNC_GROUP_C 0x88
-#define SIS_PLAY_SYNC_GROUP_D 0x8c
-#define SIS_MIXER_SYNC_GROUP 0x90
-
-/* Wave Engine Config and Control Register */
-#define SIS_WECCR 0xa0
-#define SIS_WECCR_TESTMODE_MASK 0x00300000
-#define SIS_WECCR_TESTMODE_NORMAL 0x00000000
-#define SIS_WECCR_TESTMODE_BYPASS_NSO_ALPHA 0x00100000
-#define SIS_WECCR_TESTMODE_BYPASS_FC 0x00200000
-#define SIS_WECCR_TESTMODE_BYPASS_WOL 0x00300000
-#define SIS_WECCR_RESONANCE_DELAY_MASK 0x00060000
-#define SIS_WECCR_RESONANCE_DELAY_NONE 0x00000000
-#define SIS_WECCR_RESONANCE_DELAY_FC_1F00 0x00020000
-#define SIS_WECCR_RESONANCE_DELAY_FC_1E00 0x00040000
-#define SIS_WECCR_RESONANCE_DELAY_FC_1C00 0x00060000
-#define SIS_WECCR_IGNORE_CHANNEL_PARMS 0x00010000
-#define SIS_WECCR_COMMAND_CHANNEL_ID_MASK 0x0003ff00
-#define SIS_WECCR_COMMAND_MASK 0x00000007
-#define SIS_WECCR_COMMAND_NONE 0x00000000
-#define SIS_WECCR_COMMAND_DONE 0x00000000
-#define SIS_WECCR_COMMAND_PAUSE 0x00000001
-#define SIS_WECCR_COMMAND_TOGGLE_VEG 0x00000002
-#define SIS_WECCR_COMMAND_TOGGLE_MEG 0x00000003
-#define SIS_WECCR_COMMAND_TOGGLE_VEG_MEG 0x00000004
-
-/* Wave Engine Volume Control Register */
-#define SIS_WEVCR 0xa4
-#define SIS_WEVCR_LEFT_MUSIC_ATTENUATION_MASK 0xff000000
-#define SIS_WEVCR_RIGHT_MUSIC_ATTENUATION_MASK 0x00ff0000
-#define SIS_WEVCR_LEFT_WAVE_ATTENUATION_MASK 0x0000ff00
-#define SIS_WEVCR_RIGHT_WAVE_ATTENUATION_MASK 0x000000ff
-
-/* Wave Engine Interrupt Status Registers */
-#define SIS_WEISR_A 0xa8
-#define SIS_WEISR_B 0xac
-
-
-/* Playback DMA parameters (parameter RAM) */
-#define SIS_PLAY_DMA_OFFSET 0x0000
-#define SIS_PLAY_DMA_SIZE 0x10
-#define SIS_PLAY_DMA_ADDR(addr, num) \
- ((num * SIS_PLAY_DMA_SIZE) + (addr) + SIS_PLAY_DMA_OFFSET)
-
-#define SIS_PLAY_DMA_FORMAT_CSO 0x00
-#define SIS_PLAY_DMA_FORMAT_UNSIGNED 0x00080000
-#define SIS_PLAY_DMA_FORMAT_8BIT 0x00040000
-#define SIS_PLAY_DMA_FORMAT_MONO 0x00020000
-#define SIS_PLAY_DMA_CSO_MASK 0x0000ffff
-#define SIS_PLAY_DMA_BASE 0x04
-#define SIS_PLAY_DMA_CONTROL 0x08
-#define SIS_PLAY_DMA_STOP_AT_SSO 0x04000000
-#define SIS_PLAY_DMA_RELEASE 0x02000000
-#define SIS_PLAY_DMA_LOOP 0x01000000
-#define SIS_PLAY_DMA_INTR_AT_SSO 0x00080000
-#define SIS_PLAY_DMA_INTR_AT_ESO 0x00040000
-#define SIS_PLAY_DMA_INTR_AT_LEO 0x00020000
-#define SIS_PLAY_DMA_INTR_AT_MLP 0x00010000
-#define SIS_PLAY_DMA_LEO_MASK 0x0000ffff
-#define SIS_PLAY_DMA_SSO_ESO 0x0c
-#define SIS_PLAY_DMA_SSO_MASK 0xffff0000
-#define SIS_PLAY_DMA_ESO_MASK 0x0000ffff
-
-/* Capture DMA parameters (parameter RAM) */
-#define SIS_CAPTURE_DMA_OFFSET 0x0800
-#define SIS_CAPTURE_DMA_SIZE 0x10
-#define SIS_CAPTURE_DMA_ADDR(addr, num) \
- ((num * SIS_CAPTURE_DMA_SIZE) + (addr) + SIS_CAPTURE_DMA_OFFSET)
-
-#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_0 0
-#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_1 1
-#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_2 2
-#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_3 3
-#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_4 4
-#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_5 5
-#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_6 6
-#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_7 7
-#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_8 8
-#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_9 9
-#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_10 10
-#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_11 11
-#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_12 12
-#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_13 13
-#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_14 14
-#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_15 15
-#define SIS_CAPTURE_CHAN_AC97_PCM_IN 16
-#define SIS_CAPTURE_CHAN_AC97_MIC_IN 17
-#define SIS_CAPTURE_CHAN_AC97_LINE1_IN 18
-#define SIS_CAPTURE_CHAN_AC97_LINE2_IN 19
-#define SIS_CAPTURE_CHAN_AC97_HANDSE_IN 20
-
-#define SIS_CAPTURE_DMA_FORMAT_CSO 0x00
-#define SIS_CAPTURE_DMA_MONO_MODE_MASK 0xc0000000
-#define SIS_CAPTURE_DMA_MONO_MODE_AVG 0x00000000
-#define SIS_CAPTURE_DMA_MONO_MODE_LEFT 0x40000000
-#define SIS_CAPTURE_DMA_MONO_MODE_RIGHT 0x80000000
-#define SIS_CAPTURE_DMA_FORMAT_UNSIGNED 0x00080000
-#define SIS_CAPTURE_DMA_FORMAT_8BIT 0x00040000
-#define SIS_CAPTURE_DMA_FORMAT_MONO 0x00020000
-#define SIS_CAPTURE_DMA_CSO_MASK 0x0000ffff
-#define SIS_CAPTURE_DMA_BASE 0x04
-#define SIS_CAPTURE_DMA_CONTROL 0x08
-#define SIS_CAPTURE_DMA_STOP_AT_SSO 0x04000000
-#define SIS_CAPTURE_DMA_RELEASE 0x02000000
-#define SIS_CAPTURE_DMA_LOOP 0x01000000
-#define SIS_CAPTURE_DMA_INTR_AT_LEO 0x00020000
-#define SIS_CAPTURE_DMA_INTR_AT_MLP 0x00010000
-#define SIS_CAPTURE_DMA_LEO_MASK 0x0000ffff
-#define SIS_CAPTURE_DMA_RESERVED 0x0c
-
-
-/* Mixer routing list start pointer (parameter RAM) */
-#define SIS_MIXER_START_OFFSET 0x1000
-#define SIS_MIXER_START_SIZE 0x04
-#define SIS_MIXER_START_ADDR(addr, num) \
- ((num * SIS_MIXER_START_SIZE) + (addr) + SIS_MIXER_START_OFFSET)
-
-#define SIS_MIXER_START_MASK 0x0000007f
-
-/* Mixer routing table (parameter RAM) */
-#define SIS_MIXER_OFFSET 0x1400
-#define SIS_MIXER_SIZE 0x04
-#define SIS_MIXER_ADDR(addr, num) \
- ((num * SIS_MIXER_SIZE) + (addr) + SIS_MIXER_OFFSET)
-
-#define SIS_MIXER_RIGHT_ATTENUTATION_MASK 0xff000000
-#define SIS_MIXER_RIGHT_NO_ATTEN 0xff000000
-#define SIS_MIXER_LEFT_ATTENUTATION_MASK 0x00ff0000
-#define SIS_MIXER_LEFT_NO_ATTEN 0x00ff0000
-#define SIS_MIXER_NEXT_ENTRY_MASK 0x00007f00
-#define SIS_MIXER_NEXT_ENTRY_NONE 0x00000000
-#define SIS_MIXER_DEST_MASK 0x0000007f
-#define SIS_MIXER_DEST_0 0x00000020
-#define SIS_MIXER_DEST_1 0x00000021
-#define SIS_MIXER_DEST_2 0x00000022
-#define SIS_MIXER_DEST_3 0x00000023
-#define SIS_MIXER_DEST_4 0x00000024
-#define SIS_MIXER_DEST_5 0x00000025
-#define SIS_MIXER_DEST_6 0x00000026
-#define SIS_MIXER_DEST_7 0x00000027
-#define SIS_MIXER_DEST_8 0x00000028
-#define SIS_MIXER_DEST_9 0x00000029
-#define SIS_MIXER_DEST_10 0x0000002a
-#define SIS_MIXER_DEST_11 0x0000002b
-#define SIS_MIXER_DEST_12 0x0000002c
-#define SIS_MIXER_DEST_13 0x0000002d
-#define SIS_MIXER_DEST_14 0x0000002e
-#define SIS_MIXER_DEST_15 0x0000002f
-
-/* Wave Engine Control Parameters (parameter RAM) */
-#define SIS_WAVE_OFFSET 0x2000
-#define SIS_WAVE_SIZE 0x40
-#define SIS_WAVE_ADDR(addr, num) \
- ((num * SIS_WAVE_SIZE) + (addr) + SIS_WAVE_OFFSET)
-
-#define SIS_WAVE_GENERAL 0x00
-#define SIS_WAVE_GENERAL_WAVE_VOLUME 0x80000000
-#define SIS_WAVE_GENERAL_MUSIC_VOLUME 0x00000000
-#define SIS_WAVE_GENERAL_VOLUME_MASK 0x7f000000
-#define SIS_WAVE_GENERAL_ARTICULATION 0x04
-#define SIS_WAVE_GENERAL_ARTICULATION_DELTA_MASK 0x3fff0000
-#define SIS_WAVE_ARTICULATION 0x08
-#define SIS_WAVE_TIMER 0x0c
-#define SIS_WAVE_GENERATOR 0x10
-#define SIS_WAVE_CHANNEL_CONTROL 0x14
-#define SIS_WAVE_CHANNEL_CONTROL_FIRST_SAMPLE 0x80000000
-#define SIS_WAVE_CHANNEL_CONTROL_AMP_ENABLE 0x40000000
-#define SIS_WAVE_CHANNEL_CONTROL_FILTER_ENABLE 0x20000000
-#define SIS_WAVE_CHANNEL_CONTROL_INTERPOLATE_ENABLE 0x10000000
-#define SIS_WAVE_LFO_EG_CONTROL 0x18
-#define SIS_WAVE_LFO_EG_CONTROL_2 0x1c
-#define SIS_WAVE_LFO_EG_CONTROL_3 0x20
-#define SIS_WAVE_LFO_EG_CONTROL_4 0x24
-
-#endif /* __sis7019_h__ */
diff --git a/ANDROID_3.4.5/sound/pci/sonicvibes.c b/ANDROID_3.4.5/sound/pci/sonicvibes.c
deleted file mode 100644
index 54cc8020..00000000
--- a/ANDROID_3.4.5/sound/pci/sonicvibes.c
+++ /dev/null
@@ -1,1551 +0,0 @@
-/*
- * Driver for S3 SonicVibes soundcard
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- * BUGS:
- * It looks like 86c617 rev 3 doesn't supports DDMA buffers above 16MB?
- * Driver sometimes hangs... Nobody knows why at this moment...
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/gameport.h>
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/mpu401.h>
-#include <sound/opl3.h>
-#include <sound/initval.h>
-
-#include <asm/io.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("S3 SonicVibes PCI");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{S3,SonicVibes PCI}}");
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK 1
-#endif
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static bool reverb[SNDRV_CARDS];
-static bool mge[SNDRV_CARDS];
-static unsigned int dmaio = 0x7a00; /* DDMA i/o address */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for S3 SonicVibes soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for S3 SonicVibes soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable S3 SonicVibes soundcard.");
-module_param_array(reverb, bool, NULL, 0444);
-MODULE_PARM_DESC(reverb, "Enable reverb (SRAM is present) for S3 SonicVibes soundcard.");
-module_param_array(mge, bool, NULL, 0444);
-MODULE_PARM_DESC(mge, "MIC Gain Enable for S3 SonicVibes soundcard.");
-module_param(dmaio, uint, 0444);
-MODULE_PARM_DESC(dmaio, "DDMA i/o base address for S3 SonicVibes soundcard.");
-
-/*
- * Enhanced port direct registers
- */
-
-#define SV_REG(sonic, x) ((sonic)->enh_port + SV_REG_##x)
-
-#define SV_REG_CONTROL 0x00 /* R/W: CODEC/Mixer control register */
-#define SV_ENHANCED 0x01 /* audio mode select - enhanced mode */
-#define SV_TEST 0x02 /* test bit */
-#define SV_REVERB 0x04 /* reverb enable */
-#define SV_WAVETABLE 0x08 /* wavetable active / FM active if not set */
-#define SV_INTA 0x20 /* INTA driving - should be always 1 */
-#define SV_RESET 0x80 /* reset chip */
-#define SV_REG_IRQMASK 0x01 /* R/W: CODEC/Mixer interrupt mask register */
-#define SV_DMAA_MASK 0x01 /* mask DMA-A interrupt */
-#define SV_DMAC_MASK 0x04 /* mask DMA-C interrupt */
-#define SV_SPEC_MASK 0x08 /* special interrupt mask - should be always masked */
-#define SV_UD_MASK 0x40 /* Up/Down button interrupt mask */
-#define SV_MIDI_MASK 0x80 /* mask MIDI interrupt */
-#define SV_REG_STATUS 0x02 /* R/O: CODEC/Mixer status register */
-#define SV_DMAA_IRQ 0x01 /* DMA-A interrupt */
-#define SV_DMAC_IRQ 0x04 /* DMA-C interrupt */
-#define SV_SPEC_IRQ 0x08 /* special interrupt */
-#define SV_UD_IRQ 0x40 /* Up/Down interrupt */
-#define SV_MIDI_IRQ 0x80 /* MIDI interrupt */
-#define SV_REG_INDEX 0x04 /* R/W: CODEC/Mixer index address register */
-#define SV_MCE 0x40 /* mode change enable */
-#define SV_TRD 0x80 /* DMA transfer request disabled */
-#define SV_REG_DATA 0x05 /* R/W: CODEC/Mixer index data register */
-
-/*
- * Enhanced port indirect registers
- */
-
-#define SV_IREG_LEFT_ADC 0x00 /* Left ADC Input Control */
-#define SV_IREG_RIGHT_ADC 0x01 /* Right ADC Input Control */
-#define SV_IREG_LEFT_AUX1 0x02 /* Left AUX1 Input Control */
-#define SV_IREG_RIGHT_AUX1 0x03 /* Right AUX1 Input Control */
-#define SV_IREG_LEFT_CD 0x04 /* Left CD Input Control */
-#define SV_IREG_RIGHT_CD 0x05 /* Right CD Input Control */
-#define SV_IREG_LEFT_LINE 0x06 /* Left Line Input Control */
-#define SV_IREG_RIGHT_LINE 0x07 /* Right Line Input Control */
-#define SV_IREG_MIC 0x08 /* MIC Input Control */
-#define SV_IREG_GAME_PORT 0x09 /* Game Port Control */
-#define SV_IREG_LEFT_SYNTH 0x0a /* Left Synth Input Control */
-#define SV_IREG_RIGHT_SYNTH 0x0b /* Right Synth Input Control */
-#define SV_IREG_LEFT_AUX2 0x0c /* Left AUX2 Input Control */
-#define SV_IREG_RIGHT_AUX2 0x0d /* Right AUX2 Input Control */
-#define SV_IREG_LEFT_ANALOG 0x0e /* Left Analog Mixer Output Control */
-#define SV_IREG_RIGHT_ANALOG 0x0f /* Right Analog Mixer Output Control */
-#define SV_IREG_LEFT_PCM 0x10 /* Left PCM Input Control */
-#define SV_IREG_RIGHT_PCM 0x11 /* Right PCM Input Control */
-#define SV_IREG_DMA_DATA_FMT 0x12 /* DMA Data Format */
-#define SV_IREG_PC_ENABLE 0x13 /* Playback/Capture Enable Register */
-#define SV_IREG_UD_BUTTON 0x14 /* Up/Down Button Register */
-#define SV_IREG_REVISION 0x15 /* Revision */
-#define SV_IREG_ADC_OUTPUT_CTRL 0x16 /* ADC Output Control */
-#define SV_IREG_DMA_A_UPPER 0x18 /* DMA A Upper Base Count */
-#define SV_IREG_DMA_A_LOWER 0x19 /* DMA A Lower Base Count */
-#define SV_IREG_DMA_C_UPPER 0x1c /* DMA C Upper Base Count */
-#define SV_IREG_DMA_C_LOWER 0x1d /* DMA C Lower Base Count */
-#define SV_IREG_PCM_RATE_LOW 0x1e /* PCM Sampling Rate Low Byte */
-#define SV_IREG_PCM_RATE_HIGH 0x1f /* PCM Sampling Rate High Byte */
-#define SV_IREG_SYNTH_RATE_LOW 0x20 /* Synthesizer Sampling Rate Low Byte */
-#define SV_IREG_SYNTH_RATE_HIGH 0x21 /* Synthesizer Sampling Rate High Byte */
-#define SV_IREG_ADC_CLOCK 0x22 /* ADC Clock Source Selection */
-#define SV_IREG_ADC_ALT_RATE 0x23 /* ADC Alternative Sampling Rate Selection */
-#define SV_IREG_ADC_PLL_M 0x24 /* ADC PLL M Register */
-#define SV_IREG_ADC_PLL_N 0x25 /* ADC PLL N Register */
-#define SV_IREG_SYNTH_PLL_M 0x26 /* Synthesizer PLL M Register */
-#define SV_IREG_SYNTH_PLL_N 0x27 /* Synthesizer PLL N Register */
-#define SV_IREG_MPU401 0x2a /* MPU-401 UART Operation */
-#define SV_IREG_DRIVE_CTRL 0x2b /* Drive Control */
-#define SV_IREG_SRS_SPACE 0x2c /* SRS Space Control */
-#define SV_IREG_SRS_CENTER 0x2d /* SRS Center Control */
-#define SV_IREG_WAVE_SOURCE 0x2e /* Wavetable Sample Source Select */
-#define SV_IREG_ANALOG_POWER 0x30 /* Analog Power Down Control */
-#define SV_IREG_DIGITAL_POWER 0x31 /* Digital Power Down Control */
-
-#define SV_IREG_ADC_PLL SV_IREG_ADC_PLL_M
-#define SV_IREG_SYNTH_PLL SV_IREG_SYNTH_PLL_M
-
-/*
- * DMA registers
- */
-
-#define SV_DMA_ADDR0 0x00
-#define SV_DMA_ADDR1 0x01
-#define SV_DMA_ADDR2 0x02
-#define SV_DMA_ADDR3 0x03
-#define SV_DMA_COUNT0 0x04
-#define SV_DMA_COUNT1 0x05
-#define SV_DMA_COUNT2 0x06
-#define SV_DMA_MODE 0x0b
-#define SV_DMA_RESET 0x0d
-#define SV_DMA_MASK 0x0f
-
-/*
- * Record sources
- */
-
-#define SV_RECSRC_RESERVED (0x00<<5)
-#define SV_RECSRC_CD (0x01<<5)
-#define SV_RECSRC_DAC (0x02<<5)
-#define SV_RECSRC_AUX2 (0x03<<5)
-#define SV_RECSRC_LINE (0x04<<5)
-#define SV_RECSRC_AUX1 (0x05<<5)
-#define SV_RECSRC_MIC (0x06<<5)
-#define SV_RECSRC_OUT (0x07<<5)
-
-/*
- * constants
- */
-
-#define SV_FULLRATE 48000
-#define SV_REFFREQUENCY 24576000
-#define SV_ADCMULT 512
-
-#define SV_MODE_PLAY 1
-#define SV_MODE_CAPTURE 2
-
-/*
-
- */
-
-struct sonicvibes {
- unsigned long dma1size;
- unsigned long dma2size;
- int irq;
-
- unsigned long sb_port;
- unsigned long enh_port;
- unsigned long synth_port;
- unsigned long midi_port;
- unsigned long game_port;
- unsigned int dmaa_port;
- struct resource *res_dmaa;
- unsigned int dmac_port;
- struct resource *res_dmac;
-
- unsigned char enable;
- unsigned char irqmask;
- unsigned char revision;
- unsigned char format;
- unsigned char srs_space;
- unsigned char srs_center;
- unsigned char mpu_switch;
- unsigned char wave_source;
-
- unsigned int mode;
-
- struct pci_dev *pci;
- struct snd_card *card;
- struct snd_pcm *pcm;
- struct snd_pcm_substream *playback_substream;
- struct snd_pcm_substream *capture_substream;
- struct snd_rawmidi *rmidi;
- struct snd_hwdep *fmsynth; /* S3FM */
-
- spinlock_t reg_lock;
-
- unsigned int p_dma_size;
- unsigned int c_dma_size;
-
- struct snd_kcontrol *master_mute;
- struct snd_kcontrol *master_volume;
-
-#ifdef SUPPORT_JOYSTICK
- struct gameport *gameport;
-#endif
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_sonic_ids) = {
- { PCI_VDEVICE(S3, 0xca00), 0, },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_sonic_ids);
-
-static struct snd_ratden sonicvibes_adc_clock = {
- .num_min = 4000 * 65536,
- .num_max = 48000UL * 65536,
- .num_step = 1,
- .den = 65536,
-};
-static struct snd_pcm_hw_constraint_ratdens snd_sonicvibes_hw_constraints_adc_clock = {
- .nrats = 1,
- .rats = &sonicvibes_adc_clock,
-};
-
-/*
- * common I/O routines
- */
-
-static inline void snd_sonicvibes_setdmaa(struct sonicvibes * sonic,
- unsigned int addr,
- unsigned int count)
-{
- count--;
- outl(addr, sonic->dmaa_port + SV_DMA_ADDR0);
- outl(count, sonic->dmaa_port + SV_DMA_COUNT0);
- outb(0x18, sonic->dmaa_port + SV_DMA_MODE);
-#if 0
- printk(KERN_DEBUG "program dmaa: addr = 0x%x, paddr = 0x%x\n",
- addr, inl(sonic->dmaa_port + SV_DMA_ADDR0));
-#endif
-}
-
-static inline void snd_sonicvibes_setdmac(struct sonicvibes * sonic,
- unsigned int addr,
- unsigned int count)
-{
- /* note: dmac is working in word mode!!! */
- count >>= 1;
- count--;
- outl(addr, sonic->dmac_port + SV_DMA_ADDR0);
- outl(count, sonic->dmac_port + SV_DMA_COUNT0);
- outb(0x14, sonic->dmac_port + SV_DMA_MODE);
-#if 0
- printk(KERN_DEBUG "program dmac: addr = 0x%x, paddr = 0x%x\n",
- addr, inl(sonic->dmac_port + SV_DMA_ADDR0));
-#endif
-}
-
-static inline unsigned int snd_sonicvibes_getdmaa(struct sonicvibes * sonic)
-{
- return (inl(sonic->dmaa_port + SV_DMA_COUNT0) & 0xffffff) + 1;
-}
-
-static inline unsigned int snd_sonicvibes_getdmac(struct sonicvibes * sonic)
-{
- /* note: dmac is working in word mode!!! */
- return ((inl(sonic->dmac_port + SV_DMA_COUNT0) & 0xffffff) + 1) << 1;
-}
-
-static void snd_sonicvibes_out1(struct sonicvibes * sonic,
- unsigned char reg,
- unsigned char value)
-{
- outb(reg, SV_REG(sonic, INDEX));
- udelay(10);
- outb(value, SV_REG(sonic, DATA));
- udelay(10);
-}
-
-static void snd_sonicvibes_out(struct sonicvibes * sonic,
- unsigned char reg,
- unsigned char value)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&sonic->reg_lock, flags);
- outb(reg, SV_REG(sonic, INDEX));
- udelay(10);
- outb(value, SV_REG(sonic, DATA));
- udelay(10);
- spin_unlock_irqrestore(&sonic->reg_lock, flags);
-}
-
-static unsigned char snd_sonicvibes_in1(struct sonicvibes * sonic, unsigned char reg)
-{
- unsigned char value;
-
- outb(reg, SV_REG(sonic, INDEX));
- udelay(10);
- value = inb(SV_REG(sonic, DATA));
- udelay(10);
- return value;
-}
-
-static unsigned char snd_sonicvibes_in(struct sonicvibes * sonic, unsigned char reg)
-{
- unsigned long flags;
- unsigned char value;
-
- spin_lock_irqsave(&sonic->reg_lock, flags);
- outb(reg, SV_REG(sonic, INDEX));
- udelay(10);
- value = inb(SV_REG(sonic, DATA));
- udelay(10);
- spin_unlock_irqrestore(&sonic->reg_lock, flags);
- return value;
-}
-
-#if 0
-static void snd_sonicvibes_debug(struct sonicvibes * sonic)
-{
- printk(KERN_DEBUG
- "SV REGS: INDEX = 0x%02x ", inb(SV_REG(sonic, INDEX)));
- printk(" STATUS = 0x%02x\n", inb(SV_REG(sonic, STATUS)));
- printk(KERN_DEBUG
- " 0x00: left input = 0x%02x ", snd_sonicvibes_in(sonic, 0x00));
- printk(" 0x20: synth rate low = 0x%02x\n", snd_sonicvibes_in(sonic, 0x20));
- printk(KERN_DEBUG
- " 0x01: right input = 0x%02x ", snd_sonicvibes_in(sonic, 0x01));
- printk(" 0x21: synth rate high = 0x%02x\n", snd_sonicvibes_in(sonic, 0x21));
- printk(KERN_DEBUG
- " 0x02: left AUX1 = 0x%02x ", snd_sonicvibes_in(sonic, 0x02));
- printk(" 0x22: ADC clock = 0x%02x\n", snd_sonicvibes_in(sonic, 0x22));
- printk(KERN_DEBUG
- " 0x03: right AUX1 = 0x%02x ", snd_sonicvibes_in(sonic, 0x03));
- printk(" 0x23: ADC alt rate = 0x%02x\n", snd_sonicvibes_in(sonic, 0x23));
- printk(KERN_DEBUG
- " 0x04: left CD = 0x%02x ", snd_sonicvibes_in(sonic, 0x04));
- printk(" 0x24: ADC pll M = 0x%02x\n", snd_sonicvibes_in(sonic, 0x24));
- printk(KERN_DEBUG
- " 0x05: right CD = 0x%02x ", snd_sonicvibes_in(sonic, 0x05));
- printk(" 0x25: ADC pll N = 0x%02x\n", snd_sonicvibes_in(sonic, 0x25));
- printk(KERN_DEBUG
- " 0x06: left line = 0x%02x ", snd_sonicvibes_in(sonic, 0x06));
- printk(" 0x26: Synth pll M = 0x%02x\n", snd_sonicvibes_in(sonic, 0x26));
- printk(KERN_DEBUG
- " 0x07: right line = 0x%02x ", snd_sonicvibes_in(sonic, 0x07));
- printk(" 0x27: Synth pll N = 0x%02x\n", snd_sonicvibes_in(sonic, 0x27));
- printk(KERN_DEBUG
- " 0x08: MIC = 0x%02x ", snd_sonicvibes_in(sonic, 0x08));
- printk(" 0x28: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x28));
- printk(KERN_DEBUG
- " 0x09: Game port = 0x%02x ", snd_sonicvibes_in(sonic, 0x09));
- printk(" 0x29: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x29));
- printk(KERN_DEBUG
- " 0x0a: left synth = 0x%02x ", snd_sonicvibes_in(sonic, 0x0a));
- printk(" 0x2a: MPU401 = 0x%02x\n", snd_sonicvibes_in(sonic, 0x2a));
- printk(KERN_DEBUG
- " 0x0b: right synth = 0x%02x ", snd_sonicvibes_in(sonic, 0x0b));
- printk(" 0x2b: drive ctrl = 0x%02x\n", snd_sonicvibes_in(sonic, 0x2b));
- printk(KERN_DEBUG
- " 0x0c: left AUX2 = 0x%02x ", snd_sonicvibes_in(sonic, 0x0c));
- printk(" 0x2c: SRS space = 0x%02x\n", snd_sonicvibes_in(sonic, 0x2c));
- printk(KERN_DEBUG
- " 0x0d: right AUX2 = 0x%02x ", snd_sonicvibes_in(sonic, 0x0d));
- printk(" 0x2d: SRS center = 0x%02x\n", snd_sonicvibes_in(sonic, 0x2d));
- printk(KERN_DEBUG
- " 0x0e: left analog = 0x%02x ", snd_sonicvibes_in(sonic, 0x0e));
- printk(" 0x2e: wave source = 0x%02x\n", snd_sonicvibes_in(sonic, 0x2e));
- printk(KERN_DEBUG
- " 0x0f: right analog = 0x%02x ", snd_sonicvibes_in(sonic, 0x0f));
- printk(" 0x2f: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x2f));
- printk(KERN_DEBUG
- " 0x10: left PCM = 0x%02x ", snd_sonicvibes_in(sonic, 0x10));
- printk(" 0x30: analog power = 0x%02x\n", snd_sonicvibes_in(sonic, 0x30));
- printk(KERN_DEBUG
- " 0x11: right PCM = 0x%02x ", snd_sonicvibes_in(sonic, 0x11));
- printk(" 0x31: analog power = 0x%02x\n", snd_sonicvibes_in(sonic, 0x31));
- printk(KERN_DEBUG
- " 0x12: DMA data format = 0x%02x ", snd_sonicvibes_in(sonic, 0x12));
- printk(" 0x32: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x32));
- printk(KERN_DEBUG
- " 0x13: P/C enable = 0x%02x ", snd_sonicvibes_in(sonic, 0x13));
- printk(" 0x33: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x33));
- printk(KERN_DEBUG
- " 0x14: U/D button = 0x%02x ", snd_sonicvibes_in(sonic, 0x14));
- printk(" 0x34: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x34));
- printk(KERN_DEBUG
- " 0x15: revision = 0x%02x ", snd_sonicvibes_in(sonic, 0x15));
- printk(" 0x35: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x35));
- printk(KERN_DEBUG
- " 0x16: ADC output ctrl = 0x%02x ", snd_sonicvibes_in(sonic, 0x16));
- printk(" 0x36: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x36));
- printk(KERN_DEBUG
- " 0x17: --- = 0x%02x ", snd_sonicvibes_in(sonic, 0x17));
- printk(" 0x37: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x37));
- printk(KERN_DEBUG
- " 0x18: DMA A upper cnt = 0x%02x ", snd_sonicvibes_in(sonic, 0x18));
- printk(" 0x38: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x38));
- printk(KERN_DEBUG
- " 0x19: DMA A lower cnt = 0x%02x ", snd_sonicvibes_in(sonic, 0x19));
- printk(" 0x39: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x39));
- printk(KERN_DEBUG
- " 0x1a: --- = 0x%02x ", snd_sonicvibes_in(sonic, 0x1a));
- printk(" 0x3a: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x3a));
- printk(KERN_DEBUG
- " 0x1b: --- = 0x%02x ", snd_sonicvibes_in(sonic, 0x1b));
- printk(" 0x3b: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x3b));
- printk(KERN_DEBUG
- " 0x1c: DMA C upper cnt = 0x%02x ", snd_sonicvibes_in(sonic, 0x1c));
- printk(" 0x3c: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x3c));
- printk(KERN_DEBUG
- " 0x1d: DMA C upper cnt = 0x%02x ", snd_sonicvibes_in(sonic, 0x1d));
- printk(" 0x3d: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x3d));
- printk(KERN_DEBUG
- " 0x1e: PCM rate low = 0x%02x ", snd_sonicvibes_in(sonic, 0x1e));
- printk(" 0x3e: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x3e));
- printk(KERN_DEBUG
- " 0x1f: PCM rate high = 0x%02x ", snd_sonicvibes_in(sonic, 0x1f));
- printk(" 0x3f: --- = 0x%02x\n", snd_sonicvibes_in(sonic, 0x3f));
-}
-
-#endif
-
-static void snd_sonicvibes_setfmt(struct sonicvibes * sonic,
- unsigned char mask,
- unsigned char value)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&sonic->reg_lock, flags);
- outb(SV_MCE | SV_IREG_DMA_DATA_FMT, SV_REG(sonic, INDEX));
- if (mask) {
- sonic->format = inb(SV_REG(sonic, DATA));
- udelay(10);
- }
- sonic->format = (sonic->format & mask) | value;
- outb(sonic->format, SV_REG(sonic, DATA));
- udelay(10);
- outb(0, SV_REG(sonic, INDEX));
- udelay(10);
- spin_unlock_irqrestore(&sonic->reg_lock, flags);
-}
-
-static void snd_sonicvibes_pll(unsigned int rate,
- unsigned int *res_r,
- unsigned int *res_m,
- unsigned int *res_n)
-{
- unsigned int r, m = 0, n = 0;
- unsigned int xm, xn, xr, xd, metric = ~0U;
-
- if (rate < 625000 / SV_ADCMULT)
- rate = 625000 / SV_ADCMULT;
- if (rate > 150000000 / SV_ADCMULT)
- rate = 150000000 / SV_ADCMULT;
- /* slight violation of specs, needed for continuous sampling rates */
- for (r = 0; rate < 75000000 / SV_ADCMULT; r += 0x20, rate <<= 1);
- for (xn = 3; xn < 33; xn++) /* 35 */
- for (xm = 3; xm < 257; xm++) {
- xr = ((SV_REFFREQUENCY / SV_ADCMULT) * xm) / xn;
- if (xr >= rate)
- xd = xr - rate;
- else
- xd = rate - xr;
- if (xd < metric) {
- metric = xd;
- m = xm - 2;
- n = xn - 2;
- }
- }
- *res_r = r;
- *res_m = m;
- *res_n = n;
-#if 0
- printk(KERN_DEBUG "metric = %i, xm = %i, xn = %i\n", metric, xm, xn);
- printk(KERN_DEBUG "pll: m = 0x%x, r = 0x%x, n = 0x%x\n", reg, m, r, n);
-#endif
-}
-
-static void snd_sonicvibes_setpll(struct sonicvibes * sonic,
- unsigned char reg,
- unsigned int rate)
-{
- unsigned long flags;
- unsigned int r, m, n;
-
- snd_sonicvibes_pll(rate, &r, &m, &n);
- if (sonic != NULL) {
- spin_lock_irqsave(&sonic->reg_lock, flags);
- snd_sonicvibes_out1(sonic, reg, m);
- snd_sonicvibes_out1(sonic, reg + 1, r | n);
- spin_unlock_irqrestore(&sonic->reg_lock, flags);
- }
-}
-
-static void snd_sonicvibes_set_adc_rate(struct sonicvibes * sonic, unsigned int rate)
-{
- unsigned long flags;
- unsigned int div;
- unsigned char clock;
-
- div = 48000 / rate;
- if (div > 8)
- div = 8;
- if ((48000 / div) == rate) { /* use the alternate clock */
- clock = 0x10;
- } else { /* use the PLL source */
- clock = 0x00;
- snd_sonicvibes_setpll(sonic, SV_IREG_ADC_PLL, rate);
- }
- spin_lock_irqsave(&sonic->reg_lock, flags);
- snd_sonicvibes_out1(sonic, SV_IREG_ADC_ALT_RATE, (div - 1) << 4);
- snd_sonicvibes_out1(sonic, SV_IREG_ADC_CLOCK, clock);
- spin_unlock_irqrestore(&sonic->reg_lock, flags);
-}
-
-static int snd_sonicvibes_hw_constraint_dac_rate(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- unsigned int rate, div, r, m, n;
-
- if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min ==
- hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max) {
- rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min;
- div = 48000 / rate;
- if (div > 8)
- div = 8;
- if ((48000 / div) == rate) {
- params->rate_num = rate;
- params->rate_den = 1;
- } else {
- snd_sonicvibes_pll(rate, &r, &m, &n);
- snd_BUG_ON(SV_REFFREQUENCY % 16);
- snd_BUG_ON(SV_ADCMULT % 512);
- params->rate_num = (SV_REFFREQUENCY/16) * (n+2) * r;
- params->rate_den = (SV_ADCMULT/512) * (m+2);
- }
- }
- return 0;
-}
-
-static void snd_sonicvibes_set_dac_rate(struct sonicvibes * sonic, unsigned int rate)
-{
- unsigned int div;
- unsigned long flags;
-
- div = (rate * 65536 + SV_FULLRATE / 2) / SV_FULLRATE;
- if (div > 65535)
- div = 65535;
- spin_lock_irqsave(&sonic->reg_lock, flags);
- snd_sonicvibes_out1(sonic, SV_IREG_PCM_RATE_HIGH, div >> 8);
- snd_sonicvibes_out1(sonic, SV_IREG_PCM_RATE_LOW, div);
- spin_unlock_irqrestore(&sonic->reg_lock, flags);
-}
-
-static int snd_sonicvibes_trigger(struct sonicvibes * sonic, int what, int cmd)
-{
- int result = 0;
-
- spin_lock(&sonic->reg_lock);
- if (cmd == SNDRV_PCM_TRIGGER_START) {
- if (!(sonic->enable & what)) {
- sonic->enable |= what;
- snd_sonicvibes_out1(sonic, SV_IREG_PC_ENABLE, sonic->enable);
- }
- } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
- if (sonic->enable & what) {
- sonic->enable &= ~what;
- snd_sonicvibes_out1(sonic, SV_IREG_PC_ENABLE, sonic->enable);
- }
- } else {
- result = -EINVAL;
- }
- spin_unlock(&sonic->reg_lock);
- return result;
-}
-
-static irqreturn_t snd_sonicvibes_interrupt(int irq, void *dev_id)
-{
- struct sonicvibes *sonic = dev_id;
- unsigned char status;
-
- status = inb(SV_REG(sonic, STATUS));
- if (!(status & (SV_DMAA_IRQ | SV_DMAC_IRQ | SV_MIDI_IRQ)))
- return IRQ_NONE;
- if (status == 0xff) { /* failure */
- outb(sonic->irqmask = ~0, SV_REG(sonic, IRQMASK));
- snd_printk(KERN_ERR "IRQ failure - interrupts disabled!!\n");
- return IRQ_HANDLED;
- }
- if (sonic->pcm) {
- if (status & SV_DMAA_IRQ)
- snd_pcm_period_elapsed(sonic->playback_substream);
- if (status & SV_DMAC_IRQ)
- snd_pcm_period_elapsed(sonic->capture_substream);
- }
- if (sonic->rmidi) {
- if (status & SV_MIDI_IRQ)
- snd_mpu401_uart_interrupt(irq, sonic->rmidi->private_data);
- }
- if (status & SV_UD_IRQ) {
- unsigned char udreg;
- int vol, oleft, oright, mleft, mright;
-
- spin_lock(&sonic->reg_lock);
- udreg = snd_sonicvibes_in1(sonic, SV_IREG_UD_BUTTON);
- vol = udreg & 0x3f;
- if (!(udreg & 0x40))
- vol = -vol;
- oleft = mleft = snd_sonicvibes_in1(sonic, SV_IREG_LEFT_ANALOG);
- oright = mright = snd_sonicvibes_in1(sonic, SV_IREG_RIGHT_ANALOG);
- oleft &= 0x1f;
- oright &= 0x1f;
- oleft += vol;
- if (oleft < 0)
- oleft = 0;
- if (oleft > 0x1f)
- oleft = 0x1f;
- oright += vol;
- if (oright < 0)
- oright = 0;
- if (oright > 0x1f)
- oright = 0x1f;
- if (udreg & 0x80) {
- mleft ^= 0x80;
- mright ^= 0x80;
- }
- oleft |= mleft & 0x80;
- oright |= mright & 0x80;
- snd_sonicvibes_out1(sonic, SV_IREG_LEFT_ANALOG, oleft);
- snd_sonicvibes_out1(sonic, SV_IREG_RIGHT_ANALOG, oright);
- spin_unlock(&sonic->reg_lock);
- snd_ctl_notify(sonic->card, SNDRV_CTL_EVENT_MASK_VALUE, &sonic->master_mute->id);
- snd_ctl_notify(sonic->card, SNDRV_CTL_EVENT_MASK_VALUE, &sonic->master_volume->id);
- }
- return IRQ_HANDLED;
-}
-
-/*
- * PCM part
- */
-
-static int snd_sonicvibes_playback_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct sonicvibes *sonic = snd_pcm_substream_chip(substream);
- return snd_sonicvibes_trigger(sonic, 1, cmd);
-}
-
-static int snd_sonicvibes_capture_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct sonicvibes *sonic = snd_pcm_substream_chip(substream);
- return snd_sonicvibes_trigger(sonic, 2, cmd);
-}
-
-static int snd_sonicvibes_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static int snd_sonicvibes_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_sonicvibes_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct sonicvibes *sonic = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned char fmt = 0;
- unsigned int size = snd_pcm_lib_buffer_bytes(substream);
- unsigned int count = snd_pcm_lib_period_bytes(substream);
-
- sonic->p_dma_size = size;
- count--;
- if (runtime->channels > 1)
- fmt |= 1;
- if (snd_pcm_format_width(runtime->format) == 16)
- fmt |= 2;
- snd_sonicvibes_setfmt(sonic, ~3, fmt);
- snd_sonicvibes_set_dac_rate(sonic, runtime->rate);
- spin_lock_irq(&sonic->reg_lock);
- snd_sonicvibes_setdmaa(sonic, runtime->dma_addr, size);
- snd_sonicvibes_out1(sonic, SV_IREG_DMA_A_UPPER, count >> 8);
- snd_sonicvibes_out1(sonic, SV_IREG_DMA_A_LOWER, count);
- spin_unlock_irq(&sonic->reg_lock);
- return 0;
-}
-
-static int snd_sonicvibes_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct sonicvibes *sonic = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned char fmt = 0;
- unsigned int size = snd_pcm_lib_buffer_bytes(substream);
- unsigned int count = snd_pcm_lib_period_bytes(substream);
-
- sonic->c_dma_size = size;
- count >>= 1;
- count--;
- if (runtime->channels > 1)
- fmt |= 0x10;
- if (snd_pcm_format_width(runtime->format) == 16)
- fmt |= 0x20;
- snd_sonicvibes_setfmt(sonic, ~0x30, fmt);
- snd_sonicvibes_set_adc_rate(sonic, runtime->rate);
- spin_lock_irq(&sonic->reg_lock);
- snd_sonicvibes_setdmac(sonic, runtime->dma_addr, size);
- snd_sonicvibes_out1(sonic, SV_IREG_DMA_C_UPPER, count >> 8);
- snd_sonicvibes_out1(sonic, SV_IREG_DMA_C_LOWER, count);
- spin_unlock_irq(&sonic->reg_lock);
- return 0;
-}
-
-static snd_pcm_uframes_t snd_sonicvibes_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct sonicvibes *sonic = snd_pcm_substream_chip(substream);
- size_t ptr;
-
- if (!(sonic->enable & 1))
- return 0;
- ptr = sonic->p_dma_size - snd_sonicvibes_getdmaa(sonic);
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-static snd_pcm_uframes_t snd_sonicvibes_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct sonicvibes *sonic = snd_pcm_substream_chip(substream);
- size_t ptr;
- if (!(sonic->enable & 2))
- return 0;
- ptr = sonic->c_dma_size - snd_sonicvibes_getdmac(sonic);
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-static struct snd_pcm_hardware snd_sonicvibes_playback =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 32,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_sonicvibes_capture =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 32,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static int snd_sonicvibes_playback_open(struct snd_pcm_substream *substream)
-{
- struct sonicvibes *sonic = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- sonic->mode |= SV_MODE_PLAY;
- sonic->playback_substream = substream;
- runtime->hw = snd_sonicvibes_playback;
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, snd_sonicvibes_hw_constraint_dac_rate, NULL, SNDRV_PCM_HW_PARAM_RATE, -1);
- return 0;
-}
-
-static int snd_sonicvibes_capture_open(struct snd_pcm_substream *substream)
-{
- struct sonicvibes *sonic = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- sonic->mode |= SV_MODE_CAPTURE;
- sonic->capture_substream = substream;
- runtime->hw = snd_sonicvibes_capture;
- snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &snd_sonicvibes_hw_constraints_adc_clock);
- return 0;
-}
-
-static int snd_sonicvibes_playback_close(struct snd_pcm_substream *substream)
-{
- struct sonicvibes *sonic = snd_pcm_substream_chip(substream);
-
- sonic->playback_substream = NULL;
- sonic->mode &= ~SV_MODE_PLAY;
- return 0;
-}
-
-static int snd_sonicvibes_capture_close(struct snd_pcm_substream *substream)
-{
- struct sonicvibes *sonic = snd_pcm_substream_chip(substream);
-
- sonic->capture_substream = NULL;
- sonic->mode &= ~SV_MODE_CAPTURE;
- return 0;
-}
-
-static struct snd_pcm_ops snd_sonicvibes_playback_ops = {
- .open = snd_sonicvibes_playback_open,
- .close = snd_sonicvibes_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_sonicvibes_hw_params,
- .hw_free = snd_sonicvibes_hw_free,
- .prepare = snd_sonicvibes_playback_prepare,
- .trigger = snd_sonicvibes_playback_trigger,
- .pointer = snd_sonicvibes_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_sonicvibes_capture_ops = {
- .open = snd_sonicvibes_capture_open,
- .close = snd_sonicvibes_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_sonicvibes_hw_params,
- .hw_free = snd_sonicvibes_hw_free,
- .prepare = snd_sonicvibes_capture_prepare,
- .trigger = snd_sonicvibes_capture_trigger,
- .pointer = snd_sonicvibes_capture_pointer,
-};
-
-static int __devinit snd_sonicvibes_pcm(struct sonicvibes * sonic, int device, struct snd_pcm ** rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if ((err = snd_pcm_new(sonic->card, "s3_86c617", device, 1, 1, &pcm)) < 0)
- return err;
- if (snd_BUG_ON(!pcm))
- return -EINVAL;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sonicvibes_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sonicvibes_capture_ops);
-
- pcm->private_data = sonic;
- pcm->info_flags = 0;
- strcpy(pcm->name, "S3 SonicVibes");
- sonic->pcm = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(sonic->pci), 64*1024, 128*1024);
-
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-/*
- * Mixer part
- */
-
-#define SONICVIBES_MUX(xname, xindex) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_sonicvibes_info_mux, \
- .get = snd_sonicvibes_get_mux, .put = snd_sonicvibes_put_mux }
-
-static int snd_sonicvibes_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[7] = {
- "CD", "PCM", "Aux1", "Line", "Aux0", "Mic", "Mix"
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 2;
- uinfo->value.enumerated.items = 7;
- if (uinfo->value.enumerated.item >= 7)
- uinfo->value.enumerated.item = 6;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_sonicvibes_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&sonic->reg_lock);
- ucontrol->value.enumerated.item[0] = ((snd_sonicvibes_in1(sonic, SV_IREG_LEFT_ADC) & SV_RECSRC_OUT) >> 5) - 1;
- ucontrol->value.enumerated.item[1] = ((snd_sonicvibes_in1(sonic, SV_IREG_RIGHT_ADC) & SV_RECSRC_OUT) >> 5) - 1;
- spin_unlock_irq(&sonic->reg_lock);
- return 0;
-}
-
-static int snd_sonicvibes_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol);
- unsigned short left, right, oval1, oval2;
- int change;
-
- if (ucontrol->value.enumerated.item[0] >= 7 ||
- ucontrol->value.enumerated.item[1] >= 7)
- return -EINVAL;
- left = (ucontrol->value.enumerated.item[0] + 1) << 5;
- right = (ucontrol->value.enumerated.item[1] + 1) << 5;
- spin_lock_irq(&sonic->reg_lock);
- oval1 = snd_sonicvibes_in1(sonic, SV_IREG_LEFT_ADC);
- oval2 = snd_sonicvibes_in1(sonic, SV_IREG_RIGHT_ADC);
- left = (oval1 & ~SV_RECSRC_OUT) | left;
- right = (oval2 & ~SV_RECSRC_OUT) | right;
- change = left != oval1 || right != oval2;
- snd_sonicvibes_out1(sonic, SV_IREG_LEFT_ADC, left);
- snd_sonicvibes_out1(sonic, SV_IREG_RIGHT_ADC, right);
- spin_unlock_irq(&sonic->reg_lock);
- return change;
-}
-
-#define SONICVIBES_SINGLE(xname, xindex, reg, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_sonicvibes_info_single, \
- .get = snd_sonicvibes_get_single, .put = snd_sonicvibes_put_single, \
- .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
-
-static int snd_sonicvibes_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 16) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_sonicvibes_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
-
- spin_lock_irq(&sonic->reg_lock);
- ucontrol->value.integer.value[0] = (snd_sonicvibes_in1(sonic, reg)>> shift) & mask;
- spin_unlock_irq(&sonic->reg_lock);
- if (invert)
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- return 0;
-}
-
-static int snd_sonicvibes_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
- int change;
- unsigned short val, oval;
-
- val = (ucontrol->value.integer.value[0] & mask);
- if (invert)
- val = mask - val;
- val <<= shift;
- spin_lock_irq(&sonic->reg_lock);
- oval = snd_sonicvibes_in1(sonic, reg);
- val = (oval & ~(mask << shift)) | val;
- change = val != oval;
- snd_sonicvibes_out1(sonic, reg, val);
- spin_unlock_irq(&sonic->reg_lock);
- return change;
-}
-
-#define SONICVIBES_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_sonicvibes_info_double, \
- .get = snd_sonicvibes_get_double, .put = snd_sonicvibes_put_double, \
- .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
-
-static int snd_sonicvibes_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 24) & 0xff;
-
- uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_sonicvibes_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol);
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int shift_left = (kcontrol->private_value >> 16) & 0x07;
- int shift_right = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
-
- spin_lock_irq(&sonic->reg_lock);
- ucontrol->value.integer.value[0] = (snd_sonicvibes_in1(sonic, left_reg) >> shift_left) & mask;
- ucontrol->value.integer.value[1] = (snd_sonicvibes_in1(sonic, right_reg) >> shift_right) & mask;
- spin_unlock_irq(&sonic->reg_lock);
- if (invert) {
- ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
- ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
- }
- return 0;
-}
-
-static int snd_sonicvibes_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol);
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int shift_left = (kcontrol->private_value >> 16) & 0x07;
- int shift_right = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
- int change;
- unsigned short val1, val2, oval1, oval2;
-
- val1 = ucontrol->value.integer.value[0] & mask;
- val2 = ucontrol->value.integer.value[1] & mask;
- if (invert) {
- val1 = mask - val1;
- val2 = mask - val2;
- }
- val1 <<= shift_left;
- val2 <<= shift_right;
- spin_lock_irq(&sonic->reg_lock);
- oval1 = snd_sonicvibes_in1(sonic, left_reg);
- oval2 = snd_sonicvibes_in1(sonic, right_reg);
- val1 = (oval1 & ~(mask << shift_left)) | val1;
- val2 = (oval2 & ~(mask << shift_right)) | val2;
- change = val1 != oval1 || val2 != oval2;
- snd_sonicvibes_out1(sonic, left_reg, val1);
- snd_sonicvibes_out1(sonic, right_reg, val2);
- spin_unlock_irq(&sonic->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_sonicvibes_controls[] __devinitdata = {
-SONICVIBES_DOUBLE("Capture Volume", 0, SV_IREG_LEFT_ADC, SV_IREG_RIGHT_ADC, 0, 0, 15, 0),
-SONICVIBES_DOUBLE("Aux Playback Switch", 0, SV_IREG_LEFT_AUX1, SV_IREG_RIGHT_AUX1, 7, 7, 1, 1),
-SONICVIBES_DOUBLE("Aux Playback Volume", 0, SV_IREG_LEFT_AUX1, SV_IREG_RIGHT_AUX1, 0, 0, 31, 1),
-SONICVIBES_DOUBLE("CD Playback Switch", 0, SV_IREG_LEFT_CD, SV_IREG_RIGHT_CD, 7, 7, 1, 1),
-SONICVIBES_DOUBLE("CD Playback Volume", 0, SV_IREG_LEFT_CD, SV_IREG_RIGHT_CD, 0, 0, 31, 1),
-SONICVIBES_DOUBLE("Line Playback Switch", 0, SV_IREG_LEFT_LINE, SV_IREG_RIGHT_LINE, 7, 7, 1, 1),
-SONICVIBES_DOUBLE("Line Playback Volume", 0, SV_IREG_LEFT_LINE, SV_IREG_RIGHT_LINE, 0, 0, 31, 1),
-SONICVIBES_SINGLE("Mic Playback Switch", 0, SV_IREG_MIC, 7, 1, 1),
-SONICVIBES_SINGLE("Mic Playback Volume", 0, SV_IREG_MIC, 0, 15, 1),
-SONICVIBES_SINGLE("Mic Boost", 0, SV_IREG_LEFT_ADC, 4, 1, 0),
-SONICVIBES_DOUBLE("Synth Playback Switch", 0, SV_IREG_LEFT_SYNTH, SV_IREG_RIGHT_SYNTH, 7, 7, 1, 1),
-SONICVIBES_DOUBLE("Synth Playback Volume", 0, SV_IREG_LEFT_SYNTH, SV_IREG_RIGHT_SYNTH, 0, 0, 31, 1),
-SONICVIBES_DOUBLE("Aux Playback Switch", 1, SV_IREG_LEFT_AUX2, SV_IREG_RIGHT_AUX2, 7, 7, 1, 1),
-SONICVIBES_DOUBLE("Aux Playback Volume", 1, SV_IREG_LEFT_AUX2, SV_IREG_RIGHT_AUX2, 0, 0, 31, 1),
-SONICVIBES_DOUBLE("Master Playback Switch", 0, SV_IREG_LEFT_ANALOG, SV_IREG_RIGHT_ANALOG, 7, 7, 1, 1),
-SONICVIBES_DOUBLE("Master Playback Volume", 0, SV_IREG_LEFT_ANALOG, SV_IREG_RIGHT_ANALOG, 0, 0, 31, 1),
-SONICVIBES_DOUBLE("PCM Playback Switch", 0, SV_IREG_LEFT_PCM, SV_IREG_RIGHT_PCM, 7, 7, 1, 1),
-SONICVIBES_DOUBLE("PCM Playback Volume", 0, SV_IREG_LEFT_PCM, SV_IREG_RIGHT_PCM, 0, 0, 63, 1),
-SONICVIBES_SINGLE("Loopback Capture Switch", 0, SV_IREG_ADC_OUTPUT_CTRL, 0, 1, 0),
-SONICVIBES_SINGLE("Loopback Capture Volume", 0, SV_IREG_ADC_OUTPUT_CTRL, 2, 63, 1),
-SONICVIBES_MUX("Capture Source", 0)
-};
-
-static void snd_sonicvibes_master_free(struct snd_kcontrol *kcontrol)
-{
- struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol);
- sonic->master_mute = NULL;
- sonic->master_volume = NULL;
-}
-
-static int __devinit snd_sonicvibes_mixer(struct sonicvibes * sonic)
-{
- struct snd_card *card;
- struct snd_kcontrol *kctl;
- unsigned int idx;
- int err;
-
- if (snd_BUG_ON(!sonic || !sonic->card))
- return -EINVAL;
- card = sonic->card;
- strcpy(card->mixername, "S3 SonicVibes");
-
- for (idx = 0; idx < ARRAY_SIZE(snd_sonicvibes_controls); idx++) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_sonicvibes_controls[idx], sonic))) < 0)
- return err;
- switch (idx) {
- case 0:
- case 1: kctl->private_free = snd_sonicvibes_master_free; break;
- }
- }
- return 0;
-}
-
-/*
-
- */
-
-static void snd_sonicvibes_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct sonicvibes *sonic = entry->private_data;
- unsigned char tmp;
-
- tmp = sonic->srs_space & 0x0f;
- snd_iprintf(buffer, "SRS 3D : %s\n",
- sonic->srs_space & 0x80 ? "off" : "on");
- snd_iprintf(buffer, "SRS Space : %s\n",
- tmp == 0x00 ? "100%" :
- tmp == 0x01 ? "75%" :
- tmp == 0x02 ? "50%" :
- tmp == 0x03 ? "25%" : "0%");
- tmp = sonic->srs_center & 0x0f;
- snd_iprintf(buffer, "SRS Center : %s\n",
- tmp == 0x00 ? "100%" :
- tmp == 0x01 ? "75%" :
- tmp == 0x02 ? "50%" :
- tmp == 0x03 ? "25%" : "0%");
- tmp = sonic->wave_source & 0x03;
- snd_iprintf(buffer, "WaveTable Source : %s\n",
- tmp == 0x00 ? "on-board ROM" :
- tmp == 0x01 ? "PCI bus" : "on-board ROM + PCI bus");
- tmp = sonic->mpu_switch;
- snd_iprintf(buffer, "Onboard synth : %s\n", tmp & 0x01 ? "on" : "off");
- snd_iprintf(buffer, "Ext. Rx to synth : %s\n", tmp & 0x02 ? "on" : "off");
- snd_iprintf(buffer, "MIDI to ext. Tx : %s\n", tmp & 0x04 ? "on" : "off");
-}
-
-static void __devinit snd_sonicvibes_proc_init(struct sonicvibes * sonic)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(sonic->card, "sonicvibes", &entry))
- snd_info_set_text_ops(entry, sonic, snd_sonicvibes_proc_read);
-}
-
-/*
-
- */
-
-#ifdef SUPPORT_JOYSTICK
-static struct snd_kcontrol_new snd_sonicvibes_game_control __devinitdata =
-SONICVIBES_SINGLE("Joystick Speed", 0, SV_IREG_GAME_PORT, 1, 15, 0);
-
-static int __devinit snd_sonicvibes_create_gameport(struct sonicvibes *sonic)
-{
- struct gameport *gp;
-
- sonic->gameport = gp = gameport_allocate_port();
- if (!gp) {
- printk(KERN_ERR "sonicvibes: cannot allocate memory for gameport\n");
- return -ENOMEM;
- }
-
- gameport_set_name(gp, "SonicVibes Gameport");
- gameport_set_phys(gp, "pci%s/gameport0", pci_name(sonic->pci));
- gameport_set_dev_parent(gp, &sonic->pci->dev);
- gp->io = sonic->game_port;
-
- gameport_register_port(gp);
-
- snd_ctl_add(sonic->card, snd_ctl_new1(&snd_sonicvibes_game_control, sonic));
-
- return 0;
-}
-
-static void snd_sonicvibes_free_gameport(struct sonicvibes *sonic)
-{
- if (sonic->gameport) {
- gameport_unregister_port(sonic->gameport);
- sonic->gameport = NULL;
- }
-}
-#else
-static inline int snd_sonicvibes_create_gameport(struct sonicvibes *sonic) { return -ENOSYS; }
-static inline void snd_sonicvibes_free_gameport(struct sonicvibes *sonic) { }
-#endif
-
-static int snd_sonicvibes_free(struct sonicvibes *sonic)
-{
- snd_sonicvibes_free_gameport(sonic);
- pci_write_config_dword(sonic->pci, 0x40, sonic->dmaa_port);
- pci_write_config_dword(sonic->pci, 0x48, sonic->dmac_port);
- if (sonic->irq >= 0)
- free_irq(sonic->irq, sonic);
- release_and_free_resource(sonic->res_dmaa);
- release_and_free_resource(sonic->res_dmac);
- pci_release_regions(sonic->pci);
- pci_disable_device(sonic->pci);
- kfree(sonic);
- return 0;
-}
-
-static int snd_sonicvibes_dev_free(struct snd_device *device)
-{
- struct sonicvibes *sonic = device->device_data;
- return snd_sonicvibes_free(sonic);
-}
-
-static int __devinit snd_sonicvibes_create(struct snd_card *card,
- struct pci_dev *pci,
- int reverb,
- int mge,
- struct sonicvibes ** rsonic)
-{
- struct sonicvibes *sonic;
- unsigned int dmaa, dmac;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_sonicvibes_dev_free,
- };
-
- *rsonic = NULL;
- /* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
- return err;
- /* check, if we can restrict PCI DMA transfers to 24 bits */
- if (pci_set_dma_mask(pci, DMA_BIT_MASK(24)) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(24)) < 0) {
- snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
- pci_disable_device(pci);
- return -ENXIO;
- }
-
- sonic = kzalloc(sizeof(*sonic), GFP_KERNEL);
- if (sonic == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
- spin_lock_init(&sonic->reg_lock);
- sonic->card = card;
- sonic->pci = pci;
- sonic->irq = -1;
-
- if ((err = pci_request_regions(pci, "S3 SonicVibes")) < 0) {
- kfree(sonic);
- pci_disable_device(pci);
- return err;
- }
-
- sonic->sb_port = pci_resource_start(pci, 0);
- sonic->enh_port = pci_resource_start(pci, 1);
- sonic->synth_port = pci_resource_start(pci, 2);
- sonic->midi_port = pci_resource_start(pci, 3);
- sonic->game_port = pci_resource_start(pci, 4);
-
- if (request_irq(pci->irq, snd_sonicvibes_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, sonic)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_sonicvibes_free(sonic);
- return -EBUSY;
- }
- sonic->irq = pci->irq;
-
- pci_read_config_dword(pci, 0x40, &dmaa);
- pci_read_config_dword(pci, 0x48, &dmac);
- dmaio &= ~0x0f;
- dmaa &= ~0x0f;
- dmac &= ~0x0f;
- if (!dmaa) {
- dmaa = dmaio;
- dmaio += 0x10;
- snd_printk(KERN_INFO "BIOS did not allocate DDMA channel A i/o, allocated at 0x%x\n", dmaa);
- }
- if (!dmac) {
- dmac = dmaio;
- dmaio += 0x10;
- snd_printk(KERN_INFO "BIOS did not allocate DDMA channel C i/o, allocated at 0x%x\n", dmac);
- }
- pci_write_config_dword(pci, 0x40, dmaa);
- pci_write_config_dword(pci, 0x48, dmac);
-
- if ((sonic->res_dmaa = request_region(dmaa, 0x10, "S3 SonicVibes DDMA-A")) == NULL) {
- snd_sonicvibes_free(sonic);
- snd_printk(KERN_ERR "unable to grab DDMA-A port at 0x%x-0x%x\n", dmaa, dmaa + 0x10 - 1);
- return -EBUSY;
- }
- if ((sonic->res_dmac = request_region(dmac, 0x10, "S3 SonicVibes DDMA-C")) == NULL) {
- snd_sonicvibes_free(sonic);
- snd_printk(KERN_ERR "unable to grab DDMA-C port at 0x%x-0x%x\n", dmac, dmac + 0x10 - 1);
- return -EBUSY;
- }
-
- pci_read_config_dword(pci, 0x40, &sonic->dmaa_port);
- pci_read_config_dword(pci, 0x48, &sonic->dmac_port);
- sonic->dmaa_port &= ~0x0f;
- sonic->dmac_port &= ~0x0f;
- pci_write_config_dword(pci, 0x40, sonic->dmaa_port | 9); /* enable + enhanced */
- pci_write_config_dword(pci, 0x48, sonic->dmac_port | 9); /* enable */
- /* ok.. initialize S3 SonicVibes chip */
- outb(SV_RESET, SV_REG(sonic, CONTROL)); /* reset chip */
- udelay(100);
- outb(0, SV_REG(sonic, CONTROL)); /* release reset */
- udelay(100);
- outb(SV_ENHANCED | SV_INTA | (reverb ? SV_REVERB : 0), SV_REG(sonic, CONTROL));
- inb(SV_REG(sonic, STATUS)); /* clear IRQs */
-#if 1
- snd_sonicvibes_out(sonic, SV_IREG_DRIVE_CTRL, 0); /* drive current 16mA */
-#else
- snd_sonicvibes_out(sonic, SV_IREG_DRIVE_CTRL, 0x40); /* drive current 8mA */
-#endif
- snd_sonicvibes_out(sonic, SV_IREG_PC_ENABLE, sonic->enable = 0); /* disable playback & capture */
- outb(sonic->irqmask = ~(SV_DMAA_MASK | SV_DMAC_MASK | SV_UD_MASK), SV_REG(sonic, IRQMASK));
- inb(SV_REG(sonic, STATUS)); /* clear IRQs */
- snd_sonicvibes_out(sonic, SV_IREG_ADC_CLOCK, 0); /* use PLL as clock source */
- snd_sonicvibes_out(sonic, SV_IREG_ANALOG_POWER, 0); /* power up analog parts */
- snd_sonicvibes_out(sonic, SV_IREG_DIGITAL_POWER, 0); /* power up digital parts */
- snd_sonicvibes_setpll(sonic, SV_IREG_ADC_PLL, 8000);
- snd_sonicvibes_out(sonic, SV_IREG_SRS_SPACE, sonic->srs_space = 0x80); /* SRS space off */
- snd_sonicvibes_out(sonic, SV_IREG_SRS_CENTER, sonic->srs_center = 0x00);/* SRS center off */
- snd_sonicvibes_out(sonic, SV_IREG_MPU401, sonic->mpu_switch = 0x05); /* MPU-401 switch */
- snd_sonicvibes_out(sonic, SV_IREG_WAVE_SOURCE, sonic->wave_source = 0x00); /* onboard ROM */
- snd_sonicvibes_out(sonic, SV_IREG_PCM_RATE_LOW, (8000 * 65536 / SV_FULLRATE) & 0xff);
- snd_sonicvibes_out(sonic, SV_IREG_PCM_RATE_HIGH, ((8000 * 65536 / SV_FULLRATE) >> 8) & 0xff);
- snd_sonicvibes_out(sonic, SV_IREG_LEFT_ADC, mge ? 0xd0 : 0xc0);
- snd_sonicvibes_out(sonic, SV_IREG_RIGHT_ADC, 0xc0);
- snd_sonicvibes_out(sonic, SV_IREG_LEFT_AUX1, 0x9f);
- snd_sonicvibes_out(sonic, SV_IREG_RIGHT_AUX1, 0x9f);
- snd_sonicvibes_out(sonic, SV_IREG_LEFT_CD, 0x9f);
- snd_sonicvibes_out(sonic, SV_IREG_RIGHT_CD, 0x9f);
- snd_sonicvibes_out(sonic, SV_IREG_LEFT_LINE, 0x9f);
- snd_sonicvibes_out(sonic, SV_IREG_RIGHT_LINE, 0x9f);
- snd_sonicvibes_out(sonic, SV_IREG_MIC, 0x8f);
- snd_sonicvibes_out(sonic, SV_IREG_LEFT_SYNTH, 0x9f);
- snd_sonicvibes_out(sonic, SV_IREG_RIGHT_SYNTH, 0x9f);
- snd_sonicvibes_out(sonic, SV_IREG_LEFT_AUX2, 0x9f);
- snd_sonicvibes_out(sonic, SV_IREG_RIGHT_AUX2, 0x9f);
- snd_sonicvibes_out(sonic, SV_IREG_LEFT_ANALOG, 0x9f);
- snd_sonicvibes_out(sonic, SV_IREG_RIGHT_ANALOG, 0x9f);
- snd_sonicvibes_out(sonic, SV_IREG_LEFT_PCM, 0xbf);
- snd_sonicvibes_out(sonic, SV_IREG_RIGHT_PCM, 0xbf);
- snd_sonicvibes_out(sonic, SV_IREG_ADC_OUTPUT_CTRL, 0xfc);
-#if 0
- snd_sonicvibes_debug(sonic);
-#endif
- sonic->revision = snd_sonicvibes_in(sonic, SV_IREG_REVISION);
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, sonic, &ops)) < 0) {
- snd_sonicvibes_free(sonic);
- return err;
- }
-
- snd_sonicvibes_proc_init(sonic);
-
- snd_card_set_dev(card, &pci->dev);
-
- *rsonic = sonic;
- return 0;
-}
-
-/*
- * MIDI section
- */
-
-static struct snd_kcontrol_new snd_sonicvibes_midi_controls[] __devinitdata = {
-SONICVIBES_SINGLE("SonicVibes Wave Source RAM", 0, SV_IREG_WAVE_SOURCE, 0, 1, 0),
-SONICVIBES_SINGLE("SonicVibes Wave Source RAM+ROM", 0, SV_IREG_WAVE_SOURCE, 1, 1, 0),
-SONICVIBES_SINGLE("SonicVibes Onboard Synth", 0, SV_IREG_MPU401, 0, 1, 0),
-SONICVIBES_SINGLE("SonicVibes External Rx to Synth", 0, SV_IREG_MPU401, 1, 1, 0),
-SONICVIBES_SINGLE("SonicVibes External Tx", 0, SV_IREG_MPU401, 2, 1, 0)
-};
-
-static int snd_sonicvibes_midi_input_open(struct snd_mpu401 * mpu)
-{
- struct sonicvibes *sonic = mpu->private_data;
- outb(sonic->irqmask &= ~SV_MIDI_MASK, SV_REG(sonic, IRQMASK));
- return 0;
-}
-
-static void snd_sonicvibes_midi_input_close(struct snd_mpu401 * mpu)
-{
- struct sonicvibes *sonic = mpu->private_data;
- outb(sonic->irqmask |= SV_MIDI_MASK, SV_REG(sonic, IRQMASK));
-}
-
-static int __devinit snd_sonicvibes_midi(struct sonicvibes * sonic,
- struct snd_rawmidi *rmidi)
-{
- struct snd_mpu401 * mpu = rmidi->private_data;
- struct snd_card *card = sonic->card;
- struct snd_rawmidi_str *dir;
- unsigned int idx;
- int err;
-
- mpu->private_data = sonic;
- mpu->open_input = snd_sonicvibes_midi_input_open;
- mpu->close_input = snd_sonicvibes_midi_input_close;
- dir = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
- for (idx = 0; idx < ARRAY_SIZE(snd_sonicvibes_midi_controls); idx++)
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_sonicvibes_midi_controls[idx], sonic))) < 0)
- return err;
- return 0;
-}
-
-static int __devinit snd_sonic_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct sonicvibes *sonic;
- struct snd_rawmidi *midi_uart;
- struct snd_opl3 *opl3;
- int idx, err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
- for (idx = 0; idx < 5; idx++) {
- if (pci_resource_start(pci, idx) == 0 ||
- !(pci_resource_flags(pci, idx) & IORESOURCE_IO)) {
- snd_card_free(card);
- return -ENODEV;
- }
- }
- if ((err = snd_sonicvibes_create(card, pci,
- reverb[dev] ? 1 : 0,
- mge[dev] ? 1 : 0,
- &sonic)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- strcpy(card->driver, "SonicVibes");
- strcpy(card->shortname, "S3 SonicVibes");
- sprintf(card->longname, "%s rev %i at 0x%llx, irq %i",
- card->shortname,
- sonic->revision,
- (unsigned long long)pci_resource_start(pci, 1),
- sonic->irq);
-
- if ((err = snd_sonicvibes_pcm(sonic, 0, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_sonicvibes_mixer(sonic)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SONICVIBES,
- sonic->midi_port,
- MPU401_INFO_INTEGRATED |
- MPU401_INFO_IRQ_HOOK,
- -1, &midi_uart)) < 0) {
- snd_card_free(card);
- return err;
- }
- snd_sonicvibes_midi(sonic, midi_uart);
- if ((err = snd_opl3_create(card, sonic->synth_port,
- sonic->synth_port + 2,
- OPL3_HW_OPL3_SV, 1, &opl3)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- snd_sonicvibes_create_gameport(sonic);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_sonic_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_sonic_ids,
- .probe = snd_sonic_probe,
- .remove = __devexit_p(snd_sonic_remove),
-};
-
-static int __init alsa_card_sonicvibes_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_sonicvibes_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_sonicvibes_init)
-module_exit(alsa_card_sonicvibes_exit)
diff --git a/ANDROID_3.4.5/sound/pci/trident/Makefile b/ANDROID_3.4.5/sound/pci/trident/Makefile
deleted file mode 100644
index 88676b50..00000000
--- a/ANDROID_3.4.5/sound/pci/trident/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-trident-objs := trident.o trident_main.o trident_memory.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_TRIDENT) += snd-trident.o
diff --git a/ANDROID_3.4.5/sound/pci/trident/trident.c b/ANDROID_3.4.5/sound/pci/trident/trident.c
deleted file mode 100644
index 5f1def7f..00000000
--- a/ANDROID_3.4.5/sound/pci/trident/trident.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Driver for Trident 4DWave DX/NX & SiS SI7018 Audio PCI soundcard
- *
- * Driver was originated by Trident <audio@tridentmicro.com>
- * Fri Feb 19 15:55:28 MST 1999
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/time.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/trident.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, <audio@tridentmicro.com>");
-MODULE_DESCRIPTION("Trident 4D-WaveDX/NX & SiS SI7018");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Trident,4DWave DX},"
- "{Trident,4DWave NX},"
- "{SiS,SI7018 PCI Audio},"
- "{Best Union,Miss Melody 4DWave PCI},"
- "{HIS,4DWave PCI},"
- "{Warpspeed,ONSpeed 4DWave PCI},"
- "{Aztech Systems,PCI 64-Q3D},"
- "{Addonics,SV 750},"
- "{CHIC,True Sound 4Dwave},"
- "{Shark,Predator4D-PCI},"
- "{Jaton,SonicWave 4D},"
- "{Hoontech,SoundTrack Digital 4DWave NX}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 32};
-static int wavetable_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8192};
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Trident 4DWave PCI soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Trident 4DWave PCI soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Trident 4DWave PCI soundcard.");
-module_param_array(pcm_channels, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_channels, "Number of hardware channels assigned for PCM.");
-module_param_array(wavetable_size, int, NULL, 0444);
-MODULE_PARM_DESC(wavetable_size, "Maximum memory size in kB for wavetable synth.");
-
-static DEFINE_PCI_DEVICE_TABLE(snd_trident_ids) = {
- {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX),
- PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
- {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX),
- 0, 0, 0},
- {PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7018), 0, 0, 0},
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_trident_ids);
-
-static int __devinit snd_trident_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct snd_trident *trident;
- const char *str;
- int err, pcm_dev = 0;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- if ((err = snd_trident_create(card, pci,
- pcm_channels[dev],
- ((pci->vendor << 16) | pci->device) == TRIDENT_DEVICE_ID_SI7018 ? 1 : 2,
- wavetable_size[dev],
- &trident)) < 0) {
- snd_card_free(card);
- return err;
- }
- card->private_data = trident;
-
- switch (trident->device) {
- case TRIDENT_DEVICE_ID_DX:
- str = "TRID4DWAVEDX";
- break;
- case TRIDENT_DEVICE_ID_NX:
- str = "TRID4DWAVENX";
- break;
- case TRIDENT_DEVICE_ID_SI7018:
- str = "SI7018";
- break;
- default:
- str = "Unknown";
- }
- strcpy(card->driver, str);
- if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
- strcpy(card->shortname, "SiS ");
- } else {
- strcpy(card->shortname, "Trident ");
- }
- strcat(card->shortname, card->driver);
- sprintf(card->longname, "%s PCI Audio at 0x%lx, irq %d",
- card->shortname, trident->port, trident->irq);
-
- if ((err = snd_trident_pcm(trident, pcm_dev++, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- switch (trident->device) {
- case TRIDENT_DEVICE_ID_DX:
- case TRIDENT_DEVICE_ID_NX:
- if ((err = snd_trident_foldback_pcm(trident, pcm_dev++, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- break;
- }
- if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018) {
- if ((err = snd_trident_spdif_pcm(trident, pcm_dev++, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- }
- if (trident->device != TRIDENT_DEVICE_ID_SI7018 &&
- (err = snd_mpu401_uart_new(card, 0, MPU401_HW_TRID4DWAVE,
- trident->midi_port,
- MPU401_INFO_INTEGRATED |
- MPU401_INFO_IRQ_HOOK,
- -1, &trident->rmidi)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- snd_trident_create_gameport(trident);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_trident_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_trident_ids,
- .probe = snd_trident_probe,
- .remove = __devexit_p(snd_trident_remove),
-#ifdef CONFIG_PM
- .suspend = snd_trident_suspend,
- .resume = snd_trident_resume,
-#endif
-};
-
-static int __init alsa_card_trident_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_trident_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_trident_init)
-module_exit(alsa_card_trident_exit)
diff --git a/ANDROID_3.4.5/sound/pci/trident/trident_main.c b/ANDROID_3.4.5/sound/pci/trident/trident_main.c
deleted file mode 100644
index 61d3c0e8..00000000
--- a/ANDROID_3.4.5/sound/pci/trident/trident_main.c
+++ /dev/null
@@ -1,3982 +0,0 @@
-/*
- * Maintained by Jaroslav Kysela <perex@perex.cz>
- * Originated by audio@tridentmicro.com
- * Fri Feb 19 15:55:28 MST 1999
- * Routines for control of Trident 4DWave (DX and NX) chip
- *
- * BUGS:
- *
- * TODO:
- * ---
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
- * SiS7018 S/PDIF support by Thomas Winischhofer <thomas@winischhofer.net>
- */
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/gameport.h>
-#include <linux/dma-mapping.h>
-#include <linux/export.h>
-
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/trident.h>
-#include <sound/asoundef.h>
-
-#include <asm/io.h>
-
-static int snd_trident_pcm_mixer_build(struct snd_trident *trident,
- struct snd_trident_voice * voice,
- struct snd_pcm_substream *substream);
-static int snd_trident_pcm_mixer_free(struct snd_trident *trident,
- struct snd_trident_voice * voice,
- struct snd_pcm_substream *substream);
-static irqreturn_t snd_trident_interrupt(int irq, void *dev_id);
-static int snd_trident_sis_reset(struct snd_trident *trident);
-
-static void snd_trident_clear_voices(struct snd_trident * trident,
- unsigned short v_min, unsigned short v_max);
-static int snd_trident_free(struct snd_trident *trident);
-
-/*
- * common I/O routines
- */
-
-
-#if 0
-static void snd_trident_print_voice_regs(struct snd_trident *trident, int voice)
-{
- unsigned int val, tmp;
-
- printk(KERN_DEBUG "Trident voice %i:\n", voice);
- outb(voice, TRID_REG(trident, T4D_LFO_GC_CIR));
- val = inl(TRID_REG(trident, CH_LBA));
- printk(KERN_DEBUG "LBA: 0x%x\n", val);
- val = inl(TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC));
- printk(KERN_DEBUG "GVSel: %i\n", val >> 31);
- printk(KERN_DEBUG "Pan: 0x%x\n", (val >> 24) & 0x7f);
- printk(KERN_DEBUG "Vol: 0x%x\n", (val >> 16) & 0xff);
- printk(KERN_DEBUG "CTRL: 0x%x\n", (val >> 12) & 0x0f);
- printk(KERN_DEBUG "EC: 0x%x\n", val & 0x0fff);
- if (trident->device != TRIDENT_DEVICE_ID_NX) {
- val = inl(TRID_REG(trident, CH_DX_CSO_ALPHA_FMS));
- printk(KERN_DEBUG "CSO: 0x%x\n", val >> 16);
- printk("Alpha: 0x%x\n", (val >> 4) & 0x0fff);
- printk(KERN_DEBUG "FMS: 0x%x\n", val & 0x0f);
- val = inl(TRID_REG(trident, CH_DX_ESO_DELTA));
- printk(KERN_DEBUG "ESO: 0x%x\n", val >> 16);
- printk(KERN_DEBUG "Delta: 0x%x\n", val & 0xffff);
- val = inl(TRID_REG(trident, CH_DX_FMC_RVOL_CVOL));
- } else { // TRIDENT_DEVICE_ID_NX
- val = inl(TRID_REG(trident, CH_NX_DELTA_CSO));
- tmp = (val >> 24) & 0xff;
- printk(KERN_DEBUG "CSO: 0x%x\n", val & 0x00ffffff);
- val = inl(TRID_REG(trident, CH_NX_DELTA_ESO));
- tmp |= (val >> 16) & 0xff00;
- printk(KERN_DEBUG "Delta: 0x%x\n", tmp);
- printk(KERN_DEBUG "ESO: 0x%x\n", val & 0x00ffffff);
- val = inl(TRID_REG(trident, CH_NX_ALPHA_FMS_FMC_RVOL_CVOL));
- printk(KERN_DEBUG "Alpha: 0x%x\n", val >> 20);
- printk(KERN_DEBUG "FMS: 0x%x\n", (val >> 16) & 0x0f);
- }
- printk(KERN_DEBUG "FMC: 0x%x\n", (val >> 14) & 3);
- printk(KERN_DEBUG "RVol: 0x%x\n", (val >> 7) & 0x7f);
- printk(KERN_DEBUG "CVol: 0x%x\n", val & 0x7f);
-}
-#endif
-
-/*---------------------------------------------------------------------------
- unsigned short snd_trident_codec_read(struct snd_ac97 *ac97, unsigned short reg)
-
- Description: This routine will do all of the reading from the external
- CODEC (AC97).
-
- Parameters: ac97 - ac97 codec structure
- reg - CODEC register index, from AC97 Hal.
-
- returns: 16 bit value read from the AC97.
-
- ---------------------------------------------------------------------------*/
-static unsigned short snd_trident_codec_read(struct snd_ac97 *ac97, unsigned short reg)
-{
- unsigned int data = 0, treg;
- unsigned short count = 0xffff;
- unsigned long flags;
- struct snd_trident *trident = ac97->private_data;
-
- spin_lock_irqsave(&trident->reg_lock, flags);
- if (trident->device == TRIDENT_DEVICE_ID_DX) {
- data = (DX_AC97_BUSY_READ | (reg & 0x000000ff));
- outl(data, TRID_REG(trident, DX_ACR1_AC97_R));
- do {
- data = inl(TRID_REG(trident, DX_ACR1_AC97_R));
- if ((data & DX_AC97_BUSY_READ) == 0)
- break;
- } while (--count);
- } else if (trident->device == TRIDENT_DEVICE_ID_NX) {
- data = (NX_AC97_BUSY_READ | (reg & 0x000000ff));
- treg = ac97->num == 0 ? NX_ACR2_AC97_R_PRIMARY : NX_ACR3_AC97_R_SECONDARY;
- outl(data, TRID_REG(trident, treg));
- do {
- data = inl(TRID_REG(trident, treg));
- if ((data & 0x00000C00) == 0)
- break;
- } while (--count);
- } else if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
- data = SI_AC97_BUSY_READ | SI_AC97_AUDIO_BUSY | (reg & 0x000000ff);
- if (ac97->num == 1)
- data |= SI_AC97_SECONDARY;
- outl(data, TRID_REG(trident, SI_AC97_READ));
- do {
- data = inl(TRID_REG(trident, SI_AC97_READ));
- if ((data & (SI_AC97_BUSY_READ)) == 0)
- break;
- } while (--count);
- }
-
- if (count == 0 && !trident->ac97_detect) {
- snd_printk(KERN_ERR "ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n",
- reg, data);
- data = 0;
- }
-
- spin_unlock_irqrestore(&trident->reg_lock, flags);
- return ((unsigned short) (data >> 16));
-}
-
-/*---------------------------------------------------------------------------
- void snd_trident_codec_write(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short wdata)
-
- Description: This routine will do all of the writing to the external
- CODEC (AC97).
-
- Parameters: ac97 - ac97 codec structure
- reg - CODEC register index, from AC97 Hal.
- data - Lower 16 bits are the data to write to CODEC.
-
- returns: TRUE if everything went ok, else FALSE.
-
- ---------------------------------------------------------------------------*/
-static void snd_trident_codec_write(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short wdata)
-{
- unsigned int address, data;
- unsigned short count = 0xffff;
- unsigned long flags;
- struct snd_trident *trident = ac97->private_data;
-
- data = ((unsigned long) wdata) << 16;
-
- spin_lock_irqsave(&trident->reg_lock, flags);
- if (trident->device == TRIDENT_DEVICE_ID_DX) {
- address = DX_ACR0_AC97_W;
-
- /* read AC-97 write register status */
- do {
- if ((inw(TRID_REG(trident, address)) & DX_AC97_BUSY_WRITE) == 0)
- break;
- } while (--count);
-
- data |= (DX_AC97_BUSY_WRITE | (reg & 0x000000ff));
- } else if (trident->device == TRIDENT_DEVICE_ID_NX) {
- address = NX_ACR1_AC97_W;
-
- /* read AC-97 write register status */
- do {
- if ((inw(TRID_REG(trident, address)) & NX_AC97_BUSY_WRITE) == 0)
- break;
- } while (--count);
-
- data |= (NX_AC97_BUSY_WRITE | (ac97->num << 8) | (reg & 0x000000ff));
- } else if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
- address = SI_AC97_WRITE;
-
- /* read AC-97 write register status */
- do {
- if ((inw(TRID_REG(trident, address)) & (SI_AC97_BUSY_WRITE)) == 0)
- break;
- } while (--count);
-
- data |= SI_AC97_BUSY_WRITE | SI_AC97_AUDIO_BUSY | (reg & 0x000000ff);
- if (ac97->num == 1)
- data |= SI_AC97_SECONDARY;
- } else {
- address = 0; /* keep GCC happy */
- count = 0; /* return */
- }
-
- if (count == 0) {
- spin_unlock_irqrestore(&trident->reg_lock, flags);
- return;
- }
- outl(data, TRID_REG(trident, address));
- spin_unlock_irqrestore(&trident->reg_lock, flags);
-}
-
-/*---------------------------------------------------------------------------
- void snd_trident_enable_eso(struct snd_trident *trident)
-
- Description: This routine will enable end of loop interrupts.
- End of loop interrupts will occur when a running
- channel reaches ESO.
- Also enables middle of loop interrupts.
-
- Parameters: trident - pointer to target device class for 4DWave.
-
- ---------------------------------------------------------------------------*/
-
-static void snd_trident_enable_eso(struct snd_trident * trident)
-{
- unsigned int val;
-
- val = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
- val |= ENDLP_IE;
- val |= MIDLP_IE;
- if (trident->device == TRIDENT_DEVICE_ID_SI7018)
- val |= BANK_B_EN;
- outl(val, TRID_REG(trident, T4D_LFO_GC_CIR));
-}
-
-/*---------------------------------------------------------------------------
- void snd_trident_disable_eso(struct snd_trident *trident)
-
- Description: This routine will disable end of loop interrupts.
- End of loop interrupts will occur when a running
- channel reaches ESO.
- Also disables middle of loop interrupts.
-
- Parameters:
- trident - pointer to target device class for 4DWave.
-
- returns: TRUE if everything went ok, else FALSE.
-
- ---------------------------------------------------------------------------*/
-
-static void snd_trident_disable_eso(struct snd_trident * trident)
-{
- unsigned int tmp;
-
- tmp = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
- tmp &= ~ENDLP_IE;
- tmp &= ~MIDLP_IE;
- outl(tmp, TRID_REG(trident, T4D_LFO_GC_CIR));
-}
-
-/*---------------------------------------------------------------------------
- void snd_trident_start_voice(struct snd_trident * trident, unsigned int voice)
-
- Description: Start a voice, any channel 0 thru 63.
- This routine automatically handles the fact that there are
- more than 32 channels available.
-
- Parameters : voice - Voice number 0 thru n.
- trident - pointer to target device class for 4DWave.
-
- Return Value: None.
-
- ---------------------------------------------------------------------------*/
-
-void snd_trident_start_voice(struct snd_trident * trident, unsigned int voice)
-{
- unsigned int mask = 1 << (voice & 0x1f);
- unsigned int reg = (voice & 0x20) ? T4D_START_B : T4D_START_A;
-
- outl(mask, TRID_REG(trident, reg));
-}
-
-EXPORT_SYMBOL(snd_trident_start_voice);
-
-/*---------------------------------------------------------------------------
- void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice)
-
- Description: Stop a voice, any channel 0 thru 63.
- This routine automatically handles the fact that there are
- more than 32 channels available.
-
- Parameters : voice - Voice number 0 thru n.
- trident - pointer to target device class for 4DWave.
-
- Return Value: None.
-
- ---------------------------------------------------------------------------*/
-
-void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice)
-{
- unsigned int mask = 1 << (voice & 0x1f);
- unsigned int reg = (voice & 0x20) ? T4D_STOP_B : T4D_STOP_A;
-
- outl(mask, TRID_REG(trident, reg));
-}
-
-EXPORT_SYMBOL(snd_trident_stop_voice);
-
-/*---------------------------------------------------------------------------
- int snd_trident_allocate_pcm_channel(struct snd_trident *trident)
-
- Description: Allocate hardware channel in Bank B (32-63).
-
- Parameters : trident - pointer to target device class for 4DWave.
-
- Return Value: hardware channel - 32-63 or -1 when no channel is available
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_allocate_pcm_channel(struct snd_trident * trident)
-{
- int idx;
-
- if (trident->ChanPCMcnt >= trident->ChanPCM)
- return -1;
- for (idx = 31; idx >= 0; idx--) {
- if (!(trident->ChanMap[T4D_BANK_B] & (1 << idx))) {
- trident->ChanMap[T4D_BANK_B] |= 1 << idx;
- trident->ChanPCMcnt++;
- return idx + 32;
- }
- }
- return -1;
-}
-
-/*---------------------------------------------------------------------------
- void snd_trident_free_pcm_channel(int channel)
-
- Description: Free hardware channel in Bank B (32-63)
-
- Parameters : trident - pointer to target device class for 4DWave.
- channel - hardware channel number 0-63
-
- Return Value: none
-
- ---------------------------------------------------------------------------*/
-
-static void snd_trident_free_pcm_channel(struct snd_trident *trident, int channel)
-{
- if (channel < 32 || channel > 63)
- return;
- channel &= 0x1f;
- if (trident->ChanMap[T4D_BANK_B] & (1 << channel)) {
- trident->ChanMap[T4D_BANK_B] &= ~(1 << channel);
- trident->ChanPCMcnt--;
- }
-}
-
-/*---------------------------------------------------------------------------
- unsigned int snd_trident_allocate_synth_channel(void)
-
- Description: Allocate hardware channel in Bank A (0-31).
-
- Parameters : trident - pointer to target device class for 4DWave.
-
- Return Value: hardware channel - 0-31 or -1 when no channel is available
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_allocate_synth_channel(struct snd_trident * trident)
-{
- int idx;
-
- for (idx = 31; idx >= 0; idx--) {
- if (!(trident->ChanMap[T4D_BANK_A] & (1 << idx))) {
- trident->ChanMap[T4D_BANK_A] |= 1 << idx;
- trident->synth.ChanSynthCount++;
- return idx;
- }
- }
- return -1;
-}
-
-/*---------------------------------------------------------------------------
- void snd_trident_free_synth_channel( int channel )
-
- Description: Free hardware channel in Bank B (0-31).
-
- Parameters : trident - pointer to target device class for 4DWave.
- channel - hardware channel number 0-63
-
- Return Value: none
-
- ---------------------------------------------------------------------------*/
-
-static void snd_trident_free_synth_channel(struct snd_trident *trident, int channel)
-{
- if (channel < 0 || channel > 31)
- return;
- channel &= 0x1f;
- if (trident->ChanMap[T4D_BANK_A] & (1 << channel)) {
- trident->ChanMap[T4D_BANK_A] &= ~(1 << channel);
- trident->synth.ChanSynthCount--;
- }
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_write_voice_regs
-
- Description: This routine will complete and write the 5 hardware channel
- registers to hardware.
-
- Parameters: trident - pointer to target device class for 4DWave.
- voice - synthesizer voice structure
- Each register field.
-
- ---------------------------------------------------------------------------*/
-
-void snd_trident_write_voice_regs(struct snd_trident * trident,
- struct snd_trident_voice * voice)
-{
- unsigned int FmcRvolCvol;
- unsigned int regs[5];
-
- regs[1] = voice->LBA;
- regs[4] = (voice->GVSel << 31) |
- ((voice->Pan & 0x0000007f) << 24) |
- ((voice->CTRL & 0x0000000f) << 12);
- FmcRvolCvol = ((voice->FMC & 3) << 14) |
- ((voice->RVol & 0x7f) << 7) |
- (voice->CVol & 0x7f);
-
- switch (trident->device) {
- case TRIDENT_DEVICE_ID_SI7018:
- regs[4] |= voice->number > 31 ?
- (voice->Vol & 0x000003ff) :
- ((voice->Vol & 0x00003fc) << (16-2)) |
- (voice->EC & 0x00000fff);
- regs[0] = (voice->CSO << 16) | ((voice->Alpha & 0x00000fff) << 4) |
- (voice->FMS & 0x0000000f);
- regs[2] = (voice->ESO << 16) | (voice->Delta & 0x0ffff);
- regs[3] = (voice->Attribute << 16) | FmcRvolCvol;
- break;
- case TRIDENT_DEVICE_ID_DX:
- regs[4] |= ((voice->Vol & 0x000003fc) << (16-2)) |
- (voice->EC & 0x00000fff);
- regs[0] = (voice->CSO << 16) | ((voice->Alpha & 0x00000fff) << 4) |
- (voice->FMS & 0x0000000f);
- regs[2] = (voice->ESO << 16) | (voice->Delta & 0x0ffff);
- regs[3] = FmcRvolCvol;
- break;
- case TRIDENT_DEVICE_ID_NX:
- regs[4] |= ((voice->Vol & 0x000003fc) << (16-2)) |
- (voice->EC & 0x00000fff);
- regs[0] = (voice->Delta << 24) | (voice->CSO & 0x00ffffff);
- regs[2] = ((voice->Delta << 16) & 0xff000000) |
- (voice->ESO & 0x00ffffff);
- regs[3] = (voice->Alpha << 20) |
- ((voice->FMS & 0x0000000f) << 16) | FmcRvolCvol;
- break;
- default:
- snd_BUG();
- return;
- }
-
- outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
- outl(regs[0], TRID_REG(trident, CH_START + 0));
- outl(regs[1], TRID_REG(trident, CH_START + 4));
- outl(regs[2], TRID_REG(trident, CH_START + 8));
- outl(regs[3], TRID_REG(trident, CH_START + 12));
- outl(regs[4], TRID_REG(trident, CH_START + 16));
-
-#if 0
- printk(KERN_DEBUG "written %i channel:\n", voice->number);
- printk(KERN_DEBUG " regs[0] = 0x%x/0x%x\n",
- regs[0], inl(TRID_REG(trident, CH_START + 0)));
- printk(KERN_DEBUG " regs[1] = 0x%x/0x%x\n",
- regs[1], inl(TRID_REG(trident, CH_START + 4)));
- printk(KERN_DEBUG " regs[2] = 0x%x/0x%x\n",
- regs[2], inl(TRID_REG(trident, CH_START + 8)));
- printk(KERN_DEBUG " regs[3] = 0x%x/0x%x\n",
- regs[3], inl(TRID_REG(trident, CH_START + 12)));
- printk(KERN_DEBUG " regs[4] = 0x%x/0x%x\n",
- regs[4], inl(TRID_REG(trident, CH_START + 16)));
-#endif
-}
-
-EXPORT_SYMBOL(snd_trident_write_voice_regs);
-
-/*---------------------------------------------------------------------------
- snd_trident_write_cso_reg
-
- Description: This routine will write the new CSO offset
- register to hardware.
-
- Parameters: trident - pointer to target device class for 4DWave.
- voice - synthesizer voice structure
- CSO - new CSO value
-
- ---------------------------------------------------------------------------*/
-
-static void snd_trident_write_cso_reg(struct snd_trident * trident,
- struct snd_trident_voice * voice,
- unsigned int CSO)
-{
- voice->CSO = CSO;
- outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
- if (trident->device != TRIDENT_DEVICE_ID_NX) {
- outw(voice->CSO, TRID_REG(trident, CH_DX_CSO_ALPHA_FMS) + 2);
- } else {
- outl((voice->Delta << 24) |
- (voice->CSO & 0x00ffffff), TRID_REG(trident, CH_NX_DELTA_CSO));
- }
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_write_eso_reg
-
- Description: This routine will write the new ESO offset
- register to hardware.
-
- Parameters: trident - pointer to target device class for 4DWave.
- voice - synthesizer voice structure
- ESO - new ESO value
-
- ---------------------------------------------------------------------------*/
-
-static void snd_trident_write_eso_reg(struct snd_trident * trident,
- struct snd_trident_voice * voice,
- unsigned int ESO)
-{
- voice->ESO = ESO;
- outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
- if (trident->device != TRIDENT_DEVICE_ID_NX) {
- outw(voice->ESO, TRID_REG(trident, CH_DX_ESO_DELTA) + 2);
- } else {
- outl(((voice->Delta << 16) & 0xff000000) | (voice->ESO & 0x00ffffff),
- TRID_REG(trident, CH_NX_DELTA_ESO));
- }
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_write_vol_reg
-
- Description: This routine will write the new voice volume
- register to hardware.
-
- Parameters: trident - pointer to target device class for 4DWave.
- voice - synthesizer voice structure
- Vol - new voice volume
-
- ---------------------------------------------------------------------------*/
-
-static void snd_trident_write_vol_reg(struct snd_trident * trident,
- struct snd_trident_voice * voice,
- unsigned int Vol)
-{
- voice->Vol = Vol;
- outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
- switch (trident->device) {
- case TRIDENT_DEVICE_ID_DX:
- case TRIDENT_DEVICE_ID_NX:
- outb(voice->Vol >> 2, TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC + 2));
- break;
- case TRIDENT_DEVICE_ID_SI7018:
- /* printk(KERN_DEBUG "voice->Vol = 0x%x\n", voice->Vol); */
- outw((voice->CTRL << 12) | voice->Vol,
- TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC));
- break;
- }
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_write_pan_reg
-
- Description: This routine will write the new voice pan
- register to hardware.
-
- Parameters: trident - pointer to target device class for 4DWave.
- voice - synthesizer voice structure
- Pan - new pan value
-
- ---------------------------------------------------------------------------*/
-
-static void snd_trident_write_pan_reg(struct snd_trident * trident,
- struct snd_trident_voice * voice,
- unsigned int Pan)
-{
- voice->Pan = Pan;
- outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
- outb(((voice->GVSel & 0x01) << 7) | (voice->Pan & 0x7f),
- TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC + 3));
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_write_rvol_reg
-
- Description: This routine will write the new reverb volume
- register to hardware.
-
- Parameters: trident - pointer to target device class for 4DWave.
- voice - synthesizer voice structure
- RVol - new reverb volume
-
- ---------------------------------------------------------------------------*/
-
-static void snd_trident_write_rvol_reg(struct snd_trident * trident,
- struct snd_trident_voice * voice,
- unsigned int RVol)
-{
- voice->RVol = RVol;
- outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
- outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) |
- (voice->CVol & 0x007f),
- TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ?
- CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL));
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_write_cvol_reg
-
- Description: This routine will write the new chorus volume
- register to hardware.
-
- Parameters: trident - pointer to target device class for 4DWave.
- voice - synthesizer voice structure
- CVol - new chorus volume
-
- ---------------------------------------------------------------------------*/
-
-static void snd_trident_write_cvol_reg(struct snd_trident * trident,
- struct snd_trident_voice * voice,
- unsigned int CVol)
-{
- voice->CVol = CVol;
- outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
- outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) |
- (voice->CVol & 0x007f),
- TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ?
- CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL));
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_convert_rate
-
- Description: This routine converts rate in HZ to hardware delta value.
-
- Parameters: trident - pointer to target device class for 4DWave.
- rate - Real or Virtual channel number.
-
- Returns: Delta value.
-
- ---------------------------------------------------------------------------*/
-static unsigned int snd_trident_convert_rate(unsigned int rate)
-{
- unsigned int delta;
-
- // We special case 44100 and 8000 since rounding with the equation
- // does not give us an accurate enough value. For 11025 and 22050
- // the equation gives us the best answer. All other frequencies will
- // also use the equation. JDW
- if (rate == 44100)
- delta = 0xeb3;
- else if (rate == 8000)
- delta = 0x2ab;
- else if (rate == 48000)
- delta = 0x1000;
- else
- delta = (((rate << 12) + 24000) / 48000) & 0x0000ffff;
- return delta;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_convert_adc_rate
-
- Description: This routine converts rate in HZ to hardware delta value.
-
- Parameters: trident - pointer to target device class for 4DWave.
- rate - Real or Virtual channel number.
-
- Returns: Delta value.
-
- ---------------------------------------------------------------------------*/
-static unsigned int snd_trident_convert_adc_rate(unsigned int rate)
-{
- unsigned int delta;
-
- // We special case 44100 and 8000 since rounding with the equation
- // does not give us an accurate enough value. For 11025 and 22050
- // the equation gives us the best answer. All other frequencies will
- // also use the equation. JDW
- if (rate == 44100)
- delta = 0x116a;
- else if (rate == 8000)
- delta = 0x6000;
- else if (rate == 48000)
- delta = 0x1000;
- else
- delta = ((48000 << 12) / rate) & 0x0000ffff;
- return delta;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_spurious_threshold
-
- Description: This routine converts rate in HZ to spurious threshold.
-
- Parameters: trident - pointer to target device class for 4DWave.
- rate - Real or Virtual channel number.
-
- Returns: Delta value.
-
- ---------------------------------------------------------------------------*/
-static unsigned int snd_trident_spurious_threshold(unsigned int rate,
- unsigned int period_size)
-{
- unsigned int res = (rate * period_size) / 48000;
- if (res < 64)
- res = res / 2;
- else
- res -= 32;
- return res;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_control_mode
-
- Description: This routine returns a control mode for a PCM channel.
-
- Parameters: trident - pointer to target device class for 4DWave.
- substream - PCM substream
-
- Returns: Control value.
-
- ---------------------------------------------------------------------------*/
-static unsigned int snd_trident_control_mode(struct snd_pcm_substream *substream)
-{
- unsigned int CTRL;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- /* set ctrl mode
- CTRL default: 8-bit (unsigned) mono, loop mode enabled
- */
- CTRL = 0x00000001;
- if (snd_pcm_format_width(runtime->format) == 16)
- CTRL |= 0x00000008; // 16-bit data
- if (snd_pcm_format_signed(runtime->format))
- CTRL |= 0x00000002; // signed data
- if (runtime->channels > 1)
- CTRL |= 0x00000004; // stereo data
- return CTRL;
-}
-
-/*
- * PCM part
- */
-
-/*---------------------------------------------------------------------------
- snd_trident_ioctl
-
- Description: Device I/O control handler for playback/capture parameters.
-
- Parameters: substream - PCM substream class
- cmd - what ioctl message to process
- arg - additional message infoarg
-
- Returns: Error status
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_ioctl(struct snd_pcm_substream *substream,
- unsigned int cmd,
- void *arg)
-{
- /* FIXME: it seems that with small periods the behaviour of
- trident hardware is unpredictable and interrupt generator
- is broken */
- return snd_pcm_lib_ioctl(substream, cmd, arg);
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_allocate_pcm_mem
-
- Description: Allocate PCM ring buffer for given substream
-
- Parameters: substream - PCM substream class
- hw_params - hardware parameters
-
- Returns: Error status
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_allocate_pcm_mem(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_trident_voice *voice = runtime->private_data;
- int err;
-
- if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
- return err;
- if (trident->tlb.entries) {
- if (err > 0) { /* change */
- if (voice->memblk)
- snd_trident_free_pages(trident, voice->memblk);
- voice->memblk = snd_trident_alloc_pages(trident, substream);
- if (voice->memblk == NULL)
- return -ENOMEM;
- }
- }
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_allocate_evoice
-
- Description: Allocate extra voice as interrupt generator
-
- Parameters: substream - PCM substream class
- hw_params - hardware parameters
-
- Returns: Error status
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_allocate_evoice(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_trident_voice *voice = runtime->private_data;
- struct snd_trident_voice *evoice = voice->extra;
-
- /* voice management */
-
- if (params_buffer_size(hw_params) / 2 != params_period_size(hw_params)) {
- if (evoice == NULL) {
- evoice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
- if (evoice == NULL)
- return -ENOMEM;
- voice->extra = evoice;
- evoice->substream = substream;
- }
- } else {
- if (evoice != NULL) {
- snd_trident_free_voice(trident, evoice);
- voice->extra = evoice = NULL;
- }
- }
-
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_hw_params
-
- Description: Set the hardware parameters for the playback device.
-
- Parameters: substream - PCM substream class
- hw_params - hardware parameters
-
- Returns: Error status
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- int err;
-
- err = snd_trident_allocate_pcm_mem(substream, hw_params);
- if (err >= 0)
- err = snd_trident_allocate_evoice(substream, hw_params);
- return err;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_playback_hw_free
-
- Description: Release the hardware resources for the playback device.
-
- Parameters: substream - PCM substream class
-
- Returns: Error status
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_trident_voice *voice = runtime->private_data;
- struct snd_trident_voice *evoice = voice ? voice->extra : NULL;
-
- if (trident->tlb.entries) {
- if (voice && voice->memblk) {
- snd_trident_free_pages(trident, voice->memblk);
- voice->memblk = NULL;
- }
- }
- snd_pcm_lib_free_pages(substream);
- if (evoice != NULL) {
- snd_trident_free_voice(trident, evoice);
- voice->extra = NULL;
- }
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_playback_prepare
-
- Description: Prepare playback device for playback.
-
- Parameters: substream - PCM substream class
-
- Returns: Error status
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_trident_voice *voice = runtime->private_data;
- struct snd_trident_voice *evoice = voice->extra;
- struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[substream->number];
-
- spin_lock_irq(&trident->reg_lock);
-
- /* set delta (rate) value */
- voice->Delta = snd_trident_convert_rate(runtime->rate);
- voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);
-
- /* set Loop Begin Address */
- if (voice->memblk)
- voice->LBA = voice->memblk->offset;
- else
- voice->LBA = runtime->dma_addr;
-
- voice->CSO = 0;
- voice->ESO = runtime->buffer_size - 1; /* in samples */
- voice->CTRL = snd_trident_control_mode(substream);
- voice->FMC = 3;
- voice->GVSel = 1;
- voice->EC = 0;
- voice->Alpha = 0;
- voice->FMS = 0;
- voice->Vol = mix->vol;
- voice->RVol = mix->rvol;
- voice->CVol = mix->cvol;
- voice->Pan = mix->pan;
- voice->Attribute = 0;
-#if 0
- voice->Attribute = (1<<(30-16))|(2<<(26-16))|
- (0<<(24-16))|(0x1f<<(19-16));
-#else
- voice->Attribute = 0;
-#endif
-
- snd_trident_write_voice_regs(trident, voice);
-
- if (evoice != NULL) {
- evoice->Delta = voice->Delta;
- evoice->spurious_threshold = voice->spurious_threshold;
- evoice->LBA = voice->LBA;
- evoice->CSO = 0;
- evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */
- evoice->CTRL = voice->CTRL;
- evoice->FMC = 3;
- evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1;
- evoice->EC = 0;
- evoice->Alpha = 0;
- evoice->FMS = 0;
- evoice->Vol = 0x3ff; /* mute */
- evoice->RVol = evoice->CVol = 0x7f; /* mute */
- evoice->Pan = 0x7f; /* mute */
-#if 0
- evoice->Attribute = (1<<(30-16))|(2<<(26-16))|
- (0<<(24-16))|(0x1f<<(19-16));
-#else
- evoice->Attribute = 0;
-#endif
- snd_trident_write_voice_regs(trident, evoice);
- evoice->isync2 = 1;
- evoice->isync_mark = runtime->period_size;
- evoice->ESO = (runtime->period_size * 2) - 1;
- }
-
- spin_unlock_irq(&trident->reg_lock);
-
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_capture_hw_params
-
- Description: Set the hardware parameters for the capture device.
-
- Parameters: substream - PCM substream class
- hw_params - hardware parameters
-
- Returns: Error status
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_capture_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_trident_allocate_pcm_mem(substream, hw_params);
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_capture_prepare
-
- Description: Prepare capture device for playback.
-
- Parameters: substream - PCM substream class
-
- Returns: Error status
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_trident_voice *voice = runtime->private_data;
- unsigned int val, ESO_bytes;
-
- spin_lock_irq(&trident->reg_lock);
-
- // Initialize the channel and set channel Mode
- outb(0, TRID_REG(trident, LEGACY_DMAR15));
-
- // Set DMA channel operation mode register
- outb(0x54, TRID_REG(trident, LEGACY_DMAR11));
-
- // Set channel buffer Address, DMAR0 expects contiguous PCI memory area
- voice->LBA = runtime->dma_addr;
- outl(voice->LBA, TRID_REG(trident, LEGACY_DMAR0));
- if (voice->memblk)
- voice->LBA = voice->memblk->offset;
-
- // set ESO
- ESO_bytes = snd_pcm_lib_buffer_bytes(substream) - 1;
- outb((ESO_bytes & 0x00ff0000) >> 16, TRID_REG(trident, LEGACY_DMAR6));
- outw((ESO_bytes & 0x0000ffff), TRID_REG(trident, LEGACY_DMAR4));
- ESO_bytes++;
-
- // Set channel sample rate, 4.12 format
- val = (((unsigned int) 48000L << 12) + (runtime->rate/2)) / runtime->rate;
- outw(val, TRID_REG(trident, T4D_SBDELTA_DELTA_R));
-
- // Set channel interrupt blk length
- if (snd_pcm_format_width(runtime->format) == 16) {
- val = (unsigned short) ((ESO_bytes >> 1) - 1);
- } else {
- val = (unsigned short) (ESO_bytes - 1);
- }
-
- outl((val << 16) | val, TRID_REG(trident, T4D_SBBL_SBCL));
-
- // Right now, set format and start to run captureing,
- // continuous run loop enable.
- trident->bDMAStart = 0x19; // 0001 1001b
-
- if (snd_pcm_format_width(runtime->format) == 16)
- trident->bDMAStart |= 0x80;
- if (snd_pcm_format_signed(runtime->format))
- trident->bDMAStart |= 0x20;
- if (runtime->channels > 1)
- trident->bDMAStart |= 0x40;
-
- // Prepare capture intr channel
-
- voice->Delta = snd_trident_convert_rate(runtime->rate);
- voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);
- voice->isync = 1;
- voice->isync_mark = runtime->period_size;
- voice->isync_max = runtime->buffer_size;
-
- // Set voice parameters
- voice->CSO = 0;
- voice->ESO = voice->isync_ESO = (runtime->period_size * 2) + 6 - 1;
- voice->CTRL = snd_trident_control_mode(substream);
- voice->FMC = 3;
- voice->RVol = 0x7f;
- voice->CVol = 0x7f;
- voice->GVSel = 1;
- voice->Pan = 0x7f; /* mute */
- voice->Vol = 0x3ff; /* mute */
- voice->EC = 0;
- voice->Alpha = 0;
- voice->FMS = 0;
- voice->Attribute = 0;
-
- snd_trident_write_voice_regs(trident, voice);
-
- spin_unlock_irq(&trident->reg_lock);
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_si7018_capture_hw_params
-
- Description: Set the hardware parameters for the capture device.
-
- Parameters: substream - PCM substream class
- hw_params - hardware parameters
-
- Returns: Error status
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_si7018_capture_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- int err;
-
- if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
- return err;
-
- return snd_trident_allocate_evoice(substream, hw_params);
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_si7018_capture_hw_free
-
- Description: Release the hardware resources for the capture device.
-
- Parameters: substream - PCM substream class
-
- Returns: Error status
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_si7018_capture_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_trident_voice *voice = runtime->private_data;
- struct snd_trident_voice *evoice = voice ? voice->extra : NULL;
-
- snd_pcm_lib_free_pages(substream);
- if (evoice != NULL) {
- snd_trident_free_voice(trident, evoice);
- voice->extra = NULL;
- }
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_si7018_capture_prepare
-
- Description: Prepare capture device for playback.
-
- Parameters: substream - PCM substream class
-
- Returns: Error status
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_si7018_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_trident_voice *voice = runtime->private_data;
- struct snd_trident_voice *evoice = voice->extra;
-
- spin_lock_irq(&trident->reg_lock);
-
- voice->LBA = runtime->dma_addr;
- voice->Delta = snd_trident_convert_adc_rate(runtime->rate);
- voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);
-
- // Set voice parameters
- voice->CSO = 0;
- voice->ESO = runtime->buffer_size - 1; /* in samples */
- voice->CTRL = snd_trident_control_mode(substream);
- voice->FMC = 0;
- voice->RVol = 0;
- voice->CVol = 0;
- voice->GVSel = 1;
- voice->Pan = T4D_DEFAULT_PCM_PAN;
- voice->Vol = 0;
- voice->EC = 0;
- voice->Alpha = 0;
- voice->FMS = 0;
-
- voice->Attribute = (2 << (30-16)) |
- (2 << (26-16)) |
- (2 << (24-16)) |
- (1 << (23-16));
-
- snd_trident_write_voice_regs(trident, voice);
-
- if (evoice != NULL) {
- evoice->Delta = snd_trident_convert_rate(runtime->rate);
- evoice->spurious_threshold = voice->spurious_threshold;
- evoice->LBA = voice->LBA;
- evoice->CSO = 0;
- evoice->ESO = (runtime->period_size * 2) + 20 - 1; /* in samples, 20 means correction */
- evoice->CTRL = voice->CTRL;
- evoice->FMC = 3;
- evoice->GVSel = 0;
- evoice->EC = 0;
- evoice->Alpha = 0;
- evoice->FMS = 0;
- evoice->Vol = 0x3ff; /* mute */
- evoice->RVol = evoice->CVol = 0x7f; /* mute */
- evoice->Pan = 0x7f; /* mute */
- evoice->Attribute = 0;
- snd_trident_write_voice_regs(trident, evoice);
- evoice->isync2 = 1;
- evoice->isync_mark = runtime->period_size;
- evoice->ESO = (runtime->period_size * 2) - 1;
- }
-
- spin_unlock_irq(&trident->reg_lock);
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_foldback_prepare
-
- Description: Prepare foldback capture device for playback.
-
- Parameters: substream - PCM substream class
-
- Returns: Error status
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_foldback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_trident_voice *voice = runtime->private_data;
- struct snd_trident_voice *evoice = voice->extra;
-
- spin_lock_irq(&trident->reg_lock);
-
- /* Set channel buffer Address */
- if (voice->memblk)
- voice->LBA = voice->memblk->offset;
- else
- voice->LBA = runtime->dma_addr;
-
- /* set target ESO for channel */
- voice->ESO = runtime->buffer_size - 1; /* in samples */
-
- /* set sample rate */
- voice->Delta = 0x1000;
- voice->spurious_threshold = snd_trident_spurious_threshold(48000, runtime->period_size);
-
- voice->CSO = 0;
- voice->CTRL = snd_trident_control_mode(substream);
- voice->FMC = 3;
- voice->RVol = 0x7f;
- voice->CVol = 0x7f;
- voice->GVSel = 1;
- voice->Pan = 0x7f; /* mute */
- voice->Vol = 0x3ff; /* mute */
- voice->EC = 0;
- voice->Alpha = 0;
- voice->FMS = 0;
- voice->Attribute = 0;
-
- /* set up capture channel */
- outb(((voice->number & 0x3f) | 0x80), TRID_REG(trident, T4D_RCI + voice->foldback_chan));
-
- snd_trident_write_voice_regs(trident, voice);
-
- if (evoice != NULL) {
- evoice->Delta = voice->Delta;
- evoice->spurious_threshold = voice->spurious_threshold;
- evoice->LBA = voice->LBA;
- evoice->CSO = 0;
- evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */
- evoice->CTRL = voice->CTRL;
- evoice->FMC = 3;
- evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1;
- evoice->EC = 0;
- evoice->Alpha = 0;
- evoice->FMS = 0;
- evoice->Vol = 0x3ff; /* mute */
- evoice->RVol = evoice->CVol = 0x7f; /* mute */
- evoice->Pan = 0x7f; /* mute */
- evoice->Attribute = 0;
- snd_trident_write_voice_regs(trident, evoice);
- evoice->isync2 = 1;
- evoice->isync_mark = runtime->period_size;
- evoice->ESO = (runtime->period_size * 2) - 1;
- }
-
- spin_unlock_irq(&trident->reg_lock);
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_spdif_hw_params
-
- Description: Set the hardware parameters for the spdif device.
-
- Parameters: substream - PCM substream class
- hw_params - hardware parameters
-
- Returns: Error status
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_spdif_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- unsigned int old_bits = 0, change = 0;
- int err;
-
- err = snd_trident_allocate_pcm_mem(substream, hw_params);
- if (err < 0)
- return err;
-
- if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
- err = snd_trident_allocate_evoice(substream, hw_params);
- if (err < 0)
- return err;
- }
-
- /* prepare SPDIF channel */
- spin_lock_irq(&trident->reg_lock);
- old_bits = trident->spdif_pcm_bits;
- if (old_bits & IEC958_AES0_PROFESSIONAL)
- trident->spdif_pcm_bits &= ~IEC958_AES0_PRO_FS;
- else
- trident->spdif_pcm_bits &= ~(IEC958_AES3_CON_FS << 24);
- if (params_rate(hw_params) >= 48000) {
- trident->spdif_pcm_ctrl = 0x3c; // 48000 Hz
- trident->spdif_pcm_bits |=
- trident->spdif_bits & IEC958_AES0_PROFESSIONAL ?
- IEC958_AES0_PRO_FS_48000 :
- (IEC958_AES3_CON_FS_48000 << 24);
- }
- else if (params_rate(hw_params) >= 44100) {
- trident->spdif_pcm_ctrl = 0x3e; // 44100 Hz
- trident->spdif_pcm_bits |=
- trident->spdif_bits & IEC958_AES0_PROFESSIONAL ?
- IEC958_AES0_PRO_FS_44100 :
- (IEC958_AES3_CON_FS_44100 << 24);
- }
- else {
- trident->spdif_pcm_ctrl = 0x3d; // 32000 Hz
- trident->spdif_pcm_bits |=
- trident->spdif_bits & IEC958_AES0_PROFESSIONAL ?
- IEC958_AES0_PRO_FS_32000 :
- (IEC958_AES3_CON_FS_32000 << 24);
- }
- change = old_bits != trident->spdif_pcm_bits;
- spin_unlock_irq(&trident->reg_lock);
-
- if (change)
- snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE, &trident->spdif_pcm_ctl->id);
-
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_spdif_prepare
-
- Description: Prepare SPDIF device for playback.
-
- Parameters: substream - PCM substream class
-
- Returns: Error status
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_spdif_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_trident_voice *voice = runtime->private_data;
- struct snd_trident_voice *evoice = voice->extra;
- struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[substream->number];
- unsigned int RESO, LBAO;
- unsigned int temp;
-
- spin_lock_irq(&trident->reg_lock);
-
- if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
-
- /* set delta (rate) value */
- voice->Delta = snd_trident_convert_rate(runtime->rate);
- voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);
-
- /* set Loop Back Address */
- LBAO = runtime->dma_addr;
- if (voice->memblk)
- voice->LBA = voice->memblk->offset;
- else
- voice->LBA = LBAO;
-
- voice->isync = 1;
- voice->isync3 = 1;
- voice->isync_mark = runtime->period_size;
- voice->isync_max = runtime->buffer_size;
-
- /* set target ESO for channel */
- RESO = runtime->buffer_size - 1;
- voice->ESO = voice->isync_ESO = (runtime->period_size * 2) + 6 - 1;
-
- /* set ctrl mode */
- voice->CTRL = snd_trident_control_mode(substream);
-
- voice->FMC = 3;
- voice->RVol = 0x7f;
- voice->CVol = 0x7f;
- voice->GVSel = 1;
- voice->Pan = 0x7f;
- voice->Vol = 0x3ff;
- voice->EC = 0;
- voice->CSO = 0;
- voice->Alpha = 0;
- voice->FMS = 0;
- voice->Attribute = 0;
-
- /* prepare surrogate IRQ channel */
- snd_trident_write_voice_regs(trident, voice);
-
- outw((RESO & 0xffff), TRID_REG(trident, NX_SPESO));
- outb((RESO >> 16), TRID_REG(trident, NX_SPESO + 2));
- outl((LBAO & 0xfffffffc), TRID_REG(trident, NX_SPLBA));
- outw((voice->CSO & 0xffff), TRID_REG(trident, NX_SPCTRL_SPCSO));
- outb((voice->CSO >> 16), TRID_REG(trident, NX_SPCTRL_SPCSO + 2));
-
- /* set SPDIF setting */
- outb(trident->spdif_pcm_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
- outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS));
-
- } else { /* SiS */
-
- /* set delta (rate) value */
- voice->Delta = 0x800;
- voice->spurious_threshold = snd_trident_spurious_threshold(48000, runtime->period_size);
-
- /* set Loop Begin Address */
- if (voice->memblk)
- voice->LBA = voice->memblk->offset;
- else
- voice->LBA = runtime->dma_addr;
-
- voice->CSO = 0;
- voice->ESO = runtime->buffer_size - 1; /* in samples */
- voice->CTRL = snd_trident_control_mode(substream);
- voice->FMC = 3;
- voice->GVSel = 1;
- voice->EC = 0;
- voice->Alpha = 0;
- voice->FMS = 0;
- voice->Vol = mix->vol;
- voice->RVol = mix->rvol;
- voice->CVol = mix->cvol;
- voice->Pan = mix->pan;
- voice->Attribute = (1<<(30-16))|(7<<(26-16))|
- (0<<(24-16))|(0<<(19-16));
-
- snd_trident_write_voice_regs(trident, voice);
-
- if (evoice != NULL) {
- evoice->Delta = voice->Delta;
- evoice->spurious_threshold = voice->spurious_threshold;
- evoice->LBA = voice->LBA;
- evoice->CSO = 0;
- evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */
- evoice->CTRL = voice->CTRL;
- evoice->FMC = 3;
- evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1;
- evoice->EC = 0;
- evoice->Alpha = 0;
- evoice->FMS = 0;
- evoice->Vol = 0x3ff; /* mute */
- evoice->RVol = evoice->CVol = 0x7f; /* mute */
- evoice->Pan = 0x7f; /* mute */
- evoice->Attribute = 0;
- snd_trident_write_voice_regs(trident, evoice);
- evoice->isync2 = 1;
- evoice->isync_mark = runtime->period_size;
- evoice->ESO = (runtime->period_size * 2) - 1;
- }
-
- outl(trident->spdif_pcm_bits, TRID_REG(trident, SI_SPDIF_CS));
- temp = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
- temp &= ~(1<<19);
- outl(temp, TRID_REG(trident, T4D_LFO_GC_CIR));
- temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL));
- temp |= SPDIF_EN;
- outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
- }
-
- spin_unlock_irq(&trident->reg_lock);
-
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_trigger
-
- Description: Start/stop devices
-
- Parameters: substream - PCM substream class
- cmd - trigger command (STOP, GO)
-
- Returns: Error status
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_trigger(struct snd_pcm_substream *substream,
- int cmd)
-
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- struct snd_pcm_substream *s;
- unsigned int what, whati, capture_flag, spdif_flag;
- struct snd_trident_voice *voice, *evoice;
- unsigned int val, go;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
- go = 1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- go = 0;
- break;
- default:
- return -EINVAL;
- }
- what = whati = capture_flag = spdif_flag = 0;
- spin_lock(&trident->reg_lock);
- val = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff;
- snd_pcm_group_for_each_entry(s, substream) {
- if ((struct snd_trident *) snd_pcm_substream_chip(s) == trident) {
- voice = s->runtime->private_data;
- evoice = voice->extra;
- what |= 1 << (voice->number & 0x1f);
- if (evoice == NULL) {
- whati |= 1 << (voice->number & 0x1f);
- } else {
- what |= 1 << (evoice->number & 0x1f);
- whati |= 1 << (evoice->number & 0x1f);
- if (go)
- evoice->stimer = val;
- }
- if (go) {
- voice->running = 1;
- voice->stimer = val;
- } else {
- voice->running = 0;
- }
- snd_pcm_trigger_done(s, substream);
- if (voice->capture)
- capture_flag = 1;
- if (voice->spdif)
- spdif_flag = 1;
- }
- }
- if (spdif_flag) {
- if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
- outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS));
- val = trident->spdif_pcm_ctrl;
- if (!go)
- val &= ~(0x28);
- outb(val, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
- } else {
- outl(trident->spdif_pcm_bits, TRID_REG(trident, SI_SPDIF_CS));
- val = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) | SPDIF_EN;
- outl(val, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
- }
- }
- if (!go)
- outl(what, TRID_REG(trident, T4D_STOP_B));
- val = inl(TRID_REG(trident, T4D_AINTEN_B));
- if (go) {
- val |= whati;
- } else {
- val &= ~whati;
- }
- outl(val, TRID_REG(trident, T4D_AINTEN_B));
- if (go) {
- outl(what, TRID_REG(trident, T4D_START_B));
-
- if (capture_flag && trident->device != TRIDENT_DEVICE_ID_SI7018)
- outb(trident->bDMAStart, TRID_REG(trident, T4D_SBCTRL_SBE2R_SBDD));
- } else {
- if (capture_flag && trident->device != TRIDENT_DEVICE_ID_SI7018)
- outb(0x00, TRID_REG(trident, T4D_SBCTRL_SBE2R_SBDD));
- }
- spin_unlock(&trident->reg_lock);
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_playback_pointer
-
- Description: This routine return the playback position
-
- Parameters: substream - PCM substream class
-
- Returns: position of buffer
-
- ---------------------------------------------------------------------------*/
-
-static snd_pcm_uframes_t snd_trident_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_trident_voice *voice = runtime->private_data;
- unsigned int cso;
-
- if (!voice->running)
- return 0;
-
- spin_lock(&trident->reg_lock);
-
- outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
-
- if (trident->device != TRIDENT_DEVICE_ID_NX) {
- cso = inw(TRID_REG(trident, CH_DX_CSO_ALPHA_FMS + 2));
- } else { // ID_4DWAVE_NX
- cso = (unsigned int) inl(TRID_REG(trident, CH_NX_DELTA_CSO)) & 0x00ffffff;
- }
-
- spin_unlock(&trident->reg_lock);
-
- if (cso >= runtime->buffer_size)
- cso = 0;
-
- return cso;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_capture_pointer
-
- Description: This routine return the capture position
-
- Parameters: pcm1 - PCM device class
-
- Returns: position of buffer
-
- ---------------------------------------------------------------------------*/
-
-static snd_pcm_uframes_t snd_trident_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_trident_voice *voice = runtime->private_data;
- unsigned int result;
-
- if (!voice->running)
- return 0;
-
- result = inw(TRID_REG(trident, T4D_SBBL_SBCL));
- if (runtime->channels > 1)
- result >>= 1;
- if (result > 0)
- result = runtime->buffer_size - result;
-
- return result;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_spdif_pointer
-
- Description: This routine return the SPDIF playback position
-
- Parameters: substream - PCM substream class
-
- Returns: position of buffer
-
- ---------------------------------------------------------------------------*/
-
-static snd_pcm_uframes_t snd_trident_spdif_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_trident_voice *voice = runtime->private_data;
- unsigned int result;
-
- if (!voice->running)
- return 0;
-
- result = inl(TRID_REG(trident, NX_SPCTRL_SPCSO)) & 0x00ffffff;
-
- return result;
-}
-
-/*
- * Playback support device description
- */
-
-static struct snd_pcm_hardware snd_trident_playback =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
- SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */),
- .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (256*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (256*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-/*
- * Capture support device description
- */
-
-static struct snd_pcm_hardware snd_trident_capture =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
- SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */),
- .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 4000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-/*
- * Foldback capture support device description
- */
-
-static struct snd_pcm_hardware snd_trident_foldback =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
- SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-/*
- * SPDIF playback support device description
- */
-
-static struct snd_pcm_hardware snd_trident_spdif =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
- SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000),
- .rate_min = 32000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_trident_spdif_7018 =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
- SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 1,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static void snd_trident_pcm_free_substream(struct snd_pcm_runtime *runtime)
-{
- struct snd_trident_voice *voice = runtime->private_data;
- struct snd_trident *trident;
-
- if (voice) {
- trident = voice->trident;
- snd_trident_free_voice(trident, voice);
- }
-}
-
-static int snd_trident_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_trident_voice *voice;
-
- voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
- if (voice == NULL)
- return -EAGAIN;
- snd_trident_pcm_mixer_build(trident, voice, substream);
- voice->substream = substream;
- runtime->private_data = voice;
- runtime->private_free = snd_trident_pcm_free_substream;
- runtime->hw = snd_trident_playback;
- snd_pcm_set_sync(substream);
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_playback_close
-
- Description: This routine will close the 4DWave playback device. For now
- we will simply free the dma transfer buffer.
-
- Parameters: substream - PCM substream class
-
- ---------------------------------------------------------------------------*/
-static int snd_trident_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_trident_voice *voice = runtime->private_data;
-
- snd_trident_pcm_mixer_free(trident, voice, substream);
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_spdif_open
-
- Description: This routine will open the 4DWave SPDIF device.
-
- Parameters: substream - PCM substream class
-
- Returns: status - success or failure flag
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_spdif_open(struct snd_pcm_substream *substream)
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- struct snd_trident_voice *voice;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
- if (voice == NULL)
- return -EAGAIN;
- voice->spdif = 1;
- voice->substream = substream;
- spin_lock_irq(&trident->reg_lock);
- trident->spdif_pcm_bits = trident->spdif_bits;
- spin_unlock_irq(&trident->reg_lock);
-
- runtime->private_data = voice;
- runtime->private_free = snd_trident_pcm_free_substream;
- if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
- runtime->hw = snd_trident_spdif;
- } else {
- runtime->hw = snd_trident_spdif_7018;
- }
-
- trident->spdif_pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO, &trident->spdif_pcm_ctl->id);
-
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
- return 0;
-}
-
-
-/*---------------------------------------------------------------------------
- snd_trident_spdif_close
-
- Description: This routine will close the 4DWave SPDIF device.
-
- Parameters: substream - PCM substream class
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_spdif_close(struct snd_pcm_substream *substream)
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- unsigned int temp;
-
- spin_lock_irq(&trident->reg_lock);
- // restore default SPDIF setting
- if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
- outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
- outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
- } else {
- outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
- temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL));
- if (trident->spdif_ctrl) {
- temp |= SPDIF_EN;
- } else {
- temp &= ~SPDIF_EN;
- }
- outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
- }
- spin_unlock_irq(&trident->reg_lock);
- trident->spdif_pcm_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO, &trident->spdif_pcm_ctl->id);
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_capture_open
-
- Description: This routine will open the 4DWave capture device.
-
- Parameters: substream - PCM substream class
-
- Returns: status - success or failure flag
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- struct snd_trident_voice *voice;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
- if (voice == NULL)
- return -EAGAIN;
- voice->capture = 1;
- voice->substream = substream;
- runtime->private_data = voice;
- runtime->private_free = snd_trident_pcm_free_substream;
- runtime->hw = snd_trident_capture;
- snd_pcm_set_sync(substream);
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_capture_close
-
- Description: This routine will close the 4DWave capture device. For now
- we will simply free the dma transfer buffer.
-
- Parameters: substream - PCM substream class
-
- ---------------------------------------------------------------------------*/
-static int snd_trident_capture_close(struct snd_pcm_substream *substream)
-{
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_foldback_open
-
- Description: This routine will open the 4DWave foldback capture device.
-
- Parameters: substream - PCM substream class
-
- Returns: status - success or failure flag
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_foldback_open(struct snd_pcm_substream *substream)
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- struct snd_trident_voice *voice;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
- if (voice == NULL)
- return -EAGAIN;
- voice->foldback_chan = substream->number;
- voice->substream = substream;
- runtime->private_data = voice;
- runtime->private_free = snd_trident_pcm_free_substream;
- runtime->hw = snd_trident_foldback;
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_foldback_close
-
- Description: This routine will close the 4DWave foldback capture device.
- For now we will simply free the dma transfer buffer.
-
- Parameters: substream - PCM substream class
-
- ---------------------------------------------------------------------------*/
-static int snd_trident_foldback_close(struct snd_pcm_substream *substream)
-{
- struct snd_trident *trident = snd_pcm_substream_chip(substream);
- struct snd_trident_voice *voice;
- struct snd_pcm_runtime *runtime = substream->runtime;
- voice = runtime->private_data;
-
- /* stop capture channel */
- spin_lock_irq(&trident->reg_lock);
- outb(0x00, TRID_REG(trident, T4D_RCI + voice->foldback_chan));
- spin_unlock_irq(&trident->reg_lock);
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- PCM operations
- ---------------------------------------------------------------------------*/
-
-static struct snd_pcm_ops snd_trident_playback_ops = {
- .open = snd_trident_playback_open,
- .close = snd_trident_playback_close,
- .ioctl = snd_trident_ioctl,
- .hw_params = snd_trident_hw_params,
- .hw_free = snd_trident_hw_free,
- .prepare = snd_trident_playback_prepare,
- .trigger = snd_trident_trigger,
- .pointer = snd_trident_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_trident_nx_playback_ops = {
- .open = snd_trident_playback_open,
- .close = snd_trident_playback_close,
- .ioctl = snd_trident_ioctl,
- .hw_params = snd_trident_hw_params,
- .hw_free = snd_trident_hw_free,
- .prepare = snd_trident_playback_prepare,
- .trigger = snd_trident_trigger,
- .pointer = snd_trident_playback_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
-static struct snd_pcm_ops snd_trident_capture_ops = {
- .open = snd_trident_capture_open,
- .close = snd_trident_capture_close,
- .ioctl = snd_trident_ioctl,
- .hw_params = snd_trident_capture_hw_params,
- .hw_free = snd_trident_hw_free,
- .prepare = snd_trident_capture_prepare,
- .trigger = snd_trident_trigger,
- .pointer = snd_trident_capture_pointer,
-};
-
-static struct snd_pcm_ops snd_trident_si7018_capture_ops = {
- .open = snd_trident_capture_open,
- .close = snd_trident_capture_close,
- .ioctl = snd_trident_ioctl,
- .hw_params = snd_trident_si7018_capture_hw_params,
- .hw_free = snd_trident_si7018_capture_hw_free,
- .prepare = snd_trident_si7018_capture_prepare,
- .trigger = snd_trident_trigger,
- .pointer = snd_trident_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_trident_foldback_ops = {
- .open = snd_trident_foldback_open,
- .close = snd_trident_foldback_close,
- .ioctl = snd_trident_ioctl,
- .hw_params = snd_trident_hw_params,
- .hw_free = snd_trident_hw_free,
- .prepare = snd_trident_foldback_prepare,
- .trigger = snd_trident_trigger,
- .pointer = snd_trident_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_trident_nx_foldback_ops = {
- .open = snd_trident_foldback_open,
- .close = snd_trident_foldback_close,
- .ioctl = snd_trident_ioctl,
- .hw_params = snd_trident_hw_params,
- .hw_free = snd_trident_hw_free,
- .prepare = snd_trident_foldback_prepare,
- .trigger = snd_trident_trigger,
- .pointer = snd_trident_playback_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
-static struct snd_pcm_ops snd_trident_spdif_ops = {
- .open = snd_trident_spdif_open,
- .close = snd_trident_spdif_close,
- .ioctl = snd_trident_ioctl,
- .hw_params = snd_trident_spdif_hw_params,
- .hw_free = snd_trident_hw_free,
- .prepare = snd_trident_spdif_prepare,
- .trigger = snd_trident_trigger,
- .pointer = snd_trident_spdif_pointer,
-};
-
-static struct snd_pcm_ops snd_trident_spdif_7018_ops = {
- .open = snd_trident_spdif_open,
- .close = snd_trident_spdif_close,
- .ioctl = snd_trident_ioctl,
- .hw_params = snd_trident_spdif_hw_params,
- .hw_free = snd_trident_hw_free,
- .prepare = snd_trident_spdif_prepare,
- .trigger = snd_trident_trigger,
- .pointer = snd_trident_playback_pointer,
-};
-
-/*---------------------------------------------------------------------------
- snd_trident_pcm
-
- Description: This routine registers the 4DWave device for PCM support.
-
- Parameters: trident - pointer to target device class for 4DWave.
-
- Returns: None
-
- ---------------------------------------------------------------------------*/
-
-int __devinit snd_trident_pcm(struct snd_trident * trident,
- int device, struct snd_pcm ** rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
- if ((err = snd_pcm_new(trident->card, "trident_dx_nx", device, trident->ChanPCM, 1, &pcm)) < 0)
- return err;
-
- pcm->private_data = trident;
-
- if (trident->tlb.entries) {
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_nx_playback_ops);
- } else {
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_playback_ops);
- }
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- trident->device != TRIDENT_DEVICE_ID_SI7018 ?
- &snd_trident_capture_ops :
- &snd_trident_si7018_capture_ops);
-
- pcm->info_flags = 0;
- pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
- strcpy(pcm->name, "Trident 4DWave");
- trident->pcm = pcm;
-
- if (trident->tlb.entries) {
- struct snd_pcm_substream *substream;
- for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)
- snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(trident->pci),
- 64*1024, 128*1024);
- snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
- SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci),
- 64*1024, 128*1024);
- } else {
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(trident->pci), 64*1024, 128*1024);
- }
-
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_foldback_pcm
-
- Description: This routine registers the 4DWave device for foldback PCM support.
-
- Parameters: trident - pointer to target device class for 4DWave.
-
- Returns: None
-
- ---------------------------------------------------------------------------*/
-
-int __devinit snd_trident_foldback_pcm(struct snd_trident * trident,
- int device, struct snd_pcm ** rpcm)
-{
- struct snd_pcm *foldback;
- int err;
- int num_chan = 3;
- struct snd_pcm_substream *substream;
-
- if (rpcm)
- *rpcm = NULL;
- if (trident->device == TRIDENT_DEVICE_ID_NX)
- num_chan = 4;
- if ((err = snd_pcm_new(trident->card, "trident_dx_nx", device, 0, num_chan, &foldback)) < 0)
- return err;
-
- foldback->private_data = trident;
- if (trident->tlb.entries)
- snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_nx_foldback_ops);
- else
- snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_foldback_ops);
- foldback->info_flags = 0;
- strcpy(foldback->name, "Trident 4DWave");
- substream = foldback->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
- strcpy(substream->name, "Front Mixer");
- substream = substream->next;
- strcpy(substream->name, "Reverb Mixer");
- substream = substream->next;
- strcpy(substream->name, "Chorus Mixer");
- if (num_chan == 4) {
- substream = substream->next;
- strcpy(substream->name, "Second AC'97 ADC");
- }
- trident->foldback = foldback;
-
- if (trident->tlb.entries)
- snd_pcm_lib_preallocate_pages_for_all(foldback, SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(trident->pci), 0, 128*1024);
- else
- snd_pcm_lib_preallocate_pages_for_all(foldback, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(trident->pci), 64*1024, 128*1024);
-
- if (rpcm)
- *rpcm = foldback;
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_spdif
-
- Description: This routine registers the 4DWave-NX device for SPDIF support.
-
- Parameters: trident - pointer to target device class for 4DWave-NX.
-
- Returns: None
-
- ---------------------------------------------------------------------------*/
-
-int __devinit snd_trident_spdif_pcm(struct snd_trident * trident,
- int device, struct snd_pcm ** rpcm)
-{
- struct snd_pcm *spdif;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
- if ((err = snd_pcm_new(trident->card, "trident_dx_nx IEC958", device, 1, 0, &spdif)) < 0)
- return err;
-
- spdif->private_data = trident;
- if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
- snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_ops);
- } else {
- snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_7018_ops);
- }
- spdif->info_flags = 0;
- strcpy(spdif->name, "Trident 4DWave IEC958");
- trident->spdif = spdif;
-
- snd_pcm_lib_preallocate_pages_for_all(spdif, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci), 64*1024, 128*1024);
-
- if (rpcm)
- *rpcm = spdif;
- return 0;
-}
-
-/*
- * Mixer part
- */
-
-
-/*---------------------------------------------------------------------------
- snd_trident_spdif_control
-
- Description: enable/disable S/PDIF out from ac97 mixer
- ---------------------------------------------------------------------------*/
-
-#define snd_trident_spdif_control_info snd_ctl_boolean_mono_info
-
-static int snd_trident_spdif_control_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
- unsigned char val;
-
- spin_lock_irq(&trident->reg_lock);
- val = trident->spdif_ctrl;
- ucontrol->value.integer.value[0] = val == kcontrol->private_value;
- spin_unlock_irq(&trident->reg_lock);
- return 0;
-}
-
-static int snd_trident_spdif_control_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
- unsigned char val;
- int change;
-
- val = ucontrol->value.integer.value[0] ? (unsigned char) kcontrol->private_value : 0x00;
- spin_lock_irq(&trident->reg_lock);
- /* S/PDIF C Channel bits 0-31 : 48khz, SCMS disabled */
- change = trident->spdif_ctrl != val;
- trident->spdif_ctrl = val;
- if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
- if ((inb(TRID_REG(trident, NX_SPCTRL_SPCSO + 3)) & 0x10) == 0) {
- outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
- outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
- }
- } else {
- if (trident->spdif == NULL) {
- unsigned int temp;
- outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
- temp = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & ~SPDIF_EN;
- if (val)
- temp |= SPDIF_EN;
- outl(temp, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
- }
- }
- spin_unlock_irq(&trident->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_trident_spdif_control __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),
- .info = snd_trident_spdif_control_info,
- .get = snd_trident_spdif_control_get,
- .put = snd_trident_spdif_control_put,
- .private_value = 0x28,
-};
-
-/*---------------------------------------------------------------------------
- snd_trident_spdif_default
-
- Description: put/get the S/PDIF default settings
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_spdif_default_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_trident_spdif_default_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&trident->reg_lock);
- ucontrol->value.iec958.status[0] = (trident->spdif_bits >> 0) & 0xff;
- ucontrol->value.iec958.status[1] = (trident->spdif_bits >> 8) & 0xff;
- ucontrol->value.iec958.status[2] = (trident->spdif_bits >> 16) & 0xff;
- ucontrol->value.iec958.status[3] = (trident->spdif_bits >> 24) & 0xff;
- spin_unlock_irq(&trident->reg_lock);
- return 0;
-}
-
-static int snd_trident_spdif_default_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change;
-
- val = (ucontrol->value.iec958.status[0] << 0) |
- (ucontrol->value.iec958.status[1] << 8) |
- (ucontrol->value.iec958.status[2] << 16) |
- (ucontrol->value.iec958.status[3] << 24);
- spin_lock_irq(&trident->reg_lock);
- change = trident->spdif_bits != val;
- trident->spdif_bits = val;
- if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
- if ((inb(TRID_REG(trident, NX_SPCTRL_SPCSO + 3)) & 0x10) == 0)
- outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
- } else {
- if (trident->spdif == NULL)
- outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
- }
- spin_unlock_irq(&trident->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_trident_spdif_default __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
- .info = snd_trident_spdif_default_info,
- .get = snd_trident_spdif_default_get,
- .put = snd_trident_spdif_default_put
-};
-
-/*---------------------------------------------------------------------------
- snd_trident_spdif_mask
-
- Description: put/get the S/PDIF mask
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_spdif_mask_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_trident_spdif_mask_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.iec958.status[0] = 0xff;
- ucontrol->value.iec958.status[1] = 0xff;
- ucontrol->value.iec958.status[2] = 0xff;
- ucontrol->value.iec958.status[3] = 0xff;
- return 0;
-}
-
-static struct snd_kcontrol_new snd_trident_spdif_mask __devinitdata =
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
- .info = snd_trident_spdif_mask_info,
- .get = snd_trident_spdif_mask_get,
-};
-
-/*---------------------------------------------------------------------------
- snd_trident_spdif_stream
-
- Description: put/get the S/PDIF stream settings
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_spdif_stream_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_trident_spdif_stream_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&trident->reg_lock);
- ucontrol->value.iec958.status[0] = (trident->spdif_pcm_bits >> 0) & 0xff;
- ucontrol->value.iec958.status[1] = (trident->spdif_pcm_bits >> 8) & 0xff;
- ucontrol->value.iec958.status[2] = (trident->spdif_pcm_bits >> 16) & 0xff;
- ucontrol->value.iec958.status[3] = (trident->spdif_pcm_bits >> 24) & 0xff;
- spin_unlock_irq(&trident->reg_lock);
- return 0;
-}
-
-static int snd_trident_spdif_stream_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change;
-
- val = (ucontrol->value.iec958.status[0] << 0) |
- (ucontrol->value.iec958.status[1] << 8) |
- (ucontrol->value.iec958.status[2] << 16) |
- (ucontrol->value.iec958.status[3] << 24);
- spin_lock_irq(&trident->reg_lock);
- change = trident->spdif_pcm_bits != val;
- trident->spdif_pcm_bits = val;
- if (trident->spdif != NULL) {
- if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
- outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS));
- } else {
- outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
- }
- }
- spin_unlock_irq(&trident->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_trident_spdif_stream __devinitdata =
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
- .info = snd_trident_spdif_stream_info,
- .get = snd_trident_spdif_stream_get,
- .put = snd_trident_spdif_stream_put
-};
-
-/*---------------------------------------------------------------------------
- snd_trident_ac97_control
-
- Description: enable/disable rear path for ac97
- ---------------------------------------------------------------------------*/
-
-#define snd_trident_ac97_control_info snd_ctl_boolean_mono_info
-
-static int snd_trident_ac97_control_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
- unsigned char val;
-
- spin_lock_irq(&trident->reg_lock);
- val = trident->ac97_ctrl = inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
- ucontrol->value.integer.value[0] = (val & (1 << kcontrol->private_value)) ? 1 : 0;
- spin_unlock_irq(&trident->reg_lock);
- return 0;
-}
-
-static int snd_trident_ac97_control_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
- unsigned char val;
- int change = 0;
-
- spin_lock_irq(&trident->reg_lock);
- val = trident->ac97_ctrl = inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
- val &= ~(1 << kcontrol->private_value);
- if (ucontrol->value.integer.value[0])
- val |= 1 << kcontrol->private_value;
- change = val != trident->ac97_ctrl;
- trident->ac97_ctrl = val;
- outl(trident->ac97_ctrl = val, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
- spin_unlock_irq(&trident->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_trident_ac97_rear_control __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Rear Path",
- .info = snd_trident_ac97_control_info,
- .get = snd_trident_ac97_control_get,
- .put = snd_trident_ac97_control_put,
- .private_value = 4,
-};
-
-/*---------------------------------------------------------------------------
- snd_trident_vol_control
-
- Description: wave & music volume control
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_vol_control_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 255;
- return 0;
-}
-
-static int snd_trident_vol_control_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
- unsigned int val;
-
- val = trident->musicvol_wavevol;
- ucontrol->value.integer.value[0] = 255 - ((val >> kcontrol->private_value) & 0xff);
- ucontrol->value.integer.value[1] = 255 - ((val >> (kcontrol->private_value + 8)) & 0xff);
- return 0;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_gvol, -6375, 25, 0);
-
-static int snd_trident_vol_control_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change = 0;
-
- spin_lock_irq(&trident->reg_lock);
- val = trident->musicvol_wavevol;
- val &= ~(0xffff << kcontrol->private_value);
- val |= ((255 - (ucontrol->value.integer.value[0] & 0xff)) |
- ((255 - (ucontrol->value.integer.value[1] & 0xff)) << 8)) << kcontrol->private_value;
- change = val != trident->musicvol_wavevol;
- outl(trident->musicvol_wavevol = val, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
- spin_unlock_irq(&trident->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_trident_vol_music_control __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Music Playback Volume",
- .info = snd_trident_vol_control_info,
- .get = snd_trident_vol_control_get,
- .put = snd_trident_vol_control_put,
- .private_value = 16,
- .tlv = { .p = db_scale_gvol },
-};
-
-static struct snd_kcontrol_new snd_trident_vol_wave_control __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Wave Playback Volume",
- .info = snd_trident_vol_control_info,
- .get = snd_trident_vol_control_get,
- .put = snd_trident_vol_control_put,
- .private_value = 0,
- .tlv = { .p = db_scale_gvol },
-};
-
-/*---------------------------------------------------------------------------
- snd_trident_pcm_vol_control
-
- Description: PCM front volume control
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_pcm_vol_control_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 255;
- if (trident->device == TRIDENT_DEVICE_ID_SI7018)
- uinfo->value.integer.max = 1023;
- return 0;
-}
-
-static int snd_trident_pcm_vol_control_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
- struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
-
- if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
- ucontrol->value.integer.value[0] = 1023 - mix->vol;
- } else {
- ucontrol->value.integer.value[0] = 255 - (mix->vol>>2);
- }
- return 0;
-}
-
-static int snd_trident_pcm_vol_control_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
- struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
- unsigned int val;
- int change = 0;
-
- if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
- val = 1023 - (ucontrol->value.integer.value[0] & 1023);
- } else {
- val = (255 - (ucontrol->value.integer.value[0] & 255)) << 2;
- }
- spin_lock_irq(&trident->reg_lock);
- change = val != mix->vol;
- mix->vol = val;
- if (mix->voice != NULL)
- snd_trident_write_vol_reg(trident, mix->voice, val);
- spin_unlock_irq(&trident->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_trident_pcm_vol_control __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Front Playback Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .count = 32,
- .info = snd_trident_pcm_vol_control_info,
- .get = snd_trident_pcm_vol_control_get,
- .put = snd_trident_pcm_vol_control_put,
- /* FIXME: no tlv yet */
-};
-
-/*---------------------------------------------------------------------------
- snd_trident_pcm_pan_control
-
- Description: PCM front pan control
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_pcm_pan_control_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 127;
- return 0;
-}
-
-static int snd_trident_pcm_pan_control_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
- struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
-
- ucontrol->value.integer.value[0] = mix->pan;
- if (ucontrol->value.integer.value[0] & 0x40) {
- ucontrol->value.integer.value[0] = (0x3f - (ucontrol->value.integer.value[0] & 0x3f));
- } else {
- ucontrol->value.integer.value[0] |= 0x40;
- }
- return 0;
-}
-
-static int snd_trident_pcm_pan_control_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
- struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
- unsigned char val;
- int change = 0;
-
- if (ucontrol->value.integer.value[0] & 0x40)
- val = ucontrol->value.integer.value[0] & 0x3f;
- else
- val = (0x3f - (ucontrol->value.integer.value[0] & 0x3f)) | 0x40;
- spin_lock_irq(&trident->reg_lock);
- change = val != mix->pan;
- mix->pan = val;
- if (mix->voice != NULL)
- snd_trident_write_pan_reg(trident, mix->voice, val);
- spin_unlock_irq(&trident->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_trident_pcm_pan_control __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Pan Playback Control",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .count = 32,
- .info = snd_trident_pcm_pan_control_info,
- .get = snd_trident_pcm_pan_control_get,
- .put = snd_trident_pcm_pan_control_put,
-};
-
-/*---------------------------------------------------------------------------
- snd_trident_pcm_rvol_control
-
- Description: PCM reverb volume control
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_pcm_rvol_control_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 127;
- return 0;
-}
-
-static int snd_trident_pcm_rvol_control_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
- struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
-
- ucontrol->value.integer.value[0] = 127 - mix->rvol;
- return 0;
-}
-
-static int snd_trident_pcm_rvol_control_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
- struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
- unsigned short val;
- int change = 0;
-
- val = 0x7f - (ucontrol->value.integer.value[0] & 0x7f);
- spin_lock_irq(&trident->reg_lock);
- change = val != mix->rvol;
- mix->rvol = val;
- if (mix->voice != NULL)
- snd_trident_write_rvol_reg(trident, mix->voice, val);
- spin_unlock_irq(&trident->reg_lock);
- return change;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_crvol, -3175, 25, 1);
-
-static struct snd_kcontrol_new snd_trident_pcm_rvol_control __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Reverb Playback Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .count = 32,
- .info = snd_trident_pcm_rvol_control_info,
- .get = snd_trident_pcm_rvol_control_get,
- .put = snd_trident_pcm_rvol_control_put,
- .tlv = { .p = db_scale_crvol },
-};
-
-/*---------------------------------------------------------------------------
- snd_trident_pcm_cvol_control
-
- Description: PCM chorus volume control
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_pcm_cvol_control_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 127;
- return 0;
-}
-
-static int snd_trident_pcm_cvol_control_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
- struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
-
- ucontrol->value.integer.value[0] = 127 - mix->cvol;
- return 0;
-}
-
-static int snd_trident_pcm_cvol_control_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
- struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
- unsigned short val;
- int change = 0;
-
- val = 0x7f - (ucontrol->value.integer.value[0] & 0x7f);
- spin_lock_irq(&trident->reg_lock);
- change = val != mix->cvol;
- mix->cvol = val;
- if (mix->voice != NULL)
- snd_trident_write_cvol_reg(trident, mix->voice, val);
- spin_unlock_irq(&trident->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_trident_pcm_cvol_control __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Chorus Playback Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .count = 32,
- .info = snd_trident_pcm_cvol_control_info,
- .get = snd_trident_pcm_cvol_control_get,
- .put = snd_trident_pcm_cvol_control_put,
- .tlv = { .p = db_scale_crvol },
-};
-
-static void snd_trident_notify_pcm_change1(struct snd_card *card,
- struct snd_kcontrol *kctl,
- int num, int activate)
-{
- struct snd_ctl_elem_id id;
-
- if (! kctl)
- return;
- if (activate)
- kctl->vd[num].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- else
- kctl->vd[num].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO,
- snd_ctl_build_ioff(&id, kctl, num));
-}
-
-static void snd_trident_notify_pcm_change(struct snd_trident *trident,
- struct snd_trident_pcm_mixer *tmix,
- int num, int activate)
-{
- snd_trident_notify_pcm_change1(trident->card, trident->ctl_vol, num, activate);
- snd_trident_notify_pcm_change1(trident->card, trident->ctl_pan, num, activate);
- snd_trident_notify_pcm_change1(trident->card, trident->ctl_rvol, num, activate);
- snd_trident_notify_pcm_change1(trident->card, trident->ctl_cvol, num, activate);
-}
-
-static int snd_trident_pcm_mixer_build(struct snd_trident *trident,
- struct snd_trident_voice *voice,
- struct snd_pcm_substream *substream)
-{
- struct snd_trident_pcm_mixer *tmix;
-
- if (snd_BUG_ON(!trident || !voice || !substream))
- return -EINVAL;
- tmix = &trident->pcm_mixer[substream->number];
- tmix->voice = voice;
- tmix->vol = T4D_DEFAULT_PCM_VOL;
- tmix->pan = T4D_DEFAULT_PCM_PAN;
- tmix->rvol = T4D_DEFAULT_PCM_RVOL;
- tmix->cvol = T4D_DEFAULT_PCM_CVOL;
- snd_trident_notify_pcm_change(trident, tmix, substream->number, 1);
- return 0;
-}
-
-static int snd_trident_pcm_mixer_free(struct snd_trident *trident, struct snd_trident_voice *voice, struct snd_pcm_substream *substream)
-{
- struct snd_trident_pcm_mixer *tmix;
-
- if (snd_BUG_ON(!trident || !substream))
- return -EINVAL;
- tmix = &trident->pcm_mixer[substream->number];
- tmix->voice = NULL;
- snd_trident_notify_pcm_change(trident, tmix, substream->number, 0);
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_mixer
-
- Description: This routine registers the 4DWave device for mixer support.
-
- Parameters: trident - pointer to target device class for 4DWave.
-
- Returns: None
-
- ---------------------------------------------------------------------------*/
-
-static int __devinit snd_trident_mixer(struct snd_trident * trident, int pcm_spdif_device)
-{
- struct snd_ac97_template _ac97;
- struct snd_card *card = trident->card;
- struct snd_kcontrol *kctl;
- struct snd_ctl_elem_value *uctl;
- int idx, err, retries = 2;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_trident_codec_write,
- .read = snd_trident_codec_read,
- };
-
- uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
- if (!uctl)
- return -ENOMEM;
-
- if ((err = snd_ac97_bus(trident->card, 0, &ops, NULL, &trident->ac97_bus)) < 0)
- goto __out;
-
- memset(&_ac97, 0, sizeof(_ac97));
- _ac97.private_data = trident;
- trident->ac97_detect = 1;
-
- __again:
- if ((err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97)) < 0) {
- if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
- if ((err = snd_trident_sis_reset(trident)) < 0)
- goto __out;
- if (retries-- > 0)
- goto __again;
- err = -EIO;
- }
- goto __out;
- }
-
- /* secondary codec? */
- if (trident->device == TRIDENT_DEVICE_ID_SI7018 &&
- (inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_PRIMARY_READY) != 0) {
- _ac97.num = 1;
- err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97_sec);
- if (err < 0)
- snd_printk(KERN_ERR "SI7018: the secondary codec - invalid access\n");
-#if 0 // only for my testing purpose --jk
- {
- struct snd_ac97 *mc97;
- err = snd_ac97_modem(trident->card, &_ac97, &mc97);
- if (err < 0)
- snd_printk(KERN_ERR "snd_ac97_modem returned error %i\n", err);
- }
-#endif
- }
-
- trident->ac97_detect = 0;
-
- if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_vol_wave_control, trident))) < 0)
- goto __out;
- kctl->put(kctl, uctl);
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_vol_music_control, trident))) < 0)
- goto __out;
- kctl->put(kctl, uctl);
- outl(trident->musicvol_wavevol = 0x00000000, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
- } else {
- outl(trident->musicvol_wavevol = 0xffff0000, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
- }
-
- for (idx = 0; idx < 32; idx++) {
- struct snd_trident_pcm_mixer *tmix;
-
- tmix = &trident->pcm_mixer[idx];
- tmix->voice = NULL;
- }
- if ((trident->ctl_vol = snd_ctl_new1(&snd_trident_pcm_vol_control, trident)) == NULL)
- goto __nomem;
- if ((err = snd_ctl_add(card, trident->ctl_vol)))
- goto __out;
-
- if ((trident->ctl_pan = snd_ctl_new1(&snd_trident_pcm_pan_control, trident)) == NULL)
- goto __nomem;
- if ((err = snd_ctl_add(card, trident->ctl_pan)))
- goto __out;
-
- if ((trident->ctl_rvol = snd_ctl_new1(&snd_trident_pcm_rvol_control, trident)) == NULL)
- goto __nomem;
- if ((err = snd_ctl_add(card, trident->ctl_rvol)))
- goto __out;
-
- if ((trident->ctl_cvol = snd_ctl_new1(&snd_trident_pcm_cvol_control, trident)) == NULL)
- goto __nomem;
- if ((err = snd_ctl_add(card, trident->ctl_cvol)))
- goto __out;
-
- if (trident->device == TRIDENT_DEVICE_ID_NX) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_ac97_rear_control, trident))) < 0)
- goto __out;
- kctl->put(kctl, uctl);
- }
- if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018) {
-
- kctl = snd_ctl_new1(&snd_trident_spdif_control, trident);
- if (kctl == NULL) {
- err = -ENOMEM;
- goto __out;
- }
- if (trident->ac97->ext_id & AC97_EI_SPDIF)
- kctl->id.index++;
- if (trident->ac97_sec && (trident->ac97_sec->ext_id & AC97_EI_SPDIF))
- kctl->id.index++;
- idx = kctl->id.index;
- if ((err = snd_ctl_add(card, kctl)) < 0)
- goto __out;
- kctl->put(kctl, uctl);
-
- kctl = snd_ctl_new1(&snd_trident_spdif_default, trident);
- if (kctl == NULL) {
- err = -ENOMEM;
- goto __out;
- }
- kctl->id.index = idx;
- kctl->id.device = pcm_spdif_device;
- if ((err = snd_ctl_add(card, kctl)) < 0)
- goto __out;
-
- kctl = snd_ctl_new1(&snd_trident_spdif_mask, trident);
- if (kctl == NULL) {
- err = -ENOMEM;
- goto __out;
- }
- kctl->id.index = idx;
- kctl->id.device = pcm_spdif_device;
- if ((err = snd_ctl_add(card, kctl)) < 0)
- goto __out;
-
- kctl = snd_ctl_new1(&snd_trident_spdif_stream, trident);
- if (kctl == NULL) {
- err = -ENOMEM;
- goto __out;
- }
- kctl->id.index = idx;
- kctl->id.device = pcm_spdif_device;
- if ((err = snd_ctl_add(card, kctl)) < 0)
- goto __out;
- trident->spdif_pcm_ctl = kctl;
- }
-
- err = 0;
- goto __out;
-
- __nomem:
- err = -ENOMEM;
-
- __out:
- kfree(uctl);
-
- return err;
-}
-
-/*
- * gameport interface
- */
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-
-static unsigned char snd_trident_gameport_read(struct gameport *gameport)
-{
- struct snd_trident *chip = gameport_get_port_data(gameport);
-
- if (snd_BUG_ON(!chip))
- return 0;
- return inb(TRID_REG(chip, GAMEPORT_LEGACY));
-}
-
-static void snd_trident_gameport_trigger(struct gameport *gameport)
-{
- struct snd_trident *chip = gameport_get_port_data(gameport);
-
- if (snd_BUG_ON(!chip))
- return;
- outb(0xff, TRID_REG(chip, GAMEPORT_LEGACY));
-}
-
-static int snd_trident_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
-{
- struct snd_trident *chip = gameport_get_port_data(gameport);
- int i;
-
- if (snd_BUG_ON(!chip))
- return 0;
-
- *buttons = (~inb(TRID_REG(chip, GAMEPORT_LEGACY)) >> 4) & 0xf;
-
- for (i = 0; i < 4; i++) {
- axes[i] = inw(TRID_REG(chip, GAMEPORT_AXES + i * 2));
- if (axes[i] == 0xffff) axes[i] = -1;
- }
-
- return 0;
-}
-
-static int snd_trident_gameport_open(struct gameport *gameport, int mode)
-{
- struct snd_trident *chip = gameport_get_port_data(gameport);
-
- if (snd_BUG_ON(!chip))
- return 0;
-
- switch (mode) {
- case GAMEPORT_MODE_COOKED:
- outb(GAMEPORT_MODE_ADC, TRID_REG(chip, GAMEPORT_GCR));
- msleep(20);
- return 0;
- case GAMEPORT_MODE_RAW:
- outb(0, TRID_REG(chip, GAMEPORT_GCR));
- return 0;
- default:
- return -1;
- }
-}
-
-int __devinit snd_trident_create_gameport(struct snd_trident *chip)
-{
- struct gameport *gp;
-
- chip->gameport = gp = gameport_allocate_port();
- if (!gp) {
- printk(KERN_ERR "trident: cannot allocate memory for gameport\n");
- return -ENOMEM;
- }
-
- gameport_set_name(gp, "Trident 4DWave");
- gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
- gameport_set_dev_parent(gp, &chip->pci->dev);
-
- gameport_set_port_data(gp, chip);
- gp->fuzz = 64;
- gp->read = snd_trident_gameport_read;
- gp->trigger = snd_trident_gameport_trigger;
- gp->cooked_read = snd_trident_gameport_cooked_read;
- gp->open = snd_trident_gameport_open;
-
- gameport_register_port(gp);
-
- return 0;
-}
-
-static inline void snd_trident_free_gameport(struct snd_trident *chip)
-{
- if (chip->gameport) {
- gameport_unregister_port(chip->gameport);
- chip->gameport = NULL;
- }
-}
-#else
-int __devinit snd_trident_create_gameport(struct snd_trident *chip) { return -ENOSYS; }
-static inline void snd_trident_free_gameport(struct snd_trident *chip) { }
-#endif /* CONFIG_GAMEPORT */
-
-/*
- * delay for 1 tick
- */
-static inline void do_delay(struct snd_trident *chip)
-{
- schedule_timeout_uninterruptible(1);
-}
-
-/*
- * SiS reset routine
- */
-
-static int snd_trident_sis_reset(struct snd_trident *trident)
-{
- unsigned long end_time;
- unsigned int i;
- int r;
-
- r = trident->in_suspend ? 0 : 2; /* count of retries */
- __si7018_retry:
- pci_write_config_byte(trident->pci, 0x46, 0x04); /* SOFTWARE RESET */
- udelay(100);
- pci_write_config_byte(trident->pci, 0x46, 0x00);
- udelay(100);
- /* disable AC97 GPIO interrupt */
- outb(0x00, TRID_REG(trident, SI_AC97_GPIO));
- /* initialize serial interface, force cold reset */
- i = PCMOUT|SURROUT|CENTEROUT|LFEOUT|SECONDARY_ID|COLD_RESET;
- outl(i, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
- udelay(1000);
- /* remove cold reset */
- i &= ~COLD_RESET;
- outl(i, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
- udelay(2000);
- /* wait, until the codec is ready */
- end_time = (jiffies + (HZ * 3) / 4) + 1;
- do {
- if ((inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_PRIMARY_READY) != 0)
- goto __si7018_ok;
- do_delay(trident);
- } while (time_after_eq(end_time, jiffies));
- snd_printk(KERN_ERR "AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)));
- if (r-- > 0) {
- end_time = jiffies + HZ;
- do {
- do_delay(trident);
- } while (time_after_eq(end_time, jiffies));
- goto __si7018_retry;
- }
- __si7018_ok:
- /* wait for the second codec */
- do {
- if ((inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_SECONDARY_READY) != 0)
- break;
- do_delay(trident);
- } while (time_after_eq(end_time, jiffies));
- /* enable 64 channel mode */
- outl(BANK_B_EN, TRID_REG(trident, T4D_LFO_GC_CIR));
- return 0;
-}
-
-/*
- * /proc interface
- */
-
-static void snd_trident_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_trident *trident = entry->private_data;
- char *s;
-
- switch (trident->device) {
- case TRIDENT_DEVICE_ID_SI7018:
- s = "SiS 7018 Audio";
- break;
- case TRIDENT_DEVICE_ID_DX:
- s = "Trident 4DWave PCI DX";
- break;
- case TRIDENT_DEVICE_ID_NX:
- s = "Trident 4DWave PCI NX";
- break;
- default:
- s = "???";
- }
- snd_iprintf(buffer, "%s\n\n", s);
- snd_iprintf(buffer, "Spurious IRQs : %d\n", trident->spurious_irq_count);
- snd_iprintf(buffer, "Spurious IRQ dlta: %d\n", trident->spurious_irq_max_delta);
- if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018)
- snd_iprintf(buffer, "IEC958 Mixer Out : %s\n", trident->spdif_ctrl == 0x28 ? "on" : "off");
- if (trident->device == TRIDENT_DEVICE_ID_NX) {
- snd_iprintf(buffer, "Rear Speakers : %s\n", trident->ac97_ctrl & 0x00000010 ? "on" : "off");
- if (trident->tlb.entries) {
- snd_iprintf(buffer,"\nVirtual Memory\n");
- snd_iprintf(buffer, "Memory Maximum : %d\n", trident->tlb.memhdr->size);
- snd_iprintf(buffer, "Memory Used : %d\n", trident->tlb.memhdr->used);
- snd_iprintf(buffer, "Memory Free : %d\n", snd_util_mem_avail(trident->tlb.memhdr));
- }
- }
-}
-
-static void __devinit snd_trident_proc_init(struct snd_trident * trident)
-{
- struct snd_info_entry *entry;
- const char *s = "trident";
-
- if (trident->device == TRIDENT_DEVICE_ID_SI7018)
- s = "sis7018";
- if (! snd_card_proc_new(trident->card, s, &entry))
- snd_info_set_text_ops(entry, trident, snd_trident_proc_read);
-}
-
-static int snd_trident_dev_free(struct snd_device *device)
-{
- struct snd_trident *trident = device->device_data;
- return snd_trident_free(trident);
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_tlb_alloc
-
- Description: Allocate and set up the TLB page table on 4D NX.
- Each entry has 4 bytes (physical PCI address).
-
- Parameters: trident - pointer to target device class for 4DWave.
-
- Returns: 0 or negative error code
-
- ---------------------------------------------------------------------------*/
-
-static int __devinit snd_trident_tlb_alloc(struct snd_trident *trident)
-{
- int i;
-
- /* TLB array must be aligned to 16kB !!! so we allocate
- 32kB region and correct offset when necessary */
-
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci),
- 2 * SNDRV_TRIDENT_MAX_PAGES * 4, &trident->tlb.buffer) < 0) {
- snd_printk(KERN_ERR "trident: unable to allocate TLB buffer\n");
- return -ENOMEM;
- }
- trident->tlb.entries = (unsigned int*)ALIGN((unsigned long)trident->tlb.buffer.area, SNDRV_TRIDENT_MAX_PAGES * 4);
- trident->tlb.entries_dmaaddr = ALIGN(trident->tlb.buffer.addr, SNDRV_TRIDENT_MAX_PAGES * 4);
- /* allocate shadow TLB page table (virtual addresses) */
- trident->tlb.shadow_entries = vmalloc(SNDRV_TRIDENT_MAX_PAGES*sizeof(unsigned long));
- if (trident->tlb.shadow_entries == NULL) {
- snd_printk(KERN_ERR "trident: unable to allocate shadow TLB entries\n");
- return -ENOMEM;
- }
- /* allocate and setup silent page and initialise TLB entries */
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci),
- SNDRV_TRIDENT_PAGE_SIZE, &trident->tlb.silent_page) < 0) {
- snd_printk(KERN_ERR "trident: unable to allocate silent page\n");
- return -ENOMEM;
- }
- memset(trident->tlb.silent_page.area, 0, SNDRV_TRIDENT_PAGE_SIZE);
- for (i = 0; i < SNDRV_TRIDENT_MAX_PAGES; i++) {
- trident->tlb.entries[i] = cpu_to_le32(trident->tlb.silent_page.addr & ~(SNDRV_TRIDENT_PAGE_SIZE-1));
- trident->tlb.shadow_entries[i] = (unsigned long)trident->tlb.silent_page.area;
- }
-
- /* use emu memory block manager code to manage tlb page allocation */
- trident->tlb.memhdr = snd_util_memhdr_new(SNDRV_TRIDENT_PAGE_SIZE * SNDRV_TRIDENT_MAX_PAGES);
- if (trident->tlb.memhdr == NULL)
- return -ENOMEM;
-
- trident->tlb.memhdr->block_extra_size = sizeof(struct snd_trident_memblk_arg);
- return 0;
-}
-
-/*
- * initialize 4D DX chip
- */
-
-static void snd_trident_stop_all_voices(struct snd_trident *trident)
-{
- outl(0xffffffff, TRID_REG(trident, T4D_STOP_A));
- outl(0xffffffff, TRID_REG(trident, T4D_STOP_B));
- outl(0, TRID_REG(trident, T4D_AINTEN_A));
- outl(0, TRID_REG(trident, T4D_AINTEN_B));
-}
-
-static int snd_trident_4d_dx_init(struct snd_trident *trident)
-{
- struct pci_dev *pci = trident->pci;
- unsigned long end_time;
-
- /* reset the legacy configuration and whole audio/wavetable block */
- pci_write_config_dword(pci, 0x40, 0); /* DDMA */
- pci_write_config_byte(pci, 0x44, 0); /* ports */
- pci_write_config_byte(pci, 0x45, 0); /* Legacy DMA */
- pci_write_config_byte(pci, 0x46, 4); /* reset */
- udelay(100);
- pci_write_config_byte(pci, 0x46, 0); /* release reset */
- udelay(100);
-
- /* warm reset of the AC'97 codec */
- outl(0x00000001, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
- udelay(100);
- outl(0x00000000, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
- /* DAC on, disable SB IRQ and try to force ADC valid signal */
- trident->ac97_ctrl = 0x0000004a;
- outl(trident->ac97_ctrl, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
- /* wait, until the codec is ready */
- end_time = (jiffies + (HZ * 3) / 4) + 1;
- do {
- if ((inl(TRID_REG(trident, DX_ACR2_AC97_COM_STAT)) & 0x0010) != 0)
- goto __dx_ok;
- do_delay(trident);
- } while (time_after_eq(end_time, jiffies));
- snd_printk(KERN_ERR "AC'97 codec ready error\n");
- return -EIO;
-
- __dx_ok:
- snd_trident_stop_all_voices(trident);
-
- return 0;
-}
-
-/*
- * initialize 4D NX chip
- */
-static int snd_trident_4d_nx_init(struct snd_trident *trident)
-{
- struct pci_dev *pci = trident->pci;
- unsigned long end_time;
-
- /* reset the legacy configuration and whole audio/wavetable block */
- pci_write_config_dword(pci, 0x40, 0); /* DDMA */
- pci_write_config_byte(pci, 0x44, 0); /* ports */
- pci_write_config_byte(pci, 0x45, 0); /* Legacy DMA */
-
- pci_write_config_byte(pci, 0x46, 1); /* reset */
- udelay(100);
- pci_write_config_byte(pci, 0x46, 0); /* release reset */
- udelay(100);
-
- /* warm reset of the AC'97 codec */
- outl(0x00000001, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
- udelay(100);
- outl(0x00000000, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
- /* wait, until the codec is ready */
- end_time = (jiffies + (HZ * 3) / 4) + 1;
- do {
- if ((inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)) & 0x0008) != 0)
- goto __nx_ok;
- do_delay(trident);
- } while (time_after_eq(end_time, jiffies));
- snd_printk(KERN_ERR "AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)));
- return -EIO;
-
- __nx_ok:
- /* DAC on */
- trident->ac97_ctrl = 0x00000002;
- outl(trident->ac97_ctrl, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
- /* disable SB IRQ */
- outl(NX_SB_IRQ_DISABLE, TRID_REG(trident, T4D_MISCINT));
-
- snd_trident_stop_all_voices(trident);
-
- if (trident->tlb.entries != NULL) {
- unsigned int i;
- /* enable virtual addressing via TLB */
- i = trident->tlb.entries_dmaaddr;
- i |= 0x00000001;
- outl(i, TRID_REG(trident, NX_TLBC));
- } else {
- outl(0, TRID_REG(trident, NX_TLBC));
- }
- /* initialize S/PDIF */
- outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
- outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
-
- return 0;
-}
-
-/*
- * initialize sis7018 chip
- */
-static int snd_trident_sis_init(struct snd_trident *trident)
-{
- int err;
-
- if ((err = snd_trident_sis_reset(trident)) < 0)
- return err;
-
- snd_trident_stop_all_voices(trident);
-
- /* initialize S/PDIF */
- outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
-
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_create
-
- Description: This routine will create the device specific class for
- the 4DWave card. It will also perform basic initialization.
-
- Parameters: card - which card to create
- pci - interface to PCI bus resource info
- dma1ptr - playback dma buffer
- dma2ptr - capture dma buffer
- irqptr - interrupt resource info
-
- Returns: 4DWave device class private data
-
- ---------------------------------------------------------------------------*/
-
-int __devinit snd_trident_create(struct snd_card *card,
- struct pci_dev *pci,
- int pcm_streams,
- int pcm_spdif_device,
- int max_wavetable_size,
- struct snd_trident ** rtrident)
-{
- struct snd_trident *trident;
- int i, err;
- struct snd_trident_voice *voice;
- struct snd_trident_pcm_mixer *tmix;
- static struct snd_device_ops ops = {
- .dev_free = snd_trident_dev_free,
- };
-
- *rtrident = NULL;
-
- /* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
- return err;
- /* check, if we can restrict PCI DMA transfers to 30 bits */
- if (pci_set_dma_mask(pci, DMA_BIT_MASK(30)) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(30)) < 0) {
- snd_printk(KERN_ERR "architecture does not support 30bit PCI busmaster DMA\n");
- pci_disable_device(pci);
- return -ENXIO;
- }
-
- trident = kzalloc(sizeof(*trident), GFP_KERNEL);
- if (trident == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
- trident->device = (pci->vendor << 16) | pci->device;
- trident->card = card;
- trident->pci = pci;
- spin_lock_init(&trident->reg_lock);
- spin_lock_init(&trident->event_lock);
- spin_lock_init(&trident->voice_alloc);
- if (pcm_streams < 1)
- pcm_streams = 1;
- if (pcm_streams > 32)
- pcm_streams = 32;
- trident->ChanPCM = pcm_streams;
- if (max_wavetable_size < 0 )
- max_wavetable_size = 0;
- trident->synth.max_size = max_wavetable_size * 1024;
- trident->irq = -1;
-
- trident->midi_port = TRID_REG(trident, T4D_MPU401_BASE);
- pci_set_master(pci);
-
- if ((err = pci_request_regions(pci, "Trident Audio")) < 0) {
- kfree(trident);
- pci_disable_device(pci);
- return err;
- }
- trident->port = pci_resource_start(pci, 0);
-
- if (request_irq(pci->irq, snd_trident_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, trident)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_trident_free(trident);
- return -EBUSY;
- }
- trident->irq = pci->irq;
-
- /* allocate 16k-aligned TLB for NX cards */
- trident->tlb.entries = NULL;
- trident->tlb.buffer.area = NULL;
- if (trident->device == TRIDENT_DEVICE_ID_NX) {
- if ((err = snd_trident_tlb_alloc(trident)) < 0) {
- snd_trident_free(trident);
- return err;
- }
- }
-
- trident->spdif_bits = trident->spdif_pcm_bits = SNDRV_PCM_DEFAULT_CON_SPDIF;
-
- /* initialize chip */
- switch (trident->device) {
- case TRIDENT_DEVICE_ID_DX:
- err = snd_trident_4d_dx_init(trident);
- break;
- case TRIDENT_DEVICE_ID_NX:
- err = snd_trident_4d_nx_init(trident);
- break;
- case TRIDENT_DEVICE_ID_SI7018:
- err = snd_trident_sis_init(trident);
- break;
- default:
- snd_BUG();
- break;
- }
- if (err < 0) {
- snd_trident_free(trident);
- return err;
- }
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, trident, &ops)) < 0) {
- snd_trident_free(trident);
- return err;
- }
-
- if ((err = snd_trident_mixer(trident, pcm_spdif_device)) < 0)
- return err;
-
- /* initialise synth voices */
- for (i = 0; i < 64; i++) {
- voice = &trident->synth.voices[i];
- voice->number = i;
- voice->trident = trident;
- }
- /* initialize pcm mixer entries */
- for (i = 0; i < 32; i++) {
- tmix = &trident->pcm_mixer[i];
- tmix->vol = T4D_DEFAULT_PCM_VOL;
- tmix->pan = T4D_DEFAULT_PCM_PAN;
- tmix->rvol = T4D_DEFAULT_PCM_RVOL;
- tmix->cvol = T4D_DEFAULT_PCM_CVOL;
- }
-
- snd_trident_enable_eso(trident);
-
- snd_trident_proc_init(trident);
- snd_card_set_dev(card, &pci->dev);
- *rtrident = trident;
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_free
-
- Description: This routine will free the device specific class for
- the 4DWave card.
-
- Parameters: trident - device specific private data for 4DWave card
-
- Returns: None.
-
- ---------------------------------------------------------------------------*/
-
-static int snd_trident_free(struct snd_trident *trident)
-{
- snd_trident_free_gameport(trident);
- snd_trident_disable_eso(trident);
- // Disable S/PDIF out
- if (trident->device == TRIDENT_DEVICE_ID_NX)
- outb(0x00, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
- else if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
- outl(0, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
- }
- if (trident->irq >= 0)
- free_irq(trident->irq, trident);
- if (trident->tlb.buffer.area) {
- outl(0, TRID_REG(trident, NX_TLBC));
- if (trident->tlb.memhdr)
- snd_util_memhdr_free(trident->tlb.memhdr);
- if (trident->tlb.silent_page.area)
- snd_dma_free_pages(&trident->tlb.silent_page);
- vfree(trident->tlb.shadow_entries);
- snd_dma_free_pages(&trident->tlb.buffer);
- }
- pci_release_regions(trident->pci);
- pci_disable_device(trident->pci);
- kfree(trident);
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- snd_trident_interrupt
-
- Description: ISR for Trident 4DWave device
-
- Parameters: trident - device specific private data for 4DWave card
-
- Problems: It seems that Trident chips generates interrupts more than
- one time in special cases. The spurious interrupts are
- detected via sample timer (T4D_STIMER) and computing
- corresponding delta value. The limits are detected with
- the method try & fail so it is possible that it won't
- work on all computers. [jaroslav]
-
- Returns: None.
-
- ---------------------------------------------------------------------------*/
-
-static irqreturn_t snd_trident_interrupt(int irq, void *dev_id)
-{
- struct snd_trident *trident = dev_id;
- unsigned int audio_int, chn_int, stimer, channel, mask, tmp;
- int delta;
- struct snd_trident_voice *voice;
-
- audio_int = inl(TRID_REG(trident, T4D_MISCINT));
- if ((audio_int & (ADDRESS_IRQ|MPU401_IRQ)) == 0)
- return IRQ_NONE;
- if (audio_int & ADDRESS_IRQ) {
- // get interrupt status for all channels
- spin_lock(&trident->reg_lock);
- stimer = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff;
- chn_int = inl(TRID_REG(trident, T4D_AINT_A));
- if (chn_int == 0)
- goto __skip1;
- outl(chn_int, TRID_REG(trident, T4D_AINT_A)); /* ack */
- __skip1:
- chn_int = inl(TRID_REG(trident, T4D_AINT_B));
- if (chn_int == 0)
- goto __skip2;
- for (channel = 63; channel >= 32; channel--) {
- mask = 1 << (channel&0x1f);
- if ((chn_int & mask) == 0)
- continue;
- voice = &trident->synth.voices[channel];
- if (!voice->pcm || voice->substream == NULL) {
- outl(mask, TRID_REG(trident, T4D_STOP_B));
- continue;
- }
- delta = (int)stimer - (int)voice->stimer;
- if (delta < 0)
- delta = -delta;
- if ((unsigned int)delta < voice->spurious_threshold) {
- /* do some statistics here */
- trident->spurious_irq_count++;
- if (trident->spurious_irq_max_delta < (unsigned int)delta)
- trident->spurious_irq_max_delta = delta;
- continue;
- }
- voice->stimer = stimer;
- if (voice->isync) {
- if (!voice->isync3) {
- tmp = inw(TRID_REG(trident, T4D_SBBL_SBCL));
- if (trident->bDMAStart & 0x40)
- tmp >>= 1;
- if (tmp > 0)
- tmp = voice->isync_max - tmp;
- } else {
- tmp = inl(TRID_REG(trident, NX_SPCTRL_SPCSO)) & 0x00ffffff;
- }
- if (tmp < voice->isync_mark) {
- if (tmp > 0x10)
- tmp = voice->isync_ESO - 7;
- else
- tmp = voice->isync_ESO + 2;
- /* update ESO for IRQ voice to preserve sync */
- snd_trident_stop_voice(trident, voice->number);
- snd_trident_write_eso_reg(trident, voice, tmp);
- snd_trident_start_voice(trident, voice->number);
- }
- } else if (voice->isync2) {
- voice->isync2 = 0;
- /* write original ESO and update CSO for IRQ voice to preserve sync */
- snd_trident_stop_voice(trident, voice->number);
- snd_trident_write_cso_reg(trident, voice, voice->isync_mark);
- snd_trident_write_eso_reg(trident, voice, voice->ESO);
- snd_trident_start_voice(trident, voice->number);
- }
-#if 0
- if (voice->extra) {
- /* update CSO for extra voice to preserve sync */
- snd_trident_stop_voice(trident, voice->extra->number);
- snd_trident_write_cso_reg(trident, voice->extra, 0);
- snd_trident_start_voice(trident, voice->extra->number);
- }
-#endif
- spin_unlock(&trident->reg_lock);
- snd_pcm_period_elapsed(voice->substream);
- spin_lock(&trident->reg_lock);
- }
- outl(chn_int, TRID_REG(trident, T4D_AINT_B)); /* ack */
- __skip2:
- spin_unlock(&trident->reg_lock);
- }
- if (audio_int & MPU401_IRQ) {
- if (trident->rmidi) {
- snd_mpu401_uart_interrupt(irq, trident->rmidi->private_data);
- } else {
- inb(TRID_REG(trident, T4D_MPUR0));
- }
- }
- // outl((ST_TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW), TRID_REG(trident, T4D_MISCINT));
- return IRQ_HANDLED;
-}
-
-struct snd_trident_voice *snd_trident_alloc_voice(struct snd_trident * trident, int type, int client, int port)
-{
- struct snd_trident_voice *pvoice;
- unsigned long flags;
- int idx;
-
- spin_lock_irqsave(&trident->voice_alloc, flags);
- if (type == SNDRV_TRIDENT_VOICE_TYPE_PCM) {
- idx = snd_trident_allocate_pcm_channel(trident);
- if(idx < 0) {
- spin_unlock_irqrestore(&trident->voice_alloc, flags);
- return NULL;
- }
- pvoice = &trident->synth.voices[idx];
- pvoice->use = 1;
- pvoice->pcm = 1;
- pvoice->capture = 0;
- pvoice->spdif = 0;
- pvoice->memblk = NULL;
- pvoice->substream = NULL;
- spin_unlock_irqrestore(&trident->voice_alloc, flags);
- return pvoice;
- }
- if (type == SNDRV_TRIDENT_VOICE_TYPE_SYNTH) {
- idx = snd_trident_allocate_synth_channel(trident);
- if(idx < 0) {
- spin_unlock_irqrestore(&trident->voice_alloc, flags);
- return NULL;
- }
- pvoice = &trident->synth.voices[idx];
- pvoice->use = 1;
- pvoice->synth = 1;
- pvoice->client = client;
- pvoice->port = port;
- pvoice->memblk = NULL;
- spin_unlock_irqrestore(&trident->voice_alloc, flags);
- return pvoice;
- }
- if (type == SNDRV_TRIDENT_VOICE_TYPE_MIDI) {
- }
- spin_unlock_irqrestore(&trident->voice_alloc, flags);
- return NULL;
-}
-
-EXPORT_SYMBOL(snd_trident_alloc_voice);
-
-void snd_trident_free_voice(struct snd_trident * trident, struct snd_trident_voice *voice)
-{
- unsigned long flags;
- void (*private_free)(struct snd_trident_voice *);
- void *private_data;
-
- if (voice == NULL || !voice->use)
- return;
- snd_trident_clear_voices(trident, voice->number, voice->number);
- spin_lock_irqsave(&trident->voice_alloc, flags);
- private_free = voice->private_free;
- private_data = voice->private_data;
- voice->private_free = NULL;
- voice->private_data = NULL;
- if (voice->pcm)
- snd_trident_free_pcm_channel(trident, voice->number);
- if (voice->synth)
- snd_trident_free_synth_channel(trident, voice->number);
- voice->use = voice->pcm = voice->synth = voice->midi = 0;
- voice->capture = voice->spdif = 0;
- voice->sample_ops = NULL;
- voice->substream = NULL;
- voice->extra = NULL;
- spin_unlock_irqrestore(&trident->voice_alloc, flags);
- if (private_free)
- private_free(voice);
-}
-
-EXPORT_SYMBOL(snd_trident_free_voice);
-
-static void snd_trident_clear_voices(struct snd_trident * trident, unsigned short v_min, unsigned short v_max)
-{
- unsigned int i, val, mask[2] = { 0, 0 };
-
- if (snd_BUG_ON(v_min > 63 || v_max > 63))
- return;
- for (i = v_min; i <= v_max; i++)
- mask[i >> 5] |= 1 << (i & 0x1f);
- if (mask[0]) {
- outl(mask[0], TRID_REG(trident, T4D_STOP_A));
- val = inl(TRID_REG(trident, T4D_AINTEN_A));
- outl(val & ~mask[0], TRID_REG(trident, T4D_AINTEN_A));
- }
- if (mask[1]) {
- outl(mask[1], TRID_REG(trident, T4D_STOP_B));
- val = inl(TRID_REG(trident, T4D_AINTEN_B));
- outl(val & ~mask[1], TRID_REG(trident, T4D_AINTEN_B));
- }
-}
-
-#ifdef CONFIG_PM
-int snd_trident_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_trident *trident = card->private_data;
-
- trident->in_suspend = 1;
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(trident->pcm);
- snd_pcm_suspend_all(trident->foldback);
- snd_pcm_suspend_all(trident->spdif);
-
- snd_ac97_suspend(trident->ac97);
- snd_ac97_suspend(trident->ac97_sec);
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-int snd_trident_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_trident *trident = card->private_data;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "trident: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
-
- switch (trident->device) {
- case TRIDENT_DEVICE_ID_DX:
- snd_trident_4d_dx_init(trident);
- break;
- case TRIDENT_DEVICE_ID_NX:
- snd_trident_4d_nx_init(trident);
- break;
- case TRIDENT_DEVICE_ID_SI7018:
- snd_trident_sis_init(trident);
- break;
- }
-
- snd_ac97_resume(trident->ac97);
- snd_ac97_resume(trident->ac97_sec);
-
- /* restore some registers */
- outl(trident->musicvol_wavevol, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
-
- snd_trident_enable_eso(trident);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- trident->in_suspend = 0;
- return 0;
-}
-#endif /* CONFIG_PM */
diff --git a/ANDROID_3.4.5/sound/pci/trident/trident_memory.c b/ANDROID_3.4.5/sound/pci/trident/trident_memory.c
deleted file mode 100644
index f9779e23..00000000
--- a/ANDROID_3.4.5/sound/pci/trident/trident_memory.c
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- * Copyright (c) by Scott McNab <sdm@fractalgraphics.com.au>
- *
- * Trident 4DWave-NX memory page allocation (TLB area)
- * Trident chip can handle only 16MByte of the memory at the same time.
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/io.h>
-#include <linux/pci.h>
-#include <linux/time.h>
-#include <linux/mutex.h>
-
-#include <sound/core.h>
-#include <sound/trident.h>
-
-/* page arguments of these two macros are Trident page (4096 bytes), not like
- * aligned pages in others
- */
-#define __set_tlb_bus(trident,page,ptr,addr) \
- do { (trident)->tlb.entries[page] = cpu_to_le32((addr) & ~(SNDRV_TRIDENT_PAGE_SIZE-1)); \
- (trident)->tlb.shadow_entries[page] = (ptr); } while (0)
-#define __tlb_to_ptr(trident,page) \
- (void*)((trident)->tlb.shadow_entries[page])
-#define __tlb_to_addr(trident,page) \
- (dma_addr_t)le32_to_cpu((trident->tlb.entries[page]) & ~(SNDRV_TRIDENT_PAGE_SIZE - 1))
-
-#if PAGE_SIZE == 4096
-/* page size == SNDRV_TRIDENT_PAGE_SIZE */
-#define ALIGN_PAGE_SIZE PAGE_SIZE /* minimum page size for allocation */
-#define MAX_ALIGN_PAGES SNDRV_TRIDENT_MAX_PAGES /* maxmium aligned pages */
-/* fill TLB entrie(s) corresponding to page with ptr */
-#define set_tlb_bus(trident,page,ptr,addr) __set_tlb_bus(trident,page,ptr,addr)
-/* fill TLB entrie(s) corresponding to page with silence pointer */
-#define set_silent_tlb(trident,page) __set_tlb_bus(trident, page, (unsigned long)trident->tlb.silent_page.area, trident->tlb.silent_page.addr)
-/* get aligned page from offset address */
-#define get_aligned_page(offset) ((offset) >> 12)
-/* get offset address from aligned page */
-#define aligned_page_offset(page) ((page) << 12)
-/* get buffer address from aligned page */
-#define page_to_ptr(trident,page) __tlb_to_ptr(trident, page)
-/* get PCI physical address from aligned page */
-#define page_to_addr(trident,page) __tlb_to_addr(trident, page)
-
-#elif PAGE_SIZE == 8192
-/* page size == SNDRV_TRIDENT_PAGE_SIZE x 2*/
-#define ALIGN_PAGE_SIZE PAGE_SIZE
-#define MAX_ALIGN_PAGES (SNDRV_TRIDENT_MAX_PAGES / 2)
-#define get_aligned_page(offset) ((offset) >> 13)
-#define aligned_page_offset(page) ((page) << 13)
-#define page_to_ptr(trident,page) __tlb_to_ptr(trident, (page) << 1)
-#define page_to_addr(trident,page) __tlb_to_addr(trident, (page) << 1)
-
-/* fill TLB entries -- we need to fill two entries */
-static inline void set_tlb_bus(struct snd_trident *trident, int page,
- unsigned long ptr, dma_addr_t addr)
-{
- page <<= 1;
- __set_tlb_bus(trident, page, ptr, addr);
- __set_tlb_bus(trident, page+1, ptr + SNDRV_TRIDENT_PAGE_SIZE, addr + SNDRV_TRIDENT_PAGE_SIZE);
-}
-static inline void set_silent_tlb(struct snd_trident *trident, int page)
-{
- page <<= 1;
- __set_tlb_bus(trident, page, (unsigned long)trident->tlb.silent_page.area, trident->tlb.silent_page.addr);
- __set_tlb_bus(trident, page+1, (unsigned long)trident->tlb.silent_page.area, trident->tlb.silent_page.addr);
-}
-
-#else
-/* arbitrary size */
-#define UNIT_PAGES (PAGE_SIZE / SNDRV_TRIDENT_PAGE_SIZE)
-#define ALIGN_PAGE_SIZE (SNDRV_TRIDENT_PAGE_SIZE * UNIT_PAGES)
-#define MAX_ALIGN_PAGES (SNDRV_TRIDENT_MAX_PAGES / UNIT_PAGES)
-/* Note: if alignment doesn't match to the maximum size, the last few blocks
- * become unusable. To use such blocks, you'll need to check the validity
- * of accessing page in set_tlb_bus and set_silent_tlb. search_empty()
- * should also check it, too.
- */
-#define get_aligned_page(offset) ((offset) / ALIGN_PAGE_SIZE)
-#define aligned_page_offset(page) ((page) * ALIGN_PAGE_SIZE)
-#define page_to_ptr(trident,page) __tlb_to_ptr(trident, (page) * UNIT_PAGES)
-#define page_to_addr(trident,page) __tlb_to_addr(trident, (page) * UNIT_PAGES)
-
-/* fill TLB entries -- UNIT_PAGES entries must be filled */
-static inline void set_tlb_bus(struct snd_trident *trident, int page,
- unsigned long ptr, dma_addr_t addr)
-{
- int i;
- page *= UNIT_PAGES;
- for (i = 0; i < UNIT_PAGES; i++, page++) {
- __set_tlb_bus(trident, page, ptr, addr);
- ptr += SNDRV_TRIDENT_PAGE_SIZE;
- addr += SNDRV_TRIDENT_PAGE_SIZE;
- }
-}
-static inline void set_silent_tlb(struct snd_trident *trident, int page)
-{
- int i;
- page *= UNIT_PAGES;
- for (i = 0; i < UNIT_PAGES; i++, page++)
- __set_tlb_bus(trident, page, (unsigned long)trident->tlb.silent_page.area, trident->tlb.silent_page.addr);
-}
-
-#endif /* PAGE_SIZE */
-
-/* calculate buffer pointer from offset address */
-static inline void *offset_ptr(struct snd_trident *trident, int offset)
-{
- char *ptr;
- ptr = page_to_ptr(trident, get_aligned_page(offset));
- ptr += offset % ALIGN_PAGE_SIZE;
- return (void*)ptr;
-}
-
-/* first and last (aligned) pages of memory block */
-#define firstpg(blk) (((struct snd_trident_memblk_arg *)snd_util_memblk_argptr(blk))->first_page)
-#define lastpg(blk) (((struct snd_trident_memblk_arg *)snd_util_memblk_argptr(blk))->last_page)
-
-/*
- * search empty pages which may contain given size
- */
-static struct snd_util_memblk *
-search_empty(struct snd_util_memhdr *hdr, int size)
-{
- struct snd_util_memblk *blk, *prev;
- int page, psize;
- struct list_head *p;
-
- psize = get_aligned_page(size + ALIGN_PAGE_SIZE -1);
- prev = NULL;
- page = 0;
- list_for_each(p, &hdr->block) {
- blk = list_entry(p, struct snd_util_memblk, list);
- if (page + psize <= firstpg(blk))
- goto __found_pages;
- page = lastpg(blk) + 1;
- }
- if (page + psize > MAX_ALIGN_PAGES)
- return NULL;
-
-__found_pages:
- /* create a new memory block */
- blk = __snd_util_memblk_new(hdr, psize * ALIGN_PAGE_SIZE, p->prev);
- if (blk == NULL)
- return NULL;
- blk->offset = aligned_page_offset(page); /* set aligned offset */
- firstpg(blk) = page;
- lastpg(blk) = page + psize - 1;
- return blk;
-}
-
-
-/*
- * check if the given pointer is valid for pages
- */
-static int is_valid_page(unsigned long ptr)
-{
- if (ptr & ~0x3fffffffUL) {
- snd_printk(KERN_ERR "max memory size is 1GB!!\n");
- return 0;
- }
- if (ptr & (SNDRV_TRIDENT_PAGE_SIZE-1)) {
- snd_printk(KERN_ERR "page is not aligned\n");
- return 0;
- }
- return 1;
-}
-
-/*
- * page allocation for DMA (Scatter-Gather version)
- */
-static struct snd_util_memblk *
-snd_trident_alloc_sg_pages(struct snd_trident *trident,
- struct snd_pcm_substream *substream)
-{
- struct snd_util_memhdr *hdr;
- struct snd_util_memblk *blk;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int idx, page;
-
- if (snd_BUG_ON(runtime->dma_bytes <= 0 ||
- runtime->dma_bytes > SNDRV_TRIDENT_MAX_PAGES *
- SNDRV_TRIDENT_PAGE_SIZE))
- return NULL;
- hdr = trident->tlb.memhdr;
- if (snd_BUG_ON(!hdr))
- return NULL;
-
-
-
- mutex_lock(&hdr->block_mutex);
- blk = search_empty(hdr, runtime->dma_bytes);
- if (blk == NULL) {
- mutex_unlock(&hdr->block_mutex);
- return NULL;
- }
-
- /* set TLB entries */
- idx = 0;
- for (page = firstpg(blk); page <= lastpg(blk); page++, idx++) {
- unsigned long ofs = idx << PAGE_SHIFT;
- dma_addr_t addr = snd_pcm_sgbuf_get_addr(substream, ofs);
- unsigned long ptr = (unsigned long)
- snd_pcm_sgbuf_get_ptr(substream, ofs);
- if (! is_valid_page(addr)) {
- __snd_util_mem_free(hdr, blk);
- mutex_unlock(&hdr->block_mutex);
- return NULL;
- }
- set_tlb_bus(trident, page, ptr, addr);
- }
- mutex_unlock(&hdr->block_mutex);
- return blk;
-}
-
-/*
- * page allocation for DMA (contiguous version)
- */
-static struct snd_util_memblk *
-snd_trident_alloc_cont_pages(struct snd_trident *trident,
- struct snd_pcm_substream *substream)
-{
- struct snd_util_memhdr *hdr;
- struct snd_util_memblk *blk;
- int page;
- struct snd_pcm_runtime *runtime = substream->runtime;
- dma_addr_t addr;
- unsigned long ptr;
-
- if (snd_BUG_ON(runtime->dma_bytes <= 0 ||
- runtime->dma_bytes > SNDRV_TRIDENT_MAX_PAGES *
- SNDRV_TRIDENT_PAGE_SIZE))
- return NULL;
- hdr = trident->tlb.memhdr;
- if (snd_BUG_ON(!hdr))
- return NULL;
-
- mutex_lock(&hdr->block_mutex);
- blk = search_empty(hdr, runtime->dma_bytes);
- if (blk == NULL) {
- mutex_unlock(&hdr->block_mutex);
- return NULL;
- }
-
- /* set TLB entries */
- addr = runtime->dma_addr;
- ptr = (unsigned long)runtime->dma_area;
- for (page = firstpg(blk); page <= lastpg(blk); page++,
- ptr += SNDRV_TRIDENT_PAGE_SIZE, addr += SNDRV_TRIDENT_PAGE_SIZE) {
- if (! is_valid_page(addr)) {
- __snd_util_mem_free(hdr, blk);
- mutex_unlock(&hdr->block_mutex);
- return NULL;
- }
- set_tlb_bus(trident, page, ptr, addr);
- }
- mutex_unlock(&hdr->block_mutex);
- return blk;
-}
-
-/*
- * page allocation for DMA
- */
-struct snd_util_memblk *
-snd_trident_alloc_pages(struct snd_trident *trident,
- struct snd_pcm_substream *substream)
-{
- if (snd_BUG_ON(!trident || !substream))
- return NULL;
- if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV_SG)
- return snd_trident_alloc_sg_pages(trident, substream);
- else
- return snd_trident_alloc_cont_pages(trident, substream);
-}
-
-
-/*
- * release DMA buffer from page table
- */
-int snd_trident_free_pages(struct snd_trident *trident,
- struct snd_util_memblk *blk)
-{
- struct snd_util_memhdr *hdr;
- int page;
-
- if (snd_BUG_ON(!trident || !blk))
- return -EINVAL;
-
- hdr = trident->tlb.memhdr;
- mutex_lock(&hdr->block_mutex);
- /* reset TLB entries */
- for (page = firstpg(blk); page <= lastpg(blk); page++)
- set_silent_tlb(trident, page);
- /* free memory block */
- __snd_util_mem_free(hdr, blk);
- mutex_unlock(&hdr->block_mutex);
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pci/via82xx.c b/ANDROID_3.4.5/sound/pci/via82xx.c
deleted file mode 100644
index 75630408..00000000
--- a/ANDROID_3.4.5/sound/pci/via82xx.c
+++ /dev/null
@@ -1,2644 +0,0 @@
-/*
- * ALSA driver for VIA VT82xx (South Bridge)
- *
- * VT82C686A/B/C, VT8233A/C, VT8235
- *
- * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
- * Tjeerd.Mulder <Tjeerd.Mulder@fujitsu-siemens.com>
- * 2002 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- * Changes:
- *
- * Dec. 19, 2002 Takashi Iwai <tiwai@suse.de>
- * - use the DSX channels for the first pcm playback.
- * (on VIA8233, 8233C and 8235 only)
- * this will allow you play simultaneously up to 4 streams.
- * multi-channel playback is assigned to the second device
- * on these chips.
- * - support the secondary capture (on VIA8233/C,8235)
- * - SPDIF support
- * the DSX3 channel can be used for SPDIF output.
- * on VIA8233A, this channel is assigned to the second pcm
- * playback.
- * the card config of alsa-lib will assign the correct
- * device for applications.
- * - clean up the code, separate low-level initialization
- * routines for each chipset.
- *
- * Sep. 26, 2005 Karsten Wiese <annabellesgarden@yahoo.de>
- * - Optimize position calculation for the 823x chips.
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/gameport.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/info.h>
-#include <sound/tlv.h>
-#include <sound/ac97_codec.h>
-#include <sound/mpu401.h>
-#include <sound/initval.h>
-
-#if 0
-#define POINTER_DEBUG
-#endif
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("VIA VT82xx audio");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{VIA,VT82C686A/B/C,pci},{VIA,VT8233A/C,8235}}");
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK 1
-#endif
-
-static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
-static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-static long mpu_port;
-#ifdef SUPPORT_JOYSTICK
-static bool joystick;
-#endif
-static int ac97_clock = 48000;
-static char *ac97_quirk;
-static int dxs_support;
-static int dxs_init_volume = 31;
-static int nodelay;
-
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for VIA 82xx bridge.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for VIA 82xx bridge.");
-module_param(mpu_port, long, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port. (VT82C686x only)");
-#ifdef SUPPORT_JOYSTICK
-module_param(joystick, bool, 0444);
-MODULE_PARM_DESC(joystick, "Enable joystick. (VT82C686x only)");
-#endif
-module_param(ac97_clock, int, 0444);
-MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
-module_param(ac97_quirk, charp, 0444);
-MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
-module_param(dxs_support, int, 0444);
-MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA, 5 = enable any sample rate)");
-module_param(dxs_init_volume, int, 0644);
-MODULE_PARM_DESC(dxs_init_volume, "initial DXS volume (0-31)");
-module_param(nodelay, int, 0444);
-MODULE_PARM_DESC(nodelay, "Disable 500ms init delay");
-
-/* just for backward compatibility */
-static bool enable;
-module_param(enable, bool, 0444);
-
-
-/* revision numbers for via686 */
-#define VIA_REV_686_A 0x10
-#define VIA_REV_686_B 0x11
-#define VIA_REV_686_C 0x12
-#define VIA_REV_686_D 0x13
-#define VIA_REV_686_E 0x14
-#define VIA_REV_686_H 0x20
-
-/* revision numbers for via8233 */
-#define VIA_REV_PRE_8233 0x10 /* not in market */
-#define VIA_REV_8233C 0x20 /* 2 rec, 4 pb, 1 multi-pb */
-#define VIA_REV_8233 0x30 /* 2 rec, 4 pb, 1 multi-pb, spdif */
-#define VIA_REV_8233A 0x40 /* 1 rec, 1 multi-pb, spdf */
-#define VIA_REV_8235 0x50 /* 2 rec, 4 pb, 1 multi-pb, spdif */
-#define VIA_REV_8237 0x60
-#define VIA_REV_8251 0x70
-
-/*
- * Direct registers
- */
-
-#define VIAREG(via, x) ((via)->port + VIA_REG_##x)
-#define VIADEV_REG(viadev, x) ((viadev)->port + VIA_REG_##x)
-
-/* common offsets */
-#define VIA_REG_OFFSET_STATUS 0x00 /* byte - channel status */
-#define VIA_REG_STAT_ACTIVE 0x80 /* RO */
-#define VIA8233_SHADOW_STAT_ACTIVE 0x08 /* RO */
-#define VIA_REG_STAT_PAUSED 0x40 /* RO */
-#define VIA_REG_STAT_TRIGGER_QUEUED 0x08 /* RO */
-#define VIA_REG_STAT_STOPPED 0x04 /* RWC */
-#define VIA_REG_STAT_EOL 0x02 /* RWC */
-#define VIA_REG_STAT_FLAG 0x01 /* RWC */
-#define VIA_REG_OFFSET_CONTROL 0x01 /* byte - channel control */
-#define VIA_REG_CTRL_START 0x80 /* WO */
-#define VIA_REG_CTRL_TERMINATE 0x40 /* WO */
-#define VIA_REG_CTRL_AUTOSTART 0x20
-#define VIA_REG_CTRL_PAUSE 0x08 /* RW */
-#define VIA_REG_CTRL_INT_STOP 0x04
-#define VIA_REG_CTRL_INT_EOL 0x02
-#define VIA_REG_CTRL_INT_FLAG 0x01
-#define VIA_REG_CTRL_RESET 0x01 /* RW - probably reset? undocumented */
-#define VIA_REG_CTRL_INT (VIA_REG_CTRL_INT_FLAG | VIA_REG_CTRL_INT_EOL | VIA_REG_CTRL_AUTOSTART)
-#define VIA_REG_OFFSET_TYPE 0x02 /* byte - channel type (686 only) */
-#define VIA_REG_TYPE_AUTOSTART 0x80 /* RW - autostart at EOL */
-#define VIA_REG_TYPE_16BIT 0x20 /* RW */
-#define VIA_REG_TYPE_STEREO 0x10 /* RW */
-#define VIA_REG_TYPE_INT_LLINE 0x00
-#define VIA_REG_TYPE_INT_LSAMPLE 0x04
-#define VIA_REG_TYPE_INT_LESSONE 0x08
-#define VIA_REG_TYPE_INT_MASK 0x0c
-#define VIA_REG_TYPE_INT_EOL 0x02
-#define VIA_REG_TYPE_INT_FLAG 0x01
-#define VIA_REG_OFFSET_TABLE_PTR 0x04 /* dword - channel table pointer */
-#define VIA_REG_OFFSET_CURR_PTR 0x04 /* dword - channel current pointer */
-#define VIA_REG_OFFSET_STOP_IDX 0x08 /* dword - stop index, channel type, sample rate */
-#define VIA8233_REG_TYPE_16BIT 0x00200000 /* RW */
-#define VIA8233_REG_TYPE_STEREO 0x00100000 /* RW */
-#define VIA_REG_OFFSET_CURR_COUNT 0x0c /* dword - channel current count (24 bit) */
-#define VIA_REG_OFFSET_CURR_INDEX 0x0f /* byte - channel current index (for via8233 only) */
-
-#define DEFINE_VIA_REGSET(name,val) \
-enum {\
- VIA_REG_##name##_STATUS = (val),\
- VIA_REG_##name##_CONTROL = (val) + 0x01,\
- VIA_REG_##name##_TYPE = (val) + 0x02,\
- VIA_REG_##name##_TABLE_PTR = (val) + 0x04,\
- VIA_REG_##name##_CURR_PTR = (val) + 0x04,\
- VIA_REG_##name##_STOP_IDX = (val) + 0x08,\
- VIA_REG_##name##_CURR_COUNT = (val) + 0x0c,\
-}
-
-/* playback block */
-DEFINE_VIA_REGSET(PLAYBACK, 0x00);
-DEFINE_VIA_REGSET(CAPTURE, 0x10);
-DEFINE_VIA_REGSET(FM, 0x20);
-
-/* AC'97 */
-#define VIA_REG_AC97 0x80 /* dword */
-#define VIA_REG_AC97_CODEC_ID_MASK (3<<30)
-#define VIA_REG_AC97_CODEC_ID_SHIFT 30
-#define VIA_REG_AC97_CODEC_ID_PRIMARY 0x00
-#define VIA_REG_AC97_CODEC_ID_SECONDARY 0x01
-#define VIA_REG_AC97_SECONDARY_VALID (1<<27)
-#define VIA_REG_AC97_PRIMARY_VALID (1<<25)
-#define VIA_REG_AC97_BUSY (1<<24)
-#define VIA_REG_AC97_READ (1<<23)
-#define VIA_REG_AC97_CMD_SHIFT 16
-#define VIA_REG_AC97_CMD_MASK 0x7e
-#define VIA_REG_AC97_DATA_SHIFT 0
-#define VIA_REG_AC97_DATA_MASK 0xffff
-
-#define VIA_REG_SGD_SHADOW 0x84 /* dword */
-/* via686 */
-#define VIA_REG_SGD_STAT_PB_FLAG (1<<0)
-#define VIA_REG_SGD_STAT_CP_FLAG (1<<1)
-#define VIA_REG_SGD_STAT_FM_FLAG (1<<2)
-#define VIA_REG_SGD_STAT_PB_EOL (1<<4)
-#define VIA_REG_SGD_STAT_CP_EOL (1<<5)
-#define VIA_REG_SGD_STAT_FM_EOL (1<<6)
-#define VIA_REG_SGD_STAT_PB_STOP (1<<8)
-#define VIA_REG_SGD_STAT_CP_STOP (1<<9)
-#define VIA_REG_SGD_STAT_FM_STOP (1<<10)
-#define VIA_REG_SGD_STAT_PB_ACTIVE (1<<12)
-#define VIA_REG_SGD_STAT_CP_ACTIVE (1<<13)
-#define VIA_REG_SGD_STAT_FM_ACTIVE (1<<14)
-/* via8233 */
-#define VIA8233_REG_SGD_STAT_FLAG (1<<0)
-#define VIA8233_REG_SGD_STAT_EOL (1<<1)
-#define VIA8233_REG_SGD_STAT_STOP (1<<2)
-#define VIA8233_REG_SGD_STAT_ACTIVE (1<<3)
-#define VIA8233_INTR_MASK(chan) ((VIA8233_REG_SGD_STAT_FLAG|VIA8233_REG_SGD_STAT_EOL) << ((chan) * 4))
-#define VIA8233_REG_SGD_CHAN_SDX 0
-#define VIA8233_REG_SGD_CHAN_MULTI 4
-#define VIA8233_REG_SGD_CHAN_REC 6
-#define VIA8233_REG_SGD_CHAN_REC1 7
-
-#define VIA_REG_GPI_STATUS 0x88
-#define VIA_REG_GPI_INTR 0x8c
-
-/* multi-channel and capture registers for via8233 */
-DEFINE_VIA_REGSET(MULTPLAY, 0x40);
-DEFINE_VIA_REGSET(CAPTURE_8233, 0x60);
-
-/* via8233-specific registers */
-#define VIA_REG_OFS_PLAYBACK_VOLUME_L 0x02 /* byte */
-#define VIA_REG_OFS_PLAYBACK_VOLUME_R 0x03 /* byte */
-#define VIA_REG_OFS_MULTPLAY_FORMAT 0x02 /* byte - format and channels */
-#define VIA_REG_MULTPLAY_FMT_8BIT 0x00
-#define VIA_REG_MULTPLAY_FMT_16BIT 0x80
-#define VIA_REG_MULTPLAY_FMT_CH_MASK 0x70 /* # channels << 4 (valid = 1,2,4,6) */
-#define VIA_REG_OFS_CAPTURE_FIFO 0x02 /* byte - bit 6 = fifo enable */
-#define VIA_REG_CAPTURE_FIFO_ENABLE 0x40
-
-#define VIA_DXS_MAX_VOLUME 31 /* max. volume (attenuation) of reg 0x32/33 */
-
-#define VIA_REG_CAPTURE_CHANNEL 0x63 /* byte - input select */
-#define VIA_REG_CAPTURE_CHANNEL_MIC 0x4
-#define VIA_REG_CAPTURE_CHANNEL_LINE 0
-#define VIA_REG_CAPTURE_SELECT_CODEC 0x03 /* recording source codec (0 = primary) */
-
-#define VIA_TBL_BIT_FLAG 0x40000000
-#define VIA_TBL_BIT_EOL 0x80000000
-
-/* pci space */
-#define VIA_ACLINK_STAT 0x40
-#define VIA_ACLINK_C11_READY 0x20
-#define VIA_ACLINK_C10_READY 0x10
-#define VIA_ACLINK_C01_READY 0x04 /* secondary codec ready */
-#define VIA_ACLINK_LOWPOWER 0x02 /* low-power state */
-#define VIA_ACLINK_C00_READY 0x01 /* primary codec ready */
-#define VIA_ACLINK_CTRL 0x41
-#define VIA_ACLINK_CTRL_ENABLE 0x80 /* 0: disable, 1: enable */
-#define VIA_ACLINK_CTRL_RESET 0x40 /* 0: assert, 1: de-assert */
-#define VIA_ACLINK_CTRL_SYNC 0x20 /* 0: release SYNC, 1: force SYNC hi */
-#define VIA_ACLINK_CTRL_SDO 0x10 /* 0: release SDO, 1: force SDO hi */
-#define VIA_ACLINK_CTRL_VRA 0x08 /* 0: disable VRA, 1: enable VRA */
-#define VIA_ACLINK_CTRL_PCM 0x04 /* 0: disable PCM, 1: enable PCM */
-#define VIA_ACLINK_CTRL_FM 0x02 /* via686 only */
-#define VIA_ACLINK_CTRL_SB 0x01 /* via686 only */
-#define VIA_ACLINK_CTRL_INIT (VIA_ACLINK_CTRL_ENABLE|\
- VIA_ACLINK_CTRL_RESET|\
- VIA_ACLINK_CTRL_PCM|\
- VIA_ACLINK_CTRL_VRA)
-#define VIA_FUNC_ENABLE 0x42
-#define VIA_FUNC_MIDI_PNP 0x80 /* FIXME: it's 0x40 in the datasheet! */
-#define VIA_FUNC_MIDI_IRQMASK 0x40 /* FIXME: not documented! */
-#define VIA_FUNC_RX2C_WRITE 0x20
-#define VIA_FUNC_SB_FIFO_EMPTY 0x10
-#define VIA_FUNC_ENABLE_GAME 0x08
-#define VIA_FUNC_ENABLE_FM 0x04
-#define VIA_FUNC_ENABLE_MIDI 0x02
-#define VIA_FUNC_ENABLE_SB 0x01
-#define VIA_PNP_CONTROL 0x43
-#define VIA_FM_NMI_CTRL 0x48
-#define VIA8233_VOLCHG_CTRL 0x48
-#define VIA8233_SPDIF_CTRL 0x49
-#define VIA8233_SPDIF_DX3 0x08
-#define VIA8233_SPDIF_SLOT_MASK 0x03
-#define VIA8233_SPDIF_SLOT_1011 0x00
-#define VIA8233_SPDIF_SLOT_34 0x01
-#define VIA8233_SPDIF_SLOT_78 0x02
-#define VIA8233_SPDIF_SLOT_69 0x03
-
-/*
- */
-
-#define VIA_DXS_AUTO 0
-#define VIA_DXS_ENABLE 1
-#define VIA_DXS_DISABLE 2
-#define VIA_DXS_48K 3
-#define VIA_DXS_NO_VRA 4
-#define VIA_DXS_SRC 5
-
-
-/*
- * pcm stream
- */
-
-struct snd_via_sg_table {
- unsigned int offset;
- unsigned int size;
-} ;
-
-#define VIA_TABLE_SIZE 255
-#define VIA_MAX_BUFSIZE (1<<24)
-
-struct viadev {
- unsigned int reg_offset;
- unsigned long port;
- int direction; /* playback = 0, capture = 1 */
- struct snd_pcm_substream *substream;
- int running;
- unsigned int tbl_entries; /* # descriptors */
- struct snd_dma_buffer table;
- struct snd_via_sg_table *idx_table;
- /* for recovery from the unexpected pointer */
- unsigned int lastpos;
- unsigned int fragsize;
- unsigned int bufsize;
- unsigned int bufsize2;
- int hwptr_done; /* processed frame position in the buffer */
- int in_interrupt;
- int shadow_shift;
-};
-
-
-enum { TYPE_CARD_VIA686 = 1, TYPE_CARD_VIA8233 };
-enum { TYPE_VIA686, TYPE_VIA8233, TYPE_VIA8233A };
-
-#define VIA_MAX_DEVS 7 /* 4 playback, 1 multi, 2 capture */
-
-struct via_rate_lock {
- spinlock_t lock;
- int rate;
- int used;
-};
-
-struct via82xx {
- int irq;
-
- unsigned long port;
- struct resource *mpu_res;
- int chip_type;
- unsigned char revision;
-
- unsigned char old_legacy;
- unsigned char old_legacy_cfg;
-#ifdef CONFIG_PM
- unsigned char legacy_saved;
- unsigned char legacy_cfg_saved;
- unsigned char spdif_ctrl_saved;
- unsigned char capture_src_saved[2];
- unsigned int mpu_port_saved;
-#endif
-
- unsigned char playback_volume[4][2]; /* for VIA8233/C/8235; default = 0 */
- unsigned char playback_volume_c[2]; /* for VIA8233/C/8235; default = 0 */
-
- unsigned int intr_mask; /* SGD_SHADOW mask to check interrupts */
-
- struct pci_dev *pci;
- struct snd_card *card;
-
- unsigned int num_devs;
- unsigned int playback_devno, multi_devno, capture_devno;
- struct viadev devs[VIA_MAX_DEVS];
- struct via_rate_lock rates[2]; /* playback and capture */
- unsigned int dxs_fixed: 1; /* DXS channel accepts only 48kHz */
- unsigned int no_vra: 1; /* no need to set VRA on DXS channels */
- unsigned int dxs_src: 1; /* use full SRC capabilities of DXS */
- unsigned int spdif_on: 1; /* only spdif rates work to external DACs */
-
- struct snd_pcm *pcms[2];
- struct snd_rawmidi *rmidi;
- struct snd_kcontrol *dxs_controls[4];
-
- struct snd_ac97_bus *ac97_bus;
- struct snd_ac97 *ac97;
- unsigned int ac97_clock;
- unsigned int ac97_secondary; /* secondary AC'97 codec is present */
-
- spinlock_t reg_lock;
- struct snd_info_entry *proc_entry;
-
-#ifdef SUPPORT_JOYSTICK
- struct gameport *gameport;
-#endif
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_via82xx_ids) = {
- /* 0x1106, 0x3058 */
- { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C686_5), TYPE_CARD_VIA686, }, /* 686A */
- /* 0x1106, 0x3059 */
- { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233_5), TYPE_CARD_VIA8233, }, /* VT8233 */
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_via82xx_ids);
-
-/*
- */
-
-/*
- * allocate and initialize the descriptor buffers
- * periods = number of periods
- * fragsize = period size in bytes
- */
-static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substream,
- struct pci_dev *pci,
- unsigned int periods, unsigned int fragsize)
-{
- unsigned int i, idx, ofs, rest;
- struct via82xx *chip = snd_pcm_substream_chip(substream);
-
- if (dev->table.area == NULL) {
- /* the start of each lists must be aligned to 8 bytes,
- * but the kernel pages are much bigger, so we don't care
- */
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
- PAGE_ALIGN(VIA_TABLE_SIZE * 2 * 8),
- &dev->table) < 0)
- return -ENOMEM;
- }
- if (! dev->idx_table) {
- dev->idx_table = kmalloc(sizeof(*dev->idx_table) * VIA_TABLE_SIZE, GFP_KERNEL);
- if (! dev->idx_table)
- return -ENOMEM;
- }
-
- /* fill the entries */
- idx = 0;
- ofs = 0;
- for (i = 0; i < periods; i++) {
- rest = fragsize;
- /* fill descriptors for a period.
- * a period can be split to several descriptors if it's
- * over page boundary.
- */
- do {
- unsigned int r;
- unsigned int flag;
- unsigned int addr;
-
- if (idx >= VIA_TABLE_SIZE) {
- snd_printk(KERN_ERR "via82xx: too much table size!\n");
- return -EINVAL;
- }
- addr = snd_pcm_sgbuf_get_addr(substream, ofs);
- ((u32 *)dev->table.area)[idx << 1] = cpu_to_le32(addr);
- r = snd_pcm_sgbuf_get_chunk_size(substream, ofs, rest);
- rest -= r;
- if (! rest) {
- if (i == periods - 1)
- flag = VIA_TBL_BIT_EOL; /* buffer boundary */
- else
- flag = VIA_TBL_BIT_FLAG; /* period boundary */
- } else
- flag = 0; /* period continues to the next */
- /*
- printk(KERN_DEBUG "via: tbl %d: at %d size %d "
- "(rest %d)\n", idx, ofs, r, rest);
- */
- ((u32 *)dev->table.area)[(idx<<1) + 1] = cpu_to_le32(r | flag);
- dev->idx_table[idx].offset = ofs;
- dev->idx_table[idx].size = r;
- ofs += r;
- idx++;
- } while (rest > 0);
- }
- dev->tbl_entries = idx;
- dev->bufsize = periods * fragsize;
- dev->bufsize2 = dev->bufsize / 2;
- dev->fragsize = fragsize;
- return 0;
-}
-
-
-static int clean_via_table(struct viadev *dev, struct snd_pcm_substream *substream,
- struct pci_dev *pci)
-{
- if (dev->table.area) {
- snd_dma_free_pages(&dev->table);
- dev->table.area = NULL;
- }
- kfree(dev->idx_table);
- dev->idx_table = NULL;
- return 0;
-}
-
-/*
- * Basic I/O
- */
-
-static inline unsigned int snd_via82xx_codec_xread(struct via82xx *chip)
-{
- return inl(VIAREG(chip, AC97));
-}
-
-static inline void snd_via82xx_codec_xwrite(struct via82xx *chip, unsigned int val)
-{
- outl(val, VIAREG(chip, AC97));
-}
-
-static int snd_via82xx_codec_ready(struct via82xx *chip, int secondary)
-{
- unsigned int timeout = 1000; /* 1ms */
- unsigned int val;
-
- while (timeout-- > 0) {
- udelay(1);
- if (!((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY))
- return val & 0xffff;
- }
- snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n",
- secondary, snd_via82xx_codec_xread(chip));
- return -EIO;
-}
-
-static int snd_via82xx_codec_valid(struct via82xx *chip, int secondary)
-{
- unsigned int timeout = 1000; /* 1ms */
- unsigned int val, val1;
- unsigned int stat = !secondary ? VIA_REG_AC97_PRIMARY_VALID :
- VIA_REG_AC97_SECONDARY_VALID;
-
- while (timeout-- > 0) {
- val = snd_via82xx_codec_xread(chip);
- val1 = val & (VIA_REG_AC97_BUSY | stat);
- if (val1 == stat)
- return val & 0xffff;
- udelay(1);
- }
- return -EIO;
-}
-
-static void snd_via82xx_codec_wait(struct snd_ac97 *ac97)
-{
- struct via82xx *chip = ac97->private_data;
- int err;
- err = snd_via82xx_codec_ready(chip, ac97->num);
- /* here we need to wait fairly for long time.. */
- if (!nodelay)
- msleep(500);
-}
-
-static void snd_via82xx_codec_write(struct snd_ac97 *ac97,
- unsigned short reg,
- unsigned short val)
-{
- struct via82xx *chip = ac97->private_data;
- unsigned int xval;
-
- xval = !ac97->num ? VIA_REG_AC97_CODEC_ID_PRIMARY : VIA_REG_AC97_CODEC_ID_SECONDARY;
- xval <<= VIA_REG_AC97_CODEC_ID_SHIFT;
- xval |= reg << VIA_REG_AC97_CMD_SHIFT;
- xval |= val << VIA_REG_AC97_DATA_SHIFT;
- snd_via82xx_codec_xwrite(chip, xval);
- snd_via82xx_codec_ready(chip, ac97->num);
-}
-
-static unsigned short snd_via82xx_codec_read(struct snd_ac97 *ac97, unsigned short reg)
-{
- struct via82xx *chip = ac97->private_data;
- unsigned int xval, val = 0xffff;
- int again = 0;
-
- xval = ac97->num << VIA_REG_AC97_CODEC_ID_SHIFT;
- xval |= ac97->num ? VIA_REG_AC97_SECONDARY_VALID : VIA_REG_AC97_PRIMARY_VALID;
- xval |= VIA_REG_AC97_READ;
- xval |= (reg & 0x7f) << VIA_REG_AC97_CMD_SHIFT;
- while (1) {
- if (again++ > 3) {
- snd_printk(KERN_ERR "codec_read: codec %i is not valid [0x%x]\n",
- ac97->num, snd_via82xx_codec_xread(chip));
- return 0xffff;
- }
- snd_via82xx_codec_xwrite(chip, xval);
- udelay (20);
- if (snd_via82xx_codec_valid(chip, ac97->num) >= 0) {
- udelay(25);
- val = snd_via82xx_codec_xread(chip);
- break;
- }
- }
- return val & 0xffff;
-}
-
-static void snd_via82xx_channel_reset(struct via82xx *chip, struct viadev *viadev)
-{
- outb(VIA_REG_CTRL_PAUSE | VIA_REG_CTRL_TERMINATE | VIA_REG_CTRL_RESET,
- VIADEV_REG(viadev, OFFSET_CONTROL));
- inb(VIADEV_REG(viadev, OFFSET_CONTROL));
- udelay(50);
- /* disable interrupts */
- outb(0x00, VIADEV_REG(viadev, OFFSET_CONTROL));
- /* clear interrupts */
- outb(0x03, VIADEV_REG(viadev, OFFSET_STATUS));
- outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */
- // outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR));
- viadev->lastpos = 0;
- viadev->hwptr_done = 0;
-}
-
-
-/*
- * Interrupt handler
- * Used for 686 and 8233A
- */
-static irqreturn_t snd_via686_interrupt(int irq, void *dev_id)
-{
- struct via82xx *chip = dev_id;
- unsigned int status;
- unsigned int i;
-
- status = inl(VIAREG(chip, SGD_SHADOW));
- if (! (status & chip->intr_mask)) {
- if (chip->rmidi)
- /* check mpu401 interrupt */
- return snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
- return IRQ_NONE;
- }
-
- /* check status for each stream */
- spin_lock(&chip->reg_lock);
- for (i = 0; i < chip->num_devs; i++) {
- struct viadev *viadev = &chip->devs[i];
- unsigned char c_status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
- if (! (c_status & (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG|VIA_REG_STAT_STOPPED)))
- continue;
- if (viadev->substream && viadev->running) {
- /*
- * Update hwptr_done based on 'period elapsed'
- * interrupts. We'll use it, when the chip returns 0
- * for OFFSET_CURR_COUNT.
- */
- if (c_status & VIA_REG_STAT_EOL)
- viadev->hwptr_done = 0;
- else
- viadev->hwptr_done += viadev->fragsize;
- viadev->in_interrupt = c_status;
- spin_unlock(&chip->reg_lock);
- snd_pcm_period_elapsed(viadev->substream);
- spin_lock(&chip->reg_lock);
- viadev->in_interrupt = 0;
- }
- outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
- }
- spin_unlock(&chip->reg_lock);
- return IRQ_HANDLED;
-}
-
-/*
- * Interrupt handler
- */
-static irqreturn_t snd_via8233_interrupt(int irq, void *dev_id)
-{
- struct via82xx *chip = dev_id;
- unsigned int status;
- unsigned int i;
- int irqreturn = 0;
-
- /* check status for each stream */
- spin_lock(&chip->reg_lock);
- status = inl(VIAREG(chip, SGD_SHADOW));
-
- for (i = 0; i < chip->num_devs; i++) {
- struct viadev *viadev = &chip->devs[i];
- struct snd_pcm_substream *substream;
- unsigned char c_status, shadow_status;
-
- shadow_status = (status >> viadev->shadow_shift) &
- (VIA8233_SHADOW_STAT_ACTIVE|VIA_REG_STAT_EOL|
- VIA_REG_STAT_FLAG);
- c_status = shadow_status & (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG);
- if (!c_status)
- continue;
-
- substream = viadev->substream;
- if (substream && viadev->running) {
- /*
- * Update hwptr_done based on 'period elapsed'
- * interrupts. We'll use it, when the chip returns 0
- * for OFFSET_CURR_COUNT.
- */
- if (c_status & VIA_REG_STAT_EOL)
- viadev->hwptr_done = 0;
- else
- viadev->hwptr_done += viadev->fragsize;
- viadev->in_interrupt = c_status;
- if (shadow_status & VIA8233_SHADOW_STAT_ACTIVE)
- viadev->in_interrupt |= VIA_REG_STAT_ACTIVE;
- spin_unlock(&chip->reg_lock);
-
- snd_pcm_period_elapsed(substream);
-
- spin_lock(&chip->reg_lock);
- viadev->in_interrupt = 0;
- }
- outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
- irqreturn = 1;
- }
- spin_unlock(&chip->reg_lock);
- return IRQ_RETVAL(irqreturn);
-}
-
-/*
- * PCM callbacks
- */
-
-/*
- * trigger callback
- */
-static int snd_via82xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct via82xx *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = substream->runtime->private_data;
- unsigned char val;
-
- if (chip->chip_type != TYPE_VIA686)
- val = VIA_REG_CTRL_INT;
- else
- val = 0;
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- val |= VIA_REG_CTRL_START;
- viadev->running = 1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- val = VIA_REG_CTRL_TERMINATE;
- viadev->running = 0;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- val |= VIA_REG_CTRL_PAUSE;
- viadev->running = 0;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- viadev->running = 1;
- break;
- default:
- return -EINVAL;
- }
- outb(val, VIADEV_REG(viadev, OFFSET_CONTROL));
- if (cmd == SNDRV_PCM_TRIGGER_STOP)
- snd_via82xx_channel_reset(chip, viadev);
- return 0;
-}
-
-
-/*
- * pointer callbacks
- */
-
-/*
- * calculate the linear position at the given sg-buffer index and the rest count
- */
-
-#define check_invalid_pos(viadev,pos) \
- ((pos) < viadev->lastpos && ((pos) >= viadev->bufsize2 ||\
- viadev->lastpos < viadev->bufsize2))
-
-static inline unsigned int calc_linear_pos(struct viadev *viadev, unsigned int idx,
- unsigned int count)
-{
- unsigned int size, base, res;
-
- size = viadev->idx_table[idx].size;
- base = viadev->idx_table[idx].offset;
- res = base + size - count;
- if (res >= viadev->bufsize)
- res -= viadev->bufsize;
-
- /* check the validity of the calculated position */
- if (size < count) {
- snd_printd(KERN_ERR "invalid via82xx_cur_ptr (size = %d, count = %d)\n",
- (int)size, (int)count);
- res = viadev->lastpos;
- } else {
- if (! count) {
- /* Some mobos report count = 0 on the DMA boundary,
- * i.e. count = size indeed.
- * Let's check whether this step is above the expected size.
- */
- int delta = res - viadev->lastpos;
- if (delta < 0)
- delta += viadev->bufsize;
- if ((unsigned int)delta > viadev->fragsize)
- res = base;
- }
- if (check_invalid_pos(viadev, res)) {
-#ifdef POINTER_DEBUG
- printk(KERN_DEBUG "fail: idx = %i/%i, lastpos = 0x%x, "
- "bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, "
- "count = 0x%x\n", idx, viadev->tbl_entries,
- viadev->lastpos, viadev->bufsize2,
- viadev->idx_table[idx].offset,
- viadev->idx_table[idx].size, count);
-#endif
- /* count register returns full size when end of buffer is reached */
- res = base + size;
- if (check_invalid_pos(viadev, res)) {
- snd_printd(KERN_ERR "invalid via82xx_cur_ptr (2), "
- "using last valid pointer\n");
- res = viadev->lastpos;
- }
- }
- }
- return res;
-}
-
-/*
- * get the current pointer on via686
- */
-static snd_pcm_uframes_t snd_via686_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct via82xx *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = substream->runtime->private_data;
- unsigned int idx, ptr, count, res;
-
- if (snd_BUG_ON(!viadev->tbl_entries))
- return 0;
- if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
- return 0;
-
- spin_lock(&chip->reg_lock);
- count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT)) & 0xffffff;
- /* The via686a does not have the current index register,
- * so we need to calculate the index from CURR_PTR.
- */
- ptr = inl(VIADEV_REG(viadev, OFFSET_CURR_PTR));
- if (ptr <= (unsigned int)viadev->table.addr)
- idx = 0;
- else /* CURR_PTR holds the address + 8 */
- idx = ((ptr - (unsigned int)viadev->table.addr) / 8 - 1) % viadev->tbl_entries;
- res = calc_linear_pos(viadev, idx, count);
- viadev->lastpos = res; /* remember the last position */
- spin_unlock(&chip->reg_lock);
-
- return bytes_to_frames(substream->runtime, res);
-}
-
-/*
- * get the current pointer on via823x
- */
-static snd_pcm_uframes_t snd_via8233_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct via82xx *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = substream->runtime->private_data;
- unsigned int idx, count, res;
- int status;
-
- if (snd_BUG_ON(!viadev->tbl_entries))
- return 0;
-
- spin_lock(&chip->reg_lock);
- count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT));
- status = viadev->in_interrupt;
- if (!status)
- status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
-
- /* An apparent bug in the 8251 is worked around by sending a
- * REG_CTRL_START. */
- if (chip->revision == VIA_REV_8251 && (status & VIA_REG_STAT_EOL))
- snd_via82xx_pcm_trigger(substream, SNDRV_PCM_TRIGGER_START);
-
- if (!(status & VIA_REG_STAT_ACTIVE)) {
- res = 0;
- goto unlock;
- }
- if (count & 0xffffff) {
- idx = count >> 24;
- if (idx >= viadev->tbl_entries) {
-#ifdef POINTER_DEBUG
- printk(KERN_DEBUG "fail: invalid idx = %i/%i\n", idx,
- viadev->tbl_entries);
-#endif
- res = viadev->lastpos;
- } else {
- count &= 0xffffff;
- res = calc_linear_pos(viadev, idx, count);
- }
- } else {
- res = viadev->hwptr_done;
- if (!viadev->in_interrupt) {
- if (status & VIA_REG_STAT_EOL) {
- res = 0;
- } else
- if (status & VIA_REG_STAT_FLAG) {
- res += viadev->fragsize;
- }
- }
- }
-unlock:
- viadev->lastpos = res;
- spin_unlock(&chip->reg_lock);
-
- return bytes_to_frames(substream->runtime, res);
-}
-
-
-/*
- * hw_params callback:
- * allocate the buffer and build up the buffer description table
- */
-static int snd_via82xx_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct via82xx *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = substream->runtime->private_data;
- int err;
-
- err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
- err = build_via_table(viadev, substream, chip->pci,
- params_periods(hw_params),
- params_period_bytes(hw_params));
- if (err < 0)
- return err;
-
- return 0;
-}
-
-/*
- * hw_free callback:
- * clean up the buffer description table and release the buffer
- */
-static int snd_via82xx_hw_free(struct snd_pcm_substream *substream)
-{
- struct via82xx *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = substream->runtime->private_data;
-
- clean_via_table(viadev, substream, chip->pci);
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-
-/*
- * set up the table pointer
- */
-static void snd_via82xx_set_table_ptr(struct via82xx *chip, struct viadev *viadev)
-{
- snd_via82xx_codec_ready(chip, 0);
- outl((u32)viadev->table.addr, VIADEV_REG(viadev, OFFSET_TABLE_PTR));
- udelay(20);
- snd_via82xx_codec_ready(chip, 0);
-}
-
-/*
- * prepare callback for playback and capture on via686
- */
-static void via686_setup_format(struct via82xx *chip, struct viadev *viadev,
- struct snd_pcm_runtime *runtime)
-{
- snd_via82xx_channel_reset(chip, viadev);
- /* this must be set after channel_reset */
- snd_via82xx_set_table_ptr(chip, viadev);
- outb(VIA_REG_TYPE_AUTOSTART |
- (runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA_REG_TYPE_16BIT : 0) |
- (runtime->channels > 1 ? VIA_REG_TYPE_STEREO : 0) |
- ((viadev->reg_offset & 0x10) == 0 ? VIA_REG_TYPE_INT_LSAMPLE : 0) |
- VIA_REG_TYPE_INT_EOL |
- VIA_REG_TYPE_INT_FLAG, VIADEV_REG(viadev, OFFSET_TYPE));
-}
-
-static int snd_via686_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct via82xx *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = substream->runtime->private_data;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate);
- snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate);
- via686_setup_format(chip, viadev, runtime);
- return 0;
-}
-
-static int snd_via686_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct via82xx *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = substream->runtime->private_data;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- snd_ac97_set_rate(chip->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
- via686_setup_format(chip, viadev, runtime);
- return 0;
-}
-
-/*
- * lock the current rate
- */
-static int via_lock_rate(struct via_rate_lock *rec, int rate)
-{
- int changed = 0;
-
- spin_lock_irq(&rec->lock);
- if (rec->rate != rate) {
- if (rec->rate && rec->used > 1) /* already set */
- changed = -EINVAL;
- else {
- rec->rate = rate;
- changed = 1;
- }
- }
- spin_unlock_irq(&rec->lock);
- return changed;
-}
-
-/*
- * prepare callback for DSX playback on via823x
- */
-static int snd_via8233_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct via82xx *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = substream->runtime->private_data;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int ac97_rate = chip->dxs_src ? 48000 : runtime->rate;
- int rate_changed;
- u32 rbits;
-
- if ((rate_changed = via_lock_rate(&chip->rates[0], ac97_rate)) < 0)
- return rate_changed;
- if (rate_changed)
- snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE,
- chip->no_vra ? 48000 : runtime->rate);
- if (chip->spdif_on && viadev->reg_offset == 0x30)
- snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate);
-
- if (runtime->rate == 48000)
- rbits = 0xfffff;
- else
- rbits = (0x100000 / 48000) * runtime->rate +
- ((0x100000 % 48000) * runtime->rate) / 48000;
- snd_BUG_ON(rbits & ~0xfffff);
- snd_via82xx_channel_reset(chip, viadev);
- snd_via82xx_set_table_ptr(chip, viadev);
- outb(chip->playback_volume[viadev->reg_offset / 0x10][0],
- VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_L));
- outb(chip->playback_volume[viadev->reg_offset / 0x10][1],
- VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_R));
- outl((runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA8233_REG_TYPE_16BIT : 0) | /* format */
- (runtime->channels > 1 ? VIA8233_REG_TYPE_STEREO : 0) | /* stereo */
- rbits | /* rate */
- 0xff000000, /* STOP index is never reached */
- VIADEV_REG(viadev, OFFSET_STOP_IDX));
- udelay(20);
- snd_via82xx_codec_ready(chip, 0);
- return 0;
-}
-
-/*
- * prepare callback for multi-channel playback on via823x
- */
-static int snd_via8233_multi_prepare(struct snd_pcm_substream *substream)
-{
- struct via82xx *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = substream->runtime->private_data;
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int slots;
- int fmt;
-
- if (via_lock_rate(&chip->rates[0], runtime->rate) < 0)
- return -EINVAL;
- snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate);
- snd_ac97_set_rate(chip->ac97, AC97_PCM_SURR_DAC_RATE, runtime->rate);
- snd_ac97_set_rate(chip->ac97, AC97_PCM_LFE_DAC_RATE, runtime->rate);
- snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate);
- snd_via82xx_channel_reset(chip, viadev);
- snd_via82xx_set_table_ptr(chip, viadev);
-
- fmt = (runtime->format == SNDRV_PCM_FORMAT_S16_LE) ?
- VIA_REG_MULTPLAY_FMT_16BIT : VIA_REG_MULTPLAY_FMT_8BIT;
- fmt |= runtime->channels << 4;
- outb(fmt, VIADEV_REG(viadev, OFS_MULTPLAY_FORMAT));
-#if 0
- if (chip->revision == VIA_REV_8233A)
- slots = 0;
- else
-#endif
- {
- /* set sample number to slot 3, 4, 7, 8, 6, 9 (for VIA8233/C,8235) */
- /* corresponding to FL, FR, RL, RR, C, LFE ?? */
- switch (runtime->channels) {
- case 1: slots = (1<<0) | (1<<4); break;
- case 2: slots = (1<<0) | (2<<4); break;
- case 3: slots = (1<<0) | (2<<4) | (5<<8); break;
- case 4: slots = (1<<0) | (2<<4) | (3<<8) | (4<<12); break;
- case 5: slots = (1<<0) | (2<<4) | (3<<8) | (4<<12) | (5<<16); break;
- case 6: slots = (1<<0) | (2<<4) | (3<<8) | (4<<12) | (5<<16) | (6<<20); break;
- default: slots = 0; break;
- }
- }
- /* STOP index is never reached */
- outl(0xff000000 | slots, VIADEV_REG(viadev, OFFSET_STOP_IDX));
- udelay(20);
- snd_via82xx_codec_ready(chip, 0);
- return 0;
-}
-
-/*
- * prepare callback for capture on via823x
- */
-static int snd_via8233_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct via82xx *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = substream->runtime->private_data;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- if (via_lock_rate(&chip->rates[1], runtime->rate) < 0)
- return -EINVAL;
- snd_ac97_set_rate(chip->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
- snd_via82xx_channel_reset(chip, viadev);
- snd_via82xx_set_table_ptr(chip, viadev);
- outb(VIA_REG_CAPTURE_FIFO_ENABLE, VIADEV_REG(viadev, OFS_CAPTURE_FIFO));
- outl((runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA8233_REG_TYPE_16BIT : 0) |
- (runtime->channels > 1 ? VIA8233_REG_TYPE_STEREO : 0) |
- 0xff000000, /* STOP index is never reached */
- VIADEV_REG(viadev, OFFSET_STOP_IDX));
- udelay(20);
- snd_via82xx_codec_ready(chip, 0);
- return 0;
-}
-
-
-/*
- * pcm hardware definition, identical for both playback and capture
- */
-static struct snd_pcm_hardware snd_via82xx_hw =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- /* SNDRV_PCM_INFO_RESUME | */
- SNDRV_PCM_INFO_PAUSE),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = VIA_MAX_BUFSIZE,
- .period_bytes_min = 32,
- .period_bytes_max = VIA_MAX_BUFSIZE / 2,
- .periods_min = 2,
- .periods_max = VIA_TABLE_SIZE / 2,
- .fifo_size = 0,
-};
-
-
-/*
- * open callback skeleton
- */
-static int snd_via82xx_pcm_open(struct via82xx *chip, struct viadev *viadev,
- struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
- struct via_rate_lock *ratep;
- bool use_src = false;
-
- runtime->hw = snd_via82xx_hw;
-
- /* set the hw rate condition */
- ratep = &chip->rates[viadev->direction];
- spin_lock_irq(&ratep->lock);
- ratep->used++;
- if (chip->spdif_on && viadev->reg_offset == 0x30) {
- /* DXS#3 and spdif is on */
- runtime->hw.rates = chip->ac97->rates[AC97_RATES_SPDIF];
- snd_pcm_limit_hw_rates(runtime);
- } else if (chip->dxs_fixed && viadev->reg_offset < 0x40) {
- /* fixed DXS playback rate */
- runtime->hw.rates = SNDRV_PCM_RATE_48000;
- runtime->hw.rate_min = runtime->hw.rate_max = 48000;
- } else if (chip->dxs_src && viadev->reg_offset < 0x40) {
- /* use full SRC capabilities of DXS */
- runtime->hw.rates = (SNDRV_PCM_RATE_CONTINUOUS |
- SNDRV_PCM_RATE_8000_48000);
- runtime->hw.rate_min = 8000;
- runtime->hw.rate_max = 48000;
- use_src = true;
- } else if (! ratep->rate) {
- int idx = viadev->direction ? AC97_RATES_ADC : AC97_RATES_FRONT_DAC;
- runtime->hw.rates = chip->ac97->rates[idx];
- snd_pcm_limit_hw_rates(runtime);
- } else {
- /* a fixed rate */
- runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
- runtime->hw.rate_max = runtime->hw.rate_min = ratep->rate;
- }
- spin_unlock_irq(&ratep->lock);
-
- /* we may remove following constaint when we modify table entries
- in interrupt */
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
- return err;
-
- if (use_src) {
- err = snd_pcm_hw_rule_noresample(runtime, 48000);
- if (err < 0)
- return err;
- }
-
- runtime->private_data = viadev;
- viadev->substream = substream;
-
- return 0;
-}
-
-
-/*
- * open callback for playback on via686
- */
-static int snd_via686_playback_open(struct snd_pcm_substream *substream)
-{
- struct via82xx *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = &chip->devs[chip->playback_devno + substream->number];
- int err;
-
- if ((err = snd_via82xx_pcm_open(chip, viadev, substream)) < 0)
- return err;
- return 0;
-}
-
-/*
- * open callback for playback on via823x DXS
- */
-static int snd_via8233_playback_open(struct snd_pcm_substream *substream)
-{
- struct via82xx *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev;
- unsigned int stream;
- int err;
-
- viadev = &chip->devs[chip->playback_devno + substream->number];
- if ((err = snd_via82xx_pcm_open(chip, viadev, substream)) < 0)
- return err;
- stream = viadev->reg_offset / 0x10;
- if (chip->dxs_controls[stream]) {
- chip->playback_volume[stream][0] =
- VIA_DXS_MAX_VOLUME - (dxs_init_volume & 31);
- chip->playback_volume[stream][1] =
- VIA_DXS_MAX_VOLUME - (dxs_init_volume & 31);
- chip->dxs_controls[stream]->vd[0].access &=
- ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO,
- &chip->dxs_controls[stream]->id);
- }
- return 0;
-}
-
-/*
- * open callback for playback on via823x multi-channel
- */
-static int snd_via8233_multi_open(struct snd_pcm_substream *substream)
-{
- struct via82xx *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = &chip->devs[chip->multi_devno];
- int err;
- /* channels constraint for VIA8233A
- * 3 and 5 channels are not supported
- */
- static unsigned int channels[] = {
- 1, 2, 4, 6
- };
- static struct snd_pcm_hw_constraint_list hw_constraints_channels = {
- .count = ARRAY_SIZE(channels),
- .list = channels,
- .mask = 0,
- };
-
- if ((err = snd_via82xx_pcm_open(chip, viadev, substream)) < 0)
- return err;
- substream->runtime->hw.channels_max = 6;
- if (chip->revision == VIA_REV_8233A)
- snd_pcm_hw_constraint_list(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- &hw_constraints_channels);
- return 0;
-}
-
-/*
- * open callback for capture on via686 and via823x
- */
-static int snd_via82xx_capture_open(struct snd_pcm_substream *substream)
-{
- struct via82xx *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = &chip->devs[chip->capture_devno + substream->pcm->device];
-
- return snd_via82xx_pcm_open(chip, viadev, substream);
-}
-
-/*
- * close callback
- */
-static int snd_via82xx_pcm_close(struct snd_pcm_substream *substream)
-{
- struct via82xx *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = substream->runtime->private_data;
- struct via_rate_lock *ratep;
-
- /* release the rate lock */
- ratep = &chip->rates[viadev->direction];
- spin_lock_irq(&ratep->lock);
- ratep->used--;
- if (! ratep->used)
- ratep->rate = 0;
- spin_unlock_irq(&ratep->lock);
- if (! ratep->rate) {
- if (! viadev->direction) {
- snd_ac97_update_power(chip->ac97,
- AC97_PCM_FRONT_DAC_RATE, 0);
- snd_ac97_update_power(chip->ac97,
- AC97_PCM_SURR_DAC_RATE, 0);
- snd_ac97_update_power(chip->ac97,
- AC97_PCM_LFE_DAC_RATE, 0);
- } else
- snd_ac97_update_power(chip->ac97,
- AC97_PCM_LR_ADC_RATE, 0);
- }
- viadev->substream = NULL;
- return 0;
-}
-
-static int snd_via8233_playback_close(struct snd_pcm_substream *substream)
-{
- struct via82xx *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = substream->runtime->private_data;
- unsigned int stream;
-
- stream = viadev->reg_offset / 0x10;
- if (chip->dxs_controls[stream]) {
- chip->dxs_controls[stream]->vd[0].access |=
- SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO,
- &chip->dxs_controls[stream]->id);
- }
- return snd_via82xx_pcm_close(substream);
-}
-
-
-/* via686 playback callbacks */
-static struct snd_pcm_ops snd_via686_playback_ops = {
- .open = snd_via686_playback_open,
- .close = snd_via82xx_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_via82xx_hw_params,
- .hw_free = snd_via82xx_hw_free,
- .prepare = snd_via686_playback_prepare,
- .trigger = snd_via82xx_pcm_trigger,
- .pointer = snd_via686_pcm_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
-/* via686 capture callbacks */
-static struct snd_pcm_ops snd_via686_capture_ops = {
- .open = snd_via82xx_capture_open,
- .close = snd_via82xx_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_via82xx_hw_params,
- .hw_free = snd_via82xx_hw_free,
- .prepare = snd_via686_capture_prepare,
- .trigger = snd_via82xx_pcm_trigger,
- .pointer = snd_via686_pcm_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
-/* via823x DSX playback callbacks */
-static struct snd_pcm_ops snd_via8233_playback_ops = {
- .open = snd_via8233_playback_open,
- .close = snd_via8233_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_via82xx_hw_params,
- .hw_free = snd_via82xx_hw_free,
- .prepare = snd_via8233_playback_prepare,
- .trigger = snd_via82xx_pcm_trigger,
- .pointer = snd_via8233_pcm_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
-/* via823x multi-channel playback callbacks */
-static struct snd_pcm_ops snd_via8233_multi_ops = {
- .open = snd_via8233_multi_open,
- .close = snd_via82xx_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_via82xx_hw_params,
- .hw_free = snd_via82xx_hw_free,
- .prepare = snd_via8233_multi_prepare,
- .trigger = snd_via82xx_pcm_trigger,
- .pointer = snd_via8233_pcm_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
-/* via823x capture callbacks */
-static struct snd_pcm_ops snd_via8233_capture_ops = {
- .open = snd_via82xx_capture_open,
- .close = snd_via82xx_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_via82xx_hw_params,
- .hw_free = snd_via82xx_hw_free,
- .prepare = snd_via8233_capture_prepare,
- .trigger = snd_via82xx_pcm_trigger,
- .pointer = snd_via8233_pcm_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
-
-static void init_viadev(struct via82xx *chip, int idx, unsigned int reg_offset,
- int shadow_pos, int direction)
-{
- chip->devs[idx].reg_offset = reg_offset;
- chip->devs[idx].shadow_shift = shadow_pos * 4;
- chip->devs[idx].direction = direction;
- chip->devs[idx].port = chip->port + reg_offset;
-}
-
-/*
- * create pcm instances for VIA8233, 8233C and 8235 (not 8233A)
- */
-static int __devinit snd_via8233_pcm_new(struct via82xx *chip)
-{
- struct snd_pcm *pcm;
- int i, err;
-
- chip->playback_devno = 0; /* x 4 */
- chip->multi_devno = 4; /* x 1 */
- chip->capture_devno = 5; /* x 2 */
- chip->num_devs = 7;
- chip->intr_mask = 0x33033333; /* FLAG|EOL for rec0-1, mc, sdx0-3 */
-
- /* PCM #0: 4 DSX playbacks and 1 capture */
- err = snd_pcm_new(chip->card, chip->card->shortname, 0, 4, 1, &pcm);
- if (err < 0)
- return err;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via8233_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via8233_capture_ops);
- pcm->private_data = chip;
- strcpy(pcm->name, chip->card->shortname);
- chip->pcms[0] = pcm;
- /* set up playbacks */
- for (i = 0; i < 4; i++)
- init_viadev(chip, i, 0x10 * i, i, 0);
- /* capture */
- init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1);
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(chip->pci),
- 64*1024, VIA_MAX_BUFSIZE);
-
- /* PCM #1: multi-channel playback and 2nd capture */
- err = snd_pcm_new(chip->card, chip->card->shortname, 1, 1, 1, &pcm);
- if (err < 0)
- return err;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via8233_multi_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via8233_capture_ops);
- pcm->private_data = chip;
- strcpy(pcm->name, chip->card->shortname);
- chip->pcms[1] = pcm;
- /* set up playback */
- init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 4, 0);
- /* set up capture */
- init_viadev(chip, chip->capture_devno + 1, VIA_REG_CAPTURE_8233_STATUS + 0x10, 7, 1);
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(chip->pci),
- 64*1024, VIA_MAX_BUFSIZE);
- return 0;
-}
-
-/*
- * create pcm instances for VIA8233A
- */
-static int __devinit snd_via8233a_pcm_new(struct via82xx *chip)
-{
- struct snd_pcm *pcm;
- int err;
-
- chip->multi_devno = 0;
- chip->playback_devno = 1;
- chip->capture_devno = 2;
- chip->num_devs = 3;
- chip->intr_mask = 0x03033000; /* FLAG|EOL for rec0, mc, sdx3 */
-
- /* PCM #0: multi-channel playback and capture */
- err = snd_pcm_new(chip->card, chip->card->shortname, 0, 1, 1, &pcm);
- if (err < 0)
- return err;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via8233_multi_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via8233_capture_ops);
- pcm->private_data = chip;
- strcpy(pcm->name, chip->card->shortname);
- chip->pcms[0] = pcm;
- /* set up playback */
- init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 4, 0);
- /* capture */
- init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1);
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(chip->pci),
- 64*1024, VIA_MAX_BUFSIZE);
-
- /* SPDIF supported? */
- if (! ac97_can_spdif(chip->ac97))
- return 0;
-
- /* PCM #1: DXS3 playback (for spdif) */
- err = snd_pcm_new(chip->card, chip->card->shortname, 1, 1, 0, &pcm);
- if (err < 0)
- return err;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via8233_playback_ops);
- pcm->private_data = chip;
- strcpy(pcm->name, chip->card->shortname);
- chip->pcms[1] = pcm;
- /* set up playback */
- init_viadev(chip, chip->playback_devno, 0x30, 3, 0);
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(chip->pci),
- 64*1024, VIA_MAX_BUFSIZE);
- return 0;
-}
-
-/*
- * create a pcm instance for via686a/b
- */
-static int __devinit snd_via686_pcm_new(struct via82xx *chip)
-{
- struct snd_pcm *pcm;
- int err;
-
- chip->playback_devno = 0;
- chip->capture_devno = 1;
- chip->num_devs = 2;
- chip->intr_mask = 0x77; /* FLAG | EOL for PB, CP, FM */
-
- err = snd_pcm_new(chip->card, chip->card->shortname, 0, 1, 1, &pcm);
- if (err < 0)
- return err;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via686_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via686_capture_ops);
- pcm->private_data = chip;
- strcpy(pcm->name, chip->card->shortname);
- chip->pcms[0] = pcm;
- init_viadev(chip, 0, VIA_REG_PLAYBACK_STATUS, 0, 0);
- init_viadev(chip, 1, VIA_REG_CAPTURE_STATUS, 0, 1);
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(chip->pci),
- 64*1024, VIA_MAX_BUFSIZE);
- return 0;
-}
-
-
-/*
- * Mixer part
- */
-
-static int snd_via8233_capture_source_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- /* formerly they were "Line" and "Mic", but it looks like that they
- * have nothing to do with the actual physical connections...
- */
- static char *texts[2] = {
- "Input1", "Input2"
- };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item >= 2)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snd_via8233_capture_source_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct via82xx *chip = snd_kcontrol_chip(kcontrol);
- unsigned long port = chip->port + (kcontrol->id.index ? (VIA_REG_CAPTURE_CHANNEL + 0x10) : VIA_REG_CAPTURE_CHANNEL);
- ucontrol->value.enumerated.item[0] = inb(port) & VIA_REG_CAPTURE_CHANNEL_MIC ? 1 : 0;
- return 0;
-}
-
-static int snd_via8233_capture_source_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct via82xx *chip = snd_kcontrol_chip(kcontrol);
- unsigned long port = chip->port + (kcontrol->id.index ? (VIA_REG_CAPTURE_CHANNEL + 0x10) : VIA_REG_CAPTURE_CHANNEL);
- u8 val, oval;
-
- spin_lock_irq(&chip->reg_lock);
- oval = inb(port);
- val = oval & ~VIA_REG_CAPTURE_CHANNEL_MIC;
- if (ucontrol->value.enumerated.item[0])
- val |= VIA_REG_CAPTURE_CHANNEL_MIC;
- if (val != oval)
- outb(val, port);
- spin_unlock_irq(&chip->reg_lock);
- return val != oval;
-}
-
-static struct snd_kcontrol_new snd_via8233_capture_source __devinitdata = {
- .name = "Input Source Select",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = snd_via8233_capture_source_info,
- .get = snd_via8233_capture_source_get,
- .put = snd_via8233_capture_source_put,
-};
-
-#define snd_via8233_dxs3_spdif_info snd_ctl_boolean_mono_info
-
-static int snd_via8233_dxs3_spdif_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct via82xx *chip = snd_kcontrol_chip(kcontrol);
- u8 val;
-
- pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &val);
- ucontrol->value.integer.value[0] = (val & VIA8233_SPDIF_DX3) ? 1 : 0;
- return 0;
-}
-
-static int snd_via8233_dxs3_spdif_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct via82xx *chip = snd_kcontrol_chip(kcontrol);
- u8 val, oval;
-
- pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &oval);
- val = oval & ~VIA8233_SPDIF_DX3;
- if (ucontrol->value.integer.value[0])
- val |= VIA8233_SPDIF_DX3;
- /* save the spdif flag for rate filtering */
- chip->spdif_on = ucontrol->value.integer.value[0] ? 1 : 0;
- if (val != oval) {
- pci_write_config_byte(chip->pci, VIA8233_SPDIF_CTRL, val);
- return 1;
- }
- return 0;
-}
-
-static struct snd_kcontrol_new snd_via8233_dxs3_spdif_control __devinitdata = {
- .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH),
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = snd_via8233_dxs3_spdif_info,
- .get = snd_via8233_dxs3_spdif_get,
- .put = snd_via8233_dxs3_spdif_put,
-};
-
-static int snd_via8233_dxs_volume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = VIA_DXS_MAX_VOLUME;
- return 0;
-}
-
-static int snd_via8233_dxs_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct via82xx *chip = snd_kcontrol_chip(kcontrol);
- unsigned int idx = kcontrol->id.subdevice;
-
- ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][0];
- ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][1];
- return 0;
-}
-
-static int snd_via8233_pcmdxs_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct via82xx *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume_c[0];
- ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume_c[1];
- return 0;
-}
-
-static int snd_via8233_dxs_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct via82xx *chip = snd_kcontrol_chip(kcontrol);
- unsigned int idx = kcontrol->id.subdevice;
- unsigned long port = chip->port + 0x10 * idx;
- unsigned char val;
- int i, change = 0;
-
- for (i = 0; i < 2; i++) {
- val = ucontrol->value.integer.value[i];
- if (val > VIA_DXS_MAX_VOLUME)
- val = VIA_DXS_MAX_VOLUME;
- val = VIA_DXS_MAX_VOLUME - val;
- change |= val != chip->playback_volume[idx][i];
- if (change) {
- chip->playback_volume[idx][i] = val;
- outb(val, port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
- }
- }
- return change;
-}
-
-static int snd_via8233_pcmdxs_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct via82xx *chip = snd_kcontrol_chip(kcontrol);
- unsigned int idx;
- unsigned char val;
- int i, change = 0;
-
- for (i = 0; i < 2; i++) {
- val = ucontrol->value.integer.value[i];
- if (val > VIA_DXS_MAX_VOLUME)
- val = VIA_DXS_MAX_VOLUME;
- val = VIA_DXS_MAX_VOLUME - val;
- if (val != chip->playback_volume_c[i]) {
- change = 1;
- chip->playback_volume_c[i] = val;
- for (idx = 0; idx < 4; idx++) {
- unsigned long port = chip->port + 0x10 * idx;
- chip->playback_volume[idx][i] = val;
- outb(val, port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
- }
- }
- }
- return change;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_dxs, -4650, 150, 1);
-
-static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control __devinitdata = {
- .name = "PCM Playback Volume",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .info = snd_via8233_dxs_volume_info,
- .get = snd_via8233_pcmdxs_volume_get,
- .put = snd_via8233_pcmdxs_volume_put,
- .tlv = { .p = db_scale_dxs }
-};
-
-static struct snd_kcontrol_new snd_via8233_dxs_volume_control __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .device = 0,
- /* .subdevice set later */
- .name = "PCM Playback Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ |
- SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .info = snd_via8233_dxs_volume_info,
- .get = snd_via8233_dxs_volume_get,
- .put = snd_via8233_dxs_volume_put,
- .tlv = { .p = db_scale_dxs }
-};
-
-/*
- */
-
-static void snd_via82xx_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
-{
- struct via82xx *chip = bus->private_data;
- chip->ac97_bus = NULL;
-}
-
-static void snd_via82xx_mixer_free_ac97(struct snd_ac97 *ac97)
-{
- struct via82xx *chip = ac97->private_data;
- chip->ac97 = NULL;
-}
-
-static struct ac97_quirk ac97_quirks[] = {
- {
- .subvendor = 0x1106,
- .subdevice = 0x4161,
- .codec_id = 0x56494161, /* VT1612A */
- .name = "Soltek SL-75DRV5",
- .type = AC97_TUNE_NONE
- },
- { /* FIXME: which codec? */
- .subvendor = 0x1106,
- .subdevice = 0x4161,
- .name = "ASRock K7VT2",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x110a,
- .subdevice = 0x0079,
- .name = "Fujitsu Siemens D1289",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x1019,
- .subdevice = 0x0a81,
- .name = "ECS K7VTA3",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x1019,
- .subdevice = 0x0a85,
- .name = "ECS L7VMM2",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x1019,
- .subdevice = 0x1841,
- .name = "ECS K7VTA3",
- .type = AC97_TUNE_HP_ONLY
- },
- {
- .subvendor = 0x1849,
- .subdevice = 0x3059,
- .name = "ASRock K7VM2",
- .type = AC97_TUNE_HP_ONLY /* VT1616 */
- },
- {
- .subvendor = 0x14cd,
- .subdevice = 0x7002,
- .name = "Unknown",
- .type = AC97_TUNE_ALC_JACK
- },
- {
- .subvendor = 0x1071,
- .subdevice = 0x8590,
- .name = "Mitac Mobo",
- .type = AC97_TUNE_ALC_JACK
- },
- {
- .subvendor = 0x161f,
- .subdevice = 0x202b,
- .name = "Arima Notebook",
- .type = AC97_TUNE_HP_ONLY,
- },
- {
- .subvendor = 0x161f,
- .subdevice = 0x2032,
- .name = "Targa Traveller 811",
- .type = AC97_TUNE_HP_ONLY,
- },
- {
- .subvendor = 0x161f,
- .subdevice = 0x2032,
- .name = "m680x",
- .type = AC97_TUNE_HP_ONLY, /* http://launchpad.net/bugs/38546 */
- },
- {
- .subvendor = 0x1297,
- .subdevice = 0xa232,
- .name = "Shuttle AK32VN",
- .type = AC97_TUNE_HP_ONLY
- },
- { } /* terminator */
-};
-
-static int __devinit snd_via82xx_mixer_new(struct via82xx *chip, const char *quirk_override)
-{
- struct snd_ac97_template ac97;
- int err;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_via82xx_codec_write,
- .read = snd_via82xx_codec_read,
- .wait = snd_via82xx_codec_wait,
- };
-
- if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
- return err;
- chip->ac97_bus->private_free = snd_via82xx_mixer_free_ac97_bus;
- chip->ac97_bus->clock = chip->ac97_clock;
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = chip;
- ac97.private_free = snd_via82xx_mixer_free_ac97;
- ac97.pci = chip->pci;
- ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE;
- if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
- return err;
-
- snd_ac97_tune_hardware(chip->ac97, ac97_quirks, quirk_override);
-
- if (chip->chip_type != TYPE_VIA686) {
- /* use slot 10/11 */
- snd_ac97_update_bits(chip->ac97, AC97_EXTENDED_STATUS, 0x03 << 4, 0x03 << 4);
- }
-
- return 0;
-}
-
-#ifdef SUPPORT_JOYSTICK
-#define JOYSTICK_ADDR 0x200
-static int __devinit snd_via686_create_gameport(struct via82xx *chip, unsigned char *legacy)
-{
- struct gameport *gp;
- struct resource *r;
-
- if (!joystick)
- return -ENODEV;
-
- r = request_region(JOYSTICK_ADDR, 8, "VIA686 gameport");
- if (!r) {
- printk(KERN_WARNING "via82xx: cannot reserve joystick port 0x%#x\n",
- JOYSTICK_ADDR);
- return -EBUSY;
- }
-
- chip->gameport = gp = gameport_allocate_port();
- if (!gp) {
- printk(KERN_ERR "via82xx: cannot allocate memory for gameport\n");
- release_and_free_resource(r);
- return -ENOMEM;
- }
-
- gameport_set_name(gp, "VIA686 Gameport");
- gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
- gameport_set_dev_parent(gp, &chip->pci->dev);
- gp->io = JOYSTICK_ADDR;
- gameport_set_port_data(gp, r);
-
- /* Enable legacy joystick port */
- *legacy |= VIA_FUNC_ENABLE_GAME;
- pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, *legacy);
-
- gameport_register_port(chip->gameport);
-
- return 0;
-}
-
-static void snd_via686_free_gameport(struct via82xx *chip)
-{
- if (chip->gameport) {
- struct resource *r = gameport_get_port_data(chip->gameport);
-
- gameport_unregister_port(chip->gameport);
- chip->gameport = NULL;
- release_and_free_resource(r);
- }
-}
-#else
-static inline int snd_via686_create_gameport(struct via82xx *chip, unsigned char *legacy)
-{
- return -ENOSYS;
-}
-static inline void snd_via686_free_gameport(struct via82xx *chip) { }
-#endif
-
-
-/*
- *
- */
-
-static int __devinit snd_via8233_init_misc(struct via82xx *chip)
-{
- int i, err, caps;
- unsigned char val;
-
- caps = chip->chip_type == TYPE_VIA8233A ? 1 : 2;
- for (i = 0; i < caps; i++) {
- snd_via8233_capture_source.index = i;
- err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_capture_source, chip));
- if (err < 0)
- return err;
- }
- if (ac97_can_spdif(chip->ac97)) {
- err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs3_spdif_control, chip));
- if (err < 0)
- return err;
- }
- if (chip->chip_type != TYPE_VIA8233A) {
- /* when no h/w PCM volume control is found, use DXS volume control
- * as the PCM vol control
- */
- struct snd_ctl_elem_id sid;
- memset(&sid, 0, sizeof(sid));
- strcpy(sid.name, "PCM Playback Volume");
- sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- if (! snd_ctl_find_id(chip->card, &sid)) {
- snd_printd(KERN_INFO "Using DXS as PCM Playback\n");
- err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_pcmdxs_volume_control, chip));
- if (err < 0)
- return err;
- }
- else /* Using DXS when PCM emulation is enabled is really weird */
- {
- for (i = 0; i < 4; ++i) {
- struct snd_kcontrol *kctl;
-
- kctl = snd_ctl_new1(
- &snd_via8233_dxs_volume_control, chip);
- if (!kctl)
- return -ENOMEM;
- kctl->id.subdevice = i;
- err = snd_ctl_add(chip->card, kctl);
- if (err < 0)
- return err;
- chip->dxs_controls[i] = kctl;
- }
- }
- }
- /* select spdif data slot 10/11 */
- pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &val);
- val = (val & ~VIA8233_SPDIF_SLOT_MASK) | VIA8233_SPDIF_SLOT_1011;
- val &= ~VIA8233_SPDIF_DX3; /* SPDIF off as default */
- pci_write_config_byte(chip->pci, VIA8233_SPDIF_CTRL, val);
-
- return 0;
-}
-
-static int __devinit snd_via686_init_misc(struct via82xx *chip)
-{
- unsigned char legacy, legacy_cfg;
- int rev_h = 0;
-
- legacy = chip->old_legacy;
- legacy_cfg = chip->old_legacy_cfg;
- legacy |= VIA_FUNC_MIDI_IRQMASK; /* FIXME: correct? (disable MIDI) */
- legacy &= ~VIA_FUNC_ENABLE_GAME; /* disable joystick */
- if (chip->revision >= VIA_REV_686_H) {
- rev_h = 1;
- if (mpu_port >= 0x200) { /* force MIDI */
- mpu_port &= 0xfffc;
- pci_write_config_dword(chip->pci, 0x18, mpu_port | 0x01);
-#ifdef CONFIG_PM
- chip->mpu_port_saved = mpu_port;
-#endif
- } else {
- mpu_port = pci_resource_start(chip->pci, 2);
- }
- } else {
- switch (mpu_port) { /* force MIDI */
- case 0x300:
- case 0x310:
- case 0x320:
- case 0x330:
- legacy_cfg &= ~(3 << 2);
- legacy_cfg |= (mpu_port & 0x0030) >> 2;
- break;
- default: /* no, use BIOS settings */
- if (legacy & VIA_FUNC_ENABLE_MIDI)
- mpu_port = 0x300 + ((legacy_cfg & 0x000c) << 2);
- break;
- }
- }
- if (mpu_port >= 0x200 &&
- (chip->mpu_res = request_region(mpu_port, 2, "VIA82xx MPU401"))
- != NULL) {
- if (rev_h)
- legacy |= VIA_FUNC_MIDI_PNP; /* enable PCI I/O 2 */
- legacy |= VIA_FUNC_ENABLE_MIDI;
- } else {
- if (rev_h)
- legacy &= ~VIA_FUNC_MIDI_PNP; /* disable PCI I/O 2 */
- legacy &= ~VIA_FUNC_ENABLE_MIDI;
- mpu_port = 0;
- }
-
- pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy);
- pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg);
- if (chip->mpu_res) {
- if (snd_mpu401_uart_new(chip->card, 0, MPU401_HW_VIA686A,
- mpu_port, MPU401_INFO_INTEGRATED |
- MPU401_INFO_IRQ_HOOK, -1,
- &chip->rmidi) < 0) {
- printk(KERN_WARNING "unable to initialize MPU-401"
- " at 0x%lx, skipping\n", mpu_port);
- legacy &= ~VIA_FUNC_ENABLE_MIDI;
- } else {
- legacy &= ~VIA_FUNC_MIDI_IRQMASK; /* enable MIDI interrupt */
- }
- pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy);
- }
-
- snd_via686_create_gameport(chip, &legacy);
-
-#ifdef CONFIG_PM
- chip->legacy_saved = legacy;
- chip->legacy_cfg_saved = legacy_cfg;
-#endif
-
- return 0;
-}
-
-
-/*
- * proc interface
- */
-static void snd_via82xx_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct via82xx *chip = entry->private_data;
- int i;
-
- snd_iprintf(buffer, "%s\n\n", chip->card->longname);
- for (i = 0; i < 0xa0; i += 4) {
- snd_iprintf(buffer, "%02x: %08x\n", i, inl(chip->port + i));
- }
-}
-
-static void __devinit snd_via82xx_proc_init(struct via82xx *chip)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(chip->card, "via82xx", &entry))
- snd_info_set_text_ops(entry, chip, snd_via82xx_proc_read);
-}
-
-/*
- *
- */
-
-static int snd_via82xx_chip_init(struct via82xx *chip)
-{
- unsigned int val;
- unsigned long end_time;
- unsigned char pval;
-
-#if 0 /* broken on K7M? */
- if (chip->chip_type == TYPE_VIA686)
- /* disable all legacy ports */
- pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, 0);
-#endif
- pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
- if (! (pval & VIA_ACLINK_C00_READY)) { /* codec not ready? */
- /* deassert ACLink reset, force SYNC */
- pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL,
- VIA_ACLINK_CTRL_ENABLE |
- VIA_ACLINK_CTRL_RESET |
- VIA_ACLINK_CTRL_SYNC);
- udelay(100);
-#if 1 /* FIXME: should we do full reset here for all chip models? */
- pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, 0x00);
- udelay(100);
-#else
- /* deassert ACLink reset, force SYNC (warm AC'97 reset) */
- pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL,
- VIA_ACLINK_CTRL_RESET|VIA_ACLINK_CTRL_SYNC);
- udelay(2);
-#endif
- /* ACLink on, deassert ACLink reset, VSR, SGD data out */
- /* note - FM data out has trouble with non VRA codecs !! */
- pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, VIA_ACLINK_CTRL_INIT);
- udelay(100);
- }
-
- /* Make sure VRA is enabled, in case we didn't do a
- * complete codec reset, above */
- pci_read_config_byte(chip->pci, VIA_ACLINK_CTRL, &pval);
- if ((pval & VIA_ACLINK_CTRL_INIT) != VIA_ACLINK_CTRL_INIT) {
- /* ACLink on, deassert ACLink reset, VSR, SGD data out */
- /* note - FM data out has trouble with non VRA codecs !! */
- pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, VIA_ACLINK_CTRL_INIT);
- udelay(100);
- }
-
- /* wait until codec ready */
- end_time = jiffies + msecs_to_jiffies(750);
- do {
- pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
- if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
- break;
- schedule_timeout_uninterruptible(1);
- } while (time_before(jiffies, end_time));
-
- if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
- snd_printk(KERN_ERR "AC'97 codec is not ready [0x%x]\n", val);
-
-#if 0 /* FIXME: we don't support the second codec yet so skip the detection now.. */
- snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
- VIA_REG_AC97_SECONDARY_VALID |
- (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT));
- end_time = jiffies + msecs_to_jiffies(750);
- snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
- VIA_REG_AC97_SECONDARY_VALID |
- (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT));
- do {
- if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_SECONDARY_VALID) {
- chip->ac97_secondary = 1;
- goto __ac97_ok2;
- }
- schedule_timeout_uninterruptible(1);
- } while (time_before(jiffies, end_time));
- /* This is ok, the most of motherboards have only one codec */
-
- __ac97_ok2:
-#endif
-
- if (chip->chip_type == TYPE_VIA686) {
- /* route FM trap to IRQ, disable FM trap */
- pci_write_config_byte(chip->pci, VIA_FM_NMI_CTRL, 0);
- /* disable all GPI interrupts */
- outl(0, VIAREG(chip, GPI_INTR));
- }
-
- if (chip->chip_type != TYPE_VIA686) {
- /* Workaround for Award BIOS bug:
- * DXS channels don't work properly with VRA if MC97 is disabled.
- */
- struct pci_dev *pci;
- pci = pci_get_device(0x1106, 0x3068, NULL); /* MC97 */
- if (pci) {
- unsigned char data;
- pci_read_config_byte(pci, 0x44, &data);
- pci_write_config_byte(pci, 0x44, data | 0x40);
- pci_dev_put(pci);
- }
- }
-
- if (chip->chip_type != TYPE_VIA8233A) {
- int i, idx;
- for (idx = 0; idx < 4; idx++) {
- unsigned long port = chip->port + 0x10 * idx;
- for (i = 0; i < 2; i++) {
- chip->playback_volume[idx][i]=chip->playback_volume_c[i];
- outb(chip->playback_volume_c[i],
- port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
- }
- }
- }
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-/*
- * power management
- */
-static int snd_via82xx_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct via82xx *chip = card->private_data;
- int i;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- for (i = 0; i < 2; i++)
- snd_pcm_suspend_all(chip->pcms[i]);
- for (i = 0; i < chip->num_devs; i++)
- snd_via82xx_channel_reset(chip, &chip->devs[i]);
- synchronize_irq(chip->irq);
- snd_ac97_suspend(chip->ac97);
-
- /* save misc values */
- if (chip->chip_type != TYPE_VIA686) {
- pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &chip->spdif_ctrl_saved);
- chip->capture_src_saved[0] = inb(chip->port + VIA_REG_CAPTURE_CHANNEL);
- chip->capture_src_saved[1] = inb(chip->port + VIA_REG_CAPTURE_CHANNEL + 0x10);
- }
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int snd_via82xx_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct via82xx *chip = card->private_data;
- int i;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "via82xx: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
-
- snd_via82xx_chip_init(chip);
-
- if (chip->chip_type == TYPE_VIA686) {
- if (chip->mpu_port_saved)
- pci_write_config_dword(chip->pci, 0x18, chip->mpu_port_saved | 0x01);
- pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, chip->legacy_saved);
- pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, chip->legacy_cfg_saved);
- } else {
- pci_write_config_byte(chip->pci, VIA8233_SPDIF_CTRL, chip->spdif_ctrl_saved);
- outb(chip->capture_src_saved[0], chip->port + VIA_REG_CAPTURE_CHANNEL);
- outb(chip->capture_src_saved[1], chip->port + VIA_REG_CAPTURE_CHANNEL + 0x10);
- }
-
- snd_ac97_resume(chip->ac97);
-
- for (i = 0; i < chip->num_devs; i++)
- snd_via82xx_channel_reset(chip, &chip->devs[i]);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif /* CONFIG_PM */
-
-static int snd_via82xx_free(struct via82xx *chip)
-{
- unsigned int i;
-
- if (chip->irq < 0)
- goto __end_hw;
- /* disable interrupts */
- for (i = 0; i < chip->num_devs; i++)
- snd_via82xx_channel_reset(chip, &chip->devs[i]);
-
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
- __end_hw:
- release_and_free_resource(chip->mpu_res);
- pci_release_regions(chip->pci);
-
- if (chip->chip_type == TYPE_VIA686) {
- snd_via686_free_gameport(chip);
- pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, chip->old_legacy);
- pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, chip->old_legacy_cfg);
- }
- pci_disable_device(chip->pci);
- kfree(chip);
- return 0;
-}
-
-static int snd_via82xx_dev_free(struct snd_device *device)
-{
- struct via82xx *chip = device->device_data;
- return snd_via82xx_free(chip);
-}
-
-static int __devinit snd_via82xx_create(struct snd_card *card,
- struct pci_dev *pci,
- int chip_type,
- int revision,
- unsigned int ac97_clock,
- struct via82xx ** r_via)
-{
- struct via82xx *chip;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_via82xx_dev_free,
- };
-
- if ((err = pci_enable_device(pci)) < 0)
- return err;
-
- if ((chip = kzalloc(sizeof(*chip), GFP_KERNEL)) == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- chip->chip_type = chip_type;
- chip->revision = revision;
-
- spin_lock_init(&chip->reg_lock);
- spin_lock_init(&chip->rates[0].lock);
- spin_lock_init(&chip->rates[1].lock);
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
-
- pci_read_config_byte(pci, VIA_FUNC_ENABLE, &chip->old_legacy);
- pci_read_config_byte(pci, VIA_PNP_CONTROL, &chip->old_legacy_cfg);
- pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE,
- chip->old_legacy & ~(VIA_FUNC_ENABLE_SB|VIA_FUNC_ENABLE_FM));
-
- if ((err = pci_request_regions(pci, card->driver)) < 0) {
- kfree(chip);
- pci_disable_device(pci);
- return err;
- }
- chip->port = pci_resource_start(pci, 0);
- if (request_irq(pci->irq,
- chip_type == TYPE_VIA8233 ?
- snd_via8233_interrupt : snd_via686_interrupt,
- IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_via82xx_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
- if (ac97_clock >= 8000 && ac97_clock <= 48000)
- chip->ac97_clock = ac97_clock;
- synchronize_irq(chip->irq);
-
- if ((err = snd_via82xx_chip_init(chip)) < 0) {
- snd_via82xx_free(chip);
- return err;
- }
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_via82xx_free(chip);
- return err;
- }
-
- /* The 8233 ac97 controller does not implement the master bit
- * in the pci command register. IMHO this is a violation of the PCI spec.
- * We call pci_set_master here because it does not hurt. */
- pci_set_master(pci);
-
- snd_card_set_dev(card, &pci->dev);
-
- *r_via = chip;
- return 0;
-}
-
-struct via823x_info {
- int revision;
- char *name;
- int type;
-};
-static struct via823x_info via823x_cards[] __devinitdata = {
- { VIA_REV_PRE_8233, "VIA 8233-Pre", TYPE_VIA8233 },
- { VIA_REV_8233C, "VIA 8233C", TYPE_VIA8233 },
- { VIA_REV_8233, "VIA 8233", TYPE_VIA8233 },
- { VIA_REV_8233A, "VIA 8233A", TYPE_VIA8233A },
- { VIA_REV_8235, "VIA 8235", TYPE_VIA8233 },
- { VIA_REV_8237, "VIA 8237", TYPE_VIA8233 },
- { VIA_REV_8251, "VIA 8251", TYPE_VIA8233 },
-};
-
-/*
- * auto detection of DXS channel supports.
- */
-
-static struct snd_pci_quirk dxs_whitelist[] __devinitdata = {
- SND_PCI_QUIRK(0x1005, 0x4710, "Avance Logic Mobo", VIA_DXS_ENABLE),
- SND_PCI_QUIRK(0x1019, 0x0996, "ESC Mobo", VIA_DXS_48K),
- SND_PCI_QUIRK(0x1019, 0x0a81, "ECS K7VTA3 v8.0", VIA_DXS_NO_VRA),
- SND_PCI_QUIRK(0x1019, 0x0a85, "ECS L7VMM2", VIA_DXS_NO_VRA),
- SND_PCI_QUIRK_VENDOR(0x1019, "ESC K8", VIA_DXS_SRC),
- SND_PCI_QUIRK(0x1019, 0xaa01, "ESC K8T890-A", VIA_DXS_SRC),
- SND_PCI_QUIRK(0x1025, 0x0033, "Acer Inspire 1353LM", VIA_DXS_NO_VRA),
- SND_PCI_QUIRK(0x1025, 0x0046, "Acer Aspire 1524 WLMi", VIA_DXS_SRC),
- SND_PCI_QUIRK_VENDOR(0x1043, "ASUS A7/A8", VIA_DXS_NO_VRA),
- SND_PCI_QUIRK_VENDOR(0x1071, "Diverse Notebook", VIA_DXS_NO_VRA),
- SND_PCI_QUIRK(0x10cf, 0x118e, "FSC Laptop", VIA_DXS_ENABLE),
- SND_PCI_QUIRK_VENDOR(0x1106, "ASRock", VIA_DXS_SRC),
- SND_PCI_QUIRK(0x1297, 0xa231, "Shuttle AK31v2", VIA_DXS_SRC),
- SND_PCI_QUIRK(0x1297, 0xa232, "Shuttle", VIA_DXS_SRC),
- SND_PCI_QUIRK(0x1297, 0xc160, "Shuttle Sk41G", VIA_DXS_SRC),
- SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte GA-7VAXP", VIA_DXS_ENABLE),
- SND_PCI_QUIRK(0x1462, 0x3800, "MSI KT266", VIA_DXS_ENABLE),
- SND_PCI_QUIRK(0x1462, 0x7120, "MSI KT4V", VIA_DXS_ENABLE),
- SND_PCI_QUIRK(0x1462, 0x7142, "MSI K8MM-V", VIA_DXS_ENABLE),
- SND_PCI_QUIRK_VENDOR(0x1462, "MSI Mobo", VIA_DXS_SRC),
- SND_PCI_QUIRK(0x147b, 0x1401, "ABIT KD7(-RAID)", VIA_DXS_ENABLE),
- SND_PCI_QUIRK(0x147b, 0x1411, "ABIT VA-20", VIA_DXS_ENABLE),
- SND_PCI_QUIRK(0x147b, 0x1413, "ABIT KV8 Pro", VIA_DXS_ENABLE),
- SND_PCI_QUIRK(0x147b, 0x1415, "ABIT AV8", VIA_DXS_NO_VRA),
- SND_PCI_QUIRK(0x14ff, 0x0403, "Twinhead mobo", VIA_DXS_ENABLE),
- SND_PCI_QUIRK(0x14ff, 0x0408, "Twinhead laptop", VIA_DXS_SRC),
- SND_PCI_QUIRK(0x1558, 0x4701, "Clevo D470", VIA_DXS_SRC),
- SND_PCI_QUIRK(0x1584, 0x8120, "Diverse Laptop", VIA_DXS_ENABLE),
- SND_PCI_QUIRK(0x1584, 0x8123, "Targa/Uniwill", VIA_DXS_NO_VRA),
- SND_PCI_QUIRK(0x161f, 0x202b, "Amira Notebook", VIA_DXS_NO_VRA),
- SND_PCI_QUIRK(0x161f, 0x2032, "m680x machines", VIA_DXS_48K),
- SND_PCI_QUIRK(0x1631, 0xe004, "PB EasyNote 3174", VIA_DXS_ENABLE),
- SND_PCI_QUIRK(0x1695, 0x3005, "EPoX EP-8K9A", VIA_DXS_ENABLE),
- SND_PCI_QUIRK_VENDOR(0x1695, "EPoX mobo", VIA_DXS_SRC),
- SND_PCI_QUIRK_VENDOR(0x16f3, "Jetway K8", VIA_DXS_SRC),
- SND_PCI_QUIRK_VENDOR(0x1734, "FSC Laptop", VIA_DXS_SRC),
- SND_PCI_QUIRK(0x1849, 0x3059, "ASRock K7VM2", VIA_DXS_NO_VRA),
- SND_PCI_QUIRK_VENDOR(0x1849, "ASRock mobo", VIA_DXS_SRC),
- SND_PCI_QUIRK(0x1919, 0x200a, "Soltek SL-K8", VIA_DXS_NO_VRA),
- SND_PCI_QUIRK(0x4005, 0x4710, "MSI K7T266", VIA_DXS_SRC),
- { } /* terminator */
-};
-
-static int __devinit check_dxs_list(struct pci_dev *pci, int revision)
-{
- const struct snd_pci_quirk *w;
-
- w = snd_pci_quirk_lookup(pci, dxs_whitelist);
- if (w) {
- snd_printdd(KERN_INFO "via82xx: DXS white list for %s found\n",
- w->name);
- return w->value;
- }
-
- /* for newer revision, default to DXS_SRC */
- if (revision >= VIA_REV_8235)
- return VIA_DXS_SRC;
-
- /*
- * not detected, try 48k rate only to be sure.
- */
- printk(KERN_INFO "via82xx: Assuming DXS channels with 48k fixed sample rate.\n");
- printk(KERN_INFO " Please try dxs_support=5 option\n");
- printk(KERN_INFO " and report if it works on your machine.\n");
- printk(KERN_INFO " For more details, read ALSA-Configuration.txt.\n");
- return VIA_DXS_48K;
-};
-
-static int __devinit snd_via82xx_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- struct snd_card *card;
- struct via82xx *chip;
- int chip_type = 0, card_type;
- unsigned int i;
- int err;
-
- err = snd_card_create(index, id, THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- card_type = pci_id->driver_data;
- switch (card_type) {
- case TYPE_CARD_VIA686:
- strcpy(card->driver, "VIA686A");
- sprintf(card->shortname, "VIA 82C686A/B rev%x", pci->revision);
- chip_type = TYPE_VIA686;
- break;
- case TYPE_CARD_VIA8233:
- chip_type = TYPE_VIA8233;
- sprintf(card->shortname, "VIA 823x rev%x", pci->revision);
- for (i = 0; i < ARRAY_SIZE(via823x_cards); i++) {
- if (pci->revision == via823x_cards[i].revision) {
- chip_type = via823x_cards[i].type;
- strcpy(card->shortname, via823x_cards[i].name);
- break;
- }
- }
- if (chip_type != TYPE_VIA8233A) {
- if (dxs_support == VIA_DXS_AUTO)
- dxs_support = check_dxs_list(pci, pci->revision);
- /* force to use VIA8233 or 8233A model according to
- * dxs_support module option
- */
- if (dxs_support == VIA_DXS_DISABLE)
- chip_type = TYPE_VIA8233A;
- else
- chip_type = TYPE_VIA8233;
- }
- if (chip_type == TYPE_VIA8233A)
- strcpy(card->driver, "VIA8233A");
- else if (pci->revision >= VIA_REV_8237)
- strcpy(card->driver, "VIA8237"); /* no slog assignment */
- else
- strcpy(card->driver, "VIA8233");
- break;
- default:
- snd_printk(KERN_ERR "invalid card type %d\n", card_type);
- err = -EINVAL;
- goto __error;
- }
-
- if ((err = snd_via82xx_create(card, pci, chip_type, pci->revision,
- ac97_clock, &chip)) < 0)
- goto __error;
- card->private_data = chip;
- if ((err = snd_via82xx_mixer_new(chip, ac97_quirk)) < 0)
- goto __error;
-
- if (chip_type == TYPE_VIA686) {
- if ((err = snd_via686_pcm_new(chip)) < 0 ||
- (err = snd_via686_init_misc(chip)) < 0)
- goto __error;
- } else {
- if (chip_type == TYPE_VIA8233A) {
- if ((err = snd_via8233a_pcm_new(chip)) < 0)
- goto __error;
- // chip->dxs_fixed = 1; /* FIXME: use 48k for DXS #3? */
- } else {
- if ((err = snd_via8233_pcm_new(chip)) < 0)
- goto __error;
- if (dxs_support == VIA_DXS_48K)
- chip->dxs_fixed = 1;
- else if (dxs_support == VIA_DXS_NO_VRA)
- chip->no_vra = 1;
- else if (dxs_support == VIA_DXS_SRC) {
- chip->no_vra = 1;
- chip->dxs_src = 1;
- }
- }
- if ((err = snd_via8233_init_misc(chip)) < 0)
- goto __error;
- }
-
- /* disable interrupts */
- for (i = 0; i < chip->num_devs; i++)
- snd_via82xx_channel_reset(chip, &chip->devs[i]);
-
- snprintf(card->longname, sizeof(card->longname),
- "%s with %s at %#lx, irq %d", card->shortname,
- snd_ac97_get_short_name(chip->ac97), chip->port, chip->irq);
-
- snd_via82xx_proc_init(chip);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- pci_set_drvdata(pci, card);
- return 0;
-
- __error:
- snd_card_free(card);
- return err;
-}
-
-static void __devexit snd_via82xx_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_via82xx_ids,
- .probe = snd_via82xx_probe,
- .remove = __devexit_p(snd_via82xx_remove),
-#ifdef CONFIG_PM
- .suspend = snd_via82xx_suspend,
- .resume = snd_via82xx_resume,
-#endif
-};
-
-static int __init alsa_card_via82xx_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_via82xx_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_via82xx_init)
-module_exit(alsa_card_via82xx_exit)
diff --git a/ANDROID_3.4.5/sound/pci/via82xx_modem.c b/ANDROID_3.4.5/sound/pci/via82xx_modem.c
deleted file mode 100644
index 5efcbcac..00000000
--- a/ANDROID_3.4.5/sound/pci/via82xx_modem.c
+++ /dev/null
@@ -1,1248 +0,0 @@
-/*
- * ALSA modem driver for VIA VT82xx (South Bridge)
- *
- * VT82C686A/B/C, VT8233A/C, VT8235
- *
- * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
- * Tjeerd.Mulder <Tjeerd.Mulder@fujitsu-siemens.com>
- * 2002 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- * Changes:
- *
- * Sep. 2, 2004 Sasha Khapyorsky <sashak@alsa-project.org>
- * Modified from original audio driver 'via82xx.c' to support AC97
- * modems.
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/info.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-
-#if 0
-#define POINTER_DEBUG
-#endif
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("VIA VT82xx modem");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{VIA,VT82C686A/B/C modem,pci}}");
-
-static int index = -2; /* Exclude the first card */
-static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-static int ac97_clock = 48000;
-
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for VIA 82xx bridge.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for VIA 82xx bridge.");
-module_param(ac97_clock, int, 0444);
-MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
-
-/* just for backward compatibility */
-static bool enable;
-module_param(enable, bool, 0444);
-
-
-/*
- * Direct registers
- */
-
-#define VIAREG(via, x) ((via)->port + VIA_REG_##x)
-#define VIADEV_REG(viadev, x) ((viadev)->port + VIA_REG_##x)
-
-/* common offsets */
-#define VIA_REG_OFFSET_STATUS 0x00 /* byte - channel status */
-#define VIA_REG_STAT_ACTIVE 0x80 /* RO */
-#define VIA_REG_STAT_PAUSED 0x40 /* RO */
-#define VIA_REG_STAT_TRIGGER_QUEUED 0x08 /* RO */
-#define VIA_REG_STAT_STOPPED 0x04 /* RWC */
-#define VIA_REG_STAT_EOL 0x02 /* RWC */
-#define VIA_REG_STAT_FLAG 0x01 /* RWC */
-#define VIA_REG_OFFSET_CONTROL 0x01 /* byte - channel control */
-#define VIA_REG_CTRL_START 0x80 /* WO */
-#define VIA_REG_CTRL_TERMINATE 0x40 /* WO */
-#define VIA_REG_CTRL_AUTOSTART 0x20
-#define VIA_REG_CTRL_PAUSE 0x08 /* RW */
-#define VIA_REG_CTRL_INT_STOP 0x04
-#define VIA_REG_CTRL_INT_EOL 0x02
-#define VIA_REG_CTRL_INT_FLAG 0x01
-#define VIA_REG_CTRL_RESET 0x01 /* RW - probably reset? undocumented */
-#define VIA_REG_CTRL_INT (VIA_REG_CTRL_INT_FLAG | VIA_REG_CTRL_INT_EOL | VIA_REG_CTRL_AUTOSTART)
-#define VIA_REG_OFFSET_TYPE 0x02 /* byte - channel type (686 only) */
-#define VIA_REG_TYPE_AUTOSTART 0x80 /* RW - autostart at EOL */
-#define VIA_REG_TYPE_16BIT 0x20 /* RW */
-#define VIA_REG_TYPE_STEREO 0x10 /* RW */
-#define VIA_REG_TYPE_INT_LLINE 0x00
-#define VIA_REG_TYPE_INT_LSAMPLE 0x04
-#define VIA_REG_TYPE_INT_LESSONE 0x08
-#define VIA_REG_TYPE_INT_MASK 0x0c
-#define VIA_REG_TYPE_INT_EOL 0x02
-#define VIA_REG_TYPE_INT_FLAG 0x01
-#define VIA_REG_OFFSET_TABLE_PTR 0x04 /* dword - channel table pointer */
-#define VIA_REG_OFFSET_CURR_PTR 0x04 /* dword - channel current pointer */
-#define VIA_REG_OFFSET_STOP_IDX 0x08 /* dword - stop index, channel type, sample rate */
-#define VIA_REG_OFFSET_CURR_COUNT 0x0c /* dword - channel current count (24 bit) */
-#define VIA_REG_OFFSET_CURR_INDEX 0x0f /* byte - channel current index (for via8233 only) */
-
-#define DEFINE_VIA_REGSET(name,val) \
-enum {\
- VIA_REG_##name##_STATUS = (val),\
- VIA_REG_##name##_CONTROL = (val) + 0x01,\
- VIA_REG_##name##_TYPE = (val) + 0x02,\
- VIA_REG_##name##_TABLE_PTR = (val) + 0x04,\
- VIA_REG_##name##_CURR_PTR = (val) + 0x04,\
- VIA_REG_##name##_STOP_IDX = (val) + 0x08,\
- VIA_REG_##name##_CURR_COUNT = (val) + 0x0c,\
-}
-
-/* modem block */
-DEFINE_VIA_REGSET(MO, 0x40);
-DEFINE_VIA_REGSET(MI, 0x50);
-
-/* AC'97 */
-#define VIA_REG_AC97 0x80 /* dword */
-#define VIA_REG_AC97_CODEC_ID_MASK (3<<30)
-#define VIA_REG_AC97_CODEC_ID_SHIFT 30
-#define VIA_REG_AC97_CODEC_ID_PRIMARY 0x00
-#define VIA_REG_AC97_CODEC_ID_SECONDARY 0x01
-#define VIA_REG_AC97_SECONDARY_VALID (1<<27)
-#define VIA_REG_AC97_PRIMARY_VALID (1<<25)
-#define VIA_REG_AC97_BUSY (1<<24)
-#define VIA_REG_AC97_READ (1<<23)
-#define VIA_REG_AC97_CMD_SHIFT 16
-#define VIA_REG_AC97_CMD_MASK 0x7e
-#define VIA_REG_AC97_DATA_SHIFT 0
-#define VIA_REG_AC97_DATA_MASK 0xffff
-
-#define VIA_REG_SGD_SHADOW 0x84 /* dword */
-#define VIA_REG_SGD_STAT_PB_FLAG (1<<0)
-#define VIA_REG_SGD_STAT_CP_FLAG (1<<1)
-#define VIA_REG_SGD_STAT_FM_FLAG (1<<2)
-#define VIA_REG_SGD_STAT_PB_EOL (1<<4)
-#define VIA_REG_SGD_STAT_CP_EOL (1<<5)
-#define VIA_REG_SGD_STAT_FM_EOL (1<<6)
-#define VIA_REG_SGD_STAT_PB_STOP (1<<8)
-#define VIA_REG_SGD_STAT_CP_STOP (1<<9)
-#define VIA_REG_SGD_STAT_FM_STOP (1<<10)
-#define VIA_REG_SGD_STAT_PB_ACTIVE (1<<12)
-#define VIA_REG_SGD_STAT_CP_ACTIVE (1<<13)
-#define VIA_REG_SGD_STAT_FM_ACTIVE (1<<14)
-#define VIA_REG_SGD_STAT_MR_FLAG (1<<16)
-#define VIA_REG_SGD_STAT_MW_FLAG (1<<17)
-#define VIA_REG_SGD_STAT_MR_EOL (1<<20)
-#define VIA_REG_SGD_STAT_MW_EOL (1<<21)
-#define VIA_REG_SGD_STAT_MR_STOP (1<<24)
-#define VIA_REG_SGD_STAT_MW_STOP (1<<25)
-#define VIA_REG_SGD_STAT_MR_ACTIVE (1<<28)
-#define VIA_REG_SGD_STAT_MW_ACTIVE (1<<29)
-
-#define VIA_REG_GPI_STATUS 0x88
-#define VIA_REG_GPI_INTR 0x8c
-
-#define VIA_TBL_BIT_FLAG 0x40000000
-#define VIA_TBL_BIT_EOL 0x80000000
-
-/* pci space */
-#define VIA_ACLINK_STAT 0x40
-#define VIA_ACLINK_C11_READY 0x20
-#define VIA_ACLINK_C10_READY 0x10
-#define VIA_ACLINK_C01_READY 0x04 /* secondary codec ready */
-#define VIA_ACLINK_LOWPOWER 0x02 /* low-power state */
-#define VIA_ACLINK_C00_READY 0x01 /* primary codec ready */
-#define VIA_ACLINK_CTRL 0x41
-#define VIA_ACLINK_CTRL_ENABLE 0x80 /* 0: disable, 1: enable */
-#define VIA_ACLINK_CTRL_RESET 0x40 /* 0: assert, 1: de-assert */
-#define VIA_ACLINK_CTRL_SYNC 0x20 /* 0: release SYNC, 1: force SYNC hi */
-#define VIA_ACLINK_CTRL_SDO 0x10 /* 0: release SDO, 1: force SDO hi */
-#define VIA_ACLINK_CTRL_VRA 0x08 /* 0: disable VRA, 1: enable VRA */
-#define VIA_ACLINK_CTRL_PCM 0x04 /* 0: disable PCM, 1: enable PCM */
-#define VIA_ACLINK_CTRL_FM 0x02 /* via686 only */
-#define VIA_ACLINK_CTRL_SB 0x01 /* via686 only */
-#define VIA_ACLINK_CTRL_INIT (VIA_ACLINK_CTRL_ENABLE|\
- VIA_ACLINK_CTRL_RESET|\
- VIA_ACLINK_CTRL_PCM)
-#define VIA_FUNC_ENABLE 0x42
-#define VIA_FUNC_MIDI_PNP 0x80 /* FIXME: it's 0x40 in the datasheet! */
-#define VIA_FUNC_MIDI_IRQMASK 0x40 /* FIXME: not documented! */
-#define VIA_FUNC_RX2C_WRITE 0x20
-#define VIA_FUNC_SB_FIFO_EMPTY 0x10
-#define VIA_FUNC_ENABLE_GAME 0x08
-#define VIA_FUNC_ENABLE_FM 0x04
-#define VIA_FUNC_ENABLE_MIDI 0x02
-#define VIA_FUNC_ENABLE_SB 0x01
-#define VIA_PNP_CONTROL 0x43
-#define VIA_MC97_CTRL 0x44
-#define VIA_MC97_CTRL_ENABLE 0x80
-#define VIA_MC97_CTRL_SECONDARY 0x40
-#define VIA_MC97_CTRL_INIT (VIA_MC97_CTRL_ENABLE|\
- VIA_MC97_CTRL_SECONDARY)
-
-
-/*
- * pcm stream
- */
-
-struct snd_via_sg_table {
- unsigned int offset;
- unsigned int size;
-} ;
-
-#define VIA_TABLE_SIZE 255
-
-struct viadev {
- unsigned int reg_offset;
- unsigned long port;
- int direction; /* playback = 0, capture = 1 */
- struct snd_pcm_substream *substream;
- int running;
- unsigned int tbl_entries; /* # descriptors */
- struct snd_dma_buffer table;
- struct snd_via_sg_table *idx_table;
- /* for recovery from the unexpected pointer */
- unsigned int lastpos;
- unsigned int bufsize;
- unsigned int bufsize2;
-};
-
-enum { TYPE_CARD_VIA82XX_MODEM = 1 };
-
-#define VIA_MAX_MODEM_DEVS 2
-
-struct via82xx_modem {
- int irq;
-
- unsigned long port;
-
- unsigned int intr_mask; /* SGD_SHADOW mask to check interrupts */
-
- struct pci_dev *pci;
- struct snd_card *card;
-
- unsigned int num_devs;
- unsigned int playback_devno, capture_devno;
- struct viadev devs[VIA_MAX_MODEM_DEVS];
-
- struct snd_pcm *pcms[2];
-
- struct snd_ac97_bus *ac97_bus;
- struct snd_ac97 *ac97;
- unsigned int ac97_clock;
- unsigned int ac97_secondary; /* secondary AC'97 codec is present */
-
- spinlock_t reg_lock;
- struct snd_info_entry *proc_entry;
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_via82xx_modem_ids) = {
- { PCI_VDEVICE(VIA, 0x3068), TYPE_CARD_VIA82XX_MODEM, },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_via82xx_modem_ids);
-
-/*
- */
-
-/*
- * allocate and initialize the descriptor buffers
- * periods = number of periods
- * fragsize = period size in bytes
- */
-static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substream,
- struct pci_dev *pci,
- unsigned int periods, unsigned int fragsize)
-{
- unsigned int i, idx, ofs, rest;
- struct via82xx_modem *chip = snd_pcm_substream_chip(substream);
-
- if (dev->table.area == NULL) {
- /* the start of each lists must be aligned to 8 bytes,
- * but the kernel pages are much bigger, so we don't care
- */
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
- PAGE_ALIGN(VIA_TABLE_SIZE * 2 * 8),
- &dev->table) < 0)
- return -ENOMEM;
- }
- if (! dev->idx_table) {
- dev->idx_table = kmalloc(sizeof(*dev->idx_table) * VIA_TABLE_SIZE, GFP_KERNEL);
- if (! dev->idx_table)
- return -ENOMEM;
- }
-
- /* fill the entries */
- idx = 0;
- ofs = 0;
- for (i = 0; i < periods; i++) {
- rest = fragsize;
- /* fill descriptors for a period.
- * a period can be split to several descriptors if it's
- * over page boundary.
- */
- do {
- unsigned int r;
- unsigned int flag;
- unsigned int addr;
-
- if (idx >= VIA_TABLE_SIZE) {
- snd_printk(KERN_ERR "via82xx: too much table size!\n");
- return -EINVAL;
- }
- addr = snd_pcm_sgbuf_get_addr(substream, ofs);
- ((u32 *)dev->table.area)[idx << 1] = cpu_to_le32(addr);
- r = PAGE_SIZE - (ofs % PAGE_SIZE);
- if (rest < r)
- r = rest;
- rest -= r;
- if (! rest) {
- if (i == periods - 1)
- flag = VIA_TBL_BIT_EOL; /* buffer boundary */
- else
- flag = VIA_TBL_BIT_FLAG; /* period boundary */
- } else
- flag = 0; /* period continues to the next */
- /*
- printk(KERN_DEBUG "via: tbl %d: at %d size %d "
- "(rest %d)\n", idx, ofs, r, rest);
- */
- ((u32 *)dev->table.area)[(idx<<1) + 1] = cpu_to_le32(r | flag);
- dev->idx_table[idx].offset = ofs;
- dev->idx_table[idx].size = r;
- ofs += r;
- idx++;
- } while (rest > 0);
- }
- dev->tbl_entries = idx;
- dev->bufsize = periods * fragsize;
- dev->bufsize2 = dev->bufsize / 2;
- return 0;
-}
-
-
-static int clean_via_table(struct viadev *dev, struct snd_pcm_substream *substream,
- struct pci_dev *pci)
-{
- if (dev->table.area) {
- snd_dma_free_pages(&dev->table);
- dev->table.area = NULL;
- }
- kfree(dev->idx_table);
- dev->idx_table = NULL;
- return 0;
-}
-
-/*
- * Basic I/O
- */
-
-static inline unsigned int snd_via82xx_codec_xread(struct via82xx_modem *chip)
-{
- return inl(VIAREG(chip, AC97));
-}
-
-static inline void snd_via82xx_codec_xwrite(struct via82xx_modem *chip, unsigned int val)
-{
- outl(val, VIAREG(chip, AC97));
-}
-
-static int snd_via82xx_codec_ready(struct via82xx_modem *chip, int secondary)
-{
- unsigned int timeout = 1000; /* 1ms */
- unsigned int val;
-
- while (timeout-- > 0) {
- udelay(1);
- if (!((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY))
- return val & 0xffff;
- }
- snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n",
- secondary, snd_via82xx_codec_xread(chip));
- return -EIO;
-}
-
-static int snd_via82xx_codec_valid(struct via82xx_modem *chip, int secondary)
-{
- unsigned int timeout = 1000; /* 1ms */
- unsigned int val, val1;
- unsigned int stat = !secondary ? VIA_REG_AC97_PRIMARY_VALID :
- VIA_REG_AC97_SECONDARY_VALID;
-
- while (timeout-- > 0) {
- val = snd_via82xx_codec_xread(chip);
- val1 = val & (VIA_REG_AC97_BUSY | stat);
- if (val1 == stat)
- return val & 0xffff;
- udelay(1);
- }
- return -EIO;
-}
-
-static void snd_via82xx_codec_wait(struct snd_ac97 *ac97)
-{
- struct via82xx_modem *chip = ac97->private_data;
- int err;
- err = snd_via82xx_codec_ready(chip, ac97->num);
- /* here we need to wait fairly for long time.. */
- msleep(500);
-}
-
-static void snd_via82xx_codec_write(struct snd_ac97 *ac97,
- unsigned short reg,
- unsigned short val)
-{
- struct via82xx_modem *chip = ac97->private_data;
- unsigned int xval;
- if(reg == AC97_GPIO_STATUS) {
- outl(val, VIAREG(chip, GPI_STATUS));
- return;
- }
- xval = !ac97->num ? VIA_REG_AC97_CODEC_ID_PRIMARY : VIA_REG_AC97_CODEC_ID_SECONDARY;
- xval <<= VIA_REG_AC97_CODEC_ID_SHIFT;
- xval |= reg << VIA_REG_AC97_CMD_SHIFT;
- xval |= val << VIA_REG_AC97_DATA_SHIFT;
- snd_via82xx_codec_xwrite(chip, xval);
- snd_via82xx_codec_ready(chip, ac97->num);
-}
-
-static unsigned short snd_via82xx_codec_read(struct snd_ac97 *ac97, unsigned short reg)
-{
- struct via82xx_modem *chip = ac97->private_data;
- unsigned int xval, val = 0xffff;
- int again = 0;
-
- xval = ac97->num << VIA_REG_AC97_CODEC_ID_SHIFT;
- xval |= ac97->num ? VIA_REG_AC97_SECONDARY_VALID : VIA_REG_AC97_PRIMARY_VALID;
- xval |= VIA_REG_AC97_READ;
- xval |= (reg & 0x7f) << VIA_REG_AC97_CMD_SHIFT;
- while (1) {
- if (again++ > 3) {
- snd_printk(KERN_ERR "codec_read: codec %i is not valid [0x%x]\n",
- ac97->num, snd_via82xx_codec_xread(chip));
- return 0xffff;
- }
- snd_via82xx_codec_xwrite(chip, xval);
- udelay (20);
- if (snd_via82xx_codec_valid(chip, ac97->num) >= 0) {
- udelay(25);
- val = snd_via82xx_codec_xread(chip);
- break;
- }
- }
- return val & 0xffff;
-}
-
-static void snd_via82xx_channel_reset(struct via82xx_modem *chip, struct viadev *viadev)
-{
- outb(VIA_REG_CTRL_PAUSE | VIA_REG_CTRL_TERMINATE | VIA_REG_CTRL_RESET,
- VIADEV_REG(viadev, OFFSET_CONTROL));
- inb(VIADEV_REG(viadev, OFFSET_CONTROL));
- udelay(50);
- /* disable interrupts */
- outb(0x00, VIADEV_REG(viadev, OFFSET_CONTROL));
- /* clear interrupts */
- outb(0x03, VIADEV_REG(viadev, OFFSET_STATUS));
- outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */
- // outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR));
- viadev->lastpos = 0;
-}
-
-
-/*
- * Interrupt handler
- */
-
-static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id)
-{
- struct via82xx_modem *chip = dev_id;
- unsigned int status;
- unsigned int i;
-
- status = inl(VIAREG(chip, SGD_SHADOW));
- if (! (status & chip->intr_mask)) {
- return IRQ_NONE;
- }
-// _skip_sgd:
-
- /* check status for each stream */
- spin_lock(&chip->reg_lock);
- for (i = 0; i < chip->num_devs; i++) {
- struct viadev *viadev = &chip->devs[i];
- unsigned char c_status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
- c_status &= (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG|VIA_REG_STAT_STOPPED);
- if (! c_status)
- continue;
- if (viadev->substream && viadev->running) {
- spin_unlock(&chip->reg_lock);
- snd_pcm_period_elapsed(viadev->substream);
- spin_lock(&chip->reg_lock);
- }
- outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
- }
- spin_unlock(&chip->reg_lock);
- return IRQ_HANDLED;
-}
-
-/*
- * PCM callbacks
- */
-
-/*
- * trigger callback
- */
-static int snd_via82xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct via82xx_modem *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = substream->runtime->private_data;
- unsigned char val = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- val |= VIA_REG_CTRL_START;
- viadev->running = 1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- val = VIA_REG_CTRL_TERMINATE;
- viadev->running = 0;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- val |= VIA_REG_CTRL_PAUSE;
- viadev->running = 0;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- viadev->running = 1;
- break;
- default:
- return -EINVAL;
- }
- outb(val, VIADEV_REG(viadev, OFFSET_CONTROL));
- if (cmd == SNDRV_PCM_TRIGGER_STOP)
- snd_via82xx_channel_reset(chip, viadev);
- return 0;
-}
-
-/*
- * pointer callbacks
- */
-
-/*
- * calculate the linear position at the given sg-buffer index and the rest count
- */
-
-#define check_invalid_pos(viadev,pos) \
- ((pos) < viadev->lastpos && ((pos) >= viadev->bufsize2 ||\
- viadev->lastpos < viadev->bufsize2))
-
-static inline unsigned int calc_linear_pos(struct viadev *viadev, unsigned int idx,
- unsigned int count)
-{
- unsigned int size, res;
-
- size = viadev->idx_table[idx].size;
- res = viadev->idx_table[idx].offset + size - count;
-
- /* check the validity of the calculated position */
- if (size < count) {
- snd_printd(KERN_ERR "invalid via82xx_cur_ptr (size = %d, count = %d)\n",
- (int)size, (int)count);
- res = viadev->lastpos;
- } else if (check_invalid_pos(viadev, res)) {
-#ifdef POINTER_DEBUG
- printk(KERN_DEBUG "fail: idx = %i/%i, lastpos = 0x%x, "
- "bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, "
- "count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos,
- viadev->bufsize2, viadev->idx_table[idx].offset,
- viadev->idx_table[idx].size, count);
-#endif
- if (count && size < count) {
- snd_printd(KERN_ERR "invalid via82xx_cur_ptr, "
- "using last valid pointer\n");
- res = viadev->lastpos;
- } else {
- if (! count)
- /* bogus count 0 on the DMA boundary? */
- res = viadev->idx_table[idx].offset;
- else
- /* count register returns full size
- * when end of buffer is reached
- */
- res = viadev->idx_table[idx].offset + size;
- if (check_invalid_pos(viadev, res)) {
- snd_printd(KERN_ERR "invalid via82xx_cur_ptr (2), "
- "using last valid pointer\n");
- res = viadev->lastpos;
- }
- }
- }
- viadev->lastpos = res; /* remember the last position */
- if (res >= viadev->bufsize)
- res -= viadev->bufsize;
- return res;
-}
-
-/*
- * get the current pointer on via686
- */
-static snd_pcm_uframes_t snd_via686_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct via82xx_modem *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = substream->runtime->private_data;
- unsigned int idx, ptr, count, res;
-
- if (snd_BUG_ON(!viadev->tbl_entries))
- return 0;
- if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
- return 0;
-
- spin_lock(&chip->reg_lock);
- count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT)) & 0xffffff;
- /* The via686a does not have the current index register,
- * so we need to calculate the index from CURR_PTR.
- */
- ptr = inl(VIADEV_REG(viadev, OFFSET_CURR_PTR));
- if (ptr <= (unsigned int)viadev->table.addr)
- idx = 0;
- else /* CURR_PTR holds the address + 8 */
- idx = ((ptr - (unsigned int)viadev->table.addr) / 8 - 1) %
- viadev->tbl_entries;
- res = calc_linear_pos(viadev, idx, count);
- spin_unlock(&chip->reg_lock);
-
- return bytes_to_frames(substream->runtime, res);
-}
-
-/*
- * hw_params callback:
- * allocate the buffer and build up the buffer description table
- */
-static int snd_via82xx_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct via82xx_modem *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = substream->runtime->private_data;
- int err;
-
- err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
- err = build_via_table(viadev, substream, chip->pci,
- params_periods(hw_params),
- params_period_bytes(hw_params));
- if (err < 0)
- return err;
-
- snd_ac97_write(chip->ac97, AC97_LINE1_RATE, params_rate(hw_params));
- snd_ac97_write(chip->ac97, AC97_LINE1_LEVEL, 0);
-
- return 0;
-}
-
-/*
- * hw_free callback:
- * clean up the buffer description table and release the buffer
- */
-static int snd_via82xx_hw_free(struct snd_pcm_substream *substream)
-{
- struct via82xx_modem *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = substream->runtime->private_data;
-
- clean_via_table(viadev, substream, chip->pci);
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-
-/*
- * set up the table pointer
- */
-static void snd_via82xx_set_table_ptr(struct via82xx_modem *chip, struct viadev *viadev)
-{
- snd_via82xx_codec_ready(chip, chip->ac97_secondary);
- outl((u32)viadev->table.addr, VIADEV_REG(viadev, OFFSET_TABLE_PTR));
- udelay(20);
- snd_via82xx_codec_ready(chip, chip->ac97_secondary);
-}
-
-/*
- * prepare callback for playback and capture
- */
-static int snd_via82xx_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct via82xx_modem *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = substream->runtime->private_data;
-
- snd_via82xx_channel_reset(chip, viadev);
- /* this must be set after channel_reset */
- snd_via82xx_set_table_ptr(chip, viadev);
- outb(VIA_REG_TYPE_AUTOSTART|VIA_REG_TYPE_INT_EOL|VIA_REG_TYPE_INT_FLAG,
- VIADEV_REG(viadev, OFFSET_TYPE));
- return 0;
-}
-
-/*
- * pcm hardware definition, identical for both playback and capture
- */
-static struct snd_pcm_hardware snd_via82xx_hw =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- /* SNDRV_PCM_INFO_RESUME | */
- SNDRV_PCM_INFO_PAUSE),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_KNOT,
- .rate_min = 8000,
- .rate_max = 16000,
- .channels_min = 1,
- .channels_max = 1,
- .buffer_bytes_max = 128 * 1024,
- .period_bytes_min = 32,
- .period_bytes_max = 128 * 1024,
- .periods_min = 2,
- .periods_max = VIA_TABLE_SIZE / 2,
- .fifo_size = 0,
-};
-
-
-/*
- * open callback skeleton
- */
-static int snd_via82xx_modem_pcm_open(struct via82xx_modem *chip, struct viadev *viadev,
- struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
- static unsigned int rates[] = { 8000, 9600, 12000, 16000 };
- static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
- .count = ARRAY_SIZE(rates),
- .list = rates,
- .mask = 0,
- };
-
- runtime->hw = snd_via82xx_hw;
-
- if ((err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &hw_constraints_rates)) < 0)
- return err;
-
- /* we may remove following constaint when we modify table entries
- in interrupt */
- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
- return err;
-
- runtime->private_data = viadev;
- viadev->substream = substream;
-
- return 0;
-}
-
-
-/*
- * open callback for playback
- */
-static int snd_via82xx_playback_open(struct snd_pcm_substream *substream)
-{
- struct via82xx_modem *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = &chip->devs[chip->playback_devno + substream->number];
-
- return snd_via82xx_modem_pcm_open(chip, viadev, substream);
-}
-
-/*
- * open callback for capture
- */
-static int snd_via82xx_capture_open(struct snd_pcm_substream *substream)
-{
- struct via82xx_modem *chip = snd_pcm_substream_chip(substream);
- struct viadev *viadev = &chip->devs[chip->capture_devno + substream->pcm->device];
-
- return snd_via82xx_modem_pcm_open(chip, viadev, substream);
-}
-
-/*
- * close callback
- */
-static int snd_via82xx_pcm_close(struct snd_pcm_substream *substream)
-{
- struct viadev *viadev = substream->runtime->private_data;
-
- viadev->substream = NULL;
- return 0;
-}
-
-
-/* via686 playback callbacks */
-static struct snd_pcm_ops snd_via686_playback_ops = {
- .open = snd_via82xx_playback_open,
- .close = snd_via82xx_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_via82xx_hw_params,
- .hw_free = snd_via82xx_hw_free,
- .prepare = snd_via82xx_pcm_prepare,
- .trigger = snd_via82xx_pcm_trigger,
- .pointer = snd_via686_pcm_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
-/* via686 capture callbacks */
-static struct snd_pcm_ops snd_via686_capture_ops = {
- .open = snd_via82xx_capture_open,
- .close = snd_via82xx_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_via82xx_hw_params,
- .hw_free = snd_via82xx_hw_free,
- .prepare = snd_via82xx_pcm_prepare,
- .trigger = snd_via82xx_pcm_trigger,
- .pointer = snd_via686_pcm_pointer,
- .page = snd_pcm_sgbuf_ops_page,
-};
-
-
-static void init_viadev(struct via82xx_modem *chip, int idx, unsigned int reg_offset,
- int direction)
-{
- chip->devs[idx].reg_offset = reg_offset;
- chip->devs[idx].direction = direction;
- chip->devs[idx].port = chip->port + reg_offset;
-}
-
-/*
- * create a pcm instance for via686a/b
- */
-static int __devinit snd_via686_pcm_new(struct via82xx_modem *chip)
-{
- struct snd_pcm *pcm;
- int err;
-
- chip->playback_devno = 0;
- chip->capture_devno = 1;
- chip->num_devs = 2;
- chip->intr_mask = 0x330000; /* FLAGS | EOL for MR, MW */
-
- err = snd_pcm_new(chip->card, chip->card->shortname, 0, 1, 1, &pcm);
- if (err < 0)
- return err;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via686_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via686_capture_ops);
- pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
- pcm->private_data = chip;
- strcpy(pcm->name, chip->card->shortname);
- chip->pcms[0] = pcm;
- init_viadev(chip, 0, VIA_REG_MO_STATUS, 0);
- init_viadev(chip, 1, VIA_REG_MI_STATUS, 1);
-
- if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(chip->pci),
- 64*1024, 128*1024)) < 0)
- return err;
-
- return 0;
-}
-
-
-/*
- * Mixer part
- */
-
-
-static void snd_via82xx_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
-{
- struct via82xx_modem *chip = bus->private_data;
- chip->ac97_bus = NULL;
-}
-
-static void snd_via82xx_mixer_free_ac97(struct snd_ac97 *ac97)
-{
- struct via82xx_modem *chip = ac97->private_data;
- chip->ac97 = NULL;
-}
-
-
-static int __devinit snd_via82xx_mixer_new(struct via82xx_modem *chip)
-{
- struct snd_ac97_template ac97;
- int err;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_via82xx_codec_write,
- .read = snd_via82xx_codec_read,
- .wait = snd_via82xx_codec_wait,
- };
-
- if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
- return err;
- chip->ac97_bus->private_free = snd_via82xx_mixer_free_ac97_bus;
- chip->ac97_bus->clock = chip->ac97_clock;
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = chip;
- ac97.private_free = snd_via82xx_mixer_free_ac97;
- ac97.pci = chip->pci;
- ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
- ac97.num = chip->ac97_secondary;
-
- if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
- return err;
-
- return 0;
-}
-
-
-/*
- * proc interface
- */
-static void snd_via82xx_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- struct via82xx_modem *chip = entry->private_data;
- int i;
-
- snd_iprintf(buffer, "%s\n\n", chip->card->longname);
- for (i = 0; i < 0xa0; i += 4) {
- snd_iprintf(buffer, "%02x: %08x\n", i, inl(chip->port + i));
- }
-}
-
-static void __devinit snd_via82xx_proc_init(struct via82xx_modem *chip)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(chip->card, "via82xx", &entry))
- snd_info_set_text_ops(entry, chip, snd_via82xx_proc_read);
-}
-
-/*
- *
- */
-
-static int snd_via82xx_chip_init(struct via82xx_modem *chip)
-{
- unsigned int val;
- unsigned long end_time;
- unsigned char pval;
-
- pci_read_config_byte(chip->pci, VIA_MC97_CTRL, &pval);
- if((pval & VIA_MC97_CTRL_INIT) != VIA_MC97_CTRL_INIT) {
- pci_write_config_byte(chip->pci, 0x44, pval|VIA_MC97_CTRL_INIT);
- udelay(100);
- }
-
- pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
- if (! (pval & VIA_ACLINK_C00_READY)) { /* codec not ready? */
- /* deassert ACLink reset, force SYNC */
- pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL,
- VIA_ACLINK_CTRL_ENABLE |
- VIA_ACLINK_CTRL_RESET |
- VIA_ACLINK_CTRL_SYNC);
- udelay(100);
-#if 1 /* FIXME: should we do full reset here for all chip models? */
- pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, 0x00);
- udelay(100);
-#else
- /* deassert ACLink reset, force SYNC (warm AC'97 reset) */
- pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL,
- VIA_ACLINK_CTRL_RESET|VIA_ACLINK_CTRL_SYNC);
- udelay(2);
-#endif
- /* ACLink on, deassert ACLink reset, VSR, SGD data out */
- pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, VIA_ACLINK_CTRL_INIT);
- udelay(100);
- }
-
- pci_read_config_byte(chip->pci, VIA_ACLINK_CTRL, &pval);
- if ((pval & VIA_ACLINK_CTRL_INIT) != VIA_ACLINK_CTRL_INIT) {
- /* ACLink on, deassert ACLink reset, VSR, SGD data out */
- pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, VIA_ACLINK_CTRL_INIT);
- udelay(100);
- }
-
- /* wait until codec ready */
- end_time = jiffies + msecs_to_jiffies(750);
- do {
- pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
- if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
- break;
- schedule_timeout_uninterruptible(1);
- } while (time_before(jiffies, end_time));
-
- if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
- snd_printk(KERN_ERR "AC'97 codec is not ready [0x%x]\n", val);
-
- snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
- VIA_REG_AC97_SECONDARY_VALID |
- (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT));
- end_time = jiffies + msecs_to_jiffies(750);
- snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
- VIA_REG_AC97_SECONDARY_VALID |
- (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT));
- do {
- if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_SECONDARY_VALID) {
- chip->ac97_secondary = 1;
- goto __ac97_ok2;
- }
- schedule_timeout_uninterruptible(1);
- } while (time_before(jiffies, end_time));
- /* This is ok, the most of motherboards have only one codec */
-
- __ac97_ok2:
-
- /* route FM trap to IRQ, disable FM trap */
- // pci_write_config_byte(chip->pci, VIA_FM_NMI_CTRL, 0);
- /* disable all GPI interrupts */
- outl(0, VIAREG(chip, GPI_INTR));
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-/*
- * power management
- */
-static int snd_via82xx_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct via82xx_modem *chip = card->private_data;
- int i;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- for (i = 0; i < 2; i++)
- snd_pcm_suspend_all(chip->pcms[i]);
- for (i = 0; i < chip->num_devs; i++)
- snd_via82xx_channel_reset(chip, &chip->devs[i]);
- synchronize_irq(chip->irq);
- snd_ac97_suspend(chip->ac97);
-
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-static int snd_via82xx_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct via82xx_modem *chip = card->private_data;
- int i;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "via82xx-modem: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
-
- snd_via82xx_chip_init(chip);
-
- snd_ac97_resume(chip->ac97);
-
- for (i = 0; i < chip->num_devs; i++)
- snd_via82xx_channel_reset(chip, &chip->devs[i]);
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif /* CONFIG_PM */
-
-static int snd_via82xx_free(struct via82xx_modem *chip)
-{
- unsigned int i;
-
- if (chip->irq < 0)
- goto __end_hw;
- /* disable interrupts */
- for (i = 0; i < chip->num_devs; i++)
- snd_via82xx_channel_reset(chip, &chip->devs[i]);
-
- __end_hw:
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
- kfree(chip);
- return 0;
-}
-
-static int snd_via82xx_dev_free(struct snd_device *device)
-{
- struct via82xx_modem *chip = device->device_data;
- return snd_via82xx_free(chip);
-}
-
-static int __devinit snd_via82xx_create(struct snd_card *card,
- struct pci_dev *pci,
- int chip_type,
- int revision,
- unsigned int ac97_clock,
- struct via82xx_modem ** r_via)
-{
- struct via82xx_modem *chip;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_via82xx_dev_free,
- };
-
- if ((err = pci_enable_device(pci)) < 0)
- return err;
-
- if ((chip = kzalloc(sizeof(*chip), GFP_KERNEL)) == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
- spin_lock_init(&chip->reg_lock);
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
-
- if ((err = pci_request_regions(pci, card->driver)) < 0) {
- kfree(chip);
- pci_disable_device(pci);
- return err;
- }
- chip->port = pci_resource_start(pci, 0);
- if (request_irq(pci->irq, snd_via82xx_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_via82xx_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
- if (ac97_clock >= 8000 && ac97_clock <= 48000)
- chip->ac97_clock = ac97_clock;
- synchronize_irq(chip->irq);
-
- if ((err = snd_via82xx_chip_init(chip)) < 0) {
- snd_via82xx_free(chip);
- return err;
- }
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_via82xx_free(chip);
- return err;
- }
-
- /* The 8233 ac97 controller does not implement the master bit
- * in the pci command register. IMHO this is a violation of the PCI spec.
- * We call pci_set_master here because it does not hurt. */
- pci_set_master(pci);
-
- snd_card_set_dev(card, &pci->dev);
-
- *r_via = chip;
- return 0;
-}
-
-
-static int __devinit snd_via82xx_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- struct snd_card *card;
- struct via82xx_modem *chip;
- int chip_type = 0, card_type;
- unsigned int i;
- int err;
-
- err = snd_card_create(index, id, THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- card_type = pci_id->driver_data;
- switch (card_type) {
- case TYPE_CARD_VIA82XX_MODEM:
- strcpy(card->driver, "VIA82XX-MODEM");
- sprintf(card->shortname, "VIA 82XX modem");
- break;
- default:
- snd_printk(KERN_ERR "invalid card type %d\n", card_type);
- err = -EINVAL;
- goto __error;
- }
-
- if ((err = snd_via82xx_create(card, pci, chip_type, pci->revision,
- ac97_clock, &chip)) < 0)
- goto __error;
- card->private_data = chip;
- if ((err = snd_via82xx_mixer_new(chip)) < 0)
- goto __error;
-
- if ((err = snd_via686_pcm_new(chip)) < 0 )
- goto __error;
-
- /* disable interrupts */
- for (i = 0; i < chip->num_devs; i++)
- snd_via82xx_channel_reset(chip, &chip->devs[i]);
-
- sprintf(card->longname, "%s at 0x%lx, irq %d",
- card->shortname, chip->port, chip->irq);
-
- snd_via82xx_proc_init(chip);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- pci_set_drvdata(pci, card);
- return 0;
-
- __error:
- snd_card_free(card);
- return err;
-}
-
-static void __devexit snd_via82xx_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_via82xx_modem_ids,
- .probe = snd_via82xx_probe,
- .remove = __devexit_p(snd_via82xx_remove),
-#ifdef CONFIG_PM
- .suspend = snd_via82xx_suspend,
- .resume = snd_via82xx_resume,
-#endif
-};
-
-static int __init alsa_card_via82xx_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_via82xx_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_via82xx_init)
-module_exit(alsa_card_via82xx_exit)
diff --git a/ANDROID_3.4.5/sound/pci/vx222/Makefile b/ANDROID_3.4.5/sound/pci/vx222/Makefile
deleted file mode 100644
index a4d08d4d..00000000
--- a/ANDROID_3.4.5/sound/pci/vx222/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-vx222-objs := vx222.o vx222_ops.o
-
-obj-$(CONFIG_SND_VX222) += snd-vx222.o
diff --git a/ANDROID_3.4.5/sound/pci/vx222/vx222.c b/ANDROID_3.4.5/sound/pci/vx222/vx222.c
deleted file mode 100644
index 6a534bfe..00000000
--- a/ANDROID_3.4.5/sound/pci/vx222/vx222.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Driver for Digigram VX222 V2/Mic PCI soundcards
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include "vx222.h"
-
-#define CARD_NAME "VX222"
-
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("Digigram VX222 V2/Mic");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Digigram," CARD_NAME "}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static bool mic[SNDRV_CARDS]; /* microphone */
-static int ibl[SNDRV_CARDS]; /* microphone */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Digigram " CARD_NAME " soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Digigram " CARD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Digigram " CARD_NAME " soundcard.");
-module_param_array(mic, bool, NULL, 0444);
-MODULE_PARM_DESC(mic, "Enable Microphone.");
-module_param_array(ibl, int, NULL, 0444);
-MODULE_PARM_DESC(ibl, "Capture IBL size.");
-
-/*
- */
-
-enum {
- VX_PCI_VX222_OLD,
- VX_PCI_VX222_NEW
-};
-
-static DEFINE_PCI_DEVICE_TABLE(snd_vx222_ids) = {
- { 0x10b5, 0x9050, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_OLD, }, /* PLX */
- { 0x10b5, 0x9030, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_NEW, }, /* PLX */
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_vx222_ids);
-
-
-/*
- */
-
-static const DECLARE_TLV_DB_SCALE(db_scale_old_vol, -11350, 50, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_akm, -7350, 50, 0);
-
-static struct snd_vx_hardware vx222_old_hw = {
-
- .name = "VX222/Old",
- .type = VX_TYPE_BOARD,
- /* hw specs */
- .num_codecs = 1,
- .num_ins = 1,
- .num_outs = 1,
- .output_level_max = VX_ANALOG_OUT_LEVEL_MAX,
- .output_level_db_scale = db_scale_old_vol,
-};
-
-static struct snd_vx_hardware vx222_v2_hw = {
-
- .name = "VX222/v2",
- .type = VX_TYPE_V2,
- /* hw specs */
- .num_codecs = 1,
- .num_ins = 1,
- .num_outs = 1,
- .output_level_max = VX2_AKM_LEVEL_MAX,
- .output_level_db_scale = db_scale_akm,
-};
-
-static struct snd_vx_hardware vx222_mic_hw = {
-
- .name = "VX222/Mic",
- .type = VX_TYPE_MIC,
- /* hw specs */
- .num_codecs = 1,
- .num_ins = 1,
- .num_outs = 1,
- .output_level_max = VX2_AKM_LEVEL_MAX,
- .output_level_db_scale = db_scale_akm,
-};
-
-
-/*
- */
-static int snd_vx222_free(struct vx_core *chip)
-{
- struct snd_vx222 *vx = (struct snd_vx222 *)chip;
-
- if (chip->irq >= 0)
- free_irq(chip->irq, (void*)chip);
- if (vx->port[0])
- pci_release_regions(vx->pci);
- pci_disable_device(vx->pci);
- kfree(chip);
- return 0;
-}
-
-static int snd_vx222_dev_free(struct snd_device *device)
-{
- struct vx_core *chip = device->device_data;
- return snd_vx222_free(chip);
-}
-
-
-static int __devinit snd_vx222_create(struct snd_card *card, struct pci_dev *pci,
- struct snd_vx_hardware *hw,
- struct snd_vx222 **rchip)
-{
- struct vx_core *chip;
- struct snd_vx222 *vx;
- int i, err;
- static struct snd_device_ops ops = {
- .dev_free = snd_vx222_dev_free,
- };
- struct snd_vx_ops *vx_ops;
-
- /* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
- return err;
- pci_set_master(pci);
-
- vx_ops = hw->type == VX_TYPE_BOARD ? &vx222_old_ops : &vx222_ops;
- chip = snd_vx_create(card, hw, vx_ops,
- sizeof(struct snd_vx222) - sizeof(struct vx_core));
- if (! chip) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
- vx = (struct snd_vx222 *)chip;
- vx->pci = pci;
-
- if ((err = pci_request_regions(pci, CARD_NAME)) < 0) {
- snd_vx222_free(chip);
- return err;
- }
- for (i = 0; i < 2; i++)
- vx->port[i] = pci_resource_start(pci, i + 1);
-
- if (request_irq(pci->irq, snd_vx_irq_handler, IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_vx222_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_vx222_free(chip);
- return err;
- }
-
- snd_card_set_dev(card, &pci->dev);
-
- *rchip = vx;
- return 0;
-}
-
-
-static int __devinit snd_vx222_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct snd_vx_hardware *hw;
- struct snd_vx222 *vx;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- switch ((int)pci_id->driver_data) {
- case VX_PCI_VX222_OLD:
- hw = &vx222_old_hw;
- break;
- case VX_PCI_VX222_NEW:
- default:
- if (mic[dev])
- hw = &vx222_mic_hw;
- else
- hw = &vx222_v2_hw;
- break;
- }
- if ((err = snd_vx222_create(card, pci, hw, &vx)) < 0) {
- snd_card_free(card);
- return err;
- }
- card->private_data = vx;
- vx->core.ibl.size = ibl[dev];
-
- sprintf(card->longname, "%s at 0x%lx & 0x%lx, irq %i",
- card->shortname, vx->port[0], vx->port[1], vx->core.irq);
- snd_printdd("%s at 0x%lx & 0x%lx, irq %i\n",
- card->shortname, vx->port[0], vx->port[1], vx->core.irq);
-
-#ifdef SND_VX_FW_LOADER
- vx->core.dev = &pci->dev;
-#endif
-
- if ((err = snd_vx_setup_firmware(&vx->core)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
-
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_vx222_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-#ifdef CONFIG_PM
-static int snd_vx222_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_vx222 *vx = card->private_data;
- int err;
-
- err = snd_vx_suspend(&vx->core, state);
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return err;
-}
-
-static int snd_vx222_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_vx222 *vx = card->private_data;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "vx222: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
- return snd_vx_resume(&vx->core);
-}
-#endif
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_vx222_ids,
- .probe = snd_vx222_probe,
- .remove = __devexit_p(snd_vx222_remove),
-#ifdef CONFIG_PM
- .suspend = snd_vx222_suspend,
- .resume = snd_vx222_resume,
-#endif
-};
-
-static int __init alsa_card_vx222_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_vx222_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_vx222_init)
-module_exit(alsa_card_vx222_exit)
diff --git a/ANDROID_3.4.5/sound/pci/vx222/vx222.h b/ANDROID_3.4.5/sound/pci/vx222/vx222.h
deleted file mode 100644
index 2f0d78f6..00000000
--- a/ANDROID_3.4.5/sound/pci/vx222/vx222.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Driver for Digigram VX222 PCI soundcards
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __VX222_H
-#define __VX222_H
-
-#include <sound/vx_core.h>
-
-struct snd_vx222 {
-
- struct vx_core core;
-
- /* h/w config; for PLX and for DSP */
- struct pci_dev *pci;
- unsigned long port[2];
-
- unsigned int regCDSP; /* current CDSP register */
- unsigned int regCFG; /* current CFG register */
- unsigned int regSELMIC; /* current SELMIC reg. (for VX222 Mic) */
-
- int input_level[2]; /* input level for vx222 mic */
- int mic_level; /* mic level for vx222 mic */
-};
-
-/* we use a lookup table with 148 values, see vx_mixer.c */
-#define VX2_AKM_LEVEL_MAX 0x93
-
-extern struct snd_vx_ops vx222_ops;
-extern struct snd_vx_ops vx222_old_ops;
-
-/* Offset of registers with base equal to portDSP. */
-#define VX_RESET_DMA_REGISTER_OFFSET 0x00000008
-
-/* Constants used to access the INTCSR register. */
-#define VX_INTCSR_VALUE 0x00000001
-#define VX_PCI_INTERRUPT_MASK 0x00000040
-
-/* Constants used to access the CDSP register (0x20). */
-#define VX_CDSP_TEST1_MASK 0x00000080
-#define VX_CDSP_TOR1_MASK 0x00000040
-#define VX_CDSP_TOR2_MASK 0x00000020
-#define VX_CDSP_RESERVED0_0_MASK 0x00000010
-#define VX_CDSP_CODEC_RESET_MASK 0x00000008
-#define VX_CDSP_VALID_IRQ_MASK 0x00000004
-#define VX_CDSP_TEST0_MASK 0x00000002
-#define VX_CDSP_DSP_RESET_MASK 0x00000001
-
-#define VX_CDSP_GPIO_OUT_MASK 0x00000060
-#define VX_GPIO_OUT_BIT_OFFSET 5 // transform output to bit 0 and 1
-
-/* Constants used to access the CFG register (0x24). */
-#define VX_CFG_SYNCDSP_MASK 0x00000080
-#define VX_CFG_RESERVED0_0_MASK 0x00000040
-#define VX_CFG_RESERVED1_0_MASK 0x00000020
-#define VX_CFG_RESERVED2_0_MASK 0x00000010
-#define VX_CFG_DATAIN_SEL_MASK 0x00000008 // 0 (ana), 1 (UER)
-#define VX_CFG_RESERVED3_0_MASK 0x00000004
-#define VX_CFG_RESERVED4_0_MASK 0x00000002
-#define VX_CFG_CLOCKIN_SEL_MASK 0x00000001 // 0 (internal), 1 (AES/EBU)
-
-/* Constants used to access the STATUS register (0x30). */
-#define VX_STATUS_DATA_XICOR_MASK 0x00000080
-#define VX_STATUS_VAL_TEST1_MASK 0x00000040
-#define VX_STATUS_VAL_TEST0_MASK 0x00000020
-#define VX_STATUS_RESERVED0_MASK 0x00000010
-#define VX_STATUS_VAL_TOR1_MASK 0x00000008
-#define VX_STATUS_VAL_TOR0_MASK 0x00000004
-#define VX_STATUS_LEVEL_IN_MASK 0x00000002 // 6 dBu (0), 22 dBu (1)
-#define VX_STATUS_MEMIRQ_MASK 0x00000001
-
-#define VX_STATUS_GPIO_IN_MASK 0x0000000C
-#define VX_GPIO_IN_BIT_OFFSET 0 // leave input as bit 2 and 3
-
-/* Constants used to access the MICRO INPUT SELECT register (0x40). */
-#define MICRO_SELECT_INPUT_NORM 0x00
-#define MICRO_SELECT_INPUT_MUTE 0x01
-#define MICRO_SELECT_INPUT_LIMIT 0x02
-#define MICRO_SELECT_INPUT_MASK 0x03
-
-#define MICRO_SELECT_PREAMPLI_G_0 0x00
-#define MICRO_SELECT_PREAMPLI_G_1 0x04
-#define MICRO_SELECT_PREAMPLI_G_2 0x08
-#define MICRO_SELECT_PREAMPLI_G_3 0x0C
-#define MICRO_SELECT_PREAMPLI_MASK 0x0C
-#define MICRO_SELECT_PREAMPLI_OFFSET 2
-
-#define MICRO_SELECT_RAISE_COMPR 0x10
-
-#define MICRO_SELECT_NOISE_T_52DB 0x00
-#define MICRO_SELECT_NOISE_T_42DB 0x20
-#define MICRO_SELECT_NOISE_T_32DB 0x40
-#define MICRO_SELECT_NOISE_T_MASK 0x60
-
-#define MICRO_SELECT_PHANTOM_ALIM 0x80
-
-
-#endif /* __VX222_H */
diff --git a/ANDROID_3.4.5/sound/pci/vx222/vx222_ops.c b/ANDROID_3.4.5/sound/pci/vx222/vx222_ops.c
deleted file mode 100644
index a69e774d..00000000
--- a/ANDROID_3.4.5/sound/pci/vx222/vx222_ops.c
+++ /dev/null
@@ -1,1031 +0,0 @@
-/*
- * Driver for Digigram VX222 V2/Mic soundcards
- *
- * VX222-specific low-level routines
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/mutex.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <asm/io.h>
-#include "vx222.h"
-
-
-static int vx2_reg_offset[VX_REG_MAX] = {
- [VX_ICR] = 0x00,
- [VX_CVR] = 0x04,
- [VX_ISR] = 0x08,
- [VX_IVR] = 0x0c,
- [VX_RXH] = 0x14,
- [VX_RXM] = 0x18,
- [VX_RXL] = 0x1c,
- [VX_DMA] = 0x10,
- [VX_CDSP] = 0x20,
- [VX_CFG] = 0x24,
- [VX_RUER] = 0x28,
- [VX_DATA] = 0x2c,
- [VX_STATUS] = 0x30,
- [VX_LOFREQ] = 0x34,
- [VX_HIFREQ] = 0x38,
- [VX_CSUER] = 0x3c,
- [VX_SELMIC] = 0x40,
- [VX_COMPOT] = 0x44, // Write: POTENTIOMETER ; Read: COMPRESSION LEVEL activate
- [VX_SCOMPR] = 0x48, // Read: COMPRESSION THRESHOLD activate
- [VX_GLIMIT] = 0x4c, // Read: LEVEL LIMITATION activate
- [VX_INTCSR] = 0x4c, // VX_INTCSR_REGISTER_OFFSET
- [VX_CNTRL] = 0x50, // VX_CNTRL_REGISTER_OFFSET
- [VX_GPIOC] = 0x54, // VX_GPIOC (new with PLX9030)
-};
-
-static int vx2_reg_index[VX_REG_MAX] = {
- [VX_ICR] = 1,
- [VX_CVR] = 1,
- [VX_ISR] = 1,
- [VX_IVR] = 1,
- [VX_RXH] = 1,
- [VX_RXM] = 1,
- [VX_RXL] = 1,
- [VX_DMA] = 1,
- [VX_CDSP] = 1,
- [VX_CFG] = 1,
- [VX_RUER] = 1,
- [VX_DATA] = 1,
- [VX_STATUS] = 1,
- [VX_LOFREQ] = 1,
- [VX_HIFREQ] = 1,
- [VX_CSUER] = 1,
- [VX_SELMIC] = 1,
- [VX_COMPOT] = 1,
- [VX_SCOMPR] = 1,
- [VX_GLIMIT] = 1,
- [VX_INTCSR] = 0, /* on the PLX */
- [VX_CNTRL] = 0, /* on the PLX */
- [VX_GPIOC] = 0, /* on the PLX */
-};
-
-static inline unsigned long vx2_reg_addr(struct vx_core *_chip, int reg)
-{
- struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
- return chip->port[vx2_reg_index[reg]] + vx2_reg_offset[reg];
-}
-
-/**
- * snd_vx_inb - read a byte from the register
- * @offset: register enum
- */
-static unsigned char vx2_inb(struct vx_core *chip, int offset)
-{
- return inb(vx2_reg_addr(chip, offset));
-}
-
-/**
- * snd_vx_outb - write a byte on the register
- * @offset: the register offset
- * @val: the value to write
- */
-static void vx2_outb(struct vx_core *chip, int offset, unsigned char val)
-{
- outb(val, vx2_reg_addr(chip, offset));
- /*
- printk(KERN_DEBUG "outb: %x -> %x\n", val, vx2_reg_addr(chip, offset));
- */
-}
-
-/**
- * snd_vx_inl - read a 32bit word from the register
- * @offset: register enum
- */
-static unsigned int vx2_inl(struct vx_core *chip, int offset)
-{
- return inl(vx2_reg_addr(chip, offset));
-}
-
-/**
- * snd_vx_outl - write a 32bit word on the register
- * @offset: the register enum
- * @val: the value to write
- */
-static void vx2_outl(struct vx_core *chip, int offset, unsigned int val)
-{
- /*
- printk(KERN_DEBUG "outl: %x -> %x\n", val, vx2_reg_addr(chip, offset));
- */
- outl(val, vx2_reg_addr(chip, offset));
-}
-
-/*
- * redefine macros to call directly
- */
-#undef vx_inb
-#define vx_inb(chip,reg) vx2_inb((struct vx_core*)(chip), VX_##reg)
-#undef vx_outb
-#define vx_outb(chip,reg,val) vx2_outb((struct vx_core*)(chip), VX_##reg, val)
-#undef vx_inl
-#define vx_inl(chip,reg) vx2_inl((struct vx_core*)(chip), VX_##reg)
-#undef vx_outl
-#define vx_outl(chip,reg,val) vx2_outl((struct vx_core*)(chip), VX_##reg, val)
-
-
-/*
- * vx_reset_dsp - reset the DSP
- */
-
-#define XX_DSP_RESET_WAIT_TIME 2 /* ms */
-
-static void vx2_reset_dsp(struct vx_core *_chip)
-{
- struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
-
- /* set the reset dsp bit to 0 */
- vx_outl(chip, CDSP, chip->regCDSP & ~VX_CDSP_DSP_RESET_MASK);
-
- mdelay(XX_DSP_RESET_WAIT_TIME);
-
- chip->regCDSP |= VX_CDSP_DSP_RESET_MASK;
- /* set the reset dsp bit to 1 */
- vx_outl(chip, CDSP, chip->regCDSP);
-}
-
-
-static int vx2_test_xilinx(struct vx_core *_chip)
-{
- struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
- unsigned int data;
-
- snd_printdd("testing xilinx...\n");
- /* This test uses several write/read sequences on TEST0 and TEST1 bits
- * to figure out whever or not the xilinx was correctly loaded
- */
-
- /* We write 1 on CDSP.TEST0. We should get 0 on STATUS.TEST0. */
- vx_outl(chip, CDSP, chip->regCDSP | VX_CDSP_TEST0_MASK);
- vx_inl(chip, ISR);
- data = vx_inl(chip, STATUS);
- if ((data & VX_STATUS_VAL_TEST0_MASK) == VX_STATUS_VAL_TEST0_MASK) {
- snd_printdd("bad!\n");
- return -ENODEV;
- }
-
- /* We write 0 on CDSP.TEST0. We should get 1 on STATUS.TEST0. */
- vx_outl(chip, CDSP, chip->regCDSP & ~VX_CDSP_TEST0_MASK);
- vx_inl(chip, ISR);
- data = vx_inl(chip, STATUS);
- if (! (data & VX_STATUS_VAL_TEST0_MASK)) {
- snd_printdd("bad! #2\n");
- return -ENODEV;
- }
-
- if (_chip->type == VX_TYPE_BOARD) {
- /* not implemented on VX_2_BOARDS */
- /* We write 1 on CDSP.TEST1. We should get 0 on STATUS.TEST1. */
- vx_outl(chip, CDSP, chip->regCDSP | VX_CDSP_TEST1_MASK);
- vx_inl(chip, ISR);
- data = vx_inl(chip, STATUS);
- if ((data & VX_STATUS_VAL_TEST1_MASK) == VX_STATUS_VAL_TEST1_MASK) {
- snd_printdd("bad! #3\n");
- return -ENODEV;
- }
-
- /* We write 0 on CDSP.TEST1. We should get 1 on STATUS.TEST1. */
- vx_outl(chip, CDSP, chip->regCDSP & ~VX_CDSP_TEST1_MASK);
- vx_inl(chip, ISR);
- data = vx_inl(chip, STATUS);
- if (! (data & VX_STATUS_VAL_TEST1_MASK)) {
- snd_printdd("bad! #4\n");
- return -ENODEV;
- }
- }
- snd_printdd("ok, xilinx fine.\n");
- return 0;
-}
-
-
-/**
- * vx_setup_pseudo_dma - set up the pseudo dma read/write mode.
- * @do_write: 0 = read, 1 = set up for DMA write
- */
-static void vx2_setup_pseudo_dma(struct vx_core *chip, int do_write)
-{
- /* Interrupt mode and HREQ pin enabled for host transmit data transfers
- * (in case of the use of the pseudo-dma facility).
- */
- vx_outl(chip, ICR, do_write ? ICR_TREQ : ICR_RREQ);
-
- /* Reset the pseudo-dma register (in case of the use of the
- * pseudo-dma facility).
- */
- vx_outl(chip, RESET_DMA, 0);
-}
-
-/*
- * vx_release_pseudo_dma - disable the pseudo-DMA mode
- */
-static inline void vx2_release_pseudo_dma(struct vx_core *chip)
-{
- /* HREQ pin disabled. */
- vx_outl(chip, ICR, 0);
-}
-
-
-
-/* pseudo-dma write */
-static void vx2_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime,
- struct vx_pipe *pipe, int count)
-{
- unsigned long port = vx2_reg_addr(chip, VX_DMA);
- int offset = pipe->hw_ptr;
- u32 *addr = (u32 *)(runtime->dma_area + offset);
-
- if (snd_BUG_ON(count % 4))
- return;
-
- vx2_setup_pseudo_dma(chip, 1);
-
- /* Transfer using pseudo-dma.
- */
- if (offset + count > pipe->buffer_bytes) {
- int length = pipe->buffer_bytes - offset;
- count -= length;
- length >>= 2; /* in 32bit words */
- /* Transfer using pseudo-dma. */
- while (length-- > 0) {
- outl(cpu_to_le32(*addr), port);
- addr++;
- }
- addr = (u32 *)runtime->dma_area;
- pipe->hw_ptr = 0;
- }
- pipe->hw_ptr += count;
- count >>= 2; /* in 32bit words */
- /* Transfer using pseudo-dma. */
- while (count-- > 0) {
- outl(cpu_to_le32(*addr), port);
- addr++;
- }
-
- vx2_release_pseudo_dma(chip);
-}
-
-
-/* pseudo dma read */
-static void vx2_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
- struct vx_pipe *pipe, int count)
-{
- int offset = pipe->hw_ptr;
- u32 *addr = (u32 *)(runtime->dma_area + offset);
- unsigned long port = vx2_reg_addr(chip, VX_DMA);
-
- if (snd_BUG_ON(count % 4))
- return;
-
- vx2_setup_pseudo_dma(chip, 0);
- /* Transfer using pseudo-dma.
- */
- if (offset + count > pipe->buffer_bytes) {
- int length = pipe->buffer_bytes - offset;
- count -= length;
- length >>= 2; /* in 32bit words */
- /* Transfer using pseudo-dma. */
- while (length-- > 0)
- *addr++ = le32_to_cpu(inl(port));
- addr = (u32 *)runtime->dma_area;
- pipe->hw_ptr = 0;
- }
- pipe->hw_ptr += count;
- count >>= 2; /* in 32bit words */
- /* Transfer using pseudo-dma. */
- while (count-- > 0)
- *addr++ = le32_to_cpu(inl(port));
-
- vx2_release_pseudo_dma(chip);
-}
-
-#define VX_XILINX_RESET_MASK 0x40000000
-#define VX_USERBIT0_MASK 0x00000004
-#define VX_USERBIT1_MASK 0x00000020
-#define VX_CNTRL_REGISTER_VALUE 0x00172012
-
-/*
- * transfer counts bits to PLX
- */
-static int put_xilinx_data(struct vx_core *chip, unsigned int port, unsigned int counts, unsigned char data)
-{
- unsigned int i;
-
- for (i = 0; i < counts; i++) {
- unsigned int val;
-
- /* set the clock bit to 0. */
- val = VX_CNTRL_REGISTER_VALUE & ~VX_USERBIT0_MASK;
- vx2_outl(chip, port, val);
- vx2_inl(chip, port);
- udelay(1);
-
- if (data & (1 << i))
- val |= VX_USERBIT1_MASK;
- else
- val &= ~VX_USERBIT1_MASK;
- vx2_outl(chip, port, val);
- vx2_inl(chip, port);
-
- /* set the clock bit to 1. */
- val |= VX_USERBIT0_MASK;
- vx2_outl(chip, port, val);
- vx2_inl(chip, port);
- udelay(1);
- }
- return 0;
-}
-
-/*
- * load the xilinx image
- */
-static int vx2_load_xilinx_binary(struct vx_core *chip, const struct firmware *xilinx)
-{
- unsigned int i;
- unsigned int port;
- const unsigned char *image;
-
- /* XILINX reset (wait at least 1 millisecond between reset on and off). */
- vx_outl(chip, CNTRL, VX_CNTRL_REGISTER_VALUE | VX_XILINX_RESET_MASK);
- vx_inl(chip, CNTRL);
- msleep(10);
- vx_outl(chip, CNTRL, VX_CNTRL_REGISTER_VALUE);
- vx_inl(chip, CNTRL);
- msleep(10);
-
- if (chip->type == VX_TYPE_BOARD)
- port = VX_CNTRL;
- else
- port = VX_GPIOC; /* VX222 V2 and VX222_MIC_BOARD with new PLX9030 use this register */
-
- image = xilinx->data;
- for (i = 0; i < xilinx->size; i++, image++) {
- if (put_xilinx_data(chip, port, 8, *image) < 0)
- return -EINVAL;
- /* don't take too much time in this loop... */
- cond_resched();
- }
- put_xilinx_data(chip, port, 4, 0xff); /* end signature */
-
- msleep(200);
-
- /* test after loading (is buggy with VX222) */
- if (chip->type != VX_TYPE_BOARD) {
- /* Test if load successful: test bit 8 of register GPIOC (VX222: use CNTRL) ! */
- i = vx_inl(chip, GPIOC);
- if (i & 0x0100)
- return 0;
- snd_printk(KERN_ERR "vx222: xilinx test failed after load, GPIOC=0x%x\n", i);
- return -EINVAL;
- }
-
- return 0;
-}
-
-
-/*
- * load the boot/dsp images
- */
-static int vx2_load_dsp(struct vx_core *vx, int index, const struct firmware *dsp)
-{
- int err;
-
- switch (index) {
- case 1:
- /* xilinx image */
- if ((err = vx2_load_xilinx_binary(vx, dsp)) < 0)
- return err;
- if ((err = vx2_test_xilinx(vx)) < 0)
- return err;
- return 0;
- case 2:
- /* DSP boot */
- return snd_vx_dsp_boot(vx, dsp);
- case 3:
- /* DSP image */
- return snd_vx_dsp_load(vx, dsp);
- default:
- snd_BUG();
- return -EINVAL;
- }
-}
-
-
-/*
- * vx_test_and_ack - test and acknowledge interrupt
- *
- * called from irq hander, too
- *
- * spinlock held!
- */
-static int vx2_test_and_ack(struct vx_core *chip)
-{
- /* not booted yet? */
- if (! (chip->chip_status & VX_STAT_XILINX_LOADED))
- return -ENXIO;
-
- if (! (vx_inl(chip, STATUS) & VX_STATUS_MEMIRQ_MASK))
- return -EIO;
-
- /* ok, interrupts generated, now ack it */
- /* set ACQUIT bit up and down */
- vx_outl(chip, STATUS, 0);
- /* useless read just to spend some time and maintain
- * the ACQUIT signal up for a while ( a bus cycle )
- */
- vx_inl(chip, STATUS);
- /* ack */
- vx_outl(chip, STATUS, VX_STATUS_MEMIRQ_MASK);
- /* useless read just to spend some time and maintain
- * the ACQUIT signal up for a while ( a bus cycle ) */
- vx_inl(chip, STATUS);
- /* clear */
- vx_outl(chip, STATUS, 0);
-
- return 0;
-}
-
-
-/*
- * vx_validate_irq - enable/disable IRQ
- */
-static void vx2_validate_irq(struct vx_core *_chip, int enable)
-{
- struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
-
- /* Set the interrupt enable bit to 1 in CDSP register */
- if (enable) {
- /* Set the PCI interrupt enable bit to 1.*/
- vx_outl(chip, INTCSR, VX_INTCSR_VALUE|VX_PCI_INTERRUPT_MASK);
- chip->regCDSP |= VX_CDSP_VALID_IRQ_MASK;
- } else {
- /* Set the PCI interrupt enable bit to 0. */
- vx_outl(chip, INTCSR, VX_INTCSR_VALUE&~VX_PCI_INTERRUPT_MASK);
- chip->regCDSP &= ~VX_CDSP_VALID_IRQ_MASK;
- }
- vx_outl(chip, CDSP, chip->regCDSP);
-}
-
-
-/*
- * write an AKM codec data (24bit)
- */
-static void vx2_write_codec_reg(struct vx_core *chip, unsigned int data)
-{
- unsigned int i;
-
- vx_inl(chip, HIFREQ);
-
- /* We have to send 24 bits (3 x 8 bits). Start with most signif. Bit */
- for (i = 0; i < 24; i++, data <<= 1)
- vx_outl(chip, DATA, ((data & 0x800000) ? VX_DATA_CODEC_MASK : 0));
- /* Terminate access to codec registers */
- vx_inl(chip, RUER);
-}
-
-
-#define AKM_CODEC_POWER_CONTROL_CMD 0xA007
-#define AKM_CODEC_RESET_ON_CMD 0xA100
-#define AKM_CODEC_RESET_OFF_CMD 0xA103
-#define AKM_CODEC_CLOCK_FORMAT_CMD 0xA240
-#define AKM_CODEC_MUTE_CMD 0xA38D
-#define AKM_CODEC_UNMUTE_CMD 0xA30D
-#define AKM_CODEC_LEFT_LEVEL_CMD 0xA400
-#define AKM_CODEC_RIGHT_LEVEL_CMD 0xA500
-
-static const u8 vx2_akm_gains_lut[VX2_AKM_LEVEL_MAX+1] = {
- 0x7f, // [000] = +0.000 dB -> AKM(0x7f) = +0.000 dB error(+0.000 dB)
- 0x7d, // [001] = -0.500 dB -> AKM(0x7d) = -0.572 dB error(-0.072 dB)
- 0x7c, // [002] = -1.000 dB -> AKM(0x7c) = -0.873 dB error(+0.127 dB)
- 0x7a, // [003] = -1.500 dB -> AKM(0x7a) = -1.508 dB error(-0.008 dB)
- 0x79, // [004] = -2.000 dB -> AKM(0x79) = -1.844 dB error(+0.156 dB)
- 0x77, // [005] = -2.500 dB -> AKM(0x77) = -2.557 dB error(-0.057 dB)
- 0x76, // [006] = -3.000 dB -> AKM(0x76) = -2.937 dB error(+0.063 dB)
- 0x75, // [007] = -3.500 dB -> AKM(0x75) = -3.334 dB error(+0.166 dB)
- 0x73, // [008] = -4.000 dB -> AKM(0x73) = -4.188 dB error(-0.188 dB)
- 0x72, // [009] = -4.500 dB -> AKM(0x72) = -4.648 dB error(-0.148 dB)
- 0x71, // [010] = -5.000 dB -> AKM(0x71) = -5.134 dB error(-0.134 dB)
- 0x70, // [011] = -5.500 dB -> AKM(0x70) = -5.649 dB error(-0.149 dB)
- 0x6f, // [012] = -6.000 dB -> AKM(0x6f) = -6.056 dB error(-0.056 dB)
- 0x6d, // [013] = -6.500 dB -> AKM(0x6d) = -6.631 dB error(-0.131 dB)
- 0x6c, // [014] = -7.000 dB -> AKM(0x6c) = -6.933 dB error(+0.067 dB)
- 0x6a, // [015] = -7.500 dB -> AKM(0x6a) = -7.571 dB error(-0.071 dB)
- 0x69, // [016] = -8.000 dB -> AKM(0x69) = -7.909 dB error(+0.091 dB)
- 0x67, // [017] = -8.500 dB -> AKM(0x67) = -8.626 dB error(-0.126 dB)
- 0x66, // [018] = -9.000 dB -> AKM(0x66) = -9.008 dB error(-0.008 dB)
- 0x65, // [019] = -9.500 dB -> AKM(0x65) = -9.407 dB error(+0.093 dB)
- 0x64, // [020] = -10.000 dB -> AKM(0x64) = -9.826 dB error(+0.174 dB)
- 0x62, // [021] = -10.500 dB -> AKM(0x62) = -10.730 dB error(-0.230 dB)
- 0x61, // [022] = -11.000 dB -> AKM(0x61) = -11.219 dB error(-0.219 dB)
- 0x60, // [023] = -11.500 dB -> AKM(0x60) = -11.738 dB error(-0.238 dB)
- 0x5f, // [024] = -12.000 dB -> AKM(0x5f) = -12.149 dB error(-0.149 dB)
- 0x5e, // [025] = -12.500 dB -> AKM(0x5e) = -12.434 dB error(+0.066 dB)
- 0x5c, // [026] = -13.000 dB -> AKM(0x5c) = -13.033 dB error(-0.033 dB)
- 0x5b, // [027] = -13.500 dB -> AKM(0x5b) = -13.350 dB error(+0.150 dB)
- 0x59, // [028] = -14.000 dB -> AKM(0x59) = -14.018 dB error(-0.018 dB)
- 0x58, // [029] = -14.500 dB -> AKM(0x58) = -14.373 dB error(+0.127 dB)
- 0x56, // [030] = -15.000 dB -> AKM(0x56) = -15.130 dB error(-0.130 dB)
- 0x55, // [031] = -15.500 dB -> AKM(0x55) = -15.534 dB error(-0.034 dB)
- 0x54, // [032] = -16.000 dB -> AKM(0x54) = -15.958 dB error(+0.042 dB)
- 0x53, // [033] = -16.500 dB -> AKM(0x53) = -16.404 dB error(+0.096 dB)
- 0x52, // [034] = -17.000 dB -> AKM(0x52) = -16.874 dB error(+0.126 dB)
- 0x51, // [035] = -17.500 dB -> AKM(0x51) = -17.371 dB error(+0.129 dB)
- 0x50, // [036] = -18.000 dB -> AKM(0x50) = -17.898 dB error(+0.102 dB)
- 0x4e, // [037] = -18.500 dB -> AKM(0x4e) = -18.605 dB error(-0.105 dB)
- 0x4d, // [038] = -19.000 dB -> AKM(0x4d) = -18.905 dB error(+0.095 dB)
- 0x4b, // [039] = -19.500 dB -> AKM(0x4b) = -19.538 dB error(-0.038 dB)
- 0x4a, // [040] = -20.000 dB -> AKM(0x4a) = -19.872 dB error(+0.128 dB)
- 0x48, // [041] = -20.500 dB -> AKM(0x48) = -20.583 dB error(-0.083 dB)
- 0x47, // [042] = -21.000 dB -> AKM(0x47) = -20.961 dB error(+0.039 dB)
- 0x46, // [043] = -21.500 dB -> AKM(0x46) = -21.356 dB error(+0.144 dB)
- 0x44, // [044] = -22.000 dB -> AKM(0x44) = -22.206 dB error(-0.206 dB)
- 0x43, // [045] = -22.500 dB -> AKM(0x43) = -22.664 dB error(-0.164 dB)
- 0x42, // [046] = -23.000 dB -> AKM(0x42) = -23.147 dB error(-0.147 dB)
- 0x41, // [047] = -23.500 dB -> AKM(0x41) = -23.659 dB error(-0.159 dB)
- 0x40, // [048] = -24.000 dB -> AKM(0x40) = -24.203 dB error(-0.203 dB)
- 0x3f, // [049] = -24.500 dB -> AKM(0x3f) = -24.635 dB error(-0.135 dB)
- 0x3e, // [050] = -25.000 dB -> AKM(0x3e) = -24.935 dB error(+0.065 dB)
- 0x3c, // [051] = -25.500 dB -> AKM(0x3c) = -25.569 dB error(-0.069 dB)
- 0x3b, // [052] = -26.000 dB -> AKM(0x3b) = -25.904 dB error(+0.096 dB)
- 0x39, // [053] = -26.500 dB -> AKM(0x39) = -26.615 dB error(-0.115 dB)
- 0x38, // [054] = -27.000 dB -> AKM(0x38) = -26.994 dB error(+0.006 dB)
- 0x37, // [055] = -27.500 dB -> AKM(0x37) = -27.390 dB error(+0.110 dB)
- 0x36, // [056] = -28.000 dB -> AKM(0x36) = -27.804 dB error(+0.196 dB)
- 0x34, // [057] = -28.500 dB -> AKM(0x34) = -28.699 dB error(-0.199 dB)
- 0x33, // [058] = -29.000 dB -> AKM(0x33) = -29.183 dB error(-0.183 dB)
- 0x32, // [059] = -29.500 dB -> AKM(0x32) = -29.696 dB error(-0.196 dB)
- 0x31, // [060] = -30.000 dB -> AKM(0x31) = -30.241 dB error(-0.241 dB)
- 0x31, // [061] = -30.500 dB -> AKM(0x31) = -30.241 dB error(+0.259 dB)
- 0x30, // [062] = -31.000 dB -> AKM(0x30) = -30.823 dB error(+0.177 dB)
- 0x2e, // [063] = -31.500 dB -> AKM(0x2e) = -31.610 dB error(-0.110 dB)
- 0x2d, // [064] = -32.000 dB -> AKM(0x2d) = -31.945 dB error(+0.055 dB)
- 0x2b, // [065] = -32.500 dB -> AKM(0x2b) = -32.659 dB error(-0.159 dB)
- 0x2a, // [066] = -33.000 dB -> AKM(0x2a) = -33.038 dB error(-0.038 dB)
- 0x29, // [067] = -33.500 dB -> AKM(0x29) = -33.435 dB error(+0.065 dB)
- 0x28, // [068] = -34.000 dB -> AKM(0x28) = -33.852 dB error(+0.148 dB)
- 0x27, // [069] = -34.500 dB -> AKM(0x27) = -34.289 dB error(+0.211 dB)
- 0x25, // [070] = -35.000 dB -> AKM(0x25) = -35.235 dB error(-0.235 dB)
- 0x24, // [071] = -35.500 dB -> AKM(0x24) = -35.750 dB error(-0.250 dB)
- 0x24, // [072] = -36.000 dB -> AKM(0x24) = -35.750 dB error(+0.250 dB)
- 0x23, // [073] = -36.500 dB -> AKM(0x23) = -36.297 dB error(+0.203 dB)
- 0x22, // [074] = -37.000 dB -> AKM(0x22) = -36.881 dB error(+0.119 dB)
- 0x21, // [075] = -37.500 dB -> AKM(0x21) = -37.508 dB error(-0.008 dB)
- 0x20, // [076] = -38.000 dB -> AKM(0x20) = -38.183 dB error(-0.183 dB)
- 0x1f, // [077] = -38.500 dB -> AKM(0x1f) = -38.726 dB error(-0.226 dB)
- 0x1e, // [078] = -39.000 dB -> AKM(0x1e) = -39.108 dB error(-0.108 dB)
- 0x1d, // [079] = -39.500 dB -> AKM(0x1d) = -39.507 dB error(-0.007 dB)
- 0x1c, // [080] = -40.000 dB -> AKM(0x1c) = -39.926 dB error(+0.074 dB)
- 0x1b, // [081] = -40.500 dB -> AKM(0x1b) = -40.366 dB error(+0.134 dB)
- 0x1a, // [082] = -41.000 dB -> AKM(0x1a) = -40.829 dB error(+0.171 dB)
- 0x19, // [083] = -41.500 dB -> AKM(0x19) = -41.318 dB error(+0.182 dB)
- 0x18, // [084] = -42.000 dB -> AKM(0x18) = -41.837 dB error(+0.163 dB)
- 0x17, // [085] = -42.500 dB -> AKM(0x17) = -42.389 dB error(+0.111 dB)
- 0x16, // [086] = -43.000 dB -> AKM(0x16) = -42.978 dB error(+0.022 dB)
- 0x15, // [087] = -43.500 dB -> AKM(0x15) = -43.610 dB error(-0.110 dB)
- 0x14, // [088] = -44.000 dB -> AKM(0x14) = -44.291 dB error(-0.291 dB)
- 0x14, // [089] = -44.500 dB -> AKM(0x14) = -44.291 dB error(+0.209 dB)
- 0x13, // [090] = -45.000 dB -> AKM(0x13) = -45.031 dB error(-0.031 dB)
- 0x12, // [091] = -45.500 dB -> AKM(0x12) = -45.840 dB error(-0.340 dB)
- 0x12, // [092] = -46.000 dB -> AKM(0x12) = -45.840 dB error(+0.160 dB)
- 0x11, // [093] = -46.500 dB -> AKM(0x11) = -46.731 dB error(-0.231 dB)
- 0x11, // [094] = -47.000 dB -> AKM(0x11) = -46.731 dB error(+0.269 dB)
- 0x10, // [095] = -47.500 dB -> AKM(0x10) = -47.725 dB error(-0.225 dB)
- 0x10, // [096] = -48.000 dB -> AKM(0x10) = -47.725 dB error(+0.275 dB)
- 0x0f, // [097] = -48.500 dB -> AKM(0x0f) = -48.553 dB error(-0.053 dB)
- 0x0e, // [098] = -49.000 dB -> AKM(0x0e) = -49.152 dB error(-0.152 dB)
- 0x0d, // [099] = -49.500 dB -> AKM(0x0d) = -49.796 dB error(-0.296 dB)
- 0x0d, // [100] = -50.000 dB -> AKM(0x0d) = -49.796 dB error(+0.204 dB)
- 0x0c, // [101] = -50.500 dB -> AKM(0x0c) = -50.491 dB error(+0.009 dB)
- 0x0b, // [102] = -51.000 dB -> AKM(0x0b) = -51.247 dB error(-0.247 dB)
- 0x0b, // [103] = -51.500 dB -> AKM(0x0b) = -51.247 dB error(+0.253 dB)
- 0x0a, // [104] = -52.000 dB -> AKM(0x0a) = -52.075 dB error(-0.075 dB)
- 0x0a, // [105] = -52.500 dB -> AKM(0x0a) = -52.075 dB error(+0.425 dB)
- 0x09, // [106] = -53.000 dB -> AKM(0x09) = -52.990 dB error(+0.010 dB)
- 0x09, // [107] = -53.500 dB -> AKM(0x09) = -52.990 dB error(+0.510 dB)
- 0x08, // [108] = -54.000 dB -> AKM(0x08) = -54.013 dB error(-0.013 dB)
- 0x08, // [109] = -54.500 dB -> AKM(0x08) = -54.013 dB error(+0.487 dB)
- 0x07, // [110] = -55.000 dB -> AKM(0x07) = -55.173 dB error(-0.173 dB)
- 0x07, // [111] = -55.500 dB -> AKM(0x07) = -55.173 dB error(+0.327 dB)
- 0x06, // [112] = -56.000 dB -> AKM(0x06) = -56.512 dB error(-0.512 dB)
- 0x06, // [113] = -56.500 dB -> AKM(0x06) = -56.512 dB error(-0.012 dB)
- 0x06, // [114] = -57.000 dB -> AKM(0x06) = -56.512 dB error(+0.488 dB)
- 0x05, // [115] = -57.500 dB -> AKM(0x05) = -58.095 dB error(-0.595 dB)
- 0x05, // [116] = -58.000 dB -> AKM(0x05) = -58.095 dB error(-0.095 dB)
- 0x05, // [117] = -58.500 dB -> AKM(0x05) = -58.095 dB error(+0.405 dB)
- 0x05, // [118] = -59.000 dB -> AKM(0x05) = -58.095 dB error(+0.905 dB)
- 0x04, // [119] = -59.500 dB -> AKM(0x04) = -60.034 dB error(-0.534 dB)
- 0x04, // [120] = -60.000 dB -> AKM(0x04) = -60.034 dB error(-0.034 dB)
- 0x04, // [121] = -60.500 dB -> AKM(0x04) = -60.034 dB error(+0.466 dB)
- 0x04, // [122] = -61.000 dB -> AKM(0x04) = -60.034 dB error(+0.966 dB)
- 0x03, // [123] = -61.500 dB -> AKM(0x03) = -62.532 dB error(-1.032 dB)
- 0x03, // [124] = -62.000 dB -> AKM(0x03) = -62.532 dB error(-0.532 dB)
- 0x03, // [125] = -62.500 dB -> AKM(0x03) = -62.532 dB error(-0.032 dB)
- 0x03, // [126] = -63.000 dB -> AKM(0x03) = -62.532 dB error(+0.468 dB)
- 0x03, // [127] = -63.500 dB -> AKM(0x03) = -62.532 dB error(+0.968 dB)
- 0x03, // [128] = -64.000 dB -> AKM(0x03) = -62.532 dB error(+1.468 dB)
- 0x02, // [129] = -64.500 dB -> AKM(0x02) = -66.054 dB error(-1.554 dB)
- 0x02, // [130] = -65.000 dB -> AKM(0x02) = -66.054 dB error(-1.054 dB)
- 0x02, // [131] = -65.500 dB -> AKM(0x02) = -66.054 dB error(-0.554 dB)
- 0x02, // [132] = -66.000 dB -> AKM(0x02) = -66.054 dB error(-0.054 dB)
- 0x02, // [133] = -66.500 dB -> AKM(0x02) = -66.054 dB error(+0.446 dB)
- 0x02, // [134] = -67.000 dB -> AKM(0x02) = -66.054 dB error(+0.946 dB)
- 0x02, // [135] = -67.500 dB -> AKM(0x02) = -66.054 dB error(+1.446 dB)
- 0x02, // [136] = -68.000 dB -> AKM(0x02) = -66.054 dB error(+1.946 dB)
- 0x02, // [137] = -68.500 dB -> AKM(0x02) = -66.054 dB error(+2.446 dB)
- 0x02, // [138] = -69.000 dB -> AKM(0x02) = -66.054 dB error(+2.946 dB)
- 0x01, // [139] = -69.500 dB -> AKM(0x01) = -72.075 dB error(-2.575 dB)
- 0x01, // [140] = -70.000 dB -> AKM(0x01) = -72.075 dB error(-2.075 dB)
- 0x01, // [141] = -70.500 dB -> AKM(0x01) = -72.075 dB error(-1.575 dB)
- 0x01, // [142] = -71.000 dB -> AKM(0x01) = -72.075 dB error(-1.075 dB)
- 0x01, // [143] = -71.500 dB -> AKM(0x01) = -72.075 dB error(-0.575 dB)
- 0x01, // [144] = -72.000 dB -> AKM(0x01) = -72.075 dB error(-0.075 dB)
- 0x01, // [145] = -72.500 dB -> AKM(0x01) = -72.075 dB error(+0.425 dB)
- 0x01, // [146] = -73.000 dB -> AKM(0x01) = -72.075 dB error(+0.925 dB)
- 0x00}; // [147] = -73.500 dB -> AKM(0x00) = mute error(+infini)
-
-/*
- * pseudo-codec write entry
- */
-static void vx2_write_akm(struct vx_core *chip, int reg, unsigned int data)
-{
- unsigned int val;
-
- if (reg == XX_CODEC_DAC_CONTROL_REGISTER) {
- vx2_write_codec_reg(chip, data ? AKM_CODEC_MUTE_CMD : AKM_CODEC_UNMUTE_CMD);
- return;
- }
-
- /* `data' is a value between 0x0 and VX2_AKM_LEVEL_MAX = 0x093, in the case of the AKM codecs, we need
- a look up table, as there is no linear matching between the driver codec values
- and the real dBu value
- */
- if (snd_BUG_ON(data >= sizeof(vx2_akm_gains_lut)))
- return;
-
- switch (reg) {
- case XX_CODEC_LEVEL_LEFT_REGISTER:
- val = AKM_CODEC_LEFT_LEVEL_CMD;
- break;
- case XX_CODEC_LEVEL_RIGHT_REGISTER:
- val = AKM_CODEC_RIGHT_LEVEL_CMD;
- break;
- default:
- snd_BUG();
- return;
- }
- val |= vx2_akm_gains_lut[data];
-
- vx2_write_codec_reg(chip, val);
-}
-
-
-/*
- * write codec bit for old VX222 board
- */
-static void vx2_old_write_codec_bit(struct vx_core *chip, int codec, unsigned int data)
-{
- int i;
-
- /* activate access to codec registers */
- vx_inl(chip, HIFREQ);
-
- for (i = 0; i < 24; i++, data <<= 1)
- vx_outl(chip, DATA, ((data & 0x800000) ? VX_DATA_CODEC_MASK : 0));
-
- /* Terminate access to codec registers */
- vx_inl(chip, RUER);
-}
-
-
-/*
- * reset codec bit
- */
-static void vx2_reset_codec(struct vx_core *_chip)
-{
- struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
-
- /* Set the reset CODEC bit to 0. */
- vx_outl(chip, CDSP, chip->regCDSP &~ VX_CDSP_CODEC_RESET_MASK);
- vx_inl(chip, CDSP);
- msleep(10);
- /* Set the reset CODEC bit to 1. */
- chip->regCDSP |= VX_CDSP_CODEC_RESET_MASK;
- vx_outl(chip, CDSP, chip->regCDSP);
- vx_inl(chip, CDSP);
- if (_chip->type == VX_TYPE_BOARD) {
- msleep(1);
- return;
- }
-
- msleep(5); /* additionnel wait time for AKM's */
-
- vx2_write_codec_reg(_chip, AKM_CODEC_POWER_CONTROL_CMD); /* DAC power up, ADC power up, Vref power down */
-
- vx2_write_codec_reg(_chip, AKM_CODEC_CLOCK_FORMAT_CMD); /* default */
- vx2_write_codec_reg(_chip, AKM_CODEC_MUTE_CMD); /* Mute = ON ,Deemphasis = OFF */
- vx2_write_codec_reg(_chip, AKM_CODEC_RESET_OFF_CMD); /* DAC and ADC normal operation */
-
- if (_chip->type == VX_TYPE_MIC) {
- /* set up the micro input selector */
- chip->regSELMIC = MICRO_SELECT_INPUT_NORM |
- MICRO_SELECT_PREAMPLI_G_0 |
- MICRO_SELECT_NOISE_T_52DB;
-
- /* reset phantom power supply */
- chip->regSELMIC &= ~MICRO_SELECT_PHANTOM_ALIM;
-
- vx_outl(_chip, SELMIC, chip->regSELMIC);
- }
-}
-
-
-/*
- * change the audio source
- */
-static void vx2_change_audio_source(struct vx_core *_chip, int src)
-{
- struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
-
- switch (src) {
- case VX_AUDIO_SRC_DIGITAL:
- chip->regCFG |= VX_CFG_DATAIN_SEL_MASK;
- break;
- default:
- chip->regCFG &= ~VX_CFG_DATAIN_SEL_MASK;
- break;
- }
- vx_outl(chip, CFG, chip->regCFG);
-}
-
-
-/*
- * set the clock source
- */
-static void vx2_set_clock_source(struct vx_core *_chip, int source)
-{
- struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
-
- if (source == INTERNAL_QUARTZ)
- chip->regCFG &= ~VX_CFG_CLOCKIN_SEL_MASK;
- else
- chip->regCFG |= VX_CFG_CLOCKIN_SEL_MASK;
- vx_outl(chip, CFG, chip->regCFG);
-}
-
-/*
- * reset the board
- */
-static void vx2_reset_board(struct vx_core *_chip, int cold_reset)
-{
- struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
-
- /* initialize the register values */
- chip->regCDSP = VX_CDSP_CODEC_RESET_MASK | VX_CDSP_DSP_RESET_MASK ;
- chip->regCFG = 0;
-}
-
-
-
-/*
- * input level controls for VX222 Mic
- */
-
-/* Micro level is specified to be adjustable from -96dB to 63 dB (board coded 0x00 ... 318),
- * 318 = 210 + 36 + 36 + 36 (210 = +9dB variable) (3 * 36 = 3 steps of 18dB pre ampli)
- * as we will mute if less than -110dB, so let's simply use line input coded levels and add constant offset !
- */
-#define V2_MICRO_LEVEL_RANGE (318 - 255)
-
-static void vx2_set_input_level(struct snd_vx222 *chip)
-{
- int i, miclevel, preamp;
- unsigned int data;
-
- miclevel = chip->mic_level;
- miclevel += V2_MICRO_LEVEL_RANGE; /* add 318 - 0xff */
- preamp = 0;
- while (miclevel > 210) { /* limitation to +9dB of 3310 real gain */
- preamp++; /* raise pre ampli + 18dB */
- miclevel -= (18 * 2); /* lower level 18 dB (*2 because of 0.5 dB steps !) */
- }
- if (snd_BUG_ON(preamp >= 4))
- return;
-
- /* set pre-amp level */
- chip->regSELMIC &= ~MICRO_SELECT_PREAMPLI_MASK;
- chip->regSELMIC |= (preamp << MICRO_SELECT_PREAMPLI_OFFSET) & MICRO_SELECT_PREAMPLI_MASK;
- vx_outl(chip, SELMIC, chip->regSELMIC);
-
- data = (unsigned int)miclevel << 16 |
- (unsigned int)chip->input_level[1] << 8 |
- (unsigned int)chip->input_level[0];
- vx_inl(chip, DATA); /* Activate input level programming */
-
- /* We have to send 32 bits (4 x 8 bits) */
- for (i = 0; i < 32; i++, data <<= 1)
- vx_outl(chip, DATA, ((data & 0x80000000) ? VX_DATA_CODEC_MASK : 0));
-
- vx_inl(chip, RUER); /* Terminate input level programming */
-}
-
-
-#define MIC_LEVEL_MAX 0xff
-
-static const DECLARE_TLV_DB_SCALE(db_scale_mic, -6450, 50, 0);
-
-/*
- * controls API for input levels
- */
-
-/* input levels */
-static int vx_input_level_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = MIC_LEVEL_MAX;
- return 0;
-}
-
-static int vx_input_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
- struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
- mutex_lock(&_chip->mixer_mutex);
- ucontrol->value.integer.value[0] = chip->input_level[0];
- ucontrol->value.integer.value[1] = chip->input_level[1];
- mutex_unlock(&_chip->mixer_mutex);
- return 0;
-}
-
-static int vx_input_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
- struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
- if (ucontrol->value.integer.value[0] < 0 ||
- ucontrol->value.integer.value[0] > MIC_LEVEL_MAX)
- return -EINVAL;
- if (ucontrol->value.integer.value[1] < 0 ||
- ucontrol->value.integer.value[1] > MIC_LEVEL_MAX)
- return -EINVAL;
- mutex_lock(&_chip->mixer_mutex);
- if (chip->input_level[0] != ucontrol->value.integer.value[0] ||
- chip->input_level[1] != ucontrol->value.integer.value[1]) {
- chip->input_level[0] = ucontrol->value.integer.value[0];
- chip->input_level[1] = ucontrol->value.integer.value[1];
- vx2_set_input_level(chip);
- mutex_unlock(&_chip->mixer_mutex);
- return 1;
- }
- mutex_unlock(&_chip->mixer_mutex);
- return 0;
-}
-
-/* mic level */
-static int vx_mic_level_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = MIC_LEVEL_MAX;
- return 0;
-}
-
-static int vx_mic_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
- struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
- ucontrol->value.integer.value[0] = chip->mic_level;
- return 0;
-}
-
-static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
- struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
- if (ucontrol->value.integer.value[0] < 0 ||
- ucontrol->value.integer.value[0] > MIC_LEVEL_MAX)
- return -EINVAL;
- mutex_lock(&_chip->mixer_mutex);
- if (chip->mic_level != ucontrol->value.integer.value[0]) {
- chip->mic_level = ucontrol->value.integer.value[0];
- vx2_set_input_level(chip);
- mutex_unlock(&_chip->mixer_mutex);
- return 1;
- }
- mutex_unlock(&_chip->mixer_mutex);
- return 0;
-}
-
-static struct snd_kcontrol_new vx_control_input_level = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Capture Volume",
- .info = vx_input_level_info,
- .get = vx_input_level_get,
- .put = vx_input_level_put,
- .tlv = { .p = db_scale_mic },
-};
-
-static struct snd_kcontrol_new vx_control_mic_level = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Mic Capture Volume",
- .info = vx_mic_level_info,
- .get = vx_mic_level_get,
- .put = vx_mic_level_put,
- .tlv = { .p = db_scale_mic },
-};
-
-/*
- * FIXME: compressor/limiter implementation is missing yet...
- */
-
-static int vx2_add_mic_controls(struct vx_core *_chip)
-{
- struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
- int err;
-
- if (_chip->type != VX_TYPE_MIC)
- return 0;
-
- /* mute input levels */
- chip->input_level[0] = chip->input_level[1] = 0;
- chip->mic_level = 0;
- vx2_set_input_level(chip);
-
- /* controls */
- if ((err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_input_level, chip))) < 0)
- return err;
- if ((err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_mic_level, chip))) < 0)
- return err;
-
- return 0;
-}
-
-
-/*
- * callbacks
- */
-struct snd_vx_ops vx222_ops = {
- .in8 = vx2_inb,
- .in32 = vx2_inl,
- .out8 = vx2_outb,
- .out32 = vx2_outl,
- .test_and_ack = vx2_test_and_ack,
- .validate_irq = vx2_validate_irq,
- .akm_write = vx2_write_akm,
- .reset_codec = vx2_reset_codec,
- .change_audio_source = vx2_change_audio_source,
- .set_clock_source = vx2_set_clock_source,
- .load_dsp = vx2_load_dsp,
- .reset_dsp = vx2_reset_dsp,
- .reset_board = vx2_reset_board,
- .dma_write = vx2_dma_write,
- .dma_read = vx2_dma_read,
- .add_controls = vx2_add_mic_controls,
-};
-
-/* for old VX222 board */
-struct snd_vx_ops vx222_old_ops = {
- .in8 = vx2_inb,
- .in32 = vx2_inl,
- .out8 = vx2_outb,
- .out32 = vx2_outl,
- .test_and_ack = vx2_test_and_ack,
- .validate_irq = vx2_validate_irq,
- .write_codec = vx2_old_write_codec_bit,
- .reset_codec = vx2_reset_codec,
- .change_audio_source = vx2_change_audio_source,
- .set_clock_source = vx2_set_clock_source,
- .load_dsp = vx2_load_dsp,
- .reset_dsp = vx2_reset_dsp,
- .reset_board = vx2_reset_board,
- .dma_write = vx2_dma_write,
- .dma_read = vx2_dma_read,
-};
-
diff --git a/ANDROID_3.4.5/sound/pci/ymfpci/Makefile b/ANDROID_3.4.5/sound/pci/ymfpci/Makefile
deleted file mode 100644
index bd3d514e..00000000
--- a/ANDROID_3.4.5/sound/pci/ymfpci/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-ymfpci-objs := ymfpci.o ymfpci_main.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_YMFPCI) += snd-ymfpci.o
diff --git a/ANDROID_3.4.5/sound/pci/ymfpci/ymfpci.c b/ANDROID_3.4.5/sound/pci/ymfpci/ymfpci.c
deleted file mode 100644
index 94ab728f..00000000
--- a/ANDROID_3.4.5/sound/pci/ymfpci/ymfpci.c
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * The driver for the Yamaha's DS1/DS1E cards
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/time.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/ymfpci.h>
-#include <sound/mpu401.h>
-#include <sound/opl3.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Yamaha DS-1 PCI");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Yamaha,YMF724},"
- "{Yamaha,YMF724F},"
- "{Yamaha,YMF740},"
- "{Yamaha,YMF740C},"
- "{Yamaha,YMF744},"
- "{Yamaha,YMF754}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static long fm_port[SNDRV_CARDS];
-static long mpu_port[SNDRV_CARDS];
-#ifdef SUPPORT_JOYSTICK
-static long joystick_port[SNDRV_CARDS];
-#endif
-static bool rear_switch[SNDRV_CARDS];
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for the Yamaha DS-1 PCI soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for the Yamaha DS-1 PCI soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Yamaha DS-1 soundcard.");
-module_param_array(mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 Port.");
-module_param_array(fm_port, long, NULL, 0444);
-MODULE_PARM_DESC(fm_port, "FM OPL-3 Port.");
-#ifdef SUPPORT_JOYSTICK
-module_param_array(joystick_port, long, NULL, 0444);
-MODULE_PARM_DESC(joystick_port, "Joystick port address");
-#endif
-module_param_array(rear_switch, bool, NULL, 0444);
-MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch");
-
-static DEFINE_PCI_DEVICE_TABLE(snd_ymfpci_ids) = {
- { PCI_VDEVICE(YAMAHA, 0x0004), 0, }, /* YMF724 */
- { PCI_VDEVICE(YAMAHA, 0x000d), 0, }, /* YMF724F */
- { PCI_VDEVICE(YAMAHA, 0x000a), 0, }, /* YMF740 */
- { PCI_VDEVICE(YAMAHA, 0x000c), 0, }, /* YMF740C */
- { PCI_VDEVICE(YAMAHA, 0x0010), 0, }, /* YMF744 */
- { PCI_VDEVICE(YAMAHA, 0x0012), 0, }, /* YMF754 */
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_ymfpci_ids);
-
-#ifdef SUPPORT_JOYSTICK
-static int __devinit snd_ymfpci_create_gameport(struct snd_ymfpci *chip, int dev,
- int legacy_ctrl, int legacy_ctrl2)
-{
- struct gameport *gp;
- struct resource *r = NULL;
- int io_port = joystick_port[dev];
-
- if (!io_port)
- return -ENODEV;
-
- if (chip->pci->device >= 0x0010) { /* YMF 744/754 */
-
- if (io_port == 1) {
- /* auto-detect */
- if (!(io_port = pci_resource_start(chip->pci, 2)))
- return -ENODEV;
- }
- } else {
- if (io_port == 1) {
- /* auto-detect */
- for (io_port = 0x201; io_port <= 0x205; io_port++) {
- if (io_port == 0x203)
- continue;
- if ((r = request_region(io_port, 1, "YMFPCI gameport")) != NULL)
- break;
- }
- if (!r) {
- printk(KERN_ERR "ymfpci: no gameport ports available\n");
- return -EBUSY;
- }
- }
- switch (io_port) {
- case 0x201: legacy_ctrl2 |= 0 << 6; break;
- case 0x202: legacy_ctrl2 |= 1 << 6; break;
- case 0x204: legacy_ctrl2 |= 2 << 6; break;
- case 0x205: legacy_ctrl2 |= 3 << 6; break;
- default:
- printk(KERN_ERR "ymfpci: invalid joystick port %#x", io_port);
- return -EINVAL;
- }
- }
-
- if (!r && !(r = request_region(io_port, 1, "YMFPCI gameport"))) {
- printk(KERN_ERR "ymfpci: joystick port %#x is in use.\n", io_port);
- return -EBUSY;
- }
-
- chip->gameport = gp = gameport_allocate_port();
- if (!gp) {
- printk(KERN_ERR "ymfpci: cannot allocate memory for gameport\n");
- release_and_free_resource(r);
- return -ENOMEM;
- }
-
-
- gameport_set_name(gp, "Yamaha YMF Gameport");
- gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
- gameport_set_dev_parent(gp, &chip->pci->dev);
- gp->io = io_port;
- gameport_set_port_data(gp, r);
-
- if (chip->pci->device >= 0x0010) /* YMF 744/754 */
- pci_write_config_word(chip->pci, PCIR_DSXG_JOYBASE, io_port);
-
- pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY, legacy_ctrl | YMFPCI_LEGACY_JPEN);
- pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY, legacy_ctrl2);
-
- gameport_register_port(chip->gameport);
-
- return 0;
-}
-
-void snd_ymfpci_free_gameport(struct snd_ymfpci *chip)
-{
- if (chip->gameport) {
- struct resource *r = gameport_get_port_data(chip->gameport);
-
- gameport_unregister_port(chip->gameport);
- chip->gameport = NULL;
-
- release_and_free_resource(r);
- }
-}
-#else
-static inline int snd_ymfpci_create_gameport(struct snd_ymfpci *chip, int dev, int l, int l2) { return -ENOSYS; }
-void snd_ymfpci_free_gameport(struct snd_ymfpci *chip) { }
-#endif /* SUPPORT_JOYSTICK */
-
-static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
-{
- static int dev;
- struct snd_card *card;
- struct resource *fm_res = NULL;
- struct resource *mpu_res = NULL;
- struct snd_ymfpci *chip;
- struct snd_opl3 *opl3;
- const char *str, *model;
- int err;
- u16 legacy_ctrl, legacy_ctrl2, old_legacy_ctrl;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- switch (pci_id->device) {
- case 0x0004: str = "YMF724"; model = "DS-1"; break;
- case 0x000d: str = "YMF724F"; model = "DS-1"; break;
- case 0x000a: str = "YMF740"; model = "DS-1L"; break;
- case 0x000c: str = "YMF740C"; model = "DS-1L"; break;
- case 0x0010: str = "YMF744"; model = "DS-1S"; break;
- case 0x0012: str = "YMF754"; model = "DS-1E"; break;
- default: model = str = "???"; break;
- }
-
- legacy_ctrl = 0;
- legacy_ctrl2 = 0x0800; /* SBEN = 0, SMOD = 01, LAD = 0 */
-
- if (pci_id->device >= 0x0010) { /* YMF 744/754 */
- if (fm_port[dev] == 1) {
- /* auto-detect */
- fm_port[dev] = pci_resource_start(pci, 1);
- }
- if (fm_port[dev] > 0 &&
- (fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3")) != NULL) {
- legacy_ctrl |= YMFPCI_LEGACY_FMEN;
- pci_write_config_word(pci, PCIR_DSXG_FMBASE, fm_port[dev]);
- }
- if (mpu_port[dev] == 1) {
- /* auto-detect */
- mpu_port[dev] = pci_resource_start(pci, 1) + 0x20;
- }
- if (mpu_port[dev] > 0 &&
- (mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401")) != NULL) {
- legacy_ctrl |= YMFPCI_LEGACY_MEN;
- pci_write_config_word(pci, PCIR_DSXG_MPU401BASE, mpu_port[dev]);
- }
- } else {
- switch (fm_port[dev]) {
- case 0x388: legacy_ctrl2 |= 0; break;
- case 0x398: legacy_ctrl2 |= 1; break;
- case 0x3a0: legacy_ctrl2 |= 2; break;
- case 0x3a8: legacy_ctrl2 |= 3; break;
- default: fm_port[dev] = 0; break;
- }
- if (fm_port[dev] > 0 &&
- (fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3")) != NULL) {
- legacy_ctrl |= YMFPCI_LEGACY_FMEN;
- } else {
- legacy_ctrl2 &= ~YMFPCI_LEGACY2_FMIO;
- fm_port[dev] = 0;
- }
- switch (mpu_port[dev]) {
- case 0x330: legacy_ctrl2 |= 0 << 4; break;
- case 0x300: legacy_ctrl2 |= 1 << 4; break;
- case 0x332: legacy_ctrl2 |= 2 << 4; break;
- case 0x334: legacy_ctrl2 |= 3 << 4; break;
- default: mpu_port[dev] = 0; break;
- }
- if (mpu_port[dev] > 0 &&
- (mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401")) != NULL) {
- legacy_ctrl |= YMFPCI_LEGACY_MEN;
- } else {
- legacy_ctrl2 &= ~YMFPCI_LEGACY2_MPUIO;
- mpu_port[dev] = 0;
- }
- }
- if (mpu_res) {
- legacy_ctrl |= YMFPCI_LEGACY_MIEN;
- legacy_ctrl2 |= YMFPCI_LEGACY2_IMOD;
- }
- pci_read_config_word(pci, PCIR_DSXG_LEGACY, &old_legacy_ctrl);
- pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
- pci_write_config_word(pci, PCIR_DSXG_ELEGACY, legacy_ctrl2);
- if ((err = snd_ymfpci_create(card, pci,
- old_legacy_ctrl,
- &chip)) < 0) {
- snd_card_free(card);
- release_and_free_resource(mpu_res);
- release_and_free_resource(fm_res);
- return err;
- }
- chip->fm_res = fm_res;
- chip->mpu_res = mpu_res;
- card->private_data = chip;
-
- strcpy(card->driver, str);
- sprintf(card->shortname, "Yamaha %s (%s)", model, str);
- sprintf(card->longname, "%s at 0x%lx, irq %i",
- card->shortname,
- chip->reg_area_phys,
- chip->irq);
- if ((err = snd_ymfpci_pcm(chip, 0, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- if ((err = snd_ymfpci_pcm_spdif(chip, 1, NULL)) < 0) {
- snd_card_free(card);
- return err;
- }
- err = snd_ymfpci_mixer(chip, rear_switch[dev]);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- if (chip->ac97->ext_id & AC97_EI_SDAC) {
- err = snd_ymfpci_pcm_4ch(chip, 2, NULL);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- err = snd_ymfpci_pcm2(chip, 3, NULL);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- }
- if ((err = snd_ymfpci_timer(chip, 0)) < 0) {
- snd_card_free(card);
- return err;
- }
- if (chip->mpu_res) {
- if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI,
- mpu_port[dev],
- MPU401_INFO_INTEGRATED |
- MPU401_INFO_IRQ_HOOK,
- -1, &chip->rawmidi)) < 0) {
- printk(KERN_WARNING "ymfpci: cannot initialize MPU401 at 0x%lx, skipping...\n", mpu_port[dev]);
- legacy_ctrl &= ~YMFPCI_LEGACY_MIEN; /* disable MPU401 irq */
- pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
- }
- }
- if (chip->fm_res) {
- if ((err = snd_opl3_create(card,
- fm_port[dev],
- fm_port[dev] + 2,
- OPL3_HW_OPL3, 1, &opl3)) < 0) {
- printk(KERN_WARNING "ymfpci: cannot initialize FM OPL3 at 0x%lx, skipping...\n", fm_port[dev]);
- legacy_ctrl &= ~YMFPCI_LEGACY_FMEN;
- pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
- } else if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
- snd_card_free(card);
- snd_printk(KERN_ERR "cannot create opl3 hwdep\n");
- return err;
- }
- }
-
- snd_ymfpci_create_gameport(chip, dev, legacy_ctrl, legacy_ctrl2);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- pci_set_drvdata(pci, card);
- dev++;
- return 0;
-}
-
-static void __devexit snd_card_ymfpci_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
- pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
- .name = KBUILD_MODNAME,
- .id_table = snd_ymfpci_ids,
- .probe = snd_card_ymfpci_probe,
- .remove = __devexit_p(snd_card_ymfpci_remove),
-#ifdef CONFIG_PM
- .suspend = snd_ymfpci_suspend,
- .resume = snd_ymfpci_resume,
-#endif
-};
-
-static int __init alsa_card_ymfpci_init(void)
-{
- return pci_register_driver(&driver);
-}
-
-static void __exit alsa_card_ymfpci_exit(void)
-{
- pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_ymfpci_init)
-module_exit(alsa_card_ymfpci_exit)
diff --git a/ANDROID_3.4.5/sound/pci/ymfpci/ymfpci_main.c b/ANDROID_3.4.5/sound/pci/ymfpci/ymfpci_main.c
deleted file mode 100644
index a8159b81..00000000
--- a/ANDROID_3.4.5/sound/pci/ymfpci/ymfpci_main.c
+++ /dev/null
@@ -1,2470 +0,0 @@
-/*
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- * Routines for control of YMF724/740/744/754 chips
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/delay.h>
-#include <linux/firmware.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/mutex.h>
-#include <linux/module.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/info.h>
-#include <sound/tlv.h>
-#include <sound/ymfpci.h>
-#include <sound/asoundef.h>
-#include <sound/mpu401.h>
-
-#include <asm/io.h>
-#include <asm/byteorder.h>
-
-/*
- * common I/O routines
- */
-
-static void snd_ymfpci_irq_wait(struct snd_ymfpci *chip);
-
-static inline u8 snd_ymfpci_readb(struct snd_ymfpci *chip, u32 offset)
-{
- return readb(chip->reg_area_virt + offset);
-}
-
-static inline void snd_ymfpci_writeb(struct snd_ymfpci *chip, u32 offset, u8 val)
-{
- writeb(val, chip->reg_area_virt + offset);
-}
-
-static inline u16 snd_ymfpci_readw(struct snd_ymfpci *chip, u32 offset)
-{
- return readw(chip->reg_area_virt + offset);
-}
-
-static inline void snd_ymfpci_writew(struct snd_ymfpci *chip, u32 offset, u16 val)
-{
- writew(val, chip->reg_area_virt + offset);
-}
-
-static inline u32 snd_ymfpci_readl(struct snd_ymfpci *chip, u32 offset)
-{
- return readl(chip->reg_area_virt + offset);
-}
-
-static inline void snd_ymfpci_writel(struct snd_ymfpci *chip, u32 offset, u32 val)
-{
- writel(val, chip->reg_area_virt + offset);
-}
-
-static int snd_ymfpci_codec_ready(struct snd_ymfpci *chip, int secondary)
-{
- unsigned long end_time;
- u32 reg = secondary ? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR;
-
- end_time = jiffies + msecs_to_jiffies(750);
- do {
- if ((snd_ymfpci_readw(chip, reg) & 0x8000) == 0)
- return 0;
- schedule_timeout_uninterruptible(1);
- } while (time_before(jiffies, end_time));
- snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg));
- return -EBUSY;
-}
-
-static void snd_ymfpci_codec_write(struct snd_ac97 *ac97, u16 reg, u16 val)
-{
- struct snd_ymfpci *chip = ac97->private_data;
- u32 cmd;
-
- snd_ymfpci_codec_ready(chip, 0);
- cmd = ((YDSXG_AC97WRITECMD | reg) << 16) | val;
- snd_ymfpci_writel(chip, YDSXGR_AC97CMDDATA, cmd);
-}
-
-static u16 snd_ymfpci_codec_read(struct snd_ac97 *ac97, u16 reg)
-{
- struct snd_ymfpci *chip = ac97->private_data;
-
- if (snd_ymfpci_codec_ready(chip, 0))
- return ~0;
- snd_ymfpci_writew(chip, YDSXGR_AC97CMDADR, YDSXG_AC97READCMD | reg);
- if (snd_ymfpci_codec_ready(chip, 0))
- return ~0;
- if (chip->device_id == PCI_DEVICE_ID_YAMAHA_744 && chip->rev < 2) {
- int i;
- for (i = 0; i < 600; i++)
- snd_ymfpci_readw(chip, YDSXGR_PRISTATUSDATA);
- }
- return snd_ymfpci_readw(chip, YDSXGR_PRISTATUSDATA);
-}
-
-/*
- * Misc routines
- */
-
-static u32 snd_ymfpci_calc_delta(u32 rate)
-{
- switch (rate) {
- case 8000: return 0x02aaab00;
- case 11025: return 0x03accd00;
- case 16000: return 0x05555500;
- case 22050: return 0x07599a00;
- case 32000: return 0x0aaaab00;
- case 44100: return 0x0eb33300;
- default: return ((rate << 16) / 375) << 5;
- }
-}
-
-static u32 def_rate[8] = {
- 100, 2000, 8000, 11025, 16000, 22050, 32000, 48000
-};
-
-static u32 snd_ymfpci_calc_lpfK(u32 rate)
-{
- u32 i;
- static u32 val[8] = {
- 0x00570000, 0x06AA0000, 0x18B20000, 0x20930000,
- 0x2B9A0000, 0x35A10000, 0x3EAA0000, 0x40000000
- };
-
- if (rate == 44100)
- return 0x40000000; /* FIXME: What's the right value? */
- for (i = 0; i < 8; i++)
- if (rate <= def_rate[i])
- return val[i];
- return val[0];
-}
-
-static u32 snd_ymfpci_calc_lpfQ(u32 rate)
-{
- u32 i;
- static u32 val[8] = {
- 0x35280000, 0x34A70000, 0x32020000, 0x31770000,
- 0x31390000, 0x31C90000, 0x33D00000, 0x40000000
- };
-
- if (rate == 44100)
- return 0x370A0000;
- for (i = 0; i < 8; i++)
- if (rate <= def_rate[i])
- return val[i];
- return val[0];
-}
-
-/*
- * Hardware start management
- */
-
-static void snd_ymfpci_hw_start(struct snd_ymfpci *chip)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (chip->start_count++ > 0)
- goto __end;
- snd_ymfpci_writel(chip, YDSXGR_MODE,
- snd_ymfpci_readl(chip, YDSXGR_MODE) | 3);
- chip->active_bank = snd_ymfpci_readl(chip, YDSXGR_CTRLSELECT) & 1;
- __end:
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-
-static void snd_ymfpci_hw_stop(struct snd_ymfpci *chip)
-{
- unsigned long flags;
- long timeout = 1000;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (--chip->start_count > 0)
- goto __end;
- snd_ymfpci_writel(chip, YDSXGR_MODE,
- snd_ymfpci_readl(chip, YDSXGR_MODE) & ~3);
- while (timeout-- > 0) {
- if ((snd_ymfpci_readl(chip, YDSXGR_STATUS) & 2) == 0)
- break;
- }
- if (atomic_read(&chip->interrupt_sleep_count)) {
- atomic_set(&chip->interrupt_sleep_count, 0);
- wake_up(&chip->interrupt_sleep);
- }
- __end:
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-
-/*
- * Playback voice management
- */
-
-static int voice_alloc(struct snd_ymfpci *chip,
- enum snd_ymfpci_voice_type type, int pair,
- struct snd_ymfpci_voice **rvoice)
-{
- struct snd_ymfpci_voice *voice, *voice2;
- int idx;
-
- *rvoice = NULL;
- for (idx = 0; idx < YDSXG_PLAYBACK_VOICES; idx += pair ? 2 : 1) {
- voice = &chip->voices[idx];
- voice2 = pair ? &chip->voices[idx+1] : NULL;
- if (voice->use || (voice2 && voice2->use))
- continue;
- voice->use = 1;
- if (voice2)
- voice2->use = 1;
- switch (type) {
- case YMFPCI_PCM:
- voice->pcm = 1;
- if (voice2)
- voice2->pcm = 1;
- break;
- case YMFPCI_SYNTH:
- voice->synth = 1;
- break;
- case YMFPCI_MIDI:
- voice->midi = 1;
- break;
- }
- snd_ymfpci_hw_start(chip);
- if (voice2)
- snd_ymfpci_hw_start(chip);
- *rvoice = voice;
- return 0;
- }
- return -ENOMEM;
-}
-
-static int snd_ymfpci_voice_alloc(struct snd_ymfpci *chip,
- enum snd_ymfpci_voice_type type, int pair,
- struct snd_ymfpci_voice **rvoice)
-{
- unsigned long flags;
- int result;
-
- if (snd_BUG_ON(!rvoice))
- return -EINVAL;
- if (snd_BUG_ON(pair && type != YMFPCI_PCM))
- return -EINVAL;
-
- spin_lock_irqsave(&chip->voice_lock, flags);
- for (;;) {
- result = voice_alloc(chip, type, pair, rvoice);
- if (result == 0 || type != YMFPCI_PCM)
- break;
- /* TODO: synth/midi voice deallocation */
- break;
- }
- spin_unlock_irqrestore(&chip->voice_lock, flags);
- return result;
-}
-
-static int snd_ymfpci_voice_free(struct snd_ymfpci *chip, struct snd_ymfpci_voice *pvoice)
-{
- unsigned long flags;
-
- if (snd_BUG_ON(!pvoice))
- return -EINVAL;
- snd_ymfpci_hw_stop(chip);
- spin_lock_irqsave(&chip->voice_lock, flags);
- if (pvoice->number == chip->src441_used) {
- chip->src441_used = -1;
- pvoice->ypcm->use_441_slot = 0;
- }
- pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = 0;
- pvoice->ypcm = NULL;
- pvoice->interrupt = NULL;
- spin_unlock_irqrestore(&chip->voice_lock, flags);
- return 0;
-}
-
-/*
- * PCM part
- */
-
-static void snd_ymfpci_pcm_interrupt(struct snd_ymfpci *chip, struct snd_ymfpci_voice *voice)
-{
- struct snd_ymfpci_pcm *ypcm;
- u32 pos, delta;
-
- if ((ypcm = voice->ypcm) == NULL)
- return;
- if (ypcm->substream == NULL)
- return;
- spin_lock(&chip->reg_lock);
- if (ypcm->running) {
- pos = le32_to_cpu(voice->bank[chip->active_bank].start);
- if (pos < ypcm->last_pos)
- delta = pos + (ypcm->buffer_size - ypcm->last_pos);
- else
- delta = pos - ypcm->last_pos;
- ypcm->period_pos += delta;
- ypcm->last_pos = pos;
- if (ypcm->period_pos >= ypcm->period_size) {
- /*
- printk(KERN_DEBUG
- "done - active_bank = 0x%x, start = 0x%x\n",
- chip->active_bank,
- voice->bank[chip->active_bank].start);
- */
- ypcm->period_pos %= ypcm->period_size;
- spin_unlock(&chip->reg_lock);
- snd_pcm_period_elapsed(ypcm->substream);
- spin_lock(&chip->reg_lock);
- }
-
- if (unlikely(ypcm->update_pcm_vol)) {
- unsigned int subs = ypcm->substream->number;
- unsigned int next_bank = 1 - chip->active_bank;
- struct snd_ymfpci_playback_bank *bank;
- u32 volume;
-
- bank = &voice->bank[next_bank];
- volume = cpu_to_le32(chip->pcm_mixer[subs].left << 15);
- bank->left_gain_end = volume;
- if (ypcm->output_rear)
- bank->eff2_gain_end = volume;
- if (ypcm->voices[1])
- bank = &ypcm->voices[1]->bank[next_bank];
- volume = cpu_to_le32(chip->pcm_mixer[subs].right << 15);
- bank->right_gain_end = volume;
- if (ypcm->output_rear)
- bank->eff3_gain_end = volume;
- ypcm->update_pcm_vol--;
- }
- }
- spin_unlock(&chip->reg_lock);
-}
-
-static void snd_ymfpci_pcm_capture_interrupt(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ymfpci_pcm *ypcm = runtime->private_data;
- struct snd_ymfpci *chip = ypcm->chip;
- u32 pos, delta;
-
- spin_lock(&chip->reg_lock);
- if (ypcm->running) {
- pos = le32_to_cpu(chip->bank_capture[ypcm->capture_bank_number][chip->active_bank]->start) >> ypcm->shift;
- if (pos < ypcm->last_pos)
- delta = pos + (ypcm->buffer_size - ypcm->last_pos);
- else
- delta = pos - ypcm->last_pos;
- ypcm->period_pos += delta;
- ypcm->last_pos = pos;
- if (ypcm->period_pos >= ypcm->period_size) {
- ypcm->period_pos %= ypcm->period_size;
- /*
- printk(KERN_DEBUG
- "done - active_bank = 0x%x, start = 0x%x\n",
- chip->active_bank,
- voice->bank[chip->active_bank].start);
- */
- spin_unlock(&chip->reg_lock);
- snd_pcm_period_elapsed(substream);
- spin_lock(&chip->reg_lock);
- }
- }
- spin_unlock(&chip->reg_lock);
-}
-
-static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
- struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data;
- struct snd_kcontrol *kctl = NULL;
- int result = 0;
-
- spin_lock(&chip->reg_lock);
- if (ypcm->voices[0] == NULL) {
- result = -EINVAL;
- goto __unlock;
- }
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
- chip->ctrl_playback[ypcm->voices[0]->number + 1] = cpu_to_le32(ypcm->voices[0]->bank_addr);
- if (ypcm->voices[1] != NULL && !ypcm->use_441_slot)
- chip->ctrl_playback[ypcm->voices[1]->number + 1] = cpu_to_le32(ypcm->voices[1]->bank_addr);
- ypcm->running = 1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- if (substream->pcm == chip->pcm && !ypcm->use_441_slot) {
- kctl = chip->pcm_mixer[substream->number].ctl;
- kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- }
- /* fall through */
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- chip->ctrl_playback[ypcm->voices[0]->number + 1] = 0;
- if (ypcm->voices[1] != NULL && !ypcm->use_441_slot)
- chip->ctrl_playback[ypcm->voices[1]->number + 1] = 0;
- ypcm->running = 0;
- break;
- default:
- result = -EINVAL;
- break;
- }
- __unlock:
- spin_unlock(&chip->reg_lock);
- if (kctl)
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id);
- return result;
-}
-static int snd_ymfpci_capture_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
- struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data;
- int result = 0;
- u32 tmp;
-
- spin_lock(&chip->reg_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
- tmp = snd_ymfpci_readl(chip, YDSXGR_MAPOFREC) | (1 << ypcm->capture_bank_number);
- snd_ymfpci_writel(chip, YDSXGR_MAPOFREC, tmp);
- ypcm->running = 1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- tmp = snd_ymfpci_readl(chip, YDSXGR_MAPOFREC) & ~(1 << ypcm->capture_bank_number);
- snd_ymfpci_writel(chip, YDSXGR_MAPOFREC, tmp);
- ypcm->running = 0;
- break;
- default:
- result = -EINVAL;
- break;
- }
- spin_unlock(&chip->reg_lock);
- return result;
-}
-
-static int snd_ymfpci_pcm_voice_alloc(struct snd_ymfpci_pcm *ypcm, int voices)
-{
- int err;
-
- if (ypcm->voices[1] != NULL && voices < 2) {
- snd_ymfpci_voice_free(ypcm->chip, ypcm->voices[1]);
- ypcm->voices[1] = NULL;
- }
- if (voices == 1 && ypcm->voices[0] != NULL)
- return 0; /* already allocated */
- if (voices == 2 && ypcm->voices[0] != NULL && ypcm->voices[1] != NULL)
- return 0; /* already allocated */
- if (voices > 1) {
- if (ypcm->voices[0] != NULL && ypcm->voices[1] == NULL) {
- snd_ymfpci_voice_free(ypcm->chip, ypcm->voices[0]);
- ypcm->voices[0] = NULL;
- }
- }
- err = snd_ymfpci_voice_alloc(ypcm->chip, YMFPCI_PCM, voices > 1, &ypcm->voices[0]);
- if (err < 0)
- return err;
- ypcm->voices[0]->ypcm = ypcm;
- ypcm->voices[0]->interrupt = snd_ymfpci_pcm_interrupt;
- if (voices > 1) {
- ypcm->voices[1] = &ypcm->chip->voices[ypcm->voices[0]->number + 1];
- ypcm->voices[1]->ypcm = ypcm;
- }
- return 0;
-}
-
-static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int voiceidx,
- struct snd_pcm_runtime *runtime,
- int has_pcm_volume)
-{
- struct snd_ymfpci_voice *voice = ypcm->voices[voiceidx];
- u32 format;
- u32 delta = snd_ymfpci_calc_delta(runtime->rate);
- u32 lpfQ = snd_ymfpci_calc_lpfQ(runtime->rate);
- u32 lpfK = snd_ymfpci_calc_lpfK(runtime->rate);
- struct snd_ymfpci_playback_bank *bank;
- unsigned int nbank;
- u32 vol_left, vol_right;
- u8 use_left, use_right;
- unsigned long flags;
-
- if (snd_BUG_ON(!voice))
- return;
- if (runtime->channels == 1) {
- use_left = 1;
- use_right = 1;
- } else {
- use_left = (voiceidx & 1) == 0;
- use_right = !use_left;
- }
- if (has_pcm_volume) {
- vol_left = cpu_to_le32(ypcm->chip->pcm_mixer
- [ypcm->substream->number].left << 15);
- vol_right = cpu_to_le32(ypcm->chip->pcm_mixer
- [ypcm->substream->number].right << 15);
- } else {
- vol_left = cpu_to_le32(0x40000000);
- vol_right = cpu_to_le32(0x40000000);
- }
- spin_lock_irqsave(&ypcm->chip->voice_lock, flags);
- format = runtime->channels == 2 ? 0x00010000 : 0;
- if (snd_pcm_format_width(runtime->format) == 8)
- format |= 0x80000000;
- else if (ypcm->chip->device_id == PCI_DEVICE_ID_YAMAHA_754 &&
- runtime->rate == 44100 && runtime->channels == 2 &&
- voiceidx == 0 && (ypcm->chip->src441_used == -1 ||
- ypcm->chip->src441_used == voice->number)) {
- ypcm->chip->src441_used = voice->number;
- ypcm->use_441_slot = 1;
- format |= 0x10000000;
- }
- if (ypcm->chip->src441_used == voice->number &&
- (format & 0x10000000) == 0) {
- ypcm->chip->src441_used = -1;
- ypcm->use_441_slot = 0;
- }
- if (runtime->channels == 2 && (voiceidx & 1) != 0)
- format |= 1;
- spin_unlock_irqrestore(&ypcm->chip->voice_lock, flags);
- for (nbank = 0; nbank < 2; nbank++) {
- bank = &voice->bank[nbank];
- memset(bank, 0, sizeof(*bank));
- bank->format = cpu_to_le32(format);
- bank->base = cpu_to_le32(runtime->dma_addr);
- bank->loop_end = cpu_to_le32(ypcm->buffer_size);
- bank->lpfQ = cpu_to_le32(lpfQ);
- bank->delta =
- bank->delta_end = cpu_to_le32(delta);
- bank->lpfK =
- bank->lpfK_end = cpu_to_le32(lpfK);
- bank->eg_gain =
- bank->eg_gain_end = cpu_to_le32(0x40000000);
-
- if (ypcm->output_front) {
- if (use_left) {
- bank->left_gain =
- bank->left_gain_end = vol_left;
- }
- if (use_right) {
- bank->right_gain =
- bank->right_gain_end = vol_right;
- }
- }
- if (ypcm->output_rear) {
- if (!ypcm->swap_rear) {
- if (use_left) {
- bank->eff2_gain =
- bank->eff2_gain_end = vol_left;
- }
- if (use_right) {
- bank->eff3_gain =
- bank->eff3_gain_end = vol_right;
- }
- } else {
- /* The SPDIF out channels seem to be swapped, so we have
- * to swap them here, too. The rear analog out channels
- * will be wrong, but otherwise AC3 would not work.
- */
- if (use_left) {
- bank->eff3_gain =
- bank->eff3_gain_end = vol_left;
- }
- if (use_right) {
- bank->eff2_gain =
- bank->eff2_gain_end = vol_right;
- }
- }
- }
- }
-}
-
-static int __devinit snd_ymfpci_ac3_init(struct snd_ymfpci *chip)
-{
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
- 4096, &chip->ac3_tmp_base) < 0)
- return -ENOMEM;
-
- chip->bank_effect[3][0]->base =
- chip->bank_effect[3][1]->base = cpu_to_le32(chip->ac3_tmp_base.addr);
- chip->bank_effect[3][0]->loop_end =
- chip->bank_effect[3][1]->loop_end = cpu_to_le32(1024);
- chip->bank_effect[4][0]->base =
- chip->bank_effect[4][1]->base = cpu_to_le32(chip->ac3_tmp_base.addr + 2048);
- chip->bank_effect[4][0]->loop_end =
- chip->bank_effect[4][1]->loop_end = cpu_to_le32(1024);
-
- spin_lock_irq(&chip->reg_lock);
- snd_ymfpci_writel(chip, YDSXGR_MAPOFEFFECT,
- snd_ymfpci_readl(chip, YDSXGR_MAPOFEFFECT) | 3 << 3);
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static int snd_ymfpci_ac3_done(struct snd_ymfpci *chip)
-{
- spin_lock_irq(&chip->reg_lock);
- snd_ymfpci_writel(chip, YDSXGR_MAPOFEFFECT,
- snd_ymfpci_readl(chip, YDSXGR_MAPOFEFFECT) & ~(3 << 3));
- spin_unlock_irq(&chip->reg_lock);
- // snd_ymfpci_irq_wait(chip);
- if (chip->ac3_tmp_base.area) {
- snd_dma_free_pages(&chip->ac3_tmp_base);
- chip->ac3_tmp_base.area = NULL;
- }
- return 0;
-}
-
-static int snd_ymfpci_playback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ymfpci_pcm *ypcm = runtime->private_data;
- int err;
-
- if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
- return err;
- if ((err = snd_ymfpci_pcm_voice_alloc(ypcm, params_channels(hw_params))) < 0)
- return err;
- return 0;
-}
-
-static int snd_ymfpci_playback_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ymfpci_pcm *ypcm;
-
- if (runtime->private_data == NULL)
- return 0;
- ypcm = runtime->private_data;
-
- /* wait, until the PCI operations are not finished */
- snd_ymfpci_irq_wait(chip);
- snd_pcm_lib_free_pages(substream);
- if (ypcm->voices[1]) {
- snd_ymfpci_voice_free(chip, ypcm->voices[1]);
- ypcm->voices[1] = NULL;
- }
- if (ypcm->voices[0]) {
- snd_ymfpci_voice_free(chip, ypcm->voices[0]);
- ypcm->voices[0] = NULL;
- }
- return 0;
-}
-
-static int snd_ymfpci_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ymfpci_pcm *ypcm = runtime->private_data;
- struct snd_kcontrol *kctl;
- unsigned int nvoice;
-
- ypcm->period_size = runtime->period_size;
- ypcm->buffer_size = runtime->buffer_size;
- ypcm->period_pos = 0;
- ypcm->last_pos = 0;
- for (nvoice = 0; nvoice < runtime->channels; nvoice++)
- snd_ymfpci_pcm_init_voice(ypcm, nvoice, runtime,
- substream->pcm == chip->pcm);
-
- if (substream->pcm == chip->pcm && !ypcm->use_441_slot) {
- kctl = chip->pcm_mixer[substream->number].ctl;
- kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id);
- }
- return 0;
-}
-
-static int snd_ymfpci_capture_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static int snd_ymfpci_capture_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
-
- /* wait, until the PCI operations are not finished */
- snd_ymfpci_irq_wait(chip);
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_ymfpci_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ymfpci_pcm *ypcm = runtime->private_data;
- struct snd_ymfpci_capture_bank * bank;
- int nbank;
- u32 rate, format;
-
- ypcm->period_size = runtime->period_size;
- ypcm->buffer_size = runtime->buffer_size;
- ypcm->period_pos = 0;
- ypcm->last_pos = 0;
- ypcm->shift = 0;
- rate = ((48000 * 4096) / runtime->rate) - 1;
- format = 0;
- if (runtime->channels == 2) {
- format |= 2;
- ypcm->shift++;
- }
- if (snd_pcm_format_width(runtime->format) == 8)
- format |= 1;
- else
- ypcm->shift++;
- switch (ypcm->capture_bank_number) {
- case 0:
- snd_ymfpci_writel(chip, YDSXGR_RECFORMAT, format);
- snd_ymfpci_writel(chip, YDSXGR_RECSLOTSR, rate);
- break;
- case 1:
- snd_ymfpci_writel(chip, YDSXGR_ADCFORMAT, format);
- snd_ymfpci_writel(chip, YDSXGR_ADCSLOTSR, rate);
- break;
- }
- for (nbank = 0; nbank < 2; nbank++) {
- bank = chip->bank_capture[ypcm->capture_bank_number][nbank];
- bank->base = cpu_to_le32(runtime->dma_addr);
- bank->loop_end = cpu_to_le32(ypcm->buffer_size << ypcm->shift);
- bank->start = 0;
- bank->num_of_loops = 0;
- }
- return 0;
-}
-
-static snd_pcm_uframes_t snd_ymfpci_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ymfpci_pcm *ypcm = runtime->private_data;
- struct snd_ymfpci_voice *voice = ypcm->voices[0];
-
- if (!(ypcm->running && voice))
- return 0;
- return le32_to_cpu(voice->bank[chip->active_bank].start);
-}
-
-static snd_pcm_uframes_t snd_ymfpci_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ymfpci_pcm *ypcm = runtime->private_data;
-
- if (!ypcm->running)
- return 0;
- return le32_to_cpu(chip->bank_capture[ypcm->capture_bank_number][chip->active_bank]->start) >> ypcm->shift;
-}
-
-static void snd_ymfpci_irq_wait(struct snd_ymfpci *chip)
-{
- wait_queue_t wait;
- int loops = 4;
-
- while (loops-- > 0) {
- if ((snd_ymfpci_readl(chip, YDSXGR_MODE) & 3) == 0)
- continue;
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&chip->interrupt_sleep, &wait);
- atomic_inc(&chip->interrupt_sleep_count);
- schedule_timeout_uninterruptible(msecs_to_jiffies(50));
- remove_wait_queue(&chip->interrupt_sleep, &wait);
- }
-}
-
-static irqreturn_t snd_ymfpci_interrupt(int irq, void *dev_id)
-{
- struct snd_ymfpci *chip = dev_id;
- u32 status, nvoice, mode;
- struct snd_ymfpci_voice *voice;
-
- status = snd_ymfpci_readl(chip, YDSXGR_STATUS);
- if (status & 0x80000000) {
- chip->active_bank = snd_ymfpci_readl(chip, YDSXGR_CTRLSELECT) & 1;
- spin_lock(&chip->voice_lock);
- for (nvoice = 0; nvoice < YDSXG_PLAYBACK_VOICES; nvoice++) {
- voice = &chip->voices[nvoice];
- if (voice->interrupt)
- voice->interrupt(chip, voice);
- }
- for (nvoice = 0; nvoice < YDSXG_CAPTURE_VOICES; nvoice++) {
- if (chip->capture_substream[nvoice])
- snd_ymfpci_pcm_capture_interrupt(chip->capture_substream[nvoice]);
- }
-#if 0
- for (nvoice = 0; nvoice < YDSXG_EFFECT_VOICES; nvoice++) {
- if (chip->effect_substream[nvoice])
- snd_ymfpci_pcm_effect_interrupt(chip->effect_substream[nvoice]);
- }
-#endif
- spin_unlock(&chip->voice_lock);
- spin_lock(&chip->reg_lock);
- snd_ymfpci_writel(chip, YDSXGR_STATUS, 0x80000000);
- mode = snd_ymfpci_readl(chip, YDSXGR_MODE) | 2;
- snd_ymfpci_writel(chip, YDSXGR_MODE, mode);
- spin_unlock(&chip->reg_lock);
-
- if (atomic_read(&chip->interrupt_sleep_count)) {
- atomic_set(&chip->interrupt_sleep_count, 0);
- wake_up(&chip->interrupt_sleep);
- }
- }
-
- status = snd_ymfpci_readw(chip, YDSXGR_INTFLAG);
- if (status & 1) {
- if (chip->timer)
- snd_timer_interrupt(chip->timer, chip->timer_ticks);
- }
- snd_ymfpci_writew(chip, YDSXGR_INTFLAG, status);
-
- if (chip->rawmidi)
- snd_mpu401_uart_interrupt(irq, chip->rawmidi->private_data);
- return IRQ_HANDLED;
-}
-
-static struct snd_pcm_hardware snd_ymfpci_playback =
-{
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 256 * 1024, /* FIXME: enough? */
- .period_bytes_min = 64,
- .period_bytes_max = 256 * 1024, /* FIXME: enough? */
- .periods_min = 3,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware snd_ymfpci_capture =
-{
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME),
- .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 256 * 1024, /* FIXME: enough? */
- .period_bytes_min = 64,
- .period_bytes_max = 256 * 1024, /* FIXME: enough? */
- .periods_min = 3,
- .periods_max = 1024,
- .fifo_size = 0,
-};
-
-static void snd_ymfpci_pcm_free_substream(struct snd_pcm_runtime *runtime)
-{
- kfree(runtime->private_data);
-}
-
-static int snd_ymfpci_playback_open_1(struct snd_pcm_substream *substream)
-{
- struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ymfpci_pcm *ypcm;
- int err;
-
- runtime->hw = snd_ymfpci_playback;
- /* FIXME? True value is 256/48 = 5.33333 ms */
- err = snd_pcm_hw_constraint_minmax(runtime,
- SNDRV_PCM_HW_PARAM_PERIOD_TIME,
- 5334, UINT_MAX);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_noresample(runtime, 48000);
- if (err < 0)
- return err;
-
- ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL);
- if (ypcm == NULL)
- return -ENOMEM;
- ypcm->chip = chip;
- ypcm->type = PLAYBACK_VOICE;
- ypcm->substream = substream;
- runtime->private_data = ypcm;
- runtime->private_free = snd_ymfpci_pcm_free_substream;
- return 0;
-}
-
-/* call with spinlock held */
-static void ymfpci_open_extension(struct snd_ymfpci *chip)
-{
- if (! chip->rear_opened) {
- if (! chip->spdif_opened) /* set AC3 */
- snd_ymfpci_writel(chip, YDSXGR_MODE,
- snd_ymfpci_readl(chip, YDSXGR_MODE) | (1 << 30));
- /* enable second codec (4CHEN) */
- snd_ymfpci_writew(chip, YDSXGR_SECCONFIG,
- (snd_ymfpci_readw(chip, YDSXGR_SECCONFIG) & ~0x0330) | 0x0010);
- }
-}
-
-/* call with spinlock held */
-static void ymfpci_close_extension(struct snd_ymfpci *chip)
-{
- if (! chip->rear_opened) {
- if (! chip->spdif_opened)
- snd_ymfpci_writel(chip, YDSXGR_MODE,
- snd_ymfpci_readl(chip, YDSXGR_MODE) & ~(1 << 30));
- snd_ymfpci_writew(chip, YDSXGR_SECCONFIG,
- (snd_ymfpci_readw(chip, YDSXGR_SECCONFIG) & ~0x0330) & ~0x0010);
- }
-}
-
-static int snd_ymfpci_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ymfpci_pcm *ypcm;
- int err;
-
- if ((err = snd_ymfpci_playback_open_1(substream)) < 0)
- return err;
- ypcm = runtime->private_data;
- ypcm->output_front = 1;
- ypcm->output_rear = chip->mode_dup4ch ? 1 : 0;
- ypcm->swap_rear = 0;
- spin_lock_irq(&chip->reg_lock);
- if (ypcm->output_rear) {
- ymfpci_open_extension(chip);
- chip->rear_opened++;
- }
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static int snd_ymfpci_playback_spdif_open(struct snd_pcm_substream *substream)
-{
- struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ymfpci_pcm *ypcm;
- int err;
-
- if ((err = snd_ymfpci_playback_open_1(substream)) < 0)
- return err;
- ypcm = runtime->private_data;
- ypcm->output_front = 0;
- ypcm->output_rear = 1;
- ypcm->swap_rear = 1;
- spin_lock_irq(&chip->reg_lock);
- snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTCTRL,
- snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) | 2);
- ymfpci_open_extension(chip);
- chip->spdif_pcm_bits = chip->spdif_bits;
- snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_pcm_bits);
- chip->spdif_opened++;
- spin_unlock_irq(&chip->reg_lock);
-
- chip->spdif_pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO, &chip->spdif_pcm_ctl->id);
- return 0;
-}
-
-static int snd_ymfpci_playback_4ch_open(struct snd_pcm_substream *substream)
-{
- struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ymfpci_pcm *ypcm;
- int err;
-
- if ((err = snd_ymfpci_playback_open_1(substream)) < 0)
- return err;
- ypcm = runtime->private_data;
- ypcm->output_front = 0;
- ypcm->output_rear = 1;
- ypcm->swap_rear = 0;
- spin_lock_irq(&chip->reg_lock);
- ymfpci_open_extension(chip);
- chip->rear_opened++;
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static int snd_ymfpci_capture_open(struct snd_pcm_substream *substream,
- u32 capture_bank_number)
-{
- struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ymfpci_pcm *ypcm;
- int err;
-
- runtime->hw = snd_ymfpci_capture;
- /* FIXME? True value is 256/48 = 5.33333 ms */
- err = snd_pcm_hw_constraint_minmax(runtime,
- SNDRV_PCM_HW_PARAM_PERIOD_TIME,
- 5334, UINT_MAX);
- if (err < 0)
- return err;
- err = snd_pcm_hw_rule_noresample(runtime, 48000);
- if (err < 0)
- return err;
-
- ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL);
- if (ypcm == NULL)
- return -ENOMEM;
- ypcm->chip = chip;
- ypcm->type = capture_bank_number + CAPTURE_REC;
- ypcm->substream = substream;
- ypcm->capture_bank_number = capture_bank_number;
- chip->capture_substream[capture_bank_number] = substream;
- runtime->private_data = ypcm;
- runtime->private_free = snd_ymfpci_pcm_free_substream;
- snd_ymfpci_hw_start(chip);
- return 0;
-}
-
-static int snd_ymfpci_capture_rec_open(struct snd_pcm_substream *substream)
-{
- return snd_ymfpci_capture_open(substream, 0);
-}
-
-static int snd_ymfpci_capture_ac97_open(struct snd_pcm_substream *substream)
-{
- return snd_ymfpci_capture_open(substream, 1);
-}
-
-static int snd_ymfpci_playback_close_1(struct snd_pcm_substream *substream)
-{
- return 0;
-}
-
-static int snd_ymfpci_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
- struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data;
-
- spin_lock_irq(&chip->reg_lock);
- if (ypcm->output_rear && chip->rear_opened > 0) {
- chip->rear_opened--;
- ymfpci_close_extension(chip);
- }
- spin_unlock_irq(&chip->reg_lock);
- return snd_ymfpci_playback_close_1(substream);
-}
-
-static int snd_ymfpci_playback_spdif_close(struct snd_pcm_substream *substream)
-{
- struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&chip->reg_lock);
- chip->spdif_opened = 0;
- ymfpci_close_extension(chip);
- snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTCTRL,
- snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) & ~2);
- snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_bits);
- spin_unlock_irq(&chip->reg_lock);
- chip->spdif_pcm_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
- SNDRV_CTL_EVENT_MASK_INFO, &chip->spdif_pcm_ctl->id);
- return snd_ymfpci_playback_close_1(substream);
-}
-
-static int snd_ymfpci_playback_4ch_close(struct snd_pcm_substream *substream)
-{
- struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
-
- spin_lock_irq(&chip->reg_lock);
- if (chip->rear_opened > 0) {
- chip->rear_opened--;
- ymfpci_close_extension(chip);
- }
- spin_unlock_irq(&chip->reg_lock);
- return snd_ymfpci_playback_close_1(substream);
-}
-
-static int snd_ymfpci_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ymfpci_pcm *ypcm = runtime->private_data;
-
- if (ypcm != NULL) {
- chip->capture_substream[ypcm->capture_bank_number] = NULL;
- snd_ymfpci_hw_stop(chip);
- }
- return 0;
-}
-
-static struct snd_pcm_ops snd_ymfpci_playback_ops = {
- .open = snd_ymfpci_playback_open,
- .close = snd_ymfpci_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ymfpci_playback_hw_params,
- .hw_free = snd_ymfpci_playback_hw_free,
- .prepare = snd_ymfpci_playback_prepare,
- .trigger = snd_ymfpci_playback_trigger,
- .pointer = snd_ymfpci_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_ymfpci_capture_rec_ops = {
- .open = snd_ymfpci_capture_rec_open,
- .close = snd_ymfpci_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ymfpci_capture_hw_params,
- .hw_free = snd_ymfpci_capture_hw_free,
- .prepare = snd_ymfpci_capture_prepare,
- .trigger = snd_ymfpci_capture_trigger,
- .pointer = snd_ymfpci_capture_pointer,
-};
-
-int __devinit snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
- if ((err = snd_pcm_new(chip->card, "YMFPCI", device, 32, 1, &pcm)) < 0)
- return err;
- pcm->private_data = chip;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ymfpci_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ymfpci_capture_rec_ops);
-
- /* global setup */
- pcm->info_flags = 0;
- strcpy(pcm->name, "YMFPCI");
- chip->pcm = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
-
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-static struct snd_pcm_ops snd_ymfpci_capture_ac97_ops = {
- .open = snd_ymfpci_capture_ac97_open,
- .close = snd_ymfpci_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ymfpci_capture_hw_params,
- .hw_free = snd_ymfpci_capture_hw_free,
- .prepare = snd_ymfpci_capture_prepare,
- .trigger = snd_ymfpci_capture_trigger,
- .pointer = snd_ymfpci_capture_pointer,
-};
-
-int __devinit snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
- if ((err = snd_pcm_new(chip->card, "YMFPCI - PCM2", device, 0, 1, &pcm)) < 0)
- return err;
- pcm->private_data = chip;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ymfpci_capture_ac97_ops);
-
- /* global setup */
- pcm->info_flags = 0;
- sprintf(pcm->name, "YMFPCI - %s",
- chip->device_id == PCI_DEVICE_ID_YAMAHA_754 ? "Direct Recording" : "AC'97");
- chip->pcm2 = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
-
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-static struct snd_pcm_ops snd_ymfpci_playback_spdif_ops = {
- .open = snd_ymfpci_playback_spdif_open,
- .close = snd_ymfpci_playback_spdif_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ymfpci_playback_hw_params,
- .hw_free = snd_ymfpci_playback_hw_free,
- .prepare = snd_ymfpci_playback_prepare,
- .trigger = snd_ymfpci_playback_trigger,
- .pointer = snd_ymfpci_playback_pointer,
-};
-
-int __devinit snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
- if ((err = snd_pcm_new(chip->card, "YMFPCI - IEC958", device, 1, 0, &pcm)) < 0)
- return err;
- pcm->private_data = chip;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ymfpci_playback_spdif_ops);
-
- /* global setup */
- pcm->info_flags = 0;
- strcpy(pcm->name, "YMFPCI - IEC958");
- chip->pcm_spdif = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
-
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-static struct snd_pcm_ops snd_ymfpci_playback_4ch_ops = {
- .open = snd_ymfpci_playback_4ch_open,
- .close = snd_ymfpci_playback_4ch_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ymfpci_playback_hw_params,
- .hw_free = snd_ymfpci_playback_hw_free,
- .prepare = snd_ymfpci_playback_prepare,
- .trigger = snd_ymfpci_playback_trigger,
- .pointer = snd_ymfpci_playback_pointer,
-};
-
-int __devinit snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm)
-{
- struct snd_pcm *pcm;
- int err;
-
- if (rpcm)
- *rpcm = NULL;
- if ((err = snd_pcm_new(chip->card, "YMFPCI - Rear", device, 1, 0, &pcm)) < 0)
- return err;
- pcm->private_data = chip;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ymfpci_playback_4ch_ops);
-
- /* global setup */
- pcm->info_flags = 0;
- strcpy(pcm->name, "YMFPCI - Rear PCM");
- chip->pcm_4ch = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
-
- if (rpcm)
- *rpcm = pcm;
- return 0;
-}
-
-static int snd_ymfpci_spdif_default_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_ymfpci_spdif_default_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&chip->reg_lock);
- ucontrol->value.iec958.status[0] = (chip->spdif_bits >> 0) & 0xff;
- ucontrol->value.iec958.status[1] = (chip->spdif_bits >> 8) & 0xff;
- ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_48000;
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static int snd_ymfpci_spdif_default_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change;
-
- val = ((ucontrol->value.iec958.status[0] & 0x3e) << 0) |
- (ucontrol->value.iec958.status[1] << 8);
- spin_lock_irq(&chip->reg_lock);
- change = chip->spdif_bits != val;
- chip->spdif_bits = val;
- if ((snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) & 1) && chip->pcm_spdif == NULL)
- snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_bits);
- spin_unlock_irq(&chip->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_ymfpci_spdif_default __devinitdata =
-{
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
- .info = snd_ymfpci_spdif_default_info,
- .get = snd_ymfpci_spdif_default_get,
- .put = snd_ymfpci_spdif_default_put
-};
-
-static int snd_ymfpci_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_ymfpci_spdif_mask_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&chip->reg_lock);
- ucontrol->value.iec958.status[0] = 0x3e;
- ucontrol->value.iec958.status[1] = 0xff;
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static struct snd_kcontrol_new snd_ymfpci_spdif_mask __devinitdata =
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
- .info = snd_ymfpci_spdif_mask_info,
- .get = snd_ymfpci_spdif_mask_get,
-};
-
-static int snd_ymfpci_spdif_stream_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-static int snd_ymfpci_spdif_stream_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
-
- spin_lock_irq(&chip->reg_lock);
- ucontrol->value.iec958.status[0] = (chip->spdif_pcm_bits >> 0) & 0xff;
- ucontrol->value.iec958.status[1] = (chip->spdif_pcm_bits >> 8) & 0xff;
- ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_48000;
- spin_unlock_irq(&chip->reg_lock);
- return 0;
-}
-
-static int snd_ymfpci_spdif_stream_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int change;
-
- val = ((ucontrol->value.iec958.status[0] & 0x3e) << 0) |
- (ucontrol->value.iec958.status[1] << 8);
- spin_lock_irq(&chip->reg_lock);
- change = chip->spdif_pcm_bits != val;
- chip->spdif_pcm_bits = val;
- if ((snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) & 2))
- snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_pcm_bits);
- spin_unlock_irq(&chip->reg_lock);
- return change;
-}
-
-static struct snd_kcontrol_new snd_ymfpci_spdif_stream __devinitdata =
-{
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
- .info = snd_ymfpci_spdif_stream_info,
- .get = snd_ymfpci_spdif_stream_get,
- .put = snd_ymfpci_spdif_stream_put
-};
-
-static int snd_ymfpci_drec_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *info)
-{
- static const char *const texts[3] = {"AC'97", "IEC958", "ZV Port"};
-
- return snd_ctl_enum_info(info, 1, 3, texts);
-}
-
-static int snd_ymfpci_drec_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value)
-{
- struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
- u16 reg;
-
- spin_lock_irq(&chip->reg_lock);
- reg = snd_ymfpci_readw(chip, YDSXGR_GLOBALCTRL);
- spin_unlock_irq(&chip->reg_lock);
- if (!(reg & 0x100))
- value->value.enumerated.item[0] = 0;
- else
- value->value.enumerated.item[0] = 1 + ((reg & 0x200) != 0);
- return 0;
-}
-
-static int snd_ymfpci_drec_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value)
-{
- struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
- u16 reg, old_reg;
-
- spin_lock_irq(&chip->reg_lock);
- old_reg = snd_ymfpci_readw(chip, YDSXGR_GLOBALCTRL);
- if (value->value.enumerated.item[0] == 0)
- reg = old_reg & ~0x100;
- else
- reg = (old_reg & ~0x300) | 0x100 | ((value->value.enumerated.item[0] == 2) << 9);
- snd_ymfpci_writew(chip, YDSXGR_GLOBALCTRL, reg);
- spin_unlock_irq(&chip->reg_lock);
- return reg != old_reg;
-}
-
-static struct snd_kcontrol_new snd_ymfpci_drec_source __devinitdata = {
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Direct Recording Source",
- .info = snd_ymfpci_drec_source_info,
- .get = snd_ymfpci_drec_source_get,
- .put = snd_ymfpci_drec_source_put
-};
-
-/*
- * Mixer controls
- */
-
-#define YMFPCI_SINGLE(xname, xindex, reg, shift) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_ymfpci_info_single, \
- .get = snd_ymfpci_get_single, .put = snd_ymfpci_put_single, \
- .private_value = ((reg) | ((shift) << 16)) }
-
-#define snd_ymfpci_info_single snd_ctl_boolean_mono_info
-
-static int snd_ymfpci_get_single(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xffff;
- unsigned int shift = (kcontrol->private_value >> 16) & 0xff;
- unsigned int mask = 1;
-
- switch (reg) {
- case YDSXGR_SPDIFOUTCTRL: break;
- case YDSXGR_SPDIFINCTRL: break;
- default: return -EINVAL;
- }
- ucontrol->value.integer.value[0] =
- (snd_ymfpci_readl(chip, reg) >> shift) & mask;
- return 0;
-}
-
-static int snd_ymfpci_put_single(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xffff;
- unsigned int shift = (kcontrol->private_value >> 16) & 0xff;
- unsigned int mask = 1;
- int change;
- unsigned int val, oval;
-
- switch (reg) {
- case YDSXGR_SPDIFOUTCTRL: break;
- case YDSXGR_SPDIFINCTRL: break;
- default: return -EINVAL;
- }
- val = (ucontrol->value.integer.value[0] & mask);
- val <<= shift;
- spin_lock_irq(&chip->reg_lock);
- oval = snd_ymfpci_readl(chip, reg);
- val = (oval & ~(mask << shift)) | val;
- change = val != oval;
- snd_ymfpci_writel(chip, reg, val);
- spin_unlock_irq(&chip->reg_lock);
- return change;
-}
-
-static const DECLARE_TLV_DB_LINEAR(db_scale_native, TLV_DB_GAIN_MUTE, 0);
-
-#define YMFPCI_DOUBLE(xname, xindex, reg) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
- .info = snd_ymfpci_info_double, \
- .get = snd_ymfpci_get_double, .put = snd_ymfpci_put_double, \
- .private_value = reg, \
- .tlv = { .p = db_scale_native } }
-
-static int snd_ymfpci_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- unsigned int reg = kcontrol->private_value;
-
- if (reg < 0x80 || reg >= 0xc0)
- return -EINVAL;
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 16383;
- return 0;
-}
-
-static int snd_ymfpci_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
- unsigned int reg = kcontrol->private_value;
- unsigned int shift_left = 0, shift_right = 16, mask = 16383;
- unsigned int val;
-
- if (reg < 0x80 || reg >= 0xc0)
- return -EINVAL;
- spin_lock_irq(&chip->reg_lock);
- val = snd_ymfpci_readl(chip, reg);
- spin_unlock_irq(&chip->reg_lock);
- ucontrol->value.integer.value[0] = (val >> shift_left) & mask;
- ucontrol->value.integer.value[1] = (val >> shift_right) & mask;
- return 0;
-}
-
-static int snd_ymfpci_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
- unsigned int reg = kcontrol->private_value;
- unsigned int shift_left = 0, shift_right = 16, mask = 16383;
- int change;
- unsigned int val1, val2, oval;
-
- if (reg < 0x80 || reg >= 0xc0)
- return -EINVAL;
- val1 = ucontrol->value.integer.value[0] & mask;
- val2 = ucontrol->value.integer.value[1] & mask;
- val1 <<= shift_left;
- val2 <<= shift_right;
- spin_lock_irq(&chip->reg_lock);
- oval = snd_ymfpci_readl(chip, reg);
- val1 = (oval & ~((mask << shift_left) | (mask << shift_right))) | val1 | val2;
- change = val1 != oval;
- snd_ymfpci_writel(chip, reg, val1);
- spin_unlock_irq(&chip->reg_lock);
- return change;
-}
-
-static int snd_ymfpci_put_nativedacvol(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
- unsigned int reg = YDSXGR_NATIVEDACOUTVOL;
- unsigned int reg2 = YDSXGR_BUF441OUTVOL;
- int change;
- unsigned int value, oval;
-
- value = ucontrol->value.integer.value[0] & 0x3fff;
- value |= (ucontrol->value.integer.value[1] & 0x3fff) << 16;
- spin_lock_irq(&chip->reg_lock);
- oval = snd_ymfpci_readl(chip, reg);
- change = value != oval;
- snd_ymfpci_writel(chip, reg, value);
- snd_ymfpci_writel(chip, reg2, value);
- spin_unlock_irq(&chip->reg_lock);
- return change;
-}
-
-/*
- * 4ch duplication
- */
-#define snd_ymfpci_info_dup4ch snd_ctl_boolean_mono_info
-
-static int snd_ymfpci_get_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = chip->mode_dup4ch;
- return 0;
-}
-
-static int snd_ymfpci_put_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
- int change;
- change = (ucontrol->value.integer.value[0] != chip->mode_dup4ch);
- if (change)
- chip->mode_dup4ch = !!ucontrol->value.integer.value[0];
- return change;
-}
-
-static struct snd_kcontrol_new snd_ymfpci_dup4ch __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "4ch Duplication",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = snd_ymfpci_info_dup4ch,
- .get = snd_ymfpci_get_dup4ch,
- .put = snd_ymfpci_put_dup4ch,
-};
-
-static struct snd_kcontrol_new snd_ymfpci_controls[] __devinitdata = {
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Wave Playback Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = snd_ymfpci_info_double,
- .get = snd_ymfpci_get_double,
- .put = snd_ymfpci_put_nativedacvol,
- .private_value = YDSXGR_NATIVEDACOUTVOL,
- .tlv = { .p = db_scale_native },
-},
-YMFPCI_DOUBLE("Wave Capture Volume", 0, YDSXGR_NATIVEDACLOOPVOL),
-YMFPCI_DOUBLE("Digital Capture Volume", 0, YDSXGR_NATIVEDACINVOL),
-YMFPCI_DOUBLE("Digital Capture Volume", 1, YDSXGR_NATIVEADCINVOL),
-YMFPCI_DOUBLE("ADC Playback Volume", 0, YDSXGR_PRIADCOUTVOL),
-YMFPCI_DOUBLE("ADC Capture Volume", 0, YDSXGR_PRIADCLOOPVOL),
-YMFPCI_DOUBLE("ADC Playback Volume", 1, YDSXGR_SECADCOUTVOL),
-YMFPCI_DOUBLE("ADC Capture Volume", 1, YDSXGR_SECADCLOOPVOL),
-YMFPCI_DOUBLE("FM Legacy Playback Volume", 0, YDSXGR_LEGACYOUTVOL),
-YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ", PLAYBACK,VOLUME), 0, YDSXGR_ZVOUTVOL),
-YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("", CAPTURE,VOLUME), 0, YDSXGR_ZVLOOPVOL),
-YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ",PLAYBACK,VOLUME), 1, YDSXGR_SPDIFOUTVOL),
-YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,VOLUME), 1, YDSXGR_SPDIFLOOPVOL),
-YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 0, YDSXGR_SPDIFOUTCTRL, 0),
-YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, YDSXGR_SPDIFINCTRL, 0),
-YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("Loop",NONE,NONE), 0, YDSXGR_SPDIFINCTRL, 4),
-};
-
-
-/*
- * GPIO
- */
-
-static int snd_ymfpci_get_gpio_out(struct snd_ymfpci *chip, int pin)
-{
- u16 reg, mode;
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- reg = snd_ymfpci_readw(chip, YDSXGR_GPIOFUNCENABLE);
- reg &= ~(1 << (pin + 8));
- reg |= (1 << pin);
- snd_ymfpci_writew(chip, YDSXGR_GPIOFUNCENABLE, reg);
- /* set the level mode for input line */
- mode = snd_ymfpci_readw(chip, YDSXGR_GPIOTYPECONFIG);
- mode &= ~(3 << (pin * 2));
- snd_ymfpci_writew(chip, YDSXGR_GPIOTYPECONFIG, mode);
- snd_ymfpci_writew(chip, YDSXGR_GPIOFUNCENABLE, reg | (1 << (pin + 8)));
- mode = snd_ymfpci_readw(chip, YDSXGR_GPIOINSTATUS);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return (mode >> pin) & 1;
-}
-
-static int snd_ymfpci_set_gpio_out(struct snd_ymfpci *chip, int pin, int enable)
-{
- u16 reg;
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- reg = snd_ymfpci_readw(chip, YDSXGR_GPIOFUNCENABLE);
- reg &= ~(1 << pin);
- reg &= ~(1 << (pin + 8));
- snd_ymfpci_writew(chip, YDSXGR_GPIOFUNCENABLE, reg);
- snd_ymfpci_writew(chip, YDSXGR_GPIOOUTCTRL, enable << pin);
- snd_ymfpci_writew(chip, YDSXGR_GPIOFUNCENABLE, reg | (1 << (pin + 8)));
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- return 0;
-}
-
-#define snd_ymfpci_gpio_sw_info snd_ctl_boolean_mono_info
-
-static int snd_ymfpci_gpio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
- int pin = (int)kcontrol->private_value;
- ucontrol->value.integer.value[0] = snd_ymfpci_get_gpio_out(chip, pin);
- return 0;
-}
-
-static int snd_ymfpci_gpio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
- int pin = (int)kcontrol->private_value;
-
- if (snd_ymfpci_get_gpio_out(chip, pin) != ucontrol->value.integer.value[0]) {
- snd_ymfpci_set_gpio_out(chip, pin, !!ucontrol->value.integer.value[0]);
- ucontrol->value.integer.value[0] = snd_ymfpci_get_gpio_out(chip, pin);
- return 1;
- }
- return 0;
-}
-
-static struct snd_kcontrol_new snd_ymfpci_rear_shared __devinitdata = {
- .name = "Shared Rear/Line-In Switch",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .info = snd_ymfpci_gpio_sw_info,
- .get = snd_ymfpci_gpio_sw_get,
- .put = snd_ymfpci_gpio_sw_put,
- .private_value = 2,
-};
-
-/*
- * PCM voice volume
- */
-
-static int snd_ymfpci_pcm_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 0x8000;
- return 0;
-}
-
-static int snd_ymfpci_pcm_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
- unsigned int subs = kcontrol->id.subdevice;
-
- ucontrol->value.integer.value[0] = chip->pcm_mixer[subs].left;
- ucontrol->value.integer.value[1] = chip->pcm_mixer[subs].right;
- return 0;
-}
-
-static int snd_ymfpci_pcm_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
- unsigned int subs = kcontrol->id.subdevice;
- struct snd_pcm_substream *substream;
- unsigned long flags;
-
- if (ucontrol->value.integer.value[0] != chip->pcm_mixer[subs].left ||
- ucontrol->value.integer.value[1] != chip->pcm_mixer[subs].right) {
- chip->pcm_mixer[subs].left = ucontrol->value.integer.value[0];
- chip->pcm_mixer[subs].right = ucontrol->value.integer.value[1];
- if (chip->pcm_mixer[subs].left > 0x8000)
- chip->pcm_mixer[subs].left = 0x8000;
- if (chip->pcm_mixer[subs].right > 0x8000)
- chip->pcm_mixer[subs].right = 0x8000;
-
- substream = (struct snd_pcm_substream *)kcontrol->private_value;
- spin_lock_irqsave(&chip->voice_lock, flags);
- if (substream->runtime && substream->runtime->private_data) {
- struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data;
- if (!ypcm->use_441_slot)
- ypcm->update_pcm_vol = 2;
- }
- spin_unlock_irqrestore(&chip->voice_lock, flags);
- return 1;
- }
- return 0;
-}
-
-static struct snd_kcontrol_new snd_ymfpci_pcm_volume __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "PCM Playback Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .info = snd_ymfpci_pcm_vol_info,
- .get = snd_ymfpci_pcm_vol_get,
- .put = snd_ymfpci_pcm_vol_put,
-};
-
-
-/*
- * Mixer routines
- */
-
-static void snd_ymfpci_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
-{
- struct snd_ymfpci *chip = bus->private_data;
- chip->ac97_bus = NULL;
-}
-
-static void snd_ymfpci_mixer_free_ac97(struct snd_ac97 *ac97)
-{
- struct snd_ymfpci *chip = ac97->private_data;
- chip->ac97 = NULL;
-}
-
-int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch)
-{
- struct snd_ac97_template ac97;
- struct snd_kcontrol *kctl;
- struct snd_pcm_substream *substream;
- unsigned int idx;
- int err;
- static struct snd_ac97_bus_ops ops = {
- .write = snd_ymfpci_codec_write,
- .read = snd_ymfpci_codec_read,
- };
-
- if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
- return err;
- chip->ac97_bus->private_free = snd_ymfpci_mixer_free_ac97_bus;
- chip->ac97_bus->no_vra = 1; /* YMFPCI doesn't need VRA */
-
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = chip;
- ac97.private_free = snd_ymfpci_mixer_free_ac97;
- if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
- return err;
-
- /* to be sure */
- snd_ac97_update_bits(chip->ac97, AC97_EXTENDED_STATUS,
- AC97_EA_VRA|AC97_EA_VRM, 0);
-
- for (idx = 0; idx < ARRAY_SIZE(snd_ymfpci_controls); idx++) {
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_controls[idx], chip))) < 0)
- return err;
- }
- if (chip->ac97->ext_id & AC97_EI_SDAC) {
- kctl = snd_ctl_new1(&snd_ymfpci_dup4ch, chip);
- err = snd_ctl_add(chip->card, kctl);
- if (err < 0)
- return err;
- }
-
- /* add S/PDIF control */
- if (snd_BUG_ON(!chip->pcm_spdif))
- return -ENXIO;
- if ((err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_spdif_default, chip))) < 0)
- return err;
- kctl->id.device = chip->pcm_spdif->device;
- if ((err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_spdif_mask, chip))) < 0)
- return err;
- kctl->id.device = chip->pcm_spdif->device;
- if ((err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_spdif_stream, chip))) < 0)
- return err;
- kctl->id.device = chip->pcm_spdif->device;
- chip->spdif_pcm_ctl = kctl;
-
- /* direct recording source */
- if (chip->device_id == PCI_DEVICE_ID_YAMAHA_754 &&
- (err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_drec_source, chip))) < 0)
- return err;
-
- /*
- * shared rear/line-in
- */
- if (rear_switch) {
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_rear_shared, chip))) < 0)
- return err;
- }
-
- /* per-voice volume */
- substream = chip->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
- for (idx = 0; idx < 32; ++idx) {
- kctl = snd_ctl_new1(&snd_ymfpci_pcm_volume, chip);
- if (!kctl)
- return -ENOMEM;
- kctl->id.device = chip->pcm->device;
- kctl->id.subdevice = idx;
- kctl->private_value = (unsigned long)substream;
- if ((err = snd_ctl_add(chip->card, kctl)) < 0)
- return err;
- chip->pcm_mixer[idx].left = 0x8000;
- chip->pcm_mixer[idx].right = 0x8000;
- chip->pcm_mixer[idx].ctl = kctl;
- substream = substream->next;
- }
-
- return 0;
-}
-
-
-/*
- * timer
- */
-
-static int snd_ymfpci_timer_start(struct snd_timer *timer)
-{
- struct snd_ymfpci *chip;
- unsigned long flags;
- unsigned int count;
-
- chip = snd_timer_chip(timer);
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (timer->sticks > 1) {
- chip->timer_ticks = timer->sticks;
- count = timer->sticks - 1;
- } else {
- /*
- * Divisor 1 is not allowed; fake it by using divisor 2 and
- * counting two ticks for each interrupt.
- */
- chip->timer_ticks = 2;
- count = 2 - 1;
- }
- snd_ymfpci_writew(chip, YDSXGR_TIMERCOUNT, count);
- snd_ymfpci_writeb(chip, YDSXGR_TIMERCTRL, 0x03);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
-}
-
-static int snd_ymfpci_timer_stop(struct snd_timer *timer)
-{
- struct snd_ymfpci *chip;
- unsigned long flags;
-
- chip = snd_timer_chip(timer);
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_ymfpci_writeb(chip, YDSXGR_TIMERCTRL, 0x00);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
-}
-
-static int snd_ymfpci_timer_precise_resolution(struct snd_timer *timer,
- unsigned long *num, unsigned long *den)
-{
- *num = 1;
- *den = 96000;
- return 0;
-}
-
-static struct snd_timer_hardware snd_ymfpci_timer_hw = {
- .flags = SNDRV_TIMER_HW_AUTO,
- .resolution = 10417, /* 1 / 96 kHz = 10.41666...us */
- .ticks = 0x10000,
- .start = snd_ymfpci_timer_start,
- .stop = snd_ymfpci_timer_stop,
- .precise_resolution = snd_ymfpci_timer_precise_resolution,
-};
-
-int __devinit snd_ymfpci_timer(struct snd_ymfpci *chip, int device)
-{
- struct snd_timer *timer = NULL;
- struct snd_timer_id tid;
- int err;
-
- tid.dev_class = SNDRV_TIMER_CLASS_CARD;
- tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
- tid.card = chip->card->number;
- tid.device = device;
- tid.subdevice = 0;
- if ((err = snd_timer_new(chip->card, "YMFPCI", &tid, &timer)) >= 0) {
- strcpy(timer->name, "YMFPCI timer");
- timer->private_data = chip;
- timer->hw = snd_ymfpci_timer_hw;
- }
- chip->timer = timer;
- return err;
-}
-
-
-/*
- * proc interface
- */
-
-static void snd_ymfpci_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_ymfpci *chip = entry->private_data;
- int i;
-
- snd_iprintf(buffer, "YMFPCI\n\n");
- for (i = 0; i <= YDSXGR_WORKBASE; i += 4)
- snd_iprintf(buffer, "%04x: %04x\n", i, snd_ymfpci_readl(chip, i));
-}
-
-static int __devinit snd_ymfpci_proc_init(struct snd_card *card, struct snd_ymfpci *chip)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(card, "ymfpci", &entry))
- snd_info_set_text_ops(entry, chip, snd_ymfpci_proc_read);
- return 0;
-}
-
-/*
- * initialization routines
- */
-
-static void snd_ymfpci_aclink_reset(struct pci_dev * pci)
-{
- u8 cmd;
-
- pci_read_config_byte(pci, PCIR_DSXG_CTRL, &cmd);
-#if 0 // force to reset
- if (cmd & 0x03) {
-#endif
- pci_write_config_byte(pci, PCIR_DSXG_CTRL, cmd & 0xfc);
- pci_write_config_byte(pci, PCIR_DSXG_CTRL, cmd | 0x03);
- pci_write_config_byte(pci, PCIR_DSXG_CTRL, cmd & 0xfc);
- pci_write_config_word(pci, PCIR_DSXG_PWRCTRL1, 0);
- pci_write_config_word(pci, PCIR_DSXG_PWRCTRL2, 0);
-#if 0
- }
-#endif
-}
-
-static void snd_ymfpci_enable_dsp(struct snd_ymfpci *chip)
-{
- snd_ymfpci_writel(chip, YDSXGR_CONFIG, 0x00000001);
-}
-
-static void snd_ymfpci_disable_dsp(struct snd_ymfpci *chip)
-{
- u32 val;
- int timeout = 1000;
-
- val = snd_ymfpci_readl(chip, YDSXGR_CONFIG);
- if (val)
- snd_ymfpci_writel(chip, YDSXGR_CONFIG, 0x00000000);
- while (timeout-- > 0) {
- val = snd_ymfpci_readl(chip, YDSXGR_STATUS);
- if ((val & 0x00000002) == 0)
- break;
- }
-}
-
-static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip)
-{
- int err, is_1e;
- const char *name;
-
- err = request_firmware(&chip->dsp_microcode, "yamaha/ds1_dsp.fw",
- &chip->pci->dev);
- if (err >= 0) {
- if (chip->dsp_microcode->size != YDSXG_DSPLENGTH) {
- snd_printk(KERN_ERR "DSP microcode has wrong size\n");
- err = -EINVAL;
- }
- }
- if (err < 0)
- return err;
- is_1e = chip->device_id == PCI_DEVICE_ID_YAMAHA_724F ||
- chip->device_id == PCI_DEVICE_ID_YAMAHA_740C ||
- chip->device_id == PCI_DEVICE_ID_YAMAHA_744 ||
- chip->device_id == PCI_DEVICE_ID_YAMAHA_754;
- name = is_1e ? "yamaha/ds1e_ctrl.fw" : "yamaha/ds1_ctrl.fw";
- err = request_firmware(&chip->controller_microcode, name,
- &chip->pci->dev);
- if (err >= 0) {
- if (chip->controller_microcode->size != YDSXG_CTRLLENGTH) {
- snd_printk(KERN_ERR "controller microcode"
- " has wrong size\n");
- err = -EINVAL;
- }
- }
- if (err < 0)
- return err;
- return 0;
-}
-
-MODULE_FIRMWARE("yamaha/ds1_dsp.fw");
-MODULE_FIRMWARE("yamaha/ds1_ctrl.fw");
-MODULE_FIRMWARE("yamaha/ds1e_ctrl.fw");
-
-static void snd_ymfpci_download_image(struct snd_ymfpci *chip)
-{
- int i;
- u16 ctrl;
- const __le32 *inst;
-
- snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0x00000000);
- snd_ymfpci_disable_dsp(chip);
- snd_ymfpci_writel(chip, YDSXGR_MODE, 0x00010000);
- snd_ymfpci_writel(chip, YDSXGR_MODE, 0x00000000);
- snd_ymfpci_writel(chip, YDSXGR_MAPOFREC, 0x00000000);
- snd_ymfpci_writel(chip, YDSXGR_MAPOFEFFECT, 0x00000000);
- snd_ymfpci_writel(chip, YDSXGR_PLAYCTRLBASE, 0x00000000);
- snd_ymfpci_writel(chip, YDSXGR_RECCTRLBASE, 0x00000000);
- snd_ymfpci_writel(chip, YDSXGR_EFFCTRLBASE, 0x00000000);
- ctrl = snd_ymfpci_readw(chip, YDSXGR_GLOBALCTRL);
- snd_ymfpci_writew(chip, YDSXGR_GLOBALCTRL, ctrl & ~0x0007);
-
- /* setup DSP instruction code */
- inst = (const __le32 *)chip->dsp_microcode->data;
- for (i = 0; i < YDSXG_DSPLENGTH / 4; i++)
- snd_ymfpci_writel(chip, YDSXGR_DSPINSTRAM + (i << 2),
- le32_to_cpu(inst[i]));
-
- /* setup control instruction code */
- inst = (const __le32 *)chip->controller_microcode->data;
- for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++)
- snd_ymfpci_writel(chip, YDSXGR_CTRLINSTRAM + (i << 2),
- le32_to_cpu(inst[i]));
-
- snd_ymfpci_enable_dsp(chip);
-}
-
-static int __devinit snd_ymfpci_memalloc(struct snd_ymfpci *chip)
-{
- long size, playback_ctrl_size;
- int voice, bank, reg;
- u8 *ptr;
- dma_addr_t ptr_addr;
-
- playback_ctrl_size = 4 + 4 * YDSXG_PLAYBACK_VOICES;
- chip->bank_size_playback = snd_ymfpci_readl(chip, YDSXGR_PLAYCTRLSIZE) << 2;
- chip->bank_size_capture = snd_ymfpci_readl(chip, YDSXGR_RECCTRLSIZE) << 2;
- chip->bank_size_effect = snd_ymfpci_readl(chip, YDSXGR_EFFCTRLSIZE) << 2;
- chip->work_size = YDSXG_DEFAULT_WORK_SIZE;
-
- size = ALIGN(playback_ctrl_size, 0x100) +
- ALIGN(chip->bank_size_playback * 2 * YDSXG_PLAYBACK_VOICES, 0x100) +
- ALIGN(chip->bank_size_capture * 2 * YDSXG_CAPTURE_VOICES, 0x100) +
- ALIGN(chip->bank_size_effect * 2 * YDSXG_EFFECT_VOICES, 0x100) +
- chip->work_size;
- /* work_ptr must be aligned to 256 bytes, but it's already
- covered with the kernel page allocation mechanism */
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
- size, &chip->work_ptr) < 0)
- return -ENOMEM;
- ptr = chip->work_ptr.area;
- ptr_addr = chip->work_ptr.addr;
- memset(ptr, 0, size); /* for sure */
-
- chip->bank_base_playback = ptr;
- chip->bank_base_playback_addr = ptr_addr;
- chip->ctrl_playback = (u32 *)ptr;
- chip->ctrl_playback[0] = cpu_to_le32(YDSXG_PLAYBACK_VOICES);
- ptr += ALIGN(playback_ctrl_size, 0x100);
- ptr_addr += ALIGN(playback_ctrl_size, 0x100);
- for (voice = 0; voice < YDSXG_PLAYBACK_VOICES; voice++) {
- chip->voices[voice].number = voice;
- chip->voices[voice].bank = (struct snd_ymfpci_playback_bank *)ptr;
- chip->voices[voice].bank_addr = ptr_addr;
- for (bank = 0; bank < 2; bank++) {
- chip->bank_playback[voice][bank] = (struct snd_ymfpci_playback_bank *)ptr;
- ptr += chip->bank_size_playback;
- ptr_addr += chip->bank_size_playback;
- }
- }
- ptr = (char *)ALIGN((unsigned long)ptr, 0x100);
- ptr_addr = ALIGN(ptr_addr, 0x100);
- chip->bank_base_capture = ptr;
- chip->bank_base_capture_addr = ptr_addr;
- for (voice = 0; voice < YDSXG_CAPTURE_VOICES; voice++)
- for (bank = 0; bank < 2; bank++) {
- chip->bank_capture[voice][bank] = (struct snd_ymfpci_capture_bank *)ptr;
- ptr += chip->bank_size_capture;
- ptr_addr += chip->bank_size_capture;
- }
- ptr = (char *)ALIGN((unsigned long)ptr, 0x100);
- ptr_addr = ALIGN(ptr_addr, 0x100);
- chip->bank_base_effect = ptr;
- chip->bank_base_effect_addr = ptr_addr;
- for (voice = 0; voice < YDSXG_EFFECT_VOICES; voice++)
- for (bank = 0; bank < 2; bank++) {
- chip->bank_effect[voice][bank] = (struct snd_ymfpci_effect_bank *)ptr;
- ptr += chip->bank_size_effect;
- ptr_addr += chip->bank_size_effect;
- }
- ptr = (char *)ALIGN((unsigned long)ptr, 0x100);
- ptr_addr = ALIGN(ptr_addr, 0x100);
- chip->work_base = ptr;
- chip->work_base_addr = ptr_addr;
-
- snd_BUG_ON(ptr + chip->work_size !=
- chip->work_ptr.area + chip->work_ptr.bytes);
-
- snd_ymfpci_writel(chip, YDSXGR_PLAYCTRLBASE, chip->bank_base_playback_addr);
- snd_ymfpci_writel(chip, YDSXGR_RECCTRLBASE, chip->bank_base_capture_addr);
- snd_ymfpci_writel(chip, YDSXGR_EFFCTRLBASE, chip->bank_base_effect_addr);
- snd_ymfpci_writel(chip, YDSXGR_WORKBASE, chip->work_base_addr);
- snd_ymfpci_writel(chip, YDSXGR_WORKSIZE, chip->work_size >> 2);
-
- /* S/PDIF output initialization */
- chip->spdif_bits = chip->spdif_pcm_bits = SNDRV_PCM_DEFAULT_CON_SPDIF & 0xffff;
- snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTCTRL, 0);
- snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_bits);
-
- /* S/PDIF input initialization */
- snd_ymfpci_writew(chip, YDSXGR_SPDIFINCTRL, 0);
-
- /* digital mixer setup */
- for (reg = 0x80; reg < 0xc0; reg += 4)
- snd_ymfpci_writel(chip, reg, 0);
- snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0x3fff3fff);
- snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0x3fff3fff);
- snd_ymfpci_writel(chip, YDSXGR_ZVOUTVOL, 0x3fff3fff);
- snd_ymfpci_writel(chip, YDSXGR_SPDIFOUTVOL, 0x3fff3fff);
- snd_ymfpci_writel(chip, YDSXGR_NATIVEADCINVOL, 0x3fff3fff);
- snd_ymfpci_writel(chip, YDSXGR_NATIVEDACINVOL, 0x3fff3fff);
- snd_ymfpci_writel(chip, YDSXGR_PRIADCLOOPVOL, 0x3fff3fff);
- snd_ymfpci_writel(chip, YDSXGR_LEGACYOUTVOL, 0x3fff3fff);
-
- return 0;
-}
-
-static int snd_ymfpci_free(struct snd_ymfpci *chip)
-{
- u16 ctrl;
-
- if (snd_BUG_ON(!chip))
- return -EINVAL;
-
- if (chip->res_reg_area) { /* don't touch busy hardware */
- snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
- snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0);
- snd_ymfpci_writel(chip, YDSXGR_LEGACYOUTVOL, 0);
- snd_ymfpci_writel(chip, YDSXGR_STATUS, ~0);
- snd_ymfpci_disable_dsp(chip);
- snd_ymfpci_writel(chip, YDSXGR_PLAYCTRLBASE, 0);
- snd_ymfpci_writel(chip, YDSXGR_RECCTRLBASE, 0);
- snd_ymfpci_writel(chip, YDSXGR_EFFCTRLBASE, 0);
- snd_ymfpci_writel(chip, YDSXGR_WORKBASE, 0);
- snd_ymfpci_writel(chip, YDSXGR_WORKSIZE, 0);
- ctrl = snd_ymfpci_readw(chip, YDSXGR_GLOBALCTRL);
- snd_ymfpci_writew(chip, YDSXGR_GLOBALCTRL, ctrl & ~0x0007);
- }
-
- snd_ymfpci_ac3_done(chip);
-
- /* Set PCI device to D3 state */
-#if 0
- /* FIXME: temporarily disabled, otherwise we cannot fire up
- * the chip again unless reboot. ACPI bug?
- */
- pci_set_power_state(chip->pci, 3);
-#endif
-
-#ifdef CONFIG_PM
- vfree(chip->saved_regs);
-#endif
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
- release_and_free_resource(chip->mpu_res);
- release_and_free_resource(chip->fm_res);
- snd_ymfpci_free_gameport(chip);
- if (chip->reg_area_virt)
- iounmap(chip->reg_area_virt);
- if (chip->work_ptr.area)
- snd_dma_free_pages(&chip->work_ptr);
-
- release_and_free_resource(chip->res_reg_area);
-
- pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl);
-
- pci_disable_device(chip->pci);
- release_firmware(chip->dsp_microcode);
- release_firmware(chip->controller_microcode);
- kfree(chip);
- return 0;
-}
-
-static int snd_ymfpci_dev_free(struct snd_device *device)
-{
- struct snd_ymfpci *chip = device->device_data;
- return snd_ymfpci_free(chip);
-}
-
-#ifdef CONFIG_PM
-static int saved_regs_index[] = {
- /* spdif */
- YDSXGR_SPDIFOUTCTRL,
- YDSXGR_SPDIFOUTSTATUS,
- YDSXGR_SPDIFINCTRL,
- /* volumes */
- YDSXGR_PRIADCLOOPVOL,
- YDSXGR_NATIVEDACINVOL,
- YDSXGR_NATIVEDACOUTVOL,
- YDSXGR_BUF441OUTVOL,
- YDSXGR_NATIVEADCINVOL,
- YDSXGR_SPDIFLOOPVOL,
- YDSXGR_SPDIFOUTVOL,
- YDSXGR_ZVOUTVOL,
- YDSXGR_LEGACYOUTVOL,
- /* address bases */
- YDSXGR_PLAYCTRLBASE,
- YDSXGR_RECCTRLBASE,
- YDSXGR_EFFCTRLBASE,
- YDSXGR_WORKBASE,
- /* capture set up */
- YDSXGR_MAPOFREC,
- YDSXGR_RECFORMAT,
- YDSXGR_RECSLOTSR,
- YDSXGR_ADCFORMAT,
- YDSXGR_ADCSLOTSR,
-};
-#define YDSXGR_NUM_SAVED_REGS ARRAY_SIZE(saved_regs_index)
-
-int snd_ymfpci_suspend(struct pci_dev *pci, pm_message_t state)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_ymfpci *chip = card->private_data;
- unsigned int i;
-
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(chip->pcm);
- snd_pcm_suspend_all(chip->pcm2);
- snd_pcm_suspend_all(chip->pcm_spdif);
- snd_pcm_suspend_all(chip->pcm_4ch);
- snd_ac97_suspend(chip->ac97);
- for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++)
- chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]);
- chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE);
- pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY,
- &chip->saved_dsxg_legacy);
- pci_read_config_word(chip->pci, PCIR_DSXG_ELEGACY,
- &chip->saved_dsxg_elegacy);
- snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
- snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0);
- snd_ymfpci_disable_dsp(chip);
- pci_disable_device(pci);
- pci_save_state(pci);
- pci_set_power_state(pci, pci_choose_state(pci, state));
- return 0;
-}
-
-int snd_ymfpci_resume(struct pci_dev *pci)
-{
- struct snd_card *card = pci_get_drvdata(pci);
- struct snd_ymfpci *chip = card->private_data;
- unsigned int i;
-
- pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
- if (pci_enable_device(pci) < 0) {
- printk(KERN_ERR "ymfpci: pci_enable_device failed, "
- "disabling device\n");
- snd_card_disconnect(card);
- return -EIO;
- }
- pci_set_master(pci);
- snd_ymfpci_aclink_reset(pci);
- snd_ymfpci_codec_ready(chip, 0);
- snd_ymfpci_download_image(chip);
- udelay(100);
-
- for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++)
- snd_ymfpci_writel(chip, saved_regs_index[i], chip->saved_regs[i]);
-
- snd_ac97_resume(chip->ac97);
-
- pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY,
- chip->saved_dsxg_legacy);
- pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY,
- chip->saved_dsxg_elegacy);
-
- /* start hw again */
- if (chip->start_count > 0) {
- spin_lock_irq(&chip->reg_lock);
- snd_ymfpci_writel(chip, YDSXGR_MODE, chip->saved_ydsxgr_mode);
- chip->active_bank = snd_ymfpci_readl(chip, YDSXGR_CTRLSELECT);
- spin_unlock_irq(&chip->reg_lock);
- }
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif /* CONFIG_PM */
-
-int __devinit snd_ymfpci_create(struct snd_card *card,
- struct pci_dev * pci,
- unsigned short old_legacy_ctrl,
- struct snd_ymfpci ** rchip)
-{
- struct snd_ymfpci *chip;
- int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_ymfpci_dev_free,
- };
-
- *rchip = NULL;
-
- /* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
- return err;
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
- chip->old_legacy_ctrl = old_legacy_ctrl;
- spin_lock_init(&chip->reg_lock);
- spin_lock_init(&chip->voice_lock);
- init_waitqueue_head(&chip->interrupt_sleep);
- atomic_set(&chip->interrupt_sleep_count, 0);
- chip->card = card;
- chip->pci = pci;
- chip->irq = -1;
- chip->device_id = pci->device;
- chip->rev = pci->revision;
- chip->reg_area_phys = pci_resource_start(pci, 0);
- chip->reg_area_virt = ioremap_nocache(chip->reg_area_phys, 0x8000);
- pci_set_master(pci);
- chip->src441_used = -1;
-
- if ((chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI")) == NULL) {
- snd_printk(KERN_ERR "unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1);
- snd_ymfpci_free(chip);
- return -EBUSY;
- }
- if (request_irq(pci->irq, snd_ymfpci_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_ymfpci_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
-
- snd_ymfpci_aclink_reset(pci);
- if (snd_ymfpci_codec_ready(chip, 0) < 0) {
- snd_ymfpci_free(chip);
- return -EIO;
- }
-
- err = snd_ymfpci_request_firmware(chip);
- if (err < 0) {
- snd_printk(KERN_ERR "firmware request failed: %d\n", err);
- snd_ymfpci_free(chip);
- return err;
- }
- snd_ymfpci_download_image(chip);
-
- udelay(100); /* seems we need a delay after downloading image.. */
-
- if (snd_ymfpci_memalloc(chip) < 0) {
- snd_ymfpci_free(chip);
- return -EIO;
- }
-
- if ((err = snd_ymfpci_ac3_init(chip)) < 0) {
- snd_ymfpci_free(chip);
- return err;
- }
-
-#ifdef CONFIG_PM
- chip->saved_regs = vmalloc(YDSXGR_NUM_SAVED_REGS * sizeof(u32));
- if (chip->saved_regs == NULL) {
- snd_ymfpci_free(chip);
- return -ENOMEM;
- }
-#endif
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_ymfpci_free(chip);
- return err;
- }
-
- snd_ymfpci_proc_init(card, chip);
-
- snd_card_set_dev(card, &pci->dev);
-
- *rchip = chip;
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pcmcia/Kconfig b/ANDROID_3.4.5/sound/pcmcia/Kconfig
deleted file mode 100644
index 7fbb190a..00000000
--- a/ANDROID_3.4.5/sound/pcmcia/Kconfig
+++ /dev/null
@@ -1,33 +0,0 @@
-# ALSA PCMCIA drivers
-
-menuconfig SND_PCMCIA
- bool "PCMCIA sound devices"
- depends on PCMCIA
- default y
- help
- Support for sound devices connected via the PCMCIA bus.
-
-if SND_PCMCIA && PCMCIA
-
-config SND_VXPOCKET
- tristate "Digigram VXpocket"
- select SND_VX_LIB
- help
- Say Y here to include support for Digigram VXpocket and
- VXpocket 440 soundcards.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-vxpocket.
-
-config SND_PDAUDIOCF
- tristate "Sound Core PDAudioCF"
- select SND_PCM
- help
- Say Y here to include support for Sound Core PDAudioCF
- soundcards.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-pdaudiocf.
-
-endif # SND_PCMCIA
-
diff --git a/ANDROID_3.4.5/sound/pcmcia/Makefile b/ANDROID_3.4.5/sound/pcmcia/Makefile
deleted file mode 100644
index beef2e33..00000000
--- a/ANDROID_3.4.5/sound/pcmcia/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-obj-$(CONFIG_SND) += vx/ pdaudiocf/
diff --git a/ANDROID_3.4.5/sound/pcmcia/pdaudiocf/Makefile b/ANDROID_3.4.5/sound/pcmcia/pdaudiocf/Makefile
deleted file mode 100644
index e892d729..00000000
--- a/ANDROID_3.4.5/sound/pcmcia/pdaudiocf/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2004 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-pdaudiocf-objs := pdaudiocf.o pdaudiocf_core.o pdaudiocf_irq.o pdaudiocf_pcm.o
-
-obj-$(CONFIG_SND_PDAUDIOCF) += snd-pdaudiocf.o
diff --git a/ANDROID_3.4.5/sound/pcmcia/pdaudiocf/pdaudiocf.c b/ANDROID_3.4.5/sound/pcmcia/pdaudiocf/pdaudiocf.c
deleted file mode 100644
index 830839a8..00000000
--- a/ANDROID_3.4.5/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Driver for Sound Core PDAudioCF soundcard
- *
- * Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <sound/core.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <pcmcia/ciscode.h>
-#include <pcmcia/cisreg.h>
-#include "pdaudiocf.h"
-#include <sound/initval.h>
-#include <linux/init.h>
-
-/*
- */
-
-#define CARD_NAME "PDAudio-CF"
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
-MODULE_DESCRIPTION("Sound Core " CARD_NAME);
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Sound Core," CARD_NAME "}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
-
-/*
- */
-
-static struct snd_card *card_list[SNDRV_CARDS];
-
-/*
- * prototypes
- */
-static int pdacf_config(struct pcmcia_device *link);
-static void snd_pdacf_detach(struct pcmcia_device *p_dev);
-
-static void pdacf_release(struct pcmcia_device *link)
-{
- pcmcia_disable_device(link);
-}
-
-/*
- * destructor
- */
-static int snd_pdacf_free(struct snd_pdacf *pdacf)
-{
- struct pcmcia_device *link = pdacf->p_dev;
-
- pdacf_release(link);
-
- card_list[pdacf->index] = NULL;
- pdacf->card = NULL;
-
- kfree(pdacf);
- return 0;
-}
-
-static int snd_pdacf_dev_free(struct snd_device *device)
-{
- struct snd_pdacf *chip = device->device_data;
- return snd_pdacf_free(chip);
-}
-
-/*
- * snd_pdacf_attach - attach callback for cs
- */
-static int snd_pdacf_probe(struct pcmcia_device *link)
-{
- int i, err;
- struct snd_pdacf *pdacf;
- struct snd_card *card;
- static struct snd_device_ops ops = {
- .dev_free = snd_pdacf_dev_free,
- };
-
- snd_printdd(KERN_DEBUG "pdacf_attach called\n");
- /* find an empty slot from the card list */
- for (i = 0; i < SNDRV_CARDS; i++) {
- if (! card_list[i])
- break;
- }
- if (i >= SNDRV_CARDS) {
- snd_printk(KERN_ERR "pdacf: too many cards found\n");
- return -EINVAL;
- }
- if (! enable[i])
- return -ENODEV; /* disabled explicitly */
-
- /* ok, create a card instance */
- err = snd_card_create(index[i], id[i], THIS_MODULE, 0, &card);
- if (err < 0) {
- snd_printk(KERN_ERR "pdacf: cannot create a card instance\n");
- return err;
- }
-
- pdacf = snd_pdacf_create(card);
- if (!pdacf) {
- snd_card_free(card);
- return -ENOMEM;
- }
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, pdacf, &ops);
- if (err < 0) {
- kfree(pdacf);
- snd_card_free(card);
- return err;
- }
-
- snd_card_set_dev(card, &link->dev);
-
- pdacf->index = i;
- card_list[i] = card;
-
- pdacf->p_dev = link;
- link->priv = pdacf;
-
- link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
- link->resource[0]->end = 16;
-
- link->config_flags = CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ;
- link->config_index = 1;
- link->config_regs = PRESENT_OPTION;
-
- return pdacf_config(link);
-}
-
-
-/**
- * snd_pdacf_assign_resources - initialize the hardware and card instance.
- * @port: i/o port for the card
- * @irq: irq number for the card
- *
- * this function assigns the specified port and irq, boot the card,
- * create pcm and control instances, and initialize the rest hardware.
- *
- * returns 0 if successful, or a negative error code.
- */
-static int snd_pdacf_assign_resources(struct snd_pdacf *pdacf, int port, int irq)
-{
- int err;
- struct snd_card *card = pdacf->card;
-
- snd_printdd(KERN_DEBUG "pdacf assign resources: port = 0x%x, irq = %d\n", port, irq);
- pdacf->port = port;
- pdacf->irq = irq;
- pdacf->chip_status |= PDAUDIOCF_STAT_IS_CONFIGURED;
-
- err = snd_pdacf_ak4117_create(pdacf);
- if (err < 0)
- return err;
-
- strcpy(card->driver, "PDAudio-CF");
- sprintf(card->shortname, "Core Sound %s", card->driver);
- sprintf(card->longname, "%s at 0x%x, irq %i",
- card->shortname, port, irq);
-
- err = snd_pdacf_pcm_new(pdacf);
- if (err < 0)
- return err;
-
- if ((err = snd_card_register(card)) < 0)
- return err;
-
- return 0;
-}
-
-
-/*
- * snd_pdacf_detach - detach callback for cs
- */
-static void snd_pdacf_detach(struct pcmcia_device *link)
-{
- struct snd_pdacf *chip = link->priv;
-
- snd_printdd(KERN_DEBUG "pdacf_detach called\n");
-
- if (chip->chip_status & PDAUDIOCF_STAT_IS_CONFIGURED)
- snd_pdacf_powerdown(chip);
- chip->chip_status |= PDAUDIOCF_STAT_IS_STALE; /* to be sure */
- snd_card_disconnect(chip->card);
- snd_card_free_when_closed(chip->card);
-}
-
-/*
- * configuration callback
- */
-
-static int pdacf_config(struct pcmcia_device *link)
-{
- struct snd_pdacf *pdacf = link->priv;
- int ret;
-
- snd_printdd(KERN_DEBUG "pdacf_config called\n");
- link->config_index = 0x5;
- link->config_flags |= CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ;
-
- ret = pcmcia_request_io(link);
- if (ret)
- goto failed;
-
- ret = pcmcia_request_irq(link, pdacf_interrupt);
- if (ret)
- goto failed;
-
- ret = pcmcia_enable_device(link);
- if (ret)
- goto failed;
-
- if (snd_pdacf_assign_resources(pdacf, link->resource[0]->start,
- link->irq) < 0)
- goto failed;
-
- return 0;
-
-failed:
- pcmcia_disable_device(link);
- return -ENODEV;
-}
-
-#ifdef CONFIG_PM
-
-static int pdacf_suspend(struct pcmcia_device *link)
-{
- struct snd_pdacf *chip = link->priv;
-
- snd_printdd(KERN_DEBUG "SUSPEND\n");
- if (chip) {
- snd_printdd(KERN_DEBUG "snd_pdacf_suspend calling\n");
- snd_pdacf_suspend(chip, PMSG_SUSPEND);
- }
-
- return 0;
-}
-
-static int pdacf_resume(struct pcmcia_device *link)
-{
- struct snd_pdacf *chip = link->priv;
-
- snd_printdd(KERN_DEBUG "RESUME\n");
- if (pcmcia_dev_present(link)) {
- if (chip) {
- snd_printdd(KERN_DEBUG "calling snd_pdacf_resume\n");
- snd_pdacf_resume(chip);
- }
- }
- snd_printdd(KERN_DEBUG "resume done!\n");
-
- return 0;
-}
-
-#endif
-
-/*
- * Module entry points
- */
-static const struct pcmcia_device_id snd_pdacf_ids[] = {
- /* this is too general PCMCIA_DEVICE_MANF_CARD(0x015d, 0x4c45), */
- PCMCIA_DEVICE_PROD_ID12("Core Sound","PDAudio-CF",0x396d19d2,0x71717b49),
- PCMCIA_DEVICE_NULL
-};
-MODULE_DEVICE_TABLE(pcmcia, snd_pdacf_ids);
-
-static struct pcmcia_driver pdacf_cs_driver = {
- .owner = THIS_MODULE,
- .name = "snd-pdaudiocf",
- .probe = snd_pdacf_probe,
- .remove = snd_pdacf_detach,
- .id_table = snd_pdacf_ids,
-#ifdef CONFIG_PM
- .suspend = pdacf_suspend,
- .resume = pdacf_resume,
-#endif
-
-};
-
-static int __init init_pdacf(void)
-{
- return pcmcia_register_driver(&pdacf_cs_driver);
-}
-
-static void __exit exit_pdacf(void)
-{
- pcmcia_unregister_driver(&pdacf_cs_driver);
-}
-
-module_init(init_pdacf);
-module_exit(exit_pdacf);
diff --git a/ANDROID_3.4.5/sound/pcmcia/pdaudiocf/pdaudiocf.h b/ANDROID_3.4.5/sound/pcmcia/pdaudiocf/pdaudiocf.h
deleted file mode 100644
index 6ce9ad70..00000000
--- a/ANDROID_3.4.5/sound/pcmcia/pdaudiocf/pdaudiocf.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Driver for Sound Cors PDAudioCF soundcard
- *
- * Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __PDAUDIOCF_H
-#define __PDAUDIOCF_H
-
-#include <sound/pcm.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ds.h>
-
-#include <sound/ak4117.h>
-
-/* PDAUDIOCF registers */
-#define PDAUDIOCF_REG_MD 0x00 /* music data, R/O */
-#define PDAUDIOCF_REG_WDP 0x02 /* write data pointer / 2, R/O */
-#define PDAUDIOCF_REG_RDP 0x04 /* read data pointer / 2, R/O */
-#define PDAUDIOCF_REG_TCR 0x06 /* test control register W/O */
-#define PDAUDIOCF_REG_SCR 0x08 /* status and control, R/W (see bit description) */
-#define PDAUDIOCF_REG_ISR 0x0a /* interrupt status, R/O */
-#define PDAUDIOCF_REG_IER 0x0c /* interrupt enable, R/W */
-#define PDAUDIOCF_REG_AK_IFR 0x0e /* AK interface register, R/W */
-
-/* PDAUDIOCF_REG_TCR */
-#define PDAUDIOCF_ELIMAKMBIT (1<<0) /* simulate AKM music data */
-#define PDAUDIOCF_TESTDATASEL (1<<1) /* test data selection, 0 = 0x55, 1 = pseudo-random */
-
-/* PDAUDIOCF_REG_SCR */
-#define PDAUDIOCF_AK_SBP (1<<0) /* serial port busy flag */
-#define PDAUDIOCF_RST (1<<2) /* FPGA, AKM + SRAM buffer reset */
-#define PDAUDIOCF_PDN (1<<3) /* power down bit */
-#define PDAUDIOCF_CLKDIV0 (1<<4) /* choose 24.576Mhz clock divided by 1,2,3 or 4 */
-#define PDAUDIOCF_CLKDIV1 (1<<5)
-#define PDAUDIOCF_RECORD (1<<6) /* start capturing to SRAM */
-#define PDAUDIOCF_AK_SDD (1<<7) /* music data detected */
-#define PDAUDIOCF_RED_LED_OFF (1<<8) /* red LED off override */
-#define PDAUDIOCF_BLUE_LED_OFF (1<<9) /* blue LED off override */
-#define PDAUDIOCF_DATAFMT0 (1<<10) /* data format bits: 00 = 16-bit, 01 = 18-bit */
-#define PDAUDIOCF_DATAFMT1 (1<<11) /* 10 = 20-bit, 11 = 24-bit, all right justified */
-#define PDAUDIOCF_FPGAREV(x) ((x>>12)&0x0f) /* FPGA revision */
-
-/* PDAUDIOCF_REG_ISR */
-#define PDAUDIOCF_IRQLVL (1<<0) /* Buffer level IRQ */
-#define PDAUDIOCF_IRQOVR (1<<1) /* Overrun IRQ */
-#define PDAUDIOCF_IRQAKM (1<<2) /* AKM IRQ */
-
-/* PDAUDIOCF_REG_IER */
-#define PDAUDIOCF_IRQLVLEN0 (1<<0) /* fill threshold levels; 00 = none, 01 = 1/8th of buffer */
-#define PDAUDIOCF_IRQLVLEN1 (1<<1) /* 10 = 1/4th of buffer, 11 = 1/2th of buffer */
-#define PDAUDIOCF_IRQOVREN (1<<2) /* enable overrun IRQ */
-#define PDAUDIOCF_IRQAKMEN (1<<3) /* enable AKM IRQ */
-#define PDAUDIOCF_BLUEDUTY0 (1<<8) /* blue LED duty cycle; 00 = 100%, 01 = 50% */
-#define PDAUDIOCF_BLUEDUTY1 (1<<9) /* 02 = 25%, 11 = 12% */
-#define PDAUDIOCF_REDDUTY0 (1<<10) /* red LED duty cycle; 00 = 100%, 01 = 50% */
-#define PDAUDIOCF_REDDUTY1 (1<<11) /* 02 = 25%, 11 = 12% */
-#define PDAUDIOCF_BLUESDD (1<<12) /* blue LED against SDD bit */
-#define PDAUDIOCF_BLUEMODULATE (1<<13) /* save power when 100% duty cycle selected */
-#define PDAUDIOCF_REDMODULATE (1<<14) /* save power when 100% duty cycle selected */
-#define PDAUDIOCF_HALFRATE (1<<15) /* slow both LED blinks by half (also spdif detect rate) */
-
-/* chip status */
-#define PDAUDIOCF_STAT_IS_STALE (1<<0)
-#define PDAUDIOCF_STAT_IS_CONFIGURED (1<<1)
-#define PDAUDIOCF_STAT_IS_SUSPENDED (1<<2)
-
-struct snd_pdacf {
- struct snd_card *card;
- int index;
-
- unsigned long port;
- int irq;
-
- spinlock_t reg_lock;
- unsigned short regmap[8];
- unsigned short suspend_reg_scr;
- struct tasklet_struct tq;
-
- spinlock_t ak4117_lock;
- struct ak4117 *ak4117;
-
- unsigned int chip_status;
-
- struct snd_pcm *pcm;
- struct snd_pcm_substream *pcm_substream;
- unsigned int pcm_running: 1;
- unsigned int pcm_channels;
- unsigned int pcm_swab;
- unsigned int pcm_little;
- unsigned int pcm_frame;
- unsigned int pcm_sample;
- unsigned int pcm_xor;
- unsigned int pcm_size;
- unsigned int pcm_period;
- unsigned int pcm_tdone;
- unsigned int pcm_hwptr;
- void *pcm_area;
-
- /* pcmcia stuff */
- struct pcmcia_device *p_dev;
-};
-
-static inline void pdacf_reg_write(struct snd_pdacf *chip, unsigned char reg, unsigned short val)
-{
- outw(chip->regmap[reg>>1] = val, chip->port + reg);
-}
-
-static inline unsigned short pdacf_reg_read(struct snd_pdacf *chip, unsigned char reg)
-{
- return inw(chip->port + reg);
-}
-
-struct snd_pdacf *snd_pdacf_create(struct snd_card *card);
-int snd_pdacf_ak4117_create(struct snd_pdacf *pdacf);
-void snd_pdacf_powerdown(struct snd_pdacf *chip);
-#ifdef CONFIG_PM
-int snd_pdacf_suspend(struct snd_pdacf *chip, pm_message_t state);
-int snd_pdacf_resume(struct snd_pdacf *chip);
-#endif
-int snd_pdacf_pcm_new(struct snd_pdacf *chip);
-irqreturn_t pdacf_interrupt(int irq, void *dev);
-void pdacf_tasklet(unsigned long private_data);
-void pdacf_reinit(struct snd_pdacf *chip, int resume);
-
-#endif /* __PDAUDIOCF_H */
diff --git a/ANDROID_3.4.5/sound/pcmcia/pdaudiocf/pdaudiocf_core.c b/ANDROID_3.4.5/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
deleted file mode 100644
index 9dce0bde..00000000
--- a/ANDROID_3.4.5/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Driver for Sound Core PDAudioCF soundcard
- *
- * Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include "pdaudiocf.h"
-#include <sound/initval.h>
-
-/*
- *
- */
-static unsigned char pdacf_ak4117_read(void *private_data, unsigned char reg)
-{
- struct snd_pdacf *chip = private_data;
- unsigned long timeout;
- unsigned long flags;
- unsigned char res;
-
- spin_lock_irqsave(&chip->ak4117_lock, flags);
- timeout = 1000;
- while (pdacf_reg_read(chip, PDAUDIOCF_REG_SCR) & PDAUDIOCF_AK_SBP) {
- udelay(5);
- if (--timeout == 0) {
- spin_unlock_irqrestore(&chip->ak4117_lock, flags);
- snd_printk(KERN_ERR "AK4117 ready timeout (read)\n");
- return 0;
- }
- }
- pdacf_reg_write(chip, PDAUDIOCF_REG_AK_IFR, (u16)reg << 8);
- timeout = 1000;
- while (pdacf_reg_read(chip, PDAUDIOCF_REG_SCR) & PDAUDIOCF_AK_SBP) {
- udelay(5);
- if (--timeout == 0) {
- spin_unlock_irqrestore(&chip->ak4117_lock, flags);
- snd_printk(KERN_ERR "AK4117 read timeout (read2)\n");
- return 0;
- }
- }
- res = (unsigned char)pdacf_reg_read(chip, PDAUDIOCF_REG_AK_IFR);
- spin_unlock_irqrestore(&chip->ak4117_lock, flags);
- return res;
-}
-
-static void pdacf_ak4117_write(void *private_data, unsigned char reg, unsigned char val)
-{
- struct snd_pdacf *chip = private_data;
- unsigned long timeout;
- unsigned long flags;
-
- spin_lock_irqsave(&chip->ak4117_lock, flags);
- timeout = 1000;
- while (inw(chip->port + PDAUDIOCF_REG_SCR) & PDAUDIOCF_AK_SBP) {
- udelay(5);
- if (--timeout == 0) {
- spin_unlock_irqrestore(&chip->ak4117_lock, flags);
- snd_printk(KERN_ERR "AK4117 ready timeout (write)\n");
- return;
- }
- }
- outw((u16)reg << 8 | val | (1<<13), chip->port + PDAUDIOCF_REG_AK_IFR);
- spin_unlock_irqrestore(&chip->ak4117_lock, flags);
-}
-
-#if 0
-void pdacf_dump(struct snd_pdacf *chip)
-{
- printk(KERN_DEBUG "PDAUDIOCF DUMP (0x%lx):\n", chip->port);
- printk(KERN_DEBUG "WPD : 0x%x\n",
- inw(chip->port + PDAUDIOCF_REG_WDP));
- printk(KERN_DEBUG "RDP : 0x%x\n",
- inw(chip->port + PDAUDIOCF_REG_RDP));
- printk(KERN_DEBUG "TCR : 0x%x\n",
- inw(chip->port + PDAUDIOCF_REG_TCR));
- printk(KERN_DEBUG "SCR : 0x%x\n",
- inw(chip->port + PDAUDIOCF_REG_SCR));
- printk(KERN_DEBUG "ISR : 0x%x\n",
- inw(chip->port + PDAUDIOCF_REG_ISR));
- printk(KERN_DEBUG "IER : 0x%x\n",
- inw(chip->port + PDAUDIOCF_REG_IER));
- printk(KERN_DEBUG "AK_IFR : 0x%x\n",
- inw(chip->port + PDAUDIOCF_REG_AK_IFR));
-}
-#endif
-
-static int pdacf_reset(struct snd_pdacf *chip, int powerdown)
-{
- u16 val;
-
- val = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR);
- val |= PDAUDIOCF_PDN;
- val &= ~PDAUDIOCF_RECORD; /* for sure */
- pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, val);
- udelay(5);
- val |= PDAUDIOCF_RST;
- pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, val);
- udelay(200);
- val &= ~PDAUDIOCF_RST;
- pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, val);
- udelay(5);
- if (!powerdown) {
- val &= ~PDAUDIOCF_PDN;
- pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, val);
- udelay(200);
- }
- return 0;
-}
-
-void pdacf_reinit(struct snd_pdacf *chip, int resume)
-{
- pdacf_reset(chip, 0);
- if (resume)
- pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, chip->suspend_reg_scr);
- snd_ak4117_reinit(chip->ak4117);
- pdacf_reg_write(chip, PDAUDIOCF_REG_TCR, chip->regmap[PDAUDIOCF_REG_TCR>>1]);
- pdacf_reg_write(chip, PDAUDIOCF_REG_IER, chip->regmap[PDAUDIOCF_REG_IER>>1]);
-}
-
-static void pdacf_proc_read(struct snd_info_entry * entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_pdacf *chip = entry->private_data;
- u16 tmp;
-
- snd_iprintf(buffer, "PDAudioCF\n\n");
- tmp = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR);
- snd_iprintf(buffer, "FPGA revision : 0x%x\n", PDAUDIOCF_FPGAREV(tmp));
-
-}
-
-static void pdacf_proc_init(struct snd_pdacf *chip)
-{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(chip->card, "pdaudiocf", &entry))
- snd_info_set_text_ops(entry, chip, pdacf_proc_read);
-}
-
-struct snd_pdacf *snd_pdacf_create(struct snd_card *card)
-{
- struct snd_pdacf *chip;
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL)
- return NULL;
- chip->card = card;
- spin_lock_init(&chip->reg_lock);
- spin_lock_init(&chip->ak4117_lock);
- tasklet_init(&chip->tq, pdacf_tasklet, (unsigned long)chip);
- card->private_data = chip;
-
- pdacf_proc_init(chip);
- return chip;
-}
-
-static void snd_pdacf_ak4117_change(struct ak4117 *ak4117, unsigned char c0, unsigned char c1)
-{
- struct snd_pdacf *chip = ak4117->change_callback_private;
- unsigned long flags;
- u16 val;
-
- if (!(c0 & AK4117_UNLCK))
- return;
- spin_lock_irqsave(&chip->reg_lock, flags);
- val = chip->regmap[PDAUDIOCF_REG_SCR>>1];
- if (ak4117->rcs0 & AK4117_UNLCK)
- val |= PDAUDIOCF_BLUE_LED_OFF;
- else
- val &= ~PDAUDIOCF_BLUE_LED_OFF;
- pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, val);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-}
-
-int snd_pdacf_ak4117_create(struct snd_pdacf *chip)
-{
- int err;
- u16 val;
- /* design note: if we unmask PLL unlock, parity, valid, audio or auto bit interrupts */
- /* from AK4117 then INT1 pin from AK4117 will be high all time, because PCMCIA interrupts are */
- /* egde based and FPGA does logical OR for all interrupt sources, we cannot use these */
- /* high-rate sources */
- static unsigned char pgm[5] = {
- AK4117_XTL_24_576M | AK4117_EXCT, /* AK4117_REG_PWRDN */
- AK4117_CM_PLL_XTAL | AK4117_PKCS_128fs | AK4117_XCKS_128fs, /* AK4117_REQ_CLOCK */
- AK4117_EFH_1024LRCLK | AK4117_DIF_24R | AK4117_IPS, /* AK4117_REG_IO */
- 0xff, /* AK4117_REG_INT0_MASK */
- AK4117_MAUTO | AK4117_MAUD | AK4117_MULK | AK4117_MPAR | AK4117_MV, /* AK4117_REG_INT1_MASK */
- };
-
- err = pdacf_reset(chip, 0);
- if (err < 0)
- return err;
- err = snd_ak4117_create(chip->card, pdacf_ak4117_read, pdacf_ak4117_write, pgm, chip, &chip->ak4117);
- if (err < 0)
- return err;
-
- val = pdacf_reg_read(chip, PDAUDIOCF_REG_TCR);
-#if 1 /* normal operation */
- val &= ~(PDAUDIOCF_ELIMAKMBIT|PDAUDIOCF_TESTDATASEL);
-#else /* debug */
- val |= PDAUDIOCF_ELIMAKMBIT;
- val &= ~PDAUDIOCF_TESTDATASEL;
-#endif
- pdacf_reg_write(chip, PDAUDIOCF_REG_TCR, val);
-
- /* setup the FPGA to match AK4117 setup */
- val = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR);
- val &= ~(PDAUDIOCF_CLKDIV0 | PDAUDIOCF_CLKDIV1); /* use 24.576Mhz clock */
- val &= ~(PDAUDIOCF_RED_LED_OFF|PDAUDIOCF_BLUE_LED_OFF);
- val |= PDAUDIOCF_DATAFMT0 | PDAUDIOCF_DATAFMT1; /* 24-bit data */
- pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, val);
-
- /* setup LEDs and IRQ */
- val = pdacf_reg_read(chip, PDAUDIOCF_REG_IER);
- val &= ~(PDAUDIOCF_IRQLVLEN0 | PDAUDIOCF_IRQLVLEN1);
- val &= ~(PDAUDIOCF_BLUEDUTY0 | PDAUDIOCF_REDDUTY0 | PDAUDIOCF_REDDUTY1);
- val |= PDAUDIOCF_BLUEDUTY1 | PDAUDIOCF_HALFRATE;
- val |= PDAUDIOCF_IRQOVREN | PDAUDIOCF_IRQAKMEN;
- pdacf_reg_write(chip, PDAUDIOCF_REG_IER, val);
-
- chip->ak4117->change_callback_private = chip;
- chip->ak4117->change_callback = snd_pdacf_ak4117_change;
-
- /* update LED status */
- snd_pdacf_ak4117_change(chip->ak4117, AK4117_UNLCK, 0);
-
- return 0;
-}
-
-void snd_pdacf_powerdown(struct snd_pdacf *chip)
-{
- u16 val;
-
- val = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR);
- chip->suspend_reg_scr = val;
- val |= PDAUDIOCF_RED_LED_OFF | PDAUDIOCF_BLUE_LED_OFF;
- pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, val);
- /* disable interrupts, but use direct write to preserve old register value in chip->regmap */
- val = inw(chip->port + PDAUDIOCF_REG_IER);
- val &= ~(PDAUDIOCF_IRQOVREN|PDAUDIOCF_IRQAKMEN|PDAUDIOCF_IRQLVLEN0|PDAUDIOCF_IRQLVLEN1);
- outw(val, chip->port + PDAUDIOCF_REG_IER);
- pdacf_reset(chip, 1);
-}
-
-#ifdef CONFIG_PM
-
-int snd_pdacf_suspend(struct snd_pdacf *chip, pm_message_t state)
-{
- u16 val;
-
- snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(chip->pcm);
- /* disable interrupts, but use direct write to preserve old register value in chip->regmap */
- val = inw(chip->port + PDAUDIOCF_REG_IER);
- val &= ~(PDAUDIOCF_IRQOVREN|PDAUDIOCF_IRQAKMEN|PDAUDIOCF_IRQLVLEN0|PDAUDIOCF_IRQLVLEN1);
- outw(val, chip->port + PDAUDIOCF_REG_IER);
- chip->chip_status |= PDAUDIOCF_STAT_IS_SUSPENDED; /* ignore interrupts from now */
- snd_pdacf_powerdown(chip);
- return 0;
-}
-
-static inline int check_signal(struct snd_pdacf *chip)
-{
- return (chip->ak4117->rcs0 & AK4117_UNLCK) == 0;
-}
-
-int snd_pdacf_resume(struct snd_pdacf *chip)
-{
- int timeout = 40;
-
- pdacf_reinit(chip, 1);
- /* wait for AK4117's PLL */
- while (timeout-- > 0 &&
- (snd_ak4117_external_rate(chip->ak4117) <= 0 || !check_signal(chip)))
- mdelay(1);
- chip->chip_status &= ~PDAUDIOCF_STAT_IS_SUSPENDED;
- snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
- return 0;
-}
-#endif
diff --git a/ANDROID_3.4.5/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c b/ANDROID_3.4.5/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
deleted file mode 100644
index dcd32201..00000000
--- a/ANDROID_3.4.5/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * Driver for Sound Core PDAudioCF soundcard
- *
- * Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <sound/core.h>
-#include "pdaudiocf.h"
-#include <sound/initval.h>
-#include <asm/irq_regs.h>
-
-/*
- *
- */
-irqreturn_t pdacf_interrupt(int irq, void *dev)
-{
- struct snd_pdacf *chip = dev;
- unsigned short stat;
-
- if ((chip->chip_status & (PDAUDIOCF_STAT_IS_STALE|
- PDAUDIOCF_STAT_IS_CONFIGURED|
- PDAUDIOCF_STAT_IS_SUSPENDED)) != PDAUDIOCF_STAT_IS_CONFIGURED)
- return IRQ_HANDLED; /* IRQ_NONE here? */
-
- stat = inw(chip->port + PDAUDIOCF_REG_ISR);
- if (stat & (PDAUDIOCF_IRQLVL|PDAUDIOCF_IRQOVR)) {
- if (stat & PDAUDIOCF_IRQOVR) /* should never happen */
- snd_printk(KERN_ERR "PDAUDIOCF SRAM buffer overrun detected!\n");
- if (chip->pcm_substream)
- tasklet_schedule(&chip->tq);
- if (!(stat & PDAUDIOCF_IRQAKM))
- stat |= PDAUDIOCF_IRQAKM; /* check rate */
- }
- if (get_irq_regs() != NULL)
- snd_ak4117_check_rate_and_errors(chip->ak4117, 0);
- return IRQ_HANDLED;
-}
-
-static inline void pdacf_transfer_mono16(u16 *dst, u16 xor, unsigned int size, unsigned long rdp_port)
-{
- while (size-- > 0) {
- *dst++ = inw(rdp_port) ^ xor;
- inw(rdp_port);
- }
-}
-
-static inline void pdacf_transfer_mono32(u32 *dst, u32 xor, unsigned int size, unsigned long rdp_port)
-{
- register u16 val1, val2;
-
- while (size-- > 0) {
- val1 = inw(rdp_port);
- val2 = inw(rdp_port);
- inw(rdp_port);
- *dst++ = ((((u32)val2 & 0xff) << 24) | ((u32)val1 << 8)) ^ xor;
- }
-}
-
-static inline void pdacf_transfer_stereo16(u16 *dst, u16 xor, unsigned int size, unsigned long rdp_port)
-{
- while (size-- > 0) {
- *dst++ = inw(rdp_port) ^ xor;
- *dst++ = inw(rdp_port) ^ xor;
- }
-}
-
-static inline void pdacf_transfer_stereo32(u32 *dst, u32 xor, unsigned int size, unsigned long rdp_port)
-{
- register u16 val1, val2, val3;
-
- while (size-- > 0) {
- val1 = inw(rdp_port);
- val2 = inw(rdp_port);
- val3 = inw(rdp_port);
- *dst++ = ((((u32)val2 & 0xff) << 24) | ((u32)val1 << 8)) ^ xor;
- *dst++ = (((u32)val3 << 16) | (val2 & 0xff00)) ^ xor;
- }
-}
-
-static inline void pdacf_transfer_mono16sw(u16 *dst, u16 xor, unsigned int size, unsigned long rdp_port)
-{
- while (size-- > 0) {
- *dst++ = swab16(inw(rdp_port) ^ xor);
- inw(rdp_port);
- }
-}
-
-static inline void pdacf_transfer_mono32sw(u32 *dst, u32 xor, unsigned int size, unsigned long rdp_port)
-{
- register u16 val1, val2;
-
- while (size-- > 0) {
- val1 = inw(rdp_port);
- val2 = inw(rdp_port);
- inw(rdp_port);
- *dst++ = swab32((((val2 & 0xff) << 24) | ((u32)val1 << 8)) ^ xor);
- }
-}
-
-static inline void pdacf_transfer_stereo16sw(u16 *dst, u16 xor, unsigned int size, unsigned long rdp_port)
-{
- while (size-- > 0) {
- *dst++ = swab16(inw(rdp_port) ^ xor);
- *dst++ = swab16(inw(rdp_port) ^ xor);
- }
-}
-
-static inline void pdacf_transfer_stereo32sw(u32 *dst, u32 xor, unsigned int size, unsigned long rdp_port)
-{
- register u16 val1, val2, val3;
-
- while (size-- > 0) {
- val1 = inw(rdp_port);
- val2 = inw(rdp_port);
- val3 = inw(rdp_port);
- *dst++ = swab32((((val2 & 0xff) << 24) | ((u32)val1 << 8)) ^ xor);
- *dst++ = swab32((((u32)val3 << 16) | (val2 & 0xff00)) ^ xor);
- }
-}
-
-static inline void pdacf_transfer_mono24le(u8 *dst, u16 xor, unsigned int size, unsigned long rdp_port)
-{
- register u16 val1, val2;
- register u32 xval1;
-
- while (size-- > 0) {
- val1 = inw(rdp_port);
- val2 = inw(rdp_port);
- inw(rdp_port);
- xval1 = (((val2 & 0xff) << 8) | (val1 << 16)) ^ xor;
- *dst++ = (u8)(xval1 >> 8);
- *dst++ = (u8)(xval1 >> 16);
- *dst++ = (u8)(xval1 >> 24);
- }
-}
-
-static inline void pdacf_transfer_mono24be(u8 *dst, u16 xor, unsigned int size, unsigned long rdp_port)
-{
- register u16 val1, val2;
- register u32 xval1;
-
- while (size-- > 0) {
- val1 = inw(rdp_port);
- val2 = inw(rdp_port);
- inw(rdp_port);
- xval1 = (((val2 & 0xff) << 8) | (val1 << 16)) ^ xor;
- *dst++ = (u8)(xval1 >> 24);
- *dst++ = (u8)(xval1 >> 16);
- *dst++ = (u8)(xval1 >> 8);
- }
-}
-
-static inline void pdacf_transfer_stereo24le(u8 *dst, u32 xor, unsigned int size, unsigned long rdp_port)
-{
- register u16 val1, val2, val3;
- register u32 xval1, xval2;
-
- while (size-- > 0) {
- val1 = inw(rdp_port);
- val2 = inw(rdp_port);
- val3 = inw(rdp_port);
- xval1 = ((((u32)val2 & 0xff) << 24) | ((u32)val1 << 8)) ^ xor;
- xval2 = (((u32)val3 << 16) | (val2 & 0xff00)) ^ xor;
- *dst++ = (u8)(xval1 >> 8);
- *dst++ = (u8)(xval1 >> 16);
- *dst++ = (u8)(xval1 >> 24);
- *dst++ = (u8)(xval2 >> 8);
- *dst++ = (u8)(xval2 >> 16);
- *dst++ = (u8)(xval2 >> 24);
- }
-}
-
-static inline void pdacf_transfer_stereo24be(u8 *dst, u32 xor, unsigned int size, unsigned long rdp_port)
-{
- register u16 val1, val2, val3;
- register u32 xval1, xval2;
-
- while (size-- > 0) {
- val1 = inw(rdp_port);
- val2 = inw(rdp_port);
- val3 = inw(rdp_port);
- xval1 = ((((u32)val2 & 0xff) << 24) | ((u32)val1 << 8)) ^ xor;
- xval2 = (((u32)val3 << 16) | (val2 & 0xff00)) ^ xor;
- *dst++ = (u8)(xval1 >> 24);
- *dst++ = (u8)(xval1 >> 16);
- *dst++ = (u8)(xval1 >> 8);
- *dst++ = (u8)(xval2 >> 24);
- *dst++ = (u8)(xval2 >> 16);
- *dst++ = (u8)(xval2 >> 8);
- }
-}
-
-static void pdacf_transfer(struct snd_pdacf *chip, unsigned int size, unsigned int off)
-{
- unsigned long rdp_port = chip->port + PDAUDIOCF_REG_MD;
- unsigned int xor = chip->pcm_xor;
-
- if (chip->pcm_sample == 3) {
- if (chip->pcm_little) {
- if (chip->pcm_channels == 1) {
- pdacf_transfer_mono24le((char *)chip->pcm_area + (off * 3), xor, size, rdp_port);
- } else {
- pdacf_transfer_stereo24le((char *)chip->pcm_area + (off * 6), xor, size, rdp_port);
- }
- } else {
- if (chip->pcm_channels == 1) {
- pdacf_transfer_mono24be((char *)chip->pcm_area + (off * 3), xor, size, rdp_port);
- } else {
- pdacf_transfer_stereo24be((char *)chip->pcm_area + (off * 6), xor, size, rdp_port);
- }
- }
- return;
- }
- if (chip->pcm_swab == 0) {
- if (chip->pcm_channels == 1) {
- if (chip->pcm_frame == 2) {
- pdacf_transfer_mono16((u16 *)chip->pcm_area + off, xor, size, rdp_port);
- } else {
- pdacf_transfer_mono32((u32 *)chip->pcm_area + off, xor, size, rdp_port);
- }
- } else {
- if (chip->pcm_frame == 2) {
- pdacf_transfer_stereo16((u16 *)chip->pcm_area + (off * 2), xor, size, rdp_port);
- } else {
- pdacf_transfer_stereo32((u32 *)chip->pcm_area + (off * 2), xor, size, rdp_port);
- }
- }
- } else {
- if (chip->pcm_channels == 1) {
- if (chip->pcm_frame == 2) {
- pdacf_transfer_mono16sw((u16 *)chip->pcm_area + off, xor, size, rdp_port);
- } else {
- pdacf_transfer_mono32sw((u32 *)chip->pcm_area + off, xor, size, rdp_port);
- }
- } else {
- if (chip->pcm_frame == 2) {
- pdacf_transfer_stereo16sw((u16 *)chip->pcm_area + (off * 2), xor, size, rdp_port);
- } else {
- pdacf_transfer_stereo32sw((u32 *)chip->pcm_area + (off * 2), xor, size, rdp_port);
- }
- }
- }
-}
-
-void pdacf_tasklet(unsigned long private_data)
-{
- struct snd_pdacf *chip = (struct snd_pdacf *) private_data;
- int size, off, cont, rdp, wdp;
-
- if ((chip->chip_status & (PDAUDIOCF_STAT_IS_STALE|PDAUDIOCF_STAT_IS_CONFIGURED)) != PDAUDIOCF_STAT_IS_CONFIGURED)
- return;
-
- if (chip->pcm_substream == NULL || chip->pcm_substream->runtime == NULL || !snd_pcm_running(chip->pcm_substream))
- return;
-
- rdp = inw(chip->port + PDAUDIOCF_REG_RDP);
- wdp = inw(chip->port + PDAUDIOCF_REG_WDP);
- /* printk(KERN_DEBUG "TASKLET: rdp = %x, wdp = %x\n", rdp, wdp); */
- size = wdp - rdp;
- if (size < 0)
- size += 0x10000;
- if (size == 0)
- size = 0x10000;
- size /= chip->pcm_frame;
- if (size > 64)
- size -= 32;
-
-#if 0
- chip->pcm_hwptr += size;
- chip->pcm_hwptr %= chip->pcm_size;
- chip->pcm_tdone += size;
- if (chip->pcm_frame == 2) {
- unsigned long rdp_port = chip->port + PDAUDIOCF_REG_MD;
- while (size-- > 0) {
- inw(rdp_port);
- inw(rdp_port);
- }
- } else {
- unsigned long rdp_port = chip->port + PDAUDIOCF_REG_MD;
- while (size-- > 0) {
- inw(rdp_port);
- inw(rdp_port);
- inw(rdp_port);
- }
- }
-#else
- off = chip->pcm_hwptr + chip->pcm_tdone;
- off %= chip->pcm_size;
- chip->pcm_tdone += size;
- while (size > 0) {
- cont = chip->pcm_size - off;
- if (cont > size)
- cont = size;
- pdacf_transfer(chip, cont, off);
- off += cont;
- off %= chip->pcm_size;
- size -= cont;
- }
-#endif
- spin_lock(&chip->reg_lock);
- while (chip->pcm_tdone >= chip->pcm_period) {
- chip->pcm_hwptr += chip->pcm_period;
- chip->pcm_hwptr %= chip->pcm_size;
- chip->pcm_tdone -= chip->pcm_period;
- spin_unlock(&chip->reg_lock);
- snd_pcm_period_elapsed(chip->pcm_substream);
- spin_lock(&chip->reg_lock);
- }
- spin_unlock(&chip->reg_lock);
- /* printk(KERN_DEBUG "TASKLET: end\n"); */
-}
diff --git a/ANDROID_3.4.5/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/ANDROID_3.4.5/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
deleted file mode 100644
index 43f995a3..00000000
--- a/ANDROID_3.4.5/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Driver for Sound Core PDAudioCF soundcards
- *
- * PCM part
- *
- * Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/delay.h>
-#include <sound/core.h>
-#include <sound/asoundef.h>
-#include "pdaudiocf.h"
-
-
-/*
- * clear the SRAM contents
- */
-static int pdacf_pcm_clear_sram(struct snd_pdacf *chip)
-{
- int max_loop = 64 * 1024;
-
- while (inw(chip->port + PDAUDIOCF_REG_RDP) != inw(chip->port + PDAUDIOCF_REG_WDP)) {
- if (max_loop-- < 0)
- return -EIO;
- inw(chip->port + PDAUDIOCF_REG_MD);
- }
- return 0;
-}
-
-/*
- * pdacf_pcm_trigger - trigger callback for capture
- */
-static int pdacf_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
-{
- struct snd_pdacf *chip = snd_pcm_substream_chip(subs);
- struct snd_pcm_runtime *runtime = subs->runtime;
- int inc, ret = 0, rate;
- unsigned short mask, val, tmp;
-
- if (chip->chip_status & PDAUDIOCF_STAT_IS_STALE)
- return -EBUSY;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- chip->pcm_hwptr = 0;
- chip->pcm_tdone = 0;
- /* fall thru */
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
- mask = 0;
- val = PDAUDIOCF_RECORD;
- inc = 1;
- rate = snd_ak4117_check_rate_and_errors(chip->ak4117, AK4117_CHECK_NO_STAT|AK4117_CHECK_NO_RATE);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- mask = PDAUDIOCF_RECORD;
- val = 0;
- inc = -1;
- rate = 0;
- break;
- default:
- return -EINVAL;
- }
- spin_lock(&chip->reg_lock);
- chip->pcm_running += inc;
- tmp = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR);
- if (chip->pcm_running) {
- if ((chip->ak4117->rcs0 & AK4117_UNLCK) || runtime->rate != rate) {
- chip->pcm_running -= inc;
- ret = -EIO;
- goto __end;
- }
- }
- tmp &= ~mask;
- tmp |= val;
- pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, tmp);
- __end:
- spin_unlock(&chip->reg_lock);
- snd_ak4117_check_rate_and_errors(chip->ak4117, AK4117_CHECK_NO_RATE);
- return ret;
-}
-
-/*
- * pdacf_pcm_hw_params - hw_params callback for playback and capture
- */
-static int pdacf_pcm_hw_params(struct snd_pcm_substream *subs,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_alloc_vmalloc_32_buffer
- (subs, params_buffer_bytes(hw_params));
-}
-
-/*
- * pdacf_pcm_hw_free - hw_free callback for playback and capture
- */
-static int pdacf_pcm_hw_free(struct snd_pcm_substream *subs)
-{
- return snd_pcm_lib_free_vmalloc_buffer(subs);
-}
-
-/*
- * pdacf_pcm_prepare - prepare callback for playback and capture
- */
-static int pdacf_pcm_prepare(struct snd_pcm_substream *subs)
-{
- struct snd_pdacf *chip = snd_pcm_substream_chip(subs);
- struct snd_pcm_runtime *runtime = subs->runtime;
- u16 val, nval, aval;
-
- if (chip->chip_status & PDAUDIOCF_STAT_IS_STALE)
- return -EBUSY;
-
- chip->pcm_channels = runtime->channels;
-
- chip->pcm_little = snd_pcm_format_little_endian(runtime->format) > 0;
-#ifdef SNDRV_LITTLE_ENDIAN
- chip->pcm_swab = snd_pcm_format_big_endian(runtime->format) > 0;
-#else
- chip->pcm_swab = chip->pcm_little;
-#endif
-
- if (snd_pcm_format_unsigned(runtime->format))
- chip->pcm_xor = 0x80008000;
-
- if (pdacf_pcm_clear_sram(chip) < 0)
- return -EIO;
-
- val = nval = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR);
- nval &= ~(PDAUDIOCF_DATAFMT0|PDAUDIOCF_DATAFMT1);
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_S16_LE:
- case SNDRV_PCM_FORMAT_S16_BE:
- break;
- default: /* 24-bit */
- nval |= PDAUDIOCF_DATAFMT0 | PDAUDIOCF_DATAFMT1;
- break;
- }
- aval = 0;
- chip->pcm_sample = 4;
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_S16_LE:
- case SNDRV_PCM_FORMAT_S16_BE:
- aval = AK4117_DIF_16R;
- chip->pcm_frame = 2;
- chip->pcm_sample = 2;
- break;
- case SNDRV_PCM_FORMAT_S24_3LE:
- case SNDRV_PCM_FORMAT_S24_3BE:
- chip->pcm_sample = 3;
- /* fall through */
- default: /* 24-bit */
- aval = AK4117_DIF_24R;
- chip->pcm_frame = 3;
- chip->pcm_xor &= 0xffff0000;
- break;
- }
-
- if (val != nval) {
- snd_ak4117_reg_write(chip->ak4117, AK4117_REG_IO, AK4117_DIF2|AK4117_DIF1|AK4117_DIF0, aval);
- pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, nval);
- }
-
- val = pdacf_reg_read(chip, PDAUDIOCF_REG_IER);
- val &= ~(PDAUDIOCF_IRQLVLEN1);
- val |= PDAUDIOCF_IRQLVLEN0;
- pdacf_reg_write(chip, PDAUDIOCF_REG_IER, val);
-
- chip->pcm_size = runtime->buffer_size;
- chip->pcm_period = runtime->period_size;
- chip->pcm_area = runtime->dma_area;
-
- return 0;
-}
-
-
-/*
- * capture hw information
- */
-
-static struct snd_pcm_hardware pdacf_pcm_capture_hw = {
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BATCH),
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |
- SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE,
- .rates = SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000 |
- SNDRV_PCM_RATE_176400 |
- SNDRV_PCM_RATE_192000,
- .rate_min = 32000,
- .rate_max = 192000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = (512*1024),
- .period_bytes_min = 8*1024,
- .period_bytes_max = (64*1024),
- .periods_min = 2,
- .periods_max = 128,
- .fifo_size = 0,
-};
-
-
-/*
- * pdacf_pcm_capture_open - open callback for capture
- */
-static int pdacf_pcm_capture_open(struct snd_pcm_substream *subs)
-{
- struct snd_pcm_runtime *runtime = subs->runtime;
- struct snd_pdacf *chip = snd_pcm_substream_chip(subs);
-
- if (chip->chip_status & PDAUDIOCF_STAT_IS_STALE)
- return -EBUSY;
-
- runtime->hw = pdacf_pcm_capture_hw;
- runtime->private_data = chip;
- chip->pcm_substream = subs;
-
- return 0;
-}
-
-/*
- * pdacf_pcm_capture_close - close callback for capture
- */
-static int pdacf_pcm_capture_close(struct snd_pcm_substream *subs)
-{
- struct snd_pdacf *chip = snd_pcm_substream_chip(subs);
-
- if (!chip)
- return -EINVAL;
- pdacf_reinit(chip, 0);
- chip->pcm_substream = NULL;
- return 0;
-}
-
-
-/*
- * pdacf_pcm_capture_pointer - pointer callback for capture
- */
-static snd_pcm_uframes_t pdacf_pcm_capture_pointer(struct snd_pcm_substream *subs)
-{
- struct snd_pdacf *chip = snd_pcm_substream_chip(subs);
- return chip->pcm_hwptr;
-}
-
-/*
- * operators for PCM capture
- */
-static struct snd_pcm_ops pdacf_pcm_capture_ops = {
- .open = pdacf_pcm_capture_open,
- .close = pdacf_pcm_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = pdacf_pcm_hw_params,
- .hw_free = pdacf_pcm_hw_free,
- .prepare = pdacf_pcm_prepare,
- .trigger = pdacf_pcm_trigger,
- .pointer = pdacf_pcm_capture_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
-};
-
-
-/*
- * snd_pdacf_pcm_new - create and initialize a pcm
- */
-int snd_pdacf_pcm_new(struct snd_pdacf *chip)
-{
- struct snd_pcm *pcm;
- int err;
-
- err = snd_pcm_new(chip->card, "PDAudioCF", 0, 0, 1, &pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pdacf_pcm_capture_ops);
-
- pcm->private_data = chip;
- pcm->info_flags = 0;
- strcpy(pcm->name, chip->card->shortname);
- chip->pcm = pcm;
-
- err = snd_ak4117_build(chip->ak4117, pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
- if (err < 0)
- return err;
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/pcmcia/vx/Makefile b/ANDROID_3.4.5/sound/pcmcia/vx/Makefile
deleted file mode 100644
index 2bb42ea1..00000000
--- a/ANDROID_3.4.5/sound/pcmcia/vx/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-vxpocket-objs := vxpocket.o vxp_ops.o vxp_mixer.o
-
-obj-$(CONFIG_SND_VXPOCKET) += snd-vxpocket.o
diff --git a/ANDROID_3.4.5/sound/pcmcia/vx/vxp_mixer.c b/ANDROID_3.4.5/sound/pcmcia/vx/vxp_mixer.c
deleted file mode 100644
index a4a66425..00000000
--- a/ANDROID_3.4.5/sound/pcmcia/vx/vxp_mixer.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Driver for Digigram VXpocket soundcards
- *
- * VX-pocket mixer
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include "vxpocket.h"
-
-#define MIC_LEVEL_MIN 0
-#define MIC_LEVEL_MAX 8
-
-/*
- * mic level control (for VXPocket)
- */
-static int vx_mic_level_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = MIC_LEVEL_MAX;
- return 0;
-}
-
-static int vx_mic_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
- struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
- ucontrol->value.integer.value[0] = chip->mic_level;
- return 0;
-}
-
-static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
- struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
- unsigned int val = ucontrol->value.integer.value[0];
-
- if (val > MIC_LEVEL_MAX)
- return -EINVAL;
- mutex_lock(&_chip->mixer_mutex);
- if (chip->mic_level != ucontrol->value.integer.value[0]) {
- vx_set_mic_level(_chip, ucontrol->value.integer.value[0]);
- chip->mic_level = ucontrol->value.integer.value[0];
- mutex_unlock(&_chip->mixer_mutex);
- return 1;
- }
- mutex_unlock(&_chip->mixer_mutex);
- return 0;
-}
-
-static const DECLARE_TLV_DB_SCALE(db_scale_mic, -21, 3, 0);
-
-static struct snd_kcontrol_new vx_control_mic_level = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Mic Capture Volume",
- .info = vx_mic_level_info,
- .get = vx_mic_level_get,
- .put = vx_mic_level_put,
- .tlv = { .p = db_scale_mic },
-};
-
-/*
- * mic boost level control (for VXP440)
- */
-#define vx_mic_boost_info snd_ctl_boolean_mono_info
-
-static int vx_mic_boost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
- struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
- ucontrol->value.integer.value[0] = chip->mic_level;
- return 0;
-}
-
-static int vx_mic_boost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
- struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
- int val = !!ucontrol->value.integer.value[0];
- mutex_lock(&_chip->mixer_mutex);
- if (chip->mic_level != val) {
- vx_set_mic_boost(_chip, val);
- chip->mic_level = val;
- mutex_unlock(&_chip->mixer_mutex);
- return 1;
- }
- mutex_unlock(&_chip->mixer_mutex);
- return 0;
-}
-
-static struct snd_kcontrol_new vx_control_mic_boost = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Mic Boost",
- .info = vx_mic_boost_info,
- .get = vx_mic_boost_get,
- .put = vx_mic_boost_put,
-};
-
-
-int vxp_add_mic_controls(struct vx_core *_chip)
-{
- struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
- int err;
-
- /* mute input levels */
- chip->mic_level = 0;
- switch (_chip->type) {
- case VX_TYPE_VXPOCKET:
- vx_set_mic_level(_chip, 0);
- break;
- case VX_TYPE_VXP440:
- vx_set_mic_boost(_chip, 0);
- break;
- }
-
- /* mic level */
- switch (_chip->type) {
- case VX_TYPE_VXPOCKET:
- if ((err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_mic_level, chip))) < 0)
- return err;
- break;
- case VX_TYPE_VXP440:
- if ((err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_mic_boost, chip))) < 0)
- return err;
- break;
- }
-
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/pcmcia/vx/vxp_ops.c b/ANDROID_3.4.5/sound/pcmcia/vx/vxp_ops.c
deleted file mode 100644
index fe33e122..00000000
--- a/ANDROID_3.4.5/sound/pcmcia/vx/vxp_ops.c
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
- * Driver for Digigram VXpocket soundcards
- *
- * lowlevel routines for VXpocket soundcards
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/io.h>
-#include <sound/core.h>
-#include "vxpocket.h"
-
-
-static int vxp_reg_offset[VX_REG_MAX] = {
- [VX_ICR] = 0x00, // ICR
- [VX_CVR] = 0x01, // CVR
- [VX_ISR] = 0x02, // ISR
- [VX_IVR] = 0x03, // IVR
- [VX_RXH] = 0x05, // RXH
- [VX_RXM] = 0x06, // RXM
- [VX_RXL] = 0x07, // RXL
- [VX_DMA] = 0x04, // DMA
- [VX_CDSP] = 0x08, // CDSP
- [VX_LOFREQ] = 0x09, // LFREQ
- [VX_HIFREQ] = 0x0a, // HFREQ
- [VX_DATA] = 0x0b, // DATA
- [VX_MICRO] = 0x0c, // MICRO
- [VX_DIALOG] = 0x0d, // DIALOG
- [VX_CSUER] = 0x0e, // CSUER
- [VX_RUER] = 0x0f, // RUER
-};
-
-
-static inline unsigned long vxp_reg_addr(struct vx_core *_chip, int reg)
-{
- struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
- return chip->port + vxp_reg_offset[reg];
-}
-
-/*
- * snd_vx_inb - read a byte from the register
- * @offset: register offset
- */
-static unsigned char vxp_inb(struct vx_core *chip, int offset)
-{
- return inb(vxp_reg_addr(chip, offset));
-}
-
-/*
- * snd_vx_outb - write a byte on the register
- * @offset: the register offset
- * @val: the value to write
- */
-static void vxp_outb(struct vx_core *chip, int offset, unsigned char val)
-{
- outb(val, vxp_reg_addr(chip, offset));
-}
-
-/*
- * redefine macros to call directly
- */
-#undef vx_inb
-#define vx_inb(chip,reg) vxp_inb((struct vx_core *)(chip), VX_##reg)
-#undef vx_outb
-#define vx_outb(chip,reg,val) vxp_outb((struct vx_core *)(chip), VX_##reg,val)
-
-
-/*
- * vx_check_magic - check the magic word on xilinx
- *
- * returns zero if a magic word is detected, or a negative error code.
- */
-static int vx_check_magic(struct vx_core *chip)
-{
- unsigned long end_time = jiffies + HZ / 5;
- int c;
- do {
- c = vx_inb(chip, CDSP);
- if (c == CDSP_MAGIC)
- return 0;
- msleep(10);
- } while (time_after_eq(end_time, jiffies));
- snd_printk(KERN_ERR "cannot find xilinx magic word (%x)\n", c);
- return -EIO;
-}
-
-
-/*
- * vx_reset_dsp - reset the DSP
- */
-
-#define XX_DSP_RESET_WAIT_TIME 2 /* ms */
-
-static void vxp_reset_dsp(struct vx_core *_chip)
-{
- struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
-
- /* set the reset dsp bit to 1 */
- vx_outb(chip, CDSP, chip->regCDSP | VXP_CDSP_DSP_RESET_MASK);
- vx_inb(chip, CDSP);
- mdelay(XX_DSP_RESET_WAIT_TIME);
- /* reset the bit */
- chip->regCDSP &= ~VXP_CDSP_DSP_RESET_MASK;
- vx_outb(chip, CDSP, chip->regCDSP);
- vx_inb(chip, CDSP);
- mdelay(XX_DSP_RESET_WAIT_TIME);
-}
-
-/*
- * reset codec bit
- */
-static void vxp_reset_codec(struct vx_core *_chip)
-{
- struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
-
- /* Set the reset CODEC bit to 1. */
- vx_outb(chip, CDSP, chip->regCDSP | VXP_CDSP_CODEC_RESET_MASK);
- vx_inb(chip, CDSP);
- msleep(10);
- /* Set the reset CODEC bit to 0. */
- chip->regCDSP &= ~VXP_CDSP_CODEC_RESET_MASK;
- vx_outb(chip, CDSP, chip->regCDSP);
- vx_inb(chip, CDSP);
- msleep(1);
-}
-
-/*
- * vx_load_xilinx_binary - load the xilinx binary image
- * the binary image is the binary array converted from the bitstream file.
- */
-static int vxp_load_xilinx_binary(struct vx_core *_chip, const struct firmware *fw)
-{
- struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
- unsigned int i;
- int c;
- int regCSUER, regRUER;
- const unsigned char *image;
- unsigned char data;
-
- /* Switch to programmation mode */
- chip->regDIALOG |= VXP_DLG_XILINX_REPROG_MASK;
- vx_outb(chip, DIALOG, chip->regDIALOG);
-
- /* Save register CSUER and RUER */
- regCSUER = vx_inb(chip, CSUER);
- regRUER = vx_inb(chip, RUER);
-
- /* reset HF0 and HF1 */
- vx_outb(chip, ICR, 0);
-
- /* Wait for answer HF2 equal to 1 */
- snd_printdd(KERN_DEBUG "check ISR_HF2\n");
- if (vx_check_isr(_chip, ISR_HF2, ISR_HF2, 20) < 0)
- goto _error;
-
- /* set HF1 for loading xilinx binary */
- vx_outb(chip, ICR, ICR_HF1);
- image = fw->data;
- for (i = 0; i < fw->size; i++, image++) {
- data = *image;
- if (vx_wait_isr_bit(_chip, ISR_TX_EMPTY) < 0)
- goto _error;
- vx_outb(chip, TXL, data);
- /* wait for reading */
- if (vx_wait_for_rx_full(_chip) < 0)
- goto _error;
- c = vx_inb(chip, RXL);
- if (c != (int)data)
- snd_printk(KERN_ERR "vxpocket: load xilinx mismatch at %d: 0x%x != 0x%x\n", i, c, (int)data);
- }
-
- /* reset HF1 */
- vx_outb(chip, ICR, 0);
-
- /* wait for HF3 */
- if (vx_check_isr(_chip, ISR_HF3, ISR_HF3, 20) < 0)
- goto _error;
-
- /* read the number of bytes received */
- if (vx_wait_for_rx_full(_chip) < 0)
- goto _error;
-
- c = (int)vx_inb(chip, RXH) << 16;
- c |= (int)vx_inb(chip, RXM) << 8;
- c |= vx_inb(chip, RXL);
-
- snd_printdd(KERN_DEBUG "xilinx: dsp size received 0x%x, orig 0x%Zx\n", c, fw->size);
-
- vx_outb(chip, ICR, ICR_HF0);
-
- /* TEMPO 250ms : wait until Xilinx is downloaded */
- msleep(300);
-
- /* test magical word */
- if (vx_check_magic(_chip) < 0)
- goto _error;
-
- /* Restore register 0x0E and 0x0F (thus replacing COR and FCSR) */
- vx_outb(chip, CSUER, regCSUER);
- vx_outb(chip, RUER, regRUER);
-
- /* Reset the Xilinx's signal enabling IO access */
- chip->regDIALOG |= VXP_DLG_XILINX_REPROG_MASK;
- vx_outb(chip, DIALOG, chip->regDIALOG);
- vx_inb(chip, DIALOG);
- msleep(10);
- chip->regDIALOG &= ~VXP_DLG_XILINX_REPROG_MASK;
- vx_outb(chip, DIALOG, chip->regDIALOG);
- vx_inb(chip, DIALOG);
-
- /* Reset of the Codec */
- vxp_reset_codec(_chip);
- vx_reset_dsp(_chip);
-
- return 0;
-
- _error:
- vx_outb(chip, CSUER, regCSUER);
- vx_outb(chip, RUER, regRUER);
- chip->regDIALOG &= ~VXP_DLG_XILINX_REPROG_MASK;
- vx_outb(chip, DIALOG, chip->regDIALOG);
- return -EIO;
-}
-
-
-/*
- * vxp_load_dsp - load_dsp callback
- */
-static int vxp_load_dsp(struct vx_core *vx, int index, const struct firmware *fw)
-{
- int err;
-
- switch (index) {
- case 0:
- /* xilinx boot */
- if ((err = vx_check_magic(vx)) < 0)
- return err;
- if ((err = snd_vx_load_boot_image(vx, fw)) < 0)
- return err;
- return 0;
- case 1:
- /* xilinx image */
- return vxp_load_xilinx_binary(vx, fw);
- case 2:
- /* DSP boot */
- return snd_vx_dsp_boot(vx, fw);
- case 3:
- /* DSP image */
- return snd_vx_dsp_load(vx, fw);
- default:
- snd_BUG();
- return -EINVAL;
- }
-}
-
-
-/*
- * vx_test_and_ack - test and acknowledge interrupt
- *
- * called from irq hander, too
- *
- * spinlock held!
- */
-static int vxp_test_and_ack(struct vx_core *_chip)
-{
- struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
-
- /* not booted yet? */
- if (! (_chip->chip_status & VX_STAT_XILINX_LOADED))
- return -ENXIO;
-
- if (! (vx_inb(chip, DIALOG) & VXP_DLG_MEMIRQ_MASK))
- return -EIO;
-
- /* ok, interrupts generated, now ack it */
- /* set ACQUIT bit up and down */
- vx_outb(chip, DIALOG, chip->regDIALOG | VXP_DLG_ACK_MEMIRQ_MASK);
- /* useless read just to spend some time and maintain
- * the ACQUIT signal up for a while ( a bus cycle )
- */
- vx_inb(chip, DIALOG);
- vx_outb(chip, DIALOG, chip->regDIALOG & ~VXP_DLG_ACK_MEMIRQ_MASK);
-
- return 0;
-}
-
-
-/*
- * vx_validate_irq - enable/disable IRQ
- */
-static void vxp_validate_irq(struct vx_core *_chip, int enable)
-{
- struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
-
- /* Set the interrupt enable bit to 1 in CDSP register */
- if (enable)
- chip->regCDSP |= VXP_CDSP_VALID_IRQ_MASK;
- else
- chip->regCDSP &= ~VXP_CDSP_VALID_IRQ_MASK;
- vx_outb(chip, CDSP, chip->regCDSP);
-}
-
-/*
- * vx_setup_pseudo_dma - set up the pseudo dma read/write mode.
- * @do_write: 0 = read, 1 = set up for DMA write
- */
-static void vx_setup_pseudo_dma(struct vx_core *_chip, int do_write)
-{
- struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
-
- /* Interrupt mode and HREQ pin enabled for host transmit / receive data transfers */
- vx_outb(chip, ICR, do_write ? ICR_TREQ : ICR_RREQ);
- /* Reset the pseudo-dma register */
- vx_inb(chip, ISR);
- vx_outb(chip, ISR, 0);
-
- /* Select DMA in read/write transfer mode and in 16-bit accesses */
- chip->regDIALOG |= VXP_DLG_DMA16_SEL_MASK;
- chip->regDIALOG |= do_write ? VXP_DLG_DMAWRITE_SEL_MASK : VXP_DLG_DMAREAD_SEL_MASK;
- vx_outb(chip, DIALOG, chip->regDIALOG);
-
-}
-
-/*
- * vx_release_pseudo_dma - disable the pseudo-DMA mode
- */
-static void vx_release_pseudo_dma(struct vx_core *_chip)
-{
- struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
-
- /* Disable DMA and 16-bit accesses */
- chip->regDIALOG &= ~(VXP_DLG_DMAWRITE_SEL_MASK|
- VXP_DLG_DMAREAD_SEL_MASK|
- VXP_DLG_DMA16_SEL_MASK);
- vx_outb(chip, DIALOG, chip->regDIALOG);
- /* HREQ pin disabled. */
- vx_outb(chip, ICR, 0);
-}
-
-/*
- * vx_pseudo_dma_write - write bulk data on pseudo-DMA mode
- * @count: data length to transfer in bytes
- *
- * data size must be aligned to 6 bytes to ensure the 24bit alignment on DSP.
- * NB: call with a certain lock!
- */
-static void vxp_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime,
- struct vx_pipe *pipe, int count)
-{
- long port = vxp_reg_addr(chip, VX_DMA);
- int offset = pipe->hw_ptr;
- unsigned short *addr = (unsigned short *)(runtime->dma_area + offset);
-
- vx_setup_pseudo_dma(chip, 1);
- if (offset + count > pipe->buffer_bytes) {
- int length = pipe->buffer_bytes - offset;
- count -= length;
- length >>= 1; /* in 16bit words */
- /* Transfer using pseudo-dma. */
- while (length-- > 0) {
- outw(cpu_to_le16(*addr), port);
- addr++;
- }
- addr = (unsigned short *)runtime->dma_area;
- pipe->hw_ptr = 0;
- }
- pipe->hw_ptr += count;
- count >>= 1; /* in 16bit words */
- /* Transfer using pseudo-dma. */
- while (count-- > 0) {
- outw(cpu_to_le16(*addr), port);
- addr++;
- }
- vx_release_pseudo_dma(chip);
-}
-
-
-/*
- * vx_pseudo_dma_read - read bulk data on pseudo DMA mode
- * @offset: buffer offset in bytes
- * @count: data length to transfer in bytes
- *
- * the read length must be aligned to 6 bytes, as well as write.
- * NB: call with a certain lock!
- */
-static void vxp_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
- struct vx_pipe *pipe, int count)
-{
- struct snd_vxpocket *pchip = (struct snd_vxpocket *)chip;
- long port = vxp_reg_addr(chip, VX_DMA);
- int offset = pipe->hw_ptr;
- unsigned short *addr = (unsigned short *)(runtime->dma_area + offset);
-
- if (snd_BUG_ON(count % 2))
- return;
- vx_setup_pseudo_dma(chip, 0);
- if (offset + count > pipe->buffer_bytes) {
- int length = pipe->buffer_bytes - offset;
- count -= length;
- length >>= 1; /* in 16bit words */
- /* Transfer using pseudo-dma. */
- while (length-- > 0)
- *addr++ = le16_to_cpu(inw(port));
- addr = (unsigned short *)runtime->dma_area;
- pipe->hw_ptr = 0;
- }
- pipe->hw_ptr += count;
- count >>= 1; /* in 16bit words */
- /* Transfer using pseudo-dma. */
- while (count-- > 1)
- *addr++ = le16_to_cpu(inw(port));
- /* Disable DMA */
- pchip->regDIALOG &= ~VXP_DLG_DMAREAD_SEL_MASK;
- vx_outb(chip, DIALOG, pchip->regDIALOG);
- /* Read the last word (16 bits) */
- *addr = le16_to_cpu(inw(port));
- /* Disable 16-bit accesses */
- pchip->regDIALOG &= ~VXP_DLG_DMA16_SEL_MASK;
- vx_outb(chip, DIALOG, pchip->regDIALOG);
- /* HREQ pin disabled. */
- vx_outb(chip, ICR, 0);
-}
-
-
-/*
- * write a codec data (24bit)
- */
-static void vxp_write_codec_reg(struct vx_core *chip, int codec, unsigned int data)
-{
- int i;
-
- /* Activate access to the corresponding codec register */
- if (! codec)
- vx_inb(chip, LOFREQ);
- else
- vx_inb(chip, CODEC2);
-
- /* We have to send 24 bits (3 x 8 bits). Start with most signif. Bit */
- for (i = 0; i < 24; i++, data <<= 1)
- vx_outb(chip, DATA, ((data & 0x800000) ? VX_DATA_CODEC_MASK : 0));
-
- /* Terminate access to codec registers */
- vx_inb(chip, HIFREQ);
-}
-
-
-/*
- * vx_set_mic_boost - set mic boost level (on vxp440 only)
- * @boost: 0 = 20dB, 1 = +38dB
- */
-void vx_set_mic_boost(struct vx_core *chip, int boost)
-{
- struct snd_vxpocket *pchip = (struct snd_vxpocket *)chip;
- unsigned long flags;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return;
-
- spin_lock_irqsave(&chip->lock, flags);
- if (pchip->regCDSP & P24_CDSP_MICS_SEL_MASK) {
- if (boost) {
- /* boost: 38 dB */
- pchip->regCDSP &= ~P24_CDSP_MIC20_SEL_MASK;
- pchip->regCDSP |= P24_CDSP_MIC38_SEL_MASK;
- } else {
- /* minimum value: 20 dB */
- pchip->regCDSP |= P24_CDSP_MIC20_SEL_MASK;
- pchip->regCDSP &= ~P24_CDSP_MIC38_SEL_MASK;
- }
- vx_outb(chip, CDSP, pchip->regCDSP);
- }
- spin_unlock_irqrestore(&chip->lock, flags);
-}
-
-/*
- * remap the linear value (0-8) to the actual value (0-15)
- */
-static int vx_compute_mic_level(int level)
-{
- switch (level) {
- case 5: level = 6 ; break;
- case 6: level = 8 ; break;
- case 7: level = 11; break;
- case 8: level = 15; break;
- default: break ;
- }
- return level;
-}
-
-/*
- * vx_set_mic_level - set mic level (on vxpocket only)
- * @level: the mic level = 0 - 8 (max)
- */
-void vx_set_mic_level(struct vx_core *chip, int level)
-{
- struct snd_vxpocket *pchip = (struct snd_vxpocket *)chip;
- unsigned long flags;
-
- if (chip->chip_status & VX_STAT_IS_STALE)
- return;
-
- spin_lock_irqsave(&chip->lock, flags);
- if (pchip->regCDSP & VXP_CDSP_MIC_SEL_MASK) {
- level = vx_compute_mic_level(level);
- vx_outb(chip, MICRO, level);
- }
- spin_unlock_irqrestore(&chip->lock, flags);
-}
-
-
-/*
- * change the input audio source
- */
-static void vxp_change_audio_source(struct vx_core *_chip, int src)
-{
- struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
-
- switch (src) {
- case VX_AUDIO_SRC_DIGITAL:
- chip->regCDSP |= VXP_CDSP_DATAIN_SEL_MASK;
- vx_outb(chip, CDSP, chip->regCDSP);
- break;
- case VX_AUDIO_SRC_LINE:
- chip->regCDSP &= ~VXP_CDSP_DATAIN_SEL_MASK;
- if (_chip->type == VX_TYPE_VXP440)
- chip->regCDSP &= ~P24_CDSP_MICS_SEL_MASK;
- else
- chip->regCDSP &= ~VXP_CDSP_MIC_SEL_MASK;
- vx_outb(chip, CDSP, chip->regCDSP);
- break;
- case VX_AUDIO_SRC_MIC:
- chip->regCDSP &= ~VXP_CDSP_DATAIN_SEL_MASK;
- /* reset mic levels */
- if (_chip->type == VX_TYPE_VXP440) {
- chip->regCDSP &= ~P24_CDSP_MICS_SEL_MASK;
- if (chip->mic_level)
- chip->regCDSP |= P24_CDSP_MIC38_SEL_MASK;
- else
- chip->regCDSP |= P24_CDSP_MIC20_SEL_MASK;
- vx_outb(chip, CDSP, chip->regCDSP);
- } else {
- chip->regCDSP |= VXP_CDSP_MIC_SEL_MASK;
- vx_outb(chip, CDSP, chip->regCDSP);
- vx_outb(chip, MICRO, vx_compute_mic_level(chip->mic_level));
- }
- break;
- }
-}
-
-/*
- * change the clock source
- * source = INTERNAL_QUARTZ or UER_SYNC
- */
-static void vxp_set_clock_source(struct vx_core *_chip, int source)
-{
- struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
-
- if (source == INTERNAL_QUARTZ)
- chip->regCDSP &= ~VXP_CDSP_CLOCKIN_SEL_MASK;
- else
- chip->regCDSP |= VXP_CDSP_CLOCKIN_SEL_MASK;
- vx_outb(chip, CDSP, chip->regCDSP);
-}
-
-
-/*
- * reset the board
- */
-static void vxp_reset_board(struct vx_core *_chip, int cold_reset)
-{
- struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
-
- chip->regCDSP = 0;
- chip->regDIALOG = 0;
-}
-
-
-/*
- * callbacks
- */
-/* exported */
-struct snd_vx_ops snd_vxpocket_ops = {
- .in8 = vxp_inb,
- .out8 = vxp_outb,
- .test_and_ack = vxp_test_and_ack,
- .validate_irq = vxp_validate_irq,
- .write_codec = vxp_write_codec_reg,
- .reset_codec = vxp_reset_codec,
- .change_audio_source = vxp_change_audio_source,
- .set_clock_source = vxp_set_clock_source,
- .load_dsp = vxp_load_dsp,
- .add_controls = vxp_add_mic_controls,
- .reset_dsp = vxp_reset_dsp,
- .reset_board = vxp_reset_board,
- .dma_write = vxp_dma_write,
- .dma_read = vxp_dma_read,
-};
diff --git a/ANDROID_3.4.5/sound/pcmcia/vx/vxpocket.c b/ANDROID_3.4.5/sound/pcmcia/vx/vxpocket.c
deleted file mode 100644
index 512f0b47..00000000
--- a/ANDROID_3.4.5/sound/pcmcia/vx/vxpocket.c
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Driver for Digigram VXpocket V2/440 soundcards
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
-
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include "vxpocket.h"
-#include <pcmcia/ciscode.h>
-#include <pcmcia/cisreg.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-/*
- */
-
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("Digigram VXPocket");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Digigram,VXPocket},{Digigram,VXPocket440}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
-static int ibl[SNDRV_CARDS];
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for VXPocket soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for VXPocket soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable VXPocket soundcard.");
-module_param_array(ibl, int, NULL, 0444);
-MODULE_PARM_DESC(ibl, "Capture IBL size for VXPocket soundcard.");
-
-
-/*
- */
-
-static unsigned int card_alloc;
-
-
-/*
- */
-static void vxpocket_release(struct pcmcia_device *link)
-{
- pcmcia_disable_device(link);
-}
-
-/*
- * destructor, called from snd_card_free_when_closed()
- */
-static int snd_vxpocket_dev_free(struct snd_device *device)
-{
- struct vx_core *chip = device->device_data;
-
- snd_vx_free_firmware(chip);
- kfree(chip);
- return 0;
-}
-
-
-/*
- * Hardware information
- */
-
-/* VX-pocket V2
- *
- * 1 DSP, 1 sync UER
- * 1 programmable clock (NIY)
- * 1 stereo analog input (line/micro)
- * 1 stereo analog output
- * Only output levels can be modified
- */
-
-static const DECLARE_TLV_DB_SCALE(db_scale_old_vol, -11350, 50, 0);
-
-static struct snd_vx_hardware vxpocket_hw = {
- .name = "VXPocket",
- .type = VX_TYPE_VXPOCKET,
-
- /* hardware specs */
- .num_codecs = 1,
- .num_ins = 1,
- .num_outs = 1,
- .output_level_max = VX_ANALOG_OUT_LEVEL_MAX,
- .output_level_db_scale = db_scale_old_vol,
-};
-
-/* VX-pocket 440
- *
- * 1 DSP, 1 sync UER, 1 sync World Clock (NIY)
- * SMPTE (NIY)
- * 2 stereo analog input (line/micro)
- * 2 stereo analog output
- * Only output levels can be modified
- * UER, but only for the first two inputs and outputs.
- */
-
-static struct snd_vx_hardware vxp440_hw = {
- .name = "VXPocket440",
- .type = VX_TYPE_VXP440,
-
- /* hardware specs */
- .num_codecs = 2,
- .num_ins = 2,
- .num_outs = 2,
- .output_level_max = VX_ANALOG_OUT_LEVEL_MAX,
- .output_level_db_scale = db_scale_old_vol,
-};
-
-
-/*
- * create vxpocket instance
- */
-static int snd_vxpocket_new(struct snd_card *card, int ibl,
- struct pcmcia_device *link,
- struct snd_vxpocket **chip_ret)
-{
- struct vx_core *chip;
- struct snd_vxpocket *vxp;
- static struct snd_device_ops ops = {
- .dev_free = snd_vxpocket_dev_free,
- };
- int err;
-
- chip = snd_vx_create(card, &vxpocket_hw, &snd_vxpocket_ops,
- sizeof(struct snd_vxpocket) - sizeof(struct vx_core));
- if (!chip)
- return -ENOMEM;
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
- if (err < 0) {
- kfree(chip);
- return err;
- }
- chip->ibl.size = ibl;
-
- vxp = (struct snd_vxpocket *)chip;
-
- vxp->p_dev = link;
- link->priv = chip;
-
- link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
- link->resource[0]->end = 16;
-
- link->config_flags |= CONF_ENABLE_IRQ;
- link->config_index = 1;
- link->config_regs = PRESENT_OPTION;
-
- *chip_ret = vxp;
- return 0;
-}
-
-
-/**
- * snd_vxpocket_assign_resources - initialize the hardware and card instance.
- * @port: i/o port for the card
- * @irq: irq number for the card
- *
- * this function assigns the specified port and irq, boot the card,
- * create pcm and control instances, and initialize the rest hardware.
- *
- * returns 0 if successful, or a negative error code.
- */
-static int snd_vxpocket_assign_resources(struct vx_core *chip, int port, int irq)
-{
- int err;
- struct snd_card *card = chip->card;
- struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
-
- snd_printdd(KERN_DEBUG "vxpocket assign resources: port = 0x%x, irq = %d\n", port, irq);
- vxp->port = port;
-
- sprintf(card->shortname, "Digigram %s", card->driver);
- sprintf(card->longname, "%s at 0x%x, irq %i",
- card->shortname, port, irq);
-
- chip->irq = irq;
-
- if ((err = snd_vx_setup_firmware(chip)) < 0)
- return err;
-
- return 0;
-}
-
-
-/*
- * configuration callback
- */
-
-static int vxpocket_config(struct pcmcia_device *link)
-{
- struct vx_core *chip = link->priv;
- int ret;
-
- snd_printdd(KERN_DEBUG "vxpocket_config called\n");
-
- /* redefine hardware record according to the VERSION1 string */
- if (!strcmp(link->prod_id[1], "VX-POCKET")) {
- snd_printdd("VX-pocket is detected\n");
- } else {
- snd_printdd("VX-pocket 440 is detected\n");
- /* overwrite the hardware information */
- chip->hw = &vxp440_hw;
- chip->type = vxp440_hw.type;
- strcpy(chip->card->driver, vxp440_hw.name);
- }
-
- ret = pcmcia_request_io(link);
- if (ret)
- goto failed;
-
- ret = pcmcia_request_irq(link, snd_vx_irq_handler);
- if (ret)
- goto failed;
-
- ret = pcmcia_enable_device(link);
- if (ret)
- goto failed;
-
- chip->dev = &link->dev;
- snd_card_set_dev(chip->card, chip->dev);
-
- if (snd_vxpocket_assign_resources(chip, link->resource[0]->start,
- link->irq) < 0)
- goto failed;
-
- return 0;
-
-failed:
- pcmcia_disable_device(link);
- return -ENODEV;
-}
-
-#ifdef CONFIG_PM
-
-static int vxp_suspend(struct pcmcia_device *link)
-{
- struct vx_core *chip = link->priv;
-
- snd_printdd(KERN_DEBUG "SUSPEND\n");
- if (chip) {
- snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n");
- snd_vx_suspend(chip, PMSG_SUSPEND);
- }
-
- return 0;
-}
-
-static int vxp_resume(struct pcmcia_device *link)
-{
- struct vx_core *chip = link->priv;
-
- snd_printdd(KERN_DEBUG "RESUME\n");
- if (pcmcia_dev_present(link)) {
- //struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
- if (chip) {
- snd_printdd(KERN_DEBUG "calling snd_vx_resume\n");
- snd_vx_resume(chip);
- }
- }
- snd_printdd(KERN_DEBUG "resume done!\n");
-
- return 0;
-}
-
-#endif
-
-
-/*
- */
-static int vxpocket_probe(struct pcmcia_device *p_dev)
-{
- struct snd_card *card;
- struct snd_vxpocket *vxp;
- int i, err;
-
- /* find an empty slot from the card list */
- for (i = 0; i < SNDRV_CARDS; i++) {
- if (!(card_alloc & (1 << i)))
- break;
- }
- if (i >= SNDRV_CARDS) {
- snd_printk(KERN_ERR "vxpocket: too many cards found\n");
- return -EINVAL;
- }
- if (! enable[i])
- return -ENODEV; /* disabled explicitly */
-
- /* ok, create a card instance */
- err = snd_card_create(index[i], id[i], THIS_MODULE, 0, &card);
- if (err < 0) {
- snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n");
- return err;
- }
-
- err = snd_vxpocket_new(card, ibl[i], p_dev, &vxp);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
- card->private_data = vxp;
-
- vxp->index = i;
- card_alloc |= 1 << i;
-
- vxp->p_dev = p_dev;
-
- return vxpocket_config(p_dev);
-}
-
-static void vxpocket_detach(struct pcmcia_device *link)
-{
- struct snd_vxpocket *vxp;
- struct vx_core *chip;
-
- if (! link)
- return;
-
- vxp = link->priv;
- chip = (struct vx_core *)vxp;
- card_alloc &= ~(1 << vxp->index);
-
- chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */
- snd_card_disconnect(chip->card);
- vxpocket_release(link);
- snd_card_free_when_closed(chip->card);
-}
-
-/*
- * Module entry points
- */
-
-static const struct pcmcia_device_id vxp_ids[] = {
- PCMCIA_DEVICE_MANF_CARD(0x01f1, 0x0100),
- PCMCIA_DEVICE_NULL
-};
-MODULE_DEVICE_TABLE(pcmcia, vxp_ids);
-
-static struct pcmcia_driver vxp_cs_driver = {
- .owner = THIS_MODULE,
- .name = "snd-vxpocket",
- .probe = vxpocket_probe,
- .remove = vxpocket_detach,
- .id_table = vxp_ids,
-#ifdef CONFIG_PM
- .suspend = vxp_suspend,
- .resume = vxp_resume,
-#endif
-};
-
-static int __init init_vxpocket(void)
-{
- return pcmcia_register_driver(&vxp_cs_driver);
-}
-
-static void __exit exit_vxpocket(void)
-{
- pcmcia_unregister_driver(&vxp_cs_driver);
-}
-
-module_init(init_vxpocket);
-module_exit(exit_vxpocket);
diff --git a/ANDROID_3.4.5/sound/pcmcia/vx/vxpocket.h b/ANDROID_3.4.5/sound/pcmcia/vx/vxpocket.h
deleted file mode 100644
index 13d658c1..00000000
--- a/ANDROID_3.4.5/sound/pcmcia/vx/vxpocket.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Driver for Digigram VXpocket soundcards
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __VXPOCKET_H
-#define __VXPOCKET_H
-
-#include <sound/vx_core.h>
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ds.h>
-
-struct snd_vxpocket {
-
- struct vx_core core;
-
- unsigned long port;
-
- int mic_level; /* analog mic level (or boost) */
-
- unsigned int regCDSP; /* current CDSP register */
- unsigned int regDIALOG; /* current DIALOG register */
-
- int index; /* card index */
-
- /* pcmcia stuff */
- struct pcmcia_device *p_dev;
-};
-
-extern struct snd_vx_ops snd_vxpocket_ops;
-
-void vx_set_mic_boost(struct vx_core *chip, int boost);
-void vx_set_mic_level(struct vx_core *chip, int level);
-
-int vxp_add_mic_controls(struct vx_core *chip);
-
-/* Constants used to access the CDSP register (0x08). */
-#define CDSP_MAGIC 0xA7 /* magic value (for read) */
-/* for write */
-#define VXP_CDSP_CLOCKIN_SEL_MASK 0x80 /* 0 (internal), 1 (AES/EBU) */
-#define VXP_CDSP_DATAIN_SEL_MASK 0x40 /* 0 (analog), 1 (UER) */
-#define VXP_CDSP_SMPTE_SEL_MASK 0x20
-#define VXP_CDSP_RESERVED_MASK 0x10
-#define VXP_CDSP_MIC_SEL_MASK 0x08
-#define VXP_CDSP_VALID_IRQ_MASK 0x04
-#define VXP_CDSP_CODEC_RESET_MASK 0x02
-#define VXP_CDSP_DSP_RESET_MASK 0x01
-/* VXPOCKET 240/440 */
-#define P24_CDSP_MICS_SEL_MASK 0x18
-#define P24_CDSP_MIC20_SEL_MASK 0x10
-#define P24_CDSP_MIC38_SEL_MASK 0x08
-
-/* Constants used to access the MEMIRQ register (0x0C). */
-#define P44_MEMIRQ_MASTER_SLAVE_SEL_MASK 0x08
-#define P44_MEMIRQ_SYNCED_ALONE_SEL_MASK 0x04
-#define P44_MEMIRQ_WCLK_OUT_IN_SEL_MASK 0x02 /* Not used */
-#define P44_MEMIRQ_WCLK_UER_SEL_MASK 0x01 /* Not used */
-
-/* Micro levels (0x0C) */
-
-/* Constants used to access the DIALOG register (0x0D). */
-#define VXP_DLG_XILINX_REPROG_MASK 0x80 /* W */
-#define VXP_DLG_DATA_XICOR_MASK 0x80 /* R */
-#define VXP_DLG_RESERVED4_0_MASK 0x40
-#define VXP_DLG_RESERVED2_0_MASK 0x20
-#define VXP_DLG_RESERVED1_0_MASK 0x10
-#define VXP_DLG_DMAWRITE_SEL_MASK 0x08 /* W */
-#define VXP_DLG_DMAREAD_SEL_MASK 0x04 /* W */
-#define VXP_DLG_MEMIRQ_MASK 0x02 /* R */
-#define VXP_DLG_DMA16_SEL_MASK 0x02 /* W */
-#define VXP_DLG_ACK_MEMIRQ_MASK 0x01 /* R/W */
-
-
-#endif /* __VXPOCKET_H */
diff --git a/ANDROID_3.4.5/sound/ppc/Kconfig b/ANDROID_3.4.5/sound/ppc/Kconfig
deleted file mode 100644
index 0519c60f..00000000
--- a/ANDROID_3.4.5/sound/ppc/Kconfig
+++ /dev/null
@@ -1,52 +0,0 @@
-# ALSA PowerMac drivers
-
-menuconfig SND_PPC
- bool "PowerPC sound devices"
- depends on PPC
- default y
- help
- Support for sound devices specific to PowerPC architectures.
-
-if SND_PPC
-
-config SND_POWERMAC
- tristate "PowerMac (AWACS, DACA, Burgundy, Tumbler, Keywest)"
- depends on I2C && INPUT && PPC_PMAC
- select SND_PCM
- select SND_VMASTER
- help
- Say Y here to include support for the integrated sound device.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-powermac.
-
-config SND_POWERMAC_AUTO_DRC
- bool "Toggle DRC automatically at headphone/line plug-in"
- depends on SND_POWERMAC
- default y
- help
- Say Y here to enable the automatic toggle of DRC (dynamic
- range compression) on Tumbler/Snapper.
- If this feature is enabled, DRC is turned off when the
- headphone/line jack is plugged, and turned on when unplugged.
-
- Note that you can turn on/off DRC manually even without this
- option.
-
-config SND_PS3
- tristate "PS3 Audio support"
- depends on PS3_PS3AV
- select SND_PCM
- default m
- help
- Say Y here to include support for audio on the PS3
-
- To compile this driver as a module, choose M here: the module
- will be called snd_ps3.
-
-config SND_PS3_DEFAULT_START_DELAY
- int "Startup delay time in ms"
- depends on SND_PS3
- default "2000"
-
-endif # SND_PPC
diff --git a/ANDROID_3.4.5/sound/ppc/Makefile b/ANDROID_3.4.5/sound/ppc/Makefile
deleted file mode 100644
index 679c45a8..00000000
--- a/ANDROID_3.4.5/sound/ppc/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o
-obj-$(CONFIG_SND_PS3) += snd_ps3.o
diff --git a/ANDROID_3.4.5/sound/ppc/awacs.c b/ANDROID_3.4.5/sound/ppc/awacs.c
deleted file mode 100644
index b3667938..00000000
--- a/ANDROID_3.4.5/sound/ppc/awacs.c
+++ /dev/null
@@ -1,1146 +0,0 @@
-/*
- * PMac AWACS lowlevel functions
- *
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- * code based on dmasound.c.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <asm/io.h>
-#include <asm/nvram.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include "pmac.h"
-
-
-#ifdef CONFIG_ADB_CUDA
-#define PMAC_AMP_AVAIL
-#endif
-
-#ifdef PMAC_AMP_AVAIL
-struct awacs_amp {
- unsigned char amp_master;
- unsigned char amp_vol[2][2];
- unsigned char amp_tone[2];
-};
-
-#define CHECK_CUDA_AMP() (sys_ctrler == SYS_CTRLER_CUDA)
-
-#endif /* PMAC_AMP_AVAIL */
-
-
-static void snd_pmac_screamer_wait(struct snd_pmac *chip)
-{
- long timeout = 2000;
- while (!(in_le32(&chip->awacs->codec_stat) & MASK_VALID)) {
- mdelay(1);
- if (! --timeout) {
- snd_printd("snd_pmac_screamer_wait timeout\n");
- break;
- }
- }
-}
-
-/*
- * write AWACS register
- */
-static void
-snd_pmac_awacs_write(struct snd_pmac *chip, int val)
-{
- long timeout = 5000000;
-
- if (chip->model == PMAC_SCREAMER)
- snd_pmac_screamer_wait(chip);
- out_le32(&chip->awacs->codec_ctrl, val | (chip->subframe << 22));
- while (in_le32(&chip->awacs->codec_ctrl) & MASK_NEWECMD) {
- if (! --timeout) {
- snd_printd("snd_pmac_awacs_write timeout\n");
- break;
- }
- }
-}
-
-static void
-snd_pmac_awacs_write_reg(struct snd_pmac *chip, int reg, int val)
-{
- snd_pmac_awacs_write(chip, val | (reg << 12));
- chip->awacs_reg[reg] = val;
-}
-
-static void
-snd_pmac_awacs_write_noreg(struct snd_pmac *chip, int reg, int val)
-{
- snd_pmac_awacs_write(chip, val | (reg << 12));
-}
-
-#ifdef CONFIG_PM
-/* Recalibrate chip */
-static void screamer_recalibrate(struct snd_pmac *chip)
-{
- if (chip->model != PMAC_SCREAMER)
- return;
-
- /* Sorry for the horrible delays... I hope to get that improved
- * by making the whole PM process asynchronous in a future version
- */
- snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
- if (chip->manufacturer == 0x1)
- /* delay for broken crystal part */
- msleep(750);
- snd_pmac_awacs_write_noreg(chip, 1,
- chip->awacs_reg[1] | MASK_RECALIBRATE |
- MASK_CMUTE | MASK_AMUTE);
- snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
- snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
-}
-
-#else
-#define screamer_recalibrate(chip) /* NOP */
-#endif
-
-
-/*
- * additional callback to set the pcm format
- */
-static void snd_pmac_awacs_set_format(struct snd_pmac *chip)
-{
- chip->awacs_reg[1] &= ~MASK_SAMPLERATE;
- chip->awacs_reg[1] |= chip->rate_index << 3;
- snd_pmac_awacs_write_reg(chip, 1, chip->awacs_reg[1]);
-}
-
-
-/*
- * AWACS volume callbacks
- */
-/*
- * volumes: 0-15 stereo
- */
-static int snd_pmac_awacs_info_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 15;
- return 0;
-}
-
-static int snd_pmac_awacs_get_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int lshift = (kcontrol->private_value >> 8) & 0xff;
- int inverted = (kcontrol->private_value >> 16) & 1;
- unsigned long flags;
- int vol[2];
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- vol[0] = (chip->awacs_reg[reg] >> lshift) & 0xf;
- vol[1] = chip->awacs_reg[reg] & 0xf;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (inverted) {
- vol[0] = 0x0f - vol[0];
- vol[1] = 0x0f - vol[1];
- }
- ucontrol->value.integer.value[0] = vol[0];
- ucontrol->value.integer.value[1] = vol[1];
- return 0;
-}
-
-static int snd_pmac_awacs_put_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int lshift = (kcontrol->private_value >> 8) & 0xff;
- int inverted = (kcontrol->private_value >> 16) & 1;
- int val, oldval;
- unsigned long flags;
- unsigned int vol[2];
-
- vol[0] = ucontrol->value.integer.value[0];
- vol[1] = ucontrol->value.integer.value[1];
- if (vol[0] > 0x0f || vol[1] > 0x0f)
- return -EINVAL;
- if (inverted) {
- vol[0] = 0x0f - vol[0];
- vol[1] = 0x0f - vol[1];
- }
- vol[0] &= 0x0f;
- vol[1] &= 0x0f;
- spin_lock_irqsave(&chip->reg_lock, flags);
- oldval = chip->awacs_reg[reg];
- val = oldval & ~(0xf | (0xf << lshift));
- val |= vol[0] << lshift;
- val |= vol[1];
- if (oldval != val)
- snd_pmac_awacs_write_reg(chip, reg, val);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return oldval != reg;
-}
-
-
-#define AWACS_VOLUME(xname, xreg, xshift, xinverted) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
- .info = snd_pmac_awacs_info_volume, \
- .get = snd_pmac_awacs_get_volume, \
- .put = snd_pmac_awacs_put_volume, \
- .private_value = (xreg) | ((xshift) << 8) | ((xinverted) << 16) }
-
-/*
- * mute master/ogain for AWACS: mono
- */
-static int snd_pmac_awacs_get_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int invert = (kcontrol->private_value >> 16) & 1;
- int val;
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- val = (chip->awacs_reg[reg] >> shift) & 1;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (invert)
- val = 1 - val;
- ucontrol->value.integer.value[0] = val;
- return 0;
-}
-
-static int snd_pmac_awacs_put_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int invert = (kcontrol->private_value >> 16) & 1;
- int mask = 1 << shift;
- int val, changed;
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- val = chip->awacs_reg[reg] & ~mask;
- if (ucontrol->value.integer.value[0] != invert)
- val |= mask;
- changed = chip->awacs_reg[reg] != val;
- if (changed)
- snd_pmac_awacs_write_reg(chip, reg, val);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return changed;
-}
-
-#define AWACS_SWITCH(xname, xreg, xshift, xinvert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
- .info = snd_pmac_boolean_mono_info, \
- .get = snd_pmac_awacs_get_switch, \
- .put = snd_pmac_awacs_put_switch, \
- .private_value = (xreg) | ((xshift) << 8) | ((xinvert) << 16) }
-
-
-#ifdef PMAC_AMP_AVAIL
-/*
- * controls for perch/whisper extension cards, e.g. G3 desktop
- *
- * TDA7433 connected via i2c address 0x45 (= 0x8a),
- * accessed through cuda
- */
-static void awacs_set_cuda(int reg, int val)
-{
- struct adb_request req;
- cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC, 0x8a,
- reg, val);
- while (! req.complete)
- cuda_poll();
-}
-
-/*
- * level = 0 - 14, 7 = 0 dB
- */
-static void awacs_amp_set_tone(struct awacs_amp *amp, int bass, int treble)
-{
- amp->amp_tone[0] = bass;
- amp->amp_tone[1] = treble;
- if (bass > 7)
- bass = (14 - bass) + 8;
- if (treble > 7)
- treble = (14 - treble) + 8;
- awacs_set_cuda(2, (bass << 4) | treble);
-}
-
-/*
- * vol = 0 - 31 (attenuation), 32 = mute bit, stereo
- */
-static int awacs_amp_set_vol(struct awacs_amp *amp, int index,
- int lvol, int rvol, int do_check)
-{
- if (do_check && amp->amp_vol[index][0] == lvol &&
- amp->amp_vol[index][1] == rvol)
- return 0;
- awacs_set_cuda(3 + index, lvol);
- awacs_set_cuda(5 + index, rvol);
- amp->amp_vol[index][0] = lvol;
- amp->amp_vol[index][1] = rvol;
- return 1;
-}
-
-/*
- * 0 = -79 dB, 79 = 0 dB, 99 = +20 dB
- */
-static void awacs_amp_set_master(struct awacs_amp *amp, int vol)
-{
- amp->amp_master = vol;
- if (vol <= 79)
- vol = 32 + (79 - vol);
- else
- vol = 32 - (vol - 79);
- awacs_set_cuda(1, vol);
-}
-
-static void awacs_amp_free(struct snd_pmac *chip)
-{
- struct awacs_amp *amp = chip->mixer_data;
- if (!amp)
- return;
- kfree(amp);
- chip->mixer_data = NULL;
- chip->mixer_free = NULL;
-}
-
-
-/*
- * mixer controls
- */
-static int snd_pmac_awacs_info_volume_amp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 31;
- return 0;
-}
-
-static int snd_pmac_awacs_get_volume_amp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- int index = kcontrol->private_value;
- struct awacs_amp *amp = chip->mixer_data;
-
- ucontrol->value.integer.value[0] = 31 - (amp->amp_vol[index][0] & 31);
- ucontrol->value.integer.value[1] = 31 - (amp->amp_vol[index][1] & 31);
- return 0;
-}
-
-static int snd_pmac_awacs_put_volume_amp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- int index = kcontrol->private_value;
- int vol[2];
- struct awacs_amp *amp = chip->mixer_data;
-
- vol[0] = (31 - (ucontrol->value.integer.value[0] & 31))
- | (amp->amp_vol[index][0] & 32);
- vol[1] = (31 - (ucontrol->value.integer.value[1] & 31))
- | (amp->amp_vol[index][1] & 32);
- return awacs_amp_set_vol(amp, index, vol[0], vol[1], 1);
-}
-
-static int snd_pmac_awacs_get_switch_amp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- int index = kcontrol->private_value;
- struct awacs_amp *amp = chip->mixer_data;
-
- ucontrol->value.integer.value[0] = (amp->amp_vol[index][0] & 32)
- ? 0 : 1;
- ucontrol->value.integer.value[1] = (amp->amp_vol[index][1] & 32)
- ? 0 : 1;
- return 0;
-}
-
-static int snd_pmac_awacs_put_switch_amp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- int index = kcontrol->private_value;
- int vol[2];
- struct awacs_amp *amp = chip->mixer_data;
-
- vol[0] = (ucontrol->value.integer.value[0] ? 0 : 32)
- | (amp->amp_vol[index][0] & 31);
- vol[1] = (ucontrol->value.integer.value[1] ? 0 : 32)
- | (amp->amp_vol[index][1] & 31);
- return awacs_amp_set_vol(amp, index, vol[0], vol[1], 1);
-}
-
-static int snd_pmac_awacs_info_tone_amp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 14;
- return 0;
-}
-
-static int snd_pmac_awacs_get_tone_amp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- int index = kcontrol->private_value;
- struct awacs_amp *amp = chip->mixer_data;
-
- ucontrol->value.integer.value[0] = amp->amp_tone[index];
- return 0;
-}
-
-static int snd_pmac_awacs_put_tone_amp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- int index = kcontrol->private_value;
- struct awacs_amp *amp = chip->mixer_data;
- unsigned int val;
-
- val = ucontrol->value.integer.value[0];
- if (val > 14)
- return -EINVAL;
- if (val != amp->amp_tone[index]) {
- amp->amp_tone[index] = val;
- awacs_amp_set_tone(amp, amp->amp_tone[0], amp->amp_tone[1]);
- return 1;
- }
- return 0;
-}
-
-static int snd_pmac_awacs_info_master_amp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 99;
- return 0;
-}
-
-static int snd_pmac_awacs_get_master_amp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct awacs_amp *amp = chip->mixer_data;
-
- ucontrol->value.integer.value[0] = amp->amp_master;
- return 0;
-}
-
-static int snd_pmac_awacs_put_master_amp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct awacs_amp *amp = chip->mixer_data;
- unsigned int val;
-
- val = ucontrol->value.integer.value[0];
- if (val > 99)
- return -EINVAL;
- if (val != amp->amp_master) {
- amp->amp_master = val;
- awacs_amp_set_master(amp, amp->amp_master);
- return 1;
- }
- return 0;
-}
-
-#define AMP_CH_SPK 0
-#define AMP_CH_HD 1
-
-static struct snd_kcontrol_new snd_pmac_awacs_amp_vol[] __devinitdata = {
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Speaker Playback Volume",
- .info = snd_pmac_awacs_info_volume_amp,
- .get = snd_pmac_awacs_get_volume_amp,
- .put = snd_pmac_awacs_put_volume_amp,
- .private_value = AMP_CH_SPK,
- },
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Headphone Playback Volume",
- .info = snd_pmac_awacs_info_volume_amp,
- .get = snd_pmac_awacs_get_volume_amp,
- .put = snd_pmac_awacs_put_volume_amp,
- .private_value = AMP_CH_HD,
- },
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Tone Control - Bass",
- .info = snd_pmac_awacs_info_tone_amp,
- .get = snd_pmac_awacs_get_tone_amp,
- .put = snd_pmac_awacs_put_tone_amp,
- .private_value = 0,
- },
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Tone Control - Treble",
- .info = snd_pmac_awacs_info_tone_amp,
- .get = snd_pmac_awacs_get_tone_amp,
- .put = snd_pmac_awacs_put_tone_amp,
- .private_value = 1,
- },
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Amp Master Playback Volume",
- .info = snd_pmac_awacs_info_master_amp,
- .get = snd_pmac_awacs_get_master_amp,
- .put = snd_pmac_awacs_put_master_amp,
- },
-};
-
-static struct snd_kcontrol_new snd_pmac_awacs_amp_hp_sw __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Headphone Playback Switch",
- .info = snd_pmac_boolean_stereo_info,
- .get = snd_pmac_awacs_get_switch_amp,
- .put = snd_pmac_awacs_put_switch_amp,
- .private_value = AMP_CH_HD,
-};
-
-static struct snd_kcontrol_new snd_pmac_awacs_amp_spk_sw __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Speaker Playback Switch",
- .info = snd_pmac_boolean_stereo_info,
- .get = snd_pmac_awacs_get_switch_amp,
- .put = snd_pmac_awacs_put_switch_amp,
- .private_value = AMP_CH_SPK,
-};
-
-#endif /* PMAC_AMP_AVAIL */
-
-
-/*
- * mic boost for screamer
- */
-static int snd_pmac_screamer_mic_boost_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 3;
- return 0;
-}
-
-static int snd_pmac_screamer_mic_boost_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- int val = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (chip->awacs_reg[6] & MASK_MIC_BOOST)
- val |= 2;
- if (chip->awacs_reg[0] & MASK_GAINLINE)
- val |= 1;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- ucontrol->value.integer.value[0] = val;
- return 0;
-}
-
-static int snd_pmac_screamer_mic_boost_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- int val0, val6;
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- val0 = chip->awacs_reg[0] & ~MASK_GAINLINE;
- val6 = chip->awacs_reg[6] & ~MASK_MIC_BOOST;
- if (ucontrol->value.integer.value[0] & 1)
- val0 |= MASK_GAINLINE;
- if (ucontrol->value.integer.value[0] & 2)
- val6 |= MASK_MIC_BOOST;
- if (val0 != chip->awacs_reg[0]) {
- snd_pmac_awacs_write_reg(chip, 0, val0);
- changed = 1;
- }
- if (val6 != chip->awacs_reg[6]) {
- snd_pmac_awacs_write_reg(chip, 6, val6);
- changed = 1;
- }
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return changed;
-}
-
-/*
- * lists of mixer elements
- */
-static struct snd_kcontrol_new snd_pmac_awacs_mixers[] __devinitdata = {
- AWACS_SWITCH("Master Capture Switch", 1, SHIFT_LOOPTHRU, 0),
- AWACS_VOLUME("Master Capture Volume", 0, 4, 0),
-/* AWACS_SWITCH("Unknown Playback Switch", 6, SHIFT_PAROUT0, 0), */
-};
-
-static struct snd_kcontrol_new snd_pmac_screamer_mixers_beige[] __devinitdata = {
- AWACS_VOLUME("Master Playback Volume", 2, 6, 1),
- AWACS_VOLUME("Play-through Playback Volume", 5, 6, 1),
- AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
- AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_LINE, 0),
-};
-
-static struct snd_kcontrol_new snd_pmac_screamer_mixers_lo[] __devinitdata = {
- AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
-};
-
-static struct snd_kcontrol_new snd_pmac_screamer_mixers_imac[] __devinitdata = {
- AWACS_VOLUME("Play-through Playback Volume", 5, 6, 1),
- AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
-};
-
-static struct snd_kcontrol_new snd_pmac_screamer_mixers_g4agp[] __devinitdata = {
- AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
- AWACS_VOLUME("Master Playback Volume", 5, 6, 1),
- AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
- AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
-};
-
-static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac7500[] __devinitdata = {
- AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
- AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
- AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
-};
-
-static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac5500[] __devinitdata = {
- AWACS_VOLUME("Headphone Playback Volume", 2, 6, 1),
-};
-
-static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac[] __devinitdata = {
- AWACS_VOLUME("Master Playback Volume", 2, 6, 1),
- AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
-};
-
-/* FIXME: is this correct order?
- * screamer (powerbook G3 pismo) seems to have different bits...
- */
-static struct snd_kcontrol_new snd_pmac_awacs_mixers2[] __devinitdata = {
- AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_LINE, 0),
- AWACS_SWITCH("Mic Capture Switch", 0, SHIFT_MUX_MIC, 0),
-};
-
-static struct snd_kcontrol_new snd_pmac_screamer_mixers2[] __devinitdata = {
- AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
- AWACS_SWITCH("Mic Capture Switch", 0, SHIFT_MUX_LINE, 0),
-};
-
-static struct snd_kcontrol_new snd_pmac_awacs_mixers2_pmac5500[] __devinitdata = {
- AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
-};
-
-static struct snd_kcontrol_new snd_pmac_awacs_master_sw __devinitdata =
-AWACS_SWITCH("Master Playback Switch", 1, SHIFT_HDMUTE, 1);
-
-static struct snd_kcontrol_new snd_pmac_awacs_master_sw_imac __devinitdata =
-AWACS_SWITCH("Line out Playback Switch", 1, SHIFT_HDMUTE, 1);
-
-static struct snd_kcontrol_new snd_pmac_awacs_master_sw_pmac5500 __devinitdata =
-AWACS_SWITCH("Headphone Playback Switch", 1, SHIFT_HDMUTE, 1);
-
-static struct snd_kcontrol_new snd_pmac_awacs_mic_boost[] __devinitdata = {
- AWACS_SWITCH("Mic Boost Capture Switch", 0, SHIFT_GAINLINE, 0),
-};
-
-static struct snd_kcontrol_new snd_pmac_screamer_mic_boost[] __devinitdata = {
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Mic Boost Capture Volume",
- .info = snd_pmac_screamer_mic_boost_info,
- .get = snd_pmac_screamer_mic_boost_get,
- .put = snd_pmac_screamer_mic_boost_put,
- },
-};
-
-static struct snd_kcontrol_new snd_pmac_awacs_mic_boost_pmac7500[] __devinitdata =
-{
- AWACS_SWITCH("Line Boost Capture Switch", 0, SHIFT_GAINLINE, 0),
-};
-
-static struct snd_kcontrol_new snd_pmac_screamer_mic_boost_beige[] __devinitdata =
-{
- AWACS_SWITCH("Line Boost Capture Switch", 0, SHIFT_GAINLINE, 0),
- AWACS_SWITCH("CD Boost Capture Switch", 6, SHIFT_MIC_BOOST, 0),
-};
-
-static struct snd_kcontrol_new snd_pmac_screamer_mic_boost_imac[] __devinitdata =
-{
- AWACS_SWITCH("Line Boost Capture Switch", 0, SHIFT_GAINLINE, 0),
- AWACS_SWITCH("Mic Boost Capture Switch", 6, SHIFT_MIC_BOOST, 0),
-};
-
-static struct snd_kcontrol_new snd_pmac_awacs_speaker_vol[] __devinitdata = {
- AWACS_VOLUME("Speaker Playback Volume", 4, 6, 1),
-};
-
-static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw __devinitdata =
-AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1);
-
-static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac1 __devinitdata =
-AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_PAROUT1, 1);
-
-static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac2 __devinitdata =
-AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_PAROUT1, 0);
-
-
-/*
- * add new mixer elements to the card
- */
-static int build_mixers(struct snd_pmac *chip, int nums,
- struct snd_kcontrol_new *mixers)
-{
- int i, err;
-
- for (i = 0; i < nums; i++) {
- err = snd_ctl_add(chip->card, snd_ctl_new1(&mixers[i], chip));
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-
-/*
- * restore all registers
- */
-static void awacs_restore_all_regs(struct snd_pmac *chip)
-{
- snd_pmac_awacs_write_noreg(chip, 0, chip->awacs_reg[0]);
- snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
- snd_pmac_awacs_write_noreg(chip, 2, chip->awacs_reg[2]);
- snd_pmac_awacs_write_noreg(chip, 4, chip->awacs_reg[4]);
- if (chip->model == PMAC_SCREAMER) {
- snd_pmac_awacs_write_noreg(chip, 5, chip->awacs_reg[5]);
- snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
- snd_pmac_awacs_write_noreg(chip, 7, chip->awacs_reg[7]);
- }
-}
-
-#ifdef CONFIG_PM
-static void snd_pmac_awacs_suspend(struct snd_pmac *chip)
-{
- snd_pmac_awacs_write_noreg(chip, 1, (chip->awacs_reg[1]
- | MASK_AMUTE | MASK_CMUTE));
-}
-
-static void snd_pmac_awacs_resume(struct snd_pmac *chip)
-{
- if (of_machine_is_compatible("PowerBook3,1")
- || of_machine_is_compatible("PowerBook3,2")) {
- msleep(100);
- snd_pmac_awacs_write_reg(chip, 1,
- chip->awacs_reg[1] & ~MASK_PAROUT);
- msleep(300);
- }
-
- awacs_restore_all_regs(chip);
- if (chip->model == PMAC_SCREAMER) {
- /* reset power bits in reg 6 */
- mdelay(5);
- snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
- }
- screamer_recalibrate(chip);
-#ifdef PMAC_AMP_AVAIL
- if (chip->mixer_data) {
- struct awacs_amp *amp = chip->mixer_data;
- awacs_amp_set_vol(amp, 0,
- amp->amp_vol[0][0], amp->amp_vol[0][1], 0);
- awacs_amp_set_vol(amp, 1,
- amp->amp_vol[1][0], amp->amp_vol[1][1], 0);
- awacs_amp_set_tone(amp, amp->amp_tone[0], amp->amp_tone[1]);
- awacs_amp_set_master(amp, amp->amp_master);
- }
-#endif
-}
-#endif /* CONFIG_PM */
-
-#define IS_PM7500 (of_machine_is_compatible("AAPL,7500") \
- || of_machine_is_compatible("AAPL,8500") \
- || of_machine_is_compatible("AAPL,9500"))
-#define IS_PM5500 (of_machine_is_compatible("AAPL,e411"))
-#define IS_BEIGE (of_machine_is_compatible("AAPL,Gossamer"))
-#define IS_IMAC1 (of_machine_is_compatible("PowerMac2,1"))
-#define IS_IMAC2 (of_machine_is_compatible("PowerMac2,2") \
- || of_machine_is_compatible("PowerMac4,1"))
-#define IS_G4AGP (of_machine_is_compatible("PowerMac3,1"))
-#define IS_LOMBARD (of_machine_is_compatible("PowerBook1,1"))
-
-static int imac1, imac2;
-
-#ifdef PMAC_SUPPORT_AUTOMUTE
-/*
- * auto-mute stuffs
- */
-static int snd_pmac_awacs_detect_headphone(struct snd_pmac *chip)
-{
- return (in_le32(&chip->awacs->codec_stat) & chip->hp_stat_mask) ? 1 : 0;
-}
-
-#ifdef PMAC_AMP_AVAIL
-static int toggle_amp_mute(struct awacs_amp *amp, int index, int mute)
-{
- int vol[2];
- vol[0] = amp->amp_vol[index][0] & 31;
- vol[1] = amp->amp_vol[index][1] & 31;
- if (mute) {
- vol[0] |= 32;
- vol[1] |= 32;
- }
- return awacs_amp_set_vol(amp, index, vol[0], vol[1], 1);
-}
-#endif
-
-static void snd_pmac_awacs_update_automute(struct snd_pmac *chip, int do_notify)
-{
- if (chip->auto_mute) {
-#ifdef PMAC_AMP_AVAIL
- if (chip->mixer_data) {
- struct awacs_amp *amp = chip->mixer_data;
- int changed;
- if (snd_pmac_awacs_detect_headphone(chip)) {
- changed = toggle_amp_mute(amp, AMP_CH_HD, 0);
- changed |= toggle_amp_mute(amp, AMP_CH_SPK, 1);
- } else {
- changed = toggle_amp_mute(amp, AMP_CH_HD, 1);
- changed |= toggle_amp_mute(amp, AMP_CH_SPK, 0);
- }
- if (do_notify && ! changed)
- return;
- } else
-#endif
- {
- int reg = chip->awacs_reg[1]
- | (MASK_HDMUTE | MASK_SPKMUTE);
- if (imac1) {
- reg &= ~MASK_SPKMUTE;
- reg |= MASK_PAROUT1;
- } else if (imac2) {
- reg &= ~MASK_SPKMUTE;
- reg &= ~MASK_PAROUT1;
- }
- if (snd_pmac_awacs_detect_headphone(chip))
- reg &= ~MASK_HDMUTE;
- else if (imac1)
- reg &= ~MASK_PAROUT1;
- else if (imac2)
- reg |= MASK_PAROUT1;
- else
- reg &= ~MASK_SPKMUTE;
- if (do_notify && reg == chip->awacs_reg[1])
- return;
- snd_pmac_awacs_write_reg(chip, 1, reg);
- }
- if (do_notify) {
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->master_sw_ctl->id);
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->speaker_sw_ctl->id);
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->hp_detect_ctl->id);
- }
- }
-}
-#endif /* PMAC_SUPPORT_AUTOMUTE */
-
-
-/*
- * initialize chip
- */
-int __devinit
-snd_pmac_awacs_init(struct snd_pmac *chip)
-{
- int pm7500 = IS_PM7500;
- int pm5500 = IS_PM5500;
- int beige = IS_BEIGE;
- int g4agp = IS_G4AGP;
- int lombard = IS_LOMBARD;
- int imac;
- int err, vol;
- struct snd_kcontrol *vmaster_sw, *vmaster_vol;
- struct snd_kcontrol *master_vol, *speaker_vol;
-
- imac1 = IS_IMAC1;
- imac2 = IS_IMAC2;
- imac = imac1 || imac2;
- /* looks like MASK_GAINLINE triggers something, so we set here
- * as start-up
- */
- chip->awacs_reg[0] = MASK_MUX_CD | 0xff | MASK_GAINLINE;
- chip->awacs_reg[1] = MASK_CMUTE | MASK_AMUTE;
- /* FIXME: Only machines with external SRS module need MASK_PAROUT */
- if (chip->has_iic || chip->device_id == 0x5 ||
- /* chip->_device_id == 0x8 || */
- chip->device_id == 0xb)
- chip->awacs_reg[1] |= MASK_PAROUT;
- /* get default volume from nvram */
- // vol = (~nvram_read_byte(0x1308) & 7) << 1;
- // vol = ((pmac_xpram_read( 8 ) & 7 ) << 1 );
- vol = 0x0f; /* no, on alsa, muted as default */
- vol = vol + (vol << 6);
- chip->awacs_reg[2] = vol;
- chip->awacs_reg[4] = vol;
- if (chip->model == PMAC_SCREAMER) {
- /* FIXME: screamer has loopthru vol control */
- chip->awacs_reg[5] = vol;
- /* FIXME: maybe should be vol << 3 for PCMCIA speaker */
- chip->awacs_reg[6] = MASK_MIC_BOOST;
- chip->awacs_reg[7] = 0;
- }
-
- awacs_restore_all_regs(chip);
- chip->manufacturer = (in_le32(&chip->awacs->codec_stat) >> 8) & 0xf;
- screamer_recalibrate(chip);
-
- chip->revision = (in_le32(&chip->awacs->codec_stat) >> 12) & 0xf;
-#ifdef PMAC_AMP_AVAIL
- if (chip->revision == 3 && chip->has_iic && CHECK_CUDA_AMP()) {
- struct awacs_amp *amp = kzalloc(sizeof(*amp), GFP_KERNEL);
- if (! amp)
- return -ENOMEM;
- chip->mixer_data = amp;
- chip->mixer_free = awacs_amp_free;
- /* mute and zero vol */
- awacs_amp_set_vol(amp, 0, 63, 63, 0);
- awacs_amp_set_vol(amp, 1, 63, 63, 0);
- awacs_amp_set_tone(amp, 7, 7); /* 0 dB */
- awacs_amp_set_master(amp, 79); /* 0 dB */
- }
-#endif /* PMAC_AMP_AVAIL */
-
- if (chip->hp_stat_mask == 0) {
- /* set headphone-jack detection bit */
- switch (chip->model) {
- case PMAC_AWACS:
- chip->hp_stat_mask = pm7500 || pm5500 ? MASK_HDPCONN
- : MASK_LOCONN;
- break;
- case PMAC_SCREAMER:
- switch (chip->device_id) {
- case 0x08:
- case 0x0B:
- chip->hp_stat_mask = imac
- ? MASK_LOCONN_IMAC |
- MASK_HDPLCONN_IMAC |
- MASK_HDPRCONN_IMAC
- : MASK_HDPCONN;
- break;
- case 0x00:
- case 0x05:
- chip->hp_stat_mask = MASK_LOCONN;
- break;
- default:
- chip->hp_stat_mask = MASK_HDPCONN;
- break;
- }
- break;
- default:
- snd_BUG();
- break;
- }
- }
-
- /*
- * build mixers
- */
- strcpy(chip->card->mixername, "PowerMac AWACS");
-
- err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_mixers),
- snd_pmac_awacs_mixers);
- if (err < 0)
- return err;
- if (beige || g4agp)
- ;
- else if (chip->model == PMAC_SCREAMER || pm5500)
- err = build_mixers(chip, ARRAY_SIZE(snd_pmac_screamer_mixers2),
- snd_pmac_screamer_mixers2);
- else if (!pm7500)
- err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_mixers2),
- snd_pmac_awacs_mixers2);
- if (err < 0)
- return err;
- if (pm5500) {
- err = build_mixers(chip,
- ARRAY_SIZE(snd_pmac_awacs_mixers2_pmac5500),
- snd_pmac_awacs_mixers2_pmac5500);
- if (err < 0)
- return err;
- }
- if (pm7500)
- err = build_mixers(chip,
- ARRAY_SIZE(snd_pmac_awacs_mixers_pmac7500),
- snd_pmac_awacs_mixers_pmac7500);
- else if (pm5500)
- err = snd_ctl_add(chip->card,
- (master_vol = snd_ctl_new1(snd_pmac_awacs_mixers_pmac5500,
- chip)));
- else if (beige)
- err = build_mixers(chip,
- ARRAY_SIZE(snd_pmac_screamer_mixers_beige),
- snd_pmac_screamer_mixers_beige);
- else if (imac || lombard) {
- err = snd_ctl_add(chip->card,
- (master_vol = snd_ctl_new1(snd_pmac_screamer_mixers_lo,
- chip)));
- if (err < 0)
- return err;
- err = build_mixers(chip,
- ARRAY_SIZE(snd_pmac_screamer_mixers_imac),
- snd_pmac_screamer_mixers_imac);
- } else if (g4agp)
- err = build_mixers(chip,
- ARRAY_SIZE(snd_pmac_screamer_mixers_g4agp),
- snd_pmac_screamer_mixers_g4agp);
- else
- err = build_mixers(chip,
- ARRAY_SIZE(snd_pmac_awacs_mixers_pmac),
- snd_pmac_awacs_mixers_pmac);
- if (err < 0)
- return err;
- chip->master_sw_ctl = snd_ctl_new1((pm7500 || imac || g4agp || lombard)
- ? &snd_pmac_awacs_master_sw_imac
- : pm5500
- ? &snd_pmac_awacs_master_sw_pmac5500
- : &snd_pmac_awacs_master_sw, chip);
- err = snd_ctl_add(chip->card, chip->master_sw_ctl);
- if (err < 0)
- return err;
-#ifdef PMAC_AMP_AVAIL
- if (chip->mixer_data) {
- /* use amplifier. the signal is connected from route A
- * to the amp. the amp has its headphone and speaker
- * volumes and mute switches, so we use them instead of
- * screamer registers.
- * in this case, it seems the route C is not used.
- */
- err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_amp_vol),
- snd_pmac_awacs_amp_vol);
- if (err < 0)
- return err;
- /* overwrite */
- chip->master_sw_ctl = snd_ctl_new1(&snd_pmac_awacs_amp_hp_sw,
- chip);
- err = snd_ctl_add(chip->card, chip->master_sw_ctl);
- if (err < 0)
- return err;
- chip->speaker_sw_ctl = snd_ctl_new1(&snd_pmac_awacs_amp_spk_sw,
- chip);
- err = snd_ctl_add(chip->card, chip->speaker_sw_ctl);
- if (err < 0)
- return err;
- } else
-#endif /* PMAC_AMP_AVAIL */
- {
- /* route A = headphone, route C = speaker */
- err = snd_ctl_add(chip->card,
- (speaker_vol = snd_ctl_new1(snd_pmac_awacs_speaker_vol,
- chip)));
- if (err < 0)
- return err;
- chip->speaker_sw_ctl = snd_ctl_new1(imac1
- ? &snd_pmac_awacs_speaker_sw_imac1
- : imac2
- ? &snd_pmac_awacs_speaker_sw_imac2
- : &snd_pmac_awacs_speaker_sw, chip);
- err = snd_ctl_add(chip->card, chip->speaker_sw_ctl);
- if (err < 0)
- return err;
- }
-
- if (pm5500 || imac || lombard) {
- vmaster_sw = snd_ctl_make_virtual_master(
- "Master Playback Switch", (unsigned int *) NULL);
- err = snd_ctl_add_slave_uncached(vmaster_sw,
- chip->master_sw_ctl);
- if (err < 0)
- return err;
- err = snd_ctl_add_slave_uncached(vmaster_sw,
- chip->speaker_sw_ctl);
- if (err < 0)
- return err;
- err = snd_ctl_add(chip->card, vmaster_sw);
- if (err < 0)
- return err;
- vmaster_vol = snd_ctl_make_virtual_master(
- "Master Playback Volume", (unsigned int *) NULL);
- err = snd_ctl_add_slave(vmaster_vol, master_vol);
- if (err < 0)
- return err;
- err = snd_ctl_add_slave(vmaster_vol, speaker_vol);
- if (err < 0)
- return err;
- err = snd_ctl_add(chip->card, vmaster_vol);
- if (err < 0)
- return err;
- }
-
- if (beige || g4agp)
- err = build_mixers(chip,
- ARRAY_SIZE(snd_pmac_screamer_mic_boost_beige),
- snd_pmac_screamer_mic_boost_beige);
- else if (imac)
- err = build_mixers(chip,
- ARRAY_SIZE(snd_pmac_screamer_mic_boost_imac),
- snd_pmac_screamer_mic_boost_imac);
- else if (chip->model == PMAC_SCREAMER)
- err = build_mixers(chip,
- ARRAY_SIZE(snd_pmac_screamer_mic_boost),
- snd_pmac_screamer_mic_boost);
- else if (pm7500)
- err = build_mixers(chip,
- ARRAY_SIZE(snd_pmac_awacs_mic_boost_pmac7500),
- snd_pmac_awacs_mic_boost_pmac7500);
- else
- err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_mic_boost),
- snd_pmac_awacs_mic_boost);
- if (err < 0)
- return err;
-
- /*
- * set lowlevel callbacks
- */
- chip->set_format = snd_pmac_awacs_set_format;
-#ifdef CONFIG_PM
- chip->suspend = snd_pmac_awacs_suspend;
- chip->resume = snd_pmac_awacs_resume;
-#endif
-#ifdef PMAC_SUPPORT_AUTOMUTE
- err = snd_pmac_add_automute(chip);
- if (err < 0)
- return err;
- chip->detect_headphone = snd_pmac_awacs_detect_headphone;
- chip->update_automute = snd_pmac_awacs_update_automute;
- snd_pmac_awacs_update_automute(chip, 0); /* update the status only */
-#endif
- if (chip->model == PMAC_SCREAMER) {
- snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
- snd_pmac_awacs_write_noreg(chip, 0, chip->awacs_reg[0]);
- }
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/ppc/awacs.h b/ANDROID_3.4.5/sound/ppc/awacs.h
deleted file mode 100644
index c33e6a53..00000000
--- a/ANDROID_3.4.5/sound/ppc/awacs.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Driver for PowerMac AWACS onboard soundchips
- * Copyright (c) 2001 by Takashi Iwai <tiwai@suse.de>
- * based on dmasound.c.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#ifndef __AWACS_H
-#define __AWACS_H
-
-/*******************************/
-/* AWACs Audio Register Layout */
-/*******************************/
-
-struct awacs_regs {
- unsigned control; /* Audio control register */
- unsigned pad0[3];
- unsigned codec_ctrl; /* Codec control register */
- unsigned pad1[3];
- unsigned codec_stat; /* Codec status register */
- unsigned pad2[3];
- unsigned clip_count; /* Clipping count register */
- unsigned pad3[3];
- unsigned byteswap; /* Data is little-endian if 1 */
-};
-
-/*******************/
-/* Audio Bit Masks */
-/*******************/
-
-/* Audio Control Reg Bit Masks */
-/* ----- ------- --- --- ----- */
-#define MASK_ISFSEL (0xf) /* Input SubFrame Select */
-#define MASK_OSFSEL (0xf << 4) /* Output SubFrame Select */
-#define MASK_RATE (0x7 << 8) /* Sound Rate */
-#define MASK_CNTLERR (0x1 << 11) /* Error */
-#define MASK_PORTCHG (0x1 << 12) /* Port Change */
-#define MASK_IEE (0x1 << 13) /* Enable Interrupt on Error */
-#define MASK_IEPC (0x1 << 14) /* Enable Interrupt on Port Change */
-#define MASK_SSFSEL (0x3 << 15) /* Status SubFrame Select */
-
-/* Audio Codec Control Reg Bit Masks */
-/* ----- ----- ------- --- --- ----- */
-#define MASK_NEWECMD (0x1 << 24) /* Lock: don't write to reg when 1 */
-#define MASK_EMODESEL (0x3 << 22) /* Send info out on which frame? */
-#define MASK_EXMODEADDR (0x3ff << 12) /* Extended Mode Address -- 10 bits */
-#define MASK_EXMODEDATA (0xfff) /* Extended Mode Data -- 12 bits */
-
-/* Audio Codec Control Address Values / Masks */
-/* ----- ----- ------- ------- ------ - ----- */
-#define MASK_ADDR0 (0x0 << 12) /* Expanded Data Mode Address 0 */
-#define MASK_ADDR_MUX MASK_ADDR0 /* Mux Control */
-#define MASK_ADDR_GAIN MASK_ADDR0
-
-#define MASK_ADDR1 (0x1 << 12) /* Expanded Data Mode Address 1 */
-#define MASK_ADDR_MUTE MASK_ADDR1
-#define MASK_ADDR_RATE MASK_ADDR1
-
-#define MASK_ADDR2 (0x2 << 12) /* Expanded Data Mode Address 2 */
-#define MASK_ADDR_VOLA MASK_ADDR2 /* Volume Control A -- Headphones */
-#define MASK_ADDR_VOLHD MASK_ADDR2
-
-#define MASK_ADDR4 (0x4 << 12) /* Expanded Data Mode Address 4 */
-#define MASK_ADDR_VOLC MASK_ADDR4 /* Volume Control C -- Speaker */
-#define MASK_ADDR_VOLSPK MASK_ADDR4
-
-/* additional registers of screamer */
-#define MASK_ADDR5 (0x5 << 12) /* Expanded Data Mode Address 5 */
-#define MASK_ADDR6 (0x6 << 12) /* Expanded Data Mode Address 6 */
-#define MASK_ADDR7 (0x7 << 12) /* Expanded Data Mode Address 7 */
-
-/* Address 0 Bit Masks & Macros */
-/* ------- - --- ----- - ------ */
-#define MASK_GAINRIGHT (0xf) /* Gain Right Mask */
-#define MASK_GAINLEFT (0xf << 4) /* Gain Left Mask */
-#define MASK_GAINLINE (0x1 << 8) /* Disable Mic preamp */
-#define MASK_GAINMIC (0x0 << 8) /* Enable Mic preamp */
-#define MASK_MUX_CD (0x1 << 9) /* Select CD in MUX */
-#define MASK_MUX_MIC (0x1 << 10) /* Select Mic in MUX */
-#define MASK_MUX_AUDIN (0x1 << 11) /* Select Audio In in MUX */
-#define MASK_MUX_LINE MASK_MUX_AUDIN
-#define SHIFT_GAINLINE 8
-#define SHIFT_MUX_CD 9
-#define SHIFT_MUX_MIC 10
-#define SHIFT_MUX_LINE 11
-
-#define GAINRIGHT(x) ((x) & MASK_GAINRIGHT)
-#define GAINLEFT(x) (((x) << 4) & MASK_GAINLEFT)
-
-/* Address 1 Bit Masks */
-/* ------- - --- ----- */
-#define MASK_ADDR1RES1 (0x3) /* Reserved */
-#define MASK_RECALIBRATE (0x1 << 2) /* Recalibrate */
-#define MASK_SAMPLERATE (0x7 << 3) /* Sample Rate: */
-#define MASK_LOOPTHRU (0x1 << 6) /* Loopthrough Enable */
-#define SHIFT_LOOPTHRU 6
-#define MASK_CMUTE (0x1 << 7) /* Output C (Speaker) Mute when 1 */
-#define MASK_SPKMUTE MASK_CMUTE
-#define SHIFT_SPKMUTE 7
-#define MASK_ADDR1RES2 (0x1 << 8) /* Reserved */
-#define MASK_AMUTE (0x1 << 9) /* Output A (Headphone) Mute when 1 */
-#define MASK_HDMUTE MASK_AMUTE
-#define SHIFT_HDMUTE 9
-#define MASK_PAROUT (0x3 << 10) /* Parallel Out (???) */
-#define MASK_PAROUT0 (0x1 << 10) /* Parallel Out (???) */
-#define MASK_PAROUT1 (0x1 << 11) /* Parallel Out (enable speaker) */
-#define SHIFT_PAROUT 10
-#define SHIFT_PAROUT0 10
-#define SHIFT_PAROUT1 11
-
-#define SAMPLERATE_48000 (0x0 << 3) /* 48 or 44.1 kHz */
-#define SAMPLERATE_32000 (0x1 << 3) /* 32 or 29.4 kHz */
-#define SAMPLERATE_24000 (0x2 << 3) /* 24 or 22.05 kHz */
-#define SAMPLERATE_19200 (0x3 << 3) /* 19.2 or 17.64 kHz */
-#define SAMPLERATE_16000 (0x4 << 3) /* 16 or 14.7 kHz */
-#define SAMPLERATE_12000 (0x5 << 3) /* 12 or 11.025 kHz */
-#define SAMPLERATE_9600 (0x6 << 3) /* 9.6 or 8.82 kHz */
-#define SAMPLERATE_8000 (0x7 << 3) /* 8 or 7.35 kHz */
-
-/* Address 2 & 4 Bit Masks & Macros */
-/* ------- - - - --- ----- - ------ */
-#define MASK_OUTVOLRIGHT (0xf) /* Output Right Volume */
-#define MASK_ADDR2RES1 (0x2 << 4) /* Reserved */
-#define MASK_ADDR4RES1 MASK_ADDR2RES1
-#define MASK_OUTVOLLEFT (0xf << 6) /* Output Left Volume */
-#define MASK_ADDR2RES2 (0x2 << 10) /* Reserved */
-#define MASK_ADDR4RES2 MASK_ADDR2RES2
-
-#define VOLRIGHT(x) (((~(x)) & MASK_OUTVOLRIGHT))
-#define VOLLEFT(x) (((~(x)) << 6) & MASK_OUTVOLLEFT)
-
-/* address 6 */
-#define MASK_MIC_BOOST (0x4) /* screamer mic boost */
-#define SHIFT_MIC_BOOST 2
-
-/* Audio Codec Status Reg Bit Masks */
-/* ----- ----- ------ --- --- ----- */
-#define MASK_EXTEND (0x1 << 23) /* Extend */
-#define MASK_VALID (0x1 << 22) /* Valid Data? */
-#define MASK_OFLEFT (0x1 << 21) /* Overflow Left */
-#define MASK_OFRIGHT (0x1 << 20) /* Overflow Right */
-#define MASK_ERRCODE (0xf << 16) /* Error Code */
-#define MASK_REVISION (0xf << 12) /* Revision Number */
-#define MASK_MFGID (0xf << 8) /* Mfg. ID */
-#define MASK_CODSTATRES (0xf << 4) /* bits 4 - 7 reserved */
-#define MASK_INSENSE (0xf) /* port sense bits: */
-#define MASK_HDPCONN 8 /* headphone plugged in */
-#define MASK_LOCONN 4 /* line-out plugged in */
-#define MASK_LICONN 2 /* line-in plugged in */
-#define MASK_MICCONN 1 /* microphone plugged in */
-#define MASK_LICONN_IMAC 8 /* line-in plugged in */
-#define MASK_HDPRCONN_IMAC 4 /* headphone right plugged in */
-#define MASK_HDPLCONN_IMAC 2 /* headphone left plugged in */
-#define MASK_LOCONN_IMAC 1 /* line-out plugged in */
-
-/* Clipping Count Reg Bit Masks */
-/* -------- ----- --- --- ----- */
-#define MASK_CLIPLEFT (0xff << 7) /* Clipping Count, Left Channel */
-#define MASK_CLIPRIGHT (0xff) /* Clipping Count, Right Channel */
-
-/* DBDMA ChannelStatus Bit Masks */
-/* ----- ------------- --- ----- */
-#define MASK_CSERR (0x1 << 7) /* Error */
-#define MASK_EOI (0x1 << 6) /* End of Input --
- only for Input Channel */
-#define MASK_CSUNUSED (0x1f << 1) /* bits 1-5 not used */
-#define MASK_WAIT (0x1) /* Wait */
-
-/* Various Rates */
-/* ------- ----- */
-#define RATE_48000 (0x0 << 8) /* 48 kHz */
-#define RATE_44100 (0x0 << 8) /* 44.1 kHz */
-#define RATE_32000 (0x1 << 8) /* 32 kHz */
-#define RATE_29400 (0x1 << 8) /* 29.4 kHz */
-#define RATE_24000 (0x2 << 8) /* 24 kHz */
-#define RATE_22050 (0x2 << 8) /* 22.05 kHz */
-#define RATE_19200 (0x3 << 8) /* 19.2 kHz */
-#define RATE_17640 (0x3 << 8) /* 17.64 kHz */
-#define RATE_16000 (0x4 << 8) /* 16 kHz */
-#define RATE_14700 (0x4 << 8) /* 14.7 kHz */
-#define RATE_12000 (0x5 << 8) /* 12 kHz */
-#define RATE_11025 (0x5 << 8) /* 11.025 kHz */
-#define RATE_9600 (0x6 << 8) /* 9.6 kHz */
-#define RATE_8820 (0x6 << 8) /* 8.82 kHz */
-#define RATE_8000 (0x7 << 8) /* 8 kHz */
-#define RATE_7350 (0x7 << 8) /* 7.35 kHz */
-
-#define RATE_LOW 1 /* HIGH = 48kHz, etc; LOW = 44.1kHz, etc. */
-
-
-#endif /* __AWACS_H */
diff --git a/ANDROID_3.4.5/sound/ppc/beep.c b/ANDROID_3.4.5/sound/ppc/beep.c
deleted file mode 100644
index a9d35078..00000000
--- a/ANDROID_3.4.5/sound/ppc/beep.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Beep using pcm
- *
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/input.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include "pmac.h"
-
-struct pmac_beep {
- int running; /* boolean */
- int volume; /* mixer volume: 0-100 */
- int volume_play; /* currently playing volume */
- int hz;
- int nsamples;
- short *buf; /* allocated wave buffer */
- dma_addr_t addr; /* physical address of buffer */
- struct input_dev *dev;
-};
-
-/*
- * stop beep if running
- */
-void snd_pmac_beep_stop(struct snd_pmac *chip)
-{
- struct pmac_beep *beep = chip->beep;
- if (beep && beep->running) {
- beep->running = 0;
- snd_pmac_beep_dma_stop(chip);
- }
-}
-
-/*
- * Stuff for outputting a beep. The values range from -327 to +327
- * so we can multiply by an amplitude in the range 0..100 to get a
- * signed short value to put in the output buffer.
- */
-static short beep_wform[256] = {
- 0, 40, 79, 117, 153, 187, 218, 245,
- 269, 288, 304, 316, 323, 327, 327, 324,
- 318, 310, 299, 288, 275, 262, 249, 236,
- 224, 213, 204, 196, 190, 186, 183, 182,
- 182, 183, 186, 189, 192, 196, 200, 203,
- 206, 208, 209, 209, 209, 207, 204, 201,
- 197, 193, 188, 183, 179, 174, 170, 166,
- 163, 161, 160, 159, 159, 160, 161, 162,
- 164, 166, 168, 169, 171, 171, 171, 170,
- 169, 167, 163, 159, 155, 150, 144, 139,
- 133, 128, 122, 117, 113, 110, 107, 105,
- 103, 103, 103, 103, 104, 104, 105, 105,
- 105, 103, 101, 97, 92, 86, 78, 68,
- 58, 45, 32, 18, 3, -11, -26, -41,
- -55, -68, -79, -88, -95, -100, -102, -102,
- -99, -93, -85, -75, -62, -48, -33, -16,
- 0, 16, 33, 48, 62, 75, 85, 93,
- 99, 102, 102, 100, 95, 88, 79, 68,
- 55, 41, 26, 11, -3, -18, -32, -45,
- -58, -68, -78, -86, -92, -97, -101, -103,
- -105, -105, -105, -104, -104, -103, -103, -103,
- -103, -105, -107, -110, -113, -117, -122, -128,
- -133, -139, -144, -150, -155, -159, -163, -167,
- -169, -170, -171, -171, -171, -169, -168, -166,
- -164, -162, -161, -160, -159, -159, -160, -161,
- -163, -166, -170, -174, -179, -183, -188, -193,
- -197, -201, -204, -207, -209, -209, -209, -208,
- -206, -203, -200, -196, -192, -189, -186, -183,
- -182, -182, -183, -186, -190, -196, -204, -213,
- -224, -236, -249, -262, -275, -288, -299, -310,
- -318, -324, -327, -327, -323, -316, -304, -288,
- -269, -245, -218, -187, -153, -117, -79, -40,
-};
-
-#define BEEP_SRATE 22050 /* 22050 Hz sample rate */
-#define BEEP_BUFLEN 512
-#define BEEP_VOLUME 15 /* 0 - 100 */
-
-static int snd_pmac_beep_event(struct input_dev *dev, unsigned int type,
- unsigned int code, int hz)
-{
- struct snd_pmac *chip;
- struct pmac_beep *beep;
- unsigned long flags;
- int beep_speed = 0;
- int srate;
- int period, ncycles, nsamples;
- int i, j, f;
- short *p;
-
- if (type != EV_SND)
- return -1;
-
- switch (code) {
- case SND_BELL: if (hz) hz = 1000;
- case SND_TONE: break;
- default: return -1;
- }
-
- chip = input_get_drvdata(dev);
- if (! chip || (beep = chip->beep) == NULL)
- return -1;
-
- if (! hz) {
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (beep->running)
- snd_pmac_beep_stop(chip);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
- }
-
- beep_speed = snd_pmac_rate_index(chip, &chip->playback, BEEP_SRATE);
- srate = chip->freq_table[beep_speed];
-
- if (hz <= srate / BEEP_BUFLEN || hz > srate / 2)
- hz = 1000;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- if (chip->playback.running || chip->capture.running || beep->running) {
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
- }
- beep->running = 1;
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- if (hz == beep->hz && beep->volume == beep->volume_play) {
- nsamples = beep->nsamples;
- } else {
- period = srate * 256 / hz; /* fixed point */
- ncycles = BEEP_BUFLEN * 256 / period;
- nsamples = (period * ncycles) >> 8;
- f = ncycles * 65536 / nsamples;
- j = 0;
- p = beep->buf;
- for (i = 0; i < nsamples; ++i, p += 2) {
- p[0] = p[1] = beep_wform[j >> 8] * beep->volume;
- j = (j + f) & 0xffff;
- }
- beep->hz = hz;
- beep->volume_play = beep->volume;
- beep->nsamples = nsamples;
- }
-
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_pmac_beep_dma_start(chip, beep->nsamples * 4, beep->addr, beep_speed);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return 0;
-}
-
-/*
- * beep volume mixer
- */
-
-static int snd_pmac_info_beep(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 100;
- return 0;
-}
-
-static int snd_pmac_get_beep(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- if (snd_BUG_ON(!chip->beep))
- return -ENXIO;
- ucontrol->value.integer.value[0] = chip->beep->volume;
- return 0;
-}
-
-static int snd_pmac_put_beep(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- unsigned int oval, nval;
- if (snd_BUG_ON(!chip->beep))
- return -ENXIO;
- oval = chip->beep->volume;
- nval = ucontrol->value.integer.value[0];
- if (nval > 100)
- return -EINVAL;
- chip->beep->volume = nval;
- return oval != chip->beep->volume;
-}
-
-static struct snd_kcontrol_new snd_pmac_beep_mixer = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Beep Playback Volume",
- .info = snd_pmac_info_beep,
- .get = snd_pmac_get_beep,
- .put = snd_pmac_put_beep,
-};
-
-/* Initialize beep stuff */
-int __devinit snd_pmac_attach_beep(struct snd_pmac *chip)
-{
- struct pmac_beep *beep;
- struct input_dev *input_dev;
- struct snd_kcontrol *beep_ctl;
- void *dmabuf;
- int err = -ENOMEM;
-
- beep = kzalloc(sizeof(*beep), GFP_KERNEL);
- if (! beep)
- return -ENOMEM;
- dmabuf = dma_alloc_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4,
- &beep->addr, GFP_KERNEL);
- input_dev = input_allocate_device();
- if (! dmabuf || ! input_dev)
- goto fail1;
-
- /* FIXME: set more better values */
- input_dev->name = "PowerMac Beep";
- input_dev->phys = "powermac/beep";
- input_dev->id.bustype = BUS_ADB;
- input_dev->id.vendor = 0x001f;
- input_dev->id.product = 0x0001;
- input_dev->id.version = 0x0100;
-
- input_dev->evbit[0] = BIT_MASK(EV_SND);
- input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
- input_dev->event = snd_pmac_beep_event;
- input_dev->dev.parent = &chip->pdev->dev;
- input_set_drvdata(input_dev, chip);
-
- beep->dev = input_dev;
- beep->buf = dmabuf;
- beep->volume = BEEP_VOLUME;
- beep->running = 0;
-
- beep_ctl = snd_ctl_new1(&snd_pmac_beep_mixer, chip);
- err = snd_ctl_add(chip->card, beep_ctl);
- if (err < 0)
- goto fail1;
-
- chip->beep = beep;
-
- err = input_register_device(beep->dev);
- if (err)
- goto fail2;
-
- return 0;
-
- fail2: snd_ctl_remove(chip->card, beep_ctl);
- fail1: input_free_device(input_dev);
- if (dmabuf)
- dma_free_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4,
- dmabuf, beep->addr);
- kfree(beep);
- return err;
-}
-
-void snd_pmac_detach_beep(struct snd_pmac *chip)
-{
- if (chip->beep) {
- input_unregister_device(chip->beep->dev);
- dma_free_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4,
- chip->beep->buf, chip->beep->addr);
- kfree(chip->beep);
- chip->beep = NULL;
- }
-}
diff --git a/ANDROID_3.4.5/sound/ppc/burgundy.c b/ANDROID_3.4.5/sound/ppc/burgundy.c
deleted file mode 100644
index 00e2d516..00000000
--- a/ANDROID_3.4.5/sound/ppc/burgundy.c
+++ /dev/null
@@ -1,732 +0,0 @@
-/*
- * PMac Burgundy lowlevel functions
- *
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- * code based on dmasound.c.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <asm/io.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <sound/core.h>
-#include "pmac.h"
-#include "burgundy.h"
-
-
-/* Waits for busy flag to clear */
-static inline void
-snd_pmac_burgundy_busy_wait(struct snd_pmac *chip)
-{
- int timeout = 50;
- while ((in_le32(&chip->awacs->codec_ctrl) & MASK_NEWECMD) && timeout--)
- udelay(1);
- if (timeout < 0)
- printk(KERN_DEBUG "burgundy_busy_wait: timeout\n");
-}
-
-static inline void
-snd_pmac_burgundy_extend_wait(struct snd_pmac *chip)
-{
- int timeout;
- timeout = 50;
- while (!(in_le32(&chip->awacs->codec_stat) & MASK_EXTEND) && timeout--)
- udelay(1);
- if (timeout < 0)
- printk(KERN_DEBUG "burgundy_extend_wait: timeout #1\n");
- timeout = 50;
- while ((in_le32(&chip->awacs->codec_stat) & MASK_EXTEND) && timeout--)
- udelay(1);
- if (timeout < 0)
- printk(KERN_DEBUG "burgundy_extend_wait: timeout #2\n");
-}
-
-static void
-snd_pmac_burgundy_wcw(struct snd_pmac *chip, unsigned addr, unsigned val)
-{
- out_le32(&chip->awacs->codec_ctrl, addr + 0x200c00 + (val & 0xff));
- snd_pmac_burgundy_busy_wait(chip);
- out_le32(&chip->awacs->codec_ctrl, addr + 0x200d00 +((val>>8) & 0xff));
- snd_pmac_burgundy_busy_wait(chip);
- out_le32(&chip->awacs->codec_ctrl, addr + 0x200e00 +((val>>16) & 0xff));
- snd_pmac_burgundy_busy_wait(chip);
- out_le32(&chip->awacs->codec_ctrl, addr + 0x200f00 +((val>>24) & 0xff));
- snd_pmac_burgundy_busy_wait(chip);
-}
-
-static unsigned
-snd_pmac_burgundy_rcw(struct snd_pmac *chip, unsigned addr)
-{
- unsigned val = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
-
- out_le32(&chip->awacs->codec_ctrl, addr + 0x100000);
- snd_pmac_burgundy_busy_wait(chip);
- snd_pmac_burgundy_extend_wait(chip);
- val += (in_le32(&chip->awacs->codec_stat) >> 4) & 0xff;
-
- out_le32(&chip->awacs->codec_ctrl, addr + 0x100100);
- snd_pmac_burgundy_busy_wait(chip);
- snd_pmac_burgundy_extend_wait(chip);
- val += ((in_le32(&chip->awacs->codec_stat)>>4) & 0xff) <<8;
-
- out_le32(&chip->awacs->codec_ctrl, addr + 0x100200);
- snd_pmac_burgundy_busy_wait(chip);
- snd_pmac_burgundy_extend_wait(chip);
- val += ((in_le32(&chip->awacs->codec_stat)>>4) & 0xff) <<16;
-
- out_le32(&chip->awacs->codec_ctrl, addr + 0x100300);
- snd_pmac_burgundy_busy_wait(chip);
- snd_pmac_burgundy_extend_wait(chip);
- val += ((in_le32(&chip->awacs->codec_stat)>>4) & 0xff) <<24;
-
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- return val;
-}
-
-static void
-snd_pmac_burgundy_wcb(struct snd_pmac *chip, unsigned int addr,
- unsigned int val)
-{
- out_le32(&chip->awacs->codec_ctrl, addr + 0x300000 + (val & 0xff));
- snd_pmac_burgundy_busy_wait(chip);
-}
-
-static unsigned
-snd_pmac_burgundy_rcb(struct snd_pmac *chip, unsigned int addr)
-{
- unsigned val = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&chip->reg_lock, flags);
-
- out_le32(&chip->awacs->codec_ctrl, addr + 0x100000);
- snd_pmac_burgundy_busy_wait(chip);
- snd_pmac_burgundy_extend_wait(chip);
- val += (in_le32(&chip->awacs->codec_stat) >> 4) & 0xff;
-
- spin_unlock_irqrestore(&chip->reg_lock, flags);
-
- return val;
-}
-
-#define BASE2ADDR(base) ((base) << 12)
-#define ADDR2BASE(addr) ((addr) >> 12)
-
-/*
- * Burgundy volume: 0 - 100, stereo, word reg
- */
-static void
-snd_pmac_burgundy_write_volume(struct snd_pmac *chip, unsigned int address,
- long *volume, int shift)
-{
- int hardvolume, lvolume, rvolume;
-
- if (volume[0] < 0 || volume[0] > 100 ||
- volume[1] < 0 || volume[1] > 100)
- return; /* -EINVAL */
- lvolume = volume[0] ? volume[0] + BURGUNDY_VOLUME_OFFSET : 0;
- rvolume = volume[1] ? volume[1] + BURGUNDY_VOLUME_OFFSET : 0;
-
- hardvolume = lvolume + (rvolume << shift);
- if (shift == 8)
- hardvolume |= hardvolume << 16;
-
- snd_pmac_burgundy_wcw(chip, address, hardvolume);
-}
-
-static void
-snd_pmac_burgundy_read_volume(struct snd_pmac *chip, unsigned int address,
- long *volume, int shift)
-{
- int wvolume;
-
- wvolume = snd_pmac_burgundy_rcw(chip, address);
-
- volume[0] = wvolume & 0xff;
- if (volume[0] >= BURGUNDY_VOLUME_OFFSET)
- volume[0] -= BURGUNDY_VOLUME_OFFSET;
- else
- volume[0] = 0;
- volume[1] = (wvolume >> shift) & 0xff;
- if (volume[1] >= BURGUNDY_VOLUME_OFFSET)
- volume[1] -= BURGUNDY_VOLUME_OFFSET;
- else
- volume[1] = 0;
-}
-
-static int snd_pmac_burgundy_info_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 100;
- return 0;
-}
-
-static int snd_pmac_burgundy_get_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- unsigned int addr = BASE2ADDR(kcontrol->private_value & 0xff);
- int shift = (kcontrol->private_value >> 8) & 0xff;
- snd_pmac_burgundy_read_volume(chip, addr,
- ucontrol->value.integer.value, shift);
- return 0;
-}
-
-static int snd_pmac_burgundy_put_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- unsigned int addr = BASE2ADDR(kcontrol->private_value & 0xff);
- int shift = (kcontrol->private_value >> 8) & 0xff;
- long nvoices[2];
-
- snd_pmac_burgundy_write_volume(chip, addr,
- ucontrol->value.integer.value, shift);
- snd_pmac_burgundy_read_volume(chip, addr, nvoices, shift);
- return (nvoices[0] != ucontrol->value.integer.value[0] ||
- nvoices[1] != ucontrol->value.integer.value[1]);
-}
-
-#define BURGUNDY_VOLUME_W(xname, xindex, addr, shift) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex,\
- .info = snd_pmac_burgundy_info_volume,\
- .get = snd_pmac_burgundy_get_volume,\
- .put = snd_pmac_burgundy_put_volume,\
- .private_value = ((ADDR2BASE(addr) & 0xff) | ((shift) << 8)) }
-
-/*
- * Burgundy volume: 0 - 100, stereo, 2-byte reg
- */
-static void
-snd_pmac_burgundy_write_volume_2b(struct snd_pmac *chip, unsigned int address,
- long *volume, int off)
-{
- int lvolume, rvolume;
-
- off |= off << 2;
- lvolume = volume[0] ? volume[0] + BURGUNDY_VOLUME_OFFSET : 0;
- rvolume = volume[1] ? volume[1] + BURGUNDY_VOLUME_OFFSET : 0;
-
- snd_pmac_burgundy_wcb(chip, address + off, lvolume);
- snd_pmac_burgundy_wcb(chip, address + off + 0x500, rvolume);
-}
-
-static void
-snd_pmac_burgundy_read_volume_2b(struct snd_pmac *chip, unsigned int address,
- long *volume, int off)
-{
- volume[0] = snd_pmac_burgundy_rcb(chip, address + off);
- if (volume[0] >= BURGUNDY_VOLUME_OFFSET)
- volume[0] -= BURGUNDY_VOLUME_OFFSET;
- else
- volume[0] = 0;
- volume[1] = snd_pmac_burgundy_rcb(chip, address + off + 0x100);
- if (volume[1] >= BURGUNDY_VOLUME_OFFSET)
- volume[1] -= BURGUNDY_VOLUME_OFFSET;
- else
- volume[1] = 0;
-}
-
-static int snd_pmac_burgundy_info_volume_2b(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 100;
- return 0;
-}
-
-static int snd_pmac_burgundy_get_volume_2b(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- unsigned int addr = BASE2ADDR(kcontrol->private_value & 0xff);
- int off = kcontrol->private_value & 0x300;
- snd_pmac_burgundy_read_volume_2b(chip, addr,
- ucontrol->value.integer.value, off);
- return 0;
-}
-
-static int snd_pmac_burgundy_put_volume_2b(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- unsigned int addr = BASE2ADDR(kcontrol->private_value & 0xff);
- int off = kcontrol->private_value & 0x300;
- long nvoices[2];
-
- snd_pmac_burgundy_write_volume_2b(chip, addr,
- ucontrol->value.integer.value, off);
- snd_pmac_burgundy_read_volume_2b(chip, addr, nvoices, off);
- return (nvoices[0] != ucontrol->value.integer.value[0] ||
- nvoices[1] != ucontrol->value.integer.value[1]);
-}
-
-#define BURGUNDY_VOLUME_2B(xname, xindex, addr, off) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex,\
- .info = snd_pmac_burgundy_info_volume_2b,\
- .get = snd_pmac_burgundy_get_volume_2b,\
- .put = snd_pmac_burgundy_put_volume_2b,\
- .private_value = ((ADDR2BASE(addr) & 0xff) | ((off) << 8)) }
-
-/*
- * Burgundy gain/attenuation: 0 - 15, mono/stereo, byte reg
- */
-static int snd_pmac_burgundy_info_gain(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int stereo = (kcontrol->private_value >> 24) & 1;
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = stereo + 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 15;
- return 0;
-}
-
-static int snd_pmac_burgundy_get_gain(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- unsigned int addr = BASE2ADDR(kcontrol->private_value & 0xff);
- int stereo = (kcontrol->private_value >> 24) & 1;
- int atten = (kcontrol->private_value >> 25) & 1;
- int oval;
-
- oval = snd_pmac_burgundy_rcb(chip, addr);
- if (atten)
- oval = ~oval & 0xff;
- ucontrol->value.integer.value[0] = oval & 0xf;
- if (stereo)
- ucontrol->value.integer.value[1] = (oval >> 4) & 0xf;
- return 0;
-}
-
-static int snd_pmac_burgundy_put_gain(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- unsigned int addr = BASE2ADDR(kcontrol->private_value & 0xff);
- int stereo = (kcontrol->private_value >> 24) & 1;
- int atten = (kcontrol->private_value >> 25) & 1;
- int oval, val;
-
- oval = snd_pmac_burgundy_rcb(chip, addr);
- if (atten)
- oval = ~oval & 0xff;
- val = ucontrol->value.integer.value[0];
- if (stereo)
- val |= ucontrol->value.integer.value[1] << 4;
- else
- val |= ucontrol->value.integer.value[0] << 4;
- if (atten)
- val = ~val & 0xff;
- snd_pmac_burgundy_wcb(chip, addr, val);
- return val != oval;
-}
-
-#define BURGUNDY_VOLUME_B(xname, xindex, addr, stereo, atten) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex,\
- .info = snd_pmac_burgundy_info_gain,\
- .get = snd_pmac_burgundy_get_gain,\
- .put = snd_pmac_burgundy_put_gain,\
- .private_value = (ADDR2BASE(addr) | ((stereo) << 24) | ((atten) << 25)) }
-
-/*
- * Burgundy switch: 0/1, mono/stereo, word reg
- */
-static int snd_pmac_burgundy_info_switch_w(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int stereo = (kcontrol->private_value >> 24) & 1;
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = stereo + 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int snd_pmac_burgundy_get_switch_w(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- unsigned int addr = BASE2ADDR((kcontrol->private_value >> 16) & 0xff);
- int lmask = 1 << (kcontrol->private_value & 0xff);
- int rmask = 1 << ((kcontrol->private_value >> 8) & 0xff);
- int stereo = (kcontrol->private_value >> 24) & 1;
- int val = snd_pmac_burgundy_rcw(chip, addr);
- ucontrol->value.integer.value[0] = (val & lmask) ? 1 : 0;
- if (stereo)
- ucontrol->value.integer.value[1] = (val & rmask) ? 1 : 0;
- return 0;
-}
-
-static int snd_pmac_burgundy_put_switch_w(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- unsigned int addr = BASE2ADDR((kcontrol->private_value >> 16) & 0xff);
- int lmask = 1 << (kcontrol->private_value & 0xff);
- int rmask = 1 << ((kcontrol->private_value >> 8) & 0xff);
- int stereo = (kcontrol->private_value >> 24) & 1;
- int val, oval;
- oval = snd_pmac_burgundy_rcw(chip, addr);
- val = oval & ~(lmask | (stereo ? rmask : 0));
- if (ucontrol->value.integer.value[0])
- val |= lmask;
- if (stereo && ucontrol->value.integer.value[1])
- val |= rmask;
- snd_pmac_burgundy_wcw(chip, addr, val);
- return val != oval;
-}
-
-#define BURGUNDY_SWITCH_W(xname, xindex, addr, lbit, rbit, stereo) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex,\
- .info = snd_pmac_burgundy_info_switch_w,\
- .get = snd_pmac_burgundy_get_switch_w,\
- .put = snd_pmac_burgundy_put_switch_w,\
- .private_value = ((lbit) | ((rbit) << 8)\
- | (ADDR2BASE(addr) << 16) | ((stereo) << 24)) }
-
-/*
- * Burgundy switch: 0/1, mono/stereo, byte reg, bit mask
- */
-static int snd_pmac_burgundy_info_switch_b(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int stereo = (kcontrol->private_value >> 24) & 1;
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = stereo + 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int snd_pmac_burgundy_get_switch_b(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- unsigned int addr = BASE2ADDR((kcontrol->private_value >> 16) & 0xff);
- int lmask = kcontrol->private_value & 0xff;
- int rmask = (kcontrol->private_value >> 8) & 0xff;
- int stereo = (kcontrol->private_value >> 24) & 1;
- int val = snd_pmac_burgundy_rcb(chip, addr);
- ucontrol->value.integer.value[0] = (val & lmask) ? 1 : 0;
- if (stereo)
- ucontrol->value.integer.value[1] = (val & rmask) ? 1 : 0;
- return 0;
-}
-
-static int snd_pmac_burgundy_put_switch_b(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- unsigned int addr = BASE2ADDR((kcontrol->private_value >> 16) & 0xff);
- int lmask = kcontrol->private_value & 0xff;
- int rmask = (kcontrol->private_value >> 8) & 0xff;
- int stereo = (kcontrol->private_value >> 24) & 1;
- int val, oval;
- oval = snd_pmac_burgundy_rcb(chip, addr);
- val = oval & ~(lmask | rmask);
- if (ucontrol->value.integer.value[0])
- val |= lmask;
- if (stereo && ucontrol->value.integer.value[1])
- val |= rmask;
- snd_pmac_burgundy_wcb(chip, addr, val);
- return val != oval;
-}
-
-#define BURGUNDY_SWITCH_B(xname, xindex, addr, lmask, rmask, stereo) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex,\
- .info = snd_pmac_burgundy_info_switch_b,\
- .get = snd_pmac_burgundy_get_switch_b,\
- .put = snd_pmac_burgundy_put_switch_b,\
- .private_value = ((lmask) | ((rmask) << 8)\
- | (ADDR2BASE(addr) << 16) | ((stereo) << 24)) }
-
-/*
- * Burgundy mixers
- */
-static struct snd_kcontrol_new snd_pmac_burgundy_mixers[] __devinitdata = {
- BURGUNDY_VOLUME_W("Master Playback Volume", 0,
- MASK_ADDR_BURGUNDY_MASTER_VOLUME, 8),
- BURGUNDY_VOLUME_W("CD Capture Volume", 0,
- MASK_ADDR_BURGUNDY_VOLCD, 16),
- BURGUNDY_VOLUME_2B("Input Capture Volume", 0,
- MASK_ADDR_BURGUNDY_VOLMIX01, 2),
- BURGUNDY_VOLUME_2B("Mixer Playback Volume", 0,
- MASK_ADDR_BURGUNDY_VOLMIX23, 0),
- BURGUNDY_VOLUME_B("CD Gain Capture Volume", 0,
- MASK_ADDR_BURGUNDY_GAINCD, 1, 0),
- BURGUNDY_SWITCH_W("Master Capture Switch", 0,
- MASK_ADDR_BURGUNDY_OUTPUTENABLES, 24, 0, 0),
- BURGUNDY_SWITCH_W("CD Capture Switch", 0,
- MASK_ADDR_BURGUNDY_CAPTURESELECTS, 0, 16, 1),
- BURGUNDY_SWITCH_W("CD Playback Switch", 0,
- MASK_ADDR_BURGUNDY_OUTPUTSELECTS, 0, 16, 1),
-/* BURGUNDY_SWITCH_W("Loop Capture Switch", 0,
- * MASK_ADDR_BURGUNDY_CAPTURESELECTS, 8, 24, 1),
- * BURGUNDY_SWITCH_B("Mixer out Capture Switch", 0,
- * MASK_ADDR_BURGUNDY_HOSTIFAD, 0x02, 0, 0),
- * BURGUNDY_SWITCH_B("Mixer Capture Switch", 0,
- * MASK_ADDR_BURGUNDY_HOSTIFAD, 0x01, 0, 0),
- * BURGUNDY_SWITCH_B("PCM out Capture Switch", 0,
- * MASK_ADDR_BURGUNDY_HOSTIFEH, 0x02, 0, 0),
- */ BURGUNDY_SWITCH_B("PCM Capture Switch", 0,
- MASK_ADDR_BURGUNDY_HOSTIFEH, 0x01, 0, 0)
-};
-static struct snd_kcontrol_new snd_pmac_burgundy_mixers_imac[] __devinitdata = {
- BURGUNDY_VOLUME_W("Line in Capture Volume", 0,
- MASK_ADDR_BURGUNDY_VOLLINE, 16),
- BURGUNDY_VOLUME_W("Mic Capture Volume", 0,
- MASK_ADDR_BURGUNDY_VOLMIC, 16),
- BURGUNDY_VOLUME_B("Line in Gain Capture Volume", 0,
- MASK_ADDR_BURGUNDY_GAINLINE, 1, 0),
- BURGUNDY_VOLUME_B("Mic Gain Capture Volume", 0,
- MASK_ADDR_BURGUNDY_GAINMIC, 1, 0),
- BURGUNDY_VOLUME_B("Speaker Playback Volume", 0,
- MASK_ADDR_BURGUNDY_ATTENSPEAKER, 1, 1),
- BURGUNDY_VOLUME_B("Line out Playback Volume", 0,
- MASK_ADDR_BURGUNDY_ATTENLINEOUT, 1, 1),
- BURGUNDY_VOLUME_B("Headphone Playback Volume", 0,
- MASK_ADDR_BURGUNDY_ATTENHP, 1, 1),
- BURGUNDY_SWITCH_W("Line in Capture Switch", 0,
- MASK_ADDR_BURGUNDY_CAPTURESELECTS, 1, 17, 1),
- BURGUNDY_SWITCH_W("Mic Capture Switch", 0,
- MASK_ADDR_BURGUNDY_CAPTURESELECTS, 2, 18, 1),
- BURGUNDY_SWITCH_W("Line in Playback Switch", 0,
- MASK_ADDR_BURGUNDY_OUTPUTSELECTS, 1, 17, 1),
- BURGUNDY_SWITCH_W("Mic Playback Switch", 0,
- MASK_ADDR_BURGUNDY_OUTPUTSELECTS, 2, 18, 1),
- BURGUNDY_SWITCH_B("Mic Boost Capture Switch", 0,
- MASK_ADDR_BURGUNDY_INPBOOST, 0x40, 0x80, 1)
-};
-static struct snd_kcontrol_new snd_pmac_burgundy_mixers_pmac[] __devinitdata = {
- BURGUNDY_VOLUME_W("Line in Capture Volume", 0,
- MASK_ADDR_BURGUNDY_VOLMIC, 16),
- BURGUNDY_VOLUME_B("Line in Gain Capture Volume", 0,
- MASK_ADDR_BURGUNDY_GAINMIC, 1, 0),
- BURGUNDY_VOLUME_B("Speaker Playback Volume", 0,
- MASK_ADDR_BURGUNDY_ATTENMONO, 0, 1),
- BURGUNDY_VOLUME_B("Line out Playback Volume", 0,
- MASK_ADDR_BURGUNDY_ATTENSPEAKER, 1, 1),
- BURGUNDY_SWITCH_W("Line in Capture Switch", 0,
- MASK_ADDR_BURGUNDY_CAPTURESELECTS, 2, 18, 1),
- BURGUNDY_SWITCH_W("Line in Playback Switch", 0,
- MASK_ADDR_BURGUNDY_OUTPUTSELECTS, 2, 18, 1),
-/* BURGUNDY_SWITCH_B("Line in Boost Capture Switch", 0,
- * MASK_ADDR_BURGUNDY_INPBOOST, 0x40, 0x80, 1) */
-};
-static struct snd_kcontrol_new snd_pmac_burgundy_master_sw_imac __devinitdata =
-BURGUNDY_SWITCH_B("Master Playback Switch", 0,
- MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
- BURGUNDY_OUTPUT_LEFT | BURGUNDY_LINEOUT_LEFT | BURGUNDY_HP_LEFT,
- BURGUNDY_OUTPUT_RIGHT | BURGUNDY_LINEOUT_RIGHT | BURGUNDY_HP_RIGHT, 1);
-static struct snd_kcontrol_new snd_pmac_burgundy_master_sw_pmac __devinitdata =
-BURGUNDY_SWITCH_B("Master Playback Switch", 0,
- MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
- BURGUNDY_OUTPUT_INTERN
- | BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPUT_RIGHT, 1);
-static struct snd_kcontrol_new snd_pmac_burgundy_speaker_sw_imac __devinitdata =
-BURGUNDY_SWITCH_B("Speaker Playback Switch", 0,
- MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
- BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPUT_RIGHT, 1);
-static struct snd_kcontrol_new snd_pmac_burgundy_speaker_sw_pmac __devinitdata =
-BURGUNDY_SWITCH_B("Speaker Playback Switch", 0,
- MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
- BURGUNDY_OUTPUT_INTERN, 0, 0);
-static struct snd_kcontrol_new snd_pmac_burgundy_line_sw_imac __devinitdata =
-BURGUNDY_SWITCH_B("Line out Playback Switch", 0,
- MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
- BURGUNDY_LINEOUT_LEFT, BURGUNDY_LINEOUT_RIGHT, 1);
-static struct snd_kcontrol_new snd_pmac_burgundy_line_sw_pmac __devinitdata =
-BURGUNDY_SWITCH_B("Line out Playback Switch", 0,
- MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
- BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPUT_RIGHT, 1);
-static struct snd_kcontrol_new snd_pmac_burgundy_hp_sw_imac __devinitdata =
-BURGUNDY_SWITCH_B("Headphone Playback Switch", 0,
- MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
- BURGUNDY_HP_LEFT, BURGUNDY_HP_RIGHT, 1);
-
-
-#ifdef PMAC_SUPPORT_AUTOMUTE
-/*
- * auto-mute stuffs
- */
-static int snd_pmac_burgundy_detect_headphone(struct snd_pmac *chip)
-{
- return (in_le32(&chip->awacs->codec_stat) & chip->hp_stat_mask) ? 1 : 0;
-}
-
-static void snd_pmac_burgundy_update_automute(struct snd_pmac *chip, int do_notify)
-{
- if (chip->auto_mute) {
- int imac = of_machine_is_compatible("iMac");
- int reg, oreg;
- reg = oreg = snd_pmac_burgundy_rcb(chip,
- MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES);
- reg &= imac ? ~(BURGUNDY_OUTPUT_LEFT | BURGUNDY_OUTPUT_RIGHT
- | BURGUNDY_HP_LEFT | BURGUNDY_HP_RIGHT)
- : ~(BURGUNDY_OUTPUT_LEFT | BURGUNDY_OUTPUT_RIGHT
- | BURGUNDY_OUTPUT_INTERN);
- if (snd_pmac_burgundy_detect_headphone(chip))
- reg |= imac ? (BURGUNDY_HP_LEFT | BURGUNDY_HP_RIGHT)
- : (BURGUNDY_OUTPUT_LEFT
- | BURGUNDY_OUTPUT_RIGHT);
- else
- reg |= imac ? (BURGUNDY_OUTPUT_LEFT
- | BURGUNDY_OUTPUT_RIGHT)
- : (BURGUNDY_OUTPUT_INTERN);
- if (do_notify && reg == oreg)
- return;
- snd_pmac_burgundy_wcb(chip,
- MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, reg);
- if (do_notify) {
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->master_sw_ctl->id);
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->speaker_sw_ctl->id);
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->hp_detect_ctl->id);
- }
- }
-}
-#endif /* PMAC_SUPPORT_AUTOMUTE */
-
-
-/*
- * initialize burgundy
- */
-int __devinit snd_pmac_burgundy_init(struct snd_pmac *chip)
-{
- int imac = of_machine_is_compatible("iMac");
- int i, err;
-
- /* Checks to see the chip is alive and kicking */
- if ((in_le32(&chip->awacs->codec_ctrl) & MASK_ERRCODE) == 0xf0000) {
- printk(KERN_WARNING "pmac burgundy: disabled by MacOS :-(\n");
- return 1;
- }
-
- snd_pmac_burgundy_wcw(chip, MASK_ADDR_BURGUNDY_OUTPUTENABLES,
- DEF_BURGUNDY_OUTPUTENABLES);
- snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
- DEF_BURGUNDY_MORE_OUTPUTENABLES);
- snd_pmac_burgundy_wcw(chip, MASK_ADDR_BURGUNDY_OUTPUTSELECTS,
- DEF_BURGUNDY_OUTPUTSELECTS);
-
- snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_INPSEL21,
- DEF_BURGUNDY_INPSEL21);
- snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_INPSEL3,
- imac ? DEF_BURGUNDY_INPSEL3_IMAC
- : DEF_BURGUNDY_INPSEL3_PMAC);
- snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_GAINCD,
- DEF_BURGUNDY_GAINCD);
- snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_GAINLINE,
- DEF_BURGUNDY_GAINLINE);
- snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_GAINMIC,
- DEF_BURGUNDY_GAINMIC);
- snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_GAINMODEM,
- DEF_BURGUNDY_GAINMODEM);
-
- snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_ATTENSPEAKER,
- DEF_BURGUNDY_ATTENSPEAKER);
- snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_ATTENLINEOUT,
- DEF_BURGUNDY_ATTENLINEOUT);
- snd_pmac_burgundy_wcb(chip, MASK_ADDR_BURGUNDY_ATTENHP,
- DEF_BURGUNDY_ATTENHP);
-
- snd_pmac_burgundy_wcw(chip, MASK_ADDR_BURGUNDY_MASTER_VOLUME,
- DEF_BURGUNDY_MASTER_VOLUME);
- snd_pmac_burgundy_wcw(chip, MASK_ADDR_BURGUNDY_VOLCD,
- DEF_BURGUNDY_VOLCD);
- snd_pmac_burgundy_wcw(chip, MASK_ADDR_BURGUNDY_VOLLINE,
- DEF_BURGUNDY_VOLLINE);
- snd_pmac_burgundy_wcw(chip, MASK_ADDR_BURGUNDY_VOLMIC,
- DEF_BURGUNDY_VOLMIC);
-
- if (chip->hp_stat_mask == 0) {
- /* set headphone-jack detection bit */
- if (imac)
- chip->hp_stat_mask = BURGUNDY_HPDETECT_IMAC_UPPER
- | BURGUNDY_HPDETECT_IMAC_LOWER
- | BURGUNDY_HPDETECT_IMAC_SIDE;
- else
- chip->hp_stat_mask = BURGUNDY_HPDETECT_PMAC_BACK;
- }
- /*
- * build burgundy mixers
- */
- strcpy(chip->card->mixername, "PowerMac Burgundy");
-
- for (i = 0; i < ARRAY_SIZE(snd_pmac_burgundy_mixers); i++) {
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(&snd_pmac_burgundy_mixers[i], chip));
- if (err < 0)
- return err;
- }
- for (i = 0; i < (imac ? ARRAY_SIZE(snd_pmac_burgundy_mixers_imac)
- : ARRAY_SIZE(snd_pmac_burgundy_mixers_pmac)); i++) {
- err = snd_ctl_add(chip->card,
- snd_ctl_new1(imac ? &snd_pmac_burgundy_mixers_imac[i]
- : &snd_pmac_burgundy_mixers_pmac[i], chip));
- if (err < 0)
- return err;
- }
- chip->master_sw_ctl = snd_ctl_new1(imac
- ? &snd_pmac_burgundy_master_sw_imac
- : &snd_pmac_burgundy_master_sw_pmac, chip);
- err = snd_ctl_add(chip->card, chip->master_sw_ctl);
- if (err < 0)
- return err;
- chip->master_sw_ctl = snd_ctl_new1(imac
- ? &snd_pmac_burgundy_line_sw_imac
- : &snd_pmac_burgundy_line_sw_pmac, chip);
- err = snd_ctl_add(chip->card, chip->master_sw_ctl);
- if (err < 0)
- return err;
- if (imac) {
- chip->master_sw_ctl = snd_ctl_new1(
- &snd_pmac_burgundy_hp_sw_imac, chip);
- err = snd_ctl_add(chip->card, chip->master_sw_ctl);
- if (err < 0)
- return err;
- }
- chip->speaker_sw_ctl = snd_ctl_new1(imac
- ? &snd_pmac_burgundy_speaker_sw_imac
- : &snd_pmac_burgundy_speaker_sw_pmac, chip);
- err = snd_ctl_add(chip->card, chip->speaker_sw_ctl);
- if (err < 0)
- return err;
-#ifdef PMAC_SUPPORT_AUTOMUTE
- err = snd_pmac_add_automute(chip);
- if (err < 0)
- return err;
-
- chip->detect_headphone = snd_pmac_burgundy_detect_headphone;
- chip->update_automute = snd_pmac_burgundy_update_automute;
- snd_pmac_burgundy_update_automute(chip, 0); /* update the status only */
-#endif
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/ppc/burgundy.h b/ANDROID_3.4.5/sound/ppc/burgundy.h
deleted file mode 100644
index 7a7f9cf3..00000000
--- a/ANDROID_3.4.5/sound/ppc/burgundy.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Driver for PowerMac Burgundy onboard soundchips
- * Copyright (c) 2001 by Takashi Iwai <tiwai@suse.de>
- * based on dmasound.c.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#ifndef __BURGUNDY_H
-#define __BURGUNDY_H
-
-#define MASK_ADDR_BURGUNDY_INPBOOST (0x10 << 12)
-#define MASK_ADDR_BURGUNDY_INPSEL21 (0x11 << 12)
-#define MASK_ADDR_BURGUNDY_INPSEL3 (0x12 << 12)
-
-#define MASK_ADDR_BURGUNDY_GAINCH1 (0x13 << 12)
-#define MASK_ADDR_BURGUNDY_GAINCH2 (0x14 << 12)
-#define MASK_ADDR_BURGUNDY_GAINCH3 (0x15 << 12)
-#define MASK_ADDR_BURGUNDY_GAINCH4 (0x16 << 12)
-
-#define MASK_ADDR_BURGUNDY_VOLCH1 (0x20 << 12)
-#define MASK_ADDR_BURGUNDY_VOLCH2 (0x21 << 12)
-#define MASK_ADDR_BURGUNDY_VOLCH3 (0x22 << 12)
-#define MASK_ADDR_BURGUNDY_VOLCH4 (0x23 << 12)
-
-#define MASK_ADDR_BURGUNDY_CAPTURESELECTS (0x2A << 12)
-#define MASK_ADDR_BURGUNDY_OUTPUTSELECTS (0x2B << 12)
-#define MASK_ADDR_BURGUNDY_VOLMIX01 (0x2D << 12)
-#define MASK_ADDR_BURGUNDY_VOLMIX23 (0x2E << 12)
-#define MASK_ADDR_BURGUNDY_OUTPUTENABLES (0x2F << 12)
-
-#define MASK_ADDR_BURGUNDY_MASTER_VOLUME (0x30 << 12)
-
-#define MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES (0x60 << 12)
-
-#define MASK_ADDR_BURGUNDY_ATTENSPEAKER (0x62 << 12)
-#define MASK_ADDR_BURGUNDY_ATTENLINEOUT (0x63 << 12)
-#define MASK_ADDR_BURGUNDY_ATTENHP (0x64 << 12)
-#define MASK_ADDR_BURGUNDY_ATTENMONO (0x65 << 12)
-
-#define MASK_ADDR_BURGUNDY_HOSTIFAD (0x78 << 12)
-#define MASK_ADDR_BURGUNDY_HOSTIFEH (0x79 << 12)
-
-#define MASK_ADDR_BURGUNDY_VOLCD (MASK_ADDR_BURGUNDY_VOLCH1)
-#define MASK_ADDR_BURGUNDY_VOLLINE (MASK_ADDR_BURGUNDY_VOLCH2)
-#define MASK_ADDR_BURGUNDY_VOLMIC (MASK_ADDR_BURGUNDY_VOLCH3)
-#define MASK_ADDR_BURGUNDY_VOLMODEM (MASK_ADDR_BURGUNDY_VOLCH4)
-
-#define MASK_ADDR_BURGUNDY_GAINCD (MASK_ADDR_BURGUNDY_GAINCH1)
-#define MASK_ADDR_BURGUNDY_GAINLINE (MASK_ADDR_BURGUNDY_GAINCH2)
-#define MASK_ADDR_BURGUNDY_GAINMIC (MASK_ADDR_BURGUNDY_GAINCH3)
-#define MASK_ADDR_BURGUNDY_GAINMODEM (MASK_ADDR_BURGUNDY_VOLCH4)
-
-
-/* These are all default values for the burgundy */
-#define DEF_BURGUNDY_INPSEL21 (0xAA)
-#define DEF_BURGUNDY_INPSEL3_IMAC (0x0A)
-#define DEF_BURGUNDY_INPSEL3_PMAC (0x05)
-
-#define DEF_BURGUNDY_GAINCD (0x33)
-#define DEF_BURGUNDY_GAINLINE (0x44)
-#define DEF_BURGUNDY_GAINMIC (0x44)
-#define DEF_BURGUNDY_GAINMODEM (0x06)
-
-/* Remember: lowest volume here is 0x9B (155) */
-#define DEF_BURGUNDY_VOLCD (0xCCCCCCCC)
-#define DEF_BURGUNDY_VOLLINE (0x00000000)
-#define DEF_BURGUNDY_VOLMIC (0x00000000)
-#define DEF_BURGUNDY_VOLMODEM (0xCCCCCCCC)
-
-#define DEF_BURGUNDY_OUTPUTSELECTS (0x010F010F)
-#define DEF_BURGUNDY_OUTPUTENABLES (0x0100000A)
-
-/* #define DEF_BURGUNDY_MASTER_VOLUME (0xFFFFFFFF) */ /* too loud */
-#define DEF_BURGUNDY_MASTER_VOLUME (0xDDDDDDDD)
-
-#define DEF_BURGUNDY_MORE_OUTPUTENABLES (0x7E)
-
-#define DEF_BURGUNDY_ATTENSPEAKER (0x44)
-#define DEF_BURGUNDY_ATTENLINEOUT (0xCC)
-#define DEF_BURGUNDY_ATTENHP (0xCC)
-
-/* MORE_OUTPUTENABLES bits */
-#define BURGUNDY_OUTPUT_LEFT 0x02
-#define BURGUNDY_OUTPUT_RIGHT 0x04
-#define BURGUNDY_LINEOUT_LEFT 0x08
-#define BURGUNDY_LINEOUT_RIGHT 0x10
-#define BURGUNDY_HP_LEFT 0x20
-#define BURGUNDY_HP_RIGHT 0x40
-#define BURGUNDY_OUTPUT_INTERN 0x80
-
-/* Headphone detection bits */
-#define BURGUNDY_HPDETECT_PMAC_BACK 0x04
-#define BURGUNDY_HPDETECT_IMAC_SIDE 0x04
-#define BURGUNDY_HPDETECT_IMAC_UPPER 0x08
-#define BURGUNDY_HPDETECT_IMAC_LOWER 0x01
-
-/* Volume offset */
-#define BURGUNDY_VOLUME_OFFSET 155
-
-#endif /* __BURGUNDY_H */
diff --git a/ANDROID_3.4.5/sound/ppc/daca.c b/ANDROID_3.4.5/sound/ppc/daca.c
deleted file mode 100644
index 24200b7b..00000000
--- a/ANDROID_3.4.5/sound/ppc/daca.c
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * PMac DACA lowlevel functions
- *
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/kmod.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include "pmac.h"
-
-/* i2c address */
-#define DACA_I2C_ADDR 0x4d
-
-/* registers */
-#define DACA_REG_SR 0x01
-#define DACA_REG_AVOL 0x02
-#define DACA_REG_GCFG 0x03
-
-/* maximum volume value */
-#define DACA_VOL_MAX 0x38
-
-
-struct pmac_daca {
- struct pmac_keywest i2c;
- int left_vol, right_vol;
- unsigned int deemphasis : 1;
- unsigned int amp_on : 1;
-};
-
-
-/*
- * initialize / detect DACA
- */
-static int daca_init_client(struct pmac_keywest *i2c)
-{
- unsigned short wdata = 0x00;
- /* SR: no swap, 1bit delay, 32-48kHz */
- /* GCFG: power amp inverted, DAC on */
- if (i2c_smbus_write_byte_data(i2c->client, DACA_REG_SR, 0x08) < 0 ||
- i2c_smbus_write_byte_data(i2c->client, DACA_REG_GCFG, 0x05) < 0)
- return -EINVAL;
- return i2c_smbus_write_block_data(i2c->client, DACA_REG_AVOL,
- 2, (unsigned char*)&wdata);
-}
-
-/*
- * update volume
- */
-static int daca_set_volume(struct pmac_daca *mix)
-{
- unsigned char data[2];
-
- if (! mix->i2c.client)
- return -ENODEV;
-
- if (mix->left_vol > DACA_VOL_MAX)
- data[0] = DACA_VOL_MAX;
- else
- data[0] = mix->left_vol;
- if (mix->right_vol > DACA_VOL_MAX)
- data[1] = DACA_VOL_MAX;
- else
- data[1] = mix->right_vol;
- data[1] |= mix->deemphasis ? 0x40 : 0;
- if (i2c_smbus_write_block_data(mix->i2c.client, DACA_REG_AVOL,
- 2, data) < 0) {
- snd_printk(KERN_ERR "failed to set volume \n");
- return -EINVAL;
- }
- return 0;
-}
-
-
-/* deemphasis switch */
-#define daca_info_deemphasis snd_ctl_boolean_mono_info
-
-static int daca_get_deemphasis(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_daca *mix;
- if (! (mix = chip->mixer_data))
- return -ENODEV;
- ucontrol->value.integer.value[0] = mix->deemphasis ? 1 : 0;
- return 0;
-}
-
-static int daca_put_deemphasis(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_daca *mix;
- int change;
-
- if (! (mix = chip->mixer_data))
- return -ENODEV;
- change = mix->deemphasis != ucontrol->value.integer.value[0];
- if (change) {
- mix->deemphasis = !!ucontrol->value.integer.value[0];
- daca_set_volume(mix);
- }
- return change;
-}
-
-/* output volume */
-static int daca_info_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = DACA_VOL_MAX;
- return 0;
-}
-
-static int daca_get_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_daca *mix;
- if (! (mix = chip->mixer_data))
- return -ENODEV;
- ucontrol->value.integer.value[0] = mix->left_vol;
- ucontrol->value.integer.value[1] = mix->right_vol;
- return 0;
-}
-
-static int daca_put_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_daca *mix;
- unsigned int vol[2];
- int change;
-
- if (! (mix = chip->mixer_data))
- return -ENODEV;
- vol[0] = ucontrol->value.integer.value[0];
- vol[1] = ucontrol->value.integer.value[1];
- if (vol[0] > DACA_VOL_MAX || vol[1] > DACA_VOL_MAX)
- return -EINVAL;
- change = mix->left_vol != vol[0] ||
- mix->right_vol != vol[1];
- if (change) {
- mix->left_vol = vol[0];
- mix->right_vol = vol[1];
- daca_set_volume(mix);
- }
- return change;
-}
-
-/* amplifier switch */
-#define daca_info_amp daca_info_deemphasis
-
-static int daca_get_amp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_daca *mix;
- if (! (mix = chip->mixer_data))
- return -ENODEV;
- ucontrol->value.integer.value[0] = mix->amp_on ? 1 : 0;
- return 0;
-}
-
-static int daca_put_amp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_daca *mix;
- int change;
-
- if (! (mix = chip->mixer_data))
- return -ENODEV;
- change = mix->amp_on != ucontrol->value.integer.value[0];
- if (change) {
- mix->amp_on = !!ucontrol->value.integer.value[0];
- i2c_smbus_write_byte_data(mix->i2c.client, DACA_REG_GCFG,
- mix->amp_on ? 0x05 : 0x04);
- }
- return change;
-}
-
-static struct snd_kcontrol_new daca_mixers[] = {
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Deemphasis Switch",
- .info = daca_info_deemphasis,
- .get = daca_get_deemphasis,
- .put = daca_put_deemphasis
- },
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Volume",
- .info = daca_info_volume,
- .get = daca_get_volume,
- .put = daca_put_volume
- },
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Power Amplifier Switch",
- .info = daca_info_amp,
- .get = daca_get_amp,
- .put = daca_put_amp
- },
-};
-
-
-#ifdef CONFIG_PM
-static void daca_resume(struct snd_pmac *chip)
-{
- struct pmac_daca *mix = chip->mixer_data;
- i2c_smbus_write_byte_data(mix->i2c.client, DACA_REG_SR, 0x08);
- i2c_smbus_write_byte_data(mix->i2c.client, DACA_REG_GCFG,
- mix->amp_on ? 0x05 : 0x04);
- daca_set_volume(mix);
-}
-#endif /* CONFIG_PM */
-
-
-static void daca_cleanup(struct snd_pmac *chip)
-{
- struct pmac_daca *mix = chip->mixer_data;
- if (! mix)
- return;
- snd_pmac_keywest_cleanup(&mix->i2c);
- kfree(mix);
- chip->mixer_data = NULL;
-}
-
-/* exported */
-int __devinit snd_pmac_daca_init(struct snd_pmac *chip)
-{
- int i, err;
- struct pmac_daca *mix;
-
- request_module("i2c-powermac");
-
- mix = kzalloc(sizeof(*mix), GFP_KERNEL);
- if (! mix)
- return -ENOMEM;
- chip->mixer_data = mix;
- chip->mixer_free = daca_cleanup;
- mix->amp_on = 1; /* default on */
-
- mix->i2c.addr = DACA_I2C_ADDR;
- mix->i2c.init_client = daca_init_client;
- mix->i2c.name = "DACA";
- if ((err = snd_pmac_keywest_init(&mix->i2c)) < 0)
- return err;
-
- /*
- * build mixers
- */
- strcpy(chip->card->mixername, "PowerMac DACA");
-
- for (i = 0; i < ARRAY_SIZE(daca_mixers); i++) {
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&daca_mixers[i], chip))) < 0)
- return err;
- }
-
-#ifdef CONFIG_PM
- chip->resume = daca_resume;
-#endif
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/ppc/keywest.c b/ANDROID_3.4.5/sound/ppc/keywest.c
deleted file mode 100644
index 4080becf..00000000
--- a/ANDROID_3.4.5/sound/ppc/keywest.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * common keywest i2c layer
- *
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <sound/core.h>
-#include "pmac.h"
-
-/*
- * we have to keep a static variable here since i2c attach_adapter
- * callback cannot pass a private data.
- */
-static struct pmac_keywest *keywest_ctx;
-
-
-static int keywest_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- i2c_set_clientdata(client, keywest_ctx);
- return 0;
-}
-
-/*
- * This is kind of a hack, best would be to turn powermac to fixed i2c
- * bus numbers and declare the sound device as part of platform
- * initialization
- */
-static int keywest_attach_adapter(struct i2c_adapter *adapter)
-{
- struct i2c_board_info info;
-
- if (! keywest_ctx)
- return -EINVAL;
-
- if (strncmp(adapter->name, "mac-io", 6))
- return 0; /* ignored */
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- strlcpy(info.type, "keywest", I2C_NAME_SIZE);
- info.addr = keywest_ctx->addr;
- keywest_ctx->client = i2c_new_device(adapter, &info);
- if (!keywest_ctx->client)
- return -ENODEV;
- /*
- * We know the driver is already loaded, so the device should be
- * already bound. If not it means binding failed, and then there
- * is no point in keeping the device instantiated.
- */
- if (!keywest_ctx->client->driver) {
- i2c_unregister_device(keywest_ctx->client);
- keywest_ctx->client = NULL;
- return -ENODEV;
- }
-
- /*
- * Let i2c-core delete that device on driver removal.
- * This is safe because i2c-core holds the core_lock mutex for us.
- */
- list_add_tail(&keywest_ctx->client->detected,
- &keywest_ctx->client->driver->clients);
- return 0;
-}
-
-static int keywest_remove(struct i2c_client *client)
-{
- if (! keywest_ctx)
- return 0;
- if (client == keywest_ctx->client)
- keywest_ctx->client = NULL;
-
- return 0;
-}
-
-
-static const struct i2c_device_id keywest_i2c_id[] = {
- { "keywest", 0 },
- { }
-};
-
-static struct i2c_driver keywest_driver = {
- .driver = {
- .name = "PMac Keywest Audio",
- },
- .attach_adapter = keywest_attach_adapter,
- .probe = keywest_probe,
- .remove = keywest_remove,
- .id_table = keywest_i2c_id,
-};
-
-/* exported */
-void snd_pmac_keywest_cleanup(struct pmac_keywest *i2c)
-{
- if (keywest_ctx && keywest_ctx == i2c) {
- i2c_del_driver(&keywest_driver);
- keywest_ctx = NULL;
- }
-}
-
-int __devinit snd_pmac_tumbler_post_init(void)
-{
- int err;
-
- if (!keywest_ctx || !keywest_ctx->client)
- return -ENXIO;
-
- if ((err = keywest_ctx->init_client(keywest_ctx)) < 0) {
- snd_printk(KERN_ERR "tumbler: %i :cannot initialize the MCS\n", err);
- return err;
- }
- return 0;
-}
-
-/* exported */
-int __devinit snd_pmac_keywest_init(struct pmac_keywest *i2c)
-{
- int err;
-
- if (keywest_ctx)
- return -EBUSY;
-
- keywest_ctx = i2c;
-
- if ((err = i2c_add_driver(&keywest_driver))) {
- snd_printk(KERN_ERR "cannot register keywest i2c driver\n");
- return err;
- }
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/ppc/pmac.c b/ANDROID_3.4.5/sound/ppc/pmac.c
deleted file mode 100644
index ab96cde7..00000000
--- a/ANDROID_3.4.5/sound/ppc/pmac.c
+++ /dev/null
@@ -1,1410 +0,0 @@
-/*
- * PMac DBDMA lowlevel functions
- *
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- * code based on dmasound.c.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <sound/core.h>
-#include "pmac.h"
-#include <sound/pcm_params.h>
-#include <asm/pmac_feature.h>
-#include <asm/pci-bridge.h>
-
-
-/* fixed frequency table for awacs, screamer, burgundy, DACA (44100 max) */
-static int awacs_freqs[8] = {
- 44100, 29400, 22050, 17640, 14700, 11025, 8820, 7350
-};
-/* fixed frequency table for tumbler */
-static int tumbler_freqs[1] = {
- 44100
-};
-
-
-/*
- * we will allocate a single 'emergency' dbdma cmd block to use if the
- * tx status comes up "DEAD". This happens on some PowerComputing Pmac
- * clones, either owing to a bug in dbdma or some interaction between
- * IDE and sound. However, this measure would deal with DEAD status if
- * it appeared elsewhere.
- */
-static struct pmac_dbdma emergency_dbdma;
-static int emergency_in_use;
-
-
-/*
- * allocate DBDMA command arrays
- */
-static int snd_pmac_dbdma_alloc(struct snd_pmac *chip, struct pmac_dbdma *rec, int size)
-{
- unsigned int rsize = sizeof(struct dbdma_cmd) * (size + 1);
-
- rec->space = dma_alloc_coherent(&chip->pdev->dev, rsize,
- &rec->dma_base, GFP_KERNEL);
- if (rec->space == NULL)
- return -ENOMEM;
- rec->size = size;
- memset(rec->space, 0, rsize);
- rec->cmds = (void __iomem *)DBDMA_ALIGN(rec->space);
- rec->addr = rec->dma_base + (unsigned long)((char *)rec->cmds - (char *)rec->space);
-
- return 0;
-}
-
-static void snd_pmac_dbdma_free(struct snd_pmac *chip, struct pmac_dbdma *rec)
-{
- if (rec->space) {
- unsigned int rsize = sizeof(struct dbdma_cmd) * (rec->size + 1);
-
- dma_free_coherent(&chip->pdev->dev, rsize, rec->space, rec->dma_base);
- }
-}
-
-
-/*
- * pcm stuff
- */
-
-/*
- * look up frequency table
- */
-
-unsigned int snd_pmac_rate_index(struct snd_pmac *chip, struct pmac_stream *rec, unsigned int rate)
-{
- int i, ok, found;
-
- ok = rec->cur_freqs;
- if (rate > chip->freq_table[0])
- return 0;
- found = 0;
- for (i = 0; i < chip->num_freqs; i++, ok >>= 1) {
- if (! (ok & 1)) continue;
- found = i;
- if (rate >= chip->freq_table[i])
- break;
- }
- return found;
-}
-
-/*
- * check whether another stream is active
- */
-static inline int another_stream(int stream)
-{
- return (stream == SNDRV_PCM_STREAM_PLAYBACK) ?
- SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
-}
-
-/*
- * allocate buffers
- */
-static int snd_pmac_pcm_hw_params(struct snd_pcm_substream *subs,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(subs, params_buffer_bytes(hw_params));
-}
-
-/*
- * release buffers
- */
-static int snd_pmac_pcm_hw_free(struct snd_pcm_substream *subs)
-{
- snd_pcm_lib_free_pages(subs);
- return 0;
-}
-
-/*
- * get a stream of the opposite direction
- */
-static struct pmac_stream *snd_pmac_get_stream(struct snd_pmac *chip, int stream)
-{
- switch (stream) {
- case SNDRV_PCM_STREAM_PLAYBACK:
- return &chip->playback;
- case SNDRV_PCM_STREAM_CAPTURE:
- return &chip->capture;
- default:
- snd_BUG();
- return NULL;
- }
-}
-
-/*
- * wait while run status is on
- */
-static inline void
-snd_pmac_wait_ack(struct pmac_stream *rec)
-{
- int timeout = 50000;
- while ((in_le32(&rec->dma->status) & RUN) && timeout-- > 0)
- udelay(1);
-}
-
-/*
- * set the format and rate to the chip.
- * call the lowlevel function if defined (e.g. for AWACS).
- */
-static void snd_pmac_pcm_set_format(struct snd_pmac *chip)
-{
- /* set up frequency and format */
- out_le32(&chip->awacs->control, chip->control_mask | (chip->rate_index << 8));
- out_le32(&chip->awacs->byteswap, chip->format == SNDRV_PCM_FORMAT_S16_LE ? 1 : 0);
- if (chip->set_format)
- chip->set_format(chip);
-}
-
-/*
- * stop the DMA transfer
- */
-static inline void snd_pmac_dma_stop(struct pmac_stream *rec)
-{
- out_le32(&rec->dma->control, (RUN|WAKE|FLUSH|PAUSE) << 16);
- snd_pmac_wait_ack(rec);
-}
-
-/*
- * set the command pointer address
- */
-static inline void snd_pmac_dma_set_command(struct pmac_stream *rec, struct pmac_dbdma *cmd)
-{
- out_le32(&rec->dma->cmdptr, cmd->addr);
-}
-
-/*
- * start the DMA
- */
-static inline void snd_pmac_dma_run(struct pmac_stream *rec, int status)
-{
- out_le32(&rec->dma->control, status | (status << 16));
-}
-
-
-/*
- * prepare playback/capture stream
- */
-static int snd_pmac_pcm_prepare(struct snd_pmac *chip, struct pmac_stream *rec, struct snd_pcm_substream *subs)
-{
- int i;
- volatile struct dbdma_cmd __iomem *cp;
- struct snd_pcm_runtime *runtime = subs->runtime;
- int rate_index;
- long offset;
- struct pmac_stream *astr;
-
- rec->dma_size = snd_pcm_lib_buffer_bytes(subs);
- rec->period_size = snd_pcm_lib_period_bytes(subs);
- rec->nperiods = rec->dma_size / rec->period_size;
- rec->cur_period = 0;
- rate_index = snd_pmac_rate_index(chip, rec, runtime->rate);
-
- /* set up constraints */
- astr = snd_pmac_get_stream(chip, another_stream(rec->stream));
- if (! astr)
- return -EINVAL;
- astr->cur_freqs = 1 << rate_index;
- astr->cur_formats = 1 << runtime->format;
- chip->rate_index = rate_index;
- chip->format = runtime->format;
-
- /* We really want to execute a DMA stop command, after the AWACS
- * is initialized.
- * For reasons I don't understand, it stops the hissing noise
- * common to many PowerBook G3 systems and random noise otherwise
- * captured on iBook2's about every third time. -ReneR
- */
- spin_lock_irq(&chip->reg_lock);
- snd_pmac_dma_stop(rec);
- st_le16(&chip->extra_dma.cmds->command, DBDMA_STOP);
- snd_pmac_dma_set_command(rec, &chip->extra_dma);
- snd_pmac_dma_run(rec, RUN);
- spin_unlock_irq(&chip->reg_lock);
- mdelay(5);
- spin_lock_irq(&chip->reg_lock);
- /* continuous DMA memory type doesn't provide the physical address,
- * so we need to resolve the address here...
- */
- offset = runtime->dma_addr;
- for (i = 0, cp = rec->cmd.cmds; i < rec->nperiods; i++, cp++) {
- st_le32(&cp->phy_addr, offset);
- st_le16(&cp->req_count, rec->period_size);
- /*st_le16(&cp->res_count, 0);*/
- st_le16(&cp->xfer_status, 0);
- offset += rec->period_size;
- }
- /* make loop */
- st_le16(&cp->command, DBDMA_NOP + BR_ALWAYS);
- st_le32(&cp->cmd_dep, rec->cmd.addr);
-
- snd_pmac_dma_stop(rec);
- snd_pmac_dma_set_command(rec, &rec->cmd);
- spin_unlock_irq(&chip->reg_lock);
-
- return 0;
-}
-
-
-/*
- * PCM trigger/stop
- */
-static int snd_pmac_pcm_trigger(struct snd_pmac *chip, struct pmac_stream *rec,
- struct snd_pcm_substream *subs, int cmd)
-{
- volatile struct dbdma_cmd __iomem *cp;
- int i, command;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- if (rec->running)
- return -EBUSY;
- command = (subs->stream == SNDRV_PCM_STREAM_PLAYBACK ?
- OUTPUT_MORE : INPUT_MORE) + INTR_ALWAYS;
- spin_lock(&chip->reg_lock);
- snd_pmac_beep_stop(chip);
- snd_pmac_pcm_set_format(chip);
- for (i = 0, cp = rec->cmd.cmds; i < rec->nperiods; i++, cp++)
- out_le16(&cp->command, command);
- snd_pmac_dma_set_command(rec, &rec->cmd);
- (void)in_le32(&rec->dma->status);
- snd_pmac_dma_run(rec, RUN|WAKE);
- rec->running = 1;
- spin_unlock(&chip->reg_lock);
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- spin_lock(&chip->reg_lock);
- rec->running = 0;
- /*printk(KERN_DEBUG "stopped!!\n");*/
- snd_pmac_dma_stop(rec);
- for (i = 0, cp = rec->cmd.cmds; i < rec->nperiods; i++, cp++)
- out_le16(&cp->command, DBDMA_STOP);
- spin_unlock(&chip->reg_lock);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * return the current pointer
- */
-inline
-static snd_pcm_uframes_t snd_pmac_pcm_pointer(struct snd_pmac *chip,
- struct pmac_stream *rec,
- struct snd_pcm_substream *subs)
-{
- int count = 0;
-
-#if 1 /* hmm.. how can we get the current dma pointer?? */
- int stat;
- volatile struct dbdma_cmd __iomem *cp = &rec->cmd.cmds[rec->cur_period];
- stat = ld_le16(&cp->xfer_status);
- if (stat & (ACTIVE|DEAD)) {
- count = in_le16(&cp->res_count);
- if (count)
- count = rec->period_size - count;
- }
-#endif
- count += rec->cur_period * rec->period_size;
- /*printk(KERN_DEBUG "pointer=%d\n", count);*/
- return bytes_to_frames(subs->runtime, count);
-}
-
-/*
- * playback
- */
-
-static int snd_pmac_playback_prepare(struct snd_pcm_substream *subs)
-{
- struct snd_pmac *chip = snd_pcm_substream_chip(subs);
- return snd_pmac_pcm_prepare(chip, &chip->playback, subs);
-}
-
-static int snd_pmac_playback_trigger(struct snd_pcm_substream *subs,
- int cmd)
-{
- struct snd_pmac *chip = snd_pcm_substream_chip(subs);
- return snd_pmac_pcm_trigger(chip, &chip->playback, subs, cmd);
-}
-
-static snd_pcm_uframes_t snd_pmac_playback_pointer(struct snd_pcm_substream *subs)
-{
- struct snd_pmac *chip = snd_pcm_substream_chip(subs);
- return snd_pmac_pcm_pointer(chip, &chip->playback, subs);
-}
-
-
-/*
- * capture
- */
-
-static int snd_pmac_capture_prepare(struct snd_pcm_substream *subs)
-{
- struct snd_pmac *chip = snd_pcm_substream_chip(subs);
- return snd_pmac_pcm_prepare(chip, &chip->capture, subs);
-}
-
-static int snd_pmac_capture_trigger(struct snd_pcm_substream *subs,
- int cmd)
-{
- struct snd_pmac *chip = snd_pcm_substream_chip(subs);
- return snd_pmac_pcm_trigger(chip, &chip->capture, subs, cmd);
-}
-
-static snd_pcm_uframes_t snd_pmac_capture_pointer(struct snd_pcm_substream *subs)
-{
- struct snd_pmac *chip = snd_pcm_substream_chip(subs);
- return snd_pmac_pcm_pointer(chip, &chip->capture, subs);
-}
-
-
-/*
- * Handle DEAD DMA transfers:
- * if the TX status comes up "DEAD" - reported on some Power Computing machines
- * we need to re-start the dbdma - but from a different physical start address
- * and with a different transfer length. It would get very messy to do this
- * with the normal dbdma_cmd blocks - we would have to re-write the buffer start
- * addresses each time. So, we will keep a single dbdma_cmd block which can be
- * fiddled with.
- * When DEAD status is first reported the content of the faulted dbdma block is
- * copied into the emergency buffer and we note that the buffer is in use.
- * we then bump the start physical address by the amount that was successfully
- * output before it died.
- * On any subsequent DEAD result we just do the bump-ups (we know that we are
- * already using the emergency dbdma_cmd).
- * CHECK: this just tries to "do it". It is possible that we should abandon
- * xfers when the number of residual bytes gets below a certain value - I can
- * see that this might cause a loop-forever if a too small transfer causes
- * DEAD status. However this is a TODO for now - we'll see what gets reported.
- * When we get a successful transfer result with the emergency buffer we just
- * pretend that it completed using the original dmdma_cmd and carry on. The
- * 'next_cmd' field will already point back to the original loop of blocks.
- */
-static inline void snd_pmac_pcm_dead_xfer(struct pmac_stream *rec,
- volatile struct dbdma_cmd __iomem *cp)
-{
- unsigned short req, res ;
- unsigned int phy ;
-
- /* printk(KERN_WARNING "snd-powermac: DMA died - patching it up!\n"); */
-
- /* to clear DEAD status we must first clear RUN
- set it to quiescent to be on the safe side */
- (void)in_le32(&rec->dma->status);
- out_le32(&rec->dma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
-
- if (!emergency_in_use) { /* new problem */
- memcpy((void *)emergency_dbdma.cmds, (void *)cp,
- sizeof(struct dbdma_cmd));
- emergency_in_use = 1;
- st_le16(&cp->xfer_status, 0);
- st_le16(&cp->req_count, rec->period_size);
- cp = emergency_dbdma.cmds;
- }
-
- /* now bump the values to reflect the amount
- we haven't yet shifted */
- req = ld_le16(&cp->req_count);
- res = ld_le16(&cp->res_count);
- phy = ld_le32(&cp->phy_addr);
- phy += (req - res);
- st_le16(&cp->req_count, res);
- st_le16(&cp->res_count, 0);
- st_le16(&cp->xfer_status, 0);
- st_le32(&cp->phy_addr, phy);
-
- st_le32(&cp->cmd_dep, rec->cmd.addr
- + sizeof(struct dbdma_cmd)*((rec->cur_period+1)%rec->nperiods));
-
- st_le16(&cp->command, OUTPUT_MORE | BR_ALWAYS | INTR_ALWAYS);
-
- /* point at our patched up command block */
- out_le32(&rec->dma->cmdptr, emergency_dbdma.addr);
-
- /* we must re-start the controller */
- (void)in_le32(&rec->dma->status);
- /* should complete clearing the DEAD status */
- out_le32(&rec->dma->control, ((RUN|WAKE) << 16) + (RUN|WAKE));
-}
-
-/*
- * update playback/capture pointer from interrupts
- */
-static void snd_pmac_pcm_update(struct snd_pmac *chip, struct pmac_stream *rec)
-{
- volatile struct dbdma_cmd __iomem *cp;
- int c;
- int stat;
-
- spin_lock(&chip->reg_lock);
- if (rec->running) {
- for (c = 0; c < rec->nperiods; c++) { /* at most all fragments */
-
- if (emergency_in_use) /* already using DEAD xfer? */
- cp = emergency_dbdma.cmds;
- else
- cp = &rec->cmd.cmds[rec->cur_period];
-
- stat = ld_le16(&cp->xfer_status);
-
- if (stat & DEAD) {
- snd_pmac_pcm_dead_xfer(rec, cp);
- break; /* this block is still going */
- }
-
- if (emergency_in_use)
- emergency_in_use = 0 ; /* done that */
-
- if (! (stat & ACTIVE))
- break;
-
- /*printk(KERN_DEBUG "update frag %d\n", rec->cur_period);*/
- st_le16(&cp->xfer_status, 0);
- st_le16(&cp->req_count, rec->period_size);
- /*st_le16(&cp->res_count, 0);*/
- rec->cur_period++;
- if (rec->cur_period >= rec->nperiods) {
- rec->cur_period = 0;
- }
-
- spin_unlock(&chip->reg_lock);
- snd_pcm_period_elapsed(rec->substream);
- spin_lock(&chip->reg_lock);
- }
- }
- spin_unlock(&chip->reg_lock);
-}
-
-
-/*
- * hw info
- */
-
-static struct snd_pcm_hardware snd_pmac_playback =
-{
- .info = (SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_RESUME),
- .formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_8000_44100,
- .rate_min = 7350,
- .rate_max = 44100,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 131072,
- .period_bytes_min = 256,
- .period_bytes_max = 16384,
- .periods_min = 3,
- .periods_max = PMAC_MAX_FRAGS,
-};
-
-static struct snd_pcm_hardware snd_pmac_capture =
-{
- .info = (SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_RESUME),
- .formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_8000_44100,
- .rate_min = 7350,
- .rate_max = 44100,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 131072,
- .period_bytes_min = 256,
- .period_bytes_max = 16384,
- .periods_min = 3,
- .periods_max = PMAC_MAX_FRAGS,
-};
-
-
-#if 0 // NYI
-static int snd_pmac_hw_rule_rate(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_pmac *chip = rule->private;
- struct pmac_stream *rec = snd_pmac_get_stream(chip, rule->deps[0]);
- int i, freq_table[8], num_freqs;
-
- if (! rec)
- return -EINVAL;
- num_freqs = 0;
- for (i = chip->num_freqs - 1; i >= 0; i--) {
- if (rec->cur_freqs & (1 << i))
- freq_table[num_freqs++] = chip->freq_table[i];
- }
-
- return snd_interval_list(hw_param_interval(params, rule->var),
- num_freqs, freq_table, 0);
-}
-
-static int snd_pmac_hw_rule_format(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_pmac *chip = rule->private;
- struct pmac_stream *rec = snd_pmac_get_stream(chip, rule->deps[0]);
-
- if (! rec)
- return -EINVAL;
- return snd_mask_refine_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
- rec->cur_formats);
-}
-#endif // NYI
-
-static int snd_pmac_pcm_open(struct snd_pmac *chip, struct pmac_stream *rec,
- struct snd_pcm_substream *subs)
-{
- struct snd_pcm_runtime *runtime = subs->runtime;
- int i;
-
- /* look up frequency table and fill bit mask */
- runtime->hw.rates = 0;
- for (i = 0; i < chip->num_freqs; i++)
- if (chip->freqs_ok & (1 << i))
- runtime->hw.rates |=
- snd_pcm_rate_to_rate_bit(chip->freq_table[i]);
-
- /* check for minimum and maximum rates */
- for (i = 0; i < chip->num_freqs; i++) {
- if (chip->freqs_ok & (1 << i)) {
- runtime->hw.rate_max = chip->freq_table[i];
- break;
- }
- }
- for (i = chip->num_freqs - 1; i >= 0; i--) {
- if (chip->freqs_ok & (1 << i)) {
- runtime->hw.rate_min = chip->freq_table[i];
- break;
- }
- }
- runtime->hw.formats = chip->formats_ok;
- if (chip->can_capture) {
- if (! chip->can_duplex)
- runtime->hw.info |= SNDRV_PCM_INFO_HALF_DUPLEX;
- runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX;
- }
- runtime->private_data = rec;
- rec->substream = subs;
-
-#if 0 /* FIXME: still under development.. */
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- snd_pmac_hw_rule_rate, chip, rec->stream, -1);
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
- snd_pmac_hw_rule_format, chip, rec->stream, -1);
-#endif
-
- runtime->hw.periods_max = rec->cmd.size - 1;
-
- /* constraints to fix choppy sound */
- snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
- return 0;
-}
-
-static int snd_pmac_pcm_close(struct snd_pmac *chip, struct pmac_stream *rec,
- struct snd_pcm_substream *subs)
-{
- struct pmac_stream *astr;
-
- snd_pmac_dma_stop(rec);
-
- astr = snd_pmac_get_stream(chip, another_stream(rec->stream));
- if (! astr)
- return -EINVAL;
-
- /* reset constraints */
- astr->cur_freqs = chip->freqs_ok;
- astr->cur_formats = chip->formats_ok;
-
- return 0;
-}
-
-static int snd_pmac_playback_open(struct snd_pcm_substream *subs)
-{
- struct snd_pmac *chip = snd_pcm_substream_chip(subs);
-
- subs->runtime->hw = snd_pmac_playback;
- return snd_pmac_pcm_open(chip, &chip->playback, subs);
-}
-
-static int snd_pmac_capture_open(struct snd_pcm_substream *subs)
-{
- struct snd_pmac *chip = snd_pcm_substream_chip(subs);
-
- subs->runtime->hw = snd_pmac_capture;
- return snd_pmac_pcm_open(chip, &chip->capture, subs);
-}
-
-static int snd_pmac_playback_close(struct snd_pcm_substream *subs)
-{
- struct snd_pmac *chip = snd_pcm_substream_chip(subs);
-
- return snd_pmac_pcm_close(chip, &chip->playback, subs);
-}
-
-static int snd_pmac_capture_close(struct snd_pcm_substream *subs)
-{
- struct snd_pmac *chip = snd_pcm_substream_chip(subs);
-
- return snd_pmac_pcm_close(chip, &chip->capture, subs);
-}
-
-/*
- */
-
-static struct snd_pcm_ops snd_pmac_playback_ops = {
- .open = snd_pmac_playback_open,
- .close = snd_pmac_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_pmac_pcm_hw_params,
- .hw_free = snd_pmac_pcm_hw_free,
- .prepare = snd_pmac_playback_prepare,
- .trigger = snd_pmac_playback_trigger,
- .pointer = snd_pmac_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_pmac_capture_ops = {
- .open = snd_pmac_capture_open,
- .close = snd_pmac_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_pmac_pcm_hw_params,
- .hw_free = snd_pmac_pcm_hw_free,
- .prepare = snd_pmac_capture_prepare,
- .trigger = snd_pmac_capture_trigger,
- .pointer = snd_pmac_capture_pointer,
-};
-
-int __devinit snd_pmac_pcm_new(struct snd_pmac *chip)
-{
- struct snd_pcm *pcm;
- int err;
- int num_captures = 1;
-
- if (! chip->can_capture)
- num_captures = 0;
- err = snd_pcm_new(chip->card, chip->card->driver, 0, 1, num_captures, &pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_pmac_playback_ops);
- if (chip->can_capture)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_pmac_capture_ops);
-
- pcm->private_data = chip;
- pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
- strcpy(pcm->name, chip->card->shortname);
- chip->pcm = pcm;
-
- chip->formats_ok = SNDRV_PCM_FMTBIT_S16_BE;
- if (chip->can_byte_swap)
- chip->formats_ok |= SNDRV_PCM_FMTBIT_S16_LE;
-
- chip->playback.cur_formats = chip->formats_ok;
- chip->capture.cur_formats = chip->formats_ok;
- chip->playback.cur_freqs = chip->freqs_ok;
- chip->capture.cur_freqs = chip->freqs_ok;
-
- /* preallocate 64k buffer */
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- &chip->pdev->dev,
- 64 * 1024, 64 * 1024);
-
- return 0;
-}
-
-
-static void snd_pmac_dbdma_reset(struct snd_pmac *chip)
-{
- out_le32(&chip->playback.dma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
- snd_pmac_wait_ack(&chip->playback);
- out_le32(&chip->capture.dma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
- snd_pmac_wait_ack(&chip->capture);
-}
-
-
-/*
- * handling beep
- */
-void snd_pmac_beep_dma_start(struct snd_pmac *chip, int bytes, unsigned long addr, int speed)
-{
- struct pmac_stream *rec = &chip->playback;
-
- snd_pmac_dma_stop(rec);
- st_le16(&chip->extra_dma.cmds->req_count, bytes);
- st_le16(&chip->extra_dma.cmds->xfer_status, 0);
- st_le32(&chip->extra_dma.cmds->cmd_dep, chip->extra_dma.addr);
- st_le32(&chip->extra_dma.cmds->phy_addr, addr);
- st_le16(&chip->extra_dma.cmds->command, OUTPUT_MORE + BR_ALWAYS);
- out_le32(&chip->awacs->control,
- (in_le32(&chip->awacs->control) & ~0x1f00)
- | (speed << 8));
- out_le32(&chip->awacs->byteswap, 0);
- snd_pmac_dma_set_command(rec, &chip->extra_dma);
- snd_pmac_dma_run(rec, RUN);
-}
-
-void snd_pmac_beep_dma_stop(struct snd_pmac *chip)
-{
- snd_pmac_dma_stop(&chip->playback);
- st_le16(&chip->extra_dma.cmds->command, DBDMA_STOP);
- snd_pmac_pcm_set_format(chip); /* reset format */
-}
-
-
-/*
- * interrupt handlers
- */
-static irqreturn_t
-snd_pmac_tx_intr(int irq, void *devid)
-{
- struct snd_pmac *chip = devid;
- snd_pmac_pcm_update(chip, &chip->playback);
- return IRQ_HANDLED;
-}
-
-
-static irqreturn_t
-snd_pmac_rx_intr(int irq, void *devid)
-{
- struct snd_pmac *chip = devid;
- snd_pmac_pcm_update(chip, &chip->capture);
- return IRQ_HANDLED;
-}
-
-
-static irqreturn_t
-snd_pmac_ctrl_intr(int irq, void *devid)
-{
- struct snd_pmac *chip = devid;
- int ctrl = in_le32(&chip->awacs->control);
-
- /*printk(KERN_DEBUG "pmac: control interrupt.. 0x%x\n", ctrl);*/
- if (ctrl & MASK_PORTCHG) {
- /* do something when headphone is plugged/unplugged? */
- if (chip->update_automute)
- chip->update_automute(chip, 1);
- }
- if (ctrl & MASK_CNTLERR) {
- int err = (in_le32(&chip->awacs->codec_stat) & MASK_ERRCODE) >> 16;
- if (err && chip->model <= PMAC_SCREAMER)
- snd_printk(KERN_DEBUG "error %x\n", err);
- }
- /* Writing 1s to the CNTLERR and PORTCHG bits clears them... */
- out_le32(&chip->awacs->control, ctrl);
- return IRQ_HANDLED;
-}
-
-
-/*
- * a wrapper to feature call for compatibility
- */
-static void snd_pmac_sound_feature(struct snd_pmac *chip, int enable)
-{
- if (ppc_md.feature_call)
- ppc_md.feature_call(PMAC_FTR_SOUND_CHIP_ENABLE, chip->node, 0, enable);
-}
-
-/*
- * release resources
- */
-
-static int snd_pmac_free(struct snd_pmac *chip)
-{
- /* stop sounds */
- if (chip->initialized) {
- snd_pmac_dbdma_reset(chip);
- /* disable interrupts from awacs interface */
- out_le32(&chip->awacs->control, in_le32(&chip->awacs->control) & 0xfff);
- }
-
- if (chip->node)
- snd_pmac_sound_feature(chip, 0);
-
- /* clean up mixer if any */
- if (chip->mixer_free)
- chip->mixer_free(chip);
-
- snd_pmac_detach_beep(chip);
-
- /* release resources */
- if (chip->irq >= 0)
- free_irq(chip->irq, (void*)chip);
- if (chip->tx_irq >= 0)
- free_irq(chip->tx_irq, (void*)chip);
- if (chip->rx_irq >= 0)
- free_irq(chip->rx_irq, (void*)chip);
- snd_pmac_dbdma_free(chip, &chip->playback.cmd);
- snd_pmac_dbdma_free(chip, &chip->capture.cmd);
- snd_pmac_dbdma_free(chip, &chip->extra_dma);
- snd_pmac_dbdma_free(chip, &emergency_dbdma);
- if (chip->macio_base)
- iounmap(chip->macio_base);
- if (chip->latch_base)
- iounmap(chip->latch_base);
- if (chip->awacs)
- iounmap(chip->awacs);
- if (chip->playback.dma)
- iounmap(chip->playback.dma);
- if (chip->capture.dma)
- iounmap(chip->capture.dma);
-
- if (chip->node) {
- int i;
- for (i = 0; i < 3; i++) {
- if (chip->requested & (1 << i))
- release_mem_region(chip->rsrc[i].start,
- resource_size(&chip->rsrc[i]));
- }
- }
-
- if (chip->pdev)
- pci_dev_put(chip->pdev);
- of_node_put(chip->node);
- kfree(chip);
- return 0;
-}
-
-
-/*
- * free the device
- */
-static int snd_pmac_dev_free(struct snd_device *device)
-{
- struct snd_pmac *chip = device->device_data;
- return snd_pmac_free(chip);
-}
-
-
-/*
- * check the machine support byteswap (little-endian)
- */
-
-static void __devinit detect_byte_swap(struct snd_pmac *chip)
-{
- struct device_node *mio;
-
- /* if seems that Keylargo can't byte-swap */
- for (mio = chip->node->parent; mio; mio = mio->parent) {
- if (strcmp(mio->name, "mac-io") == 0) {
- if (of_device_is_compatible(mio, "Keylargo"))
- chip->can_byte_swap = 0;
- break;
- }
- }
-
- /* it seems the Pismo & iBook can't byte-swap in hardware. */
- if (of_machine_is_compatible("PowerBook3,1") ||
- of_machine_is_compatible("PowerBook2,1"))
- chip->can_byte_swap = 0 ;
-
- if (of_machine_is_compatible("PowerBook2,1"))
- chip->can_duplex = 0;
-}
-
-
-/*
- * detect a sound chip
- */
-static int __devinit snd_pmac_detect(struct snd_pmac *chip)
-{
- struct device_node *sound;
- struct device_node *dn;
- const unsigned int *prop;
- unsigned int l;
- struct macio_chip* macio;
-
- if (!machine_is(powermac))
- return -ENODEV;
-
- chip->subframe = 0;
- chip->revision = 0;
- chip->freqs_ok = 0xff; /* all ok */
- chip->model = PMAC_AWACS;
- chip->can_byte_swap = 1;
- chip->can_duplex = 1;
- chip->can_capture = 1;
- chip->num_freqs = ARRAY_SIZE(awacs_freqs);
- chip->freq_table = awacs_freqs;
- chip->pdev = NULL;
-
- chip->control_mask = MASK_IEPC | MASK_IEE | 0x11; /* default */
-
- /* check machine type */
- if (of_machine_is_compatible("AAPL,3400/2400")
- || of_machine_is_compatible("AAPL,3500"))
- chip->is_pbook_3400 = 1;
- else if (of_machine_is_compatible("PowerBook1,1")
- || of_machine_is_compatible("AAPL,PowerBook1998"))
- chip->is_pbook_G3 = 1;
- chip->node = of_find_node_by_name(NULL, "awacs");
- sound = of_node_get(chip->node);
-
- /*
- * powermac G3 models have a node called "davbus"
- * with a child called "sound".
- */
- if (!chip->node)
- chip->node = of_find_node_by_name(NULL, "davbus");
- /*
- * if we didn't find a davbus device, try 'i2s-a' since
- * this seems to be what iBooks have
- */
- if (! chip->node) {
- chip->node = of_find_node_by_name(NULL, "i2s-a");
- if (chip->node && chip->node->parent &&
- chip->node->parent->parent) {
- if (of_device_is_compatible(chip->node->parent->parent,
- "K2-Keylargo"))
- chip->is_k2 = 1;
- }
- }
- if (! chip->node)
- return -ENODEV;
-
- if (!sound) {
- sound = of_find_node_by_name(NULL, "sound");
- while (sound && sound->parent != chip->node)
- sound = of_find_node_by_name(sound, "sound");
- }
- if (! sound) {
- of_node_put(chip->node);
- chip->node = NULL;
- return -ENODEV;
- }
- prop = of_get_property(sound, "sub-frame", NULL);
- if (prop && *prop < 16)
- chip->subframe = *prop;
- prop = of_get_property(sound, "layout-id", NULL);
- if (prop) {
- /* partly deprecate snd-powermac, for those machines
- * that have a layout-id property for now */
- printk(KERN_INFO "snd-powermac no longer handles any "
- "machines with a layout-id property "
- "in the device-tree, use snd-aoa.\n");
- of_node_put(sound);
- of_node_put(chip->node);
- chip->node = NULL;
- return -ENODEV;
- }
- /* This should be verified on older screamers */
- if (of_device_is_compatible(sound, "screamer")) {
- chip->model = PMAC_SCREAMER;
- // chip->can_byte_swap = 0; /* FIXME: check this */
- }
- if (of_device_is_compatible(sound, "burgundy")) {
- chip->model = PMAC_BURGUNDY;
- chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
- }
- if (of_device_is_compatible(sound, "daca")) {
- chip->model = PMAC_DACA;
- chip->can_capture = 0; /* no capture */
- chip->can_duplex = 0;
- // chip->can_byte_swap = 0; /* FIXME: check this */
- chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
- }
- if (of_device_is_compatible(sound, "tumbler")) {
- chip->model = PMAC_TUMBLER;
- chip->can_capture = of_machine_is_compatible("PowerMac4,2")
- || of_machine_is_compatible("PowerBook3,2")
- || of_machine_is_compatible("PowerBook3,3")
- || of_machine_is_compatible("PowerBook4,1")
- || of_machine_is_compatible("PowerBook4,2")
- || of_machine_is_compatible("PowerBook4,3");
- chip->can_duplex = 0;
- // chip->can_byte_swap = 0; /* FIXME: check this */
- chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
- chip->freq_table = tumbler_freqs;
- chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
- }
- if (of_device_is_compatible(sound, "snapper")) {
- chip->model = PMAC_SNAPPER;
- // chip->can_byte_swap = 0; /* FIXME: check this */
- chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
- chip->freq_table = tumbler_freqs;
- chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
- }
- prop = of_get_property(sound, "device-id", NULL);
- if (prop)
- chip->device_id = *prop;
- dn = of_find_node_by_name(NULL, "perch");
- chip->has_iic = (dn != NULL);
- of_node_put(dn);
-
- /* We need the PCI device for DMA allocations, let's use a crude method
- * for now ...
- */
- macio = macio_find(chip->node, macio_unknown);
- if (macio == NULL)
- printk(KERN_WARNING "snd-powermac: can't locate macio !\n");
- else {
- struct pci_dev *pdev = NULL;
-
- for_each_pci_dev(pdev) {
- struct device_node *np = pci_device_to_OF_node(pdev);
- if (np && np == macio->of_node) {
- chip->pdev = pdev;
- break;
- }
- }
- }
- if (chip->pdev == NULL)
- printk(KERN_WARNING "snd-powermac: can't locate macio PCI"
- " device !\n");
-
- detect_byte_swap(chip);
-
- /* look for a property saying what sample rates
- are available */
- prop = of_get_property(sound, "sample-rates", &l);
- if (! prop)
- prop = of_get_property(sound, "output-frame-rates", &l);
- if (prop) {
- int i;
- chip->freqs_ok = 0;
- for (l /= sizeof(int); l > 0; --l) {
- unsigned int r = *prop++;
- /* Apple 'Fixed' format */
- if (r >= 0x10000)
- r >>= 16;
- for (i = 0; i < chip->num_freqs; ++i) {
- if (r == chip->freq_table[i]) {
- chip->freqs_ok |= (1 << i);
- break;
- }
- }
- }
- } else {
- /* assume only 44.1khz */
- chip->freqs_ok = 1;
- }
-
- of_node_put(sound);
- return 0;
-}
-
-#ifdef PMAC_SUPPORT_AUTOMUTE
-/*
- * auto-mute
- */
-static int pmac_auto_mute_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = chip->auto_mute;
- return 0;
-}
-
-static int pmac_auto_mute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- if (ucontrol->value.integer.value[0] != chip->auto_mute) {
- chip->auto_mute = !!ucontrol->value.integer.value[0];
- if (chip->update_automute)
- chip->update_automute(chip, 1);
- return 1;
- }
- return 0;
-}
-
-static int pmac_hp_detect_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- if (chip->detect_headphone)
- ucontrol->value.integer.value[0] = chip->detect_headphone(chip);
- else
- ucontrol->value.integer.value[0] = 0;
- return 0;
-}
-
-static struct snd_kcontrol_new auto_mute_controls[] __devinitdata = {
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Auto Mute Switch",
- .info = snd_pmac_boolean_mono_info,
- .get = pmac_auto_mute_get,
- .put = pmac_auto_mute_put,
- },
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Headphone Detection",
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .info = snd_pmac_boolean_mono_info,
- .get = pmac_hp_detect_get,
- },
-};
-
-int __devinit snd_pmac_add_automute(struct snd_pmac *chip)
-{
- int err;
- chip->auto_mute = 1;
- err = snd_ctl_add(chip->card, snd_ctl_new1(&auto_mute_controls[0], chip));
- if (err < 0) {
- printk(KERN_ERR "snd-powermac: Failed to add automute control\n");
- return err;
- }
- chip->hp_detect_ctl = snd_ctl_new1(&auto_mute_controls[1], chip);
- return snd_ctl_add(chip->card, chip->hp_detect_ctl);
-}
-#endif /* PMAC_SUPPORT_AUTOMUTE */
-
-/*
- * create and detect a pmac chip record
- */
-int __devinit snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return)
-{
- struct snd_pmac *chip;
- struct device_node *np;
- int i, err;
- unsigned int irq;
- unsigned long ctrl_addr, txdma_addr, rxdma_addr;
- static struct snd_device_ops ops = {
- .dev_free = snd_pmac_dev_free,
- };
-
- *chip_return = NULL;
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL)
- return -ENOMEM;
- chip->card = card;
-
- spin_lock_init(&chip->reg_lock);
- chip->irq = chip->tx_irq = chip->rx_irq = -1;
-
- chip->playback.stream = SNDRV_PCM_STREAM_PLAYBACK;
- chip->capture.stream = SNDRV_PCM_STREAM_CAPTURE;
-
- if ((err = snd_pmac_detect(chip)) < 0)
- goto __error;
-
- if (snd_pmac_dbdma_alloc(chip, &chip->playback.cmd, PMAC_MAX_FRAGS + 1) < 0 ||
- snd_pmac_dbdma_alloc(chip, &chip->capture.cmd, PMAC_MAX_FRAGS + 1) < 0 ||
- snd_pmac_dbdma_alloc(chip, &chip->extra_dma, 2) < 0 ||
- snd_pmac_dbdma_alloc(chip, &emergency_dbdma, 2) < 0) {
- err = -ENOMEM;
- goto __error;
- }
-
- np = chip->node;
- chip->requested = 0;
- if (chip->is_k2) {
- static char *rnames[] = {
- "Sound Control", "Sound DMA" };
- for (i = 0; i < 2; i ++) {
- if (of_address_to_resource(np->parent, i,
- &chip->rsrc[i])) {
- printk(KERN_ERR "snd: can't translate rsrc "
- " %d (%s)\n", i, rnames[i]);
- err = -ENODEV;
- goto __error;
- }
- if (request_mem_region(chip->rsrc[i].start,
- resource_size(&chip->rsrc[i]),
- rnames[i]) == NULL) {
- printk(KERN_ERR "snd: can't request rsrc "
- " %d (%s: %pR)\n",
- i, rnames[i], &chip->rsrc[i]);
- err = -ENODEV;
- goto __error;
- }
- chip->requested |= (1 << i);
- }
- ctrl_addr = chip->rsrc[0].start;
- txdma_addr = chip->rsrc[1].start;
- rxdma_addr = txdma_addr + 0x100;
- } else {
- static char *rnames[] = {
- "Sound Control", "Sound Tx DMA", "Sound Rx DMA" };
- for (i = 0; i < 3; i ++) {
- if (of_address_to_resource(np, i,
- &chip->rsrc[i])) {
- printk(KERN_ERR "snd: can't translate rsrc "
- " %d (%s)\n", i, rnames[i]);
- err = -ENODEV;
- goto __error;
- }
- if (request_mem_region(chip->rsrc[i].start,
- resource_size(&chip->rsrc[i]),
- rnames[i]) == NULL) {
- printk(KERN_ERR "snd: can't request rsrc "
- " %d (%s: %pR)\n",
- i, rnames[i], &chip->rsrc[i]);
- err = -ENODEV;
- goto __error;
- }
- chip->requested |= (1 << i);
- }
- ctrl_addr = chip->rsrc[0].start;
- txdma_addr = chip->rsrc[1].start;
- rxdma_addr = chip->rsrc[2].start;
- }
-
- chip->awacs = ioremap(ctrl_addr, 0x1000);
- chip->playback.dma = ioremap(txdma_addr, 0x100);
- chip->capture.dma = ioremap(rxdma_addr, 0x100);
- if (chip->model <= PMAC_BURGUNDY) {
- irq = irq_of_parse_and_map(np, 0);
- if (request_irq(irq, snd_pmac_ctrl_intr, 0,
- "PMac", (void*)chip)) {
- snd_printk(KERN_ERR "pmac: unable to grab IRQ %d\n",
- irq);
- err = -EBUSY;
- goto __error;
- }
- chip->irq = irq;
- }
- irq = irq_of_parse_and_map(np, 1);
- if (request_irq(irq, snd_pmac_tx_intr, 0, "PMac Output", (void*)chip)){
- snd_printk(KERN_ERR "pmac: unable to grab IRQ %d\n", irq);
- err = -EBUSY;
- goto __error;
- }
- chip->tx_irq = irq;
- irq = irq_of_parse_and_map(np, 2);
- if (request_irq(irq, snd_pmac_rx_intr, 0, "PMac Input", (void*)chip)) {
- snd_printk(KERN_ERR "pmac: unable to grab IRQ %d\n", irq);
- err = -EBUSY;
- goto __error;
- }
- chip->rx_irq = irq;
-
- snd_pmac_sound_feature(chip, 1);
-
- /* reset & enable interrupts */
- if (chip->model <= PMAC_BURGUNDY)
- out_le32(&chip->awacs->control, chip->control_mask);
-
- /* Powerbooks have odd ways of enabling inputs such as
- an expansion-bay CD or sound from an internal modem
- or a PC-card modem. */
- if (chip->is_pbook_3400) {
- /* Enable CD and PC-card sound inputs. */
- /* This is done by reading from address
- * f301a000, + 0x10 to enable the expansion-bay
- * CD sound input, + 0x80 to enable the PC-card
- * sound input. The 0x100 enables the SCSI bus
- * terminator power.
- */
- chip->latch_base = ioremap (0xf301a000, 0x1000);
- in_8(chip->latch_base + 0x190);
- } else if (chip->is_pbook_G3) {
- struct device_node* mio;
- for (mio = chip->node->parent; mio; mio = mio->parent) {
- if (strcmp(mio->name, "mac-io") == 0) {
- struct resource r;
- if (of_address_to_resource(mio, 0, &r) == 0)
- chip->macio_base =
- ioremap(r.start, 0x40);
- break;
- }
- }
- /* Enable CD sound input. */
- /* The relevant bits for writing to this byte are 0x8f.
- * I haven't found out what the 0x80 bit does.
- * For the 0xf bits, writing 3 or 7 enables the CD
- * input, any other value disables it. Values
- * 1, 3, 5, 7 enable the microphone. Values 0, 2,
- * 4, 6, 8 - f enable the input from the modem.
- */
- if (chip->macio_base)
- out_8(chip->macio_base + 0x37, 3);
- }
-
- /* Reset dbdma channels */
- snd_pmac_dbdma_reset(chip);
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0)
- goto __error;
-
- *chip_return = chip;
- return 0;
-
- __error:
- snd_pmac_free(chip);
- return err;
-}
-
-
-/*
- * sleep notify for powerbook
- */
-
-#ifdef CONFIG_PM
-
-/*
- * Save state when going to sleep, restore it afterwards.
- */
-
-void snd_pmac_suspend(struct snd_pmac *chip)
-{
- unsigned long flags;
-
- snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
- if (chip->suspend)
- chip->suspend(chip);
- snd_pcm_suspend_all(chip->pcm);
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_pmac_beep_stop(chip);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (chip->irq >= 0)
- disable_irq(chip->irq);
- if (chip->tx_irq >= 0)
- disable_irq(chip->tx_irq);
- if (chip->rx_irq >= 0)
- disable_irq(chip->rx_irq);
- snd_pmac_sound_feature(chip, 0);
-}
-
-void snd_pmac_resume(struct snd_pmac *chip)
-{
- snd_pmac_sound_feature(chip, 1);
- if (chip->resume)
- chip->resume(chip);
- /* enable CD sound input */
- if (chip->macio_base && chip->is_pbook_G3)
- out_8(chip->macio_base + 0x37, 3);
- else if (chip->is_pbook_3400)
- in_8(chip->latch_base + 0x190);
-
- snd_pmac_pcm_set_format(chip);
-
- if (chip->irq >= 0)
- enable_irq(chip->irq);
- if (chip->tx_irq >= 0)
- enable_irq(chip->tx_irq);
- if (chip->rx_irq >= 0)
- enable_irq(chip->rx_irq);
-
- snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
-}
-
-#endif /* CONFIG_PM */
-
diff --git a/ANDROID_3.4.5/sound/ppc/pmac.h b/ANDROID_3.4.5/sound/ppc/pmac.h
deleted file mode 100644
index 25c512c2..00000000
--- a/ANDROID_3.4.5/sound/ppc/pmac.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Driver for PowerMac onboard soundchips
- * Copyright (c) 2001 by Takashi Iwai <tiwai@suse.de>
- * based on dmasound.c.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#ifndef __PMAC_H
-#define __PMAC_H
-
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include "awacs.h"
-
-#include <linux/adb.h>
-#ifdef CONFIG_ADB_CUDA
-#include <linux/cuda.h>
-#endif
-#ifdef CONFIG_ADB_PMU
-#include <linux/pmu.h>
-#endif
-#include <linux/nvram.h>
-#include <linux/tty.h>
-#include <linux/vt_kern.h>
-#include <asm/dbdma.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-
-/* maximum number of fragments */
-#define PMAC_MAX_FRAGS 32
-
-
-#define PMAC_SUPPORT_AUTOMUTE
-
-/*
- * DBDMA space
- */
-struct pmac_dbdma {
- dma_addr_t dma_base;
- dma_addr_t addr;
- struct dbdma_cmd __iomem *cmds;
- void *space;
- int size;
-};
-
-/*
- * playback/capture stream
- */
-struct pmac_stream {
- int running; /* boolean */
-
- int stream; /* PLAYBACK/CAPTURE */
-
- int dma_size; /* in bytes */
- int period_size; /* in bytes */
- int buffer_size; /* in kbytes */
- int nperiods, cur_period;
-
- struct pmac_dbdma cmd;
- volatile struct dbdma_regs __iomem *dma;
-
- struct snd_pcm_substream *substream;
-
- unsigned int cur_freqs; /* currently available frequencies */
- unsigned int cur_formats; /* currently available formats */
-};
-
-
-/*
- */
-
-enum snd_pmac_model {
- PMAC_AWACS, PMAC_SCREAMER, PMAC_BURGUNDY, PMAC_DACA, PMAC_TUMBLER,
- PMAC_SNAPPER
-};
-
-struct snd_pmac {
- struct snd_card *card;
-
- /* h/w info */
- struct device_node *node;
- struct pci_dev *pdev;
- unsigned int revision;
- unsigned int manufacturer;
- unsigned int subframe;
- unsigned int device_id;
- enum snd_pmac_model model;
-
- unsigned int has_iic : 1;
- unsigned int is_pbook_3400 : 1;
- unsigned int is_pbook_G3 : 1;
- unsigned int is_k2 : 1;
-
- unsigned int can_byte_swap : 1;
- unsigned int can_duplex : 1;
- unsigned int can_capture : 1;
-
- unsigned int auto_mute : 1;
- unsigned int initialized : 1;
- unsigned int feature_is_set : 1;
-
- unsigned int requested;
- struct resource rsrc[3];
-
- int num_freqs;
- int *freq_table;
- unsigned int freqs_ok; /* bit flags */
- unsigned int formats_ok; /* pcm hwinfo */
- int active;
- int rate_index;
- int format; /* current format */
-
- spinlock_t reg_lock;
- volatile struct awacs_regs __iomem *awacs;
- int awacs_reg[8]; /* register cache */
- unsigned int hp_stat_mask;
-
- unsigned char __iomem *latch_base;
- unsigned char __iomem *macio_base;
-
- struct pmac_stream playback;
- struct pmac_stream capture;
-
- struct pmac_dbdma extra_dma;
-
- int irq, tx_irq, rx_irq;
-
- struct snd_pcm *pcm;
-
- struct pmac_beep *beep;
-
- unsigned int control_mask; /* control mask */
-
- /* mixer stuffs */
- void *mixer_data;
- void (*mixer_free)(struct snd_pmac *);
- struct snd_kcontrol *master_sw_ctl;
- struct snd_kcontrol *speaker_sw_ctl;
- struct snd_kcontrol *drc_sw_ctl; /* only used for tumbler -ReneR */
- struct snd_kcontrol *hp_detect_ctl;
- struct snd_kcontrol *lineout_sw_ctl;
-
- /* lowlevel callbacks */
- void (*set_format)(struct snd_pmac *chip);
- void (*update_automute)(struct snd_pmac *chip, int do_notify);
- int (*detect_headphone)(struct snd_pmac *chip);
-#ifdef CONFIG_PM
- void (*suspend)(struct snd_pmac *chip);
- void (*resume)(struct snd_pmac *chip);
-#endif
-
-};
-
-
-/* exported functions */
-int snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return);
-int snd_pmac_pcm_new(struct snd_pmac *chip);
-int snd_pmac_attach_beep(struct snd_pmac *chip);
-void snd_pmac_detach_beep(struct snd_pmac *chip);
-void snd_pmac_beep_stop(struct snd_pmac *chip);
-unsigned int snd_pmac_rate_index(struct snd_pmac *chip, struct pmac_stream *rec, unsigned int rate);
-
-void snd_pmac_beep_dma_start(struct snd_pmac *chip, int bytes, unsigned long addr, int speed);
-void snd_pmac_beep_dma_stop(struct snd_pmac *chip);
-
-#ifdef CONFIG_PM
-void snd_pmac_suspend(struct snd_pmac *chip);
-void snd_pmac_resume(struct snd_pmac *chip);
-#endif
-
-/* initialize mixer */
-int snd_pmac_awacs_init(struct snd_pmac *chip);
-int snd_pmac_burgundy_init(struct snd_pmac *chip);
-int snd_pmac_daca_init(struct snd_pmac *chip);
-int snd_pmac_tumbler_init(struct snd_pmac *chip);
-int snd_pmac_tumbler_post_init(void);
-
-/* i2c functions */
-struct pmac_keywest {
- int addr;
- struct i2c_client *client;
- int id;
- int (*init_client)(struct pmac_keywest *i2c);
- char *name;
-};
-
-int snd_pmac_keywest_init(struct pmac_keywest *i2c);
-void snd_pmac_keywest_cleanup(struct pmac_keywest *i2c);
-
-/* misc */
-#define snd_pmac_boolean_stereo_info snd_ctl_boolean_stereo_info
-#define snd_pmac_boolean_mono_info snd_ctl_boolean_mono_info
-
-int snd_pmac_add_automute(struct snd_pmac *chip);
-
-#endif /* __PMAC_H */
diff --git a/ANDROID_3.4.5/sound/ppc/powermac.c b/ANDROID_3.4.5/sound/ppc/powermac.c
deleted file mode 100644
index 5a4e263b..00000000
--- a/ANDROID_3.4.5/sound/ppc/powermac.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Driver for PowerMac AWACS
- * Copyright (c) 2001 by Takashi Iwai <tiwai@suse.de>
- * based on dmasound.c.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include "pmac.h"
-#include "awacs.h"
-#include "burgundy.h"
-
-#define CHIP_NAME "PMac"
-
-MODULE_DESCRIPTION("PowerMac");
-MODULE_SUPPORTED_DEVICE("{{Apple,PowerMac}}");
-MODULE_LICENSE("GPL");
-
-static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
-static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
-static bool enable_beep = 1;
-
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for " CHIP_NAME " soundchip.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for " CHIP_NAME " soundchip.");
-module_param(enable_beep, bool, 0444);
-MODULE_PARM_DESC(enable_beep, "Enable beep using PCM.");
-
-static struct platform_device *device;
-
-
-/*
- */
-
-static int __devinit snd_pmac_probe(struct platform_device *devptr)
-{
- struct snd_card *card;
- struct snd_pmac *chip;
- char *name_ext;
- int err;
-
- err = snd_card_create(index, id, THIS_MODULE, 0, &card);
- if (err < 0)
- return err;
-
- if ((err = snd_pmac_new(card, &chip)) < 0)
- goto __error;
- card->private_data = chip;
-
- switch (chip->model) {
- case PMAC_BURGUNDY:
- strcpy(card->driver, "PMac Burgundy");
- strcpy(card->shortname, "PowerMac Burgundy");
- sprintf(card->longname, "%s (Dev %d) Sub-frame %d",
- card->shortname, chip->device_id, chip->subframe);
- if ((err = snd_pmac_burgundy_init(chip)) < 0)
- goto __error;
- break;
- case PMAC_DACA:
- strcpy(card->driver, "PMac DACA");
- strcpy(card->shortname, "PowerMac DACA");
- sprintf(card->longname, "%s (Dev %d) Sub-frame %d",
- card->shortname, chip->device_id, chip->subframe);
- if ((err = snd_pmac_daca_init(chip)) < 0)
- goto __error;
- break;
- case PMAC_TUMBLER:
- case PMAC_SNAPPER:
- name_ext = chip->model == PMAC_TUMBLER ? "Tumbler" : "Snapper";
- sprintf(card->driver, "PMac %s", name_ext);
- sprintf(card->shortname, "PowerMac %s", name_ext);
- sprintf(card->longname, "%s (Dev %d) Sub-frame %d",
- card->shortname, chip->device_id, chip->subframe);
- if ( snd_pmac_tumbler_init(chip) < 0 || snd_pmac_tumbler_post_init() < 0)
- goto __error;
- break;
- case PMAC_AWACS:
- case PMAC_SCREAMER:
- name_ext = chip->model == PMAC_SCREAMER ? "Screamer" : "AWACS";
- sprintf(card->driver, "PMac %s", name_ext);
- sprintf(card->shortname, "PowerMac %s", name_ext);
- if (chip->is_pbook_3400)
- name_ext = " [PB3400]";
- else if (chip->is_pbook_G3)
- name_ext = " [PBG3]";
- else
- name_ext = "";
- sprintf(card->longname, "%s%s Rev %d",
- card->shortname, name_ext, chip->revision);
- if ((err = snd_pmac_awacs_init(chip)) < 0)
- goto __error;
- break;
- default:
- snd_printk(KERN_ERR "unsupported hardware %d\n", chip->model);
- err = -EINVAL;
- goto __error;
- }
-
- if ((err = snd_pmac_pcm_new(chip)) < 0)
- goto __error;
-
- chip->initialized = 1;
- if (enable_beep)
- snd_pmac_attach_beep(chip);
-
- snd_card_set_dev(card, &devptr->dev);
-
- if ((err = snd_card_register(card)) < 0)
- goto __error;
-
- platform_set_drvdata(devptr, card);
- return 0;
-
-__error:
- snd_card_free(card);
- return err;
-}
-
-
-static int __devexit snd_pmac_remove(struct platform_device *devptr)
-{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int snd_pmac_driver_suspend(struct platform_device *devptr, pm_message_t state)
-{
- struct snd_card *card = platform_get_drvdata(devptr);
- snd_pmac_suspend(card->private_data);
- return 0;
-}
-
-static int snd_pmac_driver_resume(struct platform_device *devptr)
-{
- struct snd_card *card = platform_get_drvdata(devptr);
- snd_pmac_resume(card->private_data);
- return 0;
-}
-#endif
-
-#define SND_PMAC_DRIVER "snd_powermac"
-
-static struct platform_driver snd_pmac_driver = {
- .probe = snd_pmac_probe,
- .remove = __devexit_p(snd_pmac_remove),
-#ifdef CONFIG_PM
- .suspend = snd_pmac_driver_suspend,
- .resume = snd_pmac_driver_resume,
-#endif
- .driver = {
- .name = SND_PMAC_DRIVER
- },
-};
-
-static int __init alsa_card_pmac_init(void)
-{
- int err;
-
- if ((err = platform_driver_register(&snd_pmac_driver)) < 0)
- return err;
- device = platform_device_register_simple(SND_PMAC_DRIVER, -1, NULL, 0);
- return 0;
-
-}
-
-static void __exit alsa_card_pmac_exit(void)
-{
- if (!IS_ERR(device))
- platform_device_unregister(device);
- platform_driver_unregister(&snd_pmac_driver);
-}
-
-module_init(alsa_card_pmac_init)
-module_exit(alsa_card_pmac_exit)
diff --git a/ANDROID_3.4.5/sound/ppc/snd_ps3.c b/ANDROID_3.4.5/sound/ppc/snd_ps3.c
deleted file mode 100644
index 1aa52eff..00000000
--- a/ANDROID_3.4.5/sound/ppc/snd_ps3.c
+++ /dev/null
@@ -1,1160 +0,0 @@
-/*
- * Audio support for PS3
- * Copyright (C) 2007 Sony Computer Entertainment Inc.
- * All rights reserved.
- * Copyright 2006, 2007 Sony Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; version 2 of the Licence.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/dmapool.h>
-#include <linux/gfp.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/module.h>
-
-#include <sound/asound.h>
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/memalloc.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-
-#include <asm/dma.h>
-#include <asm/firmware.h>
-#include <asm/lv1call.h>
-#include <asm/ps3.h>
-#include <asm/ps3av.h>
-
-#include "snd_ps3.h"
-#include "snd_ps3_reg.h"
-
-
-/*
- * global
- */
-static struct snd_ps3_card_info the_card;
-
-static int snd_ps3_start_delay = CONFIG_SND_PS3_DEFAULT_START_DELAY;
-
-module_param_named(start_delay, snd_ps3_start_delay, uint, 0644);
-MODULE_PARM_DESC(start_delay, "time to insert silent data in ms");
-
-static int index = SNDRV_DEFAULT_IDX1;
-static char *id = SNDRV_DEFAULT_STR1;
-
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for PS3 soundchip.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for PS3 soundchip.");
-
-
-/*
- * PS3 audio register access
- */
-static inline u32 read_reg(unsigned int reg)
-{
- return in_be32(the_card.mapped_mmio_vaddr + reg);
-}
-static inline void write_reg(unsigned int reg, u32 val)
-{
- out_be32(the_card.mapped_mmio_vaddr + reg, val);
-}
-static inline void update_reg(unsigned int reg, u32 or_val)
-{
- u32 newval = read_reg(reg) | or_val;
- write_reg(reg, newval);
-}
-static inline void update_mask_reg(unsigned int reg, u32 mask, u32 or_val)
-{
- u32 newval = (read_reg(reg) & mask) | or_val;
- write_reg(reg, newval);
-}
-
-/*
- * ALSA defs
- */
-static const struct snd_pcm_hardware snd_ps3_pcm_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_NONINTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = (SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_S24_BE),
- .rates = (SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000),
- .rate_min = 44100,
- .rate_max = 96000,
-
- .channels_min = 2, /* stereo only */
- .channels_max = 2,
-
- .buffer_bytes_max = PS3_AUDIO_FIFO_SIZE * 64,
-
- /* interrupt by four stages */
- .period_bytes_min = PS3_AUDIO_FIFO_STAGE_SIZE * 4,
- .period_bytes_max = PS3_AUDIO_FIFO_STAGE_SIZE * 4,
-
- .periods_min = 16,
- .periods_max = 32, /* buffer_size_max/ period_bytes_max */
-
- .fifo_size = PS3_AUDIO_FIFO_SIZE
-};
-
-static int snd_ps3_verify_dma_stop(struct snd_ps3_card_info *card,
- int count, int force_stop)
-{
- int dma_ch, done, retries, stop_forced = 0;
- uint32_t status;
-
- for (dma_ch = 0; dma_ch < 8; dma_ch++) {
- retries = count;
- do {
- status = read_reg(PS3_AUDIO_KICK(dma_ch)) &
- PS3_AUDIO_KICK_STATUS_MASK;
- switch (status) {
- case PS3_AUDIO_KICK_STATUS_DONE:
- case PS3_AUDIO_KICK_STATUS_NOTIFY:
- case PS3_AUDIO_KICK_STATUS_CLEAR:
- case PS3_AUDIO_KICK_STATUS_ERROR:
- done = 1;
- break;
- default:
- done = 0;
- udelay(10);
- }
- } while (!done && --retries);
- if (!retries && force_stop) {
- pr_info("%s: DMA ch %d is not stopped.",
- __func__, dma_ch);
- /* last resort. force to stop dma.
- * NOTE: this cause DMA done interrupts
- */
- update_reg(PS3_AUDIO_CONFIG, PS3_AUDIO_CONFIG_CLEAR);
- stop_forced = 1;
- }
- }
- return stop_forced;
-}
-
-/*
- * wait for all dma is done.
- * NOTE: caller should reset card->running before call.
- * If not, the interrupt handler will re-start DMA,
- * then DMA is never stopped.
- */
-static void snd_ps3_wait_for_dma_stop(struct snd_ps3_card_info *card)
-{
- int stop_forced;
- /*
- * wait for the last dma is done
- */
-
- /*
- * expected maximum DMA done time is 5.7ms + something (DMA itself).
- * 5.7ms is from 16bit/sample 2ch 44.1Khz; the time next
- * DMA kick event would occur.
- */
- stop_forced = snd_ps3_verify_dma_stop(card, 700, 1);
-
- /*
- * clear outstanding interrupts.
- */
- update_reg(PS3_AUDIO_INTR_0, 0);
- update_reg(PS3_AUDIO_AX_IS, 0);
-
- /*
- *revert CLEAR bit since it will not reset automatically after DMA stop
- */
- if (stop_forced)
- update_mask_reg(PS3_AUDIO_CONFIG, ~PS3_AUDIO_CONFIG_CLEAR, 0);
- /* ensure the hardware sees changes */
- wmb();
-}
-
-static void snd_ps3_kick_dma(struct snd_ps3_card_info *card)
-{
-
- update_reg(PS3_AUDIO_KICK(0), PS3_AUDIO_KICK_REQUEST);
- /* ensure the hardware sees the change */
- wmb();
-}
-
-/*
- * convert virtual addr to ioif bus addr.
- */
-static dma_addr_t v_to_bus(struct snd_ps3_card_info *card, void *paddr, int ch)
-{
- return card->dma_start_bus_addr[ch] +
- (paddr - card->dma_start_vaddr[ch]);
-};
-
-
-/*
- * increment ring buffer pointer.
- * NOTE: caller must hold write spinlock
- */
-static void snd_ps3_bump_buffer(struct snd_ps3_card_info *card,
- enum snd_ps3_ch ch, size_t byte_count,
- int stage)
-{
- if (!stage)
- card->dma_last_transfer_vaddr[ch] =
- card->dma_next_transfer_vaddr[ch];
- card->dma_next_transfer_vaddr[ch] += byte_count;
- if ((card->dma_start_vaddr[ch] + (card->dma_buffer_size / 2)) <=
- card->dma_next_transfer_vaddr[ch]) {
- card->dma_next_transfer_vaddr[ch] = card->dma_start_vaddr[ch];
- }
-}
-/*
- * setup dmac to send data to audio and attenuate samples on the ring buffer
- */
-static int snd_ps3_program_dma(struct snd_ps3_card_info *card,
- enum snd_ps3_dma_filltype filltype)
-{
- /* this dmac does not support over 4G */
- uint32_t dma_addr;
- int fill_stages, dma_ch, stage;
- enum snd_ps3_ch ch;
- uint32_t ch0_kick_event = 0; /* initialize to mute gcc */
- void *start_vaddr;
- unsigned long irqsave;
- int silent = 0;
-
- switch (filltype) {
- case SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL:
- silent = 1;
- /* intentionally fall thru */
- case SND_PS3_DMA_FILLTYPE_FIRSTFILL:
- ch0_kick_event = PS3_AUDIO_KICK_EVENT_ALWAYS;
- break;
-
- case SND_PS3_DMA_FILLTYPE_SILENT_RUNNING:
- silent = 1;
- /* intentionally fall thru */
- case SND_PS3_DMA_FILLTYPE_RUNNING:
- ch0_kick_event = PS3_AUDIO_KICK_EVENT_SERIALOUT0_EMPTY;
- break;
- }
-
- snd_ps3_verify_dma_stop(card, 700, 0);
- fill_stages = 4;
- spin_lock_irqsave(&card->dma_lock, irqsave);
- for (ch = 0; ch < 2; ch++) {
- start_vaddr = card->dma_next_transfer_vaddr[0];
- for (stage = 0; stage < fill_stages; stage++) {
- dma_ch = stage * 2 + ch;
- if (silent)
- dma_addr = card->null_buffer_start_dma_addr;
- else
- dma_addr =
- v_to_bus(card,
- card->dma_next_transfer_vaddr[ch],
- ch);
-
- write_reg(PS3_AUDIO_SOURCE(dma_ch),
- (PS3_AUDIO_SOURCE_TARGET_SYSTEM_MEMORY |
- dma_addr));
-
- /* dst: fixed to 3wire#0 */
- if (ch == 0)
- write_reg(PS3_AUDIO_DEST(dma_ch),
- (PS3_AUDIO_DEST_TARGET_AUDIOFIFO |
- PS3_AUDIO_AO_3W_LDATA(0)));
- else
- write_reg(PS3_AUDIO_DEST(dma_ch),
- (PS3_AUDIO_DEST_TARGET_AUDIOFIFO |
- PS3_AUDIO_AO_3W_RDATA(0)));
-
- /* count always 1 DMA block (1/2 stage = 128 bytes) */
- write_reg(PS3_AUDIO_DMASIZE(dma_ch), 0);
- /* bump pointer if needed */
- if (!silent)
- snd_ps3_bump_buffer(card, ch,
- PS3_AUDIO_DMAC_BLOCK_SIZE,
- stage);
-
- /* kick event */
- if (dma_ch == 0)
- write_reg(PS3_AUDIO_KICK(dma_ch),
- ch0_kick_event);
- else
- write_reg(PS3_AUDIO_KICK(dma_ch),
- PS3_AUDIO_KICK_EVENT_AUDIO_DMA(dma_ch
- - 1) |
- PS3_AUDIO_KICK_REQUEST);
- }
- }
- /* ensure the hardware sees the change */
- wmb();
- spin_unlock_irqrestore(&card->dma_lock, irqsave);
-
- return 0;
-}
-
-/*
- * Interrupt handler
- */
-static irqreturn_t snd_ps3_interrupt(int irq, void *dev_id)
-{
-
- uint32_t port_intr;
- int underflow_occured = 0;
- struct snd_ps3_card_info *card = dev_id;
-
- if (!card->running) {
- update_reg(PS3_AUDIO_AX_IS, 0);
- update_reg(PS3_AUDIO_INTR_0, 0);
- return IRQ_HANDLED;
- }
-
- port_intr = read_reg(PS3_AUDIO_AX_IS);
- /*
- *serial buffer empty detected (every 4 times),
- *program next dma and kick it
- */
- if (port_intr & PS3_AUDIO_AX_IE_ASOBEIE(0)) {
- write_reg(PS3_AUDIO_AX_IS, PS3_AUDIO_AX_IE_ASOBEIE(0));
- if (port_intr & PS3_AUDIO_AX_IE_ASOBUIE(0)) {
- write_reg(PS3_AUDIO_AX_IS, port_intr);
- underflow_occured = 1;
- }
- if (card->silent) {
- /* we are still in silent time */
- snd_ps3_program_dma(card,
- (underflow_occured) ?
- SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL :
- SND_PS3_DMA_FILLTYPE_SILENT_RUNNING);
- snd_ps3_kick_dma(card);
- card->silent--;
- } else {
- snd_ps3_program_dma(card,
- (underflow_occured) ?
- SND_PS3_DMA_FILLTYPE_FIRSTFILL :
- SND_PS3_DMA_FILLTYPE_RUNNING);
- snd_ps3_kick_dma(card);
- snd_pcm_period_elapsed(card->substream);
- }
- } else if (port_intr & PS3_AUDIO_AX_IE_ASOBUIE(0)) {
- write_reg(PS3_AUDIO_AX_IS, PS3_AUDIO_AX_IE_ASOBUIE(0));
- /*
- * serial out underflow, but buffer empty not detected.
- * in this case, fill fifo with 0 to recover. After
- * filling dummy data, serial automatically start to
- * consume them and then will generate normal buffer
- * empty interrupts.
- * If both buffer underflow and buffer empty are occurred,
- * it is better to do nomal data transfer than empty one
- */
- snd_ps3_program_dma(card,
- SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL);
- snd_ps3_kick_dma(card);
- snd_ps3_program_dma(card,
- SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL);
- snd_ps3_kick_dma(card);
- }
- /* clear interrupt cause */
- return IRQ_HANDLED;
-};
-
-/*
- * audio mute on/off
- * mute_on : 0 output enabled
- * 1 mute
- */
-static int snd_ps3_mute(int mute_on)
-{
- return ps3av_audio_mute(mute_on);
-}
-
-/*
- * av setting
- * NOTE: calling this function may generate audio interrupt.
- */
-static int snd_ps3_change_avsetting(struct snd_ps3_card_info *card)
-{
- int ret, retries, i;
- pr_debug("%s: start\n", __func__);
-
- ret = ps3av_set_audio_mode(card->avs.avs_audio_ch,
- card->avs.avs_audio_rate,
- card->avs.avs_audio_width,
- card->avs.avs_audio_format,
- card->avs.avs_audio_source);
- /*
- * Reset the following unwanted settings:
- */
-
- /* disable all 3wire buffers */
- update_mask_reg(PS3_AUDIO_AO_3WMCTRL,
- ~(PS3_AUDIO_AO_3WMCTRL_ASOEN(0) |
- PS3_AUDIO_AO_3WMCTRL_ASOEN(1) |
- PS3_AUDIO_AO_3WMCTRL_ASOEN(2) |
- PS3_AUDIO_AO_3WMCTRL_ASOEN(3)),
- 0);
- wmb(); /* ensure the hardware sees the change */
- /* wait for actually stopped */
- retries = 1000;
- while ((read_reg(PS3_AUDIO_AO_3WMCTRL) &
- (PS3_AUDIO_AO_3WMCTRL_ASORUN(0) |
- PS3_AUDIO_AO_3WMCTRL_ASORUN(1) |
- PS3_AUDIO_AO_3WMCTRL_ASORUN(2) |
- PS3_AUDIO_AO_3WMCTRL_ASORUN(3))) &&
- --retries) {
- udelay(1);
- }
-
- /* reset buffer pointer */
- for (i = 0; i < 4; i++) {
- update_reg(PS3_AUDIO_AO_3WCTRL(i),
- PS3_AUDIO_AO_3WCTRL_ASOBRST_RESET);
- udelay(10);
- }
- wmb(); /* ensure the hardware actually start resetting */
-
- /* enable 3wire#0 buffer */
- update_reg(PS3_AUDIO_AO_3WMCTRL, PS3_AUDIO_AO_3WMCTRL_ASOEN(0));
-
-
- /* In 24bit mode,ALSA inserts a zero byte at first byte of per sample */
- update_mask_reg(PS3_AUDIO_AO_3WCTRL(0),
- ~PS3_AUDIO_AO_3WCTRL_ASODF,
- PS3_AUDIO_AO_3WCTRL_ASODF_LSB);
- update_mask_reg(PS3_AUDIO_AO_SPDCTRL(0),
- ~PS3_AUDIO_AO_SPDCTRL_SPODF,
- PS3_AUDIO_AO_SPDCTRL_SPODF_LSB);
- /* ensure all the setting above is written back to register */
- wmb();
- /* avsetting driver altered AX_IE, caller must reset it if you want */
- pr_debug("%s: end\n", __func__);
- return ret;
-}
-
-/*
- * set sampling rate according to the substream
- */
-static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream)
-{
- struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream);
- struct snd_ps3_avsetting_info avs;
- int ret;
-
- avs = card->avs;
-
- pr_debug("%s: called freq=%d width=%d\n", __func__,
- substream->runtime->rate,
- snd_pcm_format_width(substream->runtime->format));
-
- pr_debug("%s: before freq=%d width=%d\n", __func__,
- card->avs.avs_audio_rate, card->avs.avs_audio_width);
-
- /* sample rate */
- switch (substream->runtime->rate) {
- case 44100:
- avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_44K;
- break;
- case 48000:
- avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_48K;
- break;
- case 88200:
- avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_88K;
- break;
- case 96000:
- avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_96K;
- break;
- default:
- pr_info("%s: invalid rate %d\n", __func__,
- substream->runtime->rate);
- return 1;
- }
-
- /* width */
- switch (snd_pcm_format_width(substream->runtime->format)) {
- case 16:
- avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16;
- break;
- case 24:
- avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_24;
- break;
- default:
- pr_info("%s: invalid width %d\n", __func__,
- snd_pcm_format_width(substream->runtime->format));
- return 1;
- }
-
- memcpy(avs.avs_cs_info, ps3av_mode_cs_info, 8);
-
- if (memcmp(&card->avs, &avs, sizeof(avs))) {
- pr_debug("%s: after freq=%d width=%d\n", __func__,
- card->avs.avs_audio_rate, card->avs.avs_audio_width);
-
- card->avs = avs;
- snd_ps3_change_avsetting(card);
- ret = 0;
- } else
- ret = 1;
-
- /* check CS non-audio bit and mute accordingly */
- if (avs.avs_cs_info[0] & 0x02)
- ps3av_audio_mute_analog(1); /* mute if non-audio */
- else
- ps3av_audio_mute_analog(0);
-
- return ret;
-}
-
-/*
- * PCM operators
- */
-static int snd_ps3_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream);
- int pcm_index;
-
- pcm_index = substream->pcm->device;
- /* to retrieve substream/runtime in interrupt handler */
- card->substream = substream;
-
- runtime->hw = snd_ps3_pcm_hw;
-
- card->start_delay = snd_ps3_start_delay;
-
- /* mute off */
- snd_ps3_mute(0); /* this function sleep */
-
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
- PS3_AUDIO_FIFO_STAGE_SIZE * 4 * 2);
- return 0;
-};
-
-static int snd_ps3_pcm_close(struct snd_pcm_substream *substream)
-{
- /* mute on */
- snd_ps3_mute(1);
- return 0;
-};
-
-static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- size_t size;
-
- /* alloc transport buffer */
- size = params_buffer_bytes(hw_params);
- snd_pcm_lib_malloc_pages(substream, size);
- return 0;
-};
-
-static int snd_ps3_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- int ret;
- ret = snd_pcm_lib_free_pages(substream);
- return ret;
-};
-
-static int snd_ps3_delay_to_bytes(struct snd_pcm_substream *substream,
- unsigned int delay_ms)
-{
- int ret;
- int rate ;
-
- rate = substream->runtime->rate;
- ret = snd_pcm_format_size(substream->runtime->format,
- rate * delay_ms / 1000)
- * substream->runtime->channels;
-
- pr_debug("%s: time=%d rate=%d bytes=%ld, frames=%d, ret=%d\n",
- __func__,
- delay_ms,
- rate,
- snd_pcm_format_size(substream->runtime->format, rate),
- rate * delay_ms / 1000,
- ret);
-
- return ret;
-};
-
-static int snd_ps3_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream);
- unsigned long irqsave;
-
- if (!snd_ps3_set_avsetting(substream)) {
- /* some parameter changed */
- write_reg(PS3_AUDIO_AX_IE,
- PS3_AUDIO_AX_IE_ASOBEIE(0) |
- PS3_AUDIO_AX_IE_ASOBUIE(0));
- /*
- * let SPDIF device re-lock with SPDIF signal,
- * start with some silence
- */
- card->silent = snd_ps3_delay_to_bytes(substream,
- card->start_delay) /
- (PS3_AUDIO_FIFO_STAGE_SIZE * 4); /* every 4 times */
- }
-
- /* restart ring buffer pointer */
- spin_lock_irqsave(&card->dma_lock, irqsave);
- {
- card->dma_buffer_size = runtime->dma_bytes;
-
- card->dma_last_transfer_vaddr[SND_PS3_CH_L] =
- card->dma_next_transfer_vaddr[SND_PS3_CH_L] =
- card->dma_start_vaddr[SND_PS3_CH_L] =
- runtime->dma_area;
- card->dma_start_bus_addr[SND_PS3_CH_L] = runtime->dma_addr;
-
- card->dma_last_transfer_vaddr[SND_PS3_CH_R] =
- card->dma_next_transfer_vaddr[SND_PS3_CH_R] =
- card->dma_start_vaddr[SND_PS3_CH_R] =
- runtime->dma_area + (runtime->dma_bytes / 2);
- card->dma_start_bus_addr[SND_PS3_CH_R] =
- runtime->dma_addr + (runtime->dma_bytes / 2);
-
- pr_debug("%s: vaddr=%p bus=%#llx\n", __func__,
- card->dma_start_vaddr[SND_PS3_CH_L],
- card->dma_start_bus_addr[SND_PS3_CH_L]);
-
- }
- spin_unlock_irqrestore(&card->dma_lock, irqsave);
-
- /* ensure the hardware sees the change */
- mb();
-
- return 0;
-};
-
-static int snd_ps3_pcm_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream);
- int ret = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- /* clear outstanding interrupts */
- update_reg(PS3_AUDIO_AX_IS, 0);
-
- spin_lock(&card->dma_lock);
- {
- card->running = 1;
- }
- spin_unlock(&card->dma_lock);
-
- snd_ps3_program_dma(card,
- SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL);
- snd_ps3_kick_dma(card);
- while (read_reg(PS3_AUDIO_KICK(7)) &
- PS3_AUDIO_KICK_STATUS_MASK) {
- udelay(1);
- }
- snd_ps3_program_dma(card, SND_PS3_DMA_FILLTYPE_SILENT_RUNNING);
- snd_ps3_kick_dma(card);
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- spin_lock(&card->dma_lock);
- {
- card->running = 0;
- }
- spin_unlock(&card->dma_lock);
- snd_ps3_wait_for_dma_stop(card);
- break;
- default:
- break;
-
- }
-
- return ret;
-};
-
-/*
- * report current pointer
- */
-static snd_pcm_uframes_t snd_ps3_pcm_pointer(
- struct snd_pcm_substream *substream)
-{
- struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream);
- size_t bytes;
- snd_pcm_uframes_t ret;
-
- spin_lock(&card->dma_lock);
- {
- bytes = (size_t)(card->dma_last_transfer_vaddr[SND_PS3_CH_L] -
- card->dma_start_vaddr[SND_PS3_CH_L]);
- }
- spin_unlock(&card->dma_lock);
-
- ret = bytes_to_frames(substream->runtime, bytes * 2);
-
- return ret;
-};
-
-/*
- * SPDIF status bits controls
- */
-static int snd_ps3_spdif_mask_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-
-/* FIXME: ps3av_set_audio_mode() assumes only consumer mode */
-static int snd_ps3_spdif_cmask_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- memset(ucontrol->value.iec958.status, 0xff, 8);
- return 0;
-}
-
-static int snd_ps3_spdif_pmask_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- return 0;
-}
-
-static int snd_ps3_spdif_default_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- memcpy(ucontrol->value.iec958.status, ps3av_mode_cs_info, 8);
- return 0;
-}
-
-static int snd_ps3_spdif_default_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- if (memcmp(ps3av_mode_cs_info, ucontrol->value.iec958.status, 8)) {
- memcpy(ps3av_mode_cs_info, ucontrol->value.iec958.status, 8);
- return 1;
- }
- return 0;
-}
-
-static struct snd_kcontrol_new spdif_ctls[] = {
- {
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
- .info = snd_ps3_spdif_mask_info,
- .get = snd_ps3_spdif_cmask_get,
- },
- {
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK),
- .info = snd_ps3_spdif_mask_info,
- .get = snd_ps3_spdif_pmask_get,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
- .info = snd_ps3_spdif_mask_info,
- .get = snd_ps3_spdif_default_get,
- .put = snd_ps3_spdif_default_put,
- },
-};
-
-static struct snd_pcm_ops snd_ps3_pcm_spdif_ops = {
- .open = snd_ps3_pcm_open,
- .close = snd_ps3_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_ps3_pcm_hw_params,
- .hw_free = snd_ps3_pcm_hw_free,
- .prepare = snd_ps3_pcm_prepare,
- .trigger = snd_ps3_pcm_trigger,
- .pointer = snd_ps3_pcm_pointer,
-};
-
-
-static int __devinit snd_ps3_map_mmio(void)
-{
- the_card.mapped_mmio_vaddr =
- ioremap(the_card.ps3_dev->m_region->bus_addr,
- the_card.ps3_dev->m_region->len);
-
- if (!the_card.mapped_mmio_vaddr) {
- pr_info("%s: ioremap 0 failed p=%#lx l=%#lx \n",
- __func__, the_card.ps3_dev->m_region->lpar_addr,
- the_card.ps3_dev->m_region->len);
- return -ENXIO;
- }
-
- return 0;
-};
-
-static void snd_ps3_unmap_mmio(void)
-{
- iounmap(the_card.mapped_mmio_vaddr);
- the_card.mapped_mmio_vaddr = NULL;
-}
-
-static int __devinit snd_ps3_allocate_irq(void)
-{
- int ret;
- u64 lpar_addr, lpar_size;
- u64 __iomem *mapped;
-
- /* FIXME: move this to device_init (H/W probe) */
-
- /* get irq outlet */
- ret = lv1_gpu_device_map(1, &lpar_addr, &lpar_size);
- if (ret) {
- pr_info("%s: device map 1 failed %d\n", __func__,
- ret);
- return -ENXIO;
- }
-
- mapped = ioremap(lpar_addr, lpar_size);
- if (!mapped) {
- pr_info("%s: ioremap 1 failed \n", __func__);
- return -ENXIO;
- }
-
- the_card.audio_irq_outlet = in_be64(mapped);
-
- iounmap(mapped);
- ret = lv1_gpu_device_unmap(1);
- if (ret)
- pr_info("%s: unmap 1 failed\n", __func__);
-
- /* irq */
- ret = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY,
- the_card.audio_irq_outlet,
- &the_card.irq_no);
- if (ret) {
- pr_info("%s:ps3_alloc_irq failed (%d)\n", __func__, ret);
- return ret;
- }
-
- ret = request_irq(the_card.irq_no, snd_ps3_interrupt, 0,
- SND_PS3_DRIVER_NAME, &the_card);
- if (ret) {
- pr_info("%s: request_irq failed (%d)\n", __func__, ret);
- goto cleanup_irq;
- }
-
- return 0;
-
- cleanup_irq:
- ps3_irq_plug_destroy(the_card.irq_no);
- return ret;
-};
-
-static void snd_ps3_free_irq(void)
-{
- free_irq(the_card.irq_no, &the_card);
- ps3_irq_plug_destroy(the_card.irq_no);
-}
-
-static void __devinit snd_ps3_audio_set_base_addr(uint64_t ioaddr_start)
-{
- uint64_t val;
- int ret;
-
- val = (ioaddr_start & (0x0fUL << 32)) >> (32 - 20) |
- (0x03UL << 24) |
- (0x0fUL << 12) |
- (PS3_AUDIO_IOID);
-
- ret = lv1_gpu_attribute(0x100, 0x007, val);
- if (ret)
- pr_info("%s: gpu_attribute failed %d\n", __func__,
- ret);
-}
-
-static void __devinit snd_ps3_audio_fixup(struct snd_ps3_card_info *card)
-{
- /*
- * avsetting driver seems to never change the followings
- * so, init them here once
- */
-
- /* no dma interrupt needed */
- write_reg(PS3_AUDIO_INTR_EN_0, 0);
-
- /* use every 4 buffer empty interrupt */
- update_mask_reg(PS3_AUDIO_AX_IC,
- PS3_AUDIO_AX_IC_AASOIMD_MASK,
- PS3_AUDIO_AX_IC_AASOIMD_EVERY4);
-
- /* enable 3wire clocks */
- update_mask_reg(PS3_AUDIO_AO_3WMCTRL,
- ~(PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_DISABLED |
- PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_DISABLED),
- 0);
- update_reg(PS3_AUDIO_AO_3WMCTRL,
- PS3_AUDIO_AO_3WMCTRL_ASOPLRCK_DEFAULT);
-}
-
-static int __devinit snd_ps3_init_avsetting(struct snd_ps3_card_info *card)
-{
- int ret;
- pr_debug("%s: start\n", __func__);
- card->avs.avs_audio_ch = PS3AV_CMD_AUDIO_NUM_OF_CH_2;
- card->avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_48K;
- card->avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16;
- card->avs.avs_audio_format = PS3AV_CMD_AUDIO_FORMAT_PCM;
- card->avs.avs_audio_source = PS3AV_CMD_AUDIO_SOURCE_SERIAL;
- memcpy(card->avs.avs_cs_info, ps3av_mode_cs_info, 8);
-
- ret = snd_ps3_change_avsetting(card);
-
- snd_ps3_audio_fixup(card);
-
- /* to start to generate SPDIF signal, fill data */
- snd_ps3_program_dma(card, SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL);
- snd_ps3_kick_dma(card);
- pr_debug("%s: end\n", __func__);
- return ret;
-}
-
-static int __devinit snd_ps3_driver_probe(struct ps3_system_bus_device *dev)
-{
- int i, ret;
- u64 lpar_addr, lpar_size;
-
- BUG_ON(!firmware_has_feature(FW_FEATURE_PS3_LV1));
- BUG_ON(dev->match_id != PS3_MATCH_ID_SOUND);
-
- the_card.ps3_dev = dev;
-
- ret = ps3_open_hv_device(dev);
-
- if (ret)
- return -ENXIO;
-
- /* setup MMIO */
- ret = lv1_gpu_device_map(2, &lpar_addr, &lpar_size);
- if (ret) {
- pr_info("%s: device map 2 failed %d\n", __func__, ret);
- goto clean_open;
- }
- ps3_mmio_region_init(dev, dev->m_region, lpar_addr, lpar_size,
- PAGE_SHIFT);
-
- ret = snd_ps3_map_mmio();
- if (ret)
- goto clean_dev_map;
-
- /* setup DMA area */
- ps3_dma_region_init(dev, dev->d_region,
- PAGE_SHIFT, /* use system page size */
- 0, /* dma type; not used */
- NULL,
- _ALIGN_UP(SND_PS3_DMA_REGION_SIZE, PAGE_SIZE));
- dev->d_region->ioid = PS3_AUDIO_IOID;
-
- ret = ps3_dma_region_create(dev->d_region);
- if (ret) {
- pr_info("%s: region_create\n", __func__);
- goto clean_mmio;
- }
-
- snd_ps3_audio_set_base_addr(dev->d_region->bus_addr);
-
- /* CONFIG_SND_PS3_DEFAULT_START_DELAY */
- the_card.start_delay = snd_ps3_start_delay;
-
- /* irq */
- if (snd_ps3_allocate_irq()) {
- ret = -ENXIO;
- goto clean_dma_region;
- }
-
- /* create card instance */
- ret = snd_card_create(index, id, THIS_MODULE, 0, &the_card.card);
- if (ret < 0)
- goto clean_irq;
-
- strcpy(the_card.card->driver, "PS3");
- strcpy(the_card.card->shortname, "PS3");
- strcpy(the_card.card->longname, "PS3 sound");
-
- /* create control elements */
- for (i = 0; i < ARRAY_SIZE(spdif_ctls); i++) {
- ret = snd_ctl_add(the_card.card,
- snd_ctl_new1(&spdif_ctls[i], &the_card));
- if (ret < 0)
- goto clean_card;
- }
-
- /* create PCM devices instance */
- /* NOTE:this driver works assuming pcm:substream = 1:1 */
- ret = snd_pcm_new(the_card.card,
- "SPDIF",
- 0, /* instance index, will be stored pcm.device*/
- 1, /* output substream */
- 0, /* input substream */
- &(the_card.pcm));
- if (ret)
- goto clean_card;
-
- the_card.pcm->private_data = &the_card;
- strcpy(the_card.pcm->name, "SPDIF");
-
- /* set pcm ops */
- snd_pcm_set_ops(the_card.pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_ps3_pcm_spdif_ops);
-
- the_card.pcm->info_flags = SNDRV_PCM_INFO_NONINTERLEAVED;
- /* pre-alloc PCM DMA buffer*/
- ret = snd_pcm_lib_preallocate_pages_for_all(the_card.pcm,
- SNDRV_DMA_TYPE_DEV,
- &dev->core,
- SND_PS3_PCM_PREALLOC_SIZE,
- SND_PS3_PCM_PREALLOC_SIZE);
- if (ret < 0) {
- pr_info("%s: prealloc failed\n", __func__);
- goto clean_card;
- }
-
- /*
- * allocate null buffer
- * its size should be lager than PS3_AUDIO_FIFO_STAGE_SIZE * 2
- * PAGE_SIZE is enogh
- */
- the_card.null_buffer_start_vaddr =
- dma_alloc_coherent(&the_card.ps3_dev->core,
- PAGE_SIZE,
- &the_card.null_buffer_start_dma_addr,
- GFP_KERNEL);
- if (!the_card.null_buffer_start_vaddr) {
- pr_info("%s: nullbuffer alloc failed\n", __func__);
- goto clean_preallocate;
- }
- pr_debug("%s: null vaddr=%p dma=%#llx\n", __func__,
- the_card.null_buffer_start_vaddr,
- the_card.null_buffer_start_dma_addr);
- /* set default sample rate/word width */
- snd_ps3_init_avsetting(&the_card);
-
- /* register the card */
- snd_card_set_dev(the_card.card, &dev->core);
- ret = snd_card_register(the_card.card);
- if (ret < 0)
- goto clean_dma_map;
-
- pr_info("%s started. start_delay=%dms\n",
- the_card.card->longname, the_card.start_delay);
- return 0;
-
-clean_dma_map:
- dma_free_coherent(&the_card.ps3_dev->core,
- PAGE_SIZE,
- the_card.null_buffer_start_vaddr,
- the_card.null_buffer_start_dma_addr);
-clean_preallocate:
- snd_pcm_lib_preallocate_free_for_all(the_card.pcm);
-clean_card:
- snd_card_free(the_card.card);
-clean_irq:
- snd_ps3_free_irq();
-clean_dma_region:
- ps3_dma_region_free(dev->d_region);
-clean_mmio:
- snd_ps3_unmap_mmio();
-clean_dev_map:
- lv1_gpu_device_unmap(2);
-clean_open:
- ps3_close_hv_device(dev);
- /*
- * there is no destructor function to pcm.
- * midlayer automatically releases if the card removed
- */
- return ret;
-}; /* snd_ps3_probe */
-
-/* called when module removal */
-static int snd_ps3_driver_remove(struct ps3_system_bus_device *dev)
-{
- int ret;
- pr_info("%s:start id=%d\n", __func__, dev->match_id);
- if (dev->match_id != PS3_MATCH_ID_SOUND)
- return -ENXIO;
-
- /*
- * ctl and preallocate buffer will be freed in
- * snd_card_free
- */
- ret = snd_card_free(the_card.card);
- if (ret)
- pr_info("%s: ctl freecard=%d\n", __func__, ret);
-
- dma_free_coherent(&dev->core,
- PAGE_SIZE,
- the_card.null_buffer_start_vaddr,
- the_card.null_buffer_start_dma_addr);
-
- ps3_dma_region_free(dev->d_region);
-
- snd_ps3_free_irq();
- snd_ps3_unmap_mmio();
-
- lv1_gpu_device_unmap(2);
- ps3_close_hv_device(dev);
- pr_info("%s:end id=%d\n", __func__, dev->match_id);
- return 0;
-} /* snd_ps3_remove */
-
-static struct ps3_system_bus_driver snd_ps3_bus_driver_info = {
- .match_id = PS3_MATCH_ID_SOUND,
- .probe = snd_ps3_driver_probe,
- .remove = snd_ps3_driver_remove,
- .shutdown = snd_ps3_driver_remove,
- .core = {
- .name = SND_PS3_DRIVER_NAME,
- .owner = THIS_MODULE,
- },
-};
-
-
-/*
- * module/subsystem initialize/terminate
- */
-static int __init snd_ps3_init(void)
-{
- int ret;
-
- if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
- return -ENXIO;
-
- memset(&the_card, 0, sizeof(the_card));
- spin_lock_init(&the_card.dma_lock);
-
- /* register systembus DRIVER, this calls our probe() func */
- ret = ps3_system_bus_driver_register(&snd_ps3_bus_driver_info);
-
- return ret;
-}
-module_init(snd_ps3_init);
-
-static void __exit snd_ps3_exit(void)
-{
- ps3_system_bus_driver_unregister(&snd_ps3_bus_driver_info);
-}
-module_exit(snd_ps3_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("PS3 sound driver");
-MODULE_AUTHOR("Sony Computer Entertainment Inc.");
-MODULE_ALIAS(PS3_MODULE_ALIAS_SOUND);
diff --git a/ANDROID_3.4.5/sound/ppc/snd_ps3.h b/ANDROID_3.4.5/sound/ppc/snd_ps3.h
deleted file mode 100644
index 326fb29e..00000000
--- a/ANDROID_3.4.5/sound/ppc/snd_ps3.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Audio support for PS3
- * Copyright (C) 2007 Sony Computer Entertainment Inc.
- * All rights reserved.
- * Copyright 2006, 2007 Sony Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; version 2 of the Licence.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#if !defined(_SND_PS3_H_)
-#define _SND_PS3_H_
-
-#include <linux/irqreturn.h>
-
-#define SND_PS3_DRIVER_NAME "snd_ps3"
-
-enum snd_ps3_out_channel {
- SND_PS3_OUT_SPDIF_0,
- SND_PS3_OUT_SPDIF_1,
- SND_PS3_OUT_SERIAL_0,
- SND_PS3_OUT_DEVS
-};
-
-enum snd_ps3_dma_filltype {
- SND_PS3_DMA_FILLTYPE_FIRSTFILL,
- SND_PS3_DMA_FILLTYPE_RUNNING,
- SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL,
- SND_PS3_DMA_FILLTYPE_SILENT_RUNNING
-};
-
-enum snd_ps3_ch {
- SND_PS3_CH_L = 0,
- SND_PS3_CH_R = 1,
- SND_PS3_CH_MAX = 2
-};
-
-struct snd_ps3_avsetting_info {
- uint32_t avs_audio_ch; /* fixed */
- uint32_t avs_audio_rate;
- uint32_t avs_audio_width;
- uint32_t avs_audio_format; /* fixed */
- uint32_t avs_audio_source; /* fixed */
- unsigned char avs_cs_info[8];
-};
-/*
- * PS3 audio 'card' instance
- * there should be only ONE hardware.
- */
-struct snd_ps3_card_info {
- struct ps3_system_bus_device *ps3_dev;
- struct snd_card *card;
-
- struct snd_pcm *pcm;
- struct snd_pcm_substream *substream;
-
- /* hvc info */
- u64 audio_lpar_addr;
- u64 audio_lpar_size;
-
- /* registers */
- void __iomem *mapped_mmio_vaddr;
-
- /* irq */
- u64 audio_irq_outlet;
- unsigned int irq_no;
-
- /* remember avsetting */
- struct snd_ps3_avsetting_info avs;
-
- /* dma buffer management */
- spinlock_t dma_lock;
- /* dma_lock start */
- void * dma_start_vaddr[2]; /* 0 for L, 1 for R */
- dma_addr_t dma_start_bus_addr[2];
- size_t dma_buffer_size;
- void * dma_last_transfer_vaddr[2];
- void * dma_next_transfer_vaddr[2];
- int silent;
- /* dma_lock end */
-
- int running;
-
- /* null buffer */
- void *null_buffer_start_vaddr;
- dma_addr_t null_buffer_start_dma_addr;
-
- /* start delay */
- unsigned int start_delay;
-
-};
-
-
-/* PS3 audio DMAC block size in bytes */
-#define PS3_AUDIO_DMAC_BLOCK_SIZE (128)
-/* one stage (stereo) of audio FIFO in bytes */
-#define PS3_AUDIO_FIFO_STAGE_SIZE (256)
-/* how many stages the fifo have */
-#define PS3_AUDIO_FIFO_STAGE_COUNT (8)
-/* fifo size 128 bytes * 8 stages * stereo (2ch) */
-#define PS3_AUDIO_FIFO_SIZE \
- (PS3_AUDIO_FIFO_STAGE_SIZE * PS3_AUDIO_FIFO_STAGE_COUNT)
-
-/* PS3 audio DMAC max block count in one dma shot = 128 (0x80) blocks*/
-#define PS3_AUDIO_DMAC_MAX_BLOCKS (PS3_AUDIO_DMASIZE_BLOCKS_MASK + 1)
-
-#define PS3_AUDIO_NORMAL_DMA_START_CH (0)
-#define PS3_AUDIO_NORMAL_DMA_COUNT (8)
-#define PS3_AUDIO_NULL_DMA_START_CH \
- (PS3_AUDIO_NORMAL_DMA_START_CH + PS3_AUDIO_NORMAL_DMA_COUNT)
-#define PS3_AUDIO_NULL_DMA_COUNT (2)
-
-#define SND_PS3_MAX_VOL (0x0F)
-#define SND_PS3_MIN_VOL (0x00)
-#define SND_PS3_MIN_ATT SND_PS3_MIN_VOL
-#define SND_PS3_MAX_ATT SND_PS3_MAX_VOL
-
-#define SND_PS3_PCM_PREALLOC_SIZE \
- (PS3_AUDIO_DMAC_BLOCK_SIZE * PS3_AUDIO_DMAC_MAX_BLOCKS * 4)
-
-#define SND_PS3_DMA_REGION_SIZE \
- (SND_PS3_PCM_PREALLOC_SIZE + PAGE_SIZE)
-
-#define PS3_AUDIO_IOID (1UL)
-
-#endif /* _SND_PS3_H_ */
diff --git a/ANDROID_3.4.5/sound/ppc/snd_ps3_reg.h b/ANDROID_3.4.5/sound/ppc/snd_ps3_reg.h
deleted file mode 100644
index 2e630207..00000000
--- a/ANDROID_3.4.5/sound/ppc/snd_ps3_reg.h
+++ /dev/null
@@ -1,891 +0,0 @@
-/*
- * Audio support for PS3
- * Copyright (C) 2007 Sony Computer Entertainment Inc.
- * Copyright 2006, 2007 Sony Corporation
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * interrupt / configure registers
- */
-
-#define PS3_AUDIO_INTR_0 (0x00000100)
-#define PS3_AUDIO_INTR_EN_0 (0x00000140)
-#define PS3_AUDIO_CONFIG (0x00000200)
-
-/*
- * DMAC registers
- * n:0..9
- */
-#define PS3_AUDIO_DMAC_REGBASE(x) (0x0000210 + 0x20 * (x))
-
-#define PS3_AUDIO_KICK(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x00)
-#define PS3_AUDIO_SOURCE(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x04)
-#define PS3_AUDIO_DEST(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x08)
-#define PS3_AUDIO_DMASIZE(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x0C)
-
-/*
- * mute control
- */
-#define PS3_AUDIO_AX_MCTRL (0x00004000)
-#define PS3_AUDIO_AX_ISBP (0x00004004)
-#define PS3_AUDIO_AX_AOBP (0x00004008)
-#define PS3_AUDIO_AX_IC (0x00004010)
-#define PS3_AUDIO_AX_IE (0x00004014)
-#define PS3_AUDIO_AX_IS (0x00004018)
-
-/*
- * three wire serial
- * n:0..3
- */
-#define PS3_AUDIO_AO_MCTRL (0x00006000)
-#define PS3_AUDIO_AO_3WMCTRL (0x00006004)
-
-#define PS3_AUDIO_AO_3WCTRL(n) (0x00006200 + 0x200 * (n))
-
-/*
- * S/PDIF
- * n:0..1
- * x:0..11
- * y:0..5
- */
-#define PS3_AUDIO_AO_SPD_REGBASE(n) (0x00007200 + 0x200 * (n))
-
-#define PS3_AUDIO_AO_SPDCTRL(n) \
- (PS3_AUDIO_AO_SPD_REGBASE(n) + 0x00)
-#define PS3_AUDIO_AO_SPDUB(n, x) \
- (PS3_AUDIO_AO_SPD_REGBASE(n) + 0x04 + 0x04 * (x))
-#define PS3_AUDIO_AO_SPDCS(n, y) \
- (PS3_AUDIO_AO_SPD_REGBASE(n) + 0x34 + 0x04 * (y))
-
-
-/*
- PS3_AUDIO_INTR_0 register tells an interrupt handler which audio
- DMA channel triggered the interrupt. The interrupt status for a channel
- can be cleared by writing a '1' to the corresponding bit. A new interrupt
- cannot be generated until the previous interrupt has been cleared.
-
- Note that the status reported by PS3_AUDIO_INTR_0 is independent of the
- value of PS3_AUDIO_INTR_EN_0.
-
- 31 24 23 16 15 8 7 0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
- |0 0 0 0 0 0 0 0 0 0 0 0 0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C| INTR_0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
-*/
-#define PS3_AUDIO_INTR_0_CHAN(n) (1 << ((n) * 2))
-#define PS3_AUDIO_INTR_0_CHAN9 PS3_AUDIO_INTR_0_CHAN(9)
-#define PS3_AUDIO_INTR_0_CHAN8 PS3_AUDIO_INTR_0_CHAN(8)
-#define PS3_AUDIO_INTR_0_CHAN7 PS3_AUDIO_INTR_0_CHAN(7)
-#define PS3_AUDIO_INTR_0_CHAN6 PS3_AUDIO_INTR_0_CHAN(6)
-#define PS3_AUDIO_INTR_0_CHAN5 PS3_AUDIO_INTR_0_CHAN(5)
-#define PS3_AUDIO_INTR_0_CHAN4 PS3_AUDIO_INTR_0_CHAN(4)
-#define PS3_AUDIO_INTR_0_CHAN3 PS3_AUDIO_INTR_0_CHAN(3)
-#define PS3_AUDIO_INTR_0_CHAN2 PS3_AUDIO_INTR_0_CHAN(2)
-#define PS3_AUDIO_INTR_0_CHAN1 PS3_AUDIO_INTR_0_CHAN(1)
-#define PS3_AUDIO_INTR_0_CHAN0 PS3_AUDIO_INTR_0_CHAN(0)
-
-/*
- The PS3_AUDIO_INTR_EN_0 register specifies which DMA channels can generate
- an interrupt to the PU. Each bit of PS3_AUDIO_INTR_EN_0 is ANDed with the
- corresponding bit in PS3_AUDIO_INTR_0. The resulting bits are OR'd together
- to generate the Audio interrupt.
-
- 31 24 23 16 15 8 7 0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
- |0 0 0 0 0 0 0 0 0 0 0 0 0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C| INTR_EN_0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
-
- Bit assignments are same as PS3_AUDIO_INTR_0
-*/
-
-/*
- PS3_AUDIO_CONFIG
- 31 24 23 16 15 8 7 0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
- |0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 C|0 0 0 0 0 0 0 0| CONFIG
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
-
-*/
-
-/* The CLEAR field cancels all pending transfers, and stops any running DMA
- transfers. Any interrupts associated with the canceled transfers
- will occur as if the transfer had finished.
- Since this bit is designed to recover from DMA related issues
- which are caused by unpredictable situations, it is preferred to wait
- for normal DMA transfer end without using this bit.
-*/
-#define PS3_AUDIO_CONFIG_CLEAR (1 << 8) /* RWIVF */
-
-/*
- PS3_AUDIO_AX_MCTRL: Audio Port Mute Control Register
-
- 31 24 23 16 15 8 7 0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
- |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|A|A|A|0 0 0 0 0 0 0|S|S|A|A|A|A| AX_MCTRL
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
-*/
-
-/* 3 Wire Audio Serial Output Channel Mutes (0..3) */
-#define PS3_AUDIO_AX_MCTRL_ASOMT(n) (1 << (3 - (n))) /* RWIVF */
-#define PS3_AUDIO_AX_MCTRL_ASO3MT (1 << 0) /* RWIVF */
-#define PS3_AUDIO_AX_MCTRL_ASO2MT (1 << 1) /* RWIVF */
-#define PS3_AUDIO_AX_MCTRL_ASO1MT (1 << 2) /* RWIVF */
-#define PS3_AUDIO_AX_MCTRL_ASO0MT (1 << 3) /* RWIVF */
-
-/* S/PDIF mutes (0,1)*/
-#define PS3_AUDIO_AX_MCTRL_SPOMT(n) (1 << (5 - (n))) /* RWIVF */
-#define PS3_AUDIO_AX_MCTRL_SPO1MT (1 << 4) /* RWIVF */
-#define PS3_AUDIO_AX_MCTRL_SPO0MT (1 << 5) /* RWIVF */
-
-/* All 3 Wire Serial Outputs Mute */
-#define PS3_AUDIO_AX_MCTRL_AASOMT (1 << 13) /* RWIVF */
-
-/* All S/PDIF Mute */
-#define PS3_AUDIO_AX_MCTRL_ASPOMT (1 << 14) /* RWIVF */
-
-/* All Audio Outputs Mute */
-#define PS3_AUDIO_AX_MCTRL_AAOMT (1 << 15) /* RWIVF */
-
-/*
- S/PDIF Outputs Buffer Read/Write Pointer Register
-
- 31 24 23 16 15 8 7 0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
- |0 0 0 0 0 0 0 0|0|SPO0B|0|SPO1B|0 0 0 0 0 0 0 0|0|SPO0B|0|SPO1B| AX_ISBP
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
-
-*/
-/*
- S/PDIF Output Channel Read Buffer Numbers
- Buffer number is value of field.
- Indicates current read access buffer ID from Audio Data
- Transfer controller of S/PDIF Output
-*/
-
-#define PS3_AUDIO_AX_ISBP_SPOBRN_MASK(n) (0x7 << 4 * (1 - (n))) /* R-IUF */
-#define PS3_AUDIO_AX_ISBP_SPO1BRN_MASK (0x7 << 0) /* R-IUF */
-#define PS3_AUDIO_AX_ISBP_SPO0BRN_MASK (0x7 << 4) /* R-IUF */
-
-/*
-S/PDIF Output Channel Buffer Write Numbers
-Indicates current write access buffer ID from bus master.
-*/
-#define PS3_AUDIO_AX_ISBP_SPOBWN_MASK(n) (0x7 << 4 * (5 - (n))) /* R-IUF */
-#define PS3_AUDIO_AX_ISBP_SPO1BWN_MASK (0x7 << 16) /* R-IUF */
-#define PS3_AUDIO_AX_ISBP_SPO0BWN_MASK (0x7 << 20) /* R-IUF */
-
-/*
- 3 Wire Audio Serial Outputs Buffer Read/Write
- Pointer Register
- Buffer number is value of field
-
- 31 24 23 16 15 8 7 0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
- |0|ASO0B|0|ASO1B|0|ASO2B|0|ASO3B|0|ASO0B|0|ASO1B|0|ASO2B|0|ASO3B| AX_AOBP
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
-*/
-
-/*
-3 Wire Audio Serial Output Channel Buffer Read Numbers
-Indicates current read access buffer Id from Audio Data Transfer
-Controller of 3 Wire Audio Serial Output Channels
-*/
-#define PS3_AUDIO_AX_AOBP_ASOBRN_MASK(n) (0x7 << 4 * (3 - (n))) /* R-IUF */
-
-#define PS3_AUDIO_AX_AOBP_ASO3BRN_MASK (0x7 << 0) /* R-IUF */
-#define PS3_AUDIO_AX_AOBP_ASO2BRN_MASK (0x7 << 4) /* R-IUF */
-#define PS3_AUDIO_AX_AOBP_ASO1BRN_MASK (0x7 << 8) /* R-IUF */
-#define PS3_AUDIO_AX_AOBP_ASO0BRN_MASK (0x7 << 12) /* R-IUF */
-
-/*
-3 Wire Audio Serial Output Channel Buffer Write Numbers
-Indicates current write access buffer ID from bus master.
-*/
-#define PS3_AUDIO_AX_AOBP_ASOBWN_MASK(n) (0x7 << 4 * (7 - (n))) /* R-IUF */
-
-#define PS3_AUDIO_AX_AOBP_ASO3BWN_MASK (0x7 << 16) /* R-IUF */
-#define PS3_AUDIO_AX_AOBP_ASO2BWN_MASK (0x7 << 20) /* R-IUF */
-#define PS3_AUDIO_AX_AOBP_ASO1BWN_MASK (0x7 << 24) /* R-IUF */
-#define PS3_AUDIO_AX_AOBP_ASO0BWN_MASK (0x7 << 28) /* R-IUF */
-
-
-
-/*
-Audio Port Interrupt Condition Register
-For the fields in this register, the following values apply:
-0 = Interrupt is generated every interrupt event.
-1 = Interrupt is generated every 2 interrupt events.
-2 = Interrupt is generated every 4 interrupt events.
-3 = Reserved
-
-
- 31 24 23 16 15 8 7 0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
- |0 0 0 0 0 0 0 0|0 0|SPO|0 0|SPO|0 0|AAS|0 0 0 0 0 0 0 0 0 0 0 0| AX_IC
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
-*/
-/*
-All 3-Wire Audio Serial Outputs Interrupt Mode
-Configures the Interrupt and Signal Notification
-condition of all 3-wire Audio Serial Outputs.
-*/
-#define PS3_AUDIO_AX_IC_AASOIMD_MASK (0x3 << 12) /* RWIVF */
-#define PS3_AUDIO_AX_IC_AASOIMD_EVERY1 (0x0 << 12) /* RWI-V */
-#define PS3_AUDIO_AX_IC_AASOIMD_EVERY2 (0x1 << 12) /* RW--V */
-#define PS3_AUDIO_AX_IC_AASOIMD_EVERY4 (0x2 << 12) /* RW--V */
-
-/*
-S/PDIF Output Channel Interrupt Modes
-Configures the Interrupt and signal Notification
-conditions of S/PDIF output channels.
-*/
-#define PS3_AUDIO_AX_IC_SPO1IMD_MASK (0x3 << 16) /* RWIVF */
-#define PS3_AUDIO_AX_IC_SPO1IMD_EVERY1 (0x0 << 16) /* RWI-V */
-#define PS3_AUDIO_AX_IC_SPO1IMD_EVERY2 (0x1 << 16) /* RW--V */
-#define PS3_AUDIO_AX_IC_SPO1IMD_EVERY4 (0x2 << 16) /* RW--V */
-
-#define PS3_AUDIO_AX_IC_SPO0IMD_MASK (0x3 << 20) /* RWIVF */
-#define PS3_AUDIO_AX_IC_SPO0IMD_EVERY1 (0x0 << 20) /* RWI-V */
-#define PS3_AUDIO_AX_IC_SPO0IMD_EVERY2 (0x1 << 20) /* RW--V */
-#define PS3_AUDIO_AX_IC_SPO0IMD_EVERY4 (0x2 << 20) /* RW--V */
-
-/*
-Audio Port interrupt Enable Register
-Configures whether to enable or disable each Interrupt Generation.
-
-
- 31 24 23 16 15 8 7 0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
- |0 0 0 0 0 0 0 0|S|S|0 0|A|A|A|A|0 0 0 0|S|S|0 0|S|S|0 0|A|A|A|A| AX_IE
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
-
-*/
-
-/*
-3 Wire Audio Serial Output Channel Buffer Underflow
-Interrupt Enables
-Select enable/disable of Buffer Underflow Interrupts for
-3-Wire Audio Serial Output Channels
-DISABLED=Interrupt generation disabled.
-*/
-#define PS3_AUDIO_AX_IE_ASOBUIE(n) (1 << (3 - (n))) /* RWIVF */
-#define PS3_AUDIO_AX_IE_ASO3BUIE (1 << 0) /* RWIVF */
-#define PS3_AUDIO_AX_IE_ASO2BUIE (1 << 1) /* RWIVF */
-#define PS3_AUDIO_AX_IE_ASO1BUIE (1 << 2) /* RWIVF */
-#define PS3_AUDIO_AX_IE_ASO0BUIE (1 << 3) /* RWIVF */
-
-/* S/PDIF Output Channel Buffer Underflow Interrupt Enables */
-
-#define PS3_AUDIO_AX_IE_SPOBUIE(n) (1 << (7 - (n))) /* RWIVF */
-#define PS3_AUDIO_AX_IE_SPO1BUIE (1 << 6) /* RWIVF */
-#define PS3_AUDIO_AX_IE_SPO0BUIE (1 << 7) /* RWIVF */
-
-/* S/PDIF Output Channel One Block Transfer Completion Interrupt Enables */
-
-#define PS3_AUDIO_AX_IE_SPOBTCIE(n) (1 << (11 - (n))) /* RWIVF */
-#define PS3_AUDIO_AX_IE_SPO1BTCIE (1 << 10) /* RWIVF */
-#define PS3_AUDIO_AX_IE_SPO0BTCIE (1 << 11) /* RWIVF */
-
-/* 3-Wire Audio Serial Output Channel Buffer Empty Interrupt Enables */
-
-#define PS3_AUDIO_AX_IE_ASOBEIE(n) (1 << (19 - (n))) /* RWIVF */
-#define PS3_AUDIO_AX_IE_ASO3BEIE (1 << 16) /* RWIVF */
-#define PS3_AUDIO_AX_IE_ASO2BEIE (1 << 17) /* RWIVF */
-#define PS3_AUDIO_AX_IE_ASO1BEIE (1 << 18) /* RWIVF */
-#define PS3_AUDIO_AX_IE_ASO0BEIE (1 << 19) /* RWIVF */
-
-/* S/PDIF Output Channel Buffer Empty Interrupt Enables */
-
-#define PS3_AUDIO_AX_IE_SPOBEIE(n) (1 << (23 - (n))) /* RWIVF */
-#define PS3_AUDIO_AX_IE_SPO1BEIE (1 << 22) /* RWIVF */
-#define PS3_AUDIO_AX_IE_SPO0BEIE (1 << 23) /* RWIVF */
-
-/*
-Audio Port Interrupt Status Register
-Indicates Interrupt status, which interrupt has occurred, and can clear
-each interrupt in this register.
-Writing 1b to a field containing 1b clears field and de-asserts interrupt.
-Writing 0b to a field has no effect.
-Field vaules are the following:
-0 - Interrupt hasn't occurred.
-1 - Interrupt has occurred.
-
-
- 31 24 23 16 15 8 7 0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
- |0 0 0 0 0 0 0 0|S|S|0 0|A|A|A|A|0 0 0 0|S|S|0 0|S|S|0 0|A|A|A|A| AX_IS
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
-
- Bit assignment are same as AX_IE
-*/
-
-/*
-Audio Output Master Control Register
-Configures Master Clock and other master Audio Output Settings
-
-
- 31 24 23 16 15 8 7 0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
- |0|SCKSE|0|SCKSE| MR0 | MR1 |MCL|MCL|0 0 0 0|0 0 0 0 0 0 0 0| AO_MCTRL
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
-*/
-
-/*
-MCLK Output Control
-Controls mclko[1] output.
-0 - Disable output (fixed at High)
-1 - Output clock produced by clock selected
-with scksel1 by mr1
-2 - Reserved
-3 - Reserved
-*/
-
-#define PS3_AUDIO_AO_MCTRL_MCLKC1_MASK (0x3 << 12) /* RWIVF */
-#define PS3_AUDIO_AO_MCTRL_MCLKC1_DISABLED (0x0 << 12) /* RWI-V */
-#define PS3_AUDIO_AO_MCTRL_MCLKC1_ENABLED (0x1 << 12) /* RW--V */
-#define PS3_AUDIO_AO_MCTRL_MCLKC1_RESVD2 (0x2 << 12) /* RW--V */
-#define PS3_AUDIO_AO_MCTRL_MCLKC1_RESVD3 (0x3 << 12) /* RW--V */
-
-/*
-MCLK Output Control
-Controls mclko[0] output.
-0 - Disable output (fixed at High)
-1 - Output clock produced by clock selected
-with SCKSEL0 by MR0
-2 - Reserved
-3 - Reserved
-*/
-#define PS3_AUDIO_AO_MCTRL_MCLKC0_MASK (0x3 << 14) /* RWIVF */
-#define PS3_AUDIO_AO_MCTRL_MCLKC0_DISABLED (0x0 << 14) /* RWI-V */
-#define PS3_AUDIO_AO_MCTRL_MCLKC0_ENABLED (0x1 << 14) /* RW--V */
-#define PS3_AUDIO_AO_MCTRL_MCLKC0_RESVD2 (0x2 << 14) /* RW--V */
-#define PS3_AUDIO_AO_MCTRL_MCLKC0_RESVD3 (0x3 << 14) /* RW--V */
-/*
-Master Clock Rate 1
-Sets the divide ration of Master Clock1 (clock output from
-mclko[1] for the input clock selected by scksel1.
-*/
-#define PS3_AUDIO_AO_MCTRL_MR1_MASK (0xf << 16)
-#define PS3_AUDIO_AO_MCTRL_MR1_DEFAULT (0x0 << 16) /* RWI-V */
-/*
-Master Clock Rate 0
-Sets the divide ratio of Master Clock0 (clock output from
-mclko[0] for the input clock selected by scksel0).
-*/
-#define PS3_AUDIO_AO_MCTRL_MR0_MASK (0xf << 20) /* RWIVF */
-#define PS3_AUDIO_AO_MCTRL_MR0_DEFAULT (0x0 << 20) /* RWI-V */
-/*
-System Clock Select 0/1
-Selects the system clock to be used as Master Clock 0/1
-Input the system clock that is appropriate for the sampling
-rate.
-*/
-#define PS3_AUDIO_AO_MCTRL_SCKSEL1_MASK (0x7 << 24) /* RWIVF */
-#define PS3_AUDIO_AO_MCTRL_SCKSEL1_DEFAULT (0x2 << 24) /* RWI-V */
-
-#define PS3_AUDIO_AO_MCTRL_SCKSEL0_MASK (0x7 << 28) /* RWIVF */
-#define PS3_AUDIO_AO_MCTRL_SCKSEL0_DEFAULT (0x2 << 28) /* RWI-V */
-
-
-/*
-3-Wire Audio Output Master Control Register
-Configures clock, 3-Wire Audio Serial Output Enable, and
-other 3-Wire Audio Serial Output Master Settings
-
-
- 31 24 23 16 15 8 7 0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
- |A|A|A|A|0 0 0|A| ASOSR |0 0 0 0|A|A|A|A|A|A|0|1|0 0 0 0 0 0 0 0| AO_3WMCTRL
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
-*/
-
-
-/*
-LRCKO Polarity
-0 - Reserved
-1 - default
-*/
-#define PS3_AUDIO_AO_3WMCTRL_ASOPLRCK (1 << 8) /* RWIVF */
-#define PS3_AUDIO_AO_3WMCTRL_ASOPLRCK_DEFAULT (1 << 8) /* RW--V */
-
-/* LRCK Output Disable */
-
-#define PS3_AUDIO_AO_3WMCTRL_ASOLRCKD (1 << 10) /* RWIVF */
-#define PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_ENABLED (0 << 10) /* RW--V */
-#define PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_DISABLED (1 << 10) /* RWI-V */
-
-/* Bit Clock Output Disable */
-
-#define PS3_AUDIO_AO_3WMCTRL_ASOBCLKD (1 << 11) /* RWIVF */
-#define PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_ENABLED (0 << 11) /* RW--V */
-#define PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_DISABLED (1 << 11) /* RWI-V */
-
-/*
-3-Wire Audio Serial Output Channel 0-3 Operational
-Status. Each bit becomes 1 after each 3-Wire Audio
-Serial Output Channel N is in action by setting 1 to
-asoen.
-Each bit becomes 0 after each 3-Wire Audio Serial Output
-Channel N is out of action by setting 0 to asoen.
-*/
-#define PS3_AUDIO_AO_3WMCTRL_ASORUN(n) (1 << (15 - (n))) /* R-IVF */
-#define PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(n) (0 << (15 - (n))) /* R-I-V */
-#define PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(n) (1 << (15 - (n))) /* R---V */
-#define PS3_AUDIO_AO_3WMCTRL_ASORUN0 \
- PS3_AUDIO_AO_3WMCTRL_ASORUN(0)
-#define PS3_AUDIO_AO_3WMCTRL_ASORUN0_STOPPED \
- PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(0)
-#define PS3_AUDIO_AO_3WMCTRL_ASORUN0_RUNNING \
- PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(0)
-#define PS3_AUDIO_AO_3WMCTRL_ASORUN1 \
- PS3_AUDIO_AO_3WMCTRL_ASORUN(1)
-#define PS3_AUDIO_AO_3WMCTRL_ASORUN1_STOPPED \
- PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(1)
-#define PS3_AUDIO_AO_3WMCTRL_ASORUN1_RUNNING \
- PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(1)
-#define PS3_AUDIO_AO_3WMCTRL_ASORUN2 \
- PS3_AUDIO_AO_3WMCTRL_ASORUN(2)
-#define PS3_AUDIO_AO_3WMCTRL_ASORUN2_STOPPED \
- PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(2)
-#define PS3_AUDIO_AO_3WMCTRL_ASORUN2_RUNNING \
- PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(2)
-#define PS3_AUDIO_AO_3WMCTRL_ASORUN3 \
- PS3_AUDIO_AO_3WMCTRL_ASORUN(3)
-#define PS3_AUDIO_AO_3WMCTRL_ASORUN3_STOPPED \
- PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(3)
-#define PS3_AUDIO_AO_3WMCTRL_ASORUN3_RUNNING \
- PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(3)
-
-/*
-Sampling Rate
-Specifies the divide ratio of the bit clock (clock output
-from bclko) used by the 3-wire Audio Output Clock, which
-is applied to the master clock selected by mcksel.
-Data output is synchronized with this clock.
-*/
-#define PS3_AUDIO_AO_3WMCTRL_ASOSR_MASK (0xf << 20) /* RWIVF */
-#define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV2 (0x1 << 20) /* RWI-V */
-#define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV4 (0x2 << 20) /* RW--V */
-#define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV8 (0x4 << 20) /* RW--V */
-#define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV12 (0x6 << 20) /* RW--V */
-
-/*
-Master Clock Select
-0 - Master Clock 0
-1 - Master Clock 1
-*/
-#define PS3_AUDIO_AO_3WMCTRL_ASOMCKSEL (1 << 24) /* RWIVF */
-#define PS3_AUDIO_AO_3WMCTRL_ASOMCKSEL_CLK0 (0 << 24) /* RWI-V */
-#define PS3_AUDIO_AO_3WMCTRL_ASOMCKSEL_CLK1 (1 << 24) /* RW--V */
-
-/*
-Enables and disables 4ch 3-Wire Audio Serial Output
-operation. Each Bit from 0 to 3 corresponds to an
-output channel, which means that each output channel
-can be enabled or disabled individually. When
-multiple channels are enabled at the same time, output
-operations are performed in synchronization.
-Bit 0 - Output Channel 0 (SDOUT[0])
-Bit 1 - Output Channel 1 (SDOUT[1])
-Bit 2 - Output Channel 2 (SDOUT[2])
-Bit 3 - Output Channel 3 (SDOUT[3])
-*/
-#define PS3_AUDIO_AO_3WMCTRL_ASOEN(n) (1 << (31 - (n))) /* RWIVF */
-#define PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(n) (0 << (31 - (n))) /* RWI-V */
-#define PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(n) (1 << (31 - (n))) /* RW--V */
-
-#define PS3_AUDIO_AO_3WMCTRL_ASOEN0 \
- PS3_AUDIO_AO_3WMCTRL_ASOEN(0) /* RWIVF */
-#define PS3_AUDIO_AO_3WMCTRL_ASOEN0_DISABLED \
- PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(0) /* RWI-V */
-#define PS3_AUDIO_AO_3WMCTRL_ASOEN0_ENABLED \
- PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(0) /* RW--V */
-#define PS3_AUDIO_A1_3WMCTRL_ASOEN0 \
- PS3_AUDIO_AO_3WMCTRL_ASOEN(1) /* RWIVF */
-#define PS3_AUDIO_A1_3WMCTRL_ASOEN0_DISABLED \
- PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(1) /* RWI-V */
-#define PS3_AUDIO_A1_3WMCTRL_ASOEN0_ENABLED \
- PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(1) /* RW--V */
-#define PS3_AUDIO_A2_3WMCTRL_ASOEN0 \
- PS3_AUDIO_AO_3WMCTRL_ASOEN(2) /* RWIVF */
-#define PS3_AUDIO_A2_3WMCTRL_ASOEN0_DISABLED \
- PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(2) /* RWI-V */
-#define PS3_AUDIO_A2_3WMCTRL_ASOEN0_ENABLED \
- PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(2) /* RW--V */
-#define PS3_AUDIO_A3_3WMCTRL_ASOEN0 \
- PS3_AUDIO_AO_3WMCTRL_ASOEN(3) /* RWIVF */
-#define PS3_AUDIO_A3_3WMCTRL_ASOEN0_DISABLED \
- PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(3) /* RWI-V */
-#define PS3_AUDIO_A3_3WMCTRL_ASOEN0_ENABLED \
- PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(3) /* RW--V */
-
-/*
-3-Wire Audio Serial output Channel 0-3 Control Register
-Configures settings for 3-Wire Serial Audio Output Channel 0-3
-
-
- 31 24 23 16 15 8 7 0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
- |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|A|0 0 0 0|A|0|ASO|0 0 0|0|0|0|0|0| AO_3WCTRL
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
-
-*/
-/*
-Data Bit Mode
-Specifies the number of data bits
-0 - 16 bits
-1 - reserved
-2 - 20 bits
-3 - 24 bits
-*/
-#define PS3_AUDIO_AO_3WCTRL_ASODB_MASK (0x3 << 8) /* RWIVF */
-#define PS3_AUDIO_AO_3WCTRL_ASODB_16BIT (0x0 << 8) /* RWI-V */
-#define PS3_AUDIO_AO_3WCTRL_ASODB_RESVD (0x1 << 8) /* RWI-V */
-#define PS3_AUDIO_AO_3WCTRL_ASODB_20BIT (0x2 << 8) /* RW--V */
-#define PS3_AUDIO_AO_3WCTRL_ASODB_24BIT (0x3 << 8) /* RW--V */
-/*
-Data Format Mode
-Specifies the data format where (LSB side or MSB) the data(in 20 bit
-or 24 bit resolution mode) is put in a 32 bit field.
-0 - Data put on LSB side
-1 - Data put on MSB side
-*/
-#define PS3_AUDIO_AO_3WCTRL_ASODF (1 << 11) /* RWIVF */
-#define PS3_AUDIO_AO_3WCTRL_ASODF_LSB (0 << 11) /* RWI-V */
-#define PS3_AUDIO_AO_3WCTRL_ASODF_MSB (1 << 11) /* RW--V */
-/*
-Buffer Reset
-Performs buffer reset. Writing 1 to this bit initializes the
-corresponding 3-Wire Audio Output buffers(both L and R).
-*/
-#define PS3_AUDIO_AO_3WCTRL_ASOBRST (1 << 16) /* CWIVF */
-#define PS3_AUDIO_AO_3WCTRL_ASOBRST_IDLE (0 << 16) /* -WI-V */
-#define PS3_AUDIO_AO_3WCTRL_ASOBRST_RESET (1 << 16) /* -W--T */
-
-/*
-S/PDIF Audio Output Channel 0/1 Control Register
-Configures settings for S/PDIF Audio Output Channel 0/1.
-
- 31 24 23 16 15 8 7 0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
- |S|0 0 0|S|0 0|S| SPOSR |0 0|SPO|0 0 0 0|S|0|SPO|0 0 0 0 0 0 0|S| AO_SPDCTRL
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
-*/
-/*
-Buffer reset. Writing 1 to this bit initializes the
-corresponding S/PDIF output buffer pointer.
-*/
-#define PS3_AUDIO_AO_SPDCTRL_SPOBRST (1 << 0) /* CWIVF */
-#define PS3_AUDIO_AO_SPDCTRL_SPOBRST_IDLE (0 << 0) /* -WI-V */
-#define PS3_AUDIO_AO_SPDCTRL_SPOBRST_RESET (1 << 0) /* -W--T */
-
-/*
-Data Bit Mode
-Specifies number of data bits
-0 - 16 bits
-1 - Reserved
-2 - 20 bits
-3 - 24 bits
-*/
-#define PS3_AUDIO_AO_SPDCTRL_SPODB_MASK (0x3 << 8) /* RWIVF */
-#define PS3_AUDIO_AO_SPDCTRL_SPODB_16BIT (0x0 << 8) /* RWI-V */
-#define PS3_AUDIO_AO_SPDCTRL_SPODB_RESVD (0x1 << 8) /* RW--V */
-#define PS3_AUDIO_AO_SPDCTRL_SPODB_20BIT (0x2 << 8) /* RW--V */
-#define PS3_AUDIO_AO_SPDCTRL_SPODB_24BIT (0x3 << 8) /* RW--V */
-/*
-Data format Mode
-Specifies the data format, where (LSB side or MSB)
-the data(in 20 or 24 bit resolution) is put in the
-32 bit field.
-0 - LSB Side
-1 - MSB Side
-*/
-#define PS3_AUDIO_AO_SPDCTRL_SPODF (1 << 11) /* RWIVF */
-#define PS3_AUDIO_AO_SPDCTRL_SPODF_LSB (0 << 11) /* RWI-V */
-#define PS3_AUDIO_AO_SPDCTRL_SPODF_MSB (1 << 11) /* RW--V */
-/*
-Source Select
-Specifies the source of the S/PDIF output. When 0, output
-operation is controlled by 3wen[0] of AO_3WMCTRL register.
-The SR must have the same setting as the a0_3wmctrl reg.
-0 - 3-Wire Audio OUT Ch0 Buffer
-1 - S/PDIF buffer
-*/
-#define PS3_AUDIO_AO_SPDCTRL_SPOSS_MASK (0x3 << 16) /* RWIVF */
-#define PS3_AUDIO_AO_SPDCTRL_SPOSS_3WEN (0x0 << 16) /* RWI-V */
-#define PS3_AUDIO_AO_SPDCTRL_SPOSS_SPDIF (0x1 << 16) /* RW--V */
-/*
-Sampling Rate
-Specifies the divide ratio of the bit clock (clock output
-from bclko) used by the S/PDIF Output Clock, which
-is applied to the master clock selected by mcksel.
-*/
-#define PS3_AUDIO_AO_SPDCTRL_SPOSR (0xf << 20) /* RWIVF */
-#define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV2 (0x1 << 20) /* RWI-V */
-#define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV4 (0x2 << 20) /* RW--V */
-#define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV8 (0x4 << 20) /* RW--V */
-#define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV12 (0x6 << 20) /* RW--V */
-/*
-Master Clock Select
-0 - Master Clock 0
-1 - Master Clock 1
-*/
-#define PS3_AUDIO_AO_SPDCTRL_SPOMCKSEL (1 << 24) /* RWIVF */
-#define PS3_AUDIO_AO_SPDCTRL_SPOMCKSEL_CLK0 (0 << 24) /* RWI-V */
-#define PS3_AUDIO_AO_SPDCTRL_SPOMCKSEL_CLK1 (1 << 24) /* RW--V */
-
-/*
-S/PDIF Output Channel Operational Status
-This bit becomes 1 after S/PDIF Output Channel is in
-action by setting 1 to spoen. This bit becomes 0
-after S/PDIF Output Channel is out of action by setting
-0 to spoen.
-*/
-#define PS3_AUDIO_AO_SPDCTRL_SPORUN (1 << 27) /* R-IVF */
-#define PS3_AUDIO_AO_SPDCTRL_SPORUN_STOPPED (0 << 27) /* R-I-V */
-#define PS3_AUDIO_AO_SPDCTRL_SPORUN_RUNNING (1 << 27) /* R---V */
-
-/*
-S/PDIF Audio Output Channel Output Enable
-Enables and disables output operation. This bit is used
-only when sposs = 1
-*/
-#define PS3_AUDIO_AO_SPDCTRL_SPOEN (1 << 31) /* RWIVF */
-#define PS3_AUDIO_AO_SPDCTRL_SPOEN_DISABLED (0 << 31) /* RWI-V */
-#define PS3_AUDIO_AO_SPDCTRL_SPOEN_ENABLED (1 << 31) /* RW--V */
-
-/*
-S/PDIF Audio Output Channel Channel Status
-Setting Registers.
-Configures channel status bit settings for each block
-(192 bits).
-Output is performed from the MSB(AO_SPDCS0 register bit 31).
-The same value is added for subframes within the same frame.
- 31 24 23 16 15 8 7 0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
- | SPOCS | AO_SPDCS
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
-
-S/PDIF Audio Output Channel User Bit Setting
-Configures user bit settings for each block (384 bits).
-Output is performed from the MSB(ao_spdub0 register bit 31).
-
-
- 31 24 23 16 15 8 7 0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
- | SPOUB | AO_SPDUB
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
-*/
-/*****************************************************************************
- *
- * DMAC register
- *
- *****************************************************************************/
-/*
-The PS3_AUDIO_KICK register is used to initiate a DMA transfer and monitor
-its status
-
- 31 24 23 16 15 8 7 0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
- |0 0 0 0 0|STATU|0 0 0| EVENT |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|R| KICK
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
-*/
-/*
-The REQUEST field is written to ACTIVE to initiate a DMA request when EVENT
-occurs.
-It will return to the DONE state when the request is completed.
-The registers for a DMA channel should only be written if REQUEST is IDLE.
-*/
-
-#define PS3_AUDIO_KICK_REQUEST (1 << 0) /* RWIVF */
-#define PS3_AUDIO_KICK_REQUEST_IDLE (0 << 0) /* RWI-V */
-#define PS3_AUDIO_KICK_REQUEST_ACTIVE (1 << 0) /* -W--T */
-
-/*
- *The EVENT field is used to set the event in which
- *the DMA request becomes active.
- */
-#define PS3_AUDIO_KICK_EVENT_MASK (0x1f << 16) /* RWIVF */
-#define PS3_AUDIO_KICK_EVENT_ALWAYS (0x00 << 16) /* RWI-V */
-#define PS3_AUDIO_KICK_EVENT_SERIALOUT0_EMPTY (0x01 << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_SERIALOUT0_UNDERFLOW (0x02 << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_SERIALOUT1_EMPTY (0x03 << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_SERIALOUT1_UNDERFLOW (0x04 << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_SERIALOUT2_EMPTY (0x05 << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_SERIALOUT2_UNDERFLOW (0x06 << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_SERIALOUT3_EMPTY (0x07 << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_SERIALOUT3_UNDERFLOW (0x08 << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_SPDIF0_BLOCKTRANSFERCOMPLETE \
- (0x09 << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_SPDIF0_UNDERFLOW (0x0A << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_SPDIF0_EMPTY (0x0B << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_SPDIF1_BLOCKTRANSFERCOMPLETE \
- (0x0C << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_SPDIF1_UNDERFLOW (0x0D << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_SPDIF1_EMPTY (0x0E << 16) /* RW--V */
-
-#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA(n) \
- ((0x13 + (n)) << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA0 (0x13 << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA1 (0x14 << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA2 (0x15 << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA3 (0x16 << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA4 (0x17 << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA5 (0x18 << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA6 (0x19 << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA7 (0x1A << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA8 (0x1B << 16) /* RW--V */
-#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA9 (0x1C << 16) /* RW--V */
-
-/*
-The STATUS field can be used to monitor the progress of a DMA request.
-DONE indicates the previous request has completed.
-EVENT indicates that the DMA engine is waiting for the EVENT to occur.
-PENDING indicates that the DMA engine has not started processing this
-request, but the EVENT has occurred.
-DMA indicates that the data transfer is in progress.
-NOTIFY indicates that the notifier signalling end of transfer is being written.
-CLEAR indicated that the previous transfer was cleared.
-ERROR indicates the previous transfer requested an unsupported
-source/destination combination.
-*/
-
-#define PS3_AUDIO_KICK_STATUS_MASK (0x7 << 24) /* R-IVF */
-#define PS3_AUDIO_KICK_STATUS_DONE (0x0 << 24) /* R-I-V */
-#define PS3_AUDIO_KICK_STATUS_EVENT (0x1 << 24) /* R---V */
-#define PS3_AUDIO_KICK_STATUS_PENDING (0x2 << 24) /* R---V */
-#define PS3_AUDIO_KICK_STATUS_DMA (0x3 << 24) /* R---V */
-#define PS3_AUDIO_KICK_STATUS_NOTIFY (0x4 << 24) /* R---V */
-#define PS3_AUDIO_KICK_STATUS_CLEAR (0x5 << 24) /* R---V */
-#define PS3_AUDIO_KICK_STATUS_ERROR (0x6 << 24) /* R---V */
-
-/*
-The PS3_AUDIO_SOURCE register specifies the source address for transfers.
-
-
- 31 24 23 16 15 8 7 0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
- | START |0 0 0 0 0|TAR| SOURCE
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
-*/
-
-/*
-The Audio DMA engine uses 128-byte transfers, thus the address must be aligned
-to a 128 byte boundary. The low seven bits are assumed to be 0.
-*/
-
-#define PS3_AUDIO_SOURCE_START_MASK (0x01FFFFFF << 7) /* RWIUF */
-
-/*
-The TARGET field specifies the memory space containing the source address.
-*/
-
-#define PS3_AUDIO_SOURCE_TARGET_MASK (3 << 0) /* RWIVF */
-#define PS3_AUDIO_SOURCE_TARGET_SYSTEM_MEMORY (2 << 0) /* RW--V */
-
-/*
-The PS3_AUDIO_DEST register specifies the destination address for transfers.
-
-
- 31 24 23 16 15 8 7 0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
- | START |0 0 0 0 0|TAR| DEST
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
-*/
-
-/*
-The Audio DMA engine uses 128-byte transfers, thus the address must be aligned
-to a 128 byte boundary. The low seven bits are assumed to be 0.
-*/
-
-#define PS3_AUDIO_DEST_START_MASK (0x01FFFFFF << 7) /* RWIUF */
-
-/*
-The TARGET field specifies the memory space containing the destination address
-AUDIOFIFO = Audio WriteData FIFO,
-*/
-
-#define PS3_AUDIO_DEST_TARGET_MASK (3 << 0) /* RWIVF */
-#define PS3_AUDIO_DEST_TARGET_AUDIOFIFO (1 << 0) /* RW--V */
-
-/*
-PS3_AUDIO_DMASIZE specifies the number of 128-byte blocks + 1 to transfer.
-So a value of 0 means 128-bytes will get transferred.
-
-
- 31 24 23 16 15 8 7 0
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
- |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| BLOCKS | DMASIZE
- +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
-*/
-
-
-#define PS3_AUDIO_DMASIZE_BLOCKS_MASK (0x7f << 0) /* RWIUF */
-
-/*
- * source/destination address for internal fifos
- */
-#define PS3_AUDIO_AO_3W_LDATA(n) (0x1000 + (0x100 * (n)))
-#define PS3_AUDIO_AO_3W_RDATA(n) (0x1080 + (0x100 * (n)))
-
-#define PS3_AUDIO_AO_SPD_DATA(n) (0x2000 + (0x400 * (n)))
-
-
-/*
- * field attiribute
- *
- * Read
- * ' ' = Other Information
- * '-' = Field is part of a write-only register
- * 'C' = Value read is always the same, constant value line follows (C)
- * 'R' = Value is read
- *
- * Write
- * ' ' = Other Information
- * '-' = Must not be written (D), value ignored when written (R,A,F)
- * 'W' = Can be written
- *
- * Internal State
- * ' ' = Other Information
- * '-' = No internal state
- * 'X' = Internal state, initial value is unknown
- * 'I' = Internal state, initial value is known and follows (I)
- *
- * Declaration/Size
- * ' ' = Other Information
- * '-' = Does Not Apply
- * 'V' = Type is void
- * 'U' = Type is unsigned integer
- * 'S' = Type is signed integer
- * 'F' = Type is IEEE floating point
- * '1' = Byte size (008)
- * '2' = Short size (016)
- * '3' = Three byte size (024)
- * '4' = Word size (032)
- * '8' = Double size (064)
- *
- * Define Indicator
- * ' ' = Other Information
- * 'D' = Device
- * 'M' = Memory
- * 'R' = Register
- * 'A' = Array of Registers
- * 'F' = Field
- * 'V' = Value
- * 'T' = Task
- */
-
diff --git a/ANDROID_3.4.5/sound/ppc/tumbler.c b/ANDROID_3.4.5/sound/ppc/tumbler.c
deleted file mode 100644
index 9cea84c3..00000000
--- a/ANDROID_3.4.5/sound/ppc/tumbler.c
+++ /dev/null
@@ -1,1495 +0,0 @@
-/*
- * PMac Tumbler/Snapper lowlevel functions
- *
- * Copyright (c) by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Rene Rebe <rene.rebe@gmx.net>:
- * * update from shadow registers on wakeup and headphone plug
- * * automatically toggle DRC on headphone plug
- *
- */
-
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/kmod.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/string.h>
-#include <sound/core.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include "pmac.h"
-#include "tumbler_volume.h"
-
-#undef DEBUG
-
-#ifdef DEBUG
-#define DBG(fmt...) printk(KERN_DEBUG fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-#define IS_G4DA (of_machine_is_compatible("PowerMac3,4"))
-
-/* i2c address for tumbler */
-#define TAS_I2C_ADDR 0x34
-
-/* registers */
-#define TAS_REG_MCS 0x01 /* main control */
-#define TAS_REG_DRC 0x02
-#define TAS_REG_VOL 0x04
-#define TAS_REG_TREBLE 0x05
-#define TAS_REG_BASS 0x06
-#define TAS_REG_INPUT1 0x07
-#define TAS_REG_INPUT2 0x08
-
-/* tas3001c */
-#define TAS_REG_PCM TAS_REG_INPUT1
-
-/* tas3004 */
-#define TAS_REG_LMIX TAS_REG_INPUT1
-#define TAS_REG_RMIX TAS_REG_INPUT2
-#define TAS_REG_MCS2 0x43 /* main control 2 */
-#define TAS_REG_ACS 0x40 /* analog control */
-
-/* mono volumes for tas3001c/tas3004 */
-enum {
- VOL_IDX_PCM_MONO, /* tas3001c only */
- VOL_IDX_BASS, VOL_IDX_TREBLE,
- VOL_IDX_LAST_MONO
-};
-
-/* stereo volumes for tas3004 */
-enum {
- VOL_IDX_PCM, VOL_IDX_PCM2, VOL_IDX_ADC,
- VOL_IDX_LAST_MIX
-};
-
-struct pmac_gpio {
- unsigned int addr;
- u8 active_val;
- u8 inactive_val;
- u8 active_state;
-};
-
-struct pmac_tumbler {
- struct pmac_keywest i2c;
- struct pmac_gpio audio_reset;
- struct pmac_gpio amp_mute;
- struct pmac_gpio line_mute;
- struct pmac_gpio line_detect;
- struct pmac_gpio hp_mute;
- struct pmac_gpio hp_detect;
- int headphone_irq;
- int lineout_irq;
- unsigned int save_master_vol[2];
- unsigned int master_vol[2];
- unsigned int save_master_switch[2];
- unsigned int master_switch[2];
- unsigned int mono_vol[VOL_IDX_LAST_MONO];
- unsigned int mix_vol[VOL_IDX_LAST_MIX][2]; /* stereo volumes for tas3004 */
- int drc_range;
- int drc_enable;
- int capture_source;
- int anded_reset;
- int auto_mute_notify;
- int reset_on_sleep;
- u8 acs;
-};
-
-
-/*
- */
-
-static int send_init_client(struct pmac_keywest *i2c, unsigned int *regs)
-{
- while (*regs > 0) {
- int err, count = 10;
- do {
- err = i2c_smbus_write_byte_data(i2c->client,
- regs[0], regs[1]);
- if (err >= 0)
- break;
- DBG("(W) i2c error %d\n", err);
- mdelay(10);
- } while (count--);
- if (err < 0)
- return -ENXIO;
- regs += 2;
- }
- return 0;
-}
-
-
-static int tumbler_init_client(struct pmac_keywest *i2c)
-{
- static unsigned int regs[] = {
- /* normal operation, SCLK=64fps, i2s output, i2s input, 16bit width */
- TAS_REG_MCS, (1<<6)|(2<<4)|(2<<2)|0,
- 0, /* terminator */
- };
- DBG("(I) tumbler init client\n");
- return send_init_client(i2c, regs);
-}
-
-static int snapper_init_client(struct pmac_keywest *i2c)
-{
- static unsigned int regs[] = {
- /* normal operation, SCLK=64fps, i2s output, 16bit width */
- TAS_REG_MCS, (1<<6)|(2<<4)|0,
- /* normal operation, all-pass mode */
- TAS_REG_MCS2, (1<<1),
- /* normal output, no deemphasis, A input, power-up, line-in */
- TAS_REG_ACS, 0,
- 0, /* terminator */
- };
- DBG("(I) snapper init client\n");
- return send_init_client(i2c, regs);
-}
-
-/*
- * gpio access
- */
-#define do_gpio_write(gp, val) \
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, (gp)->addr, val)
-#define do_gpio_read(gp) \
- pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, (gp)->addr, 0)
-#define tumbler_gpio_free(gp) /* NOP */
-
-static void write_audio_gpio(struct pmac_gpio *gp, int active)
-{
- if (! gp->addr)
- return;
- active = active ? gp->active_val : gp->inactive_val;
- do_gpio_write(gp, active);
- DBG("(I) gpio %x write %d\n", gp->addr, active);
-}
-
-static int check_audio_gpio(struct pmac_gpio *gp)
-{
- int ret;
-
- if (! gp->addr)
- return 0;
-
- ret = do_gpio_read(gp);
-
- return (ret & 0x1) == (gp->active_val & 0x1);
-}
-
-static int read_audio_gpio(struct pmac_gpio *gp)
-{
- int ret;
- if (! gp->addr)
- return 0;
- ret = do_gpio_read(gp);
- ret = (ret & 0x02) !=0;
- return ret == gp->active_state;
-}
-
-/*
- * update master volume
- */
-static int tumbler_set_master_volume(struct pmac_tumbler *mix)
-{
- unsigned char block[6];
- unsigned int left_vol, right_vol;
-
- if (! mix->i2c.client)
- return -ENODEV;
-
- if (! mix->master_switch[0])
- left_vol = 0;
- else {
- left_vol = mix->master_vol[0];
- if (left_vol >= ARRAY_SIZE(master_volume_table))
- left_vol = ARRAY_SIZE(master_volume_table) - 1;
- left_vol = master_volume_table[left_vol];
- }
- if (! mix->master_switch[1])
- right_vol = 0;
- else {
- right_vol = mix->master_vol[1];
- if (right_vol >= ARRAY_SIZE(master_volume_table))
- right_vol = ARRAY_SIZE(master_volume_table) - 1;
- right_vol = master_volume_table[right_vol];
- }
-
- block[0] = (left_vol >> 16) & 0xff;
- block[1] = (left_vol >> 8) & 0xff;
- block[2] = (left_vol >> 0) & 0xff;
-
- block[3] = (right_vol >> 16) & 0xff;
- block[4] = (right_vol >> 8) & 0xff;
- block[5] = (right_vol >> 0) & 0xff;
-
- if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_VOL, 6,
- block) < 0) {
- snd_printk(KERN_ERR "failed to set volume \n");
- return -EINVAL;
- }
- DBG("(I) succeeded to set volume (%u, %u)\n", left_vol, right_vol);
- return 0;
-}
-
-
-/* output volume */
-static int tumbler_info_master_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = ARRAY_SIZE(master_volume_table) - 1;
- return 0;
-}
-
-static int tumbler_get_master_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_tumbler *mix = chip->mixer_data;
-
- ucontrol->value.integer.value[0] = mix->master_vol[0];
- ucontrol->value.integer.value[1] = mix->master_vol[1];
- return 0;
-}
-
-static int tumbler_put_master_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_tumbler *mix = chip->mixer_data;
- unsigned int vol[2];
- int change;
-
- vol[0] = ucontrol->value.integer.value[0];
- vol[1] = ucontrol->value.integer.value[1];
- if (vol[0] >= ARRAY_SIZE(master_volume_table) ||
- vol[1] >= ARRAY_SIZE(master_volume_table))
- return -EINVAL;
- change = mix->master_vol[0] != vol[0] ||
- mix->master_vol[1] != vol[1];
- if (change) {
- mix->master_vol[0] = vol[0];
- mix->master_vol[1] = vol[1];
- tumbler_set_master_volume(mix);
- }
- return change;
-}
-
-/* output switch */
-static int tumbler_get_master_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_tumbler *mix = chip->mixer_data;
-
- ucontrol->value.integer.value[0] = mix->master_switch[0];
- ucontrol->value.integer.value[1] = mix->master_switch[1];
- return 0;
-}
-
-static int tumbler_put_master_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_tumbler *mix = chip->mixer_data;
- int change;
-
- change = mix->master_switch[0] != ucontrol->value.integer.value[0] ||
- mix->master_switch[1] != ucontrol->value.integer.value[1];
- if (change) {
- mix->master_switch[0] = !!ucontrol->value.integer.value[0];
- mix->master_switch[1] = !!ucontrol->value.integer.value[1];
- tumbler_set_master_volume(mix);
- }
- return change;
-}
-
-
-/*
- * TAS3001c dynamic range compression
- */
-
-#define TAS3001_DRC_MAX 0x5f
-
-static int tumbler_set_drc(struct pmac_tumbler *mix)
-{
- unsigned char val[2];
-
- if (! mix->i2c.client)
- return -ENODEV;
-
- if (mix->drc_enable) {
- val[0] = 0xc1; /* enable, 3:1 compression */
- if (mix->drc_range > TAS3001_DRC_MAX)
- val[1] = 0xf0;
- else if (mix->drc_range < 0)
- val[1] = 0x91;
- else
- val[1] = mix->drc_range + 0x91;
- } else {
- val[0] = 0;
- val[1] = 0;
- }
-
- if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_DRC,
- 2, val) < 0) {
- snd_printk(KERN_ERR "failed to set DRC\n");
- return -EINVAL;
- }
- DBG("(I) succeeded to set DRC (%u, %u)\n", val[0], val[1]);
- return 0;
-}
-
-/*
- * TAS3004
- */
-
-#define TAS3004_DRC_MAX 0xef
-
-static int snapper_set_drc(struct pmac_tumbler *mix)
-{
- unsigned char val[6];
-
- if (! mix->i2c.client)
- return -ENODEV;
-
- if (mix->drc_enable)
- val[0] = 0x50; /* 3:1 above threshold */
- else
- val[0] = 0x51; /* disabled */
- val[1] = 0x02; /* 1:1 below threshold */
- if (mix->drc_range > 0xef)
- val[2] = 0xef;
- else if (mix->drc_range < 0)
- val[2] = 0x00;
- else
- val[2] = mix->drc_range;
- val[3] = 0xb0;
- val[4] = 0x60;
- val[5] = 0xa0;
-
- if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_DRC,
- 6, val) < 0) {
- snd_printk(KERN_ERR "failed to set DRC\n");
- return -EINVAL;
- }
- DBG("(I) succeeded to set DRC (%u, %u)\n", val[0], val[1]);
- return 0;
-}
-
-static int tumbler_info_drc_value(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max =
- chip->model == PMAC_TUMBLER ? TAS3001_DRC_MAX : TAS3004_DRC_MAX;
- return 0;
-}
-
-static int tumbler_get_drc_value(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_tumbler *mix;
- if (! (mix = chip->mixer_data))
- return -ENODEV;
- ucontrol->value.integer.value[0] = mix->drc_range;
- return 0;
-}
-
-static int tumbler_put_drc_value(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_tumbler *mix;
- unsigned int val;
- int change;
-
- if (! (mix = chip->mixer_data))
- return -ENODEV;
- val = ucontrol->value.integer.value[0];
- if (chip->model == PMAC_TUMBLER) {
- if (val > TAS3001_DRC_MAX)
- return -EINVAL;
- } else {
- if (val > TAS3004_DRC_MAX)
- return -EINVAL;
- }
- change = mix->drc_range != val;
- if (change) {
- mix->drc_range = val;
- if (chip->model == PMAC_TUMBLER)
- tumbler_set_drc(mix);
- else
- snapper_set_drc(mix);
- }
- return change;
-}
-
-static int tumbler_get_drc_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_tumbler *mix;
- if (! (mix = chip->mixer_data))
- return -ENODEV;
- ucontrol->value.integer.value[0] = mix->drc_enable;
- return 0;
-}
-
-static int tumbler_put_drc_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_tumbler *mix;
- int change;
-
- if (! (mix = chip->mixer_data))
- return -ENODEV;
- change = mix->drc_enable != ucontrol->value.integer.value[0];
- if (change) {
- mix->drc_enable = !!ucontrol->value.integer.value[0];
- if (chip->model == PMAC_TUMBLER)
- tumbler_set_drc(mix);
- else
- snapper_set_drc(mix);
- }
- return change;
-}
-
-
-/*
- * mono volumes
- */
-
-struct tumbler_mono_vol {
- int index;
- int reg;
- int bytes;
- unsigned int max;
- unsigned int *table;
-};
-
-static int tumbler_set_mono_volume(struct pmac_tumbler *mix,
- struct tumbler_mono_vol *info)
-{
- unsigned char block[4];
- unsigned int vol;
- int i;
-
- if (! mix->i2c.client)
- return -ENODEV;
-
- vol = mix->mono_vol[info->index];
- if (vol >= info->max)
- vol = info->max - 1;
- vol = info->table[vol];
- for (i = 0; i < info->bytes; i++)
- block[i] = (vol >> ((info->bytes - i - 1) * 8)) & 0xff;
- if (i2c_smbus_write_i2c_block_data(mix->i2c.client, info->reg,
- info->bytes, block) < 0) {
- snd_printk(KERN_ERR "failed to set mono volume %d\n",
- info->index);
- return -EINVAL;
- }
- return 0;
-}
-
-static int tumbler_info_mono(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct tumbler_mono_vol *info = (struct tumbler_mono_vol *)kcontrol->private_value;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = info->max - 1;
- return 0;
-}
-
-static int tumbler_get_mono(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tumbler_mono_vol *info = (struct tumbler_mono_vol *)kcontrol->private_value;
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_tumbler *mix;
- if (! (mix = chip->mixer_data))
- return -ENODEV;
- ucontrol->value.integer.value[0] = mix->mono_vol[info->index];
- return 0;
-}
-
-static int tumbler_put_mono(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct tumbler_mono_vol *info = (struct tumbler_mono_vol *)kcontrol->private_value;
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_tumbler *mix;
- unsigned int vol;
- int change;
-
- if (! (mix = chip->mixer_data))
- return -ENODEV;
- vol = ucontrol->value.integer.value[0];
- if (vol >= info->max)
- return -EINVAL;
- change = mix->mono_vol[info->index] != vol;
- if (change) {
- mix->mono_vol[info->index] = vol;
- tumbler_set_mono_volume(mix, info);
- }
- return change;
-}
-
-/* TAS3001c mono volumes */
-static struct tumbler_mono_vol tumbler_pcm_vol_info = {
- .index = VOL_IDX_PCM_MONO,
- .reg = TAS_REG_PCM,
- .bytes = 3,
- .max = ARRAY_SIZE(mixer_volume_table),
- .table = mixer_volume_table,
-};
-
-static struct tumbler_mono_vol tumbler_bass_vol_info = {
- .index = VOL_IDX_BASS,
- .reg = TAS_REG_BASS,
- .bytes = 1,
- .max = ARRAY_SIZE(bass_volume_table),
- .table = bass_volume_table,
-};
-
-static struct tumbler_mono_vol tumbler_treble_vol_info = {
- .index = VOL_IDX_TREBLE,
- .reg = TAS_REG_TREBLE,
- .bytes = 1,
- .max = ARRAY_SIZE(treble_volume_table),
- .table = treble_volume_table,
-};
-
-/* TAS3004 mono volumes */
-static struct tumbler_mono_vol snapper_bass_vol_info = {
- .index = VOL_IDX_BASS,
- .reg = TAS_REG_BASS,
- .bytes = 1,
- .max = ARRAY_SIZE(snapper_bass_volume_table),
- .table = snapper_bass_volume_table,
-};
-
-static struct tumbler_mono_vol snapper_treble_vol_info = {
- .index = VOL_IDX_TREBLE,
- .reg = TAS_REG_TREBLE,
- .bytes = 1,
- .max = ARRAY_SIZE(snapper_treble_volume_table),
- .table = snapper_treble_volume_table,
-};
-
-
-#define DEFINE_MONO(xname,type) { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\
- .name = xname, \
- .info = tumbler_info_mono, \
- .get = tumbler_get_mono, \
- .put = tumbler_put_mono, \
- .private_value = (unsigned long)(&tumbler_##type##_vol_info), \
-}
-
-#define DEFINE_SNAPPER_MONO(xname,type) { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\
- .name = xname, \
- .info = tumbler_info_mono, \
- .get = tumbler_get_mono, \
- .put = tumbler_put_mono, \
- .private_value = (unsigned long)(&snapper_##type##_vol_info), \
-}
-
-
-/*
- * snapper mixer volumes
- */
-
-static int snapper_set_mix_vol1(struct pmac_tumbler *mix, int idx, int ch, int reg)
-{
- int i, j, vol;
- unsigned char block[9];
-
- vol = mix->mix_vol[idx][ch];
- if (vol >= ARRAY_SIZE(mixer_volume_table)) {
- vol = ARRAY_SIZE(mixer_volume_table) - 1;
- mix->mix_vol[idx][ch] = vol;
- }
-
- for (i = 0; i < 3; i++) {
- vol = mix->mix_vol[i][ch];
- vol = mixer_volume_table[vol];
- for (j = 0; j < 3; j++)
- block[i * 3 + j] = (vol >> ((2 - j) * 8)) & 0xff;
- }
- if (i2c_smbus_write_i2c_block_data(mix->i2c.client, reg,
- 9, block) < 0) {
- snd_printk(KERN_ERR "failed to set mono volume %d\n", reg);
- return -EINVAL;
- }
- return 0;
-}
-
-static int snapper_set_mix_vol(struct pmac_tumbler *mix, int idx)
-{
- if (! mix->i2c.client)
- return -ENODEV;
- if (snapper_set_mix_vol1(mix, idx, 0, TAS_REG_LMIX) < 0 ||
- snapper_set_mix_vol1(mix, idx, 1, TAS_REG_RMIX) < 0)
- return -EINVAL;
- return 0;
-}
-
-static int snapper_info_mix(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = ARRAY_SIZE(mixer_volume_table) - 1;
- return 0;
-}
-
-static int snapper_get_mix(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int idx = (int)kcontrol->private_value;
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_tumbler *mix;
- if (! (mix = chip->mixer_data))
- return -ENODEV;
- ucontrol->value.integer.value[0] = mix->mix_vol[idx][0];
- ucontrol->value.integer.value[1] = mix->mix_vol[idx][1];
- return 0;
-}
-
-static int snapper_put_mix(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int idx = (int)kcontrol->private_value;
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_tumbler *mix;
- unsigned int vol[2];
- int change;
-
- if (! (mix = chip->mixer_data))
- return -ENODEV;
- vol[0] = ucontrol->value.integer.value[0];
- vol[1] = ucontrol->value.integer.value[1];
- if (vol[0] >= ARRAY_SIZE(mixer_volume_table) ||
- vol[1] >= ARRAY_SIZE(mixer_volume_table))
- return -EINVAL;
- change = mix->mix_vol[idx][0] != vol[0] ||
- mix->mix_vol[idx][1] != vol[1];
- if (change) {
- mix->mix_vol[idx][0] = vol[0];
- mix->mix_vol[idx][1] = vol[1];
- snapper_set_mix_vol(mix, idx);
- }
- return change;
-}
-
-
-/*
- * mute switches. FIXME: Turn that into software mute when both outputs are muted
- * to avoid codec reset on ibook M7
- */
-
-enum { TUMBLER_MUTE_HP, TUMBLER_MUTE_AMP, TUMBLER_MUTE_LINE };
-
-static int tumbler_get_mute_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_tumbler *mix;
- struct pmac_gpio *gp;
- if (! (mix = chip->mixer_data))
- return -ENODEV;
- switch(kcontrol->private_value) {
- case TUMBLER_MUTE_HP:
- gp = &mix->hp_mute; break;
- case TUMBLER_MUTE_AMP:
- gp = &mix->amp_mute; break;
- case TUMBLER_MUTE_LINE:
- gp = &mix->line_mute; break;
- default:
- gp = NULL;
- }
- if (gp == NULL)
- return -EINVAL;
- ucontrol->value.integer.value[0] = !check_audio_gpio(gp);
- return 0;
-}
-
-static int tumbler_put_mute_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_tumbler *mix;
- struct pmac_gpio *gp;
- int val;
-#ifdef PMAC_SUPPORT_AUTOMUTE
- if (chip->update_automute && chip->auto_mute)
- return 0; /* don't touch in the auto-mute mode */
-#endif
- if (! (mix = chip->mixer_data))
- return -ENODEV;
- switch(kcontrol->private_value) {
- case TUMBLER_MUTE_HP:
- gp = &mix->hp_mute; break;
- case TUMBLER_MUTE_AMP:
- gp = &mix->amp_mute; break;
- case TUMBLER_MUTE_LINE:
- gp = &mix->line_mute; break;
- default:
- gp = NULL;
- }
- if (gp == NULL)
- return -EINVAL;
- val = ! check_audio_gpio(gp);
- if (val != ucontrol->value.integer.value[0]) {
- write_audio_gpio(gp, ! ucontrol->value.integer.value[0]);
- return 1;
- }
- return 0;
-}
-
-static int snapper_set_capture_source(struct pmac_tumbler *mix)
-{
- if (! mix->i2c.client)
- return -ENODEV;
- if (mix->capture_source)
- mix->acs |= 2;
- else
- mix->acs &= ~2;
- return i2c_smbus_write_byte_data(mix->i2c.client, TAS_REG_ACS, mix->acs);
-}
-
-static int snapper_info_capture_source(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[2] = {
- "Line", "Mic"
- };
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item > 1)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int snapper_get_capture_source(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_tumbler *mix = chip->mixer_data;
-
- ucontrol->value.enumerated.item[0] = mix->capture_source;
- return 0;
-}
-
-static int snapper_put_capture_source(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
- struct pmac_tumbler *mix = chip->mixer_data;
- int change;
-
- change = ucontrol->value.enumerated.item[0] != mix->capture_source;
- if (change) {
- mix->capture_source = !!ucontrol->value.enumerated.item[0];
- snapper_set_capture_source(mix);
- }
- return change;
-}
-
-#define DEFINE_SNAPPER_MIX(xname,idx,ofs) { \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\
- .name = xname, \
- .info = snapper_info_mix, \
- .get = snapper_get_mix, \
- .put = snapper_put_mix, \
- .index = idx,\
- .private_value = ofs, \
-}
-
-
-/*
- */
-static struct snd_kcontrol_new tumbler_mixers[] __devinitdata = {
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Volume",
- .info = tumbler_info_master_volume,
- .get = tumbler_get_master_volume,
- .put = tumbler_put_master_volume
- },
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = snd_pmac_boolean_stereo_info,
- .get = tumbler_get_master_switch,
- .put = tumbler_put_master_switch
- },
- DEFINE_MONO("Tone Control - Bass", bass),
- DEFINE_MONO("Tone Control - Treble", treble),
- DEFINE_MONO("PCM Playback Volume", pcm),
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "DRC Range",
- .info = tumbler_info_drc_value,
- .get = tumbler_get_drc_value,
- .put = tumbler_put_drc_value
- },
-};
-
-static struct snd_kcontrol_new snapper_mixers[] __devinitdata = {
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Volume",
- .info = tumbler_info_master_volume,
- .get = tumbler_get_master_volume,
- .put = tumbler_put_master_volume
- },
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = snd_pmac_boolean_stereo_info,
- .get = tumbler_get_master_switch,
- .put = tumbler_put_master_switch
- },
- DEFINE_SNAPPER_MIX("PCM Playback Volume", 0, VOL_IDX_PCM),
- /* Alternative PCM is assigned to Mic analog loopback on iBook G4 */
- DEFINE_SNAPPER_MIX("Mic Playback Volume", 0, VOL_IDX_PCM2),
- DEFINE_SNAPPER_MIX("Monitor Mix Volume", 0, VOL_IDX_ADC),
- DEFINE_SNAPPER_MONO("Tone Control - Bass", bass),
- DEFINE_SNAPPER_MONO("Tone Control - Treble", treble),
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "DRC Range",
- .info = tumbler_info_drc_value,
- .get = tumbler_get_drc_value,
- .put = tumbler_put_drc_value
- },
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input Source", /* FIXME: "Capture Source" doesn't work properly */
- .info = snapper_info_capture_source,
- .get = snapper_get_capture_source,
- .put = snapper_put_capture_source
- },
-};
-
-static struct snd_kcontrol_new tumbler_hp_sw __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Headphone Playback Switch",
- .info = snd_pmac_boolean_mono_info,
- .get = tumbler_get_mute_switch,
- .put = tumbler_put_mute_switch,
- .private_value = TUMBLER_MUTE_HP,
-};
-static struct snd_kcontrol_new tumbler_speaker_sw __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Speaker Playback Switch",
- .info = snd_pmac_boolean_mono_info,
- .get = tumbler_get_mute_switch,
- .put = tumbler_put_mute_switch,
- .private_value = TUMBLER_MUTE_AMP,
-};
-static struct snd_kcontrol_new tumbler_lineout_sw __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Line Out Playback Switch",
- .info = snd_pmac_boolean_mono_info,
- .get = tumbler_get_mute_switch,
- .put = tumbler_put_mute_switch,
- .private_value = TUMBLER_MUTE_LINE,
-};
-static struct snd_kcontrol_new tumbler_drc_sw __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "DRC Switch",
- .info = snd_pmac_boolean_mono_info,
- .get = tumbler_get_drc_switch,
- .put = tumbler_put_drc_switch
-};
-
-
-#ifdef PMAC_SUPPORT_AUTOMUTE
-/*
- * auto-mute stuffs
- */
-static int tumbler_detect_headphone(struct snd_pmac *chip)
-{
- struct pmac_tumbler *mix = chip->mixer_data;
- int detect = 0;
-
- if (mix->hp_detect.addr)
- detect |= read_audio_gpio(&mix->hp_detect);
- return detect;
-}
-
-static int tumbler_detect_lineout(struct snd_pmac *chip)
-{
- struct pmac_tumbler *mix = chip->mixer_data;
- int detect = 0;
-
- if (mix->line_detect.addr)
- detect |= read_audio_gpio(&mix->line_detect);
- return detect;
-}
-
-static void check_mute(struct snd_pmac *chip, struct pmac_gpio *gp, int val, int do_notify,
- struct snd_kcontrol *sw)
-{
- if (check_audio_gpio(gp) != val) {
- write_audio_gpio(gp, val);
- if (do_notify)
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &sw->id);
- }
-}
-
-static struct work_struct device_change;
-static struct snd_pmac *device_change_chip;
-
-static void device_change_handler(struct work_struct *work)
-{
- struct snd_pmac *chip = device_change_chip;
- struct pmac_tumbler *mix;
- int headphone, lineout;
-
- if (!chip)
- return;
-
- mix = chip->mixer_data;
- if (snd_BUG_ON(!mix))
- return;
-
- headphone = tumbler_detect_headphone(chip);
- lineout = tumbler_detect_lineout(chip);
-
- DBG("headphone: %d, lineout: %d\n", headphone, lineout);
-
- if (headphone || lineout) {
- /* unmute headphone/lineout & mute speaker */
- if (headphone)
- check_mute(chip, &mix->hp_mute, 0, mix->auto_mute_notify,
- chip->master_sw_ctl);
- if (lineout && mix->line_mute.addr != 0)
- check_mute(chip, &mix->line_mute, 0, mix->auto_mute_notify,
- chip->lineout_sw_ctl);
- if (mix->anded_reset)
- msleep(10);
- check_mute(chip, &mix->amp_mute, !IS_G4DA, mix->auto_mute_notify,
- chip->speaker_sw_ctl);
- } else {
- /* unmute speaker, mute others */
- check_mute(chip, &mix->amp_mute, 0, mix->auto_mute_notify,
- chip->speaker_sw_ctl);
- if (mix->anded_reset)
- msleep(10);
- check_mute(chip, &mix->hp_mute, 1, mix->auto_mute_notify,
- chip->master_sw_ctl);
- if (mix->line_mute.addr != 0)
- check_mute(chip, &mix->line_mute, 1, mix->auto_mute_notify,
- chip->lineout_sw_ctl);
- }
- if (mix->auto_mute_notify)
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->hp_detect_ctl->id);
-
-#ifdef CONFIG_SND_POWERMAC_AUTO_DRC
- mix->drc_enable = ! (headphone || lineout);
- if (mix->auto_mute_notify)
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->drc_sw_ctl->id);
- if (chip->model == PMAC_TUMBLER)
- tumbler_set_drc(mix);
- else
- snapper_set_drc(mix);
-#endif
-
- /* reset the master volume so the correct amplification is applied */
- tumbler_set_master_volume(mix);
-}
-
-static void tumbler_update_automute(struct snd_pmac *chip, int do_notify)
-{
- if (chip->auto_mute) {
- struct pmac_tumbler *mix;
- mix = chip->mixer_data;
- if (snd_BUG_ON(!mix))
- return;
- mix->auto_mute_notify = do_notify;
- schedule_work(&device_change);
- }
-}
-#endif /* PMAC_SUPPORT_AUTOMUTE */
-
-
-/* interrupt - headphone plug changed */
-static irqreturn_t headphone_intr(int irq, void *devid)
-{
- struct snd_pmac *chip = devid;
- if (chip->update_automute && chip->initialized) {
- chip->update_automute(chip, 1);
- return IRQ_HANDLED;
- }
- return IRQ_NONE;
-}
-
-/* look for audio-gpio device */
-static struct device_node *find_audio_device(const char *name)
-{
- struct device_node *gpiop;
- struct device_node *np;
-
- gpiop = of_find_node_by_name(NULL, "gpio");
- if (! gpiop)
- return NULL;
-
- for (np = of_get_next_child(gpiop, NULL); np;
- np = of_get_next_child(gpiop, np)) {
- const char *property = of_get_property(np, "audio-gpio", NULL);
- if (property && strcmp(property, name) == 0)
- break;
- }
- of_node_put(gpiop);
- return np;
-}
-
-/* look for audio-gpio device */
-static struct device_node *find_compatible_audio_device(const char *name)
-{
- struct device_node *gpiop;
- struct device_node *np;
-
- gpiop = of_find_node_by_name(NULL, "gpio");
- if (!gpiop)
- return NULL;
-
- for (np = of_get_next_child(gpiop, NULL); np;
- np = of_get_next_child(gpiop, np)) {
- if (of_device_is_compatible(np, name))
- break;
- }
- of_node_put(gpiop);
- return np;
-}
-
-/* find an audio device and get its address */
-static long tumbler_find_device(const char *device, const char *platform,
- struct pmac_gpio *gp, int is_compatible)
-{
- struct device_node *node;
- const u32 *base;
- u32 addr;
- long ret;
-
- if (is_compatible)
- node = find_compatible_audio_device(device);
- else
- node = find_audio_device(device);
- if (! node) {
- DBG("(W) cannot find audio device %s !\n", device);
- snd_printdd("cannot find device %s\n", device);
- return -ENODEV;
- }
-
- base = of_get_property(node, "AAPL,address", NULL);
- if (! base) {
- base = of_get_property(node, "reg", NULL);
- if (!base) {
- DBG("(E) cannot find address for device %s !\n", device);
- snd_printd("cannot find address for device %s\n", device);
- of_node_put(node);
- return -ENODEV;
- }
- addr = *base;
- if (addr < 0x50)
- addr += 0x50;
- } else
- addr = *base;
-
- gp->addr = addr & 0x0000ffff;
- /* Try to find the active state, default to 0 ! */
- base = of_get_property(node, "audio-gpio-active-state", NULL);
- if (base) {
- gp->active_state = *base;
- gp->active_val = (*base) ? 0x5 : 0x4;
- gp->inactive_val = (*base) ? 0x4 : 0x5;
- } else {
- const u32 *prop = NULL;
- gp->active_state = IS_G4DA
- && !strncmp(device, "keywest-gpio1", 13);
- gp->active_val = 0x4;
- gp->inactive_val = 0x5;
- /* Here are some crude hacks to extract the GPIO polarity and
- * open collector informations out of the do-platform script
- * as we don't yet have an interpreter for these things
- */
- if (platform)
- prop = of_get_property(node, platform, NULL);
- if (prop) {
- if (prop[3] == 0x9 && prop[4] == 0x9) {
- gp->active_val = 0xd;
- gp->inactive_val = 0xc;
- }
- if (prop[3] == 0x1 && prop[4] == 0x1) {
- gp->active_val = 0x5;
- gp->inactive_val = 0x4;
- }
- }
- }
-
- DBG("(I) GPIO device %s found, offset: %x, active state: %d !\n",
- device, gp->addr, gp->active_state);
-
- ret = irq_of_parse_and_map(node, 0);
- of_node_put(node);
- return ret;
-}
-
-/* reset audio */
-static void tumbler_reset_audio(struct snd_pmac *chip)
-{
- struct pmac_tumbler *mix = chip->mixer_data;
-
- if (mix->anded_reset) {
- DBG("(I) codec anded reset !\n");
- write_audio_gpio(&mix->hp_mute, 0);
- write_audio_gpio(&mix->amp_mute, 0);
- msleep(200);
- write_audio_gpio(&mix->hp_mute, 1);
- write_audio_gpio(&mix->amp_mute, 1);
- msleep(100);
- write_audio_gpio(&mix->hp_mute, 0);
- write_audio_gpio(&mix->amp_mute, 0);
- msleep(100);
- } else {
- DBG("(I) codec normal reset !\n");
-
- write_audio_gpio(&mix->audio_reset, 0);
- msleep(200);
- write_audio_gpio(&mix->audio_reset, 1);
- msleep(100);
- write_audio_gpio(&mix->audio_reset, 0);
- msleep(100);
- }
-}
-
-#ifdef CONFIG_PM
-/* suspend mixer */
-static void tumbler_suspend(struct snd_pmac *chip)
-{
- struct pmac_tumbler *mix = chip->mixer_data;
-
- if (mix->headphone_irq >= 0)
- disable_irq(mix->headphone_irq);
- if (mix->lineout_irq >= 0)
- disable_irq(mix->lineout_irq);
- mix->save_master_switch[0] = mix->master_switch[0];
- mix->save_master_switch[1] = mix->master_switch[1];
- mix->save_master_vol[0] = mix->master_vol[0];
- mix->save_master_vol[1] = mix->master_vol[1];
- mix->master_switch[0] = mix->master_switch[1] = 0;
- tumbler_set_master_volume(mix);
- if (!mix->anded_reset) {
- write_audio_gpio(&mix->amp_mute, 1);
- write_audio_gpio(&mix->hp_mute, 1);
- }
- if (chip->model == PMAC_SNAPPER) {
- mix->acs |= 1;
- i2c_smbus_write_byte_data(mix->i2c.client, TAS_REG_ACS, mix->acs);
- }
- if (mix->anded_reset) {
- write_audio_gpio(&mix->amp_mute, 1);
- write_audio_gpio(&mix->hp_mute, 1);
- } else
- write_audio_gpio(&mix->audio_reset, 1);
-}
-
-/* resume mixer */
-static void tumbler_resume(struct snd_pmac *chip)
-{
- struct pmac_tumbler *mix = chip->mixer_data;
-
- mix->acs &= ~1;
- mix->master_switch[0] = mix->save_master_switch[0];
- mix->master_switch[1] = mix->save_master_switch[1];
- mix->master_vol[0] = mix->save_master_vol[0];
- mix->master_vol[1] = mix->save_master_vol[1];
- tumbler_reset_audio(chip);
- if (mix->i2c.client && mix->i2c.init_client) {
- if (mix->i2c.init_client(&mix->i2c) < 0)
- printk(KERN_ERR "tumbler_init_client error\n");
- } else
- printk(KERN_ERR "tumbler: i2c is not initialized\n");
- if (chip->model == PMAC_TUMBLER) {
- tumbler_set_mono_volume(mix, &tumbler_pcm_vol_info);
- tumbler_set_mono_volume(mix, &tumbler_bass_vol_info);
- tumbler_set_mono_volume(mix, &tumbler_treble_vol_info);
- tumbler_set_drc(mix);
- } else {
- snapper_set_mix_vol(mix, VOL_IDX_PCM);
- snapper_set_mix_vol(mix, VOL_IDX_PCM2);
- snapper_set_mix_vol(mix, VOL_IDX_ADC);
- tumbler_set_mono_volume(mix, &snapper_bass_vol_info);
- tumbler_set_mono_volume(mix, &snapper_treble_vol_info);
- snapper_set_drc(mix);
- snapper_set_capture_source(mix);
- }
- tumbler_set_master_volume(mix);
- if (chip->update_automute)
- chip->update_automute(chip, 0);
- if (mix->headphone_irq >= 0) {
- unsigned char val;
-
- enable_irq(mix->headphone_irq);
- /* activate headphone status interrupts */
- val = do_gpio_read(&mix->hp_detect);
- do_gpio_write(&mix->hp_detect, val | 0x80);
- }
- if (mix->lineout_irq >= 0)
- enable_irq(mix->lineout_irq);
-}
-#endif
-
-/* initialize tumbler */
-static int __devinit tumbler_init(struct snd_pmac *chip)
-{
- int irq;
- struct pmac_tumbler *mix = chip->mixer_data;
-
- if (tumbler_find_device("audio-hw-reset",
- "platform-do-hw-reset",
- &mix->audio_reset, 0) < 0)
- tumbler_find_device("hw-reset",
- "platform-do-hw-reset",
- &mix->audio_reset, 1);
- if (tumbler_find_device("amp-mute",
- "platform-do-amp-mute",
- &mix->amp_mute, 0) < 0)
- tumbler_find_device("amp-mute",
- "platform-do-amp-mute",
- &mix->amp_mute, 1);
- if (tumbler_find_device("headphone-mute",
- "platform-do-headphone-mute",
- &mix->hp_mute, 0) < 0)
- tumbler_find_device("headphone-mute",
- "platform-do-headphone-mute",
- &mix->hp_mute, 1);
- if (tumbler_find_device("line-output-mute",
- "platform-do-lineout-mute",
- &mix->line_mute, 0) < 0)
- tumbler_find_device("line-output-mute",
- "platform-do-lineout-mute",
- &mix->line_mute, 1);
- irq = tumbler_find_device("headphone-detect",
- NULL, &mix->hp_detect, 0);
- if (irq <= NO_IRQ)
- irq = tumbler_find_device("headphone-detect",
- NULL, &mix->hp_detect, 1);
- if (irq <= NO_IRQ)
- irq = tumbler_find_device("keywest-gpio15",
- NULL, &mix->hp_detect, 1);
- mix->headphone_irq = irq;
- irq = tumbler_find_device("line-output-detect",
- NULL, &mix->line_detect, 0);
- if (irq <= NO_IRQ)
- irq = tumbler_find_device("line-output-detect",
- NULL, &mix->line_detect, 1);
- if (IS_G4DA && irq <= NO_IRQ)
- irq = tumbler_find_device("keywest-gpio16",
- NULL, &mix->line_detect, 1);
- mix->lineout_irq = irq;
-
- tumbler_reset_audio(chip);
-
- return 0;
-}
-
-static void tumbler_cleanup(struct snd_pmac *chip)
-{
- struct pmac_tumbler *mix = chip->mixer_data;
- if (! mix)
- return;
-
- if (mix->headphone_irq >= 0)
- free_irq(mix->headphone_irq, chip);
- if (mix->lineout_irq >= 0)
- free_irq(mix->lineout_irq, chip);
- tumbler_gpio_free(&mix->audio_reset);
- tumbler_gpio_free(&mix->amp_mute);
- tumbler_gpio_free(&mix->hp_mute);
- tumbler_gpio_free(&mix->hp_detect);
- snd_pmac_keywest_cleanup(&mix->i2c);
- kfree(mix);
- chip->mixer_data = NULL;
-}
-
-/* exported */
-int __devinit snd_pmac_tumbler_init(struct snd_pmac *chip)
-{
- int i, err;
- struct pmac_tumbler *mix;
- const u32 *paddr;
- struct device_node *tas_node, *np;
- char *chipname;
-
- request_module("i2c-powermac");
-
- mix = kzalloc(sizeof(*mix), GFP_KERNEL);
- if (! mix)
- return -ENOMEM;
- mix->headphone_irq = -1;
-
- chip->mixer_data = mix;
- chip->mixer_free = tumbler_cleanup;
- mix->anded_reset = 0;
- mix->reset_on_sleep = 1;
-
- for (np = chip->node->child; np; np = np->sibling) {
- if (!strcmp(np->name, "sound")) {
- if (of_get_property(np, "has-anded-reset", NULL))
- mix->anded_reset = 1;
- if (of_get_property(np, "layout-id", NULL))
- mix->reset_on_sleep = 0;
- break;
- }
- }
- if ((err = tumbler_init(chip)) < 0)
- return err;
-
- /* set up TAS */
- tas_node = of_find_node_by_name(NULL, "deq");
- if (tas_node == NULL)
- tas_node = of_find_node_by_name(NULL, "codec");
- if (tas_node == NULL)
- return -ENODEV;
-
- paddr = of_get_property(tas_node, "i2c-address", NULL);
- if (paddr == NULL)
- paddr = of_get_property(tas_node, "reg", NULL);
- if (paddr)
- mix->i2c.addr = (*paddr) >> 1;
- else
- mix->i2c.addr = TAS_I2C_ADDR;
- of_node_put(tas_node);
-
- DBG("(I) TAS i2c address is: %x\n", mix->i2c.addr);
-
- if (chip->model == PMAC_TUMBLER) {
- mix->i2c.init_client = tumbler_init_client;
- mix->i2c.name = "TAS3001c";
- chipname = "Tumbler";
- } else {
- mix->i2c.init_client = snapper_init_client;
- mix->i2c.name = "TAS3004";
- chipname = "Snapper";
- }
-
- if ((err = snd_pmac_keywest_init(&mix->i2c)) < 0)
- return err;
-
- /*
- * build mixers
- */
- sprintf(chip->card->mixername, "PowerMac %s", chipname);
-
- if (chip->model == PMAC_TUMBLER) {
- for (i = 0; i < ARRAY_SIZE(tumbler_mixers); i++) {
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&tumbler_mixers[i], chip))) < 0)
- return err;
- }
- } else {
- for (i = 0; i < ARRAY_SIZE(snapper_mixers); i++) {
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snapper_mixers[i], chip))) < 0)
- return err;
- }
- }
- chip->master_sw_ctl = snd_ctl_new1(&tumbler_hp_sw, chip);
- if ((err = snd_ctl_add(chip->card, chip->master_sw_ctl)) < 0)
- return err;
- chip->speaker_sw_ctl = snd_ctl_new1(&tumbler_speaker_sw, chip);
- if ((err = snd_ctl_add(chip->card, chip->speaker_sw_ctl)) < 0)
- return err;
- if (mix->line_mute.addr != 0) {
- chip->lineout_sw_ctl = snd_ctl_new1(&tumbler_lineout_sw, chip);
- if ((err = snd_ctl_add(chip->card, chip->lineout_sw_ctl)) < 0)
- return err;
- }
- chip->drc_sw_ctl = snd_ctl_new1(&tumbler_drc_sw, chip);
- if ((err = snd_ctl_add(chip->card, chip->drc_sw_ctl)) < 0)
- return err;
-
- /* set initial DRC range to 60% */
- if (chip->model == PMAC_TUMBLER)
- mix->drc_range = (TAS3001_DRC_MAX * 6) / 10;
- else
- mix->drc_range = (TAS3004_DRC_MAX * 6) / 10;
- mix->drc_enable = 1; /* will be changed later if AUTO_DRC is set */
- if (chip->model == PMAC_TUMBLER)
- tumbler_set_drc(mix);
- else
- snapper_set_drc(mix);
-
-#ifdef CONFIG_PM
- chip->suspend = tumbler_suspend;
- chip->resume = tumbler_resume;
-#endif
-
- INIT_WORK(&device_change, device_change_handler);
- device_change_chip = chip;
-
-#ifdef PMAC_SUPPORT_AUTOMUTE
- if ((mix->headphone_irq >=0 || mix->lineout_irq >= 0)
- && (err = snd_pmac_add_automute(chip)) < 0)
- return err;
- chip->detect_headphone = tumbler_detect_headphone;
- chip->update_automute = tumbler_update_automute;
- tumbler_update_automute(chip, 0); /* update the status only */
-
- /* activate headphone status interrupts */
- if (mix->headphone_irq >= 0) {
- unsigned char val;
- if ((err = request_irq(mix->headphone_irq, headphone_intr, 0,
- "Sound Headphone Detection", chip)) < 0)
- return 0;
- /* activate headphone status interrupts */
- val = do_gpio_read(&mix->hp_detect);
- do_gpio_write(&mix->hp_detect, val | 0x80);
- }
- if (mix->lineout_irq >= 0) {
- unsigned char val;
- if ((err = request_irq(mix->lineout_irq, headphone_intr, 0,
- "Sound Lineout Detection", chip)) < 0)
- return 0;
- /* activate headphone status interrupts */
- val = do_gpio_read(&mix->line_detect);
- do_gpio_write(&mix->line_detect, val | 0x80);
- }
-#endif
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/ppc/tumbler_volume.h b/ANDROID_3.4.5/sound/ppc/tumbler_volume.h
deleted file mode 100644
index ef8d85d5..00000000
--- a/ANDROID_3.4.5/sound/ppc/tumbler_volume.h
+++ /dev/null
@@ -1,250 +0,0 @@
-/* volume tables, taken from TAS3001c data manual */
-/* volume gain values */
-/* 0 = -70 dB, 175 = 18.0 dB in 0.5 dB step */
-static unsigned int master_volume_table[] = {
- 0x00000015, 0x00000016, 0x00000017,
- 0x00000019, 0x0000001a, 0x0000001c,
- 0x0000001d, 0x0000001f, 0x00000021,
- 0x00000023, 0x00000025, 0x00000027,
- 0x00000029, 0x0000002c, 0x0000002e,
- 0x00000031, 0x00000034, 0x00000037,
- 0x0000003a, 0x0000003e, 0x00000042,
- 0x00000045, 0x0000004a, 0x0000004e,
- 0x00000053, 0x00000057, 0x0000005d,
- 0x00000062, 0x00000068, 0x0000006e,
- 0x00000075, 0x0000007b, 0x00000083,
- 0x0000008b, 0x00000093, 0x0000009b,
- 0x000000a5, 0x000000ae, 0x000000b9,
- 0x000000c4, 0x000000cf, 0x000000dc,
- 0x000000e9, 0x000000f6, 0x00000105,
- 0x00000114, 0x00000125, 0x00000136,
- 0x00000148, 0x0000015c, 0x00000171,
- 0x00000186, 0x0000019e, 0x000001b6,
- 0x000001d0, 0x000001eb, 0x00000209,
- 0x00000227, 0x00000248, 0x0000026b,
- 0x0000028f, 0x000002b6, 0x000002df,
- 0x0000030b, 0x00000339, 0x0000036a,
- 0x0000039e, 0x000003d5, 0x0000040f,
- 0x0000044c, 0x0000048d, 0x000004d2,
- 0x0000051c, 0x00000569, 0x000005bb,
- 0x00000612, 0x0000066e, 0x000006d0,
- 0x00000737, 0x000007a5, 0x00000818,
- 0x00000893, 0x00000915, 0x0000099f,
- 0x00000a31, 0x00000acc, 0x00000b6f,
- 0x00000c1d, 0x00000cd5, 0x00000d97,
- 0x00000e65, 0x00000f40, 0x00001027,
- 0x0000111c, 0x00001220, 0x00001333,
- 0x00001456, 0x0000158a, 0x000016d1,
- 0x0000182b, 0x0000199a, 0x00001b1e,
- 0x00001cb9, 0x00001e6d, 0x0000203a,
- 0x00002223, 0x00002429, 0x0000264e,
- 0x00002893, 0x00002afa, 0x00002d86,
- 0x00003039, 0x00003314, 0x0000361b,
- 0x00003950, 0x00003cb5, 0x0000404e,
- 0x0000441d, 0x00004827, 0x00004c6d,
- 0x000050f4, 0x000055c0, 0x00005ad5,
- 0x00006037, 0x000065ea, 0x00006bf4,
- 0x0000725a, 0x00007920, 0x0000804e,
- 0x000087e8, 0x00008ff6, 0x0000987d,
- 0x0000a186, 0x0000ab19, 0x0000b53c,
- 0x0000bff9, 0x0000cb59, 0x0000d766,
- 0x0000e429, 0x0000f1ae, 0x00010000,
- 0x00010f2b, 0x00011f3d, 0x00013042,
- 0x00014249, 0x00015562, 0x0001699c,
- 0x00017f09, 0x000195bc, 0x0001adc6,
- 0x0001c73d, 0x0001e237, 0x0001feca,
- 0x00021d0e, 0x00023d1d, 0x00025f12,
- 0x0002830b, 0x0002a925, 0x0002d182,
- 0x0002fc42, 0x0003298b, 0x00035983,
- 0x00038c53, 0x0003c225, 0x0003fb28,
- 0x0004378b, 0x00047783, 0x0004bb44,
- 0x0005030a, 0x00054f10, 0x00059f98,
- 0x0005f4e5, 0x00064f40, 0x0006aef6,
- 0x00071457, 0x00077fbb, 0x0007f17b,
-};
-
-/* treble table for TAS3001c */
-/* 0 = -18 dB, 72 = 18 dB in 0.5 dB step */
-static unsigned int treble_volume_table[] = {
- 0x96, 0x95, 0x94,
- 0x93, 0x92, 0x91,
- 0x90, 0x8f, 0x8e,
- 0x8d, 0x8c, 0x8b,
- 0x8a, 0x89, 0x88,
- 0x87, 0x86, 0x85,
- 0x84, 0x83, 0x82,
- 0x81, 0x80, 0x7f,
- 0x7e, 0x7d, 0x7c,
- 0x7b, 0x7a, 0x79,
- 0x78, 0x77, 0x76,
- 0x75, 0x74, 0x73,
- 0x72, 0x71, 0x70,
- 0x6e, 0x6d, 0x6c,
- 0x6b, 0x69, 0x68,
- 0x66, 0x65, 0x63,
- 0x62, 0x60, 0x5e,
- 0x5c, 0x5a, 0x57,
- 0x55, 0x52, 0x4f,
- 0x4c, 0x49, 0x45,
- 0x42, 0x3e, 0x3a,
- 0x36, 0x32, 0x2d,
- 0x28, 0x22, 0x1c,
- 0x16, 0x10, 0x09,
- 0x01,
-};
-
-/* bass table for TAS3001c */
-/* 0 = -18 dB, 72 = 18 dB in 0.5 dB step */
-static unsigned int bass_volume_table[] = {
- 0x86, 0x82, 0x7f,
- 0x7d, 0x7a, 0x78,
- 0x76, 0x74, 0x72,
- 0x70, 0x6e, 0x6d,
- 0x6b, 0x69, 0x66,
- 0x64, 0x61, 0x5f,
- 0x5d, 0x5c, 0x5a,
- 0x59, 0x58, 0x56,
- 0x55, 0x54, 0x53,
- 0x51, 0x4f, 0x4d,
- 0x4b, 0x49, 0x46,
- 0x44, 0x42, 0x40,
- 0x3e, 0x3c, 0x3b,
- 0x39, 0x38, 0x36,
- 0x35, 0x33, 0x31,
- 0x30, 0x2e, 0x2c,
- 0x2b, 0x29, 0x28,
- 0x26, 0x25, 0x23,
- 0x21, 0x1f, 0x1c,
- 0x19, 0x18, 0x17,
- 0x16, 0x14, 0x13,
- 0x12, 0x10, 0x0f,
- 0x0d, 0x0b, 0x0a,
- 0x08, 0x06, 0x03,
- 0x01,
-};
-
-/* mixer (pcm) volume table */
-/* 0 = -70 dB, 175 = 18.0 dB in 0.5 dB step */
-static unsigned int mixer_volume_table[] = {
- 0x00014b, 0x00015f, 0x000174,
- 0x00018a, 0x0001a1, 0x0001ba,
- 0x0001d4, 0x0001f0, 0x00020d,
- 0x00022c, 0x00024d, 0x000270,
- 0x000295, 0x0002bc, 0x0002e6,
- 0x000312, 0x000340, 0x000372,
- 0x0003a6, 0x0003dd, 0x000418,
- 0x000456, 0x000498, 0x0004de,
- 0x000528, 0x000576, 0x0005c9,
- 0x000620, 0x00067d, 0x0006e0,
- 0x000748, 0x0007b7, 0x00082c,
- 0x0008a8, 0x00092b, 0x0009b6,
- 0x000a49, 0x000ae5, 0x000b8b,
- 0x000c3a, 0x000cf3, 0x000db8,
- 0x000e88, 0x000f64, 0x00104e,
- 0x001145, 0x00124b, 0x001361,
- 0x001487, 0x0015be, 0x001708,
- 0x001865, 0x0019d8, 0x001b60,
- 0x001cff, 0x001eb7, 0x002089,
- 0x002276, 0x002481, 0x0026ab,
- 0x0028f5, 0x002b63, 0x002df5,
- 0x0030ae, 0x003390, 0x00369e,
- 0x0039db, 0x003d49, 0x0040ea,
- 0x0044c3, 0x0048d6, 0x004d27,
- 0x0051b9, 0x005691, 0x005bb2,
- 0x006121, 0x0066e3, 0x006cfb,
- 0x007370, 0x007a48, 0x008186,
- 0x008933, 0x009154, 0x0099f1,
- 0x00a310, 0x00acba, 0x00b6f6,
- 0x00c1cd, 0x00cd49, 0x00d973,
- 0x00e655, 0x00f3fb, 0x010270,
- 0x0111c0, 0x0121f9, 0x013328,
- 0x01455b, 0x0158a2, 0x016d0e,
- 0x0182af, 0x019999, 0x01b1de,
- 0x01cb94, 0x01e6cf, 0x0203a7,
- 0x022235, 0x024293, 0x0264db,
- 0x02892c, 0x02afa3, 0x02d862,
- 0x03038a, 0x033142, 0x0361af,
- 0x0394fa, 0x03cb50, 0x0404de,
- 0x0441d5, 0x048268, 0x04c6d0,
- 0x050f44, 0x055c04, 0x05ad50,
- 0x06036e, 0x065ea5, 0x06bf44,
- 0x07259d, 0x079207, 0x0804dc,
- 0x087e80, 0x08ff59, 0x0987d5,
- 0x0a1866, 0x0ab189, 0x0b53be,
- 0x0bff91, 0x0cb591, 0x0d765a,
- 0x0e4290, 0x0f1adf, 0x100000,
- 0x10f2b4, 0x11f3c9, 0x13041a,
- 0x14248e, 0x15561a, 0x1699c0,
- 0x17f094, 0x195bb8, 0x1adc61,
- 0x1c73d5, 0x1e236d, 0x1fec98,
- 0x21d0d9, 0x23d1cd, 0x25f125,
- 0x2830af, 0x2a9254, 0x2d1818,
- 0x2fc420, 0x3298b0, 0x35982f,
- 0x38c528, 0x3c224c, 0x3fb278,
- 0x437880, 0x477828, 0x4bb446,
- 0x5030a1, 0x54f106, 0x59f980,
- 0x5f4e52, 0x64f403, 0x6aef5d,
- 0x714575, 0x77fbaa, 0x7f17af,
-};
-
-
-/* treble table for TAS3004 */
-/* 0 = -18 dB, 72 = 18 dB in 0.5 dB step */
-static unsigned int snapper_treble_volume_table[] = {
- 0x96, 0x95, 0x94,
- 0x93, 0x92, 0x91,
- 0x90, 0x8f, 0x8e,
- 0x8d, 0x8c, 0x8b,
- 0x8a, 0x89, 0x88,
- 0x87, 0x86, 0x85,
- 0x84, 0x83, 0x82,
- 0x81, 0x80, 0x7f,
- 0x7e, 0x7d, 0x7c,
- 0x7b, 0x7a, 0x79,
- 0x78, 0x77, 0x76,
- 0x75, 0x74, 0x73,
- 0x72, 0x71, 0x70,
- 0x6f, 0x6d, 0x6c,
- 0x6b, 0x69, 0x68,
- 0x67, 0x65, 0x63,
- 0x62, 0x60, 0x5d,
- 0x5b, 0x59, 0x56,
- 0x53, 0x51, 0x4d,
- 0x4a, 0x47, 0x43,
- 0x3f, 0x3b, 0x36,
- 0x31, 0x2c, 0x26,
- 0x20, 0x1a, 0x13,
- 0x08, 0x04, 0x01,
- 0x01,
-};
-
-/* bass table for TAS3004 */
-/* 0 = -18 dB, 72 = 18 dB in 0.5 dB step */
-static unsigned int snapper_bass_volume_table[] = {
- 0x96, 0x95, 0x94,
- 0x93, 0x92, 0x91,
- 0x90, 0x8f, 0x8e,
- 0x8d, 0x8c, 0x8b,
- 0x8a, 0x89, 0x88,
- 0x87, 0x86, 0x85,
- 0x84, 0x83, 0x82,
- 0x81, 0x80, 0x7f,
- 0x7e, 0x7d, 0x7c,
- 0x7b, 0x7a, 0x79,
- 0x78, 0x77, 0x76,
- 0x75, 0x74, 0x73,
- 0x72, 0x71, 0x6f,
- 0x6e, 0x6d, 0x6b,
- 0x6a, 0x69, 0x67,
- 0x66, 0x65, 0x63,
- 0x62, 0x61, 0x5f,
- 0x5d, 0x5b, 0x58,
- 0x55, 0x52, 0x4f,
- 0x4c, 0x49, 0x46,
- 0x43, 0x3f, 0x3b,
- 0x37, 0x33, 0x2e,
- 0x29, 0x24, 0x1e,
- 0x18, 0x11, 0x0a,
- 0x01,
-};
-
diff --git a/ANDROID_3.4.5/sound/sh/Kconfig b/ANDROID_3.4.5/sound/sh/Kconfig
deleted file mode 100644
index 61139f3c..00000000
--- a/ANDROID_3.4.5/sound/sh/Kconfig
+++ /dev/null
@@ -1,31 +0,0 @@
-# ALSA SH drivers
-
-menuconfig SND_SUPERH
- bool "SUPERH sound devices"
- depends on SUPERH
- default y
- help
- Support for sound devices specific to SUPERH architectures.
- Drivers that are implemented on ASoC can be found in
- "ALSA for SoC audio support" section.
-
-if SND_SUPERH
-
-config SND_AICA
- tristate "Dreamcast Yamaha AICA sound"
- depends on SH_DREAMCAST
- select SND_PCM
- select G2_DMA
- help
- ALSA Sound driver for the SEGA Dreamcast console.
-
-config SND_SH_DAC_AUDIO
- tristate "SuperH DAC audio support"
- depends on SND
- depends on CPU_SH3 && HIGH_RES_TIMERS
- select SND_PCM
- help
- Say Y here to include support for the on-chip DAC.
-
-endif # SND_SUPERH
-
diff --git a/ANDROID_3.4.5/sound/sh/Makefile b/ANDROID_3.4.5/sound/sh/Makefile
deleted file mode 100644
index 7d09b518..00000000
--- a/ANDROID_3.4.5/sound/sh/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile for ALSA
-#
-
-snd-aica-objs := aica.o
-snd-sh_dac_audio-objs := sh_dac_audio.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_AICA) += snd-aica.o
-obj-$(CONFIG_SND_SH_DAC_AUDIO) += snd-sh_dac_audio.o
diff --git a/ANDROID_3.4.5/sound/sh/aica.c b/ANDROID_3.4.5/sound/sh/aica.c
deleted file mode 100644
index 391a38ca..00000000
--- a/ANDROID_3.4.5/sound/sh/aica.c
+++ /dev/null
@@ -1,689 +0,0 @@
-/*
-* This code is licenced under
-* the General Public Licence
-* version 2
-*
-* Copyright Adrian McMenamin 2005, 2006, 2007
-* <adrian@mcmen.demon.co.uk>
-* Requires firmware (BSD licenced) available from:
-* http://linuxdc.cvs.sourceforge.net/linuxdc/linux-sh-dc/sound/oss/aica/firmware/
-* or the maintainer
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of version 2 of the GNU General Public License as published by
-* the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*
-*/
-
-#include <linux/init.h>
-#include <linux/jiffies.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/firmware.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/workqueue.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/initval.h>
-#include <sound/info.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <mach/sysasic.h>
-#include "aica.h"
-
-MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>");
-MODULE_DESCRIPTION("Dreamcast AICA sound (pcm) driver");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Yamaha/SEGA, AICA}}");
-MODULE_FIRMWARE("aica_firmware.bin");
-
-/* module parameters */
-#define CARD_NAME "AICA"
-static int index = -1;
-static char *id;
-static bool enable = 1;
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
-module_param(enable, bool, 0644);
-MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
-
-/* Use workqueue */
-static struct workqueue_struct *aica_queue;
-
-/* Simple platform device */
-static struct platform_device *pd;
-static struct resource aica_memory_space[2] = {
- {
- .name = "AICA ARM CONTROL",
- .start = ARM_RESET_REGISTER,
- .flags = IORESOURCE_MEM,
- .end = ARM_RESET_REGISTER + 3,
- },
- {
- .name = "AICA Sound RAM",
- .start = SPU_MEMORY_BASE,
- .flags = IORESOURCE_MEM,
- .end = SPU_MEMORY_BASE + 0x200000 - 1,
- },
-};
-
-/* SPU specific functions */
-/* spu_write_wait - wait for G2-SH FIFO to clear */
-static void spu_write_wait(void)
-{
- int time_count;
- time_count = 0;
- while (1) {
- if (!(readl(G2_FIFO) & 0x11))
- break;
- /* To ensure hardware failure doesn't wedge kernel */
- time_count++;
- if (time_count > 0x10000) {
- snd_printk
- ("WARNING: G2 FIFO appears to be blocked.\n");
- break;
- }
- }
-}
-
-/* spu_memset - write to memory in SPU address space */
-static void spu_memset(u32 toi, u32 what, int length)
-{
- int i;
- unsigned long flags;
- if (snd_BUG_ON(length % 4))
- return;
- for (i = 0; i < length; i++) {
- if (!(i % 8))
- spu_write_wait();
- local_irq_save(flags);
- writel(what, toi + SPU_MEMORY_BASE);
- local_irq_restore(flags);
- toi++;
- }
-}
-
-/* spu_memload - write to SPU address space */
-static void spu_memload(u32 toi, void *from, int length)
-{
- unsigned long flags;
- u32 *froml = from;
- u32 __iomem *to = (u32 __iomem *) (SPU_MEMORY_BASE + toi);
- int i;
- u32 val;
- length = DIV_ROUND_UP(length, 4);
- spu_write_wait();
- for (i = 0; i < length; i++) {
- if (!(i % 8))
- spu_write_wait();
- val = *froml;
- local_irq_save(flags);
- writel(val, to);
- local_irq_restore(flags);
- froml++;
- to++;
- }
-}
-
-/* spu_disable - set spu registers to stop sound output */
-static void spu_disable(void)
-{
- int i;
- unsigned long flags;
- u32 regval;
- spu_write_wait();
- regval = readl(ARM_RESET_REGISTER);
- regval |= 1;
- spu_write_wait();
- local_irq_save(flags);
- writel(regval, ARM_RESET_REGISTER);
- local_irq_restore(flags);
- for (i = 0; i < 64; i++) {
- spu_write_wait();
- regval = readl(SPU_REGISTER_BASE + (i * 0x80));
- regval = (regval & ~0x4000) | 0x8000;
- spu_write_wait();
- local_irq_save(flags);
- writel(regval, SPU_REGISTER_BASE + (i * 0x80));
- local_irq_restore(flags);
- }
-}
-
-/* spu_enable - set spu registers to enable sound output */
-static void spu_enable(void)
-{
- unsigned long flags;
- u32 regval = readl(ARM_RESET_REGISTER);
- regval &= ~1;
- spu_write_wait();
- local_irq_save(flags);
- writel(regval, ARM_RESET_REGISTER);
- local_irq_restore(flags);
-}
-
-/*
- * Halt the sound processor, clear the memory,
- * load some default ARM7 code, and then restart ARM7
-*/
-static void spu_reset(void)
-{
- unsigned long flags;
- spu_disable();
- spu_memset(0, 0, 0x200000 / 4);
- /* Put ARM7 in endless loop */
- local_irq_save(flags);
- __raw_writel(0xea000002, SPU_MEMORY_BASE);
- local_irq_restore(flags);
- spu_enable();
-}
-
-/* aica_chn_start - write to spu to start playback */
-static void aica_chn_start(void)
-{
- unsigned long flags;
- spu_write_wait();
- local_irq_save(flags);
- writel(AICA_CMD_KICK | AICA_CMD_START, (u32 *) AICA_CONTROL_POINT);
- local_irq_restore(flags);
-}
-
-/* aica_chn_halt - write to spu to halt playback */
-static void aica_chn_halt(void)
-{
- unsigned long flags;
- spu_write_wait();
- local_irq_save(flags);
- writel(AICA_CMD_KICK | AICA_CMD_STOP, (u32 *) AICA_CONTROL_POINT);
- local_irq_restore(flags);
-}
-
-/* ALSA code below */
-static struct snd_pcm_hardware snd_pcm_aica_playback_hw = {
- .info = (SNDRV_PCM_INFO_NONINTERLEAVED),
- .formats =
- (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_IMA_ADPCM),
- .rates = SNDRV_PCM_RATE_8000_48000,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = AICA_BUFFER_SIZE,
- .period_bytes_min = AICA_PERIOD_SIZE,
- .period_bytes_max = AICA_PERIOD_SIZE,
- .periods_min = AICA_PERIOD_NUMBER,
- .periods_max = AICA_PERIOD_NUMBER,
-};
-
-static int aica_dma_transfer(int channels, int buffer_size,
- struct snd_pcm_substream *substream)
-{
- int q, err, period_offset;
- struct snd_card_aica *dreamcastcard;
- struct snd_pcm_runtime *runtime;
- unsigned long flags;
- err = 0;
- dreamcastcard = substream->pcm->private_data;
- period_offset = dreamcastcard->clicks;
- period_offset %= (AICA_PERIOD_NUMBER / channels);
- runtime = substream->runtime;
- for (q = 0; q < channels; q++) {
- local_irq_save(flags);
- err = dma_xfer(AICA_DMA_CHANNEL,
- (unsigned long) (runtime->dma_area +
- (AICA_BUFFER_SIZE * q) /
- channels +
- AICA_PERIOD_SIZE *
- period_offset),
- AICA_CHANNEL0_OFFSET + q * CHANNEL_OFFSET +
- AICA_PERIOD_SIZE * period_offset,
- buffer_size / channels, AICA_DMA_MODE);
- if (unlikely(err < 0)) {
- local_irq_restore(flags);
- break;
- }
- dma_wait_for_completion(AICA_DMA_CHANNEL);
- local_irq_restore(flags);
- }
- return err;
-}
-
-static void startup_aica(struct snd_card_aica *dreamcastcard)
-{
- spu_memload(AICA_CHANNEL0_CONTROL_OFFSET,
- dreamcastcard->channel, sizeof(struct aica_channel));
- aica_chn_start();
-}
-
-static void run_spu_dma(struct work_struct *work)
-{
- int buffer_size;
- struct snd_pcm_runtime *runtime;
- struct snd_card_aica *dreamcastcard;
- dreamcastcard =
- container_of(work, struct snd_card_aica, spu_dma_work);
- runtime = dreamcastcard->substream->runtime;
- if (unlikely(dreamcastcard->dma_check == 0)) {
- buffer_size =
- frames_to_bytes(runtime, runtime->buffer_size);
- if (runtime->channels > 1)
- dreamcastcard->channel->flags |= 0x01;
- aica_dma_transfer(runtime->channels, buffer_size,
- dreamcastcard->substream);
- startup_aica(dreamcastcard);
- dreamcastcard->clicks =
- buffer_size / (AICA_PERIOD_SIZE * runtime->channels);
- return;
- } else {
- aica_dma_transfer(runtime->channels,
- AICA_PERIOD_SIZE * runtime->channels,
- dreamcastcard->substream);
- snd_pcm_period_elapsed(dreamcastcard->substream);
- dreamcastcard->clicks++;
- if (unlikely(dreamcastcard->clicks >= AICA_PERIOD_NUMBER))
- dreamcastcard->clicks %= AICA_PERIOD_NUMBER;
- mod_timer(&dreamcastcard->timer, jiffies + 1);
- }
-}
-
-static void aica_period_elapsed(unsigned long timer_var)
-{
- /*timer function - so cannot sleep */
- int play_period;
- struct snd_pcm_runtime *runtime;
- struct snd_pcm_substream *substream;
- struct snd_card_aica *dreamcastcard;
- substream = (struct snd_pcm_substream *) timer_var;
- runtime = substream->runtime;
- dreamcastcard = substream->pcm->private_data;
- /* Have we played out an additional period? */
- play_period =
- frames_to_bytes(runtime,
- readl
- (AICA_CONTROL_CHANNEL_SAMPLE_NUMBER)) /
- AICA_PERIOD_SIZE;
- if (play_period == dreamcastcard->current_period) {
- /* reschedule the timer */
- mod_timer(&(dreamcastcard->timer), jiffies + 1);
- return;
- }
- if (runtime->channels > 1)
- dreamcastcard->current_period = play_period;
- if (unlikely(dreamcastcard->dma_check == 0))
- dreamcastcard->dma_check = 1;
- queue_work(aica_queue, &(dreamcastcard->spu_dma_work));
-}
-
-static void spu_begin_dma(struct snd_pcm_substream *substream)
-{
- struct snd_card_aica *dreamcastcard;
- struct snd_pcm_runtime *runtime;
- runtime = substream->runtime;
- dreamcastcard = substream->pcm->private_data;
- /*get the queue to do the work */
- queue_work(aica_queue, &(dreamcastcard->spu_dma_work));
- /* Timer may already be running */
- if (unlikely(dreamcastcard->timer.data)) {
- mod_timer(&dreamcastcard->timer, jiffies + 4);
- return;
- }
- init_timer(&(dreamcastcard->timer));
- dreamcastcard->timer.data = (unsigned long) substream;
- dreamcastcard->timer.function = aica_period_elapsed;
- dreamcastcard->timer.expires = jiffies + 4;
- add_timer(&(dreamcastcard->timer));
-}
-
-static int snd_aicapcm_pcm_open(struct snd_pcm_substream
- *substream)
-{
- struct snd_pcm_runtime *runtime;
- struct aica_channel *channel;
- struct snd_card_aica *dreamcastcard;
- if (!enable)
- return -ENOENT;
- dreamcastcard = substream->pcm->private_data;
- channel = kmalloc(sizeof(struct aica_channel), GFP_KERNEL);
- if (!channel)
- return -ENOMEM;
- /* set defaults for channel */
- channel->sfmt = SM_8BIT;
- channel->cmd = AICA_CMD_START;
- channel->vol = dreamcastcard->master_volume;
- channel->pan = 0x80;
- channel->pos = 0;
- channel->flags = 0; /* default to mono */
- dreamcastcard->channel = channel;
- runtime = substream->runtime;
- runtime->hw = snd_pcm_aica_playback_hw;
- spu_enable();
- dreamcastcard->clicks = 0;
- dreamcastcard->current_period = 0;
- dreamcastcard->dma_check = 0;
- return 0;
-}
-
-static int snd_aicapcm_pcm_close(struct snd_pcm_substream
- *substream)
-{
- struct snd_card_aica *dreamcastcard = substream->pcm->private_data;
- flush_workqueue(aica_queue);
- if (dreamcastcard->timer.data)
- del_timer(&dreamcastcard->timer);
- kfree(dreamcastcard->channel);
- spu_disable();
- return 0;
-}
-
-static int snd_aicapcm_pcm_hw_free(struct snd_pcm_substream
- *substream)
-{
- /* Free the DMA buffer */
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_aicapcm_pcm_hw_params(struct snd_pcm_substream
- *substream, struct snd_pcm_hw_params
- *hw_params)
-{
- /* Allocate a DMA buffer using ALSA built-ins */
- return
- snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-}
-
-static int snd_aicapcm_pcm_prepare(struct snd_pcm_substream
- *substream)
-{
- struct snd_card_aica *dreamcastcard = substream->pcm->private_data;
- if ((substream->runtime)->format == SNDRV_PCM_FORMAT_S16_LE)
- dreamcastcard->channel->sfmt = SM_16BIT;
- dreamcastcard->channel->freq = substream->runtime->rate;
- dreamcastcard->substream = substream;
- return 0;
-}
-
-static int snd_aicapcm_pcm_trigger(struct snd_pcm_substream
- *substream, int cmd)
-{
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- spu_begin_dma(substream);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- aica_chn_halt();
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static unsigned long snd_aicapcm_pcm_pointer(struct snd_pcm_substream
- *substream)
-{
- return readl(AICA_CONTROL_CHANNEL_SAMPLE_NUMBER);
-}
-
-static struct snd_pcm_ops snd_aicapcm_playback_ops = {
- .open = snd_aicapcm_pcm_open,
- .close = snd_aicapcm_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_aicapcm_pcm_hw_params,
- .hw_free = snd_aicapcm_pcm_hw_free,
- .prepare = snd_aicapcm_pcm_prepare,
- .trigger = snd_aicapcm_pcm_trigger,
- .pointer = snd_aicapcm_pcm_pointer,
-};
-
-/* TO DO: set up to handle more than one pcm instance */
-static int __init snd_aicapcmchip(struct snd_card_aica
- *dreamcastcard, int pcm_index)
-{
- struct snd_pcm *pcm;
- int err;
- /* AICA has no capture ability */
- err =
- snd_pcm_new(dreamcastcard->card, "AICA PCM", pcm_index, 1, 0,
- &pcm);
- if (unlikely(err < 0))
- return err;
- pcm->private_data = dreamcastcard;
- strcpy(pcm->name, "AICA PCM");
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_aicapcm_playback_ops);
- /* Allocate the DMA buffers */
- err =
- snd_pcm_lib_preallocate_pages_for_all(pcm,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data
- (GFP_KERNEL),
- AICA_BUFFER_SIZE,
- AICA_BUFFER_SIZE);
- return err;
-}
-
-/* Mixer controls */
-#define aica_pcmswitch_info snd_ctl_boolean_mono_info
-
-static int aica_pcmswitch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = 1; /* TO DO: Fix me */
- return 0;
-}
-
-static int aica_pcmswitch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- if (ucontrol->value.integer.value[0] == 1)
- return 0; /* TO DO: Fix me */
- else
- aica_chn_halt();
- return 0;
-}
-
-static int aica_pcmvolume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 0xFF;
- return 0;
-}
-
-static int aica_pcmvolume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_card_aica *dreamcastcard;
- dreamcastcard = kcontrol->private_data;
- if (unlikely(!dreamcastcard->channel))
- return -ETXTBSY; /* we've not yet been set up */
- ucontrol->value.integer.value[0] = dreamcastcard->channel->vol;
- return 0;
-}
-
-static int aica_pcmvolume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_card_aica *dreamcastcard;
- unsigned int vol;
- dreamcastcard = kcontrol->private_data;
- if (unlikely(!dreamcastcard->channel))
- return -ETXTBSY;
- vol = ucontrol->value.integer.value[0];
- if (vol > 0xff)
- return -EINVAL;
- if (unlikely(dreamcastcard->channel->vol == vol))
- return 0;
- dreamcastcard->channel->vol = ucontrol->value.integer.value[0];
- dreamcastcard->master_volume = ucontrol->value.integer.value[0];
- spu_memload(AICA_CHANNEL0_CONTROL_OFFSET,
- dreamcastcard->channel, sizeof(struct aica_channel));
- return 1;
-}
-
-static struct snd_kcontrol_new snd_aica_pcmswitch_control __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Playback Switch",
- .index = 0,
- .info = aica_pcmswitch_info,
- .get = aica_pcmswitch_get,
- .put = aica_pcmswitch_put
-};
-
-static struct snd_kcontrol_new snd_aica_pcmvolume_control __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Playback Volume",
- .index = 0,
- .info = aica_pcmvolume_info,
- .get = aica_pcmvolume_get,
- .put = aica_pcmvolume_put
-};
-
-static int load_aica_firmware(void)
-{
- int err;
- const struct firmware *fw_entry;
- spu_reset();
- err = request_firmware(&fw_entry, "aica_firmware.bin", &pd->dev);
- if (unlikely(err))
- return err;
- /* write firmware into memory */
- spu_disable();
- spu_memload(0, fw_entry->data, fw_entry->size);
- spu_enable();
- release_firmware(fw_entry);
- return err;
-}
-
-static int __devinit add_aicamixer_controls(struct snd_card_aica
- *dreamcastcard)
-{
- int err;
- err = snd_ctl_add
- (dreamcastcard->card,
- snd_ctl_new1(&snd_aica_pcmvolume_control, dreamcastcard));
- if (unlikely(err < 0))
- return err;
- err = snd_ctl_add
- (dreamcastcard->card,
- snd_ctl_new1(&snd_aica_pcmswitch_control, dreamcastcard));
- if (unlikely(err < 0))
- return err;
- return 0;
-}
-
-static int __devexit snd_aica_remove(struct platform_device *devptr)
-{
- struct snd_card_aica *dreamcastcard;
- dreamcastcard = platform_get_drvdata(devptr);
- if (unlikely(!dreamcastcard))
- return -ENODEV;
- snd_card_free(dreamcastcard->card);
- kfree(dreamcastcard);
- platform_set_drvdata(devptr, NULL);
- return 0;
-}
-
-static int __devinit snd_aica_probe(struct platform_device *devptr)
-{
- int err;
- struct snd_card_aica *dreamcastcard;
- dreamcastcard = kmalloc(sizeof(struct snd_card_aica), GFP_KERNEL);
- if (unlikely(!dreamcastcard))
- return -ENOMEM;
- err = snd_card_create(index, SND_AICA_DRIVER, THIS_MODULE, 0,
- &dreamcastcard->card);
- if (unlikely(err < 0)) {
- kfree(dreamcastcard);
- return err;
- }
- strcpy(dreamcastcard->card->driver, "snd_aica");
- strcpy(dreamcastcard->card->shortname, SND_AICA_DRIVER);
- strcpy(dreamcastcard->card->longname,
- "Yamaha AICA Super Intelligent Sound Processor for SEGA Dreamcast");
- /* Prepare to use the queue */
- INIT_WORK(&(dreamcastcard->spu_dma_work), run_spu_dma);
- /* Load the PCM 'chip' */
- err = snd_aicapcmchip(dreamcastcard, 0);
- if (unlikely(err < 0))
- goto freedreamcast;
- snd_card_set_dev(dreamcastcard->card, &devptr->dev);
- dreamcastcard->timer.data = 0;
- dreamcastcard->channel = NULL;
- /* Add basic controls */
- err = add_aicamixer_controls(dreamcastcard);
- if (unlikely(err < 0))
- goto freedreamcast;
- /* Register the card with ALSA subsystem */
- err = snd_card_register(dreamcastcard->card);
- if (unlikely(err < 0))
- goto freedreamcast;
- platform_set_drvdata(devptr, dreamcastcard);
- aica_queue = create_workqueue(CARD_NAME);
- if (unlikely(!aica_queue))
- goto freedreamcast;
- snd_printk
- ("ALSA Driver for Yamaha AICA Super Intelligent Sound Processor\n");
- return 0;
- freedreamcast:
- snd_card_free(dreamcastcard->card);
- kfree(dreamcastcard);
- return err;
-}
-
-static struct platform_driver snd_aica_driver = {
- .probe = snd_aica_probe,
- .remove = __devexit_p(snd_aica_remove),
- .driver = {
- .name = SND_AICA_DRIVER},
-};
-
-static int __init aica_init(void)
-{
- int err;
- err = platform_driver_register(&snd_aica_driver);
- if (unlikely(err < 0))
- return err;
- pd = platform_device_register_simple(SND_AICA_DRIVER, -1,
- aica_memory_space, 2);
- if (IS_ERR(pd)) {
- platform_driver_unregister(&snd_aica_driver);
- return PTR_ERR(pd);
- }
- /* Load the firmware */
- return load_aica_firmware();
-}
-
-static void __exit aica_exit(void)
-{
- /* Destroy the aica kernel thread *
- * being extra cautious to check if it exists*/
- if (likely(aica_queue))
- destroy_workqueue(aica_queue);
- platform_device_unregister(pd);
- platform_driver_unregister(&snd_aica_driver);
- /* Kill any sound still playing and reset ARM7 to safe state */
- spu_reset();
-}
-
-module_init(aica_init);
-module_exit(aica_exit);
diff --git a/ANDROID_3.4.5/sound/sh/aica.h b/ANDROID_3.4.5/sound/sh/aica.h
deleted file mode 100644
index d098baaa..00000000
--- a/ANDROID_3.4.5/sound/sh/aica.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* aica.h
- * Header file for ALSA driver for
- * Sega Dreamcast Yamaha AICA sound
- * Copyright Adrian McMenamin
- * <adrian@mcmen.demon.co.uk>
- * 2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/* SPU memory and register constants etc */
-#define G2_FIFO 0xa05f688c
-#define SPU_MEMORY_BASE 0xA0800000
-#define ARM_RESET_REGISTER 0xA0702C00
-#define SPU_REGISTER_BASE 0xA0700000
-
-/* AICA channels stuff */
-#define AICA_CONTROL_POINT 0xA0810000
-#define AICA_CONTROL_CHANNEL_SAMPLE_NUMBER 0xA0810008
-#define AICA_CHANNEL0_CONTROL_OFFSET 0x10004
-
-/* Command values */
-#define AICA_CMD_KICK 0x80000000
-#define AICA_CMD_NONE 0
-#define AICA_CMD_START 1
-#define AICA_CMD_STOP 2
-#define AICA_CMD_VOL 3
-
-/* Sound modes */
-#define SM_8BIT 1
-#define SM_16BIT 0
-#define SM_ADPCM 2
-
-/* Buffer and period size */
-#define AICA_BUFFER_SIZE 0x8000
-#define AICA_PERIOD_SIZE 0x800
-#define AICA_PERIOD_NUMBER 16
-
-#define AICA_CHANNEL0_OFFSET 0x11000
-#define AICA_CHANNEL1_OFFSET 0x21000
-#define CHANNEL_OFFSET 0x10000
-
-#define AICA_DMA_CHANNEL 5
-#define AICA_DMA_MODE 5
-
-#define SND_AICA_DRIVER "AICA"
-
-struct aica_channel {
- uint32_t cmd; /* Command ID */
- uint32_t pos; /* Sample position */
- uint32_t length; /* Sample length */
- uint32_t freq; /* Frequency */
- uint32_t vol; /* Volume 0-255 */
- uint32_t pan; /* Pan 0-255 */
- uint32_t sfmt; /* Sound format */
- uint32_t flags; /* Bit flags */
-};
-
-struct snd_card_aica {
- struct work_struct spu_dma_work;
- struct snd_card *card;
- struct aica_channel *channel;
- struct snd_pcm_substream *substream;
- int clicks;
- int current_period;
- struct timer_list timer;
- int master_volume;
- int dma_check;
-};
diff --git a/ANDROID_3.4.5/sound/sh/sh_dac_audio.c b/ANDROID_3.4.5/sound/sh/sh_dac_audio.c
deleted file mode 100644
index b11f82b5..00000000
--- a/ANDROID_3.4.5/sound/sh/sh_dac_audio.c
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * sh_dac_audio.c - SuperH DAC audio driver for ALSA
- *
- * Copyright (c) 2009 by Rafael Ignacio Zurita <rizurita@yahoo.com>
- *
- *
- * Based on sh_dac_audio.c (Copyright (C) 2004, 2005 by Andriy Skulysh)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/hrtimer.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/sh_dac_audio.h>
-#include <asm/clock.h>
-#include <asm/hd64461.h>
-#include <mach/hp6xx.h>
-#include <cpu/dac.h>
-
-MODULE_AUTHOR("Rafael Ignacio Zurita <rizurita@yahoo.com>");
-MODULE_DESCRIPTION("SuperH DAC audio driver");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{SuperH DAC audio support}}");
-
-/* Module Parameters */
-static int index = SNDRV_DEFAULT_IDX1;
-static char *id = SNDRV_DEFAULT_STR1;
-module_param(index, int, 0444);
-MODULE_PARM_DESC(index, "Index value for SuperH DAC audio.");
-module_param(id, charp, 0444);
-MODULE_PARM_DESC(id, "ID string for SuperH DAC audio.");
-
-/* main struct */
-struct snd_sh_dac {
- struct snd_card *card;
- struct snd_pcm_substream *substream;
- struct hrtimer hrtimer;
- ktime_t wakeups_per_second;
-
- int rate;
- int empty;
- char *data_buffer, *buffer_begin, *buffer_end;
- int processed; /* bytes proccesed, to compare with period_size */
- int buffer_size;
- struct dac_audio_pdata *pdata;
-};
-
-
-static void dac_audio_start_timer(struct snd_sh_dac *chip)
-{
- hrtimer_start(&chip->hrtimer, chip->wakeups_per_second,
- HRTIMER_MODE_REL);
-}
-
-static void dac_audio_stop_timer(struct snd_sh_dac *chip)
-{
- hrtimer_cancel(&chip->hrtimer);
-}
-
-static void dac_audio_reset(struct snd_sh_dac *chip)
-{
- dac_audio_stop_timer(chip);
- chip->buffer_begin = chip->buffer_end = chip->data_buffer;
- chip->processed = 0;
- chip->empty = 1;
-}
-
-static void dac_audio_set_rate(struct snd_sh_dac *chip)
-{
- chip->wakeups_per_second = ktime_set(0, 1000000000 / chip->rate);
-}
-
-
-/* PCM INTERFACE */
-
-static struct snd_pcm_hardware snd_sh_dac_pcm_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_HALF_DUPLEX),
- .formats = SNDRV_PCM_FMTBIT_U8,
- .rates = SNDRV_PCM_RATE_8000,
- .rate_min = 8000,
- .rate_max = 8000,
- .channels_min = 1,
- .channels_max = 1,
- .buffer_bytes_max = (48*1024),
- .period_bytes_min = 1,
- .period_bytes_max = (48*1024),
- .periods_min = 1,
- .periods_max = 1024,
-};
-
-static int snd_sh_dac_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- runtime->hw = snd_sh_dac_pcm_hw;
-
- chip->substream = substream;
- chip->buffer_begin = chip->buffer_end = chip->data_buffer;
- chip->processed = 0;
- chip->empty = 1;
-
- chip->pdata->start(chip->pdata);
-
- return 0;
-}
-
-static int snd_sh_dac_pcm_close(struct snd_pcm_substream *substream)
-{
- struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
-
- chip->substream = NULL;
-
- dac_audio_stop_timer(chip);
- chip->pdata->stop(chip->pdata);
-
- return 0;
-}
-
-static int snd_sh_dac_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-}
-
-static int snd_sh_dac_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_sh_dac_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = chip->substream->runtime;
-
- chip->buffer_size = runtime->buffer_size;
- memset(chip->data_buffer, 0, chip->pdata->buffer_size);
-
- return 0;
-}
-
-static int snd_sh_dac_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- dac_audio_start_timer(chip);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- chip->buffer_begin = chip->buffer_end = chip->data_buffer;
- chip->processed = 0;
- chip->empty = 1;
- dac_audio_stop_timer(chip);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int snd_sh_dac_pcm_copy(struct snd_pcm_substream *substream, int channel,
- snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count)
-{
- /* channel is not used (interleaved data) */
- struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- ssize_t b_count = frames_to_bytes(runtime , count);
- ssize_t b_pos = frames_to_bytes(runtime , pos);
-
- if (count < 0)
- return -EINVAL;
-
- if (!count)
- return 0;
-
- memcpy_toio(chip->data_buffer + b_pos, src, b_count);
- chip->buffer_end = chip->data_buffer + b_pos + b_count;
-
- if (chip->empty) {
- chip->empty = 0;
- dac_audio_start_timer(chip);
- }
-
- return 0;
-}
-
-static int snd_sh_dac_pcm_silence(struct snd_pcm_substream *substream,
- int channel, snd_pcm_uframes_t pos,
- snd_pcm_uframes_t count)
-{
- /* channel is not used (interleaved data) */
- struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- ssize_t b_count = frames_to_bytes(runtime , count);
- ssize_t b_pos = frames_to_bytes(runtime , pos);
-
- if (count < 0)
- return -EINVAL;
-
- if (!count)
- return 0;
-
- memset_io(chip->data_buffer + b_pos, 0, b_count);
- chip->buffer_end = chip->data_buffer + b_pos + b_count;
-
- if (chip->empty) {
- chip->empty = 0;
- dac_audio_start_timer(chip);
- }
-
- return 0;
-}
-
-static
-snd_pcm_uframes_t snd_sh_dac_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
- int pointer = chip->buffer_begin - chip->data_buffer;
-
- return pointer;
-}
-
-/* pcm ops */
-static struct snd_pcm_ops snd_sh_dac_pcm_ops = {
- .open = snd_sh_dac_pcm_open,
- .close = snd_sh_dac_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_sh_dac_pcm_hw_params,
- .hw_free = snd_sh_dac_pcm_hw_free,
- .prepare = snd_sh_dac_pcm_prepare,
- .trigger = snd_sh_dac_pcm_trigger,
- .pointer = snd_sh_dac_pcm_pointer,
- .copy = snd_sh_dac_pcm_copy,
- .silence = snd_sh_dac_pcm_silence,
- .mmap = snd_pcm_lib_mmap_iomem,
-};
-
-static int __devinit snd_sh_dac_pcm(struct snd_sh_dac *chip, int device)
-{
- int err;
- struct snd_pcm *pcm;
-
- /* device should be always 0 for us */
- err = snd_pcm_new(chip->card, "SH_DAC PCM", device, 1, 0, &pcm);
- if (err < 0)
- return err;
-
- pcm->private_data = chip;
- strcpy(pcm->name, "SH_DAC PCM");
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sh_dac_pcm_ops);
-
- /* buffer size=48K */
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- 48 * 1024,
- 48 * 1024);
-
- return 0;
-}
-/* END OF PCM INTERFACE */
-
-
-/* driver .remove -- destructor */
-static int snd_sh_dac_remove(struct platform_device *devptr)
-{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
-
- return 0;
-}
-
-/* free -- it has been defined by create */
-static int snd_sh_dac_free(struct snd_sh_dac *chip)
-{
- /* release the data */
- kfree(chip->data_buffer);
- kfree(chip);
-
- return 0;
-}
-
-static int snd_sh_dac_dev_free(struct snd_device *device)
-{
- struct snd_sh_dac *chip = device->device_data;
-
- return snd_sh_dac_free(chip);
-}
-
-static enum hrtimer_restart sh_dac_audio_timer(struct hrtimer *handle)
-{
- struct snd_sh_dac *chip = container_of(handle, struct snd_sh_dac,
- hrtimer);
- struct snd_pcm_runtime *runtime = chip->substream->runtime;
- ssize_t b_ps = frames_to_bytes(runtime, runtime->period_size);
-
- if (!chip->empty) {
- sh_dac_output(*chip->buffer_begin, chip->pdata->channel);
- chip->buffer_begin++;
-
- chip->processed++;
- if (chip->processed >= b_ps) {
- chip->processed -= b_ps;
- snd_pcm_period_elapsed(chip->substream);
- }
-
- if (chip->buffer_begin == (chip->data_buffer +
- chip->buffer_size - 1))
- chip->buffer_begin = chip->data_buffer;
-
- if (chip->buffer_begin == chip->buffer_end)
- chip->empty = 1;
-
- }
-
- if (!chip->empty)
- hrtimer_start(&chip->hrtimer, chip->wakeups_per_second,
- HRTIMER_MODE_REL);
-
- return HRTIMER_NORESTART;
-}
-
-/* create -- chip-specific constructor for the cards components */
-static int __devinit snd_sh_dac_create(struct snd_card *card,
- struct platform_device *devptr,
- struct snd_sh_dac **rchip)
-{
- struct snd_sh_dac *chip;
- int err;
-
- static struct snd_device_ops ops = {
- .dev_free = snd_sh_dac_dev_free,
- };
-
- *rchip = NULL;
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL)
- return -ENOMEM;
-
- chip->card = card;
-
- hrtimer_init(&chip->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- chip->hrtimer.function = sh_dac_audio_timer;
-
- dac_audio_reset(chip);
- chip->rate = 8000;
- dac_audio_set_rate(chip);
-
- chip->pdata = devptr->dev.platform_data;
-
- chip->data_buffer = kmalloc(chip->pdata->buffer_size, GFP_KERNEL);
- if (chip->data_buffer == NULL) {
- kfree(chip);
- return -ENOMEM;
- }
-
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
- if (err < 0) {
- snd_sh_dac_free(chip);
- return err;
- }
-
- *rchip = chip;
-
- return 0;
-}
-
-/* driver .probe -- constructor */
-static int __devinit snd_sh_dac_probe(struct platform_device *devptr)
-{
- struct snd_sh_dac *chip;
- struct snd_card *card;
- int err;
-
- err = snd_card_create(index, id, THIS_MODULE, 0, &card);
- if (err < 0) {
- snd_printk(KERN_ERR "cannot allocate the card\n");
- return err;
- }
-
- err = snd_sh_dac_create(card, devptr, &chip);
- if (err < 0)
- goto probe_error;
-
- err = snd_sh_dac_pcm(chip, 0);
- if (err < 0)
- goto probe_error;
-
- strcpy(card->driver, "snd_sh_dac");
- strcpy(card->shortname, "SuperH DAC audio driver");
- printk(KERN_INFO "%s %s", card->longname, card->shortname);
-
- err = snd_card_register(card);
- if (err < 0)
- goto probe_error;
-
- snd_printk("ALSA driver for SuperH DAC audio");
-
- platform_set_drvdata(devptr, card);
- return 0;
-
-probe_error:
- snd_card_free(card);
- return err;
-}
-
-/*
- * "driver" definition
- */
-static struct platform_driver driver = {
- .probe = snd_sh_dac_probe,
- .remove = snd_sh_dac_remove,
- .driver = {
- .name = "dac_audio",
- },
-};
-
-module_platform_driver(driver);
diff --git a/ANDROID_3.4.5/sound/soc/Kconfig b/ANDROID_3.4.5/sound/soc/Kconfig
deleted file mode 100644
index 5727227d..00000000
--- a/ANDROID_3.4.5/sound/soc/Kconfig
+++ /dev/null
@@ -1,57 +0,0 @@
-#
-# SoC audio configuration
-#
-
-menuconfig SND_SOC
- tristate "ALSA for SoC audio support"
- select SND_PCM
- select AC97_BUS if SND_SOC_AC97_BUS
- select SND_JACK if INPUT=y || INPUT=SND
- select REGMAP_I2C if I2C
- select REGMAP_SPI if SPI_MASTER
- ---help---
-
- If you want ASoC support, you should say Y here and also to the
- specific driver for your SoC platform below.
-
- ASoC provides power efficient ALSA support for embedded battery powered
- SoC based systems like PDA's, Phones and Personal Media Players.
-
- This ASoC audio support can also be built as a module. If so, the module
- will be called snd-soc-core.
-
-if SND_SOC
-
-config SND_SOC_AC97_BUS
- bool
-
-config SND_SOC_DMAENGINE_PCM
- bool
-
-# All the supported SoCs
-source "sound/soc/atmel/Kconfig"
-source "sound/soc/au1x/Kconfig"
-source "sound/soc/blackfin/Kconfig"
-source "sound/soc/davinci/Kconfig"
-source "sound/soc/ep93xx/Kconfig"
-source "sound/soc/fsl/Kconfig"
-source "sound/soc/imx/Kconfig"
-source "sound/soc/jz4740/Kconfig"
-source "sound/soc/nuc900/Kconfig"
-source "sound/soc/omap/Kconfig"
-source "sound/soc/kirkwood/Kconfig"
-source "sound/soc/mid-x86/Kconfig"
-source "sound/soc/mxs/Kconfig"
-source "sound/soc/pxa/Kconfig"
-source "sound/soc/samsung/Kconfig"
-source "sound/soc/s6000/Kconfig"
-source "sound/soc/sh/Kconfig"
-source "sound/soc/tegra/Kconfig"
-source "sound/soc/txx9/Kconfig"
-source "sound/soc/wmt/Kconfig"
-
-# Supported codecs
-source "sound/soc/codecs/Kconfig"
-
-endif # SND_SOC
-
diff --git a/ANDROID_3.4.5/sound/soc/Makefile b/ANDROID_3.4.5/sound/soc/Makefile
deleted file mode 100644
index 4dca9714..00000000
--- a/ANDROID_3.4.5/sound/soc/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
-snd-soc-core-objs += soc-pcm.o soc-io.o
-
-snd-soc-dmaengine-pcm-objs := soc-dmaengine-pcm.o
-obj-$(CONFIG_SND_SOC_DMAENGINE_PCM) += snd-soc-dmaengine-pcm.o
-
-obj-$(CONFIG_SND_SOC) += snd-soc-core.o
-obj-$(CONFIG_SND_SOC) += wmt/
-obj-$(CONFIG_SND_SOC) += codecs/
-obj-$(CONFIG_SND_SOC) += atmel/
-obj-$(CONFIG_SND_SOC) += au1x/
-obj-$(CONFIG_SND_SOC) += blackfin/
-obj-$(CONFIG_SND_SOC) += davinci/
-obj-$(CONFIG_SND_SOC) += ep93xx/
-obj-$(CONFIG_SND_SOC) += fsl/
-obj-$(CONFIG_SND_SOC) += imx/
-obj-$(CONFIG_SND_SOC) += jz4740/
-obj-$(CONFIG_SND_SOC) += mid-x86/
-obj-$(CONFIG_SND_SOC) += mxs/
-obj-$(CONFIG_SND_SOC) += nuc900/
-obj-$(CONFIG_SND_SOC) += omap/
-obj-$(CONFIG_SND_SOC) += kirkwood/
-obj-$(CONFIG_SND_SOC) += pxa/
-obj-$(CONFIG_SND_SOC) += samsung/
-obj-$(CONFIG_SND_SOC) += s6000/
-obj-$(CONFIG_SND_SOC) += sh/
-obj-$(CONFIG_SND_SOC) += tegra/
-obj-$(CONFIG_SND_SOC) += txx9/
diff --git a/ANDROID_3.4.5/sound/soc/atmel/Kconfig b/ANDROID_3.4.5/sound/soc/atmel/Kconfig
deleted file mode 100644
index 72b09cfd..00000000
--- a/ANDROID_3.4.5/sound/soc/atmel/Kconfig
+++ /dev/null
@@ -1,33 +0,0 @@
-config SND_ATMEL_SOC
- tristate "SoC Audio for the Atmel System-on-Chip"
- depends on ARCH_AT91
- help
- Say Y or M if you want to add support for codecs attached to
- the ATMEL SSC interface. You will also need
- to select the audio interfaces to support below.
-
-config SND_ATMEL_SOC_SSC
- tristate
- depends on SND_ATMEL_SOC
- help
- Say Y or M if you want to add support for codecs the
- ATMEL SSC interface. You will also needs to select the individual
- machine drivers to support below.
-
-config SND_AT91_SOC_SAM9G20_WM8731
- tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
- depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC && \
- AT91_PROGRAMMABLE_CLOCKS
- select SND_ATMEL_SOC_SSC
- select SND_SOC_WM8731
- help
- Say Y if you want to add support for SoC audio on WM8731-based
- AT91sam9g20 evaluation board.
-
-config SND_AT91_SOC_AFEB9260
- tristate "SoC Audio support for AFEB9260 board"
- depends on ATMEL_SSC && ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC
- select SND_ATMEL_SOC_SSC
- select SND_SOC_TLV320AIC23
- help
- Say Y here to support sound on AFEB9260 board.
diff --git a/ANDROID_3.4.5/sound/soc/atmel/Makefile b/ANDROID_3.4.5/sound/soc/atmel/Makefile
deleted file mode 100644
index a5c0bf19..00000000
--- a/ANDROID_3.4.5/sound/soc/atmel/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# AT91 Platform Support
-snd-soc-atmel-pcm-objs := atmel-pcm.o
-snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o
-
-obj-$(CONFIG_SND_ATMEL_SOC) += snd-soc-atmel-pcm.o
-obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
-
-# AT91 Machine Support
-snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o
-
-obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o
-obj-$(CONFIG_SND_AT91_SOC_AFEB9260) += snd-soc-afeb9260.o
diff --git a/ANDROID_3.4.5/sound/soc/atmel/atmel-pcm.c b/ANDROID_3.4.5/sound/soc/atmel/atmel-pcm.c
deleted file mode 100644
index 9b84f985..00000000
--- a/ANDROID_3.4.5/sound/soc/atmel/atmel-pcm.c
+++ /dev/null
@@ -1,501 +0,0 @@
-/*
- * atmel-pcm.c -- ALSA PCM interface for the Atmel atmel SoC.
- *
- * Copyright (C) 2005 SAN People
- * Copyright (C) 2008 Atmel
- *
- * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com>
- *
- * Based on at91-pcm. by:
- * Frank Mandarino <fmandarino@endrelia.com>
- * Copyright 2006 Endrelia Technologies Inc.
- *
- * Based on pxa2xx-pcm.c by:
- *
- * Author: Nicolas Pitre
- * Created: Nov 30, 2004
- * Copyright: (C) 2004 MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/dma-mapping.h>
-#include <linux/atmel_pdc.h>
-#include <linux/atmel-ssc.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include "atmel-pcm.h"
-
-
-/*--------------------------------------------------------------------------*\
- * Hardware definition
-\*--------------------------------------------------------------------------*/
-/* TODO: These values were taken from the AT91 platform driver, check
- * them against real values for AT32
- */
-static const struct snd_pcm_hardware atmel_pcm_hardware = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .period_bytes_min = 32,
- .period_bytes_max = 8192,
- .periods_min = 2,
- .periods_max = 1024,
- .buffer_bytes_max = 32 * 1024,
-};
-
-
-/*--------------------------------------------------------------------------*\
- * Data types
-\*--------------------------------------------------------------------------*/
-struct atmel_runtime_data {
- struct atmel_pcm_dma_params *params;
- dma_addr_t dma_buffer; /* physical address of dma buffer */
- dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */
- size_t period_size;
-
- dma_addr_t period_ptr; /* physical address of next period */
-
- /* PDC register save */
- u32 pdc_xpr_save;
- u32 pdc_xcr_save;
- u32 pdc_xnpr_save;
- u32 pdc_xncr_save;
-};
-
-
-/*--------------------------------------------------------------------------*\
- * Helper functions
-\*--------------------------------------------------------------------------*/
-static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
- int stream)
-{
- struct snd_pcm_substream *substream = pcm->streams[stream].substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = atmel_pcm_hardware.buffer_bytes_max;
-
- buf->dev.type = SNDRV_DMA_TYPE_DEV;
- buf->dev.dev = pcm->card->dev;
- buf->private_data = NULL;
- buf->area = dma_alloc_coherent(pcm->card->dev, size,
- &buf->addr, GFP_KERNEL);
- pr_debug("atmel-pcm:"
- "preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
- (void *) buf->area,
- (void *) buf->addr,
- size);
-
- if (!buf->area)
- return -ENOMEM;
-
- buf->bytes = size;
- return 0;
-}
-/*--------------------------------------------------------------------------*\
- * ISR
-\*--------------------------------------------------------------------------*/
-static void atmel_pcm_dma_irq(u32 ssc_sr,
- struct snd_pcm_substream *substream)
-{
- struct atmel_runtime_data *prtd = substream->runtime->private_data;
- struct atmel_pcm_dma_params *params = prtd->params;
- static int count;
-
- count++;
-
- if (ssc_sr & params->mask->ssc_endbuf) {
- pr_warning("atmel-pcm: buffer %s on %s"
- " (SSC_SR=%#x, count=%d)\n",
- substream->stream == SNDRV_PCM_STREAM_PLAYBACK
- ? "underrun" : "overrun",
- params->name, ssc_sr, count);
-
- /* re-start the PDC */
- ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
- params->mask->pdc_disable);
- prtd->period_ptr += prtd->period_size;
- if (prtd->period_ptr >= prtd->dma_buffer_end)
- prtd->period_ptr = prtd->dma_buffer;
-
- ssc_writex(params->ssc->regs, params->pdc->xpr,
- prtd->period_ptr);
- ssc_writex(params->ssc->regs, params->pdc->xcr,
- prtd->period_size / params->pdc_xfer_size);
- ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
- params->mask->pdc_enable);
- }
-
- if (ssc_sr & params->mask->ssc_endx) {
- /* Load the PDC next pointer and counter registers */
- prtd->period_ptr += prtd->period_size;
- if (prtd->period_ptr >= prtd->dma_buffer_end)
- prtd->period_ptr = prtd->dma_buffer;
-
- ssc_writex(params->ssc->regs, params->pdc->xnpr,
- prtd->period_ptr);
- ssc_writex(params->ssc->regs, params->pdc->xncr,
- prtd->period_size / params->pdc_xfer_size);
- }
-
- snd_pcm_period_elapsed(substream);
-}
-
-
-/*--------------------------------------------------------------------------*\
- * PCM operations
-\*--------------------------------------------------------------------------*/
-static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct atmel_runtime_data *prtd = runtime->private_data;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
-
- /* this may get called several times by oss emulation
- * with different params */
-
- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
- runtime->dma_bytes = params_buffer_bytes(params);
-
- prtd->params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
- prtd->params->dma_intr_handler = atmel_pcm_dma_irq;
-
- prtd->dma_buffer = runtime->dma_addr;
- prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes;
- prtd->period_size = params_period_bytes(params);
-
- pr_debug("atmel-pcm: "
- "hw_params: DMA for %s initialized "
- "(dma_bytes=%u, period_size=%u)\n",
- prtd->params->name,
- runtime->dma_bytes,
- prtd->period_size);
- return 0;
-}
-
-static int atmel_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct atmel_runtime_data *prtd = substream->runtime->private_data;
- struct atmel_pcm_dma_params *params = prtd->params;
-
- if (params != NULL) {
- ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
- params->mask->pdc_disable);
- prtd->params->dma_intr_handler = NULL;
- }
-
- return 0;
-}
-
-static int atmel_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct atmel_runtime_data *prtd = substream->runtime->private_data;
- struct atmel_pcm_dma_params *params = prtd->params;
-
- ssc_writex(params->ssc->regs, SSC_IDR,
- params->mask->ssc_endx | params->mask->ssc_endbuf);
- ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
- params->mask->pdc_disable);
- return 0;
-}
-
-static int atmel_pcm_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_pcm_runtime *rtd = substream->runtime;
- struct atmel_runtime_data *prtd = rtd->private_data;
- struct atmel_pcm_dma_params *params = prtd->params;
- int ret = 0;
-
- pr_debug("atmel-pcm:buffer_size = %ld,"
- "dma_area = %p, dma_bytes = %u\n",
- rtd->buffer_size, rtd->dma_area, rtd->dma_bytes);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- prtd->period_ptr = prtd->dma_buffer;
-
- ssc_writex(params->ssc->regs, params->pdc->xpr,
- prtd->period_ptr);
- ssc_writex(params->ssc->regs, params->pdc->xcr,
- prtd->period_size / params->pdc_xfer_size);
-
- prtd->period_ptr += prtd->period_size;
- ssc_writex(params->ssc->regs, params->pdc->xnpr,
- prtd->period_ptr);
- ssc_writex(params->ssc->regs, params->pdc->xncr,
- prtd->period_size / params->pdc_xfer_size);
-
- pr_debug("atmel-pcm: trigger: "
- "period_ptr=%lx, xpr=%u, "
- "xcr=%u, xnpr=%u, xncr=%u\n",
- (unsigned long)prtd->period_ptr,
- ssc_readx(params->ssc->regs, params->pdc->xpr),
- ssc_readx(params->ssc->regs, params->pdc->xcr),
- ssc_readx(params->ssc->regs, params->pdc->xnpr),
- ssc_readx(params->ssc->regs, params->pdc->xncr));
-
- ssc_writex(params->ssc->regs, SSC_IER,
- params->mask->ssc_endx | params->mask->ssc_endbuf);
- ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
- params->mask->pdc_enable);
-
- pr_debug("sr=%u imr=%u\n",
- ssc_readx(params->ssc->regs, SSC_SR),
- ssc_readx(params->ssc->regs, SSC_IER));
- break; /* SNDRV_PCM_TRIGGER_START */
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
- params->mask->pdc_disable);
- break;
-
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
- params->mask->pdc_enable);
- break;
-
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static snd_pcm_uframes_t atmel_pcm_pointer(
- struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct atmel_runtime_data *prtd = runtime->private_data;
- struct atmel_pcm_dma_params *params = prtd->params;
- dma_addr_t ptr;
- snd_pcm_uframes_t x;
-
- ptr = (dma_addr_t) ssc_readx(params->ssc->regs, params->pdc->xpr);
- x = bytes_to_frames(runtime, ptr - prtd->dma_buffer);
-
- if (x == runtime->buffer_size)
- x = 0;
-
- return x;
-}
-
-static int atmel_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct atmel_runtime_data *prtd;
- int ret = 0;
-
- snd_soc_set_runtime_hwparams(substream, &atmel_pcm_hardware);
-
- /* ensure that buffer size is a multiple of period size */
- ret = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (ret < 0)
- goto out;
-
- prtd = kzalloc(sizeof(struct atmel_runtime_data), GFP_KERNEL);
- if (prtd == NULL) {
- ret = -ENOMEM;
- goto out;
- }
- runtime->private_data = prtd;
-
- out:
- return ret;
-}
-
-static int atmel_pcm_close(struct snd_pcm_substream *substream)
-{
- struct atmel_runtime_data *prtd = substream->runtime->private_data;
-
- kfree(prtd);
- return 0;
-}
-
-static int atmel_pcm_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- return remap_pfn_range(vma, vma->vm_start,
- substream->dma_buffer.addr >> PAGE_SHIFT,
- vma->vm_end - vma->vm_start, vma->vm_page_prot);
-}
-
-static struct snd_pcm_ops atmel_pcm_ops = {
- .open = atmel_pcm_open,
- .close = atmel_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = atmel_pcm_hw_params,
- .hw_free = atmel_pcm_hw_free,
- .prepare = atmel_pcm_prepare,
- .trigger = atmel_pcm_trigger,
- .pointer = atmel_pcm_pointer,
- .mmap = atmel_pcm_mmap,
-};
-
-
-/*--------------------------------------------------------------------------*\
- * ASoC platform driver
-\*--------------------------------------------------------------------------*/
-static u64 atmel_pcm_dmamask = DMA_BIT_MASK(32);
-
-static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- int ret = 0;
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &atmel_pcm_dmamask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = atmel_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_PLAYBACK);
- if (ret)
- goto out;
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- pr_debug("atmel-pcm:"
- "Allocating PCM capture DMA buffer\n");
- ret = atmel_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_CAPTURE);
- if (ret)
- goto out;
- }
- out:
- return ret;
-}
-
-static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- struct snd_dma_buffer *buf;
- int stream;
-
- for (stream = 0; stream < 2; stream++) {
- substream = pcm->streams[stream].substream;
- if (!substream)
- continue;
-
- buf = &substream->dma_buffer;
- if (!buf->area)
- continue;
- dma_free_coherent(pcm->card->dev, buf->bytes,
- buf->area, buf->addr);
- buf->area = NULL;
- }
-}
-
-#ifdef CONFIG_PM
-static int atmel_pcm_suspend(struct snd_soc_dai *dai)
-{
- struct snd_pcm_runtime *runtime = dai->runtime;
- struct atmel_runtime_data *prtd;
- struct atmel_pcm_dma_params *params;
-
- if (!runtime)
- return 0;
-
- prtd = runtime->private_data;
- params = prtd->params;
-
- /* disable the PDC and save the PDC registers */
-
- ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable);
-
- prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr);
- prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr);
- prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr);
- prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr);
-
- return 0;
-}
-
-static int atmel_pcm_resume(struct snd_soc_dai *dai)
-{
- struct snd_pcm_runtime *runtime = dai->runtime;
- struct atmel_runtime_data *prtd;
- struct atmel_pcm_dma_params *params;
-
- if (!runtime)
- return 0;
-
- prtd = runtime->private_data;
- params = prtd->params;
-
- /* restore the PDC registers and enable the PDC */
- ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save);
- ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save);
- ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save);
- ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save);
-
- ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable);
- return 0;
-}
-#else
-#define atmel_pcm_suspend NULL
-#define atmel_pcm_resume NULL
-#endif
-
-static struct snd_soc_platform_driver atmel_soc_platform = {
- .ops = &atmel_pcm_ops,
- .pcm_new = atmel_pcm_new,
- .pcm_free = atmel_pcm_free_dma_buffers,
- .suspend = atmel_pcm_suspend,
- .resume = atmel_pcm_resume,
-};
-
-static int __devinit atmel_soc_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_platform(&pdev->dev, &atmel_soc_platform);
-}
-
-static int __devexit atmel_soc_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver atmel_pcm_driver = {
- .driver = {
- .name = "atmel-pcm-audio",
- .owner = THIS_MODULE,
- },
-
- .probe = atmel_soc_platform_probe,
- .remove = __devexit_p(atmel_soc_platform_remove),
-};
-
-module_platform_driver(atmel_pcm_driver);
-
-MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
-MODULE_DESCRIPTION("Atmel PCM module");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/atmel/atmel-pcm.h b/ANDROID_3.4.5/sound/soc/atmel/atmel-pcm.h
deleted file mode 100644
index 5e0a95e6..00000000
--- a/ANDROID_3.4.5/sound/soc/atmel/atmel-pcm.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * at91-pcm.h - ALSA PCM interface for the Atmel AT91 SoC.
- *
- * Copyright (C) 2005 SAN People
- * Copyright (C) 2008 Atmel
- *
- * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com>
- *
- * Based on at91-pcm. by:
- * Frank Mandarino <fmandarino@endrelia.com>
- * Copyright 2006 Endrelia Technologies Inc.
- *
- * Based on pxa2xx-pcm.c by:
- *
- * Author: Nicolas Pitre
- * Created: Nov 30, 2004
- * Copyright: (C) 2004 MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _ATMEL_PCM_H
-#define _ATMEL_PCM_H
-
-#include <linux/atmel-ssc.h>
-
-/*
- * Registers and status bits that are required by the PCM driver.
- */
-struct atmel_pdc_regs {
- unsigned int xpr; /* PDC recv/trans pointer */
- unsigned int xcr; /* PDC recv/trans counter */
- unsigned int xnpr; /* PDC next recv/trans pointer */
- unsigned int xncr; /* PDC next recv/trans counter */
- unsigned int ptcr; /* PDC transfer control */
-};
-
-struct atmel_ssc_mask {
- u32 ssc_enable; /* SSC recv/trans enable */
- u32 ssc_disable; /* SSC recv/trans disable */
- u32 ssc_endx; /* SSC ENDTX or ENDRX */
- u32 ssc_endbuf; /* SSC TXBUFE or RXBUFF */
- u32 pdc_enable; /* PDC recv/trans enable */
- u32 pdc_disable; /* PDC recv/trans disable */
-};
-
-/*
- * This structure, shared between the PCM driver and the interface,
- * contains all information required by the PCM driver to perform the
- * PDC DMA operation. All fields except dma_intr_handler() are initialized
- * by the interface. The dma_intr_handler() pointer is set by the PCM
- * driver and called by the interface SSC interrupt handler if it is
- * non-NULL.
- */
-struct atmel_pcm_dma_params {
- char *name; /* stream identifier */
- int pdc_xfer_size; /* PDC counter increment in bytes */
- struct ssc_device *ssc; /* SSC device for stream */
- struct atmel_pdc_regs *pdc; /* PDC receive or transmit registers */
- struct atmel_ssc_mask *mask; /* SSC & PDC status bits */
- struct snd_pcm_substream *substream;
- void (*dma_intr_handler)(u32, struct snd_pcm_substream *);
-};
-
-/*
- * SSC register access (since ssc_writel() / ssc_readl() require literal name)
- */
-#define ssc_readx(base, reg) (__raw_readl((base) + (reg)))
-#define ssc_writex(base, reg, value) __raw_writel((value), (base) + (reg))
-
-#endif /* _ATMEL_PCM_H */
diff --git a/ANDROID_3.4.5/sound/soc/atmel/atmel_ssc_dai.c b/ANDROID_3.4.5/sound/soc/atmel/atmel_ssc_dai.c
deleted file mode 100644
index 354341ec..00000000
--- a/ANDROID_3.4.5/sound/soc/atmel/atmel_ssc_dai.c
+++ /dev/null
@@ -1,867 +0,0 @@
-/*
- * atmel_ssc_dai.c -- ALSA SoC ATMEL SSC Audio Layer Platform driver
- *
- * Copyright (C) 2005 SAN People
- * Copyright (C) 2008 Atmel
- *
- * Author: Sedji Gaouaou <sedji.gaouaou@atmel.com>
- * ATMEL CORP.
- *
- * Based on at91-ssc.c by
- * Frank Mandarino <fmandarino@endrelia.com>
- * Based on pxa2xx Platform drivers by
- * Liam Girdwood <lrg@slimlogic.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/atmel_pdc.h>
-
-#include <linux/atmel-ssc.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include <mach/hardware.h>
-
-#include "atmel-pcm.h"
-#include "atmel_ssc_dai.h"
-
-
-#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
-#define NUM_SSC_DEVICES 1
-#else
-#define NUM_SSC_DEVICES 3
-#endif
-
-/*
- * SSC PDC registers required by the PCM DMA engine.
- */
-static struct atmel_pdc_regs pdc_tx_reg = {
- .xpr = ATMEL_PDC_TPR,
- .xcr = ATMEL_PDC_TCR,
- .xnpr = ATMEL_PDC_TNPR,
- .xncr = ATMEL_PDC_TNCR,
-};
-
-static struct atmel_pdc_regs pdc_rx_reg = {
- .xpr = ATMEL_PDC_RPR,
- .xcr = ATMEL_PDC_RCR,
- .xnpr = ATMEL_PDC_RNPR,
- .xncr = ATMEL_PDC_RNCR,
-};
-
-/*
- * SSC & PDC status bits for transmit and receive.
- */
-static struct atmel_ssc_mask ssc_tx_mask = {
- .ssc_enable = SSC_BIT(CR_TXEN),
- .ssc_disable = SSC_BIT(CR_TXDIS),
- .ssc_endx = SSC_BIT(SR_ENDTX),
- .ssc_endbuf = SSC_BIT(SR_TXBUFE),
- .pdc_enable = ATMEL_PDC_TXTEN,
- .pdc_disable = ATMEL_PDC_TXTDIS,
-};
-
-static struct atmel_ssc_mask ssc_rx_mask = {
- .ssc_enable = SSC_BIT(CR_RXEN),
- .ssc_disable = SSC_BIT(CR_RXDIS),
- .ssc_endx = SSC_BIT(SR_ENDRX),
- .ssc_endbuf = SSC_BIT(SR_RXBUFF),
- .pdc_enable = ATMEL_PDC_RXTEN,
- .pdc_disable = ATMEL_PDC_RXTDIS,
-};
-
-
-/*
- * DMA parameters.
- */
-static struct atmel_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
- {{
- .name = "SSC0 PCM out",
- .pdc = &pdc_tx_reg,
- .mask = &ssc_tx_mask,
- },
- {
- .name = "SSC0 PCM in",
- .pdc = &pdc_rx_reg,
- .mask = &ssc_rx_mask,
- } },
-#if NUM_SSC_DEVICES == 3
- {{
- .name = "SSC1 PCM out",
- .pdc = &pdc_tx_reg,
- .mask = &ssc_tx_mask,
- },
- {
- .name = "SSC1 PCM in",
- .pdc = &pdc_rx_reg,
- .mask = &ssc_rx_mask,
- } },
- {{
- .name = "SSC2 PCM out",
- .pdc = &pdc_tx_reg,
- .mask = &ssc_tx_mask,
- },
- {
- .name = "SSC2 PCM in",
- .pdc = &pdc_rx_reg,
- .mask = &ssc_rx_mask,
- } },
-#endif
-};
-
-
-static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = {
- {
- .name = "ssc0",
- .lock = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock),
- .dir_mask = SSC_DIR_MASK_UNUSED,
- .initialized = 0,
- },
-#if NUM_SSC_DEVICES == 3
- {
- .name = "ssc1",
- .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
- .dir_mask = SSC_DIR_MASK_UNUSED,
- .initialized = 0,
- },
- {
- .name = "ssc2",
- .lock = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock),
- .dir_mask = SSC_DIR_MASK_UNUSED,
- .initialized = 0,
- },
-#endif
-};
-
-
-/*
- * SSC interrupt handler. Passes PDC interrupts to the DMA
- * interrupt handler in the PCM driver.
- */
-static irqreturn_t atmel_ssc_interrupt(int irq, void *dev_id)
-{
- struct atmel_ssc_info *ssc_p = dev_id;
- struct atmel_pcm_dma_params *dma_params;
- u32 ssc_sr;
- u32 ssc_substream_mask;
- int i;
-
- ssc_sr = (unsigned long)ssc_readl(ssc_p->ssc->regs, SR)
- & (unsigned long)ssc_readl(ssc_p->ssc->regs, IMR);
-
- /*
- * Loop through the substreams attached to this SSC. If
- * a DMA-related interrupt occurred on that substream, call
- * the DMA interrupt handler function, if one has been
- * registered in the dma_params structure by the PCM driver.
- */
- for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) {
- dma_params = ssc_p->dma_params[i];
-
- if ((dma_params != NULL) &&
- (dma_params->dma_intr_handler != NULL)) {
- ssc_substream_mask = (dma_params->mask->ssc_endx |
- dma_params->mask->ssc_endbuf);
- if (ssc_sr & ssc_substream_mask) {
- dma_params->dma_intr_handler(ssc_sr,
- dma_params->
- substream);
- }
- }
- }
-
- return IRQ_HANDLED;
-}
-
-
-/*-------------------------------------------------------------------------*\
- * DAI functions
-\*-------------------------------------------------------------------------*/
-/*
- * Startup. Only that one substream allowed in each direction.
- */
-static int atmel_ssc_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
- int dir_mask;
-
- pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n",
- ssc_readl(ssc_p->ssc->regs, SR));
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dir_mask = SSC_DIR_MASK_PLAYBACK;
- else
- dir_mask = SSC_DIR_MASK_CAPTURE;
-
- spin_lock_irq(&ssc_p->lock);
- if (ssc_p->dir_mask & dir_mask) {
- spin_unlock_irq(&ssc_p->lock);
- return -EBUSY;
- }
- ssc_p->dir_mask |= dir_mask;
- spin_unlock_irq(&ssc_p->lock);
-
- return 0;
-}
-
-/*
- * Shutdown. Clear DMA parameters and shutdown the SSC if there
- * are no other substreams open.
- */
-static void atmel_ssc_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
- struct atmel_pcm_dma_params *dma_params;
- int dir, dir_mask;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dir = 0;
- else
- dir = 1;
-
- dma_params = ssc_p->dma_params[dir];
-
- if (dma_params != NULL) {
- ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable);
- pr_debug("atmel_ssc_shutdown: %s disabled SSC_SR=0x%08x\n",
- (dir ? "receive" : "transmit"),
- ssc_readl(ssc_p->ssc->regs, SR));
-
- dma_params->ssc = NULL;
- dma_params->substream = NULL;
- ssc_p->dma_params[dir] = NULL;
- }
-
- dir_mask = 1 << dir;
-
- spin_lock_irq(&ssc_p->lock);
- ssc_p->dir_mask &= ~dir_mask;
- if (!ssc_p->dir_mask) {
- if (ssc_p->initialized) {
- /* Shutdown the SSC clock. */
- pr_debug("atmel_ssc_dau: Stopping clock\n");
- clk_disable(ssc_p->ssc->clk);
-
- free_irq(ssc_p->ssc->irq, ssc_p);
- ssc_p->initialized = 0;
- }
-
- /* Reset the SSC */
- ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
- /* Clear the SSC dividers */
- ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0;
- }
- spin_unlock_irq(&ssc_p->lock);
-}
-
-
-/*
- * Record the DAI format for use in hw_params().
- */
-static int atmel_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,
- unsigned int fmt)
-{
- struct atmel_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
-
- ssc_p->daifmt = fmt;
- return 0;
-}
-
-/*
- * Record SSC clock dividers for use in hw_params().
- */
-static int atmel_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
- int div_id, int div)
-{
- struct atmel_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
-
- switch (div_id) {
- case ATMEL_SSC_CMR_DIV:
- /*
- * The same master clock divider is used for both
- * transmit and receive, so if a value has already
- * been set, it must match this value.
- */
- if (ssc_p->cmr_div == 0)
- ssc_p->cmr_div = div;
- else
- if (div != ssc_p->cmr_div)
- return -EBUSY;
- break;
-
- case ATMEL_SSC_TCMR_PERIOD:
- ssc_p->tcmr_period = div;
- break;
-
- case ATMEL_SSC_RCMR_PERIOD:
- ssc_p->rcmr_period = div;
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * Configure the SSC.
- */
-static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
- int id = dai->id;
- struct atmel_ssc_info *ssc_p = &ssc_info[id];
- struct atmel_pcm_dma_params *dma_params;
- int dir, channels, bits;
- u32 tfmr, rfmr, tcmr, rcmr;
- int start_event;
- int ret;
-
- /*
- * Currently, there is only one set of dma params for
- * each direction. If more are added, this code will
- * have to be changed to select the proper set.
- */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dir = 0;
- else
- dir = 1;
-
- dma_params = &ssc_dma_params[id][dir];
- dma_params->ssc = ssc_p->ssc;
- dma_params->substream = substream;
-
- ssc_p->dma_params[dir] = dma_params;
-
- /*
- * The snd_soc_pcm_stream->dma_data field is only used to communicate
- * the appropriate DMA parameters to the pcm driver hw_params()
- * function. It should not be used for other purposes
- * as it is common to all substreams.
- */
- snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_params);
-
- channels = params_channels(params);
-
- /*
- * Determine sample size in bits and the PDC increment.
- */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S8:
- bits = 8;
- dma_params->pdc_xfer_size = 1;
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- bits = 16;
- dma_params->pdc_xfer_size = 2;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- bits = 24;
- dma_params->pdc_xfer_size = 4;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- bits = 32;
- dma_params->pdc_xfer_size = 4;
- break;
- default:
- printk(KERN_WARNING "atmel_ssc_dai: unsupported PCM format");
- return -EINVAL;
- }
-
- /*
- * The SSC only supports up to 16-bit samples in I2S format, due
- * to the size of the Frame Mode Register FSLEN field.
- */
- if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S
- && bits > 16) {
- printk(KERN_WARNING
- "atmel_ssc_dai: sample size %d "
- "is too large for I2S\n", bits);
- return -EINVAL;
- }
-
- /*
- * Compute SSC register settings.
- */
- switch (ssc_p->daifmt
- & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) {
-
- case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
- /*
- * I2S format, SSC provides BCLK and LRC clocks.
- *
- * The SSC transmit and receive clocks are generated
- * from the MCK divider, and the BCLK signal
- * is output on the SSC TK line.
- */
- rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period)
- | SSC_BF(RCMR_STTDLY, START_DELAY)
- | SSC_BF(RCMR_START, SSC_START_FALLING_RF)
- | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
- | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
- | SSC_BF(RCMR_CKS, SSC_CKS_DIV);
-
- rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
- | SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE)
- | SSC_BF(RFMR_FSLEN, (bits - 1))
- | SSC_BF(RFMR_DATNB, (channels - 1))
- | SSC_BIT(RFMR_MSBF)
- | SSC_BF(RFMR_LOOP, 0)
- | SSC_BF(RFMR_DATLEN, (bits - 1));
-
- tcmr = SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period)
- | SSC_BF(TCMR_STTDLY, START_DELAY)
- | SSC_BF(TCMR_START, SSC_START_FALLING_RF)
- | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
- | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS)
- | SSC_BF(TCMR_CKS, SSC_CKS_DIV);
-
- tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
- | SSC_BF(TFMR_FSDEN, 0)
- | SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE)
- | SSC_BF(TFMR_FSLEN, (bits - 1))
- | SSC_BF(TFMR_DATNB, (channels - 1))
- | SSC_BIT(TFMR_MSBF)
- | SSC_BF(TFMR_DATDEF, 0)
- | SSC_BF(TFMR_DATLEN, (bits - 1));
- break;
-
- case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
- /*
- * I2S format, CODEC supplies BCLK and LRC clocks.
- *
- * The SSC transmit clock is obtained from the BCLK signal on
- * on the TK line, and the SSC receive clock is
- * generated from the transmit clock.
- *
- * For single channel data, one sample is transferred
- * on the falling edge of the LRC clock.
- * For two channel data, one sample is
- * transferred on both edges of the LRC clock.
- */
- start_event = ((channels == 1)
- ? SSC_START_FALLING_RF
- : SSC_START_EDGE_RF);
-
- rcmr = SSC_BF(RCMR_PERIOD, 0)
- | SSC_BF(RCMR_STTDLY, START_DELAY)
- | SSC_BF(RCMR_START, start_event)
- | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
- | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
- | SSC_BF(RCMR_CKS, SSC_CKS_CLOCK);
-
- rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
- | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
- | SSC_BF(RFMR_FSLEN, 0)
- | SSC_BF(RFMR_DATNB, 0)
- | SSC_BIT(RFMR_MSBF)
- | SSC_BF(RFMR_LOOP, 0)
- | SSC_BF(RFMR_DATLEN, (bits - 1));
-
- tcmr = SSC_BF(TCMR_PERIOD, 0)
- | SSC_BF(TCMR_STTDLY, START_DELAY)
- | SSC_BF(TCMR_START, start_event)
- | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
- | SSC_BF(TCMR_CKO, SSC_CKO_NONE)
- | SSC_BF(TCMR_CKS, SSC_CKS_PIN);
-
- tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
- | SSC_BF(TFMR_FSDEN, 0)
- | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE)
- | SSC_BF(TFMR_FSLEN, 0)
- | SSC_BF(TFMR_DATNB, 0)
- | SSC_BIT(TFMR_MSBF)
- | SSC_BF(TFMR_DATDEF, 0)
- | SSC_BF(TFMR_DATLEN, (bits - 1));
- break;
-
- case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
- /*
- * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks.
- *
- * The SSC transmit and receive clocks are generated from the
- * MCK divider, and the BCLK signal is output
- * on the SSC TK line.
- */
- rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period)
- | SSC_BF(RCMR_STTDLY, 1)
- | SSC_BF(RCMR_START, SSC_START_RISING_RF)
- | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
- | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
- | SSC_BF(RCMR_CKS, SSC_CKS_DIV);
-
- rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
- | SSC_BF(RFMR_FSOS, SSC_FSOS_POSITIVE)
- | SSC_BF(RFMR_FSLEN, 0)
- | SSC_BF(RFMR_DATNB, (channels - 1))
- | SSC_BIT(RFMR_MSBF)
- | SSC_BF(RFMR_LOOP, 0)
- | SSC_BF(RFMR_DATLEN, (bits - 1));
-
- tcmr = SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period)
- | SSC_BF(TCMR_STTDLY, 1)
- | SSC_BF(TCMR_START, SSC_START_RISING_RF)
- | SSC_BF(TCMR_CKI, SSC_CKI_RISING)
- | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS)
- | SSC_BF(TCMR_CKS, SSC_CKS_DIV);
-
- tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
- | SSC_BF(TFMR_FSDEN, 0)
- | SSC_BF(TFMR_FSOS, SSC_FSOS_POSITIVE)
- | SSC_BF(TFMR_FSLEN, 0)
- | SSC_BF(TFMR_DATNB, (channels - 1))
- | SSC_BIT(TFMR_MSBF)
- | SSC_BF(TFMR_DATDEF, 0)
- | SSC_BF(TFMR_DATLEN, (bits - 1));
- break;
-
- case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
- default:
- printk(KERN_WARNING "atmel_ssc_dai: unsupported DAI format 0x%x\n",
- ssc_p->daifmt);
- return -EINVAL;
- }
- pr_debug("atmel_ssc_hw_params: "
- "RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n",
- rcmr, rfmr, tcmr, tfmr);
-
- if (!ssc_p->initialized) {
-
- /* Enable PMC peripheral clock for this SSC */
- pr_debug("atmel_ssc_dai: Starting clock\n");
- clk_enable(ssc_p->ssc->clk);
-
- /* Reset the SSC and its PDC registers */
- ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
-
- ssc_writel(ssc_p->ssc->regs, PDC_RPR, 0);
- ssc_writel(ssc_p->ssc->regs, PDC_RCR, 0);
- ssc_writel(ssc_p->ssc->regs, PDC_RNPR, 0);
- ssc_writel(ssc_p->ssc->regs, PDC_RNCR, 0);
-
- ssc_writel(ssc_p->ssc->regs, PDC_TPR, 0);
- ssc_writel(ssc_p->ssc->regs, PDC_TCR, 0);
- ssc_writel(ssc_p->ssc->regs, PDC_TNPR, 0);
- ssc_writel(ssc_p->ssc->regs, PDC_TNCR, 0);
-
- ret = request_irq(ssc_p->ssc->irq, atmel_ssc_interrupt, 0,
- ssc_p->name, ssc_p);
- if (ret < 0) {
- printk(KERN_WARNING
- "atmel_ssc_dai: request_irq failure\n");
- pr_debug("Atmel_ssc_dai: Stoping clock\n");
- clk_disable(ssc_p->ssc->clk);
- return ret;
- }
-
- ssc_p->initialized = 1;
- }
-
- /* set SSC clock mode register */
- ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->cmr_div);
-
- /* set receive clock mode and format */
- ssc_writel(ssc_p->ssc->regs, RCMR, rcmr);
- ssc_writel(ssc_p->ssc->regs, RFMR, rfmr);
-
- /* set transmit clock mode and format */
- ssc_writel(ssc_p->ssc->regs, TCMR, tcmr);
- ssc_writel(ssc_p->ssc->regs, TFMR, tfmr);
-
- pr_debug("atmel_ssc_dai,hw_params: SSC initialized\n");
- return 0;
-}
-
-
-static int atmel_ssc_prepare(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
- struct atmel_pcm_dma_params *dma_params;
- int dir;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dir = 0;
- else
- dir = 1;
-
- dma_params = ssc_p->dma_params[dir];
-
- ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_enable);
-
- pr_debug("%s enabled SSC_SR=0x%08x\n",
- dir ? "receive" : "transmit",
- ssc_readl(ssc_p->ssc->regs, SR));
- return 0;
-}
-
-
-#ifdef CONFIG_PM
-static int atmel_ssc_suspend(struct snd_soc_dai *cpu_dai)
-{
- struct atmel_ssc_info *ssc_p;
-
- if (!cpu_dai->active)
- return 0;
-
- ssc_p = &ssc_info[cpu_dai->id];
-
- /* Save the status register before disabling transmit and receive */
- ssc_p->ssc_state.ssc_sr = ssc_readl(ssc_p->ssc->regs, SR);
- ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_TXDIS) | SSC_BIT(CR_RXDIS));
-
- /* Save the current interrupt mask, then disable unmasked interrupts */
- ssc_p->ssc_state.ssc_imr = ssc_readl(ssc_p->ssc->regs, IMR);
- ssc_writel(ssc_p->ssc->regs, IDR, ssc_p->ssc_state.ssc_imr);
-
- ssc_p->ssc_state.ssc_cmr = ssc_readl(ssc_p->ssc->regs, CMR);
- ssc_p->ssc_state.ssc_rcmr = ssc_readl(ssc_p->ssc->regs, RCMR);
- ssc_p->ssc_state.ssc_rfmr = ssc_readl(ssc_p->ssc->regs, RFMR);
- ssc_p->ssc_state.ssc_tcmr = ssc_readl(ssc_p->ssc->regs, TCMR);
- ssc_p->ssc_state.ssc_tfmr = ssc_readl(ssc_p->ssc->regs, TFMR);
-
- return 0;
-}
-
-
-
-static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai)
-{
- struct atmel_ssc_info *ssc_p;
- u32 cr;
-
- if (!cpu_dai->active)
- return 0;
-
- ssc_p = &ssc_info[cpu_dai->id];
-
- /* restore SSC register settings */
- ssc_writel(ssc_p->ssc->regs, TFMR, ssc_p->ssc_state.ssc_tfmr);
- ssc_writel(ssc_p->ssc->regs, TCMR, ssc_p->ssc_state.ssc_tcmr);
- ssc_writel(ssc_p->ssc->regs, RFMR, ssc_p->ssc_state.ssc_rfmr);
- ssc_writel(ssc_p->ssc->regs, RCMR, ssc_p->ssc_state.ssc_rcmr);
- ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->ssc_state.ssc_cmr);
-
- /* re-enable interrupts */
- ssc_writel(ssc_p->ssc->regs, IER, ssc_p->ssc_state.ssc_imr);
-
- /* Re-enable receive and transmit as appropriate */
- cr = 0;
- cr |=
- (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_RXEN)) ? SSC_BIT(CR_RXEN) : 0;
- cr |=
- (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_TXEN)) ? SSC_BIT(CR_TXEN) : 0;
- ssc_writel(ssc_p->ssc->regs, CR, cr);
-
- return 0;
-}
-#else /* CONFIG_PM */
-# define atmel_ssc_suspend NULL
-# define atmel_ssc_resume NULL
-#endif /* CONFIG_PM */
-
-static int atmel_ssc_probe(struct snd_soc_dai *dai)
-{
- struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
- int ret = 0;
-
- snd_soc_dai_set_drvdata(dai, ssc_p);
-
- /*
- * Request SSC device
- */
- ssc_p->ssc = ssc_request(dai->id);
- if (IS_ERR(ssc_p->ssc)) {
- printk(KERN_ERR "ASoC: Failed to request SSC %d\n", dai->id);
- ret = PTR_ERR(ssc_p->ssc);
- }
-
- return ret;
-}
-
-static int atmel_ssc_remove(struct snd_soc_dai *dai)
-{
- struct atmel_ssc_info *ssc_p = snd_soc_dai_get_drvdata(dai);
-
- ssc_free(ssc_p->ssc);
- return 0;
-}
-
-#define ATMEL_SSC_RATES (SNDRV_PCM_RATE_8000_96000)
-
-#define ATMEL_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops atmel_ssc_dai_ops = {
- .startup = atmel_ssc_startup,
- .shutdown = atmel_ssc_shutdown,
- .prepare = atmel_ssc_prepare,
- .hw_params = atmel_ssc_hw_params,
- .set_fmt = atmel_ssc_set_dai_fmt,
- .set_clkdiv = atmel_ssc_set_dai_clkdiv,
-};
-
-static struct snd_soc_dai_driver atmel_ssc_dai[NUM_SSC_DEVICES] = {
- {
- .name = "atmel-ssc-dai.0",
- .probe = atmel_ssc_probe,
- .remove = atmel_ssc_remove,
- .suspend = atmel_ssc_suspend,
- .resume = atmel_ssc_resume,
- .playback = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = ATMEL_SSC_RATES,
- .formats = ATMEL_SSC_FORMATS,},
- .capture = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = ATMEL_SSC_RATES,
- .formats = ATMEL_SSC_FORMATS,},
- .ops = &atmel_ssc_dai_ops,
- },
-#if NUM_SSC_DEVICES == 3
- {
- .name = "atmel-ssc-dai.1",
- .probe = atmel_ssc_probe,
- .remove = atmel_ssc_remove,
- .suspend = atmel_ssc_suspend,
- .resume = atmel_ssc_resume,
- .playback = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = ATMEL_SSC_RATES,
- .formats = ATMEL_SSC_FORMATS,},
- .capture = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = ATMEL_SSC_RATES,
- .formats = ATMEL_SSC_FORMATS,},
- .ops = &atmel_ssc_dai_ops,
- },
- {
- .name = "atmel-ssc-dai.2",
- .probe = atmel_ssc_probe,
- .remove = atmel_ssc_remove,
- .suspend = atmel_ssc_suspend,
- .resume = atmel_ssc_resume,
- .playback = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = ATMEL_SSC_RATES,
- .formats = ATMEL_SSC_FORMATS,},
- .capture = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = ATMEL_SSC_RATES,
- .formats = ATMEL_SSC_FORMATS,},
- .ops = &atmel_ssc_dai_ops,
- },
-#endif
-};
-
-static __devinit int asoc_ssc_probe(struct platform_device *pdev)
-{
- BUG_ON(pdev->id < 0);
- BUG_ON(pdev->id >= ARRAY_SIZE(atmel_ssc_dai));
- return snd_soc_register_dai(&pdev->dev, &atmel_ssc_dai[pdev->id]);
-}
-
-static int __devexit asoc_ssc_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_dai(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver asoc_ssc_driver = {
- .driver = {
- .name = "atmel-ssc-dai",
- .owner = THIS_MODULE,
- },
-
- .probe = asoc_ssc_probe,
- .remove = __devexit_p(asoc_ssc_remove),
-};
-
-/**
- * atmel_ssc_set_audio - Allocate the specified SSC for audio use.
- */
-int atmel_ssc_set_audio(int ssc_id)
-{
- struct ssc_device *ssc;
- static struct platform_device *dma_pdev;
- struct platform_device *ssc_pdev;
- int ret;
-
- if (ssc_id < 0 || ssc_id >= ARRAY_SIZE(atmel_ssc_dai))
- return -EINVAL;
-
- /* Allocate a dummy device for DMA if we don't have one already */
- if (!dma_pdev) {
- dma_pdev = platform_device_alloc("atmel-pcm-audio", -1);
- if (!dma_pdev)
- return -ENOMEM;
-
- ret = platform_device_add(dma_pdev);
- if (ret < 0) {
- platform_device_put(dma_pdev);
- dma_pdev = NULL;
- return ret;
- }
- }
-
- ssc_pdev = platform_device_alloc("atmel-ssc-dai", ssc_id);
- if (!ssc_pdev)
- return -ENOMEM;
-
- /* If we can grab the SSC briefly to parent the DAI device off it */
- ssc = ssc_request(ssc_id);
- if (IS_ERR(ssc))
- pr_warn("Unable to parent ASoC SSC DAI on SSC: %ld\n",
- PTR_ERR(ssc));
- else {
- ssc_pdev->dev.parent = &(ssc->pdev->dev);
- ssc_free(ssc);
- }
-
- ret = platform_device_add(ssc_pdev);
- if (ret < 0)
- platform_device_put(ssc_pdev);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(atmel_ssc_set_audio);
-
-module_platform_driver(asoc_ssc_driver);
-
-/* Module information */
-MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com");
-MODULE_DESCRIPTION("ATMEL SSC ASoC Interface");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/atmel/atmel_ssc_dai.h b/ANDROID_3.4.5/sound/soc/atmel/atmel_ssc_dai.h
deleted file mode 100644
index 5d4f0f9b..00000000
--- a/ANDROID_3.4.5/sound/soc/atmel/atmel_ssc_dai.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * atmel_ssc_dai.h - ALSA SSC interface for the Atmel SoC
- *
- * Copyright (C) 2005 SAN People
- * Copyright (C) 2008 Atmel
- *
- * Author: Sedji Gaouaou <sedji.gaouaou@atmel.com>
- * ATMEL CORP.
- *
- * Based on at91-ssc.c by
- * Frank Mandarino <fmandarino@endrelia.com>
- * Based on pxa2xx Platform drivers by
- * Liam Girdwood <lrg@slimlogic.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _ATMEL_SSC_DAI_H
-#define _ATMEL_SSC_DAI_H
-
-#include <linux/types.h>
-#include <linux/atmel-ssc.h>
-
-#include "atmel-pcm.h"
-
-/* SSC system clock ids */
-#define ATMEL_SYSCLK_MCK 0 /* SSC uses AT91 MCK as system clock */
-
-/* SSC divider ids */
-#define ATMEL_SSC_CMR_DIV 0 /* MCK divider for BCLK */
-#define ATMEL_SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */
-#define ATMEL_SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */
-/*
- * SSC direction masks
- */
-#define SSC_DIR_MASK_UNUSED 0
-#define SSC_DIR_MASK_PLAYBACK 1
-#define SSC_DIR_MASK_CAPTURE 2
-
-/*
- * SSC register values that Atmel left out of <linux/atmel-ssc.h>. These
- * are expected to be used with SSC_BF
- */
-/* START bit field values */
-#define SSC_START_CONTINUOUS 0
-#define SSC_START_TX_RX 1
-#define SSC_START_LOW_RF 2
-#define SSC_START_HIGH_RF 3
-#define SSC_START_FALLING_RF 4
-#define SSC_START_RISING_RF 5
-#define SSC_START_LEVEL_RF 6
-#define SSC_START_EDGE_RF 7
-#define SSS_START_COMPARE_0 8
-
-/* CKI bit field values */
-#define SSC_CKI_FALLING 0
-#define SSC_CKI_RISING 1
-
-/* CKO bit field values */
-#define SSC_CKO_NONE 0
-#define SSC_CKO_CONTINUOUS 1
-#define SSC_CKO_TRANSFER 2
-
-/* CKS bit field values */
-#define SSC_CKS_DIV 0
-#define SSC_CKS_CLOCK 1
-#define SSC_CKS_PIN 2
-
-/* FSEDGE bit field values */
-#define SSC_FSEDGE_POSITIVE 0
-#define SSC_FSEDGE_NEGATIVE 1
-
-/* FSOS bit field values */
-#define SSC_FSOS_NONE 0
-#define SSC_FSOS_NEGATIVE 1
-#define SSC_FSOS_POSITIVE 2
-#define SSC_FSOS_LOW 3
-#define SSC_FSOS_HIGH 4
-#define SSC_FSOS_TOGGLE 5
-
-#define START_DELAY 1
-
-struct atmel_ssc_state {
- u32 ssc_cmr;
- u32 ssc_rcmr;
- u32 ssc_rfmr;
- u32 ssc_tcmr;
- u32 ssc_tfmr;
- u32 ssc_sr;
- u32 ssc_imr;
-};
-
-
-struct atmel_ssc_info {
- char *name;
- struct ssc_device *ssc;
- spinlock_t lock; /* lock for dir_mask */
- unsigned short dir_mask; /* 0=unused, 1=playback, 2=capture */
- unsigned short initialized; /* true if SSC has been initialized */
- unsigned short daifmt;
- unsigned short cmr_div;
- unsigned short tcmr_period;
- unsigned short rcmr_period;
- struct atmel_pcm_dma_params *dma_params[2];
- struct atmel_ssc_state ssc_state;
-};
-
-int atmel_ssc_set_audio(int ssc);
-
-#endif /* _AT91_SSC_DAI_H */
diff --git a/ANDROID_3.4.5/sound/soc/atmel/sam9g20_wm8731.c b/ANDROID_3.4.5/sound/soc/atmel/sam9g20_wm8731.c
deleted file mode 100644
index c8835148..00000000
--- a/ANDROID_3.4.5/sound/soc/atmel/sam9g20_wm8731.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * sam9g20_wm8731 -- SoC audio for AT91SAM9G20-based
- * ATMEL AT91SAM9G20ek board.
- *
- * Copyright (C) 2005 SAN People
- * Copyright (C) 2008 Atmel
- *
- * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com>
- *
- * Based on ati_b1_wm8731.c by:
- * Frank Mandarino <fmandarino@endrelia.com>
- * Copyright 2006 Endrelia Technologies Inc.
- * Based on corgi.c by:
- * Copyright 2005 Wolfson Microelectronics PLC.
- * Copyright 2005 Openedhand Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/clk.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-
-#include <linux/atmel-ssc.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-
-#include "../codecs/wm8731.h"
-#include "atmel-pcm.h"
-#include "atmel_ssc_dai.h"
-
-#define MCLK_RATE 12000000
-
-/*
- * As shipped the board does not have inputs. However, it is relatively
- * straightforward to modify the board to hook them up so support is left
- * in the driver.
- */
-#undef ENABLE_MIC_INPUT
-
-static struct clk *mclk;
-
-static int at91sam9g20ek_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret;
-
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- /* set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops at91sam9g20ek_ops = {
- .hw_params = at91sam9g20ek_hw_params,
-};
-
-static int at91sam9g20ek_set_bias_level(struct snd_soc_card *card,
- struct snd_soc_dapm_context *dapm,
- enum snd_soc_bias_level level)
-{
- static int mclk_on;
- int ret = 0;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- case SND_SOC_BIAS_PREPARE:
- if (!mclk_on)
- ret = clk_enable(mclk);
- if (ret == 0)
- mclk_on = 1;
- break;
-
- case SND_SOC_BIAS_OFF:
- case SND_SOC_BIAS_STANDBY:
- if (mclk_on)
- clk_disable(mclk);
- mclk_on = 0;
- break;
- }
-
- return ret;
-}
-
-static const struct snd_soc_dapm_widget at91sam9g20ek_dapm_widgets[] = {
- SND_SOC_DAPM_MIC("Int Mic", NULL),
- SND_SOC_DAPM_SPK("Ext Spk", NULL),
-};
-
-static const struct snd_soc_dapm_route intercon[] = {
-
- /* speaker connected to LHPOUT */
- {"Ext Spk", NULL, "LHPOUT"},
-
- /* mic is connected to Mic Jack, with WM8731 Mic Bias */
- {"MICIN", NULL, "Mic Bias"},
- {"Mic Bias", NULL, "Int Mic"},
-};
-
-/*
- * Logic for a wm8731 as connected on a at91sam9g20ek board.
- */
-static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret;
-
- printk(KERN_DEBUG
- "at91sam9g20ek_wm8731 "
- ": at91sam9g20ek_wm8731_init() called\n");
-
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_MCLK,
- MCLK_RATE, SND_SOC_CLOCK_IN);
- if (ret < 0) {
- printk(KERN_ERR "Failed to set WM8731 SYSCLK: %d\n", ret);
- return ret;
- }
-
- /* Add specific widgets */
- snd_soc_dapm_new_controls(dapm, at91sam9g20ek_dapm_widgets,
- ARRAY_SIZE(at91sam9g20ek_dapm_widgets));
- /* Set up specific audio path interconnects */
- snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
-
- /* not connected */
- snd_soc_dapm_nc_pin(dapm, "RLINEIN");
- snd_soc_dapm_nc_pin(dapm, "LLINEIN");
-
-#ifdef ENABLE_MIC_INPUT
- snd_soc_dapm_enable_pin(dapm, "Int Mic");
-#else
- snd_soc_dapm_nc_pin(dapm, "Int Mic");
-#endif
-
- /* always connected */
- snd_soc_dapm_enable_pin(dapm, "Ext Spk");
-
- return 0;
-}
-
-static struct snd_soc_dai_link at91sam9g20ek_dai = {
- .name = "WM8731",
- .stream_name = "WM8731 PCM",
- .cpu_dai_name = "atmel-ssc-dai.0",
- .codec_dai_name = "wm8731-hifi",
- .init = at91sam9g20ek_wm8731_init,
- .platform_name = "atmel-pcm-audio",
- .codec_name = "wm8731.0-001b",
- .ops = &at91sam9g20ek_ops,
-};
-
-static struct snd_soc_card snd_soc_at91sam9g20ek = {
- .name = "AT91SAMG20-EK",
- .owner = THIS_MODULE,
- .dai_link = &at91sam9g20ek_dai,
- .num_links = 1,
- .set_bias_level = at91sam9g20ek_set_bias_level,
-};
-
-static struct platform_device *at91sam9g20ek_snd_device;
-
-static int __init at91sam9g20ek_init(void)
-{
- struct clk *pllb;
- int ret;
-
- if (!(machine_is_at91sam9g20ek() || machine_is_at91sam9g20ek_2mmc()))
- return -ENODEV;
-
- ret = atmel_ssc_set_audio(0);
- if (ret != 0) {
- pr_err("Failed to set SSC 0 for audio: %d\n", ret);
- return ret;
- }
-
- /*
- * Codec MCLK is supplied by PCK0 - set it up.
- */
- mclk = clk_get(NULL, "pck0");
- if (IS_ERR(mclk)) {
- printk(KERN_ERR "ASoC: Failed to get MCLK\n");
- ret = PTR_ERR(mclk);
- goto err;
- }
-
- pllb = clk_get(NULL, "pllb");
- if (IS_ERR(pllb)) {
- printk(KERN_ERR "ASoC: Failed to get PLLB\n");
- ret = PTR_ERR(pllb);
- goto err_mclk;
- }
- ret = clk_set_parent(mclk, pllb);
- clk_put(pllb);
- if (ret != 0) {
- printk(KERN_ERR "ASoC: Failed to set MCLK parent\n");
- goto err_mclk;
- }
-
- clk_set_rate(mclk, MCLK_RATE);
-
- at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1);
- if (!at91sam9g20ek_snd_device) {
- printk(KERN_ERR "ASoC: Platform device allocation failed\n");
- ret = -ENOMEM;
- goto err_mclk;
- }
-
- platform_set_drvdata(at91sam9g20ek_snd_device,
- &snd_soc_at91sam9g20ek);
-
- ret = platform_device_add(at91sam9g20ek_snd_device);
- if (ret) {
- printk(KERN_ERR "ASoC: Platform device allocation failed\n");
- goto err_device_add;
- }
-
- return ret;
-
-err_device_add:
- platform_device_put(at91sam9g20ek_snd_device);
-err_mclk:
- clk_put(mclk);
- mclk = NULL;
-err:
- return ret;
-}
-
-static void __exit at91sam9g20ek_exit(void)
-{
- platform_device_unregister(at91sam9g20ek_snd_device);
- at91sam9g20ek_snd_device = NULL;
- clk_put(mclk);
- mclk = NULL;
-}
-
-module_init(at91sam9g20ek_init);
-module_exit(at91sam9g20ek_exit);
-
-/* Module information */
-MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
-MODULE_DESCRIPTION("ALSA SoC AT91SAM9G20EK_WM8731");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/atmel/snd-soc-afeb9260.c b/ANDROID_3.4.5/sound/soc/atmel/snd-soc-afeb9260.c
deleted file mode 100644
index f65f08be..00000000
--- a/ANDROID_3.4.5/sound/soc/atmel/snd-soc-afeb9260.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * afeb9260.c -- SoC audio for AFEB9260
- *
- * Copyright (C) 2009 Sergey Lapin <slapin@ossfans.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-
-#include <linux/atmel-ssc.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <linux/gpio.h>
-
-#include "../codecs/tlv320aic23.h"
-#include "atmel-pcm.h"
-#include "atmel_ssc_dai.h"
-
-#define CODEC_CLOCK 12000000
-
-static int afeb9260_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int err;
-
- /* Set the codec system clock for DAC and ADC */
- err =
- snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN);
-
- if (err < 0) {
- printk(KERN_ERR "can't set codec system clock\n");
- return err;
- }
-
- return err;
-}
-
-static struct snd_soc_ops afeb9260_ops = {
- .hw_params = afeb9260_hw_params,
-};
-
-static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_LINE("Line In", NULL),
- SND_SOC_DAPM_MIC("Mic Jack", NULL),
-};
-
-static const struct snd_soc_dapm_route afeb9260_audio_map[] = {
- {"Headphone Jack", NULL, "LHPOUT"},
- {"Headphone Jack", NULL, "RHPOUT"},
-
- {"LLINEIN", NULL, "Line In"},
- {"RLINEIN", NULL, "Line In"},
-
- {"MICIN", NULL, "Mic Jack"},
-};
-
-static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_enable_pin(dapm, "Line In");
- snd_soc_dapm_enable_pin(dapm, "Mic Jack");
-
- return 0;
-}
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link afeb9260_dai = {
- .name = "TLV320AIC23",
- .stream_name = "AIC23",
- .cpu_dai_name = "atmel-ssc-dai.0",
- .codec_dai_name = "tlv320aic23-hifi",
- .platform_name = "atmel_pcm-audio",
- .codec_name = "tlv320aic23-codec.0-001a",
- .init = afeb9260_tlv320aic23_init,
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
- SND_SOC_DAIFMT_CBM_CFM,
- .ops = &afeb9260_ops,
-};
-
-/* Audio machine driver */
-static struct snd_soc_card snd_soc_machine_afeb9260 = {
- .name = "AFEB9260",
- .owner = THIS_MODULE,
- .dai_link = &afeb9260_dai,
- .num_links = 1,
-
- .dapm_widgets = tlv320aic23_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
- .dapm_routes = afeb9260_audio_map,
- .num_dapm_routes = ARRAY_SIZE(afeb9260_audio_map),
-};
-
-static struct platform_device *afeb9260_snd_device;
-
-static int __init afeb9260_soc_init(void)
-{
- int err;
- struct device *dev;
-
- if (!(machine_is_afeb9260()))
- return -ENODEV;
-
-
- afeb9260_snd_device = platform_device_alloc("soc-audio", -1);
- if (!afeb9260_snd_device) {
- printk(KERN_ERR "ASoC: Platform device allocation failed\n");
- return -ENOMEM;
- }
-
- platform_set_drvdata(afeb9260_snd_device, &snd_soc_machine_afeb9260);
- err = platform_device_add(afeb9260_snd_device);
- if (err)
- goto err1;
-
- dev = &afeb9260_snd_device->dev;
-
- return 0;
-err1:
- platform_device_put(afeb9260_snd_device);
- return err;
-}
-
-static void __exit afeb9260_soc_exit(void)
-{
- platform_device_unregister(afeb9260_snd_device);
-}
-
-module_init(afeb9260_soc_init);
-module_exit(afeb9260_soc_exit);
-
-MODULE_AUTHOR("Sergey Lapin <slapin@ossfans.org>");
-MODULE_DESCRIPTION("ALSA SoC for AFEB9260");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/soc/au1x/Kconfig b/ANDROID_3.4.5/sound/soc/au1x/Kconfig
deleted file mode 100644
index a5610404..00000000
--- a/ANDROID_3.4.5/sound/soc/au1x/Kconfig
+++ /dev/null
@@ -1,64 +0,0 @@
-##
-## Au1200/Au1550/Au1300 PSC + DBDMA
-##
-config SND_SOC_AU1XPSC
- tristate "SoC Audio for Au12xx/Au13xx/Au1550"
- depends on MIPS_ALCHEMY
- help
- This option enables support for the Programmable Serial
- Controllers in AC97 and I2S mode, and the Descriptor-Based DMA
- Controller (DBDMA) as found on the Au12xx/Au13xx/Au1550 SoC.
-
-config SND_SOC_AU1XPSC_I2S
- tristate
-
-config SND_SOC_AU1XPSC_AC97
- tristate
- select AC97_BUS
- select SND_AC97_CODEC
- select SND_SOC_AC97_BUS
-
-##
-## Au1000/1500/1100 DMA + AC97C/I2SC
-##
-config SND_SOC_AU1XAUDIO
- tristate "SoC Audio for Au1000/Au1500/Au1100"
- depends on MIPS_ALCHEMY
- help
- This is a driver set for the AC97 unit and the
- old DMA controller as found on the Au1000/Au1500/Au1100 chips.
-
-config SND_SOC_AU1XAC97C
- tristate
- select AC97_BUS
- select SND_AC97_CODEC
- select SND_SOC_AC97_BUS
-
-config SND_SOC_AU1XI2SC
- tristate
-
-
-##
-## Boards
-##
-config SND_SOC_DB1000
- tristate "DB1000 Audio support"
- depends on SND_SOC_AU1XAUDIO
- select SND_SOC_AU1XAC97C
- select SND_SOC_AC97_CODEC
- help
- Select this option to enable AC97 audio on the early DB1x00 series
- of boards (DB1000/DB1500/DB1100).
-
-config SND_SOC_DB1200
- tristate "DB1200/DB1300/DB1550 Audio support"
- depends on SND_SOC_AU1XPSC
- select SND_SOC_AU1XPSC_AC97
- select SND_SOC_AC97_CODEC
- select SND_SOC_WM9712
- select SND_SOC_AU1XPSC_I2S
- select SND_SOC_WM8731
- help
- Select this option to enable audio (AC97 and I2S) on the
- Alchemy/AMD/RMI/NetLogic Db1200, Db1550 and Db1300 evaluation boards.
- If you need Db1300 touchscreen support, you definitely want to say Y.
diff --git a/ANDROID_3.4.5/sound/soc/au1x/Makefile b/ANDROID_3.4.5/sound/soc/au1x/Makefile
deleted file mode 100644
index 92071051..00000000
--- a/ANDROID_3.4.5/sound/soc/au1x/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-# Au1200/Au1550 PSC audio
-snd-soc-au1xpsc-dbdma-objs := dbdma2.o
-snd-soc-au1xpsc-i2s-objs := psc-i2s.o
-snd-soc-au1xpsc-ac97-objs := psc-ac97.o
-
-# Au1000/1500/1100 Audio units
-snd-soc-au1x-dma-objs := dma.o
-snd-soc-au1x-ac97c-objs := ac97c.o
-snd-soc-au1x-i2sc-objs := i2sc.o
-
-obj-$(CONFIG_SND_SOC_AU1XPSC) += snd-soc-au1xpsc-dbdma.o
-obj-$(CONFIG_SND_SOC_AU1XPSC_I2S) += snd-soc-au1xpsc-i2s.o
-obj-$(CONFIG_SND_SOC_AU1XPSC_AC97) += snd-soc-au1xpsc-ac97.o
-obj-$(CONFIG_SND_SOC_AU1XAUDIO) += snd-soc-au1x-dma.o
-obj-$(CONFIG_SND_SOC_AU1XAC97C) += snd-soc-au1x-ac97c.o
-obj-$(CONFIG_SND_SOC_AU1XI2SC) += snd-soc-au1x-i2sc.o
-
-# Boards
-snd-soc-db1000-objs := db1000.o
-snd-soc-db1200-objs := db1200.o
-
-obj-$(CONFIG_SND_SOC_DB1000) += snd-soc-db1000.o
-obj-$(CONFIG_SND_SOC_DB1200) += snd-soc-db1200.o
diff --git a/ANDROID_3.4.5/sound/soc/au1x/ac97c.c b/ANDROID_3.4.5/sound/soc/au1x/ac97c.c
deleted file mode 100644
index c5ac2449..00000000
--- a/ANDROID_3.4.5/sound/soc/au1x/ac97c.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Au1000/Au1500/Au1100 AC97C controller driver for ASoC
- *
- * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
- *
- * based on the old ALSA driver originally written by
- * Charles Eidsness <charles@cooper-street.com>
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/platform_device.h>
-#include <linux/suspend.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-#include <asm/mach-au1x00/au1000.h>
-
-#include "psc.h"
-
-/* register offsets and bits */
-#define AC97_CONFIG 0x00
-#define AC97_STATUS 0x04
-#define AC97_DATA 0x08
-#define AC97_CMDRESP 0x0c
-#define AC97_ENABLE 0x10
-
-#define CFG_RC(x) (((x) & 0x3ff) << 13) /* valid rx slots mask */
-#define CFG_XS(x) (((x) & 0x3ff) << 3) /* valid tx slots mask */
-#define CFG_SG (1 << 2) /* sync gate */
-#define CFG_SN (1 << 1) /* sync control */
-#define CFG_RS (1 << 0) /* acrst# control */
-#define STAT_XU (1 << 11) /* tx underflow */
-#define STAT_XO (1 << 10) /* tx overflow */
-#define STAT_RU (1 << 9) /* rx underflow */
-#define STAT_RO (1 << 8) /* rx overflow */
-#define STAT_RD (1 << 7) /* codec ready */
-#define STAT_CP (1 << 6) /* command pending */
-#define STAT_TE (1 << 4) /* tx fifo empty */
-#define STAT_TF (1 << 3) /* tx fifo full */
-#define STAT_RE (1 << 1) /* rx fifo empty */
-#define STAT_RF (1 << 0) /* rx fifo full */
-#define CMD_SET_DATA(x) (((x) & 0xffff) << 16)
-#define CMD_GET_DATA(x) ((x) & 0xffff)
-#define CMD_READ (1 << 7)
-#define CMD_WRITE (0 << 7)
-#define CMD_IDX(x) ((x) & 0x7f)
-#define EN_D (1 << 1) /* DISable bit */
-#define EN_CE (1 << 0) /* clock enable bit */
-
-/* how often to retry failed codec register reads/writes */
-#define AC97_RW_RETRIES 5
-
-#define AC97_RATES \
- SNDRV_PCM_RATE_CONTINUOUS
-
-#define AC97_FMTS \
- (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE)
-
-/* instance data. There can be only one, MacLeod!!!!, fortunately there IS only
- * once AC97C on early Alchemy chips. The newer ones aren't so lucky.
- */
-static struct au1xpsc_audio_data *ac97c_workdata;
-#define ac97_to_ctx(x) ac97c_workdata
-
-static inline unsigned long RD(struct au1xpsc_audio_data *ctx, int reg)
-{
- return __raw_readl(ctx->mmio + reg);
-}
-
-static inline void WR(struct au1xpsc_audio_data *ctx, int reg, unsigned long v)
-{
- __raw_writel(v, ctx->mmio + reg);
- wmb();
-}
-
-static unsigned short au1xac97c_ac97_read(struct snd_ac97 *ac97,
- unsigned short r)
-{
- struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
- unsigned int tmo, retry;
- unsigned long data;
-
- data = ~0;
- retry = AC97_RW_RETRIES;
- do {
- mutex_lock(&ctx->lock);
-
- tmo = 5;
- while ((RD(ctx, AC97_STATUS) & STAT_CP) && tmo--)
- udelay(21); /* wait an ac97 frame time */
- if (!tmo) {
- pr_debug("ac97rd timeout #1\n");
- goto next;
- }
-
- WR(ctx, AC97_CMDRESP, CMD_IDX(r) | CMD_READ);
-
- /* stupid errata: data is only valid for 21us, so
- * poll, Forrest, poll...
- */
- tmo = 0x10000;
- while ((RD(ctx, AC97_STATUS) & STAT_CP) && tmo--)
- asm volatile ("nop");
- data = RD(ctx, AC97_CMDRESP);
-
- if (!tmo)
- pr_debug("ac97rd timeout #2\n");
-
-next:
- mutex_unlock(&ctx->lock);
- } while (--retry && !tmo);
-
- pr_debug("AC97RD %04x %04lx %d\n", r, data, retry);
-
- return retry ? data & 0xffff : 0xffff;
-}
-
-static void au1xac97c_ac97_write(struct snd_ac97 *ac97, unsigned short r,
- unsigned short v)
-{
- struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
- unsigned int tmo, retry;
-
- retry = AC97_RW_RETRIES;
- do {
- mutex_lock(&ctx->lock);
-
- for (tmo = 5; (RD(ctx, AC97_STATUS) & STAT_CP) && tmo; tmo--)
- udelay(21);
- if (!tmo) {
- pr_debug("ac97wr timeout #1\n");
- goto next;
- }
-
- WR(ctx, AC97_CMDRESP, CMD_WRITE | CMD_IDX(r) | CMD_SET_DATA(v));
-
- for (tmo = 10; (RD(ctx, AC97_STATUS) & STAT_CP) && tmo; tmo--)
- udelay(21);
- if (!tmo)
- pr_debug("ac97wr timeout #2\n");
-next:
- mutex_unlock(&ctx->lock);
- } while (--retry && !tmo);
-
- pr_debug("AC97WR %04x %04x %d\n", r, v, retry);
-}
-
-static void au1xac97c_ac97_warm_reset(struct snd_ac97 *ac97)
-{
- struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
-
- WR(ctx, AC97_CONFIG, ctx->cfg | CFG_SG | CFG_SN);
- msleep(20);
- WR(ctx, AC97_CONFIG, ctx->cfg | CFG_SG);
- WR(ctx, AC97_CONFIG, ctx->cfg);
-}
-
-static void au1xac97c_ac97_cold_reset(struct snd_ac97 *ac97)
-{
- struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
- int i;
-
- WR(ctx, AC97_CONFIG, ctx->cfg | CFG_RS);
- msleep(500);
- WR(ctx, AC97_CONFIG, ctx->cfg);
-
- /* wait for codec ready */
- i = 50;
- while (((RD(ctx, AC97_STATUS) & STAT_RD) == 0) && --i)
- msleep(20);
- if (!i)
- printk(KERN_ERR "ac97c: codec not ready after cold reset\n");
-}
-
-/* AC97 controller operations */
-struct snd_ac97_bus_ops soc_ac97_ops = {
- .read = au1xac97c_ac97_read,
- .write = au1xac97c_ac97_write,
- .reset = au1xac97c_ac97_cold_reset,
- .warm_reset = au1xac97c_ac97_warm_reset,
-};
-EXPORT_SYMBOL_GPL(soc_ac97_ops); /* globals be gone! */
-
-static int alchemy_ac97c_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
- snd_soc_dai_set_dma_data(dai, substream, &ctx->dmaids[0]);
- return 0;
-}
-
-static const struct snd_soc_dai_ops alchemy_ac97c_ops = {
- .startup = alchemy_ac97c_startup,
-};
-
-static int au1xac97c_dai_probe(struct snd_soc_dai *dai)
-{
- return ac97c_workdata ? 0 : -ENODEV;
-}
-
-static struct snd_soc_dai_driver au1xac97c_dai_driver = {
- .name = "alchemy-ac97c",
- .ac97_control = 1,
- .probe = au1xac97c_dai_probe,
- .playback = {
- .rates = AC97_RATES,
- .formats = AC97_FMTS,
- .channels_min = 2,
- .channels_max = 2,
- },
- .capture = {
- .rates = AC97_RATES,
- .formats = AC97_FMTS,
- .channels_min = 2,
- .channels_max = 2,
- },
- .ops = &alchemy_ac97c_ops,
-};
-
-static int __devinit au1xac97c_drvprobe(struct platform_device *pdev)
-{
- int ret;
- struct resource *iores, *dmares;
- struct au1xpsc_audio_data *ctx;
-
- ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
- if (!ctx)
- return -ENOMEM;
-
- mutex_init(&ctx->lock);
-
- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!iores)
- return -ENODEV;
-
- if (!devm_request_mem_region(&pdev->dev, iores->start,
- resource_size(iores),
- pdev->name))
- return -EBUSY;
-
- ctx->mmio = devm_ioremap_nocache(&pdev->dev, iores->start,
- resource_size(iores));
- if (!ctx->mmio)
- return -EBUSY;
-
- dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!dmares)
- return -EBUSY;
- ctx->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start;
-
- dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (!dmares)
- return -EBUSY;
- ctx->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start;
-
- /* switch it on */
- WR(ctx, AC97_ENABLE, EN_D | EN_CE);
- WR(ctx, AC97_ENABLE, EN_CE);
-
- ctx->cfg = CFG_RC(3) | CFG_XS(3);
- WR(ctx, AC97_CONFIG, ctx->cfg);
-
- platform_set_drvdata(pdev, ctx);
-
- ret = snd_soc_register_dai(&pdev->dev, &au1xac97c_dai_driver);
- if (ret)
- return ret;
-
- ac97c_workdata = ctx;
- return 0;
-}
-
-static int __devexit au1xac97c_drvremove(struct platform_device *pdev)
-{
- struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
-
- snd_soc_unregister_dai(&pdev->dev);
-
- WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */
-
- ac97c_workdata = NULL; /* MDEV */
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int au1xac97c_drvsuspend(struct device *dev)
-{
- struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev);
-
- WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */
-
- return 0;
-}
-
-static int au1xac97c_drvresume(struct device *dev)
-{
- struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev);
-
- WR(ctx, AC97_ENABLE, EN_D | EN_CE);
- WR(ctx, AC97_ENABLE, EN_CE);
- WR(ctx, AC97_CONFIG, ctx->cfg);
-
- return 0;
-}
-
-static const struct dev_pm_ops au1xpscac97_pmops = {
- .suspend = au1xac97c_drvsuspend,
- .resume = au1xac97c_drvresume,
-};
-
-#define AU1XPSCAC97_PMOPS (&au1xpscac97_pmops)
-
-#else
-
-#define AU1XPSCAC97_PMOPS NULL
-
-#endif
-
-static struct platform_driver au1xac97c_driver = {
- .driver = {
- .name = "alchemy-ac97c",
- .owner = THIS_MODULE,
- .pm = AU1XPSCAC97_PMOPS,
- },
- .probe = au1xac97c_drvprobe,
- .remove = __devexit_p(au1xac97c_drvremove),
-};
-
-static int __init au1xac97c_load(void)
-{
- ac97c_workdata = NULL;
- return platform_driver_register(&au1xac97c_driver);
-}
-
-static void __exit au1xac97c_unload(void)
-{
- platform_driver_unregister(&au1xac97c_driver);
-}
-
-module_init(au1xac97c_load);
-module_exit(au1xac97c_unload);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Au1000/1500/1100 AC97C ASoC driver");
-MODULE_AUTHOR("Manuel Lauss");
diff --git a/ANDROID_3.4.5/sound/soc/au1x/db1000.c b/ANDROID_3.4.5/sound/soc/au1x/db1000.c
deleted file mode 100644
index 511d83c1..00000000
--- a/ANDROID_3.4.5/sound/soc/au1x/db1000.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * DB1000/DB1500/DB1100 ASoC audio fabric support code.
- *
- * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-db1x00/bcsr.h>
-
-#include "psc.h"
-
-static struct snd_soc_dai_link db1000_ac97_dai = {
- .name = "AC97",
- .stream_name = "AC97 HiFi",
- .codec_dai_name = "ac97-hifi",
- .cpu_dai_name = "alchemy-ac97c",
- .platform_name = "alchemy-pcm-dma.0",
- .codec_name = "ac97-codec",
-};
-
-static struct snd_soc_card db1000_ac97 = {
- .name = "DB1000_AC97",
- .owner = THIS_MODULE,
- .dai_link = &db1000_ac97_dai,
- .num_links = 1,
-};
-
-static int __devinit db1000_audio_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &db1000_ac97;
- card->dev = &pdev->dev;
- return snd_soc_register_card(card);
-}
-
-static int __devexit db1000_audio_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
- snd_soc_unregister_card(card);
- return 0;
-}
-
-static struct platform_driver db1000_audio_driver = {
- .driver = {
- .name = "db1000-audio",
- .owner = THIS_MODULE,
- .pm = &snd_soc_pm_ops,
- },
- .probe = db1000_audio_probe,
- .remove = __devexit_p(db1000_audio_remove),
-};
-
-module_platform_driver(db1000_audio_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("DB1000/DB1500/DB1100 ASoC audio");
-MODULE_AUTHOR("Manuel Lauss");
diff --git a/ANDROID_3.4.5/sound/soc/au1x/db1200.c b/ANDROID_3.4.5/sound/soc/au1x/db1200.c
deleted file mode 100644
index 30ea513d..00000000
--- a/ANDROID_3.4.5/sound/soc/au1x/db1200.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * DB1200/DB1300/DB1550 ASoC audio fabric support code.
- *
- * (c) 2008-2011 Manuel Lauss <manuel.lauss@googlemail.com>
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-au1x00/au1xxx_psc.h>
-#include <asm/mach-au1x00/au1xxx_dbdma.h>
-#include <asm/mach-db1x00/bcsr.h>
-
-#include "../codecs/wm8731.h"
-#include "psc.h"
-
-static struct platform_device_id db1200_pids[] = {
- {
- .name = "db1200-ac97",
- .driver_data = 0,
- }, {
- .name = "db1200-i2s",
- .driver_data = 1,
- }, {
- .name = "db1300-ac97",
- .driver_data = 2,
- }, {
- .name = "db1300-i2s",
- .driver_data = 3,
- }, {
- .name = "db1550-ac97",
- .driver_data = 4,
- }, {
- .name = "db1550-i2s",
- .driver_data = 5,
- },
- {},
-};
-
-/*------------------------- AC97 PART ---------------------------*/
-
-static struct snd_soc_dai_link db1200_ac97_dai = {
- .name = "AC97",
- .stream_name = "AC97 HiFi",
- .codec_dai_name = "ac97-hifi",
- .cpu_dai_name = "au1xpsc_ac97.1",
- .platform_name = "au1xpsc-pcm.1",
- .codec_name = "ac97-codec.1",
-};
-
-static struct snd_soc_card db1200_ac97_machine = {
- .name = "DB1200_AC97",
- .owner = THIS_MODULE,
- .dai_link = &db1200_ac97_dai,
- .num_links = 1,
-};
-
-static struct snd_soc_dai_link db1300_ac97_dai = {
- .name = "AC97",
- .stream_name = "AC97 HiFi",
- .codec_dai_name = "wm9712-hifi",
- .cpu_dai_name = "au1xpsc_ac97.1",
- .platform_name = "au1xpsc-pcm.1",
- .codec_name = "wm9712-codec.1",
-};
-
-static struct snd_soc_card db1300_ac97_machine = {
- .name = "DB1300_AC97",
- .dai_link = &db1300_ac97_dai,
- .num_links = 1,
-};
-
-static struct snd_soc_card db1550_ac97_machine = {
- .name = "DB1550_AC97",
- .dai_link = &db1200_ac97_dai,
- .num_links = 1,
-};
-
-/*------------------------- I2S PART ---------------------------*/
-
-static int db1200_i2s_startup(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret;
-
- /* WM8731 has its own 12MHz crystal */
- snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL,
- 12000000, SND_SOC_CLOCK_IN);
-
- /* codec is bitclock and lrclk master */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- goto out;
-
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_LEFT_J |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- goto out;
-
- ret = 0;
-out:
- return ret;
-}
-
-static struct snd_soc_ops db1200_i2s_wm8731_ops = {
- .startup = db1200_i2s_startup,
-};
-
-static struct snd_soc_dai_link db1200_i2s_dai = {
- .name = "WM8731",
- .stream_name = "WM8731 PCM",
- .codec_dai_name = "wm8731-hifi",
- .cpu_dai_name = "au1xpsc_i2s.1",
- .platform_name = "au1xpsc-pcm.1",
- .codec_name = "wm8731.0-001b",
- .ops = &db1200_i2s_wm8731_ops,
-};
-
-static struct snd_soc_card db1200_i2s_machine = {
- .name = "DB1200_I2S",
- .owner = THIS_MODULE,
- .dai_link = &db1200_i2s_dai,
- .num_links = 1,
-};
-
-static struct snd_soc_dai_link db1300_i2s_dai = {
- .name = "WM8731",
- .stream_name = "WM8731 PCM",
- .codec_dai_name = "wm8731-hifi",
- .cpu_dai_name = "au1xpsc_i2s.2",
- .platform_name = "au1xpsc-pcm.2",
- .codec_name = "wm8731.0-001b",
- .ops = &db1200_i2s_wm8731_ops,
-};
-
-static struct snd_soc_card db1300_i2s_machine = {
- .name = "DB1300_I2S",
- .dai_link = &db1300_i2s_dai,
- .num_links = 1,
-};
-
-static struct snd_soc_dai_link db1550_i2s_dai = {
- .name = "WM8731",
- .stream_name = "WM8731 PCM",
- .codec_dai_name = "wm8731-hifi",
- .cpu_dai_name = "au1xpsc_i2s.3",
- .platform_name = "au1xpsc-pcm.3",
- .codec_name = "wm8731.0-001b",
- .ops = &db1200_i2s_wm8731_ops,
-};
-
-static struct snd_soc_card db1550_i2s_machine = {
- .name = "DB1550_I2S",
- .dai_link = &db1550_i2s_dai,
- .num_links = 1,
-};
-
-/*------------------------- COMMON PART ---------------------------*/
-
-static struct snd_soc_card *db1200_cards[] __devinitdata = {
- &db1200_ac97_machine,
- &db1200_i2s_machine,
- &db1300_ac97_machine,
- &db1300_i2s_machine,
- &db1550_ac97_machine,
- &db1550_i2s_machine,
-};
-
-static int __devinit db1200_audio_probe(struct platform_device *pdev)
-{
- const struct platform_device_id *pid = platform_get_device_id(pdev);
- struct snd_soc_card *card;
-
- card = db1200_cards[pid->driver_data];
- card->dev = &pdev->dev;
- return snd_soc_register_card(card);
-}
-
-static int __devexit db1200_audio_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
- snd_soc_unregister_card(card);
- return 0;
-}
-
-static struct platform_driver db1200_audio_driver = {
- .driver = {
- .name = "db1200-ac97",
- .owner = THIS_MODULE,
- .pm = &snd_soc_pm_ops,
- },
- .id_table = db1200_pids,
- .probe = db1200_audio_probe,
- .remove = __devexit_p(db1200_audio_remove),
-};
-
-module_platform_driver(db1200_audio_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("DB1200/DB1300/DB1550 ASoC audio support");
-MODULE_AUTHOR("Manuel Lauss");
diff --git a/ANDROID_3.4.5/sound/soc/au1x/dbdma2.c b/ANDROID_3.4.5/sound/soc/au1x/dbdma2.c
deleted file mode 100644
index 8372cd35..00000000
--- a/ANDROID_3.4.5/sound/soc/au1x/dbdma2.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * Au12x0/Au1550 PSC ALSA ASoC audio support.
- *
- * (c) 2007-2008 MSC Vertriebsges.m.b.H.,
- * Manuel Lauss <manuel.lauss@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * DMA glue for Au1x-PSC audio.
- *
- */
-
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/dma-mapping.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-au1x00/au1xxx_dbdma.h>
-#include <asm/mach-au1x00/au1xxx_psc.h>
-
-#include "psc.h"
-
-/*#define PCM_DEBUG*/
-
-#define MSG(x...) printk(KERN_INFO "au1xpsc_pcm: " x)
-#ifdef PCM_DEBUG
-#define DBG MSG
-#else
-#define DBG(x...) do {} while (0)
-#endif
-
-struct au1xpsc_audio_dmadata {
- /* DDMA control data */
- unsigned int ddma_id; /* DDMA direction ID for this PSC */
- u32 ddma_chan; /* DDMA context */
-
- /* PCM context (for irq handlers) */
- struct snd_pcm_substream *substream;
- unsigned long curr_period; /* current segment DDMA is working on */
- unsigned long q_period; /* queue period(s) */
- dma_addr_t dma_area; /* address of queued DMA area */
- dma_addr_t dma_area_s; /* start address of DMA area */
- unsigned long pos; /* current byte position being played */
- unsigned long periods; /* number of SG segments in total */
- unsigned long period_bytes; /* size in bytes of one SG segment */
-
- /* runtime data */
- int msbits;
-};
-
-/*
- * These settings are somewhat okay, at least on my machine audio plays
- * almost skip-free. Especially the 64kB buffer seems to help a LOT.
- */
-#define AU1XPSC_PERIOD_MIN_BYTES 1024
-#define AU1XPSC_BUFFER_MIN_BYTES 65536
-
-#define AU1XPSC_PCM_FMTS \
- (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
- SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE | \
- SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE | \
- SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE | \
- 0)
-
-/* PCM hardware DMA capabilities - platform specific */
-static const struct snd_pcm_hardware au1xpsc_pcm_hardware = {
- .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BATCH,
- .formats = AU1XPSC_PCM_FMTS,
- .period_bytes_min = AU1XPSC_PERIOD_MIN_BYTES,
- .period_bytes_max = 4096 * 1024 - 1,
- .periods_min = 2,
- .periods_max = 4096, /* 2 to as-much-as-you-like */
- .buffer_bytes_max = 4096 * 1024 - 1,
- .fifo_size = 16, /* fifo entries of AC97/I2S PSC */
-};
-
-static void au1x_pcm_queue_tx(struct au1xpsc_audio_dmadata *cd)
-{
- au1xxx_dbdma_put_source(cd->ddma_chan, cd->dma_area,
- cd->period_bytes, DDMA_FLAGS_IE);
-
- /* update next-to-queue period */
- ++cd->q_period;
- cd->dma_area += cd->period_bytes;
- if (cd->q_period >= cd->periods) {
- cd->q_period = 0;
- cd->dma_area = cd->dma_area_s;
- }
-}
-
-static void au1x_pcm_queue_rx(struct au1xpsc_audio_dmadata *cd)
-{
- au1xxx_dbdma_put_dest(cd->ddma_chan, cd->dma_area,
- cd->period_bytes, DDMA_FLAGS_IE);
-
- /* update next-to-queue period */
- ++cd->q_period;
- cd->dma_area += cd->period_bytes;
- if (cd->q_period >= cd->periods) {
- cd->q_period = 0;
- cd->dma_area = cd->dma_area_s;
- }
-}
-
-static void au1x_pcm_dmatx_cb(int irq, void *dev_id)
-{
- struct au1xpsc_audio_dmadata *cd = dev_id;
-
- cd->pos += cd->period_bytes;
- if (++cd->curr_period >= cd->periods) {
- cd->pos = 0;
- cd->curr_period = 0;
- }
- snd_pcm_period_elapsed(cd->substream);
- au1x_pcm_queue_tx(cd);
-}
-
-static void au1x_pcm_dmarx_cb(int irq, void *dev_id)
-{
- struct au1xpsc_audio_dmadata *cd = dev_id;
-
- cd->pos += cd->period_bytes;
- if (++cd->curr_period >= cd->periods) {
- cd->pos = 0;
- cd->curr_period = 0;
- }
- snd_pcm_period_elapsed(cd->substream);
- au1x_pcm_queue_rx(cd);
-}
-
-static void au1x_pcm_dbdma_free(struct au1xpsc_audio_dmadata *pcd)
-{
- if (pcd->ddma_chan) {
- au1xxx_dbdma_stop(pcd->ddma_chan);
- au1xxx_dbdma_reset(pcd->ddma_chan);
- au1xxx_dbdma_chan_free(pcd->ddma_chan);
- pcd->ddma_chan = 0;
- pcd->msbits = 0;
- }
-}
-
-/* in case of missing DMA ring or changed TX-source / RX-dest bit widths,
- * allocate (or reallocate) a 2-descriptor DMA ring with bit depth according
- * to ALSA-supplied sample depth. This is due to limitations in the dbdma api
- * (cannot adjust source/dest widths of already allocated descriptor ring).
- */
-static int au1x_pcm_dbdma_realloc(struct au1xpsc_audio_dmadata *pcd,
- int stype, int msbits)
-{
- /* DMA only in 8/16/32 bit widths */
- if (msbits == 24)
- msbits = 32;
-
- /* check current config: correct bits and descriptors allocated? */
- if ((pcd->ddma_chan) && (msbits == pcd->msbits))
- goto out; /* all ok! */
-
- au1x_pcm_dbdma_free(pcd);
-
- if (stype == SNDRV_PCM_STREAM_CAPTURE)
- pcd->ddma_chan = au1xxx_dbdma_chan_alloc(pcd->ddma_id,
- DSCR_CMD0_ALWAYS,
- au1x_pcm_dmarx_cb, (void *)pcd);
- else
- pcd->ddma_chan = au1xxx_dbdma_chan_alloc(DSCR_CMD0_ALWAYS,
- pcd->ddma_id,
- au1x_pcm_dmatx_cb, (void *)pcd);
-
- if (!pcd->ddma_chan)
- return -ENOMEM;
-
- au1xxx_dbdma_set_devwidth(pcd->ddma_chan, msbits);
- au1xxx_dbdma_ring_alloc(pcd->ddma_chan, 2);
-
- pcd->msbits = msbits;
-
- au1xxx_dbdma_stop(pcd->ddma_chan);
- au1xxx_dbdma_reset(pcd->ddma_chan);
-
-out:
- return 0;
-}
-
-static inline struct au1xpsc_audio_dmadata *to_dmadata(struct snd_pcm_substream *ss)
-{
- struct snd_soc_pcm_runtime *rtd = ss->private_data;
- struct au1xpsc_audio_dmadata *pcd =
- snd_soc_platform_get_drvdata(rtd->platform);
- return &pcd[ss->stream];
-}
-
-static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct au1xpsc_audio_dmadata *pcd;
- int stype, ret;
-
- ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
- if (ret < 0)
- goto out;
-
- stype = substream->stream;
- pcd = to_dmadata(substream);
-
- DBG("runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %d "
- "runtime->min_align %d\n",
- (unsigned long)runtime->dma_area,
- (unsigned long)runtime->dma_addr, runtime->dma_bytes,
- runtime->min_align);
-
- DBG("bits %d frags %d frag_bytes %d is_rx %d\n", params->msbits,
- params_periods(params), params_period_bytes(params), stype);
-
- ret = au1x_pcm_dbdma_realloc(pcd, stype, params->msbits);
- if (ret) {
- MSG("DDMA channel (re)alloc failed!\n");
- goto out;
- }
-
- pcd->substream = substream;
- pcd->period_bytes = params_period_bytes(params);
- pcd->periods = params_periods(params);
- pcd->dma_area_s = pcd->dma_area = runtime->dma_addr;
- pcd->q_period = 0;
- pcd->curr_period = 0;
- pcd->pos = 0;
-
- ret = 0;
-out:
- return ret;
-}
-
-static int au1xpsc_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-static int au1xpsc_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct au1xpsc_audio_dmadata *pcd = to_dmadata(substream);
-
- au1xxx_dbdma_reset(pcd->ddma_chan);
-
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- au1x_pcm_queue_rx(pcd);
- au1x_pcm_queue_rx(pcd);
- } else {
- au1x_pcm_queue_tx(pcd);
- au1x_pcm_queue_tx(pcd);
- }
-
- return 0;
-}
-
-static int au1xpsc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- u32 c = to_dmadata(substream)->ddma_chan;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- au1xxx_dbdma_start(c);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- au1xxx_dbdma_stop(c);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static snd_pcm_uframes_t
-au1xpsc_pcm_pointer(struct snd_pcm_substream *substream)
-{
- return bytes_to_frames(substream->runtime, to_dmadata(substream)->pos);
-}
-
-static int au1xpsc_pcm_open(struct snd_pcm_substream *substream)
-{
- struct au1xpsc_audio_dmadata *pcd = to_dmadata(substream);
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- int stype = substream->stream, *dmaids;
-
- dmaids = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
- if (!dmaids)
- return -ENODEV; /* whoa, has ordering changed? */
-
- pcd->ddma_id = dmaids[stype];
-
- snd_soc_set_runtime_hwparams(substream, &au1xpsc_pcm_hardware);
- return 0;
-}
-
-static int au1xpsc_pcm_close(struct snd_pcm_substream *substream)
-{
- au1x_pcm_dbdma_free(to_dmadata(substream));
- return 0;
-}
-
-static struct snd_pcm_ops au1xpsc_pcm_ops = {
- .open = au1xpsc_pcm_open,
- .close = au1xpsc_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = au1xpsc_pcm_hw_params,
- .hw_free = au1xpsc_pcm_hw_free,
- .prepare = au1xpsc_pcm_prepare,
- .trigger = au1xpsc_pcm_trigger,
- .pointer = au1xpsc_pcm_pointer,
-};
-
-static void au1xpsc_pcm_free_dma_buffers(struct snd_pcm *pcm)
-{
- snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int au1xpsc_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- card->dev, AU1XPSC_BUFFER_MIN_BYTES, (4096 * 1024) - 1);
-
- return 0;
-}
-
-/* au1xpsc audio platform */
-static struct snd_soc_platform_driver au1xpsc_soc_platform = {
- .ops = &au1xpsc_pcm_ops,
- .pcm_new = au1xpsc_pcm_new,
- .pcm_free = au1xpsc_pcm_free_dma_buffers,
-};
-
-static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev)
-{
- struct au1xpsc_audio_dmadata *dmadata;
-
- dmadata = devm_kzalloc(&pdev->dev,
- 2 * sizeof(struct au1xpsc_audio_dmadata),
- GFP_KERNEL);
- if (!dmadata)
- return -ENOMEM;
-
- platform_set_drvdata(pdev, dmadata);
-
- return snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform);
-}
-
-static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
-
- return 0;
-}
-
-static struct platform_driver au1xpsc_pcm_driver = {
- .driver = {
- .name = "au1xpsc-pcm",
- .owner = THIS_MODULE,
- },
- .probe = au1xpsc_pcm_drvprobe,
- .remove = __devexit_p(au1xpsc_pcm_drvremove),
-};
-
-module_platform_driver(au1xpsc_pcm_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver");
-MODULE_AUTHOR("Manuel Lauss");
diff --git a/ANDROID_3.4.5/sound/soc/au1x/dma.c b/ANDROID_3.4.5/sound/soc/au1x/dma.c
deleted file mode 100644
index 0a91b186..00000000
--- a/ANDROID_3.4.5/sound/soc/au1x/dma.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * Au1000/Au1500/Au1100 Audio DMA support.
- *
- * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
- *
- * copied almost verbatim from the old ALSA driver, written by
- * Charles Eidsness <charles@cooper-street.com>
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/dma-mapping.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-au1x00/au1000_dma.h>
-
-#include "psc.h"
-
-#define ALCHEMY_PCM_FMTS \
- (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
- SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE | \
- SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE | \
- SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE | \
- 0)
-
-struct pcm_period {
- u32 start;
- u32 relative_end; /* relative to start of buffer */
- struct pcm_period *next;
-};
-
-struct audio_stream {
- struct snd_pcm_substream *substream;
- int dma;
- struct pcm_period *buffer;
- unsigned int period_size;
- unsigned int periods;
-};
-
-struct alchemy_pcm_ctx {
- struct audio_stream stream[2]; /* playback & capture */
-};
-
-static void au1000_release_dma_link(struct audio_stream *stream)
-{
- struct pcm_period *pointer;
- struct pcm_period *pointer_next;
-
- stream->period_size = 0;
- stream->periods = 0;
- pointer = stream->buffer;
- if (!pointer)
- return;
- do {
- pointer_next = pointer->next;
- kfree(pointer);
- pointer = pointer_next;
- } while (pointer != stream->buffer);
- stream->buffer = NULL;
-}
-
-static int au1000_setup_dma_link(struct audio_stream *stream,
- unsigned int period_bytes,
- unsigned int periods)
-{
- struct snd_pcm_substream *substream = stream->substream;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct pcm_period *pointer;
- unsigned long dma_start;
- int i;
-
- dma_start = virt_to_phys(runtime->dma_area);
-
- if (stream->period_size == period_bytes &&
- stream->periods == periods)
- return 0; /* not changed */
-
- au1000_release_dma_link(stream);
-
- stream->period_size = period_bytes;
- stream->periods = periods;
-
- stream->buffer = kmalloc(sizeof(struct pcm_period), GFP_KERNEL);
- if (!stream->buffer)
- return -ENOMEM;
- pointer = stream->buffer;
- for (i = 0; i < periods; i++) {
- pointer->start = (u32)(dma_start + (i * period_bytes));
- pointer->relative_end = (u32) (((i+1) * period_bytes) - 0x1);
- if (i < periods - 1) {
- pointer->next = kmalloc(sizeof(struct pcm_period),
- GFP_KERNEL);
- if (!pointer->next) {
- au1000_release_dma_link(stream);
- return -ENOMEM;
- }
- pointer = pointer->next;
- }
- }
- pointer->next = stream->buffer;
- return 0;
-}
-
-static void au1000_dma_stop(struct audio_stream *stream)
-{
- if (stream->buffer)
- disable_dma(stream->dma);
-}
-
-static void au1000_dma_start(struct audio_stream *stream)
-{
- if (!stream->buffer)
- return;
-
- init_dma(stream->dma);
- if (get_dma_active_buffer(stream->dma) == 0) {
- clear_dma_done0(stream->dma);
- set_dma_addr0(stream->dma, stream->buffer->start);
- set_dma_count0(stream->dma, stream->period_size >> 1);
- set_dma_addr1(stream->dma, stream->buffer->next->start);
- set_dma_count1(stream->dma, stream->period_size >> 1);
- } else {
- clear_dma_done1(stream->dma);
- set_dma_addr1(stream->dma, stream->buffer->start);
- set_dma_count1(stream->dma, stream->period_size >> 1);
- set_dma_addr0(stream->dma, stream->buffer->next->start);
- set_dma_count0(stream->dma, stream->period_size >> 1);
- }
- enable_dma_buffers(stream->dma);
- start_dma(stream->dma);
-}
-
-static irqreturn_t au1000_dma_interrupt(int irq, void *ptr)
-{
- struct audio_stream *stream = (struct audio_stream *)ptr;
- struct snd_pcm_substream *substream = stream->substream;
-
- switch (get_dma_buffer_done(stream->dma)) {
- case DMA_D0:
- stream->buffer = stream->buffer->next;
- clear_dma_done0(stream->dma);
- set_dma_addr0(stream->dma, stream->buffer->next->start);
- set_dma_count0(stream->dma, stream->period_size >> 1);
- enable_dma_buffer0(stream->dma);
- break;
- case DMA_D1:
- stream->buffer = stream->buffer->next;
- clear_dma_done1(stream->dma);
- set_dma_addr1(stream->dma, stream->buffer->next->start);
- set_dma_count1(stream->dma, stream->period_size >> 1);
- enable_dma_buffer1(stream->dma);
- break;
- case (DMA_D0 | DMA_D1):
- pr_debug("DMA %d missed interrupt.\n", stream->dma);
- au1000_dma_stop(stream);
- au1000_dma_start(stream);
- break;
- case (~DMA_D0 & ~DMA_D1):
- pr_debug("DMA %d empty irq.\n", stream->dma);
- }
- snd_pcm_period_elapsed(substream);
- return IRQ_HANDLED;
-}
-
-static const struct snd_pcm_hardware alchemy_pcm_hardware = {
- .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BATCH,
- .formats = ALCHEMY_PCM_FMTS,
- .rates = SNDRV_PCM_RATE_8000_192000,
- .rate_min = SNDRV_PCM_RATE_8000,
- .rate_max = SNDRV_PCM_RATE_192000,
- .channels_min = 2,
- .channels_max = 2,
- .period_bytes_min = 1024,
- .period_bytes_max = 16 * 1024 - 1,
- .periods_min = 4,
- .periods_max = 255,
- .buffer_bytes_max = 128 * 1024,
- .fifo_size = 16,
-};
-
-static inline struct alchemy_pcm_ctx *ss_to_ctx(struct snd_pcm_substream *ss)
-{
- struct snd_soc_pcm_runtime *rtd = ss->private_data;
- return snd_soc_platform_get_drvdata(rtd->platform);
-}
-
-static inline struct audio_stream *ss_to_as(struct snd_pcm_substream *ss)
-{
- struct alchemy_pcm_ctx *ctx = ss_to_ctx(ss);
- return &(ctx->stream[ss->stream]);
-}
-
-static int alchemy_pcm_open(struct snd_pcm_substream *substream)
-{
- struct alchemy_pcm_ctx *ctx = ss_to_ctx(substream);
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- int *dmaids, s = substream->stream;
- char *name;
-
- dmaids = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
- if (!dmaids)
- return -ENODEV; /* whoa, has ordering changed? */
-
- /* DMA setup */
- name = (s == SNDRV_PCM_STREAM_PLAYBACK) ? "audio-tx" : "audio-rx";
- ctx->stream[s].dma = request_au1000_dma(dmaids[s], name,
- au1000_dma_interrupt, 0,
- &ctx->stream[s]);
- set_dma_mode(ctx->stream[s].dma,
- get_dma_mode(ctx->stream[s].dma) & ~DMA_NC);
-
- ctx->stream[s].substream = substream;
- ctx->stream[s].buffer = NULL;
- snd_soc_set_runtime_hwparams(substream, &alchemy_pcm_hardware);
-
- return 0;
-}
-
-static int alchemy_pcm_close(struct snd_pcm_substream *substream)
-{
- struct alchemy_pcm_ctx *ctx = ss_to_ctx(substream);
- int stype = substream->stream;
-
- ctx->stream[stype].substream = NULL;
- free_au1000_dma(ctx->stream[stype].dma);
-
- return 0;
-}
-
-static int alchemy_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct audio_stream *stream = ss_to_as(substream);
- int err;
-
- err = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
- err = au1000_setup_dma_link(stream,
- params_period_bytes(hw_params),
- params_periods(hw_params));
- if (err)
- snd_pcm_lib_free_pages(substream);
-
- return err;
-}
-
-static int alchemy_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct audio_stream *stream = ss_to_as(substream);
- au1000_release_dma_link(stream);
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int alchemy_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct audio_stream *stream = ss_to_as(substream);
- int err = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- au1000_dma_start(stream);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- au1000_dma_stop(stream);
- break;
- default:
- err = -EINVAL;
- break;
- }
- return err;
-}
-
-static snd_pcm_uframes_t alchemy_pcm_pointer(struct snd_pcm_substream *ss)
-{
- struct audio_stream *stream = ss_to_as(ss);
- long location;
-
- location = get_dma_residue(stream->dma);
- location = stream->buffer->relative_end - location;
- if (location == -1)
- location = 0;
- return bytes_to_frames(ss->runtime, location);
-}
-
-static struct snd_pcm_ops alchemy_pcm_ops = {
- .open = alchemy_pcm_open,
- .close = alchemy_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = alchemy_pcm_hw_params,
- .hw_free = alchemy_pcm_hw_free,
- .trigger = alchemy_pcm_trigger,
- .pointer = alchemy_pcm_pointer,
-};
-
-static void alchemy_pcm_free_dma_buffers(struct snd_pcm *pcm)
-{
- snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int alchemy_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_pcm *pcm = rtd->pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL), 65536, (4096 * 1024) - 1);
-
- return 0;
-}
-
-static struct snd_soc_platform_driver alchemy_pcm_soc_platform = {
- .ops = &alchemy_pcm_ops,
- .pcm_new = alchemy_pcm_new,
- .pcm_free = alchemy_pcm_free_dma_buffers,
-};
-
-static int __devinit alchemy_pcm_drvprobe(struct platform_device *pdev)
-{
- struct alchemy_pcm_ctx *ctx;
-
- ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
- if (!ctx)
- return -ENOMEM;
-
- platform_set_drvdata(pdev, ctx);
-
- return snd_soc_register_platform(&pdev->dev, &alchemy_pcm_soc_platform);
-}
-
-static int __devexit alchemy_pcm_drvremove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
-
- return 0;
-}
-
-static struct platform_driver alchemy_pcmdma_driver = {
- .driver = {
- .name = "alchemy-pcm-dma",
- .owner = THIS_MODULE,
- },
- .probe = alchemy_pcm_drvprobe,
- .remove = __devexit_p(alchemy_pcm_drvremove),
-};
-
-module_platform_driver(alchemy_pcmdma_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Au1000/Au1500/Au1100 Audio DMA driver");
-MODULE_AUTHOR("Manuel Lauss");
diff --git a/ANDROID_3.4.5/sound/soc/au1x/i2sc.c b/ANDROID_3.4.5/sound/soc/au1x/i2sc.c
deleted file mode 100644
index d4b9e364..00000000
--- a/ANDROID_3.4.5/sound/soc/au1x/i2sc.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Au1000/Au1500/Au1100 I2S controller driver for ASoC
- *
- * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
- *
- * Note: clock supplied to the I2S controller must be 256x samplerate.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/suspend.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-#include <asm/mach-au1x00/au1000.h>
-
-#include "psc.h"
-
-#define I2S_RXTX 0x00
-#define I2S_CFG 0x04
-#define I2S_ENABLE 0x08
-
-#define CFG_XU (1 << 25) /* tx underflow */
-#define CFG_XO (1 << 24)
-#define CFG_RU (1 << 23)
-#define CFG_RO (1 << 22)
-#define CFG_TR (1 << 21)
-#define CFG_TE (1 << 20)
-#define CFG_TF (1 << 19)
-#define CFG_RR (1 << 18)
-#define CFG_RF (1 << 17)
-#define CFG_ICK (1 << 12) /* clock invert */
-#define CFG_PD (1 << 11) /* set to make I2SDIO INPUT */
-#define CFG_LB (1 << 10) /* loopback */
-#define CFG_IC (1 << 9) /* word select invert */
-#define CFG_FM_I2S (0 << 7) /* I2S format */
-#define CFG_FM_LJ (1 << 7) /* left-justified */
-#define CFG_FM_RJ (2 << 7) /* right-justified */
-#define CFG_FM_MASK (3 << 7)
-#define CFG_TN (1 << 6) /* tx fifo en */
-#define CFG_RN (1 << 5) /* rx fifo en */
-#define CFG_SZ_8 (0x08)
-#define CFG_SZ_16 (0x10)
-#define CFG_SZ_18 (0x12)
-#define CFG_SZ_20 (0x14)
-#define CFG_SZ_24 (0x18)
-#define CFG_SZ_MASK (0x1f)
-#define EN_D (1 << 1) /* DISable */
-#define EN_CE (1 << 0) /* clock enable */
-
-/* only limited by clock generator and board design */
-#define AU1XI2SC_RATES \
- SNDRV_PCM_RATE_CONTINUOUS
-
-#define AU1XI2SC_FMTS \
- (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
- SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE | \
- SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_U18_3LE | \
- SNDRV_PCM_FMTBIT_S18_3BE | SNDRV_PCM_FMTBIT_U18_3BE | \
- SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \
- SNDRV_PCM_FMTBIT_S20_3BE | SNDRV_PCM_FMTBIT_U20_3BE | \
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE | \
- SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_U24_BE | \
- 0)
-
-static inline unsigned long RD(struct au1xpsc_audio_data *ctx, int reg)
-{
- return __raw_readl(ctx->mmio + reg);
-}
-
-static inline void WR(struct au1xpsc_audio_data *ctx, int reg, unsigned long v)
-{
- __raw_writel(v, ctx->mmio + reg);
- wmb();
-}
-
-static int au1xi2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
-{
- struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(cpu_dai);
- unsigned long c;
- int ret;
-
- ret = -EINVAL;
- c = ctx->cfg;
-
- c &= ~CFG_FM_MASK;
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- c |= CFG_FM_I2S;
- break;
- case SND_SOC_DAIFMT_MSB:
- c |= CFG_FM_RJ;
- break;
- case SND_SOC_DAIFMT_LSB:
- c |= CFG_FM_LJ;
- break;
- default:
- goto out;
- }
-
- c &= ~(CFG_IC | CFG_ICK); /* IB-IF */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- c |= CFG_IC | CFG_ICK;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- c |= CFG_IC;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- c |= CFG_ICK;
- break;
- case SND_SOC_DAIFMT_IB_IF:
- break;
- default:
- goto out;
- }
-
- /* I2S controller only supports master */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS: /* CODEC slave */
- break;
- default:
- goto out;
- }
-
- ret = 0;
- ctx->cfg = c;
-out:
- return ret;
-}
-
-static int au1xi2s_trigger(struct snd_pcm_substream *substream,
- int cmd, struct snd_soc_dai *dai)
-{
- struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
- int stype = SUBSTREAM_TYPE(substream);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- /* power up */
- WR(ctx, I2S_ENABLE, EN_D | EN_CE);
- WR(ctx, I2S_ENABLE, EN_CE);
- ctx->cfg |= (stype == PCM_TX) ? CFG_TN : CFG_RN;
- WR(ctx, I2S_CFG, ctx->cfg);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- ctx->cfg &= ~((stype == PCM_TX) ? CFG_TN : CFG_RN);
- WR(ctx, I2S_CFG, ctx->cfg);
- WR(ctx, I2S_ENABLE, EN_D); /* power off */
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static unsigned long msbits_to_reg(int msbits)
-{
- switch (msbits) {
- case 8:
- return CFG_SZ_8;
- case 16:
- return CFG_SZ_16;
- case 18:
- return CFG_SZ_18;
- case 20:
- return CFG_SZ_20;
- case 24:
- return CFG_SZ_24;
- }
- return 0;
-}
-
-static int au1xi2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
- unsigned long v;
-
- v = msbits_to_reg(params->msbits);
- if (!v)
- return -EINVAL;
-
- ctx->cfg &= ~CFG_SZ_MASK;
- ctx->cfg |= v;
- return 0;
-}
-
-static int au1xi2s_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
- snd_soc_dai_set_dma_data(dai, substream, &ctx->dmaids[0]);
- return 0;
-}
-
-static const struct snd_soc_dai_ops au1xi2s_dai_ops = {
- .startup = au1xi2s_startup,
- .trigger = au1xi2s_trigger,
- .hw_params = au1xi2s_hw_params,
- .set_fmt = au1xi2s_set_fmt,
-};
-
-static struct snd_soc_dai_driver au1xi2s_dai_driver = {
- .symmetric_rates = 1,
- .playback = {
- .rates = AU1XI2SC_RATES,
- .formats = AU1XI2SC_FMTS,
- .channels_min = 2,
- .channels_max = 2,
- },
- .capture = {
- .rates = AU1XI2SC_RATES,
- .formats = AU1XI2SC_FMTS,
- .channels_min = 2,
- .channels_max = 2,
- },
- .ops = &au1xi2s_dai_ops,
-};
-
-static int __devinit au1xi2s_drvprobe(struct platform_device *pdev)
-{
- struct resource *iores, *dmares;
- struct au1xpsc_audio_data *ctx;
-
- ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
- if (!ctx)
- return -ENOMEM;
-
- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!iores)
- return -ENODEV;
-
- if (!devm_request_mem_region(&pdev->dev, iores->start,
- resource_size(iores),
- pdev->name))
- return -EBUSY;
-
- ctx->mmio = devm_ioremap_nocache(&pdev->dev, iores->start,
- resource_size(iores));
- if (!ctx->mmio)
- return -EBUSY;
-
- dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!dmares)
- return -EBUSY;
- ctx->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start;
-
- dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (!dmares)
- return -EBUSY;
- ctx->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start;
-
- platform_set_drvdata(pdev, ctx);
-
- return snd_soc_register_dai(&pdev->dev, &au1xi2s_dai_driver);
-}
-
-static int __devexit au1xi2s_drvremove(struct platform_device *pdev)
-{
- struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
-
- snd_soc_unregister_dai(&pdev->dev);
-
- WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int au1xi2s_drvsuspend(struct device *dev)
-{
- struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev);
-
- WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */
-
- return 0;
-}
-
-static int au1xi2s_drvresume(struct device *dev)
-{
- return 0;
-}
-
-static const struct dev_pm_ops au1xi2sc_pmops = {
- .suspend = au1xi2s_drvsuspend,
- .resume = au1xi2s_drvresume,
-};
-
-#define AU1XI2SC_PMOPS (&au1xi2sc_pmops)
-
-#else
-
-#define AU1XI2SC_PMOPS NULL
-
-#endif
-
-static struct platform_driver au1xi2s_driver = {
- .driver = {
- .name = "alchemy-i2sc",
- .owner = THIS_MODULE,
- .pm = AU1XI2SC_PMOPS,
- },
- .probe = au1xi2s_drvprobe,
- .remove = __devexit_p(au1xi2s_drvremove),
-};
-
-module_platform_driver(au1xi2s_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Au1000/1500/1100 I2S ASoC driver");
-MODULE_AUTHOR("Manuel Lauss");
diff --git a/ANDROID_3.4.5/sound/soc/au1x/psc-ac97.c b/ANDROID_3.4.5/sound/soc/au1x/psc-ac97.c
deleted file mode 100644
index 476b79a1..00000000
--- a/ANDROID_3.4.5/sound/soc/au1x/psc-ac97.c
+++ /dev/null
@@ -1,518 +0,0 @@
-/*
- * Au12x0/Au1550 PSC ALSA ASoC audio support.
- *
- * (c) 2007-2009 MSC Vertriebsges.m.b.H.,
- * Manuel Lauss <manuel.lauss@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Au1xxx-PSC AC97 glue.
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/suspend.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-au1x00/au1xxx_psc.h>
-
-#include "psc.h"
-
-/* how often to retry failed codec register reads/writes */
-#define AC97_RW_RETRIES 5
-
-#define AC97_DIR \
- (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE)
-
-#define AC97_RATES \
- SNDRV_PCM_RATE_8000_48000
-
-#define AC97_FMTS \
- (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3BE)
-
-#define AC97PCR_START(stype) \
- ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TS : PSC_AC97PCR_RS)
-#define AC97PCR_STOP(stype) \
- ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TP : PSC_AC97PCR_RP)
-#define AC97PCR_CLRFIFO(stype) \
- ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TC : PSC_AC97PCR_RC)
-
-#define AC97STAT_BUSY(stype) \
- ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97STAT_TB : PSC_AC97STAT_RB)
-
-/* instance data. There can be only one, MacLeod!!!! */
-static struct au1xpsc_audio_data *au1xpsc_ac97_workdata;
-
-#if 0
-
-/* this could theoretically work, but ac97->bus->card->private_data can be NULL
- * when snd_ac97_mixer() is called; I don't know if the rest further down the
- * chain are always valid either.
- */
-static inline struct au1xpsc_audio_data *ac97_to_pscdata(struct snd_ac97 *x)
-{
- struct snd_soc_card *c = x->bus->card->private_data;
- return snd_soc_dai_get_drvdata(c->rtd->cpu_dai);
-}
-
-#else
-
-#define ac97_to_pscdata(x) au1xpsc_ac97_workdata
-
-#endif
-
-/* AC97 controller reads codec register */
-static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97);
- unsigned short retry, tmo;
- unsigned long data;
-
- au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
- au_sync();
-
- retry = AC97_RW_RETRIES;
- do {
- mutex_lock(&pscdata->lock);
-
- au_writel(PSC_AC97CDC_RD | PSC_AC97CDC_INDX(reg),
- AC97_CDC(pscdata));
- au_sync();
-
- tmo = 20;
- do {
- udelay(21);
- if (au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)
- break;
- } while (--tmo);
-
- data = au_readl(AC97_CDC(pscdata));
-
- au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
- au_sync();
-
- mutex_unlock(&pscdata->lock);
-
- if (reg != ((data >> 16) & 0x7f))
- tmo = 1; /* wrong register, try again */
-
- } while (--retry && !tmo);
-
- return retry ? data & 0xffff : 0xffff;
-}
-
-/* AC97 controller writes to codec register */
-static void au1xpsc_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short val)
-{
- struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97);
- unsigned int tmo, retry;
-
- au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
- au_sync();
-
- retry = AC97_RW_RETRIES;
- do {
- mutex_lock(&pscdata->lock);
-
- au_writel(PSC_AC97CDC_INDX(reg) | (val & 0xffff),
- AC97_CDC(pscdata));
- au_sync();
-
- tmo = 20;
- do {
- udelay(21);
- if (au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)
- break;
- } while (--tmo);
-
- au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
- au_sync();
-
- mutex_unlock(&pscdata->lock);
- } while (--retry && !tmo);
-}
-
-/* AC97 controller asserts a warm reset */
-static void au1xpsc_ac97_warm_reset(struct snd_ac97 *ac97)
-{
- struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97);
-
- au_writel(PSC_AC97RST_SNC, AC97_RST(pscdata));
- au_sync();
- msleep(10);
- au_writel(0, AC97_RST(pscdata));
- au_sync();
-}
-
-static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97)
-{
- struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97);
- int i;
-
- /* disable PSC during cold reset */
- au_writel(0, AC97_CFG(au1xpsc_ac97_workdata));
- au_sync();
- au_writel(PSC_CTRL_DISABLE, PSC_CTRL(pscdata));
- au_sync();
-
- /* issue cold reset */
- au_writel(PSC_AC97RST_RST, AC97_RST(pscdata));
- au_sync();
- msleep(500);
- au_writel(0, AC97_RST(pscdata));
- au_sync();
-
- /* enable PSC */
- au_writel(PSC_CTRL_ENABLE, PSC_CTRL(pscdata));
- au_sync();
-
- /* wait for PSC to indicate it's ready */
- i = 1000;
- while (!((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_SR)) && (--i))
- msleep(1);
-
- if (i == 0) {
- printk(KERN_ERR "au1xpsc-ac97: PSC not ready!\n");
- return;
- }
-
- /* enable the ac97 function */
- au_writel(pscdata->cfg | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata));
- au_sync();
-
- /* wait for AC97 core to become ready */
- i = 1000;
- while (!((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && (--i))
- msleep(1);
- if (i == 0)
- printk(KERN_ERR "au1xpsc-ac97: AC97 ctrl not ready\n");
-}
-
-/* AC97 controller operations */
-struct snd_ac97_bus_ops soc_ac97_ops = {
- .read = au1xpsc_ac97_read,
- .write = au1xpsc_ac97_write,
- .reset = au1xpsc_ac97_cold_reset,
- .warm_reset = au1xpsc_ac97_warm_reset,
-};
-EXPORT_SYMBOL_GPL(soc_ac97_ops);
-
-static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
- unsigned long r, ro, stat;
- int chans, t, stype = substream->stream;
-
- chans = params_channels(params);
-
- r = ro = au_readl(AC97_CFG(pscdata));
- stat = au_readl(AC97_STAT(pscdata));
-
- /* already active? */
- if (stat & (PSC_AC97STAT_TB | PSC_AC97STAT_RB)) {
- /* reject parameters not currently set up */
- if ((PSC_AC97CFG_GET_LEN(r) != params->msbits) ||
- (pscdata->rate != params_rate(params)))
- return -EINVAL;
- } else {
-
- /* set sample bitdepth: REG[24:21]=(BITS-2)/2 */
- r &= ~PSC_AC97CFG_LEN_MASK;
- r |= PSC_AC97CFG_SET_LEN(params->msbits);
-
- /* channels: enable slots for front L/R channel */
- if (stype == SNDRV_PCM_STREAM_PLAYBACK) {
- r &= ~PSC_AC97CFG_TXSLOT_MASK;
- r |= PSC_AC97CFG_TXSLOT_ENA(3);
- r |= PSC_AC97CFG_TXSLOT_ENA(4);
- } else {
- r &= ~PSC_AC97CFG_RXSLOT_MASK;
- r |= PSC_AC97CFG_RXSLOT_ENA(3);
- r |= PSC_AC97CFG_RXSLOT_ENA(4);
- }
-
- /* do we need to poke the hardware? */
- if (!(r ^ ro))
- goto out;
-
- /* ac97 engine is about to be disabled */
- mutex_lock(&pscdata->lock);
-
- /* disable AC97 device controller first... */
- au_writel(r & ~PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata));
- au_sync();
-
- /* ...wait for it... */
- t = 100;
- while ((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR) && --t)
- msleep(1);
-
- if (!t)
- printk(KERN_ERR "PSC-AC97: can't disable!\n");
-
- /* ...write config... */
- au_writel(r, AC97_CFG(pscdata));
- au_sync();
-
- /* ...enable the AC97 controller again... */
- au_writel(r | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata));
- au_sync();
-
- /* ...and wait for ready bit */
- t = 100;
- while ((!(au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && --t)
- msleep(1);
-
- if (!t)
- printk(KERN_ERR "PSC-AC97: can't enable!\n");
-
- mutex_unlock(&pscdata->lock);
-
- pscdata->cfg = r;
- pscdata->rate = params_rate(params);
- }
-
-out:
- return 0;
-}
-
-static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
- int cmd, struct snd_soc_dai *dai)
-{
- struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
- int ret, stype = substream->stream;
-
- ret = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- au_writel(AC97PCR_CLRFIFO(stype), AC97_PCR(pscdata));
- au_sync();
- au_writel(AC97PCR_START(stype), AC97_PCR(pscdata));
- au_sync();
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- au_writel(AC97PCR_STOP(stype), AC97_PCR(pscdata));
- au_sync();
-
- while (au_readl(AC97_STAT(pscdata)) & AC97STAT_BUSY(stype))
- asm volatile ("nop");
-
- au_writel(AC97PCR_CLRFIFO(stype), AC97_PCR(pscdata));
- au_sync();
-
- break;
- default:
- ret = -EINVAL;
- }
- return ret;
-}
-
-static int au1xpsc_ac97_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
- snd_soc_dai_set_dma_data(dai, substream, &pscdata->dmaids[0]);
- return 0;
-}
-
-static int au1xpsc_ac97_probe(struct snd_soc_dai *dai)
-{
- return au1xpsc_ac97_workdata ? 0 : -ENODEV;
-}
-
-static const struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = {
- .startup = au1xpsc_ac97_startup,
- .trigger = au1xpsc_ac97_trigger,
- .hw_params = au1xpsc_ac97_hw_params,
-};
-
-static const struct snd_soc_dai_driver au1xpsc_ac97_dai_template = {
- .ac97_control = 1,
- .probe = au1xpsc_ac97_probe,
- .playback = {
- .rates = AC97_RATES,
- .formats = AC97_FMTS,
- .channels_min = 2,
- .channels_max = 2,
- },
- .capture = {
- .rates = AC97_RATES,
- .formats = AC97_FMTS,
- .channels_min = 2,
- .channels_max = 2,
- },
- .ops = &au1xpsc_ac97_dai_ops,
-};
-
-static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
-{
- int ret;
- struct resource *iores, *dmares;
- unsigned long sel;
- struct au1xpsc_audio_data *wd;
-
- wd = devm_kzalloc(&pdev->dev, sizeof(struct au1xpsc_audio_data),
- GFP_KERNEL);
- if (!wd)
- return -ENOMEM;
-
- mutex_init(&wd->lock);
-
- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!iores)
- return -ENODEV;
-
- if (!devm_request_mem_region(&pdev->dev, iores->start,
- resource_size(iores),
- pdev->name))
- return -EBUSY;
-
- wd->mmio = devm_ioremap(&pdev->dev, iores->start,
- resource_size(iores));
- if (!wd->mmio)
- return -EBUSY;
-
- dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!dmares)
- return -EBUSY;
- wd->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start;
-
- dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (!dmares)
- return -EBUSY;
- wd->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start;
-
- /* configuration: max dma trigger threshold, enable ac97 */
- wd->cfg = PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8 |
- PSC_AC97CFG_DE_ENABLE;
-
- /* preserve PSC clock source set up by platform */
- sel = au_readl(PSC_SEL(wd)) & PSC_SEL_CLK_MASK;
- au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
- au_sync();
- au_writel(0, PSC_SEL(wd));
- au_sync();
- au_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(wd));
- au_sync();
-
- /* name the DAI like this device instance ("au1xpsc-ac97.PSCINDEX") */
- memcpy(&wd->dai_drv, &au1xpsc_ac97_dai_template,
- sizeof(struct snd_soc_dai_driver));
- wd->dai_drv.name = dev_name(&pdev->dev);
-
- platform_set_drvdata(pdev, wd);
-
- ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv);
- if (ret)
- return ret;
-
- au1xpsc_ac97_workdata = wd;
- return 0;
-}
-
-static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev)
-{
- struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
-
- snd_soc_unregister_dai(&pdev->dev);
-
- /* disable PSC completely */
- au_writel(0, AC97_CFG(wd));
- au_sync();
- au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
- au_sync();
-
- au1xpsc_ac97_workdata = NULL; /* MDEV */
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int au1xpsc_ac97_drvsuspend(struct device *dev)
-{
- struct au1xpsc_audio_data *wd = dev_get_drvdata(dev);
-
- /* save interesting registers and disable PSC */
- wd->pm[0] = au_readl(PSC_SEL(wd));
-
- au_writel(0, AC97_CFG(wd));
- au_sync();
- au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
- au_sync();
-
- return 0;
-}
-
-static int au1xpsc_ac97_drvresume(struct device *dev)
-{
- struct au1xpsc_audio_data *wd = dev_get_drvdata(dev);
-
- /* restore PSC clock config */
- au_writel(wd->pm[0] | PSC_SEL_PS_AC97MODE, PSC_SEL(wd));
- au_sync();
-
- /* after this point the ac97 core will cold-reset the codec.
- * During cold-reset the PSC is reinitialized and the last
- * configuration set up in hw_params() is restored.
- */
- return 0;
-}
-
-static struct dev_pm_ops au1xpscac97_pmops = {
- .suspend = au1xpsc_ac97_drvsuspend,
- .resume = au1xpsc_ac97_drvresume,
-};
-
-#define AU1XPSCAC97_PMOPS &au1xpscac97_pmops
-
-#else
-
-#define AU1XPSCAC97_PMOPS NULL
-
-#endif
-
-static struct platform_driver au1xpsc_ac97_driver = {
- .driver = {
- .name = "au1xpsc_ac97",
- .owner = THIS_MODULE,
- .pm = AU1XPSCAC97_PMOPS,
- },
- .probe = au1xpsc_ac97_drvprobe,
- .remove = __devexit_p(au1xpsc_ac97_drvremove),
-};
-
-static int __init au1xpsc_ac97_load(void)
-{
- au1xpsc_ac97_workdata = NULL;
- return platform_driver_register(&au1xpsc_ac97_driver);
-}
-
-static void __exit au1xpsc_ac97_unload(void)
-{
- platform_driver_unregister(&au1xpsc_ac97_driver);
-}
-
-module_init(au1xpsc_ac97_load);
-module_exit(au1xpsc_ac97_unload);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Au12x0/Au1550 PSC AC97 ALSA ASoC audio driver");
-MODULE_AUTHOR("Manuel Lauss");
-
diff --git a/ANDROID_3.4.5/sound/soc/au1x/psc-i2s.c b/ANDROID_3.4.5/sound/soc/au1x/psc-i2s.c
deleted file mode 100644
index 0607ba3d..00000000
--- a/ANDROID_3.4.5/sound/soc/au1x/psc-i2s.c
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * Au12x0/Au1550 PSC ALSA ASoC audio support.
- *
- * (c) 2007-2008 MSC Vertriebsges.m.b.H.,
- * Manuel Lauss <manuel.lauss@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Au1xxx-PSC I2S glue.
- *
- * NOTE: so far only PSC slave mode (bit- and frameclock) is supported.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/suspend.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-au1x00/au1xxx_psc.h>
-
-#include "psc.h"
-
-/* supported I2S DAI hardware formats */
-#define AU1XPSC_I2S_DAIFMT \
- (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J | \
- SND_SOC_DAIFMT_NB_NF)
-
-/* supported I2S direction */
-#define AU1XPSC_I2S_DIR \
- (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE)
-
-#define AU1XPSC_I2S_RATES \
- SNDRV_PCM_RATE_8000_192000
-
-#define AU1XPSC_I2S_FMTS \
- (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
-
-#define I2SSTAT_BUSY(stype) \
- ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SSTAT_TB : PSC_I2SSTAT_RB)
-#define I2SPCR_START(stype) \
- ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SPCR_TS : PSC_I2SPCR_RS)
-#define I2SPCR_STOP(stype) \
- ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SPCR_TP : PSC_I2SPCR_RP)
-#define I2SPCR_CLRFIFO(stype) \
- ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SPCR_TC : PSC_I2SPCR_RC)
-
-
-static int au1xpsc_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
- unsigned int fmt)
-{
- struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(cpu_dai);
- unsigned long ct;
- int ret;
-
- ret = -EINVAL;
-
- ct = pscdata->cfg;
-
- ct &= ~(PSC_I2SCFG_XM | PSC_I2SCFG_MLJ); /* left-justified */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- ct |= PSC_I2SCFG_XM; /* enable I2S mode */
- break;
- case SND_SOC_DAIFMT_MSB:
- break;
- case SND_SOC_DAIFMT_LSB:
- ct |= PSC_I2SCFG_MLJ; /* LSB (right-) justified */
- break;
- default:
- goto out;
- }
-
- ct &= ~(PSC_I2SCFG_BI | PSC_I2SCFG_WI); /* IB-IF */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- ct |= PSC_I2SCFG_BI | PSC_I2SCFG_WI;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- ct |= PSC_I2SCFG_BI;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- ct |= PSC_I2SCFG_WI;
- break;
- case SND_SOC_DAIFMT_IB_IF:
- break;
- default:
- goto out;
- }
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM: /* CODEC master */
- ct |= PSC_I2SCFG_MS; /* PSC I2S slave mode */
- break;
- case SND_SOC_DAIFMT_CBS_CFS: /* CODEC slave */
- ct &= ~PSC_I2SCFG_MS; /* PSC I2S Master mode */
- break;
- default:
- goto out;
- }
-
- pscdata->cfg = ct;
- ret = 0;
-out:
- return ret;
-}
-
-static int au1xpsc_i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
-
- int cfgbits;
- unsigned long stat;
-
- /* check if the PSC is already streaming data */
- stat = au_readl(I2S_STAT(pscdata));
- if (stat & (PSC_I2SSTAT_TB | PSC_I2SSTAT_RB)) {
- /* reject parameters not currently set up in hardware */
- cfgbits = au_readl(I2S_CFG(pscdata));
- if ((PSC_I2SCFG_GET_LEN(cfgbits) != params->msbits) ||
- (params_rate(params) != pscdata->rate))
- return -EINVAL;
- } else {
- /* set sample bitdepth */
- pscdata->cfg &= ~(0x1f << 4);
- pscdata->cfg |= PSC_I2SCFG_SET_LEN(params->msbits);
- /* remember current rate for other stream */
- pscdata->rate = params_rate(params);
- }
- return 0;
-}
-
-/* Configure PSC late: on my devel systems the codec is I2S master and
- * supplies the i2sbitclock __AND__ i2sMclk (!) to the PSC unit. ASoC
- * uses aggressive PM and switches the codec off when it is not in use
- * which also means the PSC unit doesn't get any clocks and is therefore
- * dead. That's why this chunk here gets called from the trigger callback
- * because I can be reasonably certain the codec is driving the clocks.
- */
-static int au1xpsc_i2s_configure(struct au1xpsc_audio_data *pscdata)
-{
- unsigned long tmo;
-
- /* bring PSC out of sleep, and configure I2S unit */
- au_writel(PSC_CTRL_ENABLE, PSC_CTRL(pscdata));
- au_sync();
-
- tmo = 1000000;
- while (!(au_readl(I2S_STAT(pscdata)) & PSC_I2SSTAT_SR) && tmo)
- tmo--;
-
- if (!tmo)
- goto psc_err;
-
- au_writel(0, I2S_CFG(pscdata));
- au_sync();
- au_writel(pscdata->cfg | PSC_I2SCFG_DE_ENABLE, I2S_CFG(pscdata));
- au_sync();
-
- /* wait for I2S controller to become ready */
- tmo = 1000000;
- while (!(au_readl(I2S_STAT(pscdata)) & PSC_I2SSTAT_DR) && tmo)
- tmo--;
-
- if (tmo)
- return 0;
-
-psc_err:
- au_writel(0, I2S_CFG(pscdata));
- au_writel(PSC_CTRL_SUSPEND, PSC_CTRL(pscdata));
- au_sync();
- return -ETIMEDOUT;
-}
-
-static int au1xpsc_i2s_start(struct au1xpsc_audio_data *pscdata, int stype)
-{
- unsigned long tmo, stat;
- int ret;
-
- ret = 0;
-
- /* if both TX and RX are idle, configure the PSC */
- stat = au_readl(I2S_STAT(pscdata));
- if (!(stat & (PSC_I2SSTAT_TB | PSC_I2SSTAT_RB))) {
- ret = au1xpsc_i2s_configure(pscdata);
- if (ret)
- goto out;
- }
-
- au_writel(I2SPCR_CLRFIFO(stype), I2S_PCR(pscdata));
- au_sync();
- au_writel(I2SPCR_START(stype), I2S_PCR(pscdata));
- au_sync();
-
- /* wait for start confirmation */
- tmo = 1000000;
- while (!(au_readl(I2S_STAT(pscdata)) & I2SSTAT_BUSY(stype)) && tmo)
- tmo--;
-
- if (!tmo) {
- au_writel(I2SPCR_STOP(stype), I2S_PCR(pscdata));
- au_sync();
- ret = -ETIMEDOUT;
- }
-out:
- return ret;
-}
-
-static int au1xpsc_i2s_stop(struct au1xpsc_audio_data *pscdata, int stype)
-{
- unsigned long tmo, stat;
-
- au_writel(I2SPCR_STOP(stype), I2S_PCR(pscdata));
- au_sync();
-
- /* wait for stop confirmation */
- tmo = 1000000;
- while ((au_readl(I2S_STAT(pscdata)) & I2SSTAT_BUSY(stype)) && tmo)
- tmo--;
-
- /* if both TX and RX are idle, disable PSC */
- stat = au_readl(I2S_STAT(pscdata));
- if (!(stat & (PSC_I2SSTAT_TB | PSC_I2SSTAT_RB))) {
- au_writel(0, I2S_CFG(pscdata));
- au_sync();
- au_writel(PSC_CTRL_SUSPEND, PSC_CTRL(pscdata));
- au_sync();
- }
- return 0;
-}
-
-static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
- int ret, stype = substream->stream;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- ret = au1xpsc_i2s_start(pscdata, stype);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- ret = au1xpsc_i2s_stop(pscdata, stype);
- break;
- default:
- ret = -EINVAL;
- }
- return ret;
-}
-
-static int au1xpsc_i2s_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
- snd_soc_dai_set_dma_data(dai, substream, &pscdata->dmaids[0]);
- return 0;
-}
-
-static const struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = {
- .startup = au1xpsc_i2s_startup,
- .trigger = au1xpsc_i2s_trigger,
- .hw_params = au1xpsc_i2s_hw_params,
- .set_fmt = au1xpsc_i2s_set_fmt,
-};
-
-static const struct snd_soc_dai_driver au1xpsc_i2s_dai_template = {
- .playback = {
- .rates = AU1XPSC_I2S_RATES,
- .formats = AU1XPSC_I2S_FMTS,
- .channels_min = 2,
- .channels_max = 8, /* 2 without external help */
- },
- .capture = {
- .rates = AU1XPSC_I2S_RATES,
- .formats = AU1XPSC_I2S_FMTS,
- .channels_min = 2,
- .channels_max = 8, /* 2 without external help */
- },
- .ops = &au1xpsc_i2s_dai_ops,
-};
-
-static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
-{
- struct resource *iores, *dmares;
- unsigned long sel;
- int ret;
- struct au1xpsc_audio_data *wd;
-
- wd = devm_kzalloc(&pdev->dev, sizeof(struct au1xpsc_audio_data),
- GFP_KERNEL);
- if (!wd)
- return -ENOMEM;
-
- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!iores)
- return -ENODEV;
-
- ret = -EBUSY;
- if (!devm_request_mem_region(&pdev->dev, iores->start,
- resource_size(iores),
- pdev->name))
- return -EBUSY;
-
- wd->mmio = devm_ioremap(&pdev->dev, iores->start,
- resource_size(iores));
- if (!wd->mmio)
- return -EBUSY;
-
- dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!dmares)
- return -EBUSY;
- wd->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start;
-
- dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (!dmares)
- return -EBUSY;
- wd->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start;
-
- /* preserve PSC clock source set up by platform (dev.platform_data
- * is already occupied by soc layer)
- */
- sel = au_readl(PSC_SEL(wd)) & PSC_SEL_CLK_MASK;
- au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
- au_sync();
- au_writel(PSC_SEL_PS_I2SMODE | sel, PSC_SEL(wd));
- au_writel(0, I2S_CFG(wd));
- au_sync();
-
- /* preconfigure: set max rx/tx fifo depths */
- wd->cfg |= PSC_I2SCFG_RT_FIFO8 | PSC_I2SCFG_TT_FIFO8;
-
- /* don't wait for I2S core to become ready now; clocks may not
- * be running yet; depending on clock input for PSC a wait might
- * time out.
- */
-
- /* name the DAI like this device instance ("au1xpsc-i2s.PSCINDEX") */
- memcpy(&wd->dai_drv, &au1xpsc_i2s_dai_template,
- sizeof(struct snd_soc_dai_driver));
- wd->dai_drv.name = dev_name(&pdev->dev);
-
- platform_set_drvdata(pdev, wd);
-
- return snd_soc_register_dai(&pdev->dev, &wd->dai_drv);
-}
-
-static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev)
-{
- struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
-
- snd_soc_unregister_dai(&pdev->dev);
-
- au_writel(0, I2S_CFG(wd));
- au_sync();
- au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
- au_sync();
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int au1xpsc_i2s_drvsuspend(struct device *dev)
-{
- struct au1xpsc_audio_data *wd = dev_get_drvdata(dev);
-
- /* save interesting register and disable PSC */
- wd->pm[0] = au_readl(PSC_SEL(wd));
-
- au_writel(0, I2S_CFG(wd));
- au_sync();
- au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
- au_sync();
-
- return 0;
-}
-
-static int au1xpsc_i2s_drvresume(struct device *dev)
-{
- struct au1xpsc_audio_data *wd = dev_get_drvdata(dev);
-
- /* select I2S mode and PSC clock */
- au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
- au_sync();
- au_writel(0, PSC_SEL(wd));
- au_sync();
- au_writel(wd->pm[0], PSC_SEL(wd));
- au_sync();
-
- return 0;
-}
-
-static struct dev_pm_ops au1xpsci2s_pmops = {
- .suspend = au1xpsc_i2s_drvsuspend,
- .resume = au1xpsc_i2s_drvresume,
-};
-
-#define AU1XPSCI2S_PMOPS &au1xpsci2s_pmops
-
-#else
-
-#define AU1XPSCI2S_PMOPS NULL
-
-#endif
-
-static struct platform_driver au1xpsc_i2s_driver = {
- .driver = {
- .name = "au1xpsc_i2s",
- .owner = THIS_MODULE,
- .pm = AU1XPSCI2S_PMOPS,
- },
- .probe = au1xpsc_i2s_drvprobe,
- .remove = __devexit_p(au1xpsc_i2s_drvremove),
-};
-
-module_platform_driver(au1xpsc_i2s_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Au12x0/Au1550 PSC I2S ALSA ASoC audio driver");
-MODULE_AUTHOR("Manuel Lauss");
diff --git a/ANDROID_3.4.5/sound/soc/au1x/psc.h b/ANDROID_3.4.5/sound/soc/au1x/psc.h
deleted file mode 100644
index b16b2e02..00000000
--- a/ANDROID_3.4.5/sound/soc/au1x/psc.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Alchemy ALSA ASoC audio support.
- *
- * (c) 2007-2011 MSC Vertriebsges.m.b.H.,
- * Manuel Lauss <manuel.lauss@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#ifndef _AU1X_PCM_H
-#define _AU1X_PCM_H
-
-struct au1xpsc_audio_data {
- void __iomem *mmio;
-
- unsigned long cfg;
- unsigned long rate;
-
- struct snd_soc_dai_driver dai_drv;
-
- unsigned long pm[2];
- struct mutex lock;
- int dmaids[2];
-};
-
-/* easy access macros */
-#define PSC_CTRL(x) ((unsigned long)((x)->mmio) + PSC_CTRL_OFFSET)
-#define PSC_SEL(x) ((unsigned long)((x)->mmio) + PSC_SEL_OFFSET)
-#define I2S_STAT(x) ((unsigned long)((x)->mmio) + PSC_I2SSTAT_OFFSET)
-#define I2S_CFG(x) ((unsigned long)((x)->mmio) + PSC_I2SCFG_OFFSET)
-#define I2S_PCR(x) ((unsigned long)((x)->mmio) + PSC_I2SPCR_OFFSET)
-#define AC97_CFG(x) ((unsigned long)((x)->mmio) + PSC_AC97CFG_OFFSET)
-#define AC97_CDC(x) ((unsigned long)((x)->mmio) + PSC_AC97CDC_OFFSET)
-#define AC97_EVNT(x) ((unsigned long)((x)->mmio) + PSC_AC97EVNT_OFFSET)
-#define AC97_PCR(x) ((unsigned long)((x)->mmio) + PSC_AC97PCR_OFFSET)
-#define AC97_RST(x) ((unsigned long)((x)->mmio) + PSC_AC97RST_OFFSET)
-#define AC97_STAT(x) ((unsigned long)((x)->mmio) + PSC_AC97STAT_OFFSET)
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/Kconfig b/ANDROID_3.4.5/sound/soc/blackfin/Kconfig
deleted file mode 100644
index 9f6bc55f..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/Kconfig
+++ /dev/null
@@ -1,181 +0,0 @@
-config SND_BF5XX_I2S
- tristate "SoC I2S Audio for the ADI BF5xx chip"
- depends on BLACKFIN
- select SND_BF5XX_SOC_SPORT
- help
- Say Y or M if you want to add support for codecs attached to
- the Blackfin SPORT (synchronous serial ports) interface in I2S
- mode (supports single stereo In/Out).
- You will also need to select the audio interfaces to support below.
-
-config SND_BF5XX_SOC_SSM2602
- tristate "SoC SSM2602 Audio support for BF52x ezkit"
- depends on SND_BF5XX_I2S && (SPI_MASTER || I2C)
- select SND_BF5XX_SOC_I2S
- select SND_SOC_SSM2602
- help
- Say Y if you want to add support for SoC audio on BF527-EZKIT.
-
-config SND_SOC_BFIN_EVAL_ADAU1701
- tristate "Support for the EVAL-ADAU1701MINIZ board on Blackfin eval boards"
- depends on SND_BF5XX_I2S
- select SND_BF5XX_SOC_I2S
- select SND_SOC_ADAU1701
- select I2C
- help
- Say Y if you want to add support for the Analog Devices EVAL-ADAU1701MINIZ
- board connected to one of the Blackfin evaluation boards like the
- BF5XX-STAMP or BF5XX-EZKIT.
-
-config SND_SOC_BFIN_EVAL_ADAU1373
- tristate "Support for the EVAL-ADAU1373 board on Blackfin eval boards"
- depends on SND_BF5XX_I2S && I2C
- select SND_BF5XX_SOC_I2S
- select SND_SOC_ADAU1373
- help
- Say Y if you want to add support for the Analog Devices EVAL-ADAU1373
- board connected to one of the Blackfin evaluation boards like the
- BF5XX-STAMP or BF5XX-EZKIT.
-
- Note: This driver assumes that first ADAU1373 DAI is connected to the
- first SPORT port on the BF5XX board.
-
-config SND_SOC_BFIN_EVAL_ADAV80X
- tristate "Support for the EVAL-ADAV80X boards on Blackfin eval boards"
- depends on SND_BF5XX_I2S && (SPI_MASTER || I2C)
- select SND_BF5XX_SOC_I2S
- select SND_SOC_ADAV80X
- help
- Say Y if you want to add support for the Analog Devices EVAL-ADAV801 or
- EVAL-ADAV803 board connected to one of the Blackfin evaluation boards
- like the BF5XX-STAMP or BF5XX-EZKIT.
-
- Note: This driver assumes that the ADAV80X digital record and playback
- interfaces are connected to the first SPORT port on the BF5XX board.
-
-config SND_BF5XX_SOC_AD73311
- tristate "SoC AD73311 Audio support for Blackfin"
- depends on SND_BF5XX_I2S
- select SND_BF5XX_SOC_I2S
- select SND_SOC_AD73311
- help
- Say Y if you want to add support for AD73311 codec on Blackfin.
-
-config SND_BFIN_AD73311_SE
- int "PF pin for AD73311L Chip Select"
- depends on SND_BF5XX_SOC_AD73311
- default 4
- help
- Enter the GPIO used to control AD73311's SE pin. Acceptable
- values are 0 to 7
-
-config SND_BF5XX_TDM
- tristate "SoC I2S(TDM mode) Audio for the ADI BF5xx chip"
- depends on (BLACKFIN && SND_SOC)
- select SND_BF5XX_SOC_SPORT
- help
- Say Y or M if you want to add support for codecs attached to
- the Blackfin SPORT (synchronous serial ports) interface in TDM
- mode.
- You will also need to select the audio interfaces to support below.
-
-config SND_BF5XX_SOC_AD1836
- tristate "SoC AD1836 Audio support for BF5xx"
- depends on SND_BF5XX_TDM
- select SND_BF5XX_SOC_TDM
- select SND_SOC_AD1836
- help
- Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
-
-config SND_BF5XX_SOC_AD193X
- tristate "SoC AD193X Audio support for Blackfin"
- depends on SND_BF5XX_TDM
- select SND_BF5XX_SOC_TDM
- select SND_SOC_AD193X
- help
- Say Y if you want to add support for AD193X codec on Blackfin.
- This driver supports AD1936, AD1937, AD1938 and AD1939.
-
-config SND_BF5XX_AC97
- tristate "SoC AC97 Audio for the ADI BF5xx chip"
- depends on BLACKFIN
- select AC97_BUS
- select SND_SOC_AC97_BUS
- select SND_BF5XX_SOC_SPORT
- select SND_BF5XX_SOC_AC97
- help
- Say Y or M if you want to add support for codecs attached to
- the Blackfin SPORT (synchronous serial ports) interface in slot 16
- mode (pseudo AC97 interface).
- You will also need to select the audio interfaces to support below.
-
- Note:
- AC97 codecs which do not implement the slot-16 mode will not function
- properly with this driver. This driver is known to work with the
- Analog Devices line of AC97 codecs.
-
-config SND_BF5XX_MMAP_SUPPORT
- bool "Enable MMAP Support"
- depends on SND_BF5XX_AC97
- default y
- help
- Say y if you want AC97 driver to support mmap mode.
- We introduce an intermediate buffer to simulate mmap.
-
-config SND_BF5XX_MULTICHAN_SUPPORT
- bool "Enable Multichannel Support"
- depends on SND_BF5XX_AC97
- default n
- help
- Say y if you want AC97 driver to support up to 5.1 channel audio.
- this mode will consume much more memory for DMA.
-
-config SND_BF5XX_HAVE_COLD_RESET
- bool "BOARD has COLD Reset GPIO"
- depends on SND_BF5XX_AC97
- default y if BFIN548_EZKIT
- default n if !BFIN548_EZKIT
-
-config SND_BF5XX_RESET_GPIO_NUM
- int "Set a GPIO for cold reset"
- depends on SND_BF5XX_HAVE_COLD_RESET
- range 0 159
- default 19 if BFIN548_EZKIT
- default 5 if BFIN537_STAMP
- default 0
- help
- Set the correct GPIO for RESET the sound chip.
-
-config SND_BF5XX_SOC_AD1980
- tristate "SoC AD1980/1 Audio support for BF5xx (Obsolete)"
- depends on SND_BF5XX_AC97
- select SND_BF5XX_SOC_AC97
- select SND_SOC_AD1980
- help
- Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
-
- Warning:
- Because Analog Devices Inc. discontinued the ad1980 sound chip since
- Sep. 2009, this ad1980 driver is not maintained, tested and supported
- by ADI now.
-
-config SND_BF5XX_SOC_SPORT
- tristate
-
-config SND_BF5XX_SOC_I2S
- tristate
-
-config SND_BF5XX_SOC_TDM
- tristate
-
-config SND_BF5XX_SOC_AC97
- tristate
-
-config SND_BF5XX_SPORT_NUM
- int "Set a SPORT for Sound chip"
- depends on (SND_BF5XX_I2S || SND_BF5XX_AC97 || SND_BF5XX_TDM)
- range 0 3 if BF54x
- range 0 1 if !BF54x
- default 0
- help
- Set the correct SPORT for sound chip.
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/Makefile b/ANDROID_3.4.5/sound/soc/blackfin/Makefile
deleted file mode 100644
index 1bf86cca..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-# Blackfin Platform Support
-snd-bf5xx-ac97-objs := bf5xx-ac97-pcm.o
-snd-bf5xx-i2s-objs := bf5xx-i2s-pcm.o
-snd-bf5xx-tdm-objs := bf5xx-tdm-pcm.o
-snd-soc-bf5xx-sport-objs := bf5xx-sport.o
-snd-soc-bf5xx-ac97-objs := bf5xx-ac97.o
-snd-soc-bf5xx-i2s-objs := bf5xx-i2s.o
-snd-soc-bf5xx-tdm-objs := bf5xx-tdm.o
-
-obj-$(CONFIG_SND_BF5XX_AC97) += snd-bf5xx-ac97.o
-obj-$(CONFIG_SND_BF5XX_I2S) += snd-bf5xx-i2s.o
-obj-$(CONFIG_SND_BF5XX_TDM) += snd-bf5xx-tdm.o
-obj-$(CONFIG_SND_BF5XX_SOC_SPORT) += snd-soc-bf5xx-sport.o
-obj-$(CONFIG_SND_BF5XX_SOC_AC97) += snd-soc-bf5xx-ac97.o
-obj-$(CONFIG_SND_BF5XX_SOC_I2S) += snd-soc-bf5xx-i2s.o
-obj-$(CONFIG_SND_BF5XX_SOC_TDM) += snd-soc-bf5xx-tdm.o
-
-# Blackfin Machine Support
-snd-ad1836-objs := bf5xx-ad1836.o
-snd-ad1980-objs := bf5xx-ad1980.o
-snd-ssm2602-objs := bf5xx-ssm2602.o
-snd-ad73311-objs := bf5xx-ad73311.o
-snd-ad193x-objs := bf5xx-ad193x.o
-snd-soc-bfin-eval-adau1373-objs := bfin-eval-adau1373.o
-snd-soc-bfin-eval-adau1701-objs := bfin-eval-adau1701.o
-snd-soc-bfin-eval-adav80x-objs := bfin-eval-adav80x.o
-
-obj-$(CONFIG_SND_BF5XX_SOC_AD1836) += snd-ad1836.o
-obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o
-obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o
-obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o
-obj-$(CONFIG_SND_BF5XX_SOC_AD193X) += snd-ad193x.o
-obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1373) += snd-soc-bfin-eval-adau1373.o
-obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1701) += snd-soc-bfin-eval-adau1701.o
-obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAV80X) += snd-soc-bfin-eval-adav80x.o
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ac97-pcm.c b/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ac97-pcm.c
deleted file mode 100644
index d7dc9bde..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- * File: sound/soc/blackfin/bf5xx-ac97-pcm.c
- * Author: Cliff Cai <Cliff.Cai@analog.com>
- *
- * Created: Tue June 06 2008
- * Description: DMA Driver for AC97 sound chip
- *
- * Modified:
- * Copyright 2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/gfp.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/dma.h>
-
-#include "bf5xx-ac97-pcm.h"
-#include "bf5xx-ac97.h"
-#include "bf5xx-sport.h"
-
-static unsigned int ac97_chan_mask[] = {
- SP_FL, /* Mono */
- SP_STEREO, /* Stereo */
- SP_2DOT1, /* 2.1*/
- SP_QUAD,/*Quadraquic*/
- SP_FL | SP_FR | SP_FC | SP_SL | SP_SR,/*5 channels */
- SP_5DOT1, /* 5.1 */
-};
-
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-static void bf5xx_mmap_copy(struct snd_pcm_substream *substream,
- snd_pcm_uframes_t count)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct sport_device *sport = runtime->private_data;
- unsigned int chan_mask = ac97_chan_mask[runtime->channels - 1];
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- bf5xx_pcm_to_ac97((struct ac97_frame *)sport->tx_dma_buf +
- sport->tx_pos, (__u16 *)runtime->dma_area + sport->tx_pos *
- runtime->channels, count, chan_mask);
- sport->tx_pos += runtime->period_size;
- if (sport->tx_pos >= runtime->buffer_size)
- sport->tx_pos %= runtime->buffer_size;
- sport->tx_delay_pos = sport->tx_pos;
- } else {
- bf5xx_ac97_to_pcm((struct ac97_frame *)sport->rx_dma_buf +
- sport->rx_pos, (__u16 *)runtime->dma_area + sport->rx_pos *
- runtime->channels, count);
- sport->rx_pos += runtime->period_size;
- if (sport->rx_pos >= runtime->buffer_size)
- sport->rx_pos %= runtime->buffer_size;
- }
-}
-#endif
-
-static void bf5xx_dma_irq(void *data)
-{
- struct snd_pcm_substream *pcm = data;
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
- struct snd_pcm_runtime *runtime = pcm->runtime;
- struct sport_device *sport = runtime->private_data;
- bf5xx_mmap_copy(pcm, runtime->period_size);
- if (pcm->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (sport->once == 0) {
- snd_pcm_period_elapsed(pcm);
- bf5xx_mmap_copy(pcm, runtime->period_size);
- sport->once = 1;
- }
- }
-#endif
- snd_pcm_period_elapsed(pcm);
-}
-
-/* The memory size for pure pcm data is 128*1024 = 0x20000 bytes.
- * The total rx/tx buffer is for ac97 frame to hold all pcm data
- * is 0x20000 * sizeof(struct ac97_frame) / 4.
- */
-static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
- .info = SNDRV_PCM_INFO_INTERLEAVED |
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
-#endif
- SNDRV_PCM_INFO_BLOCK_TRANSFER,
-
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .period_bytes_min = 32,
- .period_bytes_max = 0x10000,
- .periods_min = 1,
- .periods_max = PAGE_SIZE/32,
- .buffer_bytes_max = 0x20000, /* 128 kbytes */
- .fifo_size = 16,
-};
-
-static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- size_t size = bf5xx_pcm_hardware.buffer_bytes_max
- * sizeof(struct ac97_frame) / 4;
-
- snd_pcm_lib_malloc_pages(substream, size);
-
- return 0;
-}
-
-static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
-{
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct sport_device *sport = runtime->private_data;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- sport->once = 0;
- if (runtime->dma_area)
- memset(runtime->dma_area, 0, runtime->buffer_size);
- memset(sport->tx_dma_buf, 0, runtime->buffer_size *
- sizeof(struct ac97_frame));
- } else
- memset(sport->rx_dma_buf, 0, runtime->buffer_size *
- sizeof(struct ac97_frame));
-#endif
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct sport_device *sport = runtime->private_data;
-
- /* An intermediate buffer is introduced for implementing mmap for
- * SPORT working in TMD mode(include AC97).
- */
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
- sport_config_tx_dma(sport, sport->tx_dma_buf, runtime->periods,
- runtime->period_size * sizeof(struct ac97_frame));
- } else {
- sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
- sport_config_rx_dma(sport, sport->rx_dma_buf, runtime->periods,
- runtime->period_size * sizeof(struct ac97_frame));
- }
-#else
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
- sport_config_tx_dma(sport, runtime->dma_area, runtime->periods,
- runtime->period_size * sizeof(struct ac97_frame));
- } else {
- sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
- sport_config_rx_dma(sport, runtime->dma_area, runtime->periods,
- runtime->period_size * sizeof(struct ac97_frame));
- }
-#endif
- return 0;
-}
-
-static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct sport_device *sport = runtime->private_data;
- int ret = 0;
-
- pr_debug("%s enter\n", __func__);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
- bf5xx_mmap_copy(substream, runtime->period_size);
- sport->tx_delay_pos = 0;
-#endif
- sport_tx_start(sport);
- } else
- sport_rx_start(sport);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
- sport->tx_pos = 0;
-#endif
- sport_tx_stop(sport);
- } else {
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
- sport->rx_pos = 0;
-#endif
- sport_rx_stop(sport);
- }
- break;
- default:
- ret = -EINVAL;
- }
- return ret;
-}
-
-static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct sport_device *sport = runtime->private_data;
- unsigned int curr;
-
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- curr = sport->tx_delay_pos;
- else
- curr = sport->rx_pos;
-#else
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- curr = sport_curr_offset_tx(sport) / sizeof(struct ac97_frame);
- else
- curr = sport_curr_offset_rx(sport) / sizeof(struct ac97_frame);
-
-#endif
- return curr;
-}
-
-static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int ret;
-
- pr_debug("%s enter\n", __func__);
- snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
-
- ret = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (ret < 0)
- goto out;
-
- if (sport_handle != NULL)
- runtime->private_data = sport_handle;
- else {
- pr_err("sport_handle is NULL\n");
- return -1;
- }
- return 0;
-
- out:
- return ret;
-}
-
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- size_t size = vma->vm_end - vma->vm_start;
- vma->vm_start = (unsigned long)runtime->dma_area;
- vma->vm_end = vma->vm_start + size;
- vma->vm_flags |= VM_SHARED;
- return 0 ;
-}
-#else
-static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
- snd_pcm_uframes_t pos,
- void __user *buf, snd_pcm_uframes_t count)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int chan_mask = ac97_chan_mask[runtime->channels - 1];
- pr_debug("%s copy pos:0x%lx count:0x%lx\n",
- substream->stream ? "Capture" : "Playback", pos, count);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- bf5xx_pcm_to_ac97((struct ac97_frame *)runtime->dma_area + pos,
- (__u16 *)buf, count, chan_mask);
- else
- bf5xx_ac97_to_pcm((struct ac97_frame *)runtime->dma_area + pos,
- (__u16 *)buf, count);
- return 0;
-}
-#endif
-
-static struct snd_pcm_ops bf5xx_pcm_ac97_ops = {
- .open = bf5xx_pcm_open,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = bf5xx_pcm_hw_params,
- .hw_free = bf5xx_pcm_hw_free,
- .prepare = bf5xx_pcm_prepare,
- .trigger = bf5xx_pcm_trigger,
- .pointer = bf5xx_pcm_pointer,
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
- .mmap = bf5xx_pcm_mmap,
-#else
- .copy = bf5xx_pcm_copy,
-#endif
-};
-
-static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
- struct snd_soc_pcm_runtime *rtd = pcm->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
- struct snd_pcm_substream *substream = pcm->streams[stream].substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = bf5xx_pcm_hardware.buffer_bytes_max
- * sizeof(struct ac97_frame) / 4;
-
- buf->dev.type = SNDRV_DMA_TYPE_DEV;
- buf->dev.dev = pcm->card->dev;
- buf->private_data = NULL;
- buf->area = dma_alloc_coherent(pcm->card->dev, size,
- &buf->addr, GFP_KERNEL);
- if (!buf->area) {
- pr_err("Failed to allocate dma memory\n");
- pr_err("Please increase uncached DMA memory region\n");
- return -ENOMEM;
- }
- buf->bytes = size;
-
- pr_debug("%s, area:%p, size:0x%08lx\n", __func__,
- buf->area, buf->bytes);
-
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
- sport_handle->tx_buf = buf->area;
- else
- sport_handle->rx_buf = buf->area;
-
-/*
- * Need to allocate local buffer when enable
- * MMAP for SPORT working in TMD mode (include AC97).
- */
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (!sport_handle->tx_dma_buf) {
- sport_handle->tx_dma_buf = dma_alloc_coherent(NULL, \
- size, &sport_handle->tx_dma_phy, GFP_KERNEL);
- if (!sport_handle->tx_dma_buf) {
- pr_err("Failed to allocate memory for tx dma buf - Please increase uncached DMA memory region\n");
- return -ENOMEM;
- } else
- memset(sport_handle->tx_dma_buf, 0, size);
- } else
- memset(sport_handle->tx_dma_buf, 0, size);
- } else {
- if (!sport_handle->rx_dma_buf) {
- sport_handle->rx_dma_buf = dma_alloc_coherent(NULL, \
- size, &sport_handle->rx_dma_phy, GFP_KERNEL);
- if (!sport_handle->rx_dma_buf) {
- pr_err("Failed to allocate memory for rx dma buf - Please increase uncached DMA memory region\n");
- return -ENOMEM;
- } else
- memset(sport_handle->rx_dma_buf, 0, size);
- } else
- memset(sport_handle->rx_dma_buf, 0, size);
- }
-#endif
- return 0;
-}
-
-static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- struct snd_dma_buffer *buf;
- int stream;
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
- struct snd_soc_pcm_runtime *rtd = pcm->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
- size_t size = bf5xx_pcm_hardware.buffer_bytes_max *
- sizeof(struct ac97_frame) / 4;
-#endif
- for (stream = 0; stream < 2; stream++) {
- substream = pcm->streams[stream].substream;
- if (!substream)
- continue;
-
- buf = &substream->dma_buffer;
- if (!buf->area)
- continue;
- dma_free_coherent(NULL, buf->bytes, buf->area, 0);
- buf->area = NULL;
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (sport_handle->tx_dma_buf)
- dma_free_coherent(NULL, size, \
- sport_handle->tx_dma_buf, 0);
- sport_handle->tx_dma_buf = NULL;
- } else {
-
- if (sport_handle->rx_dma_buf)
- dma_free_coherent(NULL, size, \
- sport_handle->rx_dma_buf, 0);
- sport_handle->rx_dma_buf = NULL;
- }
-#endif
- }
-}
-
-static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
-
-static int bf5xx_pcm_ac97_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- int ret = 0;
-
- pr_debug("%s enter\n", __func__);
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &bf5xx_pcm_dmamask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_PLAYBACK);
- if (ret)
- goto out;
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_CAPTURE);
- if (ret)
- goto out;
- }
- out:
- return ret;
-}
-
-static struct snd_soc_platform_driver bf5xx_ac97_soc_platform = {
- .ops = &bf5xx_pcm_ac97_ops,
- .pcm_new = bf5xx_pcm_ac97_new,
- .pcm_free = bf5xx_pcm_free_dma_buffers,
-};
-
-static int __devinit bf5xx_soc_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_platform(&pdev->dev, &bf5xx_ac97_soc_platform);
-}
-
-static int __devexit bf5xx_soc_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver bf5xx_pcm_driver = {
- .driver = {
- .name = "bfin-ac97-pcm-audio",
- .owner = THIS_MODULE,
- },
-
- .probe = bf5xx_soc_platform_probe,
- .remove = __devexit_p(bf5xx_soc_platform_remove),
-};
-
-module_platform_driver(bf5xx_pcm_driver);
-
-MODULE_AUTHOR("Cliff Cai");
-MODULE_DESCRIPTION("ADI Blackfin AC97 PCM DMA module");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ac97-pcm.h b/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ac97-pcm.h
deleted file mode 100644
index d324d582..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ac97-pcm.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * linux/sound/arm/bf5xx-ac97-pcm.h -- ALSA PCM interface for the Blackfin
- *
- * Copyright 2007 Analog Device Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _BF5XX_AC97_PCM_H
-#define _BF5XX_AC97_PCM_H
-
-struct bf5xx_pcm_dma_params {
- char *name; /* stream identifier */
-};
-
-struct bf5xx_gpio {
- u32 sys;
- u32 rx;
- u32 tx;
- u32 clk;
- u32 frm;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ac97.c b/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ac97.c
deleted file mode 100644
index f4e9dc4e..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ac97.c
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * bf5xx-ac97.c -- AC97 support for the ADI blackfin chip.
- *
- * Author: Roy Huang
- * Created: 11th. June 2007
- * Copyright: Analog Device Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include <asm/irq.h>
-#include <asm/portmux.h>
-#include <linux/mutex.h>
-#include <linux/gpio.h>
-
-#include "bf5xx-sport.h"
-#include "bf5xx-ac97.h"
-
-/* Anomaly notes:
- * 05000250 - AD1980 is running in TDM mode and RFS/TFS are generated by SPORT
- * contrtoller. But, RFSDIV and TFSDIV are always set to 16*16-1,
- * while the max AC97 data size is 13*16. The DIV is always larger
- * than data size. AD73311 and ad2602 are not running in TDM mode.
- * AD1836 and AD73322 depend on external RFS/TFS only. So, this
- * anomaly does not affect blackfin sound drivers.
-*/
-
-static struct sport_device *ac97_sport_handle;
-
-void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src,
- size_t count, unsigned int chan_mask)
-{
- while (count--) {
- dst->ac97_tag = TAG_VALID;
- if (chan_mask & SP_FL) {
- dst->ac97_pcm_r = *src++;
- dst->ac97_tag |= TAG_PCM_RIGHT;
- }
- if (chan_mask & SP_FR) {
- dst->ac97_pcm_l = *src++;
- dst->ac97_tag |= TAG_PCM_LEFT;
-
- }
-#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
- if (chan_mask & SP_SR) {
- dst->ac97_sl = *src++;
- dst->ac97_tag |= TAG_PCM_SL;
- }
- if (chan_mask & SP_SL) {
- dst->ac97_sr = *src++;
- dst->ac97_tag |= TAG_PCM_SR;
- }
- if (chan_mask & SP_LFE) {
- dst->ac97_lfe = *src++;
- dst->ac97_tag |= TAG_PCM_LFE;
- }
- if (chan_mask & SP_FC) {
- dst->ac97_center = *src++;
- dst->ac97_tag |= TAG_PCM_CENTER;
- }
-#endif
- dst++;
- }
-}
-EXPORT_SYMBOL(bf5xx_pcm_to_ac97);
-
-void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u16 *dst,
- size_t count)
-{
- while (count--) {
- *(dst++) = src->ac97_pcm_l;
- *(dst++) = src->ac97_pcm_r;
- src++;
- }
-}
-EXPORT_SYMBOL(bf5xx_ac97_to_pcm);
-
-static unsigned int sport_tx_curr_frag(struct sport_device *sport)
-{
- return sport->tx_curr_frag = sport_curr_offset_tx(sport) /
- sport->tx_fragsize;
-}
-
-static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data)
-{
- struct sport_device *sport = ac97_sport_handle;
- int *cmd_count = sport->private_data;
- int nextfrag = sport_tx_curr_frag(sport);
- struct ac97_frame *nextwrite;
-
- sport_incfrag(sport, &nextfrag, 1);
-
- nextwrite = (struct ac97_frame *)(sport->tx_buf +
- nextfrag * sport->tx_fragsize);
- pr_debug("sport->tx_buf:%p, nextfrag:0x%x nextwrite:%p, cmd_count:%d\n",
- sport->tx_buf, nextfrag, nextwrite, cmd_count[nextfrag]);
- nextwrite[cmd_count[nextfrag]].ac97_tag |= TAG_CMD;
- nextwrite[cmd_count[nextfrag]].ac97_addr = addr;
- nextwrite[cmd_count[nextfrag]].ac97_data = data;
- ++cmd_count[nextfrag];
- pr_debug("ac97_sport: Inserting %02x/%04x into fragment %d\n",
- addr >> 8, data, nextfrag);
-}
-
-static unsigned short bf5xx_ac97_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- struct sport_device *sport_handle = ac97_sport_handle;
- struct ac97_frame out_frame[2], in_frame[2];
-
- pr_debug("%s enter 0x%x\n", __func__, reg);
-
- /* When dma descriptor is enabled, the register should not be read */
- if (sport_handle->tx_run || sport_handle->rx_run) {
- pr_err("Could you send a mail to cliff.cai@analog.com "
- "to report this?\n");
- return -EFAULT;
- }
-
- memset(&out_frame, 0, 2 * sizeof(struct ac97_frame));
- memset(&in_frame, 0, 2 * sizeof(struct ac97_frame));
- out_frame[0].ac97_tag = TAG_VALID | TAG_CMD;
- out_frame[0].ac97_addr = ((reg << 8) | 0x8000);
- sport_send_and_recv(sport_handle, (unsigned char *)&out_frame,
- (unsigned char *)&in_frame,
- 2 * sizeof(struct ac97_frame));
- return in_frame[1].ac97_data;
-}
-
-void bf5xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short val)
-{
- struct sport_device *sport_handle = ac97_sport_handle;
-
- pr_debug("%s enter 0x%x:0x%04x\n", __func__, reg, val);
-
- if (sport_handle->tx_run) {
- enqueue_cmd(ac97, (reg << 8), val); /* write */
- enqueue_cmd(ac97, (reg << 8) | 0x8000, 0); /* read back */
- } else {
- struct ac97_frame frame;
- memset(&frame, 0, sizeof(struct ac97_frame));
- frame.ac97_tag = TAG_VALID | TAG_CMD;
- frame.ac97_addr = (reg << 8);
- frame.ac97_data = val;
- sport_send_and_recv(sport_handle, (unsigned char *)&frame, \
- NULL, sizeof(struct ac97_frame));
- }
-}
-
-static void bf5xx_ac97_warm_reset(struct snd_ac97 *ac97)
-{
- struct sport_device *sport_handle = ac97_sport_handle;
- u16 gpio = P_IDENT(sport_handle->pin_req[3]);
-
- pr_debug("%s enter\n", __func__);
-
- peripheral_free_list(sport_handle->pin_req);
- gpio_request(gpio, "bf5xx-ac97");
- gpio_direction_output(gpio, 1);
- udelay(2);
- gpio_set_value(gpio, 0);
- udelay(1);
- gpio_free(gpio);
- peripheral_request_list(sport_handle->pin_req, "soc-audio");
-}
-
-static void bf5xx_ac97_cold_reset(struct snd_ac97 *ac97)
-{
-#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
- pr_debug("%s enter\n", __func__);
-
- /* It is specified for bf548-ezkit */
- gpio_set_value(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 0);
- /* Keep reset pin low for 1 ms */
- mdelay(1);
- gpio_set_value(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1);
- /* Wait for bit clock recover */
- mdelay(1);
-#else
- pr_info("%s: Not implemented\n", __func__);
-#endif
-}
-
-struct snd_ac97_bus_ops soc_ac97_ops = {
- .read = bf5xx_ac97_read,
- .write = bf5xx_ac97_write,
- .warm_reset = bf5xx_ac97_warm_reset,
- .reset = bf5xx_ac97_cold_reset,
-};
-EXPORT_SYMBOL_GPL(soc_ac97_ops);
-
-#ifdef CONFIG_PM
-static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
-{
- struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
-
- pr_debug("%s : sport %d\n", __func__, dai->id);
- if (!dai->active)
- return 0;
- if (dai->capture_active)
- sport_rx_stop(sport);
- if (dai->playback_active)
- sport_tx_stop(sport);
- return 0;
-}
-
-static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
-{
- int ret;
- struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
-
- pr_debug("%s : sport %d\n", __func__, dai->id);
- if (!dai->active)
- return 0;
-
-#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
- ret = sport_set_multichannel(sport, 16, 0x3FF, 1);
-#else
- ret = sport_set_multichannel(sport, 16, 0x1F, 1);
-#endif
- if (ret) {
- pr_err("SPORT is busy!\n");
- return -EBUSY;
- }
-
- ret = sport_config_rx(sport, IRFS, 0xF, 0, (16*16-1));
- if (ret) {
- pr_err("SPORT is busy!\n");
- return -EBUSY;
- }
-
- ret = sport_config_tx(sport, ITFS, 0xF, 0, (16*16-1));
- if (ret) {
- pr_err("SPORT is busy!\n");
- return -EBUSY;
- }
-
- return 0;
-}
-
-#else
-#define bf5xx_ac97_suspend NULL
-#define bf5xx_ac97_resume NULL
-#endif
-
-static struct snd_soc_dai_driver bfin_ac97_dai = {
- .ac97_control = 1,
- .suspend = bf5xx_ac97_suspend,
- .resume = bf5xx_ac97_resume,
- .playback = {
- .stream_name = "AC97 Playback",
- .channels_min = 2,
-#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
- .channels_max = 6,
-#else
- .channels_max = 2,
-#endif
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE, },
- .capture = {
- .stream_name = "AC97 Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE, },
-};
-
-static int __devinit asoc_bfin_ac97_probe(struct platform_device *pdev)
-{
- struct sport_device *sport_handle;
- int ret;
-
-#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
- /* Request PB3 as reset pin */
- if (gpio_request(CONFIG_SND_BF5XX_RESET_GPIO_NUM, "SND_AD198x RESET")) {
- pr_err("Failed to request GPIO_%d for reset\n",
- CONFIG_SND_BF5XX_RESET_GPIO_NUM);
- ret = -1;
- goto gpio_err;
- }
- gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1);
-#endif
-
- sport_handle = sport_init(pdev, 2, sizeof(struct ac97_frame),
- PAGE_SIZE);
- if (!sport_handle) {
- ret = -ENODEV;
- goto sport_err;
- }
-
- /*SPORT works in TDM mode to simulate AC97 transfers*/
-#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
- ret = sport_set_multichannel(sport_handle, 16, 0x3FF, 1);
-#else
- ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1);
-#endif
- if (ret) {
- pr_err("SPORT is busy!\n");
- ret = -EBUSY;
- goto sport_config_err;
- }
-
- ret = sport_config_rx(sport_handle, IRFS, 0xF, 0, (16*16-1));
- if (ret) {
- pr_err("SPORT is busy!\n");
- ret = -EBUSY;
- goto sport_config_err;
- }
-
- ret = sport_config_tx(sport_handle, ITFS, 0xF, 0, (16*16-1));
- if (ret) {
- pr_err("SPORT is busy!\n");
- ret = -EBUSY;
- goto sport_config_err;
- }
-
- ret = snd_soc_register_dai(&pdev->dev, &bfin_ac97_dai);
- if (ret) {
- pr_err("Failed to register DAI: %d\n", ret);
- goto sport_config_err;
- }
-
- ac97_sport_handle = sport_handle;
-
- return 0;
-
-sport_config_err:
- sport_done(sport_handle);
-sport_err:
-#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
- gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
-gpio_err:
-#endif
-
- return ret;
-}
-
-static int __devexit asoc_bfin_ac97_remove(struct platform_device *pdev)
-{
- struct sport_device *sport_handle = platform_get_drvdata(pdev);
-
- snd_soc_unregister_dai(&pdev->dev);
- sport_done(sport_handle);
-#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
- gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
-#endif
-
- return 0;
-}
-
-static struct platform_driver asoc_bfin_ac97_driver = {
- .driver = {
- .name = "bfin-ac97",
- .owner = THIS_MODULE,
- },
-
- .probe = asoc_bfin_ac97_probe,
- .remove = __devexit_p(asoc_bfin_ac97_remove),
-};
-
-module_platform_driver(asoc_bfin_ac97_driver);
-
-MODULE_AUTHOR("Roy Huang");
-MODULE_DESCRIPTION("AC97 driver for ADI Blackfin");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ac97.h b/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ac97.h
deleted file mode 100644
index 15c635e3..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ac97.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * sound/soc/blackfin/bf5xx-ac97.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _BF5XX_AC97_H
-#define _BF5XX_AC97_H
-
-extern struct snd_ac97_bus_ops bf5xx_ac97_ops;
-extern struct snd_ac97 *ac97;
-/* Frame format in memory, only support stereo currently */
-struct ac97_frame {
- u16 ac97_tag; /* slot 0 */
- u16 ac97_addr; /* slot 1 */
- u16 ac97_data; /* slot 2 */
- u16 ac97_pcm_l; /*slot 3:front left*/
- u16 ac97_pcm_r; /*slot 4:front left*/
-#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
- u16 ac97_mdm_l1;
- u16 ac97_center; /*slot 6:center*/
- u16 ac97_sl; /*slot 7:surround left*/
- u16 ac97_sr; /*slot 8:surround right*/
- u16 ac97_lfe; /*slot 9:lfe*/
-#endif
-} __attribute__ ((packed));
-
-/* Speaker location */
-#define SP_FL 0x0001
-#define SP_FR 0x0010
-#define SP_FC 0x0002
-#define SP_LFE 0x0020
-#define SP_SL 0x0004
-#define SP_SR 0x0040
-
-#define SP_STEREO (SP_FL | SP_FR)
-#define SP_2DOT1 (SP_FL | SP_FR | SP_LFE)
-#define SP_QUAD (SP_FL | SP_FR | SP_SL | SP_SR)
-#define SP_5DOT1 (SP_FL | SP_FR | SP_FC | SP_LFE | SP_SL | SP_SR)
-
-#define TAG_VALID 0x8000
-#define TAG_CMD 0x6000
-#define TAG_PCM_LEFT 0x1000
-#define TAG_PCM_RIGHT 0x0800
-#define TAG_PCM_MDM_L1 0x0400
-#define TAG_PCM_CENTER 0x0200
-#define TAG_PCM_SL 0x0100
-#define TAG_PCM_SR 0x0080
-#define TAG_PCM_LFE 0x0040
-
-void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src, \
- size_t count, unsigned int chan_mask);
-
-void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u16 *dst, \
- size_t count);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ad1836.c b/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ad1836.c
deleted file mode 100644
index d542d406..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ad1836.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * File: sound/soc/blackfin/bf5xx-ad1836.c
- * Author: Barry Song <Barry.Song@analog.com>
- *
- * Created: Aug 4 2009
- * Description: Board driver for ad1836 sound chip
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <asm/blackfin.h>
-#include <asm/cacheflush.h>
-#include <asm/irq.h>
-#include <asm/dma.h>
-#include <asm/portmux.h>
-
-#include "../codecs/ad1836.h"
-
-#include "bf5xx-tdm-pcm.h"
-#include "bf5xx-tdm.h"
-
-static struct snd_soc_card bf5xx_ad1836;
-
-static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7};
- int ret = 0;
-
- /* set cpu DAI channel mapping */
- ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map),
- channel_map, ARRAY_SIZE(channel_map), channel_map);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops bf5xx_ad1836_ops = {
- .hw_params = bf5xx_ad1836_hw_params,
-};
-
-#define BF5XX_AD1836_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
- SND_SOC_DAIFMT_CBM_CFM)
-
-static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
- {
- .name = "ad1836",
- .stream_name = "AD1836",
- .cpu_dai_name = "bfin-tdm.0",
- .codec_dai_name = "ad1836-hifi",
- .platform_name = "bfin-tdm-pcm-audio",
- .codec_name = "spi0.4",
- .ops = &bf5xx_ad1836_ops,
- .dai_fmt = BF5XX_AD1836_DAIFMT,
- },
- {
- .name = "ad1836",
- .stream_name = "AD1836",
- .cpu_dai_name = "bfin-tdm.1",
- .codec_dai_name = "ad1836-hifi",
- .platform_name = "bfin-tdm-pcm-audio",
- .codec_name = "spi0.4",
- .ops = &bf5xx_ad1836_ops,
- .dai_fmt = BF5XX_AD1836_DAIFMT,
- },
-};
-
-static struct snd_soc_card bf5xx_ad1836 = {
- .name = "bfin-ad1836",
- .owner = THIS_MODULE,
- .dai_link = &bf5xx_ad1836_dai[CONFIG_SND_BF5XX_SPORT_NUM],
- .num_links = 1,
-};
-
-static struct platform_device *bfxx_ad1836_snd_device;
-
-static int __init bf5xx_ad1836_init(void)
-{
- int ret;
-
- bfxx_ad1836_snd_device = platform_device_alloc("soc-audio", -1);
- if (!bfxx_ad1836_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(bfxx_ad1836_snd_device, &bf5xx_ad1836);
- ret = platform_device_add(bfxx_ad1836_snd_device);
-
- if (ret)
- platform_device_put(bfxx_ad1836_snd_device);
-
- return ret;
-}
-
-static void __exit bf5xx_ad1836_exit(void)
-{
- platform_device_unregister(bfxx_ad1836_snd_device);
-}
-
-module_init(bf5xx_ad1836_init);
-module_exit(bf5xx_ad1836_exit);
-
-/* Module information */
-MODULE_AUTHOR("Barry Song");
-MODULE_DESCRIPTION("ALSA SoC AD1836 board driver");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ad193x.c b/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ad193x.c
deleted file mode 100644
index 0e55e9f2..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ad193x.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * File: sound/soc/blackfin/bf5xx-ad193x.c
- * Author: Barry Song <Barry.Song@analog.com>
- *
- * Created: Thur June 4 2009
- * Description: Board driver for ad193x sound chip
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <asm/blackfin.h>
-#include <asm/cacheflush.h>
-#include <asm/irq.h>
-#include <asm/dma.h>
-#include <asm/portmux.h>
-
-#include "../codecs/ad193x.h"
-
-#include "bf5xx-tdm-pcm.h"
-#include "bf5xx-tdm.h"
-
-static struct snd_soc_card bf5xx_ad193x;
-
-static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- unsigned int clk = 0;
- unsigned int channel_map[] = {0, 1, 2, 3, 4, 5, 6, 7};
- int ret = 0;
-
- switch (params_rate(params)) {
- case 48000:
- clk = 24576000;
- break;
- }
-
- /* set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- /* set codec DAI slots, 8 channels, all channels are enabled */
- ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xFF, 0xFF, 8, 32);
- if (ret < 0)
- return ret;
-
- /* set cpu DAI channel mapping */
- ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map),
- channel_map, ARRAY_SIZE(channel_map), channel_map);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-#define BF5XX_AD193X_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
- SND_SOC_DAIFMT_CBM_CFM)
-
-static struct snd_soc_ops bf5xx_ad193x_ops = {
- .hw_params = bf5xx_ad193x_hw_params,
-};
-
-static struct snd_soc_dai_link bf5xx_ad193x_dai[] = {
- {
- .name = "ad193x",
- .stream_name = "AD193X",
- .cpu_dai_name = "bfin-tdm.0",
- .codec_dai_name ="ad193x-hifi",
- .platform_name = "bfin-tdm-pcm-audio",
- .codec_name = "spi0.5",
- .ops = &bf5xx_ad193x_ops,
- .dai_fmt = BF5XX_AD193X_DAIFMT,
- },
- {
- .name = "ad193x",
- .stream_name = "AD193X",
- .cpu_dai_name = "bfin-tdm.1",
- .codec_dai_name ="ad193x-hifi",
- .platform_name = "bfin-tdm-pcm-audio",
- .codec_name = "spi0.5",
- .ops = &bf5xx_ad193x_ops,
- .dai_fmt = BF5XX_AD193X_DAIFMT,
- },
-};
-
-static struct snd_soc_card bf5xx_ad193x = {
- .name = "bfin-ad193x",
- .owner = THIS_MODULE,
- .dai_link = &bf5xx_ad193x_dai[CONFIG_SND_BF5XX_SPORT_NUM],
- .num_links = 1,
-};
-
-static struct platform_device *bfxx_ad193x_snd_device;
-
-static int __init bf5xx_ad193x_init(void)
-{
- int ret;
-
- bfxx_ad193x_snd_device = platform_device_alloc("soc-audio", -1);
- if (!bfxx_ad193x_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(bfxx_ad193x_snd_device, &bf5xx_ad193x);
- ret = platform_device_add(bfxx_ad193x_snd_device);
-
- if (ret)
- platform_device_put(bfxx_ad193x_snd_device);
-
- return ret;
-}
-
-static void __exit bf5xx_ad193x_exit(void)
-{
- platform_device_unregister(bfxx_ad193x_snd_device);
-}
-
-module_init(bf5xx_ad193x_init);
-module_exit(bf5xx_ad193x_exit);
-
-/* Module information */
-MODULE_AUTHOR("Barry Song");
-MODULE_DESCRIPTION("ALSA SoC AD193X board driver");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ad1980.c b/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ad1980.c
deleted file mode 100644
index b30f88bb..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ad1980.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * File: sound/soc/blackfin/bf5xx-ad1980.c
- * Author: Cliff Cai <Cliff.Cai@analog.com>
- *
- * Created: Tue June 06 2008
- * Description: Board driver for AD1980/1 audio codec
- *
- * Modified:
- * Copyright 2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * WARNING:
- *
- * Because Analog Devices Inc. discontinued the ad1980 sound chip since
- * Sep. 2009, this ad1980 driver is not maintained, tested and supported
- * by ADI now.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <asm/dma.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <linux/gpio.h>
-#include <asm/portmux.h>
-
-#include "../codecs/ad1980.h"
-
-#include "bf5xx-ac97-pcm.h"
-#include "bf5xx-ac97.h"
-
-static struct snd_soc_card bf5xx_board;
-
-static struct snd_soc_dai_link bf5xx_board_dai[] = {
- {
- .name = "AC97",
- .stream_name = "AC97 HiFi",
- .cpu_dai_name = "bfin-ac97.0",
- .codec_dai_name = "ad1980-hifi",
- .platform_name = "bfin-ac97-pcm-audio",
- .codec_name = "ad1980",
- },
- {
- .name = "AC97",
- .stream_name = "AC97 HiFi",
- .cpu_dai_name = "bfin-ac97.1",
- .codec_dai_name = "ad1980-hifi",
- .platform_name = "bfin-ac97-pcm-audio",
- .codec_name = "ad1980",
- },
-};
-
-static struct snd_soc_card bf5xx_board = {
- .name = "bfin-ad1980",
- .owner = THIS_MODULE,
- .dai_link = &bf5xx_board_dai[CONFIG_SND_BF5XX_SPORT_NUM],
- .num_links = 1,
-};
-
-static struct platform_device *bf5xx_board_snd_device;
-
-static int __init bf5xx_board_init(void)
-{
- int ret;
-
- bf5xx_board_snd_device = platform_device_alloc("soc-audio", -1);
- if (!bf5xx_board_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(bf5xx_board_snd_device, &bf5xx_board);
- ret = platform_device_add(bf5xx_board_snd_device);
-
- if (ret)
- platform_device_put(bf5xx_board_snd_device);
-
- return ret;
-}
-
-static void __exit bf5xx_board_exit(void)
-{
- platform_device_unregister(bf5xx_board_snd_device);
-}
-
-module_init(bf5xx_board_init);
-module_exit(bf5xx_board_exit);
-
-/* Module information */
-MODULE_AUTHOR("Cliff Cai");
-MODULE_DESCRIPTION("ALSA SoC AD1980/1 BF5xx board (Obsolete)");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ad73311.c b/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ad73311.c
deleted file mode 100644
index 61cc91d4..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ad73311.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * File: sound/soc/blackfin/bf5xx-ad73311.c
- * Author: Cliff Cai <Cliff.Cai@analog.com>
- *
- * Created: Thur Sep 25 2008
- * Description: Board driver for ad73311 sound chip
- *
- * Modified:
- * Copyright 2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <asm/blackfin.h>
-#include <asm/cacheflush.h>
-#include <asm/irq.h>
-#include <asm/dma.h>
-#include <asm/portmux.h>
-
-#include "../codecs/ad73311.h"
-#include "bf5xx-sport.h"
-#include "bf5xx-i2s-pcm.h"
-
-#if CONFIG_SND_BF5XX_SPORT_NUM == 0
-#define bfin_write_SPORT_TCR1 bfin_write_SPORT0_TCR1
-#define bfin_read_SPORT_TCR1 bfin_read_SPORT0_TCR1
-#define bfin_write_SPORT_TCR2 bfin_write_SPORT0_TCR2
-#define bfin_write_SPORT_TX16 bfin_write_SPORT0_TX16
-#define bfin_read_SPORT_STAT bfin_read_SPORT0_STAT
-#else
-#define bfin_write_SPORT_TCR1 bfin_write_SPORT1_TCR1
-#define bfin_read_SPORT_TCR1 bfin_read_SPORT1_TCR1
-#define bfin_write_SPORT_TCR2 bfin_write_SPORT1_TCR2
-#define bfin_write_SPORT_TX16 bfin_write_SPORT1_TX16
-#define bfin_read_SPORT_STAT bfin_read_SPORT1_STAT
-#endif
-
-#define GPIO_SE CONFIG_SND_BFIN_AD73311_SE
-
-static struct snd_soc_card bf5xx_ad73311;
-
-static int snd_ad73311_startup(void)
-{
- pr_debug("%s enter\n", __func__);
-
- /* Pull up SE pin on AD73311L */
- gpio_set_value(GPIO_SE, 1);
- return 0;
-}
-
-static int snd_ad73311_configure(void)
-{
- unsigned short ctrl_regs[6];
- unsigned short status = 0;
- int count = 0;
-
- /* DMCLK = MCLK = 16.384 MHz
- * SCLK = DMCLK/8 = 2.048 MHz
- * Sample Rate = DMCLK/2048 = 8 KHz
- */
- ctrl_regs[0] = AD_CONTROL | AD_WRITE | CTRL_REG_B | REGB_MCDIV(0) | \
- REGB_SCDIV(0) | REGB_DIRATE(0);
- ctrl_regs[1] = AD_CONTROL | AD_WRITE | CTRL_REG_C | REGC_PUDEV | \
- REGC_PUADC | REGC_PUDAC | REGC_PUREF | REGC_REFUSE ;
- ctrl_regs[2] = AD_CONTROL | AD_WRITE | CTRL_REG_D | REGD_OGS(2) | \
- REGD_IGS(2);
- ctrl_regs[3] = AD_CONTROL | AD_WRITE | CTRL_REG_E | REGE_DA(0x1f);
- ctrl_regs[4] = AD_CONTROL | AD_WRITE | CTRL_REG_F | REGF_SEEN ;
- ctrl_regs[5] = AD_CONTROL | AD_WRITE | CTRL_REG_A | REGA_MODE_DATA;
-
- local_irq_disable();
- snd_ad73311_startup();
- udelay(1);
-
- bfin_write_SPORT_TCR1(TFSR);
- bfin_write_SPORT_TCR2(0xF);
- SSYNC();
-
- /* SPORT Tx Register is a 8 x 16 FIFO, all the data can be put to
- * FIFO before enable SPORT to transfer the data
- */
- for (count = 0; count < 6; count++)
- bfin_write_SPORT_TX16(ctrl_regs[count]);
- SSYNC();
- bfin_write_SPORT_TCR1(bfin_read_SPORT_TCR1() | TSPEN);
- SSYNC();
-
- /* When TUVF is set, the data is already send out */
- while (!(status & TUVF) && ++count < 10000) {
- udelay(1);
- status = bfin_read_SPORT_STAT();
- SSYNC();
- }
- bfin_write_SPORT_TCR1(bfin_read_SPORT_TCR1() & ~TSPEN);
- SSYNC();
- local_irq_enable();
-
- if (count >= 10000) {
- printk(KERN_ERR "ad73311: failed to configure codec\n");
- return -1;
- }
- return 0;
-}
-
-static int bf5xx_probe(struct snd_soc_card *card)
-{
- int err;
- if (gpio_request(GPIO_SE, "AD73311_SE")) {
- printk(KERN_ERR "%s: Failed ro request GPIO_%d\n", __func__, GPIO_SE);
- return -EBUSY;
- }
-
- gpio_direction_output(GPIO_SE, 0);
-
- err = snd_ad73311_configure();
- if (err < 0)
- return -EFAULT;
-
- return 0;
-}
-
-#define BF5XX_AD7311_DAI_FMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | \
- SND_SOC_DAIFMT_CBM_CFM)
-
-static struct snd_soc_dai_link bf5xx_ad73311_dai[] = {
- {
- .name = "ad73311",
- .stream_name = "AD73311",
- .cpu_dai_name = "bfin-i2s.0",
- .codec_dai_name = "ad73311-hifi",
- .platform_name = "bfin-i2s-pcm-audio",
- .codec_name = "ad73311",
- .dai_fmt = BF5XX_AD7311_DAI_FMT,
- },
- {
- .name = "ad73311",
- .stream_name = "AD73311",
- .cpu_dai_name = "bfin-i2s.1",
- .codec_dai_name = "ad73311-hifi",
- .platform_name = "bfin-i2s-pcm-audio",
- .codec_name = "ad73311",
- .dai_fmt = BF5XX_AD7311_DAI_FMT,
- },
-};
-
-static struct snd_soc_card bf5xx_ad73311 = {
- .name = "bfin-ad73311",
- .owner = THIS_MODULE,
- .probe = bf5xx_probe,
- .dai_link = &bf5xx_ad73311_dai[CONFIG_SND_BF5XX_SPORT_NUM],
- .num_links = 1,
-};
-
-static struct platform_device *bf5xx_ad73311_snd_device;
-
-static int __init bf5xx_ad73311_init(void)
-{
- int ret;
-
- pr_debug("%s enter\n", __func__);
- bf5xx_ad73311_snd_device = platform_device_alloc("soc-audio", -1);
- if (!bf5xx_ad73311_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(bf5xx_ad73311_snd_device, &bf5xx_ad73311);
- ret = platform_device_add(bf5xx_ad73311_snd_device);
-
- if (ret)
- platform_device_put(bf5xx_ad73311_snd_device);
-
- return ret;
-}
-
-static void __exit bf5xx_ad73311_exit(void)
-{
- pr_debug("%s enter\n", __func__);
- platform_device_unregister(bf5xx_ad73311_snd_device);
-}
-
-module_init(bf5xx_ad73311_init);
-module_exit(bf5xx_ad73311_exit);
-
-/* Module information */
-MODULE_AUTHOR("Cliff Cai");
-MODULE_DESCRIPTION("ALSA SoC AD73311 Blackfin");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-i2s-pcm.c b/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-i2s-pcm.c
deleted file mode 100644
index 63205d72..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * File: sound/soc/blackfin/bf5xx-i2s-pcm.c
- * Author: Cliff Cai <Cliff.Cai@analog.com>
- *
- * Created: Tue June 06 2008
- * Description: DMA driver for i2s codec
- *
- * Modified:
- * Copyright 2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/gfp.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/dma.h>
-
-#include "bf5xx-i2s-pcm.h"
-#include "bf5xx-sport.h"
-
-static void bf5xx_dma_irq(void *data)
-{
- struct snd_pcm_substream *pcm = data;
- snd_pcm_period_elapsed(pcm);
-}
-
-static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
- .info = SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BLOCK_TRANSFER,
- .formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- .period_bytes_min = 32,
- .period_bytes_max = 0x10000,
- .periods_min = 1,
- .periods_max = PAGE_SIZE/32,
- .buffer_bytes_max = 0x20000, /* 128 kbytes */
- .fifo_size = 16,
-};
-
-static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- size_t size = bf5xx_pcm_hardware.buffer_bytes_max;
- snd_pcm_lib_malloc_pages(substream, size);
-
- return 0;
-}
-
-static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- snd_pcm_lib_free_pages(substream);
-
- return 0;
-}
-
-static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct sport_device *sport = runtime->private_data;
- int period_bytes = frames_to_bytes(runtime, runtime->period_size);
-
- pr_debug("%s enter\n", __func__);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
- sport_config_tx_dma(sport, runtime->dma_area,
- runtime->periods, period_bytes);
- } else {
- sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
- sport_config_rx_dma(sport, runtime->dma_area,
- runtime->periods, period_bytes);
- }
-
- return 0;
-}
-
-static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct sport_device *sport = runtime->private_data;
- int ret = 0;
-
- pr_debug("%s enter\n", __func__);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- sport_tx_start(sport);
- else
- sport_rx_start(sport);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- sport_tx_stop(sport);
- else
- sport_rx_stop(sport);
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct sport_device *sport = runtime->private_data;
- unsigned int diff;
- snd_pcm_uframes_t frames;
- pr_debug("%s enter\n", __func__);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- diff = sport_curr_offset_tx(sport);
- } else {
- diff = sport_curr_offset_rx(sport);
- }
-
- /*
- * TX at least can report one frame beyond the end of the
- * buffer if we hit the wraparound case - clamp to within the
- * buffer as the ALSA APIs require.
- */
- if (diff == snd_pcm_lib_buffer_bytes(substream))
- diff = 0;
-
- frames = bytes_to_frames(substream->runtime, diff);
-
- return frames;
-}
-
-static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- int ret;
-
- pr_debug("%s enter\n", __func__);
-
- snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
-
- ret = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (ret < 0)
- goto out;
-
- if (sport_handle != NULL) {
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- sport_handle->tx_buf = buf->area;
- else
- sport_handle->rx_buf = buf->area;
-
- runtime->private_data = sport_handle;
- } else {
- pr_err("sport_handle is NULL\n");
- return -1;
- }
- return 0;
-
- out:
- return ret;
-}
-
-static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- size_t size = vma->vm_end - vma->vm_start;
- vma->vm_start = (unsigned long)runtime->dma_area;
- vma->vm_end = vma->vm_start + size;
- vma->vm_flags |= VM_SHARED;
-
- return 0 ;
-}
-
-static struct snd_pcm_ops bf5xx_pcm_i2s_ops = {
- .open = bf5xx_pcm_open,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = bf5xx_pcm_hw_params,
- .hw_free = bf5xx_pcm_hw_free,
- .prepare = bf5xx_pcm_prepare,
- .trigger = bf5xx_pcm_trigger,
- .pointer = bf5xx_pcm_pointer,
- .mmap = bf5xx_pcm_mmap,
-};
-
-static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
- struct snd_pcm_substream *substream = pcm->streams[stream].substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = bf5xx_pcm_hardware.buffer_bytes_max;
-
- buf->dev.type = SNDRV_DMA_TYPE_DEV;
- buf->dev.dev = pcm->card->dev;
- buf->private_data = NULL;
- buf->area = dma_alloc_coherent(pcm->card->dev, size,
- &buf->addr, GFP_KERNEL);
- if (!buf->area) {
- pr_err("Failed to allocate dma memory - Please increase uncached DMA memory region\n");
- return -ENOMEM;
- }
- buf->bytes = size;
-
- pr_debug("%s, area:%p, size:0x%08lx\n", __func__,
- buf->area, buf->bytes);
-
- return 0;
-}
-
-static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- struct snd_dma_buffer *buf;
- int stream;
-
- for (stream = 0; stream < 2; stream++) {
- substream = pcm->streams[stream].substream;
- if (!substream)
- continue;
-
- buf = &substream->dma_buffer;
- if (!buf->area)
- continue;
- dma_free_coherent(NULL, buf->bytes, buf->area, 0);
- buf->area = NULL;
- }
-}
-
-static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
-
-static int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- int ret = 0;
-
- pr_debug("%s enter\n", __func__);
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &bf5xx_pcm_dmamask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_PLAYBACK);
- if (ret)
- goto out;
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_CAPTURE);
- if (ret)
- goto out;
- }
- out:
- return ret;
-}
-
-static struct snd_soc_platform_driver bf5xx_i2s_soc_platform = {
- .ops = &bf5xx_pcm_i2s_ops,
- .pcm_new = bf5xx_pcm_i2s_new,
- .pcm_free = bf5xx_pcm_free_dma_buffers,
-};
-
-static int __devinit bfin_i2s_soc_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_platform(&pdev->dev, &bf5xx_i2s_soc_platform);
-}
-
-static int __devexit bfin_i2s_soc_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver bfin_i2s_pcm_driver = {
- .driver = {
- .name = "bfin-i2s-pcm-audio",
- .owner = THIS_MODULE,
- },
-
- .probe = bfin_i2s_soc_platform_probe,
- .remove = __devexit_p(bfin_i2s_soc_platform_remove),
-};
-
-module_platform_driver(bfin_i2s_pcm_driver);
-
-MODULE_AUTHOR("Cliff Cai");
-MODULE_DESCRIPTION("ADI Blackfin I2S PCM DMA module");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-i2s-pcm.h b/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-i2s-pcm.h
deleted file mode 100644
index 0c2c5a68..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-i2s-pcm.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * linux/sound/arm/bf5xx-i2s-pcm.h -- ALSA PCM interface for the Blackfin
- *
- * Copyright 2007 Analog Device Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _BF5XX_I2S_PCM_H
-#define _BF5XX_I2S_PCM_H
-
-struct bf5xx_pcm_dma_params {
- char *name; /* stream identifier */
-};
-
-struct bf5xx_gpio {
- u32 sys;
- u32 rx;
- u32 tx;
- u32 clk;
- u32 frm;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-i2s.c b/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-i2s.c
deleted file mode 100644
index 4dccf037..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-i2s.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * File: sound/soc/blackfin/bf5xx-i2s.c
- * Author: Cliff Cai <Cliff.Cai@analog.com>
- *
- * Created: Tue June 06 2008
- * Description: Blackfin I2S CPU DAI driver
- *
- * Modified:
- * Copyright 2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include <asm/irq.h>
-#include <asm/portmux.h>
-#include <linux/mutex.h>
-#include <linux/gpio.h>
-
-#include "bf5xx-sport.h"
-
-struct bf5xx_i2s_port {
- u16 tcr1;
- u16 rcr1;
- u16 tcr2;
- u16 rcr2;
- int configured;
-};
-
-static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
- unsigned int fmt)
-{
- struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
- struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
- int ret = 0;
-
- /* interface format:support I2S,slave mode */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- bf5xx_i2s->tcr1 |= TFSR | TCKFE;
- bf5xx_i2s->rcr1 |= RFSR | RCKFE;
- bf5xx_i2s->tcr2 |= TSFSE;
- bf5xx_i2s->rcr2 |= RSFSE;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- bf5xx_i2s->tcr1 |= TFSR;
- bf5xx_i2s->rcr1 |= RFSR;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- ret = -EINVAL;
- break;
- default:
- printk(KERN_ERR "%s: Unknown DAI format type\n", __func__);
- ret = -EINVAL;
- break;
- }
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- case SND_SOC_DAIFMT_CBM_CFS:
- case SND_SOC_DAIFMT_CBS_CFM:
- ret = -EINVAL;
- break;
- default:
- printk(KERN_ERR "%s: Unknown DAI master type\n", __func__);
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
- struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
- int ret = 0;
-
- bf5xx_i2s->tcr2 &= ~0x1f;
- bf5xx_i2s->rcr2 &= ~0x1f;
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S8:
- bf5xx_i2s->tcr2 |= 7;
- bf5xx_i2s->rcr2 |= 7;
- sport_handle->wdsize = 1;
- case SNDRV_PCM_FORMAT_S16_LE:
- bf5xx_i2s->tcr2 |= 15;
- bf5xx_i2s->rcr2 |= 15;
- sport_handle->wdsize = 2;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- bf5xx_i2s->tcr2 |= 23;
- bf5xx_i2s->rcr2 |= 23;
- sport_handle->wdsize = 3;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- bf5xx_i2s->tcr2 |= 31;
- bf5xx_i2s->rcr2 |= 31;
- sport_handle->wdsize = 4;
- break;
- }
-
- if (!bf5xx_i2s->configured) {
- /*
- * TX and RX are not independent,they are enabled at the
- * same time, even if only one side is running. So, we
- * need to configure both of them at the time when the first
- * stream is opened.
- *
- * CPU DAI:slave mode.
- */
- bf5xx_i2s->configured = 1;
- ret = sport_config_rx(sport_handle, bf5xx_i2s->rcr1,
- bf5xx_i2s->rcr2, 0, 0);
- if (ret) {
- pr_err("SPORT is busy!\n");
- return -EBUSY;
- }
-
- ret = sport_config_tx(sport_handle, bf5xx_i2s->tcr1,
- bf5xx_i2s->tcr2, 0, 0);
- if (ret) {
- pr_err("SPORT is busy!\n");
- return -EBUSY;
- }
- }
-
- return 0;
-}
-
-static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
- struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
-
- pr_debug("%s enter\n", __func__);
- /* No active stream, SPORT is allowed to be configured again. */
- if (!dai->active)
- bf5xx_i2s->configured = 0;
-}
-
-#ifdef CONFIG_PM
-static int bf5xx_i2s_suspend(struct snd_soc_dai *dai)
-{
- struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
-
- pr_debug("%s : sport %d\n", __func__, dai->id);
-
- if (dai->capture_active)
- sport_rx_stop(sport_handle);
- if (dai->playback_active)
- sport_tx_stop(sport_handle);
- return 0;
-}
-
-static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
-{
- struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
- struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
- int ret;
-
- pr_debug("%s : sport %d\n", __func__, dai->id);
-
- ret = sport_config_rx(sport_handle, bf5xx_i2s->rcr1,
- bf5xx_i2s->rcr2, 0, 0);
- if (ret) {
- pr_err("SPORT is busy!\n");
- return -EBUSY;
- }
-
- ret = sport_config_tx(sport_handle, bf5xx_i2s->tcr1,
- bf5xx_i2s->tcr2, 0, 0);
- if (ret) {
- pr_err("SPORT is busy!\n");
- return -EBUSY;
- }
-
- return 0;
-}
-
-#else
-#define bf5xx_i2s_suspend NULL
-#define bf5xx_i2s_resume NULL
-#endif
-
-#define BF5XX_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
- SNDRV_PCM_RATE_96000)
-
-#define BF5XX_I2S_FORMATS \
- (SNDRV_PCM_FMTBIT_S8 | \
- SNDRV_PCM_FMTBIT_S16_LE | \
- SNDRV_PCM_FMTBIT_S24_LE | \
- SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops bf5xx_i2s_dai_ops = {
- .shutdown = bf5xx_i2s_shutdown,
- .hw_params = bf5xx_i2s_hw_params,
- .set_fmt = bf5xx_i2s_set_dai_fmt,
-};
-
-static struct snd_soc_dai_driver bf5xx_i2s_dai = {
- .suspend = bf5xx_i2s_suspend,
- .resume = bf5xx_i2s_resume,
- .playback = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = BF5XX_I2S_RATES,
- .formats = BF5XX_I2S_FORMATS,},
- .capture = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = BF5XX_I2S_RATES,
- .formats = BF5XX_I2S_FORMATS,},
- .ops = &bf5xx_i2s_dai_ops,
-};
-
-static int __devinit bf5xx_i2s_probe(struct platform_device *pdev)
-{
- struct sport_device *sport_handle;
- int ret;
-
- /* configure SPORT for I2S */
- sport_handle = sport_init(pdev, 4, 2 * sizeof(u32),
- sizeof(struct bf5xx_i2s_port));
- if (!sport_handle)
- return -ENODEV;
-
- /* register with the ASoC layers */
- ret = snd_soc_register_dai(&pdev->dev, &bf5xx_i2s_dai);
- if (ret) {
- pr_err("Failed to register DAI: %d\n", ret);
- sport_done(sport_handle);
- return ret;
- }
-
- return 0;
-}
-
-static int __devexit bf5xx_i2s_remove(struct platform_device *pdev)
-{
- struct sport_device *sport_handle = platform_get_drvdata(pdev);
-
- pr_debug("%s enter\n", __func__);
-
- snd_soc_unregister_dai(&pdev->dev);
- sport_done(sport_handle);
-
- return 0;
-}
-
-static struct platform_driver bfin_i2s_driver = {
- .probe = bf5xx_i2s_probe,
- .remove = __devexit_p(bf5xx_i2s_remove),
- .driver = {
- .name = "bfin-i2s",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(bfin_i2s_driver);
-
-/* Module information */
-MODULE_AUTHOR("Cliff Cai");
-MODULE_DESCRIPTION("I2S driver for ADI Blackfin");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-sport.c b/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-sport.c
deleted file mode 100644
index 2fd9f2a0..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-sport.c
+++ /dev/null
@@ -1,1094 +0,0 @@
-/*
- * File: bf5xx_sport.c
- * Based on:
- * Author: Roy Huang <roy.huang@analog.com>
- *
- * Created: Tue Sep 21 10:52:42 CEST 2004
- * Description:
- * Blackfin SPORT Driver
- *
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
-#include <linux/bug.h>
-#include <linux/module.h>
-#include <asm/portmux.h>
-#include <asm/dma.h>
-#include <asm/blackfin.h>
-#include <asm/cacheflush.h>
-
-#include "bf5xx-sport.h"
-/* delay between frame sync pulse and first data bit in multichannel mode */
-#define FRAME_DELAY (1<<12)
-
-/* note: multichannel is in units of 8 channels,
- * tdm_count is # channels NOT / 8 ! */
-int sport_set_multichannel(struct sport_device *sport,
- int tdm_count, u32 mask, int packed)
-{
- pr_debug("%s tdm_count=%d mask:0x%08x packed=%d\n", __func__,
- tdm_count, mask, packed);
-
- if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
- return -EBUSY;
-
- if (tdm_count & 0x7)
- return -EINVAL;
-
- if (tdm_count > 32)
- return -EINVAL; /* Only support less than 32 channels now */
-
- if (tdm_count) {
- sport->regs->mcmc1 = ((tdm_count>>3)-1) << 12;
- sport->regs->mcmc2 = FRAME_DELAY | MCMEN | \
- (packed ? (MCDTXPE|MCDRXPE) : 0);
-
- sport->regs->mtcs0 = mask;
- sport->regs->mrcs0 = mask;
- sport->regs->mtcs1 = 0;
- sport->regs->mrcs1 = 0;
- sport->regs->mtcs2 = 0;
- sport->regs->mrcs2 = 0;
- sport->regs->mtcs3 = 0;
- sport->regs->mrcs3 = 0;
- } else {
- sport->regs->mcmc1 = 0;
- sport->regs->mcmc2 = 0;
-
- sport->regs->mtcs0 = 0;
- sport->regs->mrcs0 = 0;
- }
-
- sport->regs->mtcs1 = 0; sport->regs->mtcs2 = 0; sport->regs->mtcs3 = 0;
- sport->regs->mrcs1 = 0; sport->regs->mrcs2 = 0; sport->regs->mrcs3 = 0;
-
- SSYNC();
-
- return 0;
-}
-EXPORT_SYMBOL(sport_set_multichannel);
-
-int sport_config_rx(struct sport_device *sport, unsigned int rcr1,
- unsigned int rcr2, unsigned int clkdiv, unsigned int fsdiv)
-{
- if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
- return -EBUSY;
-
- sport->regs->rcr1 = rcr1;
- sport->regs->rcr2 = rcr2;
- sport->regs->rclkdiv = clkdiv;
- sport->regs->rfsdiv = fsdiv;
-
- SSYNC();
-
- return 0;
-}
-EXPORT_SYMBOL(sport_config_rx);
-
-int sport_config_tx(struct sport_device *sport, unsigned int tcr1,
- unsigned int tcr2, unsigned int clkdiv, unsigned int fsdiv)
-{
- if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
- return -EBUSY;
-
- sport->regs->tcr1 = tcr1;
- sport->regs->tcr2 = tcr2;
- sport->regs->tclkdiv = clkdiv;
- sport->regs->tfsdiv = fsdiv;
-
- SSYNC();
-
- return 0;
-}
-EXPORT_SYMBOL(sport_config_tx);
-
-static void setup_desc(struct dmasg *desc, void *buf, int fragcount,
- size_t fragsize, unsigned int cfg,
- unsigned int x_count, unsigned int ycount, size_t wdsize)
-{
-
- int i;
-
- for (i = 0; i < fragcount; ++i) {
- desc[i].next_desc_addr = &(desc[i + 1]);
- desc[i].start_addr = (unsigned long)buf + i*fragsize;
- desc[i].cfg = cfg;
- desc[i].x_count = x_count;
- desc[i].x_modify = wdsize;
- desc[i].y_count = ycount;
- desc[i].y_modify = wdsize;
- }
-
- /* make circular */
- desc[fragcount-1].next_desc_addr = desc;
-
- pr_debug("setup desc: desc0=%p, next0=%p, desc1=%p,"
- "next1=%p\nx_count=%x,y_count=%x,addr=0x%lx,cfs=0x%x\n",
- desc, desc[0].next_desc_addr,
- desc+1, desc[1].next_desc_addr,
- desc[0].x_count, desc[0].y_count,
- desc[0].start_addr, desc[0].cfg);
-}
-
-static int sport_start(struct sport_device *sport)
-{
- enable_dma(sport->dma_rx_chan);
- enable_dma(sport->dma_tx_chan);
- sport->regs->rcr1 |= RSPEN;
- sport->regs->tcr1 |= TSPEN;
- SSYNC();
-
- return 0;
-}
-
-static int sport_stop(struct sport_device *sport)
-{
- sport->regs->tcr1 &= ~TSPEN;
- sport->regs->rcr1 &= ~RSPEN;
- SSYNC();
-
- disable_dma(sport->dma_rx_chan);
- disable_dma(sport->dma_tx_chan);
- return 0;
-}
-
-static inline int sport_hook_rx_dummy(struct sport_device *sport)
-{
- struct dmasg *desc, temp_desc;
- unsigned long flags;
-
- BUG_ON(sport->dummy_rx_desc == NULL);
- BUG_ON(sport->curr_rx_desc == sport->dummy_rx_desc);
-
- /* Maybe the dummy buffer descriptor ring is damaged */
- sport->dummy_rx_desc->next_desc_addr = sport->dummy_rx_desc + 1;
-
- local_irq_save(flags);
- desc = get_dma_next_desc_ptr(sport->dma_rx_chan);
- /* Copy the descriptor which will be damaged to backup */
- temp_desc = *desc;
- desc->x_count = sport->dummy_count / 2;
- desc->y_count = 0;
- desc->next_desc_addr = sport->dummy_rx_desc;
- local_irq_restore(flags);
- /* Waiting for dummy buffer descriptor is already hooked*/
- while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) -
- sizeof(struct dmasg)) != sport->dummy_rx_desc)
- continue;
- sport->curr_rx_desc = sport->dummy_rx_desc;
- /* Restore the damaged descriptor */
- *desc = temp_desc;
-
- return 0;
-}
-
-static inline int sport_rx_dma_start(struct sport_device *sport, int dummy)
-{
- if (dummy) {
- sport->dummy_rx_desc->next_desc_addr = sport->dummy_rx_desc;
- sport->curr_rx_desc = sport->dummy_rx_desc;
- } else
- sport->curr_rx_desc = sport->dma_rx_desc;
-
- set_dma_next_desc_addr(sport->dma_rx_chan, sport->curr_rx_desc);
- set_dma_x_count(sport->dma_rx_chan, 0);
- set_dma_x_modify(sport->dma_rx_chan, 0);
- set_dma_config(sport->dma_rx_chan, (DMAFLOW_LARGE | NDSIZE_9 | \
- WDSIZE_32 | WNR));
- set_dma_curr_addr(sport->dma_rx_chan, sport->curr_rx_desc->start_addr);
- SSYNC();
-
- return 0;
-}
-
-static inline int sport_tx_dma_start(struct sport_device *sport, int dummy)
-{
- if (dummy) {
- sport->dummy_tx_desc->next_desc_addr = sport->dummy_tx_desc;
- sport->curr_tx_desc = sport->dummy_tx_desc;
- } else
- sport->curr_tx_desc = sport->dma_tx_desc;
-
- set_dma_next_desc_addr(sport->dma_tx_chan, sport->curr_tx_desc);
- set_dma_x_count(sport->dma_tx_chan, 0);
- set_dma_x_modify(sport->dma_tx_chan, 0);
- set_dma_config(sport->dma_tx_chan,
- (DMAFLOW_LARGE | NDSIZE_9 | WDSIZE_32));
- set_dma_curr_addr(sport->dma_tx_chan, sport->curr_tx_desc->start_addr);
- SSYNC();
-
- return 0;
-}
-
-int sport_rx_start(struct sport_device *sport)
-{
- unsigned long flags;
- pr_debug("%s enter\n", __func__);
- if (sport->rx_run)
- return -EBUSY;
- if (sport->tx_run) {
- /* tx is running, rx is not running */
- BUG_ON(sport->dma_rx_desc == NULL);
- BUG_ON(sport->curr_rx_desc != sport->dummy_rx_desc);
- local_irq_save(flags);
- while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) -
- sizeof(struct dmasg)) != sport->dummy_rx_desc)
- continue;
- sport->dummy_rx_desc->next_desc_addr = sport->dma_rx_desc;
- local_irq_restore(flags);
- sport->curr_rx_desc = sport->dma_rx_desc;
- } else {
- sport_tx_dma_start(sport, 1);
- sport_rx_dma_start(sport, 0);
- sport_start(sport);
- }
-
- sport->rx_run = 1;
-
- return 0;
-}
-EXPORT_SYMBOL(sport_rx_start);
-
-int sport_rx_stop(struct sport_device *sport)
-{
- pr_debug("%s enter\n", __func__);
-
- if (!sport->rx_run)
- return 0;
- if (sport->tx_run) {
- /* TX dma is still running, hook the dummy buffer */
- sport_hook_rx_dummy(sport);
- } else {
- /* Both rx and tx dma will be stopped */
- sport_stop(sport);
- sport->curr_rx_desc = NULL;
- sport->curr_tx_desc = NULL;
- }
-
- sport->rx_run = 0;
-
- return 0;
-}
-EXPORT_SYMBOL(sport_rx_stop);
-
-static inline int sport_hook_tx_dummy(struct sport_device *sport)
-{
- struct dmasg *desc, temp_desc;
- unsigned long flags;
-
- BUG_ON(sport->dummy_tx_desc == NULL);
- BUG_ON(sport->curr_tx_desc == sport->dummy_tx_desc);
-
- sport->dummy_tx_desc->next_desc_addr = sport->dummy_tx_desc + 1;
-
- /* Shorten the time on last normal descriptor */
- local_irq_save(flags);
- desc = get_dma_next_desc_ptr(sport->dma_tx_chan);
- /* Store the descriptor which will be damaged */
- temp_desc = *desc;
- desc->x_count = sport->dummy_count / 2;
- desc->y_count = 0;
- desc->next_desc_addr = sport->dummy_tx_desc;
- local_irq_restore(flags);
- /* Waiting for dummy buffer descriptor is already hooked*/
- while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) - \
- sizeof(struct dmasg)) != sport->dummy_tx_desc)
- continue;
- sport->curr_tx_desc = sport->dummy_tx_desc;
- /* Restore the damaged descriptor */
- *desc = temp_desc;
-
- return 0;
-}
-
-int sport_tx_start(struct sport_device *sport)
-{
- unsigned long flags;
- pr_debug("%s: tx_run:%d, rx_run:%d\n", __func__,
- sport->tx_run, sport->rx_run);
- if (sport->tx_run)
- return -EBUSY;
- if (sport->rx_run) {
- BUG_ON(sport->dma_tx_desc == NULL);
- BUG_ON(sport->curr_tx_desc != sport->dummy_tx_desc);
- /* Hook the normal buffer descriptor */
- local_irq_save(flags);
- while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) -
- sizeof(struct dmasg)) != sport->dummy_tx_desc)
- continue;
- sport->dummy_tx_desc->next_desc_addr = sport->dma_tx_desc;
- local_irq_restore(flags);
- sport->curr_tx_desc = sport->dma_tx_desc;
- } else {
-
- sport_tx_dma_start(sport, 0);
- /* Let rx dma run the dummy buffer */
- sport_rx_dma_start(sport, 1);
- sport_start(sport);
- }
- sport->tx_run = 1;
- return 0;
-}
-EXPORT_SYMBOL(sport_tx_start);
-
-int sport_tx_stop(struct sport_device *sport)
-{
- if (!sport->tx_run)
- return 0;
- if (sport->rx_run) {
- /* RX is still running, hook the dummy buffer */
- sport_hook_tx_dummy(sport);
- } else {
- /* Both rx and tx dma stopped */
- sport_stop(sport);
- sport->curr_rx_desc = NULL;
- sport->curr_tx_desc = NULL;
- }
-
- sport->tx_run = 0;
-
- return 0;
-}
-EXPORT_SYMBOL(sport_tx_stop);
-
-static inline int compute_wdsize(size_t wdsize)
-{
- switch (wdsize) {
- case 1:
- return WDSIZE_8;
- case 2:
- return WDSIZE_16;
- case 4:
- default:
- return WDSIZE_32;
- }
-}
-
-int sport_config_rx_dma(struct sport_device *sport, void *buf,
- int fragcount, size_t fragsize)
-{
- unsigned int x_count;
- unsigned int y_count;
- unsigned int cfg;
- dma_addr_t addr;
-
- pr_debug("%s buf:%p, frag:%d, fragsize:0x%lx\n", __func__, \
- buf, fragcount, fragsize);
-
- x_count = fragsize / sport->wdsize;
- y_count = 0;
-
- /* for fragments larger than 64k words we use 2d dma,
- * denote fragecount as two numbers' mutliply and both of them
- * are less than 64k.*/
- if (x_count >= 0x10000) {
- int i, count = x_count;
-
- for (i = 16; i > 0; i--) {
- x_count = 1 << i;
- if ((count & (x_count - 1)) == 0) {
- y_count = count >> i;
- if (y_count < 0x10000)
- break;
- }
- }
- if (i == 0)
- return -EINVAL;
- }
- pr_debug("%s(x_count:0x%x, y_count:0x%x)\n", __func__,
- x_count, y_count);
-
- if (sport->dma_rx_desc)
- dma_free_coherent(NULL, sport->rx_desc_bytes,
- sport->dma_rx_desc, 0);
-
- /* Allocate a new descritor ring as current one. */
- sport->dma_rx_desc = dma_alloc_coherent(NULL, \
- fragcount * sizeof(struct dmasg), &addr, 0);
- sport->rx_desc_bytes = fragcount * sizeof(struct dmasg);
-
- if (!sport->dma_rx_desc) {
- pr_err("Failed to allocate memory for rx desc\n");
- return -ENOMEM;
- }
-
- sport->rx_buf = buf;
- sport->rx_fragsize = fragsize;
- sport->rx_frags = fragcount;
-
- cfg = 0x7000 | DI_EN | compute_wdsize(sport->wdsize) | WNR | \
- (DESC_ELEMENT_COUNT << 8); /* large descriptor mode */
-
- if (y_count != 0)
- cfg |= DMA2D;
-
- setup_desc(sport->dma_rx_desc, buf, fragcount, fragsize,
- cfg|DMAEN, x_count, y_count, sport->wdsize);
-
- return 0;
-}
-EXPORT_SYMBOL(sport_config_rx_dma);
-
-int sport_config_tx_dma(struct sport_device *sport, void *buf, \
- int fragcount, size_t fragsize)
-{
- unsigned int x_count;
- unsigned int y_count;
- unsigned int cfg;
- dma_addr_t addr;
-
- pr_debug("%s buf:%p, fragcount:%d, fragsize:0x%lx\n",
- __func__, buf, fragcount, fragsize);
-
- x_count = fragsize/sport->wdsize;
- y_count = 0;
-
- /* for fragments larger than 64k words we use 2d dma,
- * denote fragecount as two numbers' mutliply and both of them
- * are less than 64k.*/
- if (x_count >= 0x10000) {
- int i, count = x_count;
-
- for (i = 16; i > 0; i--) {
- x_count = 1 << i;
- if ((count & (x_count - 1)) == 0) {
- y_count = count >> i;
- if (y_count < 0x10000)
- break;
- }
- }
- if (i == 0)
- return -EINVAL;
- }
- pr_debug("%s x_count:0x%x, y_count:0x%x\n", __func__,
- x_count, y_count);
-
-
- if (sport->dma_tx_desc) {
- dma_free_coherent(NULL, sport->tx_desc_bytes, \
- sport->dma_tx_desc, 0);
- }
-
- sport->dma_tx_desc = dma_alloc_coherent(NULL, \
- fragcount * sizeof(struct dmasg), &addr, 0);
- sport->tx_desc_bytes = fragcount * sizeof(struct dmasg);
- if (!sport->dma_tx_desc) {
- pr_err("Failed to allocate memory for tx desc\n");
- return -ENOMEM;
- }
-
- sport->tx_buf = buf;
- sport->tx_fragsize = fragsize;
- sport->tx_frags = fragcount;
- cfg = 0x7000 | DI_EN | compute_wdsize(sport->wdsize) | \
- (DESC_ELEMENT_COUNT << 8); /* large descriptor mode */
-
- if (y_count != 0)
- cfg |= DMA2D;
-
- setup_desc(sport->dma_tx_desc, buf, fragcount, fragsize,
- cfg|DMAEN, x_count, y_count, sport->wdsize);
-
- return 0;
-}
-EXPORT_SYMBOL(sport_config_tx_dma);
-
-/* setup dummy dma descriptor ring, which don't generate interrupts,
- * the x_modify is set to 0 */
-static int sport_config_rx_dummy(struct sport_device *sport)
-{
- struct dmasg *desc;
- unsigned config;
-
- pr_debug("%s entered\n", __func__);
- if (L1_DATA_A_LENGTH)
- desc = l1_data_sram_zalloc(2 * sizeof(*desc));
- else {
- dma_addr_t addr;
- desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0);
- memset(desc, 0, 2 * sizeof(*desc));
- }
- if (desc == NULL) {
- pr_err("Failed to allocate memory for dummy rx desc\n");
- return -ENOMEM;
- }
- sport->dummy_rx_desc = desc;
- desc->start_addr = (unsigned long)sport->dummy_buf;
- config = DMAFLOW_LARGE | NDSIZE_9 | compute_wdsize(sport->wdsize)
- | WNR | DMAEN;
- desc->cfg = config;
- desc->x_count = sport->dummy_count/sport->wdsize;
- desc->x_modify = sport->wdsize;
- desc->y_count = 0;
- desc->y_modify = 0;
- memcpy(desc+1, desc, sizeof(*desc));
- desc->next_desc_addr = desc + 1;
- desc[1].next_desc_addr = desc;
- return 0;
-}
-
-static int sport_config_tx_dummy(struct sport_device *sport)
-{
- struct dmasg *desc;
- unsigned int config;
-
- pr_debug("%s entered\n", __func__);
-
- if (L1_DATA_A_LENGTH)
- desc = l1_data_sram_zalloc(2 * sizeof(*desc));
- else {
- dma_addr_t addr;
- desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0);
- memset(desc, 0, 2 * sizeof(*desc));
- }
- if (!desc) {
- pr_err("Failed to allocate memory for dummy tx desc\n");
- return -ENOMEM;
- }
- sport->dummy_tx_desc = desc;
- desc->start_addr = (unsigned long)sport->dummy_buf + \
- sport->dummy_count;
- config = DMAFLOW_LARGE | NDSIZE_9 |
- compute_wdsize(sport->wdsize) | DMAEN;
- desc->cfg = config;
- desc->x_count = sport->dummy_count/sport->wdsize;
- desc->x_modify = sport->wdsize;
- desc->y_count = 0;
- desc->y_modify = 0;
- memcpy(desc+1, desc, sizeof(*desc));
- desc->next_desc_addr = desc + 1;
- desc[1].next_desc_addr = desc;
- return 0;
-}
-
-unsigned long sport_curr_offset_rx(struct sport_device *sport)
-{
- unsigned long curr = get_dma_curr_addr(sport->dma_rx_chan);
-
- return (unsigned char *)curr - sport->rx_buf;
-}
-EXPORT_SYMBOL(sport_curr_offset_rx);
-
-unsigned long sport_curr_offset_tx(struct sport_device *sport)
-{
- unsigned long curr = get_dma_curr_addr(sport->dma_tx_chan);
-
- return (unsigned char *)curr - sport->tx_buf;
-}
-EXPORT_SYMBOL(sport_curr_offset_tx);
-
-void sport_incfrag(struct sport_device *sport, int *frag, int tx)
-{
- ++(*frag);
- if (tx == 1 && *frag == sport->tx_frags)
- *frag = 0;
-
- if (tx == 0 && *frag == sport->rx_frags)
- *frag = 0;
-}
-EXPORT_SYMBOL(sport_incfrag);
-
-void sport_decfrag(struct sport_device *sport, int *frag, int tx)
-{
- --(*frag);
- if (tx == 1 && *frag == 0)
- *frag = sport->tx_frags;
-
- if (tx == 0 && *frag == 0)
- *frag = sport->rx_frags;
-}
-EXPORT_SYMBOL(sport_decfrag);
-
-static int sport_check_status(struct sport_device *sport,
- unsigned int *sport_stat,
- unsigned int *rx_stat,
- unsigned int *tx_stat)
-{
- int status = 0;
-
- if (sport_stat) {
- SSYNC();
- status = sport->regs->stat;
- if (status & (TOVF|TUVF|ROVF|RUVF))
- sport->regs->stat = (status & (TOVF|TUVF|ROVF|RUVF));
- SSYNC();
- *sport_stat = status;
- }
-
- if (rx_stat) {
- SSYNC();
- status = get_dma_curr_irqstat(sport->dma_rx_chan);
- if (status & (DMA_DONE|DMA_ERR))
- clear_dma_irqstat(sport->dma_rx_chan);
- SSYNC();
- *rx_stat = status;
- }
-
- if (tx_stat) {
- SSYNC();
- status = get_dma_curr_irqstat(sport->dma_tx_chan);
- if (status & (DMA_DONE|DMA_ERR))
- clear_dma_irqstat(sport->dma_tx_chan);
- SSYNC();
- *tx_stat = status;
- }
-
- return 0;
-}
-
-int sport_dump_stat(struct sport_device *sport, char *buf, size_t len)
-{
- int ret;
-
- ret = snprintf(buf, len,
- "sts: 0x%04x\n"
- "rx dma %d sts: 0x%04x tx dma %d sts: 0x%04x\n",
- sport->regs->stat,
- sport->dma_rx_chan,
- get_dma_curr_irqstat(sport->dma_rx_chan),
- sport->dma_tx_chan,
- get_dma_curr_irqstat(sport->dma_tx_chan));
- buf += ret;
- len -= ret;
-
- ret += snprintf(buf, len,
- "curr_rx_desc:0x%p, curr_tx_desc:0x%p\n"
- "dma_rx_desc:0x%p, dma_tx_desc:0x%p\n"
- "dummy_rx_desc:0x%p, dummy_tx_desc:0x%p\n",
- sport->curr_rx_desc, sport->curr_tx_desc,
- sport->dma_rx_desc, sport->dma_tx_desc,
- sport->dummy_rx_desc, sport->dummy_tx_desc);
-
- return ret;
-}
-
-static irqreturn_t rx_handler(int irq, void *dev_id)
-{
- unsigned int rx_stat;
- struct sport_device *sport = dev_id;
-
- pr_debug("%s enter\n", __func__);
- sport_check_status(sport, NULL, &rx_stat, NULL);
- if (!(rx_stat & DMA_DONE))
- pr_err("rx dma is already stopped\n");
-
- if (sport->rx_callback) {
- sport->rx_callback(sport->rx_data);
- return IRQ_HANDLED;
- }
-
- return IRQ_NONE;
-}
-
-static irqreturn_t tx_handler(int irq, void *dev_id)
-{
- unsigned int tx_stat;
- struct sport_device *sport = dev_id;
- pr_debug("%s enter\n", __func__);
- sport_check_status(sport, NULL, NULL, &tx_stat);
- if (!(tx_stat & DMA_DONE)) {
- pr_err("tx dma is already stopped\n");
- return IRQ_HANDLED;
- }
- if (sport->tx_callback) {
- sport->tx_callback(sport->tx_data);
- return IRQ_HANDLED;
- }
-
- return IRQ_NONE;
-}
-
-static irqreturn_t err_handler(int irq, void *dev_id)
-{
- unsigned int status = 0;
- struct sport_device *sport = dev_id;
-
- pr_debug("%s\n", __func__);
- if (sport_check_status(sport, &status, NULL, NULL)) {
- pr_err("error checking status ??");
- return IRQ_NONE;
- }
-
- if (status & (TOVF|TUVF|ROVF|RUVF)) {
- pr_info("sport status error:%s%s%s%s\n",
- status & TOVF ? " TOVF" : "",
- status & TUVF ? " TUVF" : "",
- status & ROVF ? " ROVF" : "",
- status & RUVF ? " RUVF" : "");
- if (status & TOVF || status & TUVF) {
- disable_dma(sport->dma_tx_chan);
- if (sport->tx_run)
- sport_tx_dma_start(sport, 0);
- else
- sport_tx_dma_start(sport, 1);
- enable_dma(sport->dma_tx_chan);
- } else {
- disable_dma(sport->dma_rx_chan);
- if (sport->rx_run)
- sport_rx_dma_start(sport, 0);
- else
- sport_rx_dma_start(sport, 1);
- enable_dma(sport->dma_rx_chan);
- }
- }
- status = sport->regs->stat;
- if (status & (TOVF|TUVF|ROVF|RUVF))
- sport->regs->stat = (status & (TOVF|TUVF|ROVF|RUVF));
- SSYNC();
-
- if (sport->err_callback)
- sport->err_callback(sport->err_data);
-
- return IRQ_HANDLED;
-}
-
-int sport_set_rx_callback(struct sport_device *sport,
- void (*rx_callback)(void *), void *rx_data)
-{
- BUG_ON(rx_callback == NULL);
- sport->rx_callback = rx_callback;
- sport->rx_data = rx_data;
-
- return 0;
-}
-EXPORT_SYMBOL(sport_set_rx_callback);
-
-int sport_set_tx_callback(struct sport_device *sport,
- void (*tx_callback)(void *), void *tx_data)
-{
- BUG_ON(tx_callback == NULL);
- sport->tx_callback = tx_callback;
- sport->tx_data = tx_data;
-
- return 0;
-}
-EXPORT_SYMBOL(sport_set_tx_callback);
-
-int sport_set_err_callback(struct sport_device *sport,
- void (*err_callback)(void *), void *err_data)
-{
- BUG_ON(err_callback == NULL);
- sport->err_callback = err_callback;
- sport->err_data = err_data;
-
- return 0;
-}
-EXPORT_SYMBOL(sport_set_err_callback);
-
-static int sport_config_pdev(struct platform_device *pdev, struct sport_param *param)
-{
- /* Extract settings from platform data */
- struct device *dev = &pdev->dev;
- struct bfin_snd_platform_data *pdata = dev->platform_data;
- struct resource *res;
-
- param->num = pdev->id;
-
- if (!pdata) {
- dev_err(dev, "no platform_data\n");
- return -ENODEV;
- }
- param->pin_req = pdata->pin_req;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(dev, "no MEM resource\n");
- return -ENODEV;
- }
- param->regs = (struct sport_register *)res->start;
-
- /* first RX, then TX */
- res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!res) {
- dev_err(dev, "no rx DMA resource\n");
- return -ENODEV;
- }
- param->dma_rx_chan = res->start;
-
- res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (!res) {
- dev_err(dev, "no tx DMA resource\n");
- return -ENODEV;
- }
- param->dma_tx_chan = res->start;
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- dev_err(dev, "no irq resource\n");
- return -ENODEV;
- }
- param->err_irq = res->start;
-
- return 0;
-}
-
-struct sport_device *sport_init(struct platform_device *pdev,
- unsigned int wdsize, unsigned int dummy_count, size_t priv_size)
-{
- struct device *dev = &pdev->dev;
- struct sport_param param;
- struct sport_device *sport;
- int ret;
-
- dev_dbg(dev, "%s enter\n", __func__);
-
- param.wdsize = wdsize;
- param.dummy_count = dummy_count;
- BUG_ON(param.wdsize == 0 || param.dummy_count == 0);
-
- ret = sport_config_pdev(pdev, &param);
- if (ret)
- return NULL;
-
- if (peripheral_request_list(param.pin_req, "soc-audio")) {
- dev_err(dev, "requesting Peripherals failed\n");
- return NULL;
- }
-
- sport = kzalloc(sizeof(*sport), GFP_KERNEL);
- if (!sport) {
- dev_err(dev, "failed to allocate for sport device\n");
- goto __init_err0;
- }
-
- sport->num = param.num;
- sport->dma_rx_chan = param.dma_rx_chan;
- sport->dma_tx_chan = param.dma_tx_chan;
- sport->err_irq = param.err_irq;
- sport->regs = param.regs;
- sport->pin_req = param.pin_req;
-
- if (request_dma(sport->dma_rx_chan, "SPORT RX Data") == -EBUSY) {
- dev_err(dev, "failed to request RX dma %d\n", sport->dma_rx_chan);
- goto __init_err1;
- }
- if (set_dma_callback(sport->dma_rx_chan, rx_handler, sport) != 0) {
- dev_err(dev, "failed to request RX irq %d\n", sport->dma_rx_chan);
- goto __init_err2;
- }
-
- if (request_dma(sport->dma_tx_chan, "SPORT TX Data") == -EBUSY) {
- dev_err(dev, "failed to request TX dma %d\n", sport->dma_tx_chan);
- goto __init_err2;
- }
-
- if (set_dma_callback(sport->dma_tx_chan, tx_handler, sport) != 0) {
- dev_err(dev, "failed to request TX irq %d\n", sport->dma_tx_chan);
- goto __init_err3;
- }
-
- if (request_irq(sport->err_irq, err_handler, IRQF_SHARED, "SPORT err",
- sport) < 0) {
- dev_err(dev, "failed to request err irq %d\n", sport->err_irq);
- goto __init_err3;
- }
-
- dev_info(dev, "dma rx:%d tx:%d, err irq:%d, regs:%p\n",
- sport->dma_rx_chan, sport->dma_tx_chan,
- sport->err_irq, sport->regs);
-
- sport->wdsize = param.wdsize;
- sport->dummy_count = param.dummy_count;
-
- sport->private_data = kzalloc(priv_size, GFP_KERNEL);
- if (!sport->private_data) {
- dev_err(dev, "could not alloc priv data %zu bytes\n", priv_size);
- goto __init_err4;
- }
-
- if (L1_DATA_A_LENGTH)
- sport->dummy_buf = l1_data_sram_zalloc(param.dummy_count * 2);
- else
- sport->dummy_buf = kzalloc(param.dummy_count * 2, GFP_KERNEL);
- if (sport->dummy_buf == NULL) {
- dev_err(dev, "failed to allocate dummy buffer\n");
- goto __error1;
- }
-
- ret = sport_config_rx_dummy(sport);
- if (ret) {
- dev_err(dev, "failed to config rx dummy ring\n");
- goto __error2;
- }
- ret = sport_config_tx_dummy(sport);
- if (ret) {
- dev_err(dev, "failed to config tx dummy ring\n");
- goto __error3;
- }
-
- platform_set_drvdata(pdev, sport);
-
- return sport;
-__error3:
- if (L1_DATA_A_LENGTH)
- l1_data_sram_free(sport->dummy_rx_desc);
- else
- dma_free_coherent(NULL, 2*sizeof(struct dmasg),
- sport->dummy_rx_desc, 0);
-__error2:
- if (L1_DATA_A_LENGTH)
- l1_data_sram_free(sport->dummy_buf);
- else
- kfree(sport->dummy_buf);
-__error1:
- kfree(sport->private_data);
-__init_err4:
- free_irq(sport->err_irq, sport);
-__init_err3:
- free_dma(sport->dma_tx_chan);
-__init_err2:
- free_dma(sport->dma_rx_chan);
-__init_err1:
- kfree(sport);
-__init_err0:
- peripheral_free_list(param.pin_req);
- return NULL;
-}
-EXPORT_SYMBOL(sport_init);
-
-void sport_done(struct sport_device *sport)
-{
- if (sport == NULL)
- return;
-
- sport_stop(sport);
- if (sport->dma_rx_desc)
- dma_free_coherent(NULL, sport->rx_desc_bytes,
- sport->dma_rx_desc, 0);
- if (sport->dma_tx_desc)
- dma_free_coherent(NULL, sport->tx_desc_bytes,
- sport->dma_tx_desc, 0);
-
-#if L1_DATA_A_LENGTH != 0
- l1_data_sram_free(sport->dummy_rx_desc);
- l1_data_sram_free(sport->dummy_tx_desc);
- l1_data_sram_free(sport->dummy_buf);
-#else
- dma_free_coherent(NULL, 2*sizeof(struct dmasg),
- sport->dummy_rx_desc, 0);
- dma_free_coherent(NULL, 2*sizeof(struct dmasg),
- sport->dummy_tx_desc, 0);
- kfree(sport->dummy_buf);
-#endif
- free_dma(sport->dma_rx_chan);
- free_dma(sport->dma_tx_chan);
- free_irq(sport->err_irq, sport);
-
- kfree(sport->private_data);
- peripheral_free_list(sport->pin_req);
- kfree(sport);
-}
-EXPORT_SYMBOL(sport_done);
-
-/*
-* It is only used to send several bytes when dma is not enabled
- * sport controller is configured but not enabled.
- * Multichannel cannot works with pio mode */
-/* Used by ac97 to write and read codec register */
-int sport_send_and_recv(struct sport_device *sport, u8 *out_data, \
- u8 *in_data, int len)
-{
- unsigned short dma_config;
- unsigned short status;
- unsigned long flags;
- unsigned long wait = 0;
-
- pr_debug("%s enter, out_data:%p, in_data:%p len:%d\n", \
- __func__, out_data, in_data, len);
- pr_debug("tcr1:0x%04x, tcr2:0x%04x, tclkdiv:0x%04x, tfsdiv:0x%04x\n"
- "mcmc1:0x%04x, mcmc2:0x%04x\n",
- sport->regs->tcr1, sport->regs->tcr2,
- sport->regs->tclkdiv, sport->regs->tfsdiv,
- sport->regs->mcmc1, sport->regs->mcmc2);
- flush_dcache_range((unsigned)out_data, (unsigned)(out_data + len));
-
- /* Enable tx dma */
- dma_config = (RESTART | WDSIZE_16 | DI_EN);
- set_dma_start_addr(sport->dma_tx_chan, (unsigned long)out_data);
- set_dma_x_count(sport->dma_tx_chan, len/2);
- set_dma_x_modify(sport->dma_tx_chan, 2);
- set_dma_config(sport->dma_tx_chan, dma_config);
- enable_dma(sport->dma_tx_chan);
-
- if (in_data != NULL) {
- invalidate_dcache_range((unsigned)in_data, \
- (unsigned)(in_data + len));
- /* Enable rx dma */
- dma_config = (RESTART | WDSIZE_16 | WNR | DI_EN);
- set_dma_start_addr(sport->dma_rx_chan, (unsigned long)in_data);
- set_dma_x_count(sport->dma_rx_chan, len/2);
- set_dma_x_modify(sport->dma_rx_chan, 2);
- set_dma_config(sport->dma_rx_chan, dma_config);
- enable_dma(sport->dma_rx_chan);
- }
-
- local_irq_save(flags);
- sport->regs->tcr1 |= TSPEN;
- sport->regs->rcr1 |= RSPEN;
- SSYNC();
-
- status = get_dma_curr_irqstat(sport->dma_tx_chan);
- while (status & DMA_RUN) {
- udelay(1);
- status = get_dma_curr_irqstat(sport->dma_tx_chan);
- pr_debug("DMA status:0x%04x\n", status);
- if (wait++ > 100)
- goto __over;
- }
- status = sport->regs->stat;
- wait = 0;
-
- while (!(status & TXHRE)) {
- pr_debug("sport status:0x%04x\n", status);
- udelay(1);
- status = *(unsigned short *)&sport->regs->stat;
- if (wait++ > 1000)
- goto __over;
- }
- /* Wait for the last byte sent out */
- udelay(20);
- pr_debug("sport status:0x%04x\n", status);
-
-__over:
- sport->regs->tcr1 &= ~TSPEN;
- sport->regs->rcr1 &= ~RSPEN;
- SSYNC();
- disable_dma(sport->dma_tx_chan);
- /* Clear the status */
- clear_dma_irqstat(sport->dma_tx_chan);
- if (in_data != NULL) {
- disable_dma(sport->dma_rx_chan);
- clear_dma_irqstat(sport->dma_rx_chan);
- }
- SSYNC();
- local_irq_restore(flags);
-
- return 0;
-}
-EXPORT_SYMBOL(sport_send_and_recv);
-
-MODULE_AUTHOR("Roy Huang");
-MODULE_DESCRIPTION("SPORT driver for ADI Blackfin");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-sport.h b/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-sport.h
deleted file mode 100644
index 5ab60bd6..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-sport.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * File: bf5xx_sport.h
- * Based on:
- * Author: Roy Huang <roy.huang@analog.com>
- *
- * Created:
- * Description:
- *
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-
-#ifndef __BF5XX_SPORT_H__
-#define __BF5XX_SPORT_H__
-
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <linux/workqueue.h>
-#include <linux/platform_device.h>
-#include <asm/dma.h>
-#include <asm/bfin_sport.h>
-
-#define DESC_ELEMENT_COUNT 9
-
-struct sport_device {
- int num;
- int dma_rx_chan;
- int dma_tx_chan;
- int err_irq;
- const unsigned short *pin_req;
- struct sport_register *regs;
-
- unsigned char *rx_buf;
- unsigned char *tx_buf;
- unsigned int rx_fragsize;
- unsigned int tx_fragsize;
- unsigned int rx_frags;
- unsigned int tx_frags;
- unsigned int wdsize;
-
- /* for dummy dma transfer */
- void *dummy_buf;
- unsigned int dummy_count;
-
- /* DMA descriptor ring head of current audio stream*/
- struct dmasg *dma_rx_desc;
- struct dmasg *dma_tx_desc;
- unsigned int rx_desc_bytes;
- unsigned int tx_desc_bytes;
-
- unsigned int rx_run:1; /* rx is running */
- unsigned int tx_run:1; /* tx is running */
-
- struct dmasg *dummy_rx_desc;
- struct dmasg *dummy_tx_desc;
-
- struct dmasg *curr_rx_desc;
- struct dmasg *curr_tx_desc;
-
- int rx_curr_frag;
- int tx_curr_frag;
-
- unsigned int rcr1;
- unsigned int rcr2;
- int rx_tdm_count;
-
- unsigned int tcr1;
- unsigned int tcr2;
- int tx_tdm_count;
-
- void (*rx_callback)(void *data);
- void *rx_data;
- void (*tx_callback)(void *data);
- void *tx_data;
- void (*err_callback)(void *data);
- void *err_data;
- unsigned char *tx_dma_buf;
- unsigned char *rx_dma_buf;
-#ifdef CONFIG_SND_BF5XX_MMAP_SUPPORT
- dma_addr_t tx_dma_phy;
- dma_addr_t rx_dma_phy;
- int tx_pos;/*pcm sample count*/
- int rx_pos;
- unsigned int tx_buffer_size;
- unsigned int rx_buffer_size;
- int tx_delay_pos;
- int once;
-#endif
- void *private_data;
-};
-
-struct sport_param {
- int num;
- int dma_rx_chan;
- int dma_tx_chan;
- int err_irq;
- const unsigned short *pin_req;
- struct sport_register *regs;
- unsigned int wdsize;
- unsigned int dummy_count;
- void *private_data;
-};
-
-struct sport_device *sport_init(struct platform_device *pdev,
- unsigned int wdsize, unsigned int dummy_count, size_t priv_size);
-
-void sport_done(struct sport_device *sport);
-
-/* first use these ...*/
-
-/* note: multichannel is in units of 8 channels, tdm_count is number of channels
- * NOT / 8 ! all channels are enabled by default */
-int sport_set_multichannel(struct sport_device *sport, int tdm_count,
- u32 mask, int packed);
-
-int sport_config_rx(struct sport_device *sport,
- unsigned int rcr1, unsigned int rcr2,
- unsigned int clkdiv, unsigned int fsdiv);
-
-int sport_config_tx(struct sport_device *sport,
- unsigned int tcr1, unsigned int tcr2,
- unsigned int clkdiv, unsigned int fsdiv);
-
-/* ... then these: */
-
-/* buffer size (in bytes) == fragcount * fragsize_bytes */
-
-/* this is not a very general api, it sets the dma to 2d autobuffer mode */
-
-int sport_config_rx_dma(struct sport_device *sport, void *buf,
- int fragcount, size_t fragsize_bytes);
-
-int sport_config_tx_dma(struct sport_device *sport, void *buf,
- int fragcount, size_t fragsize_bytes);
-
-int sport_tx_start(struct sport_device *sport);
-int sport_tx_stop(struct sport_device *sport);
-int sport_rx_start(struct sport_device *sport);
-int sport_rx_stop(struct sport_device *sport);
-
-/* for use in interrupt handler */
-unsigned long sport_curr_offset_rx(struct sport_device *sport);
-unsigned long sport_curr_offset_tx(struct sport_device *sport);
-
-void sport_incfrag(struct sport_device *sport, int *frag, int tx);
-void sport_decfrag(struct sport_device *sport, int *frag, int tx);
-
-int sport_set_rx_callback(struct sport_device *sport,
- void (*rx_callback)(void *), void *rx_data);
-int sport_set_tx_callback(struct sport_device *sport,
- void (*tx_callback)(void *), void *tx_data);
-int sport_set_err_callback(struct sport_device *sport,
- void (*err_callback)(void *), void *err_data);
-
-int sport_send_and_recv(struct sport_device *sport, u8 *out_data, \
- u8 *in_data, int len);
-#endif /* BF53X_SPORT_H */
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ssm2602.c b/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ssm2602.c
deleted file mode 100644
index b39ad356..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-ssm2602.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * File: sound/soc/blackfin/bf5xx-ssm2602.c
- * Author: Cliff Cai <Cliff.Cai@analog.com>
- *
- * Created: Tue June 06 2008
- * Description: board driver for SSM2602 sound chip
- *
- * Modified:
- * Copyright 2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <asm/dma.h>
-#include <asm/portmux.h>
-#include <linux/gpio.h>
-#include "../codecs/ssm2602.h"
-#include "bf5xx-sport.h"
-#include "bf5xx-i2s-pcm.h"
-
-static struct snd_soc_card bf5xx_ssm2602;
-
-static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- unsigned int clk = 0;
- int ret = 0;
-
- pr_debug("%s rate %d format %x\n", __func__, params_rate(params),
- params_format(params));
- /*
- * If you are using a crystal source which frequency is not 12MHz
- * then modify the below case statement with frequency of the crystal.
- *
- * If you are using the SPORT to generate clocking then this is
- * where to do it.
- */
-
- switch (params_rate(params)) {
- case 8000:
- case 16000:
- case 48000:
- case 96000:
- case 11025:
- case 22050:
- case 44100:
- clk = 12000000;
- break;
- }
-
- ret = snd_soc_dai_set_sysclk(codec_dai, SSM2602_SYSCLK, clk,
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops bf5xx_ssm2602_ops = {
- .hw_params = bf5xx_ssm2602_hw_params,
-};
-
-/* CODEC is master for BCLK and LRC in this configuration. */
-#define BF5XX_SSM2602_DAIFMT (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | \
- SND_SOC_DAIFMT_CBM_CFM)
-
-static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = {
- {
- .name = "ssm2602",
- .stream_name = "SSM2602",
- .cpu_dai_name = "bfin-i2s.0",
- .codec_dai_name = "ssm2602-hifi",
- .platform_name = "bfin-i2s-pcm-audio",
- .codec_name = "ssm2602.0-001b",
- .ops = &bf5xx_ssm2602_ops,
- .dai_fmt = BF5XX_SSM2602_DAIFMT,
- },
- {
- .name = "ssm2602",
- .stream_name = "SSM2602",
- .cpu_dai_name = "bfin-i2s.1",
- .codec_dai_name = "ssm2602-hifi",
- .platform_name = "bfin-i2s-pcm-audio",
- .codec_name = "ssm2602.0-001b",
- .ops = &bf5xx_ssm2602_ops,
- .dai_fmt = BF5XX_SSM2602_DAIFMT,
- },
-};
-
-static struct snd_soc_card bf5xx_ssm2602 = {
- .name = "bfin-ssm2602",
- .owner = THIS_MODULE,
- .dai_link = &bf5xx_ssm2602_dai[CONFIG_SND_BF5XX_SPORT_NUM],
- .num_links = 1,
-};
-
-static struct platform_device *bf5xx_ssm2602_snd_device;
-
-static int __init bf5xx_ssm2602_init(void)
-{
- int ret;
-
- pr_debug("%s enter\n", __func__);
- bf5xx_ssm2602_snd_device = platform_device_alloc("soc-audio", -1);
- if (!bf5xx_ssm2602_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(bf5xx_ssm2602_snd_device, &bf5xx_ssm2602);
- ret = platform_device_add(bf5xx_ssm2602_snd_device);
-
- if (ret)
- platform_device_put(bf5xx_ssm2602_snd_device);
-
- return ret;
-}
-
-static void __exit bf5xx_ssm2602_exit(void)
-{
- pr_debug("%s enter\n", __func__);
- platform_device_unregister(bf5xx_ssm2602_snd_device);
-}
-
-module_init(bf5xx_ssm2602_init);
-module_exit(bf5xx_ssm2602_exit);
-
-/* Module information */
-MODULE_AUTHOR("Cliff Cai");
-MODULE_DESCRIPTION("ALSA SoC SSM2602 BF527-EZKIT");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-tdm-pcm.c b/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-tdm-pcm.c
deleted file mode 100644
index 254490cf..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-tdm-pcm.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * File: sound/soc/blackfin/bf5xx-tdm-pcm.c
- * Author: Barry Song <Barry.Song@analog.com>
- *
- * Created: Tue June 06 2009
- * Description: DMA driver for tdm codec
- *
- * Modified:
- * Copyright 2009 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/gfp.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/dma.h>
-
-#include "bf5xx-tdm-pcm.h"
-#include "bf5xx-tdm.h"
-#include "bf5xx-sport.h"
-
-#define PCM_BUFFER_MAX 0x8000
-#define FRAGMENT_SIZE_MIN (4*1024)
-#define FRAGMENTS_MIN 2
-#define FRAGMENTS_MAX 32
-
-static void bf5xx_dma_irq(void *data)
-{
- struct snd_pcm_substream *pcm = data;
- snd_pcm_period_elapsed(pcm);
-}
-
-static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
- .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_RESUME),
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .channels_min = 2,
- .channels_max = 8,
- .buffer_bytes_max = PCM_BUFFER_MAX,
- .period_bytes_min = FRAGMENT_SIZE_MIN,
- .period_bytes_max = PCM_BUFFER_MAX/2,
- .periods_min = FRAGMENTS_MIN,
- .periods_max = FRAGMENTS_MAX,
-};
-
-static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- size_t size = bf5xx_pcm_hardware.buffer_bytes_max;
- snd_pcm_lib_malloc_pages(substream, size * 4);
-
- return 0;
-}
-
-static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- snd_pcm_lib_free_pages(substream);
-
- return 0;
-}
-
-static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct sport_device *sport = runtime->private_data;
- int fragsize_bytes = frames_to_bytes(runtime, runtime->period_size);
-
- fragsize_bytes /= runtime->channels;
- /* inflate the fragsize to match the dma width of SPORT */
- fragsize_bytes *= 8;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
- sport_config_tx_dma(sport, runtime->dma_area,
- runtime->periods, fragsize_bytes);
- } else {
- sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
- sport_config_rx_dma(sport, runtime->dma_area,
- runtime->periods, fragsize_bytes);
- }
-
- return 0;
-}
-
-static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct sport_device *sport = runtime->private_data;
- int ret = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- sport_tx_start(sport);
- else
- sport_rx_start(sport);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- sport_tx_stop(sport);
- else
- sport_rx_stop(sport);
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct sport_device *sport = runtime->private_data;
- unsigned int diff;
- snd_pcm_uframes_t frames;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- diff = sport_curr_offset_tx(sport);
- frames = diff / (8*4); /* 32 bytes per frame */
- } else {
- diff = sport_curr_offset_rx(sport);
- frames = diff / (8*4);
- }
- return frames;
-}
-
-static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
-
- int ret = 0;
-
- snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
-
- ret = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (ret < 0)
- goto out;
-
- if (sport_handle != NULL) {
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- sport_handle->tx_buf = buf->area;
- else
- sport_handle->rx_buf = buf->area;
-
- runtime->private_data = sport_handle;
- } else {
- pr_err("sport_handle is NULL\n");
- ret = -ENODEV;
- }
-out:
- return ret;
-}
-
-static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
- snd_pcm_uframes_t pos, void *buf, snd_pcm_uframes_t count)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct sport_device *sport = runtime->private_data;
- struct bf5xx_tdm_port *tdm_port = sport->private_data;
- unsigned int *src;
- unsigned int *dst;
- int i;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- src = buf;
- dst = (unsigned int *)substream->runtime->dma_area;
-
- dst += pos * 8;
- while (count--) {
- for (i = 0; i < substream->runtime->channels; i++)
- *(dst + tdm_port->tx_map[i]) = *src++;
- dst += 8;
- }
- } else {
- src = (unsigned int *)substream->runtime->dma_area;
- dst = buf;
-
- src += pos * 8;
- while (count--) {
- for (i = 0; i < substream->runtime->channels; i++)
- *dst++ = *(src + tdm_port->rx_map[i]);
- src += 8;
- }
- }
-
- return 0;
-}
-
-static int bf5xx_pcm_silence(struct snd_pcm_substream *substream,
- int channel, snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
-{
- unsigned char *buf = substream->runtime->dma_area;
- buf += pos * 8 * 4;
- memset(buf, '\0', count * 8 * 4);
-
- return 0;
-}
-
-
-struct snd_pcm_ops bf5xx_pcm_tdm_ops = {
- .open = bf5xx_pcm_open,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = bf5xx_pcm_hw_params,
- .hw_free = bf5xx_pcm_hw_free,
- .prepare = bf5xx_pcm_prepare,
- .trigger = bf5xx_pcm_trigger,
- .pointer = bf5xx_pcm_pointer,
- .copy = bf5xx_pcm_copy,
- .silence = bf5xx_pcm_silence,
-};
-
-static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
- struct snd_pcm_substream *substream = pcm->streams[stream].substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = bf5xx_pcm_hardware.buffer_bytes_max;
-
- buf->dev.type = SNDRV_DMA_TYPE_DEV;
- buf->dev.dev = pcm->card->dev;
- buf->private_data = NULL;
- buf->area = dma_alloc_coherent(pcm->card->dev, size * 4,
- &buf->addr, GFP_KERNEL);
- if (!buf->area) {
- pr_err("Failed to allocate dma memory - Please increase uncached DMA memory region\n");
- return -ENOMEM;
- }
- buf->bytes = size;
-
- return 0;
-}
-
-static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- struct snd_dma_buffer *buf;
- int stream;
-
- for (stream = 0; stream < 2; stream++) {
- substream = pcm->streams[stream].substream;
- if (!substream)
- continue;
-
- buf = &substream->dma_buffer;
- if (!buf->area)
- continue;
- dma_free_coherent(NULL, buf->bytes, buf->area, 0);
- buf->area = NULL;
- }
-}
-
-static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
-
-static int bf5xx_pcm_tdm_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- int ret = 0;
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &bf5xx_pcm_dmamask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_PLAYBACK);
- if (ret)
- goto out;
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_CAPTURE);
- if (ret)
- goto out;
- }
-out:
- return ret;
-}
-
-static struct snd_soc_platform_driver bf5xx_tdm_soc_platform = {
- .ops = &bf5xx_pcm_tdm_ops,
- .pcm_new = bf5xx_pcm_tdm_new,
- .pcm_free = bf5xx_pcm_free_dma_buffers,
-};
-
-static int __devinit bf5xx_soc_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_platform(&pdev->dev, &bf5xx_tdm_soc_platform);
-}
-
-static int __devexit bf5xx_soc_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver bfin_tdm_driver = {
- .driver = {
- .name = "bfin-tdm-pcm-audio",
- .owner = THIS_MODULE,
- },
-
- .probe = bf5xx_soc_platform_probe,
- .remove = __devexit_p(bf5xx_soc_platform_remove),
-};
-
-module_platform_driver(bfin_tdm_driver);
-
-MODULE_AUTHOR("Barry Song");
-MODULE_DESCRIPTION("ADI Blackfin TDM PCM DMA module");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-tdm-pcm.h b/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-tdm-pcm.h
deleted file mode 100644
index 7f8cc01c..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-tdm-pcm.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * sound/soc/blackfin/bf5xx-tdm-pcm.h -- ALSA PCM interface for the Blackfin
- *
- * Copyright 2009 Analog Device Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _BF5XX_TDM_PCM_H
-#define _BF5XX_TDM_PCM_H
-
-struct bf5xx_pcm_dma_params {
- char *name; /* stream identifier */
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-tdm.c b/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-tdm.c
deleted file mode 100644
index 594f8821..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-tdm.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * File: sound/soc/blackfin/bf5xx-tdm.c
- * Author: Barry Song <Barry.Song@analog.com>
- *
- * Created: Thurs June 04 2009
- * Description: Blackfin I2S(TDM) CPU DAI driver
- * Even though TDM mode can be as part of I2S DAI, but there
- * are so much difference in configuration and data flow,
- * it's very ugly to integrate I2S and TDM into a module
- *
- * Modified:
- * Copyright 2009 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include <asm/irq.h>
-#include <asm/portmux.h>
-#include <linux/mutex.h>
-#include <linux/gpio.h>
-
-#include "bf5xx-sport.h"
-#include "bf5xx-tdm.h"
-
-static int bf5xx_tdm_set_dai_fmt(struct snd_soc_dai *cpu_dai,
- unsigned int fmt)
-{
- int ret = 0;
-
- /* interface format:support TDM,slave mode */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- break;
- default:
- printk(KERN_ERR "%s: Unknown DAI format type\n", __func__);
- ret = -EINVAL;
- break;
- }
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- case SND_SOC_DAIFMT_CBM_CFS:
- case SND_SOC_DAIFMT_CBS_CFM:
- ret = -EINVAL;
- break;
- default:
- printk(KERN_ERR "%s: Unknown DAI master type\n", __func__);
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-static int bf5xx_tdm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
- struct bf5xx_tdm_port *bf5xx_tdm = sport_handle->private_data;
- int ret = 0;
-
- bf5xx_tdm->tcr2 &= ~0x1f;
- bf5xx_tdm->rcr2 &= ~0x1f;
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S32_LE:
- bf5xx_tdm->tcr2 |= 31;
- bf5xx_tdm->rcr2 |= 31;
- sport_handle->wdsize = 4;
- break;
- /* at present, we only support 32bit transfer */
- default:
- pr_err("not supported PCM format yet\n");
- return -EINVAL;
- break;
- }
-
- if (!bf5xx_tdm->configured) {
- /*
- * TX and RX are not independent,they are enabled at the
- * same time, even if only one side is running. So, we
- * need to configure both of them at the time when the first
- * stream is opened.
- *
- * CPU DAI:slave mode.
- */
- ret = sport_config_rx(sport_handle, bf5xx_tdm->rcr1,
- bf5xx_tdm->rcr2, 0, 0);
- if (ret) {
- pr_err("SPORT is busy!\n");
- return -EBUSY;
- }
-
- ret = sport_config_tx(sport_handle, bf5xx_tdm->tcr1,
- bf5xx_tdm->tcr2, 0, 0);
- if (ret) {
- pr_err("SPORT is busy!\n");
- return -EBUSY;
- }
-
- bf5xx_tdm->configured = 1;
- }
-
- return 0;
-}
-
-static void bf5xx_tdm_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
- struct bf5xx_tdm_port *bf5xx_tdm = sport_handle->private_data;
-
- /* No active stream, SPORT is allowed to be configured again. */
- if (!dai->active)
- bf5xx_tdm->configured = 0;
-}
-
-static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai,
- unsigned int tx_num, unsigned int *tx_slot,
- unsigned int rx_num, unsigned int *rx_slot)
-{
- struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
- struct bf5xx_tdm_port *bf5xx_tdm = sport_handle->private_data;
- int i;
- unsigned int slot;
- unsigned int tx_mapped = 0, rx_mapped = 0;
-
- if ((tx_num > BFIN_TDM_DAI_MAX_SLOTS) ||
- (rx_num > BFIN_TDM_DAI_MAX_SLOTS))
- return -EINVAL;
-
- for (i = 0; i < tx_num; i++) {
- slot = tx_slot[i];
- if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
- (!(tx_mapped & (1 << slot)))) {
- bf5xx_tdm->tx_map[i] = slot;
- tx_mapped |= 1 << slot;
- } else
- return -EINVAL;
- }
- for (i = 0; i < rx_num; i++) {
- slot = rx_slot[i];
- if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
- (!(rx_mapped & (1 << slot)))) {
- bf5xx_tdm->rx_map[i] = slot;
- rx_mapped |= 1 << slot;
- } else
- return -EINVAL;
- }
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int bf5xx_tdm_suspend(struct snd_soc_dai *dai)
-{
- struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
-
- if (dai->playback_active)
- sport_tx_stop(sport);
- if (dai->capture_active)
- sport_rx_stop(sport);
-
- /* isolate sync/clock pins from codec while sports resume */
- peripheral_free_list(sport->pin_req);
-
- return 0;
-}
-
-static int bf5xx_tdm_resume(struct snd_soc_dai *dai)
-{
- int ret;
- struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
-
- ret = sport_set_multichannel(sport, 8, 0xFF, 1);
- if (ret) {
- pr_err("SPORT is busy!\n");
- ret = -EBUSY;
- }
-
- ret = sport_config_rx(sport, 0, 0x1F, 0, 0);
- if (ret) {
- pr_err("SPORT is busy!\n");
- ret = -EBUSY;
- }
-
- ret = sport_config_tx(sport, 0, 0x1F, 0, 0);
- if (ret) {
- pr_err("SPORT is busy!\n");
- ret = -EBUSY;
- }
-
- peripheral_request_list(sport->pin_req, "soc-audio");
-
- return 0;
-}
-
-#else
-#define bf5xx_tdm_suspend NULL
-#define bf5xx_tdm_resume NULL
-#endif
-
-static const struct snd_soc_dai_ops bf5xx_tdm_dai_ops = {
- .hw_params = bf5xx_tdm_hw_params,
- .set_fmt = bf5xx_tdm_set_dai_fmt,
- .shutdown = bf5xx_tdm_shutdown,
- .set_channel_map = bf5xx_tdm_set_channel_map,
-};
-
-static struct snd_soc_dai_driver bf5xx_tdm_dai = {
- .suspend = bf5xx_tdm_suspend,
- .resume = bf5xx_tdm_resume,
- .playback = {
- .channels_min = 2,
- .channels_max = 8,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S32_LE,},
- .capture = {
- .channels_min = 2,
- .channels_max = 8,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S32_LE,},
- .ops = &bf5xx_tdm_dai_ops,
-};
-
-static int __devinit bfin_tdm_probe(struct platform_device *pdev)
-{
- struct sport_device *sport_handle;
- int ret;
-
- /* configure SPORT for TDM */
- sport_handle = sport_init(pdev, 4, 8 * sizeof(u32),
- sizeof(struct bf5xx_tdm_port));
- if (!sport_handle)
- return -ENODEV;
-
- /* SPORT works in TDM mode */
- ret = sport_set_multichannel(sport_handle, 8, 0xFF, 1);
- if (ret) {
- pr_err("SPORT is busy!\n");
- ret = -EBUSY;
- goto sport_config_err;
- }
-
- ret = sport_config_rx(sport_handle, 0, 0x1F, 0, 0);
- if (ret) {
- pr_err("SPORT is busy!\n");
- ret = -EBUSY;
- goto sport_config_err;
- }
-
- ret = sport_config_tx(sport_handle, 0, 0x1F, 0, 0);
- if (ret) {
- pr_err("SPORT is busy!\n");
- ret = -EBUSY;
- goto sport_config_err;
- }
-
- ret = snd_soc_register_dai(&pdev->dev, &bf5xx_tdm_dai);
- if (ret) {
- pr_err("Failed to register DAI: %d\n", ret);
- goto sport_config_err;
- }
-
- return 0;
-
-sport_config_err:
- sport_done(sport_handle);
- return ret;
-}
-
-static int __devexit bfin_tdm_remove(struct platform_device *pdev)
-{
- struct sport_device *sport_handle = platform_get_drvdata(pdev);
-
- snd_soc_unregister_dai(&pdev->dev);
- sport_done(sport_handle);
-
- return 0;
-}
-
-static struct platform_driver bfin_tdm_driver = {
- .probe = bfin_tdm_probe,
- .remove = __devexit_p(bfin_tdm_remove),
- .driver = {
- .name = "bfin-tdm",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(bfin_tdm_driver);
-
-/* Module information */
-MODULE_AUTHOR("Barry Song");
-MODULE_DESCRIPTION("TDM driver for ADI Blackfin");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-tdm.h b/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-tdm.h
deleted file mode 100644
index e986a3ea..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bf5xx-tdm.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * sound/soc/blackfin/bf5xx-tdm.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _BF5XX_TDM_H
-#define _BF5XX_TDM_H
-
-#define BFIN_TDM_DAI_MAX_SLOTS 8
-struct bf5xx_tdm_port {
- u16 tcr1;
- u16 rcr1;
- u16 tcr2;
- u16 rcr2;
- unsigned int tx_map[BFIN_TDM_DAI_MAX_SLOTS];
- unsigned int rx_map[BFIN_TDM_DAI_MAX_SLOTS];
- int configured;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bfin-eval-adau1373.c b/ANDROID_3.4.5/sound/soc/blackfin/bfin-eval-adau1373.c
deleted file mode 100644
index f3adbdbd..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bfin-eval-adau1373.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Machine driver for EVAL-ADAU1373 on Analog Devices bfin
- * evaluation boards.
- *
- * Copyright 2011 Analog Devices Inc.
- * Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include "../codecs/adau1373.h"
-
-static const struct snd_soc_dapm_widget bfin_eval_adau1373_dapm_widgets[] = {
- SND_SOC_DAPM_LINE("Line In1", NULL),
- SND_SOC_DAPM_LINE("Line In2", NULL),
- SND_SOC_DAPM_LINE("Line In3", NULL),
- SND_SOC_DAPM_LINE("Line In4", NULL),
-
- SND_SOC_DAPM_LINE("Line Out1", NULL),
- SND_SOC_DAPM_LINE("Line Out2", NULL),
- SND_SOC_DAPM_LINE("Stereo Out", NULL),
- SND_SOC_DAPM_HP("Headphone", NULL),
- SND_SOC_DAPM_HP("Earpiece", NULL),
- SND_SOC_DAPM_SPK("Speaker", NULL),
-};
-
-static const struct snd_soc_dapm_route bfin_eval_adau1373_dapm_routes[] = {
- { "AIN1L", NULL, "Line In1" },
- { "AIN1R", NULL, "Line In1" },
- { "AIN2L", NULL, "Line In2" },
- { "AIN2R", NULL, "Line In2" },
- { "AIN3L", NULL, "Line In3" },
- { "AIN3R", NULL, "Line In3" },
- { "AIN4L", NULL, "Line In4" },
- { "AIN4R", NULL, "Line In4" },
-
- /* MICBIAS can be connected via a jumper to the line-in jack, since w
- don't know which one is going to be used, just power both. */
- { "Line In1", NULL, "MICBIAS1" },
- { "Line In2", NULL, "MICBIAS1" },
- { "Line In3", NULL, "MICBIAS1" },
- { "Line In4", NULL, "MICBIAS1" },
- { "Line In1", NULL, "MICBIAS2" },
- { "Line In2", NULL, "MICBIAS2" },
- { "Line In3", NULL, "MICBIAS2" },
- { "Line In4", NULL, "MICBIAS2" },
-
- { "Line Out1", NULL, "LOUT1L" },
- { "Line Out1", NULL, "LOUT1R" },
- { "Line Out2", NULL, "LOUT2L" },
- { "Line Out2", NULL, "LOUT2R" },
- { "Headphone", NULL, "HPL" },
- { "Headphone", NULL, "HPR" },
- { "Earpiece", NULL, "EP" },
- { "Speaker", NULL, "SPKL" },
- { "Stereo Out", NULL, "SPKR" },
-};
-
-static int bfin_eval_adau1373_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int ret;
- int pll_rate;
-
- switch (params_rate(params)) {
- case 48000:
- case 8000:
- case 12000:
- case 16000:
- case 24000:
- case 32000:
- pll_rate = 48000 * 1024;
- break;
- case 44100:
- case 7350:
- case 11025:
- case 14700:
- case 22050:
- case 29400:
- pll_rate = 44100 * 1024;
- break;
- default:
- return -EINVAL;
- }
-
- ret = snd_soc_dai_set_pll(codec_dai, ADAU1373_PLL1,
- ADAU1373_PLL_SRC_MCLK1, 12288000, pll_rate);
- if (ret)
- return ret;
-
- ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1373_CLK_SRC_PLL1, pll_rate,
- SND_SOC_CLOCK_IN);
-
- return ret;
-}
-
-static int bfin_eval_adau1373_codec_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- unsigned int pll_rate = 48000 * 1024;
- int ret;
-
- ret = snd_soc_dai_set_pll(codec_dai, ADAU1373_PLL1,
- ADAU1373_PLL_SRC_MCLK1, 12288000, pll_rate);
- if (ret)
- return ret;
-
- ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1373_CLK_SRC_PLL1, pll_rate,
- SND_SOC_CLOCK_IN);
-
- return ret;
-}
-static struct snd_soc_ops bfin_eval_adau1373_ops = {
- .hw_params = bfin_eval_adau1373_hw_params,
-};
-
-static struct snd_soc_dai_link bfin_eval_adau1373_dai = {
- .name = "adau1373",
- .stream_name = "adau1373",
- .cpu_dai_name = "bfin-i2s.0",
- .codec_dai_name = "adau1373-aif1",
- .platform_name = "bfin-i2s-pcm-audio",
- .codec_name = "adau1373.0-001a",
- .ops = &bfin_eval_adau1373_ops,
- .init = bfin_eval_adau1373_codec_init,
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM,
-};
-
-static struct snd_soc_card bfin_eval_adau1373 = {
- .name = "bfin-eval-adau1373",
- .owner = THIS_MODULE,
- .dai_link = &bfin_eval_adau1373_dai,
- .num_links = 1,
-
- .dapm_widgets = bfin_eval_adau1373_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(bfin_eval_adau1373_dapm_widgets),
- .dapm_routes = bfin_eval_adau1373_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(bfin_eval_adau1373_dapm_routes),
-};
-
-static int bfin_eval_adau1373_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &bfin_eval_adau1373;
-
- card->dev = &pdev->dev;
-
- return snd_soc_register_card(&bfin_eval_adau1373);
-}
-
-static int __devexit bfin_eval_adau1373_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- snd_soc_unregister_card(card);
-
- return 0;
-}
-
-static struct platform_driver bfin_eval_adau1373_driver = {
- .driver = {
- .name = "bfin-eval-adau1373",
- .owner = THIS_MODULE,
- .pm = &snd_soc_pm_ops,
- },
- .probe = bfin_eval_adau1373_probe,
- .remove = __devexit_p(bfin_eval_adau1373_remove),
-};
-
-module_platform_driver(bfin_eval_adau1373_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("ALSA SoC bfin adau1373 driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:bfin-eval-adau1373");
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bfin-eval-adau1701.c b/ANDROID_3.4.5/sound/soc/blackfin/bfin-eval-adau1701.c
deleted file mode 100644
index b0531fc9..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bfin-eval-adau1701.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Machine driver for EVAL-ADAU1701MINIZ on Analog Devices bfin
- * evaluation boards.
- *
- * Copyright 2011 Analog Devices Inc.
- * Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include "../codecs/adau1701.h"
-
-static const struct snd_soc_dapm_widget bfin_eval_adau1701_dapm_widgets[] = {
- SND_SOC_DAPM_SPK("Speaker", NULL),
- SND_SOC_DAPM_LINE("Line Out", NULL),
- SND_SOC_DAPM_LINE("Line In", NULL),
-};
-
-static const struct snd_soc_dapm_route bfin_eval_adau1701_dapm_routes[] = {
- { "Speaker", NULL, "OUT0" },
- { "Speaker", NULL, "OUT1" },
- { "Line Out", NULL, "OUT2" },
- { "Line Out", NULL, "OUT3" },
-
- { "IN0", NULL, "Line In" },
- { "IN1", NULL, "Line In" },
-};
-
-static int bfin_eval_adau1701_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int ret;
-
- ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1701_CLK_SRC_OSC, 12288000,
- SND_SOC_CLOCK_IN);
-
- return ret;
-}
-
-static struct snd_soc_ops bfin_eval_adau1701_ops = {
- .hw_params = bfin_eval_adau1701_hw_params,
-};
-
-#define BFIN_EVAL_ADAU1701_DAI_FMT (SND_SOC_DAIFMT_I2S | \
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM)
-
-static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = {
- {
- .name = "adau1701",
- .stream_name = "adau1701",
- .cpu_dai_name = "bfin-i2s.0",
- .codec_dai_name = "adau1701",
- .platform_name = "bfin-i2s-pcm-audio",
- .codec_name = "adau1701.0-0034",
- .ops = &bfin_eval_adau1701_ops,
- .dai_fmt = BFIN_EVAL_ADAU1701_DAI_FMT,
- },
- {
- .name = "adau1701",
- .stream_name = "adau1701",
- .cpu_dai_name = "bfin-i2s.1",
- .codec_dai_name = "adau1701",
- .platform_name = "bfin-i2s-pcm-audio",
- .codec_name = "adau1701.0-0034",
- .ops = &bfin_eval_adau1701_ops,
- .dai_fmt = BFIN_EVAL_ADAU1701_DAI_FMT,
- },
-};
-
-static struct snd_soc_card bfin_eval_adau1701 = {
- .name = "bfin-eval-adau1701",
- .owner = THIS_MODULE,
- .dai_link = &bfin_eval_adau1701_dai[CONFIG_SND_BF5XX_SPORT_NUM],
- .num_links = 1,
-
- .dapm_widgets = bfin_eval_adau1701_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(bfin_eval_adau1701_dapm_widgets),
- .dapm_routes = bfin_eval_adau1701_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(bfin_eval_adau1701_dapm_routes),
-};
-
-static int bfin_eval_adau1701_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &bfin_eval_adau1701;
-
- card->dev = &pdev->dev;
-
- return snd_soc_register_card(&bfin_eval_adau1701);
-}
-
-static int __devexit bfin_eval_adau1701_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- snd_soc_unregister_card(card);
-
- return 0;
-}
-
-static struct platform_driver bfin_eval_adau1701_driver = {
- .driver = {
- .name = "bfin-eval-adau1701",
- .owner = THIS_MODULE,
- .pm = &snd_soc_pm_ops,
- },
- .probe = bfin_eval_adau1701_probe,
- .remove = __devexit_p(bfin_eval_adau1701_remove),
-};
-
-module_platform_driver(bfin_eval_adau1701_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("ALSA SoC bfin ADAU1701 driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:bfin-eval-adau1701");
diff --git a/ANDROID_3.4.5/sound/soc/blackfin/bfin-eval-adav80x.c b/ANDROID_3.4.5/sound/soc/blackfin/bfin-eval-adav80x.c
deleted file mode 100644
index 84b09987..00000000
--- a/ANDROID_3.4.5/sound/soc/blackfin/bfin-eval-adav80x.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Machine driver for EVAL-ADAV801 and EVAL-ADAV803 on Analog Devices bfin
- * evaluation boards.
- *
- * Copyright 2011 Analog Devices Inc.
- * Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include "../codecs/adav80x.h"
-
-static const struct snd_soc_dapm_widget bfin_eval_adav80x_dapm_widgets[] = {
- SND_SOC_DAPM_LINE("Line Out", NULL),
- SND_SOC_DAPM_LINE("Line In", NULL),
-};
-
-static const struct snd_soc_dapm_route bfin_eval_adav80x_dapm_routes[] = {
- { "Line Out", NULL, "VOUTL" },
- { "Line Out", NULL, "VOUTR" },
-
- { "VINL", NULL, "Line In" },
- { "VINR", NULL, "Line In" },
-};
-
-static int bfin_eval_adav80x_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int ret;
-
- ret = snd_soc_dai_set_pll(codec_dai, ADAV80X_PLL1, ADAV80X_PLL_SRC_XTAL,
- 27000000, params_rate(params) * 256);
- if (ret)
- return ret;
-
- ret = snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_PLL1,
- params_rate(params) * 256, SND_SOC_CLOCK_IN);
-
- return ret;
-}
-
-static int bfin_eval_adav80x_codec_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
-
- snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_SYSCLK1, 0,
- SND_SOC_CLOCK_OUT);
- snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_SYSCLK2, 0,
- SND_SOC_CLOCK_OUT);
- snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_SYSCLK3, 0,
- SND_SOC_CLOCK_OUT);
-
- snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_XTAL, 2700000, 0);
-
- return 0;
-}
-
-static struct snd_soc_ops bfin_eval_adav80x_ops = {
- .hw_params = bfin_eval_adav80x_hw_params,
-};
-
-static struct snd_soc_dai_link bfin_eval_adav80x_dais[] = {
- {
- .name = "adav80x",
- .stream_name = "ADAV80x HiFi",
- .cpu_dai_name = "bfin-i2s.0",
- .codec_dai_name = "adav80x-hifi",
- .platform_name = "bfin-i2s-pcm-audio",
- .init = bfin_eval_adav80x_codec_init,
- .ops = &bfin_eval_adav80x_ops,
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM,
- },
-};
-
-static struct snd_soc_card bfin_eval_adav80x = {
- .name = "bfin-eval-adav80x",
- .owner = THIS_MODULE,
- .dai_link = bfin_eval_adav80x_dais,
- .num_links = ARRAY_SIZE(bfin_eval_adav80x_dais),
-
- .dapm_widgets = bfin_eval_adav80x_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(bfin_eval_adav80x_dapm_widgets),
- .dapm_routes = bfin_eval_adav80x_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(bfin_eval_adav80x_dapm_routes),
-};
-
-enum bfin_eval_adav80x_type {
- BFIN_EVAL_ADAV801,
- BFIN_EVAL_ADAV803,
-};
-
-static int bfin_eval_adav80x_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &bfin_eval_adav80x;
- const char *codec_name;
-
- switch (platform_get_device_id(pdev)->driver_data) {
- case BFIN_EVAL_ADAV801:
- codec_name = "spi0.1";
- break;
- case BFIN_EVAL_ADAV803:
- codec_name = "adav803.0-0034";
- break;
- default:
- return -EINVAL;
- }
-
- bfin_eval_adav80x_dais[0].codec_name = codec_name;
-
- card->dev = &pdev->dev;
-
- return snd_soc_register_card(&bfin_eval_adav80x);
-}
-
-static int __devexit bfin_eval_adav80x_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- snd_soc_unregister_card(card);
-
- return 0;
-}
-
-static const struct platform_device_id bfin_eval_adav80x_ids[] = {
- { "bfin-eval-adav801", BFIN_EVAL_ADAV801 },
- { "bfin-eval-adav803", BFIN_EVAL_ADAV803 },
- { },
-};
-MODULE_DEVICE_TABLE(platform, bfin_eval_adav80x_ids);
-
-static struct platform_driver bfin_eval_adav80x_driver = {
- .driver = {
- .name = "bfin-eval-adav80x",
- .owner = THIS_MODULE,
- .pm = &snd_soc_pm_ops,
- },
- .probe = bfin_eval_adav80x_probe,
- .remove = __devexit_p(bfin_eval_adav80x_remove),
- .id_table = bfin_eval_adav80x_ids,
-};
-
-module_platform_driver(bfin_eval_adav80x_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("ALSA SoC bfin adav80x driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/88pm860x-codec.c b/ANDROID_3.4.5/sound/soc/codecs/88pm860x-codec.c
deleted file mode 100644
index 9fd3b682..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/88pm860x-codec.c
+++ /dev/null
@@ -1,1488 +0,0 @@
-/*
- * 88pm860x-codec.c -- 88PM860x ALSA SoC Audio Driver
- *
- * Copyright 2010 Marvell International Ltd.
- * Author: Haojian Zhuang <haojian.zhuang@marvell.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/platform_device.h>
-#include <linux/mfd/88pm860x.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/tlv.h>
-#include <sound/initval.h>
-#include <sound/jack.h>
-#include <trace/events/asoc.h>
-
-#include "88pm860x-codec.h"
-
-#define MAX_NAME_LEN 20
-#define REG_CACHE_SIZE 0x40
-#define REG_CACHE_BASE 0xb0
-
-/* Status Register 1 (0x01) */
-#define REG_STATUS_1 0x01
-#define MIC_STATUS (1 << 7)
-#define HOOK_STATUS (1 << 6)
-#define HEADSET_STATUS (1 << 5)
-
-/* Mic Detection Register (0x37) */
-#define REG_MIC_DET 0x37
-#define CONTINUOUS_POLLING (3 << 1)
-#define EN_MIC_DET (1 << 0)
-#define MICDET_MASK 0x07
-
-/* Headset Detection Register (0x38) */
-#define REG_HS_DET 0x38
-#define EN_HS_DET (1 << 0)
-
-/* Misc2 Register (0x42) */
-#define REG_MISC2 0x42
-#define AUDIO_PLL (1 << 5)
-#define AUDIO_SECTION_RESET (1 << 4)
-#define AUDIO_SECTION_ON (1 << 3)
-
-/* PCM Interface Register 2 (0xb1) */
-#define PCM_INF2_BCLK (1 << 6) /* Bit clock polarity */
-#define PCM_INF2_FS (1 << 5) /* Frame Sync polarity */
-#define PCM_INF2_MASTER (1 << 4) /* Master / Slave */
-#define PCM_INF2_18WL (1 << 3) /* 18 / 16 bits */
-#define PCM_GENERAL_I2S 0
-#define PCM_EXACT_I2S 1
-#define PCM_LEFT_I2S 2
-#define PCM_RIGHT_I2S 3
-#define PCM_SHORT_FS 4
-#define PCM_LONG_FS 5
-#define PCM_MODE_MASK 7
-
-/* I2S Interface Register 4 (0xbe) */
-#define I2S_EQU_BYP (1 << 6)
-
-/* DAC Offset Register (0xcb) */
-#define DAC_MUTE (1 << 7)
-#define MUTE_LEFT (1 << 6)
-#define MUTE_RIGHT (1 << 2)
-
-/* ADC Analog Register 1 (0xd0) */
-#define REG_ADC_ANA_1 0xd0
-#define MIC1BIAS_MASK 0x60
-
-/* Earpiece/Speaker Control Register 2 (0xda) */
-#define REG_EAR2 0xda
-#define RSYNC_CHANGE (1 << 2)
-
-/* Audio Supplies Register 2 (0xdc) */
-#define REG_SUPPLIES2 0xdc
-#define LDO15_READY (1 << 4)
-#define LDO15_EN (1 << 3)
-#define CPUMP_READY (1 << 2)
-#define CPUMP_EN (1 << 1)
-#define AUDIO_EN (1 << 0)
-#define SUPPLY_MASK (LDO15_EN | CPUMP_EN | AUDIO_EN)
-
-/* Audio Enable Register 1 (0xdd) */
-#define ADC_MOD_RIGHT (1 << 1)
-#define ADC_MOD_LEFT (1 << 0)
-
-/* Audio Enable Register 2 (0xde) */
-#define ADC_LEFT (1 << 5)
-#define ADC_RIGHT (1 << 4)
-
-/* DAC Enable Register 2 (0xe1) */
-#define DAC_LEFT (1 << 5)
-#define DAC_RIGHT (1 << 4)
-#define MODULATOR (1 << 3)
-
-/* Shorts Register (0xeb) */
-#define REG_SHORTS 0xeb
-#define CLR_SHORT_LO2 (1 << 7)
-#define SHORT_LO2 (1 << 6)
-#define CLR_SHORT_LO1 (1 << 5)
-#define SHORT_LO1 (1 << 4)
-#define CLR_SHORT_HS2 (1 << 3)
-#define SHORT_HS2 (1 << 2)
-#define CLR_SHORT_HS1 (1 << 1)
-#define SHORT_HS1 (1 << 0)
-
-/*
- * This widget should be just after DAC & PGA in DAPM power-on sequence and
- * before DAC & PGA in DAPM power-off sequence.
- */
-#define PM860X_DAPM_OUTPUT(wname, wevent) \
-{ .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \
- .shift = 0, .invert = 0, .kcontrol_news = NULL, \
- .num_kcontrols = 0, .event = wevent, \
- .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD, }
-
-struct pm860x_det {
- struct snd_soc_jack *hp_jack;
- struct snd_soc_jack *mic_jack;
- int hp_det;
- int mic_det;
- int hook_det;
- int hs_shrt;
- int lo_shrt;
-};
-
-struct pm860x_priv {
- unsigned int sysclk;
- unsigned int pcmclk;
- unsigned int dir;
- unsigned int filter;
- struct snd_soc_codec *codec;
- struct i2c_client *i2c;
- struct pm860x_chip *chip;
- struct pm860x_det det;
-
- int irq[4];
- unsigned char name[4][MAX_NAME_LEN];
-};
-
-/* -9450dB to 0dB in 150dB steps ( mute instead of -9450dB) */
-static const DECLARE_TLV_DB_SCALE(dpga_tlv, -9450, 150, 1);
-
-/* -9dB to 0db in 3dB steps */
-static const DECLARE_TLV_DB_SCALE(adc_tlv, -900, 300, 0);
-
-/* {-23, -17, -13.5, -11, -9, -6, -3, 0}dB */
-static const unsigned int mic_tlv[] = {
- TLV_DB_RANGE_HEAD(5),
- 0, 0, TLV_DB_SCALE_ITEM(-2300, 0, 0),
- 1, 1, TLV_DB_SCALE_ITEM(-1700, 0, 0),
- 2, 2, TLV_DB_SCALE_ITEM(-1350, 0, 0),
- 3, 3, TLV_DB_SCALE_ITEM(-1100, 0, 0),
- 4, 7, TLV_DB_SCALE_ITEM(-900, 300, 0),
-};
-
-/* {0, 0, 0, -6, 0, 6, 12, 18}dB */
-static const unsigned int aux_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 2, TLV_DB_SCALE_ITEM(0, 0, 0),
- 3, 7, TLV_DB_SCALE_ITEM(-600, 600, 0),
-};
-
-/* {-16, -13, -10, -7, -5.2, -3,3, -2.2, 0}dB, mute instead of -16dB */
-static const unsigned int out_tlv[] = {
- TLV_DB_RANGE_HEAD(4),
- 0, 3, TLV_DB_SCALE_ITEM(-1600, 300, 1),
- 4, 4, TLV_DB_SCALE_ITEM(-520, 0, 0),
- 5, 5, TLV_DB_SCALE_ITEM(-330, 0, 0),
- 6, 7, TLV_DB_SCALE_ITEM(-220, 220, 0),
-};
-
-static const unsigned int st_tlv[] = {
- TLV_DB_RANGE_HEAD(8),
- 0, 1, TLV_DB_SCALE_ITEM(-12041, 602, 0),
- 2, 3, TLV_DB_SCALE_ITEM(-11087, 250, 0),
- 4, 5, TLV_DB_SCALE_ITEM(-10643, 158, 0),
- 6, 7, TLV_DB_SCALE_ITEM(-10351, 116, 0),
- 8, 9, TLV_DB_SCALE_ITEM(-10133, 92, 0),
- 10, 13, TLV_DB_SCALE_ITEM(-9958, 70, 0),
- 14, 17, TLV_DB_SCALE_ITEM(-9689, 53, 0),
- 18, 271, TLV_DB_SCALE_ITEM(-9484, 37, 0),
-};
-
-/* Sidetone Gain = M * 2^(-5-N) */
-struct st_gain {
- unsigned int db;
- unsigned int m;
- unsigned int n;
-};
-
-static struct st_gain st_table[] = {
- {-12041, 1, 15}, {-11439, 1, 14}, {-11087, 3, 15}, {-10837, 1, 13},
- {-10643, 5, 15}, {-10485, 3, 14}, {-10351, 7, 15}, {-10235, 1, 12},
- {-10133, 9, 15}, {-10041, 5, 14}, { -9958, 11, 15}, { -9883, 3, 13},
- { -9813, 13, 15}, { -9749, 7, 14}, { -9689, 15, 15}, { -9633, 1, 11},
- { -9580, 17, 15}, { -9531, 9, 14}, { -9484, 19, 15}, { -9439, 5, 13},
- { -9397, 21, 15}, { -9356, 11, 14}, { -9318, 23, 15}, { -9281, 3, 12},
- { -9245, 25, 15}, { -9211, 13, 14}, { -9178, 27, 15}, { -9147, 7, 13},
- { -9116, 29, 15}, { -9087, 15, 14}, { -9058, 31, 15}, { -9031, 1, 10},
- { -8978, 17, 14}, { -8929, 9, 13}, { -8882, 19, 14}, { -8837, 5, 12},
- { -8795, 21, 14}, { -8754, 11, 13}, { -8716, 23, 14}, { -8679, 3, 11},
- { -8643, 25, 14}, { -8609, 13, 13}, { -8576, 27, 14}, { -8545, 7, 12},
- { -8514, 29, 14}, { -8485, 15, 13}, { -8456, 31, 14}, { -8429, 1, 9},
- { -8376, 17, 13}, { -8327, 9, 12}, { -8280, 19, 13}, { -8235, 5, 11},
- { -8193, 21, 13}, { -8152, 11, 12}, { -8114, 23, 13}, { -8077, 3, 10},
- { -8041, 25, 13}, { -8007, 13, 12}, { -7974, 27, 13}, { -7943, 7, 11},
- { -7912, 29, 13}, { -7883, 15, 12}, { -7854, 31, 13}, { -7827, 1, 8},
- { -7774, 17, 12}, { -7724, 9, 11}, { -7678, 19, 12}, { -7633, 5, 10},
- { -7591, 21, 12}, { -7550, 11, 11}, { -7512, 23, 12}, { -7475, 3, 9},
- { -7439, 25, 12}, { -7405, 13, 11}, { -7372, 27, 12}, { -7341, 7, 10},
- { -7310, 29, 12}, { -7281, 15, 11}, { -7252, 31, 12}, { -7225, 1, 7},
- { -7172, 17, 11}, { -7122, 9, 10}, { -7075, 19, 11}, { -7031, 5, 9},
- { -6989, 21, 11}, { -6948, 11, 10}, { -6910, 23, 11}, { -6873, 3, 8},
- { -6837, 25, 11}, { -6803, 13, 10}, { -6770, 27, 11}, { -6739, 7, 9},
- { -6708, 29, 11}, { -6679, 15, 10}, { -6650, 31, 11}, { -6623, 1, 6},
- { -6570, 17, 10}, { -6520, 9, 9}, { -6473, 19, 10}, { -6429, 5, 8},
- { -6386, 21, 10}, { -6346, 11, 9}, { -6307, 23, 10}, { -6270, 3, 7},
- { -6235, 25, 10}, { -6201, 13, 9}, { -6168, 27, 10}, { -6137, 7, 8},
- { -6106, 29, 10}, { -6077, 15, 9}, { -6048, 31, 10}, { -6021, 1, 5},
- { -5968, 17, 9}, { -5918, 9, 8}, { -5871, 19, 9}, { -5827, 5, 7},
- { -5784, 21, 9}, { -5744, 11, 8}, { -5705, 23, 9}, { -5668, 3, 6},
- { -5633, 25, 9}, { -5599, 13, 8}, { -5566, 27, 9}, { -5535, 7, 7},
- { -5504, 29, 9}, { -5475, 15, 8}, { -5446, 31, 9}, { -5419, 1, 4},
- { -5366, 17, 8}, { -5316, 9, 7}, { -5269, 19, 8}, { -5225, 5, 6},
- { -5182, 21, 8}, { -5142, 11, 7}, { -5103, 23, 8}, { -5066, 3, 5},
- { -5031, 25, 8}, { -4997, 13, 7}, { -4964, 27, 8}, { -4932, 7, 6},
- { -4902, 29, 8}, { -4873, 15, 7}, { -4844, 31, 8}, { -4816, 1, 3},
- { -4764, 17, 7}, { -4714, 9, 6}, { -4667, 19, 7}, { -4623, 5, 5},
- { -4580, 21, 7}, { -4540, 11, 6}, { -4501, 23, 7}, { -4464, 3, 4},
- { -4429, 25, 7}, { -4395, 13, 6}, { -4362, 27, 7}, { -4330, 7, 5},
- { -4300, 29, 7}, { -4270, 15, 6}, { -4242, 31, 7}, { -4214, 1, 2},
- { -4162, 17, 6}, { -4112, 9, 5}, { -4065, 19, 6}, { -4021, 5, 4},
- { -3978, 21, 6}, { -3938, 11, 5}, { -3899, 23, 6}, { -3862, 3, 3},
- { -3827, 25, 6}, { -3793, 13, 5}, { -3760, 27, 6}, { -3728, 7, 4},
- { -3698, 29, 6}, { -3668, 15, 5}, { -3640, 31, 6}, { -3612, 1, 1},
- { -3560, 17, 5}, { -3510, 9, 4}, { -3463, 19, 5}, { -3419, 5, 3},
- { -3376, 21, 5}, { -3336, 11, 4}, { -3297, 23, 5}, { -3260, 3, 2},
- { -3225, 25, 5}, { -3191, 13, 4}, { -3158, 27, 5}, { -3126, 7, 3},
- { -3096, 29, 5}, { -3066, 15, 4}, { -3038, 31, 5}, { -3010, 1, 0},
- { -2958, 17, 4}, { -2908, 9, 3}, { -2861, 19, 4}, { -2816, 5, 2},
- { -2774, 21, 4}, { -2734, 11, 3}, { -2695, 23, 4}, { -2658, 3, 1},
- { -2623, 25, 4}, { -2589, 13, 3}, { -2556, 27, 4}, { -2524, 7, 2},
- { -2494, 29, 4}, { -2464, 15, 3}, { -2436, 31, 4}, { -2408, 2, 0},
- { -2356, 17, 3}, { -2306, 9, 2}, { -2259, 19, 3}, { -2214, 5, 1},
- { -2172, 21, 3}, { -2132, 11, 2}, { -2093, 23, 3}, { -2056, 3, 0},
- { -2021, 25, 3}, { -1987, 13, 2}, { -1954, 27, 3}, { -1922, 7, 1},
- { -1892, 29, 3}, { -1862, 15, 2}, { -1834, 31, 3}, { -1806, 4, 0},
- { -1754, 17, 2}, { -1704, 9, 1}, { -1657, 19, 2}, { -1612, 5, 0},
- { -1570, 21, 2}, { -1530, 11, 1}, { -1491, 23, 2}, { -1454, 6, 0},
- { -1419, 25, 2}, { -1384, 13, 1}, { -1352, 27, 2}, { -1320, 7, 0},
- { -1290, 29, 2}, { -1260, 15, 1}, { -1232, 31, 2}, { -1204, 8, 0},
- { -1151, 17, 1}, { -1102, 9, 0}, { -1055, 19, 1}, { -1010, 10, 0},
- { -968, 21, 1}, { -928, 11, 0}, { -889, 23, 1}, { -852, 12, 0},
- { -816, 25, 1}, { -782, 13, 0}, { -750, 27, 1}, { -718, 14, 0},
- { -688, 29, 1}, { -658, 15, 0}, { -630, 31, 1}, { -602, 16, 0},
- { -549, 17, 0}, { -500, 18, 0}, { -453, 19, 0}, { -408, 20, 0},
- { -366, 21, 0}, { -325, 22, 0}, { -287, 23, 0}, { -250, 24, 0},
- { -214, 25, 0}, { -180, 26, 0}, { -148, 27, 0}, { -116, 28, 0},
- { -86, 29, 0}, { -56, 30, 0}, { -28, 31, 0}, { 0, 0, 0},
-};
-
-static int pm860x_volatile(unsigned int reg)
-{
- BUG_ON(reg >= REG_CACHE_SIZE);
-
- switch (reg) {
- case PM860X_AUDIO_SUPPLIES_2:
- return 1;
- }
-
- return 0;
-}
-
-static unsigned int pm860x_read_reg_cache(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- unsigned char *cache = codec->reg_cache;
-
- BUG_ON(reg >= REG_CACHE_SIZE);
-
- if (pm860x_volatile(reg))
- return cache[reg];
-
- reg += REG_CACHE_BASE;
-
- return pm860x_reg_read(codec->control_data, reg);
-}
-
-static int pm860x_write_reg_cache(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int value)
-{
- unsigned char *cache = codec->reg_cache;
-
- BUG_ON(reg >= REG_CACHE_SIZE);
-
- if (!pm860x_volatile(reg))
- cache[reg] = (unsigned char)value;
-
- reg += REG_CACHE_BASE;
-
- return pm860x_reg_write(codec->control_data, reg, value);
-}
-
-static int snd_soc_get_volsw_2r_st(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int reg = mc->reg;
- unsigned int reg2 = mc->rreg;
- int val[2], val2[2], i;
-
- val[0] = snd_soc_read(codec, reg) & 0x3f;
- val[1] = (snd_soc_read(codec, PM860X_SIDETONE_SHIFT) >> 4) & 0xf;
- val2[0] = snd_soc_read(codec, reg2) & 0x3f;
- val2[1] = (snd_soc_read(codec, PM860X_SIDETONE_SHIFT)) & 0xf;
-
- for (i = 0; i < ARRAY_SIZE(st_table); i++) {
- if ((st_table[i].m == val[0]) && (st_table[i].n == val[1]))
- ucontrol->value.integer.value[0] = i;
- if ((st_table[i].m == val2[0]) && (st_table[i].n == val2[1]))
- ucontrol->value.integer.value[1] = i;
- }
- return 0;
-}
-
-static int snd_soc_put_volsw_2r_st(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int reg = mc->reg;
- unsigned int reg2 = mc->rreg;
- int err;
- unsigned int val, val2;
-
- val = ucontrol->value.integer.value[0];
- val2 = ucontrol->value.integer.value[1];
-
- err = snd_soc_update_bits(codec, reg, 0x3f, st_table[val].m);
- if (err < 0)
- return err;
- err = snd_soc_update_bits(codec, PM860X_SIDETONE_SHIFT, 0xf0,
- st_table[val].n << 4);
- if (err < 0)
- return err;
-
- err = snd_soc_update_bits(codec, reg2, 0x3f, st_table[val2].m);
- if (err < 0)
- return err;
- err = snd_soc_update_bits(codec, PM860X_SIDETONE_SHIFT, 0x0f,
- st_table[val2].n);
- return err;
-}
-
-static int snd_soc_get_volsw_2r_out(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int reg = mc->reg;
- unsigned int reg2 = mc->rreg;
- unsigned int shift = mc->shift;
- int max = mc->max, val, val2;
- unsigned int mask = (1 << fls(max)) - 1;
-
- val = snd_soc_read(codec, reg) >> shift;
- val2 = snd_soc_read(codec, reg2) >> shift;
- ucontrol->value.integer.value[0] = (max - val) & mask;
- ucontrol->value.integer.value[1] = (max - val2) & mask;
-
- return 0;
-}
-
-static int snd_soc_put_volsw_2r_out(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int reg = mc->reg;
- unsigned int reg2 = mc->rreg;
- unsigned int shift = mc->shift;
- int max = mc->max;
- unsigned int mask = (1 << fls(max)) - 1;
- int err;
- unsigned int val, val2, val_mask;
-
- val_mask = mask << shift;
- val = ((max - ucontrol->value.integer.value[0]) & mask);
- val2 = ((max - ucontrol->value.integer.value[1]) & mask);
-
- val = val << shift;
- val2 = val2 << shift;
-
- err = snd_soc_update_bits(codec, reg, val_mask, val);
- if (err < 0)
- return err;
-
- err = snd_soc_update_bits(codec, reg2, val_mask, val2);
- return err;
-}
-
-/* DAPM Widget Events */
-/*
- * A lot registers are belong to RSYNC domain. It requires enabling RSYNC bit
- * after updating these registers. Otherwise, these updated registers won't
- * be effective.
- */
-static int pm860x_rsync_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
-
- /*
- * In order to avoid current on the load, mute power-on and power-off
- * should be transients.
- * Unmute by DAC_MUTE. It should be unmuted when DAPM sequence is
- * finished.
- */
- snd_soc_update_bits(codec, PM860X_DAC_OFFSET, DAC_MUTE, 0);
- snd_soc_update_bits(codec, PM860X_EAR_CTRL_2,
- RSYNC_CHANGE, RSYNC_CHANGE);
- return 0;
-}
-
-static int pm860x_dac_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- unsigned int dac = 0;
- int data;
-
- if (!strcmp(w->name, "Left DAC"))
- dac = DAC_LEFT;
- if (!strcmp(w->name, "Right DAC"))
- dac = DAC_RIGHT;
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- if (dac) {
- /* Auto mute in power-on sequence. */
- dac |= MODULATOR;
- snd_soc_update_bits(codec, PM860X_DAC_OFFSET,
- DAC_MUTE, DAC_MUTE);
- snd_soc_update_bits(codec, PM860X_EAR_CTRL_2,
- RSYNC_CHANGE, RSYNC_CHANGE);
- /* update dac */
- snd_soc_update_bits(codec, PM860X_DAC_EN_2,
- dac, dac);
- }
- break;
- case SND_SOC_DAPM_PRE_PMD:
- if (dac) {
- /* Auto mute in power-off sequence. */
- snd_soc_update_bits(codec, PM860X_DAC_OFFSET,
- DAC_MUTE, DAC_MUTE);
- snd_soc_update_bits(codec, PM860X_EAR_CTRL_2,
- RSYNC_CHANGE, RSYNC_CHANGE);
- /* update dac */
- data = snd_soc_read(codec, PM860X_DAC_EN_2);
- data &= ~dac;
- if (!(data & (DAC_LEFT | DAC_RIGHT)))
- data &= ~MODULATOR;
- snd_soc_write(codec, PM860X_DAC_EN_2, data);
- }
- break;
- }
- return 0;
-}
-
-static const char *pm860x_opamp_texts[] = {"-50%", "-25%", "0%", "75%"};
-
-static const char *pm860x_pa_texts[] = {"-33%", "0%", "33%", "66%"};
-
-static const struct soc_enum pm860x_hs1_opamp_enum =
- SOC_ENUM_SINGLE(PM860X_HS1_CTRL, 5, 4, pm860x_opamp_texts);
-
-static const struct soc_enum pm860x_hs2_opamp_enum =
- SOC_ENUM_SINGLE(PM860X_HS2_CTRL, 5, 4, pm860x_opamp_texts);
-
-static const struct soc_enum pm860x_hs1_pa_enum =
- SOC_ENUM_SINGLE(PM860X_HS1_CTRL, 3, 4, pm860x_pa_texts);
-
-static const struct soc_enum pm860x_hs2_pa_enum =
- SOC_ENUM_SINGLE(PM860X_HS2_CTRL, 3, 4, pm860x_pa_texts);
-
-static const struct soc_enum pm860x_lo1_opamp_enum =
- SOC_ENUM_SINGLE(PM860X_LO1_CTRL, 5, 4, pm860x_opamp_texts);
-
-static const struct soc_enum pm860x_lo2_opamp_enum =
- SOC_ENUM_SINGLE(PM860X_LO2_CTRL, 5, 4, pm860x_opamp_texts);
-
-static const struct soc_enum pm860x_lo1_pa_enum =
- SOC_ENUM_SINGLE(PM860X_LO1_CTRL, 3, 4, pm860x_pa_texts);
-
-static const struct soc_enum pm860x_lo2_pa_enum =
- SOC_ENUM_SINGLE(PM860X_LO2_CTRL, 3, 4, pm860x_pa_texts);
-
-static const struct soc_enum pm860x_spk_pa_enum =
- SOC_ENUM_SINGLE(PM860X_EAR_CTRL_1, 5, 4, pm860x_pa_texts);
-
-static const struct soc_enum pm860x_ear_pa_enum =
- SOC_ENUM_SINGLE(PM860X_EAR_CTRL_2, 0, 4, pm860x_pa_texts);
-
-static const struct soc_enum pm860x_spk_ear_opamp_enum =
- SOC_ENUM_SINGLE(PM860X_EAR_CTRL_1, 3, 4, pm860x_opamp_texts);
-
-static const struct snd_kcontrol_new pm860x_snd_controls[] = {
- SOC_DOUBLE_R_TLV("ADC Capture Volume", PM860X_ADC_ANA_2,
- PM860X_ADC_ANA_3, 6, 3, 0, adc_tlv),
- SOC_DOUBLE_TLV("AUX Capture Volume", PM860X_ADC_ANA_3, 0, 3, 7, 0,
- aux_tlv),
- SOC_SINGLE_TLV("MIC1 Capture Volume", PM860X_ADC_ANA_2, 0, 7, 0,
- mic_tlv),
- SOC_SINGLE_TLV("MIC3 Capture Volume", PM860X_ADC_ANA_2, 3, 7, 0,
- mic_tlv),
- SOC_DOUBLE_R_EXT_TLV("Sidetone Volume", PM860X_SIDETONE_L_GAIN,
- PM860X_SIDETONE_R_GAIN, 0, ARRAY_SIZE(st_table)-1,
- 0, snd_soc_get_volsw_2r_st,
- snd_soc_put_volsw_2r_st, st_tlv),
- SOC_SINGLE_TLV("Speaker Playback Volume", PM860X_EAR_CTRL_1,
- 0, 7, 0, out_tlv),
- SOC_DOUBLE_R_TLV("Line Playback Volume", PM860X_LO1_CTRL,
- PM860X_LO2_CTRL, 0, 7, 0, out_tlv),
- SOC_DOUBLE_R_TLV("Headset Playback Volume", PM860X_HS1_CTRL,
- PM860X_HS2_CTRL, 0, 7, 0, out_tlv),
- SOC_DOUBLE_R_EXT_TLV("Hifi Left Playback Volume",
- PM860X_HIFIL_GAIN_LEFT,
- PM860X_HIFIL_GAIN_RIGHT, 0, 63, 0,
- snd_soc_get_volsw_2r_out,
- snd_soc_put_volsw_2r_out, dpga_tlv),
- SOC_DOUBLE_R_EXT_TLV("Hifi Right Playback Volume",
- PM860X_HIFIR_GAIN_LEFT,
- PM860X_HIFIR_GAIN_RIGHT, 0, 63, 0,
- snd_soc_get_volsw_2r_out,
- snd_soc_put_volsw_2r_out, dpga_tlv),
- SOC_DOUBLE_R_EXT_TLV("Lofi Playback Volume", PM860X_LOFI_GAIN_LEFT,
- PM860X_LOFI_GAIN_RIGHT, 0, 63, 0,
- snd_soc_get_volsw_2r_out,
- snd_soc_put_volsw_2r_out, dpga_tlv),
- SOC_ENUM("Headset1 Operational Amplifier Current",
- pm860x_hs1_opamp_enum),
- SOC_ENUM("Headset2 Operational Amplifier Current",
- pm860x_hs2_opamp_enum),
- SOC_ENUM("Headset1 Amplifier Current", pm860x_hs1_pa_enum),
- SOC_ENUM("Headset2 Amplifier Current", pm860x_hs2_pa_enum),
- SOC_ENUM("Lineout1 Operational Amplifier Current",
- pm860x_lo1_opamp_enum),
- SOC_ENUM("Lineout2 Operational Amplifier Current",
- pm860x_lo2_opamp_enum),
- SOC_ENUM("Lineout1 Amplifier Current", pm860x_lo1_pa_enum),
- SOC_ENUM("Lineout2 Amplifier Current", pm860x_lo2_pa_enum),
- SOC_ENUM("Speaker Operational Amplifier Current",
- pm860x_spk_ear_opamp_enum),
- SOC_ENUM("Speaker Amplifier Current", pm860x_spk_pa_enum),
- SOC_ENUM("Earpiece Amplifier Current", pm860x_ear_pa_enum),
-};
-
-/*
- * DAPM Controls
- */
-
-/* PCM Switch / PCM Interface */
-static const struct snd_kcontrol_new pcm_switch_controls =
- SOC_DAPM_SINGLE("Switch", PM860X_ADC_EN_2, 0, 1, 0);
-
-/* AUX1 Switch */
-static const struct snd_kcontrol_new aux1_switch_controls =
- SOC_DAPM_SINGLE("Switch", PM860X_ANA_TO_ANA, 4, 1, 0);
-
-/* AUX2 Switch */
-static const struct snd_kcontrol_new aux2_switch_controls =
- SOC_DAPM_SINGLE("Switch", PM860X_ANA_TO_ANA, 5, 1, 0);
-
-/* Left Ex. PA Switch */
-static const struct snd_kcontrol_new lepa_switch_controls =
- SOC_DAPM_SINGLE("Switch", PM860X_DAC_EN_2, 2, 1, 0);
-
-/* Right Ex. PA Switch */
-static const struct snd_kcontrol_new repa_switch_controls =
- SOC_DAPM_SINGLE("Switch", PM860X_DAC_EN_2, 1, 1, 0);
-
-/* PCM Mux / Mux7 */
-static const char *aif1_text[] = {
- "PCM L", "PCM R",
-};
-
-static const struct soc_enum aif1_enum =
- SOC_ENUM_SINGLE(PM860X_PCM_IFACE_3, 6, 2, aif1_text);
-
-static const struct snd_kcontrol_new aif1_mux =
- SOC_DAPM_ENUM("PCM Mux", aif1_enum);
-
-/* I2S Mux / Mux9 */
-static const char *i2s_din_text[] = {
- "DIN", "DIN1",
-};
-
-static const struct soc_enum i2s_din_enum =
- SOC_ENUM_SINGLE(PM860X_I2S_IFACE_3, 1, 2, i2s_din_text);
-
-static const struct snd_kcontrol_new i2s_din_mux =
- SOC_DAPM_ENUM("I2S DIN Mux", i2s_din_enum);
-
-/* I2S Mic Mux / Mux8 */
-static const char *i2s_mic_text[] = {
- "Ex PA", "ADC",
-};
-
-static const struct soc_enum i2s_mic_enum =
- SOC_ENUM_SINGLE(PM860X_I2S_IFACE_3, 4, 2, i2s_mic_text);
-
-static const struct snd_kcontrol_new i2s_mic_mux =
- SOC_DAPM_ENUM("I2S Mic Mux", i2s_mic_enum);
-
-/* ADCL Mux / Mux2 */
-static const char *adcl_text[] = {
- "ADCR", "ADCL",
-};
-
-static const struct soc_enum adcl_enum =
- SOC_ENUM_SINGLE(PM860X_PCM_IFACE_3, 4, 2, adcl_text);
-
-static const struct snd_kcontrol_new adcl_mux =
- SOC_DAPM_ENUM("ADC Left Mux", adcl_enum);
-
-/* ADCR Mux / Mux3 */
-static const char *adcr_text[] = {
- "ADCL", "ADCR",
-};
-
-static const struct soc_enum adcr_enum =
- SOC_ENUM_SINGLE(PM860X_PCM_IFACE_3, 2, 2, adcr_text);
-
-static const struct snd_kcontrol_new adcr_mux =
- SOC_DAPM_ENUM("ADC Right Mux", adcr_enum);
-
-/* ADCR EC Mux / Mux6 */
-static const char *adcr_ec_text[] = {
- "ADCR", "EC",
-};
-
-static const struct soc_enum adcr_ec_enum =
- SOC_ENUM_SINGLE(PM860X_ADC_EN_2, 3, 2, adcr_ec_text);
-
-static const struct snd_kcontrol_new adcr_ec_mux =
- SOC_DAPM_ENUM("ADCR EC Mux", adcr_ec_enum);
-
-/* EC Mux / Mux4 */
-static const char *ec_text[] = {
- "Left", "Right", "Left + Right",
-};
-
-static const struct soc_enum ec_enum =
- SOC_ENUM_SINGLE(PM860X_EC_PATH, 1, 3, ec_text);
-
-static const struct snd_kcontrol_new ec_mux =
- SOC_DAPM_ENUM("EC Mux", ec_enum);
-
-static const char *dac_text[] = {
- "No input", "Right", "Left", "No input",
-};
-
-/* DAC Headset 1 Mux / Mux10 */
-static const struct soc_enum dac_hs1_enum =
- SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_1, 0, 4, dac_text);
-
-static const struct snd_kcontrol_new dac_hs1_mux =
- SOC_DAPM_ENUM("DAC HS1 Mux", dac_hs1_enum);
-
-/* DAC Headset 2 Mux / Mux11 */
-static const struct soc_enum dac_hs2_enum =
- SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_1, 2, 4, dac_text);
-
-static const struct snd_kcontrol_new dac_hs2_mux =
- SOC_DAPM_ENUM("DAC HS2 Mux", dac_hs2_enum);
-
-/* DAC Lineout 1 Mux / Mux12 */
-static const struct soc_enum dac_lo1_enum =
- SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_1, 4, 4, dac_text);
-
-static const struct snd_kcontrol_new dac_lo1_mux =
- SOC_DAPM_ENUM("DAC LO1 Mux", dac_lo1_enum);
-
-/* DAC Lineout 2 Mux / Mux13 */
-static const struct soc_enum dac_lo2_enum =
- SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_1, 6, 4, dac_text);
-
-static const struct snd_kcontrol_new dac_lo2_mux =
- SOC_DAPM_ENUM("DAC LO2 Mux", dac_lo2_enum);
-
-/* DAC Spearker Earphone Mux / Mux14 */
-static const struct soc_enum dac_spk_ear_enum =
- SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_2, 0, 4, dac_text);
-
-static const struct snd_kcontrol_new dac_spk_ear_mux =
- SOC_DAPM_ENUM("DAC SP Mux", dac_spk_ear_enum);
-
-/* Headset 1 Mux / Mux15 */
-static const char *in_text[] = {
- "Digital", "Analog",
-};
-
-static const struct soc_enum hs1_enum =
- SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 0, 2, in_text);
-
-static const struct snd_kcontrol_new hs1_mux =
- SOC_DAPM_ENUM("Headset1 Mux", hs1_enum);
-
-/* Headset 2 Mux / Mux16 */
-static const struct soc_enum hs2_enum =
- SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 1, 2, in_text);
-
-static const struct snd_kcontrol_new hs2_mux =
- SOC_DAPM_ENUM("Headset2 Mux", hs2_enum);
-
-/* Lineout 1 Mux / Mux17 */
-static const struct soc_enum lo1_enum =
- SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 2, 2, in_text);
-
-static const struct snd_kcontrol_new lo1_mux =
- SOC_DAPM_ENUM("Lineout1 Mux", lo1_enum);
-
-/* Lineout 2 Mux / Mux18 */
-static const struct soc_enum lo2_enum =
- SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 3, 2, in_text);
-
-static const struct snd_kcontrol_new lo2_mux =
- SOC_DAPM_ENUM("Lineout2 Mux", lo2_enum);
-
-/* Speaker Earpiece Demux */
-static const char *spk_text[] = {
- "Earpiece", "Speaker",
-};
-
-static const struct soc_enum spk_enum =
- SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 6, 2, spk_text);
-
-static const struct snd_kcontrol_new spk_demux =
- SOC_DAPM_ENUM("Speaker Earpiece Demux", spk_enum);
-
-/* MIC Mux / Mux1 */
-static const char *mic_text[] = {
- "Mic 1", "Mic 2",
-};
-
-static const struct soc_enum mic_enum =
- SOC_ENUM_SINGLE(PM860X_ADC_ANA_4, 4, 2, mic_text);
-
-static const struct snd_kcontrol_new mic_mux =
- SOC_DAPM_ENUM("MIC Mux", mic_enum);
-
-static const struct snd_soc_dapm_widget pm860x_dapm_widgets[] = {
- SND_SOC_DAPM_AIF_IN("PCM SDI", "PCM Playback", 0,
- PM860X_ADC_EN_2, 0, 0),
- SND_SOC_DAPM_AIF_OUT("PCM SDO", "PCM Capture", 0,
- PM860X_PCM_IFACE_3, 1, 1),
-
-
- SND_SOC_DAPM_AIF_IN("I2S DIN", "I2S Playback", 0,
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_AIF_IN("I2S DIN1", "I2S Playback", 0,
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_AIF_OUT("I2S DOUT", "I2S Capture", 0,
- PM860X_I2S_IFACE_3, 5, 1),
- SND_SOC_DAPM_SUPPLY("I2S CLK", PM860X_DAC_EN_2, 0, 0, NULL, 0),
- SND_SOC_DAPM_MUX("I2S Mic Mux", SND_SOC_NOPM, 0, 0, &i2s_mic_mux),
- SND_SOC_DAPM_MUX("ADC Left Mux", SND_SOC_NOPM, 0, 0, &adcl_mux),
- SND_SOC_DAPM_MUX("ADC Right Mux", SND_SOC_NOPM, 0, 0, &adcr_mux),
- SND_SOC_DAPM_MUX("EC Mux", SND_SOC_NOPM, 0, 0, &ec_mux),
- SND_SOC_DAPM_MUX("ADCR EC Mux", SND_SOC_NOPM, 0, 0, &adcr_ec_mux),
- SND_SOC_DAPM_SWITCH("Left EPA", SND_SOC_NOPM, 0, 0,
- &lepa_switch_controls),
- SND_SOC_DAPM_SWITCH("Right EPA", SND_SOC_NOPM, 0, 0,
- &repa_switch_controls),
-
- SND_SOC_DAPM_REG(snd_soc_dapm_supply, "Left ADC MOD", PM860X_ADC_EN_1,
- 0, 1, 1, 0),
- SND_SOC_DAPM_REG(snd_soc_dapm_supply, "Right ADC MOD", PM860X_ADC_EN_1,
- 1, 1, 1, 0),
- SND_SOC_DAPM_ADC("Left ADC", NULL, PM860X_ADC_EN_2, 5, 0),
- SND_SOC_DAPM_ADC("Right ADC", NULL, PM860X_ADC_EN_2, 4, 0),
-
- SND_SOC_DAPM_SWITCH("AUX1 Switch", SND_SOC_NOPM, 0, 0,
- &aux1_switch_controls),
- SND_SOC_DAPM_SWITCH("AUX2 Switch", SND_SOC_NOPM, 0, 0,
- &aux2_switch_controls),
-
- SND_SOC_DAPM_MUX("MIC Mux", SND_SOC_NOPM, 0, 0, &mic_mux),
- SND_SOC_DAPM_MICBIAS("Mic1 Bias", PM860X_ADC_ANA_1, 2, 0),
- SND_SOC_DAPM_MICBIAS("Mic3 Bias", PM860X_ADC_ANA_1, 7, 0),
- SND_SOC_DAPM_PGA("MIC1 Volume", PM860X_ADC_EN_1, 2, 0, NULL, 0),
- SND_SOC_DAPM_PGA("MIC3 Volume", PM860X_ADC_EN_1, 3, 0, NULL, 0),
- SND_SOC_DAPM_PGA("AUX1 Volume", PM860X_ADC_EN_1, 4, 0, NULL, 0),
- SND_SOC_DAPM_PGA("AUX2 Volume", PM860X_ADC_EN_1, 5, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Sidetone PGA", PM860X_ADC_EN_2, 1, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Lofi PGA", PM860X_ADC_EN_2, 2, 0, NULL, 0),
-
- SND_SOC_DAPM_INPUT("AUX1"),
- SND_SOC_DAPM_INPUT("AUX2"),
- SND_SOC_DAPM_INPUT("MIC1P"),
- SND_SOC_DAPM_INPUT("MIC1N"),
- SND_SOC_DAPM_INPUT("MIC2P"),
- SND_SOC_DAPM_INPUT("MIC2N"),
- SND_SOC_DAPM_INPUT("MIC3P"),
- SND_SOC_DAPM_INPUT("MIC3N"),
-
- SND_SOC_DAPM_DAC_E("Left DAC", NULL, SND_SOC_NOPM, 0, 0,
- pm860x_dac_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
- SND_SOC_DAPM_DAC_E("Right DAC", NULL, SND_SOC_NOPM, 0, 0,
- pm860x_dac_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
-
- SND_SOC_DAPM_MUX("I2S DIN Mux", SND_SOC_NOPM, 0, 0, &i2s_din_mux),
- SND_SOC_DAPM_MUX("DAC HS1 Mux", SND_SOC_NOPM, 0, 0, &dac_hs1_mux),
- SND_SOC_DAPM_MUX("DAC HS2 Mux", SND_SOC_NOPM, 0, 0, &dac_hs2_mux),
- SND_SOC_DAPM_MUX("DAC LO1 Mux", SND_SOC_NOPM, 0, 0, &dac_lo1_mux),
- SND_SOC_DAPM_MUX("DAC LO2 Mux", SND_SOC_NOPM, 0, 0, &dac_lo2_mux),
- SND_SOC_DAPM_MUX("DAC SP Mux", SND_SOC_NOPM, 0, 0, &dac_spk_ear_mux),
- SND_SOC_DAPM_MUX("Headset1 Mux", SND_SOC_NOPM, 0, 0, &hs1_mux),
- SND_SOC_DAPM_MUX("Headset2 Mux", SND_SOC_NOPM, 0, 0, &hs2_mux),
- SND_SOC_DAPM_MUX("Lineout1 Mux", SND_SOC_NOPM, 0, 0, &lo1_mux),
- SND_SOC_DAPM_MUX("Lineout2 Mux", SND_SOC_NOPM, 0, 0, &lo2_mux),
- SND_SOC_DAPM_MUX("Speaker Earpiece Demux", SND_SOC_NOPM, 0, 0,
- &spk_demux),
-
-
- SND_SOC_DAPM_PGA("Headset1 PGA", PM860X_DAC_EN_1, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Headset2 PGA", PM860X_DAC_EN_1, 1, 0, NULL, 0),
- SND_SOC_DAPM_OUTPUT("HS1"),
- SND_SOC_DAPM_OUTPUT("HS2"),
- SND_SOC_DAPM_PGA("Lineout1 PGA", PM860X_DAC_EN_1, 2, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Lineout2 PGA", PM860X_DAC_EN_1, 3, 0, NULL, 0),
- SND_SOC_DAPM_OUTPUT("LINEOUT1"),
- SND_SOC_DAPM_OUTPUT("LINEOUT2"),
- SND_SOC_DAPM_PGA("Earpiece PGA", PM860X_DAC_EN_1, 4, 0, NULL, 0),
- SND_SOC_DAPM_OUTPUT("EARP"),
- SND_SOC_DAPM_OUTPUT("EARN"),
- SND_SOC_DAPM_PGA("Speaker PGA", PM860X_DAC_EN_1, 5, 0, NULL, 0),
- SND_SOC_DAPM_OUTPUT("LSP"),
- SND_SOC_DAPM_OUTPUT("LSN"),
- SND_SOC_DAPM_REG(snd_soc_dapm_supply, "VCODEC", PM860X_AUDIO_SUPPLIES_2,
- 0, SUPPLY_MASK, SUPPLY_MASK, 0),
-
- PM860X_DAPM_OUTPUT("RSYNC", pm860x_rsync_event),
-};
-
-static const struct snd_soc_dapm_route pm860x_dapm_routes[] = {
- /* supply */
- {"Left DAC", NULL, "VCODEC"},
- {"Right DAC", NULL, "VCODEC"},
- {"Left ADC", NULL, "VCODEC"},
- {"Right ADC", NULL, "VCODEC"},
- {"Left ADC", NULL, "Left ADC MOD"},
- {"Right ADC", NULL, "Right ADC MOD"},
-
- /* I2S Clock */
- {"I2S DIN", NULL, "I2S CLK"},
- {"I2S DIN1", NULL, "I2S CLK"},
- {"I2S DOUT", NULL, "I2S CLK"},
-
- /* PCM/AIF1 Inputs */
- {"PCM SDO", NULL, "ADC Left Mux"},
- {"PCM SDO", NULL, "ADCR EC Mux"},
-
- /* PCM/AFI2 Outputs */
- {"Lofi PGA", NULL, "PCM SDI"},
- {"Lofi PGA", NULL, "Sidetone PGA"},
- {"Left DAC", NULL, "Lofi PGA"},
- {"Right DAC", NULL, "Lofi PGA"},
-
- /* I2S/AIF2 Inputs */
- {"MIC Mux", "Mic 1", "MIC1P"},
- {"MIC Mux", "Mic 1", "MIC1N"},
- {"MIC Mux", "Mic 2", "MIC2P"},
- {"MIC Mux", "Mic 2", "MIC2N"},
- {"MIC1 Volume", NULL, "MIC Mux"},
- {"MIC3 Volume", NULL, "MIC3P"},
- {"MIC3 Volume", NULL, "MIC3N"},
- {"Left ADC", NULL, "MIC1 Volume"},
- {"Right ADC", NULL, "MIC3 Volume"},
- {"ADC Left Mux", "ADCR", "Right ADC"},
- {"ADC Left Mux", "ADCL", "Left ADC"},
- {"ADC Right Mux", "ADCL", "Left ADC"},
- {"ADC Right Mux", "ADCR", "Right ADC"},
- {"Left EPA", "Switch", "Left DAC"},
- {"Right EPA", "Switch", "Right DAC"},
- {"EC Mux", "Left", "Left DAC"},
- {"EC Mux", "Right", "Right DAC"},
- {"EC Mux", "Left + Right", "Left DAC"},
- {"EC Mux", "Left + Right", "Right DAC"},
- {"ADCR EC Mux", "ADCR", "ADC Right Mux"},
- {"ADCR EC Mux", "EC", "EC Mux"},
- {"I2S Mic Mux", "Ex PA", "Left EPA"},
- {"I2S Mic Mux", "Ex PA", "Right EPA"},
- {"I2S Mic Mux", "ADC", "ADC Left Mux"},
- {"I2S Mic Mux", "ADC", "ADCR EC Mux"},
- {"I2S DOUT", NULL, "I2S Mic Mux"},
-
- /* I2S/AIF2 Outputs */
- {"I2S DIN Mux", "DIN", "I2S DIN"},
- {"I2S DIN Mux", "DIN1", "I2S DIN1"},
- {"Left DAC", NULL, "I2S DIN Mux"},
- {"Right DAC", NULL, "I2S DIN Mux"},
- {"DAC HS1 Mux", "Left", "Left DAC"},
- {"DAC HS1 Mux", "Right", "Right DAC"},
- {"DAC HS2 Mux", "Left", "Left DAC"},
- {"DAC HS2 Mux", "Right", "Right DAC"},
- {"DAC LO1 Mux", "Left", "Left DAC"},
- {"DAC LO1 Mux", "Right", "Right DAC"},
- {"DAC LO2 Mux", "Left", "Left DAC"},
- {"DAC LO2 Mux", "Right", "Right DAC"},
- {"Headset1 Mux", "Digital", "DAC HS1 Mux"},
- {"Headset2 Mux", "Digital", "DAC HS2 Mux"},
- {"Lineout1 Mux", "Digital", "DAC LO1 Mux"},
- {"Lineout2 Mux", "Digital", "DAC LO2 Mux"},
- {"Headset1 PGA", NULL, "Headset1 Mux"},
- {"Headset2 PGA", NULL, "Headset2 Mux"},
- {"Lineout1 PGA", NULL, "Lineout1 Mux"},
- {"Lineout2 PGA", NULL, "Lineout2 Mux"},
- {"DAC SP Mux", "Left", "Left DAC"},
- {"DAC SP Mux", "Right", "Right DAC"},
- {"Speaker Earpiece Demux", "Speaker", "DAC SP Mux"},
- {"Speaker PGA", NULL, "Speaker Earpiece Demux"},
- {"Earpiece PGA", NULL, "Speaker Earpiece Demux"},
-
- {"RSYNC", NULL, "Headset1 PGA"},
- {"RSYNC", NULL, "Headset2 PGA"},
- {"RSYNC", NULL, "Lineout1 PGA"},
- {"RSYNC", NULL, "Lineout2 PGA"},
- {"RSYNC", NULL, "Speaker PGA"},
- {"RSYNC", NULL, "Speaker PGA"},
- {"RSYNC", NULL, "Earpiece PGA"},
- {"RSYNC", NULL, "Earpiece PGA"},
-
- {"HS1", NULL, "RSYNC"},
- {"HS2", NULL, "RSYNC"},
- {"LINEOUT1", NULL, "RSYNC"},
- {"LINEOUT2", NULL, "RSYNC"},
- {"LSP", NULL, "RSYNC"},
- {"LSN", NULL, "RSYNC"},
- {"EARP", NULL, "RSYNC"},
- {"EARN", NULL, "RSYNC"},
-};
-
-/*
- * Use MUTE_LEFT & MUTE_RIGHT to implement digital mute.
- * These bits can also be used to mute.
- */
-static int pm860x_digital_mute(struct snd_soc_dai *codec_dai, int mute)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- int data = 0, mask = MUTE_LEFT | MUTE_RIGHT;
-
- if (mute)
- data = mask;
- snd_soc_update_bits(codec, PM860X_DAC_OFFSET, mask, data);
- snd_soc_update_bits(codec, PM860X_EAR_CTRL_2,
- RSYNC_CHANGE, RSYNC_CHANGE);
- return 0;
-}
-
-static int pm860x_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- unsigned char inf = 0, mask = 0;
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- inf &= ~PCM_INF2_18WL;
- break;
- case SNDRV_PCM_FORMAT_S18_3LE:
- inf |= PCM_INF2_18WL;
- break;
- default:
- return -EINVAL;
- }
- mask |= PCM_INF2_18WL;
- snd_soc_update_bits(codec, PM860X_PCM_IFACE_2, mask, inf);
-
- /* sample rate */
- switch (params_rate(params)) {
- case 8000:
- inf = 0;
- break;
- case 16000:
- inf = 3;
- break;
- case 32000:
- inf = 6;
- break;
- case 48000:
- inf = 8;
- break;
- default:
- return -EINVAL;
- }
- snd_soc_update_bits(codec, PM860X_PCM_RATE, 0x0f, inf);
-
- return 0;
-}
-
-static int pm860x_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
- unsigned char inf = 0, mask = 0;
- int ret = -EINVAL;
-
- mask |= PCM_INF2_BCLK | PCM_INF2_FS | PCM_INF2_MASTER;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- case SND_SOC_DAIFMT_CBM_CFS:
- if (pm860x->dir == PM860X_CLK_DIR_OUT) {
- inf |= PCM_INF2_MASTER;
- ret = 0;
- }
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- if (pm860x->dir == PM860X_CLK_DIR_IN) {
- inf &= ~PCM_INF2_MASTER;
- ret = 0;
- }
- break;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- inf |= PCM_EXACT_I2S;
- ret = 0;
- break;
- }
- mask |= PCM_MODE_MASK;
- if (ret)
- return ret;
- snd_soc_update_bits(codec, PM860X_PCM_IFACE_2, mask, inf);
- return 0;
-}
-
-static int pm860x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
-
- if (dir == PM860X_CLK_DIR_OUT)
- pm860x->dir = PM860X_CLK_DIR_OUT;
- else {
- pm860x->dir = PM860X_CLK_DIR_IN;
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int pm860x_i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- unsigned char inf;
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- inf = 0;
- break;
- case SNDRV_PCM_FORMAT_S18_3LE:
- inf = PCM_INF2_18WL;
- break;
- default:
- return -EINVAL;
- }
- snd_soc_update_bits(codec, PM860X_I2S_IFACE_2, PCM_INF2_18WL, inf);
-
- /* sample rate */
- switch (params_rate(params)) {
- case 8000:
- inf = 0;
- break;
- case 11025:
- inf = 1;
- break;
- case 16000:
- inf = 3;
- break;
- case 22050:
- inf = 4;
- break;
- case 32000:
- inf = 6;
- break;
- case 44100:
- inf = 7;
- break;
- case 48000:
- inf = 8;
- break;
- default:
- return -EINVAL;
- }
- snd_soc_update_bits(codec, PM860X_I2S_IFACE_4, 0xf, inf);
-
- return 0;
-}
-
-static int pm860x_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
- unsigned char inf = 0, mask = 0;
-
- mask |= PCM_INF2_BCLK | PCM_INF2_FS | PCM_INF2_MASTER;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- if (pm860x->dir == PM860X_CLK_DIR_OUT)
- inf |= PCM_INF2_MASTER;
- else
- return -EINVAL;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- if (pm860x->dir == PM860X_CLK_DIR_IN)
- inf &= ~PCM_INF2_MASTER;
- else
- return -EINVAL;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- inf |= PCM_EXACT_I2S;
- break;
- default:
- return -EINVAL;
- }
- mask |= PCM_MODE_MASK;
- snd_soc_update_bits(codec, PM860X_I2S_IFACE_2, mask, inf);
- return 0;
-}
-
-static int pm860x_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- int data;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- /* Enable Audio PLL & Audio section */
- data = AUDIO_PLL | AUDIO_SECTION_ON;
- pm860x_reg_write(codec->control_data, REG_MISC2, data);
- udelay(300);
- data = AUDIO_PLL | AUDIO_SECTION_RESET
- | AUDIO_SECTION_ON;
- pm860x_reg_write(codec->control_data, REG_MISC2, data);
- }
- break;
-
- case SND_SOC_BIAS_OFF:
- data = AUDIO_PLL | AUDIO_SECTION_RESET | AUDIO_SECTION_ON;
- pm860x_set_bits(codec->control_data, REG_MISC2, data, 0);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-static const struct snd_soc_dai_ops pm860x_pcm_dai_ops = {
- .digital_mute = pm860x_digital_mute,
- .hw_params = pm860x_pcm_hw_params,
- .set_fmt = pm860x_pcm_set_dai_fmt,
- .set_sysclk = pm860x_set_dai_sysclk,
-};
-
-static const struct snd_soc_dai_ops pm860x_i2s_dai_ops = {
- .digital_mute = pm860x_digital_mute,
- .hw_params = pm860x_i2s_hw_params,
- .set_fmt = pm860x_i2s_set_dai_fmt,
- .set_sysclk = pm860x_set_dai_sysclk,
-};
-
-#define PM860X_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | \
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000)
-
-static struct snd_soc_dai_driver pm860x_dai[] = {
- {
- /* DAI PCM */
- .name = "88pm860x-pcm",
- .id = 1,
- .playback = {
- .stream_name = "PCM Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = PM860X_RATES,
- .formats = SNDRV_PCM_FORMAT_S16_LE | \
- SNDRV_PCM_FORMAT_S18_3LE,
- },
- .capture = {
- .stream_name = "PCM Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = PM860X_RATES,
- .formats = SNDRV_PCM_FORMAT_S16_LE | \
- SNDRV_PCM_FORMAT_S18_3LE,
- },
- .ops = &pm860x_pcm_dai_ops,
- }, {
- /* DAI I2S */
- .name = "88pm860x-i2s",
- .id = 2,
- .playback = {
- .stream_name = "I2S Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FORMAT_S16_LE | \
- SNDRV_PCM_FORMAT_S18_3LE,
- },
- .capture = {
- .stream_name = "I2S Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FORMAT_S16_LE | \
- SNDRV_PCM_FORMAT_S18_3LE,
- },
- .ops = &pm860x_i2s_dai_ops,
- },
-};
-
-static irqreturn_t pm860x_codec_handler(int irq, void *data)
-{
- struct pm860x_priv *pm860x = data;
- int status, shrt, report = 0, mic_report = 0;
- int mask;
-
- status = pm860x_reg_read(pm860x->i2c, REG_STATUS_1);
- shrt = pm860x_reg_read(pm860x->i2c, REG_SHORTS);
- mask = pm860x->det.hs_shrt | pm860x->det.hook_det | pm860x->det.lo_shrt
- | pm860x->det.hp_det;
-
-#ifndef CONFIG_SND_SOC_88PM860X_MODULE
- if (status & (HEADSET_STATUS | MIC_STATUS | SHORT_HS1 | SHORT_HS2 |
- SHORT_LO1 | SHORT_LO2))
- trace_snd_soc_jack_irq(dev_name(pm860x->codec->dev));
-#endif
-
- if ((pm860x->det.hp_det & SND_JACK_HEADPHONE)
- && (status & HEADSET_STATUS))
- report |= SND_JACK_HEADPHONE;
-
- if ((pm860x->det.mic_det & SND_JACK_MICROPHONE)
- && (status & MIC_STATUS))
- mic_report |= SND_JACK_MICROPHONE;
-
- if (pm860x->det.hs_shrt && (shrt & (SHORT_HS1 | SHORT_HS2)))
- report |= pm860x->det.hs_shrt;
-
- if (pm860x->det.hook_det && (status & HOOK_STATUS))
- report |= pm860x->det.hook_det;
-
- if (pm860x->det.lo_shrt && (shrt & (SHORT_LO1 | SHORT_LO2)))
- report |= pm860x->det.lo_shrt;
-
- if (report)
- snd_soc_jack_report(pm860x->det.hp_jack, report, mask);
- if (mic_report)
- snd_soc_jack_report(pm860x->det.mic_jack, SND_JACK_MICROPHONE,
- SND_JACK_MICROPHONE);
-
- dev_dbg(pm860x->codec->dev, "headphone report:0x%x, mask:%x\n",
- report, mask);
- dev_dbg(pm860x->codec->dev, "microphone report:0x%x\n", mic_report);
- return IRQ_HANDLED;
-}
-
-int pm860x_hs_jack_detect(struct snd_soc_codec *codec,
- struct snd_soc_jack *jack,
- int det, int hook, int hs_shrt, int lo_shrt)
-{
- struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
- int data;
-
- pm860x->det.hp_jack = jack;
- pm860x->det.hp_det = det;
- pm860x->det.hook_det = hook;
- pm860x->det.hs_shrt = hs_shrt;
- pm860x->det.lo_shrt = lo_shrt;
-
- if (det & SND_JACK_HEADPHONE)
- pm860x_set_bits(codec->control_data, REG_HS_DET,
- EN_HS_DET, EN_HS_DET);
- /* headset short detect */
- if (hs_shrt) {
- data = CLR_SHORT_HS2 | CLR_SHORT_HS1;
- pm860x_set_bits(codec->control_data, REG_SHORTS, data, data);
- }
- /* Lineout short detect */
- if (lo_shrt) {
- data = CLR_SHORT_LO2 | CLR_SHORT_LO1;
- pm860x_set_bits(codec->control_data, REG_SHORTS, data, data);
- }
-
- /* sync status */
- pm860x_codec_handler(0, pm860x);
- return 0;
-}
-EXPORT_SYMBOL_GPL(pm860x_hs_jack_detect);
-
-int pm860x_mic_jack_detect(struct snd_soc_codec *codec,
- struct snd_soc_jack *jack, int det)
-{
- struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
-
- pm860x->det.mic_jack = jack;
- pm860x->det.mic_det = det;
-
- if (det & SND_JACK_MICROPHONE)
- pm860x_set_bits(codec->control_data, REG_MIC_DET,
- MICDET_MASK, MICDET_MASK);
-
- /* sync status */
- pm860x_codec_handler(0, pm860x);
- return 0;
-}
-EXPORT_SYMBOL_GPL(pm860x_mic_jack_detect);
-
-static int pm860x_probe(struct snd_soc_codec *codec)
-{
- struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
- int i, ret;
-
- pm860x->codec = codec;
-
- codec->control_data = pm860x->i2c;
-
- for (i = 0; i < 4; i++) {
- ret = request_threaded_irq(pm860x->irq[i], NULL,
- pm860x_codec_handler, IRQF_ONESHOT,
- pm860x->name[i], pm860x);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to request IRQ!\n");
- goto out;
- }
- }
-
- pm860x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- ret = pm860x_bulk_read(codec->control_data, REG_CACHE_BASE,
- REG_CACHE_SIZE, codec->reg_cache);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to fill register cache: %d\n",
- ret);
- goto out;
- }
-
- return 0;
-
-out:
- while (--i >= 0)
- free_irq(pm860x->irq[i], pm860x);
- return ret;
-}
-
-static int pm860x_remove(struct snd_soc_codec *codec)
-{
- struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
- int i;
-
- for (i = 3; i >= 0; i--)
- free_irq(pm860x->irq[i], pm860x);
- pm860x_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_pm860x = {
- .probe = pm860x_probe,
- .remove = pm860x_remove,
- .read = pm860x_read_reg_cache,
- .write = pm860x_write_reg_cache,
- .reg_cache_size = REG_CACHE_SIZE,
- .reg_word_size = sizeof(u8),
- .set_bias_level = pm860x_set_bias_level,
-
- .controls = pm860x_snd_controls,
- .num_controls = ARRAY_SIZE(pm860x_snd_controls),
- .dapm_widgets = pm860x_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(pm860x_dapm_widgets),
- .dapm_routes = pm860x_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(pm860x_dapm_routes),
-};
-
-static int __devinit pm860x_codec_probe(struct platform_device *pdev)
-{
- struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
- struct pm860x_priv *pm860x;
- struct resource *res;
- int i, ret;
-
- pm860x = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_priv),
- GFP_KERNEL);
- if (pm860x == NULL)
- return -ENOMEM;
-
- pm860x->chip = chip;
- pm860x->i2c = (chip->id == CHIP_PM8607) ? chip->client
- : chip->companion;
- platform_set_drvdata(pdev, pm860x);
-
- for (i = 0; i < 4; i++) {
- res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
- if (!res) {
- dev_err(&pdev->dev, "Failed to get IRQ resources\n");
- goto out;
- }
- pm860x->irq[i] = res->start + chip->irq_base;
- strncpy(pm860x->name[i], res->name, MAX_NAME_LEN);
- }
-
- ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pm860x,
- pm860x_dai, ARRAY_SIZE(pm860x_dai));
- if (ret) {
- dev_err(&pdev->dev, "Failed to register codec\n");
- goto out;
- }
- return ret;
-
-out:
- platform_set_drvdata(pdev, NULL);
- return -EINVAL;
-}
-
-static int __devexit pm860x_codec_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- platform_set_drvdata(pdev, NULL);
- return 0;
-}
-
-static struct platform_driver pm860x_codec_driver = {
- .driver = {
- .name = "88pm860x-codec",
- .owner = THIS_MODULE,
- },
- .probe = pm860x_codec_probe,
- .remove = __devexit_p(pm860x_codec_remove),
-};
-
-module_platform_driver(pm860x_codec_driver);
-
-MODULE_DESCRIPTION("ASoC 88PM860x driver");
-MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:88pm860x-codec");
-
diff --git a/ANDROID_3.4.5/sound/soc/codecs/88pm860x-codec.h b/ANDROID_3.4.5/sound/soc/codecs/88pm860x-codec.h
deleted file mode 100644
index 3364ba4a..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/88pm860x-codec.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 88pm860x-codec.h -- 88PM860x ALSA SoC Audio Driver
- *
- * Copyright 2010 Marvell International Ltd.
- * Haojian Zhuang <haojian.zhuang@marvell.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __88PM860X_H
-#define __88PM860X_H
-
-/* The offset of these registers are 0xb0 */
-#define PM860X_PCM_IFACE_1 0x00
-#define PM860X_PCM_IFACE_2 0x01
-#define PM860X_PCM_IFACE_3 0x02
-#define PM860X_PCM_RATE 0x03
-#define PM860X_EC_PATH 0x04
-#define PM860X_SIDETONE_L_GAIN 0x05
-#define PM860X_SIDETONE_R_GAIN 0x06
-#define PM860X_SIDETONE_SHIFT 0x07
-#define PM860X_ADC_OFFSET_1 0x08
-#define PM860X_ADC_OFFSET_2 0x09
-#define PM860X_DMIC_DELAY 0x0a
-
-#define PM860X_I2S_IFACE_1 0x0b
-#define PM860X_I2S_IFACE_2 0x0c
-#define PM860X_I2S_IFACE_3 0x0d
-#define PM860X_I2S_IFACE_4 0x0e
-#define PM860X_EQUALIZER_N0_1 0x0f
-#define PM860X_EQUALIZER_N0_2 0x10
-#define PM860X_EQUALIZER_N1_1 0x11
-#define PM860X_EQUALIZER_N1_2 0x12
-#define PM860X_EQUALIZER_D1_1 0x13
-#define PM860X_EQUALIZER_D1_2 0x14
-#define PM860X_LOFI_GAIN_LEFT 0x15
-#define PM860X_LOFI_GAIN_RIGHT 0x16
-#define PM860X_HIFIL_GAIN_LEFT 0x17
-#define PM860X_HIFIL_GAIN_RIGHT 0x18
-#define PM860X_HIFIR_GAIN_LEFT 0x19
-#define PM860X_HIFIR_GAIN_RIGHT 0x1a
-#define PM860X_DAC_OFFSET 0x1b
-#define PM860X_OFFSET_LEFT_1 0x1c
-#define PM860X_OFFSET_LEFT_2 0x1d
-#define PM860X_OFFSET_RIGHT_1 0x1e
-#define PM860X_OFFSET_RIGHT_2 0x1f
-#define PM860X_ADC_ANA_1 0x20
-#define PM860X_ADC_ANA_2 0x21
-#define PM860X_ADC_ANA_3 0x22
-#define PM860X_ADC_ANA_4 0x23
-#define PM860X_ANA_TO_ANA 0x24
-#define PM860X_HS1_CTRL 0x25
-#define PM860X_HS2_CTRL 0x26
-#define PM860X_LO1_CTRL 0x27
-#define PM860X_LO2_CTRL 0x28
-#define PM860X_EAR_CTRL_1 0x29
-#define PM860X_EAR_CTRL_2 0x2a
-#define PM860X_AUDIO_SUPPLIES_1 0x2b
-#define PM860X_AUDIO_SUPPLIES_2 0x2c
-#define PM860X_ADC_EN_1 0x2d
-#define PM860X_ADC_EN_2 0x2e
-#define PM860X_DAC_EN_1 0x2f
-#define PM860X_DAC_EN_2 0x31
-#define PM860X_AUDIO_CAL_1 0x32
-#define PM860X_AUDIO_CAL_2 0x33
-#define PM860X_AUDIO_CAL_3 0x34
-#define PM860X_AUDIO_CAL_4 0x35
-#define PM860X_AUDIO_CAL_5 0x36
-#define PM860X_ANA_INPUT_SEL_1 0x37
-#define PM860X_ANA_INPUT_SEL_2 0x38
-
-#define PM860X_PCM_IFACE_4 0x39
-#define PM860X_I2S_IFACE_5 0x3a
-
-#define PM860X_SHORTS 0x3b
-#define PM860X_PLL_ADJ_1 0x3c
-#define PM860X_PLL_ADJ_2 0x3d
-
-/* bits definition */
-#define PM860X_CLK_DIR_IN 0
-#define PM860X_CLK_DIR_OUT 1
-
-#define PM860X_DET_HEADSET (1 << 0)
-#define PM860X_DET_MIC (1 << 1)
-#define PM860X_DET_HOOK (1 << 2)
-#define PM860X_SHORT_HEADSET (1 << 3)
-#define PM860X_SHORT_LINEOUT (1 << 4)
-#define PM860X_DET_MASK 0x1F
-
-extern int pm860x_hs_jack_detect(struct snd_soc_codec *, struct snd_soc_jack *,
- int, int, int, int);
-extern int pm860x_mic_jack_detect(struct snd_soc_codec *, struct snd_soc_jack *,
- int);
-
-#endif /* __88PM860X_H */
diff --git a/ANDROID_3.4.5/sound/soc/codecs/Kconfig b/ANDROID_3.4.5/sound/soc/codecs/Kconfig
deleted file mode 100644
index 7077ac69..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/Kconfig
+++ /dev/null
@@ -1,455 +0,0 @@
-# Helper to resolve issues with configs that have SPI enabled but I2C
-# modular, meaning we can't build the codec driver in with I2C support.
-# We use an ordered list of conditional defaults to pick the appropriate
-# setting - SPI can't be modular so that case doesn't need to be covered.
-config SND_SOC_I2C_AND_SPI
- tristate
- default m if I2C=m
- default y if I2C=y
- default y if SPI_MASTER=y
-
-config SND_SOC_ALL_CODECS
- tristate "Build all ASoC CODEC drivers"
- select SND_SOC_88PM860X if MFD_88PM860X
- select SND_SOC_L3
- select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS
- select SND_SOC_AD1836 if SPI_MASTER
- select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI
- select SND_SOC_AD1980 if SND_SOC_AC97_BUS
- select SND_SOC_AD73311
- select SND_SOC_ADAU1373 if I2C
- select SND_SOC_ADAV80X
- select SND_SOC_ADS117X
- select SND_SOC_AK4104 if SPI_MASTER
- select SND_SOC_AK4535 if I2C
- select SND_SOC_AK4641 if I2C
- select SND_SOC_AK4642 if I2C
- select SND_SOC_AK4671 if I2C
- select SND_SOC_ALC5623 if I2C
- select SND_SOC_ALC5632 if I2C
- select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
- select SND_SOC_CS42L51 if I2C
- select SND_SOC_CS42L73 if I2C
- select SND_SOC_CS4270 if I2C
- select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
- select SND_SOC_CX20442
- select SND_SOC_DA7210 if I2C
- select SND_SOC_DFBMCS320
- select SND_SOC_JZ4740_CODEC
- select SND_SOC_LM4857 if I2C
- select SND_SOC_MAX98088 if I2C
- select SND_SOC_MAX98095 if I2C
- select SND_SOC_MAX9850 if I2C
- select SND_SOC_MAX9768 if I2C
- select SND_SOC_MAX9877 if I2C
- select SND_SOC_PCM3008
- select SND_SOC_RT5631 if I2C
- select SND_SOC_SGTL5000 if I2C
- select SND_SOC_SN95031 if INTEL_SCU_IPC
- select SND_SOC_SPDIF
- select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI
- select SND_SOC_STA32X if I2C
- select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
- select SND_SOC_TLV320AIC23 if I2C
- select SND_SOC_TLV320AIC26 if SPI_MASTER
- select SND_SOC_TLV320AIC32X4 if I2C
- select SND_SOC_TLV320AIC3X if I2C
- select SND_SOC_TPA6130A2 if I2C
- select SND_SOC_TLV320DAC33 if I2C
- select SND_SOC_TWL4030 if TWL4030_CORE
- select SND_SOC_TWL6040 if TWL6040_CORE
- select SND_SOC_UDA134X
- select SND_SOC_UDA1380 if I2C
- select SND_SOC_WL1273 if MFD_WL1273_CORE
- select SND_SOC_WM1250_EV1 if I2C
- select SND_SOC_WM2000 if I2C
- select SND_SOC_WM2200 if I2C
- select SND_SOC_WM5100 if I2C
- select SND_SOC_WM8350 if MFD_WM8350
- select SND_SOC_WM8400 if MFD_WM8400
- select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
- select SND_SOC_WM8523 if I2C
- select SND_SOC_WM8580 if I2C
- select SND_SOC_WM8711 if SND_SOC_I2C_AND_SPI
- select SND_SOC_WM8727
- select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI
- select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI
- select SND_SOC_WM8737 if SND_SOC_I2C_AND_SPI
- select SND_SOC_WM8741 if SND_SOC_I2C_AND_SPI
- select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI
- select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI
- select SND_SOC_WM8770 if SPI_MASTER
- select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI
- select SND_SOC_WM8782
- select SND_SOC_WM8804 if SND_SOC_I2C_AND_SPI
- select SND_SOC_WM8900 if I2C
- select SND_SOC_WM8903 if I2C
- select SND_SOC_WM8904 if I2C
- select SND_SOC_WM8940 if I2C
- select SND_SOC_WM8955 if I2C
- select SND_SOC_WM8960 if I2C
- select SND_SOC_WM8961 if I2C
- select SND_SOC_WM8962 if I2C
- select SND_SOC_WM8971 if I2C
- select SND_SOC_WM8974 if I2C
- select SND_SOC_WM8978 if I2C
- select SND_SOC_WM8983 if SND_SOC_I2C_AND_SPI
- select SND_SOC_WM8985 if SND_SOC_I2C_AND_SPI
- select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
- select SND_SOC_WM8990 if I2C
- select SND_SOC_WM8991 if I2C
- select SND_SOC_WM8993 if I2C
- select SND_SOC_WM8994 if MFD_WM8994
- select SND_SOC_WM8995 if SND_SOC_I2C_AND_SPI
- select SND_SOC_WM8996 if I2C
- select SND_SOC_WM9081 if I2C
- select SND_SOC_WM9090 if I2C
- select SND_SOC_WM9705 if SND_SOC_AC97_BUS
- select SND_SOC_WM9712 if SND_SOC_AC97_BUS
- select SND_SOC_WM9713 if SND_SOC_AC97_BUS
- help
- Normally ASoC codec drivers are only built if a machine driver which
- uses them is also built since they are only usable with a machine
- driver. Selecting this option will allow these drivers to be built
- without an explicit machine driver for test and development purposes.
-
- Support for the bus types used to access the codecs to be built must
- be selected separately.
-
- If unsure select "N".
-
-config SND_SOC_88PM860X
- tristate
-
-config SND_SOC_WM_HUBS
- tristate
- default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y
- default m if SND_SOC_WM8993=m || SND_SOC_WM8994=m
-
-config SND_SOC_AC97_CODEC
- tristate
- select SND_AC97_CODEC
-
-config SND_SOC_AD1836
- tristate
-
-config SND_SOC_AD193X
- tristate
-
-config SND_SOC_AD1980
- tristate
-
-config SND_SOC_AD73311
- tristate
-
-config SND_SOC_ADAU1701
- select SND_SOC_SIGMADSP
- tristate
-
-config SND_SOC_ADAU1373
- tristate
-
-config SND_SOC_ADAV80X
- tristate
-
-config SND_SOC_ADS117X
- tristate
-
-config SND_SOC_AK4104
- tristate
-
-config SND_SOC_AK4535
- tristate
-
-config SND_SOC_AK4641
- tristate
-
-config SND_SOC_AK4642
- tristate
-
-config SND_SOC_AK4671
- tristate
-
-config SND_SOC_ALC5623
- tristate
-config SND_SOC_ALC5632
- tristate
-
-config SND_SOC_CQ0093VC
- tristate
-
-config SND_SOC_CS42L51
- tristate
-
-config SND_SOC_CS42L73
- tristate
-
-# Cirrus Logic CS4270 Codec
-config SND_SOC_CS4270
- tristate
-
-# Cirrus Logic CS4270 Codec VD = 3.3V Errata
-# Select if you are affected by the errata where the part will not function
-# if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will
-# not select any sample rates that require MCLK to be divided by 1.5.
-config SND_SOC_CS4270_VD33_ERRATA
- bool
- depends on SND_SOC_CS4270
-
-config SND_SOC_CS4271
- tristate
-
-config SND_SOC_CX20442
- tristate
-
-config SND_SOC_JZ4740_CODEC
- tristate
-
-config SND_SOC_L3
- tristate
-
-config SND_SOC_DA7210
- tristate
-
-config SND_SOC_DFBMCS320
- tristate
-
-config SND_SOC_DMIC
- tristate
-
-config SND_SOC_MAX98088
- tristate
-
-config SND_SOC_MAX98095
- tristate
-
-config SND_SOC_MAX9850
- tristate
-
-config SND_SOC_PCM3008
- tristate
-
-config SND_SOC_RT5631
- tristate
-
-#Freescale sgtl5000 codec
-config SND_SOC_SGTL5000
- tristate
-
-config SND_SOC_SIGMADSP
- tristate
- select CRC32
-
-config SND_SOC_SN95031
- tristate
-
-config SND_SOC_SPDIF
- tristate
-
-config SND_SOC_SSM2602
- tristate
-
-config SND_SOC_STA32X
- tristate
-
-config SND_SOC_STAC9766
- tristate
-
-config SND_SOC_TLV320AIC23
- tristate
-
-config SND_SOC_TLV320AIC26
- tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE
- depends on SPI
-
-config SND_SOC_TLV320AIC32X4
- tristate
-
-config SND_SOC_TLV320AIC3X
- tristate
-
-config SND_SOC_TLV320DAC33
- tristate
-
-config SND_SOC_TWL4030
- select MFD_TWL4030_AUDIO
- tristate
-
-config SND_SOC_TWL6040
- tristate
-
-config SND_SOC_UDA134X
- tristate
-
-config SND_SOC_UDA1380
- tristate
-
-config SND_SOC_WL1273
- tristate
-
-config SND_SOC_WM1250_EV1
- tristate
-
-config SND_SOC_WM2000
- tristate
-
-config SND_SOC_WM2200
- tristate
-
-config SND_SOC_WM5100
- tristate
-
-config SND_SOC_WM8350
- tristate
-
-config SND_SOC_WM8400
- tristate
-
-config SND_SOC_WM8510
- tristate
-
-config SND_SOC_WM8523
- tristate
-
-config SND_SOC_WM8580
- tristate
-
-config SND_SOC_WM8711
- tristate
-
-config SND_SOC_WM8727
- tristate
-
-config SND_SOC_WM8728
- tristate
-
-config SND_SOC_WM8731
- tristate
-
-config SND_SOC_WM8737
- tristate
-
-config SND_SOC_WM8741
- tristate
-
-config SND_SOC_WM8750
- tristate
-
-config SND_SOC_VT1602
- tristate
- depends on SND_SOC
-
-config SND_SOC_VT1603
- tristate
- depends on SND_SOC
-
-config SND_SOC_HWDAC
- tristate
- depends on SND_SOC
-
-config SND_SOC_WM8753
- tristate
-
-config SND_SOC_WM8770
- tristate
-
-config SND_SOC_WM8776
- tristate
-
-config SND_SOC_WM8782
- tristate
-
-config SND_SOC_WM8804
- tristate
-
-config SND_SOC_WM8900
- tristate
-
-config SND_SOC_WM8903
- tristate
-
-config SND_SOC_WM8904
- tristate
-
-config SND_SOC_WM8940
- tristate
-
-config SND_SOC_WM8955
- tristate
-
-config SND_SOC_WM8960
- tristate
-
-config SND_SOC_WM8961
- tristate
-
-config SND_SOC_WM8962
- tristate
-
-config SND_SOC_WM8971
- tristate
-
-config SND_SOC_WM8974
- tristate
-
-config SND_SOC_WM8978
- tristate
-
-config SND_SOC_WM8983
- tristate
-
-config SND_SOC_WM8985
- tristate
-
-config SND_SOC_WM8988
- tristate
-
-config SND_SOC_WM8990
- tristate
-
-config SND_SOC_WM8991
- tristate
-
-config SND_SOC_WM8993
- tristate
-
-config SND_SOC_WM8994
- tristate
-
-config SND_SOC_WM8995
- tristate
-
-config SND_SOC_WM8996
- tristate
-
-config SND_SOC_WM9081
- tristate
-
-config SND_SOC_WM9090
- tristate
-
-config SND_SOC_WM9705
- tristate
-
-config SND_SOC_WM9712
- tristate
-
-config SND_SOC_WM9713
- tristate
-
-# Amp
-config SND_SOC_LM4857
- tristate
-
-config SND_SOC_MAX9768
- tristate
-
-config SND_SOC_MAX9877
- tristate
-
-config SND_SOC_TPA6130A2
- tristate
-
-# echo cancellation
-config SND_SOC_WMT_FM34
- tristate
diff --git a/ANDROID_3.4.5/sound/soc/codecs/Makefile b/ANDROID_3.4.5/sound/soc/codecs/Makefile
deleted file mode 100644
index 83175a64..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/Makefile
+++ /dev/null
@@ -1,219 +0,0 @@
-snd-soc-88pm860x-objs := 88pm860x-codec.o
-snd-soc-ac97-objs := ac97.o
-snd-soc-ad1836-objs := ad1836.o
-snd-soc-ad193x-objs := ad193x.o
-snd-soc-ad1980-objs := ad1980.o
-snd-soc-ad73311-objs := ad73311.o
-snd-soc-adau1701-objs := adau1701.o
-snd-soc-adau1373-objs := adau1373.o
-snd-soc-adav80x-objs := adav80x.o
-snd-soc-ads117x-objs := ads117x.o
-snd-soc-ak4104-objs := ak4104.o
-snd-soc-ak4535-objs := ak4535.o
-snd-soc-ak4641-objs := ak4641.o
-snd-soc-ak4642-objs := ak4642.o
-snd-soc-ak4671-objs := ak4671.o
-snd-soc-cq93vc-objs := cq93vc.o
-snd-soc-cs42l51-objs := cs42l51.o
-snd-soc-cs42l73-objs := cs42l73.o
-snd-soc-cs4270-objs := cs4270.o
-snd-soc-cs4271-objs := cs4271.o
-snd-soc-cx20442-objs := cx20442.o
-snd-soc-da7210-objs := da7210.o
-snd-soc-dfbmcs320-objs := dfbmcs320.o
-snd-soc-dmic-objs := dmic.o
-snd-soc-jz4740-codec-objs := jz4740.o
-snd-soc-l3-objs := l3.o
-snd-soc-lm4857-objs := lm4857.o
-snd-soc-max9768-objs := max9768.o
-snd-soc-max98088-objs := max98088.o
-snd-soc-max98095-objs := max98095.o
-snd-soc-max9850-objs := max9850.o
-snd-soc-pcm3008-objs := pcm3008.o
-snd-soc-rt5631-objs := rt5631.o
-snd-soc-sgtl5000-objs := sgtl5000.o
-snd-soc-alc5623-objs := alc5623.o
-snd-soc-alc5632-objs := alc5632.o
-snd-soc-sigmadsp-objs := sigmadsp.o
-snd-soc-sn95031-objs := sn95031.o
-snd-soc-spdif-objs := spdif_transciever.o
-snd-soc-ssm2602-objs := ssm2602.o
-snd-soc-sta32x-objs := sta32x.o
-snd-soc-stac9766-objs := stac9766.o
-snd-soc-tlv320aic23-objs := tlv320aic23.o
-snd-soc-tlv320aic26-objs := tlv320aic26.o
-snd-soc-tlv320aic3x-objs := tlv320aic3x.o
-snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o
-snd-soc-tlv320dac33-objs := tlv320dac33.o
-snd-soc-twl4030-objs := twl4030.o
-snd-soc-twl6040-objs := twl6040.o
-snd-soc-uda134x-objs := uda134x.o
-snd-soc-uda1380-objs := uda1380.o
-snd-soc-wl1273-objs := wl1273.o
-snd-soc-wm1250-ev1-objs := wm1250-ev1.o
-snd-soc-wm2000-objs := wm2000.o
-snd-soc-wm2200-objs := wm2200.o
-snd-soc-wm5100-objs := wm5100.o wm5100-tables.o
-snd-soc-wm8350-objs := wm8350.o
-snd-soc-wm8400-objs := wm8400.o
-snd-soc-wm8510-objs := wm8510.o
-snd-soc-wm8523-objs := wm8523.o
-snd-soc-wm8580-objs := wm8580.o
-snd-soc-wm8711-objs := wm8711.o
-snd-soc-wm8727-objs := wm8727.o
-snd-soc-wm8728-objs := wm8728.o
-snd-soc-wm8731-objs := wm8731.o
-snd-soc-wm8737-objs := wm8737.o
-snd-soc-wm8741-objs := wm8741.o
-snd-soc-wm8750-objs := wm8750.o
-snd-soc-vt1602-objs := wmt_vt1602.o
-snd-soc-vt1603-objs := vt1603.o
-snd-soc-hwdac-objs := wmt_hwdac.o
-snd-soc-wm8753-objs := wm8753.o
-snd-soc-wm8770-objs := wm8770.o
-snd-soc-wm8776-objs := wm8776.o
-snd-soc-wm8782-objs := wm8782.o
-snd-soc-wm8804-objs := wm8804.o
-snd-soc-wm8900-objs := wm8900.o
-snd-soc-wm8903-objs := wm8903.o
-snd-soc-wm8904-objs := wm8904.o
-snd-soc-wm8996-objs := wm8996.o
-snd-soc-wm8940-objs := wm8940.o
-snd-soc-wm8955-objs := wm8955.o
-snd-soc-wm8960-objs := wm8960.o
-snd-soc-wm8961-objs := wm8961.o
-snd-soc-wm8962-objs := wm8962.o
-snd-soc-wm8971-objs := wm8971.o
-snd-soc-wm8974-objs := wm8974.o
-snd-soc-wm8978-objs := wm8978.o
-snd-soc-wm8983-objs := wm8983.o
-snd-soc-wm8985-objs := wm8985.o
-snd-soc-wm8988-objs := wm8988.o
-snd-soc-wm8990-objs := wm8990.o
-snd-soc-wm8991-objs := wm8991.o
-snd-soc-wm8993-objs := wm8993.o
-snd-soc-wm8994-objs := wm8994.o wm8958-dsp2.o
-snd-soc-wm8995-objs := wm8995.o
-snd-soc-wm9081-objs := wm9081.o
-snd-soc-wm9090-objs := wm9090.o
-snd-soc-wm9705-objs := wm9705.o
-snd-soc-wm9712-objs := wm9712.o
-snd-soc-wm9713-objs := wm9713.o
-snd-soc-wm-hubs-objs := wm_hubs.o
-
-# Amp
-snd-soc-max9877-objs := max9877.o
-snd-soc-tpa6130a2-objs := tpa6130a2.o
-
-# echo cancellation
-snd-soc-wmt-fm34-objs := wmt_fm34.o
-
-obj-$(CONFIG_SND_SOC_88PM860X) += snd-soc-88pm860x.o
-obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
-obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
-obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o
-obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
-obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
-obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o
-obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o
-obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o
-obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
-obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
-obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
-obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o
-obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
-obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
-obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
-obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o
-obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
-obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
-obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o
-obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
-obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o
-obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
-obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
-obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o
-obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
-obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
-obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
-obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
-obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o
-obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
-obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
-obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
-obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
-obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
-obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
-obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o
-obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o
-obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
-obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
-obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o
-obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
-obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
-obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
-obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
-obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o
-obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
-obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
-obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
-obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
-obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
-obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o
-obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
-obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
-obj-$(CONFIG_SND_SOC_WM2200) += snd-soc-wm2200.o
-obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o
-obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
-obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
-obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
-obj-$(CONFIG_SND_SOC_WM8523) += snd-soc-wm8523.o
-obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o
-obj-$(CONFIG_SND_SOC_WM8711) += snd-soc-wm8711.o
-obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o
-obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o
-obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
-obj-$(CONFIG_SND_SOC_WM8737) += snd-soc-wm8737.o
-obj-$(CONFIG_SND_SOC_WM8741) += snd-soc-wm8741.o
-obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
-obj-$(CONFIG_SND_SOC_VT1602) += snd-soc-vt1602.o
-obj-$(CONFIG_SND_SOC_VT1603) += snd-soc-vt1603.o
-obj-$(CONFIG_SND_SOC_HWDAC) += snd-soc-hwdac.o
-obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
-obj-$(CONFIG_SND_SOC_WM8770) += snd-soc-wm8770.o
-obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o
-obj-$(CONFIG_SND_SOC_WM8782) += snd-soc-wm8782.o
-obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o
-obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
-obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
-obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o
-obj-$(CONFIG_SND_SOC_WM8996) += snd-soc-wm8996.o
-obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o
-obj-$(CONFIG_SND_SOC_WM8955) += snd-soc-wm8955.o
-obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o
-obj-$(CONFIG_SND_SOC_WM8961) += snd-soc-wm8961.o
-obj-$(CONFIG_SND_SOC_WM8962) += snd-soc-wm8962.o
-obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o
-obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o
-obj-$(CONFIG_SND_SOC_WM8978) += snd-soc-wm8978.o
-obj-$(CONFIG_SND_SOC_WM8983) += snd-soc-wm8983.o
-obj-$(CONFIG_SND_SOC_WM8985) += snd-soc-wm8985.o
-obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o
-obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
-obj-$(CONFIG_SND_SOC_WM8991) += snd-soc-wm8991.o
-obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o
-obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o
-obj-$(CONFIG_SND_SOC_WM8995) += snd-soc-wm8995.o
-obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o
-obj-$(CONFIG_SND_SOC_WM9090) += snd-soc-wm9090.o
-obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
-obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
-obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
-obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
-
-# Amp
-obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
-obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
-
-# echo cancellation
-obj-$(CONFIG_SND_SOC_WMT_FM34) += snd-soc-wmt-fm34.o
diff --git a/ANDROID_3.4.5/sound/soc/codecs/ac97.c b/ANDROID_3.4.5/sound/soc/codecs/ac97.c
deleted file mode 100644
index 1bbad4c1..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/ac97.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * ac97.c -- ALSA Soc AC97 codec support
- *
- * Copyright 2005 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood <lrg@slimlogic.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * Generic AC97 support.
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-static int ac97_prepare(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
-
- int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
- AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE;
- return snd_ac97_set_rate(codec->ac97, reg, runtime->rate);
-}
-
-#define STD_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\
- SNDRV_PCM_RATE_48000)
-
-static const struct snd_soc_dai_ops ac97_dai_ops = {
- .prepare = ac97_prepare,
-};
-
-static struct snd_soc_dai_driver ac97_dai = {
- .name = "ac97-hifi",
- .ac97_control = 1,
- .playback = {
- .stream_name = "AC97 Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = STD_AC97_RATES,
- .formats = SND_SOC_STD_AC97_FMTS,},
- .capture = {
- .stream_name = "AC97 Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = STD_AC97_RATES,
- .formats = SND_SOC_STD_AC97_FMTS,},
- .ops = &ac97_dai_ops,
-};
-
-static unsigned int ac97_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- return soc_ac97_ops.read(codec->ac97, reg);
-}
-
-static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int val)
-{
- soc_ac97_ops.write(codec->ac97, reg, val);
- return 0;
-}
-
-static int ac97_soc_probe(struct snd_soc_codec *codec)
-{
- struct snd_ac97_bus *ac97_bus;
- struct snd_ac97_template ac97_template;
- int ret;
-
- /* add codec as bus device for standard ac97 */
- ret = snd_ac97_bus(codec->card->snd_card, 0, &soc_ac97_ops, NULL, &ac97_bus);
- if (ret < 0)
- return ret;
-
- memset(&ac97_template, 0, sizeof(struct snd_ac97_template));
- ret = snd_ac97_mixer(ac97_bus, &ac97_template, &codec->ac97);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int ac97_soc_remove(struct snd_soc_codec *codec)
-{
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int ac97_soc_suspend(struct snd_soc_codec *codec)
-{
- snd_ac97_suspend(codec->ac97);
-
- return 0;
-}
-
-static int ac97_soc_resume(struct snd_soc_codec *codec)
-{
- snd_ac97_resume(codec->ac97);
-
- return 0;
-}
-#else
-#define ac97_soc_suspend NULL
-#define ac97_soc_resume NULL
-#endif
-
-static struct snd_soc_codec_driver soc_codec_dev_ac97 = {
- .write = ac97_write,
- .read = ac97_read,
- .probe = ac97_soc_probe,
- .remove = ac97_soc_remove,
- .suspend = ac97_soc_suspend,
- .resume = ac97_soc_resume,
-};
-
-static __devinit int ac97_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev,
- &soc_codec_dev_ac97, &ac97_dai, 1);
-}
-
-static int __devexit ac97_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver ac97_codec_driver = {
- .driver = {
- .name = "ac97-codec",
- .owner = THIS_MODULE,
- },
-
- .probe = ac97_probe,
- .remove = __devexit_p(ac97_remove),
-};
-
-module_platform_driver(ac97_codec_driver);
-
-MODULE_DESCRIPTION("Soc Generic AC97 driver");
-MODULE_AUTHOR("Liam Girdwood");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:ac97-codec");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/ad1836.c b/ANDROID_3.4.5/sound/soc/codecs/ad1836.c
deleted file mode 100644
index 12e3b411..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/ad1836.c
+++ /dev/null
@@ -1,398 +0,0 @@
- /*
- * Audio Codec driver supporting:
- * AD1835A, AD1836, AD1837A, AD1838A, AD1839A
- *
- * Copyright 2009-2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-#include <sound/tlv.h>
-#include <linux/spi/spi.h>
-#include "ad1836.h"
-
-enum ad1836_type {
- AD1835,
- AD1836,
- AD1838,
-};
-
-/* codec private data */
-struct ad1836_priv {
- enum ad1836_type type;
-};
-
-/*
- * AD1836 volume/mute/de-emphasis etc. controls
- */
-static const char *ad1836_deemp[] = {"None", "44.1kHz", "32kHz", "48kHz"};
-
-static const struct soc_enum ad1836_deemp_enum =
- SOC_ENUM_SINGLE(AD1836_DAC_CTRL1, 8, 4, ad1836_deemp);
-
-#define AD1836_DAC_VOLUME(x) \
- SOC_DOUBLE_R("DAC" #x " Playback Volume", AD1836_DAC_L_VOL(x), \
- AD1836_DAC_R_VOL(x), 0, 0x3FF, 0)
-
-#define AD1836_DAC_SWITCH(x) \
- SOC_DOUBLE("DAC" #x " Playback Switch", AD1836_DAC_CTRL2, \
- AD1836_MUTE_LEFT(x), AD1836_MUTE_RIGHT(x), 1, 1)
-
-#define AD1836_ADC_SWITCH(x) \
- SOC_DOUBLE("ADC" #x " Capture Switch", AD1836_ADC_CTRL2, \
- AD1836_MUTE_LEFT(x), AD1836_MUTE_RIGHT(x), 1, 1)
-
-static const struct snd_kcontrol_new ad183x_dac_controls[] = {
- AD1836_DAC_VOLUME(1),
- AD1836_DAC_SWITCH(1),
- AD1836_DAC_VOLUME(2),
- AD1836_DAC_SWITCH(2),
- AD1836_DAC_VOLUME(3),
- AD1836_DAC_SWITCH(3),
- AD1836_DAC_VOLUME(4),
- AD1836_DAC_SWITCH(4),
-};
-
-static const struct snd_soc_dapm_widget ad183x_dac_dapm_widgets[] = {
- SND_SOC_DAPM_OUTPUT("DAC1OUT"),
- SND_SOC_DAPM_OUTPUT("DAC2OUT"),
- SND_SOC_DAPM_OUTPUT("DAC3OUT"),
- SND_SOC_DAPM_OUTPUT("DAC4OUT"),
-};
-
-static const struct snd_soc_dapm_route ad183x_dac_routes[] = {
- { "DAC1OUT", NULL, "DAC" },
- { "DAC2OUT", NULL, "DAC" },
- { "DAC3OUT", NULL, "DAC" },
- { "DAC4OUT", NULL, "DAC" },
-};
-
-static const struct snd_kcontrol_new ad183x_adc_controls[] = {
- AD1836_ADC_SWITCH(1),
- AD1836_ADC_SWITCH(2),
- AD1836_ADC_SWITCH(3),
-};
-
-static const struct snd_soc_dapm_widget ad183x_adc_dapm_widgets[] = {
- SND_SOC_DAPM_INPUT("ADC1IN"),
- SND_SOC_DAPM_INPUT("ADC2IN"),
-};
-
-static const struct snd_soc_dapm_route ad183x_adc_routes[] = {
- { "ADC", NULL, "ADC1IN" },
- { "ADC", NULL, "ADC2IN" },
-};
-
-static const struct snd_kcontrol_new ad183x_controls[] = {
- /* ADC high-pass filter */
- SOC_SINGLE("ADC High Pass Filter Switch", AD1836_ADC_CTRL1,
- AD1836_ADC_HIGHPASS_FILTER, 1, 0),
-
- /* DAC de-emphasis */
- SOC_ENUM("Playback Deemphasis", ad1836_deemp_enum),
-};
-
-static const struct snd_soc_dapm_widget ad183x_dapm_widgets[] = {
- SND_SOC_DAPM_DAC("DAC", "Playback", AD1836_DAC_CTRL1,
- AD1836_DAC_POWERDOWN, 1),
- SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1836_ADC_CTRL1,
- AD1836_ADC_POWERDOWN, 1, NULL, 0),
-};
-
-static const struct snd_soc_dapm_route ad183x_dapm_routes[] = {
- { "DAC", NULL, "ADC_PWR" },
- { "ADC", NULL, "ADC_PWR" },
-};
-
-static const DECLARE_TLV_DB_SCALE(ad1836_in_tlv, 0, 300, 0);
-
-static const struct snd_kcontrol_new ad1836_controls[] = {
- SOC_DOUBLE_TLV("ADC2 Capture Volume", AD1836_ADC_CTRL1, 3, 0, 4, 0,
- ad1836_in_tlv),
-};
-
-/*
- * DAI ops entries
- */
-
-static int ad1836_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- /* at present, we support adc aux mode to interface with
- * blackfin sport tdm mode
- */
- case SND_SOC_DAIFMT_DSP_A:
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_IB_IF:
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- /* ALCLK,ABCLK are both output, AD1836 can only be master */
- case SND_SOC_DAIFMT_CBM_CFM:
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int ad1836_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- int word_len = 0;
-
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- word_len = AD1836_WORD_LEN_16;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- word_len = AD1836_WORD_LEN_20;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- case SNDRV_PCM_FORMAT_S32_LE:
- word_len = AD1836_WORD_LEN_24;
- break;
- }
-
- snd_soc_update_bits(codec, AD1836_DAC_CTRL1, AD1836_DAC_WORD_LEN_MASK,
- word_len << AD1836_DAC_WORD_LEN_OFFSET);
-
- snd_soc_update_bits(codec, AD1836_ADC_CTRL2, AD1836_ADC_WORD_LEN_MASK,
- word_len << AD1836_ADC_WORD_OFFSET);
-
- return 0;
-}
-
-static const struct snd_soc_dai_ops ad1836_dai_ops = {
- .hw_params = ad1836_hw_params,
- .set_fmt = ad1836_set_dai_fmt,
-};
-
-#define AD183X_DAI(_name, num_dacs, num_adcs) \
-{ \
- .name = _name "-hifi", \
- .playback = { \
- .stream_name = "Playback", \
- .channels_min = 2, \
- .channels_max = (num_dacs) * 2, \
- .rates = SNDRV_PCM_RATE_48000, \
- .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE | \
- SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE, \
- }, \
- .capture = { \
- .stream_name = "Capture", \
- .channels_min = 2, \
- .channels_max = (num_adcs) * 2, \
- .rates = SNDRV_PCM_RATE_48000, \
- .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE | \
- SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE, \
- }, \
- .ops = &ad1836_dai_ops, \
-}
-
-static struct snd_soc_dai_driver ad183x_dais[] = {
- [AD1835] = AD183X_DAI("ad1835", 4, 1),
- [AD1836] = AD183X_DAI("ad1836", 3, 2),
- [AD1838] = AD183X_DAI("ad1838", 3, 1),
-};
-
-#ifdef CONFIG_PM
-static int ad1836_suspend(struct snd_soc_codec *codec)
-{
- /* reset clock control mode */
- return snd_soc_update_bits(codec, AD1836_ADC_CTRL2,
- AD1836_ADC_SERFMT_MASK, 0);
-}
-
-static int ad1836_resume(struct snd_soc_codec *codec)
-{
- /* restore clock control mode */
- return snd_soc_update_bits(codec, AD1836_ADC_CTRL2,
- AD1836_ADC_SERFMT_MASK, AD1836_ADC_AUX);
-}
-#else
-#define ad1836_suspend NULL
-#define ad1836_resume NULL
-#endif
-
-static int ad1836_probe(struct snd_soc_codec *codec)
-{
- struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int num_dacs, num_adcs;
- int ret = 0;
- int i;
-
- num_dacs = ad183x_dais[ad1836->type].playback.channels_max / 2;
- num_adcs = ad183x_dais[ad1836->type].capture.channels_max / 2;
-
- ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI);
- if (ret < 0) {
- dev_err(codec->dev, "failed to set cache I/O: %d\n",
- ret);
- return ret;
- }
-
- /* default setting for ad1836 */
- /* de-emphasis: 48kHz, power-on dac */
- snd_soc_write(codec, AD1836_DAC_CTRL1, 0x300);
- /* unmute dac channels */
- snd_soc_write(codec, AD1836_DAC_CTRL2, 0x0);
- /* high-pass filter enable, power-on adc */
- snd_soc_write(codec, AD1836_ADC_CTRL1, 0x100);
- /* unmute adc channles, adc aux mode */
- snd_soc_write(codec, AD1836_ADC_CTRL2, 0x180);
- /* volume */
- for (i = 1; i <= num_dacs; ++i) {
- snd_soc_write(codec, AD1836_DAC_L_VOL(i), 0x3FF);
- snd_soc_write(codec, AD1836_DAC_R_VOL(i), 0x3FF);
- }
-
- if (ad1836->type == AD1836) {
- /* left/right diff:PGA/MUX */
- snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A);
- ret = snd_soc_add_codec_controls(codec, ad1836_controls,
- ARRAY_SIZE(ad1836_controls));
- if (ret)
- return ret;
- } else {
- snd_soc_write(codec, AD1836_ADC_CTRL3, 0x00);
- }
-
- ret = snd_soc_add_codec_controls(codec, ad183x_dac_controls, num_dacs * 2);
- if (ret)
- return ret;
-
- ret = snd_soc_add_codec_controls(codec, ad183x_adc_controls, num_adcs);
- if (ret)
- return ret;
-
- ret = snd_soc_dapm_new_controls(dapm, ad183x_dac_dapm_widgets, num_dacs);
- if (ret)
- return ret;
-
- ret = snd_soc_dapm_new_controls(dapm, ad183x_adc_dapm_widgets, num_adcs);
- if (ret)
- return ret;
-
- ret = snd_soc_dapm_add_routes(dapm, ad183x_dac_routes, num_dacs);
- if (ret)
- return ret;
-
- ret = snd_soc_dapm_add_routes(dapm, ad183x_adc_routes, num_adcs);
- if (ret)
- return ret;
-
- return ret;
-}
-
-/* power down chip */
-static int ad1836_remove(struct snd_soc_codec *codec)
-{
- /* reset clock control mode */
- return snd_soc_update_bits(codec, AD1836_ADC_CTRL2,
- AD1836_ADC_SERFMT_MASK, 0);
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_ad1836 = {
- .probe = ad1836_probe,
- .remove = ad1836_remove,
- .suspend = ad1836_suspend,
- .resume = ad1836_resume,
- .reg_cache_size = AD1836_NUM_REGS,
- .reg_word_size = sizeof(u16),
-
- .controls = ad183x_controls,
- .num_controls = ARRAY_SIZE(ad183x_controls),
- .dapm_widgets = ad183x_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(ad183x_dapm_widgets),
- .dapm_routes = ad183x_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(ad183x_dapm_routes),
-};
-
-static int __devinit ad1836_spi_probe(struct spi_device *spi)
-{
- struct ad1836_priv *ad1836;
- int ret;
-
- ad1836 = devm_kzalloc(&spi->dev, sizeof(struct ad1836_priv),
- GFP_KERNEL);
- if (ad1836 == NULL)
- return -ENOMEM;
-
- ad1836->type = spi_get_device_id(spi)->driver_data;
-
- spi_set_drvdata(spi, ad1836);
-
- ret = snd_soc_register_codec(&spi->dev,
- &soc_codec_dev_ad1836, &ad183x_dais[ad1836->type], 1);
- return ret;
-}
-
-static int __devexit ad1836_spi_remove(struct spi_device *spi)
-{
- snd_soc_unregister_codec(&spi->dev);
- return 0;
-}
-
-static const struct spi_device_id ad1836_ids[] = {
- { "ad1835", AD1835 },
- { "ad1836", AD1836 },
- { "ad1837", AD1835 },
- { "ad1838", AD1838 },
- { "ad1839", AD1838 },
- { },
-};
-MODULE_DEVICE_TABLE(spi, ad1836_ids);
-
-static struct spi_driver ad1836_spi_driver = {
- .driver = {
- .name = "ad1836",
- .owner = THIS_MODULE,
- },
- .probe = ad1836_spi_probe,
- .remove = __devexit_p(ad1836_spi_remove),
- .id_table = ad1836_ids,
-};
-
-static int __init ad1836_init(void)
-{
- return spi_register_driver(&ad1836_spi_driver);
-}
-module_init(ad1836_init);
-
-static void __exit ad1836_exit(void)
-{
- spi_unregister_driver(&ad1836_spi_driver);
-}
-module_exit(ad1836_exit);
-
-MODULE_DESCRIPTION("ASoC ad1836 driver");
-MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/ad1836.h b/ANDROID_3.4.5/sound/soc/codecs/ad1836.h
deleted file mode 100644
index dd7be0db..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/ad1836.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Audio Codec driver supporting:
- * AD1835A, AD1836, AD1837A, AD1838A, AD1839A
- *
- * Copyright 2009-2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#ifndef __AD1836_H__
-#define __AD1836_H__
-
-#define AD1836_DAC_CTRL1 0
-#define AD1836_DAC_POWERDOWN 2
-#define AD1836_DAC_SERFMT_MASK 0xE0
-#define AD1836_DAC_SERFMT_PCK256 (0x4 << 5)
-#define AD1836_DAC_SERFMT_PCK128 (0x5 << 5)
-#define AD1836_DAC_WORD_LEN_MASK 0x18
-#define AD1836_DAC_WORD_LEN_OFFSET 3
-
-#define AD1836_DAC_CTRL2 1
-
-/* These macros are one-based. So AD183X_MUTE_LEFT(1) will return the mute bit
- * for the first ADC/DAC */
-#define AD1836_MUTE_LEFT(x) (((x) * 2) - 2)
-#define AD1836_MUTE_RIGHT(x) (((x) * 2) - 1)
-
-#define AD1836_DAC_L_VOL(x) ((x) * 2)
-#define AD1836_DAC_R_VOL(x) (1 + ((x) * 2))
-
-#define AD1836_ADC_CTRL1 12
-#define AD1836_ADC_POWERDOWN 7
-#define AD1836_ADC_HIGHPASS_FILTER 8
-
-#define AD1836_ADC_CTRL2 13
-#define AD1836_ADC_WORD_LEN_MASK 0x30
-#define AD1836_ADC_WORD_OFFSET 4
-#define AD1836_ADC_SERFMT_MASK (7 << 6)
-#define AD1836_ADC_SERFMT_PCK256 (0x4 << 6)
-#define AD1836_ADC_SERFMT_PCK128 (0x5 << 6)
-#define AD1836_ADC_AUX (0x6 << 6)
-
-#define AD1836_ADC_CTRL3 14
-
-#define AD1836_NUM_REGS 16
-
-#define AD1836_WORD_LEN_24 0x0
-#define AD1836_WORD_LEN_20 0x1
-#define AD1836_WORD_LEN_16 0x2
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/ad193x.c b/ANDROID_3.4.5/sound/soc/codecs/ad193x.c
deleted file mode 100644
index a4a6bef2..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/ad193x.c
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * AD193X Audio Codec driver supporting AD1936/7/8/9
- *
- * Copyright 2010 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-#include <sound/tlv.h>
-#include "ad193x.h"
-
-/* codec private data */
-struct ad193x_priv {
- struct regmap *regmap;
- int sysclk;
-};
-
-/*
- * AD193X volume/mute/de-emphasis etc. controls
- */
-static const char * const ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"};
-
-static const struct soc_enum ad193x_deemp_enum =
- SOC_ENUM_SINGLE(AD193X_DAC_CTRL2, 1, 4, ad193x_deemp);
-
-static const DECLARE_TLV_DB_MINMAX(adau193x_tlv, -9563, 0);
-
-static const struct snd_kcontrol_new ad193x_snd_controls[] = {
- /* DAC volume control */
- SOC_DOUBLE_R_TLV("DAC1 Volume", AD193X_DAC_L1_VOL,
- AD193X_DAC_R1_VOL, 0, 0xFF, 1, adau193x_tlv),
- SOC_DOUBLE_R_TLV("DAC2 Volume", AD193X_DAC_L2_VOL,
- AD193X_DAC_R2_VOL, 0, 0xFF, 1, adau193x_tlv),
- SOC_DOUBLE_R_TLV("DAC3 Volume", AD193X_DAC_L3_VOL,
- AD193X_DAC_R3_VOL, 0, 0xFF, 1, adau193x_tlv),
- SOC_DOUBLE_R_TLV("DAC4 Volume", AD193X_DAC_L4_VOL,
- AD193X_DAC_R4_VOL, 0, 0xFF, 1, adau193x_tlv),
-
- /* ADC switch control */
- SOC_DOUBLE("ADC1 Switch", AD193X_ADC_CTRL0, AD193X_ADCL1_MUTE,
- AD193X_ADCR1_MUTE, 1, 1),
- SOC_DOUBLE("ADC2 Switch", AD193X_ADC_CTRL0, AD193X_ADCL2_MUTE,
- AD193X_ADCR2_MUTE, 1, 1),
-
- /* DAC switch control */
- SOC_DOUBLE("DAC1 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL1_MUTE,
- AD193X_DACR1_MUTE, 1, 1),
- SOC_DOUBLE("DAC2 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL2_MUTE,
- AD193X_DACR2_MUTE, 1, 1),
- SOC_DOUBLE("DAC3 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL3_MUTE,
- AD193X_DACR3_MUTE, 1, 1),
- SOC_DOUBLE("DAC4 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL4_MUTE,
- AD193X_DACR4_MUTE, 1, 1),
-
- /* ADC high-pass filter */
- SOC_SINGLE("ADC High Pass Filter Switch", AD193X_ADC_CTRL0,
- AD193X_ADC_HIGHPASS_FILTER, 1, 0),
-
- /* DAC de-emphasis */
- SOC_ENUM("Playback Deemphasis", ad193x_deemp_enum),
-};
-
-static const struct snd_soc_dapm_widget ad193x_dapm_widgets[] = {
- SND_SOC_DAPM_DAC("DAC", "Playback", AD193X_DAC_CTRL0, 0, 1),
- SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_SUPPLY("PLL_PWR", AD193X_PLL_CLK_CTRL0, 0, 1, NULL, 0),
- SND_SOC_DAPM_SUPPLY("ADC_PWR", AD193X_ADC_CTRL0, 0, 1, NULL, 0),
- SND_SOC_DAPM_SUPPLY("SYSCLK", AD193X_PLL_CLK_CTRL0, 7, 0, NULL, 0),
- SND_SOC_DAPM_OUTPUT("DAC1OUT"),
- SND_SOC_DAPM_OUTPUT("DAC2OUT"),
- SND_SOC_DAPM_OUTPUT("DAC3OUT"),
- SND_SOC_DAPM_OUTPUT("DAC4OUT"),
- SND_SOC_DAPM_INPUT("ADC1IN"),
- SND_SOC_DAPM_INPUT("ADC2IN"),
-};
-
-static const struct snd_soc_dapm_route audio_paths[] = {
- { "DAC", NULL, "SYSCLK" },
- { "ADC", NULL, "SYSCLK" },
- { "DAC", NULL, "ADC_PWR" },
- { "ADC", NULL, "ADC_PWR" },
- { "DAC1OUT", NULL, "DAC" },
- { "DAC2OUT", NULL, "DAC" },
- { "DAC3OUT", NULL, "DAC" },
- { "DAC4OUT", NULL, "DAC" },
- { "ADC", NULL, "ADC1IN" },
- { "ADC", NULL, "ADC2IN" },
- { "SYSCLK", NULL, "PLL_PWR" },
-};
-
-/*
- * DAI ops entries
- */
-
-static int ad193x_mute(struct snd_soc_dai *dai, int mute)
-{
- struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(dai->codec);
-
- if (mute)
- regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2,
- AD193X_DAC_MASTER_MUTE,
- AD193X_DAC_MASTER_MUTE);
- else
- regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2,
- AD193X_DAC_MASTER_MUTE, 0);
-
- return 0;
-}
-
-static int ad193x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
- unsigned int rx_mask, int slots, int width)
-{
- struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(dai->codec);
- unsigned int channels;
-
- switch (slots) {
- case 2:
- channels = AD193X_2_CHANNELS;
- break;
- case 4:
- channels = AD193X_4_CHANNELS;
- break;
- case 8:
- channels = AD193X_8_CHANNELS;
- break;
- case 16:
- channels = AD193X_16_CHANNELS;
- break;
- default:
- return -EINVAL;
- }
-
- regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1,
- AD193X_DAC_CHAN_MASK, channels << AD193X_DAC_CHAN_SHFT);
- regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2,
- AD193X_ADC_CHAN_MASK, channels << AD193X_ADC_CHAN_SHFT);
-
- return 0;
-}
-
-static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec_dai->codec);
- unsigned int adc_serfmt = 0;
- unsigned int adc_fmt = 0;
- unsigned int dac_fmt = 0;
-
- /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S
- * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A)
- */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- adc_serfmt |= AD193X_ADC_SERFMT_TDM;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- adc_serfmt |= AD193X_ADC_SERFMT_AUX;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */
- break;
- case SND_SOC_DAIFMT_NB_IF: /* normal bclk + invert frm */
- adc_fmt |= AD193X_ADC_LEFT_HIGH;
- dac_fmt |= AD193X_DAC_LEFT_HIGH;
- break;
- case SND_SOC_DAIFMT_IB_NF: /* invert bclk + normal frm */
- adc_fmt |= AD193X_ADC_BCLK_INV;
- dac_fmt |= AD193X_DAC_BCLK_INV;
- break;
- case SND_SOC_DAIFMT_IB_IF: /* invert bclk + frm */
- adc_fmt |= AD193X_ADC_LEFT_HIGH;
- adc_fmt |= AD193X_ADC_BCLK_INV;
- dac_fmt |= AD193X_DAC_LEFT_HIGH;
- dac_fmt |= AD193X_DAC_BCLK_INV;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master */
- adc_fmt |= AD193X_ADC_LCR_MASTER;
- adc_fmt |= AD193X_ADC_BCLK_MASTER;
- dac_fmt |= AD193X_DAC_LCR_MASTER;
- dac_fmt |= AD193X_DAC_BCLK_MASTER;
- break;
- case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & frm master */
- adc_fmt |= AD193X_ADC_LCR_MASTER;
- dac_fmt |= AD193X_DAC_LCR_MASTER;
- break;
- case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */
- adc_fmt |= AD193X_ADC_BCLK_MASTER;
- dac_fmt |= AD193X_DAC_BCLK_MASTER;
- break;
- case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & frm slave */
- break;
- default:
- return -EINVAL;
- }
-
- regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1,
- AD193X_ADC_SERFMT_MASK, adc_serfmt);
- regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2,
- AD193X_ADC_FMT_MASK, adc_fmt);
- regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1,
- AD193X_DAC_FMT_MASK, dac_fmt);
-
- return 0;
-}
-
-static int ad193x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
- switch (freq) {
- case 12288000:
- case 18432000:
- case 24576000:
- case 36864000:
- ad193x->sysclk = freq;
- return 0;
- }
- return -EINVAL;
-}
-
-static int ad193x_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- int word_len = 0, master_rate = 0;
-
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- word_len = 3;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- word_len = 1;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- case SNDRV_PCM_FORMAT_S32_LE:
- word_len = 0;
- break;
- }
-
- switch (ad193x->sysclk) {
- case 12288000:
- master_rate = AD193X_PLL_INPUT_256;
- break;
- case 18432000:
- master_rate = AD193X_PLL_INPUT_384;
- break;
- case 24576000:
- master_rate = AD193X_PLL_INPUT_512;
- break;
- case 36864000:
- master_rate = AD193X_PLL_INPUT_768;
- break;
- }
-
- regmap_update_bits(ad193x->regmap, AD193X_PLL_CLK_CTRL0,
- AD193X_PLL_INPUT_MASK, master_rate);
-
- regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2,
- AD193X_DAC_WORD_LEN_MASK,
- word_len << AD193X_DAC_WORD_LEN_SHFT);
-
- regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1,
- AD193X_ADC_WORD_LEN_MASK, word_len);
-
- return 0;
-}
-
-static const struct snd_soc_dai_ops ad193x_dai_ops = {
- .hw_params = ad193x_hw_params,
- .digital_mute = ad193x_mute,
- .set_tdm_slot = ad193x_set_tdm_slot,
- .set_sysclk = ad193x_set_dai_sysclk,
- .set_fmt = ad193x_set_dai_fmt,
-};
-
-/* codec DAI instance */
-static struct snd_soc_dai_driver ad193x_dai = {
- .name = "ad193x-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 8,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 4,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
- },
- .ops = &ad193x_dai_ops,
-};
-
-static int ad193x_probe(struct snd_soc_codec *codec)
-{
- struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- codec->control_data = ad193x->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- /* default setting for ad193x */
-
- /* unmute dac channels */
- regmap_write(ad193x->regmap, AD193X_DAC_CHNL_MUTE, 0x0);
- /* de-emphasis: 48kHz, powedown dac */
- regmap_write(ad193x->regmap, AD193X_DAC_CTRL2, 0x1A);
- /* powerdown dac, dac in tdm mode */
- regmap_write(ad193x->regmap, AD193X_DAC_CTRL0, 0x41);
- /* high-pass filter enable */
- regmap_write(ad193x->regmap, AD193X_ADC_CTRL0, 0x3);
- /* sata delay=1, adc aux mode */
- regmap_write(ad193x->regmap, AD193X_ADC_CTRL1, 0x43);
- /* pll input: mclki/xi */
- regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
- regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL1, 0x04);
-
- return ret;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
- .probe = ad193x_probe,
- .controls = ad193x_snd_controls,
- .num_controls = ARRAY_SIZE(ad193x_snd_controls),
- .dapm_widgets = ad193x_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(ad193x_dapm_widgets),
- .dapm_routes = audio_paths,
- .num_dapm_routes = ARRAY_SIZE(audio_paths),
-};
-
-static bool adau193x_reg_volatile(struct device *dev, unsigned int reg)
-{
- return false;
-}
-
-#if defined(CONFIG_SPI_MASTER)
-
-static const struct regmap_config ad193x_spi_regmap_config = {
- .val_bits = 8,
- .reg_bits = 16,
- .read_flag_mask = 0x09,
- .write_flag_mask = 0x08,
-
- .max_register = AD193X_NUM_REGS - 1,
- .volatile_reg = adau193x_reg_volatile,
-};
-
-static int __devinit ad193x_spi_probe(struct spi_device *spi)
-{
- struct ad193x_priv *ad193x;
- int ret;
-
- ad193x = devm_kzalloc(&spi->dev, sizeof(struct ad193x_priv),
- GFP_KERNEL);
- if (ad193x == NULL)
- return -ENOMEM;
-
- ad193x->regmap = regmap_init_spi(spi, &ad193x_spi_regmap_config);
- if (IS_ERR(ad193x->regmap)) {
- ret = PTR_ERR(ad193x->regmap);
- goto err_out;
- }
-
- spi_set_drvdata(spi, ad193x);
-
- ret = snd_soc_register_codec(&spi->dev,
- &soc_codec_dev_ad193x, &ad193x_dai, 1);
- if (ret < 0)
- goto err_regmap_exit;
-
- return 0;
-
-err_regmap_exit:
- regmap_exit(ad193x->regmap);
-err_out:
- return ret;
-}
-
-static int __devexit ad193x_spi_remove(struct spi_device *spi)
-{
- struct ad193x_priv *ad193x = spi_get_drvdata(spi);
-
- snd_soc_unregister_codec(&spi->dev);
- regmap_exit(ad193x->regmap);
- return 0;
-}
-
-static struct spi_driver ad193x_spi_driver = {
- .driver = {
- .name = "ad193x",
- .owner = THIS_MODULE,
- },
- .probe = ad193x_spi_probe,
- .remove = __devexit_p(ad193x_spi_remove),
-};
-#endif
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-
-static const struct regmap_config ad193x_i2c_regmap_config = {
- .val_bits = 8,
- .reg_bits = 8,
-
- .max_register = AD193X_NUM_REGS - 1,
- .volatile_reg = adau193x_reg_volatile,
-};
-
-static const struct i2c_device_id ad193x_id[] = {
- { "ad1936", 0 },
- { "ad1937", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ad193x_id);
-
-static int __devinit ad193x_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct ad193x_priv *ad193x;
- int ret;
-
- ad193x = devm_kzalloc(&client->dev, sizeof(struct ad193x_priv),
- GFP_KERNEL);
- if (ad193x == NULL)
- return -ENOMEM;
-
- ad193x->regmap = regmap_init_i2c(client, &ad193x_i2c_regmap_config);
- if (IS_ERR(ad193x->regmap)) {
- ret = PTR_ERR(ad193x->regmap);
- goto err_out;
- }
-
- i2c_set_clientdata(client, ad193x);
-
- ret = snd_soc_register_codec(&client->dev,
- &soc_codec_dev_ad193x, &ad193x_dai, 1);
- if (ret < 0)
- goto err_regmap_exit;
-
- return 0;
-
-err_regmap_exit:
- regmap_exit(ad193x->regmap);
-err_out:
- return ret;
-}
-
-static int __devexit ad193x_i2c_remove(struct i2c_client *client)
-{
- struct ad193x_priv *ad193x = i2c_get_clientdata(client);
-
- snd_soc_unregister_codec(&client->dev);
- regmap_exit(ad193x->regmap);
- return 0;
-}
-
-static struct i2c_driver ad193x_i2c_driver = {
- .driver = {
- .name = "ad193x",
- },
- .probe = ad193x_i2c_probe,
- .remove = __devexit_p(ad193x_i2c_remove),
- .id_table = ad193x_id,
-};
-#endif
-
-static int __init ad193x_modinit(void)
-{
- int ret;
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&ad193x_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register AD193X I2C driver: %d\n",
- ret);
- }
-#endif
-
-#if defined(CONFIG_SPI_MASTER)
- ret = spi_register_driver(&ad193x_spi_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register AD193X SPI driver: %d\n",
- ret);
- }
-#endif
- return ret;
-}
-module_init(ad193x_modinit);
-
-static void __exit ad193x_modexit(void)
-{
-#if defined(CONFIG_SPI_MASTER)
- spi_unregister_driver(&ad193x_spi_driver);
-#endif
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&ad193x_i2c_driver);
-#endif
-}
-module_exit(ad193x_modexit);
-
-MODULE_DESCRIPTION("ASoC ad193x driver");
-MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/ad193x.h b/ANDROID_3.4.5/sound/soc/codecs/ad193x.h
deleted file mode 100644
index 47338804..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/ad193x.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * AD193X Audio Codec driver
- *
- * Copyright 2010 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#ifndef __AD193X_H__
-#define __AD193X_H__
-
-#define AD193X_PLL_CLK_CTRL0 0x00
-#define AD193X_PLL_POWERDOWN 0x01
-#define AD193X_PLL_INPUT_MASK 0x6
-#define AD193X_PLL_INPUT_256 (0 << 1)
-#define AD193X_PLL_INPUT_384 (1 << 1)
-#define AD193X_PLL_INPUT_512 (2 << 1)
-#define AD193X_PLL_INPUT_768 (3 << 1)
-#define AD193X_PLL_CLK_CTRL1 0x01
-#define AD193X_DAC_CTRL0 0x02
-#define AD193X_DAC_POWERDOWN 0x01
-#define AD193X_DAC_SERFMT_MASK 0xC0
-#define AD193X_DAC_SERFMT_STEREO (0 << 6)
-#define AD193X_DAC_SERFMT_TDM (1 << 6)
-#define AD193X_DAC_CTRL1 0x03
-#define AD193X_DAC_CHAN_SHFT 1
-#define AD193X_DAC_CHAN_MASK (3 << AD193X_DAC_CHAN_SHFT)
-#define AD193X_DAC_LCR_MASTER (1 << 4)
-#define AD193X_DAC_BCLK_MASTER (1 << 5)
-#define AD193X_DAC_LEFT_HIGH (1 << 3)
-#define AD193X_DAC_BCLK_INV (1 << 7)
-#define AD193X_DAC_FMT_MASK (AD193X_DAC_LCR_MASTER | \
- AD193X_DAC_BCLK_MASTER | AD193X_DAC_LEFT_HIGH | AD193X_DAC_BCLK_INV)
-#define AD193X_DAC_CTRL2 0x04
-#define AD193X_DAC_WORD_LEN_SHFT 3
-#define AD193X_DAC_WORD_LEN_MASK 0x18
-#define AD193X_DAC_MASTER_MUTE 1
-#define AD193X_DAC_CHNL_MUTE 0x05
-#define AD193X_DACL1_MUTE 0
-#define AD193X_DACR1_MUTE 1
-#define AD193X_DACL2_MUTE 2
-#define AD193X_DACR2_MUTE 3
-#define AD193X_DACL3_MUTE 4
-#define AD193X_DACR3_MUTE 5
-#define AD193X_DACL4_MUTE 6
-#define AD193X_DACR4_MUTE 7
-#define AD193X_DAC_L1_VOL 0x06
-#define AD193X_DAC_R1_VOL 0x07
-#define AD193X_DAC_L2_VOL 0x08
-#define AD193X_DAC_R2_VOL 0x09
-#define AD193X_DAC_L3_VOL 0x0a
-#define AD193X_DAC_R3_VOL 0x0b
-#define AD193X_DAC_L4_VOL 0x0c
-#define AD193X_DAC_R4_VOL 0x0d
-#define AD193X_ADC_CTRL0 0x0e
-#define AD193X_ADC_POWERDOWN 0x01
-#define AD193X_ADC_HIGHPASS_FILTER 1
-#define AD193X_ADCL1_MUTE 2
-#define AD193X_ADCR1_MUTE 3
-#define AD193X_ADCL2_MUTE 4
-#define AD193X_ADCR2_MUTE 5
-#define AD193X_ADC_CTRL1 0x0f
-#define AD193X_ADC_SERFMT_MASK 0x60
-#define AD193X_ADC_SERFMT_STEREO (0 << 5)
-#define AD193X_ADC_SERFMT_TDM (1 << 5)
-#define AD193X_ADC_SERFMT_AUX (2 << 5)
-#define AD193X_ADC_WORD_LEN_MASK 0x3
-#define AD193X_ADC_CTRL2 0x10
-#define AD193X_ADC_CHAN_SHFT 4
-#define AD193X_ADC_CHAN_MASK (3 << AD193X_ADC_CHAN_SHFT)
-#define AD193X_ADC_LCR_MASTER (1 << 3)
-#define AD193X_ADC_BCLK_MASTER (1 << 6)
-#define AD193X_ADC_LEFT_HIGH (1 << 2)
-#define AD193X_ADC_BCLK_INV (1 << 1)
-#define AD193X_ADC_FMT_MASK (AD193X_ADC_LCR_MASTER | \
- AD193X_ADC_BCLK_MASTER | AD193X_ADC_LEFT_HIGH | AD193X_ADC_BCLK_INV)
-
-#define AD193X_2_CHANNELS 0
-#define AD193X_4_CHANNELS 1
-#define AD193X_8_CHANNELS 2
-#define AD193X_16_CHANNELS 3
-
-#define AD193X_NUM_REGS 17
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/ad1980.c b/ANDROID_3.4.5/sound/soc/codecs/ad1980.c
deleted file mode 100644
index 8c39dddd..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/ad1980.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * ad1980.c -- ALSA Soc AD1980 codec support
- *
- * Copyright: Analog Device Inc.
- * Author: Roy Huang <roy.huang@analog.com>
- * Cliff Cai <cliff.cai@analog.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/*
- * WARNING:
- *
- * Because Analog Devices Inc. discontinued the ad1980 sound chip since
- * Sep. 2009, this ad1980 driver is not maintained, tested and supported
- * by ADI now.
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include "ad1980.h"
-
-/*
- * AD1980 register cache
- */
-static const u16 ad1980_reg[] = {
- 0x0090, 0x8000, 0x8000, 0x8000, /* 0 - 6 */
- 0x0000, 0x0000, 0x8008, 0x8008, /* 8 - e */
- 0x8808, 0x8808, 0x0000, 0x8808, /* 10 - 16 */
- 0x8808, 0x0000, 0x8000, 0x0000, /* 18 - 1e */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 20 - 26 */
- 0x03c7, 0x0000, 0xbb80, 0xbb80, /* 28 - 2e */
- 0xbb80, 0xbb80, 0x0000, 0x8080, /* 30 - 36 */
- 0x8080, 0x2000, 0x0000, 0x0000, /* 38 - 3e */
- 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
- 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
- 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
- 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
- 0x8080, 0x0000, 0x0000, 0x0000, /* 60 - 66 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
- 0x0000, 0x0000, 0x1001, 0x0000, /* 70 - 76 */
- 0x0000, 0x0000, 0x4144, 0x5370 /* 78 - 7e */
-};
-
-static const char *ad1980_rec_sel[] = {"Mic", "CD", "NC", "AUX", "Line",
- "Stereo Mix", "Mono Mix", "Phone"};
-
-static const struct soc_enum ad1980_cap_src =
- SOC_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 7, ad1980_rec_sel);
-
-static const struct snd_kcontrol_new ad1980_snd_ac97_controls[] = {
-SOC_DOUBLE("Master Playback Volume", AC97_MASTER, 8, 0, 31, 1),
-SOC_SINGLE("Master Playback Switch", AC97_MASTER, 15, 1, 1),
-
-SOC_DOUBLE("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1),
-SOC_SINGLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 1, 1),
-
-SOC_DOUBLE("PCM Playback Volume", AC97_PCM, 8, 0, 31, 1),
-SOC_SINGLE("PCM Playback Switch", AC97_PCM, 15, 1, 1),
-
-SOC_DOUBLE("PCM Capture Volume", AC97_REC_GAIN, 8, 0, 31, 0),
-SOC_SINGLE("PCM Capture Switch", AC97_REC_GAIN, 15, 1, 1),
-
-SOC_SINGLE("Mono Playback Volume", AC97_MASTER_MONO, 0, 31, 1),
-SOC_SINGLE("Mono Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
-
-SOC_SINGLE("Phone Capture Volume", AC97_PHONE, 0, 31, 1),
-SOC_SINGLE("Phone Capture Switch", AC97_PHONE, 15, 1, 1),
-
-SOC_SINGLE("Mic Volume", AC97_MIC, 0, 31, 1),
-SOC_SINGLE("Mic Switch", AC97_MIC, 15, 1, 1),
-
-SOC_SINGLE("Stereo Mic Switch", AC97_AD_MISC, 6, 1, 0),
-SOC_DOUBLE("Line HP Swap Switch", AC97_AD_MISC, 10, 5, 1, 0),
-
-SOC_DOUBLE("Surround Playback Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1),
-SOC_DOUBLE("Surround Playback Switch", AC97_SURROUND_MASTER, 15, 7, 1, 1),
-
-SOC_DOUBLE("Center/LFE Playback Volume", AC97_CENTER_LFE_MASTER, 8, 0, 31, 1),
-SOC_DOUBLE("Center/LFE Playback Switch", AC97_CENTER_LFE_MASTER, 15, 7, 1, 1),
-
-SOC_ENUM("Capture Source", ad1980_cap_src),
-
-SOC_SINGLE("Mic Boost Switch", AC97_MIC, 6, 1, 0),
-};
-
-static unsigned int ac97_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- u16 *cache = codec->reg_cache;
-
- switch (reg) {
- case AC97_RESET:
- case AC97_INT_PAGING:
- case AC97_POWERDOWN:
- case AC97_EXTENDED_STATUS:
- case AC97_VENDOR_ID1:
- case AC97_VENDOR_ID2:
- return soc_ac97_ops.read(codec->ac97, reg);
- default:
- reg = reg >> 1;
-
- if (reg >= ARRAY_SIZE(ad1980_reg))
- return -EINVAL;
-
- return cache[reg];
- }
-}
-
-static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int val)
-{
- u16 *cache = codec->reg_cache;
-
- soc_ac97_ops.write(codec->ac97, reg, val);
- reg = reg >> 1;
- if (reg < ARRAY_SIZE(ad1980_reg))
- cache[reg] = val;
-
- return 0;
-}
-
-static struct snd_soc_dai_driver ad1980_dai = {
- .name = "ad1980-hifi",
- .ac97_control = 1,
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 6,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SND_SOC_STD_AC97_FMTS, },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SND_SOC_STD_AC97_FMTS, },
-};
-
-static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)
-{
- u16 retry_cnt = 0;
-
-retry:
- if (try_warm && soc_ac97_ops.warm_reset) {
- soc_ac97_ops.warm_reset(codec->ac97);
- if (ac97_read(codec, AC97_RESET) == 0x0090)
- return 1;
- }
-
- soc_ac97_ops.reset(codec->ac97);
- /* Set bit 16slot in register 74h, then every slot will has only 16
- * bits. This command is sent out in 20bit mode, in which case the
- * first nibble of data is eaten by the addr. (Tag is always 16 bit)*/
- ac97_write(codec, AC97_AD_SERIAL_CFG, 0x9900);
-
- if (ac97_read(codec, AC97_RESET) != 0x0090)
- goto err;
- return 0;
-
-err:
- while (retry_cnt++ < 10)
- goto retry;
-
- printk(KERN_ERR "AD1980 AC97 reset failed\n");
- return -EIO;
-}
-
-static int ad1980_soc_probe(struct snd_soc_codec *codec)
-{
- int ret;
- u16 vendor_id2;
- u16 ext_status;
-
- printk(KERN_INFO "AD1980 SoC Audio Codec\n");
-
- ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
- if (ret < 0) {
- printk(KERN_ERR "ad1980: failed to register AC97 codec\n");
- return ret;
- }
-
- ret = ad1980_reset(codec, 0);
- if (ret < 0) {
- printk(KERN_ERR "Failed to reset AD1980: AC97 link error\n");
- goto reset_err;
- }
-
- /* Read out vendor ID to make sure it is ad1980 */
- if (ac97_read(codec, AC97_VENDOR_ID1) != 0x4144) {
- ret = -ENODEV;
- goto reset_err;
- }
-
- vendor_id2 = ac97_read(codec, AC97_VENDOR_ID2);
-
- if (vendor_id2 != 0x5370) {
- if (vendor_id2 != 0x5374) {
- ret = -ENODEV;
- goto reset_err;
- } else {
- printk(KERN_WARNING "ad1980: "
- "Found AD1981 - only 2/2 IN/OUT Channels "
- "supported\n");
- }
- }
-
- /* unmute captures and playbacks volume */
- ac97_write(codec, AC97_MASTER, 0x0000);
- ac97_write(codec, AC97_PCM, 0x0000);
- ac97_write(codec, AC97_REC_GAIN, 0x0000);
- ac97_write(codec, AC97_CENTER_LFE_MASTER, 0x0000);
- ac97_write(codec, AC97_SURROUND_MASTER, 0x0000);
-
- /*power on LFE/CENTER/Surround DACs*/
- ext_status = ac97_read(codec, AC97_EXTENDED_STATUS);
- ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800);
-
- snd_soc_add_codec_controls(codec, ad1980_snd_ac97_controls,
- ARRAY_SIZE(ad1980_snd_ac97_controls));
-
- return 0;
-
-reset_err:
- snd_soc_free_ac97_codec(codec);
- return ret;
-}
-
-static int ad1980_soc_remove(struct snd_soc_codec *codec)
-{
- snd_soc_free_ac97_codec(codec);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_ad1980 = {
- .probe = ad1980_soc_probe,
- .remove = ad1980_soc_remove,
- .reg_cache_size = ARRAY_SIZE(ad1980_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = ad1980_reg,
- .reg_cache_step = 2,
- .write = ac97_write,
- .read = ac97_read,
-};
-
-static __devinit int ad1980_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev,
- &soc_codec_dev_ad1980, &ad1980_dai, 1);
-}
-
-static int __devexit ad1980_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver ad1980_codec_driver = {
- .driver = {
- .name = "ad1980",
- .owner = THIS_MODULE,
- },
-
- .probe = ad1980_probe,
- .remove = __devexit_p(ad1980_remove),
-};
-
-module_platform_driver(ad1980_codec_driver);
-
-MODULE_DESCRIPTION("ASoC ad1980 driver (Obsolete)");
-MODULE_AUTHOR("Roy Huang, Cliff Cai");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/ad1980.h b/ANDROID_3.4.5/sound/soc/codecs/ad1980.h
deleted file mode 100644
index eb0af44a..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/ad1980.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * ad1980.h -- ad1980 Soc Audio driver
- *
- * WARNING:
- *
- * Because Analog Devices Inc. discontinued the ad1980 sound chip since
- * Sep. 2009, this ad1980 driver is not maintained, tested and supported
- * by ADI now.
- */
-
-#ifndef _AD1980_H
-#define _AD1980_H
-/* Bit definition of Power-Down Control/Status Register */
-#define ADC 0x0001
-#define DAC 0x0002
-#define ANL 0x0004
-#define REF 0x0008
-#define PR0 0x0100
-#define PR1 0x0200
-#define PR2 0x0400
-#define PR3 0x0800
-#define PR4 0x1000
-#define PR5 0x2000
-#define PR6 0x4000
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/ad73311.c b/ANDROID_3.4.5/sound/soc/codecs/ad73311.c
deleted file mode 100644
index ee7a68dc..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/ad73311.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * ad73311.c -- ALSA Soc AD73311 codec support
- *
- * Copyright: Analog Device Inc.
- * Author: Cliff Cai <cliff.cai@analog.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include "ad73311.h"
-
-static struct snd_soc_dai_driver ad73311_dai = {
- .name = "ad73311-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 1,
- .rates = SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE, },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 1,
- .rates = SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE, },
-};
-
-static struct snd_soc_codec_driver soc_codec_dev_ad73311;
-
-static int ad73311_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev,
- &soc_codec_dev_ad73311, &ad73311_dai, 1);
-}
-
-static int __devexit ad73311_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver ad73311_codec_driver = {
- .driver = {
- .name = "ad73311",
- .owner = THIS_MODULE,
- },
-
- .probe = ad73311_probe,
- .remove = __devexit_p(ad73311_remove),
-};
-
-module_platform_driver(ad73311_codec_driver);
-
-MODULE_DESCRIPTION("ASoC ad73311 driver");
-MODULE_AUTHOR("Cliff Cai ");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/ad73311.h b/ANDROID_3.4.5/sound/soc/codecs/ad73311.h
deleted file mode 100644
index 4b353eef..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/ad73311.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * File: sound/soc/codec/ad73311.h
- * Based on:
- * Author: Cliff Cai <cliff.cai@analog.com>
- *
- * Created: Thur Sep 25, 2008
- * Description: definitions for AD73311 registers
- *
- *
- * Modified:
- * Copyright 2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef __AD73311_H__
-#define __AD73311_H__
-
-#define AD_CONTROL 0x8000
-#define AD_DATA 0x0000
-#define AD_READ 0x4000
-#define AD_WRITE 0x0000
-
-/* Control register A */
-#define CTRL_REG_A (0 << 8)
-
-#define REGA_MODE_PRO 0x00
-#define REGA_MODE_DATA 0x01
-#define REGA_MODE_MIXED 0x03
-#define REGA_DLB 0x04
-#define REGA_SLB 0x08
-#define REGA_DEVC(x) ((x & 0x7) << 4)
-#define REGA_RESET 0x80
-
-/* Control register B */
-#define CTRL_REG_B (1 << 8)
-
-#define REGB_DIRATE(x) (x & 0x3)
-#define REGB_SCDIV(x) ((x & 0x3) << 2)
-#define REGB_MCDIV(x) ((x & 0x7) << 4)
-#define REGB_CEE (1 << 7)
-
-/* Control register C */
-#define CTRL_REG_C (2 << 8)
-
-#define REGC_PUDEV (1 << 0)
-#define REGC_PUADC (1 << 3)
-#define REGC_PUDAC (1 << 4)
-#define REGC_PUREF (1 << 5)
-#define REGC_REFUSE (1 << 6)
-
-/* Control register D */
-#define CTRL_REG_D (3 << 8)
-
-#define REGD_IGS(x) (x & 0x7)
-#define REGD_RMOD (1 << 3)
-#define REGD_OGS(x) ((x & 0x7) << 4)
-#define REGD_MUTE (1 << 7)
-
-/* Control register E */
-#define CTRL_REG_E (4 << 8)
-
-#define REGE_DA(x) (x & 0x1f)
-#define REGE_IBYP (1 << 5)
-
-/* Control register F */
-#define CTRL_REG_F (5 << 8)
-
-#define REGF_SEEN (1 << 5)
-#define REGF_INV (1 << 6)
-#define REGF_ALB (1 << 7)
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/adau1373.c b/ANDROID_3.4.5/sound/soc/codecs/adau1373.c
deleted file mode 100644
index 44f59064..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/adau1373.c
+++ /dev/null
@@ -1,1409 +0,0 @@
-/*
- * Analog Devices ADAU1373 Audio Codec drive
- *
- * Copyright 2011 Analog Devices Inc.
- * Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/gcd.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/tlv.h>
-#include <sound/soc.h>
-#include <sound/adau1373.h>
-
-#include "adau1373.h"
-
-struct adau1373_dai {
- unsigned int clk_src;
- unsigned int sysclk;
- bool enable_src;
- bool master;
-};
-
-struct adau1373 {
- struct adau1373_dai dais[3];
-};
-
-#define ADAU1373_INPUT_MODE 0x00
-#define ADAU1373_AINL_CTRL(x) (0x01 + (x) * 2)
-#define ADAU1373_AINR_CTRL(x) (0x02 + (x) * 2)
-#define ADAU1373_LLINE_OUT(x) (0x9 + (x) * 2)
-#define ADAU1373_RLINE_OUT(x) (0xa + (x) * 2)
-#define ADAU1373_LSPK_OUT 0x0d
-#define ADAU1373_RSPK_OUT 0x0e
-#define ADAU1373_LHP_OUT 0x0f
-#define ADAU1373_RHP_OUT 0x10
-#define ADAU1373_ADC_GAIN 0x11
-#define ADAU1373_LADC_MIXER 0x12
-#define ADAU1373_RADC_MIXER 0x13
-#define ADAU1373_LLINE1_MIX 0x14
-#define ADAU1373_RLINE1_MIX 0x15
-#define ADAU1373_LLINE2_MIX 0x16
-#define ADAU1373_RLINE2_MIX 0x17
-#define ADAU1373_LSPK_MIX 0x18
-#define ADAU1373_RSPK_MIX 0x19
-#define ADAU1373_LHP_MIX 0x1a
-#define ADAU1373_RHP_MIX 0x1b
-#define ADAU1373_EP_MIX 0x1c
-#define ADAU1373_HP_CTRL 0x1d
-#define ADAU1373_HP_CTRL2 0x1e
-#define ADAU1373_LS_CTRL 0x1f
-#define ADAU1373_EP_CTRL 0x21
-#define ADAU1373_MICBIAS_CTRL1 0x22
-#define ADAU1373_MICBIAS_CTRL2 0x23
-#define ADAU1373_OUTPUT_CTRL 0x24
-#define ADAU1373_PWDN_CTRL1 0x25
-#define ADAU1373_PWDN_CTRL2 0x26
-#define ADAU1373_PWDN_CTRL3 0x27
-#define ADAU1373_DPLL_CTRL(x) (0x28 + (x) * 7)
-#define ADAU1373_PLL_CTRL1(x) (0x29 + (x) * 7)
-#define ADAU1373_PLL_CTRL2(x) (0x2a + (x) * 7)
-#define ADAU1373_PLL_CTRL3(x) (0x2b + (x) * 7)
-#define ADAU1373_PLL_CTRL4(x) (0x2c + (x) * 7)
-#define ADAU1373_PLL_CTRL5(x) (0x2d + (x) * 7)
-#define ADAU1373_PLL_CTRL6(x) (0x2e + (x) * 7)
-#define ADAU1373_PLL_CTRL7(x) (0x2f + (x) * 7)
-#define ADAU1373_HEADDECT 0x36
-#define ADAU1373_ADC_DAC_STATUS 0x37
-#define ADAU1373_ADC_CTRL 0x3c
-#define ADAU1373_DAI(x) (0x44 + (x))
-#define ADAU1373_CLK_SRC_DIV(x) (0x40 + (x) * 2)
-#define ADAU1373_BCLKDIV(x) (0x47 + (x))
-#define ADAU1373_SRC_RATIOA(x) (0x4a + (x) * 2)
-#define ADAU1373_SRC_RATIOB(x) (0x4b + (x) * 2)
-#define ADAU1373_DEEMP_CTRL 0x50
-#define ADAU1373_SRC_DAI_CTRL(x) (0x51 + (x))
-#define ADAU1373_DIN_MIX_CTRL(x) (0x56 + (x))
-#define ADAU1373_DOUT_MIX_CTRL(x) (0x5b + (x))
-#define ADAU1373_DAI_PBL_VOL(x) (0x62 + (x) * 2)
-#define ADAU1373_DAI_PBR_VOL(x) (0x63 + (x) * 2)
-#define ADAU1373_DAI_RECL_VOL(x) (0x68 + (x) * 2)
-#define ADAU1373_DAI_RECR_VOL(x) (0x69 + (x) * 2)
-#define ADAU1373_DAC1_PBL_VOL 0x6e
-#define ADAU1373_DAC1_PBR_VOL 0x6f
-#define ADAU1373_DAC2_PBL_VOL 0x70
-#define ADAU1373_DAC2_PBR_VOL 0x71
-#define ADAU1373_ADC_RECL_VOL 0x72
-#define ADAU1373_ADC_RECR_VOL 0x73
-#define ADAU1373_DMIC_RECL_VOL 0x74
-#define ADAU1373_DMIC_RECR_VOL 0x75
-#define ADAU1373_VOL_GAIN1 0x76
-#define ADAU1373_VOL_GAIN2 0x77
-#define ADAU1373_VOL_GAIN3 0x78
-#define ADAU1373_HPF_CTRL 0x7d
-#define ADAU1373_BASS1 0x7e
-#define ADAU1373_BASS2 0x7f
-#define ADAU1373_DRC(x) (0x80 + (x) * 0x10)
-#define ADAU1373_3D_CTRL1 0xc0
-#define ADAU1373_3D_CTRL2 0xc1
-#define ADAU1373_FDSP_SEL1 0xdc
-#define ADAU1373_FDSP_SEL2 0xdd
-#define ADAU1373_FDSP_SEL3 0xde
-#define ADAU1373_FDSP_SEL4 0xdf
-#define ADAU1373_DIGMICCTRL 0xe2
-#define ADAU1373_DIGEN 0xeb
-#define ADAU1373_SOFT_RESET 0xff
-
-
-#define ADAU1373_PLL_CTRL6_DPLL_BYPASS BIT(1)
-#define ADAU1373_PLL_CTRL6_PLL_EN BIT(0)
-
-#define ADAU1373_DAI_INVERT_BCLK BIT(7)
-#define ADAU1373_DAI_MASTER BIT(6)
-#define ADAU1373_DAI_INVERT_LRCLK BIT(4)
-#define ADAU1373_DAI_WLEN_16 0x0
-#define ADAU1373_DAI_WLEN_20 0x4
-#define ADAU1373_DAI_WLEN_24 0x8
-#define ADAU1373_DAI_WLEN_32 0xc
-#define ADAU1373_DAI_WLEN_MASK 0xc
-#define ADAU1373_DAI_FORMAT_RIGHT_J 0x0
-#define ADAU1373_DAI_FORMAT_LEFT_J 0x1
-#define ADAU1373_DAI_FORMAT_I2S 0x2
-#define ADAU1373_DAI_FORMAT_DSP 0x3
-
-#define ADAU1373_BCLKDIV_SOURCE BIT(5)
-#define ADAU1373_BCLKDIV_32 0x03
-#define ADAU1373_BCLKDIV_64 0x02
-#define ADAU1373_BCLKDIV_128 0x01
-#define ADAU1373_BCLKDIV_256 0x00
-
-#define ADAU1373_ADC_CTRL_PEAK_DETECT BIT(0)
-#define ADAU1373_ADC_CTRL_RESET BIT(1)
-#define ADAU1373_ADC_CTRL_RESET_FORCE BIT(2)
-
-#define ADAU1373_OUTPUT_CTRL_LDIFF BIT(3)
-#define ADAU1373_OUTPUT_CTRL_LNFBEN BIT(2)
-
-#define ADAU1373_PWDN_CTRL3_PWR_EN BIT(0)
-
-#define ADAU1373_EP_CTRL_MICBIAS1_OFFSET 4
-#define ADAU1373_EP_CTRL_MICBIAS2_OFFSET 2
-
-static const uint8_t adau1373_default_regs[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00 */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10 */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20 */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* 0x30 */
- 0x00, 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x00, /* 0x40 */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, /* 0x50 */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60 */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0x80 */
- 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00,
- 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0x90 */
- 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00,
- 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0xa0 */
- 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb0 */
- 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0 */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* 0xe0 */
- 0x00, 0x1f, 0x0f, 0x00, 0x00,
-};
-
-static const unsigned int adau1373_out_tlv[] = {
- TLV_DB_RANGE_HEAD(4),
- 0, 7, TLV_DB_SCALE_ITEM(-7900, 400, 1),
- 8, 15, TLV_DB_SCALE_ITEM(-4700, 300, 0),
- 16, 23, TLV_DB_SCALE_ITEM(-2300, 200, 0),
- 24, 31, TLV_DB_SCALE_ITEM(-700, 100, 0),
-};
-
-static const DECLARE_TLV_DB_MINMAX(adau1373_digital_tlv, -9563, 0);
-static const DECLARE_TLV_DB_SCALE(adau1373_in_pga_tlv, -1300, 100, 1);
-static const DECLARE_TLV_DB_SCALE(adau1373_ep_tlv, -600, 600, 1);
-
-static const DECLARE_TLV_DB_SCALE(adau1373_input_boost_tlv, 0, 2000, 0);
-static const DECLARE_TLV_DB_SCALE(adau1373_gain_boost_tlv, 0, 600, 0);
-static const DECLARE_TLV_DB_SCALE(adau1373_speaker_boost_tlv, 1200, 600, 0);
-
-static const char *adau1373_fdsp_sel_text[] = {
- "None",
- "Channel 1",
- "Channel 2",
- "Channel 3",
- "Channel 4",
- "Channel 5",
-};
-
-static const SOC_ENUM_SINGLE_DECL(adau1373_drc1_channel_enum,
- ADAU1373_FDSP_SEL1, 4, adau1373_fdsp_sel_text);
-static const SOC_ENUM_SINGLE_DECL(adau1373_drc2_channel_enum,
- ADAU1373_FDSP_SEL1, 0, adau1373_fdsp_sel_text);
-static const SOC_ENUM_SINGLE_DECL(adau1373_drc3_channel_enum,
- ADAU1373_FDSP_SEL2, 0, adau1373_fdsp_sel_text);
-static const SOC_ENUM_SINGLE_DECL(adau1373_hpf_channel_enum,
- ADAU1373_FDSP_SEL3, 0, adau1373_fdsp_sel_text);
-static const SOC_ENUM_SINGLE_DECL(adau1373_bass_channel_enum,
- ADAU1373_FDSP_SEL4, 4, adau1373_fdsp_sel_text);
-
-static const char *adau1373_hpf_cutoff_text[] = {
- "3.7Hz", "50Hz", "100Hz", "150Hz", "200Hz", "250Hz", "300Hz", "350Hz",
- "400Hz", "450Hz", "500Hz", "550Hz", "600Hz", "650Hz", "700Hz", "750Hz",
- "800Hz",
-};
-
-static const SOC_ENUM_SINGLE_DECL(adau1373_hpf_cutoff_enum,
- ADAU1373_HPF_CTRL, 3, adau1373_hpf_cutoff_text);
-
-static const char *adau1373_bass_lpf_cutoff_text[] = {
- "801Hz", "1001Hz",
-};
-
-static const char *adau1373_bass_clip_level_text[] = {
- "0.125", "0.250", "0.370", "0.500", "0.625", "0.750", "0.875",
-};
-
-static const unsigned int adau1373_bass_clip_level_values[] = {
- 1, 2, 3, 4, 5, 6, 7,
-};
-
-static const char *adau1373_bass_hpf_cutoff_text[] = {
- "158Hz", "232Hz", "347Hz", "520Hz",
-};
-
-static const unsigned int adau1373_bass_tlv[] = {
- TLV_DB_RANGE_HEAD(3),
- 0, 2, TLV_DB_SCALE_ITEM(-600, 600, 1),
- 3, 4, TLV_DB_SCALE_ITEM(950, 250, 0),
- 5, 7, TLV_DB_SCALE_ITEM(1400, 150, 0),
-};
-
-static const SOC_ENUM_SINGLE_DECL(adau1373_bass_lpf_cutoff_enum,
- ADAU1373_BASS1, 5, adau1373_bass_lpf_cutoff_text);
-
-static const SOC_VALUE_ENUM_SINGLE_DECL(adau1373_bass_clip_level_enum,
- ADAU1373_BASS1, 2, 7, adau1373_bass_clip_level_text,
- adau1373_bass_clip_level_values);
-
-static const SOC_ENUM_SINGLE_DECL(adau1373_bass_hpf_cutoff_enum,
- ADAU1373_BASS1, 0, adau1373_bass_hpf_cutoff_text);
-
-static const char *adau1373_3d_level_text[] = {
- "0%", "6.67%", "13.33%", "20%", "26.67%", "33.33%",
- "40%", "46.67%", "53.33%", "60%", "66.67%", "73.33%",
- "80%", "86.67", "99.33%", "100%"
-};
-
-static const char *adau1373_3d_cutoff_text[] = {
- "No 3D", "0.03125 fs", "0.04583 fs", "0.075 fs", "0.11458 fs",
- "0.16875 fs", "0.27083 fs"
-};
-
-static const SOC_ENUM_SINGLE_DECL(adau1373_3d_level_enum,
- ADAU1373_3D_CTRL1, 4, adau1373_3d_level_text);
-static const SOC_ENUM_SINGLE_DECL(adau1373_3d_cutoff_enum,
- ADAU1373_3D_CTRL1, 0, adau1373_3d_cutoff_text);
-
-static const unsigned int adau1373_3d_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
- 1, 7, TLV_DB_LINEAR_ITEM(-1800, -120),
-};
-
-static const char *adau1373_lr_mux_text[] = {
- "Mute",
- "Right Channel (L+R)",
- "Left Channel (L+R)",
- "Stereo",
-};
-
-static const SOC_ENUM_SINGLE_DECL(adau1373_lineout1_lr_mux_enum,
- ADAU1373_OUTPUT_CTRL, 4, adau1373_lr_mux_text);
-static const SOC_ENUM_SINGLE_DECL(adau1373_lineout2_lr_mux_enum,
- ADAU1373_OUTPUT_CTRL, 6, adau1373_lr_mux_text);
-static const SOC_ENUM_SINGLE_DECL(adau1373_speaker_lr_mux_enum,
- ADAU1373_LS_CTRL, 4, adau1373_lr_mux_text);
-
-static const struct snd_kcontrol_new adau1373_controls[] = {
- SOC_DOUBLE_R_TLV("AIF1 Capture Volume", ADAU1373_DAI_RECL_VOL(0),
- ADAU1373_DAI_RECR_VOL(0), 0, 0xff, 1, adau1373_digital_tlv),
- SOC_DOUBLE_R_TLV("AIF2 Capture Volume", ADAU1373_DAI_RECL_VOL(1),
- ADAU1373_DAI_RECR_VOL(1), 0, 0xff, 1, adau1373_digital_tlv),
- SOC_DOUBLE_R_TLV("AIF3 Capture Volume", ADAU1373_DAI_RECL_VOL(2),
- ADAU1373_DAI_RECR_VOL(2), 0, 0xff, 1, adau1373_digital_tlv),
-
- SOC_DOUBLE_R_TLV("ADC Capture Volume", ADAU1373_ADC_RECL_VOL,
- ADAU1373_ADC_RECR_VOL, 0, 0xff, 1, adau1373_digital_tlv),
- SOC_DOUBLE_R_TLV("DMIC Capture Volume", ADAU1373_DMIC_RECL_VOL,
- ADAU1373_DMIC_RECR_VOL, 0, 0xff, 1, adau1373_digital_tlv),
-
- SOC_DOUBLE_R_TLV("AIF1 Playback Volume", ADAU1373_DAI_PBL_VOL(0),
- ADAU1373_DAI_PBR_VOL(0), 0, 0xff, 1, adau1373_digital_tlv),
- SOC_DOUBLE_R_TLV("AIF2 Playback Volume", ADAU1373_DAI_PBL_VOL(1),
- ADAU1373_DAI_PBR_VOL(1), 0, 0xff, 1, adau1373_digital_tlv),
- SOC_DOUBLE_R_TLV("AIF3 Playback Volume", ADAU1373_DAI_PBL_VOL(2),
- ADAU1373_DAI_PBR_VOL(2), 0, 0xff, 1, adau1373_digital_tlv),
-
- SOC_DOUBLE_R_TLV("DAC1 Playback Volume", ADAU1373_DAC1_PBL_VOL,
- ADAU1373_DAC1_PBR_VOL, 0, 0xff, 1, adau1373_digital_tlv),
- SOC_DOUBLE_R_TLV("DAC2 Playback Volume", ADAU1373_DAC2_PBL_VOL,
- ADAU1373_DAC2_PBR_VOL, 0, 0xff, 1, adau1373_digital_tlv),
-
- SOC_DOUBLE_R_TLV("Lineout1 Playback Volume", ADAU1373_LLINE_OUT(0),
- ADAU1373_RLINE_OUT(0), 0, 0x1f, 0, adau1373_out_tlv),
- SOC_DOUBLE_R_TLV("Speaker Playback Volume", ADAU1373_LSPK_OUT,
- ADAU1373_RSPK_OUT, 0, 0x1f, 0, adau1373_out_tlv),
- SOC_DOUBLE_R_TLV("Headphone Playback Volume", ADAU1373_LHP_OUT,
- ADAU1373_RHP_OUT, 0, 0x1f, 0, adau1373_out_tlv),
-
- SOC_DOUBLE_R_TLV("Input 1 Capture Volume", ADAU1373_AINL_CTRL(0),
- ADAU1373_AINR_CTRL(0), 0, 0x1f, 0, adau1373_in_pga_tlv),
- SOC_DOUBLE_R_TLV("Input 2 Capture Volume", ADAU1373_AINL_CTRL(1),
- ADAU1373_AINR_CTRL(1), 0, 0x1f, 0, adau1373_in_pga_tlv),
- SOC_DOUBLE_R_TLV("Input 3 Capture Volume", ADAU1373_AINL_CTRL(2),
- ADAU1373_AINR_CTRL(2), 0, 0x1f, 0, adau1373_in_pga_tlv),
- SOC_DOUBLE_R_TLV("Input 4 Capture Volume", ADAU1373_AINL_CTRL(3),
- ADAU1373_AINR_CTRL(3), 0, 0x1f, 0, adau1373_in_pga_tlv),
-
- SOC_SINGLE_TLV("Earpiece Playback Volume", ADAU1373_EP_CTRL, 0, 3, 0,
- adau1373_ep_tlv),
-
- SOC_DOUBLE_TLV("AIF3 Boost Playback Volume", ADAU1373_VOL_GAIN1, 4, 5,
- 1, 0, adau1373_gain_boost_tlv),
- SOC_DOUBLE_TLV("AIF2 Boost Playback Volume", ADAU1373_VOL_GAIN1, 2, 3,
- 1, 0, adau1373_gain_boost_tlv),
- SOC_DOUBLE_TLV("AIF1 Boost Playback Volume", ADAU1373_VOL_GAIN1, 0, 1,
- 1, 0, adau1373_gain_boost_tlv),
- SOC_DOUBLE_TLV("AIF3 Boost Capture Volume", ADAU1373_VOL_GAIN2, 4, 5,
- 1, 0, adau1373_gain_boost_tlv),
- SOC_DOUBLE_TLV("AIF2 Boost Capture Volume", ADAU1373_VOL_GAIN2, 2, 3,
- 1, 0, adau1373_gain_boost_tlv),
- SOC_DOUBLE_TLV("AIF1 Boost Capture Volume", ADAU1373_VOL_GAIN2, 0, 1,
- 1, 0, adau1373_gain_boost_tlv),
- SOC_DOUBLE_TLV("DMIC Boost Capture Volume", ADAU1373_VOL_GAIN3, 6, 7,
- 1, 0, adau1373_gain_boost_tlv),
- SOC_DOUBLE_TLV("ADC Boost Capture Volume", ADAU1373_VOL_GAIN3, 4, 5,
- 1, 0, adau1373_gain_boost_tlv),
- SOC_DOUBLE_TLV("DAC2 Boost Playback Volume", ADAU1373_VOL_GAIN3, 2, 3,
- 1, 0, adau1373_gain_boost_tlv),
- SOC_DOUBLE_TLV("DAC1 Boost Playback Volume", ADAU1373_VOL_GAIN3, 0, 1,
- 1, 0, adau1373_gain_boost_tlv),
-
- SOC_DOUBLE_TLV("Input 1 Boost Capture Volume", ADAU1373_ADC_GAIN, 0, 4,
- 1, 0, adau1373_input_boost_tlv),
- SOC_DOUBLE_TLV("Input 2 Boost Capture Volume", ADAU1373_ADC_GAIN, 1, 5,
- 1, 0, adau1373_input_boost_tlv),
- SOC_DOUBLE_TLV("Input 3 Boost Capture Volume", ADAU1373_ADC_GAIN, 2, 6,
- 1, 0, adau1373_input_boost_tlv),
- SOC_DOUBLE_TLV("Input 4 Boost Capture Volume", ADAU1373_ADC_GAIN, 3, 7,
- 1, 0, adau1373_input_boost_tlv),
-
- SOC_DOUBLE_TLV("Speaker Boost Playback Volume", ADAU1373_LS_CTRL, 2, 3,
- 1, 0, adau1373_speaker_boost_tlv),
-
- SOC_ENUM("Lineout1 LR Mux", adau1373_lineout1_lr_mux_enum),
- SOC_ENUM("Speaker LR Mux", adau1373_speaker_lr_mux_enum),
-
- SOC_ENUM("HPF Cutoff", adau1373_hpf_cutoff_enum),
- SOC_DOUBLE("HPF Switch", ADAU1373_HPF_CTRL, 1, 0, 1, 0),
- SOC_ENUM("HPF Channel", adau1373_hpf_channel_enum),
-
- SOC_ENUM("Bass HPF Cutoff", adau1373_bass_hpf_cutoff_enum),
- SOC_VALUE_ENUM("Bass Clip Level Threshold",
- adau1373_bass_clip_level_enum),
- SOC_ENUM("Bass LPF Cutoff", adau1373_bass_lpf_cutoff_enum),
- SOC_DOUBLE("Bass Playback Switch", ADAU1373_BASS2, 0, 1, 1, 0),
- SOC_SINGLE_TLV("Bass Playback Volume", ADAU1373_BASS2, 2, 7, 0,
- adau1373_bass_tlv),
- SOC_ENUM("Bass Channel", adau1373_bass_channel_enum),
-
- SOC_ENUM("3D Freq", adau1373_3d_cutoff_enum),
- SOC_ENUM("3D Level", adau1373_3d_level_enum),
- SOC_SINGLE("3D Playback Switch", ADAU1373_3D_CTRL2, 0, 1, 0),
- SOC_SINGLE_TLV("3D Playback Volume", ADAU1373_3D_CTRL2, 2, 7, 0,
- adau1373_3d_tlv),
- SOC_ENUM("3D Channel", adau1373_bass_channel_enum),
-
- SOC_SINGLE("Zero Cross Switch", ADAU1373_PWDN_CTRL3, 7, 1, 0),
-};
-
-static const struct snd_kcontrol_new adau1373_lineout2_controls[] = {
- SOC_DOUBLE_R_TLV("Lineout2 Playback Volume", ADAU1373_LLINE_OUT(1),
- ADAU1373_RLINE_OUT(1), 0, 0x1f, 0, adau1373_out_tlv),
- SOC_ENUM("Lineout2 LR Mux", adau1373_lineout2_lr_mux_enum),
-};
-
-static const struct snd_kcontrol_new adau1373_drc_controls[] = {
- SOC_ENUM("DRC1 Channel", adau1373_drc1_channel_enum),
- SOC_ENUM("DRC2 Channel", adau1373_drc2_channel_enum),
- SOC_ENUM("DRC3 Channel", adau1373_drc3_channel_enum),
-};
-
-static int adau1373_pll_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- unsigned int pll_id = w->name[3] - '1';
- unsigned int val;
-
- if (SND_SOC_DAPM_EVENT_ON(event))
- val = ADAU1373_PLL_CTRL6_PLL_EN;
- else
- val = 0;
-
- snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id),
- ADAU1373_PLL_CTRL6_PLL_EN, val);
-
- if (SND_SOC_DAPM_EVENT_ON(event))
- mdelay(5);
-
- return 0;
-}
-
-static const char *adau1373_decimator_text[] = {
- "ADC",
- "DMIC1",
-};
-
-static const struct soc_enum adau1373_decimator_enum =
- SOC_ENUM_SINGLE(0, 0, 2, adau1373_decimator_text);
-
-static const struct snd_kcontrol_new adau1373_decimator_mux =
- SOC_DAPM_ENUM_VIRT("Decimator Mux", adau1373_decimator_enum);
-
-static const struct snd_kcontrol_new adau1373_left_adc_mixer_controls[] = {
- SOC_DAPM_SINGLE("DAC1 Switch", ADAU1373_LADC_MIXER, 4, 1, 0),
- SOC_DAPM_SINGLE("Input 4 Switch", ADAU1373_LADC_MIXER, 3, 1, 0),
- SOC_DAPM_SINGLE("Input 3 Switch", ADAU1373_LADC_MIXER, 2, 1, 0),
- SOC_DAPM_SINGLE("Input 2 Switch", ADAU1373_LADC_MIXER, 1, 1, 0),
- SOC_DAPM_SINGLE("Input 1 Switch", ADAU1373_LADC_MIXER, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new adau1373_right_adc_mixer_controls[] = {
- SOC_DAPM_SINGLE("DAC1 Switch", ADAU1373_RADC_MIXER, 4, 1, 0),
- SOC_DAPM_SINGLE("Input 4 Switch", ADAU1373_RADC_MIXER, 3, 1, 0),
- SOC_DAPM_SINGLE("Input 3 Switch", ADAU1373_RADC_MIXER, 2, 1, 0),
- SOC_DAPM_SINGLE("Input 2 Switch", ADAU1373_RADC_MIXER, 1, 1, 0),
- SOC_DAPM_SINGLE("Input 1 Switch", ADAU1373_RADC_MIXER, 0, 1, 0),
-};
-
-#define DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(_name, _reg) \
-const struct snd_kcontrol_new _name[] = { \
- SOC_DAPM_SINGLE("Left DAC2 Switch", _reg, 7, 1, 0), \
- SOC_DAPM_SINGLE("Right DAC2 Switch", _reg, 6, 1, 0), \
- SOC_DAPM_SINGLE("Left DAC1 Switch", _reg, 5, 1, 0), \
- SOC_DAPM_SINGLE("Right DAC1 Switch", _reg, 4, 1, 0), \
- SOC_DAPM_SINGLE("Input 4 Bypass Switch", _reg, 3, 1, 0), \
- SOC_DAPM_SINGLE("Input 3 Bypass Switch", _reg, 2, 1, 0), \
- SOC_DAPM_SINGLE("Input 2 Bypass Switch", _reg, 1, 1, 0), \
- SOC_DAPM_SINGLE("Input 1 Bypass Switch", _reg, 0, 1, 0), \
-}
-
-static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_line1_mixer_controls,
- ADAU1373_LLINE1_MIX);
-static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_line1_mixer_controls,
- ADAU1373_RLINE1_MIX);
-static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_line2_mixer_controls,
- ADAU1373_LLINE2_MIX);
-static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_line2_mixer_controls,
- ADAU1373_RLINE2_MIX);
-static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_spk_mixer_controls,
- ADAU1373_LSPK_MIX);
-static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_spk_mixer_controls,
- ADAU1373_RSPK_MIX);
-static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_ep_mixer_controls,
- ADAU1373_EP_MIX);
-
-static const struct snd_kcontrol_new adau1373_left_hp_mixer_controls[] = {
- SOC_DAPM_SINGLE("Left DAC1 Switch", ADAU1373_LHP_MIX, 5, 1, 0),
- SOC_DAPM_SINGLE("Left DAC2 Switch", ADAU1373_LHP_MIX, 4, 1, 0),
- SOC_DAPM_SINGLE("Input 4 Bypass Switch", ADAU1373_LHP_MIX, 3, 1, 0),
- SOC_DAPM_SINGLE("Input 3 Bypass Switch", ADAU1373_LHP_MIX, 2, 1, 0),
- SOC_DAPM_SINGLE("Input 2 Bypass Switch", ADAU1373_LHP_MIX, 1, 1, 0),
- SOC_DAPM_SINGLE("Input 1 Bypass Switch", ADAU1373_LHP_MIX, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new adau1373_right_hp_mixer_controls[] = {
- SOC_DAPM_SINGLE("Right DAC1 Switch", ADAU1373_RHP_MIX, 5, 1, 0),
- SOC_DAPM_SINGLE("Right DAC2 Switch", ADAU1373_RHP_MIX, 4, 1, 0),
- SOC_DAPM_SINGLE("Input 4 Bypass Switch", ADAU1373_RHP_MIX, 3, 1, 0),
- SOC_DAPM_SINGLE("Input 3 Bypass Switch", ADAU1373_RHP_MIX, 2, 1, 0),
- SOC_DAPM_SINGLE("Input 2 Bypass Switch", ADAU1373_RHP_MIX, 1, 1, 0),
- SOC_DAPM_SINGLE("Input 1 Bypass Switch", ADAU1373_RHP_MIX, 0, 1, 0),
-};
-
-#define DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(_name, _reg) \
-const struct snd_kcontrol_new _name[] = { \
- SOC_DAPM_SINGLE("DMIC2 Swapped Switch", _reg, 6, 1, 0), \
- SOC_DAPM_SINGLE("DMIC2 Switch", _reg, 5, 1, 0), \
- SOC_DAPM_SINGLE("ADC/DMIC1 Swapped Switch", _reg, 4, 1, 0), \
- SOC_DAPM_SINGLE("ADC/DMIC1 Switch", _reg, 3, 1, 0), \
- SOC_DAPM_SINGLE("AIF3 Switch", _reg, 2, 1, 0), \
- SOC_DAPM_SINGLE("AIF2 Switch", _reg, 1, 1, 0), \
- SOC_DAPM_SINGLE("AIF1 Switch", _reg, 0, 1, 0), \
-}
-
-static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel1_mixer_controls,
- ADAU1373_DIN_MIX_CTRL(0));
-static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel2_mixer_controls,
- ADAU1373_DIN_MIX_CTRL(1));
-static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel3_mixer_controls,
- ADAU1373_DIN_MIX_CTRL(2));
-static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel4_mixer_controls,
- ADAU1373_DIN_MIX_CTRL(3));
-static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel5_mixer_controls,
- ADAU1373_DIN_MIX_CTRL(4));
-
-#define DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(_name, _reg) \
-const struct snd_kcontrol_new _name[] = { \
- SOC_DAPM_SINGLE("DSP Channel5 Switch", _reg, 4, 1, 0), \
- SOC_DAPM_SINGLE("DSP Channel4 Switch", _reg, 3, 1, 0), \
- SOC_DAPM_SINGLE("DSP Channel3 Switch", _reg, 2, 1, 0), \
- SOC_DAPM_SINGLE("DSP Channel2 Switch", _reg, 1, 1, 0), \
- SOC_DAPM_SINGLE("DSP Channel1 Switch", _reg, 0, 1, 0), \
-}
-
-static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif1_mixer_controls,
- ADAU1373_DOUT_MIX_CTRL(0));
-static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif2_mixer_controls,
- ADAU1373_DOUT_MIX_CTRL(1));
-static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif3_mixer_controls,
- ADAU1373_DOUT_MIX_CTRL(2));
-static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_dac1_mixer_controls,
- ADAU1373_DOUT_MIX_CTRL(3));
-static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_dac2_mixer_controls,
- ADAU1373_DOUT_MIX_CTRL(4));
-
-static const struct snd_soc_dapm_widget adau1373_dapm_widgets[] = {
- /* Datasheet claims Left ADC is bit 6 and Right ADC is bit 7, but that
- * doesn't seem to be the case. */
- SND_SOC_DAPM_ADC("Left ADC", NULL, ADAU1373_PWDN_CTRL1, 7, 0),
- SND_SOC_DAPM_ADC("Right ADC", NULL, ADAU1373_PWDN_CTRL1, 6, 0),
-
- SND_SOC_DAPM_ADC("DMIC1", NULL, ADAU1373_DIGMICCTRL, 0, 0),
- SND_SOC_DAPM_ADC("DMIC2", NULL, ADAU1373_DIGMICCTRL, 2, 0),
-
- SND_SOC_DAPM_VIRT_MUX("Decimator Mux", SND_SOC_NOPM, 0, 0,
- &adau1373_decimator_mux),
-
- SND_SOC_DAPM_SUPPLY("MICBIAS2", ADAU1373_PWDN_CTRL1, 5, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("MICBIAS1", ADAU1373_PWDN_CTRL1, 4, 0, NULL, 0),
-
- SND_SOC_DAPM_PGA("IN4PGA", ADAU1373_PWDN_CTRL1, 3, 0, NULL, 0),
- SND_SOC_DAPM_PGA("IN3PGA", ADAU1373_PWDN_CTRL1, 2, 0, NULL, 0),
- SND_SOC_DAPM_PGA("IN2PGA", ADAU1373_PWDN_CTRL1, 1, 0, NULL, 0),
- SND_SOC_DAPM_PGA("IN1PGA", ADAU1373_PWDN_CTRL1, 0, 0, NULL, 0),
-
- SND_SOC_DAPM_DAC("Left DAC2", NULL, ADAU1373_PWDN_CTRL2, 7, 0),
- SND_SOC_DAPM_DAC("Right DAC2", NULL, ADAU1373_PWDN_CTRL2, 6, 0),
- SND_SOC_DAPM_DAC("Left DAC1", NULL, ADAU1373_PWDN_CTRL2, 5, 0),
- SND_SOC_DAPM_DAC("Right DAC1", NULL, ADAU1373_PWDN_CTRL2, 4, 0),
-
- SOC_MIXER_ARRAY("Left ADC Mixer", SND_SOC_NOPM, 0, 0,
- adau1373_left_adc_mixer_controls),
- SOC_MIXER_ARRAY("Right ADC Mixer", SND_SOC_NOPM, 0, 0,
- adau1373_right_adc_mixer_controls),
-
- SOC_MIXER_ARRAY("Left Lineout2 Mixer", ADAU1373_PWDN_CTRL2, 3, 0,
- adau1373_left_line2_mixer_controls),
- SOC_MIXER_ARRAY("Right Lineout2 Mixer", ADAU1373_PWDN_CTRL2, 2, 0,
- adau1373_right_line2_mixer_controls),
- SOC_MIXER_ARRAY("Left Lineout1 Mixer", ADAU1373_PWDN_CTRL2, 1, 0,
- adau1373_left_line1_mixer_controls),
- SOC_MIXER_ARRAY("Right Lineout1 Mixer", ADAU1373_PWDN_CTRL2, 0, 0,
- adau1373_right_line1_mixer_controls),
-
- SOC_MIXER_ARRAY("Earpiece Mixer", ADAU1373_PWDN_CTRL3, 4, 0,
- adau1373_ep_mixer_controls),
- SOC_MIXER_ARRAY("Left Speaker Mixer", ADAU1373_PWDN_CTRL3, 3, 0,
- adau1373_left_spk_mixer_controls),
- SOC_MIXER_ARRAY("Right Speaker Mixer", ADAU1373_PWDN_CTRL3, 2, 0,
- adau1373_right_spk_mixer_controls),
- SOC_MIXER_ARRAY("Left Headphone Mixer", SND_SOC_NOPM, 0, 0,
- adau1373_left_hp_mixer_controls),
- SOC_MIXER_ARRAY("Right Headphone Mixer", SND_SOC_NOPM, 0, 0,
- adau1373_right_hp_mixer_controls),
- SND_SOC_DAPM_SUPPLY("Headphone Enable", ADAU1373_PWDN_CTRL3, 1, 0,
- NULL, 0),
-
- SND_SOC_DAPM_SUPPLY("AIF1 CLK", ADAU1373_SRC_DAI_CTRL(0), 0, 0,
- NULL, 0),
- SND_SOC_DAPM_SUPPLY("AIF2 CLK", ADAU1373_SRC_DAI_CTRL(1), 0, 0,
- NULL, 0),
- SND_SOC_DAPM_SUPPLY("AIF3 CLK", ADAU1373_SRC_DAI_CTRL(2), 0, 0,
- NULL, 0),
- SND_SOC_DAPM_SUPPLY("AIF1 IN SRC", ADAU1373_SRC_DAI_CTRL(0), 2, 0,
- NULL, 0),
- SND_SOC_DAPM_SUPPLY("AIF1 OUT SRC", ADAU1373_SRC_DAI_CTRL(0), 1, 0,
- NULL, 0),
- SND_SOC_DAPM_SUPPLY("AIF2 IN SRC", ADAU1373_SRC_DAI_CTRL(1), 2, 0,
- NULL, 0),
- SND_SOC_DAPM_SUPPLY("AIF2 OUT SRC", ADAU1373_SRC_DAI_CTRL(1), 1, 0,
- NULL, 0),
- SND_SOC_DAPM_SUPPLY("AIF3 IN SRC", ADAU1373_SRC_DAI_CTRL(2), 2, 0,
- NULL, 0),
- SND_SOC_DAPM_SUPPLY("AIF3 OUT SRC", ADAU1373_SRC_DAI_CTRL(2), 1, 0,
- NULL, 0),
-
- SND_SOC_DAPM_AIF_IN("AIF1 IN", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_AIF_OUT("AIF1 OUT", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_AIF_IN("AIF2 IN", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_AIF_OUT("AIF2 OUT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_AIF_IN("AIF3 IN", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_AIF_OUT("AIF3 OUT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
-
- SOC_MIXER_ARRAY("DSP Channel1 Mixer", SND_SOC_NOPM, 0, 0,
- adau1373_dsp_channel1_mixer_controls),
- SOC_MIXER_ARRAY("DSP Channel2 Mixer", SND_SOC_NOPM, 0, 0,
- adau1373_dsp_channel2_mixer_controls),
- SOC_MIXER_ARRAY("DSP Channel3 Mixer", SND_SOC_NOPM, 0, 0,
- adau1373_dsp_channel3_mixer_controls),
- SOC_MIXER_ARRAY("DSP Channel4 Mixer", SND_SOC_NOPM, 0, 0,
- adau1373_dsp_channel4_mixer_controls),
- SOC_MIXER_ARRAY("DSP Channel5 Mixer", SND_SOC_NOPM, 0, 0,
- adau1373_dsp_channel5_mixer_controls),
-
- SOC_MIXER_ARRAY("AIF1 Mixer", SND_SOC_NOPM, 0, 0,
- adau1373_aif1_mixer_controls),
- SOC_MIXER_ARRAY("AIF2 Mixer", SND_SOC_NOPM, 0, 0,
- adau1373_aif2_mixer_controls),
- SOC_MIXER_ARRAY("AIF3 Mixer", SND_SOC_NOPM, 0, 0,
- adau1373_aif3_mixer_controls),
- SOC_MIXER_ARRAY("DAC1 Mixer", SND_SOC_NOPM, 0, 0,
- adau1373_dac1_mixer_controls),
- SOC_MIXER_ARRAY("DAC2 Mixer", SND_SOC_NOPM, 0, 0,
- adau1373_dac2_mixer_controls),
-
- SND_SOC_DAPM_SUPPLY("DSP", ADAU1373_DIGEN, 4, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("Recording Engine B", ADAU1373_DIGEN, 3, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("Recording Engine A", ADAU1373_DIGEN, 2, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("Playback Engine B", ADAU1373_DIGEN, 1, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("Playback Engine A", ADAU1373_DIGEN, 0, 0, NULL, 0),
-
- SND_SOC_DAPM_SUPPLY("PLL1", SND_SOC_NOPM, 0, 0, adau1373_pll_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_SUPPLY("PLL2", SND_SOC_NOPM, 0, 0, adau1373_pll_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_SUPPLY("SYSCLK1", ADAU1373_CLK_SRC_DIV(0), 7, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("SYSCLK2", ADAU1373_CLK_SRC_DIV(1), 7, 0, NULL, 0),
-
- SND_SOC_DAPM_INPUT("AIN1L"),
- SND_SOC_DAPM_INPUT("AIN1R"),
- SND_SOC_DAPM_INPUT("AIN2L"),
- SND_SOC_DAPM_INPUT("AIN2R"),
- SND_SOC_DAPM_INPUT("AIN3L"),
- SND_SOC_DAPM_INPUT("AIN3R"),
- SND_SOC_DAPM_INPUT("AIN4L"),
- SND_SOC_DAPM_INPUT("AIN4R"),
-
- SND_SOC_DAPM_INPUT("DMIC1DAT"),
- SND_SOC_DAPM_INPUT("DMIC2DAT"),
-
- SND_SOC_DAPM_OUTPUT("LOUT1L"),
- SND_SOC_DAPM_OUTPUT("LOUT1R"),
- SND_SOC_DAPM_OUTPUT("LOUT2L"),
- SND_SOC_DAPM_OUTPUT("LOUT2R"),
- SND_SOC_DAPM_OUTPUT("HPL"),
- SND_SOC_DAPM_OUTPUT("HPR"),
- SND_SOC_DAPM_OUTPUT("SPKL"),
- SND_SOC_DAPM_OUTPUT("SPKR"),
- SND_SOC_DAPM_OUTPUT("EP"),
-};
-
-static int adau1373_check_aif_clk(struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink)
-{
- struct snd_soc_codec *codec = source->codec;
- struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
- unsigned int dai;
- const char *clk;
-
- dai = sink->name[3] - '1';
-
- if (!adau1373->dais[dai].master)
- return 0;
-
- if (adau1373->dais[dai].clk_src == ADAU1373_CLK_SRC_PLL1)
- clk = "SYSCLK1";
- else
- clk = "SYSCLK2";
-
- return strcmp(source->name, clk) == 0;
-}
-
-static int adau1373_check_src(struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink)
-{
- struct snd_soc_codec *codec = source->codec;
- struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
- unsigned int dai;
-
- dai = sink->name[3] - '1';
-
- return adau1373->dais[dai].enable_src;
-}
-
-#define DSP_CHANNEL_MIXER_ROUTES(_sink) \
- { _sink, "DMIC2 Swapped Switch", "DMIC2" }, \
- { _sink, "DMIC2 Switch", "DMIC2" }, \
- { _sink, "ADC/DMIC1 Swapped Switch", "Decimator Mux" }, \
- { _sink, "ADC/DMIC1 Switch", "Decimator Mux" }, \
- { _sink, "AIF1 Switch", "AIF1 IN" }, \
- { _sink, "AIF2 Switch", "AIF2 IN" }, \
- { _sink, "AIF3 Switch", "AIF3 IN" }
-
-#define DSP_OUTPUT_MIXER_ROUTES(_sink) \
- { _sink, "DSP Channel1 Switch", "DSP Channel1 Mixer" }, \
- { _sink, "DSP Channel2 Switch", "DSP Channel2 Mixer" }, \
- { _sink, "DSP Channel3 Switch", "DSP Channel3 Mixer" }, \
- { _sink, "DSP Channel4 Switch", "DSP Channel4 Mixer" }, \
- { _sink, "DSP Channel5 Switch", "DSP Channel5 Mixer" }
-
-#define LEFT_OUTPUT_MIXER_ROUTES(_sink) \
- { _sink, "Right DAC2 Switch", "Right DAC2" }, \
- { _sink, "Left DAC2 Switch", "Left DAC2" }, \
- { _sink, "Right DAC1 Switch", "Right DAC1" }, \
- { _sink, "Left DAC1 Switch", "Left DAC1" }, \
- { _sink, "Input 1 Bypass Switch", "IN1PGA" }, \
- { _sink, "Input 2 Bypass Switch", "IN2PGA" }, \
- { _sink, "Input 3 Bypass Switch", "IN3PGA" }, \
- { _sink, "Input 4 Bypass Switch", "IN4PGA" }
-
-#define RIGHT_OUTPUT_MIXER_ROUTES(_sink) \
- { _sink, "Right DAC2 Switch", "Right DAC2" }, \
- { _sink, "Left DAC2 Switch", "Left DAC2" }, \
- { _sink, "Right DAC1 Switch", "Right DAC1" }, \
- { _sink, "Left DAC1 Switch", "Left DAC1" }, \
- { _sink, "Input 1 Bypass Switch", "IN1PGA" }, \
- { _sink, "Input 2 Bypass Switch", "IN2PGA" }, \
- { _sink, "Input 3 Bypass Switch", "IN3PGA" }, \
- { _sink, "Input 4 Bypass Switch", "IN4PGA" }
-
-static const struct snd_soc_dapm_route adau1373_dapm_routes[] = {
- { "Left ADC Mixer", "DAC1 Switch", "Left DAC1" },
- { "Left ADC Mixer", "Input 1 Switch", "IN1PGA" },
- { "Left ADC Mixer", "Input 2 Switch", "IN2PGA" },
- { "Left ADC Mixer", "Input 3 Switch", "IN3PGA" },
- { "Left ADC Mixer", "Input 4 Switch", "IN4PGA" },
-
- { "Right ADC Mixer", "DAC1 Switch", "Right DAC1" },
- { "Right ADC Mixer", "Input 1 Switch", "IN1PGA" },
- { "Right ADC Mixer", "Input 2 Switch", "IN2PGA" },
- { "Right ADC Mixer", "Input 3 Switch", "IN3PGA" },
- { "Right ADC Mixer", "Input 4 Switch", "IN4PGA" },
-
- { "Left ADC", NULL, "Left ADC Mixer" },
- { "Right ADC", NULL, "Right ADC Mixer" },
-
- { "Decimator Mux", "ADC", "Left ADC" },
- { "Decimator Mux", "ADC", "Right ADC" },
- { "Decimator Mux", "DMIC1", "DMIC1" },
-
- DSP_CHANNEL_MIXER_ROUTES("DSP Channel1 Mixer"),
- DSP_CHANNEL_MIXER_ROUTES("DSP Channel2 Mixer"),
- DSP_CHANNEL_MIXER_ROUTES("DSP Channel3 Mixer"),
- DSP_CHANNEL_MIXER_ROUTES("DSP Channel4 Mixer"),
- DSP_CHANNEL_MIXER_ROUTES("DSP Channel5 Mixer"),
-
- DSP_OUTPUT_MIXER_ROUTES("AIF1 Mixer"),
- DSP_OUTPUT_MIXER_ROUTES("AIF2 Mixer"),
- DSP_OUTPUT_MIXER_ROUTES("AIF3 Mixer"),
- DSP_OUTPUT_MIXER_ROUTES("DAC1 Mixer"),
- DSP_OUTPUT_MIXER_ROUTES("DAC2 Mixer"),
-
- { "AIF1 OUT", NULL, "AIF1 Mixer" },
- { "AIF2 OUT", NULL, "AIF2 Mixer" },
- { "AIF3 OUT", NULL, "AIF3 Mixer" },
- { "Left DAC1", NULL, "DAC1 Mixer" },
- { "Right DAC1", NULL, "DAC1 Mixer" },
- { "Left DAC2", NULL, "DAC2 Mixer" },
- { "Right DAC2", NULL, "DAC2 Mixer" },
-
- LEFT_OUTPUT_MIXER_ROUTES("Left Lineout1 Mixer"),
- RIGHT_OUTPUT_MIXER_ROUTES("Right Lineout1 Mixer"),
- LEFT_OUTPUT_MIXER_ROUTES("Left Lineout2 Mixer"),
- RIGHT_OUTPUT_MIXER_ROUTES("Right Lineout2 Mixer"),
- LEFT_OUTPUT_MIXER_ROUTES("Left Speaker Mixer"),
- RIGHT_OUTPUT_MIXER_ROUTES("Right Speaker Mixer"),
-
- { "Left Headphone Mixer", "Left DAC2 Switch", "Left DAC2" },
- { "Left Headphone Mixer", "Left DAC1 Switch", "Left DAC1" },
- { "Left Headphone Mixer", "Input 1 Bypass Switch", "IN1PGA" },
- { "Left Headphone Mixer", "Input 2 Bypass Switch", "IN2PGA" },
- { "Left Headphone Mixer", "Input 3 Bypass Switch", "IN3PGA" },
- { "Left Headphone Mixer", "Input 4 Bypass Switch", "IN4PGA" },
- { "Right Headphone Mixer", "Right DAC2 Switch", "Right DAC2" },
- { "Right Headphone Mixer", "Right DAC1 Switch", "Right DAC1" },
- { "Right Headphone Mixer", "Input 1 Bypass Switch", "IN1PGA" },
- { "Right Headphone Mixer", "Input 2 Bypass Switch", "IN2PGA" },
- { "Right Headphone Mixer", "Input 3 Bypass Switch", "IN3PGA" },
- { "Right Headphone Mixer", "Input 4 Bypass Switch", "IN4PGA" },
-
- { "Left Headphone Mixer", NULL, "Headphone Enable" },
- { "Right Headphone Mixer", NULL, "Headphone Enable" },
-
- { "Earpiece Mixer", "Right DAC2 Switch", "Right DAC2" },
- { "Earpiece Mixer", "Left DAC2 Switch", "Left DAC2" },
- { "Earpiece Mixer", "Right DAC1 Switch", "Right DAC1" },
- { "Earpiece Mixer", "Left DAC1 Switch", "Left DAC1" },
- { "Earpiece Mixer", "Input 1 Bypass Switch", "IN1PGA" },
- { "Earpiece Mixer", "Input 2 Bypass Switch", "IN2PGA" },
- { "Earpiece Mixer", "Input 3 Bypass Switch", "IN3PGA" },
- { "Earpiece Mixer", "Input 4 Bypass Switch", "IN4PGA" },
-
- { "LOUT1L", NULL, "Left Lineout1 Mixer" },
- { "LOUT1R", NULL, "Right Lineout1 Mixer" },
- { "LOUT2L", NULL, "Left Lineout2 Mixer" },
- { "LOUT2R", NULL, "Right Lineout2 Mixer" },
- { "SPKL", NULL, "Left Speaker Mixer" },
- { "SPKR", NULL, "Right Speaker Mixer" },
- { "HPL", NULL, "Left Headphone Mixer" },
- { "HPR", NULL, "Right Headphone Mixer" },
- { "EP", NULL, "Earpiece Mixer" },
-
- { "IN1PGA", NULL, "AIN1L" },
- { "IN2PGA", NULL, "AIN2L" },
- { "IN3PGA", NULL, "AIN3L" },
- { "IN4PGA", NULL, "AIN4L" },
- { "IN1PGA", NULL, "AIN1R" },
- { "IN2PGA", NULL, "AIN2R" },
- { "IN3PGA", NULL, "AIN3R" },
- { "IN4PGA", NULL, "AIN4R" },
-
- { "SYSCLK1", NULL, "PLL1" },
- { "SYSCLK2", NULL, "PLL2" },
-
- { "Left DAC1", NULL, "SYSCLK1" },
- { "Right DAC1", NULL, "SYSCLK1" },
- { "Left DAC2", NULL, "SYSCLK1" },
- { "Right DAC2", NULL, "SYSCLK1" },
- { "Left ADC", NULL, "SYSCLK1" },
- { "Right ADC", NULL, "SYSCLK1" },
-
- { "DSP", NULL, "SYSCLK1" },
-
- { "AIF1 Mixer", NULL, "DSP" },
- { "AIF2 Mixer", NULL, "DSP" },
- { "AIF3 Mixer", NULL, "DSP" },
- { "DAC1 Mixer", NULL, "DSP" },
- { "DAC2 Mixer", NULL, "DSP" },
- { "DAC1 Mixer", NULL, "Playback Engine A" },
- { "DAC2 Mixer", NULL, "Playback Engine B" },
- { "Left ADC Mixer", NULL, "Recording Engine A" },
- { "Right ADC Mixer", NULL, "Recording Engine A" },
-
- { "AIF1 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk },
- { "AIF2 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk },
- { "AIF3 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk },
- { "AIF1 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk },
- { "AIF2 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk },
- { "AIF3 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk },
-
- { "AIF1 IN", NULL, "AIF1 CLK" },
- { "AIF1 OUT", NULL, "AIF1 CLK" },
- { "AIF2 IN", NULL, "AIF2 CLK" },
- { "AIF2 OUT", NULL, "AIF2 CLK" },
- { "AIF3 IN", NULL, "AIF3 CLK" },
- { "AIF3 OUT", NULL, "AIF3 CLK" },
- { "AIF1 IN", NULL, "AIF1 IN SRC", adau1373_check_src },
- { "AIF1 OUT", NULL, "AIF1 OUT SRC", adau1373_check_src },
- { "AIF2 IN", NULL, "AIF2 IN SRC", adau1373_check_src },
- { "AIF2 OUT", NULL, "AIF2 OUT SRC", adau1373_check_src },
- { "AIF3 IN", NULL, "AIF3 IN SRC", adau1373_check_src },
- { "AIF3 OUT", NULL, "AIF3 OUT SRC", adau1373_check_src },
-
- { "DMIC1", NULL, "DMIC1DAT" },
- { "DMIC1", NULL, "SYSCLK1" },
- { "DMIC1", NULL, "Recording Engine A" },
- { "DMIC2", NULL, "DMIC2DAT" },
- { "DMIC2", NULL, "SYSCLK1" },
- { "DMIC2", NULL, "Recording Engine B" },
-};
-
-static int adau1373_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
- struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
- unsigned int div;
- unsigned int freq;
- unsigned int ctrl;
-
- freq = adau1373_dai->sysclk;
-
- if (freq % params_rate(params) != 0)
- return -EINVAL;
-
- switch (freq / params_rate(params)) {
- case 1024: /* sysclk / 256 */
- div = 0;
- break;
- case 1536: /* 2/3 sysclk / 256 */
- div = 1;
- break;
- case 2048: /* 1/2 sysclk / 256 */
- div = 2;
- break;
- case 3072: /* 1/3 sysclk / 256 */
- div = 3;
- break;
- case 4096: /* 1/4 sysclk / 256 */
- div = 4;
- break;
- case 6144: /* 1/6 sysclk / 256 */
- div = 5;
- break;
- case 5632: /* 2/11 sysclk / 256 */
- div = 6;
- break;
- default:
- return -EINVAL;
- }
-
- adau1373_dai->enable_src = (div != 0);
-
- snd_soc_update_bits(codec, ADAU1373_BCLKDIV(dai->id),
- ~ADAU1373_BCLKDIV_SOURCE, (div << 2) | ADAU1373_BCLKDIV_64);
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- ctrl = ADAU1373_DAI_WLEN_16;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- ctrl = ADAU1373_DAI_WLEN_20;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- ctrl = ADAU1373_DAI_WLEN_24;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- ctrl = ADAU1373_DAI_WLEN_32;
- break;
- default:
- return -EINVAL;
- }
-
- return snd_soc_update_bits(codec, ADAU1373_DAI(dai->id),
- ADAU1373_DAI_WLEN_MASK, ctrl);
-}
-
-static int adau1373_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
- struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
- unsigned int ctrl;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- ctrl = ADAU1373_DAI_MASTER;
- adau1373_dai->master = true;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- ctrl = 0;
- adau1373_dai->master = false;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- ctrl |= ADAU1373_DAI_FORMAT_I2S;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- ctrl |= ADAU1373_DAI_FORMAT_LEFT_J;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- ctrl |= ADAU1373_DAI_FORMAT_RIGHT_J;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- ctrl |= ADAU1373_DAI_FORMAT_DSP;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_NF:
- ctrl |= ADAU1373_DAI_INVERT_BCLK;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- ctrl |= ADAU1373_DAI_INVERT_LRCLK;
- break;
- case SND_SOC_DAIFMT_IB_IF:
- ctrl |= ADAU1373_DAI_INVERT_LRCLK | ADAU1373_DAI_INVERT_BCLK;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, ADAU1373_DAI(dai->id),
- ~ADAU1373_DAI_WLEN_MASK, ctrl);
-
- return 0;
-}
-
-static int adau1373_set_dai_sysclk(struct snd_soc_dai *dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(dai->codec);
- struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
-
- switch (clk_id) {
- case ADAU1373_CLK_SRC_PLL1:
- case ADAU1373_CLK_SRC_PLL2:
- break;
- default:
- return -EINVAL;
- }
-
- adau1373_dai->sysclk = freq;
- adau1373_dai->clk_src = clk_id;
-
- snd_soc_update_bits(dai->codec, ADAU1373_BCLKDIV(dai->id),
- ADAU1373_BCLKDIV_SOURCE, clk_id << 5);
-
- return 0;
-}
-
-static const struct snd_soc_dai_ops adau1373_dai_ops = {
- .hw_params = adau1373_hw_params,
- .set_sysclk = adau1373_set_dai_sysclk,
- .set_fmt = adau1373_set_dai_fmt,
-};
-
-#define ADAU1373_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static struct snd_soc_dai_driver adau1373_dai_driver[] = {
- {
- .id = 0,
- .name = "adau1373-aif1",
- .playback = {
- .stream_name = "AIF1 Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = ADAU1373_FORMATS,
- },
- .capture = {
- .stream_name = "AIF1 Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = ADAU1373_FORMATS,
- },
- .ops = &adau1373_dai_ops,
- .symmetric_rates = 1,
- },
- {
- .id = 1,
- .name = "adau1373-aif2",
- .playback = {
- .stream_name = "AIF2 Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = ADAU1373_FORMATS,
- },
- .capture = {
- .stream_name = "AIF2 Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = ADAU1373_FORMATS,
- },
- .ops = &adau1373_dai_ops,
- .symmetric_rates = 1,
- },
- {
- .id = 2,
- .name = "adau1373-aif3",
- .playback = {
- .stream_name = "AIF3 Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = ADAU1373_FORMATS,
- },
- .capture = {
- .stream_name = "AIF3 Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = ADAU1373_FORMATS,
- },
- .ops = &adau1373_dai_ops,
- .symmetric_rates = 1,
- },
-};
-
-static int adau1373_set_pll(struct snd_soc_codec *codec, int pll_id,
- int source, unsigned int freq_in, unsigned int freq_out)
-{
- unsigned int dpll_div = 0;
- unsigned int x, r, n, m, i, j, mode;
-
- switch (pll_id) {
- case ADAU1373_PLL1:
- case ADAU1373_PLL2:
- break;
- default:
- return -EINVAL;
- }
-
- switch (source) {
- case ADAU1373_PLL_SRC_BCLK1:
- case ADAU1373_PLL_SRC_BCLK2:
- case ADAU1373_PLL_SRC_BCLK3:
- case ADAU1373_PLL_SRC_LRCLK1:
- case ADAU1373_PLL_SRC_LRCLK2:
- case ADAU1373_PLL_SRC_LRCLK3:
- case ADAU1373_PLL_SRC_MCLK1:
- case ADAU1373_PLL_SRC_MCLK2:
- case ADAU1373_PLL_SRC_GPIO1:
- case ADAU1373_PLL_SRC_GPIO2:
- case ADAU1373_PLL_SRC_GPIO3:
- case ADAU1373_PLL_SRC_GPIO4:
- break;
- default:
- return -EINVAL;
- }
-
- if (freq_in < 7813 || freq_in > 27000000)
- return -EINVAL;
-
- if (freq_out < 45158000 || freq_out > 49152000)
- return -EINVAL;
-
- /* APLL input needs to be >= 8Mhz, so in case freq_in is less we use the
- * DPLL to get it there. DPLL_out = (DPLL_in / div) * 1024 */
- while (freq_in < 8000000) {
- freq_in *= 2;
- dpll_div++;
- }
-
- if (freq_out % freq_in != 0) {
- /* fout = fin * (r + (n/m)) / x */
- x = DIV_ROUND_UP(freq_in, 13500000);
- freq_in /= x;
- r = freq_out / freq_in;
- i = freq_out % freq_in;
- j = gcd(i, freq_in);
- n = i / j;
- m = freq_in / j;
- x--;
- mode = 1;
- } else {
- /* fout = fin / r */
- r = freq_out / freq_in;
- n = 0;
- m = 0;
- x = 0;
- mode = 0;
- }
-
- if (r < 2 || r > 8 || x > 3 || m > 0xffff || n > 0xffff)
- return -EINVAL;
-
- if (dpll_div) {
- dpll_div = 11 - dpll_div;
- snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id),
- ADAU1373_PLL_CTRL6_DPLL_BYPASS, 0);
- } else {
- snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id),
- ADAU1373_PLL_CTRL6_DPLL_BYPASS,
- ADAU1373_PLL_CTRL6_DPLL_BYPASS);
- }
-
- snd_soc_write(codec, ADAU1373_DPLL_CTRL(pll_id),
- (source << 4) | dpll_div);
- snd_soc_write(codec, ADAU1373_PLL_CTRL1(pll_id), (m >> 8) & 0xff);
- snd_soc_write(codec, ADAU1373_PLL_CTRL2(pll_id), m & 0xff);
- snd_soc_write(codec, ADAU1373_PLL_CTRL3(pll_id), (n >> 8) & 0xff);
- snd_soc_write(codec, ADAU1373_PLL_CTRL4(pll_id), n & 0xff);
- snd_soc_write(codec, ADAU1373_PLL_CTRL5(pll_id),
- (r << 3) | (x << 1) | mode);
-
- /* Set sysclk to pll_rate / 4 */
- snd_soc_update_bits(codec, ADAU1373_CLK_SRC_DIV(pll_id), 0x3f, 0x09);
-
- return 0;
-}
-
-static void adau1373_load_drc_settings(struct snd_soc_codec *codec,
- unsigned int nr, uint8_t *drc)
-{
- unsigned int i;
-
- for (i = 0; i < ADAU1373_DRC_SIZE; ++i)
- snd_soc_write(codec, ADAU1373_DRC(nr) + i, drc[i]);
-}
-
-static bool adau1373_valid_micbias(enum adau1373_micbias_voltage micbias)
-{
- switch (micbias) {
- case ADAU1373_MICBIAS_2_9V:
- case ADAU1373_MICBIAS_2_2V:
- case ADAU1373_MICBIAS_2_6V:
- case ADAU1373_MICBIAS_1_8V:
- return true;
- default:
- break;
- }
- return false;
-}
-
-static int adau1373_probe(struct snd_soc_codec *codec)
-{
- struct adau1373_platform_data *pdata = codec->dev->platform_data;
- bool lineout_differential = false;
- unsigned int val;
- int ret;
- int i;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
- if (ret) {
- dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- if (pdata) {
- if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting))
- return -EINVAL;
-
- if (!adau1373_valid_micbias(pdata->micbias1) ||
- !adau1373_valid_micbias(pdata->micbias2))
- return -EINVAL;
-
- for (i = 0; i < pdata->num_drc; ++i) {
- adau1373_load_drc_settings(codec, i,
- pdata->drc_setting[i]);
- }
-
- snd_soc_add_codec_controls(codec, adau1373_drc_controls,
- pdata->num_drc);
-
- val = 0;
- for (i = 0; i < 4; ++i) {
- if (pdata->input_differential[i])
- val |= BIT(i);
- }
- snd_soc_write(codec, ADAU1373_INPUT_MODE, val);
-
- val = 0;
- if (pdata->lineout_differential)
- val |= ADAU1373_OUTPUT_CTRL_LDIFF;
- if (pdata->lineout_ground_sense)
- val |= ADAU1373_OUTPUT_CTRL_LNFBEN;
- snd_soc_write(codec, ADAU1373_OUTPUT_CTRL, val);
-
- lineout_differential = pdata->lineout_differential;
-
- snd_soc_write(codec, ADAU1373_EP_CTRL,
- (pdata->micbias1 << ADAU1373_EP_CTRL_MICBIAS1_OFFSET) |
- (pdata->micbias2 << ADAU1373_EP_CTRL_MICBIAS2_OFFSET));
- }
-
- if (!lineout_differential) {
- snd_soc_add_codec_controls(codec, adau1373_lineout2_controls,
- ARRAY_SIZE(adau1373_lineout2_controls));
- }
-
- snd_soc_write(codec, ADAU1373_ADC_CTRL,
- ADAU1373_ADC_CTRL_RESET_FORCE | ADAU1373_ADC_CTRL_PEAK_DETECT);
-
- return 0;
-}
-
-static int adau1373_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- snd_soc_update_bits(codec, ADAU1373_PWDN_CTRL3,
- ADAU1373_PWDN_CTRL3_PWR_EN, ADAU1373_PWDN_CTRL3_PWR_EN);
- break;
- case SND_SOC_BIAS_OFF:
- snd_soc_update_bits(codec, ADAU1373_PWDN_CTRL3,
- ADAU1373_PWDN_CTRL3_PWR_EN, 0);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-static int adau1373_remove(struct snd_soc_codec *codec)
-{
- adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int adau1373_suspend(struct snd_soc_codec *codec)
-{
- return adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF);
-}
-
-static int adau1373_resume(struct snd_soc_codec *codec)
-{
- adau1373_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- snd_soc_cache_sync(codec);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver adau1373_codec_driver = {
- .probe = adau1373_probe,
- .remove = adau1373_remove,
- .suspend = adau1373_suspend,
- .resume = adau1373_resume,
- .set_bias_level = adau1373_set_bias_level,
- .idle_bias_off = true,
- .reg_cache_size = ARRAY_SIZE(adau1373_default_regs),
- .reg_cache_default = adau1373_default_regs,
- .reg_word_size = sizeof(uint8_t),
-
- .set_pll = adau1373_set_pll,
-
- .controls = adau1373_controls,
- .num_controls = ARRAY_SIZE(adau1373_controls),
- .dapm_widgets = adau1373_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(adau1373_dapm_widgets),
- .dapm_routes = adau1373_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(adau1373_dapm_routes),
-};
-
-static int __devinit adau1373_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct adau1373 *adau1373;
- int ret;
-
- adau1373 = devm_kzalloc(&client->dev, sizeof(*adau1373), GFP_KERNEL);
- if (!adau1373)
- return -ENOMEM;
-
- dev_set_drvdata(&client->dev, adau1373);
-
- ret = snd_soc_register_codec(&client->dev, &adau1373_codec_driver,
- adau1373_dai_driver, ARRAY_SIZE(adau1373_dai_driver));
- return ret;
-}
-
-static int __devexit adau1373_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static const struct i2c_device_id adau1373_i2c_id[] = {
- { "adau1373", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, adau1373_i2c_id);
-
-static struct i2c_driver adau1373_i2c_driver = {
- .driver = {
- .name = "adau1373",
- .owner = THIS_MODULE,
- },
- .probe = adau1373_i2c_probe,
- .remove = __devexit_p(adau1373_i2c_remove),
- .id_table = adau1373_i2c_id,
-};
-
-static int __init adau1373_init(void)
-{
- return i2c_add_driver(&adau1373_i2c_driver);
-}
-module_init(adau1373_init);
-
-static void __exit adau1373_exit(void)
-{
- i2c_del_driver(&adau1373_i2c_driver);
-}
-module_exit(adau1373_exit);
-
-MODULE_DESCRIPTION("ASoC ADAU1373 driver");
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/adau1373.h b/ANDROID_3.4.5/sound/soc/codecs/adau1373.h
deleted file mode 100644
index c6ab5530..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/adau1373.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef __ADAU1373_H__
-#define __ADAU1373_H__
-
-enum adau1373_pll_src {
- ADAU1373_PLL_SRC_MCLK1 = 0,
- ADAU1373_PLL_SRC_BCLK1 = 1,
- ADAU1373_PLL_SRC_BCLK2 = 2,
- ADAU1373_PLL_SRC_BCLK3 = 3,
- ADAU1373_PLL_SRC_LRCLK1 = 4,
- ADAU1373_PLL_SRC_LRCLK2 = 5,
- ADAU1373_PLL_SRC_LRCLK3 = 6,
- ADAU1373_PLL_SRC_GPIO1 = 7,
- ADAU1373_PLL_SRC_GPIO2 = 8,
- ADAU1373_PLL_SRC_GPIO3 = 9,
- ADAU1373_PLL_SRC_GPIO4 = 10,
- ADAU1373_PLL_SRC_MCLK2 = 11,
-};
-
-enum adau1373_pll {
- ADAU1373_PLL1 = 0,
- ADAU1373_PLL2 = 1,
-};
-
-enum adau1373_clk_src {
- ADAU1373_CLK_SRC_PLL1 = 0,
- ADAU1373_CLK_SRC_PLL2 = 1,
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/adau1701.c b/ANDROID_3.4.5/sound/soc/codecs/adau1701.c
deleted file mode 100644
index 78e9ce48..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/adau1701.c
+++ /dev/null
@@ -1,546 +0,0 @@
-/*
- * Driver for ADAU1701 SigmaDSP processor
- *
- * Copyright 2011 Analog Devices Inc.
- * Author: Lars-Peter Clausen <lars@metafoo.de>
- * based on an inital version by Cliff Cai <cliff.cai@analog.com>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include "sigmadsp.h"
-#include "adau1701.h"
-
-#define ADAU1701_DSPCTRL 0x1c
-#define ADAU1701_SEROCTL 0x1e
-#define ADAU1701_SERICTL 0x1f
-
-#define ADAU1701_AUXNPOW 0x22
-
-#define ADAU1701_OSCIPOW 0x26
-#define ADAU1701_DACSET 0x27
-
-#define ADAU1701_NUM_REGS 0x28
-
-#define ADAU1701_DSPCTRL_CR (1 << 2)
-#define ADAU1701_DSPCTRL_DAM (1 << 3)
-#define ADAU1701_DSPCTRL_ADM (1 << 4)
-#define ADAU1701_DSPCTRL_SR_48 0x00
-#define ADAU1701_DSPCTRL_SR_96 0x01
-#define ADAU1701_DSPCTRL_SR_192 0x02
-#define ADAU1701_DSPCTRL_SR_MASK 0x03
-
-#define ADAU1701_SEROCTL_INV_LRCLK 0x2000
-#define ADAU1701_SEROCTL_INV_BCLK 0x1000
-#define ADAU1701_SEROCTL_MASTER 0x0800
-
-#define ADAU1701_SEROCTL_OBF16 0x0000
-#define ADAU1701_SEROCTL_OBF8 0x0200
-#define ADAU1701_SEROCTL_OBF4 0x0400
-#define ADAU1701_SEROCTL_OBF2 0x0600
-#define ADAU1701_SEROCTL_OBF_MASK 0x0600
-
-#define ADAU1701_SEROCTL_OLF1024 0x0000
-#define ADAU1701_SEROCTL_OLF512 0x0080
-#define ADAU1701_SEROCTL_OLF256 0x0100
-#define ADAU1701_SEROCTL_OLF_MASK 0x0180
-
-#define ADAU1701_SEROCTL_MSB_DEALY1 0x0000
-#define ADAU1701_SEROCTL_MSB_DEALY0 0x0004
-#define ADAU1701_SEROCTL_MSB_DEALY8 0x0008
-#define ADAU1701_SEROCTL_MSB_DEALY12 0x000c
-#define ADAU1701_SEROCTL_MSB_DEALY16 0x0010
-#define ADAU1701_SEROCTL_MSB_DEALY_MASK 0x001c
-
-#define ADAU1701_SEROCTL_WORD_LEN_24 0x0000
-#define ADAU1701_SEROCTL_WORD_LEN_20 0x0001
-#define ADAU1701_SEROCTL_WORD_LEN_16 0x0010
-#define ADAU1701_SEROCTL_WORD_LEN_MASK 0x0003
-
-#define ADAU1701_AUXNPOW_VBPD 0x40
-#define ADAU1701_AUXNPOW_VRPD 0x20
-
-#define ADAU1701_SERICTL_I2S 0
-#define ADAU1701_SERICTL_LEFTJ 1
-#define ADAU1701_SERICTL_TDM 2
-#define ADAU1701_SERICTL_RIGHTJ_24 3
-#define ADAU1701_SERICTL_RIGHTJ_20 4
-#define ADAU1701_SERICTL_RIGHTJ_18 5
-#define ADAU1701_SERICTL_RIGHTJ_16 6
-#define ADAU1701_SERICTL_MODE_MASK 7
-#define ADAU1701_SERICTL_INV_BCLK BIT(3)
-#define ADAU1701_SERICTL_INV_LRCLK BIT(4)
-
-#define ADAU1701_OSCIPOW_OPD 0x04
-#define ADAU1701_DACSET_DACINIT 1
-
-#define ADAU1701_FIRMWARE "adau1701.bin"
-
-struct adau1701 {
- unsigned int dai_fmt;
-};
-
-static const struct snd_kcontrol_new adau1701_controls[] = {
- SOC_SINGLE("Master Capture Switch", ADAU1701_DSPCTRL, 4, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget adau1701_dapm_widgets[] = {
- SND_SOC_DAPM_DAC("DAC0", "Playback", ADAU1701_AUXNPOW, 3, 1),
- SND_SOC_DAPM_DAC("DAC1", "Playback", ADAU1701_AUXNPOW, 2, 1),
- SND_SOC_DAPM_DAC("DAC2", "Playback", ADAU1701_AUXNPOW, 1, 1),
- SND_SOC_DAPM_DAC("DAC3", "Playback", ADAU1701_AUXNPOW, 0, 1),
- SND_SOC_DAPM_ADC("ADC", "Capture", ADAU1701_AUXNPOW, 7, 1),
-
- SND_SOC_DAPM_OUTPUT("OUT0"),
- SND_SOC_DAPM_OUTPUT("OUT1"),
- SND_SOC_DAPM_OUTPUT("OUT2"),
- SND_SOC_DAPM_OUTPUT("OUT3"),
- SND_SOC_DAPM_INPUT("IN0"),
- SND_SOC_DAPM_INPUT("IN1"),
-};
-
-static const struct snd_soc_dapm_route adau1701_dapm_routes[] = {
- { "OUT0", NULL, "DAC0" },
- { "OUT1", NULL, "DAC1" },
- { "OUT2", NULL, "DAC2" },
- { "OUT3", NULL, "DAC3" },
-
- { "ADC", NULL, "IN0" },
- { "ADC", NULL, "IN1" },
-};
-
-static unsigned int adau1701_register_size(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- switch (reg) {
- case ADAU1701_DSPCTRL:
- case ADAU1701_SEROCTL:
- case ADAU1701_AUXNPOW:
- case ADAU1701_OSCIPOW:
- case ADAU1701_DACSET:
- return 2;
- case ADAU1701_SERICTL:
- return 1;
- }
-
- dev_err(codec->dev, "Unsupported register address: %d\n", reg);
- return 0;
-}
-
-static int adau1701_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- unsigned int i;
- unsigned int size;
- uint8_t buf[4];
- int ret;
-
- size = adau1701_register_size(codec, reg);
- if (size == 0)
- return -EINVAL;
-
- snd_soc_cache_write(codec, reg, value);
-
- buf[0] = 0x08;
- buf[1] = reg;
-
- for (i = size + 1; i >= 2; --i) {
- buf[i] = value;
- value >>= 8;
- }
-
- ret = i2c_master_send(to_i2c_client(codec->dev), buf, size + 2);
- if (ret == size + 2)
- return 0;
- else if (ret < 0)
- return ret;
- else
- return -EIO;
-}
-
-static unsigned int adau1701_read(struct snd_soc_codec *codec, unsigned int reg)
-{
- unsigned int value;
- unsigned int ret;
-
- ret = snd_soc_cache_read(codec, reg, &value);
- if (ret)
- return ret;
-
- return value;
-}
-
-static int adau1701_load_firmware(struct snd_soc_codec *codec)
-{
- return process_sigma_firmware(codec->control_data, ADAU1701_FIRMWARE);
-}
-
-static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
- snd_pcm_format_t format)
-{
- struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
- unsigned int mask = ADAU1701_SEROCTL_WORD_LEN_MASK;
- unsigned int val;
-
- switch (format) {
- case SNDRV_PCM_FORMAT_S16_LE:
- val = ADAU1701_SEROCTL_WORD_LEN_16;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- val = ADAU1701_SEROCTL_WORD_LEN_20;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- val = ADAU1701_SEROCTL_WORD_LEN_24;
- break;
- default:
- return -EINVAL;
- }
-
- if (adau1701->dai_fmt == SND_SOC_DAIFMT_RIGHT_J) {
- switch (format) {
- case SNDRV_PCM_FORMAT_S16_LE:
- val |= ADAU1701_SEROCTL_MSB_DEALY16;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- val |= ADAU1701_SEROCTL_MSB_DEALY12;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- val |= ADAU1701_SEROCTL_MSB_DEALY8;
- break;
- }
- mask |= ADAU1701_SEROCTL_MSB_DEALY_MASK;
- }
-
- snd_soc_update_bits(codec, ADAU1701_SEROCTL, mask, val);
-
- return 0;
-}
-
-static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec,
- snd_pcm_format_t format)
-{
- struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
- unsigned int val;
-
- if (adau1701->dai_fmt != SND_SOC_DAIFMT_RIGHT_J)
- return 0;
-
- switch (format) {
- case SNDRV_PCM_FORMAT_S16_LE:
- val = ADAU1701_SERICTL_RIGHTJ_16;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- val = ADAU1701_SERICTL_RIGHTJ_20;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- val = ADAU1701_SERICTL_RIGHTJ_24;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, ADAU1701_SERICTL,
- ADAU1701_SERICTL_MODE_MASK, val);
-
- return 0;
-}
-
-static int adau1701_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- snd_pcm_format_t format;
- unsigned int val;
-
- switch (params_rate(params)) {
- case 192000:
- val = ADAU1701_DSPCTRL_SR_192;
- break;
- case 96000:
- val = ADAU1701_DSPCTRL_SR_96;
- break;
- case 48000:
- val = ADAU1701_DSPCTRL_SR_48;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, ADAU1701_DSPCTRL,
- ADAU1701_DSPCTRL_SR_MASK, val);
-
- format = params_format(params);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- return adau1701_set_playback_pcm_format(codec, format);
- else
- return adau1701_set_capture_pcm_format(codec, format);
-}
-
-static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
- unsigned int serictl = 0x00, seroctl = 0x00;
- bool invert_lrclk;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- /* master, 64-bits per sample, 1 frame per sample */
- seroctl |= ADAU1701_SEROCTL_MASTER | ADAU1701_SEROCTL_OBF16
- | ADAU1701_SEROCTL_OLF1024;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- invert_lrclk = false;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- invert_lrclk = true;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- invert_lrclk = false;
- serictl |= ADAU1701_SERICTL_INV_BCLK;
- seroctl |= ADAU1701_SEROCTL_INV_BCLK;
- break;
- case SND_SOC_DAIFMT_IB_IF:
- invert_lrclk = true;
- serictl |= ADAU1701_SERICTL_INV_BCLK;
- seroctl |= ADAU1701_SEROCTL_INV_BCLK;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- serictl |= ADAU1701_SERICTL_LEFTJ;
- seroctl |= ADAU1701_SEROCTL_MSB_DEALY0;
- invert_lrclk = !invert_lrclk;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- serictl |= ADAU1701_SERICTL_RIGHTJ_24;
- seroctl |= ADAU1701_SEROCTL_MSB_DEALY8;
- invert_lrclk = !invert_lrclk;
- break;
- default:
- return -EINVAL;
- }
-
- if (invert_lrclk) {
- seroctl |= ADAU1701_SEROCTL_INV_LRCLK;
- serictl |= ADAU1701_SERICTL_INV_LRCLK;
- }
-
- adau1701->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
-
- snd_soc_write(codec, ADAU1701_SERICTL, serictl);
- snd_soc_update_bits(codec, ADAU1701_SEROCTL,
- ~ADAU1701_SEROCTL_WORD_LEN_MASK, seroctl);
-
- return 0;
-}
-
-static int adau1701_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- unsigned int mask = ADAU1701_AUXNPOW_VBPD | ADAU1701_AUXNPOW_VRPD;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- /* Enable VREF and VREF buffer */
- snd_soc_update_bits(codec, ADAU1701_AUXNPOW, mask, 0x00);
- break;
- case SND_SOC_BIAS_OFF:
- /* Disable VREF and VREF buffer */
- snd_soc_update_bits(codec, ADAU1701_AUXNPOW, mask, mask);
- break;
- }
-
- codec->dapm.bias_level = level;
- return 0;
-}
-
-static int adau1701_digital_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- unsigned int mask = ADAU1701_DSPCTRL_DAM;
- unsigned int val;
-
- if (mute)
- val = 0;
- else
- val = mask;
-
- snd_soc_update_bits(codec, ADAU1701_DSPCTRL, mask, val);
-
- return 0;
-}
-
-static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
- int source, unsigned int freq, int dir)
-{
- unsigned int val;
-
- switch (clk_id) {
- case ADAU1701_CLK_SRC_OSC:
- val = 0x0;
- break;
- case ADAU1701_CLK_SRC_MCLK:
- val = ADAU1701_OSCIPOW_OPD;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, ADAU1701_OSCIPOW, ADAU1701_OSCIPOW_OPD, val);
-
- return 0;
-}
-
-#define ADAU1701_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | \
- SNDRV_PCM_RATE_192000)
-
-#define ADAU1701_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops adau1701_dai_ops = {
- .set_fmt = adau1701_set_dai_fmt,
- .hw_params = adau1701_hw_params,
- .digital_mute = adau1701_digital_mute,
-};
-
-static struct snd_soc_dai_driver adau1701_dai = {
- .name = "adau1701",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 8,
- .rates = ADAU1701_RATES,
- .formats = ADAU1701_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 8,
- .rates = ADAU1701_RATES,
- .formats = ADAU1701_FORMATS,
- },
- .ops = &adau1701_dai_ops,
- .symmetric_rates = 1,
-};
-
-static int adau1701_probe(struct snd_soc_codec *codec)
-{
- int ret;
-
- codec->control_data = to_i2c_client(codec->dev);
-
- ret = adau1701_load_firmware(codec);
- if (ret)
- dev_warn(codec->dev, "Failed to load firmware\n");
-
- snd_soc_write(codec, ADAU1701_DACSET, ADAU1701_DACSET_DACINIT);
- snd_soc_write(codec, ADAU1701_DSPCTRL, ADAU1701_DSPCTRL_CR);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver adau1701_codec_drv = {
- .probe = adau1701_probe,
- .set_bias_level = adau1701_set_bias_level,
- .idle_bias_off = true,
-
- .reg_cache_size = ADAU1701_NUM_REGS,
- .reg_word_size = sizeof(u16),
-
- .controls = adau1701_controls,
- .num_controls = ARRAY_SIZE(adau1701_controls),
- .dapm_widgets = adau1701_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(adau1701_dapm_widgets),
- .dapm_routes = adau1701_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes),
-
- .write = adau1701_write,
- .read = adau1701_read,
-
- .set_sysclk = adau1701_set_sysclk,
-};
-
-static __devinit int adau1701_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct adau1701 *adau1701;
- int ret;
-
- adau1701 = devm_kzalloc(&client->dev, sizeof(*adau1701), GFP_KERNEL);
- if (!adau1701)
- return -ENOMEM;
-
- i2c_set_clientdata(client, adau1701);
- ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv,
- &adau1701_dai, 1);
- return ret;
-}
-
-static __devexit int adau1701_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static const struct i2c_device_id adau1701_i2c_id[] = {
- { "adau1701", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, adau1701_i2c_id);
-
-static struct i2c_driver adau1701_i2c_driver = {
- .driver = {
- .name = "adau1701",
- .owner = THIS_MODULE,
- },
- .probe = adau1701_i2c_probe,
- .remove = __devexit_p(adau1701_i2c_remove),
- .id_table = adau1701_i2c_id,
-};
-
-static int __init adau1701_init(void)
-{
- return i2c_add_driver(&adau1701_i2c_driver);
-}
-module_init(adau1701_init);
-
-static void __exit adau1701_exit(void)
-{
- i2c_del_driver(&adau1701_i2c_driver);
-}
-module_exit(adau1701_exit);
-
-MODULE_DESCRIPTION("ASoC ADAU1701 SigmaDSP driver");
-MODULE_AUTHOR("Cliff Cai <cliff.cai@analog.com>");
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/adau1701.h b/ANDROID_3.4.5/sound/soc/codecs/adau1701.h
deleted file mode 100644
index 8d0949a2..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/adau1701.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * header file for ADAU1701 SigmaDSP processor
- *
- * Copyright 2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#ifndef _ADAU1701_H
-#define _ADAU1701_H
-
-enum adau1701_clk_src {
- ADAU1701_CLK_SRC_OSC,
- ADAU1701_CLK_SRC_MCLK,
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/adav80x.c b/ANDROID_3.4.5/sound/soc/codecs/adav80x.c
deleted file mode 100644
index ebd7b37b..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/adav80x.c
+++ /dev/null
@@ -1,952 +0,0 @@
-/*
- * ADAV80X Audio Codec driver supporting ADAV801, ADAV803
- *
- * Copyright 2011 Analog Devices Inc.
- * Author: Yi Li <yi.li@analog.com>
- * Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/i2c.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/tlv.h>
-#include <sound/soc.h>
-
-#include "adav80x.h"
-
-#define ADAV80X_PLAYBACK_CTRL 0x04
-#define ADAV80X_AUX_IN_CTRL 0x05
-#define ADAV80X_REC_CTRL 0x06
-#define ADAV80X_AUX_OUT_CTRL 0x07
-#define ADAV80X_DPATH_CTRL1 0x62
-#define ADAV80X_DPATH_CTRL2 0x63
-#define ADAV80X_DAC_CTRL1 0x64
-#define ADAV80X_DAC_CTRL2 0x65
-#define ADAV80X_DAC_CTRL3 0x66
-#define ADAV80X_DAC_L_VOL 0x68
-#define ADAV80X_DAC_R_VOL 0x69
-#define ADAV80X_PGA_L_VOL 0x6c
-#define ADAV80X_PGA_R_VOL 0x6d
-#define ADAV80X_ADC_CTRL1 0x6e
-#define ADAV80X_ADC_CTRL2 0x6f
-#define ADAV80X_ADC_L_VOL 0x70
-#define ADAV80X_ADC_R_VOL 0x71
-#define ADAV80X_PLL_CTRL1 0x74
-#define ADAV80X_PLL_CTRL2 0x75
-#define ADAV80X_ICLK_CTRL1 0x76
-#define ADAV80X_ICLK_CTRL2 0x77
-#define ADAV80X_PLL_CLK_SRC 0x78
-#define ADAV80X_PLL_OUTE 0x7a
-
-#define ADAV80X_PLL_CLK_SRC_PLL_XIN(pll) 0x00
-#define ADAV80X_PLL_CLK_SRC_PLL_MCLKI(pll) (0x40 << (pll))
-#define ADAV80X_PLL_CLK_SRC_PLL_MASK(pll) (0x40 << (pll))
-
-#define ADAV80X_ICLK_CTRL1_DAC_SRC(src) ((src) << 5)
-#define ADAV80X_ICLK_CTRL1_ADC_SRC(src) ((src) << 2)
-#define ADAV80X_ICLK_CTRL1_ICLK2_SRC(src) (src)
-#define ADAV80X_ICLK_CTRL2_ICLK1_SRC(src) ((src) << 3)
-
-#define ADAV80X_PLL_CTRL1_PLLDIV 0x10
-#define ADAV80X_PLL_CTRL1_PLLPD(pll) (0x04 << (pll))
-#define ADAV80X_PLL_CTRL1_XTLPD 0x02
-
-#define ADAV80X_PLL_CTRL2_FIELD(pll, x) ((x) << ((pll) * 4))
-
-#define ADAV80X_PLL_CTRL2_FS_48(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x00)
-#define ADAV80X_PLL_CTRL2_FS_32(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x08)
-#define ADAV80X_PLL_CTRL2_FS_44(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x0c)
-
-#define ADAV80X_PLL_CTRL2_SEL(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x02)
-#define ADAV80X_PLL_CTRL2_DOUB(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x01)
-#define ADAV80X_PLL_CTRL2_PLL_MASK(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x0f)
-
-#define ADAV80X_ADC_CTRL1_MODULATOR_MASK 0x80
-#define ADAV80X_ADC_CTRL1_MODULATOR_128FS 0x00
-#define ADAV80X_ADC_CTRL1_MODULATOR_64FS 0x80
-
-#define ADAV80X_DAC_CTRL1_PD 0x80
-
-#define ADAV80X_DAC_CTRL2_DIV1 0x00
-#define ADAV80X_DAC_CTRL2_DIV1_5 0x10
-#define ADAV80X_DAC_CTRL2_DIV2 0x20
-#define ADAV80X_DAC_CTRL2_DIV3 0x30
-#define ADAV80X_DAC_CTRL2_DIV_MASK 0x30
-
-#define ADAV80X_DAC_CTRL2_INTERPOL_256FS 0x00
-#define ADAV80X_DAC_CTRL2_INTERPOL_128FS 0x40
-#define ADAV80X_DAC_CTRL2_INTERPOL_64FS 0x80
-#define ADAV80X_DAC_CTRL2_INTERPOL_MASK 0xc0
-
-#define ADAV80X_DAC_CTRL2_DEEMPH_NONE 0x00
-#define ADAV80X_DAC_CTRL2_DEEMPH_44 0x01
-#define ADAV80X_DAC_CTRL2_DEEMPH_32 0x02
-#define ADAV80X_DAC_CTRL2_DEEMPH_48 0x03
-#define ADAV80X_DAC_CTRL2_DEEMPH_MASK 0x01
-
-#define ADAV80X_CAPTURE_MODE_MASTER 0x20
-#define ADAV80X_CAPTURE_WORD_LEN24 0x00
-#define ADAV80X_CAPTURE_WORD_LEN20 0x04
-#define ADAV80X_CAPTRUE_WORD_LEN18 0x08
-#define ADAV80X_CAPTURE_WORD_LEN16 0x0c
-#define ADAV80X_CAPTURE_WORD_LEN_MASK 0x0c
-
-#define ADAV80X_CAPTURE_MODE_LEFT_J 0x00
-#define ADAV80X_CAPTURE_MODE_I2S 0x01
-#define ADAV80X_CAPTURE_MODE_RIGHT_J 0x03
-#define ADAV80X_CAPTURE_MODE_MASK 0x03
-
-#define ADAV80X_PLAYBACK_MODE_MASTER 0x10
-#define ADAV80X_PLAYBACK_MODE_LEFT_J 0x00
-#define ADAV80X_PLAYBACK_MODE_I2S 0x01
-#define ADAV80X_PLAYBACK_MODE_RIGHT_J_24 0x04
-#define ADAV80X_PLAYBACK_MODE_RIGHT_J_20 0x05
-#define ADAV80X_PLAYBACK_MODE_RIGHT_J_18 0x06
-#define ADAV80X_PLAYBACK_MODE_RIGHT_J_16 0x07
-#define ADAV80X_PLAYBACK_MODE_MASK 0x07
-
-#define ADAV80X_PLL_OUTE_SYSCLKPD(x) BIT(2 - (x))
-
-static u8 adav80x_default_regs[] = {
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x01, 0x80, 0x26, 0x00, 0x00,
- 0x02, 0x40, 0x20, 0x00, 0x09, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0x92, 0xb1, 0x37,
- 0x48, 0xd2, 0xfb, 0xca, 0xd2, 0x15, 0xe8, 0x29, 0xb9, 0x6a, 0xda, 0x2b,
- 0xb7, 0xc0, 0x11, 0x65, 0x5c, 0xf6, 0xff, 0x8d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00,
- 0x00, 0xe8, 0x46, 0xe1, 0x5b, 0xd3, 0x43, 0x77, 0x93, 0xa7, 0x44, 0xee,
- 0x32, 0x12, 0xc0, 0x11, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x3f,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x52, 0x00,
-};
-
-struct adav80x {
- enum snd_soc_control_type control_type;
-
- enum adav80x_clk_src clk_src;
- unsigned int sysclk;
- enum adav80x_pll_src pll_src;
-
- unsigned int dai_fmt[2];
- unsigned int rate;
- bool deemph;
- bool sysclk_pd[3];
-};
-
-static const char *adav80x_mux_text[] = {
- "ADC",
- "Playback",
- "Aux Playback",
-};
-
-static const unsigned int adav80x_mux_values[] = {
- 0, 2, 3,
-};
-
-#define ADAV80X_MUX_ENUM_DECL(name, reg, shift) \
- SOC_VALUE_ENUM_DOUBLE_DECL(name, reg, shift, 7, \
- ARRAY_SIZE(adav80x_mux_text), adav80x_mux_text, \
- adav80x_mux_values)
-
-static ADAV80X_MUX_ENUM_DECL(adav80x_aux_capture_enum, ADAV80X_DPATH_CTRL1, 0);
-static ADAV80X_MUX_ENUM_DECL(adav80x_capture_enum, ADAV80X_DPATH_CTRL1, 3);
-static ADAV80X_MUX_ENUM_DECL(adav80x_dac_enum, ADAV80X_DPATH_CTRL2, 3);
-
-static const struct snd_kcontrol_new adav80x_aux_capture_mux_ctrl =
- SOC_DAPM_VALUE_ENUM("Route", adav80x_aux_capture_enum);
-static const struct snd_kcontrol_new adav80x_capture_mux_ctrl =
- SOC_DAPM_VALUE_ENUM("Route", adav80x_capture_enum);
-static const struct snd_kcontrol_new adav80x_dac_mux_ctrl =
- SOC_DAPM_VALUE_ENUM("Route", adav80x_dac_enum);
-
-#define ADAV80X_MUX(name, ctrl) \
- SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
-
-static const struct snd_soc_dapm_widget adav80x_dapm_widgets[] = {
- SND_SOC_DAPM_DAC("DAC", NULL, ADAV80X_DAC_CTRL1, 7, 1),
- SND_SOC_DAPM_ADC("ADC", NULL, ADAV80X_ADC_CTRL1, 5, 1),
-
- SND_SOC_DAPM_PGA("Right PGA", ADAV80X_ADC_CTRL1, 0, 1, NULL, 0),
- SND_SOC_DAPM_PGA("Left PGA", ADAV80X_ADC_CTRL1, 1, 1, NULL, 0),
-
- SND_SOC_DAPM_AIF_OUT("AIFOUT", "HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_AIF_IN("AIFIN", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
-
- SND_SOC_DAPM_AIF_OUT("AIFAUXOUT", "Aux Capture", 0, SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_AIF_IN("AIFAUXIN", "Aux Playback", 0, SND_SOC_NOPM, 0, 0),
-
- ADAV80X_MUX("Aux Capture Select", &adav80x_aux_capture_mux_ctrl),
- ADAV80X_MUX("Capture Select", &adav80x_capture_mux_ctrl),
- ADAV80X_MUX("DAC Select", &adav80x_dac_mux_ctrl),
-
- SND_SOC_DAPM_INPUT("VINR"),
- SND_SOC_DAPM_INPUT("VINL"),
- SND_SOC_DAPM_OUTPUT("VOUTR"),
- SND_SOC_DAPM_OUTPUT("VOUTL"),
-
- SND_SOC_DAPM_SUPPLY("SYSCLK", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("PLL1", ADAV80X_PLL_CTRL1, 2, 1, NULL, 0),
- SND_SOC_DAPM_SUPPLY("PLL2", ADAV80X_PLL_CTRL1, 3, 1, NULL, 0),
- SND_SOC_DAPM_SUPPLY("OSC", ADAV80X_PLL_CTRL1, 1, 1, NULL, 0),
-};
-
-static int adav80x_dapm_sysclk_check(struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink)
-{
- struct snd_soc_codec *codec = source->codec;
- struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
- const char *clk;
-
- switch (adav80x->clk_src) {
- case ADAV80X_CLK_PLL1:
- clk = "PLL1";
- break;
- case ADAV80X_CLK_PLL2:
- clk = "PLL2";
- break;
- case ADAV80X_CLK_XTAL:
- clk = "OSC";
- break;
- default:
- return 0;
- }
-
- return strcmp(source->name, clk) == 0;
-}
-
-static int adav80x_dapm_pll_check(struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink)
-{
- struct snd_soc_codec *codec = source->codec;
- struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
-
- return adav80x->pll_src == ADAV80X_PLL_SRC_XTAL;
-}
-
-
-static const struct snd_soc_dapm_route adav80x_dapm_routes[] = {
- { "DAC Select", "ADC", "ADC" },
- { "DAC Select", "Playback", "AIFIN" },
- { "DAC Select", "Aux Playback", "AIFAUXIN" },
- { "DAC", NULL, "DAC Select" },
-
- { "Capture Select", "ADC", "ADC" },
- { "Capture Select", "Playback", "AIFIN" },
- { "Capture Select", "Aux Playback", "AIFAUXIN" },
- { "AIFOUT", NULL, "Capture Select" },
-
- { "Aux Capture Select", "ADC", "ADC" },
- { "Aux Capture Select", "Playback", "AIFIN" },
- { "Aux Capture Select", "Aux Playback", "AIFAUXIN" },
- { "AIFAUXOUT", NULL, "Aux Capture Select" },
-
- { "VOUTR", NULL, "DAC" },
- { "VOUTL", NULL, "DAC" },
-
- { "Left PGA", NULL, "VINL" },
- { "Right PGA", NULL, "VINR" },
- { "ADC", NULL, "Left PGA" },
- { "ADC", NULL, "Right PGA" },
-
- { "SYSCLK", NULL, "PLL1", adav80x_dapm_sysclk_check },
- { "SYSCLK", NULL, "PLL2", adav80x_dapm_sysclk_check },
- { "SYSCLK", NULL, "OSC", adav80x_dapm_sysclk_check },
- { "PLL1", NULL, "OSC", adav80x_dapm_pll_check },
- { "PLL2", NULL, "OSC", adav80x_dapm_pll_check },
-
- { "ADC", NULL, "SYSCLK" },
- { "DAC", NULL, "SYSCLK" },
- { "AIFOUT", NULL, "SYSCLK" },
- { "AIFAUXOUT", NULL, "SYSCLK" },
- { "AIFIN", NULL, "SYSCLK" },
- { "AIFAUXIN", NULL, "SYSCLK" },
-};
-
-static int adav80x_set_deemph(struct snd_soc_codec *codec)
-{
- struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
- unsigned int val;
-
- if (adav80x->deemph) {
- switch (adav80x->rate) {
- case 32000:
- val = ADAV80X_DAC_CTRL2_DEEMPH_32;
- break;
- case 44100:
- val = ADAV80X_DAC_CTRL2_DEEMPH_44;
- break;
- case 48000:
- case 64000:
- case 88200:
- case 96000:
- val = ADAV80X_DAC_CTRL2_DEEMPH_48;
- break;
- default:
- val = ADAV80X_DAC_CTRL2_DEEMPH_NONE;
- break;
- }
- } else {
- val = ADAV80X_DAC_CTRL2_DEEMPH_NONE;
- }
-
- return snd_soc_update_bits(codec, ADAV80X_DAC_CTRL2,
- ADAV80X_DAC_CTRL2_DEEMPH_MASK, val);
-}
-
-static int adav80x_put_deemph(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
- unsigned int deemph = ucontrol->value.enumerated.item[0];
-
- if (deemph > 1)
- return -EINVAL;
-
- adav80x->deemph = deemph;
-
- return adav80x_set_deemph(codec);
-}
-
-static int adav80x_get_deemph(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.enumerated.item[0] = adav80x->deemph;
- return 0;
-};
-
-static const DECLARE_TLV_DB_SCALE(adav80x_inpga_tlv, 0, 50, 0);
-static const DECLARE_TLV_DB_MINMAX(adav80x_digital_tlv, -9563, 0);
-
-static const struct snd_kcontrol_new adav80x_controls[] = {
- SOC_DOUBLE_R_TLV("Master Playback Volume", ADAV80X_DAC_L_VOL,
- ADAV80X_DAC_R_VOL, 0, 0xff, 0, adav80x_digital_tlv),
- SOC_DOUBLE_R_TLV("Master Capture Volume", ADAV80X_ADC_L_VOL,
- ADAV80X_ADC_R_VOL, 0, 0xff, 0, adav80x_digital_tlv),
-
- SOC_DOUBLE_R_TLV("PGA Capture Volume", ADAV80X_PGA_L_VOL,
- ADAV80X_PGA_R_VOL, 0, 0x30, 0, adav80x_inpga_tlv),
-
- SOC_DOUBLE("Master Playback Switch", ADAV80X_DAC_CTRL1, 0, 1, 1, 0),
- SOC_DOUBLE("Master Capture Switch", ADAV80X_ADC_CTRL1, 2, 3, 1, 1),
-
- SOC_SINGLE("ADC High Pass Filter Switch", ADAV80X_ADC_CTRL1, 6, 1, 0),
-
- SOC_SINGLE_BOOL_EXT("Playback De-emphasis Switch", 0,
- adav80x_get_deemph, adav80x_put_deemph),
-};
-
-static unsigned int adav80x_port_ctrl_regs[2][2] = {
- { ADAV80X_REC_CTRL, ADAV80X_PLAYBACK_CTRL, },
- { ADAV80X_AUX_OUT_CTRL, ADAV80X_AUX_IN_CTRL },
-};
-
-static int adav80x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
- unsigned int capture = 0x00;
- unsigned int playback = 0x00;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- capture |= ADAV80X_CAPTURE_MODE_MASTER;
- playback |= ADAV80X_PLAYBACK_MODE_MASTER;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- capture |= ADAV80X_CAPTURE_MODE_I2S;
- playback |= ADAV80X_PLAYBACK_MODE_I2S;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- capture |= ADAV80X_CAPTURE_MODE_LEFT_J;
- playback |= ADAV80X_PLAYBACK_MODE_LEFT_J;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- capture |= ADAV80X_CAPTURE_MODE_RIGHT_J;
- playback |= ADAV80X_PLAYBACK_MODE_RIGHT_J_24;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, adav80x_port_ctrl_regs[dai->id][0],
- ADAV80X_CAPTURE_MODE_MASK | ADAV80X_CAPTURE_MODE_MASTER,
- capture);
- snd_soc_write(codec, adav80x_port_ctrl_regs[dai->id][1], playback);
-
- adav80x->dai_fmt[dai->id] = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
-
- return 0;
-}
-
-static int adav80x_set_adc_clock(struct snd_soc_codec *codec,
- unsigned int sample_rate)
-{
- unsigned int val;
-
- if (sample_rate <= 48000)
- val = ADAV80X_ADC_CTRL1_MODULATOR_128FS;
- else
- val = ADAV80X_ADC_CTRL1_MODULATOR_64FS;
-
- snd_soc_update_bits(codec, ADAV80X_ADC_CTRL1,
- ADAV80X_ADC_CTRL1_MODULATOR_MASK, val);
-
- return 0;
-}
-
-static int adav80x_set_dac_clock(struct snd_soc_codec *codec,
- unsigned int sample_rate)
-{
- unsigned int val;
-
- if (sample_rate <= 48000)
- val = ADAV80X_DAC_CTRL2_DIV1 | ADAV80X_DAC_CTRL2_INTERPOL_256FS;
- else
- val = ADAV80X_DAC_CTRL2_DIV2 | ADAV80X_DAC_CTRL2_INTERPOL_128FS;
-
- snd_soc_update_bits(codec, ADAV80X_DAC_CTRL2,
- ADAV80X_DAC_CTRL2_DIV_MASK | ADAV80X_DAC_CTRL2_INTERPOL_MASK,
- val);
-
- return 0;
-}
-
-static int adav80x_set_capture_pcm_format(struct snd_soc_codec *codec,
- struct snd_soc_dai *dai, snd_pcm_format_t format)
-{
- unsigned int val;
-
- switch (format) {
- case SNDRV_PCM_FORMAT_S16_LE:
- val = ADAV80X_CAPTURE_WORD_LEN16;
- break;
- case SNDRV_PCM_FORMAT_S18_3LE:
- val = ADAV80X_CAPTRUE_WORD_LEN18;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- val = ADAV80X_CAPTURE_WORD_LEN20;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- val = ADAV80X_CAPTURE_WORD_LEN24;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, adav80x_port_ctrl_regs[dai->id][0],
- ADAV80X_CAPTURE_WORD_LEN_MASK, val);
-
- return 0;
-}
-
-static int adav80x_set_playback_pcm_format(struct snd_soc_codec *codec,
- struct snd_soc_dai *dai, snd_pcm_format_t format)
-{
- struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
- unsigned int val;
-
- if (adav80x->dai_fmt[dai->id] != SND_SOC_DAIFMT_RIGHT_J)
- return 0;
-
- switch (format) {
- case SNDRV_PCM_FORMAT_S16_LE:
- val = ADAV80X_PLAYBACK_MODE_RIGHT_J_16;
- break;
- case SNDRV_PCM_FORMAT_S18_3LE:
- val = ADAV80X_PLAYBACK_MODE_RIGHT_J_18;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- val = ADAV80X_PLAYBACK_MODE_RIGHT_J_20;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- val = ADAV80X_PLAYBACK_MODE_RIGHT_J_24;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, adav80x_port_ctrl_regs[dai->id][1],
- ADAV80X_PLAYBACK_MODE_MASK, val);
-
- return 0;
-}
-
-static int adav80x_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
- unsigned int rate = params_rate(params);
-
- if (rate * 256 != adav80x->sysclk)
- return -EINVAL;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- adav80x_set_playback_pcm_format(codec, dai,
- params_format(params));
- adav80x_set_dac_clock(codec, rate);
- } else {
- adav80x_set_capture_pcm_format(codec, dai,
- params_format(params));
- adav80x_set_adc_clock(codec, rate);
- }
- adav80x->rate = rate;
- adav80x_set_deemph(codec);
-
- return 0;
-}
-
-static int adav80x_set_sysclk(struct snd_soc_codec *codec,
- int clk_id, int source,
- unsigned int freq, int dir)
-{
- struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
-
- if (dir == SND_SOC_CLOCK_IN) {
- switch (clk_id) {
- case ADAV80X_CLK_XIN:
- case ADAV80X_CLK_XTAL:
- case ADAV80X_CLK_MCLKI:
- case ADAV80X_CLK_PLL1:
- case ADAV80X_CLK_PLL2:
- break;
- default:
- return -EINVAL;
- }
-
- adav80x->sysclk = freq;
-
- if (adav80x->clk_src != clk_id) {
- unsigned int iclk_ctrl1, iclk_ctrl2;
-
- adav80x->clk_src = clk_id;
- if (clk_id == ADAV80X_CLK_XTAL)
- clk_id = ADAV80X_CLK_XIN;
-
- iclk_ctrl1 = ADAV80X_ICLK_CTRL1_DAC_SRC(clk_id) |
- ADAV80X_ICLK_CTRL1_ADC_SRC(clk_id) |
- ADAV80X_ICLK_CTRL1_ICLK2_SRC(clk_id);
- iclk_ctrl2 = ADAV80X_ICLK_CTRL2_ICLK1_SRC(clk_id);
-
- snd_soc_write(codec, ADAV80X_ICLK_CTRL1, iclk_ctrl1);
- snd_soc_write(codec, ADAV80X_ICLK_CTRL2, iclk_ctrl2);
-
- snd_soc_dapm_sync(&codec->dapm);
- }
- } else {
- unsigned int mask;
-
- switch (clk_id) {
- case ADAV80X_CLK_SYSCLK1:
- case ADAV80X_CLK_SYSCLK2:
- case ADAV80X_CLK_SYSCLK3:
- break;
- default:
- return -EINVAL;
- }
-
- clk_id -= ADAV80X_CLK_SYSCLK1;
- mask = ADAV80X_PLL_OUTE_SYSCLKPD(clk_id);
-
- if (freq == 0) {
- snd_soc_update_bits(codec, ADAV80X_PLL_OUTE, mask, mask);
- adav80x->sysclk_pd[clk_id] = true;
- } else {
- snd_soc_update_bits(codec, ADAV80X_PLL_OUTE, mask, 0);
- adav80x->sysclk_pd[clk_id] = false;
- }
-
- if (adav80x->sysclk_pd[0])
- snd_soc_dapm_disable_pin(&codec->dapm, "PLL1");
- else
- snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1");
-
- if (adav80x->sysclk_pd[1] || adav80x->sysclk_pd[2])
- snd_soc_dapm_disable_pin(&codec->dapm, "PLL2");
- else
- snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2");
-
- snd_soc_dapm_sync(&codec->dapm);
- }
-
- return 0;
-}
-
-static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id,
- int source, unsigned int freq_in, unsigned int freq_out)
-{
- struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
- unsigned int pll_ctrl1 = 0;
- unsigned int pll_ctrl2 = 0;
- unsigned int pll_src;
-
- switch (source) {
- case ADAV80X_PLL_SRC_XTAL:
- case ADAV80X_PLL_SRC_XIN:
- case ADAV80X_PLL_SRC_MCLKI:
- break;
- default:
- return -EINVAL;
- }
-
- if (!freq_out)
- return 0;
-
- switch (freq_in) {
- case 27000000:
- break;
- case 54000000:
- if (source == ADAV80X_PLL_SRC_XIN) {
- pll_ctrl1 |= ADAV80X_PLL_CTRL1_PLLDIV;
- break;
- }
- default:
- return -EINVAL;
- }
-
- if (freq_out > 12288000) {
- pll_ctrl2 |= ADAV80X_PLL_CTRL2_DOUB(pll_id);
- freq_out /= 2;
- }
-
- /* freq_out = sample_rate * 256 */
- switch (freq_out) {
- case 8192000:
- pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_32(pll_id);
- break;
- case 11289600:
- pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_44(pll_id);
- break;
- case 12288000:
- pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_48(pll_id);
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, ADAV80X_PLL_CTRL1, ADAV80X_PLL_CTRL1_PLLDIV,
- pll_ctrl1);
- snd_soc_update_bits(codec, ADAV80X_PLL_CTRL2,
- ADAV80X_PLL_CTRL2_PLL_MASK(pll_id), pll_ctrl2);
-
- if (source != adav80x->pll_src) {
- if (source == ADAV80X_PLL_SRC_MCLKI)
- pll_src = ADAV80X_PLL_CLK_SRC_PLL_MCLKI(pll_id);
- else
- pll_src = ADAV80X_PLL_CLK_SRC_PLL_XIN(pll_id);
-
- snd_soc_update_bits(codec, ADAV80X_PLL_CLK_SRC,
- ADAV80X_PLL_CLK_SRC_PLL_MASK(pll_id), pll_src);
-
- adav80x->pll_src = source;
-
- snd_soc_dapm_sync(&codec->dapm);
- }
-
- return 0;
-}
-
-static int adav80x_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- unsigned int mask = ADAV80X_DAC_CTRL1_PD;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- snd_soc_update_bits(codec, ADAV80X_DAC_CTRL1, mask, 0x00);
- break;
- case SND_SOC_BIAS_OFF:
- snd_soc_update_bits(codec, ADAV80X_DAC_CTRL1, mask, mask);
- break;
- }
-
- codec->dapm.bias_level = level;
- return 0;
-}
-
-/* Enforce the same sample rate on all audio interfaces */
-static int adav80x_dai_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
-
- if (!codec->active || !adav80x->rate)
- return 0;
-
- return snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_RATE, adav80x->rate, adav80x->rate);
-}
-
-static void adav80x_dai_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
-
- if (!codec->active)
- adav80x->rate = 0;
-}
-
-static const struct snd_soc_dai_ops adav80x_dai_ops = {
- .set_fmt = adav80x_set_dai_fmt,
- .hw_params = adav80x_hw_params,
- .startup = adav80x_dai_startup,
- .shutdown = adav80x_dai_shutdown,
-};
-
-#define ADAV80X_PLAYBACK_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 | \
- SNDRV_PCM_RATE_96000)
-
-#define ADAV80X_CAPTURE_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
-
-#define ADAV80X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE | \
- SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE)
-
-static struct snd_soc_dai_driver adav80x_dais[] = {
- {
- .name = "adav80x-hifi",
- .id = 0,
- .playback = {
- .stream_name = "HiFi Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = ADAV80X_PLAYBACK_RATES,
- .formats = ADAV80X_FORMATS,
- },
- .capture = {
- .stream_name = "HiFi Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = ADAV80X_CAPTURE_RATES,
- .formats = ADAV80X_FORMATS,
- },
- .ops = &adav80x_dai_ops,
- },
- {
- .name = "adav80x-aux",
- .id = 1,
- .playback = {
- .stream_name = "Aux Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = ADAV80X_PLAYBACK_RATES,
- .formats = ADAV80X_FORMATS,
- },
- .capture = {
- .stream_name = "Aux Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = ADAV80X_CAPTURE_RATES,
- .formats = ADAV80X_FORMATS,
- },
- .ops = &adav80x_dai_ops,
- },
-};
-
-static int adav80x_probe(struct snd_soc_codec *codec)
-{
- int ret;
- struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, adav80x->control_type);
- if (ret) {
- dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- /* Force PLLs on for SYSCLK output */
- snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1");
- snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2");
-
- /* Power down S/PDIF receiver, since it is currently not supported */
- snd_soc_write(codec, ADAV80X_PLL_OUTE, 0x20);
- /* Disable DAC zero flag */
- snd_soc_write(codec, ADAV80X_DAC_CTRL3, 0x6);
-
- return adav80x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-}
-
-static int adav80x_suspend(struct snd_soc_codec *codec)
-{
- return adav80x_set_bias_level(codec, SND_SOC_BIAS_OFF);
-}
-
-static int adav80x_resume(struct snd_soc_codec *codec)
-{
- adav80x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- codec->cache_sync = 1;
- snd_soc_cache_sync(codec);
-
- return 0;
-}
-
-static int adav80x_remove(struct snd_soc_codec *codec)
-{
- return adav80x_set_bias_level(codec, SND_SOC_BIAS_OFF);
-}
-
-static struct snd_soc_codec_driver adav80x_codec_driver = {
- .probe = adav80x_probe,
- .remove = adav80x_remove,
- .suspend = adav80x_suspend,
- .resume = adav80x_resume,
- .set_bias_level = adav80x_set_bias_level,
-
- .set_pll = adav80x_set_pll,
- .set_sysclk = adav80x_set_sysclk,
-
- .reg_word_size = sizeof(u8),
- .reg_cache_size = ARRAY_SIZE(adav80x_default_regs),
- .reg_cache_default = adav80x_default_regs,
-
- .controls = adav80x_controls,
- .num_controls = ARRAY_SIZE(adav80x_controls),
- .dapm_widgets = adav80x_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(adav80x_dapm_widgets),
- .dapm_routes = adav80x_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes),
-};
-
-static int __devinit adav80x_bus_probe(struct device *dev,
- enum snd_soc_control_type control_type)
-{
- struct adav80x *adav80x;
- int ret;
-
- adav80x = kzalloc(sizeof(*adav80x), GFP_KERNEL);
- if (!adav80x)
- return -ENOMEM;
-
- dev_set_drvdata(dev, adav80x);
- adav80x->control_type = control_type;
-
- ret = snd_soc_register_codec(dev, &adav80x_codec_driver,
- adav80x_dais, ARRAY_SIZE(adav80x_dais));
- if (ret)
- kfree(adav80x);
-
- return ret;
-}
-
-static int __devexit adav80x_bus_remove(struct device *dev)
-{
- snd_soc_unregister_codec(dev);
- kfree(dev_get_drvdata(dev));
- return 0;
-}
-
-#if defined(CONFIG_SPI_MASTER)
-static int __devinit adav80x_spi_probe(struct spi_device *spi)
-{
- return adav80x_bus_probe(&spi->dev, SND_SOC_SPI);
-}
-
-static int __devexit adav80x_spi_remove(struct spi_device *spi)
-{
- return adav80x_bus_remove(&spi->dev);
-}
-
-static struct spi_driver adav80x_spi_driver = {
- .driver = {
- .name = "adav801",
- .owner = THIS_MODULE,
- },
- .probe = adav80x_spi_probe,
- .remove = __devexit_p(adav80x_spi_remove),
-};
-#endif
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static const struct i2c_device_id adav80x_id[] = {
- { "adav803", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, adav80x_id);
-
-static int __devinit adav80x_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- return adav80x_bus_probe(&client->dev, SND_SOC_I2C);
-}
-
-static int __devexit adav80x_i2c_remove(struct i2c_client *client)
-{
- return adav80x_bus_remove(&client->dev);
-}
-
-static struct i2c_driver adav80x_i2c_driver = {
- .driver = {
- .name = "adav803",
- .owner = THIS_MODULE,
- },
- .probe = adav80x_i2c_probe,
- .remove = __devexit_p(adav80x_i2c_remove),
- .id_table = adav80x_id,
-};
-#endif
-
-static int __init adav80x_init(void)
-{
- int ret = 0;
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&adav80x_i2c_driver);
- if (ret)
- return ret;
-#endif
-
-#if defined(CONFIG_SPI_MASTER)
- ret = spi_register_driver(&adav80x_spi_driver);
-#endif
-
- return ret;
-}
-module_init(adav80x_init);
-
-static void __exit adav80x_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&adav80x_i2c_driver);
-#endif
-#if defined(CONFIG_SPI_MASTER)
- spi_unregister_driver(&adav80x_spi_driver);
-#endif
-}
-module_exit(adav80x_exit);
-
-MODULE_DESCRIPTION("ASoC ADAV80x driver");
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_AUTHOR("Yi Li <yi.li@analog.com>>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/adav80x.h b/ANDROID_3.4.5/sound/soc/codecs/adav80x.h
deleted file mode 100644
index adb0fc76..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/adav80x.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * header file for ADAV80X parts
- *
- * Copyright 2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#ifndef _ADAV80X_H
-#define _ADAV80X_H
-
-enum adav80x_pll_src {
- ADAV80X_PLL_SRC_XIN,
- ADAV80X_PLL_SRC_XTAL,
- ADAV80X_PLL_SRC_MCLKI,
-};
-
-enum adav80x_pll {
- ADAV80X_PLL1 = 0,
- ADAV80X_PLL2 = 1,
-};
-
-enum adav80x_clk_src {
- ADAV80X_CLK_XIN = 0,
- ADAV80X_CLK_MCLKI = 1,
- ADAV80X_CLK_PLL1 = 2,
- ADAV80X_CLK_PLL2 = 3,
- ADAV80X_CLK_XTAL = 6,
-
- ADAV80X_CLK_SYSCLK1 = 6,
- ADAV80X_CLK_SYSCLK2 = 7,
- ADAV80X_CLK_SYSCLK3 = 8,
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/ads117x.c b/ANDROID_3.4.5/sound/soc/codecs/ads117x.c
deleted file mode 100644
index 8103b938..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/ads117x.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * ads117x.c -- Driver for ads1174/8 ADC chips
- *
- * Copyright 2009 ShotSpotter Inc.
- * Author: Graeme Gregory <gg@slimlogic.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#define ADS117X_RATES (SNDRV_PCM_RATE_8000_48000)
-#define ADS117X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
-
-static struct snd_soc_dai_driver ads117x_dai = {
-/* ADC */
- .name = "ads117x-hifi",
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 32,
- .rates = ADS117X_RATES,
- .formats = ADS117X_FORMATS,},
-};
-
-static struct snd_soc_codec_driver soc_codec_dev_ads117x;
-
-static __devinit int ads117x_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev,
- &soc_codec_dev_ads117x, &ads117x_dai, 1);
-}
-
-static int __devexit ads117x_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver ads117x_codec_driver = {
- .driver = {
- .name = "ads117x-codec",
- .owner = THIS_MODULE,
- },
-
- .probe = ads117x_probe,
- .remove = __devexit_p(ads117x_remove),
-};
-
-module_platform_driver(ads117x_codec_driver);
-
-MODULE_DESCRIPTION("ASoC ads117x driver");
-MODULE_AUTHOR("Graeme Gregory");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/ak4104.c b/ANDROID_3.4.5/sound/soc/codecs/ak4104.c
deleted file mode 100644
index ceb96ecf..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/ak4104.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * AK4104 ALSA SoC (ASoC) driver
- *
- * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <linux/spi/spi.h>
-#include <sound/asoundef.h>
-
-/* AK4104 registers addresses */
-#define AK4104_REG_CONTROL1 0x00
-#define AK4104_REG_RESERVED 0x01
-#define AK4104_REG_CONTROL2 0x02
-#define AK4104_REG_TX 0x03
-#define AK4104_REG_CHN_STATUS(x) ((x) + 0x04)
-#define AK4104_NUM_REGS 10
-
-#define AK4104_REG_MASK 0x1f
-#define AK4104_READ 0xc0
-#define AK4104_WRITE 0xe0
-#define AK4104_RESERVED_VAL 0x5b
-
-/* Bit masks for AK4104 registers */
-#define AK4104_CONTROL1_RSTN (1 << 0)
-#define AK4104_CONTROL1_PW (1 << 1)
-#define AK4104_CONTROL1_DIF0 (1 << 2)
-#define AK4104_CONTROL1_DIF1 (1 << 3)
-
-#define AK4104_CONTROL2_SEL0 (1 << 0)
-#define AK4104_CONTROL2_SEL1 (1 << 1)
-#define AK4104_CONTROL2_MODE (1 << 2)
-
-#define AK4104_TX_TXE (1 << 0)
-#define AK4104_TX_V (1 << 1)
-
-#define DRV_NAME "ak4104-codec"
-
-struct ak4104_private {
- struct regmap *regmap;
-};
-
-static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int format)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- int val = 0;
- int ret;
-
- /* set DAI format */
- switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- val |= AK4104_CONTROL1_DIF0;
- break;
- case SND_SOC_DAIFMT_I2S:
- val |= AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1;
- break;
- default:
- dev_err(codec->dev, "invalid dai format\n");
- return -EINVAL;
- }
-
- /* This device can only be slave */
- if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
- return -EINVAL;
-
- ret = snd_soc_update_bits(codec, AK4104_REG_CONTROL1,
- AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1,
- val);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int ak4104_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- int val = 0;
-
- /* set the IEC958 bits: consumer mode, no copyright bit */
- val |= IEC958_AES0_CON_NOT_COPYRIGHT;
- snd_soc_write(codec, AK4104_REG_CHN_STATUS(0), val);
-
- val = 0;
-
- switch (params_rate(params)) {
- case 44100:
- val |= IEC958_AES3_CON_FS_44100;
- break;
- case 48000:
- val |= IEC958_AES3_CON_FS_48000;
- break;
- case 32000:
- val |= IEC958_AES3_CON_FS_32000;
- break;
- default:
- dev_err(codec->dev, "unsupported sampling rate\n");
- return -EINVAL;
- }
-
- return snd_soc_write(codec, AK4104_REG_CHN_STATUS(3), val);
-}
-
-static const struct snd_soc_dai_ops ak4101_dai_ops = {
- .hw_params = ak4104_hw_params,
- .set_fmt = ak4104_set_dai_fmt,
-};
-
-static struct snd_soc_dai_driver ak4104_dai = {
- .name = "ak4104-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_192000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_3LE |
- SNDRV_PCM_FMTBIT_S24_LE
- },
- .ops = &ak4101_dai_ops,
-};
-
-static int ak4104_probe(struct snd_soc_codec *codec)
-{
- struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- codec->control_data = ak4104->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret != 0)
- return ret;
-
- /* set power-up and non-reset bits */
- ret = snd_soc_update_bits(codec, AK4104_REG_CONTROL1,
- AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN,
- AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN);
- if (ret < 0)
- return ret;
-
- /* enable transmitter */
- ret = snd_soc_update_bits(codec, AK4104_REG_TX,
- AK4104_TX_TXE, AK4104_TX_TXE);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int ak4104_remove(struct snd_soc_codec *codec)
-{
- snd_soc_update_bits(codec, AK4104_REG_CONTROL1,
- AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_device_ak4104 = {
- .probe = ak4104_probe,
- .remove = ak4104_remove,
-};
-
-static const struct regmap_config ak4104_regmap = {
- .reg_bits = 8,
- .val_bits = 8,
-
- .max_register = AK4104_NUM_REGS - 1,
- .read_flag_mask = AK4104_READ,
- .write_flag_mask = AK4104_WRITE,
-
- .cache_type = REGCACHE_RBTREE,
-};
-
-static int ak4104_spi_probe(struct spi_device *spi)
-{
- struct ak4104_private *ak4104;
- unsigned int val;
- int ret;
-
- spi->bits_per_word = 8;
- spi->mode = SPI_MODE_0;
- ret = spi_setup(spi);
- if (ret < 0)
- return ret;
-
- ak4104 = devm_kzalloc(&spi->dev, sizeof(struct ak4104_private),
- GFP_KERNEL);
- if (ak4104 == NULL)
- return -ENOMEM;
-
- ak4104->regmap = regmap_init_spi(spi, &ak4104_regmap);
- if (IS_ERR(ak4104->regmap)) {
- ret = PTR_ERR(ak4104->regmap);
- return ret;
- }
-
- /* read the 'reserved' register - according to the datasheet, it
- * should contain 0x5b. Not a good way to verify the presence of
- * the device, but there is no hardware ID register. */
- ret = regmap_read(ak4104->regmap, AK4104_REG_RESERVED, &val);
- if (ret != 0)
- goto err;
- if (val != AK4104_RESERVED_VAL) {
- ret = -ENODEV;
- goto err;
- }
-
- spi_set_drvdata(spi, ak4104);
-
- ret = snd_soc_register_codec(&spi->dev,
- &soc_codec_device_ak4104, &ak4104_dai, 1);
- if (ret != 0)
- goto err;
-
- return 0;
-
-err:
- regmap_exit(ak4104->regmap);
- return ret;
-}
-
-static int __devexit ak4104_spi_remove(struct spi_device *spi)
-{
- struct ak4104_private *ak4101 = spi_get_drvdata(spi);
- regmap_exit(ak4101->regmap);
- snd_soc_unregister_codec(&spi->dev);
- return 0;
-}
-
-static struct spi_driver ak4104_spi_driver = {
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- },
- .probe = ak4104_spi_probe,
- .remove = __devexit_p(ak4104_spi_remove),
-};
-
-module_spi_driver(ak4104_spi_driver);
-
-MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
-MODULE_DESCRIPTION("Asahi Kasei AK4104 ALSA SoC driver");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/soc/codecs/ak4535.c b/ANDROID_3.4.5/sound/soc/codecs/ak4535.c
deleted file mode 100644
index 838ae8b2..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/ak4535.c
+++ /dev/null
@@ -1,497 +0,0 @@
-/*
- * ak4535.c -- AK4535 ALSA Soc Audio driver
- *
- * Copyright 2005 Openedhand Ltd.
- *
- * Author: Richard Purdie <richard@openedhand.com>
- *
- * Based on wm8753.c by Liam Girdwood
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/regmap.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-
-#include "ak4535.h"
-
-/* codec private data */
-struct ak4535_priv {
- struct regmap *regmap;
- unsigned int sysclk;
-};
-
-/*
- * ak4535 register cache
- */
-static const struct reg_default ak4535_reg_defaults[] = {
- { 0, 0x00 },
- { 1, 0x80 },
- { 2, 0x00 },
- { 3, 0x03 },
- { 4, 0x02 },
- { 5, 0x00 },
- { 6, 0x11 },
- { 7, 0x01 },
- { 8, 0x00 },
- { 9, 0x40 },
- { 10, 0x36 },
- { 11, 0x10 },
- { 12, 0x00 },
- { 13, 0x00 },
- { 14, 0x57 },
-};
-
-static bool ak4535_volatile(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case AK4535_STATUS:
- return true;
- default:
- return false;
- }
-}
-
-static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"};
-static const char *ak4535_mono_out[] = {"(L + R)/2", "Hi-Z"};
-static const char *ak4535_hp_out[] = {"Stereo", "Mono"};
-static const char *ak4535_deemp[] = {"44.1kHz", "Off", "48kHz", "32kHz"};
-static const char *ak4535_mic_select[] = {"Internal", "External"};
-
-static const struct soc_enum ak4535_enum[] = {
- SOC_ENUM_SINGLE(AK4535_SIG1, 7, 2, ak4535_mono_gain),
- SOC_ENUM_SINGLE(AK4535_SIG1, 6, 2, ak4535_mono_out),
- SOC_ENUM_SINGLE(AK4535_MODE2, 2, 2, ak4535_hp_out),
- SOC_ENUM_SINGLE(AK4535_DAC, 0, 4, ak4535_deemp),
- SOC_ENUM_SINGLE(AK4535_MIC, 1, 2, ak4535_mic_select),
-};
-
-static const struct snd_kcontrol_new ak4535_snd_controls[] = {
- SOC_SINGLE("ALC2 Switch", AK4535_SIG1, 1, 1, 0),
- SOC_ENUM("Mono 1 Output", ak4535_enum[1]),
- SOC_ENUM("Mono 1 Gain", ak4535_enum[0]),
- SOC_ENUM("Headphone Output", ak4535_enum[2]),
- SOC_ENUM("Playback Deemphasis", ak4535_enum[3]),
- SOC_SINGLE("Bass Volume", AK4535_DAC, 2, 3, 0),
- SOC_SINGLE("Mic Boost (+20dB) Switch", AK4535_MIC, 0, 1, 0),
- SOC_ENUM("Mic Select", ak4535_enum[4]),
- SOC_SINGLE("ALC Operation Time", AK4535_TIMER, 0, 3, 0),
- SOC_SINGLE("ALC Recovery Time", AK4535_TIMER, 2, 3, 0),
- SOC_SINGLE("ALC ZC Time", AK4535_TIMER, 4, 3, 0),
- SOC_SINGLE("ALC 1 Switch", AK4535_ALC1, 5, 1, 0),
- SOC_SINGLE("ALC 2 Switch", AK4535_ALC1, 6, 1, 0),
- SOC_SINGLE("ALC Volume", AK4535_ALC2, 0, 127, 0),
- SOC_SINGLE("Capture Volume", AK4535_PGA, 0, 127, 0),
- SOC_SINGLE("Left Playback Volume", AK4535_LATT, 0, 127, 1),
- SOC_SINGLE("Right Playback Volume", AK4535_RATT, 0, 127, 1),
- SOC_SINGLE("AUX Bypass Volume", AK4535_VOL, 0, 15, 0),
- SOC_SINGLE("Mic Sidetone Volume", AK4535_VOL, 4, 7, 0),
-};
-
-/* Mono 1 Mixer */
-static const struct snd_kcontrol_new ak4535_mono1_mixer_controls[] = {
- SOC_DAPM_SINGLE("Mic Sidetone Switch", AK4535_SIG1, 4, 1, 0),
- SOC_DAPM_SINGLE("Mono Playback Switch", AK4535_SIG1, 5, 1, 0),
-};
-
-/* Stereo Mixer */
-static const struct snd_kcontrol_new ak4535_stereo_mixer_controls[] = {
- SOC_DAPM_SINGLE("Mic Sidetone Switch", AK4535_SIG2, 4, 1, 0),
- SOC_DAPM_SINGLE("Playback Switch", AK4535_SIG2, 7, 1, 0),
- SOC_DAPM_SINGLE("Aux Bypass Switch", AK4535_SIG2, 5, 1, 0),
-};
-
-/* Input Mixer */
-static const struct snd_kcontrol_new ak4535_input_mixer_controls[] = {
- SOC_DAPM_SINGLE("Mic Capture Switch", AK4535_MIC, 2, 1, 0),
- SOC_DAPM_SINGLE("Aux Capture Switch", AK4535_MIC, 5, 1, 0),
-};
-
-/* Input mux */
-static const struct snd_kcontrol_new ak4535_input_mux_control =
- SOC_DAPM_ENUM("Input Select", ak4535_enum[4]);
-
-/* HP L switch */
-static const struct snd_kcontrol_new ak4535_hpl_control =
- SOC_DAPM_SINGLE("Switch", AK4535_SIG2, 1, 1, 1);
-
-/* HP R switch */
-static const struct snd_kcontrol_new ak4535_hpr_control =
- SOC_DAPM_SINGLE("Switch", AK4535_SIG2, 0, 1, 1);
-
-/* mono 2 switch */
-static const struct snd_kcontrol_new ak4535_mono2_control =
- SOC_DAPM_SINGLE("Switch", AK4535_SIG1, 0, 1, 0);
-
-/* Line out switch */
-static const struct snd_kcontrol_new ak4535_line_control =
- SOC_DAPM_SINGLE("Switch", AK4535_SIG2, 6, 1, 0);
-
-/* ak4535 dapm widgets */
-static const struct snd_soc_dapm_widget ak4535_dapm_widgets[] = {
- SND_SOC_DAPM_MIXER("Stereo Mixer", SND_SOC_NOPM, 0, 0,
- &ak4535_stereo_mixer_controls[0],
- ARRAY_SIZE(ak4535_stereo_mixer_controls)),
- SND_SOC_DAPM_MIXER("Mono1 Mixer", SND_SOC_NOPM, 0, 0,
- &ak4535_mono1_mixer_controls[0],
- ARRAY_SIZE(ak4535_mono1_mixer_controls)),
- SND_SOC_DAPM_MIXER("Input Mixer", SND_SOC_NOPM, 0, 0,
- &ak4535_input_mixer_controls[0],
- ARRAY_SIZE(ak4535_input_mixer_controls)),
- SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
- &ak4535_input_mux_control),
- SND_SOC_DAPM_DAC("DAC", "Playback", AK4535_PM2, 0, 0),
- SND_SOC_DAPM_SWITCH("Mono 2 Enable", SND_SOC_NOPM, 0, 0,
- &ak4535_mono2_control),
- /* speaker powersave bit */
- SND_SOC_DAPM_PGA("Speaker Enable", AK4535_MODE2, 0, 0, NULL, 0),
- SND_SOC_DAPM_SWITCH("Line Out Enable", SND_SOC_NOPM, 0, 0,
- &ak4535_line_control),
- SND_SOC_DAPM_SWITCH("Left HP Enable", SND_SOC_NOPM, 0, 0,
- &ak4535_hpl_control),
- SND_SOC_DAPM_SWITCH("Right HP Enable", SND_SOC_NOPM, 0, 0,
- &ak4535_hpr_control),
- SND_SOC_DAPM_OUTPUT("LOUT"),
- SND_SOC_DAPM_OUTPUT("HPL"),
- SND_SOC_DAPM_OUTPUT("ROUT"),
- SND_SOC_DAPM_OUTPUT("HPR"),
- SND_SOC_DAPM_OUTPUT("SPP"),
- SND_SOC_DAPM_OUTPUT("SPN"),
- SND_SOC_DAPM_OUTPUT("MOUT1"),
- SND_SOC_DAPM_OUTPUT("MOUT2"),
- SND_SOC_DAPM_OUTPUT("MICOUT"),
- SND_SOC_DAPM_ADC("ADC", "Capture", AK4535_PM1, 0, 0),
- SND_SOC_DAPM_PGA("Spk Amp", AK4535_PM2, 3, 0, NULL, 0),
- SND_SOC_DAPM_PGA("HP R Amp", AK4535_PM2, 1, 0, NULL, 0),
- SND_SOC_DAPM_PGA("HP L Amp", AK4535_PM2, 2, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Mic", AK4535_PM1, 1, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Line Out", AK4535_PM1, 4, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Mono Out", AK4535_PM1, 3, 0, NULL, 0),
- SND_SOC_DAPM_PGA("AUX In", AK4535_PM1, 2, 0, NULL, 0),
-
- SND_SOC_DAPM_MICBIAS("Mic Int Bias", AK4535_MIC, 3, 0),
- SND_SOC_DAPM_MICBIAS("Mic Ext Bias", AK4535_MIC, 4, 0),
- SND_SOC_DAPM_INPUT("MICIN"),
- SND_SOC_DAPM_INPUT("MICEXT"),
- SND_SOC_DAPM_INPUT("AUX"),
- SND_SOC_DAPM_INPUT("MIN"),
- SND_SOC_DAPM_INPUT("AIN"),
-};
-
-static const struct snd_soc_dapm_route ak4535_audio_map[] = {
- /*stereo mixer */
- {"Stereo Mixer", "Playback Switch", "DAC"},
- {"Stereo Mixer", "Mic Sidetone Switch", "Mic"},
- {"Stereo Mixer", "Aux Bypass Switch", "AUX In"},
-
- /* mono1 mixer */
- {"Mono1 Mixer", "Mic Sidetone Switch", "Mic"},
- {"Mono1 Mixer", "Mono Playback Switch", "DAC"},
-
- /* Mic */
- {"Mic", NULL, "AIN"},
- {"Input Mux", "Internal", "Mic Int Bias"},
- {"Input Mux", "External", "Mic Ext Bias"},
- {"Mic Int Bias", NULL, "MICIN"},
- {"Mic Ext Bias", NULL, "MICEXT"},
- {"MICOUT", NULL, "Input Mux"},
-
- /* line out */
- {"LOUT", NULL, "Line Out Enable"},
- {"ROUT", NULL, "Line Out Enable"},
- {"Line Out Enable", "Switch", "Line Out"},
- {"Line Out", NULL, "Stereo Mixer"},
-
- /* mono1 out */
- {"MOUT1", NULL, "Mono Out"},
- {"Mono Out", NULL, "Mono1 Mixer"},
-
- /* left HP */
- {"HPL", NULL, "Left HP Enable"},
- {"Left HP Enable", "Switch", "HP L Amp"},
- {"HP L Amp", NULL, "Stereo Mixer"},
-
- /* right HP */
- {"HPR", NULL, "Right HP Enable"},
- {"Right HP Enable", "Switch", "HP R Amp"},
- {"HP R Amp", NULL, "Stereo Mixer"},
-
- /* speaker */
- {"SPP", NULL, "Speaker Enable"},
- {"SPN", NULL, "Speaker Enable"},
- {"Speaker Enable", "Switch", "Spk Amp"},
- {"Spk Amp", NULL, "MIN"},
-
- /* mono 2 */
- {"MOUT2", NULL, "Mono 2 Enable"},
- {"Mono 2 Enable", "Switch", "Stereo Mixer"},
-
- /* Aux In */
- {"Aux In", NULL, "AUX"},
-
- /* ADC */
- {"ADC", NULL, "Input Mixer"},
- {"Input Mixer", "Mic Capture Switch", "Mic"},
- {"Input Mixer", "Aux Capture Switch", "Aux In"},
-};
-
-static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
-
- ak4535->sysclk = freq;
- return 0;
-}
-
-static int ak4535_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
- u8 mode2 = snd_soc_read(codec, AK4535_MODE2) & ~(0x3 << 5);
- int rate = params_rate(params), fs = 256;
-
- if (rate)
- fs = ak4535->sysclk / rate;
-
- /* set fs */
- switch (fs) {
- case 1024:
- mode2 |= (0x2 << 5);
- break;
- case 512:
- mode2 |= (0x1 << 5);
- break;
- case 256:
- break;
- }
-
- /* set rate */
- snd_soc_write(codec, AK4535_MODE2, mode2);
- return 0;
-}
-
-static int ak4535_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u8 mode1 = 0;
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- mode1 = 0x0002;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- mode1 = 0x0001;
- break;
- default:
- return -EINVAL;
- }
-
- /* use 32 fs for BCLK to save power */
- mode1 |= 0x4;
-
- snd_soc_write(codec, AK4535_MODE1, mode1);
- return 0;
-}
-
-static int ak4535_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 mute_reg = snd_soc_read(codec, AK4535_DAC);
- if (!mute)
- snd_soc_write(codec, AK4535_DAC, mute_reg & ~0x20);
- else
- snd_soc_write(codec, AK4535_DAC, mute_reg | 0x20);
- return 0;
-}
-
-static int ak4535_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- switch (level) {
- case SND_SOC_BIAS_ON:
- snd_soc_update_bits(codec, AK4535_DAC, 0x20, 0);
- break;
- case SND_SOC_BIAS_PREPARE:
- snd_soc_update_bits(codec, AK4535_DAC, 0x20, 0x20);
- break;
- case SND_SOC_BIAS_STANDBY:
- snd_soc_update_bits(codec, AK4535_PM1, 0x80, 0x80);
- snd_soc_update_bits(codec, AK4535_PM2, 0x80, 0);
- break;
- case SND_SOC_BIAS_OFF:
- snd_soc_update_bits(codec, AK4535_PM1, 0x80, 0);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define AK4535_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
-
-static const struct snd_soc_dai_ops ak4535_dai_ops = {
- .hw_params = ak4535_hw_params,
- .set_fmt = ak4535_set_dai_fmt,
- .digital_mute = ak4535_mute,
- .set_sysclk = ak4535_set_dai_sysclk,
-};
-
-static struct snd_soc_dai_driver ak4535_dai = {
- .name = "ak4535-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = AK4535_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = AK4535_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .ops = &ak4535_dai_ops,
-};
-
-static int ak4535_suspend(struct snd_soc_codec *codec)
-{
- ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int ak4535_resume(struct snd_soc_codec *codec)
-{
- snd_soc_cache_sync(codec);
- ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-
-static int ak4535_probe(struct snd_soc_codec *codec)
-{
- struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- codec->control_data = ak4535->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
- /* power on device */
- ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- snd_soc_add_codec_controls(codec, ak4535_snd_controls,
- ARRAY_SIZE(ak4535_snd_controls));
- return 0;
-}
-
-/* power down chip */
-static int ak4535_remove(struct snd_soc_codec *codec)
-{
- ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static const struct regmap_config ak4535_regmap = {
- .reg_bits = 8,
- .val_bits = 8,
-
- .max_register = AK4535_STATUS,
- .volatile_reg = ak4535_volatile,
-
- .cache_type = REGCACHE_RBTREE,
- .reg_defaults = ak4535_reg_defaults,
- .num_reg_defaults = ARRAY_SIZE(ak4535_reg_defaults),
-};
-
-static struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
- .probe = ak4535_probe,
- .remove = ak4535_remove,
- .suspend = ak4535_suspend,
- .resume = ak4535_resume,
- .set_bias_level = ak4535_set_bias_level,
- .dapm_widgets = ak4535_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets),
- .dapm_routes = ak4535_audio_map,
- .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map),
-};
-
-static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct ak4535_priv *ak4535;
- int ret;
-
- ak4535 = devm_kzalloc(&i2c->dev, sizeof(struct ak4535_priv),
- GFP_KERNEL);
- if (ak4535 == NULL)
- return -ENOMEM;
-
- ak4535->regmap = regmap_init_i2c(i2c, &ak4535_regmap);
- if (IS_ERR(ak4535->regmap)) {
- ret = PTR_ERR(ak4535->regmap);
- dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
- return ret;
- }
-
- i2c_set_clientdata(i2c, ak4535);
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_ak4535, &ak4535_dai, 1);
- if (ret != 0)
- regmap_exit(ak4535->regmap);
-
- return ret;
-}
-
-static __devexit int ak4535_i2c_remove(struct i2c_client *client)
-{
- struct ak4535_priv *ak4535 = i2c_get_clientdata(client);
-
- snd_soc_unregister_codec(&client->dev);
- regmap_exit(ak4535->regmap);
- return 0;
-}
-
-static const struct i2c_device_id ak4535_i2c_id[] = {
- { "ak4535", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ak4535_i2c_id);
-
-static struct i2c_driver ak4535_i2c_driver = {
- .driver = {
- .name = "ak4535",
- .owner = THIS_MODULE,
- },
- .probe = ak4535_i2c_probe,
- .remove = __devexit_p(ak4535_i2c_remove),
- .id_table = ak4535_i2c_id,
-};
-
-module_i2c_driver(ak4535_i2c_driver);
-
-MODULE_DESCRIPTION("Soc AK4535 driver");
-MODULE_AUTHOR("Richard Purdie");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/ak4535.h b/ANDROID_3.4.5/sound/soc/codecs/ak4535.h
deleted file mode 100644
index 402de1d2..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/ak4535.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * ak4535.h -- AK4535 Soc Audio driver
- *
- * Copyright 2005 Openedhand Ltd.
- *
- * Author: Richard Purdie <richard@openedhand.com>
- *
- * Based on wm8753.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _AK4535_H
-#define _AK4535_H
-
-/* AK4535 register space */
-
-#define AK4535_PM1 0x0
-#define AK4535_PM2 0x1
-#define AK4535_SIG1 0x2
-#define AK4535_SIG2 0x3
-#define AK4535_MODE1 0x4
-#define AK4535_MODE2 0x5
-#define AK4535_DAC 0x6
-#define AK4535_MIC 0x7
-#define AK4535_TIMER 0x8
-#define AK4535_ALC1 0x9
-#define AK4535_ALC2 0xa
-#define AK4535_PGA 0xb
-#define AK4535_LATT 0xc
-#define AK4535_RATT 0xd
-#define AK4535_VOL 0xe
-#define AK4535_STATUS 0xf
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/ak4641.c b/ANDROID_3.4.5/sound/soc/codecs/ak4641.c
deleted file mode 100644
index c4d165a4..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/ak4641.c
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
- * ak4641.c -- AK4641 ALSA Soc Audio driver
- *
- * Copyright (C) 2008 Harald Welte <laforge@gnufiish.org>
- * Copyright (C) 2011 Dmitry Artamonow <mad_soft@inbox.ru>
- *
- * Based on ak4535.c by Richard Purdie
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <sound/ak4641.h>
-
-#include "ak4641.h"
-
-/* codec private data */
-struct ak4641_priv {
- unsigned int sysclk;
- int deemph;
- int playback_fs;
-};
-
-/*
- * ak4641 register cache
- */
-static const u8 ak4641_reg[AK4641_CACHEREGNUM] = {
- 0x00, 0x80, 0x00, 0x80,
- 0x02, 0x00, 0x11, 0x05,
- 0x00, 0x00, 0x36, 0x10,
- 0x00, 0x00, 0x57, 0x00,
- 0x88, 0x88, 0x08, 0x08
-};
-
-static const int deemph_settings[] = {44100, 0, 48000, 32000};
-
-static int ak4641_set_deemph(struct snd_soc_codec *codec)
-{
- struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
- int i, best = 0;
-
- for (i = 0 ; i < ARRAY_SIZE(deemph_settings); i++) {
- /* if deemphasis is on, select the nearest available rate */
- if (ak4641->deemph && deemph_settings[i] != 0 &&
- abs(deemph_settings[i] - ak4641->playback_fs) <
- abs(deemph_settings[best] - ak4641->playback_fs))
- best = i;
-
- if (!ak4641->deemph && deemph_settings[i] == 0)
- best = i;
- }
-
- dev_dbg(codec->dev, "Set deemphasis %d\n", best);
-
- return snd_soc_update_bits(codec, AK4641_DAC, 0x3, best);
-}
-
-static int ak4641_put_deemph(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
- int deemph = ucontrol->value.enumerated.item[0];
-
- if (deemph > 1)
- return -EINVAL;
-
- ak4641->deemph = deemph;
-
- return ak4641_set_deemph(codec);
-}
-
-static int ak4641_get_deemph(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.enumerated.item[0] = ak4641->deemph;
- return 0;
-};
-
-static const char *ak4641_mono_out[] = {"(L + R)/2", "Hi-Z"};
-static const char *ak4641_hp_out[] = {"Stereo", "Mono"};
-static const char *ak4641_mic_select[] = {"Internal", "External"};
-static const char *ak4641_mic_or_dac[] = {"Microphone", "Voice DAC"};
-
-
-static const DECLARE_TLV_DB_SCALE(mono_gain_tlv, -1700, 2300, 0);
-static const DECLARE_TLV_DB_SCALE(mic_boost_tlv, 0, 2000, 0);
-static const DECLARE_TLV_DB_SCALE(eq_tlv, -1050, 150, 0);
-static const DECLARE_TLV_DB_SCALE(master_tlv, -12750, 50, 0);
-static const DECLARE_TLV_DB_SCALE(mic_stereo_sidetone_tlv, -2700, 300, 0);
-static const DECLARE_TLV_DB_SCALE(mic_mono_sidetone_tlv, -400, 400, 0);
-static const DECLARE_TLV_DB_SCALE(capture_tlv, -800, 50, 0);
-static const DECLARE_TLV_DB_SCALE(alc_tlv, -800, 50, 0);
-static const DECLARE_TLV_DB_SCALE(aux_in_tlv, -2100, 300, 0);
-
-
-static const struct soc_enum ak4641_mono_out_enum =
- SOC_ENUM_SINGLE(AK4641_SIG1, 6, 2, ak4641_mono_out);
-static const struct soc_enum ak4641_hp_out_enum =
- SOC_ENUM_SINGLE(AK4641_MODE2, 2, 2, ak4641_hp_out);
-static const struct soc_enum ak4641_mic_select_enum =
- SOC_ENUM_SINGLE(AK4641_MIC, 1, 2, ak4641_mic_select);
-static const struct soc_enum ak4641_mic_or_dac_enum =
- SOC_ENUM_SINGLE(AK4641_BTIF, 4, 2, ak4641_mic_or_dac);
-
-static const struct snd_kcontrol_new ak4641_snd_controls[] = {
- SOC_ENUM("Mono 1 Output", ak4641_mono_out_enum),
- SOC_SINGLE_TLV("Mono 1 Gain Volume", AK4641_SIG1, 7, 1, 1,
- mono_gain_tlv),
- SOC_ENUM("Headphone Output", ak4641_hp_out_enum),
- SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0,
- ak4641_get_deemph, ak4641_put_deemph),
-
- SOC_SINGLE_TLV("Mic Boost Volume", AK4641_MIC, 0, 1, 0, mic_boost_tlv),
-
- SOC_SINGLE("ALC Operation Time", AK4641_TIMER, 0, 3, 0),
- SOC_SINGLE("ALC Recovery Time", AK4641_TIMER, 2, 3, 0),
- SOC_SINGLE("ALC ZC Time", AK4641_TIMER, 4, 3, 0),
-
- SOC_SINGLE("ALC 1 Switch", AK4641_ALC1, 5, 1, 0),
-
- SOC_SINGLE_TLV("ALC Volume", AK4641_ALC2, 0, 71, 0, alc_tlv),
- SOC_SINGLE("Left Out Enable Switch", AK4641_SIG2, 1, 1, 0),
- SOC_SINGLE("Right Out Enable Switch", AK4641_SIG2, 0, 1, 0),
-
- SOC_SINGLE_TLV("Capture Volume", AK4641_PGA, 0, 71, 0, capture_tlv),
-
- SOC_DOUBLE_R_TLV("Master Playback Volume", AK4641_LATT,
- AK4641_RATT, 0, 255, 1, master_tlv),
-
- SOC_SINGLE_TLV("AUX In Volume", AK4641_VOL, 0, 15, 0, aux_in_tlv),
-
- SOC_SINGLE("Equalizer Switch", AK4641_DAC, 2, 1, 0),
- SOC_SINGLE_TLV("EQ1 100 Hz Volume", AK4641_EQLO, 0, 15, 1, eq_tlv),
- SOC_SINGLE_TLV("EQ2 250 Hz Volume", AK4641_EQLO, 4, 15, 1, eq_tlv),
- SOC_SINGLE_TLV("EQ3 1 kHz Volume", AK4641_EQMID, 0, 15, 1, eq_tlv),
- SOC_SINGLE_TLV("EQ4 3.5 kHz Volume", AK4641_EQMID, 4, 15, 1, eq_tlv),
- SOC_SINGLE_TLV("EQ5 10 kHz Volume", AK4641_EQHI, 0, 15, 1, eq_tlv),
-};
-
-/* Mono 1 Mixer */
-static const struct snd_kcontrol_new ak4641_mono1_mixer_controls[] = {
- SOC_DAPM_SINGLE_TLV("Mic Mono Sidetone Volume", AK4641_VOL, 7, 1, 0,
- mic_mono_sidetone_tlv),
- SOC_DAPM_SINGLE("Mic Mono Sidetone Switch", AK4641_SIG1, 4, 1, 0),
- SOC_DAPM_SINGLE("Mono Playback Switch", AK4641_SIG1, 5, 1, 0),
-};
-
-/* Stereo Mixer */
-static const struct snd_kcontrol_new ak4641_stereo_mixer_controls[] = {
- SOC_DAPM_SINGLE_TLV("Mic Sidetone Volume", AK4641_VOL, 4, 7, 0,
- mic_stereo_sidetone_tlv),
- SOC_DAPM_SINGLE("Mic Sidetone Switch", AK4641_SIG2, 4, 1, 0),
- SOC_DAPM_SINGLE("Playback Switch", AK4641_SIG2, 7, 1, 0),
- SOC_DAPM_SINGLE("Aux Bypass Switch", AK4641_SIG2, 5, 1, 0),
-};
-
-/* Input Mixer */
-static const struct snd_kcontrol_new ak4641_input_mixer_controls[] = {
- SOC_DAPM_SINGLE("Mic Capture Switch", AK4641_MIC, 2, 1, 0),
- SOC_DAPM_SINGLE("Aux Capture Switch", AK4641_MIC, 5, 1, 0),
-};
-
-/* Mic mux */
-static const struct snd_kcontrol_new ak4641_mic_mux_control =
- SOC_DAPM_ENUM("Mic Select", ak4641_mic_select_enum);
-
-/* Input mux */
-static const struct snd_kcontrol_new ak4641_input_mux_control =
- SOC_DAPM_ENUM("Input Select", ak4641_mic_or_dac_enum);
-
-/* mono 2 switch */
-static const struct snd_kcontrol_new ak4641_mono2_control =
- SOC_DAPM_SINGLE("Switch", AK4641_SIG1, 0, 1, 0);
-
-/* ak4641 dapm widgets */
-static const struct snd_soc_dapm_widget ak4641_dapm_widgets[] = {
- SND_SOC_DAPM_MIXER("Stereo Mixer", SND_SOC_NOPM, 0, 0,
- &ak4641_stereo_mixer_controls[0],
- ARRAY_SIZE(ak4641_stereo_mixer_controls)),
- SND_SOC_DAPM_MIXER("Mono1 Mixer", SND_SOC_NOPM, 0, 0,
- &ak4641_mono1_mixer_controls[0],
- ARRAY_SIZE(ak4641_mono1_mixer_controls)),
- SND_SOC_DAPM_MIXER("Input Mixer", SND_SOC_NOPM, 0, 0,
- &ak4641_input_mixer_controls[0],
- ARRAY_SIZE(ak4641_input_mixer_controls)),
- SND_SOC_DAPM_MUX("Mic Mux", SND_SOC_NOPM, 0, 0,
- &ak4641_mic_mux_control),
- SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
- &ak4641_input_mux_control),
- SND_SOC_DAPM_SWITCH("Mono 2 Enable", SND_SOC_NOPM, 0, 0,
- &ak4641_mono2_control),
-
- SND_SOC_DAPM_OUTPUT("LOUT"),
- SND_SOC_DAPM_OUTPUT("ROUT"),
- SND_SOC_DAPM_OUTPUT("MOUT1"),
- SND_SOC_DAPM_OUTPUT("MOUT2"),
- SND_SOC_DAPM_OUTPUT("MICOUT"),
-
- SND_SOC_DAPM_ADC("ADC", "HiFi Capture", AK4641_PM1, 0, 0),
- SND_SOC_DAPM_PGA("Mic", AK4641_PM1, 1, 0, NULL, 0),
- SND_SOC_DAPM_PGA("AUX In", AK4641_PM1, 2, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Mono Out", AK4641_PM1, 3, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Line Out", AK4641_PM1, 4, 0, NULL, 0),
-
- SND_SOC_DAPM_DAC("DAC", "HiFi Playback", AK4641_PM2, 0, 0),
- SND_SOC_DAPM_PGA("Mono Out 2", AK4641_PM2, 3, 0, NULL, 0),
-
- SND_SOC_DAPM_ADC("Voice ADC", "Voice Capture", AK4641_BTIF, 0, 0),
- SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", AK4641_BTIF, 1, 0),
-
- SND_SOC_DAPM_MICBIAS("Mic Int Bias", AK4641_MIC, 3, 0),
- SND_SOC_DAPM_MICBIAS("Mic Ext Bias", AK4641_MIC, 4, 0),
-
- SND_SOC_DAPM_INPUT("MICIN"),
- SND_SOC_DAPM_INPUT("MICEXT"),
- SND_SOC_DAPM_INPUT("AUX"),
- SND_SOC_DAPM_INPUT("AIN"),
-};
-
-static const struct snd_soc_dapm_route ak4641_audio_map[] = {
- /* Stereo Mixer */
- {"Stereo Mixer", "Playback Switch", "DAC"},
- {"Stereo Mixer", "Mic Sidetone Switch", "Input Mux"},
- {"Stereo Mixer", "Aux Bypass Switch", "AUX In"},
-
- /* Mono 1 Mixer */
- {"Mono1 Mixer", "Mic Mono Sidetone Switch", "Input Mux"},
- {"Mono1 Mixer", "Mono Playback Switch", "DAC"},
-
- /* Mic */
- {"Mic", NULL, "AIN"},
- {"Mic Mux", "Internal", "Mic Int Bias"},
- {"Mic Mux", "External", "Mic Ext Bias"},
- {"Mic Int Bias", NULL, "MICIN"},
- {"Mic Ext Bias", NULL, "MICEXT"},
- {"MICOUT", NULL, "Mic Mux"},
-
- /* Input Mux */
- {"Input Mux", "Microphone", "Mic"},
- {"Input Mux", "Voice DAC", "Voice DAC"},
-
- /* Line Out */
- {"LOUT", NULL, "Line Out"},
- {"ROUT", NULL, "Line Out"},
- {"Line Out", NULL, "Stereo Mixer"},
-
- /* Mono 1 Out */
- {"MOUT1", NULL, "Mono Out"},
- {"Mono Out", NULL, "Mono1 Mixer"},
-
- /* Mono 2 Out */
- {"MOUT2", NULL, "Mono 2 Enable"},
- {"Mono 2 Enable", "Switch", "Mono Out 2"},
- {"Mono Out 2", NULL, "Stereo Mixer"},
-
- {"Voice ADC", NULL, "Mono 2 Enable"},
-
- /* Aux In */
- {"AUX In", NULL, "AUX"},
-
- /* ADC */
- {"ADC", NULL, "Input Mixer"},
- {"Input Mixer", "Mic Capture Switch", "Mic"},
- {"Input Mixer", "Aux Capture Switch", "AUX In"},
-};
-
-static int ak4641_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
-
- ak4641->sysclk = freq;
- return 0;
-}
-
-static int ak4641_i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
- int rate = params_rate(params), fs = 256;
- u8 mode2;
-
- if (rate)
- fs = ak4641->sysclk / rate;
- else
- return -EINVAL;
-
- /* set fs */
- switch (fs) {
- case 1024:
- mode2 = (0x2 << 5);
- break;
- case 512:
- mode2 = (0x1 << 5);
- break;
- case 256:
- mode2 = (0x0 << 5);
- break;
- default:
- dev_err(codec->dev, "Error: unsupported fs=%d\n", fs);
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, AK4641_MODE2, (0x3 << 5), mode2);
-
- /* Update de-emphasis filter for the new rate */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- ak4641->playback_fs = rate;
- ak4641_set_deemph(codec);
- };
-
- return 0;
-}
-
-static int ak4641_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u8 btif;
- int ret;
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- btif = (0x3 << 5);
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- btif = (0x2 << 5);
- break;
- case SND_SOC_DAIFMT_DSP_A: /* MSB after FRM */
- btif = (0x0 << 5);
- break;
- case SND_SOC_DAIFMT_DSP_B: /* MSB during FRM */
- btif = (0x1 << 5);
- break;
- default:
- return -EINVAL;
- }
-
- ret = snd_soc_update_bits(codec, AK4641_BTIF, (0x3 << 5), btif);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int ak4641_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u8 mode1 = 0;
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- mode1 = 0x02;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- mode1 = 0x01;
- break;
- default:
- return -EINVAL;
- }
-
- return snd_soc_write(codec, AK4641_MODE1, mode1);
-}
-
-static int ak4641_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
-
- return snd_soc_update_bits(codec, AK4641_DAC, 0x20, mute ? 0x20 : 0);
-}
-
-static int ak4641_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct ak4641_platform_data *pdata = codec->dev->platform_data;
- int ret;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- /* unmute */
- snd_soc_update_bits(codec, AK4641_DAC, 0x20, 0);
- break;
- case SND_SOC_BIAS_PREPARE:
- /* mute */
- snd_soc_update_bits(codec, AK4641_DAC, 0x20, 0x20);
- break;
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- if (pdata && gpio_is_valid(pdata->gpio_power))
- gpio_set_value(pdata->gpio_power, 1);
- mdelay(1);
- if (pdata && gpio_is_valid(pdata->gpio_npdn))
- gpio_set_value(pdata->gpio_npdn, 1);
- mdelay(1);
-
- ret = snd_soc_cache_sync(codec);
- if (ret) {
- dev_err(codec->dev,
- "Failed to sync cache: %d\n", ret);
- return ret;
- }
- }
- snd_soc_update_bits(codec, AK4641_PM1, 0x80, 0x80);
- snd_soc_update_bits(codec, AK4641_PM2, 0x80, 0);
- break;
- case SND_SOC_BIAS_OFF:
- snd_soc_update_bits(codec, AK4641_PM1, 0x80, 0);
- if (pdata && gpio_is_valid(pdata->gpio_npdn))
- gpio_set_value(pdata->gpio_npdn, 0);
- if (pdata && gpio_is_valid(pdata->gpio_power))
- gpio_set_value(pdata->gpio_power, 0);
- codec->cache_sync = 1;
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define AK4641_RATES (SNDRV_PCM_RATE_8000_48000)
-#define AK4641_RATES_BT (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_16000)
-#define AK4641_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
-
-static const struct snd_soc_dai_ops ak4641_i2s_dai_ops = {
- .hw_params = ak4641_i2s_hw_params,
- .set_fmt = ak4641_i2s_set_dai_fmt,
- .digital_mute = ak4641_mute,
- .set_sysclk = ak4641_set_dai_sysclk,
-};
-
-static const struct snd_soc_dai_ops ak4641_pcm_dai_ops = {
- .hw_params = NULL, /* rates are controlled by BT chip */
- .set_fmt = ak4641_pcm_set_dai_fmt,
- .digital_mute = ak4641_mute,
- .set_sysclk = ak4641_set_dai_sysclk,
-};
-
-static struct snd_soc_dai_driver ak4641_dai[] = {
-{
- .name = "ak4641-hifi",
- .id = 1,
- .playback = {
- .stream_name = "HiFi Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = AK4641_RATES,
- .formats = AK4641_FORMATS,
- },
- .capture = {
- .stream_name = "HiFi Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = AK4641_RATES,
- .formats = AK4641_FORMATS,
- },
- .ops = &ak4641_i2s_dai_ops,
- .symmetric_rates = 1,
-},
-{
- .name = "ak4641-voice",
- .id = 1,
- .playback = {
- .stream_name = "Voice Playback",
- .channels_min = 1,
- .channels_max = 1,
- .rates = AK4641_RATES_BT,
- .formats = AK4641_FORMATS,
- },
- .capture = {
- .stream_name = "Voice Capture",
- .channels_min = 1,
- .channels_max = 1,
- .rates = AK4641_RATES_BT,
- .formats = AK4641_FORMATS,
- },
- .ops = &ak4641_pcm_dai_ops,
- .symmetric_rates = 1,
-},
-};
-
-static int ak4641_suspend(struct snd_soc_codec *codec)
-{
- ak4641_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int ak4641_resume(struct snd_soc_codec *codec)
-{
- ak4641_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-
-static int ak4641_probe(struct snd_soc_codec *codec)
-{
- struct ak4641_platform_data *pdata = codec->dev->platform_data;
- int ret;
-
-
- if (pdata) {
- if (gpio_is_valid(pdata->gpio_power)) {
- ret = gpio_request_one(pdata->gpio_power,
- GPIOF_OUT_INIT_LOW, "ak4641 power");
- if (ret)
- goto err_out;
- }
- if (gpio_is_valid(pdata->gpio_npdn)) {
- ret = gpio_request_one(pdata->gpio_npdn,
- GPIOF_OUT_INIT_LOW, "ak4641 npdn");
- if (ret)
- goto err_gpio;
-
- udelay(1); /* > 150 ns */
- gpio_set_value(pdata->gpio_npdn, 1);
- }
- }
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err_register;
- }
-
- /* power on device */
- ak4641_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-
-err_register:
- if (pdata) {
- if (gpio_is_valid(pdata->gpio_power))
- gpio_set_value(pdata->gpio_power, 0);
- if (gpio_is_valid(pdata->gpio_npdn))
- gpio_free(pdata->gpio_npdn);
- }
-err_gpio:
- if (pdata && gpio_is_valid(pdata->gpio_power))
- gpio_free(pdata->gpio_power);
-err_out:
- return ret;
-}
-
-static int ak4641_remove(struct snd_soc_codec *codec)
-{
- struct ak4641_platform_data *pdata = codec->dev->platform_data;
-
- ak4641_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- if (pdata) {
- if (gpio_is_valid(pdata->gpio_power)) {
- gpio_set_value(pdata->gpio_power, 0);
- gpio_free(pdata->gpio_power);
- }
- if (gpio_is_valid(pdata->gpio_npdn))
- gpio_free(pdata->gpio_npdn);
- }
- return 0;
-}
-
-
-static struct snd_soc_codec_driver soc_codec_dev_ak4641 = {
- .probe = ak4641_probe,
- .remove = ak4641_remove,
- .suspend = ak4641_suspend,
- .resume = ak4641_resume,
- .controls = ak4641_snd_controls,
- .num_controls = ARRAY_SIZE(ak4641_snd_controls),
- .dapm_widgets = ak4641_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(ak4641_dapm_widgets),
- .dapm_routes = ak4641_audio_map,
- .num_dapm_routes = ARRAY_SIZE(ak4641_audio_map),
- .set_bias_level = ak4641_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(ak4641_reg),
- .reg_word_size = sizeof(u8),
- .reg_cache_default = ak4641_reg,
- .reg_cache_step = 1,
-};
-
-
-static int __devinit ak4641_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct ak4641_priv *ak4641;
- int ret;
-
- ak4641 = devm_kzalloc(&i2c->dev, sizeof(struct ak4641_priv),
- GFP_KERNEL);
- if (!ak4641)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, ak4641);
-
- ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_ak4641,
- ak4641_dai, ARRAY_SIZE(ak4641_dai));
- return ret;
-}
-
-static int __devexit ak4641_i2c_remove(struct i2c_client *i2c)
-{
- snd_soc_unregister_codec(&i2c->dev);
- return 0;
-}
-
-static const struct i2c_device_id ak4641_i2c_id[] = {
- { "ak4641", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ak4641_i2c_id);
-
-static struct i2c_driver ak4641_i2c_driver = {
- .driver = {
- .name = "ak4641",
- .owner = THIS_MODULE,
- },
- .probe = ak4641_i2c_probe,
- .remove = __devexit_p(ak4641_i2c_remove),
- .id_table = ak4641_i2c_id,
-};
-
-static int __init ak4641_modinit(void)
-{
- int ret;
-
- ret = i2c_add_driver(&ak4641_i2c_driver);
- if (ret != 0)
- pr_err("Failed to register AK4641 I2C driver: %d\n", ret);
-
- return ret;
-}
-module_init(ak4641_modinit);
-
-static void __exit ak4641_exit(void)
-{
- i2c_del_driver(&ak4641_i2c_driver);
-}
-module_exit(ak4641_exit);
-
-MODULE_DESCRIPTION("SoC AK4641 driver");
-MODULE_AUTHOR("Harald Welte <laforge@gnufiish.org>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/ak4641.h b/ANDROID_3.4.5/sound/soc/codecs/ak4641.h
deleted file mode 100644
index 4a263248..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/ak4641.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * ak4641.h -- AK4641 SoC Audio driver
- *
- * Copyright 2008 Harald Welte <laforge@gnufiish.org>
- *
- * Based on ak4535.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _AK4641_H
-#define _AK4641_H
-
-/* AK4641 register space */
-
-#define AK4641_PM1 0x00
-#define AK4641_PM2 0x01
-#define AK4641_SIG1 0x02
-#define AK4641_SIG2 0x03
-#define AK4641_MODE1 0x04
-#define AK4641_MODE2 0x05
-#define AK4641_DAC 0x06
-#define AK4641_MIC 0x07
-#define AK4641_TIMER 0x08
-#define AK4641_ALC1 0x09
-#define AK4641_ALC2 0x0a
-#define AK4641_PGA 0x0b
-#define AK4641_LATT 0x0c
-#define AK4641_RATT 0x0d
-#define AK4641_VOL 0x0e
-#define AK4641_STATUS 0x0f
-#define AK4641_EQLO 0x10
-#define AK4641_EQMID 0x11
-#define AK4641_EQHI 0x12
-#define AK4641_BTIF 0x13
-
-#define AK4641_CACHEREGNUM 0x14
-
-
-
-#define AK4641_DAI_HIFI 0
-#define AK4641_DAI_VOICE 1
-
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/ak4642.c b/ANDROID_3.4.5/sound/soc/codecs/ak4642.c
deleted file mode 100644
index b3e24f28..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/ak4642.c
+++ /dev/null
@@ -1,590 +0,0 @@
-/*
- * ak4642.c -- AK4642/AK4643 ALSA Soc Audio driver
- *
- * Copyright (C) 2009 Renesas Solutions Corp.
- * Kuninori Morimoto <morimoto.kuninori@renesas.com>
- *
- * Based on wm8731.c by Richard Purdie
- * Based on ak4535.c by Richard Purdie
- * Based on wm8753.c by Liam Girdwood
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-/* ** CAUTION **
- *
- * This is very simple driver.
- * It can use headphone output / stereo input only
- *
- * AK4642 is tested.
- * AK4643 is tested.
- * AK4648 is tested.
- */
-
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#define PW_MGMT1 0x00
-#define PW_MGMT2 0x01
-#define SG_SL1 0x02
-#define SG_SL2 0x03
-#define MD_CTL1 0x04
-#define MD_CTL2 0x05
-#define TIMER 0x06
-#define ALC_CTL1 0x07
-#define ALC_CTL2 0x08
-#define L_IVC 0x09
-#define L_DVC 0x0a
-#define ALC_CTL3 0x0b
-#define R_IVC 0x0c
-#define R_DVC 0x0d
-#define MD_CTL3 0x0e
-#define MD_CTL4 0x0f
-#define PW_MGMT3 0x10
-#define DF_S 0x11
-#define FIL3_0 0x12
-#define FIL3_1 0x13
-#define FIL3_2 0x14
-#define FIL3_3 0x15
-#define EQ_0 0x16
-#define EQ_1 0x17
-#define EQ_2 0x18
-#define EQ_3 0x19
-#define EQ_4 0x1a
-#define EQ_5 0x1b
-#define FIL1_0 0x1c
-#define FIL1_1 0x1d
-#define FIL1_2 0x1e
-#define FIL1_3 0x1f
-#define PW_MGMT4 0x20
-#define MD_CTL5 0x21
-#define LO_MS 0x22
-#define HP_MS 0x23
-#define SPK_MS 0x24
-
-/* PW_MGMT1*/
-#define PMVCM (1 << 6) /* VCOM Power Management */
-#define PMMIN (1 << 5) /* MIN Input Power Management */
-#define PMDAC (1 << 2) /* DAC Power Management */
-#define PMADL (1 << 0) /* MIC Amp Lch and ADC Lch Power Management */
-
-/* PW_MGMT2 */
-#define HPMTN (1 << 6)
-#define PMHPL (1 << 5)
-#define PMHPR (1 << 4)
-#define MS (1 << 3) /* master/slave select */
-#define MCKO (1 << 1)
-#define PMPLL (1 << 0)
-
-#define PMHP_MASK (PMHPL | PMHPR)
-#define PMHP PMHP_MASK
-
-/* PW_MGMT3 */
-#define PMADR (1 << 0) /* MIC L / ADC R Power Management */
-
-/* SG_SL1 */
-#define MINS (1 << 6) /* Switch from MIN to Speaker */
-#define DACL (1 << 4) /* Switch from DAC to Stereo or Receiver */
-#define PMMP (1 << 2) /* MPWR pin Power Management */
-#define MGAIN0 (1 << 0) /* MIC amp gain*/
-
-/* TIMER */
-#define ZTM(param) ((param & 0x3) << 4) /* ALC Zoro Crossing TimeOut */
-#define WTM(param) (((param & 0x4) << 4) | ((param & 0x3) << 2))
-
-/* ALC_CTL1 */
-#define ALC (1 << 5) /* ALC Enable */
-#define LMTH0 (1 << 0) /* ALC Limiter / Recovery Level */
-
-/* MD_CTL1 */
-#define PLL3 (1 << 7)
-#define PLL2 (1 << 6)
-#define PLL1 (1 << 5)
-#define PLL0 (1 << 4)
-#define PLL_MASK (PLL3 | PLL2 | PLL1 | PLL0)
-
-#define BCKO_MASK (1 << 3)
-#define BCKO_64 BCKO_MASK
-
-#define DIF_MASK (3 << 0)
-#define DSP (0 << 0)
-#define RIGHT_J (1 << 0)
-#define LEFT_J (2 << 0)
-#define I2S (3 << 0)
-
-/* MD_CTL2 */
-#define FS0 (1 << 0)
-#define FS1 (1 << 1)
-#define FS2 (1 << 2)
-#define FS3 (1 << 5)
-#define FS_MASK (FS0 | FS1 | FS2 | FS3)
-
-/* MD_CTL3 */
-#define BST1 (1 << 3)
-
-/* MD_CTL4 */
-#define DACH (1 << 0)
-
-/*
- * Playback Volume (table 39)
- *
- * max : 0x00 : +12.0 dB
- * ( 0.5 dB step )
- * min : 0xFE : -115.0 dB
- * mute: 0xFF
- */
-static const DECLARE_TLV_DB_SCALE(out_tlv, -11550, 50, 1);
-
-static const struct snd_kcontrol_new ak4642_snd_controls[] = {
-
- SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC,
- 0, 0xFF, 1, out_tlv),
-};
-
-static const struct snd_kcontrol_new ak4642_headphone_control =
- SOC_DAPM_SINGLE("Switch", PW_MGMT2, 6, 1, 0);
-
-static const struct snd_kcontrol_new ak4642_lout_mixer_controls[] = {
- SOC_DAPM_SINGLE("DACL", SG_SL1, 4, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = {
-
- /* Outputs */
- SND_SOC_DAPM_OUTPUT("HPOUTL"),
- SND_SOC_DAPM_OUTPUT("HPOUTR"),
- SND_SOC_DAPM_OUTPUT("LINEOUT"),
-
- SND_SOC_DAPM_PGA("HPL Out", PW_MGMT2, 5, 0, NULL, 0),
- SND_SOC_DAPM_PGA("HPR Out", PW_MGMT2, 4, 0, NULL, 0),
- SND_SOC_DAPM_SWITCH("Headphone Enable", SND_SOC_NOPM, 0, 0,
- &ak4642_headphone_control),
-
- SND_SOC_DAPM_PGA("DACH", MD_CTL4, 0, 0, NULL, 0),
-
- SND_SOC_DAPM_MIXER("LINEOUT Mixer", PW_MGMT1, 3, 0,
- &ak4642_lout_mixer_controls[0],
- ARRAY_SIZE(ak4642_lout_mixer_controls)),
-
- /* DAC */
- SND_SOC_DAPM_DAC("DAC", "HiFi Playback", PW_MGMT1, 2, 0),
-};
-
-static const struct snd_soc_dapm_route ak4642_intercon[] = {
-
- /* Outputs */
- {"HPOUTL", NULL, "HPL Out"},
- {"HPOUTR", NULL, "HPR Out"},
- {"LINEOUT", NULL, "LINEOUT Mixer"},
-
- {"HPL Out", NULL, "Headphone Enable"},
- {"HPR Out", NULL, "Headphone Enable"},
-
- {"Headphone Enable", "Switch", "DACH"},
-
- {"DACH", NULL, "DAC"},
-
- {"LINEOUT Mixer", "DACL", "DAC"},
-};
-
-/* codec private data */
-struct ak4642_priv {
- unsigned int sysclk;
- enum snd_soc_control_type control_type;
-};
-
-/*
- * ak4642 register cache
- */
-static const u8 ak4642_reg[] = {
- 0x00, 0x00, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0x00,
- 0xe1, 0xe1, 0x18, 0x00,
- 0xe1, 0x18, 0x11, 0x08,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00,
-};
-
-static const u8 ak4648_reg[] = {
- 0x00, 0x00, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0x00,
- 0xe1, 0xe1, 0x18, 0x00,
- 0xe1, 0x18, 0x11, 0xb8,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x88, 0x88, 0x08,
-};
-
-static int ak4642_dai_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
- struct snd_soc_codec *codec = dai->codec;
-
- if (is_play) {
- /*
- * start headphone output
- *
- * PLL, Master Mode
- * Audio I/F Format :MSB justified (ADC & DAC)
- * Bass Boost Level : Middle
- *
- * This operation came from example code of
- * "ASAHI KASEI AK4642" (japanese) manual p97.
- */
- snd_soc_write(codec, L_IVC, 0x91); /* volume */
- snd_soc_write(codec, R_IVC, 0x91); /* volume */
- } else {
- /*
- * start stereo input
- *
- * PLL Master Mode
- * Audio I/F Format:MSB justified (ADC & DAC)
- * Pre MIC AMP:+20dB
- * MIC Power On
- * ALC setting:Refer to Table 35
- * ALC bit=“1”
- *
- * This operation came from example code of
- * "ASAHI KASEI AK4642" (japanese) manual p94.
- */
- snd_soc_write(codec, SG_SL1, PMMP | MGAIN0);
- snd_soc_write(codec, TIMER, ZTM(0x3) | WTM(0x3));
- snd_soc_write(codec, ALC_CTL1, ALC | LMTH0);
- snd_soc_update_bits(codec, PW_MGMT1, PMADL, PMADL);
- snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR);
- }
-
- return 0;
-}
-
-static void ak4642_dai_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
- struct snd_soc_codec *codec = dai->codec;
-
- if (is_play) {
- } else {
- /* stop stereo input */
- snd_soc_update_bits(codec, PW_MGMT1, PMADL, 0);
- snd_soc_update_bits(codec, PW_MGMT3, PMADR, 0);
- snd_soc_update_bits(codec, ALC_CTL1, ALC, 0);
- }
-}
-
-static int ak4642_dai_set_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u8 pll;
-
- switch (freq) {
- case 11289600:
- pll = PLL2;
- break;
- case 12288000:
- pll = PLL2 | PLL0;
- break;
- case 12000000:
- pll = PLL2 | PLL1;
- break;
- case 24000000:
- pll = PLL2 | PLL1 | PLL0;
- break;
- case 13500000:
- pll = PLL3 | PLL2;
- break;
- case 27000000:
- pll = PLL3 | PLL2 | PLL0;
- break;
- default:
- return -EINVAL;
- }
- snd_soc_update_bits(codec, MD_CTL1, PLL_MASK, pll);
-
- return 0;
-}
-
-static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = dai->codec;
- u8 data;
- u8 bcko;
-
- data = MCKO | PMPLL; /* use MCKO */
- bcko = 0;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- data |= MS;
- bcko = BCKO_64;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
- snd_soc_update_bits(codec, PW_MGMT2, MS | MCKO | PMPLL, data);
- snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko);
-
- /* format type */
- data = 0;
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_LEFT_J:
- data = LEFT_J;
- break;
- case SND_SOC_DAIFMT_I2S:
- data = I2S;
- break;
- /* FIXME
- * Please add RIGHT_J / DSP support here
- */
- default:
- return -EINVAL;
- break;
- }
- snd_soc_update_bits(codec, MD_CTL1, DIF_MASK, data);
-
- return 0;
-}
-
-static int ak4642_dai_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- u8 rate;
-
- switch (params_rate(params)) {
- case 7350:
- rate = FS2;
- break;
- case 8000:
- rate = 0;
- break;
- case 11025:
- rate = FS2 | FS0;
- break;
- case 12000:
- rate = FS0;
- break;
- case 14700:
- rate = FS2 | FS1;
- break;
- case 16000:
- rate = FS1;
- break;
- case 22050:
- rate = FS2 | FS1 | FS0;
- break;
- case 24000:
- rate = FS1 | FS0;
- break;
- case 29400:
- rate = FS3 | FS2 | FS1;
- break;
- case 32000:
- rate = FS3 | FS1;
- break;
- case 44100:
- rate = FS3 | FS2 | FS1 | FS0;
- break;
- case 48000:
- rate = FS3 | FS1 | FS0;
- break;
- default:
- return -EINVAL;
- break;
- }
- snd_soc_update_bits(codec, MD_CTL2, FS_MASK, rate);
-
- return 0;
-}
-
-static int ak4642_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- switch (level) {
- case SND_SOC_BIAS_OFF:
- snd_soc_write(codec, PW_MGMT1, 0x00);
- break;
- default:
- snd_soc_update_bits(codec, PW_MGMT1, PMVCM, PMVCM);
- break;
- }
- codec->dapm.bias_level = level;
-
- return 0;
-}
-
-static const struct snd_soc_dai_ops ak4642_dai_ops = {
- .startup = ak4642_dai_startup,
- .shutdown = ak4642_dai_shutdown,
- .set_sysclk = ak4642_dai_set_sysclk,
- .set_fmt = ak4642_dai_set_fmt,
- .hw_params = ak4642_dai_hw_params,
-};
-
-static struct snd_soc_dai_driver ak4642_dai = {
- .name = "ak4642-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE },
- .ops = &ak4642_dai_ops,
- .symmetric_rates = 1,
-};
-
-static int ak4642_resume(struct snd_soc_codec *codec)
-{
- snd_soc_cache_sync(codec);
- return 0;
-}
-
-
-static int ak4642_probe(struct snd_soc_codec *codec)
-{
- struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4642->control_type);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- snd_soc_add_codec_controls(codec, ak4642_snd_controls,
- ARRAY_SIZE(ak4642_snd_controls));
-
- ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-
-static int ak4642_remove(struct snd_soc_codec *codec)
-{
- ak4642_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
- .probe = ak4642_probe,
- .remove = ak4642_remove,
- .resume = ak4642_resume,
- .set_bias_level = ak4642_set_bias_level,
- .reg_cache_default = ak4642_reg, /* ak4642 reg */
- .reg_cache_size = ARRAY_SIZE(ak4642_reg), /* ak4642 reg */
- .reg_word_size = sizeof(u8),
- .dapm_widgets = ak4642_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets),
- .dapm_routes = ak4642_intercon,
- .num_dapm_routes = ARRAY_SIZE(ak4642_intercon),
-};
-
-static struct snd_soc_codec_driver soc_codec_dev_ak4648 = {
- .probe = ak4642_probe,
- .remove = ak4642_remove,
- .resume = ak4642_resume,
- .set_bias_level = ak4642_set_bias_level,
- .reg_cache_default = ak4648_reg, /* ak4648 reg */
- .reg_cache_size = ARRAY_SIZE(ak4648_reg), /* ak4648 reg */
- .reg_word_size = sizeof(u8),
- .dapm_widgets = ak4642_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets),
- .dapm_routes = ak4642_intercon,
- .num_dapm_routes = ARRAY_SIZE(ak4642_intercon),
-};
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int ak4642_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct ak4642_priv *ak4642;
- int ret;
-
- ak4642 = devm_kzalloc(&i2c->dev, sizeof(struct ak4642_priv),
- GFP_KERNEL);
- if (!ak4642)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, ak4642);
- ak4642->control_type = SND_SOC_I2C;
-
- ret = snd_soc_register_codec(&i2c->dev,
- (struct snd_soc_codec_driver *)id->driver_data,
- &ak4642_dai, 1);
- return ret;
-}
-
-static __devexit int ak4642_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static const struct i2c_device_id ak4642_i2c_id[] = {
- { "ak4642", (kernel_ulong_t)&soc_codec_dev_ak4642 },
- { "ak4643", (kernel_ulong_t)&soc_codec_dev_ak4642 },
- { "ak4648", (kernel_ulong_t)&soc_codec_dev_ak4648 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id);
-
-static struct i2c_driver ak4642_i2c_driver = {
- .driver = {
- .name = "ak4642-codec",
- .owner = THIS_MODULE,
- },
- .probe = ak4642_i2c_probe,
- .remove = __devexit_p(ak4642_i2c_remove),
- .id_table = ak4642_i2c_id,
-};
-#endif
-
-static int __init ak4642_modinit(void)
-{
- int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&ak4642_i2c_driver);
-#endif
- return ret;
-
-}
-module_init(ak4642_modinit);
-
-static void __exit ak4642_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&ak4642_i2c_driver);
-#endif
-
-}
-module_exit(ak4642_exit);
-
-MODULE_DESCRIPTION("Soc AK4642 driver");
-MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/ak4671.c b/ANDROID_3.4.5/sound/soc/codecs/ak4671.c
deleted file mode 100644
index 5fb7c2a8..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/ak4671.c
+++ /dev/null
@@ -1,713 +0,0 @@
-/*
- * ak4671.c -- audio driver for AK4671
- *
- * Copyright (C) 2009 Samsung Electronics Co.Ltd
- * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "ak4671.h"
-
-
-/* codec private data */
-struct ak4671_priv {
- enum snd_soc_control_type control_type;
-};
-
-/* ak4671 register cache & default register settings */
-static const u8 ak4671_reg[AK4671_CACHEREGNUM] = {
- 0x00, /* AK4671_AD_DA_POWER_MANAGEMENT (0x00) */
- 0xf6, /* AK4671_PLL_MODE_SELECT0 (0x01) */
- 0x00, /* AK4671_PLL_MODE_SELECT1 (0x02) */
- 0x02, /* AK4671_FORMAT_SELECT (0x03) */
- 0x00, /* AK4671_MIC_SIGNAL_SELECT (0x04) */
- 0x55, /* AK4671_MIC_AMP_GAIN (0x05) */
- 0x00, /* AK4671_MIXING_POWER_MANAGEMENT0 (0x06) */
- 0x00, /* AK4671_MIXING_POWER_MANAGEMENT1 (0x07) */
- 0xb5, /* AK4671_OUTPUT_VOLUME_CONTROL (0x08) */
- 0x00, /* AK4671_LOUT1_SIGNAL_SELECT (0x09) */
- 0x00, /* AK4671_ROUT1_SIGNAL_SELECT (0x0a) */
- 0x00, /* AK4671_LOUT2_SIGNAL_SELECT (0x0b) */
- 0x00, /* AK4671_ROUT2_SIGNAL_SELECT (0x0c) */
- 0x00, /* AK4671_LOUT3_SIGNAL_SELECT (0x0d) */
- 0x00, /* AK4671_ROUT3_SIGNAL_SELECT (0x0e) */
- 0x00, /* AK4671_LOUT1_POWER_MANAGERMENT (0x0f) */
- 0x00, /* AK4671_LOUT2_POWER_MANAGERMENT (0x10) */
- 0x80, /* AK4671_LOUT3_POWER_MANAGERMENT (0x11) */
- 0x91, /* AK4671_LCH_INPUT_VOLUME_CONTROL (0x12) */
- 0x91, /* AK4671_RCH_INPUT_VOLUME_CONTROL (0x13) */
- 0xe1, /* AK4671_ALC_REFERENCE_SELECT (0x14) */
- 0x00, /* AK4671_DIGITAL_MIXING_CONTROL (0x15) */
- 0x00, /* AK4671_ALC_TIMER_SELECT (0x16) */
- 0x00, /* AK4671_ALC_MODE_CONTROL (0x17) */
- 0x02, /* AK4671_MODE_CONTROL1 (0x18) */
- 0x01, /* AK4671_MODE_CONTROL2 (0x19) */
- 0x18, /* AK4671_LCH_OUTPUT_VOLUME_CONTROL (0x1a) */
- 0x18, /* AK4671_RCH_OUTPUT_VOLUME_CONTROL (0x1b) */
- 0x00, /* AK4671_SIDETONE_A_CONTROL (0x1c) */
- 0x02, /* AK4671_DIGITAL_FILTER_SELECT (0x1d) */
- 0x00, /* AK4671_FIL3_COEFFICIENT0 (0x1e) */
- 0x00, /* AK4671_FIL3_COEFFICIENT1 (0x1f) */
- 0x00, /* AK4671_FIL3_COEFFICIENT2 (0x20) */
- 0x00, /* AK4671_FIL3_COEFFICIENT3 (0x21) */
- 0x00, /* AK4671_EQ_COEFFICIENT0 (0x22) */
- 0x00, /* AK4671_EQ_COEFFICIENT1 (0x23) */
- 0x00, /* AK4671_EQ_COEFFICIENT2 (0x24) */
- 0x00, /* AK4671_EQ_COEFFICIENT3 (0x25) */
- 0x00, /* AK4671_EQ_COEFFICIENT4 (0x26) */
- 0x00, /* AK4671_EQ_COEFFICIENT5 (0x27) */
- 0xa9, /* AK4671_FIL1_COEFFICIENT0 (0x28) */
- 0x1f, /* AK4671_FIL1_COEFFICIENT1 (0x29) */
- 0xad, /* AK4671_FIL1_COEFFICIENT2 (0x2a) */
- 0x20, /* AK4671_FIL1_COEFFICIENT3 (0x2b) */
- 0x00, /* AK4671_FIL2_COEFFICIENT0 (0x2c) */
- 0x00, /* AK4671_FIL2_COEFFICIENT1 (0x2d) */
- 0x00, /* AK4671_FIL2_COEFFICIENT2 (0x2e) */
- 0x00, /* AK4671_FIL2_COEFFICIENT3 (0x2f) */
- 0x00, /* AK4671_DIGITAL_FILTER_SELECT2 (0x30) */
- 0x00, /* this register not used */
- 0x00, /* AK4671_E1_COEFFICIENT0 (0x32) */
- 0x00, /* AK4671_E1_COEFFICIENT1 (0x33) */
- 0x00, /* AK4671_E1_COEFFICIENT2 (0x34) */
- 0x00, /* AK4671_E1_COEFFICIENT3 (0x35) */
- 0x00, /* AK4671_E1_COEFFICIENT4 (0x36) */
- 0x00, /* AK4671_E1_COEFFICIENT5 (0x37) */
- 0x00, /* AK4671_E2_COEFFICIENT0 (0x38) */
- 0x00, /* AK4671_E2_COEFFICIENT1 (0x39) */
- 0x00, /* AK4671_E2_COEFFICIENT2 (0x3a) */
- 0x00, /* AK4671_E2_COEFFICIENT3 (0x3b) */
- 0x00, /* AK4671_E2_COEFFICIENT4 (0x3c) */
- 0x00, /* AK4671_E2_COEFFICIENT5 (0x3d) */
- 0x00, /* AK4671_E3_COEFFICIENT0 (0x3e) */
- 0x00, /* AK4671_E3_COEFFICIENT1 (0x3f) */
- 0x00, /* AK4671_E3_COEFFICIENT2 (0x40) */
- 0x00, /* AK4671_E3_COEFFICIENT3 (0x41) */
- 0x00, /* AK4671_E3_COEFFICIENT4 (0x42) */
- 0x00, /* AK4671_E3_COEFFICIENT5 (0x43) */
- 0x00, /* AK4671_E4_COEFFICIENT0 (0x44) */
- 0x00, /* AK4671_E4_COEFFICIENT1 (0x45) */
- 0x00, /* AK4671_E4_COEFFICIENT2 (0x46) */
- 0x00, /* AK4671_E4_COEFFICIENT3 (0x47) */
- 0x00, /* AK4671_E4_COEFFICIENT4 (0x48) */
- 0x00, /* AK4671_E4_COEFFICIENT5 (0x49) */
- 0x00, /* AK4671_E5_COEFFICIENT0 (0x4a) */
- 0x00, /* AK4671_E5_COEFFICIENT1 (0x4b) */
- 0x00, /* AK4671_E5_COEFFICIENT2 (0x4c) */
- 0x00, /* AK4671_E5_COEFFICIENT3 (0x4d) */
- 0x00, /* AK4671_E5_COEFFICIENT4 (0x4e) */
- 0x00, /* AK4671_E5_COEFFICIENT5 (0x4f) */
- 0x88, /* AK4671_EQ_CONTROL_250HZ_100HZ (0x50) */
- 0x88, /* AK4671_EQ_CONTROL_3500HZ_1KHZ (0x51) */
- 0x08, /* AK4671_EQ_CONTRO_10KHZ (0x52) */
- 0x00, /* AK4671_PCM_IF_CONTROL0 (0x53) */
- 0x00, /* AK4671_PCM_IF_CONTROL1 (0x54) */
- 0x00, /* AK4671_PCM_IF_CONTROL2 (0x55) */
- 0x18, /* AK4671_DIGITAL_VOLUME_B_CONTROL (0x56) */
- 0x18, /* AK4671_DIGITAL_VOLUME_C_CONTROL (0x57) */
- 0x00, /* AK4671_SIDETONE_VOLUME_CONTROL (0x58) */
- 0x00, /* AK4671_DIGITAL_MIXING_CONTROL2 (0x59) */
- 0x00, /* AK4671_SAR_ADC_CONTROL (0x5a) */
-};
-
-/*
- * LOUT1/ROUT1 output volume control:
- * from -24 to 6 dB in 6 dB steps (mute instead of -30 dB)
- */
-static DECLARE_TLV_DB_SCALE(out1_tlv, -3000, 600, 1);
-
-/*
- * LOUT2/ROUT2 output volume control:
- * from -33 to 6 dB in 3 dB steps (mute instead of -33 dB)
- */
-static DECLARE_TLV_DB_SCALE(out2_tlv, -3300, 300, 1);
-
-/*
- * LOUT3/ROUT3 output volume control:
- * from -6 to 3 dB in 3 dB steps
- */
-static DECLARE_TLV_DB_SCALE(out3_tlv, -600, 300, 0);
-
-/*
- * Mic amp gain control:
- * from -15 to 30 dB in 3 dB steps
- * REVISIT: The actual min value(0x01) is -12 dB and the reg value 0x00 is not
- * available
- */
-static DECLARE_TLV_DB_SCALE(mic_amp_tlv, -1500, 300, 0);
-
-static const struct snd_kcontrol_new ak4671_snd_controls[] = {
- /* Common playback gain controls */
- SOC_SINGLE_TLV("Line Output1 Playback Volume",
- AK4671_OUTPUT_VOLUME_CONTROL, 0, 0x6, 0, out1_tlv),
- SOC_SINGLE_TLV("Headphone Output2 Playback Volume",
- AK4671_OUTPUT_VOLUME_CONTROL, 4, 0xd, 0, out2_tlv),
- SOC_SINGLE_TLV("Line Output3 Playback Volume",
- AK4671_LOUT3_POWER_MANAGERMENT, 6, 0x3, 0, out3_tlv),
-
- /* Common capture gain controls */
- SOC_DOUBLE_TLV("Mic Amp Capture Volume",
- AK4671_MIC_AMP_GAIN, 0, 4, 0xf, 0, mic_amp_tlv),
-};
-
-/* event handlers */
-static int ak4671_out2_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- snd_soc_update_bits(codec, AK4671_LOUT2_POWER_MANAGERMENT,
- AK4671_MUTEN, AK4671_MUTEN);
- break;
- case SND_SOC_DAPM_PRE_PMD:
- snd_soc_update_bits(codec, AK4671_LOUT2_POWER_MANAGERMENT,
- AK4671_MUTEN, 0);
- break;
- }
-
- return 0;
-}
-
-/* Output Mixers */
-static const struct snd_kcontrol_new ak4671_lout1_mixer_controls[] = {
- SOC_DAPM_SINGLE("DACL", AK4671_LOUT1_SIGNAL_SELECT, 0, 1, 0),
- SOC_DAPM_SINGLE("LINL1", AK4671_LOUT1_SIGNAL_SELECT, 1, 1, 0),
- SOC_DAPM_SINGLE("LINL2", AK4671_LOUT1_SIGNAL_SELECT, 2, 1, 0),
- SOC_DAPM_SINGLE("LINL3", AK4671_LOUT1_SIGNAL_SELECT, 3, 1, 0),
- SOC_DAPM_SINGLE("LINL4", AK4671_LOUT1_SIGNAL_SELECT, 4, 1, 0),
- SOC_DAPM_SINGLE("LOOPL", AK4671_LOUT1_SIGNAL_SELECT, 5, 1, 0),
-};
-
-static const struct snd_kcontrol_new ak4671_rout1_mixer_controls[] = {
- SOC_DAPM_SINGLE("DACR", AK4671_ROUT1_SIGNAL_SELECT, 0, 1, 0),
- SOC_DAPM_SINGLE("RINR1", AK4671_ROUT1_SIGNAL_SELECT, 1, 1, 0),
- SOC_DAPM_SINGLE("RINR2", AK4671_ROUT1_SIGNAL_SELECT, 2, 1, 0),
- SOC_DAPM_SINGLE("RINR3", AK4671_ROUT1_SIGNAL_SELECT, 3, 1, 0),
- SOC_DAPM_SINGLE("RINR4", AK4671_ROUT1_SIGNAL_SELECT, 4, 1, 0),
- SOC_DAPM_SINGLE("LOOPR", AK4671_ROUT1_SIGNAL_SELECT, 5, 1, 0),
-};
-
-static const struct snd_kcontrol_new ak4671_lout2_mixer_controls[] = {
- SOC_DAPM_SINGLE("DACHL", AK4671_LOUT2_SIGNAL_SELECT, 0, 1, 0),
- SOC_DAPM_SINGLE("LINH1", AK4671_LOUT2_SIGNAL_SELECT, 1, 1, 0),
- SOC_DAPM_SINGLE("LINH2", AK4671_LOUT2_SIGNAL_SELECT, 2, 1, 0),
- SOC_DAPM_SINGLE("LINH3", AK4671_LOUT2_SIGNAL_SELECT, 3, 1, 0),
- SOC_DAPM_SINGLE("LINH4", AK4671_LOUT2_SIGNAL_SELECT, 4, 1, 0),
- SOC_DAPM_SINGLE("LOOPHL", AK4671_LOUT2_SIGNAL_SELECT, 5, 1, 0),
-};
-
-static const struct snd_kcontrol_new ak4671_rout2_mixer_controls[] = {
- SOC_DAPM_SINGLE("DACHR", AK4671_ROUT2_SIGNAL_SELECT, 0, 1, 0),
- SOC_DAPM_SINGLE("RINH1", AK4671_ROUT2_SIGNAL_SELECT, 1, 1, 0),
- SOC_DAPM_SINGLE("RINH2", AK4671_ROUT2_SIGNAL_SELECT, 2, 1, 0),
- SOC_DAPM_SINGLE("RINH3", AK4671_ROUT2_SIGNAL_SELECT, 3, 1, 0),
- SOC_DAPM_SINGLE("RINH4", AK4671_ROUT2_SIGNAL_SELECT, 4, 1, 0),
- SOC_DAPM_SINGLE("LOOPHR", AK4671_ROUT2_SIGNAL_SELECT, 5, 1, 0),
-};
-
-static const struct snd_kcontrol_new ak4671_lout3_mixer_controls[] = {
- SOC_DAPM_SINGLE("DACSL", AK4671_LOUT3_SIGNAL_SELECT, 0, 1, 0),
- SOC_DAPM_SINGLE("LINS1", AK4671_LOUT3_SIGNAL_SELECT, 1, 1, 0),
- SOC_DAPM_SINGLE("LINS2", AK4671_LOUT3_SIGNAL_SELECT, 2, 1, 0),
- SOC_DAPM_SINGLE("LINS3", AK4671_LOUT3_SIGNAL_SELECT, 3, 1, 0),
- SOC_DAPM_SINGLE("LINS4", AK4671_LOUT3_SIGNAL_SELECT, 4, 1, 0),
- SOC_DAPM_SINGLE("LOOPSL", AK4671_LOUT3_SIGNAL_SELECT, 5, 1, 0),
-};
-
-static const struct snd_kcontrol_new ak4671_rout3_mixer_controls[] = {
- SOC_DAPM_SINGLE("DACSR", AK4671_ROUT3_SIGNAL_SELECT, 0, 1, 0),
- SOC_DAPM_SINGLE("RINS1", AK4671_ROUT3_SIGNAL_SELECT, 1, 1, 0),
- SOC_DAPM_SINGLE("RINS2", AK4671_ROUT3_SIGNAL_SELECT, 2, 1, 0),
- SOC_DAPM_SINGLE("RINS3", AK4671_ROUT3_SIGNAL_SELECT, 3, 1, 0),
- SOC_DAPM_SINGLE("RINS4", AK4671_ROUT3_SIGNAL_SELECT, 4, 1, 0),
- SOC_DAPM_SINGLE("LOOPSR", AK4671_ROUT3_SIGNAL_SELECT, 5, 1, 0),
-};
-
-/* Input MUXs */
-static const char *ak4671_lin_mux_texts[] =
- {"LIN1", "LIN2", "LIN3", "LIN4"};
-static const struct soc_enum ak4671_lin_mux_enum =
- SOC_ENUM_SINGLE(AK4671_MIC_SIGNAL_SELECT, 0,
- ARRAY_SIZE(ak4671_lin_mux_texts),
- ak4671_lin_mux_texts);
-static const struct snd_kcontrol_new ak4671_lin_mux_control =
- SOC_DAPM_ENUM("Route", ak4671_lin_mux_enum);
-
-static const char *ak4671_rin_mux_texts[] =
- {"RIN1", "RIN2", "RIN3", "RIN4"};
-static const struct soc_enum ak4671_rin_mux_enum =
- SOC_ENUM_SINGLE(AK4671_MIC_SIGNAL_SELECT, 2,
- ARRAY_SIZE(ak4671_rin_mux_texts),
- ak4671_rin_mux_texts);
-static const struct snd_kcontrol_new ak4671_rin_mux_control =
- SOC_DAPM_ENUM("Route", ak4671_rin_mux_enum);
-
-static const struct snd_soc_dapm_widget ak4671_dapm_widgets[] = {
- /* Inputs */
- SND_SOC_DAPM_INPUT("LIN1"),
- SND_SOC_DAPM_INPUT("RIN1"),
- SND_SOC_DAPM_INPUT("LIN2"),
- SND_SOC_DAPM_INPUT("RIN2"),
- SND_SOC_DAPM_INPUT("LIN3"),
- SND_SOC_DAPM_INPUT("RIN3"),
- SND_SOC_DAPM_INPUT("LIN4"),
- SND_SOC_DAPM_INPUT("RIN4"),
-
- /* Outputs */
- SND_SOC_DAPM_OUTPUT("LOUT1"),
- SND_SOC_DAPM_OUTPUT("ROUT1"),
- SND_SOC_DAPM_OUTPUT("LOUT2"),
- SND_SOC_DAPM_OUTPUT("ROUT2"),
- SND_SOC_DAPM_OUTPUT("LOUT3"),
- SND_SOC_DAPM_OUTPUT("ROUT3"),
-
- /* DAC */
- SND_SOC_DAPM_DAC("DAC Left", "Left HiFi Playback",
- AK4671_AD_DA_POWER_MANAGEMENT, 6, 0),
- SND_SOC_DAPM_DAC("DAC Right", "Right HiFi Playback",
- AK4671_AD_DA_POWER_MANAGEMENT, 7, 0),
-
- /* ADC */
- SND_SOC_DAPM_ADC("ADC Left", "Left HiFi Capture",
- AK4671_AD_DA_POWER_MANAGEMENT, 4, 0),
- SND_SOC_DAPM_ADC("ADC Right", "Right HiFi Capture",
- AK4671_AD_DA_POWER_MANAGEMENT, 5, 0),
-
- /* PGA */
- SND_SOC_DAPM_PGA("LOUT2 Mix Amp",
- AK4671_LOUT2_POWER_MANAGERMENT, 5, 0, NULL, 0),
- SND_SOC_DAPM_PGA("ROUT2 Mix Amp",
- AK4671_LOUT2_POWER_MANAGERMENT, 6, 0, NULL, 0),
-
- SND_SOC_DAPM_PGA("LIN1 Mixing Circuit",
- AK4671_MIXING_POWER_MANAGEMENT1, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("RIN1 Mixing Circuit",
- AK4671_MIXING_POWER_MANAGEMENT1, 1, 0, NULL, 0),
- SND_SOC_DAPM_PGA("LIN2 Mixing Circuit",
- AK4671_MIXING_POWER_MANAGEMENT1, 2, 0, NULL, 0),
- SND_SOC_DAPM_PGA("RIN2 Mixing Circuit",
- AK4671_MIXING_POWER_MANAGEMENT1, 3, 0, NULL, 0),
- SND_SOC_DAPM_PGA("LIN3 Mixing Circuit",
- AK4671_MIXING_POWER_MANAGEMENT1, 4, 0, NULL, 0),
- SND_SOC_DAPM_PGA("RIN3 Mixing Circuit",
- AK4671_MIXING_POWER_MANAGEMENT1, 5, 0, NULL, 0),
- SND_SOC_DAPM_PGA("LIN4 Mixing Circuit",
- AK4671_MIXING_POWER_MANAGEMENT1, 6, 0, NULL, 0),
- SND_SOC_DAPM_PGA("RIN4 Mixing Circuit",
- AK4671_MIXING_POWER_MANAGEMENT1, 7, 0, NULL, 0),
-
- /* Output Mixers */
- SND_SOC_DAPM_MIXER("LOUT1 Mixer", AK4671_LOUT1_POWER_MANAGERMENT, 0, 0,
- &ak4671_lout1_mixer_controls[0],
- ARRAY_SIZE(ak4671_lout1_mixer_controls)),
- SND_SOC_DAPM_MIXER("ROUT1 Mixer", AK4671_LOUT1_POWER_MANAGERMENT, 1, 0,
- &ak4671_rout1_mixer_controls[0],
- ARRAY_SIZE(ak4671_rout1_mixer_controls)),
- SND_SOC_DAPM_MIXER_E("LOUT2 Mixer", AK4671_LOUT2_POWER_MANAGERMENT,
- 0, 0, &ak4671_lout2_mixer_controls[0],
- ARRAY_SIZE(ak4671_lout2_mixer_controls),
- ak4671_out2_event,
- SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_PRE_PMD),
- SND_SOC_DAPM_MIXER_E("ROUT2 Mixer", AK4671_LOUT2_POWER_MANAGERMENT,
- 1, 0, &ak4671_rout2_mixer_controls[0],
- ARRAY_SIZE(ak4671_rout2_mixer_controls),
- ak4671_out2_event,
- SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_PRE_PMD),
- SND_SOC_DAPM_MIXER("LOUT3 Mixer", AK4671_LOUT3_POWER_MANAGERMENT, 0, 0,
- &ak4671_lout3_mixer_controls[0],
- ARRAY_SIZE(ak4671_lout3_mixer_controls)),
- SND_SOC_DAPM_MIXER("ROUT3 Mixer", AK4671_LOUT3_POWER_MANAGERMENT, 1, 0,
- &ak4671_rout3_mixer_controls[0],
- ARRAY_SIZE(ak4671_rout3_mixer_controls)),
-
- /* Input MUXs */
- SND_SOC_DAPM_MUX("LIN MUX", AK4671_AD_DA_POWER_MANAGEMENT, 2, 0,
- &ak4671_lin_mux_control),
- SND_SOC_DAPM_MUX("RIN MUX", AK4671_AD_DA_POWER_MANAGEMENT, 3, 0,
- &ak4671_rin_mux_control),
-
- /* Mic Power */
- SND_SOC_DAPM_MICBIAS("Mic Bias", AK4671_AD_DA_POWER_MANAGEMENT, 1, 0),
-
- /* Supply */
- SND_SOC_DAPM_SUPPLY("PMPLL", AK4671_PLL_MODE_SELECT1, 0, 0, NULL, 0),
-};
-
-static const struct snd_soc_dapm_route ak4671_intercon[] = {
- {"DAC Left", "NULL", "PMPLL"},
- {"DAC Right", "NULL", "PMPLL"},
- {"ADC Left", "NULL", "PMPLL"},
- {"ADC Right", "NULL", "PMPLL"},
-
- /* Outputs */
- {"LOUT1", "NULL", "LOUT1 Mixer"},
- {"ROUT1", "NULL", "ROUT1 Mixer"},
- {"LOUT2", "NULL", "LOUT2 Mix Amp"},
- {"ROUT2", "NULL", "ROUT2 Mix Amp"},
- {"LOUT3", "NULL", "LOUT3 Mixer"},
- {"ROUT3", "NULL", "ROUT3 Mixer"},
-
- {"LOUT1 Mixer", "DACL", "DAC Left"},
- {"ROUT1 Mixer", "DACR", "DAC Right"},
- {"LOUT2 Mixer", "DACHL", "DAC Left"},
- {"ROUT2 Mixer", "DACHR", "DAC Right"},
- {"LOUT2 Mix Amp", "NULL", "LOUT2 Mixer"},
- {"ROUT2 Mix Amp", "NULL", "ROUT2 Mixer"},
- {"LOUT3 Mixer", "DACSL", "DAC Left"},
- {"ROUT3 Mixer", "DACSR", "DAC Right"},
-
- /* Inputs */
- {"LIN MUX", "LIN1", "LIN1"},
- {"LIN MUX", "LIN2", "LIN2"},
- {"LIN MUX", "LIN3", "LIN3"},
- {"LIN MUX", "LIN4", "LIN4"},
-
- {"RIN MUX", "RIN1", "RIN1"},
- {"RIN MUX", "RIN2", "RIN2"},
- {"RIN MUX", "RIN3", "RIN3"},
- {"RIN MUX", "RIN4", "RIN4"},
-
- {"LIN1", NULL, "Mic Bias"},
- {"RIN1", NULL, "Mic Bias"},
- {"LIN2", NULL, "Mic Bias"},
- {"RIN2", NULL, "Mic Bias"},
-
- {"ADC Left", "NULL", "LIN MUX"},
- {"ADC Right", "NULL", "RIN MUX"},
-
- /* Analog Loops */
- {"LIN1 Mixing Circuit", "NULL", "LIN1"},
- {"RIN1 Mixing Circuit", "NULL", "RIN1"},
- {"LIN2 Mixing Circuit", "NULL", "LIN2"},
- {"RIN2 Mixing Circuit", "NULL", "RIN2"},
- {"LIN3 Mixing Circuit", "NULL", "LIN3"},
- {"RIN3 Mixing Circuit", "NULL", "RIN3"},
- {"LIN4 Mixing Circuit", "NULL", "LIN4"},
- {"RIN4 Mixing Circuit", "NULL", "RIN4"},
-
- {"LOUT1 Mixer", "LINL1", "LIN1 Mixing Circuit"},
- {"ROUT1 Mixer", "RINR1", "RIN1 Mixing Circuit"},
- {"LOUT2 Mixer", "LINH1", "LIN1 Mixing Circuit"},
- {"ROUT2 Mixer", "RINH1", "RIN1 Mixing Circuit"},
- {"LOUT3 Mixer", "LINS1", "LIN1 Mixing Circuit"},
- {"ROUT3 Mixer", "RINS1", "RIN1 Mixing Circuit"},
-
- {"LOUT1 Mixer", "LINL2", "LIN2 Mixing Circuit"},
- {"ROUT1 Mixer", "RINR2", "RIN2 Mixing Circuit"},
- {"LOUT2 Mixer", "LINH2", "LIN2 Mixing Circuit"},
- {"ROUT2 Mixer", "RINH2", "RIN2 Mixing Circuit"},
- {"LOUT3 Mixer", "LINS2", "LIN2 Mixing Circuit"},
- {"ROUT3 Mixer", "RINS2", "RIN2 Mixing Circuit"},
-
- {"LOUT1 Mixer", "LINL3", "LIN3 Mixing Circuit"},
- {"ROUT1 Mixer", "RINR3", "RIN3 Mixing Circuit"},
- {"LOUT2 Mixer", "LINH3", "LIN3 Mixing Circuit"},
- {"ROUT2 Mixer", "RINH3", "RIN3 Mixing Circuit"},
- {"LOUT3 Mixer", "LINS3", "LIN3 Mixing Circuit"},
- {"ROUT3 Mixer", "RINS3", "RIN3 Mixing Circuit"},
-
- {"LOUT1 Mixer", "LINL4", "LIN4 Mixing Circuit"},
- {"ROUT1 Mixer", "RINR4", "RIN4 Mixing Circuit"},
- {"LOUT2 Mixer", "LINH4", "LIN4 Mixing Circuit"},
- {"ROUT2 Mixer", "RINH4", "RIN4 Mixing Circuit"},
- {"LOUT3 Mixer", "LINS4", "LIN4 Mixing Circuit"},
- {"ROUT3 Mixer", "RINS4", "RIN4 Mixing Circuit"},
-};
-
-static int ak4671_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- u8 fs;
-
- fs = snd_soc_read(codec, AK4671_PLL_MODE_SELECT0);
- fs &= ~AK4671_FS;
-
- switch (params_rate(params)) {
- case 8000:
- fs |= AK4671_FS_8KHZ;
- break;
- case 12000:
- fs |= AK4671_FS_12KHZ;
- break;
- case 16000:
- fs |= AK4671_FS_16KHZ;
- break;
- case 24000:
- fs |= AK4671_FS_24KHZ;
- break;
- case 11025:
- fs |= AK4671_FS_11_025KHZ;
- break;
- case 22050:
- fs |= AK4671_FS_22_05KHZ;
- break;
- case 32000:
- fs |= AK4671_FS_32KHZ;
- break;
- case 44100:
- fs |= AK4671_FS_44_1KHZ;
- break;
- case 48000:
- fs |= AK4671_FS_48KHZ;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, AK4671_PLL_MODE_SELECT0, fs);
-
- return 0;
-}
-
-static int ak4671_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
- unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = dai->codec;
- u8 pll;
-
- pll = snd_soc_read(codec, AK4671_PLL_MODE_SELECT0);
- pll &= ~AK4671_PLL;
-
- switch (freq) {
- case 11289600:
- pll |= AK4671_PLL_11_2896MHZ;
- break;
- case 12000000:
- pll |= AK4671_PLL_12MHZ;
- break;
- case 12288000:
- pll |= AK4671_PLL_12_288MHZ;
- break;
- case 13000000:
- pll |= AK4671_PLL_13MHZ;
- break;
- case 13500000:
- pll |= AK4671_PLL_13_5MHZ;
- break;
- case 19200000:
- pll |= AK4671_PLL_19_2MHZ;
- break;
- case 24000000:
- pll |= AK4671_PLL_24MHZ;
- break;
- case 26000000:
- pll |= AK4671_PLL_26MHZ;
- break;
- case 27000000:
- pll |= AK4671_PLL_27MHZ;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, AK4671_PLL_MODE_SELECT0, pll);
-
- return 0;
-}
-
-static int ak4671_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = dai->codec;
- u8 mode;
- u8 format;
-
- /* set master/slave audio interface */
- mode = snd_soc_read(codec, AK4671_PLL_MODE_SELECT1);
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- mode |= AK4671_M_S;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- mode &= ~(AK4671_M_S);
- break;
- default:
- return -EINVAL;
- }
-
- /* interface format */
- format = snd_soc_read(codec, AK4671_FORMAT_SELECT);
- format &= ~AK4671_DIF;
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- format |= AK4671_DIF_I2S_MODE;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- format |= AK4671_DIF_MSB_MODE;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- format |= AK4671_DIF_DSP_MODE;
- format |= AK4671_BCKP;
- format |= AK4671_MSBS;
- break;
- default:
- return -EINVAL;
- }
-
- /* set mode and format */
- snd_soc_write(codec, AK4671_PLL_MODE_SELECT1, mode);
- snd_soc_write(codec, AK4671_FORMAT_SELECT, format);
-
- return 0;
-}
-
-static int ak4671_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- switch (level) {
- case SND_SOC_BIAS_ON:
- case SND_SOC_BIAS_PREPARE:
- case SND_SOC_BIAS_STANDBY:
- snd_soc_update_bits(codec, AK4671_AD_DA_POWER_MANAGEMENT,
- AK4671_PMVCM, AK4671_PMVCM);
- break;
- case SND_SOC_BIAS_OFF:
- snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define AK4671_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
- SNDRV_PCM_RATE_48000)
-
-#define AK4671_FORMATS SNDRV_PCM_FMTBIT_S16_LE
-
-static const struct snd_soc_dai_ops ak4671_dai_ops = {
- .hw_params = ak4671_hw_params,
- .set_sysclk = ak4671_set_dai_sysclk,
- .set_fmt = ak4671_set_dai_fmt,
-};
-
-static struct snd_soc_dai_driver ak4671_dai = {
- .name = "ak4671-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = AK4671_RATES,
- .formats = AK4671_FORMATS,},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = AK4671_RATES,
- .formats = AK4671_FORMATS,},
- .ops = &ak4671_dai_ops,
-};
-
-static int ak4671_probe(struct snd_soc_codec *codec)
-{
- struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- snd_soc_add_codec_controls(codec, ak4671_snd_controls,
- ARRAY_SIZE(ak4671_snd_controls));
-
- ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return ret;
-}
-
-static int ak4671_remove(struct snd_soc_codec *codec)
-{
- ak4671_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_ak4671 = {
- .probe = ak4671_probe,
- .remove = ak4671_remove,
- .set_bias_level = ak4671_set_bias_level,
- .reg_cache_size = AK4671_CACHEREGNUM,
- .reg_word_size = sizeof(u8),
- .reg_cache_default = ak4671_reg,
- .dapm_widgets = ak4671_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets),
- .dapm_routes = ak4671_intercon,
- .num_dapm_routes = ARRAY_SIZE(ak4671_intercon),
-};
-
-static int __devinit ak4671_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct ak4671_priv *ak4671;
- int ret;
-
- ak4671 = devm_kzalloc(&client->dev, sizeof(struct ak4671_priv),
- GFP_KERNEL);
- if (ak4671 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(client, ak4671);
- ak4671->control_type = SND_SOC_I2C;
-
- ret = snd_soc_register_codec(&client->dev,
- &soc_codec_dev_ak4671, &ak4671_dai, 1);
- return ret;
-}
-
-static __devexit int ak4671_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static const struct i2c_device_id ak4671_i2c_id[] = {
- { "ak4671", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ak4671_i2c_id);
-
-static struct i2c_driver ak4671_i2c_driver = {
- .driver = {
- .name = "ak4671-codec",
- .owner = THIS_MODULE,
- },
- .probe = ak4671_i2c_probe,
- .remove = __devexit_p(ak4671_i2c_remove),
- .id_table = ak4671_i2c_id,
-};
-
-static int __init ak4671_modinit(void)
-{
- return i2c_add_driver(&ak4671_i2c_driver);
-}
-module_init(ak4671_modinit);
-
-static void __exit ak4671_exit(void)
-{
- i2c_del_driver(&ak4671_i2c_driver);
-}
-module_exit(ak4671_exit);
-
-MODULE_DESCRIPTION("ASoC AK4671 codec driver");
-MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/ak4671.h b/ANDROID_3.4.5/sound/soc/codecs/ak4671.h
deleted file mode 100644
index 61cb7ab7..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/ak4671.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * ak4671.h -- audio driver for AK4671
- *
- * Copyright (C) 2009 Samsung Electronics Co.Ltd
- * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#ifndef _AK4671_H
-#define _AK4671_H
-
-#define AK4671_AD_DA_POWER_MANAGEMENT 0x00
-#define AK4671_PLL_MODE_SELECT0 0x01
-#define AK4671_PLL_MODE_SELECT1 0x02
-#define AK4671_FORMAT_SELECT 0x03
-#define AK4671_MIC_SIGNAL_SELECT 0x04
-#define AK4671_MIC_AMP_GAIN 0x05
-#define AK4671_MIXING_POWER_MANAGEMENT0 0x06
-#define AK4671_MIXING_POWER_MANAGEMENT1 0x07
-#define AK4671_OUTPUT_VOLUME_CONTROL 0x08
-#define AK4671_LOUT1_SIGNAL_SELECT 0x09
-#define AK4671_ROUT1_SIGNAL_SELECT 0x0a
-#define AK4671_LOUT2_SIGNAL_SELECT 0x0b
-#define AK4671_ROUT2_SIGNAL_SELECT 0x0c
-#define AK4671_LOUT3_SIGNAL_SELECT 0x0d
-#define AK4671_ROUT3_SIGNAL_SELECT 0x0e
-#define AK4671_LOUT1_POWER_MANAGERMENT 0x0f
-#define AK4671_LOUT2_POWER_MANAGERMENT 0x10
-#define AK4671_LOUT3_POWER_MANAGERMENT 0x11
-#define AK4671_LCH_INPUT_VOLUME_CONTROL 0x12
-#define AK4671_RCH_INPUT_VOLUME_CONTROL 0x13
-#define AK4671_ALC_REFERENCE_SELECT 0x14
-#define AK4671_DIGITAL_MIXING_CONTROL 0x15
-#define AK4671_ALC_TIMER_SELECT 0x16
-#define AK4671_ALC_MODE_CONTROL 0x17
-#define AK4671_MODE_CONTROL1 0x18
-#define AK4671_MODE_CONTROL2 0x19
-#define AK4671_LCH_OUTPUT_VOLUME_CONTROL 0x1a
-#define AK4671_RCH_OUTPUT_VOLUME_CONTROL 0x1b
-#define AK4671_SIDETONE_A_CONTROL 0x1c
-#define AK4671_DIGITAL_FILTER_SELECT 0x1d
-#define AK4671_FIL3_COEFFICIENT0 0x1e
-#define AK4671_FIL3_COEFFICIENT1 0x1f
-#define AK4671_FIL3_COEFFICIENT2 0x20
-#define AK4671_FIL3_COEFFICIENT3 0x21
-#define AK4671_EQ_COEFFICIENT0 0x22
-#define AK4671_EQ_COEFFICIENT1 0x23
-#define AK4671_EQ_COEFFICIENT2 0x24
-#define AK4671_EQ_COEFFICIENT3 0x25
-#define AK4671_EQ_COEFFICIENT4 0x26
-#define AK4671_EQ_COEFFICIENT5 0x27
-#define AK4671_FIL1_COEFFICIENT0 0x28
-#define AK4671_FIL1_COEFFICIENT1 0x29
-#define AK4671_FIL1_COEFFICIENT2 0x2a
-#define AK4671_FIL1_COEFFICIENT3 0x2b
-#define AK4671_FIL2_COEFFICIENT0 0x2c
-#define AK4671_FIL2_COEFFICIENT1 0x2d
-#define AK4671_FIL2_COEFFICIENT2 0x2e
-#define AK4671_FIL2_COEFFICIENT3 0x2f
-#define AK4671_DIGITAL_FILTER_SELECT2 0x30
-#define AK4671_E1_COEFFICIENT0 0x32
-#define AK4671_E1_COEFFICIENT1 0x33
-#define AK4671_E1_COEFFICIENT2 0x34
-#define AK4671_E1_COEFFICIENT3 0x35
-#define AK4671_E1_COEFFICIENT4 0x36
-#define AK4671_E1_COEFFICIENT5 0x37
-#define AK4671_E2_COEFFICIENT0 0x38
-#define AK4671_E2_COEFFICIENT1 0x39
-#define AK4671_E2_COEFFICIENT2 0x3a
-#define AK4671_E2_COEFFICIENT3 0x3b
-#define AK4671_E2_COEFFICIENT4 0x3c
-#define AK4671_E2_COEFFICIENT5 0x3d
-#define AK4671_E3_COEFFICIENT0 0x3e
-#define AK4671_E3_COEFFICIENT1 0x3f
-#define AK4671_E3_COEFFICIENT2 0x40
-#define AK4671_E3_COEFFICIENT3 0x41
-#define AK4671_E3_COEFFICIENT4 0x42
-#define AK4671_E3_COEFFICIENT5 0x43
-#define AK4671_E4_COEFFICIENT0 0x44
-#define AK4671_E4_COEFFICIENT1 0x45
-#define AK4671_E4_COEFFICIENT2 0x46
-#define AK4671_E4_COEFFICIENT3 0x47
-#define AK4671_E4_COEFFICIENT4 0x48
-#define AK4671_E4_COEFFICIENT5 0x49
-#define AK4671_E5_COEFFICIENT0 0x4a
-#define AK4671_E5_COEFFICIENT1 0x4b
-#define AK4671_E5_COEFFICIENT2 0x4c
-#define AK4671_E5_COEFFICIENT3 0x4d
-#define AK4671_E5_COEFFICIENT4 0x4e
-#define AK4671_E5_COEFFICIENT5 0x4f
-#define AK4671_EQ_CONTROL_250HZ_100HZ 0x50
-#define AK4671_EQ_CONTROL_3500HZ_1KHZ 0x51
-#define AK4671_EQ_CONTRO_10KHZ 0x52
-#define AK4671_PCM_IF_CONTROL0 0x53
-#define AK4671_PCM_IF_CONTROL1 0x54
-#define AK4671_PCM_IF_CONTROL2 0x55
-#define AK4671_DIGITAL_VOLUME_B_CONTROL 0x56
-#define AK4671_DIGITAL_VOLUME_C_CONTROL 0x57
-#define AK4671_SIDETONE_VOLUME_CONTROL 0x58
-#define AK4671_DIGITAL_MIXING_CONTROL2 0x59
-#define AK4671_SAR_ADC_CONTROL 0x5a
-
-#define AK4671_CACHEREGNUM (AK4671_SAR_ADC_CONTROL + 1)
-
-/* Bitfield Definitions */
-
-/* AK4671_AD_DA_POWER_MANAGEMENT (0x00) Fields */
-#define AK4671_PMVCM 0x01
-
-/* AK4671_PLL_MODE_SELECT0 (0x01) Fields */
-#define AK4671_PLL 0x0f
-#define AK4671_PLL_11_2896MHZ (4 << 0)
-#define AK4671_PLL_12_288MHZ (5 << 0)
-#define AK4671_PLL_12MHZ (6 << 0)
-#define AK4671_PLL_24MHZ (7 << 0)
-#define AK4671_PLL_19_2MHZ (8 << 0)
-#define AK4671_PLL_13_5MHZ (12 << 0)
-#define AK4671_PLL_27MHZ (13 << 0)
-#define AK4671_PLL_13MHZ (14 << 0)
-#define AK4671_PLL_26MHZ (15 << 0)
-#define AK4671_FS 0xf0
-#define AK4671_FS_8KHZ (0 << 4)
-#define AK4671_FS_12KHZ (1 << 4)
-#define AK4671_FS_16KHZ (2 << 4)
-#define AK4671_FS_24KHZ (3 << 4)
-#define AK4671_FS_11_025KHZ (5 << 4)
-#define AK4671_FS_22_05KHZ (7 << 4)
-#define AK4671_FS_32KHZ (10 << 4)
-#define AK4671_FS_48KHZ (11 << 4)
-#define AK4671_FS_44_1KHZ (15 << 4)
-
-/* AK4671_PLL_MODE_SELECT1 (0x02) Fields */
-#define AK4671_PMPLL 0x01
-#define AK4671_M_S 0x02
-
-/* AK4671_FORMAT_SELECT (0x03) Fields */
-#define AK4671_DIF 0x03
-#define AK4671_DIF_DSP_MODE (0 << 0)
-#define AK4671_DIF_MSB_MODE (2 << 0)
-#define AK4671_DIF_I2S_MODE (3 << 0)
-#define AK4671_BCKP 0x04
-#define AK4671_MSBS 0x08
-#define AK4671_SDOD 0x10
-
-/* AK4671_LOUT2_POWER_MANAGEMENT (0x10) Fields */
-#define AK4671_MUTEN 0x04
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/alc5623.c b/ANDROID_3.4.5/sound/soc/codecs/alc5623.c
deleted file mode 100644
index d47b62dd..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/alc5623.c
+++ /dev/null
@@ -1,1109 +0,0 @@
-/*
- * alc5623.c -- alc562[123] ALSA Soc Audio driver
- *
- * Copyright 2008 Realtek Microelectronics
- * Author: flove <flove@realtek.com> Ethan <eku@marvell.com>
- *
- * Copyright 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
- *
- *
- * Based on WM8753.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/tlv.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/alc5623.h>
-
-#include "alc5623.h"
-
-static int caps_charge = 2000;
-module_param(caps_charge, int, 0);
-MODULE_PARM_DESC(caps_charge, "ALC5623 cap charge time (msecs)");
-
-/* codec private data */
-struct alc5623_priv {
- enum snd_soc_control_type control_type;
- u8 id;
- unsigned int sysclk;
- u16 reg_cache[ALC5623_VENDOR_ID2+2];
- unsigned int add_ctrl;
- unsigned int jack_det_ctrl;
-};
-
-static void alc5623_fill_cache(struct snd_soc_codec *codec)
-{
- int i, step = codec->driver->reg_cache_step;
- u16 *cache = codec->reg_cache;
-
- /* not really efficient ... */
- codec->cache_bypass = 1;
- for (i = 0 ; i < codec->driver->reg_cache_size ; i += step)
- cache[i] = snd_soc_read(codec, i);
- codec->cache_bypass = 0;
-}
-
-static inline int alc5623_reset(struct snd_soc_codec *codec)
-{
- return snd_soc_write(codec, ALC5623_RESET, 0);
-}
-
-static int amp_mixer_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- /* to power-on/off class-d amp generators/speaker */
- /* need to write to 'index-46h' register : */
- /* so write index num (here 0x46) to reg 0x6a */
- /* and then 0xffff/0 to reg 0x6c */
- snd_soc_write(w->codec, ALC5623_HID_CTRL_INDEX, 0x46);
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- snd_soc_write(w->codec, ALC5623_HID_CTRL_DATA, 0xFFFF);
- break;
- case SND_SOC_DAPM_POST_PMD:
- snd_soc_write(w->codec, ALC5623_HID_CTRL_DATA, 0);
- break;
- }
-
- return 0;
-}
-
-/*
- * ALC5623 Controls
- */
-
-static const DECLARE_TLV_DB_SCALE(vol_tlv, -3450, 150, 0);
-static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0);
-static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0);
-static const unsigned int boost_tlv[] = {
- TLV_DB_RANGE_HEAD(3),
- 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
- 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
- 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
-};
-static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0);
-
-static const struct snd_kcontrol_new alc5621_vol_snd_controls[] = {
- SOC_DOUBLE_TLV("Speaker Playback Volume",
- ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
- SOC_DOUBLE("Speaker Playback Switch",
- ALC5623_SPK_OUT_VOL, 15, 7, 1, 1),
- SOC_DOUBLE_TLV("Headphone Playback Volume",
- ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),
- SOC_DOUBLE("Headphone Playback Switch",
- ALC5623_HP_OUT_VOL, 15, 7, 1, 1),
-};
-
-static const struct snd_kcontrol_new alc5622_vol_snd_controls[] = {
- SOC_DOUBLE_TLV("Speaker Playback Volume",
- ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
- SOC_DOUBLE("Speaker Playback Switch",
- ALC5623_SPK_OUT_VOL, 15, 7, 1, 1),
- SOC_DOUBLE_TLV("Line Playback Volume",
- ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),
- SOC_DOUBLE("Line Playback Switch",
- ALC5623_HP_OUT_VOL, 15, 7, 1, 1),
-};
-
-static const struct snd_kcontrol_new alc5623_vol_snd_controls[] = {
- SOC_DOUBLE_TLV("Line Playback Volume",
- ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
- SOC_DOUBLE("Line Playback Switch",
- ALC5623_SPK_OUT_VOL, 15, 7, 1, 1),
- SOC_DOUBLE_TLV("Headphone Playback Volume",
- ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),
- SOC_DOUBLE("Headphone Playback Switch",
- ALC5623_HP_OUT_VOL, 15, 7, 1, 1),
-};
-
-static const struct snd_kcontrol_new alc5623_snd_controls[] = {
- SOC_DOUBLE_TLV("Auxout Playback Volume",
- ALC5623_MONO_AUX_OUT_VOL, 8, 0, 31, 1, hp_tlv),
- SOC_DOUBLE("Auxout Playback Switch",
- ALC5623_MONO_AUX_OUT_VOL, 15, 7, 1, 1),
- SOC_DOUBLE_TLV("PCM Playback Volume",
- ALC5623_STEREO_DAC_VOL, 8, 0, 31, 1, vol_tlv),
- SOC_DOUBLE_TLV("AuxI Capture Volume",
- ALC5623_AUXIN_VOL, 8, 0, 31, 1, vol_tlv),
- SOC_DOUBLE_TLV("LineIn Capture Volume",
- ALC5623_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv),
- SOC_SINGLE_TLV("Mic1 Capture Volume",
- ALC5623_MIC_VOL, 8, 31, 1, vol_tlv),
- SOC_SINGLE_TLV("Mic2 Capture Volume",
- ALC5623_MIC_VOL, 0, 31, 1, vol_tlv),
- SOC_DOUBLE_TLV("Rec Capture Volume",
- ALC5623_ADC_REC_GAIN, 7, 0, 31, 0, adc_rec_tlv),
- SOC_SINGLE_TLV("Mic 1 Boost Volume",
- ALC5623_MIC_CTRL, 10, 2, 0, boost_tlv),
- SOC_SINGLE_TLV("Mic 2 Boost Volume",
- ALC5623_MIC_CTRL, 8, 2, 0, boost_tlv),
- SOC_SINGLE_TLV("Digital Boost Volume",
- ALC5623_ADD_CTRL_REG, 4, 3, 0, dig_tlv),
-};
-
-/*
- * DAPM Controls
- */
-static const struct snd_kcontrol_new alc5623_hp_mixer_controls[] = {
-SOC_DAPM_SINGLE("LI2HP Playback Switch", ALC5623_LINE_IN_VOL, 15, 1, 1),
-SOC_DAPM_SINGLE("AUXI2HP Playback Switch", ALC5623_AUXIN_VOL, 15, 1, 1),
-SOC_DAPM_SINGLE("MIC12HP Playback Switch", ALC5623_MIC_ROUTING_CTRL, 15, 1, 1),
-SOC_DAPM_SINGLE("MIC22HP Playback Switch", ALC5623_MIC_ROUTING_CTRL, 7, 1, 1),
-SOC_DAPM_SINGLE("DAC2HP Playback Switch", ALC5623_STEREO_DAC_VOL, 15, 1, 1),
-};
-
-static const struct snd_kcontrol_new alc5623_hpl_mixer_controls[] = {
-SOC_DAPM_SINGLE("ADC2HP_L Playback Switch", ALC5623_ADC_REC_GAIN, 15, 1, 1),
-};
-
-static const struct snd_kcontrol_new alc5623_hpr_mixer_controls[] = {
-SOC_DAPM_SINGLE("ADC2HP_R Playback Switch", ALC5623_ADC_REC_GAIN, 14, 1, 1),
-};
-
-static const struct snd_kcontrol_new alc5623_mono_mixer_controls[] = {
-SOC_DAPM_SINGLE("ADC2MONO_L Playback Switch", ALC5623_ADC_REC_GAIN, 13, 1, 1),
-SOC_DAPM_SINGLE("ADC2MONO_R Playback Switch", ALC5623_ADC_REC_GAIN, 12, 1, 1),
-SOC_DAPM_SINGLE("LI2MONO Playback Switch", ALC5623_LINE_IN_VOL, 13, 1, 1),
-SOC_DAPM_SINGLE("AUXI2MONO Playback Switch", ALC5623_AUXIN_VOL, 13, 1, 1),
-SOC_DAPM_SINGLE("MIC12MONO Playback Switch", ALC5623_MIC_ROUTING_CTRL, 13, 1, 1),
-SOC_DAPM_SINGLE("MIC22MONO Playback Switch", ALC5623_MIC_ROUTING_CTRL, 5, 1, 1),
-SOC_DAPM_SINGLE("DAC2MONO Playback Switch", ALC5623_STEREO_DAC_VOL, 13, 1, 1),
-};
-
-static const struct snd_kcontrol_new alc5623_speaker_mixer_controls[] = {
-SOC_DAPM_SINGLE("LI2SPK Playback Switch", ALC5623_LINE_IN_VOL, 14, 1, 1),
-SOC_DAPM_SINGLE("AUXI2SPK Playback Switch", ALC5623_AUXIN_VOL, 14, 1, 1),
-SOC_DAPM_SINGLE("MIC12SPK Playback Switch", ALC5623_MIC_ROUTING_CTRL, 14, 1, 1),
-SOC_DAPM_SINGLE("MIC22SPK Playback Switch", ALC5623_MIC_ROUTING_CTRL, 6, 1, 1),
-SOC_DAPM_SINGLE("DAC2SPK Playback Switch", ALC5623_STEREO_DAC_VOL, 14, 1, 1),
-};
-
-/* Left Record Mixer */
-static const struct snd_kcontrol_new alc5623_captureL_mixer_controls[] = {
-SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5623_ADC_REC_MIXER, 14, 1, 1),
-SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5623_ADC_REC_MIXER, 13, 1, 1),
-SOC_DAPM_SINGLE("LineInL Capture Switch", ALC5623_ADC_REC_MIXER, 12, 1, 1),
-SOC_DAPM_SINGLE("Left AuxI Capture Switch", ALC5623_ADC_REC_MIXER, 11, 1, 1),
-SOC_DAPM_SINGLE("HPMixerL Capture Switch", ALC5623_ADC_REC_MIXER, 10, 1, 1),
-SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5623_ADC_REC_MIXER, 9, 1, 1),
-SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5623_ADC_REC_MIXER, 8, 1, 1),
-};
-
-/* Right Record Mixer */
-static const struct snd_kcontrol_new alc5623_captureR_mixer_controls[] = {
-SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5623_ADC_REC_MIXER, 6, 1, 1),
-SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5623_ADC_REC_MIXER, 5, 1, 1),
-SOC_DAPM_SINGLE("LineInR Capture Switch", ALC5623_ADC_REC_MIXER, 4, 1, 1),
-SOC_DAPM_SINGLE("Right AuxI Capture Switch", ALC5623_ADC_REC_MIXER, 3, 1, 1),
-SOC_DAPM_SINGLE("HPMixerR Capture Switch", ALC5623_ADC_REC_MIXER, 2, 1, 1),
-SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5623_ADC_REC_MIXER, 1, 1, 1),
-SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5623_ADC_REC_MIXER, 0, 1, 1),
-};
-
-static const char *alc5623_spk_n_sour_sel[] = {
- "RN/-R", "RP/+R", "LN/-R", "Vmid" };
-static const char *alc5623_hpl_out_input_sel[] = {
- "Vmid", "HP Left Mix"};
-static const char *alc5623_hpr_out_input_sel[] = {
- "Vmid", "HP Right Mix"};
-static const char *alc5623_spkout_input_sel[] = {
- "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
-static const char *alc5623_aux_out_input_sel[] = {
- "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
-
-/* auxout output mux */
-static const struct soc_enum alc5623_aux_out_input_enum =
-SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 6, 4, alc5623_aux_out_input_sel);
-static const struct snd_kcontrol_new alc5623_auxout_mux_controls =
-SOC_DAPM_ENUM("Route", alc5623_aux_out_input_enum);
-
-/* speaker output mux */
-static const struct soc_enum alc5623_spkout_input_enum =
-SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 10, 4, alc5623_spkout_input_sel);
-static const struct snd_kcontrol_new alc5623_spkout_mux_controls =
-SOC_DAPM_ENUM("Route", alc5623_spkout_input_enum);
-
-/* headphone left output mux */
-static const struct soc_enum alc5623_hpl_out_input_enum =
-SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 9, 2, alc5623_hpl_out_input_sel);
-static const struct snd_kcontrol_new alc5623_hpl_out_mux_controls =
-SOC_DAPM_ENUM("Route", alc5623_hpl_out_input_enum);
-
-/* headphone right output mux */
-static const struct soc_enum alc5623_hpr_out_input_enum =
-SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 8, 2, alc5623_hpr_out_input_sel);
-static const struct snd_kcontrol_new alc5623_hpr_out_mux_controls =
-SOC_DAPM_ENUM("Route", alc5623_hpr_out_input_enum);
-
-/* speaker output N select */
-static const struct soc_enum alc5623_spk_n_sour_enum =
-SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 14, 4, alc5623_spk_n_sour_sel);
-static const struct snd_kcontrol_new alc5623_spkoutn_mux_controls =
-SOC_DAPM_ENUM("Route", alc5623_spk_n_sour_enum);
-
-static const struct snd_soc_dapm_widget alc5623_dapm_widgets[] = {
-/* Muxes */
-SND_SOC_DAPM_MUX("AuxOut Mux", SND_SOC_NOPM, 0, 0,
- &alc5623_auxout_mux_controls),
-SND_SOC_DAPM_MUX("SpeakerOut Mux", SND_SOC_NOPM, 0, 0,
- &alc5623_spkout_mux_controls),
-SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0,
- &alc5623_hpl_out_mux_controls),
-SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0,
- &alc5623_hpr_out_mux_controls),
-SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0,
- &alc5623_spkoutn_mux_controls),
-
-/* output mixers */
-SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0,
- &alc5623_hp_mixer_controls[0],
- ARRAY_SIZE(alc5623_hp_mixer_controls)),
-SND_SOC_DAPM_MIXER("HPR Mix", ALC5623_PWR_MANAG_ADD2, 4, 0,
- &alc5623_hpr_mixer_controls[0],
- ARRAY_SIZE(alc5623_hpr_mixer_controls)),
-SND_SOC_DAPM_MIXER("HPL Mix", ALC5623_PWR_MANAG_ADD2, 5, 0,
- &alc5623_hpl_mixer_controls[0],
- ARRAY_SIZE(alc5623_hpl_mixer_controls)),
-SND_SOC_DAPM_MIXER("HPOut Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("Mono Mix", ALC5623_PWR_MANAG_ADD2, 2, 0,
- &alc5623_mono_mixer_controls[0],
- ARRAY_SIZE(alc5623_mono_mixer_controls)),
-SND_SOC_DAPM_MIXER("Speaker Mix", ALC5623_PWR_MANAG_ADD2, 3, 0,
- &alc5623_speaker_mixer_controls[0],
- ARRAY_SIZE(alc5623_speaker_mixer_controls)),
-
-/* input mixers */
-SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5623_PWR_MANAG_ADD2, 1, 0,
- &alc5623_captureL_mixer_controls[0],
- ARRAY_SIZE(alc5623_captureL_mixer_controls)),
-SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5623_PWR_MANAG_ADD2, 0, 0,
- &alc5623_captureR_mixer_controls[0],
- ARRAY_SIZE(alc5623_captureR_mixer_controls)),
-
-SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback",
- ALC5623_PWR_MANAG_ADD2, 9, 0),
-SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback",
- ALC5623_PWR_MANAG_ADD2, 8, 0),
-SND_SOC_DAPM_MIXER("I2S Mix", ALC5623_PWR_MANAG_ADD1, 15, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("AuxI Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture",
- ALC5623_PWR_MANAG_ADD2, 7, 0),
-SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture",
- ALC5623_PWR_MANAG_ADD2, 6, 0),
-SND_SOC_DAPM_PGA("Left Headphone", ALC5623_PWR_MANAG_ADD3, 10, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right Headphone", ALC5623_PWR_MANAG_ADD3, 9, 0, NULL, 0),
-SND_SOC_DAPM_PGA("SpeakerOut", ALC5623_PWR_MANAG_ADD3, 12, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Left AuxOut", ALC5623_PWR_MANAG_ADD3, 14, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right AuxOut", ALC5623_PWR_MANAG_ADD3, 13, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Left LineIn", ALC5623_PWR_MANAG_ADD3, 7, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right LineIn", ALC5623_PWR_MANAG_ADD3, 6, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Left AuxI", ALC5623_PWR_MANAG_ADD3, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right AuxI", ALC5623_PWR_MANAG_ADD3, 4, 0, NULL, 0),
-SND_SOC_DAPM_PGA("MIC1 PGA", ALC5623_PWR_MANAG_ADD3, 3, 0, NULL, 0),
-SND_SOC_DAPM_PGA("MIC2 PGA", ALC5623_PWR_MANAG_ADD3, 2, 0, NULL, 0),
-SND_SOC_DAPM_PGA("MIC1 Pre Amp", ALC5623_PWR_MANAG_ADD3, 1, 0, NULL, 0),
-SND_SOC_DAPM_PGA("MIC2 Pre Amp", ALC5623_PWR_MANAG_ADD3, 0, 0, NULL, 0),
-SND_SOC_DAPM_MICBIAS("Mic Bias1", ALC5623_PWR_MANAG_ADD1, 11, 0),
-
-SND_SOC_DAPM_OUTPUT("AUXOUTL"),
-SND_SOC_DAPM_OUTPUT("AUXOUTR"),
-SND_SOC_DAPM_OUTPUT("HPL"),
-SND_SOC_DAPM_OUTPUT("HPR"),
-SND_SOC_DAPM_OUTPUT("SPKOUT"),
-SND_SOC_DAPM_OUTPUT("SPKOUTN"),
-SND_SOC_DAPM_INPUT("LINEINL"),
-SND_SOC_DAPM_INPUT("LINEINR"),
-SND_SOC_DAPM_INPUT("AUXINL"),
-SND_SOC_DAPM_INPUT("AUXINR"),
-SND_SOC_DAPM_INPUT("MIC1"),
-SND_SOC_DAPM_INPUT("MIC2"),
-SND_SOC_DAPM_VMID("Vmid"),
-};
-
-static const char *alc5623_amp_names[] = {"AB Amp", "D Amp"};
-static const struct soc_enum alc5623_amp_enum =
- SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 13, 2, alc5623_amp_names);
-static const struct snd_kcontrol_new alc5623_amp_mux_controls =
- SOC_DAPM_ENUM("Route", alc5623_amp_enum);
-
-static const struct snd_soc_dapm_widget alc5623_dapm_amp_widgets[] = {
-SND_SOC_DAPM_PGA_E("D Amp", ALC5623_PWR_MANAG_ADD2, 14, 0, NULL, 0,
- amp_mixer_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-SND_SOC_DAPM_PGA("AB Amp", ALC5623_PWR_MANAG_ADD2, 15, 0, NULL, 0),
-SND_SOC_DAPM_MUX("AB-D Amp Mux", SND_SOC_NOPM, 0, 0,
- &alc5623_amp_mux_controls),
-};
-
-static const struct snd_soc_dapm_route intercon[] = {
- /* virtual mixer - mixes left & right channels */
- {"I2S Mix", NULL, "Left DAC"},
- {"I2S Mix", NULL, "Right DAC"},
- {"Line Mix", NULL, "Right LineIn"},
- {"Line Mix", NULL, "Left LineIn"},
- {"AuxI Mix", NULL, "Left AuxI"},
- {"AuxI Mix", NULL, "Right AuxI"},
- {"AUXOUTL", NULL, "Left AuxOut"},
- {"AUXOUTR", NULL, "Right AuxOut"},
-
- /* HP mixer */
- {"HPL Mix", "ADC2HP_L Playback Switch", "Left Capture Mix"},
- {"HPL Mix", NULL, "HP Mix"},
- {"HPR Mix", "ADC2HP_R Playback Switch", "Right Capture Mix"},
- {"HPR Mix", NULL, "HP Mix"},
- {"HP Mix", "LI2HP Playback Switch", "Line Mix"},
- {"HP Mix", "AUXI2HP Playback Switch", "AuxI Mix"},
- {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"},
- {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"},
- {"HP Mix", "DAC2HP Playback Switch", "I2S Mix"},
-
- /* speaker mixer */
- {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"},
- {"Speaker Mix", "AUXI2SPK Playback Switch", "AuxI Mix"},
- {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"},
- {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"},
- {"Speaker Mix", "DAC2SPK Playback Switch", "I2S Mix"},
-
- /* mono mixer */
- {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"},
- {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"},
- {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"},
- {"Mono Mix", "AUXI2MONO Playback Switch", "AuxI Mix"},
- {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"},
- {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"},
- {"Mono Mix", "DAC2MONO Playback Switch", "I2S Mix"},
-
- /* Left record mixer */
- {"Left Capture Mix", "LineInL Capture Switch", "LINEINL"},
- {"Left Capture Mix", "Left AuxI Capture Switch", "AUXINL"},
- {"Left Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"},
- {"Left Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"},
- {"Left Capture Mix", "HPMixerL Capture Switch", "HPL Mix"},
- {"Left Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
- {"Left Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
-
- /*Right record mixer */
- {"Right Capture Mix", "LineInR Capture Switch", "LINEINR"},
- {"Right Capture Mix", "Right AuxI Capture Switch", "AUXINR"},
- {"Right Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"},
- {"Right Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"},
- {"Right Capture Mix", "HPMixerR Capture Switch", "HPR Mix"},
- {"Right Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
- {"Right Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
-
- /* headphone left mux */
- {"Left Headphone Mux", "HP Left Mix", "HPL Mix"},
- {"Left Headphone Mux", "Vmid", "Vmid"},
-
- /* headphone right mux */
- {"Right Headphone Mux", "HP Right Mix", "HPR Mix"},
- {"Right Headphone Mux", "Vmid", "Vmid"},
-
- /* speaker out mux */
- {"SpeakerOut Mux", "Vmid", "Vmid"},
- {"SpeakerOut Mux", "HPOut Mix", "HPOut Mix"},
- {"SpeakerOut Mux", "Speaker Mix", "Speaker Mix"},
- {"SpeakerOut Mux", "Mono Mix", "Mono Mix"},
-
- /* Mono/Aux Out mux */
- {"AuxOut Mux", "Vmid", "Vmid"},
- {"AuxOut Mux", "HPOut Mix", "HPOut Mix"},
- {"AuxOut Mux", "Speaker Mix", "Speaker Mix"},
- {"AuxOut Mux", "Mono Mix", "Mono Mix"},
-
- /* output pga */
- {"HPL", NULL, "Left Headphone"},
- {"Left Headphone", NULL, "Left Headphone Mux"},
- {"HPR", NULL, "Right Headphone"},
- {"Right Headphone", NULL, "Right Headphone Mux"},
- {"Left AuxOut", NULL, "AuxOut Mux"},
- {"Right AuxOut", NULL, "AuxOut Mux"},
-
- /* input pga */
- {"Left LineIn", NULL, "LINEINL"},
- {"Right LineIn", NULL, "LINEINR"},
- {"Left AuxI", NULL, "AUXINL"},
- {"Right AuxI", NULL, "AUXINR"},
- {"MIC1 Pre Amp", NULL, "MIC1"},
- {"MIC2 Pre Amp", NULL, "MIC2"},
- {"MIC1 PGA", NULL, "MIC1 Pre Amp"},
- {"MIC2 PGA", NULL, "MIC2 Pre Amp"},
-
- /* left ADC */
- {"Left ADC", NULL, "Left Capture Mix"},
-
- /* right ADC */
- {"Right ADC", NULL, "Right Capture Mix"},
-
- {"SpeakerOut N Mux", "RN/-R", "SpeakerOut"},
- {"SpeakerOut N Mux", "RP/+R", "SpeakerOut"},
- {"SpeakerOut N Mux", "LN/-R", "SpeakerOut"},
- {"SpeakerOut N Mux", "Vmid", "Vmid"},
-
- {"SPKOUT", NULL, "SpeakerOut"},
- {"SPKOUTN", NULL, "SpeakerOut N Mux"},
-};
-
-static const struct snd_soc_dapm_route intercon_spk[] = {
- {"SpeakerOut", NULL, "SpeakerOut Mux"},
-};
-
-static const struct snd_soc_dapm_route intercon_amp_spk[] = {
- {"AB Amp", NULL, "SpeakerOut Mux"},
- {"D Amp", NULL, "SpeakerOut Mux"},
- {"AB-D Amp Mux", "AB Amp", "AB Amp"},
- {"AB-D Amp Mux", "D Amp", "D Amp"},
- {"SpeakerOut", NULL, "AB-D Amp Mux"},
-};
-
-/* PLL divisors */
-struct _pll_div {
- u32 pll_in;
- u32 pll_out;
- u16 regvalue;
-};
-
-/* Note : pll code from original alc5623 driver. Not sure of how good it is */
-/* useful only for master mode */
-static const struct _pll_div codec_master_pll_div[] = {
-
- { 2048000, 8192000, 0x0ea0},
- { 3686400, 8192000, 0x4e27},
- { 12000000, 8192000, 0x456b},
- { 13000000, 8192000, 0x495f},
- { 13100000, 8192000, 0x0320},
- { 2048000, 11289600, 0xf637},
- { 3686400, 11289600, 0x2f22},
- { 12000000, 11289600, 0x3e2f},
- { 13000000, 11289600, 0x4d5b},
- { 13100000, 11289600, 0x363b},
- { 2048000, 16384000, 0x1ea0},
- { 3686400, 16384000, 0x9e27},
- { 12000000, 16384000, 0x452b},
- { 13000000, 16384000, 0x542f},
- { 13100000, 16384000, 0x03a0},
- { 2048000, 16934400, 0xe625},
- { 3686400, 16934400, 0x9126},
- { 12000000, 16934400, 0x4d2c},
- { 13000000, 16934400, 0x742f},
- { 13100000, 16934400, 0x3c27},
- { 2048000, 22579200, 0x2aa0},
- { 3686400, 22579200, 0x2f20},
- { 12000000, 22579200, 0x7e2f},
- { 13000000, 22579200, 0x742f},
- { 13100000, 22579200, 0x3c27},
- { 2048000, 24576000, 0x2ea0},
- { 3686400, 24576000, 0xee27},
- { 12000000, 24576000, 0x2915},
- { 13000000, 24576000, 0x772e},
- { 13100000, 24576000, 0x0d20},
-};
-
-static const struct _pll_div codec_slave_pll_div[] = {
-
- { 1024000, 16384000, 0x3ea0},
- { 1411200, 22579200, 0x3ea0},
- { 1536000, 24576000, 0x3ea0},
- { 2048000, 16384000, 0x1ea0},
- { 2822400, 22579200, 0x1ea0},
- { 3072000, 24576000, 0x1ea0},
-
-};
-
-static int alc5623_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
- int source, unsigned int freq_in, unsigned int freq_out)
-{
- int i;
- struct snd_soc_codec *codec = codec_dai->codec;
- int gbl_clk = 0, pll_div = 0;
- u16 reg;
-
- if (pll_id < ALC5623_PLL_FR_MCLK || pll_id > ALC5623_PLL_FR_BCK)
- return -ENODEV;
-
- /* Disable PLL power */
- snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD2,
- ALC5623_PWR_ADD2_PLL,
- 0);
-
- /* pll is not used in slave mode */
- reg = snd_soc_read(codec, ALC5623_DAI_CONTROL);
- if (reg & ALC5623_DAI_SDP_SLAVE_MODE)
- return 0;
-
- if (!freq_in || !freq_out)
- return 0;
-
- switch (pll_id) {
- case ALC5623_PLL_FR_MCLK:
- for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++) {
- if (codec_master_pll_div[i].pll_in == freq_in
- && codec_master_pll_div[i].pll_out == freq_out) {
- /* PLL source from MCLK */
- pll_div = codec_master_pll_div[i].regvalue;
- break;
- }
- }
- break;
- case ALC5623_PLL_FR_BCK:
- for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) {
- if (codec_slave_pll_div[i].pll_in == freq_in
- && codec_slave_pll_div[i].pll_out == freq_out) {
- /* PLL source from Bitclk */
- gbl_clk = ALC5623_GBL_CLK_PLL_SOUR_SEL_BITCLK;
- pll_div = codec_slave_pll_div[i].regvalue;
- break;
- }
- }
- break;
- default:
- return -EINVAL;
- }
-
- if (!pll_div)
- return -EINVAL;
-
- snd_soc_write(codec, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk);
- snd_soc_write(codec, ALC5623_PLL_CTRL, pll_div);
- snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD2,
- ALC5623_PWR_ADD2_PLL,
- ALC5623_PWR_ADD2_PLL);
- gbl_clk |= ALC5623_GBL_CLK_SYS_SOUR_SEL_PLL;
- snd_soc_write(codec, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk);
-
- return 0;
-}
-
-struct _coeff_div {
- u16 fs;
- u16 regvalue;
-};
-
-/* codec hifi mclk (after PLL) clock divider coefficients */
-/* values inspired from column BCLK=32Fs of Appendix A table */
-static const struct _coeff_div coeff_div[] = {
- {256*8, 0x3a69},
- {384*8, 0x3c6b},
- {256*4, 0x2a69},
- {384*4, 0x2c6b},
- {256*2, 0x1a69},
- {384*2, 0x1c6b},
- {256*1, 0x0a69},
- {384*1, 0x0c6b},
-};
-
-static int get_coeff(struct snd_soc_codec *codec, int rate)
-{
- struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
- int i;
-
- for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
- if (coeff_div[i].fs * rate == alc5623->sysclk)
- return i;
- }
- return -EINVAL;
-}
-
-/*
- * Clock after PLL and dividers
- */
-static int alc5623_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
-
- switch (freq) {
- case 8192000:
- case 11289600:
- case 12288000:
- case 16384000:
- case 16934400:
- case 18432000:
- case 22579200:
- case 24576000:
- alc5623->sysclk = freq;
- return 0;
- }
- return -EINVAL;
-}
-
-static int alc5623_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 iface = 0;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- iface = ALC5623_DAI_SDP_MASTER_MODE;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- iface = ALC5623_DAI_SDP_SLAVE_MODE;
- break;
- default:
- return -EINVAL;
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= ALC5623_DAI_I2S_DF_I2S;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- iface |= ALC5623_DAI_I2S_DF_RIGHT;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= ALC5623_DAI_I2S_DF_LEFT;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= ALC5623_DAI_I2S_DF_PCM;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- iface |= ALC5623_DAI_I2S_DF_PCM | ALC5623_DAI_I2S_PCM_MODE;
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- break;
- default:
- return -EINVAL;
- }
-
- return snd_soc_write(codec, ALC5623_DAI_CONTROL, iface);
-}
-
-static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
- int coeff, rate;
- u16 iface;
-
- iface = snd_soc_read(codec, ALC5623_DAI_CONTROL);
- iface &= ~ALC5623_DAI_I2S_DL_MASK;
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- iface |= ALC5623_DAI_I2S_DL_16;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= ALC5623_DAI_I2S_DL_20;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface |= ALC5623_DAI_I2S_DL_24;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- iface |= ALC5623_DAI_I2S_DL_32;
- break;
- default:
- return -EINVAL;
- }
-
- /* set iface & srate */
- snd_soc_write(codec, ALC5623_DAI_CONTROL, iface);
- rate = params_rate(params);
- coeff = get_coeff(codec, rate);
- if (coeff < 0)
- return -EINVAL;
-
- coeff = coeff_div[coeff].regvalue;
- dev_dbg(codec->dev, "%s: sysclk=%d,rate=%d,coeff=0x%04x\n",
- __func__, alc5623->sysclk, rate, coeff);
- snd_soc_write(codec, ALC5623_STEREO_AD_DA_CLK_CTRL, coeff);
-
- return 0;
-}
-
-static int alc5623_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 hp_mute = ALC5623_MISC_M_DAC_L_INPUT | ALC5623_MISC_M_DAC_R_INPUT;
- u16 mute_reg = snd_soc_read(codec, ALC5623_MISC_CTRL) & ~hp_mute;
-
- if (mute)
- mute_reg |= hp_mute;
-
- return snd_soc_write(codec, ALC5623_MISC_CTRL, mute_reg);
-}
-
-#define ALC5623_ADD2_POWER_EN (ALC5623_PWR_ADD2_VREF \
- | ALC5623_PWR_ADD2_DAC_REF_CIR)
-
-#define ALC5623_ADD3_POWER_EN (ALC5623_PWR_ADD3_MAIN_BIAS \
- | ALC5623_PWR_ADD3_MIC1_BOOST_AD)
-
-#define ALC5623_ADD1_POWER_EN \
- (ALC5623_PWR_ADD1_SHORT_CURR_DET_EN | ALC5623_PWR_ADD1_SOFTGEN_EN \
- | ALC5623_PWR_ADD1_DEPOP_BUF_HP | ALC5623_PWR_ADD1_HP_OUT_AMP \
- | ALC5623_PWR_ADD1_HP_OUT_ENH_AMP)
-
-#define ALC5623_ADD1_POWER_EN_5622 \
- (ALC5623_PWR_ADD1_SHORT_CURR_DET_EN \
- | ALC5623_PWR_ADD1_HP_OUT_AMP)
-
-static void enable_power_depop(struct snd_soc_codec *codec)
-{
- struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
-
- snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD1,
- ALC5623_PWR_ADD1_SOFTGEN_EN,
- ALC5623_PWR_ADD1_SOFTGEN_EN);
-
- snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, ALC5623_ADD3_POWER_EN);
-
- snd_soc_update_bits(codec, ALC5623_MISC_CTRL,
- ALC5623_MISC_HP_DEPOP_MODE2_EN,
- ALC5623_MISC_HP_DEPOP_MODE2_EN);
-
- msleep(500);
-
- snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, ALC5623_ADD2_POWER_EN);
-
- /* avoid writing '1' into 5622 reserved bits */
- if (alc5623->id == 0x22)
- snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1,
- ALC5623_ADD1_POWER_EN_5622);
- else
- snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1,
- ALC5623_ADD1_POWER_EN);
-
- /* disable HP Depop2 */
- snd_soc_update_bits(codec, ALC5623_MISC_CTRL,
- ALC5623_MISC_HP_DEPOP_MODE2_EN,
- 0);
-
-}
-
-static int alc5623_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- switch (level) {
- case SND_SOC_BIAS_ON:
- enable_power_depop(codec);
- break;
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- /* everything off except vref/vmid, */
- snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2,
- ALC5623_PWR_ADD2_VREF);
- snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3,
- ALC5623_PWR_ADD3_MAIN_BIAS);
- break;
- case SND_SOC_BIAS_OFF:
- /* everything off, dac mute, inactive */
- snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, 0);
- snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, 0);
- snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, 0);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define ALC5623_FORMATS (SNDRV_PCM_FMTBIT_S16_LE \
- | SNDRV_PCM_FMTBIT_S24_LE \
- | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops alc5623_dai_ops = {
- .hw_params = alc5623_pcm_hw_params,
- .digital_mute = alc5623_mute,
- .set_fmt = alc5623_set_dai_fmt,
- .set_sysclk = alc5623_set_dai_sysclk,
- .set_pll = alc5623_set_dai_pll,
-};
-
-static struct snd_soc_dai_driver alc5623_dai = {
- .name = "alc5623-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rate_min = 8000,
- .rate_max = 48000,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = ALC5623_FORMATS,},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rate_min = 8000,
- .rate_max = 48000,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = ALC5623_FORMATS,},
-
- .ops = &alc5623_dai_ops,
-};
-
-static int alc5623_suspend(struct snd_soc_codec *codec)
-{
- alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int alc5623_resume(struct snd_soc_codec *codec)
-{
- int i, step = codec->driver->reg_cache_step;
- u16 *cache = codec->reg_cache;
-
- /* Sync reg_cache with the hardware */
- for (i = 2 ; i < codec->driver->reg_cache_size ; i += step)
- snd_soc_write(codec, i, cache[i]);
-
- alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* charge alc5623 caps */
- if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
- alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- codec->dapm.bias_level = SND_SOC_BIAS_ON;
- alc5623_set_bias_level(codec, codec->dapm.bias_level);
- }
-
- return 0;
-}
-
-static int alc5623_probe(struct snd_soc_codec *codec)
-{
- struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, alc5623->control_type);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- alc5623_reset(codec);
- alc5623_fill_cache(codec);
-
- /* power on device */
- alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- if (alc5623->add_ctrl) {
- snd_soc_write(codec, ALC5623_ADD_CTRL_REG,
- alc5623->add_ctrl);
- }
-
- if (alc5623->jack_det_ctrl) {
- snd_soc_write(codec, ALC5623_JACK_DET_CTRL,
- alc5623->jack_det_ctrl);
- }
-
- switch (alc5623->id) {
- case 0x21:
- snd_soc_add_codec_controls(codec, alc5621_vol_snd_controls,
- ARRAY_SIZE(alc5621_vol_snd_controls));
- break;
- case 0x22:
- snd_soc_add_codec_controls(codec, alc5622_vol_snd_controls,
- ARRAY_SIZE(alc5622_vol_snd_controls));
- break;
- case 0x23:
- snd_soc_add_codec_controls(codec, alc5623_vol_snd_controls,
- ARRAY_SIZE(alc5623_vol_snd_controls));
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_add_codec_controls(codec, alc5623_snd_controls,
- ARRAY_SIZE(alc5623_snd_controls));
-
- snd_soc_dapm_new_controls(dapm, alc5623_dapm_widgets,
- ARRAY_SIZE(alc5623_dapm_widgets));
-
- /* set up audio path interconnects */
- snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
-
- switch (alc5623->id) {
- case 0x21:
- case 0x22:
- snd_soc_dapm_new_controls(dapm, alc5623_dapm_amp_widgets,
- ARRAY_SIZE(alc5623_dapm_amp_widgets));
- snd_soc_dapm_add_routes(dapm, intercon_amp_spk,
- ARRAY_SIZE(intercon_amp_spk));
- break;
- case 0x23:
- snd_soc_dapm_add_routes(dapm, intercon_spk,
- ARRAY_SIZE(intercon_spk));
- break;
- default:
- return -EINVAL;
- }
-
- return ret;
-}
-
-/* power down chip */
-static int alc5623_remove(struct snd_soc_codec *codec)
-{
- alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_device_alc5623 = {
- .probe = alc5623_probe,
- .remove = alc5623_remove,
- .suspend = alc5623_suspend,
- .resume = alc5623_resume,
- .set_bias_level = alc5623_set_bias_level,
- .reg_cache_size = ALC5623_VENDOR_ID2+2,
- .reg_word_size = sizeof(u16),
- .reg_cache_step = 2,
-};
-
-/*
- * ALC5623 2 wire address is determined by A1 pin
- * state during powerup.
- * low = 0x1a
- * high = 0x1b
- */
-static __devinit int alc5623_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct alc5623_platform_data *pdata;
- struct alc5623_priv *alc5623;
- int ret, vid1, vid2;
-
- vid1 = i2c_smbus_read_word_data(client, ALC5623_VENDOR_ID1);
- if (vid1 < 0) {
- dev_err(&client->dev, "failed to read I2C\n");
- return -EIO;
- }
- vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8);
-
- vid2 = i2c_smbus_read_byte_data(client, ALC5623_VENDOR_ID2);
- if (vid2 < 0) {
- dev_err(&client->dev, "failed to read I2C\n");
- return -EIO;
- }
-
- if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) {
- dev_err(&client->dev, "unknown or wrong codec\n");
- dev_err(&client->dev, "Expected %x:%lx, got %x:%x\n",
- 0x10ec, id->driver_data,
- vid1, vid2);
- return -ENODEV;
- }
-
- dev_dbg(&client->dev, "Found codec id : alc56%02x\n", vid2);
-
- alc5623 = devm_kzalloc(&client->dev, sizeof(struct alc5623_priv),
- GFP_KERNEL);
- if (alc5623 == NULL)
- return -ENOMEM;
-
- pdata = client->dev.platform_data;
- if (pdata) {
- alc5623->add_ctrl = pdata->add_ctrl;
- alc5623->jack_det_ctrl = pdata->jack_det_ctrl;
- }
-
- alc5623->id = vid2;
- switch (alc5623->id) {
- case 0x21:
- alc5623_dai.name = "alc5621-hifi";
- break;
- case 0x22:
- alc5623_dai.name = "alc5622-hifi";
- break;
- case 0x23:
- alc5623_dai.name = "alc5623-hifi";
- break;
- default:
- return -EINVAL;
- }
-
- i2c_set_clientdata(client, alc5623);
- alc5623->control_type = SND_SOC_I2C;
-
- ret = snd_soc_register_codec(&client->dev,
- &soc_codec_device_alc5623, &alc5623_dai, 1);
- if (ret != 0)
- dev_err(&client->dev, "Failed to register codec: %d\n", ret);
-
- return ret;
-}
-
-static __devexit int alc5623_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static const struct i2c_device_id alc5623_i2c_table[] = {
- {"alc5621", 0x21},
- {"alc5622", 0x22},
- {"alc5623", 0x23},
- {}
-};
-MODULE_DEVICE_TABLE(i2c, alc5623_i2c_table);
-
-/* i2c codec control layer */
-static struct i2c_driver alc5623_i2c_driver = {
- .driver = {
- .name = "alc562x-codec",
- .owner = THIS_MODULE,
- },
- .probe = alc5623_i2c_probe,
- .remove = __devexit_p(alc5623_i2c_remove),
- .id_table = alc5623_i2c_table,
-};
-
-static int __init alc5623_modinit(void)
-{
- int ret;
-
- ret = i2c_add_driver(&alc5623_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "%s: can't add i2c driver", __func__);
- return ret;
- }
-
- return ret;
-}
-module_init(alc5623_modinit);
-
-static void __exit alc5623_modexit(void)
-{
- i2c_del_driver(&alc5623_i2c_driver);
-}
-module_exit(alc5623_modexit);
-
-MODULE_DESCRIPTION("ASoC alc5621/2/3 driver");
-MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/alc5623.h b/ANDROID_3.4.5/sound/soc/codecs/alc5623.h
deleted file mode 100644
index f3d68260..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/alc5623.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * alc5623.h -- alc562[123] ALSA Soc Audio driver
- *
- * Copyright 2008 Realtek Microelectronics
- * Copyright 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
- *
- * Author: flove <flove@realtek.com>
- * Arnaud Patard <arnaud.patard@rtp-net.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#ifndef _ALC5623_H
-#define _ALC5623_H
-
-#define ALC5623_RESET 0x00
-/* 5621 5622 5623 */
-/* speaker output vol 2 2 */
-/* line output vol 4 2 */
-/* HP output vol 4 0 4 */
-#define ALC5623_SPK_OUT_VOL 0x02
-#define ALC5623_HP_OUT_VOL 0x04
-#define ALC5623_MONO_AUX_OUT_VOL 0x06
-#define ALC5623_AUXIN_VOL 0x08
-#define ALC5623_LINE_IN_VOL 0x0A
-#define ALC5623_STEREO_DAC_VOL 0x0C
-#define ALC5623_MIC_VOL 0x0E
-#define ALC5623_MIC_ROUTING_CTRL 0x10
-#define ALC5623_ADC_REC_GAIN 0x12
-#define ALC5623_ADC_REC_MIXER 0x14
-#define ALC5623_SOFT_VOL_CTRL_TIME 0x16
-/* ALC5623_OUTPUT_MIXER_CTRL : */
-/* same remark as for reg 2 line vs speaker */
-#define ALC5623_OUTPUT_MIXER_CTRL 0x1C
-#define ALC5623_MIC_CTRL 0x22
-
-#define ALC5623_DAI_CONTROL 0x34
-#define ALC5623_DAI_SDP_MASTER_MODE (0 << 15)
-#define ALC5623_DAI_SDP_SLAVE_MODE (1 << 15)
-#define ALC5623_DAI_I2S_PCM_MODE (1 << 14)
-#define ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL (1 << 7)
-#define ALC5623_DAI_ADC_DATA_L_R_SWAP (1 << 5)
-#define ALC5623_DAI_DAC_DATA_L_R_SWAP (1 << 4)
-#define ALC5623_DAI_I2S_DL_MASK (3 << 2)
-#define ALC5623_DAI_I2S_DL_32 (3 << 2)
-#define ALC5623_DAI_I2S_DL_24 (2 << 2)
-#define ALC5623_DAI_I2S_DL_20 (1 << 2)
-#define ALC5623_DAI_I2S_DL_16 (0 << 2)
-#define ALC5623_DAI_I2S_DF_PCM (3 << 0)
-#define ALC5623_DAI_I2S_DF_LEFT (2 << 0)
-#define ALC5623_DAI_I2S_DF_RIGHT (1 << 0)
-#define ALC5623_DAI_I2S_DF_I2S (0 << 0)
-
-#define ALC5623_STEREO_AD_DA_CLK_CTRL 0x36
-#define ALC5623_COMPANDING_CTRL 0x38
-
-#define ALC5623_PWR_MANAG_ADD1 0x3A
-#define ALC5623_PWR_ADD1_MAIN_I2S_EN (1 << 15)
-#define ALC5623_PWR_ADD1_ZC_DET_PD_EN (1 << 14)
-#define ALC5623_PWR_ADD1_MIC1_BIAS_EN (1 << 11)
-#define ALC5623_PWR_ADD1_SHORT_CURR_DET_EN (1 << 10)
-#define ALC5623_PWR_ADD1_SOFTGEN_EN (1 << 8) /* rsvd on 5622 */
-#define ALC5623_PWR_ADD1_DEPOP_BUF_HP (1 << 6) /* rsvd on 5622 */
-#define ALC5623_PWR_ADD1_HP_OUT_AMP (1 << 5)
-#define ALC5623_PWR_ADD1_HP_OUT_ENH_AMP (1 << 4) /* rsvd on 5622 */
-#define ALC5623_PWR_ADD1_DEPOP_BUF_AUX (1 << 2)
-#define ALC5623_PWR_ADD1_AUX_OUT_AMP (1 << 1)
-#define ALC5623_PWR_ADD1_AUX_OUT_ENH_AMP (1 << 0) /* rsvd on 5622 */
-
-#define ALC5623_PWR_MANAG_ADD2 0x3C
-#define ALC5623_PWR_ADD2_LINEOUT (1 << 15) /* rt5623 */
-#define ALC5623_PWR_ADD2_CLASS_AB (1 << 15) /* rt5621 */
-#define ALC5623_PWR_ADD2_CLASS_D (1 << 14) /* rt5621 */
-#define ALC5623_PWR_ADD2_VREF (1 << 13)
-#define ALC5623_PWR_ADD2_PLL (1 << 12)
-#define ALC5623_PWR_ADD2_DAC_REF_CIR (1 << 10)
-#define ALC5623_PWR_ADD2_L_DAC_CLK (1 << 9)
-#define ALC5623_PWR_ADD2_R_DAC_CLK (1 << 8)
-#define ALC5623_PWR_ADD2_L_ADC_CLK_GAIN (1 << 7)
-#define ALC5623_PWR_ADD2_R_ADC_CLK_GAIN (1 << 6)
-#define ALC5623_PWR_ADD2_L_HP_MIXER (1 << 5)
-#define ALC5623_PWR_ADD2_R_HP_MIXER (1 << 4)
-#define ALC5623_PWR_ADD2_SPK_MIXER (1 << 3)
-#define ALC5623_PWR_ADD2_MONO_MIXER (1 << 2)
-#define ALC5623_PWR_ADD2_L_ADC_REC_MIXER (1 << 1)
-#define ALC5623_PWR_ADD2_R_ADC_REC_MIXER (1 << 0)
-
-#define ALC5623_PWR_MANAG_ADD3 0x3E
-#define ALC5623_PWR_ADD3_MAIN_BIAS (1 << 15)
-#define ALC5623_PWR_ADD3_AUXOUT_L_VOL_AMP (1 << 14)
-#define ALC5623_PWR_ADD3_AUXOUT_R_VOL_AMP (1 << 13)
-#define ALC5623_PWR_ADD3_SPK_OUT (1 << 12)
-#define ALC5623_PWR_ADD3_HP_L_OUT_VOL (1 << 10)
-#define ALC5623_PWR_ADD3_HP_R_OUT_VOL (1 << 9)
-#define ALC5623_PWR_ADD3_LINEIN_L_VOL (1 << 7)
-#define ALC5623_PWR_ADD3_LINEIN_R_VOL (1 << 6)
-#define ALC5623_PWR_ADD3_AUXIN_L_VOL (1 << 5)
-#define ALC5623_PWR_ADD3_AUXIN_R_VOL (1 << 4)
-#define ALC5623_PWR_ADD3_MIC1_FUN_CTRL (1 << 3)
-#define ALC5623_PWR_ADD3_MIC2_FUN_CTRL (1 << 2)
-#define ALC5623_PWR_ADD3_MIC1_BOOST_AD (1 << 1)
-#define ALC5623_PWR_ADD3_MIC2_BOOST_AD (1 << 0)
-
-#define ALC5623_ADD_CTRL_REG 0x40
-
-#define ALC5623_GLOBAL_CLK_CTRL_REG 0x42
-#define ALC5623_GBL_CLK_SYS_SOUR_SEL_PLL (1 << 15)
-#define ALC5623_GBL_CLK_SYS_SOUR_SEL_MCLK (0 << 15)
-#define ALC5623_GBL_CLK_PLL_SOUR_SEL_BITCLK (1 << 14)
-#define ALC5623_GBL_CLK_PLL_SOUR_SEL_MCLK (0 << 14)
-#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV8 (3 << 1)
-#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV4 (2 << 1)
-#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV2 (1 << 1)
-#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV1 (0 << 1)
-#define ALC5623_GBL_CLK_PLL_PRE_DIV2 (1 << 0)
-#define ALC5623_GBL_CLK_PLL_PRE_DIV1 (0 << 0)
-
-#define ALC5623_PLL_CTRL 0x44
-#define ALC5623_PLL_CTRL_N_VAL(n) (((n)&0xff) << 8)
-#define ALC5623_PLL_CTRL_K_VAL(k) (((k)&0x7) << 4)
-#define ALC5623_PLL_CTRL_M_VAL(m) ((m)&0xf)
-
-#define ALC5623_GPIO_OUTPUT_PIN_CTRL 0x4A
-#define ALC5623_GPIO_PIN_CONFIG 0x4C
-#define ALC5623_GPIO_PIN_POLARITY 0x4E
-#define ALC5623_GPIO_PIN_STICKY 0x50
-#define ALC5623_GPIO_PIN_WAKEUP 0x52
-#define ALC5623_GPIO_PIN_STATUS 0x54
-#define ALC5623_GPIO_PIN_SHARING 0x56
-#define ALC5623_OVER_CURR_STATUS 0x58
-#define ALC5623_JACK_DET_CTRL 0x5A
-
-#define ALC5623_MISC_CTRL 0x5E
-#define ALC5623_MISC_DISABLE_FAST_VREG (1 << 15)
-#define ALC5623_MISC_SPK_CLASS_AB_OC_PD (1 << 13) /* 5621 */
-#define ALC5623_MISC_SPK_CLASS_AB_OC_DET (1 << 12) /* 5621 */
-#define ALC5623_MISC_HP_DEPOP_MODE3_EN (1 << 10)
-#define ALC5623_MISC_HP_DEPOP_MODE2_EN (1 << 9)
-#define ALC5623_MISC_HP_DEPOP_MODE1_EN (1 << 8)
-#define ALC5623_MISC_AUXOUT_DEPOP_MODE3_EN (1 << 6)
-#define ALC5623_MISC_AUXOUT_DEPOP_MODE2_EN (1 << 5)
-#define ALC5623_MISC_AUXOUT_DEPOP_MODE1_EN (1 << 4)
-#define ALC5623_MISC_M_DAC_L_INPUT (1 << 3)
-#define ALC5623_MISC_M_DAC_R_INPUT (1 << 2)
-#define ALC5623_MISC_IRQOUT_INV_CTRL (1 << 0)
-
-#define ALC5623_PSEDUEO_SPATIAL_CTRL 0x60
-#define ALC5623_EQ_CTRL 0x62
-#define ALC5623_EQ_MODE_ENABLE 0x66
-#define ALC5623_AVC_CTRL 0x68
-#define ALC5623_HID_CTRL_INDEX 0x6A
-#define ALC5623_HID_CTRL_DATA 0x6C
-#define ALC5623_VENDOR_ID1 0x7C
-#define ALC5623_VENDOR_ID2 0x7E
-
-#define ALC5623_PLL_FR_MCLK 0
-#define ALC5623_PLL_FR_BCK 1
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/alc5632.c b/ANDROID_3.4.5/sound/soc/codecs/alc5632.c
deleted file mode 100644
index e2111e0c..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/alc5632.c
+++ /dev/null
@@ -1,1234 +0,0 @@
-/*
-* alc5632.c -- ALC5632 ALSA SoC Audio Codec
-*
-* Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
-*
-* Authors: Leon Romanovsky <leon@leon.nu>
-* Andrey Danin <danindrey@mail.ru>
-* Ilya Petrov <ilya.muromec@gmail.com>
-* Marc Dietrich <marvin24@gmx.de>
-*
-* Based on alc5623.c by Arnaud Patard
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License version 2 as
-* published by the Free Software Foundation.
-*/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/regmap.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/tlv.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-
-#include "alc5632.h"
-
-/*
- * ALC5632 register cache
- */
-static struct reg_default alc5632_reg_defaults[] = {
- { 2, 0x8080 }, /* R2 - Speaker Output Volume */
- { 4, 0x8080 }, /* R4 - Headphone Output Volume */
- { 6, 0x8080 }, /* R6 - AUXOUT Volume */
- { 8, 0xC800 }, /* R8 - Phone Input */
- { 10, 0xE808 }, /* R10 - LINE_IN Volume */
- { 12, 0x1010 }, /* R12 - STEREO DAC Input Volume */
- { 14, 0x0808 }, /* R14 - MIC Input Volume */
- { 16, 0xEE0F }, /* R16 - Stereo DAC and MIC Routing Control */
- { 18, 0xCBCB }, /* R18 - ADC Record Gain */
- { 20, 0x7F7F }, /* R20 - ADC Record Mixer Control */
- { 24, 0xE010 }, /* R24 - Voice DAC Volume */
- { 28, 0x8008 }, /* R28 - Output Mixer Control */
- { 34, 0x0000 }, /* R34 - Microphone Control */
- { 36, 0x00C0 }, /* R36 - Codec Digital MIC/Digital Boost
- Control */
- { 46, 0x0000 }, /* R46 - Stereo DAC/Voice DAC/Stereo ADC
- Function Select */
- { 52, 0x8000 }, /* R52 - Main Serial Data Port Control
- (Stereo I2S) */
- { 54, 0x0000 }, /* R54 - Extend Serial Data Port Control
- (VoDAC_I2S/PCM) */
- { 58, 0x0000 }, /* R58 - Power Management Addition 1 */
- { 60, 0x0000 }, /* R60 - Power Management Addition 2 */
- { 62, 0x8000 }, /* R62 - Power Management Addition 3 */
- { 64, 0x0C0A }, /* R64 - General Purpose Control Register 1 */
- { 66, 0x0000 }, /* R66 - General Purpose Control Register 2 */
- { 68, 0x0000 }, /* R68 - PLL1 Control */
- { 70, 0x0000 }, /* R70 - PLL2 Control */
- { 76, 0xBE3E }, /* R76 - GPIO Pin Configuration */
- { 78, 0xBE3E }, /* R78 - GPIO Pin Polarity */
- { 80, 0x0000 }, /* R80 - GPIO Pin Sticky */
- { 82, 0x0000 }, /* R82 - GPIO Pin Wake Up */
- { 86, 0x0000 }, /* R86 - Pin Sharing */
- { 90, 0x0009 }, /* R90 - Soft Volume Control Setting */
- { 92, 0x0000 }, /* R92 - GPIO_Output Pin Control */
- { 94, 0x3000 }, /* R94 - MISC Control */
- { 96, 0x3075 }, /* R96 - Stereo DAC Clock Control_1 */
- { 98, 0x1010 }, /* R98 - Stereo DAC Clock Control_2 */
- { 100, 0x3110 }, /* R100 - VoDAC_PCM Clock Control_1 */
- { 104, 0x0553 }, /* R104 - Pseudo Stereo and Spatial Effect
- Block Control */
- { 106, 0x0000 }, /* R106 - Private Register Address */
-};
-
-/* codec private data */
-struct alc5632_priv {
- struct regmap *regmap;
- u8 id;
- unsigned int sysclk;
-};
-
-static bool alc5632_volatile_register(struct device *dev,
- unsigned int reg)
-{
- switch (reg) {
- case ALC5632_RESET:
- case ALC5632_PWR_DOWN_CTRL_STATUS:
- case ALC5632_GPIO_PIN_STATUS:
- case ALC5632_OVER_CURR_STATUS:
- case ALC5632_HID_CTRL_DATA:
- case ALC5632_EQ_CTRL:
- case ALC5632_VENDOR_ID1:
- case ALC5632_VENDOR_ID2:
- return true;
-
- default:
- break;
- }
-
- return false;
-}
-
-static inline int alc5632_reset(struct regmap *map)
-{
- return regmap_write(map, ALC5632_RESET, 0x59B4);
-}
-
-static int amp_mixer_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- /* to power-on/off class-d amp generators/speaker */
- /* need to write to 'index-46h' register : */
- /* so write index num (here 0x46) to reg 0x6a */
- /* and then 0xffff/0 to reg 0x6c */
- snd_soc_write(w->codec, ALC5632_HID_CTRL_INDEX, 0x46);
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- snd_soc_write(w->codec, ALC5632_HID_CTRL_DATA, 0xFFFF);
- break;
- case SND_SOC_DAPM_POST_PMD:
- snd_soc_write(w->codec, ALC5632_HID_CTRL_DATA, 0);
- break;
- }
-
- return 0;
-}
-
-/*
- * ALC5632 Controls
- */
-
-/* -34.5db min scale, 1.5db steps, no mute */
-static const DECLARE_TLV_DB_SCALE(vol_tlv, -3450, 150, 0);
-/* -46.5db min scale, 1.5db steps, no mute */
-static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0);
-/* -16.5db min scale, 1.5db steps, no mute */
-static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0);
-static const unsigned int boost_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0),
- 1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0),
-};
-/* 0db min scale, 6 db steps, no mute */
-static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0);
-/* 0db min scalem 0.75db steps, no mute */
-static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 75, 0);
-
-static const struct snd_kcontrol_new alc5632_vol_snd_controls[] = {
- /* left starts at bit 8, right at bit 0 */
- /* 31 steps (5 bit), -46.5db scale */
- SOC_DOUBLE_TLV("Speaker Playback Volume",
- ALC5632_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
- /* bit 15 mutes left, bit 7 right */
- SOC_DOUBLE("Speaker Playback Switch",
- ALC5632_SPK_OUT_VOL, 15, 7, 1, 1),
- SOC_DOUBLE_TLV("Headphone Playback Volume",
- ALC5632_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),
- SOC_DOUBLE("Headphone Playback Switch",
- ALC5632_HP_OUT_VOL, 15, 7, 1, 1),
-};
-
-static const struct snd_kcontrol_new alc5632_snd_controls[] = {
- SOC_DOUBLE_TLV("Auxout Playback Volume",
- ALC5632_AUX_OUT_VOL, 8, 0, 31, 1, hp_tlv),
- SOC_DOUBLE("Auxout Playback Switch",
- ALC5632_AUX_OUT_VOL, 15, 7, 1, 1),
- SOC_SINGLE_TLV("Voice DAC Playback Volume",
- ALC5632_VOICE_DAC_VOL, 0, 63, 0, vdac_tlv),
- SOC_SINGLE("Voice DAC Playback Switch",
- ALC5632_VOICE_DAC_VOL, 12, 1, 1),
- SOC_SINGLE_TLV("Phone Playback Volume",
- ALC5632_PHONE_IN_VOL, 8, 31, 1, vol_tlv),
- SOC_DOUBLE_TLV("LineIn Playback Volume",
- ALC5632_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv),
- SOC_DOUBLE_TLV("Master Playback Volume",
- ALC5632_STEREO_DAC_IN_VOL, 8, 0, 63, 1, vdac_tlv),
- SOC_DOUBLE("Master Playback Switch",
- ALC5632_STEREO_DAC_IN_VOL, 15, 7, 1, 1),
- SOC_SINGLE_TLV("Mic1 Playback Volume",
- ALC5632_MIC_VOL, 8, 31, 1, vol_tlv),
- SOC_SINGLE_TLV("Mic2 Playback Volume",
- ALC5632_MIC_VOL, 0, 31, 1, vol_tlv),
- SOC_DOUBLE_TLV("Rec Capture Volume",
- ALC5632_ADC_REC_GAIN, 8, 0, 31, 0, adc_rec_tlv),
- SOC_SINGLE_TLV("Mic 1 Boost Volume",
- ALC5632_MIC_CTRL, 10, 3, 0, boost_tlv),
- SOC_SINGLE_TLV("Mic 2 Boost Volume",
- ALC5632_MIC_CTRL, 8, 3, 0, boost_tlv),
- SOC_SINGLE_TLV("DMIC Boost Capture Volume",
- ALC5632_DIGI_BOOST_CTRL, 0, 7, 0, dig_tlv),
- SOC_SINGLE("DMIC En Capture Switch",
- ALC5632_DIGI_BOOST_CTRL, 15, 1, 0),
- SOC_SINGLE("DMIC PreFilter Capture Switch",
- ALC5632_DIGI_BOOST_CTRL, 12, 1, 0),
-};
-
-/*
- * DAPM Controls
- */
-static const struct snd_kcontrol_new alc5632_hp_mixer_controls[] = {
-SOC_DAPM_SINGLE("LI2HP Playback Switch", ALC5632_LINE_IN_VOL, 15, 1, 1),
-SOC_DAPM_SINGLE("PHONE2HP Playback Switch", ALC5632_PHONE_IN_VOL, 15, 1, 1),
-SOC_DAPM_SINGLE("MIC12HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 15, 1, 1),
-SOC_DAPM_SINGLE("MIC22HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 11, 1, 1),
-SOC_DAPM_SINGLE("VOICE2HP Playback Switch", ALC5632_VOICE_DAC_VOL, 15, 1, 1),
-};
-
-static const struct snd_kcontrol_new alc5632_hpl_mixer_controls[] = {
-SOC_DAPM_SINGLE("ADC2HP_L Playback Switch", ALC5632_ADC_REC_GAIN, 15, 1, 1),
-SOC_DAPM_SINGLE("DACL2HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 3, 1, 1),
-};
-
-static const struct snd_kcontrol_new alc5632_hpr_mixer_controls[] = {
-SOC_DAPM_SINGLE("ADC2HP_R Playback Switch", ALC5632_ADC_REC_GAIN, 7, 1, 1),
-SOC_DAPM_SINGLE("DACR2HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 2, 1, 1),
-};
-
-static const struct snd_kcontrol_new alc5632_mono_mixer_controls[] = {
-SOC_DAPM_SINGLE("ADC2MONO_L Playback Switch", ALC5632_ADC_REC_GAIN, 14, 1, 1),
-SOC_DAPM_SINGLE("ADC2MONO_R Playback Switch", ALC5632_ADC_REC_GAIN, 6, 1, 1),
-SOC_DAPM_SINGLE("LI2MONO Playback Switch", ALC5632_LINE_IN_VOL, 13, 1, 1),
-SOC_DAPM_SINGLE("MIC12MONO Playback Switch",
- ALC5632_MIC_ROUTING_CTRL, 13, 1, 1),
-SOC_DAPM_SINGLE("MIC22MONO Playback Switch",
- ALC5632_MIC_ROUTING_CTRL, 9, 1, 1),
-SOC_DAPM_SINGLE("DAC2MONO Playback Switch", ALC5632_MIC_ROUTING_CTRL, 0, 1, 1),
-SOC_DAPM_SINGLE("VOICE2MONO Playback Switch", ALC5632_VOICE_DAC_VOL, 13, 1, 1),
-};
-
-static const struct snd_kcontrol_new alc5632_speaker_mixer_controls[] = {
-SOC_DAPM_SINGLE("LI2SPK Playback Switch", ALC5632_LINE_IN_VOL, 14, 1, 1),
-SOC_DAPM_SINGLE("PHONE2SPK Playback Switch", ALC5632_PHONE_IN_VOL, 14, 1, 1),
-SOC_DAPM_SINGLE("MIC12SPK Playback Switch",
- ALC5632_MIC_ROUTING_CTRL, 14, 1, 1),
-SOC_DAPM_SINGLE("MIC22SPK Playback Switch",
- ALC5632_MIC_ROUTING_CTRL, 10, 1, 1),
-SOC_DAPM_SINGLE("DAC2SPK Playback Switch", ALC5632_MIC_ROUTING_CTRL, 1, 1, 1),
-SOC_DAPM_SINGLE("VOICE2SPK Playback Switch", ALC5632_VOICE_DAC_VOL, 14, 1, 1),
-};
-
-/* Left Record Mixer */
-static const struct snd_kcontrol_new alc5632_captureL_mixer_controls[] = {
-SOC_DAPM_SINGLE("MIC12REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1),
-SOC_DAPM_SINGLE("MIC22REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1),
-SOC_DAPM_SINGLE("LIL2REC Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1),
-SOC_DAPM_SINGLE("PH2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1),
-SOC_DAPM_SINGLE("HPL2REC Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1),
-SOC_DAPM_SINGLE("SPK2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1),
-SOC_DAPM_SINGLE("MONO2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1),
-};
-
-/* Right Record Mixer */
-static const struct snd_kcontrol_new alc5632_captureR_mixer_controls[] = {
-SOC_DAPM_SINGLE("MIC12REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1),
-SOC_DAPM_SINGLE("MIC22REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1),
-SOC_DAPM_SINGLE("LIR2REC Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1),
-SOC_DAPM_SINGLE("PH2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1),
-SOC_DAPM_SINGLE("HPR2REC Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1),
-SOC_DAPM_SINGLE("SPK2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1),
-SOC_DAPM_SINGLE("MONO2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1),
-};
-
-/* Dmic Mixer */
-static const struct snd_kcontrol_new alc5632_dmicl_mixer_controls[] = {
-SOC_DAPM_SINGLE("DMICL2ADC Capture Switch", ALC5632_DIGI_BOOST_CTRL, 7, 1, 1),
-};
-static const struct snd_kcontrol_new alc5632_dmicr_mixer_controls[] = {
-SOC_DAPM_SINGLE("DMICR2ADC Capture Switch", ALC5632_DIGI_BOOST_CTRL, 6, 1, 1),
-};
-
-static const char * const alc5632_spk_n_sour_sel[] = {
- "RN/-R", "RP/+R", "LN/-R", "Mute"};
-static const char * const alc5632_hpl_out_input_sel[] = {
- "Vmid", "HP Left Mix"};
-static const char * const alc5632_hpr_out_input_sel[] = {
- "Vmid", "HP Right Mix"};
-static const char * const alc5632_spkout_input_sel[] = {
- "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
-static const char * const alc5632_aux_out_input_sel[] = {
- "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
-static const char * const alc5632_adcr_func_sel[] = {
- "Stereo ADC", "Voice ADC"};
-static const char * const alc5632_i2s_out_sel[] = {
- "ADC LR", "Voice Stereo Digital"};
-
-/* auxout output mux */
-static const struct soc_enum alc5632_aux_out_input_enum =
-SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 6, 4, alc5632_aux_out_input_sel);
-static const struct snd_kcontrol_new alc5632_auxout_mux_controls =
-SOC_DAPM_ENUM("AuxOut Mux", alc5632_aux_out_input_enum);
-
-/* speaker output mux */
-static const struct soc_enum alc5632_spkout_input_enum =
-SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 10, 4, alc5632_spkout_input_sel);
-static const struct snd_kcontrol_new alc5632_spkout_mux_controls =
-SOC_DAPM_ENUM("SpeakerOut Mux", alc5632_spkout_input_enum);
-
-/* headphone left output mux */
-static const struct soc_enum alc5632_hpl_out_input_enum =
-SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 9, 2, alc5632_hpl_out_input_sel);
-static const struct snd_kcontrol_new alc5632_hpl_out_mux_controls =
-SOC_DAPM_ENUM("Left Headphone Mux", alc5632_hpl_out_input_enum);
-
-/* headphone right output mux */
-static const struct soc_enum alc5632_hpr_out_input_enum =
-SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 8, 2, alc5632_hpr_out_input_sel);
-static const struct snd_kcontrol_new alc5632_hpr_out_mux_controls =
-SOC_DAPM_ENUM("Right Headphone Mux", alc5632_hpr_out_input_enum);
-
-/* speaker output N select */
-static const struct soc_enum alc5632_spk_n_sour_enum =
-SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 14, 4, alc5632_spk_n_sour_sel);
-static const struct snd_kcontrol_new alc5632_spkoutn_mux_controls =
-SOC_DAPM_ENUM("SpeakerOut N Mux", alc5632_spk_n_sour_enum);
-
-/* speaker amplifier */
-static const char *alc5632_amp_names[] = {"AB Amp", "D Amp"};
-static const struct soc_enum alc5632_amp_enum =
- SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 13, 2, alc5632_amp_names);
-static const struct snd_kcontrol_new alc5632_amp_mux_controls =
- SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum);
-
-/* ADC output select */
-static const struct soc_enum alc5632_adcr_func_enum =
- SOC_ENUM_SINGLE(ALC5632_DAC_FUNC_SELECT, 5, 2, alc5632_adcr_func_sel);
-static const struct snd_kcontrol_new alc5632_adcr_func_controls =
- SOC_DAPM_ENUM("ADCR Mux", alc5632_adcr_func_enum);
-
-/* I2S out select */
-static const struct soc_enum alc5632_i2s_out_enum =
- SOC_ENUM_SINGLE(ALC5632_I2S_OUT_CTL, 5, 2, alc5632_i2s_out_sel);
-static const struct snd_kcontrol_new alc5632_i2s_out_controls =
- SOC_DAPM_ENUM("I2SOut Mux", alc5632_i2s_out_enum);
-
-static const struct snd_soc_dapm_widget alc5632_dapm_widgets[] = {
-/* Muxes */
-SND_SOC_DAPM_MUX("AuxOut Mux", SND_SOC_NOPM, 0, 0,
- &alc5632_auxout_mux_controls),
-SND_SOC_DAPM_MUX("SpeakerOut Mux", SND_SOC_NOPM, 0, 0,
- &alc5632_spkout_mux_controls),
-SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0,
- &alc5632_hpl_out_mux_controls),
-SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0,
- &alc5632_hpr_out_mux_controls),
-SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0,
- &alc5632_spkoutn_mux_controls),
-SND_SOC_DAPM_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0,
- &alc5632_adcr_func_controls),
-SND_SOC_DAPM_MUX("I2SOut Mux", ALC5632_PWR_MANAG_ADD1, 11, 0,
- &alc5632_i2s_out_controls),
-
-/* output mixers */
-SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0,
- &alc5632_hp_mixer_controls[0],
- ARRAY_SIZE(alc5632_hp_mixer_controls)),
-SND_SOC_DAPM_MIXER("HPR Mix", ALC5632_PWR_MANAG_ADD2, 4, 0,
- &alc5632_hpr_mixer_controls[0],
- ARRAY_SIZE(alc5632_hpr_mixer_controls)),
-SND_SOC_DAPM_MIXER("HPL Mix", ALC5632_PWR_MANAG_ADD2, 5, 0,
- &alc5632_hpl_mixer_controls[0],
- ARRAY_SIZE(alc5632_hpl_mixer_controls)),
-SND_SOC_DAPM_MIXER("HPOut Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("Mono Mix", ALC5632_PWR_MANAG_ADD2, 2, 0,
- &alc5632_mono_mixer_controls[0],
- ARRAY_SIZE(alc5632_mono_mixer_controls)),
-SND_SOC_DAPM_MIXER("Speaker Mix", ALC5632_PWR_MANAG_ADD2, 3, 0,
- &alc5632_speaker_mixer_controls[0],
- ARRAY_SIZE(alc5632_speaker_mixer_controls)),
-SND_SOC_DAPM_MIXER("DMICL Mix", SND_SOC_NOPM, 0, 0,
- &alc5632_dmicl_mixer_controls[0],
- ARRAY_SIZE(alc5632_dmicl_mixer_controls)),
-SND_SOC_DAPM_MIXER("DMICR Mix", SND_SOC_NOPM, 0, 0,
- &alc5632_dmicr_mixer_controls[0],
- ARRAY_SIZE(alc5632_dmicr_mixer_controls)),
-
-/* input mixers */
-SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5632_PWR_MANAG_ADD2, 1, 0,
- &alc5632_captureL_mixer_controls[0],
- ARRAY_SIZE(alc5632_captureL_mixer_controls)),
-SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5632_PWR_MANAG_ADD2, 0, 0,
- &alc5632_captureR_mixer_controls[0],
- ARRAY_SIZE(alc5632_captureR_mixer_controls)),
-
-SND_SOC_DAPM_AIF_IN("AIFRXL", "Left HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_AIF_IN("AIFRXR", "Right HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_AIF_OUT("AIFTXL", "Left HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_AIF_OUT("AIFTXR", "Right HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_AIF_IN("VAIFRX", "Voice Playback", 0, SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_AIF_OUT("VAIFTX", "Voice Capture", 0, SND_SOC_NOPM, 0, 0),
-
-SND_SOC_DAPM_DAC("Voice DAC", NULL, ALC5632_PWR_MANAG_ADD2, 10, 0),
-SND_SOC_DAPM_DAC("Left DAC", NULL, ALC5632_PWR_MANAG_ADD2, 9, 0),
-SND_SOC_DAPM_DAC("Right DAC", NULL, ALC5632_PWR_MANAG_ADD2, 8, 0),
-SND_SOC_DAPM_ADC("Left ADC", NULL, ALC5632_PWR_MANAG_ADD2, 7, 0),
-SND_SOC_DAPM_ADC("Right ADC", NULL, ALC5632_PWR_MANAG_ADD2, 6, 0),
-
-SND_SOC_DAPM_MIXER("DAC Left Channel", ALC5632_PWR_MANAG_ADD1, 15, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("DAC Right Channel",
- ALC5632_PWR_MANAG_ADD1, 14, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("I2S Mix", ALC5632_PWR_MANAG_ADD1, 11, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("Phone Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("Voice Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("ADCLR", SND_SOC_NOPM, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA("Left Headphone", ALC5632_PWR_MANAG_ADD3, 11, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right Headphone", ALC5632_PWR_MANAG_ADD3, 10, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Left Speaker", ALC5632_PWR_MANAG_ADD3, 13, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right Speaker", ALC5632_PWR_MANAG_ADD3, 12, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Aux Out", ALC5632_PWR_MANAG_ADD3, 14, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Left LineIn", ALC5632_PWR_MANAG_ADD3, 7, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right LineIn", ALC5632_PWR_MANAG_ADD3, 6, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Phone", ALC5632_PWR_MANAG_ADD3, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Phone ADMix", ALC5632_PWR_MANAG_ADD3, 4, 0, NULL, 0),
-SND_SOC_DAPM_PGA("MIC1 PGA", ALC5632_PWR_MANAG_ADD3, 3, 0, NULL, 0),
-SND_SOC_DAPM_PGA("MIC2 PGA", ALC5632_PWR_MANAG_ADD3, 2, 0, NULL, 0),
-SND_SOC_DAPM_PGA("MIC1 Pre Amp", ALC5632_PWR_MANAG_ADD3, 1, 0, NULL, 0),
-SND_SOC_DAPM_PGA("MIC2 Pre Amp", ALC5632_PWR_MANAG_ADD3, 0, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("MICBIAS1", ALC5632_PWR_MANAG_ADD1, 3, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("MICBIAS2", ALC5632_PWR_MANAG_ADD1, 2, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA_E("D Amp", ALC5632_PWR_MANAG_ADD2, 14, 0, NULL, 0,
- amp_mixer_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-SND_SOC_DAPM_PGA("AB Amp", ALC5632_PWR_MANAG_ADD2, 15, 0, NULL, 0),
-SND_SOC_DAPM_MUX("AB-D Amp Mux", ALC5632_PWR_MANAG_ADD1, 10, 0,
- &alc5632_amp_mux_controls),
-
-SND_SOC_DAPM_OUTPUT("AUXOUT"),
-SND_SOC_DAPM_OUTPUT("HPL"),
-SND_SOC_DAPM_OUTPUT("HPR"),
-SND_SOC_DAPM_OUTPUT("SPKOUT"),
-SND_SOC_DAPM_OUTPUT("SPKOUTN"),
-
-SND_SOC_DAPM_INPUT("LINEINL"),
-SND_SOC_DAPM_INPUT("LINEINR"),
-SND_SOC_DAPM_INPUT("PHONEP"),
-SND_SOC_DAPM_INPUT("PHONEN"),
-SND_SOC_DAPM_INPUT("DMICDAT"),
-SND_SOC_DAPM_INPUT("MIC1"),
-SND_SOC_DAPM_INPUT("MIC2"),
-SND_SOC_DAPM_VMID("Vmid"),
-};
-
-
-static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
- /* Playback streams */
- {"Left DAC", NULL, "AIFRXL"},
- {"Right DAC", NULL, "AIFRXR"},
-
- /* virtual mixer - mixes left & right channels */
- {"I2S Mix", NULL, "Left DAC"},
- {"I2S Mix", NULL, "Right DAC"},
- {"Line Mix", NULL, "Right LineIn"},
- {"Line Mix", NULL, "Left LineIn"},
- {"Phone Mix", NULL, "Phone"},
- {"Phone Mix", NULL, "Phone ADMix"},
- {"AUXOUT", NULL, "Aux Out"},
-
- /* DAC */
- {"DAC Right Channel", NULL, "I2S Mix"},
- {"DAC Left Channel", NULL, "I2S Mix"},
-
- /* HP mixer */
- {"HPL Mix", "ADC2HP_L Playback Switch", "Left Capture Mix"},
- {"HPL Mix", NULL, "HP Mix"},
- {"HPR Mix", "ADC2HP_R Playback Switch", "Right Capture Mix"},
- {"HPR Mix", NULL, "HP Mix"},
- {"HP Mix", "LI2HP Playback Switch", "Line Mix"},
- {"HP Mix", "PHONE2HP Playback Switch", "Phone Mix"},
- {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"},
- {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"},
- {"HP Mix", "VOICE2HP Playback Switch", "Voice Mix"},
- {"HPR Mix", "DACR2HP Playback Switch", "DAC Right Channel"},
- {"HPL Mix", "DACL2HP Playback Switch", "DAC Left Channel"},
- {"HPOut Mix", NULL, "HP Mix"},
- {"HPOut Mix", NULL, "HPR Mix"},
- {"HPOut Mix", NULL, "HPL Mix"},
-
- /* speaker mixer */
- {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"},
- {"Speaker Mix", "PHONE2SPK Playback Switch", "Phone Mix"},
- {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"},
- {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"},
- {"Speaker Mix", "DAC2SPK Playback Switch", "DAC Left Channel"},
- {"Speaker Mix", "VOICE2SPK Playback Switch", "Voice Mix"},
-
- /* mono mixer */
- {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"},
- {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"},
- {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"},
- {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"},
- {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"},
- {"Mono Mix", "DAC2MONO Playback Switch", "DAC Left Channel"},
- {"Mono Mix", "VOICE2MONO Playback Switch", "Voice Mix"},
-
- /* Left record mixer */
- {"Left Capture Mix", "LIL2REC Capture Switch", "LINEINL"},
- {"Left Capture Mix", "PH2REC_L Capture Switch", "PHONEN"},
- {"Left Capture Mix", "MIC12REC_L Capture Switch", "MIC1 Pre Amp"},
- {"Left Capture Mix", "MIC22REC_L Capture Switch", "MIC2 Pre Amp"},
- {"Left Capture Mix", "HPL2REC Capture Switch", "HPL Mix"},
- {"Left Capture Mix", "SPK2REC_L Capture Switch", "Speaker Mix"},
- {"Left Capture Mix", "MONO2REC_L Capture Switch", "Mono Mix"},
-
- /*Right record mixer */
- {"Right Capture Mix", "LIR2REC Capture Switch", "LINEINR"},
- {"Right Capture Mix", "PH2REC_R Capture Switch", "PHONEP"},
- {"Right Capture Mix", "MIC12REC_R Capture Switch", "MIC1 Pre Amp"},
- {"Right Capture Mix", "MIC22REC_R Capture Switch", "MIC2 Pre Amp"},
- {"Right Capture Mix", "HPR2REC Capture Switch", "HPR Mix"},
- {"Right Capture Mix", "SPK2REC_R Capture Switch", "Speaker Mix"},
- {"Right Capture Mix", "MONO2REC_R Capture Switch", "Mono Mix"},
-
- /* headphone left mux */
- {"Left Headphone Mux", "HP Left Mix", "HPL Mix"},
- {"Left Headphone Mux", "Vmid", "Vmid"},
-
- /* headphone right mux */
- {"Right Headphone Mux", "HP Right Mix", "HPR Mix"},
- {"Right Headphone Mux", "Vmid", "Vmid"},
-
- /* speaker out mux */
- {"SpeakerOut Mux", "Vmid", "Vmid"},
- {"SpeakerOut Mux", "HPOut Mix", "HPOut Mix"},
- {"SpeakerOut Mux", "Speaker Mix", "Speaker Mix"},
- {"SpeakerOut Mux", "Mono Mix", "Mono Mix"},
-
- /* Mono/Aux Out mux */
- {"AuxOut Mux", "Vmid", "Vmid"},
- {"AuxOut Mux", "HPOut Mix", "HPOut Mix"},
- {"AuxOut Mux", "Speaker Mix", "Speaker Mix"},
- {"AuxOut Mux", "Mono Mix", "Mono Mix"},
-
- /* output pga */
- {"HPL", NULL, "Left Headphone"},
- {"Left Headphone", NULL, "Left Headphone Mux"},
- {"HPR", NULL, "Right Headphone"},
- {"Right Headphone", NULL, "Right Headphone Mux"},
- {"Aux Out", NULL, "AuxOut Mux"},
-
- /* input pga */
- {"Left LineIn", NULL, "LINEINL"},
- {"Right LineIn", NULL, "LINEINR"},
- {"Phone", NULL, "PHONEP"},
- {"MIC1 Pre Amp", NULL, "MIC1"},
- {"MIC2 Pre Amp", NULL, "MIC2"},
- {"MIC1 PGA", NULL, "MIC1 Pre Amp"},
- {"MIC2 PGA", NULL, "MIC2 Pre Amp"},
-
- /* left ADC */
- {"Left ADC", NULL, "Left Capture Mix"},
- {"DMICL Mix", "DMICL2ADC Capture Switch", "DMICDAT"},
- {"Left ADC", NULL, "DMICL Mix"},
- {"ADCLR", NULL, "Left ADC"},
-
- /* right ADC */
- {"Right ADC", NULL, "Right Capture Mix"},
- {"DMICR Mix", "DMICR2ADC Capture Switch", "DMICDAT"},
- {"Right ADC", NULL, "DMICR Mix"},
- {"ADCR Mux", "Stereo ADC", "Right ADC"},
- {"ADCR Mux", "Voice ADC", "Right ADC"},
- {"ADCLR", NULL, "ADCR Mux"},
- {"VAIFTX", NULL, "ADCR Mux"},
-
- /* Digital I2S out */
- {"I2SOut Mux", "ADC LR", "ADCLR"},
- {"I2SOut Mux", "Voice Stereo Digital", "VAIFRX"},
- {"AIFTXL", NULL, "I2SOut Mux"},
- {"AIFTXR", NULL, "I2SOut Mux"},
-
- /* Voice Mix */
- {"Voice DAC", NULL, "VAIFRX"},
- {"Voice Mix", NULL, "Voice DAC"},
-
- /* Speaker Output */
- {"SpeakerOut N Mux", "RN/-R", "Left Speaker"},
- {"SpeakerOut N Mux", "RP/+R", "Left Speaker"},
- {"SpeakerOut N Mux", "LN/-R", "Left Speaker"},
- {"SpeakerOut N Mux", "Mute", "Vmid"},
-
- {"SpeakerOut N Mux", "RN/-R", "Right Speaker"},
- {"SpeakerOut N Mux", "RP/+R", "Right Speaker"},
- {"SpeakerOut N Mux", "LN/-R", "Right Speaker"},
- {"SpeakerOut N Mux", "Mute", "Vmid"},
-
- {"AB Amp", NULL, "SpeakerOut Mux"},
- {"D Amp", NULL, "SpeakerOut Mux"},
- {"AB-D Amp Mux", "AB Amp", "AB Amp"},
- {"AB-D Amp Mux", "D Amp", "D Amp"},
- {"Left Speaker", NULL, "AB-D Amp Mux"},
- {"Right Speaker", NULL, "AB-D Amp Mux"},
-
- {"SPKOUT", NULL, "Left Speaker"},
- {"SPKOUT", NULL, "Right Speaker"},
-
- {"SPKOUTN", NULL, "SpeakerOut N Mux"},
-
-};
-
-/* PLL divisors */
-struct _pll_div {
- u32 pll_in;
- u32 pll_out;
- u16 regvalue;
-};
-
-/* Note : pll code from original alc5632 driver. Not sure of how good it is */
-/* usefull only for master mode */
-static const struct _pll_div codec_master_pll_div[] = {
-
- { 2048000, 8192000, 0x0ea0},
- { 3686400, 8192000, 0x4e27},
- { 12000000, 8192000, 0x456b},
- { 13000000, 8192000, 0x495f},
- { 13100000, 8192000, 0x0320},
- { 2048000, 11289600, 0xf637},
- { 3686400, 11289600, 0x2f22},
- { 12000000, 11289600, 0x3e2f},
- { 13000000, 11289600, 0x4d5b},
- { 13100000, 11289600, 0x363b},
- { 2048000, 16384000, 0x1ea0},
- { 3686400, 16384000, 0x9e27},
- { 12000000, 16384000, 0x452b},
- { 13000000, 16384000, 0x542f},
- { 13100000, 16384000, 0x03a0},
- { 2048000, 16934400, 0xe625},
- { 3686400, 16934400, 0x9126},
- { 12000000, 16934400, 0x4d2c},
- { 13000000, 16934400, 0x742f},
- { 13100000, 16934400, 0x3c27},
- { 2048000, 22579200, 0x2aa0},
- { 3686400, 22579200, 0x2f20},
- { 12000000, 22579200, 0x7e2f},
- { 13000000, 22579200, 0x742f},
- { 13100000, 22579200, 0x3c27},
- { 2048000, 24576000, 0x2ea0},
- { 3686400, 24576000, 0xee27},
- { 12000000, 24576000, 0x2915},
- { 13000000, 24576000, 0x772e},
- { 13100000, 24576000, 0x0d20},
-};
-
-/* FOUT = MCLK*(N+2)/((M+2)*(K+2))
- N: bit 15:8 (div 2 .. div 257)
- K: bit 6:4 typical 2
- M: bit 3:0 (div 2 .. div 17)
-
- same as for 5623 - thanks!
-*/
-
-static const struct _pll_div codec_slave_pll_div[] = {
-
- { 1024000, 16384000, 0x3ea0},
- { 1411200, 22579200, 0x3ea0},
- { 1536000, 24576000, 0x3ea0},
- { 2048000, 16384000, 0x1ea0},
- { 2822400, 22579200, 0x1ea0},
- { 3072000, 24576000, 0x1ea0},
-
-};
-
-static int alc5632_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
- int source, unsigned int freq_in, unsigned int freq_out)
-{
- int i;
- struct snd_soc_codec *codec = codec_dai->codec;
- int gbl_clk = 0, pll_div = 0;
- u16 reg;
-
- if (pll_id < ALC5632_PLL_FR_MCLK || pll_id > ALC5632_PLL_FR_VBCLK)
- return -EINVAL;
-
- /* Disable PLL power */
- snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
- ALC5632_PWR_ADD2_PLL1,
- 0);
- snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
- ALC5632_PWR_ADD2_PLL2,
- 0);
-
- /* pll is not used in slave mode */
- reg = snd_soc_read(codec, ALC5632_DAI_CONTROL);
- if (reg & ALC5632_DAI_SDP_SLAVE_MODE)
- return 0;
-
- if (!freq_in || !freq_out)
- return 0;
-
- switch (pll_id) {
- case ALC5632_PLL_FR_MCLK:
- for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++) {
- if (codec_master_pll_div[i].pll_in == freq_in
- && codec_master_pll_div[i].pll_out == freq_out) {
- /* PLL source from MCLK */
- pll_div = codec_master_pll_div[i].regvalue;
- break;
- }
- }
- break;
- case ALC5632_PLL_FR_BCLK:
- for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) {
- if (codec_slave_pll_div[i].pll_in == freq_in
- && codec_slave_pll_div[i].pll_out == freq_out) {
- /* PLL source from Bitclk */
- gbl_clk = ALC5632_PLL_FR_BCLK;
- pll_div = codec_slave_pll_div[i].regvalue;
- break;
- }
- }
- break;
- case ALC5632_PLL_FR_VBCLK:
- for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) {
- if (codec_slave_pll_div[i].pll_in == freq_in
- && codec_slave_pll_div[i].pll_out == freq_out) {
- /* PLL source from voice clock */
- gbl_clk = ALC5632_PLL_FR_VBCLK;
- pll_div = codec_slave_pll_div[i].regvalue;
- break;
- }
- }
- break;
- default:
- return -EINVAL;
- }
-
- if (!pll_div)
- return -EINVAL;
-
- /* choose MCLK/BCLK/VBCLK */
- snd_soc_write(codec, ALC5632_GPCR2, gbl_clk);
- /* choose PLL1 clock rate */
- snd_soc_write(codec, ALC5632_PLL1_CTRL, pll_div);
- /* enable PLL1 */
- snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
- ALC5632_PWR_ADD2_PLL1,
- ALC5632_PWR_ADD2_PLL1);
- /* enable PLL2 */
- snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
- ALC5632_PWR_ADD2_PLL2,
- ALC5632_PWR_ADD2_PLL2);
- /* use PLL1 as main SYSCLK */
- snd_soc_update_bits(codec, ALC5632_GPCR1,
- ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1,
- ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1);
-
- return 0;
-}
-
-struct _coeff_div {
- u16 fs;
- u16 regvalue;
-};
-
-/* codec hifi mclk (after PLL) clock divider coefficients */
-/* values inspired from column BCLK=32Fs of Appendix A table */
-static const struct _coeff_div coeff_div[] = {
- {512*1, 0x3075},
-};
-
-static int get_coeff(struct snd_soc_codec *codec, int rate)
-{
- struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
- int i;
-
- for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
- if (coeff_div[i].fs * rate == alc5632->sysclk)
- return i;
- }
- return -EINVAL;
-}
-
-/*
- * Clock after PLL and dividers
- */
-static int alc5632_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
-
- switch (freq) {
- case 4096000:
- case 8192000:
- case 11289600:
- case 12288000:
- case 16384000:
- case 16934400:
- case 18432000:
- case 22579200:
- case 24576000:
- alc5632->sysclk = freq;
- return 0;
- }
- return -EINVAL;
-}
-
-static int alc5632_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 iface = 0;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- iface = ALC5632_DAI_SDP_MASTER_MODE;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- iface = ALC5632_DAI_SDP_SLAVE_MODE;
- break;
- default:
- return -EINVAL;
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= ALC5632_DAI_I2S_DF_I2S;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= ALC5632_DAI_I2S_DF_LEFT;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= ALC5632_DAI_I2S_DF_PCM_A;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- iface |= ALC5632_DAI_I2S_DF_PCM_B;
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- break;
- default:
- return -EINVAL;
- }
-
- return snd_soc_write(codec, ALC5632_DAI_CONTROL, iface);
-}
-
-static int alc5632_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- int coeff, rate;
- u16 iface;
-
- iface = snd_soc_read(codec, ALC5632_DAI_CONTROL);
- iface &= ~ALC5632_DAI_I2S_DL_MASK;
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- iface |= ALC5632_DAI_I2S_DL_16;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= ALC5632_DAI_I2S_DL_20;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface |= ALC5632_DAI_I2S_DL_24;
- break;
- default:
- return -EINVAL;
- }
-
- /* set iface & srate */
- snd_soc_write(codec, ALC5632_DAI_CONTROL, iface);
- rate = params_rate(params);
- coeff = get_coeff(codec, rate);
- if (coeff < 0)
- return -EINVAL;
-
- coeff = coeff_div[coeff].regvalue;
- snd_soc_write(codec, ALC5632_DAC_CLK_CTRL1, coeff);
-
- return 0;
-}
-
-static int alc5632_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 hp_mute = ALC5632_MISC_HP_DEPOP_MUTE_L
- |ALC5632_MISC_HP_DEPOP_MUTE_R;
- u16 mute_reg = snd_soc_read(codec, ALC5632_MISC_CTRL) & ~hp_mute;
-
- if (mute)
- mute_reg |= hp_mute;
-
- return snd_soc_write(codec, ALC5632_MISC_CTRL, mute_reg);
-}
-
-#define ALC5632_ADD2_POWER_EN (ALC5632_PWR_ADD2_VREF)
-
-#define ALC5632_ADD3_POWER_EN (ALC5632_PWR_ADD3_MIC1_BOOST_AD)
-
-#define ALC5632_ADD1_POWER_EN \
- (ALC5632_PWR_ADD1_DAC_REF \
- | ALC5632_PWR_ADD1_SOFTGEN_EN \
- | ALC5632_PWR_ADD1_HP_OUT_AMP \
- | ALC5632_PWR_ADD1_HP_OUT_ENH_AMP \
- | ALC5632_PWR_ADD1_MAIN_BIAS)
-
-static void enable_power_depop(struct snd_soc_codec *codec)
-{
- snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
- ALC5632_PWR_ADD1_SOFTGEN_EN,
- ALC5632_PWR_ADD1_SOFTGEN_EN);
-
- snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD3,
- ALC5632_ADD3_POWER_EN,
- ALC5632_ADD3_POWER_EN);
-
- snd_soc_update_bits(codec, ALC5632_MISC_CTRL,
- ALC5632_MISC_HP_DEPOP_MODE2_EN,
- ALC5632_MISC_HP_DEPOP_MODE2_EN);
-
- /* "normal" mode: 0 @ 26 */
- /* set all PR0-7 mixers to 0 */
- snd_soc_update_bits(codec, ALC5632_PWR_DOWN_CTRL_STATUS,
- ALC5632_PWR_DOWN_CTRL_STATUS_MASK,
- 0);
-
- msleep(500);
-
- snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
- ALC5632_ADD2_POWER_EN,
- ALC5632_ADD2_POWER_EN);
-
- snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
- ALC5632_ADD1_POWER_EN,
- ALC5632_ADD1_POWER_EN);
-
- /* disable HP Depop2 */
- snd_soc_update_bits(codec, ALC5632_MISC_CTRL,
- ALC5632_MISC_HP_DEPOP_MODE2_EN,
- 0);
-
-}
-
-static int alc5632_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- switch (level) {
- case SND_SOC_BIAS_ON:
- enable_power_depop(codec);
- break;
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- /* everything off except vref/vmid, */
- snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
- ALC5632_PWR_MANAG_ADD1_MASK,
- ALC5632_PWR_ADD1_MAIN_BIAS);
- snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
- ALC5632_PWR_MANAG_ADD2_MASK,
- ALC5632_PWR_ADD2_VREF);
- /* "normal" mode: 0 @ 26 */
- snd_soc_update_bits(codec, ALC5632_PWR_DOWN_CTRL_STATUS,
- ALC5632_PWR_DOWN_CTRL_STATUS_MASK,
- 0xffff ^ (ALC5632_PWR_VREF_PR3
- | ALC5632_PWR_VREF_PR2));
- break;
- case SND_SOC_BIAS_OFF:
- /* everything off, dac mute, inactive */
- snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
- ALC5632_PWR_MANAG_ADD2_MASK, 0);
- snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD3,
- ALC5632_PWR_MANAG_ADD3_MASK, 0);
- snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
- ALC5632_PWR_MANAG_ADD1_MASK, 0);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define ALC5632_FORMATS (SNDRV_PCM_FMTBIT_S16_LE \
- | SNDRV_PCM_FMTBIT_S24_LE \
- | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops alc5632_dai_ops = {
- .hw_params = alc5632_pcm_hw_params,
- .digital_mute = alc5632_mute,
- .set_fmt = alc5632_set_dai_fmt,
- .set_sysclk = alc5632_set_dai_sysclk,
- .set_pll = alc5632_set_dai_pll,
-};
-
-static struct snd_soc_dai_driver alc5632_dai = {
- .name = "alc5632-hifi",
- .playback = {
- .stream_name = "HiFi Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rate_min = 8000,
- .rate_max = 48000,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = ALC5632_FORMATS,},
- .capture = {
- .stream_name = "HiFi Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rate_min = 8000,
- .rate_max = 48000,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = ALC5632_FORMATS,},
-
- .ops = &alc5632_dai_ops,
- .symmetric_rates = 1,
-};
-
-#ifdef CONFIG_PM
-static int alc5632_suspend(struct snd_soc_codec *codec)
-{
- alc5632_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int alc5632_resume(struct snd_soc_codec *codec)
-{
- struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
-
- regcache_sync(alc5632->regmap);
-
- alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-#else
-#define alc5632_suspend NULL
-#define alc5632_resume NULL
-#endif
-
-static int alc5632_probe(struct snd_soc_codec *codec)
-{
- struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- codec->control_data = alc5632->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- /* power on device */
- alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- switch (alc5632->id) {
- case 0x5c:
- snd_soc_add_codec_controls(codec, alc5632_vol_snd_controls,
- ARRAY_SIZE(alc5632_vol_snd_controls));
- break;
- default:
- return -EINVAL;
- }
-
- return ret;
-}
-
-/* power down chip */
-static int alc5632_remove(struct snd_soc_codec *codec)
-{
- alc5632_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_device_alc5632 = {
- .probe = alc5632_probe,
- .remove = alc5632_remove,
- .suspend = alc5632_suspend,
- .resume = alc5632_resume,
- .set_bias_level = alc5632_set_bias_level,
- .controls = alc5632_snd_controls,
- .num_controls = ARRAY_SIZE(alc5632_snd_controls),
- .dapm_widgets = alc5632_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(alc5632_dapm_widgets),
- .dapm_routes = alc5632_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes),
-};
-
-static struct regmap_config alc5632_regmap = {
- .reg_bits = 8,
- .val_bits = 16,
-
- .max_register = ALC5632_MAX_REGISTER,
- .reg_defaults = alc5632_reg_defaults,
- .num_reg_defaults = ARRAY_SIZE(alc5632_reg_defaults),
- .volatile_reg = alc5632_volatile_register,
- .cache_type = REGCACHE_RBTREE,
-};
-
-/*
- * alc5632 2 wire address is determined by A1 pin
- * state during powerup.
- * low = 0x1a
- * high = 0x1b
- */
-static __devinit int alc5632_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct alc5632_priv *alc5632;
- int ret, ret1, ret2;
- unsigned int vid1, vid2;
-
- alc5632 = devm_kzalloc(&client->dev,
- sizeof(struct alc5632_priv), GFP_KERNEL);
- if (alc5632 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(client, alc5632);
-
- alc5632->regmap = regmap_init_i2c(client, &alc5632_regmap);
- if (IS_ERR(alc5632->regmap)) {
- ret = PTR_ERR(alc5632->regmap);
- dev_err(&client->dev, "regmap_init() failed: %d\n", ret);
- return ret;
- }
-
- ret1 = regmap_read(alc5632->regmap, ALC5632_VENDOR_ID1, &vid1);
- ret2 = regmap_read(alc5632->regmap, ALC5632_VENDOR_ID2, &vid2);
- if (ret1 != 0 || ret2 != 0) {
- dev_err(&client->dev,
- "Failed to read chip ID: ret1=%d, ret2=%d\n", ret1, ret2);
- regmap_exit(alc5632->regmap);
- return -EIO;
- }
-
- vid2 >>= 8;
-
- if ((vid1 != 0x10EC) || (vid2 != id->driver_data)) {
- dev_err(&client->dev,
- "Device is not a ALC5632: VID1=0x%x, VID2=0x%x\n", vid1, vid2);
- regmap_exit(alc5632->regmap);
- return -EINVAL;
- }
-
- ret = alc5632_reset(alc5632->regmap);
- if (ret < 0) {
- dev_err(&client->dev, "Failed to issue reset\n");
- regmap_exit(alc5632->regmap);
- return ret;
- }
-
- alc5632->id = vid2;
- switch (alc5632->id) {
- case 0x5c:
- alc5632_dai.name = "alc5632-hifi";
- break;
- default:
- return -EINVAL;
- }
-
- ret = snd_soc_register_codec(&client->dev,
- &soc_codec_device_alc5632, &alc5632_dai, 1);
-
- if (ret < 0) {
- dev_err(&client->dev, "Failed to register codec: %d\n", ret);
- regmap_exit(alc5632->regmap);
- return ret;
- }
-
- return ret;
-}
-
-static __devexit int alc5632_i2c_remove(struct i2c_client *client)
-{
- struct alc5632_priv *alc5632 = i2c_get_clientdata(client);
- snd_soc_unregister_codec(&client->dev);
- regmap_exit(alc5632->regmap);
- return 0;
-}
-
-static const struct i2c_device_id alc5632_i2c_table[] = {
- {"alc5632", 0x5c},
- {}
-};
-MODULE_DEVICE_TABLE(i2c, alc5632_i2c_table);
-
-/* i2c codec control layer */
-static struct i2c_driver alc5632_i2c_driver = {
- .driver = {
- .name = "alc5632",
- .owner = THIS_MODULE,
- },
- .probe = alc5632_i2c_probe,
- .remove = __devexit_p(alc5632_i2c_remove),
- .id_table = alc5632_i2c_table,
-};
-
-static int __init alc5632_modinit(void)
-{
- int ret;
-
- ret = i2c_add_driver(&alc5632_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "%s: can't add i2c driver", __func__);
- return ret;
- }
-
- return ret;
-}
-module_init(alc5632_modinit);
-
-static void __exit alc5632_modexit(void)
-{
- i2c_del_driver(&alc5632_i2c_driver);
-}
-module_exit(alc5632_modexit);
-
-MODULE_DESCRIPTION("ASoC ALC5632 driver");
-MODULE_AUTHOR("Leon Romanovsky <leon@leon.nu>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/alc5632.h b/ANDROID_3.4.5/sound/soc/codecs/alc5632.h
deleted file mode 100644
index 1b5bda59..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/alc5632.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
-* alc5632.h -- ALC5632 ALSA SoC Audio Codec
-*
-* Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
-*
-* Authors: Leon Romanovsky <leon@leon.nu>
-* Andrey Danin <danindrey@mail.ru>
-* Ilya Petrov <ilya.muromec@gmail.com>
-* Marc Dietrich <marvin24@gmx.de>
-*
-* Based on alc5623.h by Arnaud Patard
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License version 2 as
-* published by the Free Software Foundation.
-*/
-
-#ifndef _ALC5632_H
-#define _ALC5632_H
-
-#define ALC5632_RESET 0x00
-/* speaker output vol 2 2 */
-/* line output vol 4 2 */
-/* HP output vol 4 0 4 */
-#define ALC5632_SPK_OUT_VOL 0x02 /* spe out vol */
-#define ALC5632_SPK_OUT_VOL_STEP 1.5
-#define ALC5632_HP_OUT_VOL 0x04 /* hp out vol */
-#define ALC5632_AUX_OUT_VOL 0x06 /* aux out vol */
-#define ALC5632_PHONE_IN_VOL 0x08 /* phone in vol */
-#define ALC5632_LINE_IN_VOL 0x0A /* line in vol */
-#define ALC5632_STEREO_DAC_IN_VOL 0x0C /* stereo dac in vol */
-#define ALC5632_MIC_VOL 0x0E /* mic in vol */
-/* stero dac/mic routing */
-#define ALC5632_MIC_ROUTING_CTRL 0x10
-#define ALC5632_MIC_ROUTE_MONOMIX (1 << 0)
-#define ALC5632_MIC_ROUTE_SPK (1 << 1)
-#define ALC5632_MIC_ROUTE_HP (1 << 2)
-
-#define ALC5632_ADC_REC_GAIN 0x12 /* rec gain */
-#define ALC5632_ADC_REC_GAIN_RANGE 0x1F1F
-#define ALC5632_ADC_REC_GAIN_BASE (-16.5)
-#define ALC5632_ADC_REC_GAIN_STEP 1.5
-
-#define ALC5632_ADC_REC_MIXER 0x14 /* mixer control */
-#define ALC5632_ADC_REC_MIC1 (1 << 6)
-#define ALC5632_ADC_REC_MIC2 (1 << 5)
-#define ALC5632_ADC_REC_LINE_IN (1 << 4)
-#define ALC5632_ADC_REC_AUX (1 << 3)
-#define ALC5632_ADC_REC_HP (1 << 2)
-#define ALC5632_ADC_REC_SPK (1 << 1)
-#define ALC5632_ADC_REC_MONOMIX (1 << 0)
-
-#define ALC5632_VOICE_DAC_VOL 0x18 /* voice dac vol */
-#define ALC5632_I2S_OUT_CTL 0x1A /* undocumented reg. found in path scheme */
-/* ALC5632_OUTPUT_MIXER_CTRL : */
-/* same remark as for reg 2 line vs speaker */
-#define ALC5632_OUTPUT_MIXER_CTRL 0x1C /* out mix ctrl */
-#define ALC5632_OUTPUT_MIXER_RP (1 << 14)
-#define ALC5632_OUTPUT_MIXER_WEEK (1 << 12)
-#define ALC5632_OUTPUT_MIXER_HP (1 << 10)
-#define ALC5632_OUTPUT_MIXER_AUX_SPK (2 << 6)
-#define ALC5632_OUTPUT_MIXER_AUX_HP_LR (1 << 6)
-#define ALC5632_OUTPUT_MIXER_HP_R (1 << 8)
-#define ALC5632_OUTPUT_MIXER_HP_L (1 << 9)
-
-#define ALC5632_MIC_CTRL 0x22 /* mic phone ctrl */
-#define ALC5632_MIC_BOOST_BYPASS 0
-#define ALC5632_MIC_BOOST_20DB 1
-#define ALC5632_MIC_BOOST_30DB 2
-#define ALC5632_MIC_BOOST_40DB 3
-
-#define ALC5632_DIGI_BOOST_CTRL 0x24 /* digi mic / bost ctl */
-#define ALC5632_MIC_BOOST_RANGE 7
-#define ALC5632_MIC_BOOST_STEP 6
-#define ALC5632_PWR_DOWN_CTRL_STATUS 0x26
-#define ALC5632_PWR_DOWN_CTRL_STATUS_MASK 0xEF00
-#define ALC5632_PWR_VREF_PR3 (1 << 11)
-#define ALC5632_PWR_VREF_PR2 (1 << 10)
-#define ALC5632_PWR_VREF_STATUS (1 << 3)
-#define ALC5632_PWR_AMIX_STATUS (1 << 2)
-#define ALC5632_PWR_DAC_STATUS (1 << 1)
-#define ALC5632_PWR_ADC_STATUS (1 << 0)
-/* stereo/voice DAC / stereo adc func ctrl */
-#define ALC5632_DAC_FUNC_SELECT 0x2E
-
-/* Main serial data port ctrl (i2s) */
-#define ALC5632_DAI_CONTROL 0x34
-
-#define ALC5632_DAI_SDP_MASTER_MODE (0 << 15)
-#define ALC5632_DAI_SDP_SLAVE_MODE (1 << 15)
-#define ALC5632_DAI_SADLRCK_MODE (1 << 14)
-/* 0:voice, 1:main */
-#define ALC5632_DAI_MAIN_I2S_SYSCLK_SEL (1 << 8)
-#define ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL (1 << 7)
-/* 0:normal, 1:invert */
-#define ALC5632_DAI_MAIN_I2S_LRCK_INV (1 << 6)
-#define ALC5632_DAI_I2S_DL_MASK (3 << 2)
-#define ALC5632_DAI_I2S_DL_8 (3 << 2)
-#define ALC5632_DAI_I2S_DL_24 (2 << 2)
-#define ALC5632_DAI_I2S_DL_20 (1 << 2)
-#define ALC5632_DAI_I2S_DL_16 (0 << 2)
-#define ALC5632_DAI_I2S_DF_MASK (3 << 0)
-#define ALC5632_DAI_I2S_DF_PCM_B (3 << 0)
-#define ALC5632_DAI_I2S_DF_PCM_A (2 << 0)
-#define ALC5632_DAI_I2S_DF_LEFT (1 << 0)
-#define ALC5632_DAI_I2S_DF_I2S (0 << 0)
-/* extend serial data port control (VoDAC_i2c/pcm) */
-#define ALC5632_DAI_CONTROL2 0x36
-/* 0:gpio func, 1:voice pcm */
-#define ALC5632_DAI_VOICE_PCM_ENABLE (1 << 15)
-/* 0:master, 1:slave */
-#define ALC5632_DAI_VOICE_MODE_SEL (1 << 14)
-/* 0:disable, 1:enable */
-#define ALC5632_DAI_HPF_CLK_CTRL (1 << 13)
-/* 0:main, 1:voice */
-#define ALC5632_DAI_VOICE_I2S_SYSCLK_SEL (1 << 8)
-/* 0:normal, 1:invert */
-#define ALC5632_DAI_VOICE_VBCLK_SYSCLK_SEL (1 << 7)
-/* 0:normal, 1:invert */
-#define ALC5632_DAI_VOICE_I2S_LR_INV (1 << 6)
-#define ALC5632_DAI_VOICE_DL_MASK (3 << 2)
-#define ALC5632_DAI_VOICE_DL_16 (0 << 2)
-#define ALC5632_DAI_VOICE_DL_20 (1 << 2)
-#define ALC5632_DAI_VOICE_DL_24 (2 << 2)
-#define ALC5632_DAI_VOICE_DL_8 (3 << 2)
-#define ALC5632_DAI_VOICE_DF_MASK (3 << 0)
-#define ALC5632_DAI_VOICE_DF_I2S (0 << 0)
-#define ALC5632_DAI_VOICE_DF_LEFT (1 << 0)
-#define ALC5632_DAI_VOICE_DF_PCM_A (2 << 0)
-#define ALC5632_DAI_VOICE_DF_PCM_B (3 << 0)
-
-#define ALC5632_PWR_MANAG_ADD1 0x3A
-#define ALC5632_PWR_MANAG_ADD1_MASK 0xEFFF
-#define ALC5632_PWR_ADD1_DAC_L_EN (1 << 15)
-#define ALC5632_PWR_ADD1_DAC_R_EN (1 << 14)
-#define ALC5632_PWR_ADD1_ZERO_CROSS (1 << 13)
-#define ALC5632_PWR_ADD1_MAIN_I2S_EN (1 << 11)
-#define ALC5632_PWR_ADD1_SPK_AMP_EN (1 << 10)
-#define ALC5632_PWR_ADD1_HP_OUT_AMP (1 << 9)
-#define ALC5632_PWR_ADD1_HP_OUT_ENH_AMP (1 << 8)
-#define ALC5632_PWR_ADD1_VOICE_DAC_MIX (1 << 7)
-#define ALC5632_PWR_ADD1_SOFTGEN_EN (1 << 6)
-#define ALC5632_PWR_ADD1_MIC1_SHORT_CURR (1 << 5)
-#define ALC5632_PWR_ADD1_MIC2_SHORT_CURR (1 << 4)
-#define ALC5632_PWR_ADD1_MIC1_EN (1 << 3)
-#define ALC5632_PWR_ADD1_MIC2_EN (1 << 2)
-#define ALC5632_PWR_ADD1_MAIN_BIAS (1 << 1)
-#define ALC5632_PWR_ADD1_DAC_REF (1 << 0)
-
-#define ALC5632_PWR_MANAG_ADD2 0x3C
-#define ALC5632_PWR_MANAG_ADD2_MASK 0x7FFF
-#define ALC5632_PWR_ADD2_PLL1 (1 << 15)
-#define ALC5632_PWR_ADD2_PLL2 (1 << 14)
-#define ALC5632_PWR_ADD2_VREF (1 << 13)
-#define ALC5632_PWR_ADD2_OVT_DET (1 << 12)
-#define ALC5632_PWR_ADD2_VOICE_DAC (1 << 10)
-#define ALC5632_PWR_ADD2_L_DAC_CLK (1 << 9)
-#define ALC5632_PWR_ADD2_R_DAC_CLK (1 << 8)
-#define ALC5632_PWR_ADD2_L_ADC_CLK_GAIN (1 << 7)
-#define ALC5632_PWR_ADD2_R_ADC_CLK_GAIN (1 << 6)
-#define ALC5632_PWR_ADD2_L_HP_MIXER (1 << 5)
-#define ALC5632_PWR_ADD2_R_HP_MIXER (1 << 4)
-#define ALC5632_PWR_ADD2_SPK_MIXER (1 << 3)
-#define ALC5632_PWR_ADD2_MONO_MIXER (1 << 2)
-#define ALC5632_PWR_ADD2_L_ADC_REC_MIXER (1 << 1)
-#define ALC5632_PWR_ADD2_R_ADC_REC_MIXER (1 << 0)
-
-#define ALC5632_PWR_MANAG_ADD3 0x3E
-#define ALC5632_PWR_MANAG_ADD3_MASK 0x7CFF
-#define ALC5632_PWR_ADD3_AUXOUT_VOL (1 << 14)
-#define ALC5632_PWR_ADD3_SPK_L_OUT (1 << 13)
-#define ALC5632_PWR_ADD3_SPK_R_OUT (1 << 12)
-#define ALC5632_PWR_ADD3_HP_L_OUT_VOL (1 << 11)
-#define ALC5632_PWR_ADD3_HP_R_OUT_VOL (1 << 10)
-#define ALC5632_PWR_ADD3_LINEIN_L_VOL (1 << 7)
-#define ALC5632_PWR_ADD3_LINEIN_R_VOL (1 << 6)
-#define ALC5632_PWR_ADD3_AUXIN_VOL (1 << 5)
-#define ALC5632_PWR_ADD3_AUXIN_MIX (1 << 4)
-#define ALC5632_PWR_ADD3_MIC1_VOL (1 << 3)
-#define ALC5632_PWR_ADD3_MIC2_VOL (1 << 2)
-#define ALC5632_PWR_ADD3_MIC1_BOOST_AD (1 << 1)
-#define ALC5632_PWR_ADD3_MIC2_BOOST_AD (1 << 0)
-
-#define ALC5632_GPCR1 0x40
-#define ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1 (1 << 15)
-#define ALC5632_GPCR1_CLK_SYS_SRC_SEL_MCLK (0 << 15)
-#define ALC5632_GPCR1_DAC_HI_FLT_EN (1 << 10)
-#define ALC5632_GPCR1_SPK_AMP_CTRL (7 << 1)
-#define ALC5632_GPCR1_VDD_100 (5 << 1)
-#define ALC5632_GPCR1_VDD_125 (4 << 1)
-#define ALC5632_GPCR1_VDD_150 (3 << 1)
-#define ALC5632_GPCR1_VDD_175 (2 << 1)
-#define ALC5632_GPCR1_VDD_200 (1 << 1)
-#define ALC5632_GPCR1_VDD_225 (0 << 1)
-
-#define ALC5632_GPCR2 0x42
-#define ALC5632_GPCR2_PLL1_SOUR_SEL (3 << 12)
-#define ALC5632_PLL_FR_MCLK (0 << 12)
-#define ALC5632_PLL_FR_BCLK (2 << 12)
-#define ALC5632_PLL_FR_VBCLK (3 << 12)
-#define ALC5632_GPCR2_CLK_PLL_PRE_DIV1 (0 << 0)
-
-#define ALC5632_PLL1_CTRL 0x44
-#define ALC5632_PLL1_CTRL_N_VAL(n) (((n) & 0x0f) << 8)
-#define ALC5632_PLL1_M_BYPASS (1 << 7)
-#define ALC5632_PLL1_CTRL_K_VAL(k) (((k) & 0x07) << 4)
-#define ALC5632_PLL1_CTRL_M_VAL(m) (((m) & 0x0f) << 0)
-
-#define ALC5632_PLL2_CTRL 0x46
-#define ALC5632_PLL2_EN (1 << 15)
-#define ALC5632_PLL2_RATIO (0 << 15)
-
-#define ALC5632_GPIO_PIN_CONFIG 0x4C
-#define ALC5632_GPIO_PIN_POLARITY 0x4E
-#define ALC5632_GPIO_PIN_STICKY 0x50
-#define ALC5632_GPIO_PIN_WAKEUP 0x52
-#define ALC5632_GPIO_PIN_STATUS 0x54
-#define ALC5632_GPIO_PIN_SHARING 0x56
-#define ALC5632_OVER_CURR_STATUS 0x58
-#define ALC5632_SOFTVOL_CTRL 0x5A
-#define ALC5632_GPIO_OUPUT_PIN_CTRL 0x5C
-
-#define ALC5632_MISC_CTRL 0x5E
-#define ALC5632_MISC_DISABLE_FAST_VREG (1 << 15)
-#define ALC5632_MISC_AVC_TRGT_SEL (3 << 12)
-#define ALC5632_MISC_AVC_TRGT_RIGHT (1 << 12)
-#define ALC5632_MISC_AVC_TRGT_LEFT (2 << 12)
-#define ALC5632_MISC_AVC_TRGT_BOTH (3 << 12)
-#define ALC5632_MISC_HP_DEPOP_MODE1_EN (1 << 9)
-#define ALC5632_MISC_HP_DEPOP_MODE2_EN (1 << 8)
-#define ALC5632_MISC_HP_DEPOP_MUTE_L (1 << 7)
-#define ALC5632_MISC_HP_DEPOP_MUTE_R (1 << 6)
-#define ALC5632_MISC_HP_DEPOP_MUTE (1 << 5)
-#define ALC5632_MISC_GPIO_WAKEUP_CTRL (1 << 1)
-#define ALC5632_MISC_IRQOUT_INV_CTRL (1 << 0)
-
-#define ALC5632_DAC_CLK_CTRL1 0x60
-#define ALC5632_DAC_CLK_CTRL2 0x62
-#define ALC5632_DAC_CLK_CTRL2_DIV1_2 (1 << 0)
-#define ALC5632_VOICE_DAC_PCM_CLK_CTRL1 0x64
-#define ALC5632_PSEUDO_SPATIAL_CTRL 0x68
-#define ALC5632_HID_CTRL_INDEX 0x6A
-#define ALC5632_HID_CTRL_DATA 0x6C
-#define ALC5632_EQ_CTRL 0x6E
-
-/* undocumented */
-#define ALC5632_VENDOR_ID1 0x7C
-#define ALC5632_VENDOR_ID2 0x7E
-
-#define ALC5632_MAX_REGISTER 0x7E
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/cq93vc.c b/ANDROID_3.4.5/sound/soc/codecs/cq93vc.c
deleted file mode 100644
index 064cd6a9..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/cq93vc.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * ALSA SoC CQ0093 Voice Codec Driver for DaVinci platforms
- *
- * Copyright (C) 2010 Texas Instruments, Inc
- *
- * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/platform_device.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <linux/mfd/davinci_voicecodec.h>
-#include <linux/spi/spi.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-
-static inline unsigned int cq93vc_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- struct davinci_vc *davinci_vc = codec->control_data;
-
- return readl(davinci_vc->base + reg);
-}
-
-static inline int cq93vc_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- struct davinci_vc *davinci_vc = codec->control_data;
-
- writel(value, davinci_vc->base + reg);
-
- return 0;
-}
-
-static const struct snd_kcontrol_new cq93vc_snd_controls[] = {
- SOC_SINGLE("PGA Capture Volume", DAVINCI_VC_REG05, 0, 0x03, 0),
- SOC_SINGLE("Mono DAC Playback Volume", DAVINCI_VC_REG09, 0, 0x3f, 0),
-};
-
-static int cq93vc_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u8 reg = cq93vc_read(codec, DAVINCI_VC_REG09) & ~DAVINCI_VC_REG09_MUTE;
-
- if (mute)
- cq93vc_write(codec, DAVINCI_VC_REG09,
- reg | DAVINCI_VC_REG09_MUTE);
- else
- cq93vc_write(codec, DAVINCI_VC_REG09, reg);
-
- return 0;
-}
-
-static int cq93vc_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct davinci_vc *davinci_vc = codec->control_data;
-
- switch (freq) {
- case 22579200:
- case 27000000:
- case 33868800:
- davinci_vc->cq93vc.sysclk = freq;
- return 0;
- }
-
- return -EINVAL;
-}
-
-static int cq93vc_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- switch (level) {
- case SND_SOC_BIAS_ON:
- cq93vc_write(codec, DAVINCI_VC_REG12,
- DAVINCI_VC_REG12_POWER_ALL_ON);
- break;
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- cq93vc_write(codec, DAVINCI_VC_REG12,
- DAVINCI_VC_REG12_POWER_ALL_OFF);
- break;
- case SND_SOC_BIAS_OFF:
- /* force all power off */
- cq93vc_write(codec, DAVINCI_VC_REG12,
- DAVINCI_VC_REG12_POWER_ALL_OFF);
- break;
- }
- codec->dapm.bias_level = level;
-
- return 0;
-}
-
-#define CQ93VC_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000)
-#define CQ93VC_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE)
-
-static const struct snd_soc_dai_ops cq93vc_dai_ops = {
- .digital_mute = cq93vc_mute,
- .set_sysclk = cq93vc_set_dai_sysclk,
-};
-
-static struct snd_soc_dai_driver cq93vc_dai = {
- .name = "cq93vc-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = CQ93VC_RATES,
- .formats = CQ93VC_FORMATS,},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = CQ93VC_RATES,
- .formats = CQ93VC_FORMATS,},
- .ops = &cq93vc_dai_ops,
-};
-
-static int cq93vc_resume(struct snd_soc_codec *codec)
-{
- cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-
-static int cq93vc_probe(struct snd_soc_codec *codec)
-{
- struct davinci_vc *davinci_vc = codec->dev->platform_data;
-
- davinci_vc->cq93vc.codec = codec;
- codec->control_data = davinci_vc;
-
- /* Set controls */
- snd_soc_add_codec_controls(codec, cq93vc_snd_controls,
- ARRAY_SIZE(cq93vc_snd_controls));
-
- /* Off, with power on */
- cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-
-static int cq93vc_remove(struct snd_soc_codec *codec)
-{
- cq93vc_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_cq93vc = {
- .read = cq93vc_read,
- .write = cq93vc_write,
- .set_bias_level = cq93vc_set_bias_level,
- .probe = cq93vc_probe,
- .remove = cq93vc_remove,
- .resume = cq93vc_resume,
-};
-
-static int cq93vc_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev,
- &soc_codec_dev_cq93vc, &cq93vc_dai, 1);
-}
-
-static int cq93vc_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver cq93vc_codec_driver = {
- .driver = {
- .name = "cq93vc-codec",
- .owner = THIS_MODULE,
- },
-
- .probe = cq93vc_platform_probe,
- .remove = __devexit_p(cq93vc_platform_remove),
-};
-
-module_platform_driver(cq93vc_codec_driver);
-
-MODULE_DESCRIPTION("Texas Instruments DaVinci ASoC CQ0093 Voice Codec Driver");
-MODULE_AUTHOR("Miguel Aguilar");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/cs4270.c b/ANDROID_3.4.5/sound/soc/codecs/cs4270.c
deleted file mode 100644
index 1d672f52..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/cs4270.c
+++ /dev/null
@@ -1,740 +0,0 @@
-/*
- * CS4270 ALSA SoC (ASoC) codec driver
- *
- * Author: Timur Tabi <timur@freescale.com>
- *
- * Copyright 2007-2009 Freescale Semiconductor, Inc. This file is licensed
- * under the terms of the GNU General Public License version 2. This
- * program is licensed "as is" without any warranty of any kind, whether
- * express or implied.
- *
- * This is an ASoC device driver for the Cirrus Logic CS4270 codec.
- *
- * Current features/limitations:
- *
- * - Software mode is supported. Stand-alone mode is not supported.
- * - Only I2C is supported, not SPI
- * - Support for master and slave mode
- * - The machine driver's 'startup' function must call
- * cs4270_set_dai_sysclk() with the value of MCLK.
- * - Only I2S and left-justified modes are supported
- * - Power management is supported
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <linux/regulator/consumer.h>
-
-/*
- * The codec isn't really big-endian or little-endian, since the I2S
- * interface requires data to be sent serially with the MSbit first.
- * However, to support BE and LE I2S devices, we specify both here. That
- * way, ALSA will always match the bit patterns.
- */
-#define CS4270_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
- SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
- SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
- SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
-
-/* CS4270 registers addresses */
-#define CS4270_CHIPID 0x01 /* Chip ID */
-#define CS4270_PWRCTL 0x02 /* Power Control */
-#define CS4270_MODE 0x03 /* Mode Control */
-#define CS4270_FORMAT 0x04 /* Serial Format, ADC/DAC Control */
-#define CS4270_TRANS 0x05 /* Transition Control */
-#define CS4270_MUTE 0x06 /* Mute Control */
-#define CS4270_VOLA 0x07 /* DAC Channel A Volume Control */
-#define CS4270_VOLB 0x08 /* DAC Channel B Volume Control */
-
-#define CS4270_FIRSTREG 0x01
-#define CS4270_LASTREG 0x08
-#define CS4270_NUMREGS (CS4270_LASTREG - CS4270_FIRSTREG + 1)
-#define CS4270_I2C_INCR 0x80
-
-/* Bit masks for the CS4270 registers */
-#define CS4270_CHIPID_ID 0xF0
-#define CS4270_CHIPID_REV 0x0F
-#define CS4270_PWRCTL_FREEZE 0x80
-#define CS4270_PWRCTL_PDN_ADC 0x20
-#define CS4270_PWRCTL_PDN_DAC 0x02
-#define CS4270_PWRCTL_PDN 0x01
-#define CS4270_PWRCTL_PDN_ALL \
- (CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC | CS4270_PWRCTL_PDN)
-#define CS4270_MODE_SPEED_MASK 0x30
-#define CS4270_MODE_1X 0x00
-#define CS4270_MODE_2X 0x10
-#define CS4270_MODE_4X 0x20
-#define CS4270_MODE_SLAVE 0x30
-#define CS4270_MODE_DIV_MASK 0x0E
-#define CS4270_MODE_DIV1 0x00
-#define CS4270_MODE_DIV15 0x02
-#define CS4270_MODE_DIV2 0x04
-#define CS4270_MODE_DIV3 0x06
-#define CS4270_MODE_DIV4 0x08
-#define CS4270_MODE_POPGUARD 0x01
-#define CS4270_FORMAT_FREEZE_A 0x80
-#define CS4270_FORMAT_FREEZE_B 0x40
-#define CS4270_FORMAT_LOOPBACK 0x20
-#define CS4270_FORMAT_DAC_MASK 0x18
-#define CS4270_FORMAT_DAC_LJ 0x00
-#define CS4270_FORMAT_DAC_I2S 0x08
-#define CS4270_FORMAT_DAC_RJ16 0x18
-#define CS4270_FORMAT_DAC_RJ24 0x10
-#define CS4270_FORMAT_ADC_MASK 0x01
-#define CS4270_FORMAT_ADC_LJ 0x00
-#define CS4270_FORMAT_ADC_I2S 0x01
-#define CS4270_TRANS_ONE_VOL 0x80
-#define CS4270_TRANS_SOFT 0x40
-#define CS4270_TRANS_ZERO 0x20
-#define CS4270_TRANS_INV_ADC_A 0x08
-#define CS4270_TRANS_INV_ADC_B 0x10
-#define CS4270_TRANS_INV_DAC_A 0x02
-#define CS4270_TRANS_INV_DAC_B 0x04
-#define CS4270_TRANS_DEEMPH 0x01
-#define CS4270_MUTE_AUTO 0x20
-#define CS4270_MUTE_ADC_A 0x08
-#define CS4270_MUTE_ADC_B 0x10
-#define CS4270_MUTE_POLARITY 0x04
-#define CS4270_MUTE_DAC_A 0x01
-#define CS4270_MUTE_DAC_B 0x02
-
-/* Power-on default values for the registers
- *
- * This array contains the power-on default values of the registers, with the
- * exception of the "CHIPID" register (01h). The lower four bits of that
- * register contain the hardware revision, so it is treated as volatile.
- *
- * Also note that on the CS4270, the first readable register is 1, but ASoC
- * assumes the first register is 0. Therfore, the array must have an entry for
- * register 0, but we use cs4270_reg_is_readable() to tell ASoC that it can't
- * be read.
- */
-static const u8 cs4270_default_reg_cache[CS4270_LASTREG + 1] = {
- 0x00, 0x00, 0x00, 0x30, 0x00, 0x60, 0x20, 0x00, 0x00
-};
-
-static const char *supply_names[] = {
- "va", "vd", "vlc"
-};
-
-/* Private data for the CS4270 */
-struct cs4270_private {
- enum snd_soc_control_type control_type;
- unsigned int mclk; /* Input frequency of the MCLK pin */
- unsigned int mode; /* The mode (I2S or left-justified) */
- unsigned int slave_mode;
- unsigned int manual_mute;
-
- /* power domain regulators */
- struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
-};
-
-/**
- * struct cs4270_mode_ratios - clock ratio tables
- * @ratio: the ratio of MCLK to the sample rate
- * @speed_mode: the Speed Mode bits to set in the Mode Control register for
- * this ratio
- * @mclk: the Ratio Select bits to set in the Mode Control register for this
- * ratio
- *
- * The data for this chart is taken from Table 5 of the CS4270 reference
- * manual.
- *
- * This table is used to determine how to program the Mode Control register.
- * It is also used by cs4270_set_dai_sysclk() to tell ALSA which sampling
- * rates the CS4270 currently supports.
- *
- * @speed_mode is the corresponding bit pattern to be written to the
- * MODE bits of the Mode Control Register
- *
- * @mclk is the corresponding bit pattern to be wirten to the MCLK bits of
- * the Mode Control Register.
- *
- * In situations where a single ratio is represented by multiple speed
- * modes, we favor the slowest speed. E.g, for a ratio of 128, we pick
- * double-speed instead of quad-speed. However, the CS4270 errata states
- * that divide-By-1.5 can cause failures, so we avoid that mode where
- * possible.
- *
- * Errata: There is an errata for the CS4270 where divide-by-1.5 does not
- * work if Vd is 3.3V. If this effects you, select the
- * CONFIG_SND_SOC_CS4270_VD33_ERRATA Kconfig option, and the driver will
- * never select any sample rates that require divide-by-1.5.
- */
-struct cs4270_mode_ratios {
- unsigned int ratio;
- u8 speed_mode;
- u8 mclk;
-};
-
-static struct cs4270_mode_ratios cs4270_mode_ratios[] = {
- {64, CS4270_MODE_4X, CS4270_MODE_DIV1},
-#ifndef CONFIG_SND_SOC_CS4270_VD33_ERRATA
- {96, CS4270_MODE_4X, CS4270_MODE_DIV15},
-#endif
- {128, CS4270_MODE_2X, CS4270_MODE_DIV1},
- {192, CS4270_MODE_4X, CS4270_MODE_DIV3},
- {256, CS4270_MODE_1X, CS4270_MODE_DIV1},
- {384, CS4270_MODE_2X, CS4270_MODE_DIV3},
- {512, CS4270_MODE_1X, CS4270_MODE_DIV2},
- {768, CS4270_MODE_1X, CS4270_MODE_DIV3},
- {1024, CS4270_MODE_1X, CS4270_MODE_DIV4}
-};
-
-/* The number of MCLK/LRCK ratios supported by the CS4270 */
-#define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios)
-
-static int cs4270_reg_is_readable(struct snd_soc_codec *codec, unsigned int reg)
-{
- return (reg >= CS4270_FIRSTREG) && (reg <= CS4270_LASTREG);
-}
-
-static int cs4270_reg_is_volatile(struct snd_soc_codec *codec, unsigned int reg)
-{
- /* Unreadable registers are considered volatile */
- if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG))
- return 1;
-
- return reg == CS4270_CHIPID;
-}
-
-/**
- * cs4270_set_dai_sysclk - determine the CS4270 samples rates.
- * @codec_dai: the codec DAI
- * @clk_id: the clock ID (ignored)
- * @freq: the MCLK input frequency
- * @dir: the clock direction (ignored)
- *
- * This function is used to tell the codec driver what the input MCLK
- * frequency is.
- *
- * The value of MCLK is used to determine which sample rates are supported
- * by the CS4270. The ratio of MCLK / Fs must be equal to one of nine
- * supported values - 64, 96, 128, 192, 256, 384, 512, 768, and 1024.
- *
- * This function calculates the nine ratios and determines which ones match
- * a standard sample rate. If there's a match, then it is added to the list
- * of supported sample rates.
- *
- * This function must be called by the machine driver's 'startup' function,
- * otherwise the list of supported sample rates will not be available in
- * time for ALSA.
- *
- * For setups with variable MCLKs, pass 0 as 'freq' argument. This will cause
- * theoretically possible sample rates to be enabled. Call it again with a
- * proper value set one the external clock is set (most probably you would do
- * that from a machine's driver 'hw_param' hook.
- */
-static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
-
- cs4270->mclk = freq;
- return 0;
-}
-
-/**
- * cs4270_set_dai_fmt - configure the codec for the selected audio format
- * @codec_dai: the codec DAI
- * @format: a SND_SOC_DAIFMT_x value indicating the data format
- *
- * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the
- * codec accordingly.
- *
- * Currently, this function only supports SND_SOC_DAIFMT_I2S and
- * SND_SOC_DAIFMT_LEFT_J. The CS4270 codec also supports right-justified
- * data for playback only, but ASoC currently does not support different
- * formats for playback vs. record.
- */
-static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int format)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
-
- /* set DAI format */
- switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- case SND_SOC_DAIFMT_LEFT_J:
- cs4270->mode = format & SND_SOC_DAIFMT_FORMAT_MASK;
- break;
- default:
- dev_err(codec->dev, "invalid dai format\n");
- return -EINVAL;
- }
-
- /* set master/slave audio interface */
- switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- cs4270->slave_mode = 1;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- cs4270->slave_mode = 0;
- break;
- default:
- /* all other modes are unsupported by the hardware */
- dev_err(codec->dev, "Unknown master/slave configuration\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-/**
- * cs4270_hw_params - program the CS4270 with the given hardware parameters.
- * @substream: the audio stream
- * @params: the hardware parameters to set
- * @dai: the SOC DAI (ignored)
- *
- * This function programs the hardware with the values provided.
- * Specifically, the sample rate and the data format.
- *
- * The .ops functions are used to provide board-specific data, like input
- * frequencies, to this driver. This function takes that information,
- * combines it with the hardware parameters provided, and programs the
- * hardware accordingly.
- */
-static int cs4270_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
- int ret;
- unsigned int i;
- unsigned int rate;
- unsigned int ratio;
- int reg;
-
- /* Figure out which MCLK/LRCK ratio to use */
-
- rate = params_rate(params); /* Sampling rate, in Hz */
- ratio = cs4270->mclk / rate; /* MCLK/LRCK ratio */
-
- for (i = 0; i < NUM_MCLK_RATIOS; i++) {
- if (cs4270_mode_ratios[i].ratio == ratio)
- break;
- }
-
- if (i == NUM_MCLK_RATIOS) {
- /* We did not find a matching ratio */
- dev_err(codec->dev, "could not find matching ratio\n");
- return -EINVAL;
- }
-
- /* Set the sample rate */
-
- reg = snd_soc_read(codec, CS4270_MODE);
- reg &= ~(CS4270_MODE_SPEED_MASK | CS4270_MODE_DIV_MASK);
- reg |= cs4270_mode_ratios[i].mclk;
-
- if (cs4270->slave_mode)
- reg |= CS4270_MODE_SLAVE;
- else
- reg |= cs4270_mode_ratios[i].speed_mode;
-
- ret = snd_soc_write(codec, CS4270_MODE, reg);
- if (ret < 0) {
- dev_err(codec->dev, "i2c write failed\n");
- return ret;
- }
-
- /* Set the DAI format */
-
- reg = snd_soc_read(codec, CS4270_FORMAT);
- reg &= ~(CS4270_FORMAT_DAC_MASK | CS4270_FORMAT_ADC_MASK);
-
- switch (cs4270->mode) {
- case SND_SOC_DAIFMT_I2S:
- reg |= CS4270_FORMAT_DAC_I2S | CS4270_FORMAT_ADC_I2S;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- reg |= CS4270_FORMAT_DAC_LJ | CS4270_FORMAT_ADC_LJ;
- break;
- default:
- dev_err(codec->dev, "unknown dai format\n");
- return -EINVAL;
- }
-
- ret = snd_soc_write(codec, CS4270_FORMAT, reg);
- if (ret < 0) {
- dev_err(codec->dev, "i2c write failed\n");
- return ret;
- }
-
- return ret;
-}
-
-/**
- * cs4270_dai_mute - enable/disable the CS4270 external mute
- * @dai: the SOC DAI
- * @mute: 0 = disable mute, 1 = enable mute
- *
- * This function toggles the mute bits in the MUTE register. The CS4270's
- * mute capability is intended for external muting circuitry, so if the
- * board does not have the MUTEA or MUTEB pins connected to such circuitry,
- * then this function will do nothing.
- */
-static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
- int reg6;
-
- reg6 = snd_soc_read(codec, CS4270_MUTE);
-
- if (mute)
- reg6 |= CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B;
- else {
- reg6 &= ~(CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B);
- reg6 |= cs4270->manual_mute;
- }
-
- return snd_soc_write(codec, CS4270_MUTE, reg6);
-}
-
-/**
- * cs4270_soc_put_mute - put callback for the 'Master Playback switch'
- * alsa control.
- * @kcontrol: mixer control
- * @ucontrol: control element information
- *
- * This function basically passes the arguments on to the generic
- * snd_soc_put_volsw() function and saves the mute information in
- * our private data structure. This is because we want to prevent
- * cs4270_dai_mute() neglecting the user's decision to manually
- * mute the codec's output.
- *
- * Returns 0 for success.
- */
-static int cs4270_soc_put_mute(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
- int left = !ucontrol->value.integer.value[0];
- int right = !ucontrol->value.integer.value[1];
-
- cs4270->manual_mute = (left ? CS4270_MUTE_DAC_A : 0) |
- (right ? CS4270_MUTE_DAC_B : 0);
-
- return snd_soc_put_volsw(kcontrol, ucontrol);
-}
-
-/* A list of non-DAPM controls that the CS4270 supports */
-static const struct snd_kcontrol_new cs4270_snd_controls[] = {
- SOC_DOUBLE_R("Master Playback Volume",
- CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1),
- SOC_SINGLE("Digital Sidetone Switch", CS4270_FORMAT, 5, 1, 0),
- SOC_SINGLE("Soft Ramp Switch", CS4270_TRANS, 6, 1, 0),
- SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0),
- SOC_SINGLE("De-emphasis filter", CS4270_TRANS, 0, 1, 0),
- SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1),
- SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0),
- SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1),
- SOC_DOUBLE_EXT("Master Playback Switch", CS4270_MUTE, 0, 1, 1, 1,
- snd_soc_get_volsw, cs4270_soc_put_mute),
-};
-
-static const struct snd_soc_dai_ops cs4270_dai_ops = {
- .hw_params = cs4270_hw_params,
- .set_sysclk = cs4270_set_dai_sysclk,
- .set_fmt = cs4270_set_dai_fmt,
- .digital_mute = cs4270_dai_mute,
-};
-
-static struct snd_soc_dai_driver cs4270_dai = {
- .name = "cs4270-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 4000,
- .rate_max = 216000,
- .formats = CS4270_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 4000,
- .rate_max = 216000,
- .formats = CS4270_FORMATS,
- },
- .ops = &cs4270_dai_ops,
-};
-
-/**
- * cs4270_probe - ASoC probe function
- * @pdev: platform device
- *
- * This function is called when ASoC has all the pieces it needs to
- * instantiate a sound driver.
- */
-static int cs4270_probe(struct snd_soc_codec *codec)
-{
- struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
- int i, ret;
-
- /* Tell ASoC what kind of I/O to use to read the registers. ASoC will
- * then do the I2C transactions itself.
- */
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs4270->control_type);
- if (ret < 0) {
- dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret);
- return ret;
- }
-
- /* Disable auto-mute. This feature appears to be buggy. In some
- * situations, auto-mute will not deactivate when it should, so we want
- * this feature disabled by default. An application (e.g. alsactl) can
- * re-enabled it by using the controls.
- */
- ret = snd_soc_update_bits(codec, CS4270_MUTE, CS4270_MUTE_AUTO, 0);
- if (ret < 0) {
- dev_err(codec->dev, "i2c write failed\n");
- return ret;
- }
-
- /* Disable automatic volume control. The hardware enables, and it
- * causes volume change commands to be delayed, sometimes until after
- * playback has started. An application (e.g. alsactl) can
- * re-enabled it by using the controls.
- */
- ret = snd_soc_update_bits(codec, CS4270_TRANS,
- CS4270_TRANS_SOFT | CS4270_TRANS_ZERO, 0);
- if (ret < 0) {
- dev_err(codec->dev, "i2c write failed\n");
- return ret;
- }
-
- /* Add the non-DAPM controls */
- ret = snd_soc_add_codec_controls(codec, cs4270_snd_controls,
- ARRAY_SIZE(cs4270_snd_controls));
- if (ret < 0) {
- dev_err(codec->dev, "failed to add controls\n");
- return ret;
- }
-
- /* get the power supply regulators */
- for (i = 0; i < ARRAY_SIZE(supply_names); i++)
- cs4270->supplies[i].supply = supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies),
- cs4270->supplies);
- if (ret < 0)
- return ret;
-
- ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
- cs4270->supplies);
- if (ret < 0)
- goto error_free_regulators;
-
- return 0;
-
-error_free_regulators:
- regulator_bulk_free(ARRAY_SIZE(cs4270->supplies),
- cs4270->supplies);
-
- return ret;
-}
-
-/**
- * cs4270_remove - ASoC remove function
- * @pdev: platform device
- *
- * This function is the counterpart to cs4270_probe().
- */
-static int cs4270_remove(struct snd_soc_codec *codec)
-{
- struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
-
- regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
- regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
-
- return 0;
-};
-
-#ifdef CONFIG_PM
-
-/* This suspend/resume implementation can handle both - a simple standby
- * where the codec remains powered, and a full suspend, where the voltage
- * domain the codec is connected to is teared down and/or any other hardware
- * reset condition is asserted.
- *
- * The codec's own power saving features are enabled in the suspend callback,
- * and all registers are written back to the hardware when resuming.
- */
-
-static int cs4270_soc_suspend(struct snd_soc_codec *codec)
-{
- struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
- int reg, ret;
-
- reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
- if (reg < 0)
- return reg;
-
- ret = snd_soc_write(codec, CS4270_PWRCTL, reg);
- if (ret < 0)
- return ret;
-
- regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies),
- cs4270->supplies);
-
- return 0;
-}
-
-static int cs4270_soc_resume(struct snd_soc_codec *codec)
-{
- struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
- int reg;
-
- regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
- cs4270->supplies);
-
- /* In case the device was put to hard reset during sleep, we need to
- * wait 500ns here before any I2C communication. */
- ndelay(500);
-
- /* first restore the entire register cache ... */
- snd_soc_cache_sync(codec);
-
- /* ... then disable the power-down bits */
- reg = snd_soc_read(codec, CS4270_PWRCTL);
- reg &= ~CS4270_PWRCTL_PDN_ALL;
-
- return snd_soc_write(codec, CS4270_PWRCTL, reg);
-}
-#else
-#define cs4270_soc_suspend NULL
-#define cs4270_soc_resume NULL
-#endif /* CONFIG_PM */
-
-/*
- * ASoC codec driver structure
- */
-static const struct snd_soc_codec_driver soc_codec_device_cs4270 = {
- .probe = cs4270_probe,
- .remove = cs4270_remove,
- .suspend = cs4270_soc_suspend,
- .resume = cs4270_soc_resume,
- .volatile_register = cs4270_reg_is_volatile,
- .readable_register = cs4270_reg_is_readable,
- .reg_cache_size = CS4270_LASTREG + 1,
- .reg_word_size = sizeof(u8),
- .reg_cache_default = cs4270_default_reg_cache,
-};
-
-/**
- * cs4270_i2c_probe - initialize the I2C interface of the CS4270
- * @i2c_client: the I2C client object
- * @id: the I2C device ID (ignored)
- *
- * This function is called whenever the I2C subsystem finds a device that
- * matches the device ID given via a prior call to i2c_add_driver().
- */
-static int cs4270_i2c_probe(struct i2c_client *i2c_client,
- const struct i2c_device_id *id)
-{
- struct cs4270_private *cs4270;
- int ret;
-
- /* Verify that we have a CS4270 */
-
- ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
- if (ret < 0) {
- dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
- i2c_client->addr);
- return ret;
- }
- /* The top four bits of the chip ID should be 1100. */
- if ((ret & 0xF0) != 0xC0) {
- dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n",
- i2c_client->addr);
- return -ENODEV;
- }
-
- dev_info(&i2c_client->dev, "found device at i2c address %X\n",
- i2c_client->addr);
- dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF);
-
- cs4270 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs4270_private),
- GFP_KERNEL);
- if (!cs4270) {
- dev_err(&i2c_client->dev, "could not allocate codec\n");
- return -ENOMEM;
- }
-
- i2c_set_clientdata(i2c_client, cs4270);
- cs4270->control_type = SND_SOC_I2C;
-
- ret = snd_soc_register_codec(&i2c_client->dev,
- &soc_codec_device_cs4270, &cs4270_dai, 1);
- return ret;
-}
-
-/**
- * cs4270_i2c_remove - remove an I2C device
- * @i2c_client: the I2C client object
- *
- * This function is the counterpart to cs4270_i2c_probe().
- */
-static int cs4270_i2c_remove(struct i2c_client *i2c_client)
-{
- snd_soc_unregister_codec(&i2c_client->dev);
- return 0;
-}
-
-/*
- * cs4270_id - I2C device IDs supported by this driver
- */
-static const struct i2c_device_id cs4270_id[] = {
- {"cs4270", 0},
- {}
-};
-MODULE_DEVICE_TABLE(i2c, cs4270_id);
-
-/*
- * cs4270_i2c_driver - I2C device identification
- *
- * This structure tells the I2C subsystem how to identify and support a
- * given I2C device type.
- */
-static struct i2c_driver cs4270_i2c_driver = {
- .driver = {
- .name = "cs4270",
- .owner = THIS_MODULE,
- },
- .id_table = cs4270_id,
- .probe = cs4270_i2c_probe,
- .remove = cs4270_i2c_remove,
-};
-
-static int __init cs4270_init(void)
-{
- return i2c_add_driver(&cs4270_i2c_driver);
-}
-module_init(cs4270_init);
-
-static void __exit cs4270_exit(void)
-{
- i2c_del_driver(&cs4270_i2c_driver);
-}
-module_exit(cs4270_exit);
-
-MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
-MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/cs4271.c b/ANDROID_3.4.5/sound/soc/codecs/cs4271.c
deleted file mode 100644
index bf714128..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/cs4271.c
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
- * CS4271 ASoC codec driver
- *
- * Copyright (c) 2010 Alexander Sverdlin <subaparts@yandex.ru>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * This driver support CS4271 codec being master or slave, working
- * in control port mode, connected either via SPI or I2C.
- * The data format accepted is I2S or left-justified.
- * DAPM support not implemented.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/tlv.h>
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-#include <linux/spi/spi.h>
-#include <sound/cs4271.h>
-
-#define CS4271_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
- SNDRV_PCM_FMTBIT_S24_LE | \
- SNDRV_PCM_FMTBIT_S32_LE)
-#define CS4271_PCM_RATES SNDRV_PCM_RATE_8000_192000
-
-/*
- * CS4271 registers
- * High byte represents SPI chip address (0x10) + write command (0)
- * Low byte - codec register address
- */
-#define CS4271_MODE1 0x2001 /* Mode Control 1 */
-#define CS4271_DACCTL 0x2002 /* DAC Control */
-#define CS4271_DACVOL 0x2003 /* DAC Volume & Mixing Control */
-#define CS4271_VOLA 0x2004 /* DAC Channel A Volume Control */
-#define CS4271_VOLB 0x2005 /* DAC Channel B Volume Control */
-#define CS4271_ADCCTL 0x2006 /* ADC Control */
-#define CS4271_MODE2 0x2007 /* Mode Control 2 */
-#define CS4271_CHIPID 0x2008 /* Chip ID */
-
-#define CS4271_FIRSTREG CS4271_MODE1
-#define CS4271_LASTREG CS4271_MODE2
-#define CS4271_NR_REGS ((CS4271_LASTREG & 0xFF) + 1)
-
-/* Bit masks for the CS4271 registers */
-#define CS4271_MODE1_MODE_MASK 0xC0
-#define CS4271_MODE1_MODE_1X 0x00
-#define CS4271_MODE1_MODE_2X 0x80
-#define CS4271_MODE1_MODE_4X 0xC0
-
-#define CS4271_MODE1_DIV_MASK 0x30
-#define CS4271_MODE1_DIV_1 0x00
-#define CS4271_MODE1_DIV_15 0x10
-#define CS4271_MODE1_DIV_2 0x20
-#define CS4271_MODE1_DIV_3 0x30
-
-#define CS4271_MODE1_MASTER 0x08
-
-#define CS4271_MODE1_DAC_DIF_MASK 0x07
-#define CS4271_MODE1_DAC_DIF_LJ 0x00
-#define CS4271_MODE1_DAC_DIF_I2S 0x01
-#define CS4271_MODE1_DAC_DIF_RJ16 0x02
-#define CS4271_MODE1_DAC_DIF_RJ24 0x03
-#define CS4271_MODE1_DAC_DIF_RJ20 0x04
-#define CS4271_MODE1_DAC_DIF_RJ18 0x05
-
-#define CS4271_DACCTL_AMUTE 0x80
-#define CS4271_DACCTL_IF_SLOW 0x40
-
-#define CS4271_DACCTL_DEM_MASK 0x30
-#define CS4271_DACCTL_DEM_DIS 0x00
-#define CS4271_DACCTL_DEM_441 0x10
-#define CS4271_DACCTL_DEM_48 0x20
-#define CS4271_DACCTL_DEM_32 0x30
-
-#define CS4271_DACCTL_SVRU 0x08
-#define CS4271_DACCTL_SRD 0x04
-#define CS4271_DACCTL_INVA 0x02
-#define CS4271_DACCTL_INVB 0x01
-
-#define CS4271_DACVOL_BEQUA 0x40
-#define CS4271_DACVOL_SOFT 0x20
-#define CS4271_DACVOL_ZEROC 0x10
-
-#define CS4271_DACVOL_ATAPI_MASK 0x0F
-#define CS4271_DACVOL_ATAPI_M_M 0x00
-#define CS4271_DACVOL_ATAPI_M_BR 0x01
-#define CS4271_DACVOL_ATAPI_M_BL 0x02
-#define CS4271_DACVOL_ATAPI_M_BLR2 0x03
-#define CS4271_DACVOL_ATAPI_AR_M 0x04
-#define CS4271_DACVOL_ATAPI_AR_BR 0x05
-#define CS4271_DACVOL_ATAPI_AR_BL 0x06
-#define CS4271_DACVOL_ATAPI_AR_BLR2 0x07
-#define CS4271_DACVOL_ATAPI_AL_M 0x08
-#define CS4271_DACVOL_ATAPI_AL_BR 0x09
-#define CS4271_DACVOL_ATAPI_AL_BL 0x0A
-#define CS4271_DACVOL_ATAPI_AL_BLR2 0x0B
-#define CS4271_DACVOL_ATAPI_ALR2_M 0x0C
-#define CS4271_DACVOL_ATAPI_ALR2_BR 0x0D
-#define CS4271_DACVOL_ATAPI_ALR2_BL 0x0E
-#define CS4271_DACVOL_ATAPI_ALR2_BLR2 0x0F
-
-#define CS4271_VOLA_MUTE 0x80
-#define CS4271_VOLA_VOL_MASK 0x7F
-#define CS4271_VOLB_MUTE 0x80
-#define CS4271_VOLB_VOL_MASK 0x7F
-
-#define CS4271_ADCCTL_DITHER16 0x20
-
-#define CS4271_ADCCTL_ADC_DIF_MASK 0x10
-#define CS4271_ADCCTL_ADC_DIF_LJ 0x00
-#define CS4271_ADCCTL_ADC_DIF_I2S 0x10
-
-#define CS4271_ADCCTL_MUTEA 0x08
-#define CS4271_ADCCTL_MUTEB 0x04
-#define CS4271_ADCCTL_HPFDA 0x02
-#define CS4271_ADCCTL_HPFDB 0x01
-
-#define CS4271_MODE2_LOOP 0x10
-#define CS4271_MODE2_MUTECAEQUB 0x08
-#define CS4271_MODE2_FREEZE 0x04
-#define CS4271_MODE2_CPEN 0x02
-#define CS4271_MODE2_PDN 0x01
-
-#define CS4271_CHIPID_PART_MASK 0xF0
-#define CS4271_CHIPID_REV_MASK 0x0F
-
-/*
- * Default CS4271 power-up configuration
- * Array contains non-existing in hw register at address 0
- * Array do not include Chip ID, as codec driver does not use
- * registers read operations at all
- */
-static const u8 cs4271_dflt_reg[CS4271_NR_REGS] = {
- 0,
- 0,
- CS4271_DACCTL_AMUTE,
- CS4271_DACVOL_SOFT | CS4271_DACVOL_ATAPI_AL_BR,
- 0,
- 0,
- 0,
- 0,
-};
-
-struct cs4271_private {
- /* SND_SOC_I2C or SND_SOC_SPI */
- enum snd_soc_control_type bus_type;
- unsigned int mclk;
- bool master;
- bool deemph;
- /* Current sample rate for de-emphasis control */
- int rate;
- /* GPIO driving Reset pin, if any */
- int gpio_nreset;
- /* GPIO that disable serial bus, if any */
- int gpio_disable;
-};
-
-/*
- * @freq is the desired MCLK rate
- * MCLK rate should (c) be the sample rate, multiplied by one of the
- * ratios listed in cs4271_mclk_fs_ratios table
- */
-static int cs4271_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
-
- cs4271->mclk = freq;
- return 0;
-}
-
-static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int format)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
- unsigned int val = 0;
- int ret;
-
- switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- cs4271->master = 0;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- cs4271->master = 1;
- val |= CS4271_MODE1_MASTER;
- break;
- default:
- dev_err(codec->dev, "Invalid DAI format\n");
- return -EINVAL;
- }
-
- switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_LEFT_J:
- val |= CS4271_MODE1_DAC_DIF_LJ;
- ret = snd_soc_update_bits(codec, CS4271_ADCCTL,
- CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_LJ);
- if (ret < 0)
- return ret;
- break;
- case SND_SOC_DAIFMT_I2S:
- val |= CS4271_MODE1_DAC_DIF_I2S;
- ret = snd_soc_update_bits(codec, CS4271_ADCCTL,
- CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_I2S);
- if (ret < 0)
- return ret;
- break;
- default:
- dev_err(codec->dev, "Invalid DAI format\n");
- return -EINVAL;
- }
-
- ret = snd_soc_update_bits(codec, CS4271_MODE1,
- CS4271_MODE1_DAC_DIF_MASK | CS4271_MODE1_MASTER, val);
- if (ret < 0)
- return ret;
- return 0;
-}
-
-static int cs4271_deemph[] = {0, 44100, 48000, 32000};
-
-static int cs4271_set_deemph(struct snd_soc_codec *codec)
-{
- struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
- int i, ret;
- int val = CS4271_DACCTL_DEM_DIS;
-
- if (cs4271->deemph) {
- /* Find closest de-emphasis freq */
- val = 1;
- for (i = 2; i < ARRAY_SIZE(cs4271_deemph); i++)
- if (abs(cs4271_deemph[i] - cs4271->rate) <
- abs(cs4271_deemph[val] - cs4271->rate))
- val = i;
- val <<= 4;
- }
-
- ret = snd_soc_update_bits(codec, CS4271_DACCTL,
- CS4271_DACCTL_DEM_MASK, val);
- if (ret < 0)
- return ret;
- return 0;
-}
-
-static int cs4271_get_deemph(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.enumerated.item[0] = cs4271->deemph;
- return 0;
-}
-
-static int cs4271_put_deemph(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
-
- cs4271->deemph = ucontrol->value.enumerated.item[0];
- return cs4271_set_deemph(codec);
-}
-
-struct cs4271_clk_cfg {
- bool master; /* codec mode */
- u8 speed_mode; /* codec speed mode: 1x, 2x, 4x */
- unsigned short ratio; /* MCLK / sample rate */
- u8 ratio_mask; /* ratio bit mask for Master mode */
-};
-
-static struct cs4271_clk_cfg cs4271_clk_tab[] = {
- {1, CS4271_MODE1_MODE_1X, 256, CS4271_MODE1_DIV_1},
- {1, CS4271_MODE1_MODE_1X, 384, CS4271_MODE1_DIV_15},
- {1, CS4271_MODE1_MODE_1X, 512, CS4271_MODE1_DIV_2},
- {1, CS4271_MODE1_MODE_1X, 768, CS4271_MODE1_DIV_3},
- {1, CS4271_MODE1_MODE_2X, 128, CS4271_MODE1_DIV_1},
- {1, CS4271_MODE1_MODE_2X, 192, CS4271_MODE1_DIV_15},
- {1, CS4271_MODE1_MODE_2X, 256, CS4271_MODE1_DIV_2},
- {1, CS4271_MODE1_MODE_2X, 384, CS4271_MODE1_DIV_3},
- {1, CS4271_MODE1_MODE_4X, 64, CS4271_MODE1_DIV_1},
- {1, CS4271_MODE1_MODE_4X, 96, CS4271_MODE1_DIV_15},
- {1, CS4271_MODE1_MODE_4X, 128, CS4271_MODE1_DIV_2},
- {1, CS4271_MODE1_MODE_4X, 192, CS4271_MODE1_DIV_3},
- {0, CS4271_MODE1_MODE_1X, 256, CS4271_MODE1_DIV_1},
- {0, CS4271_MODE1_MODE_1X, 384, CS4271_MODE1_DIV_1},
- {0, CS4271_MODE1_MODE_1X, 512, CS4271_MODE1_DIV_1},
- {0, CS4271_MODE1_MODE_1X, 768, CS4271_MODE1_DIV_2},
- {0, CS4271_MODE1_MODE_1X, 1024, CS4271_MODE1_DIV_2},
- {0, CS4271_MODE1_MODE_2X, 128, CS4271_MODE1_DIV_1},
- {0, CS4271_MODE1_MODE_2X, 192, CS4271_MODE1_DIV_1},
- {0, CS4271_MODE1_MODE_2X, 256, CS4271_MODE1_DIV_1},
- {0, CS4271_MODE1_MODE_2X, 384, CS4271_MODE1_DIV_2},
- {0, CS4271_MODE1_MODE_2X, 512, CS4271_MODE1_DIV_2},
- {0, CS4271_MODE1_MODE_4X, 64, CS4271_MODE1_DIV_1},
- {0, CS4271_MODE1_MODE_4X, 96, CS4271_MODE1_DIV_1},
- {0, CS4271_MODE1_MODE_4X, 128, CS4271_MODE1_DIV_1},
- {0, CS4271_MODE1_MODE_4X, 192, CS4271_MODE1_DIV_2},
- {0, CS4271_MODE1_MODE_4X, 256, CS4271_MODE1_DIV_2},
-};
-
-#define CS4171_NR_RATIOS ARRAY_SIZE(cs4271_clk_tab)
-
-static int cs4271_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
- int i, ret;
- unsigned int ratio, val;
-
- cs4271->rate = params_rate(params);
-
- /* Configure DAC */
- if (cs4271->rate < 50000)
- val = CS4271_MODE1_MODE_1X;
- else if (cs4271->rate < 100000)
- val = CS4271_MODE1_MODE_2X;
- else
- val = CS4271_MODE1_MODE_4X;
-
- ratio = cs4271->mclk / cs4271->rate;
- for (i = 0; i < CS4171_NR_RATIOS; i++)
- if ((cs4271_clk_tab[i].master == cs4271->master) &&
- (cs4271_clk_tab[i].speed_mode == val) &&
- (cs4271_clk_tab[i].ratio == ratio))
- break;
-
- if (i == CS4171_NR_RATIOS) {
- dev_err(codec->dev, "Invalid sample rate\n");
- return -EINVAL;
- }
-
- val |= cs4271_clk_tab[i].ratio_mask;
-
- ret = snd_soc_update_bits(codec, CS4271_MODE1,
- CS4271_MODE1_MODE_MASK | CS4271_MODE1_DIV_MASK, val);
- if (ret < 0)
- return ret;
-
- return cs4271_set_deemph(codec);
-}
-
-static int cs4271_digital_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- int ret;
- int val_a = 0;
- int val_b = 0;
-
- if (mute) {
- val_a = CS4271_VOLA_MUTE;
- val_b = CS4271_VOLB_MUTE;
- }
-
- ret = snd_soc_update_bits(codec, CS4271_VOLA, CS4271_VOLA_MUTE, val_a);
- if (ret < 0)
- return ret;
- ret = snd_soc_update_bits(codec, CS4271_VOLB, CS4271_VOLB_MUTE, val_b);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-/* CS4271 controls */
-static DECLARE_TLV_DB_SCALE(cs4271_dac_tlv, -12700, 100, 0);
-
-static const struct snd_kcontrol_new cs4271_snd_controls[] = {
- SOC_DOUBLE_R_TLV("Master Playback Volume", CS4271_VOLA, CS4271_VOLB,
- 0, 0x7F, 1, cs4271_dac_tlv),
- SOC_SINGLE("Digital Loopback Switch", CS4271_MODE2, 4, 1, 0),
- SOC_SINGLE("Soft Ramp Switch", CS4271_DACVOL, 5, 1, 0),
- SOC_SINGLE("Zero Cross Switch", CS4271_DACVOL, 4, 1, 0),
- SOC_SINGLE_BOOL_EXT("De-emphasis Switch", 0,
- cs4271_get_deemph, cs4271_put_deemph),
- SOC_SINGLE("Auto-Mute Switch", CS4271_DACCTL, 7, 1, 0),
- SOC_SINGLE("Slow Roll Off Filter Switch", CS4271_DACCTL, 6, 1, 0),
- SOC_SINGLE("Soft Volume Ramp-Up Switch", CS4271_DACCTL, 3, 1, 0),
- SOC_SINGLE("Soft Ramp-Down Switch", CS4271_DACCTL, 2, 1, 0),
- SOC_SINGLE("Left Channel Inversion Switch", CS4271_DACCTL, 1, 1, 0),
- SOC_SINGLE("Right Channel Inversion Switch", CS4271_DACCTL, 0, 1, 0),
- SOC_DOUBLE("Master Capture Switch", CS4271_ADCCTL, 3, 2, 1, 1),
- SOC_SINGLE("Dither 16-Bit Data Switch", CS4271_ADCCTL, 5, 1, 0),
- SOC_DOUBLE("High Pass Filter Switch", CS4271_ADCCTL, 1, 0, 1, 1),
- SOC_DOUBLE_R("Master Playback Switch", CS4271_VOLA, CS4271_VOLB,
- 7, 1, 1),
-};
-
-static const struct snd_soc_dai_ops cs4271_dai_ops = {
- .hw_params = cs4271_hw_params,
- .set_sysclk = cs4271_set_dai_sysclk,
- .set_fmt = cs4271_set_dai_fmt,
- .digital_mute = cs4271_digital_mute,
-};
-
-static struct snd_soc_dai_driver cs4271_dai = {
- .name = "cs4271-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = CS4271_PCM_RATES,
- .formats = CS4271_PCM_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = CS4271_PCM_RATES,
- .formats = CS4271_PCM_FORMATS,
- },
- .ops = &cs4271_dai_ops,
- .symmetric_rates = 1,
-};
-
-#ifdef CONFIG_PM
-static int cs4271_soc_suspend(struct snd_soc_codec *codec)
-{
- int ret;
- /* Set power-down bit */
- ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN,
- CS4271_MODE2_PDN);
- if (ret < 0)
- return ret;
- return 0;
-}
-
-static int cs4271_soc_resume(struct snd_soc_codec *codec)
-{
- int ret;
- /* Restore codec state */
- ret = snd_soc_cache_sync(codec);
- if (ret < 0)
- return ret;
- /* then disable the power-down bit */
- ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0);
- if (ret < 0)
- return ret;
- return 0;
-}
-#else
-#define cs4271_soc_suspend NULL
-#define cs4271_soc_resume NULL
-#endif /* CONFIG_PM */
-
-static int cs4271_probe(struct snd_soc_codec *codec)
-{
- struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
- struct cs4271_platform_data *cs4271plat = codec->dev->platform_data;
- int ret;
- int gpio_nreset = -EINVAL;
-
- if (cs4271plat && gpio_is_valid(cs4271plat->gpio_nreset))
- gpio_nreset = cs4271plat->gpio_nreset;
-
- if (gpio_nreset >= 0)
- if (gpio_request(gpio_nreset, "CS4271 Reset"))
- gpio_nreset = -EINVAL;
- if (gpio_nreset >= 0) {
- /* Reset codec */
- gpio_direction_output(gpio_nreset, 0);
- udelay(1);
- gpio_set_value(gpio_nreset, 1);
- /* Give the codec time to wake up */
- udelay(1);
- }
-
- cs4271->gpio_nreset = gpio_nreset;
-
- /*
- * In case of I2C, chip address specified in board data.
- * So cache IO operations use 8 bit codec register address.
- * In case of SPI, chip address and register address
- * passed together as 16 bit value.
- * Anyway, register address is masked with 0xFF inside
- * soc-cache code.
- */
- if (cs4271->bus_type == SND_SOC_SPI)
- ret = snd_soc_codec_set_cache_io(codec, 16, 8,
- cs4271->bus_type);
- else
- ret = snd_soc_codec_set_cache_io(codec, 8, 8,
- cs4271->bus_type);
- if (ret) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- ret = snd_soc_update_bits(codec, CS4271_MODE2,
- CS4271_MODE2_PDN | CS4271_MODE2_CPEN,
- CS4271_MODE2_PDN | CS4271_MODE2_CPEN);
- if (ret < 0)
- return ret;
- ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0);
- if (ret < 0)
- return ret;
- /* Power-up sequence requires 85 uS */
- udelay(85);
-
- return snd_soc_add_codec_controls(codec, cs4271_snd_controls,
- ARRAY_SIZE(cs4271_snd_controls));
-}
-
-static int cs4271_remove(struct snd_soc_codec *codec)
-{
- struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
- int gpio_nreset;
-
- gpio_nreset = cs4271->gpio_nreset;
-
- if (gpio_is_valid(gpio_nreset)) {
- /* Set codec to the reset state */
- gpio_set_value(gpio_nreset, 0);
- gpio_free(gpio_nreset);
- }
-
- return 0;
-};
-
-static struct snd_soc_codec_driver soc_codec_dev_cs4271 = {
- .probe = cs4271_probe,
- .remove = cs4271_remove,
- .suspend = cs4271_soc_suspend,
- .resume = cs4271_soc_resume,
- .reg_cache_default = cs4271_dflt_reg,
- .reg_cache_size = ARRAY_SIZE(cs4271_dflt_reg),
- .reg_word_size = sizeof(cs4271_dflt_reg[0]),
- .compress_type = SND_SOC_FLAT_COMPRESSION,
-};
-
-#if defined(CONFIG_SPI_MASTER)
-static int __devinit cs4271_spi_probe(struct spi_device *spi)
-{
- struct cs4271_private *cs4271;
-
- cs4271 = devm_kzalloc(&spi->dev, sizeof(*cs4271), GFP_KERNEL);
- if (!cs4271)
- return -ENOMEM;
-
- spi_set_drvdata(spi, cs4271);
- cs4271->bus_type = SND_SOC_SPI;
-
- return snd_soc_register_codec(&spi->dev, &soc_codec_dev_cs4271,
- &cs4271_dai, 1);
-}
-
-static int __devexit cs4271_spi_remove(struct spi_device *spi)
-{
- snd_soc_unregister_codec(&spi->dev);
- return 0;
-}
-
-static struct spi_driver cs4271_spi_driver = {
- .driver = {
- .name = "cs4271",
- .owner = THIS_MODULE,
- },
- .probe = cs4271_spi_probe,
- .remove = __devexit_p(cs4271_spi_remove),
-};
-#endif /* defined(CONFIG_SPI_MASTER) */
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static const struct i2c_device_id cs4271_i2c_id[] = {
- {"cs4271", 0},
- {}
-};
-MODULE_DEVICE_TABLE(i2c, cs4271_i2c_id);
-
-static int __devinit cs4271_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct cs4271_private *cs4271;
-
- cs4271 = devm_kzalloc(&client->dev, sizeof(*cs4271), GFP_KERNEL);
- if (!cs4271)
- return -ENOMEM;
-
- i2c_set_clientdata(client, cs4271);
- cs4271->bus_type = SND_SOC_I2C;
-
- return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4271,
- &cs4271_dai, 1);
-}
-
-static int __devexit cs4271_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static struct i2c_driver cs4271_i2c_driver = {
- .driver = {
- .name = "cs4271",
- .owner = THIS_MODULE,
- },
- .id_table = cs4271_i2c_id,
- .probe = cs4271_i2c_probe,
- .remove = __devexit_p(cs4271_i2c_remove),
-};
-#endif /* defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) */
-
-/*
- * We only register our serial bus driver here without
- * assignment to particular chip. So if any of the below
- * fails, there is some problem with I2C or SPI subsystem.
- * In most cases this module will be compiled with support
- * of only one serial bus.
- */
-static int __init cs4271_modinit(void)
-{
- int ret;
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&cs4271_i2c_driver);
- if (ret) {
- pr_err("Failed to register CS4271 I2C driver: %d\n", ret);
- return ret;
- }
-#endif
-
-#if defined(CONFIG_SPI_MASTER)
- ret = spi_register_driver(&cs4271_spi_driver);
- if (ret) {
- pr_err("Failed to register CS4271 SPI driver: %d\n", ret);
- return ret;
- }
-#endif
-
- return 0;
-}
-module_init(cs4271_modinit);
-
-static void __exit cs4271_modexit(void)
-{
-#if defined(CONFIG_SPI_MASTER)
- spi_unregister_driver(&cs4271_spi_driver);
-#endif
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&cs4271_i2c_driver);
-#endif
-}
-module_exit(cs4271_modexit);
-
-MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>");
-MODULE_DESCRIPTION("Cirrus Logic CS4271 ALSA SoC Codec Driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/cs42l51.c b/ANDROID_3.4.5/sound/soc/codecs/cs42l51.c
deleted file mode 100644
index a8bf588e..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/cs42l51.c
+++ /dev/null
@@ -1,639 +0,0 @@
-/*
- * cs42l51.c
- *
- * ASoC Driver for Cirrus Logic CS42L51 codecs
- *
- * Copyright (c) 2010 Arnaud Patard <apatard@mandriva.com>
- *
- * Based on cs4270.c - Copyright (c) Freescale Semiconductor
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * For now:
- * - Only I2C is support. Not SPI
- * - master mode *NOT* supported
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/soc.h>
-#include <sound/tlv.h>
-#include <sound/initval.h>
-#include <sound/pcm_params.h>
-#include <sound/pcm.h>
-#include <linux/i2c.h>
-
-#include "cs42l51.h"
-
-enum master_slave_mode {
- MODE_SLAVE,
- MODE_SLAVE_AUTO,
- MODE_MASTER,
-};
-
-struct cs42l51_private {
- enum snd_soc_control_type control_type;
- unsigned int mclk;
- unsigned int audio_mode; /* The mode (I2S or left-justified) */
- enum master_slave_mode func;
-};
-
-#define CS42L51_FORMATS ( \
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
- SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
- SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
-
-static int cs42l51_fill_cache(struct snd_soc_codec *codec)
-{
- u8 *cache = codec->reg_cache + 1;
- struct i2c_client *i2c_client = to_i2c_client(codec->dev);
- s32 length;
-
- length = i2c_smbus_read_i2c_block_data(i2c_client,
- CS42L51_FIRSTREG | 0x80, CS42L51_NUMREGS, cache);
- if (length != CS42L51_NUMREGS) {
- dev_err(&i2c_client->dev,
- "I2C read failure, addr=0x%x (ret=%d vs %d)\n",
- i2c_client->addr, length, CS42L51_NUMREGS);
- return -EIO;
- }
-
- return 0;
-}
-
-static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned long value = snd_soc_read(codec, CS42L51_PCM_MIXER)&3;
-
- switch (value) {
- default:
- case 0:
- ucontrol->value.integer.value[0] = 0;
- break;
- /* same value : (L+R)/2 and (R+L)/2 */
- case 1:
- case 2:
- ucontrol->value.integer.value[0] = 1;
- break;
- case 3:
- ucontrol->value.integer.value[0] = 2;
- break;
- }
-
- return 0;
-}
-
-#define CHAN_MIX_NORMAL 0x00
-#define CHAN_MIX_BOTH 0x55
-#define CHAN_MIX_SWAP 0xFF
-
-static int cs42l51_set_chan_mix(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned char val;
-
- switch (ucontrol->value.integer.value[0]) {
- default:
- case 0:
- val = CHAN_MIX_NORMAL;
- break;
- case 1:
- val = CHAN_MIX_BOTH;
- break;
- case 2:
- val = CHAN_MIX_SWAP;
- break;
- }
-
- snd_soc_write(codec, CS42L51_PCM_MIXER, val);
-
- return 1;
-}
-
-static const DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -5150, 50, 0);
-static const DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0);
-/* This is a lie. after -102 db, it stays at -102 */
-/* maybe a range would be better */
-static const DECLARE_TLV_DB_SCALE(aout_tlv, -11550, 50, 0);
-
-static const DECLARE_TLV_DB_SCALE(boost_tlv, 1600, 1600, 0);
-static const char *chan_mix[] = {
- "L R",
- "L+R",
- "R L",
-};
-
-static const struct soc_enum cs42l51_chan_mix =
- SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(chan_mix), chan_mix);
-
-static const struct snd_kcontrol_new cs42l51_snd_controls[] = {
- SOC_DOUBLE_R_SX_TLV("PCM Playback Volume",
- CS42L51_PCMA_VOL, CS42L51_PCMB_VOL,
- 7, 0xffffff99, 0x18, adc_pcm_tlv),
- SOC_DOUBLE_R("PCM Playback Switch",
- CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 7, 1, 1),
- SOC_DOUBLE_R_SX_TLV("Analog Playback Volume",
- CS42L51_AOUTA_VOL, CS42L51_AOUTB_VOL,
- 8, 0xffffff19, 0x18, aout_tlv),
- SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume",
- CS42L51_ADCA_VOL, CS42L51_ADCB_VOL,
- 7, 0xffffff99, 0x18, adc_pcm_tlv),
- SOC_DOUBLE_R("ADC Mixer Switch",
- CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 7, 1, 1),
- SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0),
- SOC_SINGLE("Auto-Mute Switch", CS42L51_DAC_CTL, 2, 1, 0),
- SOC_SINGLE("Soft Ramp Switch", CS42L51_DAC_CTL, 1, 1, 0),
- SOC_SINGLE("Zero Cross Switch", CS42L51_DAC_CTL, 0, 0, 0),
- SOC_DOUBLE_TLV("Mic Boost Volume",
- CS42L51_MIC_CTL, 0, 1, 1, 0, boost_tlv),
- SOC_SINGLE_TLV("Bass Volume", CS42L51_TONE_CTL, 0, 0xf, 1, tone_tlv),
- SOC_SINGLE_TLV("Treble Volume", CS42L51_TONE_CTL, 4, 0xf, 1, tone_tlv),
- SOC_ENUM_EXT("PCM channel mixer",
- cs42l51_chan_mix,
- cs42l51_get_chan_mix, cs42l51_set_chan_mix),
-};
-
-/*
- * to power down, one must:
- * 1.) Enable the PDN bit
- * 2.) enable power-down for the select channels
- * 3.) disable the PDN bit.
- */
-static int cs42l51_pdn_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- switch (event) {
- case SND_SOC_DAPM_PRE_PMD:
- snd_soc_update_bits(w->codec, CS42L51_POWER_CTL1,
- CS42L51_POWER_CTL1_PDN,
- CS42L51_POWER_CTL1_PDN);
- break;
- default:
- case SND_SOC_DAPM_POST_PMD:
- snd_soc_update_bits(w->codec, CS42L51_POWER_CTL1,
- CS42L51_POWER_CTL1_PDN, 0);
- break;
- }
-
- return 0;
-}
-
-static const char *cs42l51_dac_names[] = {"Direct PCM",
- "DSP PCM", "ADC"};
-static const struct soc_enum cs42l51_dac_mux_enum =
- SOC_ENUM_SINGLE(CS42L51_DAC_CTL, 6, 3, cs42l51_dac_names);
-static const struct snd_kcontrol_new cs42l51_dac_mux_controls =
- SOC_DAPM_ENUM("Route", cs42l51_dac_mux_enum);
-
-static const char *cs42l51_adcl_names[] = {"AIN1 Left", "AIN2 Left",
- "MIC Left", "MIC+preamp Left"};
-static const struct soc_enum cs42l51_adcl_mux_enum =
- SOC_ENUM_SINGLE(CS42L51_ADC_INPUT, 4, 4, cs42l51_adcl_names);
-static const struct snd_kcontrol_new cs42l51_adcl_mux_controls =
- SOC_DAPM_ENUM("Route", cs42l51_adcl_mux_enum);
-
-static const char *cs42l51_adcr_names[] = {"AIN1 Right", "AIN2 Right",
- "MIC Right", "MIC+preamp Right"};
-static const struct soc_enum cs42l51_adcr_mux_enum =
- SOC_ENUM_SINGLE(CS42L51_ADC_INPUT, 6, 4, cs42l51_adcr_names);
-static const struct snd_kcontrol_new cs42l51_adcr_mux_controls =
- SOC_DAPM_ENUM("Route", cs42l51_adcr_mux_enum);
-
-static const struct snd_soc_dapm_widget cs42l51_dapm_widgets[] = {
- SND_SOC_DAPM_MICBIAS("Mic Bias", CS42L51_MIC_POWER_CTL, 1, 1),
- SND_SOC_DAPM_PGA_E("Left PGA", CS42L51_POWER_CTL1, 3, 1, NULL, 0,
- cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
- SND_SOC_DAPM_PGA_E("Right PGA", CS42L51_POWER_CTL1, 4, 1, NULL, 0,
- cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
- SND_SOC_DAPM_ADC_E("Left ADC", "Left HiFi Capture",
- CS42L51_POWER_CTL1, 1, 1,
- cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
- SND_SOC_DAPM_ADC_E("Right ADC", "Right HiFi Capture",
- CS42L51_POWER_CTL1, 2, 1,
- cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
- SND_SOC_DAPM_DAC_E("Left DAC", "Left HiFi Playback",
- CS42L51_POWER_CTL1, 5, 1,
- cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
- SND_SOC_DAPM_DAC_E("Right DAC", "Right HiFi Playback",
- CS42L51_POWER_CTL1, 6, 1,
- cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
-
- /* analog/mic */
- SND_SOC_DAPM_INPUT("AIN1L"),
- SND_SOC_DAPM_INPUT("AIN1R"),
- SND_SOC_DAPM_INPUT("AIN2L"),
- SND_SOC_DAPM_INPUT("AIN2R"),
- SND_SOC_DAPM_INPUT("MICL"),
- SND_SOC_DAPM_INPUT("MICR"),
-
- SND_SOC_DAPM_MIXER("Mic Preamp Left",
- CS42L51_MIC_POWER_CTL, 2, 1, NULL, 0),
- SND_SOC_DAPM_MIXER("Mic Preamp Right",
- CS42L51_MIC_POWER_CTL, 3, 1, NULL, 0),
-
- /* HP */
- SND_SOC_DAPM_OUTPUT("HPL"),
- SND_SOC_DAPM_OUTPUT("HPR"),
-
- /* mux */
- SND_SOC_DAPM_MUX("DAC Mux", SND_SOC_NOPM, 0, 0,
- &cs42l51_dac_mux_controls),
- SND_SOC_DAPM_MUX("PGA-ADC Mux Left", SND_SOC_NOPM, 0, 0,
- &cs42l51_adcl_mux_controls),
- SND_SOC_DAPM_MUX("PGA-ADC Mux Right", SND_SOC_NOPM, 0, 0,
- &cs42l51_adcr_mux_controls),
-};
-
-static const struct snd_soc_dapm_route cs42l51_routes[] = {
- {"HPL", NULL, "Left DAC"},
- {"HPR", NULL, "Right DAC"},
-
- {"Left ADC", NULL, "Left PGA"},
- {"Right ADC", NULL, "Right PGA"},
-
- {"Mic Preamp Left", NULL, "MICL"},
- {"Mic Preamp Right", NULL, "MICR"},
-
- {"PGA-ADC Mux Left", "AIN1 Left", "AIN1L" },
- {"PGA-ADC Mux Left", "AIN2 Left", "AIN2L" },
- {"PGA-ADC Mux Left", "MIC Left", "MICL" },
- {"PGA-ADC Mux Left", "MIC+preamp Left", "Mic Preamp Left" },
- {"PGA-ADC Mux Right", "AIN1 Right", "AIN1R" },
- {"PGA-ADC Mux Right", "AIN2 Right", "AIN2R" },
- {"PGA-ADC Mux Right", "MIC Right", "MICR" },
- {"PGA-ADC Mux Right", "MIC+preamp Right", "Mic Preamp Right" },
-
- {"Left PGA", NULL, "PGA-ADC Mux Left"},
- {"Right PGA", NULL, "PGA-ADC Mux Right"},
-};
-
-static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int format)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
-
- switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- case SND_SOC_DAIFMT_LEFT_J:
- case SND_SOC_DAIFMT_RIGHT_J:
- cs42l51->audio_mode = format & SND_SOC_DAIFMT_FORMAT_MASK;
- break;
- default:
- dev_err(codec->dev, "invalid DAI format\n");
- return -EINVAL;
- }
-
- switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- cs42l51->func = MODE_MASTER;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- cs42l51->func = MODE_SLAVE_AUTO;
- break;
- default:
- dev_err(codec->dev, "Unknown master/slave configuration\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-struct cs42l51_ratios {
- unsigned int ratio;
- unsigned char speed_mode;
- unsigned char mclk;
-};
-
-static struct cs42l51_ratios slave_ratios[] = {
- { 512, CS42L51_QSM_MODE, 0 }, { 768, CS42L51_QSM_MODE, 0 },
- { 1024, CS42L51_QSM_MODE, 0 }, { 1536, CS42L51_QSM_MODE, 0 },
- { 2048, CS42L51_QSM_MODE, 0 }, { 3072, CS42L51_QSM_MODE, 0 },
- { 256, CS42L51_HSM_MODE, 0 }, { 384, CS42L51_HSM_MODE, 0 },
- { 512, CS42L51_HSM_MODE, 0 }, { 768, CS42L51_HSM_MODE, 0 },
- { 1024, CS42L51_HSM_MODE, 0 }, { 1536, CS42L51_HSM_MODE, 0 },
- { 128, CS42L51_SSM_MODE, 0 }, { 192, CS42L51_SSM_MODE, 0 },
- { 256, CS42L51_SSM_MODE, 0 }, { 384, CS42L51_SSM_MODE, 0 },
- { 512, CS42L51_SSM_MODE, 0 }, { 768, CS42L51_SSM_MODE, 0 },
- { 128, CS42L51_DSM_MODE, 0 }, { 192, CS42L51_DSM_MODE, 0 },
- { 256, CS42L51_DSM_MODE, 0 }, { 384, CS42L51_DSM_MODE, 0 },
-};
-
-static struct cs42l51_ratios slave_auto_ratios[] = {
- { 1024, CS42L51_QSM_MODE, 0 }, { 1536, CS42L51_QSM_MODE, 0 },
- { 2048, CS42L51_QSM_MODE, 1 }, { 3072, CS42L51_QSM_MODE, 1 },
- { 512, CS42L51_HSM_MODE, 0 }, { 768, CS42L51_HSM_MODE, 0 },
- { 1024, CS42L51_HSM_MODE, 1 }, { 1536, CS42L51_HSM_MODE, 1 },
- { 256, CS42L51_SSM_MODE, 0 }, { 384, CS42L51_SSM_MODE, 0 },
- { 512, CS42L51_SSM_MODE, 1 }, { 768, CS42L51_SSM_MODE, 1 },
- { 128, CS42L51_DSM_MODE, 0 }, { 192, CS42L51_DSM_MODE, 0 },
- { 256, CS42L51_DSM_MODE, 1 }, { 384, CS42L51_DSM_MODE, 1 },
-};
-
-static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
-
- cs42l51->mclk = freq;
- return 0;
-}
-
-static int cs42l51_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
- int ret;
- unsigned int i;
- unsigned int rate;
- unsigned int ratio;
- struct cs42l51_ratios *ratios = NULL;
- int nr_ratios = 0;
- int intf_ctl, power_ctl, fmt;
-
- switch (cs42l51->func) {
- case MODE_MASTER:
- return -EINVAL;
- case MODE_SLAVE:
- ratios = slave_ratios;
- nr_ratios = ARRAY_SIZE(slave_ratios);
- break;
- case MODE_SLAVE_AUTO:
- ratios = slave_auto_ratios;
- nr_ratios = ARRAY_SIZE(slave_auto_ratios);
- break;
- }
-
- /* Figure out which MCLK/LRCK ratio to use */
- rate = params_rate(params); /* Sampling rate, in Hz */
- ratio = cs42l51->mclk / rate; /* MCLK/LRCK ratio */
- for (i = 0; i < nr_ratios; i++) {
- if (ratios[i].ratio == ratio)
- break;
- }
-
- if (i == nr_ratios) {
- /* We did not find a matching ratio */
- dev_err(codec->dev, "could not find matching ratio\n");
- return -EINVAL;
- }
-
- intf_ctl = snd_soc_read(codec, CS42L51_INTF_CTL);
- power_ctl = snd_soc_read(codec, CS42L51_MIC_POWER_CTL);
-
- intf_ctl &= ~(CS42L51_INTF_CTL_MASTER | CS42L51_INTF_CTL_ADC_I2S
- | CS42L51_INTF_CTL_DAC_FORMAT(7));
- power_ctl &= ~(CS42L51_MIC_POWER_CTL_SPEED(3)
- | CS42L51_MIC_POWER_CTL_MCLK_DIV2);
-
- switch (cs42l51->func) {
- case MODE_MASTER:
- intf_ctl |= CS42L51_INTF_CTL_MASTER;
- power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode);
- break;
- case MODE_SLAVE:
- power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode);
- break;
- case MODE_SLAVE_AUTO:
- power_ctl |= CS42L51_MIC_POWER_CTL_AUTO;
- break;
- }
-
- switch (cs42l51->audio_mode) {
- case SND_SOC_DAIFMT_I2S:
- intf_ctl |= CS42L51_INTF_CTL_ADC_I2S;
- intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_I2S);
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_LJ24);
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- case SNDRV_PCM_FORMAT_S16_BE:
- fmt = CS42L51_DAC_DIF_RJ16;
- break;
- case SNDRV_PCM_FORMAT_S18_3LE:
- case SNDRV_PCM_FORMAT_S18_3BE:
- fmt = CS42L51_DAC_DIF_RJ18;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- case SNDRV_PCM_FORMAT_S20_3BE:
- fmt = CS42L51_DAC_DIF_RJ20;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- case SNDRV_PCM_FORMAT_S24_BE:
- fmt = CS42L51_DAC_DIF_RJ24;
- break;
- default:
- dev_err(codec->dev, "unknown format\n");
- return -EINVAL;
- }
- intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(fmt);
- break;
- default:
- dev_err(codec->dev, "unknown format\n");
- return -EINVAL;
- }
-
- if (ratios[i].mclk)
- power_ctl |= CS42L51_MIC_POWER_CTL_MCLK_DIV2;
-
- ret = snd_soc_write(codec, CS42L51_INTF_CTL, intf_ctl);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_write(codec, CS42L51_MIC_POWER_CTL, power_ctl);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int cs42l51_dai_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- int reg;
- int mask = CS42L51_DAC_OUT_CTL_DACA_MUTE|CS42L51_DAC_OUT_CTL_DACB_MUTE;
-
- reg = snd_soc_read(codec, CS42L51_DAC_OUT_CTL);
-
- if (mute)
- reg |= mask;
- else
- reg &= ~mask;
-
- return snd_soc_write(codec, CS42L51_DAC_OUT_CTL, reg);
-}
-
-static const struct snd_soc_dai_ops cs42l51_dai_ops = {
- .hw_params = cs42l51_hw_params,
- .set_sysclk = cs42l51_set_dai_sysclk,
- .set_fmt = cs42l51_set_dai_fmt,
- .digital_mute = cs42l51_dai_mute,
-};
-
-static struct snd_soc_dai_driver cs42l51_dai = {
- .name = "cs42l51-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = CS42L51_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = CS42L51_FORMATS,
- },
- .ops = &cs42l51_dai_ops,
-};
-
-static int cs42l51_probe(struct snd_soc_codec *codec)
-{
- struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
- int ret, reg;
-
- ret = cs42l51_fill_cache(codec);
- if (ret < 0) {
- dev_err(codec->dev, "failed to fill register cache\n");
- return ret;
- }
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs42l51->control_type);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- /*
- * DAC configuration
- * - Use signal processor
- * - auto mute
- * - vol changes immediate
- * - no de-emphasize
- */
- reg = CS42L51_DAC_CTL_DATA_SEL(1)
- | CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0);
- ret = snd_soc_write(codec, CS42L51_DAC_CTL, reg);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
- .probe = cs42l51_probe,
- .reg_cache_size = CS42L51_NUMREGS + 1,
- .reg_word_size = sizeof(u8),
-
- .controls = cs42l51_snd_controls,
- .num_controls = ARRAY_SIZE(cs42l51_snd_controls),
- .dapm_widgets = cs42l51_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(cs42l51_dapm_widgets),
- .dapm_routes = cs42l51_routes,
- .num_dapm_routes = ARRAY_SIZE(cs42l51_routes),
-};
-
-static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
- const struct i2c_device_id *id)
-{
- struct cs42l51_private *cs42l51;
- int ret;
-
- /* Verify that we have a CS42L51 */
- ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID);
- if (ret < 0) {
- dev_err(&i2c_client->dev, "failed to read I2C\n");
- goto error;
- }
-
- if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
- (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
- dev_err(&i2c_client->dev, "Invalid chip id\n");
- ret = -ENODEV;
- goto error;
- }
-
- dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
- ret & 7);
-
- cs42l51 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l51_private),
- GFP_KERNEL);
- if (!cs42l51) {
- dev_err(&i2c_client->dev, "could not allocate codec\n");
- return -ENOMEM;
- }
-
- i2c_set_clientdata(i2c_client, cs42l51);
- cs42l51->control_type = SND_SOC_I2C;
-
- ret = snd_soc_register_codec(&i2c_client->dev,
- &soc_codec_device_cs42l51, &cs42l51_dai, 1);
-error:
- return ret;
-}
-
-static int cs42l51_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static const struct i2c_device_id cs42l51_id[] = {
- {"cs42l51", 0},
- {}
-};
-MODULE_DEVICE_TABLE(i2c, cs42l51_id);
-
-static struct i2c_driver cs42l51_i2c_driver = {
- .driver = {
- .name = "cs42l51-codec",
- .owner = THIS_MODULE,
- },
- .id_table = cs42l51_id,
- .probe = cs42l51_i2c_probe,
- .remove = cs42l51_i2c_remove,
-};
-
-static int __init cs42l51_init(void)
-{
- int ret;
-
- ret = i2c_add_driver(&cs42l51_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "%s: can't add i2c driver\n", __func__);
- return ret;
- }
- return 0;
-}
-module_init(cs42l51_init);
-
-static void __exit cs42l51_exit(void)
-{
- i2c_del_driver(&cs42l51_i2c_driver);
-}
-module_exit(cs42l51_exit);
-
-MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
-MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/cs42l51.h b/ANDROID_3.4.5/sound/soc/codecs/cs42l51.h
deleted file mode 100644
index 2beeb171..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/cs42l51.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * cs42l51.h
- *
- * ASoC Driver for Cirrus Logic CS42L51 codecs
- *
- * Copyright (c) 2010 Arnaud Patard <apatard@mandriva.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-#ifndef _CS42L51_H
-#define _CS42L51_H
-
-#define CS42L51_CHIP_ID 0x1B
-#define CS42L51_CHIP_REV_A 0x00
-#define CS42L51_CHIP_REV_B 0x01
-
-#define CS42L51_CHIP_REV_ID 0x01
-#define CS42L51_MK_CHIP_REV(a, b) ((a)<<3|(b))
-
-#define CS42L51_POWER_CTL1 0x02
-#define CS42L51_POWER_CTL1_PDN_DACB (1<<6)
-#define CS42L51_POWER_CTL1_PDN_DACA (1<<5)
-#define CS42L51_POWER_CTL1_PDN_PGAB (1<<4)
-#define CS42L51_POWER_CTL1_PDN_PGAA (1<<3)
-#define CS42L51_POWER_CTL1_PDN_ADCB (1<<2)
-#define CS42L51_POWER_CTL1_PDN_ADCA (1<<1)
-#define CS42L51_POWER_CTL1_PDN (1<<0)
-
-#define CS42L51_MIC_POWER_CTL 0x03
-#define CS42L51_MIC_POWER_CTL_AUTO (1<<7)
-#define CS42L51_MIC_POWER_CTL_SPEED(x) (((x)&3)<<5)
-#define CS42L51_QSM_MODE 3
-#define CS42L51_HSM_MODE 2
-#define CS42L51_SSM_MODE 1
-#define CS42L51_DSM_MODE 0
-#define CS42L51_MIC_POWER_CTL_3ST_SP (1<<4)
-#define CS42L51_MIC_POWER_CTL_PDN_MICB (1<<3)
-#define CS42L51_MIC_POWER_CTL_PDN_MICA (1<<2)
-#define CS42L51_MIC_POWER_CTL_PDN_BIAS (1<<1)
-#define CS42L51_MIC_POWER_CTL_MCLK_DIV2 (1<<0)
-
-#define CS42L51_INTF_CTL 0x04
-#define CS42L51_INTF_CTL_LOOPBACK (1<<7)
-#define CS42L51_INTF_CTL_MASTER (1<<6)
-#define CS42L51_INTF_CTL_DAC_FORMAT(x) (((x)&7)<<3)
-#define CS42L51_DAC_DIF_LJ24 0x00
-#define CS42L51_DAC_DIF_I2S 0x01
-#define CS42L51_DAC_DIF_RJ24 0x02
-#define CS42L51_DAC_DIF_RJ20 0x03
-#define CS42L51_DAC_DIF_RJ18 0x04
-#define CS42L51_DAC_DIF_RJ16 0x05
-#define CS42L51_INTF_CTL_ADC_I2S (1<<2)
-#define CS42L51_INTF_CTL_DIGMIX (1<<1)
-#define CS42L51_INTF_CTL_MICMIX (1<<0)
-
-#define CS42L51_MIC_CTL 0x05
-#define CS42L51_MIC_CTL_ADC_SNGVOL (1<<7)
-#define CS42L51_MIC_CTL_ADCD_DBOOST (1<<6)
-#define CS42L51_MIC_CTL_ADCA_DBOOST (1<<5)
-#define CS42L51_MIC_CTL_MICBIAS_SEL (1<<4)
-#define CS42L51_MIC_CTL_MICBIAS_LVL(x) (((x)&3)<<2)
-#define CS42L51_MIC_CTL_MICB_BOOST (1<<1)
-#define CS42L51_MIC_CTL_MICA_BOOST (1<<0)
-
-#define CS42L51_ADC_CTL 0x06
-#define CS42L51_ADC_CTL_ADCB_HPFEN (1<<7)
-#define CS42L51_ADC_CTL_ADCB_HPFRZ (1<<6)
-#define CS42L51_ADC_CTL_ADCA_HPFEN (1<<5)
-#define CS42L51_ADC_CTL_ADCA_HPFRZ (1<<4)
-#define CS42L51_ADC_CTL_SOFTB (1<<3)
-#define CS42L51_ADC_CTL_ZCROSSB (1<<2)
-#define CS42L51_ADC_CTL_SOFTA (1<<1)
-#define CS42L51_ADC_CTL_ZCROSSA (1<<0)
-
-#define CS42L51_ADC_INPUT 0x07
-#define CS42L51_ADC_INPUT_AINB_MUX(x) (((x)&3)<<6)
-#define CS42L51_ADC_INPUT_AINA_MUX(x) (((x)&3)<<4)
-#define CS42L51_ADC_INPUT_INV_ADCB (1<<3)
-#define CS42L51_ADC_INPUT_INV_ADCA (1<<2)
-#define CS42L51_ADC_INPUT_ADCB_MUTE (1<<1)
-#define CS42L51_ADC_INPUT_ADCA_MUTE (1<<0)
-
-#define CS42L51_DAC_OUT_CTL 0x08
-#define CS42L51_DAC_OUT_CTL_HP_GAIN(x) (((x)&7)<<5)
-#define CS42L51_DAC_OUT_CTL_DAC_SNGVOL (1<<4)
-#define CS42L51_DAC_OUT_CTL_INV_PCMB (1<<3)
-#define CS42L51_DAC_OUT_CTL_INV_PCMA (1<<2)
-#define CS42L51_DAC_OUT_CTL_DACB_MUTE (1<<1)
-#define CS42L51_DAC_OUT_CTL_DACA_MUTE (1<<0)
-
-#define CS42L51_DAC_CTL 0x09
-#define CS42L51_DAC_CTL_DATA_SEL(x) (((x)&3)<<6)
-#define CS42L51_DAC_CTL_FREEZE (1<<5)
-#define CS42L51_DAC_CTL_DEEMPH (1<<3)
-#define CS42L51_DAC_CTL_AMUTE (1<<2)
-#define CS42L51_DAC_CTL_DACSZ(x) (((x)&3)<<0)
-
-#define CS42L51_ALC_PGA_CTL 0x0A
-#define CS42L51_ALC_PGB_CTL 0x0B
-#define CS42L51_ALC_PGX_ALCX_SRDIS (1<<7)
-#define CS42L51_ALC_PGX_ALCX_ZCDIS (1<<6)
-#define CS42L51_ALC_PGX_PGX_VOL(x) (((x)&0x1f)<<0)
-
-#define CS42L51_ADCA_ATT 0x0C
-#define CS42L51_ADCB_ATT 0x0D
-
-#define CS42L51_ADCA_VOL 0x0E
-#define CS42L51_ADCB_VOL 0x0F
-#define CS42L51_PCMA_VOL 0x10
-#define CS42L51_PCMB_VOL 0x11
-#define CS42L51_MIX_MUTE_ADCMIX (1<<7)
-#define CS42L51_MIX_VOLUME(x) (((x)&0x7f)<<0)
-
-#define CS42L51_BEEP_FREQ 0x12
-#define CS42L51_BEEP_VOL 0x13
-#define CS42L51_BEEP_CONF 0x14
-
-#define CS42L51_TONE_CTL 0x15
-#define CS42L51_TONE_CTL_TREB(x) (((x)&0xf)<<4)
-#define CS42L51_TONE_CTL_BASS(x) (((x)&0xf)<<0)
-
-#define CS42L51_AOUTA_VOL 0x16
-#define CS42L51_AOUTB_VOL 0x17
-#define CS42L51_PCM_MIXER 0x18
-#define CS42L51_LIMIT_THRES_DIS 0x19
-#define CS42L51_LIMIT_REL 0x1A
-#define CS42L51_LIMIT_ATT 0x1B
-#define CS42L51_ALC_EN 0x1C
-#define CS42L51_ALC_REL 0x1D
-#define CS42L51_ALC_THRES 0x1E
-#define CS42L51_NOISE_CONF 0x1F
-
-#define CS42L51_STATUS 0x20
-#define CS42L51_STATUS_SP_CLKERR (1<<6)
-#define CS42L51_STATUS_SPEA_OVFL (1<<5)
-#define CS42L51_STATUS_SPEB_OVFL (1<<4)
-#define CS42L51_STATUS_PCMA_OVFL (1<<3)
-#define CS42L51_STATUS_PCMB_OVFL (1<<2)
-#define CS42L51_STATUS_ADCA_OVFL (1<<1)
-#define CS42L51_STATUS_ADCB_OVFL (1<<0)
-
-#define CS42L51_CHARGE_FREQ 0x21
-
-#define CS42L51_FIRSTREG 0x01
-/*
- * Hack: with register 0x21, it makes 33 registers. Looks like someone in the
- * i2c layer doesn't like i2c smbus block read of 33 regs. Workaround by using
- * 32 regs
- */
-#define CS42L51_LASTREG 0x20
-#define CS42L51_NUMREGS (CS42L51_LASTREG - CS42L51_FIRSTREG + 1)
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/cs42l73.c b/ANDROID_3.4.5/sound/soc/codecs/cs42l73.c
deleted file mode 100644
index 3686417f..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/cs42l73.c
+++ /dev/null
@@ -1,1455 +0,0 @@
-/*
- * cs42l73.c -- CS42L73 ALSA Soc Audio driver
- *
- * Copyright 2011 Cirrus Logic, Inc.
- *
- * Authors: Georgi Vlaev, Nucleus Systems Ltd, <joe@nucleusys.com>
- * Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/regmap.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include "cs42l73.h"
-
-struct sp_config {
- u8 spc, mmcc, spfs;
- u32 srate;
-};
-struct cs42l73_private {
- struct sp_config config[3];
- struct regmap *regmap;
- u32 sysclk;
- u8 mclksel;
- u32 mclk;
-};
-
-static const struct reg_default cs42l73_reg_defaults[] = {
- { 1, 0x42 }, /* r01 - Device ID A&B */
- { 2, 0xA7 }, /* r02 - Device ID C&D */
- { 3, 0x30 }, /* r03 - Device ID E */
- { 6, 0xF1 }, /* r06 - Power Ctl 1 */
- { 7, 0xDF }, /* r07 - Power Ctl 2 */
- { 8, 0x3F }, /* r08 - Power Ctl 3 */
- { 9, 0x50 }, /* r09 - Charge Pump Freq */
- { 10, 0x53 }, /* r0A - Output Load MicBias Short Detect */
- { 11, 0x00 }, /* r0B - DMIC Master Clock Ctl */
- { 12, 0x00 }, /* r0C - Aux PCM Ctl */
- { 13, 0x15 }, /* r0D - Aux PCM Master Clock Ctl */
- { 14, 0x00 }, /* r0E - Audio PCM Ctl */
- { 15, 0x15 }, /* r0F - Audio PCM Master Clock Ctl */
- { 16, 0x00 }, /* r10 - Voice PCM Ctl */
- { 17, 0x15 }, /* r11 - Voice PCM Master Clock Ctl */
- { 18, 0x00 }, /* r12 - Voice/Aux Sample Rate */
- { 19, 0x06 }, /* r13 - Misc I/O Path Ctl */
- { 20, 0x00 }, /* r14 - ADC Input Path Ctl */
- { 21, 0x00 }, /* r15 - MICA Preamp, PGA Volume */
- { 22, 0x00 }, /* r16 - MICB Preamp, PGA Volume */
- { 23, 0x00 }, /* r17 - Input Path A Digital Volume */
- { 24, 0x00 }, /* r18 - Input Path B Digital Volume */
- { 25, 0x00 }, /* r19 - Playback Digital Ctl */
- { 26, 0x00 }, /* r1A - HP/LO Left Digital Volume */
- { 27, 0x00 }, /* r1B - HP/LO Right Digital Volume */
- { 28, 0x00 }, /* r1C - Speakerphone Digital Volume */
- { 29, 0x00 }, /* r1D - Ear/SPKLO Digital Volume */
- { 30, 0x00 }, /* r1E - HP Left Analog Volume */
- { 31, 0x00 }, /* r1F - HP Right Analog Volume */
- { 32, 0x00 }, /* r20 - LO Left Analog Volume */
- { 33, 0x00 }, /* r21 - LO Right Analog Volume */
- { 34, 0x00 }, /* r22 - Stereo Input Path Advisory Volume */
- { 35, 0x00 }, /* r23 - Aux PCM Input Advisory Volume */
- { 36, 0x00 }, /* r24 - Audio PCM Input Advisory Volume */
- { 37, 0x00 }, /* r25 - Voice PCM Input Advisory Volume */
- { 38, 0x00 }, /* r26 - Limiter Attack Rate HP/LO */
- { 39, 0x7F }, /* r27 - Limter Ctl, Release Rate HP/LO */
- { 40, 0x00 }, /* r28 - Limter Threshold HP/LO */
- { 41, 0x00 }, /* r29 - Limiter Attack Rate Speakerphone */
- { 42, 0x3F }, /* r2A - Limter Ctl, Release Rate Speakerphone */
- { 43, 0x00 }, /* r2B - Limter Threshold Speakerphone */
- { 44, 0x00 }, /* r2C - Limiter Attack Rate Ear/SPKLO */
- { 45, 0x3F }, /* r2D - Limter Ctl, Release Rate Ear/SPKLO */
- { 46, 0x00 }, /* r2E - Limter Threshold Ear/SPKLO */
- { 47, 0x00 }, /* r2F - ALC Enable, Attack Rate Left/Right */
- { 48, 0x3F }, /* r30 - ALC Release Rate Left/Right */
- { 49, 0x00 }, /* r31 - ALC Threshold Left/Right */
- { 50, 0x00 }, /* r32 - Noise Gate Ctl Left/Right */
- { 51, 0x00 }, /* r33 - ALC/NG Misc Ctl */
- { 52, 0x18 }, /* r34 - Mixer Ctl */
- { 53, 0x3F }, /* r35 - HP/LO Left Mixer Input Path Volume */
- { 54, 0x3F }, /* r36 - HP/LO Right Mixer Input Path Volume */
- { 55, 0x3F }, /* r37 - HP/LO Left Mixer Aux PCM Volume */
- { 56, 0x3F }, /* r38 - HP/LO Right Mixer Aux PCM Volume */
- { 57, 0x3F }, /* r39 - HP/LO Left Mixer Audio PCM Volume */
- { 58, 0x3F }, /* r3A - HP/LO Right Mixer Audio PCM Volume */
- { 59, 0x3F }, /* r3B - HP/LO Left Mixer Voice PCM Mono Volume */
- { 60, 0x3F }, /* r3C - HP/LO Right Mixer Voice PCM Mono Volume */
- { 61, 0x3F }, /* r3D - Aux PCM Left Mixer Input Path Volume */
- { 62, 0x3F }, /* r3E - Aux PCM Right Mixer Input Path Volume */
- { 63, 0x3F }, /* r3F - Aux PCM Left Mixer Volume */
- { 64, 0x3F }, /* r40 - Aux PCM Left Mixer Volume */
- { 65, 0x3F }, /* r41 - Aux PCM Left Mixer Audio PCM L Volume */
- { 66, 0x3F }, /* r42 - Aux PCM Right Mixer Audio PCM R Volume */
- { 67, 0x3F }, /* r43 - Aux PCM Left Mixer Voice PCM Volume */
- { 68, 0x3F }, /* r44 - Aux PCM Right Mixer Voice PCM Volume */
- { 69, 0x3F }, /* r45 - Audio PCM Left Input Path Volume */
- { 70, 0x3F }, /* r46 - Audio PCM Right Input Path Volume */
- { 71, 0x3F }, /* r47 - Audio PCM Left Mixer Aux PCM L Volume */
- { 72, 0x3F }, /* r48 - Audio PCM Right Mixer Aux PCM R Volume */
- { 73, 0x3F }, /* r49 - Audio PCM Left Mixer Volume */
- { 74, 0x3F }, /* r4A - Audio PCM Right Mixer Volume */
- { 75, 0x3F }, /* r4B - Audio PCM Left Mixer Voice PCM Volume */
- { 76, 0x3F }, /* r4C - Audio PCM Right Mixer Voice PCM Volume */
- { 77, 0x3F }, /* r4D - Voice PCM Left Input Path Volume */
- { 78, 0x3F }, /* r4E - Voice PCM Right Input Path Volume */
- { 79, 0x3F }, /* r4F - Voice PCM Left Mixer Aux PCM L Volume */
- { 80, 0x3F }, /* r50 - Voice PCM Right Mixer Aux PCM R Volume */
- { 81, 0x3F }, /* r51 - Voice PCM Left Mixer Audio PCM L Volume */
- { 82, 0x3F }, /* r52 - Voice PCM Right Mixer Audio PCM R Volume */
- { 83, 0x3F }, /* r53 - Voice PCM Left Mixer Voice PCM Volume */
- { 84, 0x3F }, /* r54 - Voice PCM Right Mixer Voice PCM Volume */
- { 85, 0xAA }, /* r55 - Mono Mixer Ctl */
- { 86, 0x3F }, /* r56 - SPK Mono Mixer Input Path Volume */
- { 87, 0x3F }, /* r57 - SPK Mono Mixer Aux PCM Mono/L/R Volume */
- { 88, 0x3F }, /* r58 - SPK Mono Mixer Audio PCM Mono/L/R Volume */
- { 89, 0x3F }, /* r59 - SPK Mono Mixer Voice PCM Mono Volume */
- { 90, 0x3F }, /* r5A - SPKLO Mono Mixer Input Path Mono Volume */
- { 91, 0x3F }, /* r5B - SPKLO Mono Mixer Aux Mono/L/R Volume */
- { 92, 0x3F }, /* r5C - SPKLO Mono Mixer Audio Mono/L/R Volume */
- { 93, 0x3F }, /* r5D - SPKLO Mono Mixer Voice Mono Volume */
- { 94, 0x00 }, /* r5E - Interrupt Mask 1 */
- { 95, 0x00 }, /* r5F - Interrupt Mask 2 */
-};
-
-static bool cs42l73_volatile_register(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case CS42L73_IS1:
- case CS42L73_IS2:
- return true;
- default:
- return false;
- }
-}
-
-static bool cs42l73_readable_register(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case CS42L73_DEVID_AB:
- case CS42L73_DEVID_CD:
- case CS42L73_DEVID_E:
- case CS42L73_REVID:
- case CS42L73_PWRCTL1:
- case CS42L73_PWRCTL2:
- case CS42L73_PWRCTL3:
- case CS42L73_CPFCHC:
- case CS42L73_OLMBMSDC:
- case CS42L73_DMMCC:
- case CS42L73_XSPC:
- case CS42L73_XSPMMCC:
- case CS42L73_ASPC:
- case CS42L73_ASPMMCC:
- case CS42L73_VSPC:
- case CS42L73_VSPMMCC:
- case CS42L73_VXSPFS:
- case CS42L73_MIOPC:
- case CS42L73_ADCIPC:
- case CS42L73_MICAPREPGAAVOL:
- case CS42L73_MICBPREPGABVOL:
- case CS42L73_IPADVOL:
- case CS42L73_IPBDVOL:
- case CS42L73_PBDC:
- case CS42L73_HLADVOL:
- case CS42L73_HLBDVOL:
- case CS42L73_SPKDVOL:
- case CS42L73_ESLDVOL:
- case CS42L73_HPAAVOL:
- case CS42L73_HPBAVOL:
- case CS42L73_LOAAVOL:
- case CS42L73_LOBAVOL:
- case CS42L73_STRINV:
- case CS42L73_XSPINV:
- case CS42L73_ASPINV:
- case CS42L73_VSPINV:
- case CS42L73_LIMARATEHL:
- case CS42L73_LIMRRATEHL:
- case CS42L73_LMAXHL:
- case CS42L73_LIMARATESPK:
- case CS42L73_LIMRRATESPK:
- case CS42L73_LMAXSPK:
- case CS42L73_LIMARATEESL:
- case CS42L73_LIMRRATEESL:
- case CS42L73_LMAXESL:
- case CS42L73_ALCARATE:
- case CS42L73_ALCRRATE:
- case CS42L73_ALCMINMAX:
- case CS42L73_NGCAB:
- case CS42L73_ALCNGMC:
- case CS42L73_MIXERCTL:
- case CS42L73_HLAIPAA:
- case CS42L73_HLBIPBA:
- case CS42L73_HLAXSPAA:
- case CS42L73_HLBXSPBA:
- case CS42L73_HLAASPAA:
- case CS42L73_HLBASPBA:
- case CS42L73_HLAVSPMA:
- case CS42L73_HLBVSPMA:
- case CS42L73_XSPAIPAA:
- case CS42L73_XSPBIPBA:
- case CS42L73_XSPAXSPAA:
- case CS42L73_XSPBXSPBA:
- case CS42L73_XSPAASPAA:
- case CS42L73_XSPAASPBA:
- case CS42L73_XSPAVSPMA:
- case CS42L73_XSPBVSPMA:
- case CS42L73_ASPAIPAA:
- case CS42L73_ASPBIPBA:
- case CS42L73_ASPAXSPAA:
- case CS42L73_ASPBXSPBA:
- case CS42L73_ASPAASPAA:
- case CS42L73_ASPBASPBA:
- case CS42L73_ASPAVSPMA:
- case CS42L73_ASPBVSPMA:
- case CS42L73_VSPAIPAA:
- case CS42L73_VSPBIPBA:
- case CS42L73_VSPAXSPAA:
- case CS42L73_VSPBXSPBA:
- case CS42L73_VSPAASPAA:
- case CS42L73_VSPBASPBA:
- case CS42L73_VSPAVSPMA:
- case CS42L73_VSPBVSPMA:
- case CS42L73_MMIXCTL:
- case CS42L73_SPKMIPMA:
- case CS42L73_SPKMXSPA:
- case CS42L73_SPKMASPA:
- case CS42L73_SPKMVSPMA:
- case CS42L73_ESLMIPMA:
- case CS42L73_ESLMXSPA:
- case CS42L73_ESLMASPA:
- case CS42L73_ESLMVSPMA:
- case CS42L73_IM1:
- case CS42L73_IM2:
- return true;
- default:
- return false;
- }
-}
-
-static const unsigned int hpaloa_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 13, TLV_DB_SCALE_ITEM(-7600, 200, 0),
- 14, 75, TLV_DB_SCALE_ITEM(-4900, 100, 0),
-};
-
-static DECLARE_TLV_DB_SCALE(adc_boost_tlv, 0, 2500, 0);
-
-static DECLARE_TLV_DB_SCALE(hl_tlv, -10200, 50, 0);
-
-static DECLARE_TLV_DB_SCALE(ipd_tlv, -9600, 100, 0);
-
-static DECLARE_TLV_DB_SCALE(micpga_tlv, -600, 50, 0);
-
-static const unsigned int limiter_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0),
- 3, 7, TLV_DB_SCALE_ITEM(-1200, 300, 0),
-};
-
-static const DECLARE_TLV_DB_SCALE(attn_tlv, -6300, 100, 1);
-
-static const char * const cs42l73_pgaa_text[] = { "Line A", "Mic 1" };
-static const char * const cs42l73_pgab_text[] = { "Line B", "Mic 2" };
-
-static const struct soc_enum pgaa_enum =
- SOC_ENUM_SINGLE(CS42L73_ADCIPC, 3,
- ARRAY_SIZE(cs42l73_pgaa_text), cs42l73_pgaa_text);
-
-static const struct soc_enum pgab_enum =
- SOC_ENUM_SINGLE(CS42L73_ADCIPC, 7,
- ARRAY_SIZE(cs42l73_pgab_text), cs42l73_pgab_text);
-
-static const struct snd_kcontrol_new pgaa_mux =
- SOC_DAPM_ENUM("Left Analog Input Capture Mux", pgaa_enum);
-
-static const struct snd_kcontrol_new pgab_mux =
- SOC_DAPM_ENUM("Right Analog Input Capture Mux", pgab_enum);
-
-static const struct snd_kcontrol_new input_left_mixer[] = {
- SOC_DAPM_SINGLE("ADC Left Input", CS42L73_PWRCTL1,
- 5, 1, 1),
- SOC_DAPM_SINGLE("DMIC Left Input", CS42L73_PWRCTL1,
- 4, 1, 1),
-};
-
-static const struct snd_kcontrol_new input_right_mixer[] = {
- SOC_DAPM_SINGLE("ADC Right Input", CS42L73_PWRCTL1,
- 7, 1, 1),
- SOC_DAPM_SINGLE("DMIC Right Input", CS42L73_PWRCTL1,
- 6, 1, 1),
-};
-
-static const char * const cs42l73_ng_delay_text[] = {
- "50ms", "100ms", "150ms", "200ms" };
-
-static const struct soc_enum ng_delay_enum =
- SOC_ENUM_SINGLE(CS42L73_NGCAB, 0,
- ARRAY_SIZE(cs42l73_ng_delay_text), cs42l73_ng_delay_text);
-
-static const char * const charge_pump_freq_text[] = {
- "0", "1", "2", "3", "4",
- "5", "6", "7", "8", "9",
- "10", "11", "12", "13", "14", "15" };
-
-static const struct soc_enum charge_pump_enum =
- SOC_ENUM_SINGLE(CS42L73_CPFCHC, 4,
- ARRAY_SIZE(charge_pump_freq_text), charge_pump_freq_text);
-
-static const char * const cs42l73_mono_mix_texts[] = {
- "Left", "Right", "Mono Mix"};
-
-static const unsigned int cs42l73_mono_mix_values[] = { 0, 1, 2 };
-
-static const struct soc_enum spk_asp_enum =
- SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 6, 1,
- ARRAY_SIZE(cs42l73_mono_mix_texts),
- cs42l73_mono_mix_texts,
- cs42l73_mono_mix_values);
-
-static const struct snd_kcontrol_new spk_asp_mixer =
- SOC_DAPM_ENUM("Route", spk_asp_enum);
-
-static const struct soc_enum spk_xsp_enum =
- SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 4, 3,
- ARRAY_SIZE(cs42l73_mono_mix_texts),
- cs42l73_mono_mix_texts,
- cs42l73_mono_mix_values);
-
-static const struct snd_kcontrol_new spk_xsp_mixer =
- SOC_DAPM_ENUM("Route", spk_xsp_enum);
-
-static const struct soc_enum esl_asp_enum =
- SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 2, 5,
- ARRAY_SIZE(cs42l73_mono_mix_texts),
- cs42l73_mono_mix_texts,
- cs42l73_mono_mix_values);
-
-static const struct snd_kcontrol_new esl_asp_mixer =
- SOC_DAPM_ENUM("Route", esl_asp_enum);
-
-static const struct soc_enum esl_xsp_enum =
- SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 0, 7,
- ARRAY_SIZE(cs42l73_mono_mix_texts),
- cs42l73_mono_mix_texts,
- cs42l73_mono_mix_values);
-
-static const struct snd_kcontrol_new esl_xsp_mixer =
- SOC_DAPM_ENUM("Route", esl_xsp_enum);
-
-static const char * const cs42l73_ip_swap_text[] = {
- "Stereo", "Mono A", "Mono B", "Swap A-B"};
-
-static const struct soc_enum ip_swap_enum =
- SOC_ENUM_SINGLE(CS42L73_MIOPC, 6,
- ARRAY_SIZE(cs42l73_ip_swap_text), cs42l73_ip_swap_text);
-
-static const char * const cs42l73_spo_mixer_text[] = {"Mono", "Stereo"};
-
-static const struct soc_enum vsp_output_mux_enum =
- SOC_ENUM_SINGLE(CS42L73_MIXERCTL, 5,
- ARRAY_SIZE(cs42l73_spo_mixer_text), cs42l73_spo_mixer_text);
-
-static const struct soc_enum xsp_output_mux_enum =
- SOC_ENUM_SINGLE(CS42L73_MIXERCTL, 4,
- ARRAY_SIZE(cs42l73_spo_mixer_text), cs42l73_spo_mixer_text);
-
-static const struct snd_kcontrol_new vsp_output_mux =
- SOC_DAPM_ENUM("Route", vsp_output_mux_enum);
-
-static const struct snd_kcontrol_new xsp_output_mux =
- SOC_DAPM_ENUM("Route", xsp_output_mux_enum);
-
-static const struct snd_kcontrol_new hp_amp_ctl =
- SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 0, 1, 1);
-
-static const struct snd_kcontrol_new lo_amp_ctl =
- SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 1, 1, 1);
-
-static const struct snd_kcontrol_new spk_amp_ctl =
- SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 2, 1, 1);
-
-static const struct snd_kcontrol_new spklo_amp_ctl =
- SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 4, 1, 1);
-
-static const struct snd_kcontrol_new ear_amp_ctl =
- SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 3, 1, 1);
-
-static const struct snd_kcontrol_new cs42l73_snd_controls[] = {
- SOC_DOUBLE_R_SX_TLV("Headphone Analog Playback Volume",
- CS42L73_HPAAVOL, CS42L73_HPBAVOL, 7,
- 0xffffffC1, 0x0C, hpaloa_tlv),
-
- SOC_DOUBLE_R_SX_TLV("LineOut Analog Playback Volume", CS42L73_LOAAVOL,
- CS42L73_LOBAVOL, 7, 0xffffffC1, 0x0C, hpaloa_tlv),
-
- SOC_DOUBLE_R_SX_TLV("Input PGA Analog Volume", CS42L73_MICAPREPGAAVOL,
- CS42L73_MICBPREPGABVOL, 5, 0xffffff35,
- 0x34, micpga_tlv),
-
- SOC_DOUBLE_R("MIC Preamp Switch", CS42L73_MICAPREPGAAVOL,
- CS42L73_MICBPREPGABVOL, 6, 1, 1),
-
- SOC_DOUBLE_R_SX_TLV("Input Path Digital Volume", CS42L73_IPADVOL,
- CS42L73_IPBDVOL, 7, 0xffffffA0, 0xA0, ipd_tlv),
-
- SOC_DOUBLE_R_SX_TLV("HL Digital Playback Volume",
- CS42L73_HLADVOL, CS42L73_HLBDVOL, 7, 0xffffffE5,
- 0xE4, hl_tlv),
-
- SOC_SINGLE_TLV("ADC A Boost Volume",
- CS42L73_ADCIPC, 2, 0x01, 1, adc_boost_tlv),
-
- SOC_SINGLE_TLV("ADC B Boost Volume",
- CS42L73_ADCIPC, 6, 0x01, 1, adc_boost_tlv),
-
- SOC_SINGLE_TLV("Speakerphone Digital Playback Volume",
- CS42L73_SPKDVOL, 0, 0xE4, 1, hl_tlv),
-
- SOC_SINGLE_TLV("Ear Speaker Digital Playback Volume",
- CS42L73_ESLDVOL, 0, 0xE4, 1, hl_tlv),
-
- SOC_DOUBLE_R("Headphone Analog Playback Switch", CS42L73_HPAAVOL,
- CS42L73_HPBAVOL, 7, 1, 1),
-
- SOC_DOUBLE_R("LineOut Analog Playback Switch", CS42L73_LOAAVOL,
- CS42L73_LOBAVOL, 7, 1, 1),
- SOC_DOUBLE("Input Path Digital Switch", CS42L73_ADCIPC, 0, 4, 1, 1),
- SOC_DOUBLE("HL Digital Playback Switch", CS42L73_PBDC, 0,
- 1, 1, 1),
- SOC_SINGLE("Speakerphone Digital Playback Switch", CS42L73_PBDC, 2, 1,
- 1),
- SOC_SINGLE("Ear Speaker Digital Playback Switch", CS42L73_PBDC, 3, 1,
- 1),
-
- SOC_SINGLE("PGA Soft-Ramp Switch", CS42L73_MIOPC, 3, 1, 0),
- SOC_SINGLE("Analog Zero Cross Switch", CS42L73_MIOPC, 2, 1, 0),
- SOC_SINGLE("Digital Soft-Ramp Switch", CS42L73_MIOPC, 1, 1, 0),
- SOC_SINGLE("Analog Output Soft-Ramp Switch", CS42L73_MIOPC, 0, 1, 0),
-
- SOC_DOUBLE("ADC Signal Polarity Switch", CS42L73_ADCIPC, 1, 5, 1,
- 0),
-
- SOC_SINGLE("HL Limiter Attack Rate", CS42L73_LIMARATEHL, 0, 0x3F,
- 0),
- SOC_SINGLE("HL Limiter Release Rate", CS42L73_LIMRRATEHL, 0,
- 0x3F, 0),
-
-
- SOC_SINGLE("HL Limiter Switch", CS42L73_LIMRRATEHL, 7, 1, 0),
- SOC_SINGLE("HL Limiter All Channels Switch", CS42L73_LIMRRATEHL, 6, 1,
- 0),
-
- SOC_SINGLE_TLV("HL Limiter Max Threshold Volume", CS42L73_LMAXHL, 5, 7,
- 1, limiter_tlv),
-
- SOC_SINGLE_TLV("HL Limiter Cushion Volume", CS42L73_LMAXHL, 2, 7, 1,
- limiter_tlv),
-
- SOC_SINGLE("SPK Limiter Attack Rate Volume", CS42L73_LIMARATESPK, 0,
- 0x3F, 0),
- SOC_SINGLE("SPK Limiter Release Rate Volume", CS42L73_LIMRRATESPK, 0,
- 0x3F, 0),
- SOC_SINGLE("SPK Limiter Switch", CS42L73_LIMRRATESPK, 7, 1, 0),
- SOC_SINGLE("SPK Limiter All Channels Switch", CS42L73_LIMRRATESPK,
- 6, 1, 0),
- SOC_SINGLE_TLV("SPK Limiter Max Threshold Volume", CS42L73_LMAXSPK, 5,
- 7, 1, limiter_tlv),
-
- SOC_SINGLE_TLV("SPK Limiter Cushion Volume", CS42L73_LMAXSPK, 2, 7, 1,
- limiter_tlv),
-
- SOC_SINGLE("ESL Limiter Attack Rate Volume", CS42L73_LIMARATEESL, 0,
- 0x3F, 0),
- SOC_SINGLE("ESL Limiter Release Rate Volume", CS42L73_LIMRRATEESL, 0,
- 0x3F, 0),
- SOC_SINGLE("ESL Limiter Switch", CS42L73_LIMRRATEESL, 7, 1, 0),
- SOC_SINGLE_TLV("ESL Limiter Max Threshold Volume", CS42L73_LMAXESL, 5,
- 7, 1, limiter_tlv),
-
- SOC_SINGLE_TLV("ESL Limiter Cushion Volume", CS42L73_LMAXESL, 2, 7, 1,
- limiter_tlv),
-
- SOC_SINGLE("ALC Attack Rate Volume", CS42L73_ALCARATE, 0, 0x3F, 0),
- SOC_SINGLE("ALC Release Rate Volume", CS42L73_ALCRRATE, 0, 0x3F, 0),
- SOC_DOUBLE("ALC Switch", CS42L73_ALCARATE, 6, 7, 1, 0),
- SOC_SINGLE_TLV("ALC Max Threshold Volume", CS42L73_ALCMINMAX, 5, 7, 0,
- limiter_tlv),
- SOC_SINGLE_TLV("ALC Min Threshold Volume", CS42L73_ALCMINMAX, 2, 7, 0,
- limiter_tlv),
-
- SOC_DOUBLE("NG Enable Switch", CS42L73_NGCAB, 6, 7, 1, 0),
- SOC_SINGLE("NG Boost Switch", CS42L73_NGCAB, 5, 1, 0),
- /*
- NG Threshold depends on NG_BOOTSAB, which selects
- between two threshold scales in decibels.
- Set linear values for now ..
- */
- SOC_SINGLE("NG Threshold", CS42L73_NGCAB, 2, 7, 0),
- SOC_ENUM("NG Delay", ng_delay_enum),
-
- SOC_ENUM("Charge Pump Frequency", charge_pump_enum),
-
- SOC_DOUBLE_R_TLV("XSP-IP Volume",
- CS42L73_XSPAIPAA, CS42L73_XSPBIPBA, 0, 0x3F, 1,
- attn_tlv),
- SOC_DOUBLE_R_TLV("XSP-XSP Volume",
- CS42L73_XSPAXSPAA, CS42L73_XSPBXSPBA, 0, 0x3F, 1,
- attn_tlv),
- SOC_DOUBLE_R_TLV("XSP-ASP Volume",
- CS42L73_XSPAASPAA, CS42L73_XSPAASPBA, 0, 0x3F, 1,
- attn_tlv),
- SOC_DOUBLE_R_TLV("XSP-VSP Volume",
- CS42L73_XSPAVSPMA, CS42L73_XSPBVSPMA, 0, 0x3F, 1,
- attn_tlv),
-
- SOC_DOUBLE_R_TLV("ASP-IP Volume",
- CS42L73_ASPAIPAA, CS42L73_ASPBIPBA, 0, 0x3F, 1,
- attn_tlv),
- SOC_DOUBLE_R_TLV("ASP-XSP Volume",
- CS42L73_ASPAXSPAA, CS42L73_ASPBXSPBA, 0, 0x3F, 1,
- attn_tlv),
- SOC_DOUBLE_R_TLV("ASP-ASP Volume",
- CS42L73_ASPAASPAA, CS42L73_ASPBASPBA, 0, 0x3F, 1,
- attn_tlv),
- SOC_DOUBLE_R_TLV("ASP-VSP Volume",
- CS42L73_ASPAVSPMA, CS42L73_ASPBVSPMA, 0, 0x3F, 1,
- attn_tlv),
-
- SOC_DOUBLE_R_TLV("VSP-IP Volume",
- CS42L73_VSPAIPAA, CS42L73_VSPBIPBA, 0, 0x3F, 1,
- attn_tlv),
- SOC_DOUBLE_R_TLV("VSP-XSP Volume",
- CS42L73_VSPAXSPAA, CS42L73_VSPBXSPBA, 0, 0x3F, 1,
- attn_tlv),
- SOC_DOUBLE_R_TLV("VSP-ASP Volume",
- CS42L73_VSPAASPAA, CS42L73_VSPBASPBA, 0, 0x3F, 1,
- attn_tlv),
- SOC_DOUBLE_R_TLV("VSP-VSP Volume",
- CS42L73_VSPAVSPMA, CS42L73_VSPBVSPMA, 0, 0x3F, 1,
- attn_tlv),
-
- SOC_DOUBLE_R_TLV("HL-IP Volume",
- CS42L73_HLAIPAA, CS42L73_HLBIPBA, 0, 0x3F, 1,
- attn_tlv),
- SOC_DOUBLE_R_TLV("HL-XSP Volume",
- CS42L73_HLAXSPAA, CS42L73_HLBXSPBA, 0, 0x3F, 1,
- attn_tlv),
- SOC_DOUBLE_R_TLV("HL-ASP Volume",
- CS42L73_HLAASPAA, CS42L73_HLBASPBA, 0, 0x3F, 1,
- attn_tlv),
- SOC_DOUBLE_R_TLV("HL-VSP Volume",
- CS42L73_HLAVSPMA, CS42L73_HLBVSPMA, 0, 0x3F, 1,
- attn_tlv),
-
- SOC_SINGLE_TLV("SPK-IP Mono Volume",
- CS42L73_SPKMIPMA, 0, 0x3F, 1, attn_tlv),
- SOC_SINGLE_TLV("SPK-XSP Mono Volume",
- CS42L73_SPKMXSPA, 0, 0x3F, 1, attn_tlv),
- SOC_SINGLE_TLV("SPK-ASP Mono Volume",
- CS42L73_SPKMASPA, 0, 0x3F, 1, attn_tlv),
- SOC_SINGLE_TLV("SPK-VSP Mono Volume",
- CS42L73_SPKMVSPMA, 0, 0x3F, 1, attn_tlv),
-
- SOC_SINGLE_TLV("ESL-IP Mono Volume",
- CS42L73_ESLMIPMA, 0, 0x3F, 1, attn_tlv),
- SOC_SINGLE_TLV("ESL-XSP Mono Volume",
- CS42L73_ESLMXSPA, 0, 0x3F, 1, attn_tlv),
- SOC_SINGLE_TLV("ESL-ASP Mono Volume",
- CS42L73_ESLMASPA, 0, 0x3F, 1, attn_tlv),
- SOC_SINGLE_TLV("ESL-VSP Mono Volume",
- CS42L73_ESLMVSPMA, 0, 0x3F, 1, attn_tlv),
-
- SOC_ENUM("IP Digital Swap/Mono Select", ip_swap_enum),
-
- SOC_ENUM("VSPOUT Mono/Stereo Select", vsp_output_mux_enum),
- SOC_ENUM("XSPOUT Mono/Stereo Select", xsp_output_mux_enum),
-};
-
-static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
- SND_SOC_DAPM_INPUT("LINEINA"),
- SND_SOC_DAPM_INPUT("LINEINB"),
- SND_SOC_DAPM_INPUT("MIC1"),
- SND_SOC_DAPM_SUPPLY("MIC1 Bias", CS42L73_PWRCTL2, 6, 1, NULL, 0),
- SND_SOC_DAPM_INPUT("MIC2"),
- SND_SOC_DAPM_SUPPLY("MIC2 Bias", CS42L73_PWRCTL2, 7, 1, NULL, 0),
-
- SND_SOC_DAPM_AIF_OUT("XSPOUTL", "XSP Capture", 0,
- CS42L73_PWRCTL2, 1, 1),
- SND_SOC_DAPM_AIF_OUT("XSPOUTR", "XSP Capture", 0,
- CS42L73_PWRCTL2, 1, 1),
- SND_SOC_DAPM_AIF_OUT("ASPOUTL", "ASP Capture", 0,
- CS42L73_PWRCTL2, 3, 1),
- SND_SOC_DAPM_AIF_OUT("ASPOUTR", "ASP Capture", 0,
- CS42L73_PWRCTL2, 3, 1),
- SND_SOC_DAPM_AIF_OUT("VSPOUTL", "VSP Capture", 0,
- CS42L73_PWRCTL2, 4, 1),
- SND_SOC_DAPM_AIF_OUT("VSPOUTR", "VSP Capture", 0,
- CS42L73_PWRCTL2, 4, 1),
-
- SND_SOC_DAPM_PGA("PGA Left", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("PGA Right", SND_SOC_NOPM, 0, 0, NULL, 0),
-
- SND_SOC_DAPM_MUX("PGA Left Mux", SND_SOC_NOPM, 0, 0, &pgaa_mux),
- SND_SOC_DAPM_MUX("PGA Right Mux", SND_SOC_NOPM, 0, 0, &pgab_mux),
-
- SND_SOC_DAPM_ADC("ADC Left", NULL, CS42L73_PWRCTL1, 7, 1),
- SND_SOC_DAPM_ADC("ADC Right", NULL, CS42L73_PWRCTL1, 5, 1),
- SND_SOC_DAPM_ADC("DMIC Left", NULL, CS42L73_PWRCTL1, 6, 1),
- SND_SOC_DAPM_ADC("DMIC Right", NULL, CS42L73_PWRCTL1, 4, 1),
-
- SND_SOC_DAPM_MIXER_NAMED_CTL("Input Left Capture", SND_SOC_NOPM,
- 0, 0, input_left_mixer,
- ARRAY_SIZE(input_left_mixer)),
-
- SND_SOC_DAPM_MIXER_NAMED_CTL("Input Right Capture", SND_SOC_NOPM,
- 0, 0, input_right_mixer,
- ARRAY_SIZE(input_right_mixer)),
-
- SND_SOC_DAPM_MIXER("ASPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("ASPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("XSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("XSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("VSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("VSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-
- SND_SOC_DAPM_AIF_IN("XSPINL", "XSP Playback", 0,
- CS42L73_PWRCTL2, 0, 1),
- SND_SOC_DAPM_AIF_IN("XSPINR", "XSP Playback", 0,
- CS42L73_PWRCTL2, 0, 1),
- SND_SOC_DAPM_AIF_IN("XSPINM", "XSP Playback", 0,
- CS42L73_PWRCTL2, 0, 1),
-
- SND_SOC_DAPM_AIF_IN("ASPINL", "ASP Playback", 0,
- CS42L73_PWRCTL2, 2, 1),
- SND_SOC_DAPM_AIF_IN("ASPINR", "ASP Playback", 0,
- CS42L73_PWRCTL2, 2, 1),
- SND_SOC_DAPM_AIF_IN("ASPINM", "ASP Playback", 0,
- CS42L73_PWRCTL2, 2, 1),
-
- SND_SOC_DAPM_AIF_IN("VSPIN", "VSP Playback", 0,
- CS42L73_PWRCTL2, 4, 1),
-
- SND_SOC_DAPM_MIXER("HL Left Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("HL Right Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("SPK Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("ESL Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-
- SND_SOC_DAPM_MUX("ESL-XSP Mux", SND_SOC_NOPM,
- 0, 0, &esl_xsp_mixer),
-
- SND_SOC_DAPM_MUX("ESL-ASP Mux", SND_SOC_NOPM,
- 0, 0, &esl_asp_mixer),
-
- SND_SOC_DAPM_MUX("SPK-ASP Mux", SND_SOC_NOPM,
- 0, 0, &spk_asp_mixer),
-
- SND_SOC_DAPM_MUX("SPK-XSP Mux", SND_SOC_NOPM,
- 0, 0, &spk_xsp_mixer),
-
- SND_SOC_DAPM_PGA("HL Left DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("HL Right DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("SPK DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("ESL DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
-
- SND_SOC_DAPM_SWITCH("HP Amp", CS42L73_PWRCTL3, 0, 1,
- &hp_amp_ctl),
- SND_SOC_DAPM_SWITCH("LO Amp", CS42L73_PWRCTL3, 1, 1,
- &lo_amp_ctl),
- SND_SOC_DAPM_SWITCH("SPK Amp", CS42L73_PWRCTL3, 2, 1,
- &spk_amp_ctl),
- SND_SOC_DAPM_SWITCH("EAR Amp", CS42L73_PWRCTL3, 3, 1,
- &ear_amp_ctl),
- SND_SOC_DAPM_SWITCH("SPKLO Amp", CS42L73_PWRCTL3, 4, 1,
- &spklo_amp_ctl),
-
- SND_SOC_DAPM_OUTPUT("HPOUTA"),
- SND_SOC_DAPM_OUTPUT("HPOUTB"),
- SND_SOC_DAPM_OUTPUT("LINEOUTA"),
- SND_SOC_DAPM_OUTPUT("LINEOUTB"),
- SND_SOC_DAPM_OUTPUT("EAROUT"),
- SND_SOC_DAPM_OUTPUT("SPKOUT"),
- SND_SOC_DAPM_OUTPUT("SPKLINEOUT"),
-};
-
-static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
-
- /* SPKLO EARSPK Paths */
- {"EAROUT", NULL, "EAR Amp"},
- {"SPKLINEOUT", NULL, "SPKLO Amp"},
-
- {"EAR Amp", "Switch", "ESL DAC"},
- {"SPKLO Amp", "Switch", "ESL DAC"},
-
- {"ESL DAC", "ESL-ASP Mono Volume", "ESL Mixer"},
- {"ESL DAC", "ESL-XSP Mono Volume", "ESL Mixer"},
- {"ESL DAC", "ESL-VSP Mono Volume", "VSPIN"},
- /* Loopback */
- {"ESL DAC", "ESL-IP Mono Volume", "Input Left Capture"},
- {"ESL DAC", "ESL-IP Mono Volume", "Input Right Capture"},
-
- {"ESL Mixer", NULL, "ESL-ASP Mux"},
- {"ESL Mixer", NULL, "ESL-XSP Mux"},
-
- {"ESL-ASP Mux", "Left", "ASPINL"},
- {"ESL-ASP Mux", "Right", "ASPINR"},
- {"ESL-ASP Mux", "Mono Mix", "ASPINM"},
-
- {"ESL-XSP Mux", "Left", "XSPINL"},
- {"ESL-XSP Mux", "Right", "XSPINR"},
- {"ESL-XSP Mux", "Mono Mix", "XSPINM"},
-
- /* Speakerphone Paths */
- {"SPKOUT", NULL, "SPK Amp"},
- {"SPK Amp", "Switch", "SPK DAC"},
-
- {"SPK DAC", "SPK-ASP Mono Volume", "SPK Mixer"},
- {"SPK DAC", "SPK-XSP Mono Volume", "SPK Mixer"},
- {"SPK DAC", "SPK-VSP Mono Volume", "VSPIN"},
- /* Loopback */
- {"SPK DAC", "SPK-IP Mono Volume", "Input Left Capture"},
- {"SPK DAC", "SPK-IP Mono Volume", "Input Right Capture"},
-
- {"SPK Mixer", NULL, "SPK-ASP Mux"},
- {"SPK Mixer", NULL, "SPK-XSP Mux"},
-
- {"SPK-ASP Mux", "Left", "ASPINL"},
- {"SPK-ASP Mux", "Mono Mix", "ASPINM"},
- {"SPK-ASP Mux", "Right", "ASPINR"},
-
- {"SPK-XSP Mux", "Left", "XSPINL"},
- {"SPK-XSP Mux", "Mono Mix", "XSPINM"},
- {"SPK-XSP Mux", "Right", "XSPINR"},
-
- /* HP LineOUT Paths */
- {"HPOUTA", NULL, "HP Amp"},
- {"HPOUTB", NULL, "HP Amp"},
- {"LINEOUTA", NULL, "LO Amp"},
- {"LINEOUTB", NULL, "LO Amp"},
-
- {"HP Amp", "Switch", "HL Left DAC"},
- {"HP Amp", "Switch", "HL Right DAC"},
- {"LO Amp", "Switch", "HL Left DAC"},
- {"LO Amp", "Switch", "HL Right DAC"},
-
- {"HL Left DAC", "HL-XSP Volume", "HL Left Mixer"},
- {"HL Right DAC", "HL-XSP Volume", "HL Right Mixer"},
- {"HL Left DAC", "HL-ASP Volume", "HL Left Mixer"},
- {"HL Right DAC", "HL-ASP Volume", "HL Right Mixer"},
- {"HL Left DAC", "HL-VSP Volume", "HL Left Mixer"},
- {"HL Right DAC", "HL-VSP Volume", "HL Right Mixer"},
- /* Loopback */
- {"HL Left DAC", "HL-IP Volume", "HL Left Mixer"},
- {"HL Right DAC", "HL-IP Volume", "HL Right Mixer"},
- {"HL Left Mixer", NULL, "Input Left Capture"},
- {"HL Right Mixer", NULL, "Input Right Capture"},
-
- {"HL Left Mixer", NULL, "ASPINL"},
- {"HL Right Mixer", NULL, "ASPINR"},
- {"HL Left Mixer", NULL, "XSPINL"},
- {"HL Right Mixer", NULL, "XSPINR"},
- {"HL Left Mixer", NULL, "VSPIN"},
- {"HL Right Mixer", NULL, "VSPIN"},
-
- /* Capture Paths */
- {"MIC1", NULL, "MIC1 Bias"},
- {"PGA Left Mux", "Mic 1", "MIC1"},
- {"MIC2", NULL, "MIC2 Bias"},
- {"PGA Right Mux", "Mic 2", "MIC2"},
-
- {"PGA Left Mux", "Line A", "LINEINA"},
- {"PGA Right Mux", "Line B", "LINEINB"},
-
- {"PGA Left", NULL, "PGA Left Mux"},
- {"PGA Right", NULL, "PGA Right Mux"},
-
- {"ADC Left", NULL, "PGA Left"},
- {"ADC Right", NULL, "PGA Right"},
-
- {"Input Left Capture", "ADC Left Input", "ADC Left"},
- {"Input Right Capture", "ADC Right Input", "ADC Right"},
- {"Input Left Capture", "DMIC Left Input", "DMIC Left"},
- {"Input Right Capture", "DMIC Right Input", "DMIC Right"},
-
- /* Audio Capture */
- {"ASPL Output Mixer", NULL, "Input Left Capture"},
- {"ASPR Output Mixer", NULL, "Input Right Capture"},
-
- {"ASPOUTL", "ASP-IP Volume", "ASPL Output Mixer"},
- {"ASPOUTR", "ASP-IP Volume", "ASPR Output Mixer"},
-
- /* Auxillary Capture */
- {"XSPL Output Mixer", NULL, "Input Left Capture"},
- {"XSPR Output Mixer", NULL, "Input Right Capture"},
-
- {"XSPOUTL", "XSP-IP Volume", "XSPL Output Mixer"},
- {"XSPOUTR", "XSP-IP Volume", "XSPR Output Mixer"},
-
- {"XSPOUTL", NULL, "XSPL Output Mixer"},
- {"XSPOUTR", NULL, "XSPR Output Mixer"},
-
- /* Voice Capture */
- {"VSPL Output Mixer", NULL, "Input Left Capture"},
- {"VSPR Output Mixer", NULL, "Input Left Capture"},
-
- {"VSPOUTL", "VSP-IP Volume", "VSPL Output Mixer"},
- {"VSPOUTR", "VSP-IP Volume", "VSPR Output Mixer"},
-
- {"VSPOUTL", NULL, "VSPL Output Mixer"},
- {"VSPOUTR", NULL, "VSPR Output Mixer"},
-};
-
-struct cs42l73_mclk_div {
- u32 mclk;
- u32 srate;
- u8 mmcc;
-};
-
-static struct cs42l73_mclk_div cs42l73_mclk_coeffs[] = {
- /* MCLK, Sample Rate, xMMCC[5:0] */
- {5644800, 11025, 0x30},
- {5644800, 22050, 0x20},
- {5644800, 44100, 0x10},
-
- {6000000, 8000, 0x39},
- {6000000, 11025, 0x33},
- {6000000, 12000, 0x31},
- {6000000, 16000, 0x29},
- {6000000, 22050, 0x23},
- {6000000, 24000, 0x21},
- {6000000, 32000, 0x19},
- {6000000, 44100, 0x13},
- {6000000, 48000, 0x11},
-
- {6144000, 8000, 0x38},
- {6144000, 12000, 0x30},
- {6144000, 16000, 0x28},
- {6144000, 24000, 0x20},
- {6144000, 32000, 0x18},
- {6144000, 48000, 0x10},
-
- {6500000, 8000, 0x3C},
- {6500000, 11025, 0x35},
- {6500000, 12000, 0x34},
- {6500000, 16000, 0x2C},
- {6500000, 22050, 0x25},
- {6500000, 24000, 0x24},
- {6500000, 32000, 0x1C},
- {6500000, 44100, 0x15},
- {6500000, 48000, 0x14},
-
- {6400000, 8000, 0x3E},
- {6400000, 11025, 0x37},
- {6400000, 12000, 0x36},
- {6400000, 16000, 0x2E},
- {6400000, 22050, 0x27},
- {6400000, 24000, 0x26},
- {6400000, 32000, 0x1E},
- {6400000, 44100, 0x17},
- {6400000, 48000, 0x16},
-};
-
-struct cs42l73_mclkx_div {
- u32 mclkx;
- u8 ratio;
- u8 mclkdiv;
-};
-
-static struct cs42l73_mclkx_div cs42l73_mclkx_coeffs[] = {
- {5644800, 1, 0}, /* 5644800 */
- {6000000, 1, 0}, /* 6000000 */
- {6144000, 1, 0}, /* 6144000 */
- {11289600, 2, 2}, /* 5644800 */
- {12288000, 2, 2}, /* 6144000 */
- {12000000, 2, 2}, /* 6000000 */
- {13000000, 2, 2}, /* 6500000 */
- {19200000, 3, 3}, /* 6400000 */
- {24000000, 4, 4}, /* 6000000 */
- {26000000, 4, 4}, /* 6500000 */
- {38400000, 6, 5} /* 6400000 */
-};
-
-static int cs42l73_get_mclkx_coeff(int mclkx)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(cs42l73_mclkx_coeffs); i++) {
- if (cs42l73_mclkx_coeffs[i].mclkx == mclkx)
- return i;
- }
- return -EINVAL;
-}
-
-static int cs42l73_get_mclk_coeff(int mclk, int srate)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(cs42l73_mclk_coeffs); i++) {
- if (cs42l73_mclk_coeffs[i].mclk == mclk &&
- cs42l73_mclk_coeffs[i].srate == srate)
- return i;
- }
- return -EINVAL;
-
-}
-
-static int cs42l73_set_mclk(struct snd_soc_dai *dai, unsigned int freq)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
-
- int mclkx_coeff;
- u32 mclk = 0;
- u8 dmmcc = 0;
-
- /* MCLKX -> MCLK */
- mclkx_coeff = cs42l73_get_mclkx_coeff(freq);
- if (mclkx_coeff < 0)
- return mclkx_coeff;
-
- mclk = cs42l73_mclkx_coeffs[mclkx_coeff].mclkx /
- cs42l73_mclkx_coeffs[mclkx_coeff].ratio;
-
- dev_dbg(codec->dev, "MCLK%u %u <-> internal MCLK %u\n",
- priv->mclksel + 1, cs42l73_mclkx_coeffs[mclkx_coeff].mclkx,
- mclk);
-
- dmmcc = (priv->mclksel << 4) |
- (cs42l73_mclkx_coeffs[mclkx_coeff].mclkdiv << 1);
-
- snd_soc_write(codec, CS42L73_DMMCC, dmmcc);
-
- priv->sysclk = mclkx_coeff;
- priv->mclk = mclk;
-
- return 0;
-}
-
-static int cs42l73_set_sysclk(struct snd_soc_dai *dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
-
- switch (clk_id) {
- case CS42L73_CLKID_MCLK1:
- break;
- case CS42L73_CLKID_MCLK2:
- break;
- default:
- return -EINVAL;
- }
-
- if ((cs42l73_set_mclk(dai, freq)) < 0) {
- dev_err(codec->dev, "Unable to set MCLK for dai %s\n",
- dai->name);
- return -EINVAL;
- }
-
- priv->mclksel = clk_id;
-
- return 0;
-}
-
-static int cs42l73_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
- u8 id = codec_dai->id;
- unsigned int inv, format;
- u8 spc, mmcc;
-
- spc = snd_soc_read(codec, CS42L73_SPC(id));
- mmcc = snd_soc_read(codec, CS42L73_MMCC(id));
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- mmcc |= MS_MASTER;
- break;
-
- case SND_SOC_DAIFMT_CBS_CFS:
- mmcc &= ~MS_MASTER;
- break;
-
- default:
- return -EINVAL;
- }
-
- format = (fmt & SND_SOC_DAIFMT_FORMAT_MASK);
- inv = (fmt & SND_SOC_DAIFMT_INV_MASK);
-
- switch (format) {
- case SND_SOC_DAIFMT_I2S:
- spc &= ~SPDIF_PCM;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- case SND_SOC_DAIFMT_DSP_B:
- if (mmcc & MS_MASTER) {
- dev_err(codec->dev,
- "PCM format in slave mode only\n");
- return -EINVAL;
- }
- if (id == CS42L73_ASP) {
- dev_err(codec->dev,
- "PCM format is not supported on ASP port\n");
- return -EINVAL;
- }
- spc |= SPDIF_PCM;
- break;
- default:
- return -EINVAL;
- }
-
- if (spc & SPDIF_PCM) {
- /* Clear PCM mode, clear PCM_BIT_ORDER bit for MSB->LSB */
- spc &= ~(PCM_MODE_MASK | PCM_BIT_ORDER);
- switch (format) {
- case SND_SOC_DAIFMT_DSP_B:
- if (inv == SND_SOC_DAIFMT_IB_IF)
- spc |= PCM_MODE0;
- if (inv == SND_SOC_DAIFMT_IB_NF)
- spc |= PCM_MODE1;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- if (inv == SND_SOC_DAIFMT_IB_IF)
- spc |= PCM_MODE1;
- break;
- default:
- return -EINVAL;
- }
- }
-
- priv->config[id].spc = spc;
- priv->config[id].mmcc = mmcc;
-
- return 0;
-}
-
-static u32 cs42l73_asrc_rates[] = {
- 8000, 11025, 12000, 16000, 22050,
- 24000, 32000, 44100, 48000
-};
-
-static unsigned int cs42l73_get_xspfs_coeff(u32 rate)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(cs42l73_asrc_rates); i++) {
- if (cs42l73_asrc_rates[i] == rate)
- return i + 1;
- }
- return 0; /* 0 = Don't know */
-}
-
-static void cs42l73_update_asrc(struct snd_soc_codec *codec, int id, int srate)
-{
- u8 spfs = 0;
-
- if (srate > 0)
- spfs = cs42l73_get_xspfs_coeff(srate);
-
- switch (id) {
- case CS42L73_XSP:
- snd_soc_update_bits(codec, CS42L73_VXSPFS, 0x0f, spfs);
- break;
- case CS42L73_ASP:
- snd_soc_update_bits(codec, CS42L73_ASPC, 0x3c, spfs << 2);
- break;
- case CS42L73_VSP:
- snd_soc_update_bits(codec, CS42L73_VXSPFS, 0xf0, spfs << 4);
- break;
- default:
- break;
- }
-}
-
-static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
- int id = dai->id;
- int mclk_coeff;
- int srate = params_rate(params);
-
- if (priv->config[id].mmcc & MS_MASTER) {
- /* CS42L73 Master */
- /* MCLK -> srate */
- mclk_coeff =
- cs42l73_get_mclk_coeff(priv->mclk, srate);
-
- if (mclk_coeff < 0)
- return -EINVAL;
-
- dev_dbg(codec->dev,
- "DAI[%d]: MCLK %u, srate %u, MMCC[5:0] = %x\n",
- id, priv->mclk, srate,
- cs42l73_mclk_coeffs[mclk_coeff].mmcc);
-
- priv->config[id].mmcc &= 0xC0;
- priv->config[id].mmcc |= cs42l73_mclk_coeffs[mclk_coeff].mmcc;
- priv->config[id].spc &= 0xFC;
- priv->config[id].spc |= MCK_SCLK_MCLK;
- } else {
- /* CS42L73 Slave */
- priv->config[id].spc &= 0xFC;
- priv->config[id].spc |= MCK_SCLK_64FS;
- }
- /* Update ASRCs */
- priv->config[id].srate = srate;
-
- snd_soc_write(codec, CS42L73_SPC(id), priv->config[id].spc);
- snd_soc_write(codec, CS42L73_MMCC(id), priv->config[id].mmcc);
-
- cs42l73_update_asrc(codec, id, srate);
-
- return 0;
-}
-
-static int cs42l73_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec);
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 0);
- snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 0);
- break;
-
- case SND_SOC_BIAS_PREPARE:
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- regcache_cache_only(cs42l73->regmap, false);
- regcache_sync(cs42l73->regmap);
- }
- snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 1);
- break;
-
- case SND_SOC_BIAS_OFF:
- snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 1);
- snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 1);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-static int cs42l73_set_tristate(struct snd_soc_dai *dai, int tristate)
-{
- struct snd_soc_codec *codec = dai->codec;
- int id = dai->id;
-
- return snd_soc_update_bits(codec, CS42L73_SPC(id),
- 0x7F, tristate << 7);
-}
-
-static struct snd_pcm_hw_constraint_list constraints_12_24 = {
- .count = ARRAY_SIZE(cs42l73_asrc_rates),
- .list = cs42l73_asrc_rates,
-};
-
-static int cs42l73_pcm_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- snd_pcm_hw_constraint_list(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- &constraints_12_24);
- return 0;
-}
-
-/* SNDRV_PCM_RATE_KNOT -> 12000, 24000 Hz, limit with constraint list */
-#define CS42L73_RATES (SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT)
-
-
-#define CS42L73_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops cs42l73_ops = {
- .startup = cs42l73_pcm_startup,
- .hw_params = cs42l73_pcm_hw_params,
- .set_fmt = cs42l73_set_dai_fmt,
- .set_sysclk = cs42l73_set_sysclk,
- .set_tristate = cs42l73_set_tristate,
-};
-
-static struct snd_soc_dai_driver cs42l73_dai[] = {
- {
- .name = "cs42l73-xsp",
- .id = CS42L73_XSP,
- .playback = {
- .stream_name = "XSP Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = CS42L73_RATES,
- .formats = CS42L73_FORMATS,
- },
- .capture = {
- .stream_name = "XSP Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = CS42L73_RATES,
- .formats = CS42L73_FORMATS,
- },
- .ops = &cs42l73_ops,
- .symmetric_rates = 1,
- },
- {
- .name = "cs42l73-asp",
- .id = CS42L73_ASP,
- .playback = {
- .stream_name = "ASP Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = CS42L73_RATES,
- .formats = CS42L73_FORMATS,
- },
- .capture = {
- .stream_name = "ASP Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = CS42L73_RATES,
- .formats = CS42L73_FORMATS,
- },
- .ops = &cs42l73_ops,
- .symmetric_rates = 1,
- },
- {
- .name = "cs42l73-vsp",
- .id = CS42L73_VSP,
- .playback = {
- .stream_name = "VSP Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = CS42L73_RATES,
- .formats = CS42L73_FORMATS,
- },
- .capture = {
- .stream_name = "VSP Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = CS42L73_RATES,
- .formats = CS42L73_FORMATS,
- },
- .ops = &cs42l73_ops,
- .symmetric_rates = 1,
- }
-};
-
-static int cs42l73_suspend(struct snd_soc_codec *codec)
-{
- cs42l73_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int cs42l73_resume(struct snd_soc_codec *codec)
-{
- cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-
-static int cs42l73_probe(struct snd_soc_codec *codec)
-{
- int ret;
- struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec);
-
- codec->control_data = cs42l73->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- regcache_cache_only(cs42l73->regmap, true);
-
- cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- cs42l73->mclksel = CS42L73_CLKID_MCLK1; /* MCLK1 as master clk */
- cs42l73->mclk = 0;
-
- return ret;
-}
-
-static int cs42l73_remove(struct snd_soc_codec *codec)
-{
- cs42l73_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_cs42l73 = {
- .probe = cs42l73_probe,
- .remove = cs42l73_remove,
- .suspend = cs42l73_suspend,
- .resume = cs42l73_resume,
- .set_bias_level = cs42l73_set_bias_level,
-
- .dapm_widgets = cs42l73_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(cs42l73_dapm_widgets),
- .dapm_routes = cs42l73_audio_map,
- .num_dapm_routes = ARRAY_SIZE(cs42l73_audio_map),
-
- .controls = cs42l73_snd_controls,
- .num_controls = ARRAY_SIZE(cs42l73_snd_controls),
-};
-
-static struct regmap_config cs42l73_regmap = {
- .reg_bits = 8,
- .val_bits = 8,
-
- .max_register = CS42L73_MAX_REGISTER,
- .reg_defaults = cs42l73_reg_defaults,
- .num_reg_defaults = ARRAY_SIZE(cs42l73_reg_defaults),
- .volatile_reg = cs42l73_volatile_register,
- .readable_reg = cs42l73_readable_register,
- .cache_type = REGCACHE_RBTREE,
-};
-
-static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client,
- const struct i2c_device_id *id)
-{
- struct cs42l73_private *cs42l73;
- int ret;
- unsigned int devid = 0;
- unsigned int reg;
-
- cs42l73 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l73_private),
- GFP_KERNEL);
- if (!cs42l73) {
- dev_err(&i2c_client->dev, "could not allocate codec\n");
- return -ENOMEM;
- }
-
- i2c_set_clientdata(i2c_client, cs42l73);
-
- cs42l73->regmap = regmap_init_i2c(i2c_client, &cs42l73_regmap);
- if (IS_ERR(cs42l73->regmap)) {
- ret = PTR_ERR(cs42l73->regmap);
- dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
- goto err;
- }
- /* initialize codec */
- ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_AB, &reg);
- devid = (reg & 0xFF) << 12;
-
- ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_CD, &reg);
- devid |= (reg & 0xFF) << 4;
-
- ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_E, &reg);
- devid |= (reg & 0xF0) >> 4;
-
-
- if (devid != CS42L73_DEVID) {
- ret = -ENODEV;
- dev_err(&i2c_client->dev,
- "CS42L73 Device ID (%X). Expected %X\n",
- devid, CS42L73_DEVID);
- goto err_regmap;
- }
-
- ret = regmap_read(cs42l73->regmap, CS42L73_REVID, &reg);
- if (ret < 0) {
- dev_err(&i2c_client->dev, "Get Revision ID failed\n");
- goto err_regmap;
- }
-
- dev_info(&i2c_client->dev,
- "Cirrus Logic CS42L73, Revision: %02X\n", reg & 0xFF);
-
- regcache_cache_only(cs42l73->regmap, true);
-
- ret = snd_soc_register_codec(&i2c_client->dev,
- &soc_codec_dev_cs42l73, cs42l73_dai,
- ARRAY_SIZE(cs42l73_dai));
- if (ret < 0)
- goto err_regmap;
- return 0;
-
-err_regmap:
- regmap_exit(cs42l73->regmap);
-
-err:
- return ret;
-}
-
-static __devexit int cs42l73_i2c_remove(struct i2c_client *client)
-{
- struct cs42l73_private *cs42l73 = i2c_get_clientdata(client);
-
- snd_soc_unregister_codec(&client->dev);
- regmap_exit(cs42l73->regmap);
-
- return 0;
-}
-
-static const struct i2c_device_id cs42l73_id[] = {
- {"cs42l73", 0},
- {}
-};
-
-MODULE_DEVICE_TABLE(i2c, cs42l73_id);
-
-static struct i2c_driver cs42l73_i2c_driver = {
- .driver = {
- .name = "cs42l73",
- .owner = THIS_MODULE,
- },
- .id_table = cs42l73_id,
- .probe = cs42l73_i2c_probe,
- .remove = __devexit_p(cs42l73_i2c_remove),
-
-};
-
-static int __init cs42l73_modinit(void)
-{
- int ret;
- ret = i2c_add_driver(&cs42l73_i2c_driver);
- if (ret != 0) {
- pr_err("Failed to register CS42L73 I2C driver: %d\n", ret);
- return ret;
- }
- return 0;
-}
-
-module_init(cs42l73_modinit);
-
-static void __exit cs42l73_exit(void)
-{
- i2c_del_driver(&cs42l73_i2c_driver);
-}
-
-module_exit(cs42l73_exit);
-
-MODULE_DESCRIPTION("ASoC CS42L73 driver");
-MODULE_AUTHOR("Georgi Vlaev, Nucleus Systems Ltd, <joe@nucleusys.com>");
-MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/cs42l73.h b/ANDROID_3.4.5/sound/soc/codecs/cs42l73.h
deleted file mode 100644
index f30a4c4d..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/cs42l73.h
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * ALSA SoC CS42L73 codec driver
- *
- * Copyright 2011 Cirrus Logic, Inc.
- *
- * Author: Georgi Vlaev <joe@nucleusys.com>
- * Brian Austin <brian.austin@cirrus.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __CS42L73_H__
-#define __CS42L73_H__
-
-/* I2C Registers */
-/* I2C Address: 1001010[R/W] - 10010100 = 0x94(Write); 10010101 = 0x95(Read) */
-#define CS42L73_CHIP_ID 0x4a
-#define CS42L73_DEVID_AB 0x01 /* Device ID A & B [RO]. */
-#define CS42L73_DEVID_CD 0x02 /* Device ID C & D [RO]. */
-#define CS42L73_DEVID_E 0x03 /* Device ID E [RO]. */
-#define CS42L73_REVID 0x05 /* Revision ID [RO]. */
-#define CS42L73_PWRCTL1 0x06 /* Power Control 1. */
-#define CS42L73_PWRCTL2 0x07 /* Power Control 2. */
-#define CS42L73_PWRCTL3 0x08 /* Power Control 3. */
-#define CS42L73_CPFCHC 0x09 /* Charge Pump Freq. Class H Ctl. */
-#define CS42L73_OLMBMSDC 0x0A /* Output Load, MIC Bias, MIC2 SDT */
-#define CS42L73_DMMCC 0x0B /* Digital MIC & Master Clock Ctl. */
-#define CS42L73_XSPC 0x0C /* Auxiliary Serial Port (XSP) Ctl. */
-#define CS42L73_XSPMMCC 0x0D /* XSP Master Mode Clocking Control. */
-#define CS42L73_ASPC 0x0E /* Audio Serial Port (ASP) Control. */
-#define CS42L73_ASPMMCC 0x0F /* ASP Master Mode Clocking Control. */
-#define CS42L73_VSPC 0x10 /* Voice Serial Port (VSP) Control. */
-#define CS42L73_VSPMMCC 0x11 /* VSP Master Mode Clocking Control. */
-#define CS42L73_VXSPFS 0x12 /* VSP & XSP Sample Rate. */
-#define CS42L73_MIOPC 0x13 /* Misc. Input & Output Path Control. */
-#define CS42L73_ADCIPC 0x14 /* ADC/IP Control. */
-#define CS42L73_MICAPREPGAAVOL 0x15 /* MIC 1 [A] PreAmp, PGAA Vol. */
-#define CS42L73_MICBPREPGABVOL 0x16 /* MIC 2 [B] PreAmp, PGAB Vol. */
-#define CS42L73_IPADVOL 0x17 /* Input Pat7h A Digital Volume. */
-#define CS42L73_IPBDVOL 0x18 /* Input Path B Digital Volume. */
-#define CS42L73_PBDC 0x19 /* Playback Digital Control. */
-#define CS42L73_HLADVOL 0x1A /* HP/Line A Out Digital Vol. */
-#define CS42L73_HLBDVOL 0x1B /* HP/Line B Out Digital Vol. */
-#define CS42L73_SPKDVOL 0x1C /* Spkphone Out [A] Digital Vol. */
-#define CS42L73_ESLDVOL 0x1D /* Ear/Spkphone LO [B] Digital */
-#define CS42L73_HPAAVOL 0x1E /* HP A Analog Volume. */
-#define CS42L73_HPBAVOL 0x1F /* HP B Analog Volume. */
-#define CS42L73_LOAAVOL 0x20 /* Line Out A Analog Volume. */
-#define CS42L73_LOBAVOL 0x21 /* Line Out B Analog Volume. */
-#define CS42L73_STRINV 0x22 /* Stereo Input Path Adv. Vol. */
-#define CS42L73_XSPINV 0x23 /* Auxiliary Port Input Advisory Vol. */
-#define CS42L73_ASPINV 0x24 /* Audio Port Input Advisory Vol. */
-#define CS42L73_VSPINV 0x25 /* Voice Port Input Advisory Vol. */
-#define CS42L73_LIMARATEHL 0x26 /* Lmtr Attack Rate HP/Line. */
-#define CS42L73_LIMRRATEHL 0x27 /* Lmtr Ctl, Rel.Rate HP/Line. */
-#define CS42L73_LMAXHL 0x28 /* Lmtr Thresholds HP/Line. */
-#define CS42L73_LIMARATESPK 0x29 /* Lmtr Attack Rate Spkphone [A]. */
-#define CS42L73_LIMRRATESPK 0x2A /* Lmtr Ctl,Release Rate Spk. [A]. */
-#define CS42L73_LMAXSPK 0x2B /* Lmtr Thresholds Spkphone [A]. */
-#define CS42L73_LIMARATEESL 0x2C /* Lmtr Attack Rate */
-#define CS42L73_LIMRRATEESL 0x2D /* Lmtr Ctl,Release Rate */
-#define CS42L73_LMAXESL 0x2E /* Lmtr Thresholds */
-#define CS42L73_ALCARATE 0x2F /* ALC Enable, Attack Rate AB. */
-#define CS42L73_ALCRRATE 0x30 /* ALC Release Rate AB. */
-#define CS42L73_ALCMINMAX 0x31 /* ALC Thresholds AB. */
-#define CS42L73_NGCAB 0x32 /* Noise Gate Ctl AB. */
-#define CS42L73_ALCNGMC 0x33 /* ALC & Noise Gate Misc Ctl. */
-#define CS42L73_MIXERCTL 0x34 /* Mixer Control. */
-#define CS42L73_HLAIPAA 0x35 /* HP/LO Left Mixer: L. */
-#define CS42L73_HLBIPBA 0x36 /* HP/LO Right Mixer: R. */
-#define CS42L73_HLAXSPAA 0x37 /* HP/LO Left Mixer: XSP L */
-#define CS42L73_HLBXSPBA 0x38 /* HP/LO Right Mixer: XSP R */
-#define CS42L73_HLAASPAA 0x39 /* HP/LO Left Mixer: ASP L */
-#define CS42L73_HLBASPBA 0x3A /* HP/LO Right Mixer: ASP R */
-#define CS42L73_HLAVSPMA 0x3B /* HP/LO Left Mixer: VSP. */
-#define CS42L73_HLBVSPMA 0x3C /* HP/LO Right Mixer: VSP */
-#define CS42L73_XSPAIPAA 0x3D /* XSP Left Mixer: Left */
-#define CS42L73_XSPBIPBA 0x3E /* XSP Rt. Mixer: Right */
-#define CS42L73_XSPAXSPAA 0x3F /* XSP Left Mixer: XSP L */
-#define CS42L73_XSPBXSPBA 0x40 /* XSP Rt. Mixer: XSP R */
-#define CS42L73_XSPAASPAA 0x41 /* XSP Left Mixer: ASP L */
-#define CS42L73_XSPAASPBA 0x42 /* XSP Rt. Mixer: ASP R */
-#define CS42L73_XSPAVSPMA 0x43 /* XSP Left Mixer: VSP */
-#define CS42L73_XSPBVSPMA 0x44 /* XSP Rt. Mixer: VSP */
-#define CS42L73_ASPAIPAA 0x45 /* ASP Left Mixer: Left */
-#define CS42L73_ASPBIPBA 0x46 /* ASP Rt. Mixer: Right */
-#define CS42L73_ASPAXSPAA 0x47 /* ASP Left Mixer: XSP L */
-#define CS42L73_ASPBXSPBA 0x48 /* ASP Rt. Mixer: XSP R */
-#define CS42L73_ASPAASPAA 0x49 /* ASP Left Mixer: ASP L */
-#define CS42L73_ASPBASPBA 0x4A /* ASP Rt. Mixer: ASP R */
-#define CS42L73_ASPAVSPMA 0x4B /* ASP Left Mixer: VSP */
-#define CS42L73_ASPBVSPMA 0x4C /* ASP Rt. Mixer: VSP */
-#define CS42L73_VSPAIPAA 0x4D /* VSP Left Mixer: Left */
-#define CS42L73_VSPBIPBA 0x4E /* VSP Rt. Mixer: Right */
-#define CS42L73_VSPAXSPAA 0x4F /* VSP Left Mixer: XSP L */
-#define CS42L73_VSPBXSPBA 0x50 /* VSP Rt. Mixer: XSP R */
-#define CS42L73_VSPAASPAA 0x51 /* VSP Left Mixer: ASP Left */
-#define CS42L73_VSPBASPBA 0x52 /* VSP Rt. Mixer: ASP Right */
-#define CS42L73_VSPAVSPMA 0x53 /* VSP Left Mixer: VSP */
-#define CS42L73_VSPBVSPMA 0x54 /* VSP Rt. Mixer: VSP */
-#define CS42L73_MMIXCTL 0x55 /* Mono Mixer Controls. */
-#define CS42L73_SPKMIPMA 0x56 /* SPK Mono Mixer: In. Path */
-#define CS42L73_SPKMXSPA 0x57 /* SPK Mono Mixer: XSP Mono/L/R Att. */
-#define CS42L73_SPKMASPA 0x58 /* SPK Mono Mixer: ASP Mono/L/R Att. */
-#define CS42L73_SPKMVSPMA 0x59 /* SPK Mono Mixer: VSP Mono Atten. */
-#define CS42L73_ESLMIPMA 0x5A /* Ear/SpLO Mono Mixer: */
-#define CS42L73_ESLMXSPA 0x5B /* Ear/SpLO Mono Mixer: XSP */
-#define CS42L73_ESLMASPA 0x5C /* Ear/SpLO Mono Mixer: ASP */
-#define CS42L73_ESLMVSPMA 0x5D /* Ear/SpLO Mono Mixer: VSP */
-#define CS42L73_IM1 0x5E /* Interrupt Mask 1. */
-#define CS42L73_IM2 0x5F /* Interrupt Mask 2. */
-#define CS42L73_IS1 0x60 /* Interrupt Status 1 [RO]. */
-#define CS42L73_IS2 0x61 /* Interrupt Status 2 [RO]. */
-#define CS42L73_MAX_REGISTER 0x61 /* Total Registers */
-/* Bitfield Definitions */
-
-/* CS42L73_PWRCTL1 */
-#define PDN_ADCB (1 << 7)
-#define PDN_DMICB (1 << 6)
-#define PDN_ADCA (1 << 5)
-#define PDN_DMICA (1 << 4)
-#define PDN_LDO (1 << 2)
-#define DISCHG_FILT (1 << 1)
-#define PDN (1 << 0)
-
-/* CS42L73_PWRCTL2 */
-#define PDN_MIC2_BIAS (1 << 7)
-#define PDN_MIC1_BIAS (1 << 6)
-#define PDN_VSP (1 << 4)
-#define PDN_ASP_SDOUT (1 << 3)
-#define PDN_ASP_SDIN (1 << 2)
-#define PDN_XSP_SDOUT (1 << 1)
-#define PDN_XSP_SDIN (1 << 0)
-
-/* CS42L73_PWRCTL3 */
-#define PDN_THMS (1 << 5)
-#define PDN_SPKLO (1 << 4)
-#define PDN_EAR (1 << 3)
-#define PDN_SPK (1 << 2)
-#define PDN_LO (1 << 1)
-#define PDN_HP (1 << 0)
-
-/* Thermal Overload Detect. Requires interrupt ... */
-#define THMOVLD_150C 0
-#define THMOVLD_132C 1
-#define THMOVLD_115C 2
-#define THMOVLD_098C 3
-
-
-/* CS42L73_ASPC, CS42L73_XSPC, CS42L73_VSPC */
-#define SP_3ST (1 << 7)
-#define SPDIF_I2S (0 << 6)
-#define SPDIF_PCM (1 << 6)
-#define PCM_MODE0 (0 << 4)
-#define PCM_MODE1 (1 << 4)
-#define PCM_MODE2 (2 << 4)
-#define PCM_MODE_MASK (3 << 4)
-#define PCM_BIT_ORDER (1 << 3)
-#define MCK_SCLK_64FS (0 << 0)
-#define MCK_SCLK_MCLK (2 << 0)
-#define MCK_SCLK_PREMCLK (3 << 0)
-
-/* CS42L73_xSPMMCC */
-#define MS_MASTER (1 << 7)
-
-
-/* CS42L73_DMMCC */
-#define MCLKDIS (1 << 0)
-#define MCLKSEL_MCLK2 (1 << 4)
-#define MCLKSEL_MCLK1 (0 << 4)
-
-/* CS42L73 MCLK derived from MCLK1 or MCLK2 */
-#define CS42L73_CLKID_MCLK1 0
-#define CS42L73_CLKID_MCLK2 1
-
-#define CS42L73_MCLKXDIV 0
-#define CS42L73_MMCCDIV 1
-
-#define CS42L73_XSP 0
-#define CS42L73_ASP 1
-#define CS42L73_VSP 2
-
-/* IS1, IM1 */
-#define MIC2_SDET (1 << 6)
-#define THMOVLD (1 << 4)
-#define DIGMIXOVFL (1 << 3)
-#define IPBOVFL (1 << 1)
-#define IPAOVFL (1 << 0)
-
-/* Analog Softramp */
-#define ANLGOSFT (1 << 0)
-
-/* HP A/B Analog Mute */
-#define HPA_MUTE (1 << 7)
-/* LO A/B Analog Mute */
-#define LOA_MUTE (1 << 7)
-/* Digital Mute */
-#define HLAD_MUTE (1 << 0)
-#define HLBD_MUTE (1 << 1)
-#define SPKD_MUTE (1 << 2)
-#define ESLD_MUTE (1 << 3)
-
-/* Misc defines for codec */
-#define CS42L73_RESET_GPIO 143
-
-#define CS42L73_DEVID 0x00042A73
-#define CS42L73_MCLKX_MIN 5644800
-#define CS42L73_MCLKX_MAX 38400000
-
-#define CS42L73_SPC(id) (CS42L73_XSPC + (id << 1))
-#define CS42L73_MMCC(id) (CS42L73_XSPMMCC + (id << 1))
-#define CS42L73_SPFS(id) ((id == CS42L73_ASP) ? CS42L73_ASPC : CS42L73_VXSPFS)
-
-#endif /* __CS42L73_H__ */
diff --git a/ANDROID_3.4.5/sound/soc/codecs/cx20442.c b/ANDROID_3.4.5/sound/soc/codecs/cx20442.c
deleted file mode 100644
index d5fd00a6..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/cx20442.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * cx20442.c -- CX20442 ALSA Soc Audio driver
- *
- * Copyright 2009 Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
- *
- * Initially based on sound/soc/codecs/wm8400.c
- * Copyright 2008, 2009 Wolfson Microelectronics PLC.
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/regulator/consumer.h>
-
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include "cx20442.h"
-
-
-struct cx20442_priv {
- void *control_data;
- struct regulator *por;
-};
-
-#define CX20442_PM 0x0
-
-#define CX20442_TELIN 0
-#define CX20442_TELOUT 1
-#define CX20442_MIC 2
-#define CX20442_SPKOUT 3
-#define CX20442_AGC 4
-
-static const struct snd_soc_dapm_widget cx20442_dapm_widgets[] = {
- SND_SOC_DAPM_OUTPUT("TELOUT"),
- SND_SOC_DAPM_OUTPUT("SPKOUT"),
- SND_SOC_DAPM_OUTPUT("AGCOUT"),
-
- SND_SOC_DAPM_MIXER("SPKOUT Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-
- SND_SOC_DAPM_PGA("TELOUT Amp", CX20442_PM, CX20442_TELOUT, 0, NULL, 0),
- SND_SOC_DAPM_PGA("SPKOUT Amp", CX20442_PM, CX20442_SPKOUT, 0, NULL, 0),
- SND_SOC_DAPM_PGA("SPKOUT AGC", CX20442_PM, CX20442_AGC, 0, NULL, 0),
-
- SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
-
- SND_SOC_DAPM_MIXER("Input Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-
- SND_SOC_DAPM_MICBIAS("TELIN Bias", CX20442_PM, CX20442_TELIN, 0),
- SND_SOC_DAPM_MICBIAS("MIC Bias", CX20442_PM, CX20442_MIC, 0),
-
- SND_SOC_DAPM_PGA("MIC AGC", CX20442_PM, CX20442_AGC, 0, NULL, 0),
-
- SND_SOC_DAPM_INPUT("TELIN"),
- SND_SOC_DAPM_INPUT("MIC"),
- SND_SOC_DAPM_INPUT("AGCIN"),
-};
-
-static const struct snd_soc_dapm_route cx20442_audio_map[] = {
- {"TELOUT", NULL, "TELOUT Amp"},
-
- {"SPKOUT", NULL, "SPKOUT Mixer"},
- {"SPKOUT Mixer", NULL, "SPKOUT Amp"},
-
- {"TELOUT Amp", NULL, "DAC"},
- {"SPKOUT Amp", NULL, "DAC"},
-
- {"SPKOUT Mixer", NULL, "SPKOUT AGC"},
- {"SPKOUT AGC", NULL, "AGCIN"},
-
- {"AGCOUT", NULL, "MIC AGC"},
- {"MIC AGC", NULL, "MIC"},
-
- {"MIC Bias", NULL, "MIC"},
- {"Input Mixer", NULL, "MIC Bias"},
-
- {"TELIN Bias", NULL, "TELIN"},
- {"Input Mixer", NULL, "TELIN Bias"},
-
- {"ADC", NULL, "Input Mixer"},
-};
-
-static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- u8 *reg_cache = codec->reg_cache;
-
- if (reg >= codec->driver->reg_cache_size)
- return -EINVAL;
-
- return reg_cache[reg];
-}
-
-enum v253_vls {
- V253_VLS_NONE = 0,
- V253_VLS_T,
- V253_VLS_L,
- V253_VLS_LT,
- V253_VLS_S,
- V253_VLS_ST,
- V253_VLS_M,
- V253_VLS_MST,
- V253_VLS_S1,
- V253_VLS_S1T,
- V253_VLS_MS1T,
- V253_VLS_M1,
- V253_VLS_M1ST,
- V253_VLS_M1S1T,
- V253_VLS_H,
- V253_VLS_HT,
- V253_VLS_MS,
- V253_VLS_MS1,
- V253_VLS_M1S,
- V253_VLS_M1S1,
- V253_VLS_TEST,
-};
-
-static int cx20442_pm_to_v253_vls(u8 value)
-{
- switch (value & ~(1 << CX20442_AGC)) {
- case 0:
- return V253_VLS_T;
- case (1 << CX20442_SPKOUT):
- case (1 << CX20442_MIC):
- case (1 << CX20442_SPKOUT) | (1 << CX20442_MIC):
- return V253_VLS_M1S1;
- case (1 << CX20442_TELOUT):
- case (1 << CX20442_TELIN):
- case (1 << CX20442_TELOUT) | (1 << CX20442_TELIN):
- return V253_VLS_L;
- case (1 << CX20442_TELOUT) | (1 << CX20442_MIC):
- return V253_VLS_NONE;
- }
- return -EINVAL;
-}
-static int cx20442_pm_to_v253_vsp(u8 value)
-{
- switch (value & ~(1 << CX20442_AGC)) {
- case (1 << CX20442_SPKOUT):
- case (1 << CX20442_MIC):
- case (1 << CX20442_SPKOUT) | (1 << CX20442_MIC):
- return (bool)(value & (1 << CX20442_AGC));
- }
- return (value & (1 << CX20442_AGC)) ? -EINVAL : 0;
-}
-
-static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
- u8 *reg_cache = codec->reg_cache;
- int vls, vsp, old, len;
- char buf[18];
-
- if (reg >= codec->driver->reg_cache_size)
- return -EINVAL;
-
- /* hw_write and control_data pointers required for talking to the modem
- * are expected to be set by the line discipline initialization code */
- if (!codec->hw_write || !cx20442->control_data)
- return -EIO;
-
- old = reg_cache[reg];
- reg_cache[reg] = value;
-
- vls = cx20442_pm_to_v253_vls(value);
- if (vls < 0)
- return vls;
-
- vsp = cx20442_pm_to_v253_vsp(value);
- if (vsp < 0)
- return vsp;
-
- if ((vls == V253_VLS_T) ||
- (vls == cx20442_pm_to_v253_vls(old))) {
- if (vsp == cx20442_pm_to_v253_vsp(old))
- return 0;
- len = snprintf(buf, ARRAY_SIZE(buf), "at+vsp=%d\r", vsp);
- } else if (vsp == cx20442_pm_to_v253_vsp(old))
- len = snprintf(buf, ARRAY_SIZE(buf), "at+vls=%d\r", vls);
- else
- len = snprintf(buf, ARRAY_SIZE(buf),
- "at+vls=%d;+vsp=%d\r", vls, vsp);
-
- if (unlikely(len > (ARRAY_SIZE(buf) - 1)))
- return -ENOMEM;
-
- dev_dbg(codec->dev, "%s: %s\n", __func__, buf);
- if (codec->hw_write(cx20442->control_data, buf, len) != len)
- return -EIO;
-
- return 0;
-}
-
-
-/*
- * Line discpline related code
- *
- * Any of the callback functions below can be used in two ways:
- * 1) registerd by a machine driver as one of line discipline operations,
- * 2) called from a machine's provided line discipline callback function
- * in case when extra machine specific code must be run as well.
- */
-
-/* Modem init: echo off, digital speaker off, quiet off, voice mode */
-static const char *v253_init = "ate0m0q0+fclass=8\r";
-
-/* Line discipline .open() */
-static int v253_open(struct tty_struct *tty)
-{
- int ret, len = strlen(v253_init);
-
- /* Doesn't make sense without write callback */
- if (!tty->ops->write)
- return -EINVAL;
-
- /* Won't work if no codec pointer has been passed by a card driver */
- if (!tty->disc_data)
- return -ENODEV;
-
- if (tty->ops->write(tty, v253_init, len) != len) {
- ret = -EIO;
- goto err;
- }
- /* Actual setup will be performed after the modem responds. */
- return 0;
-err:
- tty->disc_data = NULL;
- return ret;
-}
-
-/* Line discipline .close() */
-static void v253_close(struct tty_struct *tty)
-{
- struct snd_soc_codec *codec = tty->disc_data;
- struct cx20442_priv *cx20442;
-
- tty->disc_data = NULL;
-
- if (!codec)
- return;
-
- cx20442 = snd_soc_codec_get_drvdata(codec);
-
- /* Prevent the codec driver from further accessing the modem */
- codec->hw_write = NULL;
- cx20442->control_data = NULL;
- codec->card->pop_time = 0;
-}
-
-/* Line discipline .hangup() */
-static int v253_hangup(struct tty_struct *tty)
-{
- v253_close(tty);
- return 0;
-}
-
-/* Line discipline .receive_buf() */
-static void v253_receive(struct tty_struct *tty,
- const unsigned char *cp, char *fp, int count)
-{
- struct snd_soc_codec *codec = tty->disc_data;
- struct cx20442_priv *cx20442;
-
- if (!codec)
- return;
-
- cx20442 = snd_soc_codec_get_drvdata(codec);
-
- if (!cx20442->control_data) {
- /* First modem response, complete setup procedure */
-
- /* Set up codec driver access to modem controls */
- cx20442->control_data = tty;
- codec->hw_write = (hw_write_t)tty->ops->write;
- codec->card->pop_time = 1;
- }
-}
-
-/* Line discipline .write_wakeup() */
-static void v253_wakeup(struct tty_struct *tty)
-{
-}
-
-struct tty_ldisc_ops v253_ops = {
- .magic = TTY_LDISC_MAGIC,
- .name = "cx20442",
- .owner = THIS_MODULE,
- .open = v253_open,
- .close = v253_close,
- .hangup = v253_hangup,
- .receive_buf = v253_receive,
- .write_wakeup = v253_wakeup,
-};
-EXPORT_SYMBOL_GPL(v253_ops);
-
-
-/*
- * Codec DAI
- */
-
-static struct snd_soc_dai_driver cx20442_dai = {
- .name = "cx20442-voice",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 1,
- .rates = SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 1,
- .rates = SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
-};
-
-static int cx20442_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
- int err = 0;
-
- switch (level) {
- case SND_SOC_BIAS_PREPARE:
- if (codec->dapm.bias_level != SND_SOC_BIAS_STANDBY)
- break;
- if (IS_ERR(cx20442->por))
- err = PTR_ERR(cx20442->por);
- else
- err = regulator_enable(cx20442->por);
- break;
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level != SND_SOC_BIAS_PREPARE)
- break;
- if (IS_ERR(cx20442->por))
- err = PTR_ERR(cx20442->por);
- else
- err = regulator_disable(cx20442->por);
- break;
- default:
- break;
- }
- if (!err)
- codec->dapm.bias_level = level;
-
- return err;
-}
-
-static int cx20442_codec_probe(struct snd_soc_codec *codec)
-{
- struct cx20442_priv *cx20442;
-
- cx20442 = kzalloc(sizeof(struct cx20442_priv), GFP_KERNEL);
- if (cx20442 == NULL)
- return -ENOMEM;
-
- cx20442->por = regulator_get(codec->dev, "POR");
- if (IS_ERR(cx20442->por))
- dev_warn(codec->dev, "failed to get the regulator");
- cx20442->control_data = NULL;
-
- snd_soc_codec_set_drvdata(codec, cx20442);
- codec->hw_write = NULL;
- codec->card->pop_time = 0;
-
- return 0;
-}
-
-/* power down chip */
-static int cx20442_codec_remove(struct snd_soc_codec *codec)
-{
- struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
-
- if (cx20442->control_data) {
- struct tty_struct *tty = cx20442->control_data;
- tty_hangup(tty);
- }
-
- if (!IS_ERR(cx20442->por)) {
- /* should be already in STANDBY, hence disabled */
- regulator_put(cx20442->por);
- }
-
- snd_soc_codec_set_drvdata(codec, NULL);
- kfree(cx20442);
- return 0;
-}
-
-static const u8 cx20442_reg;
-
-static struct snd_soc_codec_driver cx20442_codec_dev = {
- .probe = cx20442_codec_probe,
- .remove = cx20442_codec_remove,
- .set_bias_level = cx20442_set_bias_level,
- .reg_cache_default = &cx20442_reg,
- .reg_cache_size = 1,
- .reg_word_size = sizeof(u8),
- .read = cx20442_read_reg_cache,
- .write = cx20442_write,
- .dapm_widgets = cx20442_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(cx20442_dapm_widgets),
- .dapm_routes = cx20442_audio_map,
- .num_dapm_routes = ARRAY_SIZE(cx20442_audio_map),
-};
-
-static int cx20442_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev,
- &cx20442_codec_dev, &cx20442_dai, 1);
-}
-
-static int __exit cx20442_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver cx20442_platform_driver = {
- .driver = {
- .name = "cx20442-codec",
- .owner = THIS_MODULE,
- },
- .probe = cx20442_platform_probe,
- .remove = __exit_p(cx20442_platform_remove),
-};
-
-module_platform_driver(cx20442_platform_driver);
-
-MODULE_DESCRIPTION("ASoC CX20442-11 voice modem codec driver");
-MODULE_AUTHOR("Janusz Krzysztofik");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:cx20442-codec");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/cx20442.h b/ANDROID_3.4.5/sound/soc/codecs/cx20442.h
deleted file mode 100644
index c7a7c79e..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/cx20442.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * cx20442.h -- audio driver for CX20442
- *
- * Copyright 2009 Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#ifndef _CX20442_CODEC_H
-#define _CX20442_CODEC_H
-
-extern struct tty_ldisc_ops v253_ops;
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/da7210.c b/ANDROID_3.4.5/sound/soc/codecs/da7210.c
deleted file mode 100644
index 78437117..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/da7210.c
+++ /dev/null
@@ -1,1151 +0,0 @@
-/*
- * DA7210 ALSA Soc codec driver
- *
- * Copyright (c) 2009 Dialog Semiconductor
- * Written by David Chen <Dajun.chen@diasemi.com>
- *
- * Copyright (C) 2009 Renesas Solutions Corp.
- * Cleanups by Kuninori Morimoto <morimoto.kuninori@renesas.com>
- *
- * Tested on SuperH Ecovec24 board with S16/S24 LE in 48KHz using I2S
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/regmap.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-/* DA7210 register space */
-#define DA7210_CONTROL 0x01
-#define DA7210_STATUS 0x02
-#define DA7210_STARTUP1 0x03
-#define DA7210_STARTUP2 0x04
-#define DA7210_STARTUP3 0x05
-#define DA7210_MIC_L 0x07
-#define DA7210_MIC_R 0x08
-#define DA7210_AUX1_L 0x09
-#define DA7210_AUX1_R 0x0A
-#define DA7210_AUX2 0x0B
-#define DA7210_IN_GAIN 0x0C
-#define DA7210_INMIX_L 0x0D
-#define DA7210_INMIX_R 0x0E
-#define DA7210_ADC_HPF 0x0F
-#define DA7210_ADC 0x10
-#define DA7210_ADC_EQ1_2 0X11
-#define DA7210_ADC_EQ3_4 0x12
-#define DA7210_ADC_EQ5 0x13
-#define DA7210_DAC_HPF 0x14
-#define DA7210_DAC_L 0x15
-#define DA7210_DAC_R 0x16
-#define DA7210_DAC_SEL 0x17
-#define DA7210_SOFTMUTE 0x18
-#define DA7210_DAC_EQ1_2 0x19
-#define DA7210_DAC_EQ3_4 0x1A
-#define DA7210_DAC_EQ5 0x1B
-#define DA7210_OUTMIX_L 0x1C
-#define DA7210_OUTMIX_R 0x1D
-#define DA7210_OUT1_L 0x1E
-#define DA7210_OUT1_R 0x1F
-#define DA7210_OUT2 0x20
-#define DA7210_HP_L_VOL 0x21
-#define DA7210_HP_R_VOL 0x22
-#define DA7210_HP_CFG 0x23
-#define DA7210_ZERO_CROSS 0x24
-#define DA7210_DAI_SRC_SEL 0x25
-#define DA7210_DAI_CFG1 0x26
-#define DA7210_DAI_CFG3 0x28
-#define DA7210_PLL_DIV1 0x29
-#define DA7210_PLL_DIV2 0x2A
-#define DA7210_PLL_DIV3 0x2B
-#define DA7210_PLL 0x2C
-#define DA7210_ALC_MAX 0x83
-#define DA7210_ALC_MIN 0x84
-#define DA7210_ALC_NOIS 0x85
-#define DA7210_ALC_ATT 0x86
-#define DA7210_ALC_REL 0x87
-#define DA7210_ALC_DEL 0x88
-#define DA7210_A_HID_UNLOCK 0x8A
-#define DA7210_A_TEST_UNLOCK 0x8B
-#define DA7210_A_PLL1 0x90
-#define DA7210_A_CP_MODE 0xA7
-
-/* STARTUP1 bit fields */
-#define DA7210_SC_MST_EN (1 << 0)
-
-/* MIC_L bit fields */
-#define DA7210_MICBIAS_EN (1 << 6)
-#define DA7210_MIC_L_EN (1 << 7)
-
-/* MIC_R bit fields */
-#define DA7210_MIC_R_EN (1 << 7)
-
-/* INMIX_L bit fields */
-#define DA7210_IN_L_EN (1 << 7)
-
-/* INMIX_R bit fields */
-#define DA7210_IN_R_EN (1 << 7)
-
-/* ADC bit fields */
-#define DA7210_ADC_ALC_EN (1 << 0)
-#define DA7210_ADC_L_EN (1 << 3)
-#define DA7210_ADC_R_EN (1 << 7)
-
-/* DAC/ADC HPF fields */
-#define DA7210_VOICE_F0_MASK (0x7 << 4)
-#define DA7210_VOICE_F0_25 (1 << 4)
-#define DA7210_VOICE_EN (1 << 7)
-
-/* DAC_SEL bit fields */
-#define DA7210_DAC_L_SRC_DAI_L (4 << 0)
-#define DA7210_DAC_L_EN (1 << 3)
-#define DA7210_DAC_R_SRC_DAI_R (5 << 4)
-#define DA7210_DAC_R_EN (1 << 7)
-
-/* OUTMIX_L bit fields */
-#define DA7210_OUT_L_EN (1 << 7)
-
-/* OUTMIX_R bit fields */
-#define DA7210_OUT_R_EN (1 << 7)
-
-/* HP_CFG bit fields */
-#define DA7210_HP_2CAP_MODE (1 << 1)
-#define DA7210_HP_SENSE_EN (1 << 2)
-#define DA7210_HP_L_EN (1 << 3)
-#define DA7210_HP_MODE (1 << 6)
-#define DA7210_HP_R_EN (1 << 7)
-
-/* DAI_SRC_SEL bit fields */
-#define DA7210_DAI_OUT_L_SRC (6 << 0)
-#define DA7210_DAI_OUT_R_SRC (7 << 4)
-
-/* DAI_CFG1 bit fields */
-#define DA7210_DAI_WORD_S16_LE (0 << 0)
-#define DA7210_DAI_WORD_S20_3LE (1 << 0)
-#define DA7210_DAI_WORD_S24_LE (2 << 0)
-#define DA7210_DAI_WORD_S32_LE (3 << 0)
-#define DA7210_DAI_FLEN_64BIT (1 << 2)
-#define DA7210_DAI_MODE_SLAVE (0 << 7)
-#define DA7210_DAI_MODE_MASTER (1 << 7)
-
-/* DAI_CFG3 bit fields */
-#define DA7210_DAI_FORMAT_I2SMODE (0 << 0)
-#define DA7210_DAI_FORMAT_LEFT_J (1 << 0)
-#define DA7210_DAI_FORMAT_RIGHT_J (2 << 0)
-#define DA7210_DAI_OE (1 << 3)
-#define DA7210_DAI_EN (1 << 7)
-
-/*PLL_DIV3 bit fields */
-#define DA7210_MCLK_RANGE_10_20_MHZ (1 << 4)
-#define DA7210_PLL_BYP (1 << 6)
-
-/* PLL bit fields */
-#define DA7210_PLL_FS_MASK (0xF << 0)
-#define DA7210_PLL_FS_8000 (0x1 << 0)
-#define DA7210_PLL_FS_11025 (0x2 << 0)
-#define DA7210_PLL_FS_12000 (0x3 << 0)
-#define DA7210_PLL_FS_16000 (0x5 << 0)
-#define DA7210_PLL_FS_22050 (0x6 << 0)
-#define DA7210_PLL_FS_24000 (0x7 << 0)
-#define DA7210_PLL_FS_32000 (0x9 << 0)
-#define DA7210_PLL_FS_44100 (0xA << 0)
-#define DA7210_PLL_FS_48000 (0xB << 0)
-#define DA7210_PLL_FS_88200 (0xE << 0)
-#define DA7210_PLL_FS_96000 (0xF << 0)
-#define DA7210_PLL_EN (0x1 << 7)
-
-/* SOFTMUTE bit fields */
-#define DA7210_RAMP_EN (1 << 6)
-
-/* CONTROL bit fields */
-#define DA7210_NOISE_SUP_EN (1 << 3)
-
-/* IN_GAIN bit fields */
-#define DA7210_INPGA_L_VOL (0x0F << 0)
-#define DA7210_INPGA_R_VOL (0xF0 << 0)
-
-/* ZERO_CROSS bit fields */
-#define DA7210_AUX1_L_ZC (1 << 0)
-#define DA7210_AUX1_R_ZC (1 << 1)
-#define DA7210_HP_L_ZC (1 << 6)
-#define DA7210_HP_R_ZC (1 << 7)
-
-/* AUX1_L bit fields */
-#define DA7210_AUX1_L_VOL (0x3F << 0)
-#define DA7210_AUX1_L_EN (1 << 7)
-
-/* AUX1_R bit fields */
-#define DA7210_AUX1_R_VOL (0x3F << 0)
-#define DA7210_AUX1_R_EN (1 << 7)
-
-/* AUX2 bit fields */
-#define DA7210_AUX2_EN (1 << 3)
-
-/* Minimum INPGA and AUX1 volume to enable noise suppression */
-#define DA7210_INPGA_MIN_VOL_NS 0x0A /* 10.5dB */
-#define DA7210_AUX1_MIN_VOL_NS 0x35 /* 6dB */
-
-/* OUT1_L bit fields */
-#define DA7210_OUT1_L_EN (1 << 7)
-
-/* OUT1_R bit fields */
-#define DA7210_OUT1_R_EN (1 << 7)
-
-/* OUT2 bit fields */
-#define DA7210_OUT2_OUTMIX_R (1 << 5)
-#define DA7210_OUT2_OUTMIX_L (1 << 6)
-#define DA7210_OUT2_EN (1 << 7)
-
-#define DA7210_VERSION "0.0.1"
-
-/*
- * Playback Volume
- *
- * max : 0x3F (+15.0 dB)
- * (1.5 dB step)
- * min : 0x11 (-54.0 dB)
- * mute : 0x10
- * reserved : 0x00 - 0x0F
- *
- * Reserved area are considered as "mute".
- */
-static const unsigned int hp_out_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0x0, 0x10, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
- /* -54 dB to +15 dB */
- 0x11, 0x3f, TLV_DB_SCALE_ITEM(-5400, 150, 0),
-};
-
-static const unsigned int lineout_vol_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0x0, 0x10, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
- /* -54dB to 15dB */
- 0x11, 0x3f, TLV_DB_SCALE_ITEM(-5400, 150, 0)
-};
-
-static const unsigned int mono_vol_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0x0, 0x2, TLV_DB_SCALE_ITEM(-1800, 0, 1),
- /* -18dB to 6dB */
- 0x3, 0x7, TLV_DB_SCALE_ITEM(-1800, 600, 0)
-};
-
-static const unsigned int aux1_vol_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0x0, 0x10, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
- /* -48dB to 21dB */
- 0x11, 0x3f, TLV_DB_SCALE_ITEM(-4800, 150, 0)
-};
-
-static const DECLARE_TLV_DB_SCALE(eq_gain_tlv, -1050, 150, 0);
-static const DECLARE_TLV_DB_SCALE(adc_eq_master_gain_tlv, -1800, 600, 1);
-static const DECLARE_TLV_DB_SCALE(dac_gain_tlv, -7725, 75, 0);
-static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, -600, 600, 0);
-static const DECLARE_TLV_DB_SCALE(aux2_vol_tlv, -600, 600, 0);
-static const DECLARE_TLV_DB_SCALE(inpga_gain_tlv, -450, 150, 0);
-
-/* ADC and DAC high pass filter f0 value */
-static const char * const da7210_hpf_cutoff_txt[] = {
- "Fs/8192*pi", "Fs/4096*pi", "Fs/2048*pi", "Fs/1024*pi"
-};
-
-static const struct soc_enum da7210_dac_hpf_cutoff =
- SOC_ENUM_SINGLE(DA7210_DAC_HPF, 0, 4, da7210_hpf_cutoff_txt);
-
-static const struct soc_enum da7210_adc_hpf_cutoff =
- SOC_ENUM_SINGLE(DA7210_ADC_HPF, 0, 4, da7210_hpf_cutoff_txt);
-
-/* ADC and DAC voice (8kHz) high pass cutoff value */
-static const char * const da7210_vf_cutoff_txt[] = {
- "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
-};
-
-static const struct soc_enum da7210_dac_vf_cutoff =
- SOC_ENUM_SINGLE(DA7210_DAC_HPF, 4, 8, da7210_vf_cutoff_txt);
-
-static const struct soc_enum da7210_adc_vf_cutoff =
- SOC_ENUM_SINGLE(DA7210_ADC_HPF, 4, 8, da7210_vf_cutoff_txt);
-
-static const char *da7210_hp_mode_txt[] = {
- "Class H", "Class G"
-};
-
-static const struct soc_enum da7210_hp_mode_sel =
- SOC_ENUM_SINGLE(DA7210_HP_CFG, 0, 2, da7210_hp_mode_txt);
-
-/* ALC can be enabled only if noise suppression is disabled */
-static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-
- if (ucontrol->value.integer.value[0]) {
- /* Check if noise suppression is enabled */
- if (snd_soc_read(codec, DA7210_CONTROL) & DA7210_NOISE_SUP_EN) {
- dev_dbg(codec->dev,
- "Disable noise suppression to enable ALC\n");
- return -EINVAL;
- }
- }
- /* If all conditions are met or we are actually disabling ALC */
- return snd_soc_put_volsw(kcontrol, ucontrol);
-}
-
-/* Noise suppression can be enabled only if following conditions are met
- * ALC disabled
- * ZC enabled for HP and AUX1 PGA
- * INPGA_L_VOL and INPGA_R_VOL >= 10.5 dB
- * AUX1_L_VOL and AUX1_R_VOL >= 6 dB
- */
-static int da7210_put_noise_sup_sw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- u8 val;
-
- if (ucontrol->value.integer.value[0]) {
- /* Check if ALC is enabled */
- if (snd_soc_read(codec, DA7210_ADC) & DA7210_ADC_ALC_EN)
- goto err;
-
- /* Check ZC for HP and AUX1 PGA */
- if ((snd_soc_read(codec, DA7210_ZERO_CROSS) &
- (DA7210_AUX1_L_ZC | DA7210_AUX1_R_ZC | DA7210_HP_L_ZC |
- DA7210_HP_R_ZC)) != (DA7210_AUX1_L_ZC |
- DA7210_AUX1_R_ZC | DA7210_HP_L_ZC | DA7210_HP_R_ZC))
- goto err;
-
- /* Check INPGA_L_VOL and INPGA_R_VOL */
- val = snd_soc_read(codec, DA7210_IN_GAIN);
- if (((val & DA7210_INPGA_L_VOL) < DA7210_INPGA_MIN_VOL_NS) ||
- (((val & DA7210_INPGA_R_VOL) >> 4) <
- DA7210_INPGA_MIN_VOL_NS))
- goto err;
-
- /* Check AUX1_L_VOL and AUX1_R_VOL */
- if (((snd_soc_read(codec, DA7210_AUX1_L) & DA7210_AUX1_L_VOL) <
- DA7210_AUX1_MIN_VOL_NS) ||
- ((snd_soc_read(codec, DA7210_AUX1_R) & DA7210_AUX1_R_VOL) <
- DA7210_AUX1_MIN_VOL_NS))
- goto err;
- }
- /* If all conditions are met or we are actually disabling Noise sup */
- return snd_soc_put_volsw(kcontrol, ucontrol);
-
-err:
- return -EINVAL;
-}
-
-static const struct snd_kcontrol_new da7210_snd_controls[] = {
-
- SOC_DOUBLE_R_TLV("HeadPhone Playback Volume",
- DA7210_HP_L_VOL, DA7210_HP_R_VOL,
- 0, 0x3F, 0, hp_out_tlv),
- SOC_DOUBLE_R_TLV("Digital Playback Volume",
- DA7210_DAC_L, DA7210_DAC_R,
- 0, 0x77, 1, dac_gain_tlv),
- SOC_DOUBLE_R_TLV("Lineout Playback Volume",
- DA7210_OUT1_L, DA7210_OUT1_R,
- 0, 0x3f, 0, lineout_vol_tlv),
- SOC_SINGLE_TLV("Mono Playback Volume", DA7210_OUT2, 0, 0x7, 0,
- mono_vol_tlv),
-
- SOC_DOUBLE_R_TLV("Mic Capture Volume",
- DA7210_MIC_L, DA7210_MIC_R,
- 0, 0x5, 0, mic_vol_tlv),
- SOC_DOUBLE_R_TLV("Aux1 Capture Volume",
- DA7210_AUX1_L, DA7210_AUX1_R,
- 0, 0x3f, 0, aux1_vol_tlv),
- SOC_SINGLE_TLV("Aux2 Capture Volume", DA7210_AUX2, 0, 0x3, 0,
- aux2_vol_tlv),
- SOC_DOUBLE_TLV("In PGA Capture Volume", DA7210_IN_GAIN, 0, 4, 0xF, 0,
- inpga_gain_tlv),
-
- /* DAC Equalizer controls */
- SOC_SINGLE("DAC EQ Switch", DA7210_DAC_EQ5, 7, 1, 0),
- SOC_SINGLE_TLV("DAC EQ1 Volume", DA7210_DAC_EQ1_2, 0, 0xf, 1,
- eq_gain_tlv),
- SOC_SINGLE_TLV("DAC EQ2 Volume", DA7210_DAC_EQ1_2, 4, 0xf, 1,
- eq_gain_tlv),
- SOC_SINGLE_TLV("DAC EQ3 Volume", DA7210_DAC_EQ3_4, 0, 0xf, 1,
- eq_gain_tlv),
- SOC_SINGLE_TLV("DAC EQ4 Volume", DA7210_DAC_EQ3_4, 4, 0xf, 1,
- eq_gain_tlv),
- SOC_SINGLE_TLV("DAC EQ5 Volume", DA7210_DAC_EQ5, 0, 0xf, 1,
- eq_gain_tlv),
-
- /* ADC Equalizer controls */
- SOC_SINGLE("ADC EQ Switch", DA7210_ADC_EQ5, 7, 1, 0),
- SOC_SINGLE_TLV("ADC EQ Master Volume", DA7210_ADC_EQ5, 4, 0x3,
- 1, adc_eq_master_gain_tlv),
- SOC_SINGLE_TLV("ADC EQ1 Volume", DA7210_ADC_EQ1_2, 0, 0xf, 1,
- eq_gain_tlv),
- SOC_SINGLE_TLV("ADC EQ2 Volume", DA7210_ADC_EQ1_2, 4, 0xf, 1,
- eq_gain_tlv),
- SOC_SINGLE_TLV("ADC EQ3 Volume", DA7210_ADC_EQ3_4, 0, 0xf, 1,
- eq_gain_tlv),
- SOC_SINGLE_TLV("ADC EQ4 Volume", DA7210_ADC_EQ3_4, 4, 0xf, 1,
- eq_gain_tlv),
- SOC_SINGLE_TLV("ADC EQ5 Volume", DA7210_ADC_EQ5, 0, 0xf, 1,
- eq_gain_tlv),
-
- SOC_SINGLE("DAC HPF Switch", DA7210_DAC_HPF, 3, 1, 0),
- SOC_ENUM("DAC HPF Cutoff", da7210_dac_hpf_cutoff),
- SOC_SINGLE("DAC Voice Mode Switch", DA7210_DAC_HPF, 7, 1, 0),
- SOC_ENUM("DAC Voice Cutoff", da7210_dac_vf_cutoff),
-
- SOC_SINGLE("ADC HPF Switch", DA7210_ADC_HPF, 3, 1, 0),
- SOC_ENUM("ADC HPF Cutoff", da7210_adc_hpf_cutoff),
- SOC_SINGLE("ADC Voice Mode Switch", DA7210_ADC_HPF, 7, 1, 0),
- SOC_ENUM("ADC Voice Cutoff", da7210_adc_vf_cutoff),
-
- /* Mute controls */
- SOC_DOUBLE_R("Mic Capture Switch", DA7210_MIC_L, DA7210_MIC_R, 3, 1, 0),
- SOC_SINGLE("Aux2 Capture Switch", DA7210_AUX2, 2, 1, 0),
- SOC_DOUBLE("ADC Capture Switch", DA7210_ADC, 2, 6, 1, 0),
- SOC_SINGLE("Digital Soft Mute Switch", DA7210_SOFTMUTE, 7, 1, 0),
- SOC_SINGLE("Digital Soft Mute Rate", DA7210_SOFTMUTE, 0, 0x7, 0),
-
- /* Zero cross controls */
- SOC_DOUBLE("Aux1 ZC Switch", DA7210_ZERO_CROSS, 0, 1, 1, 0),
- SOC_DOUBLE("In PGA ZC Switch", DA7210_ZERO_CROSS, 2, 3, 1, 0),
- SOC_DOUBLE("Lineout ZC Switch", DA7210_ZERO_CROSS, 4, 5, 1, 0),
- SOC_DOUBLE("Headphone ZC Switch", DA7210_ZERO_CROSS, 6, 7, 1, 0),
-
- SOC_ENUM("Headphone Class", da7210_hp_mode_sel),
-
- /* ALC controls */
- SOC_SINGLE_EXT("ALC Enable Switch", DA7210_ADC, 0, 1, 0,
- snd_soc_get_volsw, da7210_put_alc_sw),
- SOC_SINGLE("ALC Capture Max Volume", DA7210_ALC_MAX, 0, 0x3F, 0),
- SOC_SINGLE("ALC Capture Min Volume", DA7210_ALC_MIN, 0, 0x3F, 0),
- SOC_SINGLE("ALC Capture Noise Volume", DA7210_ALC_NOIS, 0, 0x3F, 0),
- SOC_SINGLE("ALC Capture Attack Rate", DA7210_ALC_ATT, 0, 0xFF, 0),
- SOC_SINGLE("ALC Capture Release Rate", DA7210_ALC_REL, 0, 0xFF, 0),
- SOC_SINGLE("ALC Capture Release Delay", DA7210_ALC_DEL, 0, 0xFF, 0),
-
- SOC_SINGLE_EXT("Noise Suppression Enable Switch", DA7210_CONTROL, 3, 1,
- 0, snd_soc_get_volsw, da7210_put_noise_sup_sw),
-};
-
-/*
- * DAPM Controls
- *
- * Current DAPM implementation covers almost all codec components e.g. IOs,
- * mixers, PGAs,ADC and DAC.
- */
-/* In Mixer Left */
-static const struct snd_kcontrol_new da7210_dapm_inmixl_controls[] = {
- SOC_DAPM_SINGLE("Mic Left Switch", DA7210_INMIX_L, 0, 1, 0),
- SOC_DAPM_SINGLE("Mic Right Switch", DA7210_INMIX_L, 1, 1, 0),
- SOC_DAPM_SINGLE("Aux1 Left Switch", DA7210_INMIX_L, 2, 1, 0),
- SOC_DAPM_SINGLE("Aux2 Switch", DA7210_INMIX_L, 3, 1, 0),
- SOC_DAPM_SINGLE("Outmix Left Switch", DA7210_INMIX_L, 4, 1, 0),
-};
-
-/* In Mixer Right */
-static const struct snd_kcontrol_new da7210_dapm_inmixr_controls[] = {
- SOC_DAPM_SINGLE("Mic Right Switch", DA7210_INMIX_R, 0, 1, 0),
- SOC_DAPM_SINGLE("Mic Left Switch", DA7210_INMIX_R, 1, 1, 0),
- SOC_DAPM_SINGLE("Aux1 Right Switch", DA7210_INMIX_R, 2, 1, 0),
- SOC_DAPM_SINGLE("Aux2 Switch", DA7210_INMIX_R, 3, 1, 0),
- SOC_DAPM_SINGLE("Outmix Right Switch", DA7210_INMIX_R, 4, 1, 0),
-};
-
-/* Out Mixer Left */
-static const struct snd_kcontrol_new da7210_dapm_outmixl_controls[] = {
- SOC_DAPM_SINGLE("Aux1 Left Switch", DA7210_OUTMIX_L, 0, 1, 0),
- SOC_DAPM_SINGLE("Aux2 Switch", DA7210_OUTMIX_L, 1, 1, 0),
- SOC_DAPM_SINGLE("INPGA Left Switch", DA7210_OUTMIX_L, 2, 1, 0),
- SOC_DAPM_SINGLE("INPGA Right Switch", DA7210_OUTMIX_L, 3, 1, 0),
- SOC_DAPM_SINGLE("DAC Left Switch", DA7210_OUTMIX_L, 4, 1, 0),
-};
-
-/* Out Mixer Right */
-static const struct snd_kcontrol_new da7210_dapm_outmixr_controls[] = {
- SOC_DAPM_SINGLE("Aux1 Right Switch", DA7210_OUTMIX_R, 0, 1, 0),
- SOC_DAPM_SINGLE("Aux2 Switch", DA7210_OUTMIX_R, 1, 1, 0),
- SOC_DAPM_SINGLE("INPGA Left Switch", DA7210_OUTMIX_R, 2, 1, 0),
- SOC_DAPM_SINGLE("INPGA Right Switch", DA7210_OUTMIX_R, 3, 1, 0),
- SOC_DAPM_SINGLE("DAC Right Switch", DA7210_OUTMIX_R, 4, 1, 0),
-};
-
-/* Mono Mixer */
-static const struct snd_kcontrol_new da7210_dapm_monomix_controls[] = {
- SOC_DAPM_SINGLE("INPGA Right Switch", DA7210_OUT2, 3, 1, 0),
- SOC_DAPM_SINGLE("INPGA Left Switch", DA7210_OUT2, 4, 1, 0),
- SOC_DAPM_SINGLE("Outmix Right Switch", DA7210_OUT2, 5, 1, 0),
- SOC_DAPM_SINGLE("Outmix Left Switch", DA7210_OUT2, 6, 1, 0),
-};
-
-/* DAPM widgets */
-static const struct snd_soc_dapm_widget da7210_dapm_widgets[] = {
- /* Input Side */
- /* Input Lines */
- SND_SOC_DAPM_INPUT("MICL"),
- SND_SOC_DAPM_INPUT("MICR"),
- SND_SOC_DAPM_INPUT("AUX1L"),
- SND_SOC_DAPM_INPUT("AUX1R"),
- SND_SOC_DAPM_INPUT("AUX2"),
-
- /* Input PGAs */
- SND_SOC_DAPM_PGA("Mic Left", DA7210_STARTUP3, 0, 1, NULL, 0),
- SND_SOC_DAPM_PGA("Mic Right", DA7210_STARTUP3, 1, 1, NULL, 0),
- SND_SOC_DAPM_PGA("Aux1 Left", DA7210_STARTUP3, 2, 1, NULL, 0),
- SND_SOC_DAPM_PGA("Aux1 Right", DA7210_STARTUP3, 3, 1, NULL, 0),
- SND_SOC_DAPM_PGA("Aux2 Mono", DA7210_STARTUP3, 4, 1, NULL, 0),
-
- SND_SOC_DAPM_PGA("INPGA Left", DA7210_INMIX_L, 7, 0, NULL, 0),
- SND_SOC_DAPM_PGA("INPGA Right", DA7210_INMIX_R, 7, 0, NULL, 0),
-
- /* MICBIAS */
- SND_SOC_DAPM_SUPPLY("Mic Bias", DA7210_MIC_L, 6, 0, NULL, 0),
-
- /* Input Mixers */
- SND_SOC_DAPM_MIXER("In Mixer Left", SND_SOC_NOPM, 0, 0,
- &da7210_dapm_inmixl_controls[0],
- ARRAY_SIZE(da7210_dapm_inmixl_controls)),
-
- SND_SOC_DAPM_MIXER("In Mixer Right", SND_SOC_NOPM, 0, 0,
- &da7210_dapm_inmixr_controls[0],
- ARRAY_SIZE(da7210_dapm_inmixr_controls)),
-
- /* ADCs */
- SND_SOC_DAPM_ADC("ADC Left", "Capture", DA7210_STARTUP3, 5, 1),
- SND_SOC_DAPM_ADC("ADC Right", "Capture", DA7210_STARTUP3, 6, 1),
-
- /* Output Side */
- /* DACs */
- SND_SOC_DAPM_DAC("DAC Left", "Playback", DA7210_STARTUP2, 5, 1),
- SND_SOC_DAPM_DAC("DAC Right", "Playback", DA7210_STARTUP2, 6, 1),
-
- /* Output Mixers */
- SND_SOC_DAPM_MIXER("Out Mixer Left", SND_SOC_NOPM, 0, 0,
- &da7210_dapm_outmixl_controls[0],
- ARRAY_SIZE(da7210_dapm_outmixl_controls)),
-
- SND_SOC_DAPM_MIXER("Out Mixer Right", SND_SOC_NOPM, 0, 0,
- &da7210_dapm_outmixr_controls[0],
- ARRAY_SIZE(da7210_dapm_outmixr_controls)),
-
- SND_SOC_DAPM_MIXER("Mono Mixer", SND_SOC_NOPM, 0, 0,
- &da7210_dapm_monomix_controls[0],
- ARRAY_SIZE(da7210_dapm_monomix_controls)),
-
- /* Output PGAs */
- SND_SOC_DAPM_PGA("OUTPGA Left Enable", DA7210_OUTMIX_L, 7, 0, NULL, 0),
- SND_SOC_DAPM_PGA("OUTPGA Right Enable", DA7210_OUTMIX_R, 7, 0, NULL, 0),
-
- SND_SOC_DAPM_PGA("Out1 Left", DA7210_STARTUP2, 0, 1, NULL, 0),
- SND_SOC_DAPM_PGA("Out1 Right", DA7210_STARTUP2, 1, 1, NULL, 0),
- SND_SOC_DAPM_PGA("Out2 Mono", DA7210_STARTUP2, 2, 1, NULL, 0),
- SND_SOC_DAPM_PGA("Headphone Left", DA7210_STARTUP2, 3, 1, NULL, 0),
- SND_SOC_DAPM_PGA("Headphone Right", DA7210_STARTUP2, 4, 1, NULL, 0),
-
- /* Output Lines */
- SND_SOC_DAPM_OUTPUT("OUT1L"),
- SND_SOC_DAPM_OUTPUT("OUT1R"),
- SND_SOC_DAPM_OUTPUT("HPL"),
- SND_SOC_DAPM_OUTPUT("HPR"),
- SND_SOC_DAPM_OUTPUT("OUT2"),
-};
-
-/* DAPM audio route definition */
-static const struct snd_soc_dapm_route da7210_audio_map[] = {
- /* Dest Connecting Widget source */
- /* Input path */
- {"Mic Left", NULL, "MICL"},
- {"Mic Right", NULL, "MICR"},
- {"Aux1 Left", NULL, "AUX1L"},
- {"Aux1 Right", NULL, "AUX1R"},
- {"Aux2 Mono", NULL, "AUX2"},
-
- {"In Mixer Left", "Mic Left Switch", "Mic Left"},
- {"In Mixer Left", "Mic Right Switch", "Mic Right"},
- {"In Mixer Left", "Aux1 Left Switch", "Aux1 Left"},
- {"In Mixer Left", "Aux2 Switch", "Aux2 Mono"},
- {"In Mixer Left", "Outmix Left Switch", "Out Mixer Left"},
-
- {"In Mixer Right", "Mic Right Switch", "Mic Right"},
- {"In Mixer Right", "Mic Left Switch", "Mic Left"},
- {"In Mixer Right", "Aux1 Right Switch", "Aux1 Right"},
- {"In Mixer Right", "Aux2 Switch", "Aux2 Mono"},
- {"In Mixer Right", "Outmix Right Switch", "Out Mixer Right"},
-
- {"INPGA Left", NULL, "In Mixer Left"},
- {"ADC Left", NULL, "INPGA Left"},
-
- {"INPGA Right", NULL, "In Mixer Right"},
- {"ADC Right", NULL, "INPGA Right"},
-
- /* Output path */
- {"Out Mixer Left", "Aux1 Left Switch", "Aux1 Left"},
- {"Out Mixer Left", "Aux2 Switch", "Aux2 Mono"},
- {"Out Mixer Left", "INPGA Left Switch", "INPGA Left"},
- {"Out Mixer Left", "INPGA Right Switch", "INPGA Right"},
- {"Out Mixer Left", "DAC Left Switch", "DAC Left"},
-
- {"Out Mixer Right", "Aux1 Right Switch", "Aux1 Right"},
- {"Out Mixer Right", "Aux2 Switch", "Aux2 Mono"},
- {"Out Mixer Right", "INPGA Right Switch", "INPGA Right"},
- {"Out Mixer Right", "INPGA Left Switch", "INPGA Left"},
- {"Out Mixer Right", "DAC Right Switch", "DAC Right"},
-
- {"Mono Mixer", "INPGA Right Switch", "INPGA Right"},
- {"Mono Mixer", "INPGA Left Switch", "INPGA Left"},
- {"Mono Mixer", "Outmix Right Switch", "Out Mixer Right"},
- {"Mono Mixer", "Outmix Left Switch", "Out Mixer Left"},
-
- {"OUTPGA Left Enable", NULL, "Out Mixer Left"},
- {"OUTPGA Right Enable", NULL, "Out Mixer Right"},
-
- {"Out1 Left", NULL, "OUTPGA Left Enable"},
- {"OUT1L", NULL, "Out1 Left"},
-
- {"Out1 Right", NULL, "OUTPGA Right Enable"},
- {"OUT1R", NULL, "Out1 Right"},
-
- {"Headphone Left", NULL, "OUTPGA Left Enable"},
- {"HPL", NULL, "Headphone Left"},
-
- {"Headphone Right", NULL, "OUTPGA Right Enable"},
- {"HPR", NULL, "Headphone Right"},
-
- {"Out2 Mono", NULL, "Mono Mixer"},
- {"OUT2", NULL, "Out2 Mono"},
-};
-
-/* Codec private data */
-struct da7210_priv {
- struct regmap *regmap;
-};
-
-static struct reg_default da7210_reg_defaults[] = {
- { 0x01, 0x11 },
- { 0x03, 0x00 },
- { 0x04, 0x00 },
- { 0x05, 0x00 },
- { 0x06, 0x00 },
- { 0x07, 0x00 },
- { 0x08, 0x00 },
- { 0x09, 0x00 },
- { 0x0a, 0x00 },
- { 0x0b, 0x00 },
- { 0x0c, 0x00 },
- { 0x0d, 0x00 },
- { 0x0e, 0x00 },
- { 0x0f, 0x08 },
- { 0x10, 0x00 },
- { 0x11, 0x00 },
- { 0x12, 0x00 },
- { 0x13, 0x00 },
- { 0x14, 0x08 },
- { 0x15, 0x10 },
- { 0x16, 0x10 },
- { 0x17, 0x54 },
- { 0x18, 0x40 },
- { 0x19, 0x00 },
- { 0x1a, 0x00 },
- { 0x1b, 0x00 },
- { 0x1c, 0x00 },
- { 0x1d, 0x00 },
- { 0x1e, 0x00 },
- { 0x1f, 0x00 },
- { 0x20, 0x00 },
- { 0x21, 0x00 },
- { 0x22, 0x00 },
- { 0x23, 0x02 },
- { 0x24, 0x00 },
- { 0x25, 0x76 },
- { 0x26, 0x00 },
- { 0x27, 0x00 },
- { 0x28, 0x04 },
- { 0x29, 0x00 },
- { 0x2a, 0x00 },
- { 0x2b, 0x30 },
- { 0x2c, 0x2A },
- { 0x83, 0x00 },
- { 0x84, 0x00 },
- { 0x85, 0x00 },
- { 0x86, 0x00 },
- { 0x87, 0x00 },
- { 0x88, 0x00 },
-};
-
-static bool da7210_readable_register(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case DA7210_A_HID_UNLOCK:
- case DA7210_A_TEST_UNLOCK:
- case DA7210_A_PLL1:
- case DA7210_A_CP_MODE:
- return false;
- default:
- return true;
- }
-}
-
-static bool da7210_volatile_register(struct device *dev,
- unsigned int reg)
-{
- switch (reg) {
- case DA7210_STATUS:
- return true;
- default:
- return false;
- }
-}
-
-/*
- * Set PCM DAI word length.
- */
-static int da7210_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- u32 dai_cfg1;
- u32 fs, bypass;
-
- /* set DAI source to Left and Right ADC */
- snd_soc_write(codec, DA7210_DAI_SRC_SEL,
- DA7210_DAI_OUT_R_SRC | DA7210_DAI_OUT_L_SRC);
-
- /* Enable DAI */
- snd_soc_write(codec, DA7210_DAI_CFG3, DA7210_DAI_OE | DA7210_DAI_EN);
-
- dai_cfg1 = 0xFC & snd_soc_read(codec, DA7210_DAI_CFG1);
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- dai_cfg1 |= DA7210_DAI_WORD_S16_LE;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- dai_cfg1 |= DA7210_DAI_WORD_S20_3LE;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- dai_cfg1 |= DA7210_DAI_WORD_S24_LE;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- dai_cfg1 |= DA7210_DAI_WORD_S32_LE;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, DA7210_DAI_CFG1, dai_cfg1);
-
- switch (params_rate(params)) {
- case 8000:
- fs = DA7210_PLL_FS_8000;
- bypass = DA7210_PLL_BYP;
- break;
- case 11025:
- fs = DA7210_PLL_FS_11025;
- bypass = 0;
- break;
- case 12000:
- fs = DA7210_PLL_FS_12000;
- bypass = DA7210_PLL_BYP;
- break;
- case 16000:
- fs = DA7210_PLL_FS_16000;
- bypass = DA7210_PLL_BYP;
- break;
- case 22050:
- fs = DA7210_PLL_FS_22050;
- bypass = 0;
- break;
- case 32000:
- fs = DA7210_PLL_FS_32000;
- bypass = DA7210_PLL_BYP;
- break;
- case 44100:
- fs = DA7210_PLL_FS_44100;
- bypass = 0;
- break;
- case 48000:
- fs = DA7210_PLL_FS_48000;
- bypass = DA7210_PLL_BYP;
- break;
- case 88200:
- fs = DA7210_PLL_FS_88200;
- bypass = 0;
- break;
- case 96000:
- fs = DA7210_PLL_FS_96000;
- bypass = DA7210_PLL_BYP;
- break;
- default:
- return -EINVAL;
- }
-
- /* Disable active mode */
- snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0);
-
- snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_FS_MASK, fs);
- snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP, bypass);
-
- /* Enable active mode */
- snd_soc_update_bits(codec, DA7210_STARTUP1,
- DA7210_SC_MST_EN, DA7210_SC_MST_EN);
-
- return 0;
-}
-
-/*
- * Set DAI mode and Format
- */
-static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u32 dai_cfg1;
- u32 dai_cfg3;
-
- dai_cfg1 = 0x7f & snd_soc_read(codec, DA7210_DAI_CFG1);
- dai_cfg3 = 0xfc & snd_soc_read(codec, DA7210_DAI_CFG3);
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- dai_cfg1 |= DA7210_DAI_MODE_MASTER;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- dai_cfg1 |= DA7210_DAI_MODE_SLAVE;
- break;
- default:
- return -EINVAL;
- }
-
- /* FIXME
- *
- * It support I2S only now
- */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- dai_cfg3 |= DA7210_DAI_FORMAT_I2SMODE;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- dai_cfg3 |= DA7210_DAI_FORMAT_LEFT_J;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- dai_cfg3 |= DA7210_DAI_FORMAT_RIGHT_J;
- break;
- default:
- return -EINVAL;
- }
-
- /* FIXME
- *
- * It support 64bit data transmission only now
- */
- dai_cfg1 |= DA7210_DAI_FLEN_64BIT;
-
- snd_soc_write(codec, DA7210_DAI_CFG1, dai_cfg1);
- snd_soc_write(codec, DA7210_DAI_CFG3, dai_cfg3);
-
- return 0;
-}
-
-static int da7210_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u8 mute_reg = snd_soc_read(codec, DA7210_DAC_HPF) & 0xFB;
-
- if (mute)
- snd_soc_write(codec, DA7210_DAC_HPF, mute_reg | 0x4);
- else
- snd_soc_write(codec, DA7210_DAC_HPF, mute_reg);
- return 0;
-}
-
-#define DA7210_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-/* DAI operations */
-static const struct snd_soc_dai_ops da7210_dai_ops = {
- .hw_params = da7210_hw_params,
- .set_fmt = da7210_set_dai_fmt,
- .digital_mute = da7210_mute,
-};
-
-static struct snd_soc_dai_driver da7210_dai = {
- .name = "da7210-hifi",
- /* playback capabilities */
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = DA7210_FORMATS,
- },
- /* capture capabilities */
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = DA7210_FORMATS,
- },
- .ops = &da7210_dai_ops,
- .symmetric_rates = 1,
-};
-
-static int da7210_probe(struct snd_soc_codec *codec)
-{
- struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
-
- codec->control_data = da7210->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- /* FIXME
- *
- * This driver use fixed value here
- * And below settings expects MCLK = 12.288MHz
- *
- * When you select different MCLK, please check...
- * DA7210_PLL_DIV1 val
- * DA7210_PLL_DIV2 val
- * DA7210_PLL_DIV3 val
- * DA7210_PLL_DIV3 :: DA7210_MCLK_RANGExxx
- */
-
- /*
- * make sure that DA7210 use bypass mode before start up
- */
- snd_soc_write(codec, DA7210_STARTUP1, 0);
- snd_soc_write(codec, DA7210_PLL_DIV3,
- DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
-
- /*
- * ADC settings
- */
-
- /* Enable Left & Right MIC PGA and Mic Bias */
- snd_soc_write(codec, DA7210_MIC_L, DA7210_MIC_L_EN | DA7210_MICBIAS_EN);
- snd_soc_write(codec, DA7210_MIC_R, DA7210_MIC_R_EN);
-
- /* Enable Left and Right input PGA */
- snd_soc_write(codec, DA7210_INMIX_L, DA7210_IN_L_EN);
- snd_soc_write(codec, DA7210_INMIX_R, DA7210_IN_R_EN);
-
- /* Enable Left and Right ADC */
- snd_soc_write(codec, DA7210_ADC, DA7210_ADC_L_EN | DA7210_ADC_R_EN);
-
- /*
- * DAC settings
- */
-
- /* Enable Left and Right DAC */
- snd_soc_write(codec, DA7210_DAC_SEL,
- DA7210_DAC_L_SRC_DAI_L | DA7210_DAC_L_EN |
- DA7210_DAC_R_SRC_DAI_R | DA7210_DAC_R_EN);
-
- /* Enable Left and Right out PGA */
- snd_soc_write(codec, DA7210_OUTMIX_L, DA7210_OUT_L_EN);
- snd_soc_write(codec, DA7210_OUTMIX_R, DA7210_OUT_R_EN);
-
- /* Enable Left and Right HeadPhone PGA */
- snd_soc_write(codec, DA7210_HP_CFG,
- DA7210_HP_2CAP_MODE | DA7210_HP_SENSE_EN |
- DA7210_HP_L_EN | DA7210_HP_MODE | DA7210_HP_R_EN);
-
- /* Enable ramp mode for DAC gain update */
- snd_soc_write(codec, DA7210_SOFTMUTE, DA7210_RAMP_EN);
-
- /*
- * For DA7210 codec, there are two ways to enable/disable analog IOs
- * and ADC/DAC,
- * (1) Using "Enable Bit" of register associated with that IO
- * (or ADC/DAC)
- * e.g. Mic Left can be enabled using bit 7 of MIC_L(0x7) reg
- *
- * (2) Using "Standby Bit" of STARTUP2 or STARTUP3 register
- * e.g. Mic left can be put to STANDBY using bit 0 of STARTUP3(0x5)
- *
- * Out of these two methods, the one using STANDBY bits is preferred
- * way to enable/disable individual blocks. This is because STANDBY
- * registers are part of system controller which allows system power
- * up/down in a controlled, pop-free manner. Also, as per application
- * note of DA7210, STANDBY register bits are only effective if a
- * particular IO (or ADC/DAC) is already enabled using enable/disable
- * register bits. Keeping these things in mind, current DAPM
- * implementation manipulates only STANDBY bits.
- *
- * Overall implementation can be outlined as below,
- *
- * - "Enable bit" of an IO or ADC/DAC is used to enable it in probe()
- * - "STANDBY bit" is controlled by DAPM
- */
-
- /* Enable Line out amplifiers */
- snd_soc_write(codec, DA7210_OUT1_L, DA7210_OUT1_L_EN);
- snd_soc_write(codec, DA7210_OUT1_R, DA7210_OUT1_R_EN);
- snd_soc_write(codec, DA7210_OUT2, DA7210_OUT2_EN |
- DA7210_OUT2_OUTMIX_L | DA7210_OUT2_OUTMIX_R);
-
- /* Enable Aux1 */
- snd_soc_write(codec, DA7210_AUX1_L, DA7210_AUX1_L_EN);
- snd_soc_write(codec, DA7210_AUX1_R, DA7210_AUX1_R_EN);
- /* Enable Aux2 */
- snd_soc_write(codec, DA7210_AUX2, DA7210_AUX2_EN);
-
- /* Diable PLL and bypass it */
- snd_soc_write(codec, DA7210_PLL, DA7210_PLL_FS_48000);
-
- /*
- * If 48kHz sound came, it use bypass mode,
- * and when it is 44.1kHz, it use PLL.
- *
- * This time, this driver sets PLL always ON
- * and controls bypass/PLL mode by switching
- * DA7210_PLL_DIV3 :: DA7210_PLL_BYP bit.
- * see da7210_hw_params
- */
- snd_soc_write(codec, DA7210_PLL_DIV1, 0xE5); /* MCLK = 12.288MHz */
- snd_soc_write(codec, DA7210_PLL_DIV2, 0x99);
- snd_soc_write(codec, DA7210_PLL_DIV3, 0x0A |
- DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
- snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN);
-
- /* As suggested by Dialog */
- /* unlock */
- regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x8B);
- regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0xB4);
- regmap_write(da7210->regmap, DA7210_A_PLL1, 0x01);
- regmap_write(da7210->regmap, DA7210_A_CP_MODE, 0x7C);
- /* re-lock */
- regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x00);
- regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0x00);
-
- /* Activate all enabled subsystem */
- snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
-
- dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
- .probe = da7210_probe,
-
- .controls = da7210_snd_controls,
- .num_controls = ARRAY_SIZE(da7210_snd_controls),
-
- .dapm_widgets = da7210_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(da7210_dapm_widgets),
- .dapm_routes = da7210_audio_map,
- .num_dapm_routes = ARRAY_SIZE(da7210_audio_map),
-};
-
-static struct regmap_config da7210_regmap = {
- .reg_bits = 8,
- .val_bits = 8,
-
- .reg_defaults = da7210_reg_defaults,
- .num_reg_defaults = ARRAY_SIZE(da7210_reg_defaults),
- .volatile_reg = da7210_volatile_register,
- .readable_reg = da7210_readable_register,
- .cache_type = REGCACHE_RBTREE,
-};
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct da7210_priv *da7210;
- int ret;
-
- da7210 = devm_kzalloc(&i2c->dev, sizeof(struct da7210_priv),
- GFP_KERNEL);
- if (!da7210)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, da7210);
-
- da7210->regmap = regmap_init_i2c(i2c, &da7210_regmap);
- if (IS_ERR(da7210->regmap)) {
- ret = PTR_ERR(da7210->regmap);
- dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
- return ret;
- }
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_da7210, &da7210_dai, 1);
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
- goto err_regmap;
- }
- return ret;
-
-err_regmap:
- regmap_exit(da7210->regmap);
-
- return ret;
-}
-
-static int __devexit da7210_i2c_remove(struct i2c_client *client)
-{
- struct da7210_priv *da7210 = i2c_get_clientdata(client);
-
- snd_soc_unregister_codec(&client->dev);
- regmap_exit(da7210->regmap);
- return 0;
-}
-
-static const struct i2c_device_id da7210_i2c_id[] = {
- { "da7210", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, da7210_i2c_id);
-
-/* I2C codec control layer */
-static struct i2c_driver da7210_i2c_driver = {
- .driver = {
- .name = "da7210-codec",
- .owner = THIS_MODULE,
- },
- .probe = da7210_i2c_probe,
- .remove = __devexit_p(da7210_i2c_remove),
- .id_table = da7210_i2c_id,
-};
-#endif
-
-static int __init da7210_modinit(void)
-{
- int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&da7210_i2c_driver);
-#endif
- return ret;
-}
-module_init(da7210_modinit);
-
-static void __exit da7210_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&da7210_i2c_driver);
-#endif
-}
-module_exit(da7210_exit);
-
-MODULE_DESCRIPTION("ASoC DA7210 driver");
-MODULE_AUTHOR("David Chen, Kuninori Morimoto");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/dfbmcs320.c b/ANDROID_3.4.5/sound/soc/codecs/dfbmcs320.c
deleted file mode 100644
index bfe46aa9..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/dfbmcs320.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Driver for the DFBM-CS320 bluetooth module
- * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-
-#include <sound/soc.h>
-
-static struct snd_soc_dai_driver dfbmcs320_dai = {
- .name = "dfbmcs320-pcm",
- .playback = {
- .channels_min = 1,
- .channels_max = 1,
- .rates = SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .capture = {
- .channels_min = 1,
- .channels_max = 1,
- .rates = SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
-};
-
-static struct snd_soc_codec_driver soc_codec_dev_dfbmcs320;
-
-static int __devinit dfbmcs320_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_dfbmcs320,
- &dfbmcs320_dai, 1);
-}
-
-static int __devexit dfbmcs320_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
-
- return 0;
-}
-
-static struct platform_driver dfmcs320_driver = {
- .driver = {
- .name = "dfbmcs320",
- .owner = THIS_MODULE,
- },
- .probe = dfbmcs320_probe,
- .remove = __devexit_p(dfbmcs320_remove),
-};
-
-module_platform_driver(dfmcs320_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("ASoC DFBM-CS320 bluethooth module driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/dmic.c b/ANDROID_3.4.5/sound/soc/codecs/dmic.c
deleted file mode 100644
index 3e929f07..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/dmic.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * dmic.c -- SoC audio for Generic Digital MICs
- *
- * Author: Liam Girdwood <lrg@slimlogic.co.uk>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-
-static struct snd_soc_dai_driver dmic_dai = {
- .name = "dmic-hifi",
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 8,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .formats = SNDRV_PCM_FMTBIT_S32_LE
- | SNDRV_PCM_FMTBIT_S24_LE
- | SNDRV_PCM_FMTBIT_S16_LE,
- },
-};
-
-static const struct snd_soc_dapm_widget dmic_dapm_widgets[] = {
- SND_SOC_DAPM_AIF_OUT("DMIC AIF", "Capture", 0,
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_INPUT("DMic"),
-};
-
-static const struct snd_soc_dapm_route intercon[] = {
- {"DMIC AIF", NULL, "DMic"},
-};
-
-static int dmic_probe(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_new_controls(dapm, dmic_dapm_widgets,
- ARRAY_SIZE(dmic_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
- snd_soc_dapm_new_widgets(dapm);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_dmic = {
- .probe = dmic_probe,
-};
-
-static int __devinit dmic_dev_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev,
- &soc_dmic, &dmic_dai, 1);
-}
-
-static int __devexit dmic_dev_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-MODULE_ALIAS("platform:dmic-codec");
-
-static struct platform_driver dmic_driver = {
- .driver = {
- .name = "dmic-codec",
- .owner = THIS_MODULE,
- },
- .probe = dmic_dev_probe,
- .remove = __devexit_p(dmic_dev_remove),
-};
-
-module_platform_driver(dmic_driver);
-
-MODULE_DESCRIPTION("Generic DMIC driver");
-MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/jz4740.c b/ANDROID_3.4.5/sound/soc/codecs/jz4740.c
deleted file mode 100644
index 4624e752..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/jz4740.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-
-#include <linux/delay.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#define JZ4740_REG_CODEC_1 0x0
-#define JZ4740_REG_CODEC_2 0x1
-
-#define JZ4740_CODEC_1_LINE_ENABLE BIT(29)
-#define JZ4740_CODEC_1_MIC_ENABLE BIT(28)
-#define JZ4740_CODEC_1_SW1_ENABLE BIT(27)
-#define JZ4740_CODEC_1_ADC_ENABLE BIT(26)
-#define JZ4740_CODEC_1_SW2_ENABLE BIT(25)
-#define JZ4740_CODEC_1_DAC_ENABLE BIT(24)
-#define JZ4740_CODEC_1_VREF_DISABLE BIT(20)
-#define JZ4740_CODEC_1_VREF_AMP_DISABLE BIT(19)
-#define JZ4740_CODEC_1_VREF_PULLDOWN BIT(18)
-#define JZ4740_CODEC_1_VREF_LOW_CURRENT BIT(17)
-#define JZ4740_CODEC_1_VREF_HIGH_CURRENT BIT(16)
-#define JZ4740_CODEC_1_HEADPHONE_DISABLE BIT(14)
-#define JZ4740_CODEC_1_HEADPHONE_AMP_CHANGE_ANY BIT(13)
-#define JZ4740_CODEC_1_HEADPHONE_CHARGE BIT(12)
-#define JZ4740_CODEC_1_HEADPHONE_PULLDOWN (BIT(11) | BIT(10))
-#define JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M BIT(9)
-#define JZ4740_CODEC_1_HEADPHONE_POWERDOWN BIT(8)
-#define JZ4740_CODEC_1_SUSPEND BIT(1)
-#define JZ4740_CODEC_1_RESET BIT(0)
-
-#define JZ4740_CODEC_1_LINE_ENABLE_OFFSET 29
-#define JZ4740_CODEC_1_MIC_ENABLE_OFFSET 28
-#define JZ4740_CODEC_1_SW1_ENABLE_OFFSET 27
-#define JZ4740_CODEC_1_ADC_ENABLE_OFFSET 26
-#define JZ4740_CODEC_1_SW2_ENABLE_OFFSET 25
-#define JZ4740_CODEC_1_DAC_ENABLE_OFFSET 24
-#define JZ4740_CODEC_1_HEADPHONE_DISABLE_OFFSET 14
-#define JZ4740_CODEC_1_HEADPHONE_POWERDOWN_OFFSET 8
-
-#define JZ4740_CODEC_2_INPUT_VOLUME_MASK 0x1f0000
-#define JZ4740_CODEC_2_SAMPLE_RATE_MASK 0x000f00
-#define JZ4740_CODEC_2_MIC_BOOST_GAIN_MASK 0x000030
-#define JZ4740_CODEC_2_HEADPHONE_VOLUME_MASK 0x000003
-
-#define JZ4740_CODEC_2_INPUT_VOLUME_OFFSET 16
-#define JZ4740_CODEC_2_SAMPLE_RATE_OFFSET 8
-#define JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET 4
-#define JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET 0
-
-static const uint32_t jz4740_codec_regs[] = {
- 0x021b2302, 0x00170803,
-};
-
-struct jz4740_codec {
- void __iomem *base;
- struct resource *mem;
-};
-
-static unsigned int jz4740_codec_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
- return readl(jz4740_codec->base + (reg << 2));
-}
-
-static int jz4740_codec_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int val)
-{
- struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
- u32 *cache = codec->reg_cache;
-
- cache[reg] = val;
- writel(val, jz4740_codec->base + (reg << 2));
-
- return 0;
-}
-
-static const struct snd_kcontrol_new jz4740_codec_controls[] = {
- SOC_SINGLE("Master Playback Volume", JZ4740_REG_CODEC_2,
- JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET, 3, 0),
- SOC_SINGLE("Master Capture Volume", JZ4740_REG_CODEC_2,
- JZ4740_CODEC_2_INPUT_VOLUME_OFFSET, 31, 0),
- SOC_SINGLE("Master Playback Switch", JZ4740_REG_CODEC_1,
- JZ4740_CODEC_1_HEADPHONE_DISABLE_OFFSET, 1, 1),
- SOC_SINGLE("Mic Capture Volume", JZ4740_REG_CODEC_2,
- JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET, 3, 0),
-};
-
-static const struct snd_kcontrol_new jz4740_codec_output_controls[] = {
- SOC_DAPM_SINGLE("Bypass Switch", JZ4740_REG_CODEC_1,
- JZ4740_CODEC_1_SW1_ENABLE_OFFSET, 1, 0),
- SOC_DAPM_SINGLE("DAC Switch", JZ4740_REG_CODEC_1,
- JZ4740_CODEC_1_SW2_ENABLE_OFFSET, 1, 0),
-};
-
-static const struct snd_kcontrol_new jz4740_codec_input_controls[] = {
- SOC_DAPM_SINGLE("Line Capture Switch", JZ4740_REG_CODEC_1,
- JZ4740_CODEC_1_LINE_ENABLE_OFFSET, 1, 0),
- SOC_DAPM_SINGLE("Mic Capture Switch", JZ4740_REG_CODEC_1,
- JZ4740_CODEC_1_MIC_ENABLE_OFFSET, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget jz4740_codec_dapm_widgets[] = {
- SND_SOC_DAPM_ADC("ADC", "Capture", JZ4740_REG_CODEC_1,
- JZ4740_CODEC_1_ADC_ENABLE_OFFSET, 0),
- SND_SOC_DAPM_DAC("DAC", "Playback", JZ4740_REG_CODEC_1,
- JZ4740_CODEC_1_DAC_ENABLE_OFFSET, 0),
-
- SND_SOC_DAPM_MIXER("Output Mixer", JZ4740_REG_CODEC_1,
- JZ4740_CODEC_1_HEADPHONE_POWERDOWN_OFFSET, 1,
- jz4740_codec_output_controls,
- ARRAY_SIZE(jz4740_codec_output_controls)),
-
- SND_SOC_DAPM_MIXER_NAMED_CTL("Input Mixer", SND_SOC_NOPM, 0, 0,
- jz4740_codec_input_controls,
- ARRAY_SIZE(jz4740_codec_input_controls)),
- SND_SOC_DAPM_MIXER("Line Input", SND_SOC_NOPM, 0, 0, NULL, 0),
-
- SND_SOC_DAPM_OUTPUT("LOUT"),
- SND_SOC_DAPM_OUTPUT("ROUT"),
-
- SND_SOC_DAPM_INPUT("MIC"),
- SND_SOC_DAPM_INPUT("LIN"),
- SND_SOC_DAPM_INPUT("RIN"),
-};
-
-static const struct snd_soc_dapm_route jz4740_codec_dapm_routes[] = {
- {"Line Input", NULL, "LIN"},
- {"Line Input", NULL, "RIN"},
-
- {"Input Mixer", "Line Capture Switch", "Line Input"},
- {"Input Mixer", "Mic Capture Switch", "MIC"},
-
- {"ADC", NULL, "Input Mixer"},
-
- {"Output Mixer", "Bypass Switch", "Input Mixer"},
- {"Output Mixer", "DAC Switch", "DAC"},
-
- {"LOUT", NULL, "Output Mixer"},
- {"ROUT", NULL, "Output Mixer"},
-};
-
-static int jz4740_codec_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
-{
- uint32_t val;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec =rtd->codec;
-
- switch (params_rate(params)) {
- case 8000:
- val = 0;
- break;
- case 11025:
- val = 1;
- break;
- case 12000:
- val = 2;
- break;
- case 16000:
- val = 3;
- break;
- case 22050:
- val = 4;
- break;
- case 24000:
- val = 5;
- break;
- case 32000:
- val = 6;
- break;
- case 44100:
- val = 7;
- break;
- case 48000:
- val = 8;
- break;
- default:
- return -EINVAL;
- }
-
- val <<= JZ4740_CODEC_2_SAMPLE_RATE_OFFSET;
-
- snd_soc_update_bits(codec, JZ4740_REG_CODEC_2,
- JZ4740_CODEC_2_SAMPLE_RATE_MASK, val);
-
- return 0;
-}
-
-static const struct snd_soc_dai_ops jz4740_codec_dai_ops = {
- .hw_params = jz4740_codec_hw_params,
-};
-
-static struct snd_soc_dai_driver jz4740_codec_dai = {
- .name = "jz4740-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8,
- },
- .ops = &jz4740_codec_dai_ops,
- .symmetric_rates = 1,
-};
-
-static void jz4740_codec_wakeup(struct snd_soc_codec *codec)
-{
- int i;
- uint32_t *cache = codec->reg_cache;
-
- snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
- JZ4740_CODEC_1_RESET, JZ4740_CODEC_1_RESET);
- udelay(2);
-
- snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
- JZ4740_CODEC_1_SUSPEND | JZ4740_CODEC_1_RESET, 0);
-
- for (i = 0; i < ARRAY_SIZE(jz4740_codec_regs); ++i)
- jz4740_codec_write(codec, i, cache[i]);
-}
-
-static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- unsigned int mask;
- unsigned int value;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
- case SND_SOC_BIAS_PREPARE:
- mask = JZ4740_CODEC_1_VREF_DISABLE |
- JZ4740_CODEC_1_VREF_AMP_DISABLE |
- JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M;
- value = 0;
-
- snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value);
- break;
- case SND_SOC_BIAS_STANDBY:
- /* The only way to clear the suspend flag is to reset the codec */
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
- jz4740_codec_wakeup(codec);
-
- mask = JZ4740_CODEC_1_VREF_DISABLE |
- JZ4740_CODEC_1_VREF_AMP_DISABLE |
- JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M;
- value = JZ4740_CODEC_1_VREF_DISABLE |
- JZ4740_CODEC_1_VREF_AMP_DISABLE |
- JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M;
-
- snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value);
- break;
- case SND_SOC_BIAS_OFF:
- mask = JZ4740_CODEC_1_SUSPEND;
- value = JZ4740_CODEC_1_SUSPEND;
-
- snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value);
- break;
- default:
- break;
- }
-
- codec->dapm.bias_level = level;
-
- return 0;
-}
-
-static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
-{
- snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
- JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
-
- jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-
-static int jz4740_codec_dev_remove(struct snd_soc_codec *codec)
-{
- jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-
-static int jz4740_codec_suspend(struct snd_soc_codec *codec)
-{
- return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
-}
-
-static int jz4740_codec_resume(struct snd_soc_codec *codec)
-{
- return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-}
-
-#else
-#define jz4740_codec_suspend NULL
-#define jz4740_codec_resume NULL
-#endif
-
-static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = {
- .probe = jz4740_codec_dev_probe,
- .remove = jz4740_codec_dev_remove,
- .suspend = jz4740_codec_suspend,
- .resume = jz4740_codec_resume,
- .read = jz4740_codec_read,
- .write = jz4740_codec_write,
- .set_bias_level = jz4740_codec_set_bias_level,
- .reg_cache_default = jz4740_codec_regs,
- .reg_word_size = sizeof(u32),
- .reg_cache_size = 2,
-
- .controls = jz4740_codec_controls,
- .num_controls = ARRAY_SIZE(jz4740_codec_controls),
- .dapm_widgets = jz4740_codec_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(jz4740_codec_dapm_widgets),
- .dapm_routes = jz4740_codec_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(jz4740_codec_dapm_routes),
-};
-
-static int __devinit jz4740_codec_probe(struct platform_device *pdev)
-{
- int ret;
- struct jz4740_codec *jz4740_codec;
- struct resource *mem;
-
- jz4740_codec = devm_kzalloc(&pdev->dev, sizeof(*jz4740_codec),
- GFP_KERNEL);
- if (!jz4740_codec)
- return -ENOMEM;
-
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem) {
- dev_err(&pdev->dev, "Failed to get mmio memory resource\n");
- ret = -ENOENT;
- goto err_out;
- }
-
- mem = request_mem_region(mem->start, resource_size(mem), pdev->name);
- if (!mem) {
- dev_err(&pdev->dev, "Failed to request mmio memory region\n");
- ret = -EBUSY;
- goto err_out;
- }
-
- jz4740_codec->base = ioremap(mem->start, resource_size(mem));
- if (!jz4740_codec->base) {
- dev_err(&pdev->dev, "Failed to ioremap mmio memory\n");
- ret = -EBUSY;
- goto err_release_mem_region;
- }
- jz4740_codec->mem = mem;
-
- platform_set_drvdata(pdev, jz4740_codec);
-
- ret = snd_soc_register_codec(&pdev->dev,
- &soc_codec_dev_jz4740_codec, &jz4740_codec_dai, 1);
- if (ret) {
- dev_err(&pdev->dev, "Failed to register codec\n");
- goto err_iounmap;
- }
-
- return 0;
-
-err_iounmap:
- iounmap(jz4740_codec->base);
-err_release_mem_region:
- release_mem_region(mem->start, resource_size(mem));
-err_out:
- return ret;
-}
-
-static int __devexit jz4740_codec_remove(struct platform_device *pdev)
-{
- struct jz4740_codec *jz4740_codec = platform_get_drvdata(pdev);
- struct resource *mem = jz4740_codec->mem;
-
- snd_soc_unregister_codec(&pdev->dev);
-
- iounmap(jz4740_codec->base);
- release_mem_region(mem->start, resource_size(mem));
-
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-static struct platform_driver jz4740_codec_driver = {
- .probe = jz4740_codec_probe,
- .remove = __devexit_p(jz4740_codec_remove),
- .driver = {
- .name = "jz4740-codec",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(jz4740_codec_driver);
-
-MODULE_DESCRIPTION("JZ4740 SoC internal codec driver");
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:jz4740-codec");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/l3.c b/ANDROID_3.4.5/sound/soc/codecs/l3.c
deleted file mode 100644
index 5353af58..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/l3.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * L3 code
- *
- * Copyright (C) 2008, Christian Pellegrin <chripell@evolware.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *
- * based on:
- *
- * L3 bus algorithm module.
- *
- * Copyright (C) 2001 Russell King, All Rights Reserved.
- *
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-
-#include <sound/l3.h>
-
-/*
- * Send one byte of data to the chip. Data is latched into the chip on
- * the rising edge of the clock.
- */
-static void sendbyte(struct l3_pins *adap, unsigned int byte)
-{
- int i;
-
- for (i = 0; i < 8; i++) {
- adap->setclk(0);
- udelay(adap->data_hold);
- adap->setdat(byte & 1);
- udelay(adap->data_setup);
- adap->setclk(1);
- udelay(adap->clock_high);
- byte >>= 1;
- }
-}
-
-/*
- * Send a set of bytes to the chip. We need to pulse the MODE line
- * between each byte, but never at the start nor at the end of the
- * transfer.
- */
-static void sendbytes(struct l3_pins *adap, const u8 *buf,
- int len)
-{
- int i;
-
- for (i = 0; i < len; i++) {
- if (i) {
- udelay(adap->mode_hold);
- adap->setmode(0);
- udelay(adap->mode);
- }
- adap->setmode(1);
- udelay(adap->mode_setup);
- sendbyte(adap, buf[i]);
- }
-}
-
-int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len)
-{
- adap->setclk(1);
- adap->setdat(1);
- adap->setmode(1);
- udelay(adap->mode);
-
- adap->setmode(0);
- udelay(adap->mode_setup);
- sendbyte(adap, addr);
- udelay(adap->mode_hold);
-
- sendbytes(adap, data, len);
-
- adap->setclk(1);
- adap->setdat(1);
- adap->setmode(0);
-
- return len;
-}
-EXPORT_SYMBOL_GPL(l3_write);
-
-MODULE_DESCRIPTION("L3 bit-banging driver");
-MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/lm4857.c b/ANDROID_3.4.5/sound/soc/codecs/lm4857.c
deleted file mode 100644
index ba4fafb9..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/lm4857.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * LM4857 AMP driver
- *
- * Copyright 2007 Wolfson Microelectronics PLC.
- * Author: Graeme Gregory
- * graeme.gregory@wolfsonmicro.com
- * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-
-#include <sound/core.h>
-#include <sound/soc.h>
-#include <sound/tlv.h>
-
-struct lm4857 {
- struct i2c_client *i2c;
- uint8_t mode;
-};
-
-static const uint8_t lm4857_default_regs[] = {
- 0x00, 0x00, 0x00, 0x00,
-};
-
-/* The register offsets in the cache array */
-#define LM4857_MVOL 0
-#define LM4857_LVOL 1
-#define LM4857_RVOL 2
-#define LM4857_CTRL 3
-
-/* the shifts required to set these bits */
-#define LM4857_3D 5
-#define LM4857_WAKEUP 5
-#define LM4857_EPGAIN 4
-
-static int lm4857_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- uint8_t data;
- int ret;
-
- ret = snd_soc_cache_write(codec, reg, value);
- if (ret < 0)
- return ret;
-
- data = (reg << 6) | value;
- ret = i2c_master_send(codec->control_data, &data, 1);
- if (ret != 1) {
- dev_err(codec->dev, "Failed to write register: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-static unsigned int lm4857_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- unsigned int val;
- int ret;
-
- ret = snd_soc_cache_read(codec, reg, &val);
- if (ret)
- return -1;
-
- return val;
-}
-
-static int lm4857_get_mode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.integer.value[0] = lm4857->mode;
-
- return 0;
-}
-
-static int lm4857_set_mode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
- uint8_t value = ucontrol->value.integer.value[0];
-
- lm4857->mode = value;
-
- if (codec->dapm.bias_level == SND_SOC_BIAS_ON)
- snd_soc_update_bits(codec, LM4857_CTRL, 0x0F, value + 6);
-
- return 1;
-}
-
-static int lm4857_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- snd_soc_update_bits(codec, LM4857_CTRL, 0x0F, lm4857->mode + 6);
- break;
- case SND_SOC_BIAS_STANDBY:
- snd_soc_update_bits(codec, LM4857_CTRL, 0x0F, 0);
- break;
- default:
- break;
- }
-
- codec->dapm.bias_level = level;
-
- return 0;
-}
-
-static const char *lm4857_mode[] = {
- "Earpiece",
- "Loudspeaker",
- "Loudspeaker + Headphone",
- "Headphone",
-};
-
-static const struct soc_enum lm4857_mode_enum =
- SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lm4857_mode), lm4857_mode);
-
-static const struct snd_soc_dapm_widget lm4857_dapm_widgets[] = {
- SND_SOC_DAPM_INPUT("IN"),
-
- SND_SOC_DAPM_OUTPUT("LS"),
- SND_SOC_DAPM_OUTPUT("HP"),
- SND_SOC_DAPM_OUTPUT("EP"),
-};
-
-static const DECLARE_TLV_DB_SCALE(stereo_tlv, -4050, 150, 0);
-static const DECLARE_TLV_DB_SCALE(mono_tlv, -3450, 150, 0);
-
-static const struct snd_kcontrol_new lm4857_controls[] = {
- SOC_SINGLE_TLV("Left Playback Volume", LM4857_LVOL, 0, 31, 0,
- stereo_tlv),
- SOC_SINGLE_TLV("Right Playback Volume", LM4857_RVOL, 0, 31, 0,
- stereo_tlv),
- SOC_SINGLE_TLV("Mono Playback Volume", LM4857_MVOL, 0, 31, 0,
- mono_tlv),
- SOC_SINGLE("Spk 3D Playback Switch", LM4857_LVOL, LM4857_3D, 1, 0),
- SOC_SINGLE("HP 3D Playback Switch", LM4857_RVOL, LM4857_3D, 1, 0),
- SOC_SINGLE("Fast Wakeup Playback Switch", LM4857_CTRL,
- LM4857_WAKEUP, 1, 0),
- SOC_SINGLE("Earpiece 6dB Playback Switch", LM4857_CTRL,
- LM4857_EPGAIN, 1, 0),
-
- SOC_ENUM_EXT("Mode", lm4857_mode_enum,
- lm4857_get_mode, lm4857_set_mode),
-};
-
-/* There is a demux between the input signal and the output signals.
- * Currently there is no easy way to model it in ASoC and since it does not make
- * much of a difference in practice simply connect the input direclty to the
- * outputs. */
-static const struct snd_soc_dapm_route lm4857_routes[] = {
- {"LS", NULL, "IN"},
- {"HP", NULL, "IN"},
- {"EP", NULL, "IN"},
-};
-
-static int lm4857_probe(struct snd_soc_codec *codec)
-{
- struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret;
-
- codec->control_data = lm4857->i2c;
-
- ret = snd_soc_add_codec_controls(codec, lm4857_controls,
- ARRAY_SIZE(lm4857_controls));
- if (ret)
- return ret;
-
- ret = snd_soc_dapm_new_controls(dapm, lm4857_dapm_widgets,
- ARRAY_SIZE(lm4857_dapm_widgets));
- if (ret)
- return ret;
-
- ret = snd_soc_dapm_add_routes(dapm, lm4857_routes,
- ARRAY_SIZE(lm4857_routes));
- if (ret)
- return ret;
-
- snd_soc_dapm_new_widgets(dapm);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_lm4857 = {
- .write = lm4857_write,
- .read = lm4857_read,
- .probe = lm4857_probe,
- .reg_cache_size = ARRAY_SIZE(lm4857_default_regs),
- .reg_word_size = sizeof(uint8_t),
- .reg_cache_default = lm4857_default_regs,
- .set_bias_level = lm4857_set_bias_level,
-};
-
-static int __devinit lm4857_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct lm4857 *lm4857;
- int ret;
-
- lm4857 = devm_kzalloc(&i2c->dev, sizeof(*lm4857), GFP_KERNEL);
- if (!lm4857)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, lm4857);
-
- lm4857->i2c = i2c;
-
- ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_lm4857, NULL, 0);
-
- return ret;
-}
-
-static int __devexit lm4857_i2c_remove(struct i2c_client *i2c)
-{
- snd_soc_unregister_codec(&i2c->dev);
- return 0;
-}
-
-static const struct i2c_device_id lm4857_i2c_id[] = {
- { "lm4857", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, lm4857_i2c_id);
-
-static struct i2c_driver lm4857_i2c_driver = {
- .driver = {
- .name = "lm4857",
- .owner = THIS_MODULE,
- },
- .probe = lm4857_i2c_probe,
- .remove = __devexit_p(lm4857_i2c_remove),
- .id_table = lm4857_i2c_id,
-};
-
-static int __init lm4857_init(void)
-{
- return i2c_add_driver(&lm4857_i2c_driver);
-}
-module_init(lm4857_init);
-
-static void __exit lm4857_exit(void)
-{
- i2c_del_driver(&lm4857_i2c_driver);
-}
-module_exit(lm4857_exit);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("LM4857 amplifier driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/max9768.c b/ANDROID_3.4.5/sound/soc/codecs/max9768.c
deleted file mode 100644
index 17b3ec2d..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/max9768.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * MAX9768 AMP driver
- *
- * Copyright (C) 2011, 2012 by Wolfram Sang, Pengutronix e.K.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; version 2 of the License.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/gpio.h>
-#include <linux/regmap.h>
-
-#include <sound/core.h>
-#include <sound/soc.h>
-#include <sound/tlv.h>
-#include <sound/max9768.h>
-
-/* "Registers" */
-#define MAX9768_VOL 0
-#define MAX9768_CTRL 3
-
-/* Commands */
-#define MAX9768_CTRL_PWM 0x15
-#define MAX9768_CTRL_FILTERLESS 0x16
-
-struct max9768 {
- struct regmap *regmap;
- int mute_gpio;
- int shdn_gpio;
- u32 flags;
-};
-
-static struct reg_default max9768_default_regs[] = {
- { 0, 0 },
- { 3, MAX9768_CTRL_FILTERLESS},
-};
-
-static int max9768_get_gpio(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
- int val = gpio_get_value_cansleep(max9768->mute_gpio);
-
- ucontrol->value.integer.value[0] = !val;
-
- return 0;
-}
-
-static int max9768_set_gpio(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
-
- gpio_set_value_cansleep(max9768->mute_gpio, !ucontrol->value.integer.value[0]);
-
- return 0;
-}
-
-static const unsigned int volume_tlv[] = {
- TLV_DB_RANGE_HEAD(43),
- 0, 0, TLV_DB_SCALE_ITEM(-16150, 0, 0),
- 1, 1, TLV_DB_SCALE_ITEM(-9280, 0, 0),
- 2, 2, TLV_DB_SCALE_ITEM(-9030, 0, 0),
- 3, 3, TLV_DB_SCALE_ITEM(-8680, 0, 0),
- 4, 4, TLV_DB_SCALE_ITEM(-8430, 0, 0),
- 5, 5, TLV_DB_SCALE_ITEM(-8080, 0, 0),
- 6, 6, TLV_DB_SCALE_ITEM(-7830, 0, 0),
- 7, 7, TLV_DB_SCALE_ITEM(-7470, 0, 0),
- 8, 8, TLV_DB_SCALE_ITEM(-7220, 0, 0),
- 9, 9, TLV_DB_SCALE_ITEM(-6870, 0, 0),
- 10, 10, TLV_DB_SCALE_ITEM(-6620, 0, 0),
- 11, 11, TLV_DB_SCALE_ITEM(-6270, 0, 0),
- 12, 12, TLV_DB_SCALE_ITEM(-6020, 0, 0),
- 13, 13, TLV_DB_SCALE_ITEM(-5670, 0, 0),
- 14, 14, TLV_DB_SCALE_ITEM(-5420, 0, 0),
- 15, 17, TLV_DB_SCALE_ITEM(-5060, 250, 0),
- 18, 18, TLV_DB_SCALE_ITEM(-4370, 0, 0),
- 19, 19, TLV_DB_SCALE_ITEM(-4210, 0, 0),
- 20, 20, TLV_DB_SCALE_ITEM(-3960, 0, 0),
- 21, 21, TLV_DB_SCALE_ITEM(-3760, 0, 0),
- 22, 22, TLV_DB_SCALE_ITEM(-3600, 0, 0),
- 23, 23, TLV_DB_SCALE_ITEM(-3340, 0, 0),
- 24, 24, TLV_DB_SCALE_ITEM(-3150, 0, 0),
- 25, 25, TLV_DB_SCALE_ITEM(-2980, 0, 0),
- 26, 26, TLV_DB_SCALE_ITEM(-2720, 0, 0),
- 27, 27, TLV_DB_SCALE_ITEM(-2520, 0, 0),
- 28, 30, TLV_DB_SCALE_ITEM(-2350, 190, 0),
- 31, 31, TLV_DB_SCALE_ITEM(-1750, 0, 0),
- 32, 34, TLV_DB_SCALE_ITEM(-1640, 100, 0),
- 35, 37, TLV_DB_SCALE_ITEM(-1310, 110, 0),
- 38, 39, TLV_DB_SCALE_ITEM(-990, 100, 0),
- 40, 40, TLV_DB_SCALE_ITEM(-710, 0, 0),
- 41, 41, TLV_DB_SCALE_ITEM(-600, 0, 0),
- 42, 42, TLV_DB_SCALE_ITEM(-500, 0, 0),
- 43, 43, TLV_DB_SCALE_ITEM(-340, 0, 0),
- 44, 44, TLV_DB_SCALE_ITEM(-190, 0, 0),
- 45, 45, TLV_DB_SCALE_ITEM(-50, 0, 0),
- 46, 46, TLV_DB_SCALE_ITEM(50, 0, 0),
- 47, 50, TLV_DB_SCALE_ITEM(120, 40, 0),
- 51, 57, TLV_DB_SCALE_ITEM(290, 50, 0),
- 58, 58, TLV_DB_SCALE_ITEM(650, 0, 0),
- 59, 62, TLV_DB_SCALE_ITEM(700, 60, 0),
- 63, 63, TLV_DB_SCALE_ITEM(950, 0, 0),
-};
-
-static const struct snd_kcontrol_new max9768_volume[] = {
- SOC_SINGLE_TLV("Playback Volume", MAX9768_VOL, 0, 63, 0, volume_tlv),
-};
-
-static const struct snd_kcontrol_new max9768_mute[] = {
- SOC_SINGLE_BOOL_EXT("Playback Switch", 0, max9768_get_gpio, max9768_set_gpio),
-};
-
-static int max9768_probe(struct snd_soc_codec *codec)
-{
- struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- codec->control_data = max9768->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 2, 6, SND_SOC_REGMAP);
- if (ret)
- return ret;
-
- if (max9768->flags & MAX9768_FLAG_CLASSIC_PWM) {
- ret = snd_soc_write(codec, MAX9768_CTRL, MAX9768_CTRL_PWM);
- if (ret)
- return ret;
- }
-
- if (gpio_is_valid(max9768->mute_gpio)) {
- ret = snd_soc_add_codec_controls(codec, max9768_mute,
- ARRAY_SIZE(max9768_mute));
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_soc_codec_driver max9768_codec_driver = {
- .probe = max9768_probe,
- .controls = max9768_volume,
- .num_controls = ARRAY_SIZE(max9768_volume),
-};
-
-static const struct regmap_config max9768_i2c_regmap_config = {
- .reg_bits = 2,
- .val_bits = 6,
- .max_register = 3,
- .reg_defaults = max9768_default_regs,
- .num_reg_defaults = ARRAY_SIZE(max9768_default_regs),
- .cache_type = REGCACHE_RBTREE,
-};
-
-static int __devinit max9768_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct max9768 *max9768;
- struct max9768_pdata *pdata = client->dev.platform_data;
- int err;
-
- max9768 = devm_kzalloc(&client->dev, sizeof(*max9768), GFP_KERNEL);
- if (!max9768)
- return -ENOMEM;
-
- if (pdata) {
- /* Mute on powerup to avoid clicks */
- err = gpio_request_one(pdata->mute_gpio, GPIOF_INIT_HIGH, "MAX9768 Mute");
- max9768->mute_gpio = err ?: pdata->mute_gpio;
-
- /* Activate chip by releasing shutdown, enables I2C */
- err = gpio_request_one(pdata->shdn_gpio, GPIOF_INIT_HIGH, "MAX9768 Shutdown");
- max9768->shdn_gpio = err ?: pdata->shdn_gpio;
-
- max9768->flags = pdata->flags;
- } else {
- max9768->shdn_gpio = -EINVAL;
- max9768->mute_gpio = -EINVAL;
- }
-
- i2c_set_clientdata(client, max9768);
-
- max9768->regmap = regmap_init_i2c(client, &max9768_i2c_regmap_config);
- if (IS_ERR(max9768->regmap)) {
- err = PTR_ERR(max9768->regmap);
- goto err_gpio_free;
- }
-
- err = snd_soc_register_codec(&client->dev, &max9768_codec_driver, NULL, 0);
- if (err)
- goto err_regmap_free;
-
- return 0;
-
- err_regmap_free:
- regmap_exit(max9768->regmap);
- err_gpio_free:
- if (gpio_is_valid(max9768->shdn_gpio))
- gpio_free(max9768->shdn_gpio);
- if (gpio_is_valid(max9768->mute_gpio))
- gpio_free(max9768->mute_gpio);
-
- return err;
-}
-
-static int __devexit max9768_i2c_remove(struct i2c_client *client)
-{
- struct max9768 *max9768 = i2c_get_clientdata(client);
-
- snd_soc_unregister_codec(&client->dev);
- regmap_exit(max9768->regmap);
-
- if (gpio_is_valid(max9768->shdn_gpio))
- gpio_free(max9768->shdn_gpio);
- if (gpio_is_valid(max9768->mute_gpio))
- gpio_free(max9768->mute_gpio);
-
- return 0;
-}
-
-static const struct i2c_device_id max9768_i2c_id[] = {
- { "max9768", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, max9768_i2c_id);
-
-static struct i2c_driver max9768_i2c_driver = {
- .driver = {
- .name = "max9768",
- .owner = THIS_MODULE,
- },
- .probe = max9768_i2c_probe,
- .remove = __devexit_p(max9768_i2c_remove),
- .id_table = max9768_i2c_id,
-};
-module_i2c_driver(max9768_i2c_driver);
-
-MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
-MODULE_DESCRIPTION("ASoC MAX9768 amplifier driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/max98088.c b/ANDROID_3.4.5/sound/soc/codecs/max98088.c
deleted file mode 100644
index af7324b7..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/max98088.c
+++ /dev/null
@@ -1,2130 +0,0 @@
-/*
- * max98088.c -- MAX98088 ALSA SoC Audio driver
- *
- * Copyright 2010 Maxim Integrated Products
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <linux/slab.h>
-#include <asm/div64.h>
-#include <sound/max98088.h>
-#include "max98088.h"
-
-enum max98088_type {
- MAX98088,
- MAX98089,
-};
-
-struct max98088_cdata {
- unsigned int rate;
- unsigned int fmt;
- int eq_sel;
-};
-
-struct max98088_priv {
- enum max98088_type devtype;
- struct max98088_pdata *pdata;
- unsigned int sysclk;
- struct max98088_cdata dai[2];
- int eq_textcnt;
- const char **eq_texts;
- struct soc_enum eq_enum;
- u8 ina_state;
- u8 inb_state;
- unsigned int ex_mode;
- unsigned int digmic;
- unsigned int mic1pre;
- unsigned int mic2pre;
- unsigned int extmic_mode;
-};
-
-static const u8 max98088_reg[M98088_REG_CNT] = {
- 0x00, /* 00 IRQ status */
- 0x00, /* 01 MIC status */
- 0x00, /* 02 jack status */
- 0x00, /* 03 battery voltage */
- 0x00, /* 04 */
- 0x00, /* 05 */
- 0x00, /* 06 */
- 0x00, /* 07 */
- 0x00, /* 08 */
- 0x00, /* 09 */
- 0x00, /* 0A */
- 0x00, /* 0B */
- 0x00, /* 0C */
- 0x00, /* 0D */
- 0x00, /* 0E */
- 0x00, /* 0F interrupt enable */
-
- 0x00, /* 10 master clock */
- 0x00, /* 11 DAI1 clock mode */
- 0x00, /* 12 DAI1 clock control */
- 0x00, /* 13 DAI1 clock control */
- 0x00, /* 14 DAI1 format */
- 0x00, /* 15 DAI1 clock */
- 0x00, /* 16 DAI1 config */
- 0x00, /* 17 DAI1 TDM */
- 0x00, /* 18 DAI1 filters */
- 0x00, /* 19 DAI2 clock mode */
- 0x00, /* 1A DAI2 clock control */
- 0x00, /* 1B DAI2 clock control */
- 0x00, /* 1C DAI2 format */
- 0x00, /* 1D DAI2 clock */
- 0x00, /* 1E DAI2 config */
- 0x00, /* 1F DAI2 TDM */
-
- 0x00, /* 20 DAI2 filters */
- 0x00, /* 21 data config */
- 0x00, /* 22 DAC mixer */
- 0x00, /* 23 left ADC mixer */
- 0x00, /* 24 right ADC mixer */
- 0x00, /* 25 left HP mixer */
- 0x00, /* 26 right HP mixer */
- 0x00, /* 27 HP control */
- 0x00, /* 28 left REC mixer */
- 0x00, /* 29 right REC mixer */
- 0x00, /* 2A REC control */
- 0x00, /* 2B left SPK mixer */
- 0x00, /* 2C right SPK mixer */
- 0x00, /* 2D SPK control */
- 0x00, /* 2E sidetone */
- 0x00, /* 2F DAI1 playback level */
-
- 0x00, /* 30 DAI1 playback level */
- 0x00, /* 31 DAI2 playback level */
- 0x00, /* 32 DAI2 playbakc level */
- 0x00, /* 33 left ADC level */
- 0x00, /* 34 right ADC level */
- 0x00, /* 35 MIC1 level */
- 0x00, /* 36 MIC2 level */
- 0x00, /* 37 INA level */
- 0x00, /* 38 INB level */
- 0x00, /* 39 left HP volume */
- 0x00, /* 3A right HP volume */
- 0x00, /* 3B left REC volume */
- 0x00, /* 3C right REC volume */
- 0x00, /* 3D left SPK volume */
- 0x00, /* 3E right SPK volume */
- 0x00, /* 3F MIC config */
-
- 0x00, /* 40 MIC threshold */
- 0x00, /* 41 excursion limiter filter */
- 0x00, /* 42 excursion limiter threshold */
- 0x00, /* 43 ALC */
- 0x00, /* 44 power limiter threshold */
- 0x00, /* 45 power limiter config */
- 0x00, /* 46 distortion limiter config */
- 0x00, /* 47 audio input */
- 0x00, /* 48 microphone */
- 0x00, /* 49 level control */
- 0x00, /* 4A bypass switches */
- 0x00, /* 4B jack detect */
- 0x00, /* 4C input enable */
- 0x00, /* 4D output enable */
- 0xF0, /* 4E bias control */
- 0x00, /* 4F DAC power */
-
- 0x0F, /* 50 DAC power */
- 0x00, /* 51 system */
- 0x00, /* 52 DAI1 EQ1 */
- 0x00, /* 53 DAI1 EQ1 */
- 0x00, /* 54 DAI1 EQ1 */
- 0x00, /* 55 DAI1 EQ1 */
- 0x00, /* 56 DAI1 EQ1 */
- 0x00, /* 57 DAI1 EQ1 */
- 0x00, /* 58 DAI1 EQ1 */
- 0x00, /* 59 DAI1 EQ1 */
- 0x00, /* 5A DAI1 EQ1 */
- 0x00, /* 5B DAI1 EQ1 */
- 0x00, /* 5C DAI1 EQ2 */
- 0x00, /* 5D DAI1 EQ2 */
- 0x00, /* 5E DAI1 EQ2 */
- 0x00, /* 5F DAI1 EQ2 */
-
- 0x00, /* 60 DAI1 EQ2 */
- 0x00, /* 61 DAI1 EQ2 */
- 0x00, /* 62 DAI1 EQ2 */
- 0x00, /* 63 DAI1 EQ2 */
- 0x00, /* 64 DAI1 EQ2 */
- 0x00, /* 65 DAI1 EQ2 */
- 0x00, /* 66 DAI1 EQ3 */
- 0x00, /* 67 DAI1 EQ3 */
- 0x00, /* 68 DAI1 EQ3 */
- 0x00, /* 69 DAI1 EQ3 */
- 0x00, /* 6A DAI1 EQ3 */
- 0x00, /* 6B DAI1 EQ3 */
- 0x00, /* 6C DAI1 EQ3 */
- 0x00, /* 6D DAI1 EQ3 */
- 0x00, /* 6E DAI1 EQ3 */
- 0x00, /* 6F DAI1 EQ3 */
-
- 0x00, /* 70 DAI1 EQ4 */
- 0x00, /* 71 DAI1 EQ4 */
- 0x00, /* 72 DAI1 EQ4 */
- 0x00, /* 73 DAI1 EQ4 */
- 0x00, /* 74 DAI1 EQ4 */
- 0x00, /* 75 DAI1 EQ4 */
- 0x00, /* 76 DAI1 EQ4 */
- 0x00, /* 77 DAI1 EQ4 */
- 0x00, /* 78 DAI1 EQ4 */
- 0x00, /* 79 DAI1 EQ4 */
- 0x00, /* 7A DAI1 EQ5 */
- 0x00, /* 7B DAI1 EQ5 */
- 0x00, /* 7C DAI1 EQ5 */
- 0x00, /* 7D DAI1 EQ5 */
- 0x00, /* 7E DAI1 EQ5 */
- 0x00, /* 7F DAI1 EQ5 */
-
- 0x00, /* 80 DAI1 EQ5 */
- 0x00, /* 81 DAI1 EQ5 */
- 0x00, /* 82 DAI1 EQ5 */
- 0x00, /* 83 DAI1 EQ5 */
- 0x00, /* 84 DAI2 EQ1 */
- 0x00, /* 85 DAI2 EQ1 */
- 0x00, /* 86 DAI2 EQ1 */
- 0x00, /* 87 DAI2 EQ1 */
- 0x00, /* 88 DAI2 EQ1 */
- 0x00, /* 89 DAI2 EQ1 */
- 0x00, /* 8A DAI2 EQ1 */
- 0x00, /* 8B DAI2 EQ1 */
- 0x00, /* 8C DAI2 EQ1 */
- 0x00, /* 8D DAI2 EQ1 */
- 0x00, /* 8E DAI2 EQ2 */
- 0x00, /* 8F DAI2 EQ2 */
-
- 0x00, /* 90 DAI2 EQ2 */
- 0x00, /* 91 DAI2 EQ2 */
- 0x00, /* 92 DAI2 EQ2 */
- 0x00, /* 93 DAI2 EQ2 */
- 0x00, /* 94 DAI2 EQ2 */
- 0x00, /* 95 DAI2 EQ2 */
- 0x00, /* 96 DAI2 EQ2 */
- 0x00, /* 97 DAI2 EQ2 */
- 0x00, /* 98 DAI2 EQ3 */
- 0x00, /* 99 DAI2 EQ3 */
- 0x00, /* 9A DAI2 EQ3 */
- 0x00, /* 9B DAI2 EQ3 */
- 0x00, /* 9C DAI2 EQ3 */
- 0x00, /* 9D DAI2 EQ3 */
- 0x00, /* 9E DAI2 EQ3 */
- 0x00, /* 9F DAI2 EQ3 */
-
- 0x00, /* A0 DAI2 EQ3 */
- 0x00, /* A1 DAI2 EQ3 */
- 0x00, /* A2 DAI2 EQ4 */
- 0x00, /* A3 DAI2 EQ4 */
- 0x00, /* A4 DAI2 EQ4 */
- 0x00, /* A5 DAI2 EQ4 */
- 0x00, /* A6 DAI2 EQ4 */
- 0x00, /* A7 DAI2 EQ4 */
- 0x00, /* A8 DAI2 EQ4 */
- 0x00, /* A9 DAI2 EQ4 */
- 0x00, /* AA DAI2 EQ4 */
- 0x00, /* AB DAI2 EQ4 */
- 0x00, /* AC DAI2 EQ5 */
- 0x00, /* AD DAI2 EQ5 */
- 0x00, /* AE DAI2 EQ5 */
- 0x00, /* AF DAI2 EQ5 */
-
- 0x00, /* B0 DAI2 EQ5 */
- 0x00, /* B1 DAI2 EQ5 */
- 0x00, /* B2 DAI2 EQ5 */
- 0x00, /* B3 DAI2 EQ5 */
- 0x00, /* B4 DAI2 EQ5 */
- 0x00, /* B5 DAI2 EQ5 */
- 0x00, /* B6 DAI1 biquad */
- 0x00, /* B7 DAI1 biquad */
- 0x00, /* B8 DAI1 biquad */
- 0x00, /* B9 DAI1 biquad */
- 0x00, /* BA DAI1 biquad */
- 0x00, /* BB DAI1 biquad */
- 0x00, /* BC DAI1 biquad */
- 0x00, /* BD DAI1 biquad */
- 0x00, /* BE DAI1 biquad */
- 0x00, /* BF DAI1 biquad */
-
- 0x00, /* C0 DAI2 biquad */
- 0x00, /* C1 DAI2 biquad */
- 0x00, /* C2 DAI2 biquad */
- 0x00, /* C3 DAI2 biquad */
- 0x00, /* C4 DAI2 biquad */
- 0x00, /* C5 DAI2 biquad */
- 0x00, /* C6 DAI2 biquad */
- 0x00, /* C7 DAI2 biquad */
- 0x00, /* C8 DAI2 biquad */
- 0x00, /* C9 DAI2 biquad */
- 0x00, /* CA */
- 0x00, /* CB */
- 0x00, /* CC */
- 0x00, /* CD */
- 0x00, /* CE */
- 0x00, /* CF */
-
- 0x00, /* D0 */
- 0x00, /* D1 */
- 0x00, /* D2 */
- 0x00, /* D3 */
- 0x00, /* D4 */
- 0x00, /* D5 */
- 0x00, /* D6 */
- 0x00, /* D7 */
- 0x00, /* D8 */
- 0x00, /* D9 */
- 0x00, /* DA */
- 0x70, /* DB */
- 0x00, /* DC */
- 0x00, /* DD */
- 0x00, /* DE */
- 0x00, /* DF */
-
- 0x00, /* E0 */
- 0x00, /* E1 */
- 0x00, /* E2 */
- 0x00, /* E3 */
- 0x00, /* E4 */
- 0x00, /* E5 */
- 0x00, /* E6 */
- 0x00, /* E7 */
- 0x00, /* E8 */
- 0x00, /* E9 */
- 0x00, /* EA */
- 0x00, /* EB */
- 0x00, /* EC */
- 0x00, /* ED */
- 0x00, /* EE */
- 0x00, /* EF */
-
- 0x00, /* F0 */
- 0x00, /* F1 */
- 0x00, /* F2 */
- 0x00, /* F3 */
- 0x00, /* F4 */
- 0x00, /* F5 */
- 0x00, /* F6 */
- 0x00, /* F7 */
- 0x00, /* F8 */
- 0x00, /* F9 */
- 0x00, /* FA */
- 0x00, /* FB */
- 0x00, /* FC */
- 0x00, /* FD */
- 0x00, /* FE */
- 0x00, /* FF */
-};
-
-static struct {
- int readable;
- int writable;
- int vol;
-} max98088_access[M98088_REG_CNT] = {
- { 0xFF, 0xFF, 1 }, /* 00 IRQ status */
- { 0xFF, 0x00, 1 }, /* 01 MIC status */
- { 0xFF, 0x00, 1 }, /* 02 jack status */
- { 0x1F, 0x1F, 1 }, /* 03 battery voltage */
- { 0xFF, 0xFF, 0 }, /* 04 */
- { 0xFF, 0xFF, 0 }, /* 05 */
- { 0xFF, 0xFF, 0 }, /* 06 */
- { 0xFF, 0xFF, 0 }, /* 07 */
- { 0xFF, 0xFF, 0 }, /* 08 */
- { 0xFF, 0xFF, 0 }, /* 09 */
- { 0xFF, 0xFF, 0 }, /* 0A */
- { 0xFF, 0xFF, 0 }, /* 0B */
- { 0xFF, 0xFF, 0 }, /* 0C */
- { 0xFF, 0xFF, 0 }, /* 0D */
- { 0xFF, 0xFF, 0 }, /* 0E */
- { 0xFF, 0xFF, 0 }, /* 0F interrupt enable */
-
- { 0xFF, 0xFF, 0 }, /* 10 master clock */
- { 0xFF, 0xFF, 0 }, /* 11 DAI1 clock mode */
- { 0xFF, 0xFF, 0 }, /* 12 DAI1 clock control */
- { 0xFF, 0xFF, 0 }, /* 13 DAI1 clock control */
- { 0xFF, 0xFF, 0 }, /* 14 DAI1 format */
- { 0xFF, 0xFF, 0 }, /* 15 DAI1 clock */
- { 0xFF, 0xFF, 0 }, /* 16 DAI1 config */
- { 0xFF, 0xFF, 0 }, /* 17 DAI1 TDM */
- { 0xFF, 0xFF, 0 }, /* 18 DAI1 filters */
- { 0xFF, 0xFF, 0 }, /* 19 DAI2 clock mode */
- { 0xFF, 0xFF, 0 }, /* 1A DAI2 clock control */
- { 0xFF, 0xFF, 0 }, /* 1B DAI2 clock control */
- { 0xFF, 0xFF, 0 }, /* 1C DAI2 format */
- { 0xFF, 0xFF, 0 }, /* 1D DAI2 clock */
- { 0xFF, 0xFF, 0 }, /* 1E DAI2 config */
- { 0xFF, 0xFF, 0 }, /* 1F DAI2 TDM */
-
- { 0xFF, 0xFF, 0 }, /* 20 DAI2 filters */
- { 0xFF, 0xFF, 0 }, /* 21 data config */
- { 0xFF, 0xFF, 0 }, /* 22 DAC mixer */
- { 0xFF, 0xFF, 0 }, /* 23 left ADC mixer */
- { 0xFF, 0xFF, 0 }, /* 24 right ADC mixer */
- { 0xFF, 0xFF, 0 }, /* 25 left HP mixer */
- { 0xFF, 0xFF, 0 }, /* 26 right HP mixer */
- { 0xFF, 0xFF, 0 }, /* 27 HP control */
- { 0xFF, 0xFF, 0 }, /* 28 left REC mixer */
- { 0xFF, 0xFF, 0 }, /* 29 right REC mixer */
- { 0xFF, 0xFF, 0 }, /* 2A REC control */
- { 0xFF, 0xFF, 0 }, /* 2B left SPK mixer */
- { 0xFF, 0xFF, 0 }, /* 2C right SPK mixer */
- { 0xFF, 0xFF, 0 }, /* 2D SPK control */
- { 0xFF, 0xFF, 0 }, /* 2E sidetone */
- { 0xFF, 0xFF, 0 }, /* 2F DAI1 playback level */
-
- { 0xFF, 0xFF, 0 }, /* 30 DAI1 playback level */
- { 0xFF, 0xFF, 0 }, /* 31 DAI2 playback level */
- { 0xFF, 0xFF, 0 }, /* 32 DAI2 playbakc level */
- { 0xFF, 0xFF, 0 }, /* 33 left ADC level */
- { 0xFF, 0xFF, 0 }, /* 34 right ADC level */
- { 0xFF, 0xFF, 0 }, /* 35 MIC1 level */
- { 0xFF, 0xFF, 0 }, /* 36 MIC2 level */
- { 0xFF, 0xFF, 0 }, /* 37 INA level */
- { 0xFF, 0xFF, 0 }, /* 38 INB level */
- { 0xFF, 0xFF, 0 }, /* 39 left HP volume */
- { 0xFF, 0xFF, 0 }, /* 3A right HP volume */
- { 0xFF, 0xFF, 0 }, /* 3B left REC volume */
- { 0xFF, 0xFF, 0 }, /* 3C right REC volume */
- { 0xFF, 0xFF, 0 }, /* 3D left SPK volume */
- { 0xFF, 0xFF, 0 }, /* 3E right SPK volume */
- { 0xFF, 0xFF, 0 }, /* 3F MIC config */
-
- { 0xFF, 0xFF, 0 }, /* 40 MIC threshold */
- { 0xFF, 0xFF, 0 }, /* 41 excursion limiter filter */
- { 0xFF, 0xFF, 0 }, /* 42 excursion limiter threshold */
- { 0xFF, 0xFF, 0 }, /* 43 ALC */
- { 0xFF, 0xFF, 0 }, /* 44 power limiter threshold */
- { 0xFF, 0xFF, 0 }, /* 45 power limiter config */
- { 0xFF, 0xFF, 0 }, /* 46 distortion limiter config */
- { 0xFF, 0xFF, 0 }, /* 47 audio input */
- { 0xFF, 0xFF, 0 }, /* 48 microphone */
- { 0xFF, 0xFF, 0 }, /* 49 level control */
- { 0xFF, 0xFF, 0 }, /* 4A bypass switches */
- { 0xFF, 0xFF, 0 }, /* 4B jack detect */
- { 0xFF, 0xFF, 0 }, /* 4C input enable */
- { 0xFF, 0xFF, 0 }, /* 4D output enable */
- { 0xFF, 0xFF, 0 }, /* 4E bias control */
- { 0xFF, 0xFF, 0 }, /* 4F DAC power */
-
- { 0xFF, 0xFF, 0 }, /* 50 DAC power */
- { 0xFF, 0xFF, 0 }, /* 51 system */
- { 0xFF, 0xFF, 0 }, /* 52 DAI1 EQ1 */
- { 0xFF, 0xFF, 0 }, /* 53 DAI1 EQ1 */
- { 0xFF, 0xFF, 0 }, /* 54 DAI1 EQ1 */
- { 0xFF, 0xFF, 0 }, /* 55 DAI1 EQ1 */
- { 0xFF, 0xFF, 0 }, /* 56 DAI1 EQ1 */
- { 0xFF, 0xFF, 0 }, /* 57 DAI1 EQ1 */
- { 0xFF, 0xFF, 0 }, /* 58 DAI1 EQ1 */
- { 0xFF, 0xFF, 0 }, /* 59 DAI1 EQ1 */
- { 0xFF, 0xFF, 0 }, /* 5A DAI1 EQ1 */
- { 0xFF, 0xFF, 0 }, /* 5B DAI1 EQ1 */
- { 0xFF, 0xFF, 0 }, /* 5C DAI1 EQ2 */
- { 0xFF, 0xFF, 0 }, /* 5D DAI1 EQ2 */
- { 0xFF, 0xFF, 0 }, /* 5E DAI1 EQ2 */
- { 0xFF, 0xFF, 0 }, /* 5F DAI1 EQ2 */
-
- { 0xFF, 0xFF, 0 }, /* 60 DAI1 EQ2 */
- { 0xFF, 0xFF, 0 }, /* 61 DAI1 EQ2 */
- { 0xFF, 0xFF, 0 }, /* 62 DAI1 EQ2 */
- { 0xFF, 0xFF, 0 }, /* 63 DAI1 EQ2 */
- { 0xFF, 0xFF, 0 }, /* 64 DAI1 EQ2 */
- { 0xFF, 0xFF, 0 }, /* 65 DAI1 EQ2 */
- { 0xFF, 0xFF, 0 }, /* 66 DAI1 EQ3 */
- { 0xFF, 0xFF, 0 }, /* 67 DAI1 EQ3 */
- { 0xFF, 0xFF, 0 }, /* 68 DAI1 EQ3 */
- { 0xFF, 0xFF, 0 }, /* 69 DAI1 EQ3 */
- { 0xFF, 0xFF, 0 }, /* 6A DAI1 EQ3 */
- { 0xFF, 0xFF, 0 }, /* 6B DAI1 EQ3 */
- { 0xFF, 0xFF, 0 }, /* 6C DAI1 EQ3 */
- { 0xFF, 0xFF, 0 }, /* 6D DAI1 EQ3 */
- { 0xFF, 0xFF, 0 }, /* 6E DAI1 EQ3 */
- { 0xFF, 0xFF, 0 }, /* 6F DAI1 EQ3 */
-
- { 0xFF, 0xFF, 0 }, /* 70 DAI1 EQ4 */
- { 0xFF, 0xFF, 0 }, /* 71 DAI1 EQ4 */
- { 0xFF, 0xFF, 0 }, /* 72 DAI1 EQ4 */
- { 0xFF, 0xFF, 0 }, /* 73 DAI1 EQ4 */
- { 0xFF, 0xFF, 0 }, /* 74 DAI1 EQ4 */
- { 0xFF, 0xFF, 0 }, /* 75 DAI1 EQ4 */
- { 0xFF, 0xFF, 0 }, /* 76 DAI1 EQ4 */
- { 0xFF, 0xFF, 0 }, /* 77 DAI1 EQ4 */
- { 0xFF, 0xFF, 0 }, /* 78 DAI1 EQ4 */
- { 0xFF, 0xFF, 0 }, /* 79 DAI1 EQ4 */
- { 0xFF, 0xFF, 0 }, /* 7A DAI1 EQ5 */
- { 0xFF, 0xFF, 0 }, /* 7B DAI1 EQ5 */
- { 0xFF, 0xFF, 0 }, /* 7C DAI1 EQ5 */
- { 0xFF, 0xFF, 0 }, /* 7D DAI1 EQ5 */
- { 0xFF, 0xFF, 0 }, /* 7E DAI1 EQ5 */
- { 0xFF, 0xFF, 0 }, /* 7F DAI1 EQ5 */
-
- { 0xFF, 0xFF, 0 }, /* 80 DAI1 EQ5 */
- { 0xFF, 0xFF, 0 }, /* 81 DAI1 EQ5 */
- { 0xFF, 0xFF, 0 }, /* 82 DAI1 EQ5 */
- { 0xFF, 0xFF, 0 }, /* 83 DAI1 EQ5 */
- { 0xFF, 0xFF, 0 }, /* 84 DAI2 EQ1 */
- { 0xFF, 0xFF, 0 }, /* 85 DAI2 EQ1 */
- { 0xFF, 0xFF, 0 }, /* 86 DAI2 EQ1 */
- { 0xFF, 0xFF, 0 }, /* 87 DAI2 EQ1 */
- { 0xFF, 0xFF, 0 }, /* 88 DAI2 EQ1 */
- { 0xFF, 0xFF, 0 }, /* 89 DAI2 EQ1 */
- { 0xFF, 0xFF, 0 }, /* 8A DAI2 EQ1 */
- { 0xFF, 0xFF, 0 }, /* 8B DAI2 EQ1 */
- { 0xFF, 0xFF, 0 }, /* 8C DAI2 EQ1 */
- { 0xFF, 0xFF, 0 }, /* 8D DAI2 EQ1 */
- { 0xFF, 0xFF, 0 }, /* 8E DAI2 EQ2 */
- { 0xFF, 0xFF, 0 }, /* 8F DAI2 EQ2 */
-
- { 0xFF, 0xFF, 0 }, /* 90 DAI2 EQ2 */
- { 0xFF, 0xFF, 0 }, /* 91 DAI2 EQ2 */
- { 0xFF, 0xFF, 0 }, /* 92 DAI2 EQ2 */
- { 0xFF, 0xFF, 0 }, /* 93 DAI2 EQ2 */
- { 0xFF, 0xFF, 0 }, /* 94 DAI2 EQ2 */
- { 0xFF, 0xFF, 0 }, /* 95 DAI2 EQ2 */
- { 0xFF, 0xFF, 0 }, /* 96 DAI2 EQ2 */
- { 0xFF, 0xFF, 0 }, /* 97 DAI2 EQ2 */
- { 0xFF, 0xFF, 0 }, /* 98 DAI2 EQ3 */
- { 0xFF, 0xFF, 0 }, /* 99 DAI2 EQ3 */
- { 0xFF, 0xFF, 0 }, /* 9A DAI2 EQ3 */
- { 0xFF, 0xFF, 0 }, /* 9B DAI2 EQ3 */
- { 0xFF, 0xFF, 0 }, /* 9C DAI2 EQ3 */
- { 0xFF, 0xFF, 0 }, /* 9D DAI2 EQ3 */
- { 0xFF, 0xFF, 0 }, /* 9E DAI2 EQ3 */
- { 0xFF, 0xFF, 0 }, /* 9F DAI2 EQ3 */
-
- { 0xFF, 0xFF, 0 }, /* A0 DAI2 EQ3 */
- { 0xFF, 0xFF, 0 }, /* A1 DAI2 EQ3 */
- { 0xFF, 0xFF, 0 }, /* A2 DAI2 EQ4 */
- { 0xFF, 0xFF, 0 }, /* A3 DAI2 EQ4 */
- { 0xFF, 0xFF, 0 }, /* A4 DAI2 EQ4 */
- { 0xFF, 0xFF, 0 }, /* A5 DAI2 EQ4 */
- { 0xFF, 0xFF, 0 }, /* A6 DAI2 EQ4 */
- { 0xFF, 0xFF, 0 }, /* A7 DAI2 EQ4 */
- { 0xFF, 0xFF, 0 }, /* A8 DAI2 EQ4 */
- { 0xFF, 0xFF, 0 }, /* A9 DAI2 EQ4 */
- { 0xFF, 0xFF, 0 }, /* AA DAI2 EQ4 */
- { 0xFF, 0xFF, 0 }, /* AB DAI2 EQ4 */
- { 0xFF, 0xFF, 0 }, /* AC DAI2 EQ5 */
- { 0xFF, 0xFF, 0 }, /* AD DAI2 EQ5 */
- { 0xFF, 0xFF, 0 }, /* AE DAI2 EQ5 */
- { 0xFF, 0xFF, 0 }, /* AF DAI2 EQ5 */
-
- { 0xFF, 0xFF, 0 }, /* B0 DAI2 EQ5 */
- { 0xFF, 0xFF, 0 }, /* B1 DAI2 EQ5 */
- { 0xFF, 0xFF, 0 }, /* B2 DAI2 EQ5 */
- { 0xFF, 0xFF, 0 }, /* B3 DAI2 EQ5 */
- { 0xFF, 0xFF, 0 }, /* B4 DAI2 EQ5 */
- { 0xFF, 0xFF, 0 }, /* B5 DAI2 EQ5 */
- { 0xFF, 0xFF, 0 }, /* B6 DAI1 biquad */
- { 0xFF, 0xFF, 0 }, /* B7 DAI1 biquad */
- { 0xFF, 0xFF, 0 }, /* B8 DAI1 biquad */
- { 0xFF, 0xFF, 0 }, /* B9 DAI1 biquad */
- { 0xFF, 0xFF, 0 }, /* BA DAI1 biquad */
- { 0xFF, 0xFF, 0 }, /* BB DAI1 biquad */
- { 0xFF, 0xFF, 0 }, /* BC DAI1 biquad */
- { 0xFF, 0xFF, 0 }, /* BD DAI1 biquad */
- { 0xFF, 0xFF, 0 }, /* BE DAI1 biquad */
- { 0xFF, 0xFF, 0 }, /* BF DAI1 biquad */
-
- { 0xFF, 0xFF, 0 }, /* C0 DAI2 biquad */
- { 0xFF, 0xFF, 0 }, /* C1 DAI2 biquad */
- { 0xFF, 0xFF, 0 }, /* C2 DAI2 biquad */
- { 0xFF, 0xFF, 0 }, /* C3 DAI2 biquad */
- { 0xFF, 0xFF, 0 }, /* C4 DAI2 biquad */
- { 0xFF, 0xFF, 0 }, /* C5 DAI2 biquad */
- { 0xFF, 0xFF, 0 }, /* C6 DAI2 biquad */
- { 0xFF, 0xFF, 0 }, /* C7 DAI2 biquad */
- { 0xFF, 0xFF, 0 }, /* C8 DAI2 biquad */
- { 0xFF, 0xFF, 0 }, /* C9 DAI2 biquad */
- { 0x00, 0x00, 0 }, /* CA */
- { 0x00, 0x00, 0 }, /* CB */
- { 0x00, 0x00, 0 }, /* CC */
- { 0x00, 0x00, 0 }, /* CD */
- { 0x00, 0x00, 0 }, /* CE */
- { 0x00, 0x00, 0 }, /* CF */
-
- { 0x00, 0x00, 0 }, /* D0 */
- { 0x00, 0x00, 0 }, /* D1 */
- { 0x00, 0x00, 0 }, /* D2 */
- { 0x00, 0x00, 0 }, /* D3 */
- { 0x00, 0x00, 0 }, /* D4 */
- { 0x00, 0x00, 0 }, /* D5 */
- { 0x00, 0x00, 0 }, /* D6 */
- { 0x00, 0x00, 0 }, /* D7 */
- { 0x00, 0x00, 0 }, /* D8 */
- { 0x00, 0x00, 0 }, /* D9 */
- { 0x00, 0x00, 0 }, /* DA */
- { 0x00, 0x00, 0 }, /* DB */
- { 0x00, 0x00, 0 }, /* DC */
- { 0x00, 0x00, 0 }, /* DD */
- { 0x00, 0x00, 0 }, /* DE */
- { 0x00, 0x00, 0 }, /* DF */
-
- { 0x00, 0x00, 0 }, /* E0 */
- { 0x00, 0x00, 0 }, /* E1 */
- { 0x00, 0x00, 0 }, /* E2 */
- { 0x00, 0x00, 0 }, /* E3 */
- { 0x00, 0x00, 0 }, /* E4 */
- { 0x00, 0x00, 0 }, /* E5 */
- { 0x00, 0x00, 0 }, /* E6 */
- { 0x00, 0x00, 0 }, /* E7 */
- { 0x00, 0x00, 0 }, /* E8 */
- { 0x00, 0x00, 0 }, /* E9 */
- { 0x00, 0x00, 0 }, /* EA */
- { 0x00, 0x00, 0 }, /* EB */
- { 0x00, 0x00, 0 }, /* EC */
- { 0x00, 0x00, 0 }, /* ED */
- { 0x00, 0x00, 0 }, /* EE */
- { 0x00, 0x00, 0 }, /* EF */
-
- { 0x00, 0x00, 0 }, /* F0 */
- { 0x00, 0x00, 0 }, /* F1 */
- { 0x00, 0x00, 0 }, /* F2 */
- { 0x00, 0x00, 0 }, /* F3 */
- { 0x00, 0x00, 0 }, /* F4 */
- { 0x00, 0x00, 0 }, /* F5 */
- { 0x00, 0x00, 0 }, /* F6 */
- { 0x00, 0x00, 0 }, /* F7 */
- { 0x00, 0x00, 0 }, /* F8 */
- { 0x00, 0x00, 0 }, /* F9 */
- { 0x00, 0x00, 0 }, /* FA */
- { 0x00, 0x00, 0 }, /* FB */
- { 0x00, 0x00, 0 }, /* FC */
- { 0x00, 0x00, 0 }, /* FD */
- { 0x00, 0x00, 0 }, /* FE */
- { 0xFF, 0x00, 1 }, /* FF */
-};
-
-static int max98088_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
-{
- return max98088_access[reg].vol;
-}
-
-
-/*
- * Load equalizer DSP coefficient configurations registers
- */
-static void m98088_eq_band(struct snd_soc_codec *codec, unsigned int dai,
- unsigned int band, u16 *coefs)
-{
- unsigned int eq_reg;
- unsigned int i;
-
- BUG_ON(band > 4);
- BUG_ON(dai > 1);
-
- /* Load the base register address */
- eq_reg = dai ? M98088_REG_84_DAI2_EQ_BASE : M98088_REG_52_DAI1_EQ_BASE;
-
- /* Add the band address offset, note adjustment for word address */
- eq_reg += band * (M98088_COEFS_PER_BAND << 1);
-
- /* Step through the registers and coefs */
- for (i = 0; i < M98088_COEFS_PER_BAND; i++) {
- snd_soc_write(codec, eq_reg++, M98088_BYTE1(coefs[i]));
- snd_soc_write(codec, eq_reg++, M98088_BYTE0(coefs[i]));
- }
-}
-
-/*
- * Excursion limiter modes
- */
-static const char *max98088_exmode_texts[] = {
- "Off", "100Hz", "400Hz", "600Hz", "800Hz", "1000Hz", "200-400Hz",
- "400-600Hz", "400-800Hz",
-};
-
-static const unsigned int max98088_exmode_values[] = {
- 0x00, 0x43, 0x10, 0x20, 0x30, 0x40, 0x11, 0x22, 0x32
-};
-
-static const struct soc_enum max98088_exmode_enum =
- SOC_VALUE_ENUM_SINGLE(M98088_REG_41_SPKDHP, 0, 127,
- ARRAY_SIZE(max98088_exmode_texts),
- max98088_exmode_texts,
- max98088_exmode_values);
-
-static const char *max98088_ex_thresh[] = { /* volts PP */
- "0.6", "1.2", "1.8", "2.4", "3.0", "3.6", "4.2", "4.8"};
-static const struct soc_enum max98088_ex_thresh_enum[] = {
- SOC_ENUM_SINGLE(M98088_REG_42_SPKDHP_THRESH, 0, 8,
- max98088_ex_thresh),
-};
-
-static const char *max98088_fltr_mode[] = {"Voice", "Music" };
-static const struct soc_enum max98088_filter_mode_enum[] = {
- SOC_ENUM_SINGLE(M98088_REG_18_DAI1_FILTERS, 7, 2, max98088_fltr_mode),
-};
-
-static const char *max98088_extmic_text[] = { "None", "MIC1", "MIC2" };
-
-static const struct soc_enum max98088_extmic_enum =
- SOC_ENUM_SINGLE(M98088_REG_48_CFG_MIC, 0, 3, max98088_extmic_text);
-
-static const struct snd_kcontrol_new max98088_extmic_mux =
- SOC_DAPM_ENUM("External MIC Mux", max98088_extmic_enum);
-
-static const char *max98088_dai1_fltr[] = {
- "Off", "fc=258/fs=16k", "fc=500/fs=16k",
- "fc=258/fs=8k", "fc=500/fs=8k", "fc=200"};
-static const struct soc_enum max98088_dai1_dac_filter_enum[] = {
- SOC_ENUM_SINGLE(M98088_REG_18_DAI1_FILTERS, 0, 6, max98088_dai1_fltr),
-};
-static const struct soc_enum max98088_dai1_adc_filter_enum[] = {
- SOC_ENUM_SINGLE(M98088_REG_18_DAI1_FILTERS, 4, 6, max98088_dai1_fltr),
-};
-
-static int max98088_mic1pre_set(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
- unsigned int sel = ucontrol->value.integer.value[0];
-
- max98088->mic1pre = sel;
- snd_soc_update_bits(codec, M98088_REG_35_LVL_MIC1, M98088_MICPRE_MASK,
- (1+sel)<<M98088_MICPRE_SHIFT);
-
- return 0;
-}
-
-static int max98088_mic1pre_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.integer.value[0] = max98088->mic1pre;
- return 0;
-}
-
-static int max98088_mic2pre_set(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
- unsigned int sel = ucontrol->value.integer.value[0];
-
- max98088->mic2pre = sel;
- snd_soc_update_bits(codec, M98088_REG_36_LVL_MIC2, M98088_MICPRE_MASK,
- (1+sel)<<M98088_MICPRE_SHIFT);
-
- return 0;
-}
-
-static int max98088_mic2pre_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.integer.value[0] = max98088->mic2pre;
- return 0;
-}
-
-static const unsigned int max98088_micboost_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0),
- 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
-};
-
-static const struct snd_kcontrol_new max98088_snd_controls[] = {
-
- SOC_DOUBLE_R("Headphone Volume", M98088_REG_39_LVL_HP_L,
- M98088_REG_3A_LVL_HP_R, 0, 31, 0),
- SOC_DOUBLE_R("Speaker Volume", M98088_REG_3D_LVL_SPK_L,
- M98088_REG_3E_LVL_SPK_R, 0, 31, 0),
- SOC_DOUBLE_R("Receiver Volume", M98088_REG_3B_LVL_REC_L,
- M98088_REG_3C_LVL_REC_R, 0, 31, 0),
-
- SOC_DOUBLE_R("Headphone Switch", M98088_REG_39_LVL_HP_L,
- M98088_REG_3A_LVL_HP_R, 7, 1, 1),
- SOC_DOUBLE_R("Speaker Switch", M98088_REG_3D_LVL_SPK_L,
- M98088_REG_3E_LVL_SPK_R, 7, 1, 1),
- SOC_DOUBLE_R("Receiver Switch", M98088_REG_3B_LVL_REC_L,
- M98088_REG_3C_LVL_REC_R, 7, 1, 1),
-
- SOC_SINGLE("MIC1 Volume", M98088_REG_35_LVL_MIC1, 0, 31, 1),
- SOC_SINGLE("MIC2 Volume", M98088_REG_36_LVL_MIC2, 0, 31, 1),
-
- SOC_SINGLE_EXT_TLV("MIC1 Boost Volume",
- M98088_REG_35_LVL_MIC1, 5, 2, 0,
- max98088_mic1pre_get, max98088_mic1pre_set,
- max98088_micboost_tlv),
- SOC_SINGLE_EXT_TLV("MIC2 Boost Volume",
- M98088_REG_36_LVL_MIC2, 5, 2, 0,
- max98088_mic2pre_get, max98088_mic2pre_set,
- max98088_micboost_tlv),
-
- SOC_SINGLE("INA Volume", M98088_REG_37_LVL_INA, 0, 7, 1),
- SOC_SINGLE("INB Volume", M98088_REG_38_LVL_INB, 0, 7, 1),
-
- SOC_SINGLE("ADCL Volume", M98088_REG_33_LVL_ADC_L, 0, 15, 0),
- SOC_SINGLE("ADCR Volume", M98088_REG_34_LVL_ADC_R, 0, 15, 0),
-
- SOC_SINGLE("ADCL Boost Volume", M98088_REG_33_LVL_ADC_L, 4, 3, 0),
- SOC_SINGLE("ADCR Boost Volume", M98088_REG_34_LVL_ADC_R, 4, 3, 0),
-
- SOC_SINGLE("EQ1 Switch", M98088_REG_49_CFG_LEVEL, 0, 1, 0),
- SOC_SINGLE("EQ2 Switch", M98088_REG_49_CFG_LEVEL, 1, 1, 0),
-
- SOC_ENUM("EX Limiter Mode", max98088_exmode_enum),
- SOC_ENUM("EX Limiter Threshold", max98088_ex_thresh_enum),
-
- SOC_ENUM("DAI1 Filter Mode", max98088_filter_mode_enum),
- SOC_ENUM("DAI1 DAC Filter", max98088_dai1_dac_filter_enum),
- SOC_ENUM("DAI1 ADC Filter", max98088_dai1_adc_filter_enum),
- SOC_SINGLE("DAI2 DC Block Switch", M98088_REG_20_DAI2_FILTERS,
- 0, 1, 0),
-
- SOC_SINGLE("ALC Switch", M98088_REG_43_SPKALC_COMP, 7, 1, 0),
- SOC_SINGLE("ALC Threshold", M98088_REG_43_SPKALC_COMP, 0, 7, 0),
- SOC_SINGLE("ALC Multiband", M98088_REG_43_SPKALC_COMP, 3, 1, 0),
- SOC_SINGLE("ALC Release Time", M98088_REG_43_SPKALC_COMP, 4, 7, 0),
-
- SOC_SINGLE("PWR Limiter Threshold", M98088_REG_44_PWRLMT_CFG,
- 4, 15, 0),
- SOC_SINGLE("PWR Limiter Weight", M98088_REG_44_PWRLMT_CFG, 0, 7, 0),
- SOC_SINGLE("PWR Limiter Time1", M98088_REG_45_PWRLMT_TIME, 0, 15, 0),
- SOC_SINGLE("PWR Limiter Time2", M98088_REG_45_PWRLMT_TIME, 4, 15, 0),
-
- SOC_SINGLE("THD Limiter Threshold", M98088_REG_46_THDLMT_CFG, 4, 15, 0),
- SOC_SINGLE("THD Limiter Time", M98088_REG_46_THDLMT_CFG, 0, 7, 0),
-};
-
-/* Left speaker mixer switch */
-static const struct snd_kcontrol_new max98088_left_speaker_mixer_controls[] = {
- SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 0, 1, 0),
- SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 7, 1, 0),
- SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 0, 1, 0),
- SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 7, 1, 0),
- SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 5, 1, 0),
- SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 6, 1, 0),
- SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 1, 1, 0),
- SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 2, 1, 0),
- SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 3, 1, 0),
- SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 4, 1, 0),
-};
-
-/* Right speaker mixer switch */
-static const struct snd_kcontrol_new max98088_right_speaker_mixer_controls[] = {
- SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 7, 1, 0),
- SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 0, 1, 0),
- SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 7, 1, 0),
- SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 0, 1, 0),
- SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 5, 1, 0),
- SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 6, 1, 0),
- SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 1, 1, 0),
- SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 2, 1, 0),
- SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 3, 1, 0),
- SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 4, 1, 0),
-};
-
-/* Left headphone mixer switch */
-static const struct snd_kcontrol_new max98088_left_hp_mixer_controls[] = {
- SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_25_MIX_HP_LEFT, 0, 1, 0),
- SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_25_MIX_HP_LEFT, 7, 1, 0),
- SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_25_MIX_HP_LEFT, 0, 1, 0),
- SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_25_MIX_HP_LEFT, 7, 1, 0),
- SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_25_MIX_HP_LEFT, 5, 1, 0),
- SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_25_MIX_HP_LEFT, 6, 1, 0),
- SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_25_MIX_HP_LEFT, 1, 1, 0),
- SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_25_MIX_HP_LEFT, 2, 1, 0),
- SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_25_MIX_HP_LEFT, 3, 1, 0),
- SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_25_MIX_HP_LEFT, 4, 1, 0),
-};
-
-/* Right headphone mixer switch */
-static const struct snd_kcontrol_new max98088_right_hp_mixer_controls[] = {
- SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_26_MIX_HP_RIGHT, 7, 1, 0),
- SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_26_MIX_HP_RIGHT, 0, 1, 0),
- SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_26_MIX_HP_RIGHT, 7, 1, 0),
- SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_26_MIX_HP_RIGHT, 0, 1, 0),
- SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_26_MIX_HP_RIGHT, 5, 1, 0),
- SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_26_MIX_HP_RIGHT, 6, 1, 0),
- SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_26_MIX_HP_RIGHT, 1, 1, 0),
- SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_26_MIX_HP_RIGHT, 2, 1, 0),
- SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_26_MIX_HP_RIGHT, 3, 1, 0),
- SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_26_MIX_HP_RIGHT, 4, 1, 0),
-};
-
-/* Left earpiece/receiver mixer switch */
-static const struct snd_kcontrol_new max98088_left_rec_mixer_controls[] = {
- SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_28_MIX_REC_LEFT, 0, 1, 0),
- SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_28_MIX_REC_LEFT, 7, 1, 0),
- SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_28_MIX_REC_LEFT, 0, 1, 0),
- SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_28_MIX_REC_LEFT, 7, 1, 0),
- SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_28_MIX_REC_LEFT, 5, 1, 0),
- SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_28_MIX_REC_LEFT, 6, 1, 0),
- SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_28_MIX_REC_LEFT, 1, 1, 0),
- SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_28_MIX_REC_LEFT, 2, 1, 0),
- SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_28_MIX_REC_LEFT, 3, 1, 0),
- SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_28_MIX_REC_LEFT, 4, 1, 0),
-};
-
-/* Right earpiece/receiver mixer switch */
-static const struct snd_kcontrol_new max98088_right_rec_mixer_controls[] = {
- SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_29_MIX_REC_RIGHT, 7, 1, 0),
- SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_29_MIX_REC_RIGHT, 0, 1, 0),
- SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_29_MIX_REC_RIGHT, 7, 1, 0),
- SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_29_MIX_REC_RIGHT, 0, 1, 0),
- SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_29_MIX_REC_RIGHT, 5, 1, 0),
- SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_29_MIX_REC_RIGHT, 6, 1, 0),
- SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_29_MIX_REC_RIGHT, 1, 1, 0),
- SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_29_MIX_REC_RIGHT, 2, 1, 0),
- SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_29_MIX_REC_RIGHT, 3, 1, 0),
- SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_29_MIX_REC_RIGHT, 4, 1, 0),
-};
-
-/* Left ADC mixer switch */
-static const struct snd_kcontrol_new max98088_left_ADC_mixer_controls[] = {
- SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_23_MIX_ADC_LEFT, 7, 1, 0),
- SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_23_MIX_ADC_LEFT, 6, 1, 0),
- SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_23_MIX_ADC_LEFT, 3, 1, 0),
- SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_23_MIX_ADC_LEFT, 2, 1, 0),
- SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_23_MIX_ADC_LEFT, 1, 1, 0),
- SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_23_MIX_ADC_LEFT, 0, 1, 0),
-};
-
-/* Right ADC mixer switch */
-static const struct snd_kcontrol_new max98088_right_ADC_mixer_controls[] = {
- SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_24_MIX_ADC_RIGHT, 7, 1, 0),
- SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_24_MIX_ADC_RIGHT, 6, 1, 0),
- SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_24_MIX_ADC_RIGHT, 3, 1, 0),
- SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_24_MIX_ADC_RIGHT, 2, 1, 0),
- SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_24_MIX_ADC_RIGHT, 1, 1, 0),
- SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_24_MIX_ADC_RIGHT, 0, 1, 0),
-};
-
-static int max98088_mic_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- if (w->reg == M98088_REG_35_LVL_MIC1) {
- snd_soc_update_bits(codec, w->reg, M98088_MICPRE_MASK,
- (1+max98088->mic1pre)<<M98088_MICPRE_SHIFT);
- } else {
- snd_soc_update_bits(codec, w->reg, M98088_MICPRE_MASK,
- (1+max98088->mic2pre)<<M98088_MICPRE_SHIFT);
- }
- break;
- case SND_SOC_DAPM_POST_PMD:
- snd_soc_update_bits(codec, w->reg, M98088_MICPRE_MASK, 0);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * The line inputs are 2-channel stereo inputs with the left
- * and right channels sharing a common PGA power control signal.
- */
-static int max98088_line_pga(struct snd_soc_dapm_widget *w,
- int event, int line, u8 channel)
-{
- struct snd_soc_codec *codec = w->codec;
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
- u8 *state;
-
- BUG_ON(!((channel == 1) || (channel == 2)));
-
- switch (line) {
- case LINE_INA:
- state = &max98088->ina_state;
- break;
- case LINE_INB:
- state = &max98088->inb_state;
- break;
- default:
- return -EINVAL;
- }
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- *state |= channel;
- snd_soc_update_bits(codec, w->reg,
- (1 << w->shift), (1 << w->shift));
- break;
- case SND_SOC_DAPM_POST_PMD:
- *state &= ~channel;
- if (*state == 0) {
- snd_soc_update_bits(codec, w->reg,
- (1 << w->shift), 0);
- }
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int max98088_pga_ina1_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- return max98088_line_pga(w, event, LINE_INA, 1);
-}
-
-static int max98088_pga_ina2_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- return max98088_line_pga(w, event, LINE_INA, 2);
-}
-
-static int max98088_pga_inb1_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- return max98088_line_pga(w, event, LINE_INB, 1);
-}
-
-static int max98088_pga_inb2_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- return max98088_line_pga(w, event, LINE_INB, 2);
-}
-
-static const struct snd_soc_dapm_widget max98088_dapm_widgets[] = {
-
- SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", M98088_REG_4C_PWR_EN_IN, 1, 0),
- SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", M98088_REG_4C_PWR_EN_IN, 0, 0),
-
- SND_SOC_DAPM_DAC("DACL1", "HiFi Playback",
- M98088_REG_4D_PWR_EN_OUT, 1, 0),
- SND_SOC_DAPM_DAC("DACR1", "HiFi Playback",
- M98088_REG_4D_PWR_EN_OUT, 0, 0),
- SND_SOC_DAPM_DAC("DACL2", "Aux Playback",
- M98088_REG_4D_PWR_EN_OUT, 1, 0),
- SND_SOC_DAPM_DAC("DACR2", "Aux Playback",
- M98088_REG_4D_PWR_EN_OUT, 0, 0),
-
- SND_SOC_DAPM_PGA("HP Left Out", M98088_REG_4D_PWR_EN_OUT,
- 7, 0, NULL, 0),
- SND_SOC_DAPM_PGA("HP Right Out", M98088_REG_4D_PWR_EN_OUT,
- 6, 0, NULL, 0),
-
- SND_SOC_DAPM_PGA("SPK Left Out", M98088_REG_4D_PWR_EN_OUT,
- 5, 0, NULL, 0),
- SND_SOC_DAPM_PGA("SPK Right Out", M98088_REG_4D_PWR_EN_OUT,
- 4, 0, NULL, 0),
-
- SND_SOC_DAPM_PGA("REC Left Out", M98088_REG_4D_PWR_EN_OUT,
- 3, 0, NULL, 0),
- SND_SOC_DAPM_PGA("REC Right Out", M98088_REG_4D_PWR_EN_OUT,
- 2, 0, NULL, 0),
-
- SND_SOC_DAPM_MUX("External MIC", SND_SOC_NOPM, 0, 0,
- &max98088_extmic_mux),
-
- SND_SOC_DAPM_MIXER("Left HP Mixer", SND_SOC_NOPM, 0, 0,
- &max98088_left_hp_mixer_controls[0],
- ARRAY_SIZE(max98088_left_hp_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Right HP Mixer", SND_SOC_NOPM, 0, 0,
- &max98088_right_hp_mixer_controls[0],
- ARRAY_SIZE(max98088_right_hp_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Left SPK Mixer", SND_SOC_NOPM, 0, 0,
- &max98088_left_speaker_mixer_controls[0],
- ARRAY_SIZE(max98088_left_speaker_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Right SPK Mixer", SND_SOC_NOPM, 0, 0,
- &max98088_right_speaker_mixer_controls[0],
- ARRAY_SIZE(max98088_right_speaker_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Left REC Mixer", SND_SOC_NOPM, 0, 0,
- &max98088_left_rec_mixer_controls[0],
- ARRAY_SIZE(max98088_left_rec_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Right REC Mixer", SND_SOC_NOPM, 0, 0,
- &max98088_right_rec_mixer_controls[0],
- ARRAY_SIZE(max98088_right_rec_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Left ADC Mixer", SND_SOC_NOPM, 0, 0,
- &max98088_left_ADC_mixer_controls[0],
- ARRAY_SIZE(max98088_left_ADC_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Right ADC Mixer", SND_SOC_NOPM, 0, 0,
- &max98088_right_ADC_mixer_controls[0],
- ARRAY_SIZE(max98088_right_ADC_mixer_controls)),
-
- SND_SOC_DAPM_PGA_E("MIC1 Input", M98088_REG_35_LVL_MIC1,
- 5, 0, NULL, 0, max98088_mic_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_PGA_E("MIC2 Input", M98088_REG_36_LVL_MIC2,
- 5, 0, NULL, 0, max98088_mic_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_PGA_E("INA1 Input", M98088_REG_4C_PWR_EN_IN,
- 7, 0, NULL, 0, max98088_pga_ina1_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_PGA_E("INA2 Input", M98088_REG_4C_PWR_EN_IN,
- 7, 0, NULL, 0, max98088_pga_ina2_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_PGA_E("INB1 Input", M98088_REG_4C_PWR_EN_IN,
- 6, 0, NULL, 0, max98088_pga_inb1_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_PGA_E("INB2 Input", M98088_REG_4C_PWR_EN_IN,
- 6, 0, NULL, 0, max98088_pga_inb2_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_MICBIAS("MICBIAS", M98088_REG_4C_PWR_EN_IN, 3, 0),
-
- SND_SOC_DAPM_OUTPUT("HPL"),
- SND_SOC_DAPM_OUTPUT("HPR"),
- SND_SOC_DAPM_OUTPUT("SPKL"),
- SND_SOC_DAPM_OUTPUT("SPKR"),
- SND_SOC_DAPM_OUTPUT("RECL"),
- SND_SOC_DAPM_OUTPUT("RECR"),
-
- SND_SOC_DAPM_INPUT("MIC1"),
- SND_SOC_DAPM_INPUT("MIC2"),
- SND_SOC_DAPM_INPUT("INA1"),
- SND_SOC_DAPM_INPUT("INA2"),
- SND_SOC_DAPM_INPUT("INB1"),
- SND_SOC_DAPM_INPUT("INB2"),
-};
-
-static const struct snd_soc_dapm_route max98088_audio_map[] = {
- /* Left headphone output mixer */
- {"Left HP Mixer", "Left DAC1 Switch", "DACL1"},
- {"Left HP Mixer", "Left DAC2 Switch", "DACL2"},
- {"Left HP Mixer", "Right DAC1 Switch", "DACR1"},
- {"Left HP Mixer", "Right DAC2 Switch", "DACR2"},
- {"Left HP Mixer", "MIC1 Switch", "MIC1 Input"},
- {"Left HP Mixer", "MIC2 Switch", "MIC2 Input"},
- {"Left HP Mixer", "INA1 Switch", "INA1 Input"},
- {"Left HP Mixer", "INA2 Switch", "INA2 Input"},
- {"Left HP Mixer", "INB1 Switch", "INB1 Input"},
- {"Left HP Mixer", "INB2 Switch", "INB2 Input"},
-
- /* Right headphone output mixer */
- {"Right HP Mixer", "Left DAC1 Switch", "DACL1"},
- {"Right HP Mixer", "Left DAC2 Switch", "DACL2" },
- {"Right HP Mixer", "Right DAC1 Switch", "DACR1"},
- {"Right HP Mixer", "Right DAC2 Switch", "DACR2"},
- {"Right HP Mixer", "MIC1 Switch", "MIC1 Input"},
- {"Right HP Mixer", "MIC2 Switch", "MIC2 Input"},
- {"Right HP Mixer", "INA1 Switch", "INA1 Input"},
- {"Right HP Mixer", "INA2 Switch", "INA2 Input"},
- {"Right HP Mixer", "INB1 Switch", "INB1 Input"},
- {"Right HP Mixer", "INB2 Switch", "INB2 Input"},
-
- /* Left speaker output mixer */
- {"Left SPK Mixer", "Left DAC1 Switch", "DACL1"},
- {"Left SPK Mixer", "Left DAC2 Switch", "DACL2"},
- {"Left SPK Mixer", "Right DAC1 Switch", "DACR1"},
- {"Left SPK Mixer", "Right DAC2 Switch", "DACR2"},
- {"Left SPK Mixer", "MIC1 Switch", "MIC1 Input"},
- {"Left SPK Mixer", "MIC2 Switch", "MIC2 Input"},
- {"Left SPK Mixer", "INA1 Switch", "INA1 Input"},
- {"Left SPK Mixer", "INA2 Switch", "INA2 Input"},
- {"Left SPK Mixer", "INB1 Switch", "INB1 Input"},
- {"Left SPK Mixer", "INB2 Switch", "INB2 Input"},
-
- /* Right speaker output mixer */
- {"Right SPK Mixer", "Left DAC1 Switch", "DACL1"},
- {"Right SPK Mixer", "Left DAC2 Switch", "DACL2"},
- {"Right SPK Mixer", "Right DAC1 Switch", "DACR1"},
- {"Right SPK Mixer", "Right DAC2 Switch", "DACR2"},
- {"Right SPK Mixer", "MIC1 Switch", "MIC1 Input"},
- {"Right SPK Mixer", "MIC2 Switch", "MIC2 Input"},
- {"Right SPK Mixer", "INA1 Switch", "INA1 Input"},
- {"Right SPK Mixer", "INA2 Switch", "INA2 Input"},
- {"Right SPK Mixer", "INB1 Switch", "INB1 Input"},
- {"Right SPK Mixer", "INB2 Switch", "INB2 Input"},
-
- /* Earpiece/Receiver output mixer */
- {"Left REC Mixer", "Left DAC1 Switch", "DACL1"},
- {"Left REC Mixer", "Left DAC2 Switch", "DACL2"},
- {"Left REC Mixer", "Right DAC1 Switch", "DACR1"},
- {"Left REC Mixer", "Right DAC2 Switch", "DACR2"},
- {"Left REC Mixer", "MIC1 Switch", "MIC1 Input"},
- {"Left REC Mixer", "MIC2 Switch", "MIC2 Input"},
- {"Left REC Mixer", "INA1 Switch", "INA1 Input"},
- {"Left REC Mixer", "INA2 Switch", "INA2 Input"},
- {"Left REC Mixer", "INB1 Switch", "INB1 Input"},
- {"Left REC Mixer", "INB2 Switch", "INB2 Input"},
-
- /* Earpiece/Receiver output mixer */
- {"Right REC Mixer", "Left DAC1 Switch", "DACL1"},
- {"Right REC Mixer", "Left DAC2 Switch", "DACL2"},
- {"Right REC Mixer", "Right DAC1 Switch", "DACR1"},
- {"Right REC Mixer", "Right DAC2 Switch", "DACR2"},
- {"Right REC Mixer", "MIC1 Switch", "MIC1 Input"},
- {"Right REC Mixer", "MIC2 Switch", "MIC2 Input"},
- {"Right REC Mixer", "INA1 Switch", "INA1 Input"},
- {"Right REC Mixer", "INA2 Switch", "INA2 Input"},
- {"Right REC Mixer", "INB1 Switch", "INB1 Input"},
- {"Right REC Mixer", "INB2 Switch", "INB2 Input"},
-
- {"HP Left Out", NULL, "Left HP Mixer"},
- {"HP Right Out", NULL, "Right HP Mixer"},
- {"SPK Left Out", NULL, "Left SPK Mixer"},
- {"SPK Right Out", NULL, "Right SPK Mixer"},
- {"REC Left Out", NULL, "Left REC Mixer"},
- {"REC Right Out", NULL, "Right REC Mixer"},
-
- {"HPL", NULL, "HP Left Out"},
- {"HPR", NULL, "HP Right Out"},
- {"SPKL", NULL, "SPK Left Out"},
- {"SPKR", NULL, "SPK Right Out"},
- {"RECL", NULL, "REC Left Out"},
- {"RECR", NULL, "REC Right Out"},
-
- /* Left ADC input mixer */
- {"Left ADC Mixer", "MIC1 Switch", "MIC1 Input"},
- {"Left ADC Mixer", "MIC2 Switch", "MIC2 Input"},
- {"Left ADC Mixer", "INA1 Switch", "INA1 Input"},
- {"Left ADC Mixer", "INA2 Switch", "INA2 Input"},
- {"Left ADC Mixer", "INB1 Switch", "INB1 Input"},
- {"Left ADC Mixer", "INB2 Switch", "INB2 Input"},
-
- /* Right ADC input mixer */
- {"Right ADC Mixer", "MIC1 Switch", "MIC1 Input"},
- {"Right ADC Mixer", "MIC2 Switch", "MIC2 Input"},
- {"Right ADC Mixer", "INA1 Switch", "INA1 Input"},
- {"Right ADC Mixer", "INA2 Switch", "INA2 Input"},
- {"Right ADC Mixer", "INB1 Switch", "INB1 Input"},
- {"Right ADC Mixer", "INB2 Switch", "INB2 Input"},
-
- /* Inputs */
- {"ADCL", NULL, "Left ADC Mixer"},
- {"ADCR", NULL, "Right ADC Mixer"},
- {"INA1 Input", NULL, "INA1"},
- {"INA2 Input", NULL, "INA2"},
- {"INB1 Input", NULL, "INB1"},
- {"INB2 Input", NULL, "INB2"},
- {"MIC1 Input", NULL, "MIC1"},
- {"MIC2 Input", NULL, "MIC2"},
-};
-
-/* codec mclk clock divider coefficients */
-static const struct {
- u32 rate;
- u8 sr;
-} rate_table[] = {
- {8000, 0x10},
- {11025, 0x20},
- {16000, 0x30},
- {22050, 0x40},
- {24000, 0x50},
- {32000, 0x60},
- {44100, 0x70},
- {48000, 0x80},
- {88200, 0x90},
- {96000, 0xA0},
-};
-
-static inline int rate_value(int rate, u8 *value)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(rate_table); i++) {
- if (rate_table[i].rate >= rate) {
- *value = rate_table[i].sr;
- return 0;
- }
- }
- *value = rate_table[0].sr;
- return -EINVAL;
-}
-
-static int max98088_dai1_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
- struct max98088_cdata *cdata;
- unsigned long long ni;
- unsigned int rate;
- u8 regval;
-
- cdata = &max98088->dai[0];
-
- rate = params_rate(params);
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
- M98088_DAI_WS, 0);
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
- M98088_DAI_WS, M98088_DAI_WS);
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN, 0);
-
- if (rate_value(rate, &regval))
- return -EINVAL;
-
- snd_soc_update_bits(codec, M98088_REG_11_DAI1_CLKMODE,
- M98088_CLKMODE_MASK, regval);
- cdata->rate = rate;
-
- /* Configure NI when operating as master */
- if (snd_soc_read(codec, M98088_REG_14_DAI1_FORMAT)
- & M98088_DAI_MAS) {
- if (max98088->sysclk == 0) {
- dev_err(codec->dev, "Invalid system clock frequency\n");
- return -EINVAL;
- }
- ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
- * (unsigned long long int)rate;
- do_div(ni, (unsigned long long int)max98088->sysclk);
- snd_soc_write(codec, M98088_REG_12_DAI1_CLKCFG_HI,
- (ni >> 8) & 0x7F);
- snd_soc_write(codec, M98088_REG_13_DAI1_CLKCFG_LO,
- ni & 0xFF);
- }
-
- /* Update sample rate mode */
- if (rate < 50000)
- snd_soc_update_bits(codec, M98088_REG_18_DAI1_FILTERS,
- M98088_DAI_DHF, 0);
- else
- snd_soc_update_bits(codec, M98088_REG_18_DAI1_FILTERS,
- M98088_DAI_DHF, M98088_DAI_DHF);
-
- snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN,
- M98088_SHDNRUN);
-
- return 0;
-}
-
-static int max98088_dai2_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
- struct max98088_cdata *cdata;
- unsigned long long ni;
- unsigned int rate;
- u8 regval;
-
- cdata = &max98088->dai[1];
-
- rate = params_rate(params);
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- snd_soc_update_bits(codec, M98088_REG_1C_DAI2_FORMAT,
- M98088_DAI_WS, 0);
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- snd_soc_update_bits(codec, M98088_REG_1C_DAI2_FORMAT,
- M98088_DAI_WS, M98088_DAI_WS);
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN, 0);
-
- if (rate_value(rate, &regval))
- return -EINVAL;
-
- snd_soc_update_bits(codec, M98088_REG_19_DAI2_CLKMODE,
- M98088_CLKMODE_MASK, regval);
- cdata->rate = rate;
-
- /* Configure NI when operating as master */
- if (snd_soc_read(codec, M98088_REG_1C_DAI2_FORMAT)
- & M98088_DAI_MAS) {
- if (max98088->sysclk == 0) {
- dev_err(codec->dev, "Invalid system clock frequency\n");
- return -EINVAL;
- }
- ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
- * (unsigned long long int)rate;
- do_div(ni, (unsigned long long int)max98088->sysclk);
- snd_soc_write(codec, M98088_REG_1A_DAI2_CLKCFG_HI,
- (ni >> 8) & 0x7F);
- snd_soc_write(codec, M98088_REG_1B_DAI2_CLKCFG_LO,
- ni & 0xFF);
- }
-
- /* Update sample rate mode */
- if (rate < 50000)
- snd_soc_update_bits(codec, M98088_REG_20_DAI2_FILTERS,
- M98088_DAI_DHF, 0);
- else
- snd_soc_update_bits(codec, M98088_REG_20_DAI2_FILTERS,
- M98088_DAI_DHF, M98088_DAI_DHF);
-
- snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN,
- M98088_SHDNRUN);
-
- return 0;
-}
-
-static int max98088_dai_set_sysclk(struct snd_soc_dai *dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
-
- /* Requested clock frequency is already setup */
- if (freq == max98088->sysclk)
- return 0;
-
- /* Setup clocks for slave mode, and using the PLL
- * PSCLK = 0x01 (when master clk is 10MHz to 20MHz)
- * 0x02 (when master clk is 20MHz to 30MHz)..
- */
- if ((freq >= 10000000) && (freq < 20000000)) {
- snd_soc_write(codec, M98088_REG_10_SYS_CLK, 0x10);
- } else if ((freq >= 20000000) && (freq < 30000000)) {
- snd_soc_write(codec, M98088_REG_10_SYS_CLK, 0x20);
- } else {
- dev_err(codec->dev, "Invalid master clock frequency\n");
- return -EINVAL;
- }
-
- if (snd_soc_read(codec, M98088_REG_51_PWR_SYS) & M98088_SHDNRUN) {
- snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS,
- M98088_SHDNRUN, 0);
- snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS,
- M98088_SHDNRUN, M98088_SHDNRUN);
- }
-
- dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
-
- max98088->sysclk = freq;
- return 0;
-}
-
-static int max98088_dai1_set_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
- struct max98088_cdata *cdata;
- u8 reg15val;
- u8 reg14val = 0;
-
- cdata = &max98088->dai[0];
-
- if (fmt != cdata->fmt) {
- cdata->fmt = fmt;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- /* Slave mode PLL */
- snd_soc_write(codec, M98088_REG_12_DAI1_CLKCFG_HI,
- 0x80);
- snd_soc_write(codec, M98088_REG_13_DAI1_CLKCFG_LO,
- 0x00);
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- /* Set to master mode */
- reg14val |= M98088_DAI_MAS;
- break;
- case SND_SOC_DAIFMT_CBS_CFM:
- case SND_SOC_DAIFMT_CBM_CFS:
- default:
- dev_err(codec->dev, "Clock mode unsupported");
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- reg14val |= M98088_DAI_DLY;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_NB_IF:
- reg14val |= M98088_DAI_WCI;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- reg14val |= M98088_DAI_BCI;
- break;
- case SND_SOC_DAIFMT_IB_IF:
- reg14val |= M98088_DAI_BCI|M98088_DAI_WCI;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
- M98088_DAI_MAS | M98088_DAI_DLY | M98088_DAI_BCI |
- M98088_DAI_WCI, reg14val);
-
- reg15val = M98088_DAI_BSEL64;
- if (max98088->digmic)
- reg15val |= M98088_DAI_OSR64;
- snd_soc_write(codec, M98088_REG_15_DAI1_CLOCK, reg15val);
- }
-
- return 0;
-}
-
-static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
- struct max98088_cdata *cdata;
- u8 reg1Cval = 0;
-
- cdata = &max98088->dai[1];
-
- if (fmt != cdata->fmt) {
- cdata->fmt = fmt;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- /* Slave mode PLL */
- snd_soc_write(codec, M98088_REG_1A_DAI2_CLKCFG_HI,
- 0x80);
- snd_soc_write(codec, M98088_REG_1B_DAI2_CLKCFG_LO,
- 0x00);
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- /* Set to master mode */
- reg1Cval |= M98088_DAI_MAS;
- break;
- case SND_SOC_DAIFMT_CBS_CFM:
- case SND_SOC_DAIFMT_CBM_CFS:
- default:
- dev_err(codec->dev, "Clock mode unsupported");
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- reg1Cval |= M98088_DAI_DLY;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_NB_IF:
- reg1Cval |= M98088_DAI_WCI;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- reg1Cval |= M98088_DAI_BCI;
- break;
- case SND_SOC_DAIFMT_IB_IF:
- reg1Cval |= M98088_DAI_BCI|M98088_DAI_WCI;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, M98088_REG_1C_DAI2_FORMAT,
- M98088_DAI_MAS | M98088_DAI_DLY | M98088_DAI_BCI |
- M98088_DAI_WCI, reg1Cval);
-
- snd_soc_write(codec, M98088_REG_1D_DAI2_CLOCK,
- M98088_DAI_BSEL64);
- }
-
- return 0;
-}
-
-static int max98088_dai1_digital_mute(struct snd_soc_dai *codec_dai, int mute)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- int reg;
-
- if (mute)
- reg = M98088_DAI_MUTE;
- else
- reg = 0;
-
- snd_soc_update_bits(codec, M98088_REG_2F_LVL_DAI1_PLAY,
- M98088_DAI_MUTE_MASK, reg);
- return 0;
-}
-
-static int max98088_dai2_digital_mute(struct snd_soc_dai *codec_dai, int mute)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- int reg;
-
- if (mute)
- reg = M98088_DAI_MUTE;
- else
- reg = 0;
-
- snd_soc_update_bits(codec, M98088_REG_31_LVL_DAI2_PLAY,
- M98088_DAI_MUTE_MASK, reg);
- return 0;
-}
-
-static void max98088_sync_cache(struct snd_soc_codec *codec)
-{
- u16 *reg_cache = codec->reg_cache;
- int i;
-
- if (!codec->cache_sync)
- return;
-
- codec->cache_only = 0;
-
- /* write back cached values if they're writeable and
- * different from the hardware default.
- */
- for (i = 1; i < codec->driver->reg_cache_size; i++) {
- if (!max98088_access[i].writable)
- continue;
-
- if (reg_cache[i] == max98088_reg[i])
- continue;
-
- snd_soc_write(codec, i, reg_cache[i]);
- }
-
- codec->cache_sync = 0;
-}
-
-static int max98088_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
- max98088_sync_cache(codec);
-
- snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN,
- M98088_MBEN, M98088_MBEN);
- break;
-
- case SND_SOC_BIAS_OFF:
- snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN,
- M98088_MBEN, 0);
- codec->cache_sync = 1;
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define MAX98088_RATES SNDRV_PCM_RATE_8000_96000
-#define MAX98088_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops max98088_dai1_ops = {
- .set_sysclk = max98088_dai_set_sysclk,
- .set_fmt = max98088_dai1_set_fmt,
- .hw_params = max98088_dai1_hw_params,
- .digital_mute = max98088_dai1_digital_mute,
-};
-
-static const struct snd_soc_dai_ops max98088_dai2_ops = {
- .set_sysclk = max98088_dai_set_sysclk,
- .set_fmt = max98088_dai2_set_fmt,
- .hw_params = max98088_dai2_hw_params,
- .digital_mute = max98088_dai2_digital_mute,
-};
-
-static struct snd_soc_dai_driver max98088_dai[] = {
-{
- .name = "HiFi",
- .playback = {
- .stream_name = "HiFi Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = MAX98088_RATES,
- .formats = MAX98088_FORMATS,
- },
- .capture = {
- .stream_name = "HiFi Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = MAX98088_RATES,
- .formats = MAX98088_FORMATS,
- },
- .ops = &max98088_dai1_ops,
-},
-{
- .name = "Aux",
- .playback = {
- .stream_name = "Aux Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = MAX98088_RATES,
- .formats = MAX98088_FORMATS,
- },
- .ops = &max98088_dai2_ops,
-}
-};
-
-static const char *eq_mode_name[] = {"EQ1 Mode", "EQ2 Mode"};
-
-static int max98088_get_channel(struct snd_soc_codec *codec, const char *name)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(eq_mode_name); i++)
- if (strcmp(name, eq_mode_name[i]) == 0)
- return i;
-
- /* Shouldn't happen */
- dev_err(codec->dev, "Bad EQ channel name '%s'\n", name);
- return -EINVAL;
-}
-
-static void max98088_setup_eq1(struct snd_soc_codec *codec)
-{
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
- struct max98088_pdata *pdata = max98088->pdata;
- struct max98088_eq_cfg *coef_set;
- int best, best_val, save, i, sel, fs;
- struct max98088_cdata *cdata;
-
- cdata = &max98088->dai[0];
-
- if (!pdata || !max98088->eq_textcnt)
- return;
-
- /* Find the selected configuration with nearest sample rate */
- fs = cdata->rate;
- sel = cdata->eq_sel;
-
- best = 0;
- best_val = INT_MAX;
- for (i = 0; i < pdata->eq_cfgcnt; i++) {
- if (strcmp(pdata->eq_cfg[i].name, max98088->eq_texts[sel]) == 0 &&
- abs(pdata->eq_cfg[i].rate - fs) < best_val) {
- best = i;
- best_val = abs(pdata->eq_cfg[i].rate - fs);
- }
- }
-
- dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n",
- pdata->eq_cfg[best].name,
- pdata->eq_cfg[best].rate, fs);
-
- /* Disable EQ while configuring, and save current on/off state */
- save = snd_soc_read(codec, M98088_REG_49_CFG_LEVEL);
- snd_soc_update_bits(codec, M98088_REG_49_CFG_LEVEL, M98088_EQ1EN, 0);
-
- coef_set = &pdata->eq_cfg[sel];
-
- m98088_eq_band(codec, 0, 0, coef_set->band1);
- m98088_eq_band(codec, 0, 1, coef_set->band2);
- m98088_eq_band(codec, 0, 2, coef_set->band3);
- m98088_eq_band(codec, 0, 3, coef_set->band4);
- m98088_eq_band(codec, 0, 4, coef_set->band5);
-
- /* Restore the original on/off state */
- snd_soc_update_bits(codec, M98088_REG_49_CFG_LEVEL, M98088_EQ1EN, save);
-}
-
-static void max98088_setup_eq2(struct snd_soc_codec *codec)
-{
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
- struct max98088_pdata *pdata = max98088->pdata;
- struct max98088_eq_cfg *coef_set;
- int best, best_val, save, i, sel, fs;
- struct max98088_cdata *cdata;
-
- cdata = &max98088->dai[1];
-
- if (!pdata || !max98088->eq_textcnt)
- return;
-
- /* Find the selected configuration with nearest sample rate */
- fs = cdata->rate;
-
- sel = cdata->eq_sel;
- best = 0;
- best_val = INT_MAX;
- for (i = 0; i < pdata->eq_cfgcnt; i++) {
- if (strcmp(pdata->eq_cfg[i].name, max98088->eq_texts[sel]) == 0 &&
- abs(pdata->eq_cfg[i].rate - fs) < best_val) {
- best = i;
- best_val = abs(pdata->eq_cfg[i].rate - fs);
- }
- }
-
- dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n",
- pdata->eq_cfg[best].name,
- pdata->eq_cfg[best].rate, fs);
-
- /* Disable EQ while configuring, and save current on/off state */
- save = snd_soc_read(codec, M98088_REG_49_CFG_LEVEL);
- snd_soc_update_bits(codec, M98088_REG_49_CFG_LEVEL, M98088_EQ2EN, 0);
-
- coef_set = &pdata->eq_cfg[sel];
-
- m98088_eq_band(codec, 1, 0, coef_set->band1);
- m98088_eq_band(codec, 1, 1, coef_set->band2);
- m98088_eq_band(codec, 1, 2, coef_set->band3);
- m98088_eq_band(codec, 1, 3, coef_set->band4);
- m98088_eq_band(codec, 1, 4, coef_set->band5);
-
- /* Restore the original on/off state */
- snd_soc_update_bits(codec, M98088_REG_49_CFG_LEVEL, M98088_EQ2EN,
- save);
-}
-
-static int max98088_put_eq_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
- struct max98088_pdata *pdata = max98088->pdata;
- int channel = max98088_get_channel(codec, kcontrol->id.name);
- struct max98088_cdata *cdata;
- int sel = ucontrol->value.integer.value[0];
-
- if (channel < 0)
- return channel;
-
- cdata = &max98088->dai[channel];
-
- if (sel >= pdata->eq_cfgcnt)
- return -EINVAL;
-
- cdata->eq_sel = sel;
-
- switch (channel) {
- case 0:
- max98088_setup_eq1(codec);
- break;
- case 1:
- max98088_setup_eq2(codec);
- break;
- }
-
- return 0;
-}
-
-static int max98088_get_eq_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
- int channel = max98088_get_channel(codec, kcontrol->id.name);
- struct max98088_cdata *cdata;
-
- if (channel < 0)
- return channel;
-
- cdata = &max98088->dai[channel];
- ucontrol->value.enumerated.item[0] = cdata->eq_sel;
- return 0;
-}
-
-static void max98088_handle_eq_pdata(struct snd_soc_codec *codec)
-{
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
- struct max98088_pdata *pdata = max98088->pdata;
- struct max98088_eq_cfg *cfg;
- unsigned int cfgcnt;
- int i, j;
- const char **t;
- int ret;
- struct snd_kcontrol_new controls[] = {
- SOC_ENUM_EXT((char *)eq_mode_name[0],
- max98088->eq_enum,
- max98088_get_eq_enum,
- max98088_put_eq_enum),
- SOC_ENUM_EXT((char *)eq_mode_name[1],
- max98088->eq_enum,
- max98088_get_eq_enum,
- max98088_put_eq_enum),
- };
- BUILD_BUG_ON(ARRAY_SIZE(controls) != ARRAY_SIZE(eq_mode_name));
-
- cfg = pdata->eq_cfg;
- cfgcnt = pdata->eq_cfgcnt;
-
- /* Setup an array of texts for the equalizer enum.
- * This is based on Mark Brown's equalizer driver code.
- */
- max98088->eq_textcnt = 0;
- max98088->eq_texts = NULL;
- for (i = 0; i < cfgcnt; i++) {
- for (j = 0; j < max98088->eq_textcnt; j++) {
- if (strcmp(cfg[i].name, max98088->eq_texts[j]) == 0)
- break;
- }
-
- if (j != max98088->eq_textcnt)
- continue;
-
- /* Expand the array */
- t = krealloc(max98088->eq_texts,
- sizeof(char *) * (max98088->eq_textcnt + 1),
- GFP_KERNEL);
- if (t == NULL)
- continue;
-
- /* Store the new entry */
- t[max98088->eq_textcnt] = cfg[i].name;
- max98088->eq_textcnt++;
- max98088->eq_texts = t;
- }
-
- /* Now point the soc_enum to .texts array items */
- max98088->eq_enum.texts = max98088->eq_texts;
- max98088->eq_enum.max = max98088->eq_textcnt;
-
- ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
- if (ret != 0)
- dev_err(codec->dev, "Failed to add EQ control: %d\n", ret);
-}
-
-static void max98088_handle_pdata(struct snd_soc_codec *codec)
-{
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
- struct max98088_pdata *pdata = max98088->pdata;
- u8 regval = 0;
-
- if (!pdata) {
- dev_dbg(codec->dev, "No platform data\n");
- return;
- }
-
- /* Configure mic for analog/digital mic mode */
- if (pdata->digmic_left_mode)
- regval |= M98088_DIGMIC_L;
-
- if (pdata->digmic_right_mode)
- regval |= M98088_DIGMIC_R;
-
- max98088->digmic = (regval ? 1 : 0);
-
- snd_soc_write(codec, M98088_REG_48_CFG_MIC, regval);
-
- /* Configure receiver output */
- regval = ((pdata->receiver_mode) ? M98088_REC_LINEMODE : 0);
- snd_soc_update_bits(codec, M98088_REG_2A_MIC_REC_CNTL,
- M98088_REC_LINEMODE_MASK, regval);
-
- /* Configure equalizers */
- if (pdata->eq_cfgcnt)
- max98088_handle_eq_pdata(codec);
-}
-
-#ifdef CONFIG_PM
-static int max98088_suspend(struct snd_soc_codec *codec)
-{
- max98088_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int max98088_resume(struct snd_soc_codec *codec)
-{
- max98088_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-#else
-#define max98088_suspend NULL
-#define max98088_resume NULL
-#endif
-
-static int max98088_probe(struct snd_soc_codec *codec)
-{
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
- struct max98088_cdata *cdata;
- int ret = 0;
-
- codec->cache_sync = 1;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- /* initialize private data */
-
- max98088->sysclk = (unsigned)-1;
- max98088->eq_textcnt = 0;
-
- cdata = &max98088->dai[0];
- cdata->rate = (unsigned)-1;
- cdata->fmt = (unsigned)-1;
- cdata->eq_sel = 0;
-
- cdata = &max98088->dai[1];
- cdata->rate = (unsigned)-1;
- cdata->fmt = (unsigned)-1;
- cdata->eq_sel = 0;
-
- max98088->ina_state = 0;
- max98088->inb_state = 0;
- max98088->ex_mode = 0;
- max98088->digmic = 0;
- max98088->mic1pre = 0;
- max98088->mic2pre = 0;
-
- ret = snd_soc_read(codec, M98088_REG_FF_REV_ID);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to read device revision: %d\n",
- ret);
- goto err_access;
- }
- dev_info(codec->dev, "revision %c\n", ret + 'A');
-
- snd_soc_write(codec, M98088_REG_51_PWR_SYS, M98088_PWRSV);
-
- /* initialize registers cache to hardware default */
- max98088_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- snd_soc_write(codec, M98088_REG_0F_IRQ_ENABLE, 0x00);
-
- snd_soc_write(codec, M98088_REG_22_MIX_DAC,
- M98088_DAI1L_TO_DACL|M98088_DAI2L_TO_DACL|
- M98088_DAI1R_TO_DACR|M98088_DAI2R_TO_DACR);
-
- snd_soc_write(codec, M98088_REG_4E_BIAS_CNTL, 0xF0);
- snd_soc_write(codec, M98088_REG_50_DAC_BIAS2, 0x0F);
-
- snd_soc_write(codec, M98088_REG_16_DAI1_IOCFG,
- M98088_S1NORMAL|M98088_SDATA);
-
- snd_soc_write(codec, M98088_REG_1E_DAI2_IOCFG,
- M98088_S2NORMAL|M98088_SDATA);
-
- max98088_handle_pdata(codec);
-
- snd_soc_add_codec_controls(codec, max98088_snd_controls,
- ARRAY_SIZE(max98088_snd_controls));
-
-err_access:
- return ret;
-}
-
-static int max98088_remove(struct snd_soc_codec *codec)
-{
- struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
-
- max98088_set_bias_level(codec, SND_SOC_BIAS_OFF);
- kfree(max98088->eq_texts);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_max98088 = {
- .probe = max98088_probe,
- .remove = max98088_remove,
- .suspend = max98088_suspend,
- .resume = max98088_resume,
- .set_bias_level = max98088_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(max98088_reg),
- .reg_word_size = sizeof(u8),
- .reg_cache_default = max98088_reg,
- .volatile_register = max98088_volatile_register,
- .dapm_widgets = max98088_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(max98088_dapm_widgets),
- .dapm_routes = max98088_audio_map,
- .num_dapm_routes = ARRAY_SIZE(max98088_audio_map),
-};
-
-static int max98088_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct max98088_priv *max98088;
- int ret;
-
- max98088 = devm_kzalloc(&i2c->dev, sizeof(struct max98088_priv),
- GFP_KERNEL);
- if (max98088 == NULL)
- return -ENOMEM;
-
- max98088->devtype = id->driver_data;
-
- i2c_set_clientdata(i2c, max98088);
- max98088->pdata = i2c->dev.platform_data;
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_max98088, &max98088_dai[0], 2);
- return ret;
-}
-
-static int __devexit max98088_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static const struct i2c_device_id max98088_i2c_id[] = {
- { "max98088", MAX98088 },
- { "max98089", MAX98089 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, max98088_i2c_id);
-
-static struct i2c_driver max98088_i2c_driver = {
- .driver = {
- .name = "max98088",
- .owner = THIS_MODULE,
- },
- .probe = max98088_i2c_probe,
- .remove = __devexit_p(max98088_i2c_remove),
- .id_table = max98088_i2c_id,
-};
-
-static int __init max98088_init(void)
-{
- int ret;
-
- ret = i2c_add_driver(&max98088_i2c_driver);
- if (ret)
- pr_err("Failed to register max98088 I2C driver: %d\n", ret);
-
- return ret;
-}
-module_init(max98088_init);
-
-static void __exit max98088_exit(void)
-{
- i2c_del_driver(&max98088_i2c_driver);
-}
-module_exit(max98088_exit);
-
-MODULE_DESCRIPTION("ALSA SoC MAX98088 driver");
-MODULE_AUTHOR("Peter Hsiang, Jesse Marroquin");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/max98088.h b/ANDROID_3.4.5/sound/soc/codecs/max98088.h
deleted file mode 100644
index be89a4f4..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/max98088.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * max98088.h -- MAX98088 ALSA SoC Audio driver
- *
- * Copyright 2010 Maxim Integrated Products
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _MAX98088_H
-#define _MAX98088_H
-
-/*
- * MAX98088 Registers Definition
- */
-#define M98088_REG_00_IRQ_STATUS 0x00
-#define M98088_REG_01_MIC_STATUS 0x01
-#define M98088_REG_02_JACK_STAUS 0x02
-#define M98088_REG_03_BATTERY_VOLTAGE 0x03
-#define M98088_REG_0F_IRQ_ENABLE 0x0F
-#define M98088_REG_10_SYS_CLK 0x10
-#define M98088_REG_11_DAI1_CLKMODE 0x11
-#define M98088_REG_12_DAI1_CLKCFG_HI 0x12
-#define M98088_REG_13_DAI1_CLKCFG_LO 0x13
-#define M98088_REG_14_DAI1_FORMAT 0x14
-#define M98088_REG_15_DAI1_CLOCK 0x15
-#define M98088_REG_16_DAI1_IOCFG 0x16
-#define M98088_REG_17_DAI1_TDM 0x17
-#define M98088_REG_18_DAI1_FILTERS 0x18
-#define M98088_REG_19_DAI2_CLKMODE 0x19
-#define M98088_REG_1A_DAI2_CLKCFG_HI 0x1A
-#define M98088_REG_1B_DAI2_CLKCFG_LO 0x1B
-#define M98088_REG_1C_DAI2_FORMAT 0x1C
-#define M98088_REG_1D_DAI2_CLOCK 0x1D
-#define M98088_REG_1E_DAI2_IOCFG 0x1E
-#define M98088_REG_1F_DAI2_TDM 0x1F
-#define M98088_REG_20_DAI2_FILTERS 0x20
-#define M98088_REG_21_SRC 0x21
-#define M98088_REG_22_MIX_DAC 0x22
-#define M98088_REG_23_MIX_ADC_LEFT 0x23
-#define M98088_REG_24_MIX_ADC_RIGHT 0x24
-#define M98088_REG_25_MIX_HP_LEFT 0x25
-#define M98088_REG_26_MIX_HP_RIGHT 0x26
-#define M98088_REG_27_MIX_HP_CNTL 0x27
-#define M98088_REG_28_MIX_REC_LEFT 0x28
-#define M98088_REG_29_MIX_REC_RIGHT 0x29
-#define M98088_REG_2A_MIC_REC_CNTL 0x2A
-#define M98088_REG_2B_MIX_SPK_LEFT 0x2B
-#define M98088_REG_2C_MIX_SPK_RIGHT 0x2C
-#define M98088_REG_2D_MIX_SPK_CNTL 0x2D
-#define M98088_REG_2E_LVL_SIDETONE 0x2E
-#define M98088_REG_2F_LVL_DAI1_PLAY 0x2F
-#define M98088_REG_30_LVL_DAI1_PLAY_EQ 0x30
-#define M98088_REG_31_LVL_DAI2_PLAY 0x31
-#define M98088_REG_32_LVL_DAI2_PLAY_EQ 0x32
-#define M98088_REG_33_LVL_ADC_L 0x33
-#define M98088_REG_34_LVL_ADC_R 0x34
-#define M98088_REG_35_LVL_MIC1 0x35
-#define M98088_REG_36_LVL_MIC2 0x36
-#define M98088_REG_37_LVL_INA 0x37
-#define M98088_REG_38_LVL_INB 0x38
-#define M98088_REG_39_LVL_HP_L 0x39
-#define M98088_REG_3A_LVL_HP_R 0x3A
-#define M98088_REG_3B_LVL_REC_L 0x3B
-#define M98088_REG_3C_LVL_REC_R 0x3C
-#define M98088_REG_3D_LVL_SPK_L 0x3D
-#define M98088_REG_3E_LVL_SPK_R 0x3E
-#define M98088_REG_3F_MICAGC_CFG 0x3F
-#define M98088_REG_40_MICAGC_THRESH 0x40
-#define M98088_REG_41_SPKDHP 0x41
-#define M98088_REG_42_SPKDHP_THRESH 0x42
-#define M98088_REG_43_SPKALC_COMP 0x43
-#define M98088_REG_44_PWRLMT_CFG 0x44
-#define M98088_REG_45_PWRLMT_TIME 0x45
-#define M98088_REG_46_THDLMT_CFG 0x46
-#define M98088_REG_47_CFG_AUDIO_IN 0x47
-#define M98088_REG_48_CFG_MIC 0x48
-#define M98088_REG_49_CFG_LEVEL 0x49
-#define M98088_REG_4A_CFG_BYPASS 0x4A
-#define M98088_REG_4B_CFG_JACKDET 0x4B
-#define M98088_REG_4C_PWR_EN_IN 0x4C
-#define M98088_REG_4D_PWR_EN_OUT 0x4D
-#define M98088_REG_4E_BIAS_CNTL 0x4E
-#define M98088_REG_4F_DAC_BIAS1 0x4F
-#define M98088_REG_50_DAC_BIAS2 0x50
-#define M98088_REG_51_PWR_SYS 0x51
-#define M98088_REG_52_DAI1_EQ_BASE 0x52
-#define M98088_REG_84_DAI2_EQ_BASE 0x84
-#define M98088_REG_B6_DAI1_BIQUAD_BASE 0xB6
-#define M98088_REG_C0_DAI2_BIQUAD_BASE 0xC0
-#define M98088_REG_FF_REV_ID 0xFF
-
-#define M98088_REG_CNT (0xFF+1)
-
-/* MAX98088 Registers Bit Fields */
-
-/* M98088_REG_11_DAI1_CLKMODE, M98088_REG_19_DAI2_CLKMODE */
- #define M98088_CLKMODE_MASK 0xFF
-
-/* M98088_REG_14_DAI1_FORMAT, M98088_REG_1C_DAI2_FORMAT */
- #define M98088_DAI_MAS (1<<7)
- #define M98088_DAI_WCI (1<<6)
- #define M98088_DAI_BCI (1<<5)
- #define M98088_DAI_DLY (1<<4)
- #define M98088_DAI_TDM (1<<2)
- #define M98088_DAI_FSW (1<<1)
- #define M98088_DAI_WS (1<<0)
-
-/* M98088_REG_15_DAI1_CLOCK, M98088_REG_1D_DAI2_CLOCK */
- #define M98088_DAI_BSEL64 (1<<0)
- #define M98088_DAI_OSR64 (1<<6)
-
-/* M98088_REG_16_DAI1_IOCFG, M98088_REG_1E_DAI2_IOCFG */
- #define M98088_S1NORMAL (1<<6)
- #define M98088_S2NORMAL (2<<6)
- #define M98088_SDATA (3<<0)
-
-/* M98088_REG_18_DAI1_FILTERS, M98088_REG_20_DAI2_FILTERS */
- #define M98088_DAI_DHF (1<<3)
-
-/* M98088_REG_22_MIX_DAC */
- #define M98088_DAI1L_TO_DACL (1<<7)
- #define M98088_DAI1R_TO_DACL (1<<6)
- #define M98088_DAI2L_TO_DACL (1<<5)
- #define M98088_DAI2R_TO_DACL (1<<4)
- #define M98088_DAI1L_TO_DACR (1<<3)
- #define M98088_DAI1R_TO_DACR (1<<2)
- #define M98088_DAI2L_TO_DACR (1<<1)
- #define M98088_DAI2R_TO_DACR (1<<0)
-
-/* M98088_REG_2A_MIC_REC_CNTL */
- #define M98088_REC_LINEMODE (1<<7)
- #define M98088_REC_LINEMODE_MASK (1<<7)
-
-/* M98088_REG_2D_MIX_SPK_CNTL */
- #define M98088_MIX_SPKR_GAIN_MASK (3<<2)
- #define M98088_MIX_SPKR_GAIN_SHIFT 2
- #define M98088_MIX_SPKL_GAIN_MASK (3<<0)
- #define M98088_MIX_SPKL_GAIN_SHIFT 0
-
-/* M98088_REG_2F_LVL_DAI1_PLAY, M98088_REG_31_LVL_DAI2_PLAY */
- #define M98088_DAI_MUTE (1<<7)
- #define M98088_DAI_MUTE_MASK (1<<7)
- #define M98088_DAI_VOICE_GAIN_MASK (3<<4)
- #define M98088_DAI_ATTENUATION_MASK (0xF<<0)
- #define M98088_DAI_ATTENUATION_SHIFT 0
-
-/* M98088_REG_35_LVL_MIC1, M98088_REG_36_LVL_MIC2 */
- #define M98088_MICPRE_MASK (3<<5)
- #define M98088_MICPRE_SHIFT 5
-
-/* M98088_REG_3A_LVL_HP_R */
- #define M98088_HP_MUTE (1<<7)
-
-/* M98088_REG_3C_LVL_REC_R */
- #define M98088_REC_MUTE (1<<7)
-
-/* M98088_REG_3E_LVL_SPK_R */
- #define M98088_SP_MUTE (1<<7)
-
-/* M98088_REG_48_CFG_MIC */
- #define M98088_EXTMIC_MASK (3<<0)
- #define M98088_DIGMIC_L (1<<5)
- #define M98088_DIGMIC_R (1<<4)
-
-/* M98088_REG_49_CFG_LEVEL */
- #define M98088_VSEN (1<<6)
- #define M98088_ZDEN (1<<5)
- #define M98088_EQ2EN (1<<1)
- #define M98088_EQ1EN (1<<0)
-
-/* M98088_REG_4C_PWR_EN_IN */
- #define M98088_INAEN (1<<7)
- #define M98088_INBEN (1<<6)
- #define M98088_MBEN (1<<3)
- #define M98088_ADLEN (1<<1)
- #define M98088_ADREN (1<<0)
-
-/* M98088_REG_4D_PWR_EN_OUT */
- #define M98088_HPLEN (1<<7)
- #define M98088_HPREN (1<<6)
- #define M98088_HPEN ((1<<7)|(1<<6))
- #define M98088_SPLEN (1<<5)
- #define M98088_SPREN (1<<4)
- #define M98088_RECEN (1<<3)
- #define M98088_DALEN (1<<1)
- #define M98088_DAREN (1<<0)
-
-/* M98088_REG_51_PWR_SYS */
- #define M98088_SHDNRUN (1<<7)
- #define M98088_PERFMODE (1<<3)
- #define M98088_HPPLYBACK (1<<2)
- #define M98088_PWRSV8K (1<<1)
- #define M98088_PWRSV (1<<0)
-
-/* Line inputs */
-#define LINE_INA 0
-#define LINE_INB 1
-
-#define M98088_COEFS_PER_BAND 5
-
-#define M98088_BYTE1(w) ((w >> 8) & 0xff)
-#define M98088_BYTE0(w) (w & 0xff)
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/max98095.c b/ANDROID_3.4.5/sound/soc/codecs/max98095.c
deleted file mode 100644
index 0bb511a0..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/max98095.c
+++ /dev/null
@@ -1,2399 +0,0 @@
-/*
- * max98095.c -- MAX98095 ALSA SoC Audio driver
- *
- * Copyright 2011 Maxim Integrated Products
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <linux/slab.h>
-#include <asm/div64.h>
-#include <sound/max98095.h>
-#include "max98095.h"
-
-enum max98095_type {
- MAX98095,
-};
-
-struct max98095_cdata {
- unsigned int rate;
- unsigned int fmt;
- int eq_sel;
- int bq_sel;
-};
-
-struct max98095_priv {
- enum max98095_type devtype;
- struct max98095_pdata *pdata;
- unsigned int sysclk;
- struct max98095_cdata dai[3];
- const char **eq_texts;
- const char **bq_texts;
- struct soc_enum eq_enum;
- struct soc_enum bq_enum;
- int eq_textcnt;
- int bq_textcnt;
- u8 lin_state;
- unsigned int mic1pre;
- unsigned int mic2pre;
-};
-
-static const u8 max98095_reg_def[M98095_REG_CNT] = {
- 0x00, /* 00 */
- 0x00, /* 01 */
- 0x00, /* 02 */
- 0x00, /* 03 */
- 0x00, /* 04 */
- 0x00, /* 05 */
- 0x00, /* 06 */
- 0x00, /* 07 */
- 0x00, /* 08 */
- 0x00, /* 09 */
- 0x00, /* 0A */
- 0x00, /* 0B */
- 0x00, /* 0C */
- 0x00, /* 0D */
- 0x00, /* 0E */
- 0x00, /* 0F */
- 0x00, /* 10 */
- 0x00, /* 11 */
- 0x00, /* 12 */
- 0x00, /* 13 */
- 0x00, /* 14 */
- 0x00, /* 15 */
- 0x00, /* 16 */
- 0x00, /* 17 */
- 0x00, /* 18 */
- 0x00, /* 19 */
- 0x00, /* 1A */
- 0x00, /* 1B */
- 0x00, /* 1C */
- 0x00, /* 1D */
- 0x00, /* 1E */
- 0x00, /* 1F */
- 0x00, /* 20 */
- 0x00, /* 21 */
- 0x00, /* 22 */
- 0x00, /* 23 */
- 0x00, /* 24 */
- 0x00, /* 25 */
- 0x00, /* 26 */
- 0x00, /* 27 */
- 0x00, /* 28 */
- 0x00, /* 29 */
- 0x00, /* 2A */
- 0x00, /* 2B */
- 0x00, /* 2C */
- 0x00, /* 2D */
- 0x00, /* 2E */
- 0x00, /* 2F */
- 0x00, /* 30 */
- 0x00, /* 31 */
- 0x00, /* 32 */
- 0x00, /* 33 */
- 0x00, /* 34 */
- 0x00, /* 35 */
- 0x00, /* 36 */
- 0x00, /* 37 */
- 0x00, /* 38 */
- 0x00, /* 39 */
- 0x00, /* 3A */
- 0x00, /* 3B */
- 0x00, /* 3C */
- 0x00, /* 3D */
- 0x00, /* 3E */
- 0x00, /* 3F */
- 0x00, /* 40 */
- 0x00, /* 41 */
- 0x00, /* 42 */
- 0x00, /* 43 */
- 0x00, /* 44 */
- 0x00, /* 45 */
- 0x00, /* 46 */
- 0x00, /* 47 */
- 0x00, /* 48 */
- 0x00, /* 49 */
- 0x00, /* 4A */
- 0x00, /* 4B */
- 0x00, /* 4C */
- 0x00, /* 4D */
- 0x00, /* 4E */
- 0x00, /* 4F */
- 0x00, /* 50 */
- 0x00, /* 51 */
- 0x00, /* 52 */
- 0x00, /* 53 */
- 0x00, /* 54 */
- 0x00, /* 55 */
- 0x00, /* 56 */
- 0x00, /* 57 */
- 0x00, /* 58 */
- 0x00, /* 59 */
- 0x00, /* 5A */
- 0x00, /* 5B */
- 0x00, /* 5C */
- 0x00, /* 5D */
- 0x00, /* 5E */
- 0x00, /* 5F */
- 0x00, /* 60 */
- 0x00, /* 61 */
- 0x00, /* 62 */
- 0x00, /* 63 */
- 0x00, /* 64 */
- 0x00, /* 65 */
- 0x00, /* 66 */
- 0x00, /* 67 */
- 0x00, /* 68 */
- 0x00, /* 69 */
- 0x00, /* 6A */
- 0x00, /* 6B */
- 0x00, /* 6C */
- 0x00, /* 6D */
- 0x00, /* 6E */
- 0x00, /* 6F */
- 0x00, /* 70 */
- 0x00, /* 71 */
- 0x00, /* 72 */
- 0x00, /* 73 */
- 0x00, /* 74 */
- 0x00, /* 75 */
- 0x00, /* 76 */
- 0x00, /* 77 */
- 0x00, /* 78 */
- 0x00, /* 79 */
- 0x00, /* 7A */
- 0x00, /* 7B */
- 0x00, /* 7C */
- 0x00, /* 7D */
- 0x00, /* 7E */
- 0x00, /* 7F */
- 0x00, /* 80 */
- 0x00, /* 81 */
- 0x00, /* 82 */
- 0x00, /* 83 */
- 0x00, /* 84 */
- 0x00, /* 85 */
- 0x00, /* 86 */
- 0x00, /* 87 */
- 0x00, /* 88 */
- 0x00, /* 89 */
- 0x00, /* 8A */
- 0x00, /* 8B */
- 0x00, /* 8C */
- 0x00, /* 8D */
- 0x00, /* 8E */
- 0x00, /* 8F */
- 0x00, /* 90 */
- 0x00, /* 91 */
- 0x30, /* 92 */
- 0xF0, /* 93 */
- 0x00, /* 94 */
- 0x00, /* 95 */
- 0x3F, /* 96 */
- 0x00, /* 97 */
- 0x00, /* 98 */
- 0x00, /* 99 */
- 0x00, /* 9A */
- 0x00, /* 9B */
- 0x00, /* 9C */
- 0x00, /* 9D */
- 0x00, /* 9E */
- 0x00, /* 9F */
- 0x00, /* A0 */
- 0x00, /* A1 */
- 0x00, /* A2 */
- 0x00, /* A3 */
- 0x00, /* A4 */
- 0x00, /* A5 */
- 0x00, /* A6 */
- 0x00, /* A7 */
- 0x00, /* A8 */
- 0x00, /* A9 */
- 0x00, /* AA */
- 0x00, /* AB */
- 0x00, /* AC */
- 0x00, /* AD */
- 0x00, /* AE */
- 0x00, /* AF */
- 0x00, /* B0 */
- 0x00, /* B1 */
- 0x00, /* B2 */
- 0x00, /* B3 */
- 0x00, /* B4 */
- 0x00, /* B5 */
- 0x00, /* B6 */
- 0x00, /* B7 */
- 0x00, /* B8 */
- 0x00, /* B9 */
- 0x00, /* BA */
- 0x00, /* BB */
- 0x00, /* BC */
- 0x00, /* BD */
- 0x00, /* BE */
- 0x00, /* BF */
- 0x00, /* C0 */
- 0x00, /* C1 */
- 0x00, /* C2 */
- 0x00, /* C3 */
- 0x00, /* C4 */
- 0x00, /* C5 */
- 0x00, /* C6 */
- 0x00, /* C7 */
- 0x00, /* C8 */
- 0x00, /* C9 */
- 0x00, /* CA */
- 0x00, /* CB */
- 0x00, /* CC */
- 0x00, /* CD */
- 0x00, /* CE */
- 0x00, /* CF */
- 0x00, /* D0 */
- 0x00, /* D1 */
- 0x00, /* D2 */
- 0x00, /* D3 */
- 0x00, /* D4 */
- 0x00, /* D5 */
- 0x00, /* D6 */
- 0x00, /* D7 */
- 0x00, /* D8 */
- 0x00, /* D9 */
- 0x00, /* DA */
- 0x00, /* DB */
- 0x00, /* DC */
- 0x00, /* DD */
- 0x00, /* DE */
- 0x00, /* DF */
- 0x00, /* E0 */
- 0x00, /* E1 */
- 0x00, /* E2 */
- 0x00, /* E3 */
- 0x00, /* E4 */
- 0x00, /* E5 */
- 0x00, /* E6 */
- 0x00, /* E7 */
- 0x00, /* E8 */
- 0x00, /* E9 */
- 0x00, /* EA */
- 0x00, /* EB */
- 0x00, /* EC */
- 0x00, /* ED */
- 0x00, /* EE */
- 0x00, /* EF */
- 0x00, /* F0 */
- 0x00, /* F1 */
- 0x00, /* F2 */
- 0x00, /* F3 */
- 0x00, /* F4 */
- 0x00, /* F5 */
- 0x00, /* F6 */
- 0x00, /* F7 */
- 0x00, /* F8 */
- 0x00, /* F9 */
- 0x00, /* FA */
- 0x00, /* FB */
- 0x00, /* FC */
- 0x00, /* FD */
- 0x00, /* FE */
- 0x00, /* FF */
-};
-
-static struct {
- int readable;
- int writable;
-} max98095_access[M98095_REG_CNT] = {
- { 0x00, 0x00 }, /* 00 */
- { 0xFF, 0x00 }, /* 01 */
- { 0xFF, 0x00 }, /* 02 */
- { 0xFF, 0x00 }, /* 03 */
- { 0xFF, 0x00 }, /* 04 */
- { 0xFF, 0x00 }, /* 05 */
- { 0xFF, 0x00 }, /* 06 */
- { 0xFF, 0x00 }, /* 07 */
- { 0xFF, 0x00 }, /* 08 */
- { 0xFF, 0x00 }, /* 09 */
- { 0xFF, 0x00 }, /* 0A */
- { 0xFF, 0x00 }, /* 0B */
- { 0xFF, 0x00 }, /* 0C */
- { 0xFF, 0x00 }, /* 0D */
- { 0xFF, 0x00 }, /* 0E */
- { 0xFF, 0x9F }, /* 0F */
- { 0xFF, 0xFF }, /* 10 */
- { 0xFF, 0xFF }, /* 11 */
- { 0xFF, 0xFF }, /* 12 */
- { 0xFF, 0xFF }, /* 13 */
- { 0xFF, 0xFF }, /* 14 */
- { 0xFF, 0xFF }, /* 15 */
- { 0xFF, 0xFF }, /* 16 */
- { 0xFF, 0xFF }, /* 17 */
- { 0xFF, 0xFF }, /* 18 */
- { 0xFF, 0xFF }, /* 19 */
- { 0xFF, 0xFF }, /* 1A */
- { 0xFF, 0xFF }, /* 1B */
- { 0xFF, 0xFF }, /* 1C */
- { 0xFF, 0xFF }, /* 1D */
- { 0xFF, 0x77 }, /* 1E */
- { 0xFF, 0x77 }, /* 1F */
- { 0xFF, 0x77 }, /* 20 */
- { 0xFF, 0x77 }, /* 21 */
- { 0xFF, 0x77 }, /* 22 */
- { 0xFF, 0x77 }, /* 23 */
- { 0xFF, 0xFF }, /* 24 */
- { 0xFF, 0x7F }, /* 25 */
- { 0xFF, 0x31 }, /* 26 */
- { 0xFF, 0xFF }, /* 27 */
- { 0xFF, 0xFF }, /* 28 */
- { 0xFF, 0xFF }, /* 29 */
- { 0xFF, 0xF7 }, /* 2A */
- { 0xFF, 0x2F }, /* 2B */
- { 0xFF, 0xEF }, /* 2C */
- { 0xFF, 0xFF }, /* 2D */
- { 0xFF, 0xFF }, /* 2E */
- { 0xFF, 0xFF }, /* 2F */
- { 0xFF, 0xFF }, /* 30 */
- { 0xFF, 0xFF }, /* 31 */
- { 0xFF, 0xFF }, /* 32 */
- { 0xFF, 0xFF }, /* 33 */
- { 0xFF, 0xF7 }, /* 34 */
- { 0xFF, 0x2F }, /* 35 */
- { 0xFF, 0xCF }, /* 36 */
- { 0xFF, 0xFF }, /* 37 */
- { 0xFF, 0xFF }, /* 38 */
- { 0xFF, 0xFF }, /* 39 */
- { 0xFF, 0xFF }, /* 3A */
- { 0xFF, 0xFF }, /* 3B */
- { 0xFF, 0xFF }, /* 3C */
- { 0xFF, 0xFF }, /* 3D */
- { 0xFF, 0xF7 }, /* 3E */
- { 0xFF, 0x2F }, /* 3F */
- { 0xFF, 0xCF }, /* 40 */
- { 0xFF, 0xFF }, /* 41 */
- { 0xFF, 0x77 }, /* 42 */
- { 0xFF, 0xFF }, /* 43 */
- { 0xFF, 0xFF }, /* 44 */
- { 0xFF, 0xFF }, /* 45 */
- { 0xFF, 0xFF }, /* 46 */
- { 0xFF, 0xFF }, /* 47 */
- { 0xFF, 0xFF }, /* 48 */
- { 0xFF, 0x0F }, /* 49 */
- { 0xFF, 0xFF }, /* 4A */
- { 0xFF, 0xFF }, /* 4B */
- { 0xFF, 0x3F }, /* 4C */
- { 0xFF, 0x3F }, /* 4D */
- { 0xFF, 0x3F }, /* 4E */
- { 0xFF, 0xFF }, /* 4F */
- { 0xFF, 0x7F }, /* 50 */
- { 0xFF, 0x7F }, /* 51 */
- { 0xFF, 0x0F }, /* 52 */
- { 0xFF, 0x3F }, /* 53 */
- { 0xFF, 0x3F }, /* 54 */
- { 0xFF, 0x3F }, /* 55 */
- { 0xFF, 0xFF }, /* 56 */
- { 0xFF, 0xFF }, /* 57 */
- { 0xFF, 0xBF }, /* 58 */
- { 0xFF, 0x1F }, /* 59 */
- { 0xFF, 0xBF }, /* 5A */
- { 0xFF, 0x1F }, /* 5B */
- { 0xFF, 0xBF }, /* 5C */
- { 0xFF, 0x3F }, /* 5D */
- { 0xFF, 0x3F }, /* 5E */
- { 0xFF, 0x7F }, /* 5F */
- { 0xFF, 0x7F }, /* 60 */
- { 0xFF, 0x47 }, /* 61 */
- { 0xFF, 0x9F }, /* 62 */
- { 0xFF, 0x9F }, /* 63 */
- { 0xFF, 0x9F }, /* 64 */
- { 0xFF, 0x9F }, /* 65 */
- { 0xFF, 0x9F }, /* 66 */
- { 0xFF, 0xBF }, /* 67 */
- { 0xFF, 0xBF }, /* 68 */
- { 0xFF, 0xFF }, /* 69 */
- { 0xFF, 0xFF }, /* 6A */
- { 0xFF, 0x7F }, /* 6B */
- { 0xFF, 0xF7 }, /* 6C */
- { 0xFF, 0xFF }, /* 6D */
- { 0xFF, 0xFF }, /* 6E */
- { 0xFF, 0x1F }, /* 6F */
- { 0xFF, 0xF7 }, /* 70 */
- { 0xFF, 0xFF }, /* 71 */
- { 0xFF, 0xFF }, /* 72 */
- { 0xFF, 0x1F }, /* 73 */
- { 0xFF, 0xF7 }, /* 74 */
- { 0xFF, 0xFF }, /* 75 */
- { 0xFF, 0xFF }, /* 76 */
- { 0xFF, 0x1F }, /* 77 */
- { 0xFF, 0xF7 }, /* 78 */
- { 0xFF, 0xFF }, /* 79 */
- { 0xFF, 0xFF }, /* 7A */
- { 0xFF, 0x1F }, /* 7B */
- { 0xFF, 0xF7 }, /* 7C */
- { 0xFF, 0xFF }, /* 7D */
- { 0xFF, 0xFF }, /* 7E */
- { 0xFF, 0x1F }, /* 7F */
- { 0xFF, 0xF7 }, /* 80 */
- { 0xFF, 0xFF }, /* 81 */
- { 0xFF, 0xFF }, /* 82 */
- { 0xFF, 0x1F }, /* 83 */
- { 0xFF, 0x7F }, /* 84 */
- { 0xFF, 0x0F }, /* 85 */
- { 0xFF, 0xD8 }, /* 86 */
- { 0xFF, 0xFF }, /* 87 */
- { 0xFF, 0xEF }, /* 88 */
- { 0xFF, 0xFE }, /* 89 */
- { 0xFF, 0xFE }, /* 8A */
- { 0xFF, 0xFF }, /* 8B */
- { 0xFF, 0xFF }, /* 8C */
- { 0xFF, 0x3F }, /* 8D */
- { 0xFF, 0xFF }, /* 8E */
- { 0xFF, 0x3F }, /* 8F */
- { 0xFF, 0x8F }, /* 90 */
- { 0xFF, 0xFF }, /* 91 */
- { 0xFF, 0x3F }, /* 92 */
- { 0xFF, 0xFF }, /* 93 */
- { 0xFF, 0xFF }, /* 94 */
- { 0xFF, 0x0F }, /* 95 */
- { 0xFF, 0x3F }, /* 96 */
- { 0xFF, 0x8C }, /* 97 */
- { 0x00, 0x00 }, /* 98 */
- { 0x00, 0x00 }, /* 99 */
- { 0x00, 0x00 }, /* 9A */
- { 0x00, 0x00 }, /* 9B */
- { 0x00, 0x00 }, /* 9C */
- { 0x00, 0x00 }, /* 9D */
- { 0x00, 0x00 }, /* 9E */
- { 0x00, 0x00 }, /* 9F */
- { 0x00, 0x00 }, /* A0 */
- { 0x00, 0x00 }, /* A1 */
- { 0x00, 0x00 }, /* A2 */
- { 0x00, 0x00 }, /* A3 */
- { 0x00, 0x00 }, /* A4 */
- { 0x00, 0x00 }, /* A5 */
- { 0x00, 0x00 }, /* A6 */
- { 0x00, 0x00 }, /* A7 */
- { 0x00, 0x00 }, /* A8 */
- { 0x00, 0x00 }, /* A9 */
- { 0x00, 0x00 }, /* AA */
- { 0x00, 0x00 }, /* AB */
- { 0x00, 0x00 }, /* AC */
- { 0x00, 0x00 }, /* AD */
- { 0x00, 0x00 }, /* AE */
- { 0x00, 0x00 }, /* AF */
- { 0x00, 0x00 }, /* B0 */
- { 0x00, 0x00 }, /* B1 */
- { 0x00, 0x00 }, /* B2 */
- { 0x00, 0x00 }, /* B3 */
- { 0x00, 0x00 }, /* B4 */
- { 0x00, 0x00 }, /* B5 */
- { 0x00, 0x00 }, /* B6 */
- { 0x00, 0x00 }, /* B7 */
- { 0x00, 0x00 }, /* B8 */
- { 0x00, 0x00 }, /* B9 */
- { 0x00, 0x00 }, /* BA */
- { 0x00, 0x00 }, /* BB */
- { 0x00, 0x00 }, /* BC */
- { 0x00, 0x00 }, /* BD */
- { 0x00, 0x00 }, /* BE */
- { 0x00, 0x00 }, /* BF */
- { 0x00, 0x00 }, /* C0 */
- { 0x00, 0x00 }, /* C1 */
- { 0x00, 0x00 }, /* C2 */
- { 0x00, 0x00 }, /* C3 */
- { 0x00, 0x00 }, /* C4 */
- { 0x00, 0x00 }, /* C5 */
- { 0x00, 0x00 }, /* C6 */
- { 0x00, 0x00 }, /* C7 */
- { 0x00, 0x00 }, /* C8 */
- { 0x00, 0x00 }, /* C9 */
- { 0x00, 0x00 }, /* CA */
- { 0x00, 0x00 }, /* CB */
- { 0x00, 0x00 }, /* CC */
- { 0x00, 0x00 }, /* CD */
- { 0x00, 0x00 }, /* CE */
- { 0x00, 0x00 }, /* CF */
- { 0x00, 0x00 }, /* D0 */
- { 0x00, 0x00 }, /* D1 */
- { 0x00, 0x00 }, /* D2 */
- { 0x00, 0x00 }, /* D3 */
- { 0x00, 0x00 }, /* D4 */
- { 0x00, 0x00 }, /* D5 */
- { 0x00, 0x00 }, /* D6 */
- { 0x00, 0x00 }, /* D7 */
- { 0x00, 0x00 }, /* D8 */
- { 0x00, 0x00 }, /* D9 */
- { 0x00, 0x00 }, /* DA */
- { 0x00, 0x00 }, /* DB */
- { 0x00, 0x00 }, /* DC */
- { 0x00, 0x00 }, /* DD */
- { 0x00, 0x00 }, /* DE */
- { 0x00, 0x00 }, /* DF */
- { 0x00, 0x00 }, /* E0 */
- { 0x00, 0x00 }, /* E1 */
- { 0x00, 0x00 }, /* E2 */
- { 0x00, 0x00 }, /* E3 */
- { 0x00, 0x00 }, /* E4 */
- { 0x00, 0x00 }, /* E5 */
- { 0x00, 0x00 }, /* E6 */
- { 0x00, 0x00 }, /* E7 */
- { 0x00, 0x00 }, /* E8 */
- { 0x00, 0x00 }, /* E9 */
- { 0x00, 0x00 }, /* EA */
- { 0x00, 0x00 }, /* EB */
- { 0x00, 0x00 }, /* EC */
- { 0x00, 0x00 }, /* ED */
- { 0x00, 0x00 }, /* EE */
- { 0x00, 0x00 }, /* EF */
- { 0x00, 0x00 }, /* F0 */
- { 0x00, 0x00 }, /* F1 */
- { 0x00, 0x00 }, /* F2 */
- { 0x00, 0x00 }, /* F3 */
- { 0x00, 0x00 }, /* F4 */
- { 0x00, 0x00 }, /* F5 */
- { 0x00, 0x00 }, /* F6 */
- { 0x00, 0x00 }, /* F7 */
- { 0x00, 0x00 }, /* F8 */
- { 0x00, 0x00 }, /* F9 */
- { 0x00, 0x00 }, /* FA */
- { 0x00, 0x00 }, /* FB */
- { 0x00, 0x00 }, /* FC */
- { 0x00, 0x00 }, /* FD */
- { 0x00, 0x00 }, /* FE */
- { 0xFF, 0x00 }, /* FF */
-};
-
-static int max98095_readable(struct snd_soc_codec *codec, unsigned int reg)
-{
- if (reg >= M98095_REG_CNT)
- return 0;
- return max98095_access[reg].readable != 0;
-}
-
-static int max98095_volatile(struct snd_soc_codec *codec, unsigned int reg)
-{
- if (reg > M98095_REG_MAX_CACHED)
- return 1;
-
- switch (reg) {
- case M98095_000_HOST_DATA:
- case M98095_001_HOST_INT_STS:
- case M98095_002_HOST_RSP_STS:
- case M98095_003_HOST_CMD_STS:
- case M98095_004_CODEC_STS:
- case M98095_005_DAI1_ALC_STS:
- case M98095_006_DAI2_ALC_STS:
- case M98095_007_JACK_AUTO_STS:
- case M98095_008_JACK_MANUAL_STS:
- case M98095_009_JACK_VBAT_STS:
- case M98095_00A_ACC_ADC_STS:
- case M98095_00B_MIC_NG_AGC_STS:
- case M98095_00C_SPK_L_VOLT_STS:
- case M98095_00D_SPK_R_VOLT_STS:
- case M98095_00E_TEMP_SENSOR_STS:
- return 1;
- }
-
- return 0;
-}
-
-/*
- * Filter coefficients are in a separate register segment
- * and they share the address space of the normal registers.
- * The coefficient registers do not need or share the cache.
- */
-static int max98095_hw_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- int ret;
-
- codec->cache_bypass = 1;
- ret = snd_soc_write(codec, reg, value);
- codec->cache_bypass = 0;
-
- return ret ? -EIO : 0;
-}
-
-/*
- * Load equalizer DSP coefficient configurations registers
- */
-static void m98095_eq_band(struct snd_soc_codec *codec, unsigned int dai,
- unsigned int band, u16 *coefs)
-{
- unsigned int eq_reg;
- unsigned int i;
-
- BUG_ON(band > 4);
- BUG_ON(dai > 1);
-
- /* Load the base register address */
- eq_reg = dai ? M98095_142_DAI2_EQ_BASE : M98095_110_DAI1_EQ_BASE;
-
- /* Add the band address offset, note adjustment for word address */
- eq_reg += band * (M98095_COEFS_PER_BAND << 1);
-
- /* Step through the registers and coefs */
- for (i = 0; i < M98095_COEFS_PER_BAND; i++) {
- max98095_hw_write(codec, eq_reg++, M98095_BYTE1(coefs[i]));
- max98095_hw_write(codec, eq_reg++, M98095_BYTE0(coefs[i]));
- }
-}
-
-/*
- * Load biquad filter coefficient configurations registers
- */
-static void m98095_biquad_band(struct snd_soc_codec *codec, unsigned int dai,
- unsigned int band, u16 *coefs)
-{
- unsigned int bq_reg;
- unsigned int i;
-
- BUG_ON(band > 1);
- BUG_ON(dai > 1);
-
- /* Load the base register address */
- bq_reg = dai ? M98095_17E_DAI2_BQ_BASE : M98095_174_DAI1_BQ_BASE;
-
- /* Add the band address offset, note adjustment for word address */
- bq_reg += band * (M98095_COEFS_PER_BAND << 1);
-
- /* Step through the registers and coefs */
- for (i = 0; i < M98095_COEFS_PER_BAND; i++) {
- max98095_hw_write(codec, bq_reg++, M98095_BYTE1(coefs[i]));
- max98095_hw_write(codec, bq_reg++, M98095_BYTE0(coefs[i]));
- }
-}
-
-static const char * const max98095_fltr_mode[] = { "Voice", "Music" };
-static const struct soc_enum max98095_dai1_filter_mode_enum[] = {
- SOC_ENUM_SINGLE(M98095_02E_DAI1_FILTERS, 7, 2, max98095_fltr_mode),
-};
-static const struct soc_enum max98095_dai2_filter_mode_enum[] = {
- SOC_ENUM_SINGLE(M98095_038_DAI2_FILTERS, 7, 2, max98095_fltr_mode),
-};
-
-static const char * const max98095_extmic_text[] = { "None", "MIC1", "MIC2" };
-
-static const struct soc_enum max98095_extmic_enum =
- SOC_ENUM_SINGLE(M98095_087_CFG_MIC, 0, 3, max98095_extmic_text);
-
-static const struct snd_kcontrol_new max98095_extmic_mux =
- SOC_DAPM_ENUM("External MIC Mux", max98095_extmic_enum);
-
-static const char * const max98095_linein_text[] = { "INA", "INB" };
-
-static const struct soc_enum max98095_linein_enum =
- SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 6, 2, max98095_linein_text);
-
-static const struct snd_kcontrol_new max98095_linein_mux =
- SOC_DAPM_ENUM("Linein Input Mux", max98095_linein_enum);
-
-static const char * const max98095_line_mode_text[] = {
- "Stereo", "Differential"};
-
-static const struct soc_enum max98095_linein_mode_enum =
- SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 7, 2, max98095_line_mode_text);
-
-static const struct soc_enum max98095_lineout_mode_enum =
- SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 4, 2, max98095_line_mode_text);
-
-static const char * const max98095_dai_fltr[] = {
- "Off", "Elliptical-HPF-16k", "Butterworth-HPF-16k",
- "Elliptical-HPF-8k", "Butterworth-HPF-8k", "Butterworth-HPF-Fs/240"};
-static const struct soc_enum max98095_dai1_dac_filter_enum[] = {
- SOC_ENUM_SINGLE(M98095_02E_DAI1_FILTERS, 0, 6, max98095_dai_fltr),
-};
-static const struct soc_enum max98095_dai2_dac_filter_enum[] = {
- SOC_ENUM_SINGLE(M98095_038_DAI2_FILTERS, 0, 6, max98095_dai_fltr),
-};
-static const struct soc_enum max98095_dai3_dac_filter_enum[] = {
- SOC_ENUM_SINGLE(M98095_042_DAI3_FILTERS, 0, 6, max98095_dai_fltr),
-};
-
-static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
- unsigned int sel = ucontrol->value.integer.value[0];
-
- max98095->mic1pre = sel;
- snd_soc_update_bits(codec, M98095_05F_LVL_MIC1, M98095_MICPRE_MASK,
- (1+sel)<<M98095_MICPRE_SHIFT);
-
- return 0;
-}
-
-static int max98095_mic1pre_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.integer.value[0] = max98095->mic1pre;
- return 0;
-}
-
-static int max98095_mic2pre_set(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
- unsigned int sel = ucontrol->value.integer.value[0];
-
- max98095->mic2pre = sel;
- snd_soc_update_bits(codec, M98095_060_LVL_MIC2, M98095_MICPRE_MASK,
- (1+sel)<<M98095_MICPRE_SHIFT);
-
- return 0;
-}
-
-static int max98095_mic2pre_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.integer.value[0] = max98095->mic2pre;
- return 0;
-}
-
-static const unsigned int max98095_micboost_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0),
- 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
-};
-
-static const DECLARE_TLV_DB_SCALE(max98095_mic_tlv, 0, 100, 0);
-static const DECLARE_TLV_DB_SCALE(max98095_adc_tlv, -1200, 100, 0);
-static const DECLARE_TLV_DB_SCALE(max98095_adcboost_tlv, 0, 600, 0);
-
-static const unsigned int max98095_hp_tlv[] = {
- TLV_DB_RANGE_HEAD(5),
- 0, 6, TLV_DB_SCALE_ITEM(-6700, 400, 0),
- 7, 14, TLV_DB_SCALE_ITEM(-4000, 300, 0),
- 15, 21, TLV_DB_SCALE_ITEM(-1700, 200, 0),
- 22, 27, TLV_DB_SCALE_ITEM(-400, 100, 0),
- 28, 31, TLV_DB_SCALE_ITEM(150, 50, 0),
-};
-
-static const unsigned int max98095_spk_tlv[] = {
- TLV_DB_RANGE_HEAD(4),
- 0, 10, TLV_DB_SCALE_ITEM(-5900, 400, 0),
- 11, 18, TLV_DB_SCALE_ITEM(-1700, 200, 0),
- 19, 27, TLV_DB_SCALE_ITEM(-200, 100, 0),
- 28, 39, TLV_DB_SCALE_ITEM(650, 50, 0),
-};
-
-static const unsigned int max98095_rcv_lout_tlv[] = {
- TLV_DB_RANGE_HEAD(5),
- 0, 6, TLV_DB_SCALE_ITEM(-6200, 400, 0),
- 7, 14, TLV_DB_SCALE_ITEM(-3500, 300, 0),
- 15, 21, TLV_DB_SCALE_ITEM(-1200, 200, 0),
- 22, 27, TLV_DB_SCALE_ITEM(100, 100, 0),
- 28, 31, TLV_DB_SCALE_ITEM(650, 50, 0),
-};
-
-static const unsigned int max98095_lin_tlv[] = {
- TLV_DB_RANGE_HEAD(3),
- 0, 2, TLV_DB_SCALE_ITEM(-600, 300, 0),
- 3, 3, TLV_DB_SCALE_ITEM(300, 1100, 0),
- 4, 5, TLV_DB_SCALE_ITEM(1400, 600, 0),
-};
-
-static const struct snd_kcontrol_new max98095_snd_controls[] = {
-
- SOC_DOUBLE_R_TLV("Headphone Volume", M98095_064_LVL_HP_L,
- M98095_065_LVL_HP_R, 0, 31, 0, max98095_hp_tlv),
-
- SOC_DOUBLE_R_TLV("Speaker Volume", M98095_067_LVL_SPK_L,
- M98095_068_LVL_SPK_R, 0, 39, 0, max98095_spk_tlv),
-
- SOC_SINGLE_TLV("Receiver Volume", M98095_066_LVL_RCV,
- 0, 31, 0, max98095_rcv_lout_tlv),
-
- SOC_DOUBLE_R_TLV("Lineout Volume", M98095_062_LVL_LINEOUT1,
- M98095_063_LVL_LINEOUT2, 0, 31, 0, max98095_rcv_lout_tlv),
-
- SOC_DOUBLE_R("Headphone Switch", M98095_064_LVL_HP_L,
- M98095_065_LVL_HP_R, 7, 1, 1),
-
- SOC_DOUBLE_R("Speaker Switch", M98095_067_LVL_SPK_L,
- M98095_068_LVL_SPK_R, 7, 1, 1),
-
- SOC_SINGLE("Receiver Switch", M98095_066_LVL_RCV, 7, 1, 1),
-
- SOC_DOUBLE_R("Lineout Switch", M98095_062_LVL_LINEOUT1,
- M98095_063_LVL_LINEOUT2, 7, 1, 1),
-
- SOC_SINGLE_TLV("MIC1 Volume", M98095_05F_LVL_MIC1, 0, 20, 1,
- max98095_mic_tlv),
-
- SOC_SINGLE_TLV("MIC2 Volume", M98095_060_LVL_MIC2, 0, 20, 1,
- max98095_mic_tlv),
-
- SOC_SINGLE_EXT_TLV("MIC1 Boost Volume",
- M98095_05F_LVL_MIC1, 5, 2, 0,
- max98095_mic1pre_get, max98095_mic1pre_set,
- max98095_micboost_tlv),
- SOC_SINGLE_EXT_TLV("MIC2 Boost Volume",
- M98095_060_LVL_MIC2, 5, 2, 0,
- max98095_mic2pre_get, max98095_mic2pre_set,
- max98095_micboost_tlv),
-
- SOC_SINGLE_TLV("Linein Volume", M98095_061_LVL_LINEIN, 0, 5, 1,
- max98095_lin_tlv),
-
- SOC_SINGLE_TLV("ADCL Volume", M98095_05D_LVL_ADC_L, 0, 15, 1,
- max98095_adc_tlv),
- SOC_SINGLE_TLV("ADCR Volume", M98095_05E_LVL_ADC_R, 0, 15, 1,
- max98095_adc_tlv),
-
- SOC_SINGLE_TLV("ADCL Boost Volume", M98095_05D_LVL_ADC_L, 4, 3, 0,
- max98095_adcboost_tlv),
- SOC_SINGLE_TLV("ADCR Boost Volume", M98095_05E_LVL_ADC_R, 4, 3, 0,
- max98095_adcboost_tlv),
-
- SOC_SINGLE("EQ1 Switch", M98095_088_CFG_LEVEL, 0, 1, 0),
- SOC_SINGLE("EQ2 Switch", M98095_088_CFG_LEVEL, 1, 1, 0),
-
- SOC_SINGLE("Biquad1 Switch", M98095_088_CFG_LEVEL, 2, 1, 0),
- SOC_SINGLE("Biquad2 Switch", M98095_088_CFG_LEVEL, 3, 1, 0),
-
- SOC_ENUM("DAI1 Filter Mode", max98095_dai1_filter_mode_enum),
- SOC_ENUM("DAI2 Filter Mode", max98095_dai2_filter_mode_enum),
- SOC_ENUM("DAI1 DAC Filter", max98095_dai1_dac_filter_enum),
- SOC_ENUM("DAI2 DAC Filter", max98095_dai2_dac_filter_enum),
- SOC_ENUM("DAI3 DAC Filter", max98095_dai3_dac_filter_enum),
-
- SOC_ENUM("Linein Mode", max98095_linein_mode_enum),
- SOC_ENUM("Lineout Mode", max98095_lineout_mode_enum),
-};
-
-/* Left speaker mixer switch */
-static const struct snd_kcontrol_new max98095_left_speaker_mixer_controls[] = {
- SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_050_MIX_SPK_LEFT, 0, 1, 0),
- SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_050_MIX_SPK_LEFT, 6, 1, 0),
- SOC_DAPM_SINGLE("Mono DAC2 Switch", M98095_050_MIX_SPK_LEFT, 3, 1, 0),
- SOC_DAPM_SINGLE("Mono DAC3 Switch", M98095_050_MIX_SPK_LEFT, 3, 1, 0),
- SOC_DAPM_SINGLE("MIC1 Switch", M98095_050_MIX_SPK_LEFT, 4, 1, 0),
- SOC_DAPM_SINGLE("MIC2 Switch", M98095_050_MIX_SPK_LEFT, 5, 1, 0),
- SOC_DAPM_SINGLE("IN1 Switch", M98095_050_MIX_SPK_LEFT, 1, 1, 0),
- SOC_DAPM_SINGLE("IN2 Switch", M98095_050_MIX_SPK_LEFT, 2, 1, 0),
-};
-
-/* Right speaker mixer switch */
-static const struct snd_kcontrol_new max98095_right_speaker_mixer_controls[] = {
- SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_051_MIX_SPK_RIGHT, 6, 1, 0),
- SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_051_MIX_SPK_RIGHT, 0, 1, 0),
- SOC_DAPM_SINGLE("Mono DAC2 Switch", M98095_051_MIX_SPK_RIGHT, 3, 1, 0),
- SOC_DAPM_SINGLE("Mono DAC3 Switch", M98095_051_MIX_SPK_RIGHT, 3, 1, 0),
- SOC_DAPM_SINGLE("MIC1 Switch", M98095_051_MIX_SPK_RIGHT, 5, 1, 0),
- SOC_DAPM_SINGLE("MIC2 Switch", M98095_051_MIX_SPK_RIGHT, 4, 1, 0),
- SOC_DAPM_SINGLE("IN1 Switch", M98095_051_MIX_SPK_RIGHT, 1, 1, 0),
- SOC_DAPM_SINGLE("IN2 Switch", M98095_051_MIX_SPK_RIGHT, 2, 1, 0),
-};
-
-/* Left headphone mixer switch */
-static const struct snd_kcontrol_new max98095_left_hp_mixer_controls[] = {
- SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_04C_MIX_HP_LEFT, 0, 1, 0),
- SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_04C_MIX_HP_LEFT, 5, 1, 0),
- SOC_DAPM_SINGLE("MIC1 Switch", M98095_04C_MIX_HP_LEFT, 3, 1, 0),
- SOC_DAPM_SINGLE("MIC2 Switch", M98095_04C_MIX_HP_LEFT, 4, 1, 0),
- SOC_DAPM_SINGLE("IN1 Switch", M98095_04C_MIX_HP_LEFT, 1, 1, 0),
- SOC_DAPM_SINGLE("IN2 Switch", M98095_04C_MIX_HP_LEFT, 2, 1, 0),
-};
-
-/* Right headphone mixer switch */
-static const struct snd_kcontrol_new max98095_right_hp_mixer_controls[] = {
- SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_04D_MIX_HP_RIGHT, 5, 1, 0),
- SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_04D_MIX_HP_RIGHT, 0, 1, 0),
- SOC_DAPM_SINGLE("MIC1 Switch", M98095_04D_MIX_HP_RIGHT, 3, 1, 0),
- SOC_DAPM_SINGLE("MIC2 Switch", M98095_04D_MIX_HP_RIGHT, 4, 1, 0),
- SOC_DAPM_SINGLE("IN1 Switch", M98095_04D_MIX_HP_RIGHT, 1, 1, 0),
- SOC_DAPM_SINGLE("IN2 Switch", M98095_04D_MIX_HP_RIGHT, 2, 1, 0),
-};
-
-/* Receiver earpiece mixer switch */
-static const struct snd_kcontrol_new max98095_mono_rcv_mixer_controls[] = {
- SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_04F_MIX_RCV, 0, 1, 0),
- SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_04F_MIX_RCV, 5, 1, 0),
- SOC_DAPM_SINGLE("MIC1 Switch", M98095_04F_MIX_RCV, 3, 1, 0),
- SOC_DAPM_SINGLE("MIC2 Switch", M98095_04F_MIX_RCV, 4, 1, 0),
- SOC_DAPM_SINGLE("IN1 Switch", M98095_04F_MIX_RCV, 1, 1, 0),
- SOC_DAPM_SINGLE("IN2 Switch", M98095_04F_MIX_RCV, 2, 1, 0),
-};
-
-/* Left lineout mixer switch */
-static const struct snd_kcontrol_new max98095_left_lineout_mixer_controls[] = {
- SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_053_MIX_LINEOUT1, 5, 1, 0),
- SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_053_MIX_LINEOUT1, 0, 1, 0),
- SOC_DAPM_SINGLE("MIC1 Switch", M98095_053_MIX_LINEOUT1, 3, 1, 0),
- SOC_DAPM_SINGLE("MIC2 Switch", M98095_053_MIX_LINEOUT1, 4, 1, 0),
- SOC_DAPM_SINGLE("IN1 Switch", M98095_053_MIX_LINEOUT1, 1, 1, 0),
- SOC_DAPM_SINGLE("IN2 Switch", M98095_053_MIX_LINEOUT1, 2, 1, 0),
-};
-
-/* Right lineout mixer switch */
-static const struct snd_kcontrol_new max98095_right_lineout_mixer_controls[] = {
- SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_054_MIX_LINEOUT2, 0, 1, 0),
- SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_054_MIX_LINEOUT2, 5, 1, 0),
- SOC_DAPM_SINGLE("MIC1 Switch", M98095_054_MIX_LINEOUT2, 3, 1, 0),
- SOC_DAPM_SINGLE("MIC2 Switch", M98095_054_MIX_LINEOUT2, 4, 1, 0),
- SOC_DAPM_SINGLE("IN1 Switch", M98095_054_MIX_LINEOUT2, 1, 1, 0),
- SOC_DAPM_SINGLE("IN2 Switch", M98095_054_MIX_LINEOUT2, 2, 1, 0),
-};
-
-/* Left ADC mixer switch */
-static const struct snd_kcontrol_new max98095_left_ADC_mixer_controls[] = {
- SOC_DAPM_SINGLE("MIC1 Switch", M98095_04A_MIX_ADC_LEFT, 7, 1, 0),
- SOC_DAPM_SINGLE("MIC2 Switch", M98095_04A_MIX_ADC_LEFT, 6, 1, 0),
- SOC_DAPM_SINGLE("IN1 Switch", M98095_04A_MIX_ADC_LEFT, 3, 1, 0),
- SOC_DAPM_SINGLE("IN2 Switch", M98095_04A_MIX_ADC_LEFT, 2, 1, 0),
-};
-
-/* Right ADC mixer switch */
-static const struct snd_kcontrol_new max98095_right_ADC_mixer_controls[] = {
- SOC_DAPM_SINGLE("MIC1 Switch", M98095_04B_MIX_ADC_RIGHT, 7, 1, 0),
- SOC_DAPM_SINGLE("MIC2 Switch", M98095_04B_MIX_ADC_RIGHT, 6, 1, 0),
- SOC_DAPM_SINGLE("IN1 Switch", M98095_04B_MIX_ADC_RIGHT, 3, 1, 0),
- SOC_DAPM_SINGLE("IN2 Switch", M98095_04B_MIX_ADC_RIGHT, 2, 1, 0),
-};
-
-static int max98095_mic_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- if (w->reg == M98095_05F_LVL_MIC1) {
- snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK,
- (1+max98095->mic1pre)<<M98095_MICPRE_SHIFT);
- } else {
- snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK,
- (1+max98095->mic2pre)<<M98095_MICPRE_SHIFT);
- }
- break;
- case SND_SOC_DAPM_POST_PMD:
- snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK, 0);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * The line inputs are stereo inputs with the left and right
- * channels sharing a common PGA power control signal.
- */
-static int max98095_line_pga(struct snd_soc_dapm_widget *w,
- int event, u8 channel)
-{
- struct snd_soc_codec *codec = w->codec;
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
- u8 *state;
-
- BUG_ON(!((channel == 1) || (channel == 2)));
-
- state = &max98095->lin_state;
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- *state |= channel;
- snd_soc_update_bits(codec, w->reg,
- (1 << w->shift), (1 << w->shift));
- break;
- case SND_SOC_DAPM_POST_PMD:
- *state &= ~channel;
- if (*state == 0) {
- snd_soc_update_bits(codec, w->reg,
- (1 << w->shift), 0);
- }
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int max98095_pga_in1_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- return max98095_line_pga(w, event, 1);
-}
-
-static int max98095_pga_in2_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- return max98095_line_pga(w, event, 2);
-}
-
-/*
- * The stereo line out mixer outputs to two stereo line outs.
- * The 2nd pair has a separate set of enables.
- */
-static int max98095_lineout_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- snd_soc_update_bits(codec, w->reg,
- (1 << (w->shift+2)), (1 << (w->shift+2)));
- break;
- case SND_SOC_DAPM_POST_PMD:
- snd_soc_update_bits(codec, w->reg,
- (1 << (w->shift+2)), 0);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static const struct snd_soc_dapm_widget max98095_dapm_widgets[] = {
-
- SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", M98095_090_PWR_EN_IN, 0, 0),
- SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", M98095_090_PWR_EN_IN, 1, 0),
-
- SND_SOC_DAPM_DAC("DACL1", "HiFi Playback",
- M98095_091_PWR_EN_OUT, 0, 0),
- SND_SOC_DAPM_DAC("DACR1", "HiFi Playback",
- M98095_091_PWR_EN_OUT, 1, 0),
- SND_SOC_DAPM_DAC("DACM2", "Aux Playback",
- M98095_091_PWR_EN_OUT, 2, 0),
- SND_SOC_DAPM_DAC("DACM3", "Voice Playback",
- M98095_091_PWR_EN_OUT, 2, 0),
-
- SND_SOC_DAPM_PGA("HP Left Out", M98095_091_PWR_EN_OUT,
- 6, 0, NULL, 0),
- SND_SOC_DAPM_PGA("HP Right Out", M98095_091_PWR_EN_OUT,
- 7, 0, NULL, 0),
-
- SND_SOC_DAPM_PGA("SPK Left Out", M98095_091_PWR_EN_OUT,
- 4, 0, NULL, 0),
- SND_SOC_DAPM_PGA("SPK Right Out", M98095_091_PWR_EN_OUT,
- 5, 0, NULL, 0),
-
- SND_SOC_DAPM_PGA("RCV Mono Out", M98095_091_PWR_EN_OUT,
- 3, 0, NULL, 0),
-
- SND_SOC_DAPM_PGA_E("LINE Left Out", M98095_092_PWR_EN_OUT,
- 0, 0, NULL, 0, max98095_lineout_event, SND_SOC_DAPM_PRE_PMD),
- SND_SOC_DAPM_PGA_E("LINE Right Out", M98095_092_PWR_EN_OUT,
- 1, 0, NULL, 0, max98095_lineout_event, SND_SOC_DAPM_PRE_PMD),
-
- SND_SOC_DAPM_MUX("External MIC", SND_SOC_NOPM, 0, 0,
- &max98095_extmic_mux),
-
- SND_SOC_DAPM_MUX("Linein Mux", SND_SOC_NOPM, 0, 0,
- &max98095_linein_mux),
-
- SND_SOC_DAPM_MIXER("Left Headphone Mixer", SND_SOC_NOPM, 0, 0,
- &max98095_left_hp_mixer_controls[0],
- ARRAY_SIZE(max98095_left_hp_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Right Headphone Mixer", SND_SOC_NOPM, 0, 0,
- &max98095_right_hp_mixer_controls[0],
- ARRAY_SIZE(max98095_right_hp_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Left Speaker Mixer", SND_SOC_NOPM, 0, 0,
- &max98095_left_speaker_mixer_controls[0],
- ARRAY_SIZE(max98095_left_speaker_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Right Speaker Mixer", SND_SOC_NOPM, 0, 0,
- &max98095_right_speaker_mixer_controls[0],
- ARRAY_SIZE(max98095_right_speaker_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Receiver Mixer", SND_SOC_NOPM, 0, 0,
- &max98095_mono_rcv_mixer_controls[0],
- ARRAY_SIZE(max98095_mono_rcv_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Left Lineout Mixer", SND_SOC_NOPM, 0, 0,
- &max98095_left_lineout_mixer_controls[0],
- ARRAY_SIZE(max98095_left_lineout_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Right Lineout Mixer", SND_SOC_NOPM, 0, 0,
- &max98095_right_lineout_mixer_controls[0],
- ARRAY_SIZE(max98095_right_lineout_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Left ADC Mixer", SND_SOC_NOPM, 0, 0,
- &max98095_left_ADC_mixer_controls[0],
- ARRAY_SIZE(max98095_left_ADC_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Right ADC Mixer", SND_SOC_NOPM, 0, 0,
- &max98095_right_ADC_mixer_controls[0],
- ARRAY_SIZE(max98095_right_ADC_mixer_controls)),
-
- SND_SOC_DAPM_PGA_E("MIC1 Input", M98095_05F_LVL_MIC1,
- 5, 0, NULL, 0, max98095_mic_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_PGA_E("MIC2 Input", M98095_060_LVL_MIC2,
- 5, 0, NULL, 0, max98095_mic_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_PGA_E("IN1 Input", M98095_090_PWR_EN_IN,
- 7, 0, NULL, 0, max98095_pga_in1_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_PGA_E("IN2 Input", M98095_090_PWR_EN_IN,
- 7, 0, NULL, 0, max98095_pga_in2_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_MICBIAS("MICBIAS1", M98095_090_PWR_EN_IN, 2, 0),
- SND_SOC_DAPM_MICBIAS("MICBIAS2", M98095_090_PWR_EN_IN, 3, 0),
-
- SND_SOC_DAPM_OUTPUT("HPL"),
- SND_SOC_DAPM_OUTPUT("HPR"),
- SND_SOC_DAPM_OUTPUT("SPKL"),
- SND_SOC_DAPM_OUTPUT("SPKR"),
- SND_SOC_DAPM_OUTPUT("RCV"),
- SND_SOC_DAPM_OUTPUT("OUT1"),
- SND_SOC_DAPM_OUTPUT("OUT2"),
- SND_SOC_DAPM_OUTPUT("OUT3"),
- SND_SOC_DAPM_OUTPUT("OUT4"),
-
- SND_SOC_DAPM_INPUT("MIC1"),
- SND_SOC_DAPM_INPUT("MIC2"),
- SND_SOC_DAPM_INPUT("INA1"),
- SND_SOC_DAPM_INPUT("INA2"),
- SND_SOC_DAPM_INPUT("INB1"),
- SND_SOC_DAPM_INPUT("INB2"),
-};
-
-static const struct snd_soc_dapm_route max98095_audio_map[] = {
- /* Left headphone output mixer */
- {"Left Headphone Mixer", "Left DAC1 Switch", "DACL1"},
- {"Left Headphone Mixer", "Right DAC1 Switch", "DACR1"},
- {"Left Headphone Mixer", "MIC1 Switch", "MIC1 Input"},
- {"Left Headphone Mixer", "MIC2 Switch", "MIC2 Input"},
- {"Left Headphone Mixer", "IN1 Switch", "IN1 Input"},
- {"Left Headphone Mixer", "IN2 Switch", "IN2 Input"},
-
- /* Right headphone output mixer */
- {"Right Headphone Mixer", "Left DAC1 Switch", "DACL1"},
- {"Right Headphone Mixer", "Right DAC1 Switch", "DACR1"},
- {"Right Headphone Mixer", "MIC1 Switch", "MIC1 Input"},
- {"Right Headphone Mixer", "MIC2 Switch", "MIC2 Input"},
- {"Right Headphone Mixer", "IN1 Switch", "IN1 Input"},
- {"Right Headphone Mixer", "IN2 Switch", "IN2 Input"},
-
- /* Left speaker output mixer */
- {"Left Speaker Mixer", "Left DAC1 Switch", "DACL1"},
- {"Left Speaker Mixer", "Right DAC1 Switch", "DACR1"},
- {"Left Speaker Mixer", "Mono DAC2 Switch", "DACM2"},
- {"Left Speaker Mixer", "Mono DAC3 Switch", "DACM3"},
- {"Left Speaker Mixer", "MIC1 Switch", "MIC1 Input"},
- {"Left Speaker Mixer", "MIC2 Switch", "MIC2 Input"},
- {"Left Speaker Mixer", "IN1 Switch", "IN1 Input"},
- {"Left Speaker Mixer", "IN2 Switch", "IN2 Input"},
-
- /* Right speaker output mixer */
- {"Right Speaker Mixer", "Left DAC1 Switch", "DACL1"},
- {"Right Speaker Mixer", "Right DAC1 Switch", "DACR1"},
- {"Right Speaker Mixer", "Mono DAC2 Switch", "DACM2"},
- {"Right Speaker Mixer", "Mono DAC3 Switch", "DACM3"},
- {"Right Speaker Mixer", "MIC1 Switch", "MIC1 Input"},
- {"Right Speaker Mixer", "MIC2 Switch", "MIC2 Input"},
- {"Right Speaker Mixer", "IN1 Switch", "IN1 Input"},
- {"Right Speaker Mixer", "IN2 Switch", "IN2 Input"},
-
- /* Earpiece/Receiver output mixer */
- {"Receiver Mixer", "Left DAC1 Switch", "DACL1"},
- {"Receiver Mixer", "Right DAC1 Switch", "DACR1"},
- {"Receiver Mixer", "MIC1 Switch", "MIC1 Input"},
- {"Receiver Mixer", "MIC2 Switch", "MIC2 Input"},
- {"Receiver Mixer", "IN1 Switch", "IN1 Input"},
- {"Receiver Mixer", "IN2 Switch", "IN2 Input"},
-
- /* Left Lineout output mixer */
- {"Left Lineout Mixer", "Left DAC1 Switch", "DACL1"},
- {"Left Lineout Mixer", "Right DAC1 Switch", "DACR1"},
- {"Left Lineout Mixer", "MIC1 Switch", "MIC1 Input"},
- {"Left Lineout Mixer", "MIC2 Switch", "MIC2 Input"},
- {"Left Lineout Mixer", "IN1 Switch", "IN1 Input"},
- {"Left Lineout Mixer", "IN2 Switch", "IN2 Input"},
-
- /* Right lineout output mixer */
- {"Right Lineout Mixer", "Left DAC1 Switch", "DACL1"},
- {"Right Lineout Mixer", "Right DAC1 Switch", "DACR1"},
- {"Right Lineout Mixer", "MIC1 Switch", "MIC1 Input"},
- {"Right Lineout Mixer", "MIC2 Switch", "MIC2 Input"},
- {"Right Lineout Mixer", "IN1 Switch", "IN1 Input"},
- {"Right Lineout Mixer", "IN2 Switch", "IN2 Input"},
-
- {"HP Left Out", NULL, "Left Headphone Mixer"},
- {"HP Right Out", NULL, "Right Headphone Mixer"},
- {"SPK Left Out", NULL, "Left Speaker Mixer"},
- {"SPK Right Out", NULL, "Right Speaker Mixer"},
- {"RCV Mono Out", NULL, "Receiver Mixer"},
- {"LINE Left Out", NULL, "Left Lineout Mixer"},
- {"LINE Right Out", NULL, "Right Lineout Mixer"},
-
- {"HPL", NULL, "HP Left Out"},
- {"HPR", NULL, "HP Right Out"},
- {"SPKL", NULL, "SPK Left Out"},
- {"SPKR", NULL, "SPK Right Out"},
- {"RCV", NULL, "RCV Mono Out"},
- {"OUT1", NULL, "LINE Left Out"},
- {"OUT2", NULL, "LINE Right Out"},
- {"OUT3", NULL, "LINE Left Out"},
- {"OUT4", NULL, "LINE Right Out"},
-
- /* Left ADC input mixer */
- {"Left ADC Mixer", "MIC1 Switch", "MIC1 Input"},
- {"Left ADC Mixer", "MIC2 Switch", "MIC2 Input"},
- {"Left ADC Mixer", "IN1 Switch", "IN1 Input"},
- {"Left ADC Mixer", "IN2 Switch", "IN2 Input"},
-
- /* Right ADC input mixer */
- {"Right ADC Mixer", "MIC1 Switch", "MIC1 Input"},
- {"Right ADC Mixer", "MIC2 Switch", "MIC2 Input"},
- {"Right ADC Mixer", "IN1 Switch", "IN1 Input"},
- {"Right ADC Mixer", "IN2 Switch", "IN2 Input"},
-
- /* Inputs */
- {"ADCL", NULL, "Left ADC Mixer"},
- {"ADCR", NULL, "Right ADC Mixer"},
-
- {"IN1 Input", NULL, "INA1"},
- {"IN2 Input", NULL, "INA2"},
-
- {"MIC1 Input", NULL, "MIC1"},
- {"MIC2 Input", NULL, "MIC2"},
-};
-
-static int max98095_add_widgets(struct snd_soc_codec *codec)
-{
- snd_soc_add_codec_controls(codec, max98095_snd_controls,
- ARRAY_SIZE(max98095_snd_controls));
-
- return 0;
-}
-
-/* codec mclk clock divider coefficients */
-static const struct {
- u32 rate;
- u8 sr;
-} rate_table[] = {
- {8000, 0x01},
- {11025, 0x02},
- {16000, 0x03},
- {22050, 0x04},
- {24000, 0x05},
- {32000, 0x06},
- {44100, 0x07},
- {48000, 0x08},
- {88200, 0x09},
- {96000, 0x0A},
-};
-
-static int rate_value(int rate, u8 *value)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(rate_table); i++) {
- if (rate_table[i].rate >= rate) {
- *value = rate_table[i].sr;
- return 0;
- }
- }
- *value = rate_table[0].sr;
- return -EINVAL;
-}
-
-static int max98095_dai1_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
- struct max98095_cdata *cdata;
- unsigned long long ni;
- unsigned int rate;
- u8 regval;
-
- cdata = &max98095->dai[0];
-
- rate = params_rate(params);
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
- M98095_DAI_WS, 0);
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
- M98095_DAI_WS, M98095_DAI_WS);
- break;
- default:
- return -EINVAL;
- }
-
- if (rate_value(rate, &regval))
- return -EINVAL;
-
- snd_soc_update_bits(codec, M98095_027_DAI1_CLKMODE,
- M98095_CLKMODE_MASK, regval);
- cdata->rate = rate;
-
- /* Configure NI when operating as master */
- if (snd_soc_read(codec, M98095_02A_DAI1_FORMAT) & M98095_DAI_MAS) {
- if (max98095->sysclk == 0) {
- dev_err(codec->dev, "Invalid system clock frequency\n");
- return -EINVAL;
- }
- ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
- * (unsigned long long int)rate;
- do_div(ni, (unsigned long long int)max98095->sysclk);
- snd_soc_write(codec, M98095_028_DAI1_CLKCFG_HI,
- (ni >> 8) & 0x7F);
- snd_soc_write(codec, M98095_029_DAI1_CLKCFG_LO,
- ni & 0xFF);
- }
-
- /* Update sample rate mode */
- if (rate < 50000)
- snd_soc_update_bits(codec, M98095_02E_DAI1_FILTERS,
- M98095_DAI_DHF, 0);
- else
- snd_soc_update_bits(codec, M98095_02E_DAI1_FILTERS,
- M98095_DAI_DHF, M98095_DAI_DHF);
-
- return 0;
-}
-
-static int max98095_dai2_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
- struct max98095_cdata *cdata;
- unsigned long long ni;
- unsigned int rate;
- u8 regval;
-
- cdata = &max98095->dai[1];
-
- rate = params_rate(params);
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
- M98095_DAI_WS, 0);
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
- M98095_DAI_WS, M98095_DAI_WS);
- break;
- default:
- return -EINVAL;
- }
-
- if (rate_value(rate, &regval))
- return -EINVAL;
-
- snd_soc_update_bits(codec, M98095_031_DAI2_CLKMODE,
- M98095_CLKMODE_MASK, regval);
- cdata->rate = rate;
-
- /* Configure NI when operating as master */
- if (snd_soc_read(codec, M98095_034_DAI2_FORMAT) & M98095_DAI_MAS) {
- if (max98095->sysclk == 0) {
- dev_err(codec->dev, "Invalid system clock frequency\n");
- return -EINVAL;
- }
- ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
- * (unsigned long long int)rate;
- do_div(ni, (unsigned long long int)max98095->sysclk);
- snd_soc_write(codec, M98095_032_DAI2_CLKCFG_HI,
- (ni >> 8) & 0x7F);
- snd_soc_write(codec, M98095_033_DAI2_CLKCFG_LO,
- ni & 0xFF);
- }
-
- /* Update sample rate mode */
- if (rate < 50000)
- snd_soc_update_bits(codec, M98095_038_DAI2_FILTERS,
- M98095_DAI_DHF, 0);
- else
- snd_soc_update_bits(codec, M98095_038_DAI2_FILTERS,
- M98095_DAI_DHF, M98095_DAI_DHF);
-
- return 0;
-}
-
-static int max98095_dai3_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
- struct max98095_cdata *cdata;
- unsigned long long ni;
- unsigned int rate;
- u8 regval;
-
- cdata = &max98095->dai[2];
-
- rate = params_rate(params);
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
- M98095_DAI_WS, 0);
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
- M98095_DAI_WS, M98095_DAI_WS);
- break;
- default:
- return -EINVAL;
- }
-
- if (rate_value(rate, &regval))
- return -EINVAL;
-
- snd_soc_update_bits(codec, M98095_03B_DAI3_CLKMODE,
- M98095_CLKMODE_MASK, regval);
- cdata->rate = rate;
-
- /* Configure NI when operating as master */
- if (snd_soc_read(codec, M98095_03E_DAI3_FORMAT) & M98095_DAI_MAS) {
- if (max98095->sysclk == 0) {
- dev_err(codec->dev, "Invalid system clock frequency\n");
- return -EINVAL;
- }
- ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
- * (unsigned long long int)rate;
- do_div(ni, (unsigned long long int)max98095->sysclk);
- snd_soc_write(codec, M98095_03C_DAI3_CLKCFG_HI,
- (ni >> 8) & 0x7F);
- snd_soc_write(codec, M98095_03D_DAI3_CLKCFG_LO,
- ni & 0xFF);
- }
-
- /* Update sample rate mode */
- if (rate < 50000)
- snd_soc_update_bits(codec, M98095_042_DAI3_FILTERS,
- M98095_DAI_DHF, 0);
- else
- snd_soc_update_bits(codec, M98095_042_DAI3_FILTERS,
- M98095_DAI_DHF, M98095_DAI_DHF);
-
- return 0;
-}
-
-static int max98095_dai_set_sysclk(struct snd_soc_dai *dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
-
- /* Requested clock frequency is already setup */
- if (freq == max98095->sysclk)
- return 0;
-
- /* Setup clocks for slave mode, and using the PLL
- * PSCLK = 0x01 (when master clk is 10MHz to 20MHz)
- * 0x02 (when master clk is 20MHz to 40MHz)..
- * 0x03 (when master clk is 40MHz to 60MHz)..
- */
- if ((freq >= 10000000) && (freq < 20000000)) {
- snd_soc_write(codec, M98095_026_SYS_CLK, 0x10);
- } else if ((freq >= 20000000) && (freq < 40000000)) {
- snd_soc_write(codec, M98095_026_SYS_CLK, 0x20);
- } else if ((freq >= 40000000) && (freq < 60000000)) {
- snd_soc_write(codec, M98095_026_SYS_CLK, 0x30);
- } else {
- dev_err(codec->dev, "Invalid master clock frequency\n");
- return -EINVAL;
- }
-
- dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
-
- max98095->sysclk = freq;
- return 0;
-}
-
-static int max98095_dai1_set_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
- struct max98095_cdata *cdata;
- u8 regval = 0;
-
- cdata = &max98095->dai[0];
-
- if (fmt != cdata->fmt) {
- cdata->fmt = fmt;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- /* Slave mode PLL */
- snd_soc_write(codec, M98095_028_DAI1_CLKCFG_HI,
- 0x80);
- snd_soc_write(codec, M98095_029_DAI1_CLKCFG_LO,
- 0x00);
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- /* Set to master mode */
- regval |= M98095_DAI_MAS;
- break;
- case SND_SOC_DAIFMT_CBS_CFM:
- case SND_SOC_DAIFMT_CBM_CFS:
- default:
- dev_err(codec->dev, "Clock mode unsupported");
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- regval |= M98095_DAI_DLY;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_NB_IF:
- regval |= M98095_DAI_WCI;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- regval |= M98095_DAI_BCI;
- break;
- case SND_SOC_DAIFMT_IB_IF:
- regval |= M98095_DAI_BCI|M98095_DAI_WCI;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
- M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
- M98095_DAI_WCI, regval);
-
- snd_soc_write(codec, M98095_02B_DAI1_CLOCK, M98095_DAI_BSEL64);
- }
-
- return 0;
-}
-
-static int max98095_dai2_set_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
- struct max98095_cdata *cdata;
- u8 regval = 0;
-
- cdata = &max98095->dai[1];
-
- if (fmt != cdata->fmt) {
- cdata->fmt = fmt;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- /* Slave mode PLL */
- snd_soc_write(codec, M98095_032_DAI2_CLKCFG_HI,
- 0x80);
- snd_soc_write(codec, M98095_033_DAI2_CLKCFG_LO,
- 0x00);
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- /* Set to master mode */
- regval |= M98095_DAI_MAS;
- break;
- case SND_SOC_DAIFMT_CBS_CFM:
- case SND_SOC_DAIFMT_CBM_CFS:
- default:
- dev_err(codec->dev, "Clock mode unsupported");
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- regval |= M98095_DAI_DLY;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_NB_IF:
- regval |= M98095_DAI_WCI;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- regval |= M98095_DAI_BCI;
- break;
- case SND_SOC_DAIFMT_IB_IF:
- regval |= M98095_DAI_BCI|M98095_DAI_WCI;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
- M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
- M98095_DAI_WCI, regval);
-
- snd_soc_write(codec, M98095_035_DAI2_CLOCK,
- M98095_DAI_BSEL64);
- }
-
- return 0;
-}
-
-static int max98095_dai3_set_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
- struct max98095_cdata *cdata;
- u8 regval = 0;
-
- cdata = &max98095->dai[2];
-
- if (fmt != cdata->fmt) {
- cdata->fmt = fmt;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- /* Slave mode PLL */
- snd_soc_write(codec, M98095_03C_DAI3_CLKCFG_HI,
- 0x80);
- snd_soc_write(codec, M98095_03D_DAI3_CLKCFG_LO,
- 0x00);
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- /* Set to master mode */
- regval |= M98095_DAI_MAS;
- break;
- case SND_SOC_DAIFMT_CBS_CFM:
- case SND_SOC_DAIFMT_CBM_CFS:
- default:
- dev_err(codec->dev, "Clock mode unsupported");
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- regval |= M98095_DAI_DLY;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_NB_IF:
- regval |= M98095_DAI_WCI;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- regval |= M98095_DAI_BCI;
- break;
- case SND_SOC_DAIFMT_IB_IF:
- regval |= M98095_DAI_BCI|M98095_DAI_WCI;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
- M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
- M98095_DAI_WCI, regval);
-
- snd_soc_write(codec, M98095_03F_DAI3_CLOCK,
- M98095_DAI_BSEL64);
- }
-
- return 0;
-}
-
-static int max98095_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- int ret;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = snd_soc_cache_sync(codec);
-
- if (ret != 0) {
- dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
- return ret;
- }
- }
-
- snd_soc_update_bits(codec, M98095_090_PWR_EN_IN,
- M98095_MBEN, M98095_MBEN);
- break;
-
- case SND_SOC_BIAS_OFF:
- snd_soc_update_bits(codec, M98095_090_PWR_EN_IN,
- M98095_MBEN, 0);
- codec->cache_sync = 1;
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define MAX98095_RATES SNDRV_PCM_RATE_8000_96000
-#define MAX98095_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops max98095_dai1_ops = {
- .set_sysclk = max98095_dai_set_sysclk,
- .set_fmt = max98095_dai1_set_fmt,
- .hw_params = max98095_dai1_hw_params,
-};
-
-static const struct snd_soc_dai_ops max98095_dai2_ops = {
- .set_sysclk = max98095_dai_set_sysclk,
- .set_fmt = max98095_dai2_set_fmt,
- .hw_params = max98095_dai2_hw_params,
-};
-
-static const struct snd_soc_dai_ops max98095_dai3_ops = {
- .set_sysclk = max98095_dai_set_sysclk,
- .set_fmt = max98095_dai3_set_fmt,
- .hw_params = max98095_dai3_hw_params,
-};
-
-static struct snd_soc_dai_driver max98095_dai[] = {
-{
- .name = "HiFi",
- .playback = {
- .stream_name = "HiFi Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = MAX98095_RATES,
- .formats = MAX98095_FORMATS,
- },
- .capture = {
- .stream_name = "HiFi Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = MAX98095_RATES,
- .formats = MAX98095_FORMATS,
- },
- .ops = &max98095_dai1_ops,
-},
-{
- .name = "Aux",
- .playback = {
- .stream_name = "Aux Playback",
- .channels_min = 1,
- .channels_max = 1,
- .rates = MAX98095_RATES,
- .formats = MAX98095_FORMATS,
- },
- .ops = &max98095_dai2_ops,
-},
-{
- .name = "Voice",
- .playback = {
- .stream_name = "Voice Playback",
- .channels_min = 1,
- .channels_max = 1,
- .rates = MAX98095_RATES,
- .formats = MAX98095_FORMATS,
- },
- .ops = &max98095_dai3_ops,
-}
-
-};
-
-static int max98095_get_eq_channel(const char *name)
-{
- if (strcmp(name, "EQ1 Mode") == 0)
- return 0;
- if (strcmp(name, "EQ2 Mode") == 0)
- return 1;
- return -EINVAL;
-}
-
-static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
- struct max98095_pdata *pdata = max98095->pdata;
- int channel = max98095_get_eq_channel(kcontrol->id.name);
- struct max98095_cdata *cdata;
- int sel = ucontrol->value.integer.value[0];
- struct max98095_eq_cfg *coef_set;
- int fs, best, best_val, i;
- int regmask, regsave;
-
- BUG_ON(channel > 1);
-
- if (!pdata || !max98095->eq_textcnt)
- return 0;
-
- if (sel >= pdata->eq_cfgcnt)
- return -EINVAL;
-
- cdata = &max98095->dai[channel];
- cdata->eq_sel = sel;
- fs = cdata->rate;
-
- /* Find the selected configuration with nearest sample rate */
- best = 0;
- best_val = INT_MAX;
- for (i = 0; i < pdata->eq_cfgcnt; i++) {
- if (strcmp(pdata->eq_cfg[i].name, max98095->eq_texts[sel]) == 0 &&
- abs(pdata->eq_cfg[i].rate - fs) < best_val) {
- best = i;
- best_val = abs(pdata->eq_cfg[i].rate - fs);
- }
- }
-
- dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n",
- pdata->eq_cfg[best].name,
- pdata->eq_cfg[best].rate, fs);
-
- coef_set = &pdata->eq_cfg[best];
-
- regmask = (channel == 0) ? M98095_EQ1EN : M98095_EQ2EN;
-
- /* Disable filter while configuring, and save current on/off state */
- regsave = snd_soc_read(codec, M98095_088_CFG_LEVEL);
- snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, 0);
-
- mutex_lock(&codec->mutex);
- snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, M98095_SEG);
- m98095_eq_band(codec, channel, 0, coef_set->band1);
- m98095_eq_band(codec, channel, 1, coef_set->band2);
- m98095_eq_band(codec, channel, 2, coef_set->band3);
- m98095_eq_band(codec, channel, 3, coef_set->band4);
- m98095_eq_band(codec, channel, 4, coef_set->band5);
- snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, 0);
- mutex_unlock(&codec->mutex);
-
- /* Restore the original on/off state */
- snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, regsave);
- return 0;
-}
-
-static int max98095_get_eq_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
- int channel = max98095_get_eq_channel(kcontrol->id.name);
- struct max98095_cdata *cdata;
-
- cdata = &max98095->dai[channel];
- ucontrol->value.enumerated.item[0] = cdata->eq_sel;
-
- return 0;
-}
-
-static void max98095_handle_eq_pdata(struct snd_soc_codec *codec)
-{
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
- struct max98095_pdata *pdata = max98095->pdata;
- struct max98095_eq_cfg *cfg;
- unsigned int cfgcnt;
- int i, j;
- const char **t;
- int ret;
-
- struct snd_kcontrol_new controls[] = {
- SOC_ENUM_EXT("EQ1 Mode",
- max98095->eq_enum,
- max98095_get_eq_enum,
- max98095_put_eq_enum),
- SOC_ENUM_EXT("EQ2 Mode",
- max98095->eq_enum,
- max98095_get_eq_enum,
- max98095_put_eq_enum),
- };
-
- cfg = pdata->eq_cfg;
- cfgcnt = pdata->eq_cfgcnt;
-
- /* Setup an array of texts for the equalizer enum.
- * This is based on Mark Brown's equalizer driver code.
- */
- max98095->eq_textcnt = 0;
- max98095->eq_texts = NULL;
- for (i = 0; i < cfgcnt; i++) {
- for (j = 0; j < max98095->eq_textcnt; j++) {
- if (strcmp(cfg[i].name, max98095->eq_texts[j]) == 0)
- break;
- }
-
- if (j != max98095->eq_textcnt)
- continue;
-
- /* Expand the array */
- t = krealloc(max98095->eq_texts,
- sizeof(char *) * (max98095->eq_textcnt + 1),
- GFP_KERNEL);
- if (t == NULL)
- continue;
-
- /* Store the new entry */
- t[max98095->eq_textcnt] = cfg[i].name;
- max98095->eq_textcnt++;
- max98095->eq_texts = t;
- }
-
- /* Now point the soc_enum to .texts array items */
- max98095->eq_enum.texts = max98095->eq_texts;
- max98095->eq_enum.max = max98095->eq_textcnt;
-
- ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
- if (ret != 0)
- dev_err(codec->dev, "Failed to add EQ control: %d\n", ret);
-}
-
-static const char *bq_mode_name[] = {"Biquad1 Mode", "Biquad2 Mode"};
-
-static int max98095_get_bq_channel(struct snd_soc_codec *codec,
- const char *name)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(bq_mode_name); i++)
- if (strcmp(name, bq_mode_name[i]) == 0)
- return i;
-
- /* Shouldn't happen */
- dev_err(codec->dev, "Bad biquad channel name '%s'\n", name);
- return -EINVAL;
-}
-
-static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
- struct max98095_pdata *pdata = max98095->pdata;
- int channel = max98095_get_bq_channel(codec, kcontrol->id.name);
- struct max98095_cdata *cdata;
- int sel = ucontrol->value.integer.value[0];
- struct max98095_biquad_cfg *coef_set;
- int fs, best, best_val, i;
- int regmask, regsave;
-
- if (channel < 0)
- return channel;
-
- if (!pdata || !max98095->bq_textcnt)
- return 0;
-
- if (sel >= pdata->bq_cfgcnt)
- return -EINVAL;
-
- cdata = &max98095->dai[channel];
- cdata->bq_sel = sel;
- fs = cdata->rate;
-
- /* Find the selected configuration with nearest sample rate */
- best = 0;
- best_val = INT_MAX;
- for (i = 0; i < pdata->bq_cfgcnt; i++) {
- if (strcmp(pdata->bq_cfg[i].name, max98095->bq_texts[sel]) == 0 &&
- abs(pdata->bq_cfg[i].rate - fs) < best_val) {
- best = i;
- best_val = abs(pdata->bq_cfg[i].rate - fs);
- }
- }
-
- dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n",
- pdata->bq_cfg[best].name,
- pdata->bq_cfg[best].rate, fs);
-
- coef_set = &pdata->bq_cfg[best];
-
- regmask = (channel == 0) ? M98095_BQ1EN : M98095_BQ2EN;
-
- /* Disable filter while configuring, and save current on/off state */
- regsave = snd_soc_read(codec, M98095_088_CFG_LEVEL);
- snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, 0);
-
- mutex_lock(&codec->mutex);
- snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, M98095_SEG);
- m98095_biquad_band(codec, channel, 0, coef_set->band1);
- m98095_biquad_band(codec, channel, 1, coef_set->band2);
- snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, 0);
- mutex_unlock(&codec->mutex);
-
- /* Restore the original on/off state */
- snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, regsave);
- return 0;
-}
-
-static int max98095_get_bq_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
- int channel = max98095_get_bq_channel(codec, kcontrol->id.name);
- struct max98095_cdata *cdata;
-
- if (channel < 0)
- return channel;
-
- cdata = &max98095->dai[channel];
- ucontrol->value.enumerated.item[0] = cdata->bq_sel;
-
- return 0;
-}
-
-static void max98095_handle_bq_pdata(struct snd_soc_codec *codec)
-{
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
- struct max98095_pdata *pdata = max98095->pdata;
- struct max98095_biquad_cfg *cfg;
- unsigned int cfgcnt;
- int i, j;
- const char **t;
- int ret;
-
- struct snd_kcontrol_new controls[] = {
- SOC_ENUM_EXT((char *)bq_mode_name[0],
- max98095->bq_enum,
- max98095_get_bq_enum,
- max98095_put_bq_enum),
- SOC_ENUM_EXT((char *)bq_mode_name[1],
- max98095->bq_enum,
- max98095_get_bq_enum,
- max98095_put_bq_enum),
- };
- BUILD_BUG_ON(ARRAY_SIZE(controls) != ARRAY_SIZE(bq_mode_name));
-
- cfg = pdata->bq_cfg;
- cfgcnt = pdata->bq_cfgcnt;
-
- /* Setup an array of texts for the biquad enum.
- * This is based on Mark Brown's equalizer driver code.
- */
- max98095->bq_textcnt = 0;
- max98095->bq_texts = NULL;
- for (i = 0; i < cfgcnt; i++) {
- for (j = 0; j < max98095->bq_textcnt; j++) {
- if (strcmp(cfg[i].name, max98095->bq_texts[j]) == 0)
- break;
- }
-
- if (j != max98095->bq_textcnt)
- continue;
-
- /* Expand the array */
- t = krealloc(max98095->bq_texts,
- sizeof(char *) * (max98095->bq_textcnt + 1),
- GFP_KERNEL);
- if (t == NULL)
- continue;
-
- /* Store the new entry */
- t[max98095->bq_textcnt] = cfg[i].name;
- max98095->bq_textcnt++;
- max98095->bq_texts = t;
- }
-
- /* Now point the soc_enum to .texts array items */
- max98095->bq_enum.texts = max98095->bq_texts;
- max98095->bq_enum.max = max98095->bq_textcnt;
-
- ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
- if (ret != 0)
- dev_err(codec->dev, "Failed to add Biquad control: %d\n", ret);
-}
-
-static void max98095_handle_pdata(struct snd_soc_codec *codec)
-{
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
- struct max98095_pdata *pdata = max98095->pdata;
- u8 regval = 0;
-
- if (!pdata) {
- dev_dbg(codec->dev, "No platform data\n");
- return;
- }
-
- /* Configure mic for analog/digital mic mode */
- if (pdata->digmic_left_mode)
- regval |= M98095_DIGMIC_L;
-
- if (pdata->digmic_right_mode)
- regval |= M98095_DIGMIC_R;
-
- snd_soc_write(codec, M98095_087_CFG_MIC, regval);
-
- /* Configure equalizers */
- if (pdata->eq_cfgcnt)
- max98095_handle_eq_pdata(codec);
-
- /* Configure bi-quad filters */
- if (pdata->bq_cfgcnt)
- max98095_handle_bq_pdata(codec);
-}
-
-#ifdef CONFIG_PM
-static int max98095_suspend(struct snd_soc_codec *codec)
-{
- max98095_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int max98095_resume(struct snd_soc_codec *codec)
-{
- max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-#else
-#define max98095_suspend NULL
-#define max98095_resume NULL
-#endif
-
-static int max98095_reset(struct snd_soc_codec *codec)
-{
- int i, ret;
-
- /* Gracefully reset the DSP core and the codec hardware
- * in a proper sequence */
- ret = snd_soc_write(codec, M98095_00F_HOST_CFG, 0);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to reset DSP: %d\n", ret);
- return ret;
- }
-
- ret = snd_soc_write(codec, M98095_097_PWR_SYS, 0);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to reset codec: %d\n", ret);
- return ret;
- }
-
- /* Reset to hardware default for registers, as there is not
- * a soft reset hardware control register */
- for (i = M98095_010_HOST_INT_CFG; i < M98095_REG_MAX_CACHED; i++) {
- ret = snd_soc_write(codec, i, max98095_reg_def[i]);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to reset: %d\n", ret);
- return ret;
- }
- }
-
- return ret;
-}
-
-static int max98095_probe(struct snd_soc_codec *codec)
-{
- struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
- struct max98095_cdata *cdata;
- int ret = 0;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- /* reset the codec, the DSP core, and disable all interrupts */
- max98095_reset(codec);
-
- /* initialize private data */
-
- max98095->sysclk = (unsigned)-1;
- max98095->eq_textcnt = 0;
- max98095->bq_textcnt = 0;
-
- cdata = &max98095->dai[0];
- cdata->rate = (unsigned)-1;
- cdata->fmt = (unsigned)-1;
- cdata->eq_sel = 0;
- cdata->bq_sel = 0;
-
- cdata = &max98095->dai[1];
- cdata->rate = (unsigned)-1;
- cdata->fmt = (unsigned)-1;
- cdata->eq_sel = 0;
- cdata->bq_sel = 0;
-
- cdata = &max98095->dai[2];
- cdata->rate = (unsigned)-1;
- cdata->fmt = (unsigned)-1;
- cdata->eq_sel = 0;
- cdata->bq_sel = 0;
-
- max98095->lin_state = 0;
- max98095->mic1pre = 0;
- max98095->mic2pre = 0;
-
- ret = snd_soc_read(codec, M98095_0FF_REV_ID);
- if (ret < 0) {
- dev_err(codec->dev, "Failure reading hardware revision: %d\n",
- ret);
- goto err_access;
- }
- dev_info(codec->dev, "Hardware revision: %c\n", ret - 0x40 + 'A');
-
- snd_soc_write(codec, M98095_097_PWR_SYS, M98095_PWRSV);
-
- /* initialize registers cache to hardware default */
- max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- snd_soc_write(codec, M98095_048_MIX_DAC_LR,
- M98095_DAI1L_TO_DACL|M98095_DAI1R_TO_DACR);
-
- snd_soc_write(codec, M98095_049_MIX_DAC_M,
- M98095_DAI2M_TO_DACM|M98095_DAI3M_TO_DACM);
-
- snd_soc_write(codec, M98095_092_PWR_EN_OUT, M98095_SPK_SPREADSPECTRUM);
- snd_soc_write(codec, M98095_045_CFG_DSP, M98095_DSPNORMAL);
- snd_soc_write(codec, M98095_04E_CFG_HP, M98095_HPNORMAL);
-
- snd_soc_write(codec, M98095_02C_DAI1_IOCFG,
- M98095_S1NORMAL|M98095_SDATA);
-
- snd_soc_write(codec, M98095_036_DAI2_IOCFG,
- M98095_S2NORMAL|M98095_SDATA);
-
- snd_soc_write(codec, M98095_040_DAI3_IOCFG,
- M98095_S3NORMAL|M98095_SDATA);
-
- max98095_handle_pdata(codec);
-
- /* take the codec out of the shut down */
- snd_soc_update_bits(codec, M98095_097_PWR_SYS, M98095_SHDNRUN,
- M98095_SHDNRUN);
-
- max98095_add_widgets(codec);
-
-err_access:
- return ret;
-}
-
-static int max98095_remove(struct snd_soc_codec *codec)
-{
- max98095_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_max98095 = {
- .probe = max98095_probe,
- .remove = max98095_remove,
- .suspend = max98095_suspend,
- .resume = max98095_resume,
- .set_bias_level = max98095_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(max98095_reg_def),
- .reg_word_size = sizeof(u8),
- .reg_cache_default = max98095_reg_def,
- .readable_register = max98095_readable,
- .volatile_register = max98095_volatile,
- .dapm_widgets = max98095_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(max98095_dapm_widgets),
- .dapm_routes = max98095_audio_map,
- .num_dapm_routes = ARRAY_SIZE(max98095_audio_map),
-};
-
-static int max98095_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct max98095_priv *max98095;
- int ret;
-
- max98095 = devm_kzalloc(&i2c->dev, sizeof(struct max98095_priv),
- GFP_KERNEL);
- if (max98095 == NULL)
- return -ENOMEM;
-
- max98095->devtype = id->driver_data;
- i2c_set_clientdata(i2c, max98095);
- max98095->pdata = i2c->dev.platform_data;
-
- ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98095,
- max98095_dai, ARRAY_SIZE(max98095_dai));
- return ret;
-}
-
-static int __devexit max98095_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static const struct i2c_device_id max98095_i2c_id[] = {
- { "max98095", MAX98095 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, max98095_i2c_id);
-
-static struct i2c_driver max98095_i2c_driver = {
- .driver = {
- .name = "max98095",
- .owner = THIS_MODULE,
- },
- .probe = max98095_i2c_probe,
- .remove = __devexit_p(max98095_i2c_remove),
- .id_table = max98095_i2c_id,
-};
-
-static int __init max98095_init(void)
-{
- int ret;
-
- ret = i2c_add_driver(&max98095_i2c_driver);
- if (ret)
- pr_err("Failed to register max98095 I2C driver: %d\n", ret);
-
- return ret;
-}
-module_init(max98095_init);
-
-static void __exit max98095_exit(void)
-{
- i2c_del_driver(&max98095_i2c_driver);
-}
-module_exit(max98095_exit);
-
-MODULE_DESCRIPTION("ALSA SoC MAX98095 driver");
-MODULE_AUTHOR("Peter Hsiang");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/max98095.h b/ANDROID_3.4.5/sound/soc/codecs/max98095.h
deleted file mode 100644
index 891584a0..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/max98095.h
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * max98095.h -- MAX98095 ALSA SoC Audio driver
- *
- * Copyright 2011 Maxim Integrated Products
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _MAX98095_H
-#define _MAX98095_H
-
-/*
- * MAX98095 Registers Definition
- */
-
-#define M98095_000_HOST_DATA 0x00
-#define M98095_001_HOST_INT_STS 0x01
-#define M98095_002_HOST_RSP_STS 0x02
-#define M98095_003_HOST_CMD_STS 0x03
-#define M98095_004_CODEC_STS 0x04
-#define M98095_005_DAI1_ALC_STS 0x05
-#define M98095_006_DAI2_ALC_STS 0x06
-#define M98095_007_JACK_AUTO_STS 0x07
-#define M98095_008_JACK_MANUAL_STS 0x08
-#define M98095_009_JACK_VBAT_STS 0x09
-#define M98095_00A_ACC_ADC_STS 0x0A
-#define M98095_00B_MIC_NG_AGC_STS 0x0B
-#define M98095_00C_SPK_L_VOLT_STS 0x0C
-#define M98095_00D_SPK_R_VOLT_STS 0x0D
-#define M98095_00E_TEMP_SENSOR_STS 0x0E
-#define M98095_00F_HOST_CFG 0x0F
-#define M98095_010_HOST_INT_CFG 0x10
-#define M98095_011_HOST_INT_EN 0x11
-#define M98095_012_CODEC_INT_EN 0x12
-#define M98095_013_JACK_INT_EN 0x13
-#define M98095_014_JACK_INT_EN 0x14
-#define M98095_015_DEC 0x15
-#define M98095_016_RESERVED 0x16
-#define M98095_017_RESERVED 0x17
-#define M98095_018_KEYCODE3 0x18
-#define M98095_019_KEYCODE2 0x19
-#define M98095_01A_KEYCODE1 0x1A
-#define M98095_01B_KEYCODE0 0x1B
-#define M98095_01C_OEMCODE1 0x1C
-#define M98095_01D_OEMCODE0 0x1D
-#define M98095_01E_XCFG1 0x1E
-#define M98095_01F_XCFG2 0x1F
-#define M98095_020_XCFG3 0x20
-#define M98095_021_XCFG4 0x21
-#define M98095_022_XCFG5 0x22
-#define M98095_023_XCFG6 0x23
-#define M98095_024_XGPIO 0x24
-#define M98095_025_XCLKCFG 0x25
-#define M98095_026_SYS_CLK 0x26
-#define M98095_027_DAI1_CLKMODE 0x27
-#define M98095_028_DAI1_CLKCFG_HI 0x28
-#define M98095_029_DAI1_CLKCFG_LO 0x29
-#define M98095_02A_DAI1_FORMAT 0x2A
-#define M98095_02B_DAI1_CLOCK 0x2B
-#define M98095_02C_DAI1_IOCFG 0x2C
-#define M98095_02D_DAI1_TDM 0x2D
-#define M98095_02E_DAI1_FILTERS 0x2E
-#define M98095_02F_DAI1_LVL1 0x2F
-#define M98095_030_DAI1_LVL2 0x30
-#define M98095_031_DAI2_CLKMODE 0x31
-#define M98095_032_DAI2_CLKCFG_HI 0x32
-#define M98095_033_DAI2_CLKCFG_LO 0x33
-#define M98095_034_DAI2_FORMAT 0x34
-#define M98095_035_DAI2_CLOCK 0x35
-#define M98095_036_DAI2_IOCFG 0x36
-#define M98095_037_DAI2_TDM 0x37
-#define M98095_038_DAI2_FILTERS 0x38
-#define M98095_039_DAI2_LVL1 0x39
-#define M98095_03A_DAI2_LVL2 0x3A
-#define M98095_03B_DAI3_CLKMODE 0x3B
-#define M98095_03C_DAI3_CLKCFG_HI 0x3C
-#define M98095_03D_DAI3_CLKCFG_LO 0x3D
-#define M98095_03E_DAI3_FORMAT 0x3E
-#define M98095_03F_DAI3_CLOCK 0x3F
-#define M98095_040_DAI3_IOCFG 0x40
-#define M98095_041_DAI3_TDM 0x41
-#define M98095_042_DAI3_FILTERS 0x42
-#define M98095_043_DAI3_LVL1 0x43
-#define M98095_044_DAI3_LVL2 0x44
-#define M98095_045_CFG_DSP 0x45
-#define M98095_046_DAC_CTRL1 0x46
-#define M98095_047_DAC_CTRL2 0x47
-#define M98095_048_MIX_DAC_LR 0x48
-#define M98095_049_MIX_DAC_M 0x49
-#define M98095_04A_MIX_ADC_LEFT 0x4A
-#define M98095_04B_MIX_ADC_RIGHT 0x4B
-#define M98095_04C_MIX_HP_LEFT 0x4C
-#define M98095_04D_MIX_HP_RIGHT 0x4D
-#define M98095_04E_CFG_HP 0x4E
-#define M98095_04F_MIX_RCV 0x4F
-#define M98095_050_MIX_SPK_LEFT 0x50
-#define M98095_051_MIX_SPK_RIGHT 0x51
-#define M98095_052_MIX_SPK_CFG 0x52
-#define M98095_053_MIX_LINEOUT1 0x53
-#define M98095_054_MIX_LINEOUT2 0x54
-#define M98095_055_MIX_LINEOUT_CFG 0x55
-#define M98095_056_LVL_SIDETONE_DAI12 0x56
-#define M98095_057_LVL_SIDETONE_DAI3 0x57
-#define M98095_058_LVL_DAI1_PLAY 0x58
-#define M98095_059_LVL_DAI1_EQ 0x59
-#define M98095_05A_LVL_DAI2_PLAY 0x5A
-#define M98095_05B_LVL_DAI2_EQ 0x5B
-#define M98095_05C_LVL_DAI3_PLAY 0x5C
-#define M98095_05D_LVL_ADC_L 0x5D
-#define M98095_05E_LVL_ADC_R 0x5E
-#define M98095_05F_LVL_MIC1 0x5F
-#define M98095_060_LVL_MIC2 0x60
-#define M98095_061_LVL_LINEIN 0x61
-#define M98095_062_LVL_LINEOUT1 0x62
-#define M98095_063_LVL_LINEOUT2 0x63
-#define M98095_064_LVL_HP_L 0x64
-#define M98095_065_LVL_HP_R 0x65
-#define M98095_066_LVL_RCV 0x66
-#define M98095_067_LVL_SPK_L 0x67
-#define M98095_068_LVL_SPK_R 0x68
-#define M98095_069_MICAGC_CFG 0x69
-#define M98095_06A_MICAGC_THRESH 0x6A
-#define M98095_06B_SPK_NOISEGATE 0x6B
-#define M98095_06C_DAI1_ALC1_TIME 0x6C
-#define M98095_06D_DAI1_ALC1_COMP 0x6D
-#define M98095_06E_DAI1_ALC1_EXPN 0x6E
-#define M98095_06F_DAI1_ALC1_GAIN 0x6F
-#define M98095_070_DAI1_ALC2_TIME 0x70
-#define M98095_071_DAI1_ALC2_COMP 0x71
-#define M98095_072_DAI1_ALC2_EXPN 0x72
-#define M98095_073_DAI1_ALC2_GAIN 0x73
-#define M98095_074_DAI1_ALC3_TIME 0x74
-#define M98095_075_DAI1_ALC3_COMP 0x75
-#define M98095_076_DAI1_ALC3_EXPN 0x76
-#define M98095_077_DAI1_ALC3_GAIN 0x77
-#define M98095_078_DAI2_ALC1_TIME 0x78
-#define M98095_079_DAI2_ALC1_COMP 0x79
-#define M98095_07A_DAI2_ALC1_EXPN 0x7A
-#define M98095_07B_DAI2_ALC1_GAIN 0x7B
-#define M98095_07C_DAI2_ALC2_TIME 0x7C
-#define M98095_07D_DAI2_ALC2_COMP 0x7D
-#define M98095_07E_DAI2_ALC2_EXPN 0x7E
-#define M98095_07F_DAI2_ALC2_GAIN 0x7F
-#define M98095_080_DAI2_ALC3_TIME 0x80
-#define M98095_081_DAI2_ALC3_COMP 0x81
-#define M98095_082_DAI2_ALC3_EXPN 0x82
-#define M98095_083_DAI2_ALC3_GAIN 0x83
-#define M98095_084_HP_NOISE_GATE 0x84
-#define M98095_085_AUX_ADC 0x85
-#define M98095_086_CFG_LINE 0x86
-#define M98095_087_CFG_MIC 0x87
-#define M98095_088_CFG_LEVEL 0x88
-#define M98095_089_JACK_DET_AUTO 0x89
-#define M98095_08A_JACK_DET_MANUAL 0x8A
-#define M98095_08B_JACK_KEYSCAN_DBC 0x8B
-#define M98095_08C_JACK_KEYSCAN_DLY 0x8C
-#define M98095_08D_JACK_KEY_THRESH 0x8D
-#define M98095_08E_JACK_DC_SLEW 0x8E
-#define M98095_08F_JACK_TEST_CFG 0x8F
-#define M98095_090_PWR_EN_IN 0x90
-#define M98095_091_PWR_EN_OUT 0x91
-#define M98095_092_PWR_EN_OUT 0x92
-#define M98095_093_BIAS_CTRL 0x93
-#define M98095_094_PWR_DAC_21 0x94
-#define M98095_095_PWR_DAC_03 0x95
-#define M98095_096_PWR_DAC_CK 0x96
-#define M98095_097_PWR_SYS 0x97
-
-#define M98095_0FF_REV_ID 0xFF
-
-#define M98095_REG_CNT (0xFF+1)
-#define M98095_REG_MAX_CACHED 0X97
-
-/* MAX98095 Registers Bit Fields */
-
-/* M98095_00F_HOST_CFG */
- #define M98095_SEG (1<<0)
- #define M98095_XTEN (1<<1)
- #define M98095_MDLLEN (1<<2)
-
-/* M98095_027_DAI1_CLKMODE, M98095_031_DAI2_CLKMODE, M98095_03B_DAI3_CLKMODE */
- #define M98095_CLKMODE_MASK 0xFF
-
-/* M98095_02A_DAI1_FORMAT, M98095_034_DAI2_FORMAT, M98095_03E_DAI3_FORMAT */
- #define M98095_DAI_MAS (1<<7)
- #define M98095_DAI_WCI (1<<6)
- #define M98095_DAI_BCI (1<<5)
- #define M98095_DAI_DLY (1<<4)
- #define M98095_DAI_TDM (1<<2)
- #define M98095_DAI_FSW (1<<1)
- #define M98095_DAI_WS (1<<0)
-
-/* M98095_02B_DAI1_CLOCK, M98095_035_DAI2_CLOCK, M98095_03F_DAI3_CLOCK */
- #define M98095_DAI_BSEL64 (1<<0)
- #define M98095_DAI_DOSR_DIV2 (0<<5)
- #define M98095_DAI_DOSR_DIV4 (1<<5)
-
-/* M98095_02C_DAI1_IOCFG, M98095_036_DAI2_IOCFG, M98095_040_DAI3_IOCFG */
- #define M98095_S1NORMAL (1<<6)
- #define M98095_S2NORMAL (2<<6)
- #define M98095_S3NORMAL (3<<6)
- #define M98095_SDATA (3<<0)
-
-/* M98095_02E_DAI1_FILTERS, M98095_038_DAI2_FILTERS, M98095_042_DAI3_FILTERS */
- #define M98095_DAI_DHF (1<<3)
-
-/* M98095_045_DSP_CFG */
- #define M98095_DSPNORMAL (5<<4)
-
-/* M98095_048_MIX_DAC_LR */
- #define M98095_DAI1L_TO_DACR (1<<7)
- #define M98095_DAI1R_TO_DACR (1<<6)
- #define M98095_DAI2M_TO_DACR (1<<5)
- #define M98095_DAI1L_TO_DACL (1<<3)
- #define M98095_DAI1R_TO_DACL (1<<2)
- #define M98095_DAI2M_TO_DACL (1<<1)
- #define M98095_DAI3M_TO_DACL (1<<0)
-
-/* M98095_049_MIX_DAC_M */
- #define M98095_DAI1L_TO_DACM (1<<3)
- #define M98095_DAI1R_TO_DACM (1<<2)
- #define M98095_DAI2M_TO_DACM (1<<1)
- #define M98095_DAI3M_TO_DACM (1<<0)
-
-/* M98095_04E_MIX_HP_CFG */
- #define M98095_HPNORMAL (3<<4)
-
-/* M98095_05F_LVL_MIC1, M98095_060_LVL_MIC2 */
- #define M98095_MICPRE_MASK (3<<5)
- #define M98095_MICPRE_SHIFT 5
-
-/* M98095_064_LVL_HP_L, M98095_065_LVL_HP_R */
- #define M98095_HP_MUTE (1<<7)
-
-/* M98095_066_LVL_RCV */
- #define M98095_REC_MUTE (1<<7)
-
-/* M98095_067_LVL_SPK_L, M98095_068_LVL_SPK_R */
- #define M98095_SP_MUTE (1<<7)
-
-/* M98095_087_CFG_MIC */
- #define M98095_MICSEL_MASK (3<<0)
- #define M98095_DIGMIC_L (1<<2)
- #define M98095_DIGMIC_R (1<<3)
- #define M98095_DIGMIC2L (1<<4)
- #define M98095_DIGMIC2R (1<<5)
-
-/* M98095_088_CFG_LEVEL */
- #define M98095_VSEN (1<<6)
- #define M98095_ZDEN (1<<5)
- #define M98095_BQ2EN (1<<3)
- #define M98095_BQ1EN (1<<2)
- #define M98095_EQ2EN (1<<1)
- #define M98095_EQ1EN (1<<0)
-
-/* M98095_090_PWR_EN_IN */
- #define M98095_INEN (1<<7)
- #define M98095_MB2EN (1<<3)
- #define M98095_MB1EN (1<<2)
- #define M98095_MBEN (3<<2)
- #define M98095_ADREN (1<<1)
- #define M98095_ADLEN (1<<0)
-
-/* M98095_091_PWR_EN_OUT */
- #define M98095_HPLEN (1<<7)
- #define M98095_HPREN (1<<6)
- #define M98095_SPLEN (1<<5)
- #define M98095_SPREN (1<<4)
- #define M98095_RECEN (1<<3)
- #define M98095_DALEN (1<<1)
- #define M98095_DAREN (1<<0)
-
-/* M98095_092_PWR_EN_OUT */
- #define M98095_SPK_FIXEDSPECTRUM (0<<4)
- #define M98095_SPK_SPREADSPECTRUM (1<<4)
-
-/* M98095_097_PWR_SYS */
- #define M98095_SHDNRUN (1<<7)
- #define M98095_PERFMODE (1<<3)
- #define M98095_HPPLYBACK (1<<2)
- #define M98095_PWRSV8K (1<<1)
- #define M98095_PWRSV (1<<0)
-
-#define M98095_COEFS_PER_BAND 5
-
-#define M98095_BYTE1(w) ((w >> 8) & 0xff)
-#define M98095_BYTE0(w) (w & 0xff)
-
-/* Equalizer filter coefficients */
-#define M98095_110_DAI1_EQ_BASE 0x10
-#define M98095_142_DAI2_EQ_BASE 0x42
-
-/* Biquad filter coefficients */
-#define M98095_174_DAI1_BQ_BASE 0x74
-#define M98095_17E_DAI2_BQ_BASE 0x7E
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/max9850.c b/ANDROID_3.4.5/sound/soc/codecs/max9850.c
deleted file mode 100644
index a1913091..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/max9850.c
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * max9850.c -- codec driver for max9850
- *
- * Copyright (C) 2011 taskit GmbH
- *
- * Author: Christian Glindkamp <christian.glindkamp@taskit.de>
- *
- * Initial development of this code was funded by
- * MICRONIC Computer Systeme GmbH, http://www.mcsberlin.de/
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/tlv.h>
-
-#include "max9850.h"
-
-struct max9850_priv {
- unsigned int sysclk;
-};
-
-/* max9850 register cache */
-static const u8 max9850_reg[MAX9850_CACHEREGNUM] = {
- 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/* these registers are not used at the moment but provided for the sake of
- * completeness */
-static int max9850_volatile_register(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- switch (reg) {
- case MAX9850_STATUSA:
- case MAX9850_STATUSB:
- return 1;
- default:
- return 0;
- }
-}
-
-static const unsigned int max9850_tlv[] = {
- TLV_DB_RANGE_HEAD(4),
- 0x18, 0x1f, TLV_DB_SCALE_ITEM(-7450, 400, 0),
- 0x20, 0x33, TLV_DB_SCALE_ITEM(-4150, 200, 0),
- 0x34, 0x37, TLV_DB_SCALE_ITEM(-150, 100, 0),
- 0x38, 0x3f, TLV_DB_SCALE_ITEM(250, 50, 0),
-};
-
-static const struct snd_kcontrol_new max9850_controls[] = {
-SOC_SINGLE_TLV("Headphone Volume", MAX9850_VOLUME, 0, 0x3f, 1, max9850_tlv),
-SOC_SINGLE("Headphone Switch", MAX9850_VOLUME, 7, 1, 1),
-SOC_SINGLE("Mono Switch", MAX9850_GENERAL_PURPOSE, 2, 1, 0),
-};
-
-static const struct snd_kcontrol_new max9850_mixer_controls[] = {
- SOC_DAPM_SINGLE("Line In Switch", MAX9850_ENABLE, 1, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget max9850_dapm_widgets[] = {
-SND_SOC_DAPM_SUPPLY("Charge Pump 1", MAX9850_ENABLE, 4, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("Charge Pump 2", MAX9850_ENABLE, 5, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("MCLK", MAX9850_ENABLE, 6, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("SHDN", MAX9850_ENABLE, 7, 0, NULL, 0),
-SND_SOC_DAPM_MIXER_NAMED_CTL("Output Mixer", MAX9850_ENABLE, 2, 0,
- &max9850_mixer_controls[0],
- ARRAY_SIZE(max9850_mixer_controls)),
-SND_SOC_DAPM_PGA("Headphone Output", MAX9850_ENABLE, 3, 0, NULL, 0),
-SND_SOC_DAPM_DAC("DAC", "HiFi Playback", MAX9850_ENABLE, 0, 0),
-SND_SOC_DAPM_OUTPUT("OUTL"),
-SND_SOC_DAPM_OUTPUT("HPL"),
-SND_SOC_DAPM_OUTPUT("OUTR"),
-SND_SOC_DAPM_OUTPUT("HPR"),
-SND_SOC_DAPM_MIXER("Line Input", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_INPUT("INL"),
-SND_SOC_DAPM_INPUT("INR"),
-};
-
-static const struct snd_soc_dapm_route max9850_dapm_routes[] = {
- /* output mixer */
- {"Output Mixer", NULL, "DAC"},
- {"Output Mixer", "Line In Switch", "Line Input"},
-
- /* outputs */
- {"Headphone Output", NULL, "Output Mixer"},
- {"HPL", NULL, "Headphone Output"},
- {"HPR", NULL, "Headphone Output"},
- {"OUTL", NULL, "Output Mixer"},
- {"OUTR", NULL, "Output Mixer"},
-
- /* inputs */
- {"Line Input", NULL, "INL"},
- {"Line Input", NULL, "INR"},
-
- /* supplies */
- {"Output Mixer", NULL, "Charge Pump 1"},
- {"Output Mixer", NULL, "Charge Pump 2"},
- {"Output Mixer", NULL, "SHDN"},
- {"DAC", NULL, "MCLK"},
-};
-
-static int max9850_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct max9850_priv *max9850 = snd_soc_codec_get_drvdata(codec);
- u64 lrclk_div;
- u8 sf, da;
-
- if (!max9850->sysclk)
- return -EINVAL;
-
- /* lrclk_div = 2^22 * rate / iclk with iclk = mclk / sf */
- sf = (snd_soc_read(codec, MAX9850_CLOCK) >> 2) + 1;
- lrclk_div = (1 << 22);
- lrclk_div *= params_rate(params);
- lrclk_div *= sf;
- do_div(lrclk_div, max9850->sysclk);
-
- snd_soc_write(codec, MAX9850_LRCLK_MSB, (lrclk_div >> 8) & 0x7f);
- snd_soc_write(codec, MAX9850_LRCLK_LSB, lrclk_div & 0xff);
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- da = 0;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- da = 0x2;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- da = 0x3;
- break;
- default:
- return -EINVAL;
- }
- snd_soc_update_bits(codec, MAX9850_DIGITAL_AUDIO, 0x3, da);
-
- return 0;
-}
-
-static int max9850_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct max9850_priv *max9850 = snd_soc_codec_get_drvdata(codec);
-
- /* calculate mclk -> iclk divider */
- if (freq <= 13000000)
- snd_soc_write(codec, MAX9850_CLOCK, 0x0);
- else if (freq <= 26000000)
- snd_soc_write(codec, MAX9850_CLOCK, 0x4);
- else if (freq <= 40000000)
- snd_soc_write(codec, MAX9850_CLOCK, 0x8);
- else
- return -EINVAL;
-
- max9850->sysclk = freq;
- return 0;
-}
-
-static int max9850_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u8 da = 0;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- da |= MAX9850_MASTER;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- da |= MAX9850_DLY;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- da |= MAX9850_RTJ;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- da |= MAX9850_BCINV | MAX9850_INV;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- da |= MAX9850_BCINV;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- da |= MAX9850_INV;
- break;
- default:
- return -EINVAL;
- }
-
- /* set da */
- snd_soc_write(codec, MAX9850_DIGITAL_AUDIO, da);
-
- return 0;
-}
-
-static int max9850_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- int ret;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = snd_soc_cache_sync(codec);
- if (ret) {
- dev_err(codec->dev,
- "Failed to sync cache: %d\n", ret);
- return ret;
- }
- }
- break;
- case SND_SOC_BIAS_OFF:
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define MAX9850_RATES SNDRV_PCM_RATE_8000_48000
-
-#define MAX9850_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops max9850_dai_ops = {
- .hw_params = max9850_hw_params,
- .set_sysclk = max9850_set_dai_sysclk,
- .set_fmt = max9850_set_dai_fmt,
-};
-
-static struct snd_soc_dai_driver max9850_dai = {
- .name = "max9850-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = MAX9850_RATES,
- .formats = MAX9850_FORMATS
- },
- .ops = &max9850_dai_ops,
-};
-
-#ifdef CONFIG_PM
-static int max9850_suspend(struct snd_soc_codec *codec)
-{
- max9850_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int max9850_resume(struct snd_soc_codec *codec)
-{
- max9850_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-#else
-#define max9850_suspend NULL
-#define max9850_resume NULL
-#endif
-
-static int max9850_probe(struct snd_soc_codec *codec)
-{
- int ret;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- /* enable zero-detect */
- snd_soc_update_bits(codec, MAX9850_GENERAL_PURPOSE, 1, 1);
- /* enable slew-rate control */
- snd_soc_update_bits(codec, MAX9850_VOLUME, 0x40, 0x40);
- /* set slew-rate 125ms */
- snd_soc_update_bits(codec, MAX9850_CHARGE_PUMP, 0xff, 0xc0);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_max9850 = {
- .probe = max9850_probe,
- .suspend = max9850_suspend,
- .resume = max9850_resume,
- .set_bias_level = max9850_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(max9850_reg),
- .reg_word_size = sizeof(u8),
- .reg_cache_default = max9850_reg,
- .volatile_register = max9850_volatile_register,
-
- .controls = max9850_controls,
- .num_controls = ARRAY_SIZE(max9850_controls),
- .dapm_widgets = max9850_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(max9850_dapm_widgets),
- .dapm_routes = max9850_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(max9850_dapm_routes),
-};
-
-static int __devinit max9850_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct max9850_priv *max9850;
- int ret;
-
- max9850 = devm_kzalloc(&i2c->dev, sizeof(struct max9850_priv),
- GFP_KERNEL);
- if (max9850 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, max9850);
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_max9850, &max9850_dai, 1);
- return ret;
-}
-
-static __devexit int max9850_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static const struct i2c_device_id max9850_i2c_id[] = {
- { "max9850", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, max9850_i2c_id);
-
-static struct i2c_driver max9850_i2c_driver = {
- .driver = {
- .name = "max9850",
- .owner = THIS_MODULE,
- },
- .probe = max9850_i2c_probe,
- .remove = __devexit_p(max9850_i2c_remove),
- .id_table = max9850_i2c_id,
-};
-
-static int __init max9850_init(void)
-{
- return i2c_add_driver(&max9850_i2c_driver);
-}
-module_init(max9850_init);
-
-static void __exit max9850_exit(void)
-{
- i2c_del_driver(&max9850_i2c_driver);
-}
-module_exit(max9850_exit);
-
-MODULE_AUTHOR("Christian Glindkamp <christian.glindkamp@taskit.de>");
-MODULE_DESCRIPTION("ASoC MAX9850 codec driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/max9850.h b/ANDROID_3.4.5/sound/soc/codecs/max9850.h
deleted file mode 100644
index 72b1ddb0..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/max9850.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * max9850.h -- codec driver for max9850
- *
- * Copyright (C) 2011 taskit GmbH
- * Author: Christian Glindkamp <christian.glindkamp@taskit.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#ifndef _MAX9850_H
-#define _MAX9850_H
-
-#define MAX9850_STATUSA 0x00
-#define MAX9850_STATUSB 0x01
-#define MAX9850_VOLUME 0x02
-#define MAX9850_GENERAL_PURPOSE 0x03
-#define MAX9850_INTERRUPT 0x04
-#define MAX9850_ENABLE 0x05
-#define MAX9850_CLOCK 0x06
-#define MAX9850_CHARGE_PUMP 0x07
-#define MAX9850_LRCLK_MSB 0x08
-#define MAX9850_LRCLK_LSB 0x09
-#define MAX9850_DIGITAL_AUDIO 0x0a
-
-#define MAX9850_CACHEREGNUM 11
-
-/* MAX9850_DIGITAL_AUDIO */
-#define MAX9850_MASTER (1<<7)
-#define MAX9850_INV (1<<6)
-#define MAX9850_BCINV (1<<5)
-#define MAX9850_DLY (1<<3)
-#define MAX9850_RTJ (1<<2)
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/max9877.c b/ANDROID_3.4.5/sound/soc/codecs/max9877.c
deleted file mode 100644
index 3a2ba3d8..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/max9877.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * max9877.c -- amp driver for max9877
- *
- * Copyright (C) 2009 Samsung Electronics Co.Ltd
- * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <sound/soc.h>
-#include <sound/tlv.h>
-
-#include "max9877.h"
-
-static struct i2c_client *i2c;
-
-static u8 max9877_regs[5] = { 0x40, 0x00, 0x00, 0x00, 0x49 };
-
-static void max9877_write_regs(void)
-{
- unsigned int i;
- u8 data[6];
-
- data[0] = MAX9877_INPUT_MODE;
- for (i = 0; i < ARRAY_SIZE(max9877_regs); i++)
- data[i + 1] = max9877_regs[i];
-
- if (i2c_master_send(i2c, data, 6) != 6)
- dev_err(&i2c->dev, "i2c write failed\n");
-}
-
-static int max9877_get_reg(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- unsigned int reg = mc->reg;
- unsigned int shift = mc->shift;
- unsigned int mask = mc->max;
- unsigned int invert = mc->invert;
-
- ucontrol->value.integer.value[0] = (max9877_regs[reg] >> shift) & mask;
-
- if (invert)
- ucontrol->value.integer.value[0] =
- mask - ucontrol->value.integer.value[0];
-
- return 0;
-}
-
-static int max9877_set_reg(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- unsigned int reg = mc->reg;
- unsigned int shift = mc->shift;
- unsigned int mask = mc->max;
- unsigned int invert = mc->invert;
- unsigned int val = (ucontrol->value.integer.value[0] & mask);
-
- if (invert)
- val = mask - val;
-
- if (((max9877_regs[reg] >> shift) & mask) == val)
- return 0;
-
- max9877_regs[reg] &= ~(mask << shift);
- max9877_regs[reg] |= val << shift;
- max9877_write_regs();
-
- return 1;
-}
-
-static int max9877_get_2reg(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- unsigned int reg = mc->reg;
- unsigned int reg2 = mc->rreg;
- unsigned int shift = mc->shift;
- unsigned int mask = mc->max;
-
- ucontrol->value.integer.value[0] = (max9877_regs[reg] >> shift) & mask;
- ucontrol->value.integer.value[1] = (max9877_regs[reg2] >> shift) & mask;
-
- return 0;
-}
-
-static int max9877_set_2reg(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- unsigned int reg = mc->reg;
- unsigned int reg2 = mc->rreg;
- unsigned int shift = mc->shift;
- unsigned int mask = mc->max;
- unsigned int val = (ucontrol->value.integer.value[0] & mask);
- unsigned int val2 = (ucontrol->value.integer.value[1] & mask);
- unsigned int change = 0;
-
- if (((max9877_regs[reg] >> shift) & mask) != val)
- change = 1;
-
- if (((max9877_regs[reg2] >> shift) & mask) != val2)
- change = 1;
-
- if (change) {
- max9877_regs[reg] &= ~(mask << shift);
- max9877_regs[reg] |= val << shift;
- max9877_regs[reg2] &= ~(mask << shift);
- max9877_regs[reg2] |= val2 << shift;
- max9877_write_regs();
- }
-
- return change;
-}
-
-static int max9877_get_out_mode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- u8 value = max9877_regs[MAX9877_OUTPUT_MODE] & MAX9877_OUTMODE_MASK;
-
- if (value)
- value -= 1;
-
- ucontrol->value.integer.value[0] = value;
- return 0;
-}
-
-static int max9877_set_out_mode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- u8 value = ucontrol->value.integer.value[0];
-
- value += 1;
-
- if ((max9877_regs[MAX9877_OUTPUT_MODE] & MAX9877_OUTMODE_MASK) == value)
- return 0;
-
- max9877_regs[MAX9877_OUTPUT_MODE] &= ~MAX9877_OUTMODE_MASK;
- max9877_regs[MAX9877_OUTPUT_MODE] |= value;
- max9877_write_regs();
- return 1;
-}
-
-static int max9877_get_osc_mode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- u8 value = (max9877_regs[MAX9877_OUTPUT_MODE] & MAX9877_OSC_MASK);
-
- value = value >> MAX9877_OSC_OFFSET;
-
- ucontrol->value.integer.value[0] = value;
- return 0;
-}
-
-static int max9877_set_osc_mode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- u8 value = ucontrol->value.integer.value[0];
-
- value = value << MAX9877_OSC_OFFSET;
- if ((max9877_regs[MAX9877_OUTPUT_MODE] & MAX9877_OSC_MASK) == value)
- return 0;
-
- max9877_regs[MAX9877_OUTPUT_MODE] &= ~MAX9877_OSC_MASK;
- max9877_regs[MAX9877_OUTPUT_MODE] |= value;
- max9877_write_regs();
- return 1;
-}
-
-static const unsigned int max9877_pgain_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 1, TLV_DB_SCALE_ITEM(0, 900, 0),
- 2, 2, TLV_DB_SCALE_ITEM(2000, 0, 0),
-};
-
-static const unsigned int max9877_output_tlv[] = {
- TLV_DB_RANGE_HEAD(4),
- 0, 7, TLV_DB_SCALE_ITEM(-7900, 400, 1),
- 8, 15, TLV_DB_SCALE_ITEM(-4700, 300, 0),
- 16, 23, TLV_DB_SCALE_ITEM(-2300, 200, 0),
- 24, 31, TLV_DB_SCALE_ITEM(-700, 100, 0),
-};
-
-static const char *max9877_out_mode[] = {
- "INA -> SPK",
- "INA -> HP",
- "INA -> SPK and HP",
- "INB -> SPK",
- "INB -> HP",
- "INB -> SPK and HP",
- "INA + INB -> SPK",
- "INA + INB -> HP",
- "INA + INB -> SPK and HP",
-};
-
-static const char *max9877_osc_mode[] = {
- "1176KHz",
- "1100KHz",
- "700KHz",
-};
-
-static const struct soc_enum max9877_enum[] = {
- SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(max9877_out_mode), max9877_out_mode),
- SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(max9877_osc_mode), max9877_osc_mode),
-};
-
-static const struct snd_kcontrol_new max9877_controls[] = {
- SOC_SINGLE_EXT_TLV("MAX9877 PGAINA Playback Volume",
- MAX9877_INPUT_MODE, 0, 2, 0,
- max9877_get_reg, max9877_set_reg, max9877_pgain_tlv),
- SOC_SINGLE_EXT_TLV("MAX9877 PGAINB Playback Volume",
- MAX9877_INPUT_MODE, 2, 2, 0,
- max9877_get_reg, max9877_set_reg, max9877_pgain_tlv),
- SOC_SINGLE_EXT_TLV("MAX9877 Amp Speaker Playback Volume",
- MAX9877_SPK_VOLUME, 0, 31, 0,
- max9877_get_reg, max9877_set_reg, max9877_output_tlv),
- SOC_DOUBLE_R_EXT_TLV("MAX9877 Amp HP Playback Volume",
- MAX9877_HPL_VOLUME, MAX9877_HPR_VOLUME, 0, 31, 0,
- max9877_get_2reg, max9877_set_2reg, max9877_output_tlv),
- SOC_SINGLE_EXT("MAX9877 INB Stereo Switch",
- MAX9877_INPUT_MODE, 4, 1, 1,
- max9877_get_reg, max9877_set_reg),
- SOC_SINGLE_EXT("MAX9877 INA Stereo Switch",
- MAX9877_INPUT_MODE, 5, 1, 1,
- max9877_get_reg, max9877_set_reg),
- SOC_SINGLE_EXT("MAX9877 Zero-crossing detection Switch",
- MAX9877_INPUT_MODE, 6, 1, 0,
- max9877_get_reg, max9877_set_reg),
- SOC_SINGLE_EXT("MAX9877 Bypass Mode Switch",
- MAX9877_OUTPUT_MODE, 6, 1, 0,
- max9877_get_reg, max9877_set_reg),
- SOC_SINGLE_EXT("MAX9877 Shutdown Mode Switch",
- MAX9877_OUTPUT_MODE, 7, 1, 1,
- max9877_get_reg, max9877_set_reg),
- SOC_ENUM_EXT("MAX9877 Output Mode", max9877_enum[0],
- max9877_get_out_mode, max9877_set_out_mode),
- SOC_ENUM_EXT("MAX9877 Oscillator Mode", max9877_enum[1],
- max9877_get_osc_mode, max9877_set_osc_mode),
-};
-
-/* This function is called from ASoC machine driver */
-int max9877_add_controls(struct snd_soc_codec *codec)
-{
- return snd_soc_add_codec_controls(codec, max9877_controls,
- ARRAY_SIZE(max9877_controls));
-}
-EXPORT_SYMBOL_GPL(max9877_add_controls);
-
-static int __devinit max9877_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- i2c = client;
-
- max9877_write_regs();
-
- return 0;
-}
-
-static __devexit int max9877_i2c_remove(struct i2c_client *client)
-{
- i2c = NULL;
-
- return 0;
-}
-
-static const struct i2c_device_id max9877_i2c_id[] = {
- { "max9877", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, max9877_i2c_id);
-
-static struct i2c_driver max9877_i2c_driver = {
- .driver = {
- .name = "max9877",
- .owner = THIS_MODULE,
- },
- .probe = max9877_i2c_probe,
- .remove = __devexit_p(max9877_i2c_remove),
- .id_table = max9877_i2c_id,
-};
-
-static int __init max9877_init(void)
-{
- return i2c_add_driver(&max9877_i2c_driver);
-}
-module_init(max9877_init);
-
-static void __exit max9877_exit(void)
-{
- i2c_del_driver(&max9877_i2c_driver);
-}
-module_exit(max9877_exit);
-
-MODULE_DESCRIPTION("ASoC MAX9877 amp driver");
-MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/max9877.h b/ANDROID_3.4.5/sound/soc/codecs/max9877.h
deleted file mode 100644
index 6da72290..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/max9877.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * max9877.h -- amp driver for max9877
- *
- * Copyright (C) 2009 Samsung Electronics Co.Ltd
- * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#ifndef _MAX9877_H
-#define _MAX9877_H
-
-#define MAX9877_INPUT_MODE 0x00
-#define MAX9877_SPK_VOLUME 0x01
-#define MAX9877_HPL_VOLUME 0x02
-#define MAX9877_HPR_VOLUME 0x03
-#define MAX9877_OUTPUT_MODE 0x04
-
-/* MAX9877_INPUT_MODE */
-#define MAX9877_INB (1 << 4)
-#define MAX9877_INA (1 << 5)
-#define MAX9877_ZCD (1 << 6)
-
-/* MAX9877_OUTPUT_MODE */
-#define MAX9877_OUTMODE_MASK (15 << 0)
-#define MAX9877_OSC_MASK (3 << 4)
-#define MAX9877_OSC_OFFSET 4
-#define MAX9877_BYPASS (1 << 6)
-#define MAX9877_SHDN (1 << 7)
-
-extern int max9877_add_controls(struct snd_soc_codec *codec);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/pcm3008.c b/ANDROID_3.4.5/sound/soc/codecs/pcm3008.c
deleted file mode 100644
index edcaa7ea..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/pcm3008.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * ALSA Soc PCM3008 codec support
- *
- * Author: Hugo Villeneuve
- * Copyright (C) 2008 Lyrtech inc
- *
- * Based on AC97 Soc codec, original copyright follow:
- * Copyright 2005 Wolfson Microelectronics PLC.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * Generic PCM3008 support.
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/gpio.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include "pcm3008.h"
-
-#define PCM3008_VERSION "0.2"
-
-#define PCM3008_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000)
-
-static struct snd_soc_dai_driver pcm3008_dai = {
- .name = "pcm3008-hifi",
- .playback = {
- .stream_name = "PCM3008 Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = PCM3008_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .capture = {
- .stream_name = "PCM3008 Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = PCM3008_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
-};
-
-static void pcm3008_gpio_free(struct pcm3008_setup_data *setup)
-{
- gpio_free(setup->dem0_pin);
- gpio_free(setup->dem1_pin);
- gpio_free(setup->pdad_pin);
- gpio_free(setup->pdda_pin);
-}
-
-static int pcm3008_soc_probe(struct snd_soc_codec *codec)
-{
- struct pcm3008_setup_data *setup = codec->dev->platform_data;
- int ret = 0;
-
- printk(KERN_INFO "PCM3008 SoC Audio Codec %s\n", PCM3008_VERSION);
-
- /* DEM1 DEM0 DE-EMPHASIS_MODE
- * Low Low De-emphasis 44.1 kHz ON
- * Low High De-emphasis OFF
- * High Low De-emphasis 48 kHz ON
- * High High De-emphasis 32 kHz ON
- */
-
- /* Configure DEM0 GPIO (turning OFF DAC De-emphasis). */
- ret = gpio_request(setup->dem0_pin, "codec_dem0");
- if (ret == 0)
- ret = gpio_direction_output(setup->dem0_pin, 1);
- if (ret != 0)
- goto gpio_err;
-
- /* Configure DEM1 GPIO (turning OFF DAC De-emphasis). */
- ret = gpio_request(setup->dem1_pin, "codec_dem1");
- if (ret == 0)
- ret = gpio_direction_output(setup->dem1_pin, 0);
- if (ret != 0)
- goto gpio_err;
-
- /* Configure PDAD GPIO. */
- ret = gpio_request(setup->pdad_pin, "codec_pdad");
- if (ret == 0)
- ret = gpio_direction_output(setup->pdad_pin, 1);
- if (ret != 0)
- goto gpio_err;
-
- /* Configure PDDA GPIO. */
- ret = gpio_request(setup->pdda_pin, "codec_pdda");
- if (ret == 0)
- ret = gpio_direction_output(setup->pdda_pin, 1);
- if (ret != 0)
- goto gpio_err;
-
- return ret;
-
-gpio_err:
- pcm3008_gpio_free(setup);
-
- return ret;
-}
-
-static int pcm3008_soc_remove(struct snd_soc_codec *codec)
-{
- struct pcm3008_setup_data *setup = codec->dev->platform_data;
-
- pcm3008_gpio_free(setup);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int pcm3008_soc_suspend(struct snd_soc_codec *codec)
-{
- struct pcm3008_setup_data *setup = codec->dev->platform_data;
-
- gpio_set_value(setup->pdad_pin, 0);
- gpio_set_value(setup->pdda_pin, 0);
-
- return 0;
-}
-
-static int pcm3008_soc_resume(struct snd_soc_codec *codec)
-{
- struct pcm3008_setup_data *setup = codec->dev->platform_data;
-
- gpio_set_value(setup->pdad_pin, 1);
- gpio_set_value(setup->pdda_pin, 1);
-
- return 0;
-}
-#else
-#define pcm3008_soc_suspend NULL
-#define pcm3008_soc_resume NULL
-#endif
-
-static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = {
- .probe = pcm3008_soc_probe,
- .remove = pcm3008_soc_remove,
- .suspend = pcm3008_soc_suspend,
- .resume = pcm3008_soc_resume,
-};
-
-static int __devinit pcm3008_codec_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev,
- &soc_codec_dev_pcm3008, &pcm3008_dai, 1);
-}
-
-static int __devexit pcm3008_codec_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-MODULE_ALIAS("platform:pcm3008-codec");
-
-static struct platform_driver pcm3008_codec_driver = {
- .probe = pcm3008_codec_probe,
- .remove = __devexit_p(pcm3008_codec_remove),
- .driver = {
- .name = "pcm3008-codec",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(pcm3008_codec_driver);
-
-MODULE_DESCRIPTION("Soc PCM3008 driver");
-MODULE_AUTHOR("Hugo Villeneuve");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/pcm3008.h b/ANDROID_3.4.5/sound/soc/codecs/pcm3008.h
deleted file mode 100644
index 7e5489ab..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/pcm3008.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * PCM3008 ALSA SoC Layer
- *
- * Author: Hugo Villeneuve
- * Copyright (C) 2008 Lyrtech inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __LINUX_SND_SOC_PCM3008_H
-#define __LINUX_SND_SOC_PCM3008_H
-
-struct pcm3008_setup_data {
- unsigned dem0_pin;
- unsigned dem1_pin;
- unsigned pdad_pin;
- unsigned pdda_pin;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/rt5631.c b/ANDROID_3.4.5/sound/soc/codecs/rt5631.c
deleted file mode 100644
index 20c324c7..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/rt5631.c
+++ /dev/null
@@ -1,1769 +0,0 @@
-/*
- * rt5631.c -- RT5631 ALSA Soc Audio driver
- *
- * Copyright 2011 Realtek Microelectronics
- *
- * Author: flove <flove@realtek.com>
- *
- * Based on WM8753.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/spi/spi.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "rt5631.h"
-
-struct rt5631_priv {
- int codec_version;
- int master;
- int sysclk;
- int rx_rate;
- int bclk_rate;
- int dmic_used_flag;
-};
-
-static const u16 rt5631_reg[RT5631_VENDOR_ID2 + 1] = {
- [RT5631_SPK_OUT_VOL] = 0x8888,
- [RT5631_HP_OUT_VOL] = 0x8080,
- [RT5631_MONO_AXO_1_2_VOL] = 0xa080,
- [RT5631_AUX_IN_VOL] = 0x0808,
- [RT5631_ADC_REC_MIXER] = 0xf0f0,
- [RT5631_VDAC_DIG_VOL] = 0x0010,
- [RT5631_OUTMIXER_L_CTRL] = 0xffc0,
- [RT5631_OUTMIXER_R_CTRL] = 0xffc0,
- [RT5631_AXO1MIXER_CTRL] = 0x88c0,
- [RT5631_AXO2MIXER_CTRL] = 0x88c0,
- [RT5631_DIG_MIC_CTRL] = 0x3000,
- [RT5631_MONO_INPUT_VOL] = 0x8808,
- [RT5631_SPK_MIXER_CTRL] = 0xf8f8,
- [RT5631_SPK_MONO_OUT_CTRL] = 0xfc00,
- [RT5631_SPK_MONO_HP_OUT_CTRL] = 0x4440,
- [RT5631_SDP_CTRL] = 0x8000,
- [RT5631_MONO_SDP_CTRL] = 0x8000,
- [RT5631_STEREO_AD_DA_CLK_CTRL] = 0x2010,
- [RT5631_GEN_PUR_CTRL_REG] = 0x0e00,
- [RT5631_INT_ST_IRQ_CTRL_2] = 0x071a,
- [RT5631_MISC_CTRL] = 0x2040,
- [RT5631_DEPOP_FUN_CTRL_2] = 0x8000,
- [RT5631_SOFT_VOL_CTRL] = 0x07e0,
- [RT5631_ALC_CTRL_1] = 0x0206,
- [RT5631_ALC_CTRL_3] = 0x2000,
- [RT5631_PSEUDO_SPATL_CTRL] = 0x0553,
-};
-
-/**
- * rt5631_write_index - write index register of 2nd layer
- */
-static void rt5631_write_index(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int value)
-{
- snd_soc_write(codec, RT5631_INDEX_ADD, reg);
- snd_soc_write(codec, RT5631_INDEX_DATA, value);
-}
-
-/**
- * rt5631_read_index - read index register of 2nd layer
- */
-static unsigned int rt5631_read_index(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- unsigned int value;
-
- snd_soc_write(codec, RT5631_INDEX_ADD, reg);
- value = snd_soc_read(codec, RT5631_INDEX_DATA);
-
- return value;
-}
-
-static int rt5631_reset(struct snd_soc_codec *codec)
-{
- return snd_soc_write(codec, RT5631_RESET, 0);
-}
-
-static int rt5631_volatile_register(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- switch (reg) {
- case RT5631_RESET:
- case RT5631_INT_ST_IRQ_CTRL_2:
- case RT5631_INDEX_ADD:
- case RT5631_INDEX_DATA:
- case RT5631_EQ_CTRL:
- return 1;
- default:
- return 0;
- }
-}
-
-static int rt5631_readable_register(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- switch (reg) {
- case RT5631_RESET:
- case RT5631_SPK_OUT_VOL:
- case RT5631_HP_OUT_VOL:
- case RT5631_MONO_AXO_1_2_VOL:
- case RT5631_AUX_IN_VOL:
- case RT5631_STEREO_DAC_VOL_1:
- case RT5631_MIC_CTRL_1:
- case RT5631_STEREO_DAC_VOL_2:
- case RT5631_ADC_CTRL_1:
- case RT5631_ADC_REC_MIXER:
- case RT5631_ADC_CTRL_2:
- case RT5631_VDAC_DIG_VOL:
- case RT5631_OUTMIXER_L_CTRL:
- case RT5631_OUTMIXER_R_CTRL:
- case RT5631_AXO1MIXER_CTRL:
- case RT5631_AXO2MIXER_CTRL:
- case RT5631_MIC_CTRL_2:
- case RT5631_DIG_MIC_CTRL:
- case RT5631_MONO_INPUT_VOL:
- case RT5631_SPK_MIXER_CTRL:
- case RT5631_SPK_MONO_OUT_CTRL:
- case RT5631_SPK_MONO_HP_OUT_CTRL:
- case RT5631_SDP_CTRL:
- case RT5631_MONO_SDP_CTRL:
- case RT5631_STEREO_AD_DA_CLK_CTRL:
- case RT5631_PWR_MANAG_ADD1:
- case RT5631_PWR_MANAG_ADD2:
- case RT5631_PWR_MANAG_ADD3:
- case RT5631_PWR_MANAG_ADD4:
- case RT5631_GEN_PUR_CTRL_REG:
- case RT5631_GLOBAL_CLK_CTRL:
- case RT5631_PLL_CTRL:
- case RT5631_INT_ST_IRQ_CTRL_1:
- case RT5631_INT_ST_IRQ_CTRL_2:
- case RT5631_GPIO_CTRL:
- case RT5631_MISC_CTRL:
- case RT5631_DEPOP_FUN_CTRL_1:
- case RT5631_DEPOP_FUN_CTRL_2:
- case RT5631_JACK_DET_CTRL:
- case RT5631_SOFT_VOL_CTRL:
- case RT5631_ALC_CTRL_1:
- case RT5631_ALC_CTRL_2:
- case RT5631_ALC_CTRL_3:
- case RT5631_PSEUDO_SPATL_CTRL:
- case RT5631_INDEX_ADD:
- case RT5631_INDEX_DATA:
- case RT5631_EQ_CTRL:
- case RT5631_VENDOR_ID:
- case RT5631_VENDOR_ID1:
- case RT5631_VENDOR_ID2:
- return 1;
- default:
- return 0;
- }
-}
-
-static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
-static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -95625, 375, 0);
-static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
-/* {0, +20, +24, +30, +35, +40, +44, +50, +52}dB */
-static unsigned int mic_bst_tlv[] = {
- TLV_DB_RANGE_HEAD(7),
- 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
- 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
- 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
- 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0),
- 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0),
- 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0),
- 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0),
-};
-
-static int rt5631_dmic_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.integer.value[0] = rt5631->dmic_used_flag;
-
- return 0;
-}
-
-static int rt5631_dmic_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
-
- rt5631->dmic_used_flag = ucontrol->value.integer.value[0];
- return 0;
-}
-
-/* MIC Input Type */
-static const char *rt5631_input_mode[] = {
- "Single ended", "Differential"};
-
-static const SOC_ENUM_SINGLE_DECL(
- rt5631_mic1_mode_enum, RT5631_MIC_CTRL_1,
- RT5631_MIC1_DIFF_INPUT_SHIFT, rt5631_input_mode);
-
-static const SOC_ENUM_SINGLE_DECL(
- rt5631_mic2_mode_enum, RT5631_MIC_CTRL_1,
- RT5631_MIC2_DIFF_INPUT_SHIFT, rt5631_input_mode);
-
-/* MONO Input Type */
-static const SOC_ENUM_SINGLE_DECL(
- rt5631_monoin_mode_enum, RT5631_MONO_INPUT_VOL,
- RT5631_MONO_DIFF_INPUT_SHIFT, rt5631_input_mode);
-
-/* SPK Ratio Gain Control */
-static const char *rt5631_spk_ratio[] = {"1.00x", "1.09x", "1.27x", "1.44x",
- "1.56x", "1.68x", "1.99x", "2.34x"};
-
-static const SOC_ENUM_SINGLE_DECL(
- rt5631_spk_ratio_enum, RT5631_GEN_PUR_CTRL_REG,
- RT5631_SPK_AMP_RATIO_CTRL_SHIFT, rt5631_spk_ratio);
-
-static const struct snd_kcontrol_new rt5631_snd_controls[] = {
- /* MIC */
- SOC_ENUM("MIC1 Mode Control", rt5631_mic1_mode_enum),
- SOC_SINGLE_TLV("MIC1 Boost", RT5631_MIC_CTRL_2,
- RT5631_MIC1_BOOST_SHIFT, 8, 0, mic_bst_tlv),
- SOC_ENUM("MIC2 Mode Control", rt5631_mic2_mode_enum),
- SOC_SINGLE_TLV("MIC2 Boost", RT5631_MIC_CTRL_2,
- RT5631_MIC2_BOOST_SHIFT, 8, 0, mic_bst_tlv),
- /* MONO IN */
- SOC_ENUM("MONOIN Mode Control", rt5631_monoin_mode_enum),
- SOC_DOUBLE_TLV("MONOIN_RX Capture Volume", RT5631_MONO_INPUT_VOL,
- RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT,
- RT5631_VOL_MASK, 1, in_vol_tlv),
- /* AXI */
- SOC_DOUBLE_TLV("AXI Capture Volume", RT5631_AUX_IN_VOL,
- RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT,
- RT5631_VOL_MASK, 1, in_vol_tlv),
- /* DAC */
- SOC_DOUBLE_TLV("PCM Playback Volume", RT5631_STEREO_DAC_VOL_2,
- RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT,
- RT5631_DAC_VOL_MASK, 1, dac_vol_tlv),
- SOC_DOUBLE("PCM Playback Switch", RT5631_STEREO_DAC_VOL_1,
- RT5631_L_MUTE_SHIFT, RT5631_R_MUTE_SHIFT, 1, 1),
- /* AXO */
- SOC_SINGLE("AXO1 Playback Switch", RT5631_MONO_AXO_1_2_VOL,
- RT5631_L_MUTE_SHIFT, 1, 1),
- SOC_SINGLE("AXO2 Playback Switch", RT5631_MONO_AXO_1_2_VOL,
- RT5631_R_VOL_SHIFT, 1, 1),
- /* OUTVOL */
- SOC_DOUBLE("OUTVOL Channel Switch", RT5631_SPK_OUT_VOL,
- RT5631_L_EN_SHIFT, RT5631_R_EN_SHIFT, 1, 0),
-
- /* SPK */
- SOC_DOUBLE("Speaker Playback Switch", RT5631_SPK_OUT_VOL,
- RT5631_L_MUTE_SHIFT, RT5631_R_MUTE_SHIFT, 1, 1),
- SOC_DOUBLE_TLV("Speaker Playback Volume", RT5631_SPK_OUT_VOL,
- RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT, 39, 1, out_vol_tlv),
- /* MONO OUT */
- SOC_SINGLE("MONO Playback Switch", RT5631_MONO_AXO_1_2_VOL,
- RT5631_MUTE_MONO_SHIFT, 1, 1),
- /* HP */
- SOC_DOUBLE("HP Playback Switch", RT5631_HP_OUT_VOL,
- RT5631_L_MUTE_SHIFT, RT5631_R_MUTE_SHIFT, 1, 1),
- SOC_DOUBLE_TLV("HP Playback Volume", RT5631_HP_OUT_VOL,
- RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT,
- RT5631_VOL_MASK, 1, out_vol_tlv),
- /* DMIC */
- SOC_SINGLE_EXT("DMIC Switch", 0, 0, 1, 0,
- rt5631_dmic_get, rt5631_dmic_put),
- SOC_DOUBLE("DMIC Capture Switch", RT5631_DIG_MIC_CTRL,
- RT5631_DMIC_L_CH_MUTE_SHIFT,
- RT5631_DMIC_R_CH_MUTE_SHIFT, 1, 1),
-
- /* SPK Ratio Gain Control */
- SOC_ENUM("SPK Ratio Control", rt5631_spk_ratio_enum),
-};
-
-static int check_sysclk1_source(struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink)
-{
- unsigned int reg;
-
- reg = snd_soc_read(source->codec, RT5631_GLOBAL_CLK_CTRL);
- return reg & RT5631_SYSCLK_SOUR_SEL_PLL;
-}
-
-static int check_dmic_used(struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink)
-{
- struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(source->codec);
- return rt5631->dmic_used_flag;
-}
-
-static int check_dacl_to_outmixl(struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink)
-{
- unsigned int reg;
-
- reg = snd_soc_read(source->codec, RT5631_OUTMIXER_L_CTRL);
- return !(reg & RT5631_M_DAC_L_TO_OUTMIXER_L);
-}
-
-static int check_dacr_to_outmixr(struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink)
-{
- unsigned int reg;
-
- reg = snd_soc_read(source->codec, RT5631_OUTMIXER_R_CTRL);
- return !(reg & RT5631_M_DAC_R_TO_OUTMIXER_R);
-}
-
-static int check_dacl_to_spkmixl(struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink)
-{
- unsigned int reg;
-
- reg = snd_soc_read(source->codec, RT5631_SPK_MIXER_CTRL);
- return !(reg & RT5631_M_DAC_L_TO_SPKMIXER_L);
-}
-
-static int check_dacr_to_spkmixr(struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink)
-{
- unsigned int reg;
-
- reg = snd_soc_read(source->codec, RT5631_SPK_MIXER_CTRL);
- return !(reg & RT5631_M_DAC_R_TO_SPKMIXER_R);
-}
-
-static int check_adcl_select(struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink)
-{
- unsigned int reg;
-
- reg = snd_soc_read(source->codec, RT5631_ADC_REC_MIXER);
- return !(reg & RT5631_M_MIC1_TO_RECMIXER_L);
-}
-
-static int check_adcr_select(struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink)
-{
- unsigned int reg;
-
- reg = snd_soc_read(source->codec, RT5631_ADC_REC_MIXER);
- return !(reg & RT5631_M_MIC2_TO_RECMIXER_R);
-}
-
-/**
- * onebit_depop_power_stage - auto depop in power stage.
- * @enable: power on/off
- *
- * When power on/off headphone, the depop sequence is done by hardware.
- */
-static void onebit_depop_power_stage(struct snd_soc_codec *codec, int enable)
-{
- unsigned int soft_vol, hp_zc;
-
- /* enable one-bit depop function */
- snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
- RT5631_EN_ONE_BIT_DEPOP, 0);
-
- /* keep soft volume and zero crossing setting */
- soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
- snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
- hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
- snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
- if (enable) {
- /* config one-bit depop parameter */
- rt5631_write_index(codec, RT5631_TEST_MODE_CTRL, 0x84c0);
- rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x309f);
- rt5631_write_index(codec, RT5631_CP_INTL_REG2, 0x6530);
- /* power on capless block */
- snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_2,
- RT5631_EN_CAP_FREE_DEPOP);
- } else {
- /* power off capless block */
- snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_2, 0);
- msleep(100);
- }
-
- /* recover soft volume and zero crossing setting */
- snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
- snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
-}
-
-/**
- * onebit_depop_mute_stage - auto depop in mute stage.
- * @enable: mute/unmute
- *
- * When mute/unmute headphone, the depop sequence is done by hardware.
- */
-static void onebit_depop_mute_stage(struct snd_soc_codec *codec, int enable)
-{
- unsigned int soft_vol, hp_zc;
-
- /* enable one-bit depop function */
- snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
- RT5631_EN_ONE_BIT_DEPOP, 0);
-
- /* keep soft volume and zero crossing setting */
- soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
- snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
- hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
- snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
- if (enable) {
- schedule_timeout_uninterruptible(msecs_to_jiffies(10));
- /* config one-bit depop parameter */
- rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x307f);
- snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
- RT5631_L_MUTE | RT5631_R_MUTE, 0);
- msleep(300);
- } else {
- snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
- RT5631_L_MUTE | RT5631_R_MUTE,
- RT5631_L_MUTE | RT5631_R_MUTE);
- msleep(100);
- }
-
- /* recover soft volume and zero crossing setting */
- snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
- snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
-}
-
-/**
- * onebit_depop_power_stage - step by step depop sequence in power stage.
- * @enable: power on/off
- *
- * When power on/off headphone, the depop sequence is done in step by step.
- */
-static void depop_seq_power_stage(struct snd_soc_codec *codec, int enable)
-{
- unsigned int soft_vol, hp_zc;
-
- /* depop control by register */
- snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
- RT5631_EN_ONE_BIT_DEPOP, RT5631_EN_ONE_BIT_DEPOP);
-
- /* keep soft volume and zero crossing setting */
- soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
- snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
- hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
- snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
- if (enable) {
- /* config depop sequence parameter */
- rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x303e);
-
- /* power on headphone and charge pump */
- snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
- RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP |
- RT5631_PWR_HP_R_AMP,
- RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP |
- RT5631_PWR_HP_R_AMP);
-
- /* power on soft generator and depop mode2 */
- snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
- RT5631_POW_ON_SOFT_GEN | RT5631_EN_DEPOP2_FOR_HP);
- msleep(100);
-
- /* stop depop mode */
- snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
- RT5631_PWR_HP_DEPOP_DIS, RT5631_PWR_HP_DEPOP_DIS);
- } else {
- /* config depop sequence parameter */
- rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x303F);
- snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
- RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP |
- RT5631_PD_HPAMP_L_ST_UP | RT5631_PD_HPAMP_R_ST_UP);
- msleep(75);
- snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
- RT5631_POW_ON_SOFT_GEN | RT5631_PD_HPAMP_L_ST_UP |
- RT5631_PD_HPAMP_R_ST_UP);
-
- /* start depop mode */
- snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
- RT5631_PWR_HP_DEPOP_DIS, 0);
-
- /* config depop sequence parameter */
- snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
- RT5631_POW_ON_SOFT_GEN | RT5631_EN_DEPOP2_FOR_HP |
- RT5631_PD_HPAMP_L_ST_UP | RT5631_PD_HPAMP_R_ST_UP);
- msleep(80);
- snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
- RT5631_POW_ON_SOFT_GEN);
-
- /* power down headphone and charge pump */
- snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
- RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP |
- RT5631_PWR_HP_R_AMP, 0);
- }
-
- /* recover soft volume and zero crossing setting */
- snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
- snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
-}
-
-/**
- * depop_seq_mute_stage - step by step depop sequence in mute stage.
- * @enable: mute/unmute
- *
- * When mute/unmute headphone, the depop sequence is done in step by step.
- */
-static void depop_seq_mute_stage(struct snd_soc_codec *codec, int enable)
-{
- unsigned int soft_vol, hp_zc;
-
- /* depop control by register */
- snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
- RT5631_EN_ONE_BIT_DEPOP, RT5631_EN_ONE_BIT_DEPOP);
-
- /* keep soft volume and zero crossing setting */
- soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
- snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
- hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
- snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
- if (enable) {
- schedule_timeout_uninterruptible(msecs_to_jiffies(10));
-
- /* config depop sequence parameter */
- rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x302f);
- snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
- RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP |
- RT5631_EN_HP_R_M_UN_MUTE_DEPOP |
- RT5631_EN_HP_L_M_UN_MUTE_DEPOP);
-
- snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
- RT5631_L_MUTE | RT5631_R_MUTE, 0);
- msleep(160);
- } else {
- /* config depop sequence parameter */
- rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x302f);
- snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
- RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP |
- RT5631_EN_HP_R_M_UN_MUTE_DEPOP |
- RT5631_EN_HP_L_M_UN_MUTE_DEPOP);
-
- snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
- RT5631_L_MUTE | RT5631_R_MUTE,
- RT5631_L_MUTE | RT5631_R_MUTE);
- msleep(150);
- }
-
- /* recover soft volume and zero crossing setting */
- snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
- snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
-}
-
-static int hp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMD:
- if (rt5631->codec_version) {
- onebit_depop_mute_stage(codec, 0);
- onebit_depop_power_stage(codec, 0);
- } else {
- depop_seq_mute_stage(codec, 0);
- depop_seq_power_stage(codec, 0);
- }
- break;
-
- case SND_SOC_DAPM_POST_PMU:
- if (rt5631->codec_version) {
- onebit_depop_power_stage(codec, 1);
- onebit_depop_mute_stage(codec, 1);
- } else {
- depop_seq_power_stage(codec, 1);
- depop_seq_mute_stage(codec, 1);
- }
- break;
-
- default:
- break;
- }
-
- return 0;
-}
-
-static int set_dmic_params(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
-
- switch (rt5631->rx_rate) {
- case 44100:
- case 48000:
- snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
- RT5631_DMIC_CLK_CTRL_MASK,
- RT5631_DMIC_CLK_CTRL_TO_32FS);
- break;
-
- case 32000:
- case 22050:
- snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
- RT5631_DMIC_CLK_CTRL_MASK,
- RT5631_DMIC_CLK_CTRL_TO_64FS);
- break;
-
- case 16000:
- case 11025:
- case 8000:
- snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
- RT5631_DMIC_CLK_CTRL_MASK,
- RT5631_DMIC_CLK_CTRL_TO_128FS);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static const struct snd_kcontrol_new rt5631_recmixl_mixer_controls[] = {
- SOC_DAPM_SINGLE("OUTMIXL Capture Switch", RT5631_ADC_REC_MIXER,
- RT5631_M_OUTMIXL_RECMIXL_BIT, 1, 1),
- SOC_DAPM_SINGLE("MIC1_BST1 Capture Switch", RT5631_ADC_REC_MIXER,
- RT5631_M_MIC1_RECMIXL_BIT, 1, 1),
- SOC_DAPM_SINGLE("AXILVOL Capture Switch", RT5631_ADC_REC_MIXER,
- RT5631_M_AXIL_RECMIXL_BIT, 1, 1),
- SOC_DAPM_SINGLE("MONOIN_RX Capture Switch", RT5631_ADC_REC_MIXER,
- RT5631_M_MONO_IN_RECMIXL_BIT, 1, 1),
-};
-
-static const struct snd_kcontrol_new rt5631_recmixr_mixer_controls[] = {
- SOC_DAPM_SINGLE("MONOIN_RX Capture Switch", RT5631_ADC_REC_MIXER,
- RT5631_M_MONO_IN_RECMIXR_BIT, 1, 1),
- SOC_DAPM_SINGLE("AXIRVOL Capture Switch", RT5631_ADC_REC_MIXER,
- RT5631_M_AXIR_RECMIXR_BIT, 1, 1),
- SOC_DAPM_SINGLE("MIC2_BST2 Capture Switch", RT5631_ADC_REC_MIXER,
- RT5631_M_MIC2_RECMIXR_BIT, 1, 1),
- SOC_DAPM_SINGLE("OUTMIXR Capture Switch", RT5631_ADC_REC_MIXER,
- RT5631_M_OUTMIXR_RECMIXR_BIT, 1, 1),
-};
-
-static const struct snd_kcontrol_new rt5631_spkmixl_mixer_controls[] = {
- SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_SPK_MIXER_CTRL,
- RT5631_M_RECMIXL_SPKMIXL_BIT, 1, 1),
- SOC_DAPM_SINGLE("MIC1_P Playback Switch", RT5631_SPK_MIXER_CTRL,
- RT5631_M_MIC1P_SPKMIXL_BIT, 1, 1),
- SOC_DAPM_SINGLE("DACL Playback Switch", RT5631_SPK_MIXER_CTRL,
- RT5631_M_DACL_SPKMIXL_BIT, 1, 1),
- SOC_DAPM_SINGLE("OUTMIXL Playback Switch", RT5631_SPK_MIXER_CTRL,
- RT5631_M_OUTMIXL_SPKMIXL_BIT, 1, 1),
-};
-
-static const struct snd_kcontrol_new rt5631_spkmixr_mixer_controls[] = {
- SOC_DAPM_SINGLE("OUTMIXR Playback Switch", RT5631_SPK_MIXER_CTRL,
- RT5631_M_OUTMIXR_SPKMIXR_BIT, 1, 1),
- SOC_DAPM_SINGLE("DACR Playback Switch", RT5631_SPK_MIXER_CTRL,
- RT5631_M_DACR_SPKMIXR_BIT, 1, 1),
- SOC_DAPM_SINGLE("MIC2_P Playback Switch", RT5631_SPK_MIXER_CTRL,
- RT5631_M_MIC2P_SPKMIXR_BIT, 1, 1),
- SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_SPK_MIXER_CTRL,
- RT5631_M_RECMIXR_SPKMIXR_BIT, 1, 1),
-};
-
-static const struct snd_kcontrol_new rt5631_outmixl_mixer_controls[] = {
- SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_OUTMIXER_L_CTRL,
- RT5631_M_RECMIXL_OUTMIXL_BIT, 1, 1),
- SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_OUTMIXER_L_CTRL,
- RT5631_M_RECMIXR_OUTMIXL_BIT, 1, 1),
- SOC_DAPM_SINGLE("DACL Playback Switch", RT5631_OUTMIXER_L_CTRL,
- RT5631_M_DACL_OUTMIXL_BIT, 1, 1),
- SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_OUTMIXER_L_CTRL,
- RT5631_M_MIC1_OUTMIXL_BIT, 1, 1),
- SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_OUTMIXER_L_CTRL,
- RT5631_M_MIC2_OUTMIXL_BIT, 1, 1),
- SOC_DAPM_SINGLE("MONOIN_RXP Playback Switch", RT5631_OUTMIXER_L_CTRL,
- RT5631_M_MONO_INP_OUTMIXL_BIT, 1, 1),
- SOC_DAPM_SINGLE("AXILVOL Playback Switch", RT5631_OUTMIXER_L_CTRL,
- RT5631_M_AXIL_OUTMIXL_BIT, 1, 1),
- SOC_DAPM_SINGLE("AXIRVOL Playback Switch", RT5631_OUTMIXER_L_CTRL,
- RT5631_M_AXIR_OUTMIXL_BIT, 1, 1),
- SOC_DAPM_SINGLE("VDAC Playback Switch", RT5631_OUTMIXER_L_CTRL,
- RT5631_M_VDAC_OUTMIXL_BIT, 1, 1),
-};
-
-static const struct snd_kcontrol_new rt5631_outmixr_mixer_controls[] = {
- SOC_DAPM_SINGLE("VDAC Playback Switch", RT5631_OUTMIXER_R_CTRL,
- RT5631_M_VDAC_OUTMIXR_BIT, 1, 1),
- SOC_DAPM_SINGLE("AXIRVOL Playback Switch", RT5631_OUTMIXER_R_CTRL,
- RT5631_M_AXIR_OUTMIXR_BIT, 1, 1),
- SOC_DAPM_SINGLE("AXILVOL Playback Switch", RT5631_OUTMIXER_R_CTRL,
- RT5631_M_AXIL_OUTMIXR_BIT, 1, 1),
- SOC_DAPM_SINGLE("MONOIN_RXN Playback Switch", RT5631_OUTMIXER_R_CTRL,
- RT5631_M_MONO_INN_OUTMIXR_BIT, 1, 1),
- SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_OUTMIXER_R_CTRL,
- RT5631_M_MIC2_OUTMIXR_BIT, 1, 1),
- SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_OUTMIXER_R_CTRL,
- RT5631_M_MIC1_OUTMIXR_BIT, 1, 1),
- SOC_DAPM_SINGLE("DACR Playback Switch", RT5631_OUTMIXER_R_CTRL,
- RT5631_M_DACR_OUTMIXR_BIT, 1, 1),
- SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_OUTMIXER_R_CTRL,
- RT5631_M_RECMIXR_OUTMIXR_BIT, 1, 1),
- SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_OUTMIXER_R_CTRL,
- RT5631_M_RECMIXL_OUTMIXR_BIT, 1, 1),
-};
-
-static const struct snd_kcontrol_new rt5631_AXO1MIX_mixer_controls[] = {
- SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_AXO1MIXER_CTRL,
- RT5631_M_MIC1_AXO1MIX_BIT , 1, 1),
- SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_AXO1MIXER_CTRL,
- RT5631_M_MIC2_AXO1MIX_BIT, 1, 1),
- SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_AXO1MIXER_CTRL,
- RT5631_M_OUTMIXL_AXO1MIX_BIT , 1 , 1),
- SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_AXO1MIXER_CTRL,
- RT5631_M_OUTMIXR_AXO1MIX_BIT, 1, 1),
-};
-
-static const struct snd_kcontrol_new rt5631_AXO2MIX_mixer_controls[] = {
- SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_AXO2MIXER_CTRL,
- RT5631_M_MIC1_AXO2MIX_BIT, 1, 1),
- SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_AXO2MIXER_CTRL,
- RT5631_M_MIC2_AXO2MIX_BIT, 1, 1),
- SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_AXO2MIXER_CTRL,
- RT5631_M_OUTMIXL_AXO2MIX_BIT, 1, 1),
- SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_AXO2MIXER_CTRL,
- RT5631_M_OUTMIXR_AXO2MIX_BIT, 1 , 1),
-};
-
-static const struct snd_kcontrol_new rt5631_spolmix_mixer_controls[] = {
- SOC_DAPM_SINGLE("SPKVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
- RT5631_M_SPKVOLL_SPOLMIX_BIT, 1, 1),
- SOC_DAPM_SINGLE("SPKVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
- RT5631_M_SPKVOLR_SPOLMIX_BIT, 1, 1),
-};
-
-static const struct snd_kcontrol_new rt5631_spormix_mixer_controls[] = {
- SOC_DAPM_SINGLE("SPKVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
- RT5631_M_SPKVOLL_SPORMIX_BIT, 1, 1),
- SOC_DAPM_SINGLE("SPKVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
- RT5631_M_SPKVOLR_SPORMIX_BIT, 1, 1),
-};
-
-static const struct snd_kcontrol_new rt5631_monomix_mixer_controls[] = {
- SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
- RT5631_M_OUTVOLL_MONOMIX_BIT, 1, 1),
- SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
- RT5631_M_OUTVOLR_MONOMIX_BIT, 1, 1),
-};
-
-/* Left SPK Volume Input */
-static const char *rt5631_spkvoll_sel[] = {"Vmid", "SPKMIXL"};
-
-static const SOC_ENUM_SINGLE_DECL(
- rt5631_spkvoll_enum, RT5631_SPK_OUT_VOL,
- RT5631_L_EN_SHIFT, rt5631_spkvoll_sel);
-
-static const struct snd_kcontrol_new rt5631_spkvoll_mux_control =
- SOC_DAPM_ENUM("Left SPKVOL SRC", rt5631_spkvoll_enum);
-
-/* Left HP Volume Input */
-static const char *rt5631_hpvoll_sel[] = {"Vmid", "OUTMIXL"};
-
-static const SOC_ENUM_SINGLE_DECL(
- rt5631_hpvoll_enum, RT5631_HP_OUT_VOL,
- RT5631_L_EN_SHIFT, rt5631_hpvoll_sel);
-
-static const struct snd_kcontrol_new rt5631_hpvoll_mux_control =
- SOC_DAPM_ENUM("Left HPVOL SRC", rt5631_hpvoll_enum);
-
-/* Left Out Volume Input */
-static const char *rt5631_outvoll_sel[] = {"Vmid", "OUTMIXL"};
-
-static const SOC_ENUM_SINGLE_DECL(
- rt5631_outvoll_enum, RT5631_MONO_AXO_1_2_VOL,
- RT5631_L_EN_SHIFT, rt5631_outvoll_sel);
-
-static const struct snd_kcontrol_new rt5631_outvoll_mux_control =
- SOC_DAPM_ENUM("Left OUTVOL SRC", rt5631_outvoll_enum);
-
-/* Right Out Volume Input */
-static const char *rt5631_outvolr_sel[] = {"Vmid", "OUTMIXR"};
-
-static const SOC_ENUM_SINGLE_DECL(
- rt5631_outvolr_enum, RT5631_MONO_AXO_1_2_VOL,
- RT5631_R_EN_SHIFT, rt5631_outvolr_sel);
-
-static const struct snd_kcontrol_new rt5631_outvolr_mux_control =
- SOC_DAPM_ENUM("Right OUTVOL SRC", rt5631_outvolr_enum);
-
-/* Right HP Volume Input */
-static const char *rt5631_hpvolr_sel[] = {"Vmid", "OUTMIXR"};
-
-static const SOC_ENUM_SINGLE_DECL(
- rt5631_hpvolr_enum, RT5631_HP_OUT_VOL,
- RT5631_R_EN_SHIFT, rt5631_hpvolr_sel);
-
-static const struct snd_kcontrol_new rt5631_hpvolr_mux_control =
- SOC_DAPM_ENUM("Right HPVOL SRC", rt5631_hpvolr_enum);
-
-/* Right SPK Volume Input */
-static const char *rt5631_spkvolr_sel[] = {"Vmid", "SPKMIXR"};
-
-static const SOC_ENUM_SINGLE_DECL(
- rt5631_spkvolr_enum, RT5631_SPK_OUT_VOL,
- RT5631_R_EN_SHIFT, rt5631_spkvolr_sel);
-
-static const struct snd_kcontrol_new rt5631_spkvolr_mux_control =
- SOC_DAPM_ENUM("Right SPKVOL SRC", rt5631_spkvolr_enum);
-
-/* SPO Left Channel Input */
-static const char *rt5631_spol_src_sel[] = {
- "SPOLMIX", "MONOIN_RX", "VDAC", "DACL"};
-
-static const SOC_ENUM_SINGLE_DECL(
- rt5631_spol_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
- RT5631_SPK_L_MUX_SEL_SHIFT, rt5631_spol_src_sel);
-
-static const struct snd_kcontrol_new rt5631_spol_mux_control =
- SOC_DAPM_ENUM("SPOL SRC", rt5631_spol_src_enum);
-
-/* SPO Right Channel Input */
-static const char *rt5631_spor_src_sel[] = {
- "SPORMIX", "MONOIN_RX", "VDAC", "DACR"};
-
-static const SOC_ENUM_SINGLE_DECL(
- rt5631_spor_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
- RT5631_SPK_R_MUX_SEL_SHIFT, rt5631_spor_src_sel);
-
-static const struct snd_kcontrol_new rt5631_spor_mux_control =
- SOC_DAPM_ENUM("SPOR SRC", rt5631_spor_src_enum);
-
-/* MONO Input */
-static const char *rt5631_mono_src_sel[] = {"MONOMIX", "MONOIN_RX", "VDAC"};
-
-static const SOC_ENUM_SINGLE_DECL(
- rt5631_mono_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
- RT5631_MONO_MUX_SEL_SHIFT, rt5631_mono_src_sel);
-
-static const struct snd_kcontrol_new rt5631_mono_mux_control =
- SOC_DAPM_ENUM("MONO SRC", rt5631_mono_src_enum);
-
-/* Left HPO Input */
-static const char *rt5631_hpl_src_sel[] = {"Left HPVOL", "Left DAC"};
-
-static const SOC_ENUM_SINGLE_DECL(
- rt5631_hpl_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
- RT5631_HP_L_MUX_SEL_SHIFT, rt5631_hpl_src_sel);
-
-static const struct snd_kcontrol_new rt5631_hpl_mux_control =
- SOC_DAPM_ENUM("HPL SRC", rt5631_hpl_src_enum);
-
-/* Right HPO Input */
-static const char *rt5631_hpr_src_sel[] = {"Right HPVOL", "Right DAC"};
-
-static const SOC_ENUM_SINGLE_DECL(
- rt5631_hpr_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
- RT5631_HP_R_MUX_SEL_SHIFT, rt5631_hpr_src_sel);
-
-static const struct snd_kcontrol_new rt5631_hpr_mux_control =
- SOC_DAPM_ENUM("HPR SRC", rt5631_hpr_src_enum);
-
-static const struct snd_soc_dapm_widget rt5631_dapm_widgets[] = {
- /* Vmid */
- SND_SOC_DAPM_VMID("Vmid"),
- /* PLL1 */
- SND_SOC_DAPM_SUPPLY("PLL1", RT5631_PWR_MANAG_ADD2,
- RT5631_PWR_PLL1_BIT, 0, NULL, 0),
-
- /* Input Side */
- /* Input Lines */
- SND_SOC_DAPM_INPUT("MIC1"),
- SND_SOC_DAPM_INPUT("MIC2"),
- SND_SOC_DAPM_INPUT("AXIL"),
- SND_SOC_DAPM_INPUT("AXIR"),
- SND_SOC_DAPM_INPUT("MONOIN_RXN"),
- SND_SOC_DAPM_INPUT("MONOIN_RXP"),
- SND_SOC_DAPM_INPUT("DMIC"),
-
- /* MICBIAS */
- SND_SOC_DAPM_MICBIAS("MIC Bias1", RT5631_PWR_MANAG_ADD2,
- RT5631_PWR_MICBIAS1_VOL_BIT, 0),
- SND_SOC_DAPM_MICBIAS("MIC Bias2", RT5631_PWR_MANAG_ADD2,
- RT5631_PWR_MICBIAS2_VOL_BIT, 0),
-
- /* Boost */
- SND_SOC_DAPM_PGA("MIC1 Boost", RT5631_PWR_MANAG_ADD2,
- RT5631_PWR_MIC1_BOOT_GAIN_BIT, 0, NULL, 0),
- SND_SOC_DAPM_PGA("MIC2 Boost", RT5631_PWR_MANAG_ADD2,
- RT5631_PWR_MIC2_BOOT_GAIN_BIT, 0, NULL, 0),
- SND_SOC_DAPM_PGA("MONOIN_RXP Boost", RT5631_PWR_MANAG_ADD4,
- RT5631_PWR_MONO_IN_P_VOL_BIT, 0, NULL, 0),
- SND_SOC_DAPM_PGA("MONOIN_RXN Boost", RT5631_PWR_MANAG_ADD4,
- RT5631_PWR_MONO_IN_N_VOL_BIT, 0, NULL, 0),
- SND_SOC_DAPM_PGA("AXIL Boost", RT5631_PWR_MANAG_ADD4,
- RT5631_PWR_AXIL_IN_VOL_BIT, 0, NULL, 0),
- SND_SOC_DAPM_PGA("AXIR Boost", RT5631_PWR_MANAG_ADD4,
- RT5631_PWR_AXIR_IN_VOL_BIT, 0, NULL, 0),
-
- /* MONO In */
- SND_SOC_DAPM_MIXER("MONO_IN", SND_SOC_NOPM, 0, 0, NULL, 0),
-
- /* REC Mixer */
- SND_SOC_DAPM_MIXER("RECMIXL Mixer", RT5631_PWR_MANAG_ADD2,
- RT5631_PWR_RECMIXER_L_BIT, 0,
- &rt5631_recmixl_mixer_controls[0],
- ARRAY_SIZE(rt5631_recmixl_mixer_controls)),
- SND_SOC_DAPM_MIXER("RECMIXR Mixer", RT5631_PWR_MANAG_ADD2,
- RT5631_PWR_RECMIXER_R_BIT, 0,
- &rt5631_recmixr_mixer_controls[0],
- ARRAY_SIZE(rt5631_recmixr_mixer_controls)),
- /* Because of record duplication for L/R channel,
- * L/R ADCs need power up at the same time */
- SND_SOC_DAPM_MIXER("ADC Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-
- /* DMIC */
- SND_SOC_DAPM_SUPPLY("DMIC Supply", RT5631_DIG_MIC_CTRL,
- RT5631_DMIC_ENA_SHIFT, 0,
- set_dmic_params, SND_SOC_DAPM_PRE_PMU),
- /* ADC Data Srouce */
- SND_SOC_DAPM_SUPPLY("Left ADC Select", RT5631_INT_ST_IRQ_CTRL_2,
- RT5631_ADC_DATA_SEL_MIC1_SHIFT, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("Right ADC Select", RT5631_INT_ST_IRQ_CTRL_2,
- RT5631_ADC_DATA_SEL_MIC2_SHIFT, 0, NULL, 0),
-
- /* ADCs */
- SND_SOC_DAPM_ADC("Left ADC", "HIFI Capture",
- RT5631_PWR_MANAG_ADD1, RT5631_PWR_ADC_L_CLK_BIT, 0),
- SND_SOC_DAPM_ADC("Right ADC", "HIFI Capture",
- RT5631_PWR_MANAG_ADD1, RT5631_PWR_ADC_R_CLK_BIT, 0),
-
- /* DAC and ADC supply power */
- SND_SOC_DAPM_SUPPLY("I2S", RT5631_PWR_MANAG_ADD1,
- RT5631_PWR_MAIN_I2S_BIT, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("DAC REF", RT5631_PWR_MANAG_ADD1,
- RT5631_PWR_DAC_REF_BIT, 0, NULL, 0),
-
- /* Output Side */
- /* DACs */
- SND_SOC_DAPM_DAC("Left DAC", "HIFI Playback",
- RT5631_PWR_MANAG_ADD1, RT5631_PWR_DAC_L_CLK_BIT, 0),
- SND_SOC_DAPM_DAC("Right DAC", "HIFI Playback",
- RT5631_PWR_MANAG_ADD1, RT5631_PWR_DAC_R_CLK_BIT, 0),
- SND_SOC_DAPM_DAC("Voice DAC", "Voice DAC Mono Playback",
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_PGA("Voice DAC Boost", SND_SOC_NOPM, 0, 0, NULL, 0),
- /* DAC supply power */
- SND_SOC_DAPM_SUPPLY("Left DAC To Mixer", RT5631_PWR_MANAG_ADD1,
- RT5631_PWR_DAC_L_TO_MIXER_BIT, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("Right DAC To Mixer", RT5631_PWR_MANAG_ADD1,
- RT5631_PWR_DAC_R_TO_MIXER_BIT, 0, NULL, 0),
-
- /* Left SPK Mixer */
- SND_SOC_DAPM_MIXER("SPKMIXL Mixer", RT5631_PWR_MANAG_ADD2,
- RT5631_PWR_SPKMIXER_L_BIT, 0,
- &rt5631_spkmixl_mixer_controls[0],
- ARRAY_SIZE(rt5631_spkmixl_mixer_controls)),
- /* Left Out Mixer */
- SND_SOC_DAPM_MIXER("OUTMIXL Mixer", RT5631_PWR_MANAG_ADD2,
- RT5631_PWR_OUTMIXER_L_BIT, 0,
- &rt5631_outmixl_mixer_controls[0],
- ARRAY_SIZE(rt5631_outmixl_mixer_controls)),
- /* Right Out Mixer */
- SND_SOC_DAPM_MIXER("OUTMIXR Mixer", RT5631_PWR_MANAG_ADD2,
- RT5631_PWR_OUTMIXER_R_BIT, 0,
- &rt5631_outmixr_mixer_controls[0],
- ARRAY_SIZE(rt5631_outmixr_mixer_controls)),
- /* Right SPK Mixer */
- SND_SOC_DAPM_MIXER("SPKMIXR Mixer", RT5631_PWR_MANAG_ADD2,
- RT5631_PWR_SPKMIXER_R_BIT, 0,
- &rt5631_spkmixr_mixer_controls[0],
- ARRAY_SIZE(rt5631_spkmixr_mixer_controls)),
-
- /* Volume Mux */
- SND_SOC_DAPM_MUX("Left SPKVOL Mux", RT5631_PWR_MANAG_ADD4,
- RT5631_PWR_SPK_L_VOL_BIT, 0,
- &rt5631_spkvoll_mux_control),
- SND_SOC_DAPM_MUX("Left HPVOL Mux", RT5631_PWR_MANAG_ADD4,
- RT5631_PWR_HP_L_OUT_VOL_BIT, 0,
- &rt5631_hpvoll_mux_control),
- SND_SOC_DAPM_MUX("Left OUTVOL Mux", RT5631_PWR_MANAG_ADD4,
- RT5631_PWR_LOUT_VOL_BIT, 0,
- &rt5631_outvoll_mux_control),
- SND_SOC_DAPM_MUX("Right OUTVOL Mux", RT5631_PWR_MANAG_ADD4,
- RT5631_PWR_ROUT_VOL_BIT, 0,
- &rt5631_outvolr_mux_control),
- SND_SOC_DAPM_MUX("Right HPVOL Mux", RT5631_PWR_MANAG_ADD4,
- RT5631_PWR_HP_R_OUT_VOL_BIT, 0,
- &rt5631_hpvolr_mux_control),
- SND_SOC_DAPM_MUX("Right SPKVOL Mux", RT5631_PWR_MANAG_ADD4,
- RT5631_PWR_SPK_R_VOL_BIT, 0,
- &rt5631_spkvolr_mux_control),
-
- /* DAC To HP */
- SND_SOC_DAPM_PGA_S("Left DAC_HP", 0, SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA_S("Right DAC_HP", 0, SND_SOC_NOPM, 0, 0, NULL, 0),
-
- /* HP Depop */
- SND_SOC_DAPM_PGA_S("HP Depop", 1, SND_SOC_NOPM, 0, 0,
- hp_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
-
- /* AXO1 Mixer */
- SND_SOC_DAPM_MIXER("AXO1MIX Mixer", RT5631_PWR_MANAG_ADD3,
- RT5631_PWR_AXO1MIXER_BIT, 0,
- &rt5631_AXO1MIX_mixer_controls[0],
- ARRAY_SIZE(rt5631_AXO1MIX_mixer_controls)),
- /* SPOL Mixer */
- SND_SOC_DAPM_MIXER("SPOLMIX Mixer", SND_SOC_NOPM, 0, 0,
- &rt5631_spolmix_mixer_controls[0],
- ARRAY_SIZE(rt5631_spolmix_mixer_controls)),
- /* MONO Mixer */
- SND_SOC_DAPM_MIXER("MONOMIX Mixer", RT5631_PWR_MANAG_ADD3,
- RT5631_PWR_MONOMIXER_BIT, 0,
- &rt5631_monomix_mixer_controls[0],
- ARRAY_SIZE(rt5631_monomix_mixer_controls)),
- /* SPOR Mixer */
- SND_SOC_DAPM_MIXER("SPORMIX Mixer", SND_SOC_NOPM, 0, 0,
- &rt5631_spormix_mixer_controls[0],
- ARRAY_SIZE(rt5631_spormix_mixer_controls)),
- /* AXO2 Mixer */
- SND_SOC_DAPM_MIXER("AXO2MIX Mixer", RT5631_PWR_MANAG_ADD3,
- RT5631_PWR_AXO2MIXER_BIT, 0,
- &rt5631_AXO2MIX_mixer_controls[0],
- ARRAY_SIZE(rt5631_AXO2MIX_mixer_controls)),
-
- /* Mux */
- SND_SOC_DAPM_MUX("SPOL Mux", SND_SOC_NOPM, 0, 0,
- &rt5631_spol_mux_control),
- SND_SOC_DAPM_MUX("SPOR Mux", SND_SOC_NOPM, 0, 0,
- &rt5631_spor_mux_control),
- SND_SOC_DAPM_MUX("MONO Mux", SND_SOC_NOPM, 0, 0,
- &rt5631_mono_mux_control),
- SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0,
- &rt5631_hpl_mux_control),
- SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0,
- &rt5631_hpr_mux_control),
-
- /* AMP supply */
- SND_SOC_DAPM_SUPPLY("MONO Depop", RT5631_PWR_MANAG_ADD3,
- RT5631_PWR_MONO_DEPOP_DIS_BIT, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("Class D", RT5631_PWR_MANAG_ADD1,
- RT5631_PWR_CLASS_D_BIT, 0, NULL, 0),
-
- /* Output Lines */
- SND_SOC_DAPM_OUTPUT("AUXO1"),
- SND_SOC_DAPM_OUTPUT("AUXO2"),
- SND_SOC_DAPM_OUTPUT("SPOL"),
- SND_SOC_DAPM_OUTPUT("SPOR"),
- SND_SOC_DAPM_OUTPUT("HPOL"),
- SND_SOC_DAPM_OUTPUT("HPOR"),
- SND_SOC_DAPM_OUTPUT("MONO"),
-};
-
-static const struct snd_soc_dapm_route rt5631_dapm_routes[] = {
- {"MIC1 Boost", NULL, "MIC1"},
- {"MIC2 Boost", NULL, "MIC2"},
- {"MONOIN_RXP Boost", NULL, "MONOIN_RXP"},
- {"MONOIN_RXN Boost", NULL, "MONOIN_RXN"},
- {"AXIL Boost", NULL, "AXIL"},
- {"AXIR Boost", NULL, "AXIR"},
-
- {"MONO_IN", NULL, "MONOIN_RXP Boost"},
- {"MONO_IN", NULL, "MONOIN_RXN Boost"},
-
- {"RECMIXL Mixer", "OUTMIXL Capture Switch", "OUTMIXL Mixer"},
- {"RECMIXL Mixer", "MIC1_BST1 Capture Switch", "MIC1 Boost"},
- {"RECMIXL Mixer", "AXILVOL Capture Switch", "AXIL Boost"},
- {"RECMIXL Mixer", "MONOIN_RX Capture Switch", "MONO_IN"},
-
- {"RECMIXR Mixer", "OUTMIXR Capture Switch", "OUTMIXR Mixer"},
- {"RECMIXR Mixer", "MIC2_BST2 Capture Switch", "MIC2 Boost"},
- {"RECMIXR Mixer", "AXIRVOL Capture Switch", "AXIR Boost"},
- {"RECMIXR Mixer", "MONOIN_RX Capture Switch", "MONO_IN"},
-
- {"ADC Mixer", NULL, "RECMIXL Mixer"},
- {"ADC Mixer", NULL, "RECMIXR Mixer"},
-
- {"Left ADC", NULL, "ADC Mixer"},
- {"Left ADC", NULL, "Left ADC Select", check_adcl_select},
- {"Left ADC", NULL, "PLL1", check_sysclk1_source},
- {"Left ADC", NULL, "I2S"},
- {"Left ADC", NULL, "DAC REF"},
-
- {"Right ADC", NULL, "ADC Mixer"},
- {"Right ADC", NULL, "Right ADC Select", check_adcr_select},
- {"Right ADC", NULL, "PLL1", check_sysclk1_source},
- {"Right ADC", NULL, "I2S"},
- {"Right ADC", NULL, "DAC REF"},
-
- {"DMIC", NULL, "DMIC Supply", check_dmic_used},
- {"Left ADC", NULL, "DMIC"},
- {"Right ADC", NULL, "DMIC"},
-
- {"Left DAC", NULL, "PLL1", check_sysclk1_source},
- {"Left DAC", NULL, "I2S"},
- {"Left DAC", NULL, "DAC REF"},
- {"Right DAC", NULL, "PLL1", check_sysclk1_source},
- {"Right DAC", NULL, "I2S"},
- {"Right DAC", NULL, "DAC REF"},
-
- {"Voice DAC Boost", NULL, "Voice DAC"},
-
- {"SPKMIXL Mixer", NULL, "Left DAC To Mixer", check_dacl_to_spkmixl},
- {"SPKMIXL Mixer", "RECMIXL Playback Switch", "RECMIXL Mixer"},
- {"SPKMIXL Mixer", "MIC1_P Playback Switch", "MIC1"},
- {"SPKMIXL Mixer", "DACL Playback Switch", "Left DAC"},
- {"SPKMIXL Mixer", "OUTMIXL Playback Switch", "OUTMIXL Mixer"},
-
- {"SPKMIXR Mixer", NULL, "Right DAC To Mixer", check_dacr_to_spkmixr},
- {"SPKMIXR Mixer", "OUTMIXR Playback Switch", "OUTMIXR Mixer"},
- {"SPKMIXR Mixer", "DACR Playback Switch", "Right DAC"},
- {"SPKMIXR Mixer", "MIC2_P Playback Switch", "MIC2"},
- {"SPKMIXR Mixer", "RECMIXR Playback Switch", "RECMIXR Mixer"},
-
- {"OUTMIXL Mixer", NULL, "Left DAC To Mixer", check_dacl_to_outmixl},
- {"OUTMIXL Mixer", "RECMIXL Playback Switch", "RECMIXL Mixer"},
- {"OUTMIXL Mixer", "RECMIXR Playback Switch", "RECMIXR Mixer"},
- {"OUTMIXL Mixer", "DACL Playback Switch", "Left DAC"},
- {"OUTMIXL Mixer", "MIC1_BST1 Playback Switch", "MIC1 Boost"},
- {"OUTMIXL Mixer", "MIC2_BST2 Playback Switch", "MIC2 Boost"},
- {"OUTMIXL Mixer", "MONOIN_RXP Playback Switch", "MONOIN_RXP Boost"},
- {"OUTMIXL Mixer", "AXILVOL Playback Switch", "AXIL Boost"},
- {"OUTMIXL Mixer", "AXIRVOL Playback Switch", "AXIR Boost"},
- {"OUTMIXL Mixer", "VDAC Playback Switch", "Voice DAC Boost"},
-
- {"OUTMIXR Mixer", NULL, "Right DAC To Mixer", check_dacr_to_outmixr},
- {"OUTMIXR Mixer", "RECMIXL Playback Switch", "RECMIXL Mixer"},
- {"OUTMIXR Mixer", "RECMIXR Playback Switch", "RECMIXR Mixer"},
- {"OUTMIXR Mixer", "DACR Playback Switch", "Right DAC"},
- {"OUTMIXR Mixer", "MIC1_BST1 Playback Switch", "MIC1 Boost"},
- {"OUTMIXR Mixer", "MIC2_BST2 Playback Switch", "MIC2 Boost"},
- {"OUTMIXR Mixer", "MONOIN_RXN Playback Switch", "MONOIN_RXN Boost"},
- {"OUTMIXR Mixer", "AXILVOL Playback Switch", "AXIL Boost"},
- {"OUTMIXR Mixer", "AXIRVOL Playback Switch", "AXIR Boost"},
- {"OUTMIXR Mixer", "VDAC Playback Switch", "Voice DAC Boost"},
-
- {"Left SPKVOL Mux", "SPKMIXL", "SPKMIXL Mixer"},
- {"Left SPKVOL Mux", "Vmid", "Vmid"},
- {"Left HPVOL Mux", "OUTMIXL", "OUTMIXL Mixer"},
- {"Left HPVOL Mux", "Vmid", "Vmid"},
- {"Left OUTVOL Mux", "OUTMIXL", "OUTMIXL Mixer"},
- {"Left OUTVOL Mux", "Vmid", "Vmid"},
- {"Right OUTVOL Mux", "OUTMIXR", "OUTMIXR Mixer"},
- {"Right OUTVOL Mux", "Vmid", "Vmid"},
- {"Right HPVOL Mux", "OUTMIXR", "OUTMIXR Mixer"},
- {"Right HPVOL Mux", "Vmid", "Vmid"},
- {"Right SPKVOL Mux", "SPKMIXR", "SPKMIXR Mixer"},
- {"Right SPKVOL Mux", "Vmid", "Vmid"},
-
- {"AXO1MIX Mixer", "MIC1_BST1 Playback Switch", "MIC1 Boost"},
- {"AXO1MIX Mixer", "OUTVOLL Playback Switch", "Left OUTVOL Mux"},
- {"AXO1MIX Mixer", "OUTVOLR Playback Switch", "Right OUTVOL Mux"},
- {"AXO1MIX Mixer", "MIC2_BST2 Playback Switch", "MIC2 Boost"},
-
- {"AXO2MIX Mixer", "MIC1_BST1 Playback Switch", "MIC1 Boost"},
- {"AXO2MIX Mixer", "OUTVOLL Playback Switch", "Left OUTVOL Mux"},
- {"AXO2MIX Mixer", "OUTVOLR Playback Switch", "Right OUTVOL Mux"},
- {"AXO2MIX Mixer", "MIC2_BST2 Playback Switch", "MIC2 Boost"},
-
- {"SPOLMIX Mixer", "SPKVOLL Playback Switch", "Left SPKVOL Mux"},
- {"SPOLMIX Mixer", "SPKVOLR Playback Switch", "Right SPKVOL Mux"},
-
- {"SPORMIX Mixer", "SPKVOLL Playback Switch", "Left SPKVOL Mux"},
- {"SPORMIX Mixer", "SPKVOLR Playback Switch", "Right SPKVOL Mux"},
-
- {"MONOMIX Mixer", "OUTVOLL Playback Switch", "Left OUTVOL Mux"},
- {"MONOMIX Mixer", "OUTVOLR Playback Switch", "Right OUTVOL Mux"},
-
- {"SPOL Mux", "SPOLMIX", "SPOLMIX Mixer"},
- {"SPOL Mux", "MONOIN_RX", "MONO_IN"},
- {"SPOL Mux", "VDAC", "Voice DAC Boost"},
- {"SPOL Mux", "DACL", "Left DAC"},
-
- {"SPOR Mux", "SPORMIX", "SPORMIX Mixer"},
- {"SPOR Mux", "MONOIN_RX", "MONO_IN"},
- {"SPOR Mux", "VDAC", "Voice DAC Boost"},
- {"SPOR Mux", "DACR", "Right DAC"},
-
- {"MONO Mux", "MONOMIX", "MONOMIX Mixer"},
- {"MONO Mux", "MONOIN_RX", "MONO_IN"},
- {"MONO Mux", "VDAC", "Voice DAC Boost"},
-
- {"Right DAC_HP", NULL, "Right DAC"},
- {"Left DAC_HP", NULL, "Left DAC"},
-
- {"HPL Mux", "Left HPVOL", "Left HPVOL Mux"},
- {"HPL Mux", "Left DAC", "Left DAC_HP"},
- {"HPR Mux", "Right HPVOL", "Right HPVOL Mux"},
- {"HPR Mux", "Right DAC", "Right DAC_HP"},
-
- {"HP Depop", NULL, "HPL Mux"},
- {"HP Depop", NULL, "HPR Mux"},
-
- {"AUXO1", NULL, "AXO1MIX Mixer"},
- {"AUXO2", NULL, "AXO2MIX Mixer"},
-
- {"SPOL", NULL, "Class D"},
- {"SPOL", NULL, "SPOL Mux"},
- {"SPOR", NULL, "Class D"},
- {"SPOR", NULL, "SPOR Mux"},
-
- {"HPOL", NULL, "HP Depop"},
- {"HPOR", NULL, "HP Depop"},
-
- {"MONO", NULL, "MONO Depop"},
- {"MONO", NULL, "MONO Mux"},
-};
-
-struct coeff_clk_div {
- u32 mclk;
- u32 bclk;
- u32 rate;
- u16 reg_val;
-};
-
-/* PLL divisors */
-struct pll_div {
- u32 pll_in;
- u32 pll_out;
- u16 reg_val;
-};
-
-static const struct pll_div codec_master_pll_div[] = {
- {2048000, 8192000, 0x0ea0},
- {3686400, 8192000, 0x4e27},
- {12000000, 8192000, 0x456b},
- {13000000, 8192000, 0x495f},
- {13100000, 8192000, 0x0320},
- {2048000, 11289600, 0xf637},
- {3686400, 11289600, 0x2f22},
- {12000000, 11289600, 0x3e2f},
- {13000000, 11289600, 0x4d5b},
- {13100000, 11289600, 0x363b},
- {2048000, 16384000, 0x1ea0},
- {3686400, 16384000, 0x9e27},
- {12000000, 16384000, 0x452b},
- {13000000, 16384000, 0x542f},
- {13100000, 16384000, 0x03a0},
- {2048000, 16934400, 0xe625},
- {3686400, 16934400, 0x9126},
- {12000000, 16934400, 0x4d2c},
- {13000000, 16934400, 0x742f},
- {13100000, 16934400, 0x3c27},
- {2048000, 22579200, 0x2aa0},
- {3686400, 22579200, 0x2f20},
- {12000000, 22579200, 0x7e2f},
- {13000000, 22579200, 0x742f},
- {13100000, 22579200, 0x3c27},
- {2048000, 24576000, 0x2ea0},
- {3686400, 24576000, 0xee27},
- {12000000, 24576000, 0x2915},
- {13000000, 24576000, 0x772e},
- {13100000, 24576000, 0x0d20},
- {26000000, 24576000, 0x2027},
- {26000000, 22579200, 0x392f},
- {24576000, 22579200, 0x0921},
- {24576000, 24576000, 0x02a0},
-};
-
-static const struct pll_div codec_slave_pll_div[] = {
- {256000, 2048000, 0x46f0},
- {256000, 4096000, 0x3ea0},
- {352800, 5644800, 0x3ea0},
- {512000, 8192000, 0x3ea0},
- {1024000, 8192000, 0x46f0},
- {705600, 11289600, 0x3ea0},
- {1024000, 16384000, 0x3ea0},
- {1411200, 22579200, 0x3ea0},
- {1536000, 24576000, 0x3ea0},
- {2048000, 16384000, 0x1ea0},
- {2822400, 22579200, 0x1ea0},
- {2822400, 45158400, 0x5ec0},
- {5644800, 45158400, 0x46f0},
- {3072000, 24576000, 0x1ea0},
- {3072000, 49152000, 0x5ec0},
- {6144000, 49152000, 0x46f0},
- {705600, 11289600, 0x3ea0},
- {705600, 8467200, 0x3ab0},
- {24576000, 24576000, 0x02a0},
- {1411200, 11289600, 0x1690},
- {2822400, 11289600, 0x0a90},
- {1536000, 12288000, 0x1690},
- {3072000, 12288000, 0x0a90},
-};
-
-static struct coeff_clk_div coeff_div[] = {
- /* sysclk is 256fs */
- {2048000, 8000 * 32, 8000, 0x1000},
- {2048000, 8000 * 64, 8000, 0x0000},
- {2822400, 11025 * 32, 11025, 0x1000},
- {2822400, 11025 * 64, 11025, 0x0000},
- {4096000, 16000 * 32, 16000, 0x1000},
- {4096000, 16000 * 64, 16000, 0x0000},
- {5644800, 22050 * 32, 22050, 0x1000},
- {5644800, 22050 * 64, 22050, 0x0000},
- {8192000, 32000 * 32, 32000, 0x1000},
- {8192000, 32000 * 64, 32000, 0x0000},
- {11289600, 44100 * 32, 44100, 0x1000},
- {11289600, 44100 * 64, 44100, 0x0000},
- {12288000, 48000 * 32, 48000, 0x1000},
- {12288000, 48000 * 64, 48000, 0x0000},
- {22579200, 88200 * 32, 88200, 0x1000},
- {22579200, 88200 * 64, 88200, 0x0000},
- {24576000, 96000 * 32, 96000, 0x1000},
- {24576000, 96000 * 64, 96000, 0x0000},
- /* sysclk is 512fs */
- {4096000, 8000 * 32, 8000, 0x3000},
- {4096000, 8000 * 64, 8000, 0x2000},
- {5644800, 11025 * 32, 11025, 0x3000},
- {5644800, 11025 * 64, 11025, 0x2000},
- {8192000, 16000 * 32, 16000, 0x3000},
- {8192000, 16000 * 64, 16000, 0x2000},
- {11289600, 22050 * 32, 22050, 0x3000},
- {11289600, 22050 * 64, 22050, 0x2000},
- {16384000, 32000 * 32, 32000, 0x3000},
- {16384000, 32000 * 64, 32000, 0x2000},
- {22579200, 44100 * 32, 44100, 0x3000},
- {22579200, 44100 * 64, 44100, 0x2000},
- {24576000, 48000 * 32, 48000, 0x3000},
- {24576000, 48000 * 64, 48000, 0x2000},
- {45158400, 88200 * 32, 88200, 0x3000},
- {45158400, 88200 * 64, 88200, 0x2000},
- {49152000, 96000 * 32, 96000, 0x3000},
- {49152000, 96000 * 64, 96000, 0x2000},
- /* sysclk is 24.576Mhz or 22.5792Mhz */
- {24576000, 8000 * 32, 8000, 0x7080},
- {24576000, 8000 * 64, 8000, 0x6080},
- {24576000, 16000 * 32, 16000, 0x5080},
- {24576000, 16000 * 64, 16000, 0x4080},
- {24576000, 24000 * 32, 24000, 0x5000},
- {24576000, 24000 * 64, 24000, 0x4000},
- {24576000, 32000 * 32, 32000, 0x3080},
- {24576000, 32000 * 64, 32000, 0x2080},
- {22579200, 11025 * 32, 11025, 0x7000},
- {22579200, 11025 * 64, 11025, 0x6000},
- {22579200, 22050 * 32, 22050, 0x5000},
- {22579200, 22050 * 64, 22050, 0x4000},
-};
-
-static int get_coeff(int mclk, int rate, int timesofbclk)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
- if (coeff_div[i].mclk == mclk && coeff_div[i].rate == rate &&
- (coeff_div[i].bclk / coeff_div[i].rate) == timesofbclk)
- return i;
- }
- return -EINVAL;
-}
-
-static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
- int timesofbclk = 32, coeff;
- unsigned int iface = 0;
-
- dev_dbg(codec->dev, "enter %s\n", __func__);
-
- rt5631->bclk_rate = snd_soc_params_to_bclk(params);
- if (rt5631->bclk_rate < 0) {
- dev_err(codec->dev, "Fail to get BCLK rate\n");
- return rt5631->bclk_rate;
- }
- rt5631->rx_rate = params_rate(params);
-
- if (rt5631->master)
- coeff = get_coeff(rt5631->sysclk, rt5631->rx_rate,
- rt5631->bclk_rate / rt5631->rx_rate);
- else
- coeff = get_coeff(rt5631->sysclk, rt5631->rx_rate,
- timesofbclk);
- if (coeff < 0) {
- dev_err(codec->dev, "Fail to get coeff\n");
- return -EINVAL;
- }
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= RT5631_SDP_I2S_DL_20;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface |= RT5631_SDP_I2S_DL_24;
- break;
- case SNDRV_PCM_FORMAT_S8:
- iface |= RT5631_SDP_I2S_DL_8;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, RT5631_SDP_CTRL,
- RT5631_SDP_I2S_DL_MASK, iface);
- snd_soc_write(codec, RT5631_STEREO_AD_DA_CLK_CTRL,
- coeff_div[coeff].reg_val);
-
- return 0;
-}
-
-static int rt5631_hifi_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
- unsigned int iface = 0;
-
- dev_dbg(codec->dev, "enter %s\n", __func__);
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- rt5631->master = 1;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- iface |= RT5631_SDP_MODE_SEL_SLAVE;
- rt5631->master = 0;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= RT5631_SDP_I2S_DF_LEFT;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= RT5631_SDP_I2S_DF_PCM_A;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- iface |= RT5631_SDP_I2S_DF_PCM_B;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= RT5631_SDP_I2S_BCLK_POL_CTRL;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, RT5631_SDP_CTRL, iface);
-
- return 0;
-}
-
-static int rt5631_hifi_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
-
- dev_dbg(codec->dev, "enter %s, syclk=%d\n", __func__, freq);
-
- if ((freq >= (256 * 8000)) && (freq <= (512 * 96000))) {
- rt5631->sysclk = freq;
- return 0;
- }
-
- return -EINVAL;
-}
-
-static int rt5631_codec_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
- int source, unsigned int freq_in, unsigned int freq_out)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
- int i, ret = -EINVAL;
-
- dev_dbg(codec->dev, "enter %s\n", __func__);
-
- if (!freq_in || !freq_out) {
- dev_dbg(codec->dev, "PLL disabled\n");
-
- snd_soc_update_bits(codec, RT5631_GLOBAL_CLK_CTRL,
- RT5631_SYSCLK_SOUR_SEL_MASK,
- RT5631_SYSCLK_SOUR_SEL_MCLK);
-
- return 0;
- }
-
- if (rt5631->master) {
- for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++)
- if (freq_in == codec_master_pll_div[i].pll_in &&
- freq_out == codec_master_pll_div[i].pll_out) {
- dev_info(codec->dev,
- "change PLL in master mode\n");
- snd_soc_write(codec, RT5631_PLL_CTRL,
- codec_master_pll_div[i].reg_val);
- schedule_timeout_uninterruptible(
- msecs_to_jiffies(20));
- snd_soc_update_bits(codec,
- RT5631_GLOBAL_CLK_CTRL,
- RT5631_SYSCLK_SOUR_SEL_MASK |
- RT5631_PLLCLK_SOUR_SEL_MASK,
- RT5631_SYSCLK_SOUR_SEL_PLL |
- RT5631_PLLCLK_SOUR_SEL_MCLK);
- ret = 0;
- break;
- }
- } else {
- for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++)
- if (freq_in == codec_slave_pll_div[i].pll_in &&
- freq_out == codec_slave_pll_div[i].pll_out) {
- dev_info(codec->dev,
- "change PLL in slave mode\n");
- snd_soc_write(codec, RT5631_PLL_CTRL,
- codec_slave_pll_div[i].reg_val);
- schedule_timeout_uninterruptible(
- msecs_to_jiffies(20));
- snd_soc_update_bits(codec,
- RT5631_GLOBAL_CLK_CTRL,
- RT5631_SYSCLK_SOUR_SEL_MASK |
- RT5631_PLLCLK_SOUR_SEL_MASK,
- RT5631_SYSCLK_SOUR_SEL_PLL |
- RT5631_PLLCLK_SOUR_SEL_BCLK);
- ret = 0;
- break;
- }
- }
-
- return ret;
-}
-
-static int rt5631_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- switch (level) {
- case SND_SOC_BIAS_ON:
- case SND_SOC_BIAS_PREPARE:
- snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD2,
- RT5631_PWR_MICBIAS1_VOL | RT5631_PWR_MICBIAS2_VOL,
- RT5631_PWR_MICBIAS1_VOL | RT5631_PWR_MICBIAS2_VOL);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
- RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS,
- RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS);
- msleep(80);
- snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
- RT5631_PWR_FAST_VREF_CTRL,
- RT5631_PWR_FAST_VREF_CTRL);
- codec->cache_only = false;
- snd_soc_cache_sync(codec);
- }
- break;
-
- case SND_SOC_BIAS_OFF:
- snd_soc_write(codec, RT5631_PWR_MANAG_ADD1, 0x0000);
- snd_soc_write(codec, RT5631_PWR_MANAG_ADD2, 0x0000);
- snd_soc_write(codec, RT5631_PWR_MANAG_ADD3, 0x0000);
- snd_soc_write(codec, RT5631_PWR_MANAG_ADD4, 0x0000);
- break;
-
- default:
- break;
- }
- codec->dapm.bias_level = level;
-
- return 0;
-}
-
-static int rt5631_probe(struct snd_soc_codec *codec)
-{
- struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
- unsigned int val;
- int ret;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- val = rt5631_read_index(codec, RT5631_ADDA_MIXER_INTL_REG3);
- if (val & 0x0002)
- rt5631->codec_version = 1;
- else
- rt5631->codec_version = 0;
-
- rt5631_reset(codec);
- snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
- RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS,
- RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS);
- msleep(80);
- snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
- RT5631_PWR_FAST_VREF_CTRL, RT5631_PWR_FAST_VREF_CTRL);
- /* enable HP zero cross */
- snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, 0x0f18);
- /* power off ClassD auto Recovery */
- if (rt5631->codec_version)
- snd_soc_update_bits(codec, RT5631_INT_ST_IRQ_CTRL_2,
- 0x2000, 0x2000);
- else
- snd_soc_update_bits(codec, RT5631_INT_ST_IRQ_CTRL_2,
- 0x2000, 0);
- /* DMIC */
- if (rt5631->dmic_used_flag) {
- snd_soc_update_bits(codec, RT5631_GPIO_CTRL,
- RT5631_GPIO_PIN_FUN_SEL_MASK |
- RT5631_GPIO_DMIC_FUN_SEL_MASK,
- RT5631_GPIO_PIN_FUN_SEL_GPIO_DIMC |
- RT5631_GPIO_DMIC_FUN_SEL_DIMC);
- snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
- RT5631_DMIC_L_CH_LATCH_MASK |
- RT5631_DMIC_R_CH_LATCH_MASK,
- RT5631_DMIC_L_CH_LATCH_FALLING |
- RT5631_DMIC_R_CH_LATCH_RISING);
- }
-
- codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
-
- return 0;
-}
-
-static int rt5631_remove(struct snd_soc_codec *codec)
-{
- rt5631_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int rt5631_suspend(struct snd_soc_codec *codec)
-{
- rt5631_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int rt5631_resume(struct snd_soc_codec *codec)
-{
- rt5631_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-#else
-#define rt5631_suspend NULL
-#define rt5631_resume NULL
-#endif
-
-#define RT5631_STEREO_RATES SNDRV_PCM_RATE_8000_96000
-#define RT5631_FORMAT (SNDRV_PCM_FMTBIT_S16_LE | \
- SNDRV_PCM_FMTBIT_S20_3LE | \
- SNDRV_PCM_FMTBIT_S24_LE | \
- SNDRV_PCM_FMTBIT_S8)
-
-static const struct snd_soc_dai_ops rt5631_ops = {
- .hw_params = rt5631_hifi_pcm_params,
- .set_fmt = rt5631_hifi_codec_set_dai_fmt,
- .set_sysclk = rt5631_hifi_codec_set_dai_sysclk,
- .set_pll = rt5631_codec_set_dai_pll,
-};
-
-static struct snd_soc_dai_driver rt5631_dai[] = {
- {
- .name = "rt5631-hifi",
- .id = 1,
- .playback = {
- .stream_name = "HIFI Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = RT5631_STEREO_RATES,
- .formats = RT5631_FORMAT,
- },
- .capture = {
- .stream_name = "HIFI Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = RT5631_STEREO_RATES,
- .formats = RT5631_FORMAT,
- },
- .ops = &rt5631_ops,
- },
-};
-
-static struct snd_soc_codec_driver soc_codec_dev_rt5631 = {
- .probe = rt5631_probe,
- .remove = rt5631_remove,
- .suspend = rt5631_suspend,
- .resume = rt5631_resume,
- .set_bias_level = rt5631_set_bias_level,
- .reg_cache_size = RT5631_VENDOR_ID2 + 1,
- .reg_word_size = sizeof(u16),
- .reg_cache_default = rt5631_reg,
- .volatile_register = rt5631_volatile_register,
- .readable_register = rt5631_readable_register,
- .reg_cache_step = 1,
- .controls = rt5631_snd_controls,
- .num_controls = ARRAY_SIZE(rt5631_snd_controls),
- .dapm_widgets = rt5631_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(rt5631_dapm_widgets),
- .dapm_routes = rt5631_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(rt5631_dapm_routes),
-};
-
-static const struct i2c_device_id rt5631_i2c_id[] = {
- { "rt5631", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, rt5631_i2c_id);
-
-static int rt5631_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct rt5631_priv *rt5631;
- int ret;
-
- rt5631 = devm_kzalloc(&i2c->dev, sizeof(struct rt5631_priv),
- GFP_KERNEL);
- if (NULL == rt5631)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, rt5631);
-
- ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5631,
- rt5631_dai, ARRAY_SIZE(rt5631_dai));
- return ret;
-}
-
-static __devexit int rt5631_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static struct i2c_driver rt5631_i2c_driver = {
- .driver = {
- .name = "rt5631",
- .owner = THIS_MODULE,
- },
- .probe = rt5631_i2c_probe,
- .remove = __devexit_p(rt5631_i2c_remove),
- .id_table = rt5631_i2c_id,
-};
-
-static int __init rt5631_modinit(void)
-{
- return i2c_add_driver(&rt5631_i2c_driver);
-}
-module_init(rt5631_modinit);
-
-static void __exit rt5631_modexit(void)
-{
- i2c_del_driver(&rt5631_i2c_driver);
-}
-module_exit(rt5631_modexit);
-
-MODULE_DESCRIPTION("ASoC RT5631 driver");
-MODULE_AUTHOR("flove <flove@realtek.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/rt5631.h b/ANDROID_3.4.5/sound/soc/codecs/rt5631.h
deleted file mode 100644
index 13401581..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/rt5631.h
+++ /dev/null
@@ -1,701 +0,0 @@
-#ifndef __RTCODEC5631_H__
-#define __RTCODEC5631_H__
-
-
-#define RT5631_RESET 0x00
-#define RT5631_SPK_OUT_VOL 0x02
-#define RT5631_HP_OUT_VOL 0x04
-#define RT5631_MONO_AXO_1_2_VOL 0x06
-#define RT5631_AUX_IN_VOL 0x0A
-#define RT5631_STEREO_DAC_VOL_1 0x0C
-#define RT5631_MIC_CTRL_1 0x0E
-#define RT5631_STEREO_DAC_VOL_2 0x10
-#define RT5631_ADC_CTRL_1 0x12
-#define RT5631_ADC_REC_MIXER 0x14
-#define RT5631_ADC_CTRL_2 0x16
-#define RT5631_VDAC_DIG_VOL 0x18
-#define RT5631_OUTMIXER_L_CTRL 0x1A
-#define RT5631_OUTMIXER_R_CTRL 0x1C
-#define RT5631_AXO1MIXER_CTRL 0x1E
-#define RT5631_AXO2MIXER_CTRL 0x20
-#define RT5631_MIC_CTRL_2 0x22
-#define RT5631_DIG_MIC_CTRL 0x24
-#define RT5631_MONO_INPUT_VOL 0x26
-#define RT5631_SPK_MIXER_CTRL 0x28
-#define RT5631_SPK_MONO_OUT_CTRL 0x2A
-#define RT5631_SPK_MONO_HP_OUT_CTRL 0x2C
-#define RT5631_SDP_CTRL 0x34
-#define RT5631_MONO_SDP_CTRL 0x36
-#define RT5631_STEREO_AD_DA_CLK_CTRL 0x38
-#define RT5631_PWR_MANAG_ADD1 0x3A
-#define RT5631_PWR_MANAG_ADD2 0x3B
-#define RT5631_PWR_MANAG_ADD3 0x3C
-#define RT5631_PWR_MANAG_ADD4 0x3E
-#define RT5631_GEN_PUR_CTRL_REG 0x40
-#define RT5631_GLOBAL_CLK_CTRL 0x42
-#define RT5631_PLL_CTRL 0x44
-#define RT5631_INT_ST_IRQ_CTRL_1 0x48
-#define RT5631_INT_ST_IRQ_CTRL_2 0x4A
-#define RT5631_GPIO_CTRL 0x4C
-#define RT5631_MISC_CTRL 0x52
-#define RT5631_DEPOP_FUN_CTRL_1 0x54
-#define RT5631_DEPOP_FUN_CTRL_2 0x56
-#define RT5631_JACK_DET_CTRL 0x5A
-#define RT5631_SOFT_VOL_CTRL 0x5C
-#define RT5631_ALC_CTRL_1 0x64
-#define RT5631_ALC_CTRL_2 0x65
-#define RT5631_ALC_CTRL_3 0x66
-#define RT5631_PSEUDO_SPATL_CTRL 0x68
-#define RT5631_INDEX_ADD 0x6A
-#define RT5631_INDEX_DATA 0x6C
-#define RT5631_EQ_CTRL 0x6E
-#define RT5631_VENDOR_ID 0x7A
-#define RT5631_VENDOR_ID1 0x7C
-#define RT5631_VENDOR_ID2 0x7E
-
-/* Index of Codec Private Register definition */
-#define RT5631_EQ_BW_LOP 0x00
-#define RT5631_EQ_GAIN_LOP 0x01
-#define RT5631_EQ_FC_BP1 0x02
-#define RT5631_EQ_BW_BP1 0x03
-#define RT5631_EQ_GAIN_BP1 0x04
-#define RT5631_EQ_FC_BP2 0x05
-#define RT5631_EQ_BW_BP2 0x06
-#define RT5631_EQ_GAIN_BP2 0x07
-#define RT5631_EQ_FC_BP3 0x08
-#define RT5631_EQ_BW_BP3 0x09
-#define RT5631_EQ_GAIN_BP3 0x0a
-#define RT5631_EQ_BW_HIP 0x0b
-#define RT5631_EQ_GAIN_HIP 0x0c
-#define RT5631_EQ_HPF_A1 0x0d
-#define RT5631_EQ_HPF_A2 0x0e
-#define RT5631_EQ_HPF_GAIN 0x0f
-#define RT5631_EQ_PRE_VOL_CTRL 0x11
-#define RT5631_EQ_POST_VOL_CTRL 0x12
-#define RT5631_TEST_MODE_CTRL 0x39
-#define RT5631_CP_INTL_REG2 0x45
-#define RT5631_ADDA_MIXER_INTL_REG3 0x52
-#define RT5631_SPK_INTL_CTRL 0x56
-
-
-/* global definition */
-#define RT5631_L_MUTE (0x1 << 15)
-#define RT5631_L_MUTE_SHIFT 15
-#define RT5631_L_EN (0x1 << 14)
-#define RT5631_L_EN_SHIFT 14
-#define RT5631_R_MUTE (0x1 << 7)
-#define RT5631_R_MUTE_SHIFT 7
-#define RT5631_R_EN (0x1 << 6)
-#define RT5631_R_EN_SHIFT 6
-#define RT5631_VOL_MASK 0x1f
-#define RT5631_L_VOL_SHIFT 8
-#define RT5631_R_VOL_SHIFT 0
-
-/* Speaker Output Control(0x02) */
-#define RT5631_SPK_L_VOL_SEL_MASK (0x1 << 14)
-#define RT5631_SPK_L_VOL_SEL_VMID (0x0 << 14)
-#define RT5631_SPK_L_VOL_SEL_SPKMIX_L (0x1 << 14)
-#define RT5631_SPK_R_VOL_SEL_MASK (0x1 << 6)
-#define RT5631_SPK_R_VOL_SEL_VMID (0x0 << 6)
-#define RT5631_SPK_R_VOL_SEL_SPKMIX_R (0x1 << 6)
-
-/* Headphone Output Control(0x04) */
-#define RT5631_HP_L_VOL_SEL_MASK (0x1 << 14)
-#define RT5631_HP_L_VOL_SEL_VMID (0x0 << 14)
-#define RT5631_HP_L_VOL_SEL_OUTMIX_L (0x1 << 14)
-#define RT5631_HP_R_VOL_SEL_MASK (0x1 << 6)
-#define RT5631_HP_R_VOL_SEL_VMID (0x0 << 6)
-#define RT5631_HP_R_VOL_SEL_OUTMIX_R (0x1 << 6)
-
-/* Output Control for AUXOUT/MONO(0x06) */
-#define RT5631_AUXOUT_1_VOL_SEL_MASK (0x1 << 14)
-#define RT5631_AUXOUT_1_VOL_SEL_VMID (0x0 << 14)
-#define RT5631_AUXOUT_1_VOL_SEL_OUTMIX_L (0x1 << 14)
-#define RT5631_MUTE_MONO (0x1 << 13)
-#define RT5631_MUTE_MONO_SHIFT 13
-#define RT5631_AUXOUT_2_VOL_SEL_MASK (0x1 << 6)
-#define RT5631_AUXOUT_2_VOL_SEL_VMID (0x0 << 6)
-#define RT5631_AUXOUT_2_VOL_SEL_OUTMIX_R (0x1 << 6)
-
-/* Microphone Input Control 1(0x0E) */
-#define RT5631_MIC1_DIFF_INPUT_CTRL (0x1 << 15)
-#define RT5631_MIC1_DIFF_INPUT_SHIFT 15
-#define RT5631_MIC2_DIFF_INPUT_CTRL (0x1 << 7)
-#define RT5631_MIC2_DIFF_INPUT_SHIFT 7
-
-/* Stereo DAC Digital Volume2(0x10) */
-#define RT5631_DAC_VOL_MASK 0xff
-
-/* ADC Recording Mixer Control(0x14) */
-#define RT5631_M_OUTMIXER_L_TO_RECMIXER_L (0x1 << 15)
-#define RT5631_M_OUTMIXL_RECMIXL_BIT 15
-#define RT5631_M_MIC1_TO_RECMIXER_L (0x1 << 14)
-#define RT5631_M_MIC1_RECMIXL_BIT 14
-#define RT5631_M_AXIL_TO_RECMIXER_L (0x1 << 13)
-#define RT5631_M_AXIL_RECMIXL_BIT 13
-#define RT5631_M_MONO_IN_TO_RECMIXER_L (0x1 << 12)
-#define RT5631_M_MONO_IN_RECMIXL_BIT 12
-#define RT5631_M_OUTMIXER_R_TO_RECMIXER_R (0x1 << 7)
-#define RT5631_M_OUTMIXR_RECMIXR_BIT 7
-#define RT5631_M_MIC2_TO_RECMIXER_R (0x1 << 6)
-#define RT5631_M_MIC2_RECMIXR_BIT 6
-#define RT5631_M_AXIR_TO_RECMIXER_R (0x1 << 5)
-#define RT5631_M_AXIR_RECMIXR_BIT 5
-#define RT5631_M_MONO_IN_TO_RECMIXER_R (0x1 << 4)
-#define RT5631_M_MONO_IN_RECMIXR_BIT 4
-
-/* Left Output Mixer Control(0x1A) */
-#define RT5631_M_RECMIXER_L_TO_OUTMIXER_L (0x1 << 15)
-#define RT5631_M_RECMIXL_OUTMIXL_BIT 15
-#define RT5631_M_RECMIXER_R_TO_OUTMIXER_L (0x1 << 14)
-#define RT5631_M_RECMIXR_OUTMIXL_BIT 14
-#define RT5631_M_DAC_L_TO_OUTMIXER_L (0x1 << 13)
-#define RT5631_M_DACL_OUTMIXL_BIT 13
-#define RT5631_M_MIC1_TO_OUTMIXER_L (0x1 << 12)
-#define RT5631_M_MIC1_OUTMIXL_BIT 12
-#define RT5631_M_MIC2_TO_OUTMIXER_L (0x1 << 11)
-#define RT5631_M_MIC2_OUTMIXL_BIT 11
-#define RT5631_M_MONO_IN_P_TO_OUTMIXER_L (0x1 << 10)
-#define RT5631_M_MONO_INP_OUTMIXL_BIT 10
-#define RT5631_M_AXIL_TO_OUTMIXER_L (0x1 << 9)
-#define RT5631_M_AXIL_OUTMIXL_BIT 9
-#define RT5631_M_AXIR_TO_OUTMIXER_L (0x1 << 8)
-#define RT5631_M_AXIR_OUTMIXL_BIT 8
-#define RT5631_M_VDAC_TO_OUTMIXER_L (0x1 << 7)
-#define RT5631_M_VDAC_OUTMIXL_BIT 7
-
-/* Right Output Mixer Control(0x1C) */
-#define RT5631_M_RECMIXER_L_TO_OUTMIXER_R (0x1 << 15)
-#define RT5631_M_RECMIXL_OUTMIXR_BIT 15
-#define RT5631_M_RECMIXER_R_TO_OUTMIXER_R (0x1 << 14)
-#define RT5631_M_RECMIXR_OUTMIXR_BIT 14
-#define RT5631_M_DAC_R_TO_OUTMIXER_R (0x1 << 13)
-#define RT5631_M_DACR_OUTMIXR_BIT 13
-#define RT5631_M_MIC1_TO_OUTMIXER_R (0x1 << 12)
-#define RT5631_M_MIC1_OUTMIXR_BIT 12
-#define RT5631_M_MIC2_TO_OUTMIXER_R (0x1 << 11)
-#define RT5631_M_MIC2_OUTMIXR_BIT 11
-#define RT5631_M_MONO_IN_N_TO_OUTMIXER_R (0x1 << 10)
-#define RT5631_M_MONO_INN_OUTMIXR_BIT 10
-#define RT5631_M_AXIL_TO_OUTMIXER_R (0x1 << 9)
-#define RT5631_M_AXIL_OUTMIXR_BIT 9
-#define RT5631_M_AXIR_TO_OUTMIXER_R (0x1 << 8)
-#define RT5631_M_AXIR_OUTMIXR_BIT 8
-#define RT5631_M_VDAC_TO_OUTMIXER_R (0x1 << 7)
-#define RT5631_M_VDAC_OUTMIXR_BIT 7
-
-/* Lout Mixer Control(0x1E) */
-#define RT5631_M_MIC1_TO_AXO1MIXER (0x1 << 15)
-#define RT5631_M_MIC1_AXO1MIX_BIT 15
-#define RT5631_M_MIC2_TO_AXO1MIXER (0x1 << 11)
-#define RT5631_M_MIC2_AXO1MIX_BIT 11
-#define RT5631_M_OUTMIXER_L_TO_AXO1MIXER (0x1 << 7)
-#define RT5631_M_OUTMIXL_AXO1MIX_BIT 7
-#define RT5631_M_OUTMIXER_R_TO_AXO1MIXER (0x1 << 6)
-#define RT5631_M_OUTMIXR_AXO1MIX_BIT 6
-
-/* Rout Mixer Control(0x20) */
-#define RT5631_M_MIC1_TO_AXO2MIXER (0x1 << 15)
-#define RT5631_M_MIC1_AXO2MIX_BIT 15
-#define RT5631_M_MIC2_TO_AXO2MIXER (0x1 << 11)
-#define RT5631_M_MIC2_AXO2MIX_BIT 11
-#define RT5631_M_OUTMIXER_L_TO_AXO2MIXER (0x1 << 7)
-#define RT5631_M_OUTMIXL_AXO2MIX_BIT 7
-#define RT5631_M_OUTMIXER_R_TO_AXO2MIXER (0x1 << 6)
-#define RT5631_M_OUTMIXR_AXO2MIX_BIT 6
-
-/* Micphone Input Control 2(0x22) */
-#define RT5631_MIC_BIAS_90_PRECNET_AVDD 1
-#define RT5631_MIC_BIAS_75_PRECNET_AVDD 2
-
-#define RT5631_MIC1_BOOST_CTRL_MASK (0xf << 12)
-#define RT5631_MIC1_BOOST_CTRL_BYPASS (0x0 << 12)
-#define RT5631_MIC1_BOOST_CTRL_20DB (0x1 << 12)
-#define RT5631_MIC1_BOOST_CTRL_24DB (0x2 << 12)
-#define RT5631_MIC1_BOOST_CTRL_30DB (0x3 << 12)
-#define RT5631_MIC1_BOOST_CTRL_35DB (0x4 << 12)
-#define RT5631_MIC1_BOOST_CTRL_40DB (0x5 << 12)
-#define RT5631_MIC1_BOOST_CTRL_34DB (0x6 << 12)
-#define RT5631_MIC1_BOOST_CTRL_50DB (0x7 << 12)
-#define RT5631_MIC1_BOOST_CTRL_52DB (0x8 << 12)
-#define RT5631_MIC1_BOOST_SHIFT 12
-
-#define RT5631_MIC2_BOOST_CTRL_MASK (0xf << 8)
-#define RT5631_MIC2_BOOST_CTRL_BYPASS (0x0 << 8)
-#define RT5631_MIC2_BOOST_CTRL_20DB (0x1 << 8)
-#define RT5631_MIC2_BOOST_CTRL_24DB (0x2 << 8)
-#define RT5631_MIC2_BOOST_CTRL_30DB (0x3 << 8)
-#define RT5631_MIC2_BOOST_CTRL_35DB (0x4 << 8)
-#define RT5631_MIC2_BOOST_CTRL_40DB (0x5 << 8)
-#define RT5631_MIC2_BOOST_CTRL_34DB (0x6 << 8)
-#define RT5631_MIC2_BOOST_CTRL_50DB (0x7 << 8)
-#define RT5631_MIC2_BOOST_CTRL_52DB (0x8 << 8)
-#define RT5631_MIC2_BOOST_SHIFT 8
-
-#define RT5631_MICBIAS1_VOLT_CTRL_MASK (0x1 << 7)
-#define RT5631_MICBIAS1_VOLT_CTRL_90P (0x0 << 7)
-#define RT5631_MICBIAS1_VOLT_CTRL_75P (0x1 << 7)
-
-#define RT5631_MICBIAS1_S_C_DET_MASK (0x1 << 6)
-#define RT5631_MICBIAS1_S_C_DET_DIS (0x0 << 6)
-#define RT5631_MICBIAS1_S_C_DET_ENA (0x1 << 6)
-
-#define RT5631_MICBIAS1_SHORT_CURR_DET_MASK (0x3 << 4)
-#define RT5631_MICBIAS1_SHORT_CURR_DET_600UA (0x0 << 4)
-#define RT5631_MICBIAS1_SHORT_CURR_DET_1500UA (0x1 << 4)
-#define RT5631_MICBIAS1_SHORT_CURR_DET_2000UA (0x2 << 4)
-
-#define RT5631_MICBIAS2_VOLT_CTRL_MASK (0x1 << 3)
-#define RT5631_MICBIAS2_VOLT_CTRL_90P (0x0 << 3)
-#define RT5631_MICBIAS2_VOLT_CTRL_75P (0x1 << 3)
-
-#define RT5631_MICBIAS2_S_C_DET_MASK (0x1 << 2)
-#define RT5631_MICBIAS2_S_C_DET_DIS (0x0 << 2)
-#define RT5631_MICBIAS2_S_C_DET_ENA (0x1 << 2)
-
-#define RT5631_MICBIAS2_SHORT_CURR_DET_MASK (0x3)
-#define RT5631_MICBIAS2_SHORT_CURR_DET_600UA (0x0)
-#define RT5631_MICBIAS2_SHORT_CURR_DET_1500UA (0x1)
-#define RT5631_MICBIAS2_SHORT_CURR_DET_2000UA (0x2)
-
-
-/* Digital Microphone Control(0x24) */
-#define RT5631_DMIC_ENA_MASK (0x1 << 15)
-#define RT5631_DMIC_ENA_SHIFT 15
-/* DMIC_ENA: DMIC to ADC Digital filter */
-#define RT5631_DMIC_ENA (0x1 << 15)
-/* DMIC_DIS: ADC mixer to ADC Digital filter */
-#define RT5631_DMIC_DIS (0x0 << 15)
-#define RT5631_DMIC_L_CH_MUTE (0x1 << 13)
-#define RT5631_DMIC_L_CH_MUTE_SHIFT 13
-#define RT5631_DMIC_R_CH_MUTE (0x1 << 12)
-#define RT5631_DMIC_R_CH_MUTE_SHIFT 12
-#define RT5631_DMIC_L_CH_LATCH_MASK (0x1 << 9)
-#define RT5631_DMIC_L_CH_LATCH_RISING (0x1 << 9)
-#define RT5631_DMIC_L_CH_LATCH_FALLING (0x0 << 9)
-#define RT5631_DMIC_R_CH_LATCH_MASK (0x1 << 8)
-#define RT5631_DMIC_R_CH_LATCH_RISING (0x1 << 8)
-#define RT5631_DMIC_R_CH_LATCH_FALLING (0x0 << 8)
-#define RT5631_DMIC_CLK_CTRL_MASK (0x3 << 4)
-#define RT5631_DMIC_CLK_CTRL_TO_128FS (0x0 << 4)
-#define RT5631_DMIC_CLK_CTRL_TO_64FS (0x1 << 4)
-#define RT5631_DMIC_CLK_CTRL_TO_32FS (0x2 << 4)
-
-/* Microphone Input Volume(0x26) */
-#define RT5631_MONO_DIFF_INPUT_SHIFT 15
-
-/* Speaker Mixer Control(0x28) */
-#define RT5631_M_RECMIXER_L_TO_SPKMIXER_L (0x1 << 15)
-#define RT5631_M_RECMIXL_SPKMIXL_BIT 15
-#define RT5631_M_MIC1_P_TO_SPKMIXER_L (0x1 << 14)
-#define RT5631_M_MIC1P_SPKMIXL_BIT 14
-#define RT5631_M_DAC_L_TO_SPKMIXER_L (0x1 << 13)
-#define RT5631_M_DACL_SPKMIXL_BIT 13
-#define RT5631_M_OUTMIXER_L_TO_SPKMIXER_L (0x1 << 12)
-#define RT5631_M_OUTMIXL_SPKMIXL_BIT 12
-
-#define RT5631_M_RECMIXER_R_TO_SPKMIXER_R (0x1 << 7)
-#define RT5631_M_RECMIXR_SPKMIXR_BIT 7
-#define RT5631_M_MIC2_P_TO_SPKMIXER_R (0x1 << 6)
-#define RT5631_M_MIC2P_SPKMIXR_BIT 6
-#define RT5631_M_DAC_R_TO_SPKMIXER_R (0x1 << 5)
-#define RT5631_M_DACR_SPKMIXR_BIT 5
-#define RT5631_M_OUTMIXER_R_TO_SPKMIXER_R (0x1 << 4)
-#define RT5631_M_OUTMIXR_SPKMIXR_BIT 4
-
-/* Speaker/Mono Output Control(0x2A) */
-#define RT5631_M_SPKVOL_L_TO_SPOL_MIXER (0x1 << 15)
-#define RT5631_M_SPKVOLL_SPOLMIX_BIT 15
-#define RT5631_M_SPKVOL_R_TO_SPOL_MIXER (0x1 << 14)
-#define RT5631_M_SPKVOLR_SPOLMIX_BIT 14
-#define RT5631_M_SPKVOL_L_TO_SPOR_MIXER (0x1 << 13)
-#define RT5631_M_SPKVOLL_SPORMIX_BIT 13
-#define RT5631_M_SPKVOL_R_TO_SPOR_MIXER (0x1 << 12)
-#define RT5631_M_SPKVOLR_SPORMIX_BIT 12
-#define RT5631_M_OUTVOL_L_TO_MONOMIXER (0x1 << 11)
-#define RT5631_M_OUTVOLL_MONOMIX_BIT 11
-#define RT5631_M_OUTVOL_R_TO_MONOMIXER (0x1 << 10)
-#define RT5631_M_OUTVOLR_MONOMIX_BIT 10
-
-/* Speaker/Mono/HP Output Control(0x2C) */
-#define RT5631_SPK_L_MUX_SEL_MASK (0x3 << 14)
-#define RT5631_SPK_L_MUX_SEL_SPKMIXER_L (0x0 << 14)
-#define RT5631_SPK_L_MUX_SEL_MONO_IN (0x1 << 14)
-#define RT5631_SPK_L_MUX_SEL_DAC_L (0x3 << 14)
-#define RT5631_SPK_L_MUX_SEL_SHIFT 14
-
-#define RT5631_SPK_R_MUX_SEL_MASK (0x3 << 10)
-#define RT5631_SPK_R_MUX_SEL_SPKMIXER_R (0x0 << 10)
-#define RT5631_SPK_R_MUX_SEL_MONO_IN (0x1 << 10)
-#define RT5631_SPK_R_MUX_SEL_DAC_R (0x3 << 10)
-#define RT5631_SPK_R_MUX_SEL_SHIFT 10
-
-#define RT5631_MONO_MUX_SEL_MASK (0x3 << 6)
-#define RT5631_MONO_MUX_SEL_MONOMIXER (0x0 << 6)
-#define RT5631_MONO_MUX_SEL_MONO_IN (0x1 << 6)
-#define RT5631_MONO_MUX_SEL_SHIFT 6
-
-#define RT5631_HP_L_MUX_SEL_MASK (0x1 << 3)
-#define RT5631_HP_L_MUX_SEL_HPVOL_L (0x0 << 3)
-#define RT5631_HP_L_MUX_SEL_DAC_L (0x1 << 3)
-#define RT5631_HP_L_MUX_SEL_SHIFT 3
-
-#define RT5631_HP_R_MUX_SEL_MASK (0x1 << 2)
-#define RT5631_HP_R_MUX_SEL_HPVOL_R (0x0 << 2)
-#define RT5631_HP_R_MUX_SEL_DAC_R (0x1 << 2)
-#define RT5631_HP_R_MUX_SEL_SHIFT 2
-
-/* Stereo I2S Serial Data Port Control(0x34) */
-#define RT5631_SDP_MODE_SEL_MASK (0x1 << 15)
-#define RT5631_SDP_MODE_SEL_MASTER (0x0 << 15)
-#define RT5631_SDP_MODE_SEL_SLAVE (0x1 << 15)
-
-#define RT5631_SDP_ADC_CPS_SEL_MASK (0x3 << 10)
-#define RT5631_SDP_ADC_CPS_SEL_OFF (0x0 << 10)
-#define RT5631_SDP_ADC_CPS_SEL_U_LAW (0x1 << 10)
-#define RT5631_SDP_ADC_CPS_SEL_A_LAW (0x2 << 10)
-
-#define RT5631_SDP_DAC_CPS_SEL_MASK (0x3 << 8)
-#define RT5631_SDP_DAC_CPS_SEL_OFF (0x0 << 8)
-#define RT5631_SDP_DAC_CPS_SEL_U_LAW (0x1 << 8)
-#define RT5631_SDP_DAC_CPS_SEL_A_LAW (0x2 << 8)
-/* 0:Normal 1:Invert */
-#define RT5631_SDP_I2S_BCLK_POL_CTRL (0x1 << 7)
-/* 0:Normal 1:Invert */
-#define RT5631_SDP_DAC_R_INV (0x1 << 6)
-/* 0:ADC data appear at left phase of LRCK
- * 1:ADC data appear at right phase of LRCK
- */
-#define RT5631_SDP_ADC_DATA_L_R_SWAP (0x1 << 5)
-/* 0:DAC data appear at left phase of LRCK
- * 1:DAC data appear at right phase of LRCK
- */
-#define RT5631_SDP_DAC_DATA_L_R_SWAP (0x1 << 4)
-
-/* Data Length Slection */
-#define RT5631_SDP_I2S_DL_MASK (0x3 << 2)
-#define RT5631_SDP_I2S_DL_16 (0x0 << 2)
-#define RT5631_SDP_I2S_DL_20 (0x1 << 2)
-#define RT5631_SDP_I2S_DL_24 (0x2 << 2)
-#define RT5631_SDP_I2S_DL_8 (0x3 << 2)
-
-/* PCM Data Format Selection */
-#define RT5631_SDP_I2S_DF_MASK (0x3)
-#define RT5631_SDP_I2S_DF_I2S (0x0)
-#define RT5631_SDP_I2S_DF_LEFT (0x1)
-#define RT5631_SDP_I2S_DF_PCM_A (0x2)
-#define RT5631_SDP_I2S_DF_PCM_B (0x3)
-
-/* Stereo AD/DA Clock Control(0x38h) */
-#define RT5631_I2S_PRE_DIV_MASK (0x7 << 13)
-#define RT5631_I2S_PRE_DIV_1 (0x0 << 13)
-#define RT5631_I2S_PRE_DIV_2 (0x1 << 13)
-#define RT5631_I2S_PRE_DIV_4 (0x2 << 13)
-#define RT5631_I2S_PRE_DIV_8 (0x3 << 13)
-#define RT5631_I2S_PRE_DIV_16 (0x4 << 13)
-#define RT5631_I2S_PRE_DIV_32 (0x5 << 13)
-/* CLOCK RELATIVE OF BCLK AND LCRK */
-#define RT5631_I2S_LRCK_SEL_N_BCLK_MASK (0x1 << 12)
-#define RT5631_I2S_LRCK_SEL_64_BCLK (0x0 << 12) /* 64FS */
-#define RT5631_I2S_LRCK_SEL_32_BCLK (0x1 << 12) /* 32FS */
-
-#define RT5631_DAC_OSR_SEL_MASK (0x3 << 10)
-#define RT5631_DAC_OSR_SEL_128FS (0x3 << 10)
-#define RT5631_DAC_OSR_SEL_64FS (0x3 << 10)
-#define RT5631_DAC_OSR_SEL_32FS (0x3 << 10)
-#define RT5631_DAC_OSR_SEL_16FS (0x3 << 10)
-
-#define RT5631_ADC_OSR_SEL_MASK (0x3 << 8)
-#define RT5631_ADC_OSR_SEL_128FS (0x3 << 8)
-#define RT5631_ADC_OSR_SEL_64FS (0x3 << 8)
-#define RT5631_ADC_OSR_SEL_32FS (0x3 << 8)
-#define RT5631_ADC_OSR_SEL_16FS (0x3 << 8)
-
-#define RT5631_ADDA_FILTER_CLK_SEL_256FS (0 << 7) /* 256FS */
-#define RT5631_ADDA_FILTER_CLK_SEL_384FS (1 << 7) /* 384FS */
-
-/* Power managment addition 1 (0x3A) */
-#define RT5631_PWR_MAIN_I2S_EN (0x1 << 15)
-#define RT5631_PWR_MAIN_I2S_BIT 15
-#define RT5631_PWR_CLASS_D (0x1 << 12)
-#define RT5631_PWR_CLASS_D_BIT 12
-#define RT5631_PWR_ADC_L_CLK (0x1 << 11)
-#define RT5631_PWR_ADC_L_CLK_BIT 11
-#define RT5631_PWR_ADC_R_CLK (0x1 << 10)
-#define RT5631_PWR_ADC_R_CLK_BIT 10
-#define RT5631_PWR_DAC_L_CLK (0x1 << 9)
-#define RT5631_PWR_DAC_L_CLK_BIT 9
-#define RT5631_PWR_DAC_R_CLK (0x1 << 8)
-#define RT5631_PWR_DAC_R_CLK_BIT 8
-#define RT5631_PWR_DAC_REF (0x1 << 7)
-#define RT5631_PWR_DAC_REF_BIT 7
-#define RT5631_PWR_DAC_L_TO_MIXER (0x1 << 6)
-#define RT5631_PWR_DAC_L_TO_MIXER_BIT 6
-#define RT5631_PWR_DAC_R_TO_MIXER (0x1 << 5)
-#define RT5631_PWR_DAC_R_TO_MIXER_BIT 5
-
-/* Power managment addition 2 (0x3B) */
-#define RT5631_PWR_OUTMIXER_L (0x1 << 15)
-#define RT5631_PWR_OUTMIXER_L_BIT 15
-#define RT5631_PWR_OUTMIXER_R (0x1 << 14)
-#define RT5631_PWR_OUTMIXER_R_BIT 14
-#define RT5631_PWR_SPKMIXER_L (0x1 << 13)
-#define RT5631_PWR_SPKMIXER_L_BIT 13
-#define RT5631_PWR_SPKMIXER_R (0x1 << 12)
-#define RT5631_PWR_SPKMIXER_R_BIT 12
-#define RT5631_PWR_RECMIXER_L (0x1 << 11)
-#define RT5631_PWR_RECMIXER_L_BIT 11
-#define RT5631_PWR_RECMIXER_R (0x1 << 10)
-#define RT5631_PWR_RECMIXER_R_BIT 10
-#define RT5631_PWR_MIC1_BOOT_GAIN (0x1 << 5)
-#define RT5631_PWR_MIC1_BOOT_GAIN_BIT 5
-#define RT5631_PWR_MIC2_BOOT_GAIN (0x1 << 4)
-#define RT5631_PWR_MIC2_BOOT_GAIN_BIT 4
-#define RT5631_PWR_MICBIAS1_VOL (0x1 << 3)
-#define RT5631_PWR_MICBIAS1_VOL_BIT 3
-#define RT5631_PWR_MICBIAS2_VOL (0x1 << 2)
-#define RT5631_PWR_MICBIAS2_VOL_BIT 2
-#define RT5631_PWR_PLL1 (0x1 << 1)
-#define RT5631_PWR_PLL1_BIT 1
-#define RT5631_PWR_PLL2 (0x1 << 0)
-#define RT5631_PWR_PLL2_BIT 0
-
-/* Power managment addition 3(0x3C) */
-#define RT5631_PWR_VREF (0x1 << 15)
-#define RT5631_PWR_VREF_BIT 15
-#define RT5631_PWR_FAST_VREF_CTRL (0x1 << 14)
-#define RT5631_PWR_FAST_VREF_CTRL_BIT 14
-#define RT5631_PWR_MAIN_BIAS (0x1 << 13)
-#define RT5631_PWR_MAIN_BIAS_BIT 13
-#define RT5631_PWR_AXO1MIXER (0x1 << 11)
-#define RT5631_PWR_AXO1MIXER_BIT 11
-#define RT5631_PWR_AXO2MIXER (0x1 << 10)
-#define RT5631_PWR_AXO2MIXER_BIT 10
-#define RT5631_PWR_MONOMIXER (0x1 << 9)
-#define RT5631_PWR_MONOMIXER_BIT 9
-#define RT5631_PWR_MONO_DEPOP_DIS (0x1 << 8)
-#define RT5631_PWR_MONO_DEPOP_DIS_BIT 8
-#define RT5631_PWR_MONO_AMP_EN (0x1 << 7)
-#define RT5631_PWR_MONO_AMP_EN_BIT 7
-#define RT5631_PWR_CHARGE_PUMP (0x1 << 4)
-#define RT5631_PWR_CHARGE_PUMP_BIT 4
-#define RT5631_PWR_HP_L_AMP (0x1 << 3)
-#define RT5631_PWR_HP_L_AMP_BIT 3
-#define RT5631_PWR_HP_R_AMP (0x1 << 2)
-#define RT5631_PWR_HP_R_AMP_BIT 2
-#define RT5631_PWR_HP_DEPOP_DIS (0x1 << 1)
-#define RT5631_PWR_HP_DEPOP_DIS_BIT 1
-#define RT5631_PWR_HP_AMP_DRIVING (0x1 << 0)
-#define RT5631_PWR_HP_AMP_DRIVING_BIT 0
-
-/* Power managment addition 4(0x3E) */
-#define RT5631_PWR_SPK_L_VOL (0x1 << 15)
-#define RT5631_PWR_SPK_L_VOL_BIT 15
-#define RT5631_PWR_SPK_R_VOL (0x1 << 14)
-#define RT5631_PWR_SPK_R_VOL_BIT 14
-#define RT5631_PWR_LOUT_VOL (0x1 << 13)
-#define RT5631_PWR_LOUT_VOL_BIT 13
-#define RT5631_PWR_ROUT_VOL (0x1 << 12)
-#define RT5631_PWR_ROUT_VOL_BIT 12
-#define RT5631_PWR_HP_L_OUT_VOL (0x1 << 11)
-#define RT5631_PWR_HP_L_OUT_VOL_BIT 11
-#define RT5631_PWR_HP_R_OUT_VOL (0x1 << 10)
-#define RT5631_PWR_HP_R_OUT_VOL_BIT 10
-#define RT5631_PWR_AXIL_IN_VOL (0x1 << 9)
-#define RT5631_PWR_AXIL_IN_VOL_BIT 9
-#define RT5631_PWR_AXIR_IN_VOL (0x1 << 8)
-#define RT5631_PWR_AXIR_IN_VOL_BIT 8
-#define RT5631_PWR_MONO_IN_P_VOL (0x1 << 7)
-#define RT5631_PWR_MONO_IN_P_VOL_BIT 7
-#define RT5631_PWR_MONO_IN_N_VOL (0x1 << 6)
-#define RT5631_PWR_MONO_IN_N_VOL_BIT 6
-
-/* General Purpose Control Register(0x40) */
-#define RT5631_SPK_AMP_AUTO_RATIO_EN (0x1 << 15)
-
-#define RT5631_SPK_AMP_RATIO_CTRL_MASK (0x7 << 12)
-#define RT5631_SPK_AMP_RATIO_CTRL_2_34 (0x0 << 12) /* 7.40DB */
-#define RT5631_SPK_AMP_RATIO_CTRL_1_99 (0x1 << 12) /* 5.99DB */
-#define RT5631_SPK_AMP_RATIO_CTRL_1_68 (0x2 << 12) /* 4.50DB */
-#define RT5631_SPK_AMP_RATIO_CTRL_1_56 (0x3 << 12) /* 3.86DB */
-#define RT5631_SPK_AMP_RATIO_CTRL_1_44 (0x4 << 12) /* 3.16DB */
-#define RT5631_SPK_AMP_RATIO_CTRL_1_27 (0x5 << 12) /* 2.10DB */
-#define RT5631_SPK_AMP_RATIO_CTRL_1_09 (0x6 << 12) /* 0.80DB */
-#define RT5631_SPK_AMP_RATIO_CTRL_1_00 (0x7 << 12) /* 0.00DB */
-#define RT5631_SPK_AMP_RATIO_CTRL_SHIFT 12
-
-#define RT5631_STEREO_DAC_HI_PASS_FILT_EN (0x1 << 11)
-#define RT5631_STEREO_ADC_HI_PASS_FILT_EN (0x1 << 10)
-/* Select ADC Wind Filter Clock type */
-#define RT5631_ADC_WIND_FILT_MASK (0x3 << 4)
-#define RT5631_ADC_WIND_FILT_8_16_32K (0x0 << 4) /*8/16/32k*/
-#define RT5631_ADC_WIND_FILT_11_22_44K (0x1 << 4) /*11/22/44k*/
-#define RT5631_ADC_WIND_FILT_12_24_48K (0x2 << 4) /*12/24/48k*/
-#define RT5631_ADC_WIND_FILT_EN (0x1 << 3)
-/* SelectADC Wind Filter Corner Frequency */
-#define RT5631_ADC_WIND_CNR_FREQ_MASK (0x7 << 0)
-#define RT5631_ADC_WIND_CNR_FREQ_82_113_122 (0x0 << 0) /* 82/113/122 Hz */
-#define RT5631_ADC_WIND_CNR_FREQ_102_141_153 (0x1 << 0) /* 102/141/153 Hz */
-#define RT5631_ADC_WIND_CNR_FREQ_131_180_156 (0x2 << 0) /* 131/180/156 Hz */
-#define RT5631_ADC_WIND_CNR_FREQ_163_225_245 (0x3 << 0) /* 163/225/245 Hz */
-#define RT5631_ADC_WIND_CNR_FREQ_204_281_306 (0x4 << 0) /* 204/281/306 Hz */
-#define RT5631_ADC_WIND_CNR_FREQ_261_360_392 (0x5 << 0) /* 261/360/392 Hz */
-#define RT5631_ADC_WIND_CNR_FREQ_327_450_490 (0x6 << 0) /* 327/450/490 Hz */
-#define RT5631_ADC_WIND_CNR_FREQ_408_563_612 (0x7 << 0) /* 408/563/612 Hz */
-
-/* Global Clock Control Register(0x42) */
-#define RT5631_SYSCLK_SOUR_SEL_MASK (0x3 << 14)
-#define RT5631_SYSCLK_SOUR_SEL_MCLK (0x0 << 14)
-#define RT5631_SYSCLK_SOUR_SEL_PLL (0x1 << 14)
-#define RT5631_SYSCLK_SOUR_SEL_PLL_TCK (0x2 << 14)
-
-#define RT5631_PLLCLK_SOUR_SEL_MASK (0x3 << 12)
-#define RT5631_PLLCLK_SOUR_SEL_MCLK (0x0 << 12)
-#define RT5631_PLLCLK_SOUR_SEL_BCLK (0x1 << 12)
-#define RT5631_PLLCLK_SOUR_SEL_VBCLK (0x2 << 12)
-
-#define RT5631_PLLCLK_PRE_DIV1 (0x0 << 11)
-#define RT5631_PLLCLK_PRE_DIV2 (0x1 << 11)
-
-/* PLL Control(0x44) */
-#define RT5631_PLL_CTRL_M_VAL(m) ((m)&0xf)
-#define RT5631_PLL_CTRL_K_VAL(k) (((k)&0x7) << 4)
-#define RT5631_PLL_CTRL_N_VAL(n) (((n)&0xff) << 8)
-
-/* Internal Status and IRQ Control2(0x4A) */
-#define RT5631_ADC_DATA_SEL_MASK (0x3 << 14)
-#define RT5631_ADC_DATA_SEL_Disable (0x0 << 14)
-#define RT5631_ADC_DATA_SEL_MIC1 (0x1 << 14)
-#define RT5631_ADC_DATA_SEL_MIC1_SHIFT 14
-#define RT5631_ADC_DATA_SEL_MIC2 (0x2 << 14)
-#define RT5631_ADC_DATA_SEL_MIC2_SHIFT 15
-#define RT5631_ADC_DATA_SEL_STO (0x3 << 14)
-#define RT5631_ADC_DATA_SEL_SHIFT 14
-
-/* GPIO Pin Configuration(0x4C) */
-#define RT5631_GPIO_PIN_FUN_SEL_MASK (0x1 << 15)
-#define RT5631_GPIO_PIN_FUN_SEL_IRQ (0x1 << 15)
-#define RT5631_GPIO_PIN_FUN_SEL_GPIO_DIMC (0x0 << 15)
-
-#define RT5631_GPIO_DMIC_FUN_SEL_MASK (0x1 << 3)
-#define RT5631_GPIO_DMIC_FUN_SEL_DIMC (0x1 << 3)
-#define RT5631_GPIO_DMIC_FUN_SEL_GPIO (0x0 << 3)
-
-#define RT5631_GPIO_PIN_CON_MASK (0x1 << 2)
-#define RT5631_GPIO_PIN_SET_INPUT (0x0 << 2)
-#define RT5631_GPIO_PIN_SET_OUTPUT (0x1 << 2)
-
-/* De-POP function Control 1(0x54) */
-#define RT5631_POW_ON_SOFT_GEN (0x1 << 15)
-#define RT5631_EN_MUTE_UNMUTE_DEPOP (0x1 << 14)
-#define RT5631_EN_DEPOP2_FOR_HP (0x1 << 7)
-/* Power Down HPAMP_L Starts Up Signal */
-#define RT5631_PD_HPAMP_L_ST_UP (0x1 << 5)
-/* Power Down HPAMP_R Starts Up Signal */
-#define RT5631_PD_HPAMP_R_ST_UP (0x1 << 4)
-/* Enable left HP mute/unmute depop */
-#define RT5631_EN_HP_L_M_UN_MUTE_DEPOP (0x1 << 1)
-/* Enable right HP mute/unmute depop */
-#define RT5631_EN_HP_R_M_UN_MUTE_DEPOP (0x1 << 0)
-
-/* De-POP Fnction Control(0x56) */
-#define RT5631_EN_ONE_BIT_DEPOP (0x1 << 15)
-#define RT5631_EN_CAP_FREE_DEPOP (0x1 << 14)
-
-/* Jack Detect Control Register(0x5A) */
-#define RT5631_JD_USE_MASK (0x3 << 14)
-#define RT5631_JD_USE_JD2 (0x3 << 14)
-#define RT5631_JD_USE_JD1 (0x2 << 14)
-#define RT5631_JD_USE_GPIO (0x1 << 14)
-#define RT5631_JD_OFF (0x0 << 14)
-/* JD trigger enable for HP */
-#define RT5631_JD_HP_EN (0x1 << 11)
-#define RT5631_JD_HP_TRI_MASK (0x1 << 10)
-#define RT5631_JD_HP_TRI_HI (0x1 << 10)
-#define RT5631_JD_HP_TRI_LO (0x1 << 10)
-/* JD trigger enable for speaker LP/LN */
-#define RT5631_JD_SPK_L_EN (0x1 << 9)
-#define RT5631_JD_SPK_L_TRI_MASK (0x1 << 8)
-#define RT5631_JD_SPK_L_TRI_HI (0x1 << 8)
-#define RT5631_JD_SPK_L_TRI_LO (0x0 << 8)
-/* JD trigger enable for speaker RP/RN */
-#define RT5631_JD_SPK_R_EN (0x1 << 7)
-#define RT5631_JD_SPK_R_TRI_MASK (0x1 << 6)
-#define RT5631_JD_SPK_R_TRI_HI (0x1 << 6)
-#define RT5631_JD_SPK_R_TRI_LO (0x0 << 6)
-/* JD trigger enable for monoout */
-#define RT5631_JD_MONO_EN (0x1 << 5)
-#define RT5631_JD_MONO_TRI_MASK (0x1 << 4)
-#define RT5631_JD_MONO_TRI_HI (0x1 << 4)
-#define RT5631_JD_MONO_TRI_LO (0x0 << 4)
-/* JD trigger enable for Lout */
-#define RT5631_JD_AUX_1_EN (0x1 << 3)
-#define RT5631_JD_AUX_1_MASK (0x1 << 2)
-#define RT5631_JD_AUX_1_TRI_HI (0x1 << 2)
-#define RT5631_JD_AUX_1_TRI_LO (0x0 << 2)
-/* JD trigger enable for Rout */
-#define RT5631_JD_AUX_2_EN (0x1 << 1)
-#define RT5631_JD_AUX_2_MASK (0x1 << 0)
-#define RT5631_JD_AUX_2_TRI_HI (0x1 << 0)
-#define RT5631_JD_AUX_2_TRI_LO (0x0 << 0)
-
-/* ALC CONTROL 1(0x64) */
-#define RT5631_ALC_ATTACK_RATE_MASK (0x1F << 8)
-#define RT5631_ALC_RECOVERY_RATE_MASK (0x1F << 0)
-
-/* ALC CONTROL 2(0x65) */
-/* select Compensation gain for Noise gate function */
-#define RT5631_ALC_COM_NOISE_GATE_MASK (0xF << 0)
-
-/* ALC CONTROL 3(0x66) */
-#define RT5631_ALC_FUN_MASK (0x3 << 14)
-#define RT5631_ALC_FUN_DIS (0x0 << 14)
-#define RT5631_ALC_ENA_DAC_PATH (0x1 << 14)
-#define RT5631_ALC_ENA_ADC_PATH (0x3 << 14)
-#define RT5631_ALC_PARA_UPDATE (0x1 << 13)
-#define RT5631_ALC_LIMIT_LEVEL_MASK (0x1F << 8)
-#define RT5631_ALC_NOISE_GATE_FUN_MASK (0x1 << 7)
-#define RT5631_ALC_NOISE_GATE_FUN_DIS (0x0 << 7)
-#define RT5631_ALC_NOISE_GATE_FUN_ENA (0x1 << 7)
-/* ALC noise gate hold data function */
-#define RT5631_ALC_NOISE_GATE_H_D_MASK (0x1 << 6)
-#define RT5631_ALC_NOISE_GATE_H_D_DIS (0x0 << 6)
-#define RT5631_ALC_NOISE_GATE_H_D_ENA (0x1 << 6)
-
-/* Psedueo Stereo & Spatial Effect Block Control(0x68) */
-#define RT5631_SPATIAL_CTRL_EN (0x1 << 15)
-#define RT5631_ALL_PASS_FILTER_EN (0x1 << 14)
-#define RT5631_PSEUDO_STEREO_EN (0x1 << 13)
-#define RT5631_STEREO_EXPENSION_EN (0x1 << 12)
-/* 3D gain parameter */
-#define RT5631_GAIN_3D_PARA_MASK (0x3 << 6)
-#define RT5631_GAIN_3D_PARA_1_00 (0x0 << 6) /* 3D gain 1.0 */
-#define RT5631_GAIN_3D_PARA_1_50 (0x1 << 6) /* 3D gain 1.5 */
-#define RT5631_GAIN_3D_PARA_2_00 (0x2 << 6) /* 3D gain 2.0 */
-/* 3D ratio parameter */
-#define RT5631_RATIO_3D_MASK (0x3 << 4)
-#define RT5631_RATIO_3D_0_0 (0x0 << 4) /* 3D ratio 0.0 */
-#define RT5631_RATIO_3D_0_66 (0x1 << 4) /* 3D ratio 0.66 */
-#define RT5631_RATIO_3D_1_0 (0x2 << 4) /* 3D ratio 1.0 */
-/* select samplerate for all pass filter */
-#define RT5631_APF_FUN_SLE_MASK (0x3 << 0)
-#define RT5631_APF_FUN_SEL_48K (0x3 << 0)
-#define RT5631_APF_FUN_SEL_44_1K (0x2 << 0)
-#define RT5631_APF_FUN_SEL_32K (0x1 << 0)
-#define RT5631_APF_FUN_DIS (0x0 << 0)
-
-/* EQ CONTROL 1(0x6E) */
-#define RT5631_HW_EQ_PATH_SEL_MASK (0x1 << 15)
-#define RT5631_HW_EQ_PATH_SEL_DAC (0x0 << 15)
-#define RT5631_HW_EQ_PATH_SEL_ADC (0x1 << 15)
-#define RT5631_HW_EQ_UPDATE_CTRL (0x1 << 14)
-
-#define RT5631_EN_HW_EQ_HPF2 (0x1 << 5)
-#define RT5631_EN_HW_EQ_HPF1 (0x1 << 4)
-#define RT5631_EN_HW_EQ_BP3 (0x1 << 3)
-#define RT5631_EN_HW_EQ_BP2 (0x1 << 2)
-#define RT5631_EN_HW_EQ_BP1 (0x1 << 1)
-#define RT5631_EN_HW_EQ_LPF (0x1 << 0)
-
-
-#endif /* __RTCODEC5631_H__ */
diff --git a/ANDROID_3.4.5/sound/soc/codecs/sgtl5000.c b/ANDROID_3.4.5/sound/soc/codecs/sgtl5000.c
deleted file mode 100644
index 8e92fb88..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/sgtl5000.c
+++ /dev/null
@@ -1,1468 +0,0 @@
-/*
- * sgtl5000.c -- SGTL5000 ALSA SoC Audio driver
- *
- * Copyright 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/clk.h>
-#include <linux/regulator/driver.h>
-#include <linux/regulator/machine.h>
-#include <linux/regulator/consumer.h>
-#include <linux/of_device.h>
-#include <sound/core.h>
-#include <sound/tlv.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/initval.h>
-
-#include "sgtl5000.h"
-
-#define SGTL5000_DAP_REG_OFFSET 0x0100
-#define SGTL5000_MAX_REG_OFFSET 0x013A
-
-/* default value of sgtl5000 registers */
-static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET] = {
- [SGTL5000_CHIP_CLK_CTRL] = 0x0008,
- [SGTL5000_CHIP_I2S_CTRL] = 0x0010,
- [SGTL5000_CHIP_SSS_CTRL] = 0x0008,
- [SGTL5000_CHIP_DAC_VOL] = 0x3c3c,
- [SGTL5000_CHIP_PAD_STRENGTH] = 0x015f,
- [SGTL5000_CHIP_ANA_HP_CTRL] = 0x1818,
- [SGTL5000_CHIP_ANA_CTRL] = 0x0111,
- [SGTL5000_CHIP_LINE_OUT_VOL] = 0x0404,
- [SGTL5000_CHIP_ANA_POWER] = 0x7060,
- [SGTL5000_CHIP_PLL_CTRL] = 0x5000,
- [SGTL5000_DAP_BASS_ENHANCE] = 0x0040,
- [SGTL5000_DAP_BASS_ENHANCE_CTRL] = 0x051f,
- [SGTL5000_DAP_SURROUND] = 0x0040,
- [SGTL5000_DAP_EQ_BASS_BAND0] = 0x002f,
- [SGTL5000_DAP_EQ_BASS_BAND1] = 0x002f,
- [SGTL5000_DAP_EQ_BASS_BAND2] = 0x002f,
- [SGTL5000_DAP_EQ_BASS_BAND3] = 0x002f,
- [SGTL5000_DAP_EQ_BASS_BAND4] = 0x002f,
- [SGTL5000_DAP_MAIN_CHAN] = 0x8000,
- [SGTL5000_DAP_AVC_CTRL] = 0x0510,
- [SGTL5000_DAP_AVC_THRESHOLD] = 0x1473,
- [SGTL5000_DAP_AVC_ATTACK] = 0x0028,
- [SGTL5000_DAP_AVC_DECAY] = 0x0050,
-};
-
-/* regulator supplies for sgtl5000, VDDD is an optional external supply */
-enum sgtl5000_regulator_supplies {
- VDDA,
- VDDIO,
- VDDD,
- SGTL5000_SUPPLY_NUM
-};
-
-/* vddd is optional supply */
-static const char *supply_names[SGTL5000_SUPPLY_NUM] = {
- "VDDA",
- "VDDIO",
- "VDDD"
-};
-
-#define LDO_CONSUMER_NAME "VDDD_LDO"
-#define LDO_VOLTAGE 1200000
-
-static struct regulator_consumer_supply ldo_consumer[] = {
- REGULATOR_SUPPLY(LDO_CONSUMER_NAME, NULL),
-};
-
-static struct regulator_init_data ldo_init_data = {
- .constraints = {
- .min_uV = 850000,
- .max_uV = 1600000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .valid_ops_mask = REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = 1,
- .consumer_supplies = &ldo_consumer[0],
-};
-
-/*
- * sgtl5000 internal ldo regulator,
- * enabled when VDDD not provided
- */
-struct ldo_regulator {
- struct regulator_desc desc;
- struct regulator_dev *dev;
- int voltage;
- void *codec_data;
- bool enabled;
-};
-
-/* sgtl5000 private structure in codec */
-struct sgtl5000_priv {
- int sysclk; /* sysclk rate */
- int master; /* i2s master or not */
- int fmt; /* i2s data format */
- struct regulator_bulk_data supplies[SGTL5000_SUPPLY_NUM];
- struct ldo_regulator *ldo;
-};
-
-/*
- * mic_bias power on/off share the same register bits with
- * output impedance of mic bias, when power on mic bias, we
- * need reclaim it to impedance value.
- * 0x0 = Powered off
- * 0x1 = 2Kohm
- * 0x2 = 4Kohm
- * 0x3 = 8Kohm
- */
-static int mic_bias_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- /* change mic bias resistor to 4Kohm */
- snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL,
- SGTL5000_BIAS_R_MASK,
- SGTL5000_BIAS_R_4k << SGTL5000_BIAS_R_SHIFT);
- break;
-
- case SND_SOC_DAPM_PRE_PMD:
- snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL,
- SGTL5000_BIAS_R_MASK, 0);
- break;
- }
- return 0;
-}
-
-/*
- * As manual described, ADC/DAC only works when VAG powerup,
- * So enabled VAG before ADC/DAC up.
- * In power down case, we need wait 400ms when vag fully ramped down.
- */
-static int power_vag_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER,
- SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP);
- break;
-
- case SND_SOC_DAPM_POST_PMD:
- snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER,
- SGTL5000_VAG_POWERUP, 0);
- msleep(400);
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-/* input sources for ADC */
-static const char *adc_mux_text[] = {
- "MIC_IN", "LINE_IN"
-};
-
-static const struct soc_enum adc_enum =
-SOC_ENUM_SINGLE(SGTL5000_CHIP_ANA_CTRL, 2, 2, adc_mux_text);
-
-static const struct snd_kcontrol_new adc_mux =
-SOC_DAPM_ENUM("Capture Mux", adc_enum);
-
-/* input sources for DAC */
-static const char *dac_mux_text[] = {
- "DAC", "LINE_IN"
-};
-
-static const struct soc_enum dac_enum =
-SOC_ENUM_SINGLE(SGTL5000_CHIP_ANA_CTRL, 6, 2, dac_mux_text);
-
-static const struct snd_kcontrol_new dac_mux =
-SOC_DAPM_ENUM("Headphone Mux", dac_enum);
-
-static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
- SND_SOC_DAPM_INPUT("LINE_IN"),
- SND_SOC_DAPM_INPUT("MIC_IN"),
-
- SND_SOC_DAPM_OUTPUT("HP_OUT"),
- SND_SOC_DAPM_OUTPUT("LINE_OUT"),
-
- SND_SOC_DAPM_MICBIAS_E("Mic Bias", SGTL5000_CHIP_MIC_CTRL, 8, 0,
- mic_bias_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-
- SND_SOC_DAPM_PGA("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0),
- SND_SOC_DAPM_PGA("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0),
-
- SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0, &adc_mux),
- SND_SOC_DAPM_MUX("Headphone Mux", SND_SOC_NOPM, 0, 0, &dac_mux),
-
- /* aif for i2s input */
- SND_SOC_DAPM_AIF_IN("AIFIN", "Playback",
- 0, SGTL5000_CHIP_DIG_POWER,
- 0, 0),
-
- /* aif for i2s output */
- SND_SOC_DAPM_AIF_OUT("AIFOUT", "Capture",
- 0, SGTL5000_CHIP_DIG_POWER,
- 1, 0),
-
- SND_SOC_DAPM_SUPPLY("VAG_POWER", SGTL5000_CHIP_ANA_POWER, 7, 0,
- power_vag_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_ADC("ADC", "Capture", SGTL5000_CHIP_ANA_POWER, 1, 0),
- SND_SOC_DAPM_DAC("DAC", "Playback", SGTL5000_CHIP_ANA_POWER, 3, 0),
-};
-
-/* routes for sgtl5000 */
-static const struct snd_soc_dapm_route sgtl5000_dapm_routes[] = {
- {"Capture Mux", "LINE_IN", "LINE_IN"}, /* line_in --> adc_mux */
- {"Capture Mux", "MIC_IN", "MIC_IN"}, /* mic_in --> adc_mux */
-
- {"ADC", NULL, "VAG_POWER"},
- {"ADC", NULL, "Capture Mux"}, /* adc_mux --> adc */
- {"AIFOUT", NULL, "ADC"}, /* adc --> i2s_out */
-
- {"DAC", NULL, "VAG_POWER"},
- {"DAC", NULL, "AIFIN"}, /* i2s-->dac,skip audio mux */
- {"Headphone Mux", "DAC", "DAC"}, /* dac --> hp_mux */
- {"LO", NULL, "DAC"}, /* dac --> line_out */
-
- {"Headphone Mux", "LINE_IN", "LINE_IN"},/* line_in --> hp_mux */
- {"HP", NULL, "Headphone Mux"}, /* hp_mux --> hp */
-
- {"LINE_OUT", NULL, "LO"},
- {"HP_OUT", NULL, "HP"},
-};
-
-/* custom function to fetch info of PCM playback volume */
-static int dac_info_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 0xfc - 0x3c;
- return 0;
-}
-
-/*
- * custom function to get of PCM playback volume
- *
- * dac volume register
- * 15-------------8-7--------------0
- * | R channel vol | L channel vol |
- * -------------------------------
- *
- * PCM volume with 0.5017 dB steps from 0 to -90 dB
- *
- * register values map to dB
- * 0x3B and less = Reserved
- * 0x3C = 0 dB
- * 0x3D = -0.5 dB
- * 0xF0 = -90 dB
- * 0xFC and greater = Muted
- *
- * register value map to userspace value
- *
- * register value 0x3c(0dB) 0xf0(-90dB)0xfc
- * ------------------------------
- * userspace value 0xc0 0
- */
-static int dac_get_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- int reg;
- int l;
- int r;
-
- reg = snd_soc_read(codec, SGTL5000_CHIP_DAC_VOL);
-
- /* get left channel volume */
- l = (reg & SGTL5000_DAC_VOL_LEFT_MASK) >> SGTL5000_DAC_VOL_LEFT_SHIFT;
-
- /* get right channel volume */
- r = (reg & SGTL5000_DAC_VOL_RIGHT_MASK) >> SGTL5000_DAC_VOL_RIGHT_SHIFT;
-
- /* make sure value fall in (0x3c,0xfc) */
- l = clamp(l, 0x3c, 0xfc);
- r = clamp(r, 0x3c, 0xfc);
-
- /* invert it and map to userspace value */
- l = 0xfc - l;
- r = 0xfc - r;
-
- ucontrol->value.integer.value[0] = l;
- ucontrol->value.integer.value[1] = r;
-
- return 0;
-}
-
-/*
- * custom function to put of PCM playback volume
- *
- * dac volume register
- * 15-------------8-7--------------0
- * | R channel vol | L channel vol |
- * -------------------------------
- *
- * PCM volume with 0.5017 dB steps from 0 to -90 dB
- *
- * register values map to dB
- * 0x3B and less = Reserved
- * 0x3C = 0 dB
- * 0x3D = -0.5 dB
- * 0xF0 = -90 dB
- * 0xFC and greater = Muted
- *
- * userspace value map to register value
- *
- * userspace value 0xc0 0
- * ------------------------------
- * register value 0x3c(0dB) 0xf0(-90dB)0xfc
- */
-static int dac_put_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- int reg;
- int l;
- int r;
-
- l = ucontrol->value.integer.value[0];
- r = ucontrol->value.integer.value[1];
-
- /* make sure userspace volume fall in (0, 0xfc-0x3c) */
- l = clamp(l, 0, 0xfc - 0x3c);
- r = clamp(r, 0, 0xfc - 0x3c);
-
- /* invert it, get the value can be set to register */
- l = 0xfc - l;
- r = 0xfc - r;
-
- /* shift to get the register value */
- reg = l << SGTL5000_DAC_VOL_LEFT_SHIFT |
- r << SGTL5000_DAC_VOL_RIGHT_SHIFT;
-
- snd_soc_write(codec, SGTL5000_CHIP_DAC_VOL, reg);
-
- return 0;
-}
-
-static const DECLARE_TLV_DB_SCALE(capture_6db_attenuate, -600, 600, 0);
-
-/* tlv for mic gain, 0db 20db 30db 40db */
-static const unsigned int mic_gain_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
- 1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0),
-};
-
-/* tlv for hp volume, -51.5db to 12.0db, step .5db */
-static const DECLARE_TLV_DB_SCALE(headphone_volume, -5150, 50, 0);
-
-static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
- /* SOC_DOUBLE_S8_TLV with invert */
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Playback Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |
- SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = dac_info_volsw,
- .get = dac_get_volsw,
- .put = dac_put_volsw,
- },
-
- SOC_DOUBLE("Capture Volume", SGTL5000_CHIP_ANA_ADC_CTRL, 0, 4, 0xf, 0),
- SOC_SINGLE_TLV("Capture Attenuate Switch (-6dB)",
- SGTL5000_CHIP_ANA_ADC_CTRL,
- 8, 2, 0, capture_6db_attenuate),
- SOC_SINGLE("Capture ZC Switch", SGTL5000_CHIP_ANA_CTRL, 1, 1, 0),
-
- SOC_DOUBLE_TLV("Headphone Playback Volume",
- SGTL5000_CHIP_ANA_HP_CTRL,
- 0, 8,
- 0x7f, 1,
- headphone_volume),
- SOC_SINGLE("Headphone Playback ZC Switch", SGTL5000_CHIP_ANA_CTRL,
- 5, 1, 0),
-
- SOC_SINGLE_TLV("Mic Volume", SGTL5000_CHIP_MIC_CTRL,
- 0, 4, 0, mic_gain_tlv),
-};
-
-/* mute the codec used by alsa core */
-static int sgtl5000_digital_mute(struct snd_soc_dai *codec_dai, int mute)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 adcdac_ctrl = SGTL5000_DAC_MUTE_LEFT | SGTL5000_DAC_MUTE_RIGHT;
-
- snd_soc_update_bits(codec, SGTL5000_CHIP_ADCDAC_CTRL,
- adcdac_ctrl, mute ? adcdac_ctrl : 0);
-
- return 0;
-}
-
-/* set codec format */
-static int sgtl5000_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
- u16 i2sctl = 0;
-
- sgtl5000->master = 0;
- /*
- * i2s clock and frame master setting.
- * ONLY support:
- * - clock and frame slave,
- * - clock and frame master
- */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- i2sctl |= SGTL5000_I2S_MASTER;
- sgtl5000->master = 1;
- break;
- default:
- return -EINVAL;
- }
-
- /* setting i2s data format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- i2sctl |= SGTL5000_I2S_MODE_PCM;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- i2sctl |= SGTL5000_I2S_MODE_PCM;
- i2sctl |= SGTL5000_I2S_LRALIGN;
- break;
- case SND_SOC_DAIFMT_I2S:
- i2sctl |= SGTL5000_I2S_MODE_I2S_LJ;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- i2sctl |= SGTL5000_I2S_MODE_RJ;
- i2sctl |= SGTL5000_I2S_LRPOL;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- i2sctl |= SGTL5000_I2S_MODE_I2S_LJ;
- i2sctl |= SGTL5000_I2S_LRALIGN;
- break;
- default:
- return -EINVAL;
- }
-
- sgtl5000->fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
-
- /* Clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_NF:
- i2sctl |= SGTL5000_I2S_SCLK_INV;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, SGTL5000_CHIP_I2S_CTRL, i2sctl);
-
- return 0;
-}
-
-/* set codec sysclk */
-static int sgtl5000_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
-
- switch (clk_id) {
- case SGTL5000_SYSCLK:
- sgtl5000->sysclk = freq;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * set clock according to i2s frame clock,
- * sgtl5000 provide 2 clock sources.
- * 1. sys_mclk. sample freq can only configure to
- * 1/256, 1/384, 1/512 of sys_mclk.
- * 2. pll. can derive any audio clocks.
- *
- * clock setting rules:
- * 1. in slave mode, only sys_mclk can use.
- * 2. as constraint by sys_mclk, sample freq should
- * set to 32k, 44.1k and above.
- * 3. using sys_mclk prefer to pll to save power.
- */
-static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate)
-{
- struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
- int clk_ctl = 0;
- int sys_fs; /* sample freq */
-
- /*
- * sample freq should be divided by frame clock,
- * if frame clock lower than 44.1khz, sample feq should set to
- * 32khz or 44.1khz.
- */
- switch (frame_rate) {
- case 8000:
- case 16000:
- sys_fs = 32000;
- break;
- case 11025:
- case 22050:
- sys_fs = 44100;
- break;
- default:
- sys_fs = frame_rate;
- break;
- }
-
- /* set divided factor of frame clock */
- switch (sys_fs / frame_rate) {
- case 4:
- clk_ctl |= SGTL5000_RATE_MODE_DIV_4 << SGTL5000_RATE_MODE_SHIFT;
- break;
- case 2:
- clk_ctl |= SGTL5000_RATE_MODE_DIV_2 << SGTL5000_RATE_MODE_SHIFT;
- break;
- case 1:
- clk_ctl |= SGTL5000_RATE_MODE_DIV_1 << SGTL5000_RATE_MODE_SHIFT;
- break;
- default:
- return -EINVAL;
- }
-
- /* set the sys_fs according to frame rate */
- switch (sys_fs) {
- case 32000:
- clk_ctl |= SGTL5000_SYS_FS_32k << SGTL5000_SYS_FS_SHIFT;
- break;
- case 44100:
- clk_ctl |= SGTL5000_SYS_FS_44_1k << SGTL5000_SYS_FS_SHIFT;
- break;
- case 48000:
- clk_ctl |= SGTL5000_SYS_FS_48k << SGTL5000_SYS_FS_SHIFT;
- break;
- case 96000:
- clk_ctl |= SGTL5000_SYS_FS_96k << SGTL5000_SYS_FS_SHIFT;
- break;
- default:
- dev_err(codec->dev, "frame rate %d not supported\n",
- frame_rate);
- return -EINVAL;
- }
-
- /*
- * calculate the divider of mclk/sample_freq,
- * factor of freq =96k can only be 256, since mclk in range (12m,27m)
- */
- switch (sgtl5000->sysclk / sys_fs) {
- case 256:
- clk_ctl |= SGTL5000_MCLK_FREQ_256FS <<
- SGTL5000_MCLK_FREQ_SHIFT;
- break;
- case 384:
- clk_ctl |= SGTL5000_MCLK_FREQ_384FS <<
- SGTL5000_MCLK_FREQ_SHIFT;
- break;
- case 512:
- clk_ctl |= SGTL5000_MCLK_FREQ_512FS <<
- SGTL5000_MCLK_FREQ_SHIFT;
- break;
- default:
- /* if mclk not satisify the divider, use pll */
- if (sgtl5000->master) {
- clk_ctl |= SGTL5000_MCLK_FREQ_PLL <<
- SGTL5000_MCLK_FREQ_SHIFT;
- } else {
- dev_err(codec->dev,
- "PLL not supported in slave mode\n");
- return -EINVAL;
- }
- }
-
- /* if using pll, please check manual 6.4.2 for detail */
- if ((clk_ctl & SGTL5000_MCLK_FREQ_MASK) == SGTL5000_MCLK_FREQ_PLL) {
- u64 out, t;
- int div2;
- int pll_ctl;
- unsigned int in, int_div, frac_div;
-
- if (sgtl5000->sysclk > 17000000) {
- div2 = 1;
- in = sgtl5000->sysclk / 2;
- } else {
- div2 = 0;
- in = sgtl5000->sysclk;
- }
- if (sys_fs == 44100)
- out = 180633600;
- else
- out = 196608000;
- t = do_div(out, in);
- int_div = out;
- t *= 2048;
- do_div(t, in);
- frac_div = t;
- pll_ctl = int_div << SGTL5000_PLL_INT_DIV_SHIFT |
- frac_div << SGTL5000_PLL_FRAC_DIV_SHIFT;
-
- snd_soc_write(codec, SGTL5000_CHIP_PLL_CTRL, pll_ctl);
- if (div2)
- snd_soc_update_bits(codec,
- SGTL5000_CHIP_CLK_TOP_CTRL,
- SGTL5000_INPUT_FREQ_DIV2,
- SGTL5000_INPUT_FREQ_DIV2);
- else
- snd_soc_update_bits(codec,
- SGTL5000_CHIP_CLK_TOP_CTRL,
- SGTL5000_INPUT_FREQ_DIV2,
- 0);
-
- /* power up pll */
- snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
- SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP,
- SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP);
- } else {
- /* power down pll */
- snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
- SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP,
- 0);
- }
-
- /* if using pll, clk_ctrl must be set after pll power up */
- snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
-
- return 0;
-}
-
-/*
- * Set PCM DAI bit size and sample rate.
- * input: params_rate, params_fmt
- */
-static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
- int channels = params_channels(params);
- int i2s_ctl = 0;
- int stereo;
- int ret;
-
- /* sysclk should already set */
- if (!sgtl5000->sysclk) {
- dev_err(codec->dev, "%s: set sysclk first!\n", __func__);
- return -EFAULT;
- }
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- stereo = SGTL5000_DAC_STEREO;
- else
- stereo = SGTL5000_ADC_STEREO;
-
- /* set mono to save power */
- snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER, stereo,
- channels == 1 ? 0 : stereo);
-
- /* set codec clock base on lrclk */
- ret = sgtl5000_set_clock(codec, params_rate(params));
- if (ret)
- return ret;
-
- /* set i2s data format */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- if (sgtl5000->fmt == SND_SOC_DAIFMT_RIGHT_J)
- return -EINVAL;
- i2s_ctl |= SGTL5000_I2S_DLEN_16 << SGTL5000_I2S_DLEN_SHIFT;
- i2s_ctl |= SGTL5000_I2S_SCLKFREQ_32FS <<
- SGTL5000_I2S_SCLKFREQ_SHIFT;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- i2s_ctl |= SGTL5000_I2S_DLEN_20 << SGTL5000_I2S_DLEN_SHIFT;
- i2s_ctl |= SGTL5000_I2S_SCLKFREQ_64FS <<
- SGTL5000_I2S_SCLKFREQ_SHIFT;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- i2s_ctl |= SGTL5000_I2S_DLEN_24 << SGTL5000_I2S_DLEN_SHIFT;
- i2s_ctl |= SGTL5000_I2S_SCLKFREQ_64FS <<
- SGTL5000_I2S_SCLKFREQ_SHIFT;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- if (sgtl5000->fmt == SND_SOC_DAIFMT_RIGHT_J)
- return -EINVAL;
- i2s_ctl |= SGTL5000_I2S_DLEN_32 << SGTL5000_I2S_DLEN_SHIFT;
- i2s_ctl |= SGTL5000_I2S_SCLKFREQ_64FS <<
- SGTL5000_I2S_SCLKFREQ_SHIFT;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, SGTL5000_CHIP_I2S_CTRL,
- SGTL5000_I2S_DLEN_MASK | SGTL5000_I2S_SCLKFREQ_MASK,
- i2s_ctl);
-
- return 0;
-}
-
-#ifdef CONFIG_REGULATOR
-static int ldo_regulator_is_enabled(struct regulator_dev *dev)
-{
- struct ldo_regulator *ldo = rdev_get_drvdata(dev);
-
- return ldo->enabled;
-}
-
-static int ldo_regulator_enable(struct regulator_dev *dev)
-{
- struct ldo_regulator *ldo = rdev_get_drvdata(dev);
- struct snd_soc_codec *codec = (struct snd_soc_codec *)ldo->codec_data;
- int reg;
-
- if (ldo_regulator_is_enabled(dev))
- return 0;
-
- /* set regulator value firstly */
- reg = (1600 - ldo->voltage / 1000) / 50;
- reg = clamp(reg, 0x0, 0xf);
-
- /* amend the voltage value, unit: uV */
- ldo->voltage = (1600 - reg * 50) * 1000;
-
- /* set voltage to register */
- snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
- SGTL5000_LINREG_VDDD_MASK, reg);
-
- snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
- SGTL5000_LINEREG_D_POWERUP,
- SGTL5000_LINEREG_D_POWERUP);
-
- /* when internal ldo enabled, simple digital power can be disabled */
- snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
- SGTL5000_LINREG_SIMPLE_POWERUP,
- 0);
-
- ldo->enabled = 1;
- return 0;
-}
-
-static int ldo_regulator_disable(struct regulator_dev *dev)
-{
- struct ldo_regulator *ldo = rdev_get_drvdata(dev);
- struct snd_soc_codec *codec = (struct snd_soc_codec *)ldo->codec_data;
-
- snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
- SGTL5000_LINEREG_D_POWERUP,
- 0);
-
- /* clear voltage info */
- snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
- SGTL5000_LINREG_VDDD_MASK, 0);
-
- ldo->enabled = 0;
-
- return 0;
-}
-
-static int ldo_regulator_get_voltage(struct regulator_dev *dev)
-{
- struct ldo_regulator *ldo = rdev_get_drvdata(dev);
-
- return ldo->voltage;
-}
-
-static struct regulator_ops ldo_regulator_ops = {
- .is_enabled = ldo_regulator_is_enabled,
- .enable = ldo_regulator_enable,
- .disable = ldo_regulator_disable,
- .get_voltage = ldo_regulator_get_voltage,
-};
-
-static int ldo_regulator_register(struct snd_soc_codec *codec,
- struct regulator_init_data *init_data,
- int voltage)
-{
- struct ldo_regulator *ldo;
- struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
-
- ldo = kzalloc(sizeof(struct ldo_regulator), GFP_KERNEL);
-
- if (!ldo) {
- dev_err(codec->dev, "failed to allocate ldo_regulator\n");
- return -ENOMEM;
- }
-
- ldo->desc.name = kstrdup(dev_name(codec->dev), GFP_KERNEL);
- if (!ldo->desc.name) {
- kfree(ldo);
- dev_err(codec->dev, "failed to allocate decs name memory\n");
- return -ENOMEM;
- }
-
- ldo->desc.type = REGULATOR_VOLTAGE;
- ldo->desc.owner = THIS_MODULE;
- ldo->desc.ops = &ldo_regulator_ops;
- ldo->desc.n_voltages = 1;
-
- ldo->codec_data = codec;
- ldo->voltage = voltage;
-
- ldo->dev = regulator_register(&ldo->desc, codec->dev,
- init_data, ldo, NULL);
- if (IS_ERR(ldo->dev)) {
- int ret = PTR_ERR(ldo->dev);
-
- dev_err(codec->dev, "failed to register regulator\n");
- kfree(ldo->desc.name);
- kfree(ldo);
-
- return ret;
- }
- sgtl5000->ldo = ldo;
-
- return 0;
-}
-
-static int ldo_regulator_remove(struct snd_soc_codec *codec)
-{
- struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
- struct ldo_regulator *ldo = sgtl5000->ldo;
-
- if (!ldo)
- return 0;
-
- regulator_unregister(ldo->dev);
- kfree(ldo->desc.name);
- kfree(ldo);
-
- return 0;
-}
-#else
-static int ldo_regulator_register(struct snd_soc_codec *codec,
- struct regulator_init_data *init_data,
- int voltage)
-{
- dev_err(codec->dev, "this setup needs regulator support in the kernel\n");
- return -EINVAL;
-}
-
-static int ldo_regulator_remove(struct snd_soc_codec *codec)
-{
- return 0;
-}
-#endif
-
-/*
- * set dac bias
- * common state changes:
- * startup:
- * off --> standby --> prepare --> on
- * standby --> prepare --> on
- *
- * stop:
- * on --> prepare --> standby
- */
-static int sgtl5000_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- int ret;
- struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = regulator_bulk_enable(
- ARRAY_SIZE(sgtl5000->supplies),
- sgtl5000->supplies);
- if (ret)
- return ret;
- udelay(10);
- }
-
- break;
- case SND_SOC_BIAS_OFF:
- regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
- sgtl5000->supplies);
- break;
- }
-
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define SGTL5000_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
- SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE |\
- SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops sgtl5000_ops = {
- .hw_params = sgtl5000_pcm_hw_params,
- .digital_mute = sgtl5000_digital_mute,
- .set_fmt = sgtl5000_set_dai_fmt,
- .set_sysclk = sgtl5000_set_dai_sysclk,
-};
-
-static struct snd_soc_dai_driver sgtl5000_dai = {
- .name = "sgtl5000",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- /*
- * only support 8~48K + 96K,
- * TODO modify hw_param to support more
- */
- .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_96000,
- .formats = SGTL5000_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_96000,
- .formats = SGTL5000_FORMATS,
- },
- .ops = &sgtl5000_ops,
- .symmetric_rates = 1,
-};
-
-static int sgtl5000_volatile_register(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- switch (reg) {
- case SGTL5000_CHIP_ID:
- case SGTL5000_CHIP_ADCDAC_CTRL:
- case SGTL5000_CHIP_ANA_STATUS:
- return 1;
- }
-
- return 0;
-}
-
-#ifdef CONFIG_SUSPEND
-static int sgtl5000_suspend(struct snd_soc_codec *codec)
-{
- sgtl5000_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-/*
- * restore all sgtl5000 registers,
- * since a big hole between dap and regular registers,
- * we will restore them respectively.
- */
-static int sgtl5000_restore_regs(struct snd_soc_codec *codec)
-{
- u16 *cache = codec->reg_cache;
- u16 reg;
-
- /* restore regular registers */
- for (reg = 0; reg <= SGTL5000_CHIP_SHORT_CTRL; reg += 2) {
-
- /* These regs should restore in particular order */
- if (reg == SGTL5000_CHIP_ANA_POWER ||
- reg == SGTL5000_CHIP_CLK_CTRL ||
- reg == SGTL5000_CHIP_LINREG_CTRL ||
- reg == SGTL5000_CHIP_LINE_OUT_CTRL ||
- reg == SGTL5000_CHIP_REF_CTRL)
- continue;
-
- snd_soc_write(codec, reg, cache[reg]);
- }
-
- /* restore dap registers */
- for (reg = SGTL5000_DAP_REG_OFFSET; reg < SGTL5000_MAX_REG_OFFSET; reg += 2)
- snd_soc_write(codec, reg, cache[reg]);
-
- /*
- * restore these regs according to the power setting sequence in
- * sgtl5000_set_power_regs() and clock setting sequence in
- * sgtl5000_set_clock().
- *
- * The order of restore is:
- * 1. SGTL5000_CHIP_CLK_CTRL MCLK_FREQ bits (1:0) should be restore after
- * SGTL5000_CHIP_ANA_POWER PLL bits set
- * 2. SGTL5000_CHIP_LINREG_CTRL should be set before
- * SGTL5000_CHIP_ANA_POWER LINREG_D restored
- * 3. SGTL5000_CHIP_REF_CTRL controls Analog Ground Voltage,
- * prefer to resotre it after SGTL5000_CHIP_ANA_POWER restored
- */
- snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL,
- cache[SGTL5000_CHIP_LINREG_CTRL]);
-
- snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER,
- cache[SGTL5000_CHIP_ANA_POWER]);
-
- snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL,
- cache[SGTL5000_CHIP_CLK_CTRL]);
-
- snd_soc_write(codec, SGTL5000_CHIP_REF_CTRL,
- cache[SGTL5000_CHIP_REF_CTRL]);
-
- snd_soc_write(codec, SGTL5000_CHIP_LINE_OUT_CTRL,
- cache[SGTL5000_CHIP_LINE_OUT_CTRL]);
- return 0;
-}
-
-static int sgtl5000_resume(struct snd_soc_codec *codec)
-{
- /* Bring the codec back up to standby to enable regulators */
- sgtl5000_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* Restore registers by cached in memory */
- sgtl5000_restore_regs(codec);
- return 0;
-}
-#else
-#define sgtl5000_suspend NULL
-#define sgtl5000_resume NULL
-#endif /* CONFIG_SUSPEND */
-
-/*
- * sgtl5000 has 3 internal power supplies:
- * 1. VAG, normally set to vdda/2
- * 2. chargepump, set to different value
- * according to voltage of vdda and vddio
- * 3. line out VAG, normally set to vddio/2
- *
- * and should be set according to:
- * 1. vddd provided by external or not
- * 2. vdda and vddio voltage value. > 3.1v or not
- * 3. chip revision >=0x11 or not. If >=0x11, not use external vddd.
- */
-static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
-{
- int vddd;
- int vdda;
- int vddio;
- u16 ana_pwr;
- u16 lreg_ctrl;
- int vag;
- struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
-
- vdda = regulator_get_voltage(sgtl5000->supplies[VDDA].consumer);
- vddio = regulator_get_voltage(sgtl5000->supplies[VDDIO].consumer);
- vddd = regulator_get_voltage(sgtl5000->supplies[VDDD].consumer);
-
- vdda = vdda / 1000;
- vddio = vddio / 1000;
- vddd = vddd / 1000;
-
- if (vdda <= 0 || vddio <= 0 || vddd < 0) {
- dev_err(codec->dev, "regulator voltage not set correctly\n");
-
- return -EINVAL;
- }
-
- /* according to datasheet, maximum voltage of supplies */
- if (vdda > 3600 || vddio > 3600 || vddd > 1980) {
- dev_err(codec->dev,
- "exceed max voltage vdda %dmV vddio %dmV vddd %dmV\n",
- vdda, vddio, vddd);
-
- return -EINVAL;
- }
-
- /* reset value */
- ana_pwr = snd_soc_read(codec, SGTL5000_CHIP_ANA_POWER);
- ana_pwr |= SGTL5000_DAC_STEREO |
- SGTL5000_ADC_STEREO |
- SGTL5000_REFTOP_POWERUP;
- lreg_ctrl = snd_soc_read(codec, SGTL5000_CHIP_LINREG_CTRL);
-
- if (vddio < 3100 && vdda < 3100) {
- /* enable internal oscillator used for charge pump */
- snd_soc_update_bits(codec, SGTL5000_CHIP_CLK_TOP_CTRL,
- SGTL5000_INT_OSC_EN,
- SGTL5000_INT_OSC_EN);
- /* Enable VDDC charge pump */
- ana_pwr |= SGTL5000_VDDC_CHRGPMP_POWERUP;
- } else if (vddio >= 3100 && vdda >= 3100) {
- /*
- * if vddio and vddd > 3.1v,
- * charge pump should be clean before set ana_pwr
- */
- snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
- SGTL5000_VDDC_CHRGPMP_POWERUP, 0);
-
- /* VDDC use VDDIO rail */
- lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD;
- lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO <<
- SGTL5000_VDDC_MAN_ASSN_SHIFT;
- }
-
- snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL, lreg_ctrl);
-
- snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER, ana_pwr);
-
- /* set voltage to register */
- snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
- SGTL5000_LINREG_VDDD_MASK, 0x8);
-
- /*
- * if vddd linear reg has been enabled,
- * simple digital supply should be clear to get
- * proper VDDD voltage.
- */
- if (ana_pwr & SGTL5000_LINEREG_D_POWERUP)
- snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
- SGTL5000_LINREG_SIMPLE_POWERUP,
- 0);
- else
- snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
- SGTL5000_LINREG_SIMPLE_POWERUP |
- SGTL5000_STARTUP_POWERUP,
- 0);
-
- /*
- * set ADC/DAC VAG to vdda / 2,
- * should stay in range (0.8v, 1.575v)
- */
- vag = vdda / 2;
- if (vag <= SGTL5000_ANA_GND_BASE)
- vag = 0;
- else if (vag >= SGTL5000_ANA_GND_BASE + SGTL5000_ANA_GND_STP *
- (SGTL5000_ANA_GND_MASK >> SGTL5000_ANA_GND_SHIFT))
- vag = SGTL5000_ANA_GND_MASK >> SGTL5000_ANA_GND_SHIFT;
- else
- vag = (vag - SGTL5000_ANA_GND_BASE) / SGTL5000_ANA_GND_STP;
-
- snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL,
- SGTL5000_ANA_GND_MASK, vag << SGTL5000_ANA_GND_SHIFT);
-
- /* set line out VAG to vddio / 2, in range (0.8v, 1.675v) */
- vag = vddio / 2;
- if (vag <= SGTL5000_LINE_OUT_GND_BASE)
- vag = 0;
- else if (vag >= SGTL5000_LINE_OUT_GND_BASE +
- SGTL5000_LINE_OUT_GND_STP * SGTL5000_LINE_OUT_GND_MAX)
- vag = SGTL5000_LINE_OUT_GND_MAX;
- else
- vag = (vag - SGTL5000_LINE_OUT_GND_BASE) /
- SGTL5000_LINE_OUT_GND_STP;
-
- snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_CTRL,
- SGTL5000_LINE_OUT_CURRENT_MASK |
- SGTL5000_LINE_OUT_GND_MASK,
- vag << SGTL5000_LINE_OUT_GND_SHIFT |
- SGTL5000_LINE_OUT_CURRENT_360u <<
- SGTL5000_LINE_OUT_CURRENT_SHIFT);
-
- return 0;
-}
-
-static int sgtl5000_replace_vddd_with_ldo(struct snd_soc_codec *codec)
-{
- struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- /* set internal ldo to 1.2v */
- ret = ldo_regulator_register(codec, &ldo_init_data, LDO_VOLTAGE);
- if (ret) {
- dev_err(codec->dev,
- "Failed to register vddd internal supplies: %d\n", ret);
- return ret;
- }
-
- sgtl5000->supplies[VDDD].supply = LDO_CONSUMER_NAME;
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies),
- sgtl5000->supplies);
-
- if (ret) {
- ldo_regulator_remove(codec);
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- return ret;
- }
-
- dev_info(codec->dev, "Using internal LDO instead of VDDD\n");
- return 0;
-}
-
-static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
-{
- u16 reg;
- int ret;
- int rev;
- int i;
- int external_vddd = 0;
- struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
-
- for (i = 0; i < ARRAY_SIZE(sgtl5000->supplies); i++)
- sgtl5000->supplies[i].supply = supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies),
- sgtl5000->supplies);
- if (!ret)
- external_vddd = 1;
- else {
- ret = sgtl5000_replace_vddd_with_ldo(codec);
- if (ret)
- return ret;
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies),
- sgtl5000->supplies);
- if (ret)
- goto err_regulator_free;
-
- /* wait for all power rails bring up */
- udelay(10);
-
- /* read chip information */
- reg = snd_soc_read(codec, SGTL5000_CHIP_ID);
- if (((reg & SGTL5000_PARTID_MASK) >> SGTL5000_PARTID_SHIFT) !=
- SGTL5000_PARTID_PART_ID) {
- dev_err(codec->dev,
- "Device with ID register %x is not a sgtl5000\n", reg);
- ret = -ENODEV;
- goto err_regulator_disable;
- }
-
- rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT;
- dev_info(codec->dev, "sgtl5000 revision 0x%x\n", rev);
-
- /*
- * workaround for revision 0x11 and later,
- * roll back to use internal LDO
- */
- if (external_vddd && rev >= 0x11) {
- /* disable all regulator first */
- regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
- sgtl5000->supplies);
- /* free VDDD regulator */
- regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
- sgtl5000->supplies);
-
- ret = sgtl5000_replace_vddd_with_ldo(codec);
- if (ret)
- return ret;
-
- ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies),
- sgtl5000->supplies);
- if (ret)
- goto err_regulator_free;
-
- /* wait for all power rails bring up */
- udelay(10);
- }
-
- return 0;
-
-err_regulator_disable:
- regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
- sgtl5000->supplies);
-err_regulator_free:
- regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
- sgtl5000->supplies);
- if (external_vddd)
- ldo_regulator_remove(codec);
- return ret;
-
-}
-
-static int sgtl5000_probe(struct snd_soc_codec *codec)
-{
- int ret;
- struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
-
- /* setup i2c data ops */
- ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- ret = sgtl5000_enable_regulators(codec);
- if (ret)
- return ret;
-
- /* power up sgtl5000 */
- ret = sgtl5000_set_power_regs(codec);
- if (ret)
- goto err;
-
- /* enable small pop, introduce 400ms delay in turning off */
- snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL,
- SGTL5000_SMALL_POP,
- SGTL5000_SMALL_POP);
-
- /* disable short cut detector */
- snd_soc_write(codec, SGTL5000_CHIP_SHORT_CTRL, 0);
-
- /*
- * set i2s as default input of sound switch
- * TODO: add sound switch to control and dapm widge.
- */
- snd_soc_write(codec, SGTL5000_CHIP_SSS_CTRL,
- SGTL5000_DAC_SEL_I2S_IN << SGTL5000_DAC_SEL_SHIFT);
- snd_soc_write(codec, SGTL5000_CHIP_DIG_POWER,
- SGTL5000_ADC_EN | SGTL5000_DAC_EN);
-
- /* enable dac volume ramp by default */
- snd_soc_write(codec, SGTL5000_CHIP_ADCDAC_CTRL,
- SGTL5000_DAC_VOL_RAMP_EN |
- SGTL5000_DAC_MUTE_RIGHT |
- SGTL5000_DAC_MUTE_LEFT);
-
- snd_soc_write(codec, SGTL5000_CHIP_PAD_STRENGTH, 0x015f);
-
- snd_soc_write(codec, SGTL5000_CHIP_ANA_CTRL,
- SGTL5000_HP_ZCD_EN |
- SGTL5000_ADC_ZCD_EN);
-
- snd_soc_write(codec, SGTL5000_CHIP_MIC_CTRL, 0);
-
- /*
- * disable DAP
- * TODO:
- * Enable DAP in kcontrol and dapm.
- */
- snd_soc_write(codec, SGTL5000_DAP_CTRL, 0);
-
- /* leading to standby state */
- ret = sgtl5000_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- if (ret)
- goto err;
-
- snd_soc_dapm_new_widgets(&codec->dapm);
-
- return 0;
-
-err:
- regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
- sgtl5000->supplies);
- regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
- sgtl5000->supplies);
- ldo_regulator_remove(codec);
-
- return ret;
-}
-
-static int sgtl5000_remove(struct snd_soc_codec *codec)
-{
- struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
-
- sgtl5000_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
- sgtl5000->supplies);
- regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
- sgtl5000->supplies);
- ldo_regulator_remove(codec);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver sgtl5000_driver = {
- .probe = sgtl5000_probe,
- .remove = sgtl5000_remove,
- .suspend = sgtl5000_suspend,
- .resume = sgtl5000_resume,
- .set_bias_level = sgtl5000_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(sgtl5000_regs),
- .reg_word_size = sizeof(u16),
- .reg_cache_step = 2,
- .reg_cache_default = sgtl5000_regs,
- .volatile_register = sgtl5000_volatile_register,
- .controls = sgtl5000_snd_controls,
- .num_controls = ARRAY_SIZE(sgtl5000_snd_controls),
- .dapm_widgets = sgtl5000_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(sgtl5000_dapm_widgets),
- .dapm_routes = sgtl5000_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes),
-};
-
-static __devinit int sgtl5000_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct sgtl5000_priv *sgtl5000;
- int ret;
-
- sgtl5000 = devm_kzalloc(&client->dev, sizeof(struct sgtl5000_priv),
- GFP_KERNEL);
- if (!sgtl5000)
- return -ENOMEM;
-
- i2c_set_clientdata(client, sgtl5000);
-
- ret = snd_soc_register_codec(&client->dev,
- &sgtl5000_driver, &sgtl5000_dai, 1);
- return ret;
-}
-
-static __devexit int sgtl5000_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
-
- return 0;
-}
-
-static const struct i2c_device_id sgtl5000_id[] = {
- {"sgtl5000", 0},
- {},
-};
-
-MODULE_DEVICE_TABLE(i2c, sgtl5000_id);
-
-static const struct of_device_id sgtl5000_dt_ids[] = {
- { .compatible = "fsl,sgtl5000", },
- { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, sgtl5000_dt_ids);
-
-static struct i2c_driver sgtl5000_i2c_driver = {
- .driver = {
- .name = "sgtl5000",
- .owner = THIS_MODULE,
- .of_match_table = sgtl5000_dt_ids,
- },
- .probe = sgtl5000_i2c_probe,
- .remove = __devexit_p(sgtl5000_i2c_remove),
- .id_table = sgtl5000_id,
-};
-
-static int __init sgtl5000_modinit(void)
-{
- return i2c_add_driver(&sgtl5000_i2c_driver);
-}
-module_init(sgtl5000_modinit);
-
-static void __exit sgtl5000_exit(void)
-{
- i2c_del_driver(&sgtl5000_i2c_driver);
-}
-module_exit(sgtl5000_exit);
-
-MODULE_DESCRIPTION("Freescale SGTL5000 ALSA SoC Codec Driver");
-MODULE_AUTHOR("Zeng Zhaoming <zengzm.kernel@gmail.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/sgtl5000.h b/ANDROID_3.4.5/sound/soc/codecs/sgtl5000.h
deleted file mode 100644
index 8a9f4353..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/sgtl5000.h
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * sgtl5000.h - SGTL5000 audio codec interface
- *
- * Copyright 2010-2011 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _SGTL5000_H
-#define _SGTL5000_H
-
-/*
- * Register values.
- */
-#define SGTL5000_CHIP_ID 0x0000
-#define SGTL5000_CHIP_DIG_POWER 0x0002
-#define SGTL5000_CHIP_CLK_CTRL 0x0004
-#define SGTL5000_CHIP_I2S_CTRL 0x0006
-#define SGTL5000_CHIP_SSS_CTRL 0x000a
-#define SGTL5000_CHIP_ADCDAC_CTRL 0x000e
-#define SGTL5000_CHIP_DAC_VOL 0x0010
-#define SGTL5000_CHIP_PAD_STRENGTH 0x0014
-#define SGTL5000_CHIP_ANA_ADC_CTRL 0x0020
-#define SGTL5000_CHIP_ANA_HP_CTRL 0x0022
-#define SGTL5000_CHIP_ANA_CTRL 0x0024
-#define SGTL5000_CHIP_LINREG_CTRL 0x0026
-#define SGTL5000_CHIP_REF_CTRL 0x0028
-#define SGTL5000_CHIP_MIC_CTRL 0x002a
-#define SGTL5000_CHIP_LINE_OUT_CTRL 0x002c
-#define SGTL5000_CHIP_LINE_OUT_VOL 0x002e
-#define SGTL5000_CHIP_ANA_POWER 0x0030
-#define SGTL5000_CHIP_PLL_CTRL 0x0032
-#define SGTL5000_CHIP_CLK_TOP_CTRL 0x0034
-#define SGTL5000_CHIP_ANA_STATUS 0x0036
-#define SGTL5000_CHIP_SHORT_CTRL 0x003c
-#define SGTL5000_CHIP_ANA_TEST2 0x003a
-#define SGTL5000_DAP_CTRL 0x0100
-#define SGTL5000_DAP_PEQ 0x0102
-#define SGTL5000_DAP_BASS_ENHANCE 0x0104
-#define SGTL5000_DAP_BASS_ENHANCE_CTRL 0x0106
-#define SGTL5000_DAP_AUDIO_EQ 0x0108
-#define SGTL5000_DAP_SURROUND 0x010a
-#define SGTL5000_DAP_FLT_COEF_ACCESS 0x010c
-#define SGTL5000_DAP_COEF_WR_B0_MSB 0x010e
-#define SGTL5000_DAP_COEF_WR_B0_LSB 0x0110
-#define SGTL5000_DAP_EQ_BASS_BAND0 0x0116
-#define SGTL5000_DAP_EQ_BASS_BAND1 0x0118
-#define SGTL5000_DAP_EQ_BASS_BAND2 0x011a
-#define SGTL5000_DAP_EQ_BASS_BAND3 0x011c
-#define SGTL5000_DAP_EQ_BASS_BAND4 0x011e
-#define SGTL5000_DAP_MAIN_CHAN 0x0120
-#define SGTL5000_DAP_MIX_CHAN 0x0122
-#define SGTL5000_DAP_AVC_CTRL 0x0124
-#define SGTL5000_DAP_AVC_THRESHOLD 0x0126
-#define SGTL5000_DAP_AVC_ATTACK 0x0128
-#define SGTL5000_DAP_AVC_DECAY 0x012a
-#define SGTL5000_DAP_COEF_WR_B1_MSB 0x012c
-#define SGTL5000_DAP_COEF_WR_B1_LSB 0x012e
-#define SGTL5000_DAP_COEF_WR_B2_MSB 0x0130
-#define SGTL5000_DAP_COEF_WR_B2_LSB 0x0132
-#define SGTL5000_DAP_COEF_WR_A1_MSB 0x0134
-#define SGTL5000_DAP_COEF_WR_A1_LSB 0x0136
-#define SGTL5000_DAP_COEF_WR_A2_MSB 0x0138
-#define SGTL5000_DAP_COEF_WR_A2_LSB 0x013a
-
-/*
- * Field Definitions.
- */
-
-/*
- * SGTL5000_CHIP_ID
- */
-#define SGTL5000_PARTID_MASK 0xff00
-#define SGTL5000_PARTID_SHIFT 8
-#define SGTL5000_PARTID_WIDTH 8
-#define SGTL5000_PARTID_PART_ID 0xa0
-#define SGTL5000_REVID_MASK 0x00ff
-#define SGTL5000_REVID_SHIFT 0
-#define SGTL5000_REVID_WIDTH 8
-
-/*
- * SGTL5000_CHIP_DIG_POWER
- */
-#define SGTL5000_ADC_EN 0x0040
-#define SGTL5000_DAC_EN 0x0020
-#define SGTL5000_DAP_POWERUP 0x0010
-#define SGTL5000_I2S_OUT_POWERUP 0x0002
-#define SGTL5000_I2S_IN_POWERUP 0x0001
-
-/*
- * SGTL5000_CHIP_CLK_CTRL
- */
-#define SGTL5000_RATE_MODE_MASK 0x0030
-#define SGTL5000_RATE_MODE_SHIFT 4
-#define SGTL5000_RATE_MODE_WIDTH 2
-#define SGTL5000_RATE_MODE_DIV_1 0
-#define SGTL5000_RATE_MODE_DIV_2 1
-#define SGTL5000_RATE_MODE_DIV_4 2
-#define SGTL5000_RATE_MODE_DIV_6 3
-#define SGTL5000_SYS_FS_MASK 0x000c
-#define SGTL5000_SYS_FS_SHIFT 2
-#define SGTL5000_SYS_FS_WIDTH 2
-#define SGTL5000_SYS_FS_32k 0x0
-#define SGTL5000_SYS_FS_44_1k 0x1
-#define SGTL5000_SYS_FS_48k 0x2
-#define SGTL5000_SYS_FS_96k 0x3
-#define SGTL5000_MCLK_FREQ_MASK 0x0003
-#define SGTL5000_MCLK_FREQ_SHIFT 0
-#define SGTL5000_MCLK_FREQ_WIDTH 2
-#define SGTL5000_MCLK_FREQ_256FS 0x0
-#define SGTL5000_MCLK_FREQ_384FS 0x1
-#define SGTL5000_MCLK_FREQ_512FS 0x2
-#define SGTL5000_MCLK_FREQ_PLL 0x3
-
-/*
- * SGTL5000_CHIP_I2S_CTRL
- */
-#define SGTL5000_I2S_SCLKFREQ_MASK 0x0100
-#define SGTL5000_I2S_SCLKFREQ_SHIFT 8
-#define SGTL5000_I2S_SCLKFREQ_WIDTH 1
-#define SGTL5000_I2S_SCLKFREQ_64FS 0x0
-#define SGTL5000_I2S_SCLKFREQ_32FS 0x1 /* Not for RJ mode */
-#define SGTL5000_I2S_MASTER 0x0080
-#define SGTL5000_I2S_SCLK_INV 0x0040
-#define SGTL5000_I2S_DLEN_MASK 0x0030
-#define SGTL5000_I2S_DLEN_SHIFT 4
-#define SGTL5000_I2S_DLEN_WIDTH 2
-#define SGTL5000_I2S_DLEN_32 0x0
-#define SGTL5000_I2S_DLEN_24 0x1
-#define SGTL5000_I2S_DLEN_20 0x2
-#define SGTL5000_I2S_DLEN_16 0x3
-#define SGTL5000_I2S_MODE_MASK 0x000c
-#define SGTL5000_I2S_MODE_SHIFT 2
-#define SGTL5000_I2S_MODE_WIDTH 2
-#define SGTL5000_I2S_MODE_I2S_LJ 0x0
-#define SGTL5000_I2S_MODE_RJ 0x1
-#define SGTL5000_I2S_MODE_PCM 0x2
-#define SGTL5000_I2S_LRALIGN 0x0002
-#define SGTL5000_I2S_LRPOL 0x0001 /* set for which mode */
-
-/*
- * SGTL5000_CHIP_SSS_CTRL
- */
-#define SGTL5000_DAP_MIX_LRSWAP 0x4000
-#define SGTL5000_DAP_LRSWAP 0x2000
-#define SGTL5000_DAC_LRSWAP 0x1000
-#define SGTL5000_I2S_OUT_LRSWAP 0x0400
-#define SGTL5000_DAP_MIX_SEL_MASK 0x0300
-#define SGTL5000_DAP_MIX_SEL_SHIFT 8
-#define SGTL5000_DAP_MIX_SEL_WIDTH 2
-#define SGTL5000_DAP_MIX_SEL_ADC 0x0
-#define SGTL5000_DAP_MIX_SEL_I2S_IN 0x1
-#define SGTL5000_DAP_SEL_MASK 0x00c0
-#define SGTL5000_DAP_SEL_SHIFT 6
-#define SGTL5000_DAP_SEL_WIDTH 2
-#define SGTL5000_DAP_SEL_ADC 0x0
-#define SGTL5000_DAP_SEL_I2S_IN 0x1
-#define SGTL5000_DAC_SEL_MASK 0x0030
-#define SGTL5000_DAC_SEL_SHIFT 4
-#define SGTL5000_DAC_SEL_WIDTH 2
-#define SGTL5000_DAC_SEL_ADC 0x0
-#define SGTL5000_DAC_SEL_I2S_IN 0x1
-#define SGTL5000_DAC_SEL_DAP 0x3
-#define SGTL5000_I2S_OUT_SEL_MASK 0x0003
-#define SGTL5000_I2S_OUT_SEL_SHIFT 0
-#define SGTL5000_I2S_OUT_SEL_WIDTH 2
-#define SGTL5000_I2S_OUT_SEL_ADC 0x0
-#define SGTL5000_I2S_OUT_SEL_I2S_IN 0x1
-#define SGTL5000_I2S_OUT_SEL_DAP 0x3
-
-/*
- * SGTL5000_CHIP_ADCDAC_CTRL
- */
-#define SGTL5000_VOL_BUSY_DAC_RIGHT 0x2000
-#define SGTL5000_VOL_BUSY_DAC_LEFT 0x1000
-#define SGTL5000_DAC_VOL_RAMP_EN 0x0200
-#define SGTL5000_DAC_VOL_RAMP_EXPO 0x0100
-#define SGTL5000_DAC_MUTE_RIGHT 0x0008
-#define SGTL5000_DAC_MUTE_LEFT 0x0004
-#define SGTL5000_ADC_HPF_FREEZE 0x0002
-#define SGTL5000_ADC_HPF_BYPASS 0x0001
-
-/*
- * SGTL5000_CHIP_DAC_VOL
- */
-#define SGTL5000_DAC_VOL_RIGHT_MASK 0xff00
-#define SGTL5000_DAC_VOL_RIGHT_SHIFT 8
-#define SGTL5000_DAC_VOL_RIGHT_WIDTH 8
-#define SGTL5000_DAC_VOL_LEFT_MASK 0x00ff
-#define SGTL5000_DAC_VOL_LEFT_SHIFT 0
-#define SGTL5000_DAC_VOL_LEFT_WIDTH 8
-
-/*
- * SGTL5000_CHIP_PAD_STRENGTH
- */
-#define SGTL5000_PAD_I2S_LRCLK_MASK 0x0300
-#define SGTL5000_PAD_I2S_LRCLK_SHIFT 8
-#define SGTL5000_PAD_I2S_LRCLK_WIDTH 2
-#define SGTL5000_PAD_I2S_SCLK_MASK 0x00c0
-#define SGTL5000_PAD_I2S_SCLK_SHIFT 6
-#define SGTL5000_PAD_I2S_SCLK_WIDTH 2
-#define SGTL5000_PAD_I2S_DOUT_MASK 0x0030
-#define SGTL5000_PAD_I2S_DOUT_SHIFT 4
-#define SGTL5000_PAD_I2S_DOUT_WIDTH 2
-#define SGTL5000_PAD_I2C_SDA_MASK 0x000c
-#define SGTL5000_PAD_I2C_SDA_SHIFT 2
-#define SGTL5000_PAD_I2C_SDA_WIDTH 2
-#define SGTL5000_PAD_I2C_SCL_MASK 0x0003
-#define SGTL5000_PAD_I2C_SCL_SHIFT 0
-#define SGTL5000_PAD_I2C_SCL_WIDTH 2
-
-/*
- * SGTL5000_CHIP_ANA_ADC_CTRL
- */
-#define SGTL5000_ADC_VOL_M6DB 0x0100
-#define SGTL5000_ADC_VOL_RIGHT_MASK 0x00f0
-#define SGTL5000_ADC_VOL_RIGHT_SHIFT 4
-#define SGTL5000_ADC_VOL_RIGHT_WIDTH 4
-#define SGTL5000_ADC_VOL_LEFT_MASK 0x000f
-#define SGTL5000_ADC_VOL_LEFT_SHIFT 0
-#define SGTL5000_ADC_VOL_LEFT_WIDTH 4
-
-/*
- * SGTL5000_CHIP_ANA_HP_CTRL
- */
-#define SGTL5000_HP_VOL_RIGHT_MASK 0x7f00
-#define SGTL5000_HP_VOL_RIGHT_SHIFT 8
-#define SGTL5000_HP_VOL_RIGHT_WIDTH 7
-#define SGTL5000_HP_VOL_LEFT_MASK 0x007f
-#define SGTL5000_HP_VOL_LEFT_SHIFT 0
-#define SGTL5000_HP_VOL_LEFT_WIDTH 7
-
-/*
- * SGTL5000_CHIP_ANA_CTRL
- */
-#define SGTL5000_LINE_OUT_MUTE 0x0100
-#define SGTL5000_HP_SEL_MASK 0x0040
-#define SGTL5000_HP_SEL_SHIFT 6
-#define SGTL5000_HP_SEL_WIDTH 1
-#define SGTL5000_HP_SEL_DAC 0x0
-#define SGTL5000_HP_SEL_LINE_IN 0x1
-#define SGTL5000_HP_ZCD_EN 0x0020
-#define SGTL5000_HP_MUTE 0x0010
-#define SGTL5000_ADC_SEL_MASK 0x0004
-#define SGTL5000_ADC_SEL_SHIFT 2
-#define SGTL5000_ADC_SEL_WIDTH 1
-#define SGTL5000_ADC_SEL_MIC 0x0
-#define SGTL5000_ADC_SEL_LINE_IN 0x1
-#define SGTL5000_ADC_ZCD_EN 0x0002
-#define SGTL5000_ADC_MUTE 0x0001
-
-/*
- * SGTL5000_CHIP_LINREG_CTRL
- */
-#define SGTL5000_VDDC_MAN_ASSN_MASK 0x0040
-#define SGTL5000_VDDC_MAN_ASSN_SHIFT 6
-#define SGTL5000_VDDC_MAN_ASSN_WIDTH 1
-#define SGTL5000_VDDC_MAN_ASSN_VDDA 0x0
-#define SGTL5000_VDDC_MAN_ASSN_VDDIO 0x1
-#define SGTL5000_VDDC_ASSN_OVRD 0x0020
-#define SGTL5000_LINREG_VDDD_MASK 0x000f
-#define SGTL5000_LINREG_VDDD_SHIFT 0
-#define SGTL5000_LINREG_VDDD_WIDTH 4
-
-/*
- * SGTL5000_CHIP_REF_CTRL
- */
-#define SGTL5000_ANA_GND_MASK 0x01f0
-#define SGTL5000_ANA_GND_SHIFT 4
-#define SGTL5000_ANA_GND_WIDTH 5
-#define SGTL5000_ANA_GND_BASE 800 /* mv */
-#define SGTL5000_ANA_GND_STP 25 /*mv */
-#define SGTL5000_BIAS_CTRL_MASK 0x000e
-#define SGTL5000_BIAS_CTRL_SHIFT 1
-#define SGTL5000_BIAS_CTRL_WIDTH 3
-#define SGTL5000_SMALL_POP 0x0001
-
-/*
- * SGTL5000_CHIP_MIC_CTRL
- */
-#define SGTL5000_BIAS_R_MASK 0x0300
-#define SGTL5000_BIAS_R_SHIFT 8
-#define SGTL5000_BIAS_R_WIDTH 2
-#define SGTL5000_BIAS_R_off 0x0
-#define SGTL5000_BIAS_R_2K 0x1
-#define SGTL5000_BIAS_R_4k 0x2
-#define SGTL5000_BIAS_R_8k 0x3
-#define SGTL5000_BIAS_VOLT_MASK 0x0070
-#define SGTL5000_BIAS_VOLT_SHIFT 4
-#define SGTL5000_BIAS_VOLT_WIDTH 3
-#define SGTL5000_MIC_GAIN_MASK 0x0003
-#define SGTL5000_MIC_GAIN_SHIFT 0
-#define SGTL5000_MIC_GAIN_WIDTH 2
-
-/*
- * SGTL5000_CHIP_LINE_OUT_CTRL
- */
-#define SGTL5000_LINE_OUT_CURRENT_MASK 0x0f00
-#define SGTL5000_LINE_OUT_CURRENT_SHIFT 8
-#define SGTL5000_LINE_OUT_CURRENT_WIDTH 4
-#define SGTL5000_LINE_OUT_CURRENT_180u 0x0
-#define SGTL5000_LINE_OUT_CURRENT_270u 0x1
-#define SGTL5000_LINE_OUT_CURRENT_360u 0x3
-#define SGTL5000_LINE_OUT_CURRENT_450u 0x7
-#define SGTL5000_LINE_OUT_CURRENT_540u 0xf
-#define SGTL5000_LINE_OUT_GND_MASK 0x003f
-#define SGTL5000_LINE_OUT_GND_SHIFT 0
-#define SGTL5000_LINE_OUT_GND_WIDTH 6
-#define SGTL5000_LINE_OUT_GND_BASE 800 /* mv */
-#define SGTL5000_LINE_OUT_GND_STP 25
-#define SGTL5000_LINE_OUT_GND_MAX 0x23
-
-/*
- * SGTL5000_CHIP_LINE_OUT_VOL
- */
-#define SGTL5000_LINE_OUT_VOL_RIGHT_MASK 0x1f00
-#define SGTL5000_LINE_OUT_VOL_RIGHT_SHIFT 8
-#define SGTL5000_LINE_OUT_VOL_RIGHT_WIDTH 5
-#define SGTL5000_LINE_OUT_VOL_LEFT_MASK 0x001f
-#define SGTL5000_LINE_OUT_VOL_LEFT_SHIFT 0
-#define SGTL5000_LINE_OUT_VOL_LEFT_WIDTH 5
-
-/*
- * SGTL5000_CHIP_ANA_POWER
- */
-#define SGTL5000_DAC_STEREO 0x4000
-#define SGTL5000_LINREG_SIMPLE_POWERUP 0x2000
-#define SGTL5000_STARTUP_POWERUP 0x1000
-#define SGTL5000_VDDC_CHRGPMP_POWERUP 0x0800
-#define SGTL5000_PLL_POWERUP 0x0400
-#define SGTL5000_LINEREG_D_POWERUP 0x0200
-#define SGTL5000_VCOAMP_POWERUP 0x0100
-#define SGTL5000_VAG_POWERUP 0x0080
-#define SGTL5000_ADC_STEREO 0x0040
-#define SGTL5000_REFTOP_POWERUP 0x0020
-#define SGTL5000_HP_POWERUP 0x0010
-#define SGTL5000_DAC_POWERUP 0x0008
-#define SGTL5000_CAPLESS_HP_POWERUP 0x0004
-#define SGTL5000_ADC_POWERUP 0x0002
-#define SGTL5000_LINE_OUT_POWERUP 0x0001
-
-/*
- * SGTL5000_CHIP_PLL_CTRL
- */
-#define SGTL5000_PLL_INT_DIV_MASK 0xf800
-#define SGTL5000_PLL_INT_DIV_SHIFT 11
-#define SGTL5000_PLL_INT_DIV_WIDTH 5
-#define SGTL5000_PLL_FRAC_DIV_MASK 0x0700
-#define SGTL5000_PLL_FRAC_DIV_SHIFT 0
-#define SGTL5000_PLL_FRAC_DIV_WIDTH 11
-
-/*
- * SGTL5000_CHIP_CLK_TOP_CTRL
- */
-#define SGTL5000_INT_OSC_EN 0x0800
-#define SGTL5000_INPUT_FREQ_DIV2 0x0008
-
-/*
- * SGTL5000_CHIP_ANA_STATUS
- */
-#define SGTL5000_HP_LRSHORT 0x0200
-#define SGTL5000_CAPLESS_SHORT 0x0100
-#define SGTL5000_PLL_LOCKED 0x0010
-
-/*
- * SGTL5000_CHIP_SHORT_CTRL
- */
-#define SGTL5000_LVLADJR_MASK 0x7000
-#define SGTL5000_LVLADJR_SHIFT 12
-#define SGTL5000_LVLADJR_WIDTH 3
-#define SGTL5000_LVLADJL_MASK 0x0700
-#define SGTL5000_LVLADJL_SHIFT 8
-#define SGTL5000_LVLADJL_WIDTH 3
-#define SGTL5000_LVLADJC_MASK 0x0070
-#define SGTL5000_LVLADJC_SHIFT 4
-#define SGTL5000_LVLADJC_WIDTH 3
-#define SGTL5000_LR_SHORT_MOD_MASK 0x000c
-#define SGTL5000_LR_SHORT_MOD_SHIFT 2
-#define SGTL5000_LR_SHORT_MOD_WIDTH 2
-#define SGTL5000_CM_SHORT_MOD_MASK 0x0003
-#define SGTL5000_CM_SHORT_MOD_SHIFT 0
-#define SGTL5000_CM_SHORT_MOD_WIDTH 2
-
-/*
- *SGTL5000_CHIP_ANA_TEST2
- */
-#define SGTL5000_MONO_DAC 0x1000
-
-/*
- * SGTL5000_DAP_CTRL
- */
-#define SGTL5000_DAP_MIX_EN 0x0010
-#define SGTL5000_DAP_EN 0x0001
-
-#define SGTL5000_SYSCLK 0x00
-#define SGTL5000_LRCLK 0x01
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/sigmadsp.c b/ANDROID_3.4.5/sound/soc/codecs/sigmadsp.c
deleted file mode 100644
index 5be42bf5..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/sigmadsp.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Load Analog Devices SigmaStudio firmware files
- *
- * Copyright 2009-2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/crc32.h>
-#include <linux/delay.h>
-#include <linux/firmware.h>
-#include <linux/kernel.h>
-#include <linux/i2c.h>
-#include <linux/regmap.h>
-#include <linux/module.h>
-
-#include "sigmadsp.h"
-
-#define SIGMA_MAGIC "ADISIGM"
-
-struct sigma_firmware_header {
- unsigned char magic[7];
- u8 version;
- __le32 crc;
-} __packed;
-
-enum {
- SIGMA_ACTION_WRITEXBYTES = 0,
- SIGMA_ACTION_WRITESINGLE,
- SIGMA_ACTION_WRITESAFELOAD,
- SIGMA_ACTION_DELAY,
- SIGMA_ACTION_PLLWAIT,
- SIGMA_ACTION_NOOP,
- SIGMA_ACTION_END,
-};
-
-struct sigma_action {
- u8 instr;
- u8 len_hi;
- __le16 len;
- __be16 addr;
- unsigned char payload[];
-} __packed;
-
-struct sigma_firmware {
- const struct firmware *fw;
- size_t pos;
-
- void *control_data;
- int (*write)(void *control_data, const struct sigma_action *sa,
- size_t len);
-};
-
-static inline u32 sigma_action_len(struct sigma_action *sa)
-{
- return (sa->len_hi << 16) | le16_to_cpu(sa->len);
-}
-
-static size_t sigma_action_size(struct sigma_action *sa)
-{
- size_t payload = 0;
-
- switch (sa->instr) {
- case SIGMA_ACTION_WRITEXBYTES:
- case SIGMA_ACTION_WRITESINGLE:
- case SIGMA_ACTION_WRITESAFELOAD:
- payload = sigma_action_len(sa);
- break;
- default:
- break;
- }
-
- payload = ALIGN(payload, 2);
-
- return payload + sizeof(struct sigma_action);
-}
-
-/*
- * Returns a negative error value in case of an error, 0 if processing of
- * the firmware should be stopped after this action, 1 otherwise.
- */
-static int
-process_sigma_action(struct sigma_firmware *ssfw, struct sigma_action *sa)
-{
- size_t len = sigma_action_len(sa);
- int ret;
-
- pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__,
- sa->instr, sa->addr, len);
-
- switch (sa->instr) {
- case SIGMA_ACTION_WRITEXBYTES:
- case SIGMA_ACTION_WRITESINGLE:
- case SIGMA_ACTION_WRITESAFELOAD:
- ret = ssfw->write(ssfw->control_data, sa, len);
- if (ret < 0)
- return -EINVAL;
- break;
- case SIGMA_ACTION_DELAY:
- udelay(len);
- len = 0;
- break;
- case SIGMA_ACTION_END:
- return 0;
- default:
- return -EINVAL;
- }
-
- return 1;
-}
-
-static int
-process_sigma_actions(struct sigma_firmware *ssfw)
-{
- struct sigma_action *sa;
- size_t size;
- int ret;
-
- while (ssfw->pos + sizeof(*sa) <= ssfw->fw->size) {
- sa = (struct sigma_action *)(ssfw->fw->data + ssfw->pos);
-
- size = sigma_action_size(sa);
- ssfw->pos += size;
- if (ssfw->pos > ssfw->fw->size || size == 0)
- break;
-
- ret = process_sigma_action(ssfw, sa);
-
- pr_debug("%s: action returned %i\n", __func__, ret);
-
- if (ret <= 0)
- return ret;
- }
-
- if (ssfw->pos != ssfw->fw->size)
- return -EINVAL;
-
- return 0;
-}
-
-static int _process_sigma_firmware(struct device *dev,
- struct sigma_firmware *ssfw, const char *name)
-{
- int ret;
- struct sigma_firmware_header *ssfw_head;
- const struct firmware *fw;
- u32 crc;
-
- pr_debug("%s: loading firmware %s\n", __func__, name);
-
- /* first load the blob */
- ret = request_firmware(&fw, name, dev);
- if (ret) {
- pr_debug("%s: request_firmware() failed with %i\n", __func__, ret);
- return ret;
- }
- ssfw->fw = fw;
-
- /* then verify the header */
- ret = -EINVAL;
-
- /*
- * Reject too small or unreasonable large files. The upper limit has been
- * chosen a bit arbitrarily, but it should be enough for all practical
- * purposes and having the limit makes it easier to avoid integer
- * overflows later in the loading process.
- */
- if (fw->size < sizeof(*ssfw_head) || fw->size >= 0x4000000) {
- dev_err(dev, "Failed to load firmware: Invalid size\n");
- goto done;
- }
-
- ssfw_head = (void *)fw->data;
- if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic))) {
- dev_err(dev, "Failed to load firmware: Invalid magic\n");
- goto done;
- }
-
- crc = crc32(0, fw->data + sizeof(*ssfw_head),
- fw->size - sizeof(*ssfw_head));
- pr_debug("%s: crc=%x\n", __func__, crc);
- if (crc != le32_to_cpu(ssfw_head->crc)) {
- dev_err(dev, "Failed to load firmware: Wrong crc checksum: expected %x got %x\n",
- le32_to_cpu(ssfw_head->crc), crc);
- goto done;
- }
-
- ssfw->pos = sizeof(*ssfw_head);
-
- /* finally process all of the actions */
- ret = process_sigma_actions(ssfw);
-
- done:
- release_firmware(fw);
-
- pr_debug("%s: loaded %s\n", __func__, name);
-
- return ret;
-}
-
-#if IS_ENABLED(CONFIG_I2C)
-
-static int sigma_action_write_i2c(void *control_data,
- const struct sigma_action *sa, size_t len)
-{
- return i2c_master_send(control_data, (const unsigned char *)&sa->addr,
- len);
-}
-
-int process_sigma_firmware(struct i2c_client *client, const char *name)
-{
- struct sigma_firmware ssfw;
-
- ssfw.control_data = client;
- ssfw.write = sigma_action_write_i2c;
-
- return _process_sigma_firmware(&client->dev, &ssfw, name);
-}
-EXPORT_SYMBOL(process_sigma_firmware);
-
-#endif
-
-#if IS_ENABLED(CONFIG_REGMAP)
-
-static int sigma_action_write_regmap(void *control_data,
- const struct sigma_action *sa, size_t len)
-{
- return regmap_raw_write(control_data, le16_to_cpu(sa->addr),
- sa->payload, len - 2);
-}
-
-int process_sigma_firmware_regmap(struct device *dev, struct regmap *regmap,
- const char *name)
-{
- struct sigma_firmware ssfw;
-
- ssfw.control_data = regmap;
- ssfw.write = sigma_action_write_regmap;
-
- return _process_sigma_firmware(dev, &ssfw, name);
-}
-EXPORT_SYMBOL(process_sigma_firmware_regmap);
-
-#endif
-
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/sigmadsp.h b/ANDROID_3.4.5/sound/soc/codecs/sigmadsp.h
deleted file mode 100644
index e439cbd7..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/sigmadsp.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Load firmware files from Analog Devices SigmaStudio
- *
- * Copyright 2009-2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#ifndef __SIGMA_FIRMWARE_H__
-#define __SIGMA_FIRMWARE_H__
-
-#include <linux/device.h>
-#include <linux/regmap.h>
-
-struct i2c_client;
-
-extern int process_sigma_firmware(struct i2c_client *client, const char *name);
-extern int process_sigma_firmware_regmap(struct device *dev,
- struct regmap *regmap, const char *name);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/sn95031.c b/ANDROID_3.4.5/sound/soc/codecs/sn95031.c
deleted file mode 100644
index 50dbdb93..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/sn95031.c
+++ /dev/null
@@ -1,928 +0,0 @@
-/*
- * sn95031.c - TI sn95031 Codec driver
- *
- * Copyright (C) 2010 Intel Corp
- * Author: Vinod Koul <vinod.koul@intel.com>
- * Author: Harsha Priya <priya.harsha@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *
- */
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-#include <asm/intel_scu_ipc.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <sound/jack.h>
-#include "sn95031.h"
-
-#define SN95031_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100)
-#define SN95031_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
-
-/* adc helper functions */
-
-/* enables mic bias voltage */
-static void sn95031_enable_mic_bias(struct snd_soc_codec *codec)
-{
- snd_soc_write(codec, SN95031_VAUD, BIT(2)|BIT(1)|BIT(0));
- snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(2), BIT(2));
-}
-
-/* Enable/Disable the ADC depending on the argument */
-static void configure_adc(struct snd_soc_codec *sn95031_codec, int val)
-{
- int value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1);
-
- if (val) {
- /* Enable and start the ADC */
- value |= (SN95031_ADC_ENBL | SN95031_ADC_START);
- value &= (~SN95031_ADC_NO_LOOP);
- } else {
- /* Just stop the ADC */
- value &= (~SN95031_ADC_START);
- }
- snd_soc_write(sn95031_codec, SN95031_ADC1CNTL1, value);
-}
-
-/*
- * finds an empty channel for conversion
- * If the ADC is not enabled then start using 0th channel
- * itself. Otherwise find an empty channel by looking for a
- * channel in which the stopbit is set to 1. returns the index
- * of the first free channel if succeeds or an error code.
- *
- * Context: can sleep
- *
- */
-static int find_free_channel(struct snd_soc_codec *sn95031_codec)
-{
- int i, value;
-
- /* check whether ADC is enabled */
- value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1);
-
- if ((value & SN95031_ADC_ENBL) == 0)
- return 0;
-
- /* ADC is already enabled; Looking for an empty channel */
- for (i = 0; i < SN95031_ADC_CHANLS_MAX; i++) {
- value = snd_soc_read(sn95031_codec,
- SN95031_ADC_CHNL_START_ADDR + i);
- if (value & SN95031_STOPBIT_MASK)
- break;
- }
- return (i == SN95031_ADC_CHANLS_MAX) ? (-EINVAL) : i;
-}
-
-/* Initialize the ADC for reading micbias values. Can sleep. */
-static int sn95031_initialize_adc(struct snd_soc_codec *sn95031_codec)
-{
- int base_addr, chnl_addr;
- int value;
- int channel_index;
-
- /* Index of the first channel in which the stop bit is set */
- channel_index = find_free_channel(sn95031_codec);
- if (channel_index < 0) {
- pr_err("No free ADC channels");
- return channel_index;
- }
-
- base_addr = SN95031_ADC_CHNL_START_ADDR + channel_index;
-
- if (!(channel_index == 0 || channel_index == SN95031_ADC_LOOP_MAX)) {
- /* Reset stop bit for channels other than 0 and 12 */
- value = snd_soc_read(sn95031_codec, base_addr);
- /* Set the stop bit to zero */
- snd_soc_write(sn95031_codec, base_addr, value & 0xEF);
- /* Index of the first free channel */
- base_addr++;
- channel_index++;
- }
-
- /* Since this is the last channel, set the stop bit
- to 1 by ORing the DIE_SENSOR_CODE with 0x10 */
- snd_soc_write(sn95031_codec, base_addr,
- SN95031_AUDIO_DETECT_CODE | 0x10);
-
- chnl_addr = SN95031_ADC_DATA_START_ADDR + 2 * channel_index;
- pr_debug("mid_initialize : %x", chnl_addr);
- configure_adc(sn95031_codec, 1);
- return chnl_addr;
-}
-
-
-/* reads the ADC registers and gets the mic bias value in mV. */
-static unsigned int sn95031_get_mic_bias(struct snd_soc_codec *codec)
-{
- u16 adc_adr = sn95031_initialize_adc(codec);
- u16 adc_val1, adc_val2;
- unsigned int mic_bias;
-
- sn95031_enable_mic_bias(codec);
-
- /* Enable the sound card for conversion before reading */
- snd_soc_write(codec, SN95031_ADC1CNTL3, 0x05);
- /* Re-toggle the RRDATARD bit */
- snd_soc_write(codec, SN95031_ADC1CNTL3, 0x04);
-
- /* Read the higher bits of data */
- msleep(1000);
- adc_val1 = snd_soc_read(codec, adc_adr);
- adc_adr++;
- adc_val2 = snd_soc_read(codec, adc_adr);
-
- /* Adding lower two bits to the higher bits */
- mic_bias = (adc_val1 << 2) + (adc_val2 & 3);
- mic_bias = (mic_bias * SN95031_ADC_ONE_LSB_MULTIPLIER) / 1000;
- pr_debug("mic bias = %dmV\n", mic_bias);
- return mic_bias;
-}
-/*end - adc helper functions */
-
-static inline unsigned int sn95031_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- u8 value = 0;
- int ret;
-
- ret = intel_scu_ipc_ioread8(reg, &value);
- if (ret)
- pr_err("read of %x failed, err %d\n", reg, ret);
- return value;
-
-}
-
-static inline int sn95031_write(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int value)
-{
- int ret;
-
- ret = intel_scu_ipc_iowrite8(reg, value);
- if (ret)
- pr_err("write of %x failed, err %d\n", reg, ret);
- return ret;
-}
-
-static int sn95031_set_vaud_bias(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
- pr_debug("vaud_bias powering up pll\n");
- /* power up the pll */
- snd_soc_write(codec, SN95031_AUDPLLCTRL, BIT(5));
- /* enable pcm 2 */
- snd_soc_update_bits(codec, SN95031_PCM2C2,
- BIT(0), BIT(0));
- }
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- pr_debug("vaud_bias power up rail\n");
- /* power up the rail */
- snd_soc_write(codec, SN95031_VAUD,
- BIT(2)|BIT(1)|BIT(0));
- msleep(1);
- } else if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) {
- /* turn off pcm */
- pr_debug("vaud_bias power dn pcm\n");
- snd_soc_update_bits(codec, SN95031_PCM2C2, BIT(0), 0);
- snd_soc_write(codec, SN95031_AUDPLLCTRL, 0);
- }
- break;
-
-
- case SND_SOC_BIAS_OFF:
- pr_debug("vaud_bias _OFF doing rail shutdown\n");
- snd_soc_write(codec, SN95031_VAUD, BIT(3));
- break;
- }
-
- codec->dapm.bias_level = level;
- return 0;
-}
-
-static int sn95031_vhs_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- if (SND_SOC_DAPM_EVENT_ON(event)) {
- pr_debug("VHS SND_SOC_DAPM_EVENT_ON doing rail startup now\n");
- /* power up the rail */
- snd_soc_write(w->codec, SN95031_VHSP, 0x3D);
- snd_soc_write(w->codec, SN95031_VHSN, 0x3F);
- msleep(1);
- } else if (SND_SOC_DAPM_EVENT_OFF(event)) {
- pr_debug("VHS SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n");
- snd_soc_write(w->codec, SN95031_VHSP, 0xC4);
- snd_soc_write(w->codec, SN95031_VHSN, 0x04);
- }
- return 0;
-}
-
-static int sn95031_vihf_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- if (SND_SOC_DAPM_EVENT_ON(event)) {
- pr_debug("VIHF SND_SOC_DAPM_EVENT_ON doing rail startup now\n");
- /* power up the rail */
- snd_soc_write(w->codec, SN95031_VIHF, 0x27);
- msleep(1);
- } else if (SND_SOC_DAPM_EVENT_OFF(event)) {
- pr_debug("VIHF SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n");
- snd_soc_write(w->codec, SN95031_VIHF, 0x24);
- }
- return 0;
-}
-
-static int sn95031_dmic12_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- unsigned int ldo = 0, clk_dir = 0, data_dir = 0;
-
- if (SND_SOC_DAPM_EVENT_ON(event)) {
- ldo = BIT(5)|BIT(4);
- clk_dir = BIT(0);
- data_dir = BIT(7);
- }
- /* program DMIC LDO, clock and set clock */
- snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo);
- snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(0), clk_dir);
- snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(7), data_dir);
- return 0;
-}
-
-static int sn95031_dmic34_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- unsigned int ldo = 0, clk_dir = 0, data_dir = 0;
-
- if (SND_SOC_DAPM_EVENT_ON(event)) {
- ldo = BIT(5)|BIT(4);
- clk_dir = BIT(2);
- data_dir = BIT(1);
- }
- /* program DMIC LDO, clock and set clock */
- snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo);
- snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(2), clk_dir);
- snd_soc_update_bits(w->codec, SN95031_DMICBUF45, BIT(1), data_dir);
- return 0;
-}
-
-static int sn95031_dmic56_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- unsigned int ldo = 0;
-
- if (SND_SOC_DAPM_EVENT_ON(event))
- ldo = BIT(7)|BIT(6);
-
- /* program DMIC LDO */
- snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(7)|BIT(6), ldo);
- return 0;
-}
-
-/* mux controls */
-static const char *sn95031_mic_texts[] = { "AMIC", "LineIn" };
-
-static const struct soc_enum sn95031_micl_enum =
- SOC_ENUM_SINGLE(SN95031_ADCCONFIG, 1, 2, sn95031_mic_texts);
-
-static const struct snd_kcontrol_new sn95031_micl_mux_control =
- SOC_DAPM_ENUM("Route", sn95031_micl_enum);
-
-static const struct soc_enum sn95031_micr_enum =
- SOC_ENUM_SINGLE(SN95031_ADCCONFIG, 3, 2, sn95031_mic_texts);
-
-static const struct snd_kcontrol_new sn95031_micr_mux_control =
- SOC_DAPM_ENUM("Route", sn95031_micr_enum);
-
-static const char *sn95031_input_texts[] = { "DMIC1", "DMIC2", "DMIC3",
- "DMIC4", "DMIC5", "DMIC6",
- "ADC Left", "ADC Right" };
-
-static const struct soc_enum sn95031_input1_enum =
- SOC_ENUM_SINGLE(SN95031_AUDIOMUX12, 0, 8, sn95031_input_texts);
-
-static const struct snd_kcontrol_new sn95031_input1_mux_control =
- SOC_DAPM_ENUM("Route", sn95031_input1_enum);
-
-static const struct soc_enum sn95031_input2_enum =
- SOC_ENUM_SINGLE(SN95031_AUDIOMUX12, 4, 8, sn95031_input_texts);
-
-static const struct snd_kcontrol_new sn95031_input2_mux_control =
- SOC_DAPM_ENUM("Route", sn95031_input2_enum);
-
-static const struct soc_enum sn95031_input3_enum =
- SOC_ENUM_SINGLE(SN95031_AUDIOMUX34, 0, 8, sn95031_input_texts);
-
-static const struct snd_kcontrol_new sn95031_input3_mux_control =
- SOC_DAPM_ENUM("Route", sn95031_input3_enum);
-
-static const struct soc_enum sn95031_input4_enum =
- SOC_ENUM_SINGLE(SN95031_AUDIOMUX34, 4, 8, sn95031_input_texts);
-
-static const struct snd_kcontrol_new sn95031_input4_mux_control =
- SOC_DAPM_ENUM("Route", sn95031_input4_enum);
-
-/* capture path controls */
-
-static const char *sn95031_micmode_text[] = {"Single Ended", "Differential"};
-
-/* 0dB to 30dB in 10dB steps */
-static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 10, 0);
-
-static const struct soc_enum sn95031_micmode1_enum =
- SOC_ENUM_SINGLE(SN95031_MICAMP1, 1, 2, sn95031_micmode_text);
-static const struct soc_enum sn95031_micmode2_enum =
- SOC_ENUM_SINGLE(SN95031_MICAMP2, 1, 2, sn95031_micmode_text);
-
-static const char *sn95031_dmic_cfg_text[] = {"GPO", "DMIC"};
-
-static const struct soc_enum sn95031_dmic12_cfg_enum =
- SOC_ENUM_SINGLE(SN95031_DMICMUX, 0, 2, sn95031_dmic_cfg_text);
-static const struct soc_enum sn95031_dmic34_cfg_enum =
- SOC_ENUM_SINGLE(SN95031_DMICMUX, 1, 2, sn95031_dmic_cfg_text);
-static const struct soc_enum sn95031_dmic56_cfg_enum =
- SOC_ENUM_SINGLE(SN95031_DMICMUX, 2, 2, sn95031_dmic_cfg_text);
-
-static const struct snd_kcontrol_new sn95031_snd_controls[] = {
- SOC_ENUM("Mic1Mode Capture Route", sn95031_micmode1_enum),
- SOC_ENUM("Mic2Mode Capture Route", sn95031_micmode2_enum),
- SOC_ENUM("DMIC12 Capture Route", sn95031_dmic12_cfg_enum),
- SOC_ENUM("DMIC34 Capture Route", sn95031_dmic34_cfg_enum),
- SOC_ENUM("DMIC56 Capture Route", sn95031_dmic56_cfg_enum),
- SOC_SINGLE_TLV("Mic1 Capture Volume", SN95031_MICAMP1,
- 2, 4, 0, mic_tlv),
- SOC_SINGLE_TLV("Mic2 Capture Volume", SN95031_MICAMP2,
- 2, 4, 0, mic_tlv),
-};
-
-/* DAPM widgets */
-static const struct snd_soc_dapm_widget sn95031_dapm_widgets[] = {
-
- /* all end points mic, hs etc */
- SND_SOC_DAPM_OUTPUT("HPOUTL"),
- SND_SOC_DAPM_OUTPUT("HPOUTR"),
- SND_SOC_DAPM_OUTPUT("EPOUT"),
- SND_SOC_DAPM_OUTPUT("IHFOUTL"),
- SND_SOC_DAPM_OUTPUT("IHFOUTR"),
- SND_SOC_DAPM_OUTPUT("LINEOUTL"),
- SND_SOC_DAPM_OUTPUT("LINEOUTR"),
- SND_SOC_DAPM_OUTPUT("VIB1OUT"),
- SND_SOC_DAPM_OUTPUT("VIB2OUT"),
-
- SND_SOC_DAPM_INPUT("AMIC1"), /* headset mic */
- SND_SOC_DAPM_INPUT("AMIC2"),
- SND_SOC_DAPM_INPUT("DMIC1"),
- SND_SOC_DAPM_INPUT("DMIC2"),
- SND_SOC_DAPM_INPUT("DMIC3"),
- SND_SOC_DAPM_INPUT("DMIC4"),
- SND_SOC_DAPM_INPUT("DMIC5"),
- SND_SOC_DAPM_INPUT("DMIC6"),
- SND_SOC_DAPM_INPUT("LINEINL"),
- SND_SOC_DAPM_INPUT("LINEINR"),
-
- SND_SOC_DAPM_MICBIAS("AMIC1Bias", SN95031_MICBIAS, 2, 0),
- SND_SOC_DAPM_MICBIAS("AMIC2Bias", SN95031_MICBIAS, 3, 0),
- SND_SOC_DAPM_MICBIAS("DMIC12Bias", SN95031_DMICMUX, 3, 0),
- SND_SOC_DAPM_MICBIAS("DMIC34Bias", SN95031_DMICMUX, 4, 0),
- SND_SOC_DAPM_MICBIAS("DMIC56Bias", SN95031_DMICMUX, 5, 0),
-
- SND_SOC_DAPM_SUPPLY("DMIC12supply", SN95031_DMICLK, 0, 0,
- sn95031_dmic12_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_SUPPLY("DMIC34supply", SN95031_DMICLK, 1, 0,
- sn95031_dmic34_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_SUPPLY("DMIC56supply", SN95031_DMICLK, 2, 0,
- sn95031_dmic56_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_AIF_OUT("PCM_Out", "Capture", 0,
- SND_SOC_NOPM, 0, 0),
-
- SND_SOC_DAPM_SUPPLY("Headset Rail", SND_SOC_NOPM, 0, 0,
- sn95031_vhs_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_SUPPLY("Speaker Rail", SND_SOC_NOPM, 0, 0,
- sn95031_vihf_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
- /* playback path driver enables */
- SND_SOC_DAPM_PGA("Headset Left Playback",
- SN95031_DRIVEREN, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Headset Right Playback",
- SN95031_DRIVEREN, 1, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Speaker Left Playback",
- SN95031_DRIVEREN, 2, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Speaker Right Playback",
- SN95031_DRIVEREN, 3, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Vibra1 Playback",
- SN95031_DRIVEREN, 4, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Vibra2 Playback",
- SN95031_DRIVEREN, 5, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Earpiece Playback",
- SN95031_DRIVEREN, 6, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Lineout Left Playback",
- SN95031_LOCTL, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Lineout Right Playback",
- SN95031_LOCTL, 4, 0, NULL, 0),
-
- /* playback path filter enable */
- SND_SOC_DAPM_PGA("Headset Left Filter",
- SN95031_HSEPRXCTRL, 4, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Headset Right Filter",
- SN95031_HSEPRXCTRL, 5, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Speaker Left Filter",
- SN95031_IHFRXCTRL, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Speaker Right Filter",
- SN95031_IHFRXCTRL, 1, 0, NULL, 0),
-
- /* DACs */
- SND_SOC_DAPM_DAC("HSDAC Left", "Headset",
- SN95031_DACCONFIG, 0, 0),
- SND_SOC_DAPM_DAC("HSDAC Right", "Headset",
- SN95031_DACCONFIG, 1, 0),
- SND_SOC_DAPM_DAC("IHFDAC Left", "Speaker",
- SN95031_DACCONFIG, 2, 0),
- SND_SOC_DAPM_DAC("IHFDAC Right", "Speaker",
- SN95031_DACCONFIG, 3, 0),
- SND_SOC_DAPM_DAC("Vibra1 DAC", "Vibra1",
- SN95031_VIB1C5, 1, 0),
- SND_SOC_DAPM_DAC("Vibra2 DAC", "Vibra2",
- SN95031_VIB2C5, 1, 0),
-
- /* capture widgets */
- SND_SOC_DAPM_PGA("LineIn Enable Left", SN95031_MICAMP1,
- 7, 0, NULL, 0),
- SND_SOC_DAPM_PGA("LineIn Enable Right", SN95031_MICAMP2,
- 7, 0, NULL, 0),
-
- SND_SOC_DAPM_PGA("MIC1 Enable", SN95031_MICAMP1, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("MIC2 Enable", SN95031_MICAMP2, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("TX1 Enable", SN95031_AUDIOTXEN, 2, 0, NULL, 0),
- SND_SOC_DAPM_PGA("TX2 Enable", SN95031_AUDIOTXEN, 3, 0, NULL, 0),
- SND_SOC_DAPM_PGA("TX3 Enable", SN95031_AUDIOTXEN, 4, 0, NULL, 0),
- SND_SOC_DAPM_PGA("TX4 Enable", SN95031_AUDIOTXEN, 5, 0, NULL, 0),
-
- /* ADC have null stream as they will be turned ON by TX path */
- SND_SOC_DAPM_ADC("ADC Left", NULL,
- SN95031_ADCCONFIG, 0, 0),
- SND_SOC_DAPM_ADC("ADC Right", NULL,
- SN95031_ADCCONFIG, 2, 0),
-
- SND_SOC_DAPM_MUX("Mic_InputL Capture Route",
- SND_SOC_NOPM, 0, 0, &sn95031_micl_mux_control),
- SND_SOC_DAPM_MUX("Mic_InputR Capture Route",
- SND_SOC_NOPM, 0, 0, &sn95031_micr_mux_control),
-
- SND_SOC_DAPM_MUX("Txpath1 Capture Route",
- SND_SOC_NOPM, 0, 0, &sn95031_input1_mux_control),
- SND_SOC_DAPM_MUX("Txpath2 Capture Route",
- SND_SOC_NOPM, 0, 0, &sn95031_input2_mux_control),
- SND_SOC_DAPM_MUX("Txpath3 Capture Route",
- SND_SOC_NOPM, 0, 0, &sn95031_input3_mux_control),
- SND_SOC_DAPM_MUX("Txpath4 Capture Route",
- SND_SOC_NOPM, 0, 0, &sn95031_input4_mux_control),
-
-};
-
-static const struct snd_soc_dapm_route sn95031_audio_map[] = {
- /* headset and earpiece map */
- { "HPOUTL", NULL, "Headset Rail"},
- { "HPOUTR", NULL, "Headset Rail"},
- { "HPOUTL", NULL, "Headset Left Playback" },
- { "HPOUTR", NULL, "Headset Right Playback" },
- { "EPOUT", NULL, "Earpiece Playback" },
- { "Headset Left Playback", NULL, "Headset Left Filter"},
- { "Headset Right Playback", NULL, "Headset Right Filter"},
- { "Earpiece Playback", NULL, "Headset Left Filter"},
- { "Headset Left Filter", NULL, "HSDAC Left"},
- { "Headset Right Filter", NULL, "HSDAC Right"},
-
- /* speaker map */
- { "IHFOUTL", NULL, "Speaker Rail"},
- { "IHFOUTR", NULL, "Speaker Rail"},
- { "IHFOUTL", "NULL", "Speaker Left Playback"},
- { "IHFOUTR", "NULL", "Speaker Right Playback"},
- { "Speaker Left Playback", NULL, "Speaker Left Filter"},
- { "Speaker Right Playback", NULL, "Speaker Right Filter"},
- { "Speaker Left Filter", NULL, "IHFDAC Left"},
- { "Speaker Right Filter", NULL, "IHFDAC Right"},
-
- /* vibra map */
- { "VIB1OUT", NULL, "Vibra1 Playback"},
- { "Vibra1 Playback", NULL, "Vibra1 DAC"},
-
- { "VIB2OUT", NULL, "Vibra2 Playback"},
- { "Vibra2 Playback", NULL, "Vibra2 DAC"},
-
- /* lineout */
- { "LINEOUTL", NULL, "Lineout Left Playback"},
- { "LINEOUTR", NULL, "Lineout Right Playback"},
- { "Lineout Left Playback", NULL, "Headset Left Filter"},
- { "Lineout Left Playback", NULL, "Speaker Left Filter"},
- { "Lineout Left Playback", NULL, "Vibra1 DAC"},
- { "Lineout Right Playback", NULL, "Headset Right Filter"},
- { "Lineout Right Playback", NULL, "Speaker Right Filter"},
- { "Lineout Right Playback", NULL, "Vibra2 DAC"},
-
- /* Headset (AMIC1) mic */
- { "AMIC1Bias", NULL, "AMIC1"},
- { "MIC1 Enable", NULL, "AMIC1Bias"},
- { "Mic_InputL Capture Route", "AMIC", "MIC1 Enable"},
-
- /* AMIC2 */
- { "AMIC2Bias", NULL, "AMIC2"},
- { "MIC2 Enable", NULL, "AMIC2Bias"},
- { "Mic_InputR Capture Route", "AMIC", "MIC2 Enable"},
-
-
- /* Linein */
- { "LineIn Enable Left", NULL, "LINEINL"},
- { "LineIn Enable Right", NULL, "LINEINR"},
- { "Mic_InputL Capture Route", "LineIn", "LineIn Enable Left"},
- { "Mic_InputR Capture Route", "LineIn", "LineIn Enable Right"},
-
- /* ADC connection */
- { "ADC Left", NULL, "Mic_InputL Capture Route"},
- { "ADC Right", NULL, "Mic_InputR Capture Route"},
-
- /*DMIC connections */
- { "DMIC1", NULL, "DMIC12supply"},
- { "DMIC2", NULL, "DMIC12supply"},
- { "DMIC3", NULL, "DMIC34supply"},
- { "DMIC4", NULL, "DMIC34supply"},
- { "DMIC5", NULL, "DMIC56supply"},
- { "DMIC6", NULL, "DMIC56supply"},
-
- { "DMIC12Bias", NULL, "DMIC1"},
- { "DMIC12Bias", NULL, "DMIC2"},
- { "DMIC34Bias", NULL, "DMIC3"},
- { "DMIC34Bias", NULL, "DMIC4"},
- { "DMIC56Bias", NULL, "DMIC5"},
- { "DMIC56Bias", NULL, "DMIC6"},
-
- /*TX path inputs*/
- { "Txpath1 Capture Route", "ADC Left", "ADC Left"},
- { "Txpath2 Capture Route", "ADC Left", "ADC Left"},
- { "Txpath3 Capture Route", "ADC Left", "ADC Left"},
- { "Txpath4 Capture Route", "ADC Left", "ADC Left"},
- { "Txpath1 Capture Route", "ADC Right", "ADC Right"},
- { "Txpath2 Capture Route", "ADC Right", "ADC Right"},
- { "Txpath3 Capture Route", "ADC Right", "ADC Right"},
- { "Txpath4 Capture Route", "ADC Right", "ADC Right"},
- { "Txpath1 Capture Route", "DMIC1", "DMIC1"},
- { "Txpath2 Capture Route", "DMIC1", "DMIC1"},
- { "Txpath3 Capture Route", "DMIC1", "DMIC1"},
- { "Txpath4 Capture Route", "DMIC1", "DMIC1"},
- { "Txpath1 Capture Route", "DMIC2", "DMIC2"},
- { "Txpath2 Capture Route", "DMIC2", "DMIC2"},
- { "Txpath3 Capture Route", "DMIC2", "DMIC2"},
- { "Txpath4 Capture Route", "DMIC2", "DMIC2"},
- { "Txpath1 Capture Route", "DMIC3", "DMIC3"},
- { "Txpath2 Capture Route", "DMIC3", "DMIC3"},
- { "Txpath3 Capture Route", "DMIC3", "DMIC3"},
- { "Txpath4 Capture Route", "DMIC3", "DMIC3"},
- { "Txpath1 Capture Route", "DMIC4", "DMIC4"},
- { "Txpath2 Capture Route", "DMIC4", "DMIC4"},
- { "Txpath3 Capture Route", "DMIC4", "DMIC4"},
- { "Txpath4 Capture Route", "DMIC4", "DMIC4"},
- { "Txpath1 Capture Route", "DMIC5", "DMIC5"},
- { "Txpath2 Capture Route", "DMIC5", "DMIC5"},
- { "Txpath3 Capture Route", "DMIC5", "DMIC5"},
- { "Txpath4 Capture Route", "DMIC5", "DMIC5"},
- { "Txpath1 Capture Route", "DMIC6", "DMIC6"},
- { "Txpath2 Capture Route", "DMIC6", "DMIC6"},
- { "Txpath3 Capture Route", "DMIC6", "DMIC6"},
- { "Txpath4 Capture Route", "DMIC6", "DMIC6"},
-
- /* tx path */
- { "TX1 Enable", NULL, "Txpath1 Capture Route"},
- { "TX2 Enable", NULL, "Txpath2 Capture Route"},
- { "TX3 Enable", NULL, "Txpath3 Capture Route"},
- { "TX4 Enable", NULL, "Txpath4 Capture Route"},
- { "PCM_Out", NULL, "TX1 Enable"},
- { "PCM_Out", NULL, "TX2 Enable"},
- { "PCM_Out", NULL, "TX3 Enable"},
- { "PCM_Out", NULL, "TX4 Enable"},
-
-};
-
-/* speaker and headset mutes, for audio pops and clicks */
-static int sn95031_pcm_hs_mute(struct snd_soc_dai *dai, int mute)
-{
- snd_soc_update_bits(dai->codec,
- SN95031_HSLVOLCTRL, BIT(7), (!mute << 7));
- snd_soc_update_bits(dai->codec,
- SN95031_HSRVOLCTRL, BIT(7), (!mute << 7));
- return 0;
-}
-
-static int sn95031_pcm_spkr_mute(struct snd_soc_dai *dai, int mute)
-{
- snd_soc_update_bits(dai->codec,
- SN95031_IHFLVOLCTRL, BIT(7), (!mute << 7));
- snd_soc_update_bits(dai->codec,
- SN95031_IHFRVOLCTRL, BIT(7), (!mute << 7));
- return 0;
-}
-
-static int sn95031_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
-{
- unsigned int format, rate;
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- format = BIT(4)|BIT(5);
- break;
-
- case SNDRV_PCM_FORMAT_S24_LE:
- format = 0;
- break;
- default:
- return -EINVAL;
- }
- snd_soc_update_bits(dai->codec, SN95031_PCM2C2,
- BIT(4)|BIT(5), format);
-
- switch (params_rate(params)) {
- case 48000:
- pr_debug("RATE_48000\n");
- rate = 0;
- break;
-
- case 44100:
- pr_debug("RATE_44100\n");
- rate = BIT(7);
- break;
-
- default:
- pr_err("ERR rate %d\n", params_rate(params));
- return -EINVAL;
- }
- snd_soc_update_bits(dai->codec, SN95031_PCM1C1, BIT(7), rate);
-
- return 0;
-}
-
-/* Codec DAI section */
-static const struct snd_soc_dai_ops sn95031_headset_dai_ops = {
- .digital_mute = sn95031_pcm_hs_mute,
- .hw_params = sn95031_pcm_hw_params,
-};
-
-static const struct snd_soc_dai_ops sn95031_speaker_dai_ops = {
- .digital_mute = sn95031_pcm_spkr_mute,
- .hw_params = sn95031_pcm_hw_params,
-};
-
-static const struct snd_soc_dai_ops sn95031_vib1_dai_ops = {
- .hw_params = sn95031_pcm_hw_params,
-};
-
-static const struct snd_soc_dai_ops sn95031_vib2_dai_ops = {
- .hw_params = sn95031_pcm_hw_params,
-};
-
-static struct snd_soc_dai_driver sn95031_dais[] = {
-{
- .name = "SN95031 Headset",
- .playback = {
- .stream_name = "Headset",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SN95031_RATES,
- .formats = SN95031_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 5,
- .rates = SN95031_RATES,
- .formats = SN95031_FORMATS,
- },
- .ops = &sn95031_headset_dai_ops,
-},
-{ .name = "SN95031 Speaker",
- .playback = {
- .stream_name = "Speaker",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SN95031_RATES,
- .formats = SN95031_FORMATS,
- },
- .ops = &sn95031_speaker_dai_ops,
-},
-{ .name = "SN95031 Vibra1",
- .playback = {
- .stream_name = "Vibra1",
- .channels_min = 1,
- .channels_max = 1,
- .rates = SN95031_RATES,
- .formats = SN95031_FORMATS,
- },
- .ops = &sn95031_vib1_dai_ops,
-},
-{ .name = "SN95031 Vibra2",
- .playback = {
- .stream_name = "Vibra2",
- .channels_min = 1,
- .channels_max = 1,
- .rates = SN95031_RATES,
- .formats = SN95031_FORMATS,
- },
- .ops = &sn95031_vib2_dai_ops,
-},
-};
-
-static inline void sn95031_disable_jack_btn(struct snd_soc_codec *codec)
-{
- snd_soc_write(codec, SN95031_BTNCTRL2, 0x00);
-}
-
-static inline void sn95031_enable_jack_btn(struct snd_soc_codec *codec)
-{
- snd_soc_write(codec, SN95031_BTNCTRL1, 0x77);
- snd_soc_write(codec, SN95031_BTNCTRL2, 0x01);
-}
-
-static int sn95031_get_headset_state(struct snd_soc_jack *mfld_jack)
-{
- int micbias = sn95031_get_mic_bias(mfld_jack->codec);
-
- int jack_type = snd_soc_jack_get_type(mfld_jack, micbias);
-
- pr_debug("jack type detected = %d\n", jack_type);
- if (jack_type == SND_JACK_HEADSET)
- sn95031_enable_jack_btn(mfld_jack->codec);
- return jack_type;
-}
-
-void sn95031_jack_detection(struct mfld_jack_data *jack_data)
-{
- unsigned int status;
- unsigned int mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_HEADSET;
-
- pr_debug("interrupt id read in sram = 0x%x\n", jack_data->intr_id);
- if (jack_data->intr_id & 0x1) {
- pr_debug("short_push detected\n");
- status = SND_JACK_HEADSET | SND_JACK_BTN_0;
- } else if (jack_data->intr_id & 0x2) {
- pr_debug("long_push detected\n");
- status = SND_JACK_HEADSET | SND_JACK_BTN_1;
- } else if (jack_data->intr_id & 0x4) {
- pr_debug("headset or headphones inserted\n");
- status = sn95031_get_headset_state(jack_data->mfld_jack);
- } else if (jack_data->intr_id & 0x8) {
- pr_debug("headset or headphones removed\n");
- status = 0;
- sn95031_disable_jack_btn(jack_data->mfld_jack->codec);
- } else {
- pr_err("unidentified interrupt\n");
- return;
- }
-
- snd_soc_jack_report(jack_data->mfld_jack, status, mask);
- /*button pressed and released so we send explicit button release */
- if ((status & SND_JACK_BTN_0) | (status & SND_JACK_BTN_1))
- snd_soc_jack_report(jack_data->mfld_jack,
- SND_JACK_HEADSET, mask);
-}
-EXPORT_SYMBOL_GPL(sn95031_jack_detection);
-
-/* codec registration */
-static int sn95031_codec_probe(struct snd_soc_codec *codec)
-{
- pr_debug("codec_probe called\n");
-
- /* PCM interface config
- * This sets the pcm rx slot conguration to max 6 slots
- * for max 4 dais (2 stereo and 2 mono)
- */
- snd_soc_write(codec, SN95031_PCM2RXSLOT01, 0x10);
- snd_soc_write(codec, SN95031_PCM2RXSLOT23, 0x32);
- snd_soc_write(codec, SN95031_PCM2RXSLOT45, 0x54);
- snd_soc_write(codec, SN95031_PCM2TXSLOT01, 0x10);
- snd_soc_write(codec, SN95031_PCM2TXSLOT23, 0x32);
- /* pcm port setting
- * This sets the pcm port to slave and clock at 19.2Mhz which
- * can support 6slots, sampling rate set per stream in hw-params
- */
- snd_soc_write(codec, SN95031_PCM1C1, 0x00);
- snd_soc_write(codec, SN95031_PCM2C1, 0x01);
- snd_soc_write(codec, SN95031_PCM2C2, 0x0A);
- snd_soc_write(codec, SN95031_HSMIXER, BIT(0)|BIT(4));
- /* vendor vibra workround, the vibras are muted by
- * custom register so unmute them
- */
- snd_soc_write(codec, SN95031_SSR5, 0x80);
- snd_soc_write(codec, SN95031_SSR6, 0x80);
- snd_soc_write(codec, SN95031_VIB1C5, 0x00);
- snd_soc_write(codec, SN95031_VIB2C5, 0x00);
- /* configure vibras for pcm port */
- snd_soc_write(codec, SN95031_VIB1C3, 0x00);
- snd_soc_write(codec, SN95031_VIB2C3, 0x00);
-
- /* soft mute ramp time */
- snd_soc_write(codec, SN95031_SOFTMUTE, 0x3);
- /* fix the initial volume at 1dB,
- * default in +9dB,
- * 1dB give optimal swing on DAC, amps
- */
- snd_soc_write(codec, SN95031_HSLVOLCTRL, 0x08);
- snd_soc_write(codec, SN95031_HSRVOLCTRL, 0x08);
- snd_soc_write(codec, SN95031_IHFLVOLCTRL, 0x08);
- snd_soc_write(codec, SN95031_IHFRVOLCTRL, 0x08);
- /* dac mode and lineout workaround */
- snd_soc_write(codec, SN95031_SSR2, 0x10);
- snd_soc_write(codec, SN95031_SSR3, 0x40);
-
- snd_soc_add_codec_controls(codec, sn95031_snd_controls,
- ARRAY_SIZE(sn95031_snd_controls));
-
- return 0;
-}
-
-static int sn95031_codec_remove(struct snd_soc_codec *codec)
-{
- pr_debug("codec_remove called\n");
- sn95031_set_vaud_bias(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-struct snd_soc_codec_driver sn95031_codec = {
- .probe = sn95031_codec_probe,
- .remove = sn95031_codec_remove,
- .read = sn95031_read,
- .write = sn95031_write,
- .set_bias_level = sn95031_set_vaud_bias,
- .idle_bias_off = true,
- .dapm_widgets = sn95031_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets),
- .dapm_routes = sn95031_audio_map,
- .num_dapm_routes = ARRAY_SIZE(sn95031_audio_map),
-};
-
-static int __devinit sn95031_device_probe(struct platform_device *pdev)
-{
- pr_debug("codec device probe called for %s\n", dev_name(&pdev->dev));
- return snd_soc_register_codec(&pdev->dev, &sn95031_codec,
- sn95031_dais, ARRAY_SIZE(sn95031_dais));
-}
-
-static int __devexit sn95031_device_remove(struct platform_device *pdev)
-{
- pr_debug("codec device remove called\n");
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver sn95031_codec_driver = {
- .driver = {
- .name = "sn95031",
- .owner = THIS_MODULE,
- },
- .probe = sn95031_device_probe,
- .remove = __devexit_p(sn95031_device_remove),
-};
-
-module_platform_driver(sn95031_codec_driver);
-
-MODULE_DESCRIPTION("ASoC TI SN95031 codec driver");
-MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
-MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:sn95031");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/sn95031.h b/ANDROID_3.4.5/sound/soc/codecs/sn95031.h
deleted file mode 100644
index 20376d23..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/sn95031.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * sn95031.h - TI sn95031 Codec driver
- *
- * Copyright (C) 2010 Intel Corp
- * Author: Vinod Koul <vinod.koul@intel.com>
- * Author: Harsha Priya <priya.harsha@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *
- */
-#ifndef _SN95031_H
-#define _SN95031_H
-
-/*register map*/
-#define SN95031_VAUD 0xDB
-#define SN95031_VHSP 0xDC
-#define SN95031_VHSN 0xDD
-#define SN95031_VIHF 0xC9
-
-#define SN95031_AUDPLLCTRL 0x240
-#define SN95031_DMICBUF0123 0x241
-#define SN95031_DMICBUF45 0x242
-#define SN95031_DMICGPO 0x244
-#define SN95031_DMICMUX 0x245
-#define SN95031_DMICLK 0x246
-#define SN95031_MICBIAS 0x247
-#define SN95031_ADCCONFIG 0x248
-#define SN95031_MICAMP1 0x249
-#define SN95031_MICAMP2 0x24A
-#define SN95031_NOISEMUX 0x24B
-#define SN95031_AUDIOMUX12 0x24C
-#define SN95031_AUDIOMUX34 0x24D
-#define SN95031_AUDIOSINC 0x24E
-#define SN95031_AUDIOTXEN 0x24F
-#define SN95031_HSEPRXCTRL 0x250
-#define SN95031_IHFRXCTRL 0x251
-#define SN95031_HSMIXER 0x256
-#define SN95031_DACCONFIG 0x257
-#define SN95031_SOFTMUTE 0x258
-#define SN95031_HSLVOLCTRL 0x259
-#define SN95031_HSRVOLCTRL 0x25A
-#define SN95031_IHFLVOLCTRL 0x25B
-#define SN95031_IHFRVOLCTRL 0x25C
-#define SN95031_DRIVEREN 0x25D
-#define SN95031_LOCTL 0x25E
-#define SN95031_VIB1C1 0x25F
-#define SN95031_VIB1C2 0x260
-#define SN95031_VIB1C3 0x261
-#define SN95031_VIB1SPIPCM1 0x262
-#define SN95031_VIB1SPIPCM2 0x263
-#define SN95031_VIB1C5 0x264
-#define SN95031_VIB2C1 0x265
-#define SN95031_VIB2C2 0x266
-#define SN95031_VIB2C3 0x267
-#define SN95031_VIB2SPIPCM1 0x268
-#define SN95031_VIB2SPIPCM2 0x269
-#define SN95031_VIB2C5 0x26A
-#define SN95031_BTNCTRL1 0x26B
-#define SN95031_BTNCTRL2 0x26C
-#define SN95031_PCM1TXSLOT01 0x26D
-#define SN95031_PCM1TXSLOT23 0x26E
-#define SN95031_PCM1TXSLOT45 0x26F
-#define SN95031_PCM1RXSLOT0_3 0x270
-#define SN95031_PCM1RXSLOT45 0x271
-#define SN95031_PCM2TXSLOT01 0x272
-#define SN95031_PCM2TXSLOT23 0x273
-#define SN95031_PCM2TXSLOT45 0x274
-#define SN95031_PCM2RXSLOT01 0x275
-#define SN95031_PCM2RXSLOT23 0x276
-#define SN95031_PCM2RXSLOT45 0x277
-#define SN95031_PCM1C1 0x278
-#define SN95031_PCM1C2 0x279
-#define SN95031_PCM1C3 0x27A
-#define SN95031_PCM2C1 0x27B
-#define SN95031_PCM2C2 0x27C
-/*end codec register defn*/
-
-/*vendor defn these are not part of avp*/
-#define SN95031_SSR2 0x381
-#define SN95031_SSR3 0x382
-#define SN95031_SSR5 0x384
-#define SN95031_SSR6 0x385
-
-/* ADC registers */
-
-#define SN95031_ADC1CNTL1 0x1C0
-#define SN95031_ADC_ENBL 0x10
-#define SN95031_ADC_START 0x08
-#define SN95031_ADC1CNTL3 0x1C2
-#define SN95031_ADCTHERM_ENBL 0x04
-#define SN95031_ADCRRDATA_ENBL 0x05
-#define SN95031_STOPBIT_MASK 16
-#define SN95031_ADCTHERM_MASK 4
-#define SN95031_ADC_CHANLS_MAX 15 /* Number of ADC channels */
-#define SN95031_ADC_LOOP_MAX (SN95031_ADC_CHANLS_MAX - 1)
-#define SN95031_ADC_NO_LOOP 0x07
-#define SN95031_AUDIO_GPIO_CTRL 0x070
-
-/* ADC channel code values */
-#define SN95031_AUDIO_DETECT_CODE 0x06
-
-/* ADC base addresses */
-#define SN95031_ADC_CHNL_START_ADDR 0x1C5 /* increments by 1 */
-#define SN95031_ADC_DATA_START_ADDR 0x1D4 /* increments by 2 */
-/* multipier to convert to mV */
-#define SN95031_ADC_ONE_LSB_MULTIPLIER 2346
-
-
-struct mfld_jack_data {
- int intr_id;
- int micbias_vol;
- struct snd_soc_jack *mfld_jack;
-};
-
-extern void sn95031_jack_detection(struct mfld_jack_data *jack_data);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/spdif_transciever.c b/ANDROID_3.4.5/sound/soc/codecs/spdif_transciever.c
deleted file mode 100644
index 112a49d6..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/spdif_transciever.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * ALSA SoC SPDIF DIT driver
- *
- * This driver is used by controllers which can operate in DIT (SPDI/F) where
- * no codec is needed. This file provides stub codec that can be used
- * in these configurations. TI DaVinci Audio controller uses this driver.
- *
- * Author: Steve Chen, <schen@mvista.com>
- * Copyright: (C) 2009 MontaVista Software, Inc., <source@mvista.com>
- * Copyright: (C) 2009 Texas Instruments, India
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/slab.h>
-#include <sound/soc.h>
-#include <sound/pcm.h>
-#include <sound/initval.h>
-
-#define DRV_NAME "spdif-dit"
-
-#define STUB_RATES SNDRV_PCM_RATE_8000_96000
-#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE
-
-
-static struct snd_soc_codec_driver soc_codec_spdif_dit;
-
-static struct snd_soc_dai_driver dit_stub_dai = {
- .name = "dit-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 384,
- .rates = STUB_RATES,
- .formats = STUB_FORMATS,
- },
-};
-
-static int spdif_dit_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev, &soc_codec_spdif_dit,
- &dit_stub_dai, 1);
-}
-
-static int spdif_dit_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver spdif_dit_driver = {
- .probe = spdif_dit_probe,
- .remove = spdif_dit_remove,
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(spdif_dit_driver);
-
-MODULE_AUTHOR("Steve Chen <schen@mvista.com>");
-MODULE_DESCRIPTION("SPDIF dummy codec driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/ANDROID_3.4.5/sound/soc/codecs/ssm2602.c b/ANDROID_3.4.5/sound/soc/codecs/ssm2602.c
deleted file mode 100644
index de2b2054..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/ssm2602.c
+++ /dev/null
@@ -1,773 +0,0 @@
-/*
- * File: sound/soc/codecs/ssm2602.c
- * Author: Cliff Cai <Cliff.Cai@analog.com>
- *
- * Created: Tue June 06 2008
- * Description: Driver for ssm2602 sound chip
- *
- * Modified:
- * Copyright 2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "ssm2602.h"
-
-#define SSM2602_VERSION "0.1"
-
-enum ssm2602_type {
- SSM2602,
- SSM2604,
-};
-
-/* codec private data */
-struct ssm2602_priv {
- unsigned int sysclk;
- enum snd_soc_control_type control_type;
- struct snd_pcm_substream *master_substream;
- struct snd_pcm_substream *slave_substream;
-
- enum ssm2602_type type;
- unsigned int clk_out_pwr;
-};
-
-/*
- * ssm2602 register cache
- * We can't read the ssm2602 register space when we are
- * using 2 wire for device control, so we cache them instead.
- * There is no point in caching the reset register
- */
-static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = {
- 0x0097, 0x0097, 0x0079, 0x0079,
- 0x000a, 0x0008, 0x009f, 0x000a,
- 0x0000, 0x0000
-};
-
-#define ssm2602_reset(c) snd_soc_write(c, SSM2602_RESET, 0)
-
-/*Appending several "None"s just for OSS mixer use*/
-static const char *ssm2602_input_select[] = {
- "Line", "Mic", "None", "None", "None",
- "None", "None", "None",
-};
-
-static const char *ssm2602_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
-
-static const struct soc_enum ssm2602_enum[] = {
- SOC_ENUM_SINGLE(SSM2602_APANA, 2, 2, ssm2602_input_select),
- SOC_ENUM_SINGLE(SSM2602_APDIGI, 1, 4, ssm2602_deemph),
-};
-
-static const unsigned int ssm260x_outmix_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 47, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0),
- 48, 127, TLV_DB_SCALE_ITEM(-7400, 100, 0),
-};
-
-static const DECLARE_TLV_DB_SCALE(ssm260x_inpga_tlv, -3450, 150, 0);
-static const DECLARE_TLV_DB_SCALE(ssm260x_sidetone_tlv, -1500, 300, 0);
-
-static const struct snd_kcontrol_new ssm260x_snd_controls[] = {
-SOC_DOUBLE_R_TLV("Capture Volume", SSM2602_LINVOL, SSM2602_RINVOL, 0, 45, 0,
- ssm260x_inpga_tlv),
-SOC_DOUBLE_R("Capture Switch", SSM2602_LINVOL, SSM2602_RINVOL, 7, 1, 1),
-
-SOC_SINGLE("ADC High Pass Filter Switch", SSM2602_APDIGI, 0, 1, 1),
-SOC_SINGLE("Store DC Offset Switch", SSM2602_APDIGI, 4, 1, 0),
-
-SOC_ENUM("Playback De-emphasis", ssm2602_enum[1]),
-};
-
-static const struct snd_kcontrol_new ssm2602_snd_controls[] = {
-SOC_DOUBLE_R_TLV("Master Playback Volume", SSM2602_LOUT1V, SSM2602_ROUT1V,
- 0, 127, 0, ssm260x_outmix_tlv),
-SOC_DOUBLE_R("Master Playback ZC Switch", SSM2602_LOUT1V, SSM2602_ROUT1V,
- 7, 1, 0),
-SOC_SINGLE_TLV("Sidetone Playback Volume", SSM2602_APANA, 6, 3, 1,
- ssm260x_sidetone_tlv),
-
-SOC_SINGLE("Mic Boost (+20dB)", SSM2602_APANA, 0, 1, 0),
-SOC_SINGLE("Mic Boost2 (+20dB)", SSM2602_APANA, 8, 1, 0),
-SOC_SINGLE("Mic Switch", SSM2602_APANA, 1, 1, 1),
-};
-
-/* Output Mixer */
-static const struct snd_kcontrol_new ssm260x_output_mixer_controls[] = {
-SOC_DAPM_SINGLE("Line Bypass Switch", SSM2602_APANA, 3, 1, 0),
-SOC_DAPM_SINGLE("HiFi Playback Switch", SSM2602_APANA, 4, 1, 0),
-SOC_DAPM_SINGLE("Mic Sidetone Switch", SSM2602_APANA, 5, 1, 0),
-};
-
-/* Input mux */
-static const struct snd_kcontrol_new ssm2602_input_mux_controls =
-SOC_DAPM_ENUM("Input Select", ssm2602_enum[0]);
-
-static const struct snd_soc_dapm_widget ssm260x_dapm_widgets[] = {
-SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SSM2602_PWR, 3, 1),
-SND_SOC_DAPM_ADC("ADC", "HiFi Capture", SSM2602_PWR, 2, 1),
-SND_SOC_DAPM_PGA("Line Input", SSM2602_PWR, 0, 1, NULL, 0),
-
-SND_SOC_DAPM_SUPPLY("Digital Core Power", SSM2602_ACTIVE, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_OUTPUT("LOUT"),
-SND_SOC_DAPM_OUTPUT("ROUT"),
-SND_SOC_DAPM_INPUT("RLINEIN"),
-SND_SOC_DAPM_INPUT("LLINEIN"),
-};
-
-static const struct snd_soc_dapm_widget ssm2602_dapm_widgets[] = {
-SND_SOC_DAPM_MIXER("Output Mixer", SSM2602_PWR, 4, 1,
- ssm260x_output_mixer_controls,
- ARRAY_SIZE(ssm260x_output_mixer_controls)),
-
-SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, &ssm2602_input_mux_controls),
-SND_SOC_DAPM_MICBIAS("Mic Bias", SSM2602_PWR, 1, 1),
-
-SND_SOC_DAPM_OUTPUT("LHPOUT"),
-SND_SOC_DAPM_OUTPUT("RHPOUT"),
-SND_SOC_DAPM_INPUT("MICIN"),
-};
-
-static const struct snd_soc_dapm_widget ssm2604_dapm_widgets[] = {
-SND_SOC_DAPM_MIXER("Output Mixer", SND_SOC_NOPM, 0, 0,
- ssm260x_output_mixer_controls,
- ARRAY_SIZE(ssm260x_output_mixer_controls) - 1), /* Last element is the mic */
-};
-
-static const struct snd_soc_dapm_route ssm260x_routes[] = {
- {"DAC", NULL, "Digital Core Power"},
- {"ADC", NULL, "Digital Core Power"},
-
- {"Output Mixer", "Line Bypass Switch", "Line Input"},
- {"Output Mixer", "HiFi Playback Switch", "DAC"},
-
- {"ROUT", NULL, "Output Mixer"},
- {"LOUT", NULL, "Output Mixer"},
-
- {"Line Input", NULL, "LLINEIN"},
- {"Line Input", NULL, "RLINEIN"},
-};
-
-static const struct snd_soc_dapm_route ssm2602_routes[] = {
- {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"},
-
- {"RHPOUT", NULL, "Output Mixer"},
- {"LHPOUT", NULL, "Output Mixer"},
-
- {"Input Mux", "Line", "Line Input"},
- {"Input Mux", "Mic", "Mic Bias"},
- {"ADC", NULL, "Input Mux"},
-
- {"Mic Bias", NULL, "MICIN"},
-};
-
-static const struct snd_soc_dapm_route ssm2604_routes[] = {
- {"ADC", NULL, "Line Input"},
-};
-
-struct ssm2602_coeff {
- u32 mclk;
- u32 rate;
- u8 srate;
-};
-
-#define SSM2602_COEFF_SRATE(sr, bosr, usb) (((sr) << 2) | ((bosr) << 1) | (usb))
-
-/* codec mclk clock coefficients */
-static const struct ssm2602_coeff ssm2602_coeff_table[] = {
- /* 48k */
- {12288000, 48000, SSM2602_COEFF_SRATE(0x0, 0x0, 0x0)},
- {18432000, 48000, SSM2602_COEFF_SRATE(0x0, 0x1, 0x0)},
- {12000000, 48000, SSM2602_COEFF_SRATE(0x0, 0x0, 0x1)},
-
- /* 32k */
- {12288000, 32000, SSM2602_COEFF_SRATE(0x6, 0x0, 0x0)},
- {18432000, 32000, SSM2602_COEFF_SRATE(0x6, 0x1, 0x0)},
- {12000000, 32000, SSM2602_COEFF_SRATE(0x6, 0x0, 0x1)},
-
- /* 8k */
- {12288000, 8000, SSM2602_COEFF_SRATE(0x3, 0x0, 0x0)},
- {18432000, 8000, SSM2602_COEFF_SRATE(0x3, 0x1, 0x0)},
- {11289600, 8000, SSM2602_COEFF_SRATE(0xb, 0x0, 0x0)},
- {16934400, 8000, SSM2602_COEFF_SRATE(0xb, 0x1, 0x0)},
- {12000000, 8000, SSM2602_COEFF_SRATE(0x3, 0x0, 0x1)},
-
- /* 96k */
- {12288000, 96000, SSM2602_COEFF_SRATE(0x7, 0x0, 0x0)},
- {18432000, 96000, SSM2602_COEFF_SRATE(0x7, 0x1, 0x0)},
- {12000000, 96000, SSM2602_COEFF_SRATE(0x7, 0x0, 0x1)},
-
- /* 44.1k */
- {11289600, 44100, SSM2602_COEFF_SRATE(0x8, 0x0, 0x0)},
- {16934400, 44100, SSM2602_COEFF_SRATE(0x8, 0x1, 0x0)},
- {12000000, 44100, SSM2602_COEFF_SRATE(0x8, 0x1, 0x1)},
-
- /* 88.2k */
- {11289600, 88200, SSM2602_COEFF_SRATE(0xf, 0x0, 0x0)},
- {16934400, 88200, SSM2602_COEFF_SRATE(0xf, 0x1, 0x0)},
- {12000000, 88200, SSM2602_COEFF_SRATE(0xf, 0x1, 0x1)},
-};
-
-static inline int ssm2602_get_coeff(int mclk, int rate)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(ssm2602_coeff_table); i++) {
- if (ssm2602_coeff_table[i].rate == rate &&
- ssm2602_coeff_table[i].mclk == mclk)
- return ssm2602_coeff_table[i].srate;
- }
- return -EINVAL;
-}
-
-static int ssm2602_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
- u16 iface = snd_soc_read(codec, SSM2602_IFACE) & 0xfff3;
- int srate = ssm2602_get_coeff(ssm2602->sysclk, params_rate(params));
-
- if (substream == ssm2602->slave_substream) {
- dev_dbg(codec->dev, "Ignoring hw_params for slave substream\n");
- return 0;
- }
-
- if (srate < 0)
- return srate;
-
- snd_soc_write(codec, SSM2602_SRATE, srate);
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= 0x0004;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface |= 0x0008;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- iface |= 0x000c;
- break;
- }
- snd_soc_write(codec, SSM2602_IFACE, iface);
- return 0;
-}
-
-static int ssm2602_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
- struct snd_pcm_runtime *master_runtime;
-
- /* The DAI has shared clocks so if we already have a playback or
- * capture going then constrain this substream to match it.
- * TODO: the ssm2602 allows pairs of non-matching PB/REC rates
- */
- if (ssm2602->master_substream) {
- master_runtime = ssm2602->master_substream->runtime;
- dev_dbg(codec->dev, "Constraining to %d bits at %dHz\n",
- master_runtime->sample_bits,
- master_runtime->rate);
-
- if (master_runtime->rate != 0)
- snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_RATE,
- master_runtime->rate,
- master_runtime->rate);
-
- if (master_runtime->sample_bits != 0)
- snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
- master_runtime->sample_bits,
- master_runtime->sample_bits);
-
- ssm2602->slave_substream = substream;
- } else
- ssm2602->master_substream = substream;
-
- return 0;
-}
-
-static void ssm2602_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
-
- if (ssm2602->master_substream == substream)
- ssm2602->master_substream = ssm2602->slave_substream;
-
- ssm2602->slave_substream = NULL;
-}
-
-
-static int ssm2602_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
-
- if (mute)
- snd_soc_update_bits(codec, SSM2602_APDIGI,
- APDIGI_ENABLE_DAC_MUTE,
- APDIGI_ENABLE_DAC_MUTE);
- else
- snd_soc_update_bits(codec, SSM2602_APDIGI,
- APDIGI_ENABLE_DAC_MUTE, 0);
- return 0;
-}
-
-static int ssm2602_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
-
- if (dir == SND_SOC_CLOCK_IN) {
- if (clk_id != SSM2602_SYSCLK)
- return -EINVAL;
-
- switch (freq) {
- case 11289600:
- case 12000000:
- case 12288000:
- case 16934400:
- case 18432000:
- ssm2602->sysclk = freq;
- break;
- default:
- return -EINVAL;
- }
- } else {
- unsigned int mask;
-
- switch (clk_id) {
- case SSM2602_CLK_CLKOUT:
- mask = PWR_CLK_OUT_PDN;
- break;
- case SSM2602_CLK_XTO:
- mask = PWR_OSC_PDN;
- break;
- default:
- return -EINVAL;
- }
-
- if (freq == 0)
- ssm2602->clk_out_pwr |= mask;
- else
- ssm2602->clk_out_pwr &= ~mask;
-
- snd_soc_update_bits(codec, SSM2602_PWR,
- PWR_CLK_OUT_PDN | PWR_OSC_PDN, ssm2602->clk_out_pwr);
- }
-
- return 0;
-}
-
-static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 iface = 0;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- iface |= 0x0040;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= 0x0002;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= 0x0001;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= 0x0013;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- iface |= 0x0003;
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= 0x0090;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= 0x0080;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- iface |= 0x0010;
- break;
- default:
- return -EINVAL;
- }
-
- /* set iface */
- snd_soc_write(codec, SSM2602_IFACE, iface);
- return 0;
-}
-
-static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- /* vref/mid on, osc and clkout on if enabled */
- snd_soc_update_bits(codec, SSM2602_PWR,
- PWR_POWER_OFF | PWR_CLK_OUT_PDN | PWR_OSC_PDN,
- ssm2602->clk_out_pwr);
- break;
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- /* everything off except vref/vmid, */
- snd_soc_update_bits(codec, SSM2602_PWR,
- PWR_POWER_OFF | PWR_CLK_OUT_PDN | PWR_OSC_PDN,
- PWR_CLK_OUT_PDN | PWR_OSC_PDN);
- break;
- case SND_SOC_BIAS_OFF:
- /* everything off */
- snd_soc_update_bits(codec, SSM2602_PWR,
- PWR_POWER_OFF, PWR_POWER_OFF);
- break;
-
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_32000 |\
- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
- SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
-
-#define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops ssm2602_dai_ops = {
- .startup = ssm2602_startup,
- .hw_params = ssm2602_hw_params,
- .shutdown = ssm2602_shutdown,
- .digital_mute = ssm2602_mute,
- .set_sysclk = ssm2602_set_dai_sysclk,
- .set_fmt = ssm2602_set_dai_fmt,
-};
-
-static struct snd_soc_dai_driver ssm2602_dai = {
- .name = "ssm2602-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SSM2602_RATES,
- .formats = SSM2602_FORMATS,},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SSM2602_RATES,
- .formats = SSM2602_FORMATS,},
- .ops = &ssm2602_dai_ops,
-};
-
-static int ssm2602_suspend(struct snd_soc_codec *codec)
-{
- ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int ssm2602_resume(struct snd_soc_codec *codec)
-{
- snd_soc_cache_sync(codec);
-
- ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-
-static int ssm2602_probe(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret;
-
- snd_soc_update_bits(codec, SSM2602_LOUT1V,
- LOUT1V_LRHP_BOTH, LOUT1V_LRHP_BOTH);
- snd_soc_update_bits(codec, SSM2602_ROUT1V,
- ROUT1V_RLHP_BOTH, ROUT1V_RLHP_BOTH);
-
- ret = snd_soc_add_codec_controls(codec, ssm2602_snd_controls,
- ARRAY_SIZE(ssm2602_snd_controls));
- if (ret)
- return ret;
-
- ret = snd_soc_dapm_new_controls(dapm, ssm2602_dapm_widgets,
- ARRAY_SIZE(ssm2602_dapm_widgets));
- if (ret)
- return ret;
-
- return snd_soc_dapm_add_routes(dapm, ssm2602_routes,
- ARRAY_SIZE(ssm2602_routes));
-}
-
-static int ssm2604_probe(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret;
-
- ret = snd_soc_dapm_new_controls(dapm, ssm2604_dapm_widgets,
- ARRAY_SIZE(ssm2604_dapm_widgets));
- if (ret)
- return ret;
-
- return snd_soc_dapm_add_routes(dapm, ssm2604_routes,
- ARRAY_SIZE(ssm2604_routes));
-}
-
-static int ssm260x_probe(struct snd_soc_codec *codec)
-{
- struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION);
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, ssm2602->control_type);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- ret = ssm2602_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
- return ret;
- }
-
- /* set the update bits */
- snd_soc_update_bits(codec, SSM2602_LINVOL,
- LINVOL_LRIN_BOTH, LINVOL_LRIN_BOTH);
- snd_soc_update_bits(codec, SSM2602_RINVOL,
- RINVOL_RLIN_BOTH, RINVOL_RLIN_BOTH);
- /*select Line in as default input*/
- snd_soc_write(codec, SSM2602_APANA, APANA_SELECT_DAC |
- APANA_ENABLE_MIC_BOOST);
-
- switch (ssm2602->type) {
- case SSM2602:
- ret = ssm2602_probe(codec);
- break;
- case SSM2604:
- ret = ssm2604_probe(codec);
- break;
- }
-
- if (ret)
- return ret;
-
- ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-
-/* remove everything here */
-static int ssm2602_remove(struct snd_soc_codec *codec)
-{
- ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = {
- .probe = ssm260x_probe,
- .remove = ssm2602_remove,
- .suspend = ssm2602_suspend,
- .resume = ssm2602_resume,
- .set_bias_level = ssm2602_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(ssm2602_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = ssm2602_reg,
-
- .controls = ssm260x_snd_controls,
- .num_controls = ARRAY_SIZE(ssm260x_snd_controls),
- .dapm_widgets = ssm260x_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(ssm260x_dapm_widgets),
- .dapm_routes = ssm260x_routes,
- .num_dapm_routes = ARRAY_SIZE(ssm260x_routes),
-};
-
-#if defined(CONFIG_SPI_MASTER)
-static int __devinit ssm2602_spi_probe(struct spi_device *spi)
-{
- struct ssm2602_priv *ssm2602;
- int ret;
-
- ssm2602 = devm_kzalloc(&spi->dev, sizeof(struct ssm2602_priv),
- GFP_KERNEL);
- if (ssm2602 == NULL)
- return -ENOMEM;
-
- spi_set_drvdata(spi, ssm2602);
- ssm2602->control_type = SND_SOC_SPI;
- ssm2602->type = SSM2602;
-
- ret = snd_soc_register_codec(&spi->dev,
- &soc_codec_dev_ssm2602, &ssm2602_dai, 1);
- return ret;
-}
-
-static int __devexit ssm2602_spi_remove(struct spi_device *spi)
-{
- snd_soc_unregister_codec(&spi->dev);
- return 0;
-}
-
-static struct spi_driver ssm2602_spi_driver = {
- .driver = {
- .name = "ssm2602",
- .owner = THIS_MODULE,
- },
- .probe = ssm2602_spi_probe,
- .remove = __devexit_p(ssm2602_spi_remove),
-};
-#endif
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-/*
- * ssm2602 2 wire address is determined by GPIO5
- * state during powerup.
- * low = 0x1a
- * high = 0x1b
- */
-static int __devinit ssm2602_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct ssm2602_priv *ssm2602;
- int ret;
-
- ssm2602 = devm_kzalloc(&i2c->dev, sizeof(struct ssm2602_priv),
- GFP_KERNEL);
- if (ssm2602 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, ssm2602);
- ssm2602->control_type = SND_SOC_I2C;
- ssm2602->type = id->driver_data;
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_ssm2602, &ssm2602_dai, 1);
- return ret;
-}
-
-static int __devexit ssm2602_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static const struct i2c_device_id ssm2602_i2c_id[] = {
- { "ssm2602", SSM2602 },
- { "ssm2603", SSM2602 },
- { "ssm2604", SSM2604 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id);
-
-/* corgi i2c codec control layer */
-static struct i2c_driver ssm2602_i2c_driver = {
- .driver = {
- .name = "ssm2602",
- .owner = THIS_MODULE,
- },
- .probe = ssm2602_i2c_probe,
- .remove = __devexit_p(ssm2602_i2c_remove),
- .id_table = ssm2602_i2c_id,
-};
-#endif
-
-
-static int __init ssm2602_modinit(void)
-{
- int ret = 0;
-
-#if defined(CONFIG_SPI_MASTER)
- ret = spi_register_driver(&ssm2602_spi_driver);
- if (ret)
- return ret;
-#endif
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&ssm2602_i2c_driver);
- if (ret)
- return ret;
-#endif
-
- return ret;
-}
-module_init(ssm2602_modinit);
-
-static void __exit ssm2602_exit(void)
-{
-#if defined(CONFIG_SPI_MASTER)
- spi_unregister_driver(&ssm2602_spi_driver);
-#endif
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&ssm2602_i2c_driver);
-#endif
-}
-module_exit(ssm2602_exit);
-
-MODULE_DESCRIPTION("ASoC SSM2602/SSM2603/SSM2604 driver");
-MODULE_AUTHOR("Cliff Cai");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/ssm2602.h b/ANDROID_3.4.5/sound/soc/codecs/ssm2602.h
deleted file mode 100644
index fbd07d7b..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/ssm2602.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * File: sound/soc/codecs/ssm2602.h
- * Author: Cliff Cai <Cliff.Cai@analog.com>
- *
- * Created: Tue June 06 2008
- *
- * Modified:
- * Copyright 2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _SSM2602_H
-#define _SSM2602_H
-
-/* SSM2602 Codec Register definitions */
-
-#define SSM2602_LINVOL 0x00
-#define SSM2602_RINVOL 0x01
-#define SSM2602_LOUT1V 0x02
-#define SSM2602_ROUT1V 0x03
-#define SSM2602_APANA 0x04
-#define SSM2602_APDIGI 0x05
-#define SSM2602_PWR 0x06
-#define SSM2602_IFACE 0x07
-#define SSM2602_SRATE 0x08
-#define SSM2602_ACTIVE 0x09
-#define SSM2602_RESET 0x0f
-
-/*SSM2602 Codec Register Field definitions
- *(Mask value to extract the corresponding Register field)
- */
-
-/*Left ADC Volume Control (SSM2602_REG_LEFT_ADC_VOL)*/
-#define LINVOL_LIN_VOL 0x01F /* Left Channel PGA Volume control */
-#define LINVOL_LIN_ENABLE_MUTE 0x080 /* Left Channel Input Mute */
-#define LINVOL_LRIN_BOTH 0x100 /* Left Channel Line Input Volume update */
-
-/*Right ADC Volume Control (SSM2602_REG_RIGHT_ADC_VOL)*/
-#define RINVOL_RIN_VOL 0x01F /* Right Channel PGA Volume control */
-#define RINVOL_RIN_ENABLE_MUTE 0x080 /* Right Channel Input Mute */
-#define RINVOL_RLIN_BOTH 0x100 /* Right Channel Line Input Volume update */
-
-/*Left DAC Volume Control (SSM2602_REG_LEFT_DAC_VOL)*/
-#define LOUT1V_LHP_VOL 0x07F /* Left Channel Headphone volume control */
-#define LOUT1V_ENABLE_LZC 0x080 /* Left Channel Zero cross detect enable */
-#define LOUT1V_LRHP_BOTH 0x100 /* Left Channel Headphone volume update */
-
-/*Right DAC Volume Control (SSM2602_REG_RIGHT_DAC_VOL)*/
-#define ROUT1V_RHP_VOL 0x07F /* Right Channel Headphone volume control */
-#define ROUT1V_ENABLE_RZC 0x080 /* Right Channel Zero cross detect enable */
-#define ROUT1V_RLHP_BOTH 0x100 /* Right Channel Headphone volume update */
-
-/*Analogue Audio Path Control (SSM2602_REG_ANALOGUE_PATH)*/
-#define APANA_ENABLE_MIC_BOOST 0x001 /* Primary Microphone Amplifier gain booster control */
-#define APANA_ENABLE_MIC_MUTE 0x002 /* Microphone Mute Control */
-#define APANA_ADC_IN_SELECT 0x004 /* Microphone/Line IN select to ADC (1=MIC, 0=Line In) */
-#define APANA_ENABLE_BYPASS 0x008 /* Line input bypass to line output */
-#define APANA_SELECT_DAC 0x010 /* Select DAC (1=Select DAC, 0=Don't Select DAC) */
-#define APANA_ENABLE_SIDETONE 0x020 /* Enable/Disable Side Tone */
-#define APANA_SIDETONE_ATTN 0x0C0 /* Side Tone Attenuation */
-#define APANA_ENABLE_MIC_BOOST2 0x100 /* Secondary Microphone Amplifier gain booster control */
-
-/*Digital Audio Path Control (SSM2602_REG_DIGITAL_PATH)*/
-#define APDIGI_ENABLE_ADC_HPF 0x001 /* Enable/Disable ADC Highpass Filter */
-#define APDIGI_DE_EMPHASIS 0x006 /* De-Emphasis Control */
-#define APDIGI_ENABLE_DAC_MUTE 0x008 /* DAC Mute Control */
-#define APDIGI_STORE_OFFSET 0x010 /* Store/Clear DC offset when HPF is disabled */
-
-/*Power Down Control (SSM2602_REG_POWER)
- *(1=Enable PowerDown, 0=Disable PowerDown)
- */
-#define PWR_LINE_IN_PDN 0x001 /* Line Input Power Down */
-#define PWR_MIC_PDN 0x002 /* Microphone Input & Bias Power Down */
-#define PWR_ADC_PDN 0x004 /* ADC Power Down */
-#define PWR_DAC_PDN 0x008 /* DAC Power Down */
-#define PWR_OUT_PDN 0x010 /* Outputs Power Down */
-#define PWR_OSC_PDN 0x020 /* Oscillator Power Down */
-#define PWR_CLK_OUT_PDN 0x040 /* CLKOUT Power Down */
-#define PWR_POWER_OFF 0x080 /* POWEROFF Mode */
-
-/*Digital Audio Interface Format (SSM2602_REG_DIGITAL_IFACE)*/
-#define IFACE_IFACE_FORMAT 0x003 /* Digital Audio input format control */
-#define IFACE_AUDIO_DATA_LEN 0x00C /* Audio Data word length control */
-#define IFACE_DAC_LR_POLARITY 0x010 /* Polarity Control for clocks in RJ,LJ and I2S modes */
-#define IFACE_DAC_LR_SWAP 0x020 /* Swap DAC data control */
-#define IFACE_ENABLE_MASTER 0x040 /* Enable/Disable Master Mode */
-#define IFACE_BCLK_INVERT 0x080 /* Bit Clock Inversion control */
-
-/*Sampling Control (SSM2602_REG_SAMPLING_CTRL)*/
-#define SRATE_ENABLE_USB_MODE 0x001 /* Enable/Disable USB Mode */
-#define SRATE_BOS_RATE 0x002 /* Base Over-Sampling rate */
-#define SRATE_SAMPLE_RATE 0x03C /* Clock setting condition (Sampling rate control) */
-#define SRATE_CORECLK_DIV2 0x040 /* Core Clock divider select */
-#define SRATE_CLKOUT_DIV2 0x080 /* Clock Out divider select */
-
-/*Active Control (SSM2602_REG_ACTIVE_CTRL)*/
-#define ACTIVE_ACTIVATE_CODEC 0x001 /* Activate Codec Digital Audio Interface */
-
-/*********************************************************************/
-
-#define SSM2602_CACHEREGNUM 10
-
-enum ssm2602_clk {
- SSM2602_SYSCLK,
- SSM2602_CLK_CLKOUT,
- SSM2602_CLK_XTO
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/sta32x.c b/ANDROID_3.4.5/sound/soc/codecs/sta32x.c
deleted file mode 100644
index 7db6fa51..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/sta32x.c
+++ /dev/null
@@ -1,1024 +0,0 @@
-/*
- * Codec driver for ST STA32x 2.1-channel high-efficiency digital audio system
- *
- * Copyright: 2011 Raumfeld GmbH
- * Author: Johannes Stezenbach <js@sig21.net>
- *
- * based on code from:
- * Wolfson Microelectronics PLC.
- * Mark Brown <broonie@opensource.wolfsonmicro.com>
- * Freescale Semiconductor, Inc.
- * Timur Tabi <timur@freescale.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s:%d: " fmt, __func__, __LINE__
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include <sound/sta32x.h>
-#include "sta32x.h"
-
-#define STA32X_RATES (SNDRV_PCM_RATE_32000 | \
- SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000 | \
- SNDRV_PCM_RATE_88200 | \
- SNDRV_PCM_RATE_96000 | \
- SNDRV_PCM_RATE_176400 | \
- SNDRV_PCM_RATE_192000)
-
-#define STA32X_FORMATS \
- (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
- SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
- SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
- SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE | \
- SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)
-
-/* Power-up register defaults */
-static const u8 sta32x_regs[STA32X_REGISTER_COUNT] = {
- 0x63, 0x80, 0xc2, 0x40, 0xc2, 0x5c, 0x10, 0xff, 0x60, 0x60,
- 0x60, 0x80, 0x00, 0x00, 0x00, 0x40, 0x80, 0x77, 0x6a, 0x69,
- 0x6a, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
- 0xc0, 0xf3, 0x33, 0x00, 0x0c,
-};
-
-/* regulator power supply names */
-static const char *sta32x_supply_names[] = {
- "Vdda", /* analog supply, 3.3VV */
- "Vdd3", /* digital supply, 3.3V */
- "Vcc" /* power amp spply, 10V - 36V */
-};
-
-/* codec private data */
-struct sta32x_priv {
- struct regulator_bulk_data supplies[ARRAY_SIZE(sta32x_supply_names)];
- struct snd_soc_codec *codec;
- struct sta32x_platform_data *pdata;
-
- unsigned int mclk;
- unsigned int format;
-
- u32 coef_shadow[STA32X_COEF_COUNT];
- struct delayed_work watchdog_work;
- int shutdown;
-};
-
-static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12700, 50, 1);
-static const DECLARE_TLV_DB_SCALE(chvol_tlv, -7950, 50, 1);
-static const DECLARE_TLV_DB_SCALE(tone_tlv, -120, 200, 0);
-
-static const char *sta32x_drc_ac[] = {
- "Anti-Clipping", "Dynamic Range Compression" };
-static const char *sta32x_auto_eq_mode[] = {
- "User", "Preset", "Loudness" };
-static const char *sta32x_auto_gc_mode[] = {
- "User", "AC no clipping", "AC limited clipping (10%)",
- "DRC nighttime listening mode" };
-static const char *sta32x_auto_xo_mode[] = {
- "User", "80Hz", "100Hz", "120Hz", "140Hz", "160Hz", "180Hz", "200Hz",
- "220Hz", "240Hz", "260Hz", "280Hz", "300Hz", "320Hz", "340Hz", "360Hz" };
-static const char *sta32x_preset_eq_mode[] = {
- "Flat", "Rock", "Soft Rock", "Jazz", "Classical", "Dance", "Pop", "Soft",
- "Hard", "Party", "Vocal", "Hip-Hop", "Dialog", "Bass-boost #1",
- "Bass-boost #2", "Bass-boost #3", "Loudness 1", "Loudness 2",
- "Loudness 3", "Loudness 4", "Loudness 5", "Loudness 6", "Loudness 7",
- "Loudness 8", "Loudness 9", "Loudness 10", "Loudness 11", "Loudness 12",
- "Loudness 13", "Loudness 14", "Loudness 15", "Loudness 16" };
-static const char *sta32x_limiter_select[] = {
- "Limiter Disabled", "Limiter #1", "Limiter #2" };
-static const char *sta32x_limiter_attack_rate[] = {
- "3.1584", "2.7072", "2.2560", "1.8048", "1.3536", "0.9024",
- "0.4512", "0.2256", "0.1504", "0.1123", "0.0902", "0.0752",
- "0.0645", "0.0564", "0.0501", "0.0451" };
-static const char *sta32x_limiter_release_rate[] = {
- "0.5116", "0.1370", "0.0744", "0.0499", "0.0360", "0.0299",
- "0.0264", "0.0208", "0.0198", "0.0172", "0.0147", "0.0137",
- "0.0134", "0.0117", "0.0110", "0.0104" };
-
-static const unsigned int sta32x_limiter_ac_attack_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 7, TLV_DB_SCALE_ITEM(-1200, 200, 0),
- 8, 16, TLV_DB_SCALE_ITEM(300, 100, 0),
-};
-
-static const unsigned int sta32x_limiter_ac_release_tlv[] = {
- TLV_DB_RANGE_HEAD(5),
- 0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0),
- 1, 1, TLV_DB_SCALE_ITEM(-2900, 0, 0),
- 2, 2, TLV_DB_SCALE_ITEM(-2000, 0, 0),
- 3, 8, TLV_DB_SCALE_ITEM(-1400, 200, 0),
- 8, 16, TLV_DB_SCALE_ITEM(-700, 100, 0),
-};
-
-static const unsigned int sta32x_limiter_drc_attack_tlv[] = {
- TLV_DB_RANGE_HEAD(3),
- 0, 7, TLV_DB_SCALE_ITEM(-3100, 200, 0),
- 8, 13, TLV_DB_SCALE_ITEM(-1600, 100, 0),
- 14, 16, TLV_DB_SCALE_ITEM(-1000, 300, 0),
-};
-
-static const unsigned int sta32x_limiter_drc_release_tlv[] = {
- TLV_DB_RANGE_HEAD(5),
- 0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0),
- 1, 2, TLV_DB_SCALE_ITEM(-3800, 200, 0),
- 3, 4, TLV_DB_SCALE_ITEM(-3300, 200, 0),
- 5, 12, TLV_DB_SCALE_ITEM(-3000, 200, 0),
- 13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0),
-};
-
-static const struct soc_enum sta32x_drc_ac_enum =
- SOC_ENUM_SINGLE(STA32X_CONFD, STA32X_CONFD_DRC_SHIFT,
- 2, sta32x_drc_ac);
-static const struct soc_enum sta32x_auto_eq_enum =
- SOC_ENUM_SINGLE(STA32X_AUTO1, STA32X_AUTO1_AMEQ_SHIFT,
- 3, sta32x_auto_eq_mode);
-static const struct soc_enum sta32x_auto_gc_enum =
- SOC_ENUM_SINGLE(STA32X_AUTO1, STA32X_AUTO1_AMGC_SHIFT,
- 4, sta32x_auto_gc_mode);
-static const struct soc_enum sta32x_auto_xo_enum =
- SOC_ENUM_SINGLE(STA32X_AUTO2, STA32X_AUTO2_XO_SHIFT,
- 16, sta32x_auto_xo_mode);
-static const struct soc_enum sta32x_preset_eq_enum =
- SOC_ENUM_SINGLE(STA32X_AUTO3, STA32X_AUTO3_PEQ_SHIFT,
- 32, sta32x_preset_eq_mode);
-static const struct soc_enum sta32x_limiter_ch1_enum =
- SOC_ENUM_SINGLE(STA32X_C1CFG, STA32X_CxCFG_LS_SHIFT,
- 3, sta32x_limiter_select);
-static const struct soc_enum sta32x_limiter_ch2_enum =
- SOC_ENUM_SINGLE(STA32X_C2CFG, STA32X_CxCFG_LS_SHIFT,
- 3, sta32x_limiter_select);
-static const struct soc_enum sta32x_limiter_ch3_enum =
- SOC_ENUM_SINGLE(STA32X_C3CFG, STA32X_CxCFG_LS_SHIFT,
- 3, sta32x_limiter_select);
-static const struct soc_enum sta32x_limiter1_attack_rate_enum =
- SOC_ENUM_SINGLE(STA32X_L1AR, STA32X_LxA_SHIFT,
- 16, sta32x_limiter_attack_rate);
-static const struct soc_enum sta32x_limiter2_attack_rate_enum =
- SOC_ENUM_SINGLE(STA32X_L2AR, STA32X_LxA_SHIFT,
- 16, sta32x_limiter_attack_rate);
-static const struct soc_enum sta32x_limiter1_release_rate_enum =
- SOC_ENUM_SINGLE(STA32X_L1AR, STA32X_LxR_SHIFT,
- 16, sta32x_limiter_release_rate);
-static const struct soc_enum sta32x_limiter2_release_rate_enum =
- SOC_ENUM_SINGLE(STA32X_L2AR, STA32X_LxR_SHIFT,
- 16, sta32x_limiter_release_rate);
-
-/* byte array controls for setting biquad, mixer, scaling coefficients;
- * for biquads all five coefficients need to be set in one go,
- * mixer and pre/postscale coefs can be set individually;
- * each coef is 24bit, the bytes are ordered in the same way
- * as given in the STA32x data sheet (big endian; b1, b2, a1, a2, b0)
- */
-
-static int sta32x_coefficient_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int numcoef = kcontrol->private_value >> 16;
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
- uinfo->count = 3 * numcoef;
- return 0;
-}
-
-static int sta32x_coefficient_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- int numcoef = kcontrol->private_value >> 16;
- int index = kcontrol->private_value & 0xffff;
- unsigned int cfud;
- int i;
-
- /* preserve reserved bits in STA32X_CFUD */
- cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0;
- /* chip documentation does not say if the bits are self clearing,
- * so do it explicitly */
- snd_soc_write(codec, STA32X_CFUD, cfud);
-
- snd_soc_write(codec, STA32X_CFADDR2, index);
- if (numcoef == 1)
- snd_soc_write(codec, STA32X_CFUD, cfud | 0x04);
- else if (numcoef == 5)
- snd_soc_write(codec, STA32X_CFUD, cfud | 0x08);
- else
- return -EINVAL;
- for (i = 0; i < 3 * numcoef; i++)
- ucontrol->value.bytes.data[i] =
- snd_soc_read(codec, STA32X_B1CF1 + i);
-
- return 0;
-}
-
-static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
- int numcoef = kcontrol->private_value >> 16;
- int index = kcontrol->private_value & 0xffff;
- unsigned int cfud;
- int i;
-
- /* preserve reserved bits in STA32X_CFUD */
- cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0;
- /* chip documentation does not say if the bits are self clearing,
- * so do it explicitly */
- snd_soc_write(codec, STA32X_CFUD, cfud);
-
- snd_soc_write(codec, STA32X_CFADDR2, index);
- for (i = 0; i < numcoef && (index + i < STA32X_COEF_COUNT); i++)
- sta32x->coef_shadow[index + i] =
- (ucontrol->value.bytes.data[3 * i] << 16)
- | (ucontrol->value.bytes.data[3 * i + 1] << 8)
- | (ucontrol->value.bytes.data[3 * i + 2]);
- for (i = 0; i < 3 * numcoef; i++)
- snd_soc_write(codec, STA32X_B1CF1 + i,
- ucontrol->value.bytes.data[i]);
- if (numcoef == 1)
- snd_soc_write(codec, STA32X_CFUD, cfud | 0x01);
- else if (numcoef == 5)
- snd_soc_write(codec, STA32X_CFUD, cfud | 0x02);
- else
- return -EINVAL;
-
- return 0;
-}
-
-static int sta32x_sync_coef_shadow(struct snd_soc_codec *codec)
-{
- struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
- unsigned int cfud;
- int i;
-
- /* preserve reserved bits in STA32X_CFUD */
- cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0;
-
- for (i = 0; i < STA32X_COEF_COUNT; i++) {
- snd_soc_write(codec, STA32X_CFADDR2, i);
- snd_soc_write(codec, STA32X_B1CF1,
- (sta32x->coef_shadow[i] >> 16) & 0xff);
- snd_soc_write(codec, STA32X_B1CF2,
- (sta32x->coef_shadow[i] >> 8) & 0xff);
- snd_soc_write(codec, STA32X_B1CF3,
- (sta32x->coef_shadow[i]) & 0xff);
- /* chip documentation does not say if the bits are
- * self-clearing, so do it explicitly */
- snd_soc_write(codec, STA32X_CFUD, cfud);
- snd_soc_write(codec, STA32X_CFUD, cfud | 0x01);
- }
- return 0;
-}
-
-static int sta32x_cache_sync(struct snd_soc_codec *codec)
-{
- unsigned int mute;
- int rc;
-
- if (!codec->cache_sync)
- return 0;
-
- /* mute during register sync */
- mute = snd_soc_read(codec, STA32X_MMUTE);
- snd_soc_write(codec, STA32X_MMUTE, mute | STA32X_MMUTE_MMUTE);
- sta32x_sync_coef_shadow(codec);
- rc = snd_soc_cache_sync(codec);
- snd_soc_write(codec, STA32X_MMUTE, mute);
- return rc;
-}
-
-/* work around ESD issue where sta32x resets and loses all configuration */
-static void sta32x_watchdog(struct work_struct *work)
-{
- struct sta32x_priv *sta32x = container_of(work, struct sta32x_priv,
- watchdog_work.work);
- struct snd_soc_codec *codec = sta32x->codec;
- unsigned int confa, confa_cached;
-
- /* check if sta32x has reset itself */
- confa_cached = snd_soc_read(codec, STA32X_CONFA);
- codec->cache_bypass = 1;
- confa = snd_soc_read(codec, STA32X_CONFA);
- codec->cache_bypass = 0;
- if (confa != confa_cached) {
- codec->cache_sync = 1;
- sta32x_cache_sync(codec);
- }
-
- if (!sta32x->shutdown)
- schedule_delayed_work(&sta32x->watchdog_work,
- round_jiffies_relative(HZ));
-}
-
-static void sta32x_watchdog_start(struct sta32x_priv *sta32x)
-{
- if (sta32x->pdata->needs_esd_watchdog) {
- sta32x->shutdown = 0;
- schedule_delayed_work(&sta32x->watchdog_work,
- round_jiffies_relative(HZ));
- }
-}
-
-static void sta32x_watchdog_stop(struct sta32x_priv *sta32x)
-{
- if (sta32x->pdata->needs_esd_watchdog) {
- sta32x->shutdown = 1;
- cancel_delayed_work_sync(&sta32x->watchdog_work);
- }
-}
-
-#define SINGLE_COEF(xname, index) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = sta32x_coefficient_info, \
- .get = sta32x_coefficient_get,\
- .put = sta32x_coefficient_put, \
- .private_value = index | (1 << 16) }
-
-#define BIQUAD_COEFS(xname, index) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = sta32x_coefficient_info, \
- .get = sta32x_coefficient_get,\
- .put = sta32x_coefficient_put, \
- .private_value = index | (5 << 16) }
-
-static const struct snd_kcontrol_new sta32x_snd_controls[] = {
-SOC_SINGLE_TLV("Master Volume", STA32X_MVOL, 0, 0xff, 1, mvol_tlv),
-SOC_SINGLE("Master Switch", STA32X_MMUTE, 0, 1, 1),
-SOC_SINGLE("Ch1 Switch", STA32X_MMUTE, 1, 1, 1),
-SOC_SINGLE("Ch2 Switch", STA32X_MMUTE, 2, 1, 1),
-SOC_SINGLE("Ch3 Switch", STA32X_MMUTE, 3, 1, 1),
-SOC_SINGLE_TLV("Ch1 Volume", STA32X_C1VOL, 0, 0xff, 1, chvol_tlv),
-SOC_SINGLE_TLV("Ch2 Volume", STA32X_C2VOL, 0, 0xff, 1, chvol_tlv),
-SOC_SINGLE_TLV("Ch3 Volume", STA32X_C3VOL, 0, 0xff, 1, chvol_tlv),
-SOC_SINGLE("De-emphasis Filter Switch", STA32X_CONFD, STA32X_CONFD_DEMP_SHIFT, 1, 0),
-SOC_ENUM("Compressor/Limiter Switch", sta32x_drc_ac_enum),
-SOC_SINGLE("Miami Mode Switch", STA32X_CONFD, STA32X_CONFD_MME_SHIFT, 1, 0),
-SOC_SINGLE("Zero Cross Switch", STA32X_CONFE, STA32X_CONFE_ZCE_SHIFT, 1, 0),
-SOC_SINGLE("Soft Ramp Switch", STA32X_CONFE, STA32X_CONFE_SVE_SHIFT, 1, 0),
-SOC_SINGLE("Auto-Mute Switch", STA32X_CONFF, STA32X_CONFF_IDE_SHIFT, 1, 0),
-SOC_ENUM("Automode EQ", sta32x_auto_eq_enum),
-SOC_ENUM("Automode GC", sta32x_auto_gc_enum),
-SOC_ENUM("Automode XO", sta32x_auto_xo_enum),
-SOC_ENUM("Preset EQ", sta32x_preset_eq_enum),
-SOC_SINGLE("Ch1 Tone Control Bypass Switch", STA32X_C1CFG, STA32X_CxCFG_TCB_SHIFT, 1, 0),
-SOC_SINGLE("Ch2 Tone Control Bypass Switch", STA32X_C2CFG, STA32X_CxCFG_TCB_SHIFT, 1, 0),
-SOC_SINGLE("Ch1 EQ Bypass Switch", STA32X_C1CFG, STA32X_CxCFG_EQBP_SHIFT, 1, 0),
-SOC_SINGLE("Ch2 EQ Bypass Switch", STA32X_C2CFG, STA32X_CxCFG_EQBP_SHIFT, 1, 0),
-SOC_SINGLE("Ch1 Master Volume Bypass Switch", STA32X_C1CFG, STA32X_CxCFG_VBP_SHIFT, 1, 0),
-SOC_SINGLE("Ch2 Master Volume Bypass Switch", STA32X_C1CFG, STA32X_CxCFG_VBP_SHIFT, 1, 0),
-SOC_SINGLE("Ch3 Master Volume Bypass Switch", STA32X_C1CFG, STA32X_CxCFG_VBP_SHIFT, 1, 0),
-SOC_ENUM("Ch1 Limiter Select", sta32x_limiter_ch1_enum),
-SOC_ENUM("Ch2 Limiter Select", sta32x_limiter_ch2_enum),
-SOC_ENUM("Ch3 Limiter Select", sta32x_limiter_ch3_enum),
-SOC_SINGLE_TLV("Bass Tone Control", STA32X_TONE, STA32X_TONE_BTC_SHIFT, 15, 0, tone_tlv),
-SOC_SINGLE_TLV("Treble Tone Control", STA32X_TONE, STA32X_TONE_TTC_SHIFT, 15, 0, tone_tlv),
-SOC_ENUM("Limiter1 Attack Rate (dB/ms)", sta32x_limiter1_attack_rate_enum),
-SOC_ENUM("Limiter2 Attack Rate (dB/ms)", sta32x_limiter2_attack_rate_enum),
-SOC_ENUM("Limiter1 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum),
-SOC_ENUM("Limiter2 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum),
-
-/* depending on mode, the attack/release thresholds have
- * two different enum definitions; provide both
- */
-SOC_SINGLE_TLV("Limiter1 Attack Threshold (AC Mode)", STA32X_L1ATRT, STA32X_LxA_SHIFT,
- 16, 0, sta32x_limiter_ac_attack_tlv),
-SOC_SINGLE_TLV("Limiter2 Attack Threshold (AC Mode)", STA32X_L2ATRT, STA32X_LxA_SHIFT,
- 16, 0, sta32x_limiter_ac_attack_tlv),
-SOC_SINGLE_TLV("Limiter1 Release Threshold (AC Mode)", STA32X_L1ATRT, STA32X_LxR_SHIFT,
- 16, 0, sta32x_limiter_ac_release_tlv),
-SOC_SINGLE_TLV("Limiter2 Release Threshold (AC Mode)", STA32X_L2ATRT, STA32X_LxR_SHIFT,
- 16, 0, sta32x_limiter_ac_release_tlv),
-SOC_SINGLE_TLV("Limiter1 Attack Threshold (DRC Mode)", STA32X_L1ATRT, STA32X_LxA_SHIFT,
- 16, 0, sta32x_limiter_drc_attack_tlv),
-SOC_SINGLE_TLV("Limiter2 Attack Threshold (DRC Mode)", STA32X_L2ATRT, STA32X_LxA_SHIFT,
- 16, 0, sta32x_limiter_drc_attack_tlv),
-SOC_SINGLE_TLV("Limiter1 Release Threshold (DRC Mode)", STA32X_L1ATRT, STA32X_LxR_SHIFT,
- 16, 0, sta32x_limiter_drc_release_tlv),
-SOC_SINGLE_TLV("Limiter2 Release Threshold (DRC Mode)", STA32X_L2ATRT, STA32X_LxR_SHIFT,
- 16, 0, sta32x_limiter_drc_release_tlv),
-
-BIQUAD_COEFS("Ch1 - Biquad 1", 0),
-BIQUAD_COEFS("Ch1 - Biquad 2", 5),
-BIQUAD_COEFS("Ch1 - Biquad 3", 10),
-BIQUAD_COEFS("Ch1 - Biquad 4", 15),
-BIQUAD_COEFS("Ch2 - Biquad 1", 20),
-BIQUAD_COEFS("Ch2 - Biquad 2", 25),
-BIQUAD_COEFS("Ch2 - Biquad 3", 30),
-BIQUAD_COEFS("Ch2 - Biquad 4", 35),
-BIQUAD_COEFS("High-pass", 40),
-BIQUAD_COEFS("Low-pass", 45),
-SINGLE_COEF("Ch1 - Prescale", 50),
-SINGLE_COEF("Ch2 - Prescale", 51),
-SINGLE_COEF("Ch1 - Postscale", 52),
-SINGLE_COEF("Ch2 - Postscale", 53),
-SINGLE_COEF("Ch3 - Postscale", 54),
-SINGLE_COEF("Thermal warning - Postscale", 55),
-SINGLE_COEF("Ch1 - Mix 1", 56),
-SINGLE_COEF("Ch1 - Mix 2", 57),
-SINGLE_COEF("Ch2 - Mix 1", 58),
-SINGLE_COEF("Ch2 - Mix 2", 59),
-SINGLE_COEF("Ch3 - Mix 1", 60),
-SINGLE_COEF("Ch3 - Mix 2", 61),
-};
-
-static const struct snd_soc_dapm_widget sta32x_dapm_widgets[] = {
-SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_OUTPUT("LEFT"),
-SND_SOC_DAPM_OUTPUT("RIGHT"),
-SND_SOC_DAPM_OUTPUT("SUB"),
-};
-
-static const struct snd_soc_dapm_route sta32x_dapm_routes[] = {
- { "LEFT", NULL, "DAC" },
- { "RIGHT", NULL, "DAC" },
- { "SUB", NULL, "DAC" },
-};
-
-/* MCLK interpolation ratio per fs */
-static struct {
- int fs;
- int ir;
-} interpolation_ratios[] = {
- { 32000, 0 },
- { 44100, 0 },
- { 48000, 0 },
- { 88200, 1 },
- { 96000, 1 },
- { 176400, 2 },
- { 192000, 2 },
-};
-
-/* MCLK to fs clock ratios */
-static struct {
- int ratio;
- int mcs;
-} mclk_ratios[3][7] = {
- { { 768, 0 }, { 512, 1 }, { 384, 2 }, { 256, 3 },
- { 128, 4 }, { 576, 5 }, { 0, 0 } },
- { { 384, 2 }, { 256, 3 }, { 192, 4 }, { 128, 5 }, {64, 0 }, { 0, 0 } },
- { { 384, 2 }, { 256, 3 }, { 192, 4 }, { 128, 5 }, {64, 0 }, { 0, 0 } },
-};
-
-
-/**
- * sta32x_set_dai_sysclk - configure MCLK
- * @codec_dai: the codec DAI
- * @clk_id: the clock ID (ignored)
- * @freq: the MCLK input frequency
- * @dir: the clock direction (ignored)
- *
- * The value of MCLK is used to determine which sample rates are supported
- * by the STA32X, based on the mclk_ratios table.
- *
- * This function must be called by the machine driver's 'startup' function,
- * otherwise the list of supported sample rates will not be available in
- * time for ALSA.
- *
- * For setups with variable MCLKs, pass 0 as 'freq' argument. This will cause
- * theoretically possible sample rates to be enabled. Call it again with a
- * proper value set one the external clock is set (most probably you would do
- * that from a machine's driver 'hw_param' hook.
- */
-static int sta32x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
- int i, j, ir, fs;
- unsigned int rates = 0;
- unsigned int rate_min = -1;
- unsigned int rate_max = 0;
-
- pr_debug("mclk=%u\n", freq);
- sta32x->mclk = freq;
-
- if (sta32x->mclk) {
- for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) {
- ir = interpolation_ratios[i].ir;
- fs = interpolation_ratios[i].fs;
- for (j = 0; mclk_ratios[ir][j].ratio; j++) {
- if (mclk_ratios[ir][j].ratio * fs == freq) {
- rates |= snd_pcm_rate_to_rate_bit(fs);
- if (fs < rate_min)
- rate_min = fs;
- if (fs > rate_max)
- rate_max = fs;
- break;
- }
- }
- }
- /* FIXME: soc should support a rate list */
- rates &= ~SNDRV_PCM_RATE_KNOT;
-
- if (!rates) {
- dev_err(codec->dev, "could not find a valid sample rate\n");
- return -EINVAL;
- }
- } else {
- /* enable all possible rates */
- rates = STA32X_RATES;
- rate_min = 32000;
- rate_max = 192000;
- }
-
- codec_dai->driver->playback.rates = rates;
- codec_dai->driver->playback.rate_min = rate_min;
- codec_dai->driver->playback.rate_max = rate_max;
- return 0;
-}
-
-/**
- * sta32x_set_dai_fmt - configure the codec for the selected audio format
- * @codec_dai: the codec DAI
- * @fmt: a SND_SOC_DAIFMT_x value indicating the data format
- *
- * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the
- * codec accordingly.
- */
-static int sta32x_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
- u8 confb = snd_soc_read(codec, STA32X_CONFB);
-
- pr_debug("\n");
- confb &= ~(STA32X_CONFB_C1IM | STA32X_CONFB_C2IM);
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- case SND_SOC_DAIFMT_RIGHT_J:
- case SND_SOC_DAIFMT_LEFT_J:
- sta32x->format = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- confb |= STA32X_CONFB_C2IM;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- confb |= STA32X_CONFB_C1IM;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, STA32X_CONFB, confb);
- return 0;
-}
-
-/**
- * sta32x_hw_params - program the STA32X with the given hardware parameters.
- * @substream: the audio stream
- * @params: the hardware parameters to set
- * @dai: the SOC DAI (ignored)
- *
- * This function programs the hardware with the values provided.
- * Specifically, the sample rate and the data format.
- */
-static int sta32x_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
- unsigned int rate;
- int i, mcs = -1, ir = -1;
- u8 confa, confb;
-
- rate = params_rate(params);
- pr_debug("rate: %u\n", rate);
- for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++)
- if (interpolation_ratios[i].fs == rate) {
- ir = interpolation_ratios[i].ir;
- break;
- }
- if (ir < 0)
- return -EINVAL;
- for (i = 0; mclk_ratios[ir][i].ratio; i++)
- if (mclk_ratios[ir][i].ratio * rate == sta32x->mclk) {
- mcs = mclk_ratios[ir][i].mcs;
- break;
- }
- if (mcs < 0)
- return -EINVAL;
-
- confa = snd_soc_read(codec, STA32X_CONFA);
- confa &= ~(STA32X_CONFA_MCS_MASK | STA32X_CONFA_IR_MASK);
- confa |= (ir << STA32X_CONFA_IR_SHIFT) | (mcs << STA32X_CONFA_MCS_SHIFT);
-
- confb = snd_soc_read(codec, STA32X_CONFB);
- confb &= ~(STA32X_CONFB_SAI_MASK | STA32X_CONFB_SAIFB);
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S24_LE:
- case SNDRV_PCM_FORMAT_S24_BE:
- case SNDRV_PCM_FORMAT_S24_3LE:
- case SNDRV_PCM_FORMAT_S24_3BE:
- pr_debug("24bit\n");
- /* fall through */
- case SNDRV_PCM_FORMAT_S32_LE:
- case SNDRV_PCM_FORMAT_S32_BE:
- pr_debug("24bit or 32bit\n");
- switch (sta32x->format) {
- case SND_SOC_DAIFMT_I2S:
- confb |= 0x0;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- confb |= 0x1;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- confb |= 0x2;
- break;
- }
-
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- case SNDRV_PCM_FORMAT_S20_3BE:
- pr_debug("20bit\n");
- switch (sta32x->format) {
- case SND_SOC_DAIFMT_I2S:
- confb |= 0x4;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- confb |= 0x5;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- confb |= 0x6;
- break;
- }
-
- break;
- case SNDRV_PCM_FORMAT_S18_3LE:
- case SNDRV_PCM_FORMAT_S18_3BE:
- pr_debug("18bit\n");
- switch (sta32x->format) {
- case SND_SOC_DAIFMT_I2S:
- confb |= 0x8;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- confb |= 0x9;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- confb |= 0xa;
- break;
- }
-
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- case SNDRV_PCM_FORMAT_S16_BE:
- pr_debug("16bit\n");
- switch (sta32x->format) {
- case SND_SOC_DAIFMT_I2S:
- confb |= 0x0;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- confb |= 0xd;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- confb |= 0xe;
- break;
- }
-
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, STA32X_CONFA, confa);
- snd_soc_write(codec, STA32X_CONFB, confb);
- return 0;
-}
-
-/**
- * sta32x_set_bias_level - DAPM callback
- * @codec: the codec device
- * @level: DAPM power level
- *
- * This is called by ALSA to put the codec into low power mode
- * or to wake it up. If the codec is powered off completely
- * all registers must be restored after power on.
- */
-static int sta32x_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- int ret;
- struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
-
- pr_debug("level = %d\n", level);
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- /* Full power on */
- snd_soc_update_bits(codec, STA32X_CONFF,
- STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,
- STA32X_CONFF_PWDN | STA32X_CONFF_EAPD);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),
- sta32x->supplies);
- if (ret != 0) {
- dev_err(codec->dev,
- "Failed to enable supplies: %d\n", ret);
- return ret;
- }
-
- sta32x_cache_sync(codec);
- sta32x_watchdog_start(sta32x);
- }
-
- /* Power up to mute */
- /* FIXME */
- snd_soc_update_bits(codec, STA32X_CONFF,
- STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,
- STA32X_CONFF_PWDN | STA32X_CONFF_EAPD);
-
- break;
-
- case SND_SOC_BIAS_OFF:
- /* The chip runs through the power down sequence for us. */
- snd_soc_update_bits(codec, STA32X_CONFF,
- STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,
- STA32X_CONFF_PWDN);
- msleep(300);
- sta32x_watchdog_stop(sta32x);
- regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies),
- sta32x->supplies);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-static const struct snd_soc_dai_ops sta32x_dai_ops = {
- .hw_params = sta32x_hw_params,
- .set_sysclk = sta32x_set_dai_sysclk,
- .set_fmt = sta32x_set_dai_fmt,
-};
-
-static struct snd_soc_dai_driver sta32x_dai = {
- .name = "STA32X",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = STA32X_RATES,
- .formats = STA32X_FORMATS,
- },
- .ops = &sta32x_dai_ops,
-};
-
-#ifdef CONFIG_PM
-static int sta32x_suspend(struct snd_soc_codec *codec)
-{
- sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int sta32x_resume(struct snd_soc_codec *codec)
-{
- sta32x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-#else
-#define sta32x_suspend NULL
-#define sta32x_resume NULL
-#endif
-
-static int sta32x_probe(struct snd_soc_codec *codec)
-{
- struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
- int i, ret = 0, thermal = 0;
-
- sta32x->codec = codec;
- sta32x->pdata = dev_get_platdata(codec->dev);
-
- /* regulators */
- for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++)
- sta32x->supplies[i].supply = sta32x_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sta32x->supplies),
- sta32x->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- goto err;
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),
- sta32x->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
- goto err_get;
- }
-
- /* Tell ASoC what kind of I/O to use to read the registers. ASoC will
- * then do the I2C transactions itself.
- */
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
- if (ret < 0) {
- dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret);
- return ret;
- }
-
- /* Chip documentation explicitly requires that the reset values
- * of reserved register bits are left untouched.
- * Write the register default value to cache for reserved registers,
- * so the write to the these registers are suppressed by the cache
- * restore code when it skips writes of default registers.
- */
- snd_soc_cache_write(codec, STA32X_CONFC, 0xc2);
- snd_soc_cache_write(codec, STA32X_CONFE, 0xc2);
- snd_soc_cache_write(codec, STA32X_CONFF, 0x5c);
- snd_soc_cache_write(codec, STA32X_MMUTE, 0x10);
- snd_soc_cache_write(codec, STA32X_AUTO1, 0x60);
- snd_soc_cache_write(codec, STA32X_AUTO3, 0x00);
- snd_soc_cache_write(codec, STA32X_C3CFG, 0x40);
-
- /* set thermal warning adjustment and recovery */
- if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_ADJUSTMENT_ENABLE))
- thermal |= STA32X_CONFA_TWAB;
- if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_RECOVERY_ENABLE))
- thermal |= STA32X_CONFA_TWRB;
- snd_soc_update_bits(codec, STA32X_CONFA,
- STA32X_CONFA_TWAB | STA32X_CONFA_TWRB,
- thermal);
-
- /* select output configuration */
- snd_soc_update_bits(codec, STA32X_CONFF,
- STA32X_CONFF_OCFG_MASK,
- sta32x->pdata->output_conf
- << STA32X_CONFF_OCFG_SHIFT);
-
- /* channel to output mapping */
- snd_soc_update_bits(codec, STA32X_C1CFG,
- STA32X_CxCFG_OM_MASK,
- sta32x->pdata->ch1_output_mapping
- << STA32X_CxCFG_OM_SHIFT);
- snd_soc_update_bits(codec, STA32X_C2CFG,
- STA32X_CxCFG_OM_MASK,
- sta32x->pdata->ch2_output_mapping
- << STA32X_CxCFG_OM_SHIFT);
- snd_soc_update_bits(codec, STA32X_C3CFG,
- STA32X_CxCFG_OM_MASK,
- sta32x->pdata->ch3_output_mapping
- << STA32X_CxCFG_OM_SHIFT);
-
- /* initialize coefficient shadow RAM with reset values */
- for (i = 4; i <= 49; i += 5)
- sta32x->coef_shadow[i] = 0x400000;
- for (i = 50; i <= 54; i++)
- sta32x->coef_shadow[i] = 0x7fffff;
- sta32x->coef_shadow[55] = 0x5a9df7;
- sta32x->coef_shadow[56] = 0x7fffff;
- sta32x->coef_shadow[59] = 0x7fffff;
- sta32x->coef_shadow[60] = 0x400000;
- sta32x->coef_shadow[61] = 0x400000;
-
- if (sta32x->pdata->needs_esd_watchdog)
- INIT_DELAYED_WORK(&sta32x->watchdog_work, sta32x_watchdog);
-
- sta32x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- /* Bias level configuration will have done an extra enable */
- regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
-
- return 0;
-
-err_get:
- regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
-err:
- return ret;
-}
-
-static int sta32x_remove(struct snd_soc_codec *codec)
-{
- struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
-
- sta32x_watchdog_stop(sta32x);
- sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
- regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
- regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
-
- return 0;
-}
-
-static int sta32x_reg_is_volatile(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- switch (reg) {
- case STA32X_CONFA ... STA32X_L2ATRT:
- case STA32X_MPCC1 ... STA32X_FDRC2:
- return 0;
- }
- return 1;
-}
-
-static const struct snd_soc_codec_driver sta32x_codec = {
- .probe = sta32x_probe,
- .remove = sta32x_remove,
- .suspend = sta32x_suspend,
- .resume = sta32x_resume,
- .reg_cache_size = STA32X_REGISTER_COUNT,
- .reg_word_size = sizeof(u8),
- .reg_cache_default = sta32x_regs,
- .volatile_register = sta32x_reg_is_volatile,
- .set_bias_level = sta32x_set_bias_level,
- .controls = sta32x_snd_controls,
- .num_controls = ARRAY_SIZE(sta32x_snd_controls),
- .dapm_widgets = sta32x_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(sta32x_dapm_widgets),
- .dapm_routes = sta32x_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(sta32x_dapm_routes),
-};
-
-static __devinit int sta32x_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct sta32x_priv *sta32x;
- int ret;
-
- sta32x = devm_kzalloc(&i2c->dev, sizeof(struct sta32x_priv),
- GFP_KERNEL);
- if (!sta32x)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, sta32x);
-
- ret = snd_soc_register_codec(&i2c->dev, &sta32x_codec, &sta32x_dai, 1);
- if (ret != 0)
- dev_err(&i2c->dev, "Failed to register codec (%d)\n", ret);
-
- return ret;
-}
-
-static __devexit int sta32x_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static const struct i2c_device_id sta32x_i2c_id[] = {
- { "sta326", 0 },
- { "sta328", 0 },
- { "sta329", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, sta32x_i2c_id);
-
-static struct i2c_driver sta32x_i2c_driver = {
- .driver = {
- .name = "sta32x",
- .owner = THIS_MODULE,
- },
- .probe = sta32x_i2c_probe,
- .remove = __devexit_p(sta32x_i2c_remove),
- .id_table = sta32x_i2c_id,
-};
-
-static int __init sta32x_init(void)
-{
- return i2c_add_driver(&sta32x_i2c_driver);
-}
-module_init(sta32x_init);
-
-static void __exit sta32x_exit(void)
-{
- i2c_del_driver(&sta32x_i2c_driver);
-}
-module_exit(sta32x_exit);
-
-MODULE_DESCRIPTION("ASoC STA32X driver");
-MODULE_AUTHOR("Johannes Stezenbach <js@sig21.net>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/sta32x.h b/ANDROID_3.4.5/sound/soc/codecs/sta32x.h
deleted file mode 100644
index d8e32a62..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/sta32x.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Codec driver for ST STA32x 2.1-channel high-efficiency digital audio system
- *
- * Copyright: 2011 Raumfeld GmbH
- * Author: Johannes Stezenbach <js@sig21.net>
- *
- * based on code from:
- * Wolfson Microelectronics PLC.
- * Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-#ifndef _ASOC_STA_32X_H
-#define _ASOC_STA_32X_H
-
-/* STA326 register addresses */
-
-#define STA32X_REGISTER_COUNT 0x2d
-#define STA32X_COEF_COUNT 62
-
-#define STA32X_CONFA 0x00
-#define STA32X_CONFB 0x01
-#define STA32X_CONFC 0x02
-#define STA32X_CONFD 0x03
-#define STA32X_CONFE 0x04
-#define STA32X_CONFF 0x05
-#define STA32X_MMUTE 0x06
-#define STA32X_MVOL 0x07
-#define STA32X_C1VOL 0x08
-#define STA32X_C2VOL 0x09
-#define STA32X_C3VOL 0x0a
-#define STA32X_AUTO1 0x0b
-#define STA32X_AUTO2 0x0c
-#define STA32X_AUTO3 0x0d
-#define STA32X_C1CFG 0x0e
-#define STA32X_C2CFG 0x0f
-#define STA32X_C3CFG 0x10
-#define STA32X_TONE 0x11
-#define STA32X_L1AR 0x12
-#define STA32X_L1ATRT 0x13
-#define STA32X_L2AR 0x14
-#define STA32X_L2ATRT 0x15
-#define STA32X_CFADDR2 0x16
-#define STA32X_B1CF1 0x17
-#define STA32X_B1CF2 0x18
-#define STA32X_B1CF3 0x19
-#define STA32X_B2CF1 0x1a
-#define STA32X_B2CF2 0x1b
-#define STA32X_B2CF3 0x1c
-#define STA32X_A1CF1 0x1d
-#define STA32X_A1CF2 0x1e
-#define STA32X_A1CF3 0x1f
-#define STA32X_A2CF1 0x20
-#define STA32X_A2CF2 0x21
-#define STA32X_A2CF3 0x22
-#define STA32X_B0CF1 0x23
-#define STA32X_B0CF2 0x24
-#define STA32X_B0CF3 0x25
-#define STA32X_CFUD 0x26
-#define STA32X_MPCC1 0x27
-#define STA32X_MPCC2 0x28
-/* Reserved 0x29 */
-/* Reserved 0x2a */
-#define STA32X_Reserved 0x2a
-#define STA32X_FDRC1 0x2b
-#define STA32X_FDRC2 0x2c
-/* Reserved 0x2d */
-
-
-/* STA326 register field definitions */
-
-/* 0x00 CONFA */
-#define STA32X_CONFA_MCS_MASK 0x03
-#define STA32X_CONFA_MCS_SHIFT 0
-#define STA32X_CONFA_IR_MASK 0x18
-#define STA32X_CONFA_IR_SHIFT 3
-#define STA32X_CONFA_TWRB 0x20
-#define STA32X_CONFA_TWAB 0x40
-#define STA32X_CONFA_FDRB 0x80
-
-/* 0x01 CONFB */
-#define STA32X_CONFB_SAI_MASK 0x0f
-#define STA32X_CONFB_SAI_SHIFT 0
-#define STA32X_CONFB_SAIFB 0x10
-#define STA32X_CONFB_DSCKE 0x20
-#define STA32X_CONFB_C1IM 0x40
-#define STA32X_CONFB_C2IM 0x80
-
-/* 0x02 CONFC */
-#define STA32X_CONFC_OM_MASK 0x03
-#define STA32X_CONFC_OM_SHIFT 0
-#define STA32X_CONFC_CSZ_MASK 0x7c
-#define STA32X_CONFC_CSZ_SHIFT 2
-
-/* 0x03 CONFD */
-#define STA32X_CONFD_HPB 0x01
-#define STA32X_CONFD_HPB_SHIFT 0
-#define STA32X_CONFD_DEMP 0x02
-#define STA32X_CONFD_DEMP_SHIFT 1
-#define STA32X_CONFD_DSPB 0x04
-#define STA32X_CONFD_DSPB_SHIFT 2
-#define STA32X_CONFD_PSL 0x08
-#define STA32X_CONFD_PSL_SHIFT 3
-#define STA32X_CONFD_BQL 0x10
-#define STA32X_CONFD_BQL_SHIFT 4
-#define STA32X_CONFD_DRC 0x20
-#define STA32X_CONFD_DRC_SHIFT 5
-#define STA32X_CONFD_ZDE 0x40
-#define STA32X_CONFD_ZDE_SHIFT 6
-#define STA32X_CONFD_MME 0x80
-#define STA32X_CONFD_MME_SHIFT 7
-
-/* 0x04 CONFE */
-#define STA32X_CONFE_MPCV 0x01
-#define STA32X_CONFE_MPCV_SHIFT 0
-#define STA32X_CONFE_MPC 0x02
-#define STA32X_CONFE_MPC_SHIFT 1
-#define STA32X_CONFE_AME 0x08
-#define STA32X_CONFE_AME_SHIFT 3
-#define STA32X_CONFE_PWMS 0x10
-#define STA32X_CONFE_PWMS_SHIFT 4
-#define STA32X_CONFE_ZCE 0x40
-#define STA32X_CONFE_ZCE_SHIFT 6
-#define STA32X_CONFE_SVE 0x80
-#define STA32X_CONFE_SVE_SHIFT 7
-
-/* 0x05 CONFF */
-#define STA32X_CONFF_OCFG_MASK 0x03
-#define STA32X_CONFF_OCFG_SHIFT 0
-#define STA32X_CONFF_IDE 0x04
-#define STA32X_CONFF_IDE_SHIFT 3
-#define STA32X_CONFF_BCLE 0x08
-#define STA32X_CONFF_ECLE 0x20
-#define STA32X_CONFF_PWDN 0x40
-#define STA32X_CONFF_EAPD 0x80
-
-/* 0x06 MMUTE */
-#define STA32X_MMUTE_MMUTE 0x01
-
-/* 0x0b AUTO1 */
-#define STA32X_AUTO1_AMEQ_MASK 0x03
-#define STA32X_AUTO1_AMEQ_SHIFT 0
-#define STA32X_AUTO1_AMV_MASK 0xc0
-#define STA32X_AUTO1_AMV_SHIFT 2
-#define STA32X_AUTO1_AMGC_MASK 0x30
-#define STA32X_AUTO1_AMGC_SHIFT 4
-#define STA32X_AUTO1_AMPS 0x80
-
-/* 0x0c AUTO2 */
-#define STA32X_AUTO2_AMAME 0x01
-#define STA32X_AUTO2_AMAM_MASK 0x0e
-#define STA32X_AUTO2_AMAM_SHIFT 1
-#define STA32X_AUTO2_XO_MASK 0xf0
-#define STA32X_AUTO2_XO_SHIFT 4
-
-/* 0x0d AUTO3 */
-#define STA32X_AUTO3_PEQ_MASK 0x1f
-#define STA32X_AUTO3_PEQ_SHIFT 0
-
-/* 0x0e 0x0f 0x10 CxCFG */
-#define STA32X_CxCFG_TCB 0x01 /* only C1 and C2 */
-#define STA32X_CxCFG_TCB_SHIFT 0
-#define STA32X_CxCFG_EQBP 0x02 /* only C1 and C2 */
-#define STA32X_CxCFG_EQBP_SHIFT 1
-#define STA32X_CxCFG_VBP 0x03
-#define STA32X_CxCFG_VBP_SHIFT 2
-#define STA32X_CxCFG_BO 0x04
-#define STA32X_CxCFG_LS_MASK 0x30
-#define STA32X_CxCFG_LS_SHIFT 4
-#define STA32X_CxCFG_OM_MASK 0xc0
-#define STA32X_CxCFG_OM_SHIFT 6
-
-/* 0x11 TONE */
-#define STA32X_TONE_BTC_SHIFT 0
-#define STA32X_TONE_TTC_SHIFT 4
-
-/* 0x12 0x13 0x14 0x15 limiter attack/release */
-#define STA32X_LxA_SHIFT 0
-#define STA32X_LxR_SHIFT 4
-
-/* 0x26 CFUD */
-#define STA32X_CFUD_W1 0x01
-#define STA32X_CFUD_WA 0x02
-#define STA32X_CFUD_R1 0x04
-#define STA32X_CFUD_RA 0x08
-
-
-/* biquad filter coefficient table offsets */
-#define STA32X_C1_BQ_BASE 0
-#define STA32X_C2_BQ_BASE 20
-#define STA32X_CH_BQ_NUM 4
-#define STA32X_BQ_NUM_COEF 5
-#define STA32X_XO_HP_BQ_BASE 40
-#define STA32X_XO_LP_BQ_BASE 45
-#define STA32X_C1_PRESCALE 50
-#define STA32X_C2_PRESCALE 51
-#define STA32X_C1_POSTSCALE 52
-#define STA32X_C2_POSTSCALE 53
-#define STA32X_C3_POSTSCALE 54
-#define STA32X_TW_POSTSCALE 55
-#define STA32X_C1_MIX1 56
-#define STA32X_C1_MIX2 57
-#define STA32X_C2_MIX1 58
-#define STA32X_C2_MIX2 59
-#define STA32X_C3_MIX1 60
-#define STA32X_C3_MIX2 61
-
-#endif /* _ASOC_STA_32X_H */
diff --git a/ANDROID_3.4.5/sound/soc/codecs/stac9766.c b/ANDROID_3.4.5/sound/soc/codecs/stac9766.c
deleted file mode 100644
index 982e4377..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/stac9766.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * stac9766.c -- ALSA SoC STAC9766 codec support
- *
- * Copyright 2009 Jon Smirl, Digispeaker
- * Author: Jon Smirl <jonsmirl@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * Features:-
- *
- * o Support for AC97 Codec, S/PDIF
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/tlv.h>
-
-#include "stac9766.h"
-
-#define STAC9766_VERSION "0.10"
-
-/*
- * STAC9766 register cache
- */
-static const u16 stac9766_reg[] = {
- 0x6A90, 0x8000, 0x8000, 0x8000, /* 6 */
- 0x0000, 0x0000, 0x8008, 0x8008, /* e */
- 0x8808, 0x8808, 0x8808, 0x8808, /* 16 */
- 0x8808, 0x0000, 0x8000, 0x0000, /* 1e */
- 0x0000, 0x0000, 0x0000, 0x000f, /* 26 */
- 0x0a05, 0x0400, 0xbb80, 0x0000, /* 2e */
- 0x0000, 0xbb80, 0x0000, 0x0000, /* 36 */
- 0x0000, 0x2000, 0x0000, 0x0100, /* 3e */
- 0x0000, 0x0000, 0x0080, 0x0000, /* 46 */
- 0x0000, 0x0000, 0x0003, 0xffff, /* 4e */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 56 */
- 0x4000, 0x0000, 0x0000, 0x0000, /* 5e */
- 0x1201, 0xFFFF, 0xFFFF, 0x0000, /* 66 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 6e */
- 0x0000, 0x0000, 0x0000, 0x0006, /* 76 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 7e */
-};
-
-static const char *stac9766_record_mux[] = {"Mic", "CD", "Video", "AUX",
- "Line", "Stereo Mix", "Mono Mix", "Phone"};
-static const char *stac9766_mono_mux[] = {"Mix", "Mic"};
-static const char *stac9766_mic_mux[] = {"Mic1", "Mic2"};
-static const char *stac9766_SPDIF_mux[] = {"PCM", "ADC Record"};
-static const char *stac9766_popbypass_mux[] = {"Normal", "Bypass Mixer"};
-static const char *stac9766_record_all_mux[] = {"All analog",
- "Analog plus DAC"};
-static const char *stac9766_boost1[] = {"0dB", "10dB"};
-static const char *stac9766_boost2[] = {"0dB", "20dB"};
-static const char *stac9766_stereo_mic[] = {"Off", "On"};
-
-static const struct soc_enum stac9766_record_enum =
- SOC_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 8, stac9766_record_mux);
-static const struct soc_enum stac9766_mono_enum =
- SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 9, 2, stac9766_mono_mux);
-static const struct soc_enum stac9766_mic_enum =
- SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 8, 2, stac9766_mic_mux);
-static const struct soc_enum stac9766_SPDIF_enum =
- SOC_ENUM_SINGLE(AC97_STAC_DA_CONTROL, 1, 2, stac9766_SPDIF_mux);
-static const struct soc_enum stac9766_popbypass_enum =
- SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, stac9766_popbypass_mux);
-static const struct soc_enum stac9766_record_all_enum =
- SOC_ENUM_SINGLE(AC97_STAC_ANALOG_SPECIAL, 12, 2,
- stac9766_record_all_mux);
-static const struct soc_enum stac9766_boost1_enum =
- SOC_ENUM_SINGLE(AC97_MIC, 6, 2, stac9766_boost1); /* 0/10dB */
-static const struct soc_enum stac9766_boost2_enum =
- SOC_ENUM_SINGLE(AC97_STAC_ANALOG_SPECIAL, 2, 2, stac9766_boost2); /* 0/20dB */
-static const struct soc_enum stac9766_stereo_mic_enum =
- SOC_ENUM_SINGLE(AC97_STAC_STEREO_MIC, 2, 1, stac9766_stereo_mic);
-
-static const DECLARE_TLV_DB_LINEAR(master_tlv, -4600, 0);
-static const DECLARE_TLV_DB_LINEAR(record_tlv, 0, 2250);
-static const DECLARE_TLV_DB_LINEAR(beep_tlv, -4500, 0);
-static const DECLARE_TLV_DB_LINEAR(mix_tlv, -3450, 1200);
-
-static const struct snd_kcontrol_new stac9766_snd_ac97_controls[] = {
- SOC_DOUBLE_TLV("Speaker Volume", AC97_MASTER, 8, 0, 31, 1, master_tlv),
- SOC_SINGLE("Speaker Switch", AC97_MASTER, 15, 1, 1),
- SOC_DOUBLE_TLV("Headphone Volume", AC97_HEADPHONE, 8, 0, 31, 1,
- master_tlv),
- SOC_SINGLE("Headphone Switch", AC97_HEADPHONE, 15, 1, 1),
- SOC_SINGLE_TLV("Mono Out Volume", AC97_MASTER_MONO, 0, 31, 1,
- master_tlv),
- SOC_SINGLE("Mono Out Switch", AC97_MASTER_MONO, 15, 1, 1),
-
- SOC_DOUBLE_TLV("Record Volume", AC97_REC_GAIN, 8, 0, 15, 0, record_tlv),
- SOC_SINGLE("Record Switch", AC97_REC_GAIN, 15, 1, 1),
-
-
- SOC_SINGLE_TLV("Beep Volume", AC97_PC_BEEP, 1, 15, 1, beep_tlv),
- SOC_SINGLE("Beep Switch", AC97_PC_BEEP, 15, 1, 1),
- SOC_SINGLE("Beep Frequency", AC97_PC_BEEP, 5, 127, 1),
- SOC_SINGLE_TLV("Phone Volume", AC97_PHONE, 0, 31, 1, mix_tlv),
- SOC_SINGLE("Phone Switch", AC97_PHONE, 15, 1, 1),
-
- SOC_ENUM("Mic Boost1", stac9766_boost1_enum),
- SOC_ENUM("Mic Boost2", stac9766_boost2_enum),
- SOC_SINGLE_TLV("Mic Volume", AC97_MIC, 0, 31, 1, mix_tlv),
- SOC_SINGLE("Mic Switch", AC97_MIC, 15, 1, 1),
- SOC_ENUM("Stereo Mic", stac9766_stereo_mic_enum),
-
- SOC_DOUBLE_TLV("Line Volume", AC97_LINE, 8, 0, 31, 1, mix_tlv),
- SOC_SINGLE("Line Switch", AC97_LINE, 15, 1, 1),
- SOC_DOUBLE_TLV("CD Volume", AC97_CD, 8, 0, 31, 1, mix_tlv),
- SOC_SINGLE("CD Switch", AC97_CD, 15, 1, 1),
- SOC_DOUBLE_TLV("AUX Volume", AC97_AUX, 8, 0, 31, 1, mix_tlv),
- SOC_SINGLE("AUX Switch", AC97_AUX, 15, 1, 1),
- SOC_DOUBLE_TLV("Video Volume", AC97_VIDEO, 8, 0, 31, 1, mix_tlv),
- SOC_SINGLE("Video Switch", AC97_VIDEO, 15, 1, 1),
-
- SOC_DOUBLE_TLV("DAC Volume", AC97_PCM, 8, 0, 31, 1, mix_tlv),
- SOC_SINGLE("DAC Switch", AC97_PCM, 15, 1, 1),
- SOC_SINGLE("Loopback Test Switch", AC97_GENERAL_PURPOSE, 7, 1, 0),
- SOC_SINGLE("3D Volume", AC97_3D_CONTROL, 3, 2, 1),
- SOC_SINGLE("3D Switch", AC97_GENERAL_PURPOSE, 13, 1, 0),
-
- SOC_ENUM("SPDIF Mux", stac9766_SPDIF_enum),
- SOC_ENUM("Mic1/2 Mux", stac9766_mic_enum),
- SOC_ENUM("Record All Mux", stac9766_record_all_enum),
- SOC_ENUM("Record Mux", stac9766_record_enum),
- SOC_ENUM("Mono Mux", stac9766_mono_enum),
- SOC_ENUM("Pop Bypass Mux", stac9766_popbypass_enum),
-};
-
-static int stac9766_ac97_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int val)
-{
- u16 *cache = codec->reg_cache;
-
- if (reg > AC97_STAC_PAGE0) {
- stac9766_ac97_write(codec, AC97_INT_PAGING, 0);
- soc_ac97_ops.write(codec->ac97, reg, val);
- stac9766_ac97_write(codec, AC97_INT_PAGING, 1);
- return 0;
- }
- if (reg / 2 >= ARRAY_SIZE(stac9766_reg))
- return -EIO;
-
- soc_ac97_ops.write(codec->ac97, reg, val);
- cache[reg / 2] = val;
- return 0;
-}
-
-static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- u16 val = 0, *cache = codec->reg_cache;
-
- if (reg > AC97_STAC_PAGE0) {
- stac9766_ac97_write(codec, AC97_INT_PAGING, 0);
- val = soc_ac97_ops.read(codec->ac97, reg - AC97_STAC_PAGE0);
- stac9766_ac97_write(codec, AC97_INT_PAGING, 1);
- return val;
- }
- if (reg / 2 >= ARRAY_SIZE(stac9766_reg))
- return -EIO;
-
- if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||
- reg == AC97_INT_PAGING || reg == AC97_VENDOR_ID1 ||
- reg == AC97_VENDOR_ID2) {
-
- val = soc_ac97_ops.read(codec->ac97, reg);
- return val;
- }
- return cache[reg / 2];
-}
-
-static int ac97_analog_prepare(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned short reg, vra;
-
- vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS);
-
- vra |= 0x1; /* enable variable rate audio */
- vra &= ~0x4; /* disable SPDIF output */
-
- stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- reg = AC97_PCM_FRONT_DAC_RATE;
- else
- reg = AC97_PCM_LR_ADC_RATE;
-
- return stac9766_ac97_write(codec, reg, runtime->rate);
-}
-
-static int ac97_digital_prepare(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned short reg, vra;
-
- stac9766_ac97_write(codec, AC97_SPDIF, 0x2002);
-
- vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS);
- vra |= 0x5; /* Enable VRA and SPDIF out */
-
- stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra);
-
- reg = AC97_PCM_FRONT_DAC_RATE;
-
- return stac9766_ac97_write(codec, reg, runtime->rate);
-}
-
-static int stac9766_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- switch (level) {
- case SND_SOC_BIAS_ON: /* full On */
- case SND_SOC_BIAS_PREPARE: /* partial On */
- case SND_SOC_BIAS_STANDBY: /* Off, with power */
- stac9766_ac97_write(codec, AC97_POWERDOWN, 0x0000);
- break;
- case SND_SOC_BIAS_OFF: /* Off, without power */
- /* disable everything including AC link */
- stac9766_ac97_write(codec, AC97_POWERDOWN, 0xffff);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-static int stac9766_reset(struct snd_soc_codec *codec, int try_warm)
-{
- if (try_warm && soc_ac97_ops.warm_reset) {
- soc_ac97_ops.warm_reset(codec->ac97);
- if (stac9766_ac97_read(codec, 0) == stac9766_reg[0])
- return 1;
- }
-
- soc_ac97_ops.reset(codec->ac97);
- if (soc_ac97_ops.warm_reset)
- soc_ac97_ops.warm_reset(codec->ac97);
- if (stac9766_ac97_read(codec, 0) != stac9766_reg[0])
- return -EIO;
- return 0;
-}
-
-static int stac9766_codec_suspend(struct snd_soc_codec *codec)
-{
- stac9766_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int stac9766_codec_resume(struct snd_soc_codec *codec)
-{
- u16 id, reset;
-
- reset = 0;
- /* give the codec an AC97 warm reset to start the link */
-reset:
- if (reset > 5) {
- printk(KERN_ERR "stac9766 failed to resume");
- return -EIO;
- }
- codec->ac97->bus->ops->warm_reset(codec->ac97);
- id = soc_ac97_ops.read(codec->ac97, AC97_VENDOR_ID2);
- if (id != 0x4c13) {
- stac9766_reset(codec, 0);
- reset++;
- goto reset;
- }
- stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-
-static const struct snd_soc_dai_ops stac9766_dai_ops_analog = {
- .prepare = ac97_analog_prepare,
-};
-
-static const struct snd_soc_dai_ops stac9766_dai_ops_digital = {
- .prepare = ac97_digital_prepare,
-};
-
-static struct snd_soc_dai_driver stac9766_dai[] = {
-{
- .name = "stac9766-hifi-analog",
- .ac97_control = 1,
-
- /* stream cababilities */
- .playback = {
- .stream_name = "stac9766 analog",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SND_SOC_STD_AC97_FMTS,
- },
- .capture = {
- .stream_name = "stac9766 analog",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SND_SOC_STD_AC97_FMTS,
- },
- /* alsa ops */
- .ops = &stac9766_dai_ops_analog,
-},
-{
- .name = "stac9766-hifi-IEC958",
- .ac97_control = 1,
-
- /* stream cababilities */
- .playback = {
- .stream_name = "stac9766 IEC958",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_32000 | \
- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE,
- },
- /* alsa ops */
- .ops = &stac9766_dai_ops_digital,
-}
-};
-
-static int stac9766_codec_probe(struct snd_soc_codec *codec)
-{
- int ret = 0;
-
- printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION);
-
- ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
- if (ret < 0)
- goto codec_err;
-
- /* do a cold reset for the controller and then try
- * a warm reset followed by an optional cold reset for codec */
- stac9766_reset(codec, 0);
- ret = stac9766_reset(codec, 1);
- if (ret < 0) {
- printk(KERN_ERR "Failed to reset STAC9766: AC97 link error\n");
- goto codec_err;
- }
-
- stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- snd_soc_add_codec_controls(codec, stac9766_snd_ac97_controls,
- ARRAY_SIZE(stac9766_snd_ac97_controls));
-
- return 0;
-
-codec_err:
- snd_soc_free_ac97_codec(codec);
- return ret;
-}
-
-static int stac9766_codec_remove(struct snd_soc_codec *codec)
-{
- snd_soc_free_ac97_codec(codec);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_stac9766 = {
- .write = stac9766_ac97_write,
- .read = stac9766_ac97_read,
- .set_bias_level = stac9766_set_bias_level,
- .probe = stac9766_codec_probe,
- .remove = stac9766_codec_remove,
- .suspend = stac9766_codec_suspend,
- .resume = stac9766_codec_resume,
- .reg_cache_size = ARRAY_SIZE(stac9766_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_step = 2,
- .reg_cache_default = stac9766_reg,
-};
-
-static __devinit int stac9766_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev,
- &soc_codec_dev_stac9766, stac9766_dai, ARRAY_SIZE(stac9766_dai));
-}
-
-static int __devexit stac9766_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver stac9766_codec_driver = {
- .driver = {
- .name = "stac9766-codec",
- .owner = THIS_MODULE,
- },
-
- .probe = stac9766_probe,
- .remove = __devexit_p(stac9766_remove),
-};
-
-module_platform_driver(stac9766_codec_driver);
-
-MODULE_DESCRIPTION("ASoC stac9766 driver");
-MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/stac9766.h b/ANDROID_3.4.5/sound/soc/codecs/stac9766.h
deleted file mode 100644
index c726f907..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/stac9766.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * stac9766.h -- STAC9766 Soc Audio driver
- */
-
-#ifndef _STAC9766_H
-#define _STAC9766_H
-
-#define AC97_STAC_PAGE0 0x1000
-#define AC97_STAC_DA_CONTROL (AC97_STAC_PAGE0 | 0x6A)
-#define AC97_STAC_ANALOG_SPECIAL (AC97_STAC_PAGE0 | 0x6E)
-#define AC97_STAC_STEREO_MIC 0x78
-
-/* STAC9766 DAI ID's */
-#define STAC9766_DAI_AC97_ANALOG 0
-#define STAC9766_DAI_AC97_DIGITAL 1
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/tlv320aic23.c b/ANDROID_3.4.5/sound/soc/codecs/tlv320aic23.c
deleted file mode 100644
index df1e07ff..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/tlv320aic23.c
+++ /dev/null
@@ -1,696 +0,0 @@
-/*
- * ALSA SoC TLV320AIC23 codec driver
- *
- * Author: Arun KS, <arunks@mistralsolutions.com>
- * Copyright: (C) 2008 Mistral Solutions Pvt Ltd.,
- *
- * Based on sound/soc/codecs/wm8731.c by Richard Purdie
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Notes:
- * The AIC23 is a driver for a low power stereo audio
- * codec tlv320aic23
- *
- * The machine layer should disable unsupported inputs/outputs by
- * snd_soc_dapm_disable_pin(codec, "LHPOUT"), etc.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/tlv.h>
-#include <sound/initval.h>
-
-#include "tlv320aic23.h"
-
-#define AIC23_VERSION "0.1"
-
-/*
- * AIC23 register cache
- */
-static const u16 tlv320aic23_reg[] = {
- 0x0097, 0x0097, 0x00F9, 0x00F9, /* 0 */
- 0x001A, 0x0004, 0x0007, 0x0001, /* 4 */
- 0x0020, 0x0000, 0x0000, 0x0000, /* 8 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 12 */
-};
-
-static const char *rec_src_text[] = { "Line", "Mic" };
-static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"};
-
-static const struct soc_enum rec_src_enum =
- SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text);
-
-static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls =
-SOC_DAPM_ENUM("Input Select", rec_src_enum);
-
-static const struct soc_enum tlv320aic23_rec_src =
- SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text);
-static const struct soc_enum tlv320aic23_deemph =
- SOC_ENUM_SINGLE(TLV320AIC23_DIGT, 1, 4, deemph_text);
-
-static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0);
-static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0);
-static const DECLARE_TLV_DB_SCALE(sidetone_vol_tlv, -1800, 300, 0);
-
-static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- u16 val, reg;
-
- val = (ucontrol->value.integer.value[0] & 0x07);
-
- /* linear conversion to userspace
- * 000 = -6db
- * 001 = -9db
- * 010 = -12db
- * 011 = -18db (Min)
- * 100 = 0db (Max)
- */
- val = (val >= 4) ? 4 : (3 - val);
-
- reg = snd_soc_read(codec, TLV320AIC23_ANLG) & (~0x1C0);
- snd_soc_write(codec, TLV320AIC23_ANLG, reg | (val << 6));
-
- return 0;
-}
-
-static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- u16 val;
-
- val = snd_soc_read(codec, TLV320AIC23_ANLG) & (0x1C0);
- val = val >> 6;
- val = (val >= 4) ? 4 : (3 - val);
- ucontrol->value.integer.value[0] = val;
- return 0;
-
-}
-
-static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = {
- SOC_DOUBLE_R_TLV("Digital Playback Volume", TLV320AIC23_LCHNVOL,
- TLV320AIC23_RCHNVOL, 0, 127, 0, out_gain_tlv),
- SOC_SINGLE("Digital Playback Switch", TLV320AIC23_DIGT, 3, 1, 1),
- SOC_DOUBLE_R("Line Input Switch", TLV320AIC23_LINVOL,
- TLV320AIC23_RINVOL, 7, 1, 0),
- SOC_DOUBLE_R_TLV("Line Input Volume", TLV320AIC23_LINVOL,
- TLV320AIC23_RINVOL, 0, 31, 0, input_gain_tlv),
- SOC_SINGLE("Mic Input Switch", TLV320AIC23_ANLG, 1, 1, 1),
- SOC_SINGLE("Mic Booster Switch", TLV320AIC23_ANLG, 0, 1, 0),
- SOC_SINGLE_EXT_TLV("Sidetone Volume", TLV320AIC23_ANLG, 6, 4, 0,
- snd_soc_tlv320aic23_get_volsw,
- snd_soc_tlv320aic23_put_volsw, sidetone_vol_tlv),
- SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph),
-};
-
-/* PGA Mixer controls for Line and Mic switch */
-static const struct snd_kcontrol_new tlv320aic23_output_mixer_controls[] = {
- SOC_DAPM_SINGLE("Line Bypass Switch", TLV320AIC23_ANLG, 3, 1, 0),
- SOC_DAPM_SINGLE("Mic Sidetone Switch", TLV320AIC23_ANLG, 5, 1, 0),
- SOC_DAPM_SINGLE("Playback Switch", TLV320AIC23_ANLG, 4, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
- SND_SOC_DAPM_DAC("DAC", "Playback", TLV320AIC23_PWR, 3, 1),
- SND_SOC_DAPM_ADC("ADC", "Capture", TLV320AIC23_PWR, 2, 1),
- SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0,
- &tlv320aic23_rec_src_mux_controls),
- SND_SOC_DAPM_MIXER("Output Mixer", TLV320AIC23_PWR, 4, 1,
- &tlv320aic23_output_mixer_controls[0],
- ARRAY_SIZE(tlv320aic23_output_mixer_controls)),
- SND_SOC_DAPM_PGA("Line Input", TLV320AIC23_PWR, 0, 1, NULL, 0),
- SND_SOC_DAPM_PGA("Mic Input", TLV320AIC23_PWR, 1, 1, NULL, 0),
-
- SND_SOC_DAPM_OUTPUT("LHPOUT"),
- SND_SOC_DAPM_OUTPUT("RHPOUT"),
- SND_SOC_DAPM_OUTPUT("LOUT"),
- SND_SOC_DAPM_OUTPUT("ROUT"),
-
- SND_SOC_DAPM_INPUT("LLINEIN"),
- SND_SOC_DAPM_INPUT("RLINEIN"),
-
- SND_SOC_DAPM_INPUT("MICIN"),
-};
-
-static const struct snd_soc_dapm_route tlv320aic23_intercon[] = {
- /* Output Mixer */
- {"Output Mixer", "Line Bypass Switch", "Line Input"},
- {"Output Mixer", "Playback Switch", "DAC"},
- {"Output Mixer", "Mic Sidetone Switch", "Mic Input"},
-
- /* Outputs */
- {"RHPOUT", NULL, "Output Mixer"},
- {"LHPOUT", NULL, "Output Mixer"},
- {"LOUT", NULL, "Output Mixer"},
- {"ROUT", NULL, "Output Mixer"},
-
- /* Inputs */
- {"Line Input", "NULL", "LLINEIN"},
- {"Line Input", "NULL", "RLINEIN"},
-
- {"Mic Input", "NULL", "MICIN"},
-
- /* input mux */
- {"Capture Source", "Line", "Line Input"},
- {"Capture Source", "Mic", "Mic Input"},
- {"ADC", NULL, "Capture Source"},
-
-};
-
-/* AIC23 driver data */
-struct aic23 {
- enum snd_soc_control_type control_type;
- int mclk;
- int requested_adc;
- int requested_dac;
-};
-
-/*
- * Common Crystals used
- * 11.2896 Mhz /128 = *88.2k /192 = 58.8k
- * 12.0000 Mhz /125 = *96k /136 = 88.235K
- * 12.2880 Mhz /128 = *96k /192 = 64k
- * 16.9344 Mhz /128 = 132.3k /192 = *88.2k
- * 18.4320 Mhz /128 = 144k /192 = *96k
- */
-
-/*
- * Normal BOSR 0-256/2 = 128, 1-384/2 = 192
- * USB BOSR 0-250/2 = 125, 1-272/2 = 136
- */
-static const int bosr_usb_divisor_table[] = {
- 128, 125, 192, 136
-};
-#define LOWER_GROUP ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<6) | (1<<7))
-#define UPPER_GROUP ((1<<8) | (1<<9) | (1<<10) | (1<<11) | (1<<15))
-static const unsigned short sr_valid_mask[] = {
- LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 0*/
- LOWER_GROUP, /* Usb, bosr - 0*/
- LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 1*/
- UPPER_GROUP, /* Usb, bosr - 1*/
-};
-/*
- * Every divisor is a factor of 11*12
- */
-#define SR_MULT (11*12)
-#define A(x) (SR_MULT/x)
-static const unsigned char sr_adc_mult_table[] = {
- A(2), A(2), A(12), A(12), 0, 0, A(3), A(1),
- A(2), A(2), A(11), A(11), 0, 0, 0, A(1)
-};
-static const unsigned char sr_dac_mult_table[] = {
- A(2), A(12), A(2), A(12), 0, 0, A(3), A(1),
- A(2), A(11), A(2), A(11), 0, 0, 0, A(1)
-};
-
-static unsigned get_score(int adc, int adc_l, int adc_h, int need_adc,
- int dac, int dac_l, int dac_h, int need_dac)
-{
- if ((adc >= adc_l) && (adc <= adc_h) &&
- (dac >= dac_l) && (dac <= dac_h)) {
- int diff_adc = need_adc - adc;
- int diff_dac = need_dac - dac;
- return abs(diff_adc) + abs(diff_dac);
- }
- return UINT_MAX;
-}
-
-static int find_rate(int mclk, u32 need_adc, u32 need_dac)
-{
- int i, j;
- int best_i = -1;
- int best_j = -1;
- int best_div = 0;
- unsigned best_score = UINT_MAX;
- int adc_l, adc_h, dac_l, dac_h;
-
- need_adc *= SR_MULT;
- need_dac *= SR_MULT;
- /*
- * rates given are +/- 1/32
- */
- adc_l = need_adc - (need_adc >> 5);
- adc_h = need_adc + (need_adc >> 5);
- dac_l = need_dac - (need_dac >> 5);
- dac_h = need_dac + (need_dac >> 5);
- for (i = 0; i < ARRAY_SIZE(bosr_usb_divisor_table); i++) {
- int base = mclk / bosr_usb_divisor_table[i];
- int mask = sr_valid_mask[i];
- for (j = 0; j < ARRAY_SIZE(sr_adc_mult_table);
- j++, mask >>= 1) {
- int adc;
- int dac;
- int score;
- if ((mask & 1) == 0)
- continue;
- adc = base * sr_adc_mult_table[j];
- dac = base * sr_dac_mult_table[j];
- score = get_score(adc, adc_l, adc_h, need_adc,
- dac, dac_l, dac_h, need_dac);
- if (best_score > score) {
- best_score = score;
- best_i = i;
- best_j = j;
- best_div = 0;
- }
- score = get_score((adc >> 1), adc_l, adc_h, need_adc,
- (dac >> 1), dac_l, dac_h, need_dac);
- /* prefer to have a /2 */
- if ((score != UINT_MAX) && (best_score >= score)) {
- best_score = score;
- best_i = i;
- best_j = j;
- best_div = 1;
- }
- }
- }
- return (best_j << 2) | best_i | (best_div << TLV320AIC23_CLKIN_SHIFT);
-}
-
-#ifdef DEBUG
-static void get_current_sample_rates(struct snd_soc_codec *codec, int mclk,
- u32 *sample_rate_adc, u32 *sample_rate_dac)
-{
- int src = snd_soc_read(codec, TLV320AIC23_SRATE);
- int sr = (src >> 2) & 0x0f;
- int val = (mclk / bosr_usb_divisor_table[src & 3]);
- int adc = (val * sr_adc_mult_table[sr]) / SR_MULT;
- int dac = (val * sr_dac_mult_table[sr]) / SR_MULT;
- if (src & TLV320AIC23_CLKIN_HALF) {
- adc >>= 1;
- dac >>= 1;
- }
- *sample_rate_adc = adc;
- *sample_rate_dac = dac;
-}
-#endif
-
-static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk,
- u32 sample_rate_adc, u32 sample_rate_dac)
-{
- /* Search for the right sample rate */
- int data = find_rate(mclk, sample_rate_adc, sample_rate_dac);
- if (data < 0) {
- printk(KERN_ERR "%s:Invalid rate %u,%u requested\n",
- __func__, sample_rate_adc, sample_rate_dac);
- return -EINVAL;
- }
- snd_soc_write(codec, TLV320AIC23_SRATE, data);
-#ifdef DEBUG
- {
- u32 adc, dac;
- get_current_sample_rates(codec, mclk, &adc, &dac);
- printk(KERN_DEBUG "actual samplerate = %u,%u reg=%x\n",
- adc, dac, data);
- }
-#endif
- return 0;
-}
-
-static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- u16 iface_reg;
- int ret;
- struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
- u32 sample_rate_adc = aic23->requested_adc;
- u32 sample_rate_dac = aic23->requested_dac;
- u32 sample_rate = params_rate(params);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- aic23->requested_dac = sample_rate_dac = sample_rate;
- if (!sample_rate_adc)
- sample_rate_adc = sample_rate;
- } else {
- aic23->requested_adc = sample_rate_adc = sample_rate;
- if (!sample_rate_dac)
- sample_rate_dac = sample_rate;
- }
- ret = set_sample_rate_control(codec, aic23->mclk, sample_rate_adc,
- sample_rate_dac);
- if (ret < 0)
- return ret;
-
- iface_reg = snd_soc_read(codec, TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface_reg |= (0x01 << 2);
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface_reg |= (0x02 << 2);
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- iface_reg |= (0x03 << 2);
- break;
- }
- snd_soc_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
-
- return 0;
-}
-
-static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
-
- /* set active */
- snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0001);
-
- return 0;
-}
-
-static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
-
- /* deactivate */
- if (!codec->active) {
- udelay(50);
- snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0);
- }
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- aic23->requested_dac = 0;
- else
- aic23->requested_adc = 0;
-}
-
-static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 reg;
-
- reg = snd_soc_read(codec, TLV320AIC23_DIGT);
- if (mute)
- reg |= TLV320AIC23_DACM_MUTE;
-
- else
- reg &= ~TLV320AIC23_DACM_MUTE;
-
- snd_soc_write(codec, TLV320AIC23_DIGT, reg);
-
- return 0;
-}
-
-static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 iface_reg;
-
- iface_reg = snd_soc_read(codec, TLV320AIC23_DIGT_FMT) & (~0x03);
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- iface_reg |= TLV320AIC23_MS_MASTER;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- iface_reg &= ~TLV320AIC23_MS_MASTER;
- break;
- default:
- return -EINVAL;
-
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface_reg |= TLV320AIC23_FOR_I2S;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface_reg |= TLV320AIC23_LRP_ON;
- case SND_SOC_DAIFMT_DSP_B:
- iface_reg |= TLV320AIC23_FOR_DSP;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface_reg |= TLV320AIC23_FOR_LJUST;
- break;
- default:
- return -EINVAL;
-
- }
-
- snd_soc_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
-
- return 0;
-}
-
-static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct aic23 *aic23 = snd_soc_dai_get_drvdata(codec_dai);
- aic23->mclk = freq;
- return 0;
-}
-
-static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- u16 reg = snd_soc_read(codec, TLV320AIC23_PWR) & 0x17f;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- /* vref/mid, osc on, dac unmute */
- reg &= ~(TLV320AIC23_DEVICE_PWR_OFF | TLV320AIC23_OSC_OFF | \
- TLV320AIC23_DAC_OFF);
- snd_soc_write(codec, TLV320AIC23_PWR, reg);
- break;
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- /* everything off except vref/vmid, */
- snd_soc_write(codec, TLV320AIC23_PWR,
- reg | TLV320AIC23_CLK_OFF);
- break;
- case SND_SOC_BIAS_OFF:
- /* everything off, dac mute, inactive */
- snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0);
- snd_soc_write(codec, TLV320AIC23_PWR, 0x1ff);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define AIC23_RATES SNDRV_PCM_RATE_8000_96000
-#define AIC23_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
- SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops tlv320aic23_dai_ops = {
- .prepare = tlv320aic23_pcm_prepare,
- .hw_params = tlv320aic23_hw_params,
- .shutdown = tlv320aic23_shutdown,
- .digital_mute = tlv320aic23_mute,
- .set_fmt = tlv320aic23_set_dai_fmt,
- .set_sysclk = tlv320aic23_set_dai_sysclk,
-};
-
-static struct snd_soc_dai_driver tlv320aic23_dai = {
- .name = "tlv320aic23-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = AIC23_RATES,
- .formats = AIC23_FORMATS,},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = AIC23_RATES,
- .formats = AIC23_FORMATS,},
- .ops = &tlv320aic23_dai_ops,
-};
-
-static int tlv320aic23_suspend(struct snd_soc_codec *codec)
-{
- tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int tlv320aic23_resume(struct snd_soc_codec *codec)
-{
- snd_soc_cache_sync(codec);
- tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-
-static int tlv320aic23_probe(struct snd_soc_codec *codec)
-{
- struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, aic23->control_type);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- /* Reset codec */
- snd_soc_write(codec, TLV320AIC23_RESET, 0);
-
- /* Write the register default value to cache for reserved registers,
- * so the write to the these registers are suppressed by the cache
- * restore code when it skips writes of default registers.
- */
- snd_soc_cache_write(codec, 0x0A, 0);
- snd_soc_cache_write(codec, 0x0B, 0);
- snd_soc_cache_write(codec, 0x0C, 0);
- snd_soc_cache_write(codec, 0x0D, 0);
- snd_soc_cache_write(codec, 0x0E, 0);
-
- /* power on device */
- tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- snd_soc_write(codec, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K);
-
- /* Unmute input */
- snd_soc_update_bits(codec, TLV320AIC23_LINVOL,
- TLV320AIC23_LIM_MUTED, TLV320AIC23_LRS_ENABLED);
-
- snd_soc_update_bits(codec, TLV320AIC23_RINVOL,
- TLV320AIC23_LIM_MUTED, TLV320AIC23_LRS_ENABLED);
-
- snd_soc_update_bits(codec, TLV320AIC23_ANLG,
- TLV320AIC23_BYPASS_ON | TLV320AIC23_MICM_MUTED,
- 0);
-
- /* Default output volume */
- snd_soc_write(codec, TLV320AIC23_LCHNVOL,
- TLV320AIC23_DEFAULT_OUT_VOL & TLV320AIC23_OUT_VOL_MASK);
- snd_soc_write(codec, TLV320AIC23_RCHNVOL,
- TLV320AIC23_DEFAULT_OUT_VOL & TLV320AIC23_OUT_VOL_MASK);
-
- snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x1);
-
- snd_soc_add_codec_controls(codec, tlv320aic23_snd_controls,
- ARRAY_SIZE(tlv320aic23_snd_controls));
-
- return 0;
-}
-
-static int tlv320aic23_remove(struct snd_soc_codec *codec)
-{
- tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
- .reg_cache_size = ARRAY_SIZE(tlv320aic23_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = tlv320aic23_reg,
- .probe = tlv320aic23_probe,
- .remove = tlv320aic23_remove,
- .suspend = tlv320aic23_suspend,
- .resume = tlv320aic23_resume,
- .set_bias_level = tlv320aic23_set_bias_level,
- .dapm_widgets = tlv320aic23_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
- .dapm_routes = tlv320aic23_intercon,
- .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon),
-};
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-/*
- * If the i2c layer weren't so broken, we could pass this kind of data
- * around
- */
-static int tlv320aic23_codec_probe(struct i2c_client *i2c,
- const struct i2c_device_id *i2c_id)
-{
- struct aic23 *aic23;
- int ret;
-
- if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -EINVAL;
-
- aic23 = devm_kzalloc(&i2c->dev, sizeof(struct aic23), GFP_KERNEL);
- if (aic23 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, aic23);
- aic23->control_type = SND_SOC_I2C;
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_tlv320aic23, &tlv320aic23_dai, 1);
- return ret;
-}
-static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c)
-{
- snd_soc_unregister_codec(&i2c->dev);
- return 0;
-}
-
-static const struct i2c_device_id tlv320aic23_id[] = {
- {"tlv320aic23", 0},
- {}
-};
-
-MODULE_DEVICE_TABLE(i2c, tlv320aic23_id);
-
-static struct i2c_driver tlv320aic23_i2c_driver = {
- .driver = {
- .name = "tlv320aic23-codec",
- },
- .probe = tlv320aic23_codec_probe,
- .remove = __exit_p(tlv320aic23_i2c_remove),
- .id_table = tlv320aic23_id,
-};
-
-#endif
-
-static int __init tlv320aic23_modinit(void)
-{
- int ret;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&tlv320aic23_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register TLV320AIC23 I2C driver: %d\n",
- ret);
- }
-#endif
- return ret;
-}
-module_init(tlv320aic23_modinit);
-
-static void __exit tlv320aic23_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&tlv320aic23_i2c_driver);
-#endif
-}
-module_exit(tlv320aic23_exit);
-
-MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver");
-MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/tlv320aic23.h b/ANDROID_3.4.5/sound/soc/codecs/tlv320aic23.h
deleted file mode 100644
index e804120b..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/tlv320aic23.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * ALSA SoC TLV320AIC23 codec driver
- *
- * Author: Arun KS, <arunks@mistralsolutions.com>
- * Copyright: (C) 2008 Mistral Solutions Pvt Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _TLV320AIC23_H
-#define _TLV320AIC23_H
-
-/* Codec TLV320AIC23 */
-#define TLV320AIC23_LINVOL 0x00
-#define TLV320AIC23_RINVOL 0x01
-#define TLV320AIC23_LCHNVOL 0x02
-#define TLV320AIC23_RCHNVOL 0x03
-#define TLV320AIC23_ANLG 0x04
-#define TLV320AIC23_DIGT 0x05
-#define TLV320AIC23_PWR 0x06
-#define TLV320AIC23_DIGT_FMT 0x07
-#define TLV320AIC23_SRATE 0x08
-#define TLV320AIC23_ACTIVE 0x09
-#define TLV320AIC23_RESET 0x0F
-
-/* Left (right) line input volume control register */
-#define TLV320AIC23_LRS_ENABLED 0x0100
-#define TLV320AIC23_LIM_MUTED 0x0080
-#define TLV320AIC23_LIV_DEFAULT 0x0017
-#define TLV320AIC23_LIV_MAX 0x001f
-#define TLV320AIC23_LIV_MIN 0x0000
-
-/* Left (right) channel headphone volume control register */
-#define TLV320AIC23_LZC_ON 0x0080
-#define TLV320AIC23_LHV_DEFAULT 0x0079
-#define TLV320AIC23_LHV_MAX 0x007f
-#define TLV320AIC23_LHV_MIN 0x0000
-
-/* Analog audio path control register */
-#define TLV320AIC23_STA_REG(x) ((x)<<6)
-#define TLV320AIC23_STE_ENABLED 0x0020
-#define TLV320AIC23_DAC_SELECTED 0x0010
-#define TLV320AIC23_BYPASS_ON 0x0008
-#define TLV320AIC23_INSEL_MIC 0x0004
-#define TLV320AIC23_MICM_MUTED 0x0002
-#define TLV320AIC23_MICB_20DB 0x0001
-
-/* Digital audio path control register */
-#define TLV320AIC23_DACM_MUTE 0x0008
-#define TLV320AIC23_DEEMP_32K 0x0002
-#define TLV320AIC23_DEEMP_44K 0x0004
-#define TLV320AIC23_DEEMP_48K 0x0006
-#define TLV320AIC23_ADCHP_ON 0x0001
-
-/* Power control down register */
-#define TLV320AIC23_DEVICE_PWR_OFF 0x0080
-#define TLV320AIC23_CLK_OFF 0x0040
-#define TLV320AIC23_OSC_OFF 0x0020
-#define TLV320AIC23_OUT_OFF 0x0010
-#define TLV320AIC23_DAC_OFF 0x0008
-#define TLV320AIC23_ADC_OFF 0x0004
-#define TLV320AIC23_MIC_OFF 0x0002
-#define TLV320AIC23_LINE_OFF 0x0001
-
-/* Digital audio interface register */
-#define TLV320AIC23_MS_MASTER 0x0040
-#define TLV320AIC23_LRSWAP_ON 0x0020
-#define TLV320AIC23_LRP_ON 0x0010
-#define TLV320AIC23_IWL_16 0x0000
-#define TLV320AIC23_IWL_20 0x0004
-#define TLV320AIC23_IWL_24 0x0008
-#define TLV320AIC23_IWL_32 0x000C
-#define TLV320AIC23_FOR_I2S 0x0002
-#define TLV320AIC23_FOR_DSP 0x0003
-#define TLV320AIC23_FOR_LJUST 0x0001
-
-/* Sample rate control register */
-#define TLV320AIC23_CLKOUT_HALF 0x0080
-#define TLV320AIC23_CLKIN_HALF 0x0040
-#define TLV320AIC23_BOSR_384fs 0x0002 /* BOSR_272fs in USB mode */
-#define TLV320AIC23_USB_CLK_ON 0x0001
-#define TLV320AIC23_SR_MASK 0xf
-#define TLV320AIC23_CLKOUT_SHIFT 7
-#define TLV320AIC23_CLKIN_SHIFT 6
-#define TLV320AIC23_SR_SHIFT 2
-#define TLV320AIC23_BOSR_SHIFT 1
-
-/* Digital interface register */
-#define TLV320AIC23_ACT_ON 0x0001
-
-/*
- * AUDIO related MACROS
- */
-
-#define TLV320AIC23_DEFAULT_OUT_VOL 0x70
-#define TLV320AIC23_DEFAULT_IN_VOLUME 0x10
-
-#define TLV320AIC23_OUT_VOL_MIN TLV320AIC23_LHV_MIN
-#define TLV320AIC23_OUT_VOL_MAX TLV320AIC23_LHV_MAX
-#define TLV320AIC23_OUT_VO_RANGE (TLV320AIC23_OUT_VOL_MAX - \
- TLV320AIC23_OUT_VOL_MIN)
-#define TLV320AIC23_OUT_VOL_MASK TLV320AIC23_OUT_VOL_MAX
-
-#define TLV320AIC23_IN_VOL_MIN TLV320AIC23_LIV_MIN
-#define TLV320AIC23_IN_VOL_MAX TLV320AIC23_LIV_MAX
-#define TLV320AIC23_IN_VOL_RANGE (TLV320AIC23_IN_VOL_MAX - \
- TLV320AIC23_IN_VOL_MIN)
-#define TLV320AIC23_IN_VOL_MASK TLV320AIC23_IN_VOL_MAX
-
-#define TLV320AIC23_SIDETONE_MASK 0x1c0
-#define TLV320AIC23_SIDETONE_0 0x100
-#define TLV320AIC23_SIDETONE_6 0x000
-#define TLV320AIC23_SIDETONE_9 0x040
-#define TLV320AIC23_SIDETONE_12 0x080
-#define TLV320AIC23_SIDETONE_18 0x0c0
-
-#endif /* _TLV320AIC23_H */
diff --git a/ANDROID_3.4.5/sound/soc/codecs/tlv320aic26.c b/ANDROID_3.4.5/sound/soc/codecs/tlv320aic26.c
deleted file mode 100644
index 802064b5..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/tlv320aic26.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * Texas Instruments TLV320AIC26 low power audio CODEC
- * ALSA SoC CODEC driver
- *
- * Copyright (C) 2008 Secret Lab Technologies Ltd.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/device.h>
-#include <linux/sysfs.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-
-#include "tlv320aic26.h"
-
-MODULE_DESCRIPTION("ASoC TLV320AIC26 codec driver");
-MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
-MODULE_LICENSE("GPL");
-
-/* AIC26 driver private data */
-struct aic26 {
- struct spi_device *spi;
- struct snd_soc_codec codec;
- int master;
- int datfm;
- int mclk;
-
- /* Keyclick parameters */
- int keyclick_amplitude;
- int keyclick_freq;
- int keyclick_len;
-};
-
-/* ---------------------------------------------------------------------
- * Register access routines
- */
-static unsigned int aic26_reg_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
- u16 *cache = codec->reg_cache;
- u16 cmd, value;
- u8 buffer[2];
- int rc;
-
- if (reg >= AIC26_NUM_REGS) {
- WARN_ON_ONCE(1);
- return 0;
- }
-
- /* Do SPI transfer; first 16bits are command; remaining is
- * register contents */
- cmd = AIC26_READ_COMMAND_WORD(reg);
- buffer[0] = (cmd >> 8) & 0xff;
- buffer[1] = cmd & 0xff;
- rc = spi_write_then_read(aic26->spi, buffer, 2, buffer, 2);
- if (rc) {
- dev_err(&aic26->spi->dev, "AIC26 reg read error\n");
- return -EIO;
- }
- value = (buffer[0] << 8) | buffer[1];
-
- /* Update the cache before returning with the value */
- cache[reg] = value;
- return value;
-}
-
-static unsigned int aic26_reg_read_cache(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- u16 *cache = codec->reg_cache;
-
- if (reg >= AIC26_NUM_REGS) {
- WARN_ON_ONCE(1);
- return 0;
- }
-
- return cache[reg];
-}
-
-static int aic26_reg_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
- u16 *cache = codec->reg_cache;
- u16 cmd;
- u8 buffer[4];
- int rc;
-
- if (reg >= AIC26_NUM_REGS) {
- WARN_ON_ONCE(1);
- return -EINVAL;
- }
-
- /* Do SPI transfer; first 16bits are command; remaining is data
- * to write into register */
- cmd = AIC26_WRITE_COMMAND_WORD(reg);
- buffer[0] = (cmd >> 8) & 0xff;
- buffer[1] = cmd & 0xff;
- buffer[2] = value >> 8;
- buffer[3] = value;
- rc = spi_write(aic26->spi, buffer, 4);
- if (rc) {
- dev_err(&aic26->spi->dev, "AIC26 reg read error\n");
- return -EIO;
- }
-
- /* update cache before returning */
- cache[reg] = value;
- return 0;
-}
-
-/* ---------------------------------------------------------------------
- * Digital Audio Interface Operations
- */
-static int aic26_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
- int fsref, divisor, wlen, pval, jval, dval, qval;
- u16 reg;
-
- dev_dbg(&aic26->spi->dev, "aic26_hw_params(substream=%p, params=%p)\n",
- substream, params);
- dev_dbg(&aic26->spi->dev, "rate=%i format=%i\n", params_rate(params),
- params_format(params));
-
- switch (params_rate(params)) {
- case 8000: fsref = 48000; divisor = AIC26_DIV_6; break;
- case 11025: fsref = 44100; divisor = AIC26_DIV_4; break;
- case 12000: fsref = 48000; divisor = AIC26_DIV_4; break;
- case 16000: fsref = 48000; divisor = AIC26_DIV_3; break;
- case 22050: fsref = 44100; divisor = AIC26_DIV_2; break;
- case 24000: fsref = 48000; divisor = AIC26_DIV_2; break;
- case 32000: fsref = 48000; divisor = AIC26_DIV_1_5; break;
- case 44100: fsref = 44100; divisor = AIC26_DIV_1; break;
- case 48000: fsref = 48000; divisor = AIC26_DIV_1; break;
- default:
- dev_dbg(&aic26->spi->dev, "bad rate\n"); return -EINVAL;
- }
-
- /* select data word length */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S8: wlen = AIC26_WLEN_16; break;
- case SNDRV_PCM_FORMAT_S16_BE: wlen = AIC26_WLEN_16; break;
- case SNDRV_PCM_FORMAT_S24_BE: wlen = AIC26_WLEN_24; break;
- case SNDRV_PCM_FORMAT_S32_BE: wlen = AIC26_WLEN_32; break;
- default:
- dev_dbg(&aic26->spi->dev, "bad format\n"); return -EINVAL;
- }
-
- /**
- * Configure PLL
- * fsref = (mclk * PLLM) / 2048
- * where PLLM = J.DDDD (DDDD register ranges from 0 to 9999, decimal)
- */
- pval = 1;
- /* compute J portion of multiplier */
- jval = fsref / (aic26->mclk / 2048);
- /* compute fractional DDDD component of multiplier */
- dval = fsref - (jval * (aic26->mclk / 2048));
- dval = (10000 * dval) / (aic26->mclk / 2048);
- dev_dbg(&aic26->spi->dev, "Setting PLLM to %d.%04d\n", jval, dval);
- qval = 0;
- reg = 0x8000 | qval << 11 | pval << 8 | jval << 2;
- aic26_reg_write(codec, AIC26_REG_PLL_PROG1, reg);
- reg = dval << 2;
- aic26_reg_write(codec, AIC26_REG_PLL_PROG2, reg);
-
- /* Audio Control 3 (master mode, fsref rate) */
- reg = aic26_reg_read_cache(codec, AIC26_REG_AUDIO_CTRL3);
- reg &= ~0xf800;
- if (aic26->master)
- reg |= 0x0800;
- if (fsref == 48000)
- reg |= 0x2000;
- aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL3, reg);
-
- /* Audio Control 1 (FSref divisor) */
- reg = aic26_reg_read_cache(codec, AIC26_REG_AUDIO_CTRL1);
- reg &= ~0x0fff;
- reg |= wlen | aic26->datfm | (divisor << 3) | divisor;
- aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL1, reg);
-
- return 0;
-}
-
-/**
- * aic26_mute - Mute control to reduce noise when changing audio format
- */
-static int aic26_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
- u16 reg = aic26_reg_read_cache(codec, AIC26_REG_DAC_GAIN);
-
- dev_dbg(&aic26->spi->dev, "aic26_mute(dai=%p, mute=%i)\n",
- dai, mute);
-
- if (mute)
- reg |= 0x8080;
- else
- reg &= ~0x8080;
- aic26_reg_write(codec, AIC26_REG_DAC_GAIN, reg);
-
- return 0;
-}
-
-static int aic26_set_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
-
- dev_dbg(&aic26->spi->dev, "aic26_set_sysclk(dai=%p, clk_id==%i,"
- " freq=%i, dir=%i)\n",
- codec_dai, clk_id, freq, dir);
-
- /* MCLK needs to fall between 2MHz and 50 MHz */
- if ((freq < 2000000) || (freq > 50000000))
- return -EINVAL;
-
- aic26->mclk = freq;
- return 0;
-}
-
-static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
-
- dev_dbg(&aic26->spi->dev, "aic26_set_fmt(dai=%p, fmt==%i)\n",
- codec_dai, fmt);
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM: aic26->master = 1; break;
- case SND_SOC_DAIFMT_CBS_CFS: aic26->master = 0; break;
- default:
- dev_dbg(&aic26->spi->dev, "bad master\n"); return -EINVAL;
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S: aic26->datfm = AIC26_DATFM_I2S; break;
- case SND_SOC_DAIFMT_DSP_A: aic26->datfm = AIC26_DATFM_DSP; break;
- case SND_SOC_DAIFMT_RIGHT_J: aic26->datfm = AIC26_DATFM_RIGHTJ; break;
- case SND_SOC_DAIFMT_LEFT_J: aic26->datfm = AIC26_DATFM_LEFTJ; break;
- default:
- dev_dbg(&aic26->spi->dev, "bad format\n"); return -EINVAL;
- }
-
- return 0;
-}
-
-/* ---------------------------------------------------------------------
- * Digital Audio Interface Definition
- */
-#define AIC26_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
- SNDRV_PCM_RATE_48000)
-#define AIC26_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE |\
- SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE)
-
-static const struct snd_soc_dai_ops aic26_dai_ops = {
- .hw_params = aic26_hw_params,
- .digital_mute = aic26_mute,
- .set_sysclk = aic26_set_sysclk,
- .set_fmt = aic26_set_fmt,
-};
-
-static struct snd_soc_dai_driver aic26_dai = {
- .name = "tlv320aic26-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = AIC26_RATES,
- .formats = AIC26_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = AIC26_RATES,
- .formats = AIC26_FORMATS,
- },
- .ops = &aic26_dai_ops,
-};
-
-/* ---------------------------------------------------------------------
- * ALSA controls
- */
-static const char *aic26_capture_src_text[] = {"Mic", "Aux"};
-static const struct soc_enum aic26_capture_src_enum =
- SOC_ENUM_SINGLE(AIC26_REG_AUDIO_CTRL1, 12, 2, aic26_capture_src_text);
-
-static const struct snd_kcontrol_new aic26_snd_controls[] = {
- /* Output */
- SOC_DOUBLE("PCM Playback Volume", AIC26_REG_DAC_GAIN, 8, 0, 0x7f, 1),
- SOC_DOUBLE("PCM Playback Switch", AIC26_REG_DAC_GAIN, 15, 7, 1, 1),
- SOC_SINGLE("PCM Capture Volume", AIC26_REG_ADC_GAIN, 8, 0x7f, 0),
- SOC_SINGLE("PCM Capture Mute", AIC26_REG_ADC_GAIN, 15, 1, 1),
- SOC_SINGLE("Keyclick activate", AIC26_REG_AUDIO_CTRL2, 15, 0x1, 0),
- SOC_SINGLE("Keyclick amplitude", AIC26_REG_AUDIO_CTRL2, 12, 0x7, 0),
- SOC_SINGLE("Keyclick frequency", AIC26_REG_AUDIO_CTRL2, 8, 0x7, 0),
- SOC_SINGLE("Keyclick period", AIC26_REG_AUDIO_CTRL2, 4, 0xf, 0),
- SOC_ENUM("Capture Source", aic26_capture_src_enum),
-};
-
-/* ---------------------------------------------------------------------
- * SPI device portion of driver: sysfs files for debugging
- */
-
-static ssize_t aic26_keyclick_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct aic26 *aic26 = dev_get_drvdata(dev);
- int val, amp, freq, len;
-
- val = aic26_reg_read_cache(&aic26->codec, AIC26_REG_AUDIO_CTRL2);
- amp = (val >> 12) & 0x7;
- freq = (125 << ((val >> 8) & 0x7)) >> 1;
- len = 2 * (1 + ((val >> 4) & 0xf));
-
- return sprintf(buf, "amp=%x freq=%iHz len=%iclks\n", amp, freq, len);
-}
-
-/* Any write to the keyclick attribute will trigger the keyclick event */
-static ssize_t aic26_keyclick_set(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct aic26 *aic26 = dev_get_drvdata(dev);
- int val;
-
- val = aic26_reg_read_cache(&aic26->codec, AIC26_REG_AUDIO_CTRL2);
- val |= 0x8000;
- aic26_reg_write(&aic26->codec, AIC26_REG_AUDIO_CTRL2, val);
-
- return count;
-}
-
-static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
-
-/* ---------------------------------------------------------------------
- * SoC CODEC portion of driver: probe and release routines
- */
-static int aic26_probe(struct snd_soc_codec *codec)
-{
- int ret, err, i, reg;
-
- dev_info(codec->dev, "Probing AIC26 SoC CODEC driver\n");
-
- /* Reset the codec to power on defaults */
- aic26_reg_write(codec, AIC26_REG_RESET, 0xBB00);
-
- /* Power up CODEC */
- aic26_reg_write(codec, AIC26_REG_POWER_CTRL, 0);
-
- /* Audio Control 3 (master mode, fsref rate) */
- reg = aic26_reg_read(codec, AIC26_REG_AUDIO_CTRL3);
- reg &= ~0xf800;
- reg |= 0x0800; /* set master mode */
- aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL3, reg);
-
- /* Fill register cache */
- for (i = 0; i < codec->driver->reg_cache_size; i++)
- aic26_reg_read(codec, i);
-
- /* Register the sysfs files for debugging */
- /* Create SysFS files */
- ret = device_create_file(codec->dev, &dev_attr_keyclick);
- if (ret)
- dev_info(codec->dev, "error creating sysfs files\n");
-
- /* register controls */
- dev_dbg(codec->dev, "Registering controls\n");
- err = snd_soc_add_codec_controls(codec, aic26_snd_controls,
- ARRAY_SIZE(aic26_snd_controls));
- WARN_ON(err < 0);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver aic26_soc_codec_dev = {
- .probe = aic26_probe,
- .read = aic26_reg_read,
- .write = aic26_reg_write,
- .reg_cache_size = AIC26_NUM_REGS,
- .reg_word_size = sizeof(u16),
-};
-
-/* ---------------------------------------------------------------------
- * SPI device portion of driver: probe and release routines and SPI
- * driver registration.
- */
-static int aic26_spi_probe(struct spi_device *spi)
-{
- struct aic26 *aic26;
- int ret;
-
- dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n");
-
- /* Allocate driver data */
- aic26 = devm_kzalloc(&spi->dev, sizeof *aic26, GFP_KERNEL);
- if (!aic26)
- return -ENOMEM;
-
- /* Initialize the driver data */
- aic26->spi = spi;
- dev_set_drvdata(&spi->dev, aic26);
- aic26->master = 1;
-
- ret = snd_soc_register_codec(&spi->dev,
- &aic26_soc_codec_dev, &aic26_dai, 1);
- return ret;
-}
-
-static int aic26_spi_remove(struct spi_device *spi)
-{
- snd_soc_unregister_codec(&spi->dev);
- return 0;
-}
-
-static struct spi_driver aic26_spi = {
- .driver = {
- .name = "tlv320aic26-codec",
- .owner = THIS_MODULE,
- },
- .probe = aic26_spi_probe,
- .remove = aic26_spi_remove,
-};
-
-static int __init aic26_init(void)
-{
- return spi_register_driver(&aic26_spi);
-}
-module_init(aic26_init);
-
-static void __exit aic26_exit(void)
-{
- spi_unregister_driver(&aic26_spi);
-}
-module_exit(aic26_exit);
diff --git a/ANDROID_3.4.5/sound/soc/codecs/tlv320aic26.h b/ANDROID_3.4.5/sound/soc/codecs/tlv320aic26.h
deleted file mode 100644
index 67f19c3b..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/tlv320aic26.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Texas Instruments TLV320AIC26 low power audio CODEC
- * register definitions
- *
- * Copyright (C) 2008 Secret Lab Technologies Ltd.
- */
-
-#ifndef _TLV320AIC16_H_
-#define _TLV320AIC16_H_
-
-/* AIC26 Registers */
-#define AIC26_READ_COMMAND_WORD(addr) ((1 << 15) | (addr << 5))
-#define AIC26_WRITE_COMMAND_WORD(addr) ((0 << 15) | (addr << 5))
-#define AIC26_PAGE_ADDR(page, offset) ((page << 6) | offset)
-#define AIC26_NUM_REGS AIC26_PAGE_ADDR(3, 0)
-
-/* Page 0: Auxiliary data registers */
-#define AIC26_REG_BAT1 AIC26_PAGE_ADDR(0, 0x05)
-#define AIC26_REG_BAT2 AIC26_PAGE_ADDR(0, 0x06)
-#define AIC26_REG_AUX AIC26_PAGE_ADDR(0, 0x07)
-#define AIC26_REG_TEMP1 AIC26_PAGE_ADDR(0, 0x09)
-#define AIC26_REG_TEMP2 AIC26_PAGE_ADDR(0, 0x0A)
-
-/* Page 1: Auxiliary control registers */
-#define AIC26_REG_AUX_ADC AIC26_PAGE_ADDR(1, 0x00)
-#define AIC26_REG_STATUS AIC26_PAGE_ADDR(1, 0x01)
-#define AIC26_REG_REFERENCE AIC26_PAGE_ADDR(1, 0x03)
-#define AIC26_REG_RESET AIC26_PAGE_ADDR(1, 0x04)
-
-/* Page 2: Audio control registers */
-#define AIC26_REG_AUDIO_CTRL1 AIC26_PAGE_ADDR(2, 0x00)
-#define AIC26_REG_ADC_GAIN AIC26_PAGE_ADDR(2, 0x01)
-#define AIC26_REG_DAC_GAIN AIC26_PAGE_ADDR(2, 0x02)
-#define AIC26_REG_SIDETONE AIC26_PAGE_ADDR(2, 0x03)
-#define AIC26_REG_AUDIO_CTRL2 AIC26_PAGE_ADDR(2, 0x04)
-#define AIC26_REG_POWER_CTRL AIC26_PAGE_ADDR(2, 0x05)
-#define AIC26_REG_AUDIO_CTRL3 AIC26_PAGE_ADDR(2, 0x06)
-
-#define AIC26_REG_FILTER_COEFF_L_N0 AIC26_PAGE_ADDR(2, 0x07)
-#define AIC26_REG_FILTER_COEFF_L_N1 AIC26_PAGE_ADDR(2, 0x08)
-#define AIC26_REG_FILTER_COEFF_L_N2 AIC26_PAGE_ADDR(2, 0x09)
-#define AIC26_REG_FILTER_COEFF_L_N3 AIC26_PAGE_ADDR(2, 0x0A)
-#define AIC26_REG_FILTER_COEFF_L_N4 AIC26_PAGE_ADDR(2, 0x0B)
-#define AIC26_REG_FILTER_COEFF_L_N5 AIC26_PAGE_ADDR(2, 0x0C)
-#define AIC26_REG_FILTER_COEFF_L_D1 AIC26_PAGE_ADDR(2, 0x0D)
-#define AIC26_REG_FILTER_COEFF_L_D2 AIC26_PAGE_ADDR(2, 0x0E)
-#define AIC26_REG_FILTER_COEFF_L_D4 AIC26_PAGE_ADDR(2, 0x0F)
-#define AIC26_REG_FILTER_COEFF_L_D5 AIC26_PAGE_ADDR(2, 0x10)
-#define AIC26_REG_FILTER_COEFF_R_N0 AIC26_PAGE_ADDR(2, 0x11)
-#define AIC26_REG_FILTER_COEFF_R_N1 AIC26_PAGE_ADDR(2, 0x12)
-#define AIC26_REG_FILTER_COEFF_R_N2 AIC26_PAGE_ADDR(2, 0x13)
-#define AIC26_REG_FILTER_COEFF_R_N3 AIC26_PAGE_ADDR(2, 0x14)
-#define AIC26_REG_FILTER_COEFF_R_N4 AIC26_PAGE_ADDR(2, 0x15)
-#define AIC26_REG_FILTER_COEFF_R_N5 AIC26_PAGE_ADDR(2, 0x16)
-#define AIC26_REG_FILTER_COEFF_R_D1 AIC26_PAGE_ADDR(2, 0x17)
-#define AIC26_REG_FILTER_COEFF_R_D2 AIC26_PAGE_ADDR(2, 0x18)
-#define AIC26_REG_FILTER_COEFF_R_D4 AIC26_PAGE_ADDR(2, 0x19)
-#define AIC26_REG_FILTER_COEFF_R_D5 AIC26_PAGE_ADDR(2, 0x1A)
-
-#define AIC26_REG_PLL_PROG1 AIC26_PAGE_ADDR(2, 0x1B)
-#define AIC26_REG_PLL_PROG2 AIC26_PAGE_ADDR(2, 0x1C)
-#define AIC26_REG_AUDIO_CTRL4 AIC26_PAGE_ADDR(2, 0x1D)
-#define AIC26_REG_AUDIO_CTRL5 AIC26_PAGE_ADDR(2, 0x1E)
-
-/* fsref dividers; used in register 'Audio Control 1' */
-enum aic26_divisors {
- AIC26_DIV_1 = 0,
- AIC26_DIV_1_5 = 1,
- AIC26_DIV_2 = 2,
- AIC26_DIV_3 = 3,
- AIC26_DIV_4 = 4,
- AIC26_DIV_5 = 5,
- AIC26_DIV_5_5 = 6,
- AIC26_DIV_6 = 7,
-};
-
-/* Digital data format */
-enum aic26_datfm {
- AIC26_DATFM_I2S = 0 << 8,
- AIC26_DATFM_DSP = 1 << 8,
- AIC26_DATFM_RIGHTJ = 2 << 8, /* right justified */
- AIC26_DATFM_LEFTJ = 3 << 8, /* left justified */
-};
-
-/* Sample word length in bits; used in register 'Audio Control 1' */
-enum aic26_wlen {
- AIC26_WLEN_16 = 0 << 10,
- AIC26_WLEN_20 = 1 << 10,
- AIC26_WLEN_24 = 2 << 10,
- AIC26_WLEN_32 = 3 << 10,
-};
-
-#endif /* _TLV320AIC16_H_ */
diff --git a/ANDROID_3.4.5/sound/soc/codecs/tlv320aic32x4.c b/ANDROID_3.4.5/sound/soc/codecs/tlv320aic32x4.c
deleted file mode 100644
index b0a73d37..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/tlv320aic32x4.c
+++ /dev/null
@@ -1,770 +0,0 @@
-/*
- * linux/sound/soc/codecs/tlv320aic32x4.c
- *
- * Copyright 2011 Vista Silicon S.L.
- *
- * Author: Javier Martin <javier.martin@vista-silicon.com>
- *
- * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/cdev.h>
-#include <linux/slab.h>
-
-#include <sound/tlv320aic32x4.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "tlv320aic32x4.h"
-
-struct aic32x4_rate_divs {
- u32 mclk;
- u32 rate;
- u8 p_val;
- u8 pll_j;
- u16 pll_d;
- u16 dosr;
- u8 ndac;
- u8 mdac;
- u8 aosr;
- u8 nadc;
- u8 madc;
- u8 blck_N;
-};
-
-struct aic32x4_priv {
- u32 sysclk;
- u8 page_no;
- void *control_data;
- u32 power_cfg;
- u32 micpga_routing;
- bool swapdacs;
-};
-
-/* 0dB min, 1dB steps */
-static DECLARE_TLV_DB_SCALE(tlv_step_1, 0, 100, 0);
-/* 0dB min, 0.5dB steps */
-static DECLARE_TLV_DB_SCALE(tlv_step_0_5, 0, 50, 0);
-
-static const struct snd_kcontrol_new aic32x4_snd_controls[] = {
- SOC_DOUBLE_R_TLV("PCM Playback Volume", AIC32X4_LDACVOL,
- AIC32X4_RDACVOL, 0, 0x30, 0, tlv_step_0_5),
- SOC_DOUBLE_R_TLV("HP Driver Gain Volume", AIC32X4_HPLGAIN,
- AIC32X4_HPRGAIN, 0, 0x1D, 0, tlv_step_1),
- SOC_DOUBLE_R_TLV("LO Driver Gain Volume", AIC32X4_LOLGAIN,
- AIC32X4_LORGAIN, 0, 0x1D, 0, tlv_step_1),
- SOC_DOUBLE_R("HP DAC Playback Switch", AIC32X4_HPLGAIN,
- AIC32X4_HPRGAIN, 6, 0x01, 1),
- SOC_DOUBLE_R("LO DAC Playback Switch", AIC32X4_LOLGAIN,
- AIC32X4_LORGAIN, 6, 0x01, 1),
- SOC_DOUBLE_R("Mic PGA Switch", AIC32X4_LMICPGAVOL,
- AIC32X4_RMICPGAVOL, 7, 0x01, 1),
-
- SOC_SINGLE("ADCFGA Left Mute Switch", AIC32X4_ADCFGA, 7, 1, 0),
- SOC_SINGLE("ADCFGA Right Mute Switch", AIC32X4_ADCFGA, 3, 1, 0),
-
- SOC_DOUBLE_R_TLV("ADC Level Volume", AIC32X4_LADCVOL,
- AIC32X4_RADCVOL, 0, 0x28, 0, tlv_step_0_5),
- SOC_DOUBLE_R_TLV("PGA Level Volume", AIC32X4_LMICPGAVOL,
- AIC32X4_RMICPGAVOL, 0, 0x5f, 0, tlv_step_0_5),
-
- SOC_SINGLE("Auto-mute Switch", AIC32X4_DACMUTE, 4, 7, 0),
-
- SOC_SINGLE("AGC Left Switch", AIC32X4_LAGC1, 7, 1, 0),
- SOC_SINGLE("AGC Right Switch", AIC32X4_RAGC1, 7, 1, 0),
- SOC_DOUBLE_R("AGC Target Level", AIC32X4_LAGC1, AIC32X4_RAGC1,
- 4, 0x07, 0),
- SOC_DOUBLE_R("AGC Gain Hysteresis", AIC32X4_LAGC1, AIC32X4_RAGC1,
- 0, 0x03, 0),
- SOC_DOUBLE_R("AGC Hysteresis", AIC32X4_LAGC2, AIC32X4_RAGC2,
- 6, 0x03, 0),
- SOC_DOUBLE_R("AGC Noise Threshold", AIC32X4_LAGC2, AIC32X4_RAGC2,
- 1, 0x1F, 0),
- SOC_DOUBLE_R("AGC Max PGA", AIC32X4_LAGC3, AIC32X4_RAGC3,
- 0, 0x7F, 0),
- SOC_DOUBLE_R("AGC Attack Time", AIC32X4_LAGC4, AIC32X4_RAGC4,
- 3, 0x1F, 0),
- SOC_DOUBLE_R("AGC Decay Time", AIC32X4_LAGC5, AIC32X4_RAGC5,
- 3, 0x1F, 0),
- SOC_DOUBLE_R("AGC Noise Debounce", AIC32X4_LAGC6, AIC32X4_RAGC6,
- 0, 0x1F, 0),
- SOC_DOUBLE_R("AGC Signal Debounce", AIC32X4_LAGC7, AIC32X4_RAGC7,
- 0, 0x0F, 0),
-};
-
-static const struct aic32x4_rate_divs aic32x4_divs[] = {
- /* 8k rate */
- {AIC32X4_FREQ_12000000, 8000, 1, 7, 6800, 768, 5, 3, 128, 5, 18, 24},
- {AIC32X4_FREQ_24000000, 8000, 2, 7, 6800, 768, 15, 1, 64, 45, 4, 24},
- {AIC32X4_FREQ_25000000, 8000, 2, 7, 3728, 768, 15, 1, 64, 45, 4, 24},
- /* 11.025k rate */
- {AIC32X4_FREQ_12000000, 11025, 1, 7, 5264, 512, 8, 2, 128, 8, 8, 16},
- {AIC32X4_FREQ_24000000, 11025, 2, 7, 5264, 512, 16, 1, 64, 32, 4, 16},
- /* 16k rate */
- {AIC32X4_FREQ_12000000, 16000, 1, 7, 6800, 384, 5, 3, 128, 5, 9, 12},
- {AIC32X4_FREQ_24000000, 16000, 2, 7, 6800, 384, 15, 1, 64, 18, 5, 12},
- {AIC32X4_FREQ_25000000, 16000, 2, 7, 3728, 384, 15, 1, 64, 18, 5, 12},
- /* 22.05k rate */
- {AIC32X4_FREQ_12000000, 22050, 1, 7, 5264, 256, 4, 4, 128, 4, 8, 8},
- {AIC32X4_FREQ_24000000, 22050, 2, 7, 5264, 256, 16, 1, 64, 16, 4, 8},
- {AIC32X4_FREQ_25000000, 22050, 2, 7, 2253, 256, 16, 1, 64, 16, 4, 8},
- /* 32k rate */
- {AIC32X4_FREQ_12000000, 32000, 1, 7, 1680, 192, 2, 7, 64, 2, 21, 6},
- {AIC32X4_FREQ_24000000, 32000, 2, 7, 1680, 192, 7, 2, 64, 7, 6, 6},
- /* 44.1k rate */
- {AIC32X4_FREQ_12000000, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4},
- {AIC32X4_FREQ_24000000, 44100, 2, 7, 5264, 128, 8, 2, 64, 8, 4, 4},
- {AIC32X4_FREQ_25000000, 44100, 2, 7, 2253, 128, 8, 2, 64, 8, 4, 4},
- /* 48k rate */
- {AIC32X4_FREQ_12000000, 48000, 1, 8, 1920, 128, 2, 8, 128, 2, 8, 4},
- {AIC32X4_FREQ_24000000, 48000, 2, 8, 1920, 128, 8, 2, 64, 8, 4, 4},
- {AIC32X4_FREQ_25000000, 48000, 2, 7, 8643, 128, 8, 2, 64, 8, 4, 4}
-};
-
-static const struct snd_kcontrol_new hpl_output_mixer_controls[] = {
- SOC_DAPM_SINGLE("L_DAC Switch", AIC32X4_HPLROUTE, 3, 1, 0),
- SOC_DAPM_SINGLE("IN1_L Switch", AIC32X4_HPLROUTE, 2, 1, 0),
-};
-
-static const struct snd_kcontrol_new hpr_output_mixer_controls[] = {
- SOC_DAPM_SINGLE("R_DAC Switch", AIC32X4_HPRROUTE, 3, 1, 0),
- SOC_DAPM_SINGLE("IN1_R Switch", AIC32X4_HPRROUTE, 2, 1, 0),
-};
-
-static const struct snd_kcontrol_new lol_output_mixer_controls[] = {
- SOC_DAPM_SINGLE("L_DAC Switch", AIC32X4_LOLROUTE, 3, 1, 0),
-};
-
-static const struct snd_kcontrol_new lor_output_mixer_controls[] = {
- SOC_DAPM_SINGLE("R_DAC Switch", AIC32X4_LORROUTE, 3, 1, 0),
-};
-
-static const struct snd_kcontrol_new left_input_mixer_controls[] = {
- SOC_DAPM_SINGLE("IN1_L P Switch", AIC32X4_LMICPGAPIN, 6, 1, 0),
- SOC_DAPM_SINGLE("IN2_L P Switch", AIC32X4_LMICPGAPIN, 4, 1, 0),
- SOC_DAPM_SINGLE("IN3_L P Switch", AIC32X4_LMICPGAPIN, 2, 1, 0),
-};
-
-static const struct snd_kcontrol_new right_input_mixer_controls[] = {
- SOC_DAPM_SINGLE("IN1_R P Switch", AIC32X4_RMICPGAPIN, 6, 1, 0),
- SOC_DAPM_SINGLE("IN2_R P Switch", AIC32X4_RMICPGAPIN, 4, 1, 0),
- SOC_DAPM_SINGLE("IN3_R P Switch", AIC32X4_RMICPGAPIN, 2, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = {
- SND_SOC_DAPM_DAC("Left DAC", "Left Playback", AIC32X4_DACSETUP, 7, 0),
- SND_SOC_DAPM_MIXER("HPL Output Mixer", SND_SOC_NOPM, 0, 0,
- &hpl_output_mixer_controls[0],
- ARRAY_SIZE(hpl_output_mixer_controls)),
- SND_SOC_DAPM_PGA("HPL Power", AIC32X4_OUTPWRCTL, 5, 0, NULL, 0),
-
- SND_SOC_DAPM_MIXER("LOL Output Mixer", SND_SOC_NOPM, 0, 0,
- &lol_output_mixer_controls[0],
- ARRAY_SIZE(lol_output_mixer_controls)),
- SND_SOC_DAPM_PGA("LOL Power", AIC32X4_OUTPWRCTL, 3, 0, NULL, 0),
-
- SND_SOC_DAPM_DAC("Right DAC", "Right Playback", AIC32X4_DACSETUP, 6, 0),
- SND_SOC_DAPM_MIXER("HPR Output Mixer", SND_SOC_NOPM, 0, 0,
- &hpr_output_mixer_controls[0],
- ARRAY_SIZE(hpr_output_mixer_controls)),
- SND_SOC_DAPM_PGA("HPR Power", AIC32X4_OUTPWRCTL, 4, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("LOR Output Mixer", SND_SOC_NOPM, 0, 0,
- &lor_output_mixer_controls[0],
- ARRAY_SIZE(lor_output_mixer_controls)),
- SND_SOC_DAPM_PGA("LOR Power", AIC32X4_OUTPWRCTL, 2, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("Left Input Mixer", SND_SOC_NOPM, 0, 0,
- &left_input_mixer_controls[0],
- ARRAY_SIZE(left_input_mixer_controls)),
- SND_SOC_DAPM_MIXER("Right Input Mixer", SND_SOC_NOPM, 0, 0,
- &right_input_mixer_controls[0],
- ARRAY_SIZE(right_input_mixer_controls)),
- SND_SOC_DAPM_ADC("Left ADC", "Left Capture", AIC32X4_ADCSETUP, 7, 0),
- SND_SOC_DAPM_ADC("Right ADC", "Right Capture", AIC32X4_ADCSETUP, 6, 0),
- SND_SOC_DAPM_MICBIAS("Mic Bias", AIC32X4_MICBIAS, 6, 0),
-
- SND_SOC_DAPM_OUTPUT("HPL"),
- SND_SOC_DAPM_OUTPUT("HPR"),
- SND_SOC_DAPM_OUTPUT("LOL"),
- SND_SOC_DAPM_OUTPUT("LOR"),
- SND_SOC_DAPM_INPUT("IN1_L"),
- SND_SOC_DAPM_INPUT("IN1_R"),
- SND_SOC_DAPM_INPUT("IN2_L"),
- SND_SOC_DAPM_INPUT("IN2_R"),
- SND_SOC_DAPM_INPUT("IN3_L"),
- SND_SOC_DAPM_INPUT("IN3_R"),
-};
-
-static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = {
- /* Left Output */
- {"HPL Output Mixer", "L_DAC Switch", "Left DAC"},
- {"HPL Output Mixer", "IN1_L Switch", "IN1_L"},
-
- {"HPL Power", NULL, "HPL Output Mixer"},
- {"HPL", NULL, "HPL Power"},
-
- {"LOL Output Mixer", "L_DAC Switch", "Left DAC"},
-
- {"LOL Power", NULL, "LOL Output Mixer"},
- {"LOL", NULL, "LOL Power"},
-
- /* Right Output */
- {"HPR Output Mixer", "R_DAC Switch", "Right DAC"},
- {"HPR Output Mixer", "IN1_R Switch", "IN1_R"},
-
- {"HPR Power", NULL, "HPR Output Mixer"},
- {"HPR", NULL, "HPR Power"},
-
- {"LOR Output Mixer", "R_DAC Switch", "Right DAC"},
-
- {"LOR Power", NULL, "LOR Output Mixer"},
- {"LOR", NULL, "LOR Power"},
-
- /* Left input */
- {"Left Input Mixer", "IN1_L P Switch", "IN1_L"},
- {"Left Input Mixer", "IN2_L P Switch", "IN2_L"},
- {"Left Input Mixer", "IN3_L P Switch", "IN3_L"},
-
- {"Left ADC", NULL, "Left Input Mixer"},
-
- /* Right Input */
- {"Right Input Mixer", "IN1_R P Switch", "IN1_R"},
- {"Right Input Mixer", "IN2_R P Switch", "IN2_R"},
- {"Right Input Mixer", "IN3_R P Switch", "IN3_R"},
-
- {"Right ADC", NULL, "Right Input Mixer"},
-};
-
-static inline int aic32x4_change_page(struct snd_soc_codec *codec,
- unsigned int new_page)
-{
- struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
- u8 data[2];
- int ret;
-
- data[0] = 0x00;
- data[1] = new_page & 0xff;
-
- ret = codec->hw_write(codec->control_data, data, 2);
- if (ret == 2) {
- aic32x4->page_no = new_page;
- return 0;
- } else {
- return ret;
- }
-}
-
-static int aic32x4_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int val)
-{
- struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
- unsigned int page = reg / 128;
- unsigned int fixed_reg = reg % 128;
- u8 data[2];
- int ret;
-
- /* A write to AIC32X4_PSEL is really a non-explicit page change */
- if (reg == AIC32X4_PSEL)
- return aic32x4_change_page(codec, val);
-
- if (aic32x4->page_no != page) {
- ret = aic32x4_change_page(codec, page);
- if (ret != 0)
- return ret;
- }
-
- data[0] = fixed_reg & 0xff;
- data[1] = val & 0xff;
-
- if (codec->hw_write(codec->control_data, data, 2) == 2)
- return 0;
- else
- return -EIO;
-}
-
-static unsigned int aic32x4_read(struct snd_soc_codec *codec, unsigned int reg)
-{
- struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
- unsigned int page = reg / 128;
- unsigned int fixed_reg = reg % 128;
- int ret;
-
- if (aic32x4->page_no != page) {
- ret = aic32x4_change_page(codec, page);
- if (ret != 0)
- return ret;
- }
- return i2c_smbus_read_byte_data(codec->control_data, fixed_reg & 0xff);
-}
-
-static inline int aic32x4_get_divs(int mclk, int rate)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(aic32x4_divs); i++) {
- if ((aic32x4_divs[i].rate == rate)
- && (aic32x4_divs[i].mclk == mclk)) {
- return i;
- }
- }
- printk(KERN_ERR "aic32x4: master clock and sample rate is not supported\n");
- return -EINVAL;
-}
-
-static int aic32x4_add_widgets(struct snd_soc_codec *codec)
-{
- snd_soc_dapm_new_controls(&codec->dapm, aic32x4_dapm_widgets,
- ARRAY_SIZE(aic32x4_dapm_widgets));
-
- snd_soc_dapm_add_routes(&codec->dapm, aic32x4_dapm_routes,
- ARRAY_SIZE(aic32x4_dapm_routes));
-
- snd_soc_dapm_new_widgets(&codec->dapm);
- return 0;
-}
-
-static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
-
- switch (freq) {
- case AIC32X4_FREQ_12000000:
- case AIC32X4_FREQ_24000000:
- case AIC32X4_FREQ_25000000:
- aic32x4->sysclk = freq;
- return 0;
- }
- printk(KERN_ERR "aic32x4: invalid frequency to set DAI system clock\n");
- return -EINVAL;
-}
-
-static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u8 iface_reg_1;
- u8 iface_reg_2;
- u8 iface_reg_3;
-
- iface_reg_1 = snd_soc_read(codec, AIC32X4_IFACE1);
- iface_reg_1 = iface_reg_1 & ~(3 << 6 | 3 << 2);
- iface_reg_2 = snd_soc_read(codec, AIC32X4_IFACE2);
- iface_reg_2 = 0;
- iface_reg_3 = snd_soc_read(codec, AIC32X4_IFACE3);
- iface_reg_3 = iface_reg_3 & ~(1 << 3);
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- iface_reg_1 |= AIC32X4_BCLKMASTER | AIC32X4_WCLKMASTER;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- printk(KERN_ERR "aic32x4: invalid DAI master/slave interface\n");
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface_reg_1 |= (AIC32X4_DSP_MODE << AIC32X4_PLLJ_SHIFT);
- iface_reg_3 |= (1 << 3); /* invert bit clock */
- iface_reg_2 = 0x01; /* add offset 1 */
- break;
- case SND_SOC_DAIFMT_DSP_B:
- iface_reg_1 |= (AIC32X4_DSP_MODE << AIC32X4_PLLJ_SHIFT);
- iface_reg_3 |= (1 << 3); /* invert bit clock */
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- iface_reg_1 |=
- (AIC32X4_RIGHT_JUSTIFIED_MODE << AIC32X4_PLLJ_SHIFT);
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface_reg_1 |=
- (AIC32X4_LEFT_JUSTIFIED_MODE << AIC32X4_PLLJ_SHIFT);
- break;
- default:
- printk(KERN_ERR "aic32x4: invalid DAI interface format\n");
- return -EINVAL;
- }
-
- snd_soc_write(codec, AIC32X4_IFACE1, iface_reg_1);
- snd_soc_write(codec, AIC32X4_IFACE2, iface_reg_2);
- snd_soc_write(codec, AIC32X4_IFACE3, iface_reg_3);
- return 0;
-}
-
-static int aic32x4_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
- u8 data;
- int i;
-
- i = aic32x4_get_divs(aic32x4->sysclk, params_rate(params));
- if (i < 0) {
- printk(KERN_ERR "aic32x4: sampling rate not supported\n");
- return i;
- }
-
- /* Use PLL as CODEC_CLKIN and DAC_MOD_CLK as BDIV_CLKIN */
- snd_soc_write(codec, AIC32X4_CLKMUX, AIC32X4_PLLCLKIN);
- snd_soc_write(codec, AIC32X4_IFACE3, AIC32X4_DACMOD2BCLK);
-
- /* We will fix R value to 1 and will make P & J=K.D as varialble */
- data = snd_soc_read(codec, AIC32X4_PLLPR);
- data &= ~(7 << 4);
- snd_soc_write(codec, AIC32X4_PLLPR,
- (data | (aic32x4_divs[i].p_val << 4) | 0x01));
-
- snd_soc_write(codec, AIC32X4_PLLJ, aic32x4_divs[i].pll_j);
-
- snd_soc_write(codec, AIC32X4_PLLDMSB, (aic32x4_divs[i].pll_d >> 8));
- snd_soc_write(codec, AIC32X4_PLLDLSB,
- (aic32x4_divs[i].pll_d & 0xff));
-
- /* NDAC divider value */
- data = snd_soc_read(codec, AIC32X4_NDAC);
- data &= ~(0x7f);
- snd_soc_write(codec, AIC32X4_NDAC, data | aic32x4_divs[i].ndac);
-
- /* MDAC divider value */
- data = snd_soc_read(codec, AIC32X4_MDAC);
- data &= ~(0x7f);
- snd_soc_write(codec, AIC32X4_MDAC, data | aic32x4_divs[i].mdac);
-
- /* DOSR MSB & LSB values */
- snd_soc_write(codec, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8);
- snd_soc_write(codec, AIC32X4_DOSRLSB,
- (aic32x4_divs[i].dosr & 0xff));
-
- /* NADC divider value */
- data = snd_soc_read(codec, AIC32X4_NADC);
- data &= ~(0x7f);
- snd_soc_write(codec, AIC32X4_NADC, data | aic32x4_divs[i].nadc);
-
- /* MADC divider value */
- data = snd_soc_read(codec, AIC32X4_MADC);
- data &= ~(0x7f);
- snd_soc_write(codec, AIC32X4_MADC, data | aic32x4_divs[i].madc);
-
- /* AOSR value */
- snd_soc_write(codec, AIC32X4_AOSR, aic32x4_divs[i].aosr);
-
- /* BCLK N divider */
- data = snd_soc_read(codec, AIC32X4_BCLKN);
- data &= ~(0x7f);
- snd_soc_write(codec, AIC32X4_BCLKN, data | aic32x4_divs[i].blck_N);
-
- data = snd_soc_read(codec, AIC32X4_IFACE1);
- data = data & ~(3 << 4);
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- data |= (AIC32X4_WORD_LEN_20BITS << AIC32X4_DOSRMSB_SHIFT);
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- data |= (AIC32X4_WORD_LEN_24BITS << AIC32X4_DOSRMSB_SHIFT);
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- data |= (AIC32X4_WORD_LEN_32BITS << AIC32X4_DOSRMSB_SHIFT);
- break;
- }
- snd_soc_write(codec, AIC32X4_IFACE1, data);
-
- return 0;
-}
-
-static int aic32x4_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u8 dac_reg;
-
- dac_reg = snd_soc_read(codec, AIC32X4_DACMUTE) & ~AIC32X4_MUTEON;
- if (mute)
- snd_soc_write(codec, AIC32X4_DACMUTE, dac_reg | AIC32X4_MUTEON);
- else
- snd_soc_write(codec, AIC32X4_DACMUTE, dac_reg);
- return 0;
-}
-
-static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- switch (level) {
- case SND_SOC_BIAS_ON:
- /* Switch on PLL */
- snd_soc_update_bits(codec, AIC32X4_PLLPR,
- AIC32X4_PLLEN, AIC32X4_PLLEN);
-
- /* Switch on NDAC Divider */
- snd_soc_update_bits(codec, AIC32X4_NDAC,
- AIC32X4_NDACEN, AIC32X4_NDACEN);
-
- /* Switch on MDAC Divider */
- snd_soc_update_bits(codec, AIC32X4_MDAC,
- AIC32X4_MDACEN, AIC32X4_MDACEN);
-
- /* Switch on NADC Divider */
- snd_soc_update_bits(codec, AIC32X4_NADC,
- AIC32X4_NADCEN, AIC32X4_NADCEN);
-
- /* Switch on MADC Divider */
- snd_soc_update_bits(codec, AIC32X4_MADC,
- AIC32X4_MADCEN, AIC32X4_MADCEN);
-
- /* Switch on BCLK_N Divider */
- snd_soc_update_bits(codec, AIC32X4_BCLKN,
- AIC32X4_BCLKEN, AIC32X4_BCLKEN);
- break;
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- /* Switch off PLL */
- snd_soc_update_bits(codec, AIC32X4_PLLPR,
- AIC32X4_PLLEN, 0);
-
- /* Switch off NDAC Divider */
- snd_soc_update_bits(codec, AIC32X4_NDAC,
- AIC32X4_NDACEN, 0);
-
- /* Switch off MDAC Divider */
- snd_soc_update_bits(codec, AIC32X4_MDAC,
- AIC32X4_MDACEN, 0);
-
- /* Switch off NADC Divider */
- snd_soc_update_bits(codec, AIC32X4_NADC,
- AIC32X4_NADCEN, 0);
-
- /* Switch off MADC Divider */
- snd_soc_update_bits(codec, AIC32X4_MADC,
- AIC32X4_MADCEN, 0);
-
- /* Switch off BCLK_N Divider */
- snd_soc_update_bits(codec, AIC32X4_BCLKN,
- AIC32X4_BCLKEN, 0);
- break;
- case SND_SOC_BIAS_OFF:
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define AIC32X4_RATES SNDRV_PCM_RATE_8000_48000
-#define AIC32X4_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
- | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops aic32x4_ops = {
- .hw_params = aic32x4_hw_params,
- .digital_mute = aic32x4_mute,
- .set_fmt = aic32x4_set_dai_fmt,
- .set_sysclk = aic32x4_set_dai_sysclk,
-};
-
-static struct snd_soc_dai_driver aic32x4_dai = {
- .name = "tlv320aic32x4-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = AIC32X4_RATES,
- .formats = AIC32X4_FORMATS,},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = AIC32X4_RATES,
- .formats = AIC32X4_FORMATS,},
- .ops = &aic32x4_ops,
- .symmetric_rates = 1,
-};
-
-static int aic32x4_suspend(struct snd_soc_codec *codec)
-{
- aic32x4_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int aic32x4_resume(struct snd_soc_codec *codec)
-{
- aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-
-static int aic32x4_probe(struct snd_soc_codec *codec)
-{
- struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
- u32 tmp_reg;
-
- codec->hw_write = (hw_write_t) i2c_master_send;
- codec->control_data = aic32x4->control_data;
-
- snd_soc_write(codec, AIC32X4_RESET, 0x01);
-
- /* Power platform configuration */
- if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) {
- snd_soc_write(codec, AIC32X4_MICBIAS, AIC32X4_MICBIAS_LDOIN |
- AIC32X4_MICBIAS_2075V);
- }
- if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE) {
- snd_soc_write(codec, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE);
- }
-
- tmp_reg = (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) ?
- AIC32X4_LDOCTLEN : 0;
- snd_soc_write(codec, AIC32X4_LDOCTL, tmp_reg);
-
- tmp_reg = snd_soc_read(codec, AIC32X4_CMMODE);
- if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36) {
- tmp_reg |= AIC32X4_LDOIN_18_36;
- }
- if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED) {
- tmp_reg |= AIC32X4_LDOIN2HP;
- }
- snd_soc_write(codec, AIC32X4_CMMODE, tmp_reg);
-
- /* Do DACs need to be swapped? */
- if (aic32x4->swapdacs) {
- snd_soc_write(codec, AIC32X4_DACSETUP, AIC32X4_LDAC2RCHN | AIC32X4_RDAC2LCHN);
- } else {
- snd_soc_write(codec, AIC32X4_DACSETUP, AIC32X4_LDAC2LCHN | AIC32X4_RDAC2RCHN);
- }
-
- /* Mic PGA routing */
- if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K) {
- snd_soc_write(codec, AIC32X4_LMICPGANIN, AIC32X4_LMICPGANIN_IN2R_10K);
- }
- if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K) {
- snd_soc_write(codec, AIC32X4_RMICPGANIN, AIC32X4_RMICPGANIN_IN1L_10K);
- }
-
- aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- snd_soc_add_codec_controls(codec, aic32x4_snd_controls,
- ARRAY_SIZE(aic32x4_snd_controls));
- aic32x4_add_widgets(codec);
-
- return 0;
-}
-
-static int aic32x4_remove(struct snd_soc_codec *codec)
-{
- aic32x4_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = {
- .read = aic32x4_read,
- .write = aic32x4_write,
- .probe = aic32x4_probe,
- .remove = aic32x4_remove,
- .suspend = aic32x4_suspend,
- .resume = aic32x4_resume,
- .set_bias_level = aic32x4_set_bias_level,
-};
-
-static __devinit int aic32x4_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct aic32x4_pdata *pdata = i2c->dev.platform_data;
- struct aic32x4_priv *aic32x4;
- int ret;
-
- aic32x4 = devm_kzalloc(&i2c->dev, sizeof(struct aic32x4_priv),
- GFP_KERNEL);
- if (aic32x4 == NULL)
- return -ENOMEM;
-
- aic32x4->control_data = i2c;
- i2c_set_clientdata(i2c, aic32x4);
-
- if (pdata) {
- aic32x4->power_cfg = pdata->power_cfg;
- aic32x4->swapdacs = pdata->swapdacs;
- aic32x4->micpga_routing = pdata->micpga_routing;
- } else {
- aic32x4->power_cfg = 0;
- aic32x4->swapdacs = false;
- aic32x4->micpga_routing = 0;
- }
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_aic32x4, &aic32x4_dai, 1);
- return ret;
-}
-
-static __devexit int aic32x4_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static const struct i2c_device_id aic32x4_i2c_id[] = {
- { "tlv320aic32x4", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, aic32x4_i2c_id);
-
-static struct i2c_driver aic32x4_i2c_driver = {
- .driver = {
- .name = "tlv320aic32x4",
- .owner = THIS_MODULE,
- },
- .probe = aic32x4_i2c_probe,
- .remove = __devexit_p(aic32x4_i2c_remove),
- .id_table = aic32x4_i2c_id,
-};
-
-static int __init aic32x4_modinit(void)
-{
- int ret = 0;
-
- ret = i2c_add_driver(&aic32x4_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register aic32x4 I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(aic32x4_modinit);
-
-static void __exit aic32x4_exit(void)
-{
- i2c_del_driver(&aic32x4_i2c_driver);
-}
-module_exit(aic32x4_exit);
-
-MODULE_DESCRIPTION("ASoC tlv320aic32x4 codec driver");
-MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/tlv320aic32x4.h b/ANDROID_3.4.5/sound/soc/codecs/tlv320aic32x4.h
deleted file mode 100644
index aae2b244..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/tlv320aic32x4.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * tlv320aic32x4.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-
-#ifndef _TLV320AIC32X4_H
-#define _TLV320AIC32X4_H
-
-/* tlv320aic32x4 register space (in decimal to match datasheet) */
-
-#define AIC32X4_PAGE1 128
-
-#define AIC32X4_PSEL 0
-#define AIC32X4_RESET 1
-#define AIC32X4_CLKMUX 4
-#define AIC32X4_PLLPR 5
-#define AIC32X4_PLLJ 6
-#define AIC32X4_PLLDMSB 7
-#define AIC32X4_PLLDLSB 8
-#define AIC32X4_NDAC 11
-#define AIC32X4_MDAC 12
-#define AIC32X4_DOSRMSB 13
-#define AIC32X4_DOSRLSB 14
-#define AIC32X4_NADC 18
-#define AIC32X4_MADC 19
-#define AIC32X4_AOSR 20
-#define AIC32X4_CLKMUX2 25
-#define AIC32X4_CLKOUTM 26
-#define AIC32X4_IFACE1 27
-#define AIC32X4_IFACE2 28
-#define AIC32X4_IFACE3 29
-#define AIC32X4_BCLKN 30
-#define AIC32X4_IFACE4 31
-#define AIC32X4_IFACE5 32
-#define AIC32X4_IFACE6 33
-#define AIC32X4_DOUTCTL 53
-#define AIC32X4_DINCTL 54
-#define AIC32X4_DACSPB 60
-#define AIC32X4_ADCSPB 61
-#define AIC32X4_DACSETUP 63
-#define AIC32X4_DACMUTE 64
-#define AIC32X4_LDACVOL 65
-#define AIC32X4_RDACVOL 66
-#define AIC32X4_ADCSETUP 81
-#define AIC32X4_ADCFGA 82
-#define AIC32X4_LADCVOL 83
-#define AIC32X4_RADCVOL 84
-#define AIC32X4_LAGC1 86
-#define AIC32X4_LAGC2 87
-#define AIC32X4_LAGC3 88
-#define AIC32X4_LAGC4 89
-#define AIC32X4_LAGC5 90
-#define AIC32X4_LAGC6 91
-#define AIC32X4_LAGC7 92
-#define AIC32X4_RAGC1 94
-#define AIC32X4_RAGC2 95
-#define AIC32X4_RAGC3 96
-#define AIC32X4_RAGC4 97
-#define AIC32X4_RAGC5 98
-#define AIC32X4_RAGC6 99
-#define AIC32X4_RAGC7 100
-#define AIC32X4_PWRCFG (AIC32X4_PAGE1 + 1)
-#define AIC32X4_LDOCTL (AIC32X4_PAGE1 + 2)
-#define AIC32X4_OUTPWRCTL (AIC32X4_PAGE1 + 9)
-#define AIC32X4_CMMODE (AIC32X4_PAGE1 + 10)
-#define AIC32X4_HPLROUTE (AIC32X4_PAGE1 + 12)
-#define AIC32X4_HPRROUTE (AIC32X4_PAGE1 + 13)
-#define AIC32X4_LOLROUTE (AIC32X4_PAGE1 + 14)
-#define AIC32X4_LORROUTE (AIC32X4_PAGE1 + 15)
-#define AIC32X4_HPLGAIN (AIC32X4_PAGE1 + 16)
-#define AIC32X4_HPRGAIN (AIC32X4_PAGE1 + 17)
-#define AIC32X4_LOLGAIN (AIC32X4_PAGE1 + 18)
-#define AIC32X4_LORGAIN (AIC32X4_PAGE1 + 19)
-#define AIC32X4_HEADSTART (AIC32X4_PAGE1 + 20)
-#define AIC32X4_MICBIAS (AIC32X4_PAGE1 + 51)
-#define AIC32X4_LMICPGAPIN (AIC32X4_PAGE1 + 52)
-#define AIC32X4_LMICPGANIN (AIC32X4_PAGE1 + 54)
-#define AIC32X4_RMICPGAPIN (AIC32X4_PAGE1 + 55)
-#define AIC32X4_RMICPGANIN (AIC32X4_PAGE1 + 57)
-#define AIC32X4_FLOATINGINPUT (AIC32X4_PAGE1 + 58)
-#define AIC32X4_LMICPGAVOL (AIC32X4_PAGE1 + 59)
-#define AIC32X4_RMICPGAVOL (AIC32X4_PAGE1 + 60)
-
-#define AIC32X4_FREQ_12000000 12000000
-#define AIC32X4_FREQ_24000000 24000000
-#define AIC32X4_FREQ_25000000 25000000
-
-#define AIC32X4_WORD_LEN_16BITS 0x00
-#define AIC32X4_WORD_LEN_20BITS 0x01
-#define AIC32X4_WORD_LEN_24BITS 0x02
-#define AIC32X4_WORD_LEN_32BITS 0x03
-
-#define AIC32X4_I2S_MODE 0x00
-#define AIC32X4_DSP_MODE 0x01
-#define AIC32X4_RIGHT_JUSTIFIED_MODE 0x02
-#define AIC32X4_LEFT_JUSTIFIED_MODE 0x03
-
-#define AIC32X4_AVDDWEAKDISABLE 0x08
-#define AIC32X4_LDOCTLEN 0x01
-
-#define AIC32X4_LDOIN_18_36 0x01
-#define AIC32X4_LDOIN2HP 0x02
-
-#define AIC32X4_DACSPBLOCK_MASK 0x1f
-#define AIC32X4_ADCSPBLOCK_MASK 0x1f
-
-#define AIC32X4_PLLJ_SHIFT 6
-#define AIC32X4_DOSRMSB_SHIFT 4
-
-#define AIC32X4_PLLCLKIN 0x03
-
-#define AIC32X4_MICBIAS_LDOIN 0x08
-#define AIC32X4_MICBIAS_2075V 0x60
-
-#define AIC32X4_LMICPGANIN_IN2R_10K 0x10
-#define AIC32X4_RMICPGANIN_IN1L_10K 0x10
-
-#define AIC32X4_LMICPGAVOL_NOGAIN 0x80
-#define AIC32X4_RMICPGAVOL_NOGAIN 0x80
-
-#define AIC32X4_BCLKMASTER 0x08
-#define AIC32X4_WCLKMASTER 0x04
-#define AIC32X4_PLLEN (0x01 << 7)
-#define AIC32X4_NDACEN (0x01 << 7)
-#define AIC32X4_MDACEN (0x01 << 7)
-#define AIC32X4_NADCEN (0x01 << 7)
-#define AIC32X4_MADCEN (0x01 << 7)
-#define AIC32X4_BCLKEN (0x01 << 7)
-#define AIC32X4_DACEN (0x03 << 6)
-#define AIC32X4_RDAC2LCHN (0x02 << 2)
-#define AIC32X4_LDAC2RCHN (0x02 << 4)
-#define AIC32X4_LDAC2LCHN (0x01 << 4)
-#define AIC32X4_RDAC2RCHN (0x01 << 2)
-
-#define AIC32X4_SSTEP2WCLK 0x01
-#define AIC32X4_MUTEON 0x0C
-#define AIC32X4_DACMOD2BCLK 0x01
-
-#endif /* _TLV320AIC32X4_H */
diff --git a/ANDROID_3.4.5/sound/soc/codecs/tlv320aic3x.c b/ANDROID_3.4.5/sound/soc/codecs/tlv320aic3x.c
deleted file mode 100644
index b8f0262a..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/tlv320aic3x.c
+++ /dev/null
@@ -1,1505 +0,0 @@
-/*
- * ALSA SoC TLV320AIC3X codec driver
- *
- * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
- * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
- *
- * Based on sound/soc/codecs/wm8753.c by Liam Girdwood
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Notes:
- * The AIC3X is a driver for a low power stereo audio
- * codecs aic31, aic32, aic33, aic3007.
- *
- * It supports full aic33 codec functionality.
- * The compatibility with aic32, aic31 and aic3007 is as follows:
- * aic32/aic3007 | aic31
- * ---------------------------------------
- * MONO_LOUT -> N/A | MONO_LOUT -> N/A
- * | IN1L -> LINE1L
- * | IN1R -> LINE1R
- * | IN2L -> LINE2L
- * | IN2R -> LINE2R
- * | MIC3L/R -> N/A
- * truncated internal functionality in
- * accordance with documentation
- * ---------------------------------------
- *
- * Hence the machine layer should disable unsupported inputs/outputs by
- * snd_soc_dapm_disable_pin(codec, "MONO_LOUT"), etc.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/gpio.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <sound/tlv320aic3x.h>
-
-#include "tlv320aic3x.h"
-
-#define AIC3X_NUM_SUPPLIES 4
-static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = {
- "IOVDD", /* I/O Voltage */
- "DVDD", /* Digital Core Voltage */
- "AVDD", /* Analog DAC Voltage */
- "DRVDD", /* ADC Analog and Output Driver Voltage */
-};
-
-static LIST_HEAD(reset_list);
-
-struct aic3x_priv;
-
-struct aic3x_disable_nb {
- struct notifier_block nb;
- struct aic3x_priv *aic3x;
-};
-
-/* codec private data */
-struct aic3x_priv {
- struct snd_soc_codec *codec;
- struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES];
- struct aic3x_disable_nb disable_nb[AIC3X_NUM_SUPPLIES];
- enum snd_soc_control_type control_type;
- struct aic3x_setup_data *setup;
- unsigned int sysclk;
- struct list_head list;
- int master;
- int gpio_reset;
- int power;
-#define AIC3X_MODEL_3X 0
-#define AIC3X_MODEL_33 1
-#define AIC3X_MODEL_3007 2
- u16 model;
-};
-
-/*
- * AIC3X register cache
- * We can't read the AIC3X register space when we are
- * using 2 wire for device control, so we cache them instead.
- * There is no point in caching the reset register
- */
-static const u8 aic3x_reg[AIC3X_CACHEREGNUM] = {
- 0x00, 0x00, 0x00, 0x10, /* 0 */
- 0x04, 0x00, 0x00, 0x00, /* 4 */
- 0x00, 0x00, 0x00, 0x01, /* 8 */
- 0x00, 0x00, 0x00, 0x80, /* 12 */
- 0x80, 0xff, 0xff, 0x78, /* 16 */
- 0x78, 0x78, 0x78, 0x78, /* 20 */
- 0x78, 0x00, 0x00, 0xfe, /* 24 */
- 0x00, 0x00, 0xfe, 0x00, /* 28 */
- 0x18, 0x18, 0x00, 0x00, /* 32 */
- 0x00, 0x00, 0x00, 0x00, /* 36 */
- 0x00, 0x00, 0x00, 0x80, /* 40 */
- 0x80, 0x00, 0x00, 0x00, /* 44 */
- 0x00, 0x00, 0x00, 0x04, /* 48 */
- 0x00, 0x00, 0x00, 0x00, /* 52 */
- 0x00, 0x00, 0x04, 0x00, /* 56 */
- 0x00, 0x00, 0x00, 0x00, /* 60 */
- 0x00, 0x04, 0x00, 0x00, /* 64 */
- 0x00, 0x00, 0x00, 0x00, /* 68 */
- 0x04, 0x00, 0x00, 0x00, /* 72 */
- 0x00, 0x00, 0x00, 0x00, /* 76 */
- 0x00, 0x00, 0x00, 0x00, /* 80 */
- 0x00, 0x00, 0x00, 0x00, /* 84 */
- 0x00, 0x00, 0x00, 0x00, /* 88 */
- 0x00, 0x00, 0x00, 0x00, /* 92 */
- 0x00, 0x00, 0x00, 0x00, /* 96 */
- 0x00, 0x00, 0x02, /* 100 */
-};
-
-#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_soc_info_volsw, \
- .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw_aic3x, \
- .private_value = SOC_SINGLE_VALUE(reg, shift, mask, invert) }
-
-/*
- * All input lines are connected when !0xf and disconnected with 0xf bit field,
- * so we have to use specific dapm_put call for input mixer
- */
-static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
- struct snd_soc_dapm_widget *widget = wlist->widgets[0];
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- unsigned int reg = mc->reg;
- unsigned int shift = mc->shift;
- int max = mc->max;
- unsigned int mask = (1 << fls(max)) - 1;
- unsigned int invert = mc->invert;
- unsigned short val, val_mask;
- int ret;
- struct snd_soc_dapm_path *path;
- int found = 0;
-
- val = (ucontrol->value.integer.value[0] & mask);
-
- mask = 0xf;
- if (val)
- val = mask;
-
- if (invert)
- val = mask - val;
- val_mask = mask << shift;
- val = val << shift;
-
- mutex_lock(&widget->codec->mutex);
-
- if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) {
- /* find dapm widget path assoc with kcontrol */
- list_for_each_entry(path, &widget->dapm->card->paths, list) {
- if (path->kcontrol != kcontrol)
- continue;
-
- /* found, now check type */
- found = 1;
- if (val)
- /* new connection */
- path->connect = invert ? 0 : 1;
- else
- /* old connection must be powered down */
- path->connect = invert ? 1 : 0;
-
- dapm_mark_dirty(path->source, "tlv320aic3x source");
- dapm_mark_dirty(path->sink, "tlv320aic3x sink");
-
- break;
- }
-
- if (found)
- snd_soc_dapm_sync(widget->dapm);
- }
-
- ret = snd_soc_update_bits(widget->codec, reg, val_mask, val);
-
- mutex_unlock(&widget->codec->mutex);
- return ret;
-}
-
-static const char *aic3x_left_dac_mux[] = { "DAC_L1", "DAC_L3", "DAC_L2" };
-static const char *aic3x_right_dac_mux[] = { "DAC_R1", "DAC_R3", "DAC_R2" };
-static const char *aic3x_left_hpcom_mux[] =
- { "differential of HPLOUT", "constant VCM", "single-ended" };
-static const char *aic3x_right_hpcom_mux[] =
- { "differential of HPROUT", "constant VCM", "single-ended",
- "differential of HPLCOM", "external feedback" };
-static const char *aic3x_linein_mode_mux[] = { "single-ended", "differential" };
-static const char *aic3x_adc_hpf[] =
- { "Disabled", "0.0045xFs", "0.0125xFs", "0.025xFs" };
-
-#define LDAC_ENUM 0
-#define RDAC_ENUM 1
-#define LHPCOM_ENUM 2
-#define RHPCOM_ENUM 3
-#define LINE1L_2_L_ENUM 4
-#define LINE1L_2_R_ENUM 5
-#define LINE1R_2_L_ENUM 6
-#define LINE1R_2_R_ENUM 7
-#define LINE2L_ENUM 8
-#define LINE2R_ENUM 9
-#define ADC_HPF_ENUM 10
-
-static const struct soc_enum aic3x_enum[] = {
- SOC_ENUM_SINGLE(DAC_LINE_MUX, 6, 3, aic3x_left_dac_mux),
- SOC_ENUM_SINGLE(DAC_LINE_MUX, 4, 3, aic3x_right_dac_mux),
- SOC_ENUM_SINGLE(HPLCOM_CFG, 4, 3, aic3x_left_hpcom_mux),
- SOC_ENUM_SINGLE(HPRCOM_CFG, 3, 5, aic3x_right_hpcom_mux),
- SOC_ENUM_SINGLE(LINE1L_2_LADC_CTRL, 7, 2, aic3x_linein_mode_mux),
- SOC_ENUM_SINGLE(LINE1L_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux),
- SOC_ENUM_SINGLE(LINE1R_2_LADC_CTRL, 7, 2, aic3x_linein_mode_mux),
- SOC_ENUM_SINGLE(LINE1R_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux),
- SOC_ENUM_SINGLE(LINE2L_2_LADC_CTRL, 7, 2, aic3x_linein_mode_mux),
- SOC_ENUM_SINGLE(LINE2R_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux),
- SOC_ENUM_DOUBLE(AIC3X_CODEC_DFILT_CTRL, 6, 4, 4, aic3x_adc_hpf),
-};
-
-/*
- * DAC digital volumes. From -63.5 to 0 dB in 0.5 dB steps
- */
-static DECLARE_TLV_DB_SCALE(dac_tlv, -6350, 50, 0);
-/* ADC PGA gain volumes. From 0 to 59.5 dB in 0.5 dB steps */
-static DECLARE_TLV_DB_SCALE(adc_tlv, 0, 50, 0);
-/*
- * Output stage volumes. From -78.3 to 0 dB. Muted below -78.3 dB.
- * Step size is approximately 0.5 dB over most of the scale but increasing
- * near the very low levels.
- * Define dB scale so that it is mostly correct for range about -55 to 0 dB
- * but having increasing dB difference below that (and where it doesn't count
- * so much). This setting shows -50 dB (actual is -50.3 dB) for register
- * value 100 and -58.5 dB (actual is -78.3 dB) for register value 117.
- */
-static DECLARE_TLV_DB_SCALE(output_stage_tlv, -5900, 50, 1);
-
-static const struct snd_kcontrol_new aic3x_snd_controls[] = {
- /* Output */
- SOC_DOUBLE_R_TLV("PCM Playback Volume",
- LDAC_VOL, RDAC_VOL, 0, 0x7f, 1, dac_tlv),
-
- /*
- * Output controls that map to output mixer switches. Note these are
- * only for swapped L-to-R and R-to-L routes. See below stereo controls
- * for direct L-to-L and R-to-R routes.
- */
- SOC_SINGLE_TLV("Left Line Mixer Line2R Bypass Volume",
- LINE2R_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv),
- SOC_SINGLE_TLV("Left Line Mixer PGAR Bypass Volume",
- PGAR_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv),
- SOC_SINGLE_TLV("Left Line Mixer DACR1 Playback Volume",
- DACR1_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv),
-
- SOC_SINGLE_TLV("Right Line Mixer Line2L Bypass Volume",
- LINE2L_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv),
- SOC_SINGLE_TLV("Right Line Mixer PGAL Bypass Volume",
- PGAL_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv),
- SOC_SINGLE_TLV("Right Line Mixer DACL1 Playback Volume",
- DACL1_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv),
-
- SOC_SINGLE_TLV("Left HP Mixer Line2R Bypass Volume",
- LINE2R_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv),
- SOC_SINGLE_TLV("Left HP Mixer PGAR Bypass Volume",
- PGAR_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv),
- SOC_SINGLE_TLV("Left HP Mixer DACR1 Playback Volume",
- DACR1_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv),
-
- SOC_SINGLE_TLV("Right HP Mixer Line2L Bypass Volume",
- LINE2L_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv),
- SOC_SINGLE_TLV("Right HP Mixer PGAL Bypass Volume",
- PGAL_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv),
- SOC_SINGLE_TLV("Right HP Mixer DACL1 Playback Volume",
- DACL1_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv),
-
- SOC_SINGLE_TLV("Left HPCOM Mixer Line2R Bypass Volume",
- LINE2R_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv),
- SOC_SINGLE_TLV("Left HPCOM Mixer PGAR Bypass Volume",
- PGAR_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv),
- SOC_SINGLE_TLV("Left HPCOM Mixer DACR1 Playback Volume",
- DACR1_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv),
-
- SOC_SINGLE_TLV("Right HPCOM Mixer Line2L Bypass Volume",
- LINE2L_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv),
- SOC_SINGLE_TLV("Right HPCOM Mixer PGAL Bypass Volume",
- PGAL_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv),
- SOC_SINGLE_TLV("Right HPCOM Mixer DACL1 Playback Volume",
- DACL1_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv),
-
- /* Stereo output controls for direct L-to-L and R-to-R routes */
- SOC_DOUBLE_R_TLV("Line Line2 Bypass Volume",
- LINE2L_2_LLOPM_VOL, LINE2R_2_RLOPM_VOL,
- 0, 118, 1, output_stage_tlv),
- SOC_DOUBLE_R_TLV("Line PGA Bypass Volume",
- PGAL_2_LLOPM_VOL, PGAR_2_RLOPM_VOL,
- 0, 118, 1, output_stage_tlv),
- SOC_DOUBLE_R_TLV("Line DAC Playback Volume",
- DACL1_2_LLOPM_VOL, DACR1_2_RLOPM_VOL,
- 0, 118, 1, output_stage_tlv),
-
- SOC_DOUBLE_R_TLV("Mono Line2 Bypass Volume",
- LINE2L_2_MONOLOPM_VOL, LINE2R_2_MONOLOPM_VOL,
- 0, 118, 1, output_stage_tlv),
- SOC_DOUBLE_R_TLV("Mono PGA Bypass Volume",
- PGAL_2_MONOLOPM_VOL, PGAR_2_MONOLOPM_VOL,
- 0, 118, 1, output_stage_tlv),
- SOC_DOUBLE_R_TLV("Mono DAC Playback Volume",
- DACL1_2_MONOLOPM_VOL, DACR1_2_MONOLOPM_VOL,
- 0, 118, 1, output_stage_tlv),
-
- SOC_DOUBLE_R_TLV("HP Line2 Bypass Volume",
- LINE2L_2_HPLOUT_VOL, LINE2R_2_HPROUT_VOL,
- 0, 118, 1, output_stage_tlv),
- SOC_DOUBLE_R_TLV("HP PGA Bypass Volume",
- PGAL_2_HPLOUT_VOL, PGAR_2_HPROUT_VOL,
- 0, 118, 1, output_stage_tlv),
- SOC_DOUBLE_R_TLV("HP DAC Playback Volume",
- DACL1_2_HPLOUT_VOL, DACR1_2_HPROUT_VOL,
- 0, 118, 1, output_stage_tlv),
-
- SOC_DOUBLE_R_TLV("HPCOM Line2 Bypass Volume",
- LINE2L_2_HPLCOM_VOL, LINE2R_2_HPRCOM_VOL,
- 0, 118, 1, output_stage_tlv),
- SOC_DOUBLE_R_TLV("HPCOM PGA Bypass Volume",
- PGAL_2_HPLCOM_VOL, PGAR_2_HPRCOM_VOL,
- 0, 118, 1, output_stage_tlv),
- SOC_DOUBLE_R_TLV("HPCOM DAC Playback Volume",
- DACL1_2_HPLCOM_VOL, DACR1_2_HPRCOM_VOL,
- 0, 118, 1, output_stage_tlv),
-
- /* Output pin mute controls */
- SOC_DOUBLE_R("Line Playback Switch", LLOPM_CTRL, RLOPM_CTRL, 3,
- 0x01, 0),
- SOC_SINGLE("Mono Playback Switch", MONOLOPM_CTRL, 3, 0x01, 0),
- SOC_DOUBLE_R("HP Playback Switch", HPLOUT_CTRL, HPROUT_CTRL, 3,
- 0x01, 0),
- SOC_DOUBLE_R("HPCOM Playback Switch", HPLCOM_CTRL, HPRCOM_CTRL, 3,
- 0x01, 0),
-
- /*
- * Note: enable Automatic input Gain Controller with care. It can
- * adjust PGA to max value when ADC is on and will never go back.
- */
- SOC_DOUBLE_R("AGC Switch", LAGC_CTRL_A, RAGC_CTRL_A, 7, 0x01, 0),
-
- /* Input */
- SOC_DOUBLE_R_TLV("PGA Capture Volume", LADC_VOL, RADC_VOL,
- 0, 119, 0, adc_tlv),
- SOC_DOUBLE_R("PGA Capture Switch", LADC_VOL, RADC_VOL, 7, 0x01, 1),
-
- SOC_ENUM("ADC HPF Cut-off", aic3x_enum[ADC_HPF_ENUM]),
-};
-
-/*
- * Class-D amplifier gain. From 0 to 18 dB in 6 dB steps
- */
-static DECLARE_TLV_DB_SCALE(classd_amp_tlv, 0, 600, 0);
-
-static const struct snd_kcontrol_new aic3x_classd_amp_gain_ctrl =
- SOC_DOUBLE_TLV("Class-D Amplifier Gain", CLASSD_CTRL, 6, 4, 3, 0, classd_amp_tlv);
-
-/* Left DAC Mux */
-static const struct snd_kcontrol_new aic3x_left_dac_mux_controls =
-SOC_DAPM_ENUM("Route", aic3x_enum[LDAC_ENUM]);
-
-/* Right DAC Mux */
-static const struct snd_kcontrol_new aic3x_right_dac_mux_controls =
-SOC_DAPM_ENUM("Route", aic3x_enum[RDAC_ENUM]);
-
-/* Left HPCOM Mux */
-static const struct snd_kcontrol_new aic3x_left_hpcom_mux_controls =
-SOC_DAPM_ENUM("Route", aic3x_enum[LHPCOM_ENUM]);
-
-/* Right HPCOM Mux */
-static const struct snd_kcontrol_new aic3x_right_hpcom_mux_controls =
-SOC_DAPM_ENUM("Route", aic3x_enum[RHPCOM_ENUM]);
-
-/* Left Line Mixer */
-static const struct snd_kcontrol_new aic3x_left_line_mixer_controls[] = {
- SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_LLOPM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_LLOPM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_LLOPM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_LLOPM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_LLOPM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_LLOPM_VOL, 7, 1, 0),
-};
-
-/* Right Line Mixer */
-static const struct snd_kcontrol_new aic3x_right_line_mixer_controls[] = {
- SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_RLOPM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_RLOPM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_RLOPM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_RLOPM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_RLOPM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_RLOPM_VOL, 7, 1, 0),
-};
-
-/* Mono Mixer */
-static const struct snd_kcontrol_new aic3x_mono_mixer_controls[] = {
- SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_MONOLOPM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_MONOLOPM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_MONOLOPM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_MONOLOPM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_MONOLOPM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_MONOLOPM_VOL, 7, 1, 0),
-};
-
-/* Left HP Mixer */
-static const struct snd_kcontrol_new aic3x_left_hp_mixer_controls[] = {
- SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPLOUT_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPLOUT_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPLOUT_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPLOUT_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPLOUT_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPLOUT_VOL, 7, 1, 0),
-};
-
-/* Right HP Mixer */
-static const struct snd_kcontrol_new aic3x_right_hp_mixer_controls[] = {
- SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPROUT_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPROUT_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPROUT_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPROUT_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPROUT_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPROUT_VOL, 7, 1, 0),
-};
-
-/* Left HPCOM Mixer */
-static const struct snd_kcontrol_new aic3x_left_hpcom_mixer_controls[] = {
- SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPLCOM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPLCOM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPLCOM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPLCOM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPLCOM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPLCOM_VOL, 7, 1, 0),
-};
-
-/* Right HPCOM Mixer */
-static const struct snd_kcontrol_new aic3x_right_hpcom_mixer_controls[] = {
- SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPRCOM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPRCOM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPRCOM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPRCOM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPRCOM_VOL, 7, 1, 0),
- SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPRCOM_VOL, 7, 1, 0),
-};
-
-/* Left PGA Mixer */
-static const struct snd_kcontrol_new aic3x_left_pga_mixer_controls[] = {
- SOC_DAPM_SINGLE_AIC3X("Line1L Switch", LINE1L_2_LADC_CTRL, 3, 1, 1),
- SOC_DAPM_SINGLE_AIC3X("Line1R Switch", LINE1R_2_LADC_CTRL, 3, 1, 1),
- SOC_DAPM_SINGLE_AIC3X("Line2L Switch", LINE2L_2_LADC_CTRL, 3, 1, 1),
- SOC_DAPM_SINGLE_AIC3X("Mic3L Switch", MIC3LR_2_LADC_CTRL, 4, 1, 1),
- SOC_DAPM_SINGLE_AIC3X("Mic3R Switch", MIC3LR_2_LADC_CTRL, 0, 1, 1),
-};
-
-/* Right PGA Mixer */
-static const struct snd_kcontrol_new aic3x_right_pga_mixer_controls[] = {
- SOC_DAPM_SINGLE_AIC3X("Line1R Switch", LINE1R_2_RADC_CTRL, 3, 1, 1),
- SOC_DAPM_SINGLE_AIC3X("Line1L Switch", LINE1L_2_RADC_CTRL, 3, 1, 1),
- SOC_DAPM_SINGLE_AIC3X("Line2R Switch", LINE2R_2_RADC_CTRL, 3, 1, 1),
- SOC_DAPM_SINGLE_AIC3X("Mic3L Switch", MIC3LR_2_RADC_CTRL, 4, 1, 1),
- SOC_DAPM_SINGLE_AIC3X("Mic3R Switch", MIC3LR_2_RADC_CTRL, 0, 1, 1),
-};
-
-/* Left Line1 Mux */
-static const struct snd_kcontrol_new aic3x_left_line1l_mux_controls =
-SOC_DAPM_ENUM("Route", aic3x_enum[LINE1L_2_L_ENUM]);
-static const struct snd_kcontrol_new aic3x_right_line1l_mux_controls =
-SOC_DAPM_ENUM("Route", aic3x_enum[LINE1L_2_R_ENUM]);
-
-/* Right Line1 Mux */
-static const struct snd_kcontrol_new aic3x_right_line1r_mux_controls =
-SOC_DAPM_ENUM("Route", aic3x_enum[LINE1R_2_R_ENUM]);
-static const struct snd_kcontrol_new aic3x_left_line1r_mux_controls =
-SOC_DAPM_ENUM("Route", aic3x_enum[LINE1R_2_L_ENUM]);
-
-/* Left Line2 Mux */
-static const struct snd_kcontrol_new aic3x_left_line2_mux_controls =
-SOC_DAPM_ENUM("Route", aic3x_enum[LINE2L_ENUM]);
-
-/* Right Line2 Mux */
-static const struct snd_kcontrol_new aic3x_right_line2_mux_controls =
-SOC_DAPM_ENUM("Route", aic3x_enum[LINE2R_ENUM]);
-
-static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
- /* Left DAC to Left Outputs */
- SND_SOC_DAPM_DAC("Left DAC", "Left Playback", DAC_PWR, 7, 0),
- SND_SOC_DAPM_MUX("Left DAC Mux", SND_SOC_NOPM, 0, 0,
- &aic3x_left_dac_mux_controls),
- SND_SOC_DAPM_MUX("Left HPCOM Mux", SND_SOC_NOPM, 0, 0,
- &aic3x_left_hpcom_mux_controls),
- SND_SOC_DAPM_PGA("Left Line Out", LLOPM_CTRL, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Left HP Out", HPLOUT_CTRL, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Left HP Com", HPLCOM_CTRL, 0, 0, NULL, 0),
-
- /* Right DAC to Right Outputs */
- SND_SOC_DAPM_DAC("Right DAC", "Right Playback", DAC_PWR, 6, 0),
- SND_SOC_DAPM_MUX("Right DAC Mux", SND_SOC_NOPM, 0, 0,
- &aic3x_right_dac_mux_controls),
- SND_SOC_DAPM_MUX("Right HPCOM Mux", SND_SOC_NOPM, 0, 0,
- &aic3x_right_hpcom_mux_controls),
- SND_SOC_DAPM_PGA("Right Line Out", RLOPM_CTRL, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Right HP Out", HPROUT_CTRL, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Right HP Com", HPRCOM_CTRL, 0, 0, NULL, 0),
-
- /* Mono Output */
- SND_SOC_DAPM_PGA("Mono Out", MONOLOPM_CTRL, 0, 0, NULL, 0),
-
- /* Inputs to Left ADC */
- SND_SOC_DAPM_ADC("Left ADC", "Left Capture", LINE1L_2_LADC_CTRL, 2, 0),
- SND_SOC_DAPM_MIXER("Left PGA Mixer", SND_SOC_NOPM, 0, 0,
- &aic3x_left_pga_mixer_controls[0],
- ARRAY_SIZE(aic3x_left_pga_mixer_controls)),
- SND_SOC_DAPM_MUX("Left Line1L Mux", SND_SOC_NOPM, 0, 0,
- &aic3x_left_line1l_mux_controls),
- SND_SOC_DAPM_MUX("Left Line1R Mux", SND_SOC_NOPM, 0, 0,
- &aic3x_left_line1r_mux_controls),
- SND_SOC_DAPM_MUX("Left Line2L Mux", SND_SOC_NOPM, 0, 0,
- &aic3x_left_line2_mux_controls),
-
- /* Inputs to Right ADC */
- SND_SOC_DAPM_ADC("Right ADC", "Right Capture",
- LINE1R_2_RADC_CTRL, 2, 0),
- SND_SOC_DAPM_MIXER("Right PGA Mixer", SND_SOC_NOPM, 0, 0,
- &aic3x_right_pga_mixer_controls[0],
- ARRAY_SIZE(aic3x_right_pga_mixer_controls)),
- SND_SOC_DAPM_MUX("Right Line1L Mux", SND_SOC_NOPM, 0, 0,
- &aic3x_right_line1l_mux_controls),
- SND_SOC_DAPM_MUX("Right Line1R Mux", SND_SOC_NOPM, 0, 0,
- &aic3x_right_line1r_mux_controls),
- SND_SOC_DAPM_MUX("Right Line2R Mux", SND_SOC_NOPM, 0, 0,
- &aic3x_right_line2_mux_controls),
-
- /*
- * Not a real mic bias widget but similar function. This is for dynamic
- * control of GPIO1 digital mic modulator clock output function when
- * using digital mic.
- */
- SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "GPIO1 dmic modclk",
- AIC3X_GPIO1_REG, 4, 0xf,
- AIC3X_GPIO1_FUNC_DIGITAL_MIC_MODCLK,
- AIC3X_GPIO1_FUNC_DISABLED),
-
- /*
- * Also similar function like mic bias. Selects digital mic with
- * configurable oversampling rate instead of ADC converter.
- */
- SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "DMic Rate 128",
- AIC3X_ASD_INTF_CTRLA, 0, 3, 1, 0),
- SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "DMic Rate 64",
- AIC3X_ASD_INTF_CTRLA, 0, 3, 2, 0),
- SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "DMic Rate 32",
- AIC3X_ASD_INTF_CTRLA, 0, 3, 3, 0),
-
- /* Mic Bias */
- SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias 2V",
- MICBIAS_CTRL, 6, 3, 1, 0),
- SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias 2.5V",
- MICBIAS_CTRL, 6, 3, 2, 0),
- SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias AVDD",
- MICBIAS_CTRL, 6, 3, 3, 0),
-
- /* Output mixers */
- SND_SOC_DAPM_MIXER("Left Line Mixer", SND_SOC_NOPM, 0, 0,
- &aic3x_left_line_mixer_controls[0],
- ARRAY_SIZE(aic3x_left_line_mixer_controls)),
- SND_SOC_DAPM_MIXER("Right Line Mixer", SND_SOC_NOPM, 0, 0,
- &aic3x_right_line_mixer_controls[0],
- ARRAY_SIZE(aic3x_right_line_mixer_controls)),
- SND_SOC_DAPM_MIXER("Mono Mixer", SND_SOC_NOPM, 0, 0,
- &aic3x_mono_mixer_controls[0],
- ARRAY_SIZE(aic3x_mono_mixer_controls)),
- SND_SOC_DAPM_MIXER("Left HP Mixer", SND_SOC_NOPM, 0, 0,
- &aic3x_left_hp_mixer_controls[0],
- ARRAY_SIZE(aic3x_left_hp_mixer_controls)),
- SND_SOC_DAPM_MIXER("Right HP Mixer", SND_SOC_NOPM, 0, 0,
- &aic3x_right_hp_mixer_controls[0],
- ARRAY_SIZE(aic3x_right_hp_mixer_controls)),
- SND_SOC_DAPM_MIXER("Left HPCOM Mixer", SND_SOC_NOPM, 0, 0,
- &aic3x_left_hpcom_mixer_controls[0],
- ARRAY_SIZE(aic3x_left_hpcom_mixer_controls)),
- SND_SOC_DAPM_MIXER("Right HPCOM Mixer", SND_SOC_NOPM, 0, 0,
- &aic3x_right_hpcom_mixer_controls[0],
- ARRAY_SIZE(aic3x_right_hpcom_mixer_controls)),
-
- SND_SOC_DAPM_OUTPUT("LLOUT"),
- SND_SOC_DAPM_OUTPUT("RLOUT"),
- SND_SOC_DAPM_OUTPUT("MONO_LOUT"),
- SND_SOC_DAPM_OUTPUT("HPLOUT"),
- SND_SOC_DAPM_OUTPUT("HPROUT"),
- SND_SOC_DAPM_OUTPUT("HPLCOM"),
- SND_SOC_DAPM_OUTPUT("HPRCOM"),
-
- SND_SOC_DAPM_INPUT("MIC3L"),
- SND_SOC_DAPM_INPUT("MIC3R"),
- SND_SOC_DAPM_INPUT("LINE1L"),
- SND_SOC_DAPM_INPUT("LINE1R"),
- SND_SOC_DAPM_INPUT("LINE2L"),
- SND_SOC_DAPM_INPUT("LINE2R"),
-
- /*
- * Virtual output pin to detection block inside codec. This can be
- * used to keep codec bias on if gpio or detection features are needed.
- * Force pin on or construct a path with an input jack and mic bias
- * widgets.
- */
- SND_SOC_DAPM_OUTPUT("Detection"),
-};
-
-static const struct snd_soc_dapm_widget aic3007_dapm_widgets[] = {
- /* Class-D outputs */
- SND_SOC_DAPM_PGA("Left Class-D Out", CLASSD_CTRL, 3, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Right Class-D Out", CLASSD_CTRL, 2, 0, NULL, 0),
-
- SND_SOC_DAPM_OUTPUT("SPOP"),
- SND_SOC_DAPM_OUTPUT("SPOM"),
-};
-
-static const struct snd_soc_dapm_route intercon[] = {
- /* Left Input */
- {"Left Line1L Mux", "single-ended", "LINE1L"},
- {"Left Line1L Mux", "differential", "LINE1L"},
-
- {"Left Line2L Mux", "single-ended", "LINE2L"},
- {"Left Line2L Mux", "differential", "LINE2L"},
-
- {"Left PGA Mixer", "Line1L Switch", "Left Line1L Mux"},
- {"Left PGA Mixer", "Line1R Switch", "Left Line1R Mux"},
- {"Left PGA Mixer", "Line2L Switch", "Left Line2L Mux"},
- {"Left PGA Mixer", "Mic3L Switch", "MIC3L"},
- {"Left PGA Mixer", "Mic3R Switch", "MIC3R"},
-
- {"Left ADC", NULL, "Left PGA Mixer"},
- {"Left ADC", NULL, "GPIO1 dmic modclk"},
-
- /* Right Input */
- {"Right Line1R Mux", "single-ended", "LINE1R"},
- {"Right Line1R Mux", "differential", "LINE1R"},
-
- {"Right Line2R Mux", "single-ended", "LINE2R"},
- {"Right Line2R Mux", "differential", "LINE2R"},
-
- {"Right PGA Mixer", "Line1L Switch", "Right Line1L Mux"},
- {"Right PGA Mixer", "Line1R Switch", "Right Line1R Mux"},
- {"Right PGA Mixer", "Line2R Switch", "Right Line2R Mux"},
- {"Right PGA Mixer", "Mic3L Switch", "MIC3L"},
- {"Right PGA Mixer", "Mic3R Switch", "MIC3R"},
-
- {"Right ADC", NULL, "Right PGA Mixer"},
- {"Right ADC", NULL, "GPIO1 dmic modclk"},
-
- /*
- * Logical path between digital mic enable and GPIO1 modulator clock
- * output function
- */
- {"GPIO1 dmic modclk", NULL, "DMic Rate 128"},
- {"GPIO1 dmic modclk", NULL, "DMic Rate 64"},
- {"GPIO1 dmic modclk", NULL, "DMic Rate 32"},
-
- /* Left DAC Output */
- {"Left DAC Mux", "DAC_L1", "Left DAC"},
- {"Left DAC Mux", "DAC_L2", "Left DAC"},
- {"Left DAC Mux", "DAC_L3", "Left DAC"},
-
- /* Right DAC Output */
- {"Right DAC Mux", "DAC_R1", "Right DAC"},
- {"Right DAC Mux", "DAC_R2", "Right DAC"},
- {"Right DAC Mux", "DAC_R3", "Right DAC"},
-
- /* Left Line Output */
- {"Left Line Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
- {"Left Line Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
- {"Left Line Mixer", "DACL1 Switch", "Left DAC Mux"},
- {"Left Line Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
- {"Left Line Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
- {"Left Line Mixer", "DACR1 Switch", "Right DAC Mux"},
-
- {"Left Line Out", NULL, "Left Line Mixer"},
- {"Left Line Out", NULL, "Left DAC Mux"},
- {"LLOUT", NULL, "Left Line Out"},
-
- /* Right Line Output */
- {"Right Line Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
- {"Right Line Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
- {"Right Line Mixer", "DACL1 Switch", "Left DAC Mux"},
- {"Right Line Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
- {"Right Line Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
- {"Right Line Mixer", "DACR1 Switch", "Right DAC Mux"},
-
- {"Right Line Out", NULL, "Right Line Mixer"},
- {"Right Line Out", NULL, "Right DAC Mux"},
- {"RLOUT", NULL, "Right Line Out"},
-
- /* Mono Output */
- {"Mono Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
- {"Mono Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
- {"Mono Mixer", "DACL1 Switch", "Left DAC Mux"},
- {"Mono Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
- {"Mono Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
- {"Mono Mixer", "DACR1 Switch", "Right DAC Mux"},
-
- {"Mono Out", NULL, "Mono Mixer"},
- {"MONO_LOUT", NULL, "Mono Out"},
-
- /* Left HP Output */
- {"Left HP Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
- {"Left HP Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
- {"Left HP Mixer", "DACL1 Switch", "Left DAC Mux"},
- {"Left HP Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
- {"Left HP Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
- {"Left HP Mixer", "DACR1 Switch", "Right DAC Mux"},
-
- {"Left HP Out", NULL, "Left HP Mixer"},
- {"Left HP Out", NULL, "Left DAC Mux"},
- {"HPLOUT", NULL, "Left HP Out"},
-
- /* Right HP Output */
- {"Right HP Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
- {"Right HP Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
- {"Right HP Mixer", "DACL1 Switch", "Left DAC Mux"},
- {"Right HP Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
- {"Right HP Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
- {"Right HP Mixer", "DACR1 Switch", "Right DAC Mux"},
-
- {"Right HP Out", NULL, "Right HP Mixer"},
- {"Right HP Out", NULL, "Right DAC Mux"},
- {"HPROUT", NULL, "Right HP Out"},
-
- /* Left HPCOM Output */
- {"Left HPCOM Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
- {"Left HPCOM Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
- {"Left HPCOM Mixer", "DACL1 Switch", "Left DAC Mux"},
- {"Left HPCOM Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
- {"Left HPCOM Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
- {"Left HPCOM Mixer", "DACR1 Switch", "Right DAC Mux"},
-
- {"Left HPCOM Mux", "differential of HPLOUT", "Left HP Mixer"},
- {"Left HPCOM Mux", "constant VCM", "Left HPCOM Mixer"},
- {"Left HPCOM Mux", "single-ended", "Left HPCOM Mixer"},
- {"Left HP Com", NULL, "Left HPCOM Mux"},
- {"HPLCOM", NULL, "Left HP Com"},
-
- /* Right HPCOM Output */
- {"Right HPCOM Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
- {"Right HPCOM Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
- {"Right HPCOM Mixer", "DACL1 Switch", "Left DAC Mux"},
- {"Right HPCOM Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
- {"Right HPCOM Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
- {"Right HPCOM Mixer", "DACR1 Switch", "Right DAC Mux"},
-
- {"Right HPCOM Mux", "differential of HPROUT", "Right HP Mixer"},
- {"Right HPCOM Mux", "constant VCM", "Right HPCOM Mixer"},
- {"Right HPCOM Mux", "single-ended", "Right HPCOM Mixer"},
- {"Right HPCOM Mux", "differential of HPLCOM", "Left HPCOM Mixer"},
- {"Right HPCOM Mux", "external feedback", "Right HPCOM Mixer"},
- {"Right HP Com", NULL, "Right HPCOM Mux"},
- {"HPRCOM", NULL, "Right HP Com"},
-};
-
-static const struct snd_soc_dapm_route intercon_3007[] = {
- /* Class-D outputs */
- {"Left Class-D Out", NULL, "Left Line Out"},
- {"Right Class-D Out", NULL, "Left Line Out"},
- {"SPOP", NULL, "Left Class-D Out"},
- {"SPOM", NULL, "Right Class-D Out"},
-};
-
-static int aic3x_add_widgets(struct snd_soc_codec *codec)
-{
- struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
- ARRAY_SIZE(aic3x_dapm_widgets));
-
- /* set up audio path interconnects */
- snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
-
- if (aic3x->model == AIC3X_MODEL_3007) {
- snd_soc_dapm_new_controls(dapm, aic3007_dapm_widgets,
- ARRAY_SIZE(aic3007_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, intercon_3007,
- ARRAY_SIZE(intercon_3007));
- }
-
- return 0;
-}
-
-static int aic3x_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec =rtd->codec;
- struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
- int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
- u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
- u16 d, pll_d = 1;
- int clk;
-
- /* select data word length */
- data = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- data |= (0x01 << 4);
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- data |= (0x02 << 4);
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- data |= (0x03 << 4);
- break;
- }
- snd_soc_write(codec, AIC3X_ASD_INTF_CTRLB, data);
-
- /* Fsref can be 44100 or 48000 */
- fsref = (params_rate(params) % 11025 == 0) ? 44100 : 48000;
-
- /* Try to find a value for Q which allows us to bypass the PLL and
- * generate CODEC_CLK directly. */
- for (pll_q = 2; pll_q < 18; pll_q++)
- if (aic3x->sysclk / (128 * pll_q) == fsref) {
- bypass_pll = 1;
- break;
- }
-
- if (bypass_pll) {
- pll_q &= 0xf;
- snd_soc_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT);
- snd_soc_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV);
- /* disable PLL if it is bypassed */
- snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, PLL_ENABLE, 0);
-
- } else {
- snd_soc_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV);
- /* enable PLL when it is used */
- snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG,
- PLL_ENABLE, PLL_ENABLE);
- }
-
- /* Route Left DAC to left channel input and
- * right DAC to right channel input */
- data = (LDAC2LCH | RDAC2RCH);
- data |= (fsref == 44100) ? FSREF_44100 : FSREF_48000;
- if (params_rate(params) >= 64000)
- data |= DUAL_RATE_MODE;
- snd_soc_write(codec, AIC3X_CODEC_DATAPATH_REG, data);
-
- /* codec sample rate select */
- data = (fsref * 20) / params_rate(params);
- if (params_rate(params) < 64000)
- data /= 2;
- data /= 5;
- data -= 2;
- data |= (data << 4);
- snd_soc_write(codec, AIC3X_SAMPLE_RATE_SEL_REG, data);
-
- if (bypass_pll)
- return 0;
-
- /* Use PLL, compute appropriate setup for j, d, r and p, the closest
- * one wins the game. Try with d==0 first, next with d!=0.
- * Constraints for j are according to the datasheet.
- * The sysclk is divided by 1000 to prevent integer overflows.
- */
-
- codec_clk = (2048 * fsref) / (aic3x->sysclk / 1000);
-
- for (r = 1; r <= 16; r++)
- for (p = 1; p <= 8; p++) {
- for (j = 4; j <= 55; j++) {
- /* This is actually 1000*((j+(d/10000))*r)/p
- * The term had to be converted to get
- * rid of the division by 10000; d = 0 here
- */
- int tmp_clk = (1000 * j * r) / p;
-
- /* Check whether this values get closer than
- * the best ones we had before
- */
- if (abs(codec_clk - tmp_clk) <
- abs(codec_clk - last_clk)) {
- pll_j = j; pll_d = 0;
- pll_r = r; pll_p = p;
- last_clk = tmp_clk;
- }
-
- /* Early exit for exact matches */
- if (tmp_clk == codec_clk)
- goto found;
- }
- }
-
- /* try with d != 0 */
- for (p = 1; p <= 8; p++) {
- j = codec_clk * p / 1000;
-
- if (j < 4 || j > 11)
- continue;
-
- /* do not use codec_clk here since we'd loose precision */
- d = ((2048 * p * fsref) - j * aic3x->sysclk)
- * 100 / (aic3x->sysclk/100);
-
- clk = (10000 * j + d) / (10 * p);
-
- /* check whether this values get closer than the best
- * ones we had before */
- if (abs(codec_clk - clk) < abs(codec_clk - last_clk)) {
- pll_j = j; pll_d = d; pll_r = 1; pll_p = p;
- last_clk = clk;
- }
-
- /* Early exit for exact matches */
- if (clk == codec_clk)
- goto found;
- }
-
- if (last_clk == 0) {
- printk(KERN_ERR "%s(): unable to setup PLL\n", __func__);
- return -EINVAL;
- }
-
-found:
- snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, PLLP_MASK, pll_p);
- snd_soc_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG,
- pll_r << PLLR_SHIFT);
- snd_soc_write(codec, AIC3X_PLL_PROGB_REG, pll_j << PLLJ_SHIFT);
- snd_soc_write(codec, AIC3X_PLL_PROGC_REG,
- (pll_d >> 6) << PLLD_MSB_SHIFT);
- snd_soc_write(codec, AIC3X_PLL_PROGD_REG,
- (pll_d & 0x3F) << PLLD_LSB_SHIFT);
-
- return 0;
-}
-
-static int aic3x_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u8 ldac_reg = snd_soc_read(codec, LDAC_VOL) & ~MUTE_ON;
- u8 rdac_reg = snd_soc_read(codec, RDAC_VOL) & ~MUTE_ON;
-
- if (mute) {
- snd_soc_write(codec, LDAC_VOL, ldac_reg | MUTE_ON);
- snd_soc_write(codec, RDAC_VOL, rdac_reg | MUTE_ON);
- } else {
- snd_soc_write(codec, LDAC_VOL, ldac_reg);
- snd_soc_write(codec, RDAC_VOL, rdac_reg);
- }
-
- return 0;
-}
-
-static int aic3x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
-
- aic3x->sysclk = freq;
- return 0;
-}
-
-static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
- u8 iface_areg, iface_breg;
- int delay = 0;
-
- iface_areg = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLA) & 0x3f;
- iface_breg = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & 0x3f;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- aic3x->master = 1;
- iface_areg |= BIT_CLK_MASTER | WORD_CLK_MASTER;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- aic3x->master = 0;
- iface_areg &= ~(BIT_CLK_MASTER | WORD_CLK_MASTER);
- break;
- default:
- return -EINVAL;
- }
-
- /*
- * match both interface format and signal polarities since they
- * are fixed
- */
- switch (fmt & (SND_SOC_DAIFMT_FORMAT_MASK |
- SND_SOC_DAIFMT_INV_MASK)) {
- case (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF):
- break;
- case (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF):
- delay = 1;
- case (SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF):
- iface_breg |= (0x01 << 6);
- break;
- case (SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_NB_NF):
- iface_breg |= (0x02 << 6);
- break;
- case (SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF):
- iface_breg |= (0x03 << 6);
- break;
- default:
- return -EINVAL;
- }
-
- /* set iface */
- snd_soc_write(codec, AIC3X_ASD_INTF_CTRLA, iface_areg);
- snd_soc_write(codec, AIC3X_ASD_INTF_CTRLB, iface_breg);
- snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, delay);
-
- return 0;
-}
-
-static int aic3x_init_3007(struct snd_soc_codec *codec)
-{
- u8 tmp1, tmp2, *cache = codec->reg_cache;
-
- /*
- * There is no need to cache writes to undocumented page 0xD but
- * respective page 0 register cache entries must be preserved
- */
- tmp1 = cache[0xD];
- tmp2 = cache[0x8];
- /* Class-D speaker driver init; datasheet p. 46 */
- snd_soc_write(codec, AIC3X_PAGE_SELECT, 0x0D);
- snd_soc_write(codec, 0xD, 0x0D);
- snd_soc_write(codec, 0x8, 0x5C);
- snd_soc_write(codec, 0x8, 0x5D);
- snd_soc_write(codec, 0x8, 0x5C);
- snd_soc_write(codec, AIC3X_PAGE_SELECT, 0x00);
- cache[0xD] = tmp1;
- cache[0x8] = tmp2;
-
- return 0;
-}
-
-static int aic3x_regulator_event(struct notifier_block *nb,
- unsigned long event, void *data)
-{
- struct aic3x_disable_nb *disable_nb =
- container_of(nb, struct aic3x_disable_nb, nb);
- struct aic3x_priv *aic3x = disable_nb->aic3x;
-
- if (event & REGULATOR_EVENT_DISABLE) {
- /*
- * Put codec to reset and require cache sync as at least one
- * of the supplies was disabled
- */
- if (gpio_is_valid(aic3x->gpio_reset))
- gpio_set_value(aic3x->gpio_reset, 0);
- aic3x->codec->cache_sync = 1;
- }
-
- return 0;
-}
-
-static int aic3x_set_power(struct snd_soc_codec *codec, int power)
-{
- struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
- int i, ret;
- u8 *cache = codec->reg_cache;
-
- if (power) {
- ret = regulator_bulk_enable(ARRAY_SIZE(aic3x->supplies),
- aic3x->supplies);
- if (ret)
- goto out;
- aic3x->power = 1;
- /*
- * Reset release and cache sync is necessary only if some
- * supply was off or if there were cached writes
- */
- if (!codec->cache_sync)
- goto out;
-
- if (gpio_is_valid(aic3x->gpio_reset)) {
- udelay(1);
- gpio_set_value(aic3x->gpio_reset, 1);
- }
-
- /* Sync reg_cache with the hardware */
- codec->cache_only = 0;
- for (i = AIC3X_SAMPLE_RATE_SEL_REG; i < ARRAY_SIZE(aic3x_reg); i++)
- snd_soc_write(codec, i, cache[i]);
- if (aic3x->model == AIC3X_MODEL_3007)
- aic3x_init_3007(codec);
- codec->cache_sync = 0;
- } else {
- /*
- * Do soft reset to this codec instance in order to clear
- * possible VDD leakage currents in case the supply regulators
- * remain on
- */
- snd_soc_write(codec, AIC3X_RESET, SOFT_RESET);
- codec->cache_sync = 1;
- aic3x->power = 0;
- /* HW writes are needless when bias is off */
- codec->cache_only = 1;
- ret = regulator_bulk_disable(ARRAY_SIZE(aic3x->supplies),
- aic3x->supplies);
- }
-out:
- return ret;
-}
-
-static int aic3x_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
- case SND_SOC_BIAS_PREPARE:
- if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY &&
- aic3x->master) {
- /* enable pll */
- snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG,
- PLL_ENABLE, PLL_ENABLE);
- }
- break;
- case SND_SOC_BIAS_STANDBY:
- if (!aic3x->power)
- aic3x_set_power(codec, 1);
- if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE &&
- aic3x->master) {
- /* disable pll */
- snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG,
- PLL_ENABLE, 0);
- }
- break;
- case SND_SOC_BIAS_OFF:
- if (aic3x->power)
- aic3x_set_power(codec, 0);
- break;
- }
- codec->dapm.bias_level = level;
-
- return 0;
-}
-
-void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
- int headset_debounce, int button_debounce)
-{
- u8 val;
-
- val = ((detect & AIC3X_HEADSET_DETECT_MASK)
- << AIC3X_HEADSET_DETECT_SHIFT) |
- ((headset_debounce & AIC3X_HEADSET_DEBOUNCE_MASK)
- << AIC3X_HEADSET_DEBOUNCE_SHIFT) |
- ((button_debounce & AIC3X_BUTTON_DEBOUNCE_MASK)
- << AIC3X_BUTTON_DEBOUNCE_SHIFT);
-
- if (detect & AIC3X_HEADSET_DETECT_MASK)
- val |= AIC3X_HEADSET_DETECT_ENABLED;
-
- snd_soc_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val);
-}
-
-#define AIC3X_RATES SNDRV_PCM_RATE_8000_96000
-#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
- SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops aic3x_dai_ops = {
- .hw_params = aic3x_hw_params,
- .digital_mute = aic3x_mute,
- .set_sysclk = aic3x_set_dai_sysclk,
- .set_fmt = aic3x_set_dai_fmt,
-};
-
-static struct snd_soc_dai_driver aic3x_dai = {
- .name = "tlv320aic3x-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = AIC3X_RATES,
- .formats = AIC3X_FORMATS,},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = AIC3X_RATES,
- .formats = AIC3X_FORMATS,},
- .ops = &aic3x_dai_ops,
- .symmetric_rates = 1,
-};
-
-static int aic3x_suspend(struct snd_soc_codec *codec)
-{
- aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int aic3x_resume(struct snd_soc_codec *codec)
-{
- aic3x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-
-/*
- * initialise the AIC3X driver
- * register the mixer and dsp interfaces with the kernel
- */
-static int aic3x_init(struct snd_soc_codec *codec)
-{
- struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
-
- snd_soc_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT);
- snd_soc_write(codec, AIC3X_RESET, SOFT_RESET);
-
- /* DAC default volume and mute */
- snd_soc_write(codec, LDAC_VOL, DEFAULT_VOL | MUTE_ON);
- snd_soc_write(codec, RDAC_VOL, DEFAULT_VOL | MUTE_ON);
-
- /* DAC to HP default volume and route to Output mixer */
- snd_soc_write(codec, DACL1_2_HPLOUT_VOL, DEFAULT_VOL | ROUTE_ON);
- snd_soc_write(codec, DACR1_2_HPROUT_VOL, DEFAULT_VOL | ROUTE_ON);
- snd_soc_write(codec, DACL1_2_HPLCOM_VOL, DEFAULT_VOL | ROUTE_ON);
- snd_soc_write(codec, DACR1_2_HPRCOM_VOL, DEFAULT_VOL | ROUTE_ON);
- /* DAC to Line Out default volume and route to Output mixer */
- snd_soc_write(codec, DACL1_2_LLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
- snd_soc_write(codec, DACR1_2_RLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
- /* DAC to Mono Line Out default volume and route to Output mixer */
- snd_soc_write(codec, DACL1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
- snd_soc_write(codec, DACR1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
-
- /* unmute all outputs */
- snd_soc_update_bits(codec, LLOPM_CTRL, UNMUTE, UNMUTE);
- snd_soc_update_bits(codec, RLOPM_CTRL, UNMUTE, UNMUTE);
- snd_soc_update_bits(codec, MONOLOPM_CTRL, UNMUTE, UNMUTE);
- snd_soc_update_bits(codec, HPLOUT_CTRL, UNMUTE, UNMUTE);
- snd_soc_update_bits(codec, HPROUT_CTRL, UNMUTE, UNMUTE);
- snd_soc_update_bits(codec, HPLCOM_CTRL, UNMUTE, UNMUTE);
- snd_soc_update_bits(codec, HPRCOM_CTRL, UNMUTE, UNMUTE);
-
- /* ADC default volume and unmute */
- snd_soc_write(codec, LADC_VOL, DEFAULT_GAIN);
- snd_soc_write(codec, RADC_VOL, DEFAULT_GAIN);
- /* By default route Line1 to ADC PGA mixer */
- snd_soc_write(codec, LINE1L_2_LADC_CTRL, 0x0);
- snd_soc_write(codec, LINE1R_2_RADC_CTRL, 0x0);
-
- /* PGA to HP Bypass default volume, disconnect from Output Mixer */
- snd_soc_write(codec, PGAL_2_HPLOUT_VOL, DEFAULT_VOL);
- snd_soc_write(codec, PGAR_2_HPROUT_VOL, DEFAULT_VOL);
- snd_soc_write(codec, PGAL_2_HPLCOM_VOL, DEFAULT_VOL);
- snd_soc_write(codec, PGAR_2_HPRCOM_VOL, DEFAULT_VOL);
- /* PGA to Line Out default volume, disconnect from Output Mixer */
- snd_soc_write(codec, PGAL_2_LLOPM_VOL, DEFAULT_VOL);
- snd_soc_write(codec, PGAR_2_RLOPM_VOL, DEFAULT_VOL);
- /* PGA to Mono Line Out default volume, disconnect from Output Mixer */
- snd_soc_write(codec, PGAL_2_MONOLOPM_VOL, DEFAULT_VOL);
- snd_soc_write(codec, PGAR_2_MONOLOPM_VOL, DEFAULT_VOL);
-
- /* Line2 to HP Bypass default volume, disconnect from Output Mixer */
- snd_soc_write(codec, LINE2L_2_HPLOUT_VOL, DEFAULT_VOL);
- snd_soc_write(codec, LINE2R_2_HPROUT_VOL, DEFAULT_VOL);
- snd_soc_write(codec, LINE2L_2_HPLCOM_VOL, DEFAULT_VOL);
- snd_soc_write(codec, LINE2R_2_HPRCOM_VOL, DEFAULT_VOL);
- /* Line2 Line Out default volume, disconnect from Output Mixer */
- snd_soc_write(codec, LINE2L_2_LLOPM_VOL, DEFAULT_VOL);
- snd_soc_write(codec, LINE2R_2_RLOPM_VOL, DEFAULT_VOL);
- /* Line2 to Mono Out default volume, disconnect from Output Mixer */
- snd_soc_write(codec, LINE2L_2_MONOLOPM_VOL, DEFAULT_VOL);
- snd_soc_write(codec, LINE2R_2_MONOLOPM_VOL, DEFAULT_VOL);
-
- if (aic3x->model == AIC3X_MODEL_3007) {
- aic3x_init_3007(codec);
- snd_soc_write(codec, CLASSD_CTRL, 0);
- }
-
- return 0;
-}
-
-static bool aic3x_is_shared_reset(struct aic3x_priv *aic3x)
-{
- struct aic3x_priv *a;
-
- list_for_each_entry(a, &reset_list, list) {
- if (gpio_is_valid(aic3x->gpio_reset) &&
- aic3x->gpio_reset == a->gpio_reset)
- return true;
- }
-
- return false;
-}
-
-static int aic3x_probe(struct snd_soc_codec *codec)
-{
- struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
- int ret, i;
-
- INIT_LIST_HEAD(&aic3x->list);
- aic3x->codec = codec;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- if (gpio_is_valid(aic3x->gpio_reset) &&
- !aic3x_is_shared_reset(aic3x)) {
- ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset");
- if (ret != 0)
- goto err_gpio;
- gpio_direction_output(aic3x->gpio_reset, 0);
- }
-
- for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
- aic3x->supplies[i].supply = aic3x_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(aic3x->supplies),
- aic3x->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- goto err_get;
- }
- for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) {
- aic3x->disable_nb[i].nb.notifier_call = aic3x_regulator_event;
- aic3x->disable_nb[i].aic3x = aic3x;
- ret = regulator_register_notifier(aic3x->supplies[i].consumer,
- &aic3x->disable_nb[i].nb);
- if (ret) {
- dev_err(codec->dev,
- "Failed to request regulator notifier: %d\n",
- ret);
- goto err_notif;
- }
- }
-
- codec->cache_only = 1;
- aic3x_init(codec);
-
- if (aic3x->setup) {
- /* setup GPIO functions */
- snd_soc_write(codec, AIC3X_GPIO1_REG,
- (aic3x->setup->gpio_func[0] & 0xf) << 4);
- snd_soc_write(codec, AIC3X_GPIO2_REG,
- (aic3x->setup->gpio_func[1] & 0xf) << 4);
- }
-
- snd_soc_add_codec_controls(codec, aic3x_snd_controls,
- ARRAY_SIZE(aic3x_snd_controls));
- if (aic3x->model == AIC3X_MODEL_3007)
- snd_soc_add_codec_controls(codec, &aic3x_classd_amp_gain_ctrl, 1);
-
- aic3x_add_widgets(codec);
- list_add(&aic3x->list, &reset_list);
-
- return 0;
-
-err_notif:
- while (i--)
- regulator_unregister_notifier(aic3x->supplies[i].consumer,
- &aic3x->disable_nb[i].nb);
- regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
-err_get:
- if (gpio_is_valid(aic3x->gpio_reset) &&
- !aic3x_is_shared_reset(aic3x))
- gpio_free(aic3x->gpio_reset);
-err_gpio:
- return ret;
-}
-
-static int aic3x_remove(struct snd_soc_codec *codec)
-{
- struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
- int i;
-
- aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
- list_del(&aic3x->list);
- if (gpio_is_valid(aic3x->gpio_reset) &&
- !aic3x_is_shared_reset(aic3x)) {
- gpio_set_value(aic3x->gpio_reset, 0);
- gpio_free(aic3x->gpio_reset);
- }
- for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
- regulator_unregister_notifier(aic3x->supplies[i].consumer,
- &aic3x->disable_nb[i].nb);
- regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
- .set_bias_level = aic3x_set_bias_level,
- .idle_bias_off = true,
- .reg_cache_size = ARRAY_SIZE(aic3x_reg),
- .reg_word_size = sizeof(u8),
- .reg_cache_default = aic3x_reg,
- .probe = aic3x_probe,
- .remove = aic3x_remove,
- .suspend = aic3x_suspend,
- .resume = aic3x_resume,
-};
-
-/*
- * AIC3X 2 wire address can be up to 4 devices with device addresses
- * 0x18, 0x19, 0x1A, 0x1B
- */
-
-static const struct i2c_device_id aic3x_i2c_id[] = {
- { "tlv320aic3x", AIC3X_MODEL_3X },
- { "tlv320aic33", AIC3X_MODEL_33 },
- { "tlv320aic3007", AIC3X_MODEL_3007 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
-
-/*
- * If the i2c layer weren't so broken, we could pass this kind of data
- * around
- */
-static int aic3x_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct aic3x_pdata *pdata = i2c->dev.platform_data;
- struct aic3x_priv *aic3x;
- int ret;
-
- aic3x = devm_kzalloc(&i2c->dev, sizeof(struct aic3x_priv), GFP_KERNEL);
- if (aic3x == NULL) {
- dev_err(&i2c->dev, "failed to create private data\n");
- return -ENOMEM;
- }
-
- aic3x->control_type = SND_SOC_I2C;
-
- i2c_set_clientdata(i2c, aic3x);
- if (pdata) {
- aic3x->gpio_reset = pdata->gpio_reset;
- aic3x->setup = pdata->setup;
- } else {
- aic3x->gpio_reset = -1;
- }
-
- aic3x->model = id->driver_data;
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_aic3x, &aic3x_dai, 1);
- return ret;
-}
-
-static int aic3x_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-/* machine i2c codec control layer */
-static struct i2c_driver aic3x_i2c_driver = {
- .driver = {
- .name = "tlv320aic3x-codec",
- .owner = THIS_MODULE,
- },
- .probe = aic3x_i2c_probe,
- .remove = aic3x_i2c_remove,
- .id_table = aic3x_i2c_id,
-};
-
-static int __init aic3x_modinit(void)
-{
- int ret = 0;
- ret = i2c_add_driver(&aic3x_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register TLV320AIC3x I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(aic3x_modinit);
-
-static void __exit aic3x_exit(void)
-{
- i2c_del_driver(&aic3x_i2c_driver);
-}
-module_exit(aic3x_exit);
-
-MODULE_DESCRIPTION("ASoC TLV320AIC3X codec driver");
-MODULE_AUTHOR("Vladimir Barinov");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/tlv320aic3x.h b/ANDROID_3.4.5/sound/soc/codecs/tlv320aic3x.h
deleted file mode 100644
index 08c7f668..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/tlv320aic3x.h
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * ALSA SoC TLV320AIC3X codec driver
- *
- * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
- * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _AIC3X_H
-#define _AIC3X_H
-
-/* AIC3X register space */
-#define AIC3X_CACHEREGNUM 103
-
-/* Page select register */
-#define AIC3X_PAGE_SELECT 0
-/* Software reset register */
-#define AIC3X_RESET 1
-/* Codec Sample rate select register */
-#define AIC3X_SAMPLE_RATE_SEL_REG 2
-/* PLL progrramming register A */
-#define AIC3X_PLL_PROGA_REG 3
-/* PLL progrramming register B */
-#define AIC3X_PLL_PROGB_REG 4
-/* PLL progrramming register C */
-#define AIC3X_PLL_PROGC_REG 5
-/* PLL progrramming register D */
-#define AIC3X_PLL_PROGD_REG 6
-/* Codec datapath setup register */
-#define AIC3X_CODEC_DATAPATH_REG 7
-/* Audio serial data interface control register A */
-#define AIC3X_ASD_INTF_CTRLA 8
-/* Audio serial data interface control register B */
-#define AIC3X_ASD_INTF_CTRLB 9
-/* Audio serial data interface control register C */
-#define AIC3X_ASD_INTF_CTRLC 10
-/* Audio overflow status and PLL R value programming register */
-#define AIC3X_OVRF_STATUS_AND_PLLR_REG 11
-/* Audio codec digital filter control register */
-#define AIC3X_CODEC_DFILT_CTRL 12
-/* Headset/button press detection register */
-#define AIC3X_HEADSET_DETECT_CTRL_A 13
-#define AIC3X_HEADSET_DETECT_CTRL_B 14
-/* ADC PGA Gain control registers */
-#define LADC_VOL 15
-#define RADC_VOL 16
-/* MIC3 control registers */
-#define MIC3LR_2_LADC_CTRL 17
-#define MIC3LR_2_RADC_CTRL 18
-/* Line1 Input control registers */
-#define LINE1L_2_LADC_CTRL 19
-#define LINE1R_2_LADC_CTRL 21
-#define LINE1R_2_RADC_CTRL 22
-#define LINE1L_2_RADC_CTRL 24
-/* Line2 Input control registers */
-#define LINE2L_2_LADC_CTRL 20
-#define LINE2R_2_RADC_CTRL 23
-/* MICBIAS Control Register */
-#define MICBIAS_CTRL 25
-
-/* AGC Control Registers A, B, C */
-#define LAGC_CTRL_A 26
-#define LAGC_CTRL_B 27
-#define LAGC_CTRL_C 28
-#define RAGC_CTRL_A 29
-#define RAGC_CTRL_B 30
-#define RAGC_CTRL_C 31
-
-/* DAC Power and Left High Power Output control registers */
-#define DAC_PWR 37
-#define HPLCOM_CFG 37
-/* Right High Power Output control registers */
-#define HPRCOM_CFG 38
-/* DAC Output Switching control registers */
-#define DAC_LINE_MUX 41
-/* High Power Output Driver Pop Reduction registers */
-#define HPOUT_POP_REDUCTION 42
-/* DAC Digital control registers */
-#define LDAC_VOL 43
-#define RDAC_VOL 44
-/* Left High Power Output control registers */
-#define LINE2L_2_HPLOUT_VOL 45
-#define PGAL_2_HPLOUT_VOL 46
-#define DACL1_2_HPLOUT_VOL 47
-#define LINE2R_2_HPLOUT_VOL 48
-#define PGAR_2_HPLOUT_VOL 49
-#define DACR1_2_HPLOUT_VOL 50
-#define HPLOUT_CTRL 51
-/* Left High Power COM control registers */
-#define LINE2L_2_HPLCOM_VOL 52
-#define PGAL_2_HPLCOM_VOL 53
-#define DACL1_2_HPLCOM_VOL 54
-#define LINE2R_2_HPLCOM_VOL 55
-#define PGAR_2_HPLCOM_VOL 56
-#define DACR1_2_HPLCOM_VOL 57
-#define HPLCOM_CTRL 58
-/* Right High Power Output control registers */
-#define LINE2L_2_HPROUT_VOL 59
-#define PGAL_2_HPROUT_VOL 60
-#define DACL1_2_HPROUT_VOL 61
-#define LINE2R_2_HPROUT_VOL 62
-#define PGAR_2_HPROUT_VOL 63
-#define DACR1_2_HPROUT_VOL 64
-#define HPROUT_CTRL 65
-/* Right High Power COM control registers */
-#define LINE2L_2_HPRCOM_VOL 66
-#define PGAL_2_HPRCOM_VOL 67
-#define DACL1_2_HPRCOM_VOL 68
-#define LINE2R_2_HPRCOM_VOL 69
-#define PGAR_2_HPRCOM_VOL 70
-#define DACR1_2_HPRCOM_VOL 71
-#define HPRCOM_CTRL 72
-/* Mono Line Output Plus/Minus control registers */
-#define LINE2L_2_MONOLOPM_VOL 73
-#define PGAL_2_MONOLOPM_VOL 74
-#define DACL1_2_MONOLOPM_VOL 75
-#define LINE2R_2_MONOLOPM_VOL 76
-#define PGAR_2_MONOLOPM_VOL 77
-#define DACR1_2_MONOLOPM_VOL 78
-#define MONOLOPM_CTRL 79
-/* Class-D speaker driver on tlv320aic3007 */
-#define CLASSD_CTRL 73
-/* Left Line Output Plus/Minus control registers */
-#define LINE2L_2_LLOPM_VOL 80
-#define PGAL_2_LLOPM_VOL 81
-#define DACL1_2_LLOPM_VOL 82
-#define LINE2R_2_LLOPM_VOL 83
-#define PGAR_2_LLOPM_VOL 84
-#define DACR1_2_LLOPM_VOL 85
-#define LLOPM_CTRL 86
-/* Right Line Output Plus/Minus control registers */
-#define LINE2L_2_RLOPM_VOL 87
-#define PGAL_2_RLOPM_VOL 88
-#define DACL1_2_RLOPM_VOL 89
-#define LINE2R_2_RLOPM_VOL 90
-#define PGAR_2_RLOPM_VOL 91
-#define DACR1_2_RLOPM_VOL 92
-#define RLOPM_CTRL 93
-/* GPIO/IRQ registers */
-#define AIC3X_STICKY_IRQ_FLAGS_REG 96
-#define AIC3X_RT_IRQ_FLAGS_REG 97
-#define AIC3X_GPIO1_REG 98
-#define AIC3X_GPIO2_REG 99
-#define AIC3X_GPIOA_REG 100
-#define AIC3X_GPIOB_REG 101
-/* Clock generation control register */
-#define AIC3X_CLKGEN_CTRL_REG 102
-
-/* Page select register bits */
-#define PAGE0_SELECT 0
-#define PAGE1_SELECT 1
-
-/* Audio serial data interface control register A bits */
-#define BIT_CLK_MASTER 0x80
-#define WORD_CLK_MASTER 0x40
-
-/* Codec Datapath setup register 7 */
-#define FSREF_44100 (1 << 7)
-#define FSREF_48000 (0 << 7)
-#define DUAL_RATE_MODE ((1 << 5) | (1 << 6))
-#define LDAC2LCH (0x1 << 3)
-#define RDAC2RCH (0x1 << 1)
-
-/* PLL registers bitfields */
-#define PLLP_SHIFT 0
-#define PLLP_MASK 7
-#define PLLQ_SHIFT 3
-#define PLLR_SHIFT 0
-#define PLLJ_SHIFT 2
-#define PLLD_MSB_SHIFT 0
-#define PLLD_LSB_SHIFT 2
-
-/* Clock generation register bits */
-#define CODEC_CLKIN_PLLDIV 0
-#define CODEC_CLKIN_CLKDIV 1
-#define PLL_CLKIN_SHIFT 4
-#define MCLK_SOURCE 0x0
-#define PLL_CLKDIV_SHIFT 0
-
-/* Software reset register bits */
-#define SOFT_RESET 0x80
-
-/* PLL progrramming register A bits */
-#define PLL_ENABLE 0x80
-
-/* Route bits */
-#define ROUTE_ON 0x80
-
-/* Mute bits */
-#define UNMUTE 0x08
-#define MUTE_ON 0x80
-
-/* Power bits */
-#define LADC_PWR_ON 0x04
-#define RADC_PWR_ON 0x04
-#define LDAC_PWR_ON 0x80
-#define RDAC_PWR_ON 0x40
-#define HPLOUT_PWR_ON 0x01
-#define HPROUT_PWR_ON 0x01
-#define HPLCOM_PWR_ON 0x01
-#define HPRCOM_PWR_ON 0x01
-#define MONOLOPM_PWR_ON 0x01
-#define LLOPM_PWR_ON 0x01
-#define RLOPM_PWR_ON 0x01
-
-#define INVERT_VOL(val) (0x7f - val)
-
-/* Default output volume (inverted) */
-#define DEFAULT_VOL INVERT_VOL(0x50)
-/* Default input volume */
-#define DEFAULT_GAIN 0x20
-
-/* headset detection / button API */
-
-/* The AIC3x supports detection of stereo headsets (GND + left + right signal)
- * and cellular headsets (GND + speaker output + microphone input).
- * It is recommended to enable MIC bias for this function to work properly.
- * For more information, please refer to the datasheet. */
-enum {
- AIC3X_HEADSET_DETECT_OFF = 0,
- AIC3X_HEADSET_DETECT_STEREO = 1,
- AIC3X_HEADSET_DETECT_CELLULAR = 2,
- AIC3X_HEADSET_DETECT_BOTH = 3
-};
-
-enum {
- AIC3X_HEADSET_DEBOUNCE_16MS = 0,
- AIC3X_HEADSET_DEBOUNCE_32MS = 1,
- AIC3X_HEADSET_DEBOUNCE_64MS = 2,
- AIC3X_HEADSET_DEBOUNCE_128MS = 3,
- AIC3X_HEADSET_DEBOUNCE_256MS = 4,
- AIC3X_HEADSET_DEBOUNCE_512MS = 5
-};
-
-enum {
- AIC3X_BUTTON_DEBOUNCE_0MS = 0,
- AIC3X_BUTTON_DEBOUNCE_8MS = 1,
- AIC3X_BUTTON_DEBOUNCE_16MS = 2,
- AIC3X_BUTTON_DEBOUNCE_32MS = 3
-};
-
-#define AIC3X_HEADSET_DETECT_ENABLED 0x80
-#define AIC3X_HEADSET_DETECT_SHIFT 5
-#define AIC3X_HEADSET_DETECT_MASK 3
-#define AIC3X_HEADSET_DEBOUNCE_SHIFT 2
-#define AIC3X_HEADSET_DEBOUNCE_MASK 7
-#define AIC3X_BUTTON_DEBOUNCE_SHIFT 0
-#define AIC3X_BUTTON_DEBOUNCE_MASK 3
-
-#endif /* _AIC3X_H */
diff --git a/ANDROID_3.4.5/sound/soc/codecs/tlv320dac33.c b/ANDROID_3.4.5/sound/soc/codecs/tlv320dac33.c
deleted file mode 100644
index 4587ddd0..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/tlv320dac33.c
+++ /dev/null
@@ -1,1650 +0,0 @@
-/*
- * ALSA SoC Texas Instruments TLV320DAC33 codec driver
- *
- * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
- *
- * Copyright: (C) 2009 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include <sound/tlv320dac33-plat.h>
-#include "tlv320dac33.h"
-
-/*
- * The internal FIFO is 24576 bytes long
- * It can be configured to hold 16bit or 24bit samples
- * In 16bit configuration the FIFO can hold 6144 stereo samples
- * In 24bit configuration the FIFO can hold 4096 stereo samples
- */
-#define DAC33_FIFO_SIZE_16BIT 6144
-#define DAC33_FIFO_SIZE_24BIT 4096
-#define DAC33_MODE7_MARGIN 10 /* Safety margin for FIFO in Mode7 */
-
-#define BURST_BASEFREQ_HZ 49152000
-
-#define SAMPLES_TO_US(rate, samples) \
- (1000000000 / (((rate) * 1000) / (samples)))
-
-#define US_TO_SAMPLES(rate, us) \
- ((rate) / (1000000 / ((us) < 1000000 ? (us) : 1000000)))
-
-#define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \
- (((samples)*5000) / (((burstrate)*5000) / ((burstrate) - (playrate))))
-
-static void dac33_calculate_times(struct snd_pcm_substream *substream);
-static int dac33_prepare_chip(struct snd_pcm_substream *substream);
-
-enum dac33_state {
- DAC33_IDLE = 0,
- DAC33_PREFILL,
- DAC33_PLAYBACK,
- DAC33_FLUSH,
-};
-
-enum dac33_fifo_modes {
- DAC33_FIFO_BYPASS = 0,
- DAC33_FIFO_MODE1,
- DAC33_FIFO_MODE7,
- DAC33_FIFO_LAST_MODE,
-};
-
-#define DAC33_NUM_SUPPLIES 3
-static const char *dac33_supply_names[DAC33_NUM_SUPPLIES] = {
- "AVDD",
- "DVDD",
- "IOVDD",
-};
-
-struct tlv320dac33_priv {
- struct mutex mutex;
- struct workqueue_struct *dac33_wq;
- struct work_struct work;
- struct snd_soc_codec *codec;
- struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES];
- struct snd_pcm_substream *substream;
- int power_gpio;
- int chip_power;
- int irq;
- unsigned int refclk;
-
- unsigned int alarm_threshold; /* set to be half of LATENCY_TIME_MS */
- enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */
- unsigned int fifo_size; /* Size of the FIFO in samples */
- unsigned int nsample; /* burst read amount from host */
- int mode1_latency; /* latency caused by the i2c writes in
- * us */
- u8 burst_bclkdiv; /* BCLK divider value in burst mode */
- unsigned int burst_rate; /* Interface speed in Burst modes */
-
- int keep_bclk; /* Keep the BCLK continuously running
- * in FIFO modes */
- spinlock_t lock;
- unsigned long long t_stamp1; /* Time stamp for FIFO modes to */
- unsigned long long t_stamp2; /* calculate the FIFO caused delay */
-
- unsigned int mode1_us_burst; /* Time to burst read n number of
- * samples */
- unsigned int mode7_us_to_lthr; /* Time to reach lthr from uthr */
-
- unsigned int uthr;
-
- enum dac33_state state;
- enum snd_soc_control_type control_type;
- void *control_data;
-};
-
-static const u8 dac33_reg[DAC33_CACHEREGNUM] = {
-0x00, 0x00, 0x00, 0x00, /* 0x00 - 0x03 */
-0x00, 0x00, 0x00, 0x00, /* 0x04 - 0x07 */
-0x00, 0x00, 0x00, 0x00, /* 0x08 - 0x0b */
-0x00, 0x00, 0x00, 0x00, /* 0x0c - 0x0f */
-0x00, 0x00, 0x00, 0x00, /* 0x10 - 0x13 */
-0x00, 0x00, 0x00, 0x00, /* 0x14 - 0x17 */
-0x00, 0x00, 0x00, 0x00, /* 0x18 - 0x1b */
-0x00, 0x00, 0x00, 0x00, /* 0x1c - 0x1f */
-0x00, 0x00, 0x00, 0x00, /* 0x20 - 0x23 */
-0x00, 0x00, 0x00, 0x00, /* 0x24 - 0x27 */
-0x00, 0x00, 0x00, 0x00, /* 0x28 - 0x2b */
-0x00, 0x00, 0x00, 0x80, /* 0x2c - 0x2f */
-0x80, 0x00, 0x00, 0x00, /* 0x30 - 0x33 */
-0x00, 0x00, 0x00, 0x00, /* 0x34 - 0x37 */
-0x00, 0x00, /* 0x38 - 0x39 */
-/* Registers 0x3a - 0x3f are reserved */
- 0x00, 0x00, /* 0x3a - 0x3b */
-0x00, 0x00, 0x00, 0x00, /* 0x3c - 0x3f */
-
-0x00, 0x00, 0x00, 0x00, /* 0x40 - 0x43 */
-0x00, 0x80, /* 0x44 - 0x45 */
-/* Registers 0x46 - 0x47 are reserved */
- 0x80, 0x80, /* 0x46 - 0x47 */
-
-0x80, 0x00, 0x00, /* 0x48 - 0x4a */
-/* Registers 0x4b - 0x7c are reserved */
- 0x00, /* 0x4b */
-0x00, 0x00, 0x00, 0x00, /* 0x4c - 0x4f */
-0x00, 0x00, 0x00, 0x00, /* 0x50 - 0x53 */
-0x00, 0x00, 0x00, 0x00, /* 0x54 - 0x57 */
-0x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5b */
-0x00, 0x00, 0x00, 0x00, /* 0x5c - 0x5f */
-0x00, 0x00, 0x00, 0x00, /* 0x60 - 0x63 */
-0x00, 0x00, 0x00, 0x00, /* 0x64 - 0x67 */
-0x00, 0x00, 0x00, 0x00, /* 0x68 - 0x6b */
-0x00, 0x00, 0x00, 0x00, /* 0x6c - 0x6f */
-0x00, 0x00, 0x00, 0x00, /* 0x70 - 0x73 */
-0x00, 0x00, 0x00, 0x00, /* 0x74 - 0x77 */
-0x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7b */
-0x00, /* 0x7c */
-
- 0xda, 0x33, 0x03, /* 0x7d - 0x7f */
-};
-
-/* Register read and write */
-static inline unsigned int dac33_read_reg_cache(struct snd_soc_codec *codec,
- unsigned reg)
-{
- u8 *cache = codec->reg_cache;
- if (reg >= DAC33_CACHEREGNUM)
- return 0;
-
- return cache[reg];
-}
-
-static inline void dac33_write_reg_cache(struct snd_soc_codec *codec,
- u8 reg, u8 value)
-{
- u8 *cache = codec->reg_cache;
- if (reg >= DAC33_CACHEREGNUM)
- return;
-
- cache[reg] = value;
-}
-
-static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
- u8 *value)
-{
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
- int val, ret = 0;
-
- *value = reg & 0xff;
-
- /* If powered off, return the cached value */
- if (dac33->chip_power) {
- val = i2c_smbus_read_byte_data(codec->control_data, value[0]);
- if (val < 0) {
- dev_err(codec->dev, "Read failed (%d)\n", val);
- value[0] = dac33_read_reg_cache(codec, reg);
- ret = val;
- } else {
- value[0] = val;
- dac33_write_reg_cache(codec, reg, val);
- }
- } else {
- value[0] = dac33_read_reg_cache(codec, reg);
- }
-
- return ret;
-}
-
-static int dac33_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
- u8 data[2];
- int ret = 0;
-
- /*
- * data is
- * D15..D8 dac33 register offset
- * D7...D0 register data
- */
- data[0] = reg & 0xff;
- data[1] = value & 0xff;
-
- dac33_write_reg_cache(codec, data[0], data[1]);
- if (dac33->chip_power) {
- ret = codec->hw_write(codec->control_data, data, 2);
- if (ret != 2)
- dev_err(codec->dev, "Write failed (%d)\n", ret);
- else
- ret = 0;
- }
-
- return ret;
-}
-
-static int dac33_write_locked(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- mutex_lock(&dac33->mutex);
- ret = dac33_write(codec, reg, value);
- mutex_unlock(&dac33->mutex);
-
- return ret;
-}
-
-#define DAC33_I2C_ADDR_AUTOINC 0x80
-static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
- u8 data[3];
- int ret = 0;
-
- /*
- * data is
- * D23..D16 dac33 register offset
- * D15..D8 register data MSB
- * D7...D0 register data LSB
- */
- data[0] = reg & 0xff;
- data[1] = (value >> 8) & 0xff;
- data[2] = value & 0xff;
-
- dac33_write_reg_cache(codec, data[0], data[1]);
- dac33_write_reg_cache(codec, data[0] + 1, data[2]);
-
- if (dac33->chip_power) {
- /* We need to set autoincrement mode for 16 bit writes */
- data[0] |= DAC33_I2C_ADDR_AUTOINC;
- ret = codec->hw_write(codec->control_data, data, 3);
- if (ret != 3)
- dev_err(codec->dev, "Write failed (%d)\n", ret);
- else
- ret = 0;
- }
-
- return ret;
-}
-
-static void dac33_init_chip(struct snd_soc_codec *codec)
-{
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
-
- if (unlikely(!dac33->chip_power))
- return;
-
- /* A : DAC sample rate Fsref/1.5 */
- dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0));
- /* B : DAC src=normal, not muted */
- dac33_write(codec, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT |
- DAC33_DACSRCL_LEFT);
- /* C : (defaults) */
- dac33_write(codec, DAC33_DAC_CTRL_C, 0x00);
-
- /* 73 : volume soft stepping control,
- clock source = internal osc (?) */
- dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
-
- /* Restore only selected registers (gains mostly) */
- dac33_write(codec, DAC33_LDAC_DIG_VOL_CTRL,
- dac33_read_reg_cache(codec, DAC33_LDAC_DIG_VOL_CTRL));
- dac33_write(codec, DAC33_RDAC_DIG_VOL_CTRL,
- dac33_read_reg_cache(codec, DAC33_RDAC_DIG_VOL_CTRL));
-
- dac33_write(codec, DAC33_LINEL_TO_LLO_VOL,
- dac33_read_reg_cache(codec, DAC33_LINEL_TO_LLO_VOL));
- dac33_write(codec, DAC33_LINER_TO_RLO_VOL,
- dac33_read_reg_cache(codec, DAC33_LINER_TO_RLO_VOL));
-
- dac33_write(codec, DAC33_OUT_AMP_CTRL,
- dac33_read_reg_cache(codec, DAC33_OUT_AMP_CTRL));
-
- dac33_write(codec, DAC33_LDAC_PWR_CTRL,
- dac33_read_reg_cache(codec, DAC33_LDAC_PWR_CTRL));
- dac33_write(codec, DAC33_RDAC_PWR_CTRL,
- dac33_read_reg_cache(codec, DAC33_RDAC_PWR_CTRL));
-}
-
-static inline int dac33_read_id(struct snd_soc_codec *codec)
-{
- int i, ret = 0;
- u8 reg;
-
- for (i = 0; i < 3; i++) {
- ret = dac33_read(codec, DAC33_DEVICE_ID_MSB + i, &reg);
- if (ret < 0)
- break;
- }
-
- return ret;
-}
-
-static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
-{
- u8 reg;
-
- reg = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
- if (power)
- reg |= DAC33_PDNALLB;
- else
- reg &= ~(DAC33_PDNALLB | DAC33_OSCPDNB |
- DAC33_DACRPDNB | DAC33_DACLPDNB);
- dac33_write(codec, DAC33_PWR_CTRL, reg);
-}
-
-static inline void dac33_disable_digital(struct snd_soc_codec *codec)
-{
- u8 reg;
-
- /* Stop the DAI clock */
- reg = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
- reg &= ~DAC33_BCLKON;
- dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, reg);
-
- /* Power down the Oscillator, and DACs */
- reg = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
- reg &= ~(DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB);
- dac33_write(codec, DAC33_PWR_CTRL, reg);
-}
-
-static int dac33_hard_power(struct snd_soc_codec *codec, int power)
-{
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
- int ret = 0;
-
- mutex_lock(&dac33->mutex);
-
- /* Safety check */
- if (unlikely(power == dac33->chip_power)) {
- dev_dbg(codec->dev, "Trying to set the same power state: %s\n",
- power ? "ON" : "OFF");
- goto exit;
- }
-
- if (power) {
- ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies),
- dac33->supplies);
- if (ret != 0) {
- dev_err(codec->dev,
- "Failed to enable supplies: %d\n", ret);
- goto exit;
- }
-
- if (dac33->power_gpio >= 0)
- gpio_set_value(dac33->power_gpio, 1);
-
- dac33->chip_power = 1;
- } else {
- dac33_soft_power(codec, 0);
- if (dac33->power_gpio >= 0)
- gpio_set_value(dac33->power_gpio, 0);
-
- ret = regulator_bulk_disable(ARRAY_SIZE(dac33->supplies),
- dac33->supplies);
- if (ret != 0) {
- dev_err(codec->dev,
- "Failed to disable supplies: %d\n", ret);
- goto exit;
- }
-
- dac33->chip_power = 0;
- }
-
-exit:
- mutex_unlock(&dac33->mutex);
- return ret;
-}
-
-static int dac33_playback_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(w->codec);
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- if (likely(dac33->substream)) {
- dac33_calculate_times(dac33->substream);
- dac33_prepare_chip(dac33->substream);
- }
- break;
- case SND_SOC_DAPM_POST_PMD:
- dac33_disable_digital(w->codec);
- break;
- }
- return 0;
-}
-
-static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.integer.value[0] = dac33->fifo_mode;
-
- return 0;
-}
-
-static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
- int ret = 0;
-
- if (dac33->fifo_mode == ucontrol->value.integer.value[0])
- return 0;
- /* Do not allow changes while stream is running*/
- if (codec->active)
- return -EPERM;
-
- if (ucontrol->value.integer.value[0] < 0 ||
- ucontrol->value.integer.value[0] >= DAC33_FIFO_LAST_MODE)
- ret = -EINVAL;
- else
- dac33->fifo_mode = ucontrol->value.integer.value[0];
-
- return ret;
-}
-
-/* Codec operation modes */
-static const char *dac33_fifo_mode_texts[] = {
- "Bypass", "Mode 1", "Mode 7"
-};
-
-static const struct soc_enum dac33_fifo_mode_enum =
- SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dac33_fifo_mode_texts),
- dac33_fifo_mode_texts);
-
-/* L/R Line Output Gain */
-static const char *lr_lineout_gain_texts[] = {
- "Line -12dB DAC 0dB", "Line -6dB DAC 6dB",
- "Line 0dB DAC 12dB", "Line 6dB DAC 18dB",
-};
-
-static const struct soc_enum l_lineout_gain_enum =
- SOC_ENUM_SINGLE(DAC33_LDAC_PWR_CTRL, 0,
- ARRAY_SIZE(lr_lineout_gain_texts),
- lr_lineout_gain_texts);
-
-static const struct soc_enum r_lineout_gain_enum =
- SOC_ENUM_SINGLE(DAC33_RDAC_PWR_CTRL, 0,
- ARRAY_SIZE(lr_lineout_gain_texts),
- lr_lineout_gain_texts);
-
-/*
- * DACL/R digital volume control:
- * from 0 dB to -63.5 in 0.5 dB steps
- * Need to be inverted later on:
- * 0x00 == 0 dB
- * 0x7f == -63.5 dB
- */
-static DECLARE_TLV_DB_SCALE(dac_digivol_tlv, -6350, 50, 0);
-
-static const struct snd_kcontrol_new dac33_snd_controls[] = {
- SOC_DOUBLE_R_TLV("DAC Digital Playback Volume",
- DAC33_LDAC_DIG_VOL_CTRL, DAC33_RDAC_DIG_VOL_CTRL,
- 0, 0x7f, 1, dac_digivol_tlv),
- SOC_DOUBLE_R("DAC Digital Playback Switch",
- DAC33_LDAC_DIG_VOL_CTRL, DAC33_RDAC_DIG_VOL_CTRL, 7, 1, 1),
- SOC_DOUBLE_R("Line to Line Out Volume",
- DAC33_LINEL_TO_LLO_VOL, DAC33_LINER_TO_RLO_VOL, 0, 127, 1),
- SOC_ENUM("Left Line Output Gain", l_lineout_gain_enum),
- SOC_ENUM("Right Line Output Gain", r_lineout_gain_enum),
-};
-
-static const struct snd_kcontrol_new dac33_mode_snd_controls[] = {
- SOC_ENUM_EXT("FIFO Mode", dac33_fifo_mode_enum,
- dac33_get_fifo_mode, dac33_set_fifo_mode),
-};
-
-/* Analog bypass */
-static const struct snd_kcontrol_new dac33_dapm_abypassl_control =
- SOC_DAPM_SINGLE("Switch", DAC33_LINEL_TO_LLO_VOL, 7, 1, 1);
-
-static const struct snd_kcontrol_new dac33_dapm_abypassr_control =
- SOC_DAPM_SINGLE("Switch", DAC33_LINER_TO_RLO_VOL, 7, 1, 1);
-
-/* LOP L/R invert selection */
-static const char *dac33_lr_lom_texts[] = {"DAC", "LOP"};
-
-static const struct soc_enum dac33_left_lom_enum =
- SOC_ENUM_SINGLE(DAC33_OUT_AMP_CTRL, 3,
- ARRAY_SIZE(dac33_lr_lom_texts),
- dac33_lr_lom_texts);
-
-static const struct snd_kcontrol_new dac33_dapm_left_lom_control =
-SOC_DAPM_ENUM("Route", dac33_left_lom_enum);
-
-static const struct soc_enum dac33_right_lom_enum =
- SOC_ENUM_SINGLE(DAC33_OUT_AMP_CTRL, 2,
- ARRAY_SIZE(dac33_lr_lom_texts),
- dac33_lr_lom_texts);
-
-static const struct snd_kcontrol_new dac33_dapm_right_lom_control =
-SOC_DAPM_ENUM("Route", dac33_right_lom_enum);
-
-static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
- SND_SOC_DAPM_OUTPUT("LEFT_LO"),
- SND_SOC_DAPM_OUTPUT("RIGHT_LO"),
-
- SND_SOC_DAPM_INPUT("LINEL"),
- SND_SOC_DAPM_INPUT("LINER"),
-
- SND_SOC_DAPM_DAC("DACL", "Left Playback", SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_DAC("DACR", "Right Playback", SND_SOC_NOPM, 0, 0),
-
- /* Analog bypass */
- SND_SOC_DAPM_SWITCH("Analog Left Bypass", SND_SOC_NOPM, 0, 0,
- &dac33_dapm_abypassl_control),
- SND_SOC_DAPM_SWITCH("Analog Right Bypass", SND_SOC_NOPM, 0, 0,
- &dac33_dapm_abypassr_control),
-
- SND_SOC_DAPM_MUX("Left LOM Inverted From", SND_SOC_NOPM, 0, 0,
- &dac33_dapm_left_lom_control),
- SND_SOC_DAPM_MUX("Right LOM Inverted From", SND_SOC_NOPM, 0, 0,
- &dac33_dapm_right_lom_control),
- /*
- * For DAPM path, when only the anlog bypass path is enabled, and the
- * LOP inverted from the corresponding DAC side.
- * This is needed, so we can attach the DAC power supply in this case.
- */
- SND_SOC_DAPM_PGA("Left Bypass PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Right Bypass PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
-
- SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amplifier",
- DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0),
- SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amplifier",
- DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0),
-
- SND_SOC_DAPM_SUPPLY("Left DAC Power",
- DAC33_LDAC_PWR_CTRL, 2, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("Right DAC Power",
- DAC33_RDAC_PWR_CTRL, 2, 0, NULL, 0),
-
- SND_SOC_DAPM_SUPPLY("Codec Power",
- DAC33_PWR_CTRL, 4, 0, NULL, 0),
-
- SND_SOC_DAPM_PRE("Pre Playback", dac33_playback_event),
- SND_SOC_DAPM_POST("Post Playback", dac33_playback_event),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- /* Analog bypass */
- {"Analog Left Bypass", "Switch", "LINEL"},
- {"Analog Right Bypass", "Switch", "LINER"},
-
- {"Output Left Amplifier", NULL, "DACL"},
- {"Output Right Amplifier", NULL, "DACR"},
-
- {"Left Bypass PGA", NULL, "Analog Left Bypass"},
- {"Right Bypass PGA", NULL, "Analog Right Bypass"},
-
- {"Left LOM Inverted From", "DAC", "Left Bypass PGA"},
- {"Right LOM Inverted From", "DAC", "Right Bypass PGA"},
- {"Left LOM Inverted From", "LOP", "Analog Left Bypass"},
- {"Right LOM Inverted From", "LOP", "Analog Right Bypass"},
-
- {"Output Left Amplifier", NULL, "Left LOM Inverted From"},
- {"Output Right Amplifier", NULL, "Right LOM Inverted From"},
-
- {"DACL", NULL, "Left DAC Power"},
- {"DACR", NULL, "Right DAC Power"},
-
- {"Left Bypass PGA", NULL, "Left DAC Power"},
- {"Right Bypass PGA", NULL, "Right DAC Power"},
-
- /* output */
- {"LEFT_LO", NULL, "Output Left Amplifier"},
- {"RIGHT_LO", NULL, "Output Right Amplifier"},
-
- {"LEFT_LO", NULL, "Codec Power"},
- {"RIGHT_LO", NULL, "Codec Power"},
-};
-
-static int dac33_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- int ret;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- /* Coming from OFF, switch on the codec */
- ret = dac33_hard_power(codec, 1);
- if (ret != 0)
- return ret;
-
- dac33_init_chip(codec);
- }
- break;
- case SND_SOC_BIAS_OFF:
- /* Do not power off, when the codec is already off */
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
- return 0;
- ret = dac33_hard_power(codec, 0);
- if (ret != 0)
- return ret;
- break;
- }
- codec->dapm.bias_level = level;
-
- return 0;
-}
-
-static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
-{
- struct snd_soc_codec *codec = dac33->codec;
- unsigned int delay;
- unsigned long flags;
-
- switch (dac33->fifo_mode) {
- case DAC33_FIFO_MODE1:
- dac33_write16(codec, DAC33_NSAMPLE_MSB,
- DAC33_THRREG(dac33->nsample));
-
- /* Take the timestamps */
- spin_lock_irqsave(&dac33->lock, flags);
- dac33->t_stamp2 = ktime_to_us(ktime_get());
- dac33->t_stamp1 = dac33->t_stamp2;
- spin_unlock_irqrestore(&dac33->lock, flags);
-
- dac33_write16(codec, DAC33_PREFILL_MSB,
- DAC33_THRREG(dac33->alarm_threshold));
- /* Enable Alarm Threshold IRQ with a delay */
- delay = SAMPLES_TO_US(dac33->burst_rate,
- dac33->alarm_threshold) + 1000;
- usleep_range(delay, delay + 500);
- dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
- break;
- case DAC33_FIFO_MODE7:
- /* Take the timestamp */
- spin_lock_irqsave(&dac33->lock, flags);
- dac33->t_stamp1 = ktime_to_us(ktime_get());
- /* Move back the timestamp with drain time */
- dac33->t_stamp1 -= dac33->mode7_us_to_lthr;
- spin_unlock_irqrestore(&dac33->lock, flags);
-
- dac33_write16(codec, DAC33_PREFILL_MSB,
- DAC33_THRREG(DAC33_MODE7_MARGIN));
-
- /* Enable Upper Threshold IRQ */
- dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MUT);
- break;
- default:
- dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
- dac33->fifo_mode);
- break;
- }
-}
-
-static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33)
-{
- struct snd_soc_codec *codec = dac33->codec;
- unsigned long flags;
-
- switch (dac33->fifo_mode) {
- case DAC33_FIFO_MODE1:
- /* Take the timestamp */
- spin_lock_irqsave(&dac33->lock, flags);
- dac33->t_stamp2 = ktime_to_us(ktime_get());
- spin_unlock_irqrestore(&dac33->lock, flags);
-
- dac33_write16(codec, DAC33_NSAMPLE_MSB,
- DAC33_THRREG(dac33->nsample));
- break;
- case DAC33_FIFO_MODE7:
- /* At the moment we are not using interrupts in mode7 */
- break;
- default:
- dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
- dac33->fifo_mode);
- break;
- }
-}
-
-static void dac33_work(struct work_struct *work)
-{
- struct snd_soc_codec *codec;
- struct tlv320dac33_priv *dac33;
- u8 reg;
-
- dac33 = container_of(work, struct tlv320dac33_priv, work);
- codec = dac33->codec;
-
- mutex_lock(&dac33->mutex);
- switch (dac33->state) {
- case DAC33_PREFILL:
- dac33->state = DAC33_PLAYBACK;
- dac33_prefill_handler(dac33);
- break;
- case DAC33_PLAYBACK:
- dac33_playback_handler(dac33);
- break;
- case DAC33_IDLE:
- break;
- case DAC33_FLUSH:
- dac33->state = DAC33_IDLE;
- /* Mask all interrupts from dac33 */
- dac33_write(codec, DAC33_FIFO_IRQ_MASK, 0);
-
- /* flush fifo */
- reg = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A);
- reg |= DAC33_FIFOFLUSH;
- dac33_write(codec, DAC33_FIFO_CTRL_A, reg);
- break;
- }
- mutex_unlock(&dac33->mutex);
-}
-
-static irqreturn_t dac33_interrupt_handler(int irq, void *dev)
-{
- struct snd_soc_codec *codec = dev;
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
- unsigned long flags;
-
- spin_lock_irqsave(&dac33->lock, flags);
- dac33->t_stamp1 = ktime_to_us(ktime_get());
- spin_unlock_irqrestore(&dac33->lock, flags);
-
- /* Do not schedule the workqueue in Mode7 */
- if (dac33->fifo_mode != DAC33_FIFO_MODE7)
- queue_work(dac33->dac33_wq, &dac33->work);
-
- return IRQ_HANDLED;
-}
-
-static void dac33_oscwait(struct snd_soc_codec *codec)
-{
- int timeout = 60;
- u8 reg;
-
- do {
- usleep_range(1000, 2000);
- dac33_read(codec, DAC33_INT_OSC_STATUS, &reg);
- } while (((reg & 0x03) != DAC33_OSCSTATUS_NORMAL) && timeout--);
- if ((reg & 0x03) != DAC33_OSCSTATUS_NORMAL)
- dev_err(codec->dev,
- "internal oscillator calibration failed\n");
-}
-
-static int dac33_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
-
- /* Stream started, save the substream pointer */
- dac33->substream = substream;
-
- return 0;
-}
-
-static void dac33_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
-
- dac33->substream = NULL;
-}
-
-#define CALC_BURST_RATE(bclkdiv, bclk_per_sample) \
- (BURST_BASEFREQ_HZ / bclkdiv / bclk_per_sample)
-static int dac33_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
-
- /* Check parameters for validity */
- switch (params_rate(params)) {
- case 44100:
- case 48000:
- break;
- default:
- dev_err(codec->dev, "unsupported rate %d\n",
- params_rate(params));
- return -EINVAL;
- }
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- dac33->fifo_size = DAC33_FIFO_SIZE_16BIT;
- dac33->burst_rate = CALC_BURST_RATE(dac33->burst_bclkdiv, 32);
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- dac33->fifo_size = DAC33_FIFO_SIZE_24BIT;
- dac33->burst_rate = CALC_BURST_RATE(dac33->burst_bclkdiv, 64);
- break;
- default:
- dev_err(codec->dev, "unsupported format %d\n",
- params_format(params));
- return -EINVAL;
- }
-
- return 0;
-}
-
-#define CALC_OSCSET(rate, refclk) ( \
- ((((rate * 10000) / refclk) * 4096) + 7000) / 10000)
-#define CALC_RATIOSET(rate, refclk) ( \
- ((((refclk * 100000) / rate) * 16384) + 50000) / 100000)
-
-/*
- * tlv320dac33 is strict on the sequence of the register writes, if the register
- * writes happens in different order, than dac33 might end up in unknown state.
- * Use the known, working sequence of register writes to initialize the dac33.
- */
-static int dac33_prepare_chip(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
- unsigned int oscset, ratioset, pwr_ctrl, reg_tmp;
- u8 aictrl_a, aictrl_b, fifoctrl_a;
-
- switch (substream->runtime->rate) {
- case 44100:
- case 48000:
- oscset = CALC_OSCSET(substream->runtime->rate, dac33->refclk);
- ratioset = CALC_RATIOSET(substream->runtime->rate,
- dac33->refclk);
- break;
- default:
- dev_err(codec->dev, "unsupported rate %d\n",
- substream->runtime->rate);
- return -EINVAL;
- }
-
-
- aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
- aictrl_a &= ~(DAC33_NCYCL_MASK | DAC33_WLEN_MASK);
- /* Read FIFO control A, and clear FIFO flush bit */
- fifoctrl_a = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A);
- fifoctrl_a &= ~DAC33_FIFOFLUSH;
-
- fifoctrl_a &= ~DAC33_WIDTH;
- switch (substream->runtime->format) {
- case SNDRV_PCM_FORMAT_S16_LE:
- aictrl_a |= (DAC33_NCYCL_16 | DAC33_WLEN_16);
- fifoctrl_a |= DAC33_WIDTH;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- aictrl_a |= (DAC33_NCYCL_32 | DAC33_WLEN_24);
- break;
- default:
- dev_err(codec->dev, "unsupported format %d\n",
- substream->runtime->format);
- return -EINVAL;
- }
-
- mutex_lock(&dac33->mutex);
-
- if (!dac33->chip_power) {
- /*
- * Chip is not powered yet.
- * Do the init in the dac33_set_bias_level later.
- */
- mutex_unlock(&dac33->mutex);
- return 0;
- }
-
- dac33_soft_power(codec, 0);
- dac33_soft_power(codec, 1);
-
- reg_tmp = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL);
- dac33_write(codec, DAC33_INT_OSC_CTRL, reg_tmp);
-
- /* Write registers 0x08 and 0x09 (MSB, LSB) */
- dac33_write16(codec, DAC33_INT_OSC_FREQ_RAT_A, oscset);
-
- /* OSC calibration time */
- dac33_write(codec, DAC33_CALIB_TIME, 96);
-
- /* adjustment treshold & step */
- dac33_write(codec, DAC33_INT_OSC_CTRL_B, DAC33_ADJTHRSHLD(2) |
- DAC33_ADJSTEP(1));
-
- /* div=4 / gain=1 / div */
- dac33_write(codec, DAC33_INT_OSC_CTRL_C, DAC33_REFDIV(4));
-
- pwr_ctrl = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
- pwr_ctrl |= DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB;
- dac33_write(codec, DAC33_PWR_CTRL, pwr_ctrl);
-
- dac33_oscwait(codec);
-
- if (dac33->fifo_mode) {
- /* Generic for all FIFO modes */
- /* 50-51 : ASRC Control registers */
- dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCLKDIV(1));
- dac33_write(codec, DAC33_ASRC_CTRL_B, 1); /* ??? */
-
- /* Write registers 0x34 and 0x35 (MSB, LSB) */
- dac33_write16(codec, DAC33_SRC_REF_CLK_RATIO_A, ratioset);
-
- /* Set interrupts to high active */
- dac33_write(codec, DAC33_INTP_CTRL_A, DAC33_INTPM_AHIGH);
- } else {
- /* FIFO bypass mode */
- /* 50-51 : ASRC Control registers */
- dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCBYP);
- dac33_write(codec, DAC33_ASRC_CTRL_B, 0); /* ??? */
- }
-
- /* Interrupt behaviour configuration */
- switch (dac33->fifo_mode) {
- case DAC33_FIFO_MODE1:
- dac33_write(codec, DAC33_FIFO_IRQ_MODE_B,
- DAC33_ATM(DAC33_FIFO_IRQ_MODE_LEVEL));
- break;
- case DAC33_FIFO_MODE7:
- dac33_write(codec, DAC33_FIFO_IRQ_MODE_A,
- DAC33_UTM(DAC33_FIFO_IRQ_MODE_LEVEL));
- break;
- default:
- /* in FIFO bypass mode, the interrupts are not used */
- break;
- }
-
- aictrl_b = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
-
- switch (dac33->fifo_mode) {
- case DAC33_FIFO_MODE1:
- /*
- * For mode1:
- * Disable the FIFO bypass (Enable the use of FIFO)
- * Select nSample mode
- * BCLK is only running when data is needed by DAC33
- */
- fifoctrl_a &= ~DAC33_FBYPAS;
- fifoctrl_a &= ~DAC33_FAUTO;
- if (dac33->keep_bclk)
- aictrl_b |= DAC33_BCLKON;
- else
- aictrl_b &= ~DAC33_BCLKON;
- break;
- case DAC33_FIFO_MODE7:
- /*
- * For mode1:
- * Disable the FIFO bypass (Enable the use of FIFO)
- * Select Threshold mode
- * BCLK is only running when data is needed by DAC33
- */
- fifoctrl_a &= ~DAC33_FBYPAS;
- fifoctrl_a |= DAC33_FAUTO;
- if (dac33->keep_bclk)
- aictrl_b |= DAC33_BCLKON;
- else
- aictrl_b &= ~DAC33_BCLKON;
- break;
- default:
- /*
- * For FIFO bypass mode:
- * Enable the FIFO bypass (Disable the FIFO use)
- * Set the BCLK as continuous
- */
- fifoctrl_a |= DAC33_FBYPAS;
- aictrl_b |= DAC33_BCLKON;
- break;
- }
-
- dac33_write(codec, DAC33_FIFO_CTRL_A, fifoctrl_a);
- dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
- dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
-
- /*
- * BCLK divide ratio
- * 0: 1.5
- * 1: 1
- * 2: 2
- * ...
- * 254: 254
- * 255: 255
- */
- if (dac33->fifo_mode)
- dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C,
- dac33->burst_bclkdiv);
- else
- if (substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE)
- dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32);
- else
- dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 16);
-
- switch (dac33->fifo_mode) {
- case DAC33_FIFO_MODE1:
- dac33_write16(codec, DAC33_ATHR_MSB,
- DAC33_THRREG(dac33->alarm_threshold));
- break;
- case DAC33_FIFO_MODE7:
- /*
- * Configure the threshold levels, and leave 10 sample space
- * at the bottom, and also at the top of the FIFO
- */
- dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(dac33->uthr));
- dac33_write16(codec, DAC33_LTHR_MSB,
- DAC33_THRREG(DAC33_MODE7_MARGIN));
- break;
- default:
- break;
- }
-
- mutex_unlock(&dac33->mutex);
-
- return 0;
-}
-
-static void dac33_calculate_times(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
- unsigned int period_size = substream->runtime->period_size;
- unsigned int rate = substream->runtime->rate;
- unsigned int nsample_limit;
-
- /* In bypass mode we don't need to calculate */
- if (!dac33->fifo_mode)
- return;
-
- switch (dac33->fifo_mode) {
- case DAC33_FIFO_MODE1:
- /* Number of samples under i2c latency */
- dac33->alarm_threshold = US_TO_SAMPLES(rate,
- dac33->mode1_latency);
- nsample_limit = dac33->fifo_size - dac33->alarm_threshold;
-
- if (period_size <= dac33->alarm_threshold)
- /*
- * Configure nSamaple to number of periods,
- * which covers the latency requironment.
- */
- dac33->nsample = period_size *
- ((dac33->alarm_threshold / period_size) +
- (dac33->alarm_threshold % period_size ?
- 1 : 0));
- else if (period_size > nsample_limit)
- dac33->nsample = nsample_limit;
- else
- dac33->nsample = period_size;
-
- dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate,
- dac33->nsample);
- dac33->t_stamp1 = 0;
- dac33->t_stamp2 = 0;
- break;
- case DAC33_FIFO_MODE7:
- dac33->uthr = UTHR_FROM_PERIOD_SIZE(period_size, rate,
- dac33->burst_rate) + 9;
- if (dac33->uthr > (dac33->fifo_size - DAC33_MODE7_MARGIN))
- dac33->uthr = dac33->fifo_size - DAC33_MODE7_MARGIN;
- if (dac33->uthr < (DAC33_MODE7_MARGIN + 10))
- dac33->uthr = (DAC33_MODE7_MARGIN + 10);
-
- dac33->mode7_us_to_lthr =
- SAMPLES_TO_US(substream->runtime->rate,
- dac33->uthr - DAC33_MODE7_MARGIN + 1);
- dac33->t_stamp1 = 0;
- break;
- default:
- break;
- }
-
-}
-
-static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
- int ret = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (dac33->fifo_mode) {
- dac33->state = DAC33_PREFILL;
- queue_work(dac33->dac33_wq, &dac33->work);
- }
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (dac33->fifo_mode) {
- dac33->state = DAC33_FLUSH;
- queue_work(dac33->dac33_wq, &dac33->work);
- }
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static snd_pcm_sframes_t dac33_dai_delay(
- struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
- unsigned long long t0, t1, t_now;
- unsigned int time_delta, uthr;
- int samples_out, samples_in, samples;
- snd_pcm_sframes_t delay = 0;
- unsigned long flags;
-
- switch (dac33->fifo_mode) {
- case DAC33_FIFO_BYPASS:
- break;
- case DAC33_FIFO_MODE1:
- spin_lock_irqsave(&dac33->lock, flags);
- t0 = dac33->t_stamp1;
- t1 = dac33->t_stamp2;
- spin_unlock_irqrestore(&dac33->lock, flags);
- t_now = ktime_to_us(ktime_get());
-
- /* We have not started to fill the FIFO yet, delay is 0 */
- if (!t1)
- goto out;
-
- if (t0 > t1) {
- /*
- * Phase 1:
- * After Alarm threshold, and before nSample write
- */
- time_delta = t_now - t0;
- samples_out = time_delta ? US_TO_SAMPLES(
- substream->runtime->rate,
- time_delta) : 0;
-
- if (likely(dac33->alarm_threshold > samples_out))
- delay = dac33->alarm_threshold - samples_out;
- else
- delay = 0;
- } else if ((t_now - t1) <= dac33->mode1_us_burst) {
- /*
- * Phase 2:
- * After nSample write (during burst operation)
- */
- time_delta = t_now - t0;
- samples_out = time_delta ? US_TO_SAMPLES(
- substream->runtime->rate,
- time_delta) : 0;
-
- time_delta = t_now - t1;
- samples_in = time_delta ? US_TO_SAMPLES(
- dac33->burst_rate,
- time_delta) : 0;
-
- samples = dac33->alarm_threshold;
- samples += (samples_in - samples_out);
-
- if (likely(samples > 0))
- delay = samples;
- else
- delay = 0;
- } else {
- /*
- * Phase 3:
- * After burst operation, before next alarm threshold
- */
- time_delta = t_now - t0;
- samples_out = time_delta ? US_TO_SAMPLES(
- substream->runtime->rate,
- time_delta) : 0;
-
- samples_in = dac33->nsample;
- samples = dac33->alarm_threshold;
- samples += (samples_in - samples_out);
-
- if (likely(samples > 0))
- delay = samples > dac33->fifo_size ?
- dac33->fifo_size : samples;
- else
- delay = 0;
- }
- break;
- case DAC33_FIFO_MODE7:
- spin_lock_irqsave(&dac33->lock, flags);
- t0 = dac33->t_stamp1;
- uthr = dac33->uthr;
- spin_unlock_irqrestore(&dac33->lock, flags);
- t_now = ktime_to_us(ktime_get());
-
- /* We have not started to fill the FIFO yet, delay is 0 */
- if (!t0)
- goto out;
-
- if (t_now <= t0) {
- /*
- * Either the timestamps are messed or equal. Report
- * maximum delay
- */
- delay = uthr;
- goto out;
- }
-
- time_delta = t_now - t0;
- if (time_delta <= dac33->mode7_us_to_lthr) {
- /*
- * Phase 1:
- * After burst (draining phase)
- */
- samples_out = US_TO_SAMPLES(
- substream->runtime->rate,
- time_delta);
-
- if (likely(uthr > samples_out))
- delay = uthr - samples_out;
- else
- delay = 0;
- } else {
- /*
- * Phase 2:
- * During burst operation
- */
- time_delta = time_delta - dac33->mode7_us_to_lthr;
-
- samples_out = US_TO_SAMPLES(
- substream->runtime->rate,
- time_delta);
- samples_in = US_TO_SAMPLES(
- dac33->burst_rate,
- time_delta);
- delay = DAC33_MODE7_MARGIN + samples_in - samples_out;
-
- if (unlikely(delay > uthr))
- delay = uthr;
- }
- break;
- default:
- dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
- dac33->fifo_mode);
- break;
- }
-out:
- return delay;
-}
-
-static int dac33_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
- u8 ioc_reg, asrcb_reg;
-
- ioc_reg = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL);
- asrcb_reg = dac33_read_reg_cache(codec, DAC33_ASRC_CTRL_B);
- switch (clk_id) {
- case TLV320DAC33_MCLK:
- ioc_reg |= DAC33_REFSEL;
- asrcb_reg |= DAC33_SRCREFSEL;
- break;
- case TLV320DAC33_SLEEPCLK:
- ioc_reg &= ~DAC33_REFSEL;
- asrcb_reg &= ~DAC33_SRCREFSEL;
- break;
- default:
- dev_err(codec->dev, "Invalid clock ID (%d)\n", clk_id);
- break;
- }
- dac33->refclk = freq;
-
- dac33_write_reg_cache(codec, DAC33_INT_OSC_CTRL, ioc_reg);
- dac33_write_reg_cache(codec, DAC33_ASRC_CTRL_B, asrcb_reg);
-
- return 0;
-}
-
-static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
- u8 aictrl_a, aictrl_b;
-
- aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
- aictrl_b = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- /* Codec Master */
- aictrl_a |= (DAC33_MSBCLK | DAC33_MSWCLK);
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- /* Codec Slave */
- if (dac33->fifo_mode) {
- dev_err(codec->dev, "FIFO mode requires master mode\n");
- return -EINVAL;
- } else
- aictrl_a &= ~(DAC33_MSBCLK | DAC33_MSWCLK);
- break;
- default:
- return -EINVAL;
- }
-
- aictrl_a &= ~DAC33_AFMT_MASK;
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- aictrl_a |= DAC33_AFMT_I2S;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- aictrl_a |= DAC33_AFMT_DSP;
- aictrl_b &= ~DAC33_DATA_DELAY_MASK;
- aictrl_b |= DAC33_DATA_DELAY(0);
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- aictrl_a |= DAC33_AFMT_RIGHT_J;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- aictrl_a |= DAC33_AFMT_LEFT_J;
- break;
- default:
- dev_err(codec->dev, "Unsupported format (%u)\n",
- fmt & SND_SOC_DAIFMT_FORMAT_MASK);
- return -EINVAL;
- }
-
- dac33_write_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
- dac33_write_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
-
- return 0;
-}
-
-static int dac33_soc_probe(struct snd_soc_codec *codec)
-{
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
- int ret = 0;
-
- codec->control_data = dac33->control_data;
- codec->hw_write = (hw_write_t) i2c_master_send;
- dac33->codec = codec;
-
- /* Read the tlv320dac33 ID registers */
- ret = dac33_hard_power(codec, 1);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to power up codec: %d\n", ret);
- goto err_power;
- }
- ret = dac33_read_id(codec);
- dac33_hard_power(codec, 0);
-
- if (ret < 0) {
- dev_err(codec->dev, "Failed to read chip ID: %d\n", ret);
- ret = -ENODEV;
- goto err_power;
- }
-
- /* Check if the IRQ number is valid and request it */
- if (dac33->irq >= 0) {
- ret = request_irq(dac33->irq, dac33_interrupt_handler,
- IRQF_TRIGGER_RISING,
- codec->name, codec);
- if (ret < 0) {
- dev_err(codec->dev, "Could not request IRQ%d (%d)\n",
- dac33->irq, ret);
- dac33->irq = -1;
- }
- if (dac33->irq != -1) {
- /* Setup work queue */
- dac33->dac33_wq =
- create_singlethread_workqueue("tlv320dac33");
- if (dac33->dac33_wq == NULL) {
- free_irq(dac33->irq, codec);
- return -ENOMEM;
- }
-
- INIT_WORK(&dac33->work, dac33_work);
- }
- }
-
- /* Only add the FIFO controls, if we have valid IRQ number */
- if (dac33->irq >= 0)
- snd_soc_add_codec_controls(codec, dac33_mode_snd_controls,
- ARRAY_SIZE(dac33_mode_snd_controls));
-
-err_power:
- return ret;
-}
-
-static int dac33_soc_remove(struct snd_soc_codec *codec)
-{
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
-
- dac33_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- if (dac33->irq >= 0) {
- free_irq(dac33->irq, dac33->codec);
- destroy_workqueue(dac33->dac33_wq);
- }
- return 0;
-}
-
-static int dac33_soc_suspend(struct snd_soc_codec *codec)
-{
- dac33_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int dac33_soc_resume(struct snd_soc_codec *codec)
-{
- dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = {
- .read = dac33_read_reg_cache,
- .write = dac33_write_locked,
- .set_bias_level = dac33_set_bias_level,
- .idle_bias_off = true,
- .reg_cache_size = ARRAY_SIZE(dac33_reg),
- .reg_word_size = sizeof(u8),
- .reg_cache_default = dac33_reg,
- .probe = dac33_soc_probe,
- .remove = dac33_soc_remove,
- .suspend = dac33_soc_suspend,
- .resume = dac33_soc_resume,
-
- .controls = dac33_snd_controls,
- .num_controls = ARRAY_SIZE(dac33_snd_controls),
- .dapm_widgets = dac33_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(dac33_dapm_widgets),
- .dapm_routes = audio_map,
- .num_dapm_routes = ARRAY_SIZE(audio_map),
-};
-
-#define DAC33_RATES (SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000)
-#define DAC33_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops dac33_dai_ops = {
- .startup = dac33_startup,
- .shutdown = dac33_shutdown,
- .hw_params = dac33_hw_params,
- .trigger = dac33_pcm_trigger,
- .delay = dac33_dai_delay,
- .set_sysclk = dac33_set_dai_sysclk,
- .set_fmt = dac33_set_dai_fmt,
-};
-
-static struct snd_soc_dai_driver dac33_dai = {
- .name = "tlv320dac33-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = DAC33_RATES,
- .formats = DAC33_FORMATS,
- .sig_bits = 24,
- },
- .ops = &dac33_dai_ops,
-};
-
-static int __devinit dac33_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct tlv320dac33_platform_data *pdata;
- struct tlv320dac33_priv *dac33;
- int ret, i;
-
- if (client->dev.platform_data == NULL) {
- dev_err(&client->dev, "Platform data not set\n");
- return -ENODEV;
- }
- pdata = client->dev.platform_data;
-
- dac33 = devm_kzalloc(&client->dev, sizeof(struct tlv320dac33_priv),
- GFP_KERNEL);
- if (dac33 == NULL)
- return -ENOMEM;
-
- dac33->control_data = client;
- mutex_init(&dac33->mutex);
- spin_lock_init(&dac33->lock);
-
- i2c_set_clientdata(client, dac33);
-
- dac33->power_gpio = pdata->power_gpio;
- dac33->burst_bclkdiv = pdata->burst_bclkdiv;
- dac33->keep_bclk = pdata->keep_bclk;
- dac33->mode1_latency = pdata->mode1_latency;
- if (!dac33->mode1_latency)
- dac33->mode1_latency = 10000; /* 10ms */
- dac33->irq = client->irq;
- /* Disable FIFO use by default */
- dac33->fifo_mode = DAC33_FIFO_BYPASS;
-
- /* Check if the reset GPIO number is valid and request it */
- if (dac33->power_gpio >= 0) {
- ret = gpio_request(dac33->power_gpio, "tlv320dac33 reset");
- if (ret < 0) {
- dev_err(&client->dev,
- "Failed to request reset GPIO (%d)\n",
- dac33->power_gpio);
- goto err_gpio;
- }
- gpio_direction_output(dac33->power_gpio, 0);
- }
-
- for (i = 0; i < ARRAY_SIZE(dac33->supplies); i++)
- dac33->supplies[i].supply = dac33_supply_names[i];
-
- ret = regulator_bulk_get(&client->dev, ARRAY_SIZE(dac33->supplies),
- dac33->supplies);
-
- if (ret != 0) {
- dev_err(&client->dev, "Failed to request supplies: %d\n", ret);
- goto err_get;
- }
-
- ret = snd_soc_register_codec(&client->dev,
- &soc_codec_dev_tlv320dac33, &dac33_dai, 1);
- if (ret < 0)
- goto err_register;
-
- return ret;
-err_register:
- regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
-err_get:
- if (dac33->power_gpio >= 0)
- gpio_free(dac33->power_gpio);
-err_gpio:
- return ret;
-}
-
-static int __devexit dac33_i2c_remove(struct i2c_client *client)
-{
- struct tlv320dac33_priv *dac33 = i2c_get_clientdata(client);
-
- if (unlikely(dac33->chip_power))
- dac33_hard_power(dac33->codec, 0);
-
- if (dac33->power_gpio >= 0)
- gpio_free(dac33->power_gpio);
-
- regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
-
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static const struct i2c_device_id tlv320dac33_i2c_id[] = {
- {
- .name = "tlv320dac33",
- .driver_data = 0,
- },
- { },
-};
-MODULE_DEVICE_TABLE(i2c, tlv320dac33_i2c_id);
-
-static struct i2c_driver tlv320dac33_i2c_driver = {
- .driver = {
- .name = "tlv320dac33-codec",
- .owner = THIS_MODULE,
- },
- .probe = dac33_i2c_probe,
- .remove = __devexit_p(dac33_i2c_remove),
- .id_table = tlv320dac33_i2c_id,
-};
-
-static int __init dac33_module_init(void)
-{
- int r;
- r = i2c_add_driver(&tlv320dac33_i2c_driver);
- if (r < 0) {
- printk(KERN_ERR "DAC33: driver registration failed\n");
- return r;
- }
- return 0;
-}
-module_init(dac33_module_init);
-
-static void __exit dac33_module_exit(void)
-{
- i2c_del_driver(&tlv320dac33_i2c_driver);
-}
-module_exit(dac33_module_exit);
-
-
-MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver");
-MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/tlv320dac33.h b/ANDROID_3.4.5/sound/soc/codecs/tlv320dac33.h
deleted file mode 100644
index ed696707..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/tlv320dac33.h
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * ALSA SoC Texas Instruments TLV320DAC33 codec driver
- *
- * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
- *
- * Copyright: (C) 2009 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __TLV320DAC33_H
-#define __TLV320DAC33_H
-
-#define DAC33_PAGE_SELECT 0x00
-#define DAC33_PWR_CTRL 0x01
-#define DAC33_PLL_CTRL_A 0x02
-#define DAC33_PLL_CTRL_B 0x03
-#define DAC33_PLL_CTRL_C 0x04
-#define DAC33_PLL_CTRL_D 0x05
-#define DAC33_PLL_CTRL_E 0x06
-#define DAC33_INT_OSC_CTRL 0x07
-#define DAC33_INT_OSC_FREQ_RAT_A 0x08
-#define DAC33_INT_OSC_FREQ_RAT_B 0x09
-#define DAC33_INT_OSC_DAC_RATIO_SET 0x0A
-#define DAC33_CALIB_TIME 0x0B
-#define DAC33_INT_OSC_CTRL_B 0x0C
-#define DAC33_INT_OSC_CTRL_C 0x0D
-#define DAC33_INT_OSC_STATUS 0x0E
-#define DAC33_INT_OSC_DAC_RATIO_READ 0x0F
-#define DAC33_INT_OSC_FREQ_RAT_READ_A 0x10
-#define DAC33_INT_OSC_FREQ_RAT_READ_B 0x11
-#define DAC33_SER_AUDIOIF_CTRL_A 0x12
-#define DAC33_SER_AUDIOIF_CTRL_B 0x13
-#define DAC33_SER_AUDIOIF_CTRL_C 0x14
-#define DAC33_FIFO_CTRL_A 0x15
-#define DAC33_UTHR_MSB 0x16
-#define DAC33_UTHR_LSB 0x17
-#define DAC33_ATHR_MSB 0x18
-#define DAC33_ATHR_LSB 0x19
-#define DAC33_LTHR_MSB 0x1A
-#define DAC33_LTHR_LSB 0x1B
-#define DAC33_PREFILL_MSB 0x1C
-#define DAC33_PREFILL_LSB 0x1D
-#define DAC33_NSAMPLE_MSB 0x1E
-#define DAC33_NSAMPLE_LSB 0x1F
-#define DAC33_FIFO_WPTR_MSB 0x20
-#define DAC33_FIFO_WPTR_LSB 0x21
-#define DAC33_FIFO_RPTR_MSB 0x22
-#define DAC33_FIFO_RPTR_LSB 0x23
-#define DAC33_FIFO_DEPTH_MSB 0x24
-#define DAC33_FIFO_DEPTH_LSB 0x25
-#define DAC33_SAMPLES_REMAINING_MSB 0x26
-#define DAC33_SAMPLES_REMAINING_LSB 0x27
-#define DAC33_FIFO_IRQ_FLAG 0x28
-#define DAC33_FIFO_IRQ_MASK 0x29
-#define DAC33_FIFO_IRQ_MODE_A 0x2A
-#define DAC33_FIFO_IRQ_MODE_B 0x2B
-#define DAC33_DAC_CTRL_A 0x2C
-#define DAC33_DAC_CTRL_B 0x2D
-#define DAC33_DAC_CTRL_C 0x2E
-#define DAC33_LDAC_DIG_VOL_CTRL 0x2F
-#define DAC33_RDAC_DIG_VOL_CTRL 0x30
-#define DAC33_DAC_STATUS_FLAGS 0x31
-#define DAC33_ASRC_CTRL_A 0x32
-#define DAC33_ASRC_CTRL_B 0x33
-#define DAC33_SRC_REF_CLK_RATIO_A 0x34
-#define DAC33_SRC_REF_CLK_RATIO_B 0x35
-#define DAC33_SRC_EST_REF_CLK_RATIO_A 0x36
-#define DAC33_SRC_EST_REF_CLK_RATIO_B 0x37
-#define DAC33_INTP_CTRL_A 0x38
-#define DAC33_INTP_CTRL_B 0x39
-/* Registers 0x3A - 0x3F Reserved */
-#define DAC33_LDAC_PWR_CTRL 0x40
-#define DAC33_RDAC_PWR_CTRL 0x41
-#define DAC33_OUT_AMP_CM_CTRL 0x42
-#define DAC33_OUT_AMP_PWR_CTRL 0x43
-#define DAC33_OUT_AMP_CTRL 0x44
-#define DAC33_LINEL_TO_LLO_VOL 0x45
-/* Registers 0x45 - 0x47 Reserved */
-#define DAC33_LINER_TO_RLO_VOL 0x48
-#define DAC33_ANA_VOL_SOFT_STEP_CTRL 0x49
-#define DAC33_OSC_TRIM 0x4A
-/* Registers 0x4B - 0x7C Reserved */
-#define DAC33_DEVICE_ID_MSB 0x7D
-#define DAC33_DEVICE_ID_LSB 0x7E
-#define DAC33_DEVICE_REV_ID 0x7F
-
-#define DAC33_CACHEREGNUM 128
-
-/* Bit definitions */
-
-/* DAC33_PWR_CTRL (0x01) */
-#define DAC33_DACRPDNB (0x01 << 0)
-#define DAC33_DACLPDNB (0x01 << 1)
-#define DAC33_OSCPDNB (0x01 << 2)
-#define DAC33_PLLPDNB (0x01 << 3)
-#define DAC33_PDNALLB (0x01 << 4)
-#define DAC33_SOFT_RESET (0x01 << 7)
-
-/* DAC33_INT_OSC_CTRL (0x07) */
-#define DAC33_REFSEL (0x01 << 1)
-
-/* DAC33_INT_OSC_CTRL_B (0x0C) */
-#define DAC33_ADJSTEP(x) (x << 0)
-#define DAC33_ADJTHRSHLD(x) (x << 4)
-
-/* DAC33_INT_OSC_CTRL_C (0x0D) */
-#define DAC33_REFDIV(x) (x << 4)
-
-/* DAC33_INT_OSC_STATUS (0x0E) */
-#define DAC33_OSCSTATUS_IDLE_CALIB (0x00)
-#define DAC33_OSCSTATUS_NORMAL (0x01)
-#define DAC33_OSCSTATUS_ADJUSTMENT (0x03)
-#define DAC33_OSCSTATUS_NOT_USED (0x02)
-
-/* DAC33_SER_AUDIOIF_CTRL_A (0x12) */
-#define DAC33_MSWCLK (0x01 << 0)
-#define DAC33_MSBCLK (0x01 << 1)
-#define DAC33_AFMT_MASK (0x03 << 2)
-#define DAC33_AFMT_I2S (0x00 << 2)
-#define DAC33_AFMT_DSP (0x01 << 2)
-#define DAC33_AFMT_RIGHT_J (0x02 << 2)
-#define DAC33_AFMT_LEFT_J (0x03 << 2)
-#define DAC33_WLEN_MASK (0x03 << 4)
-#define DAC33_WLEN_16 (0x00 << 4)
-#define DAC33_WLEN_20 (0x01 << 4)
-#define DAC33_WLEN_24 (0x02 << 4)
-#define DAC33_WLEN_32 (0x03 << 4)
-#define DAC33_NCYCL_MASK (0x03 << 6)
-#define DAC33_NCYCL_16 (0x00 << 6)
-#define DAC33_NCYCL_20 (0x01 << 6)
-#define DAC33_NCYCL_24 (0x02 << 6)
-#define DAC33_NCYCL_32 (0x03 << 6)
-
-/* DAC33_SER_AUDIOIF_CTRL_B (0x13) */
-#define DAC33_DATA_DELAY_MASK (0x03 << 2)
-#define DAC33_DATA_DELAY(x) (x << 2)
-#define DAC33_BCLKON (0x01 << 5)
-
-/* DAC33_FIFO_CTRL_A (0x15) */
-#define DAC33_WIDTH (0x01 << 0)
-#define DAC33_FBYPAS (0x01 << 1)
-#define DAC33_FAUTO (0x01 << 2)
-#define DAC33_FIFOFLUSH (0x01 << 3)
-
-/*
- * UTHR, ATHR, LTHR, PREFILL, NSAMPLE (0x16 - 0x1F)
- * 13-bit values
-*/
-#define DAC33_THRREG(x) (((x) & 0x1FFF) << 3)
-
-/* DAC33_FIFO_IRQ_MASK (0x29) */
-#define DAC33_MNS (0x01 << 0)
-#define DAC33_MPS (0x01 << 1)
-#define DAC33_MAT (0x01 << 2)
-#define DAC33_MLT (0x01 << 3)
-#define DAC33_MUT (0x01 << 4)
-#define DAC33_MUF (0x01 << 5)
-#define DAC33_MOF (0x01 << 6)
-
-#define DAC33_FIFO_IRQ_MODE_MASK (0x03)
-#define DAC33_FIFO_IRQ_MODE_RISING (0x00)
-#define DAC33_FIFO_IRQ_MODE_FALLING (0x01)
-#define DAC33_FIFO_IRQ_MODE_LEVEL (0x02)
-#define DAC33_FIFO_IRQ_MODE_EDGE (0x03)
-
-/* DAC33_FIFO_IRQ_MODE_A (0x2A) */
-#define DAC33_UTM(x) (x << 0)
-#define DAC33_UFM(x) (x << 2)
-#define DAC33_OFM(x) (x << 4)
-
-/* DAC33_FIFO_IRQ_MODE_B (0x2B) */
-#define DAC33_NSM(x) (x << 0)
-#define DAC33_PSM(x) (x << 2)
-#define DAC33_ATM(x) (x << 4)
-#define DAC33_LTM(x) (x << 6)
-
-/* DAC33_DAC_CTRL_A (0x2C) */
-#define DAC33_DACRATE(x) (x << 0)
-#define DAC33_DACDUAL (0x01 << 4)
-#define DAC33_DACLKSEL_MASK (0x03 << 5)
-#define DAC33_DACLKSEL_INTSOC (0x00 << 5)
-#define DAC33_DACLKSEL_PLL (0x01 << 5)
-#define DAC33_DACLKSEL_MCLK (0x02 << 5)
-#define DAC33_DACLKSEL_BCLK (0x03 << 5)
-
-/* DAC33_DAC_CTRL_B (0x2D) */
-#define DAC33_DACSRCR_MASK (0x03 << 0)
-#define DAC33_DACSRCR_MUTE (0x00 << 0)
-#define DAC33_DACSRCR_RIGHT (0x01 << 0)
-#define DAC33_DACSRCR_LEFT (0x02 << 0)
-#define DAC33_DACSRCR_MONOMIX (0x03 << 0)
-#define DAC33_DACSRCL_MASK (0x03 << 2)
-#define DAC33_DACSRCL_MUTE (0x00 << 2)
-#define DAC33_DACSRCL_LEFT (0x01 << 2)
-#define DAC33_DACSRCL_RIGHT (0x02 << 2)
-#define DAC33_DACSRCL_MONOMIX (0x03 << 2)
-#define DAC33_DVOLSTEP_MASK (0x03 << 4)
-#define DAC33_DVOLSTEP_SS_PERFS (0x00 << 4)
-#define DAC33_DVOLSTEP_SS_PER2FS (0x01 << 4)
-#define DAC33_DVOLSTEP_SS_DISABLED (0x02 << 4)
-#define DAC33_DVOLCTRL_MASK (0x03 << 6)
-#define DAC33_DVOLCTRL_LR_INDEPENDENT1 (0x00 << 6)
-#define DAC33_DVOLCTRL_LR_RIGHT_CONTROL (0x01 << 6)
-#define DAC33_DVOLCTRL_LR_LEFT_CONTROL (0x02 << 6)
-#define DAC33_DVOLCTRL_LR_INDEPENDENT2 (0x03 << 6)
-
-/* DAC33_DAC_CTRL_C (0x2E) */
-#define DAC33_DEEMENR (0x01 << 0)
-#define DAC33_EFFENR (0x01 << 1)
-#define DAC33_DEEMENL (0x01 << 2)
-#define DAC33_EFFENL (0x01 << 3)
-#define DAC33_EN3D (0x01 << 4)
-#define DAC33_RESYNMUTE (0x01 << 5)
-#define DAC33_RESYNEN (0x01 << 6)
-
-/* DAC33_ASRC_CTRL_A (0x32) */
-#define DAC33_SRCBYP (0x01 << 0)
-#define DAC33_SRCLKSEL_MASK (0x03 << 1)
-#define DAC33_SRCLKSEL_INTSOC (0x00 << 1)
-#define DAC33_SRCLKSEL_PLL (0x01 << 1)
-#define DAC33_SRCLKSEL_MCLK (0x02 << 1)
-#define DAC33_SRCLKSEL_BCLK (0x03 << 1)
-#define DAC33_SRCLKDIV(x) (x << 3)
-
-/* DAC33_ASRC_CTRL_B (0x33) */
-#define DAC33_SRCSETUP(x) (x << 0)
-#define DAC33_SRCREFSEL (0x01 << 4)
-#define DAC33_SRCREFDIV(x) (x << 5)
-
-/* DAC33_INTP_CTRL_A (0x38) */
-#define DAC33_INTPSEL (0x01 << 0)
-#define DAC33_INTPM_MASK (0x03 << 1)
-#define DAC33_INTPM_ALOW_OPENDRAIN (0x00 << 1)
-#define DAC33_INTPM_ALOW (0x01 << 1)
-#define DAC33_INTPM_AHIGH (0x02 << 1)
-
-/* DAC33_LDAC_PWR_CTRL (0x40) */
-/* DAC33_RDAC_PWR_CTRL (0x41) */
-#define DAC33_DACLRNUM (0x01 << 2)
-#define DAC33_LROUT_GAIN(x) (x << 0)
-
-/* DAC33_ANA_VOL_SOFT_STEP_CTRL (0x49) */
-#define DAC33_VOLCLKSEL (0x01 << 0)
-#define DAC33_VOLCLKEN (0x01 << 1)
-#define DAC33_VOLBYPASS (0x01 << 2)
-
-#define TLV320DAC33_MCLK 0
-#define TLV320DAC33_SLEEPCLK 1
-
-#endif /* __TLV320DAC33_H */
diff --git a/ANDROID_3.4.5/sound/soc/codecs/tpa6130a2.c b/ANDROID_3.4.5/sound/soc/codecs/tpa6130a2.c
deleted file mode 100644
index 6fe4aa3a..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/tpa6130a2.c
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- * ALSA SoC Texas Instruments TPA6130A2 headset stereo amplifier driver
- *
- * Copyright (C) Nokia Corporation
- *
- * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <linux/gpio.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <sound/tpa6130a2-plat.h>
-#include <sound/soc.h>
-#include <sound/tlv.h>
-
-#include "tpa6130a2.h"
-
-enum tpa_model {
- TPA6130A2,
- TPA6140A2,
-};
-
-static struct i2c_client *tpa6130a2_client;
-
-/* This struct is used to save the context */
-struct tpa6130a2_data {
- struct mutex mutex;
- unsigned char regs[TPA6130A2_CACHEREGNUM];
- struct regulator *supply;
- int power_gpio;
- u8 power_state:1;
- enum tpa_model id;
-};
-
-static int tpa6130a2_i2c_read(int reg)
-{
- struct tpa6130a2_data *data;
- int val;
-
- BUG_ON(tpa6130a2_client == NULL);
- data = i2c_get_clientdata(tpa6130a2_client);
-
- /* If powered off, return the cached value */
- if (data->power_state) {
- val = i2c_smbus_read_byte_data(tpa6130a2_client, reg);
- if (val < 0)
- dev_err(&tpa6130a2_client->dev, "Read failed\n");
- else
- data->regs[reg] = val;
- } else {
- val = data->regs[reg];
- }
-
- return val;
-}
-
-static int tpa6130a2_i2c_write(int reg, u8 value)
-{
- struct tpa6130a2_data *data;
- int val = 0;
-
- BUG_ON(tpa6130a2_client == NULL);
- data = i2c_get_clientdata(tpa6130a2_client);
-
- if (data->power_state) {
- val = i2c_smbus_write_byte_data(tpa6130a2_client, reg, value);
- if (val < 0) {
- dev_err(&tpa6130a2_client->dev, "Write failed\n");
- return val;
- }
- }
-
- /* Either powered on or off, we save the context */
- data->regs[reg] = value;
-
- return val;
-}
-
-static u8 tpa6130a2_read(int reg)
-{
- struct tpa6130a2_data *data;
-
- BUG_ON(tpa6130a2_client == NULL);
- data = i2c_get_clientdata(tpa6130a2_client);
-
- return data->regs[reg];
-}
-
-static int tpa6130a2_initialize(void)
-{
- struct tpa6130a2_data *data;
- int i, ret = 0;
-
- BUG_ON(tpa6130a2_client == NULL);
- data = i2c_get_clientdata(tpa6130a2_client);
-
- for (i = 1; i < TPA6130A2_REG_VERSION; i++) {
- ret = tpa6130a2_i2c_write(i, data->regs[i]);
- if (ret < 0)
- break;
- }
-
- return ret;
-}
-
-static int tpa6130a2_power(u8 power)
-{
- struct tpa6130a2_data *data;
- u8 val;
- int ret = 0;
-
- BUG_ON(tpa6130a2_client == NULL);
- data = i2c_get_clientdata(tpa6130a2_client);
-
- mutex_lock(&data->mutex);
- if (power == data->power_state)
- goto exit;
-
- if (power) {
- ret = regulator_enable(data->supply);
- if (ret != 0) {
- dev_err(&tpa6130a2_client->dev,
- "Failed to enable supply: %d\n", ret);
- goto exit;
- }
- /* Power on */
- if (data->power_gpio >= 0)
- gpio_set_value(data->power_gpio, 1);
-
- data->power_state = 1;
- ret = tpa6130a2_initialize();
- if (ret < 0) {
- dev_err(&tpa6130a2_client->dev,
- "Failed to initialize chip\n");
- if (data->power_gpio >= 0)
- gpio_set_value(data->power_gpio, 0);
- regulator_disable(data->supply);
- data->power_state = 0;
- goto exit;
- }
- } else {
- /* set SWS */
- val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
- val |= TPA6130A2_SWS;
- tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
-
- /* Power off */
- if (data->power_gpio >= 0)
- gpio_set_value(data->power_gpio, 0);
-
- ret = regulator_disable(data->supply);
- if (ret != 0) {
- dev_err(&tpa6130a2_client->dev,
- "Failed to disable supply: %d\n", ret);
- goto exit;
- }
-
- data->power_state = 0;
- }
-
-exit:
- mutex_unlock(&data->mutex);
- return ret;
-}
-
-static int tpa6130a2_get_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct tpa6130a2_data *data;
- unsigned int reg = mc->reg;
- unsigned int shift = mc->shift;
- int max = mc->max;
- unsigned int mask = (1 << fls(max)) - 1;
- unsigned int invert = mc->invert;
-
- BUG_ON(tpa6130a2_client == NULL);
- data = i2c_get_clientdata(tpa6130a2_client);
-
- mutex_lock(&data->mutex);
-
- ucontrol->value.integer.value[0] =
- (tpa6130a2_read(reg) >> shift) & mask;
-
- if (invert)
- ucontrol->value.integer.value[0] =
- max - ucontrol->value.integer.value[0];
-
- mutex_unlock(&data->mutex);
- return 0;
-}
-
-static int tpa6130a2_put_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct tpa6130a2_data *data;
- unsigned int reg = mc->reg;
- unsigned int shift = mc->shift;
- int max = mc->max;
- unsigned int mask = (1 << fls(max)) - 1;
- unsigned int invert = mc->invert;
- unsigned int val = (ucontrol->value.integer.value[0] & mask);
- unsigned int val_reg;
-
- BUG_ON(tpa6130a2_client == NULL);
- data = i2c_get_clientdata(tpa6130a2_client);
-
- if (invert)
- val = max - val;
-
- mutex_lock(&data->mutex);
-
- val_reg = tpa6130a2_read(reg);
- if (((val_reg >> shift) & mask) == val) {
- mutex_unlock(&data->mutex);
- return 0;
- }
-
- val_reg &= ~(mask << shift);
- val_reg |= val << shift;
- tpa6130a2_i2c_write(reg, val_reg);
-
- mutex_unlock(&data->mutex);
-
- return 1;
-}
-
-/*
- * TPA6130 volume. From -59.5 to 4 dB with increasing step size when going
- * down in gain.
- */
-static const unsigned int tpa6130_tlv[] = {
- TLV_DB_RANGE_HEAD(10),
- 0, 1, TLV_DB_SCALE_ITEM(-5950, 600, 0),
- 2, 3, TLV_DB_SCALE_ITEM(-5000, 250, 0),
- 4, 5, TLV_DB_SCALE_ITEM(-4550, 160, 0),
- 6, 7, TLV_DB_SCALE_ITEM(-4140, 190, 0),
- 8, 9, TLV_DB_SCALE_ITEM(-3650, 120, 0),
- 10, 11, TLV_DB_SCALE_ITEM(-3330, 160, 0),
- 12, 13, TLV_DB_SCALE_ITEM(-3040, 180, 0),
- 14, 20, TLV_DB_SCALE_ITEM(-2710, 110, 0),
- 21, 37, TLV_DB_SCALE_ITEM(-1960, 74, 0),
- 38, 63, TLV_DB_SCALE_ITEM(-720, 45, 0),
-};
-
-static const struct snd_kcontrol_new tpa6130a2_controls[] = {
- SOC_SINGLE_EXT_TLV("TPA6130A2 Headphone Playback Volume",
- TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0,
- tpa6130a2_get_volsw, tpa6130a2_put_volsw,
- tpa6130_tlv),
-};
-
-static const unsigned int tpa6140_tlv[] = {
- TLV_DB_RANGE_HEAD(3),
- 0, 8, TLV_DB_SCALE_ITEM(-5900, 400, 0),
- 9, 16, TLV_DB_SCALE_ITEM(-2500, 200, 0),
- 17, 31, TLV_DB_SCALE_ITEM(-1000, 100, 0),
-};
-
-static const struct snd_kcontrol_new tpa6140a2_controls[] = {
- SOC_SINGLE_EXT_TLV("TPA6140A2 Headphone Playback Volume",
- TPA6130A2_REG_VOL_MUTE, 1, 0x1f, 0,
- tpa6130a2_get_volsw, tpa6130a2_put_volsw,
- tpa6140_tlv),
-};
-
-/*
- * Enable or disable channel (left or right)
- * The bit number for mute and amplifier are the same per channel:
- * bit 6: Right channel
- * bit 7: Left channel
- * in both registers.
- */
-static void tpa6130a2_channel_enable(u8 channel, int enable)
-{
- u8 val;
-
- if (enable) {
- /* Enable channel */
- /* Enable amplifier */
- val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
- val |= channel;
- val &= ~TPA6130A2_SWS;
- tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
-
- /* Unmute channel */
- val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
- val &= ~channel;
- tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
- } else {
- /* Disable channel */
- /* Mute channel */
- val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
- val |= channel;
- tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
-
- /* Disable amplifier */
- val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
- val &= ~channel;
- tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
- }
-}
-
-int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable)
-{
- int ret = 0;
- if (enable) {
- ret = tpa6130a2_power(1);
- if (ret < 0)
- return ret;
- tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L,
- 1);
- } else {
- tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L,
- 0);
- ret = tpa6130a2_power(0);
- }
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(tpa6130a2_stereo_enable);
-
-int tpa6130a2_add_controls(struct snd_soc_codec *codec)
-{
- struct tpa6130a2_data *data;
-
- if (tpa6130a2_client == NULL)
- return -ENODEV;
-
- data = i2c_get_clientdata(tpa6130a2_client);
-
- if (data->id == TPA6140A2)
- return snd_soc_add_codec_controls(codec, tpa6140a2_controls,
- ARRAY_SIZE(tpa6140a2_controls));
- else
- return snd_soc_add_codec_controls(codec, tpa6130a2_controls,
- ARRAY_SIZE(tpa6130a2_controls));
-}
-EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
-
-static int __devinit tpa6130a2_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct device *dev;
- struct tpa6130a2_data *data;
- struct tpa6130a2_platform_data *pdata;
- const char *regulator;
- int ret;
-
- dev = &client->dev;
-
- if (client->dev.platform_data == NULL) {
- dev_err(dev, "Platform data not set\n");
- dump_stack();
- return -ENODEV;
- }
-
- data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
- if (data == NULL) {
- dev_err(dev, "Can not allocate memory\n");
- return -ENOMEM;
- }
-
- tpa6130a2_client = client;
-
- i2c_set_clientdata(tpa6130a2_client, data);
-
- pdata = client->dev.platform_data;
- data->power_gpio = pdata->power_gpio;
- data->id = id->driver_data;
-
- mutex_init(&data->mutex);
-
- /* Set default register values */
- data->regs[TPA6130A2_REG_CONTROL] = TPA6130A2_SWS;
- data->regs[TPA6130A2_REG_VOL_MUTE] = TPA6130A2_MUTE_R |
- TPA6130A2_MUTE_L;
-
- if (data->power_gpio >= 0) {
- ret = gpio_request(data->power_gpio, "tpa6130a2 enable");
- if (ret < 0) {
- dev_err(dev, "Failed to request power GPIO (%d)\n",
- data->power_gpio);
- goto err_gpio;
- }
- gpio_direction_output(data->power_gpio, 0);
- }
-
- switch (data->id) {
- default:
- dev_warn(dev, "Unknown TPA model (%d). Assuming 6130A2\n",
- data->id);
- case TPA6130A2:
- regulator = "Vdd";
- break;
- case TPA6140A2:
- regulator = "AVdd";
- break;
- }
-
- data->supply = regulator_get(dev, regulator);
- if (IS_ERR(data->supply)) {
- ret = PTR_ERR(data->supply);
- dev_err(dev, "Failed to request supply: %d\n", ret);
- goto err_regulator;
- }
-
- ret = tpa6130a2_power(1);
- if (ret != 0)
- goto err_power;
-
-
- /* Read version */
- ret = tpa6130a2_i2c_read(TPA6130A2_REG_VERSION) &
- TPA6130A2_VERSION_MASK;
- if ((ret != 1) && (ret != 2))
- dev_warn(dev, "UNTESTED version detected (%d)\n", ret);
-
- /* Disable the chip */
- ret = tpa6130a2_power(0);
- if (ret != 0)
- goto err_power;
-
- return 0;
-
-err_power:
- regulator_put(data->supply);
-err_regulator:
- if (data->power_gpio >= 0)
- gpio_free(data->power_gpio);
-err_gpio:
- tpa6130a2_client = NULL;
-
- return ret;
-}
-
-static int __devexit tpa6130a2_remove(struct i2c_client *client)
-{
- struct tpa6130a2_data *data = i2c_get_clientdata(client);
-
- tpa6130a2_power(0);
-
- if (data->power_gpio >= 0)
- gpio_free(data->power_gpio);
-
- regulator_put(data->supply);
- tpa6130a2_client = NULL;
-
- return 0;
-}
-
-static const struct i2c_device_id tpa6130a2_id[] = {
- { "tpa6130a2", TPA6130A2 },
- { "tpa6140a2", TPA6140A2 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, tpa6130a2_id);
-
-static struct i2c_driver tpa6130a2_i2c_driver = {
- .driver = {
- .name = "tpa6130a2",
- .owner = THIS_MODULE,
- },
- .probe = tpa6130a2_probe,
- .remove = __devexit_p(tpa6130a2_remove),
- .id_table = tpa6130a2_id,
-};
-
-static int __init tpa6130a2_init(void)
-{
- return i2c_add_driver(&tpa6130a2_i2c_driver);
-}
-
-static void __exit tpa6130a2_exit(void)
-{
- i2c_del_driver(&tpa6130a2_i2c_driver);
-}
-
-MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
-MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver");
-MODULE_LICENSE("GPL");
-
-module_init(tpa6130a2_init);
-module_exit(tpa6130a2_exit);
diff --git a/ANDROID_3.4.5/sound/soc/codecs/tpa6130a2.h b/ANDROID_3.4.5/sound/soc/codecs/tpa6130a2.h
deleted file mode 100644
index 41744402..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/tpa6130a2.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * ALSA SoC TPA6130A2 amplifier driver
- *
- * Copyright (C) Nokia Corporation
- *
- * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __TPA6130A2_H__
-#define __TPA6130A2_H__
-
-/* Register addresses */
-#define TPA6130A2_REG_CONTROL 0x01
-#define TPA6130A2_REG_VOL_MUTE 0x02
-#define TPA6130A2_REG_OUT_IMPEDANCE 0x03
-#define TPA6130A2_REG_VERSION 0x04
-
-#define TPA6130A2_CACHEREGNUM (TPA6130A2_REG_VERSION + 1)
-
-/* Register bits */
-/* TPA6130A2_REG_CONTROL (0x01) */
-#define TPA6130A2_SWS (0x01 << 0)
-#define TPA6130A2_TERMAL (0x01 << 1)
-#define TPA6130A2_MODE(x) (x << 4)
-#define TPA6130A2_MODE_STEREO (0x00)
-#define TPA6130A2_MODE_DUAL_MONO (0x01)
-#define TPA6130A2_MODE_BRIDGE (0x02)
-#define TPA6130A2_MODE_MASK (0x03)
-#define TPA6130A2_HP_EN_R (0x01 << 6)
-#define TPA6130A2_HP_EN_L (0x01 << 7)
-
-/* TPA6130A2_REG_VOL_MUTE (0x02) */
-#define TPA6130A2_VOLUME(x) ((x & 0x3f) << 0)
-#define TPA6130A2_MUTE_R (0x01 << 6)
-#define TPA6130A2_MUTE_L (0x01 << 7)
-
-/* TPA6130A2_REG_OUT_IMPEDANCE (0x03) */
-#define TPA6130A2_HIZ_R (0x01 << 0)
-#define TPA6130A2_HIZ_L (0x01 << 1)
-
-/* TPA6130A2_REG_VERSION (0x04) */
-#define TPA6130A2_VERSION_MASK (0x0f)
-
-extern int tpa6130a2_add_controls(struct snd_soc_codec *codec);
-extern int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable);
-
-#endif /* __TPA6130A2_H__ */
diff --git a/ANDROID_3.4.5/sound/soc/codecs/twl4030.c b/ANDROID_3.4.5/sound/soc/codecs/twl4030.c
deleted file mode 100644
index 170cf9a8..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/twl4030.c
+++ /dev/null
@@ -1,2303 +0,0 @@
-/*
- * ALSA SoC TWL4030 codec driver
- *
- * Author: Steve Sakoman, <steve@sakoman.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/platform_device.h>
-#include <linux/i2c/twl.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-/* Register descriptions are here */
-#include <linux/mfd/twl4030-audio.h>
-
-/* Shadow register used by the audio driver */
-#define TWL4030_REG_SW_SHADOW 0x4A
-#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
-
-/* TWL4030_REG_SW_SHADOW (0x4A) Fields */
-#define TWL4030_HFL_EN 0x01
-#define TWL4030_HFR_EN 0x02
-
-/*
- * twl4030 register cache & default register settings
- */
-static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
- 0x00, /* this register not used */
- 0x00, /* REG_CODEC_MODE (0x1) */
- 0x00, /* REG_OPTION (0x2) */
- 0x00, /* REG_UNKNOWN (0x3) */
- 0x00, /* REG_MICBIAS_CTL (0x4) */
- 0x00, /* REG_ANAMICL (0x5) */
- 0x00, /* REG_ANAMICR (0x6) */
- 0x00, /* REG_AVADC_CTL (0x7) */
- 0x00, /* REG_ADCMICSEL (0x8) */
- 0x00, /* REG_DIGMIXING (0x9) */
- 0x0f, /* REG_ATXL1PGA (0xA) */
- 0x0f, /* REG_ATXR1PGA (0xB) */
- 0x0f, /* REG_AVTXL2PGA (0xC) */
- 0x0f, /* REG_AVTXR2PGA (0xD) */
- 0x00, /* REG_AUDIO_IF (0xE) */
- 0x00, /* REG_VOICE_IF (0xF) */
- 0x3f, /* REG_ARXR1PGA (0x10) */
- 0x3f, /* REG_ARXL1PGA (0x11) */
- 0x3f, /* REG_ARXR2PGA (0x12) */
- 0x3f, /* REG_ARXL2PGA (0x13) */
- 0x25, /* REG_VRXPGA (0x14) */
- 0x00, /* REG_VSTPGA (0x15) */
- 0x00, /* REG_VRX2ARXPGA (0x16) */
- 0x00, /* REG_AVDAC_CTL (0x17) */
- 0x00, /* REG_ARX2VTXPGA (0x18) */
- 0x32, /* REG_ARXL1_APGA_CTL (0x19) */
- 0x32, /* REG_ARXR1_APGA_CTL (0x1A) */
- 0x32, /* REG_ARXL2_APGA_CTL (0x1B) */
- 0x32, /* REG_ARXR2_APGA_CTL (0x1C) */
- 0x00, /* REG_ATX2ARXPGA (0x1D) */
- 0x00, /* REG_BT_IF (0x1E) */
- 0x55, /* REG_BTPGA (0x1F) */
- 0x00, /* REG_BTSTPGA (0x20) */
- 0x00, /* REG_EAR_CTL (0x21) */
- 0x00, /* REG_HS_SEL (0x22) */
- 0x00, /* REG_HS_GAIN_SET (0x23) */
- 0x00, /* REG_HS_POPN_SET (0x24) */
- 0x00, /* REG_PREDL_CTL (0x25) */
- 0x00, /* REG_PREDR_CTL (0x26) */
- 0x00, /* REG_PRECKL_CTL (0x27) */
- 0x00, /* REG_PRECKR_CTL (0x28) */
- 0x00, /* REG_HFL_CTL (0x29) */
- 0x00, /* REG_HFR_CTL (0x2A) */
- 0x05, /* REG_ALC_CTL (0x2B) */
- 0x00, /* REG_ALC_SET1 (0x2C) */
- 0x00, /* REG_ALC_SET2 (0x2D) */
- 0x00, /* REG_BOOST_CTL (0x2E) */
- 0x00, /* REG_SOFTVOL_CTL (0x2F) */
- 0x13, /* REG_DTMF_FREQSEL (0x30) */
- 0x00, /* REG_DTMF_TONEXT1H (0x31) */
- 0x00, /* REG_DTMF_TONEXT1L (0x32) */
- 0x00, /* REG_DTMF_TONEXT2H (0x33) */
- 0x00, /* REG_DTMF_TONEXT2L (0x34) */
- 0x79, /* REG_DTMF_TONOFF (0x35) */
- 0x11, /* REG_DTMF_WANONOFF (0x36) */
- 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */
- 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */
- 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */
- 0x06, /* REG_APLL_CTL (0x3A) */
- 0x00, /* REG_DTMF_CTL (0x3B) */
- 0x44, /* REG_DTMF_PGA_CTL2 (0x3C) */
- 0x69, /* REG_DTMF_PGA_CTL1 (0x3D) */
- 0x00, /* REG_MISC_SET_1 (0x3E) */
- 0x00, /* REG_PCMBTMUX (0x3F) */
- 0x00, /* not used (0x40) */
- 0x00, /* not used (0x41) */
- 0x00, /* not used (0x42) */
- 0x00, /* REG_RX_PATH_SEL (0x43) */
- 0x32, /* REG_VDL_APGA_CTL (0x44) */
- 0x00, /* REG_VIBRA_CTL (0x45) */
- 0x00, /* REG_VIBRA_SET (0x46) */
- 0x00, /* REG_VIBRA_PWM_SET (0x47) */
- 0x00, /* REG_ANAMIC_GAIN (0x48) */
- 0x00, /* REG_MISC_SET_2 (0x49) */
- 0x00, /* REG_SW_SHADOW (0x4A) - Shadow, non HW register */
-};
-
-/* codec private data */
-struct twl4030_priv {
- struct snd_soc_codec codec;
-
- unsigned int codec_powered;
-
- /* reference counts of AIF/APLL users */
- unsigned int apll_enabled;
-
- struct snd_pcm_substream *master_substream;
- struct snd_pcm_substream *slave_substream;
-
- unsigned int configured;
- unsigned int rate;
- unsigned int sample_bits;
- unsigned int channels;
-
- unsigned int sysclk;
-
- /* Output (with associated amp) states */
- u8 hsl_enabled, hsr_enabled;
- u8 earpiece_enabled;
- u8 predrivel_enabled, predriver_enabled;
- u8 carkitl_enabled, carkitr_enabled;
-
- /* Delay needed after enabling the digimic interface */
- unsigned int digimic_delay;
-};
-
-/*
- * read twl4030 register cache
- */
-static inline unsigned int twl4030_read_reg_cache(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- u8 *cache = codec->reg_cache;
-
- if (reg >= TWL4030_CACHEREGNUM)
- return -EIO;
-
- return cache[reg];
-}
-
-/*
- * write twl4030 register cache
- */
-static inline void twl4030_write_reg_cache(struct snd_soc_codec *codec,
- u8 reg, u8 value)
-{
- u8 *cache = codec->reg_cache;
-
- if (reg >= TWL4030_CACHEREGNUM)
- return;
- cache[reg] = value;
-}
-
-/*
- * write to the twl4030 register space
- */
-static int twl4030_write(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int value)
-{
- struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
- int write_to_reg = 0;
-
- twl4030_write_reg_cache(codec, reg, value);
- if (likely(reg < TWL4030_REG_SW_SHADOW)) {
- /* Decide if the given register can be written */
- switch (reg) {
- case TWL4030_REG_EAR_CTL:
- if (twl4030->earpiece_enabled)
- write_to_reg = 1;
- break;
- case TWL4030_REG_PREDL_CTL:
- if (twl4030->predrivel_enabled)
- write_to_reg = 1;
- break;
- case TWL4030_REG_PREDR_CTL:
- if (twl4030->predriver_enabled)
- write_to_reg = 1;
- break;
- case TWL4030_REG_PRECKL_CTL:
- if (twl4030->carkitl_enabled)
- write_to_reg = 1;
- break;
- case TWL4030_REG_PRECKR_CTL:
- if (twl4030->carkitr_enabled)
- write_to_reg = 1;
- break;
- case TWL4030_REG_HS_GAIN_SET:
- if (twl4030->hsl_enabled || twl4030->hsr_enabled)
- write_to_reg = 1;
- break;
- default:
- /* All other register can be written */
- write_to_reg = 1;
- break;
- }
- if (write_to_reg)
- return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
- value, reg);
- }
- return 0;
-}
-
-static inline void twl4030_wait_ms(int time)
-{
- if (time < 60) {
- time *= 1000;
- usleep_range(time, time + 500);
- } else {
- msleep(time);
- }
-}
-
-static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
-{
- struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
- int mode;
-
- if (enable == twl4030->codec_powered)
- return;
-
- if (enable)
- mode = twl4030_audio_enable_resource(TWL4030_AUDIO_RES_POWER);
- else
- mode = twl4030_audio_disable_resource(TWL4030_AUDIO_RES_POWER);
-
- if (mode >= 0) {
- twl4030_write_reg_cache(codec, TWL4030_REG_CODEC_MODE, mode);
- twl4030->codec_powered = enable;
- }
-
- /* REVISIT: this delay is present in TI sample drivers */
- /* but there seems to be no TRM requirement for it */
- udelay(10);
-}
-
-static inline void twl4030_check_defaults(struct snd_soc_codec *codec)
-{
- int i, difference = 0;
- u8 val;
-
- dev_dbg(codec->dev, "Checking TWL audio default configuration\n");
- for (i = 1; i <= TWL4030_REG_MISC_SET_2; i++) {
- twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val, i);
- if (val != twl4030_reg[i]) {
- difference++;
- dev_dbg(codec->dev,
- "Reg 0x%02x: chip: 0x%02x driver: 0x%02x\n",
- i, val, twl4030_reg[i]);
- }
- }
- dev_dbg(codec->dev, "Found %d non-matching registers. %s\n",
- difference, difference ? "Not OK" : "OK");
-}
-
-static inline void twl4030_reset_registers(struct snd_soc_codec *codec)
-{
- int i;
-
- /* set all audio section registers to reasonable defaults */
- for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++)
- if (i != TWL4030_REG_APLL_CTL)
- twl4030_write(codec, i, twl4030_reg[i]);
-
-}
-
-static void twl4030_init_chip(struct snd_soc_codec *codec)
-{
- struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev);
- struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
- u8 reg, byte;
- int i = 0;
-
- /* Check defaults, if instructed before anything else */
- if (pdata && pdata->check_defaults)
- twl4030_check_defaults(codec);
-
- /* Reset registers, if no setup data or if instructed to do so */
- if (!pdata || (pdata && pdata->reset_registers))
- twl4030_reset_registers(codec);
-
- /* Refresh APLL_CTL register from HW */
- twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
- TWL4030_REG_APLL_CTL);
- twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, byte);
-
- /* anti-pop when changing analog gain */
- reg = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1);
- twl4030_write(codec, TWL4030_REG_MISC_SET_1,
- reg | TWL4030_SMOOTH_ANAVOL_EN);
-
- twl4030_write(codec, TWL4030_REG_OPTION,
- TWL4030_ATXL1_EN | TWL4030_ATXR1_EN |
- TWL4030_ARXL2_EN | TWL4030_ARXR2_EN);
-
- /* REG_ARXR2_APGA_CTL reset according to the TRM: 0dB, DA_EN */
- twl4030_write(codec, TWL4030_REG_ARXR2_APGA_CTL, 0x32);
-
- /* Machine dependent setup */
- if (!pdata)
- return;
-
- twl4030->digimic_delay = pdata->digimic_delay;
-
- reg = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
- reg &= ~TWL4030_RAMP_DELAY;
- reg |= (pdata->ramp_delay_value << 2);
- twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, reg);
-
- /* initiate offset cancellation */
- twl4030_codec_enable(codec, 1);
-
- reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
- reg &= ~TWL4030_OFFSET_CNCL_SEL;
- reg |= pdata->offset_cncl_path;
- twl4030_write(codec, TWL4030_REG_ANAMICL,
- reg | TWL4030_CNCL_OFFSET_START);
-
- /*
- * Wait for offset cancellation to complete.
- * Since this takes a while, do not slam the i2c.
- * Start polling the status after ~20ms.
- */
- msleep(20);
- do {
- usleep_range(1000, 2000);
- twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
- TWL4030_REG_ANAMICL);
- } while ((i++ < 100) &&
- ((byte & TWL4030_CNCL_OFFSET_START) ==
- TWL4030_CNCL_OFFSET_START));
-
- /* Make sure that the reg_cache has the same value as the HW */
- twl4030_write_reg_cache(codec, TWL4030_REG_ANAMICL, byte);
-
- twl4030_codec_enable(codec, 0);
-}
-
-static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable)
-{
- struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
- int status = -1;
-
- if (enable) {
- twl4030->apll_enabled++;
- if (twl4030->apll_enabled == 1)
- status = twl4030_audio_enable_resource(
- TWL4030_AUDIO_RES_APLL);
- } else {
- twl4030->apll_enabled--;
- if (!twl4030->apll_enabled)
- status = twl4030_audio_disable_resource(
- TWL4030_AUDIO_RES_APLL);
- }
-
- if (status >= 0)
- twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status);
-}
-
-/* Earpiece */
-static const struct snd_kcontrol_new twl4030_dapm_earpiece_controls[] = {
- SOC_DAPM_SINGLE("Voice", TWL4030_REG_EAR_CTL, 0, 1, 0),
- SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_EAR_CTL, 1, 1, 0),
- SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_EAR_CTL, 2, 1, 0),
- SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_EAR_CTL, 3, 1, 0),
-};
-
-/* PreDrive Left */
-static const struct snd_kcontrol_new twl4030_dapm_predrivel_controls[] = {
- SOC_DAPM_SINGLE("Voice", TWL4030_REG_PREDL_CTL, 0, 1, 0),
- SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_PREDL_CTL, 1, 1, 0),
- SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PREDL_CTL, 2, 1, 0),
- SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PREDL_CTL, 3, 1, 0),
-};
-
-/* PreDrive Right */
-static const struct snd_kcontrol_new twl4030_dapm_predriver_controls[] = {
- SOC_DAPM_SINGLE("Voice", TWL4030_REG_PREDR_CTL, 0, 1, 0),
- SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_PREDR_CTL, 1, 1, 0),
- SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PREDR_CTL, 2, 1, 0),
- SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PREDR_CTL, 3, 1, 0),
-};
-
-/* Headset Left */
-static const struct snd_kcontrol_new twl4030_dapm_hsol_controls[] = {
- SOC_DAPM_SINGLE("Voice", TWL4030_REG_HS_SEL, 0, 1, 0),
- SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_HS_SEL, 1, 1, 0),
- SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_HS_SEL, 2, 1, 0),
-};
-
-/* Headset Right */
-static const struct snd_kcontrol_new twl4030_dapm_hsor_controls[] = {
- SOC_DAPM_SINGLE("Voice", TWL4030_REG_HS_SEL, 3, 1, 0),
- SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_HS_SEL, 4, 1, 0),
- SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_HS_SEL, 5, 1, 0),
-};
-
-/* Carkit Left */
-static const struct snd_kcontrol_new twl4030_dapm_carkitl_controls[] = {
- SOC_DAPM_SINGLE("Voice", TWL4030_REG_PRECKL_CTL, 0, 1, 0),
- SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_PRECKL_CTL, 1, 1, 0),
- SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PRECKL_CTL, 2, 1, 0),
-};
-
-/* Carkit Right */
-static const struct snd_kcontrol_new twl4030_dapm_carkitr_controls[] = {
- SOC_DAPM_SINGLE("Voice", TWL4030_REG_PRECKR_CTL, 0, 1, 0),
- SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_PRECKR_CTL, 1, 1, 0),
- SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PRECKR_CTL, 2, 1, 0),
-};
-
-/* Handsfree Left */
-static const char *twl4030_handsfreel_texts[] =
- {"Voice", "AudioL1", "AudioL2", "AudioR2"};
-
-static const struct soc_enum twl4030_handsfreel_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_HFL_CTL, 0,
- ARRAY_SIZE(twl4030_handsfreel_texts),
- twl4030_handsfreel_texts);
-
-static const struct snd_kcontrol_new twl4030_dapm_handsfreel_control =
-SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum);
-
-/* Handsfree Left virtual mute */
-static const struct snd_kcontrol_new twl4030_dapm_handsfreelmute_control =
- SOC_DAPM_SINGLE("Switch", TWL4030_REG_SW_SHADOW, 0, 1, 0);
-
-/* Handsfree Right */
-static const char *twl4030_handsfreer_texts[] =
- {"Voice", "AudioR1", "AudioR2", "AudioL2"};
-
-static const struct soc_enum twl4030_handsfreer_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_HFR_CTL, 0,
- ARRAY_SIZE(twl4030_handsfreer_texts),
- twl4030_handsfreer_texts);
-
-static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control =
-SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum);
-
-/* Handsfree Right virtual mute */
-static const struct snd_kcontrol_new twl4030_dapm_handsfreermute_control =
- SOC_DAPM_SINGLE("Switch", TWL4030_REG_SW_SHADOW, 1, 1, 0);
-
-/* Vibra */
-/* Vibra audio path selection */
-static const char *twl4030_vibra_texts[] =
- {"AudioL1", "AudioR1", "AudioL2", "AudioR2"};
-
-static const struct soc_enum twl4030_vibra_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 2,
- ARRAY_SIZE(twl4030_vibra_texts),
- twl4030_vibra_texts);
-
-static const struct snd_kcontrol_new twl4030_dapm_vibra_control =
-SOC_DAPM_ENUM("Route", twl4030_vibra_enum);
-
-/* Vibra path selection: local vibrator (PWM) or audio driven */
-static const char *twl4030_vibrapath_texts[] =
- {"Local vibrator", "Audio"};
-
-static const struct soc_enum twl4030_vibrapath_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 4,
- ARRAY_SIZE(twl4030_vibrapath_texts),
- twl4030_vibrapath_texts);
-
-static const struct snd_kcontrol_new twl4030_dapm_vibrapath_control =
-SOC_DAPM_ENUM("Route", twl4030_vibrapath_enum);
-
-/* Left analog microphone selection */
-static const struct snd_kcontrol_new twl4030_dapm_analoglmic_controls[] = {
- SOC_DAPM_SINGLE("Main Mic Capture Switch",
- TWL4030_REG_ANAMICL, 0, 1, 0),
- SOC_DAPM_SINGLE("Headset Mic Capture Switch",
- TWL4030_REG_ANAMICL, 1, 1, 0),
- SOC_DAPM_SINGLE("AUXL Capture Switch",
- TWL4030_REG_ANAMICL, 2, 1, 0),
- SOC_DAPM_SINGLE("Carkit Mic Capture Switch",
- TWL4030_REG_ANAMICL, 3, 1, 0),
-};
-
-/* Right analog microphone selection */
-static const struct snd_kcontrol_new twl4030_dapm_analogrmic_controls[] = {
- SOC_DAPM_SINGLE("Sub Mic Capture Switch", TWL4030_REG_ANAMICR, 0, 1, 0),
- SOC_DAPM_SINGLE("AUXR Capture Switch", TWL4030_REG_ANAMICR, 2, 1, 0),
-};
-
-/* TX1 L/R Analog/Digital microphone selection */
-static const char *twl4030_micpathtx1_texts[] =
- {"Analog", "Digimic0"};
-
-static const struct soc_enum twl4030_micpathtx1_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_ADCMICSEL, 0,
- ARRAY_SIZE(twl4030_micpathtx1_texts),
- twl4030_micpathtx1_texts);
-
-static const struct snd_kcontrol_new twl4030_dapm_micpathtx1_control =
-SOC_DAPM_ENUM("Route", twl4030_micpathtx1_enum);
-
-/* TX2 L/R Analog/Digital microphone selection */
-static const char *twl4030_micpathtx2_texts[] =
- {"Analog", "Digimic1"};
-
-static const struct soc_enum twl4030_micpathtx2_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_ADCMICSEL, 2,
- ARRAY_SIZE(twl4030_micpathtx2_texts),
- twl4030_micpathtx2_texts);
-
-static const struct snd_kcontrol_new twl4030_dapm_micpathtx2_control =
-SOC_DAPM_ENUM("Route", twl4030_micpathtx2_enum);
-
-/* Analog bypass for AudioR1 */
-static const struct snd_kcontrol_new twl4030_dapm_abypassr1_control =
- SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXR1_APGA_CTL, 2, 1, 0);
-
-/* Analog bypass for AudioL1 */
-static const struct snd_kcontrol_new twl4030_dapm_abypassl1_control =
- SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL1_APGA_CTL, 2, 1, 0);
-
-/* Analog bypass for AudioR2 */
-static const struct snd_kcontrol_new twl4030_dapm_abypassr2_control =
- SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXR2_APGA_CTL, 2, 1, 0);
-
-/* Analog bypass for AudioL2 */
-static const struct snd_kcontrol_new twl4030_dapm_abypassl2_control =
- SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL2_APGA_CTL, 2, 1, 0);
-
-/* Analog bypass for Voice */
-static const struct snd_kcontrol_new twl4030_dapm_abypassv_control =
- SOC_DAPM_SINGLE("Switch", TWL4030_REG_VDL_APGA_CTL, 2, 1, 0);
-
-/* Digital bypass gain, mute instead of -30dB */
-static const unsigned int twl4030_dapm_dbypass_tlv[] = {
- TLV_DB_RANGE_HEAD(3),
- 0, 1, TLV_DB_SCALE_ITEM(-3000, 600, 1),
- 2, 3, TLV_DB_SCALE_ITEM(-2400, 0, 0),
- 4, 7, TLV_DB_SCALE_ITEM(-1800, 600, 0),
-};
-
-/* Digital bypass left (TX1L -> RX2L) */
-static const struct snd_kcontrol_new twl4030_dapm_dbypassl_control =
- SOC_DAPM_SINGLE_TLV("Volume",
- TWL4030_REG_ATX2ARXPGA, 3, 7, 0,
- twl4030_dapm_dbypass_tlv);
-
-/* Digital bypass right (TX1R -> RX2R) */
-static const struct snd_kcontrol_new twl4030_dapm_dbypassr_control =
- SOC_DAPM_SINGLE_TLV("Volume",
- TWL4030_REG_ATX2ARXPGA, 0, 7, 0,
- twl4030_dapm_dbypass_tlv);
-
-/*
- * Voice Sidetone GAIN volume control:
- * from -51 to -10 dB in 1 dB steps (mute instead of -51 dB)
- */
-static DECLARE_TLV_DB_SCALE(twl4030_dapm_dbypassv_tlv, -5100, 100, 1);
-
-/* Digital bypass voice: sidetone (VUL -> VDL)*/
-static const struct snd_kcontrol_new twl4030_dapm_dbypassv_control =
- SOC_DAPM_SINGLE_TLV("Volume",
- TWL4030_REG_VSTPGA, 0, 0x29, 0,
- twl4030_dapm_dbypassv_tlv);
-
-/*
- * Output PGA builder:
- * Handle the muting and unmuting of the given output (turning off the
- * amplifier associated with the output pin)
- * On mute bypass the reg_cache and write 0 to the register
- * On unmute: restore the register content from the reg_cache
- * Outputs handled in this way: Earpiece, PreDrivL/R, CarkitL/R
- */
-#define TWL4030_OUTPUT_PGA(pin_name, reg, mask) \
-static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \
- struct snd_kcontrol *kcontrol, int event) \
-{ \
- struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); \
- \
- switch (event) { \
- case SND_SOC_DAPM_POST_PMU: \
- twl4030->pin_name##_enabled = 1; \
- twl4030_write(w->codec, reg, \
- twl4030_read_reg_cache(w->codec, reg)); \
- break; \
- case SND_SOC_DAPM_POST_PMD: \
- twl4030->pin_name##_enabled = 0; \
- twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \
- 0, reg); \
- break; \
- } \
- return 0; \
-}
-
-TWL4030_OUTPUT_PGA(earpiece, TWL4030_REG_EAR_CTL, TWL4030_EAR_GAIN);
-TWL4030_OUTPUT_PGA(predrivel, TWL4030_REG_PREDL_CTL, TWL4030_PREDL_GAIN);
-TWL4030_OUTPUT_PGA(predriver, TWL4030_REG_PREDR_CTL, TWL4030_PREDR_GAIN);
-TWL4030_OUTPUT_PGA(carkitl, TWL4030_REG_PRECKL_CTL, TWL4030_PRECKL_GAIN);
-TWL4030_OUTPUT_PGA(carkitr, TWL4030_REG_PRECKR_CTL, TWL4030_PRECKR_GAIN);
-
-static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp)
-{
- unsigned char hs_ctl;
-
- hs_ctl = twl4030_read_reg_cache(codec, reg);
-
- if (ramp) {
- /* HF ramp-up */
- hs_ctl |= TWL4030_HF_CTL_REF_EN;
- twl4030_write(codec, reg, hs_ctl);
- udelay(10);
- hs_ctl |= TWL4030_HF_CTL_RAMP_EN;
- twl4030_write(codec, reg, hs_ctl);
- udelay(40);
- hs_ctl |= TWL4030_HF_CTL_LOOP_EN;
- hs_ctl |= TWL4030_HF_CTL_HB_EN;
- twl4030_write(codec, reg, hs_ctl);
- } else {
- /* HF ramp-down */
- hs_ctl &= ~TWL4030_HF_CTL_LOOP_EN;
- hs_ctl &= ~TWL4030_HF_CTL_HB_EN;
- twl4030_write(codec, reg, hs_ctl);
- hs_ctl &= ~TWL4030_HF_CTL_RAMP_EN;
- twl4030_write(codec, reg, hs_ctl);
- udelay(40);
- hs_ctl &= ~TWL4030_HF_CTL_REF_EN;
- twl4030_write(codec, reg, hs_ctl);
- }
-}
-
-static int handsfreelpga_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- handsfree_ramp(w->codec, TWL4030_REG_HFL_CTL, 1);
- break;
- case SND_SOC_DAPM_POST_PMD:
- handsfree_ramp(w->codec, TWL4030_REG_HFL_CTL, 0);
- break;
- }
- return 0;
-}
-
-static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- handsfree_ramp(w->codec, TWL4030_REG_HFR_CTL, 1);
- break;
- case SND_SOC_DAPM_POST_PMD:
- handsfree_ramp(w->codec, TWL4030_REG_HFR_CTL, 0);
- break;
- }
- return 0;
-}
-
-static int vibramux_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- twl4030_write(w->codec, TWL4030_REG_VIBRA_SET, 0xff);
- return 0;
-}
-
-static int apll_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- twl4030_apll_enable(w->codec, 1);
- break;
- case SND_SOC_DAPM_POST_PMD:
- twl4030_apll_enable(w->codec, 0);
- break;
- }
- return 0;
-}
-
-static int aif_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- u8 audio_if;
-
- audio_if = twl4030_read_reg_cache(w->codec, TWL4030_REG_AUDIO_IF);
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- /* Enable AIF */
- /* enable the PLL before we use it to clock the DAI */
- twl4030_apll_enable(w->codec, 1);
-
- twl4030_write(w->codec, TWL4030_REG_AUDIO_IF,
- audio_if | TWL4030_AIF_EN);
- break;
- case SND_SOC_DAPM_POST_PMD:
- /* disable the DAI before we stop it's source PLL */
- twl4030_write(w->codec, TWL4030_REG_AUDIO_IF,
- audio_if & ~TWL4030_AIF_EN);
- twl4030_apll_enable(w->codec, 0);
- break;
- }
- return 0;
-}
-
-static void headset_ramp(struct snd_soc_codec *codec, int ramp)
-{
- struct twl4030_codec_data *pdata = codec->dev->platform_data;
- unsigned char hs_gain, hs_pop;
- struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
- /* Base values for ramp delay calculation: 2^19 - 2^26 */
- unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304,
- 8388608, 16777216, 33554432, 67108864};
- unsigned int delay;
-
- hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET);
- hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
- delay = (ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
- twl4030->sysclk) + 1;
-
- /* Enable external mute control, this dramatically reduces
- * the pop-noise */
- if (pdata && pdata->hs_extmute) {
- if (pdata->set_hs_extmute) {
- pdata->set_hs_extmute(1);
- } else {
- hs_pop |= TWL4030_EXTMUTE;
- twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
- }
- }
-
- if (ramp) {
- /* Headset ramp-up according to the TRM */
- hs_pop |= TWL4030_VMID_EN;
- twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
- /* Actually write to the register */
- twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
- hs_gain,
- TWL4030_REG_HS_GAIN_SET);
- hs_pop |= TWL4030_RAMP_EN;
- twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
- /* Wait ramp delay time + 1, so the VMID can settle */
- twl4030_wait_ms(delay);
- } else {
- /* Headset ramp-down _not_ according to
- * the TRM, but in a way that it is working */
- hs_pop &= ~TWL4030_RAMP_EN;
- twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
- /* Wait ramp delay time + 1, so the VMID can settle */
- twl4030_wait_ms(delay);
- /* Bypass the reg_cache to mute the headset */
- twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
- hs_gain & (~0x0f),
- TWL4030_REG_HS_GAIN_SET);
-
- hs_pop &= ~TWL4030_VMID_EN;
- twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
- }
-
- /* Disable external mute */
- if (pdata && pdata->hs_extmute) {
- if (pdata->set_hs_extmute) {
- pdata->set_hs_extmute(0);
- } else {
- hs_pop &= ~TWL4030_EXTMUTE;
- twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
- }
- }
-}
-
-static int headsetlpga_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- /* Do the ramp-up only once */
- if (!twl4030->hsr_enabled)
- headset_ramp(w->codec, 1);
-
- twl4030->hsl_enabled = 1;
- break;
- case SND_SOC_DAPM_POST_PMD:
- /* Do the ramp-down only if both headsetL/R is disabled */
- if (!twl4030->hsr_enabled)
- headset_ramp(w->codec, 0);
-
- twl4030->hsl_enabled = 0;
- break;
- }
- return 0;
-}
-
-static int headsetrpga_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- /* Do the ramp-up only once */
- if (!twl4030->hsl_enabled)
- headset_ramp(w->codec, 1);
-
- twl4030->hsr_enabled = 1;
- break;
- case SND_SOC_DAPM_POST_PMD:
- /* Do the ramp-down only if both headsetL/R is disabled */
- if (!twl4030->hsl_enabled)
- headset_ramp(w->codec, 0);
-
- twl4030->hsr_enabled = 0;
- break;
- }
- return 0;
-}
-
-static int digimic_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
-
- if (twl4030->digimic_delay)
- twl4030_wait_ms(twl4030->digimic_delay);
- return 0;
-}
-
-/*
- * Some of the gain controls in TWL (mostly those which are associated with
- * the outputs) are implemented in an interesting way:
- * 0x0 : Power down (mute)
- * 0x1 : 6dB
- * 0x2 : 0 dB
- * 0x3 : -6 dB
- * Inverting not going to help with these.
- * Custom volsw and volsw_2r get/put functions to handle these gain bits.
- */
-static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int reg = mc->reg;
- unsigned int shift = mc->shift;
- unsigned int rshift = mc->rshift;
- int max = mc->max;
- int mask = (1 << fls(max)) - 1;
-
- ucontrol->value.integer.value[0] =
- (snd_soc_read(codec, reg) >> shift) & mask;
- if (ucontrol->value.integer.value[0])
- ucontrol->value.integer.value[0] =
- max + 1 - ucontrol->value.integer.value[0];
-
- if (shift != rshift) {
- ucontrol->value.integer.value[1] =
- (snd_soc_read(codec, reg) >> rshift) & mask;
- if (ucontrol->value.integer.value[1])
- ucontrol->value.integer.value[1] =
- max + 1 - ucontrol->value.integer.value[1];
- }
-
- return 0;
-}
-
-static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int reg = mc->reg;
- unsigned int shift = mc->shift;
- unsigned int rshift = mc->rshift;
- int max = mc->max;
- int mask = (1 << fls(max)) - 1;
- unsigned short val, val2, val_mask;
-
- val = (ucontrol->value.integer.value[0] & mask);
-
- val_mask = mask << shift;
- if (val)
- val = max + 1 - val;
- val = val << shift;
- if (shift != rshift) {
- val2 = (ucontrol->value.integer.value[1] & mask);
- val_mask |= mask << rshift;
- if (val2)
- val2 = max + 1 - val2;
- val |= val2 << rshift;
- }
- return snd_soc_update_bits(codec, reg, val_mask, val);
-}
-
-static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int reg = mc->reg;
- unsigned int reg2 = mc->rreg;
- unsigned int shift = mc->shift;
- int max = mc->max;
- int mask = (1<<fls(max))-1;
-
- ucontrol->value.integer.value[0] =
- (snd_soc_read(codec, reg) >> shift) & mask;
- ucontrol->value.integer.value[1] =
- (snd_soc_read(codec, reg2) >> shift) & mask;
-
- if (ucontrol->value.integer.value[0])
- ucontrol->value.integer.value[0] =
- max + 1 - ucontrol->value.integer.value[0];
- if (ucontrol->value.integer.value[1])
- ucontrol->value.integer.value[1] =
- max + 1 - ucontrol->value.integer.value[1];
-
- return 0;
-}
-
-static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int reg = mc->reg;
- unsigned int reg2 = mc->rreg;
- unsigned int shift = mc->shift;
- int max = mc->max;
- int mask = (1 << fls(max)) - 1;
- int err;
- unsigned short val, val2, val_mask;
-
- val_mask = mask << shift;
- val = (ucontrol->value.integer.value[0] & mask);
- val2 = (ucontrol->value.integer.value[1] & mask);
-
- if (val)
- val = max + 1 - val;
- if (val2)
- val2 = max + 1 - val2;
-
- val = val << shift;
- val2 = val2 << shift;
-
- err = snd_soc_update_bits(codec, reg, val_mask, val);
- if (err < 0)
- return err;
-
- err = snd_soc_update_bits(codec, reg2, val_mask, val2);
- return err;
-}
-
-/* Codec operation modes */
-static const char *twl4030_op_modes_texts[] = {
- "Option 2 (voice/audio)", "Option 1 (audio)"
-};
-
-static const struct soc_enum twl4030_op_modes_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_CODEC_MODE, 0,
- ARRAY_SIZE(twl4030_op_modes_texts),
- twl4030_op_modes_texts);
-
-static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned short val;
- unsigned short mask, bitmask;
-
- if (twl4030->configured) {
- dev_err(codec->dev,
- "operation mode cannot be changed on-the-fly\n");
- return -EBUSY;
- }
-
- for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
- ;
- if (ucontrol->value.enumerated.item[0] > e->max - 1)
- return -EINVAL;
-
- val = ucontrol->value.enumerated.item[0] << e->shift_l;
- mask = (bitmask - 1) << e->shift_l;
- if (e->shift_l != e->shift_r) {
- if (ucontrol->value.enumerated.item[1] > e->max - 1)
- return -EINVAL;
- val |= ucontrol->value.enumerated.item[1] << e->shift_r;
- mask |= (bitmask - 1) << e->shift_r;
- }
-
- return snd_soc_update_bits(codec, e->reg, mask, val);
-}
-
-/*
- * FGAIN volume control:
- * from -62 to 0 dB in 1 dB steps (mute instead of -63 dB)
- */
-static DECLARE_TLV_DB_SCALE(digital_fine_tlv, -6300, 100, 1);
-
-/*
- * CGAIN volume control:
- * 0 dB to 12 dB in 6 dB steps
- * value 2 and 3 means 12 dB
- */
-static DECLARE_TLV_DB_SCALE(digital_coarse_tlv, 0, 600, 0);
-
-/*
- * Voice Downlink GAIN volume control:
- * from -37 to 12 dB in 1 dB steps (mute instead of -37 dB)
- */
-static DECLARE_TLV_DB_SCALE(digital_voice_downlink_tlv, -3700, 100, 1);
-
-/*
- * Analog playback gain
- * -24 dB to 12 dB in 2 dB steps
- */
-static DECLARE_TLV_DB_SCALE(analog_tlv, -2400, 200, 0);
-
-/*
- * Gain controls tied to outputs
- * -6 dB to 6 dB in 6 dB steps (mute instead of -12)
- */
-static DECLARE_TLV_DB_SCALE(output_tvl, -1200, 600, 1);
-
-/*
- * Gain control for earpiece amplifier
- * 0 dB to 12 dB in 6 dB steps (mute instead of -6)
- */
-static DECLARE_TLV_DB_SCALE(output_ear_tvl, -600, 600, 1);
-
-/*
- * Capture gain after the ADCs
- * from 0 dB to 31 dB in 1 dB steps
- */
-static DECLARE_TLV_DB_SCALE(digital_capture_tlv, 0, 100, 0);
-
-/*
- * Gain control for input amplifiers
- * 0 dB to 30 dB in 6 dB steps
- */
-static DECLARE_TLV_DB_SCALE(input_gain_tlv, 0, 600, 0);
-
-/* AVADC clock priority */
-static const char *twl4030_avadc_clk_priority_texts[] = {
- "Voice high priority", "HiFi high priority"
-};
-
-static const struct soc_enum twl4030_avadc_clk_priority_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_AVADC_CTL, 2,
- ARRAY_SIZE(twl4030_avadc_clk_priority_texts),
- twl4030_avadc_clk_priority_texts);
-
-static const char *twl4030_rampdelay_texts[] = {
- "27/20/14 ms", "55/40/27 ms", "109/81/55 ms", "218/161/109 ms",
- "437/323/218 ms", "874/645/437 ms", "1748/1291/874 ms",
- "3495/2581/1748 ms"
-};
-
-static const struct soc_enum twl4030_rampdelay_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_HS_POPN_SET, 2,
- ARRAY_SIZE(twl4030_rampdelay_texts),
- twl4030_rampdelay_texts);
-
-/* Vibra H-bridge direction mode */
-static const char *twl4030_vibradirmode_texts[] = {
- "Vibra H-bridge direction", "Audio data MSB",
-};
-
-static const struct soc_enum twl4030_vibradirmode_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 5,
- ARRAY_SIZE(twl4030_vibradirmode_texts),
- twl4030_vibradirmode_texts);
-
-/* Vibra H-bridge direction */
-static const char *twl4030_vibradir_texts[] = {
- "Positive polarity", "Negative polarity",
-};
-
-static const struct soc_enum twl4030_vibradir_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 1,
- ARRAY_SIZE(twl4030_vibradir_texts),
- twl4030_vibradir_texts);
-
-/* Digimic Left and right swapping */
-static const char *twl4030_digimicswap_texts[] = {
- "Not swapped", "Swapped",
-};
-
-static const struct soc_enum twl4030_digimicswap_enum =
- SOC_ENUM_SINGLE(TWL4030_REG_MISC_SET_1, 0,
- ARRAY_SIZE(twl4030_digimicswap_texts),
- twl4030_digimicswap_texts);
-
-static const struct snd_kcontrol_new twl4030_snd_controls[] = {
- /* Codec operation mode control */
- SOC_ENUM_EXT("Codec Operation Mode", twl4030_op_modes_enum,
- snd_soc_get_enum_double,
- snd_soc_put_twl4030_opmode_enum_double),
-
- /* Common playback gain controls */
- SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume",
- TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA,
- 0, 0x3f, 0, digital_fine_tlv),
- SOC_DOUBLE_R_TLV("DAC2 Digital Fine Playback Volume",
- TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA,
- 0, 0x3f, 0, digital_fine_tlv),
-
- SOC_DOUBLE_R_TLV("DAC1 Digital Coarse Playback Volume",
- TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA,
- 6, 0x2, 0, digital_coarse_tlv),
- SOC_DOUBLE_R_TLV("DAC2 Digital Coarse Playback Volume",
- TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA,
- 6, 0x2, 0, digital_coarse_tlv),
-
- SOC_DOUBLE_R_TLV("DAC1 Analog Playback Volume",
- TWL4030_REG_ARXL1_APGA_CTL, TWL4030_REG_ARXR1_APGA_CTL,
- 3, 0x12, 1, analog_tlv),
- SOC_DOUBLE_R_TLV("DAC2 Analog Playback Volume",
- TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL,
- 3, 0x12, 1, analog_tlv),
- SOC_DOUBLE_R("DAC1 Analog Playback Switch",
- TWL4030_REG_ARXL1_APGA_CTL, TWL4030_REG_ARXR1_APGA_CTL,
- 1, 1, 0),
- SOC_DOUBLE_R("DAC2 Analog Playback Switch",
- TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL,
- 1, 1, 0),
-
- /* Common voice downlink gain controls */
- SOC_SINGLE_TLV("DAC Voice Digital Downlink Volume",
- TWL4030_REG_VRXPGA, 0, 0x31, 0, digital_voice_downlink_tlv),
-
- SOC_SINGLE_TLV("DAC Voice Analog Downlink Volume",
- TWL4030_REG_VDL_APGA_CTL, 3, 0x12, 1, analog_tlv),
-
- SOC_SINGLE("DAC Voice Analog Downlink Switch",
- TWL4030_REG_VDL_APGA_CTL, 1, 1, 0),
-
- /* Separate output gain controls */
- SOC_DOUBLE_R_EXT_TLV("PreDriv Playback Volume",
- TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL,
- 4, 3, 0, snd_soc_get_volsw_r2_twl4030,
- snd_soc_put_volsw_r2_twl4030, output_tvl),
-
- SOC_DOUBLE_EXT_TLV("Headset Playback Volume",
- TWL4030_REG_HS_GAIN_SET, 0, 2, 3, 0, snd_soc_get_volsw_twl4030,
- snd_soc_put_volsw_twl4030, output_tvl),
-
- SOC_DOUBLE_R_EXT_TLV("Carkit Playback Volume",
- TWL4030_REG_PRECKL_CTL, TWL4030_REG_PRECKR_CTL,
- 4, 3, 0, snd_soc_get_volsw_r2_twl4030,
- snd_soc_put_volsw_r2_twl4030, output_tvl),
-
- SOC_SINGLE_EXT_TLV("Earpiece Playback Volume",
- TWL4030_REG_EAR_CTL, 4, 3, 0, snd_soc_get_volsw_twl4030,
- snd_soc_put_volsw_twl4030, output_ear_tvl),
-
- /* Common capture gain controls */
- SOC_DOUBLE_R_TLV("TX1 Digital Capture Volume",
- TWL4030_REG_ATXL1PGA, TWL4030_REG_ATXR1PGA,
- 0, 0x1f, 0, digital_capture_tlv),
- SOC_DOUBLE_R_TLV("TX2 Digital Capture Volume",
- TWL4030_REG_AVTXL2PGA, TWL4030_REG_AVTXR2PGA,
- 0, 0x1f, 0, digital_capture_tlv),
-
- SOC_DOUBLE_TLV("Analog Capture Volume", TWL4030_REG_ANAMIC_GAIN,
- 0, 3, 5, 0, input_gain_tlv),
-
- SOC_ENUM("AVADC Clock Priority", twl4030_avadc_clk_priority_enum),
-
- SOC_ENUM("HS ramp delay", twl4030_rampdelay_enum),
-
- SOC_ENUM("Vibra H-bridge mode", twl4030_vibradirmode_enum),
- SOC_ENUM("Vibra H-bridge direction", twl4030_vibradir_enum),
-
- SOC_ENUM("Digimic LR Swap", twl4030_digimicswap_enum),
-};
-
-static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
- /* Left channel inputs */
- SND_SOC_DAPM_INPUT("MAINMIC"),
- SND_SOC_DAPM_INPUT("HSMIC"),
- SND_SOC_DAPM_INPUT("AUXL"),
- SND_SOC_DAPM_INPUT("CARKITMIC"),
- /* Right channel inputs */
- SND_SOC_DAPM_INPUT("SUBMIC"),
- SND_SOC_DAPM_INPUT("AUXR"),
- /* Digital microphones (Stereo) */
- SND_SOC_DAPM_INPUT("DIGIMIC0"),
- SND_SOC_DAPM_INPUT("DIGIMIC1"),
-
- /* Outputs */
- SND_SOC_DAPM_OUTPUT("EARPIECE"),
- SND_SOC_DAPM_OUTPUT("PREDRIVEL"),
- SND_SOC_DAPM_OUTPUT("PREDRIVER"),
- SND_SOC_DAPM_OUTPUT("HSOL"),
- SND_SOC_DAPM_OUTPUT("HSOR"),
- SND_SOC_DAPM_OUTPUT("CARKITL"),
- SND_SOC_DAPM_OUTPUT("CARKITR"),
- SND_SOC_DAPM_OUTPUT("HFL"),
- SND_SOC_DAPM_OUTPUT("HFR"),
- SND_SOC_DAPM_OUTPUT("VIBRA"),
-
- /* AIF and APLL clocks for running DAIs (including loopback) */
- SND_SOC_DAPM_OUTPUT("Virtual HiFi OUT"),
- SND_SOC_DAPM_INPUT("Virtual HiFi IN"),
- SND_SOC_DAPM_OUTPUT("Virtual Voice OUT"),
-
- /* DACs */
- SND_SOC_DAPM_DAC("DAC Right1", "Right Front HiFi Playback",
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_DAC("DAC Left1", "Left Front HiFi Playback",
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_DAC("DAC Right2", "Right Rear HiFi Playback",
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_DAC("DAC Left2", "Left Rear HiFi Playback",
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_DAC("DAC Voice", "Voice Playback",
- SND_SOC_NOPM, 0, 0),
-
- /* Analog bypasses */
- SND_SOC_DAPM_SWITCH("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_abypassr1_control),
- SND_SOC_DAPM_SWITCH("Left1 Analog Loopback", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_abypassl1_control),
- SND_SOC_DAPM_SWITCH("Right2 Analog Loopback", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_abypassr2_control),
- SND_SOC_DAPM_SWITCH("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_abypassl2_control),
- SND_SOC_DAPM_SWITCH("Voice Analog Loopback", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_abypassv_control),
-
- /* Master analog loopback switch */
- SND_SOC_DAPM_SUPPLY("FM Loop Enable", TWL4030_REG_MISC_SET_1, 5, 0,
- NULL, 0),
-
- /* Digital bypasses */
- SND_SOC_DAPM_SWITCH("Left Digital Loopback", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_dbypassl_control),
- SND_SOC_DAPM_SWITCH("Right Digital Loopback", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_dbypassr_control),
- SND_SOC_DAPM_SWITCH("Voice Digital Loopback", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_dbypassv_control),
-
- /* Digital mixers, power control for the physical DACs */
- SND_SOC_DAPM_MIXER("Digital R1 Playback Mixer",
- TWL4030_REG_AVDAC_CTL, 0, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("Digital L1 Playback Mixer",
- TWL4030_REG_AVDAC_CTL, 1, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("Digital R2 Playback Mixer",
- TWL4030_REG_AVDAC_CTL, 2, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("Digital L2 Playback Mixer",
- TWL4030_REG_AVDAC_CTL, 3, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("Digital Voice Playback Mixer",
- TWL4030_REG_AVDAC_CTL, 4, 0, NULL, 0),
-
- /* Analog mixers, power control for the physical PGAs */
- SND_SOC_DAPM_MIXER("Analog R1 Playback Mixer",
- TWL4030_REG_ARXR1_APGA_CTL, 0, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("Analog L1 Playback Mixer",
- TWL4030_REG_ARXL1_APGA_CTL, 0, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("Analog R2 Playback Mixer",
- TWL4030_REG_ARXR2_APGA_CTL, 0, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("Analog L2 Playback Mixer",
- TWL4030_REG_ARXL2_APGA_CTL, 0, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("Analog Voice Playback Mixer",
- TWL4030_REG_VDL_APGA_CTL, 0, 0, NULL, 0),
-
- SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event,
- SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_SUPPLY("AIF Enable", SND_SOC_NOPM, 0, 0, aif_event,
- SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
-
- /* Output MIXER controls */
- /* Earpiece */
- SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_earpiece_controls[0],
- ARRAY_SIZE(twl4030_dapm_earpiece_controls)),
- SND_SOC_DAPM_PGA_E("Earpiece PGA", SND_SOC_NOPM,
- 0, 0, NULL, 0, earpiecepga_event,
- SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
- /* PreDrivL/R */
- SND_SOC_DAPM_MIXER("PredriveL Mixer", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_predrivel_controls[0],
- ARRAY_SIZE(twl4030_dapm_predrivel_controls)),
- SND_SOC_DAPM_PGA_E("PredriveL PGA", SND_SOC_NOPM,
- 0, 0, NULL, 0, predrivelpga_event,
- SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MIXER("PredriveR Mixer", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_predriver_controls[0],
- ARRAY_SIZE(twl4030_dapm_predriver_controls)),
- SND_SOC_DAPM_PGA_E("PredriveR PGA", SND_SOC_NOPM,
- 0, 0, NULL, 0, predriverpga_event,
- SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
- /* HeadsetL/R */
- SND_SOC_DAPM_MIXER("HeadsetL Mixer", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_hsol_controls[0],
- ARRAY_SIZE(twl4030_dapm_hsol_controls)),
- SND_SOC_DAPM_PGA_E("HeadsetL PGA", SND_SOC_NOPM,
- 0, 0, NULL, 0, headsetlpga_event,
- SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MIXER("HeadsetR Mixer", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_hsor_controls[0],
- ARRAY_SIZE(twl4030_dapm_hsor_controls)),
- SND_SOC_DAPM_PGA_E("HeadsetR PGA", SND_SOC_NOPM,
- 0, 0, NULL, 0, headsetrpga_event,
- SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
- /* CarkitL/R */
- SND_SOC_DAPM_MIXER("CarkitL Mixer", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_carkitl_controls[0],
- ARRAY_SIZE(twl4030_dapm_carkitl_controls)),
- SND_SOC_DAPM_PGA_E("CarkitL PGA", SND_SOC_NOPM,
- 0, 0, NULL, 0, carkitlpga_event,
- SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MIXER("CarkitR Mixer", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_carkitr_controls[0],
- ARRAY_SIZE(twl4030_dapm_carkitr_controls)),
- SND_SOC_DAPM_PGA_E("CarkitR PGA", SND_SOC_NOPM,
- 0, 0, NULL, 0, carkitrpga_event,
- SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
-
- /* Output MUX controls */
- /* HandsfreeL/R */
- SND_SOC_DAPM_MUX("HandsfreeL Mux", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_handsfreel_control),
- SND_SOC_DAPM_SWITCH("HandsfreeL", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_handsfreelmute_control),
- SND_SOC_DAPM_PGA_E("HandsfreeL PGA", SND_SOC_NOPM,
- 0, 0, NULL, 0, handsfreelpga_event,
- SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MUX("HandsfreeR Mux", SND_SOC_NOPM, 5, 0,
- &twl4030_dapm_handsfreer_control),
- SND_SOC_DAPM_SWITCH("HandsfreeR", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_handsfreermute_control),
- SND_SOC_DAPM_PGA_E("HandsfreeR PGA", SND_SOC_NOPM,
- 0, 0, NULL, 0, handsfreerpga_event,
- SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
- /* Vibra */
- SND_SOC_DAPM_MUX_E("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0,
- &twl4030_dapm_vibra_control, vibramux_event,
- SND_SOC_DAPM_PRE_PMU),
- SND_SOC_DAPM_MUX("Vibra Route", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_vibrapath_control),
-
- /* Introducing four virtual ADC, since TWL4030 have four channel for
- capture */
- SND_SOC_DAPM_ADC("ADC Virtual Left1", "Left Front Capture",
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_ADC("ADC Virtual Right1", "Right Front Capture",
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_ADC("ADC Virtual Left2", "Left Rear Capture",
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_ADC("ADC Virtual Right2", "Right Rear Capture",
- SND_SOC_NOPM, 0, 0),
-
- /* Analog/Digital mic path selection.
- TX1 Left/Right: either analog Left/Right or Digimic0
- TX2 Left/Right: either analog Left/Right or Digimic1 */
- SND_SOC_DAPM_MUX("TX1 Capture Route", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_micpathtx1_control),
- SND_SOC_DAPM_MUX("TX2 Capture Route", SND_SOC_NOPM, 0, 0,
- &twl4030_dapm_micpathtx2_control),
-
- /* Analog input mixers for the capture amplifiers */
- SND_SOC_DAPM_MIXER("Analog Left",
- TWL4030_REG_ANAMICL, 4, 0,
- &twl4030_dapm_analoglmic_controls[0],
- ARRAY_SIZE(twl4030_dapm_analoglmic_controls)),
- SND_SOC_DAPM_MIXER("Analog Right",
- TWL4030_REG_ANAMICR, 4, 0,
- &twl4030_dapm_analogrmic_controls[0],
- ARRAY_SIZE(twl4030_dapm_analogrmic_controls)),
-
- SND_SOC_DAPM_PGA("ADC Physical Left",
- TWL4030_REG_AVADC_CTL, 3, 0, NULL, 0),
- SND_SOC_DAPM_PGA("ADC Physical Right",
- TWL4030_REG_AVADC_CTL, 1, 0, NULL, 0),
-
- SND_SOC_DAPM_PGA_E("Digimic0 Enable",
- TWL4030_REG_ADCMICSEL, 1, 0, NULL, 0,
- digimic_event, SND_SOC_DAPM_POST_PMU),
- SND_SOC_DAPM_PGA_E("Digimic1 Enable",
- TWL4030_REG_ADCMICSEL, 3, 0, NULL, 0,
- digimic_event, SND_SOC_DAPM_POST_PMU),
-
- SND_SOC_DAPM_SUPPLY("micbias1 select", TWL4030_REG_MICBIAS_CTL, 5, 0,
- NULL, 0),
- SND_SOC_DAPM_SUPPLY("micbias2 select", TWL4030_REG_MICBIAS_CTL, 6, 0,
- NULL, 0),
-
- SND_SOC_DAPM_MICBIAS("Mic Bias 1", TWL4030_REG_MICBIAS_CTL, 0, 0),
- SND_SOC_DAPM_MICBIAS("Mic Bias 2", TWL4030_REG_MICBIAS_CTL, 1, 0),
- SND_SOC_DAPM_MICBIAS("Headset Mic Bias", TWL4030_REG_MICBIAS_CTL, 2, 0),
-
-};
-
-static const struct snd_soc_dapm_route intercon[] = {
- {"Digital L1 Playback Mixer", NULL, "DAC Left1"},
- {"Digital R1 Playback Mixer", NULL, "DAC Right1"},
- {"Digital L2 Playback Mixer", NULL, "DAC Left2"},
- {"Digital R2 Playback Mixer", NULL, "DAC Right2"},
- {"Digital Voice Playback Mixer", NULL, "DAC Voice"},
-
- /* Supply for the digital part (APLL) */
- {"Digital Voice Playback Mixer", NULL, "APLL Enable"},
-
- {"DAC Left1", NULL, "AIF Enable"},
- {"DAC Right1", NULL, "AIF Enable"},
- {"DAC Left2", NULL, "AIF Enable"},
- {"DAC Right1", NULL, "AIF Enable"},
-
- {"Digital R2 Playback Mixer", NULL, "AIF Enable"},
- {"Digital L2 Playback Mixer", NULL, "AIF Enable"},
-
- {"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"},
- {"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"},
- {"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"},
- {"Analog R2 Playback Mixer", NULL, "Digital R2 Playback Mixer"},
- {"Analog Voice Playback Mixer", NULL, "Digital Voice Playback Mixer"},
-
- /* Internal playback routings */
- /* Earpiece */
- {"Earpiece Mixer", "Voice", "Analog Voice Playback Mixer"},
- {"Earpiece Mixer", "AudioL1", "Analog L1 Playback Mixer"},
- {"Earpiece Mixer", "AudioL2", "Analog L2 Playback Mixer"},
- {"Earpiece Mixer", "AudioR1", "Analog R1 Playback Mixer"},
- {"Earpiece PGA", NULL, "Earpiece Mixer"},
- /* PreDrivL */
- {"PredriveL Mixer", "Voice", "Analog Voice Playback Mixer"},
- {"PredriveL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
- {"PredriveL Mixer", "AudioL2", "Analog L2 Playback Mixer"},
- {"PredriveL Mixer", "AudioR2", "Analog R2 Playback Mixer"},
- {"PredriveL PGA", NULL, "PredriveL Mixer"},
- /* PreDrivR */
- {"PredriveR Mixer", "Voice", "Analog Voice Playback Mixer"},
- {"PredriveR Mixer", "AudioR1", "Analog R1 Playback Mixer"},
- {"PredriveR Mixer", "AudioR2", "Analog R2 Playback Mixer"},
- {"PredriveR Mixer", "AudioL2", "Analog L2 Playback Mixer"},
- {"PredriveR PGA", NULL, "PredriveR Mixer"},
- /* HeadsetL */
- {"HeadsetL Mixer", "Voice", "Analog Voice Playback Mixer"},
- {"HeadsetL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
- {"HeadsetL Mixer", "AudioL2", "Analog L2 Playback Mixer"},
- {"HeadsetL PGA", NULL, "HeadsetL Mixer"},
- /* HeadsetR */
- {"HeadsetR Mixer", "Voice", "Analog Voice Playback Mixer"},
- {"HeadsetR Mixer", "AudioR1", "Analog R1 Playback Mixer"},
- {"HeadsetR Mixer", "AudioR2", "Analog R2 Playback Mixer"},
- {"HeadsetR PGA", NULL, "HeadsetR Mixer"},
- /* CarkitL */
- {"CarkitL Mixer", "Voice", "Analog Voice Playback Mixer"},
- {"CarkitL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
- {"CarkitL Mixer", "AudioL2", "Analog L2 Playback Mixer"},
- {"CarkitL PGA", NULL, "CarkitL Mixer"},
- /* CarkitR */
- {"CarkitR Mixer", "Voice", "Analog Voice Playback Mixer"},
- {"CarkitR Mixer", "AudioR1", "Analog R1 Playback Mixer"},
- {"CarkitR Mixer", "AudioR2", "Analog R2 Playback Mixer"},
- {"CarkitR PGA", NULL, "CarkitR Mixer"},
- /* HandsfreeL */
- {"HandsfreeL Mux", "Voice", "Analog Voice Playback Mixer"},
- {"HandsfreeL Mux", "AudioL1", "Analog L1 Playback Mixer"},
- {"HandsfreeL Mux", "AudioL2", "Analog L2 Playback Mixer"},
- {"HandsfreeL Mux", "AudioR2", "Analog R2 Playback Mixer"},
- {"HandsfreeL", "Switch", "HandsfreeL Mux"},
- {"HandsfreeL PGA", NULL, "HandsfreeL"},
- /* HandsfreeR */
- {"HandsfreeR Mux", "Voice", "Analog Voice Playback Mixer"},
- {"HandsfreeR Mux", "AudioR1", "Analog R1 Playback Mixer"},
- {"HandsfreeR Mux", "AudioR2", "Analog R2 Playback Mixer"},
- {"HandsfreeR Mux", "AudioL2", "Analog L2 Playback Mixer"},
- {"HandsfreeR", "Switch", "HandsfreeR Mux"},
- {"HandsfreeR PGA", NULL, "HandsfreeR"},
- /* Vibra */
- {"Vibra Mux", "AudioL1", "DAC Left1"},
- {"Vibra Mux", "AudioR1", "DAC Right1"},
- {"Vibra Mux", "AudioL2", "DAC Left2"},
- {"Vibra Mux", "AudioR2", "DAC Right2"},
-
- /* outputs */
- /* Must be always connected (for AIF and APLL) */
- {"Virtual HiFi OUT", NULL, "DAC Left1"},
- {"Virtual HiFi OUT", NULL, "DAC Right1"},
- {"Virtual HiFi OUT", NULL, "DAC Left2"},
- {"Virtual HiFi OUT", NULL, "DAC Right2"},
- /* Must be always connected (for APLL) */
- {"Virtual Voice OUT", NULL, "Digital Voice Playback Mixer"},
- /* Physical outputs */
- {"EARPIECE", NULL, "Earpiece PGA"},
- {"PREDRIVEL", NULL, "PredriveL PGA"},
- {"PREDRIVER", NULL, "PredriveR PGA"},
- {"HSOL", NULL, "HeadsetL PGA"},
- {"HSOR", NULL, "HeadsetR PGA"},
- {"CARKITL", NULL, "CarkitL PGA"},
- {"CARKITR", NULL, "CarkitR PGA"},
- {"HFL", NULL, "HandsfreeL PGA"},
- {"HFR", NULL, "HandsfreeR PGA"},
- {"Vibra Route", "Audio", "Vibra Mux"},
- {"VIBRA", NULL, "Vibra Route"},
-
- /* Capture path */
- /* Must be always connected (for AIF and APLL) */
- {"ADC Virtual Left1", NULL, "Virtual HiFi IN"},
- {"ADC Virtual Right1", NULL, "Virtual HiFi IN"},
- {"ADC Virtual Left2", NULL, "Virtual HiFi IN"},
- {"ADC Virtual Right2", NULL, "Virtual HiFi IN"},
- /* Physical inputs */
- {"Analog Left", "Main Mic Capture Switch", "MAINMIC"},
- {"Analog Left", "Headset Mic Capture Switch", "HSMIC"},
- {"Analog Left", "AUXL Capture Switch", "AUXL"},
- {"Analog Left", "Carkit Mic Capture Switch", "CARKITMIC"},
-
- {"Analog Right", "Sub Mic Capture Switch", "SUBMIC"},
- {"Analog Right", "AUXR Capture Switch", "AUXR"},
-
- {"ADC Physical Left", NULL, "Analog Left"},
- {"ADC Physical Right", NULL, "Analog Right"},
-
- {"Digimic0 Enable", NULL, "DIGIMIC0"},
- {"Digimic1 Enable", NULL, "DIGIMIC1"},
-
- {"DIGIMIC0", NULL, "micbias1 select"},
- {"DIGIMIC1", NULL, "micbias2 select"},
-
- /* TX1 Left capture path */
- {"TX1 Capture Route", "Analog", "ADC Physical Left"},
- {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"},
- /* TX1 Right capture path */
- {"TX1 Capture Route", "Analog", "ADC Physical Right"},
- {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"},
- /* TX2 Left capture path */
- {"TX2 Capture Route", "Analog", "ADC Physical Left"},
- {"TX2 Capture Route", "Digimic1", "Digimic1 Enable"},
- /* TX2 Right capture path */
- {"TX2 Capture Route", "Analog", "ADC Physical Right"},
- {"TX2 Capture Route", "Digimic1", "Digimic1 Enable"},
-
- {"ADC Virtual Left1", NULL, "TX1 Capture Route"},
- {"ADC Virtual Right1", NULL, "TX1 Capture Route"},
- {"ADC Virtual Left2", NULL, "TX2 Capture Route"},
- {"ADC Virtual Right2", NULL, "TX2 Capture Route"},
-
- {"ADC Virtual Left1", NULL, "AIF Enable"},
- {"ADC Virtual Right1", NULL, "AIF Enable"},
- {"ADC Virtual Left2", NULL, "AIF Enable"},
- {"ADC Virtual Right2", NULL, "AIF Enable"},
-
- /* Analog bypass routes */
- {"Right1 Analog Loopback", "Switch", "Analog Right"},
- {"Left1 Analog Loopback", "Switch", "Analog Left"},
- {"Right2 Analog Loopback", "Switch", "Analog Right"},
- {"Left2 Analog Loopback", "Switch", "Analog Left"},
- {"Voice Analog Loopback", "Switch", "Analog Left"},
-
- /* Supply for the Analog loopbacks */
- {"Right1 Analog Loopback", NULL, "FM Loop Enable"},
- {"Left1 Analog Loopback", NULL, "FM Loop Enable"},
- {"Right2 Analog Loopback", NULL, "FM Loop Enable"},
- {"Left2 Analog Loopback", NULL, "FM Loop Enable"},
- {"Voice Analog Loopback", NULL, "FM Loop Enable"},
-
- {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"},
- {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"},
- {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"},
- {"Analog L2 Playback Mixer", NULL, "Left2 Analog Loopback"},
- {"Analog Voice Playback Mixer", NULL, "Voice Analog Loopback"},
-
- /* Digital bypass routes */
- {"Right Digital Loopback", "Volume", "TX1 Capture Route"},
- {"Left Digital Loopback", "Volume", "TX1 Capture Route"},
- {"Voice Digital Loopback", "Volume", "TX2 Capture Route"},
-
- {"Digital R2 Playback Mixer", NULL, "Right Digital Loopback"},
- {"Digital L2 Playback Mixer", NULL, "Left Digital Loopback"},
- {"Digital Voice Playback Mixer", NULL, "Voice Digital Loopback"},
-
-};
-
-static int twl4030_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
- twl4030_codec_enable(codec, 1);
- break;
- case SND_SOC_BIAS_OFF:
- twl4030_codec_enable(codec, 0);
- break;
- }
- codec->dapm.bias_level = level;
-
- return 0;
-}
-
-static void twl4030_constraints(struct twl4030_priv *twl4030,
- struct snd_pcm_substream *mst_substream)
-{
- struct snd_pcm_substream *slv_substream;
-
- /* Pick the stream, which need to be constrained */
- if (mst_substream == twl4030->master_substream)
- slv_substream = twl4030->slave_substream;
- else if (mst_substream == twl4030->slave_substream)
- slv_substream = twl4030->master_substream;
- else /* This should not happen.. */
- return;
-
- /* Set the constraints according to the already configured stream */
- snd_pcm_hw_constraint_minmax(slv_substream->runtime,
- SNDRV_PCM_HW_PARAM_RATE,
- twl4030->rate,
- twl4030->rate);
-
- snd_pcm_hw_constraint_minmax(slv_substream->runtime,
- SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
- twl4030->sample_bits,
- twl4030->sample_bits);
-
- snd_pcm_hw_constraint_minmax(slv_substream->runtime,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- twl4030->channels,
- twl4030->channels);
-}
-
-/* In case of 4 channel mode, the RX1 L/R for playback and the TX2 L/R for
- * capture has to be enabled/disabled. */
-static void twl4030_tdm_enable(struct snd_soc_codec *codec, int direction,
- int enable)
-{
- u8 reg, mask;
-
- reg = twl4030_read_reg_cache(codec, TWL4030_REG_OPTION);
-
- if (direction == SNDRV_PCM_STREAM_PLAYBACK)
- mask = TWL4030_ARXL1_VRX_EN | TWL4030_ARXR1_EN;
- else
- mask = TWL4030_ATXL2_VTXL_EN | TWL4030_ATXR2_VTXR_EN;
-
- if (enable)
- reg |= mask;
- else
- reg &= ~mask;
-
- twl4030_write(codec, TWL4030_REG_OPTION, reg);
-}
-
-static int twl4030_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
-
- if (twl4030->master_substream) {
- twl4030->slave_substream = substream;
- /* The DAI has one configuration for playback and capture, so
- * if the DAI has been already configured then constrain this
- * substream to match it. */
- if (twl4030->configured)
- twl4030_constraints(twl4030, twl4030->master_substream);
- } else {
- if (!(twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) &
- TWL4030_OPTION_1)) {
- /* In option2 4 channel is not supported, set the
- * constraint for the first stream for channels, the
- * second stream will 'inherit' this cosntraint */
- snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- 2, 2);
- }
- twl4030->master_substream = substream;
- }
-
- return 0;
-}
-
-static void twl4030_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
-
- if (twl4030->master_substream == substream)
- twl4030->master_substream = twl4030->slave_substream;
-
- twl4030->slave_substream = NULL;
-
- /* If all streams are closed, or the remaining stream has not yet
- * been configured than set the DAI as not configured. */
- if (!twl4030->master_substream)
- twl4030->configured = 0;
- else if (!twl4030->master_substream->runtime->channels)
- twl4030->configured = 0;
-
- /* If the closing substream had 4 channel, do the necessary cleanup */
- if (substream->runtime->channels == 4)
- twl4030_tdm_enable(codec, substream->stream, 0);
-}
-
-static int twl4030_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
- u8 mode, old_mode, format, old_format;
-
- /* If the substream has 4 channel, do the necessary setup */
- if (params_channels(params) == 4) {
- format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
- mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
-
- /* Safety check: are we in the correct operating mode and
- * the interface is in TDM mode? */
- if ((mode & TWL4030_OPTION_1) &&
- ((format & TWL4030_AIF_FORMAT) == TWL4030_AIF_FORMAT_TDM))
- twl4030_tdm_enable(codec, substream->stream, 1);
- else
- return -EINVAL;
- }
-
- if (twl4030->configured)
- /* Ignoring hw_params for already configured DAI */
- return 0;
-
- /* bit rate */
- old_mode = twl4030_read_reg_cache(codec,
- TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ;
- mode = old_mode & ~TWL4030_APLL_RATE;
-
- switch (params_rate(params)) {
- case 8000:
- mode |= TWL4030_APLL_RATE_8000;
- break;
- case 11025:
- mode |= TWL4030_APLL_RATE_11025;
- break;
- case 12000:
- mode |= TWL4030_APLL_RATE_12000;
- break;
- case 16000:
- mode |= TWL4030_APLL_RATE_16000;
- break;
- case 22050:
- mode |= TWL4030_APLL_RATE_22050;
- break;
- case 24000:
- mode |= TWL4030_APLL_RATE_24000;
- break;
- case 32000:
- mode |= TWL4030_APLL_RATE_32000;
- break;
- case 44100:
- mode |= TWL4030_APLL_RATE_44100;
- break;
- case 48000:
- mode |= TWL4030_APLL_RATE_48000;
- break;
- case 96000:
- mode |= TWL4030_APLL_RATE_96000;
- break;
- default:
- dev_err(codec->dev, "%s: unknown rate %d\n", __func__,
- params_rate(params));
- return -EINVAL;
- }
-
- /* sample size */
- old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
- format = old_format;
- format &= ~TWL4030_DATA_WIDTH;
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- format |= TWL4030_DATA_WIDTH_16S_16W;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- format |= TWL4030_DATA_WIDTH_32S_24W;
- break;
- default:
- dev_err(codec->dev, "%s: unknown format %d\n", __func__,
- params_format(params));
- return -EINVAL;
- }
-
- if (format != old_format || mode != old_mode) {
- if (twl4030->codec_powered) {
- /*
- * If the codec is powered, than we need to toggle the
- * codec power.
- */
- twl4030_codec_enable(codec, 0);
- twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
- twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
- twl4030_codec_enable(codec, 1);
- } else {
- twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
- twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
- }
- }
-
- /* Store the important parameters for the DAI configuration and set
- * the DAI as configured */
- twl4030->configured = 1;
- twl4030->rate = params_rate(params);
- twl4030->sample_bits = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;
- twl4030->channels = params_channels(params);
-
- /* If both playback and capture streams are open, and one of them
- * is setting the hw parameters right now (since we are here), set
- * constraints to the other stream to match the current one. */
- if (twl4030->slave_substream)
- twl4030_constraints(twl4030, substream);
-
- return 0;
-}
-
-static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
-
- switch (freq) {
- case 19200000:
- case 26000000:
- case 38400000:
- break;
- default:
- dev_err(codec->dev, "Unsupported HFCLKIN: %u\n", freq);
- return -EINVAL;
- }
-
- if ((freq / 1000) != twl4030->sysclk) {
- dev_err(codec->dev,
- "Mismatch in HFCLKIN: %u (configured: %u)\n",
- freq, twl4030->sysclk * 1000);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
- u8 old_format, format;
-
- /* get format */
- old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
- format = old_format;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- format &= ~(TWL4030_AIF_SLAVE_EN);
- format &= ~(TWL4030_CLK256FS_EN);
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- format |= TWL4030_AIF_SLAVE_EN;
- format |= TWL4030_CLK256FS_EN;
- break;
- default:
- return -EINVAL;
- }
-
- /* interface format */
- format &= ~TWL4030_AIF_FORMAT;
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- format |= TWL4030_AIF_FORMAT_CODEC;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- format |= TWL4030_AIF_FORMAT_TDM;
- break;
- default:
- return -EINVAL;
- }
-
- if (format != old_format) {
- if (twl4030->codec_powered) {
- /*
- * If the codec is powered, than we need to toggle the
- * codec power.
- */
- twl4030_codec_enable(codec, 0);
- twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
- twl4030_codec_enable(codec, 1);
- } else {
- twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
- }
- }
-
- return 0;
-}
-
-static int twl4030_set_tristate(struct snd_soc_dai *dai, int tristate)
-{
- struct snd_soc_codec *codec = dai->codec;
- u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
-
- if (tristate)
- reg |= TWL4030_AIF_TRI_EN;
- else
- reg &= ~TWL4030_AIF_TRI_EN;
-
- return twl4030_write(codec, TWL4030_REG_AUDIO_IF, reg);
-}
-
-/* In case of voice mode, the RX1 L(VRX) for downlink and the TX2 L/R
- * (VTXL, VTXR) for uplink has to be enabled/disabled. */
-static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction,
- int enable)
-{
- u8 reg, mask;
-
- reg = twl4030_read_reg_cache(codec, TWL4030_REG_OPTION);
-
- if (direction == SNDRV_PCM_STREAM_PLAYBACK)
- mask = TWL4030_ARXL1_VRX_EN;
- else
- mask = TWL4030_ATXL2_VTXL_EN | TWL4030_ATXR2_VTXR_EN;
-
- if (enable)
- reg |= mask;
- else
- reg &= ~mask;
-
- twl4030_write(codec, TWL4030_REG_OPTION, reg);
-}
-
-static int twl4030_voice_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
- u8 mode;
-
- /* If the system master clock is not 26MHz, the voice PCM interface is
- * not available.
- */
- if (twl4030->sysclk != 26000) {
- dev_err(codec->dev,
- "%s: HFCLKIN is %u KHz, voice interface needs 26MHz\n",
- __func__, twl4030->sysclk);
- return -EINVAL;
- }
-
- /* If the codec mode is not option2, the voice PCM interface is not
- * available.
- */
- mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE)
- & TWL4030_OPT_MODE;
-
- if (mode != TWL4030_OPTION_2) {
- dev_err(codec->dev, "%s: the codec mode is not option2\n",
- __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void twl4030_voice_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
-
- /* Enable voice digital filters */
- twl4030_voice_enable(codec, substream->stream, 0);
-}
-
-static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
- u8 old_mode, mode;
-
- /* Enable voice digital filters */
- twl4030_voice_enable(codec, substream->stream, 1);
-
- /* bit rate */
- old_mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE)
- & ~(TWL4030_CODECPDZ);
- mode = old_mode;
-
- switch (params_rate(params)) {
- case 8000:
- mode &= ~(TWL4030_SEL_16K);
- break;
- case 16000:
- mode |= TWL4030_SEL_16K;
- break;
- default:
- dev_err(codec->dev, "%s: unknown rate %d\n", __func__,
- params_rate(params));
- return -EINVAL;
- }
-
- if (mode != old_mode) {
- if (twl4030->codec_powered) {
- /*
- * If the codec is powered, than we need to toggle the
- * codec power.
- */
- twl4030_codec_enable(codec, 0);
- twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
- twl4030_codec_enable(codec, 1);
- } else {
- twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
- }
- }
-
- return 0;
-}
-
-static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
-
- if (freq != 26000000) {
- dev_err(codec->dev,
- "%s: HFCLKIN is %u KHz, voice interface needs 26MHz\n",
- __func__, freq / 1000);
- return -EINVAL;
- }
- if ((freq / 1000) != twl4030->sysclk) {
- dev_err(codec->dev,
- "Mismatch in HFCLKIN: %u (configured: %u)\n",
- freq, twl4030->sysclk * 1000);
- return -EINVAL;
- }
- return 0;
-}
-
-static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
- u8 old_format, format;
-
- /* get format */
- old_format = twl4030_read_reg_cache(codec, TWL4030_REG_VOICE_IF);
- format = old_format;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- format &= ~(TWL4030_VIF_SLAVE_EN);
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- format |= TWL4030_VIF_SLAVE_EN;
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_IB_NF:
- format &= ~(TWL4030_VIF_FORMAT);
- break;
- case SND_SOC_DAIFMT_NB_IF:
- format |= TWL4030_VIF_FORMAT;
- break;
- default:
- return -EINVAL;
- }
-
- if (format != old_format) {
- if (twl4030->codec_powered) {
- /*
- * If the codec is powered, than we need to toggle the
- * codec power.
- */
- twl4030_codec_enable(codec, 0);
- twl4030_write(codec, TWL4030_REG_VOICE_IF, format);
- twl4030_codec_enable(codec, 1);
- } else {
- twl4030_write(codec, TWL4030_REG_VOICE_IF, format);
- }
- }
-
- return 0;
-}
-
-static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate)
-{
- struct snd_soc_codec *codec = dai->codec;
- u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_VOICE_IF);
-
- if (tristate)
- reg |= TWL4030_VIF_TRI_EN;
- else
- reg &= ~TWL4030_VIF_TRI_EN;
-
- return twl4030_write(codec, TWL4030_REG_VOICE_IF, reg);
-}
-
-#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000)
-#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops twl4030_dai_hifi_ops = {
- .startup = twl4030_startup,
- .shutdown = twl4030_shutdown,
- .hw_params = twl4030_hw_params,
- .set_sysclk = twl4030_set_dai_sysclk,
- .set_fmt = twl4030_set_dai_fmt,
- .set_tristate = twl4030_set_tristate,
-};
-
-static const struct snd_soc_dai_ops twl4030_dai_voice_ops = {
- .startup = twl4030_voice_startup,
- .shutdown = twl4030_voice_shutdown,
- .hw_params = twl4030_voice_hw_params,
- .set_sysclk = twl4030_voice_set_dai_sysclk,
- .set_fmt = twl4030_voice_set_dai_fmt,
- .set_tristate = twl4030_voice_set_tristate,
-};
-
-static struct snd_soc_dai_driver twl4030_dai[] = {
-{
- .name = "twl4030-hifi",
- .playback = {
- .stream_name = "HiFi Playback",
- .channels_min = 2,
- .channels_max = 4,
- .rates = TWL4030_RATES | SNDRV_PCM_RATE_96000,
- .formats = TWL4030_FORMATS,
- .sig_bits = 24,},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 4,
- .rates = TWL4030_RATES,
- .formats = TWL4030_FORMATS,
- .sig_bits = 24,},
- .ops = &twl4030_dai_hifi_ops,
-},
-{
- .name = "twl4030-voice",
- .playback = {
- .stream_name = "Voice Playback",
- .channels_min = 1,
- .channels_max = 1,
- .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .ops = &twl4030_dai_voice_ops,
-},
-};
-
-static int twl4030_soc_suspend(struct snd_soc_codec *codec)
-{
- twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int twl4030_soc_resume(struct snd_soc_codec *codec)
-{
- twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-
-static int twl4030_soc_probe(struct snd_soc_codec *codec)
-{
- struct twl4030_priv *twl4030;
-
- twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
- if (twl4030 == NULL) {
- dev_err(codec->dev, "Can not allocate memory\n");
- return -ENOMEM;
- }
- snd_soc_codec_set_drvdata(codec, twl4030);
- /* Set the defaults, and power up the codec */
- twl4030->sysclk = twl4030_audio_get_mclk() / 1000;
-
- twl4030_init_chip(codec);
-
- return 0;
-}
-
-static int twl4030_soc_remove(struct snd_soc_codec *codec)
-{
- struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
-
- /* Reset registers to their chip default before leaving */
- twl4030_reset_registers(codec);
- twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
- kfree(twl4030);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
- .probe = twl4030_soc_probe,
- .remove = twl4030_soc_remove,
- .suspend = twl4030_soc_suspend,
- .resume = twl4030_soc_resume,
- .read = twl4030_read_reg_cache,
- .write = twl4030_write,
- .set_bias_level = twl4030_set_bias_level,
- .idle_bias_off = true,
- .reg_cache_size = sizeof(twl4030_reg),
- .reg_word_size = sizeof(u8),
- .reg_cache_default = twl4030_reg,
-
- .controls = twl4030_snd_controls,
- .num_controls = ARRAY_SIZE(twl4030_snd_controls),
- .dapm_widgets = twl4030_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(twl4030_dapm_widgets),
- .dapm_routes = intercon,
- .num_dapm_routes = ARRAY_SIZE(intercon),
-};
-
-static int __devinit twl4030_codec_probe(struct platform_device *pdev)
-{
- struct twl4030_codec_data *pdata = pdev->dev.platform_data;
-
- if (!pdata) {
- dev_err(&pdev->dev, "platform_data is missing\n");
- return -EINVAL;
- }
-
- return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030,
- twl4030_dai, ARRAY_SIZE(twl4030_dai));
-}
-
-static int __devexit twl4030_codec_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-MODULE_ALIAS("platform:twl4030-codec");
-
-static struct platform_driver twl4030_codec_driver = {
- .probe = twl4030_codec_probe,
- .remove = __devexit_p(twl4030_codec_remove),
- .driver = {
- .name = "twl4030-codec",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(twl4030_codec_driver);
-
-MODULE_DESCRIPTION("ASoC TWL4030 codec driver");
-MODULE_AUTHOR("Steve Sakoman");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/twl6040.c b/ANDROID_3.4.5/sound/soc/codecs/twl6040.c
deleted file mode 100644
index dc7509b9..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/twl6040.c
+++ /dev/null
@@ -1,1662 +0,0 @@
-/*
- * ALSA SoC TWL6040 codec driver
- *
- * Author: Misael Lopez Cruz <x0052729@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/mfd/twl6040.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "twl6040.h"
-
-#define TWL6040_RATES SNDRV_PCM_RATE_8000_96000
-#define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
-
-#define TWL6040_OUTHS_0dB 0x00
-#define TWL6040_OUTHS_M30dB 0x0F
-#define TWL6040_OUTHF_0dB 0x03
-#define TWL6040_OUTHF_M52dB 0x1D
-
-#define TWL6040_RAMP_NONE 0
-#define TWL6040_RAMP_UP 1
-#define TWL6040_RAMP_DOWN 2
-
-#define TWL6040_HSL_VOL_MASK 0x0F
-#define TWL6040_HSL_VOL_SHIFT 0
-#define TWL6040_HSR_VOL_MASK 0xF0
-#define TWL6040_HSR_VOL_SHIFT 4
-#define TWL6040_HF_VOL_MASK 0x1F
-#define TWL6040_HF_VOL_SHIFT 0
-
-/* Shadow register used by the driver */
-#define TWL6040_REG_SW_SHADOW 0x2F
-#define TWL6040_CACHEREGNUM (TWL6040_REG_SW_SHADOW + 1)
-
-/* TWL6040_REG_SW_SHADOW (0x2F) fields */
-#define TWL6040_EAR_PATH_ENABLE 0x01
-
-struct twl6040_output {
- u16 active;
- u16 left_vol;
- u16 right_vol;
- u16 left_step;
- u16 right_step;
- unsigned int step_delay;
- u16 ramp;
- struct delayed_work work;
- struct completion ramp_done;
-};
-
-struct twl6040_jack_data {
- struct snd_soc_jack *jack;
- struct delayed_work work;
- int report;
-};
-
-/* codec private data */
-struct twl6040_data {
- int plug_irq;
- int codec_powered;
- int pll;
- int pll_power_mode;
- int hs_power_mode;
- int hs_power_mode_locked;
- unsigned int clk_in;
- unsigned int sysclk;
- u16 hs_left_step;
- u16 hs_right_step;
- u16 hf_left_step;
- u16 hf_right_step;
- struct twl6040_jack_data hs_jack;
- struct snd_soc_codec *codec;
- struct workqueue_struct *workqueue;
- struct mutex mutex;
- struct twl6040_output headset;
- struct twl6040_output handsfree;
-};
-
-/*
- * twl6040 register cache & default register settings
- */
-static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = {
- 0x00, /* not used 0x00 */
- 0x4B, /* REG_ASICID 0x01 (ro) */
- 0x00, /* REG_ASICREV 0x02 (ro) */
- 0x00, /* REG_INTID 0x03 */
- 0x00, /* REG_INTMR 0x04 */
- 0x00, /* REG_NCPCTRL 0x05 */
- 0x00, /* REG_LDOCTL 0x06 */
- 0x60, /* REG_HPPLLCTL 0x07 */
- 0x00, /* REG_LPPLLCTL 0x08 */
- 0x4A, /* REG_LPPLLDIV 0x09 */
- 0x00, /* REG_AMICBCTL 0x0A */
- 0x00, /* REG_DMICBCTL 0x0B */
- 0x00, /* REG_MICLCTL 0x0C */
- 0x00, /* REG_MICRCTL 0x0D */
- 0x00, /* REG_MICGAIN 0x0E */
- 0x1B, /* REG_LINEGAIN 0x0F */
- 0x00, /* REG_HSLCTL 0x10 */
- 0x00, /* REG_HSRCTL 0x11 */
- 0x00, /* REG_HSGAIN 0x12 */
- 0x00, /* REG_EARCTL 0x13 */
- 0x00, /* REG_HFLCTL 0x14 */
- 0x00, /* REG_HFLGAIN 0x15 */
- 0x00, /* REG_HFRCTL 0x16 */
- 0x00, /* REG_HFRGAIN 0x17 */
- 0x00, /* REG_VIBCTLL 0x18 */
- 0x00, /* REG_VIBDATL 0x19 */
- 0x00, /* REG_VIBCTLR 0x1A */
- 0x00, /* REG_VIBDATR 0x1B */
- 0x00, /* REG_HKCTL1 0x1C */
- 0x00, /* REG_HKCTL2 0x1D */
- 0x00, /* REG_GPOCTL 0x1E */
- 0x00, /* REG_ALB 0x1F */
- 0x00, /* REG_DLB 0x20 */
- 0x00, /* not used 0x21 */
- 0x00, /* not used 0x22 */
- 0x00, /* not used 0x23 */
- 0x00, /* not used 0x24 */
- 0x00, /* not used 0x25 */
- 0x00, /* not used 0x26 */
- 0x00, /* not used 0x27 */
- 0x00, /* REG_TRIM1 0x28 */
- 0x00, /* REG_TRIM2 0x29 */
- 0x00, /* REG_TRIM3 0x2A */
- 0x00, /* REG_HSOTRIM 0x2B */
- 0x00, /* REG_HFOTRIM 0x2C */
- 0x09, /* REG_ACCCTL 0x2D */
- 0x00, /* REG_STATUS 0x2E (ro) */
-
- 0x00, /* REG_SW_SHADOW 0x2F - Shadow, non HW register */
-};
-
-/* List of registers to be restored after power up */
-static const int twl6040_restore_list[] = {
- TWL6040_REG_MICLCTL,
- TWL6040_REG_MICRCTL,
- TWL6040_REG_MICGAIN,
- TWL6040_REG_LINEGAIN,
- TWL6040_REG_HSLCTL,
- TWL6040_REG_HSRCTL,
- TWL6040_REG_HSGAIN,
- TWL6040_REG_EARCTL,
- TWL6040_REG_HFLCTL,
- TWL6040_REG_HFLGAIN,
- TWL6040_REG_HFRCTL,
- TWL6040_REG_HFRGAIN,
-};
-
-/* set of rates for each pll: low-power and high-performance */
-static unsigned int lp_rates[] = {
- 8000,
- 11250,
- 16000,
- 22500,
- 32000,
- 44100,
- 48000,
- 88200,
- 96000,
-};
-
-static unsigned int hp_rates[] = {
- 8000,
- 16000,
- 32000,
- 48000,
- 96000,
-};
-
-static struct snd_pcm_hw_constraint_list sysclk_constraints[] = {
- { .count = ARRAY_SIZE(lp_rates), .list = lp_rates, },
- { .count = ARRAY_SIZE(hp_rates), .list = hp_rates, },
-};
-
-/*
- * read twl6040 register cache
- */
-static inline unsigned int twl6040_read_reg_cache(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- u8 *cache = codec->reg_cache;
-
- if (reg >= TWL6040_CACHEREGNUM)
- return -EIO;
-
- return cache[reg];
-}
-
-/*
- * write twl6040 register cache
- */
-static inline void twl6040_write_reg_cache(struct snd_soc_codec *codec,
- u8 reg, u8 value)
-{
- u8 *cache = codec->reg_cache;
-
- if (reg >= TWL6040_CACHEREGNUM)
- return;
- cache[reg] = value;
-}
-
-/*
- * read from twl6040 hardware register
- */
-static int twl6040_read_reg_volatile(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- struct twl6040 *twl6040 = codec->control_data;
- u8 value;
-
- if (reg >= TWL6040_CACHEREGNUM)
- return -EIO;
-
- if (likely(reg < TWL6040_REG_SW_SHADOW)) {
- value = twl6040_reg_read(twl6040, reg);
- twl6040_write_reg_cache(codec, reg, value);
- } else {
- value = twl6040_read_reg_cache(codec, reg);
- }
-
- return value;
-}
-
-/*
- * write to the twl6040 register space
- */
-static int twl6040_write(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int value)
-{
- struct twl6040 *twl6040 = codec->control_data;
-
- if (reg >= TWL6040_CACHEREGNUM)
- return -EIO;
-
- twl6040_write_reg_cache(codec, reg, value);
- if (likely(reg < TWL6040_REG_SW_SHADOW))
- return twl6040_reg_write(twl6040, reg, value);
- else
- return 0;
-}
-
-static void twl6040_init_chip(struct snd_soc_codec *codec)
-{
- struct twl6040 *twl6040 = codec->control_data;
- u8 val;
-
- /* Update reg_cache: ASICREV, and TRIM values */
- val = twl6040_get_revid(twl6040);
- twl6040_write_reg_cache(codec, TWL6040_REG_ASICREV, val);
-
- twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM1);
- twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM2);
- twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM3);
- twl6040_read_reg_volatile(codec, TWL6040_REG_HSOTRIM);
- twl6040_read_reg_volatile(codec, TWL6040_REG_HFOTRIM);
-
- /* Change chip defaults */
- /* No imput selected for microphone amplifiers */
- twl6040_write_reg_cache(codec, TWL6040_REG_MICLCTL, 0x18);
- twl6040_write_reg_cache(codec, TWL6040_REG_MICRCTL, 0x18);
-
- /*
- * We need to lower the default gain values, so the ramp code
- * can work correctly for the first playback.
- * This reduces the pop noise heard at the first playback.
- */
- twl6040_write_reg_cache(codec, TWL6040_REG_HSGAIN, 0xff);
- twl6040_write_reg_cache(codec, TWL6040_REG_EARCTL, 0x1e);
- twl6040_write_reg_cache(codec, TWL6040_REG_HFLGAIN, 0x1d);
- twl6040_write_reg_cache(codec, TWL6040_REG_HFRGAIN, 0x1d);
- twl6040_write_reg_cache(codec, TWL6040_REG_LINEGAIN, 0);
-}
-
-static void twl6040_restore_regs(struct snd_soc_codec *codec)
-{
- u8 *cache = codec->reg_cache;
- int reg, i;
-
- for (i = 0; i < ARRAY_SIZE(twl6040_restore_list); i++) {
- reg = twl6040_restore_list[i];
- twl6040_write(codec, reg, cache[reg]);
- }
-}
-
-/*
- * Ramp HS PGA volume to minimise pops at stream startup and shutdown.
- */
-static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
- unsigned int left_step, unsigned int right_step)
-{
-
- struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
- struct twl6040_output *headset = &priv->headset;
- int left_complete = 0, right_complete = 0;
- u8 reg, val;
-
- /* left channel */
- left_step = (left_step > 0xF) ? 0xF : left_step;
- reg = twl6040_read_reg_cache(codec, TWL6040_REG_HSGAIN);
- val = (~reg & TWL6040_HSL_VOL_MASK);
-
- if (headset->ramp == TWL6040_RAMP_UP) {
- /* ramp step up */
- if (val < headset->left_vol) {
- if (val + left_step > headset->left_vol)
- val = headset->left_vol;
- else
- val += left_step;
-
- reg &= ~TWL6040_HSL_VOL_MASK;
- twl6040_write(codec, TWL6040_REG_HSGAIN,
- (reg | (~val & TWL6040_HSL_VOL_MASK)));
- } else {
- left_complete = 1;
- }
- } else if (headset->ramp == TWL6040_RAMP_DOWN) {
- /* ramp step down */
- if (val > 0x0) {
- if ((int)val - (int)left_step < 0)
- val = 0;
- else
- val -= left_step;
-
- reg &= ~TWL6040_HSL_VOL_MASK;
- twl6040_write(codec, TWL6040_REG_HSGAIN, reg |
- (~val & TWL6040_HSL_VOL_MASK));
- } else {
- left_complete = 1;
- }
- }
-
- /* right channel */
- right_step = (right_step > 0xF) ? 0xF : right_step;
- reg = twl6040_read_reg_cache(codec, TWL6040_REG_HSGAIN);
- val = (~reg & TWL6040_HSR_VOL_MASK) >> TWL6040_HSR_VOL_SHIFT;
-
- if (headset->ramp == TWL6040_RAMP_UP) {
- /* ramp step up */
- if (val < headset->right_vol) {
- if (val + right_step > headset->right_vol)
- val = headset->right_vol;
- else
- val += right_step;
-
- reg &= ~TWL6040_HSR_VOL_MASK;
- twl6040_write(codec, TWL6040_REG_HSGAIN,
- (reg | (~val << TWL6040_HSR_VOL_SHIFT)));
- } else {
- right_complete = 1;
- }
- } else if (headset->ramp == TWL6040_RAMP_DOWN) {
- /* ramp step down */
- if (val > 0x0) {
- if ((int)val - (int)right_step < 0)
- val = 0;
- else
- val -= right_step;
-
- reg &= ~TWL6040_HSR_VOL_MASK;
- twl6040_write(codec, TWL6040_REG_HSGAIN,
- reg | (~val << TWL6040_HSR_VOL_SHIFT));
- } else {
- right_complete = 1;
- }
- }
-
- return left_complete & right_complete;
-}
-
-/*
- * Ramp HF PGA volume to minimise pops at stream startup and shutdown.
- */
-static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
- unsigned int left_step, unsigned int right_step)
-{
- struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
- struct twl6040_output *handsfree = &priv->handsfree;
- int left_complete = 0, right_complete = 0;
- u16 reg, val;
-
- /* left channel */
- left_step = (left_step > 0x1D) ? 0x1D : left_step;
- reg = twl6040_read_reg_cache(codec, TWL6040_REG_HFLGAIN);
- reg = 0x1D - reg;
- val = (reg & TWL6040_HF_VOL_MASK);
- if (handsfree->ramp == TWL6040_RAMP_UP) {
- /* ramp step up */
- if (val < handsfree->left_vol) {
- if (val + left_step > handsfree->left_vol)
- val = handsfree->left_vol;
- else
- val += left_step;
-
- reg &= ~TWL6040_HF_VOL_MASK;
- twl6040_write(codec, TWL6040_REG_HFLGAIN,
- reg | (0x1D - val));
- } else {
- left_complete = 1;
- }
- } else if (handsfree->ramp == TWL6040_RAMP_DOWN) {
- /* ramp step down */
- if (val > 0) {
- if ((int)val - (int)left_step < 0)
- val = 0;
- else
- val -= left_step;
-
- reg &= ~TWL6040_HF_VOL_MASK;
- twl6040_write(codec, TWL6040_REG_HFLGAIN,
- reg | (0x1D - val));
- } else {
- left_complete = 1;
- }
- }
-
- /* right channel */
- right_step = (right_step > 0x1D) ? 0x1D : right_step;
- reg = twl6040_read_reg_cache(codec, TWL6040_REG_HFRGAIN);
- reg = 0x1D - reg;
- val = (reg & TWL6040_HF_VOL_MASK);
- if (handsfree->ramp == TWL6040_RAMP_UP) {
- /* ramp step up */
- if (val < handsfree->right_vol) {
- if (val + right_step > handsfree->right_vol)
- val = handsfree->right_vol;
- else
- val += right_step;
-
- reg &= ~TWL6040_HF_VOL_MASK;
- twl6040_write(codec, TWL6040_REG_HFRGAIN,
- reg | (0x1D - val));
- } else {
- right_complete = 1;
- }
- } else if (handsfree->ramp == TWL6040_RAMP_DOWN) {
- /* ramp step down */
- if (val > 0) {
- if ((int)val - (int)right_step < 0)
- val = 0;
- else
- val -= right_step;
-
- reg &= ~TWL6040_HF_VOL_MASK;
- twl6040_write(codec, TWL6040_REG_HFRGAIN,
- reg | (0x1D - val));
- }
- }
-
- return left_complete & right_complete;
-}
-
-/*
- * This work ramps both output PGAs at stream start/stop time to
- * minimise pop associated with DAPM power switching.
- */
-static void twl6040_pga_hs_work(struct work_struct *work)
-{
- struct twl6040_data *priv =
- container_of(work, struct twl6040_data, headset.work.work);
- struct snd_soc_codec *codec = priv->codec;
- struct twl6040_output *headset = &priv->headset;
- int i, headset_complete;
-
- /* do we need to ramp at all ? */
- if (headset->ramp == TWL6040_RAMP_NONE)
- return;
-
- /* HS PGA gain range: 0x0 - 0xf (0 - 15) */
- for (i = 0; i < 16; i++) {
- headset_complete = twl6040_hs_ramp_step(codec,
- headset->left_step,
- headset->right_step);
-
- /* ramp finished ? */
- if (headset_complete)
- break;
-
- schedule_timeout_interruptible(
- msecs_to_jiffies(headset->step_delay));
- }
-
- if (headset->ramp == TWL6040_RAMP_DOWN) {
- headset->active = 0;
- complete(&headset->ramp_done);
- } else {
- headset->active = 1;
- }
- headset->ramp = TWL6040_RAMP_NONE;
-}
-
-static void twl6040_pga_hf_work(struct work_struct *work)
-{
- struct twl6040_data *priv =
- container_of(work, struct twl6040_data, handsfree.work.work);
- struct snd_soc_codec *codec = priv->codec;
- struct twl6040_output *handsfree = &priv->handsfree;
- int i, handsfree_complete;
-
- /* do we need to ramp at all ? */
- if (handsfree->ramp == TWL6040_RAMP_NONE)
- return;
-
- /*
- * HF PGA gain range: 0x00 - 0x1d (0 - 29) */
- for (i = 0; i < 30; i++) {
- handsfree_complete = twl6040_hf_ramp_step(codec,
- handsfree->left_step,
- handsfree->right_step);
-
- /* ramp finished ? */
- if (handsfree_complete)
- break;
-
- schedule_timeout_interruptible(
- msecs_to_jiffies(handsfree->step_delay));
- }
-
-
- if (handsfree->ramp == TWL6040_RAMP_DOWN) {
- handsfree->active = 0;
- complete(&handsfree->ramp_done);
- } else
- handsfree->active = 1;
- handsfree->ramp = TWL6040_RAMP_NONE;
-}
-
-static int out_drv_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
- struct twl6040_output *out;
- struct delayed_work *work;
-
- switch (w->shift) {
- case 2: /* Headset output driver */
- out = &priv->headset;
- work = &out->work;
- /*
- * Make sure, that we do not mess up variables for already
- * executing work.
- */
- cancel_delayed_work_sync(work);
-
- out->left_step = priv->hs_left_step;
- out->right_step = priv->hs_right_step;
- out->step_delay = 5; /* 5 ms between volume ramp steps */
- break;
- case 4: /* Handsfree output driver */
- out = &priv->handsfree;
- work = &out->work;
- /*
- * Make sure, that we do not mess up variables for already
- * executing work.
- */
- cancel_delayed_work_sync(work);
-
- out->left_step = priv->hf_left_step;
- out->right_step = priv->hf_right_step;
- out->step_delay = 5; /* 5 ms between volume ramp steps */
- break;
- default:
- return -1;
- }
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- if (out->active)
- break;
-
- /* don't use volume ramp for power-up */
- out->ramp = TWL6040_RAMP_UP;
- out->left_step = out->left_vol;
- out->right_step = out->right_vol;
-
- queue_delayed_work(priv->workqueue, work, msecs_to_jiffies(1));
- break;
-
- case SND_SOC_DAPM_PRE_PMD:
- if (!out->active)
- break;
-
- /* use volume ramp for power-down */
- out->ramp = TWL6040_RAMP_DOWN;
- INIT_COMPLETION(out->ramp_done);
-
- queue_delayed_work(priv->workqueue, work, msecs_to_jiffies(1));
-
- wait_for_completion_timeout(&out->ramp_done,
- msecs_to_jiffies(2000));
- break;
- }
-
- return 0;
-}
-
-/* set headset dac and driver power mode */
-static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
-{
- int hslctl, hsrctl;
- int mask = TWL6040_HSDRVMODE | TWL6040_HSDACMODE;
-
- hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL);
- hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL);
-
- if (high_perf) {
- hslctl &= ~mask;
- hsrctl &= ~mask;
- } else {
- hslctl |= mask;
- hsrctl |= mask;
- }
-
- twl6040_write(codec, TWL6040_REG_HSLCTL, hslctl);
- twl6040_write(codec, TWL6040_REG_HSRCTL, hsrctl);
-
- return 0;
-}
-
-static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- u8 hslctl, hsrctl;
-
- /*
- * Workaround for Headset DC offset caused pop noise:
- * Both HS DAC need to be turned on (before the HS driver) and off at
- * the same time.
- */
- hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL);
- hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL);
- if (SND_SOC_DAPM_EVENT_ON(event)) {
- hslctl |= TWL6040_HSDACENA;
- hsrctl |= TWL6040_HSDACENA;
- } else {
- hslctl &= ~TWL6040_HSDACENA;
- hsrctl &= ~TWL6040_HSDACENA;
- }
- twl6040_write(codec, TWL6040_REG_HSLCTL, hslctl);
- twl6040_write(codec, TWL6040_REG_HSRCTL, hsrctl);
-
- msleep(1);
- return 0;
-}
-
-static int twl6040_ep_drv_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
- int ret = 0;
-
- if (SND_SOC_DAPM_EVENT_ON(event)) {
- /* Earphone doesn't support low power mode */
- priv->hs_power_mode_locked = 1;
- ret = headset_power_mode(codec, 1);
- } else {
- priv->hs_power_mode_locked = 0;
- ret = headset_power_mode(codec, priv->hs_power_mode);
- }
-
- msleep(1);
-
- return ret;
-}
-
-static void twl6040_hs_jack_report(struct snd_soc_codec *codec,
- struct snd_soc_jack *jack, int report)
-{
- struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
- int status;
-
- mutex_lock(&priv->mutex);
-
- /* Sync status */
- status = twl6040_read_reg_volatile(codec, TWL6040_REG_STATUS);
- if (status & TWL6040_PLUGCOMP)
- snd_soc_jack_report(jack, report, report);
- else
- snd_soc_jack_report(jack, 0, report);
-
- mutex_unlock(&priv->mutex);
-}
-
-void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
- struct snd_soc_jack *jack, int report)
-{
- struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
- struct twl6040_jack_data *hs_jack = &priv->hs_jack;
-
- hs_jack->jack = jack;
- hs_jack->report = report;
-
- twl6040_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
-}
-EXPORT_SYMBOL_GPL(twl6040_hs_jack_detect);
-
-static void twl6040_accessory_work(struct work_struct *work)
-{
- struct twl6040_data *priv = container_of(work,
- struct twl6040_data, hs_jack.work.work);
- struct snd_soc_codec *codec = priv->codec;
- struct twl6040_jack_data *hs_jack = &priv->hs_jack;
-
- twl6040_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
-}
-
-/* audio interrupt handler */
-static irqreturn_t twl6040_audio_handler(int irq, void *data)
-{
- struct snd_soc_codec *codec = data;
- struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
-
- queue_delayed_work(priv->workqueue, &priv->hs_jack.work,
- msecs_to_jiffies(200));
-
- return IRQ_HANDLED;
-}
-
-static int twl6040_put_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
- struct twl6040_output *out = NULL;
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- int ret;
-
- /* For HS and HF we shadow the values and only actually write
- * them out when active in order to ensure the amplifier comes on
- * as quietly as possible. */
- switch (mc->reg) {
- case TWL6040_REG_HSGAIN:
- out = &twl6040_priv->headset;
- break;
- case TWL6040_REG_HFLGAIN:
- out = &twl6040_priv->handsfree;
- break;
- default:
- dev_warn(codec->dev, "%s: Unexpected register: 0x%02x\n",
- __func__, mc->reg);
- return -EINVAL;
- }
-
- out->left_vol = ucontrol->value.integer.value[0];
- out->right_vol = ucontrol->value.integer.value[1];
- if (!out->active)
- return 1;
-
- ret = snd_soc_put_volsw(kcontrol, ucontrol);
- if (ret < 0)
- return ret;
-
- return 1;
-}
-
-static int twl6040_get_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
- struct twl6040_output *out = &twl6040_priv->headset;
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
-
- switch (mc->reg) {
- case TWL6040_REG_HSGAIN:
- out = &twl6040_priv->headset;
- break;
- case TWL6040_REG_HFLGAIN:
- out = &twl6040_priv->handsfree;
- break;
- default:
- dev_warn(codec->dev, "%s: Unexpected register: 0x%02x\n",
- __func__, mc->reg);
- return -EINVAL;
- }
-
- ucontrol->value.integer.value[0] = out->left_vol;
- ucontrol->value.integer.value[1] = out->right_vol;
- return 0;
-}
-
-static int twl6040_soc_dapm_put_vibra_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
- struct snd_soc_dapm_widget *widget = wlist->widgets[0];
- struct snd_soc_codec *codec = widget->codec;
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int val;
-
- /* Do not allow changes while Input/FF efect is running */
- val = twl6040_read_reg_volatile(codec, e->reg);
- if (val & TWL6040_VIBENA && !(val & TWL6040_VIBSEL))
- return -EBUSY;
-
- return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
-}
-
-/*
- * MICATT volume control:
- * from -6 to 0 dB in 6 dB steps
- */
-static DECLARE_TLV_DB_SCALE(mic_preamp_tlv, -600, 600, 0);
-
-/*
- * MICGAIN volume control:
- * from 6 to 30 dB in 6 dB steps
- */
-static DECLARE_TLV_DB_SCALE(mic_amp_tlv, 600, 600, 0);
-
-/*
- * AFMGAIN volume control:
- * from -18 to 24 dB in 6 dB steps
- */
-static DECLARE_TLV_DB_SCALE(afm_amp_tlv, -1800, 600, 0);
-
-/*
- * HSGAIN volume control:
- * from -30 to 0 dB in 2 dB steps
- */
-static DECLARE_TLV_DB_SCALE(hs_tlv, -3000, 200, 0);
-
-/*
- * HFGAIN volume control:
- * from -52 to 6 dB in 2 dB steps
- */
-static DECLARE_TLV_DB_SCALE(hf_tlv, -5200, 200, 0);
-
-/*
- * EPGAIN volume control:
- * from -24 to 6 dB in 2 dB steps
- */
-static DECLARE_TLV_DB_SCALE(ep_tlv, -2400, 200, 0);
-
-/* Left analog microphone selection */
-static const char *twl6040_amicl_texts[] =
- {"Headset Mic", "Main Mic", "Aux/FM Left", "Off"};
-
-/* Right analog microphone selection */
-static const char *twl6040_amicr_texts[] =
- {"Headset Mic", "Sub Mic", "Aux/FM Right", "Off"};
-
-static const struct soc_enum twl6040_enum[] = {
- SOC_ENUM_SINGLE(TWL6040_REG_MICLCTL, 3, 4, twl6040_amicl_texts),
- SOC_ENUM_SINGLE(TWL6040_REG_MICRCTL, 3, 4, twl6040_amicr_texts),
-};
-
-static const char *twl6040_hs_texts[] = {
- "Off", "HS DAC", "Line-In amp"
-};
-
-static const struct soc_enum twl6040_hs_enum[] = {
- SOC_ENUM_SINGLE(TWL6040_REG_HSLCTL, 5, ARRAY_SIZE(twl6040_hs_texts),
- twl6040_hs_texts),
- SOC_ENUM_SINGLE(TWL6040_REG_HSRCTL, 5, ARRAY_SIZE(twl6040_hs_texts),
- twl6040_hs_texts),
-};
-
-static const char *twl6040_hf_texts[] = {
- "Off", "HF DAC", "Line-In amp"
-};
-
-static const struct soc_enum twl6040_hf_enum[] = {
- SOC_ENUM_SINGLE(TWL6040_REG_HFLCTL, 2, ARRAY_SIZE(twl6040_hf_texts),
- twl6040_hf_texts),
- SOC_ENUM_SINGLE(TWL6040_REG_HFRCTL, 2, ARRAY_SIZE(twl6040_hf_texts),
- twl6040_hf_texts),
-};
-
-static const char *twl6040_vibrapath_texts[] = {
- "Input FF", "Audio PDM"
-};
-
-static const struct soc_enum twl6040_vibra_enum[] = {
- SOC_ENUM_SINGLE(TWL6040_REG_VIBCTLL, 1,
- ARRAY_SIZE(twl6040_vibrapath_texts),
- twl6040_vibrapath_texts),
- SOC_ENUM_SINGLE(TWL6040_REG_VIBCTLR, 1,
- ARRAY_SIZE(twl6040_vibrapath_texts),
- twl6040_vibrapath_texts),
-};
-
-static const struct snd_kcontrol_new amicl_control =
- SOC_DAPM_ENUM("Route", twl6040_enum[0]);
-
-static const struct snd_kcontrol_new amicr_control =
- SOC_DAPM_ENUM("Route", twl6040_enum[1]);
-
-/* Headset DAC playback switches */
-static const struct snd_kcontrol_new hsl_mux_controls =
- SOC_DAPM_ENUM("Route", twl6040_hs_enum[0]);
-
-static const struct snd_kcontrol_new hsr_mux_controls =
- SOC_DAPM_ENUM("Route", twl6040_hs_enum[1]);
-
-/* Handsfree DAC playback switches */
-static const struct snd_kcontrol_new hfl_mux_controls =
- SOC_DAPM_ENUM("Route", twl6040_hf_enum[0]);
-
-static const struct snd_kcontrol_new hfr_mux_controls =
- SOC_DAPM_ENUM("Route", twl6040_hf_enum[1]);
-
-static const struct snd_kcontrol_new ep_path_enable_control =
- SOC_DAPM_SINGLE("Switch", TWL6040_REG_SW_SHADOW, 0, 1, 0);
-
-static const struct snd_kcontrol_new auxl_switch_control =
- SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 6, 1, 0);
-
-static const struct snd_kcontrol_new auxr_switch_control =
- SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 6, 1, 0);
-
-/* Vibra playback switches */
-static const struct snd_kcontrol_new vibral_mux_controls =
- SOC_DAPM_ENUM_EXT("Route", twl6040_vibra_enum[0],
- snd_soc_dapm_get_enum_double,
- twl6040_soc_dapm_put_vibra_enum);
-
-static const struct snd_kcontrol_new vibrar_mux_controls =
- SOC_DAPM_ENUM_EXT("Route", twl6040_vibra_enum[1],
- snd_soc_dapm_get_enum_double,
- twl6040_soc_dapm_put_vibra_enum);
-
-/* Headset power mode */
-static const char *twl6040_power_mode_texts[] = {
- "Low-Power", "High-Perfomance",
-};
-
-static const struct soc_enum twl6040_power_mode_enum =
- SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl6040_power_mode_texts),
- twl6040_power_mode_texts);
-
-static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.enumerated.item[0] = priv->hs_power_mode;
-
- return 0;
-}
-
-static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
- int high_perf = ucontrol->value.enumerated.item[0];
- int ret = 0;
-
- if (!priv->hs_power_mode_locked)
- ret = headset_power_mode(codec, high_perf);
-
- if (!ret)
- priv->hs_power_mode = high_perf;
-
- return ret;
-}
-
-static int twl6040_pll_get_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.enumerated.item[0] = priv->pll_power_mode;
-
- return 0;
-}
-
-static int twl6040_pll_put_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
-
- priv->pll_power_mode = ucontrol->value.enumerated.item[0];
-
- return 0;
-}
-
-int twl6040_get_dl1_gain(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- if (snd_soc_dapm_get_pin_status(dapm, "EP"))
- return -1; /* -1dB */
-
- if (snd_soc_dapm_get_pin_status(dapm, "HSOR") ||
- snd_soc_dapm_get_pin_status(dapm, "HSOL")) {
-
- u8 val = snd_soc_read(codec, TWL6040_REG_HSLCTL);
- if (val & TWL6040_HSDACMODE)
- /* HSDACL in LP mode */
- return -8; /* -8dB */
- else
- /* HSDACL in HP mode */
- return -1; /* -1dB */
- }
- return 0; /* 0dB */
-}
-EXPORT_SYMBOL_GPL(twl6040_get_dl1_gain);
-
-int twl6040_get_clk_id(struct snd_soc_codec *codec)
-{
- struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
-
- return priv->pll_power_mode;
-}
-EXPORT_SYMBOL_GPL(twl6040_get_clk_id);
-
-int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim)
-{
- if (unlikely(trim >= TWL6040_TRIM_INVAL))
- return -EINVAL;
-
- return twl6040_read_reg_cache(codec, TWL6040_REG_TRIM1 + trim);
-}
-EXPORT_SYMBOL_GPL(twl6040_get_trim_value);
-
-int twl6040_get_hs_step_size(struct snd_soc_codec *codec)
-{
- struct twl6040 *twl6040 = codec->control_data;
-
- if (twl6040_get_revid(twl6040) < TWL6040_REV_ES1_2)
- /* For ES under ES_1.3 HS step is 2 mV */
- return 2;
- else
- /* For ES_1.3 HS step is 1 mV */
- return 1;
-}
-EXPORT_SYMBOL_GPL(twl6040_get_hs_step_size);
-
-static const struct snd_kcontrol_new twl6040_snd_controls[] = {
- /* Capture gains */
- SOC_DOUBLE_TLV("Capture Preamplifier Volume",
- TWL6040_REG_MICGAIN, 6, 7, 1, 1, mic_preamp_tlv),
- SOC_DOUBLE_TLV("Capture Volume",
- TWL6040_REG_MICGAIN, 0, 3, 4, 0, mic_amp_tlv),
-
- /* AFM gains */
- SOC_DOUBLE_TLV("Aux FM Volume",
- TWL6040_REG_LINEGAIN, 0, 3, 7, 0, afm_amp_tlv),
-
- /* Playback gains */
- SOC_DOUBLE_EXT_TLV("Headset Playback Volume",
- TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, twl6040_get_volsw,
- twl6040_put_volsw, hs_tlv),
- SOC_DOUBLE_R_EXT_TLV("Handsfree Playback Volume",
- TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1,
- twl6040_get_volsw, twl6040_put_volsw, hf_tlv),
- SOC_SINGLE_TLV("Earphone Playback Volume",
- TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv),
-
- SOC_ENUM_EXT("Headset Power Mode", twl6040_power_mode_enum,
- twl6040_headset_power_get_enum,
- twl6040_headset_power_put_enum),
-
- SOC_ENUM_EXT("PLL Selection", twl6040_power_mode_enum,
- twl6040_pll_get_enum, twl6040_pll_put_enum),
-};
-
-static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
- /* Inputs */
- SND_SOC_DAPM_INPUT("MAINMIC"),
- SND_SOC_DAPM_INPUT("HSMIC"),
- SND_SOC_DAPM_INPUT("SUBMIC"),
- SND_SOC_DAPM_INPUT("AFML"),
- SND_SOC_DAPM_INPUT("AFMR"),
-
- /* Outputs */
- SND_SOC_DAPM_OUTPUT("HSOL"),
- SND_SOC_DAPM_OUTPUT("HSOR"),
- SND_SOC_DAPM_OUTPUT("HFL"),
- SND_SOC_DAPM_OUTPUT("HFR"),
- SND_SOC_DAPM_OUTPUT("EP"),
- SND_SOC_DAPM_OUTPUT("AUXL"),
- SND_SOC_DAPM_OUTPUT("AUXR"),
- SND_SOC_DAPM_OUTPUT("VIBRAL"),
- SND_SOC_DAPM_OUTPUT("VIBRAR"),
-
- /* Analog input muxes for the capture amplifiers */
- SND_SOC_DAPM_MUX("Analog Left Capture Route",
- SND_SOC_NOPM, 0, 0, &amicl_control),
- SND_SOC_DAPM_MUX("Analog Right Capture Route",
- SND_SOC_NOPM, 0, 0, &amicr_control),
-
- /* Analog capture PGAs */
- SND_SOC_DAPM_PGA("MicAmpL",
- TWL6040_REG_MICLCTL, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("MicAmpR",
- TWL6040_REG_MICRCTL, 0, 0, NULL, 0),
-
- /* Auxiliary FM PGAs */
- SND_SOC_DAPM_PGA("AFMAmpL",
- TWL6040_REG_MICLCTL, 1, 0, NULL, 0),
- SND_SOC_DAPM_PGA("AFMAmpR",
- TWL6040_REG_MICRCTL, 1, 0, NULL, 0),
-
- /* ADCs */
- SND_SOC_DAPM_ADC("ADC Left", "Left Front Capture",
- TWL6040_REG_MICLCTL, 2, 0),
- SND_SOC_DAPM_ADC("ADC Right", "Right Front Capture",
- TWL6040_REG_MICRCTL, 2, 0),
-
- /* Microphone bias */
- SND_SOC_DAPM_SUPPLY("Headset Mic Bias",
- TWL6040_REG_AMICBCTL, 0, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("Main Mic Bias",
- TWL6040_REG_AMICBCTL, 4, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("Digital Mic1 Bias",
- TWL6040_REG_DMICBCTL, 0, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("Digital Mic2 Bias",
- TWL6040_REG_DMICBCTL, 4, 0, NULL, 0),
-
- /* DACs */
- SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback", SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_DAC("HSDAC Right", "Headset Playback", SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_DAC("HFDAC Left", "Handsfree Playback",
- TWL6040_REG_HFLCTL, 0, 0),
- SND_SOC_DAPM_DAC("HFDAC Right", "Handsfree Playback",
- TWL6040_REG_HFRCTL, 0, 0),
- /* Virtual DAC for vibra path (DL4 channel) */
- SND_SOC_DAPM_DAC("VIBRA DAC", "Vibra Playback",
- SND_SOC_NOPM, 0, 0),
-
- SND_SOC_DAPM_MUX("Handsfree Left Playback",
- SND_SOC_NOPM, 0, 0, &hfl_mux_controls),
- SND_SOC_DAPM_MUX("Handsfree Right Playback",
- SND_SOC_NOPM, 0, 0, &hfr_mux_controls),
- /* Analog playback Muxes */
- SND_SOC_DAPM_MUX("Headset Left Playback",
- SND_SOC_NOPM, 0, 0, &hsl_mux_controls),
- SND_SOC_DAPM_MUX("Headset Right Playback",
- SND_SOC_NOPM, 0, 0, &hsr_mux_controls),
-
- SND_SOC_DAPM_MUX("Vibra Left Playback", SND_SOC_NOPM, 0, 0,
- &vibral_mux_controls),
- SND_SOC_DAPM_MUX("Vibra Right Playback", SND_SOC_NOPM, 0, 0,
- &vibrar_mux_controls),
-
- SND_SOC_DAPM_SWITCH("Earphone Playback", SND_SOC_NOPM, 0, 0,
- &ep_path_enable_control),
- SND_SOC_DAPM_SWITCH("AUXL Playback", SND_SOC_NOPM, 0, 0,
- &auxl_switch_control),
- SND_SOC_DAPM_SWITCH("AUXR Playback", SND_SOC_NOPM, 0, 0,
- &auxr_switch_control),
-
- /* Analog playback drivers */
- SND_SOC_DAPM_OUT_DRV_E("HF Left Driver",
- TWL6040_REG_HFLCTL, 4, 0, NULL, 0,
- out_drv_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
- SND_SOC_DAPM_OUT_DRV_E("HF Right Driver",
- TWL6040_REG_HFRCTL, 4, 0, NULL, 0,
- out_drv_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
- SND_SOC_DAPM_OUT_DRV_E("HS Left Driver",
- TWL6040_REG_HSLCTL, 2, 0, NULL, 0,
- out_drv_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
- SND_SOC_DAPM_OUT_DRV_E("HS Right Driver",
- TWL6040_REG_HSRCTL, 2, 0, NULL, 0,
- out_drv_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
- SND_SOC_DAPM_OUT_DRV_E("Earphone Driver",
- TWL6040_REG_EARCTL, 0, 0, NULL, 0,
- twl6040_ep_drv_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_OUT_DRV("Vibra Left Driver",
- TWL6040_REG_VIBCTLL, 0, 0, NULL, 0),
- SND_SOC_DAPM_OUT_DRV("Vibra Right Driver",
- TWL6040_REG_VIBCTLR, 0, 0, NULL, 0),
-
- SND_SOC_DAPM_SUPPLY("Vibra Left Control", TWL6040_REG_VIBCTLL, 2, 0,
- NULL, 0),
- SND_SOC_DAPM_SUPPLY("Vibra Right Control", TWL6040_REG_VIBCTLR, 2, 0,
- NULL, 0),
- SND_SOC_DAPM_SUPPLY_S("HSDAC Power", 1, SND_SOC_NOPM, 0, 0,
- twl6040_hs_dac_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- /* Analog playback PGAs */
- SND_SOC_DAPM_PGA("HF Left PGA",
- TWL6040_REG_HFLCTL, 1, 0, NULL, 0),
- SND_SOC_DAPM_PGA("HF Right PGA",
- TWL6040_REG_HFRCTL, 1, 0, NULL, 0),
-
-};
-
-static const struct snd_soc_dapm_route intercon[] = {
- /* Capture path */
- {"Analog Left Capture Route", "Headset Mic", "HSMIC"},
- {"Analog Left Capture Route", "Main Mic", "MAINMIC"},
- {"Analog Left Capture Route", "Aux/FM Left", "AFML"},
-
- {"Analog Right Capture Route", "Headset Mic", "HSMIC"},
- {"Analog Right Capture Route", "Sub Mic", "SUBMIC"},
- {"Analog Right Capture Route", "Aux/FM Right", "AFMR"},
-
- {"MicAmpL", NULL, "Analog Left Capture Route"},
- {"MicAmpR", NULL, "Analog Right Capture Route"},
-
- {"ADC Left", NULL, "MicAmpL"},
- {"ADC Right", NULL, "MicAmpR"},
-
- /* AFM path */
- {"AFMAmpL", NULL, "AFML"},
- {"AFMAmpR", NULL, "AFMR"},
-
- {"HSDAC Left", NULL, "HSDAC Power"},
- {"HSDAC Right", NULL, "HSDAC Power"},
-
- {"Headset Left Playback", "HS DAC", "HSDAC Left"},
- {"Headset Left Playback", "Line-In amp", "AFMAmpL"},
-
- {"Headset Right Playback", "HS DAC", "HSDAC Right"},
- {"Headset Right Playback", "Line-In amp", "AFMAmpR"},
-
- {"HS Left Driver", NULL, "Headset Left Playback"},
- {"HS Right Driver", NULL, "Headset Right Playback"},
-
- {"HSOL", NULL, "HS Left Driver"},
- {"HSOR", NULL, "HS Right Driver"},
-
- /* Earphone playback path */
- {"Earphone Playback", "Switch", "HSDAC Left"},
- {"Earphone Driver", NULL, "Earphone Playback"},
- {"EP", NULL, "Earphone Driver"},
-
- {"Handsfree Left Playback", "HF DAC", "HFDAC Left"},
- {"Handsfree Left Playback", "Line-In amp", "AFMAmpL"},
-
- {"Handsfree Right Playback", "HF DAC", "HFDAC Right"},
- {"Handsfree Right Playback", "Line-In amp", "AFMAmpR"},
-
- {"HF Left PGA", NULL, "Handsfree Left Playback"},
- {"HF Right PGA", NULL, "Handsfree Right Playback"},
-
- {"HF Left Driver", NULL, "HF Left PGA"},
- {"HF Right Driver", NULL, "HF Right PGA"},
-
- {"HFL", NULL, "HF Left Driver"},
- {"HFR", NULL, "HF Right Driver"},
-
- {"AUXL Playback", "Switch", "HF Left PGA"},
- {"AUXR Playback", "Switch", "HF Right PGA"},
-
- {"AUXL", NULL, "AUXL Playback"},
- {"AUXR", NULL, "AUXR Playback"},
-
- /* Vibrator paths */
- {"Vibra Left Playback", "Audio PDM", "VIBRA DAC"},
- {"Vibra Right Playback", "Audio PDM", "VIBRA DAC"},
-
- {"Vibra Left Driver", NULL, "Vibra Left Playback"},
- {"Vibra Right Driver", NULL, "Vibra Right Playback"},
- {"Vibra Left Driver", NULL, "Vibra Left Control"},
- {"Vibra Right Driver", NULL, "Vibra Right Control"},
-
- {"VIBRAL", NULL, "Vibra Left Driver"},
- {"VIBRAR", NULL, "Vibra Right Driver"},
-};
-
-static int twl6040_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct twl6040 *twl6040 = codec->control_data;
- struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- if (priv->codec_powered)
- break;
-
- ret = twl6040_power(twl6040, 1);
- if (ret)
- return ret;
-
- priv->codec_powered = 1;
-
- twl6040_restore_regs(codec);
-
- /* Set external boost GPO */
- twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02);
- break;
- case SND_SOC_BIAS_OFF:
- if (!priv->codec_powered)
- break;
-
- twl6040_power(twl6040, 0);
- priv->codec_powered = 0;
- break;
- }
-
- codec->dapm.bias_level = level;
-
- return 0;
-}
-
-static int twl6040_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
-
- snd_pcm_hw_constraint_list(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- &sysclk_constraints[priv->pll_power_mode]);
-
- return 0;
-}
-
-static int twl6040_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
- int rate;
-
- rate = params_rate(params);
- switch (rate) {
- case 11250:
- case 22500:
- case 44100:
- case 88200:
- /* These rates are not supported when HPPLL is in use */
- if (unlikely(priv->pll == TWL6040_SYSCLK_SEL_HPPLL)) {
- dev_err(codec->dev, "HPPLL does not support rate %d\n",
- rate);
- return -EINVAL;
- }
- priv->sysclk = 17640000;
- break;
- case 8000:
- case 16000:
- case 32000:
- case 48000:
- case 96000:
- priv->sysclk = 19200000;
- break;
- default:
- dev_err(codec->dev, "unsupported rate %d\n", rate);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int twl6040_prepare(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct twl6040 *twl6040 = codec->control_data;
- struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- if (!priv->sysclk) {
- dev_err(codec->dev,
- "no mclk configured, call set_sysclk() on init\n");
- return -EINVAL;
- }
-
- ret = twl6040_set_pll(twl6040, priv->pll, priv->clk_in, priv->sysclk);
- if (ret) {
- dev_err(codec->dev, "Can not set PLL (%d)\n", ret);
- return -EPERM;
- }
-
- return 0;
-}
-
-static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
-
- switch (clk_id) {
- case TWL6040_SYSCLK_SEL_LPPLL:
- case TWL6040_SYSCLK_SEL_HPPLL:
- priv->pll = clk_id;
- priv->clk_in = freq;
- break;
- default:
- dev_err(codec->dev, "unknown clk_id %d\n", clk_id);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static const struct snd_soc_dai_ops twl6040_dai_ops = {
- .startup = twl6040_startup,
- .hw_params = twl6040_hw_params,
- .prepare = twl6040_prepare,
- .set_sysclk = twl6040_set_dai_sysclk,
-};
-
-static struct snd_soc_dai_driver twl6040_dai[] = {
-{
- .name = "twl6040-legacy",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 5,
- .rates = TWL6040_RATES,
- .formats = TWL6040_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = TWL6040_RATES,
- .formats = TWL6040_FORMATS,
- },
- .ops = &twl6040_dai_ops,
-},
-{
- .name = "twl6040-ul",
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = TWL6040_RATES,
- .formats = TWL6040_FORMATS,
- },
- .ops = &twl6040_dai_ops,
-},
-{
- .name = "twl6040-dl1",
- .playback = {
- .stream_name = "Headset Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = TWL6040_RATES,
- .formats = TWL6040_FORMATS,
- },
- .ops = &twl6040_dai_ops,
-},
-{
- .name = "twl6040-dl2",
- .playback = {
- .stream_name = "Handsfree Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = TWL6040_RATES,
- .formats = TWL6040_FORMATS,
- },
- .ops = &twl6040_dai_ops,
-},
-{
- .name = "twl6040-vib",
- .playback = {
- .stream_name = "Vibra Playback",
- .channels_min = 1,
- .channels_max = 1,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .formats = TWL6040_FORMATS,
- },
- .ops = &twl6040_dai_ops,
-},
-};
-
-#ifdef CONFIG_PM
-static int twl6040_suspend(struct snd_soc_codec *codec)
-{
- twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int twl6040_resume(struct snd_soc_codec *codec)
-{
- twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- twl6040_set_bias_level(codec, codec->dapm.suspend_bias_level);
-
- return 0;
-}
-#else
-#define twl6040_suspend NULL
-#define twl6040_resume NULL
-#endif
-
-static int twl6040_probe(struct snd_soc_codec *codec)
-{
- struct twl6040_data *priv;
- struct twl6040_codec_data *pdata = dev_get_platdata(codec->dev);
- struct platform_device *pdev = container_of(codec->dev,
- struct platform_device, dev);
- int ret = 0;
-
- priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL);
- if (priv == NULL)
- return -ENOMEM;
- snd_soc_codec_set_drvdata(codec, priv);
-
- priv->codec = codec;
- codec->control_data = dev_get_drvdata(codec->dev->parent);
-
- if (pdata && pdata->hs_left_step && pdata->hs_right_step) {
- priv->hs_left_step = pdata->hs_left_step;
- priv->hs_right_step = pdata->hs_right_step;
- } else {
- priv->hs_left_step = 1;
- priv->hs_right_step = 1;
- }
-
- if (pdata && pdata->hf_left_step && pdata->hf_right_step) {
- priv->hf_left_step = pdata->hf_left_step;
- priv->hf_right_step = pdata->hf_right_step;
- } else {
- priv->hf_left_step = 1;
- priv->hf_right_step = 1;
- }
-
- priv->plug_irq = platform_get_irq(pdev, 0);
- if (priv->plug_irq < 0) {
- dev_err(codec->dev, "invalid irq\n");
- ret = -EINVAL;
- goto work_err;
- }
-
- priv->workqueue = alloc_workqueue("twl6040-codec", 0, 0);
- if (!priv->workqueue) {
- ret = -ENOMEM;
- goto work_err;
- }
-
- INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work);
- INIT_DELAYED_WORK(&priv->headset.work, twl6040_pga_hs_work);
- INIT_DELAYED_WORK(&priv->handsfree.work, twl6040_pga_hf_work);
-
- mutex_init(&priv->mutex);
-
- init_completion(&priv->headset.ramp_done);
- init_completion(&priv->handsfree.ramp_done);
-
- ret = request_threaded_irq(priv->plug_irq, NULL, twl6040_audio_handler,
- 0, "twl6040_irq_plug", codec);
- if (ret) {
- dev_err(codec->dev, "PLUG IRQ request failed: %d\n", ret);
- goto plugirq_err;
- }
-
- twl6040_init_chip(codec);
-
- /* power on device */
- ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- if (!ret)
- return 0;
-
- /* Error path */
- free_irq(priv->plug_irq, codec);
-plugirq_err:
- destroy_workqueue(priv->workqueue);
-work_err:
- kfree(priv);
- return ret;
-}
-
-static int twl6040_remove(struct snd_soc_codec *codec)
-{
- struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
-
- twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
- free_irq(priv->plug_irq, codec);
- destroy_workqueue(priv->workqueue);
- kfree(priv);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_twl6040 = {
- .probe = twl6040_probe,
- .remove = twl6040_remove,
- .suspend = twl6040_suspend,
- .resume = twl6040_resume,
- .read = twl6040_read_reg_cache,
- .write = twl6040_write,
- .set_bias_level = twl6040_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(twl6040_reg),
- .reg_word_size = sizeof(u8),
- .reg_cache_default = twl6040_reg,
- .ignore_pmdown_time = true,
-
- .controls = twl6040_snd_controls,
- .num_controls = ARRAY_SIZE(twl6040_snd_controls),
- .dapm_widgets = twl6040_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets),
- .dapm_routes = intercon,
- .num_dapm_routes = ARRAY_SIZE(intercon),
-};
-
-static int __devinit twl6040_codec_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl6040,
- twl6040_dai, ARRAY_SIZE(twl6040_dai));
-}
-
-static int __devexit twl6040_codec_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver twl6040_codec_driver = {
- .driver = {
- .name = "twl6040-codec",
- .owner = THIS_MODULE,
- },
- .probe = twl6040_codec_probe,
- .remove = __devexit_p(twl6040_codec_remove),
-};
-
-module_platform_driver(twl6040_codec_driver);
-
-MODULE_DESCRIPTION("ASoC TWL6040 codec driver");
-MODULE_AUTHOR("Misael Lopez Cruz");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/twl6040.h b/ANDROID_3.4.5/sound/soc/codecs/twl6040.h
deleted file mode 100644
index 0611406c..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/twl6040.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * ALSA SoC TWL6040 codec driver
- *
- * Author: Misael Lopez Cruz <x0052729@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __TWL6040_H__
-#define __TWL6040_H__
-
-enum twl6040_trim {
- TWL6040_TRIM_TRIM1 = 0,
- TWL6040_TRIM_TRIM2,
- TWL6040_TRIM_TRIM3,
- TWL6040_TRIM_HSOTRIM,
- TWL6040_TRIM_HFOTRIM,
- TWL6040_TRIM_INVAL,
-};
-
-#define TWL6040_HSF_TRIM_LEFT(x) (x & 0x0f)
-#define TWL6040_HSF_TRIM_RIGHT(x) ((x >> 4) & 0x0f)
-
-int twl6040_get_dl1_gain(struct snd_soc_codec *codec);
-void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
- struct snd_soc_jack *jack, int report);
-int twl6040_get_clk_id(struct snd_soc_codec *codec);
-int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim);
-int twl6040_get_hs_step_size(struct snd_soc_codec *codec);
-
-#endif /* End of __TWL6040_H__ */
diff --git a/ANDROID_3.4.5/sound/soc/codecs/uda134x.c b/ANDROID_3.4.5/sound/soc/codecs/uda134x.c
deleted file mode 100644
index 797b0dde..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/uda134x.c
+++ /dev/null
@@ -1,631 +0,0 @@
-/*
- * uda134x.c -- UDA134X ALSA SoC Codec driver
- *
- * Modifications by Christian Pellegrin <chripell@evolware.org>
- *
- * Copyright 2007 Dension Audio Systems Ltd.
- * Author: Zoltan Devai
- *
- * Based on the WM87xx drivers by Liam Girdwood and Richard Purdie
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-
-#include <sound/uda134x.h>
-#include <sound/l3.h>
-
-#include "uda134x.h"
-
-
-#define UDA134X_RATES SNDRV_PCM_RATE_8000_48000
-#define UDA134X_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
- SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE)
-
-struct uda134x_priv {
- int sysclk;
- int dai_fmt;
-
- struct snd_pcm_substream *master_substream;
- struct snd_pcm_substream *slave_substream;
-};
-
-/* In-data addresses are hard-coded into the reg-cache values */
-static const char uda134x_reg[UDA134X_REGS_NUM] = {
- /* Extended address registers */
- 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
- /* Status, data regs */
- 0x00, 0x83, 0x00, 0x40, 0x80, 0xC0, 0x00,
-};
-
-/*
- * The codec has no support for reading its registers except for peak level...
- */
-static inline unsigned int uda134x_read_reg_cache(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- u8 *cache = codec->reg_cache;
-
- if (reg >= UDA134X_REGS_NUM)
- return -1;
- return cache[reg];
-}
-
-/*
- * Write the register cache
- */
-static inline void uda134x_write_reg_cache(struct snd_soc_codec *codec,
- u8 reg, unsigned int value)
-{
- u8 *cache = codec->reg_cache;
-
- if (reg >= UDA134X_REGS_NUM)
- return;
- cache[reg] = value;
-}
-
-/*
- * Write to the uda134x registers
- *
- */
-static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- int ret;
- u8 addr;
- u8 data = value;
- struct uda134x_platform_data *pd = codec->control_data;
-
- pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value);
-
- if (reg >= UDA134X_REGS_NUM) {
- printk(KERN_ERR "%s unknown register: reg: %u",
- __func__, reg);
- return -EINVAL;
- }
-
- uda134x_write_reg_cache(codec, reg, value);
-
- switch (reg) {
- case UDA134X_STATUS0:
- case UDA134X_STATUS1:
- addr = UDA134X_STATUS_ADDR;
- break;
- case UDA134X_DATA000:
- case UDA134X_DATA001:
- case UDA134X_DATA010:
- case UDA134X_DATA011:
- addr = UDA134X_DATA0_ADDR;
- break;
- case UDA134X_DATA1:
- addr = UDA134X_DATA1_ADDR;
- break;
- default:
- /* It's an extended address register */
- addr = (reg | UDA134X_EXTADDR_PREFIX);
-
- ret = l3_write(&pd->l3,
- UDA134X_DATA0_ADDR, &addr, 1);
- if (ret != 1)
- return -EIO;
-
- addr = UDA134X_DATA0_ADDR;
- data = (value | UDA134X_EXTDATA_PREFIX);
- break;
- }
-
- ret = l3_write(&pd->l3,
- addr, &data, 1);
- if (ret != 1)
- return -EIO;
-
- return 0;
-}
-
-static inline void uda134x_reset(struct snd_soc_codec *codec)
-{
- u8 reset_reg = uda134x_read_reg_cache(codec, UDA134X_STATUS0);
- uda134x_write(codec, UDA134X_STATUS0, reset_reg | (1<<6));
- msleep(1);
- uda134x_write(codec, UDA134X_STATUS0, reset_reg & ~(1<<6));
-}
-
-static int uda134x_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u8 mute_reg = uda134x_read_reg_cache(codec, UDA134X_DATA010);
-
- pr_debug("%s mute: %d\n", __func__, mute);
-
- if (mute)
- mute_reg |= (1<<2);
- else
- mute_reg &= ~(1<<2);
-
- uda134x_write(codec, UDA134X_DATA010, mute_reg);
-
- return 0;
-}
-
-static int uda134x_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec =rtd->codec;
- struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
- struct snd_pcm_runtime *master_runtime;
-
- if (uda134x->master_substream) {
- master_runtime = uda134x->master_substream->runtime;
-
- pr_debug("%s constraining to %d bits at %d\n", __func__,
- master_runtime->sample_bits,
- master_runtime->rate);
-
- snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_RATE,
- master_runtime->rate,
- master_runtime->rate);
-
- snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
- master_runtime->sample_bits,
- master_runtime->sample_bits);
-
- uda134x->slave_substream = substream;
- } else
- uda134x->master_substream = substream;
-
- return 0;
-}
-
-static void uda134x_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
-
- if (uda134x->master_substream == substream)
- uda134x->master_substream = uda134x->slave_substream;
-
- uda134x->slave_substream = NULL;
-}
-
-static int uda134x_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
- u8 hw_params;
-
- if (substream == uda134x->slave_substream) {
- pr_debug("%s ignoring hw_params for slave substream\n",
- __func__);
- return 0;
- }
-
- hw_params = uda134x_read_reg_cache(codec, UDA134X_STATUS0);
- hw_params &= STATUS0_SYSCLK_MASK;
- hw_params &= STATUS0_DAIFMT_MASK;
-
- pr_debug("%s sysclk: %d, rate:%d\n", __func__,
- uda134x->sysclk, params_rate(params));
-
- /* set SYSCLK / fs ratio */
- switch (uda134x->sysclk / params_rate(params)) {
- case 512:
- break;
- case 384:
- hw_params |= (1<<4);
- break;
- case 256:
- hw_params |= (1<<5);
- break;
- default:
- printk(KERN_ERR "%s unsupported fs\n", __func__);
- return -EINVAL;
- }
-
- pr_debug("%s dai_fmt: %d, params_format:%d\n", __func__,
- uda134x->dai_fmt, params_format(params));
-
- /* set DAI format and word length */
- switch (uda134x->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- hw_params |= (1<<1);
- break;
- case SNDRV_PCM_FORMAT_S18_3LE:
- hw_params |= (1<<2);
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- hw_params |= ((1<<2) | (1<<1));
- break;
- default:
- printk(KERN_ERR "%s unsupported format (right)\n",
- __func__);
- return -EINVAL;
- }
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- hw_params |= (1<<3);
- break;
- default:
- printk(KERN_ERR "%s unsupported format\n", __func__);
- return -EINVAL;
- }
-
- uda134x_write(codec, UDA134X_STATUS0, hw_params);
-
- return 0;
-}
-
-static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
-
- pr_debug("%s clk_id: %d, freq: %u, dir: %d\n", __func__,
- clk_id, freq, dir);
-
- /* Anything between 256fs*8Khz and 512fs*48Khz should be acceptable
- because the codec is slave. Of course limitations of the clock
- master (the IIS controller) apply.
- We'll error out on set_hw_params if it's not OK */
- if ((freq >= (256 * 8000)) && (freq <= (512 * 48000))) {
- uda134x->sysclk = freq;
- return 0;
- }
-
- printk(KERN_ERR "%s unsupported sysclk\n", __func__);
- return -EINVAL;
-}
-
-static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
-
- pr_debug("%s fmt: %08X\n", __func__, fmt);
-
- /* codec supports only full slave mode */
- if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
- printk(KERN_ERR "%s unsupported slave mode\n", __func__);
- return -EINVAL;
- }
-
- /* no support for clock inversion */
- if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) {
- printk(KERN_ERR "%s unsupported clock inversion\n", __func__);
- return -EINVAL;
- }
-
- /* We can't setup DAI format here as it depends on the word bit num */
- /* so let's just store the value for later */
- uda134x->dai_fmt = fmt;
-
- return 0;
-}
-
-static int uda134x_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- u8 reg;
- struct uda134x_platform_data *pd = codec->control_data;
- int i;
- u8 *cache = codec->reg_cache;
-
- pr_debug("%s bias level %d\n", __func__, level);
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- /* ADC, DAC on */
- switch (pd->model) {
- case UDA134X_UDA1340:
- case UDA134X_UDA1344:
- case UDA134X_UDA1345:
- reg = uda134x_read_reg_cache(codec, UDA134X_DATA011);
- uda134x_write(codec, UDA134X_DATA011, reg | 0x03);
- break;
- case UDA134X_UDA1341:
- reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
- uda134x_write(codec, UDA134X_STATUS1, reg | 0x03);
- break;
- default:
- printk(KERN_ERR "UDA134X SoC codec: "
- "unsupported model %d\n", pd->model);
- return -EINVAL;
- }
- break;
- case SND_SOC_BIAS_PREPARE:
- /* power on */
- if (pd->power) {
- pd->power(1);
- /* Sync reg_cache with the hardware */
- for (i = 0; i < ARRAY_SIZE(uda134x_reg); i++)
- codec->driver->write(codec, i, *cache++);
- }
- break;
- case SND_SOC_BIAS_STANDBY:
- /* ADC, DAC power off */
- switch (pd->model) {
- case UDA134X_UDA1340:
- case UDA134X_UDA1344:
- case UDA134X_UDA1345:
- reg = uda134x_read_reg_cache(codec, UDA134X_DATA011);
- uda134x_write(codec, UDA134X_DATA011, reg & ~(0x03));
- break;
- case UDA134X_UDA1341:
- reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
- uda134x_write(codec, UDA134X_STATUS1, reg & ~(0x03));
- break;
- default:
- printk(KERN_ERR "UDA134X SoC codec: "
- "unsupported model %d\n", pd->model);
- return -EINVAL;
- }
- break;
- case SND_SOC_BIAS_OFF:
- /* power off */
- if (pd->power)
- pd->power(0);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-static const char *uda134x_dsp_setting[] = {"Flat", "Minimum1",
- "Minimum2", "Maximum"};
-static const char *uda134x_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
-static const char *uda134x_mixmode[] = {"Differential", "Analog1",
- "Analog2", "Both"};
-
-static const struct soc_enum uda134x_mixer_enum[] = {
-SOC_ENUM_SINGLE(UDA134X_DATA010, 0, 0x04, uda134x_dsp_setting),
-SOC_ENUM_SINGLE(UDA134X_DATA010, 3, 0x04, uda134x_deemph),
-SOC_ENUM_SINGLE(UDA134X_EA010, 0, 0x04, uda134x_mixmode),
-};
-
-static const struct snd_kcontrol_new uda1341_snd_controls[] = {
-SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1),
-SOC_SINGLE("Capture Volume", UDA134X_EA010, 2, 0x07, 0),
-SOC_SINGLE("Analog1 Volume", UDA134X_EA000, 0, 0x1F, 1),
-SOC_SINGLE("Analog2 Volume", UDA134X_EA001, 0, 0x1F, 1),
-
-SOC_SINGLE("Mic Sensitivity", UDA134X_EA010, 2, 7, 0),
-SOC_SINGLE("Mic Volume", UDA134X_EA101, 0, 0x1F, 0),
-
-SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001, 2, 0xF, 0),
-SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001, 0, 3, 0),
-
-SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum[0]),
-SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
-SOC_ENUM("Input Mux", uda134x_mixer_enum[2]),
-
-SOC_SINGLE("AGC Switch", UDA134X_EA100, 4, 1, 0),
-SOC_SINGLE("AGC Target Volume", UDA134X_EA110, 0, 0x03, 1),
-SOC_SINGLE("AGC Timing", UDA134X_EA110, 2, 0x07, 0),
-
-SOC_SINGLE("DAC +6dB Switch", UDA134X_STATUS1, 6, 1, 0),
-SOC_SINGLE("ADC +6dB Switch", UDA134X_STATUS1, 5, 1, 0),
-SOC_SINGLE("ADC Polarity Switch", UDA134X_STATUS1, 4, 1, 0),
-SOC_SINGLE("DAC Polarity Switch", UDA134X_STATUS1, 3, 1, 0),
-SOC_SINGLE("Double Speed Playback Switch", UDA134X_STATUS1, 2, 1, 0),
-SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new uda1340_snd_controls[] = {
-SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1),
-
-SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001, 2, 0xF, 0),
-SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001, 0, 3, 0),
-
-SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum[0]),
-SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
-
-SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new uda1345_snd_controls[] = {
-SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1),
-
-SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
-
-SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
-};
-
-static const struct snd_soc_dai_ops uda134x_dai_ops = {
- .startup = uda134x_startup,
- .shutdown = uda134x_shutdown,
- .hw_params = uda134x_hw_params,
- .digital_mute = uda134x_mute,
- .set_sysclk = uda134x_set_dai_sysclk,
- .set_fmt = uda134x_set_dai_fmt,
-};
-
-static struct snd_soc_dai_driver uda134x_dai = {
- .name = "uda134x-hifi",
- /* playback capabilities */
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = UDA134X_RATES,
- .formats = UDA134X_FORMATS,
- },
- /* capture capabilities */
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = UDA134X_RATES,
- .formats = UDA134X_FORMATS,
- },
- /* pcm operations */
- .ops = &uda134x_dai_ops,
-};
-
-static int uda134x_soc_probe(struct snd_soc_codec *codec)
-{
- struct uda134x_priv *uda134x;
- struct uda134x_platform_data *pd = codec->card->dev->platform_data;
-
- int ret;
-
- printk(KERN_INFO "UDA134X SoC Audio Codec\n");
-
- if (!pd) {
- printk(KERN_ERR "UDA134X SoC codec: "
- "missing L3 bitbang function\n");
- return -ENODEV;
- }
-
- switch (pd->model) {
- case UDA134X_UDA1340:
- case UDA134X_UDA1341:
- case UDA134X_UDA1344:
- case UDA134X_UDA1345:
- break;
- default:
- printk(KERN_ERR "UDA134X SoC codec: "
- "unsupported model %d\n",
- pd->model);
- return -EINVAL;
- }
-
- uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL);
- if (uda134x == NULL)
- return -ENOMEM;
- snd_soc_codec_set_drvdata(codec, uda134x);
-
- codec->control_data = pd;
-
- if (pd->power)
- pd->power(1);
-
- uda134x_reset(codec);
-
- if (pd->is_powered_on_standby)
- uda134x_set_bias_level(codec, SND_SOC_BIAS_ON);
- else
- uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- switch (pd->model) {
- case UDA134X_UDA1340:
- case UDA134X_UDA1344:
- ret = snd_soc_add_codec_controls(codec, uda1340_snd_controls,
- ARRAY_SIZE(uda1340_snd_controls));
- break;
- case UDA134X_UDA1341:
- ret = snd_soc_add_codec_controls(codec, uda1341_snd_controls,
- ARRAY_SIZE(uda1341_snd_controls));
- break;
- case UDA134X_UDA1345:
- ret = snd_soc_add_codec_controls(codec, uda1345_snd_controls,
- ARRAY_SIZE(uda1345_snd_controls));
- break;
- default:
- printk(KERN_ERR "%s unknown codec type: %d",
- __func__, pd->model);
- kfree(uda134x);
- return -EINVAL;
- }
-
- if (ret < 0) {
- printk(KERN_ERR "UDA134X: failed to register controls\n");
- kfree(uda134x);
- return ret;
- }
-
- return 0;
-}
-
-/* power down chip */
-static int uda134x_soc_remove(struct snd_soc_codec *codec)
-{
- struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
-
- uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- kfree(uda134x);
- return 0;
-}
-
-#if defined(CONFIG_PM)
-static int uda134x_soc_suspend(struct snd_soc_codec *codec)
-{
- uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int uda134x_soc_resume(struct snd_soc_codec *codec)
-{
- uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
- uda134x_set_bias_level(codec, SND_SOC_BIAS_ON);
- return 0;
-}
-#else
-#define uda134x_soc_suspend NULL
-#define uda134x_soc_resume NULL
-#endif /* CONFIG_PM */
-
-static struct snd_soc_codec_driver soc_codec_dev_uda134x = {
- .probe = uda134x_soc_probe,
- .remove = uda134x_soc_remove,
- .suspend = uda134x_soc_suspend,
- .resume = uda134x_soc_resume,
- .reg_cache_size = sizeof(uda134x_reg),
- .reg_word_size = sizeof(u8),
- .reg_cache_default = uda134x_reg,
- .reg_cache_step = 1,
- .read = uda134x_read_reg_cache,
- .write = uda134x_write,
- .set_bias_level = uda134x_set_bias_level,
-};
-
-static int __devinit uda134x_codec_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev,
- &soc_codec_dev_uda134x, &uda134x_dai, 1);
-}
-
-static int __devexit uda134x_codec_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver uda134x_codec_driver = {
- .driver = {
- .name = "uda134x-codec",
- .owner = THIS_MODULE,
- },
- .probe = uda134x_codec_probe,
- .remove = __devexit_p(uda134x_codec_remove),
-};
-
-module_platform_driver(uda134x_codec_driver);
-
-MODULE_DESCRIPTION("UDA134X ALSA soc codec driver");
-MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/uda134x.h b/ANDROID_3.4.5/sound/soc/codecs/uda134x.h
deleted file mode 100644
index 9faae069..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/uda134x.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef _UDA134X_CODEC_H
-#define _UDA134X_CODEC_H
-
-#define UDA134X_L3ADDR 5
-#define UDA134X_DATA0_ADDR ((UDA134X_L3ADDR << 2) | 0)
-#define UDA134X_DATA1_ADDR ((UDA134X_L3ADDR << 2) | 1)
-#define UDA134X_STATUS_ADDR ((UDA134X_L3ADDR << 2) | 2)
-
-#define UDA134X_EXTADDR_PREFIX 0xC0
-#define UDA134X_EXTDATA_PREFIX 0xE0
-
-/* UDA134X registers */
-#define UDA134X_EA000 0
-#define UDA134X_EA001 1
-#define UDA134X_EA010 2
-#define UDA134X_EA011 3
-#define UDA134X_EA100 4
-#define UDA134X_EA101 5
-#define UDA134X_EA110 6
-#define UDA134X_EA111 7
-#define UDA134X_STATUS0 8
-#define UDA134X_STATUS1 9
-#define UDA134X_DATA000 10
-#define UDA134X_DATA001 11
-#define UDA134X_DATA010 12
-#define UDA134X_DATA011 13
-#define UDA134X_DATA1 14
-
-#define UDA134X_REGS_NUM 15
-
-#define STATUS0_DAIFMT_MASK (~(7<<1))
-#define STATUS0_SYSCLK_MASK (~(3<<4))
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/uda1380.c b/ANDROID_3.4.5/sound/soc/codecs/uda1380.c
deleted file mode 100644
index 4f1b23d7..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/uda1380.c
+++ /dev/null
@@ -1,864 +0,0 @@
-/*
- * uda1380.c - Philips UDA1380 ALSA SoC audio driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Copyright (c) 2007-2009 Philipp Zabel <philipp.zabel@gmail.com>
- *
- * Modified by Richard Purdie <richard@openedhand.com> to fit into SoC
- * codec model.
- *
- * Copyright (c) 2005 Giorgio Padrin <giorgio@mandarinlogiq.org>
- * Copyright 2005 Openedhand Ltd.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/workqueue.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-#include <sound/tlv.h>
-#include <sound/uda1380.h>
-
-#include "uda1380.h"
-
-/* codec private data */
-struct uda1380_priv {
- struct snd_soc_codec *codec;
- unsigned int dac_clk;
- struct work_struct work;
- void *control_data;
-};
-
-/*
- * uda1380 register cache
- */
-static const u16 uda1380_reg[UDA1380_CACHEREGNUM] = {
- 0x0502, 0x0000, 0x0000, 0x3f3f,
- 0x0202, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0xff00, 0x0000, 0x4800,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x8000, 0x0002, 0x0000,
-};
-
-static unsigned long uda1380_cache_dirty;
-
-/*
- * read uda1380 register cache
- */
-static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- u16 *cache = codec->reg_cache;
- if (reg == UDA1380_RESET)
- return 0;
- if (reg >= UDA1380_CACHEREGNUM)
- return -1;
- return cache[reg];
-}
-
-/*
- * write uda1380 register cache
- */
-static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec,
- u16 reg, unsigned int value)
-{
- u16 *cache = codec->reg_cache;
-
- if (reg >= UDA1380_CACHEREGNUM)
- return;
- if ((reg >= 0x10) && (cache[reg] != value))
- set_bit(reg - 0x10, &uda1380_cache_dirty);
- cache[reg] = value;
-}
-
-/*
- * write to the UDA1380 register space
- */
-static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- u8 data[3];
-
- /* data is
- * data[0] is register offset
- * data[1] is MS byte
- * data[2] is LS byte
- */
- data[0] = reg;
- data[1] = (value & 0xff00) >> 8;
- data[2] = value & 0x00ff;
-
- uda1380_write_reg_cache(codec, reg, value);
-
- /* the interpolator & decimator regs must only be written when the
- * codec DAI is active.
- */
- if (!codec->active && (reg >= UDA1380_MVOL))
- return 0;
- pr_debug("uda1380: hw write %x val %x\n", reg, value);
- if (codec->hw_write(codec->control_data, data, 3) == 3) {
- unsigned int val;
- i2c_master_send(codec->control_data, data, 1);
- i2c_master_recv(codec->control_data, data, 2);
- val = (data[0]<<8) | data[1];
- if (val != value) {
- pr_debug("uda1380: READ BACK VAL %x\n",
- (data[0]<<8) | data[1]);
- return -EIO;
- }
- if (reg >= 0x10)
- clear_bit(reg - 0x10, &uda1380_cache_dirty);
- return 0;
- } else
- return -EIO;
-}
-
-static void uda1380_sync_cache(struct snd_soc_codec *codec)
-{
- int reg;
- u8 data[3];
- u16 *cache = codec->reg_cache;
-
- /* Sync reg_cache with the hardware */
- for (reg = 0; reg < UDA1380_MVOL; reg++) {
- data[0] = reg;
- data[1] = (cache[reg] & 0xff00) >> 8;
- data[2] = cache[reg] & 0x00ff;
- if (codec->hw_write(codec->control_data, data, 3) != 3)
- dev_err(codec->dev, "%s: write to reg 0x%x failed\n",
- __func__, reg);
- }
-}
-
-static int uda1380_reset(struct snd_soc_codec *codec)
-{
- struct uda1380_platform_data *pdata = codec->dev->platform_data;
-
- if (gpio_is_valid(pdata->gpio_reset)) {
- gpio_set_value(pdata->gpio_reset, 1);
- mdelay(1);
- gpio_set_value(pdata->gpio_reset, 0);
- } else {
- u8 data[3];
-
- data[0] = UDA1380_RESET;
- data[1] = 0;
- data[2] = 0;
-
- if (codec->hw_write(codec->control_data, data, 3) != 3) {
- dev_err(codec->dev, "%s: failed\n", __func__);
- return -EIO;
- }
- }
-
- return 0;
-}
-
-static void uda1380_flush_work(struct work_struct *work)
-{
- struct uda1380_priv *uda1380 = container_of(work, struct uda1380_priv, work);
- struct snd_soc_codec *uda1380_codec = uda1380->codec;
- int bit, reg;
-
- for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
- reg = 0x10 + bit;
- pr_debug("uda1380: flush reg %x val %x:\n", reg,
- uda1380_read_reg_cache(uda1380_codec, reg));
- uda1380_write(uda1380_codec, reg,
- uda1380_read_reg_cache(uda1380_codec, reg));
- clear_bit(bit, &uda1380_cache_dirty);
- }
-
-}
-
-/* declarations of ALSA reg_elem_REAL controls */
-static const char *uda1380_deemp[] = {
- "None",
- "32kHz",
- "44.1kHz",
- "48kHz",
- "96kHz",
-};
-static const char *uda1380_input_sel[] = {
- "Line",
- "Mic + Line R",
- "Line L",
- "Mic",
-};
-static const char *uda1380_output_sel[] = {
- "DAC",
- "Analog Mixer",
-};
-static const char *uda1380_spf_mode[] = {
- "Flat",
- "Minimum1",
- "Minimum2",
- "Maximum"
-};
-static const char *uda1380_capture_sel[] = {
- "ADC",
- "Digital Mixer"
-};
-static const char *uda1380_sel_ns[] = {
- "3rd-order",
- "5th-order"
-};
-static const char *uda1380_mix_control[] = {
- "off",
- "PCM only",
- "before sound processing",
- "after sound processing"
-};
-static const char *uda1380_sdet_setting[] = {
- "3200",
- "4800",
- "9600",
- "19200"
-};
-static const char *uda1380_os_setting[] = {
- "single-speed",
- "double-speed (no mixing)",
- "quad-speed (no mixing)"
-};
-
-static const struct soc_enum uda1380_deemp_enum[] = {
- SOC_ENUM_SINGLE(UDA1380_DEEMP, 8, 5, uda1380_deemp),
- SOC_ENUM_SINGLE(UDA1380_DEEMP, 0, 5, uda1380_deemp),
-};
-static const struct soc_enum uda1380_input_sel_enum =
- SOC_ENUM_SINGLE(UDA1380_ADC, 2, 4, uda1380_input_sel); /* SEL_MIC, SEL_LNA */
-static const struct soc_enum uda1380_output_sel_enum =
- SOC_ENUM_SINGLE(UDA1380_PM, 7, 2, uda1380_output_sel); /* R02_EN_AVC */
-static const struct soc_enum uda1380_spf_enum =
- SOC_ENUM_SINGLE(UDA1380_MODE, 14, 4, uda1380_spf_mode); /* M */
-static const struct soc_enum uda1380_capture_sel_enum =
- SOC_ENUM_SINGLE(UDA1380_IFACE, 6, 2, uda1380_capture_sel); /* SEL_SOURCE */
-static const struct soc_enum uda1380_sel_ns_enum =
- SOC_ENUM_SINGLE(UDA1380_MIXER, 14, 2, uda1380_sel_ns); /* SEL_NS */
-static const struct soc_enum uda1380_mix_enum =
- SOC_ENUM_SINGLE(UDA1380_MIXER, 12, 4, uda1380_mix_control); /* MIX, MIX_POS */
-static const struct soc_enum uda1380_sdet_enum =
- SOC_ENUM_SINGLE(UDA1380_MIXER, 4, 4, uda1380_sdet_setting); /* SD_VALUE */
-static const struct soc_enum uda1380_os_enum =
- SOC_ENUM_SINGLE(UDA1380_MIXER, 0, 3, uda1380_os_setting); /* OS */
-
-/*
- * from -48 dB in 1.5 dB steps (mute instead of -49.5 dB)
- */
-static DECLARE_TLV_DB_SCALE(amix_tlv, -4950, 150, 1);
-
-/*
- * from -78 dB in 1 dB steps (3 dB steps, really. LSB are ignored),
- * from -66 dB in 0.5 dB steps (2 dB steps, really) and
- * from -52 dB in 0.25 dB steps
- */
-static const unsigned int mvol_tlv[] = {
- TLV_DB_RANGE_HEAD(3),
- 0, 15, TLV_DB_SCALE_ITEM(-8200, 100, 1),
- 16, 43, TLV_DB_SCALE_ITEM(-6600, 50, 0),
- 44, 252, TLV_DB_SCALE_ITEM(-5200, 25, 0),
-};
-
-/*
- * from -72 dB in 1.5 dB steps (6 dB steps really),
- * from -66 dB in 0.75 dB steps (3 dB steps really),
- * from -60 dB in 0.5 dB steps (2 dB steps really) and
- * from -46 dB in 0.25 dB steps
- */
-static const unsigned int vc_tlv[] = {
- TLV_DB_RANGE_HEAD(4),
- 0, 7, TLV_DB_SCALE_ITEM(-7800, 150, 1),
- 8, 15, TLV_DB_SCALE_ITEM(-6600, 75, 0),
- 16, 43, TLV_DB_SCALE_ITEM(-6000, 50, 0),
- 44, 228, TLV_DB_SCALE_ITEM(-4600, 25, 0),
-};
-
-/* from 0 to 6 dB in 2 dB steps if SPF mode != flat */
-static DECLARE_TLV_DB_SCALE(tr_tlv, 0, 200, 0);
-
-/* from 0 to 24 dB in 2 dB steps, if SPF mode == maximum, otherwise cuts
- * off at 18 dB max) */
-static DECLARE_TLV_DB_SCALE(bb_tlv, 0, 200, 0);
-
-/* from -63 to 24 dB in 0.5 dB steps (-128...48) */
-static DECLARE_TLV_DB_SCALE(dec_tlv, -6400, 50, 1);
-
-/* from 0 to 24 dB in 3 dB steps */
-static DECLARE_TLV_DB_SCALE(pga_tlv, 0, 300, 0);
-
-/* from 0 to 30 dB in 2 dB steps */
-static DECLARE_TLV_DB_SCALE(vga_tlv, 0, 200, 0);
-
-static const struct snd_kcontrol_new uda1380_snd_controls[] = {
- SOC_DOUBLE_TLV("Analog Mixer Volume", UDA1380_AMIX, 0, 8, 44, 1, amix_tlv), /* AVCR, AVCL */
- SOC_DOUBLE_TLV("Master Playback Volume", UDA1380_MVOL, 0, 8, 252, 1, mvol_tlv), /* MVCL, MVCR */
- SOC_SINGLE_TLV("ADC Playback Volume", UDA1380_MIXVOL, 8, 228, 1, vc_tlv), /* VC2 */
- SOC_SINGLE_TLV("PCM Playback Volume", UDA1380_MIXVOL, 0, 228, 1, vc_tlv), /* VC1 */
- SOC_ENUM("Sound Processing Filter", uda1380_spf_enum), /* M */
- SOC_DOUBLE_TLV("Tone Control - Treble", UDA1380_MODE, 4, 12, 3, 0, tr_tlv), /* TRL, TRR */
- SOC_DOUBLE_TLV("Tone Control - Bass", UDA1380_MODE, 0, 8, 15, 0, bb_tlv), /* BBL, BBR */
-/**/ SOC_SINGLE("Master Playback Switch", UDA1380_DEEMP, 14, 1, 1), /* MTM */
- SOC_SINGLE("ADC Playback Switch", UDA1380_DEEMP, 11, 1, 1), /* MT2 from decimation filter */
- SOC_ENUM("ADC Playback De-emphasis", uda1380_deemp_enum[0]), /* DE2 */
- SOC_SINGLE("PCM Playback Switch", UDA1380_DEEMP, 3, 1, 1), /* MT1, from digital data input */
- SOC_ENUM("PCM Playback De-emphasis", uda1380_deemp_enum[1]), /* DE1 */
- SOC_SINGLE("DAC Polarity inverting Switch", UDA1380_MIXER, 15, 1, 0), /* DA_POL_INV */
- SOC_ENUM("Noise Shaper", uda1380_sel_ns_enum), /* SEL_NS */
- SOC_ENUM("Digital Mixer Signal Control", uda1380_mix_enum), /* MIX_POS, MIX */
- SOC_SINGLE("Silence Detector Switch", UDA1380_MIXER, 6, 1, 0), /* SDET_ON */
- SOC_ENUM("Silence Detector Setting", uda1380_sdet_enum), /* SD_VALUE */
- SOC_ENUM("Oversampling Input", uda1380_os_enum), /* OS */
- SOC_DOUBLE_S8_TLV("ADC Capture Volume", UDA1380_DEC, -128, 48, dec_tlv), /* ML_DEC, MR_DEC */
-/**/ SOC_SINGLE("ADC Capture Switch", UDA1380_PGA, 15, 1, 1), /* MT_ADC */
- SOC_DOUBLE_TLV("Line Capture Volume", UDA1380_PGA, 0, 8, 8, 0, pga_tlv), /* PGA_GAINCTRLL, PGA_GAINCTRLR */
- SOC_SINGLE("ADC Polarity inverting Switch", UDA1380_ADC, 12, 1, 0), /* ADCPOL_INV */
- SOC_SINGLE_TLV("Mic Capture Volume", UDA1380_ADC, 8, 15, 0, vga_tlv), /* VGA_CTRL */
- SOC_SINGLE("DC Filter Bypass Switch", UDA1380_ADC, 1, 1, 0), /* SKIP_DCFIL (before decimator) */
- SOC_SINGLE("DC Filter Enable Switch", UDA1380_ADC, 0, 1, 0), /* EN_DCFIL (at output of decimator) */
- SOC_SINGLE("AGC Timing", UDA1380_AGC, 8, 7, 0), /* TODO: enum, see table 62 */
- SOC_SINGLE("AGC Target level", UDA1380_AGC, 2, 3, 1), /* AGC_LEVEL */
- /* -5.5, -8, -11.5, -14 dBFS */
- SOC_SINGLE("AGC Switch", UDA1380_AGC, 0, 1, 0),
-};
-
-/* Input mux */
-static const struct snd_kcontrol_new uda1380_input_mux_control =
- SOC_DAPM_ENUM("Route", uda1380_input_sel_enum);
-
-/* Output mux */
-static const struct snd_kcontrol_new uda1380_output_mux_control =
- SOC_DAPM_ENUM("Route", uda1380_output_sel_enum);
-
-/* Capture mux */
-static const struct snd_kcontrol_new uda1380_capture_mux_control =
- SOC_DAPM_ENUM("Route", uda1380_capture_sel_enum);
-
-
-static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = {
- SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
- &uda1380_input_mux_control),
- SND_SOC_DAPM_MUX("Output Mux", SND_SOC_NOPM, 0, 0,
- &uda1380_output_mux_control),
- SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0,
- &uda1380_capture_mux_control),
- SND_SOC_DAPM_PGA("Left PGA", UDA1380_PM, 3, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Right PGA", UDA1380_PM, 1, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Mic LNA", UDA1380_PM, 4, 0, NULL, 0),
- SND_SOC_DAPM_ADC("Left ADC", "Left Capture", UDA1380_PM, 2, 0),
- SND_SOC_DAPM_ADC("Right ADC", "Right Capture", UDA1380_PM, 0, 0),
- SND_SOC_DAPM_INPUT("VINM"),
- SND_SOC_DAPM_INPUT("VINL"),
- SND_SOC_DAPM_INPUT("VINR"),
- SND_SOC_DAPM_MIXER("Analog Mixer", UDA1380_PM, 6, 0, NULL, 0),
- SND_SOC_DAPM_OUTPUT("VOUTLHP"),
- SND_SOC_DAPM_OUTPUT("VOUTRHP"),
- SND_SOC_DAPM_OUTPUT("VOUTL"),
- SND_SOC_DAPM_OUTPUT("VOUTR"),
- SND_SOC_DAPM_DAC("DAC", "Playback", UDA1380_PM, 10, 0),
- SND_SOC_DAPM_PGA("HeadPhone Driver", UDA1380_PM, 13, 0, NULL, 0),
-};
-
-static const struct snd_soc_dapm_route uda1380_dapm_routes[] = {
-
- /* output mux */
- {"HeadPhone Driver", NULL, "Output Mux"},
- {"VOUTR", NULL, "Output Mux"},
- {"VOUTL", NULL, "Output Mux"},
-
- {"Analog Mixer", NULL, "VINR"},
- {"Analog Mixer", NULL, "VINL"},
- {"Analog Mixer", NULL, "DAC"},
-
- {"Output Mux", "DAC", "DAC"},
- {"Output Mux", "Analog Mixer", "Analog Mixer"},
-
- /* {"DAC", "Digital Mixer", "I2S" } */
-
- /* headphone driver */
- {"VOUTLHP", NULL, "HeadPhone Driver"},
- {"VOUTRHP", NULL, "HeadPhone Driver"},
-
- /* input mux */
- {"Left ADC", NULL, "Input Mux"},
- {"Input Mux", "Mic", "Mic LNA"},
- {"Input Mux", "Mic + Line R", "Mic LNA"},
- {"Input Mux", "Line L", "Left PGA"},
- {"Input Mux", "Line", "Left PGA"},
-
- /* right input */
- {"Right ADC", "Mic + Line R", "Right PGA"},
- {"Right ADC", "Line", "Right PGA"},
-
- /* inputs */
- {"Mic LNA", NULL, "VINM"},
- {"Left PGA", NULL, "VINL"},
- {"Right PGA", NULL, "VINR"},
-};
-
-static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- int iface;
-
- /* set up DAI based upon fmt */
- iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
- iface &= ~(R01_SFORI_MASK | R01_SIM | R01_SFORO_MASK);
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= R01_SFORI_I2S | R01_SFORO_I2S;
- break;
- case SND_SOC_DAIFMT_LSB:
- iface |= R01_SFORI_LSB16 | R01_SFORO_LSB16;
- break;
- case SND_SOC_DAIFMT_MSB:
- iface |= R01_SFORI_MSB | R01_SFORO_MSB;
- }
-
- /* DATAI is slave only, so in single-link mode, this has to be slave */
- if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
- return -EINVAL;
-
- uda1380_write(codec, UDA1380_IFACE, iface);
-
- return 0;
-}
-
-static int uda1380_set_dai_fmt_playback(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- int iface;
-
- /* set up DAI based upon fmt */
- iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
- iface &= ~R01_SFORI_MASK;
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= R01_SFORI_I2S;
- break;
- case SND_SOC_DAIFMT_LSB:
- iface |= R01_SFORI_LSB16;
- break;
- case SND_SOC_DAIFMT_MSB:
- iface |= R01_SFORI_MSB;
- }
-
- /* DATAI is slave only, so this has to be slave */
- if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
- return -EINVAL;
-
- uda1380_write(codec, UDA1380_IFACE, iface);
-
- return 0;
-}
-
-static int uda1380_set_dai_fmt_capture(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- int iface;
-
- /* set up DAI based upon fmt */
- iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
- iface &= ~(R01_SIM | R01_SFORO_MASK);
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= R01_SFORO_I2S;
- break;
- case SND_SOC_DAIFMT_LSB:
- iface |= R01_SFORO_LSB16;
- break;
- case SND_SOC_DAIFMT_MSB:
- iface |= R01_SFORO_MSB;
- }
-
- if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)
- iface |= R01_SIM;
-
- uda1380_write(codec, UDA1380_IFACE, iface);
-
- return 0;
-}
-
-static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
- int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- uda1380_write_reg_cache(codec, UDA1380_MIXER,
- mixer & ~R14_SILENCE);
- schedule_work(&uda1380->work);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- uda1380_write_reg_cache(codec, UDA1380_MIXER,
- mixer | R14_SILENCE);
- schedule_work(&uda1380->work);
- break;
- }
- return 0;
-}
-
-static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
-
- /* set WSPLL power and divider if running from this clock */
- if (clk & R00_DAC_CLK) {
- int rate = params_rate(params);
- u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
- clk &= ~0x3; /* clear SEL_LOOP_DIV */
- switch (rate) {
- case 6250 ... 12500:
- clk |= 0x0;
- break;
- case 12501 ... 25000:
- clk |= 0x1;
- break;
- case 25001 ... 50000:
- clk |= 0x2;
- break;
- case 50001 ... 100000:
- clk |= 0x3;
- break;
- }
- uda1380_write(codec, UDA1380_PM, R02_PON_PLL | pm);
- }
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- clk |= R00_EN_DAC | R00_EN_INT;
- else
- clk |= R00_EN_ADC | R00_EN_DEC;
-
- uda1380_write(codec, UDA1380_CLK, clk);
- return 0;
-}
-
-static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
-
- /* shut down WSPLL power if running from this clock */
- if (clk & R00_DAC_CLK) {
- u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
- uda1380_write(codec, UDA1380_PM, ~R02_PON_PLL & pm);
- }
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- clk &= ~(R00_EN_DAC | R00_EN_INT);
- else
- clk &= ~(R00_EN_ADC | R00_EN_DEC);
-
- uda1380_write(codec, UDA1380_CLK, clk);
-}
-
-static int uda1380_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- int pm = uda1380_read_reg_cache(codec, UDA1380_PM);
- int reg;
- struct uda1380_platform_data *pdata = codec->dev->platform_data;
-
- if (codec->dapm.bias_level == level)
- return 0;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- case SND_SOC_BIAS_PREPARE:
- /* ADC, DAC on */
- uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm);
- break;
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- if (gpio_is_valid(pdata->gpio_power)) {
- gpio_set_value(pdata->gpio_power, 1);
- mdelay(1);
- uda1380_reset(codec);
- }
-
- uda1380_sync_cache(codec);
- }
- uda1380_write(codec, UDA1380_PM, 0x0);
- break;
- case SND_SOC_BIAS_OFF:
- if (!gpio_is_valid(pdata->gpio_power))
- break;
-
- gpio_set_value(pdata->gpio_power, 0);
-
- /* Mark mixer regs cache dirty to sync them with
- * codec regs on power on.
- */
- for (reg = UDA1380_MVOL; reg < UDA1380_CACHEREGNUM; reg++)
- set_bit(reg - 0x10, &uda1380_cache_dirty);
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define UDA1380_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
-
-static const struct snd_soc_dai_ops uda1380_dai_ops = {
- .hw_params = uda1380_pcm_hw_params,
- .shutdown = uda1380_pcm_shutdown,
- .trigger = uda1380_trigger,
- .set_fmt = uda1380_set_dai_fmt_both,
-};
-
-static const struct snd_soc_dai_ops uda1380_dai_ops_playback = {
- .hw_params = uda1380_pcm_hw_params,
- .shutdown = uda1380_pcm_shutdown,
- .trigger = uda1380_trigger,
- .set_fmt = uda1380_set_dai_fmt_playback,
-};
-
-static const struct snd_soc_dai_ops uda1380_dai_ops_capture = {
- .hw_params = uda1380_pcm_hw_params,
- .shutdown = uda1380_pcm_shutdown,
- .trigger = uda1380_trigger,
- .set_fmt = uda1380_set_dai_fmt_capture,
-};
-
-static struct snd_soc_dai_driver uda1380_dai[] = {
-{
- .name = "uda1380-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = UDA1380_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = UDA1380_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .ops = &uda1380_dai_ops,
-},
-{ /* playback only - dual interface */
- .name = "uda1380-hifi-playback",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = UDA1380_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .ops = &uda1380_dai_ops_playback,
-},
-{ /* capture only - dual interface*/
- .name = "uda1380-hifi-capture",
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = UDA1380_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .ops = &uda1380_dai_ops_capture,
-},
-};
-
-static int uda1380_suspend(struct snd_soc_codec *codec)
-{
- uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int uda1380_resume(struct snd_soc_codec *codec)
-{
- uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-
-static int uda1380_probe(struct snd_soc_codec *codec)
-{
- struct uda1380_platform_data *pdata =codec->dev->platform_data;
- struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- uda1380->codec = codec;
-
- codec->hw_write = (hw_write_t)i2c_master_send;
- codec->control_data = uda1380->control_data;
-
- if (!pdata)
- return -EINVAL;
-
- if (gpio_is_valid(pdata->gpio_reset)) {
- ret = gpio_request_one(pdata->gpio_reset, GPIOF_OUT_INIT_LOW,
- "uda1380 reset");
- if (ret)
- goto err_out;
- }
-
- if (gpio_is_valid(pdata->gpio_power)) {
- ret = gpio_request_one(pdata->gpio_power, GPIOF_OUT_INIT_LOW,
- "uda1380 power");
- if (ret)
- goto err_free_gpio;
- } else {
- ret = uda1380_reset(codec);
- if (ret)
- goto err_free_gpio;
- }
-
- INIT_WORK(&uda1380->work, uda1380_flush_work);
-
- /* power on device */
- uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- /* set clock input */
- switch (pdata->dac_clk) {
- case UDA1380_DAC_CLK_SYSCLK:
- uda1380_write_reg_cache(codec, UDA1380_CLK, 0);
- break;
- case UDA1380_DAC_CLK_WSPLL:
- uda1380_write_reg_cache(codec, UDA1380_CLK,
- R00_DAC_CLK);
- break;
- }
-
- return 0;
-
-err_free_gpio:
- if (gpio_is_valid(pdata->gpio_reset))
- gpio_free(pdata->gpio_reset);
-err_out:
- return ret;
-}
-
-/* power down chip */
-static int uda1380_remove(struct snd_soc_codec *codec)
-{
- struct uda1380_platform_data *pdata =codec->dev->platform_data;
-
- uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- gpio_free(pdata->gpio_reset);
- gpio_free(pdata->gpio_power);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_uda1380 = {
- .probe = uda1380_probe,
- .remove = uda1380_remove,
- .suspend = uda1380_suspend,
- .resume = uda1380_resume,
- .read = uda1380_read_reg_cache,
- .write = uda1380_write,
- .set_bias_level = uda1380_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(uda1380_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = uda1380_reg,
- .reg_cache_step = 1,
-
- .controls = uda1380_snd_controls,
- .num_controls = ARRAY_SIZE(uda1380_snd_controls),
- .dapm_widgets = uda1380_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets),
- .dapm_routes = uda1380_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(uda1380_dapm_routes),
-};
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int uda1380_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct uda1380_priv *uda1380;
- int ret;
-
- uda1380 = devm_kzalloc(&i2c->dev, sizeof(struct uda1380_priv),
- GFP_KERNEL);
- if (uda1380 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, uda1380);
- uda1380->control_data = i2c;
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai));
- return ret;
-}
-
-static int __devexit uda1380_i2c_remove(struct i2c_client *i2c)
-{
- snd_soc_unregister_codec(&i2c->dev);
- return 0;
-}
-
-static const struct i2c_device_id uda1380_i2c_id[] = {
- { "uda1380", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
-
-static struct i2c_driver uda1380_i2c_driver = {
- .driver = {
- .name = "uda1380-codec",
- .owner = THIS_MODULE,
- },
- .probe = uda1380_i2c_probe,
- .remove = __devexit_p(uda1380_i2c_remove),
- .id_table = uda1380_i2c_id,
-};
-#endif
-
-static int __init uda1380_modinit(void)
-{
- int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&uda1380_i2c_driver);
- if (ret != 0)
- pr_err("Failed to register UDA1380 I2C driver: %d\n", ret);
-#endif
- return ret;
-}
-module_init(uda1380_modinit);
-
-static void __exit uda1380_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&uda1380_i2c_driver);
-#endif
-}
-module_exit(uda1380_exit);
-
-MODULE_AUTHOR("Giorgio Padrin");
-MODULE_DESCRIPTION("Audio support for codec Philips UDA1380");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/uda1380.h b/ANDROID_3.4.5/sound/soc/codecs/uda1380.h
deleted file mode 100644
index 942e3927..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/uda1380.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Audio support for Philips UDA1380
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Copyright (c) 2005 Giorgio Padrin <giorgio@mandarinlogiq.org>
- */
-
-#ifndef _UDA1380_H
-#define _UDA1380_H
-
-#define UDA1380_CLK 0x00
-#define UDA1380_IFACE 0x01
-#define UDA1380_PM 0x02
-#define UDA1380_AMIX 0x03
-#define UDA1380_HP 0x04
-#define UDA1380_MVOL 0x10
-#define UDA1380_MIXVOL 0x11
-#define UDA1380_MODE 0x12
-#define UDA1380_DEEMP 0x13
-#define UDA1380_MIXER 0x14
-#define UDA1380_INTSTAT 0x18
-#define UDA1380_DEC 0x20
-#define UDA1380_PGA 0x21
-#define UDA1380_ADC 0x22
-#define UDA1380_AGC 0x23
-#define UDA1380_DECSTAT 0x28
-#define UDA1380_RESET 0x7f
-
-#define UDA1380_CACHEREGNUM 0x24
-
-/* Register flags */
-#define R00_EN_ADC 0x0800
-#define R00_EN_DEC 0x0400
-#define R00_EN_DAC 0x0200
-#define R00_EN_INT 0x0100
-#define R00_DAC_CLK 0x0010
-#define R01_SFORI_I2S 0x0000
-#define R01_SFORI_LSB16 0x0100
-#define R01_SFORI_LSB18 0x0200
-#define R01_SFORI_LSB20 0x0300
-#define R01_SFORI_MSB 0x0500
-#define R01_SFORI_MASK 0x0700
-#define R01_SFORO_I2S 0x0000
-#define R01_SFORO_LSB16 0x0001
-#define R01_SFORO_LSB18 0x0002
-#define R01_SFORO_LSB20 0x0003
-#define R01_SFORO_LSB24 0x0004
-#define R01_SFORO_MSB 0x0005
-#define R01_SFORO_MASK 0x0007
-#define R01_SEL_SOURCE 0x0040
-#define R01_SIM 0x0010
-#define R02_PON_PLL 0x8000
-#define R02_PON_HP 0x2000
-#define R02_PON_DAC 0x0400
-#define R02_PON_BIAS 0x0100
-#define R02_EN_AVC 0x0080
-#define R02_PON_AVC 0x0040
-#define R02_PON_LNA 0x0010
-#define R02_PON_PGAL 0x0008
-#define R02_PON_ADCL 0x0004
-#define R02_PON_PGAR 0x0002
-#define R02_PON_ADCR 0x0001
-#define R13_MTM 0x4000
-#define R14_SILENCE 0x0080
-#define R14_SDET_ON 0x0040
-#define R21_MT_ADC 0x8000
-#define R22_SEL_LNA 0x0008
-#define R22_SEL_MIC 0x0004
-#define R22_SKIP_DCFIL 0x0002
-#define R23_AGC_EN 0x0001
-
-#define UDA1380_DAI_DUPLEX 0 /* playback and capture on single DAI */
-#define UDA1380_DAI_PLAYBACK 1 /* playback DAI */
-#define UDA1380_DAI_CAPTURE 2 /* capture DAI */
-
-#endif /* _UDA1380_H */
diff --git a/ANDROID_3.4.5/sound/soc/codecs/vt1603.c b/ANDROID_3.4.5/sound/soc/codecs/vt1603.c
deleted file mode 100755
index eaa3d28e..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/vt1603.c
+++ /dev/null
@@ -1,1249 +0,0 @@
-/*++
- * linux/sound/soc/codecs/vt1603.c
- * WonderMedia audio driver for ALSA
- *
- * Copyright c 2010 WonderMedia Technologies, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * WonderMedia Technologies, Inc.
- * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
---*/
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/platform_device.h>
-#include <linux/version.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <linux/interrupt.h>
-#include <asm/irq.h>
-#include <linux/workqueue.h>
-#include <linux/switch.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
-
-#include "vt1603.h"
-#include <linux/mfd/vt1603/core.h>
-
-#define VT1603_TIMER_INTERVAL 100 // ms
-
-static struct snd_soc_codec *gvt1603_codec = NULL; //
-
-struct vt1603_priv {
- unsigned int sysclk;
- struct switch_dev hp_switch; // state of headphone insert or not
- struct work_struct work;
- struct snd_soc_codec *codec;
- struct timer_list timer; // timer for detecting headphone
- struct proc_dir_entry *proc;
- struct notifier_block reboot_notifier;
-};
-
-struct vt1603_boardinfo {
- int hp_level; // 0: headset level low; 1: high
- int ignore_hp_event;
- int rec_src; // 0: AMIC-IN; 1: DMIC-IN
-
- int hpd_rm; //add 2013-11-26
- int hp_debounce; //add 2014-1-14
- int timer_del; //2014-1-20 tvbox
-
- int out_on; //2014-4-29 av out on for tvbox noisy. hw not good!
-};
-static struct vt1603_boardinfo vt1603_boardinfo;
-
-extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
-
-static const u16 vt1603_regs[] = {
- 0x0020, 0x00D7, 0x00D7, 0x0004, /* 0-3 */
- 0x0000, 0x0040, 0x0000, 0x00c0, /* 4-7 */
- 0x00c0, 0x0010, 0x0001, 0x0041, /* 8-11 */
- 0x0000, 0x0000, 0x000b, 0x0093, /* 12-15 */
- 0x0004, 0x0016, 0x0026, 0x0060, /* 16-19 */
- 0x001a, 0x0000, 0x0002, 0x0000, /* 20-23 */
- 0x0000, 0x000a, 0x0000, 0x0010, /* 24-27 */
- 0x0000, 0x00e2, 0x0000, 0x0000, /* 28-31 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 32-35 */
- 0x0000, 0x000c, 0x0054, 0x0000, /* 36-39 */
- 0x0001, 0x000c, 0x000c, 0x000c, /* 40-43 */
- 0x000c, 0x000c, 0x00c0, 0x00d5, /* 44-47 */
- 0x00c5, 0x0012, 0x0085, 0x002b, /* 48-51 */
- 0x00cd, 0x00cd, 0x008e, 0x008d, /* 52-55 */
- 0x00e0, 0x00a6, 0x00a5, 0x0050, /* 56-59 */
- 0x00e9, 0x00cf, 0x0040, 0x0000, /* 60-63 */
- 0x0000, 0x0008, 0x0004, 0x0000, /* 64-67 */
- 0x0040, 0x0000, 0x0040, 0x0000, /* 68-71 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 72-75 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 76-79 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 80-83 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 84-87 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 88-91 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 92-95 */
- 0x00c4, 0x0079, 0x000c, 0x0024, /* 96-99 */
- 0x0016, 0x0016, 0x0060, 0x0002, /* 100-103 */
- 0x005b, 0x0003, 0x0039, 0x0039, /* 104-107 */
- 0x00fe, 0x0012, 0x0034, 0x0000, /* 108-111 */
- 0x0004, 0x00f0, 0x0000, 0x0000, /* 112-115 */
- 0x0000, 0x0000, 0x0003, 0x0000, /* 116-119 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 120-123 */
- 0x00f2, 0x0020, 0x0023, 0x006e, /* 124-127 */
- 0x0019, 0x0040, 0x0000, 0x0004, /* 128-131 */
- 0x000a, 0x0075, 0x0035, 0x00b0, /* 132-135 */
- 0x0040, 0x0000, 0x0000, 0x0000, /* 136-139 */
- 0x0088, 0x0013, 0x000c, 0x0003, /* 140-143 */
- 0x0000, 0x0000, 0x0008, 0x0000, /* 144-147 */
- 0x0003, 0x0020, 0x0030, 0x0018, /* 148-151 */
- 0x001b,
-};
-
-/*----------------------------------------------------------------------*/
-
-
-/*---------------------Control Interface Functions----------------------*/
-
-static int vt1603_write(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int value)
-{
- int ret = vt1603_reg_write(codec->control_data, reg, value);
- if (ret == 0)
- ((u16 *)codec->reg_cache)[reg] = value;
- return ret;
-}
-
-static unsigned int vt1603_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- return ((u16 *)codec->reg_cache)[reg];
-}
-
-static int vt1603_hw_write(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int value)
-{
- return vt1603_reg_write(codec->control_data, reg, value);
-}
-
-static unsigned int vt1603_hw_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- u8 val;
- int ret = vt1603_reg_read(codec->control_data, reg, &val);
- if (ret == 0)
- return val;
- else
- return ((u16 *)codec->reg_cache)[reg];
-}
-
-/*----------------------------------------------------------------------*/
-
-
-/*----------------------IRQ handle Functions----------------------------*/
-
-static void vt1603_set_switch_state(struct snd_soc_codec *codec)
-{
- /* Just report hp state, don't switch hw device, app will handle it. */
-
- struct vt1603_priv *vt1603 = snd_soc_codec_get_drvdata(codec);
- unsigned int val = vt1603_hw_read(codec, VT1603_R21);
-
- if (vt1603_boardinfo.hp_level) {
- if (val & BIT1) {
- val &= ~BIT1;
- snd_soc_write(codec, VT1603_R21, val);
- if (!vt1603_boardinfo.ignore_hp_event)
- switch_set_state(&vt1603->hp_switch, 0);
- pr_info("<<<vt1603: hp out!\n");
- }
- else {
- val |= BIT1;
- snd_soc_write(codec, VT1603_R21, val);
- if (!vt1603_boardinfo.ignore_hp_event)
- switch_set_state(&vt1603->hp_switch, 1);
- pr_info("<<<vt1603: hp in!\n");
- }
- }
- else {
- if (val & BIT1) {
- val &= ~BIT1;
- snd_soc_write(codec, VT1603_R21, val);
- if (!vt1603_boardinfo.ignore_hp_event)
- switch_set_state(&vt1603->hp_switch, 1);
- pr_info("<<<vt1603: hp in!\n");
- }
- else {
- val |= BIT1;
- snd_soc_write(codec, VT1603_R21, val);
- if (!vt1603_boardinfo.ignore_hp_event)
- switch_set_state(&vt1603->hp_switch, 0);
- pr_info("<<<vt1603: hp out!\n");
- }
- }
-}
-
-static void vt1603_codec_irq_handle(struct work_struct *work)
-{
- struct vt1603_priv *priv = container_of(work, struct vt1603_priv, work);
- struct snd_soc_codec *codec = priv->codec;
- unsigned int val;
- static unsigned int count = 0;
- int hp_state = 0; //switch_get_state(&priv->hp_switch);
- if (!vt1603_boardinfo.hpd_rm)
- hp_state = switch_get_state(&priv->hp_switch);
-
- unsigned int debounce = (hp_state == 0) ? 3 : 1; // sw-debounce for headset plugin
-
- if (vt1603_boardinfo.hp_debounce > 0)
- debounce = (hp_state == 0) ? vt1603_boardinfo.hp_debounce : 1;
-
-
-
- val = vt1603_hw_read(codec, VT1603_R51);
- if (val & BIT1) {
- val = vt1603_hw_read(codec, VT1603_R1b);
- val |= BIT1;
- snd_soc_write(codec, VT1603_R1b, val);
- val &= ~BIT1;
- snd_soc_write(codec, VT1603_R1b, val);
- count++;
- }
- else {
- count = 0;
- }
-
- if (count == debounce) {
- pr_info("vt1603: hpdetect\n");
- vt1603_set_switch_state(codec);
- // clear headphone irq mask
- val = vt1603_hw_read(codec,VT1603_R1b);
- val |= BIT1;
- snd_soc_write(codec, VT1603_R1b, val);
- val &= ~BIT1;
- snd_soc_write(codec, VT1603_R1b, val);
- count = 0;
- }
-
- val = vt1603_hw_read(codec, VT1603_R52);
- if (val & BIT4) {
- pr_info("vt1603: left cld oc\n");
- val = vt1603_hw_read(codec,VT1603_R1c);
- val |= BIT4;
- snd_soc_write(codec, VT1603_R1c, val);
- val &= ~BIT4;
- snd_soc_write(codec, VT1603_R1c, val);
- }
- if (val & BIT3) {
- pr_info("vt1603: right cld oc\n");
- val = vt1603_hw_read(codec,VT1603_R1c);
- val |= BIT3;
- snd_soc_write(codec, VT1603_R1c, val);
- val &= ~BIT3;
- snd_soc_write(codec, VT1603_R1c, val);
- }
-}
-
-static void vt1603_timer_handler(unsigned long data)
-{
- struct vt1603_priv *vt1603 = (struct vt1603_priv *)data;
- schedule_work(&vt1603->work);
- mod_timer(&vt1603->timer, jiffies + msecs_to_jiffies(VT1603_TIMER_INTERVAL));
-}
-
-/*----------------------------------------------------------------------*/
-
-
-/*--------------------Mixer controls & dapm-----------------------------*/
-
-static const DECLARE_TLV_DB_SCALE(digital_tlv, -9550, 50, 1);
-static const DECLARE_TLV_DB_SCALE(digital_clv, -4350, 50, 1);
-static const DECLARE_TLV_DB_SCALE(adc_boost_clv, 0, 1000, 1);
-static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0);
-static const DECLARE_TLV_DB_SCALE(adc_pga_clv, -1650, 150, 1);
-static const DECLARE_TLV_DB_SCALE(analog_tlv, -2100, 300, 1);
-static const DECLARE_TLV_DB_SCALE(hp_mixer_clv, -5700, 100, 1);
-static const DECLARE_TLV_DB_SCALE(cld_mixer_clv, -300, 300, 1);
-
-static const char *adc_cutoff_freq_txt[] = {
- "Hi-fi mode",
- "Voice mode 1",
- "Voice mode 2",
- "Voice mode 3",
-};
-
-static const struct soc_enum adc_cutoff_freq =
-SOC_ENUM_SINGLE(VT1603_R00, 3, 4, adc_cutoff_freq_txt);
-
-static const char *lr_txt[] = {
- "Left", "Right"
-};
-
-static const char *clamper_limit_voltage_txt[] = {
- "Vih=2.40V, Vil=0.90V, P=0.63W",
- "Vih=2.45V, Vil=0.85V, P=0.72W",
- "Vih=2.50V, ViL=0.80V, P=0.81W",
- "Vih=2.55V, Vil=0.75V, P=0.91W",
- "Vih=2.60V, Vil=0.70V, P=1.02W",
- "Vih=2.65V, Vil=0.65V, P=1.12W",
- "Vih=2.70V, Vil=0.60V, P=1.24W",
- "Vih=2.75V, Vil=0.55V, P=1.36W",
- "Vih=2.80V, Vil=0.50V, P=1.49W",
- "Vih=2.85V, Vil=0.45V, P=1.62W",
- "Vih=2.90V, Vil=0.40V, P=1.76W",
- "Vih=2.95V, Vil=0.35V, P=1.90W",
- "Vih=3.00V, Vil=0.30V, P=2.05W",
- "Vih=3.05V, Vil=0.25V, P=2.20W",
- "Vih=3.10V, Vil=0.20V, P=2.37W",
- "Vih=3.15V, Vil=0.15V, P=2.53W",
-};
-
-static const char *clamper_work_voltage_txt[] = {
- "Voh=3.10V, Vol=1.90V, P=0.36W",
- "Voh=3.25V, Vol=1.75V, P=0.56W",
- "Voh=3.40V, Vol=1.60V, P=0.81W",
- "Voh=3.55V, Vol=1.45V, P=1.10W",
- "Voh=3.70V, Vol=1.30V, P=1.44W",
- "Voh=3.85V, Vol=1.15V, P=1.82W",
- "Voh=4.00V, Vol=1.00V, P=2.25W",
- "Voh=4.15V, Vol=0.85V, P=2.72W",
-};
-
-static const struct soc_enum dacl_src =
-SOC_ENUM_SINGLE(VT1603_R0b, 7, 2, lr_txt);
-
-static const struct soc_enum dacr_src =
-SOC_ENUM_SINGLE(VT1603_R0b, 6, 2, lr_txt);
-
-static const struct soc_enum adcl_src =
-SOC_ENUM_SINGLE(VT1603_R03, 3, 2, lr_txt);
-
-static const struct soc_enum adcr_src =
-SOC_ENUM_SINGLE(VT1603_R03, 2, 2, lr_txt);
-
-static const struct soc_enum clamper_limit_voltage =
-SOC_ENUM_SINGLE(VT1603_R87, 4, 16, clamper_limit_voltage_txt);
-
-static const struct soc_enum clamper_work_voltage =
-SOC_ENUM_SINGLE(VT1603_R87, 0, 8, clamper_work_voltage_txt);
-
-static const struct snd_kcontrol_new vt1603_snd_controls[] = {
-/* Volume */
-SOC_DOUBLE_R_TLV("Digital Capture Volume", VT1603_R01, VT1603_R02, 0, 0x7f, 0, digital_clv),
-SOC_DOUBLE_R_TLV("Digital Playback Volume", VT1603_R07, VT1603_R08, 0, 0xc0, 0, digital_tlv),
-SOC_DOUBLE_R_TLV("Analog Playback Volume", VT1603_R72, VT1603_R73, 0, 0x07, 1, analog_tlv),
-SOC_DOUBLE_R_TLV("Input Boost Volume", VT1603_R64, VT1603_R65, 6, 4, 0, adc_boost_clv),
-SOC_DOUBLE_R_TLV("Input PGA Volume", VT1603_R64, VT1603_R65, 1, 0x1f, 0, adc_pga_clv),
-SOC_DOUBLE_TLV("Output Boost Volume", VT1603_R06, 0, 3, 7, 0, dac_boost_tlv),
-SOC_DOUBLE_TLV("Output CLD Volume", VT1603_R91, 5, 2, 7, 0, cld_mixer_clv),
-SOC_DOUBLE_R_TLV("Output HP Volume", VT1603_R6a, VT1603_R6b, 0, 0x3f, 0, hp_mixer_clv),
-
-/* Switch */
-SOC_SINGLE("EQ Switch", VT1603_R28, 0, 1, 0),
-
-SOC_SINGLE("DAC Mono Mix Switch", VT1603_R0d, 4, 1, 0),
-SOC_SINGLE("Left DAC Switch", VT1603_R62, 5, 1, 0),
-SOC_SINGLE("Right DAC Switch", VT1603_R62, 4, 1, 0),
-
-SOC_ENUM("Left DAC Source", dacl_src),
-SOC_ENUM("Right DAC Source", dacr_src),
-
-SOC_ENUM("Digital Capture Voice Mode", adc_cutoff_freq),
-SOC_ENUM("Left ADC Source", adcl_src),
-SOC_ENUM("Right ADC Source", adcr_src),
-
-SOC_DOUBLE("Analog Playback Switch", VT1603_R71, 7, 6, 1, 1),
-SOC_SINGLE("Digital Playback Switch", VT1603_R0b, 0, 1, 1),
-SOC_DOUBLE("Digital Capture Switch", VT1603_R63, 7, 6, 1, 0),
-
-SOC_SINGLE("Headset Switch", VT1603_R68, 4, 1, 1),
-SOC_SINGLE("Headfree Switch", VT1603_R25, 1, 1, 0),
-
-SOC_SINGLE("Left CLD Switch", VT1603_R82, 3, 1, 1),
-SOC_SINGLE("Right CLD Switch", VT1603_R82, 4, 1, 1),
-
-SOC_ENUM("Limit Voltage of Power Clamper", clamper_limit_voltage),
-SOC_ENUM("Voltage of Clamper Work", clamper_work_voltage),
-};
-
-/* DAPM Controls */
-
-static const struct snd_kcontrol_new linmix_controls[] = {
-SOC_DAPM_SINGLE("Left Mic Switch", VT1603_R8e, 5, 1, 0),
-SOC_DAPM_SINGLE("Left Linein Switch", VT1603_R8e, 7, 1, 0),
-};
-
-static const struct snd_kcontrol_new rinmix_controls[] = {
-SOC_DAPM_SINGLE("Right Mic Switch", VT1603_R8e, 4, 1, 0),
-SOC_DAPM_SINGLE("Right Linein Switch", VT1603_R8e, 6, 1, 0),
-};
-
-static const struct snd_kcontrol_new loutmix_controls[] = {
-SOC_DAPM_SINGLE("Left Input Mixer Switch", VT1603_R71, 3, 1, 0),
-SOC_DAPM_SINGLE("DACL Switch", VT1603_R71, 1, 1, 0),
-};
-
-static const struct snd_kcontrol_new routmix_controls[] = {
-SOC_DAPM_SINGLE("Right Input Mixer Switch", VT1603_R71, 2, 1, 0),
-SOC_DAPM_SINGLE("DACR Switch", VT1603_R71, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new lcld_controls[] = {
-SOC_DAPM_SINGLE("Left Output Mixer Switch", VT1603_R90, 5, 1, 0),
-SOC_DAPM_SINGLE("DACL Switch", VT1603_R90, 4, 1, 0),
-};
-
-static const struct snd_kcontrol_new rcld_controls[] = {
-SOC_DAPM_SINGLE("Right Output Mixer Switch", VT1603_R90, 3, 1, 0),
-SOC_DAPM_SINGLE("DACR Switch", VT1603_R90, 2, 1, 0),
-};
-
-static const struct snd_kcontrol_new lhp_controls[] = {
-SOC_DAPM_SINGLE("Left Output Mixer Switch", VT1603_R69, 5, 1, 0),
-SOC_DAPM_SINGLE("DACL Switch", VT1603_R69, 7, 1, 0),
-};
-
-static const struct snd_kcontrol_new rhp_controls[] = {
-SOC_DAPM_SINGLE("Right Output Mixer Switch", VT1603_R69, 2, 1, 0),
-SOC_DAPM_SINGLE("DACR Switch", VT1603_R69, 4, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget vt1603_dapm_widgets[] = {
-SND_SOC_DAPM_INPUT("Mic"),
-SND_SOC_DAPM_INPUT("Linein"),
-SND_SOC_DAPM_INPUT("Internal ADC Source"),
-
-SND_SOC_DAPM_PGA("Left Input Boost", VT1603_R67, 7, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right Input Boost", VT1603_R67, 6, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA("Left Input PGA", VT1603_R67, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right Input PGA", VT1603_R67, 4, 0, NULL, 0),
-
-
-SND_SOC_DAPM_MIXER("Left Input Mixer", VT1603_R66, 6, 1,
- linmix_controls, ARRAY_SIZE(linmix_controls)),
-SND_SOC_DAPM_MIXER("Right Input Mixer", VT1603_R66, 5, 1,
- rinmix_controls, ARRAY_SIZE(rinmix_controls)),
-
-SND_SOC_DAPM_ADC("ADCL", "Left Capture", VT1603_R01, 7, 1),
-SND_SOC_DAPM_ADC("ADCR", "Right Capture", VT1603_R02, 7, 1),
-
-//SND_SOC_DAPM_DAC("DACL", "Left Playback", VT1603_R62, 5, 0),
-//SND_SOC_DAPM_DAC("DACR", "Right Playback", VT1603_R62, 4, 0),
-
-SND_SOC_DAPM_INPUT("DACL"),
-SND_SOC_DAPM_INPUT("DACR"),
-
-SND_SOC_DAPM_MIXER("Left Output Mixer", VT1603_R72, 6, 0,
- loutmix_controls, ARRAY_SIZE(loutmix_controls)),
-SND_SOC_DAPM_MIXER("Right Output Mixer", VT1603_R73, 6, 0,
- routmix_controls, ARRAY_SIZE(routmix_controls)),
-
-SND_SOC_DAPM_MIXER("Left CLD Mixer", VT1603_R91, 1, 0,
- lcld_controls, ARRAY_SIZE(lcld_controls)),
-SND_SOC_DAPM_MIXER("Right CLD Mixer", VT1603_R91, 0, 0,
- rcld_controls, ARRAY_SIZE(rcld_controls)),
-
-SND_SOC_DAPM_PGA("Left CLD PGA", VT1603_R82, 3, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Right CLD PGA", VT1603_R82, 4, 1, NULL, 0),
-
-SND_SOC_DAPM_MIXER("Left HP Mixer", VT1603_R68, 1, 1,
- lhp_controls, ARRAY_SIZE(lhp_controls)),
-SND_SOC_DAPM_MIXER("Right HP Mixer", VT1603_R68, 0, 1,
- rhp_controls, ARRAY_SIZE(rhp_controls)),
-
-SND_SOC_DAPM_OUTPUT("Internal DAC Sink"),
-SND_SOC_DAPM_OUTPUT("Left HP"),
-SND_SOC_DAPM_OUTPUT("Right HP"),
-SND_SOC_DAPM_OUTPUT("Left SPK"),
-SND_SOC_DAPM_OUTPUT("Right SPK"),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- /* Make DACs turn on when playing even if not mixed into any outputs */
- //{"Internal DAC Sink", NULL, "DACL"},
- //{"Internal DAC Sink", NULL, "DACR"},
-
- /* Make ADCs turn on when recording even if not mixed from any inputs */
- //{"ADCL", NULL, "Internal ADC Source"},
- //{"ADCR", NULL, "Internal ADC Source"},
-
-
- /* Capture route */
-
- { "Left Input Mixer", "Left Linein Switch", "Linein" },
- { "Left Input Mixer", "Left Mic Switch", "Mic" },
- { "Right Input Mixer", "Right Linein Switch", "Linein" },
- { "Right Input Mixer", "Right Mic Switch", "Mic" },
-
- { "Left Input Boost", NULL, "Left Input Mixer"},
- { "Right Input Boost", NULL, "Right Input Mixer"},
-
- { "Left Input PGA", NULL, "Left Input Boost"},
- { "Right Input PGA", NULL, "Right Input Boost"},
-
- { "ADCL", NULL, "Left Input PGA" },
- { "ADCR", NULL, "Right Input PGA" },
-
- //{ "Left Input Mixer", NULL, "Left Input PGA" },
- //{ "Right Input Mixer", NULL, "Right Input PGA" },
-
- /* Playback route */
-
- //{ "Left Output Mixer", "Left Input Mixer Switch", "Left Input Mixer" },
- { "Left Output Mixer", "Left Input Mixer Switch", "Left Input PGA"},
- { "Left Output Mixer", "DACL Switch", "DACL" },
- //{ "Right Output Mixer", "Right Input Mixer Switch", "Right Input Mixer" },
- { "Right Output Mixer", "Right Input Mixer Switch", "Right Input PGA"},
- { "Right Output Mixer", "DACR Switch", "DACR" },
-
- { "Left CLD Mixer", "Left Output Mixer Switch", "Left Output Mixer" },
- { "Left CLD Mixer", "DACL Switch", "DACL" },
- { "Right CLD Mixer", "Right Output Mixer Switch", "Right Output Mixer" },
- { "Right CLD Mixer", "DACR Switch", "DACR" },
-
- { "Left HP Mixer", "Left Output Mixer Switch", "Left Output Mixer" },
- { "Left HP Mixer", "DACL Switch", "DACL" },
- { "Right HP Mixer", "Right Output Mixer Switch", "Right Output Mixer" },
- { "Right HP Mixer", "DACR Switch", "DACR" },
-
- { "Left CLD PGA", NULL, "Left CLD Mixer" },
- { "Right CLD PGA", NULL, "Right CLD Mixer" },
-
- { "Left HP", NULL, "Left HP Mixer" },
- { "Right HP", NULL, "Right HP Mixer" },
-
- { "Left SPK", NULL, "Left CLD PGA" },
- { "Right SPK", NULL, "Right CLD PGA" },
-};
-
-/*----------------------------------------------------------------------*/
-
-
-/*----------------------codec dai functions-----------------------------*/
-
-struct _coeff_div {
- u32 mclk;
- u32 rate;
- u16 fs;
- u8 sr;
- u8 bclk_div;
-};
-
-/* codec hifi mclk clock divider coefficients */
-static const struct _coeff_div coeff_div[] = {
- /* 8k */
- {12288000, 8000, 1536, 0x4, 0x0},
- /* 11.025k */
- {11289600, 11025, 1024, 0x8, 0x0},
- /* 16k */
- {12288000, 16000, 768, 0x5, 0x0},
- /* 22.05k */
- {11289600, 22050, 512, 0x9, 0x0},
- /* 32k */
- {12288000, 32000, 384, 0x7, 0x0},
- /* 44.1k */
- {11289600, 44100, 256, 0x6, 0x07},
- /* 48k */
- {12288000, 48000, 256, 0x0, 0x07},
- /* 96k */
- {12288000, 96000, 128, 0x1, 0x04},
-};
-
-static inline int get_coeff(int mclk, int rate)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
- if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
- return i;
- }
- return -EINVAL;
-}
-
-static int vt1603_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct vt1603_priv *vt1603 = snd_soc_codec_get_drvdata(codec);
- switch (freq) {
- case 11289600:
- case 12000000:
- case 12288000:
- case 16934400:
- case 18432000:
- vt1603->sysclk = freq;
- return 0;
- }
- return -EINVAL;
-}
-
-static int vt1603_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 iface = snd_soc_read(codec, VT1603_R19);
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- iface |= BIT5 ;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= 0x0002;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= 0x0001;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= 0x0003;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- iface |= 0x0013;
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= 0x0090;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= 0x0080;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- iface |= 0x0010;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, VT1603_R19, iface);
- return 0;
-}
-
-static int vt1603_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct vt1603_priv *vt1603 = snd_soc_codec_get_drvdata(codec);
- u16 val;
- u16 iface = snd_soc_read(codec, VT1603_R19) & 0x73;
- int coeff = get_coeff(vt1603->sysclk, params_rate(params));
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= 0x04;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface |= 0x08;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- iface |= 0x0c;
- break;
- }
-
- /* set iface & srate */
- snd_soc_write(codec, VT1603_R19, iface);
-
- if (coeff >= 0) {
- val = snd_soc_read(codec, VT1603_R42);
- val &= 0xf0;
- val |= coeff_div[coeff].bclk_div;
- snd_soc_write(codec, VT1603_R42, val);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- val = snd_soc_read(codec, VT1603_R05);
- val &= 0xf0;
- val |= coeff_div[coeff].sr;
- snd_soc_write(codec, VT1603_R05, val);
- }
-
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- val = snd_soc_read(codec, VT1603_R03);
- val &= 0x0f;
- val |= ((coeff_div[coeff].sr<<4) & 0xf0);
- snd_soc_write(codec, VT1603_R03, val);
- }
- }
-
- return 0;
-}
-
-static int vt1603_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- u16 val;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- val = snd_soc_read(codec, VT1603_R96);
- val |= BIT4+BIT5;
- snd_soc_write(codec, VT1603_R96, val);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- break;
-
- case SND_SOC_BIAS_OFF:
- break;
- }
-
- codec->dapm.bias_level = level;
- return 0;
-}
-
-static struct snd_soc_dai_ops vt1603_dai_ops = {
- .hw_params = vt1603_pcm_hw_params,
- .set_fmt = vt1603_set_dai_fmt,
- .set_sysclk = vt1603_set_dai_sysclk,
-};
-
-struct snd_soc_dai_driver vt1603_dai = {
- .name = "VT1603",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .ops = &vt1603_dai_ops,
-};
-
-/*----------------------------------------------------------------------*/
-
-
-/*----------------------------------------------------------------------*/
-
-static void vt1603_get_boardinfo(void)
-{
- int ret = 0;
- unsigned char buf[64];
- int varlen = sizeof(buf);
-
- memset(buf, 0x0, sizeof(buf));
- ret = wmt_getsyspara("wmt.audio.i2s", buf, &varlen);
- if (ret == 0) {
- sscanf(buf, "vt1603:%d:%d:%d",
- &vt1603_boardinfo.hp_level,
- &vt1603_boardinfo.ignore_hp_event,
- &vt1603_boardinfo.rec_src);
- }
- else {
- vt1603_boardinfo.hp_level = 0;
- vt1603_boardinfo.ignore_hp_event = 0;
- vt1603_boardinfo.rec_src = 0;
- }
-
- memset(buf, 0x0, sizeof(buf));
- vt1603_boardinfo.hpd_rm = 0;
- ret = wmt_getsyspara("wmt.vt1603.hpd.rm", buf, &varlen);
- if (ret == 0) {
- sscanf(buf, "%d",
- &vt1603_boardinfo.hpd_rm);
- }
- else {
- vt1603_boardinfo.hpd_rm = 0;
-
- }
- printk("<<<<%s hpd_rm %d\n", __func__, vt1603_boardinfo.hpd_rm);
-
- memset(buf, 0x0, sizeof(buf));
- vt1603_boardinfo.hp_debounce = 0;
- ret = wmt_getsyspara("wmt.vt1603.hp.debounce", buf, &varlen);
- if (ret == 0) {
- sscanf(buf, "%d",
- &vt1603_boardinfo.hp_debounce);
- }
- else {
- vt1603_boardinfo.hp_debounce = 0;
-
- }
- printk("<<<<%s hp_debounce %d\n", __func__, vt1603_boardinfo.hp_debounce);
-
-
- memset(buf, 0x0, sizeof(buf));
- vt1603_boardinfo.timer_del = 0;
- ret = wmt_getsyspara("wmt.vt1603.timer.del", buf, &varlen);
- if (ret == 0) {
- sscanf(buf, "%d",
- &vt1603_boardinfo.timer_del);
- }
- else {
- vt1603_boardinfo.timer_del = 0;
-
- }
- printk("<<<<%s timer_del %d\n", __func__, vt1603_boardinfo.timer_del);
-
- memset(buf, 0x0, sizeof(buf));
- vt1603_boardinfo.out_on = 0;
- ret = wmt_getsyspara("wmt.vt1603.out_on", buf, &varlen);
- if (ret == 0) {
- sscanf(buf, "%d",
- &vt1603_boardinfo.out_on);
- }
- else {
- vt1603_boardinfo.out_on = 0;
-
- }
- printk("<<<<%s out_on %d\n", __func__, vt1603_boardinfo.out_on);
-}
-
-static int vt1603_readproc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- struct vt1603_priv *vt1603 = data;
- pr_info("\nvt1603 regs dump:\n");
- vt1603_regs_dump(vt1603->codec->control_data);
- return 0;
-}
-
-static void vt1603_codec_reset(struct snd_soc_codec *codec)
-{
- unsigned int val;
-
- vt1603_hw_write(codec, 0xc2, 0x01);
-
- // reset all registers to default settings
- vt1603_hw_write(codec, VT1603_REG_RESET, 0xff);
- vt1603_hw_write(codec, VT1603_REG_RESET, 0x00);
-
- val = vt1603_hw_read(codec, VT1603_R60);
- val &= ~(BIT6 + BIT7);
- vt1603_hw_write(codec, VT1603_R60, val);
- val |= BIT6 + BIT7;
- vt1603_hw_write(codec, VT1603_R60, val);
-}
-
-static void vt1603_codec_init(struct snd_soc_codec *codec)
-{
- unsigned int val;
-
- // vt1603 touch uses irq low active???
- if (vt1603_boardinfo.hp_level) {
- //hp high
- snd_soc_write(codec, VT1603_R21, 0xfd);
- }
- else {
- //hp low
- snd_soc_write(codec, VT1603_R21, 0xff);
- }
-
- // vt1603 codec irq settings
- snd_soc_write(codec, VT1603_R1b, 0xff);
- snd_soc_write(codec, VT1603_R1b, 0xfd);
- snd_soc_write(codec, VT1603_R1c, 0xff);
- snd_soc_write(codec, VT1603_R1d, 0xff);
- snd_soc_write(codec, VT1603_R24, 0x04);
-
- snd_soc_write(codec, VT1603_R95, 0x00);
- snd_soc_write(codec, VT1603_R60, 0xc7);
- snd_soc_write(codec, VT1603_R93, 0x02);
- snd_soc_write(codec, VT1603_R7b, 0x10);
- snd_soc_write(codec, VT1603_R92, 0x2c);
-
- // r4 is reserved, I don't know more about it.
- snd_soc_write(codec, VT1603_R04, 0x00);
- // r9[5] is reserved, I don't know more about it.
- val = snd_soc_read(codec, VT1603_R09);
- val |= BIT5;
- snd_soc_write(codec, VT1603_R09, val);
- // r79 is reserved, I don't know more about it.
- val = snd_soc_read(codec, VT1603_R79);
- val |= BIT2;
- val &= ~(BIT0+BIT1);
- snd_soc_write(codec, VT1603_R79, val);
- // r7a is reserved, I don't know more about it.
- val = snd_soc_read(codec, VT1603_R7a);
- val |= BIT3+BIT4+BIT7;
- snd_soc_write(codec, VT1603_R7a, val);
- // r87 is reserved, I don't know more about it.
- snd_soc_write(codec, VT1603_R87, 0x90);
- // r88 is reserved, I don't know more about it.
- snd_soc_write(codec, VT1603_R88, 0x28);
- // r8a is reserved, I don't know more about it.
- val = snd_soc_read(codec, VT1603_R8a);
- val |= BIT1;
- snd_soc_write(codec, VT1603_R8a, val);
- // enable CLK_SYS, CLK_DSP, CLK_AIF
- val = snd_soc_read(codec, VT1603_R40);
- val |= BIT4+BIT5+BIT6;
- snd_soc_write(codec, VT1603_R40, val);
- // set DAC sample rate divier=CLK_SYS/1, DAC clock divider=DAC_CLK_512X
- val = snd_soc_read(codec, VT1603_R41);
- val &= ~(BIT3+BIT2+BIT1+BIT0);
- val |= BIT1;//add for mclk 24.576M, 10Khz 17kHz sine distortion 2014-6-12
- snd_soc_write(codec, VT1603_R41, val);
- // set BCLK rate=CLK_SYS/8
- val = snd_soc_read(codec, VT1603_R42);
- val |= BIT0+BIT1+BIT2;
- val &= ~BIT3;
- snd_soc_write(codec, VT1603_R42, val);
- // enable VREF_SC_DA buffer
- val = snd_soc_read(codec, VT1603_R61);
- val |= BIT7;
- snd_soc_write(codec, VT1603_R61, val);
- // ADC VREF_SC offset voltage
- snd_soc_write(codec, VT1603_R93, 0x20);
- // set mic bias voltage = 90% * AVDD
- val = snd_soc_read(codec, VT1603_R92);
- val |= BIT2;
- snd_soc_write(codec, VT1603_R92, val);
- // enable bypass for AOW0 parameterized HPF
- val = snd_soc_read(codec, VT1603_R0a);
- val |= BIT6;
- snd_soc_write(codec, VT1603_R0a, val);
- // CPVEE=2.2uF, the ripple frequency ON CPVEE above 22kHz, that will reduce HP noise
- val = snd_soc_read(codec, VT1603_R7a);
- val |= BIT6;
- val &= ~BIT5;
- snd_soc_write(codec, VT1603_R7a, val);
-
- // set DAC soft mute mode
- val = snd_soc_read(codec, VT1603_R0b);
- val |= BIT1+BIT2;
- snd_soc_write(codec, VT1603_R0b, val);
- // DAC High Voltage Switch Control Signal enable???
- val = snd_soc_read(codec, VT1603_R62);
- val |= BIT7+BIT6;
- val &= ~BIT3;
- snd_soc_write(codec, VT1603_R62, val);
- // enable microphone bias
- val = snd_soc_read(codec, VT1603_R60);
- val |= 0x0f;
- snd_soc_write(codec, VT1603_R60, val);
- // capture pga settings??
- val = snd_soc_read(codec, VT1603_R8e);
- val |= 0x0f;
- snd_soc_write(codec, VT1603_R8e, val);
- // capture pga settings??
- val = snd_soc_read(codec, VT1603_R66);
- val |= BIT1+BIT2+BIT3+BIT4; //
- snd_soc_write(codec, VT1603_R66, val);
- // PGA Zero Cross Detector Enable, Change gain on zero cross only
- val = snd_soc_read(codec, VT1603_R64);
- val |= BIT0;
- snd_soc_write(codec, VT1603_R64, val);
- val = snd_soc_read(codec, VT1603_R65);
- val |= BIT0;
- snd_soc_write(codec, VT1603_R65, val);
- // enable hp output mode
- val = snd_soc_read(codec, VT1603_R68);
- val |= BIT2;
- snd_soc_write(codec, VT1603_R68, val);
- // enable class-d, unmute channels
- snd_soc_write(codec, VT1603_R7c, 0xe0);
-
- // set DAC gain update
- val = snd_soc_read(codec, VT1603_R05);
- val |= BIT6+BIT7;
- snd_soc_write(codec, VT1603_R05, val);
- // set class-d AC boost gain=1.6
- snd_soc_write(codec, VT1603_R97, 0x1c);
- val = snd_soc_read(codec, VT1603_R97);
- val = (val & (~0x07)) + 0x04;
- snd_soc_write(codec, VT1603_R97, val);
- // set ADC gain update, enable ADCDAT output
- val = snd_soc_read(codec, VT1603_R00);
- val |= BIT5+BIT6+BIT7;
- snd_soc_write(codec, VT1603_R00, val);
-
- if (vt1603_boardinfo.out_on)
- {
- val = snd_soc_read(codec, VT1603_R68);
- val &= ~(1<<4);
- snd_soc_write(codec, VT1603_R68, val);
-
- val = snd_soc_read(codec, VT1603_R69);
- val |= BIT2 +BIT5;
- snd_soc_write(codec, VT1603_R69, val);
-
-
- val = snd_soc_read(codec, VT1603_R25);
- val |= BIT1;
- snd_soc_write(codec, VT1603_R25, val);
-
- val = snd_soc_read(codec, VT1603_R90);
- val |= BIT5 +BIT3;
- snd_soc_write(codec, VT1603_R90, val);
-
- }
- // DA DRC settings
- //snd_soc_write(codec, VT1603_R0e, 0x0b);
- //snd_soc_write(codec, VT1603_R0f, 0x94);
- //snd_soc_write(codec, VT1603_R10, 0x02);
- //snd_soc_write(codec, VT1603_R11, 0x00);
- //snd_soc_write(codec, VT1603_R12, 0x60);
-}
-
-static int vt1603_reboot_notify(struct notifier_block *this,
- unsigned long code, void *unused)
-{
- unsigned int val;
- struct vt1603_priv *priv = container_of(this, struct vt1603_priv, reboot_notifier);
- struct snd_soc_codec *codec = priv->codec;
-
- printk("vt1603_reboot_notify [%lu]\n", code);
-
- // power down headphone
- val = snd_soc_read(codec, VT1603_R68);
- val |= BIT4;
- snd_soc_write(codec, VT1603_R68, val);
-
- // power down class-d
- val = snd_soc_read(codec, VT1603_R25);
- val &= ~BIT1;
- snd_soc_write(codec, VT1603_R25, val);
-
- return NOTIFY_DONE;
-}
-
-/*----------------------------------------------------------------------*/
-
-
-/*---------------------codec driver functions---------------------------*/
-
-static int vt1603_codec_suspend(struct snd_soc_codec *codec)
-{
- struct vt1603_priv *vt1603 = snd_soc_codec_get_drvdata(codec);
- if (!vt1603_boardinfo.timer_del) { //add 2014-1-22 tvbox
- del_timer_sync(&vt1603->timer);
- }
- return 0;
-}
-
-static int vt1603_codec_resume(struct snd_soc_codec *codec)
-{
- struct vt1603_priv *vt1603 = snd_soc_codec_get_drvdata(codec);
- int reg;
- u16 *cache = codec->reg_cache;
- unsigned int val;
- int state = 0;//switch_get_state(&vt1603->hp_switch);
- if (!vt1603_boardinfo.hpd_rm)
- state = switch_get_state(&vt1603->hp_switch);
- // reset codec
- vt1603_codec_reset(codec);
-
- // restore codec registers
- for (reg = 0; reg < ARRAY_SIZE(vt1603_regs); reg++) {
- if (reg == VT1603_REG_RESET)
- continue;
- snd_soc_write(codec, reg, cache[reg]);
- }
-
- // restore headphone irq status
- val = vt1603_hw_read(codec, VT1603_R21);
- if ((vt1603_boardinfo.hp_level && state) ||
- (!vt1603_boardinfo.hp_level && !state)) {
- val |= BIT1;
- snd_soc_write(codec, VT1603_R21, val);
- }
- else {
- val &= ~BIT1;
- snd_soc_write(codec, VT1603_R21, val);
- }
-
- // open headphone detect
- val = vt1603_hw_read(codec,VT1603_R1b);
- val |= BIT1;
- snd_soc_write(codec, VT1603_R1b, val);
- val &= ~BIT1;
- snd_soc_write(codec, VT1603_R1b, val);
-
- // clear touch interrupt status??? why here???
- snd_soc_write(codec, 0xca, 0x0f);
-
- if (!vt1603_boardinfo.timer_del) { //add 2014-1-22 tvbox
- mod_timer(&vt1603->timer, jiffies + msecs_to_jiffies(50));
- }
-
- return 0;
-}
-
-static int vt1603_codec_probe(struct snd_soc_codec *codec)
-{
- struct vt1603_priv *vt1603;
- int ret;
-
- vt1603 = kzalloc(sizeof(struct vt1603_priv), GFP_KERNEL);
- if (vt1603 == NULL)
- return -ENOMEM;
-
- gvt1603_codec = codec;//add 2013-9-2
- snd_soc_codec_set_drvdata(codec, vt1603);
-
- codec->control_data = dev_get_platdata(codec->dev);
-
- vt1603->codec = codec;
-// need close to use wmt-switch.c 2013-11-27
- if (!vt1603_boardinfo.hpd_rm) {
- vt1603->hp_switch.name = "h2w";
- switch_dev_register(&vt1603->hp_switch);
- }
-//need close
- vt1603_codec_reset(codec);
- vt1603_codec_init(codec);
- vt1603_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
-
- INIT_WORK(&vt1603->work, vt1603_codec_irq_handle);
- if (!vt1603_boardinfo.timer_del) { //add 2014-1-20 tvbox
- init_timer(&vt1603->timer);
- vt1603->timer.data = (unsigned long)vt1603;
- vt1603->timer.function = vt1603_timer_handler;
- mod_timer(&vt1603->timer, jiffies + msecs_to_jiffies(2000));
- }
-
- vt1603->proc = create_proc_read_entry("vt1603_dumpregs", 0666, NULL,
- vt1603_readproc, vt1603);
-
- // register reboot notifier event
- vt1603->reboot_notifier.notifier_call = vt1603_reboot_notify;
- ret = register_reboot_notifier(&vt1603->reboot_notifier);
- if (ret != 0)
- pr_err("cannot register reboot notifier (err=%d)\n", ret);
-
- return 0;
-}
-
-static int vt1603_codec_remove(struct snd_soc_codec *codec)
-{
- struct vt1603_priv *vt1603 = snd_soc_codec_get_drvdata(codec);
- remove_proc_entry("vt1603_dumpregs", NULL);
- if (!vt1603_boardinfo.hpd_rm) {
- switch_dev_unregister(&vt1603->hp_switch);
- }
- del_timer_sync(&vt1603->timer);
- vt1603_set_bias_level(codec, SND_SOC_BIAS_OFF);
- kfree(vt1603);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_vt1603 = {
- .probe = vt1603_codec_probe,
- .remove = vt1603_codec_remove,
- .suspend = vt1603_codec_suspend,
- .resume = vt1603_codec_resume,
- .read = vt1603_read,
- .write = vt1603_write,
- .set_bias_level = vt1603_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(vt1603_regs),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = vt1603_regs,
-
- .controls = vt1603_snd_controls,
- .num_controls = ARRAY_SIZE(vt1603_snd_controls),
- .dapm_widgets = vt1603_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(vt1603_dapm_widgets),
- .dapm_routes = audio_map,
- .num_dapm_routes = ARRAY_SIZE(audio_map),
-};
-
-static int __devinit vt1603_probe(struct platform_device *pdev)
-{
- pr_info("<<<<%s \n", __FUNCTION__);
- return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_vt1603,
- &vt1603_dai, 1);
-}
-
-static int __devexit vt1603_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver vt1603_codec_driver = {
- .driver = {
- .name = "vt1603-codec",
- .owner = THIS_MODULE,
- },
- .probe = vt1603_probe,
- .remove = __devexit_p(vt1603_remove),
-};
-
-static __init int vt1603_init(void)
-{
- vt1603_get_boardinfo();
- return platform_driver_register(&vt1603_codec_driver);
-}
-module_init(vt1603_init);
-
-static __exit void vt1603_exit(void)
-{
- platform_driver_unregister(&vt1603_codec_driver);
-}
-module_exit(vt1603_exit);
-
-int vt1603_hwdep_ioctl(u8 rw_flag, u16 offset, u16 value)
-{
- struct snd_soc_codec *codec = gvt1603_codec;
- if (!codec){
- printk("%s NULL!\n", __FUNCTION__);
- return -1;
- }
- //info("rw_flag=%d, offset=0x%x, value=0x%x", rw_flag, offset, value);
-
- if (rw_flag) {
- if ((offset >= VT1603_R00) && (offset <= VT1603_R97)) {
- snd_soc_write(codec, offset, value);
- }
- else {
- printk("write to offset 0x%x is not allowed", offset);
- }
- return 0;
- }
- else {
- return snd_soc_read(codec, offset);
- }
-}
-EXPORT_SYMBOL(vt1603_hwdep_ioctl);
-
-MODULE_DESCRIPTION("WMT [ALSA SoC/codec] driver");
-MODULE_AUTHOR("WonderMedia Technologies, Inc.");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:vt1603-codec");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/vt1603.h b/ANDROID_3.4.5/sound/soc/codecs/vt1603.h
deleted file mode 100755
index ef130f10..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/vt1603.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*++
- * linux/sound/soc/codecs/vt1603.h
- * WonderMedia audio driver for ALSA
- *
- * Copyright c 2010 WonderMedia Technologies, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * WonderMedia Technologies, Inc.
- * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
---*/
-
-#ifndef _VT1603_H
-#define _VT1603_H
-
-#define BIT0 0x00000001
-#define BIT1 0x00000002
-#define BIT2 0x00000004
-#define BIT3 0x00000008
-#define BIT4 0x00000010
-#define BIT5 0x00000020
-#define BIT6 0x00000040
-#define BIT7 0x00000080
-#define BIT8 0x00000100
-
-#define VT1603_REG_RESET 0x15
-
-#define VT1603_R00 0x00
-#define VT1603_R01 0x01
-#define VT1603_R02 0x02
-#define VT1603_R03 0x03
-#define VT1603_R04 0x04
-#define VT1603_R05 0x05
-#define VT1603_R06 0x06
-#define VT1603_R07 0x07
-#define VT1603_R08 0x08
-#define VT1603_R09 0x09
-#define VT1603_R0a 0x0a
-#define VT1603_R0b 0x0b
-#define VT1603_R0c 0x0c
-#define VT1603_R0d 0x0d
-#define VT1603_R0e 0x0e
-#define VT1603_R0f 0x0f
-#define VT1603_R10 0x10
-#define VT1603_R11 0x11
-#define VT1603_R12 0x12
-#define VT1603_R13 0x13
-#define VT1603_R15 0x15
-#define VT1603_R19 0x19
-#define VT1603_R1b 0x1b
-#define VT1603_R1c 0x1c
-#define VT1603_R1d 0x1d
-#define VT1603_R20 0x20
-#define VT1603_R21 0x21
-#define VT1603_R23 0x23
-#define VT1603_R24 0x24
-#define VT1603_R25 0x25
-#define VT1603_R28 0x28
-#define VT1603_R29 0x29
-#define VT1603_R2a 0x2a
-#define VT1603_R2b 0x2b
-#define VT1603_R2c 0x2c
-#define VT1603_R2d 0x2d
-#define VT1603_R40 0x40
-#define VT1603_R41 0x41
-#define VT1603_R42 0x42
-#define VT1603_R47 0x47
-#define VT1603_R51 0x51
-#define VT1603_R52 0x52
-#define VT1603_R53 0x53
-#define VT1603_R5f 0x5f
-#define VT1603_R60 0x60
-#define VT1603_R61 0x61
-#define VT1603_R62 0x62
-#define VT1603_R63 0x63
-#define VT1603_R64 0x64
-#define VT1603_R65 0x65
-#define VT1603_R66 0x66
-#define VT1603_R67 0x67
-#define VT1603_R68 0x68
-#define VT1603_R69 0x69
-#define VT1603_R6a 0x6a
-#define VT1603_R6b 0x6b
-#define VT1603_R6d 0x6d
-#define VT1603_R6e 0x6e
-#define VT1603_R70 0x70
-#define VT1603_R71 0x71
-#define VT1603_R72 0x72
-#define VT1603_R73 0x73
-#define VT1603_R77 0x77
-#define VT1603_R79 0x79
-#define VT1603_R7a 0x7a
-#define VT1603_R7b 0x7b
-#define VT1603_R7c 0x7c
-#define VT1603_R82 0x82
-#define VT1603_R87 0x87
-#define VT1603_R88 0x88
-#define VT1603_R8a 0x8a
-#define VT1603_R8e 0x8e
-#define VT1603_R90 0x90
-#define VT1603_R91 0x91
-#define VT1603_R92 0x92
-#define VT1603_R93 0x93
-#define VT1603_R95 0x95
-#define VT1603_R96 0x96
-#define VT1603_R97 0x97
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wl1273.c b/ANDROID_3.4.5/sound/soc/codecs/wl1273.c
deleted file mode 100644
index 3d868dc4..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wl1273.c
+++ /dev/null
@@ -1,517 +0,0 @@
-/*
- * ALSA SoC WL1273 codec driver
- *
- * Author: Matti Aaltonen, <matti.j.aaltonen@nokia.com>
- *
- * Copyright: (C) 2010, 2011 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/mfd/wl1273-core.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-
-#include "wl1273.h"
-
-enum wl1273_mode { WL1273_MODE_BT, WL1273_MODE_FM_RX, WL1273_MODE_FM_TX };
-
-/* codec private data */
-struct wl1273_priv {
- enum wl1273_mode mode;
- struct wl1273_core *core;
- unsigned int channels;
-};
-
-static int snd_wl1273_fm_set_i2s_mode(struct wl1273_core *core,
- int rate, int width)
-{
- struct device *dev = &core->client->dev;
- int r = 0;
- u16 mode;
-
- dev_dbg(dev, "rate: %d\n", rate);
- dev_dbg(dev, "width: %d\n", width);
-
- mutex_lock(&core->lock);
-
- mode = core->i2s_mode & ~WL1273_IS2_WIDTH & ~WL1273_IS2_RATE;
-
- switch (rate) {
- case 48000:
- mode |= WL1273_IS2_RATE_48K;
- break;
- case 44100:
- mode |= WL1273_IS2_RATE_44_1K;
- break;
- case 32000:
- mode |= WL1273_IS2_RATE_32K;
- break;
- case 22050:
- mode |= WL1273_IS2_RATE_22_05K;
- break;
- case 16000:
- mode |= WL1273_IS2_RATE_16K;
- break;
- case 12000:
- mode |= WL1273_IS2_RATE_12K;
- break;
- case 11025:
- mode |= WL1273_IS2_RATE_11_025;
- break;
- case 8000:
- mode |= WL1273_IS2_RATE_8K;
- break;
- default:
- dev_err(dev, "Sampling rate: %d not supported\n", rate);
- r = -EINVAL;
- goto out;
- }
-
- switch (width) {
- case 16:
- mode |= WL1273_IS2_WIDTH_32;
- break;
- case 20:
- mode |= WL1273_IS2_WIDTH_40;
- break;
- case 24:
- mode |= WL1273_IS2_WIDTH_48;
- break;
- case 25:
- mode |= WL1273_IS2_WIDTH_50;
- break;
- case 30:
- mode |= WL1273_IS2_WIDTH_60;
- break;
- case 32:
- mode |= WL1273_IS2_WIDTH_64;
- break;
- case 40:
- mode |= WL1273_IS2_WIDTH_80;
- break;
- case 48:
- mode |= WL1273_IS2_WIDTH_96;
- break;
- case 64:
- mode |= WL1273_IS2_WIDTH_128;
- break;
- default:
- dev_err(dev, "Data width: %d not supported\n", width);
- r = -EINVAL;
- goto out;
- }
-
- dev_dbg(dev, "WL1273_I2S_DEF_MODE: 0x%04x\n", WL1273_I2S_DEF_MODE);
- dev_dbg(dev, "core->i2s_mode: 0x%04x\n", core->i2s_mode);
- dev_dbg(dev, "mode: 0x%04x\n", mode);
-
- if (core->i2s_mode != mode) {
- r = core->write(core, WL1273_I2S_MODE_CONFIG_SET, mode);
- if (r)
- goto out;
-
- core->i2s_mode = mode;
- r = core->write(core, WL1273_AUDIO_ENABLE,
- WL1273_AUDIO_ENABLE_I2S);
- if (r)
- goto out;
- }
-out:
- mutex_unlock(&core->lock);
-
- return r;
-}
-
-static int snd_wl1273_fm_set_channel_number(struct wl1273_core *core,
- int channel_number)
-{
- struct device *dev = &core->client->dev;
- int r = 0;
-
- dev_dbg(dev, "%s\n", __func__);
-
- mutex_lock(&core->lock);
-
- if (core->channel_number == channel_number)
- goto out;
-
- if (channel_number == 1 && core->mode == WL1273_MODE_RX)
- r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_MONO);
- else if (channel_number == 1 && core->mode == WL1273_MODE_TX)
- r = core->write(core, WL1273_MONO_SET, WL1273_TX_MONO);
- else if (channel_number == 2 && core->mode == WL1273_MODE_RX)
- r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_STEREO);
- else if (channel_number == 2 && core->mode == WL1273_MODE_TX)
- r = core->write(core, WL1273_MONO_SET, WL1273_TX_STEREO);
- else
- r = -EINVAL;
-out:
- mutex_unlock(&core->lock);
-
- return r;
-}
-
-static int snd_wl1273_get_audio_route(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.integer.value[0] = wl1273->mode;
-
- return 0;
-}
-
-/*
- * TODO: Implement the audio routing in the driver. Now this control
- * only indicates the setting that has been done elsewhere (in the user
- * space).
- */
-static const char * const wl1273_audio_route[] = { "Bt", "FmRx", "FmTx" };
-
-static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
-
- if (wl1273->mode == ucontrol->value.integer.value[0])
- return 0;
-
- /* Do not allow changes while stream is running */
- if (codec->active)
- return -EPERM;
-
- if (ucontrol->value.integer.value[0] < 0 ||
- ucontrol->value.integer.value[0] >= ARRAY_SIZE(wl1273_audio_route))
- return -EINVAL;
-
- wl1273->mode = ucontrol->value.integer.value[0];
-
- return 1;
-}
-
-static const struct soc_enum wl1273_enum =
- SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wl1273_audio_route), wl1273_audio_route);
-
-static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
-
- dev_dbg(codec->dev, "%s: enter.\n", __func__);
-
- ucontrol->value.integer.value[0] = wl1273->core->audio_mode;
-
- return 0;
-}
-
-static int snd_wl1273_fm_audio_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
- int val, r = 0;
-
- dev_dbg(codec->dev, "%s: enter.\n", __func__);
-
- val = ucontrol->value.integer.value[0];
- if (wl1273->core->audio_mode == val)
- return 0;
-
- r = wl1273->core->set_audio(wl1273->core, val);
- if (r < 0)
- return r;
-
- return 1;
-}
-
-static const char * const wl1273_audio_strings[] = { "Digital", "Analog" };
-
-static const struct soc_enum wl1273_audio_enum =
- SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wl1273_audio_strings),
- wl1273_audio_strings);
-
-static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
-
- dev_dbg(codec->dev, "%s: enter.\n", __func__);
-
- ucontrol->value.integer.value[0] = wl1273->core->volume;
-
- return 0;
-}
-
-static int snd_wl1273_fm_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
- int r;
-
- dev_dbg(codec->dev, "%s: enter.\n", __func__);
-
- r = wl1273->core->set_volume(wl1273->core,
- ucontrol->value.integer.value[0]);
- if (r)
- return r;
-
- return 1;
-}
-
-static const struct snd_kcontrol_new wl1273_controls[] = {
- SOC_ENUM_EXT("Codec Mode", wl1273_enum,
- snd_wl1273_get_audio_route, snd_wl1273_set_audio_route),
- SOC_ENUM_EXT("Audio Switch", wl1273_audio_enum,
- snd_wl1273_fm_audio_get, snd_wl1273_fm_audio_put),
- SOC_SINGLE_EXT("Volume", 0, 0, WL1273_MAX_VOLUME, 0,
- snd_wl1273_fm_volume_get, snd_wl1273_fm_volume_put),
-};
-
-static int wl1273_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
-
- switch (wl1273->mode) {
- case WL1273_MODE_BT:
- snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_RATE,
- 8000, 8000);
- snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_CHANNELS, 1, 1);
- break;
- case WL1273_MODE_FM_RX:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- pr_err("Cannot play in RX mode.\n");
- return -EINVAL;
- }
- break;
- case WL1273_MODE_FM_TX:
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- pr_err("Cannot capture in TX mode.\n");
- return -EINVAL;
- }
- break;
- default:
- return -EINVAL;
- break;
- }
-
- return 0;
-}
-
-static int wl1273_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(rtd->codec);
- struct wl1273_core *core = wl1273->core;
- unsigned int rate, width, r;
-
- if (params_format(params) != SNDRV_PCM_FORMAT_S16_LE) {
- pr_err("Only SNDRV_PCM_FORMAT_S16_LE supported.\n");
- return -EINVAL;
- }
-
- rate = params_rate(params);
- width = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;
-
- if (wl1273->mode == WL1273_MODE_BT) {
- if (rate != 8000) {
- pr_err("Rate %d not supported.\n", params_rate(params));
- return -EINVAL;
- }
-
- if (params_channels(params) != 1) {
- pr_err("Only mono supported.\n");
- return -EINVAL;
- }
-
- return 0;
- }
-
- if (wl1273->mode == WL1273_MODE_FM_TX &&
- substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- pr_err("Only playback supported with TX.\n");
- return -EINVAL;
- }
-
- if (wl1273->mode == WL1273_MODE_FM_RX &&
- substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- pr_err("Only capture supported with RX.\n");
- return -EINVAL;
- }
-
- if (wl1273->mode != WL1273_MODE_FM_RX &&
- wl1273->mode != WL1273_MODE_FM_TX) {
- pr_err("Unexpected mode: %d.\n", wl1273->mode);
- return -EINVAL;
- }
-
- r = snd_wl1273_fm_set_i2s_mode(core, rate, width);
- if (r)
- return r;
-
- wl1273->channels = params_channels(params);
- r = snd_wl1273_fm_set_channel_number(core, wl1273->channels);
- if (r)
- return r;
-
- return 0;
-}
-
-static const struct snd_soc_dai_ops wl1273_dai_ops = {
- .startup = wl1273_startup,
- .hw_params = wl1273_hw_params,
-};
-
-static struct snd_soc_dai_driver wl1273_dai = {
- .name = "wl1273-fm",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE},
- .ops = &wl1273_dai_ops,
-};
-
-/* Audio interface format for the soc_card driver */
-int wl1273_get_format(struct snd_soc_codec *codec, unsigned int *fmt)
-{
- struct wl1273_priv *wl1273;
-
- if (codec == NULL || fmt == NULL)
- return -EINVAL;
-
- wl1273 = snd_soc_codec_get_drvdata(codec);
-
- switch (wl1273->mode) {
- case WL1273_MODE_FM_RX:
- case WL1273_MODE_FM_TX:
- *fmt = SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM;
-
- break;
- case WL1273_MODE_BT:
- *fmt = SND_SOC_DAIFMT_DSP_A |
- SND_SOC_DAIFMT_IB_NF |
- SND_SOC_DAIFMT_CBM_CFM;
-
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(wl1273_get_format);
-
-static int wl1273_probe(struct snd_soc_codec *codec)
-{
- struct wl1273_core **core = codec->dev->platform_data;
- struct wl1273_priv *wl1273;
- int r;
-
- dev_dbg(codec->dev, "%s.\n", __func__);
-
- if (!core) {
- dev_err(codec->dev, "Platform data is missing.\n");
- return -EINVAL;
- }
-
- wl1273 = kzalloc(sizeof(struct wl1273_priv), GFP_KERNEL);
- if (wl1273 == NULL) {
- dev_err(codec->dev, "Cannot allocate memory.\n");
- return -ENOMEM;
- }
-
- wl1273->mode = WL1273_MODE_BT;
- wl1273->core = *core;
-
- snd_soc_codec_set_drvdata(codec, wl1273);
-
- r = snd_soc_add_codec_controls(codec, wl1273_controls,
- ARRAY_SIZE(wl1273_controls));
- if (r)
- kfree(wl1273);
-
- return r;
-}
-
-static int wl1273_remove(struct snd_soc_codec *codec)
-{
- struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
-
- dev_dbg(codec->dev, "%s\n", __func__);
- kfree(wl1273);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wl1273 = {
- .probe = wl1273_probe,
- .remove = wl1273_remove,
-};
-
-static int __devinit wl1273_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wl1273,
- &wl1273_dai, 1);
-}
-
-static int __devexit wl1273_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-MODULE_ALIAS("platform:wl1273-codec");
-
-static struct platform_driver wl1273_platform_driver = {
- .driver = {
- .name = "wl1273-codec",
- .owner = THIS_MODULE,
- },
- .probe = wl1273_platform_probe,
- .remove = __devexit_p(wl1273_platform_remove),
-};
-
-module_platform_driver(wl1273_platform_driver);
-
-MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>");
-MODULE_DESCRIPTION("ASoC WL1273 codec driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wl1273.h b/ANDROID_3.4.5/sound/soc/codecs/wl1273.h
deleted file mode 100644
index 43ec7e66..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wl1273.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * sound/soc/codec/wl1273.h
- *
- * ALSA SoC WL1273 codec driver
- *
- * Copyright (C) Nokia Corporation
- * Author: Matti Aaltonen <matti.j.aaltonen@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __WL1273_CODEC_H__
-#define __WL1273_CODEC_H__
-
-int wl1273_get_format(struct snd_soc_codec *codec, unsigned int *fmt);
-
-#endif /* End of __WL1273_CODEC_H__ */
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm1250-ev1.c b/ANDROID_3.4.5/sound/soc/codecs/wm1250-ev1.c
deleted file mode 100644
index aefb4f89..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm1250-ev1.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Driver for the 1250-EV1 audio I/O module
- *
- * Copyright 2011 Wolfson Microelectronics plc
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/gpio.h>
-
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/wm1250-ev1.h>
-
-static const char *wm1250_gpio_names[WM1250_EV1_NUM_GPIOS] = {
- "WM1250 CLK_ENA",
- "WM1250 CLK_SEL0",
- "WM1250 CLK_SEL1",
- "WM1250 OSR",
- "WM1250 MASTER",
-};
-
-struct wm1250_priv {
- struct gpio gpios[WM1250_EV1_NUM_GPIOS];
-};
-
-static int wm1250_ev1_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct wm1250_priv *wm1250 = dev_get_drvdata(codec->dev);
- int ena;
-
- if (wm1250)
- ena = wm1250->gpios[WM1250_EV1_GPIO_CLK_ENA].gpio;
- else
- ena = -1;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (ena >= 0)
- gpio_set_value_cansleep(ena, 1);
- break;
-
- case SND_SOC_BIAS_OFF:
- if (ena >= 0)
- gpio_set_value_cansleep(ena, 0);
- break;
- }
-
- codec->dapm.bias_level = level;
-
- return 0;
-}
-
-static const struct snd_soc_dapm_widget wm1250_ev1_dapm_widgets[] = {
-SND_SOC_DAPM_ADC("ADC", "wm1250-ev1 Capture", SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_DAC("DAC", "wm1250-ev1 Playback", SND_SOC_NOPM, 0, 0),
-
-SND_SOC_DAPM_INPUT("WM1250 Input"),
-SND_SOC_DAPM_OUTPUT("WM1250 Output"),
-};
-
-static const struct snd_soc_dapm_route wm1250_ev1_dapm_routes[] = {
- { "ADC", NULL, "WM1250 Input" },
- { "WM1250 Output", NULL, "DAC" },
-};
-
-static struct snd_soc_dai_driver wm1250_ev1_dai = {
- .name = "wm1250-ev1",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 1,
- .rates = SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 1,
- .rates = SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
-};
-
-static struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = {
- .dapm_widgets = wm1250_ev1_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm1250_ev1_dapm_widgets),
- .dapm_routes = wm1250_ev1_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm1250_ev1_dapm_routes),
-
- .set_bias_level = wm1250_ev1_set_bias_level,
- .idle_bias_off = true,
-};
-
-static int __devinit wm1250_ev1_pdata(struct i2c_client *i2c)
-{
- struct wm1250_ev1_pdata *pdata = dev_get_platdata(&i2c->dev);
- struct wm1250_priv *wm1250;
- int i, ret;
-
- if (!pdata)
- return 0;
-
- wm1250 = devm_kzalloc(&i2c->dev, sizeof(*wm1250), GFP_KERNEL);
- if (!wm1250) {
- dev_err(&i2c->dev, "Unable to allocate private data\n");
- ret = -ENOMEM;
- goto err;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm1250->gpios); i++) {
- wm1250->gpios[i].gpio = pdata->gpios[i];
- wm1250->gpios[i].label = wm1250_gpio_names[i];
- wm1250->gpios[i].flags = GPIOF_OUT_INIT_LOW;
- }
- wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL0].flags = GPIOF_OUT_INIT_HIGH;
- wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL1].flags = GPIOF_OUT_INIT_HIGH;
-
- ret = gpio_request_array(wm1250->gpios, ARRAY_SIZE(wm1250->gpios));
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to get GPIOs: %d\n", ret);
- goto err;
- }
-
- dev_set_drvdata(&i2c->dev, wm1250);
-
- return ret;
-
-err:
- return ret;
-}
-
-static void wm1250_ev1_free(struct i2c_client *i2c)
-{
- struct wm1250_priv *wm1250 = dev_get_drvdata(&i2c->dev);
-
- if (wm1250)
- gpio_free_array(wm1250->gpios, ARRAY_SIZE(wm1250->gpios));
-}
-
-static int __devinit wm1250_ev1_probe(struct i2c_client *i2c,
- const struct i2c_device_id *i2c_id)
-{
- int id, board, rev, ret;
-
- dev_set_drvdata(&i2c->dev, NULL);
-
- board = i2c_smbus_read_byte_data(i2c, 0);
- if (board < 0) {
- dev_err(&i2c->dev, "Failed to read ID: %d\n", board);
- return board;
- }
-
- id = (board & 0xfe) >> 2;
- rev = board & 0x3;
-
- if (id != 1) {
- dev_err(&i2c->dev, "Unknown board ID %d\n", id);
- return -ENODEV;
- }
-
- dev_info(&i2c->dev, "revision %d\n", rev + 1);
-
- ret = wm1250_ev1_pdata(i2c);
- if (ret != 0)
- return ret;
-
- ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm1250_ev1,
- &wm1250_ev1_dai, 1);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
- wm1250_ev1_free(i2c);
- return ret;
- }
-
- return 0;
-}
-
-static int __devexit wm1250_ev1_remove(struct i2c_client *i2c)
-{
- snd_soc_unregister_codec(&i2c->dev);
- wm1250_ev1_free(i2c);
-
- return 0;
-}
-
-static const struct i2c_device_id wm1250_ev1_i2c_id[] = {
- { "wm1250-ev1", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm1250_ev1_i2c_id);
-
-static struct i2c_driver wm1250_ev1_i2c_driver = {
- .driver = {
- .name = "wm1250-ev1",
- .owner = THIS_MODULE,
- },
- .probe = wm1250_ev1_probe,
- .remove = __devexit_p(wm1250_ev1_remove),
- .id_table = wm1250_ev1_i2c_id,
-};
-
-static int __init wm1250_ev1_modinit(void)
-{
- int ret = 0;
-
- ret = i2c_add_driver(&wm1250_ev1_i2c_driver);
- if (ret != 0)
- pr_err("Failed to register WM1250-EV1 I2C driver: %d\n", ret);
-
- return ret;
-}
-module_init(wm1250_ev1_modinit);
-
-static void __exit wm1250_ev1_exit(void)
-{
- i2c_del_driver(&wm1250_ev1_i2c_driver);
-}
-module_exit(wm1250_ev1_exit);
-
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_DESCRIPTION("WM1250-EV1 audio I/O module driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm2000.c b/ANDROID_3.4.5/sound/soc/codecs/wm2000.c
deleted file mode 100644
index a75c3766..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm2000.c
+++ /dev/null
@@ -1,862 +0,0 @@
-/*
- * wm2000.c -- WM2000 ALSA Soc Audio driver
- *
- * Copyright 2008-2010 Wolfson Microelectronics PLC.
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * The download image for the WM2000 will be requested as
- * 'wm2000_anc.bin' by default (overridable via platform data) at
- * runtime and is expected to be in flat binary format. This is
- * generated by Wolfson configuration tools and includes
- * system-specific callibration information. If supplied as a
- * sequence of ASCII-encoded hexidecimal bytes this can be converted
- * into a flat binary with a command such as this on the command line:
- *
- * perl -e 'while (<>) { s/[\r\n]+// ; printf("%c", hex($_)); }'
- * < file > wm2000_anc.bin
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/firmware.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/regmap.h>
-#include <linux/debugfs.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include <sound/wm2000.h>
-
-#include "wm2000.h"
-
-enum wm2000_anc_mode {
- ANC_ACTIVE = 0,
- ANC_BYPASS = 1,
- ANC_STANDBY = 2,
- ANC_OFF = 3,
-};
-
-struct wm2000_priv {
- struct i2c_client *i2c;
- struct regmap *regmap;
-
- enum wm2000_anc_mode anc_mode;
-
- unsigned int anc_active:1;
- unsigned int anc_eng_ena:1;
- unsigned int spk_ena:1;
-
- unsigned int mclk_div:1;
- unsigned int speech_clarity:1;
-
- int anc_download_size;
- char *anc_download;
-};
-
-static int wm2000_write(struct i2c_client *i2c, unsigned int reg,
- unsigned int value)
-{
- struct wm2000_priv *wm2000 = i2c_get_clientdata(i2c);
- return regmap_write(wm2000->regmap, reg, value);
-}
-
-static unsigned int wm2000_read(struct i2c_client *i2c, unsigned int r)
-{
- struct wm2000_priv *wm2000 = i2c_get_clientdata(i2c);
- unsigned int val;
- int ret;
-
- ret = regmap_read(wm2000->regmap, r, &val);
- if (ret < 0)
- return -1;
-
- return val;
-}
-
-static void wm2000_reset(struct wm2000_priv *wm2000)
-{
- struct i2c_client *i2c = wm2000->i2c;
-
- wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_ENG_CLR);
- wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_CLR);
- wm2000_write(i2c, WM2000_REG_ID1, 0);
-
- wm2000->anc_mode = ANC_OFF;
-}
-
-static int wm2000_poll_bit(struct i2c_client *i2c,
- unsigned int reg, u8 mask, int timeout)
-{
- int val;
-
- val = wm2000_read(i2c, reg);
-
- while (!(val & mask) && --timeout) {
- msleep(1);
- val = wm2000_read(i2c, reg);
- }
-
- if (timeout == 0)
- return 0;
- else
- return 1;
-}
-
-static int wm2000_power_up(struct i2c_client *i2c, int analogue)
-{
- struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
- int ret, timeout;
-
- BUG_ON(wm2000->anc_mode != ANC_OFF);
-
- dev_dbg(&i2c->dev, "Beginning power up\n");
-
- if (!wm2000->mclk_div) {
- dev_dbg(&i2c->dev, "Disabling MCLK divider\n");
- wm2000_write(i2c, WM2000_REG_SYS_CTL2,
- WM2000_MCLK_DIV2_ENA_CLR);
- } else {
- dev_dbg(&i2c->dev, "Enabling MCLK divider\n");
- wm2000_write(i2c, WM2000_REG_SYS_CTL2,
- WM2000_MCLK_DIV2_ENA_SET);
- }
-
- wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_ENG_CLR);
- wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_ENG_SET);
-
- /* Wait for ANC engine to become ready */
- if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
- WM2000_ANC_ENG_IDLE, 1)) {
- dev_err(&i2c->dev, "ANC engine failed to reset\n");
- return -ETIMEDOUT;
- }
-
- if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
- WM2000_STATUS_BOOT_COMPLETE, 1)) {
- dev_err(&i2c->dev, "ANC engine failed to initialise\n");
- return -ETIMEDOUT;
- }
-
- wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_SET);
-
- /* Open code download of the data since it is the only bulk
- * write we do. */
- dev_dbg(&i2c->dev, "Downloading %d bytes\n",
- wm2000->anc_download_size - 2);
-
- ret = i2c_master_send(i2c, wm2000->anc_download,
- wm2000->anc_download_size);
- if (ret < 0) {
- dev_err(&i2c->dev, "i2c_transfer() failed: %d\n", ret);
- return ret;
- }
- if (ret != wm2000->anc_download_size) {
- dev_err(&i2c->dev, "i2c_transfer() failed, %d != %d\n",
- ret, wm2000->anc_download_size);
- return -EIO;
- }
-
- dev_dbg(&i2c->dev, "Download complete\n");
-
- if (analogue) {
- timeout = 248;
- wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, timeout / 4);
-
- wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
- WM2000_MODE_ANA_SEQ_INCLUDE |
- WM2000_MODE_MOUSE_ENABLE |
- WM2000_MODE_THERMAL_ENABLE);
- } else {
- timeout = 10;
-
- wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
- WM2000_MODE_MOUSE_ENABLE |
- WM2000_MODE_THERMAL_ENABLE);
- }
-
- ret = wm2000_read(i2c, WM2000_REG_SPEECH_CLARITY);
- if (wm2000->speech_clarity)
- ret &= ~WM2000_SPEECH_CLARITY;
- else
- ret |= WM2000_SPEECH_CLARITY;
- wm2000_write(i2c, WM2000_REG_SPEECH_CLARITY, ret);
-
- wm2000_write(i2c, WM2000_REG_SYS_START0, 0x33);
- wm2000_write(i2c, WM2000_REG_SYS_START1, 0x02);
-
- wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);
-
- if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
- WM2000_STATUS_MOUSE_ACTIVE, timeout)) {
- dev_err(&i2c->dev, "Timed out waiting for device after %dms\n",
- timeout * 10);
- return -ETIMEDOUT;
- }
-
- dev_dbg(&i2c->dev, "ANC active\n");
- if (analogue)
- dev_dbg(&i2c->dev, "Analogue active\n");
- wm2000->anc_mode = ANC_ACTIVE;
-
- return 0;
-}
-
-static int wm2000_power_down(struct i2c_client *i2c, int analogue)
-{
- struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
- int timeout;
-
- if (analogue) {
- timeout = 248;
- wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, timeout / 4);
- wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
- WM2000_MODE_ANA_SEQ_INCLUDE |
- WM2000_MODE_POWER_DOWN);
- } else {
- timeout = 10;
- wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
- WM2000_MODE_POWER_DOWN);
- }
-
- if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
- WM2000_STATUS_POWER_DOWN_COMPLETE, timeout)) {
- dev_err(&i2c->dev, "Timeout waiting for ANC power down\n");
- return -ETIMEDOUT;
- }
-
- if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
- WM2000_ANC_ENG_IDLE, 1)) {
- dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n");
- return -ETIMEDOUT;
- }
-
- dev_dbg(&i2c->dev, "powered off\n");
- wm2000->anc_mode = ANC_OFF;
-
- return 0;
-}
-
-static int wm2000_enter_bypass(struct i2c_client *i2c, int analogue)
-{
- struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
-
- BUG_ON(wm2000->anc_mode != ANC_ACTIVE);
-
- if (analogue) {
- wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
- WM2000_MODE_ANA_SEQ_INCLUDE |
- WM2000_MODE_THERMAL_ENABLE |
- WM2000_MODE_BYPASS_ENTRY);
- } else {
- wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
- WM2000_MODE_THERMAL_ENABLE |
- WM2000_MODE_BYPASS_ENTRY);
- }
-
- if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
- WM2000_STATUS_ANC_DISABLED, 10)) {
- dev_err(&i2c->dev, "Timeout waiting for ANC disable\n");
- return -ETIMEDOUT;
- }
-
- if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
- WM2000_ANC_ENG_IDLE, 1)) {
- dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n");
- return -ETIMEDOUT;
- }
-
- wm2000_write(i2c, WM2000_REG_SYS_CTL1, WM2000_SYS_STBY);
- wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_CLR);
-
- wm2000->anc_mode = ANC_BYPASS;
- dev_dbg(&i2c->dev, "bypass enabled\n");
-
- return 0;
-}
-
-static int wm2000_exit_bypass(struct i2c_client *i2c, int analogue)
-{
- struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
-
- BUG_ON(wm2000->anc_mode != ANC_BYPASS);
-
- wm2000_write(i2c, WM2000_REG_SYS_CTL1, 0);
-
- if (analogue) {
- wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
- WM2000_MODE_ANA_SEQ_INCLUDE |
- WM2000_MODE_MOUSE_ENABLE |
- WM2000_MODE_THERMAL_ENABLE);
- } else {
- wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
- WM2000_MODE_MOUSE_ENABLE |
- WM2000_MODE_THERMAL_ENABLE);
- }
-
- wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_SET);
- wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);
-
- if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
- WM2000_STATUS_MOUSE_ACTIVE, 10)) {
- dev_err(&i2c->dev, "Timed out waiting for MOUSE\n");
- return -ETIMEDOUT;
- }
-
- wm2000->anc_mode = ANC_ACTIVE;
- dev_dbg(&i2c->dev, "MOUSE active\n");
-
- return 0;
-}
-
-static int wm2000_enter_standby(struct i2c_client *i2c, int analogue)
-{
- struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
- int timeout;
-
- BUG_ON(wm2000->anc_mode != ANC_ACTIVE);
-
- if (analogue) {
- timeout = 248;
- wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, timeout / 4);
-
- wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
- WM2000_MODE_ANA_SEQ_INCLUDE |
- WM2000_MODE_THERMAL_ENABLE |
- WM2000_MODE_STANDBY_ENTRY);
- } else {
- timeout = 10;
-
- wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
- WM2000_MODE_THERMAL_ENABLE |
- WM2000_MODE_STANDBY_ENTRY);
- }
-
- if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
- WM2000_STATUS_ANC_DISABLED, timeout)) {
- dev_err(&i2c->dev,
- "Timed out waiting for ANC disable after 1ms\n");
- return -ETIMEDOUT;
- }
-
- if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, WM2000_ANC_ENG_IDLE,
- 1)) {
- dev_err(&i2c->dev,
- "Timed out waiting for standby after %dms\n",
- timeout * 10);
- return -ETIMEDOUT;
- }
-
- wm2000_write(i2c, WM2000_REG_SYS_CTL1, WM2000_SYS_STBY);
- wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_CLR);
-
- wm2000->anc_mode = ANC_STANDBY;
- dev_dbg(&i2c->dev, "standby\n");
- if (analogue)
- dev_dbg(&i2c->dev, "Analogue disabled\n");
-
- return 0;
-}
-
-static int wm2000_exit_standby(struct i2c_client *i2c, int analogue)
-{
- struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
- int timeout;
-
- BUG_ON(wm2000->anc_mode != ANC_STANDBY);
-
- wm2000_write(i2c, WM2000_REG_SYS_CTL1, 0);
-
- if (analogue) {
- timeout = 248;
- wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, timeout / 4);
-
- wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
- WM2000_MODE_ANA_SEQ_INCLUDE |
- WM2000_MODE_THERMAL_ENABLE |
- WM2000_MODE_MOUSE_ENABLE);
- } else {
- timeout = 10;
-
- wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
- WM2000_MODE_THERMAL_ENABLE |
- WM2000_MODE_MOUSE_ENABLE);
- }
-
- wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_SET);
- wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);
-
- if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
- WM2000_STATUS_MOUSE_ACTIVE, timeout)) {
- dev_err(&i2c->dev, "Timed out waiting for MOUSE after %dms\n",
- timeout * 10);
- return -ETIMEDOUT;
- }
-
- wm2000->anc_mode = ANC_ACTIVE;
- dev_dbg(&i2c->dev, "MOUSE active\n");
- if (analogue)
- dev_dbg(&i2c->dev, "Analogue enabled\n");
-
- return 0;
-}
-
-typedef int (*wm2000_mode_fn)(struct i2c_client *i2c, int analogue);
-
-static struct {
- enum wm2000_anc_mode source;
- enum wm2000_anc_mode dest;
- int analogue;
- wm2000_mode_fn step[2];
-} anc_transitions[] = {
- {
- .source = ANC_OFF,
- .dest = ANC_ACTIVE,
- .analogue = 1,
- .step = {
- wm2000_power_up,
- },
- },
- {
- .source = ANC_OFF,
- .dest = ANC_STANDBY,
- .step = {
- wm2000_power_up,
- wm2000_enter_standby,
- },
- },
- {
- .source = ANC_OFF,
- .dest = ANC_BYPASS,
- .analogue = 1,
- .step = {
- wm2000_power_up,
- wm2000_enter_bypass,
- },
- },
- {
- .source = ANC_ACTIVE,
- .dest = ANC_BYPASS,
- .analogue = 1,
- .step = {
- wm2000_enter_bypass,
- },
- },
- {
- .source = ANC_ACTIVE,
- .dest = ANC_STANDBY,
- .analogue = 1,
- .step = {
- wm2000_enter_standby,
- },
- },
- {
- .source = ANC_ACTIVE,
- .dest = ANC_OFF,
- .analogue = 1,
- .step = {
- wm2000_power_down,
- },
- },
- {
- .source = ANC_BYPASS,
- .dest = ANC_ACTIVE,
- .analogue = 1,
- .step = {
- wm2000_exit_bypass,
- },
- },
- {
- .source = ANC_BYPASS,
- .dest = ANC_STANDBY,
- .analogue = 1,
- .step = {
- wm2000_exit_bypass,
- wm2000_enter_standby,
- },
- },
- {
- .source = ANC_BYPASS,
- .dest = ANC_OFF,
- .step = {
- wm2000_exit_bypass,
- wm2000_power_down,
- },
- },
- {
- .source = ANC_STANDBY,
- .dest = ANC_ACTIVE,
- .analogue = 1,
- .step = {
- wm2000_exit_standby,
- },
- },
- {
- .source = ANC_STANDBY,
- .dest = ANC_BYPASS,
- .analogue = 1,
- .step = {
- wm2000_exit_standby,
- wm2000_enter_bypass,
- },
- },
- {
- .source = ANC_STANDBY,
- .dest = ANC_OFF,
- .step = {
- wm2000_exit_standby,
- wm2000_power_down,
- },
- },
-};
-
-static int wm2000_anc_transition(struct wm2000_priv *wm2000,
- enum wm2000_anc_mode mode)
-{
- struct i2c_client *i2c = wm2000->i2c;
- int i, j;
- int ret;
-
- if (wm2000->anc_mode == mode)
- return 0;
-
- for (i = 0; i < ARRAY_SIZE(anc_transitions); i++)
- if (anc_transitions[i].source == wm2000->anc_mode &&
- anc_transitions[i].dest == mode)
- break;
- if (i == ARRAY_SIZE(anc_transitions)) {
- dev_err(&i2c->dev, "No transition for %d->%d\n",
- wm2000->anc_mode, mode);
- return -EINVAL;
- }
-
- for (j = 0; j < ARRAY_SIZE(anc_transitions[j].step); j++) {
- if (!anc_transitions[i].step[j])
- break;
- ret = anc_transitions[i].step[j](i2c,
- anc_transitions[i].analogue);
- if (ret != 0)
- return ret;
- }
-
- return 0;
-}
-
-static int wm2000_anc_set_mode(struct wm2000_priv *wm2000)
-{
- struct i2c_client *i2c = wm2000->i2c;
- enum wm2000_anc_mode mode;
-
- if (wm2000->anc_eng_ena && wm2000->spk_ena)
- if (wm2000->anc_active)
- mode = ANC_ACTIVE;
- else
- mode = ANC_BYPASS;
- else
- mode = ANC_STANDBY;
-
- dev_dbg(&i2c->dev, "Set mode %d (enabled %d, mute %d, active %d)\n",
- mode, wm2000->anc_eng_ena, !wm2000->spk_ena,
- wm2000->anc_active);
-
- return wm2000_anc_transition(wm2000, mode);
-}
-
-static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
-
- ucontrol->value.enumerated.item[0] = wm2000->anc_active;
-
- return 0;
-}
-
-static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
- int anc_active = ucontrol->value.enumerated.item[0];
-
- if (anc_active > 1)
- return -EINVAL;
-
- wm2000->anc_active = anc_active;
-
- return wm2000_anc_set_mode(wm2000);
-}
-
-static int wm2000_speaker_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
-
- ucontrol->value.enumerated.item[0] = wm2000->spk_ena;
-
- return 0;
-}
-
-static int wm2000_speaker_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
- int val = ucontrol->value.enumerated.item[0];
-
- if (val > 1)
- return -EINVAL;
-
- wm2000->spk_ena = val;
-
- return wm2000_anc_set_mode(wm2000);
-}
-
-static const struct snd_kcontrol_new wm2000_controls[] = {
- SOC_SINGLE_BOOL_EXT("WM2000 ANC Switch", 0,
- wm2000_anc_mode_get,
- wm2000_anc_mode_put),
- SOC_SINGLE_BOOL_EXT("WM2000 Switch", 0,
- wm2000_speaker_get,
- wm2000_speaker_put),
-};
-
-static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
-
- if (SND_SOC_DAPM_EVENT_ON(event))
- wm2000->anc_eng_ena = 1;
-
- if (SND_SOC_DAPM_EVENT_OFF(event))
- wm2000->anc_eng_ena = 0;
-
- return wm2000_anc_set_mode(wm2000);
-}
-
-static const struct snd_soc_dapm_widget wm2000_dapm_widgets[] = {
-/* Externally visible pins */
-SND_SOC_DAPM_OUTPUT("SPKN"),
-SND_SOC_DAPM_OUTPUT("SPKP"),
-
-SND_SOC_DAPM_INPUT("LINN"),
-SND_SOC_DAPM_INPUT("LINP"),
-
-SND_SOC_DAPM_PGA_E("ANC Engine", SND_SOC_NOPM, 0, 0, NULL, 0,
- wm2000_anc_power_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-};
-
-/* Target, Path, Source */
-static const struct snd_soc_dapm_route wm2000_audio_map[] = {
- { "SPKN", NULL, "ANC Engine" },
- { "SPKP", NULL, "ANC Engine" },
- { "ANC Engine", NULL, "LINN" },
- { "ANC Engine", NULL, "LINP" },
-};
-
-#ifdef CONFIG_PM
-static int wm2000_suspend(struct snd_soc_codec *codec)
-{
- struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
-
- return wm2000_anc_transition(wm2000, ANC_OFF);
-}
-
-static int wm2000_resume(struct snd_soc_codec *codec)
-{
- struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
-
- return wm2000_anc_set_mode(wm2000);
-}
-#else
-#define wm2000_suspend NULL
-#define wm2000_resume NULL
-#endif
-
-static const struct regmap_config wm2000_regmap = {
- .reg_bits = 8,
- .val_bits = 8,
-};
-
-static int wm2000_probe(struct snd_soc_codec *codec)
-{
- struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
-
- /* This will trigger a transition to standby mode by default */
- wm2000_anc_set_mode(wm2000);
-
- return 0;
-}
-
-static int wm2000_remove(struct snd_soc_codec *codec)
-{
- struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
-
- return wm2000_anc_transition(wm2000, ANC_OFF);
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm2000 = {
- .probe = wm2000_probe,
- .remove = wm2000_remove,
- .suspend = wm2000_suspend,
- .resume = wm2000_resume,
-
- .dapm_widgets = wm2000_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm2000_dapm_widgets),
- .dapm_routes = wm2000_audio_map,
- .num_dapm_routes = ARRAY_SIZE(wm2000_audio_map),
- .controls = wm2000_controls,
- .num_controls = ARRAY_SIZE(wm2000_controls),
-};
-
-static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *i2c_id)
-{
- struct wm2000_priv *wm2000;
- struct wm2000_platform_data *pdata;
- const char *filename;
- const struct firmware *fw = NULL;
- int ret;
- int reg;
- u16 id;
-
- wm2000 = devm_kzalloc(&i2c->dev, sizeof(struct wm2000_priv),
- GFP_KERNEL);
- if (wm2000 == NULL) {
- dev_err(&i2c->dev, "Unable to allocate private data\n");
- return -ENOMEM;
- }
-
- dev_set_drvdata(&i2c->dev, wm2000);
-
- wm2000->regmap = regmap_init_i2c(i2c, &wm2000_regmap);
- if (IS_ERR(wm2000->regmap)) {
- ret = PTR_ERR(wm2000->regmap);
- dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
- ret);
- goto out;
- }
-
- /* Verify that this is a WM2000 */
- reg = wm2000_read(i2c, WM2000_REG_ID1);
- id = reg << 8;
- reg = wm2000_read(i2c, WM2000_REG_ID2);
- id |= reg & 0xff;
-
- if (id != 0x2000) {
- dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id);
- ret = -ENODEV;
- goto out_regmap_exit;
- }
-
- reg = wm2000_read(i2c, WM2000_REG_REVISON);
- dev_info(&i2c->dev, "revision %c\n", reg + 'A');
-
- filename = "wm2000_anc.bin";
- pdata = dev_get_platdata(&i2c->dev);
- if (pdata) {
- wm2000->mclk_div = pdata->mclkdiv2;
- wm2000->speech_clarity = !pdata->speech_enh_disable;
-
- if (pdata->download_file)
- filename = pdata->download_file;
- }
-
- ret = request_firmware(&fw, filename, &i2c->dev);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret);
- goto out_regmap_exit;
- }
-
- /* Pre-cook the concatenation of the register address onto the image */
- wm2000->anc_download_size = fw->size + 2;
- wm2000->anc_download = devm_kzalloc(&i2c->dev,
- wm2000->anc_download_size,
- GFP_KERNEL);
- if (wm2000->anc_download == NULL) {
- dev_err(&i2c->dev, "Out of memory\n");
- ret = -ENOMEM;
- goto out_regmap_exit;
- }
-
- wm2000->anc_download[0] = 0x80;
- wm2000->anc_download[1] = 0x00;
- memcpy(wm2000->anc_download + 2, fw->data, fw->size);
-
- wm2000->anc_eng_ena = 1;
- wm2000->anc_active = 1;
- wm2000->spk_ena = 1;
- wm2000->i2c = i2c;
-
- wm2000_reset(wm2000);
-
- ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0);
- if (!ret)
- goto out;
-
-out_regmap_exit:
- regmap_exit(wm2000->regmap);
-out:
- release_firmware(fw);
- return ret;
-}
-
-static __devexit int wm2000_i2c_remove(struct i2c_client *i2c)
-{
- struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
-
- snd_soc_unregister_codec(&i2c->dev);
- regmap_exit(wm2000->regmap);
-
- return 0;
-}
-
-static const struct i2c_device_id wm2000_i2c_id[] = {
- { "wm2000", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm2000_i2c_id);
-
-static struct i2c_driver wm2000_i2c_driver = {
- .driver = {
- .name = "wm2000",
- .owner = THIS_MODULE,
- },
- .probe = wm2000_i2c_probe,
- .remove = __devexit_p(wm2000_i2c_remove),
- .id_table = wm2000_i2c_id,
-};
-
-static int __init wm2000_init(void)
-{
- return i2c_add_driver(&wm2000_i2c_driver);
-}
-module_init(wm2000_init);
-
-static void __exit wm2000_exit(void)
-{
- i2c_del_driver(&wm2000_i2c_driver);
-}
-module_exit(wm2000_exit);
-
-MODULE_DESCRIPTION("ASoC WM2000 driver");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm2000.h b/ANDROID_3.4.5/sound/soc/codecs/wm2000.h
deleted file mode 100644
index abcd82a9..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm2000.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * wm2000.h -- WM2000 Soc Audio driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM2000_H
-#define _WM2000_H
-
-#define WM2000_REG_SYS_START 0x8000
-#define WM2000_REG_SPEECH_CLARITY 0x8fef
-#define WM2000_REG_SYS_WATCHDOG 0x8ff6
-#define WM2000_REG_ANA_VMID_PD_TIME 0x8ff7
-#define WM2000_REG_ANA_VMID_PU_TIME 0x8ff8
-#define WM2000_REG_CAT_FLTR_INDX 0x8ff9
-#define WM2000_REG_CAT_GAIN_0 0x8ffa
-#define WM2000_REG_SYS_STATUS 0x8ffc
-#define WM2000_REG_SYS_MODE_CNTRL 0x8ffd
-#define WM2000_REG_SYS_START0 0x8ffe
-#define WM2000_REG_SYS_START1 0x8fff
-#define WM2000_REG_ID1 0xf000
-#define WM2000_REG_ID2 0xf001
-#define WM2000_REG_REVISON 0xf002
-#define WM2000_REG_SYS_CTL1 0xf003
-#define WM2000_REG_SYS_CTL2 0xf004
-#define WM2000_REG_ANC_STAT 0xf005
-#define WM2000_REG_IF_CTL 0xf006
-
-/* SPEECH_CLARITY */
-#define WM2000_SPEECH_CLARITY 0x01
-
-/* SYS_STATUS */
-#define WM2000_STATUS_MOUSE_ACTIVE 0x40
-#define WM2000_STATUS_CAT_FREQ_COMPLETE 0x20
-#define WM2000_STATUS_CAT_GAIN_COMPLETE 0x10
-#define WM2000_STATUS_THERMAL_SHUTDOWN_COMPLETE 0x08
-#define WM2000_STATUS_ANC_DISABLED 0x04
-#define WM2000_STATUS_POWER_DOWN_COMPLETE 0x02
-#define WM2000_STATUS_BOOT_COMPLETE 0x01
-
-/* SYS_MODE_CNTRL */
-#define WM2000_MODE_ANA_SEQ_INCLUDE 0x80
-#define WM2000_MODE_MOUSE_ENABLE 0x40
-#define WM2000_MODE_CAT_FREQ_ENABLE 0x20
-#define WM2000_MODE_CAT_GAIN_ENABLE 0x10
-#define WM2000_MODE_BYPASS_ENTRY 0x08
-#define WM2000_MODE_STANDBY_ENTRY 0x04
-#define WM2000_MODE_THERMAL_ENABLE 0x02
-#define WM2000_MODE_POWER_DOWN 0x01
-
-/* SYS_CTL1 */
-#define WM2000_SYS_STBY 0x01
-
-/* SYS_CTL2 */
-#define WM2000_MCLK_DIV2_ENA_CLR 0x80
-#define WM2000_MCLK_DIV2_ENA_SET 0x40
-#define WM2000_ANC_ENG_CLR 0x20
-#define WM2000_ANC_ENG_SET 0x10
-#define WM2000_ANC_INT_N_CLR 0x08
-#define WM2000_ANC_INT_N_SET 0x04
-#define WM2000_RAM_CLR 0x02
-#define WM2000_RAM_SET 0x01
-
-/* ANC_STAT */
-#define WM2000_ANC_ENG_IDLE 0x01
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm2200.c b/ANDROID_3.4.5/sound/soc/codecs/wm2200.c
deleted file mode 100644
index 32682c1b..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm2200.c
+++ /dev/null
@@ -1,2287 +0,0 @@
-/*
- * wm2200.c -- WM2200 ALSA SoC Audio driver
- *
- * Copyright 2012 Wolfson Microelectronics plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/gcd.h>
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-#include <linux/pm_runtime.h>
-#include <linux/regulator/consumer.h>
-#include <linux/regulator/fixed.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/jack.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <sound/wm2200.h>
-
-#include "wm2200.h"
-
-/* The code assumes DCVDD is generated internally */
-#define WM2200_NUM_CORE_SUPPLIES 2
-static const char *wm2200_core_supply_names[WM2200_NUM_CORE_SUPPLIES] = {
- "DBVDD",
- "LDOVDD",
-};
-
-struct wm2200_fll {
- int fref;
- int fout;
- int src;
- struct completion lock;
-};
-
-/* codec private data */
-struct wm2200_priv {
- struct regmap *regmap;
- struct device *dev;
- struct snd_soc_codec *codec;
- struct wm2200_pdata pdata;
- struct regulator_bulk_data core_supplies[WM2200_NUM_CORE_SUPPLIES];
-
- struct completion fll_lock;
- int fll_fout;
- int fll_fref;
- int fll_src;
-
- int rev;
- int sysclk;
-};
-
-static struct reg_default wm2200_reg_defaults[] = {
- { 0x000B, 0x0000 }, /* R11 - Tone Generator 1 */
- { 0x0102, 0x0000 }, /* R258 - Clocking 3 */
- { 0x0103, 0x0011 }, /* R259 - Clocking 4 */
- { 0x0111, 0x0000 }, /* R273 - FLL Control 1 */
- { 0x0112, 0x0000 }, /* R274 - FLL Control 2 */
- { 0x0113, 0x0000 }, /* R275 - FLL Control 3 */
- { 0x0114, 0x0000 }, /* R276 - FLL Control 4 */
- { 0x0116, 0x0177 }, /* R278 - FLL Control 6 */
- { 0x0117, 0x0004 }, /* R279 - FLL Control 7 */
- { 0x0119, 0x0000 }, /* R281 - FLL EFS 1 */
- { 0x011A, 0x0002 }, /* R282 - FLL EFS 2 */
- { 0x0200, 0x0000 }, /* R512 - Mic Charge Pump 1 */
- { 0x0201, 0x03FF }, /* R513 - Mic Charge Pump 2 */
- { 0x0202, 0x9BDE }, /* R514 - DM Charge Pump 1 */
- { 0x020C, 0x0000 }, /* R524 - Mic Bias Ctrl 1 */
- { 0x020D, 0x0000 }, /* R525 - Mic Bias Ctrl 2 */
- { 0x020F, 0x0000 }, /* R527 - Ear Piece Ctrl 1 */
- { 0x0210, 0x0000 }, /* R528 - Ear Piece Ctrl 2 */
- { 0x0301, 0x0000 }, /* R769 - Input Enables */
- { 0x0302, 0x2240 }, /* R770 - IN1L Control */
- { 0x0303, 0x0040 }, /* R771 - IN1R Control */
- { 0x0304, 0x2240 }, /* R772 - IN2L Control */
- { 0x0305, 0x0040 }, /* R773 - IN2R Control */
- { 0x0306, 0x2240 }, /* R774 - IN3L Control */
- { 0x0307, 0x0040 }, /* R775 - IN3R Control */
- { 0x030A, 0x0000 }, /* R778 - RXANC_SRC */
- { 0x030B, 0x0022 }, /* R779 - Input Volume Ramp */
- { 0x030C, 0x0180 }, /* R780 - ADC Digital Volume 1L */
- { 0x030D, 0x0180 }, /* R781 - ADC Digital Volume 1R */
- { 0x030E, 0x0180 }, /* R782 - ADC Digital Volume 2L */
- { 0x030F, 0x0180 }, /* R783 - ADC Digital Volume 2R */
- { 0x0310, 0x0180 }, /* R784 - ADC Digital Volume 3L */
- { 0x0311, 0x0180 }, /* R785 - ADC Digital Volume 3R */
- { 0x0400, 0x0000 }, /* R1024 - Output Enables */
- { 0x0401, 0x0000 }, /* R1025 - DAC Volume Limit 1L */
- { 0x0402, 0x0000 }, /* R1026 - DAC Volume Limit 1R */
- { 0x0403, 0x0000 }, /* R1027 - DAC Volume Limit 2L */
- { 0x0404, 0x0000 }, /* R1028 - DAC Volume Limit 2R */
- { 0x0409, 0x0000 }, /* R1033 - DAC AEC Control 1 */
- { 0x040A, 0x0022 }, /* R1034 - Output Volume Ramp */
- { 0x040B, 0x0180 }, /* R1035 - DAC Digital Volume 1L */
- { 0x040C, 0x0180 }, /* R1036 - DAC Digital Volume 1R */
- { 0x040D, 0x0180 }, /* R1037 - DAC Digital Volume 2L */
- { 0x040E, 0x0180 }, /* R1038 - DAC Digital Volume 2R */
- { 0x0417, 0x0069 }, /* R1047 - PDM 1 */
- { 0x0418, 0x0000 }, /* R1048 - PDM 2 */
- { 0x0500, 0x0000 }, /* R1280 - Audio IF 1_1 */
- { 0x0501, 0x0008 }, /* R1281 - Audio IF 1_2 */
- { 0x0502, 0x0000 }, /* R1282 - Audio IF 1_3 */
- { 0x0503, 0x0000 }, /* R1283 - Audio IF 1_4 */
- { 0x0504, 0x0000 }, /* R1284 - Audio IF 1_5 */
- { 0x0505, 0x0001 }, /* R1285 - Audio IF 1_6 */
- { 0x0506, 0x0001 }, /* R1286 - Audio IF 1_7 */
- { 0x0507, 0x0000 }, /* R1287 - Audio IF 1_8 */
- { 0x0508, 0x0000 }, /* R1288 - Audio IF 1_9 */
- { 0x0509, 0x0000 }, /* R1289 - Audio IF 1_10 */
- { 0x050A, 0x0000 }, /* R1290 - Audio IF 1_11 */
- { 0x050B, 0x0000 }, /* R1291 - Audio IF 1_12 */
- { 0x050C, 0x0000 }, /* R1292 - Audio IF 1_13 */
- { 0x050D, 0x0000 }, /* R1293 - Audio IF 1_14 */
- { 0x050E, 0x0000 }, /* R1294 - Audio IF 1_15 */
- { 0x050F, 0x0000 }, /* R1295 - Audio IF 1_16 */
- { 0x0510, 0x0000 }, /* R1296 - Audio IF 1_17 */
- { 0x0511, 0x0000 }, /* R1297 - Audio IF 1_18 */
- { 0x0512, 0x0000 }, /* R1298 - Audio IF 1_19 */
- { 0x0513, 0x0000 }, /* R1299 - Audio IF 1_20 */
- { 0x0514, 0x0000 }, /* R1300 - Audio IF 1_21 */
- { 0x0515, 0x0001 }, /* R1301 - Audio IF 1_22 */
- { 0x0600, 0x0000 }, /* R1536 - OUT1LMIX Input 1 Source */
- { 0x0601, 0x0080 }, /* R1537 - OUT1LMIX Input 1 Volume */
- { 0x0602, 0x0000 }, /* R1538 - OUT1LMIX Input 2 Source */
- { 0x0603, 0x0080 }, /* R1539 - OUT1LMIX Input 2 Volume */
- { 0x0604, 0x0000 }, /* R1540 - OUT1LMIX Input 3 Source */
- { 0x0605, 0x0080 }, /* R1541 - OUT1LMIX Input 3 Volume */
- { 0x0606, 0x0000 }, /* R1542 - OUT1LMIX Input 4 Source */
- { 0x0607, 0x0080 }, /* R1543 - OUT1LMIX Input 4 Volume */
- { 0x0608, 0x0000 }, /* R1544 - OUT1RMIX Input 1 Source */
- { 0x0609, 0x0080 }, /* R1545 - OUT1RMIX Input 1 Volume */
- { 0x060A, 0x0000 }, /* R1546 - OUT1RMIX Input 2 Source */
- { 0x060B, 0x0080 }, /* R1547 - OUT1RMIX Input 2 Volume */
- { 0x060C, 0x0000 }, /* R1548 - OUT1RMIX Input 3 Source */
- { 0x060D, 0x0080 }, /* R1549 - OUT1RMIX Input 3 Volume */
- { 0x060E, 0x0000 }, /* R1550 - OUT1RMIX Input 4 Source */
- { 0x060F, 0x0080 }, /* R1551 - OUT1RMIX Input 4 Volume */
- { 0x0610, 0x0000 }, /* R1552 - OUT2LMIX Input 1 Source */
- { 0x0611, 0x0080 }, /* R1553 - OUT2LMIX Input 1 Volume */
- { 0x0612, 0x0000 }, /* R1554 - OUT2LMIX Input 2 Source */
- { 0x0613, 0x0080 }, /* R1555 - OUT2LMIX Input 2 Volume */
- { 0x0614, 0x0000 }, /* R1556 - OUT2LMIX Input 3 Source */
- { 0x0615, 0x0080 }, /* R1557 - OUT2LMIX Input 3 Volume */
- { 0x0616, 0x0000 }, /* R1558 - OUT2LMIX Input 4 Source */
- { 0x0617, 0x0080 }, /* R1559 - OUT2LMIX Input 4 Volume */
- { 0x0618, 0x0000 }, /* R1560 - OUT2RMIX Input 1 Source */
- { 0x0619, 0x0080 }, /* R1561 - OUT2RMIX Input 1 Volume */
- { 0x061A, 0x0000 }, /* R1562 - OUT2RMIX Input 2 Source */
- { 0x061B, 0x0080 }, /* R1563 - OUT2RMIX Input 2 Volume */
- { 0x061C, 0x0000 }, /* R1564 - OUT2RMIX Input 3 Source */
- { 0x061D, 0x0080 }, /* R1565 - OUT2RMIX Input 3 Volume */
- { 0x061E, 0x0000 }, /* R1566 - OUT2RMIX Input 4 Source */
- { 0x061F, 0x0080 }, /* R1567 - OUT2RMIX Input 4 Volume */
- { 0x0620, 0x0000 }, /* R1568 - AIF1TX1MIX Input 1 Source */
- { 0x0621, 0x0080 }, /* R1569 - AIF1TX1MIX Input 1 Volume */
- { 0x0622, 0x0000 }, /* R1570 - AIF1TX1MIX Input 2 Source */
- { 0x0623, 0x0080 }, /* R1571 - AIF1TX1MIX Input 2 Volume */
- { 0x0624, 0x0000 }, /* R1572 - AIF1TX1MIX Input 3 Source */
- { 0x0625, 0x0080 }, /* R1573 - AIF1TX1MIX Input 3 Volume */
- { 0x0626, 0x0000 }, /* R1574 - AIF1TX1MIX Input 4 Source */
- { 0x0627, 0x0080 }, /* R1575 - AIF1TX1MIX Input 4 Volume */
- { 0x0628, 0x0000 }, /* R1576 - AIF1TX2MIX Input 1 Source */
- { 0x0629, 0x0080 }, /* R1577 - AIF1TX2MIX Input 1 Volume */
- { 0x062A, 0x0000 }, /* R1578 - AIF1TX2MIX Input 2 Source */
- { 0x062B, 0x0080 }, /* R1579 - AIF1TX2MIX Input 2 Volume */
- { 0x062C, 0x0000 }, /* R1580 - AIF1TX2MIX Input 3 Source */
- { 0x062D, 0x0080 }, /* R1581 - AIF1TX2MIX Input 3 Volume */
- { 0x062E, 0x0000 }, /* R1582 - AIF1TX2MIX Input 4 Source */
- { 0x062F, 0x0080 }, /* R1583 - AIF1TX2MIX Input 4 Volume */
- { 0x0630, 0x0000 }, /* R1584 - AIF1TX3MIX Input 1 Source */
- { 0x0631, 0x0080 }, /* R1585 - AIF1TX3MIX Input 1 Volume */
- { 0x0632, 0x0000 }, /* R1586 - AIF1TX3MIX Input 2 Source */
- { 0x0633, 0x0080 }, /* R1587 - AIF1TX3MIX Input 2 Volume */
- { 0x0634, 0x0000 }, /* R1588 - AIF1TX3MIX Input 3 Source */
- { 0x0635, 0x0080 }, /* R1589 - AIF1TX3MIX Input 3 Volume */
- { 0x0636, 0x0000 }, /* R1590 - AIF1TX3MIX Input 4 Source */
- { 0x0637, 0x0080 }, /* R1591 - AIF1TX3MIX Input 4 Volume */
- { 0x0638, 0x0000 }, /* R1592 - AIF1TX4MIX Input 1 Source */
- { 0x0639, 0x0080 }, /* R1593 - AIF1TX4MIX Input 1 Volume */
- { 0x063A, 0x0000 }, /* R1594 - AIF1TX4MIX Input 2 Source */
- { 0x063B, 0x0080 }, /* R1595 - AIF1TX4MIX Input 2 Volume */
- { 0x063C, 0x0000 }, /* R1596 - AIF1TX4MIX Input 3 Source */
- { 0x063D, 0x0080 }, /* R1597 - AIF1TX4MIX Input 3 Volume */
- { 0x063E, 0x0000 }, /* R1598 - AIF1TX4MIX Input 4 Source */
- { 0x063F, 0x0080 }, /* R1599 - AIF1TX4MIX Input 4 Volume */
- { 0x0640, 0x0000 }, /* R1600 - AIF1TX5MIX Input 1 Source */
- { 0x0641, 0x0080 }, /* R1601 - AIF1TX5MIX Input 1 Volume */
- { 0x0642, 0x0000 }, /* R1602 - AIF1TX5MIX Input 2 Source */
- { 0x0643, 0x0080 }, /* R1603 - AIF1TX5MIX Input 2 Volume */
- { 0x0644, 0x0000 }, /* R1604 - AIF1TX5MIX Input 3 Source */
- { 0x0645, 0x0080 }, /* R1605 - AIF1TX5MIX Input 3 Volume */
- { 0x0646, 0x0000 }, /* R1606 - AIF1TX5MIX Input 4 Source */
- { 0x0647, 0x0080 }, /* R1607 - AIF1TX5MIX Input 4 Volume */
- { 0x0648, 0x0000 }, /* R1608 - AIF1TX6MIX Input 1 Source */
- { 0x0649, 0x0080 }, /* R1609 - AIF1TX6MIX Input 1 Volume */
- { 0x064A, 0x0000 }, /* R1610 - AIF1TX6MIX Input 2 Source */
- { 0x064B, 0x0080 }, /* R1611 - AIF1TX6MIX Input 2 Volume */
- { 0x064C, 0x0000 }, /* R1612 - AIF1TX6MIX Input 3 Source */
- { 0x064D, 0x0080 }, /* R1613 - AIF1TX6MIX Input 3 Volume */
- { 0x064E, 0x0000 }, /* R1614 - AIF1TX6MIX Input 4 Source */
- { 0x064F, 0x0080 }, /* R1615 - AIF1TX6MIX Input 4 Volume */
- { 0x0650, 0x0000 }, /* R1616 - EQLMIX Input 1 Source */
- { 0x0651, 0x0080 }, /* R1617 - EQLMIX Input 1 Volume */
- { 0x0652, 0x0000 }, /* R1618 - EQLMIX Input 2 Source */
- { 0x0653, 0x0080 }, /* R1619 - EQLMIX Input 2 Volume */
- { 0x0654, 0x0000 }, /* R1620 - EQLMIX Input 3 Source */
- { 0x0655, 0x0080 }, /* R1621 - EQLMIX Input 3 Volume */
- { 0x0656, 0x0000 }, /* R1622 - EQLMIX Input 4 Source */
- { 0x0657, 0x0080 }, /* R1623 - EQLMIX Input 4 Volume */
- { 0x0658, 0x0000 }, /* R1624 - EQRMIX Input 1 Source */
- { 0x0659, 0x0080 }, /* R1625 - EQRMIX Input 1 Volume */
- { 0x065A, 0x0000 }, /* R1626 - EQRMIX Input 2 Source */
- { 0x065B, 0x0080 }, /* R1627 - EQRMIX Input 2 Volume */
- { 0x065C, 0x0000 }, /* R1628 - EQRMIX Input 3 Source */
- { 0x065D, 0x0080 }, /* R1629 - EQRMIX Input 3 Volume */
- { 0x065E, 0x0000 }, /* R1630 - EQRMIX Input 4 Source */
- { 0x065F, 0x0080 }, /* R1631 - EQRMIX Input 4 Volume */
- { 0x0660, 0x0000 }, /* R1632 - LHPF1MIX Input 1 Source */
- { 0x0661, 0x0080 }, /* R1633 - LHPF1MIX Input 1 Volume */
- { 0x0662, 0x0000 }, /* R1634 - LHPF1MIX Input 2 Source */
- { 0x0663, 0x0080 }, /* R1635 - LHPF1MIX Input 2 Volume */
- { 0x0664, 0x0000 }, /* R1636 - LHPF1MIX Input 3 Source */
- { 0x0665, 0x0080 }, /* R1637 - LHPF1MIX Input 3 Volume */
- { 0x0666, 0x0000 }, /* R1638 - LHPF1MIX Input 4 Source */
- { 0x0667, 0x0080 }, /* R1639 - LHPF1MIX Input 4 Volume */
- { 0x0668, 0x0000 }, /* R1640 - LHPF2MIX Input 1 Source */
- { 0x0669, 0x0080 }, /* R1641 - LHPF2MIX Input 1 Volume */
- { 0x066A, 0x0000 }, /* R1642 - LHPF2MIX Input 2 Source */
- { 0x066B, 0x0080 }, /* R1643 - LHPF2MIX Input 2 Volume */
- { 0x066C, 0x0000 }, /* R1644 - LHPF2MIX Input 3 Source */
- { 0x066D, 0x0080 }, /* R1645 - LHPF2MIX Input 3 Volume */
- { 0x066E, 0x0000 }, /* R1646 - LHPF2MIX Input 4 Source */
- { 0x066F, 0x0080 }, /* R1647 - LHPF2MIX Input 4 Volume */
- { 0x0670, 0x0000 }, /* R1648 - DSP1LMIX Input 1 Source */
- { 0x0671, 0x0080 }, /* R1649 - DSP1LMIX Input 1 Volume */
- { 0x0672, 0x0000 }, /* R1650 - DSP1LMIX Input 2 Source */
- { 0x0673, 0x0080 }, /* R1651 - DSP1LMIX Input 2 Volume */
- { 0x0674, 0x0000 }, /* R1652 - DSP1LMIX Input 3 Source */
- { 0x0675, 0x0080 }, /* R1653 - DSP1LMIX Input 3 Volume */
- { 0x0676, 0x0000 }, /* R1654 - DSP1LMIX Input 4 Source */
- { 0x0677, 0x0080 }, /* R1655 - DSP1LMIX Input 4 Volume */
- { 0x0678, 0x0000 }, /* R1656 - DSP1RMIX Input 1 Source */
- { 0x0679, 0x0080 }, /* R1657 - DSP1RMIX Input 1 Volume */
- { 0x067A, 0x0000 }, /* R1658 - DSP1RMIX Input 2 Source */
- { 0x067B, 0x0080 }, /* R1659 - DSP1RMIX Input 2 Volume */
- { 0x067C, 0x0000 }, /* R1660 - DSP1RMIX Input 3 Source */
- { 0x067D, 0x0080 }, /* R1661 - DSP1RMIX Input 3 Volume */
- { 0x067E, 0x0000 }, /* R1662 - DSP1RMIX Input 4 Source */
- { 0x067F, 0x0080 }, /* R1663 - DSP1RMIX Input 4 Volume */
- { 0x0680, 0x0000 }, /* R1664 - DSP1AUX1MIX Input 1 Source */
- { 0x0681, 0x0000 }, /* R1665 - DSP1AUX2MIX Input 1 Source */
- { 0x0682, 0x0000 }, /* R1666 - DSP1AUX3MIX Input 1 Source */
- { 0x0683, 0x0000 }, /* R1667 - DSP1AUX4MIX Input 1 Source */
- { 0x0684, 0x0000 }, /* R1668 - DSP1AUX5MIX Input 1 Source */
- { 0x0685, 0x0000 }, /* R1669 - DSP1AUX6MIX Input 1 Source */
- { 0x0686, 0x0000 }, /* R1670 - DSP2LMIX Input 1 Source */
- { 0x0687, 0x0080 }, /* R1671 - DSP2LMIX Input 1 Volume */
- { 0x0688, 0x0000 }, /* R1672 - DSP2LMIX Input 2 Source */
- { 0x0689, 0x0080 }, /* R1673 - DSP2LMIX Input 2 Volume */
- { 0x068A, 0x0000 }, /* R1674 - DSP2LMIX Input 3 Source */
- { 0x068B, 0x0080 }, /* R1675 - DSP2LMIX Input 3 Volume */
- { 0x068C, 0x0000 }, /* R1676 - DSP2LMIX Input 4 Source */
- { 0x068D, 0x0080 }, /* R1677 - DSP2LMIX Input 4 Volume */
- { 0x068E, 0x0000 }, /* R1678 - DSP2RMIX Input 1 Source */
- { 0x068F, 0x0080 }, /* R1679 - DSP2RMIX Input 1 Volume */
- { 0x0690, 0x0000 }, /* R1680 - DSP2RMIX Input 2 Source */
- { 0x0691, 0x0080 }, /* R1681 - DSP2RMIX Input 2 Volume */
- { 0x0692, 0x0000 }, /* R1682 - DSP2RMIX Input 3 Source */
- { 0x0693, 0x0080 }, /* R1683 - DSP2RMIX Input 3 Volume */
- { 0x0694, 0x0000 }, /* R1684 - DSP2RMIX Input 4 Source */
- { 0x0695, 0x0080 }, /* R1685 - DSP2RMIX Input 4 Volume */
- { 0x0696, 0x0000 }, /* R1686 - DSP2AUX1MIX Input 1 Source */
- { 0x0697, 0x0000 }, /* R1687 - DSP2AUX2MIX Input 1 Source */
- { 0x0698, 0x0000 }, /* R1688 - DSP2AUX3MIX Input 1 Source */
- { 0x0699, 0x0000 }, /* R1689 - DSP2AUX4MIX Input 1 Source */
- { 0x069A, 0x0000 }, /* R1690 - DSP2AUX5MIX Input 1 Source */
- { 0x069B, 0x0000 }, /* R1691 - DSP2AUX6MIX Input 1 Source */
- { 0x0700, 0xA101 }, /* R1792 - GPIO CTRL 1 */
- { 0x0701, 0xA101 }, /* R1793 - GPIO CTRL 2 */
- { 0x0702, 0xA101 }, /* R1794 - GPIO CTRL 3 */
- { 0x0703, 0xA101 }, /* R1795 - GPIO CTRL 4 */
- { 0x0709, 0x0000 }, /* R1801 - Misc Pad Ctrl 1 */
- { 0x0801, 0x00FF }, /* R2049 - Interrupt Status 1 Mask */
- { 0x0804, 0xFFFF }, /* R2052 - Interrupt Status 2 Mask */
- { 0x0808, 0x0000 }, /* R2056 - Interrupt Control */
- { 0x0900, 0x0000 }, /* R2304 - EQL_1 */
- { 0x0901, 0x0000 }, /* R2305 - EQL_2 */
- { 0x0902, 0x0000 }, /* R2306 - EQL_3 */
- { 0x0903, 0x0000 }, /* R2307 - EQL_4 */
- { 0x0904, 0x0000 }, /* R2308 - EQL_5 */
- { 0x0905, 0x0000 }, /* R2309 - EQL_6 */
- { 0x0906, 0x0000 }, /* R2310 - EQL_7 */
- { 0x0907, 0x0000 }, /* R2311 - EQL_8 */
- { 0x0908, 0x0000 }, /* R2312 - EQL_9 */
- { 0x0909, 0x0000 }, /* R2313 - EQL_10 */
- { 0x090A, 0x0000 }, /* R2314 - EQL_11 */
- { 0x090B, 0x0000 }, /* R2315 - EQL_12 */
- { 0x090C, 0x0000 }, /* R2316 - EQL_13 */
- { 0x090D, 0x0000 }, /* R2317 - EQL_14 */
- { 0x090E, 0x0000 }, /* R2318 - EQL_15 */
- { 0x090F, 0x0000 }, /* R2319 - EQL_16 */
- { 0x0910, 0x0000 }, /* R2320 - EQL_17 */
- { 0x0911, 0x0000 }, /* R2321 - EQL_18 */
- { 0x0912, 0x0000 }, /* R2322 - EQL_19 */
- { 0x0913, 0x0000 }, /* R2323 - EQL_20 */
- { 0x0916, 0x0000 }, /* R2326 - EQR_1 */
- { 0x0917, 0x0000 }, /* R2327 - EQR_2 */
- { 0x0918, 0x0000 }, /* R2328 - EQR_3 */
- { 0x0919, 0x0000 }, /* R2329 - EQR_4 */
- { 0x091A, 0x0000 }, /* R2330 - EQR_5 */
- { 0x091B, 0x0000 }, /* R2331 - EQR_6 */
- { 0x091C, 0x0000 }, /* R2332 - EQR_7 */
- { 0x091D, 0x0000 }, /* R2333 - EQR_8 */
- { 0x091E, 0x0000 }, /* R2334 - EQR_9 */
- { 0x091F, 0x0000 }, /* R2335 - EQR_10 */
- { 0x0920, 0x0000 }, /* R2336 - EQR_11 */
- { 0x0921, 0x0000 }, /* R2337 - EQR_12 */
- { 0x0922, 0x0000 }, /* R2338 - EQR_13 */
- { 0x0923, 0x0000 }, /* R2339 - EQR_14 */
- { 0x0924, 0x0000 }, /* R2340 - EQR_15 */
- { 0x0925, 0x0000 }, /* R2341 - EQR_16 */
- { 0x0926, 0x0000 }, /* R2342 - EQR_17 */
- { 0x0927, 0x0000 }, /* R2343 - EQR_18 */
- { 0x0928, 0x0000 }, /* R2344 - EQR_19 */
- { 0x0929, 0x0000 }, /* R2345 - EQR_20 */
- { 0x093E, 0x0000 }, /* R2366 - HPLPF1_1 */
- { 0x093F, 0x0000 }, /* R2367 - HPLPF1_2 */
- { 0x0942, 0x0000 }, /* R2370 - HPLPF2_1 */
- { 0x0943, 0x0000 }, /* R2371 - HPLPF2_2 */
- { 0x0A00, 0x0000 }, /* R2560 - DSP1 Control 1 */
- { 0x0A02, 0x0000 }, /* R2562 - DSP1 Control 2 */
- { 0x0A03, 0x0000 }, /* R2563 - DSP1 Control 3 */
- { 0x0A04, 0x0000 }, /* R2564 - DSP1 Control 4 */
- { 0x0A06, 0x0000 }, /* R2566 - DSP1 Control 5 */
- { 0x0A07, 0x0000 }, /* R2567 - DSP1 Control 6 */
- { 0x0A08, 0x0000 }, /* R2568 - DSP1 Control 7 */
- { 0x0A09, 0x0000 }, /* R2569 - DSP1 Control 8 */
- { 0x0A0A, 0x0000 }, /* R2570 - DSP1 Control 9 */
- { 0x0A0B, 0x0000 }, /* R2571 - DSP1 Control 10 */
- { 0x0A0C, 0x0000 }, /* R2572 - DSP1 Control 11 */
- { 0x0A0D, 0x0000 }, /* R2573 - DSP1 Control 12 */
- { 0x0A0F, 0x0000 }, /* R2575 - DSP1 Control 13 */
- { 0x0A10, 0x0000 }, /* R2576 - DSP1 Control 14 */
- { 0x0A11, 0x0000 }, /* R2577 - DSP1 Control 15 */
- { 0x0A12, 0x0000 }, /* R2578 - DSP1 Control 16 */
- { 0x0A13, 0x0000 }, /* R2579 - DSP1 Control 17 */
- { 0x0A14, 0x0000 }, /* R2580 - DSP1 Control 18 */
- { 0x0A16, 0x0000 }, /* R2582 - DSP1 Control 19 */
- { 0x0A17, 0x0000 }, /* R2583 - DSP1 Control 20 */
- { 0x0A18, 0x0000 }, /* R2584 - DSP1 Control 21 */
- { 0x0A1A, 0x1800 }, /* R2586 - DSP1 Control 22 */
- { 0x0A1B, 0x1000 }, /* R2587 - DSP1 Control 23 */
- { 0x0A1C, 0x0400 }, /* R2588 - DSP1 Control 24 */
- { 0x0A1E, 0x0000 }, /* R2590 - DSP1 Control 25 */
- { 0x0A20, 0x0000 }, /* R2592 - DSP1 Control 26 */
- { 0x0A21, 0x0000 }, /* R2593 - DSP1 Control 27 */
- { 0x0A22, 0x0000 }, /* R2594 - DSP1 Control 28 */
- { 0x0A23, 0x0000 }, /* R2595 - DSP1 Control 29 */
- { 0x0A24, 0x0000 }, /* R2596 - DSP1 Control 30 */
- { 0x0A26, 0x0000 }, /* R2598 - DSP1 Control 31 */
- { 0x0B00, 0x0000 }, /* R2816 - DSP2 Control 1 */
- { 0x0B02, 0x0000 }, /* R2818 - DSP2 Control 2 */
- { 0x0B03, 0x0000 }, /* R2819 - DSP2 Control 3 */
- { 0x0B04, 0x0000 }, /* R2820 - DSP2 Control 4 */
- { 0x0B06, 0x0000 }, /* R2822 - DSP2 Control 5 */
- { 0x0B07, 0x0000 }, /* R2823 - DSP2 Control 6 */
- { 0x0B08, 0x0000 }, /* R2824 - DSP2 Control 7 */
- { 0x0B09, 0x0000 }, /* R2825 - DSP2 Control 8 */
- { 0x0B0A, 0x0000 }, /* R2826 - DSP2 Control 9 */
- { 0x0B0B, 0x0000 }, /* R2827 - DSP2 Control 10 */
- { 0x0B0C, 0x0000 }, /* R2828 - DSP2 Control 11 */
- { 0x0B0D, 0x0000 }, /* R2829 - DSP2 Control 12 */
- { 0x0B0F, 0x0000 }, /* R2831 - DSP2 Control 13 */
- { 0x0B10, 0x0000 }, /* R2832 - DSP2 Control 14 */
- { 0x0B11, 0x0000 }, /* R2833 - DSP2 Control 15 */
- { 0x0B12, 0x0000 }, /* R2834 - DSP2 Control 16 */
- { 0x0B13, 0x0000 }, /* R2835 - DSP2 Control 17 */
- { 0x0B14, 0x0000 }, /* R2836 - DSP2 Control 18 */
- { 0x0B16, 0x0000 }, /* R2838 - DSP2 Control 19 */
- { 0x0B17, 0x0000 }, /* R2839 - DSP2 Control 20 */
- { 0x0B18, 0x0000 }, /* R2840 - DSP2 Control 21 */
- { 0x0B1A, 0x0800 }, /* R2842 - DSP2 Control 22 */
- { 0x0B1B, 0x1000 }, /* R2843 - DSP2 Control 23 */
- { 0x0B1C, 0x0400 }, /* R2844 - DSP2 Control 24 */
- { 0x0B1E, 0x0000 }, /* R2846 - DSP2 Control 25 */
- { 0x0B20, 0x0000 }, /* R2848 - DSP2 Control 26 */
- { 0x0B21, 0x0000 }, /* R2849 - DSP2 Control 27 */
- { 0x0B22, 0x0000 }, /* R2850 - DSP2 Control 28 */
- { 0x0B23, 0x0000 }, /* R2851 - DSP2 Control 29 */
- { 0x0B24, 0x0000 }, /* R2852 - DSP2 Control 30 */
- { 0x0B26, 0x0000 }, /* R2854 - DSP2 Control 31 */
-};
-
-static bool wm2200_volatile_register(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM2200_SOFTWARE_RESET:
- case WM2200_DEVICE_REVISION:
- case WM2200_ADPS1_IRQ0:
- case WM2200_ADPS1_IRQ1:
- case WM2200_INTERRUPT_STATUS_1:
- case WM2200_INTERRUPT_STATUS_2:
- case WM2200_INTERRUPT_RAW_STATUS_2:
- return true;
- default:
- return false;
- }
-}
-
-static bool wm2200_readable_register(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM2200_SOFTWARE_RESET:
- case WM2200_DEVICE_REVISION:
- case WM2200_TONE_GENERATOR_1:
- case WM2200_CLOCKING_3:
- case WM2200_CLOCKING_4:
- case WM2200_FLL_CONTROL_1:
- case WM2200_FLL_CONTROL_2:
- case WM2200_FLL_CONTROL_3:
- case WM2200_FLL_CONTROL_4:
- case WM2200_FLL_CONTROL_6:
- case WM2200_FLL_CONTROL_7:
- case WM2200_FLL_EFS_1:
- case WM2200_FLL_EFS_2:
- case WM2200_MIC_CHARGE_PUMP_1:
- case WM2200_MIC_CHARGE_PUMP_2:
- case WM2200_DM_CHARGE_PUMP_1:
- case WM2200_MIC_BIAS_CTRL_1:
- case WM2200_MIC_BIAS_CTRL_2:
- case WM2200_EAR_PIECE_CTRL_1:
- case WM2200_EAR_PIECE_CTRL_2:
- case WM2200_INPUT_ENABLES:
- case WM2200_IN1L_CONTROL:
- case WM2200_IN1R_CONTROL:
- case WM2200_IN2L_CONTROL:
- case WM2200_IN2R_CONTROL:
- case WM2200_IN3L_CONTROL:
- case WM2200_IN3R_CONTROL:
- case WM2200_RXANC_SRC:
- case WM2200_INPUT_VOLUME_RAMP:
- case WM2200_ADC_DIGITAL_VOLUME_1L:
- case WM2200_ADC_DIGITAL_VOLUME_1R:
- case WM2200_ADC_DIGITAL_VOLUME_2L:
- case WM2200_ADC_DIGITAL_VOLUME_2R:
- case WM2200_ADC_DIGITAL_VOLUME_3L:
- case WM2200_ADC_DIGITAL_VOLUME_3R:
- case WM2200_OUTPUT_ENABLES:
- case WM2200_DAC_VOLUME_LIMIT_1L:
- case WM2200_DAC_VOLUME_LIMIT_1R:
- case WM2200_DAC_VOLUME_LIMIT_2L:
- case WM2200_DAC_VOLUME_LIMIT_2R:
- case WM2200_DAC_AEC_CONTROL_1:
- case WM2200_OUTPUT_VOLUME_RAMP:
- case WM2200_DAC_DIGITAL_VOLUME_1L:
- case WM2200_DAC_DIGITAL_VOLUME_1R:
- case WM2200_DAC_DIGITAL_VOLUME_2L:
- case WM2200_DAC_DIGITAL_VOLUME_2R:
- case WM2200_PDM_1:
- case WM2200_PDM_2:
- case WM2200_AUDIO_IF_1_1:
- case WM2200_AUDIO_IF_1_2:
- case WM2200_AUDIO_IF_1_3:
- case WM2200_AUDIO_IF_1_4:
- case WM2200_AUDIO_IF_1_5:
- case WM2200_AUDIO_IF_1_6:
- case WM2200_AUDIO_IF_1_7:
- case WM2200_AUDIO_IF_1_8:
- case WM2200_AUDIO_IF_1_9:
- case WM2200_AUDIO_IF_1_10:
- case WM2200_AUDIO_IF_1_11:
- case WM2200_AUDIO_IF_1_12:
- case WM2200_AUDIO_IF_1_13:
- case WM2200_AUDIO_IF_1_14:
- case WM2200_AUDIO_IF_1_15:
- case WM2200_AUDIO_IF_1_16:
- case WM2200_AUDIO_IF_1_17:
- case WM2200_AUDIO_IF_1_18:
- case WM2200_AUDIO_IF_1_19:
- case WM2200_AUDIO_IF_1_20:
- case WM2200_AUDIO_IF_1_21:
- case WM2200_AUDIO_IF_1_22:
- case WM2200_OUT1LMIX_INPUT_1_SOURCE:
- case WM2200_OUT1LMIX_INPUT_1_VOLUME:
- case WM2200_OUT1LMIX_INPUT_2_SOURCE:
- case WM2200_OUT1LMIX_INPUT_2_VOLUME:
- case WM2200_OUT1LMIX_INPUT_3_SOURCE:
- case WM2200_OUT1LMIX_INPUT_3_VOLUME:
- case WM2200_OUT1LMIX_INPUT_4_SOURCE:
- case WM2200_OUT1LMIX_INPUT_4_VOLUME:
- case WM2200_OUT1RMIX_INPUT_1_SOURCE:
- case WM2200_OUT1RMIX_INPUT_1_VOLUME:
- case WM2200_OUT1RMIX_INPUT_2_SOURCE:
- case WM2200_OUT1RMIX_INPUT_2_VOLUME:
- case WM2200_OUT1RMIX_INPUT_3_SOURCE:
- case WM2200_OUT1RMIX_INPUT_3_VOLUME:
- case WM2200_OUT1RMIX_INPUT_4_SOURCE:
- case WM2200_OUT1RMIX_INPUT_4_VOLUME:
- case WM2200_OUT2LMIX_INPUT_1_SOURCE:
- case WM2200_OUT2LMIX_INPUT_1_VOLUME:
- case WM2200_OUT2LMIX_INPUT_2_SOURCE:
- case WM2200_OUT2LMIX_INPUT_2_VOLUME:
- case WM2200_OUT2LMIX_INPUT_3_SOURCE:
- case WM2200_OUT2LMIX_INPUT_3_VOLUME:
- case WM2200_OUT2LMIX_INPUT_4_SOURCE:
- case WM2200_OUT2LMIX_INPUT_4_VOLUME:
- case WM2200_OUT2RMIX_INPUT_1_SOURCE:
- case WM2200_OUT2RMIX_INPUT_1_VOLUME:
- case WM2200_OUT2RMIX_INPUT_2_SOURCE:
- case WM2200_OUT2RMIX_INPUT_2_VOLUME:
- case WM2200_OUT2RMIX_INPUT_3_SOURCE:
- case WM2200_OUT2RMIX_INPUT_3_VOLUME:
- case WM2200_OUT2RMIX_INPUT_4_SOURCE:
- case WM2200_OUT2RMIX_INPUT_4_VOLUME:
- case WM2200_AIF1TX1MIX_INPUT_1_SOURCE:
- case WM2200_AIF1TX1MIX_INPUT_1_VOLUME:
- case WM2200_AIF1TX1MIX_INPUT_2_SOURCE:
- case WM2200_AIF1TX1MIX_INPUT_2_VOLUME:
- case WM2200_AIF1TX1MIX_INPUT_3_SOURCE:
- case WM2200_AIF1TX1MIX_INPUT_3_VOLUME:
- case WM2200_AIF1TX1MIX_INPUT_4_SOURCE:
- case WM2200_AIF1TX1MIX_INPUT_4_VOLUME:
- case WM2200_AIF1TX2MIX_INPUT_1_SOURCE:
- case WM2200_AIF1TX2MIX_INPUT_1_VOLUME:
- case WM2200_AIF1TX2MIX_INPUT_2_SOURCE:
- case WM2200_AIF1TX2MIX_INPUT_2_VOLUME:
- case WM2200_AIF1TX2MIX_INPUT_3_SOURCE:
- case WM2200_AIF1TX2MIX_INPUT_3_VOLUME:
- case WM2200_AIF1TX2MIX_INPUT_4_SOURCE:
- case WM2200_AIF1TX2MIX_INPUT_4_VOLUME:
- case WM2200_AIF1TX3MIX_INPUT_1_SOURCE:
- case WM2200_AIF1TX3MIX_INPUT_1_VOLUME:
- case WM2200_AIF1TX3MIX_INPUT_2_SOURCE:
- case WM2200_AIF1TX3MIX_INPUT_2_VOLUME:
- case WM2200_AIF1TX3MIX_INPUT_3_SOURCE:
- case WM2200_AIF1TX3MIX_INPUT_3_VOLUME:
- case WM2200_AIF1TX3MIX_INPUT_4_SOURCE:
- case WM2200_AIF1TX3MIX_INPUT_4_VOLUME:
- case WM2200_AIF1TX4MIX_INPUT_1_SOURCE:
- case WM2200_AIF1TX4MIX_INPUT_1_VOLUME:
- case WM2200_AIF1TX4MIX_INPUT_2_SOURCE:
- case WM2200_AIF1TX4MIX_INPUT_2_VOLUME:
- case WM2200_AIF1TX4MIX_INPUT_3_SOURCE:
- case WM2200_AIF1TX4MIX_INPUT_3_VOLUME:
- case WM2200_AIF1TX4MIX_INPUT_4_SOURCE:
- case WM2200_AIF1TX4MIX_INPUT_4_VOLUME:
- case WM2200_AIF1TX5MIX_INPUT_1_SOURCE:
- case WM2200_AIF1TX5MIX_INPUT_1_VOLUME:
- case WM2200_AIF1TX5MIX_INPUT_2_SOURCE:
- case WM2200_AIF1TX5MIX_INPUT_2_VOLUME:
- case WM2200_AIF1TX5MIX_INPUT_3_SOURCE:
- case WM2200_AIF1TX5MIX_INPUT_3_VOLUME:
- case WM2200_AIF1TX5MIX_INPUT_4_SOURCE:
- case WM2200_AIF1TX5MIX_INPUT_4_VOLUME:
- case WM2200_AIF1TX6MIX_INPUT_1_SOURCE:
- case WM2200_AIF1TX6MIX_INPUT_1_VOLUME:
- case WM2200_AIF1TX6MIX_INPUT_2_SOURCE:
- case WM2200_AIF1TX6MIX_INPUT_2_VOLUME:
- case WM2200_AIF1TX6MIX_INPUT_3_SOURCE:
- case WM2200_AIF1TX6MIX_INPUT_3_VOLUME:
- case WM2200_AIF1TX6MIX_INPUT_4_SOURCE:
- case WM2200_AIF1TX6MIX_INPUT_4_VOLUME:
- case WM2200_EQLMIX_INPUT_1_SOURCE:
- case WM2200_EQLMIX_INPUT_1_VOLUME:
- case WM2200_EQLMIX_INPUT_2_SOURCE:
- case WM2200_EQLMIX_INPUT_2_VOLUME:
- case WM2200_EQLMIX_INPUT_3_SOURCE:
- case WM2200_EQLMIX_INPUT_3_VOLUME:
- case WM2200_EQLMIX_INPUT_4_SOURCE:
- case WM2200_EQLMIX_INPUT_4_VOLUME:
- case WM2200_EQRMIX_INPUT_1_SOURCE:
- case WM2200_EQRMIX_INPUT_1_VOLUME:
- case WM2200_EQRMIX_INPUT_2_SOURCE:
- case WM2200_EQRMIX_INPUT_2_VOLUME:
- case WM2200_EQRMIX_INPUT_3_SOURCE:
- case WM2200_EQRMIX_INPUT_3_VOLUME:
- case WM2200_EQRMIX_INPUT_4_SOURCE:
- case WM2200_EQRMIX_INPUT_4_VOLUME:
- case WM2200_LHPF1MIX_INPUT_1_SOURCE:
- case WM2200_LHPF1MIX_INPUT_1_VOLUME:
- case WM2200_LHPF1MIX_INPUT_2_SOURCE:
- case WM2200_LHPF1MIX_INPUT_2_VOLUME:
- case WM2200_LHPF1MIX_INPUT_3_SOURCE:
- case WM2200_LHPF1MIX_INPUT_3_VOLUME:
- case WM2200_LHPF1MIX_INPUT_4_SOURCE:
- case WM2200_LHPF1MIX_INPUT_4_VOLUME:
- case WM2200_LHPF2MIX_INPUT_1_SOURCE:
- case WM2200_LHPF2MIX_INPUT_1_VOLUME:
- case WM2200_LHPF2MIX_INPUT_2_SOURCE:
- case WM2200_LHPF2MIX_INPUT_2_VOLUME:
- case WM2200_LHPF2MIX_INPUT_3_SOURCE:
- case WM2200_LHPF2MIX_INPUT_3_VOLUME:
- case WM2200_LHPF2MIX_INPUT_4_SOURCE:
- case WM2200_LHPF2MIX_INPUT_4_VOLUME:
- case WM2200_DSP1LMIX_INPUT_1_SOURCE:
- case WM2200_DSP1LMIX_INPUT_1_VOLUME:
- case WM2200_DSP1LMIX_INPUT_2_SOURCE:
- case WM2200_DSP1LMIX_INPUT_2_VOLUME:
- case WM2200_DSP1LMIX_INPUT_3_SOURCE:
- case WM2200_DSP1LMIX_INPUT_3_VOLUME:
- case WM2200_DSP1LMIX_INPUT_4_SOURCE:
- case WM2200_DSP1LMIX_INPUT_4_VOLUME:
- case WM2200_DSP1RMIX_INPUT_1_SOURCE:
- case WM2200_DSP1RMIX_INPUT_1_VOLUME:
- case WM2200_DSP1RMIX_INPUT_2_SOURCE:
- case WM2200_DSP1RMIX_INPUT_2_VOLUME:
- case WM2200_DSP1RMIX_INPUT_3_SOURCE:
- case WM2200_DSP1RMIX_INPUT_3_VOLUME:
- case WM2200_DSP1RMIX_INPUT_4_SOURCE:
- case WM2200_DSP1RMIX_INPUT_4_VOLUME:
- case WM2200_DSP1AUX1MIX_INPUT_1_SOURCE:
- case WM2200_DSP1AUX2MIX_INPUT_1_SOURCE:
- case WM2200_DSP1AUX3MIX_INPUT_1_SOURCE:
- case WM2200_DSP1AUX4MIX_INPUT_1_SOURCE:
- case WM2200_DSP1AUX5MIX_INPUT_1_SOURCE:
- case WM2200_DSP1AUX6MIX_INPUT_1_SOURCE:
- case WM2200_DSP2LMIX_INPUT_1_SOURCE:
- case WM2200_DSP2LMIX_INPUT_1_VOLUME:
- case WM2200_DSP2LMIX_INPUT_2_SOURCE:
- case WM2200_DSP2LMIX_INPUT_2_VOLUME:
- case WM2200_DSP2LMIX_INPUT_3_SOURCE:
- case WM2200_DSP2LMIX_INPUT_3_VOLUME:
- case WM2200_DSP2LMIX_INPUT_4_SOURCE:
- case WM2200_DSP2LMIX_INPUT_4_VOLUME:
- case WM2200_DSP2RMIX_INPUT_1_SOURCE:
- case WM2200_DSP2RMIX_INPUT_1_VOLUME:
- case WM2200_DSP2RMIX_INPUT_2_SOURCE:
- case WM2200_DSP2RMIX_INPUT_2_VOLUME:
- case WM2200_DSP2RMIX_INPUT_3_SOURCE:
- case WM2200_DSP2RMIX_INPUT_3_VOLUME:
- case WM2200_DSP2RMIX_INPUT_4_SOURCE:
- case WM2200_DSP2RMIX_INPUT_4_VOLUME:
- case WM2200_DSP2AUX1MIX_INPUT_1_SOURCE:
- case WM2200_DSP2AUX2MIX_INPUT_1_SOURCE:
- case WM2200_DSP2AUX3MIX_INPUT_1_SOURCE:
- case WM2200_DSP2AUX4MIX_INPUT_1_SOURCE:
- case WM2200_DSP2AUX5MIX_INPUT_1_SOURCE:
- case WM2200_DSP2AUX6MIX_INPUT_1_SOURCE:
- case WM2200_GPIO_CTRL_1:
- case WM2200_GPIO_CTRL_2:
- case WM2200_GPIO_CTRL_3:
- case WM2200_GPIO_CTRL_4:
- case WM2200_ADPS1_IRQ0:
- case WM2200_ADPS1_IRQ1:
- case WM2200_MISC_PAD_CTRL_1:
- case WM2200_INTERRUPT_STATUS_1:
- case WM2200_INTERRUPT_STATUS_1_MASK:
- case WM2200_INTERRUPT_STATUS_2:
- case WM2200_INTERRUPT_RAW_STATUS_2:
- case WM2200_INTERRUPT_STATUS_2_MASK:
- case WM2200_INTERRUPT_CONTROL:
- case WM2200_EQL_1:
- case WM2200_EQL_2:
- case WM2200_EQL_3:
- case WM2200_EQL_4:
- case WM2200_EQL_5:
- case WM2200_EQL_6:
- case WM2200_EQL_7:
- case WM2200_EQL_8:
- case WM2200_EQL_9:
- case WM2200_EQL_10:
- case WM2200_EQL_11:
- case WM2200_EQL_12:
- case WM2200_EQL_13:
- case WM2200_EQL_14:
- case WM2200_EQL_15:
- case WM2200_EQL_16:
- case WM2200_EQL_17:
- case WM2200_EQL_18:
- case WM2200_EQL_19:
- case WM2200_EQL_20:
- case WM2200_EQR_1:
- case WM2200_EQR_2:
- case WM2200_EQR_3:
- case WM2200_EQR_4:
- case WM2200_EQR_5:
- case WM2200_EQR_6:
- case WM2200_EQR_7:
- case WM2200_EQR_8:
- case WM2200_EQR_9:
- case WM2200_EQR_10:
- case WM2200_EQR_11:
- case WM2200_EQR_12:
- case WM2200_EQR_13:
- case WM2200_EQR_14:
- case WM2200_EQR_15:
- case WM2200_EQR_16:
- case WM2200_EQR_17:
- case WM2200_EQR_18:
- case WM2200_EQR_19:
- case WM2200_EQR_20:
- case WM2200_HPLPF1_1:
- case WM2200_HPLPF1_2:
- case WM2200_HPLPF2_1:
- case WM2200_HPLPF2_2:
- case WM2200_DSP1_CONTROL_1:
- case WM2200_DSP1_CONTROL_2:
- case WM2200_DSP1_CONTROL_3:
- case WM2200_DSP1_CONTROL_4:
- case WM2200_DSP1_CONTROL_5:
- case WM2200_DSP1_CONTROL_6:
- case WM2200_DSP1_CONTROL_7:
- case WM2200_DSP1_CONTROL_8:
- case WM2200_DSP1_CONTROL_9:
- case WM2200_DSP1_CONTROL_10:
- case WM2200_DSP1_CONTROL_11:
- case WM2200_DSP1_CONTROL_12:
- case WM2200_DSP1_CONTROL_13:
- case WM2200_DSP1_CONTROL_14:
- case WM2200_DSP1_CONTROL_15:
- case WM2200_DSP1_CONTROL_16:
- case WM2200_DSP1_CONTROL_17:
- case WM2200_DSP1_CONTROL_18:
- case WM2200_DSP1_CONTROL_19:
- case WM2200_DSP1_CONTROL_20:
- case WM2200_DSP1_CONTROL_21:
- case WM2200_DSP1_CONTROL_22:
- case WM2200_DSP1_CONTROL_23:
- case WM2200_DSP1_CONTROL_24:
- case WM2200_DSP1_CONTROL_25:
- case WM2200_DSP1_CONTROL_26:
- case WM2200_DSP1_CONTROL_27:
- case WM2200_DSP1_CONTROL_28:
- case WM2200_DSP1_CONTROL_29:
- case WM2200_DSP1_CONTROL_30:
- case WM2200_DSP1_CONTROL_31:
- case WM2200_DSP2_CONTROL_1:
- case WM2200_DSP2_CONTROL_2:
- case WM2200_DSP2_CONTROL_3:
- case WM2200_DSP2_CONTROL_4:
- case WM2200_DSP2_CONTROL_5:
- case WM2200_DSP2_CONTROL_6:
- case WM2200_DSP2_CONTROL_7:
- case WM2200_DSP2_CONTROL_8:
- case WM2200_DSP2_CONTROL_9:
- case WM2200_DSP2_CONTROL_10:
- case WM2200_DSP2_CONTROL_11:
- case WM2200_DSP2_CONTROL_12:
- case WM2200_DSP2_CONTROL_13:
- case WM2200_DSP2_CONTROL_14:
- case WM2200_DSP2_CONTROL_15:
- case WM2200_DSP2_CONTROL_16:
- case WM2200_DSP2_CONTROL_17:
- case WM2200_DSP2_CONTROL_18:
- case WM2200_DSP2_CONTROL_19:
- case WM2200_DSP2_CONTROL_20:
- case WM2200_DSP2_CONTROL_21:
- case WM2200_DSP2_CONTROL_22:
- case WM2200_DSP2_CONTROL_23:
- case WM2200_DSP2_CONTROL_24:
- case WM2200_DSP2_CONTROL_25:
- case WM2200_DSP2_CONTROL_26:
- case WM2200_DSP2_CONTROL_27:
- case WM2200_DSP2_CONTROL_28:
- case WM2200_DSP2_CONTROL_29:
- case WM2200_DSP2_CONTROL_30:
- case WM2200_DSP2_CONTROL_31:
- return true;
- default:
- return false;
- }
-}
-
-static const struct reg_default wm2200_reva_patch[] = {
- { 0x07, 0x0003 },
- { 0x102, 0x0200 },
- { 0x203, 0x0084 },
- { 0x201, 0x83FF },
- { 0x20C, 0x0062 },
- { 0x20D, 0x0062 },
- { 0x207, 0x2002 },
- { 0x208, 0x20C0 },
- { 0x21D, 0x01C0 },
- { 0x50A, 0x0001 },
- { 0x50B, 0x0002 },
- { 0x50C, 0x0003 },
- { 0x50D, 0x0004 },
- { 0x50E, 0x0005 },
- { 0x510, 0x0001 },
- { 0x511, 0x0002 },
- { 0x512, 0x0003 },
- { 0x513, 0x0004 },
- { 0x514, 0x0005 },
- { 0x515, 0x0000 },
- { 0x201, 0x8084 },
- { 0x202, 0xBBDE },
- { 0x203, 0x00EC },
- { 0x500, 0x8000 },
- { 0x507, 0x1820 },
- { 0x508, 0x1820 },
- { 0x505, 0x0300 },
- { 0x506, 0x0300 },
- { 0x302, 0x2280 },
- { 0x303, 0x0080 },
- { 0x304, 0x2280 },
- { 0x305, 0x0080 },
- { 0x306, 0x2280 },
- { 0x307, 0x0080 },
- { 0x401, 0x0080 },
- { 0x402, 0x0080 },
- { 0x417, 0x3069 },
- { 0x900, 0x6318 },
- { 0x901, 0x6300 },
- { 0x902, 0x0FC8 },
- { 0x903, 0x03FE },
- { 0x904, 0x00E0 },
- { 0x905, 0x1EC4 },
- { 0x906, 0xF136 },
- { 0x907, 0x0409 },
- { 0x908, 0x04CC },
- { 0x909, 0x1C9B },
- { 0x90A, 0xF337 },
- { 0x90B, 0x040B },
- { 0x90C, 0x0CBB },
- { 0x90D, 0x16F8 },
- { 0x90E, 0xF7D9 },
- { 0x90F, 0x040A },
- { 0x910, 0x1F14 },
- { 0x911, 0x058C },
- { 0x912, 0x0563 },
- { 0x913, 0x4000 },
- { 0x916, 0x6318 },
- { 0x917, 0x6300 },
- { 0x918, 0x0FC8 },
- { 0x919, 0x03FE },
- { 0x91A, 0x00E0 },
- { 0x91B, 0x1EC4 },
- { 0x91C, 0xF136 },
- { 0x91D, 0x0409 },
- { 0x91E, 0x04CC },
- { 0x91F, 0x1C9B },
- { 0x920, 0xF337 },
- { 0x921, 0x040B },
- { 0x922, 0x0CBB },
- { 0x923, 0x16F8 },
- { 0x924, 0xF7D9 },
- { 0x925, 0x040A },
- { 0x926, 0x1F14 },
- { 0x927, 0x058C },
- { 0x928, 0x0563 },
- { 0x929, 0x4000 },
- { 0x709, 0x2000 },
- { 0x207, 0x200E },
- { 0x208, 0x20D4 },
- { 0x20A, 0x0080 },
- { 0x07, 0x0000 },
-};
-
-static int wm2200_reset(struct wm2200_priv *wm2200)
-{
- if (wm2200->pdata.reset) {
- gpio_set_value_cansleep(wm2200->pdata.reset, 0);
- gpio_set_value_cansleep(wm2200->pdata.reset, 1);
-
- return 0;
- } else {
- return regmap_write(wm2200->regmap, WM2200_SOFTWARE_RESET,
- 0x2200);
- }
-}
-
-static DECLARE_TLV_DB_SCALE(in_tlv, -6300, 100, 0);
-static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
-static DECLARE_TLV_DB_SCALE(out_tlv, -6400, 100, 0);
-
-static const char *wm2200_mixer_texts[] = {
- "None",
- "Tone Generator",
- "AEC loopback",
- "IN1L",
- "IN1R",
- "IN2L",
- "IN2R",
- "IN3L",
- "IN3R",
- "AIF1RX1",
- "AIF1RX2",
- "AIF1RX3",
- "AIF1RX4",
- "AIF1RX5",
- "AIF1RX6",
- "EQL",
- "EQR",
- "LHPF1",
- "LHPF2",
- "LHPF3",
- "LHPF4",
- "DSP1.1",
- "DSP1.2",
- "DSP1.3",
- "DSP1.4",
- "DSP1.5",
- "DSP1.6",
- "DSP2.1",
- "DSP2.2",
- "DSP2.3",
- "DSP2.4",
- "DSP2.5",
- "DSP2.6",
-};
-
-static int wm2200_mixer_values[] = {
- 0x00,
- 0x04, /* Tone */
- 0x08, /* AEC */
- 0x10, /* Input */
- 0x11,
- 0x12,
- 0x13,
- 0x14,
- 0x15,
- 0x20, /* AIF */
- 0x21,
- 0x22,
- 0x23,
- 0x24,
- 0x25,
- 0x50, /* EQ */
- 0x51,
- 0x52,
- 0x60, /* LHPF1 */
- 0x61, /* LHPF2 */
- 0x68, /* DSP1 */
- 0x69,
- 0x6a,
- 0x6b,
- 0x6c,
- 0x6d,
- 0x70, /* DSP2 */
- 0x71,
- 0x72,
- 0x73,
- 0x74,
- 0x75,
-};
-
-#define WM2200_MIXER_CONTROLS(name, base) \
- SOC_SINGLE_TLV(name " Input 1 Volume", base + 1 , \
- WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
- SOC_SINGLE_TLV(name " Input 2 Volume", base + 3 , \
- WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
- SOC_SINGLE_TLV(name " Input 3 Volume", base + 5 , \
- WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
- SOC_SINGLE_TLV(name " Input 4 Volume", base + 7 , \
- WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv)
-
-#define WM2200_MUX_ENUM_DECL(name, reg) \
- SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, \
- wm2200_mixer_texts, wm2200_mixer_values)
-
-#define WM2200_MUX_CTL_DECL(name) \
- const struct snd_kcontrol_new name##_mux = \
- SOC_DAPM_VALUE_ENUM("Route", name##_enum)
-
-#define WM2200_MIXER_ENUMS(name, base_reg) \
- static WM2200_MUX_ENUM_DECL(name##_in1_enum, base_reg); \
- static WM2200_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \
- static WM2200_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \
- static WM2200_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \
- static WM2200_MUX_CTL_DECL(name##_in1); \
- static WM2200_MUX_CTL_DECL(name##_in2); \
- static WM2200_MUX_CTL_DECL(name##_in3); \
- static WM2200_MUX_CTL_DECL(name##_in4)
-
-static const struct snd_kcontrol_new wm2200_snd_controls[] = {
-SOC_SINGLE("IN1 High Performance Switch", WM2200_IN1L_CONTROL,
- WM2200_IN1_OSR_SHIFT, 1, 0),
-SOC_SINGLE("IN2 High Performance Switch", WM2200_IN2L_CONTROL,
- WM2200_IN2_OSR_SHIFT, 1, 0),
-SOC_SINGLE("IN3 High Performance Switch", WM2200_IN3L_CONTROL,
- WM2200_IN3_OSR_SHIFT, 1, 0),
-
-SOC_DOUBLE_R_TLV("IN1 Volume", WM2200_IN1L_CONTROL, WM2200_IN1R_CONTROL,
- WM2200_IN1L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
-SOC_DOUBLE_R_TLV("IN2 Volume", WM2200_IN2L_CONTROL, WM2200_IN2R_CONTROL,
- WM2200_IN2L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
-SOC_DOUBLE_R_TLV("IN3 Volume", WM2200_IN3L_CONTROL, WM2200_IN3R_CONTROL,
- WM2200_IN3L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
-
-SOC_DOUBLE_R("IN1 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L,
- WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_MUTE_SHIFT, 1, 1),
-SOC_DOUBLE_R("IN2 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L,
- WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_MUTE_SHIFT, 1, 1),
-SOC_DOUBLE_R("IN3 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L,
- WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_MUTE_SHIFT, 1, 1),
-
-SOC_DOUBLE_R_TLV("IN1 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_1L,
- WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_DIG_VOL_SHIFT,
- 0xbf, 0, digital_tlv),
-SOC_DOUBLE_R_TLV("IN2 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_2L,
- WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_DIG_VOL_SHIFT,
- 0xbf, 0, digital_tlv),
-SOC_DOUBLE_R_TLV("IN3 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_3L,
- WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_DIG_VOL_SHIFT,
- 0xbf, 0, digital_tlv),
-
-SOC_SINGLE("OUT1 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_1L,
- WM2200_OUT1_OSR_SHIFT, 1, 0),
-SOC_SINGLE("OUT2 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_2L,
- WM2200_OUT2_OSR_SHIFT, 1, 0),
-
-SOC_DOUBLE_R("OUT1 Digital Switch", WM2200_DAC_DIGITAL_VOLUME_1L,
- WM2200_DAC_DIGITAL_VOLUME_1R, WM2200_OUT1L_MUTE_SHIFT, 1, 1),
-SOC_DOUBLE_R_TLV("OUT1 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_1L,
- WM2200_DAC_DIGITAL_VOLUME_1R, WM2200_OUT1L_VOL_SHIFT, 0x9f, 0,
- digital_tlv),
-SOC_DOUBLE_R_TLV("OUT1 Volume", WM2200_DAC_VOLUME_LIMIT_1L,
- WM2200_DAC_VOLUME_LIMIT_1R, WM2200_OUT1L_PGA_VOL_SHIFT,
- 0x46, 0, out_tlv),
-
-SOC_DOUBLE_R("OUT2 Digital Switch", WM2200_DAC_DIGITAL_VOLUME_2L,
- WM2200_DAC_DIGITAL_VOLUME_2R, WM2200_OUT2L_MUTE_SHIFT, 1, 1),
-SOC_DOUBLE_R_TLV("OUT2 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_2L,
- WM2200_DAC_DIGITAL_VOLUME_2R, WM2200_OUT2L_VOL_SHIFT, 0x9f, 0,
- digital_tlv),
-SOC_DOUBLE("OUT2 Switch", WM2200_PDM_1, WM2200_SPK1L_MUTE_SHIFT,
- WM2200_SPK1R_MUTE_SHIFT, 1, 0),
-};
-
-WM2200_MIXER_ENUMS(OUT1L, WM2200_OUT1LMIX_INPUT_1_SOURCE);
-WM2200_MIXER_ENUMS(OUT1R, WM2200_OUT1RMIX_INPUT_1_SOURCE);
-WM2200_MIXER_ENUMS(OUT2L, WM2200_OUT2LMIX_INPUT_1_SOURCE);
-WM2200_MIXER_ENUMS(OUT2R, WM2200_OUT2RMIX_INPUT_1_SOURCE);
-
-WM2200_MIXER_ENUMS(AIF1TX1, WM2200_AIF1TX1MIX_INPUT_1_SOURCE);
-WM2200_MIXER_ENUMS(AIF1TX2, WM2200_AIF1TX2MIX_INPUT_1_SOURCE);
-WM2200_MIXER_ENUMS(AIF1TX3, WM2200_AIF1TX3MIX_INPUT_1_SOURCE);
-WM2200_MIXER_ENUMS(AIF1TX4, WM2200_AIF1TX4MIX_INPUT_1_SOURCE);
-WM2200_MIXER_ENUMS(AIF1TX5, WM2200_AIF1TX5MIX_INPUT_1_SOURCE);
-WM2200_MIXER_ENUMS(AIF1TX6, WM2200_AIF1TX6MIX_INPUT_1_SOURCE);
-
-WM2200_MIXER_ENUMS(EQL, WM2200_EQLMIX_INPUT_1_SOURCE);
-WM2200_MIXER_ENUMS(EQR, WM2200_EQRMIX_INPUT_1_SOURCE);
-
-WM2200_MIXER_ENUMS(DSP1L, WM2200_DSP1LMIX_INPUT_1_SOURCE);
-WM2200_MIXER_ENUMS(DSP1R, WM2200_DSP1RMIX_INPUT_1_SOURCE);
-WM2200_MIXER_ENUMS(DSP2L, WM2200_DSP2LMIX_INPUT_1_SOURCE);
-WM2200_MIXER_ENUMS(DSP2R, WM2200_DSP2RMIX_INPUT_1_SOURCE);
-
-WM2200_MIXER_ENUMS(LHPF1, WM2200_LHPF1MIX_INPUT_1_SOURCE);
-WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE);
-
-#define WM2200_MUX(name, ctrl) \
- SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
-
-#define WM2200_MIXER_WIDGETS(name, name_str) \
- WM2200_MUX(name_str " Input 1", &name##_in1_mux), \
- WM2200_MUX(name_str " Input 2", &name##_in2_mux), \
- WM2200_MUX(name_str " Input 3", &name##_in3_mux), \
- WM2200_MUX(name_str " Input 4", &name##_in4_mux), \
- SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
-
-#define WM2200_MIXER_INPUT_ROUTES(name) \
- { name, "Tone Generator", "Tone Generator" }, \
- { name, "IN1L", "IN1L PGA" }, \
- { name, "IN1R", "IN1R PGA" }, \
- { name, "IN2L", "IN2L PGA" }, \
- { name, "IN2R", "IN2R PGA" }, \
- { name, "IN3L", "IN3L PGA" }, \
- { name, "IN3R", "IN3R PGA" }, \
- { name, "DSP1.1", "DSP1" }, \
- { name, "DSP1.2", "DSP1" }, \
- { name, "DSP1.3", "DSP1" }, \
- { name, "DSP1.4", "DSP1" }, \
- { name, "DSP1.5", "DSP1" }, \
- { name, "DSP1.6", "DSP1" }, \
- { name, "DSP2.1", "DSP2" }, \
- { name, "DSP2.2", "DSP2" }, \
- { name, "DSP2.3", "DSP2" }, \
- { name, "DSP2.4", "DSP2" }, \
- { name, "DSP2.5", "DSP2" }, \
- { name, "DSP2.6", "DSP2" }, \
- { name, "AIF1RX1", "AIF1RX1" }, \
- { name, "AIF1RX2", "AIF1RX2" }, \
- { name, "AIF1RX3", "AIF1RX3" }, \
- { name, "AIF1RX4", "AIF1RX4" }, \
- { name, "AIF1RX5", "AIF1RX5" }, \
- { name, "AIF1RX6", "AIF1RX6" }, \
- { name, "EQL", "EQL" }, \
- { name, "EQR", "EQR" }, \
- { name, "LHPF1", "LHPF1" }, \
- { name, "LHPF2", "LHPF2" }
-
-#define WM2200_MIXER_ROUTES(widget, name) \
- { widget, NULL, name " Mixer" }, \
- { name " Mixer", NULL, name " Input 1" }, \
- { name " Mixer", NULL, name " Input 2" }, \
- { name " Mixer", NULL, name " Input 3" }, \
- { name " Mixer", NULL, name " Input 4" }, \
- WM2200_MIXER_INPUT_ROUTES(name " Input 1"), \
- WM2200_MIXER_INPUT_ROUTES(name " Input 2"), \
- WM2200_MIXER_INPUT_ROUTES(name " Input 3"), \
- WM2200_MIXER_INPUT_ROUTES(name " Input 4")
-
-static const struct snd_soc_dapm_widget wm2200_dapm_widgets[] = {
-SND_SOC_DAPM_SUPPLY("SYSCLK", WM2200_CLOCKING_3, WM2200_SYSCLK_ENA_SHIFT, 0,
- NULL, 0),
-SND_SOC_DAPM_SUPPLY("CP1", WM2200_DM_CHARGE_PUMP_1, WM2200_CPDM_ENA_SHIFT, 0,
- NULL, 0),
-SND_SOC_DAPM_SUPPLY("CP2", WM2200_MIC_CHARGE_PUMP_1, WM2200_CPMIC_ENA_SHIFT, 0,
- NULL, 0),
-SND_SOC_DAPM_SUPPLY("MICBIAS1", WM2200_MIC_BIAS_CTRL_1, WM2200_MICB1_ENA_SHIFT,
- 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("MICBIAS2", WM2200_MIC_BIAS_CTRL_2, WM2200_MICB2_ENA_SHIFT,
- 0, NULL, 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
-SND_SOC_DAPM_REGULATOR_SUPPLY("AVDD", 20),
-
-SND_SOC_DAPM_INPUT("IN1L"),
-SND_SOC_DAPM_INPUT("IN1R"),
-SND_SOC_DAPM_INPUT("IN2L"),
-SND_SOC_DAPM_INPUT("IN2R"),
-SND_SOC_DAPM_INPUT("IN3L"),
-SND_SOC_DAPM_INPUT("IN3R"),
-
-SND_SOC_DAPM_SIGGEN("TONE"),
-SND_SOC_DAPM_PGA("Tone Generator", WM2200_TONE_GENERATOR_1,
- WM2200_TONE_ENA_SHIFT, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA("IN1L PGA", WM2200_INPUT_ENABLES, WM2200_IN1L_ENA_SHIFT, 0,
- NULL, 0),
-SND_SOC_DAPM_PGA("IN1R PGA", WM2200_INPUT_ENABLES, WM2200_IN1R_ENA_SHIFT, 0,
- NULL, 0),
-SND_SOC_DAPM_PGA("IN2L PGA", WM2200_INPUT_ENABLES, WM2200_IN2L_ENA_SHIFT, 0,
- NULL, 0),
-SND_SOC_DAPM_PGA("IN2R PGA", WM2200_INPUT_ENABLES, WM2200_IN2R_ENA_SHIFT, 0,
- NULL, 0),
-SND_SOC_DAPM_PGA("IN3L PGA", WM2200_INPUT_ENABLES, WM2200_IN3L_ENA_SHIFT, 0,
- NULL, 0),
-SND_SOC_DAPM_PGA("IN3R PGA", WM2200_INPUT_ENABLES, WM2200_IN3R_ENA_SHIFT, 0,
- NULL, 0),
-
-SND_SOC_DAPM_AIF_IN("AIF1RX1", "Playback", 0,
- WM2200_AUDIO_IF_1_22, WM2200_AIF1RX1_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX2", "Playback", 1,
- WM2200_AUDIO_IF_1_22, WM2200_AIF1RX2_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX3", "Playback", 2,
- WM2200_AUDIO_IF_1_22, WM2200_AIF1RX3_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX4", "Playback", 3,
- WM2200_AUDIO_IF_1_22, WM2200_AIF1RX4_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX5", "Playback", 4,
- WM2200_AUDIO_IF_1_22, WM2200_AIF1RX5_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX6", "Playback", 5,
- WM2200_AUDIO_IF_1_22, WM2200_AIF1RX6_ENA_SHIFT, 0),
-
-SND_SOC_DAPM_PGA("EQL", WM2200_EQL_1, WM2200_EQL_ENA_SHIFT, 0, NULL, 0),
-SND_SOC_DAPM_PGA("EQR", WM2200_EQR_1, WM2200_EQR_ENA_SHIFT, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA("LHPF1", WM2200_HPLPF1_1, WM2200_LHPF1_ENA_SHIFT, 0,
- NULL, 0),
-SND_SOC_DAPM_PGA("LHPF2", WM2200_HPLPF2_1, WM2200_LHPF2_ENA_SHIFT, 0,
- NULL, 0),
-
-SND_SOC_DAPM_PGA_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0),
-SND_SOC_DAPM_PGA_E("DSP2", SND_SOC_NOPM, 1, 0, NULL, 0, NULL, 0),
-
-SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0,
- WM2200_AUDIO_IF_1_22, WM2200_AIF1TX1_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX2", "Capture", 1,
- WM2200_AUDIO_IF_1_22, WM2200_AIF1TX2_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX3", "Capture", 2,
- WM2200_AUDIO_IF_1_22, WM2200_AIF1TX3_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX4", "Capture", 3,
- WM2200_AUDIO_IF_1_22, WM2200_AIF1TX4_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX5", "Capture", 4,
- WM2200_AUDIO_IF_1_22, WM2200_AIF1TX5_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 5,
- WM2200_AUDIO_IF_1_22, WM2200_AIF1TX6_ENA_SHIFT, 0),
-
-SND_SOC_DAPM_PGA_S("OUT1L", 0, WM2200_OUTPUT_ENABLES,
- WM2200_OUT1L_ENA_SHIFT, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("OUT1R", 0, WM2200_OUTPUT_ENABLES,
- WM2200_OUT1R_ENA_SHIFT, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA_S("EPD_LP", 1, WM2200_EAR_PIECE_CTRL_1,
- WM2200_EPD_LP_ENA_SHIFT, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("EPD_OUTP_LP", 1, WM2200_EAR_PIECE_CTRL_1,
- WM2200_EPD_OUTP_LP_ENA_SHIFT, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_LP", 1, WM2200_EAR_PIECE_CTRL_1,
- WM2200_EPD_RMV_SHRT_LP_SHIFT, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA_S("EPD_LN", 1, WM2200_EAR_PIECE_CTRL_1,
- WM2200_EPD_LN_ENA_SHIFT, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("EPD_OUTP_LN", 1, WM2200_EAR_PIECE_CTRL_1,
- WM2200_EPD_OUTP_LN_ENA_SHIFT, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_LN", 1, WM2200_EAR_PIECE_CTRL_1,
- WM2200_EPD_RMV_SHRT_LN_SHIFT, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA_S("EPD_RP", 1, WM2200_EAR_PIECE_CTRL_2,
- WM2200_EPD_RP_ENA_SHIFT, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("EPD_OUTP_RP", 1, WM2200_EAR_PIECE_CTRL_2,
- WM2200_EPD_OUTP_RP_ENA_SHIFT, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_RP", 1, WM2200_EAR_PIECE_CTRL_2,
- WM2200_EPD_RMV_SHRT_RP_SHIFT, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA_S("EPD_RN", 1, WM2200_EAR_PIECE_CTRL_2,
- WM2200_EPD_RN_ENA_SHIFT, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("EPD_OUTP_RN", 1, WM2200_EAR_PIECE_CTRL_2,
- WM2200_EPD_OUTP_RN_ENA_SHIFT, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_RN", 1, WM2200_EAR_PIECE_CTRL_2,
- WM2200_EPD_RMV_SHRT_RN_SHIFT, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA("OUT2L", WM2200_OUTPUT_ENABLES, WM2200_OUT2L_ENA_SHIFT,
- 0, NULL, 0),
-SND_SOC_DAPM_PGA("OUT2R", WM2200_OUTPUT_ENABLES, WM2200_OUT2R_ENA_SHIFT,
- 0, NULL, 0),
-
-SND_SOC_DAPM_OUTPUT("EPOUTLN"),
-SND_SOC_DAPM_OUTPUT("EPOUTLP"),
-SND_SOC_DAPM_OUTPUT("EPOUTRN"),
-SND_SOC_DAPM_OUTPUT("EPOUTRP"),
-SND_SOC_DAPM_OUTPUT("SPK"),
-
-WM2200_MIXER_WIDGETS(EQL, "EQL"),
-WM2200_MIXER_WIDGETS(EQR, "EQR"),
-
-WM2200_MIXER_WIDGETS(LHPF1, "LHPF1"),
-WM2200_MIXER_WIDGETS(LHPF2, "LHPF2"),
-
-WM2200_MIXER_WIDGETS(DSP1L, "DSP1L"),
-WM2200_MIXER_WIDGETS(DSP1R, "DSP1R"),
-WM2200_MIXER_WIDGETS(DSP2L, "DSP2L"),
-WM2200_MIXER_WIDGETS(DSP2R, "DSP2R"),
-
-WM2200_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
-WM2200_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
-WM2200_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
-WM2200_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
-WM2200_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
-WM2200_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
-
-WM2200_MIXER_WIDGETS(OUT1L, "OUT1L"),
-WM2200_MIXER_WIDGETS(OUT1R, "OUT1R"),
-WM2200_MIXER_WIDGETS(OUT2L, "OUT2L"),
-WM2200_MIXER_WIDGETS(OUT2R, "OUT2R"),
-};
-
-static const struct snd_soc_dapm_route wm2200_dapm_routes[] = {
- /* Everything needs SYSCLK but only hook up things on the edge
- * of the chip */
- { "IN1L", NULL, "SYSCLK" },
- { "IN1R", NULL, "SYSCLK" },
- { "IN2L", NULL, "SYSCLK" },
- { "IN2R", NULL, "SYSCLK" },
- { "IN3L", NULL, "SYSCLK" },
- { "IN3R", NULL, "SYSCLK" },
- { "OUT1L", NULL, "SYSCLK" },
- { "OUT1R", NULL, "SYSCLK" },
- { "OUT2L", NULL, "SYSCLK" },
- { "OUT2R", NULL, "SYSCLK" },
- { "AIF1RX1", NULL, "SYSCLK" },
- { "AIF1RX2", NULL, "SYSCLK" },
- { "AIF1RX3", NULL, "SYSCLK" },
- { "AIF1RX4", NULL, "SYSCLK" },
- { "AIF1RX5", NULL, "SYSCLK" },
- { "AIF1RX6", NULL, "SYSCLK" },
- { "AIF1TX1", NULL, "SYSCLK" },
- { "AIF1TX2", NULL, "SYSCLK" },
- { "AIF1TX3", NULL, "SYSCLK" },
- { "AIF1TX4", NULL, "SYSCLK" },
- { "AIF1TX5", NULL, "SYSCLK" },
- { "AIF1TX6", NULL, "SYSCLK" },
-
- { "IN1L", NULL, "AVDD" },
- { "IN1R", NULL, "AVDD" },
- { "IN2L", NULL, "AVDD" },
- { "IN2R", NULL, "AVDD" },
- { "IN3L", NULL, "AVDD" },
- { "IN3R", NULL, "AVDD" },
- { "OUT1L", NULL, "AVDD" },
- { "OUT1R", NULL, "AVDD" },
-
- { "IN1L PGA", NULL, "IN1L" },
- { "IN1R PGA", NULL, "IN1R" },
- { "IN2L PGA", NULL, "IN2L" },
- { "IN2R PGA", NULL, "IN2R" },
- { "IN3L PGA", NULL, "IN3L" },
- { "IN3R PGA", NULL, "IN3R" },
-
- { "Tone Generator", NULL, "TONE" },
-
- { "CP2", NULL, "CPVDD" },
- { "MICBIAS1", NULL, "CP2" },
- { "MICBIAS2", NULL, "CP2" },
-
- { "CP1", NULL, "CPVDD" },
- { "EPD_LN", NULL, "CP1" },
- { "EPD_LP", NULL, "CP1" },
- { "EPD_RN", NULL, "CP1" },
- { "EPD_RP", NULL, "CP1" },
-
- { "EPD_LP", NULL, "OUT1L" },
- { "EPD_OUTP_LP", NULL, "EPD_LP" },
- { "EPD_RMV_SHRT_LP", NULL, "EPD_OUTP_LP" },
- { "EPOUTLP", NULL, "EPD_RMV_SHRT_LP" },
-
- { "EPD_LN", NULL, "OUT1L" },
- { "EPD_OUTP_LN", NULL, "EPD_LN" },
- { "EPD_RMV_SHRT_LN", NULL, "EPD_OUTP_LN" },
- { "EPOUTLN", NULL, "EPD_RMV_SHRT_LN" },
-
- { "EPD_RP", NULL, "OUT1R" },
- { "EPD_OUTP_RP", NULL, "EPD_RP" },
- { "EPD_RMV_SHRT_RP", NULL, "EPD_OUTP_RP" },
- { "EPOUTRP", NULL, "EPD_RMV_SHRT_RP" },
-
- { "EPD_RN", NULL, "OUT1R" },
- { "EPD_OUTP_RN", NULL, "EPD_RN" },
- { "EPD_RMV_SHRT_RN", NULL, "EPD_OUTP_RN" },
- { "EPOUTRN", NULL, "EPD_RMV_SHRT_RN" },
-
- { "SPK", NULL, "OUT2L" },
- { "SPK", NULL, "OUT2R" },
-
- WM2200_MIXER_ROUTES("DSP1", "DSP1L"),
- WM2200_MIXER_ROUTES("DSP1", "DSP1R"),
- WM2200_MIXER_ROUTES("DSP2", "DSP2L"),
- WM2200_MIXER_ROUTES("DSP2", "DSP2R"),
-
- WM2200_MIXER_ROUTES("OUT1L", "OUT1L"),
- WM2200_MIXER_ROUTES("OUT1R", "OUT1R"),
- WM2200_MIXER_ROUTES("OUT2L", "OUT2L"),
- WM2200_MIXER_ROUTES("OUT2R", "OUT2R"),
-
- WM2200_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
- WM2200_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
- WM2200_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
- WM2200_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
- WM2200_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
- WM2200_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
-
- WM2200_MIXER_ROUTES("EQL", "EQL"),
- WM2200_MIXER_ROUTES("EQR", "EQR"),
-
- WM2200_MIXER_ROUTES("LHPF1", "LHPF1"),
- WM2200_MIXER_ROUTES("LHPF2", "LHPF2"),
-};
-
-static int wm2200_probe(struct snd_soc_codec *codec)
-{
- struct wm2200_priv *wm2200 = dev_get_drvdata(codec->dev);
- int ret;
-
- wm2200->codec = codec;
- codec->control_data = wm2200->regmap;
- codec->dapm.bias_level = SND_SOC_BIAS_OFF;
-
- ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- return ret;
-}
-
-static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = dai->codec;
- int lrclk, bclk, fmt_val;
-
- lrclk = 0;
- bclk = 0;
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- fmt_val = 0;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- fmt_val = 1;
- break;
- case SND_SOC_DAIFMT_I2S:
- fmt_val = 2;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- fmt_val = 3;
- break;
- default:
- dev_err(codec->dev, "Unsupported DAI format %d\n",
- fmt & SND_SOC_DAIFMT_FORMAT_MASK);
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- case SND_SOC_DAIFMT_CBS_CFM:
- lrclk |= WM2200_AIF1TX_LRCLK_MSTR;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- bclk |= WM2200_AIF1_BCLK_MSTR;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- lrclk |= WM2200_AIF1TX_LRCLK_MSTR;
- bclk |= WM2200_AIF1_BCLK_MSTR;
- break;
- default:
- dev_err(codec->dev, "Unsupported master mode %d\n",
- fmt & SND_SOC_DAIFMT_MASTER_MASK);
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- bclk |= WM2200_AIF1_BCLK_INV;
- lrclk |= WM2200_AIF1TX_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- bclk |= WM2200_AIF1_BCLK_INV;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- lrclk |= WM2200_AIF1TX_LRCLK_INV;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_1, WM2200_AIF1_BCLK_MSTR |
- WM2200_AIF1_BCLK_INV, bclk);
- snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_2,
- WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV,
- lrclk);
- snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_3,
- WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV,
- lrclk);
- snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_5,
- WM2200_AIF1_FMT_MASK << 1, fmt_val << 1);
-
- return 0;
-}
-
-static int wm2200_sr_code[] = {
- 0,
- 12000,
- 24000,
- 48000,
- 96000,
- 192000,
- 384000,
- 768000,
- 0,
- 11025,
- 22050,
- 44100,
- 88200,
- 176400,
- 352800,
- 705600,
- 4000,
- 8000,
- 16000,
- 32000,
- 64000,
- 128000,
- 256000,
- 512000,
-};
-
-#define WM2200_NUM_BCLK_RATES 12
-
-static int wm2200_bclk_rates_dat[WM2200_NUM_BCLK_RATES] = {
- 6144000,
- 3072000,
- 2048000,
- 1536000,
- 768000,
- 512000,
- 384000,
- 256000,
- 192000,
- 128000,
- 96000,
- 64000,
-};
-
-static int wm2200_bclk_rates_cd[WM2200_NUM_BCLK_RATES] = {
- 5644800,
- 3763200,
- 2882400,
- 1881600,
- 1411200,
- 705600,
- 470400,
- 352800,
- 176400,
- 117600,
- 88200,
- 58800,
-};
-
-static int wm2200_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
- int i, bclk, lrclk, wl, fl, sr_code;
- int *bclk_rates;
-
- /* Data sizes if not using TDM */
- wl = snd_pcm_format_width(params_format(params));
- if (wl < 0)
- return wl;
- fl = snd_soc_params_to_frame_size(params);
- if (fl < 0)
- return fl;
-
- dev_dbg(codec->dev, "Word length %d bits, frame length %d bits\n",
- wl, fl);
-
- /* Target BCLK rate */
- bclk = snd_soc_params_to_bclk(params);
- if (bclk < 0)
- return bclk;
-
- if (!wm2200->sysclk) {
- dev_err(codec->dev, "SYSCLK has no rate set\n");
- return -EINVAL;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm2200_sr_code); i++)
- if (wm2200_sr_code[i] == params_rate(params))
- break;
- if (i == ARRAY_SIZE(wm2200_sr_code)) {
- dev_err(codec->dev, "Unsupported sample rate: %dHz\n",
- params_rate(params));
- return -EINVAL;
- }
- sr_code = i;
-
- dev_dbg(codec->dev, "Target BCLK is %dHz, using %dHz SYSCLK\n",
- bclk, wm2200->sysclk);
-
- if (wm2200->sysclk % 4000)
- bclk_rates = wm2200_bclk_rates_cd;
- else
- bclk_rates = wm2200_bclk_rates_dat;
-
- for (i = 0; i < WM2200_NUM_BCLK_RATES; i++)
- if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0))
- break;
- if (i == WM2200_NUM_BCLK_RATES) {
- dev_err(codec->dev,
- "No valid BCLK for %dHz found from %dHz SYSCLK\n",
- bclk, wm2200->sysclk);
- return -EINVAL;
- }
-
- bclk = i;
- dev_dbg(codec->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
- snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_1,
- WM2200_AIF1_BCLK_DIV_MASK, bclk);
-
- lrclk = bclk_rates[bclk] / params_rate(params);
- dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
- dai->symmetric_rates)
- snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_7,
- WM2200_AIF1RX_BCPF_MASK, lrclk);
- else
- snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_6,
- WM2200_AIF1TX_BCPF_MASK, lrclk);
-
- i = (wl << WM2200_AIF1TX_WL_SHIFT) | wl;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_9,
- WM2200_AIF1RX_WL_MASK |
- WM2200_AIF1RX_SLOT_LEN_MASK, i);
- else
- snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_8,
- WM2200_AIF1TX_WL_MASK |
- WM2200_AIF1TX_SLOT_LEN_MASK, i);
-
- snd_soc_update_bits(codec, WM2200_CLOCKING_4,
- WM2200_SAMPLE_RATE_1_MASK, sr_code);
-
- return 0;
-}
-
-static const struct snd_soc_dai_ops wm2200_dai_ops = {
- .set_fmt = wm2200_set_fmt,
- .hw_params = wm2200_hw_params,
-};
-
-static int wm2200_set_sysclk(struct snd_soc_codec *codec, int clk_id,
- int source, unsigned int freq, int dir)
-{
- struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
- int fval;
-
- switch (clk_id) {
- case WM2200_CLK_SYSCLK:
- break;
-
- default:
- dev_err(codec->dev, "Unknown clock %d\n", clk_id);
- return -EINVAL;
- }
-
- switch (source) {
- case WM2200_CLKSRC_MCLK1:
- case WM2200_CLKSRC_MCLK2:
- case WM2200_CLKSRC_FLL:
- case WM2200_CLKSRC_BCLK1:
- break;
- default:
- dev_err(codec->dev, "Invalid source %d\n", source);
- return -EINVAL;
- }
-
- switch (freq) {
- case 22579200:
- case 24576000:
- fval = 2;
- break;
- default:
- dev_err(codec->dev, "Invalid clock rate: %d\n", freq);
- return -EINVAL;
- }
-
- /* TODO: Check if MCLKs are in use and enable/disable pulls to
- * match.
- */
-
- snd_soc_update_bits(codec, WM2200_CLOCKING_3, WM2200_SYSCLK_FREQ_MASK |
- WM2200_SYSCLK_SRC_MASK,
- fval << WM2200_SYSCLK_FREQ_SHIFT | source);
-
- wm2200->sysclk = freq;
-
- return 0;
-}
-
-struct _fll_div {
- u16 fll_fratio;
- u16 fll_outdiv;
- u16 fll_refclk_div;
- u16 n;
- u16 theta;
- u16 lambda;
-};
-
-static struct {
- unsigned int min;
- unsigned int max;
- u16 fll_fratio;
- int ratio;
-} fll_fratios[] = {
- { 0, 64000, 4, 16 },
- { 64000, 128000, 3, 8 },
- { 128000, 256000, 2, 4 },
- { 256000, 1000000, 1, 2 },
- { 1000000, 13500000, 0, 1 },
-};
-
-static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
- unsigned int Fout)
-{
- unsigned int target;
- unsigned int div;
- unsigned int fratio, gcd_fll;
- int i;
-
- /* Fref must be <=13.5MHz */
- div = 1;
- fll_div->fll_refclk_div = 0;
- while ((Fref / div) > 13500000) {
- div *= 2;
- fll_div->fll_refclk_div++;
-
- if (div > 8) {
- pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
- Fref);
- return -EINVAL;
- }
- }
-
- pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
-
- /* Apply the division for our remaining calculations */
- Fref /= div;
-
- /* Fvco should be 90-100MHz; don't check the upper bound */
- div = 2;
- while (Fout * div < 90000000) {
- div++;
- if (div > 64) {
- pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
- Fout);
- return -EINVAL;
- }
- }
- target = Fout * div;
- fll_div->fll_outdiv = div - 1;
-
- pr_debug("FLL Fvco=%dHz\n", target);
-
- /* Find an appropraite FLL_FRATIO and factor it out of the target */
- for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
- if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
- fll_div->fll_fratio = fll_fratios[i].fll_fratio;
- fratio = fll_fratios[i].ratio;
- break;
- }
- }
- if (i == ARRAY_SIZE(fll_fratios)) {
- pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
- return -EINVAL;
- }
-
- fll_div->n = target / (fratio * Fref);
-
- if (target % Fref == 0) {
- fll_div->theta = 0;
- fll_div->lambda = 0;
- } else {
- gcd_fll = gcd(target, fratio * Fref);
-
- fll_div->theta = (target - (fll_div->n * fratio * Fref))
- / gcd_fll;
- fll_div->lambda = (fratio * Fref) / gcd_fll;
- }
-
- pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
- fll_div->n, fll_div->theta, fll_div->lambda);
- pr_debug("FLL_FRATIO=%x(%d) FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
- fll_div->fll_fratio, fratio, fll_div->fll_outdiv,
- fll_div->fll_refclk_div);
-
- return 0;
-}
-
-static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
- unsigned int Fref, unsigned int Fout)
-{
- struct i2c_client *i2c = to_i2c_client(codec->dev);
- struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
- struct _fll_div factors;
- int ret, i, timeout;
-
- if (!Fout) {
- dev_dbg(codec->dev, "FLL disabled");
-
- if (wm2200->fll_fout)
- pm_runtime_put(codec->dev);
-
- wm2200->fll_fout = 0;
- snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1,
- WM2200_FLL_ENA, 0);
- return 0;
- }
-
- switch (source) {
- case WM2200_FLL_SRC_MCLK1:
- case WM2200_FLL_SRC_MCLK2:
- case WM2200_FLL_SRC_BCLK:
- break;
- default:
- dev_err(codec->dev, "Invalid FLL source %d\n", source);
- return -EINVAL;
- }
-
- ret = fll_factors(&factors, Fref, Fout);
- if (ret < 0)
- return ret;
-
- /* Disable the FLL while we reconfigure */
- snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1, WM2200_FLL_ENA, 0);
-
- snd_soc_update_bits(codec, WM2200_FLL_CONTROL_2,
- WM2200_FLL_OUTDIV_MASK | WM2200_FLL_FRATIO_MASK,
- (factors.fll_outdiv << WM2200_FLL_OUTDIV_SHIFT) |
- factors.fll_fratio);
- if (factors.theta) {
- snd_soc_update_bits(codec, WM2200_FLL_CONTROL_3,
- WM2200_FLL_FRACN_ENA,
- WM2200_FLL_FRACN_ENA);
- snd_soc_update_bits(codec, WM2200_FLL_EFS_2,
- WM2200_FLL_EFS_ENA,
- WM2200_FLL_EFS_ENA);
- } else {
- snd_soc_update_bits(codec, WM2200_FLL_CONTROL_3,
- WM2200_FLL_FRACN_ENA, 0);
- snd_soc_update_bits(codec, WM2200_FLL_EFS_2,
- WM2200_FLL_EFS_ENA, 0);
- }
-
- snd_soc_update_bits(codec, WM2200_FLL_CONTROL_4, WM2200_FLL_THETA_MASK,
- factors.theta);
- snd_soc_update_bits(codec, WM2200_FLL_CONTROL_6, WM2200_FLL_N_MASK,
- factors.n);
- snd_soc_update_bits(codec, WM2200_FLL_CONTROL_7,
- WM2200_FLL_CLK_REF_DIV_MASK |
- WM2200_FLL_CLK_REF_SRC_MASK,
- (factors.fll_refclk_div
- << WM2200_FLL_CLK_REF_DIV_SHIFT) | source);
- snd_soc_update_bits(codec, WM2200_FLL_EFS_1,
- WM2200_FLL_LAMBDA_MASK, factors.lambda);
-
- /* Clear any pending completions */
- try_wait_for_completion(&wm2200->fll_lock);
-
- pm_runtime_get_sync(codec->dev);
-
- snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1,
- WM2200_FLL_ENA, WM2200_FLL_ENA);
-
- if (i2c->irq)
- timeout = 2;
- else
- timeout = 50;
-
- snd_soc_update_bits(codec, WM2200_CLOCKING_3, WM2200_SYSCLK_ENA,
- WM2200_SYSCLK_ENA);
-
- /* Poll for the lock; will use the interrupt to exit quickly */
- for (i = 0; i < timeout; i++) {
- if (i2c->irq) {
- ret = wait_for_completion_timeout(&wm2200->fll_lock,
- msecs_to_jiffies(25));
- if (ret > 0)
- break;
- } else {
- msleep(1);
- }
-
- ret = snd_soc_read(codec,
- WM2200_INTERRUPT_RAW_STATUS_2);
- if (ret < 0) {
- dev_err(codec->dev,
- "Failed to read FLL status: %d\n",
- ret);
- continue;
- }
- if (ret & WM2200_FLL_LOCK_STS)
- break;
- }
- if (i == timeout) {
- dev_err(codec->dev, "FLL lock timed out\n");
- pm_runtime_put(codec->dev);
- return -ETIMEDOUT;
- }
-
- wm2200->fll_src = source;
- wm2200->fll_fref = Fref;
- wm2200->fll_fout = Fout;
-
- dev_dbg(codec->dev, "FLL running %dHz->%dHz\n", Fref, Fout);
-
- return 0;
-}
-
-static int wm2200_dai_probe(struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- unsigned int val = 0;
- int ret;
-
- ret = snd_soc_read(codec, WM2200_GPIO_CTRL_1);
- if (ret >= 0) {
- if ((ret & WM2200_GP1_FN_MASK) != 0) {
- dai->symmetric_rates = true;
- val = WM2200_AIF1TX_LRCLK_SRC;
- }
- } else {
- dev_err(codec->dev, "Failed to read GPIO 1 config: %d\n", ret);
- }
-
- snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_2,
- WM2200_AIF1TX_LRCLK_SRC, val);
-
- return 0;
-}
-
-#define WM2200_RATES SNDRV_PCM_RATE_8000_48000
-
-#define WM2200_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static struct snd_soc_dai_driver wm2200_dai = {
- .name = "wm2200",
- .probe = wm2200_dai_probe,
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = WM2200_RATES,
- .formats = WM2200_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = WM2200_RATES,
- .formats = WM2200_FORMATS,
- },
- .ops = &wm2200_dai_ops,
-};
-
-static struct snd_soc_codec_driver soc_codec_wm2200 = {
- .probe = wm2200_probe,
-
- .idle_bias_off = true,
- .ignore_pmdown_time = true,
- .set_sysclk = wm2200_set_sysclk,
- .set_pll = wm2200_set_fll,
-
- .controls = wm2200_snd_controls,
- .num_controls = ARRAY_SIZE(wm2200_snd_controls),
- .dapm_widgets = wm2200_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm2200_dapm_widgets),
- .dapm_routes = wm2200_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm2200_dapm_routes),
-};
-
-static irqreturn_t wm2200_irq(int irq, void *data)
-{
- struct wm2200_priv *wm2200 = data;
- unsigned int val, mask;
- int ret;
-
- ret = regmap_read(wm2200->regmap, WM2200_INTERRUPT_STATUS_2, &val);
- if (ret != 0) {
- dev_err(wm2200->dev, "Failed to read IRQ status: %d\n", ret);
- return IRQ_NONE;
- }
-
- ret = regmap_read(wm2200->regmap, WM2200_INTERRUPT_STATUS_2_MASK,
- &mask);
- if (ret != 0) {
- dev_warn(wm2200->dev, "Failed to read IRQ mask: %d\n", ret);
- mask = 0;
- }
-
- val &= ~mask;
-
- if (val & WM2200_FLL_LOCK_EINT) {
- dev_dbg(wm2200->dev, "FLL locked\n");
- complete(&wm2200->fll_lock);
- }
-
- if (val) {
- regmap_write(wm2200->regmap, WM2200_INTERRUPT_STATUS_2, val);
-
- return IRQ_HANDLED;
- } else {
- return IRQ_NONE;
- }
-}
-
-static const struct regmap_config wm2200_regmap = {
- .reg_bits = 16,
- .val_bits = 16,
-
- .max_register = WM2200_MAX_REGISTER,
- .reg_defaults = wm2200_reg_defaults,
- .num_reg_defaults = ARRAY_SIZE(wm2200_reg_defaults),
- .volatile_reg = wm2200_volatile_register,
- .readable_reg = wm2200_readable_register,
- .cache_type = REGCACHE_RBTREE,
-};
-
-static const unsigned int wm2200_dig_vu[] = {
- WM2200_DAC_DIGITAL_VOLUME_1L,
- WM2200_DAC_DIGITAL_VOLUME_1R,
- WM2200_DAC_DIGITAL_VOLUME_2L,
- WM2200_DAC_DIGITAL_VOLUME_2R,
- WM2200_ADC_DIGITAL_VOLUME_1L,
- WM2200_ADC_DIGITAL_VOLUME_1R,
- WM2200_ADC_DIGITAL_VOLUME_2L,
- WM2200_ADC_DIGITAL_VOLUME_2R,
- WM2200_ADC_DIGITAL_VOLUME_3L,
- WM2200_ADC_DIGITAL_VOLUME_3R,
-};
-
-static const unsigned int wm2200_mic_ctrl_reg[] = {
- WM2200_IN1L_CONTROL,
- WM2200_IN2L_CONTROL,
- WM2200_IN3L_CONTROL,
-};
-
-static __devinit int wm2200_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm2200_pdata *pdata = dev_get_platdata(&i2c->dev);
- struct wm2200_priv *wm2200;
- unsigned int reg;
- int ret, i;
-
- wm2200 = devm_kzalloc(&i2c->dev, sizeof(struct wm2200_priv),
- GFP_KERNEL);
- if (wm2200 == NULL)
- return -ENOMEM;
-
- wm2200->dev = &i2c->dev;
- init_completion(&wm2200->fll_lock);
-
- wm2200->regmap = regmap_init_i2c(i2c, &wm2200_regmap);
- if (IS_ERR(wm2200->regmap)) {
- ret = PTR_ERR(wm2200->regmap);
- dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
- ret);
- goto err;
- }
-
- if (pdata)
- wm2200->pdata = *pdata;
-
- i2c_set_clientdata(i2c, wm2200);
-
- for (i = 0; i < ARRAY_SIZE(wm2200->core_supplies); i++)
- wm2200->core_supplies[i].supply = wm2200_core_supply_names[i];
-
- ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm2200->core_supplies),
- wm2200->core_supplies);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to request core supplies: %d\n",
- ret);
- goto err_regmap;
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies),
- wm2200->core_supplies);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to enable core supplies: %d\n",
- ret);
- goto err_core;
- }
-
- if (wm2200->pdata.ldo_ena) {
- ret = gpio_request_one(wm2200->pdata.ldo_ena,
- GPIOF_OUT_INIT_HIGH, "WM2200 LDOENA");
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n",
- wm2200->pdata.ldo_ena, ret);
- goto err_enable;
- }
- msleep(2);
- }
-
- if (wm2200->pdata.reset) {
- ret = gpio_request_one(wm2200->pdata.reset,
- GPIOF_OUT_INIT_HIGH, "WM2200 /RESET");
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n",
- wm2200->pdata.reset, ret);
- goto err_ldo;
- }
- }
-
- ret = regmap_read(wm2200->regmap, WM2200_SOFTWARE_RESET, &reg);
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);
- goto err_reset;
- }
- switch (reg) {
- case 0x2200:
- break;
-
- default:
- dev_err(&i2c->dev, "Device is not a WM2200, ID is %x\n", reg);
- ret = -EINVAL;
- goto err_reset;
- }
-
- ret = regmap_read(wm2200->regmap, WM2200_DEVICE_REVISION, &reg);
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to read revision register\n");
- goto err_reset;
- }
-
- wm2200->rev = reg & WM2200_DEVICE_REVISION_MASK;
-
- dev_info(&i2c->dev, "revision %c\n", wm2200->rev + 'A');
-
- switch (wm2200->rev) {
- case 0:
- ret = regmap_register_patch(wm2200->regmap, wm2200_reva_patch,
- ARRAY_SIZE(wm2200_reva_patch));
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to register patch: %d\n",
- ret);
- }
- break;
- default:
- break;
- }
-
- ret = wm2200_reset(wm2200);
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to issue reset\n");
- goto err_reset;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm2200->pdata.gpio_defaults); i++) {
- if (!wm2200->pdata.gpio_defaults[i])
- continue;
-
- regmap_write(wm2200->regmap, WM2200_GPIO_CTRL_1 + i,
- wm2200->pdata.gpio_defaults[i]);
- }
-
- for (i = 0; i < ARRAY_SIZE(wm2200_dig_vu); i++)
- regmap_update_bits(wm2200->regmap, wm2200_dig_vu[i],
- WM2200_OUT_VU, WM2200_OUT_VU);
-
- /* Assign slots 1-6 to channels 1-6 for both TX and RX */
- for (i = 0; i < 6; i++) {
- regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_10 + i, i);
- regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_16 + i, i);
- }
-
- for (i = 0; i < ARRAY_SIZE(wm2200->pdata.in_mode); i++) {
- regmap_update_bits(wm2200->regmap, wm2200_mic_ctrl_reg[i],
- WM2200_IN1_MODE_MASK |
- WM2200_IN1_DMIC_SUP_MASK,
- (wm2200->pdata.in_mode[i] <<
- WM2200_IN1_MODE_SHIFT) |
- (wm2200->pdata.dmic_sup[i] <<
- WM2200_IN1_DMIC_SUP_SHIFT));
- }
-
- if (i2c->irq) {
- ret = request_threaded_irq(i2c->irq, NULL, wm2200_irq,
- IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
- "wm2200", wm2200);
- if (ret == 0)
- regmap_update_bits(wm2200->regmap,
- WM2200_INTERRUPT_STATUS_2_MASK,
- WM2200_FLL_LOCK_EINT, 0);
- else
- dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
- i2c->irq, ret);
- }
-
- pm_runtime_set_active(&i2c->dev);
- pm_runtime_enable(&i2c->dev);
- pm_request_idle(&i2c->dev);
-
- ret = snd_soc_register_codec(&i2c->dev, &soc_codec_wm2200,
- &wm2200_dai, 1);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
- goto err_pm_runtime;
- }
-
- return 0;
-
-err_pm_runtime:
- pm_runtime_disable(&i2c->dev);
-err_reset:
- if (wm2200->pdata.reset) {
- gpio_set_value_cansleep(wm2200->pdata.reset, 0);
- gpio_free(wm2200->pdata.reset);
- }
-err_ldo:
- if (wm2200->pdata.ldo_ena) {
- gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
- gpio_free(wm2200->pdata.ldo_ena);
- }
-err_enable:
- regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies),
- wm2200->core_supplies);
-err_core:
- regulator_bulk_free(ARRAY_SIZE(wm2200->core_supplies),
- wm2200->core_supplies);
-err_regmap:
- regmap_exit(wm2200->regmap);
-err:
- return ret;
-}
-
-static __devexit int wm2200_i2c_remove(struct i2c_client *i2c)
-{
- struct wm2200_priv *wm2200 = i2c_get_clientdata(i2c);
-
- snd_soc_unregister_codec(&i2c->dev);
- if (i2c->irq)
- free_irq(i2c->irq, wm2200);
- if (wm2200->pdata.reset) {
- gpio_set_value_cansleep(wm2200->pdata.reset, 0);
- gpio_free(wm2200->pdata.reset);
- }
- if (wm2200->pdata.ldo_ena) {
- gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
- gpio_free(wm2200->pdata.ldo_ena);
- }
- regulator_bulk_free(ARRAY_SIZE(wm2200->core_supplies),
- wm2200->core_supplies);
- regmap_exit(wm2200->regmap);
-
- return 0;
-}
-
-#ifdef CONFIG_PM_RUNTIME
-static int wm2200_runtime_suspend(struct device *dev)
-{
- struct wm2200_priv *wm2200 = dev_get_drvdata(dev);
-
- regcache_cache_only(wm2200->regmap, true);
- regcache_mark_dirty(wm2200->regmap);
- if (wm2200->pdata.ldo_ena)
- gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
- regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies),
- wm2200->core_supplies);
-
- return 0;
-}
-
-static int wm2200_runtime_resume(struct device *dev)
-{
- struct wm2200_priv *wm2200 = dev_get_drvdata(dev);
- int ret;
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies),
- wm2200->core_supplies);
- if (ret != 0) {
- dev_err(dev, "Failed to enable supplies: %d\n",
- ret);
- return ret;
- }
-
- if (wm2200->pdata.ldo_ena) {
- gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 1);
- msleep(2);
- }
-
- regcache_cache_only(wm2200->regmap, false);
- regcache_sync(wm2200->regmap);
-
- return 0;
-}
-#endif
-
-static struct dev_pm_ops wm2200_pm = {
- SET_RUNTIME_PM_OPS(wm2200_runtime_suspend, wm2200_runtime_resume,
- NULL)
-};
-
-static const struct i2c_device_id wm2200_i2c_id[] = {
- { "wm2200", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm2200_i2c_id);
-
-static struct i2c_driver wm2200_i2c_driver = {
- .driver = {
- .name = "wm2200",
- .owner = THIS_MODULE,
- .pm = &wm2200_pm,
- },
- .probe = wm2200_i2c_probe,
- .remove = __devexit_p(wm2200_i2c_remove),
- .id_table = wm2200_i2c_id,
-};
-
-static int __init wm2200_modinit(void)
-{
- return i2c_add_driver(&wm2200_i2c_driver);
-}
-module_init(wm2200_modinit);
-
-static void __exit wm2200_exit(void)
-{
- i2c_del_driver(&wm2200_i2c_driver);
-}
-module_exit(wm2200_exit);
-
-MODULE_DESCRIPTION("ASoC WM2200 driver");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm2200.h b/ANDROID_3.4.5/sound/soc/codecs/wm2200.h
deleted file mode 100644
index 5d719d6b..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm2200.h
+++ /dev/null
@@ -1,3674 +0,0 @@
-/*
- * wm2200.h - WM2200 audio codec interface
- *
- * Copyright 2012 Wolfson Microelectronics PLC.
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#ifndef _WM2200_H
-#define _WM2200_H
-
-#define WM2200_CLK_SYSCLK 1
-
-#define WM2200_CLKSRC_MCLK1 0
-#define WM2200_CLKSRC_MCLK2 1
-#define WM2200_CLKSRC_FLL 4
-#define WM2200_CLKSRC_BCLK1 8
-
-#define WM2200_FLL_SRC_MCLK1 0
-#define WM2200_FLL_SRC_MCLK2 1
-#define WM2200_FLL_SRC_BCLK 2
-
-/*
- * Register values.
- */
-#define WM2200_SOFTWARE_RESET 0x00
-#define WM2200_DEVICE_REVISION 0x01
-#define WM2200_TONE_GENERATOR_1 0x0B
-#define WM2200_CLOCKING_3 0x102
-#define WM2200_CLOCKING_4 0x103
-#define WM2200_FLL_CONTROL_1 0x111
-#define WM2200_FLL_CONTROL_2 0x112
-#define WM2200_FLL_CONTROL_3 0x113
-#define WM2200_FLL_CONTROL_4 0x114
-#define WM2200_FLL_CONTROL_6 0x116
-#define WM2200_FLL_CONTROL_7 0x117
-#define WM2200_FLL_EFS_1 0x119
-#define WM2200_FLL_EFS_2 0x11A
-#define WM2200_MIC_CHARGE_PUMP_1 0x200
-#define WM2200_MIC_CHARGE_PUMP_2 0x201
-#define WM2200_DM_CHARGE_PUMP_1 0x202
-#define WM2200_MIC_BIAS_CTRL_1 0x20C
-#define WM2200_MIC_BIAS_CTRL_2 0x20D
-#define WM2200_EAR_PIECE_CTRL_1 0x20F
-#define WM2200_EAR_PIECE_CTRL_2 0x210
-#define WM2200_INPUT_ENABLES 0x301
-#define WM2200_IN1L_CONTROL 0x302
-#define WM2200_IN1R_CONTROL 0x303
-#define WM2200_IN2L_CONTROL 0x304
-#define WM2200_IN2R_CONTROL 0x305
-#define WM2200_IN3L_CONTROL 0x306
-#define WM2200_IN3R_CONTROL 0x307
-#define WM2200_RXANC_SRC 0x30A
-#define WM2200_INPUT_VOLUME_RAMP 0x30B
-#define WM2200_ADC_DIGITAL_VOLUME_1L 0x30C
-#define WM2200_ADC_DIGITAL_VOLUME_1R 0x30D
-#define WM2200_ADC_DIGITAL_VOLUME_2L 0x30E
-#define WM2200_ADC_DIGITAL_VOLUME_2R 0x30F
-#define WM2200_ADC_DIGITAL_VOLUME_3L 0x310
-#define WM2200_ADC_DIGITAL_VOLUME_3R 0x311
-#define WM2200_OUTPUT_ENABLES 0x400
-#define WM2200_DAC_VOLUME_LIMIT_1L 0x401
-#define WM2200_DAC_VOLUME_LIMIT_1R 0x402
-#define WM2200_DAC_VOLUME_LIMIT_2L 0x403
-#define WM2200_DAC_VOLUME_LIMIT_2R 0x404
-#define WM2200_DAC_AEC_CONTROL_1 0x409
-#define WM2200_OUTPUT_VOLUME_RAMP 0x40A
-#define WM2200_DAC_DIGITAL_VOLUME_1L 0x40B
-#define WM2200_DAC_DIGITAL_VOLUME_1R 0x40C
-#define WM2200_DAC_DIGITAL_VOLUME_2L 0x40D
-#define WM2200_DAC_DIGITAL_VOLUME_2R 0x40E
-#define WM2200_PDM_1 0x417
-#define WM2200_PDM_2 0x418
-#define WM2200_AUDIO_IF_1_1 0x500
-#define WM2200_AUDIO_IF_1_2 0x501
-#define WM2200_AUDIO_IF_1_3 0x502
-#define WM2200_AUDIO_IF_1_4 0x503
-#define WM2200_AUDIO_IF_1_5 0x504
-#define WM2200_AUDIO_IF_1_6 0x505
-#define WM2200_AUDIO_IF_1_7 0x506
-#define WM2200_AUDIO_IF_1_8 0x507
-#define WM2200_AUDIO_IF_1_9 0x508
-#define WM2200_AUDIO_IF_1_10 0x509
-#define WM2200_AUDIO_IF_1_11 0x50A
-#define WM2200_AUDIO_IF_1_12 0x50B
-#define WM2200_AUDIO_IF_1_13 0x50C
-#define WM2200_AUDIO_IF_1_14 0x50D
-#define WM2200_AUDIO_IF_1_15 0x50E
-#define WM2200_AUDIO_IF_1_16 0x50F
-#define WM2200_AUDIO_IF_1_17 0x510
-#define WM2200_AUDIO_IF_1_18 0x511
-#define WM2200_AUDIO_IF_1_19 0x512
-#define WM2200_AUDIO_IF_1_20 0x513
-#define WM2200_AUDIO_IF_1_21 0x514
-#define WM2200_AUDIO_IF_1_22 0x515
-#define WM2200_OUT1LMIX_INPUT_1_SOURCE 0x600
-#define WM2200_OUT1LMIX_INPUT_1_VOLUME 0x601
-#define WM2200_OUT1LMIX_INPUT_2_SOURCE 0x602
-#define WM2200_OUT1LMIX_INPUT_2_VOLUME 0x603
-#define WM2200_OUT1LMIX_INPUT_3_SOURCE 0x604
-#define WM2200_OUT1LMIX_INPUT_3_VOLUME 0x605
-#define WM2200_OUT1LMIX_INPUT_4_SOURCE 0x606
-#define WM2200_OUT1LMIX_INPUT_4_VOLUME 0x607
-#define WM2200_OUT1RMIX_INPUT_1_SOURCE 0x608
-#define WM2200_OUT1RMIX_INPUT_1_VOLUME 0x609
-#define WM2200_OUT1RMIX_INPUT_2_SOURCE 0x60A
-#define WM2200_OUT1RMIX_INPUT_2_VOLUME 0x60B
-#define WM2200_OUT1RMIX_INPUT_3_SOURCE 0x60C
-#define WM2200_OUT1RMIX_INPUT_3_VOLUME 0x60D
-#define WM2200_OUT1RMIX_INPUT_4_SOURCE 0x60E
-#define WM2200_OUT1RMIX_INPUT_4_VOLUME 0x60F
-#define WM2200_OUT2LMIX_INPUT_1_SOURCE 0x610
-#define WM2200_OUT2LMIX_INPUT_1_VOLUME 0x611
-#define WM2200_OUT2LMIX_INPUT_2_SOURCE 0x612
-#define WM2200_OUT2LMIX_INPUT_2_VOLUME 0x613
-#define WM2200_OUT2LMIX_INPUT_3_SOURCE 0x614
-#define WM2200_OUT2LMIX_INPUT_3_VOLUME 0x615
-#define WM2200_OUT2LMIX_INPUT_4_SOURCE 0x616
-#define WM2200_OUT2LMIX_INPUT_4_VOLUME 0x617
-#define WM2200_OUT2RMIX_INPUT_1_SOURCE 0x618
-#define WM2200_OUT2RMIX_INPUT_1_VOLUME 0x619
-#define WM2200_OUT2RMIX_INPUT_2_SOURCE 0x61A
-#define WM2200_OUT2RMIX_INPUT_2_VOLUME 0x61B
-#define WM2200_OUT2RMIX_INPUT_3_SOURCE 0x61C
-#define WM2200_OUT2RMIX_INPUT_3_VOLUME 0x61D
-#define WM2200_OUT2RMIX_INPUT_4_SOURCE 0x61E
-#define WM2200_OUT2RMIX_INPUT_4_VOLUME 0x61F
-#define WM2200_AIF1TX1MIX_INPUT_1_SOURCE 0x620
-#define WM2200_AIF1TX1MIX_INPUT_1_VOLUME 0x621
-#define WM2200_AIF1TX1MIX_INPUT_2_SOURCE 0x622
-#define WM2200_AIF1TX1MIX_INPUT_2_VOLUME 0x623
-#define WM2200_AIF1TX1MIX_INPUT_3_SOURCE 0x624
-#define WM2200_AIF1TX1MIX_INPUT_3_VOLUME 0x625
-#define WM2200_AIF1TX1MIX_INPUT_4_SOURCE 0x626
-#define WM2200_AIF1TX1MIX_INPUT_4_VOLUME 0x627
-#define WM2200_AIF1TX2MIX_INPUT_1_SOURCE 0x628
-#define WM2200_AIF1TX2MIX_INPUT_1_VOLUME 0x629
-#define WM2200_AIF1TX2MIX_INPUT_2_SOURCE 0x62A
-#define WM2200_AIF1TX2MIX_INPUT_2_VOLUME 0x62B
-#define WM2200_AIF1TX2MIX_INPUT_3_SOURCE 0x62C
-#define WM2200_AIF1TX2MIX_INPUT_3_VOLUME 0x62D
-#define WM2200_AIF1TX2MIX_INPUT_4_SOURCE 0x62E
-#define WM2200_AIF1TX2MIX_INPUT_4_VOLUME 0x62F
-#define WM2200_AIF1TX3MIX_INPUT_1_SOURCE 0x630
-#define WM2200_AIF1TX3MIX_INPUT_1_VOLUME 0x631
-#define WM2200_AIF1TX3MIX_INPUT_2_SOURCE 0x632
-#define WM2200_AIF1TX3MIX_INPUT_2_VOLUME 0x633
-#define WM2200_AIF1TX3MIX_INPUT_3_SOURCE 0x634
-#define WM2200_AIF1TX3MIX_INPUT_3_VOLUME 0x635
-#define WM2200_AIF1TX3MIX_INPUT_4_SOURCE 0x636
-#define WM2200_AIF1TX3MIX_INPUT_4_VOLUME 0x637
-#define WM2200_AIF1TX4MIX_INPUT_1_SOURCE 0x638
-#define WM2200_AIF1TX4MIX_INPUT_1_VOLUME 0x639
-#define WM2200_AIF1TX4MIX_INPUT_2_SOURCE 0x63A
-#define WM2200_AIF1TX4MIX_INPUT_2_VOLUME 0x63B
-#define WM2200_AIF1TX4MIX_INPUT_3_SOURCE 0x63C
-#define WM2200_AIF1TX4MIX_INPUT_3_VOLUME 0x63D
-#define WM2200_AIF1TX4MIX_INPUT_4_SOURCE 0x63E
-#define WM2200_AIF1TX4MIX_INPUT_4_VOLUME 0x63F
-#define WM2200_AIF1TX5MIX_INPUT_1_SOURCE 0x640
-#define WM2200_AIF1TX5MIX_INPUT_1_VOLUME 0x641
-#define WM2200_AIF1TX5MIX_INPUT_2_SOURCE 0x642
-#define WM2200_AIF1TX5MIX_INPUT_2_VOLUME 0x643
-#define WM2200_AIF1TX5MIX_INPUT_3_SOURCE 0x644
-#define WM2200_AIF1TX5MIX_INPUT_3_VOLUME 0x645
-#define WM2200_AIF1TX5MIX_INPUT_4_SOURCE 0x646
-#define WM2200_AIF1TX5MIX_INPUT_4_VOLUME 0x647
-#define WM2200_AIF1TX6MIX_INPUT_1_SOURCE 0x648
-#define WM2200_AIF1TX6MIX_INPUT_1_VOLUME 0x649
-#define WM2200_AIF1TX6MIX_INPUT_2_SOURCE 0x64A
-#define WM2200_AIF1TX6MIX_INPUT_2_VOLUME 0x64B
-#define WM2200_AIF1TX6MIX_INPUT_3_SOURCE 0x64C
-#define WM2200_AIF1TX6MIX_INPUT_3_VOLUME 0x64D
-#define WM2200_AIF1TX6MIX_INPUT_4_SOURCE 0x64E
-#define WM2200_AIF1TX6MIX_INPUT_4_VOLUME 0x64F
-#define WM2200_EQLMIX_INPUT_1_SOURCE 0x650
-#define WM2200_EQLMIX_INPUT_1_VOLUME 0x651
-#define WM2200_EQLMIX_INPUT_2_SOURCE 0x652
-#define WM2200_EQLMIX_INPUT_2_VOLUME 0x653
-#define WM2200_EQLMIX_INPUT_3_SOURCE 0x654
-#define WM2200_EQLMIX_INPUT_3_VOLUME 0x655
-#define WM2200_EQLMIX_INPUT_4_SOURCE 0x656
-#define WM2200_EQLMIX_INPUT_4_VOLUME 0x657
-#define WM2200_EQRMIX_INPUT_1_SOURCE 0x658
-#define WM2200_EQRMIX_INPUT_1_VOLUME 0x659
-#define WM2200_EQRMIX_INPUT_2_SOURCE 0x65A
-#define WM2200_EQRMIX_INPUT_2_VOLUME 0x65B
-#define WM2200_EQRMIX_INPUT_3_SOURCE 0x65C
-#define WM2200_EQRMIX_INPUT_3_VOLUME 0x65D
-#define WM2200_EQRMIX_INPUT_4_SOURCE 0x65E
-#define WM2200_EQRMIX_INPUT_4_VOLUME 0x65F
-#define WM2200_LHPF1MIX_INPUT_1_SOURCE 0x660
-#define WM2200_LHPF1MIX_INPUT_1_VOLUME 0x661
-#define WM2200_LHPF1MIX_INPUT_2_SOURCE 0x662
-#define WM2200_LHPF1MIX_INPUT_2_VOLUME 0x663
-#define WM2200_LHPF1MIX_INPUT_3_SOURCE 0x664
-#define WM2200_LHPF1MIX_INPUT_3_VOLUME 0x665
-#define WM2200_LHPF1MIX_INPUT_4_SOURCE 0x666
-#define WM2200_LHPF1MIX_INPUT_4_VOLUME 0x667
-#define WM2200_LHPF2MIX_INPUT_1_SOURCE 0x668
-#define WM2200_LHPF2MIX_INPUT_1_VOLUME 0x669
-#define WM2200_LHPF2MIX_INPUT_2_SOURCE 0x66A
-#define WM2200_LHPF2MIX_INPUT_2_VOLUME 0x66B
-#define WM2200_LHPF2MIX_INPUT_3_SOURCE 0x66C
-#define WM2200_LHPF2MIX_INPUT_3_VOLUME 0x66D
-#define WM2200_LHPF2MIX_INPUT_4_SOURCE 0x66E
-#define WM2200_LHPF2MIX_INPUT_4_VOLUME 0x66F
-#define WM2200_DSP1LMIX_INPUT_1_SOURCE 0x670
-#define WM2200_DSP1LMIX_INPUT_1_VOLUME 0x671
-#define WM2200_DSP1LMIX_INPUT_2_SOURCE 0x672
-#define WM2200_DSP1LMIX_INPUT_2_VOLUME 0x673
-#define WM2200_DSP1LMIX_INPUT_3_SOURCE 0x674
-#define WM2200_DSP1LMIX_INPUT_3_VOLUME 0x675
-#define WM2200_DSP1LMIX_INPUT_4_SOURCE 0x676
-#define WM2200_DSP1LMIX_INPUT_4_VOLUME 0x677
-#define WM2200_DSP1RMIX_INPUT_1_SOURCE 0x678
-#define WM2200_DSP1RMIX_INPUT_1_VOLUME 0x679
-#define WM2200_DSP1RMIX_INPUT_2_SOURCE 0x67A
-#define WM2200_DSP1RMIX_INPUT_2_VOLUME 0x67B
-#define WM2200_DSP1RMIX_INPUT_3_SOURCE 0x67C
-#define WM2200_DSP1RMIX_INPUT_3_VOLUME 0x67D
-#define WM2200_DSP1RMIX_INPUT_4_SOURCE 0x67E
-#define WM2200_DSP1RMIX_INPUT_4_VOLUME 0x67F
-#define WM2200_DSP1AUX1MIX_INPUT_1_SOURCE 0x680
-#define WM2200_DSP1AUX2MIX_INPUT_1_SOURCE 0x681
-#define WM2200_DSP1AUX3MIX_INPUT_1_SOURCE 0x682
-#define WM2200_DSP1AUX4MIX_INPUT_1_SOURCE 0x683
-#define WM2200_DSP1AUX5MIX_INPUT_1_SOURCE 0x684
-#define WM2200_DSP1AUX6MIX_INPUT_1_SOURCE 0x685
-#define WM2200_DSP2LMIX_INPUT_1_SOURCE 0x686
-#define WM2200_DSP2LMIX_INPUT_1_VOLUME 0x687
-#define WM2200_DSP2LMIX_INPUT_2_SOURCE 0x688
-#define WM2200_DSP2LMIX_INPUT_2_VOLUME 0x689
-#define WM2200_DSP2LMIX_INPUT_3_SOURCE 0x68A
-#define WM2200_DSP2LMIX_INPUT_3_VOLUME 0x68B
-#define WM2200_DSP2LMIX_INPUT_4_SOURCE 0x68C
-#define WM2200_DSP2LMIX_INPUT_4_VOLUME 0x68D
-#define WM2200_DSP2RMIX_INPUT_1_SOURCE 0x68E
-#define WM2200_DSP2RMIX_INPUT_1_VOLUME 0x68F
-#define WM2200_DSP2RMIX_INPUT_2_SOURCE 0x690
-#define WM2200_DSP2RMIX_INPUT_2_VOLUME 0x691
-#define WM2200_DSP2RMIX_INPUT_3_SOURCE 0x692
-#define WM2200_DSP2RMIX_INPUT_3_VOLUME 0x693
-#define WM2200_DSP2RMIX_INPUT_4_SOURCE 0x694
-#define WM2200_DSP2RMIX_INPUT_4_VOLUME 0x695
-#define WM2200_DSP2AUX1MIX_INPUT_1_SOURCE 0x696
-#define WM2200_DSP2AUX2MIX_INPUT_1_SOURCE 0x697
-#define WM2200_DSP2AUX3MIX_INPUT_1_SOURCE 0x698
-#define WM2200_DSP2AUX4MIX_INPUT_1_SOURCE 0x699
-#define WM2200_DSP2AUX5MIX_INPUT_1_SOURCE 0x69A
-#define WM2200_DSP2AUX6MIX_INPUT_1_SOURCE 0x69B
-#define WM2200_GPIO_CTRL_1 0x700
-#define WM2200_GPIO_CTRL_2 0x701
-#define WM2200_GPIO_CTRL_3 0x702
-#define WM2200_GPIO_CTRL_4 0x703
-#define WM2200_ADPS1_IRQ0 0x707
-#define WM2200_ADPS1_IRQ1 0x708
-#define WM2200_MISC_PAD_CTRL_1 0x709
-#define WM2200_INTERRUPT_STATUS_1 0x800
-#define WM2200_INTERRUPT_STATUS_1_MASK 0x801
-#define WM2200_INTERRUPT_STATUS_2 0x802
-#define WM2200_INTERRUPT_RAW_STATUS_2 0x803
-#define WM2200_INTERRUPT_STATUS_2_MASK 0x804
-#define WM2200_INTERRUPT_CONTROL 0x808
-#define WM2200_EQL_1 0x900
-#define WM2200_EQL_2 0x901
-#define WM2200_EQL_3 0x902
-#define WM2200_EQL_4 0x903
-#define WM2200_EQL_5 0x904
-#define WM2200_EQL_6 0x905
-#define WM2200_EQL_7 0x906
-#define WM2200_EQL_8 0x907
-#define WM2200_EQL_9 0x908
-#define WM2200_EQL_10 0x909
-#define WM2200_EQL_11 0x90A
-#define WM2200_EQL_12 0x90B
-#define WM2200_EQL_13 0x90C
-#define WM2200_EQL_14 0x90D
-#define WM2200_EQL_15 0x90E
-#define WM2200_EQL_16 0x90F
-#define WM2200_EQL_17 0x910
-#define WM2200_EQL_18 0x911
-#define WM2200_EQL_19 0x912
-#define WM2200_EQL_20 0x913
-#define WM2200_EQR_1 0x916
-#define WM2200_EQR_2 0x917
-#define WM2200_EQR_3 0x918
-#define WM2200_EQR_4 0x919
-#define WM2200_EQR_5 0x91A
-#define WM2200_EQR_6 0x91B
-#define WM2200_EQR_7 0x91C
-#define WM2200_EQR_8 0x91D
-#define WM2200_EQR_9 0x91E
-#define WM2200_EQR_10 0x91F
-#define WM2200_EQR_11 0x920
-#define WM2200_EQR_12 0x921
-#define WM2200_EQR_13 0x922
-#define WM2200_EQR_14 0x923
-#define WM2200_EQR_15 0x924
-#define WM2200_EQR_16 0x925
-#define WM2200_EQR_17 0x926
-#define WM2200_EQR_18 0x927
-#define WM2200_EQR_19 0x928
-#define WM2200_EQR_20 0x929
-#define WM2200_HPLPF1_1 0x93E
-#define WM2200_HPLPF1_2 0x93F
-#define WM2200_HPLPF2_1 0x942
-#define WM2200_HPLPF2_2 0x943
-#define WM2200_DSP1_CONTROL_1 0xA00
-#define WM2200_DSP1_CONTROL_2 0xA02
-#define WM2200_DSP1_CONTROL_3 0xA03
-#define WM2200_DSP1_CONTROL_4 0xA04
-#define WM2200_DSP1_CONTROL_5 0xA06
-#define WM2200_DSP1_CONTROL_6 0xA07
-#define WM2200_DSP1_CONTROL_7 0xA08
-#define WM2200_DSP1_CONTROL_8 0xA09
-#define WM2200_DSP1_CONTROL_9 0xA0A
-#define WM2200_DSP1_CONTROL_10 0xA0B
-#define WM2200_DSP1_CONTROL_11 0xA0C
-#define WM2200_DSP1_CONTROL_12 0xA0D
-#define WM2200_DSP1_CONTROL_13 0xA0F
-#define WM2200_DSP1_CONTROL_14 0xA10
-#define WM2200_DSP1_CONTROL_15 0xA11
-#define WM2200_DSP1_CONTROL_16 0xA12
-#define WM2200_DSP1_CONTROL_17 0xA13
-#define WM2200_DSP1_CONTROL_18 0xA14
-#define WM2200_DSP1_CONTROL_19 0xA16
-#define WM2200_DSP1_CONTROL_20 0xA17
-#define WM2200_DSP1_CONTROL_21 0xA18
-#define WM2200_DSP1_CONTROL_22 0xA1A
-#define WM2200_DSP1_CONTROL_23 0xA1B
-#define WM2200_DSP1_CONTROL_24 0xA1C
-#define WM2200_DSP1_CONTROL_25 0xA1E
-#define WM2200_DSP1_CONTROL_26 0xA20
-#define WM2200_DSP1_CONTROL_27 0xA21
-#define WM2200_DSP1_CONTROL_28 0xA22
-#define WM2200_DSP1_CONTROL_29 0xA23
-#define WM2200_DSP1_CONTROL_30 0xA24
-#define WM2200_DSP1_CONTROL_31 0xA26
-#define WM2200_DSP2_CONTROL_1 0xB00
-#define WM2200_DSP2_CONTROL_2 0xB02
-#define WM2200_DSP2_CONTROL_3 0xB03
-#define WM2200_DSP2_CONTROL_4 0xB04
-#define WM2200_DSP2_CONTROL_5 0xB06
-#define WM2200_DSP2_CONTROL_6 0xB07
-#define WM2200_DSP2_CONTROL_7 0xB08
-#define WM2200_DSP2_CONTROL_8 0xB09
-#define WM2200_DSP2_CONTROL_9 0xB0A
-#define WM2200_DSP2_CONTROL_10 0xB0B
-#define WM2200_DSP2_CONTROL_11 0xB0C
-#define WM2200_DSP2_CONTROL_12 0xB0D
-#define WM2200_DSP2_CONTROL_13 0xB0F
-#define WM2200_DSP2_CONTROL_14 0xB10
-#define WM2200_DSP2_CONTROL_15 0xB11
-#define WM2200_DSP2_CONTROL_16 0xB12
-#define WM2200_DSP2_CONTROL_17 0xB13
-#define WM2200_DSP2_CONTROL_18 0xB14
-#define WM2200_DSP2_CONTROL_19 0xB16
-#define WM2200_DSP2_CONTROL_20 0xB17
-#define WM2200_DSP2_CONTROL_21 0xB18
-#define WM2200_DSP2_CONTROL_22 0xB1A
-#define WM2200_DSP2_CONTROL_23 0xB1B
-#define WM2200_DSP2_CONTROL_24 0xB1C
-#define WM2200_DSP2_CONTROL_25 0xB1E
-#define WM2200_DSP2_CONTROL_26 0xB20
-#define WM2200_DSP2_CONTROL_27 0xB21
-#define WM2200_DSP2_CONTROL_28 0xB22
-#define WM2200_DSP2_CONTROL_29 0xB23
-#define WM2200_DSP2_CONTROL_30 0xB24
-#define WM2200_DSP2_CONTROL_31 0xB26
-#define WM2200_ANC_CTRL1 0xD00
-#define WM2200_ANC_CTRL2 0xD01
-#define WM2200_ANC_CTRL3 0xD02
-#define WM2200_ANC_CTRL7 0xD08
-#define WM2200_ANC_CTRL8 0xD09
-#define WM2200_ANC_CTRL9 0xD0A
-#define WM2200_ANC_CTRL10 0xD0B
-#define WM2200_ANC_CTRL11 0xD0C
-#define WM2200_ANC_CTRL12 0xD0D
-#define WM2200_ANC_CTRL13 0xD0E
-#define WM2200_ANC_CTRL14 0xD0F
-#define WM2200_ANC_CTRL15 0xD10
-#define WM2200_ANC_CTRL16 0xD11
-#define WM2200_ANC_CTRL17 0xD12
-#define WM2200_ANC_CTRL18 0xD15
-#define WM2200_ANC_CTRL19 0xD16
-#define WM2200_ANC_CTRL20 0xD17
-#define WM2200_ANC_CTRL21 0xD18
-#define WM2200_ANC_CTRL22 0xD19
-#define WM2200_ANC_CTRL23 0xD1A
-#define WM2200_ANC_CTRL24 0xD1B
-#define WM2200_ANC_CTRL25 0xD1C
-#define WM2200_ANC_CTRL26 0xD1D
-#define WM2200_ANC_CTRL27 0xD1E
-#define WM2200_ANC_CTRL28 0xD1F
-#define WM2200_ANC_CTRL29 0xD20
-#define WM2200_ANC_CTRL30 0xD21
-#define WM2200_ANC_CTRL31 0xD23
-#define WM2200_ANC_CTRL32 0xD24
-#define WM2200_ANC_CTRL33 0xD25
-#define WM2200_ANC_CTRL34 0xD27
-#define WM2200_ANC_CTRL35 0xD28
-#define WM2200_ANC_CTRL36 0xD29
-#define WM2200_ANC_CTRL37 0xD2A
-#define WM2200_ANC_CTRL38 0xD2B
-#define WM2200_ANC_CTRL39 0xD2C
-#define WM2200_ANC_CTRL40 0xD2D
-#define WM2200_ANC_CTRL41 0xD2E
-#define WM2200_ANC_CTRL42 0xD2F
-#define WM2200_ANC_CTRL43 0xD30
-#define WM2200_ANC_CTRL44 0xD31
-#define WM2200_ANC_CTRL45 0xD32
-#define WM2200_ANC_CTRL46 0xD33
-#define WM2200_ANC_CTRL47 0xD34
-#define WM2200_ANC_CTRL48 0xD35
-#define WM2200_ANC_CTRL49 0xD36
-#define WM2200_ANC_CTRL50 0xD37
-#define WM2200_ANC_CTRL51 0xD38
-#define WM2200_ANC_CTRL52 0xD39
-#define WM2200_ANC_CTRL53 0xD3A
-#define WM2200_ANC_CTRL54 0xD3B
-#define WM2200_ANC_CTRL55 0xD3C
-#define WM2200_ANC_CTRL56 0xD3D
-#define WM2200_ANC_CTRL57 0xD3E
-#define WM2200_ANC_CTRL58 0xD3F
-#define WM2200_ANC_CTRL59 0xD40
-#define WM2200_ANC_CTRL60 0xD41
-#define WM2200_ANC_CTRL61 0xD42
-#define WM2200_ANC_CTRL62 0xD43
-#define WM2200_ANC_CTRL63 0xD44
-#define WM2200_ANC_CTRL64 0xD45
-#define WM2200_ANC_CTRL65 0xD46
-#define WM2200_ANC_CTRL66 0xD47
-#define WM2200_ANC_CTRL67 0xD48
-#define WM2200_ANC_CTRL68 0xD49
-#define WM2200_ANC_CTRL69 0xD4A
-#define WM2200_ANC_CTRL70 0xD4B
-#define WM2200_ANC_CTRL71 0xD4C
-#define WM2200_ANC_CTRL72 0xD4D
-#define WM2200_ANC_CTRL73 0xD4E
-#define WM2200_ANC_CTRL74 0xD4F
-#define WM2200_ANC_CTRL75 0xD50
-#define WM2200_ANC_CTRL76 0xD51
-#define WM2200_ANC_CTRL77 0xD52
-#define WM2200_ANC_CTRL78 0xD53
-#define WM2200_ANC_CTRL79 0xD54
-#define WM2200_ANC_CTRL80 0xD55
-#define WM2200_ANC_CTRL81 0xD56
-#define WM2200_ANC_CTRL82 0xD57
-#define WM2200_ANC_CTRL83 0xD58
-#define WM2200_ANC_CTRL84 0xD5B
-#define WM2200_ANC_CTRL85 0xD5C
-#define WM2200_ANC_CTRL86 0xD5F
-#define WM2200_ANC_CTRL87 0xD60
-#define WM2200_ANC_CTRL88 0xD61
-#define WM2200_ANC_CTRL89 0xD62
-#define WM2200_ANC_CTRL90 0xD63
-#define WM2200_ANC_CTRL91 0xD64
-#define WM2200_ANC_CTRL92 0xD65
-#define WM2200_ANC_CTRL93 0xD66
-#define WM2200_ANC_CTRL94 0xD67
-#define WM2200_ANC_CTRL95 0xD68
-#define WM2200_ANC_CTRL96 0xD69
-#define WM2200_DSP1_DM_0 0x3000
-#define WM2200_DSP1_DM_1 0x3001
-#define WM2200_DSP1_DM_2 0x3002
-#define WM2200_DSP1_DM_3 0x3003
-#define WM2200_DSP1_DM_2044 0x37FC
-#define WM2200_DSP1_DM_2045 0x37FD
-#define WM2200_DSP1_DM_2046 0x37FE
-#define WM2200_DSP1_DM_2047 0x37FF
-#define WM2200_DSP1_PM_0 0x3800
-#define WM2200_DSP1_PM_1 0x3801
-#define WM2200_DSP1_PM_2 0x3802
-#define WM2200_DSP1_PM_3 0x3803
-#define WM2200_DSP1_PM_4 0x3804
-#define WM2200_DSP1_PM_5 0x3805
-#define WM2200_DSP1_PM_762 0x3AFA
-#define WM2200_DSP1_PM_763 0x3AFB
-#define WM2200_DSP1_PM_764 0x3AFC
-#define WM2200_DSP1_PM_765 0x3AFD
-#define WM2200_DSP1_PM_766 0x3AFE
-#define WM2200_DSP1_PM_767 0x3AFF
-#define WM2200_DSP1_ZM_0 0x3C00
-#define WM2200_DSP1_ZM_1 0x3C01
-#define WM2200_DSP1_ZM_2 0x3C02
-#define WM2200_DSP1_ZM_3 0x3C03
-#define WM2200_DSP1_ZM_1020 0x3FFC
-#define WM2200_DSP1_ZM_1021 0x3FFD
-#define WM2200_DSP1_ZM_1022 0x3FFE
-#define WM2200_DSP1_ZM_1023 0x3FFF
-#define WM2200_DSP2_DM_0 0x4000
-#define WM2200_DSP2_DM_1 0x4001
-#define WM2200_DSP2_DM_2 0x4002
-#define WM2200_DSP2_DM_3 0x4003
-#define WM2200_DSP2_DM_2044 0x47FC
-#define WM2200_DSP2_DM_2045 0x47FD
-#define WM2200_DSP2_DM_2046 0x47FE
-#define WM2200_DSP2_DM_2047 0x47FF
-#define WM2200_DSP2_PM_0 0x4800
-#define WM2200_DSP2_PM_1 0x4801
-#define WM2200_DSP2_PM_2 0x4802
-#define WM2200_DSP2_PM_3 0x4803
-#define WM2200_DSP2_PM_4 0x4804
-#define WM2200_DSP2_PM_5 0x4805
-#define WM2200_DSP2_PM_762 0x4AFA
-#define WM2200_DSP2_PM_763 0x4AFB
-#define WM2200_DSP2_PM_764 0x4AFC
-#define WM2200_DSP2_PM_765 0x4AFD
-#define WM2200_DSP2_PM_766 0x4AFE
-#define WM2200_DSP2_PM_767 0x4AFF
-#define WM2200_DSP2_ZM_0 0x4C00
-#define WM2200_DSP2_ZM_1 0x4C01
-#define WM2200_DSP2_ZM_2 0x4C02
-#define WM2200_DSP2_ZM_3 0x4C03
-#define WM2200_DSP2_ZM_1020 0x4FFC
-#define WM2200_DSP2_ZM_1021 0x4FFD
-#define WM2200_DSP2_ZM_1022 0x4FFE
-#define WM2200_DSP2_ZM_1023 0x4FFF
-
-#define WM2200_REGISTER_COUNT 494
-#define WM2200_MAX_REGISTER 0x4FFF
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - software reset
- */
-#define WM2200_SW_RESET_CHIP_ID1_MASK 0xFFFF /* SW_RESET_CHIP_ID1 - [15:0] */
-#define WM2200_SW_RESET_CHIP_ID1_SHIFT 0 /* SW_RESET_CHIP_ID1 - [15:0] */
-#define WM2200_SW_RESET_CHIP_ID1_WIDTH 16 /* SW_RESET_CHIP_ID1 - [15:0] */
-
-/*
- * R1 (0x01) - Device Revision
- */
-#define WM2200_DEVICE_REVISION_MASK 0x000F /* DEVICE_REVISION - [3:0] */
-#define WM2200_DEVICE_REVISION_SHIFT 0 /* DEVICE_REVISION - [3:0] */
-#define WM2200_DEVICE_REVISION_WIDTH 4 /* DEVICE_REVISION - [3:0] */
-
-/*
- * R11 (0x0B) - Tone Generator 1
- */
-#define WM2200_TONE_ENA 0x0001 /* TONE_ENA */
-#define WM2200_TONE_ENA_MASK 0x0001 /* TONE_ENA */
-#define WM2200_TONE_ENA_SHIFT 0 /* TONE_ENA */
-#define WM2200_TONE_ENA_WIDTH 1 /* TONE_ENA */
-
-/*
- * R258 (0x102) - Clocking 3
- */
-#define WM2200_SYSCLK_FREQ_MASK 0x0700 /* SYSCLK_FREQ - [10:8] */
-#define WM2200_SYSCLK_FREQ_SHIFT 8 /* SYSCLK_FREQ - [10:8] */
-#define WM2200_SYSCLK_FREQ_WIDTH 3 /* SYSCLK_FREQ - [10:8] */
-#define WM2200_SYSCLK_ENA 0x0040 /* SYSCLK_ENA */
-#define WM2200_SYSCLK_ENA_MASK 0x0040 /* SYSCLK_ENA */
-#define WM2200_SYSCLK_ENA_SHIFT 6 /* SYSCLK_ENA */
-#define WM2200_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */
-#define WM2200_SYSCLK_SRC_MASK 0x000F /* SYSCLK_SRC - [3:0] */
-#define WM2200_SYSCLK_SRC_SHIFT 0 /* SYSCLK_SRC - [3:0] */
-#define WM2200_SYSCLK_SRC_WIDTH 4 /* SYSCLK_SRC - [3:0] */
-
-/*
- * R259 (0x103) - Clocking 4
- */
-#define WM2200_SAMPLE_RATE_1_MASK 0x001F /* SAMPLE_RATE_1 - [4:0] */
-#define WM2200_SAMPLE_RATE_1_SHIFT 0 /* SAMPLE_RATE_1 - [4:0] */
-#define WM2200_SAMPLE_RATE_1_WIDTH 5 /* SAMPLE_RATE_1 - [4:0] */
-
-/*
- * R273 (0x111) - FLL Control 1
- */
-#define WM2200_FLL_ENA 0x0001 /* FLL_ENA */
-#define WM2200_FLL_ENA_MASK 0x0001 /* FLL_ENA */
-#define WM2200_FLL_ENA_SHIFT 0 /* FLL_ENA */
-#define WM2200_FLL_ENA_WIDTH 1 /* FLL_ENA */
-
-/*
- * R274 (0x112) - FLL Control 2
- */
-#define WM2200_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */
-#define WM2200_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */
-#define WM2200_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */
-#define WM2200_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
-#define WM2200_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
-#define WM2200_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
-
-/*
- * R275 (0x113) - FLL Control 3
- */
-#define WM2200_FLL_FRACN_ENA 0x0001 /* FLL_FRACN_ENA */
-#define WM2200_FLL_FRACN_ENA_MASK 0x0001 /* FLL_FRACN_ENA */
-#define WM2200_FLL_FRACN_ENA_SHIFT 0 /* FLL_FRACN_ENA */
-#define WM2200_FLL_FRACN_ENA_WIDTH 1 /* FLL_FRACN_ENA */
-
-/*
- * R276 (0x114) - FLL Control 4
- */
-#define WM2200_FLL_THETA_MASK 0xFFFF /* FLL_THETA - [15:0] */
-#define WM2200_FLL_THETA_SHIFT 0 /* FLL_THETA - [15:0] */
-#define WM2200_FLL_THETA_WIDTH 16 /* FLL_THETA - [15:0] */
-
-/*
- * R278 (0x116) - FLL Control 6
- */
-#define WM2200_FLL_N_MASK 0x03FF /* FLL_N - [9:0] */
-#define WM2200_FLL_N_SHIFT 0 /* FLL_N - [9:0] */
-#define WM2200_FLL_N_WIDTH 10 /* FLL_N - [9:0] */
-
-/*
- * R279 (0x117) - FLL Control 7
- */
-#define WM2200_FLL_CLK_REF_DIV_MASK 0x0030 /* FLL_CLK_REF_DIV - [5:4] */
-#define WM2200_FLL_CLK_REF_DIV_SHIFT 4 /* FLL_CLK_REF_DIV - [5:4] */
-#define WM2200_FLL_CLK_REF_DIV_WIDTH 2 /* FLL_CLK_REF_DIV - [5:4] */
-#define WM2200_FLL_CLK_REF_SRC_MASK 0x0003 /* FLL_CLK_REF_SRC - [1:0] */
-#define WM2200_FLL_CLK_REF_SRC_SHIFT 0 /* FLL_CLK_REF_SRC - [1:0] */
-#define WM2200_FLL_CLK_REF_SRC_WIDTH 2 /* FLL_CLK_REF_SRC - [1:0] */
-
-/*
- * R281 (0x119) - FLL EFS 1
- */
-#define WM2200_FLL_LAMBDA_MASK 0xFFFF /* FLL_LAMBDA - [15:0] */
-#define WM2200_FLL_LAMBDA_SHIFT 0 /* FLL_LAMBDA - [15:0] */
-#define WM2200_FLL_LAMBDA_WIDTH 16 /* FLL_LAMBDA - [15:0] */
-
-/*
- * R282 (0x11A) - FLL EFS 2
- */
-#define WM2200_FLL_EFS_ENA 0x0001 /* FLL_EFS_ENA */
-#define WM2200_FLL_EFS_ENA_MASK 0x0001 /* FLL_EFS_ENA */
-#define WM2200_FLL_EFS_ENA_SHIFT 0 /* FLL_EFS_ENA */
-#define WM2200_FLL_EFS_ENA_WIDTH 1 /* FLL_EFS_ENA */
-
-/*
- * R512 (0x200) - Mic Charge Pump 1
- */
-#define WM2200_CPMIC_BYPASS_MODE 0x0020 /* CPMIC_BYPASS_MODE */
-#define WM2200_CPMIC_BYPASS_MODE_MASK 0x0020 /* CPMIC_BYPASS_MODE */
-#define WM2200_CPMIC_BYPASS_MODE_SHIFT 5 /* CPMIC_BYPASS_MODE */
-#define WM2200_CPMIC_BYPASS_MODE_WIDTH 1 /* CPMIC_BYPASS_MODE */
-#define WM2200_CPMIC_ENA 0x0001 /* CPMIC_ENA */
-#define WM2200_CPMIC_ENA_MASK 0x0001 /* CPMIC_ENA */
-#define WM2200_CPMIC_ENA_SHIFT 0 /* CPMIC_ENA */
-#define WM2200_CPMIC_ENA_WIDTH 1 /* CPMIC_ENA */
-
-/*
- * R513 (0x201) - Mic Charge Pump 2
- */
-#define WM2200_CPMIC_LDO_VSEL_OVERRIDE_MASK 0xF800 /* CPMIC_LDO_VSEL_OVERRIDE - [15:11] */
-#define WM2200_CPMIC_LDO_VSEL_OVERRIDE_SHIFT 11 /* CPMIC_LDO_VSEL_OVERRIDE - [15:11] */
-#define WM2200_CPMIC_LDO_VSEL_OVERRIDE_WIDTH 5 /* CPMIC_LDO_VSEL_OVERRIDE - [15:11] */
-
-/*
- * R514 (0x202) - DM Charge Pump 1
- */
-#define WM2200_CPDM_ENA 0x0001 /* CPDM_ENA */
-#define WM2200_CPDM_ENA_MASK 0x0001 /* CPDM_ENA */
-#define WM2200_CPDM_ENA_SHIFT 0 /* CPDM_ENA */
-#define WM2200_CPDM_ENA_WIDTH 1 /* CPDM_ENA */
-
-/*
- * R524 (0x20C) - Mic Bias Ctrl 1
- */
-#define WM2200_MICB1_DISCH 0x0040 /* MICB1_DISCH */
-#define WM2200_MICB1_DISCH_MASK 0x0040 /* MICB1_DISCH */
-#define WM2200_MICB1_DISCH_SHIFT 6 /* MICB1_DISCH */
-#define WM2200_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
-#define WM2200_MICB1_RATE 0x0020 /* MICB1_RATE */
-#define WM2200_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */
-#define WM2200_MICB1_RATE_SHIFT 5 /* MICB1_RATE */
-#define WM2200_MICB1_RATE_WIDTH 1 /* MICB1_RATE */
-#define WM2200_MICB1_LVL_MASK 0x001C /* MICB1_LVL - [4:2] */
-#define WM2200_MICB1_LVL_SHIFT 2 /* MICB1_LVL - [4:2] */
-#define WM2200_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [4:2] */
-#define WM2200_MICB1_MODE 0x0002 /* MICB1_MODE */
-#define WM2200_MICB1_MODE_MASK 0x0002 /* MICB1_MODE */
-#define WM2200_MICB1_MODE_SHIFT 1 /* MICB1_MODE */
-#define WM2200_MICB1_MODE_WIDTH 1 /* MICB1_MODE */
-#define WM2200_MICB1_ENA 0x0001 /* MICB1_ENA */
-#define WM2200_MICB1_ENA_MASK 0x0001 /* MICB1_ENA */
-#define WM2200_MICB1_ENA_SHIFT 0 /* MICB1_ENA */
-#define WM2200_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
-
-/*
- * R525 (0x20D) - Mic Bias Ctrl 2
- */
-#define WM2200_MICB2_DISCH 0x0040 /* MICB2_DISCH */
-#define WM2200_MICB2_DISCH_MASK 0x0040 /* MICB2_DISCH */
-#define WM2200_MICB2_DISCH_SHIFT 6 /* MICB2_DISCH */
-#define WM2200_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
-#define WM2200_MICB2_RATE 0x0020 /* MICB2_RATE */
-#define WM2200_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */
-#define WM2200_MICB2_RATE_SHIFT 5 /* MICB2_RATE */
-#define WM2200_MICB2_RATE_WIDTH 1 /* MICB2_RATE */
-#define WM2200_MICB2_LVL_MASK 0x001C /* MICB2_LVL - [4:2] */
-#define WM2200_MICB2_LVL_SHIFT 2 /* MICB2_LVL - [4:2] */
-#define WM2200_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [4:2] */
-#define WM2200_MICB2_MODE 0x0002 /* MICB2_MODE */
-#define WM2200_MICB2_MODE_MASK 0x0002 /* MICB2_MODE */
-#define WM2200_MICB2_MODE_SHIFT 1 /* MICB2_MODE */
-#define WM2200_MICB2_MODE_WIDTH 1 /* MICB2_MODE */
-#define WM2200_MICB2_ENA 0x0001 /* MICB2_ENA */
-#define WM2200_MICB2_ENA_MASK 0x0001 /* MICB2_ENA */
-#define WM2200_MICB2_ENA_SHIFT 0 /* MICB2_ENA */
-#define WM2200_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
-
-/*
- * R527 (0x20F) - Ear Piece Ctrl 1
- */
-#define WM2200_EPD_LP_ENA 0x4000 /* EPD_LP_ENA */
-#define WM2200_EPD_LP_ENA_MASK 0x4000 /* EPD_LP_ENA */
-#define WM2200_EPD_LP_ENA_SHIFT 14 /* EPD_LP_ENA */
-#define WM2200_EPD_LP_ENA_WIDTH 1 /* EPD_LP_ENA */
-#define WM2200_EPD_OUTP_LP_ENA 0x2000 /* EPD_OUTP_LP_ENA */
-#define WM2200_EPD_OUTP_LP_ENA_MASK 0x2000 /* EPD_OUTP_LP_ENA */
-#define WM2200_EPD_OUTP_LP_ENA_SHIFT 13 /* EPD_OUTP_LP_ENA */
-#define WM2200_EPD_OUTP_LP_ENA_WIDTH 1 /* EPD_OUTP_LP_ENA */
-#define WM2200_EPD_RMV_SHRT_LP 0x1000 /* EPD_RMV_SHRT_LP */
-#define WM2200_EPD_RMV_SHRT_LP_MASK 0x1000 /* EPD_RMV_SHRT_LP */
-#define WM2200_EPD_RMV_SHRT_LP_SHIFT 12 /* EPD_RMV_SHRT_LP */
-#define WM2200_EPD_RMV_SHRT_LP_WIDTH 1 /* EPD_RMV_SHRT_LP */
-#define WM2200_EPD_LN_ENA 0x0800 /* EPD_LN_ENA */
-#define WM2200_EPD_LN_ENA_MASK 0x0800 /* EPD_LN_ENA */
-#define WM2200_EPD_LN_ENA_SHIFT 11 /* EPD_LN_ENA */
-#define WM2200_EPD_LN_ENA_WIDTH 1 /* EPD_LN_ENA */
-#define WM2200_EPD_OUTP_LN_ENA 0x0400 /* EPD_OUTP_LN_ENA */
-#define WM2200_EPD_OUTP_LN_ENA_MASK 0x0400 /* EPD_OUTP_LN_ENA */
-#define WM2200_EPD_OUTP_LN_ENA_SHIFT 10 /* EPD_OUTP_LN_ENA */
-#define WM2200_EPD_OUTP_LN_ENA_WIDTH 1 /* EPD_OUTP_LN_ENA */
-#define WM2200_EPD_RMV_SHRT_LN 0x0200 /* EPD_RMV_SHRT_LN */
-#define WM2200_EPD_RMV_SHRT_LN_MASK 0x0200 /* EPD_RMV_SHRT_LN */
-#define WM2200_EPD_RMV_SHRT_LN_SHIFT 9 /* EPD_RMV_SHRT_LN */
-#define WM2200_EPD_RMV_SHRT_LN_WIDTH 1 /* EPD_RMV_SHRT_LN */
-
-/*
- * R528 (0x210) - Ear Piece Ctrl 2
- */
-#define WM2200_EPD_RP_ENA 0x4000 /* EPD_RP_ENA */
-#define WM2200_EPD_RP_ENA_MASK 0x4000 /* EPD_RP_ENA */
-#define WM2200_EPD_RP_ENA_SHIFT 14 /* EPD_RP_ENA */
-#define WM2200_EPD_RP_ENA_WIDTH 1 /* EPD_RP_ENA */
-#define WM2200_EPD_OUTP_RP_ENA 0x2000 /* EPD_OUTP_RP_ENA */
-#define WM2200_EPD_OUTP_RP_ENA_MASK 0x2000 /* EPD_OUTP_RP_ENA */
-#define WM2200_EPD_OUTP_RP_ENA_SHIFT 13 /* EPD_OUTP_RP_ENA */
-#define WM2200_EPD_OUTP_RP_ENA_WIDTH 1 /* EPD_OUTP_RP_ENA */
-#define WM2200_EPD_RMV_SHRT_RP 0x1000 /* EPD_RMV_SHRT_RP */
-#define WM2200_EPD_RMV_SHRT_RP_MASK 0x1000 /* EPD_RMV_SHRT_RP */
-#define WM2200_EPD_RMV_SHRT_RP_SHIFT 12 /* EPD_RMV_SHRT_RP */
-#define WM2200_EPD_RMV_SHRT_RP_WIDTH 1 /* EPD_RMV_SHRT_RP */
-#define WM2200_EPD_RN_ENA 0x0800 /* EPD_RN_ENA */
-#define WM2200_EPD_RN_ENA_MASK 0x0800 /* EPD_RN_ENA */
-#define WM2200_EPD_RN_ENA_SHIFT 11 /* EPD_RN_ENA */
-#define WM2200_EPD_RN_ENA_WIDTH 1 /* EPD_RN_ENA */
-#define WM2200_EPD_OUTP_RN_ENA 0x0400 /* EPD_OUTP_RN_ENA */
-#define WM2200_EPD_OUTP_RN_ENA_MASK 0x0400 /* EPD_OUTP_RN_ENA */
-#define WM2200_EPD_OUTP_RN_ENA_SHIFT 10 /* EPD_OUTP_RN_ENA */
-#define WM2200_EPD_OUTP_RN_ENA_WIDTH 1 /* EPD_OUTP_RN_ENA */
-#define WM2200_EPD_RMV_SHRT_RN 0x0200 /* EPD_RMV_SHRT_RN */
-#define WM2200_EPD_RMV_SHRT_RN_MASK 0x0200 /* EPD_RMV_SHRT_RN */
-#define WM2200_EPD_RMV_SHRT_RN_SHIFT 9 /* EPD_RMV_SHRT_RN */
-#define WM2200_EPD_RMV_SHRT_RN_WIDTH 1 /* EPD_RMV_SHRT_RN */
-
-/*
- * R769 (0x301) - Input Enables
- */
-#define WM2200_IN3L_ENA 0x0020 /* IN3L_ENA */
-#define WM2200_IN3L_ENA_MASK 0x0020 /* IN3L_ENA */
-#define WM2200_IN3L_ENA_SHIFT 5 /* IN3L_ENA */
-#define WM2200_IN3L_ENA_WIDTH 1 /* IN3L_ENA */
-#define WM2200_IN3R_ENA 0x0010 /* IN3R_ENA */
-#define WM2200_IN3R_ENA_MASK 0x0010 /* IN3R_ENA */
-#define WM2200_IN3R_ENA_SHIFT 4 /* IN3R_ENA */
-#define WM2200_IN3R_ENA_WIDTH 1 /* IN3R_ENA */
-#define WM2200_IN2L_ENA 0x0008 /* IN2L_ENA */
-#define WM2200_IN2L_ENA_MASK 0x0008 /* IN2L_ENA */
-#define WM2200_IN2L_ENA_SHIFT 3 /* IN2L_ENA */
-#define WM2200_IN2L_ENA_WIDTH 1 /* IN2L_ENA */
-#define WM2200_IN2R_ENA 0x0004 /* IN2R_ENA */
-#define WM2200_IN2R_ENA_MASK 0x0004 /* IN2R_ENA */
-#define WM2200_IN2R_ENA_SHIFT 2 /* IN2R_ENA */
-#define WM2200_IN2R_ENA_WIDTH 1 /* IN2R_ENA */
-#define WM2200_IN1L_ENA 0x0002 /* IN1L_ENA */
-#define WM2200_IN1L_ENA_MASK 0x0002 /* IN1L_ENA */
-#define WM2200_IN1L_ENA_SHIFT 1 /* IN1L_ENA */
-#define WM2200_IN1L_ENA_WIDTH 1 /* IN1L_ENA */
-#define WM2200_IN1R_ENA 0x0001 /* IN1R_ENA */
-#define WM2200_IN1R_ENA_MASK 0x0001 /* IN1R_ENA */
-#define WM2200_IN1R_ENA_SHIFT 0 /* IN1R_ENA */
-#define WM2200_IN1R_ENA_WIDTH 1 /* IN1R_ENA */
-
-/*
- * R770 (0x302) - IN1L Control
- */
-#define WM2200_IN1_OSR 0x2000 /* IN1_OSR */
-#define WM2200_IN1_OSR_MASK 0x2000 /* IN1_OSR */
-#define WM2200_IN1_OSR_SHIFT 13 /* IN1_OSR */
-#define WM2200_IN1_OSR_WIDTH 1 /* IN1_OSR */
-#define WM2200_IN1_DMIC_SUP_MASK 0x1800 /* IN1_DMIC_SUP - [12:11] */
-#define WM2200_IN1_DMIC_SUP_SHIFT 11 /* IN1_DMIC_SUP - [12:11] */
-#define WM2200_IN1_DMIC_SUP_WIDTH 2 /* IN1_DMIC_SUP - [12:11] */
-#define WM2200_IN1_MODE_MASK 0x0600 /* IN1_MODE - [10:9] */
-#define WM2200_IN1_MODE_SHIFT 9 /* IN1_MODE - [10:9] */
-#define WM2200_IN1_MODE_WIDTH 2 /* IN1_MODE - [10:9] */
-#define WM2200_IN1L_PGA_VOL_MASK 0x00FE /* IN1L_PGA_VOL - [7:1] */
-#define WM2200_IN1L_PGA_VOL_SHIFT 1 /* IN1L_PGA_VOL - [7:1] */
-#define WM2200_IN1L_PGA_VOL_WIDTH 7 /* IN1L_PGA_VOL - [7:1] */
-
-/*
- * R771 (0x303) - IN1R Control
- */
-#define WM2200_IN1R_PGA_VOL_MASK 0x00FE /* IN1R_PGA_VOL - [7:1] */
-#define WM2200_IN1R_PGA_VOL_SHIFT 1 /* IN1R_PGA_VOL - [7:1] */
-#define WM2200_IN1R_PGA_VOL_WIDTH 7 /* IN1R_PGA_VOL - [7:1] */
-
-/*
- * R772 (0x304) - IN2L Control
- */
-#define WM2200_IN2_OSR 0x2000 /* IN2_OSR */
-#define WM2200_IN2_OSR_MASK 0x2000 /* IN2_OSR */
-#define WM2200_IN2_OSR_SHIFT 13 /* IN2_OSR */
-#define WM2200_IN2_OSR_WIDTH 1 /* IN2_OSR */
-#define WM2200_IN2_DMIC_SUP_MASK 0x1800 /* IN2_DMIC_SUP - [12:11] */
-#define WM2200_IN2_DMIC_SUP_SHIFT 11 /* IN2_DMIC_SUP - [12:11] */
-#define WM2200_IN2_DMIC_SUP_WIDTH 2 /* IN2_DMIC_SUP - [12:11] */
-#define WM2200_IN2_MODE_MASK 0x0600 /* IN2_MODE - [10:9] */
-#define WM2200_IN2_MODE_SHIFT 9 /* IN2_MODE - [10:9] */
-#define WM2200_IN2_MODE_WIDTH 2 /* IN2_MODE - [10:9] */
-#define WM2200_IN2L_PGA_VOL_MASK 0x00FE /* IN2L_PGA_VOL - [7:1] */
-#define WM2200_IN2L_PGA_VOL_SHIFT 1 /* IN2L_PGA_VOL - [7:1] */
-#define WM2200_IN2L_PGA_VOL_WIDTH 7 /* IN2L_PGA_VOL - [7:1] */
-
-/*
- * R773 (0x305) - IN2R Control
- */
-#define WM2200_IN2R_PGA_VOL_MASK 0x00FE /* IN2R_PGA_VOL - [7:1] */
-#define WM2200_IN2R_PGA_VOL_SHIFT 1 /* IN2R_PGA_VOL - [7:1] */
-#define WM2200_IN2R_PGA_VOL_WIDTH 7 /* IN2R_PGA_VOL - [7:1] */
-
-/*
- * R774 (0x306) - IN3L Control
- */
-#define WM2200_IN3_OSR 0x2000 /* IN3_OSR */
-#define WM2200_IN3_OSR_MASK 0x2000 /* IN3_OSR */
-#define WM2200_IN3_OSR_SHIFT 13 /* IN3_OSR */
-#define WM2200_IN3_OSR_WIDTH 1 /* IN3_OSR */
-#define WM2200_IN3_DMIC_SUP_MASK 0x1800 /* IN3_DMIC_SUP - [12:11] */
-#define WM2200_IN3_DMIC_SUP_SHIFT 11 /* IN3_DMIC_SUP - [12:11] */
-#define WM2200_IN3_DMIC_SUP_WIDTH 2 /* IN3_DMIC_SUP - [12:11] */
-#define WM2200_IN3_MODE_MASK 0x0600 /* IN3_MODE - [10:9] */
-#define WM2200_IN3_MODE_SHIFT 9 /* IN3_MODE - [10:9] */
-#define WM2200_IN3_MODE_WIDTH 2 /* IN3_MODE - [10:9] */
-#define WM2200_IN3L_PGA_VOL_MASK 0x00FE /* IN3L_PGA_VOL - [7:1] */
-#define WM2200_IN3L_PGA_VOL_SHIFT 1 /* IN3L_PGA_VOL - [7:1] */
-#define WM2200_IN3L_PGA_VOL_WIDTH 7 /* IN3L_PGA_VOL - [7:1] */
-
-/*
- * R775 (0x307) - IN3R Control
- */
-#define WM2200_IN3R_PGA_VOL_MASK 0x00FE /* IN3R_PGA_VOL - [7:1] */
-#define WM2200_IN3R_PGA_VOL_SHIFT 1 /* IN3R_PGA_VOL - [7:1] */
-#define WM2200_IN3R_PGA_VOL_WIDTH 7 /* IN3R_PGA_VOL - [7:1] */
-
-/*
- * R778 (0x30A) - RXANC_SRC
- */
-#define WM2200_IN_RXANC_SEL_MASK 0x0007 /* IN_RXANC_SEL - [2:0] */
-#define WM2200_IN_RXANC_SEL_SHIFT 0 /* IN_RXANC_SEL - [2:0] */
-#define WM2200_IN_RXANC_SEL_WIDTH 3 /* IN_RXANC_SEL - [2:0] */
-
-/*
- * R779 (0x30B) - Input Volume Ramp
- */
-#define WM2200_IN_VD_RAMP_MASK 0x0070 /* IN_VD_RAMP - [6:4] */
-#define WM2200_IN_VD_RAMP_SHIFT 4 /* IN_VD_RAMP - [6:4] */
-#define WM2200_IN_VD_RAMP_WIDTH 3 /* IN_VD_RAMP - [6:4] */
-#define WM2200_IN_VI_RAMP_MASK 0x0007 /* IN_VI_RAMP - [2:0] */
-#define WM2200_IN_VI_RAMP_SHIFT 0 /* IN_VI_RAMP - [2:0] */
-#define WM2200_IN_VI_RAMP_WIDTH 3 /* IN_VI_RAMP - [2:0] */
-
-/*
- * R780 (0x30C) - ADC Digital Volume 1L
- */
-#define WM2200_IN_VU 0x0200 /* IN_VU */
-#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */
-#define WM2200_IN_VU_SHIFT 9 /* IN_VU */
-#define WM2200_IN_VU_WIDTH 1 /* IN_VU */
-#define WM2200_IN1L_MUTE 0x0100 /* IN1L_MUTE */
-#define WM2200_IN1L_MUTE_MASK 0x0100 /* IN1L_MUTE */
-#define WM2200_IN1L_MUTE_SHIFT 8 /* IN1L_MUTE */
-#define WM2200_IN1L_MUTE_WIDTH 1 /* IN1L_MUTE */
-#define WM2200_IN1L_DIG_VOL_MASK 0x00FF /* IN1L_DIG_VOL - [7:0] */
-#define WM2200_IN1L_DIG_VOL_SHIFT 0 /* IN1L_DIG_VOL - [7:0] */
-#define WM2200_IN1L_DIG_VOL_WIDTH 8 /* IN1L_DIG_VOL - [7:0] */
-
-/*
- * R781 (0x30D) - ADC Digital Volume 1R
- */
-#define WM2200_IN_VU 0x0200 /* IN_VU */
-#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */
-#define WM2200_IN_VU_SHIFT 9 /* IN_VU */
-#define WM2200_IN_VU_WIDTH 1 /* IN_VU */
-#define WM2200_IN1R_MUTE 0x0100 /* IN1R_MUTE */
-#define WM2200_IN1R_MUTE_MASK 0x0100 /* IN1R_MUTE */
-#define WM2200_IN1R_MUTE_SHIFT 8 /* IN1R_MUTE */
-#define WM2200_IN1R_MUTE_WIDTH 1 /* IN1R_MUTE */
-#define WM2200_IN1R_DIG_VOL_MASK 0x00FF /* IN1R_DIG_VOL - [7:0] */
-#define WM2200_IN1R_DIG_VOL_SHIFT 0 /* IN1R_DIG_VOL - [7:0] */
-#define WM2200_IN1R_DIG_VOL_WIDTH 8 /* IN1R_DIG_VOL - [7:0] */
-
-/*
- * R782 (0x30E) - ADC Digital Volume 2L
- */
-#define WM2200_IN_VU 0x0200 /* IN_VU */
-#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */
-#define WM2200_IN_VU_SHIFT 9 /* IN_VU */
-#define WM2200_IN_VU_WIDTH 1 /* IN_VU */
-#define WM2200_IN2L_MUTE 0x0100 /* IN2L_MUTE */
-#define WM2200_IN2L_MUTE_MASK 0x0100 /* IN2L_MUTE */
-#define WM2200_IN2L_MUTE_SHIFT 8 /* IN2L_MUTE */
-#define WM2200_IN2L_MUTE_WIDTH 1 /* IN2L_MUTE */
-#define WM2200_IN2L_DIG_VOL_MASK 0x00FF /* IN2L_DIG_VOL - [7:0] */
-#define WM2200_IN2L_DIG_VOL_SHIFT 0 /* IN2L_DIG_VOL - [7:0] */
-#define WM2200_IN2L_DIG_VOL_WIDTH 8 /* IN2L_DIG_VOL - [7:0] */
-
-/*
- * R783 (0x30F) - ADC Digital Volume 2R
- */
-#define WM2200_IN_VU 0x0200 /* IN_VU */
-#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */
-#define WM2200_IN_VU_SHIFT 9 /* IN_VU */
-#define WM2200_IN_VU_WIDTH 1 /* IN_VU */
-#define WM2200_IN2R_MUTE 0x0100 /* IN2R_MUTE */
-#define WM2200_IN2R_MUTE_MASK 0x0100 /* IN2R_MUTE */
-#define WM2200_IN2R_MUTE_SHIFT 8 /* IN2R_MUTE */
-#define WM2200_IN2R_MUTE_WIDTH 1 /* IN2R_MUTE */
-#define WM2200_IN2R_DIG_VOL_MASK 0x00FF /* IN2R_DIG_VOL - [7:0] */
-#define WM2200_IN2R_DIG_VOL_SHIFT 0 /* IN2R_DIG_VOL - [7:0] */
-#define WM2200_IN2R_DIG_VOL_WIDTH 8 /* IN2R_DIG_VOL - [7:0] */
-
-/*
- * R784 (0x310) - ADC Digital Volume 3L
- */
-#define WM2200_IN_VU 0x0200 /* IN_VU */
-#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */
-#define WM2200_IN_VU_SHIFT 9 /* IN_VU */
-#define WM2200_IN_VU_WIDTH 1 /* IN_VU */
-#define WM2200_IN3L_MUTE 0x0100 /* IN3L_MUTE */
-#define WM2200_IN3L_MUTE_MASK 0x0100 /* IN3L_MUTE */
-#define WM2200_IN3L_MUTE_SHIFT 8 /* IN3L_MUTE */
-#define WM2200_IN3L_MUTE_WIDTH 1 /* IN3L_MUTE */
-#define WM2200_IN3L_DIG_VOL_MASK 0x00FF /* IN3L_DIG_VOL - [7:0] */
-#define WM2200_IN3L_DIG_VOL_SHIFT 0 /* IN3L_DIG_VOL - [7:0] */
-#define WM2200_IN3L_DIG_VOL_WIDTH 8 /* IN3L_DIG_VOL - [7:0] */
-
-/*
- * R785 (0x311) - ADC Digital Volume 3R
- */
-#define WM2200_IN_VU 0x0200 /* IN_VU */
-#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */
-#define WM2200_IN_VU_SHIFT 9 /* IN_VU */
-#define WM2200_IN_VU_WIDTH 1 /* IN_VU */
-#define WM2200_IN3R_MUTE 0x0100 /* IN3R_MUTE */
-#define WM2200_IN3R_MUTE_MASK 0x0100 /* IN3R_MUTE */
-#define WM2200_IN3R_MUTE_SHIFT 8 /* IN3R_MUTE */
-#define WM2200_IN3R_MUTE_WIDTH 1 /* IN3R_MUTE */
-#define WM2200_IN3R_DIG_VOL_MASK 0x00FF /* IN3R_DIG_VOL - [7:0] */
-#define WM2200_IN3R_DIG_VOL_SHIFT 0 /* IN3R_DIG_VOL - [7:0] */
-#define WM2200_IN3R_DIG_VOL_WIDTH 8 /* IN3R_DIG_VOL - [7:0] */
-
-/*
- * R1024 (0x400) - Output Enables
- */
-#define WM2200_OUT2L_ENA 0x0008 /* OUT2L_ENA */
-#define WM2200_OUT2L_ENA_MASK 0x0008 /* OUT2L_ENA */
-#define WM2200_OUT2L_ENA_SHIFT 3 /* OUT2L_ENA */
-#define WM2200_OUT2L_ENA_WIDTH 1 /* OUT2L_ENA */
-#define WM2200_OUT2R_ENA 0x0004 /* OUT2R_ENA */
-#define WM2200_OUT2R_ENA_MASK 0x0004 /* OUT2R_ENA */
-#define WM2200_OUT2R_ENA_SHIFT 2 /* OUT2R_ENA */
-#define WM2200_OUT2R_ENA_WIDTH 1 /* OUT2R_ENA */
-#define WM2200_OUT1L_ENA 0x0002 /* OUT1L_ENA */
-#define WM2200_OUT1L_ENA_MASK 0x0002 /* OUT1L_ENA */
-#define WM2200_OUT1L_ENA_SHIFT 1 /* OUT1L_ENA */
-#define WM2200_OUT1L_ENA_WIDTH 1 /* OUT1L_ENA */
-#define WM2200_OUT1R_ENA 0x0001 /* OUT1R_ENA */
-#define WM2200_OUT1R_ENA_MASK 0x0001 /* OUT1R_ENA */
-#define WM2200_OUT1R_ENA_SHIFT 0 /* OUT1R_ENA */
-#define WM2200_OUT1R_ENA_WIDTH 1 /* OUT1R_ENA */
-
-/*
- * R1025 (0x401) - DAC Volume Limit 1L
- */
-#define WM2200_OUT1_OSR 0x2000 /* OUT1_OSR */
-#define WM2200_OUT1_OSR_MASK 0x2000 /* OUT1_OSR */
-#define WM2200_OUT1_OSR_SHIFT 13 /* OUT1_OSR */
-#define WM2200_OUT1_OSR_WIDTH 1 /* OUT1_OSR */
-#define WM2200_OUT1L_ANC_SRC 0x0800 /* OUT1L_ANC_SRC */
-#define WM2200_OUT1L_ANC_SRC_MASK 0x0800 /* OUT1L_ANC_SRC */
-#define WM2200_OUT1L_ANC_SRC_SHIFT 11 /* OUT1L_ANC_SRC */
-#define WM2200_OUT1L_ANC_SRC_WIDTH 1 /* OUT1L_ANC_SRC */
-#define WM2200_OUT1L_PGA_VOL_MASK 0x00FE /* OUT1L_PGA_VOL - [7:1] */
-#define WM2200_OUT1L_PGA_VOL_SHIFT 1 /* OUT1L_PGA_VOL - [7:1] */
-#define WM2200_OUT1L_PGA_VOL_WIDTH 7 /* OUT1L_PGA_VOL - [7:1] */
-
-/*
- * R1026 (0x402) - DAC Volume Limit 1R
- */
-#define WM2200_OUT1R_ANC_SRC 0x0800 /* OUT1R_ANC_SRC */
-#define WM2200_OUT1R_ANC_SRC_MASK 0x0800 /* OUT1R_ANC_SRC */
-#define WM2200_OUT1R_ANC_SRC_SHIFT 11 /* OUT1R_ANC_SRC */
-#define WM2200_OUT1R_ANC_SRC_WIDTH 1 /* OUT1R_ANC_SRC */
-#define WM2200_OUT1R_PGA_VOL_MASK 0x00FE /* OUT1R_PGA_VOL - [7:1] */
-#define WM2200_OUT1R_PGA_VOL_SHIFT 1 /* OUT1R_PGA_VOL - [7:1] */
-#define WM2200_OUT1R_PGA_VOL_WIDTH 7 /* OUT1R_PGA_VOL - [7:1] */
-
-/*
- * R1027 (0x403) - DAC Volume Limit 2L
- */
-#define WM2200_OUT2_OSR 0x2000 /* OUT2_OSR */
-#define WM2200_OUT2_OSR_MASK 0x2000 /* OUT2_OSR */
-#define WM2200_OUT2_OSR_SHIFT 13 /* OUT2_OSR */
-#define WM2200_OUT2_OSR_WIDTH 1 /* OUT2_OSR */
-#define WM2200_OUT2L_ANC_SRC 0x0800 /* OUT2L_ANC_SRC */
-#define WM2200_OUT2L_ANC_SRC_MASK 0x0800 /* OUT2L_ANC_SRC */
-#define WM2200_OUT2L_ANC_SRC_SHIFT 11 /* OUT2L_ANC_SRC */
-#define WM2200_OUT2L_ANC_SRC_WIDTH 1 /* OUT2L_ANC_SRC */
-
-/*
- * R1028 (0x404) - DAC Volume Limit 2R
- */
-#define WM2200_OUT2R_ANC_SRC 0x0800 /* OUT2R_ANC_SRC */
-#define WM2200_OUT2R_ANC_SRC_MASK 0x0800 /* OUT2R_ANC_SRC */
-#define WM2200_OUT2R_ANC_SRC_SHIFT 11 /* OUT2R_ANC_SRC */
-#define WM2200_OUT2R_ANC_SRC_WIDTH 1 /* OUT2R_ANC_SRC */
-
-/*
- * R1033 (0x409) - DAC AEC Control 1
- */
-#define WM2200_AEC_LOOPBACK_ENA 0x0004 /* AEC_LOOPBACK_ENA */
-#define WM2200_AEC_LOOPBACK_ENA_MASK 0x0004 /* AEC_LOOPBACK_ENA */
-#define WM2200_AEC_LOOPBACK_ENA_SHIFT 2 /* AEC_LOOPBACK_ENA */
-#define WM2200_AEC_LOOPBACK_ENA_WIDTH 1 /* AEC_LOOPBACK_ENA */
-#define WM2200_AEC_LOOPBACK_SRC_MASK 0x0003 /* AEC_LOOPBACK_SRC - [1:0] */
-#define WM2200_AEC_LOOPBACK_SRC_SHIFT 0 /* AEC_LOOPBACK_SRC - [1:0] */
-#define WM2200_AEC_LOOPBACK_SRC_WIDTH 2 /* AEC_LOOPBACK_SRC - [1:0] */
-
-/*
- * R1034 (0x40A) - Output Volume Ramp
- */
-#define WM2200_OUT_VD_RAMP_MASK 0x0070 /* OUT_VD_RAMP - [6:4] */
-#define WM2200_OUT_VD_RAMP_SHIFT 4 /* OUT_VD_RAMP - [6:4] */
-#define WM2200_OUT_VD_RAMP_WIDTH 3 /* OUT_VD_RAMP - [6:4] */
-#define WM2200_OUT_VI_RAMP_MASK 0x0007 /* OUT_VI_RAMP - [2:0] */
-#define WM2200_OUT_VI_RAMP_SHIFT 0 /* OUT_VI_RAMP - [2:0] */
-#define WM2200_OUT_VI_RAMP_WIDTH 3 /* OUT_VI_RAMP - [2:0] */
-
-/*
- * R1035 (0x40B) - DAC Digital Volume 1L
- */
-#define WM2200_OUT_VU 0x0200 /* OUT_VU */
-#define WM2200_OUT_VU_MASK 0x0200 /* OUT_VU */
-#define WM2200_OUT_VU_SHIFT 9 /* OUT_VU */
-#define WM2200_OUT_VU_WIDTH 1 /* OUT_VU */
-#define WM2200_OUT1L_MUTE 0x0100 /* OUT1L_MUTE */
-#define WM2200_OUT1L_MUTE_MASK 0x0100 /* OUT1L_MUTE */
-#define WM2200_OUT1L_MUTE_SHIFT 8 /* OUT1L_MUTE */
-#define WM2200_OUT1L_MUTE_WIDTH 1 /* OUT1L_MUTE */
-#define WM2200_OUT1L_VOL_MASK 0x00FF /* OUT1L_VOL - [7:0] */
-#define WM2200_OUT1L_VOL_SHIFT 0 /* OUT1L_VOL - [7:0] */
-#define WM2200_OUT1L_VOL_WIDTH 8 /* OUT1L_VOL - [7:0] */
-
-/*
- * R1036 (0x40C) - DAC Digital Volume 1R
- */
-#define WM2200_OUT_VU 0x0200 /* OUT_VU */
-#define WM2200_OUT_VU_MASK 0x0200 /* OUT_VU */
-#define WM2200_OUT_VU_SHIFT 9 /* OUT_VU */
-#define WM2200_OUT_VU_WIDTH 1 /* OUT_VU */
-#define WM2200_OUT1R_MUTE 0x0100 /* OUT1R_MUTE */
-#define WM2200_OUT1R_MUTE_MASK 0x0100 /* OUT1R_MUTE */
-#define WM2200_OUT1R_MUTE_SHIFT 8 /* OUT1R_MUTE */
-#define WM2200_OUT1R_MUTE_WIDTH 1 /* OUT1R_MUTE */
-#define WM2200_OUT1R_VOL_MASK 0x00FF /* OUT1R_VOL - [7:0] */
-#define WM2200_OUT1R_VOL_SHIFT 0 /* OUT1R_VOL - [7:0] */
-#define WM2200_OUT1R_VOL_WIDTH 8 /* OUT1R_VOL - [7:0] */
-
-/*
- * R1037 (0x40D) - DAC Digital Volume 2L
- */
-#define WM2200_OUT_VU 0x0200 /* OUT_VU */
-#define WM2200_OUT_VU_MASK 0x0200 /* OUT_VU */
-#define WM2200_OUT_VU_SHIFT 9 /* OUT_VU */
-#define WM2200_OUT_VU_WIDTH 1 /* OUT_VU */
-#define WM2200_OUT2L_MUTE 0x0100 /* OUT2L_MUTE */
-#define WM2200_OUT2L_MUTE_MASK 0x0100 /* OUT2L_MUTE */
-#define WM2200_OUT2L_MUTE_SHIFT 8 /* OUT2L_MUTE */
-#define WM2200_OUT2L_MUTE_WIDTH 1 /* OUT2L_MUTE */
-#define WM2200_OUT2L_VOL_MASK 0x00FF /* OUT2L_VOL - [7:0] */
-#define WM2200_OUT2L_VOL_SHIFT 0 /* OUT2L_VOL - [7:0] */
-#define WM2200_OUT2L_VOL_WIDTH 8 /* OUT2L_VOL - [7:0] */
-
-/*
- * R1038 (0x40E) - DAC Digital Volume 2R
- */
-#define WM2200_OUT_VU 0x0200 /* OUT_VU */
-#define WM2200_OUT_VU_MASK 0x0200 /* OUT_VU */
-#define WM2200_OUT_VU_SHIFT 9 /* OUT_VU */
-#define WM2200_OUT_VU_WIDTH 1 /* OUT_VU */
-#define WM2200_OUT2R_MUTE 0x0100 /* OUT2R_MUTE */
-#define WM2200_OUT2R_MUTE_MASK 0x0100 /* OUT2R_MUTE */
-#define WM2200_OUT2R_MUTE_SHIFT 8 /* OUT2R_MUTE */
-#define WM2200_OUT2R_MUTE_WIDTH 1 /* OUT2R_MUTE */
-#define WM2200_OUT2R_VOL_MASK 0x00FF /* OUT2R_VOL - [7:0] */
-#define WM2200_OUT2R_VOL_SHIFT 0 /* OUT2R_VOL - [7:0] */
-#define WM2200_OUT2R_VOL_WIDTH 8 /* OUT2R_VOL - [7:0] */
-
-/*
- * R1047 (0x417) - PDM 1
- */
-#define WM2200_SPK1R_MUTE 0x2000 /* SPK1R_MUTE */
-#define WM2200_SPK1R_MUTE_MASK 0x2000 /* SPK1R_MUTE */
-#define WM2200_SPK1R_MUTE_SHIFT 13 /* SPK1R_MUTE */
-#define WM2200_SPK1R_MUTE_WIDTH 1 /* SPK1R_MUTE */
-#define WM2200_SPK1L_MUTE 0x1000 /* SPK1L_MUTE */
-#define WM2200_SPK1L_MUTE_MASK 0x1000 /* SPK1L_MUTE */
-#define WM2200_SPK1L_MUTE_SHIFT 12 /* SPK1L_MUTE */
-#define WM2200_SPK1L_MUTE_WIDTH 1 /* SPK1L_MUTE */
-#define WM2200_SPK1_MUTE_ENDIAN 0x0100 /* SPK1_MUTE_ENDIAN */
-#define WM2200_SPK1_MUTE_ENDIAN_MASK 0x0100 /* SPK1_MUTE_ENDIAN */
-#define WM2200_SPK1_MUTE_ENDIAN_SHIFT 8 /* SPK1_MUTE_ENDIAN */
-#define WM2200_SPK1_MUTE_ENDIAN_WIDTH 1 /* SPK1_MUTE_ENDIAN */
-#define WM2200_SPK1_MUTE_SEQL_MASK 0x00FF /* SPK1_MUTE_SEQL - [7:0] */
-#define WM2200_SPK1_MUTE_SEQL_SHIFT 0 /* SPK1_MUTE_SEQL - [7:0] */
-#define WM2200_SPK1_MUTE_SEQL_WIDTH 8 /* SPK1_MUTE_SEQL - [7:0] */
-
-/*
- * R1048 (0x418) - PDM 2
- */
-#define WM2200_SPK1_FMT 0x0001 /* SPK1_FMT */
-#define WM2200_SPK1_FMT_MASK 0x0001 /* SPK1_FMT */
-#define WM2200_SPK1_FMT_SHIFT 0 /* SPK1_FMT */
-#define WM2200_SPK1_FMT_WIDTH 1 /* SPK1_FMT */
-
-/*
- * R1280 (0x500) - Audio IF 1_1
- */
-#define WM2200_AIF1_BCLK_INV 0x0040 /* AIF1_BCLK_INV */
-#define WM2200_AIF1_BCLK_INV_MASK 0x0040 /* AIF1_BCLK_INV */
-#define WM2200_AIF1_BCLK_INV_SHIFT 6 /* AIF1_BCLK_INV */
-#define WM2200_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */
-#define WM2200_AIF1_BCLK_FRC 0x0020 /* AIF1_BCLK_FRC */
-#define WM2200_AIF1_BCLK_FRC_MASK 0x0020 /* AIF1_BCLK_FRC */
-#define WM2200_AIF1_BCLK_FRC_SHIFT 5 /* AIF1_BCLK_FRC */
-#define WM2200_AIF1_BCLK_FRC_WIDTH 1 /* AIF1_BCLK_FRC */
-#define WM2200_AIF1_BCLK_MSTR 0x0010 /* AIF1_BCLK_MSTR */
-#define WM2200_AIF1_BCLK_MSTR_MASK 0x0010 /* AIF1_BCLK_MSTR */
-#define WM2200_AIF1_BCLK_MSTR_SHIFT 4 /* AIF1_BCLK_MSTR */
-#define WM2200_AIF1_BCLK_MSTR_WIDTH 1 /* AIF1_BCLK_MSTR */
-#define WM2200_AIF1_BCLK_DIV_MASK 0x000F /* AIF1_BCLK_DIV - [3:0] */
-#define WM2200_AIF1_BCLK_DIV_SHIFT 0 /* AIF1_BCLK_DIV - [3:0] */
-#define WM2200_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [3:0] */
-
-/*
- * R1281 (0x501) - Audio IF 1_2
- */
-#define WM2200_AIF1TX_DAT_TRI 0x0020 /* AIF1TX_DAT_TRI */
-#define WM2200_AIF1TX_DAT_TRI_MASK 0x0020 /* AIF1TX_DAT_TRI */
-#define WM2200_AIF1TX_DAT_TRI_SHIFT 5 /* AIF1TX_DAT_TRI */
-#define WM2200_AIF1TX_DAT_TRI_WIDTH 1 /* AIF1TX_DAT_TRI */
-#define WM2200_AIF1TX_LRCLK_SRC 0x0008 /* AIF1TX_LRCLK_SRC */
-#define WM2200_AIF1TX_LRCLK_SRC_MASK 0x0008 /* AIF1TX_LRCLK_SRC */
-#define WM2200_AIF1TX_LRCLK_SRC_SHIFT 3 /* AIF1TX_LRCLK_SRC */
-#define WM2200_AIF1TX_LRCLK_SRC_WIDTH 1 /* AIF1TX_LRCLK_SRC */
-#define WM2200_AIF1TX_LRCLK_INV 0x0004 /* AIF1TX_LRCLK_INV */
-#define WM2200_AIF1TX_LRCLK_INV_MASK 0x0004 /* AIF1TX_LRCLK_INV */
-#define WM2200_AIF1TX_LRCLK_INV_SHIFT 2 /* AIF1TX_LRCLK_INV */
-#define WM2200_AIF1TX_LRCLK_INV_WIDTH 1 /* AIF1TX_LRCLK_INV */
-#define WM2200_AIF1TX_LRCLK_FRC 0x0002 /* AIF1TX_LRCLK_FRC */
-#define WM2200_AIF1TX_LRCLK_FRC_MASK 0x0002 /* AIF1TX_LRCLK_FRC */
-#define WM2200_AIF1TX_LRCLK_FRC_SHIFT 1 /* AIF1TX_LRCLK_FRC */
-#define WM2200_AIF1TX_LRCLK_FRC_WIDTH 1 /* AIF1TX_LRCLK_FRC */
-#define WM2200_AIF1TX_LRCLK_MSTR 0x0001 /* AIF1TX_LRCLK_MSTR */
-#define WM2200_AIF1TX_LRCLK_MSTR_MASK 0x0001 /* AIF1TX_LRCLK_MSTR */
-#define WM2200_AIF1TX_LRCLK_MSTR_SHIFT 0 /* AIF1TX_LRCLK_MSTR */
-#define WM2200_AIF1TX_LRCLK_MSTR_WIDTH 1 /* AIF1TX_LRCLK_MSTR */
-
-/*
- * R1282 (0x502) - Audio IF 1_3
- */
-#define WM2200_AIF1RX_LRCLK_INV 0x0004 /* AIF1RX_LRCLK_INV */
-#define WM2200_AIF1RX_LRCLK_INV_MASK 0x0004 /* AIF1RX_LRCLK_INV */
-#define WM2200_AIF1RX_LRCLK_INV_SHIFT 2 /* AIF1RX_LRCLK_INV */
-#define WM2200_AIF1RX_LRCLK_INV_WIDTH 1 /* AIF1RX_LRCLK_INV */
-#define WM2200_AIF1RX_LRCLK_FRC 0x0002 /* AIF1RX_LRCLK_FRC */
-#define WM2200_AIF1RX_LRCLK_FRC_MASK 0x0002 /* AIF1RX_LRCLK_FRC */
-#define WM2200_AIF1RX_LRCLK_FRC_SHIFT 1 /* AIF1RX_LRCLK_FRC */
-#define WM2200_AIF1RX_LRCLK_FRC_WIDTH 1 /* AIF1RX_LRCLK_FRC */
-#define WM2200_AIF1RX_LRCLK_MSTR 0x0001 /* AIF1RX_LRCLK_MSTR */
-#define WM2200_AIF1RX_LRCLK_MSTR_MASK 0x0001 /* AIF1RX_LRCLK_MSTR */
-#define WM2200_AIF1RX_LRCLK_MSTR_SHIFT 0 /* AIF1RX_LRCLK_MSTR */
-#define WM2200_AIF1RX_LRCLK_MSTR_WIDTH 1 /* AIF1RX_LRCLK_MSTR */
-
-/*
- * R1283 (0x503) - Audio IF 1_4
- */
-#define WM2200_AIF1_TRI 0x0040 /* AIF1_TRI */
-#define WM2200_AIF1_TRI_MASK 0x0040 /* AIF1_TRI */
-#define WM2200_AIF1_TRI_SHIFT 6 /* AIF1_TRI */
-#define WM2200_AIF1_TRI_WIDTH 1 /* AIF1_TRI */
-
-/*
- * R1284 (0x504) - Audio IF 1_5
- */
-#define WM2200_AIF1_FMT_MASK 0x0007 /* AIF1_FMT - [2:0] */
-#define WM2200_AIF1_FMT_SHIFT 0 /* AIF1_FMT - [2:0] */
-#define WM2200_AIF1_FMT_WIDTH 3 /* AIF1_FMT - [2:0] */
-
-/*
- * R1285 (0x505) - Audio IF 1_6
- */
-#define WM2200_AIF1TX_BCPF_MASK 0x07FF /* AIF1TX_BCPF - [10:0] */
-#define WM2200_AIF1TX_BCPF_SHIFT 0 /* AIF1TX_BCPF - [10:0] */
-#define WM2200_AIF1TX_BCPF_WIDTH 11 /* AIF1TX_BCPF - [10:0] */
-
-/*
- * R1286 (0x506) - Audio IF 1_7
- */
-#define WM2200_AIF1RX_BCPF_MASK 0x07FF /* AIF1RX_BCPF - [10:0] */
-#define WM2200_AIF1RX_BCPF_SHIFT 0 /* AIF1RX_BCPF - [10:0] */
-#define WM2200_AIF1RX_BCPF_WIDTH 11 /* AIF1RX_BCPF - [10:0] */
-
-/*
- * R1287 (0x507) - Audio IF 1_8
- */
-#define WM2200_AIF1TX_WL_MASK 0x3F00 /* AIF1TX_WL - [13:8] */
-#define WM2200_AIF1TX_WL_SHIFT 8 /* AIF1TX_WL - [13:8] */
-#define WM2200_AIF1TX_WL_WIDTH 6 /* AIF1TX_WL - [13:8] */
-#define WM2200_AIF1TX_SLOT_LEN_MASK 0x00FF /* AIF1TX_SLOT_LEN - [7:0] */
-#define WM2200_AIF1TX_SLOT_LEN_SHIFT 0 /* AIF1TX_SLOT_LEN - [7:0] */
-#define WM2200_AIF1TX_SLOT_LEN_WIDTH 8 /* AIF1TX_SLOT_LEN - [7:0] */
-
-/*
- * R1288 (0x508) - Audio IF 1_9
- */
-#define WM2200_AIF1RX_WL_MASK 0x3F00 /* AIF1RX_WL - [13:8] */
-#define WM2200_AIF1RX_WL_SHIFT 8 /* AIF1RX_WL - [13:8] */
-#define WM2200_AIF1RX_WL_WIDTH 6 /* AIF1RX_WL - [13:8] */
-#define WM2200_AIF1RX_SLOT_LEN_MASK 0x00FF /* AIF1RX_SLOT_LEN - [7:0] */
-#define WM2200_AIF1RX_SLOT_LEN_SHIFT 0 /* AIF1RX_SLOT_LEN - [7:0] */
-#define WM2200_AIF1RX_SLOT_LEN_WIDTH 8 /* AIF1RX_SLOT_LEN - [7:0] */
-
-/*
- * R1289 (0x509) - Audio IF 1_10
- */
-#define WM2200_AIF1TX1_SLOT_MASK 0x003F /* AIF1TX1_SLOT - [5:0] */
-#define WM2200_AIF1TX1_SLOT_SHIFT 0 /* AIF1TX1_SLOT - [5:0] */
-#define WM2200_AIF1TX1_SLOT_WIDTH 6 /* AIF1TX1_SLOT - [5:0] */
-
-/*
- * R1290 (0x50A) - Audio IF 1_11
- */
-#define WM2200_AIF1TX2_SLOT_MASK 0x003F /* AIF1TX2_SLOT - [5:0] */
-#define WM2200_AIF1TX2_SLOT_SHIFT 0 /* AIF1TX2_SLOT - [5:0] */
-#define WM2200_AIF1TX2_SLOT_WIDTH 6 /* AIF1TX2_SLOT - [5:0] */
-
-/*
- * R1291 (0x50B) - Audio IF 1_12
- */
-#define WM2200_AIF1TX3_SLOT_MASK 0x003F /* AIF1TX3_SLOT - [5:0] */
-#define WM2200_AIF1TX3_SLOT_SHIFT 0 /* AIF1TX3_SLOT - [5:0] */
-#define WM2200_AIF1TX3_SLOT_WIDTH 6 /* AIF1TX3_SLOT - [5:0] */
-
-/*
- * R1292 (0x50C) - Audio IF 1_13
- */
-#define WM2200_AIF1TX4_SLOT_MASK 0x003F /* AIF1TX4_SLOT - [5:0] */
-#define WM2200_AIF1TX4_SLOT_SHIFT 0 /* AIF1TX4_SLOT - [5:0] */
-#define WM2200_AIF1TX4_SLOT_WIDTH 6 /* AIF1TX4_SLOT - [5:0] */
-
-/*
- * R1293 (0x50D) - Audio IF 1_14
- */
-#define WM2200_AIF1TX5_SLOT_MASK 0x003F /* AIF1TX5_SLOT - [5:0] */
-#define WM2200_AIF1TX5_SLOT_SHIFT 0 /* AIF1TX5_SLOT - [5:0] */
-#define WM2200_AIF1TX5_SLOT_WIDTH 6 /* AIF1TX5_SLOT - [5:0] */
-
-/*
- * R1294 (0x50E) - Audio IF 1_15
- */
-#define WM2200_AIF1TX6_SLOT_MASK 0x003F /* AIF1TX6_SLOT - [5:0] */
-#define WM2200_AIF1TX6_SLOT_SHIFT 0 /* AIF1TX6_SLOT - [5:0] */
-#define WM2200_AIF1TX6_SLOT_WIDTH 6 /* AIF1TX6_SLOT - [5:0] */
-
-/*
- * R1295 (0x50F) - Audio IF 1_16
- */
-#define WM2200_AIF1RX1_SLOT_MASK 0x003F /* AIF1RX1_SLOT - [5:0] */
-#define WM2200_AIF1RX1_SLOT_SHIFT 0 /* AIF1RX1_SLOT - [5:0] */
-#define WM2200_AIF1RX1_SLOT_WIDTH 6 /* AIF1RX1_SLOT - [5:0] */
-
-/*
- * R1296 (0x510) - Audio IF 1_17
- */
-#define WM2200_AIF1RX2_SLOT_MASK 0x003F /* AIF1RX2_SLOT - [5:0] */
-#define WM2200_AIF1RX2_SLOT_SHIFT 0 /* AIF1RX2_SLOT - [5:0] */
-#define WM2200_AIF1RX2_SLOT_WIDTH 6 /* AIF1RX2_SLOT - [5:0] */
-
-/*
- * R1297 (0x511) - Audio IF 1_18
- */
-#define WM2200_AIF1RX3_SLOT_MASK 0x003F /* AIF1RX3_SLOT - [5:0] */
-#define WM2200_AIF1RX3_SLOT_SHIFT 0 /* AIF1RX3_SLOT - [5:0] */
-#define WM2200_AIF1RX3_SLOT_WIDTH 6 /* AIF1RX3_SLOT - [5:0] */
-
-/*
- * R1298 (0x512) - Audio IF 1_19
- */
-#define WM2200_AIF1RX4_SLOT_MASK 0x003F /* AIF1RX4_SLOT - [5:0] */
-#define WM2200_AIF1RX4_SLOT_SHIFT 0 /* AIF1RX4_SLOT - [5:0] */
-#define WM2200_AIF1RX4_SLOT_WIDTH 6 /* AIF1RX4_SLOT - [5:0] */
-
-/*
- * R1299 (0x513) - Audio IF 1_20
- */
-#define WM2200_AIF1RX5_SLOT_MASK 0x003F /* AIF1RX5_SLOT - [5:0] */
-#define WM2200_AIF1RX5_SLOT_SHIFT 0 /* AIF1RX5_SLOT - [5:0] */
-#define WM2200_AIF1RX5_SLOT_WIDTH 6 /* AIF1RX5_SLOT - [5:0] */
-
-/*
- * R1300 (0x514) - Audio IF 1_21
- */
-#define WM2200_AIF1RX6_SLOT_MASK 0x003F /* AIF1RX6_SLOT - [5:0] */
-#define WM2200_AIF1RX6_SLOT_SHIFT 0 /* AIF1RX6_SLOT - [5:0] */
-#define WM2200_AIF1RX6_SLOT_WIDTH 6 /* AIF1RX6_SLOT - [5:0] */
-
-/*
- * R1301 (0x515) - Audio IF 1_22
- */
-#define WM2200_AIF1RX6_ENA 0x0800 /* AIF1RX6_ENA */
-#define WM2200_AIF1RX6_ENA_MASK 0x0800 /* AIF1RX6_ENA */
-#define WM2200_AIF1RX6_ENA_SHIFT 11 /* AIF1RX6_ENA */
-#define WM2200_AIF1RX6_ENA_WIDTH 1 /* AIF1RX6_ENA */
-#define WM2200_AIF1RX5_ENA 0x0400 /* AIF1RX5_ENA */
-#define WM2200_AIF1RX5_ENA_MASK 0x0400 /* AIF1RX5_ENA */
-#define WM2200_AIF1RX5_ENA_SHIFT 10 /* AIF1RX5_ENA */
-#define WM2200_AIF1RX5_ENA_WIDTH 1 /* AIF1RX5_ENA */
-#define WM2200_AIF1RX4_ENA 0x0200 /* AIF1RX4_ENA */
-#define WM2200_AIF1RX4_ENA_MASK 0x0200 /* AIF1RX4_ENA */
-#define WM2200_AIF1RX4_ENA_SHIFT 9 /* AIF1RX4_ENA */
-#define WM2200_AIF1RX4_ENA_WIDTH 1 /* AIF1RX4_ENA */
-#define WM2200_AIF1RX3_ENA 0x0100 /* AIF1RX3_ENA */
-#define WM2200_AIF1RX3_ENA_MASK 0x0100 /* AIF1RX3_ENA */
-#define WM2200_AIF1RX3_ENA_SHIFT 8 /* AIF1RX3_ENA */
-#define WM2200_AIF1RX3_ENA_WIDTH 1 /* AIF1RX3_ENA */
-#define WM2200_AIF1RX2_ENA 0x0080 /* AIF1RX2_ENA */
-#define WM2200_AIF1RX2_ENA_MASK 0x0080 /* AIF1RX2_ENA */
-#define WM2200_AIF1RX2_ENA_SHIFT 7 /* AIF1RX2_ENA */
-#define WM2200_AIF1RX2_ENA_WIDTH 1 /* AIF1RX2_ENA */
-#define WM2200_AIF1RX1_ENA 0x0040 /* AIF1RX1_ENA */
-#define WM2200_AIF1RX1_ENA_MASK 0x0040 /* AIF1RX1_ENA */
-#define WM2200_AIF1RX1_ENA_SHIFT 6 /* AIF1RX1_ENA */
-#define WM2200_AIF1RX1_ENA_WIDTH 1 /* AIF1RX1_ENA */
-#define WM2200_AIF1TX6_ENA 0x0020 /* AIF1TX6_ENA */
-#define WM2200_AIF1TX6_ENA_MASK 0x0020 /* AIF1TX6_ENA */
-#define WM2200_AIF1TX6_ENA_SHIFT 5 /* AIF1TX6_ENA */
-#define WM2200_AIF1TX6_ENA_WIDTH 1 /* AIF1TX6_ENA */
-#define WM2200_AIF1TX5_ENA 0x0010 /* AIF1TX5_ENA */
-#define WM2200_AIF1TX5_ENA_MASK 0x0010 /* AIF1TX5_ENA */
-#define WM2200_AIF1TX5_ENA_SHIFT 4 /* AIF1TX5_ENA */
-#define WM2200_AIF1TX5_ENA_WIDTH 1 /* AIF1TX5_ENA */
-#define WM2200_AIF1TX4_ENA 0x0008 /* AIF1TX4_ENA */
-#define WM2200_AIF1TX4_ENA_MASK 0x0008 /* AIF1TX4_ENA */
-#define WM2200_AIF1TX4_ENA_SHIFT 3 /* AIF1TX4_ENA */
-#define WM2200_AIF1TX4_ENA_WIDTH 1 /* AIF1TX4_ENA */
-#define WM2200_AIF1TX3_ENA 0x0004 /* AIF1TX3_ENA */
-#define WM2200_AIF1TX3_ENA_MASK 0x0004 /* AIF1TX3_ENA */
-#define WM2200_AIF1TX3_ENA_SHIFT 2 /* AIF1TX3_ENA */
-#define WM2200_AIF1TX3_ENA_WIDTH 1 /* AIF1TX3_ENA */
-#define WM2200_AIF1TX2_ENA 0x0002 /* AIF1TX2_ENA */
-#define WM2200_AIF1TX2_ENA_MASK 0x0002 /* AIF1TX2_ENA */
-#define WM2200_AIF1TX2_ENA_SHIFT 1 /* AIF1TX2_ENA */
-#define WM2200_AIF1TX2_ENA_WIDTH 1 /* AIF1TX2_ENA */
-#define WM2200_AIF1TX1_ENA 0x0001 /* AIF1TX1_ENA */
-#define WM2200_AIF1TX1_ENA_MASK 0x0001 /* AIF1TX1_ENA */
-#define WM2200_AIF1TX1_ENA_SHIFT 0 /* AIF1TX1_ENA */
-#define WM2200_AIF1TX1_ENA_WIDTH 1 /* AIF1TX1_ENA */
-
-/*
- * R1536 (0x600) - OUT1LMIX Input 1 Source
- */
-#define WM2200_OUT1LMIX_SRC1_MASK 0x007F /* OUT1LMIX_SRC1 - [6:0] */
-#define WM2200_OUT1LMIX_SRC1_SHIFT 0 /* OUT1LMIX_SRC1 - [6:0] */
-#define WM2200_OUT1LMIX_SRC1_WIDTH 7 /* OUT1LMIX_SRC1 - [6:0] */
-
-/*
- * R1537 (0x601) - OUT1LMIX Input 1 Volume
- */
-#define WM2200_OUT1LMIX_VOL1_MASK 0x00FE /* OUT1LMIX_VOL1 - [7:1] */
-#define WM2200_OUT1LMIX_VOL1_SHIFT 1 /* OUT1LMIX_VOL1 - [7:1] */
-#define WM2200_OUT1LMIX_VOL1_WIDTH 7 /* OUT1LMIX_VOL1 - [7:1] */
-
-/*
- * R1538 (0x602) - OUT1LMIX Input 2 Source
- */
-#define WM2200_OUT1LMIX_SRC2_MASK 0x007F /* OUT1LMIX_SRC2 - [6:0] */
-#define WM2200_OUT1LMIX_SRC2_SHIFT 0 /* OUT1LMIX_SRC2 - [6:0] */
-#define WM2200_OUT1LMIX_SRC2_WIDTH 7 /* OUT1LMIX_SRC2 - [6:0] */
-
-/*
- * R1539 (0x603) - OUT1LMIX Input 2 Volume
- */
-#define WM2200_OUT1LMIX_VOL2_MASK 0x00FE /* OUT1LMIX_VOL2 - [7:1] */
-#define WM2200_OUT1LMIX_VOL2_SHIFT 1 /* OUT1LMIX_VOL2 - [7:1] */
-#define WM2200_OUT1LMIX_VOL2_WIDTH 7 /* OUT1LMIX_VOL2 - [7:1] */
-
-/*
- * R1540 (0x604) - OUT1LMIX Input 3 Source
- */
-#define WM2200_OUT1LMIX_SRC3_MASK 0x007F /* OUT1LMIX_SRC3 - [6:0] */
-#define WM2200_OUT1LMIX_SRC3_SHIFT 0 /* OUT1LMIX_SRC3 - [6:0] */
-#define WM2200_OUT1LMIX_SRC3_WIDTH 7 /* OUT1LMIX_SRC3 - [6:0] */
-
-/*
- * R1541 (0x605) - OUT1LMIX Input 3 Volume
- */
-#define WM2200_OUT1LMIX_VOL3_MASK 0x00FE /* OUT1LMIX_VOL3 - [7:1] */
-#define WM2200_OUT1LMIX_VOL3_SHIFT 1 /* OUT1LMIX_VOL3 - [7:1] */
-#define WM2200_OUT1LMIX_VOL3_WIDTH 7 /* OUT1LMIX_VOL3 - [7:1] */
-
-/*
- * R1542 (0x606) - OUT1LMIX Input 4 Source
- */
-#define WM2200_OUT1LMIX_SRC4_MASK 0x007F /* OUT1LMIX_SRC4 - [6:0] */
-#define WM2200_OUT1LMIX_SRC4_SHIFT 0 /* OUT1LMIX_SRC4 - [6:0] */
-#define WM2200_OUT1LMIX_SRC4_WIDTH 7 /* OUT1LMIX_SRC4 - [6:0] */
-
-/*
- * R1543 (0x607) - OUT1LMIX Input 4 Volume
- */
-#define WM2200_OUT1LMIX_VOL4_MASK 0x00FE /* OUT1LMIX_VOL4 - [7:1] */
-#define WM2200_OUT1LMIX_VOL4_SHIFT 1 /* OUT1LMIX_VOL4 - [7:1] */
-#define WM2200_OUT1LMIX_VOL4_WIDTH 7 /* OUT1LMIX_VOL4 - [7:1] */
-
-/*
- * R1544 (0x608) - OUT1RMIX Input 1 Source
- */
-#define WM2200_OUT1RMIX_SRC1_MASK 0x007F /* OUT1RMIX_SRC1 - [6:0] */
-#define WM2200_OUT1RMIX_SRC1_SHIFT 0 /* OUT1RMIX_SRC1 - [6:0] */
-#define WM2200_OUT1RMIX_SRC1_WIDTH 7 /* OUT1RMIX_SRC1 - [6:0] */
-
-/*
- * R1545 (0x609) - OUT1RMIX Input 1 Volume
- */
-#define WM2200_OUT1RMIX_VOL1_MASK 0x00FE /* OUT1RMIX_VOL1 - [7:1] */
-#define WM2200_OUT1RMIX_VOL1_SHIFT 1 /* OUT1RMIX_VOL1 - [7:1] */
-#define WM2200_OUT1RMIX_VOL1_WIDTH 7 /* OUT1RMIX_VOL1 - [7:1] */
-
-/*
- * R1546 (0x60A) - OUT1RMIX Input 2 Source
- */
-#define WM2200_OUT1RMIX_SRC2_MASK 0x007F /* OUT1RMIX_SRC2 - [6:0] */
-#define WM2200_OUT1RMIX_SRC2_SHIFT 0 /* OUT1RMIX_SRC2 - [6:0] */
-#define WM2200_OUT1RMIX_SRC2_WIDTH 7 /* OUT1RMIX_SRC2 - [6:0] */
-
-/*
- * R1547 (0x60B) - OUT1RMIX Input 2 Volume
- */
-#define WM2200_OUT1RMIX_VOL2_MASK 0x00FE /* OUT1RMIX_VOL2 - [7:1] */
-#define WM2200_OUT1RMIX_VOL2_SHIFT 1 /* OUT1RMIX_VOL2 - [7:1] */
-#define WM2200_OUT1RMIX_VOL2_WIDTH 7 /* OUT1RMIX_VOL2 - [7:1] */
-
-/*
- * R1548 (0x60C) - OUT1RMIX Input 3 Source
- */
-#define WM2200_OUT1RMIX_SRC3_MASK 0x007F /* OUT1RMIX_SRC3 - [6:0] */
-#define WM2200_OUT1RMIX_SRC3_SHIFT 0 /* OUT1RMIX_SRC3 - [6:0] */
-#define WM2200_OUT1RMIX_SRC3_WIDTH 7 /* OUT1RMIX_SRC3 - [6:0] */
-
-/*
- * R1549 (0x60D) - OUT1RMIX Input 3 Volume
- */
-#define WM2200_OUT1RMIX_VOL3_MASK 0x00FE /* OUT1RMIX_VOL3 - [7:1] */
-#define WM2200_OUT1RMIX_VOL3_SHIFT 1 /* OUT1RMIX_VOL3 - [7:1] */
-#define WM2200_OUT1RMIX_VOL3_WIDTH 7 /* OUT1RMIX_VOL3 - [7:1] */
-
-/*
- * R1550 (0x60E) - OUT1RMIX Input 4 Source
- */
-#define WM2200_OUT1RMIX_SRC4_MASK 0x007F /* OUT1RMIX_SRC4 - [6:0] */
-#define WM2200_OUT1RMIX_SRC4_SHIFT 0 /* OUT1RMIX_SRC4 - [6:0] */
-#define WM2200_OUT1RMIX_SRC4_WIDTH 7 /* OUT1RMIX_SRC4 - [6:0] */
-
-/*
- * R1551 (0x60F) - OUT1RMIX Input 4 Volume
- */
-#define WM2200_OUT1RMIX_VOL4_MASK 0x00FE /* OUT1RMIX_VOL4 - [7:1] */
-#define WM2200_OUT1RMIX_VOL4_SHIFT 1 /* OUT1RMIX_VOL4 - [7:1] */
-#define WM2200_OUT1RMIX_VOL4_WIDTH 7 /* OUT1RMIX_VOL4 - [7:1] */
-
-/*
- * R1552 (0x610) - OUT2LMIX Input 1 Source
- */
-#define WM2200_OUT2LMIX_SRC1_MASK 0x007F /* OUT2LMIX_SRC1 - [6:0] */
-#define WM2200_OUT2LMIX_SRC1_SHIFT 0 /* OUT2LMIX_SRC1 - [6:0] */
-#define WM2200_OUT2LMIX_SRC1_WIDTH 7 /* OUT2LMIX_SRC1 - [6:0] */
-
-/*
- * R1553 (0x611) - OUT2LMIX Input 1 Volume
- */
-#define WM2200_OUT2LMIX_VOL1_MASK 0x00FE /* OUT2LMIX_VOL1 - [7:1] */
-#define WM2200_OUT2LMIX_VOL1_SHIFT 1 /* OUT2LMIX_VOL1 - [7:1] */
-#define WM2200_OUT2LMIX_VOL1_WIDTH 7 /* OUT2LMIX_VOL1 - [7:1] */
-
-/*
- * R1554 (0x612) - OUT2LMIX Input 2 Source
- */
-#define WM2200_OUT2LMIX_SRC2_MASK 0x007F /* OUT2LMIX_SRC2 - [6:0] */
-#define WM2200_OUT2LMIX_SRC2_SHIFT 0 /* OUT2LMIX_SRC2 - [6:0] */
-#define WM2200_OUT2LMIX_SRC2_WIDTH 7 /* OUT2LMIX_SRC2 - [6:0] */
-
-/*
- * R1555 (0x613) - OUT2LMIX Input 2 Volume
- */
-#define WM2200_OUT2LMIX_VOL2_MASK 0x00FE /* OUT2LMIX_VOL2 - [7:1] */
-#define WM2200_OUT2LMIX_VOL2_SHIFT 1 /* OUT2LMIX_VOL2 - [7:1] */
-#define WM2200_OUT2LMIX_VOL2_WIDTH 7 /* OUT2LMIX_VOL2 - [7:1] */
-
-/*
- * R1556 (0x614) - OUT2LMIX Input 3 Source
- */
-#define WM2200_OUT2LMIX_SRC3_MASK 0x007F /* OUT2LMIX_SRC3 - [6:0] */
-#define WM2200_OUT2LMIX_SRC3_SHIFT 0 /* OUT2LMIX_SRC3 - [6:0] */
-#define WM2200_OUT2LMIX_SRC3_WIDTH 7 /* OUT2LMIX_SRC3 - [6:0] */
-
-/*
- * R1557 (0x615) - OUT2LMIX Input 3 Volume
- */
-#define WM2200_OUT2LMIX_VOL3_MASK 0x00FE /* OUT2LMIX_VOL3 - [7:1] */
-#define WM2200_OUT2LMIX_VOL3_SHIFT 1 /* OUT2LMIX_VOL3 - [7:1] */
-#define WM2200_OUT2LMIX_VOL3_WIDTH 7 /* OUT2LMIX_VOL3 - [7:1] */
-
-/*
- * R1558 (0x616) - OUT2LMIX Input 4 Source
- */
-#define WM2200_OUT2LMIX_SRC4_MASK 0x007F /* OUT2LMIX_SRC4 - [6:0] */
-#define WM2200_OUT2LMIX_SRC4_SHIFT 0 /* OUT2LMIX_SRC4 - [6:0] */
-#define WM2200_OUT2LMIX_SRC4_WIDTH 7 /* OUT2LMIX_SRC4 - [6:0] */
-
-/*
- * R1559 (0x617) - OUT2LMIX Input 4 Volume
- */
-#define WM2200_OUT2LMIX_VOL4_MASK 0x00FE /* OUT2LMIX_VOL4 - [7:1] */
-#define WM2200_OUT2LMIX_VOL4_SHIFT 1 /* OUT2LMIX_VOL4 - [7:1] */
-#define WM2200_OUT2LMIX_VOL4_WIDTH 7 /* OUT2LMIX_VOL4 - [7:1] */
-
-/*
- * R1560 (0x618) - OUT2RMIX Input 1 Source
- */
-#define WM2200_OUT2RMIX_SRC1_MASK 0x007F /* OUT2RMIX_SRC1 - [6:0] */
-#define WM2200_OUT2RMIX_SRC1_SHIFT 0 /* OUT2RMIX_SRC1 - [6:0] */
-#define WM2200_OUT2RMIX_SRC1_WIDTH 7 /* OUT2RMIX_SRC1 - [6:0] */
-
-/*
- * R1561 (0x619) - OUT2RMIX Input 1 Volume
- */
-#define WM2200_OUT2RMIX_VOL1_MASK 0x00FE /* OUT2RMIX_VOL1 - [7:1] */
-#define WM2200_OUT2RMIX_VOL1_SHIFT 1 /* OUT2RMIX_VOL1 - [7:1] */
-#define WM2200_OUT2RMIX_VOL1_WIDTH 7 /* OUT2RMIX_VOL1 - [7:1] */
-
-/*
- * R1562 (0x61A) - OUT2RMIX Input 2 Source
- */
-#define WM2200_OUT2RMIX_SRC2_MASK 0x007F /* OUT2RMIX_SRC2 - [6:0] */
-#define WM2200_OUT2RMIX_SRC2_SHIFT 0 /* OUT2RMIX_SRC2 - [6:0] */
-#define WM2200_OUT2RMIX_SRC2_WIDTH 7 /* OUT2RMIX_SRC2 - [6:0] */
-
-/*
- * R1563 (0x61B) - OUT2RMIX Input 2 Volume
- */
-#define WM2200_OUT2RMIX_VOL2_MASK 0x00FE /* OUT2RMIX_VOL2 - [7:1] */
-#define WM2200_OUT2RMIX_VOL2_SHIFT 1 /* OUT2RMIX_VOL2 - [7:1] */
-#define WM2200_OUT2RMIX_VOL2_WIDTH 7 /* OUT2RMIX_VOL2 - [7:1] */
-
-/*
- * R1564 (0x61C) - OUT2RMIX Input 3 Source
- */
-#define WM2200_OUT2RMIX_SRC3_MASK 0x007F /* OUT2RMIX_SRC3 - [6:0] */
-#define WM2200_OUT2RMIX_SRC3_SHIFT 0 /* OUT2RMIX_SRC3 - [6:0] */
-#define WM2200_OUT2RMIX_SRC3_WIDTH 7 /* OUT2RMIX_SRC3 - [6:0] */
-
-/*
- * R1565 (0x61D) - OUT2RMIX Input 3 Volume
- */
-#define WM2200_OUT2RMIX_VOL3_MASK 0x00FE /* OUT2RMIX_VOL3 - [7:1] */
-#define WM2200_OUT2RMIX_VOL3_SHIFT 1 /* OUT2RMIX_VOL3 - [7:1] */
-#define WM2200_OUT2RMIX_VOL3_WIDTH 7 /* OUT2RMIX_VOL3 - [7:1] */
-
-/*
- * R1566 (0x61E) - OUT2RMIX Input 4 Source
- */
-#define WM2200_OUT2RMIX_SRC4_MASK 0x007F /* OUT2RMIX_SRC4 - [6:0] */
-#define WM2200_OUT2RMIX_SRC4_SHIFT 0 /* OUT2RMIX_SRC4 - [6:0] */
-#define WM2200_OUT2RMIX_SRC4_WIDTH 7 /* OUT2RMIX_SRC4 - [6:0] */
-
-/*
- * R1567 (0x61F) - OUT2RMIX Input 4 Volume
- */
-#define WM2200_OUT2RMIX_VOL4_MASK 0x00FE /* OUT2RMIX_VOL4 - [7:1] */
-#define WM2200_OUT2RMIX_VOL4_SHIFT 1 /* OUT2RMIX_VOL4 - [7:1] */
-#define WM2200_OUT2RMIX_VOL4_WIDTH 7 /* OUT2RMIX_VOL4 - [7:1] */
-
-/*
- * R1568 (0x620) - AIF1TX1MIX Input 1 Source
- */
-#define WM2200_AIF1TX1MIX_SRC1_MASK 0x007F /* AIF1TX1MIX_SRC1 - [6:0] */
-#define WM2200_AIF1TX1MIX_SRC1_SHIFT 0 /* AIF1TX1MIX_SRC1 - [6:0] */
-#define WM2200_AIF1TX1MIX_SRC1_WIDTH 7 /* AIF1TX1MIX_SRC1 - [6:0] */
-
-/*
- * R1569 (0x621) - AIF1TX1MIX Input 1 Volume
- */
-#define WM2200_AIF1TX1MIX_VOL1_MASK 0x00FE /* AIF1TX1MIX_VOL1 - [7:1] */
-#define WM2200_AIF1TX1MIX_VOL1_SHIFT 1 /* AIF1TX1MIX_VOL1 - [7:1] */
-#define WM2200_AIF1TX1MIX_VOL1_WIDTH 7 /* AIF1TX1MIX_VOL1 - [7:1] */
-
-/*
- * R1570 (0x622) - AIF1TX1MIX Input 2 Source
- */
-#define WM2200_AIF1TX1MIX_SRC2_MASK 0x007F /* AIF1TX1MIX_SRC2 - [6:0] */
-#define WM2200_AIF1TX1MIX_SRC2_SHIFT 0 /* AIF1TX1MIX_SRC2 - [6:0] */
-#define WM2200_AIF1TX1MIX_SRC2_WIDTH 7 /* AIF1TX1MIX_SRC2 - [6:0] */
-
-/*
- * R1571 (0x623) - AIF1TX1MIX Input 2 Volume
- */
-#define WM2200_AIF1TX1MIX_VOL2_MASK 0x00FE /* AIF1TX1MIX_VOL2 - [7:1] */
-#define WM2200_AIF1TX1MIX_VOL2_SHIFT 1 /* AIF1TX1MIX_VOL2 - [7:1] */
-#define WM2200_AIF1TX1MIX_VOL2_WIDTH 7 /* AIF1TX1MIX_VOL2 - [7:1] */
-
-/*
- * R1572 (0x624) - AIF1TX1MIX Input 3 Source
- */
-#define WM2200_AIF1TX1MIX_SRC3_MASK 0x007F /* AIF1TX1MIX_SRC3 - [6:0] */
-#define WM2200_AIF1TX1MIX_SRC3_SHIFT 0 /* AIF1TX1MIX_SRC3 - [6:0] */
-#define WM2200_AIF1TX1MIX_SRC3_WIDTH 7 /* AIF1TX1MIX_SRC3 - [6:0] */
-
-/*
- * R1573 (0x625) - AIF1TX1MIX Input 3 Volume
- */
-#define WM2200_AIF1TX1MIX_VOL3_MASK 0x00FE /* AIF1TX1MIX_VOL3 - [7:1] */
-#define WM2200_AIF1TX1MIX_VOL3_SHIFT 1 /* AIF1TX1MIX_VOL3 - [7:1] */
-#define WM2200_AIF1TX1MIX_VOL3_WIDTH 7 /* AIF1TX1MIX_VOL3 - [7:1] */
-
-/*
- * R1574 (0x626) - AIF1TX1MIX Input 4 Source
- */
-#define WM2200_AIF1TX1MIX_SRC4_MASK 0x007F /* AIF1TX1MIX_SRC4 - [6:0] */
-#define WM2200_AIF1TX1MIX_SRC4_SHIFT 0 /* AIF1TX1MIX_SRC4 - [6:0] */
-#define WM2200_AIF1TX1MIX_SRC4_WIDTH 7 /* AIF1TX1MIX_SRC4 - [6:0] */
-
-/*
- * R1575 (0x627) - AIF1TX1MIX Input 4 Volume
- */
-#define WM2200_AIF1TX1MIX_VOL4_MASK 0x00FE /* AIF1TX1MIX_VOL4 - [7:1] */
-#define WM2200_AIF1TX1MIX_VOL4_SHIFT 1 /* AIF1TX1MIX_VOL4 - [7:1] */
-#define WM2200_AIF1TX1MIX_VOL4_WIDTH 7 /* AIF1TX1MIX_VOL4 - [7:1] */
-
-/*
- * R1576 (0x628) - AIF1TX2MIX Input 1 Source
- */
-#define WM2200_AIF1TX2MIX_SRC1_MASK 0x007F /* AIF1TX2MIX_SRC1 - [6:0] */
-#define WM2200_AIF1TX2MIX_SRC1_SHIFT 0 /* AIF1TX2MIX_SRC1 - [6:0] */
-#define WM2200_AIF1TX2MIX_SRC1_WIDTH 7 /* AIF1TX2MIX_SRC1 - [6:0] */
-
-/*
- * R1577 (0x629) - AIF1TX2MIX Input 1 Volume
- */
-#define WM2200_AIF1TX2MIX_VOL1_MASK 0x00FE /* AIF1TX2MIX_VOL1 - [7:1] */
-#define WM2200_AIF1TX2MIX_VOL1_SHIFT 1 /* AIF1TX2MIX_VOL1 - [7:1] */
-#define WM2200_AIF1TX2MIX_VOL1_WIDTH 7 /* AIF1TX2MIX_VOL1 - [7:1] */
-
-/*
- * R1578 (0x62A) - AIF1TX2MIX Input 2 Source
- */
-#define WM2200_AIF1TX2MIX_SRC2_MASK 0x007F /* AIF1TX2MIX_SRC2 - [6:0] */
-#define WM2200_AIF1TX2MIX_SRC2_SHIFT 0 /* AIF1TX2MIX_SRC2 - [6:0] */
-#define WM2200_AIF1TX2MIX_SRC2_WIDTH 7 /* AIF1TX2MIX_SRC2 - [6:0] */
-
-/*
- * R1579 (0x62B) - AIF1TX2MIX Input 2 Volume
- */
-#define WM2200_AIF1TX2MIX_VOL2_MASK 0x00FE /* AIF1TX2MIX_VOL2 - [7:1] */
-#define WM2200_AIF1TX2MIX_VOL2_SHIFT 1 /* AIF1TX2MIX_VOL2 - [7:1] */
-#define WM2200_AIF1TX2MIX_VOL2_WIDTH 7 /* AIF1TX2MIX_VOL2 - [7:1] */
-
-/*
- * R1580 (0x62C) - AIF1TX2MIX Input 3 Source
- */
-#define WM2200_AIF1TX2MIX_SRC3_MASK 0x007F /* AIF1TX2MIX_SRC3 - [6:0] */
-#define WM2200_AIF1TX2MIX_SRC3_SHIFT 0 /* AIF1TX2MIX_SRC3 - [6:0] */
-#define WM2200_AIF1TX2MIX_SRC3_WIDTH 7 /* AIF1TX2MIX_SRC3 - [6:0] */
-
-/*
- * R1581 (0x62D) - AIF1TX2MIX Input 3 Volume
- */
-#define WM2200_AIF1TX2MIX_VOL3_MASK 0x00FE /* AIF1TX2MIX_VOL3 - [7:1] */
-#define WM2200_AIF1TX2MIX_VOL3_SHIFT 1 /* AIF1TX2MIX_VOL3 - [7:1] */
-#define WM2200_AIF1TX2MIX_VOL3_WIDTH 7 /* AIF1TX2MIX_VOL3 - [7:1] */
-
-/*
- * R1582 (0x62E) - AIF1TX2MIX Input 4 Source
- */
-#define WM2200_AIF1TX2MIX_SRC4_MASK 0x007F /* AIF1TX2MIX_SRC4 - [6:0] */
-#define WM2200_AIF1TX2MIX_SRC4_SHIFT 0 /* AIF1TX2MIX_SRC4 - [6:0] */
-#define WM2200_AIF1TX2MIX_SRC4_WIDTH 7 /* AIF1TX2MIX_SRC4 - [6:0] */
-
-/*
- * R1583 (0x62F) - AIF1TX2MIX Input 4 Volume
- */
-#define WM2200_AIF1TX2MIX_VOL4_MASK 0x00FE /* AIF1TX2MIX_VOL4 - [7:1] */
-#define WM2200_AIF1TX2MIX_VOL4_SHIFT 1 /* AIF1TX2MIX_VOL4 - [7:1] */
-#define WM2200_AIF1TX2MIX_VOL4_WIDTH 7 /* AIF1TX2MIX_VOL4 - [7:1] */
-
-/*
- * R1584 (0x630) - AIF1TX3MIX Input 1 Source
- */
-#define WM2200_AIF1TX3MIX_SRC1_MASK 0x007F /* AIF1TX3MIX_SRC1 - [6:0] */
-#define WM2200_AIF1TX3MIX_SRC1_SHIFT 0 /* AIF1TX3MIX_SRC1 - [6:0] */
-#define WM2200_AIF1TX3MIX_SRC1_WIDTH 7 /* AIF1TX3MIX_SRC1 - [6:0] */
-
-/*
- * R1585 (0x631) - AIF1TX3MIX Input 1 Volume
- */
-#define WM2200_AIF1TX3MIX_VOL1_MASK 0x00FE /* AIF1TX3MIX_VOL1 - [7:1] */
-#define WM2200_AIF1TX3MIX_VOL1_SHIFT 1 /* AIF1TX3MIX_VOL1 - [7:1] */
-#define WM2200_AIF1TX3MIX_VOL1_WIDTH 7 /* AIF1TX3MIX_VOL1 - [7:1] */
-
-/*
- * R1586 (0x632) - AIF1TX3MIX Input 2 Source
- */
-#define WM2200_AIF1TX3MIX_SRC2_MASK 0x007F /* AIF1TX3MIX_SRC2 - [6:0] */
-#define WM2200_AIF1TX3MIX_SRC2_SHIFT 0 /* AIF1TX3MIX_SRC2 - [6:0] */
-#define WM2200_AIF1TX3MIX_SRC2_WIDTH 7 /* AIF1TX3MIX_SRC2 - [6:0] */
-
-/*
- * R1587 (0x633) - AIF1TX3MIX Input 2 Volume
- */
-#define WM2200_AIF1TX3MIX_VOL2_MASK 0x00FE /* AIF1TX3MIX_VOL2 - [7:1] */
-#define WM2200_AIF1TX3MIX_VOL2_SHIFT 1 /* AIF1TX3MIX_VOL2 - [7:1] */
-#define WM2200_AIF1TX3MIX_VOL2_WIDTH 7 /* AIF1TX3MIX_VOL2 - [7:1] */
-
-/*
- * R1588 (0x634) - AIF1TX3MIX Input 3 Source
- */
-#define WM2200_AIF1TX3MIX_SRC3_MASK 0x007F /* AIF1TX3MIX_SRC3 - [6:0] */
-#define WM2200_AIF1TX3MIX_SRC3_SHIFT 0 /* AIF1TX3MIX_SRC3 - [6:0] */
-#define WM2200_AIF1TX3MIX_SRC3_WIDTH 7 /* AIF1TX3MIX_SRC3 - [6:0] */
-
-/*
- * R1589 (0x635) - AIF1TX3MIX Input 3 Volume
- */
-#define WM2200_AIF1TX3MIX_VOL3_MASK 0x00FE /* AIF1TX3MIX_VOL3 - [7:1] */
-#define WM2200_AIF1TX3MIX_VOL3_SHIFT 1 /* AIF1TX3MIX_VOL3 - [7:1] */
-#define WM2200_AIF1TX3MIX_VOL3_WIDTH 7 /* AIF1TX3MIX_VOL3 - [7:1] */
-
-/*
- * R1590 (0x636) - AIF1TX3MIX Input 4 Source
- */
-#define WM2200_AIF1TX3MIX_SRC4_MASK 0x007F /* AIF1TX3MIX_SRC4 - [6:0] */
-#define WM2200_AIF1TX3MIX_SRC4_SHIFT 0 /* AIF1TX3MIX_SRC4 - [6:0] */
-#define WM2200_AIF1TX3MIX_SRC4_WIDTH 7 /* AIF1TX3MIX_SRC4 - [6:0] */
-
-/*
- * R1591 (0x637) - AIF1TX3MIX Input 4 Volume
- */
-#define WM2200_AIF1TX3MIX_VOL4_MASK 0x00FE /* AIF1TX3MIX_VOL4 - [7:1] */
-#define WM2200_AIF1TX3MIX_VOL4_SHIFT 1 /* AIF1TX3MIX_VOL4 - [7:1] */
-#define WM2200_AIF1TX3MIX_VOL4_WIDTH 7 /* AIF1TX3MIX_VOL4 - [7:1] */
-
-/*
- * R1592 (0x638) - AIF1TX4MIX Input 1 Source
- */
-#define WM2200_AIF1TX4MIX_SRC1_MASK 0x007F /* AIF1TX4MIX_SRC1 - [6:0] */
-#define WM2200_AIF1TX4MIX_SRC1_SHIFT 0 /* AIF1TX4MIX_SRC1 - [6:0] */
-#define WM2200_AIF1TX4MIX_SRC1_WIDTH 7 /* AIF1TX4MIX_SRC1 - [6:0] */
-
-/*
- * R1593 (0x639) - AIF1TX4MIX Input 1 Volume
- */
-#define WM2200_AIF1TX4MIX_VOL1_MASK 0x00FE /* AIF1TX4MIX_VOL1 - [7:1] */
-#define WM2200_AIF1TX4MIX_VOL1_SHIFT 1 /* AIF1TX4MIX_VOL1 - [7:1] */
-#define WM2200_AIF1TX4MIX_VOL1_WIDTH 7 /* AIF1TX4MIX_VOL1 - [7:1] */
-
-/*
- * R1594 (0x63A) - AIF1TX4MIX Input 2 Source
- */
-#define WM2200_AIF1TX4MIX_SRC2_MASK 0x007F /* AIF1TX4MIX_SRC2 - [6:0] */
-#define WM2200_AIF1TX4MIX_SRC2_SHIFT 0 /* AIF1TX4MIX_SRC2 - [6:0] */
-#define WM2200_AIF1TX4MIX_SRC2_WIDTH 7 /* AIF1TX4MIX_SRC2 - [6:0] */
-
-/*
- * R1595 (0x63B) - AIF1TX4MIX Input 2 Volume
- */
-#define WM2200_AIF1TX4MIX_VOL2_MASK 0x00FE /* AIF1TX4MIX_VOL2 - [7:1] */
-#define WM2200_AIF1TX4MIX_VOL2_SHIFT 1 /* AIF1TX4MIX_VOL2 - [7:1] */
-#define WM2200_AIF1TX4MIX_VOL2_WIDTH 7 /* AIF1TX4MIX_VOL2 - [7:1] */
-
-/*
- * R1596 (0x63C) - AIF1TX4MIX Input 3 Source
- */
-#define WM2200_AIF1TX4MIX_SRC3_MASK 0x007F /* AIF1TX4MIX_SRC3 - [6:0] */
-#define WM2200_AIF1TX4MIX_SRC3_SHIFT 0 /* AIF1TX4MIX_SRC3 - [6:0] */
-#define WM2200_AIF1TX4MIX_SRC3_WIDTH 7 /* AIF1TX4MIX_SRC3 - [6:0] */
-
-/*
- * R1597 (0x63D) - AIF1TX4MIX Input 3 Volume
- */
-#define WM2200_AIF1TX4MIX_VOL3_MASK 0x00FE /* AIF1TX4MIX_VOL3 - [7:1] */
-#define WM2200_AIF1TX4MIX_VOL3_SHIFT 1 /* AIF1TX4MIX_VOL3 - [7:1] */
-#define WM2200_AIF1TX4MIX_VOL3_WIDTH 7 /* AIF1TX4MIX_VOL3 - [7:1] */
-
-/*
- * R1598 (0x63E) - AIF1TX4MIX Input 4 Source
- */
-#define WM2200_AIF1TX4MIX_SRC4_MASK 0x007F /* AIF1TX4MIX_SRC4 - [6:0] */
-#define WM2200_AIF1TX4MIX_SRC4_SHIFT 0 /* AIF1TX4MIX_SRC4 - [6:0] */
-#define WM2200_AIF1TX4MIX_SRC4_WIDTH 7 /* AIF1TX4MIX_SRC4 - [6:0] */
-
-/*
- * R1599 (0x63F) - AIF1TX4MIX Input 4 Volume
- */
-#define WM2200_AIF1TX4MIX_VOL4_MASK 0x00FE /* AIF1TX4MIX_VOL4 - [7:1] */
-#define WM2200_AIF1TX4MIX_VOL4_SHIFT 1 /* AIF1TX4MIX_VOL4 - [7:1] */
-#define WM2200_AIF1TX4MIX_VOL4_WIDTH 7 /* AIF1TX4MIX_VOL4 - [7:1] */
-
-/*
- * R1600 (0x640) - AIF1TX5MIX Input 1 Source
- */
-#define WM2200_AIF1TX5MIX_SRC1_MASK 0x007F /* AIF1TX5MIX_SRC1 - [6:0] */
-#define WM2200_AIF1TX5MIX_SRC1_SHIFT 0 /* AIF1TX5MIX_SRC1 - [6:0] */
-#define WM2200_AIF1TX5MIX_SRC1_WIDTH 7 /* AIF1TX5MIX_SRC1 - [6:0] */
-
-/*
- * R1601 (0x641) - AIF1TX5MIX Input 1 Volume
- */
-#define WM2200_AIF1TX5MIX_VOL1_MASK 0x00FE /* AIF1TX5MIX_VOL1 - [7:1] */
-#define WM2200_AIF1TX5MIX_VOL1_SHIFT 1 /* AIF1TX5MIX_VOL1 - [7:1] */
-#define WM2200_AIF1TX5MIX_VOL1_WIDTH 7 /* AIF1TX5MIX_VOL1 - [7:1] */
-
-/*
- * R1602 (0x642) - AIF1TX5MIX Input 2 Source
- */
-#define WM2200_AIF1TX5MIX_SRC2_MASK 0x007F /* AIF1TX5MIX_SRC2 - [6:0] */
-#define WM2200_AIF1TX5MIX_SRC2_SHIFT 0 /* AIF1TX5MIX_SRC2 - [6:0] */
-#define WM2200_AIF1TX5MIX_SRC2_WIDTH 7 /* AIF1TX5MIX_SRC2 - [6:0] */
-
-/*
- * R1603 (0x643) - AIF1TX5MIX Input 2 Volume
- */
-#define WM2200_AIF1TX5MIX_VOL2_MASK 0x00FE /* AIF1TX5MIX_VOL2 - [7:1] */
-#define WM2200_AIF1TX5MIX_VOL2_SHIFT 1 /* AIF1TX5MIX_VOL2 - [7:1] */
-#define WM2200_AIF1TX5MIX_VOL2_WIDTH 7 /* AIF1TX5MIX_VOL2 - [7:1] */
-
-/*
- * R1604 (0x644) - AIF1TX5MIX Input 3 Source
- */
-#define WM2200_AIF1TX5MIX_SRC3_MASK 0x007F /* AIF1TX5MIX_SRC3 - [6:0] */
-#define WM2200_AIF1TX5MIX_SRC3_SHIFT 0 /* AIF1TX5MIX_SRC3 - [6:0] */
-#define WM2200_AIF1TX5MIX_SRC3_WIDTH 7 /* AIF1TX5MIX_SRC3 - [6:0] */
-
-/*
- * R1605 (0x645) - AIF1TX5MIX Input 3 Volume
- */
-#define WM2200_AIF1TX5MIX_VOL3_MASK 0x00FE /* AIF1TX5MIX_VOL3 - [7:1] */
-#define WM2200_AIF1TX5MIX_VOL3_SHIFT 1 /* AIF1TX5MIX_VOL3 - [7:1] */
-#define WM2200_AIF1TX5MIX_VOL3_WIDTH 7 /* AIF1TX5MIX_VOL3 - [7:1] */
-
-/*
- * R1606 (0x646) - AIF1TX5MIX Input 4 Source
- */
-#define WM2200_AIF1TX5MIX_SRC4_MASK 0x007F /* AIF1TX5MIX_SRC4 - [6:0] */
-#define WM2200_AIF1TX5MIX_SRC4_SHIFT 0 /* AIF1TX5MIX_SRC4 - [6:0] */
-#define WM2200_AIF1TX5MIX_SRC4_WIDTH 7 /* AIF1TX5MIX_SRC4 - [6:0] */
-
-/*
- * R1607 (0x647) - AIF1TX5MIX Input 4 Volume
- */
-#define WM2200_AIF1TX5MIX_VOL4_MASK 0x00FE /* AIF1TX5MIX_VOL4 - [7:1] */
-#define WM2200_AIF1TX5MIX_VOL4_SHIFT 1 /* AIF1TX5MIX_VOL4 - [7:1] */
-#define WM2200_AIF1TX5MIX_VOL4_WIDTH 7 /* AIF1TX5MIX_VOL4 - [7:1] */
-
-/*
- * R1608 (0x648) - AIF1TX6MIX Input 1 Source
- */
-#define WM2200_AIF1TX6MIX_SRC1_MASK 0x007F /* AIF1TX6MIX_SRC1 - [6:0] */
-#define WM2200_AIF1TX6MIX_SRC1_SHIFT 0 /* AIF1TX6MIX_SRC1 - [6:0] */
-#define WM2200_AIF1TX6MIX_SRC1_WIDTH 7 /* AIF1TX6MIX_SRC1 - [6:0] */
-
-/*
- * R1609 (0x649) - AIF1TX6MIX Input 1 Volume
- */
-#define WM2200_AIF1TX6MIX_VOL1_MASK 0x00FE /* AIF1TX6MIX_VOL1 - [7:1] */
-#define WM2200_AIF1TX6MIX_VOL1_SHIFT 1 /* AIF1TX6MIX_VOL1 - [7:1] */
-#define WM2200_AIF1TX6MIX_VOL1_WIDTH 7 /* AIF1TX6MIX_VOL1 - [7:1] */
-
-/*
- * R1610 (0x64A) - AIF1TX6MIX Input 2 Source
- */
-#define WM2200_AIF1TX6MIX_SRC2_MASK 0x007F /* AIF1TX6MIX_SRC2 - [6:0] */
-#define WM2200_AIF1TX6MIX_SRC2_SHIFT 0 /* AIF1TX6MIX_SRC2 - [6:0] */
-#define WM2200_AIF1TX6MIX_SRC2_WIDTH 7 /* AIF1TX6MIX_SRC2 - [6:0] */
-
-/*
- * R1611 (0x64B) - AIF1TX6MIX Input 2 Volume
- */
-#define WM2200_AIF1TX6MIX_VOL2_MASK 0x00FE /* AIF1TX6MIX_VOL2 - [7:1] */
-#define WM2200_AIF1TX6MIX_VOL2_SHIFT 1 /* AIF1TX6MIX_VOL2 - [7:1] */
-#define WM2200_AIF1TX6MIX_VOL2_WIDTH 7 /* AIF1TX6MIX_VOL2 - [7:1] */
-
-/*
- * R1612 (0x64C) - AIF1TX6MIX Input 3 Source
- */
-#define WM2200_AIF1TX6MIX_SRC3_MASK 0x007F /* AIF1TX6MIX_SRC3 - [6:0] */
-#define WM2200_AIF1TX6MIX_SRC3_SHIFT 0 /* AIF1TX6MIX_SRC3 - [6:0] */
-#define WM2200_AIF1TX6MIX_SRC3_WIDTH 7 /* AIF1TX6MIX_SRC3 - [6:0] */
-
-/*
- * R1613 (0x64D) - AIF1TX6MIX Input 3 Volume
- */
-#define WM2200_AIF1TX6MIX_VOL3_MASK 0x00FE /* AIF1TX6MIX_VOL3 - [7:1] */
-#define WM2200_AIF1TX6MIX_VOL3_SHIFT 1 /* AIF1TX6MIX_VOL3 - [7:1] */
-#define WM2200_AIF1TX6MIX_VOL3_WIDTH 7 /* AIF1TX6MIX_VOL3 - [7:1] */
-
-/*
- * R1614 (0x64E) - AIF1TX6MIX Input 4 Source
- */
-#define WM2200_AIF1TX6MIX_SRC4_MASK 0x007F /* AIF1TX6MIX_SRC4 - [6:0] */
-#define WM2200_AIF1TX6MIX_SRC4_SHIFT 0 /* AIF1TX6MIX_SRC4 - [6:0] */
-#define WM2200_AIF1TX6MIX_SRC4_WIDTH 7 /* AIF1TX6MIX_SRC4 - [6:0] */
-
-/*
- * R1615 (0x64F) - AIF1TX6MIX Input 4 Volume
- */
-#define WM2200_AIF1TX6MIX_VOL4_MASK 0x00FE /* AIF1TX6MIX_VOL4 - [7:1] */
-#define WM2200_AIF1TX6MIX_VOL4_SHIFT 1 /* AIF1TX6MIX_VOL4 - [7:1] */
-#define WM2200_AIF1TX6MIX_VOL4_WIDTH 7 /* AIF1TX6MIX_VOL4 - [7:1] */
-
-/*
- * R1616 (0x650) - EQLMIX Input 1 Source
- */
-#define WM2200_EQLMIX_SRC1_MASK 0x007F /* EQLMIX_SRC1 - [6:0] */
-#define WM2200_EQLMIX_SRC1_SHIFT 0 /* EQLMIX_SRC1 - [6:0] */
-#define WM2200_EQLMIX_SRC1_WIDTH 7 /* EQLMIX_SRC1 - [6:0] */
-
-/*
- * R1617 (0x651) - EQLMIX Input 1 Volume
- */
-#define WM2200_EQLMIX_VOL1_MASK 0x00FE /* EQLMIX_VOL1 - [7:1] */
-#define WM2200_EQLMIX_VOL1_SHIFT 1 /* EQLMIX_VOL1 - [7:1] */
-#define WM2200_EQLMIX_VOL1_WIDTH 7 /* EQLMIX_VOL1 - [7:1] */
-
-/*
- * R1618 (0x652) - EQLMIX Input 2 Source
- */
-#define WM2200_EQLMIX_SRC2_MASK 0x007F /* EQLMIX_SRC2 - [6:0] */
-#define WM2200_EQLMIX_SRC2_SHIFT 0 /* EQLMIX_SRC2 - [6:0] */
-#define WM2200_EQLMIX_SRC2_WIDTH 7 /* EQLMIX_SRC2 - [6:0] */
-
-/*
- * R1619 (0x653) - EQLMIX Input 2 Volume
- */
-#define WM2200_EQLMIX_VOL2_MASK 0x00FE /* EQLMIX_VOL2 - [7:1] */
-#define WM2200_EQLMIX_VOL2_SHIFT 1 /* EQLMIX_VOL2 - [7:1] */
-#define WM2200_EQLMIX_VOL2_WIDTH 7 /* EQLMIX_VOL2 - [7:1] */
-
-/*
- * R1620 (0x654) - EQLMIX Input 3 Source
- */
-#define WM2200_EQLMIX_SRC3_MASK 0x007F /* EQLMIX_SRC3 - [6:0] */
-#define WM2200_EQLMIX_SRC3_SHIFT 0 /* EQLMIX_SRC3 - [6:0] */
-#define WM2200_EQLMIX_SRC3_WIDTH 7 /* EQLMIX_SRC3 - [6:0] */
-
-/*
- * R1621 (0x655) - EQLMIX Input 3 Volume
- */
-#define WM2200_EQLMIX_VOL3_MASK 0x00FE /* EQLMIX_VOL3 - [7:1] */
-#define WM2200_EQLMIX_VOL3_SHIFT 1 /* EQLMIX_VOL3 - [7:1] */
-#define WM2200_EQLMIX_VOL3_WIDTH 7 /* EQLMIX_VOL3 - [7:1] */
-
-/*
- * R1622 (0x656) - EQLMIX Input 4 Source
- */
-#define WM2200_EQLMIX_SRC4_MASK 0x007F /* EQLMIX_SRC4 - [6:0] */
-#define WM2200_EQLMIX_SRC4_SHIFT 0 /* EQLMIX_SRC4 - [6:0] */
-#define WM2200_EQLMIX_SRC4_WIDTH 7 /* EQLMIX_SRC4 - [6:0] */
-
-/*
- * R1623 (0x657) - EQLMIX Input 4 Volume
- */
-#define WM2200_EQLMIX_VOL4_MASK 0x00FE /* EQLMIX_VOL4 - [7:1] */
-#define WM2200_EQLMIX_VOL4_SHIFT 1 /* EQLMIX_VOL4 - [7:1] */
-#define WM2200_EQLMIX_VOL4_WIDTH 7 /* EQLMIX_VOL4 - [7:1] */
-
-/*
- * R1624 (0x658) - EQRMIX Input 1 Source
- */
-#define WM2200_EQRMIX_SRC1_MASK 0x007F /* EQRMIX_SRC1 - [6:0] */
-#define WM2200_EQRMIX_SRC1_SHIFT 0 /* EQRMIX_SRC1 - [6:0] */
-#define WM2200_EQRMIX_SRC1_WIDTH 7 /* EQRMIX_SRC1 - [6:0] */
-
-/*
- * R1625 (0x659) - EQRMIX Input 1 Volume
- */
-#define WM2200_EQRMIX_VOL1_MASK 0x00FE /* EQRMIX_VOL1 - [7:1] */
-#define WM2200_EQRMIX_VOL1_SHIFT 1 /* EQRMIX_VOL1 - [7:1] */
-#define WM2200_EQRMIX_VOL1_WIDTH 7 /* EQRMIX_VOL1 - [7:1] */
-
-/*
- * R1626 (0x65A) - EQRMIX Input 2 Source
- */
-#define WM2200_EQRMIX_SRC2_MASK 0x007F /* EQRMIX_SRC2 - [6:0] */
-#define WM2200_EQRMIX_SRC2_SHIFT 0 /* EQRMIX_SRC2 - [6:0] */
-#define WM2200_EQRMIX_SRC2_WIDTH 7 /* EQRMIX_SRC2 - [6:0] */
-
-/*
- * R1627 (0x65B) - EQRMIX Input 2 Volume
- */
-#define WM2200_EQRMIX_VOL2_MASK 0x00FE /* EQRMIX_VOL2 - [7:1] */
-#define WM2200_EQRMIX_VOL2_SHIFT 1 /* EQRMIX_VOL2 - [7:1] */
-#define WM2200_EQRMIX_VOL2_WIDTH 7 /* EQRMIX_VOL2 - [7:1] */
-
-/*
- * R1628 (0x65C) - EQRMIX Input 3 Source
- */
-#define WM2200_EQRMIX_SRC3_MASK 0x007F /* EQRMIX_SRC3 - [6:0] */
-#define WM2200_EQRMIX_SRC3_SHIFT 0 /* EQRMIX_SRC3 - [6:0] */
-#define WM2200_EQRMIX_SRC3_WIDTH 7 /* EQRMIX_SRC3 - [6:0] */
-
-/*
- * R1629 (0x65D) - EQRMIX Input 3 Volume
- */
-#define WM2200_EQRMIX_VOL3_MASK 0x00FE /* EQRMIX_VOL3 - [7:1] */
-#define WM2200_EQRMIX_VOL3_SHIFT 1 /* EQRMIX_VOL3 - [7:1] */
-#define WM2200_EQRMIX_VOL3_WIDTH 7 /* EQRMIX_VOL3 - [7:1] */
-
-/*
- * R1630 (0x65E) - EQRMIX Input 4 Source
- */
-#define WM2200_EQRMIX_SRC4_MASK 0x007F /* EQRMIX_SRC4 - [6:0] */
-#define WM2200_EQRMIX_SRC4_SHIFT 0 /* EQRMIX_SRC4 - [6:0] */
-#define WM2200_EQRMIX_SRC4_WIDTH 7 /* EQRMIX_SRC4 - [6:0] */
-
-/*
- * R1631 (0x65F) - EQRMIX Input 4 Volume
- */
-#define WM2200_EQRMIX_VOL4_MASK 0x00FE /* EQRMIX_VOL4 - [7:1] */
-#define WM2200_EQRMIX_VOL4_SHIFT 1 /* EQRMIX_VOL4 - [7:1] */
-#define WM2200_EQRMIX_VOL4_WIDTH 7 /* EQRMIX_VOL4 - [7:1] */
-
-/*
- * R1632 (0x660) - LHPF1MIX Input 1 Source
- */
-#define WM2200_LHPF1MIX_SRC1_MASK 0x007F /* LHPF1MIX_SRC1 - [6:0] */
-#define WM2200_LHPF1MIX_SRC1_SHIFT 0 /* LHPF1MIX_SRC1 - [6:0] */
-#define WM2200_LHPF1MIX_SRC1_WIDTH 7 /* LHPF1MIX_SRC1 - [6:0] */
-
-/*
- * R1633 (0x661) - LHPF1MIX Input 1 Volume
- */
-#define WM2200_LHPF1MIX_VOL1_MASK 0x00FE /* LHPF1MIX_VOL1 - [7:1] */
-#define WM2200_LHPF1MIX_VOL1_SHIFT 1 /* LHPF1MIX_VOL1 - [7:1] */
-#define WM2200_LHPF1MIX_VOL1_WIDTH 7 /* LHPF1MIX_VOL1 - [7:1] */
-
-/*
- * R1634 (0x662) - LHPF1MIX Input 2 Source
- */
-#define WM2200_LHPF1MIX_SRC2_MASK 0x007F /* LHPF1MIX_SRC2 - [6:0] */
-#define WM2200_LHPF1MIX_SRC2_SHIFT 0 /* LHPF1MIX_SRC2 - [6:0] */
-#define WM2200_LHPF1MIX_SRC2_WIDTH 7 /* LHPF1MIX_SRC2 - [6:0] */
-
-/*
- * R1635 (0x663) - LHPF1MIX Input 2 Volume
- */
-#define WM2200_LHPF1MIX_VOL2_MASK 0x00FE /* LHPF1MIX_VOL2 - [7:1] */
-#define WM2200_LHPF1MIX_VOL2_SHIFT 1 /* LHPF1MIX_VOL2 - [7:1] */
-#define WM2200_LHPF1MIX_VOL2_WIDTH 7 /* LHPF1MIX_VOL2 - [7:1] */
-
-/*
- * R1636 (0x664) - LHPF1MIX Input 3 Source
- */
-#define WM2200_LHPF1MIX_SRC3_MASK 0x007F /* LHPF1MIX_SRC3 - [6:0] */
-#define WM2200_LHPF1MIX_SRC3_SHIFT 0 /* LHPF1MIX_SRC3 - [6:0] */
-#define WM2200_LHPF1MIX_SRC3_WIDTH 7 /* LHPF1MIX_SRC3 - [6:0] */
-
-/*
- * R1637 (0x665) - LHPF1MIX Input 3 Volume
- */
-#define WM2200_LHPF1MIX_VOL3_MASK 0x00FE /* LHPF1MIX_VOL3 - [7:1] */
-#define WM2200_LHPF1MIX_VOL3_SHIFT 1 /* LHPF1MIX_VOL3 - [7:1] */
-#define WM2200_LHPF1MIX_VOL3_WIDTH 7 /* LHPF1MIX_VOL3 - [7:1] */
-
-/*
- * R1638 (0x666) - LHPF1MIX Input 4 Source
- */
-#define WM2200_LHPF1MIX_SRC4_MASK 0x007F /* LHPF1MIX_SRC4 - [6:0] */
-#define WM2200_LHPF1MIX_SRC4_SHIFT 0 /* LHPF1MIX_SRC4 - [6:0] */
-#define WM2200_LHPF1MIX_SRC4_WIDTH 7 /* LHPF1MIX_SRC4 - [6:0] */
-
-/*
- * R1639 (0x667) - LHPF1MIX Input 4 Volume
- */
-#define WM2200_LHPF1MIX_VOL4_MASK 0x00FE /* LHPF1MIX_VOL4 - [7:1] */
-#define WM2200_LHPF1MIX_VOL4_SHIFT 1 /* LHPF1MIX_VOL4 - [7:1] */
-#define WM2200_LHPF1MIX_VOL4_WIDTH 7 /* LHPF1MIX_VOL4 - [7:1] */
-
-/*
- * R1640 (0x668) - LHPF2MIX Input 1 Source
- */
-#define WM2200_LHPF2MIX_SRC1_MASK 0x007F /* LHPF2MIX_SRC1 - [6:0] */
-#define WM2200_LHPF2MIX_SRC1_SHIFT 0 /* LHPF2MIX_SRC1 - [6:0] */
-#define WM2200_LHPF2MIX_SRC1_WIDTH 7 /* LHPF2MIX_SRC1 - [6:0] */
-
-/*
- * R1641 (0x669) - LHPF2MIX Input 1 Volume
- */
-#define WM2200_LHPF2MIX_VOL1_MASK 0x00FE /* LHPF2MIX_VOL1 - [7:1] */
-#define WM2200_LHPF2MIX_VOL1_SHIFT 1 /* LHPF2MIX_VOL1 - [7:1] */
-#define WM2200_LHPF2MIX_VOL1_WIDTH 7 /* LHPF2MIX_VOL1 - [7:1] */
-
-/*
- * R1642 (0x66A) - LHPF2MIX Input 2 Source
- */
-#define WM2200_LHPF2MIX_SRC2_MASK 0x007F /* LHPF2MIX_SRC2 - [6:0] */
-#define WM2200_LHPF2MIX_SRC2_SHIFT 0 /* LHPF2MIX_SRC2 - [6:0] */
-#define WM2200_LHPF2MIX_SRC2_WIDTH 7 /* LHPF2MIX_SRC2 - [6:0] */
-
-/*
- * R1643 (0x66B) - LHPF2MIX Input 2 Volume
- */
-#define WM2200_LHPF2MIX_VOL2_MASK 0x00FE /* LHPF2MIX_VOL2 - [7:1] */
-#define WM2200_LHPF2MIX_VOL2_SHIFT 1 /* LHPF2MIX_VOL2 - [7:1] */
-#define WM2200_LHPF2MIX_VOL2_WIDTH 7 /* LHPF2MIX_VOL2 - [7:1] */
-
-/*
- * R1644 (0x66C) - LHPF2MIX Input 3 Source
- */
-#define WM2200_LHPF2MIX_SRC3_MASK 0x007F /* LHPF2MIX_SRC3 - [6:0] */
-#define WM2200_LHPF2MIX_SRC3_SHIFT 0 /* LHPF2MIX_SRC3 - [6:0] */
-#define WM2200_LHPF2MIX_SRC3_WIDTH 7 /* LHPF2MIX_SRC3 - [6:0] */
-
-/*
- * R1645 (0x66D) - LHPF2MIX Input 3 Volume
- */
-#define WM2200_LHPF2MIX_VOL3_MASK 0x00FE /* LHPF2MIX_VOL3 - [7:1] */
-#define WM2200_LHPF2MIX_VOL3_SHIFT 1 /* LHPF2MIX_VOL3 - [7:1] */
-#define WM2200_LHPF2MIX_VOL3_WIDTH 7 /* LHPF2MIX_VOL3 - [7:1] */
-
-/*
- * R1646 (0x66E) - LHPF2MIX Input 4 Source
- */
-#define WM2200_LHPF2MIX_SRC4_MASK 0x007F /* LHPF2MIX_SRC4 - [6:0] */
-#define WM2200_LHPF2MIX_SRC4_SHIFT 0 /* LHPF2MIX_SRC4 - [6:0] */
-#define WM2200_LHPF2MIX_SRC4_WIDTH 7 /* LHPF2MIX_SRC4 - [6:0] */
-
-/*
- * R1647 (0x66F) - LHPF2MIX Input 4 Volume
- */
-#define WM2200_LHPF2MIX_VOL4_MASK 0x00FE /* LHPF2MIX_VOL4 - [7:1] */
-#define WM2200_LHPF2MIX_VOL4_SHIFT 1 /* LHPF2MIX_VOL4 - [7:1] */
-#define WM2200_LHPF2MIX_VOL4_WIDTH 7 /* LHPF2MIX_VOL4 - [7:1] */
-
-/*
- * R1648 (0x670) - DSP1LMIX Input 1 Source
- */
-#define WM2200_DSP1LMIX_SRC1_MASK 0x007F /* DSP1LMIX_SRC1 - [6:0] */
-#define WM2200_DSP1LMIX_SRC1_SHIFT 0 /* DSP1LMIX_SRC1 - [6:0] */
-#define WM2200_DSP1LMIX_SRC1_WIDTH 7 /* DSP1LMIX_SRC1 - [6:0] */
-
-/*
- * R1649 (0x671) - DSP1LMIX Input 1 Volume
- */
-#define WM2200_DSP1LMIX_VOL1_MASK 0x00FE /* DSP1LMIX_VOL1 - [7:1] */
-#define WM2200_DSP1LMIX_VOL1_SHIFT 1 /* DSP1LMIX_VOL1 - [7:1] */
-#define WM2200_DSP1LMIX_VOL1_WIDTH 7 /* DSP1LMIX_VOL1 - [7:1] */
-
-/*
- * R1650 (0x672) - DSP1LMIX Input 2 Source
- */
-#define WM2200_DSP1LMIX_SRC2_MASK 0x007F /* DSP1LMIX_SRC2 - [6:0] */
-#define WM2200_DSP1LMIX_SRC2_SHIFT 0 /* DSP1LMIX_SRC2 - [6:0] */
-#define WM2200_DSP1LMIX_SRC2_WIDTH 7 /* DSP1LMIX_SRC2 - [6:0] */
-
-/*
- * R1651 (0x673) - DSP1LMIX Input 2 Volume
- */
-#define WM2200_DSP1LMIX_VOL2_MASK 0x00FE /* DSP1LMIX_VOL2 - [7:1] */
-#define WM2200_DSP1LMIX_VOL2_SHIFT 1 /* DSP1LMIX_VOL2 - [7:1] */
-#define WM2200_DSP1LMIX_VOL2_WIDTH 7 /* DSP1LMIX_VOL2 - [7:1] */
-
-/*
- * R1652 (0x674) - DSP1LMIX Input 3 Source
- */
-#define WM2200_DSP1LMIX_SRC3_MASK 0x007F /* DSP1LMIX_SRC3 - [6:0] */
-#define WM2200_DSP1LMIX_SRC3_SHIFT 0 /* DSP1LMIX_SRC3 - [6:0] */
-#define WM2200_DSP1LMIX_SRC3_WIDTH 7 /* DSP1LMIX_SRC3 - [6:0] */
-
-/*
- * R1653 (0x675) - DSP1LMIX Input 3 Volume
- */
-#define WM2200_DSP1LMIX_VOL3_MASK 0x00FE /* DSP1LMIX_VOL3 - [7:1] */
-#define WM2200_DSP1LMIX_VOL3_SHIFT 1 /* DSP1LMIX_VOL3 - [7:1] */
-#define WM2200_DSP1LMIX_VOL3_WIDTH 7 /* DSP1LMIX_VOL3 - [7:1] */
-
-/*
- * R1654 (0x676) - DSP1LMIX Input 4 Source
- */
-#define WM2200_DSP1LMIX_SRC4_MASK 0x007F /* DSP1LMIX_SRC4 - [6:0] */
-#define WM2200_DSP1LMIX_SRC4_SHIFT 0 /* DSP1LMIX_SRC4 - [6:0] */
-#define WM2200_DSP1LMIX_SRC4_WIDTH 7 /* DSP1LMIX_SRC4 - [6:0] */
-
-/*
- * R1655 (0x677) - DSP1LMIX Input 4 Volume
- */
-#define WM2200_DSP1LMIX_VOL4_MASK 0x00FE /* DSP1LMIX_VOL4 - [7:1] */
-#define WM2200_DSP1LMIX_VOL4_SHIFT 1 /* DSP1LMIX_VOL4 - [7:1] */
-#define WM2200_DSP1LMIX_VOL4_WIDTH 7 /* DSP1LMIX_VOL4 - [7:1] */
-
-/*
- * R1656 (0x678) - DSP1RMIX Input 1 Source
- */
-#define WM2200_DSP1RMIX_SRC1_MASK 0x007F /* DSP1RMIX_SRC1 - [6:0] */
-#define WM2200_DSP1RMIX_SRC1_SHIFT 0 /* DSP1RMIX_SRC1 - [6:0] */
-#define WM2200_DSP1RMIX_SRC1_WIDTH 7 /* DSP1RMIX_SRC1 - [6:0] */
-
-/*
- * R1657 (0x679) - DSP1RMIX Input 1 Volume
- */
-#define WM2200_DSP1RMIX_VOL1_MASK 0x00FE /* DSP1RMIX_VOL1 - [7:1] */
-#define WM2200_DSP1RMIX_VOL1_SHIFT 1 /* DSP1RMIX_VOL1 - [7:1] */
-#define WM2200_DSP1RMIX_VOL1_WIDTH 7 /* DSP1RMIX_VOL1 - [7:1] */
-
-/*
- * R1658 (0x67A) - DSP1RMIX Input 2 Source
- */
-#define WM2200_DSP1RMIX_SRC2_MASK 0x007F /* DSP1RMIX_SRC2 - [6:0] */
-#define WM2200_DSP1RMIX_SRC2_SHIFT 0 /* DSP1RMIX_SRC2 - [6:0] */
-#define WM2200_DSP1RMIX_SRC2_WIDTH 7 /* DSP1RMIX_SRC2 - [6:0] */
-
-/*
- * R1659 (0x67B) - DSP1RMIX Input 2 Volume
- */
-#define WM2200_DSP1RMIX_VOL2_MASK 0x00FE /* DSP1RMIX_VOL2 - [7:1] */
-#define WM2200_DSP1RMIX_VOL2_SHIFT 1 /* DSP1RMIX_VOL2 - [7:1] */
-#define WM2200_DSP1RMIX_VOL2_WIDTH 7 /* DSP1RMIX_VOL2 - [7:1] */
-
-/*
- * R1660 (0x67C) - DSP1RMIX Input 3 Source
- */
-#define WM2200_DSP1RMIX_SRC3_MASK 0x007F /* DSP1RMIX_SRC3 - [6:0] */
-#define WM2200_DSP1RMIX_SRC3_SHIFT 0 /* DSP1RMIX_SRC3 - [6:0] */
-#define WM2200_DSP1RMIX_SRC3_WIDTH 7 /* DSP1RMIX_SRC3 - [6:0] */
-
-/*
- * R1661 (0x67D) - DSP1RMIX Input 3 Volume
- */
-#define WM2200_DSP1RMIX_VOL3_MASK 0x00FE /* DSP1RMIX_VOL3 - [7:1] */
-#define WM2200_DSP1RMIX_VOL3_SHIFT 1 /* DSP1RMIX_VOL3 - [7:1] */
-#define WM2200_DSP1RMIX_VOL3_WIDTH 7 /* DSP1RMIX_VOL3 - [7:1] */
-
-/*
- * R1662 (0x67E) - DSP1RMIX Input 4 Source
- */
-#define WM2200_DSP1RMIX_SRC4_MASK 0x007F /* DSP1RMIX_SRC4 - [6:0] */
-#define WM2200_DSP1RMIX_SRC4_SHIFT 0 /* DSP1RMIX_SRC4 - [6:0] */
-#define WM2200_DSP1RMIX_SRC4_WIDTH 7 /* DSP1RMIX_SRC4 - [6:0] */
-
-/*
- * R1663 (0x67F) - DSP1RMIX Input 4 Volume
- */
-#define WM2200_DSP1RMIX_VOL4_MASK 0x00FE /* DSP1RMIX_VOL4 - [7:1] */
-#define WM2200_DSP1RMIX_VOL4_SHIFT 1 /* DSP1RMIX_VOL4 - [7:1] */
-#define WM2200_DSP1RMIX_VOL4_WIDTH 7 /* DSP1RMIX_VOL4 - [7:1] */
-
-/*
- * R1664 (0x680) - DSP1AUX1MIX Input 1 Source
- */
-#define WM2200_DSP1AUX1MIX_SRC1_MASK 0x007F /* DSP1AUX1MIX_SRC1 - [6:0] */
-#define WM2200_DSP1AUX1MIX_SRC1_SHIFT 0 /* DSP1AUX1MIX_SRC1 - [6:0] */
-#define WM2200_DSP1AUX1MIX_SRC1_WIDTH 7 /* DSP1AUX1MIX_SRC1 - [6:0] */
-
-/*
- * R1665 (0x681) - DSP1AUX2MIX Input 1 Source
- */
-#define WM2200_DSP1AUX2MIX_SRC1_MASK 0x007F /* DSP1AUX2MIX_SRC1 - [6:0] */
-#define WM2200_DSP1AUX2MIX_SRC1_SHIFT 0 /* DSP1AUX2MIX_SRC1 - [6:0] */
-#define WM2200_DSP1AUX2MIX_SRC1_WIDTH 7 /* DSP1AUX2MIX_SRC1 - [6:0] */
-
-/*
- * R1666 (0x682) - DSP1AUX3MIX Input 1 Source
- */
-#define WM2200_DSP1AUX3MIX_SRC1_MASK 0x007F /* DSP1AUX3MIX_SRC1 - [6:0] */
-#define WM2200_DSP1AUX3MIX_SRC1_SHIFT 0 /* DSP1AUX3MIX_SRC1 - [6:0] */
-#define WM2200_DSP1AUX3MIX_SRC1_WIDTH 7 /* DSP1AUX3MIX_SRC1 - [6:0] */
-
-/*
- * R1667 (0x683) - DSP1AUX4MIX Input 1 Source
- */
-#define WM2200_DSP1AUX4MIX_SRC1_MASK 0x007F /* DSP1AUX4MIX_SRC1 - [6:0] */
-#define WM2200_DSP1AUX4MIX_SRC1_SHIFT 0 /* DSP1AUX4MIX_SRC1 - [6:0] */
-#define WM2200_DSP1AUX4MIX_SRC1_WIDTH 7 /* DSP1AUX4MIX_SRC1 - [6:0] */
-
-/*
- * R1668 (0x684) - DSP1AUX5MIX Input 1 Source
- */
-#define WM2200_DSP1AUX5MIX_SRC1_MASK 0x007F /* DSP1AUX5MIX_SRC1 - [6:0] */
-#define WM2200_DSP1AUX5MIX_SRC1_SHIFT 0 /* DSP1AUX5MIX_SRC1 - [6:0] */
-#define WM2200_DSP1AUX5MIX_SRC1_WIDTH 7 /* DSP1AUX5MIX_SRC1 - [6:0] */
-
-/*
- * R1669 (0x685) - DSP1AUX6MIX Input 1 Source
- */
-#define WM2200_DSP1AUX6MIX_SRC1_MASK 0x007F /* DSP1AUX6MIX_SRC1 - [6:0] */
-#define WM2200_DSP1AUX6MIX_SRC1_SHIFT 0 /* DSP1AUX6MIX_SRC1 - [6:0] */
-#define WM2200_DSP1AUX6MIX_SRC1_WIDTH 7 /* DSP1AUX6MIX_SRC1 - [6:0] */
-
-/*
- * R1670 (0x686) - DSP2LMIX Input 1 Source
- */
-#define WM2200_DSP2LMIX_SRC1_MASK 0x007F /* DSP2LMIX_SRC1 - [6:0] */
-#define WM2200_DSP2LMIX_SRC1_SHIFT 0 /* DSP2LMIX_SRC1 - [6:0] */
-#define WM2200_DSP2LMIX_SRC1_WIDTH 7 /* DSP2LMIX_SRC1 - [6:0] */
-
-/*
- * R1671 (0x687) - DSP2LMIX Input 1 Volume
- */
-#define WM2200_DSP2LMIX_VOL1_MASK 0x00FE /* DSP2LMIX_VOL1 - [7:1] */
-#define WM2200_DSP2LMIX_VOL1_SHIFT 1 /* DSP2LMIX_VOL1 - [7:1] */
-#define WM2200_DSP2LMIX_VOL1_WIDTH 7 /* DSP2LMIX_VOL1 - [7:1] */
-
-/*
- * R1672 (0x688) - DSP2LMIX Input 2 Source
- */
-#define WM2200_DSP2LMIX_SRC2_MASK 0x007F /* DSP2LMIX_SRC2 - [6:0] */
-#define WM2200_DSP2LMIX_SRC2_SHIFT 0 /* DSP2LMIX_SRC2 - [6:0] */
-#define WM2200_DSP2LMIX_SRC2_WIDTH 7 /* DSP2LMIX_SRC2 - [6:0] */
-
-/*
- * R1673 (0x689) - DSP2LMIX Input 2 Volume
- */
-#define WM2200_DSP2LMIX_VOL2_MASK 0x00FE /* DSP2LMIX_VOL2 - [7:1] */
-#define WM2200_DSP2LMIX_VOL2_SHIFT 1 /* DSP2LMIX_VOL2 - [7:1] */
-#define WM2200_DSP2LMIX_VOL2_WIDTH 7 /* DSP2LMIX_VOL2 - [7:1] */
-
-/*
- * R1674 (0x68A) - DSP2LMIX Input 3 Source
- */
-#define WM2200_DSP2LMIX_SRC3_MASK 0x007F /* DSP2LMIX_SRC3 - [6:0] */
-#define WM2200_DSP2LMIX_SRC3_SHIFT 0 /* DSP2LMIX_SRC3 - [6:0] */
-#define WM2200_DSP2LMIX_SRC3_WIDTH 7 /* DSP2LMIX_SRC3 - [6:0] */
-
-/*
- * R1675 (0x68B) - DSP2LMIX Input 3 Volume
- */
-#define WM2200_DSP2LMIX_VOL3_MASK 0x00FE /* DSP2LMIX_VOL3 - [7:1] */
-#define WM2200_DSP2LMIX_VOL3_SHIFT 1 /* DSP2LMIX_VOL3 - [7:1] */
-#define WM2200_DSP2LMIX_VOL3_WIDTH 7 /* DSP2LMIX_VOL3 - [7:1] */
-
-/*
- * R1676 (0x68C) - DSP2LMIX Input 4 Source
- */
-#define WM2200_DSP2LMIX_SRC4_MASK 0x007F /* DSP2LMIX_SRC4 - [6:0] */
-#define WM2200_DSP2LMIX_SRC4_SHIFT 0 /* DSP2LMIX_SRC4 - [6:0] */
-#define WM2200_DSP2LMIX_SRC4_WIDTH 7 /* DSP2LMIX_SRC4 - [6:0] */
-
-/*
- * R1677 (0x68D) - DSP2LMIX Input 4 Volume
- */
-#define WM2200_DSP2LMIX_VOL4_MASK 0x00FE /* DSP2LMIX_VOL4 - [7:1] */
-#define WM2200_DSP2LMIX_VOL4_SHIFT 1 /* DSP2LMIX_VOL4 - [7:1] */
-#define WM2200_DSP2LMIX_VOL4_WIDTH 7 /* DSP2LMIX_VOL4 - [7:1] */
-
-/*
- * R1678 (0x68E) - DSP2RMIX Input 1 Source
- */
-#define WM2200_DSP2RMIX_SRC1_MASK 0x007F /* DSP2RMIX_SRC1 - [6:0] */
-#define WM2200_DSP2RMIX_SRC1_SHIFT 0 /* DSP2RMIX_SRC1 - [6:0] */
-#define WM2200_DSP2RMIX_SRC1_WIDTH 7 /* DSP2RMIX_SRC1 - [6:0] */
-
-/*
- * R1679 (0x68F) - DSP2RMIX Input 1 Volume
- */
-#define WM2200_DSP2RMIX_VOL1_MASK 0x00FE /* DSP2RMIX_VOL1 - [7:1] */
-#define WM2200_DSP2RMIX_VOL1_SHIFT 1 /* DSP2RMIX_VOL1 - [7:1] */
-#define WM2200_DSP2RMIX_VOL1_WIDTH 7 /* DSP2RMIX_VOL1 - [7:1] */
-
-/*
- * R1680 (0x690) - DSP2RMIX Input 2 Source
- */
-#define WM2200_DSP2RMIX_SRC2_MASK 0x007F /* DSP2RMIX_SRC2 - [6:0] */
-#define WM2200_DSP2RMIX_SRC2_SHIFT 0 /* DSP2RMIX_SRC2 - [6:0] */
-#define WM2200_DSP2RMIX_SRC2_WIDTH 7 /* DSP2RMIX_SRC2 - [6:0] */
-
-/*
- * R1681 (0x691) - DSP2RMIX Input 2 Volume
- */
-#define WM2200_DSP2RMIX_VOL2_MASK 0x00FE /* DSP2RMIX_VOL2 - [7:1] */
-#define WM2200_DSP2RMIX_VOL2_SHIFT 1 /* DSP2RMIX_VOL2 - [7:1] */
-#define WM2200_DSP2RMIX_VOL2_WIDTH 7 /* DSP2RMIX_VOL2 - [7:1] */
-
-/*
- * R1682 (0x692) - DSP2RMIX Input 3 Source
- */
-#define WM2200_DSP2RMIX_SRC3_MASK 0x007F /* DSP2RMIX_SRC3 - [6:0] */
-#define WM2200_DSP2RMIX_SRC3_SHIFT 0 /* DSP2RMIX_SRC3 - [6:0] */
-#define WM2200_DSP2RMIX_SRC3_WIDTH 7 /* DSP2RMIX_SRC3 - [6:0] */
-
-/*
- * R1683 (0x693) - DSP2RMIX Input 3 Volume
- */
-#define WM2200_DSP2RMIX_VOL3_MASK 0x00FE /* DSP2RMIX_VOL3 - [7:1] */
-#define WM2200_DSP2RMIX_VOL3_SHIFT 1 /* DSP2RMIX_VOL3 - [7:1] */
-#define WM2200_DSP2RMIX_VOL3_WIDTH 7 /* DSP2RMIX_VOL3 - [7:1] */
-
-/*
- * R1684 (0x694) - DSP2RMIX Input 4 Source
- */
-#define WM2200_DSP2RMIX_SRC4_MASK 0x007F /* DSP2RMIX_SRC4 - [6:0] */
-#define WM2200_DSP2RMIX_SRC4_SHIFT 0 /* DSP2RMIX_SRC4 - [6:0] */
-#define WM2200_DSP2RMIX_SRC4_WIDTH 7 /* DSP2RMIX_SRC4 - [6:0] */
-
-/*
- * R1685 (0x695) - DSP2RMIX Input 4 Volume
- */
-#define WM2200_DSP2RMIX_VOL4_MASK 0x00FE /* DSP2RMIX_VOL4 - [7:1] */
-#define WM2200_DSP2RMIX_VOL4_SHIFT 1 /* DSP2RMIX_VOL4 - [7:1] */
-#define WM2200_DSP2RMIX_VOL4_WIDTH 7 /* DSP2RMIX_VOL4 - [7:1] */
-
-/*
- * R1686 (0x696) - DSP2AUX1MIX Input 1 Source
- */
-#define WM2200_DSP2AUX1MIX_SRC1_MASK 0x007F /* DSP2AUX1MIX_SRC1 - [6:0] */
-#define WM2200_DSP2AUX1MIX_SRC1_SHIFT 0 /* DSP2AUX1MIX_SRC1 - [6:0] */
-#define WM2200_DSP2AUX1MIX_SRC1_WIDTH 7 /* DSP2AUX1MIX_SRC1 - [6:0] */
-
-/*
- * R1687 (0x697) - DSP2AUX2MIX Input 1 Source
- */
-#define WM2200_DSP2AUX2MIX_SRC1_MASK 0x007F /* DSP2AUX2MIX_SRC1 - [6:0] */
-#define WM2200_DSP2AUX2MIX_SRC1_SHIFT 0 /* DSP2AUX2MIX_SRC1 - [6:0] */
-#define WM2200_DSP2AUX2MIX_SRC1_WIDTH 7 /* DSP2AUX2MIX_SRC1 - [6:0] */
-
-/*
- * R1688 (0x698) - DSP2AUX3MIX Input 1 Source
- */
-#define WM2200_DSP2AUX3MIX_SRC1_MASK 0x007F /* DSP2AUX3MIX_SRC1 - [6:0] */
-#define WM2200_DSP2AUX3MIX_SRC1_SHIFT 0 /* DSP2AUX3MIX_SRC1 - [6:0] */
-#define WM2200_DSP2AUX3MIX_SRC1_WIDTH 7 /* DSP2AUX3MIX_SRC1 - [6:0] */
-
-/*
- * R1689 (0x699) - DSP2AUX4MIX Input 1 Source
- */
-#define WM2200_DSP2AUX4MIX_SRC1_MASK 0x007F /* DSP2AUX4MIX_SRC1 - [6:0] */
-#define WM2200_DSP2AUX4MIX_SRC1_SHIFT 0 /* DSP2AUX4MIX_SRC1 - [6:0] */
-#define WM2200_DSP2AUX4MIX_SRC1_WIDTH 7 /* DSP2AUX4MIX_SRC1 - [6:0] */
-
-/*
- * R1690 (0x69A) - DSP2AUX5MIX Input 1 Source
- */
-#define WM2200_DSP2AUX5MIX_SRC1_MASK 0x007F /* DSP2AUX5MIX_SRC1 - [6:0] */
-#define WM2200_DSP2AUX5MIX_SRC1_SHIFT 0 /* DSP2AUX5MIX_SRC1 - [6:0] */
-#define WM2200_DSP2AUX5MIX_SRC1_WIDTH 7 /* DSP2AUX5MIX_SRC1 - [6:0] */
-
-/*
- * R1691 (0x69B) - DSP2AUX6MIX Input 1 Source
- */
-#define WM2200_DSP2AUX6MIX_SRC1_MASK 0x007F /* DSP2AUX6MIX_SRC1 - [6:0] */
-#define WM2200_DSP2AUX6MIX_SRC1_SHIFT 0 /* DSP2AUX6MIX_SRC1 - [6:0] */
-#define WM2200_DSP2AUX6MIX_SRC1_WIDTH 7 /* DSP2AUX6MIX_SRC1 - [6:0] */
-
-/*
- * R1792 (0x700) - GPIO CTRL 1
- */
-#define WM2200_GP1_DIR 0x8000 /* GP1_DIR */
-#define WM2200_GP1_DIR_MASK 0x8000 /* GP1_DIR */
-#define WM2200_GP1_DIR_SHIFT 15 /* GP1_DIR */
-#define WM2200_GP1_DIR_WIDTH 1 /* GP1_DIR */
-#define WM2200_GP1_PU 0x4000 /* GP1_PU */
-#define WM2200_GP1_PU_MASK 0x4000 /* GP1_PU */
-#define WM2200_GP1_PU_SHIFT 14 /* GP1_PU */
-#define WM2200_GP1_PU_WIDTH 1 /* GP1_PU */
-#define WM2200_GP1_PD 0x2000 /* GP1_PD */
-#define WM2200_GP1_PD_MASK 0x2000 /* GP1_PD */
-#define WM2200_GP1_PD_SHIFT 13 /* GP1_PD */
-#define WM2200_GP1_PD_WIDTH 1 /* GP1_PD */
-#define WM2200_GP1_POL 0x0400 /* GP1_POL */
-#define WM2200_GP1_POL_MASK 0x0400 /* GP1_POL */
-#define WM2200_GP1_POL_SHIFT 10 /* GP1_POL */
-#define WM2200_GP1_POL_WIDTH 1 /* GP1_POL */
-#define WM2200_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */
-#define WM2200_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */
-#define WM2200_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */
-#define WM2200_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
-#define WM2200_GP1_DB 0x0100 /* GP1_DB */
-#define WM2200_GP1_DB_MASK 0x0100 /* GP1_DB */
-#define WM2200_GP1_DB_SHIFT 8 /* GP1_DB */
-#define WM2200_GP1_DB_WIDTH 1 /* GP1_DB */
-#define WM2200_GP1_LVL 0x0040 /* GP1_LVL */
-#define WM2200_GP1_LVL_MASK 0x0040 /* GP1_LVL */
-#define WM2200_GP1_LVL_SHIFT 6 /* GP1_LVL */
-#define WM2200_GP1_LVL_WIDTH 1 /* GP1_LVL */
-#define WM2200_GP1_FN_MASK 0x003F /* GP1_FN - [5:0] */
-#define WM2200_GP1_FN_SHIFT 0 /* GP1_FN - [5:0] */
-#define WM2200_GP1_FN_WIDTH 6 /* GP1_FN - [5:0] */
-
-/*
- * R1793 (0x701) - GPIO CTRL 2
- */
-#define WM2200_GP2_DIR 0x8000 /* GP2_DIR */
-#define WM2200_GP2_DIR_MASK 0x8000 /* GP2_DIR */
-#define WM2200_GP2_DIR_SHIFT 15 /* GP2_DIR */
-#define WM2200_GP2_DIR_WIDTH 1 /* GP2_DIR */
-#define WM2200_GP2_PU 0x4000 /* GP2_PU */
-#define WM2200_GP2_PU_MASK 0x4000 /* GP2_PU */
-#define WM2200_GP2_PU_SHIFT 14 /* GP2_PU */
-#define WM2200_GP2_PU_WIDTH 1 /* GP2_PU */
-#define WM2200_GP2_PD 0x2000 /* GP2_PD */
-#define WM2200_GP2_PD_MASK 0x2000 /* GP2_PD */
-#define WM2200_GP2_PD_SHIFT 13 /* GP2_PD */
-#define WM2200_GP2_PD_WIDTH 1 /* GP2_PD */
-#define WM2200_GP2_POL 0x0400 /* GP2_POL */
-#define WM2200_GP2_POL_MASK 0x0400 /* GP2_POL */
-#define WM2200_GP2_POL_SHIFT 10 /* GP2_POL */
-#define WM2200_GP2_POL_WIDTH 1 /* GP2_POL */
-#define WM2200_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */
-#define WM2200_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */
-#define WM2200_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */
-#define WM2200_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
-#define WM2200_GP2_DB 0x0100 /* GP2_DB */
-#define WM2200_GP2_DB_MASK 0x0100 /* GP2_DB */
-#define WM2200_GP2_DB_SHIFT 8 /* GP2_DB */
-#define WM2200_GP2_DB_WIDTH 1 /* GP2_DB */
-#define WM2200_GP2_LVL 0x0040 /* GP2_LVL */
-#define WM2200_GP2_LVL_MASK 0x0040 /* GP2_LVL */
-#define WM2200_GP2_LVL_SHIFT 6 /* GP2_LVL */
-#define WM2200_GP2_LVL_WIDTH 1 /* GP2_LVL */
-#define WM2200_GP2_FN_MASK 0x003F /* GP2_FN - [5:0] */
-#define WM2200_GP2_FN_SHIFT 0 /* GP2_FN - [5:0] */
-#define WM2200_GP2_FN_WIDTH 6 /* GP2_FN - [5:0] */
-
-/*
- * R1794 (0x702) - GPIO CTRL 3
- */
-#define WM2200_GP3_DIR 0x8000 /* GP3_DIR */
-#define WM2200_GP3_DIR_MASK 0x8000 /* GP3_DIR */
-#define WM2200_GP3_DIR_SHIFT 15 /* GP3_DIR */
-#define WM2200_GP3_DIR_WIDTH 1 /* GP3_DIR */
-#define WM2200_GP3_PU 0x4000 /* GP3_PU */
-#define WM2200_GP3_PU_MASK 0x4000 /* GP3_PU */
-#define WM2200_GP3_PU_SHIFT 14 /* GP3_PU */
-#define WM2200_GP3_PU_WIDTH 1 /* GP3_PU */
-#define WM2200_GP3_PD 0x2000 /* GP3_PD */
-#define WM2200_GP3_PD_MASK 0x2000 /* GP3_PD */
-#define WM2200_GP3_PD_SHIFT 13 /* GP3_PD */
-#define WM2200_GP3_PD_WIDTH 1 /* GP3_PD */
-#define WM2200_GP3_POL 0x0400 /* GP3_POL */
-#define WM2200_GP3_POL_MASK 0x0400 /* GP3_POL */
-#define WM2200_GP3_POL_SHIFT 10 /* GP3_POL */
-#define WM2200_GP3_POL_WIDTH 1 /* GP3_POL */
-#define WM2200_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */
-#define WM2200_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */
-#define WM2200_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */
-#define WM2200_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
-#define WM2200_GP3_DB 0x0100 /* GP3_DB */
-#define WM2200_GP3_DB_MASK 0x0100 /* GP3_DB */
-#define WM2200_GP3_DB_SHIFT 8 /* GP3_DB */
-#define WM2200_GP3_DB_WIDTH 1 /* GP3_DB */
-#define WM2200_GP3_LVL 0x0040 /* GP3_LVL */
-#define WM2200_GP3_LVL_MASK 0x0040 /* GP3_LVL */
-#define WM2200_GP3_LVL_SHIFT 6 /* GP3_LVL */
-#define WM2200_GP3_LVL_WIDTH 1 /* GP3_LVL */
-#define WM2200_GP3_FN_MASK 0x003F /* GP3_FN - [5:0] */
-#define WM2200_GP3_FN_SHIFT 0 /* GP3_FN - [5:0] */
-#define WM2200_GP3_FN_WIDTH 6 /* GP3_FN - [5:0] */
-
-/*
- * R1795 (0x703) - GPIO CTRL 4
- */
-#define WM2200_GP4_DIR 0x8000 /* GP4_DIR */
-#define WM2200_GP4_DIR_MASK 0x8000 /* GP4_DIR */
-#define WM2200_GP4_DIR_SHIFT 15 /* GP4_DIR */
-#define WM2200_GP4_DIR_WIDTH 1 /* GP4_DIR */
-#define WM2200_GP4_PU 0x4000 /* GP4_PU */
-#define WM2200_GP4_PU_MASK 0x4000 /* GP4_PU */
-#define WM2200_GP4_PU_SHIFT 14 /* GP4_PU */
-#define WM2200_GP4_PU_WIDTH 1 /* GP4_PU */
-#define WM2200_GP4_PD 0x2000 /* GP4_PD */
-#define WM2200_GP4_PD_MASK 0x2000 /* GP4_PD */
-#define WM2200_GP4_PD_SHIFT 13 /* GP4_PD */
-#define WM2200_GP4_PD_WIDTH 1 /* GP4_PD */
-#define WM2200_GP4_POL 0x0400 /* GP4_POL */
-#define WM2200_GP4_POL_MASK 0x0400 /* GP4_POL */
-#define WM2200_GP4_POL_SHIFT 10 /* GP4_POL */
-#define WM2200_GP4_POL_WIDTH 1 /* GP4_POL */
-#define WM2200_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */
-#define WM2200_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */
-#define WM2200_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */
-#define WM2200_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
-#define WM2200_GP4_DB 0x0100 /* GP4_DB */
-#define WM2200_GP4_DB_MASK 0x0100 /* GP4_DB */
-#define WM2200_GP4_DB_SHIFT 8 /* GP4_DB */
-#define WM2200_GP4_DB_WIDTH 1 /* GP4_DB */
-#define WM2200_GP4_LVL 0x0040 /* GP4_LVL */
-#define WM2200_GP4_LVL_MASK 0x0040 /* GP4_LVL */
-#define WM2200_GP4_LVL_SHIFT 6 /* GP4_LVL */
-#define WM2200_GP4_LVL_WIDTH 1 /* GP4_LVL */
-#define WM2200_GP4_FN_MASK 0x003F /* GP4_FN - [5:0] */
-#define WM2200_GP4_FN_SHIFT 0 /* GP4_FN - [5:0] */
-#define WM2200_GP4_FN_WIDTH 6 /* GP4_FN - [5:0] */
-
-/*
- * R1799 (0x707) - ADPS1 IRQ0
- */
-#define WM2200_DSP_IRQ1 0x0002 /* DSP_IRQ1 */
-#define WM2200_DSP_IRQ1_MASK 0x0002 /* DSP_IRQ1 */
-#define WM2200_DSP_IRQ1_SHIFT 1 /* DSP_IRQ1 */
-#define WM2200_DSP_IRQ1_WIDTH 1 /* DSP_IRQ1 */
-#define WM2200_DSP_IRQ0 0x0001 /* DSP_IRQ0 */
-#define WM2200_DSP_IRQ0_MASK 0x0001 /* DSP_IRQ0 */
-#define WM2200_DSP_IRQ0_SHIFT 0 /* DSP_IRQ0 */
-#define WM2200_DSP_IRQ0_WIDTH 1 /* DSP_IRQ0 */
-
-/*
- * R1800 (0x708) - ADPS1 IRQ1
- */
-#define WM2200_DSP_IRQ3 0x0002 /* DSP_IRQ3 */
-#define WM2200_DSP_IRQ3_MASK 0x0002 /* DSP_IRQ3 */
-#define WM2200_DSP_IRQ3_SHIFT 1 /* DSP_IRQ3 */
-#define WM2200_DSP_IRQ3_WIDTH 1 /* DSP_IRQ3 */
-#define WM2200_DSP_IRQ2 0x0001 /* DSP_IRQ2 */
-#define WM2200_DSP_IRQ2_MASK 0x0001 /* DSP_IRQ2 */
-#define WM2200_DSP_IRQ2_SHIFT 0 /* DSP_IRQ2 */
-#define WM2200_DSP_IRQ2_WIDTH 1 /* DSP_IRQ2 */
-
-/*
- * R1801 (0x709) - Misc Pad Ctrl 1
- */
-#define WM2200_LDO1ENA_PD 0x8000 /* LDO1ENA_PD */
-#define WM2200_LDO1ENA_PD_MASK 0x8000 /* LDO1ENA_PD */
-#define WM2200_LDO1ENA_PD_SHIFT 15 /* LDO1ENA_PD */
-#define WM2200_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */
-#define WM2200_MCLK2_PD 0x2000 /* MCLK2_PD */
-#define WM2200_MCLK2_PD_MASK 0x2000 /* MCLK2_PD */
-#define WM2200_MCLK2_PD_SHIFT 13 /* MCLK2_PD */
-#define WM2200_MCLK2_PD_WIDTH 1 /* MCLK2_PD */
-#define WM2200_MCLK1_PD 0x1000 /* MCLK1_PD */
-#define WM2200_MCLK1_PD_MASK 0x1000 /* MCLK1_PD */
-#define WM2200_MCLK1_PD_SHIFT 12 /* MCLK1_PD */
-#define WM2200_MCLK1_PD_WIDTH 1 /* MCLK1_PD */
-#define WM2200_DACLRCLK1_PU 0x0400 /* DACLRCLK1_PU */
-#define WM2200_DACLRCLK1_PU_MASK 0x0400 /* DACLRCLK1_PU */
-#define WM2200_DACLRCLK1_PU_SHIFT 10 /* DACLRCLK1_PU */
-#define WM2200_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */
-#define WM2200_DACLRCLK1_PD 0x0200 /* DACLRCLK1_PD */
-#define WM2200_DACLRCLK1_PD_MASK 0x0200 /* DACLRCLK1_PD */
-#define WM2200_DACLRCLK1_PD_SHIFT 9 /* DACLRCLK1_PD */
-#define WM2200_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */
-#define WM2200_BCLK1_PU 0x0100 /* BCLK1_PU */
-#define WM2200_BCLK1_PU_MASK 0x0100 /* BCLK1_PU */
-#define WM2200_BCLK1_PU_SHIFT 8 /* BCLK1_PU */
-#define WM2200_BCLK1_PU_WIDTH 1 /* BCLK1_PU */
-#define WM2200_BCLK1_PD 0x0080 /* BCLK1_PD */
-#define WM2200_BCLK1_PD_MASK 0x0080 /* BCLK1_PD */
-#define WM2200_BCLK1_PD_SHIFT 7 /* BCLK1_PD */
-#define WM2200_BCLK1_PD_WIDTH 1 /* BCLK1_PD */
-#define WM2200_DACDAT1_PU 0x0040 /* DACDAT1_PU */
-#define WM2200_DACDAT1_PU_MASK 0x0040 /* DACDAT1_PU */
-#define WM2200_DACDAT1_PU_SHIFT 6 /* DACDAT1_PU */
-#define WM2200_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */
-#define WM2200_DACDAT1_PD 0x0020 /* DACDAT1_PD */
-#define WM2200_DACDAT1_PD_MASK 0x0020 /* DACDAT1_PD */
-#define WM2200_DACDAT1_PD_SHIFT 5 /* DACDAT1_PD */
-#define WM2200_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */
-#define WM2200_DMICDAT3_PD 0x0010 /* DMICDAT3_PD */
-#define WM2200_DMICDAT3_PD_MASK 0x0010 /* DMICDAT3_PD */
-#define WM2200_DMICDAT3_PD_SHIFT 4 /* DMICDAT3_PD */
-#define WM2200_DMICDAT3_PD_WIDTH 1 /* DMICDAT3_PD */
-#define WM2200_DMICDAT2_PD 0x0008 /* DMICDAT2_PD */
-#define WM2200_DMICDAT2_PD_MASK 0x0008 /* DMICDAT2_PD */
-#define WM2200_DMICDAT2_PD_SHIFT 3 /* DMICDAT2_PD */
-#define WM2200_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */
-#define WM2200_DMICDAT1_PD 0x0004 /* DMICDAT1_PD */
-#define WM2200_DMICDAT1_PD_MASK 0x0004 /* DMICDAT1_PD */
-#define WM2200_DMICDAT1_PD_SHIFT 2 /* DMICDAT1_PD */
-#define WM2200_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */
-#define WM2200_RSTB_PU 0x0002 /* RSTB_PU */
-#define WM2200_RSTB_PU_MASK 0x0002 /* RSTB_PU */
-#define WM2200_RSTB_PU_SHIFT 1 /* RSTB_PU */
-#define WM2200_RSTB_PU_WIDTH 1 /* RSTB_PU */
-#define WM2200_ADDR_PD 0x0001 /* ADDR_PD */
-#define WM2200_ADDR_PD_MASK 0x0001 /* ADDR_PD */
-#define WM2200_ADDR_PD_SHIFT 0 /* ADDR_PD */
-#define WM2200_ADDR_PD_WIDTH 1 /* ADDR_PD */
-
-/*
- * R2048 (0x800) - Interrupt Status 1
- */
-#define WM2200_DSP_IRQ0_EINT 0x0080 /* DSP_IRQ0_EINT */
-#define WM2200_DSP_IRQ0_EINT_MASK 0x0080 /* DSP_IRQ0_EINT */
-#define WM2200_DSP_IRQ0_EINT_SHIFT 7 /* DSP_IRQ0_EINT */
-#define WM2200_DSP_IRQ0_EINT_WIDTH 1 /* DSP_IRQ0_EINT */
-#define WM2200_DSP_IRQ1_EINT 0x0040 /* DSP_IRQ1_EINT */
-#define WM2200_DSP_IRQ1_EINT_MASK 0x0040 /* DSP_IRQ1_EINT */
-#define WM2200_DSP_IRQ1_EINT_SHIFT 6 /* DSP_IRQ1_EINT */
-#define WM2200_DSP_IRQ1_EINT_WIDTH 1 /* DSP_IRQ1_EINT */
-#define WM2200_DSP_IRQ2_EINT 0x0020 /* DSP_IRQ2_EINT */
-#define WM2200_DSP_IRQ2_EINT_MASK 0x0020 /* DSP_IRQ2_EINT */
-#define WM2200_DSP_IRQ2_EINT_SHIFT 5 /* DSP_IRQ2_EINT */
-#define WM2200_DSP_IRQ2_EINT_WIDTH 1 /* DSP_IRQ2_EINT */
-#define WM2200_DSP_IRQ3_EINT 0x0010 /* DSP_IRQ3_EINT */
-#define WM2200_DSP_IRQ3_EINT_MASK 0x0010 /* DSP_IRQ3_EINT */
-#define WM2200_DSP_IRQ3_EINT_SHIFT 4 /* DSP_IRQ3_EINT */
-#define WM2200_DSP_IRQ3_EINT_WIDTH 1 /* DSP_IRQ3_EINT */
-#define WM2200_GP4_EINT 0x0008 /* GP4_EINT */
-#define WM2200_GP4_EINT_MASK 0x0008 /* GP4_EINT */
-#define WM2200_GP4_EINT_SHIFT 3 /* GP4_EINT */
-#define WM2200_GP4_EINT_WIDTH 1 /* GP4_EINT */
-#define WM2200_GP3_EINT 0x0004 /* GP3_EINT */
-#define WM2200_GP3_EINT_MASK 0x0004 /* GP3_EINT */
-#define WM2200_GP3_EINT_SHIFT 2 /* GP3_EINT */
-#define WM2200_GP3_EINT_WIDTH 1 /* GP3_EINT */
-#define WM2200_GP2_EINT 0x0002 /* GP2_EINT */
-#define WM2200_GP2_EINT_MASK 0x0002 /* GP2_EINT */
-#define WM2200_GP2_EINT_SHIFT 1 /* GP2_EINT */
-#define WM2200_GP2_EINT_WIDTH 1 /* GP2_EINT */
-#define WM2200_GP1_EINT 0x0001 /* GP1_EINT */
-#define WM2200_GP1_EINT_MASK 0x0001 /* GP1_EINT */
-#define WM2200_GP1_EINT_SHIFT 0 /* GP1_EINT */
-#define WM2200_GP1_EINT_WIDTH 1 /* GP1_EINT */
-
-/*
- * R2049 (0x801) - Interrupt Status 1 Mask
- */
-#define WM2200_IM_DSP_IRQ0_EINT 0x0080 /* IM_DSP_IRQ0_EINT */
-#define WM2200_IM_DSP_IRQ0_EINT_MASK 0x0080 /* IM_DSP_IRQ0_EINT */
-#define WM2200_IM_DSP_IRQ0_EINT_SHIFT 7 /* IM_DSP_IRQ0_EINT */
-#define WM2200_IM_DSP_IRQ0_EINT_WIDTH 1 /* IM_DSP_IRQ0_EINT */
-#define WM2200_IM_DSP_IRQ1_EINT 0x0040 /* IM_DSP_IRQ1_EINT */
-#define WM2200_IM_DSP_IRQ1_EINT_MASK 0x0040 /* IM_DSP_IRQ1_EINT */
-#define WM2200_IM_DSP_IRQ1_EINT_SHIFT 6 /* IM_DSP_IRQ1_EINT */
-#define WM2200_IM_DSP_IRQ1_EINT_WIDTH 1 /* IM_DSP_IRQ1_EINT */
-#define WM2200_IM_DSP_IRQ2_EINT 0x0020 /* IM_DSP_IRQ2_EINT */
-#define WM2200_IM_DSP_IRQ2_EINT_MASK 0x0020 /* IM_DSP_IRQ2_EINT */
-#define WM2200_IM_DSP_IRQ2_EINT_SHIFT 5 /* IM_DSP_IRQ2_EINT */
-#define WM2200_IM_DSP_IRQ2_EINT_WIDTH 1 /* IM_DSP_IRQ2_EINT */
-#define WM2200_IM_DSP_IRQ3_EINT 0x0010 /* IM_DSP_IRQ3_EINT */
-#define WM2200_IM_DSP_IRQ3_EINT_MASK 0x0010 /* IM_DSP_IRQ3_EINT */
-#define WM2200_IM_DSP_IRQ3_EINT_SHIFT 4 /* IM_DSP_IRQ3_EINT */
-#define WM2200_IM_DSP_IRQ3_EINT_WIDTH 1 /* IM_DSP_IRQ3_EINT */
-#define WM2200_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
-#define WM2200_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
-#define WM2200_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
-#define WM2200_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
-#define WM2200_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
-#define WM2200_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
-#define WM2200_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
-#define WM2200_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
-#define WM2200_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
-#define WM2200_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
-#define WM2200_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
-#define WM2200_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
-#define WM2200_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
-#define WM2200_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
-#define WM2200_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
-#define WM2200_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
-
-/*
- * R2050 (0x802) - Interrupt Status 2
- */
-#define WM2200_WSEQ_BUSY_EINT 0x0100 /* WSEQ_BUSY_EINT */
-#define WM2200_WSEQ_BUSY_EINT_MASK 0x0100 /* WSEQ_BUSY_EINT */
-#define WM2200_WSEQ_BUSY_EINT_SHIFT 8 /* WSEQ_BUSY_EINT */
-#define WM2200_WSEQ_BUSY_EINT_WIDTH 1 /* WSEQ_BUSY_EINT */
-#define WM2200_FLL_LOCK_EINT 0x0002 /* FLL_LOCK_EINT */
-#define WM2200_FLL_LOCK_EINT_MASK 0x0002 /* FLL_LOCK_EINT */
-#define WM2200_FLL_LOCK_EINT_SHIFT 1 /* FLL_LOCK_EINT */
-#define WM2200_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */
-#define WM2200_CLKGEN_EINT 0x0001 /* CLKGEN_EINT */
-#define WM2200_CLKGEN_EINT_MASK 0x0001 /* CLKGEN_EINT */
-#define WM2200_CLKGEN_EINT_SHIFT 0 /* CLKGEN_EINT */
-#define WM2200_CLKGEN_EINT_WIDTH 1 /* CLKGEN_EINT */
-
-/*
- * R2051 (0x803) - Interrupt Raw Status 2
- */
-#define WM2200_WSEQ_BUSY_STS 0x0100 /* WSEQ_BUSY_STS */
-#define WM2200_WSEQ_BUSY_STS_MASK 0x0100 /* WSEQ_BUSY_STS */
-#define WM2200_WSEQ_BUSY_STS_SHIFT 8 /* WSEQ_BUSY_STS */
-#define WM2200_WSEQ_BUSY_STS_WIDTH 1 /* WSEQ_BUSY_STS */
-#define WM2200_FLL_LOCK_STS 0x0002 /* FLL_LOCK_STS */
-#define WM2200_FLL_LOCK_STS_MASK 0x0002 /* FLL_LOCK_STS */
-#define WM2200_FLL_LOCK_STS_SHIFT 1 /* FLL_LOCK_STS */
-#define WM2200_FLL_LOCK_STS_WIDTH 1 /* FLL_LOCK_STS */
-#define WM2200_CLKGEN_STS 0x0001 /* CLKGEN_STS */
-#define WM2200_CLKGEN_STS_MASK 0x0001 /* CLKGEN_STS */
-#define WM2200_CLKGEN_STS_SHIFT 0 /* CLKGEN_STS */
-#define WM2200_CLKGEN_STS_WIDTH 1 /* CLKGEN_STS */
-
-/*
- * R2052 (0x804) - Interrupt Status 2 Mask
- */
-#define WM2200_IM_WSEQ_BUSY_EINT 0x0100 /* IM_WSEQ_BUSY_EINT */
-#define WM2200_IM_WSEQ_BUSY_EINT_MASK 0x0100 /* IM_WSEQ_BUSY_EINT */
-#define WM2200_IM_WSEQ_BUSY_EINT_SHIFT 8 /* IM_WSEQ_BUSY_EINT */
-#define WM2200_IM_WSEQ_BUSY_EINT_WIDTH 1 /* IM_WSEQ_BUSY_EINT */
-#define WM2200_IM_FLL_LOCK_EINT 0x0002 /* IM_FLL_LOCK_EINT */
-#define WM2200_IM_FLL_LOCK_EINT_MASK 0x0002 /* IM_FLL_LOCK_EINT */
-#define WM2200_IM_FLL_LOCK_EINT_SHIFT 1 /* IM_FLL_LOCK_EINT */
-#define WM2200_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */
-#define WM2200_IM_CLKGEN_EINT 0x0001 /* IM_CLKGEN_EINT */
-#define WM2200_IM_CLKGEN_EINT_MASK 0x0001 /* IM_CLKGEN_EINT */
-#define WM2200_IM_CLKGEN_EINT_SHIFT 0 /* IM_CLKGEN_EINT */
-#define WM2200_IM_CLKGEN_EINT_WIDTH 1 /* IM_CLKGEN_EINT */
-
-/*
- * R2056 (0x808) - Interrupt Control
- */
-#define WM2200_IM_IRQ 0x0001 /* IM_IRQ */
-#define WM2200_IM_IRQ_MASK 0x0001 /* IM_IRQ */
-#define WM2200_IM_IRQ_SHIFT 0 /* IM_IRQ */
-#define WM2200_IM_IRQ_WIDTH 1 /* IM_IRQ */
-
-/*
- * R2304 (0x900) - EQL_1
- */
-#define WM2200_EQL_B1_GAIN_MASK 0xF800 /* EQL_B1_GAIN - [15:11] */
-#define WM2200_EQL_B1_GAIN_SHIFT 11 /* EQL_B1_GAIN - [15:11] */
-#define WM2200_EQL_B1_GAIN_WIDTH 5 /* EQL_B1_GAIN - [15:11] */
-#define WM2200_EQL_B2_GAIN_MASK 0x07C0 /* EQL_B2_GAIN - [10:6] */
-#define WM2200_EQL_B2_GAIN_SHIFT 6 /* EQL_B2_GAIN - [10:6] */
-#define WM2200_EQL_B2_GAIN_WIDTH 5 /* EQL_B2_GAIN - [10:6] */
-#define WM2200_EQL_B3_GAIN_MASK 0x003E /* EQL_B3_GAIN - [5:1] */
-#define WM2200_EQL_B3_GAIN_SHIFT 1 /* EQL_B3_GAIN - [5:1] */
-#define WM2200_EQL_B3_GAIN_WIDTH 5 /* EQL_B3_GAIN - [5:1] */
-#define WM2200_EQL_ENA 0x0001 /* EQL_ENA */
-#define WM2200_EQL_ENA_MASK 0x0001 /* EQL_ENA */
-#define WM2200_EQL_ENA_SHIFT 0 /* EQL_ENA */
-#define WM2200_EQL_ENA_WIDTH 1 /* EQL_ENA */
-
-/*
- * R2305 (0x901) - EQL_2
- */
-#define WM2200_EQL_B4_GAIN_MASK 0xF800 /* EQL_B4_GAIN - [15:11] */
-#define WM2200_EQL_B4_GAIN_SHIFT 11 /* EQL_B4_GAIN - [15:11] */
-#define WM2200_EQL_B4_GAIN_WIDTH 5 /* EQL_B4_GAIN - [15:11] */
-#define WM2200_EQL_B5_GAIN_MASK 0x07C0 /* EQL_B5_GAIN - [10:6] */
-#define WM2200_EQL_B5_GAIN_SHIFT 6 /* EQL_B5_GAIN - [10:6] */
-#define WM2200_EQL_B5_GAIN_WIDTH 5 /* EQL_B5_GAIN - [10:6] */
-
-/*
- * R2306 (0x902) - EQL_3
- */
-#define WM2200_EQL_B1_A_MASK 0xFFFF /* EQL_B1_A - [15:0] */
-#define WM2200_EQL_B1_A_SHIFT 0 /* EQL_B1_A - [15:0] */
-#define WM2200_EQL_B1_A_WIDTH 16 /* EQL_B1_A - [15:0] */
-
-/*
- * R2307 (0x903) - EQL_4
- */
-#define WM2200_EQL_B1_B_MASK 0xFFFF /* EQL_B1_B - [15:0] */
-#define WM2200_EQL_B1_B_SHIFT 0 /* EQL_B1_B - [15:0] */
-#define WM2200_EQL_B1_B_WIDTH 16 /* EQL_B1_B - [15:0] */
-
-/*
- * R2308 (0x904) - EQL_5
- */
-#define WM2200_EQL_B1_PG_MASK 0xFFFF /* EQL_B1_PG - [15:0] */
-#define WM2200_EQL_B1_PG_SHIFT 0 /* EQL_B1_PG - [15:0] */
-#define WM2200_EQL_B1_PG_WIDTH 16 /* EQL_B1_PG - [15:0] */
-
-/*
- * R2309 (0x905) - EQL_6
- */
-#define WM2200_EQL_B2_A_MASK 0xFFFF /* EQL_B2_A - [15:0] */
-#define WM2200_EQL_B2_A_SHIFT 0 /* EQL_B2_A - [15:0] */
-#define WM2200_EQL_B2_A_WIDTH 16 /* EQL_B2_A - [15:0] */
-
-/*
- * R2310 (0x906) - EQL_7
- */
-#define WM2200_EQL_B2_B_MASK 0xFFFF /* EQL_B2_B - [15:0] */
-#define WM2200_EQL_B2_B_SHIFT 0 /* EQL_B2_B - [15:0] */
-#define WM2200_EQL_B2_B_WIDTH 16 /* EQL_B2_B - [15:0] */
-
-/*
- * R2311 (0x907) - EQL_8
- */
-#define WM2200_EQL_B2_C_MASK 0xFFFF /* EQL_B2_C - [15:0] */
-#define WM2200_EQL_B2_C_SHIFT 0 /* EQL_B2_C - [15:0] */
-#define WM2200_EQL_B2_C_WIDTH 16 /* EQL_B2_C - [15:0] */
-
-/*
- * R2312 (0x908) - EQL_9
- */
-#define WM2200_EQL_B2_PG_MASK 0xFFFF /* EQL_B2_PG - [15:0] */
-#define WM2200_EQL_B2_PG_SHIFT 0 /* EQL_B2_PG - [15:0] */
-#define WM2200_EQL_B2_PG_WIDTH 16 /* EQL_B2_PG - [15:0] */
-
-/*
- * R2313 (0x909) - EQL_10
- */
-#define WM2200_EQL_B3_A_MASK 0xFFFF /* EQL_B3_A - [15:0] */
-#define WM2200_EQL_B3_A_SHIFT 0 /* EQL_B3_A - [15:0] */
-#define WM2200_EQL_B3_A_WIDTH 16 /* EQL_B3_A - [15:0] */
-
-/*
- * R2314 (0x90A) - EQL_11
- */
-#define WM2200_EQL_B3_B_MASK 0xFFFF /* EQL_B3_B - [15:0] */
-#define WM2200_EQL_B3_B_SHIFT 0 /* EQL_B3_B - [15:0] */
-#define WM2200_EQL_B3_B_WIDTH 16 /* EQL_B3_B - [15:0] */
-
-/*
- * R2315 (0x90B) - EQL_12
- */
-#define WM2200_EQL_B3_C_MASK 0xFFFF /* EQL_B3_C - [15:0] */
-#define WM2200_EQL_B3_C_SHIFT 0 /* EQL_B3_C - [15:0] */
-#define WM2200_EQL_B3_C_WIDTH 16 /* EQL_B3_C - [15:0] */
-
-/*
- * R2316 (0x90C) - EQL_13
- */
-#define WM2200_EQL_B3_PG_MASK 0xFFFF /* EQL_B3_PG - [15:0] */
-#define WM2200_EQL_B3_PG_SHIFT 0 /* EQL_B3_PG - [15:0] */
-#define WM2200_EQL_B3_PG_WIDTH 16 /* EQL_B3_PG - [15:0] */
-
-/*
- * R2317 (0x90D) - EQL_14
- */
-#define WM2200_EQL_B4_A_MASK 0xFFFF /* EQL_B4_A - [15:0] */
-#define WM2200_EQL_B4_A_SHIFT 0 /* EQL_B4_A - [15:0] */
-#define WM2200_EQL_B4_A_WIDTH 16 /* EQL_B4_A - [15:0] */
-
-/*
- * R2318 (0x90E) - EQL_15
- */
-#define WM2200_EQL_B4_B_MASK 0xFFFF /* EQL_B4_B - [15:0] */
-#define WM2200_EQL_B4_B_SHIFT 0 /* EQL_B4_B - [15:0] */
-#define WM2200_EQL_B4_B_WIDTH 16 /* EQL_B4_B - [15:0] */
-
-/*
- * R2319 (0x90F) - EQL_16
- */
-#define WM2200_EQL_B4_C_MASK 0xFFFF /* EQL_B4_C - [15:0] */
-#define WM2200_EQL_B4_C_SHIFT 0 /* EQL_B4_C - [15:0] */
-#define WM2200_EQL_B4_C_WIDTH 16 /* EQL_B4_C - [15:0] */
-
-/*
- * R2320 (0x910) - EQL_17
- */
-#define WM2200_EQL_B4_PG_MASK 0xFFFF /* EQL_B4_PG - [15:0] */
-#define WM2200_EQL_B4_PG_SHIFT 0 /* EQL_B4_PG - [15:0] */
-#define WM2200_EQL_B4_PG_WIDTH 16 /* EQL_B4_PG - [15:0] */
-
-/*
- * R2321 (0x911) - EQL_18
- */
-#define WM2200_EQL_B5_A_MASK 0xFFFF /* EQL_B5_A - [15:0] */
-#define WM2200_EQL_B5_A_SHIFT 0 /* EQL_B5_A - [15:0] */
-#define WM2200_EQL_B5_A_WIDTH 16 /* EQL_B5_A - [15:0] */
-
-/*
- * R2322 (0x912) - EQL_19
- */
-#define WM2200_EQL_B5_B_MASK 0xFFFF /* EQL_B5_B - [15:0] */
-#define WM2200_EQL_B5_B_SHIFT 0 /* EQL_B5_B - [15:0] */
-#define WM2200_EQL_B5_B_WIDTH 16 /* EQL_B5_B - [15:0] */
-
-/*
- * R2323 (0x913) - EQL_20
- */
-#define WM2200_EQL_B5_PG_MASK 0xFFFF /* EQL_B5_PG - [15:0] */
-#define WM2200_EQL_B5_PG_SHIFT 0 /* EQL_B5_PG - [15:0] */
-#define WM2200_EQL_B5_PG_WIDTH 16 /* EQL_B5_PG - [15:0] */
-
-/*
- * R2326 (0x916) - EQR_1
- */
-#define WM2200_EQR_B1_GAIN_MASK 0xF800 /* EQR_B1_GAIN - [15:11] */
-#define WM2200_EQR_B1_GAIN_SHIFT 11 /* EQR_B1_GAIN - [15:11] */
-#define WM2200_EQR_B1_GAIN_WIDTH 5 /* EQR_B1_GAIN - [15:11] */
-#define WM2200_EQR_B2_GAIN_MASK 0x07C0 /* EQR_B2_GAIN - [10:6] */
-#define WM2200_EQR_B2_GAIN_SHIFT 6 /* EQR_B2_GAIN - [10:6] */
-#define WM2200_EQR_B2_GAIN_WIDTH 5 /* EQR_B2_GAIN - [10:6] */
-#define WM2200_EQR_B3_GAIN_MASK 0x003E /* EQR_B3_GAIN - [5:1] */
-#define WM2200_EQR_B3_GAIN_SHIFT 1 /* EQR_B3_GAIN - [5:1] */
-#define WM2200_EQR_B3_GAIN_WIDTH 5 /* EQR_B3_GAIN - [5:1] */
-#define WM2200_EQR_ENA 0x0001 /* EQR_ENA */
-#define WM2200_EQR_ENA_MASK 0x0001 /* EQR_ENA */
-#define WM2200_EQR_ENA_SHIFT 0 /* EQR_ENA */
-#define WM2200_EQR_ENA_WIDTH 1 /* EQR_ENA */
-
-/*
- * R2327 (0x917) - EQR_2
- */
-#define WM2200_EQR_B4_GAIN_MASK 0xF800 /* EQR_B4_GAIN - [15:11] */
-#define WM2200_EQR_B4_GAIN_SHIFT 11 /* EQR_B4_GAIN - [15:11] */
-#define WM2200_EQR_B4_GAIN_WIDTH 5 /* EQR_B4_GAIN - [15:11] */
-#define WM2200_EQR_B5_GAIN_MASK 0x07C0 /* EQR_B5_GAIN - [10:6] */
-#define WM2200_EQR_B5_GAIN_SHIFT 6 /* EQR_B5_GAIN - [10:6] */
-#define WM2200_EQR_B5_GAIN_WIDTH 5 /* EQR_B5_GAIN - [10:6] */
-
-/*
- * R2328 (0x918) - EQR_3
- */
-#define WM2200_EQR_B1_A_MASK 0xFFFF /* EQR_B1_A - [15:0] */
-#define WM2200_EQR_B1_A_SHIFT 0 /* EQR_B1_A - [15:0] */
-#define WM2200_EQR_B1_A_WIDTH 16 /* EQR_B1_A - [15:0] */
-
-/*
- * R2329 (0x919) - EQR_4
- */
-#define WM2200_EQR_B1_B_MASK 0xFFFF /* EQR_B1_B - [15:0] */
-#define WM2200_EQR_B1_B_SHIFT 0 /* EQR_B1_B - [15:0] */
-#define WM2200_EQR_B1_B_WIDTH 16 /* EQR_B1_B - [15:0] */
-
-/*
- * R2330 (0x91A) - EQR_5
- */
-#define WM2200_EQR_B1_PG_MASK 0xFFFF /* EQR_B1_PG - [15:0] */
-#define WM2200_EQR_B1_PG_SHIFT 0 /* EQR_B1_PG - [15:0] */
-#define WM2200_EQR_B1_PG_WIDTH 16 /* EQR_B1_PG - [15:0] */
-
-/*
- * R2331 (0x91B) - EQR_6
- */
-#define WM2200_EQR_B2_A_MASK 0xFFFF /* EQR_B2_A - [15:0] */
-#define WM2200_EQR_B2_A_SHIFT 0 /* EQR_B2_A - [15:0] */
-#define WM2200_EQR_B2_A_WIDTH 16 /* EQR_B2_A - [15:0] */
-
-/*
- * R2332 (0x91C) - EQR_7
- */
-#define WM2200_EQR_B2_B_MASK 0xFFFF /* EQR_B2_B - [15:0] */
-#define WM2200_EQR_B2_B_SHIFT 0 /* EQR_B2_B - [15:0] */
-#define WM2200_EQR_B2_B_WIDTH 16 /* EQR_B2_B - [15:0] */
-
-/*
- * R2333 (0x91D) - EQR_8
- */
-#define WM2200_EQR_B2_C_MASK 0xFFFF /* EQR_B2_C - [15:0] */
-#define WM2200_EQR_B2_C_SHIFT 0 /* EQR_B2_C - [15:0] */
-#define WM2200_EQR_B2_C_WIDTH 16 /* EQR_B2_C - [15:0] */
-
-/*
- * R2334 (0x91E) - EQR_9
- */
-#define WM2200_EQR_B2_PG_MASK 0xFFFF /* EQR_B2_PG - [15:0] */
-#define WM2200_EQR_B2_PG_SHIFT 0 /* EQR_B2_PG - [15:0] */
-#define WM2200_EQR_B2_PG_WIDTH 16 /* EQR_B2_PG - [15:0] */
-
-/*
- * R2335 (0x91F) - EQR_10
- */
-#define WM2200_EQR_B3_A_MASK 0xFFFF /* EQR_B3_A - [15:0] */
-#define WM2200_EQR_B3_A_SHIFT 0 /* EQR_B3_A - [15:0] */
-#define WM2200_EQR_B3_A_WIDTH 16 /* EQR_B3_A - [15:0] */
-
-/*
- * R2336 (0x920) - EQR_11
- */
-#define WM2200_EQR_B3_B_MASK 0xFFFF /* EQR_B3_B - [15:0] */
-#define WM2200_EQR_B3_B_SHIFT 0 /* EQR_B3_B - [15:0] */
-#define WM2200_EQR_B3_B_WIDTH 16 /* EQR_B3_B - [15:0] */
-
-/*
- * R2337 (0x921) - EQR_12
- */
-#define WM2200_EQR_B3_C_MASK 0xFFFF /* EQR_B3_C - [15:0] */
-#define WM2200_EQR_B3_C_SHIFT 0 /* EQR_B3_C - [15:0] */
-#define WM2200_EQR_B3_C_WIDTH 16 /* EQR_B3_C - [15:0] */
-
-/*
- * R2338 (0x922) - EQR_13
- */
-#define WM2200_EQR_B3_PG_MASK 0xFFFF /* EQR_B3_PG - [15:0] */
-#define WM2200_EQR_B3_PG_SHIFT 0 /* EQR_B3_PG - [15:0] */
-#define WM2200_EQR_B3_PG_WIDTH 16 /* EQR_B3_PG - [15:0] */
-
-/*
- * R2339 (0x923) - EQR_14
- */
-#define WM2200_EQR_B4_A_MASK 0xFFFF /* EQR_B4_A - [15:0] */
-#define WM2200_EQR_B4_A_SHIFT 0 /* EQR_B4_A - [15:0] */
-#define WM2200_EQR_B4_A_WIDTH 16 /* EQR_B4_A - [15:0] */
-
-/*
- * R2340 (0x924) - EQR_15
- */
-#define WM2200_EQR_B4_B_MASK 0xFFFF /* EQR_B4_B - [15:0] */
-#define WM2200_EQR_B4_B_SHIFT 0 /* EQR_B4_B - [15:0] */
-#define WM2200_EQR_B4_B_WIDTH 16 /* EQR_B4_B - [15:0] */
-
-/*
- * R2341 (0x925) - EQR_16
- */
-#define WM2200_EQR_B4_C_MASK 0xFFFF /* EQR_B4_C - [15:0] */
-#define WM2200_EQR_B4_C_SHIFT 0 /* EQR_B4_C - [15:0] */
-#define WM2200_EQR_B4_C_WIDTH 16 /* EQR_B4_C - [15:0] */
-
-/*
- * R2342 (0x926) - EQR_17
- */
-#define WM2200_EQR_B4_PG_MASK 0xFFFF /* EQR_B4_PG - [15:0] */
-#define WM2200_EQR_B4_PG_SHIFT 0 /* EQR_B4_PG - [15:0] */
-#define WM2200_EQR_B4_PG_WIDTH 16 /* EQR_B4_PG - [15:0] */
-
-/*
- * R2343 (0x927) - EQR_18
- */
-#define WM2200_EQR_B5_A_MASK 0xFFFF /* EQR_B5_A - [15:0] */
-#define WM2200_EQR_B5_A_SHIFT 0 /* EQR_B5_A - [15:0] */
-#define WM2200_EQR_B5_A_WIDTH 16 /* EQR_B5_A - [15:0] */
-
-/*
- * R2344 (0x928) - EQR_19
- */
-#define WM2200_EQR_B5_B_MASK 0xFFFF /* EQR_B5_B - [15:0] */
-#define WM2200_EQR_B5_B_SHIFT 0 /* EQR_B5_B - [15:0] */
-#define WM2200_EQR_B5_B_WIDTH 16 /* EQR_B5_B - [15:0] */
-
-/*
- * R2345 (0x929) - EQR_20
- */
-#define WM2200_EQR_B5_PG_MASK 0xFFFF /* EQR_B5_PG - [15:0] */
-#define WM2200_EQR_B5_PG_SHIFT 0 /* EQR_B5_PG - [15:0] */
-#define WM2200_EQR_B5_PG_WIDTH 16 /* EQR_B5_PG - [15:0] */
-
-/*
- * R2366 (0x93E) - HPLPF1_1
- */
-#define WM2200_LHPF1_MODE 0x0002 /* LHPF1_MODE */
-#define WM2200_LHPF1_MODE_MASK 0x0002 /* LHPF1_MODE */
-#define WM2200_LHPF1_MODE_SHIFT 1 /* LHPF1_MODE */
-#define WM2200_LHPF1_MODE_WIDTH 1 /* LHPF1_MODE */
-#define WM2200_LHPF1_ENA 0x0001 /* LHPF1_ENA */
-#define WM2200_LHPF1_ENA_MASK 0x0001 /* LHPF1_ENA */
-#define WM2200_LHPF1_ENA_SHIFT 0 /* LHPF1_ENA */
-#define WM2200_LHPF1_ENA_WIDTH 1 /* LHPF1_ENA */
-
-/*
- * R2367 (0x93F) - HPLPF1_2
- */
-#define WM2200_LHPF1_COEFF_MASK 0xFFFF /* LHPF1_COEFF - [15:0] */
-#define WM2200_LHPF1_COEFF_SHIFT 0 /* LHPF1_COEFF - [15:0] */
-#define WM2200_LHPF1_COEFF_WIDTH 16 /* LHPF1_COEFF - [15:0] */
-
-/*
- * R2370 (0x942) - HPLPF2_1
- */
-#define WM2200_LHPF2_MODE 0x0002 /* LHPF2_MODE */
-#define WM2200_LHPF2_MODE_MASK 0x0002 /* LHPF2_MODE */
-#define WM2200_LHPF2_MODE_SHIFT 1 /* LHPF2_MODE */
-#define WM2200_LHPF2_MODE_WIDTH 1 /* LHPF2_MODE */
-#define WM2200_LHPF2_ENA 0x0001 /* LHPF2_ENA */
-#define WM2200_LHPF2_ENA_MASK 0x0001 /* LHPF2_ENA */
-#define WM2200_LHPF2_ENA_SHIFT 0 /* LHPF2_ENA */
-#define WM2200_LHPF2_ENA_WIDTH 1 /* LHPF2_ENA */
-
-/*
- * R2371 (0x943) - HPLPF2_2
- */
-#define WM2200_LHPF2_COEFF_MASK 0xFFFF /* LHPF2_COEFF - [15:0] */
-#define WM2200_LHPF2_COEFF_SHIFT 0 /* LHPF2_COEFF - [15:0] */
-#define WM2200_LHPF2_COEFF_WIDTH 16 /* LHPF2_COEFF - [15:0] */
-
-/*
- * R2560 (0xA00) - DSP1 Control 1
- */
-#define WM2200_DSP1_RW_SEQUENCE_ENA 0x0001 /* DSP1_RW_SEQUENCE_ENA */
-#define WM2200_DSP1_RW_SEQUENCE_ENA_MASK 0x0001 /* DSP1_RW_SEQUENCE_ENA */
-#define WM2200_DSP1_RW_SEQUENCE_ENA_SHIFT 0 /* DSP1_RW_SEQUENCE_ENA */
-#define WM2200_DSP1_RW_SEQUENCE_ENA_WIDTH 1 /* DSP1_RW_SEQUENCE_ENA */
-
-/*
- * R2562 (0xA02) - DSP1 Control 2
- */
-#define WM2200_DSP1_PAGE_BASE_PM_0_MASK 0xFF00 /* DSP1_PAGE_BASE_PM - [15:8] */
-#define WM2200_DSP1_PAGE_BASE_PM_0_SHIFT 8 /* DSP1_PAGE_BASE_PM - [15:8] */
-#define WM2200_DSP1_PAGE_BASE_PM_0_WIDTH 8 /* DSP1_PAGE_BASE_PM - [15:8] */
-
-/*
- * R2563 (0xA03) - DSP1 Control 3
- */
-#define WM2200_DSP1_PAGE_BASE_DM_0_MASK 0xFF00 /* DSP1_PAGE_BASE_DM - [15:8] */
-#define WM2200_DSP1_PAGE_BASE_DM_0_SHIFT 8 /* DSP1_PAGE_BASE_DM - [15:8] */
-#define WM2200_DSP1_PAGE_BASE_DM_0_WIDTH 8 /* DSP1_PAGE_BASE_DM - [15:8] */
-
-/*
- * R2564 (0xA04) - DSP1 Control 4
- */
-#define WM2200_DSP1_PAGE_BASE_ZM_0_MASK 0xFF00 /* DSP1_PAGE_BASE_ZM - [15:8] */
-#define WM2200_DSP1_PAGE_BASE_ZM_0_SHIFT 8 /* DSP1_PAGE_BASE_ZM - [15:8] */
-#define WM2200_DSP1_PAGE_BASE_ZM_0_WIDTH 8 /* DSP1_PAGE_BASE_ZM - [15:8] */
-
-/*
- * R2566 (0xA06) - DSP1 Control 5
- */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_0_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_0_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_0_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
-
-/*
- * R2567 (0xA07) - DSP1 Control 6
- */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_1_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_1_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_1_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
-
-/*
- * R2568 (0xA08) - DSP1 Control 7
- */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_2_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_2_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_2_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
-
-/*
- * R2569 (0xA09) - DSP1 Control 8
- */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_3_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_3_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_3_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
-
-/*
- * R2570 (0xA0A) - DSP1 Control 9
- */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_4_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_4_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_4_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
-
-/*
- * R2571 (0xA0B) - DSP1 Control 10
- */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_5_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_5_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_5_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
-
-/*
- * R2572 (0xA0C) - DSP1 Control 11
- */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_6_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_6_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_6_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
-
-/*
- * R2573 (0xA0D) - DSP1 Control 12
- */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_7_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_7_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_7_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
-
-/*
- * R2575 (0xA0F) - DSP1 Control 13
- */
-#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_0_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_0_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_0_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
-
-/*
- * R2576 (0xA10) - DSP1 Control 14
- */
-#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_1_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_1_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_1_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
-
-/*
- * R2577 (0xA11) - DSP1 Control 15
- */
-#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_2_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_2_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_2_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
-
-/*
- * R2578 (0xA12) - DSP1 Control 16
- */
-#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_3_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_3_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_3_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
-
-/*
- * R2579 (0xA13) - DSP1 Control 17
- */
-#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_4_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_4_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_4_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
-
-/*
- * R2580 (0xA14) - DSP1 Control 18
- */
-#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_5_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_5_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
-#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_5_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
-
-/*
- * R2582 (0xA16) - DSP1 Control 19
- */
-#define WM2200_DSP1_WDMA_BUFFER_LENGTH_MASK 0x00FF /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
-#define WM2200_DSP1_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
-#define WM2200_DSP1_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
-
-/*
- * R2583 (0xA17) - DSP1 Control 20
- */
-#define WM2200_DSP1_WDMA_CHANNEL_ENABLE_MASK 0x00FF /* DSP1_WDMA_CHANNEL_ENABLE - [7:0] */
-#define WM2200_DSP1_WDMA_CHANNEL_ENABLE_SHIFT 0 /* DSP1_WDMA_CHANNEL_ENABLE - [7:0] */
-#define WM2200_DSP1_WDMA_CHANNEL_ENABLE_WIDTH 8 /* DSP1_WDMA_CHANNEL_ENABLE - [7:0] */
-
-/*
- * R2584 (0xA18) - DSP1 Control 21
- */
-#define WM2200_DSP1_RDMA_CHANNEL_ENABLE_MASK 0x003F /* DSP1_RDMA_CHANNEL_ENABLE - [5:0] */
-#define WM2200_DSP1_RDMA_CHANNEL_ENABLE_SHIFT 0 /* DSP1_RDMA_CHANNEL_ENABLE - [5:0] */
-#define WM2200_DSP1_RDMA_CHANNEL_ENABLE_WIDTH 6 /* DSP1_RDMA_CHANNEL_ENABLE - [5:0] */
-
-/*
- * R2586 (0xA1A) - DSP1 Control 22
- */
-#define WM2200_DSP1_DM_SIZE_MASK 0xFFFF /* DSP1_DM_SIZE - [15:0] */
-#define WM2200_DSP1_DM_SIZE_SHIFT 0 /* DSP1_DM_SIZE - [15:0] */
-#define WM2200_DSP1_DM_SIZE_WIDTH 16 /* DSP1_DM_SIZE - [15:0] */
-
-/*
- * R2587 (0xA1B) - DSP1 Control 23
- */
-#define WM2200_DSP1_PM_SIZE_MASK 0xFFFF /* DSP1_PM_SIZE - [15:0] */
-#define WM2200_DSP1_PM_SIZE_SHIFT 0 /* DSP1_PM_SIZE - [15:0] */
-#define WM2200_DSP1_PM_SIZE_WIDTH 16 /* DSP1_PM_SIZE - [15:0] */
-
-/*
- * R2588 (0xA1C) - DSP1 Control 24
- */
-#define WM2200_DSP1_ZM_SIZE_MASK 0xFFFF /* DSP1_ZM_SIZE - [15:0] */
-#define WM2200_DSP1_ZM_SIZE_SHIFT 0 /* DSP1_ZM_SIZE - [15:0] */
-#define WM2200_DSP1_ZM_SIZE_WIDTH 16 /* DSP1_ZM_SIZE - [15:0] */
-
-/*
- * R2590 (0xA1E) - DSP1 Control 25
- */
-#define WM2200_DSP1_PING_FULL 0x8000 /* DSP1_PING_FULL */
-#define WM2200_DSP1_PING_FULL_MASK 0x8000 /* DSP1_PING_FULL */
-#define WM2200_DSP1_PING_FULL_SHIFT 15 /* DSP1_PING_FULL */
-#define WM2200_DSP1_PING_FULL_WIDTH 1 /* DSP1_PING_FULL */
-#define WM2200_DSP1_PONG_FULL 0x4000 /* DSP1_PONG_FULL */
-#define WM2200_DSP1_PONG_FULL_MASK 0x4000 /* DSP1_PONG_FULL */
-#define WM2200_DSP1_PONG_FULL_SHIFT 14 /* DSP1_PONG_FULL */
-#define WM2200_DSP1_PONG_FULL_WIDTH 1 /* DSP1_PONG_FULL */
-#define WM2200_DSP1_WDMA_ACTIVE_CHANNELS_MASK 0x00FF /* DSP1_WDMA_ACTIVE_CHANNELS - [7:0] */
-#define WM2200_DSP1_WDMA_ACTIVE_CHANNELS_SHIFT 0 /* DSP1_WDMA_ACTIVE_CHANNELS - [7:0] */
-#define WM2200_DSP1_WDMA_ACTIVE_CHANNELS_WIDTH 8 /* DSP1_WDMA_ACTIVE_CHANNELS - [7:0] */
-
-/*
- * R2592 (0xA20) - DSP1 Control 26
- */
-#define WM2200_DSP1_SCRATCH_0_MASK 0xFFFF /* DSP1_SCRATCH_0 - [15:0] */
-#define WM2200_DSP1_SCRATCH_0_SHIFT 0 /* DSP1_SCRATCH_0 - [15:0] */
-#define WM2200_DSP1_SCRATCH_0_WIDTH 16 /* DSP1_SCRATCH_0 - [15:0] */
-
-/*
- * R2593 (0xA21) - DSP1 Control 27
- */
-#define WM2200_DSP1_SCRATCH_1_MASK 0xFFFF /* DSP1_SCRATCH_1 - [15:0] */
-#define WM2200_DSP1_SCRATCH_1_SHIFT 0 /* DSP1_SCRATCH_1 - [15:0] */
-#define WM2200_DSP1_SCRATCH_1_WIDTH 16 /* DSP1_SCRATCH_1 - [15:0] */
-
-/*
- * R2594 (0xA22) - DSP1 Control 28
- */
-#define WM2200_DSP1_SCRATCH_2_MASK 0xFFFF /* DSP1_SCRATCH_2 - [15:0] */
-#define WM2200_DSP1_SCRATCH_2_SHIFT 0 /* DSP1_SCRATCH_2 - [15:0] */
-#define WM2200_DSP1_SCRATCH_2_WIDTH 16 /* DSP1_SCRATCH_2 - [15:0] */
-
-/*
- * R2595 (0xA23) - DSP1 Control 29
- */
-#define WM2200_DSP1_SCRATCH_3_MASK 0xFFFF /* DSP1_SCRATCH_3 - [15:0] */
-#define WM2200_DSP1_SCRATCH_3_SHIFT 0 /* DSP1_SCRATCH_3 - [15:0] */
-#define WM2200_DSP1_SCRATCH_3_WIDTH 16 /* DSP1_SCRATCH_3 - [15:0] */
-
-/*
- * R2596 (0xA24) - DSP1 Control 30
- */
-#define WM2200_DSP1_DBG_CLK_ENA 0x0008 /* DSP1_DBG_CLK_ENA */
-#define WM2200_DSP1_DBG_CLK_ENA_MASK 0x0008 /* DSP1_DBG_CLK_ENA */
-#define WM2200_DSP1_DBG_CLK_ENA_SHIFT 3 /* DSP1_DBG_CLK_ENA */
-#define WM2200_DSP1_DBG_CLK_ENA_WIDTH 1 /* DSP1_DBG_CLK_ENA */
-#define WM2200_DSP1_SYS_ENA 0x0004 /* DSP1_SYS_ENA */
-#define WM2200_DSP1_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */
-#define WM2200_DSP1_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */
-#define WM2200_DSP1_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */
-#define WM2200_DSP1_CORE_ENA 0x0002 /* DSP1_CORE_ENA */
-#define WM2200_DSP1_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */
-#define WM2200_DSP1_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */
-#define WM2200_DSP1_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */
-#define WM2200_DSP1_START 0x0001 /* DSP1_START */
-#define WM2200_DSP1_START_MASK 0x0001 /* DSP1_START */
-#define WM2200_DSP1_START_SHIFT 0 /* DSP1_START */
-#define WM2200_DSP1_START_WIDTH 1 /* DSP1_START */
-
-/*
- * R2598 (0xA26) - DSP1 Control 31
- */
-#define WM2200_DSP1_CLK_RATE_MASK 0x0018 /* DSP1_CLK_RATE - [4:3] */
-#define WM2200_DSP1_CLK_RATE_SHIFT 3 /* DSP1_CLK_RATE - [4:3] */
-#define WM2200_DSP1_CLK_RATE_WIDTH 2 /* DSP1_CLK_RATE - [4:3] */
-#define WM2200_DSP1_CLK_AVAIL 0x0004 /* DSP1_CLK_AVAIL */
-#define WM2200_DSP1_CLK_AVAIL_MASK 0x0004 /* DSP1_CLK_AVAIL */
-#define WM2200_DSP1_CLK_AVAIL_SHIFT 2 /* DSP1_CLK_AVAIL */
-#define WM2200_DSP1_CLK_AVAIL_WIDTH 1 /* DSP1_CLK_AVAIL */
-#define WM2200_DSP1_CLK_REQ_MASK 0x0003 /* DSP1_CLK_REQ - [1:0] */
-#define WM2200_DSP1_CLK_REQ_SHIFT 0 /* DSP1_CLK_REQ - [1:0] */
-#define WM2200_DSP1_CLK_REQ_WIDTH 2 /* DSP1_CLK_REQ - [1:0] */
-
-/*
- * R2816 (0xB00) - DSP2 Control 1
- */
-#define WM2200_DSP2_RW_SEQUENCE_ENA 0x0001 /* DSP2_RW_SEQUENCE_ENA */
-#define WM2200_DSP2_RW_SEQUENCE_ENA_MASK 0x0001 /* DSP2_RW_SEQUENCE_ENA */
-#define WM2200_DSP2_RW_SEQUENCE_ENA_SHIFT 0 /* DSP2_RW_SEQUENCE_ENA */
-#define WM2200_DSP2_RW_SEQUENCE_ENA_WIDTH 1 /* DSP2_RW_SEQUENCE_ENA */
-
-/*
- * R2818 (0xB02) - DSP2 Control 2
- */
-#define WM2200_DSP2_PAGE_BASE_PM_0_MASK 0xFF00 /* DSP2_PAGE_BASE_PM - [15:8] */
-#define WM2200_DSP2_PAGE_BASE_PM_0_SHIFT 8 /* DSP2_PAGE_BASE_PM - [15:8] */
-#define WM2200_DSP2_PAGE_BASE_PM_0_WIDTH 8 /* DSP2_PAGE_BASE_PM - [15:8] */
-
-/*
- * R2819 (0xB03) - DSP2 Control 3
- */
-#define WM2200_DSP2_PAGE_BASE_DM_0_MASK 0xFF00 /* DSP2_PAGE_BASE_DM - [15:8] */
-#define WM2200_DSP2_PAGE_BASE_DM_0_SHIFT 8 /* DSP2_PAGE_BASE_DM - [15:8] */
-#define WM2200_DSP2_PAGE_BASE_DM_0_WIDTH 8 /* DSP2_PAGE_BASE_DM - [15:8] */
-
-/*
- * R2820 (0xB04) - DSP2 Control 4
- */
-#define WM2200_DSP2_PAGE_BASE_ZM_0_MASK 0xFF00 /* DSP2_PAGE_BASE_ZM - [15:8] */
-#define WM2200_DSP2_PAGE_BASE_ZM_0_SHIFT 8 /* DSP2_PAGE_BASE_ZM - [15:8] */
-#define WM2200_DSP2_PAGE_BASE_ZM_0_WIDTH 8 /* DSP2_PAGE_BASE_ZM - [15:8] */
-
-/*
- * R2822 (0xB06) - DSP2 Control 5
- */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_0_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_0_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_0_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
-
-/*
- * R2823 (0xB07) - DSP2 Control 6
- */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_1_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_1_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_1_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
-
-/*
- * R2824 (0xB08) - DSP2 Control 7
- */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_2_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_2_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_2_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
-
-/*
- * R2825 (0xB09) - DSP2 Control 8
- */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_3_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_3_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_3_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
-
-/*
- * R2826 (0xB0A) - DSP2 Control 9
- */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_4_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_4_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_4_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
-
-/*
- * R2827 (0xB0B) - DSP2 Control 10
- */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_5_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_5_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_5_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
-
-/*
- * R2828 (0xB0C) - DSP2 Control 11
- */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_6_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_6_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_6_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
-
-/*
- * R2829 (0xB0D) - DSP2 Control 12
- */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_7_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_7_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_7_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
-
-/*
- * R2831 (0xB0F) - DSP2 Control 13
- */
-#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_0_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_0_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_0_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
-
-/*
- * R2832 (0xB10) - DSP2 Control 14
- */
-#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_1_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_1_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_1_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
-
-/*
- * R2833 (0xB11) - DSP2 Control 15
- */
-#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_2_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_2_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_2_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
-
-/*
- * R2834 (0xB12) - DSP2 Control 16
- */
-#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_3_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_3_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_3_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
-
-/*
- * R2835 (0xB13) - DSP2 Control 17
- */
-#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_4_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_4_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_4_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
-
-/*
- * R2836 (0xB14) - DSP2 Control 18
- */
-#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_5_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_5_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
-#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_5_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
-
-/*
- * R2838 (0xB16) - DSP2 Control 19
- */
-#define WM2200_DSP2_WDMA_BUFFER_LENGTH_MASK 0x00FF /* DSP2_WDMA_BUFFER_LENGTH - [7:0] */
-#define WM2200_DSP2_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP2_WDMA_BUFFER_LENGTH - [7:0] */
-#define WM2200_DSP2_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP2_WDMA_BUFFER_LENGTH - [7:0] */
-
-/*
- * R2839 (0xB17) - DSP2 Control 20
- */
-#define WM2200_DSP2_WDMA_CHANNEL_ENABLE_MASK 0x00FF /* DSP2_WDMA_CHANNEL_ENABLE - [7:0] */
-#define WM2200_DSP2_WDMA_CHANNEL_ENABLE_SHIFT 0 /* DSP2_WDMA_CHANNEL_ENABLE - [7:0] */
-#define WM2200_DSP2_WDMA_CHANNEL_ENABLE_WIDTH 8 /* DSP2_WDMA_CHANNEL_ENABLE - [7:0] */
-
-/*
- * R2840 (0xB18) - DSP2 Control 21
- */
-#define WM2200_DSP2_RDMA_CHANNEL_ENABLE_MASK 0x003F /* DSP2_RDMA_CHANNEL_ENABLE - [5:0] */
-#define WM2200_DSP2_RDMA_CHANNEL_ENABLE_SHIFT 0 /* DSP2_RDMA_CHANNEL_ENABLE - [5:0] */
-#define WM2200_DSP2_RDMA_CHANNEL_ENABLE_WIDTH 6 /* DSP2_RDMA_CHANNEL_ENABLE - [5:0] */
-
-/*
- * R2842 (0xB1A) - DSP2 Control 22
- */
-#define WM2200_DSP2_DM_SIZE_MASK 0xFFFF /* DSP2_DM_SIZE - [15:0] */
-#define WM2200_DSP2_DM_SIZE_SHIFT 0 /* DSP2_DM_SIZE - [15:0] */
-#define WM2200_DSP2_DM_SIZE_WIDTH 16 /* DSP2_DM_SIZE - [15:0] */
-
-/*
- * R2843 (0xB1B) - DSP2 Control 23
- */
-#define WM2200_DSP2_PM_SIZE_MASK 0xFFFF /* DSP2_PM_SIZE - [15:0] */
-#define WM2200_DSP2_PM_SIZE_SHIFT 0 /* DSP2_PM_SIZE - [15:0] */
-#define WM2200_DSP2_PM_SIZE_WIDTH 16 /* DSP2_PM_SIZE - [15:0] */
-
-/*
- * R2844 (0xB1C) - DSP2 Control 24
- */
-#define WM2200_DSP2_ZM_SIZE_MASK 0xFFFF /* DSP2_ZM_SIZE - [15:0] */
-#define WM2200_DSP2_ZM_SIZE_SHIFT 0 /* DSP2_ZM_SIZE - [15:0] */
-#define WM2200_DSP2_ZM_SIZE_WIDTH 16 /* DSP2_ZM_SIZE - [15:0] */
-
-/*
- * R2846 (0xB1E) - DSP2 Control 25
- */
-#define WM2200_DSP2_PING_FULL 0x8000 /* DSP2_PING_FULL */
-#define WM2200_DSP2_PING_FULL_MASK 0x8000 /* DSP2_PING_FULL */
-#define WM2200_DSP2_PING_FULL_SHIFT 15 /* DSP2_PING_FULL */
-#define WM2200_DSP2_PING_FULL_WIDTH 1 /* DSP2_PING_FULL */
-#define WM2200_DSP2_PONG_FULL 0x4000 /* DSP2_PONG_FULL */
-#define WM2200_DSP2_PONG_FULL_MASK 0x4000 /* DSP2_PONG_FULL */
-#define WM2200_DSP2_PONG_FULL_SHIFT 14 /* DSP2_PONG_FULL */
-#define WM2200_DSP2_PONG_FULL_WIDTH 1 /* DSP2_PONG_FULL */
-#define WM2200_DSP2_WDMA_ACTIVE_CHANNELS_MASK 0x00FF /* DSP2_WDMA_ACTIVE_CHANNELS - [7:0] */
-#define WM2200_DSP2_WDMA_ACTIVE_CHANNELS_SHIFT 0 /* DSP2_WDMA_ACTIVE_CHANNELS - [7:0] */
-#define WM2200_DSP2_WDMA_ACTIVE_CHANNELS_WIDTH 8 /* DSP2_WDMA_ACTIVE_CHANNELS - [7:0] */
-
-/*
- * R2848 (0xB20) - DSP2 Control 26
- */
-#define WM2200_DSP2_SCRATCH_0_MASK 0xFFFF /* DSP2_SCRATCH_0 - [15:0] */
-#define WM2200_DSP2_SCRATCH_0_SHIFT 0 /* DSP2_SCRATCH_0 - [15:0] */
-#define WM2200_DSP2_SCRATCH_0_WIDTH 16 /* DSP2_SCRATCH_0 - [15:0] */
-
-/*
- * R2849 (0xB21) - DSP2 Control 27
- */
-#define WM2200_DSP2_SCRATCH_1_MASK 0xFFFF /* DSP2_SCRATCH_1 - [15:0] */
-#define WM2200_DSP2_SCRATCH_1_SHIFT 0 /* DSP2_SCRATCH_1 - [15:0] */
-#define WM2200_DSP2_SCRATCH_1_WIDTH 16 /* DSP2_SCRATCH_1 - [15:0] */
-
-/*
- * R2850 (0xB22) - DSP2 Control 28
- */
-#define WM2200_DSP2_SCRATCH_2_MASK 0xFFFF /* DSP2_SCRATCH_2 - [15:0] */
-#define WM2200_DSP2_SCRATCH_2_SHIFT 0 /* DSP2_SCRATCH_2 - [15:0] */
-#define WM2200_DSP2_SCRATCH_2_WIDTH 16 /* DSP2_SCRATCH_2 - [15:0] */
-
-/*
- * R2851 (0xB23) - DSP2 Control 29
- */
-#define WM2200_DSP2_SCRATCH_3_MASK 0xFFFF /* DSP2_SCRATCH_3 - [15:0] */
-#define WM2200_DSP2_SCRATCH_3_SHIFT 0 /* DSP2_SCRATCH_3 - [15:0] */
-#define WM2200_DSP2_SCRATCH_3_WIDTH 16 /* DSP2_SCRATCH_3 - [15:0] */
-
-/*
- * R2852 (0xB24) - DSP2 Control 30
- */
-#define WM2200_DSP2_DBG_CLK_ENA 0x0008 /* DSP2_DBG_CLK_ENA */
-#define WM2200_DSP2_DBG_CLK_ENA_MASK 0x0008 /* DSP2_DBG_CLK_ENA */
-#define WM2200_DSP2_DBG_CLK_ENA_SHIFT 3 /* DSP2_DBG_CLK_ENA */
-#define WM2200_DSP2_DBG_CLK_ENA_WIDTH 1 /* DSP2_DBG_CLK_ENA */
-#define WM2200_DSP2_SYS_ENA 0x0004 /* DSP2_SYS_ENA */
-#define WM2200_DSP2_SYS_ENA_MASK 0x0004 /* DSP2_SYS_ENA */
-#define WM2200_DSP2_SYS_ENA_SHIFT 2 /* DSP2_SYS_ENA */
-#define WM2200_DSP2_SYS_ENA_WIDTH 1 /* DSP2_SYS_ENA */
-#define WM2200_DSP2_CORE_ENA 0x0002 /* DSP2_CORE_ENA */
-#define WM2200_DSP2_CORE_ENA_MASK 0x0002 /* DSP2_CORE_ENA */
-#define WM2200_DSP2_CORE_ENA_SHIFT 1 /* DSP2_CORE_ENA */
-#define WM2200_DSP2_CORE_ENA_WIDTH 1 /* DSP2_CORE_ENA */
-#define WM2200_DSP2_START 0x0001 /* DSP2_START */
-#define WM2200_DSP2_START_MASK 0x0001 /* DSP2_START */
-#define WM2200_DSP2_START_SHIFT 0 /* DSP2_START */
-#define WM2200_DSP2_START_WIDTH 1 /* DSP2_START */
-
-/*
- * R2854 (0xB26) - DSP2 Control 31
- */
-#define WM2200_DSP2_CLK_RATE_MASK 0x0018 /* DSP2_CLK_RATE - [4:3] */
-#define WM2200_DSP2_CLK_RATE_SHIFT 3 /* DSP2_CLK_RATE - [4:3] */
-#define WM2200_DSP2_CLK_RATE_WIDTH 2 /* DSP2_CLK_RATE - [4:3] */
-#define WM2200_DSP2_CLK_AVAIL 0x0004 /* DSP2_CLK_AVAIL */
-#define WM2200_DSP2_CLK_AVAIL_MASK 0x0004 /* DSP2_CLK_AVAIL */
-#define WM2200_DSP2_CLK_AVAIL_SHIFT 2 /* DSP2_CLK_AVAIL */
-#define WM2200_DSP2_CLK_AVAIL_WIDTH 1 /* DSP2_CLK_AVAIL */
-#define WM2200_DSP2_CLK_REQ_MASK 0x0003 /* DSP2_CLK_REQ - [1:0] */
-#define WM2200_DSP2_CLK_REQ_SHIFT 0 /* DSP2_CLK_REQ - [1:0] */
-#define WM2200_DSP2_CLK_REQ_WIDTH 2 /* DSP2_CLK_REQ - [1:0] */
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm5100-tables.c b/ANDROID_3.4.5/sound/soc/codecs/wm5100-tables.c
deleted file mode 100644
index 9a18fae6..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm5100-tables.c
+++ /dev/null
@@ -1,1364 +0,0 @@
-/*
- * wm5100-tables.c -- WM5100 ALSA SoC Audio driver data
- *
- * Copyright 2011 Wolfson Microelectronics plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include "wm5100.h"
-
-bool wm5100_volatile_register(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM5100_SOFTWARE_RESET:
- case WM5100_DEVICE_REVISION:
- case WM5100_FX_CTRL:
- case WM5100_INTERRUPT_STATUS_1:
- case WM5100_INTERRUPT_STATUS_2:
- case WM5100_INTERRUPT_STATUS_3:
- case WM5100_INTERRUPT_STATUS_4:
- case WM5100_INTERRUPT_RAW_STATUS_2:
- case WM5100_INTERRUPT_RAW_STATUS_3:
- case WM5100_INTERRUPT_RAW_STATUS_4:
- case WM5100_OUTPUT_STATUS_1:
- case WM5100_OUTPUT_STATUS_2:
- case WM5100_INPUT_ENABLES_STATUS:
- case WM5100_MIC_DETECT_3:
- return 1;
- default:
- return 0;
- }
-}
-
-bool wm5100_readable_register(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM5100_SOFTWARE_RESET:
- case WM5100_DEVICE_REVISION:
- case WM5100_CTRL_IF_1:
- case WM5100_TONE_GENERATOR_1:
- case WM5100_PWM_DRIVE_1:
- case WM5100_PWM_DRIVE_2:
- case WM5100_PWM_DRIVE_3:
- case WM5100_CLOCKING_1:
- case WM5100_CLOCKING_3:
- case WM5100_CLOCKING_4:
- case WM5100_CLOCKING_5:
- case WM5100_CLOCKING_6:
- case WM5100_CLOCKING_7:
- case WM5100_CLOCKING_8:
- case WM5100_ASRC_ENABLE:
- case WM5100_ASRC_STATUS:
- case WM5100_ASRC_RATE1:
- case WM5100_ISRC_1_CTRL_1:
- case WM5100_ISRC_1_CTRL_2:
- case WM5100_ISRC_2_CTRL1:
- case WM5100_ISRC_2_CTRL_2:
- case WM5100_FLL1_CONTROL_1:
- case WM5100_FLL1_CONTROL_2:
- case WM5100_FLL1_CONTROL_3:
- case WM5100_FLL1_CONTROL_5:
- case WM5100_FLL1_CONTROL_6:
- case WM5100_FLL1_EFS_1:
- case WM5100_FLL2_CONTROL_1:
- case WM5100_FLL2_CONTROL_2:
- case WM5100_FLL2_CONTROL_3:
- case WM5100_FLL2_CONTROL_5:
- case WM5100_FLL2_CONTROL_6:
- case WM5100_FLL2_EFS_1:
- case WM5100_MIC_CHARGE_PUMP_1:
- case WM5100_MIC_CHARGE_PUMP_2:
- case WM5100_HP_CHARGE_PUMP_1:
- case WM5100_LDO1_CONTROL:
- case WM5100_MIC_BIAS_CTRL_1:
- case WM5100_MIC_BIAS_CTRL_2:
- case WM5100_MIC_BIAS_CTRL_3:
- case WM5100_ACCESSORY_DETECT_MODE_1:
- case WM5100_HEADPHONE_DETECT_1:
- case WM5100_HEADPHONE_DETECT_2:
- case WM5100_MIC_DETECT_1:
- case WM5100_MIC_DETECT_2:
- case WM5100_MIC_DETECT_3:
- case WM5100_MISC_CONTROL:
- case WM5100_INPUT_ENABLES:
- case WM5100_INPUT_ENABLES_STATUS:
- case WM5100_IN1L_CONTROL:
- case WM5100_IN1R_CONTROL:
- case WM5100_IN2L_CONTROL:
- case WM5100_IN2R_CONTROL:
- case WM5100_IN3L_CONTROL:
- case WM5100_IN3R_CONTROL:
- case WM5100_IN4L_CONTROL:
- case WM5100_IN4R_CONTROL:
- case WM5100_RXANC_SRC:
- case WM5100_INPUT_VOLUME_RAMP:
- case WM5100_ADC_DIGITAL_VOLUME_1L:
- case WM5100_ADC_DIGITAL_VOLUME_1R:
- case WM5100_ADC_DIGITAL_VOLUME_2L:
- case WM5100_ADC_DIGITAL_VOLUME_2R:
- case WM5100_ADC_DIGITAL_VOLUME_3L:
- case WM5100_ADC_DIGITAL_VOLUME_3R:
- case WM5100_ADC_DIGITAL_VOLUME_4L:
- case WM5100_ADC_DIGITAL_VOLUME_4R:
- case WM5100_OUTPUT_ENABLES_2:
- case WM5100_OUTPUT_STATUS_1:
- case WM5100_OUTPUT_STATUS_2:
- case WM5100_CHANNEL_ENABLES_1:
- case WM5100_OUT_VOLUME_1L:
- case WM5100_OUT_VOLUME_1R:
- case WM5100_DAC_VOLUME_LIMIT_1L:
- case WM5100_DAC_VOLUME_LIMIT_1R:
- case WM5100_OUT_VOLUME_2L:
- case WM5100_OUT_VOLUME_2R:
- case WM5100_DAC_VOLUME_LIMIT_2L:
- case WM5100_DAC_VOLUME_LIMIT_2R:
- case WM5100_OUT_VOLUME_3L:
- case WM5100_OUT_VOLUME_3R:
- case WM5100_DAC_VOLUME_LIMIT_3L:
- case WM5100_DAC_VOLUME_LIMIT_3R:
- case WM5100_OUT_VOLUME_4L:
- case WM5100_OUT_VOLUME_4R:
- case WM5100_DAC_VOLUME_LIMIT_5L:
- case WM5100_DAC_VOLUME_LIMIT_5R:
- case WM5100_DAC_VOLUME_LIMIT_6L:
- case WM5100_DAC_VOLUME_LIMIT_6R:
- case WM5100_DAC_AEC_CONTROL_1:
- case WM5100_OUTPUT_VOLUME_RAMP:
- case WM5100_DAC_DIGITAL_VOLUME_1L:
- case WM5100_DAC_DIGITAL_VOLUME_1R:
- case WM5100_DAC_DIGITAL_VOLUME_2L:
- case WM5100_DAC_DIGITAL_VOLUME_2R:
- case WM5100_DAC_DIGITAL_VOLUME_3L:
- case WM5100_DAC_DIGITAL_VOLUME_3R:
- case WM5100_DAC_DIGITAL_VOLUME_4L:
- case WM5100_DAC_DIGITAL_VOLUME_4R:
- case WM5100_DAC_DIGITAL_VOLUME_5L:
- case WM5100_DAC_DIGITAL_VOLUME_5R:
- case WM5100_DAC_DIGITAL_VOLUME_6L:
- case WM5100_DAC_DIGITAL_VOLUME_6R:
- case WM5100_PDM_SPK1_CTRL_1:
- case WM5100_PDM_SPK1_CTRL_2:
- case WM5100_PDM_SPK2_CTRL_1:
- case WM5100_PDM_SPK2_CTRL_2:
- case WM5100_AUDIO_IF_1_1:
- case WM5100_AUDIO_IF_1_2:
- case WM5100_AUDIO_IF_1_3:
- case WM5100_AUDIO_IF_1_4:
- case WM5100_AUDIO_IF_1_5:
- case WM5100_AUDIO_IF_1_6:
- case WM5100_AUDIO_IF_1_7:
- case WM5100_AUDIO_IF_1_8:
- case WM5100_AUDIO_IF_1_9:
- case WM5100_AUDIO_IF_1_10:
- case WM5100_AUDIO_IF_1_11:
- case WM5100_AUDIO_IF_1_12:
- case WM5100_AUDIO_IF_1_13:
- case WM5100_AUDIO_IF_1_14:
- case WM5100_AUDIO_IF_1_15:
- case WM5100_AUDIO_IF_1_16:
- case WM5100_AUDIO_IF_1_17:
- case WM5100_AUDIO_IF_1_18:
- case WM5100_AUDIO_IF_1_19:
- case WM5100_AUDIO_IF_1_20:
- case WM5100_AUDIO_IF_1_21:
- case WM5100_AUDIO_IF_1_22:
- case WM5100_AUDIO_IF_1_23:
- case WM5100_AUDIO_IF_1_24:
- case WM5100_AUDIO_IF_1_25:
- case WM5100_AUDIO_IF_1_26:
- case WM5100_AUDIO_IF_1_27:
- case WM5100_AUDIO_IF_2_1:
- case WM5100_AUDIO_IF_2_2:
- case WM5100_AUDIO_IF_2_3:
- case WM5100_AUDIO_IF_2_4:
- case WM5100_AUDIO_IF_2_5:
- case WM5100_AUDIO_IF_2_6:
- case WM5100_AUDIO_IF_2_7:
- case WM5100_AUDIO_IF_2_8:
- case WM5100_AUDIO_IF_2_9:
- case WM5100_AUDIO_IF_2_10:
- case WM5100_AUDIO_IF_2_11:
- case WM5100_AUDIO_IF_2_18:
- case WM5100_AUDIO_IF_2_19:
- case WM5100_AUDIO_IF_2_26:
- case WM5100_AUDIO_IF_2_27:
- case WM5100_AUDIO_IF_3_1:
- case WM5100_AUDIO_IF_3_2:
- case WM5100_AUDIO_IF_3_3:
- case WM5100_AUDIO_IF_3_4:
- case WM5100_AUDIO_IF_3_5:
- case WM5100_AUDIO_IF_3_6:
- case WM5100_AUDIO_IF_3_7:
- case WM5100_AUDIO_IF_3_8:
- case WM5100_AUDIO_IF_3_9:
- case WM5100_AUDIO_IF_3_10:
- case WM5100_AUDIO_IF_3_11:
- case WM5100_AUDIO_IF_3_18:
- case WM5100_AUDIO_IF_3_19:
- case WM5100_AUDIO_IF_3_26:
- case WM5100_AUDIO_IF_3_27:
- case WM5100_PWM1MIX_INPUT_1_SOURCE:
- case WM5100_PWM1MIX_INPUT_1_VOLUME:
- case WM5100_PWM1MIX_INPUT_2_SOURCE:
- case WM5100_PWM1MIX_INPUT_2_VOLUME:
- case WM5100_PWM1MIX_INPUT_3_SOURCE:
- case WM5100_PWM1MIX_INPUT_3_VOLUME:
- case WM5100_PWM1MIX_INPUT_4_SOURCE:
- case WM5100_PWM1MIX_INPUT_4_VOLUME:
- case WM5100_PWM2MIX_INPUT_1_SOURCE:
- case WM5100_PWM2MIX_INPUT_1_VOLUME:
- case WM5100_PWM2MIX_INPUT_2_SOURCE:
- case WM5100_PWM2MIX_INPUT_2_VOLUME:
- case WM5100_PWM2MIX_INPUT_3_SOURCE:
- case WM5100_PWM2MIX_INPUT_3_VOLUME:
- case WM5100_PWM2MIX_INPUT_4_SOURCE:
- case WM5100_PWM2MIX_INPUT_4_VOLUME:
- case WM5100_OUT1LMIX_INPUT_1_SOURCE:
- case WM5100_OUT1LMIX_INPUT_1_VOLUME:
- case WM5100_OUT1LMIX_INPUT_2_SOURCE:
- case WM5100_OUT1LMIX_INPUT_2_VOLUME:
- case WM5100_OUT1LMIX_INPUT_3_SOURCE:
- case WM5100_OUT1LMIX_INPUT_3_VOLUME:
- case WM5100_OUT1LMIX_INPUT_4_SOURCE:
- case WM5100_OUT1LMIX_INPUT_4_VOLUME:
- case WM5100_OUT1RMIX_INPUT_1_SOURCE:
- case WM5100_OUT1RMIX_INPUT_1_VOLUME:
- case WM5100_OUT1RMIX_INPUT_2_SOURCE:
- case WM5100_OUT1RMIX_INPUT_2_VOLUME:
- case WM5100_OUT1RMIX_INPUT_3_SOURCE:
- case WM5100_OUT1RMIX_INPUT_3_VOLUME:
- case WM5100_OUT1RMIX_INPUT_4_SOURCE:
- case WM5100_OUT1RMIX_INPUT_4_VOLUME:
- case WM5100_OUT2LMIX_INPUT_1_SOURCE:
- case WM5100_OUT2LMIX_INPUT_1_VOLUME:
- case WM5100_OUT2LMIX_INPUT_2_SOURCE:
- case WM5100_OUT2LMIX_INPUT_2_VOLUME:
- case WM5100_OUT2LMIX_INPUT_3_SOURCE:
- case WM5100_OUT2LMIX_INPUT_3_VOLUME:
- case WM5100_OUT2LMIX_INPUT_4_SOURCE:
- case WM5100_OUT2LMIX_INPUT_4_VOLUME:
- case WM5100_OUT2RMIX_INPUT_1_SOURCE:
- case WM5100_OUT2RMIX_INPUT_1_VOLUME:
- case WM5100_OUT2RMIX_INPUT_2_SOURCE:
- case WM5100_OUT2RMIX_INPUT_2_VOLUME:
- case WM5100_OUT2RMIX_INPUT_3_SOURCE:
- case WM5100_OUT2RMIX_INPUT_3_VOLUME:
- case WM5100_OUT2RMIX_INPUT_4_SOURCE:
- case WM5100_OUT2RMIX_INPUT_4_VOLUME:
- case WM5100_OUT3LMIX_INPUT_1_SOURCE:
- case WM5100_OUT3LMIX_INPUT_1_VOLUME:
- case WM5100_OUT3LMIX_INPUT_2_SOURCE:
- case WM5100_OUT3LMIX_INPUT_2_VOLUME:
- case WM5100_OUT3LMIX_INPUT_3_SOURCE:
- case WM5100_OUT3LMIX_INPUT_3_VOLUME:
- case WM5100_OUT3LMIX_INPUT_4_SOURCE:
- case WM5100_OUT3LMIX_INPUT_4_VOLUME:
- case WM5100_OUT3RMIX_INPUT_1_SOURCE:
- case WM5100_OUT3RMIX_INPUT_1_VOLUME:
- case WM5100_OUT3RMIX_INPUT_2_SOURCE:
- case WM5100_OUT3RMIX_INPUT_2_VOLUME:
- case WM5100_OUT3RMIX_INPUT_3_SOURCE:
- case WM5100_OUT3RMIX_INPUT_3_VOLUME:
- case WM5100_OUT3RMIX_INPUT_4_SOURCE:
- case WM5100_OUT3RMIX_INPUT_4_VOLUME:
- case WM5100_OUT4LMIX_INPUT_1_SOURCE:
- case WM5100_OUT4LMIX_INPUT_1_VOLUME:
- case WM5100_OUT4LMIX_INPUT_2_SOURCE:
- case WM5100_OUT4LMIX_INPUT_2_VOLUME:
- case WM5100_OUT4LMIX_INPUT_3_SOURCE:
- case WM5100_OUT4LMIX_INPUT_3_VOLUME:
- case WM5100_OUT4LMIX_INPUT_4_SOURCE:
- case WM5100_OUT4LMIX_INPUT_4_VOLUME:
- case WM5100_OUT4RMIX_INPUT_1_SOURCE:
- case WM5100_OUT4RMIX_INPUT_1_VOLUME:
- case WM5100_OUT4RMIX_INPUT_2_SOURCE:
- case WM5100_OUT4RMIX_INPUT_2_VOLUME:
- case WM5100_OUT4RMIX_INPUT_3_SOURCE:
- case WM5100_OUT4RMIX_INPUT_3_VOLUME:
- case WM5100_OUT4RMIX_INPUT_4_SOURCE:
- case WM5100_OUT4RMIX_INPUT_4_VOLUME:
- case WM5100_OUT5LMIX_INPUT_1_SOURCE:
- case WM5100_OUT5LMIX_INPUT_1_VOLUME:
- case WM5100_OUT5LMIX_INPUT_2_SOURCE:
- case WM5100_OUT5LMIX_INPUT_2_VOLUME:
- case WM5100_OUT5LMIX_INPUT_3_SOURCE:
- case WM5100_OUT5LMIX_INPUT_3_VOLUME:
- case WM5100_OUT5LMIX_INPUT_4_SOURCE:
- case WM5100_OUT5LMIX_INPUT_4_VOLUME:
- case WM5100_OUT5RMIX_INPUT_1_SOURCE:
- case WM5100_OUT5RMIX_INPUT_1_VOLUME:
- case WM5100_OUT5RMIX_INPUT_2_SOURCE:
- case WM5100_OUT5RMIX_INPUT_2_VOLUME:
- case WM5100_OUT5RMIX_INPUT_3_SOURCE:
- case WM5100_OUT5RMIX_INPUT_3_VOLUME:
- case WM5100_OUT5RMIX_INPUT_4_SOURCE:
- case WM5100_OUT5RMIX_INPUT_4_VOLUME:
- case WM5100_OUT6LMIX_INPUT_1_SOURCE:
- case WM5100_OUT6LMIX_INPUT_1_VOLUME:
- case WM5100_OUT6LMIX_INPUT_2_SOURCE:
- case WM5100_OUT6LMIX_INPUT_2_VOLUME:
- case WM5100_OUT6LMIX_INPUT_3_SOURCE:
- case WM5100_OUT6LMIX_INPUT_3_VOLUME:
- case WM5100_OUT6LMIX_INPUT_4_SOURCE:
- case WM5100_OUT6LMIX_INPUT_4_VOLUME:
- case WM5100_OUT6RMIX_INPUT_1_SOURCE:
- case WM5100_OUT6RMIX_INPUT_1_VOLUME:
- case WM5100_OUT6RMIX_INPUT_2_SOURCE:
- case WM5100_OUT6RMIX_INPUT_2_VOLUME:
- case WM5100_OUT6RMIX_INPUT_3_SOURCE:
- case WM5100_OUT6RMIX_INPUT_3_VOLUME:
- case WM5100_OUT6RMIX_INPUT_4_SOURCE:
- case WM5100_OUT6RMIX_INPUT_4_VOLUME:
- case WM5100_AIF1TX1MIX_INPUT_1_SOURCE:
- case WM5100_AIF1TX1MIX_INPUT_1_VOLUME:
- case WM5100_AIF1TX1MIX_INPUT_2_SOURCE:
- case WM5100_AIF1TX1MIX_INPUT_2_VOLUME:
- case WM5100_AIF1TX1MIX_INPUT_3_SOURCE:
- case WM5100_AIF1TX1MIX_INPUT_3_VOLUME:
- case WM5100_AIF1TX1MIX_INPUT_4_SOURCE:
- case WM5100_AIF1TX1MIX_INPUT_4_VOLUME:
- case WM5100_AIF1TX2MIX_INPUT_1_SOURCE:
- case WM5100_AIF1TX2MIX_INPUT_1_VOLUME:
- case WM5100_AIF1TX2MIX_INPUT_2_SOURCE:
- case WM5100_AIF1TX2MIX_INPUT_2_VOLUME:
- case WM5100_AIF1TX2MIX_INPUT_3_SOURCE:
- case WM5100_AIF1TX2MIX_INPUT_3_VOLUME:
- case WM5100_AIF1TX2MIX_INPUT_4_SOURCE:
- case WM5100_AIF1TX2MIX_INPUT_4_VOLUME:
- case WM5100_AIF1TX3MIX_INPUT_1_SOURCE:
- case WM5100_AIF1TX3MIX_INPUT_1_VOLUME:
- case WM5100_AIF1TX3MIX_INPUT_2_SOURCE:
- case WM5100_AIF1TX3MIX_INPUT_2_VOLUME:
- case WM5100_AIF1TX3MIX_INPUT_3_SOURCE:
- case WM5100_AIF1TX3MIX_INPUT_3_VOLUME:
- case WM5100_AIF1TX3MIX_INPUT_4_SOURCE:
- case WM5100_AIF1TX3MIX_INPUT_4_VOLUME:
- case WM5100_AIF1TX4MIX_INPUT_1_SOURCE:
- case WM5100_AIF1TX4MIX_INPUT_1_VOLUME:
- case WM5100_AIF1TX4MIX_INPUT_2_SOURCE:
- case WM5100_AIF1TX4MIX_INPUT_2_VOLUME:
- case WM5100_AIF1TX4MIX_INPUT_3_SOURCE:
- case WM5100_AIF1TX4MIX_INPUT_3_VOLUME:
- case WM5100_AIF1TX4MIX_INPUT_4_SOURCE:
- case WM5100_AIF1TX4MIX_INPUT_4_VOLUME:
- case WM5100_AIF1TX5MIX_INPUT_1_SOURCE:
- case WM5100_AIF1TX5MIX_INPUT_1_VOLUME:
- case WM5100_AIF1TX5MIX_INPUT_2_SOURCE:
- case WM5100_AIF1TX5MIX_INPUT_2_VOLUME:
- case WM5100_AIF1TX5MIX_INPUT_3_SOURCE:
- case WM5100_AIF1TX5MIX_INPUT_3_VOLUME:
- case WM5100_AIF1TX5MIX_INPUT_4_SOURCE:
- case WM5100_AIF1TX5MIX_INPUT_4_VOLUME:
- case WM5100_AIF1TX6MIX_INPUT_1_SOURCE:
- case WM5100_AIF1TX6MIX_INPUT_1_VOLUME:
- case WM5100_AIF1TX6MIX_INPUT_2_SOURCE:
- case WM5100_AIF1TX6MIX_INPUT_2_VOLUME:
- case WM5100_AIF1TX6MIX_INPUT_3_SOURCE:
- case WM5100_AIF1TX6MIX_INPUT_3_VOLUME:
- case WM5100_AIF1TX6MIX_INPUT_4_SOURCE:
- case WM5100_AIF1TX6MIX_INPUT_4_VOLUME:
- case WM5100_AIF1TX7MIX_INPUT_1_SOURCE:
- case WM5100_AIF1TX7MIX_INPUT_1_VOLUME:
- case WM5100_AIF1TX7MIX_INPUT_2_SOURCE:
- case WM5100_AIF1TX7MIX_INPUT_2_VOLUME:
- case WM5100_AIF1TX7MIX_INPUT_3_SOURCE:
- case WM5100_AIF1TX7MIX_INPUT_3_VOLUME:
- case WM5100_AIF1TX7MIX_INPUT_4_SOURCE:
- case WM5100_AIF1TX7MIX_INPUT_4_VOLUME:
- case WM5100_AIF1TX8MIX_INPUT_1_SOURCE:
- case WM5100_AIF1TX8MIX_INPUT_1_VOLUME:
- case WM5100_AIF1TX8MIX_INPUT_2_SOURCE:
- case WM5100_AIF1TX8MIX_INPUT_2_VOLUME:
- case WM5100_AIF1TX8MIX_INPUT_3_SOURCE:
- case WM5100_AIF1TX8MIX_INPUT_3_VOLUME:
- case WM5100_AIF1TX8MIX_INPUT_4_SOURCE:
- case WM5100_AIF1TX8MIX_INPUT_4_VOLUME:
- case WM5100_AIF2TX1MIX_INPUT_1_SOURCE:
- case WM5100_AIF2TX1MIX_INPUT_1_VOLUME:
- case WM5100_AIF2TX1MIX_INPUT_2_SOURCE:
- case WM5100_AIF2TX1MIX_INPUT_2_VOLUME:
- case WM5100_AIF2TX1MIX_INPUT_3_SOURCE:
- case WM5100_AIF2TX1MIX_INPUT_3_VOLUME:
- case WM5100_AIF2TX1MIX_INPUT_4_SOURCE:
- case WM5100_AIF2TX1MIX_INPUT_4_VOLUME:
- case WM5100_AIF2TX2MIX_INPUT_1_SOURCE:
- case WM5100_AIF2TX2MIX_INPUT_1_VOLUME:
- case WM5100_AIF2TX2MIX_INPUT_2_SOURCE:
- case WM5100_AIF2TX2MIX_INPUT_2_VOLUME:
- case WM5100_AIF2TX2MIX_INPUT_3_SOURCE:
- case WM5100_AIF2TX2MIX_INPUT_3_VOLUME:
- case WM5100_AIF2TX2MIX_INPUT_4_SOURCE:
- case WM5100_AIF2TX2MIX_INPUT_4_VOLUME:
- case WM5100_AIF3TX1MIX_INPUT_1_SOURCE:
- case WM5100_AIF3TX1MIX_INPUT_1_VOLUME:
- case WM5100_AIF3TX1MIX_INPUT_2_SOURCE:
- case WM5100_AIF3TX1MIX_INPUT_2_VOLUME:
- case WM5100_AIF3TX1MIX_INPUT_3_SOURCE:
- case WM5100_AIF3TX1MIX_INPUT_3_VOLUME:
- case WM5100_AIF3TX1MIX_INPUT_4_SOURCE:
- case WM5100_AIF3TX1MIX_INPUT_4_VOLUME:
- case WM5100_AIF3TX2MIX_INPUT_1_SOURCE:
- case WM5100_AIF3TX2MIX_INPUT_1_VOLUME:
- case WM5100_AIF3TX2MIX_INPUT_2_SOURCE:
- case WM5100_AIF3TX2MIX_INPUT_2_VOLUME:
- case WM5100_AIF3TX2MIX_INPUT_3_SOURCE:
- case WM5100_AIF3TX2MIX_INPUT_3_VOLUME:
- case WM5100_AIF3TX2MIX_INPUT_4_SOURCE:
- case WM5100_AIF3TX2MIX_INPUT_4_VOLUME:
- case WM5100_EQ1MIX_INPUT_1_SOURCE:
- case WM5100_EQ1MIX_INPUT_1_VOLUME:
- case WM5100_EQ1MIX_INPUT_2_SOURCE:
- case WM5100_EQ1MIX_INPUT_2_VOLUME:
- case WM5100_EQ1MIX_INPUT_3_SOURCE:
- case WM5100_EQ1MIX_INPUT_3_VOLUME:
- case WM5100_EQ1MIX_INPUT_4_SOURCE:
- case WM5100_EQ1MIX_INPUT_4_VOLUME:
- case WM5100_EQ2MIX_INPUT_1_SOURCE:
- case WM5100_EQ2MIX_INPUT_1_VOLUME:
- case WM5100_EQ2MIX_INPUT_2_SOURCE:
- case WM5100_EQ2MIX_INPUT_2_VOLUME:
- case WM5100_EQ2MIX_INPUT_3_SOURCE:
- case WM5100_EQ2MIX_INPUT_3_VOLUME:
- case WM5100_EQ2MIX_INPUT_4_SOURCE:
- case WM5100_EQ2MIX_INPUT_4_VOLUME:
- case WM5100_EQ3MIX_INPUT_1_SOURCE:
- case WM5100_EQ3MIX_INPUT_1_VOLUME:
- case WM5100_EQ3MIX_INPUT_2_SOURCE:
- case WM5100_EQ3MIX_INPUT_2_VOLUME:
- case WM5100_EQ3MIX_INPUT_3_SOURCE:
- case WM5100_EQ3MIX_INPUT_3_VOLUME:
- case WM5100_EQ3MIX_INPUT_4_SOURCE:
- case WM5100_EQ3MIX_INPUT_4_VOLUME:
- case WM5100_EQ4MIX_INPUT_1_SOURCE:
- case WM5100_EQ4MIX_INPUT_1_VOLUME:
- case WM5100_EQ4MIX_INPUT_2_SOURCE:
- case WM5100_EQ4MIX_INPUT_2_VOLUME:
- case WM5100_EQ4MIX_INPUT_3_SOURCE:
- case WM5100_EQ4MIX_INPUT_3_VOLUME:
- case WM5100_EQ4MIX_INPUT_4_SOURCE:
- case WM5100_EQ4MIX_INPUT_4_VOLUME:
- case WM5100_DRC1LMIX_INPUT_1_SOURCE:
- case WM5100_DRC1LMIX_INPUT_1_VOLUME:
- case WM5100_DRC1LMIX_INPUT_2_SOURCE:
- case WM5100_DRC1LMIX_INPUT_2_VOLUME:
- case WM5100_DRC1LMIX_INPUT_3_SOURCE:
- case WM5100_DRC1LMIX_INPUT_3_VOLUME:
- case WM5100_DRC1LMIX_INPUT_4_SOURCE:
- case WM5100_DRC1LMIX_INPUT_4_VOLUME:
- case WM5100_DRC1RMIX_INPUT_1_SOURCE:
- case WM5100_DRC1RMIX_INPUT_1_VOLUME:
- case WM5100_DRC1RMIX_INPUT_2_SOURCE:
- case WM5100_DRC1RMIX_INPUT_2_VOLUME:
- case WM5100_DRC1RMIX_INPUT_3_SOURCE:
- case WM5100_DRC1RMIX_INPUT_3_VOLUME:
- case WM5100_DRC1RMIX_INPUT_4_SOURCE:
- case WM5100_DRC1RMIX_INPUT_4_VOLUME:
- case WM5100_HPLP1MIX_INPUT_1_SOURCE:
- case WM5100_HPLP1MIX_INPUT_1_VOLUME:
- case WM5100_HPLP1MIX_INPUT_2_SOURCE:
- case WM5100_HPLP1MIX_INPUT_2_VOLUME:
- case WM5100_HPLP1MIX_INPUT_3_SOURCE:
- case WM5100_HPLP1MIX_INPUT_3_VOLUME:
- case WM5100_HPLP1MIX_INPUT_4_SOURCE:
- case WM5100_HPLP1MIX_INPUT_4_VOLUME:
- case WM5100_HPLP2MIX_INPUT_1_SOURCE:
- case WM5100_HPLP2MIX_INPUT_1_VOLUME:
- case WM5100_HPLP2MIX_INPUT_2_SOURCE:
- case WM5100_HPLP2MIX_INPUT_2_VOLUME:
- case WM5100_HPLP2MIX_INPUT_3_SOURCE:
- case WM5100_HPLP2MIX_INPUT_3_VOLUME:
- case WM5100_HPLP2MIX_INPUT_4_SOURCE:
- case WM5100_HPLP2MIX_INPUT_4_VOLUME:
- case WM5100_HPLP3MIX_INPUT_1_SOURCE:
- case WM5100_HPLP3MIX_INPUT_1_VOLUME:
- case WM5100_HPLP3MIX_INPUT_2_SOURCE:
- case WM5100_HPLP3MIX_INPUT_2_VOLUME:
- case WM5100_HPLP3MIX_INPUT_3_SOURCE:
- case WM5100_HPLP3MIX_INPUT_3_VOLUME:
- case WM5100_HPLP3MIX_INPUT_4_SOURCE:
- case WM5100_HPLP3MIX_INPUT_4_VOLUME:
- case WM5100_HPLP4MIX_INPUT_1_SOURCE:
- case WM5100_HPLP4MIX_INPUT_1_VOLUME:
- case WM5100_HPLP4MIX_INPUT_2_SOURCE:
- case WM5100_HPLP4MIX_INPUT_2_VOLUME:
- case WM5100_HPLP4MIX_INPUT_3_SOURCE:
- case WM5100_HPLP4MIX_INPUT_3_VOLUME:
- case WM5100_HPLP4MIX_INPUT_4_SOURCE:
- case WM5100_HPLP4MIX_INPUT_4_VOLUME:
- case WM5100_DSP1LMIX_INPUT_1_SOURCE:
- case WM5100_DSP1LMIX_INPUT_1_VOLUME:
- case WM5100_DSP1LMIX_INPUT_2_SOURCE:
- case WM5100_DSP1LMIX_INPUT_2_VOLUME:
- case WM5100_DSP1LMIX_INPUT_3_SOURCE:
- case WM5100_DSP1LMIX_INPUT_3_VOLUME:
- case WM5100_DSP1LMIX_INPUT_4_SOURCE:
- case WM5100_DSP1LMIX_INPUT_4_VOLUME:
- case WM5100_DSP1RMIX_INPUT_1_SOURCE:
- case WM5100_DSP1RMIX_INPUT_1_VOLUME:
- case WM5100_DSP1RMIX_INPUT_2_SOURCE:
- case WM5100_DSP1RMIX_INPUT_2_VOLUME:
- case WM5100_DSP1RMIX_INPUT_3_SOURCE:
- case WM5100_DSP1RMIX_INPUT_3_VOLUME:
- case WM5100_DSP1RMIX_INPUT_4_SOURCE:
- case WM5100_DSP1RMIX_INPUT_4_VOLUME:
- case WM5100_DSP1AUX1MIX_INPUT_1_SOURCE:
- case WM5100_DSP1AUX2MIX_INPUT_1_SOURCE:
- case WM5100_DSP1AUX3MIX_INPUT_1_SOURCE:
- case WM5100_DSP1AUX4MIX_INPUT_1_SOURCE:
- case WM5100_DSP1AUX5MIX_INPUT_1_SOURCE:
- case WM5100_DSP1AUX6MIX_INPUT_1_SOURCE:
- case WM5100_DSP2LMIX_INPUT_1_SOURCE:
- case WM5100_DSP2LMIX_INPUT_1_VOLUME:
- case WM5100_DSP2LMIX_INPUT_2_SOURCE:
- case WM5100_DSP2LMIX_INPUT_2_VOLUME:
- case WM5100_DSP2LMIX_INPUT_3_SOURCE:
- case WM5100_DSP2LMIX_INPUT_3_VOLUME:
- case WM5100_DSP2LMIX_INPUT_4_SOURCE:
- case WM5100_DSP2LMIX_INPUT_4_VOLUME:
- case WM5100_DSP2RMIX_INPUT_1_SOURCE:
- case WM5100_DSP2RMIX_INPUT_1_VOLUME:
- case WM5100_DSP2RMIX_INPUT_2_SOURCE:
- case WM5100_DSP2RMIX_INPUT_2_VOLUME:
- case WM5100_DSP2RMIX_INPUT_3_SOURCE:
- case WM5100_DSP2RMIX_INPUT_3_VOLUME:
- case WM5100_DSP2RMIX_INPUT_4_SOURCE:
- case WM5100_DSP2RMIX_INPUT_4_VOLUME:
- case WM5100_DSP2AUX1MIX_INPUT_1_SOURCE:
- case WM5100_DSP2AUX2MIX_INPUT_1_SOURCE:
- case WM5100_DSP2AUX3MIX_INPUT_1_SOURCE:
- case WM5100_DSP2AUX4MIX_INPUT_1_SOURCE:
- case WM5100_DSP2AUX5MIX_INPUT_1_SOURCE:
- case WM5100_DSP2AUX6MIX_INPUT_1_SOURCE:
- case WM5100_DSP3LMIX_INPUT_1_SOURCE:
- case WM5100_DSP3LMIX_INPUT_1_VOLUME:
- case WM5100_DSP3LMIX_INPUT_2_SOURCE:
- case WM5100_DSP3LMIX_INPUT_2_VOLUME:
- case WM5100_DSP3LMIX_INPUT_3_SOURCE:
- case WM5100_DSP3LMIX_INPUT_3_VOLUME:
- case WM5100_DSP3LMIX_INPUT_4_SOURCE:
- case WM5100_DSP3LMIX_INPUT_4_VOLUME:
- case WM5100_DSP3RMIX_INPUT_1_SOURCE:
- case WM5100_DSP3RMIX_INPUT_1_VOLUME:
- case WM5100_DSP3RMIX_INPUT_2_SOURCE:
- case WM5100_DSP3RMIX_INPUT_2_VOLUME:
- case WM5100_DSP3RMIX_INPUT_3_SOURCE:
- case WM5100_DSP3RMIX_INPUT_3_VOLUME:
- case WM5100_DSP3RMIX_INPUT_4_SOURCE:
- case WM5100_DSP3RMIX_INPUT_4_VOLUME:
- case WM5100_DSP3AUX1MIX_INPUT_1_SOURCE:
- case WM5100_DSP3AUX2MIX_INPUT_1_SOURCE:
- case WM5100_DSP3AUX3MIX_INPUT_1_SOURCE:
- case WM5100_DSP3AUX4MIX_INPUT_1_SOURCE:
- case WM5100_DSP3AUX5MIX_INPUT_1_SOURCE:
- case WM5100_DSP3AUX6MIX_INPUT_1_SOURCE:
- case WM5100_ASRC1LMIX_INPUT_1_SOURCE:
- case WM5100_ASRC1RMIX_INPUT_1_SOURCE:
- case WM5100_ASRC2LMIX_INPUT_1_SOURCE:
- case WM5100_ASRC2RMIX_INPUT_1_SOURCE:
- case WM5100_ISRC1DEC1MIX_INPUT_1_SOURCE:
- case WM5100_ISRC1DEC2MIX_INPUT_1_SOURCE:
- case WM5100_ISRC1DEC3MIX_INPUT_1_SOURCE:
- case WM5100_ISRC1DEC4MIX_INPUT_1_SOURCE:
- case WM5100_ISRC1INT1MIX_INPUT_1_SOURCE:
- case WM5100_ISRC1INT2MIX_INPUT_1_SOURCE:
- case WM5100_ISRC1INT3MIX_INPUT_1_SOURCE:
- case WM5100_ISRC1INT4MIX_INPUT_1_SOURCE:
- case WM5100_ISRC2DEC1MIX_INPUT_1_SOURCE:
- case WM5100_ISRC2DEC2MIX_INPUT_1_SOURCE:
- case WM5100_ISRC2DEC3MIX_INPUT_1_SOURCE:
- case WM5100_ISRC2DEC4MIX_INPUT_1_SOURCE:
- case WM5100_ISRC2INT1MIX_INPUT_1_SOURCE:
- case WM5100_ISRC2INT2MIX_INPUT_1_SOURCE:
- case WM5100_ISRC2INT3MIX_INPUT_1_SOURCE:
- case WM5100_ISRC2INT4MIX_INPUT_1_SOURCE:
- case WM5100_GPIO_CTRL_1:
- case WM5100_GPIO_CTRL_2:
- case WM5100_GPIO_CTRL_3:
- case WM5100_GPIO_CTRL_4:
- case WM5100_GPIO_CTRL_5:
- case WM5100_GPIO_CTRL_6:
- case WM5100_MISC_PAD_CTRL_1:
- case WM5100_MISC_PAD_CTRL_2:
- case WM5100_MISC_PAD_CTRL_3:
- case WM5100_MISC_PAD_CTRL_4:
- case WM5100_MISC_PAD_CTRL_5:
- case WM5100_MISC_GPIO_1:
- case WM5100_INTERRUPT_STATUS_1:
- case WM5100_INTERRUPT_STATUS_2:
- case WM5100_INTERRUPT_STATUS_3:
- case WM5100_INTERRUPT_STATUS_4:
- case WM5100_INTERRUPT_RAW_STATUS_2:
- case WM5100_INTERRUPT_RAW_STATUS_3:
- case WM5100_INTERRUPT_RAW_STATUS_4:
- case WM5100_INTERRUPT_STATUS_1_MASK:
- case WM5100_INTERRUPT_STATUS_2_MASK:
- case WM5100_INTERRUPT_STATUS_3_MASK:
- case WM5100_INTERRUPT_STATUS_4_MASK:
- case WM5100_INTERRUPT_CONTROL:
- case WM5100_IRQ_DEBOUNCE_1:
- case WM5100_IRQ_DEBOUNCE_2:
- case WM5100_FX_CTRL:
- case WM5100_EQ1_1:
- case WM5100_EQ1_2:
- case WM5100_EQ1_3:
- case WM5100_EQ1_4:
- case WM5100_EQ1_5:
- case WM5100_EQ1_6:
- case WM5100_EQ1_7:
- case WM5100_EQ1_8:
- case WM5100_EQ1_9:
- case WM5100_EQ1_10:
- case WM5100_EQ1_11:
- case WM5100_EQ1_12:
- case WM5100_EQ1_13:
- case WM5100_EQ1_14:
- case WM5100_EQ1_15:
- case WM5100_EQ1_16:
- case WM5100_EQ1_17:
- case WM5100_EQ1_18:
- case WM5100_EQ1_19:
- case WM5100_EQ1_20:
- case WM5100_EQ2_1:
- case WM5100_EQ2_2:
- case WM5100_EQ2_3:
- case WM5100_EQ2_4:
- case WM5100_EQ2_5:
- case WM5100_EQ2_6:
- case WM5100_EQ2_7:
- case WM5100_EQ2_8:
- case WM5100_EQ2_9:
- case WM5100_EQ2_10:
- case WM5100_EQ2_11:
- case WM5100_EQ2_12:
- case WM5100_EQ2_13:
- case WM5100_EQ2_14:
- case WM5100_EQ2_15:
- case WM5100_EQ2_16:
- case WM5100_EQ2_17:
- case WM5100_EQ2_18:
- case WM5100_EQ2_19:
- case WM5100_EQ2_20:
- case WM5100_EQ3_1:
- case WM5100_EQ3_2:
- case WM5100_EQ3_3:
- case WM5100_EQ3_4:
- case WM5100_EQ3_5:
- case WM5100_EQ3_6:
- case WM5100_EQ3_7:
- case WM5100_EQ3_8:
- case WM5100_EQ3_9:
- case WM5100_EQ3_10:
- case WM5100_EQ3_11:
- case WM5100_EQ3_12:
- case WM5100_EQ3_13:
- case WM5100_EQ3_14:
- case WM5100_EQ3_15:
- case WM5100_EQ3_16:
- case WM5100_EQ3_17:
- case WM5100_EQ3_18:
- case WM5100_EQ3_19:
- case WM5100_EQ3_20:
- case WM5100_EQ4_1:
- case WM5100_EQ4_2:
- case WM5100_EQ4_3:
- case WM5100_EQ4_4:
- case WM5100_EQ4_5:
- case WM5100_EQ4_6:
- case WM5100_EQ4_7:
- case WM5100_EQ4_8:
- case WM5100_EQ4_9:
- case WM5100_EQ4_10:
- case WM5100_EQ4_11:
- case WM5100_EQ4_12:
- case WM5100_EQ4_13:
- case WM5100_EQ4_14:
- case WM5100_EQ4_15:
- case WM5100_EQ4_16:
- case WM5100_EQ4_17:
- case WM5100_EQ4_18:
- case WM5100_EQ4_19:
- case WM5100_EQ4_20:
- case WM5100_DRC1_CTRL1:
- case WM5100_DRC1_CTRL2:
- case WM5100_DRC1_CTRL3:
- case WM5100_DRC1_CTRL4:
- case WM5100_DRC1_CTRL5:
- case WM5100_HPLPF1_1:
- case WM5100_HPLPF1_2:
- case WM5100_HPLPF2_1:
- case WM5100_HPLPF2_2:
- case WM5100_HPLPF3_1:
- case WM5100_HPLPF3_2:
- case WM5100_HPLPF4_1:
- case WM5100_HPLPF4_2:
- return 1;
- default:
- return 0;
- }
-}
-
-struct reg_default wm5100_reg_defaults[WM5100_REGISTER_COUNT] = {
- { 0x0000, 0x0000 }, /* R0 - software reset */
- { 0x0001, 0x0000 }, /* R1 - Device Revision */
- { 0x0010, 0x0801 }, /* R16 - Ctrl IF 1 */
- { 0x0020, 0x0000 }, /* R32 - Tone Generator 1 */
- { 0x0030, 0x0000 }, /* R48 - PWM Drive 1 */
- { 0x0031, 0x0100 }, /* R49 - PWM Drive 2 */
- { 0x0032, 0x0100 }, /* R50 - PWM Drive 3 */
- { 0x0100, 0x0002 }, /* R256 - Clocking 1 */
- { 0x0101, 0x0000 }, /* R257 - Clocking 3 */
- { 0x0102, 0x0011 }, /* R258 - Clocking 4 */
- { 0x0103, 0x0011 }, /* R259 - Clocking 5 */
- { 0x0104, 0x0011 }, /* R260 - Clocking 6 */
- { 0x0107, 0x0000 }, /* R263 - Clocking 7 */
- { 0x0108, 0x0000 }, /* R264 - Clocking 8 */
- { 0x0120, 0x0000 }, /* R288 - ASRC_ENABLE */
- { 0x0121, 0x0000 }, /* R289 - ASRC_STATUS */
- { 0x0122, 0x0000 }, /* R290 - ASRC_RATE1 */
- { 0x0141, 0x8000 }, /* R321 - ISRC 1 CTRL 1 */
- { 0x0142, 0x0000 }, /* R322 - ISRC 1 CTRL 2 */
- { 0x0143, 0x8000 }, /* R323 - ISRC 2 CTRL1 */
- { 0x0144, 0x0000 }, /* R324 - ISRC 2 CTRL 2 */
- { 0x0182, 0x0000 }, /* R386 - FLL1 Control 1 */
- { 0x0183, 0x0000 }, /* R387 - FLL1 Control 2 */
- { 0x0184, 0x0000 }, /* R388 - FLL1 Control 3 */
- { 0x0186, 0x0177 }, /* R390 - FLL1 Control 5 */
- { 0x0187, 0x0001 }, /* R391 - FLL1 Control 6 */
- { 0x0188, 0x0000 }, /* R392 - FLL1 EFS 1 */
- { 0x01A2, 0x0000 }, /* R418 - FLL2 Control 1 */
- { 0x01A3, 0x0000 }, /* R419 - FLL2 Control 2 */
- { 0x01A4, 0x0000 }, /* R420 - FLL2 Control 3 */
- { 0x01A6, 0x0177 }, /* R422 - FLL2 Control 5 */
- { 0x01A7, 0x0001 }, /* R423 - FLL2 Control 6 */
- { 0x01A8, 0x0000 }, /* R424 - FLL2 EFS 1 */
- { 0x0200, 0x0020 }, /* R512 - Mic Charge Pump 1 */
- { 0x0201, 0xB084 }, /* R513 - Mic Charge Pump 2 */
- { 0x0202, 0xBBDE }, /* R514 - HP Charge Pump 1 */
- { 0x0211, 0x20D4 }, /* R529 - LDO1 Control */
- { 0x0215, 0x0062 }, /* R533 - Mic Bias Ctrl 1 */
- { 0x0216, 0x0062 }, /* R534 - Mic Bias Ctrl 2 */
- { 0x0217, 0x0062 }, /* R535 - Mic Bias Ctrl 3 */
- { 0x0280, 0x0004 }, /* R640 - Accessory Detect Mode 1 */
- { 0x0288, 0x0020 }, /* R648 - Headphone Detect 1 */
- { 0x0289, 0x0000 }, /* R649 - Headphone Detect 2 */
- { 0x0290, 0x1100 }, /* R656 - Mic Detect 1 */
- { 0x0291, 0x009F }, /* R657 - Mic Detect 2 */
- { 0x0292, 0x0000 }, /* R658 - Mic Detect 3 */
- { 0x0301, 0x0000 }, /* R769 - Input Enables */
- { 0x0302, 0x0000 }, /* R770 - Input Enables Status */
- { 0x0310, 0x2280 }, /* R784 - Status */
- { 0x0311, 0x0080 }, /* R785 - IN1R Control */
- { 0x0312, 0x2280 }, /* R786 - IN2L Control */
- { 0x0313, 0x0080 }, /* R787 - IN2R Control */
- { 0x0314, 0x2280 }, /* R788 - IN3L Control */
- { 0x0315, 0x0080 }, /* R789 - IN3R Control */
- { 0x0316, 0x2280 }, /* R790 - IN4L Control */
- { 0x0317, 0x0080 }, /* R791 - IN4R Control */
- { 0x0318, 0x0000 }, /* R792 - RXANC_SRC */
- { 0x0319, 0x0022 }, /* R793 - Input Volume Ramp */
- { 0x0320, 0x0180 }, /* R800 - ADC Digital Volume 1L */
- { 0x0321, 0x0180 }, /* R801 - ADC Digital Volume 1R */
- { 0x0322, 0x0180 }, /* R802 - ADC Digital Volume 2L */
- { 0x0323, 0x0180 }, /* R803 - ADC Digital Volume 2R */
- { 0x0324, 0x0180 }, /* R804 - ADC Digital Volume 3L */
- { 0x0325, 0x0180 }, /* R805 - ADC Digital Volume 3R */
- { 0x0326, 0x0180 }, /* R806 - ADC Digital Volume 4L */
- { 0x0327, 0x0180 }, /* R807 - ADC Digital Volume 4R */
- { 0x0401, 0x0000 }, /* R1025 - Output Enables 2 */
- { 0x0402, 0x0000 }, /* R1026 - Output Status 1 */
- { 0x0403, 0x0000 }, /* R1027 - Output Status 2 */
- { 0x0408, 0x0000 }, /* R1032 - Channel Enables 1 */
- { 0x0410, 0x0080 }, /* R1040 - Out Volume 1L */
- { 0x0411, 0x0080 }, /* R1041 - Out Volume 1R */
- { 0x0412, 0x0080 }, /* R1042 - DAC Volume Limit 1L */
- { 0x0413, 0x0080 }, /* R1043 - DAC Volume Limit 1R */
- { 0x0414, 0x0080 }, /* R1044 - Out Volume 2L */
- { 0x0415, 0x0080 }, /* R1045 - Out Volume 2R */
- { 0x0416, 0x0080 }, /* R1046 - DAC Volume Limit 2L */
- { 0x0417, 0x0080 }, /* R1047 - DAC Volume Limit 2R */
- { 0x0418, 0x0080 }, /* R1048 - Out Volume 3L */
- { 0x0419, 0x0080 }, /* R1049 - Out Volume 3R */
- { 0x041A, 0x0080 }, /* R1050 - DAC Volume Limit 3L */
- { 0x041B, 0x0080 }, /* R1051 - DAC Volume Limit 3R */
- { 0x041C, 0x0080 }, /* R1052 - Out Volume 4L */
- { 0x041D, 0x0080 }, /* R1053 - Out Volume 4R */
- { 0x041E, 0x0080 }, /* R1054 - DAC Volume Limit 5L */
- { 0x041F, 0x0080 }, /* R1055 - DAC Volume Limit 5R */
- { 0x0420, 0x0080 }, /* R1056 - DAC Volume Limit 6L */
- { 0x0421, 0x0080 }, /* R1057 - DAC Volume Limit 6R */
- { 0x0440, 0x0000 }, /* R1088 - DAC AEC Control 1 */
- { 0x0441, 0x0022 }, /* R1089 - Output Volume Ramp */
- { 0x0480, 0x0180 }, /* R1152 - DAC Digital Volume 1L */
- { 0x0481, 0x0180 }, /* R1153 - DAC Digital Volume 1R */
- { 0x0482, 0x0180 }, /* R1154 - DAC Digital Volume 2L */
- { 0x0483, 0x0180 }, /* R1155 - DAC Digital Volume 2R */
- { 0x0484, 0x0180 }, /* R1156 - DAC Digital Volume 3L */
- { 0x0485, 0x0180 }, /* R1157 - DAC Digital Volume 3R */
- { 0x0486, 0x0180 }, /* R1158 - DAC Digital Volume 4L */
- { 0x0487, 0x0180 }, /* R1159 - DAC Digital Volume 4R */
- { 0x0488, 0x0180 }, /* R1160 - DAC Digital Volume 5L */
- { 0x0489, 0x0180 }, /* R1161 - DAC Digital Volume 5R */
- { 0x048A, 0x0180 }, /* R1162 - DAC Digital Volume 6L */
- { 0x048B, 0x0180 }, /* R1163 - DAC Digital Volume 6R */
- { 0x04C0, 0x0069 }, /* R1216 - PDM SPK1 CTRL 1 */
- { 0x04C1, 0x0000 }, /* R1217 - PDM SPK1 CTRL 2 */
- { 0x04C2, 0x0069 }, /* R1218 - PDM SPK2 CTRL 1 */
- { 0x04C3, 0x0000 }, /* R1219 - PDM SPK2 CTRL 2 */
- { 0x0500, 0x000C }, /* R1280 - Audio IF 1_1 */
- { 0x0501, 0x0008 }, /* R1281 - Audio IF 1_2 */
- { 0x0502, 0x0000 }, /* R1282 - Audio IF 1_3 */
- { 0x0503, 0x0000 }, /* R1283 - Audio IF 1_4 */
- { 0x0504, 0x0000 }, /* R1284 - Audio IF 1_5 */
- { 0x0505, 0x0300 }, /* R1285 - Audio IF 1_6 */
- { 0x0506, 0x0300 }, /* R1286 - Audio IF 1_7 */
- { 0x0507, 0x1820 }, /* R1287 - Audio IF 1_8 */
- { 0x0508, 0x1820 }, /* R1288 - Audio IF 1_9 */
- { 0x0509, 0x0000 }, /* R1289 - Audio IF 1_10 */
- { 0x050A, 0x0001 }, /* R1290 - Audio IF 1_11 */
- { 0x050B, 0x0002 }, /* R1291 - Audio IF 1_12 */
- { 0x050C, 0x0003 }, /* R1292 - Audio IF 1_13 */
- { 0x050D, 0x0004 }, /* R1293 - Audio IF 1_14 */
- { 0x050E, 0x0005 }, /* R1294 - Audio IF 1_15 */
- { 0x050F, 0x0006 }, /* R1295 - Audio IF 1_16 */
- { 0x0510, 0x0007 }, /* R1296 - Audio IF 1_17 */
- { 0x0511, 0x0000 }, /* R1297 - Audio IF 1_18 */
- { 0x0512, 0x0001 }, /* R1298 - Audio IF 1_19 */
- { 0x0513, 0x0002 }, /* R1299 - Audio IF 1_20 */
- { 0x0514, 0x0003 }, /* R1300 - Audio IF 1_21 */
- { 0x0515, 0x0004 }, /* R1301 - Audio IF 1_22 */
- { 0x0516, 0x0005 }, /* R1302 - Audio IF 1_23 */
- { 0x0517, 0x0006 }, /* R1303 - Audio IF 1_24 */
- { 0x0518, 0x0007 }, /* R1304 - Audio IF 1_25 */
- { 0x0519, 0x0000 }, /* R1305 - Audio IF 1_26 */
- { 0x051A, 0x0000 }, /* R1306 - Audio IF 1_27 */
- { 0x0540, 0x000C }, /* R1344 - Audio IF 2_1 */
- { 0x0541, 0x0008 }, /* R1345 - Audio IF 2_2 */
- { 0x0542, 0x0000 }, /* R1346 - Audio IF 2_3 */
- { 0x0543, 0x0000 }, /* R1347 - Audio IF 2_4 */
- { 0x0544, 0x0000 }, /* R1348 - Audio IF 2_5 */
- { 0x0545, 0x0300 }, /* R1349 - Audio IF 2_6 */
- { 0x0546, 0x0300 }, /* R1350 - Audio IF 2_7 */
- { 0x0547, 0x1820 }, /* R1351 - Audio IF 2_8 */
- { 0x0548, 0x1820 }, /* R1352 - Audio IF 2_9 */
- { 0x0549, 0x0000 }, /* R1353 - Audio IF 2_10 */
- { 0x054A, 0x0001 }, /* R1354 - Audio IF 2_11 */
- { 0x0551, 0x0000 }, /* R1361 - Audio IF 2_18 */
- { 0x0552, 0x0001 }, /* R1362 - Audio IF 2_19 */
- { 0x0559, 0x0000 }, /* R1369 - Audio IF 2_26 */
- { 0x055A, 0x0000 }, /* R1370 - Audio IF 2_27 */
- { 0x0580, 0x000C }, /* R1408 - Audio IF 3_1 */
- { 0x0581, 0x0008 }, /* R1409 - Audio IF 3_2 */
- { 0x0582, 0x0000 }, /* R1410 - Audio IF 3_3 */
- { 0x0583, 0x0000 }, /* R1411 - Audio IF 3_4 */
- { 0x0584, 0x0000 }, /* R1412 - Audio IF 3_5 */
- { 0x0585, 0x0300 }, /* R1413 - Audio IF 3_6 */
- { 0x0586, 0x0300 }, /* R1414 - Audio IF 3_7 */
- { 0x0587, 0x1820 }, /* R1415 - Audio IF 3_8 */
- { 0x0588, 0x1820 }, /* R1416 - Audio IF 3_9 */
- { 0x0589, 0x0000 }, /* R1417 - Audio IF 3_10 */
- { 0x058A, 0x0001 }, /* R1418 - Audio IF 3_11 */
- { 0x0591, 0x0000 }, /* R1425 - Audio IF 3_18 */
- { 0x0592, 0x0001 }, /* R1426 - Audio IF 3_19 */
- { 0x0599, 0x0000 }, /* R1433 - Audio IF 3_26 */
- { 0x059A, 0x0000 }, /* R1434 - Audio IF 3_27 */
- { 0x0640, 0x0000 }, /* R1600 - PWM1MIX Input 1 Source */
- { 0x0641, 0x0080 }, /* R1601 - PWM1MIX Input 1 Volume */
- { 0x0642, 0x0000 }, /* R1602 - PWM1MIX Input 2 Source */
- { 0x0643, 0x0080 }, /* R1603 - PWM1MIX Input 2 Volume */
- { 0x0644, 0x0000 }, /* R1604 - PWM1MIX Input 3 Source */
- { 0x0645, 0x0080 }, /* R1605 - PWM1MIX Input 3 Volume */
- { 0x0646, 0x0000 }, /* R1606 - PWM1MIX Input 4 Source */
- { 0x0647, 0x0080 }, /* R1607 - PWM1MIX Input 4 Volume */
- { 0x0648, 0x0000 }, /* R1608 - PWM2MIX Input 1 Source */
- { 0x0649, 0x0080 }, /* R1609 - PWM2MIX Input 1 Volume */
- { 0x064A, 0x0000 }, /* R1610 - PWM2MIX Input 2 Source */
- { 0x064B, 0x0080 }, /* R1611 - PWM2MIX Input 2 Volume */
- { 0x064C, 0x0000 }, /* R1612 - PWM2MIX Input 3 Source */
- { 0x064D, 0x0080 }, /* R1613 - PWM2MIX Input 3 Volume */
- { 0x064E, 0x0000 }, /* R1614 - PWM2MIX Input 4 Source */
- { 0x064F, 0x0080 }, /* R1615 - PWM2MIX Input 4 Volume */
- { 0x0680, 0x0000 }, /* R1664 - OUT1LMIX Input 1 Source */
- { 0x0681, 0x0080 }, /* R1665 - OUT1LMIX Input 1 Volume */
- { 0x0682, 0x0000 }, /* R1666 - OUT1LMIX Input 2 Source */
- { 0x0683, 0x0080 }, /* R1667 - OUT1LMIX Input 2 Volume */
- { 0x0684, 0x0000 }, /* R1668 - OUT1LMIX Input 3 Source */
- { 0x0685, 0x0080 }, /* R1669 - OUT1LMIX Input 3 Volume */
- { 0x0686, 0x0000 }, /* R1670 - OUT1LMIX Input 4 Source */
- { 0x0687, 0x0080 }, /* R1671 - OUT1LMIX Input 4 Volume */
- { 0x0688, 0x0000 }, /* R1672 - OUT1RMIX Input 1 Source */
- { 0x0689, 0x0080 }, /* R1673 - OUT1RMIX Input 1 Volume */
- { 0x068A, 0x0000 }, /* R1674 - OUT1RMIX Input 2 Source */
- { 0x068B, 0x0080 }, /* R1675 - OUT1RMIX Input 2 Volume */
- { 0x068C, 0x0000 }, /* R1676 - OUT1RMIX Input 3 Source */
- { 0x068D, 0x0080 }, /* R1677 - OUT1RMIX Input 3 Volume */
- { 0x068E, 0x0000 }, /* R1678 - OUT1RMIX Input 4 Source */
- { 0x068F, 0x0080 }, /* R1679 - OUT1RMIX Input 4 Volume */
- { 0x0690, 0x0000 }, /* R1680 - OUT2LMIX Input 1 Source */
- { 0x0691, 0x0080 }, /* R1681 - OUT2LMIX Input 1 Volume */
- { 0x0692, 0x0000 }, /* R1682 - OUT2LMIX Input 2 Source */
- { 0x0693, 0x0080 }, /* R1683 - OUT2LMIX Input 2 Volume */
- { 0x0694, 0x0000 }, /* R1684 - OUT2LMIX Input 3 Source */
- { 0x0695, 0x0080 }, /* R1685 - OUT2LMIX Input 3 Volume */
- { 0x0696, 0x0000 }, /* R1686 - OUT2LMIX Input 4 Source */
- { 0x0697, 0x0080 }, /* R1687 - OUT2LMIX Input 4 Volume */
- { 0x0698, 0x0000 }, /* R1688 - OUT2RMIX Input 1 Source */
- { 0x0699, 0x0080 }, /* R1689 - OUT2RMIX Input 1 Volume */
- { 0x069A, 0x0000 }, /* R1690 - OUT2RMIX Input 2 Source */
- { 0x069B, 0x0080 }, /* R1691 - OUT2RMIX Input 2 Volume */
- { 0x069C, 0x0000 }, /* R1692 - OUT2RMIX Input 3 Source */
- { 0x069D, 0x0080 }, /* R1693 - OUT2RMIX Input 3 Volume */
- { 0x069E, 0x0000 }, /* R1694 - OUT2RMIX Input 4 Source */
- { 0x069F, 0x0080 }, /* R1695 - OUT2RMIX Input 4 Volume */
- { 0x06A0, 0x0000 }, /* R1696 - OUT3LMIX Input 1 Source */
- { 0x06A1, 0x0080 }, /* R1697 - OUT3LMIX Input 1 Volume */
- { 0x06A2, 0x0000 }, /* R1698 - OUT3LMIX Input 2 Source */
- { 0x06A3, 0x0080 }, /* R1699 - OUT3LMIX Input 2 Volume */
- { 0x06A4, 0x0000 }, /* R1700 - OUT3LMIX Input 3 Source */
- { 0x06A5, 0x0080 }, /* R1701 - OUT3LMIX Input 3 Volume */
- { 0x06A6, 0x0000 }, /* R1702 - OUT3LMIX Input 4 Source */
- { 0x06A7, 0x0080 }, /* R1703 - OUT3LMIX Input 4 Volume */
- { 0x06A8, 0x0000 }, /* R1704 - OUT3RMIX Input 1 Source */
- { 0x06A9, 0x0080 }, /* R1705 - OUT3RMIX Input 1 Volume */
- { 0x06AA, 0x0000 }, /* R1706 - OUT3RMIX Input 2 Source */
- { 0x06AB, 0x0080 }, /* R1707 - OUT3RMIX Input 2 Volume */
- { 0x06AC, 0x0000 }, /* R1708 - OUT3RMIX Input 3 Source */
- { 0x06AD, 0x0080 }, /* R1709 - OUT3RMIX Input 3 Volume */
- { 0x06AE, 0x0000 }, /* R1710 - OUT3RMIX Input 4 Source */
- { 0x06AF, 0x0080 }, /* R1711 - OUT3RMIX Input 4 Volume */
- { 0x06B0, 0x0000 }, /* R1712 - OUT4LMIX Input 1 Source */
- { 0x06B1, 0x0080 }, /* R1713 - OUT4LMIX Input 1 Volume */
- { 0x06B2, 0x0000 }, /* R1714 - OUT4LMIX Input 2 Source */
- { 0x06B3, 0x0080 }, /* R1715 - OUT4LMIX Input 2 Volume */
- { 0x06B4, 0x0000 }, /* R1716 - OUT4LMIX Input 3 Source */
- { 0x06B5, 0x0080 }, /* R1717 - OUT4LMIX Input 3 Volume */
- { 0x06B6, 0x0000 }, /* R1718 - OUT4LMIX Input 4 Source */
- { 0x06B7, 0x0080 }, /* R1719 - OUT4LMIX Input 4 Volume */
- { 0x06B8, 0x0000 }, /* R1720 - OUT4RMIX Input 1 Source */
- { 0x06B9, 0x0080 }, /* R1721 - OUT4RMIX Input 1 Volume */
- { 0x06BA, 0x0000 }, /* R1722 - OUT4RMIX Input 2 Source */
- { 0x06BB, 0x0080 }, /* R1723 - OUT4RMIX Input 2 Volume */
- { 0x06BC, 0x0000 }, /* R1724 - OUT4RMIX Input 3 Source */
- { 0x06BD, 0x0080 }, /* R1725 - OUT4RMIX Input 3 Volume */
- { 0x06BE, 0x0000 }, /* R1726 - OUT4RMIX Input 4 Source */
- { 0x06BF, 0x0080 }, /* R1727 - OUT4RMIX Input 4 Volume */
- { 0x06C0, 0x0000 }, /* R1728 - OUT5LMIX Input 1 Source */
- { 0x06C1, 0x0080 }, /* R1729 - OUT5LMIX Input 1 Volume */
- { 0x06C2, 0x0000 }, /* R1730 - OUT5LMIX Input 2 Source */
- { 0x06C3, 0x0080 }, /* R1731 - OUT5LMIX Input 2 Volume */
- { 0x06C4, 0x0000 }, /* R1732 - OUT5LMIX Input 3 Source */
- { 0x06C5, 0x0080 }, /* R1733 - OUT5LMIX Input 3 Volume */
- { 0x06C6, 0x0000 }, /* R1734 - OUT5LMIX Input 4 Source */
- { 0x06C7, 0x0080 }, /* R1735 - OUT5LMIX Input 4 Volume */
- { 0x06C8, 0x0000 }, /* R1736 - OUT5RMIX Input 1 Source */
- { 0x06C9, 0x0080 }, /* R1737 - OUT5RMIX Input 1 Volume */
- { 0x06CA, 0x0000 }, /* R1738 - OUT5RMIX Input 2 Source */
- { 0x06CB, 0x0080 }, /* R1739 - OUT5RMIX Input 2 Volume */
- { 0x06CC, 0x0000 }, /* R1740 - OUT5RMIX Input 3 Source */
- { 0x06CD, 0x0080 }, /* R1741 - OUT5RMIX Input 3 Volume */
- { 0x06CE, 0x0000 }, /* R1742 - OUT5RMIX Input 4 Source */
- { 0x06CF, 0x0080 }, /* R1743 - OUT5RMIX Input 4 Volume */
- { 0x06D0, 0x0000 }, /* R1744 - OUT6LMIX Input 1 Source */
- { 0x06D1, 0x0080 }, /* R1745 - OUT6LMIX Input 1 Volume */
- { 0x06D2, 0x0000 }, /* R1746 - OUT6LMIX Input 2 Source */
- { 0x06D3, 0x0080 }, /* R1747 - OUT6LMIX Input 2 Volume */
- { 0x06D4, 0x0000 }, /* R1748 - OUT6LMIX Input 3 Source */
- { 0x06D5, 0x0080 }, /* R1749 - OUT6LMIX Input 3 Volume */
- { 0x06D6, 0x0000 }, /* R1750 - OUT6LMIX Input 4 Source */
- { 0x06D7, 0x0080 }, /* R1751 - OUT6LMIX Input 4 Volume */
- { 0x06D8, 0x0000 }, /* R1752 - OUT6RMIX Input 1 Source */
- { 0x06D9, 0x0080 }, /* R1753 - OUT6RMIX Input 1 Volume */
- { 0x06DA, 0x0000 }, /* R1754 - OUT6RMIX Input 2 Source */
- { 0x06DB, 0x0080 }, /* R1755 - OUT6RMIX Input 2 Volume */
- { 0x06DC, 0x0000 }, /* R1756 - OUT6RMIX Input 3 Source */
- { 0x06DD, 0x0080 }, /* R1757 - OUT6RMIX Input 3 Volume */
- { 0x06DE, 0x0000 }, /* R1758 - OUT6RMIX Input 4 Source */
- { 0x06DF, 0x0080 }, /* R1759 - OUT6RMIX Input 4 Volume */
- { 0x0700, 0x0000 }, /* R1792 - AIF1TX1MIX Input 1 Source */
- { 0x0701, 0x0080 }, /* R1793 - AIF1TX1MIX Input 1 Volume */
- { 0x0702, 0x0000 }, /* R1794 - AIF1TX1MIX Input 2 Source */
- { 0x0703, 0x0080 }, /* R1795 - AIF1TX1MIX Input 2 Volume */
- { 0x0704, 0x0000 }, /* R1796 - AIF1TX1MIX Input 3 Source */
- { 0x0705, 0x0080 }, /* R1797 - AIF1TX1MIX Input 3 Volume */
- { 0x0706, 0x0000 }, /* R1798 - AIF1TX1MIX Input 4 Source */
- { 0x0707, 0x0080 }, /* R1799 - AIF1TX1MIX Input 4 Volume */
- { 0x0708, 0x0000 }, /* R1800 - AIF1TX2MIX Input 1 Source */
- { 0x0709, 0x0080 }, /* R1801 - AIF1TX2MIX Input 1 Volume */
- { 0x070A, 0x0000 }, /* R1802 - AIF1TX2MIX Input 2 Source */
- { 0x070B, 0x0080 }, /* R1803 - AIF1TX2MIX Input 2 Volume */
- { 0x070C, 0x0000 }, /* R1804 - AIF1TX2MIX Input 3 Source */
- { 0x070D, 0x0080 }, /* R1805 - AIF1TX2MIX Input 3 Volume */
- { 0x070E, 0x0000 }, /* R1806 - AIF1TX2MIX Input 4 Source */
- { 0x070F, 0x0080 }, /* R1807 - AIF1TX2MIX Input 4 Volume */
- { 0x0710, 0x0000 }, /* R1808 - AIF1TX3MIX Input 1 Source */
- { 0x0711, 0x0080 }, /* R1809 - AIF1TX3MIX Input 1 Volume */
- { 0x0712, 0x0000 }, /* R1810 - AIF1TX3MIX Input 2 Source */
- { 0x0713, 0x0080 }, /* R1811 - AIF1TX3MIX Input 2 Volume */
- { 0x0714, 0x0000 }, /* R1812 - AIF1TX3MIX Input 3 Source */
- { 0x0715, 0x0080 }, /* R1813 - AIF1TX3MIX Input 3 Volume */
- { 0x0716, 0x0000 }, /* R1814 - AIF1TX3MIX Input 4 Source */
- { 0x0717, 0x0080 }, /* R1815 - AIF1TX3MIX Input 4 Volume */
- { 0x0718, 0x0000 }, /* R1816 - AIF1TX4MIX Input 1 Source */
- { 0x0719, 0x0080 }, /* R1817 - AIF1TX4MIX Input 1 Volume */
- { 0x071A, 0x0000 }, /* R1818 - AIF1TX4MIX Input 2 Source */
- { 0x071B, 0x0080 }, /* R1819 - AIF1TX4MIX Input 2 Volume */
- { 0x071C, 0x0000 }, /* R1820 - AIF1TX4MIX Input 3 Source */
- { 0x071D, 0x0080 }, /* R1821 - AIF1TX4MIX Input 3 Volume */
- { 0x071E, 0x0000 }, /* R1822 - AIF1TX4MIX Input 4 Source */
- { 0x071F, 0x0080 }, /* R1823 - AIF1TX4MIX Input 4 Volume */
- { 0x0720, 0x0000 }, /* R1824 - AIF1TX5MIX Input 1 Source */
- { 0x0721, 0x0080 }, /* R1825 - AIF1TX5MIX Input 1 Volume */
- { 0x0722, 0x0000 }, /* R1826 - AIF1TX5MIX Input 2 Source */
- { 0x0723, 0x0080 }, /* R1827 - AIF1TX5MIX Input 2 Volume */
- { 0x0724, 0x0000 }, /* R1828 - AIF1TX5MIX Input 3 Source */
- { 0x0725, 0x0080 }, /* R1829 - AIF1TX5MIX Input 3 Volume */
- { 0x0726, 0x0000 }, /* R1830 - AIF1TX5MIX Input 4 Source */
- { 0x0727, 0x0080 }, /* R1831 - AIF1TX5MIX Input 4 Volume */
- { 0x0728, 0x0000 }, /* R1832 - AIF1TX6MIX Input 1 Source */
- { 0x0729, 0x0080 }, /* R1833 - AIF1TX6MIX Input 1 Volume */
- { 0x072A, 0x0000 }, /* R1834 - AIF1TX6MIX Input 2 Source */
- { 0x072B, 0x0080 }, /* R1835 - AIF1TX6MIX Input 2 Volume */
- { 0x072C, 0x0000 }, /* R1836 - AIF1TX6MIX Input 3 Source */
- { 0x072D, 0x0080 }, /* R1837 - AIF1TX6MIX Input 3 Volume */
- { 0x072E, 0x0000 }, /* R1838 - AIF1TX6MIX Input 4 Source */
- { 0x072F, 0x0080 }, /* R1839 - AIF1TX6MIX Input 4 Volume */
- { 0x0730, 0x0000 }, /* R1840 - AIF1TX7MIX Input 1 Source */
- { 0x0731, 0x0080 }, /* R1841 - AIF1TX7MIX Input 1 Volume */
- { 0x0732, 0x0000 }, /* R1842 - AIF1TX7MIX Input 2 Source */
- { 0x0733, 0x0080 }, /* R1843 - AIF1TX7MIX Input 2 Volume */
- { 0x0734, 0x0000 }, /* R1844 - AIF1TX7MIX Input 3 Source */
- { 0x0735, 0x0080 }, /* R1845 - AIF1TX7MIX Input 3 Volume */
- { 0x0736, 0x0000 }, /* R1846 - AIF1TX7MIX Input 4 Source */
- { 0x0737, 0x0080 }, /* R1847 - AIF1TX7MIX Input 4 Volume */
- { 0x0738, 0x0000 }, /* R1848 - AIF1TX8MIX Input 1 Source */
- { 0x0739, 0x0080 }, /* R1849 - AIF1TX8MIX Input 1 Volume */
- { 0x073A, 0x0000 }, /* R1850 - AIF1TX8MIX Input 2 Source */
- { 0x073B, 0x0080 }, /* R1851 - AIF1TX8MIX Input 2 Volume */
- { 0x073C, 0x0000 }, /* R1852 - AIF1TX8MIX Input 3 Source */
- { 0x073D, 0x0080 }, /* R1853 - AIF1TX8MIX Input 3 Volume */
- { 0x073E, 0x0000 }, /* R1854 - AIF1TX8MIX Input 4 Source */
- { 0x073F, 0x0080 }, /* R1855 - AIF1TX8MIX Input 4 Volume */
- { 0x0740, 0x0000 }, /* R1856 - AIF2TX1MIX Input 1 Source */
- { 0x0741, 0x0080 }, /* R1857 - AIF2TX1MIX Input 1 Volume */
- { 0x0742, 0x0000 }, /* R1858 - AIF2TX1MIX Input 2 Source */
- { 0x0743, 0x0080 }, /* R1859 - AIF2TX1MIX Input 2 Volume */
- { 0x0744, 0x0000 }, /* R1860 - AIF2TX1MIX Input 3 Source */
- { 0x0745, 0x0080 }, /* R1861 - AIF2TX1MIX Input 3 Volume */
- { 0x0746, 0x0000 }, /* R1862 - AIF2TX1MIX Input 4 Source */
- { 0x0747, 0x0080 }, /* R1863 - AIF2TX1MIX Input 4 Volume */
- { 0x0748, 0x0000 }, /* R1864 - AIF2TX2MIX Input 1 Source */
- { 0x0749, 0x0080 }, /* R1865 - AIF2TX2MIX Input 1 Volume */
- { 0x074A, 0x0000 }, /* R1866 - AIF2TX2MIX Input 2 Source */
- { 0x074B, 0x0080 }, /* R1867 - AIF2TX2MIX Input 2 Volume */
- { 0x074C, 0x0000 }, /* R1868 - AIF2TX2MIX Input 3 Source */
- { 0x074D, 0x0080 }, /* R1869 - AIF2TX2MIX Input 3 Volume */
- { 0x074E, 0x0000 }, /* R1870 - AIF2TX2MIX Input 4 Source */
- { 0x074F, 0x0080 }, /* R1871 - AIF2TX2MIX Input 4 Volume */
- { 0x0780, 0x0000 }, /* R1920 - AIF3TX1MIX Input 1 Source */
- { 0x0781, 0x0080 }, /* R1921 - AIF3TX1MIX Input 1 Volume */
- { 0x0782, 0x0000 }, /* R1922 - AIF3TX1MIX Input 2 Source */
- { 0x0783, 0x0080 }, /* R1923 - AIF3TX1MIX Input 2 Volume */
- { 0x0784, 0x0000 }, /* R1924 - AIF3TX1MIX Input 3 Source */
- { 0x0785, 0x0080 }, /* R1925 - AIF3TX1MIX Input 3 Volume */
- { 0x0786, 0x0000 }, /* R1926 - AIF3TX1MIX Input 4 Source */
- { 0x0787, 0x0080 }, /* R1927 - AIF3TX1MIX Input 4 Volume */
- { 0x0788, 0x0000 }, /* R1928 - AIF3TX2MIX Input 1 Source */
- { 0x0789, 0x0080 }, /* R1929 - AIF3TX2MIX Input 1 Volume */
- { 0x078A, 0x0000 }, /* R1930 - AIF3TX2MIX Input 2 Source */
- { 0x078B, 0x0080 }, /* R1931 - AIF3TX2MIX Input 2 Volume */
- { 0x078C, 0x0000 }, /* R1932 - AIF3TX2MIX Input 3 Source */
- { 0x078D, 0x0080 }, /* R1933 - AIF3TX2MIX Input 3 Volume */
- { 0x078E, 0x0000 }, /* R1934 - AIF3TX2MIX Input 4 Source */
- { 0x078F, 0x0080 }, /* R1935 - AIF3TX2MIX Input 4 Volume */
- { 0x0880, 0x0000 }, /* R2176 - EQ1MIX Input 1 Source */
- { 0x0881, 0x0080 }, /* R2177 - EQ1MIX Input 1 Volume */
- { 0x0882, 0x0000 }, /* R2178 - EQ1MIX Input 2 Source */
- { 0x0883, 0x0080 }, /* R2179 - EQ1MIX Input 2 Volume */
- { 0x0884, 0x0000 }, /* R2180 - EQ1MIX Input 3 Source */
- { 0x0885, 0x0080 }, /* R2181 - EQ1MIX Input 3 Volume */
- { 0x0886, 0x0000 }, /* R2182 - EQ1MIX Input 4 Source */
- { 0x0887, 0x0080 }, /* R2183 - EQ1MIX Input 4 Volume */
- { 0x0888, 0x0000 }, /* R2184 - EQ2MIX Input 1 Source */
- { 0x0889, 0x0080 }, /* R2185 - EQ2MIX Input 1 Volume */
- { 0x088A, 0x0000 }, /* R2186 - EQ2MIX Input 2 Source */
- { 0x088B, 0x0080 }, /* R2187 - EQ2MIX Input 2 Volume */
- { 0x088C, 0x0000 }, /* R2188 - EQ2MIX Input 3 Source */
- { 0x088D, 0x0080 }, /* R2189 - EQ2MIX Input 3 Volume */
- { 0x088E, 0x0000 }, /* R2190 - EQ2MIX Input 4 Source */
- { 0x088F, 0x0080 }, /* R2191 - EQ2MIX Input 4 Volume */
- { 0x0890, 0x0000 }, /* R2192 - EQ3MIX Input 1 Source */
- { 0x0891, 0x0080 }, /* R2193 - EQ3MIX Input 1 Volume */
- { 0x0892, 0x0000 }, /* R2194 - EQ3MIX Input 2 Source */
- { 0x0893, 0x0080 }, /* R2195 - EQ3MIX Input 2 Volume */
- { 0x0894, 0x0000 }, /* R2196 - EQ3MIX Input 3 Source */
- { 0x0895, 0x0080 }, /* R2197 - EQ3MIX Input 3 Volume */
- { 0x0896, 0x0000 }, /* R2198 - EQ3MIX Input 4 Source */
- { 0x0897, 0x0080 }, /* R2199 - EQ3MIX Input 4 Volume */
- { 0x0898, 0x0000 }, /* R2200 - EQ4MIX Input 1 Source */
- { 0x0899, 0x0080 }, /* R2201 - EQ4MIX Input 1 Volume */
- { 0x089A, 0x0000 }, /* R2202 - EQ4MIX Input 2 Source */
- { 0x089B, 0x0080 }, /* R2203 - EQ4MIX Input 2 Volume */
- { 0x089C, 0x0000 }, /* R2204 - EQ4MIX Input 3 Source */
- { 0x089D, 0x0080 }, /* R2205 - EQ4MIX Input 3 Volume */
- { 0x089E, 0x0000 }, /* R2206 - EQ4MIX Input 4 Source */
- { 0x089F, 0x0080 }, /* R2207 - EQ4MIX Input 4 Volume */
- { 0x08C0, 0x0000 }, /* R2240 - DRC1LMIX Input 1 Source */
- { 0x08C1, 0x0080 }, /* R2241 - DRC1LMIX Input 1 Volume */
- { 0x08C2, 0x0000 }, /* R2242 - DRC1LMIX Input 2 Source */
- { 0x08C3, 0x0080 }, /* R2243 - DRC1LMIX Input 2 Volume */
- { 0x08C4, 0x0000 }, /* R2244 - DRC1LMIX Input 3 Source */
- { 0x08C5, 0x0080 }, /* R2245 - DRC1LMIX Input 3 Volume */
- { 0x08C6, 0x0000 }, /* R2246 - DRC1LMIX Input 4 Source */
- { 0x08C7, 0x0080 }, /* R2247 - DRC1LMIX Input 4 Volume */
- { 0x08C8, 0x0000 }, /* R2248 - DRC1RMIX Input 1 Source */
- { 0x08C9, 0x0080 }, /* R2249 - DRC1RMIX Input 1 Volume */
- { 0x08CA, 0x0000 }, /* R2250 - DRC1RMIX Input 2 Source */
- { 0x08CB, 0x0080 }, /* R2251 - DRC1RMIX Input 2 Volume */
- { 0x08CC, 0x0000 }, /* R2252 - DRC1RMIX Input 3 Source */
- { 0x08CD, 0x0080 }, /* R2253 - DRC1RMIX Input 3 Volume */
- { 0x08CE, 0x0000 }, /* R2254 - DRC1RMIX Input 4 Source */
- { 0x08CF, 0x0080 }, /* R2255 - DRC1RMIX Input 4 Volume */
- { 0x0900, 0x0000 }, /* R2304 - HPLP1MIX Input 1 Source */
- { 0x0901, 0x0080 }, /* R2305 - HPLP1MIX Input 1 Volume */
- { 0x0902, 0x0000 }, /* R2306 - HPLP1MIX Input 2 Source */
- { 0x0903, 0x0080 }, /* R2307 - HPLP1MIX Input 2 Volume */
- { 0x0904, 0x0000 }, /* R2308 - HPLP1MIX Input 3 Source */
- { 0x0905, 0x0080 }, /* R2309 - HPLP1MIX Input 3 Volume */
- { 0x0906, 0x0000 }, /* R2310 - HPLP1MIX Input 4 Source */
- { 0x0907, 0x0080 }, /* R2311 - HPLP1MIX Input 4 Volume */
- { 0x0908, 0x0000 }, /* R2312 - HPLP2MIX Input 1 Source */
- { 0x0909, 0x0080 }, /* R2313 - HPLP2MIX Input 1 Volume */
- { 0x090A, 0x0000 }, /* R2314 - HPLP2MIX Input 2 Source */
- { 0x090B, 0x0080 }, /* R2315 - HPLP2MIX Input 2 Volume */
- { 0x090C, 0x0000 }, /* R2316 - HPLP2MIX Input 3 Source */
- { 0x090D, 0x0080 }, /* R2317 - HPLP2MIX Input 3 Volume */
- { 0x090E, 0x0000 }, /* R2318 - HPLP2MIX Input 4 Source */
- { 0x090F, 0x0080 }, /* R2319 - HPLP2MIX Input 4 Volume */
- { 0x0910, 0x0000 }, /* R2320 - HPLP3MIX Input 1 Source */
- { 0x0911, 0x0080 }, /* R2321 - HPLP3MIX Input 1 Volume */
- { 0x0912, 0x0000 }, /* R2322 - HPLP3MIX Input 2 Source */
- { 0x0913, 0x0080 }, /* R2323 - HPLP3MIX Input 2 Volume */
- { 0x0914, 0x0000 }, /* R2324 - HPLP3MIX Input 3 Source */
- { 0x0915, 0x0080 }, /* R2325 - HPLP3MIX Input 3 Volume */
- { 0x0916, 0x0000 }, /* R2326 - HPLP3MIX Input 4 Source */
- { 0x0917, 0x0080 }, /* R2327 - HPLP3MIX Input 4 Volume */
- { 0x0918, 0x0000 }, /* R2328 - HPLP4MIX Input 1 Source */
- { 0x0919, 0x0080 }, /* R2329 - HPLP4MIX Input 1 Volume */
- { 0x091A, 0x0000 }, /* R2330 - HPLP4MIX Input 2 Source */
- { 0x091B, 0x0080 }, /* R2331 - HPLP4MIX Input 2 Volume */
- { 0x091C, 0x0000 }, /* R2332 - HPLP4MIX Input 3 Source */
- { 0x091D, 0x0080 }, /* R2333 - HPLP4MIX Input 3 Volume */
- { 0x091E, 0x0000 }, /* R2334 - HPLP4MIX Input 4 Source */
- { 0x091F, 0x0080 }, /* R2335 - HPLP4MIX Input 4 Volume */
- { 0x0940, 0x0000 }, /* R2368 - DSP1LMIX Input 1 Source */
- { 0x0941, 0x0080 }, /* R2369 - DSP1LMIX Input 1 Volume */
- { 0x0942, 0x0000 }, /* R2370 - DSP1LMIX Input 2 Source */
- { 0x0943, 0x0080 }, /* R2371 - DSP1LMIX Input 2 Volume */
- { 0x0944, 0x0000 }, /* R2372 - DSP1LMIX Input 3 Source */
- { 0x0945, 0x0080 }, /* R2373 - DSP1LMIX Input 3 Volume */
- { 0x0946, 0x0000 }, /* R2374 - DSP1LMIX Input 4 Source */
- { 0x0947, 0x0080 }, /* R2375 - DSP1LMIX Input 4 Volume */
- { 0x0948, 0x0000 }, /* R2376 - DSP1RMIX Input 1 Source */
- { 0x0949, 0x0080 }, /* R2377 - DSP1RMIX Input 1 Volume */
- { 0x094A, 0x0000 }, /* R2378 - DSP1RMIX Input 2 Source */
- { 0x094B, 0x0080 }, /* R2379 - DSP1RMIX Input 2 Volume */
- { 0x094C, 0x0000 }, /* R2380 - DSP1RMIX Input 3 Source */
- { 0x094D, 0x0080 }, /* R2381 - DSP1RMIX Input 3 Volume */
- { 0x094E, 0x0000 }, /* R2382 - DSP1RMIX Input 4 Source */
- { 0x094F, 0x0080 }, /* R2383 - DSP1RMIX Input 4 Volume */
- { 0x0950, 0x0000 }, /* R2384 - DSP1AUX1MIX Input 1 Source */
- { 0x0958, 0x0000 }, /* R2392 - DSP1AUX2MIX Input 1 Source */
- { 0x0960, 0x0000 }, /* R2400 - DSP1AUX3MIX Input 1 Source */
- { 0x0968, 0x0000 }, /* R2408 - DSP1AUX4MIX Input 1 Source */
- { 0x0970, 0x0000 }, /* R2416 - DSP1AUX5MIX Input 1 Source */
- { 0x0978, 0x0000 }, /* R2424 - DSP1AUX6MIX Input 1 Source */
- { 0x0980, 0x0000 }, /* R2432 - DSP2LMIX Input 1 Source */
- { 0x0981, 0x0080 }, /* R2433 - DSP2LMIX Input 1 Volume */
- { 0x0982, 0x0000 }, /* R2434 - DSP2LMIX Input 2 Source */
- { 0x0983, 0x0080 }, /* R2435 - DSP2LMIX Input 2 Volume */
- { 0x0984, 0x0000 }, /* R2436 - DSP2LMIX Input 3 Source */
- { 0x0985, 0x0080 }, /* R2437 - DSP2LMIX Input 3 Volume */
- { 0x0986, 0x0000 }, /* R2438 - DSP2LMIX Input 4 Source */
- { 0x0987, 0x0080 }, /* R2439 - DSP2LMIX Input 4 Volume */
- { 0x0988, 0x0000 }, /* R2440 - DSP2RMIX Input 1 Source */
- { 0x0989, 0x0080 }, /* R2441 - DSP2RMIX Input 1 Volume */
- { 0x098A, 0x0000 }, /* R2442 - DSP2RMIX Input 2 Source */
- { 0x098B, 0x0080 }, /* R2443 - DSP2RMIX Input 2 Volume */
- { 0x098C, 0x0000 }, /* R2444 - DSP2RMIX Input 3 Source */
- { 0x098D, 0x0080 }, /* R2445 - DSP2RMIX Input 3 Volume */
- { 0x098E, 0x0000 }, /* R2446 - DSP2RMIX Input 4 Source */
- { 0x098F, 0x0080 }, /* R2447 - DSP2RMIX Input 4 Volume */
- { 0x0990, 0x0000 }, /* R2448 - DSP2AUX1MIX Input 1 Source */
- { 0x0998, 0x0000 }, /* R2456 - DSP2AUX2MIX Input 1 Source */
- { 0x09A0, 0x0000 }, /* R2464 - DSP2AUX3MIX Input 1 Source */
- { 0x09A8, 0x0000 }, /* R2472 - DSP2AUX4MIX Input 1 Source */
- { 0x09B0, 0x0000 }, /* R2480 - DSP2AUX5MIX Input 1 Source */
- { 0x09B8, 0x0000 }, /* R2488 - DSP2AUX6MIX Input 1 Source */
- { 0x09C0, 0x0000 }, /* R2496 - DSP3LMIX Input 1 Source */
- { 0x09C1, 0x0080 }, /* R2497 - DSP3LMIX Input 1 Volume */
- { 0x09C2, 0x0000 }, /* R2498 - DSP3LMIX Input 2 Source */
- { 0x09C3, 0x0080 }, /* R2499 - DSP3LMIX Input 2 Volume */
- { 0x09C4, 0x0000 }, /* R2500 - DSP3LMIX Input 3 Source */
- { 0x09C5, 0x0080 }, /* R2501 - DSP3LMIX Input 3 Volume */
- { 0x09C6, 0x0000 }, /* R2502 - DSP3LMIX Input 4 Source */
- { 0x09C7, 0x0080 }, /* R2503 - DSP3LMIX Input 4 Volume */
- { 0x09C8, 0x0000 }, /* R2504 - DSP3RMIX Input 1 Source */
- { 0x09C9, 0x0080 }, /* R2505 - DSP3RMIX Input 1 Volume */
- { 0x09CA, 0x0000 }, /* R2506 - DSP3RMIX Input 2 Source */
- { 0x09CB, 0x0080 }, /* R2507 - DSP3RMIX Input 2 Volume */
- { 0x09CC, 0x0000 }, /* R2508 - DSP3RMIX Input 3 Source */
- { 0x09CD, 0x0080 }, /* R2509 - DSP3RMIX Input 3 Volume */
- { 0x09CE, 0x0000 }, /* R2510 - DSP3RMIX Input 4 Source */
- { 0x09CF, 0x0080 }, /* R2511 - DSP3RMIX Input 4 Volume */
- { 0x09D0, 0x0000 }, /* R2512 - DSP3AUX1MIX Input 1 Source */
- { 0x09D8, 0x0000 }, /* R2520 - DSP3AUX2MIX Input 1 Source */
- { 0x09E0, 0x0000 }, /* R2528 - DSP3AUX3MIX Input 1 Source */
- { 0x09E8, 0x0000 }, /* R2536 - DSP3AUX4MIX Input 1 Source */
- { 0x09F0, 0x0000 }, /* R2544 - DSP3AUX5MIX Input 1 Source */
- { 0x09F8, 0x0000 }, /* R2552 - DSP3AUX6MIX Input 1 Source */
- { 0x0A80, 0x0000 }, /* R2688 - ASRC1LMIX Input 1 Source */
- { 0x0A88, 0x0000 }, /* R2696 - ASRC1RMIX Input 1 Source */
- { 0x0A90, 0x0000 }, /* R2704 - ASRC2LMIX Input 1 Source */
- { 0x0A98, 0x0000 }, /* R2712 - ASRC2RMIX Input 1 Source */
- { 0x0B00, 0x0000 }, /* R2816 - ISRC1DEC1MIX Input 1 Source */
- { 0x0B08, 0x0000 }, /* R2824 - ISRC1DEC2MIX Input 1 Source */
- { 0x0B10, 0x0000 }, /* R2832 - ISRC1DEC3MIX Input 1 Source */
- { 0x0B18, 0x0000 }, /* R2840 - ISRC1DEC4MIX Input 1 Source */
- { 0x0B20, 0x0000 }, /* R2848 - ISRC1INT1MIX Input 1 Source */
- { 0x0B28, 0x0000 }, /* R2856 - ISRC1INT2MIX Input 1 Source */
- { 0x0B30, 0x0000 }, /* R2864 - ISRC1INT3MIX Input 1 Source */
- { 0x0B38, 0x0000 }, /* R2872 - ISRC1INT4MIX Input 1 Source */
- { 0x0B40, 0x0000 }, /* R2880 - ISRC2DEC1MIX Input 1 Source */
- { 0x0B48, 0x0000 }, /* R2888 - ISRC2DEC2MIX Input 1 Source */
- { 0x0B50, 0x0000 }, /* R2896 - ISRC2DEC3MIX Input 1 Source */
- { 0x0B58, 0x0000 }, /* R2904 - ISRC2DEC4MIX Input 1 Source */
- { 0x0B60, 0x0000 }, /* R2912 - ISRC2INT1MIX Input 1 Source */
- { 0x0B68, 0x0000 }, /* R2920 - ISRC2INT2MIX Input 1 Source */
- { 0x0B70, 0x0000 }, /* R2928 - ISRC2INT3MIX Input 1 Source */
- { 0x0B78, 0x0000 }, /* R2936 - ISRC2INT4MIX Input 1 Source */
- { 0x0C00, 0xA001 }, /* R3072 - GPIO CTRL 1 */
- { 0x0C01, 0xA001 }, /* R3073 - GPIO CTRL 2 */
- { 0x0C02, 0xA001 }, /* R3074 - GPIO CTRL 3 */
- { 0x0C03, 0xA001 }, /* R3075 - GPIO CTRL 4 */
- { 0x0C04, 0xA001 }, /* R3076 - GPIO CTRL 5 */
- { 0x0C05, 0xA001 }, /* R3077 - GPIO CTRL 6 */
- { 0x0C23, 0x4003 }, /* R3107 - Misc Pad Ctrl 1 */
- { 0x0C24, 0x0000 }, /* R3108 - Misc Pad Ctrl 2 */
- { 0x0C25, 0x0000 }, /* R3109 - Misc Pad Ctrl 3 */
- { 0x0C26, 0x0000 }, /* R3110 - Misc Pad Ctrl 4 */
- { 0x0C27, 0x0000 }, /* R3111 - Misc Pad Ctrl 5 */
- { 0x0C28, 0x0000 }, /* R3112 - Misc GPIO 1 */
- { 0x0D00, 0x0000 }, /* R3328 - Interrupt Status 1 */
- { 0x0D01, 0x0000 }, /* R3329 - Interrupt Status 2 */
- { 0x0D02, 0x0000 }, /* R3330 - Interrupt Status 3 */
- { 0x0D03, 0x0000 }, /* R3331 - Interrupt Status 4 */
- { 0x0D04, 0x0000 }, /* R3332 - Interrupt Raw Status 2 */
- { 0x0D05, 0x0000 }, /* R3333 - Interrupt Raw Status 3 */
- { 0x0D06, 0x0000 }, /* R3334 - Interrupt Raw Status 4 */
- { 0x0D07, 0xFFFF }, /* R3335 - Interrupt Status 1 Mask */
- { 0x0D08, 0xFFFF }, /* R3336 - Interrupt Status 2 Mask */
- { 0x0D09, 0xFFFF }, /* R3337 - Interrupt Status 3 Mask */
- { 0x0D0A, 0xFFFF }, /* R3338 - Interrupt Status 4 Mask */
- { 0x0D1F, 0x0000 }, /* R3359 - Interrupt Control */
- { 0x0D20, 0xFFFF }, /* R3360 - IRQ Debounce 1 */
- { 0x0D21, 0xFFFF }, /* R3361 - IRQ Debounce 2 */
- { 0x0E00, 0x0000 }, /* R3584 - FX_Ctrl */
- { 0x0E10, 0x6318 }, /* R3600 - EQ1_1 */
- { 0x0E11, 0x6300 }, /* R3601 - EQ1_2 */
- { 0x0E12, 0x0FC8 }, /* R3602 - EQ1_3 */
- { 0x0E13, 0x03FE }, /* R3603 - EQ1_4 */
- { 0x0E14, 0x00E0 }, /* R3604 - EQ1_5 */
- { 0x0E15, 0x1EC4 }, /* R3605 - EQ1_6 */
- { 0x0E16, 0xF136 }, /* R3606 - EQ1_7 */
- { 0x0E17, 0x0409 }, /* R3607 - EQ1_8 */
- { 0x0E18, 0x04CC }, /* R3608 - EQ1_9 */
- { 0x0E19, 0x1C9B }, /* R3609 - EQ1_10 */
- { 0x0E1A, 0xF337 }, /* R3610 - EQ1_11 */
- { 0x0E1B, 0x040B }, /* R3611 - EQ1_12 */
- { 0x0E1C, 0x0CBB }, /* R3612 - EQ1_13 */
- { 0x0E1D, 0x16F8 }, /* R3613 - EQ1_14 */
- { 0x0E1E, 0xF7D9 }, /* R3614 - EQ1_15 */
- { 0x0E1F, 0x040A }, /* R3615 - EQ1_16 */
- { 0x0E20, 0x1F14 }, /* R3616 - EQ1_17 */
- { 0x0E21, 0x058C }, /* R3617 - EQ1_18 */
- { 0x0E22, 0x0563 }, /* R3618 - EQ1_19 */
- { 0x0E23, 0x4000 }, /* R3619 - EQ1_20 */
- { 0x0E26, 0x6318 }, /* R3622 - EQ2_1 */
- { 0x0E27, 0x6300 }, /* R3623 - EQ2_2 */
- { 0x0E28, 0x0FC8 }, /* R3624 - EQ2_3 */
- { 0x0E29, 0x03FE }, /* R3625 - EQ2_4 */
- { 0x0E2A, 0x00E0 }, /* R3626 - EQ2_5 */
- { 0x0E2B, 0x1EC4 }, /* R3627 - EQ2_6 */
- { 0x0E2C, 0xF136 }, /* R3628 - EQ2_7 */
- { 0x0E2D, 0x0409 }, /* R3629 - EQ2_8 */
- { 0x0E2E, 0x04CC }, /* R3630 - EQ2_9 */
- { 0x0E2F, 0x1C9B }, /* R3631 - EQ2_10 */
- { 0x0E30, 0xF337 }, /* R3632 - EQ2_11 */
- { 0x0E31, 0x040B }, /* R3633 - EQ2_12 */
- { 0x0E32, 0x0CBB }, /* R3634 - EQ2_13 */
- { 0x0E33, 0x16F8 }, /* R3635 - EQ2_14 */
- { 0x0E34, 0xF7D9 }, /* R3636 - EQ2_15 */
- { 0x0E35, 0x040A }, /* R3637 - EQ2_16 */
- { 0x0E36, 0x1F14 }, /* R3638 - EQ2_17 */
- { 0x0E37, 0x058C }, /* R3639 - EQ2_18 */
- { 0x0E38, 0x0563 }, /* R3640 - EQ2_19 */
- { 0x0E39, 0x4000 }, /* R3641 - EQ2_20 */
- { 0x0E3C, 0x6318 }, /* R3644 - EQ3_1 */
- { 0x0E3D, 0x6300 }, /* R3645 - EQ3_2 */
- { 0x0E3E, 0x0FC8 }, /* R3646 - EQ3_3 */
- { 0x0E3F, 0x03FE }, /* R3647 - EQ3_4 */
- { 0x0E40, 0x00E0 }, /* R3648 - EQ3_5 */
- { 0x0E41, 0x1EC4 }, /* R3649 - EQ3_6 */
- { 0x0E42, 0xF136 }, /* R3650 - EQ3_7 */
- { 0x0E43, 0x0409 }, /* R3651 - EQ3_8 */
- { 0x0E44, 0x04CC }, /* R3652 - EQ3_9 */
- { 0x0E45, 0x1C9B }, /* R3653 - EQ3_10 */
- { 0x0E46, 0xF337 }, /* R3654 - EQ3_11 */
- { 0x0E47, 0x040B }, /* R3655 - EQ3_12 */
- { 0x0E48, 0x0CBB }, /* R3656 - EQ3_13 */
- { 0x0E49, 0x16F8 }, /* R3657 - EQ3_14 */
- { 0x0E4A, 0xF7D9 }, /* R3658 - EQ3_15 */
- { 0x0E4B, 0x040A }, /* R3659 - EQ3_16 */
- { 0x0E4C, 0x1F14 }, /* R3660 - EQ3_17 */
- { 0x0E4D, 0x058C }, /* R3661 - EQ3_18 */
- { 0x0E4E, 0x0563 }, /* R3662 - EQ3_19 */
- { 0x0E4F, 0x4000 }, /* R3663 - EQ3_20 */
- { 0x0E52, 0x6318 }, /* R3666 - EQ4_1 */
- { 0x0E53, 0x6300 }, /* R3667 - EQ4_2 */
- { 0x0E54, 0x0FC8 }, /* R3668 - EQ4_3 */
- { 0x0E55, 0x03FE }, /* R3669 - EQ4_4 */
- { 0x0E56, 0x00E0 }, /* R3670 - EQ4_5 */
- { 0x0E57, 0x1EC4 }, /* R3671 - EQ4_6 */
- { 0x0E58, 0xF136 }, /* R3672 - EQ4_7 */
- { 0x0E59, 0x0409 }, /* R3673 - EQ4_8 */
- { 0x0E5A, 0x04CC }, /* R3674 - EQ4_9 */
- { 0x0E5B, 0x1C9B }, /* R3675 - EQ4_10 */
- { 0x0E5C, 0xF337 }, /* R3676 - EQ4_11 */
- { 0x0E5D, 0x040B }, /* R3677 - EQ4_12 */
- { 0x0E5E, 0x0CBB }, /* R3678 - EQ4_13 */
- { 0x0E5F, 0x16F8 }, /* R3679 - EQ4_14 */
- { 0x0E60, 0xF7D9 }, /* R3680 - EQ4_15 */
- { 0x0E61, 0x040A }, /* R3681 - EQ4_16 */
- { 0x0E62, 0x1F14 }, /* R3682 - EQ4_17 */
- { 0x0E63, 0x058C }, /* R3683 - EQ4_18 */
- { 0x0E64, 0x0563 }, /* R3684 - EQ4_19 */
- { 0x0E65, 0x4000 }, /* R3685 - EQ4_20 */
- { 0x0E80, 0x0018 }, /* R3712 - DRC1 ctrl1 */
- { 0x0E81, 0x0933 }, /* R3713 - DRC1 ctrl2 */
- { 0x0E82, 0x0018 }, /* R3714 - DRC1 ctrl3 */
- { 0x0E83, 0x0000 }, /* R3715 - DRC1 ctrl4 */
- { 0x0E84, 0x0000 }, /* R3716 - DRC1 ctrl5 */
- { 0x0EC0, 0x0000 }, /* R3776 - HPLPF1_1 */
- { 0x0EC1, 0x0000 }, /* R3777 - HPLPF1_2 */
- { 0x0EC4, 0x0000 }, /* R3780 - HPLPF2_1 */
- { 0x0EC5, 0x0000 }, /* R3781 - HPLPF2_2 */
- { 0x0EC8, 0x0000 }, /* R3784 - HPLPF3_1 */
- { 0x0EC9, 0x0000 }, /* R3785 - HPLPF3_2 */
- { 0x0ECC, 0x0000 }, /* R3788 - HPLPF4_1 */
- { 0x0ECD, 0x0000 }, /* R3789 - HPLPF4_2 */
-};
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm5100.c b/ANDROID_3.4.5/sound/soc/codecs/wm5100.c
deleted file mode 100644
index b9c185ce..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm5100.c
+++ /dev/null
@@ -1,2766 +0,0 @@
-/*
- * wm5100.c -- WM5100 ALSA SoC Audio driver
- *
- * Copyright 2011 Wolfson Microelectronics plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/gcd.h>
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-#include <linux/pm_runtime.h>
-#include <linux/regulator/consumer.h>
-#include <linux/regulator/fixed.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/jack.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <sound/wm5100.h>
-
-#include "wm5100.h"
-
-#define WM5100_NUM_CORE_SUPPLIES 2
-static const char *wm5100_core_supply_names[WM5100_NUM_CORE_SUPPLIES] = {
- "DBVDD1",
- "LDOVDD", /* If DCVDD is supplied externally specify as LDOVDD */
-};
-
-#define WM5100_AIFS 3
-#define WM5100_SYNC_SRS 3
-
-struct wm5100_fll {
- int fref;
- int fout;
- int src;
- struct completion lock;
-};
-
-/* codec private data */
-struct wm5100_priv {
- struct device *dev;
- struct regmap *regmap;
- struct snd_soc_codec *codec;
-
- struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES];
-
- int rev;
-
- int sysclk;
- int asyncclk;
-
- bool aif_async[WM5100_AIFS];
- bool aif_symmetric[WM5100_AIFS];
- int sr_ref[WM5100_SYNC_SRS];
-
- bool out_ena[2];
-
- struct snd_soc_jack *jack;
- bool jack_detecting;
- bool jack_mic;
- int jack_mode;
- int jack_flips;
-
- struct wm5100_fll fll[2];
-
- struct wm5100_pdata pdata;
-
-#ifdef CONFIG_GPIOLIB
- struct gpio_chip gpio_chip;
-#endif
-};
-
-static int wm5100_sr_code[] = {
- 0,
- 12000,
- 24000,
- 48000,
- 96000,
- 192000,
- 384000,
- 768000,
- 0,
- 11025,
- 22050,
- 44100,
- 88200,
- 176400,
- 352800,
- 705600,
- 4000,
- 8000,
- 16000,
- 32000,
- 64000,
- 128000,
- 256000,
- 512000,
-};
-
-static int wm5100_sr_regs[WM5100_SYNC_SRS] = {
- WM5100_CLOCKING_4,
- WM5100_CLOCKING_5,
- WM5100_CLOCKING_6,
-};
-
-static int wm5100_alloc_sr(struct snd_soc_codec *codec, int rate)
-{
- struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
- int sr_code, sr_free, i;
-
- for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
- if (wm5100_sr_code[i] == rate)
- break;
- if (i == ARRAY_SIZE(wm5100_sr_code)) {
- dev_err(codec->dev, "Unsupported sample rate: %dHz\n", rate);
- return -EINVAL;
- }
- sr_code = i;
-
- if ((wm5100->sysclk % rate) == 0) {
- /* Is this rate already in use? */
- sr_free = -1;
- for (i = 0; i < ARRAY_SIZE(wm5100_sr_regs); i++) {
- if (!wm5100->sr_ref[i] && sr_free == -1) {
- sr_free = i;
- continue;
- }
- if ((snd_soc_read(codec, wm5100_sr_regs[i]) &
- WM5100_SAMPLE_RATE_1_MASK) == sr_code)
- break;
- }
-
- if (i < ARRAY_SIZE(wm5100_sr_regs)) {
- wm5100->sr_ref[i]++;
- dev_dbg(codec->dev, "SR %dHz, slot %d, ref %d\n",
- rate, i, wm5100->sr_ref[i]);
- return i;
- }
-
- if (sr_free == -1) {
- dev_err(codec->dev, "All SR slots already in use\n");
- return -EBUSY;
- }
-
- dev_dbg(codec->dev, "Allocating SR slot %d for %dHz\n",
- sr_free, rate);
- wm5100->sr_ref[sr_free]++;
- snd_soc_update_bits(codec, wm5100_sr_regs[sr_free],
- WM5100_SAMPLE_RATE_1_MASK,
- sr_code);
-
- return sr_free;
-
- } else {
- dev_err(codec->dev,
- "SR %dHz incompatible with %dHz SYSCLK and %dHz ASYNCCLK\n",
- rate, wm5100->sysclk, wm5100->asyncclk);
- return -EINVAL;
- }
-}
-
-static void wm5100_free_sr(struct snd_soc_codec *codec, int rate)
-{
- struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
- int i, sr_code;
-
- for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
- if (wm5100_sr_code[i] == rate)
- break;
- if (i == ARRAY_SIZE(wm5100_sr_code)) {
- dev_err(codec->dev, "Unsupported sample rate: %dHz\n", rate);
- return;
- }
- sr_code = wm5100_sr_code[i];
-
- for (i = 0; i < ARRAY_SIZE(wm5100_sr_regs); i++) {
- if (!wm5100->sr_ref[i])
- continue;
-
- if ((snd_soc_read(codec, wm5100_sr_regs[i]) &
- WM5100_SAMPLE_RATE_1_MASK) == sr_code)
- break;
- }
- if (i < ARRAY_SIZE(wm5100_sr_regs)) {
- wm5100->sr_ref[i]--;
- dev_dbg(codec->dev, "Dereference SR %dHz, count now %d\n",
- rate, wm5100->sr_ref[i]);
- } else {
- dev_warn(codec->dev, "Freeing unreferenced sample rate %dHz\n",
- rate);
- }
-}
-
-static int wm5100_reset(struct wm5100_priv *wm5100)
-{
- if (wm5100->pdata.reset) {
- gpio_set_value_cansleep(wm5100->pdata.reset, 0);
- gpio_set_value_cansleep(wm5100->pdata.reset, 1);
-
- return 0;
- } else {
- return regmap_write(wm5100->regmap, WM5100_SOFTWARE_RESET, 0);
- }
-}
-
-static DECLARE_TLV_DB_SCALE(in_tlv, -6300, 100, 0);
-static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
-static DECLARE_TLV_DB_SCALE(mixer_tlv, -3200, 100, 0);
-static DECLARE_TLV_DB_SCALE(out_tlv, -6400, 100, 0);
-static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
-
-static const char *wm5100_mixer_texts[] = {
- "None",
- "Tone Generator 1",
- "Tone Generator 2",
- "AEC loopback",
- "IN1L",
- "IN1R",
- "IN2L",
- "IN2R",
- "IN3L",
- "IN3R",
- "IN4L",
- "IN4R",
- "AIF1RX1",
- "AIF1RX2",
- "AIF1RX3",
- "AIF1RX4",
- "AIF1RX5",
- "AIF1RX6",
- "AIF1RX7",
- "AIF1RX8",
- "AIF2RX1",
- "AIF2RX2",
- "AIF3RX1",
- "AIF3RX2",
- "EQ1",
- "EQ2",
- "EQ3",
- "EQ4",
- "DRC1L",
- "DRC1R",
- "LHPF1",
- "LHPF2",
- "LHPF3",
- "LHPF4",
- "DSP1.1",
- "DSP1.2",
- "DSP1.3",
- "DSP1.4",
- "DSP1.5",
- "DSP1.6",
- "DSP2.1",
- "DSP2.2",
- "DSP2.3",
- "DSP2.4",
- "DSP2.5",
- "DSP2.6",
- "DSP3.1",
- "DSP3.2",
- "DSP3.3",
- "DSP3.4",
- "DSP3.5",
- "DSP3.6",
- "ASRC1L",
- "ASRC1R",
- "ASRC2L",
- "ASRC2R",
- "ISRC1INT1",
- "ISRC1INT2",
- "ISRC1INT3",
- "ISRC1INT4",
- "ISRC2INT1",
- "ISRC2INT2",
- "ISRC2INT3",
- "ISRC2INT4",
- "ISRC1DEC1",
- "ISRC1DEC2",
- "ISRC1DEC3",
- "ISRC1DEC4",
- "ISRC2DEC1",
- "ISRC2DEC2",
- "ISRC2DEC3",
- "ISRC2DEC4",
-};
-
-static int wm5100_mixer_values[] = {
- 0x00,
- 0x04, /* Tone */
- 0x05,
- 0x08, /* AEC */
- 0x10, /* Input */
- 0x11,
- 0x12,
- 0x13,
- 0x14,
- 0x15,
- 0x16,
- 0x17,
- 0x20, /* AIF */
- 0x21,
- 0x22,
- 0x23,
- 0x24,
- 0x25,
- 0x26,
- 0x27,
- 0x28,
- 0x29,
- 0x30, /* AIF3 - check */
- 0x31,
- 0x50, /* EQ */
- 0x51,
- 0x52,
- 0x53,
- 0x54,
- 0x58, /* DRC */
- 0x59,
- 0x60, /* LHPF1 */
- 0x61, /* LHPF2 */
- 0x62, /* LHPF3 */
- 0x63, /* LHPF4 */
- 0x68, /* DSP1 */
- 0x69,
- 0x6a,
- 0x6b,
- 0x6c,
- 0x6d,
- 0x70, /* DSP2 */
- 0x71,
- 0x72,
- 0x73,
- 0x74,
- 0x75,
- 0x78, /* DSP3 */
- 0x79,
- 0x7a,
- 0x7b,
- 0x7c,
- 0x7d,
- 0x90, /* ASRC1 */
- 0x91,
- 0x92, /* ASRC2 */
- 0x93,
- 0xa0, /* ISRC1DEC1 */
- 0xa1,
- 0xa2,
- 0xa3,
- 0xa4, /* ISRC1INT1 */
- 0xa5,
- 0xa6,
- 0xa7,
- 0xa8, /* ISRC2DEC1 */
- 0xa9,
- 0xaa,
- 0xab,
- 0xac, /* ISRC2INT1 */
- 0xad,
- 0xae,
- 0xaf,
-};
-
-#define WM5100_MIXER_CONTROLS(name, base) \
- SOC_SINGLE_TLV(name " Input 1 Volume", base + 1 , \
- WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
- SOC_SINGLE_TLV(name " Input 2 Volume", base + 3 , \
- WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
- SOC_SINGLE_TLV(name " Input 3 Volume", base + 5 , \
- WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
- SOC_SINGLE_TLV(name " Input 4 Volume", base + 7 , \
- WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv)
-
-#define WM5100_MUX_ENUM_DECL(name, reg) \
- SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, \
- wm5100_mixer_texts, wm5100_mixer_values)
-
-#define WM5100_MUX_CTL_DECL(name) \
- const struct snd_kcontrol_new name##_mux = \
- SOC_DAPM_VALUE_ENUM("Route", name##_enum)
-
-#define WM5100_MIXER_ENUMS(name, base_reg) \
- static WM5100_MUX_ENUM_DECL(name##_in1_enum, base_reg); \
- static WM5100_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \
- static WM5100_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \
- static WM5100_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \
- static WM5100_MUX_CTL_DECL(name##_in1); \
- static WM5100_MUX_CTL_DECL(name##_in2); \
- static WM5100_MUX_CTL_DECL(name##_in3); \
- static WM5100_MUX_CTL_DECL(name##_in4)
-
-WM5100_MIXER_ENUMS(HPOUT1L, WM5100_OUT1LMIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(HPOUT1R, WM5100_OUT1RMIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(HPOUT2L, WM5100_OUT2LMIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(HPOUT2R, WM5100_OUT2RMIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(HPOUT3L, WM5100_OUT3LMIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(HPOUT3R, WM5100_OUT3RMIX_INPUT_1_SOURCE);
-
-WM5100_MIXER_ENUMS(SPKOUTL, WM5100_OUT4LMIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(SPKOUTR, WM5100_OUT4RMIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(SPKDAT1L, WM5100_OUT5LMIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(SPKDAT1R, WM5100_OUT5RMIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(SPKDAT2L, WM5100_OUT6LMIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(SPKDAT2R, WM5100_OUT6RMIX_INPUT_1_SOURCE);
-
-WM5100_MIXER_ENUMS(PWM1, WM5100_PWM1MIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(PWM2, WM5100_PWM1MIX_INPUT_1_SOURCE);
-
-WM5100_MIXER_ENUMS(AIF1TX1, WM5100_AIF1TX1MIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(AIF1TX2, WM5100_AIF1TX2MIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(AIF1TX3, WM5100_AIF1TX3MIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(AIF1TX4, WM5100_AIF1TX4MIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(AIF1TX5, WM5100_AIF1TX5MIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(AIF1TX6, WM5100_AIF1TX6MIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(AIF1TX7, WM5100_AIF1TX7MIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(AIF1TX8, WM5100_AIF1TX8MIX_INPUT_1_SOURCE);
-
-WM5100_MIXER_ENUMS(AIF2TX1, WM5100_AIF2TX1MIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(AIF2TX2, WM5100_AIF2TX2MIX_INPUT_1_SOURCE);
-
-WM5100_MIXER_ENUMS(AIF3TX1, WM5100_AIF1TX1MIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(AIF3TX2, WM5100_AIF1TX2MIX_INPUT_1_SOURCE);
-
-WM5100_MIXER_ENUMS(EQ1, WM5100_EQ1MIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(EQ2, WM5100_EQ2MIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(EQ3, WM5100_EQ3MIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(EQ4, WM5100_EQ4MIX_INPUT_1_SOURCE);
-
-WM5100_MIXER_ENUMS(DRC1L, WM5100_DRC1LMIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(DRC1R, WM5100_DRC1RMIX_INPUT_1_SOURCE);
-
-WM5100_MIXER_ENUMS(LHPF1, WM5100_HPLP1MIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(LHPF2, WM5100_HPLP2MIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(LHPF3, WM5100_HPLP3MIX_INPUT_1_SOURCE);
-WM5100_MIXER_ENUMS(LHPF4, WM5100_HPLP4MIX_INPUT_1_SOURCE);
-
-#define WM5100_MUX(name, ctrl) \
- SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
-
-#define WM5100_MIXER_WIDGETS(name, name_str) \
- WM5100_MUX(name_str " Input 1", &name##_in1_mux), \
- WM5100_MUX(name_str " Input 2", &name##_in2_mux), \
- WM5100_MUX(name_str " Input 3", &name##_in3_mux), \
- WM5100_MUX(name_str " Input 4", &name##_in4_mux), \
- SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
-
-#define WM5100_MIXER_INPUT_ROUTES(name) \
- { name, "Tone Generator 1", "Tone Generator 1" }, \
- { name, "Tone Generator 2", "Tone Generator 2" }, \
- { name, "IN1L", "IN1L PGA" }, \
- { name, "IN1R", "IN1R PGA" }, \
- { name, "IN2L", "IN2L PGA" }, \
- { name, "IN2R", "IN2R PGA" }, \
- { name, "IN3L", "IN3L PGA" }, \
- { name, "IN3R", "IN3R PGA" }, \
- { name, "IN4L", "IN4L PGA" }, \
- { name, "IN4R", "IN4R PGA" }, \
- { name, "AIF1RX1", "AIF1RX1" }, \
- { name, "AIF1RX2", "AIF1RX2" }, \
- { name, "AIF1RX3", "AIF1RX3" }, \
- { name, "AIF1RX4", "AIF1RX4" }, \
- { name, "AIF1RX5", "AIF1RX5" }, \
- { name, "AIF1RX6", "AIF1RX6" }, \
- { name, "AIF1RX7", "AIF1RX7" }, \
- { name, "AIF1RX8", "AIF1RX8" }, \
- { name, "AIF2RX1", "AIF2RX1" }, \
- { name, "AIF2RX2", "AIF2RX2" }, \
- { name, "AIF3RX1", "AIF3RX1" }, \
- { name, "AIF3RX2", "AIF3RX2" }, \
- { name, "EQ1", "EQ1" }, \
- { name, "EQ2", "EQ2" }, \
- { name, "EQ3", "EQ3" }, \
- { name, "EQ4", "EQ4" }, \
- { name, "DRC1L", "DRC1L" }, \
- { name, "DRC1R", "DRC1R" }, \
- { name, "LHPF1", "LHPF1" }, \
- { name, "LHPF2", "LHPF2" }, \
- { name, "LHPF3", "LHPF3" }, \
- { name, "LHPF4", "LHPF4" }
-
-#define WM5100_MIXER_ROUTES(widget, name) \
- { widget, NULL, name " Mixer" }, \
- { name " Mixer", NULL, name " Input 1" }, \
- { name " Mixer", NULL, name " Input 2" }, \
- { name " Mixer", NULL, name " Input 3" }, \
- { name " Mixer", NULL, name " Input 4" }, \
- WM5100_MIXER_INPUT_ROUTES(name " Input 1"), \
- WM5100_MIXER_INPUT_ROUTES(name " Input 2"), \
- WM5100_MIXER_INPUT_ROUTES(name " Input 3"), \
- WM5100_MIXER_INPUT_ROUTES(name " Input 4")
-
-static const char *wm5100_lhpf_mode_text[] = {
- "Low-pass", "High-pass"
-};
-
-static const struct soc_enum wm5100_lhpf1_mode =
- SOC_ENUM_SINGLE(WM5100_HPLPF1_1, WM5100_LHPF1_MODE_SHIFT, 2,
- wm5100_lhpf_mode_text);
-
-static const struct soc_enum wm5100_lhpf2_mode =
- SOC_ENUM_SINGLE(WM5100_HPLPF2_1, WM5100_LHPF2_MODE_SHIFT, 2,
- wm5100_lhpf_mode_text);
-
-static const struct soc_enum wm5100_lhpf3_mode =
- SOC_ENUM_SINGLE(WM5100_HPLPF3_1, WM5100_LHPF3_MODE_SHIFT, 2,
- wm5100_lhpf_mode_text);
-
-static const struct soc_enum wm5100_lhpf4_mode =
- SOC_ENUM_SINGLE(WM5100_HPLPF4_1, WM5100_LHPF4_MODE_SHIFT, 2,
- wm5100_lhpf_mode_text);
-
-static const struct snd_kcontrol_new wm5100_snd_controls[] = {
-SOC_SINGLE("IN1 High Performance Switch", WM5100_IN1L_CONTROL,
- WM5100_IN1_OSR_SHIFT, 1, 0),
-SOC_SINGLE("IN2 High Performance Switch", WM5100_IN2L_CONTROL,
- WM5100_IN2_OSR_SHIFT, 1, 0),
-SOC_SINGLE("IN3 High Performance Switch", WM5100_IN3L_CONTROL,
- WM5100_IN3_OSR_SHIFT, 1, 0),
-SOC_SINGLE("IN4 High Performance Switch", WM5100_IN4L_CONTROL,
- WM5100_IN4_OSR_SHIFT, 1, 0),
-
-/* Only applicable for analogue inputs */
-SOC_DOUBLE_R_TLV("IN1 Volume", WM5100_IN1L_CONTROL, WM5100_IN1R_CONTROL,
- WM5100_IN1L_PGA_VOL_SHIFT, 94, 0, in_tlv),
-SOC_DOUBLE_R_TLV("IN2 Volume", WM5100_IN2L_CONTROL, WM5100_IN2R_CONTROL,
- WM5100_IN2L_PGA_VOL_SHIFT, 94, 0, in_tlv),
-SOC_DOUBLE_R_TLV("IN3 Volume", WM5100_IN3L_CONTROL, WM5100_IN3R_CONTROL,
- WM5100_IN3L_PGA_VOL_SHIFT, 94, 0, in_tlv),
-SOC_DOUBLE_R_TLV("IN4 Volume", WM5100_IN4L_CONTROL, WM5100_IN4R_CONTROL,
- WM5100_IN4L_PGA_VOL_SHIFT, 94, 0, in_tlv),
-
-SOC_DOUBLE_R_TLV("IN1 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_1L,
- WM5100_ADC_DIGITAL_VOLUME_1R, WM5100_IN1L_VOL_SHIFT, 191,
- 0, digital_tlv),
-SOC_DOUBLE_R_TLV("IN2 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_2L,
- WM5100_ADC_DIGITAL_VOLUME_2R, WM5100_IN2L_VOL_SHIFT, 191,
- 0, digital_tlv),
-SOC_DOUBLE_R_TLV("IN3 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_3L,
- WM5100_ADC_DIGITAL_VOLUME_3R, WM5100_IN3L_VOL_SHIFT, 191,
- 0, digital_tlv),
-SOC_DOUBLE_R_TLV("IN4 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_4L,
- WM5100_ADC_DIGITAL_VOLUME_4R, WM5100_IN4L_VOL_SHIFT, 191,
- 0, digital_tlv),
-
-SOC_DOUBLE_R("IN1 Switch", WM5100_ADC_DIGITAL_VOLUME_1L,
- WM5100_ADC_DIGITAL_VOLUME_1R, WM5100_IN1L_MUTE_SHIFT, 1, 1),
-SOC_DOUBLE_R("IN2 Switch", WM5100_ADC_DIGITAL_VOLUME_2L,
- WM5100_ADC_DIGITAL_VOLUME_2R, WM5100_IN2L_MUTE_SHIFT, 1, 1),
-SOC_DOUBLE_R("IN3 Switch", WM5100_ADC_DIGITAL_VOLUME_3L,
- WM5100_ADC_DIGITAL_VOLUME_3R, WM5100_IN3L_MUTE_SHIFT, 1, 1),
-SOC_DOUBLE_R("IN4 Switch", WM5100_ADC_DIGITAL_VOLUME_4L,
- WM5100_ADC_DIGITAL_VOLUME_4R, WM5100_IN4L_MUTE_SHIFT, 1, 1),
-
-SOC_SINGLE("HPOUT1 High Performance Switch", WM5100_OUT_VOLUME_1L,
- WM5100_OUT1_OSR_SHIFT, 1, 0),
-SOC_SINGLE("HPOUT2 High Performance Switch", WM5100_OUT_VOLUME_2L,
- WM5100_OUT2_OSR_SHIFT, 1, 0),
-SOC_SINGLE("HPOUT3 High Performance Switch", WM5100_OUT_VOLUME_3L,
- WM5100_OUT3_OSR_SHIFT, 1, 0),
-SOC_SINGLE("SPKOUT High Performance Switch", WM5100_OUT_VOLUME_4L,
- WM5100_OUT4_OSR_SHIFT, 1, 0),
-SOC_SINGLE("SPKDAT1 High Performance Switch", WM5100_DAC_VOLUME_LIMIT_5L,
- WM5100_OUT5_OSR_SHIFT, 1, 0),
-SOC_SINGLE("SPKDAT2 High Performance Switch", WM5100_DAC_VOLUME_LIMIT_6L,
- WM5100_OUT6_OSR_SHIFT, 1, 0),
-
-SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_1L,
- WM5100_DAC_DIGITAL_VOLUME_1R, WM5100_OUT1L_VOL_SHIFT, 159, 0,
- digital_tlv),
-SOC_DOUBLE_R_TLV("HPOUT2 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_2L,
- WM5100_DAC_DIGITAL_VOLUME_2R, WM5100_OUT2L_VOL_SHIFT, 159, 0,
- digital_tlv),
-SOC_DOUBLE_R_TLV("HPOUT3 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_3L,
- WM5100_DAC_DIGITAL_VOLUME_3R, WM5100_OUT3L_VOL_SHIFT, 159, 0,
- digital_tlv),
-SOC_DOUBLE_R_TLV("SPKOUT Digital Volume", WM5100_DAC_DIGITAL_VOLUME_4L,
- WM5100_DAC_DIGITAL_VOLUME_4R, WM5100_OUT4L_VOL_SHIFT, 159, 0,
- digital_tlv),
-SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_5L,
- WM5100_DAC_DIGITAL_VOLUME_5R, WM5100_OUT5L_VOL_SHIFT, 159, 0,
- digital_tlv),
-SOC_DOUBLE_R_TLV("SPKDAT2 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_6L,
- WM5100_DAC_DIGITAL_VOLUME_6R, WM5100_OUT6L_VOL_SHIFT, 159, 0,
- digital_tlv),
-
-SOC_DOUBLE_R("HPOUT1 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_1L,
- WM5100_DAC_DIGITAL_VOLUME_1R, WM5100_OUT1L_MUTE_SHIFT, 1, 1),
-SOC_DOUBLE_R("HPOUT2 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_2L,
- WM5100_DAC_DIGITAL_VOLUME_2R, WM5100_OUT2L_MUTE_SHIFT, 1, 1),
-SOC_DOUBLE_R("HPOUT3 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_3L,
- WM5100_DAC_DIGITAL_VOLUME_3R, WM5100_OUT3L_MUTE_SHIFT, 1, 1),
-SOC_DOUBLE_R("SPKOUT Digital Switch", WM5100_DAC_DIGITAL_VOLUME_4L,
- WM5100_DAC_DIGITAL_VOLUME_4R, WM5100_OUT4L_MUTE_SHIFT, 1, 1),
-SOC_DOUBLE_R("SPKDAT1 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_5L,
- WM5100_DAC_DIGITAL_VOLUME_5R, WM5100_OUT5L_MUTE_SHIFT, 1, 1),
-SOC_DOUBLE_R("SPKDAT2 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_6L,
- WM5100_DAC_DIGITAL_VOLUME_6R, WM5100_OUT6L_MUTE_SHIFT, 1, 1),
-
-/* FIXME: Only valid from -12dB to 0dB (52-64) */
-SOC_DOUBLE_R_TLV("HPOUT1 Volume", WM5100_OUT_VOLUME_1L, WM5100_OUT_VOLUME_1R,
- WM5100_OUT1L_PGA_VOL_SHIFT, 64, 0, out_tlv),
-SOC_DOUBLE_R_TLV("HPOUT2 Volume", WM5100_OUT_VOLUME_2L, WM5100_OUT_VOLUME_2R,
- WM5100_OUT2L_PGA_VOL_SHIFT, 64, 0, out_tlv),
-SOC_DOUBLE_R_TLV("HPOUT3 Volume", WM5100_OUT_VOLUME_3L, WM5100_OUT_VOLUME_3R,
- WM5100_OUT2L_PGA_VOL_SHIFT, 64, 0, out_tlv),
-
-SOC_DOUBLE("SPKDAT1 Switch", WM5100_PDM_SPK1_CTRL_1, WM5100_SPK1L_MUTE_SHIFT,
- WM5100_SPK1R_MUTE_SHIFT, 1, 1),
-SOC_DOUBLE("SPKDAT2 Switch", WM5100_PDM_SPK2_CTRL_1, WM5100_SPK2L_MUTE_SHIFT,
- WM5100_SPK2R_MUTE_SHIFT, 1, 1),
-
-SOC_SINGLE_TLV("EQ1 Band 1 Volume", WM5100_EQ1_1, WM5100_EQ1_B1_GAIN_SHIFT,
- 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ1 Band 2 Volume", WM5100_EQ1_1, WM5100_EQ1_B2_GAIN_SHIFT,
- 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ1 Band 3 Volume", WM5100_EQ1_1, WM5100_EQ1_B3_GAIN_SHIFT,
- 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ1 Band 4 Volume", WM5100_EQ1_2, WM5100_EQ1_B4_GAIN_SHIFT,
- 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ1 Band 5 Volume", WM5100_EQ1_2, WM5100_EQ1_B5_GAIN_SHIFT,
- 24, 0, eq_tlv),
-
-SOC_SINGLE_TLV("EQ2 Band 1 Volume", WM5100_EQ2_1, WM5100_EQ2_B1_GAIN_SHIFT,
- 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ2 Band 2 Volume", WM5100_EQ2_1, WM5100_EQ2_B2_GAIN_SHIFT,
- 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ2 Band 3 Volume", WM5100_EQ2_1, WM5100_EQ2_B3_GAIN_SHIFT,
- 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ2 Band 4 Volume", WM5100_EQ2_2, WM5100_EQ2_B4_GAIN_SHIFT,
- 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ2 Band 5 Volume", WM5100_EQ2_2, WM5100_EQ2_B5_GAIN_SHIFT,
- 24, 0, eq_tlv),
-
-SOC_SINGLE_TLV("EQ3 Band 1 Volume", WM5100_EQ1_1, WM5100_EQ3_B1_GAIN_SHIFT,
- 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ3 Band 2 Volume", WM5100_EQ3_1, WM5100_EQ3_B2_GAIN_SHIFT,
- 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ3 Band 3 Volume", WM5100_EQ3_1, WM5100_EQ3_B3_GAIN_SHIFT,
- 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ3 Band 4 Volume", WM5100_EQ3_2, WM5100_EQ3_B4_GAIN_SHIFT,
- 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ3 Band 5 Volume", WM5100_EQ3_2, WM5100_EQ3_B5_GAIN_SHIFT,
- 24, 0, eq_tlv),
-
-SOC_SINGLE_TLV("EQ4 Band 1 Volume", WM5100_EQ4_1, WM5100_EQ4_B1_GAIN_SHIFT,
- 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ4 Band 2 Volume", WM5100_EQ4_1, WM5100_EQ4_B2_GAIN_SHIFT,
- 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ4 Band 3 Volume", WM5100_EQ4_1, WM5100_EQ4_B3_GAIN_SHIFT,
- 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ4 Band 4 Volume", WM5100_EQ4_2, WM5100_EQ4_B4_GAIN_SHIFT,
- 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ4 Band 5 Volume", WM5100_EQ4_2, WM5100_EQ4_B5_GAIN_SHIFT,
- 24, 0, eq_tlv),
-
-SOC_ENUM("LHPF1 Mode", wm5100_lhpf1_mode),
-SOC_ENUM("LHPF2 Mode", wm5100_lhpf2_mode),
-SOC_ENUM("LHPF3 Mode", wm5100_lhpf3_mode),
-SOC_ENUM("LHPF4 Mode", wm5100_lhpf4_mode),
-
-WM5100_MIXER_CONTROLS("HPOUT1L", WM5100_OUT1LMIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("HPOUT1R", WM5100_OUT1RMIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("HPOUT2L", WM5100_OUT2LMIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("HPOUT2R", WM5100_OUT2RMIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("HPOUT3L", WM5100_OUT3LMIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("HPOUT3R", WM5100_OUT3RMIX_INPUT_1_SOURCE),
-
-WM5100_MIXER_CONTROLS("SPKOUTL", WM5100_OUT4LMIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("SPKOUTR", WM5100_OUT4RMIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("SPKDAT1L", WM5100_OUT5LMIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("SPKDAT1R", WM5100_OUT5RMIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("SPKDAT2L", WM5100_OUT6LMIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("SPKDAT2R", WM5100_OUT6RMIX_INPUT_1_SOURCE),
-
-WM5100_MIXER_CONTROLS("PWM1", WM5100_PWM1MIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("PWM2", WM5100_PWM2MIX_INPUT_1_SOURCE),
-
-WM5100_MIXER_CONTROLS("AIF1TX1", WM5100_AIF1TX1MIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("AIF1TX2", WM5100_AIF1TX2MIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("AIF1TX3", WM5100_AIF1TX3MIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("AIF1TX4", WM5100_AIF1TX4MIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("AIF1TX5", WM5100_AIF1TX5MIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("AIF1TX6", WM5100_AIF1TX6MIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("AIF1TX7", WM5100_AIF1TX7MIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("AIF1TX8", WM5100_AIF1TX8MIX_INPUT_1_SOURCE),
-
-WM5100_MIXER_CONTROLS("AIF2TX1", WM5100_AIF2TX1MIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("AIF2TX2", WM5100_AIF2TX2MIX_INPUT_1_SOURCE),
-
-WM5100_MIXER_CONTROLS("AIF3TX1", WM5100_AIF3TX1MIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("AIF3TX2", WM5100_AIF3TX2MIX_INPUT_1_SOURCE),
-
-WM5100_MIXER_CONTROLS("EQ1", WM5100_EQ1MIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("EQ2", WM5100_EQ2MIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("EQ3", WM5100_EQ3MIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("EQ4", WM5100_EQ4MIX_INPUT_1_SOURCE),
-
-WM5100_MIXER_CONTROLS("DRC1L", WM5100_DRC1LMIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("DRC1R", WM5100_DRC1RMIX_INPUT_1_SOURCE),
-SND_SOC_BYTES_MASK("DRC", WM5100_DRC1_CTRL1, 5,
- WM5100_DRCL_ENA | WM5100_DRCR_ENA),
-
-WM5100_MIXER_CONTROLS("LHPF1", WM5100_HPLP1MIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("LHPF2", WM5100_HPLP2MIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("LHPF3", WM5100_HPLP3MIX_INPUT_1_SOURCE),
-WM5100_MIXER_CONTROLS("LHPF4", WM5100_HPLP4MIX_INPUT_1_SOURCE),
-};
-
-static void wm5100_seq_notifier(struct snd_soc_dapm_context *dapm,
- enum snd_soc_dapm_type event, int subseq)
-{
- struct snd_soc_codec *codec = container_of(dapm,
- struct snd_soc_codec, dapm);
- struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
- u16 val, expect, i;
-
- /* Wait for the outputs to flag themselves as enabled */
- if (wm5100->out_ena[0]) {
- expect = snd_soc_read(codec, WM5100_CHANNEL_ENABLES_1);
- for (i = 0; i < 200; i++) {
- val = snd_soc_read(codec, WM5100_OUTPUT_STATUS_1);
- if (val == expect) {
- wm5100->out_ena[0] = false;
- break;
- }
- }
- if (i == 200) {
- dev_err(codec->dev, "Timeout waiting for OUTPUT1 %x\n",
- expect);
- }
- }
-
- if (wm5100->out_ena[1]) {
- expect = snd_soc_read(codec, WM5100_OUTPUT_ENABLES_2);
- for (i = 0; i < 200; i++) {
- val = snd_soc_read(codec, WM5100_OUTPUT_STATUS_2);
- if (val == expect) {
- wm5100->out_ena[1] = false;
- break;
- }
- }
- if (i == 200) {
- dev_err(codec->dev, "Timeout waiting for OUTPUT2 %x\n",
- expect);
- }
- }
-}
-
-static int wm5100_out_ev(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol,
- int event)
-{
- struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(w->codec);
-
- switch (w->reg) {
- case WM5100_CHANNEL_ENABLES_1:
- wm5100->out_ena[0] = true;
- break;
- case WM5100_OUTPUT_ENABLES_2:
- wm5100->out_ena[0] = true;
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-static void wm5100_log_status3(struct wm5100_priv *wm5100, int val)
-{
- if (val & WM5100_SPK_SHUTDOWN_WARN_EINT)
- dev_crit(wm5100->dev, "Speaker shutdown warning\n");
- if (val & WM5100_SPK_SHUTDOWN_EINT)
- dev_crit(wm5100->dev, "Speaker shutdown\n");
- if (val & WM5100_CLKGEN_ERR_EINT)
- dev_crit(wm5100->dev, "SYSCLK underclocked\n");
- if (val & WM5100_CLKGEN_ERR_ASYNC_EINT)
- dev_crit(wm5100->dev, "ASYNCCLK underclocked\n");
-}
-
-static void wm5100_log_status4(struct wm5100_priv *wm5100, int val)
-{
- if (val & WM5100_AIF3_ERR_EINT)
- dev_err(wm5100->dev, "AIF3 configuration error\n");
- if (val & WM5100_AIF2_ERR_EINT)
- dev_err(wm5100->dev, "AIF2 configuration error\n");
- if (val & WM5100_AIF1_ERR_EINT)
- dev_err(wm5100->dev, "AIF1 configuration error\n");
- if (val & WM5100_CTRLIF_ERR_EINT)
- dev_err(wm5100->dev, "Control interface error\n");
- if (val & WM5100_ISRC2_UNDERCLOCKED_EINT)
- dev_err(wm5100->dev, "ISRC2 underclocked\n");
- if (val & WM5100_ISRC1_UNDERCLOCKED_EINT)
- dev_err(wm5100->dev, "ISRC1 underclocked\n");
- if (val & WM5100_FX_UNDERCLOCKED_EINT)
- dev_err(wm5100->dev, "FX underclocked\n");
- if (val & WM5100_AIF3_UNDERCLOCKED_EINT)
- dev_err(wm5100->dev, "AIF3 underclocked\n");
- if (val & WM5100_AIF2_UNDERCLOCKED_EINT)
- dev_err(wm5100->dev, "AIF2 underclocked\n");
- if (val & WM5100_AIF1_UNDERCLOCKED_EINT)
- dev_err(wm5100->dev, "AIF1 underclocked\n");
- if (val & WM5100_ASRC_UNDERCLOCKED_EINT)
- dev_err(wm5100->dev, "ASRC underclocked\n");
- if (val & WM5100_DAC_UNDERCLOCKED_EINT)
- dev_err(wm5100->dev, "DAC underclocked\n");
- if (val & WM5100_ADC_UNDERCLOCKED_EINT)
- dev_err(wm5100->dev, "ADC underclocked\n");
- if (val & WM5100_MIXER_UNDERCLOCKED_EINT)
- dev_err(wm5100->dev, "Mixer underclocked\n");
-}
-
-static int wm5100_post_ev(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol,
- int event)
-{
- struct snd_soc_codec *codec = w->codec;
- struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_3);
- ret &= WM5100_SPK_SHUTDOWN_WARN_STS |
- WM5100_SPK_SHUTDOWN_STS | WM5100_CLKGEN_ERR_STS |
- WM5100_CLKGEN_ERR_ASYNC_STS;
- wm5100_log_status3(wm5100, ret);
-
- ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_4);
- wm5100_log_status4(wm5100, ret);
-
- return 0;
-}
-
-static const struct snd_soc_dapm_widget wm5100_dapm_widgets[] = {
-SND_SOC_DAPM_SUPPLY("SYSCLK", WM5100_CLOCKING_3, WM5100_SYSCLK_ENA_SHIFT, 0,
- NULL, 0),
-SND_SOC_DAPM_SUPPLY("ASYNCCLK", WM5100_CLOCKING_6, WM5100_ASYNC_CLK_ENA_SHIFT,
- 0, NULL, 0),
-
-SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
-SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0),
-
-SND_SOC_DAPM_SUPPLY("CP1", WM5100_HP_CHARGE_PUMP_1, WM5100_CP1_ENA_SHIFT, 0,
- NULL, 0),
-SND_SOC_DAPM_SUPPLY("CP2", WM5100_MIC_CHARGE_PUMP_1, WM5100_CP2_ENA_SHIFT, 0,
- NULL, 0),
-SND_SOC_DAPM_SUPPLY("CP2 Active", WM5100_MIC_CHARGE_PUMP_1,
- WM5100_CP2_BYPASS_SHIFT, 1, NULL, 0),
-
-SND_SOC_DAPM_SUPPLY("MICBIAS1", WM5100_MIC_BIAS_CTRL_1, WM5100_MICB1_ENA_SHIFT,
- 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("MICBIAS2", WM5100_MIC_BIAS_CTRL_2, WM5100_MICB2_ENA_SHIFT,
- 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("MICBIAS3", WM5100_MIC_BIAS_CTRL_3, WM5100_MICB3_ENA_SHIFT,
- 0, NULL, 0),
-
-SND_SOC_DAPM_INPUT("IN1L"),
-SND_SOC_DAPM_INPUT("IN1R"),
-SND_SOC_DAPM_INPUT("IN2L"),
-SND_SOC_DAPM_INPUT("IN2R"),
-SND_SOC_DAPM_INPUT("IN3L"),
-SND_SOC_DAPM_INPUT("IN3R"),
-SND_SOC_DAPM_INPUT("IN4L"),
-SND_SOC_DAPM_INPUT("IN4R"),
-SND_SOC_DAPM_SIGGEN("TONE"),
-
-SND_SOC_DAPM_PGA_E("IN1L PGA", WM5100_INPUT_ENABLES, WM5100_IN1L_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("IN1R PGA", WM5100_INPUT_ENABLES, WM5100_IN1R_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("IN2L PGA", WM5100_INPUT_ENABLES, WM5100_IN2L_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("IN2R PGA", WM5100_INPUT_ENABLES, WM5100_IN2R_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("IN3L PGA", WM5100_INPUT_ENABLES, WM5100_IN3L_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("IN3R PGA", WM5100_INPUT_ENABLES, WM5100_IN3R_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("IN4L PGA", WM5100_INPUT_ENABLES, WM5100_IN4L_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("IN4R PGA", WM5100_INPUT_ENABLES, WM5100_IN4R_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-
-SND_SOC_DAPM_PGA("Tone Generator 1", WM5100_TONE_GENERATOR_1,
- WM5100_TONE1_ENA_SHIFT, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Tone Generator 2", WM5100_TONE_GENERATOR_1,
- WM5100_TONE2_ENA_SHIFT, 0, NULL, 0),
-
-SND_SOC_DAPM_AIF_IN("AIF1RX1", "AIF1 Playback", 0,
- WM5100_AUDIO_IF_1_27, WM5100_AIF1RX1_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX2", "AIF1 Playback", 1,
- WM5100_AUDIO_IF_1_27, WM5100_AIF1RX2_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX3", "AIF1 Playback", 2,
- WM5100_AUDIO_IF_1_27, WM5100_AIF1RX3_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX4", "AIF1 Playback", 3,
- WM5100_AUDIO_IF_1_27, WM5100_AIF1RX4_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 4,
- WM5100_AUDIO_IF_1_27, WM5100_AIF1RX5_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX6", "AIF1 Playback", 5,
- WM5100_AUDIO_IF_1_27, WM5100_AIF1RX6_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX7", "AIF1 Playback", 6,
- WM5100_AUDIO_IF_1_27, WM5100_AIF1RX7_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX8", "AIF1 Playback", 7,
- WM5100_AUDIO_IF_1_27, WM5100_AIF1RX8_ENA_SHIFT, 0),
-
-SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 0,
- WM5100_AUDIO_IF_2_27, WM5100_AIF2RX1_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_IN("AIF2RX2", "AIF2 Playback", 1,
- WM5100_AUDIO_IF_2_27, WM5100_AIF2RX2_ENA_SHIFT, 0),
-
-SND_SOC_DAPM_AIF_IN("AIF3RX1", "AIF3 Playback", 0,
- WM5100_AUDIO_IF_3_27, WM5100_AIF3RX1_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_IN("AIF3RX2", "AIF3 Playback", 1,
- WM5100_AUDIO_IF_3_27, WM5100_AIF3RX2_ENA_SHIFT, 0),
-
-SND_SOC_DAPM_AIF_OUT("AIF1TX1", "AIF1 Capture", 0,
- WM5100_AUDIO_IF_1_26, WM5100_AIF1TX1_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX2", "AIF1 Capture", 1,
- WM5100_AUDIO_IF_1_26, WM5100_AIF1TX2_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX3", "AIF1 Capture", 2,
- WM5100_AUDIO_IF_1_26, WM5100_AIF1TX3_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX4", "AIF1 Capture", 3,
- WM5100_AUDIO_IF_1_26, WM5100_AIF1TX4_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX5", "AIF1 Capture", 4,
- WM5100_AUDIO_IF_1_26, WM5100_AIF1TX5_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX6", "AIF1 Capture", 5,
- WM5100_AUDIO_IF_1_26, WM5100_AIF1TX6_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX7", "AIF1 Capture", 6,
- WM5100_AUDIO_IF_1_26, WM5100_AIF1TX7_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX8", "AIF1 Capture", 7,
- WM5100_AUDIO_IF_1_26, WM5100_AIF1TX8_ENA_SHIFT, 0),
-
-SND_SOC_DAPM_AIF_OUT("AIF2TX1", "AIF2 Capture", 0,
- WM5100_AUDIO_IF_2_26, WM5100_AIF2TX1_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_OUT("AIF2TX2", "AIF2 Capture", 1,
- WM5100_AUDIO_IF_2_26, WM5100_AIF2TX2_ENA_SHIFT, 0),
-
-SND_SOC_DAPM_AIF_OUT("AIF3TX1", "AIF3 Capture", 0,
- WM5100_AUDIO_IF_3_26, WM5100_AIF3TX1_ENA_SHIFT, 0),
-SND_SOC_DAPM_AIF_OUT("AIF3TX2", "AIF3 Capture", 1,
- WM5100_AUDIO_IF_3_26, WM5100_AIF3TX2_ENA_SHIFT, 0),
-
-SND_SOC_DAPM_PGA_E("OUT6L", WM5100_OUTPUT_ENABLES_2, WM5100_OUT6L_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("OUT6R", WM5100_OUTPUT_ENABLES_2, WM5100_OUT6R_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("OUT5L", WM5100_OUTPUT_ENABLES_2, WM5100_OUT5L_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("OUT5R", WM5100_OUTPUT_ENABLES_2, WM5100_OUT5R_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("OUT4L", WM5100_OUTPUT_ENABLES_2, WM5100_OUT4L_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("OUT4R", WM5100_OUTPUT_ENABLES_2, WM5100_OUT4R_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("OUT3L", WM5100_CHANNEL_ENABLES_1, WM5100_HP3L_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("OUT3R", WM5100_CHANNEL_ENABLES_1, WM5100_HP3R_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("OUT2L", WM5100_CHANNEL_ENABLES_1, WM5100_HP2L_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("OUT2R", WM5100_CHANNEL_ENABLES_1, WM5100_HP2R_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("OUT1L", WM5100_CHANNEL_ENABLES_1, WM5100_HP1L_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("OUT1R", WM5100_CHANNEL_ENABLES_1, WM5100_HP1R_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("PWM1 Driver", WM5100_PWM_DRIVE_1, WM5100_PWM1_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("PWM2 Driver", WM5100_PWM_DRIVE_1, WM5100_PWM2_ENA_SHIFT, 0,
- NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
-
-SND_SOC_DAPM_PGA("EQ1", WM5100_EQ1_1, WM5100_EQ1_ENA_SHIFT, 0, NULL, 0),
-SND_SOC_DAPM_PGA("EQ2", WM5100_EQ2_1, WM5100_EQ2_ENA_SHIFT, 0, NULL, 0),
-SND_SOC_DAPM_PGA("EQ3", WM5100_EQ3_1, WM5100_EQ3_ENA_SHIFT, 0, NULL, 0),
-SND_SOC_DAPM_PGA("EQ4", WM5100_EQ4_1, WM5100_EQ4_ENA_SHIFT, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA("DRC1L", WM5100_DRC1_CTRL1, WM5100_DRCL_ENA_SHIFT, 0,
- NULL, 0),
-SND_SOC_DAPM_PGA("DRC1R", WM5100_DRC1_CTRL1, WM5100_DRCR_ENA_SHIFT, 0,
- NULL, 0),
-
-SND_SOC_DAPM_PGA("LHPF1", WM5100_HPLPF1_1, WM5100_LHPF1_ENA_SHIFT, 0,
- NULL, 0),
-SND_SOC_DAPM_PGA("LHPF2", WM5100_HPLPF2_1, WM5100_LHPF2_ENA_SHIFT, 0,
- NULL, 0),
-SND_SOC_DAPM_PGA("LHPF3", WM5100_HPLPF3_1, WM5100_LHPF3_ENA_SHIFT, 0,
- NULL, 0),
-SND_SOC_DAPM_PGA("LHPF4", WM5100_HPLPF4_1, WM5100_LHPF4_ENA_SHIFT, 0,
- NULL, 0),
-
-WM5100_MIXER_WIDGETS(EQ1, "EQ1"),
-WM5100_MIXER_WIDGETS(EQ2, "EQ2"),
-WM5100_MIXER_WIDGETS(EQ3, "EQ3"),
-WM5100_MIXER_WIDGETS(EQ4, "EQ4"),
-
-WM5100_MIXER_WIDGETS(DRC1L, "DRC1L"),
-WM5100_MIXER_WIDGETS(DRC1R, "DRC1R"),
-
-WM5100_MIXER_WIDGETS(LHPF1, "LHPF1"),
-WM5100_MIXER_WIDGETS(LHPF2, "LHPF2"),
-WM5100_MIXER_WIDGETS(LHPF3, "LHPF3"),
-WM5100_MIXER_WIDGETS(LHPF4, "LHPF4"),
-
-WM5100_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
-WM5100_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
-WM5100_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
-WM5100_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
-WM5100_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
-WM5100_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
-WM5100_MIXER_WIDGETS(AIF1TX7, "AIF1TX7"),
-WM5100_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"),
-
-WM5100_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
-WM5100_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
-
-WM5100_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
-WM5100_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
-
-WM5100_MIXER_WIDGETS(HPOUT1L, "HPOUT1L"),
-WM5100_MIXER_WIDGETS(HPOUT1R, "HPOUT1R"),
-WM5100_MIXER_WIDGETS(HPOUT2L, "HPOUT2L"),
-WM5100_MIXER_WIDGETS(HPOUT2R, "HPOUT2R"),
-WM5100_MIXER_WIDGETS(HPOUT3L, "HPOUT3L"),
-WM5100_MIXER_WIDGETS(HPOUT3R, "HPOUT3R"),
-
-WM5100_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"),
-WM5100_MIXER_WIDGETS(SPKOUTR, "SPKOUTR"),
-WM5100_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"),
-WM5100_MIXER_WIDGETS(SPKDAT1R, "SPKDAT1R"),
-WM5100_MIXER_WIDGETS(SPKDAT2L, "SPKDAT2L"),
-WM5100_MIXER_WIDGETS(SPKDAT2R, "SPKDAT2R"),
-
-WM5100_MIXER_WIDGETS(PWM1, "PWM1"),
-WM5100_MIXER_WIDGETS(PWM2, "PWM2"),
-
-SND_SOC_DAPM_OUTPUT("HPOUT1L"),
-SND_SOC_DAPM_OUTPUT("HPOUT1R"),
-SND_SOC_DAPM_OUTPUT("HPOUT2L"),
-SND_SOC_DAPM_OUTPUT("HPOUT2R"),
-SND_SOC_DAPM_OUTPUT("HPOUT3L"),
-SND_SOC_DAPM_OUTPUT("HPOUT3R"),
-SND_SOC_DAPM_OUTPUT("SPKOUTL"),
-SND_SOC_DAPM_OUTPUT("SPKOUTR"),
-SND_SOC_DAPM_OUTPUT("SPKDAT1"),
-SND_SOC_DAPM_OUTPUT("SPKDAT2"),
-SND_SOC_DAPM_OUTPUT("PWM1"),
-SND_SOC_DAPM_OUTPUT("PWM2"),
-};
-
-/* We register a _POST event if we don't have IRQ support so we can
- * look at the error status from the CODEC - if we've got the IRQ
- * hooked up then we will get prompted to look by an interrupt.
- */
-static const struct snd_soc_dapm_widget wm5100_dapm_widgets_noirq[] = {
-SND_SOC_DAPM_POST("Post", wm5100_post_ev),
-};
-
-static const struct snd_soc_dapm_route wm5100_dapm_routes[] = {
- { "CP1", NULL, "CPVDD" },
- { "CP2 Active", NULL, "CPVDD" },
-
- { "IN1L", NULL, "SYSCLK" },
- { "IN1R", NULL, "SYSCLK" },
- { "IN2L", NULL, "SYSCLK" },
- { "IN2R", NULL, "SYSCLK" },
- { "IN3L", NULL, "SYSCLK" },
- { "IN3R", NULL, "SYSCLK" },
- { "IN4L", NULL, "SYSCLK" },
- { "IN4R", NULL, "SYSCLK" },
-
- { "OUT1L", NULL, "SYSCLK" },
- { "OUT1R", NULL, "SYSCLK" },
- { "OUT2L", NULL, "SYSCLK" },
- { "OUT2R", NULL, "SYSCLK" },
- { "OUT3L", NULL, "SYSCLK" },
- { "OUT3R", NULL, "SYSCLK" },
- { "OUT4L", NULL, "SYSCLK" },
- { "OUT4R", NULL, "SYSCLK" },
- { "OUT5L", NULL, "SYSCLK" },
- { "OUT5R", NULL, "SYSCLK" },
- { "OUT6L", NULL, "SYSCLK" },
- { "OUT6R", NULL, "SYSCLK" },
-
- { "AIF1RX1", NULL, "SYSCLK" },
- { "AIF1RX2", NULL, "SYSCLK" },
- { "AIF1RX3", NULL, "SYSCLK" },
- { "AIF1RX4", NULL, "SYSCLK" },
- { "AIF1RX5", NULL, "SYSCLK" },
- { "AIF1RX6", NULL, "SYSCLK" },
- { "AIF1RX7", NULL, "SYSCLK" },
- { "AIF1RX8", NULL, "SYSCLK" },
-
- { "AIF2RX1", NULL, "SYSCLK" },
- { "AIF2RX1", NULL, "DBVDD2" },
- { "AIF2RX2", NULL, "SYSCLK" },
- { "AIF2RX2", NULL, "DBVDD2" },
-
- { "AIF3RX1", NULL, "SYSCLK" },
- { "AIF3RX1", NULL, "DBVDD3" },
- { "AIF3RX2", NULL, "SYSCLK" },
- { "AIF3RX2", NULL, "DBVDD3" },
-
- { "AIF1TX1", NULL, "SYSCLK" },
- { "AIF1TX2", NULL, "SYSCLK" },
- { "AIF1TX3", NULL, "SYSCLK" },
- { "AIF1TX4", NULL, "SYSCLK" },
- { "AIF1TX5", NULL, "SYSCLK" },
- { "AIF1TX6", NULL, "SYSCLK" },
- { "AIF1TX7", NULL, "SYSCLK" },
- { "AIF1TX8", NULL, "SYSCLK" },
-
- { "AIF2TX1", NULL, "SYSCLK" },
- { "AIF2TX1", NULL, "DBVDD2" },
- { "AIF2TX2", NULL, "SYSCLK" },
- { "AIF2TX2", NULL, "DBVDD2" },
-
- { "AIF3TX1", NULL, "SYSCLK" },
- { "AIF3TX1", NULL, "DBVDD3" },
- { "AIF3TX2", NULL, "SYSCLK" },
- { "AIF3TX2", NULL, "DBVDD3" },
-
- { "MICBIAS1", NULL, "CP2" },
- { "MICBIAS2", NULL, "CP2" },
- { "MICBIAS3", NULL, "CP2" },
-
- { "IN1L PGA", NULL, "CP2" },
- { "IN1R PGA", NULL, "CP2" },
- { "IN2L PGA", NULL, "CP2" },
- { "IN2R PGA", NULL, "CP2" },
- { "IN3L PGA", NULL, "CP2" },
- { "IN3R PGA", NULL, "CP2" },
- { "IN4L PGA", NULL, "CP2" },
- { "IN4R PGA", NULL, "CP2" },
-
- { "IN1L PGA", NULL, "CP2 Active" },
- { "IN1R PGA", NULL, "CP2 Active" },
- { "IN2L PGA", NULL, "CP2 Active" },
- { "IN2R PGA", NULL, "CP2 Active" },
- { "IN3L PGA", NULL, "CP2 Active" },
- { "IN3R PGA", NULL, "CP2 Active" },
- { "IN4L PGA", NULL, "CP2 Active" },
- { "IN4R PGA", NULL, "CP2 Active" },
-
- { "OUT1L", NULL, "CP1" },
- { "OUT1R", NULL, "CP1" },
- { "OUT2L", NULL, "CP1" },
- { "OUT2R", NULL, "CP1" },
- { "OUT3L", NULL, "CP1" },
- { "OUT3R", NULL, "CP1" },
-
- { "Tone Generator 1", NULL, "TONE" },
- { "Tone Generator 2", NULL, "TONE" },
-
- { "IN1L PGA", NULL, "IN1L" },
- { "IN1R PGA", NULL, "IN1R" },
- { "IN2L PGA", NULL, "IN2L" },
- { "IN2R PGA", NULL, "IN2R" },
- { "IN3L PGA", NULL, "IN3L" },
- { "IN3R PGA", NULL, "IN3R" },
- { "IN4L PGA", NULL, "IN4L" },
- { "IN4R PGA", NULL, "IN4R" },
-
- WM5100_MIXER_ROUTES("OUT1L", "HPOUT1L"),
- WM5100_MIXER_ROUTES("OUT1R", "HPOUT1R"),
- WM5100_MIXER_ROUTES("OUT2L", "HPOUT2L"),
- WM5100_MIXER_ROUTES("OUT2R", "HPOUT2R"),
- WM5100_MIXER_ROUTES("OUT3L", "HPOUT3L"),
- WM5100_MIXER_ROUTES("OUT3R", "HPOUT3R"),
-
- WM5100_MIXER_ROUTES("OUT4L", "SPKOUTL"),
- WM5100_MIXER_ROUTES("OUT4R", "SPKOUTR"),
- WM5100_MIXER_ROUTES("OUT5L", "SPKDAT1L"),
- WM5100_MIXER_ROUTES("OUT5R", "SPKDAT1R"),
- WM5100_MIXER_ROUTES("OUT6L", "SPKDAT2L"),
- WM5100_MIXER_ROUTES("OUT6R", "SPKDAT2R"),
-
- WM5100_MIXER_ROUTES("PWM1 Driver", "PWM1"),
- WM5100_MIXER_ROUTES("PWM2 Driver", "PWM2"),
-
- WM5100_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
- WM5100_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
- WM5100_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
- WM5100_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
- WM5100_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
- WM5100_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
- WM5100_MIXER_ROUTES("AIF1TX7", "AIF1TX7"),
- WM5100_MIXER_ROUTES("AIF1TX8", "AIF1TX8"),
-
- WM5100_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
- WM5100_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
-
- WM5100_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
- WM5100_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
-
- WM5100_MIXER_ROUTES("EQ1", "EQ1"),
- WM5100_MIXER_ROUTES("EQ2", "EQ2"),
- WM5100_MIXER_ROUTES("EQ3", "EQ3"),
- WM5100_MIXER_ROUTES("EQ4", "EQ4"),
-
- WM5100_MIXER_ROUTES("DRC1L", "DRC1L"),
- WM5100_MIXER_ROUTES("DRC1R", "DRC1R"),
-
- WM5100_MIXER_ROUTES("LHPF1", "LHPF1"),
- WM5100_MIXER_ROUTES("LHPF2", "LHPF2"),
- WM5100_MIXER_ROUTES("LHPF3", "LHPF3"),
- WM5100_MIXER_ROUTES("LHPF4", "LHPF4"),
-
- { "HPOUT1L", NULL, "OUT1L" },
- { "HPOUT1R", NULL, "OUT1R" },
- { "HPOUT2L", NULL, "OUT2L" },
- { "HPOUT2R", NULL, "OUT2R" },
- { "HPOUT3L", NULL, "OUT3L" },
- { "HPOUT3R", NULL, "OUT3R" },
- { "SPKOUTL", NULL, "OUT4L" },
- { "SPKOUTR", NULL, "OUT4R" },
- { "SPKDAT1", NULL, "OUT5L" },
- { "SPKDAT1", NULL, "OUT5R" },
- { "SPKDAT2", NULL, "OUT6L" },
- { "SPKDAT2", NULL, "OUT6R" },
- { "PWM1", NULL, "PWM1 Driver" },
- { "PWM2", NULL, "PWM2 Driver" },
-};
-
-static const __devinitdata struct reg_default wm5100_reva_patches[] = {
- { WM5100_AUDIO_IF_1_10, 0 },
- { WM5100_AUDIO_IF_1_11, 1 },
- { WM5100_AUDIO_IF_1_12, 2 },
- { WM5100_AUDIO_IF_1_13, 3 },
- { WM5100_AUDIO_IF_1_14, 4 },
- { WM5100_AUDIO_IF_1_15, 5 },
- { WM5100_AUDIO_IF_1_16, 6 },
- { WM5100_AUDIO_IF_1_17, 7 },
-
- { WM5100_AUDIO_IF_1_18, 0 },
- { WM5100_AUDIO_IF_1_19, 1 },
- { WM5100_AUDIO_IF_1_20, 2 },
- { WM5100_AUDIO_IF_1_21, 3 },
- { WM5100_AUDIO_IF_1_22, 4 },
- { WM5100_AUDIO_IF_1_23, 5 },
- { WM5100_AUDIO_IF_1_24, 6 },
- { WM5100_AUDIO_IF_1_25, 7 },
-
- { WM5100_AUDIO_IF_2_10, 0 },
- { WM5100_AUDIO_IF_2_11, 1 },
-
- { WM5100_AUDIO_IF_2_18, 0 },
- { WM5100_AUDIO_IF_2_19, 1 },
-
- { WM5100_AUDIO_IF_3_10, 0 },
- { WM5100_AUDIO_IF_3_11, 1 },
-
- { WM5100_AUDIO_IF_3_18, 0 },
- { WM5100_AUDIO_IF_3_19, 1 },
-};
-
-static int wm5100_dai_to_base(struct snd_soc_dai *dai)
-{
- switch (dai->id) {
- case 0:
- return WM5100_AUDIO_IF_1_1 - 1;
- case 1:
- return WM5100_AUDIO_IF_2_1 - 1;
- case 2:
- return WM5100_AUDIO_IF_3_1 - 1;
- default:
- BUG();
- return -EINVAL;
- }
-}
-
-static int wm5100_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = dai->codec;
- int lrclk, bclk, mask, base;
-
- base = wm5100_dai_to_base(dai);
- if (base < 0)
- return base;
-
- lrclk = 0;
- bclk = 0;
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- mask = 0;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- mask = 1;
- break;
- case SND_SOC_DAIFMT_I2S:
- mask = 2;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- mask = 3;
- break;
- default:
- dev_err(codec->dev, "Unsupported DAI format %d\n",
- fmt & SND_SOC_DAIFMT_FORMAT_MASK);
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- case SND_SOC_DAIFMT_CBS_CFM:
- lrclk |= WM5100_AIF1TX_LRCLK_MSTR;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- bclk |= WM5100_AIF1_BCLK_MSTR;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- lrclk |= WM5100_AIF1TX_LRCLK_MSTR;
- bclk |= WM5100_AIF1_BCLK_MSTR;
- break;
- default:
- dev_err(codec->dev, "Unsupported master mode %d\n",
- fmt & SND_SOC_DAIFMT_MASTER_MASK);
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- bclk |= WM5100_AIF1_BCLK_INV;
- lrclk |= WM5100_AIF1TX_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- bclk |= WM5100_AIF1_BCLK_INV;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- lrclk |= WM5100_AIF1TX_LRCLK_INV;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, base + 1, WM5100_AIF1_BCLK_MSTR |
- WM5100_AIF1_BCLK_INV, bclk);
- snd_soc_update_bits(codec, base + 2, WM5100_AIF1TX_LRCLK_MSTR |
- WM5100_AIF1TX_LRCLK_INV, lrclk);
- snd_soc_update_bits(codec, base + 3, WM5100_AIF1TX_LRCLK_MSTR |
- WM5100_AIF1TX_LRCLK_INV, lrclk);
- snd_soc_update_bits(codec, base + 5, WM5100_AIF1_FMT_MASK, mask);
-
- return 0;
-}
-
-#define WM5100_NUM_BCLK_RATES 19
-
-static int wm5100_bclk_rates_dat[WM5100_NUM_BCLK_RATES] = {
- 32000,
- 48000,
- 64000,
- 96000,
- 128000,
- 192000,
- 256000,
- 384000,
- 512000,
- 768000,
- 1024000,
- 1536000,
- 2048000,
- 3072000,
- 4096000,
- 6144000,
- 8192000,
- 12288000,
- 24576000,
-};
-
-static int wm5100_bclk_rates_cd[WM5100_NUM_BCLK_RATES] = {
- 29400,
- 44100,
- 58800,
- 88200,
- 117600,
- 176400,
- 235200,
- 352800,
- 470400,
- 705600,
- 940800,
- 1411200,
- 1881600,
- 2882400,
- 3763200,
- 5644800,
- 7526400,
- 11289600,
- 22579600,
-};
-
-static int wm5100_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
- bool async = wm5100->aif_async[dai->id];
- int i, base, bclk, aif_rate, lrclk, wl, fl, sr;
- int *bclk_rates;
-
- base = wm5100_dai_to_base(dai);
- if (base < 0)
- return base;
-
- /* Data sizes if not using TDM */
- wl = snd_pcm_format_width(params_format(params));
- if (wl < 0)
- return wl;
- fl = snd_soc_params_to_frame_size(params);
- if (fl < 0)
- return fl;
-
- dev_dbg(codec->dev, "Word length %d bits, frame length %d bits\n",
- wl, fl);
-
- /* Target BCLK rate */
- bclk = snd_soc_params_to_bclk(params);
- if (bclk < 0)
- return bclk;
-
- /* Root for BCLK depends on SYS/ASYNCCLK */
- if (!async) {
- aif_rate = wm5100->sysclk;
- sr = wm5100_alloc_sr(codec, params_rate(params));
- if (sr < 0)
- return sr;
- } else {
- /* If we're in ASYNCCLK set the ASYNC sample rate */
- aif_rate = wm5100->asyncclk;
- sr = 3;
-
- for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
- if (params_rate(params) == wm5100_sr_code[i])
- break;
- if (i == ARRAY_SIZE(wm5100_sr_code)) {
- dev_err(codec->dev, "Invalid rate %dHzn",
- params_rate(params));
- return -EINVAL;
- }
-
- /* TODO: We should really check for symmetry */
- snd_soc_update_bits(codec, WM5100_CLOCKING_8,
- WM5100_ASYNC_SAMPLE_RATE_MASK, i);
- }
-
- if (!aif_rate) {
- dev_err(codec->dev, "%s has no rate set\n",
- async ? "ASYNCCLK" : "SYSCLK");
- return -EINVAL;
- }
-
- dev_dbg(codec->dev, "Target BCLK is %dHz, using %dHz %s\n",
- bclk, aif_rate, async ? "ASYNCCLK" : "SYSCLK");
-
- if (aif_rate % 4000)
- bclk_rates = wm5100_bclk_rates_cd;
- else
- bclk_rates = wm5100_bclk_rates_dat;
-
- for (i = 0; i < WM5100_NUM_BCLK_RATES; i++)
- if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0))
- break;
- if (i == WM5100_NUM_BCLK_RATES) {
- dev_err(codec->dev,
- "No valid BCLK for %dHz found from %dHz %s\n",
- bclk, aif_rate, async ? "ASYNCCLK" : "SYSCLK");
- return -EINVAL;
- }
-
- bclk = i;
- dev_dbg(codec->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
- snd_soc_update_bits(codec, base + 1, WM5100_AIF1_BCLK_FREQ_MASK, bclk);
-
- lrclk = bclk_rates[bclk] / params_rate(params);
- dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
- wm5100->aif_symmetric[dai->id])
- snd_soc_update_bits(codec, base + 7,
- WM5100_AIF1RX_BCPF_MASK, lrclk);
- else
- snd_soc_update_bits(codec, base + 6,
- WM5100_AIF1TX_BCPF_MASK, lrclk);
-
- i = (wl << WM5100_AIF1TX_WL_SHIFT) | fl;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- snd_soc_update_bits(codec, base + 9,
- WM5100_AIF1RX_WL_MASK |
- WM5100_AIF1RX_SLOT_LEN_MASK, i);
- else
- snd_soc_update_bits(codec, base + 8,
- WM5100_AIF1TX_WL_MASK |
- WM5100_AIF1TX_SLOT_LEN_MASK, i);
-
- snd_soc_update_bits(codec, base + 4, WM5100_AIF1_RATE_MASK, sr);
-
- return 0;
-}
-
-static const struct snd_soc_dai_ops wm5100_dai_ops = {
- .set_fmt = wm5100_set_fmt,
- .hw_params = wm5100_hw_params,
-};
-
-static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
- int source, unsigned int freq, int dir)
-{
- struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
- int *rate_store;
- int fval, audio_rate, ret, reg;
-
- switch (clk_id) {
- case WM5100_CLK_SYSCLK:
- reg = WM5100_CLOCKING_3;
- rate_store = &wm5100->sysclk;
- break;
- case WM5100_CLK_ASYNCCLK:
- reg = WM5100_CLOCKING_7;
- rate_store = &wm5100->asyncclk;
- break;
- case WM5100_CLK_32KHZ:
- /* The 32kHz clock is slightly different to the others */
- switch (source) {
- case WM5100_CLKSRC_MCLK1:
- case WM5100_CLKSRC_MCLK2:
- case WM5100_CLKSRC_SYSCLK:
- snd_soc_update_bits(codec, WM5100_CLOCKING_1,
- WM5100_CLK_32K_SRC_MASK,
- source);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-
- case WM5100_CLK_AIF1:
- case WM5100_CLK_AIF2:
- case WM5100_CLK_AIF3:
- /* Not real clocks, record which clock domain they're in */
- switch (source) {
- case WM5100_CLKSRC_SYSCLK:
- wm5100->aif_async[clk_id - 1] = false;
- break;
- case WM5100_CLKSRC_ASYNCCLK:
- wm5100->aif_async[clk_id - 1] = true;
- break;
- default:
- dev_err(codec->dev, "Invalid source %d\n", source);
- return -EINVAL;
- }
- return 0;
-
- case WM5100_CLK_OPCLK:
- switch (freq) {
- case 5644800:
- case 6144000:
- snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
- WM5100_OPCLK_SEL_MASK, 0);
- break;
- case 11289600:
- case 12288000:
- snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
- WM5100_OPCLK_SEL_MASK, 0);
- break;
- case 22579200:
- case 24576000:
- snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
- WM5100_OPCLK_SEL_MASK, 0);
- break;
- default:
- dev_err(codec->dev, "Unsupported OPCLK %dHz\n",
- freq);
- return -EINVAL;
- }
- return 0;
-
- default:
- dev_err(codec->dev, "Unknown clock %d\n", clk_id);
- return -EINVAL;
- }
-
- switch (source) {
- case WM5100_CLKSRC_SYSCLK:
- case WM5100_CLKSRC_ASYNCCLK:
- dev_err(codec->dev, "Invalid source %d\n", source);
- return -EINVAL;
- }
-
- switch (freq) {
- case 5644800:
- case 6144000:
- fval = 0;
- break;
- case 11289600:
- case 12288000:
- fval = 1;
- break;
- case 22579200:
- case 24576000:
- fval = 2;
- break;
- default:
- dev_err(codec->dev, "Invalid clock rate: %d\n", freq);
- return -EINVAL;
- }
-
- switch (freq) {
- case 5644800:
- case 11289600:
- case 22579200:
- audio_rate = 44100;
- break;
-
- case 6144000:
- case 12288000:
- case 24576000:
- audio_rate = 48000;
- break;
-
- default:
- BUG();
- audio_rate = 0;
- break;
- }
-
- /* TODO: Check if MCLKs are in use and enable/disable pulls to
- * match.
- */
-
- snd_soc_update_bits(codec, reg, WM5100_SYSCLK_FREQ_MASK |
- WM5100_SYSCLK_SRC_MASK,
- fval << WM5100_SYSCLK_FREQ_SHIFT | source);
-
- /* If this is SYSCLK then configure the clock rate for the
- * internal audio functions to the natural sample rate for
- * this clock rate.
- */
- if (clk_id == WM5100_CLK_SYSCLK) {
- dev_dbg(codec->dev, "Setting primary audio rate to %dHz",
- audio_rate);
- if (0 && *rate_store)
- wm5100_free_sr(codec, audio_rate);
- ret = wm5100_alloc_sr(codec, audio_rate);
- if (ret != 0)
- dev_warn(codec->dev, "Primary audio slot is %d\n",
- ret);
- }
-
- *rate_store = freq;
-
- return 0;
-}
-
-struct _fll_div {
- u16 fll_fratio;
- u16 fll_outdiv;
- u16 fll_refclk_div;
- u16 n;
- u16 theta;
- u16 lambda;
-};
-
-static struct {
- unsigned int min;
- unsigned int max;
- u16 fll_fratio;
- int ratio;
-} fll_fratios[] = {
- { 0, 64000, 4, 16 },
- { 64000, 128000, 3, 8 },
- { 128000, 256000, 2, 4 },
- { 256000, 1000000, 1, 2 },
- { 1000000, 13500000, 0, 1 },
-};
-
-static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
- unsigned int Fout)
-{
- unsigned int target;
- unsigned int div;
- unsigned int fratio, gcd_fll;
- int i;
-
- /* Fref must be <=13.5MHz */
- div = 1;
- fll_div->fll_refclk_div = 0;
- while ((Fref / div) > 13500000) {
- div *= 2;
- fll_div->fll_refclk_div++;
-
- if (div > 8) {
- pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
- Fref);
- return -EINVAL;
- }
- }
-
- pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
-
- /* Apply the division for our remaining calculations */
- Fref /= div;
-
- /* Fvco should be 90-100MHz; don't check the upper bound */
- div = 2;
- while (Fout * div < 90000000) {
- div++;
- if (div > 64) {
- pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
- Fout);
- return -EINVAL;
- }
- }
- target = Fout * div;
- fll_div->fll_outdiv = div - 1;
-
- pr_debug("FLL Fvco=%dHz\n", target);
-
- /* Find an appropraite FLL_FRATIO and factor it out of the target */
- for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
- if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
- fll_div->fll_fratio = fll_fratios[i].fll_fratio;
- fratio = fll_fratios[i].ratio;
- break;
- }
- }
- if (i == ARRAY_SIZE(fll_fratios)) {
- pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
- return -EINVAL;
- }
-
- fll_div->n = target / (fratio * Fref);
-
- if (target % Fref == 0) {
- fll_div->theta = 0;
- fll_div->lambda = 0;
- } else {
- gcd_fll = gcd(target, fratio * Fref);
-
- fll_div->theta = (target - (fll_div->n * fratio * Fref))
- / gcd_fll;
- fll_div->lambda = (fratio * Fref) / gcd_fll;
- }
-
- pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
- fll_div->n, fll_div->theta, fll_div->lambda);
- pr_debug("FLL_FRATIO=%x(%d) FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
- fll_div->fll_fratio, fratio, fll_div->fll_outdiv,
- fll_div->fll_refclk_div);
-
- return 0;
-}
-
-static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
- unsigned int Fref, unsigned int Fout)
-{
- struct i2c_client *i2c = to_i2c_client(codec->dev);
- struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
- struct _fll_div factors;
- struct wm5100_fll *fll;
- int ret, base, lock, i, timeout;
-
- switch (fll_id) {
- case WM5100_FLL1:
- fll = &wm5100->fll[0];
- base = WM5100_FLL1_CONTROL_1 - 1;
- lock = WM5100_FLL1_LOCK_STS;
- break;
- case WM5100_FLL2:
- fll = &wm5100->fll[1];
- base = WM5100_FLL2_CONTROL_2 - 1;
- lock = WM5100_FLL2_LOCK_STS;
- break;
- default:
- dev_err(codec->dev, "Unknown FLL %d\n",fll_id);
- return -EINVAL;
- }
-
- if (!Fout) {
- dev_dbg(codec->dev, "FLL%d disabled", fll_id);
- if (fll->fout)
- pm_runtime_put(codec->dev);
- fll->fout = 0;
- snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
- return 0;
- }
-
- switch (source) {
- case WM5100_FLL_SRC_MCLK1:
- case WM5100_FLL_SRC_MCLK2:
- case WM5100_FLL_SRC_FLL1:
- case WM5100_FLL_SRC_FLL2:
- case WM5100_FLL_SRC_AIF1BCLK:
- case WM5100_FLL_SRC_AIF2BCLK:
- case WM5100_FLL_SRC_AIF3BCLK:
- break;
- default:
- dev_err(codec->dev, "Invalid FLL source %d\n", source);
- return -EINVAL;
- }
-
- ret = fll_factors(&factors, Fref, Fout);
- if (ret < 0)
- return ret;
-
- /* Disable the FLL while we reconfigure */
- snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
-
- snd_soc_update_bits(codec, base + 2,
- WM5100_FLL1_OUTDIV_MASK | WM5100_FLL1_FRATIO_MASK,
- (factors.fll_outdiv << WM5100_FLL1_OUTDIV_SHIFT) |
- factors.fll_fratio);
- snd_soc_update_bits(codec, base + 3, WM5100_FLL1_THETA_MASK,
- factors.theta);
- snd_soc_update_bits(codec, base + 5, WM5100_FLL1_N_MASK, factors.n);
- snd_soc_update_bits(codec, base + 6,
- WM5100_FLL1_REFCLK_DIV_MASK |
- WM5100_FLL1_REFCLK_SRC_MASK,
- (factors.fll_refclk_div
- << WM5100_FLL1_REFCLK_DIV_SHIFT) | source);
- snd_soc_update_bits(codec, base + 7, WM5100_FLL1_LAMBDA_MASK,
- factors.lambda);
-
- /* Clear any pending completions */
- try_wait_for_completion(&fll->lock);
-
- pm_runtime_get_sync(codec->dev);
-
- snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, WM5100_FLL1_ENA);
-
- if (i2c->irq)
- timeout = 2;
- else
- timeout = 50;
-
- snd_soc_update_bits(codec, WM5100_CLOCKING_3, WM5100_SYSCLK_ENA,
- WM5100_SYSCLK_ENA);
-
- /* Poll for the lock; will use interrupt when we can test */
- for (i = 0; i < timeout; i++) {
- if (i2c->irq) {
- ret = wait_for_completion_timeout(&fll->lock,
- msecs_to_jiffies(25));
- if (ret > 0)
- break;
- } else {
- msleep(1);
- }
-
- ret = snd_soc_read(codec,
- WM5100_INTERRUPT_RAW_STATUS_3);
- if (ret < 0) {
- dev_err(codec->dev,
- "Failed to read FLL status: %d\n",
- ret);
- continue;
- }
- if (ret & lock)
- break;
- }
- if (i == timeout) {
- dev_err(codec->dev, "FLL%d lock timed out\n", fll_id);
- pm_runtime_put(codec->dev);
- return -ETIMEDOUT;
- }
-
- fll->src = source;
- fll->fref = Fref;
- fll->fout = Fout;
-
- dev_dbg(codec->dev, "FLL%d running %dHz->%dHz\n", fll_id,
- Fref, Fout);
-
- return 0;
-}
-
-/* Actually go much higher */
-#define WM5100_RATES SNDRV_PCM_RATE_8000_192000
-
-#define WM5100_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static struct snd_soc_dai_driver wm5100_dai[] = {
- {
- .name = "wm5100-aif1",
- .playback = {
- .stream_name = "AIF1 Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = WM5100_RATES,
- .formats = WM5100_FORMATS,
- },
- .capture = {
- .stream_name = "AIF1 Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = WM5100_RATES,
- .formats = WM5100_FORMATS,
- },
- .ops = &wm5100_dai_ops,
- },
- {
- .name = "wm5100-aif2",
- .id = 1,
- .playback = {
- .stream_name = "AIF2 Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = WM5100_RATES,
- .formats = WM5100_FORMATS,
- },
- .capture = {
- .stream_name = "AIF2 Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = WM5100_RATES,
- .formats = WM5100_FORMATS,
- },
- .ops = &wm5100_dai_ops,
- },
- {
- .name = "wm5100-aif3",
- .id = 2,
- .playback = {
- .stream_name = "AIF3 Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = WM5100_RATES,
- .formats = WM5100_FORMATS,
- },
- .capture = {
- .stream_name = "AIF3 Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = WM5100_RATES,
- .formats = WM5100_FORMATS,
- },
- .ops = &wm5100_dai_ops,
- },
-};
-
-static int wm5100_dig_vu[] = {
- WM5100_ADC_DIGITAL_VOLUME_1L,
- WM5100_ADC_DIGITAL_VOLUME_1R,
- WM5100_ADC_DIGITAL_VOLUME_2L,
- WM5100_ADC_DIGITAL_VOLUME_2R,
- WM5100_ADC_DIGITAL_VOLUME_3L,
- WM5100_ADC_DIGITAL_VOLUME_3R,
- WM5100_ADC_DIGITAL_VOLUME_4L,
- WM5100_ADC_DIGITAL_VOLUME_4R,
-
- WM5100_DAC_DIGITAL_VOLUME_1L,
- WM5100_DAC_DIGITAL_VOLUME_1R,
- WM5100_DAC_DIGITAL_VOLUME_2L,
- WM5100_DAC_DIGITAL_VOLUME_2R,
- WM5100_DAC_DIGITAL_VOLUME_3L,
- WM5100_DAC_DIGITAL_VOLUME_3R,
- WM5100_DAC_DIGITAL_VOLUME_4L,
- WM5100_DAC_DIGITAL_VOLUME_4R,
- WM5100_DAC_DIGITAL_VOLUME_5L,
- WM5100_DAC_DIGITAL_VOLUME_5R,
- WM5100_DAC_DIGITAL_VOLUME_6L,
- WM5100_DAC_DIGITAL_VOLUME_6R,
-};
-
-static void wm5100_set_detect_mode(struct wm5100_priv *wm5100, int the_mode)
-{
- struct wm5100_jack_mode *mode = &wm5100->pdata.jack_modes[the_mode];
-
- BUG_ON(the_mode >= ARRAY_SIZE(wm5100->pdata.jack_modes));
-
- gpio_set_value_cansleep(wm5100->pdata.hp_pol, mode->hp_pol);
- regmap_update_bits(wm5100->regmap, WM5100_ACCESSORY_DETECT_MODE_1,
- WM5100_ACCDET_BIAS_SRC_MASK |
- WM5100_ACCDET_SRC,
- (mode->bias << WM5100_ACCDET_BIAS_SRC_SHIFT) |
- mode->micd_src << WM5100_ACCDET_SRC_SHIFT);
- regmap_update_bits(wm5100->regmap, WM5100_MISC_CONTROL,
- WM5100_HPCOM_SRC,
- mode->micd_src << WM5100_HPCOM_SRC_SHIFT);
-
- wm5100->jack_mode = the_mode;
-
- dev_dbg(wm5100->dev, "Set microphone polarity to %d\n",
- wm5100->jack_mode);
-}
-
-static void wm5100_report_headphone(struct wm5100_priv *wm5100)
-{
- dev_dbg(wm5100->dev, "Headphone detected\n");
- wm5100->jack_detecting = false;
- snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE,
- SND_JACK_HEADPHONE);
-
- /* Increase the detection rate a bit for responsiveness. */
- regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1,
- WM5100_ACCDET_RATE_MASK,
- 7 << WM5100_ACCDET_RATE_SHIFT);
-}
-
-static void wm5100_micd_irq(struct wm5100_priv *wm5100)
-{
- unsigned int val;
- int ret;
-
- ret = regmap_read(wm5100->regmap, WM5100_MIC_DETECT_3, &val);
- if (ret != 0) {
- dev_err(wm5100->dev, "Failed to read micropone status: %d\n",
- ret);
- return;
- }
-
- dev_dbg(wm5100->dev, "Microphone event: %x\n", val);
-
- if (!(val & WM5100_ACCDET_VALID)) {
- dev_warn(wm5100->dev, "Microphone detection state invalid\n");
- return;
- }
-
- /* No accessory, reset everything and report removal */
- if (!(val & WM5100_ACCDET_STS)) {
- dev_dbg(wm5100->dev, "Jack removal detected\n");
- wm5100->jack_mic = false;
- wm5100->jack_detecting = true;
- wm5100->jack_flips = 0;
- snd_soc_jack_report(wm5100->jack, 0,
- SND_JACK_LINEOUT | SND_JACK_HEADSET |
- SND_JACK_BTN_0);
-
- regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1,
- WM5100_ACCDET_RATE_MASK,
- WM5100_ACCDET_RATE_MASK);
- return;
- }
-
- /* If the measurement is very high we've got a microphone,
- * either we just detected one or if we already reported then
- * we've got a button release event.
- */
- if (val & 0x400) {
- if (wm5100->jack_detecting) {
- dev_dbg(wm5100->dev, "Microphone detected\n");
- wm5100->jack_mic = true;
- wm5100->jack_detecting = false;
- snd_soc_jack_report(wm5100->jack,
- SND_JACK_HEADSET,
- SND_JACK_HEADSET | SND_JACK_BTN_0);
-
- /* Increase poll rate to give better responsiveness
- * for buttons */
- regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1,
- WM5100_ACCDET_RATE_MASK,
- 5 << WM5100_ACCDET_RATE_SHIFT);
- } else {
- dev_dbg(wm5100->dev, "Mic button up\n");
- snd_soc_jack_report(wm5100->jack, 0, SND_JACK_BTN_0);
- }
-
- return;
- }
-
- /* If we detected a lower impedence during initial startup
- * then we probably have the wrong polarity, flip it. Don't
- * do this for the lowest impedences to speed up detection of
- * plain headphones and give up if neither polarity looks
- * sensible.
- */
- if (wm5100->jack_detecting && (val & 0x3f8)) {
- wm5100->jack_flips++;
-
- if (wm5100->jack_flips > 1)
- wm5100_report_headphone(wm5100);
- else
- wm5100_set_detect_mode(wm5100, !wm5100->jack_mode);
-
- return;
- }
-
- /* Don't distinguish between buttons, just report any low
- * impedence as BTN_0.
- */
- if (val & 0x3fc) {
- if (wm5100->jack_mic) {
- dev_dbg(wm5100->dev, "Mic button detected\n");
- snd_soc_jack_report(wm5100->jack, SND_JACK_BTN_0,
- SND_JACK_BTN_0);
- } else if (wm5100->jack_detecting) {
- wm5100_report_headphone(wm5100);
- }
- }
-}
-
-int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
-{
- struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
-
- if (jack) {
- wm5100->jack = jack;
- wm5100->jack_detecting = true;
- wm5100->jack_flips = 0;
-
- wm5100_set_detect_mode(wm5100, 0);
-
- /* Slowest detection rate, gives debounce for initial
- * detection */
- snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
- WM5100_ACCDET_BIAS_STARTTIME_MASK |
- WM5100_ACCDET_RATE_MASK,
- (7 << WM5100_ACCDET_BIAS_STARTTIME_SHIFT) |
- WM5100_ACCDET_RATE_MASK);
-
- /* We need the charge pump to power MICBIAS */
- snd_soc_dapm_force_enable_pin(&codec->dapm, "CP2");
- snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK");
- snd_soc_dapm_sync(&codec->dapm);
-
- /* We start off just enabling microphone detection - even a
- * plain headphone will trigger detection.
- */
- snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
- WM5100_ACCDET_ENA, WM5100_ACCDET_ENA);
-
- snd_soc_update_bits(codec, WM5100_INTERRUPT_STATUS_3_MASK,
- WM5100_IM_ACCDET_EINT, 0);
- } else {
- snd_soc_update_bits(codec, WM5100_INTERRUPT_STATUS_3_MASK,
- WM5100_IM_HPDET_EINT |
- WM5100_IM_ACCDET_EINT,
- WM5100_IM_HPDET_EINT |
- WM5100_IM_ACCDET_EINT);
- snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
- WM5100_ACCDET_ENA, 0);
- wm5100->jack = NULL;
- }
-
- return 0;
-}
-
-static irqreturn_t wm5100_irq(int irq, void *data)
-{
- struct wm5100_priv *wm5100 = data;
- irqreturn_t status = IRQ_NONE;
- unsigned int irq_val, mask_val;
- int ret;
-
- ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_3, &irq_val);
- if (ret < 0) {
- dev_err(wm5100->dev, "Failed to read IRQ status 3: %d\n",
- ret);
- irq_val = 0;
- }
-
- ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_3_MASK,
- &mask_val);
- if (ret < 0) {
- dev_err(wm5100->dev, "Failed to read IRQ mask 3: %d\n",
- ret);
- mask_val = 0xffff;
- }
-
- irq_val &= ~mask_val;
-
- regmap_write(wm5100->regmap, WM5100_INTERRUPT_STATUS_3, irq_val);
-
- if (irq_val)
- status = IRQ_HANDLED;
-
- wm5100_log_status3(wm5100, irq_val);
-
- if (irq_val & WM5100_FLL1_LOCK_EINT) {
- dev_dbg(wm5100->dev, "FLL1 locked\n");
- complete(&wm5100->fll[0].lock);
- }
- if (irq_val & WM5100_FLL2_LOCK_EINT) {
- dev_dbg(wm5100->dev, "FLL2 locked\n");
- complete(&wm5100->fll[1].lock);
- }
-
- if (irq_val & WM5100_ACCDET_EINT)
- wm5100_micd_irq(wm5100);
-
- ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_4, &irq_val);
- if (ret < 0) {
- dev_err(wm5100->dev, "Failed to read IRQ status 4: %d\n",
- ret);
- irq_val = 0;
- }
-
- ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_4_MASK,
- &mask_val);
- if (ret < 0) {
- dev_err(wm5100->dev, "Failed to read IRQ mask 4: %d\n",
- ret);
- mask_val = 0xffff;
- }
-
- irq_val &= ~mask_val;
-
- if (irq_val)
- status = IRQ_HANDLED;
-
- regmap_write(wm5100->regmap, WM5100_INTERRUPT_STATUS_4, irq_val);
-
- wm5100_log_status4(wm5100, irq_val);
-
- return status;
-}
-
-static irqreturn_t wm5100_edge_irq(int irq, void *data)
-{
- irqreturn_t ret = IRQ_NONE;
- irqreturn_t val;
-
- do {
- val = wm5100_irq(irq, data);
- if (val != IRQ_NONE)
- ret = val;
- } while (val != IRQ_NONE);
-
- return ret;
-}
-
-#ifdef CONFIG_GPIOLIB
-static inline struct wm5100_priv *gpio_to_wm5100(struct gpio_chip *chip)
-{
- return container_of(chip, struct wm5100_priv, gpio_chip);
-}
-
-static void wm5100_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-{
- struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
-
- regmap_update_bits(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset,
- WM5100_GP1_LVL, !!value << WM5100_GP1_LVL_SHIFT);
-}
-
-static int wm5100_gpio_direction_out(struct gpio_chip *chip,
- unsigned offset, int value)
-{
- struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
- int val, ret;
-
- val = (1 << WM5100_GP1_FN_SHIFT) | (!!value << WM5100_GP1_LVL_SHIFT);
-
- ret = regmap_update_bits(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset,
- WM5100_GP1_FN_MASK | WM5100_GP1_DIR |
- WM5100_GP1_LVL, val);
- if (ret < 0)
- return ret;
- else
- return 0;
-}
-
-static int wm5100_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
- struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
- unsigned int reg;
- int ret;
-
- ret = regmap_read(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset, &reg);
- if (ret < 0)
- return ret;
-
- return (reg & WM5100_GP1_LVL) != 0;
-}
-
-static int wm5100_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
-{
- struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
-
- return regmap_update_bits(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset,
- WM5100_GP1_FN_MASK | WM5100_GP1_DIR,
- (1 << WM5100_GP1_FN_SHIFT) |
- (1 << WM5100_GP1_DIR_SHIFT));
-}
-
-static struct gpio_chip wm5100_template_chip = {
- .label = "wm5100",
- .owner = THIS_MODULE,
- .direction_output = wm5100_gpio_direction_out,
- .set = wm5100_gpio_set,
- .direction_input = wm5100_gpio_direction_in,
- .get = wm5100_gpio_get,
- .can_sleep = 1,
-};
-
-static void wm5100_init_gpio(struct i2c_client *i2c)
-{
- struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c);
- int ret;
-
- wm5100->gpio_chip = wm5100_template_chip;
- wm5100->gpio_chip.ngpio = 6;
- wm5100->gpio_chip.dev = &i2c->dev;
-
- if (wm5100->pdata.gpio_base)
- wm5100->gpio_chip.base = wm5100->pdata.gpio_base;
- else
- wm5100->gpio_chip.base = -1;
-
- ret = gpiochip_add(&wm5100->gpio_chip);
- if (ret != 0)
- dev_err(&i2c->dev, "Failed to add GPIOs: %d\n", ret);
-}
-
-static void wm5100_free_gpio(struct i2c_client *i2c)
-{
- struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c);
- int ret;
-
- ret = gpiochip_remove(&wm5100->gpio_chip);
- if (ret != 0)
- dev_err(&i2c->dev, "Failed to remove GPIOs: %d\n", ret);
-}
-#else
-static void wm5100_init_gpio(struct i2c_client *i2c)
-{
-}
-
-static void wm5100_free_gpio(struct i2c_client *i2c)
-{
-}
-#endif
-
-static int wm5100_probe(struct snd_soc_codec *codec)
-{
- struct i2c_client *i2c = to_i2c_client(codec->dev);
- struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
- int ret, i;
-
- wm5100->codec = codec;
- codec->control_data = wm5100->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++)
- snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU,
- WM5100_OUT_VU);
-
- /* Don't debounce interrupts to support use of SYSCLK only */
- snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_1, 0);
- snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_2, 0);
-
- /* TODO: check if we're symmetric */
-
- if (i2c->irq)
- snd_soc_dapm_new_controls(&codec->dapm,
- wm5100_dapm_widgets_noirq,
- ARRAY_SIZE(wm5100_dapm_widgets_noirq));
-
- if (wm5100->pdata.hp_pol) {
- ret = gpio_request_one(wm5100->pdata.hp_pol,
- GPIOF_OUT_INIT_HIGH, "WM5100 HP_POL");
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to request HP_POL %d: %d\n",
- wm5100->pdata.hp_pol, ret);
- goto err_gpio;
- }
- }
-
- return 0;
-
-err_gpio:
-
- return ret;
-}
-
-static int wm5100_remove(struct snd_soc_codec *codec)
-{
- struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
-
- if (wm5100->pdata.hp_pol) {
- gpio_free(wm5100->pdata.hp_pol);
- }
-
- return 0;
-}
-
-static int wm5100_soc_volatile(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- return true;
-}
-
-
-static struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
- .probe = wm5100_probe,
- .remove = wm5100_remove,
-
- .set_sysclk = wm5100_set_sysclk,
- .set_pll = wm5100_set_fll,
- .idle_bias_off = 1,
- .reg_cache_size = WM5100_MAX_REGISTER,
- .volatile_register = wm5100_soc_volatile,
-
- .seq_notifier = wm5100_seq_notifier,
- .controls = wm5100_snd_controls,
- .num_controls = ARRAY_SIZE(wm5100_snd_controls),
- .dapm_widgets = wm5100_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm5100_dapm_widgets),
- .dapm_routes = wm5100_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes),
-};
-
-static const struct regmap_config wm5100_regmap = {
- .reg_bits = 16,
- .val_bits = 16,
-
- .max_register = WM5100_MAX_REGISTER,
- .reg_defaults = wm5100_reg_defaults,
- .num_reg_defaults = ARRAY_SIZE(wm5100_reg_defaults),
- .volatile_reg = wm5100_volatile_register,
- .readable_reg = wm5100_readable_register,
- .cache_type = REGCACHE_RBTREE,
-};
-
-static const unsigned int wm5100_mic_ctrl_reg[] = {
- WM5100_IN1L_CONTROL,
- WM5100_IN2L_CONTROL,
- WM5100_IN3L_CONTROL,
- WM5100_IN4L_CONTROL,
-};
-
-static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev);
- struct wm5100_priv *wm5100;
- unsigned int reg;
- int ret, i, irq_flags;
-
- wm5100 = devm_kzalloc(&i2c->dev, sizeof(struct wm5100_priv),
- GFP_KERNEL);
- if (wm5100 == NULL)
- return -ENOMEM;
-
- wm5100->dev = &i2c->dev;
-
- wm5100->regmap = regmap_init_i2c(i2c, &wm5100_regmap);
- if (IS_ERR(wm5100->regmap)) {
- ret = PTR_ERR(wm5100->regmap);
- dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
- ret);
- goto err;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm5100->fll); i++)
- init_completion(&wm5100->fll[i].lock);
-
- if (pdata)
- wm5100->pdata = *pdata;
-
- i2c_set_clientdata(i2c, wm5100);
-
- for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++)
- wm5100->core_supplies[i].supply = wm5100_core_supply_names[i];
-
- ret = devm_regulator_bulk_get(&i2c->dev,
- ARRAY_SIZE(wm5100->core_supplies),
- wm5100->core_supplies);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to request core supplies: %d\n",
- ret);
- goto err_regmap;
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
- wm5100->core_supplies);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to enable core supplies: %d\n",
- ret);
- goto err_regmap;
- }
-
- if (wm5100->pdata.ldo_ena) {
- ret = gpio_request_one(wm5100->pdata.ldo_ena,
- GPIOF_OUT_INIT_HIGH, "WM5100 LDOENA");
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n",
- wm5100->pdata.ldo_ena, ret);
- goto err_enable;
- }
- msleep(2);
- }
-
- if (wm5100->pdata.reset) {
- ret = gpio_request_one(wm5100->pdata.reset,
- GPIOF_OUT_INIT_HIGH, "WM5100 /RESET");
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n",
- wm5100->pdata.reset, ret);
- goto err_ldo;
- }
- }
-
- ret = regmap_read(wm5100->regmap, WM5100_SOFTWARE_RESET, &reg);
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);
- goto err_reset;
- }
- switch (reg) {
- case 0x8997:
- case 0x5100:
- break;
-
- default:
- dev_err(&i2c->dev, "Device is not a WM5100, ID is %x\n", reg);
- ret = -EINVAL;
- goto err_reset;
- }
-
- ret = regmap_read(wm5100->regmap, WM5100_DEVICE_REVISION, &reg);
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to read revision register\n");
- goto err_reset;
- }
- wm5100->rev = reg & WM5100_DEVICE_REVISION_MASK;
-
- dev_info(&i2c->dev, "revision %c\n", wm5100->rev + 'A');
-
- ret = wm5100_reset(wm5100);
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to issue reset\n");
- goto err_reset;
- }
-
- switch (wm5100->rev) {
- case 0:
- ret = regmap_register_patch(wm5100->regmap,
- wm5100_reva_patches,
- ARRAY_SIZE(wm5100_reva_patches));
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to register patches: %d\n",
- ret);
- goto err_reset;
- }
- break;
- default:
- break;
- }
-
-
- wm5100_init_gpio(i2c);
-
- for (i = 0; i < ARRAY_SIZE(wm5100->pdata.gpio_defaults); i++) {
- if (!wm5100->pdata.gpio_defaults[i])
- continue;
-
- regmap_write(wm5100->regmap, WM5100_GPIO_CTRL_1 + i,
- wm5100->pdata.gpio_defaults[i]);
- }
-
- for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) {
- regmap_update_bits(wm5100->regmap, wm5100_mic_ctrl_reg[i],
- WM5100_IN1_MODE_MASK |
- WM5100_IN1_DMIC_SUP_MASK,
- (wm5100->pdata.in_mode[i] <<
- WM5100_IN1_MODE_SHIFT) |
- (wm5100->pdata.dmic_sup[i] <<
- WM5100_IN1_DMIC_SUP_SHIFT));
- }
-
- if (i2c->irq) {
- if (wm5100->pdata.irq_flags)
- irq_flags = wm5100->pdata.irq_flags;
- else
- irq_flags = IRQF_TRIGGER_LOW;
-
- irq_flags |= IRQF_ONESHOT;
-
- if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
- ret = request_threaded_irq(i2c->irq, NULL,
- wm5100_edge_irq, irq_flags,
- "wm5100", wm5100);
- else
- ret = request_threaded_irq(i2c->irq, NULL, wm5100_irq,
- irq_flags, "wm5100",
- wm5100);
-
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
- i2c->irq, ret);
- } else {
- /* Enable default interrupts */
- regmap_update_bits(wm5100->regmap,
- WM5100_INTERRUPT_STATUS_3_MASK,
- WM5100_IM_SPK_SHUTDOWN_WARN_EINT |
- WM5100_IM_SPK_SHUTDOWN_EINT |
- WM5100_IM_ASRC2_LOCK_EINT |
- WM5100_IM_ASRC1_LOCK_EINT |
- WM5100_IM_FLL2_LOCK_EINT |
- WM5100_IM_FLL1_LOCK_EINT |
- WM5100_CLKGEN_ERR_EINT |
- WM5100_CLKGEN_ERR_ASYNC_EINT, 0);
-
- regmap_update_bits(wm5100->regmap,
- WM5100_INTERRUPT_STATUS_4_MASK,
- WM5100_AIF3_ERR_EINT |
- WM5100_AIF2_ERR_EINT |
- WM5100_AIF1_ERR_EINT |
- WM5100_CTRLIF_ERR_EINT |
- WM5100_ISRC2_UNDERCLOCKED_EINT |
- WM5100_ISRC1_UNDERCLOCKED_EINT |
- WM5100_FX_UNDERCLOCKED_EINT |
- WM5100_AIF3_UNDERCLOCKED_EINT |
- WM5100_AIF2_UNDERCLOCKED_EINT |
- WM5100_AIF1_UNDERCLOCKED_EINT |
- WM5100_ASRC_UNDERCLOCKED_EINT |
- WM5100_DAC_UNDERCLOCKED_EINT |
- WM5100_ADC_UNDERCLOCKED_EINT |
- WM5100_MIXER_UNDERCLOCKED_EINT, 0);
- }
- }
-
- pm_runtime_set_active(&i2c->dev);
- pm_runtime_enable(&i2c->dev);
- pm_request_idle(&i2c->dev);
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm5100, wm5100_dai,
- ARRAY_SIZE(wm5100_dai));
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to register WM5100: %d\n", ret);
- goto err_reset;
- }
-
- return ret;
-
-err_reset:
- if (i2c->irq)
- free_irq(i2c->irq, wm5100);
- wm5100_free_gpio(i2c);
- if (wm5100->pdata.reset) {
- gpio_set_value_cansleep(wm5100->pdata.reset, 0);
- gpio_free(wm5100->pdata.reset);
- }
-err_ldo:
- if (wm5100->pdata.ldo_ena) {
- gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
- gpio_free(wm5100->pdata.ldo_ena);
- }
-err_enable:
- regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
- wm5100->core_supplies);
-err_regmap:
- regmap_exit(wm5100->regmap);
-err:
- return ret;
-}
-
-static __devexit int wm5100_i2c_remove(struct i2c_client *i2c)
-{
- struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c);
-
- snd_soc_unregister_codec(&i2c->dev);
- if (i2c->irq)
- free_irq(i2c->irq, wm5100);
- wm5100_free_gpio(i2c);
- if (wm5100->pdata.reset) {
- gpio_set_value_cansleep(wm5100->pdata.reset, 0);
- gpio_free(wm5100->pdata.reset);
- }
- if (wm5100->pdata.ldo_ena) {
- gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
- gpio_free(wm5100->pdata.ldo_ena);
- }
- regmap_exit(wm5100->regmap);
-
- return 0;
-}
-
-#ifdef CONFIG_PM_RUNTIME
-static int wm5100_runtime_suspend(struct device *dev)
-{
- struct wm5100_priv *wm5100 = dev_get_drvdata(dev);
-
- regcache_cache_only(wm5100->regmap, true);
- regcache_mark_dirty(wm5100->regmap);
- if (wm5100->pdata.ldo_ena)
- gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
- regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
- wm5100->core_supplies);
-
- return 0;
-}
-
-static int wm5100_runtime_resume(struct device *dev)
-{
- struct wm5100_priv *wm5100 = dev_get_drvdata(dev);
- int ret;
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
- wm5100->core_supplies);
- if (ret != 0) {
- dev_err(dev, "Failed to enable supplies: %d\n",
- ret);
- return ret;
- }
-
- if (wm5100->pdata.ldo_ena) {
- gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 1);
- msleep(2);
- }
-
- regcache_cache_only(wm5100->regmap, false);
- regcache_sync(wm5100->regmap);
-
- return 0;
-}
-#endif
-
-static struct dev_pm_ops wm5100_pm = {
- SET_RUNTIME_PM_OPS(wm5100_runtime_suspend, wm5100_runtime_resume,
- NULL)
-};
-
-static const struct i2c_device_id wm5100_i2c_id[] = {
- { "wm5100", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm5100_i2c_id);
-
-static struct i2c_driver wm5100_i2c_driver = {
- .driver = {
- .name = "wm5100",
- .owner = THIS_MODULE,
- .pm = &wm5100_pm,
- },
- .probe = wm5100_i2c_probe,
- .remove = __devexit_p(wm5100_i2c_remove),
- .id_table = wm5100_i2c_id,
-};
-
-static int __init wm5100_modinit(void)
-{
- return i2c_add_driver(&wm5100_i2c_driver);
-}
-module_init(wm5100_modinit);
-
-static void __exit wm5100_exit(void)
-{
- i2c_del_driver(&wm5100_i2c_driver);
-}
-module_exit(wm5100_exit);
-
-MODULE_DESCRIPTION("ASoC WM5100 driver");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm5100.h b/ANDROID_3.4.5/sound/soc/codecs/wm5100.h
deleted file mode 100644
index 25cb6016..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm5100.h
+++ /dev/null
@@ -1,5156 +0,0 @@
-/*
- * wm5100.h -- WM5100 ALSA SoC Audio driver
- *
- * Copyright 2011 Wolfson Microelectronics plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef WM5100_ASOC_H
-#define WM5100_ASOC_H
-
-#include <sound/soc.h>
-#include <linux/regmap.h>
-
-int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
-
-#define WM5100_CLK_AIF1 1
-#define WM5100_CLK_AIF2 2
-#define WM5100_CLK_AIF3 3
-#define WM5100_CLK_SYSCLK 4
-#define WM5100_CLK_ASYNCCLK 5
-#define WM5100_CLK_32KHZ 6
-#define WM5100_CLK_OPCLK 7
-
-#define WM5100_CLKSRC_MCLK1 0
-#define WM5100_CLKSRC_MCLK2 1
-#define WM5100_CLKSRC_SYSCLK 2
-#define WM5100_CLKSRC_FLL1 4
-#define WM5100_CLKSRC_FLL2 5
-#define WM5100_CLKSRC_AIF1BCLK 8
-#define WM5100_CLKSRC_AIF2BCLK 9
-#define WM5100_CLKSRC_AIF3BCLK 10
-#define WM5100_CLKSRC_ASYNCCLK 0x100
-
-#define WM5100_FLL1 1
-#define WM5100_FLL2 2
-
-#define WM5100_FLL_SRC_MCLK1 0x0
-#define WM5100_FLL_SRC_MCLK2 0x1
-#define WM5100_FLL_SRC_FLL1 0x4
-#define WM5100_FLL_SRC_FLL2 0x5
-#define WM5100_FLL_SRC_AIF1BCLK 0x8
-#define WM5100_FLL_SRC_AIF2BCLK 0x9
-#define WM5100_FLL_SRC_AIF3BCLK 0xa
-
-/*
- * Register values.
- */
-#define WM5100_SOFTWARE_RESET 0x00
-#define WM5100_DEVICE_REVISION 0x01
-#define WM5100_CTRL_IF_1 0x10
-#define WM5100_TONE_GENERATOR_1 0x20
-#define WM5100_PWM_DRIVE_1 0x30
-#define WM5100_PWM_DRIVE_2 0x31
-#define WM5100_PWM_DRIVE_3 0x32
-#define WM5100_CLOCKING_1 0x100
-#define WM5100_CLOCKING_3 0x101
-#define WM5100_CLOCKING_4 0x102
-#define WM5100_CLOCKING_5 0x103
-#define WM5100_CLOCKING_6 0x104
-#define WM5100_CLOCKING_7 0x107
-#define WM5100_CLOCKING_8 0x108
-#define WM5100_ASRC_ENABLE 0x120
-#define WM5100_ASRC_STATUS 0x121
-#define WM5100_ASRC_RATE1 0x122
-#define WM5100_ISRC_1_CTRL_1 0x141
-#define WM5100_ISRC_1_CTRL_2 0x142
-#define WM5100_ISRC_2_CTRL1 0x143
-#define WM5100_ISRC_2_CTRL_2 0x144
-#define WM5100_FLL1_CONTROL_1 0x182
-#define WM5100_FLL1_CONTROL_2 0x183
-#define WM5100_FLL1_CONTROL_3 0x184
-#define WM5100_FLL1_CONTROL_5 0x186
-#define WM5100_FLL1_CONTROL_6 0x187
-#define WM5100_FLL1_EFS_1 0x188
-#define WM5100_FLL2_CONTROL_1 0x1A2
-#define WM5100_FLL2_CONTROL_2 0x1A3
-#define WM5100_FLL2_CONTROL_3 0x1A4
-#define WM5100_FLL2_CONTROL_5 0x1A6
-#define WM5100_FLL2_CONTROL_6 0x1A7
-#define WM5100_FLL2_EFS_1 0x1A8
-#define WM5100_MIC_CHARGE_PUMP_1 0x200
-#define WM5100_MIC_CHARGE_PUMP_2 0x201
-#define WM5100_HP_CHARGE_PUMP_1 0x202
-#define WM5100_LDO1_CONTROL 0x211
-#define WM5100_MIC_BIAS_CTRL_1 0x215
-#define WM5100_MIC_BIAS_CTRL_2 0x216
-#define WM5100_MIC_BIAS_CTRL_3 0x217
-#define WM5100_ACCESSORY_DETECT_MODE_1 0x280
-#define WM5100_HEADPHONE_DETECT_1 0x288
-#define WM5100_HEADPHONE_DETECT_2 0x289
-#define WM5100_MIC_DETECT_1 0x290
-#define WM5100_MIC_DETECT_2 0x291
-#define WM5100_MIC_DETECT_3 0x292
-#define WM5100_MISC_CONTROL 0x2BB
-#define WM5100_INPUT_ENABLES 0x301
-#define WM5100_INPUT_ENABLES_STATUS 0x302
-#define WM5100_IN1L_CONTROL 0x310
-#define WM5100_IN1R_CONTROL 0x311
-#define WM5100_IN2L_CONTROL 0x312
-#define WM5100_IN2R_CONTROL 0x313
-#define WM5100_IN3L_CONTROL 0x314
-#define WM5100_IN3R_CONTROL 0x315
-#define WM5100_IN4L_CONTROL 0x316
-#define WM5100_IN4R_CONTROL 0x317
-#define WM5100_RXANC_SRC 0x318
-#define WM5100_INPUT_VOLUME_RAMP 0x319
-#define WM5100_ADC_DIGITAL_VOLUME_1L 0x320
-#define WM5100_ADC_DIGITAL_VOLUME_1R 0x321
-#define WM5100_ADC_DIGITAL_VOLUME_2L 0x322
-#define WM5100_ADC_DIGITAL_VOLUME_2R 0x323
-#define WM5100_ADC_DIGITAL_VOLUME_3L 0x324
-#define WM5100_ADC_DIGITAL_VOLUME_3R 0x325
-#define WM5100_ADC_DIGITAL_VOLUME_4L 0x326
-#define WM5100_ADC_DIGITAL_VOLUME_4R 0x327
-#define WM5100_OUTPUT_ENABLES_2 0x401
-#define WM5100_OUTPUT_STATUS_1 0x402
-#define WM5100_OUTPUT_STATUS_2 0x403
-#define WM5100_CHANNEL_ENABLES_1 0x408
-#define WM5100_OUT_VOLUME_1L 0x410
-#define WM5100_OUT_VOLUME_1R 0x411
-#define WM5100_DAC_VOLUME_LIMIT_1L 0x412
-#define WM5100_DAC_VOLUME_LIMIT_1R 0x413
-#define WM5100_OUT_VOLUME_2L 0x414
-#define WM5100_OUT_VOLUME_2R 0x415
-#define WM5100_DAC_VOLUME_LIMIT_2L 0x416
-#define WM5100_DAC_VOLUME_LIMIT_2R 0x417
-#define WM5100_OUT_VOLUME_3L 0x418
-#define WM5100_OUT_VOLUME_3R 0x419
-#define WM5100_DAC_VOLUME_LIMIT_3L 0x41A
-#define WM5100_DAC_VOLUME_LIMIT_3R 0x41B
-#define WM5100_OUT_VOLUME_4L 0x41C
-#define WM5100_OUT_VOLUME_4R 0x41D
-#define WM5100_DAC_VOLUME_LIMIT_5L 0x41E
-#define WM5100_DAC_VOLUME_LIMIT_5R 0x41F
-#define WM5100_DAC_VOLUME_LIMIT_6L 0x420
-#define WM5100_DAC_VOLUME_LIMIT_6R 0x421
-#define WM5100_DAC_AEC_CONTROL_1 0x440
-#define WM5100_OUTPUT_VOLUME_RAMP 0x441
-#define WM5100_DAC_DIGITAL_VOLUME_1L 0x480
-#define WM5100_DAC_DIGITAL_VOLUME_1R 0x481
-#define WM5100_DAC_DIGITAL_VOLUME_2L 0x482
-#define WM5100_DAC_DIGITAL_VOLUME_2R 0x483
-#define WM5100_DAC_DIGITAL_VOLUME_3L 0x484
-#define WM5100_DAC_DIGITAL_VOLUME_3R 0x485
-#define WM5100_DAC_DIGITAL_VOLUME_4L 0x486
-#define WM5100_DAC_DIGITAL_VOLUME_4R 0x487
-#define WM5100_DAC_DIGITAL_VOLUME_5L 0x488
-#define WM5100_DAC_DIGITAL_VOLUME_5R 0x489
-#define WM5100_DAC_DIGITAL_VOLUME_6L 0x48A
-#define WM5100_DAC_DIGITAL_VOLUME_6R 0x48B
-#define WM5100_PDM_SPK1_CTRL_1 0x4C0
-#define WM5100_PDM_SPK1_CTRL_2 0x4C1
-#define WM5100_PDM_SPK2_CTRL_1 0x4C2
-#define WM5100_PDM_SPK2_CTRL_2 0x4C3
-#define WM5100_AUDIO_IF_1_1 0x500
-#define WM5100_AUDIO_IF_1_2 0x501
-#define WM5100_AUDIO_IF_1_3 0x502
-#define WM5100_AUDIO_IF_1_4 0x503
-#define WM5100_AUDIO_IF_1_5 0x504
-#define WM5100_AUDIO_IF_1_6 0x505
-#define WM5100_AUDIO_IF_1_7 0x506
-#define WM5100_AUDIO_IF_1_8 0x507
-#define WM5100_AUDIO_IF_1_9 0x508
-#define WM5100_AUDIO_IF_1_10 0x509
-#define WM5100_AUDIO_IF_1_11 0x50A
-#define WM5100_AUDIO_IF_1_12 0x50B
-#define WM5100_AUDIO_IF_1_13 0x50C
-#define WM5100_AUDIO_IF_1_14 0x50D
-#define WM5100_AUDIO_IF_1_15 0x50E
-#define WM5100_AUDIO_IF_1_16 0x50F
-#define WM5100_AUDIO_IF_1_17 0x510
-#define WM5100_AUDIO_IF_1_18 0x511
-#define WM5100_AUDIO_IF_1_19 0x512
-#define WM5100_AUDIO_IF_1_20 0x513
-#define WM5100_AUDIO_IF_1_21 0x514
-#define WM5100_AUDIO_IF_1_22 0x515
-#define WM5100_AUDIO_IF_1_23 0x516
-#define WM5100_AUDIO_IF_1_24 0x517
-#define WM5100_AUDIO_IF_1_25 0x518
-#define WM5100_AUDIO_IF_1_26 0x519
-#define WM5100_AUDIO_IF_1_27 0x51A
-#define WM5100_AUDIO_IF_2_1 0x540
-#define WM5100_AUDIO_IF_2_2 0x541
-#define WM5100_AUDIO_IF_2_3 0x542
-#define WM5100_AUDIO_IF_2_4 0x543
-#define WM5100_AUDIO_IF_2_5 0x544
-#define WM5100_AUDIO_IF_2_6 0x545
-#define WM5100_AUDIO_IF_2_7 0x546
-#define WM5100_AUDIO_IF_2_8 0x547
-#define WM5100_AUDIO_IF_2_9 0x548
-#define WM5100_AUDIO_IF_2_10 0x549
-#define WM5100_AUDIO_IF_2_11 0x54A
-#define WM5100_AUDIO_IF_2_18 0x551
-#define WM5100_AUDIO_IF_2_19 0x552
-#define WM5100_AUDIO_IF_2_26 0x559
-#define WM5100_AUDIO_IF_2_27 0x55A
-#define WM5100_AUDIO_IF_3_1 0x580
-#define WM5100_AUDIO_IF_3_2 0x581
-#define WM5100_AUDIO_IF_3_3 0x582
-#define WM5100_AUDIO_IF_3_4 0x583
-#define WM5100_AUDIO_IF_3_5 0x584
-#define WM5100_AUDIO_IF_3_6 0x585
-#define WM5100_AUDIO_IF_3_7 0x586
-#define WM5100_AUDIO_IF_3_8 0x587
-#define WM5100_AUDIO_IF_3_9 0x588
-#define WM5100_AUDIO_IF_3_10 0x589
-#define WM5100_AUDIO_IF_3_11 0x58A
-#define WM5100_AUDIO_IF_3_18 0x591
-#define WM5100_AUDIO_IF_3_19 0x592
-#define WM5100_AUDIO_IF_3_26 0x599
-#define WM5100_AUDIO_IF_3_27 0x59A
-#define WM5100_PWM1MIX_INPUT_1_SOURCE 0x640
-#define WM5100_PWM1MIX_INPUT_1_VOLUME 0x641
-#define WM5100_PWM1MIX_INPUT_2_SOURCE 0x642
-#define WM5100_PWM1MIX_INPUT_2_VOLUME 0x643
-#define WM5100_PWM1MIX_INPUT_3_SOURCE 0x644
-#define WM5100_PWM1MIX_INPUT_3_VOLUME 0x645
-#define WM5100_PWM1MIX_INPUT_4_SOURCE 0x646
-#define WM5100_PWM1MIX_INPUT_4_VOLUME 0x647
-#define WM5100_PWM2MIX_INPUT_1_SOURCE 0x648
-#define WM5100_PWM2MIX_INPUT_1_VOLUME 0x649
-#define WM5100_PWM2MIX_INPUT_2_SOURCE 0x64A
-#define WM5100_PWM2MIX_INPUT_2_VOLUME 0x64B
-#define WM5100_PWM2MIX_INPUT_3_SOURCE 0x64C
-#define WM5100_PWM2MIX_INPUT_3_VOLUME 0x64D
-#define WM5100_PWM2MIX_INPUT_4_SOURCE 0x64E
-#define WM5100_PWM2MIX_INPUT_4_VOLUME 0x64F
-#define WM5100_OUT1LMIX_INPUT_1_SOURCE 0x680
-#define WM5100_OUT1LMIX_INPUT_1_VOLUME 0x681
-#define WM5100_OUT1LMIX_INPUT_2_SOURCE 0x682
-#define WM5100_OUT1LMIX_INPUT_2_VOLUME 0x683
-#define WM5100_OUT1LMIX_INPUT_3_SOURCE 0x684
-#define WM5100_OUT1LMIX_INPUT_3_VOLUME 0x685
-#define WM5100_OUT1LMIX_INPUT_4_SOURCE 0x686
-#define WM5100_OUT1LMIX_INPUT_4_VOLUME 0x687
-#define WM5100_OUT1RMIX_INPUT_1_SOURCE 0x688
-#define WM5100_OUT1RMIX_INPUT_1_VOLUME 0x689
-#define WM5100_OUT1RMIX_INPUT_2_SOURCE 0x68A
-#define WM5100_OUT1RMIX_INPUT_2_VOLUME 0x68B
-#define WM5100_OUT1RMIX_INPUT_3_SOURCE 0x68C
-#define WM5100_OUT1RMIX_INPUT_3_VOLUME 0x68D
-#define WM5100_OUT1RMIX_INPUT_4_SOURCE 0x68E
-#define WM5100_OUT1RMIX_INPUT_4_VOLUME 0x68F
-#define WM5100_OUT2LMIX_INPUT_1_SOURCE 0x690
-#define WM5100_OUT2LMIX_INPUT_1_VOLUME 0x691
-#define WM5100_OUT2LMIX_INPUT_2_SOURCE 0x692
-#define WM5100_OUT2LMIX_INPUT_2_VOLUME 0x693
-#define WM5100_OUT2LMIX_INPUT_3_SOURCE 0x694
-#define WM5100_OUT2LMIX_INPUT_3_VOLUME 0x695
-#define WM5100_OUT2LMIX_INPUT_4_SOURCE 0x696
-#define WM5100_OUT2LMIX_INPUT_4_VOLUME 0x697
-#define WM5100_OUT2RMIX_INPUT_1_SOURCE 0x698
-#define WM5100_OUT2RMIX_INPUT_1_VOLUME 0x699
-#define WM5100_OUT2RMIX_INPUT_2_SOURCE 0x69A
-#define WM5100_OUT2RMIX_INPUT_2_VOLUME 0x69B
-#define WM5100_OUT2RMIX_INPUT_3_SOURCE 0x69C
-#define WM5100_OUT2RMIX_INPUT_3_VOLUME 0x69D
-#define WM5100_OUT2RMIX_INPUT_4_SOURCE 0x69E
-#define WM5100_OUT2RMIX_INPUT_4_VOLUME 0x69F
-#define WM5100_OUT3LMIX_INPUT_1_SOURCE 0x6A0
-#define WM5100_OUT3LMIX_INPUT_1_VOLUME 0x6A1
-#define WM5100_OUT3LMIX_INPUT_2_SOURCE 0x6A2
-#define WM5100_OUT3LMIX_INPUT_2_VOLUME 0x6A3
-#define WM5100_OUT3LMIX_INPUT_3_SOURCE 0x6A4
-#define WM5100_OUT3LMIX_INPUT_3_VOLUME 0x6A5
-#define WM5100_OUT3LMIX_INPUT_4_SOURCE 0x6A6
-#define WM5100_OUT3LMIX_INPUT_4_VOLUME 0x6A7
-#define WM5100_OUT3RMIX_INPUT_1_SOURCE 0x6A8
-#define WM5100_OUT3RMIX_INPUT_1_VOLUME 0x6A9
-#define WM5100_OUT3RMIX_INPUT_2_SOURCE 0x6AA
-#define WM5100_OUT3RMIX_INPUT_2_VOLUME 0x6AB
-#define WM5100_OUT3RMIX_INPUT_3_SOURCE 0x6AC
-#define WM5100_OUT3RMIX_INPUT_3_VOLUME 0x6AD
-#define WM5100_OUT3RMIX_INPUT_4_SOURCE 0x6AE
-#define WM5100_OUT3RMIX_INPUT_4_VOLUME 0x6AF
-#define WM5100_OUT4LMIX_INPUT_1_SOURCE 0x6B0
-#define WM5100_OUT4LMIX_INPUT_1_VOLUME 0x6B1
-#define WM5100_OUT4LMIX_INPUT_2_SOURCE 0x6B2
-#define WM5100_OUT4LMIX_INPUT_2_VOLUME 0x6B3
-#define WM5100_OUT4LMIX_INPUT_3_SOURCE 0x6B4
-#define WM5100_OUT4LMIX_INPUT_3_VOLUME 0x6B5
-#define WM5100_OUT4LMIX_INPUT_4_SOURCE 0x6B6
-#define WM5100_OUT4LMIX_INPUT_4_VOLUME 0x6B7
-#define WM5100_OUT4RMIX_INPUT_1_SOURCE 0x6B8
-#define WM5100_OUT4RMIX_INPUT_1_VOLUME 0x6B9
-#define WM5100_OUT4RMIX_INPUT_2_SOURCE 0x6BA
-#define WM5100_OUT4RMIX_INPUT_2_VOLUME 0x6BB
-#define WM5100_OUT4RMIX_INPUT_3_SOURCE 0x6BC
-#define WM5100_OUT4RMIX_INPUT_3_VOLUME 0x6BD
-#define WM5100_OUT4RMIX_INPUT_4_SOURCE 0x6BE
-#define WM5100_OUT4RMIX_INPUT_4_VOLUME 0x6BF
-#define WM5100_OUT5LMIX_INPUT_1_SOURCE 0x6C0
-#define WM5100_OUT5LMIX_INPUT_1_VOLUME 0x6C1
-#define WM5100_OUT5LMIX_INPUT_2_SOURCE 0x6C2
-#define WM5100_OUT5LMIX_INPUT_2_VOLUME 0x6C3
-#define WM5100_OUT5LMIX_INPUT_3_SOURCE 0x6C4
-#define WM5100_OUT5LMIX_INPUT_3_VOLUME 0x6C5
-#define WM5100_OUT5LMIX_INPUT_4_SOURCE 0x6C6
-#define WM5100_OUT5LMIX_INPUT_4_VOLUME 0x6C7
-#define WM5100_OUT5RMIX_INPUT_1_SOURCE 0x6C8
-#define WM5100_OUT5RMIX_INPUT_1_VOLUME 0x6C9
-#define WM5100_OUT5RMIX_INPUT_2_SOURCE 0x6CA
-#define WM5100_OUT5RMIX_INPUT_2_VOLUME 0x6CB
-#define WM5100_OUT5RMIX_INPUT_3_SOURCE 0x6CC
-#define WM5100_OUT5RMIX_INPUT_3_VOLUME 0x6CD
-#define WM5100_OUT5RMIX_INPUT_4_SOURCE 0x6CE
-#define WM5100_OUT5RMIX_INPUT_4_VOLUME 0x6CF
-#define WM5100_OUT6LMIX_INPUT_1_SOURCE 0x6D0
-#define WM5100_OUT6LMIX_INPUT_1_VOLUME 0x6D1
-#define WM5100_OUT6LMIX_INPUT_2_SOURCE 0x6D2
-#define WM5100_OUT6LMIX_INPUT_2_VOLUME 0x6D3
-#define WM5100_OUT6LMIX_INPUT_3_SOURCE 0x6D4
-#define WM5100_OUT6LMIX_INPUT_3_VOLUME 0x6D5
-#define WM5100_OUT6LMIX_INPUT_4_SOURCE 0x6D6
-#define WM5100_OUT6LMIX_INPUT_4_VOLUME 0x6D7
-#define WM5100_OUT6RMIX_INPUT_1_SOURCE 0x6D8
-#define WM5100_OUT6RMIX_INPUT_1_VOLUME 0x6D9
-#define WM5100_OUT6RMIX_INPUT_2_SOURCE 0x6DA
-#define WM5100_OUT6RMIX_INPUT_2_VOLUME 0x6DB
-#define WM5100_OUT6RMIX_INPUT_3_SOURCE 0x6DC
-#define WM5100_OUT6RMIX_INPUT_3_VOLUME 0x6DD
-#define WM5100_OUT6RMIX_INPUT_4_SOURCE 0x6DE
-#define WM5100_OUT6RMIX_INPUT_4_VOLUME 0x6DF
-#define WM5100_AIF1TX1MIX_INPUT_1_SOURCE 0x700
-#define WM5100_AIF1TX1MIX_INPUT_1_VOLUME 0x701
-#define WM5100_AIF1TX1MIX_INPUT_2_SOURCE 0x702
-#define WM5100_AIF1TX1MIX_INPUT_2_VOLUME 0x703
-#define WM5100_AIF1TX1MIX_INPUT_3_SOURCE 0x704
-#define WM5100_AIF1TX1MIX_INPUT_3_VOLUME 0x705
-#define WM5100_AIF1TX1MIX_INPUT_4_SOURCE 0x706
-#define WM5100_AIF1TX1MIX_INPUT_4_VOLUME 0x707
-#define WM5100_AIF1TX2MIX_INPUT_1_SOURCE 0x708
-#define WM5100_AIF1TX2MIX_INPUT_1_VOLUME 0x709
-#define WM5100_AIF1TX2MIX_INPUT_2_SOURCE 0x70A
-#define WM5100_AIF1TX2MIX_INPUT_2_VOLUME 0x70B
-#define WM5100_AIF1TX2MIX_INPUT_3_SOURCE 0x70C
-#define WM5100_AIF1TX2MIX_INPUT_3_VOLUME 0x70D
-#define WM5100_AIF1TX2MIX_INPUT_4_SOURCE 0x70E
-#define WM5100_AIF1TX2MIX_INPUT_4_VOLUME 0x70F
-#define WM5100_AIF1TX3MIX_INPUT_1_SOURCE 0x710
-#define WM5100_AIF1TX3MIX_INPUT_1_VOLUME 0x711
-#define WM5100_AIF1TX3MIX_INPUT_2_SOURCE 0x712
-#define WM5100_AIF1TX3MIX_INPUT_2_VOLUME 0x713
-#define WM5100_AIF1TX3MIX_INPUT_3_SOURCE 0x714
-#define WM5100_AIF1TX3MIX_INPUT_3_VOLUME 0x715
-#define WM5100_AIF1TX3MIX_INPUT_4_SOURCE 0x716
-#define WM5100_AIF1TX3MIX_INPUT_4_VOLUME 0x717
-#define WM5100_AIF1TX4MIX_INPUT_1_SOURCE 0x718
-#define WM5100_AIF1TX4MIX_INPUT_1_VOLUME 0x719
-#define WM5100_AIF1TX4MIX_INPUT_2_SOURCE 0x71A
-#define WM5100_AIF1TX4MIX_INPUT_2_VOLUME 0x71B
-#define WM5100_AIF1TX4MIX_INPUT_3_SOURCE 0x71C
-#define WM5100_AIF1TX4MIX_INPUT_3_VOLUME 0x71D
-#define WM5100_AIF1TX4MIX_INPUT_4_SOURCE 0x71E
-#define WM5100_AIF1TX4MIX_INPUT_4_VOLUME 0x71F
-#define WM5100_AIF1TX5MIX_INPUT_1_SOURCE 0x720
-#define WM5100_AIF1TX5MIX_INPUT_1_VOLUME 0x721
-#define WM5100_AIF1TX5MIX_INPUT_2_SOURCE 0x722
-#define WM5100_AIF1TX5MIX_INPUT_2_VOLUME 0x723
-#define WM5100_AIF1TX5MIX_INPUT_3_SOURCE 0x724
-#define WM5100_AIF1TX5MIX_INPUT_3_VOLUME 0x725
-#define WM5100_AIF1TX5MIX_INPUT_4_SOURCE 0x726
-#define WM5100_AIF1TX5MIX_INPUT_4_VOLUME 0x727
-#define WM5100_AIF1TX6MIX_INPUT_1_SOURCE 0x728
-#define WM5100_AIF1TX6MIX_INPUT_1_VOLUME 0x729
-#define WM5100_AIF1TX6MIX_INPUT_2_SOURCE 0x72A
-#define WM5100_AIF1TX6MIX_INPUT_2_VOLUME 0x72B
-#define WM5100_AIF1TX6MIX_INPUT_3_SOURCE 0x72C
-#define WM5100_AIF1TX6MIX_INPUT_3_VOLUME 0x72D
-#define WM5100_AIF1TX6MIX_INPUT_4_SOURCE 0x72E
-#define WM5100_AIF1TX6MIX_INPUT_4_VOLUME 0x72F
-#define WM5100_AIF1TX7MIX_INPUT_1_SOURCE 0x730
-#define WM5100_AIF1TX7MIX_INPUT_1_VOLUME 0x731
-#define WM5100_AIF1TX7MIX_INPUT_2_SOURCE 0x732
-#define WM5100_AIF1TX7MIX_INPUT_2_VOLUME 0x733
-#define WM5100_AIF1TX7MIX_INPUT_3_SOURCE 0x734
-#define WM5100_AIF1TX7MIX_INPUT_3_VOLUME 0x735
-#define WM5100_AIF1TX7MIX_INPUT_4_SOURCE 0x736
-#define WM5100_AIF1TX7MIX_INPUT_4_VOLUME 0x737
-#define WM5100_AIF1TX8MIX_INPUT_1_SOURCE 0x738
-#define WM5100_AIF1TX8MIX_INPUT_1_VOLUME 0x739
-#define WM5100_AIF1TX8MIX_INPUT_2_SOURCE 0x73A
-#define WM5100_AIF1TX8MIX_INPUT_2_VOLUME 0x73B
-#define WM5100_AIF1TX8MIX_INPUT_3_SOURCE 0x73C
-#define WM5100_AIF1TX8MIX_INPUT_3_VOLUME 0x73D
-#define WM5100_AIF1TX8MIX_INPUT_4_SOURCE 0x73E
-#define WM5100_AIF1TX8MIX_INPUT_4_VOLUME 0x73F
-#define WM5100_AIF2TX1MIX_INPUT_1_SOURCE 0x740
-#define WM5100_AIF2TX1MIX_INPUT_1_VOLUME 0x741
-#define WM5100_AIF2TX1MIX_INPUT_2_SOURCE 0x742
-#define WM5100_AIF2TX1MIX_INPUT_2_VOLUME 0x743
-#define WM5100_AIF2TX1MIX_INPUT_3_SOURCE 0x744
-#define WM5100_AIF2TX1MIX_INPUT_3_VOLUME 0x745
-#define WM5100_AIF2TX1MIX_INPUT_4_SOURCE 0x746
-#define WM5100_AIF2TX1MIX_INPUT_4_VOLUME 0x747
-#define WM5100_AIF2TX2MIX_INPUT_1_SOURCE 0x748
-#define WM5100_AIF2TX2MIX_INPUT_1_VOLUME 0x749
-#define WM5100_AIF2TX2MIX_INPUT_2_SOURCE 0x74A
-#define WM5100_AIF2TX2MIX_INPUT_2_VOLUME 0x74B
-#define WM5100_AIF2TX2MIX_INPUT_3_SOURCE 0x74C
-#define WM5100_AIF2TX2MIX_INPUT_3_VOLUME 0x74D
-#define WM5100_AIF2TX2MIX_INPUT_4_SOURCE 0x74E
-#define WM5100_AIF2TX2MIX_INPUT_4_VOLUME 0x74F
-#define WM5100_AIF3TX1MIX_INPUT_1_SOURCE 0x780
-#define WM5100_AIF3TX1MIX_INPUT_1_VOLUME 0x781
-#define WM5100_AIF3TX1MIX_INPUT_2_SOURCE 0x782
-#define WM5100_AIF3TX1MIX_INPUT_2_VOLUME 0x783
-#define WM5100_AIF3TX1MIX_INPUT_3_SOURCE 0x784
-#define WM5100_AIF3TX1MIX_INPUT_3_VOLUME 0x785
-#define WM5100_AIF3TX1MIX_INPUT_4_SOURCE 0x786
-#define WM5100_AIF3TX1MIX_INPUT_4_VOLUME 0x787
-#define WM5100_AIF3TX2MIX_INPUT_1_SOURCE 0x788
-#define WM5100_AIF3TX2MIX_INPUT_1_VOLUME 0x789
-#define WM5100_AIF3TX2MIX_INPUT_2_SOURCE 0x78A
-#define WM5100_AIF3TX2MIX_INPUT_2_VOLUME 0x78B
-#define WM5100_AIF3TX2MIX_INPUT_3_SOURCE 0x78C
-#define WM5100_AIF3TX2MIX_INPUT_3_VOLUME 0x78D
-#define WM5100_AIF3TX2MIX_INPUT_4_SOURCE 0x78E
-#define WM5100_AIF3TX2MIX_INPUT_4_VOLUME 0x78F
-#define WM5100_EQ1MIX_INPUT_1_SOURCE 0x880
-#define WM5100_EQ1MIX_INPUT_1_VOLUME 0x881
-#define WM5100_EQ1MIX_INPUT_2_SOURCE 0x882
-#define WM5100_EQ1MIX_INPUT_2_VOLUME 0x883
-#define WM5100_EQ1MIX_INPUT_3_SOURCE 0x884
-#define WM5100_EQ1MIX_INPUT_3_VOLUME 0x885
-#define WM5100_EQ1MIX_INPUT_4_SOURCE 0x886
-#define WM5100_EQ1MIX_INPUT_4_VOLUME 0x887
-#define WM5100_EQ2MIX_INPUT_1_SOURCE 0x888
-#define WM5100_EQ2MIX_INPUT_1_VOLUME 0x889
-#define WM5100_EQ2MIX_INPUT_2_SOURCE 0x88A
-#define WM5100_EQ2MIX_INPUT_2_VOLUME 0x88B
-#define WM5100_EQ2MIX_INPUT_3_SOURCE 0x88C
-#define WM5100_EQ2MIX_INPUT_3_VOLUME 0x88D
-#define WM5100_EQ2MIX_INPUT_4_SOURCE 0x88E
-#define WM5100_EQ2MIX_INPUT_4_VOLUME 0x88F
-#define WM5100_EQ3MIX_INPUT_1_SOURCE 0x890
-#define WM5100_EQ3MIX_INPUT_1_VOLUME 0x891
-#define WM5100_EQ3MIX_INPUT_2_SOURCE 0x892
-#define WM5100_EQ3MIX_INPUT_2_VOLUME 0x893
-#define WM5100_EQ3MIX_INPUT_3_SOURCE 0x894
-#define WM5100_EQ3MIX_INPUT_3_VOLUME 0x895
-#define WM5100_EQ3MIX_INPUT_4_SOURCE 0x896
-#define WM5100_EQ3MIX_INPUT_4_VOLUME 0x897
-#define WM5100_EQ4MIX_INPUT_1_SOURCE 0x898
-#define WM5100_EQ4MIX_INPUT_1_VOLUME 0x899
-#define WM5100_EQ4MIX_INPUT_2_SOURCE 0x89A
-#define WM5100_EQ4MIX_INPUT_2_VOLUME 0x89B
-#define WM5100_EQ4MIX_INPUT_3_SOURCE 0x89C
-#define WM5100_EQ4MIX_INPUT_3_VOLUME 0x89D
-#define WM5100_EQ4MIX_INPUT_4_SOURCE 0x89E
-#define WM5100_EQ4MIX_INPUT_4_VOLUME 0x89F
-#define WM5100_DRC1LMIX_INPUT_1_SOURCE 0x8C0
-#define WM5100_DRC1LMIX_INPUT_1_VOLUME 0x8C1
-#define WM5100_DRC1LMIX_INPUT_2_SOURCE 0x8C2
-#define WM5100_DRC1LMIX_INPUT_2_VOLUME 0x8C3
-#define WM5100_DRC1LMIX_INPUT_3_SOURCE 0x8C4
-#define WM5100_DRC1LMIX_INPUT_3_VOLUME 0x8C5
-#define WM5100_DRC1LMIX_INPUT_4_SOURCE 0x8C6
-#define WM5100_DRC1LMIX_INPUT_4_VOLUME 0x8C7
-#define WM5100_DRC1RMIX_INPUT_1_SOURCE 0x8C8
-#define WM5100_DRC1RMIX_INPUT_1_VOLUME 0x8C9
-#define WM5100_DRC1RMIX_INPUT_2_SOURCE 0x8CA
-#define WM5100_DRC1RMIX_INPUT_2_VOLUME 0x8CB
-#define WM5100_DRC1RMIX_INPUT_3_SOURCE 0x8CC
-#define WM5100_DRC1RMIX_INPUT_3_VOLUME 0x8CD
-#define WM5100_DRC1RMIX_INPUT_4_SOURCE 0x8CE
-#define WM5100_DRC1RMIX_INPUT_4_VOLUME 0x8CF
-#define WM5100_HPLP1MIX_INPUT_1_SOURCE 0x900
-#define WM5100_HPLP1MIX_INPUT_1_VOLUME 0x901
-#define WM5100_HPLP1MIX_INPUT_2_SOURCE 0x902
-#define WM5100_HPLP1MIX_INPUT_2_VOLUME 0x903
-#define WM5100_HPLP1MIX_INPUT_3_SOURCE 0x904
-#define WM5100_HPLP1MIX_INPUT_3_VOLUME 0x905
-#define WM5100_HPLP1MIX_INPUT_4_SOURCE 0x906
-#define WM5100_HPLP1MIX_INPUT_4_VOLUME 0x907
-#define WM5100_HPLP2MIX_INPUT_1_SOURCE 0x908
-#define WM5100_HPLP2MIX_INPUT_1_VOLUME 0x909
-#define WM5100_HPLP2MIX_INPUT_2_SOURCE 0x90A
-#define WM5100_HPLP2MIX_INPUT_2_VOLUME 0x90B
-#define WM5100_HPLP2MIX_INPUT_3_SOURCE 0x90C
-#define WM5100_HPLP2MIX_INPUT_3_VOLUME 0x90D
-#define WM5100_HPLP2MIX_INPUT_4_SOURCE 0x90E
-#define WM5100_HPLP2MIX_INPUT_4_VOLUME 0x90F
-#define WM5100_HPLP3MIX_INPUT_1_SOURCE 0x910
-#define WM5100_HPLP3MIX_INPUT_1_VOLUME 0x911
-#define WM5100_HPLP3MIX_INPUT_2_SOURCE 0x912
-#define WM5100_HPLP3MIX_INPUT_2_VOLUME 0x913
-#define WM5100_HPLP3MIX_INPUT_3_SOURCE 0x914
-#define WM5100_HPLP3MIX_INPUT_3_VOLUME 0x915
-#define WM5100_HPLP3MIX_INPUT_4_SOURCE 0x916
-#define WM5100_HPLP3MIX_INPUT_4_VOLUME 0x917
-#define WM5100_HPLP4MIX_INPUT_1_SOURCE 0x918
-#define WM5100_HPLP4MIX_INPUT_1_VOLUME 0x919
-#define WM5100_HPLP4MIX_INPUT_2_SOURCE 0x91A
-#define WM5100_HPLP4MIX_INPUT_2_VOLUME 0x91B
-#define WM5100_HPLP4MIX_INPUT_3_SOURCE 0x91C
-#define WM5100_HPLP4MIX_INPUT_3_VOLUME 0x91D
-#define WM5100_HPLP4MIX_INPUT_4_SOURCE 0x91E
-#define WM5100_HPLP4MIX_INPUT_4_VOLUME 0x91F
-#define WM5100_DSP1LMIX_INPUT_1_SOURCE 0x940
-#define WM5100_DSP1LMIX_INPUT_1_VOLUME 0x941
-#define WM5100_DSP1LMIX_INPUT_2_SOURCE 0x942
-#define WM5100_DSP1LMIX_INPUT_2_VOLUME 0x943
-#define WM5100_DSP1LMIX_INPUT_3_SOURCE 0x944
-#define WM5100_DSP1LMIX_INPUT_3_VOLUME 0x945
-#define WM5100_DSP1LMIX_INPUT_4_SOURCE 0x946
-#define WM5100_DSP1LMIX_INPUT_4_VOLUME 0x947
-#define WM5100_DSP1RMIX_INPUT_1_SOURCE 0x948
-#define WM5100_DSP1RMIX_INPUT_1_VOLUME 0x949
-#define WM5100_DSP1RMIX_INPUT_2_SOURCE 0x94A
-#define WM5100_DSP1RMIX_INPUT_2_VOLUME 0x94B
-#define WM5100_DSP1RMIX_INPUT_3_SOURCE 0x94C
-#define WM5100_DSP1RMIX_INPUT_3_VOLUME 0x94D
-#define WM5100_DSP1RMIX_INPUT_4_SOURCE 0x94E
-#define WM5100_DSP1RMIX_INPUT_4_VOLUME 0x94F
-#define WM5100_DSP1AUX1MIX_INPUT_1_SOURCE 0x950
-#define WM5100_DSP1AUX2MIX_INPUT_1_SOURCE 0x958
-#define WM5100_DSP1AUX3MIX_INPUT_1_SOURCE 0x960
-#define WM5100_DSP1AUX4MIX_INPUT_1_SOURCE 0x968
-#define WM5100_DSP1AUX5MIX_INPUT_1_SOURCE 0x970
-#define WM5100_DSP1AUX6MIX_INPUT_1_SOURCE 0x978
-#define WM5100_DSP2LMIX_INPUT_1_SOURCE 0x980
-#define WM5100_DSP2LMIX_INPUT_1_VOLUME 0x981
-#define WM5100_DSP2LMIX_INPUT_2_SOURCE 0x982
-#define WM5100_DSP2LMIX_INPUT_2_VOLUME 0x983
-#define WM5100_DSP2LMIX_INPUT_3_SOURCE 0x984
-#define WM5100_DSP2LMIX_INPUT_3_VOLUME 0x985
-#define WM5100_DSP2LMIX_INPUT_4_SOURCE 0x986
-#define WM5100_DSP2LMIX_INPUT_4_VOLUME 0x987
-#define WM5100_DSP2RMIX_INPUT_1_SOURCE 0x988
-#define WM5100_DSP2RMIX_INPUT_1_VOLUME 0x989
-#define WM5100_DSP2RMIX_INPUT_2_SOURCE 0x98A
-#define WM5100_DSP2RMIX_INPUT_2_VOLUME 0x98B
-#define WM5100_DSP2RMIX_INPUT_3_SOURCE 0x98C
-#define WM5100_DSP2RMIX_INPUT_3_VOLUME 0x98D
-#define WM5100_DSP2RMIX_INPUT_4_SOURCE 0x98E
-#define WM5100_DSP2RMIX_INPUT_4_VOLUME 0x98F
-#define WM5100_DSP2AUX1MIX_INPUT_1_SOURCE 0x990
-#define WM5100_DSP2AUX2MIX_INPUT_1_SOURCE 0x998
-#define WM5100_DSP2AUX3MIX_INPUT_1_SOURCE 0x9A0
-#define WM5100_DSP2AUX4MIX_INPUT_1_SOURCE 0x9A8
-#define WM5100_DSP2AUX5MIX_INPUT_1_SOURCE 0x9B0
-#define WM5100_DSP2AUX6MIX_INPUT_1_SOURCE 0x9B8
-#define WM5100_DSP3LMIX_INPUT_1_SOURCE 0x9C0
-#define WM5100_DSP3LMIX_INPUT_1_VOLUME 0x9C1
-#define WM5100_DSP3LMIX_INPUT_2_SOURCE 0x9C2
-#define WM5100_DSP3LMIX_INPUT_2_VOLUME 0x9C3
-#define WM5100_DSP3LMIX_INPUT_3_SOURCE 0x9C4
-#define WM5100_DSP3LMIX_INPUT_3_VOLUME 0x9C5
-#define WM5100_DSP3LMIX_INPUT_4_SOURCE 0x9C6
-#define WM5100_DSP3LMIX_INPUT_4_VOLUME 0x9C7
-#define WM5100_DSP3RMIX_INPUT_1_SOURCE 0x9C8
-#define WM5100_DSP3RMIX_INPUT_1_VOLUME 0x9C9
-#define WM5100_DSP3RMIX_INPUT_2_SOURCE 0x9CA
-#define WM5100_DSP3RMIX_INPUT_2_VOLUME 0x9CB
-#define WM5100_DSP3RMIX_INPUT_3_SOURCE 0x9CC
-#define WM5100_DSP3RMIX_INPUT_3_VOLUME 0x9CD
-#define WM5100_DSP3RMIX_INPUT_4_SOURCE 0x9CE
-#define WM5100_DSP3RMIX_INPUT_4_VOLUME 0x9CF
-#define WM5100_DSP3AUX1MIX_INPUT_1_SOURCE 0x9D0
-#define WM5100_DSP3AUX2MIX_INPUT_1_SOURCE 0x9D8
-#define WM5100_DSP3AUX3MIX_INPUT_1_SOURCE 0x9E0
-#define WM5100_DSP3AUX4MIX_INPUT_1_SOURCE 0x9E8
-#define WM5100_DSP3AUX5MIX_INPUT_1_SOURCE 0x9F0
-#define WM5100_DSP3AUX6MIX_INPUT_1_SOURCE 0x9F8
-#define WM5100_ASRC1LMIX_INPUT_1_SOURCE 0xA80
-#define WM5100_ASRC1RMIX_INPUT_1_SOURCE 0xA88
-#define WM5100_ASRC2LMIX_INPUT_1_SOURCE 0xA90
-#define WM5100_ASRC2RMIX_INPUT_1_SOURCE 0xA98
-#define WM5100_ISRC1DEC1MIX_INPUT_1_SOURCE 0xB00
-#define WM5100_ISRC1DEC2MIX_INPUT_1_SOURCE 0xB08
-#define WM5100_ISRC1DEC3MIX_INPUT_1_SOURCE 0xB10
-#define WM5100_ISRC1DEC4MIX_INPUT_1_SOURCE 0xB18
-#define WM5100_ISRC1INT1MIX_INPUT_1_SOURCE 0xB20
-#define WM5100_ISRC1INT2MIX_INPUT_1_SOURCE 0xB28
-#define WM5100_ISRC1INT3MIX_INPUT_1_SOURCE 0xB30
-#define WM5100_ISRC1INT4MIX_INPUT_1_SOURCE 0xB38
-#define WM5100_ISRC2DEC1MIX_INPUT_1_SOURCE 0xB40
-#define WM5100_ISRC2DEC2MIX_INPUT_1_SOURCE 0xB48
-#define WM5100_ISRC2DEC3MIX_INPUT_1_SOURCE 0xB50
-#define WM5100_ISRC2DEC4MIX_INPUT_1_SOURCE 0xB58
-#define WM5100_ISRC2INT1MIX_INPUT_1_SOURCE 0xB60
-#define WM5100_ISRC2INT2MIX_INPUT_1_SOURCE 0xB68
-#define WM5100_ISRC2INT3MIX_INPUT_1_SOURCE 0xB70
-#define WM5100_ISRC2INT4MIX_INPUT_1_SOURCE 0xB78
-#define WM5100_GPIO_CTRL_1 0xC00
-#define WM5100_GPIO_CTRL_2 0xC01
-#define WM5100_GPIO_CTRL_3 0xC02
-#define WM5100_GPIO_CTRL_4 0xC03
-#define WM5100_GPIO_CTRL_5 0xC04
-#define WM5100_GPIO_CTRL_6 0xC05
-#define WM5100_MISC_PAD_CTRL_1 0xC23
-#define WM5100_MISC_PAD_CTRL_2 0xC24
-#define WM5100_MISC_PAD_CTRL_3 0xC25
-#define WM5100_MISC_PAD_CTRL_4 0xC26
-#define WM5100_MISC_PAD_CTRL_5 0xC27
-#define WM5100_MISC_GPIO_1 0xC28
-#define WM5100_INTERRUPT_STATUS_1 0xD00
-#define WM5100_INTERRUPT_STATUS_2 0xD01
-#define WM5100_INTERRUPT_STATUS_3 0xD02
-#define WM5100_INTERRUPT_STATUS_4 0xD03
-#define WM5100_INTERRUPT_RAW_STATUS_2 0xD04
-#define WM5100_INTERRUPT_RAW_STATUS_3 0xD05
-#define WM5100_INTERRUPT_RAW_STATUS_4 0xD06
-#define WM5100_INTERRUPT_STATUS_1_MASK 0xD07
-#define WM5100_INTERRUPT_STATUS_2_MASK 0xD08
-#define WM5100_INTERRUPT_STATUS_3_MASK 0xD09
-#define WM5100_INTERRUPT_STATUS_4_MASK 0xD0A
-#define WM5100_INTERRUPT_CONTROL 0xD1F
-#define WM5100_IRQ_DEBOUNCE_1 0xD20
-#define WM5100_IRQ_DEBOUNCE_2 0xD21
-#define WM5100_FX_CTRL 0xE00
-#define WM5100_EQ1_1 0xE10
-#define WM5100_EQ1_2 0xE11
-#define WM5100_EQ1_3 0xE12
-#define WM5100_EQ1_4 0xE13
-#define WM5100_EQ1_5 0xE14
-#define WM5100_EQ1_6 0xE15
-#define WM5100_EQ1_7 0xE16
-#define WM5100_EQ1_8 0xE17
-#define WM5100_EQ1_9 0xE18
-#define WM5100_EQ1_10 0xE19
-#define WM5100_EQ1_11 0xE1A
-#define WM5100_EQ1_12 0xE1B
-#define WM5100_EQ1_13 0xE1C
-#define WM5100_EQ1_14 0xE1D
-#define WM5100_EQ1_15 0xE1E
-#define WM5100_EQ1_16 0xE1F
-#define WM5100_EQ1_17 0xE20
-#define WM5100_EQ1_18 0xE21
-#define WM5100_EQ1_19 0xE22
-#define WM5100_EQ1_20 0xE23
-#define WM5100_EQ2_1 0xE26
-#define WM5100_EQ2_2 0xE27
-#define WM5100_EQ2_3 0xE28
-#define WM5100_EQ2_4 0xE29
-#define WM5100_EQ2_5 0xE2A
-#define WM5100_EQ2_6 0xE2B
-#define WM5100_EQ2_7 0xE2C
-#define WM5100_EQ2_8 0xE2D
-#define WM5100_EQ2_9 0xE2E
-#define WM5100_EQ2_10 0xE2F
-#define WM5100_EQ2_11 0xE30
-#define WM5100_EQ2_12 0xE31
-#define WM5100_EQ2_13 0xE32
-#define WM5100_EQ2_14 0xE33
-#define WM5100_EQ2_15 0xE34
-#define WM5100_EQ2_16 0xE35
-#define WM5100_EQ2_17 0xE36
-#define WM5100_EQ2_18 0xE37
-#define WM5100_EQ2_19 0xE38
-#define WM5100_EQ2_20 0xE39
-#define WM5100_EQ3_1 0xE3C
-#define WM5100_EQ3_2 0xE3D
-#define WM5100_EQ3_3 0xE3E
-#define WM5100_EQ3_4 0xE3F
-#define WM5100_EQ3_5 0xE40
-#define WM5100_EQ3_6 0xE41
-#define WM5100_EQ3_7 0xE42
-#define WM5100_EQ3_8 0xE43
-#define WM5100_EQ3_9 0xE44
-#define WM5100_EQ3_10 0xE45
-#define WM5100_EQ3_11 0xE46
-#define WM5100_EQ3_12 0xE47
-#define WM5100_EQ3_13 0xE48
-#define WM5100_EQ3_14 0xE49
-#define WM5100_EQ3_15 0xE4A
-#define WM5100_EQ3_16 0xE4B
-#define WM5100_EQ3_17 0xE4C
-#define WM5100_EQ3_18 0xE4D
-#define WM5100_EQ3_19 0xE4E
-#define WM5100_EQ3_20 0xE4F
-#define WM5100_EQ4_1 0xE52
-#define WM5100_EQ4_2 0xE53
-#define WM5100_EQ4_3 0xE54
-#define WM5100_EQ4_4 0xE55
-#define WM5100_EQ4_5 0xE56
-#define WM5100_EQ4_6 0xE57
-#define WM5100_EQ4_7 0xE58
-#define WM5100_EQ4_8 0xE59
-#define WM5100_EQ4_9 0xE5A
-#define WM5100_EQ4_10 0xE5B
-#define WM5100_EQ4_11 0xE5C
-#define WM5100_EQ4_12 0xE5D
-#define WM5100_EQ4_13 0xE5E
-#define WM5100_EQ4_14 0xE5F
-#define WM5100_EQ4_15 0xE60
-#define WM5100_EQ4_16 0xE61
-#define WM5100_EQ4_17 0xE62
-#define WM5100_EQ4_18 0xE63
-#define WM5100_EQ4_19 0xE64
-#define WM5100_EQ4_20 0xE65
-#define WM5100_DRC1_CTRL1 0xE80
-#define WM5100_DRC1_CTRL2 0xE81
-#define WM5100_DRC1_CTRL3 0xE82
-#define WM5100_DRC1_CTRL4 0xE83
-#define WM5100_DRC1_CTRL5 0xE84
-#define WM5100_HPLPF1_1 0xEC0
-#define WM5100_HPLPF1_2 0xEC1
-#define WM5100_HPLPF2_1 0xEC4
-#define WM5100_HPLPF2_2 0xEC5
-#define WM5100_HPLPF3_1 0xEC8
-#define WM5100_HPLPF3_2 0xEC9
-#define WM5100_HPLPF4_1 0xECC
-#define WM5100_HPLPF4_2 0xECD
-#define WM5100_DSP1_DM_0 0x4000
-#define WM5100_DSP1_DM_1 0x4001
-#define WM5100_DSP1_DM_2 0x4002
-#define WM5100_DSP1_DM_3 0x4003
-#define WM5100_DSP1_DM_508 0x41FC
-#define WM5100_DSP1_DM_509 0x41FD
-#define WM5100_DSP1_DM_510 0x41FE
-#define WM5100_DSP1_DM_511 0x41FF
-#define WM5100_DSP1_PM_0 0x4800
-#define WM5100_DSP1_PM_1 0x4801
-#define WM5100_DSP1_PM_2 0x4802
-#define WM5100_DSP1_PM_3 0x4803
-#define WM5100_DSP1_PM_4 0x4804
-#define WM5100_DSP1_PM_5 0x4805
-#define WM5100_DSP1_PM_1530 0x4DFA
-#define WM5100_DSP1_PM_1531 0x4DFB
-#define WM5100_DSP1_PM_1532 0x4DFC
-#define WM5100_DSP1_PM_1533 0x4DFD
-#define WM5100_DSP1_PM_1534 0x4DFE
-#define WM5100_DSP1_PM_1535 0x4DFF
-#define WM5100_DSP1_ZM_0 0x5000
-#define WM5100_DSP1_ZM_1 0x5001
-#define WM5100_DSP1_ZM_2 0x5002
-#define WM5100_DSP1_ZM_3 0x5003
-#define WM5100_DSP1_ZM_2044 0x57FC
-#define WM5100_DSP1_ZM_2045 0x57FD
-#define WM5100_DSP1_ZM_2046 0x57FE
-#define WM5100_DSP1_ZM_2047 0x57FF
-#define WM5100_DSP2_DM_0 0x6000
-#define WM5100_DSP2_DM_1 0x6001
-#define WM5100_DSP2_DM_2 0x6002
-#define WM5100_DSP2_DM_3 0x6003
-#define WM5100_DSP2_DM_508 0x61FC
-#define WM5100_DSP2_DM_509 0x61FD
-#define WM5100_DSP2_DM_510 0x61FE
-#define WM5100_DSP2_DM_511 0x61FF
-#define WM5100_DSP2_PM_0 0x6800
-#define WM5100_DSP2_PM_1 0x6801
-#define WM5100_DSP2_PM_2 0x6802
-#define WM5100_DSP2_PM_3 0x6803
-#define WM5100_DSP2_PM_4 0x6804
-#define WM5100_DSP2_PM_5 0x6805
-#define WM5100_DSP2_PM_1530 0x6DFA
-#define WM5100_DSP2_PM_1531 0x6DFB
-#define WM5100_DSP2_PM_1532 0x6DFC
-#define WM5100_DSP2_PM_1533 0x6DFD
-#define WM5100_DSP2_PM_1534 0x6DFE
-#define WM5100_DSP2_PM_1535 0x6DFF
-#define WM5100_DSP2_ZM_0 0x7000
-#define WM5100_DSP2_ZM_1 0x7001
-#define WM5100_DSP2_ZM_2 0x7002
-#define WM5100_DSP2_ZM_3 0x7003
-#define WM5100_DSP2_ZM_2044 0x77FC
-#define WM5100_DSP2_ZM_2045 0x77FD
-#define WM5100_DSP2_ZM_2046 0x77FE
-#define WM5100_DSP2_ZM_2047 0x77FF
-#define WM5100_DSP3_DM_0 0x8000
-#define WM5100_DSP3_DM_1 0x8001
-#define WM5100_DSP3_DM_2 0x8002
-#define WM5100_DSP3_DM_3 0x8003
-#define WM5100_DSP3_DM_508 0x81FC
-#define WM5100_DSP3_DM_509 0x81FD
-#define WM5100_DSP3_DM_510 0x81FE
-#define WM5100_DSP3_DM_511 0x81FF
-#define WM5100_DSP3_PM_0 0x8800
-#define WM5100_DSP3_PM_1 0x8801
-#define WM5100_DSP3_PM_2 0x8802
-#define WM5100_DSP3_PM_3 0x8803
-#define WM5100_DSP3_PM_4 0x8804
-#define WM5100_DSP3_PM_5 0x8805
-#define WM5100_DSP3_PM_1530 0x8DFA
-#define WM5100_DSP3_PM_1531 0x8DFB
-#define WM5100_DSP3_PM_1532 0x8DFC
-#define WM5100_DSP3_PM_1533 0x8DFD
-#define WM5100_DSP3_PM_1534 0x8DFE
-#define WM5100_DSP3_PM_1535 0x8DFF
-#define WM5100_DSP3_ZM_0 0x9000
-#define WM5100_DSP3_ZM_1 0x9001
-#define WM5100_DSP3_ZM_2 0x9002
-#define WM5100_DSP3_ZM_3 0x9003
-#define WM5100_DSP3_ZM_2044 0x97FC
-#define WM5100_DSP3_ZM_2045 0x97FD
-#define WM5100_DSP3_ZM_2046 0x97FE
-#define WM5100_DSP3_ZM_2047 0x97FF
-
-#define WM5100_REGISTER_COUNT 1435
-#define WM5100_MAX_REGISTER 0x97FF
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - software reset
- */
-#define WM5100_SW_RST_DEV_ID1_MASK 0xFFFF /* SW_RST_DEV_ID1 - [15:0] */
-#define WM5100_SW_RST_DEV_ID1_SHIFT 0 /* SW_RST_DEV_ID1 - [15:0] */
-#define WM5100_SW_RST_DEV_ID1_WIDTH 16 /* SW_RST_DEV_ID1 - [15:0] */
-
-/*
- * R1 (0x01) - Device Revision
- */
-#define WM5100_DEVICE_REVISION_MASK 0x000F /* DEVICE_REVISION - [3:0] */
-#define WM5100_DEVICE_REVISION_SHIFT 0 /* DEVICE_REVISION - [3:0] */
-#define WM5100_DEVICE_REVISION_WIDTH 4 /* DEVICE_REVISION - [3:0] */
-
-/*
- * R16 (0x10) - Ctrl IF 1
- */
-#define WM5100_AUTO_INC 0x0001 /* AUTO_INC */
-#define WM5100_AUTO_INC_MASK 0x0001 /* AUTO_INC */
-#define WM5100_AUTO_INC_SHIFT 0 /* AUTO_INC */
-#define WM5100_AUTO_INC_WIDTH 1 /* AUTO_INC */
-
-/*
- * R32 (0x20) - Tone Generator 1
- */
-#define WM5100_TONE_RATE_MASK 0x3000 /* TONE_RATE - [13:12] */
-#define WM5100_TONE_RATE_SHIFT 12 /* TONE_RATE - [13:12] */
-#define WM5100_TONE_RATE_WIDTH 2 /* TONE_RATE - [13:12] */
-#define WM5100_TONE_OFFSET_MASK 0x0300 /* TONE_OFFSET - [9:8] */
-#define WM5100_TONE_OFFSET_SHIFT 8 /* TONE_OFFSET - [9:8] */
-#define WM5100_TONE_OFFSET_WIDTH 2 /* TONE_OFFSET - [9:8] */
-#define WM5100_TONE2_ENA 0x0002 /* TONE2_ENA */
-#define WM5100_TONE2_ENA_MASK 0x0002 /* TONE2_ENA */
-#define WM5100_TONE2_ENA_SHIFT 1 /* TONE2_ENA */
-#define WM5100_TONE2_ENA_WIDTH 1 /* TONE2_ENA */
-#define WM5100_TONE1_ENA 0x0001 /* TONE1_ENA */
-#define WM5100_TONE1_ENA_MASK 0x0001 /* TONE1_ENA */
-#define WM5100_TONE1_ENA_SHIFT 0 /* TONE1_ENA */
-#define WM5100_TONE1_ENA_WIDTH 1 /* TONE1_ENA */
-
-/*
- * R48 (0x30) - PWM Drive 1
- */
-#define WM5100_PWM_RATE_MASK 0x3000 /* PWM_RATE - [13:12] */
-#define WM5100_PWM_RATE_SHIFT 12 /* PWM_RATE - [13:12] */
-#define WM5100_PWM_RATE_WIDTH 2 /* PWM_RATE - [13:12] */
-#define WM5100_PWM_CLK_SEL_MASK 0x0300 /* PWM_CLK_SEL - [9:8] */
-#define WM5100_PWM_CLK_SEL_SHIFT 8 /* PWM_CLK_SEL - [9:8] */
-#define WM5100_PWM_CLK_SEL_WIDTH 2 /* PWM_CLK_SEL - [9:8] */
-#define WM5100_PWM2_OVD 0x0020 /* PWM2_OVD */
-#define WM5100_PWM2_OVD_MASK 0x0020 /* PWM2_OVD */
-#define WM5100_PWM2_OVD_SHIFT 5 /* PWM2_OVD */
-#define WM5100_PWM2_OVD_WIDTH 1 /* PWM2_OVD */
-#define WM5100_PWM1_OVD 0x0010 /* PWM1_OVD */
-#define WM5100_PWM1_OVD_MASK 0x0010 /* PWM1_OVD */
-#define WM5100_PWM1_OVD_SHIFT 4 /* PWM1_OVD */
-#define WM5100_PWM1_OVD_WIDTH 1 /* PWM1_OVD */
-#define WM5100_PWM2_ENA 0x0002 /* PWM2_ENA */
-#define WM5100_PWM2_ENA_MASK 0x0002 /* PWM2_ENA */
-#define WM5100_PWM2_ENA_SHIFT 1 /* PWM2_ENA */
-#define WM5100_PWM2_ENA_WIDTH 1 /* PWM2_ENA */
-#define WM5100_PWM1_ENA 0x0001 /* PWM1_ENA */
-#define WM5100_PWM1_ENA_MASK 0x0001 /* PWM1_ENA */
-#define WM5100_PWM1_ENA_SHIFT 0 /* PWM1_ENA */
-#define WM5100_PWM1_ENA_WIDTH 1 /* PWM1_ENA */
-
-/*
- * R49 (0x31) - PWM Drive 2
- */
-#define WM5100_PWM1_LVL_MASK 0x03FF /* PWM1_LVL - [9:0] */
-#define WM5100_PWM1_LVL_SHIFT 0 /* PWM1_LVL - [9:0] */
-#define WM5100_PWM1_LVL_WIDTH 10 /* PWM1_LVL - [9:0] */
-
-/*
- * R50 (0x32) - PWM Drive 3
- */
-#define WM5100_PWM2_LVL_MASK 0x03FF /* PWM2_LVL - [9:0] */
-#define WM5100_PWM2_LVL_SHIFT 0 /* PWM2_LVL - [9:0] */
-#define WM5100_PWM2_LVL_WIDTH 10 /* PWM2_LVL - [9:0] */
-
-/*
- * R256 (0x100) - Clocking 1
- */
-#define WM5100_CLK_32K_SRC_MASK 0x000F /* CLK_32K_SRC - [3:0] */
-#define WM5100_CLK_32K_SRC_SHIFT 0 /* CLK_32K_SRC - [3:0] */
-#define WM5100_CLK_32K_SRC_WIDTH 4 /* CLK_32K_SRC - [3:0] */
-
-/*
- * R257 (0x101) - Clocking 3
- */
-#define WM5100_SYSCLK_FREQ_MASK 0x0700 /* SYSCLK_FREQ - [10:8] */
-#define WM5100_SYSCLK_FREQ_SHIFT 8 /* SYSCLK_FREQ - [10:8] */
-#define WM5100_SYSCLK_FREQ_WIDTH 3 /* SYSCLK_FREQ - [10:8] */
-#define WM5100_SYSCLK_ENA 0x0040 /* SYSCLK_ENA */
-#define WM5100_SYSCLK_ENA_MASK 0x0040 /* SYSCLK_ENA */
-#define WM5100_SYSCLK_ENA_SHIFT 6 /* SYSCLK_ENA */
-#define WM5100_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */
-#define WM5100_SYSCLK_SRC_MASK 0x000F /* SYSCLK_SRC - [3:0] */
-#define WM5100_SYSCLK_SRC_SHIFT 0 /* SYSCLK_SRC - [3:0] */
-#define WM5100_SYSCLK_SRC_WIDTH 4 /* SYSCLK_SRC - [3:0] */
-
-/*
- * R258 (0x102) - Clocking 4
- */
-#define WM5100_SAMPLE_RATE_1_MASK 0x001F /* SAMPLE_RATE_1 - [4:0] */
-#define WM5100_SAMPLE_RATE_1_SHIFT 0 /* SAMPLE_RATE_1 - [4:0] */
-#define WM5100_SAMPLE_RATE_1_WIDTH 5 /* SAMPLE_RATE_1 - [4:0] */
-
-/*
- * R259 (0x103) - Clocking 5
- */
-#define WM5100_SAMPLE_RATE_2_MASK 0x001F /* SAMPLE_RATE_2 - [4:0] */
-#define WM5100_SAMPLE_RATE_2_SHIFT 0 /* SAMPLE_RATE_2 - [4:0] */
-#define WM5100_SAMPLE_RATE_2_WIDTH 5 /* SAMPLE_RATE_2 - [4:0] */
-
-/*
- * R260 (0x104) - Clocking 6
- */
-#define WM5100_SAMPLE_RATE_3_MASK 0x001F /* SAMPLE_RATE_3 - [4:0] */
-#define WM5100_SAMPLE_RATE_3_SHIFT 0 /* SAMPLE_RATE_3 - [4:0] */
-#define WM5100_SAMPLE_RATE_3_WIDTH 5 /* SAMPLE_RATE_3 - [4:0] */
-
-/*
- * R263 (0x107) - Clocking 7
- */
-#define WM5100_ASYNC_CLK_FREQ_MASK 0x0700 /* ASYNC_CLK_FREQ - [10:8] */
-#define WM5100_ASYNC_CLK_FREQ_SHIFT 8 /* ASYNC_CLK_FREQ - [10:8] */
-#define WM5100_ASYNC_CLK_FREQ_WIDTH 3 /* ASYNC_CLK_FREQ - [10:8] */
-#define WM5100_ASYNC_CLK_ENA 0x0040 /* ASYNC_CLK_ENA */
-#define WM5100_ASYNC_CLK_ENA_MASK 0x0040 /* ASYNC_CLK_ENA */
-#define WM5100_ASYNC_CLK_ENA_SHIFT 6 /* ASYNC_CLK_ENA */
-#define WM5100_ASYNC_CLK_ENA_WIDTH 1 /* ASYNC_CLK_ENA */
-#define WM5100_ASYNC_CLK_SRC_MASK 0x000F /* ASYNC_CLK_SRC - [3:0] */
-#define WM5100_ASYNC_CLK_SRC_SHIFT 0 /* ASYNC_CLK_SRC - [3:0] */
-#define WM5100_ASYNC_CLK_SRC_WIDTH 4 /* ASYNC_CLK_SRC - [3:0] */
-
-/*
- * R264 (0x108) - Clocking 8
- */
-#define WM5100_ASYNC_SAMPLE_RATE_MASK 0x001F /* ASYNC_SAMPLE_RATE - [4:0] */
-#define WM5100_ASYNC_SAMPLE_RATE_SHIFT 0 /* ASYNC_SAMPLE_RATE - [4:0] */
-#define WM5100_ASYNC_SAMPLE_RATE_WIDTH 5 /* ASYNC_SAMPLE_RATE - [4:0] */
-
-/*
- * R288 (0x120) - ASRC_ENABLE
- */
-#define WM5100_ASRC2L_ENA 0x0008 /* ASRC2L_ENA */
-#define WM5100_ASRC2L_ENA_MASK 0x0008 /* ASRC2L_ENA */
-#define WM5100_ASRC2L_ENA_SHIFT 3 /* ASRC2L_ENA */
-#define WM5100_ASRC2L_ENA_WIDTH 1 /* ASRC2L_ENA */
-#define WM5100_ASRC2R_ENA 0x0004 /* ASRC2R_ENA */
-#define WM5100_ASRC2R_ENA_MASK 0x0004 /* ASRC2R_ENA */
-#define WM5100_ASRC2R_ENA_SHIFT 2 /* ASRC2R_ENA */
-#define WM5100_ASRC2R_ENA_WIDTH 1 /* ASRC2R_ENA */
-#define WM5100_ASRC1L_ENA 0x0002 /* ASRC1L_ENA */
-#define WM5100_ASRC1L_ENA_MASK 0x0002 /* ASRC1L_ENA */
-#define WM5100_ASRC1L_ENA_SHIFT 1 /* ASRC1L_ENA */
-#define WM5100_ASRC1L_ENA_WIDTH 1 /* ASRC1L_ENA */
-#define WM5100_ASRC1R_ENA 0x0001 /* ASRC1R_ENA */
-#define WM5100_ASRC1R_ENA_MASK 0x0001 /* ASRC1R_ENA */
-#define WM5100_ASRC1R_ENA_SHIFT 0 /* ASRC1R_ENA */
-#define WM5100_ASRC1R_ENA_WIDTH 1 /* ASRC1R_ENA */
-
-/*
- * R289 (0x121) - ASRC_STATUS
- */
-#define WM5100_ASRC2L_ENA_STS 0x0008 /* ASRC2L_ENA_STS */
-#define WM5100_ASRC2L_ENA_STS_MASK 0x0008 /* ASRC2L_ENA_STS */
-#define WM5100_ASRC2L_ENA_STS_SHIFT 3 /* ASRC2L_ENA_STS */
-#define WM5100_ASRC2L_ENA_STS_WIDTH 1 /* ASRC2L_ENA_STS */
-#define WM5100_ASRC2R_ENA_STS 0x0004 /* ASRC2R_ENA_STS */
-#define WM5100_ASRC2R_ENA_STS_MASK 0x0004 /* ASRC2R_ENA_STS */
-#define WM5100_ASRC2R_ENA_STS_SHIFT 2 /* ASRC2R_ENA_STS */
-#define WM5100_ASRC2R_ENA_STS_WIDTH 1 /* ASRC2R_ENA_STS */
-#define WM5100_ASRC1L_ENA_STS 0x0002 /* ASRC1L_ENA_STS */
-#define WM5100_ASRC1L_ENA_STS_MASK 0x0002 /* ASRC1L_ENA_STS */
-#define WM5100_ASRC1L_ENA_STS_SHIFT 1 /* ASRC1L_ENA_STS */
-#define WM5100_ASRC1L_ENA_STS_WIDTH 1 /* ASRC1L_ENA_STS */
-#define WM5100_ASRC1R_ENA_STS 0x0001 /* ASRC1R_ENA_STS */
-#define WM5100_ASRC1R_ENA_STS_MASK 0x0001 /* ASRC1R_ENA_STS */
-#define WM5100_ASRC1R_ENA_STS_SHIFT 0 /* ASRC1R_ENA_STS */
-#define WM5100_ASRC1R_ENA_STS_WIDTH 1 /* ASRC1R_ENA_STS */
-
-/*
- * R290 (0x122) - ASRC_RATE1
- */
-#define WM5100_ASRC_RATE1_MASK 0x0006 /* ASRC_RATE1 - [2:1] */
-#define WM5100_ASRC_RATE1_SHIFT 1 /* ASRC_RATE1 - [2:1] */
-#define WM5100_ASRC_RATE1_WIDTH 2 /* ASRC_RATE1 - [2:1] */
-
-/*
- * R321 (0x141) - ISRC 1 CTRL 1
- */
-#define WM5100_ISRC1_DFS_ENA 0x2000 /* ISRC1_DFS_ENA */
-#define WM5100_ISRC1_DFS_ENA_MASK 0x2000 /* ISRC1_DFS_ENA */
-#define WM5100_ISRC1_DFS_ENA_SHIFT 13 /* ISRC1_DFS_ENA */
-#define WM5100_ISRC1_DFS_ENA_WIDTH 1 /* ISRC1_DFS_ENA */
-#define WM5100_ISRC1_CLK_SEL_MASK 0x0300 /* ISRC1_CLK_SEL - [9:8] */
-#define WM5100_ISRC1_CLK_SEL_SHIFT 8 /* ISRC1_CLK_SEL - [9:8] */
-#define WM5100_ISRC1_CLK_SEL_WIDTH 2 /* ISRC1_CLK_SEL - [9:8] */
-#define WM5100_ISRC1_FSH_MASK 0x000C /* ISRC1_FSH - [3:2] */
-#define WM5100_ISRC1_FSH_SHIFT 2 /* ISRC1_FSH - [3:2] */
-#define WM5100_ISRC1_FSH_WIDTH 2 /* ISRC1_FSH - [3:2] */
-#define WM5100_ISRC1_FSL_MASK 0x0003 /* ISRC1_FSL - [1:0] */
-#define WM5100_ISRC1_FSL_SHIFT 0 /* ISRC1_FSL - [1:0] */
-#define WM5100_ISRC1_FSL_WIDTH 2 /* ISRC1_FSL - [1:0] */
-
-/*
- * R322 (0x142) - ISRC 1 CTRL 2
- */
-#define WM5100_ISRC1_INT1_ENA 0x8000 /* ISRC1_INT1_ENA */
-#define WM5100_ISRC1_INT1_ENA_MASK 0x8000 /* ISRC1_INT1_ENA */
-#define WM5100_ISRC1_INT1_ENA_SHIFT 15 /* ISRC1_INT1_ENA */
-#define WM5100_ISRC1_INT1_ENA_WIDTH 1 /* ISRC1_INT1_ENA */
-#define WM5100_ISRC1_INT2_ENA 0x4000 /* ISRC1_INT2_ENA */
-#define WM5100_ISRC1_INT2_ENA_MASK 0x4000 /* ISRC1_INT2_ENA */
-#define WM5100_ISRC1_INT2_ENA_SHIFT 14 /* ISRC1_INT2_ENA */
-#define WM5100_ISRC1_INT2_ENA_WIDTH 1 /* ISRC1_INT2_ENA */
-#define WM5100_ISRC1_INT3_ENA 0x2000 /* ISRC1_INT3_ENA */
-#define WM5100_ISRC1_INT3_ENA_MASK 0x2000 /* ISRC1_INT3_ENA */
-#define WM5100_ISRC1_INT3_ENA_SHIFT 13 /* ISRC1_INT3_ENA */
-#define WM5100_ISRC1_INT3_ENA_WIDTH 1 /* ISRC1_INT3_ENA */
-#define WM5100_ISRC1_INT4_ENA 0x1000 /* ISRC1_INT4_ENA */
-#define WM5100_ISRC1_INT4_ENA_MASK 0x1000 /* ISRC1_INT4_ENA */
-#define WM5100_ISRC1_INT4_ENA_SHIFT 12 /* ISRC1_INT4_ENA */
-#define WM5100_ISRC1_INT4_ENA_WIDTH 1 /* ISRC1_INT4_ENA */
-#define WM5100_ISRC1_DEC1_ENA 0x0200 /* ISRC1_DEC1_ENA */
-#define WM5100_ISRC1_DEC1_ENA_MASK 0x0200 /* ISRC1_DEC1_ENA */
-#define WM5100_ISRC1_DEC1_ENA_SHIFT 9 /* ISRC1_DEC1_ENA */
-#define WM5100_ISRC1_DEC1_ENA_WIDTH 1 /* ISRC1_DEC1_ENA */
-#define WM5100_ISRC1_DEC2_ENA 0x0100 /* ISRC1_DEC2_ENA */
-#define WM5100_ISRC1_DEC2_ENA_MASK 0x0100 /* ISRC1_DEC2_ENA */
-#define WM5100_ISRC1_DEC2_ENA_SHIFT 8 /* ISRC1_DEC2_ENA */
-#define WM5100_ISRC1_DEC2_ENA_WIDTH 1 /* ISRC1_DEC2_ENA */
-#define WM5100_ISRC1_DEC3_ENA 0x0080 /* ISRC1_DEC3_ENA */
-#define WM5100_ISRC1_DEC3_ENA_MASK 0x0080 /* ISRC1_DEC3_ENA */
-#define WM5100_ISRC1_DEC3_ENA_SHIFT 7 /* ISRC1_DEC3_ENA */
-#define WM5100_ISRC1_DEC3_ENA_WIDTH 1 /* ISRC1_DEC3_ENA */
-#define WM5100_ISRC1_DEC4_ENA 0x0040 /* ISRC1_DEC4_ENA */
-#define WM5100_ISRC1_DEC4_ENA_MASK 0x0040 /* ISRC1_DEC4_ENA */
-#define WM5100_ISRC1_DEC4_ENA_SHIFT 6 /* ISRC1_DEC4_ENA */
-#define WM5100_ISRC1_DEC4_ENA_WIDTH 1 /* ISRC1_DEC4_ENA */
-#define WM5100_ISRC1_NOTCH_ENA 0x0001 /* ISRC1_NOTCH_ENA */
-#define WM5100_ISRC1_NOTCH_ENA_MASK 0x0001 /* ISRC1_NOTCH_ENA */
-#define WM5100_ISRC1_NOTCH_ENA_SHIFT 0 /* ISRC1_NOTCH_ENA */
-#define WM5100_ISRC1_NOTCH_ENA_WIDTH 1 /* ISRC1_NOTCH_ENA */
-
-/*
- * R323 (0x143) - ISRC 2 CTRL1
- */
-#define WM5100_ISRC2_DFS_ENA 0x2000 /* ISRC2_DFS_ENA */
-#define WM5100_ISRC2_DFS_ENA_MASK 0x2000 /* ISRC2_DFS_ENA */
-#define WM5100_ISRC2_DFS_ENA_SHIFT 13 /* ISRC2_DFS_ENA */
-#define WM5100_ISRC2_DFS_ENA_WIDTH 1 /* ISRC2_DFS_ENA */
-#define WM5100_ISRC2_CLK_SEL_MASK 0x0300 /* ISRC2_CLK_SEL - [9:8] */
-#define WM5100_ISRC2_CLK_SEL_SHIFT 8 /* ISRC2_CLK_SEL - [9:8] */
-#define WM5100_ISRC2_CLK_SEL_WIDTH 2 /* ISRC2_CLK_SEL - [9:8] */
-#define WM5100_ISRC2_FSH_MASK 0x000C /* ISRC2_FSH - [3:2] */
-#define WM5100_ISRC2_FSH_SHIFT 2 /* ISRC2_FSH - [3:2] */
-#define WM5100_ISRC2_FSH_WIDTH 2 /* ISRC2_FSH - [3:2] */
-#define WM5100_ISRC2_FSL_MASK 0x0003 /* ISRC2_FSL - [1:0] */
-#define WM5100_ISRC2_FSL_SHIFT 0 /* ISRC2_FSL - [1:0] */
-#define WM5100_ISRC2_FSL_WIDTH 2 /* ISRC2_FSL - [1:0] */
-
-/*
- * R324 (0x144) - ISRC 2 CTRL 2
- */
-#define WM5100_ISRC2_INT1_ENA 0x8000 /* ISRC2_INT1_ENA */
-#define WM5100_ISRC2_INT1_ENA_MASK 0x8000 /* ISRC2_INT1_ENA */
-#define WM5100_ISRC2_INT1_ENA_SHIFT 15 /* ISRC2_INT1_ENA */
-#define WM5100_ISRC2_INT1_ENA_WIDTH 1 /* ISRC2_INT1_ENA */
-#define WM5100_ISRC2_INT2_ENA 0x4000 /* ISRC2_INT2_ENA */
-#define WM5100_ISRC2_INT2_ENA_MASK 0x4000 /* ISRC2_INT2_ENA */
-#define WM5100_ISRC2_INT2_ENA_SHIFT 14 /* ISRC2_INT2_ENA */
-#define WM5100_ISRC2_INT2_ENA_WIDTH 1 /* ISRC2_INT2_ENA */
-#define WM5100_ISRC2_INT3_ENA 0x2000 /* ISRC2_INT3_ENA */
-#define WM5100_ISRC2_INT3_ENA_MASK 0x2000 /* ISRC2_INT3_ENA */
-#define WM5100_ISRC2_INT3_ENA_SHIFT 13 /* ISRC2_INT3_ENA */
-#define WM5100_ISRC2_INT3_ENA_WIDTH 1 /* ISRC2_INT3_ENA */
-#define WM5100_ISRC2_INT4_ENA 0x1000 /* ISRC2_INT4_ENA */
-#define WM5100_ISRC2_INT4_ENA_MASK 0x1000 /* ISRC2_INT4_ENA */
-#define WM5100_ISRC2_INT4_ENA_SHIFT 12 /* ISRC2_INT4_ENA */
-#define WM5100_ISRC2_INT4_ENA_WIDTH 1 /* ISRC2_INT4_ENA */
-#define WM5100_ISRC2_DEC1_ENA 0x0200 /* ISRC2_DEC1_ENA */
-#define WM5100_ISRC2_DEC1_ENA_MASK 0x0200 /* ISRC2_DEC1_ENA */
-#define WM5100_ISRC2_DEC1_ENA_SHIFT 9 /* ISRC2_DEC1_ENA */
-#define WM5100_ISRC2_DEC1_ENA_WIDTH 1 /* ISRC2_DEC1_ENA */
-#define WM5100_ISRC2_DEC2_ENA 0x0100 /* ISRC2_DEC2_ENA */
-#define WM5100_ISRC2_DEC2_ENA_MASK 0x0100 /* ISRC2_DEC2_ENA */
-#define WM5100_ISRC2_DEC2_ENA_SHIFT 8 /* ISRC2_DEC2_ENA */
-#define WM5100_ISRC2_DEC2_ENA_WIDTH 1 /* ISRC2_DEC2_ENA */
-#define WM5100_ISRC2_DEC3_ENA 0x0080 /* ISRC2_DEC3_ENA */
-#define WM5100_ISRC2_DEC3_ENA_MASK 0x0080 /* ISRC2_DEC3_ENA */
-#define WM5100_ISRC2_DEC3_ENA_SHIFT 7 /* ISRC2_DEC3_ENA */
-#define WM5100_ISRC2_DEC3_ENA_WIDTH 1 /* ISRC2_DEC3_ENA */
-#define WM5100_ISRC2_DEC4_ENA 0x0040 /* ISRC2_DEC4_ENA */
-#define WM5100_ISRC2_DEC4_ENA_MASK 0x0040 /* ISRC2_DEC4_ENA */
-#define WM5100_ISRC2_DEC4_ENA_SHIFT 6 /* ISRC2_DEC4_ENA */
-#define WM5100_ISRC2_DEC4_ENA_WIDTH 1 /* ISRC2_DEC4_ENA */
-#define WM5100_ISRC2_NOTCH_ENA 0x0001 /* ISRC2_NOTCH_ENA */
-#define WM5100_ISRC2_NOTCH_ENA_MASK 0x0001 /* ISRC2_NOTCH_ENA */
-#define WM5100_ISRC2_NOTCH_ENA_SHIFT 0 /* ISRC2_NOTCH_ENA */
-#define WM5100_ISRC2_NOTCH_ENA_WIDTH 1 /* ISRC2_NOTCH_ENA */
-
-/*
- * R386 (0x182) - FLL1 Control 1
- */
-#define WM5100_FLL1_ENA 0x0001 /* FLL1_ENA */
-#define WM5100_FLL1_ENA_MASK 0x0001 /* FLL1_ENA */
-#define WM5100_FLL1_ENA_SHIFT 0 /* FLL1_ENA */
-#define WM5100_FLL1_ENA_WIDTH 1 /* FLL1_ENA */
-
-/*
- * R387 (0x183) - FLL1 Control 2
- */
-#define WM5100_FLL1_OUTDIV_MASK 0x3F00 /* FLL1_OUTDIV - [13:8] */
-#define WM5100_FLL1_OUTDIV_SHIFT 8 /* FLL1_OUTDIV - [13:8] */
-#define WM5100_FLL1_OUTDIV_WIDTH 6 /* FLL1_OUTDIV - [13:8] */
-#define WM5100_FLL1_FRATIO_MASK 0x0007 /* FLL1_FRATIO - [2:0] */
-#define WM5100_FLL1_FRATIO_SHIFT 0 /* FLL1_FRATIO - [2:0] */
-#define WM5100_FLL1_FRATIO_WIDTH 3 /* FLL1_FRATIO - [2:0] */
-
-/*
- * R388 (0x184) - FLL1 Control 3
- */
-#define WM5100_FLL1_THETA_MASK 0xFFFF /* FLL1_THETA - [15:0] */
-#define WM5100_FLL1_THETA_SHIFT 0 /* FLL1_THETA - [15:0] */
-#define WM5100_FLL1_THETA_WIDTH 16 /* FLL1_THETA - [15:0] */
-
-/*
- * R390 (0x186) - FLL1 Control 5
- */
-#define WM5100_FLL1_N_MASK 0x03FF /* FLL1_N - [9:0] */
-#define WM5100_FLL1_N_SHIFT 0 /* FLL1_N - [9:0] */
-#define WM5100_FLL1_N_WIDTH 10 /* FLL1_N - [9:0] */
-
-/*
- * R391 (0x187) - FLL1 Control 6
- */
-#define WM5100_FLL1_REFCLK_DIV_MASK 0x00C0 /* FLL1_REFCLK_DIV - [7:6] */
-#define WM5100_FLL1_REFCLK_DIV_SHIFT 6 /* FLL1_REFCLK_DIV - [7:6] */
-#define WM5100_FLL1_REFCLK_DIV_WIDTH 2 /* FLL1_REFCLK_DIV - [7:6] */
-#define WM5100_FLL1_REFCLK_SRC_MASK 0x000F /* FLL1_REFCLK_SRC - [3:0] */
-#define WM5100_FLL1_REFCLK_SRC_SHIFT 0 /* FLL1_REFCLK_SRC - [3:0] */
-#define WM5100_FLL1_REFCLK_SRC_WIDTH 4 /* FLL1_REFCLK_SRC - [3:0] */
-
-/*
- * R392 (0x188) - FLL1 EFS 1
- */
-#define WM5100_FLL1_LAMBDA_MASK 0xFFFF /* FLL1_LAMBDA - [15:0] */
-#define WM5100_FLL1_LAMBDA_SHIFT 0 /* FLL1_LAMBDA - [15:0] */
-#define WM5100_FLL1_LAMBDA_WIDTH 16 /* FLL1_LAMBDA - [15:0] */
-
-/*
- * R418 (0x1A2) - FLL2 Control 1
- */
-#define WM5100_FLL2_ENA 0x0001 /* FLL2_ENA */
-#define WM5100_FLL2_ENA_MASK 0x0001 /* FLL2_ENA */
-#define WM5100_FLL2_ENA_SHIFT 0 /* FLL2_ENA */
-#define WM5100_FLL2_ENA_WIDTH 1 /* FLL2_ENA */
-
-/*
- * R419 (0x1A3) - FLL2 Control 2
- */
-#define WM5100_FLL2_OUTDIV_MASK 0x3F00 /* FLL2_OUTDIV - [13:8] */
-#define WM5100_FLL2_OUTDIV_SHIFT 8 /* FLL2_OUTDIV - [13:8] */
-#define WM5100_FLL2_OUTDIV_WIDTH 6 /* FLL2_OUTDIV - [13:8] */
-#define WM5100_FLL2_FRATIO_MASK 0x0007 /* FLL2_FRATIO - [2:0] */
-#define WM5100_FLL2_FRATIO_SHIFT 0 /* FLL2_FRATIO - [2:0] */
-#define WM5100_FLL2_FRATIO_WIDTH 3 /* FLL2_FRATIO - [2:0] */
-
-/*
- * R420 (0x1A4) - FLL2 Control 3
- */
-#define WM5100_FLL2_THETA_MASK 0xFFFF /* FLL2_THETA - [15:0] */
-#define WM5100_FLL2_THETA_SHIFT 0 /* FLL2_THETA - [15:0] */
-#define WM5100_FLL2_THETA_WIDTH 16 /* FLL2_THETA - [15:0] */
-
-/*
- * R422 (0x1A6) - FLL2 Control 5
- */
-#define WM5100_FLL2_N_MASK 0x03FF /* FLL2_N - [9:0] */
-#define WM5100_FLL2_N_SHIFT 0 /* FLL2_N - [9:0] */
-#define WM5100_FLL2_N_WIDTH 10 /* FLL2_N - [9:0] */
-
-/*
- * R423 (0x1A7) - FLL2 Control 6
- */
-#define WM5100_FLL2_REFCLK_DIV_MASK 0x00C0 /* FLL2_REFCLK_DIV - [7:6] */
-#define WM5100_FLL2_REFCLK_DIV_SHIFT 6 /* FLL2_REFCLK_DIV - [7:6] */
-#define WM5100_FLL2_REFCLK_DIV_WIDTH 2 /* FLL2_REFCLK_DIV - [7:6] */
-#define WM5100_FLL2_REFCLK_SRC_MASK 0x000F /* FLL2_REFCLK_SRC - [3:0] */
-#define WM5100_FLL2_REFCLK_SRC_SHIFT 0 /* FLL2_REFCLK_SRC - [3:0] */
-#define WM5100_FLL2_REFCLK_SRC_WIDTH 4 /* FLL2_REFCLK_SRC - [3:0] */
-
-/*
- * R424 (0x1A8) - FLL2 EFS 1
- */
-#define WM5100_FLL2_LAMBDA_MASK 0xFFFF /* FLL2_LAMBDA - [15:0] */
-#define WM5100_FLL2_LAMBDA_SHIFT 0 /* FLL2_LAMBDA - [15:0] */
-#define WM5100_FLL2_LAMBDA_WIDTH 16 /* FLL2_LAMBDA - [15:0] */
-
-/*
- * R512 (0x200) - Mic Charge Pump 1
- */
-#define WM5100_CP2_BYPASS 0x0020 /* CP2_BYPASS */
-#define WM5100_CP2_BYPASS_MASK 0x0020 /* CP2_BYPASS */
-#define WM5100_CP2_BYPASS_SHIFT 5 /* CP2_BYPASS */
-#define WM5100_CP2_BYPASS_WIDTH 1 /* CP2_BYPASS */
-#define WM5100_CP2_ENA 0x0001 /* CP2_ENA */
-#define WM5100_CP2_ENA_MASK 0x0001 /* CP2_ENA */
-#define WM5100_CP2_ENA_SHIFT 0 /* CP2_ENA */
-#define WM5100_CP2_ENA_WIDTH 1 /* CP2_ENA */
-
-/*
- * R513 (0x201) - Mic Charge Pump 2
- */
-#define WM5100_LDO2_VSEL_MASK 0xF800 /* LDO2_VSEL - [15:11] */
-#define WM5100_LDO2_VSEL_SHIFT 11 /* LDO2_VSEL - [15:11] */
-#define WM5100_LDO2_VSEL_WIDTH 5 /* LDO2_VSEL - [15:11] */
-
-/*
- * R514 (0x202) - HP Charge Pump 1
- */
-#define WM5100_CP1_ENA 0x0001 /* CP1_ENA */
-#define WM5100_CP1_ENA_MASK 0x0001 /* CP1_ENA */
-#define WM5100_CP1_ENA_SHIFT 0 /* CP1_ENA */
-#define WM5100_CP1_ENA_WIDTH 1 /* CP1_ENA */
-
-/*
- * R529 (0x211) - LDO1 Control
- */
-#define WM5100_LDO1_BYPASS 0x0002 /* LDO1_BYPASS */
-#define WM5100_LDO1_BYPASS_MASK 0x0002 /* LDO1_BYPASS */
-#define WM5100_LDO1_BYPASS_SHIFT 1 /* LDO1_BYPASS */
-#define WM5100_LDO1_BYPASS_WIDTH 1 /* LDO1_BYPASS */
-
-/*
- * R533 (0x215) - Mic Bias Ctrl 1
- */
-#define WM5100_MICB1_DISCH 0x0040 /* MICB1_DISCH */
-#define WM5100_MICB1_DISCH_MASK 0x0040 /* MICB1_DISCH */
-#define WM5100_MICB1_DISCH_SHIFT 6 /* MICB1_DISCH */
-#define WM5100_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
-#define WM5100_MICB1_RATE 0x0020 /* MICB1_RATE */
-#define WM5100_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */
-#define WM5100_MICB1_RATE_SHIFT 5 /* MICB1_RATE */
-#define WM5100_MICB1_RATE_WIDTH 1 /* MICB1_RATE */
-#define WM5100_MICB1_LVL_MASK 0x001C /* MICB1_LVL - [4:2] */
-#define WM5100_MICB1_LVL_SHIFT 2 /* MICB1_LVL - [4:2] */
-#define WM5100_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [4:2] */
-#define WM5100_MICB1_BYPASS 0x0002 /* MICB1_BYPASS */
-#define WM5100_MICB1_BYPASS_MASK 0x0002 /* MICB1_BYPASS */
-#define WM5100_MICB1_BYPASS_SHIFT 1 /* MICB1_BYPASS */
-#define WM5100_MICB1_BYPASS_WIDTH 1 /* MICB1_BYPASS */
-#define WM5100_MICB1_ENA 0x0001 /* MICB1_ENA */
-#define WM5100_MICB1_ENA_MASK 0x0001 /* MICB1_ENA */
-#define WM5100_MICB1_ENA_SHIFT 0 /* MICB1_ENA */
-#define WM5100_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
-
-/*
- * R534 (0x216) - Mic Bias Ctrl 2
- */
-#define WM5100_MICB2_DISCH 0x0040 /* MICB2_DISCH */
-#define WM5100_MICB2_DISCH_MASK 0x0040 /* MICB2_DISCH */
-#define WM5100_MICB2_DISCH_SHIFT 6 /* MICB2_DISCH */
-#define WM5100_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
-#define WM5100_MICB2_RATE 0x0020 /* MICB2_RATE */
-#define WM5100_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */
-#define WM5100_MICB2_RATE_SHIFT 5 /* MICB2_RATE */
-#define WM5100_MICB2_RATE_WIDTH 1 /* MICB2_RATE */
-#define WM5100_MICB2_LVL_MASK 0x001C /* MICB2_LVL - [4:2] */
-#define WM5100_MICB2_LVL_SHIFT 2 /* MICB2_LVL - [4:2] */
-#define WM5100_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [4:2] */
-#define WM5100_MICB2_BYPASS 0x0002 /* MICB2_BYPASS */
-#define WM5100_MICB2_BYPASS_MASK 0x0002 /* MICB2_BYPASS */
-#define WM5100_MICB2_BYPASS_SHIFT 1 /* MICB2_BYPASS */
-#define WM5100_MICB2_BYPASS_WIDTH 1 /* MICB2_BYPASS */
-#define WM5100_MICB2_ENA 0x0001 /* MICB2_ENA */
-#define WM5100_MICB2_ENA_MASK 0x0001 /* MICB2_ENA */
-#define WM5100_MICB2_ENA_SHIFT 0 /* MICB2_ENA */
-#define WM5100_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
-
-/*
- * R535 (0x217) - Mic Bias Ctrl 3
- */
-#define WM5100_MICB3_DISCH 0x0040 /* MICB3_DISCH */
-#define WM5100_MICB3_DISCH_MASK 0x0040 /* MICB3_DISCH */
-#define WM5100_MICB3_DISCH_SHIFT 6 /* MICB3_DISCH */
-#define WM5100_MICB3_DISCH_WIDTH 1 /* MICB3_DISCH */
-#define WM5100_MICB3_RATE 0x0020 /* MICB3_RATE */
-#define WM5100_MICB3_RATE_MASK 0x0020 /* MICB3_RATE */
-#define WM5100_MICB3_RATE_SHIFT 5 /* MICB3_RATE */
-#define WM5100_MICB3_RATE_WIDTH 1 /* MICB3_RATE */
-#define WM5100_MICB3_LVL_MASK 0x001C /* MICB3_LVL - [4:2] */
-#define WM5100_MICB3_LVL_SHIFT 2 /* MICB3_LVL - [4:2] */
-#define WM5100_MICB3_LVL_WIDTH 3 /* MICB3_LVL - [4:2] */
-#define WM5100_MICB3_BYPASS 0x0002 /* MICB3_BYPASS */
-#define WM5100_MICB3_BYPASS_MASK 0x0002 /* MICB3_BYPASS */
-#define WM5100_MICB3_BYPASS_SHIFT 1 /* MICB3_BYPASS */
-#define WM5100_MICB3_BYPASS_WIDTH 1 /* MICB3_BYPASS */
-#define WM5100_MICB3_ENA 0x0001 /* MICB3_ENA */
-#define WM5100_MICB3_ENA_MASK 0x0001 /* MICB3_ENA */
-#define WM5100_MICB3_ENA_SHIFT 0 /* MICB3_ENA */
-#define WM5100_MICB3_ENA_WIDTH 1 /* MICB3_ENA */
-
-/*
- * R640 (0x280) - Accessory Detect Mode 1
- */
-#define WM5100_ACCDET_BIAS_SRC_MASK 0xC000 /* ACCDET_BIAS_SRC - [15:14] */
-#define WM5100_ACCDET_BIAS_SRC_SHIFT 14 /* ACCDET_BIAS_SRC - [15:14] */
-#define WM5100_ACCDET_BIAS_SRC_WIDTH 2 /* ACCDET_BIAS_SRC - [15:14] */
-#define WM5100_ACCDET_SRC 0x2000 /* ACCDET_SRC */
-#define WM5100_ACCDET_SRC_MASK 0x2000 /* ACCDET_SRC */
-#define WM5100_ACCDET_SRC_SHIFT 13 /* ACCDET_SRC */
-#define WM5100_ACCDET_SRC_WIDTH 1 /* ACCDET_SRC */
-#define WM5100_ACCDET_MODE_MASK 0x0003 /* ACCDET_MODE - [1:0] */
-#define WM5100_ACCDET_MODE_SHIFT 0 /* ACCDET_MODE - [1:0] */
-#define WM5100_ACCDET_MODE_WIDTH 2 /* ACCDET_MODE - [1:0] */
-
-/*
- * R648 (0x288) - Headphone Detect 1
- */
-#define WM5100_HP_HOLDTIME_MASK 0x00E0 /* HP_HOLDTIME - [7:5] */
-#define WM5100_HP_HOLDTIME_SHIFT 5 /* HP_HOLDTIME - [7:5] */
-#define WM5100_HP_HOLDTIME_WIDTH 3 /* HP_HOLDTIME - [7:5] */
-#define WM5100_HP_CLK_DIV_MASK 0x0018 /* HP_CLK_DIV - [4:3] */
-#define WM5100_HP_CLK_DIV_SHIFT 3 /* HP_CLK_DIV - [4:3] */
-#define WM5100_HP_CLK_DIV_WIDTH 2 /* HP_CLK_DIV - [4:3] */
-#define WM5100_HP_STEP_SIZE 0x0002 /* HP_STEP_SIZE */
-#define WM5100_HP_STEP_SIZE_MASK 0x0002 /* HP_STEP_SIZE */
-#define WM5100_HP_STEP_SIZE_SHIFT 1 /* HP_STEP_SIZE */
-#define WM5100_HP_STEP_SIZE_WIDTH 1 /* HP_STEP_SIZE */
-#define WM5100_HP_POLL 0x0001 /* HP_POLL */
-#define WM5100_HP_POLL_MASK 0x0001 /* HP_POLL */
-#define WM5100_HP_POLL_SHIFT 0 /* HP_POLL */
-#define WM5100_HP_POLL_WIDTH 1 /* HP_POLL */
-
-/*
- * R649 (0x289) - Headphone Detect 2
- */
-#define WM5100_HP_DONE 0x0080 /* HP_DONE */
-#define WM5100_HP_DONE_MASK 0x0080 /* HP_DONE */
-#define WM5100_HP_DONE_SHIFT 7 /* HP_DONE */
-#define WM5100_HP_DONE_WIDTH 1 /* HP_DONE */
-#define WM5100_HP_LVL_MASK 0x007F /* HP_LVL - [6:0] */
-#define WM5100_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */
-#define WM5100_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */
-
-/*
- * R656 (0x290) - Mic Detect 1
- */
-#define WM5100_ACCDET_BIAS_STARTTIME_MASK 0xF000 /* ACCDET_BIAS_STARTTIME - [15:12] */
-#define WM5100_ACCDET_BIAS_STARTTIME_SHIFT 12 /* ACCDET_BIAS_STARTTIME - [15:12] */
-#define WM5100_ACCDET_BIAS_STARTTIME_WIDTH 4 /* ACCDET_BIAS_STARTTIME - [15:12] */
-#define WM5100_ACCDET_RATE_MASK 0x0F00 /* ACCDET_RATE - [11:8] */
-#define WM5100_ACCDET_RATE_SHIFT 8 /* ACCDET_RATE - [11:8] */
-#define WM5100_ACCDET_RATE_WIDTH 4 /* ACCDET_RATE - [11:8] */
-#define WM5100_ACCDET_DBTIME 0x0002 /* ACCDET_DBTIME */
-#define WM5100_ACCDET_DBTIME_MASK 0x0002 /* ACCDET_DBTIME */
-#define WM5100_ACCDET_DBTIME_SHIFT 1 /* ACCDET_DBTIME */
-#define WM5100_ACCDET_DBTIME_WIDTH 1 /* ACCDET_DBTIME */
-#define WM5100_ACCDET_ENA 0x0001 /* ACCDET_ENA */
-#define WM5100_ACCDET_ENA_MASK 0x0001 /* ACCDET_ENA */
-#define WM5100_ACCDET_ENA_SHIFT 0 /* ACCDET_ENA */
-#define WM5100_ACCDET_ENA_WIDTH 1 /* ACCDET_ENA */
-
-/*
- * R657 (0x291) - Mic Detect 2
- */
-#define WM5100_ACCDET_LVL_SEL_MASK 0x00FF /* ACCDET_LVL_SEL - [7:0] */
-#define WM5100_ACCDET_LVL_SEL_SHIFT 0 /* ACCDET_LVL_SEL - [7:0] */
-#define WM5100_ACCDET_LVL_SEL_WIDTH 8 /* ACCDET_LVL_SEL - [7:0] */
-
-/*
- * R658 (0x292) - Mic Detect 3
- */
-#define WM5100_ACCDET_LVL_MASK 0x07FC /* ACCDET_LVL - [10:2] */
-#define WM5100_ACCDET_LVL_SHIFT 2 /* ACCDET_LVL - [10:2] */
-#define WM5100_ACCDET_LVL_WIDTH 9 /* ACCDET_LVL - [10:2] */
-#define WM5100_ACCDET_VALID 0x0002 /* ACCDET_VALID */
-#define WM5100_ACCDET_VALID_MASK 0x0002 /* ACCDET_VALID */
-#define WM5100_ACCDET_VALID_SHIFT 1 /* ACCDET_VALID */
-#define WM5100_ACCDET_VALID_WIDTH 1 /* ACCDET_VALID */
-#define WM5100_ACCDET_STS 0x0001 /* ACCDET_STS */
-#define WM5100_ACCDET_STS_MASK 0x0001 /* ACCDET_STS */
-#define WM5100_ACCDET_STS_SHIFT 0 /* ACCDET_STS */
-#define WM5100_ACCDET_STS_WIDTH 1 /* ACCDET_STS */
-
-/*
- * R699 (0x2BB) - Misc Control
- */
-#define WM5100_HPCOM_SRC 0x200 /* HPCOM_SRC */
-#define WM5100_HPCOM_SRC_SHIFT 9 /* HPCOM_SRC */
-
-/*
- * R769 (0x301) - Input Enables
- */
-#define WM5100_IN4L_ENA 0x0080 /* IN4L_ENA */
-#define WM5100_IN4L_ENA_MASK 0x0080 /* IN4L_ENA */
-#define WM5100_IN4L_ENA_SHIFT 7 /* IN4L_ENA */
-#define WM5100_IN4L_ENA_WIDTH 1 /* IN4L_ENA */
-#define WM5100_IN4R_ENA 0x0040 /* IN4R_ENA */
-#define WM5100_IN4R_ENA_MASK 0x0040 /* IN4R_ENA */
-#define WM5100_IN4R_ENA_SHIFT 6 /* IN4R_ENA */
-#define WM5100_IN4R_ENA_WIDTH 1 /* IN4R_ENA */
-#define WM5100_IN3L_ENA 0x0020 /* IN3L_ENA */
-#define WM5100_IN3L_ENA_MASK 0x0020 /* IN3L_ENA */
-#define WM5100_IN3L_ENA_SHIFT 5 /* IN3L_ENA */
-#define WM5100_IN3L_ENA_WIDTH 1 /* IN3L_ENA */
-#define WM5100_IN3R_ENA 0x0010 /* IN3R_ENA */
-#define WM5100_IN3R_ENA_MASK 0x0010 /* IN3R_ENA */
-#define WM5100_IN3R_ENA_SHIFT 4 /* IN3R_ENA */
-#define WM5100_IN3R_ENA_WIDTH 1 /* IN3R_ENA */
-#define WM5100_IN2L_ENA 0x0008 /* IN2L_ENA */
-#define WM5100_IN2L_ENA_MASK 0x0008 /* IN2L_ENA */
-#define WM5100_IN2L_ENA_SHIFT 3 /* IN2L_ENA */
-#define WM5100_IN2L_ENA_WIDTH 1 /* IN2L_ENA */
-#define WM5100_IN2R_ENA 0x0004 /* IN2R_ENA */
-#define WM5100_IN2R_ENA_MASK 0x0004 /* IN2R_ENA */
-#define WM5100_IN2R_ENA_SHIFT 2 /* IN2R_ENA */
-#define WM5100_IN2R_ENA_WIDTH 1 /* IN2R_ENA */
-#define WM5100_IN1L_ENA 0x0002 /* IN1L_ENA */
-#define WM5100_IN1L_ENA_MASK 0x0002 /* IN1L_ENA */
-#define WM5100_IN1L_ENA_SHIFT 1 /* IN1L_ENA */
-#define WM5100_IN1L_ENA_WIDTH 1 /* IN1L_ENA */
-#define WM5100_IN1R_ENA 0x0001 /* IN1R_ENA */
-#define WM5100_IN1R_ENA_MASK 0x0001 /* IN1R_ENA */
-#define WM5100_IN1R_ENA_SHIFT 0 /* IN1R_ENA */
-#define WM5100_IN1R_ENA_WIDTH 1 /* IN1R_ENA */
-
-/*
- * R770 (0x302) - Input Enables Status
- */
-#define WM5100_IN4L_ENA_STS 0x0080 /* IN4L_ENA_STS */
-#define WM5100_IN4L_ENA_STS_MASK 0x0080 /* IN4L_ENA_STS */
-#define WM5100_IN4L_ENA_STS_SHIFT 7 /* IN4L_ENA_STS */
-#define WM5100_IN4L_ENA_STS_WIDTH 1 /* IN4L_ENA_STS */
-#define WM5100_IN4R_ENA_STS 0x0040 /* IN4R_ENA_STS */
-#define WM5100_IN4R_ENA_STS_MASK 0x0040 /* IN4R_ENA_STS */
-#define WM5100_IN4R_ENA_STS_SHIFT 6 /* IN4R_ENA_STS */
-#define WM5100_IN4R_ENA_STS_WIDTH 1 /* IN4R_ENA_STS */
-#define WM5100_IN3L_ENA_STS 0x0020 /* IN3L_ENA_STS */
-#define WM5100_IN3L_ENA_STS_MASK 0x0020 /* IN3L_ENA_STS */
-#define WM5100_IN3L_ENA_STS_SHIFT 5 /* IN3L_ENA_STS */
-#define WM5100_IN3L_ENA_STS_WIDTH 1 /* IN3L_ENA_STS */
-#define WM5100_IN3R_ENA_STS 0x0010 /* IN3R_ENA_STS */
-#define WM5100_IN3R_ENA_STS_MASK 0x0010 /* IN3R_ENA_STS */
-#define WM5100_IN3R_ENA_STS_SHIFT 4 /* IN3R_ENA_STS */
-#define WM5100_IN3R_ENA_STS_WIDTH 1 /* IN3R_ENA_STS */
-#define WM5100_IN2L_ENA_STS 0x0008 /* IN2L_ENA_STS */
-#define WM5100_IN2L_ENA_STS_MASK 0x0008 /* IN2L_ENA_STS */
-#define WM5100_IN2L_ENA_STS_SHIFT 3 /* IN2L_ENA_STS */
-#define WM5100_IN2L_ENA_STS_WIDTH 1 /* IN2L_ENA_STS */
-#define WM5100_IN2R_ENA_STS 0x0004 /* IN2R_ENA_STS */
-#define WM5100_IN2R_ENA_STS_MASK 0x0004 /* IN2R_ENA_STS */
-#define WM5100_IN2R_ENA_STS_SHIFT 2 /* IN2R_ENA_STS */
-#define WM5100_IN2R_ENA_STS_WIDTH 1 /* IN2R_ENA_STS */
-#define WM5100_IN1L_ENA_STS 0x0002 /* IN1L_ENA_STS */
-#define WM5100_IN1L_ENA_STS_MASK 0x0002 /* IN1L_ENA_STS */
-#define WM5100_IN1L_ENA_STS_SHIFT 1 /* IN1L_ENA_STS */
-#define WM5100_IN1L_ENA_STS_WIDTH 1 /* IN1L_ENA_STS */
-#define WM5100_IN1R_ENA_STS 0x0001 /* IN1R_ENA_STS */
-#define WM5100_IN1R_ENA_STS_MASK 0x0001 /* IN1R_ENA_STS */
-#define WM5100_IN1R_ENA_STS_SHIFT 0 /* IN1R_ENA_STS */
-#define WM5100_IN1R_ENA_STS_WIDTH 1 /* IN1R_ENA_STS */
-
-/*
- * R784 (0x310) - IN1L Control
- */
-#define WM5100_IN_RATE_MASK 0xC000 /* IN_RATE - [15:14] */
-#define WM5100_IN_RATE_SHIFT 14 /* IN_RATE - [15:14] */
-#define WM5100_IN_RATE_WIDTH 2 /* IN_RATE - [15:14] */
-#define WM5100_IN1_OSR 0x2000 /* IN1_OSR */
-#define WM5100_IN1_OSR_MASK 0x2000 /* IN1_OSR */
-#define WM5100_IN1_OSR_SHIFT 13 /* IN1_OSR */
-#define WM5100_IN1_OSR_WIDTH 1 /* IN1_OSR */
-#define WM5100_IN1_DMIC_SUP_MASK 0x1800 /* IN1_DMIC_SUP - [12:11] */
-#define WM5100_IN1_DMIC_SUP_SHIFT 11 /* IN1_DMIC_SUP - [12:11] */
-#define WM5100_IN1_DMIC_SUP_WIDTH 2 /* IN1_DMIC_SUP - [12:11] */
-#define WM5100_IN1_MODE_MASK 0x0600 /* IN1_MODE - [10:9] */
-#define WM5100_IN1_MODE_SHIFT 9 /* IN1_MODE - [10:9] */
-#define WM5100_IN1_MODE_WIDTH 2 /* IN1_MODE - [10:9] */
-#define WM5100_IN1L_PGA_VOL_MASK 0x00FE /* IN1L_PGA_VOL - [7:1] */
-#define WM5100_IN1L_PGA_VOL_SHIFT 1 /* IN1L_PGA_VOL - [7:1] */
-#define WM5100_IN1L_PGA_VOL_WIDTH 7 /* IN1L_PGA_VOL - [7:1] */
-
-/*
- * R785 (0x311) - IN1R Control
- */
-#define WM5100_IN1R_PGA_VOL_MASK 0x00FE /* IN1R_PGA_VOL - [7:1] */
-#define WM5100_IN1R_PGA_VOL_SHIFT 1 /* IN1R_PGA_VOL - [7:1] */
-#define WM5100_IN1R_PGA_VOL_WIDTH 7 /* IN1R_PGA_VOL - [7:1] */
-
-/*
- * R786 (0x312) - IN2L Control
- */
-#define WM5100_IN2_OSR 0x2000 /* IN2_OSR */
-#define WM5100_IN2_OSR_MASK 0x2000 /* IN2_OSR */
-#define WM5100_IN2_OSR_SHIFT 13 /* IN2_OSR */
-#define WM5100_IN2_OSR_WIDTH 1 /* IN2_OSR */
-#define WM5100_IN2_DMIC_SUP_MASK 0x1800 /* IN2_DMIC_SUP - [12:11] */
-#define WM5100_IN2_DMIC_SUP_SHIFT 11 /* IN2_DMIC_SUP - [12:11] */
-#define WM5100_IN2_DMIC_SUP_WIDTH 2 /* IN2_DMIC_SUP - [12:11] */
-#define WM5100_IN2_MODE_MASK 0x0600 /* IN2_MODE - [10:9] */
-#define WM5100_IN2_MODE_SHIFT 9 /* IN2_MODE - [10:9] */
-#define WM5100_IN2_MODE_WIDTH 2 /* IN2_MODE - [10:9] */
-#define WM5100_IN2L_PGA_VOL_MASK 0x00FE /* IN2L_PGA_VOL - [7:1] */
-#define WM5100_IN2L_PGA_VOL_SHIFT 1 /* IN2L_PGA_VOL - [7:1] */
-#define WM5100_IN2L_PGA_VOL_WIDTH 7 /* IN2L_PGA_VOL - [7:1] */
-
-/*
- * R787 (0x313) - IN2R Control
- */
-#define WM5100_IN2R_PGA_VOL_MASK 0x00FE /* IN2R_PGA_VOL - [7:1] */
-#define WM5100_IN2R_PGA_VOL_SHIFT 1 /* IN2R_PGA_VOL - [7:1] */
-#define WM5100_IN2R_PGA_VOL_WIDTH 7 /* IN2R_PGA_VOL - [7:1] */
-
-/*
- * R788 (0x314) - IN3L Control
- */
-#define WM5100_IN3_OSR 0x2000 /* IN3_OSR */
-#define WM5100_IN3_OSR_MASK 0x2000 /* IN3_OSR */
-#define WM5100_IN3_OSR_SHIFT 13 /* IN3_OSR */
-#define WM5100_IN3_OSR_WIDTH 1 /* IN3_OSR */
-#define WM5100_IN3_DMIC_SUP_MASK 0x1800 /* IN3_DMIC_SUP - [12:11] */
-#define WM5100_IN3_DMIC_SUP_SHIFT 11 /* IN3_DMIC_SUP - [12:11] */
-#define WM5100_IN3_DMIC_SUP_WIDTH 2 /* IN3_DMIC_SUP - [12:11] */
-#define WM5100_IN3_MODE_MASK 0x0600 /* IN3_MODE - [10:9] */
-#define WM5100_IN3_MODE_SHIFT 9 /* IN3_MODE - [10:9] */
-#define WM5100_IN3_MODE_WIDTH 2 /* IN3_MODE - [10:9] */
-#define WM5100_IN3L_PGA_VOL_MASK 0x00FE /* IN3L_PGA_VOL - [7:1] */
-#define WM5100_IN3L_PGA_VOL_SHIFT 1 /* IN3L_PGA_VOL - [7:1] */
-#define WM5100_IN3L_PGA_VOL_WIDTH 7 /* IN3L_PGA_VOL - [7:1] */
-
-/*
- * R789 (0x315) - IN3R Control
- */
-#define WM5100_IN3R_PGA_VOL_MASK 0x00FE /* IN3R_PGA_VOL - [7:1] */
-#define WM5100_IN3R_PGA_VOL_SHIFT 1 /* IN3R_PGA_VOL - [7:1] */
-#define WM5100_IN3R_PGA_VOL_WIDTH 7 /* IN3R_PGA_VOL - [7:1] */
-
-/*
- * R790 (0x316) - IN4L Control
- */
-#define WM5100_IN4_OSR 0x2000 /* IN4_OSR */
-#define WM5100_IN4_OSR_MASK 0x2000 /* IN4_OSR */
-#define WM5100_IN4_OSR_SHIFT 13 /* IN4_OSR */
-#define WM5100_IN4_OSR_WIDTH 1 /* IN4_OSR */
-#define WM5100_IN4_DMIC_SUP_MASK 0x1800 /* IN4_DMIC_SUP - [12:11] */
-#define WM5100_IN4_DMIC_SUP_SHIFT 11 /* IN4_DMIC_SUP - [12:11] */
-#define WM5100_IN4_DMIC_SUP_WIDTH 2 /* IN4_DMIC_SUP - [12:11] */
-#define WM5100_IN4_MODE_MASK 0x0600 /* IN4_MODE - [10:9] */
-#define WM5100_IN4_MODE_SHIFT 9 /* IN4_MODE - [10:9] */
-#define WM5100_IN4_MODE_WIDTH 2 /* IN4_MODE - [10:9] */
-#define WM5100_IN4L_PGA_VOL_MASK 0x00FE /* IN4L_PGA_VOL - [7:1] */
-#define WM5100_IN4L_PGA_VOL_SHIFT 1 /* IN4L_PGA_VOL - [7:1] */
-#define WM5100_IN4L_PGA_VOL_WIDTH 7 /* IN4L_PGA_VOL - [7:1] */
-
-/*
- * R791 (0x317) - IN4R Control
- */
-#define WM5100_IN4R_PGA_VOL_MASK 0x00FE /* IN4R_PGA_VOL - [7:1] */
-#define WM5100_IN4R_PGA_VOL_SHIFT 1 /* IN4R_PGA_VOL - [7:1] */
-#define WM5100_IN4R_PGA_VOL_WIDTH 7 /* IN4R_PGA_VOL - [7:1] */
-
-/*
- * R792 (0x318) - RXANC_SRC
- */
-#define WM5100_IN_RXANC_SEL_MASK 0x0007 /* IN_RXANC_SEL - [2:0] */
-#define WM5100_IN_RXANC_SEL_SHIFT 0 /* IN_RXANC_SEL - [2:0] */
-#define WM5100_IN_RXANC_SEL_WIDTH 3 /* IN_RXANC_SEL - [2:0] */
-
-/*
- * R793 (0x319) - Input Volume Ramp
- */
-#define WM5100_IN_VD_RAMP_MASK 0x0070 /* IN_VD_RAMP - [6:4] */
-#define WM5100_IN_VD_RAMP_SHIFT 4 /* IN_VD_RAMP - [6:4] */
-#define WM5100_IN_VD_RAMP_WIDTH 3 /* IN_VD_RAMP - [6:4] */
-#define WM5100_IN_VI_RAMP_MASK 0x0007 /* IN_VI_RAMP - [2:0] */
-#define WM5100_IN_VI_RAMP_SHIFT 0 /* IN_VI_RAMP - [2:0] */
-#define WM5100_IN_VI_RAMP_WIDTH 3 /* IN_VI_RAMP - [2:0] */
-
-/*
- * R800 (0x320) - ADC Digital Volume 1L
- */
-#define WM5100_IN_VU 0x0200 /* IN_VU */
-#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
-#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
-#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
-#define WM5100_IN1L_MUTE 0x0100 /* IN1L_MUTE */
-#define WM5100_IN1L_MUTE_MASK 0x0100 /* IN1L_MUTE */
-#define WM5100_IN1L_MUTE_SHIFT 8 /* IN1L_MUTE */
-#define WM5100_IN1L_MUTE_WIDTH 1 /* IN1L_MUTE */
-#define WM5100_IN1L_VOL_MASK 0x00FF /* IN1L_VOL - [7:0] */
-#define WM5100_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [7:0] */
-#define WM5100_IN1L_VOL_WIDTH 8 /* IN1L_VOL - [7:0] */
-
-/*
- * R801 (0x321) - ADC Digital Volume 1R
- */
-#define WM5100_IN_VU 0x0200 /* IN_VU */
-#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
-#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
-#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
-#define WM5100_IN1R_MUTE 0x0100 /* IN1R_MUTE */
-#define WM5100_IN1R_MUTE_MASK 0x0100 /* IN1R_MUTE */
-#define WM5100_IN1R_MUTE_SHIFT 8 /* IN1R_MUTE */
-#define WM5100_IN1R_MUTE_WIDTH 1 /* IN1R_MUTE */
-#define WM5100_IN1R_VOL_MASK 0x00FF /* IN1R_VOL - [7:0] */
-#define WM5100_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [7:0] */
-#define WM5100_IN1R_VOL_WIDTH 8 /* IN1R_VOL - [7:0] */
-
-/*
- * R802 (0x322) - ADC Digital Volume 2L
- */
-#define WM5100_IN_VU 0x0200 /* IN_VU */
-#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
-#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
-#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
-#define WM5100_IN2L_MUTE 0x0100 /* IN2L_MUTE */
-#define WM5100_IN2L_MUTE_MASK 0x0100 /* IN2L_MUTE */
-#define WM5100_IN2L_MUTE_SHIFT 8 /* IN2L_MUTE */
-#define WM5100_IN2L_MUTE_WIDTH 1 /* IN2L_MUTE */
-#define WM5100_IN2L_VOL_MASK 0x00FF /* IN2L_VOL - [7:0] */
-#define WM5100_IN2L_VOL_SHIFT 0 /* IN2L_VOL - [7:0] */
-#define WM5100_IN2L_VOL_WIDTH 8 /* IN2L_VOL - [7:0] */
-
-/*
- * R803 (0x323) - ADC Digital Volume 2R
- */
-#define WM5100_IN_VU 0x0200 /* IN_VU */
-#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
-#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
-#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
-#define WM5100_IN2R_MUTE 0x0100 /* IN2R_MUTE */
-#define WM5100_IN2R_MUTE_MASK 0x0100 /* IN2R_MUTE */
-#define WM5100_IN2R_MUTE_SHIFT 8 /* IN2R_MUTE */
-#define WM5100_IN2R_MUTE_WIDTH 1 /* IN2R_MUTE */
-#define WM5100_IN2R_VOL_MASK 0x00FF /* IN2R_VOL - [7:0] */
-#define WM5100_IN2R_VOL_SHIFT 0 /* IN2R_VOL - [7:0] */
-#define WM5100_IN2R_VOL_WIDTH 8 /* IN2R_VOL - [7:0] */
-
-/*
- * R804 (0x324) - ADC Digital Volume 3L
- */
-#define WM5100_IN_VU 0x0200 /* IN_VU */
-#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
-#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
-#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
-#define WM5100_IN3L_MUTE 0x0100 /* IN3L_MUTE */
-#define WM5100_IN3L_MUTE_MASK 0x0100 /* IN3L_MUTE */
-#define WM5100_IN3L_MUTE_SHIFT 8 /* IN3L_MUTE */
-#define WM5100_IN3L_MUTE_WIDTH 1 /* IN3L_MUTE */
-#define WM5100_IN3L_VOL_MASK 0x00FF /* IN3L_VOL - [7:0] */
-#define WM5100_IN3L_VOL_SHIFT 0 /* IN3L_VOL - [7:0] */
-#define WM5100_IN3L_VOL_WIDTH 8 /* IN3L_VOL - [7:0] */
-
-/*
- * R805 (0x325) - ADC Digital Volume 3R
- */
-#define WM5100_IN_VU 0x0200 /* IN_VU */
-#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
-#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
-#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
-#define WM5100_IN3R_MUTE 0x0100 /* IN3R_MUTE */
-#define WM5100_IN3R_MUTE_MASK 0x0100 /* IN3R_MUTE */
-#define WM5100_IN3R_MUTE_SHIFT 8 /* IN3R_MUTE */
-#define WM5100_IN3R_MUTE_WIDTH 1 /* IN3R_MUTE */
-#define WM5100_IN3R_VOL_MASK 0x00FF /* IN3R_VOL - [7:0] */
-#define WM5100_IN3R_VOL_SHIFT 0 /* IN3R_VOL - [7:0] */
-#define WM5100_IN3R_VOL_WIDTH 8 /* IN3R_VOL - [7:0] */
-
-/*
- * R806 (0x326) - ADC Digital Volume 4L
- */
-#define WM5100_IN_VU 0x0200 /* IN_VU */
-#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
-#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
-#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
-#define WM5100_IN4L_MUTE 0x0100 /* IN4L_MUTE */
-#define WM5100_IN4L_MUTE_MASK 0x0100 /* IN4L_MUTE */
-#define WM5100_IN4L_MUTE_SHIFT 8 /* IN4L_MUTE */
-#define WM5100_IN4L_MUTE_WIDTH 1 /* IN4L_MUTE */
-#define WM5100_IN4L_VOL_MASK 0x00FF /* IN4L_VOL - [7:0] */
-#define WM5100_IN4L_VOL_SHIFT 0 /* IN4L_VOL - [7:0] */
-#define WM5100_IN4L_VOL_WIDTH 8 /* IN4L_VOL - [7:0] */
-
-/*
- * R807 (0x327) - ADC Digital Volume 4R
- */
-#define WM5100_IN_VU 0x0200 /* IN_VU */
-#define WM5100_IN_VU_MASK 0x0200 /* IN_VU */
-#define WM5100_IN_VU_SHIFT 9 /* IN_VU */
-#define WM5100_IN_VU_WIDTH 1 /* IN_VU */
-#define WM5100_IN4R_MUTE 0x0100 /* IN4R_MUTE */
-#define WM5100_IN4R_MUTE_MASK 0x0100 /* IN4R_MUTE */
-#define WM5100_IN4R_MUTE_SHIFT 8 /* IN4R_MUTE */
-#define WM5100_IN4R_MUTE_WIDTH 1 /* IN4R_MUTE */
-#define WM5100_IN4R_VOL_MASK 0x00FF /* IN4R_VOL - [7:0] */
-#define WM5100_IN4R_VOL_SHIFT 0 /* IN4R_VOL - [7:0] */
-#define WM5100_IN4R_VOL_WIDTH 8 /* IN4R_VOL - [7:0] */
-
-/*
- * R1025 (0x401) - Output Enables 2
- */
-#define WM5100_OUT6L_ENA 0x0800 /* OUT6L_ENA */
-#define WM5100_OUT6L_ENA_MASK 0x0800 /* OUT6L_ENA */
-#define WM5100_OUT6L_ENA_SHIFT 11 /* OUT6L_ENA */
-#define WM5100_OUT6L_ENA_WIDTH 1 /* OUT6L_ENA */
-#define WM5100_OUT6R_ENA 0x0400 /* OUT6R_ENA */
-#define WM5100_OUT6R_ENA_MASK 0x0400 /* OUT6R_ENA */
-#define WM5100_OUT6R_ENA_SHIFT 10 /* OUT6R_ENA */
-#define WM5100_OUT6R_ENA_WIDTH 1 /* OUT6R_ENA */
-#define WM5100_OUT5L_ENA 0x0200 /* OUT5L_ENA */
-#define WM5100_OUT5L_ENA_MASK 0x0200 /* OUT5L_ENA */
-#define WM5100_OUT5L_ENA_SHIFT 9 /* OUT5L_ENA */
-#define WM5100_OUT5L_ENA_WIDTH 1 /* OUT5L_ENA */
-#define WM5100_OUT5R_ENA 0x0100 /* OUT5R_ENA */
-#define WM5100_OUT5R_ENA_MASK 0x0100 /* OUT5R_ENA */
-#define WM5100_OUT5R_ENA_SHIFT 8 /* OUT5R_ENA */
-#define WM5100_OUT5R_ENA_WIDTH 1 /* OUT5R_ENA */
-#define WM5100_OUT4L_ENA 0x0080 /* OUT4L_ENA */
-#define WM5100_OUT4L_ENA_MASK 0x0080 /* OUT4L_ENA */
-#define WM5100_OUT4L_ENA_SHIFT 7 /* OUT4L_ENA */
-#define WM5100_OUT4L_ENA_WIDTH 1 /* OUT4L_ENA */
-#define WM5100_OUT4R_ENA 0x0040 /* OUT4R_ENA */
-#define WM5100_OUT4R_ENA_MASK 0x0040 /* OUT4R_ENA */
-#define WM5100_OUT4R_ENA_SHIFT 6 /* OUT4R_ENA */
-#define WM5100_OUT4R_ENA_WIDTH 1 /* OUT4R_ENA */
-
-/*
- * R1026 (0x402) - Output Status 1
- */
-#define WM5100_OUT3L_ENA_STS 0x0020 /* OUT3L_ENA_STS */
-#define WM5100_OUT3L_ENA_STS_MASK 0x0020 /* OUT3L_ENA_STS */
-#define WM5100_OUT3L_ENA_STS_SHIFT 5 /* OUT3L_ENA_STS */
-#define WM5100_OUT3L_ENA_STS_WIDTH 1 /* OUT3L_ENA_STS */
-#define WM5100_OUT3R_ENA_STS 0x0010 /* OUT3R_ENA_STS */
-#define WM5100_OUT3R_ENA_STS_MASK 0x0010 /* OUT3R_ENA_STS */
-#define WM5100_OUT3R_ENA_STS_SHIFT 4 /* OUT3R_ENA_STS */
-#define WM5100_OUT3R_ENA_STS_WIDTH 1 /* OUT3R_ENA_STS */
-#define WM5100_OUT2L_ENA_STS 0x0008 /* OUT2L_ENA_STS */
-#define WM5100_OUT2L_ENA_STS_MASK 0x0008 /* OUT2L_ENA_STS */
-#define WM5100_OUT2L_ENA_STS_SHIFT 3 /* OUT2L_ENA_STS */
-#define WM5100_OUT2L_ENA_STS_WIDTH 1 /* OUT2L_ENA_STS */
-#define WM5100_OUT2R_ENA_STS 0x0004 /* OUT2R_ENA_STS */
-#define WM5100_OUT2R_ENA_STS_MASK 0x0004 /* OUT2R_ENA_STS */
-#define WM5100_OUT2R_ENA_STS_SHIFT 2 /* OUT2R_ENA_STS */
-#define WM5100_OUT2R_ENA_STS_WIDTH 1 /* OUT2R_ENA_STS */
-#define WM5100_OUT1L_ENA_STS 0x0002 /* OUT1L_ENA_STS */
-#define WM5100_OUT1L_ENA_STS_MASK 0x0002 /* OUT1L_ENA_STS */
-#define WM5100_OUT1L_ENA_STS_SHIFT 1 /* OUT1L_ENA_STS */
-#define WM5100_OUT1L_ENA_STS_WIDTH 1 /* OUT1L_ENA_STS */
-#define WM5100_OUT1R_ENA_STS 0x0001 /* OUT1R_ENA_STS */
-#define WM5100_OUT1R_ENA_STS_MASK 0x0001 /* OUT1R_ENA_STS */
-#define WM5100_OUT1R_ENA_STS_SHIFT 0 /* OUT1R_ENA_STS */
-#define WM5100_OUT1R_ENA_STS_WIDTH 1 /* OUT1R_ENA_STS */
-
-/*
- * R1027 (0x403) - Output Status 2
- */
-#define WM5100_OUT6L_ENA_STS 0x0800 /* OUT6L_ENA_STS */
-#define WM5100_OUT6L_ENA_STS_MASK 0x0800 /* OUT6L_ENA_STS */
-#define WM5100_OUT6L_ENA_STS_SHIFT 11 /* OUT6L_ENA_STS */
-#define WM5100_OUT6L_ENA_STS_WIDTH 1 /* OUT6L_ENA_STS */
-#define WM5100_OUT6R_ENA_STS 0x0400 /* OUT6R_ENA_STS */
-#define WM5100_OUT6R_ENA_STS_MASK 0x0400 /* OUT6R_ENA_STS */
-#define WM5100_OUT6R_ENA_STS_SHIFT 10 /* OUT6R_ENA_STS */
-#define WM5100_OUT6R_ENA_STS_WIDTH 1 /* OUT6R_ENA_STS */
-#define WM5100_OUT5L_ENA_STS 0x0200 /* OUT5L_ENA_STS */
-#define WM5100_OUT5L_ENA_STS_MASK 0x0200 /* OUT5L_ENA_STS */
-#define WM5100_OUT5L_ENA_STS_SHIFT 9 /* OUT5L_ENA_STS */
-#define WM5100_OUT5L_ENA_STS_WIDTH 1 /* OUT5L_ENA_STS */
-#define WM5100_OUT5R_ENA_STS 0x0100 /* OUT5R_ENA_STS */
-#define WM5100_OUT5R_ENA_STS_MASK 0x0100 /* OUT5R_ENA_STS */
-#define WM5100_OUT5R_ENA_STS_SHIFT 8 /* OUT5R_ENA_STS */
-#define WM5100_OUT5R_ENA_STS_WIDTH 1 /* OUT5R_ENA_STS */
-#define WM5100_OUT4L_ENA_STS 0x0080 /* OUT4L_ENA_STS */
-#define WM5100_OUT4L_ENA_STS_MASK 0x0080 /* OUT4L_ENA_STS */
-#define WM5100_OUT4L_ENA_STS_SHIFT 7 /* OUT4L_ENA_STS */
-#define WM5100_OUT4L_ENA_STS_WIDTH 1 /* OUT4L_ENA_STS */
-#define WM5100_OUT4R_ENA_STS 0x0040 /* OUT4R_ENA_STS */
-#define WM5100_OUT4R_ENA_STS_MASK 0x0040 /* OUT4R_ENA_STS */
-#define WM5100_OUT4R_ENA_STS_SHIFT 6 /* OUT4R_ENA_STS */
-#define WM5100_OUT4R_ENA_STS_WIDTH 1 /* OUT4R_ENA_STS */
-
-/*
- * R1032 (0x408) - Channel Enables 1
- */
-#define WM5100_HP3L_ENA 0x0020 /* HP3L_ENA */
-#define WM5100_HP3L_ENA_MASK 0x0020 /* HP3L_ENA */
-#define WM5100_HP3L_ENA_SHIFT 5 /* HP3L_ENA */
-#define WM5100_HP3L_ENA_WIDTH 1 /* HP3L_ENA */
-#define WM5100_HP3R_ENA 0x0010 /* HP3R_ENA */
-#define WM5100_HP3R_ENA_MASK 0x0010 /* HP3R_ENA */
-#define WM5100_HP3R_ENA_SHIFT 4 /* HP3R_ENA */
-#define WM5100_HP3R_ENA_WIDTH 1 /* HP3R_ENA */
-#define WM5100_HP2L_ENA 0x0008 /* HP2L_ENA */
-#define WM5100_HP2L_ENA_MASK 0x0008 /* HP2L_ENA */
-#define WM5100_HP2L_ENA_SHIFT 3 /* HP2L_ENA */
-#define WM5100_HP2L_ENA_WIDTH 1 /* HP2L_ENA */
-#define WM5100_HP2R_ENA 0x0004 /* HP2R_ENA */
-#define WM5100_HP2R_ENA_MASK 0x0004 /* HP2R_ENA */
-#define WM5100_HP2R_ENA_SHIFT 2 /* HP2R_ENA */
-#define WM5100_HP2R_ENA_WIDTH 1 /* HP2R_ENA */
-#define WM5100_HP1L_ENA 0x0002 /* HP1L_ENA */
-#define WM5100_HP1L_ENA_MASK 0x0002 /* HP1L_ENA */
-#define WM5100_HP1L_ENA_SHIFT 1 /* HP1L_ENA */
-#define WM5100_HP1L_ENA_WIDTH 1 /* HP1L_ENA */
-#define WM5100_HP1R_ENA 0x0001 /* HP1R_ENA */
-#define WM5100_HP1R_ENA_MASK 0x0001 /* HP1R_ENA */
-#define WM5100_HP1R_ENA_SHIFT 0 /* HP1R_ENA */
-#define WM5100_HP1R_ENA_WIDTH 1 /* HP1R_ENA */
-
-/*
- * R1040 (0x410) - Out Volume 1L
- */
-#define WM5100_OUT_RATE_MASK 0xC000 /* OUT_RATE - [15:14] */
-#define WM5100_OUT_RATE_SHIFT 14 /* OUT_RATE - [15:14] */
-#define WM5100_OUT_RATE_WIDTH 2 /* OUT_RATE - [15:14] */
-#define WM5100_OUT1_OSR 0x2000 /* OUT1_OSR */
-#define WM5100_OUT1_OSR_MASK 0x2000 /* OUT1_OSR */
-#define WM5100_OUT1_OSR_SHIFT 13 /* OUT1_OSR */
-#define WM5100_OUT1_OSR_WIDTH 1 /* OUT1_OSR */
-#define WM5100_OUT1_MONO 0x1000 /* OUT1_MONO */
-#define WM5100_OUT1_MONO_MASK 0x1000 /* OUT1_MONO */
-#define WM5100_OUT1_MONO_SHIFT 12 /* OUT1_MONO */
-#define WM5100_OUT1_MONO_WIDTH 1 /* OUT1_MONO */
-#define WM5100_OUT1L_ANC_SRC 0x0800 /* OUT1L_ANC_SRC */
-#define WM5100_OUT1L_ANC_SRC_MASK 0x0800 /* OUT1L_ANC_SRC */
-#define WM5100_OUT1L_ANC_SRC_SHIFT 11 /* OUT1L_ANC_SRC */
-#define WM5100_OUT1L_ANC_SRC_WIDTH 1 /* OUT1L_ANC_SRC */
-#define WM5100_OUT1L_PGA_VOL_MASK 0x00FE /* OUT1L_PGA_VOL - [7:1] */
-#define WM5100_OUT1L_PGA_VOL_SHIFT 1 /* OUT1L_PGA_VOL - [7:1] */
-#define WM5100_OUT1L_PGA_VOL_WIDTH 7 /* OUT1L_PGA_VOL - [7:1] */
-
-/*
- * R1041 (0x411) - Out Volume 1R
- */
-#define WM5100_OUT1R_ANC_SRC 0x0800 /* OUT1R_ANC_SRC */
-#define WM5100_OUT1R_ANC_SRC_MASK 0x0800 /* OUT1R_ANC_SRC */
-#define WM5100_OUT1R_ANC_SRC_SHIFT 11 /* OUT1R_ANC_SRC */
-#define WM5100_OUT1R_ANC_SRC_WIDTH 1 /* OUT1R_ANC_SRC */
-#define WM5100_OUT1R_PGA_VOL_MASK 0x00FE /* OUT1R_PGA_VOL - [7:1] */
-#define WM5100_OUT1R_PGA_VOL_SHIFT 1 /* OUT1R_PGA_VOL - [7:1] */
-#define WM5100_OUT1R_PGA_VOL_WIDTH 7 /* OUT1R_PGA_VOL - [7:1] */
-
-/*
- * R1042 (0x412) - DAC Volume Limit 1L
- */
-#define WM5100_OUT1L_VOL_LIM_MASK 0x00FF /* OUT1L_VOL_LIM - [7:0] */
-#define WM5100_OUT1L_VOL_LIM_SHIFT 0 /* OUT1L_VOL_LIM - [7:0] */
-#define WM5100_OUT1L_VOL_LIM_WIDTH 8 /* OUT1L_VOL_LIM - [7:0] */
-
-/*
- * R1043 (0x413) - DAC Volume Limit 1R
- */
-#define WM5100_OUT1R_VOL_LIM_MASK 0x00FF /* OUT1R_VOL_LIM - [7:0] */
-#define WM5100_OUT1R_VOL_LIM_SHIFT 0 /* OUT1R_VOL_LIM - [7:0] */
-#define WM5100_OUT1R_VOL_LIM_WIDTH 8 /* OUT1R_VOL_LIM - [7:0] */
-
-/*
- * R1044 (0x414) - Out Volume 2L
- */
-#define WM5100_OUT2_OSR 0x2000 /* OUT2_OSR */
-#define WM5100_OUT2_OSR_MASK 0x2000 /* OUT2_OSR */
-#define WM5100_OUT2_OSR_SHIFT 13 /* OUT2_OSR */
-#define WM5100_OUT2_OSR_WIDTH 1 /* OUT2_OSR */
-#define WM5100_OUT2_MONO 0x1000 /* OUT2_MONO */
-#define WM5100_OUT2_MONO_MASK 0x1000 /* OUT2_MONO */
-#define WM5100_OUT2_MONO_SHIFT 12 /* OUT2_MONO */
-#define WM5100_OUT2_MONO_WIDTH 1 /* OUT2_MONO */
-#define WM5100_OUT2L_ANC_SRC 0x0800 /* OUT2L_ANC_SRC */
-#define WM5100_OUT2L_ANC_SRC_MASK 0x0800 /* OUT2L_ANC_SRC */
-#define WM5100_OUT2L_ANC_SRC_SHIFT 11 /* OUT2L_ANC_SRC */
-#define WM5100_OUT2L_ANC_SRC_WIDTH 1 /* OUT2L_ANC_SRC */
-#define WM5100_OUT2L_PGA_VOL_MASK 0x00FE /* OUT2L_PGA_VOL - [7:1] */
-#define WM5100_OUT2L_PGA_VOL_SHIFT 1 /* OUT2L_PGA_VOL - [7:1] */
-#define WM5100_OUT2L_PGA_VOL_WIDTH 7 /* OUT2L_PGA_VOL - [7:1] */
-
-/*
- * R1045 (0x415) - Out Volume 2R
- */
-#define WM5100_OUT2R_ANC_SRC 0x0800 /* OUT2R_ANC_SRC */
-#define WM5100_OUT2R_ANC_SRC_MASK 0x0800 /* OUT2R_ANC_SRC */
-#define WM5100_OUT2R_ANC_SRC_SHIFT 11 /* OUT2R_ANC_SRC */
-#define WM5100_OUT2R_ANC_SRC_WIDTH 1 /* OUT2R_ANC_SRC */
-#define WM5100_OUT2R_PGA_VOL_MASK 0x00FE /* OUT2R_PGA_VOL - [7:1] */
-#define WM5100_OUT2R_PGA_VOL_SHIFT 1 /* OUT2R_PGA_VOL - [7:1] */
-#define WM5100_OUT2R_PGA_VOL_WIDTH 7 /* OUT2R_PGA_VOL - [7:1] */
-
-/*
- * R1046 (0x416) - DAC Volume Limit 2L
- */
-#define WM5100_OUT2L_VOL_LIM_MASK 0x00FF /* OUT2L_VOL_LIM - [7:0] */
-#define WM5100_OUT2L_VOL_LIM_SHIFT 0 /* OUT2L_VOL_LIM - [7:0] */
-#define WM5100_OUT2L_VOL_LIM_WIDTH 8 /* OUT2L_VOL_LIM - [7:0] */
-
-/*
- * R1047 (0x417) - DAC Volume Limit 2R
- */
-#define WM5100_OUT2R_VOL_LIM_MASK 0x00FF /* OUT2R_VOL_LIM - [7:0] */
-#define WM5100_OUT2R_VOL_LIM_SHIFT 0 /* OUT2R_VOL_LIM - [7:0] */
-#define WM5100_OUT2R_VOL_LIM_WIDTH 8 /* OUT2R_VOL_LIM - [7:0] */
-
-/*
- * R1048 (0x418) - Out Volume 3L
- */
-#define WM5100_OUT3_OSR 0x2000 /* OUT3_OSR */
-#define WM5100_OUT3_OSR_MASK 0x2000 /* OUT3_OSR */
-#define WM5100_OUT3_OSR_SHIFT 13 /* OUT3_OSR */
-#define WM5100_OUT3_OSR_WIDTH 1 /* OUT3_OSR */
-#define WM5100_OUT3_MONO 0x1000 /* OUT3_MONO */
-#define WM5100_OUT3_MONO_MASK 0x1000 /* OUT3_MONO */
-#define WM5100_OUT3_MONO_SHIFT 12 /* OUT3_MONO */
-#define WM5100_OUT3_MONO_WIDTH 1 /* OUT3_MONO */
-#define WM5100_OUT3L_ANC_SRC 0x0800 /* OUT3L_ANC_SRC */
-#define WM5100_OUT3L_ANC_SRC_MASK 0x0800 /* OUT3L_ANC_SRC */
-#define WM5100_OUT3L_ANC_SRC_SHIFT 11 /* OUT3L_ANC_SRC */
-#define WM5100_OUT3L_ANC_SRC_WIDTH 1 /* OUT3L_ANC_SRC */
-#define WM5100_OUT3L_PGA_VOL_MASK 0x00FE /* OUT3L_PGA_VOL - [7:1] */
-#define WM5100_OUT3L_PGA_VOL_SHIFT 1 /* OUT3L_PGA_VOL - [7:1] */
-#define WM5100_OUT3L_PGA_VOL_WIDTH 7 /* OUT3L_PGA_VOL - [7:1] */
-
-/*
- * R1049 (0x419) - Out Volume 3R
- */
-#define WM5100_OUT3R_ANC_SRC 0x0800 /* OUT3R_ANC_SRC */
-#define WM5100_OUT3R_ANC_SRC_MASK 0x0800 /* OUT3R_ANC_SRC */
-#define WM5100_OUT3R_ANC_SRC_SHIFT 11 /* OUT3R_ANC_SRC */
-#define WM5100_OUT3R_ANC_SRC_WIDTH 1 /* OUT3R_ANC_SRC */
-#define WM5100_OUT3R_PGA_VOL_MASK 0x00FE /* OUT3R_PGA_VOL - [7:1] */
-#define WM5100_OUT3R_PGA_VOL_SHIFT 1 /* OUT3R_PGA_VOL - [7:1] */
-#define WM5100_OUT3R_PGA_VOL_WIDTH 7 /* OUT3R_PGA_VOL - [7:1] */
-
-/*
- * R1050 (0x41A) - DAC Volume Limit 3L
- */
-#define WM5100_OUT3L_VOL_LIM_MASK 0x00FF /* OUT3L_VOL_LIM - [7:0] */
-#define WM5100_OUT3L_VOL_LIM_SHIFT 0 /* OUT3L_VOL_LIM - [7:0] */
-#define WM5100_OUT3L_VOL_LIM_WIDTH 8 /* OUT3L_VOL_LIM - [7:0] */
-
-/*
- * R1051 (0x41B) - DAC Volume Limit 3R
- */
-#define WM5100_OUT3R_VOL_LIM_MASK 0x00FF /* OUT3R_VOL_LIM - [7:0] */
-#define WM5100_OUT3R_VOL_LIM_SHIFT 0 /* OUT3R_VOL_LIM - [7:0] */
-#define WM5100_OUT3R_VOL_LIM_WIDTH 8 /* OUT3R_VOL_LIM - [7:0] */
-
-/*
- * R1052 (0x41C) - Out Volume 4L
- */
-#define WM5100_OUT4_OSR 0x2000 /* OUT4_OSR */
-#define WM5100_OUT4_OSR_MASK 0x2000 /* OUT4_OSR */
-#define WM5100_OUT4_OSR_SHIFT 13 /* OUT4_OSR */
-#define WM5100_OUT4_OSR_WIDTH 1 /* OUT4_OSR */
-#define WM5100_OUT4L_ANC_SRC 0x0800 /* OUT4L_ANC_SRC */
-#define WM5100_OUT4L_ANC_SRC_MASK 0x0800 /* OUT4L_ANC_SRC */
-#define WM5100_OUT4L_ANC_SRC_SHIFT 11 /* OUT4L_ANC_SRC */
-#define WM5100_OUT4L_ANC_SRC_WIDTH 1 /* OUT4L_ANC_SRC */
-#define WM5100_OUT4L_VOL_LIM_MASK 0x00FF /* OUT4L_VOL_LIM - [7:0] */
-#define WM5100_OUT4L_VOL_LIM_SHIFT 0 /* OUT4L_VOL_LIM - [7:0] */
-#define WM5100_OUT4L_VOL_LIM_WIDTH 8 /* OUT4L_VOL_LIM - [7:0] */
-
-/*
- * R1053 (0x41D) - Out Volume 4R
- */
-#define WM5100_OUT4R_ANC_SRC 0x0800 /* OUT4R_ANC_SRC */
-#define WM5100_OUT4R_ANC_SRC_MASK 0x0800 /* OUT4R_ANC_SRC */
-#define WM5100_OUT4R_ANC_SRC_SHIFT 11 /* OUT4R_ANC_SRC */
-#define WM5100_OUT4R_ANC_SRC_WIDTH 1 /* OUT4R_ANC_SRC */
-#define WM5100_OUT4R_VOL_LIM_MASK 0x00FF /* OUT4R_VOL_LIM - [7:0] */
-#define WM5100_OUT4R_VOL_LIM_SHIFT 0 /* OUT4R_VOL_LIM - [7:0] */
-#define WM5100_OUT4R_VOL_LIM_WIDTH 8 /* OUT4R_VOL_LIM - [7:0] */
-
-/*
- * R1054 (0x41E) - DAC Volume Limit 5L
- */
-#define WM5100_OUT5_OSR 0x2000 /* OUT5_OSR */
-#define WM5100_OUT5_OSR_MASK 0x2000 /* OUT5_OSR */
-#define WM5100_OUT5_OSR_SHIFT 13 /* OUT5_OSR */
-#define WM5100_OUT5_OSR_WIDTH 1 /* OUT5_OSR */
-#define WM5100_OUT5L_ANC_SRC 0x0800 /* OUT5L_ANC_SRC */
-#define WM5100_OUT5L_ANC_SRC_MASK 0x0800 /* OUT5L_ANC_SRC */
-#define WM5100_OUT5L_ANC_SRC_SHIFT 11 /* OUT5L_ANC_SRC */
-#define WM5100_OUT5L_ANC_SRC_WIDTH 1 /* OUT5L_ANC_SRC */
-#define WM5100_OUT5L_VOL_LIM_MASK 0x00FF /* OUT5L_VOL_LIM - [7:0] */
-#define WM5100_OUT5L_VOL_LIM_SHIFT 0 /* OUT5L_VOL_LIM - [7:0] */
-#define WM5100_OUT5L_VOL_LIM_WIDTH 8 /* OUT5L_VOL_LIM - [7:0] */
-
-/*
- * R1055 (0x41F) - DAC Volume Limit 5R
- */
-#define WM5100_OUT5R_ANC_SRC 0x0800 /* OUT5R_ANC_SRC */
-#define WM5100_OUT5R_ANC_SRC_MASK 0x0800 /* OUT5R_ANC_SRC */
-#define WM5100_OUT5R_ANC_SRC_SHIFT 11 /* OUT5R_ANC_SRC */
-#define WM5100_OUT5R_ANC_SRC_WIDTH 1 /* OUT5R_ANC_SRC */
-#define WM5100_OUT5R_VOL_LIM_MASK 0x00FF /* OUT5R_VOL_LIM - [7:0] */
-#define WM5100_OUT5R_VOL_LIM_SHIFT 0 /* OUT5R_VOL_LIM - [7:0] */
-#define WM5100_OUT5R_VOL_LIM_WIDTH 8 /* OUT5R_VOL_LIM - [7:0] */
-
-/*
- * R1056 (0x420) - DAC Volume Limit 6L
- */
-#define WM5100_OUT6_OSR 0x2000 /* OUT6_OSR */
-#define WM5100_OUT6_OSR_MASK 0x2000 /* OUT6_OSR */
-#define WM5100_OUT6_OSR_SHIFT 13 /* OUT6_OSR */
-#define WM5100_OUT6_OSR_WIDTH 1 /* OUT6_OSR */
-#define WM5100_OUT6L_ANC_SRC 0x0800 /* OUT6L_ANC_SRC */
-#define WM5100_OUT6L_ANC_SRC_MASK 0x0800 /* OUT6L_ANC_SRC */
-#define WM5100_OUT6L_ANC_SRC_SHIFT 11 /* OUT6L_ANC_SRC */
-#define WM5100_OUT6L_ANC_SRC_WIDTH 1 /* OUT6L_ANC_SRC */
-#define WM5100_OUT6L_VOL_LIM_MASK 0x00FF /* OUT6L_VOL_LIM - [7:0] */
-#define WM5100_OUT6L_VOL_LIM_SHIFT 0 /* OUT6L_VOL_LIM - [7:0] */
-#define WM5100_OUT6L_VOL_LIM_WIDTH 8 /* OUT6L_VOL_LIM - [7:0] */
-
-/*
- * R1057 (0x421) - DAC Volume Limit 6R
- */
-#define WM5100_OUT6R_ANC_SRC 0x0800 /* OUT6R_ANC_SRC */
-#define WM5100_OUT6R_ANC_SRC_MASK 0x0800 /* OUT6R_ANC_SRC */
-#define WM5100_OUT6R_ANC_SRC_SHIFT 11 /* OUT6R_ANC_SRC */
-#define WM5100_OUT6R_ANC_SRC_WIDTH 1 /* OUT6R_ANC_SRC */
-#define WM5100_OUT6R_VOL_LIM_MASK 0x00FF /* OUT6R_VOL_LIM - [7:0] */
-#define WM5100_OUT6R_VOL_LIM_SHIFT 0 /* OUT6R_VOL_LIM - [7:0] */
-#define WM5100_OUT6R_VOL_LIM_WIDTH 8 /* OUT6R_VOL_LIM - [7:0] */
-
-/*
- * R1088 (0x440) - DAC AEC Control 1
- */
-#define WM5100_AEC_LOOPBACK_SRC_MASK 0x003C /* AEC_LOOPBACK_SRC - [5:2] */
-#define WM5100_AEC_LOOPBACK_SRC_SHIFT 2 /* AEC_LOOPBACK_SRC - [5:2] */
-#define WM5100_AEC_LOOPBACK_SRC_WIDTH 4 /* AEC_LOOPBACK_SRC - [5:2] */
-#define WM5100_AEC_ENA_STS 0x0002 /* AEC_ENA_STS */
-#define WM5100_AEC_ENA_STS_MASK 0x0002 /* AEC_ENA_STS */
-#define WM5100_AEC_ENA_STS_SHIFT 1 /* AEC_ENA_STS */
-#define WM5100_AEC_ENA_STS_WIDTH 1 /* AEC_ENA_STS */
-#define WM5100_AEC_LOOPBACK_ENA 0x0001 /* AEC_LOOPBACK_ENA */
-#define WM5100_AEC_LOOPBACK_ENA_MASK 0x0001 /* AEC_LOOPBACK_ENA */
-#define WM5100_AEC_LOOPBACK_ENA_SHIFT 0 /* AEC_LOOPBACK_ENA */
-#define WM5100_AEC_LOOPBACK_ENA_WIDTH 1 /* AEC_LOOPBACK_ENA */
-
-/*
- * R1089 (0x441) - Output Volume Ramp
- */
-#define WM5100_OUT_VD_RAMP_MASK 0x0070 /* OUT_VD_RAMP - [6:4] */
-#define WM5100_OUT_VD_RAMP_SHIFT 4 /* OUT_VD_RAMP - [6:4] */
-#define WM5100_OUT_VD_RAMP_WIDTH 3 /* OUT_VD_RAMP - [6:4] */
-#define WM5100_OUT_VI_RAMP_MASK 0x0007 /* OUT_VI_RAMP - [2:0] */
-#define WM5100_OUT_VI_RAMP_SHIFT 0 /* OUT_VI_RAMP - [2:0] */
-#define WM5100_OUT_VI_RAMP_WIDTH 3 /* OUT_VI_RAMP - [2:0] */
-
-/*
- * R1152 (0x480) - DAC Digital Volume 1L
- */
-#define WM5100_OUT_VU 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
-#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
-#define WM5100_OUT1L_MUTE 0x0100 /* OUT1L_MUTE */
-#define WM5100_OUT1L_MUTE_MASK 0x0100 /* OUT1L_MUTE */
-#define WM5100_OUT1L_MUTE_SHIFT 8 /* OUT1L_MUTE */
-#define WM5100_OUT1L_MUTE_WIDTH 1 /* OUT1L_MUTE */
-#define WM5100_OUT1L_VOL_MASK 0x00FF /* OUT1L_VOL - [7:0] */
-#define WM5100_OUT1L_VOL_SHIFT 0 /* OUT1L_VOL - [7:0] */
-#define WM5100_OUT1L_VOL_WIDTH 8 /* OUT1L_VOL - [7:0] */
-
-/*
- * R1153 (0x481) - DAC Digital Volume 1R
- */
-#define WM5100_OUT_VU 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
-#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
-#define WM5100_OUT1R_MUTE 0x0100 /* OUT1R_MUTE */
-#define WM5100_OUT1R_MUTE_MASK 0x0100 /* OUT1R_MUTE */
-#define WM5100_OUT1R_MUTE_SHIFT 8 /* OUT1R_MUTE */
-#define WM5100_OUT1R_MUTE_WIDTH 1 /* OUT1R_MUTE */
-#define WM5100_OUT1R_VOL_MASK 0x00FF /* OUT1R_VOL - [7:0] */
-#define WM5100_OUT1R_VOL_SHIFT 0 /* OUT1R_VOL - [7:0] */
-#define WM5100_OUT1R_VOL_WIDTH 8 /* OUT1R_VOL - [7:0] */
-
-/*
- * R1154 (0x482) - DAC Digital Volume 2L
- */
-#define WM5100_OUT_VU 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
-#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
-#define WM5100_OUT2L_MUTE 0x0100 /* OUT2L_MUTE */
-#define WM5100_OUT2L_MUTE_MASK 0x0100 /* OUT2L_MUTE */
-#define WM5100_OUT2L_MUTE_SHIFT 8 /* OUT2L_MUTE */
-#define WM5100_OUT2L_MUTE_WIDTH 1 /* OUT2L_MUTE */
-#define WM5100_OUT2L_VOL_MASK 0x00FF /* OUT2L_VOL - [7:0] */
-#define WM5100_OUT2L_VOL_SHIFT 0 /* OUT2L_VOL - [7:0] */
-#define WM5100_OUT2L_VOL_WIDTH 8 /* OUT2L_VOL - [7:0] */
-
-/*
- * R1155 (0x483) - DAC Digital Volume 2R
- */
-#define WM5100_OUT_VU 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
-#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
-#define WM5100_OUT2R_MUTE 0x0100 /* OUT2R_MUTE */
-#define WM5100_OUT2R_MUTE_MASK 0x0100 /* OUT2R_MUTE */
-#define WM5100_OUT2R_MUTE_SHIFT 8 /* OUT2R_MUTE */
-#define WM5100_OUT2R_MUTE_WIDTH 1 /* OUT2R_MUTE */
-#define WM5100_OUT2R_VOL_MASK 0x00FF /* OUT2R_VOL - [7:0] */
-#define WM5100_OUT2R_VOL_SHIFT 0 /* OUT2R_VOL - [7:0] */
-#define WM5100_OUT2R_VOL_WIDTH 8 /* OUT2R_VOL - [7:0] */
-
-/*
- * R1156 (0x484) - DAC Digital Volume 3L
- */
-#define WM5100_OUT_VU 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
-#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
-#define WM5100_OUT3L_MUTE 0x0100 /* OUT3L_MUTE */
-#define WM5100_OUT3L_MUTE_MASK 0x0100 /* OUT3L_MUTE */
-#define WM5100_OUT3L_MUTE_SHIFT 8 /* OUT3L_MUTE */
-#define WM5100_OUT3L_MUTE_WIDTH 1 /* OUT3L_MUTE */
-#define WM5100_OUT3L_VOL_MASK 0x00FF /* OUT3L_VOL - [7:0] */
-#define WM5100_OUT3L_VOL_SHIFT 0 /* OUT3L_VOL - [7:0] */
-#define WM5100_OUT3L_VOL_WIDTH 8 /* OUT3L_VOL - [7:0] */
-
-/*
- * R1157 (0x485) - DAC Digital Volume 3R
- */
-#define WM5100_OUT_VU 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
-#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
-#define WM5100_OUT3R_MUTE 0x0100 /* OUT3R_MUTE */
-#define WM5100_OUT3R_MUTE_MASK 0x0100 /* OUT3R_MUTE */
-#define WM5100_OUT3R_MUTE_SHIFT 8 /* OUT3R_MUTE */
-#define WM5100_OUT3R_MUTE_WIDTH 1 /* OUT3R_MUTE */
-#define WM5100_OUT3R_VOL_MASK 0x00FF /* OUT3R_VOL - [7:0] */
-#define WM5100_OUT3R_VOL_SHIFT 0 /* OUT3R_VOL - [7:0] */
-#define WM5100_OUT3R_VOL_WIDTH 8 /* OUT3R_VOL - [7:0] */
-
-/*
- * R1158 (0x486) - DAC Digital Volume 4L
- */
-#define WM5100_OUT_VU 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
-#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
-#define WM5100_OUT4L_MUTE 0x0100 /* OUT4L_MUTE */
-#define WM5100_OUT4L_MUTE_MASK 0x0100 /* OUT4L_MUTE */
-#define WM5100_OUT4L_MUTE_SHIFT 8 /* OUT4L_MUTE */
-#define WM5100_OUT4L_MUTE_WIDTH 1 /* OUT4L_MUTE */
-#define WM5100_OUT4L_VOL_MASK 0x00FF /* OUT4L_VOL - [7:0] */
-#define WM5100_OUT4L_VOL_SHIFT 0 /* OUT4L_VOL - [7:0] */
-#define WM5100_OUT4L_VOL_WIDTH 8 /* OUT4L_VOL - [7:0] */
-
-/*
- * R1159 (0x487) - DAC Digital Volume 4R
- */
-#define WM5100_OUT_VU 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
-#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
-#define WM5100_OUT4R_MUTE 0x0100 /* OUT4R_MUTE */
-#define WM5100_OUT4R_MUTE_MASK 0x0100 /* OUT4R_MUTE */
-#define WM5100_OUT4R_MUTE_SHIFT 8 /* OUT4R_MUTE */
-#define WM5100_OUT4R_MUTE_WIDTH 1 /* OUT4R_MUTE */
-#define WM5100_OUT4R_VOL_MASK 0x00FF /* OUT4R_VOL - [7:0] */
-#define WM5100_OUT4R_VOL_SHIFT 0 /* OUT4R_VOL - [7:0] */
-#define WM5100_OUT4R_VOL_WIDTH 8 /* OUT4R_VOL - [7:0] */
-
-/*
- * R1160 (0x488) - DAC Digital Volume 5L
- */
-#define WM5100_OUT_VU 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
-#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
-#define WM5100_OUT5L_MUTE 0x0100 /* OUT5L_MUTE */
-#define WM5100_OUT5L_MUTE_MASK 0x0100 /* OUT5L_MUTE */
-#define WM5100_OUT5L_MUTE_SHIFT 8 /* OUT5L_MUTE */
-#define WM5100_OUT5L_MUTE_WIDTH 1 /* OUT5L_MUTE */
-#define WM5100_OUT5L_VOL_MASK 0x00FF /* OUT5L_VOL - [7:0] */
-#define WM5100_OUT5L_VOL_SHIFT 0 /* OUT5L_VOL - [7:0] */
-#define WM5100_OUT5L_VOL_WIDTH 8 /* OUT5L_VOL - [7:0] */
-
-/*
- * R1161 (0x489) - DAC Digital Volume 5R
- */
-#define WM5100_OUT_VU 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
-#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
-#define WM5100_OUT5R_MUTE 0x0100 /* OUT5R_MUTE */
-#define WM5100_OUT5R_MUTE_MASK 0x0100 /* OUT5R_MUTE */
-#define WM5100_OUT5R_MUTE_SHIFT 8 /* OUT5R_MUTE */
-#define WM5100_OUT5R_MUTE_WIDTH 1 /* OUT5R_MUTE */
-#define WM5100_OUT5R_VOL_MASK 0x00FF /* OUT5R_VOL - [7:0] */
-#define WM5100_OUT5R_VOL_SHIFT 0 /* OUT5R_VOL - [7:0] */
-#define WM5100_OUT5R_VOL_WIDTH 8 /* OUT5R_VOL - [7:0] */
-
-/*
- * R1162 (0x48A) - DAC Digital Volume 6L
- */
-#define WM5100_OUT_VU 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
-#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
-#define WM5100_OUT6L_MUTE 0x0100 /* OUT6L_MUTE */
-#define WM5100_OUT6L_MUTE_MASK 0x0100 /* OUT6L_MUTE */
-#define WM5100_OUT6L_MUTE_SHIFT 8 /* OUT6L_MUTE */
-#define WM5100_OUT6L_MUTE_WIDTH 1 /* OUT6L_MUTE */
-#define WM5100_OUT6L_VOL_MASK 0x00FF /* OUT6L_VOL - [7:0] */
-#define WM5100_OUT6L_VOL_SHIFT 0 /* OUT6L_VOL - [7:0] */
-#define WM5100_OUT6L_VOL_WIDTH 8 /* OUT6L_VOL - [7:0] */
-
-/*
- * R1163 (0x48B) - DAC Digital Volume 6R
- */
-#define WM5100_OUT_VU 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */
-#define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */
-#define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */
-#define WM5100_OUT6R_MUTE 0x0100 /* OUT6R_MUTE */
-#define WM5100_OUT6R_MUTE_MASK 0x0100 /* OUT6R_MUTE */
-#define WM5100_OUT6R_MUTE_SHIFT 8 /* OUT6R_MUTE */
-#define WM5100_OUT6R_MUTE_WIDTH 1 /* OUT6R_MUTE */
-#define WM5100_OUT6R_VOL_MASK 0x00FF /* OUT6R_VOL - [7:0] */
-#define WM5100_OUT6R_VOL_SHIFT 0 /* OUT6R_VOL - [7:0] */
-#define WM5100_OUT6R_VOL_WIDTH 8 /* OUT6R_VOL - [7:0] */
-
-/*
- * R1216 (0x4C0) - PDM SPK1 CTRL 1
- */
-#define WM5100_SPK1R_MUTE 0x2000 /* SPK1R_MUTE */
-#define WM5100_SPK1R_MUTE_MASK 0x2000 /* SPK1R_MUTE */
-#define WM5100_SPK1R_MUTE_SHIFT 13 /* SPK1R_MUTE */
-#define WM5100_SPK1R_MUTE_WIDTH 1 /* SPK1R_MUTE */
-#define WM5100_SPK1L_MUTE 0x1000 /* SPK1L_MUTE */
-#define WM5100_SPK1L_MUTE_MASK 0x1000 /* SPK1L_MUTE */
-#define WM5100_SPK1L_MUTE_SHIFT 12 /* SPK1L_MUTE */
-#define WM5100_SPK1L_MUTE_WIDTH 1 /* SPK1L_MUTE */
-#define WM5100_SPK1_MUTE_ENDIAN 0x0100 /* SPK1_MUTE_ENDIAN */
-#define WM5100_SPK1_MUTE_ENDIAN_MASK 0x0100 /* SPK1_MUTE_ENDIAN */
-#define WM5100_SPK1_MUTE_ENDIAN_SHIFT 8 /* SPK1_MUTE_ENDIAN */
-#define WM5100_SPK1_MUTE_ENDIAN_WIDTH 1 /* SPK1_MUTE_ENDIAN */
-#define WM5100_SPK1_MUTE_SEQ1_MASK 0x00FF /* SPK1_MUTE_SEQ1 - [7:0] */
-#define WM5100_SPK1_MUTE_SEQ1_SHIFT 0 /* SPK1_MUTE_SEQ1 - [7:0] */
-#define WM5100_SPK1_MUTE_SEQ1_WIDTH 8 /* SPK1_MUTE_SEQ1 - [7:0] */
-
-/*
- * R1217 (0x4C1) - PDM SPK1 CTRL 2
- */
-#define WM5100_SPK1_FMT 0x0001 /* SPK1_FMT */
-#define WM5100_SPK1_FMT_MASK 0x0001 /* SPK1_FMT */
-#define WM5100_SPK1_FMT_SHIFT 0 /* SPK1_FMT */
-#define WM5100_SPK1_FMT_WIDTH 1 /* SPK1_FMT */
-
-/*
- * R1218 (0x4C2) - PDM SPK2 CTRL 1
- */
-#define WM5100_SPK2R_MUTE 0x2000 /* SPK2R_MUTE */
-#define WM5100_SPK2R_MUTE_MASK 0x2000 /* SPK2R_MUTE */
-#define WM5100_SPK2R_MUTE_SHIFT 13 /* SPK2R_MUTE */
-#define WM5100_SPK2R_MUTE_WIDTH 1 /* SPK2R_MUTE */
-#define WM5100_SPK2L_MUTE 0x1000 /* SPK2L_MUTE */
-#define WM5100_SPK2L_MUTE_MASK 0x1000 /* SPK2L_MUTE */
-#define WM5100_SPK2L_MUTE_SHIFT 12 /* SPK2L_MUTE */
-#define WM5100_SPK2L_MUTE_WIDTH 1 /* SPK2L_MUTE */
-#define WM5100_SPK2_MUTE_ENDIAN 0x0100 /* SPK2_MUTE_ENDIAN */
-#define WM5100_SPK2_MUTE_ENDIAN_MASK 0x0100 /* SPK2_MUTE_ENDIAN */
-#define WM5100_SPK2_MUTE_ENDIAN_SHIFT 8 /* SPK2_MUTE_ENDIAN */
-#define WM5100_SPK2_MUTE_ENDIAN_WIDTH 1 /* SPK2_MUTE_ENDIAN */
-#define WM5100_SPK2_MUTE_SEQ1_MASK 0x00FF /* SPK2_MUTE_SEQ1 - [7:0] */
-#define WM5100_SPK2_MUTE_SEQ1_SHIFT 0 /* SPK2_MUTE_SEQ1 - [7:0] */
-#define WM5100_SPK2_MUTE_SEQ1_WIDTH 8 /* SPK2_MUTE_SEQ1 - [7:0] */
-
-/*
- * R1219 (0x4C3) - PDM SPK2 CTRL 2
- */
-#define WM5100_SPK2_FMT 0x0001 /* SPK2_FMT */
-#define WM5100_SPK2_FMT_MASK 0x0001 /* SPK2_FMT */
-#define WM5100_SPK2_FMT_SHIFT 0 /* SPK2_FMT */
-#define WM5100_SPK2_FMT_WIDTH 1 /* SPK2_FMT */
-
-/*
- * R1280 (0x500) - Audio IF 1_1
- */
-#define WM5100_AIF1_BCLK_INV 0x0080 /* AIF1_BCLK_INV */
-#define WM5100_AIF1_BCLK_INV_MASK 0x0080 /* AIF1_BCLK_INV */
-#define WM5100_AIF1_BCLK_INV_SHIFT 7 /* AIF1_BCLK_INV */
-#define WM5100_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */
-#define WM5100_AIF1_BCLK_FRC 0x0040 /* AIF1_BCLK_FRC */
-#define WM5100_AIF1_BCLK_FRC_MASK 0x0040 /* AIF1_BCLK_FRC */
-#define WM5100_AIF1_BCLK_FRC_SHIFT 6 /* AIF1_BCLK_FRC */
-#define WM5100_AIF1_BCLK_FRC_WIDTH 1 /* AIF1_BCLK_FRC */
-#define WM5100_AIF1_BCLK_MSTR 0x0020 /* AIF1_BCLK_MSTR */
-#define WM5100_AIF1_BCLK_MSTR_MASK 0x0020 /* AIF1_BCLK_MSTR */
-#define WM5100_AIF1_BCLK_MSTR_SHIFT 5 /* AIF1_BCLK_MSTR */
-#define WM5100_AIF1_BCLK_MSTR_WIDTH 1 /* AIF1_BCLK_MSTR */
-#define WM5100_AIF1_BCLK_FREQ_MASK 0x001F /* AIF1_BCLK_FREQ - [4:0] */
-#define WM5100_AIF1_BCLK_FREQ_SHIFT 0 /* AIF1_BCLK_FREQ - [4:0] */
-#define WM5100_AIF1_BCLK_FREQ_WIDTH 5 /* AIF1_BCLK_FREQ - [4:0] */
-
-/*
- * R1281 (0x501) - Audio IF 1_2
- */
-#define WM5100_AIF1TX_DAT_TRI 0x0020 /* AIF1TX_DAT_TRI */
-#define WM5100_AIF1TX_DAT_TRI_MASK 0x0020 /* AIF1TX_DAT_TRI */
-#define WM5100_AIF1TX_DAT_TRI_SHIFT 5 /* AIF1TX_DAT_TRI */
-#define WM5100_AIF1TX_DAT_TRI_WIDTH 1 /* AIF1TX_DAT_TRI */
-#define WM5100_AIF1TX_LRCLK_SRC 0x0008 /* AIF1TX_LRCLK_SRC */
-#define WM5100_AIF1TX_LRCLK_SRC_MASK 0x0008 /* AIF1TX_LRCLK_SRC */
-#define WM5100_AIF1TX_LRCLK_SRC_SHIFT 3 /* AIF1TX_LRCLK_SRC */
-#define WM5100_AIF1TX_LRCLK_SRC_WIDTH 1 /* AIF1TX_LRCLK_SRC */
-#define WM5100_AIF1TX_LRCLK_INV 0x0004 /* AIF1TX_LRCLK_INV */
-#define WM5100_AIF1TX_LRCLK_INV_MASK 0x0004 /* AIF1TX_LRCLK_INV */
-#define WM5100_AIF1TX_LRCLK_INV_SHIFT 2 /* AIF1TX_LRCLK_INV */
-#define WM5100_AIF1TX_LRCLK_INV_WIDTH 1 /* AIF1TX_LRCLK_INV */
-#define WM5100_AIF1TX_LRCLK_FRC 0x0002 /* AIF1TX_LRCLK_FRC */
-#define WM5100_AIF1TX_LRCLK_FRC_MASK 0x0002 /* AIF1TX_LRCLK_FRC */
-#define WM5100_AIF1TX_LRCLK_FRC_SHIFT 1 /* AIF1TX_LRCLK_FRC */
-#define WM5100_AIF1TX_LRCLK_FRC_WIDTH 1 /* AIF1TX_LRCLK_FRC */
-#define WM5100_AIF1TX_LRCLK_MSTR 0x0001 /* AIF1TX_LRCLK_MSTR */
-#define WM5100_AIF1TX_LRCLK_MSTR_MASK 0x0001 /* AIF1TX_LRCLK_MSTR */
-#define WM5100_AIF1TX_LRCLK_MSTR_SHIFT 0 /* AIF1TX_LRCLK_MSTR */
-#define WM5100_AIF1TX_LRCLK_MSTR_WIDTH 1 /* AIF1TX_LRCLK_MSTR */
-
-/*
- * R1282 (0x502) - Audio IF 1_3
- */
-#define WM5100_AIF1RX_LRCLK_INV 0x0004 /* AIF1RX_LRCLK_INV */
-#define WM5100_AIF1RX_LRCLK_INV_MASK 0x0004 /* AIF1RX_LRCLK_INV */
-#define WM5100_AIF1RX_LRCLK_INV_SHIFT 2 /* AIF1RX_LRCLK_INV */
-#define WM5100_AIF1RX_LRCLK_INV_WIDTH 1 /* AIF1RX_LRCLK_INV */
-#define WM5100_AIF1RX_LRCLK_FRC 0x0002 /* AIF1RX_LRCLK_FRC */
-#define WM5100_AIF1RX_LRCLK_FRC_MASK 0x0002 /* AIF1RX_LRCLK_FRC */
-#define WM5100_AIF1RX_LRCLK_FRC_SHIFT 1 /* AIF1RX_LRCLK_FRC */
-#define WM5100_AIF1RX_LRCLK_FRC_WIDTH 1 /* AIF1RX_LRCLK_FRC */
-#define WM5100_AIF1RX_LRCLK_MSTR 0x0001 /* AIF1RX_LRCLK_MSTR */
-#define WM5100_AIF1RX_LRCLK_MSTR_MASK 0x0001 /* AIF1RX_LRCLK_MSTR */
-#define WM5100_AIF1RX_LRCLK_MSTR_SHIFT 0 /* AIF1RX_LRCLK_MSTR */
-#define WM5100_AIF1RX_LRCLK_MSTR_WIDTH 1 /* AIF1RX_LRCLK_MSTR */
-
-/*
- * R1283 (0x503) - Audio IF 1_4
- */
-#define WM5100_AIF1_TRI 0x0040 /* AIF1_TRI */
-#define WM5100_AIF1_TRI_MASK 0x0040 /* AIF1_TRI */
-#define WM5100_AIF1_TRI_SHIFT 6 /* AIF1_TRI */
-#define WM5100_AIF1_TRI_WIDTH 1 /* AIF1_TRI */
-#define WM5100_AIF1_RATE_MASK 0x0003 /* AIF1_RATE - [1:0] */
-#define WM5100_AIF1_RATE_SHIFT 0 /* AIF1_RATE - [1:0] */
-#define WM5100_AIF1_RATE_WIDTH 2 /* AIF1_RATE - [1:0] */
-
-/*
- * R1284 (0x504) - Audio IF 1_5
- */
-#define WM5100_AIF1_FMT_MASK 0x0007 /* AIF1_FMT - [2:0] */
-#define WM5100_AIF1_FMT_SHIFT 0 /* AIF1_FMT - [2:0] */
-#define WM5100_AIF1_FMT_WIDTH 3 /* AIF1_FMT - [2:0] */
-
-/*
- * R1285 (0x505) - Audio IF 1_6
- */
-#define WM5100_AIF1TX_BCPF_MASK 0x1FFF /* AIF1TX_BCPF - [12:0] */
-#define WM5100_AIF1TX_BCPF_SHIFT 0 /* AIF1TX_BCPF - [12:0] */
-#define WM5100_AIF1TX_BCPF_WIDTH 13 /* AIF1TX_BCPF - [12:0] */
-
-/*
- * R1286 (0x506) - Audio IF 1_7
- */
-#define WM5100_AIF1RX_BCPF_MASK 0x1FFF /* AIF1RX_BCPF - [12:0] */
-#define WM5100_AIF1RX_BCPF_SHIFT 0 /* AIF1RX_BCPF - [12:0] */
-#define WM5100_AIF1RX_BCPF_WIDTH 13 /* AIF1RX_BCPF - [12:0] */
-
-/*
- * R1287 (0x507) - Audio IF 1_8
- */
-#define WM5100_AIF1TX_WL_MASK 0x3F00 /* AIF1TX_WL - [13:8] */
-#define WM5100_AIF1TX_WL_SHIFT 8 /* AIF1TX_WL - [13:8] */
-#define WM5100_AIF1TX_WL_WIDTH 6 /* AIF1TX_WL - [13:8] */
-#define WM5100_AIF1TX_SLOT_LEN_MASK 0x00FF /* AIF1TX_SLOT_LEN - [7:0] */
-#define WM5100_AIF1TX_SLOT_LEN_SHIFT 0 /* AIF1TX_SLOT_LEN - [7:0] */
-#define WM5100_AIF1TX_SLOT_LEN_WIDTH 8 /* AIF1TX_SLOT_LEN - [7:0] */
-
-/*
- * R1288 (0x508) - Audio IF 1_9
- */
-#define WM5100_AIF1RX_WL_MASK 0x3F00 /* AIF1RX_WL - [13:8] */
-#define WM5100_AIF1RX_WL_SHIFT 8 /* AIF1RX_WL - [13:8] */
-#define WM5100_AIF1RX_WL_WIDTH 6 /* AIF1RX_WL - [13:8] */
-#define WM5100_AIF1RX_SLOT_LEN_MASK 0x00FF /* AIF1RX_SLOT_LEN - [7:0] */
-#define WM5100_AIF1RX_SLOT_LEN_SHIFT 0 /* AIF1RX_SLOT_LEN - [7:0] */
-#define WM5100_AIF1RX_SLOT_LEN_WIDTH 8 /* AIF1RX_SLOT_LEN - [7:0] */
-
-/*
- * R1289 (0x509) - Audio IF 1_10
- */
-#define WM5100_AIF1TX1_SLOT_MASK 0x003F /* AIF1TX1_SLOT - [5:0] */
-#define WM5100_AIF1TX1_SLOT_SHIFT 0 /* AIF1TX1_SLOT - [5:0] */
-#define WM5100_AIF1TX1_SLOT_WIDTH 6 /* AIF1TX1_SLOT - [5:0] */
-
-/*
- * R1290 (0x50A) - Audio IF 1_11
- */
-#define WM5100_AIF1TX2_SLOT_MASK 0x003F /* AIF1TX2_SLOT - [5:0] */
-#define WM5100_AIF1TX2_SLOT_SHIFT 0 /* AIF1TX2_SLOT - [5:0] */
-#define WM5100_AIF1TX2_SLOT_WIDTH 6 /* AIF1TX2_SLOT - [5:0] */
-
-/*
- * R1291 (0x50B) - Audio IF 1_12
- */
-#define WM5100_AIF1TX3_SLOT_MASK 0x003F /* AIF1TX3_SLOT - [5:0] */
-#define WM5100_AIF1TX3_SLOT_SHIFT 0 /* AIF1TX3_SLOT - [5:0] */
-#define WM5100_AIF1TX3_SLOT_WIDTH 6 /* AIF1TX3_SLOT - [5:0] */
-
-/*
- * R1292 (0x50C) - Audio IF 1_13
- */
-#define WM5100_AIF1TX4_SLOT_MASK 0x003F /* AIF1TX4_SLOT - [5:0] */
-#define WM5100_AIF1TX4_SLOT_SHIFT 0 /* AIF1TX4_SLOT - [5:0] */
-#define WM5100_AIF1TX4_SLOT_WIDTH 6 /* AIF1TX4_SLOT - [5:0] */
-
-/*
- * R1293 (0x50D) - Audio IF 1_14
- */
-#define WM5100_AIF1TX5_SLOT_MASK 0x003F /* AIF1TX5_SLOT - [5:0] */
-#define WM5100_AIF1TX5_SLOT_SHIFT 0 /* AIF1TX5_SLOT - [5:0] */
-#define WM5100_AIF1TX5_SLOT_WIDTH 6 /* AIF1TX5_SLOT - [5:0] */
-
-/*
- * R1294 (0x50E) - Audio IF 1_15
- */
-#define WM5100_AIF1TX6_SLOT_MASK 0x003F /* AIF1TX6_SLOT - [5:0] */
-#define WM5100_AIF1TX6_SLOT_SHIFT 0 /* AIF1TX6_SLOT - [5:0] */
-#define WM5100_AIF1TX6_SLOT_WIDTH 6 /* AIF1TX6_SLOT - [5:0] */
-
-/*
- * R1295 (0x50F) - Audio IF 1_16
- */
-#define WM5100_AIF1TX7_SLOT_MASK 0x003F /* AIF1TX7_SLOT - [5:0] */
-#define WM5100_AIF1TX7_SLOT_SHIFT 0 /* AIF1TX7_SLOT - [5:0] */
-#define WM5100_AIF1TX7_SLOT_WIDTH 6 /* AIF1TX7_SLOT - [5:0] */
-
-/*
- * R1296 (0x510) - Audio IF 1_17
- */
-#define WM5100_AIF1TX8_SLOT_MASK 0x003F /* AIF1TX8_SLOT - [5:0] */
-#define WM5100_AIF1TX8_SLOT_SHIFT 0 /* AIF1TX8_SLOT - [5:0] */
-#define WM5100_AIF1TX8_SLOT_WIDTH 6 /* AIF1TX8_SLOT - [5:0] */
-
-/*
- * R1297 (0x511) - Audio IF 1_18
- */
-#define WM5100_AIF1RX1_SLOT_MASK 0x003F /* AIF1RX1_SLOT - [5:0] */
-#define WM5100_AIF1RX1_SLOT_SHIFT 0 /* AIF1RX1_SLOT - [5:0] */
-#define WM5100_AIF1RX1_SLOT_WIDTH 6 /* AIF1RX1_SLOT - [5:0] */
-
-/*
- * R1298 (0x512) - Audio IF 1_19
- */
-#define WM5100_AIF1RX2_SLOT_MASK 0x003F /* AIF1RX2_SLOT - [5:0] */
-#define WM5100_AIF1RX2_SLOT_SHIFT 0 /* AIF1RX2_SLOT - [5:0] */
-#define WM5100_AIF1RX2_SLOT_WIDTH 6 /* AIF1RX2_SLOT - [5:0] */
-
-/*
- * R1299 (0x513) - Audio IF 1_20
- */
-#define WM5100_AIF1RX3_SLOT_MASK 0x003F /* AIF1RX3_SLOT - [5:0] */
-#define WM5100_AIF1RX3_SLOT_SHIFT 0 /* AIF1RX3_SLOT - [5:0] */
-#define WM5100_AIF1RX3_SLOT_WIDTH 6 /* AIF1RX3_SLOT - [5:0] */
-
-/*
- * R1300 (0x514) - Audio IF 1_21
- */
-#define WM5100_AIF1RX4_SLOT_MASK 0x003F /* AIF1RX4_SLOT - [5:0] */
-#define WM5100_AIF1RX4_SLOT_SHIFT 0 /* AIF1RX4_SLOT - [5:0] */
-#define WM5100_AIF1RX4_SLOT_WIDTH 6 /* AIF1RX4_SLOT - [5:0] */
-
-/*
- * R1301 (0x515) - Audio IF 1_22
- */
-#define WM5100_AIF1RX5_SLOT_MASK 0x003F /* AIF1RX5_SLOT - [5:0] */
-#define WM5100_AIF1RX5_SLOT_SHIFT 0 /* AIF1RX5_SLOT - [5:0] */
-#define WM5100_AIF1RX5_SLOT_WIDTH 6 /* AIF1RX5_SLOT - [5:0] */
-
-/*
- * R1302 (0x516) - Audio IF 1_23
- */
-#define WM5100_AIF1RX6_SLOT_MASK 0x003F /* AIF1RX6_SLOT - [5:0] */
-#define WM5100_AIF1RX6_SLOT_SHIFT 0 /* AIF1RX6_SLOT - [5:0] */
-#define WM5100_AIF1RX6_SLOT_WIDTH 6 /* AIF1RX6_SLOT - [5:0] */
-
-/*
- * R1303 (0x517) - Audio IF 1_24
- */
-#define WM5100_AIF1RX7_SLOT_MASK 0x003F /* AIF1RX7_SLOT - [5:0] */
-#define WM5100_AIF1RX7_SLOT_SHIFT 0 /* AIF1RX7_SLOT - [5:0] */
-#define WM5100_AIF1RX7_SLOT_WIDTH 6 /* AIF1RX7_SLOT - [5:0] */
-
-/*
- * R1304 (0x518) - Audio IF 1_25
- */
-#define WM5100_AIF1RX8_SLOT_MASK 0x003F /* AIF1RX8_SLOT - [5:0] */
-#define WM5100_AIF1RX8_SLOT_SHIFT 0 /* AIF1RX8_SLOT - [5:0] */
-#define WM5100_AIF1RX8_SLOT_WIDTH 6 /* AIF1RX8_SLOT - [5:0] */
-
-/*
- * R1305 (0x519) - Audio IF 1_26
- */
-#define WM5100_AIF1TX8_ENA 0x0080 /* AIF1TX8_ENA */
-#define WM5100_AIF1TX8_ENA_MASK 0x0080 /* AIF1TX8_ENA */
-#define WM5100_AIF1TX8_ENA_SHIFT 7 /* AIF1TX8_ENA */
-#define WM5100_AIF1TX8_ENA_WIDTH 1 /* AIF1TX8_ENA */
-#define WM5100_AIF1TX7_ENA 0x0040 /* AIF1TX7_ENA */
-#define WM5100_AIF1TX7_ENA_MASK 0x0040 /* AIF1TX7_ENA */
-#define WM5100_AIF1TX7_ENA_SHIFT 6 /* AIF1TX7_ENA */
-#define WM5100_AIF1TX7_ENA_WIDTH 1 /* AIF1TX7_ENA */
-#define WM5100_AIF1TX6_ENA 0x0020 /* AIF1TX6_ENA */
-#define WM5100_AIF1TX6_ENA_MASK 0x0020 /* AIF1TX6_ENA */
-#define WM5100_AIF1TX6_ENA_SHIFT 5 /* AIF1TX6_ENA */
-#define WM5100_AIF1TX6_ENA_WIDTH 1 /* AIF1TX6_ENA */
-#define WM5100_AIF1TX5_ENA 0x0010 /* AIF1TX5_ENA */
-#define WM5100_AIF1TX5_ENA_MASK 0x0010 /* AIF1TX5_ENA */
-#define WM5100_AIF1TX5_ENA_SHIFT 4 /* AIF1TX5_ENA */
-#define WM5100_AIF1TX5_ENA_WIDTH 1 /* AIF1TX5_ENA */
-#define WM5100_AIF1TX4_ENA 0x0008 /* AIF1TX4_ENA */
-#define WM5100_AIF1TX4_ENA_MASK 0x0008 /* AIF1TX4_ENA */
-#define WM5100_AIF1TX4_ENA_SHIFT 3 /* AIF1TX4_ENA */
-#define WM5100_AIF1TX4_ENA_WIDTH 1 /* AIF1TX4_ENA */
-#define WM5100_AIF1TX3_ENA 0x0004 /* AIF1TX3_ENA */
-#define WM5100_AIF1TX3_ENA_MASK 0x0004 /* AIF1TX3_ENA */
-#define WM5100_AIF1TX3_ENA_SHIFT 2 /* AIF1TX3_ENA */
-#define WM5100_AIF1TX3_ENA_WIDTH 1 /* AIF1TX3_ENA */
-#define WM5100_AIF1TX2_ENA 0x0002 /* AIF1TX2_ENA */
-#define WM5100_AIF1TX2_ENA_MASK 0x0002 /* AIF1TX2_ENA */
-#define WM5100_AIF1TX2_ENA_SHIFT 1 /* AIF1TX2_ENA */
-#define WM5100_AIF1TX2_ENA_WIDTH 1 /* AIF1TX2_ENA */
-#define WM5100_AIF1TX1_ENA 0x0001 /* AIF1TX1_ENA */
-#define WM5100_AIF1TX1_ENA_MASK 0x0001 /* AIF1TX1_ENA */
-#define WM5100_AIF1TX1_ENA_SHIFT 0 /* AIF1TX1_ENA */
-#define WM5100_AIF1TX1_ENA_WIDTH 1 /* AIF1TX1_ENA */
-
-/*
- * R1306 (0x51A) - Audio IF 1_27
- */
-#define WM5100_AIF1RX8_ENA 0x0080 /* AIF1RX8_ENA */
-#define WM5100_AIF1RX8_ENA_MASK 0x0080 /* AIF1RX8_ENA */
-#define WM5100_AIF1RX8_ENA_SHIFT 7 /* AIF1RX8_ENA */
-#define WM5100_AIF1RX8_ENA_WIDTH 1 /* AIF1RX8_ENA */
-#define WM5100_AIF1RX7_ENA 0x0040 /* AIF1RX7_ENA */
-#define WM5100_AIF1RX7_ENA_MASK 0x0040 /* AIF1RX7_ENA */
-#define WM5100_AIF1RX7_ENA_SHIFT 6 /* AIF1RX7_ENA */
-#define WM5100_AIF1RX7_ENA_WIDTH 1 /* AIF1RX7_ENA */
-#define WM5100_AIF1RX6_ENA 0x0020 /* AIF1RX6_ENA */
-#define WM5100_AIF1RX6_ENA_MASK 0x0020 /* AIF1RX6_ENA */
-#define WM5100_AIF1RX6_ENA_SHIFT 5 /* AIF1RX6_ENA */
-#define WM5100_AIF1RX6_ENA_WIDTH 1 /* AIF1RX6_ENA */
-#define WM5100_AIF1RX5_ENA 0x0010 /* AIF1RX5_ENA */
-#define WM5100_AIF1RX5_ENA_MASK 0x0010 /* AIF1RX5_ENA */
-#define WM5100_AIF1RX5_ENA_SHIFT 4 /* AIF1RX5_ENA */
-#define WM5100_AIF1RX5_ENA_WIDTH 1 /* AIF1RX5_ENA */
-#define WM5100_AIF1RX4_ENA 0x0008 /* AIF1RX4_ENA */
-#define WM5100_AIF1RX4_ENA_MASK 0x0008 /* AIF1RX4_ENA */
-#define WM5100_AIF1RX4_ENA_SHIFT 3 /* AIF1RX4_ENA */
-#define WM5100_AIF1RX4_ENA_WIDTH 1 /* AIF1RX4_ENA */
-#define WM5100_AIF1RX3_ENA 0x0004 /* AIF1RX3_ENA */
-#define WM5100_AIF1RX3_ENA_MASK 0x0004 /* AIF1RX3_ENA */
-#define WM5100_AIF1RX3_ENA_SHIFT 2 /* AIF1RX3_ENA */
-#define WM5100_AIF1RX3_ENA_WIDTH 1 /* AIF1RX3_ENA */
-#define WM5100_AIF1RX2_ENA 0x0002 /* AIF1RX2_ENA */
-#define WM5100_AIF1RX2_ENA_MASK 0x0002 /* AIF1RX2_ENA */
-#define WM5100_AIF1RX2_ENA_SHIFT 1 /* AIF1RX2_ENA */
-#define WM5100_AIF1RX2_ENA_WIDTH 1 /* AIF1RX2_ENA */
-#define WM5100_AIF1RX1_ENA 0x0001 /* AIF1RX1_ENA */
-#define WM5100_AIF1RX1_ENA_MASK 0x0001 /* AIF1RX1_ENA */
-#define WM5100_AIF1RX1_ENA_SHIFT 0 /* AIF1RX1_ENA */
-#define WM5100_AIF1RX1_ENA_WIDTH 1 /* AIF1RX1_ENA */
-
-/*
- * R1344 (0x540) - Audio IF 2_1
- */
-#define WM5100_AIF2_BCLK_INV 0x0080 /* AIF2_BCLK_INV */
-#define WM5100_AIF2_BCLK_INV_MASK 0x0080 /* AIF2_BCLK_INV */
-#define WM5100_AIF2_BCLK_INV_SHIFT 7 /* AIF2_BCLK_INV */
-#define WM5100_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */
-#define WM5100_AIF2_BCLK_FRC 0x0040 /* AIF2_BCLK_FRC */
-#define WM5100_AIF2_BCLK_FRC_MASK 0x0040 /* AIF2_BCLK_FRC */
-#define WM5100_AIF2_BCLK_FRC_SHIFT 6 /* AIF2_BCLK_FRC */
-#define WM5100_AIF2_BCLK_FRC_WIDTH 1 /* AIF2_BCLK_FRC */
-#define WM5100_AIF2_BCLK_MSTR 0x0020 /* AIF2_BCLK_MSTR */
-#define WM5100_AIF2_BCLK_MSTR_MASK 0x0020 /* AIF2_BCLK_MSTR */
-#define WM5100_AIF2_BCLK_MSTR_SHIFT 5 /* AIF2_BCLK_MSTR */
-#define WM5100_AIF2_BCLK_MSTR_WIDTH 1 /* AIF2_BCLK_MSTR */
-#define WM5100_AIF2_BCLK_FREQ_MASK 0x001F /* AIF2_BCLK_FREQ - [4:0] */
-#define WM5100_AIF2_BCLK_FREQ_SHIFT 0 /* AIF2_BCLK_FREQ - [4:0] */
-#define WM5100_AIF2_BCLK_FREQ_WIDTH 5 /* AIF2_BCLK_FREQ - [4:0] */
-
-/*
- * R1345 (0x541) - Audio IF 2_2
- */
-#define WM5100_AIF2TX_DAT_TRI 0x0020 /* AIF2TX_DAT_TRI */
-#define WM5100_AIF2TX_DAT_TRI_MASK 0x0020 /* AIF2TX_DAT_TRI */
-#define WM5100_AIF2TX_DAT_TRI_SHIFT 5 /* AIF2TX_DAT_TRI */
-#define WM5100_AIF2TX_DAT_TRI_WIDTH 1 /* AIF2TX_DAT_TRI */
-#define WM5100_AIF2TX_LRCLK_SRC 0x0008 /* AIF2TX_LRCLK_SRC */
-#define WM5100_AIF2TX_LRCLK_SRC_MASK 0x0008 /* AIF2TX_LRCLK_SRC */
-#define WM5100_AIF2TX_LRCLK_SRC_SHIFT 3 /* AIF2TX_LRCLK_SRC */
-#define WM5100_AIF2TX_LRCLK_SRC_WIDTH 1 /* AIF2TX_LRCLK_SRC */
-#define WM5100_AIF2TX_LRCLK_INV 0x0004 /* AIF2TX_LRCLK_INV */
-#define WM5100_AIF2TX_LRCLK_INV_MASK 0x0004 /* AIF2TX_LRCLK_INV */
-#define WM5100_AIF2TX_LRCLK_INV_SHIFT 2 /* AIF2TX_LRCLK_INV */
-#define WM5100_AIF2TX_LRCLK_INV_WIDTH 1 /* AIF2TX_LRCLK_INV */
-#define WM5100_AIF2TX_LRCLK_FRC 0x0002 /* AIF2TX_LRCLK_FRC */
-#define WM5100_AIF2TX_LRCLK_FRC_MASK 0x0002 /* AIF2TX_LRCLK_FRC */
-#define WM5100_AIF2TX_LRCLK_FRC_SHIFT 1 /* AIF2TX_LRCLK_FRC */
-#define WM5100_AIF2TX_LRCLK_FRC_WIDTH 1 /* AIF2TX_LRCLK_FRC */
-#define WM5100_AIF2TX_LRCLK_MSTR 0x0001 /* AIF2TX_LRCLK_MSTR */
-#define WM5100_AIF2TX_LRCLK_MSTR_MASK 0x0001 /* AIF2TX_LRCLK_MSTR */
-#define WM5100_AIF2TX_LRCLK_MSTR_SHIFT 0 /* AIF2TX_LRCLK_MSTR */
-#define WM5100_AIF2TX_LRCLK_MSTR_WIDTH 1 /* AIF2TX_LRCLK_MSTR */
-
-/*
- * R1346 (0x542) - Audio IF 2_3
- */
-#define WM5100_AIF2RX_LRCLK_INV 0x0004 /* AIF2RX_LRCLK_INV */
-#define WM5100_AIF2RX_LRCLK_INV_MASK 0x0004 /* AIF2RX_LRCLK_INV */
-#define WM5100_AIF2RX_LRCLK_INV_SHIFT 2 /* AIF2RX_LRCLK_INV */
-#define WM5100_AIF2RX_LRCLK_INV_WIDTH 1 /* AIF2RX_LRCLK_INV */
-#define WM5100_AIF2RX_LRCLK_FRC 0x0002 /* AIF2RX_LRCLK_FRC */
-#define WM5100_AIF2RX_LRCLK_FRC_MASK 0x0002 /* AIF2RX_LRCLK_FRC */
-#define WM5100_AIF2RX_LRCLK_FRC_SHIFT 1 /* AIF2RX_LRCLK_FRC */
-#define WM5100_AIF2RX_LRCLK_FRC_WIDTH 1 /* AIF2RX_LRCLK_FRC */
-#define WM5100_AIF2RX_LRCLK_MSTR 0x0001 /* AIF2RX_LRCLK_MSTR */
-#define WM5100_AIF2RX_LRCLK_MSTR_MASK 0x0001 /* AIF2RX_LRCLK_MSTR */
-#define WM5100_AIF2RX_LRCLK_MSTR_SHIFT 0 /* AIF2RX_LRCLK_MSTR */
-#define WM5100_AIF2RX_LRCLK_MSTR_WIDTH 1 /* AIF2RX_LRCLK_MSTR */
-
-/*
- * R1347 (0x543) - Audio IF 2_4
- */
-#define WM5100_AIF2_TRI 0x0040 /* AIF2_TRI */
-#define WM5100_AIF2_TRI_MASK 0x0040 /* AIF2_TRI */
-#define WM5100_AIF2_TRI_SHIFT 6 /* AIF2_TRI */
-#define WM5100_AIF2_TRI_WIDTH 1 /* AIF2_TRI */
-#define WM5100_AIF2_RATE_MASK 0x0003 /* AIF2_RATE - [1:0] */
-#define WM5100_AIF2_RATE_SHIFT 0 /* AIF2_RATE - [1:0] */
-#define WM5100_AIF2_RATE_WIDTH 2 /* AIF2_RATE - [1:0] */
-
-/*
- * R1348 (0x544) - Audio IF 2_5
- */
-#define WM5100_AIF2_FMT_MASK 0x0007 /* AIF2_FMT - [2:0] */
-#define WM5100_AIF2_FMT_SHIFT 0 /* AIF2_FMT - [2:0] */
-#define WM5100_AIF2_FMT_WIDTH 3 /* AIF2_FMT - [2:0] */
-
-/*
- * R1349 (0x545) - Audio IF 2_6
- */
-#define WM5100_AIF2TX_BCPF_MASK 0x1FFF /* AIF2TX_BCPF - [12:0] */
-#define WM5100_AIF2TX_BCPF_SHIFT 0 /* AIF2TX_BCPF - [12:0] */
-#define WM5100_AIF2TX_BCPF_WIDTH 13 /* AIF2TX_BCPF - [12:0] */
-
-/*
- * R1350 (0x546) - Audio IF 2_7
- */
-#define WM5100_AIF2RX_BCPF_MASK 0x1FFF /* AIF2RX_BCPF - [12:0] */
-#define WM5100_AIF2RX_BCPF_SHIFT 0 /* AIF2RX_BCPF - [12:0] */
-#define WM5100_AIF2RX_BCPF_WIDTH 13 /* AIF2RX_BCPF - [12:0] */
-
-/*
- * R1351 (0x547) - Audio IF 2_8
- */
-#define WM5100_AIF2TX_WL_MASK 0x3F00 /* AIF2TX_WL - [13:8] */
-#define WM5100_AIF2TX_WL_SHIFT 8 /* AIF2TX_WL - [13:8] */
-#define WM5100_AIF2TX_WL_WIDTH 6 /* AIF2TX_WL - [13:8] */
-#define WM5100_AIF2TX_SLOT_LEN_MASK 0x00FF /* AIF2TX_SLOT_LEN - [7:0] */
-#define WM5100_AIF2TX_SLOT_LEN_SHIFT 0 /* AIF2TX_SLOT_LEN - [7:0] */
-#define WM5100_AIF2TX_SLOT_LEN_WIDTH 8 /* AIF2TX_SLOT_LEN - [7:0] */
-
-/*
- * R1352 (0x548) - Audio IF 2_9
- */
-#define WM5100_AIF2RX_WL_MASK 0x3F00 /* AIF2RX_WL - [13:8] */
-#define WM5100_AIF2RX_WL_SHIFT 8 /* AIF2RX_WL - [13:8] */
-#define WM5100_AIF2RX_WL_WIDTH 6 /* AIF2RX_WL - [13:8] */
-#define WM5100_AIF2RX_SLOT_LEN_MASK 0x00FF /* AIF2RX_SLOT_LEN - [7:0] */
-#define WM5100_AIF2RX_SLOT_LEN_SHIFT 0 /* AIF2RX_SLOT_LEN - [7:0] */
-#define WM5100_AIF2RX_SLOT_LEN_WIDTH 8 /* AIF2RX_SLOT_LEN - [7:0] */
-
-/*
- * R1353 (0x549) - Audio IF 2_10
- */
-#define WM5100_AIF2TX1_SLOT_MASK 0x003F /* AIF2TX1_SLOT - [5:0] */
-#define WM5100_AIF2TX1_SLOT_SHIFT 0 /* AIF2TX1_SLOT - [5:0] */
-#define WM5100_AIF2TX1_SLOT_WIDTH 6 /* AIF2TX1_SLOT - [5:0] */
-
-/*
- * R1354 (0x54A) - Audio IF 2_11
- */
-#define WM5100_AIF2TX2_SLOT_MASK 0x003F /* AIF2TX2_SLOT - [5:0] */
-#define WM5100_AIF2TX2_SLOT_SHIFT 0 /* AIF2TX2_SLOT - [5:0] */
-#define WM5100_AIF2TX2_SLOT_WIDTH 6 /* AIF2TX2_SLOT - [5:0] */
-
-/*
- * R1361 (0x551) - Audio IF 2_18
- */
-#define WM5100_AIF2RX1_SLOT_MASK 0x003F /* AIF2RX1_SLOT - [5:0] */
-#define WM5100_AIF2RX1_SLOT_SHIFT 0 /* AIF2RX1_SLOT - [5:0] */
-#define WM5100_AIF2RX1_SLOT_WIDTH 6 /* AIF2RX1_SLOT - [5:0] */
-
-/*
- * R1362 (0x552) - Audio IF 2_19
- */
-#define WM5100_AIF2RX2_SLOT_MASK 0x003F /* AIF2RX2_SLOT - [5:0] */
-#define WM5100_AIF2RX2_SLOT_SHIFT 0 /* AIF2RX2_SLOT - [5:0] */
-#define WM5100_AIF2RX2_SLOT_WIDTH 6 /* AIF2RX2_SLOT - [5:0] */
-
-/*
- * R1369 (0x559) - Audio IF 2_26
- */
-#define WM5100_AIF2TX2_ENA 0x0002 /* AIF2TX2_ENA */
-#define WM5100_AIF2TX2_ENA_MASK 0x0002 /* AIF2TX2_ENA */
-#define WM5100_AIF2TX2_ENA_SHIFT 1 /* AIF2TX2_ENA */
-#define WM5100_AIF2TX2_ENA_WIDTH 1 /* AIF2TX2_ENA */
-#define WM5100_AIF2TX1_ENA 0x0001 /* AIF2TX1_ENA */
-#define WM5100_AIF2TX1_ENA_MASK 0x0001 /* AIF2TX1_ENA */
-#define WM5100_AIF2TX1_ENA_SHIFT 0 /* AIF2TX1_ENA */
-#define WM5100_AIF2TX1_ENA_WIDTH 1 /* AIF2TX1_ENA */
-
-/*
- * R1370 (0x55A) - Audio IF 2_27
- */
-#define WM5100_AIF2RX2_ENA 0x0002 /* AIF2RX2_ENA */
-#define WM5100_AIF2RX2_ENA_MASK 0x0002 /* AIF2RX2_ENA */
-#define WM5100_AIF2RX2_ENA_SHIFT 1 /* AIF2RX2_ENA */
-#define WM5100_AIF2RX2_ENA_WIDTH 1 /* AIF2RX2_ENA */
-#define WM5100_AIF2RX1_ENA 0x0001 /* AIF2RX1_ENA */
-#define WM5100_AIF2RX1_ENA_MASK 0x0001 /* AIF2RX1_ENA */
-#define WM5100_AIF2RX1_ENA_SHIFT 0 /* AIF2RX1_ENA */
-#define WM5100_AIF2RX1_ENA_WIDTH 1 /* AIF2RX1_ENA */
-
-/*
- * R1408 (0x580) - Audio IF 3_1
- */
-#define WM5100_AIF3_BCLK_INV 0x0080 /* AIF3_BCLK_INV */
-#define WM5100_AIF3_BCLK_INV_MASK 0x0080 /* AIF3_BCLK_INV */
-#define WM5100_AIF3_BCLK_INV_SHIFT 7 /* AIF3_BCLK_INV */
-#define WM5100_AIF3_BCLK_INV_WIDTH 1 /* AIF3_BCLK_INV */
-#define WM5100_AIF3_BCLK_FRC 0x0040 /* AIF3_BCLK_FRC */
-#define WM5100_AIF3_BCLK_FRC_MASK 0x0040 /* AIF3_BCLK_FRC */
-#define WM5100_AIF3_BCLK_FRC_SHIFT 6 /* AIF3_BCLK_FRC */
-#define WM5100_AIF3_BCLK_FRC_WIDTH 1 /* AIF3_BCLK_FRC */
-#define WM5100_AIF3_BCLK_MSTR 0x0020 /* AIF3_BCLK_MSTR */
-#define WM5100_AIF3_BCLK_MSTR_MASK 0x0020 /* AIF3_BCLK_MSTR */
-#define WM5100_AIF3_BCLK_MSTR_SHIFT 5 /* AIF3_BCLK_MSTR */
-#define WM5100_AIF3_BCLK_MSTR_WIDTH 1 /* AIF3_BCLK_MSTR */
-#define WM5100_AIF3_BCLK_FREQ_MASK 0x001F /* AIF3_BCLK_FREQ - [4:0] */
-#define WM5100_AIF3_BCLK_FREQ_SHIFT 0 /* AIF3_BCLK_FREQ - [4:0] */
-#define WM5100_AIF3_BCLK_FREQ_WIDTH 5 /* AIF3_BCLK_FREQ - [4:0] */
-
-/*
- * R1409 (0x581) - Audio IF 3_2
- */
-#define WM5100_AIF3TX_DAT_TRI 0x0020 /* AIF3TX_DAT_TRI */
-#define WM5100_AIF3TX_DAT_TRI_MASK 0x0020 /* AIF3TX_DAT_TRI */
-#define WM5100_AIF3TX_DAT_TRI_SHIFT 5 /* AIF3TX_DAT_TRI */
-#define WM5100_AIF3TX_DAT_TRI_WIDTH 1 /* AIF3TX_DAT_TRI */
-#define WM5100_AIF3TX_LRCLK_SRC 0x0008 /* AIF3TX_LRCLK_SRC */
-#define WM5100_AIF3TX_LRCLK_SRC_MASK 0x0008 /* AIF3TX_LRCLK_SRC */
-#define WM5100_AIF3TX_LRCLK_SRC_SHIFT 3 /* AIF3TX_LRCLK_SRC */
-#define WM5100_AIF3TX_LRCLK_SRC_WIDTH 1 /* AIF3TX_LRCLK_SRC */
-#define WM5100_AIF3TX_LRCLK_INV 0x0004 /* AIF3TX_LRCLK_INV */
-#define WM5100_AIF3TX_LRCLK_INV_MASK 0x0004 /* AIF3TX_LRCLK_INV */
-#define WM5100_AIF3TX_LRCLK_INV_SHIFT 2 /* AIF3TX_LRCLK_INV */
-#define WM5100_AIF3TX_LRCLK_INV_WIDTH 1 /* AIF3TX_LRCLK_INV */
-#define WM5100_AIF3TX_LRCLK_FRC 0x0002 /* AIF3TX_LRCLK_FRC */
-#define WM5100_AIF3TX_LRCLK_FRC_MASK 0x0002 /* AIF3TX_LRCLK_FRC */
-#define WM5100_AIF3TX_LRCLK_FRC_SHIFT 1 /* AIF3TX_LRCLK_FRC */
-#define WM5100_AIF3TX_LRCLK_FRC_WIDTH 1 /* AIF3TX_LRCLK_FRC */
-#define WM5100_AIF3TX_LRCLK_MSTR 0x0001 /* AIF3TX_LRCLK_MSTR */
-#define WM5100_AIF3TX_LRCLK_MSTR_MASK 0x0001 /* AIF3TX_LRCLK_MSTR */
-#define WM5100_AIF3TX_LRCLK_MSTR_SHIFT 0 /* AIF3TX_LRCLK_MSTR */
-#define WM5100_AIF3TX_LRCLK_MSTR_WIDTH 1 /* AIF3TX_LRCLK_MSTR */
-
-/*
- * R1410 (0x582) - Audio IF 3_3
- */
-#define WM5100_AIF3RX_LRCLK_INV 0x0004 /* AIF3RX_LRCLK_INV */
-#define WM5100_AIF3RX_LRCLK_INV_MASK 0x0004 /* AIF3RX_LRCLK_INV */
-#define WM5100_AIF3RX_LRCLK_INV_SHIFT 2 /* AIF3RX_LRCLK_INV */
-#define WM5100_AIF3RX_LRCLK_INV_WIDTH 1 /* AIF3RX_LRCLK_INV */
-#define WM5100_AIF3RX_LRCLK_FRC 0x0002 /* AIF3RX_LRCLK_FRC */
-#define WM5100_AIF3RX_LRCLK_FRC_MASK 0x0002 /* AIF3RX_LRCLK_FRC */
-#define WM5100_AIF3RX_LRCLK_FRC_SHIFT 1 /* AIF3RX_LRCLK_FRC */
-#define WM5100_AIF3RX_LRCLK_FRC_WIDTH 1 /* AIF3RX_LRCLK_FRC */
-#define WM5100_AIF3RX_LRCLK_MSTR 0x0001 /* AIF3RX_LRCLK_MSTR */
-#define WM5100_AIF3RX_LRCLK_MSTR_MASK 0x0001 /* AIF3RX_LRCLK_MSTR */
-#define WM5100_AIF3RX_LRCLK_MSTR_SHIFT 0 /* AIF3RX_LRCLK_MSTR */
-#define WM5100_AIF3RX_LRCLK_MSTR_WIDTH 1 /* AIF3RX_LRCLK_MSTR */
-
-/*
- * R1411 (0x583) - Audio IF 3_4
- */
-#define WM5100_AIF3_TRI 0x0040 /* AIF3_TRI */
-#define WM5100_AIF3_TRI_MASK 0x0040 /* AIF3_TRI */
-#define WM5100_AIF3_TRI_SHIFT 6 /* AIF3_TRI */
-#define WM5100_AIF3_TRI_WIDTH 1 /* AIF3_TRI */
-#define WM5100_AIF3_RATE_MASK 0x0003 /* AIF3_RATE - [1:0] */
-#define WM5100_AIF3_RATE_SHIFT 0 /* AIF3_RATE - [1:0] */
-#define WM5100_AIF3_RATE_WIDTH 2 /* AIF3_RATE - [1:0] */
-
-/*
- * R1412 (0x584) - Audio IF 3_5
- */
-#define WM5100_AIF3_FMT_MASK 0x0007 /* AIF3_FMT - [2:0] */
-#define WM5100_AIF3_FMT_SHIFT 0 /* AIF3_FMT - [2:0] */
-#define WM5100_AIF3_FMT_WIDTH 3 /* AIF3_FMT - [2:0] */
-
-/*
- * R1413 (0x585) - Audio IF 3_6
- */
-#define WM5100_AIF3TX_BCPF_MASK 0x1FFF /* AIF3TX_BCPF - [12:0] */
-#define WM5100_AIF3TX_BCPF_SHIFT 0 /* AIF3TX_BCPF - [12:0] */
-#define WM5100_AIF3TX_BCPF_WIDTH 13 /* AIF3TX_BCPF - [12:0] */
-
-/*
- * R1414 (0x586) - Audio IF 3_7
- */
-#define WM5100_AIF3RX_BCPF_MASK 0x1FFF /* AIF3RX_BCPF - [12:0] */
-#define WM5100_AIF3RX_BCPF_SHIFT 0 /* AIF3RX_BCPF - [12:0] */
-#define WM5100_AIF3RX_BCPF_WIDTH 13 /* AIF3RX_BCPF - [12:0] */
-
-/*
- * R1415 (0x587) - Audio IF 3_8
- */
-#define WM5100_AIF3TX_WL_MASK 0x3F00 /* AIF3TX_WL - [13:8] */
-#define WM5100_AIF3TX_WL_SHIFT 8 /* AIF3TX_WL - [13:8] */
-#define WM5100_AIF3TX_WL_WIDTH 6 /* AIF3TX_WL - [13:8] */
-#define WM5100_AIF3TX_SLOT_LEN_MASK 0x00FF /* AIF3TX_SLOT_LEN - [7:0] */
-#define WM5100_AIF3TX_SLOT_LEN_SHIFT 0 /* AIF3TX_SLOT_LEN - [7:0] */
-#define WM5100_AIF3TX_SLOT_LEN_WIDTH 8 /* AIF3TX_SLOT_LEN - [7:0] */
-
-/*
- * R1416 (0x588) - Audio IF 3_9
- */
-#define WM5100_AIF3RX_WL_MASK 0x3F00 /* AIF3RX_WL - [13:8] */
-#define WM5100_AIF3RX_WL_SHIFT 8 /* AIF3RX_WL - [13:8] */
-#define WM5100_AIF3RX_WL_WIDTH 6 /* AIF3RX_WL - [13:8] */
-#define WM5100_AIF3RX_SLOT_LEN_MASK 0x00FF /* AIF3RX_SLOT_LEN - [7:0] */
-#define WM5100_AIF3RX_SLOT_LEN_SHIFT 0 /* AIF3RX_SLOT_LEN - [7:0] */
-#define WM5100_AIF3RX_SLOT_LEN_WIDTH 8 /* AIF3RX_SLOT_LEN - [7:0] */
-
-/*
- * R1417 (0x589) - Audio IF 3_10
- */
-#define WM5100_AIF3TX1_SLOT_MASK 0x003F /* AIF3TX1_SLOT - [5:0] */
-#define WM5100_AIF3TX1_SLOT_SHIFT 0 /* AIF3TX1_SLOT - [5:0] */
-#define WM5100_AIF3TX1_SLOT_WIDTH 6 /* AIF3TX1_SLOT - [5:0] */
-
-/*
- * R1418 (0x58A) - Audio IF 3_11
- */
-#define WM5100_AIF3TX2_SLOT_MASK 0x003F /* AIF3TX2_SLOT - [5:0] */
-#define WM5100_AIF3TX2_SLOT_SHIFT 0 /* AIF3TX2_SLOT - [5:0] */
-#define WM5100_AIF3TX2_SLOT_WIDTH 6 /* AIF3TX2_SLOT - [5:0] */
-
-/*
- * R1425 (0x591) - Audio IF 3_18
- */
-#define WM5100_AIF3RX1_SLOT_MASK 0x003F /* AIF3RX1_SLOT - [5:0] */
-#define WM5100_AIF3RX1_SLOT_SHIFT 0 /* AIF3RX1_SLOT - [5:0] */
-#define WM5100_AIF3RX1_SLOT_WIDTH 6 /* AIF3RX1_SLOT - [5:0] */
-
-/*
- * R1426 (0x592) - Audio IF 3_19
- */
-#define WM5100_AIF3RX2_SLOT_MASK 0x003F /* AIF3RX2_SLOT - [5:0] */
-#define WM5100_AIF3RX2_SLOT_SHIFT 0 /* AIF3RX2_SLOT - [5:0] */
-#define WM5100_AIF3RX2_SLOT_WIDTH 6 /* AIF3RX2_SLOT - [5:0] */
-
-/*
- * R1433 (0x599) - Audio IF 3_26
- */
-#define WM5100_AIF3TX2_ENA 0x0002 /* AIF3TX2_ENA */
-#define WM5100_AIF3TX2_ENA_MASK 0x0002 /* AIF3TX2_ENA */
-#define WM5100_AIF3TX2_ENA_SHIFT 1 /* AIF3TX2_ENA */
-#define WM5100_AIF3TX2_ENA_WIDTH 1 /* AIF3TX2_ENA */
-#define WM5100_AIF3TX1_ENA 0x0001 /* AIF3TX1_ENA */
-#define WM5100_AIF3TX1_ENA_MASK 0x0001 /* AIF3TX1_ENA */
-#define WM5100_AIF3TX1_ENA_SHIFT 0 /* AIF3TX1_ENA */
-#define WM5100_AIF3TX1_ENA_WIDTH 1 /* AIF3TX1_ENA */
-
-/*
- * R1434 (0x59A) - Audio IF 3_27
- */
-#define WM5100_AIF3RX2_ENA 0x0002 /* AIF3RX2_ENA */
-#define WM5100_AIF3RX2_ENA_MASK 0x0002 /* AIF3RX2_ENA */
-#define WM5100_AIF3RX2_ENA_SHIFT 1 /* AIF3RX2_ENA */
-#define WM5100_AIF3RX2_ENA_WIDTH 1 /* AIF3RX2_ENA */
-#define WM5100_AIF3RX1_ENA 0x0001 /* AIF3RX1_ENA */
-#define WM5100_AIF3RX1_ENA_MASK 0x0001 /* AIF3RX1_ENA */
-#define WM5100_AIF3RX1_ENA_SHIFT 0 /* AIF3RX1_ENA */
-#define WM5100_AIF3RX1_ENA_WIDTH 1 /* AIF3RX1_ENA */
-
-#define WM5100_MIXER_VOL_MASK 0x00FE /* MIXER_VOL - [7:1] */
-#define WM5100_MIXER_VOL_SHIFT 1 /* MIXER_VOL - [7:1] */
-#define WM5100_MIXER_VOL_WIDTH 7 /* MIXER_VOL - [7:1] */
-
-/*
- * R3072 (0xC00) - GPIO CTRL 1
- */
-#define WM5100_GP1_DIR 0x8000 /* GP1_DIR */
-#define WM5100_GP1_DIR_MASK 0x8000 /* GP1_DIR */
-#define WM5100_GP1_DIR_SHIFT 15 /* GP1_DIR */
-#define WM5100_GP1_DIR_WIDTH 1 /* GP1_DIR */
-#define WM5100_GP1_PU 0x4000 /* GP1_PU */
-#define WM5100_GP1_PU_MASK 0x4000 /* GP1_PU */
-#define WM5100_GP1_PU_SHIFT 14 /* GP1_PU */
-#define WM5100_GP1_PU_WIDTH 1 /* GP1_PU */
-#define WM5100_GP1_PD 0x2000 /* GP1_PD */
-#define WM5100_GP1_PD_MASK 0x2000 /* GP1_PD */
-#define WM5100_GP1_PD_SHIFT 13 /* GP1_PD */
-#define WM5100_GP1_PD_WIDTH 1 /* GP1_PD */
-#define WM5100_GP1_POL 0x0400 /* GP1_POL */
-#define WM5100_GP1_POL_MASK 0x0400 /* GP1_POL */
-#define WM5100_GP1_POL_SHIFT 10 /* GP1_POL */
-#define WM5100_GP1_POL_WIDTH 1 /* GP1_POL */
-#define WM5100_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */
-#define WM5100_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */
-#define WM5100_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */
-#define WM5100_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
-#define WM5100_GP1_DB 0x0100 /* GP1_DB */
-#define WM5100_GP1_DB_MASK 0x0100 /* GP1_DB */
-#define WM5100_GP1_DB_SHIFT 8 /* GP1_DB */
-#define WM5100_GP1_DB_WIDTH 1 /* GP1_DB */
-#define WM5100_GP1_LVL 0x0040 /* GP1_LVL */
-#define WM5100_GP1_LVL_MASK 0x0040 /* GP1_LVL */
-#define WM5100_GP1_LVL_SHIFT 6 /* GP1_LVL */
-#define WM5100_GP1_LVL_WIDTH 1 /* GP1_LVL */
-#define WM5100_GP1_FN_MASK 0x003F /* GP1_FN - [5:0] */
-#define WM5100_GP1_FN_SHIFT 0 /* GP1_FN - [5:0] */
-#define WM5100_GP1_FN_WIDTH 6 /* GP1_FN - [5:0] */
-
-/*
- * R3073 (0xC01) - GPIO CTRL 2
- */
-#define WM5100_GP2_DIR 0x8000 /* GP2_DIR */
-#define WM5100_GP2_DIR_MASK 0x8000 /* GP2_DIR */
-#define WM5100_GP2_DIR_SHIFT 15 /* GP2_DIR */
-#define WM5100_GP2_DIR_WIDTH 1 /* GP2_DIR */
-#define WM5100_GP2_PU 0x4000 /* GP2_PU */
-#define WM5100_GP2_PU_MASK 0x4000 /* GP2_PU */
-#define WM5100_GP2_PU_SHIFT 14 /* GP2_PU */
-#define WM5100_GP2_PU_WIDTH 1 /* GP2_PU */
-#define WM5100_GP2_PD 0x2000 /* GP2_PD */
-#define WM5100_GP2_PD_MASK 0x2000 /* GP2_PD */
-#define WM5100_GP2_PD_SHIFT 13 /* GP2_PD */
-#define WM5100_GP2_PD_WIDTH 1 /* GP2_PD */
-#define WM5100_GP2_POL 0x0400 /* GP2_POL */
-#define WM5100_GP2_POL_MASK 0x0400 /* GP2_POL */
-#define WM5100_GP2_POL_SHIFT 10 /* GP2_POL */
-#define WM5100_GP2_POL_WIDTH 1 /* GP2_POL */
-#define WM5100_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */
-#define WM5100_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */
-#define WM5100_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */
-#define WM5100_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
-#define WM5100_GP2_DB 0x0100 /* GP2_DB */
-#define WM5100_GP2_DB_MASK 0x0100 /* GP2_DB */
-#define WM5100_GP2_DB_SHIFT 8 /* GP2_DB */
-#define WM5100_GP2_DB_WIDTH 1 /* GP2_DB */
-#define WM5100_GP2_LVL 0x0040 /* GP2_LVL */
-#define WM5100_GP2_LVL_MASK 0x0040 /* GP2_LVL */
-#define WM5100_GP2_LVL_SHIFT 6 /* GP2_LVL */
-#define WM5100_GP2_LVL_WIDTH 1 /* GP2_LVL */
-#define WM5100_GP2_FN_MASK 0x003F /* GP2_FN - [5:0] */
-#define WM5100_GP2_FN_SHIFT 0 /* GP2_FN - [5:0] */
-#define WM5100_GP2_FN_WIDTH 6 /* GP2_FN - [5:0] */
-
-/*
- * R3074 (0xC02) - GPIO CTRL 3
- */
-#define WM5100_GP3_DIR 0x8000 /* GP3_DIR */
-#define WM5100_GP3_DIR_MASK 0x8000 /* GP3_DIR */
-#define WM5100_GP3_DIR_SHIFT 15 /* GP3_DIR */
-#define WM5100_GP3_DIR_WIDTH 1 /* GP3_DIR */
-#define WM5100_GP3_PU 0x4000 /* GP3_PU */
-#define WM5100_GP3_PU_MASK 0x4000 /* GP3_PU */
-#define WM5100_GP3_PU_SHIFT 14 /* GP3_PU */
-#define WM5100_GP3_PU_WIDTH 1 /* GP3_PU */
-#define WM5100_GP3_PD 0x2000 /* GP3_PD */
-#define WM5100_GP3_PD_MASK 0x2000 /* GP3_PD */
-#define WM5100_GP3_PD_SHIFT 13 /* GP3_PD */
-#define WM5100_GP3_PD_WIDTH 1 /* GP3_PD */
-#define WM5100_GP3_POL 0x0400 /* GP3_POL */
-#define WM5100_GP3_POL_MASK 0x0400 /* GP3_POL */
-#define WM5100_GP3_POL_SHIFT 10 /* GP3_POL */
-#define WM5100_GP3_POL_WIDTH 1 /* GP3_POL */
-#define WM5100_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */
-#define WM5100_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */
-#define WM5100_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */
-#define WM5100_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
-#define WM5100_GP3_DB 0x0100 /* GP3_DB */
-#define WM5100_GP3_DB_MASK 0x0100 /* GP3_DB */
-#define WM5100_GP3_DB_SHIFT 8 /* GP3_DB */
-#define WM5100_GP3_DB_WIDTH 1 /* GP3_DB */
-#define WM5100_GP3_LVL 0x0040 /* GP3_LVL */
-#define WM5100_GP3_LVL_MASK 0x0040 /* GP3_LVL */
-#define WM5100_GP3_LVL_SHIFT 6 /* GP3_LVL */
-#define WM5100_GP3_LVL_WIDTH 1 /* GP3_LVL */
-#define WM5100_GP3_FN_MASK 0x003F /* GP3_FN - [5:0] */
-#define WM5100_GP3_FN_SHIFT 0 /* GP3_FN - [5:0] */
-#define WM5100_GP3_FN_WIDTH 6 /* GP3_FN - [5:0] */
-
-/*
- * R3075 (0xC03) - GPIO CTRL 4
- */
-#define WM5100_GP4_DIR 0x8000 /* GP4_DIR */
-#define WM5100_GP4_DIR_MASK 0x8000 /* GP4_DIR */
-#define WM5100_GP4_DIR_SHIFT 15 /* GP4_DIR */
-#define WM5100_GP4_DIR_WIDTH 1 /* GP4_DIR */
-#define WM5100_GP4_PU 0x4000 /* GP4_PU */
-#define WM5100_GP4_PU_MASK 0x4000 /* GP4_PU */
-#define WM5100_GP4_PU_SHIFT 14 /* GP4_PU */
-#define WM5100_GP4_PU_WIDTH 1 /* GP4_PU */
-#define WM5100_GP4_PD 0x2000 /* GP4_PD */
-#define WM5100_GP4_PD_MASK 0x2000 /* GP4_PD */
-#define WM5100_GP4_PD_SHIFT 13 /* GP4_PD */
-#define WM5100_GP4_PD_WIDTH 1 /* GP4_PD */
-#define WM5100_GP4_POL 0x0400 /* GP4_POL */
-#define WM5100_GP4_POL_MASK 0x0400 /* GP4_POL */
-#define WM5100_GP4_POL_SHIFT 10 /* GP4_POL */
-#define WM5100_GP4_POL_WIDTH 1 /* GP4_POL */
-#define WM5100_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */
-#define WM5100_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */
-#define WM5100_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */
-#define WM5100_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
-#define WM5100_GP4_DB 0x0100 /* GP4_DB */
-#define WM5100_GP4_DB_MASK 0x0100 /* GP4_DB */
-#define WM5100_GP4_DB_SHIFT 8 /* GP4_DB */
-#define WM5100_GP4_DB_WIDTH 1 /* GP4_DB */
-#define WM5100_GP4_LVL 0x0040 /* GP4_LVL */
-#define WM5100_GP4_LVL_MASK 0x0040 /* GP4_LVL */
-#define WM5100_GP4_LVL_SHIFT 6 /* GP4_LVL */
-#define WM5100_GP4_LVL_WIDTH 1 /* GP4_LVL */
-#define WM5100_GP4_FN_MASK 0x003F /* GP4_FN - [5:0] */
-#define WM5100_GP4_FN_SHIFT 0 /* GP4_FN - [5:0] */
-#define WM5100_GP4_FN_WIDTH 6 /* GP4_FN - [5:0] */
-
-/*
- * R3076 (0xC04) - GPIO CTRL 5
- */
-#define WM5100_GP5_DIR 0x8000 /* GP5_DIR */
-#define WM5100_GP5_DIR_MASK 0x8000 /* GP5_DIR */
-#define WM5100_GP5_DIR_SHIFT 15 /* GP5_DIR */
-#define WM5100_GP5_DIR_WIDTH 1 /* GP5_DIR */
-#define WM5100_GP5_PU 0x4000 /* GP5_PU */
-#define WM5100_GP5_PU_MASK 0x4000 /* GP5_PU */
-#define WM5100_GP5_PU_SHIFT 14 /* GP5_PU */
-#define WM5100_GP5_PU_WIDTH 1 /* GP5_PU */
-#define WM5100_GP5_PD 0x2000 /* GP5_PD */
-#define WM5100_GP5_PD_MASK 0x2000 /* GP5_PD */
-#define WM5100_GP5_PD_SHIFT 13 /* GP5_PD */
-#define WM5100_GP5_PD_WIDTH 1 /* GP5_PD */
-#define WM5100_GP5_POL 0x0400 /* GP5_POL */
-#define WM5100_GP5_POL_MASK 0x0400 /* GP5_POL */
-#define WM5100_GP5_POL_SHIFT 10 /* GP5_POL */
-#define WM5100_GP5_POL_WIDTH 1 /* GP5_POL */
-#define WM5100_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */
-#define WM5100_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */
-#define WM5100_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */
-#define WM5100_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
-#define WM5100_GP5_DB 0x0100 /* GP5_DB */
-#define WM5100_GP5_DB_MASK 0x0100 /* GP5_DB */
-#define WM5100_GP5_DB_SHIFT 8 /* GP5_DB */
-#define WM5100_GP5_DB_WIDTH 1 /* GP5_DB */
-#define WM5100_GP5_LVL 0x0040 /* GP5_LVL */
-#define WM5100_GP5_LVL_MASK 0x0040 /* GP5_LVL */
-#define WM5100_GP5_LVL_SHIFT 6 /* GP5_LVL */
-#define WM5100_GP5_LVL_WIDTH 1 /* GP5_LVL */
-#define WM5100_GP5_FN_MASK 0x003F /* GP5_FN - [5:0] */
-#define WM5100_GP5_FN_SHIFT 0 /* GP5_FN - [5:0] */
-#define WM5100_GP5_FN_WIDTH 6 /* GP5_FN - [5:0] */
-
-/*
- * R3077 (0xC05) - GPIO CTRL 6
- */
-#define WM5100_GP6_DIR 0x8000 /* GP6_DIR */
-#define WM5100_GP6_DIR_MASK 0x8000 /* GP6_DIR */
-#define WM5100_GP6_DIR_SHIFT 15 /* GP6_DIR */
-#define WM5100_GP6_DIR_WIDTH 1 /* GP6_DIR */
-#define WM5100_GP6_PU 0x4000 /* GP6_PU */
-#define WM5100_GP6_PU_MASK 0x4000 /* GP6_PU */
-#define WM5100_GP6_PU_SHIFT 14 /* GP6_PU */
-#define WM5100_GP6_PU_WIDTH 1 /* GP6_PU */
-#define WM5100_GP6_PD 0x2000 /* GP6_PD */
-#define WM5100_GP6_PD_MASK 0x2000 /* GP6_PD */
-#define WM5100_GP6_PD_SHIFT 13 /* GP6_PD */
-#define WM5100_GP6_PD_WIDTH 1 /* GP6_PD */
-#define WM5100_GP6_POL 0x0400 /* GP6_POL */
-#define WM5100_GP6_POL_MASK 0x0400 /* GP6_POL */
-#define WM5100_GP6_POL_SHIFT 10 /* GP6_POL */
-#define WM5100_GP6_POL_WIDTH 1 /* GP6_POL */
-#define WM5100_GP6_OP_CFG 0x0200 /* GP6_OP_CFG */
-#define WM5100_GP6_OP_CFG_MASK 0x0200 /* GP6_OP_CFG */
-#define WM5100_GP6_OP_CFG_SHIFT 9 /* GP6_OP_CFG */
-#define WM5100_GP6_OP_CFG_WIDTH 1 /* GP6_OP_CFG */
-#define WM5100_GP6_DB 0x0100 /* GP6_DB */
-#define WM5100_GP6_DB_MASK 0x0100 /* GP6_DB */
-#define WM5100_GP6_DB_SHIFT 8 /* GP6_DB */
-#define WM5100_GP6_DB_WIDTH 1 /* GP6_DB */
-#define WM5100_GP6_LVL 0x0040 /* GP6_LVL */
-#define WM5100_GP6_LVL_MASK 0x0040 /* GP6_LVL */
-#define WM5100_GP6_LVL_SHIFT 6 /* GP6_LVL */
-#define WM5100_GP6_LVL_WIDTH 1 /* GP6_LVL */
-#define WM5100_GP6_FN_MASK 0x003F /* GP6_FN - [5:0] */
-#define WM5100_GP6_FN_SHIFT 0 /* GP6_FN - [5:0] */
-#define WM5100_GP6_FN_WIDTH 6 /* GP6_FN - [5:0] */
-
-/*
- * R3107 (0xC23) - Misc Pad Ctrl 1
- */
-#define WM5100_LDO1ENA_PD 0x8000 /* LDO1ENA_PD */
-#define WM5100_LDO1ENA_PD_MASK 0x8000 /* LDO1ENA_PD */
-#define WM5100_LDO1ENA_PD_SHIFT 15 /* LDO1ENA_PD */
-#define WM5100_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */
-#define WM5100_MCLK2_PD 0x2000 /* MCLK2_PD */
-#define WM5100_MCLK2_PD_MASK 0x2000 /* MCLK2_PD */
-#define WM5100_MCLK2_PD_SHIFT 13 /* MCLK2_PD */
-#define WM5100_MCLK2_PD_WIDTH 1 /* MCLK2_PD */
-#define WM5100_MCLK1_PD 0x1000 /* MCLK1_PD */
-#define WM5100_MCLK1_PD_MASK 0x1000 /* MCLK1_PD */
-#define WM5100_MCLK1_PD_SHIFT 12 /* MCLK1_PD */
-#define WM5100_MCLK1_PD_WIDTH 1 /* MCLK1_PD */
-#define WM5100_RESET_PU 0x0002 /* RESET_PU */
-#define WM5100_RESET_PU_MASK 0x0002 /* RESET_PU */
-#define WM5100_RESET_PU_SHIFT 1 /* RESET_PU */
-#define WM5100_RESET_PU_WIDTH 1 /* RESET_PU */
-#define WM5100_ADDR_PD 0x0001 /* ADDR_PD */
-#define WM5100_ADDR_PD_MASK 0x0001 /* ADDR_PD */
-#define WM5100_ADDR_PD_SHIFT 0 /* ADDR_PD */
-#define WM5100_ADDR_PD_WIDTH 1 /* ADDR_PD */
-
-/*
- * R3108 (0xC24) - Misc Pad Ctrl 2
- */
-#define WM5100_DMICDAT4_PD 0x0008 /* DMICDAT4_PD */
-#define WM5100_DMICDAT4_PD_MASK 0x0008 /* DMICDAT4_PD */
-#define WM5100_DMICDAT4_PD_SHIFT 3 /* DMICDAT4_PD */
-#define WM5100_DMICDAT4_PD_WIDTH 1 /* DMICDAT4_PD */
-#define WM5100_DMICDAT3_PD 0x0004 /* DMICDAT3_PD */
-#define WM5100_DMICDAT3_PD_MASK 0x0004 /* DMICDAT3_PD */
-#define WM5100_DMICDAT3_PD_SHIFT 2 /* DMICDAT3_PD */
-#define WM5100_DMICDAT3_PD_WIDTH 1 /* DMICDAT3_PD */
-#define WM5100_DMICDAT2_PD 0x0002 /* DMICDAT2_PD */
-#define WM5100_DMICDAT2_PD_MASK 0x0002 /* DMICDAT2_PD */
-#define WM5100_DMICDAT2_PD_SHIFT 1 /* DMICDAT2_PD */
-#define WM5100_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */
-#define WM5100_DMICDAT1_PD 0x0001 /* DMICDAT1_PD */
-#define WM5100_DMICDAT1_PD_MASK 0x0001 /* DMICDAT1_PD */
-#define WM5100_DMICDAT1_PD_SHIFT 0 /* DMICDAT1_PD */
-#define WM5100_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */
-
-/*
- * R3109 (0xC25) - Misc Pad Ctrl 3
- */
-#define WM5100_AIF1RXLRCLK_PU 0x0020 /* AIF1RXLRCLK_PU */
-#define WM5100_AIF1RXLRCLK_PU_MASK 0x0020 /* AIF1RXLRCLK_PU */
-#define WM5100_AIF1RXLRCLK_PU_SHIFT 5 /* AIF1RXLRCLK_PU */
-#define WM5100_AIF1RXLRCLK_PU_WIDTH 1 /* AIF1RXLRCLK_PU */
-#define WM5100_AIF1RXLRCLK_PD 0x0010 /* AIF1RXLRCLK_PD */
-#define WM5100_AIF1RXLRCLK_PD_MASK 0x0010 /* AIF1RXLRCLK_PD */
-#define WM5100_AIF1RXLRCLK_PD_SHIFT 4 /* AIF1RXLRCLK_PD */
-#define WM5100_AIF1RXLRCLK_PD_WIDTH 1 /* AIF1RXLRCLK_PD */
-#define WM5100_AIF1BCLK_PU 0x0008 /* AIF1BCLK_PU */
-#define WM5100_AIF1BCLK_PU_MASK 0x0008 /* AIF1BCLK_PU */
-#define WM5100_AIF1BCLK_PU_SHIFT 3 /* AIF1BCLK_PU */
-#define WM5100_AIF1BCLK_PU_WIDTH 1 /* AIF1BCLK_PU */
-#define WM5100_AIF1BCLK_PD 0x0004 /* AIF1BCLK_PD */
-#define WM5100_AIF1BCLK_PD_MASK 0x0004 /* AIF1BCLK_PD */
-#define WM5100_AIF1BCLK_PD_SHIFT 2 /* AIF1BCLK_PD */
-#define WM5100_AIF1BCLK_PD_WIDTH 1 /* AIF1BCLK_PD */
-#define WM5100_AIF1RXDAT_PU 0x0002 /* AIF1RXDAT_PU */
-#define WM5100_AIF1RXDAT_PU_MASK 0x0002 /* AIF1RXDAT_PU */
-#define WM5100_AIF1RXDAT_PU_SHIFT 1 /* AIF1RXDAT_PU */
-#define WM5100_AIF1RXDAT_PU_WIDTH 1 /* AIF1RXDAT_PU */
-#define WM5100_AIF1RXDAT_PD 0x0001 /* AIF1RXDAT_PD */
-#define WM5100_AIF1RXDAT_PD_MASK 0x0001 /* AIF1RXDAT_PD */
-#define WM5100_AIF1RXDAT_PD_SHIFT 0 /* AIF1RXDAT_PD */
-#define WM5100_AIF1RXDAT_PD_WIDTH 1 /* AIF1RXDAT_PD */
-
-/*
- * R3110 (0xC26) - Misc Pad Ctrl 4
- */
-#define WM5100_AIF2RXLRCLK_PU 0x0020 /* AIF2RXLRCLK_PU */
-#define WM5100_AIF2RXLRCLK_PU_MASK 0x0020 /* AIF2RXLRCLK_PU */
-#define WM5100_AIF2RXLRCLK_PU_SHIFT 5 /* AIF2RXLRCLK_PU */
-#define WM5100_AIF2RXLRCLK_PU_WIDTH 1 /* AIF2RXLRCLK_PU */
-#define WM5100_AIF2RXLRCLK_PD 0x0010 /* AIF2RXLRCLK_PD */
-#define WM5100_AIF2RXLRCLK_PD_MASK 0x0010 /* AIF2RXLRCLK_PD */
-#define WM5100_AIF2RXLRCLK_PD_SHIFT 4 /* AIF2RXLRCLK_PD */
-#define WM5100_AIF2RXLRCLK_PD_WIDTH 1 /* AIF2RXLRCLK_PD */
-#define WM5100_AIF2BCLK_PU 0x0008 /* AIF2BCLK_PU */
-#define WM5100_AIF2BCLK_PU_MASK 0x0008 /* AIF2BCLK_PU */
-#define WM5100_AIF2BCLK_PU_SHIFT 3 /* AIF2BCLK_PU */
-#define WM5100_AIF2BCLK_PU_WIDTH 1 /* AIF2BCLK_PU */
-#define WM5100_AIF2BCLK_PD 0x0004 /* AIF2BCLK_PD */
-#define WM5100_AIF2BCLK_PD_MASK 0x0004 /* AIF2BCLK_PD */
-#define WM5100_AIF2BCLK_PD_SHIFT 2 /* AIF2BCLK_PD */
-#define WM5100_AIF2BCLK_PD_WIDTH 1 /* AIF2BCLK_PD */
-#define WM5100_AIF2RXDAT_PU 0x0002 /* AIF2RXDAT_PU */
-#define WM5100_AIF2RXDAT_PU_MASK 0x0002 /* AIF2RXDAT_PU */
-#define WM5100_AIF2RXDAT_PU_SHIFT 1 /* AIF2RXDAT_PU */
-#define WM5100_AIF2RXDAT_PU_WIDTH 1 /* AIF2RXDAT_PU */
-#define WM5100_AIF2RXDAT_PD 0x0001 /* AIF2RXDAT_PD */
-#define WM5100_AIF2RXDAT_PD_MASK 0x0001 /* AIF2RXDAT_PD */
-#define WM5100_AIF2RXDAT_PD_SHIFT 0 /* AIF2RXDAT_PD */
-#define WM5100_AIF2RXDAT_PD_WIDTH 1 /* AIF2RXDAT_PD */
-
-/*
- * R3111 (0xC27) - Misc Pad Ctrl 5
- */
-#define WM5100_AIF3RXLRCLK_PU 0x0020 /* AIF3RXLRCLK_PU */
-#define WM5100_AIF3RXLRCLK_PU_MASK 0x0020 /* AIF3RXLRCLK_PU */
-#define WM5100_AIF3RXLRCLK_PU_SHIFT 5 /* AIF3RXLRCLK_PU */
-#define WM5100_AIF3RXLRCLK_PU_WIDTH 1 /* AIF3RXLRCLK_PU */
-#define WM5100_AIF3RXLRCLK_PD 0x0010 /* AIF3RXLRCLK_PD */
-#define WM5100_AIF3RXLRCLK_PD_MASK 0x0010 /* AIF3RXLRCLK_PD */
-#define WM5100_AIF3RXLRCLK_PD_SHIFT 4 /* AIF3RXLRCLK_PD */
-#define WM5100_AIF3RXLRCLK_PD_WIDTH 1 /* AIF3RXLRCLK_PD */
-#define WM5100_AIF3BCLK_PU 0x0008 /* AIF3BCLK_PU */
-#define WM5100_AIF3BCLK_PU_MASK 0x0008 /* AIF3BCLK_PU */
-#define WM5100_AIF3BCLK_PU_SHIFT 3 /* AIF3BCLK_PU */
-#define WM5100_AIF3BCLK_PU_WIDTH 1 /* AIF3BCLK_PU */
-#define WM5100_AIF3BCLK_PD 0x0004 /* AIF3BCLK_PD */
-#define WM5100_AIF3BCLK_PD_MASK 0x0004 /* AIF3BCLK_PD */
-#define WM5100_AIF3BCLK_PD_SHIFT 2 /* AIF3BCLK_PD */
-#define WM5100_AIF3BCLK_PD_WIDTH 1 /* AIF3BCLK_PD */
-#define WM5100_AIF3RXDAT_PU 0x0002 /* AIF3RXDAT_PU */
-#define WM5100_AIF3RXDAT_PU_MASK 0x0002 /* AIF3RXDAT_PU */
-#define WM5100_AIF3RXDAT_PU_SHIFT 1 /* AIF3RXDAT_PU */
-#define WM5100_AIF3RXDAT_PU_WIDTH 1 /* AIF3RXDAT_PU */
-#define WM5100_AIF3RXDAT_PD 0x0001 /* AIF3RXDAT_PD */
-#define WM5100_AIF3RXDAT_PD_MASK 0x0001 /* AIF3RXDAT_PD */
-#define WM5100_AIF3RXDAT_PD_SHIFT 0 /* AIF3RXDAT_PD */
-#define WM5100_AIF3RXDAT_PD_WIDTH 1 /* AIF3RXDAT_PD */
-
-/*
- * R3112 (0xC28) - Misc GPIO 1
- */
-#define WM5100_OPCLK_SEL_MASK 0x0003 /* OPCLK_SEL - [1:0] */
-#define WM5100_OPCLK_SEL_SHIFT 0 /* OPCLK_SEL - [1:0] */
-#define WM5100_OPCLK_SEL_WIDTH 2 /* OPCLK_SEL - [1:0] */
-
-/*
- * R3328 (0xD00) - Interrupt Status 1
- */
-#define WM5100_GP6_EINT 0x0020 /* GP6_EINT */
-#define WM5100_GP6_EINT_MASK 0x0020 /* GP6_EINT */
-#define WM5100_GP6_EINT_SHIFT 5 /* GP6_EINT */
-#define WM5100_GP6_EINT_WIDTH 1 /* GP6_EINT */
-#define WM5100_GP5_EINT 0x0010 /* GP5_EINT */
-#define WM5100_GP5_EINT_MASK 0x0010 /* GP5_EINT */
-#define WM5100_GP5_EINT_SHIFT 4 /* GP5_EINT */
-#define WM5100_GP5_EINT_WIDTH 1 /* GP5_EINT */
-#define WM5100_GP4_EINT 0x0008 /* GP4_EINT */
-#define WM5100_GP4_EINT_MASK 0x0008 /* GP4_EINT */
-#define WM5100_GP4_EINT_SHIFT 3 /* GP4_EINT */
-#define WM5100_GP4_EINT_WIDTH 1 /* GP4_EINT */
-#define WM5100_GP3_EINT 0x0004 /* GP3_EINT */
-#define WM5100_GP3_EINT_MASK 0x0004 /* GP3_EINT */
-#define WM5100_GP3_EINT_SHIFT 2 /* GP3_EINT */
-#define WM5100_GP3_EINT_WIDTH 1 /* GP3_EINT */
-#define WM5100_GP2_EINT 0x0002 /* GP2_EINT */
-#define WM5100_GP2_EINT_MASK 0x0002 /* GP2_EINT */
-#define WM5100_GP2_EINT_SHIFT 1 /* GP2_EINT */
-#define WM5100_GP2_EINT_WIDTH 1 /* GP2_EINT */
-#define WM5100_GP1_EINT 0x0001 /* GP1_EINT */
-#define WM5100_GP1_EINT_MASK 0x0001 /* GP1_EINT */
-#define WM5100_GP1_EINT_SHIFT 0 /* GP1_EINT */
-#define WM5100_GP1_EINT_WIDTH 1 /* GP1_EINT */
-
-/*
- * R3329 (0xD01) - Interrupt Status 2
- */
-#define WM5100_DSP_IRQ6_EINT 0x0020 /* DSP_IRQ6_EINT */
-#define WM5100_DSP_IRQ6_EINT_MASK 0x0020 /* DSP_IRQ6_EINT */
-#define WM5100_DSP_IRQ6_EINT_SHIFT 5 /* DSP_IRQ6_EINT */
-#define WM5100_DSP_IRQ6_EINT_WIDTH 1 /* DSP_IRQ6_EINT */
-#define WM5100_DSP_IRQ5_EINT 0x0010 /* DSP_IRQ5_EINT */
-#define WM5100_DSP_IRQ5_EINT_MASK 0x0010 /* DSP_IRQ5_EINT */
-#define WM5100_DSP_IRQ5_EINT_SHIFT 4 /* DSP_IRQ5_EINT */
-#define WM5100_DSP_IRQ5_EINT_WIDTH 1 /* DSP_IRQ5_EINT */
-#define WM5100_DSP_IRQ4_EINT 0x0008 /* DSP_IRQ4_EINT */
-#define WM5100_DSP_IRQ4_EINT_MASK 0x0008 /* DSP_IRQ4_EINT */
-#define WM5100_DSP_IRQ4_EINT_SHIFT 3 /* DSP_IRQ4_EINT */
-#define WM5100_DSP_IRQ4_EINT_WIDTH 1 /* DSP_IRQ4_EINT */
-#define WM5100_DSP_IRQ3_EINT 0x0004 /* DSP_IRQ3_EINT */
-#define WM5100_DSP_IRQ3_EINT_MASK 0x0004 /* DSP_IRQ3_EINT */
-#define WM5100_DSP_IRQ3_EINT_SHIFT 2 /* DSP_IRQ3_EINT */
-#define WM5100_DSP_IRQ3_EINT_WIDTH 1 /* DSP_IRQ3_EINT */
-#define WM5100_DSP_IRQ2_EINT 0x0002 /* DSP_IRQ2_EINT */
-#define WM5100_DSP_IRQ2_EINT_MASK 0x0002 /* DSP_IRQ2_EINT */
-#define WM5100_DSP_IRQ2_EINT_SHIFT 1 /* DSP_IRQ2_EINT */
-#define WM5100_DSP_IRQ2_EINT_WIDTH 1 /* DSP_IRQ2_EINT */
-#define WM5100_DSP_IRQ1_EINT 0x0001 /* DSP_IRQ1_EINT */
-#define WM5100_DSP_IRQ1_EINT_MASK 0x0001 /* DSP_IRQ1_EINT */
-#define WM5100_DSP_IRQ1_EINT_SHIFT 0 /* DSP_IRQ1_EINT */
-#define WM5100_DSP_IRQ1_EINT_WIDTH 1 /* DSP_IRQ1_EINT */
-
-/*
- * R3330 (0xD02) - Interrupt Status 3
- */
-#define WM5100_SPK_SHUTDOWN_WARN_EINT 0x8000 /* SPK_SHUTDOWN_WARN_EINT */
-#define WM5100_SPK_SHUTDOWN_WARN_EINT_MASK 0x8000 /* SPK_SHUTDOWN_WARN_EINT */
-#define WM5100_SPK_SHUTDOWN_WARN_EINT_SHIFT 15 /* SPK_SHUTDOWN_WARN_EINT */
-#define WM5100_SPK_SHUTDOWN_WARN_EINT_WIDTH 1 /* SPK_SHUTDOWN_WARN_EINT */
-#define WM5100_SPK_SHUTDOWN_EINT 0x4000 /* SPK_SHUTDOWN_EINT */
-#define WM5100_SPK_SHUTDOWN_EINT_MASK 0x4000 /* SPK_SHUTDOWN_EINT */
-#define WM5100_SPK_SHUTDOWN_EINT_SHIFT 14 /* SPK_SHUTDOWN_EINT */
-#define WM5100_SPK_SHUTDOWN_EINT_WIDTH 1 /* SPK_SHUTDOWN_EINT */
-#define WM5100_HPDET_EINT 0x2000 /* HPDET_EINT */
-#define WM5100_HPDET_EINT_MASK 0x2000 /* HPDET_EINT */
-#define WM5100_HPDET_EINT_SHIFT 13 /* HPDET_EINT */
-#define WM5100_HPDET_EINT_WIDTH 1 /* HPDET_EINT */
-#define WM5100_ACCDET_EINT 0x1000 /* ACCDET_EINT */
-#define WM5100_ACCDET_EINT_MASK 0x1000 /* ACCDET_EINT */
-#define WM5100_ACCDET_EINT_SHIFT 12 /* ACCDET_EINT */
-#define WM5100_ACCDET_EINT_WIDTH 1 /* ACCDET_EINT */
-#define WM5100_DRC_SIG_DET_EINT 0x0200 /* DRC_SIG_DET_EINT */
-#define WM5100_DRC_SIG_DET_EINT_MASK 0x0200 /* DRC_SIG_DET_EINT */
-#define WM5100_DRC_SIG_DET_EINT_SHIFT 9 /* DRC_SIG_DET_EINT */
-#define WM5100_DRC_SIG_DET_EINT_WIDTH 1 /* DRC_SIG_DET_EINT */
-#define WM5100_ASRC2_LOCK_EINT 0x0100 /* ASRC2_LOCK_EINT */
-#define WM5100_ASRC2_LOCK_EINT_MASK 0x0100 /* ASRC2_LOCK_EINT */
-#define WM5100_ASRC2_LOCK_EINT_SHIFT 8 /* ASRC2_LOCK_EINT */
-#define WM5100_ASRC2_LOCK_EINT_WIDTH 1 /* ASRC2_LOCK_EINT */
-#define WM5100_ASRC1_LOCK_EINT 0x0080 /* ASRC1_LOCK_EINT */
-#define WM5100_ASRC1_LOCK_EINT_MASK 0x0080 /* ASRC1_LOCK_EINT */
-#define WM5100_ASRC1_LOCK_EINT_SHIFT 7 /* ASRC1_LOCK_EINT */
-#define WM5100_ASRC1_LOCK_EINT_WIDTH 1 /* ASRC1_LOCK_EINT */
-#define WM5100_FLL2_LOCK_EINT 0x0008 /* FLL2_LOCK_EINT */
-#define WM5100_FLL2_LOCK_EINT_MASK 0x0008 /* FLL2_LOCK_EINT */
-#define WM5100_FLL2_LOCK_EINT_SHIFT 3 /* FLL2_LOCK_EINT */
-#define WM5100_FLL2_LOCK_EINT_WIDTH 1 /* FLL2_LOCK_EINT */
-#define WM5100_FLL1_LOCK_EINT 0x0004 /* FLL1_LOCK_EINT */
-#define WM5100_FLL1_LOCK_EINT_MASK 0x0004 /* FLL1_LOCK_EINT */
-#define WM5100_FLL1_LOCK_EINT_SHIFT 2 /* FLL1_LOCK_EINT */
-#define WM5100_FLL1_LOCK_EINT_WIDTH 1 /* FLL1_LOCK_EINT */
-#define WM5100_CLKGEN_ERR_EINT 0x0002 /* CLKGEN_ERR_EINT */
-#define WM5100_CLKGEN_ERR_EINT_MASK 0x0002 /* CLKGEN_ERR_EINT */
-#define WM5100_CLKGEN_ERR_EINT_SHIFT 1 /* CLKGEN_ERR_EINT */
-#define WM5100_CLKGEN_ERR_EINT_WIDTH 1 /* CLKGEN_ERR_EINT */
-#define WM5100_CLKGEN_ERR_ASYNC_EINT 0x0001 /* CLKGEN_ERR_ASYNC_EINT */
-#define WM5100_CLKGEN_ERR_ASYNC_EINT_MASK 0x0001 /* CLKGEN_ERR_ASYNC_EINT */
-#define WM5100_CLKGEN_ERR_ASYNC_EINT_SHIFT 0 /* CLKGEN_ERR_ASYNC_EINT */
-#define WM5100_CLKGEN_ERR_ASYNC_EINT_WIDTH 1 /* CLKGEN_ERR_ASYNC_EINT */
-
-/*
- * R3331 (0xD03) - Interrupt Status 4
- */
-#define WM5100_AIF3_ERR_EINT 0x2000 /* AIF3_ERR_EINT */
-#define WM5100_AIF3_ERR_EINT_MASK 0x2000 /* AIF3_ERR_EINT */
-#define WM5100_AIF3_ERR_EINT_SHIFT 13 /* AIF3_ERR_EINT */
-#define WM5100_AIF3_ERR_EINT_WIDTH 1 /* AIF3_ERR_EINT */
-#define WM5100_AIF2_ERR_EINT 0x1000 /* AIF2_ERR_EINT */
-#define WM5100_AIF2_ERR_EINT_MASK 0x1000 /* AIF2_ERR_EINT */
-#define WM5100_AIF2_ERR_EINT_SHIFT 12 /* AIF2_ERR_EINT */
-#define WM5100_AIF2_ERR_EINT_WIDTH 1 /* AIF2_ERR_EINT */
-#define WM5100_AIF1_ERR_EINT 0x0800 /* AIF1_ERR_EINT */
-#define WM5100_AIF1_ERR_EINT_MASK 0x0800 /* AIF1_ERR_EINT */
-#define WM5100_AIF1_ERR_EINT_SHIFT 11 /* AIF1_ERR_EINT */
-#define WM5100_AIF1_ERR_EINT_WIDTH 1 /* AIF1_ERR_EINT */
-#define WM5100_CTRLIF_ERR_EINT 0x0400 /* CTRLIF_ERR_EINT */
-#define WM5100_CTRLIF_ERR_EINT_MASK 0x0400 /* CTRLIF_ERR_EINT */
-#define WM5100_CTRLIF_ERR_EINT_SHIFT 10 /* CTRLIF_ERR_EINT */
-#define WM5100_CTRLIF_ERR_EINT_WIDTH 1 /* CTRLIF_ERR_EINT */
-#define WM5100_ISRC2_UNDERCLOCKED_EINT 0x0200 /* ISRC2_UNDERCLOCKED_EINT */
-#define WM5100_ISRC2_UNDERCLOCKED_EINT_MASK 0x0200 /* ISRC2_UNDERCLOCKED_EINT */
-#define WM5100_ISRC2_UNDERCLOCKED_EINT_SHIFT 9 /* ISRC2_UNDERCLOCKED_EINT */
-#define WM5100_ISRC2_UNDERCLOCKED_EINT_WIDTH 1 /* ISRC2_UNDERCLOCKED_EINT */
-#define WM5100_ISRC1_UNDERCLOCKED_EINT 0x0100 /* ISRC1_UNDERCLOCKED_EINT */
-#define WM5100_ISRC1_UNDERCLOCKED_EINT_MASK 0x0100 /* ISRC1_UNDERCLOCKED_EINT */
-#define WM5100_ISRC1_UNDERCLOCKED_EINT_SHIFT 8 /* ISRC1_UNDERCLOCKED_EINT */
-#define WM5100_ISRC1_UNDERCLOCKED_EINT_WIDTH 1 /* ISRC1_UNDERCLOCKED_EINT */
-#define WM5100_FX_UNDERCLOCKED_EINT 0x0080 /* FX_UNDERCLOCKED_EINT */
-#define WM5100_FX_UNDERCLOCKED_EINT_MASK 0x0080 /* FX_UNDERCLOCKED_EINT */
-#define WM5100_FX_UNDERCLOCKED_EINT_SHIFT 7 /* FX_UNDERCLOCKED_EINT */
-#define WM5100_FX_UNDERCLOCKED_EINT_WIDTH 1 /* FX_UNDERCLOCKED_EINT */
-#define WM5100_AIF3_UNDERCLOCKED_EINT 0x0040 /* AIF3_UNDERCLOCKED_EINT */
-#define WM5100_AIF3_UNDERCLOCKED_EINT_MASK 0x0040 /* AIF3_UNDERCLOCKED_EINT */
-#define WM5100_AIF3_UNDERCLOCKED_EINT_SHIFT 6 /* AIF3_UNDERCLOCKED_EINT */
-#define WM5100_AIF3_UNDERCLOCKED_EINT_WIDTH 1 /* AIF3_UNDERCLOCKED_EINT */
-#define WM5100_AIF2_UNDERCLOCKED_EINT 0x0020 /* AIF2_UNDERCLOCKED_EINT */
-#define WM5100_AIF2_UNDERCLOCKED_EINT_MASK 0x0020 /* AIF2_UNDERCLOCKED_EINT */
-#define WM5100_AIF2_UNDERCLOCKED_EINT_SHIFT 5 /* AIF2_UNDERCLOCKED_EINT */
-#define WM5100_AIF2_UNDERCLOCKED_EINT_WIDTH 1 /* AIF2_UNDERCLOCKED_EINT */
-#define WM5100_AIF1_UNDERCLOCKED_EINT 0x0010 /* AIF1_UNDERCLOCKED_EINT */
-#define WM5100_AIF1_UNDERCLOCKED_EINT_MASK 0x0010 /* AIF1_UNDERCLOCKED_EINT */
-#define WM5100_AIF1_UNDERCLOCKED_EINT_SHIFT 4 /* AIF1_UNDERCLOCKED_EINT */
-#define WM5100_AIF1_UNDERCLOCKED_EINT_WIDTH 1 /* AIF1_UNDERCLOCKED_EINT */
-#define WM5100_ASRC_UNDERCLOCKED_EINT 0x0008 /* ASRC_UNDERCLOCKED_EINT */
-#define WM5100_ASRC_UNDERCLOCKED_EINT_MASK 0x0008 /* ASRC_UNDERCLOCKED_EINT */
-#define WM5100_ASRC_UNDERCLOCKED_EINT_SHIFT 3 /* ASRC_UNDERCLOCKED_EINT */
-#define WM5100_ASRC_UNDERCLOCKED_EINT_WIDTH 1 /* ASRC_UNDERCLOCKED_EINT */
-#define WM5100_DAC_UNDERCLOCKED_EINT 0x0004 /* DAC_UNDERCLOCKED_EINT */
-#define WM5100_DAC_UNDERCLOCKED_EINT_MASK 0x0004 /* DAC_UNDERCLOCKED_EINT */
-#define WM5100_DAC_UNDERCLOCKED_EINT_SHIFT 2 /* DAC_UNDERCLOCKED_EINT */
-#define WM5100_DAC_UNDERCLOCKED_EINT_WIDTH 1 /* DAC_UNDERCLOCKED_EINT */
-#define WM5100_ADC_UNDERCLOCKED_EINT 0x0002 /* ADC_UNDERCLOCKED_EINT */
-#define WM5100_ADC_UNDERCLOCKED_EINT_MASK 0x0002 /* ADC_UNDERCLOCKED_EINT */
-#define WM5100_ADC_UNDERCLOCKED_EINT_SHIFT 1 /* ADC_UNDERCLOCKED_EINT */
-#define WM5100_ADC_UNDERCLOCKED_EINT_WIDTH 1 /* ADC_UNDERCLOCKED_EINT */
-#define WM5100_MIXER_UNDERCLOCKED_EINT 0x0001 /* MIXER_UNDERCLOCKED_EINT */
-#define WM5100_MIXER_UNDERCLOCKED_EINT_MASK 0x0001 /* MIXER_UNDERCLOCKED_EINT */
-#define WM5100_MIXER_UNDERCLOCKED_EINT_SHIFT 0 /* MIXER_UNDERCLOCKED_EINT */
-#define WM5100_MIXER_UNDERCLOCKED_EINT_WIDTH 1 /* MIXER_UNDERCLOCKED_EINT */
-
-/*
- * R3332 (0xD04) - Interrupt Raw Status 2
- */
-#define WM5100_DSP_IRQ6_STS 0x0020 /* DSP_IRQ6_STS */
-#define WM5100_DSP_IRQ6_STS_MASK 0x0020 /* DSP_IRQ6_STS */
-#define WM5100_DSP_IRQ6_STS_SHIFT 5 /* DSP_IRQ6_STS */
-#define WM5100_DSP_IRQ6_STS_WIDTH 1 /* DSP_IRQ6_STS */
-#define WM5100_DSP_IRQ5_STS 0x0010 /* DSP_IRQ5_STS */
-#define WM5100_DSP_IRQ5_STS_MASK 0x0010 /* DSP_IRQ5_STS */
-#define WM5100_DSP_IRQ5_STS_SHIFT 4 /* DSP_IRQ5_STS */
-#define WM5100_DSP_IRQ5_STS_WIDTH 1 /* DSP_IRQ5_STS */
-#define WM5100_DSP_IRQ4_STS 0x0008 /* DSP_IRQ4_STS */
-#define WM5100_DSP_IRQ4_STS_MASK 0x0008 /* DSP_IRQ4_STS */
-#define WM5100_DSP_IRQ4_STS_SHIFT 3 /* DSP_IRQ4_STS */
-#define WM5100_DSP_IRQ4_STS_WIDTH 1 /* DSP_IRQ4_STS */
-#define WM5100_DSP_IRQ3_STS 0x0004 /* DSP_IRQ3_STS */
-#define WM5100_DSP_IRQ3_STS_MASK 0x0004 /* DSP_IRQ3_STS */
-#define WM5100_DSP_IRQ3_STS_SHIFT 2 /* DSP_IRQ3_STS */
-#define WM5100_DSP_IRQ3_STS_WIDTH 1 /* DSP_IRQ3_STS */
-#define WM5100_DSP_IRQ2_STS 0x0002 /* DSP_IRQ2_STS */
-#define WM5100_DSP_IRQ2_STS_MASK 0x0002 /* DSP_IRQ2_STS */
-#define WM5100_DSP_IRQ2_STS_SHIFT 1 /* DSP_IRQ2_STS */
-#define WM5100_DSP_IRQ2_STS_WIDTH 1 /* DSP_IRQ2_STS */
-#define WM5100_DSP_IRQ1_STS 0x0001 /* DSP_IRQ1_STS */
-#define WM5100_DSP_IRQ1_STS_MASK 0x0001 /* DSP_IRQ1_STS */
-#define WM5100_DSP_IRQ1_STS_SHIFT 0 /* DSP_IRQ1_STS */
-#define WM5100_DSP_IRQ1_STS_WIDTH 1 /* DSP_IRQ1_STS */
-
-/*
- * R3333 (0xD05) - Interrupt Raw Status 3
- */
-#define WM5100_SPK_SHUTDOWN_WARN_STS 0x8000 /* SPK_SHUTDOWN_WARN_STS */
-#define WM5100_SPK_SHUTDOWN_WARN_STS_MASK 0x8000 /* SPK_SHUTDOWN_WARN_STS */
-#define WM5100_SPK_SHUTDOWN_WARN_STS_SHIFT 15 /* SPK_SHUTDOWN_WARN_STS */
-#define WM5100_SPK_SHUTDOWN_WARN_STS_WIDTH 1 /* SPK_SHUTDOWN_WARN_STS */
-#define WM5100_SPK_SHUTDOWN_STS 0x4000 /* SPK_SHUTDOWN_STS */
-#define WM5100_SPK_SHUTDOWN_STS_MASK 0x4000 /* SPK_SHUTDOWN_STS */
-#define WM5100_SPK_SHUTDOWN_STS_SHIFT 14 /* SPK_SHUTDOWN_STS */
-#define WM5100_SPK_SHUTDOWN_STS_WIDTH 1 /* SPK_SHUTDOWN_STS */
-#define WM5100_HPDET_STS 0x2000 /* HPDET_STS */
-#define WM5100_HPDET_STS_MASK 0x2000 /* HPDET_STS */
-#define WM5100_HPDET_STS_SHIFT 13 /* HPDET_STS */
-#define WM5100_HPDET_STS_WIDTH 1 /* HPDET_STS */
-#define WM5100_DRC_SID_DET_STS 0x0200 /* DRC_SID_DET_STS */
-#define WM5100_DRC_SID_DET_STS_MASK 0x0200 /* DRC_SID_DET_STS */
-#define WM5100_DRC_SID_DET_STS_SHIFT 9 /* DRC_SID_DET_STS */
-#define WM5100_DRC_SID_DET_STS_WIDTH 1 /* DRC_SID_DET_STS */
-#define WM5100_ASRC2_LOCK_STS 0x0100 /* ASRC2_LOCK_STS */
-#define WM5100_ASRC2_LOCK_STS_MASK 0x0100 /* ASRC2_LOCK_STS */
-#define WM5100_ASRC2_LOCK_STS_SHIFT 8 /* ASRC2_LOCK_STS */
-#define WM5100_ASRC2_LOCK_STS_WIDTH 1 /* ASRC2_LOCK_STS */
-#define WM5100_ASRC1_LOCK_STS 0x0080 /* ASRC1_LOCK_STS */
-#define WM5100_ASRC1_LOCK_STS_MASK 0x0080 /* ASRC1_LOCK_STS */
-#define WM5100_ASRC1_LOCK_STS_SHIFT 7 /* ASRC1_LOCK_STS */
-#define WM5100_ASRC1_LOCK_STS_WIDTH 1 /* ASRC1_LOCK_STS */
-#define WM5100_FLL2_LOCK_STS 0x0008 /* FLL2_LOCK_STS */
-#define WM5100_FLL2_LOCK_STS_MASK 0x0008 /* FLL2_LOCK_STS */
-#define WM5100_FLL2_LOCK_STS_SHIFT 3 /* FLL2_LOCK_STS */
-#define WM5100_FLL2_LOCK_STS_WIDTH 1 /* FLL2_LOCK_STS */
-#define WM5100_FLL1_LOCK_STS 0x0004 /* FLL1_LOCK_STS */
-#define WM5100_FLL1_LOCK_STS_MASK 0x0004 /* FLL1_LOCK_STS */
-#define WM5100_FLL1_LOCK_STS_SHIFT 2 /* FLL1_LOCK_STS */
-#define WM5100_FLL1_LOCK_STS_WIDTH 1 /* FLL1_LOCK_STS */
-#define WM5100_CLKGEN_ERR_STS 0x0002 /* CLKGEN_ERR_STS */
-#define WM5100_CLKGEN_ERR_STS_MASK 0x0002 /* CLKGEN_ERR_STS */
-#define WM5100_CLKGEN_ERR_STS_SHIFT 1 /* CLKGEN_ERR_STS */
-#define WM5100_CLKGEN_ERR_STS_WIDTH 1 /* CLKGEN_ERR_STS */
-#define WM5100_CLKGEN_ERR_ASYNC_STS 0x0001 /* CLKGEN_ERR_ASYNC_STS */
-#define WM5100_CLKGEN_ERR_ASYNC_STS_MASK 0x0001 /* CLKGEN_ERR_ASYNC_STS */
-#define WM5100_CLKGEN_ERR_ASYNC_STS_SHIFT 0 /* CLKGEN_ERR_ASYNC_STS */
-#define WM5100_CLKGEN_ERR_ASYNC_STS_WIDTH 1 /* CLKGEN_ERR_ASYNC_STS */
-
-/*
- * R3334 (0xD06) - Interrupt Raw Status 4
- */
-#define WM5100_AIF3_ERR_STS 0x2000 /* AIF3_ERR_STS */
-#define WM5100_AIF3_ERR_STS_MASK 0x2000 /* AIF3_ERR_STS */
-#define WM5100_AIF3_ERR_STS_SHIFT 13 /* AIF3_ERR_STS */
-#define WM5100_AIF3_ERR_STS_WIDTH 1 /* AIF3_ERR_STS */
-#define WM5100_AIF2_ERR_STS 0x1000 /* AIF2_ERR_STS */
-#define WM5100_AIF2_ERR_STS_MASK 0x1000 /* AIF2_ERR_STS */
-#define WM5100_AIF2_ERR_STS_SHIFT 12 /* AIF2_ERR_STS */
-#define WM5100_AIF2_ERR_STS_WIDTH 1 /* AIF2_ERR_STS */
-#define WM5100_AIF1_ERR_STS 0x0800 /* AIF1_ERR_STS */
-#define WM5100_AIF1_ERR_STS_MASK 0x0800 /* AIF1_ERR_STS */
-#define WM5100_AIF1_ERR_STS_SHIFT 11 /* AIF1_ERR_STS */
-#define WM5100_AIF1_ERR_STS_WIDTH 1 /* AIF1_ERR_STS */
-#define WM5100_CTRLIF_ERR_STS 0x0400 /* CTRLIF_ERR_STS */
-#define WM5100_CTRLIF_ERR_STS_MASK 0x0400 /* CTRLIF_ERR_STS */
-#define WM5100_CTRLIF_ERR_STS_SHIFT 10 /* CTRLIF_ERR_STS */
-#define WM5100_CTRLIF_ERR_STS_WIDTH 1 /* CTRLIF_ERR_STS */
-#define WM5100_ISRC2_UNDERCLOCKED_STS 0x0200 /* ISRC2_UNDERCLOCKED_STS */
-#define WM5100_ISRC2_UNDERCLOCKED_STS_MASK 0x0200 /* ISRC2_UNDERCLOCKED_STS */
-#define WM5100_ISRC2_UNDERCLOCKED_STS_SHIFT 9 /* ISRC2_UNDERCLOCKED_STS */
-#define WM5100_ISRC2_UNDERCLOCKED_STS_WIDTH 1 /* ISRC2_UNDERCLOCKED_STS */
-#define WM5100_ISRC1_UNDERCLOCKED_STS 0x0100 /* ISRC1_UNDERCLOCKED_STS */
-#define WM5100_ISRC1_UNDERCLOCKED_STS_MASK 0x0100 /* ISRC1_UNDERCLOCKED_STS */
-#define WM5100_ISRC1_UNDERCLOCKED_STS_SHIFT 8 /* ISRC1_UNDERCLOCKED_STS */
-#define WM5100_ISRC1_UNDERCLOCKED_STS_WIDTH 1 /* ISRC1_UNDERCLOCKED_STS */
-#define WM5100_FX_UNDERCLOCKED_STS 0x0080 /* FX_UNDERCLOCKED_STS */
-#define WM5100_FX_UNDERCLOCKED_STS_MASK 0x0080 /* FX_UNDERCLOCKED_STS */
-#define WM5100_FX_UNDERCLOCKED_STS_SHIFT 7 /* FX_UNDERCLOCKED_STS */
-#define WM5100_FX_UNDERCLOCKED_STS_WIDTH 1 /* FX_UNDERCLOCKED_STS */
-#define WM5100_AIF3_UNDERCLOCKED_STS 0x0040 /* AIF3_UNDERCLOCKED_STS */
-#define WM5100_AIF3_UNDERCLOCKED_STS_MASK 0x0040 /* AIF3_UNDERCLOCKED_STS */
-#define WM5100_AIF3_UNDERCLOCKED_STS_SHIFT 6 /* AIF3_UNDERCLOCKED_STS */
-#define WM5100_AIF3_UNDERCLOCKED_STS_WIDTH 1 /* AIF3_UNDERCLOCKED_STS */
-#define WM5100_AIF2_UNDERCLOCKED_STS 0x0020 /* AIF2_UNDERCLOCKED_STS */
-#define WM5100_AIF2_UNDERCLOCKED_STS_MASK 0x0020 /* AIF2_UNDERCLOCKED_STS */
-#define WM5100_AIF2_UNDERCLOCKED_STS_SHIFT 5 /* AIF2_UNDERCLOCKED_STS */
-#define WM5100_AIF2_UNDERCLOCKED_STS_WIDTH 1 /* AIF2_UNDERCLOCKED_STS */
-#define WM5100_AIF1_UNDERCLOCKED_STS 0x0010 /* AIF1_UNDERCLOCKED_STS */
-#define WM5100_AIF1_UNDERCLOCKED_STS_MASK 0x0010 /* AIF1_UNDERCLOCKED_STS */
-#define WM5100_AIF1_UNDERCLOCKED_STS_SHIFT 4 /* AIF1_UNDERCLOCKED_STS */
-#define WM5100_AIF1_UNDERCLOCKED_STS_WIDTH 1 /* AIF1_UNDERCLOCKED_STS */
-#define WM5100_ASRC_UNDERCLOCKED_STS 0x0008 /* ASRC_UNDERCLOCKED_STS */
-#define WM5100_ASRC_UNDERCLOCKED_STS_MASK 0x0008 /* ASRC_UNDERCLOCKED_STS */
-#define WM5100_ASRC_UNDERCLOCKED_STS_SHIFT 3 /* ASRC_UNDERCLOCKED_STS */
-#define WM5100_ASRC_UNDERCLOCKED_STS_WIDTH 1 /* ASRC_UNDERCLOCKED_STS */
-#define WM5100_DAC_UNDERCLOCKED_STS 0x0004 /* DAC_UNDERCLOCKED_STS */
-#define WM5100_DAC_UNDERCLOCKED_STS_MASK 0x0004 /* DAC_UNDERCLOCKED_STS */
-#define WM5100_DAC_UNDERCLOCKED_STS_SHIFT 2 /* DAC_UNDERCLOCKED_STS */
-#define WM5100_DAC_UNDERCLOCKED_STS_WIDTH 1 /* DAC_UNDERCLOCKED_STS */
-#define WM5100_ADC_UNDERCLOCKED_STS 0x0002 /* ADC_UNDERCLOCKED_STS */
-#define WM5100_ADC_UNDERCLOCKED_STS_MASK 0x0002 /* ADC_UNDERCLOCKED_STS */
-#define WM5100_ADC_UNDERCLOCKED_STS_SHIFT 1 /* ADC_UNDERCLOCKED_STS */
-#define WM5100_ADC_UNDERCLOCKED_STS_WIDTH 1 /* ADC_UNDERCLOCKED_STS */
-#define WM5100_MIXER_UNDERCLOCKED_STS 0x0001 /* MIXER_UNDERCLOCKED_STS */
-#define WM5100_MIXER_UNDERCLOCKED_STS_MASK 0x0001 /* MIXER_UNDERCLOCKED_STS */
-#define WM5100_MIXER_UNDERCLOCKED_STS_SHIFT 0 /* MIXER_UNDERCLOCKED_STS */
-#define WM5100_MIXER_UNDERCLOCKED_STS_WIDTH 1 /* MIXER_UNDERCLOCKED_STS */
-
-/*
- * R3335 (0xD07) - Interrupt Status 1 Mask
- */
-#define WM5100_IM_GP6_EINT 0x0020 /* IM_GP6_EINT */
-#define WM5100_IM_GP6_EINT_MASK 0x0020 /* IM_GP6_EINT */
-#define WM5100_IM_GP6_EINT_SHIFT 5 /* IM_GP6_EINT */
-#define WM5100_IM_GP6_EINT_WIDTH 1 /* IM_GP6_EINT */
-#define WM5100_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
-#define WM5100_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
-#define WM5100_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
-#define WM5100_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
-#define WM5100_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
-#define WM5100_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
-#define WM5100_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
-#define WM5100_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
-#define WM5100_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
-#define WM5100_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
-#define WM5100_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
-#define WM5100_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
-#define WM5100_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
-#define WM5100_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
-#define WM5100_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
-#define WM5100_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
-#define WM5100_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
-#define WM5100_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
-#define WM5100_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
-#define WM5100_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
-
-/*
- * R3336 (0xD08) - Interrupt Status 2 Mask
- */
-#define WM5100_IM_DSP_IRQ6_EINT 0x0020 /* IM_DSP_IRQ6_EINT */
-#define WM5100_IM_DSP_IRQ6_EINT_MASK 0x0020 /* IM_DSP_IRQ6_EINT */
-#define WM5100_IM_DSP_IRQ6_EINT_SHIFT 5 /* IM_DSP_IRQ6_EINT */
-#define WM5100_IM_DSP_IRQ6_EINT_WIDTH 1 /* IM_DSP_IRQ6_EINT */
-#define WM5100_IM_DSP_IRQ5_EINT 0x0010 /* IM_DSP_IRQ5_EINT */
-#define WM5100_IM_DSP_IRQ5_EINT_MASK 0x0010 /* IM_DSP_IRQ5_EINT */
-#define WM5100_IM_DSP_IRQ5_EINT_SHIFT 4 /* IM_DSP_IRQ5_EINT */
-#define WM5100_IM_DSP_IRQ5_EINT_WIDTH 1 /* IM_DSP_IRQ5_EINT */
-#define WM5100_IM_DSP_IRQ4_EINT 0x0008 /* IM_DSP_IRQ4_EINT */
-#define WM5100_IM_DSP_IRQ4_EINT_MASK 0x0008 /* IM_DSP_IRQ4_EINT */
-#define WM5100_IM_DSP_IRQ4_EINT_SHIFT 3 /* IM_DSP_IRQ4_EINT */
-#define WM5100_IM_DSP_IRQ4_EINT_WIDTH 1 /* IM_DSP_IRQ4_EINT */
-#define WM5100_IM_DSP_IRQ3_EINT 0x0004 /* IM_DSP_IRQ3_EINT */
-#define WM5100_IM_DSP_IRQ3_EINT_MASK 0x0004 /* IM_DSP_IRQ3_EINT */
-#define WM5100_IM_DSP_IRQ3_EINT_SHIFT 2 /* IM_DSP_IRQ3_EINT */
-#define WM5100_IM_DSP_IRQ3_EINT_WIDTH 1 /* IM_DSP_IRQ3_EINT */
-#define WM5100_IM_DSP_IRQ2_EINT 0x0002 /* IM_DSP_IRQ2_EINT */
-#define WM5100_IM_DSP_IRQ2_EINT_MASK 0x0002 /* IM_DSP_IRQ2_EINT */
-#define WM5100_IM_DSP_IRQ2_EINT_SHIFT 1 /* IM_DSP_IRQ2_EINT */
-#define WM5100_IM_DSP_IRQ2_EINT_WIDTH 1 /* IM_DSP_IRQ2_EINT */
-#define WM5100_IM_DSP_IRQ1_EINT 0x0001 /* IM_DSP_IRQ1_EINT */
-#define WM5100_IM_DSP_IRQ1_EINT_MASK 0x0001 /* IM_DSP_IRQ1_EINT */
-#define WM5100_IM_DSP_IRQ1_EINT_SHIFT 0 /* IM_DSP_IRQ1_EINT */
-#define WM5100_IM_DSP_IRQ1_EINT_WIDTH 1 /* IM_DSP_IRQ1_EINT */
-
-/*
- * R3337 (0xD09) - Interrupt Status 3 Mask
- */
-#define WM5100_IM_SPK_SHUTDOWN_WARN_EINT 0x8000 /* IM_SPK_SHUTDOWN_WARN_EINT */
-#define WM5100_IM_SPK_SHUTDOWN_WARN_EINT_MASK 0x8000 /* IM_SPK_SHUTDOWN_WARN_EINT */
-#define WM5100_IM_SPK_SHUTDOWN_WARN_EINT_SHIFT 15 /* IM_SPK_SHUTDOWN_WARN_EINT */
-#define WM5100_IM_SPK_SHUTDOWN_WARN_EINT_WIDTH 1 /* IM_SPK_SHUTDOWN_WARN_EINT */
-#define WM5100_IM_SPK_SHUTDOWN_EINT 0x4000 /* IM_SPK_SHUTDOWN_EINT */
-#define WM5100_IM_SPK_SHUTDOWN_EINT_MASK 0x4000 /* IM_SPK_SHUTDOWN_EINT */
-#define WM5100_IM_SPK_SHUTDOWN_EINT_SHIFT 14 /* IM_SPK_SHUTDOWN_EINT */
-#define WM5100_IM_SPK_SHUTDOWN_EINT_WIDTH 1 /* IM_SPK_SHUTDOWN_EINT */
-#define WM5100_IM_HPDET_EINT 0x2000 /* IM_HPDET_EINT */
-#define WM5100_IM_HPDET_EINT_MASK 0x2000 /* IM_HPDET_EINT */
-#define WM5100_IM_HPDET_EINT_SHIFT 13 /* IM_HPDET_EINT */
-#define WM5100_IM_HPDET_EINT_WIDTH 1 /* IM_HPDET_EINT */
-#define WM5100_IM_ACCDET_EINT 0x1000 /* IM_ACCDET_EINT */
-#define WM5100_IM_ACCDET_EINT_MASK 0x1000 /* IM_ACCDET_EINT */
-#define WM5100_IM_ACCDET_EINT_SHIFT 12 /* IM_ACCDET_EINT */
-#define WM5100_IM_ACCDET_EINT_WIDTH 1 /* IM_ACCDET_EINT */
-#define WM5100_IM_DRC_SIG_DET_EINT 0x0200 /* IM_DRC_SIG_DET_EINT */
-#define WM5100_IM_DRC_SIG_DET_EINT_MASK 0x0200 /* IM_DRC_SIG_DET_EINT */
-#define WM5100_IM_DRC_SIG_DET_EINT_SHIFT 9 /* IM_DRC_SIG_DET_EINT */
-#define WM5100_IM_DRC_SIG_DET_EINT_WIDTH 1 /* IM_DRC_SIG_DET_EINT */
-#define WM5100_IM_ASRC2_LOCK_EINT 0x0100 /* IM_ASRC2_LOCK_EINT */
-#define WM5100_IM_ASRC2_LOCK_EINT_MASK 0x0100 /* IM_ASRC2_LOCK_EINT */
-#define WM5100_IM_ASRC2_LOCK_EINT_SHIFT 8 /* IM_ASRC2_LOCK_EINT */
-#define WM5100_IM_ASRC2_LOCK_EINT_WIDTH 1 /* IM_ASRC2_LOCK_EINT */
-#define WM5100_IM_ASRC1_LOCK_EINT 0x0080 /* IM_ASRC1_LOCK_EINT */
-#define WM5100_IM_ASRC1_LOCK_EINT_MASK 0x0080 /* IM_ASRC1_LOCK_EINT */
-#define WM5100_IM_ASRC1_LOCK_EINT_SHIFT 7 /* IM_ASRC1_LOCK_EINT */
-#define WM5100_IM_ASRC1_LOCK_EINT_WIDTH 1 /* IM_ASRC1_LOCK_EINT */
-#define WM5100_IM_FLL2_LOCK_EINT 0x0008 /* IM_FLL2_LOCK_EINT */
-#define WM5100_IM_FLL2_LOCK_EINT_MASK 0x0008 /* IM_FLL2_LOCK_EINT */
-#define WM5100_IM_FLL2_LOCK_EINT_SHIFT 3 /* IM_FLL2_LOCK_EINT */
-#define WM5100_IM_FLL2_LOCK_EINT_WIDTH 1 /* IM_FLL2_LOCK_EINT */
-#define WM5100_IM_FLL1_LOCK_EINT 0x0004 /* IM_FLL1_LOCK_EINT */
-#define WM5100_IM_FLL1_LOCK_EINT_MASK 0x0004 /* IM_FLL1_LOCK_EINT */
-#define WM5100_IM_FLL1_LOCK_EINT_SHIFT 2 /* IM_FLL1_LOCK_EINT */
-#define WM5100_IM_FLL1_LOCK_EINT_WIDTH 1 /* IM_FLL1_LOCK_EINT */
-#define WM5100_IM_CLKGEN_ERR_EINT 0x0002 /* IM_CLKGEN_ERR_EINT */
-#define WM5100_IM_CLKGEN_ERR_EINT_MASK 0x0002 /* IM_CLKGEN_ERR_EINT */
-#define WM5100_IM_CLKGEN_ERR_EINT_SHIFT 1 /* IM_CLKGEN_ERR_EINT */
-#define WM5100_IM_CLKGEN_ERR_EINT_WIDTH 1 /* IM_CLKGEN_ERR_EINT */
-#define WM5100_IM_CLKGEN_ERR_ASYNC_EINT 0x0001 /* IM_CLKGEN_ERR_ASYNC_EINT */
-#define WM5100_IM_CLKGEN_ERR_ASYNC_EINT_MASK 0x0001 /* IM_CLKGEN_ERR_ASYNC_EINT */
-#define WM5100_IM_CLKGEN_ERR_ASYNC_EINT_SHIFT 0 /* IM_CLKGEN_ERR_ASYNC_EINT */
-#define WM5100_IM_CLKGEN_ERR_ASYNC_EINT_WIDTH 1 /* IM_CLKGEN_ERR_ASYNC_EINT */
-
-/*
- * R3338 (0xD0A) - Interrupt Status 4 Mask
- */
-#define WM5100_IM_AIF3_ERR_EINT 0x2000 /* IM_AIF3_ERR_EINT */
-#define WM5100_IM_AIF3_ERR_EINT_MASK 0x2000 /* IM_AIF3_ERR_EINT */
-#define WM5100_IM_AIF3_ERR_EINT_SHIFT 13 /* IM_AIF3_ERR_EINT */
-#define WM5100_IM_AIF3_ERR_EINT_WIDTH 1 /* IM_AIF3_ERR_EINT */
-#define WM5100_IM_AIF2_ERR_EINT 0x1000 /* IM_AIF2_ERR_EINT */
-#define WM5100_IM_AIF2_ERR_EINT_MASK 0x1000 /* IM_AIF2_ERR_EINT */
-#define WM5100_IM_AIF2_ERR_EINT_SHIFT 12 /* IM_AIF2_ERR_EINT */
-#define WM5100_IM_AIF2_ERR_EINT_WIDTH 1 /* IM_AIF2_ERR_EINT */
-#define WM5100_IM_AIF1_ERR_EINT 0x0800 /* IM_AIF1_ERR_EINT */
-#define WM5100_IM_AIF1_ERR_EINT_MASK 0x0800 /* IM_AIF1_ERR_EINT */
-#define WM5100_IM_AIF1_ERR_EINT_SHIFT 11 /* IM_AIF1_ERR_EINT */
-#define WM5100_IM_AIF1_ERR_EINT_WIDTH 1 /* IM_AIF1_ERR_EINT */
-#define WM5100_IM_CTRLIF_ERR_EINT 0x0400 /* IM_CTRLIF_ERR_EINT */
-#define WM5100_IM_CTRLIF_ERR_EINT_MASK 0x0400 /* IM_CTRLIF_ERR_EINT */
-#define WM5100_IM_CTRLIF_ERR_EINT_SHIFT 10 /* IM_CTRLIF_ERR_EINT */
-#define WM5100_IM_CTRLIF_ERR_EINT_WIDTH 1 /* IM_CTRLIF_ERR_EINT */
-#define WM5100_IM_ISRC2_UNDERCLOCKED_EINT 0x0200 /* IM_ISRC2_UNDERCLOCKED_EINT */
-#define WM5100_IM_ISRC2_UNDERCLOCKED_EINT_MASK 0x0200 /* IM_ISRC2_UNDERCLOCKED_EINT */
-#define WM5100_IM_ISRC2_UNDERCLOCKED_EINT_SHIFT 9 /* IM_ISRC2_UNDERCLOCKED_EINT */
-#define WM5100_IM_ISRC2_UNDERCLOCKED_EINT_WIDTH 1 /* IM_ISRC2_UNDERCLOCKED_EINT */
-#define WM5100_IM_ISRC1_UNDERCLOCKED_EINT 0x0100 /* IM_ISRC1_UNDERCLOCKED_EINT */
-#define WM5100_IM_ISRC1_UNDERCLOCKED_EINT_MASK 0x0100 /* IM_ISRC1_UNDERCLOCKED_EINT */
-#define WM5100_IM_ISRC1_UNDERCLOCKED_EINT_SHIFT 8 /* IM_ISRC1_UNDERCLOCKED_EINT */
-#define WM5100_IM_ISRC1_UNDERCLOCKED_EINT_WIDTH 1 /* IM_ISRC1_UNDERCLOCKED_EINT */
-#define WM5100_IM_FX_UNDERCLOCKED_EINT 0x0080 /* IM_FX_UNDERCLOCKED_EINT */
-#define WM5100_IM_FX_UNDERCLOCKED_EINT_MASK 0x0080 /* IM_FX_UNDERCLOCKED_EINT */
-#define WM5100_IM_FX_UNDERCLOCKED_EINT_SHIFT 7 /* IM_FX_UNDERCLOCKED_EINT */
-#define WM5100_IM_FX_UNDERCLOCKED_EINT_WIDTH 1 /* IM_FX_UNDERCLOCKED_EINT */
-#define WM5100_IM_AIF3_UNDERCLOCKED_EINT 0x0040 /* IM_AIF3_UNDERCLOCKED_EINT */
-#define WM5100_IM_AIF3_UNDERCLOCKED_EINT_MASK 0x0040 /* IM_AIF3_UNDERCLOCKED_EINT */
-#define WM5100_IM_AIF3_UNDERCLOCKED_EINT_SHIFT 6 /* IM_AIF3_UNDERCLOCKED_EINT */
-#define WM5100_IM_AIF3_UNDERCLOCKED_EINT_WIDTH 1 /* IM_AIF3_UNDERCLOCKED_EINT */
-#define WM5100_IM_AIF2_UNDERCLOCKED_EINT 0x0020 /* IM_AIF2_UNDERCLOCKED_EINT */
-#define WM5100_IM_AIF2_UNDERCLOCKED_EINT_MASK 0x0020 /* IM_AIF2_UNDERCLOCKED_EINT */
-#define WM5100_IM_AIF2_UNDERCLOCKED_EINT_SHIFT 5 /* IM_AIF2_UNDERCLOCKED_EINT */
-#define WM5100_IM_AIF2_UNDERCLOCKED_EINT_WIDTH 1 /* IM_AIF2_UNDERCLOCKED_EINT */
-#define WM5100_IM_AIF1_UNDERCLOCKED_EINT 0x0010 /* IM_AIF1_UNDERCLOCKED_EINT */
-#define WM5100_IM_AIF1_UNDERCLOCKED_EINT_MASK 0x0010 /* IM_AIF1_UNDERCLOCKED_EINT */
-#define WM5100_IM_AIF1_UNDERCLOCKED_EINT_SHIFT 4 /* IM_AIF1_UNDERCLOCKED_EINT */
-#define WM5100_IM_AIF1_UNDERCLOCKED_EINT_WIDTH 1 /* IM_AIF1_UNDERCLOCKED_EINT */
-#define WM5100_IM_ASRC_UNDERCLOCKED_EINT 0x0008 /* IM_ASRC_UNDERCLOCKED_EINT */
-#define WM5100_IM_ASRC_UNDERCLOCKED_EINT_MASK 0x0008 /* IM_ASRC_UNDERCLOCKED_EINT */
-#define WM5100_IM_ASRC_UNDERCLOCKED_EINT_SHIFT 3 /* IM_ASRC_UNDERCLOCKED_EINT */
-#define WM5100_IM_ASRC_UNDERCLOCKED_EINT_WIDTH 1 /* IM_ASRC_UNDERCLOCKED_EINT */
-#define WM5100_IM_DAC_UNDERCLOCKED_EINT 0x0004 /* IM_DAC_UNDERCLOCKED_EINT */
-#define WM5100_IM_DAC_UNDERCLOCKED_EINT_MASK 0x0004 /* IM_DAC_UNDERCLOCKED_EINT */
-#define WM5100_IM_DAC_UNDERCLOCKED_EINT_SHIFT 2 /* IM_DAC_UNDERCLOCKED_EINT */
-#define WM5100_IM_DAC_UNDERCLOCKED_EINT_WIDTH 1 /* IM_DAC_UNDERCLOCKED_EINT */
-#define WM5100_IM_ADC_UNDERCLOCKED_EINT 0x0002 /* IM_ADC_UNDERCLOCKED_EINT */
-#define WM5100_IM_ADC_UNDERCLOCKED_EINT_MASK 0x0002 /* IM_ADC_UNDERCLOCKED_EINT */
-#define WM5100_IM_ADC_UNDERCLOCKED_EINT_SHIFT 1 /* IM_ADC_UNDERCLOCKED_EINT */
-#define WM5100_IM_ADC_UNDERCLOCKED_EINT_WIDTH 1 /* IM_ADC_UNDERCLOCKED_EINT */
-#define WM5100_IM_MIXER_UNDERCLOCKED_EINT 0x0001 /* IM_MIXER_UNDERCLOCKED_EINT */
-#define WM5100_IM_MIXER_UNDERCLOCKED_EINT_MASK 0x0001 /* IM_MIXER_UNDERCLOCKED_EINT */
-#define WM5100_IM_MIXER_UNDERCLOCKED_EINT_SHIFT 0 /* IM_MIXER_UNDERCLOCKED_EINT */
-#define WM5100_IM_MIXER_UNDERCLOCKED_EINT_WIDTH 1 /* IM_MIXER_UNDERCLOCKED_EINT */
-
-/*
- * R3359 (0xD1F) - Interrupt Control
- */
-#define WM5100_IM_IRQ 0x0001 /* IM_IRQ */
-#define WM5100_IM_IRQ_MASK 0x0001 /* IM_IRQ */
-#define WM5100_IM_IRQ_SHIFT 0 /* IM_IRQ */
-#define WM5100_IM_IRQ_WIDTH 1 /* IM_IRQ */
-
-/*
- * R3360 (0xD20) - IRQ Debounce 1
- */
-#define WM5100_SPK_SHUTDOWN_WARN_DB 0x0200 /* SPK_SHUTDOWN_WARN_DB */
-#define WM5100_SPK_SHUTDOWN_WARN_DB_MASK 0x0200 /* SPK_SHUTDOWN_WARN_DB */
-#define WM5100_SPK_SHUTDOWN_WARN_DB_SHIFT 9 /* SPK_SHUTDOWN_WARN_DB */
-#define WM5100_SPK_SHUTDOWN_WARN_DB_WIDTH 1 /* SPK_SHUTDOWN_WARN_DB */
-#define WM5100_SPK_SHUTDOWN_DB 0x0100 /* SPK_SHUTDOWN_DB */
-#define WM5100_SPK_SHUTDOWN_DB_MASK 0x0100 /* SPK_SHUTDOWN_DB */
-#define WM5100_SPK_SHUTDOWN_DB_SHIFT 8 /* SPK_SHUTDOWN_DB */
-#define WM5100_SPK_SHUTDOWN_DB_WIDTH 1 /* SPK_SHUTDOWN_DB */
-#define WM5100_FLL1_LOCK_IRQ_DB 0x0008 /* FLL1_LOCK_IRQ_DB */
-#define WM5100_FLL1_LOCK_IRQ_DB_MASK 0x0008 /* FLL1_LOCK_IRQ_DB */
-#define WM5100_FLL1_LOCK_IRQ_DB_SHIFT 3 /* FLL1_LOCK_IRQ_DB */
-#define WM5100_FLL1_LOCK_IRQ_DB_WIDTH 1 /* FLL1_LOCK_IRQ_DB */
-#define WM5100_FLL2_LOCK_IRQ_DB 0x0004 /* FLL2_LOCK_IRQ_DB */
-#define WM5100_FLL2_LOCK_IRQ_DB_MASK 0x0004 /* FLL2_LOCK_IRQ_DB */
-#define WM5100_FLL2_LOCK_IRQ_DB_SHIFT 2 /* FLL2_LOCK_IRQ_DB */
-#define WM5100_FLL2_LOCK_IRQ_DB_WIDTH 1 /* FLL2_LOCK_IRQ_DB */
-#define WM5100_CLKGEN_ERR_IRQ_DB 0x0002 /* CLKGEN_ERR_IRQ_DB */
-#define WM5100_CLKGEN_ERR_IRQ_DB_MASK 0x0002 /* CLKGEN_ERR_IRQ_DB */
-#define WM5100_CLKGEN_ERR_IRQ_DB_SHIFT 1 /* CLKGEN_ERR_IRQ_DB */
-#define WM5100_CLKGEN_ERR_IRQ_DB_WIDTH 1 /* CLKGEN_ERR_IRQ_DB */
-#define WM5100_CLKGEN_ERR_ASYNC_IRQ_DB 0x0001 /* CLKGEN_ERR_ASYNC_IRQ_DB */
-#define WM5100_CLKGEN_ERR_ASYNC_IRQ_DB_MASK 0x0001 /* CLKGEN_ERR_ASYNC_IRQ_DB */
-#define WM5100_CLKGEN_ERR_ASYNC_IRQ_DB_SHIFT 0 /* CLKGEN_ERR_ASYNC_IRQ_DB */
-#define WM5100_CLKGEN_ERR_ASYNC_IRQ_DB_WIDTH 1 /* CLKGEN_ERR_ASYNC_IRQ_DB */
-
-/*
- * R3361 (0xD21) - IRQ Debounce 2
- */
-#define WM5100_AIF_ERR_DB 0x0001 /* AIF_ERR_DB */
-#define WM5100_AIF_ERR_DB_MASK 0x0001 /* AIF_ERR_DB */
-#define WM5100_AIF_ERR_DB_SHIFT 0 /* AIF_ERR_DB */
-#define WM5100_AIF_ERR_DB_WIDTH 1 /* AIF_ERR_DB */
-
-/*
- * R3584 (0xE00) - FX_Ctrl
- */
-#define WM5100_FX_STS_MASK 0xFFC0 /* FX_STS - [15:6] */
-#define WM5100_FX_STS_SHIFT 6 /* FX_STS - [15:6] */
-#define WM5100_FX_STS_WIDTH 10 /* FX_STS - [15:6] */
-#define WM5100_FX_RATE_MASK 0x0003 /* FX_RATE - [1:0] */
-#define WM5100_FX_RATE_SHIFT 0 /* FX_RATE - [1:0] */
-#define WM5100_FX_RATE_WIDTH 2 /* FX_RATE - [1:0] */
-
-/*
- * R3600 (0xE10) - EQ1_1
- */
-#define WM5100_EQ1_B1_GAIN_MASK 0xF800 /* EQ1_B1_GAIN - [15:11] */
-#define WM5100_EQ1_B1_GAIN_SHIFT 11 /* EQ1_B1_GAIN - [15:11] */
-#define WM5100_EQ1_B1_GAIN_WIDTH 5 /* EQ1_B1_GAIN - [15:11] */
-#define WM5100_EQ1_B2_GAIN_MASK 0x07C0 /* EQ1_B2_GAIN - [10:6] */
-#define WM5100_EQ1_B2_GAIN_SHIFT 6 /* EQ1_B2_GAIN - [10:6] */
-#define WM5100_EQ1_B2_GAIN_WIDTH 5 /* EQ1_B2_GAIN - [10:6] */
-#define WM5100_EQ1_B3_GAIN_MASK 0x003E /* EQ1_B3_GAIN - [5:1] */
-#define WM5100_EQ1_B3_GAIN_SHIFT 1 /* EQ1_B3_GAIN - [5:1] */
-#define WM5100_EQ1_B3_GAIN_WIDTH 5 /* EQ1_B3_GAIN - [5:1] */
-#define WM5100_EQ1_ENA 0x0001 /* EQ1_ENA */
-#define WM5100_EQ1_ENA_MASK 0x0001 /* EQ1_ENA */
-#define WM5100_EQ1_ENA_SHIFT 0 /* EQ1_ENA */
-#define WM5100_EQ1_ENA_WIDTH 1 /* EQ1_ENA */
-
-/*
- * R3601 (0xE11) - EQ1_2
- */
-#define WM5100_EQ1_B4_GAIN_MASK 0xF800 /* EQ1_B4_GAIN - [15:11] */
-#define WM5100_EQ1_B4_GAIN_SHIFT 11 /* EQ1_B4_GAIN - [15:11] */
-#define WM5100_EQ1_B4_GAIN_WIDTH 5 /* EQ1_B4_GAIN - [15:11] */
-#define WM5100_EQ1_B5_GAIN_MASK 0x07C0 /* EQ1_B5_GAIN - [10:6] */
-#define WM5100_EQ1_B5_GAIN_SHIFT 6 /* EQ1_B5_GAIN - [10:6] */
-#define WM5100_EQ1_B5_GAIN_WIDTH 5 /* EQ1_B5_GAIN - [10:6] */
-
-/*
- * R3602 (0xE12) - EQ1_3
- */
-#define WM5100_EQ1_B1_A_MASK 0xFFFF /* EQ1_B1_A - [15:0] */
-#define WM5100_EQ1_B1_A_SHIFT 0 /* EQ1_B1_A - [15:0] */
-#define WM5100_EQ1_B1_A_WIDTH 16 /* EQ1_B1_A - [15:0] */
-
-/*
- * R3603 (0xE13) - EQ1_4
- */
-#define WM5100_EQ1_B1_B_MASK 0xFFFF /* EQ1_B1_B - [15:0] */
-#define WM5100_EQ1_B1_B_SHIFT 0 /* EQ1_B1_B - [15:0] */
-#define WM5100_EQ1_B1_B_WIDTH 16 /* EQ1_B1_B - [15:0] */
-
-/*
- * R3604 (0xE14) - EQ1_5
- */
-#define WM5100_EQ1_B1_PG_MASK 0xFFFF /* EQ1_B1_PG - [15:0] */
-#define WM5100_EQ1_B1_PG_SHIFT 0 /* EQ1_B1_PG - [15:0] */
-#define WM5100_EQ1_B1_PG_WIDTH 16 /* EQ1_B1_PG - [15:0] */
-
-/*
- * R3605 (0xE15) - EQ1_6
- */
-#define WM5100_EQ1_B2_A_MASK 0xFFFF /* EQ1_B2_A - [15:0] */
-#define WM5100_EQ1_B2_A_SHIFT 0 /* EQ1_B2_A - [15:0] */
-#define WM5100_EQ1_B2_A_WIDTH 16 /* EQ1_B2_A - [15:0] */
-
-/*
- * R3606 (0xE16) - EQ1_7
- */
-#define WM5100_EQ1_B2_B_MASK 0xFFFF /* EQ1_B2_B - [15:0] */
-#define WM5100_EQ1_B2_B_SHIFT 0 /* EQ1_B2_B - [15:0] */
-#define WM5100_EQ1_B2_B_WIDTH 16 /* EQ1_B2_B - [15:0] */
-
-/*
- * R3607 (0xE17) - EQ1_8
- */
-#define WM5100_EQ1_B2_C_MASK 0xFFFF /* EQ1_B2_C - [15:0] */
-#define WM5100_EQ1_B2_C_SHIFT 0 /* EQ1_B2_C - [15:0] */
-#define WM5100_EQ1_B2_C_WIDTH 16 /* EQ1_B2_C - [15:0] */
-
-/*
- * R3608 (0xE18) - EQ1_9
- */
-#define WM5100_EQ1_B2_PG_MASK 0xFFFF /* EQ1_B2_PG - [15:0] */
-#define WM5100_EQ1_B2_PG_SHIFT 0 /* EQ1_B2_PG - [15:0] */
-#define WM5100_EQ1_B2_PG_WIDTH 16 /* EQ1_B2_PG - [15:0] */
-
-/*
- * R3609 (0xE19) - EQ1_10
- */
-#define WM5100_EQ1_B3_A_MASK 0xFFFF /* EQ1_B3_A - [15:0] */
-#define WM5100_EQ1_B3_A_SHIFT 0 /* EQ1_B3_A - [15:0] */
-#define WM5100_EQ1_B3_A_WIDTH 16 /* EQ1_B3_A - [15:0] */
-
-/*
- * R3610 (0xE1A) - EQ1_11
- */
-#define WM5100_EQ1_B3_B_MASK 0xFFFF /* EQ1_B3_B - [15:0] */
-#define WM5100_EQ1_B3_B_SHIFT 0 /* EQ1_B3_B - [15:0] */
-#define WM5100_EQ1_B3_B_WIDTH 16 /* EQ1_B3_B - [15:0] */
-
-/*
- * R3611 (0xE1B) - EQ1_12
- */
-#define WM5100_EQ1_B3_C_MASK 0xFFFF /* EQ1_B3_C - [15:0] */
-#define WM5100_EQ1_B3_C_SHIFT 0 /* EQ1_B3_C - [15:0] */
-#define WM5100_EQ1_B3_C_WIDTH 16 /* EQ1_B3_C - [15:0] */
-
-/*
- * R3612 (0xE1C) - EQ1_13
- */
-#define WM5100_EQ1_B3_PG_MASK 0xFFFF /* EQ1_B3_PG - [15:0] */
-#define WM5100_EQ1_B3_PG_SHIFT 0 /* EQ1_B3_PG - [15:0] */
-#define WM5100_EQ1_B3_PG_WIDTH 16 /* EQ1_B3_PG - [15:0] */
-
-/*
- * R3613 (0xE1D) - EQ1_14
- */
-#define WM5100_EQ1_B4_A_MASK 0xFFFF /* EQ1_B4_A - [15:0] */
-#define WM5100_EQ1_B4_A_SHIFT 0 /* EQ1_B4_A - [15:0] */
-#define WM5100_EQ1_B4_A_WIDTH 16 /* EQ1_B4_A - [15:0] */
-
-/*
- * R3614 (0xE1E) - EQ1_15
- */
-#define WM5100_EQ1_B4_B_MASK 0xFFFF /* EQ1_B4_B - [15:0] */
-#define WM5100_EQ1_B4_B_SHIFT 0 /* EQ1_B4_B - [15:0] */
-#define WM5100_EQ1_B4_B_WIDTH 16 /* EQ1_B4_B - [15:0] */
-
-/*
- * R3615 (0xE1F) - EQ1_16
- */
-#define WM5100_EQ1_B4_C_MASK 0xFFFF /* EQ1_B4_C - [15:0] */
-#define WM5100_EQ1_B4_C_SHIFT 0 /* EQ1_B4_C - [15:0] */
-#define WM5100_EQ1_B4_C_WIDTH 16 /* EQ1_B4_C - [15:0] */
-
-/*
- * R3616 (0xE20) - EQ1_17
- */
-#define WM5100_EQ1_B4_PG_MASK 0xFFFF /* EQ1_B4_PG - [15:0] */
-#define WM5100_EQ1_B4_PG_SHIFT 0 /* EQ1_B4_PG - [15:0] */
-#define WM5100_EQ1_B4_PG_WIDTH 16 /* EQ1_B4_PG - [15:0] */
-
-/*
- * R3617 (0xE21) - EQ1_18
- */
-#define WM5100_EQ1_B5_A_MASK 0xFFFF /* EQ1_B5_A - [15:0] */
-#define WM5100_EQ1_B5_A_SHIFT 0 /* EQ1_B5_A - [15:0] */
-#define WM5100_EQ1_B5_A_WIDTH 16 /* EQ1_B5_A - [15:0] */
-
-/*
- * R3618 (0xE22) - EQ1_19
- */
-#define WM5100_EQ1_B5_B_MASK 0xFFFF /* EQ1_B5_B - [15:0] */
-#define WM5100_EQ1_B5_B_SHIFT 0 /* EQ1_B5_B - [15:0] */
-#define WM5100_EQ1_B5_B_WIDTH 16 /* EQ1_B5_B - [15:0] */
-
-/*
- * R3619 (0xE23) - EQ1_20
- */
-#define WM5100_EQ1_B5_PG_MASK 0xFFFF /* EQ1_B5_PG - [15:0] */
-#define WM5100_EQ1_B5_PG_SHIFT 0 /* EQ1_B5_PG - [15:0] */
-#define WM5100_EQ1_B5_PG_WIDTH 16 /* EQ1_B5_PG - [15:0] */
-
-/*
- * R3622 (0xE26) - EQ2_1
- */
-#define WM5100_EQ2_B1_GAIN_MASK 0xF800 /* EQ2_B1_GAIN - [15:11] */
-#define WM5100_EQ2_B1_GAIN_SHIFT 11 /* EQ2_B1_GAIN - [15:11] */
-#define WM5100_EQ2_B1_GAIN_WIDTH 5 /* EQ2_B1_GAIN - [15:11] */
-#define WM5100_EQ2_B2_GAIN_MASK 0x07C0 /* EQ2_B2_GAIN - [10:6] */
-#define WM5100_EQ2_B2_GAIN_SHIFT 6 /* EQ2_B2_GAIN - [10:6] */
-#define WM5100_EQ2_B2_GAIN_WIDTH 5 /* EQ2_B2_GAIN - [10:6] */
-#define WM5100_EQ2_B3_GAIN_MASK 0x003E /* EQ2_B3_GAIN - [5:1] */
-#define WM5100_EQ2_B3_GAIN_SHIFT 1 /* EQ2_B3_GAIN - [5:1] */
-#define WM5100_EQ2_B3_GAIN_WIDTH 5 /* EQ2_B3_GAIN - [5:1] */
-#define WM5100_EQ2_ENA 0x0001 /* EQ2_ENA */
-#define WM5100_EQ2_ENA_MASK 0x0001 /* EQ2_ENA */
-#define WM5100_EQ2_ENA_SHIFT 0 /* EQ2_ENA */
-#define WM5100_EQ2_ENA_WIDTH 1 /* EQ2_ENA */
-
-/*
- * R3623 (0xE27) - EQ2_2
- */
-#define WM5100_EQ2_B4_GAIN_MASK 0xF800 /* EQ2_B4_GAIN - [15:11] */
-#define WM5100_EQ2_B4_GAIN_SHIFT 11 /* EQ2_B4_GAIN - [15:11] */
-#define WM5100_EQ2_B4_GAIN_WIDTH 5 /* EQ2_B4_GAIN - [15:11] */
-#define WM5100_EQ2_B5_GAIN_MASK 0x07C0 /* EQ2_B5_GAIN - [10:6] */
-#define WM5100_EQ2_B5_GAIN_SHIFT 6 /* EQ2_B5_GAIN - [10:6] */
-#define WM5100_EQ2_B5_GAIN_WIDTH 5 /* EQ2_B5_GAIN - [10:6] */
-
-/*
- * R3624 (0xE28) - EQ2_3
- */
-#define WM5100_EQ2_B1_A_MASK 0xFFFF /* EQ2_B1_A - [15:0] */
-#define WM5100_EQ2_B1_A_SHIFT 0 /* EQ2_B1_A - [15:0] */
-#define WM5100_EQ2_B1_A_WIDTH 16 /* EQ2_B1_A - [15:0] */
-
-/*
- * R3625 (0xE29) - EQ2_4
- */
-#define WM5100_EQ2_B1_B_MASK 0xFFFF /* EQ2_B1_B - [15:0] */
-#define WM5100_EQ2_B1_B_SHIFT 0 /* EQ2_B1_B - [15:0] */
-#define WM5100_EQ2_B1_B_WIDTH 16 /* EQ2_B1_B - [15:0] */
-
-/*
- * R3626 (0xE2A) - EQ2_5
- */
-#define WM5100_EQ2_B1_PG_MASK 0xFFFF /* EQ2_B1_PG - [15:0] */
-#define WM5100_EQ2_B1_PG_SHIFT 0 /* EQ2_B1_PG - [15:0] */
-#define WM5100_EQ2_B1_PG_WIDTH 16 /* EQ2_B1_PG - [15:0] */
-
-/*
- * R3627 (0xE2B) - EQ2_6
- */
-#define WM5100_EQ2_B2_A_MASK 0xFFFF /* EQ2_B2_A - [15:0] */
-#define WM5100_EQ2_B2_A_SHIFT 0 /* EQ2_B2_A - [15:0] */
-#define WM5100_EQ2_B2_A_WIDTH 16 /* EQ2_B2_A - [15:0] */
-
-/*
- * R3628 (0xE2C) - EQ2_7
- */
-#define WM5100_EQ2_B2_B_MASK 0xFFFF /* EQ2_B2_B - [15:0] */
-#define WM5100_EQ2_B2_B_SHIFT 0 /* EQ2_B2_B - [15:0] */
-#define WM5100_EQ2_B2_B_WIDTH 16 /* EQ2_B2_B - [15:0] */
-
-/*
- * R3629 (0xE2D) - EQ2_8
- */
-#define WM5100_EQ2_B2_C_MASK 0xFFFF /* EQ2_B2_C - [15:0] */
-#define WM5100_EQ2_B2_C_SHIFT 0 /* EQ2_B2_C - [15:0] */
-#define WM5100_EQ2_B2_C_WIDTH 16 /* EQ2_B2_C - [15:0] */
-
-/*
- * R3630 (0xE2E) - EQ2_9
- */
-#define WM5100_EQ2_B2_PG_MASK 0xFFFF /* EQ2_B2_PG - [15:0] */
-#define WM5100_EQ2_B2_PG_SHIFT 0 /* EQ2_B2_PG - [15:0] */
-#define WM5100_EQ2_B2_PG_WIDTH 16 /* EQ2_B2_PG - [15:0] */
-
-/*
- * R3631 (0xE2F) - EQ2_10
- */
-#define WM5100_EQ2_B3_A_MASK 0xFFFF /* EQ2_B3_A - [15:0] */
-#define WM5100_EQ2_B3_A_SHIFT 0 /* EQ2_B3_A - [15:0] */
-#define WM5100_EQ2_B3_A_WIDTH 16 /* EQ2_B3_A - [15:0] */
-
-/*
- * R3632 (0xE30) - EQ2_11
- */
-#define WM5100_EQ2_B3_B_MASK 0xFFFF /* EQ2_B3_B - [15:0] */
-#define WM5100_EQ2_B3_B_SHIFT 0 /* EQ2_B3_B - [15:0] */
-#define WM5100_EQ2_B3_B_WIDTH 16 /* EQ2_B3_B - [15:0] */
-
-/*
- * R3633 (0xE31) - EQ2_12
- */
-#define WM5100_EQ2_B3_C_MASK 0xFFFF /* EQ2_B3_C - [15:0] */
-#define WM5100_EQ2_B3_C_SHIFT 0 /* EQ2_B3_C - [15:0] */
-#define WM5100_EQ2_B3_C_WIDTH 16 /* EQ2_B3_C - [15:0] */
-
-/*
- * R3634 (0xE32) - EQ2_13
- */
-#define WM5100_EQ2_B3_PG_MASK 0xFFFF /* EQ2_B3_PG - [15:0] */
-#define WM5100_EQ2_B3_PG_SHIFT 0 /* EQ2_B3_PG - [15:0] */
-#define WM5100_EQ2_B3_PG_WIDTH 16 /* EQ2_B3_PG - [15:0] */
-
-/*
- * R3635 (0xE33) - EQ2_14
- */
-#define WM5100_EQ2_B4_A_MASK 0xFFFF /* EQ2_B4_A - [15:0] */
-#define WM5100_EQ2_B4_A_SHIFT 0 /* EQ2_B4_A - [15:0] */
-#define WM5100_EQ2_B4_A_WIDTH 16 /* EQ2_B4_A - [15:0] */
-
-/*
- * R3636 (0xE34) - EQ2_15
- */
-#define WM5100_EQ2_B4_B_MASK 0xFFFF /* EQ2_B4_B - [15:0] */
-#define WM5100_EQ2_B4_B_SHIFT 0 /* EQ2_B4_B - [15:0] */
-#define WM5100_EQ2_B4_B_WIDTH 16 /* EQ2_B4_B - [15:0] */
-
-/*
- * R3637 (0xE35) - EQ2_16
- */
-#define WM5100_EQ2_B4_C_MASK 0xFFFF /* EQ2_B4_C - [15:0] */
-#define WM5100_EQ2_B4_C_SHIFT 0 /* EQ2_B4_C - [15:0] */
-#define WM5100_EQ2_B4_C_WIDTH 16 /* EQ2_B4_C - [15:0] */
-
-/*
- * R3638 (0xE36) - EQ2_17
- */
-#define WM5100_EQ2_B4_PG_MASK 0xFFFF /* EQ2_B4_PG - [15:0] */
-#define WM5100_EQ2_B4_PG_SHIFT 0 /* EQ2_B4_PG - [15:0] */
-#define WM5100_EQ2_B4_PG_WIDTH 16 /* EQ2_B4_PG - [15:0] */
-
-/*
- * R3639 (0xE37) - EQ2_18
- */
-#define WM5100_EQ2_B5_A_MASK 0xFFFF /* EQ2_B5_A - [15:0] */
-#define WM5100_EQ2_B5_A_SHIFT 0 /* EQ2_B5_A - [15:0] */
-#define WM5100_EQ2_B5_A_WIDTH 16 /* EQ2_B5_A - [15:0] */
-
-/*
- * R3640 (0xE38) - EQ2_19
- */
-#define WM5100_EQ2_B5_B_MASK 0xFFFF /* EQ2_B5_B - [15:0] */
-#define WM5100_EQ2_B5_B_SHIFT 0 /* EQ2_B5_B - [15:0] */
-#define WM5100_EQ2_B5_B_WIDTH 16 /* EQ2_B5_B - [15:0] */
-
-/*
- * R3641 (0xE39) - EQ2_20
- */
-#define WM5100_EQ2_B5_PG_MASK 0xFFFF /* EQ2_B5_PG - [15:0] */
-#define WM5100_EQ2_B5_PG_SHIFT 0 /* EQ2_B5_PG - [15:0] */
-#define WM5100_EQ2_B5_PG_WIDTH 16 /* EQ2_B5_PG - [15:0] */
-
-/*
- * R3644 (0xE3C) - EQ3_1
- */
-#define WM5100_EQ3_B1_GAIN_MASK 0xF800 /* EQ3_B1_GAIN - [15:11] */
-#define WM5100_EQ3_B1_GAIN_SHIFT 11 /* EQ3_B1_GAIN - [15:11] */
-#define WM5100_EQ3_B1_GAIN_WIDTH 5 /* EQ3_B1_GAIN - [15:11] */
-#define WM5100_EQ3_B2_GAIN_MASK 0x07C0 /* EQ3_B2_GAIN - [10:6] */
-#define WM5100_EQ3_B2_GAIN_SHIFT 6 /* EQ3_B2_GAIN - [10:6] */
-#define WM5100_EQ3_B2_GAIN_WIDTH 5 /* EQ3_B2_GAIN - [10:6] */
-#define WM5100_EQ3_B3_GAIN_MASK 0x003E /* EQ3_B3_GAIN - [5:1] */
-#define WM5100_EQ3_B3_GAIN_SHIFT 1 /* EQ3_B3_GAIN - [5:1] */
-#define WM5100_EQ3_B3_GAIN_WIDTH 5 /* EQ3_B3_GAIN - [5:1] */
-#define WM5100_EQ3_ENA 0x0001 /* EQ3_ENA */
-#define WM5100_EQ3_ENA_MASK 0x0001 /* EQ3_ENA */
-#define WM5100_EQ3_ENA_SHIFT 0 /* EQ3_ENA */
-#define WM5100_EQ3_ENA_WIDTH 1 /* EQ3_ENA */
-
-/*
- * R3645 (0xE3D) - EQ3_2
- */
-#define WM5100_EQ3_B4_GAIN_MASK 0xF800 /* EQ3_B4_GAIN - [15:11] */
-#define WM5100_EQ3_B4_GAIN_SHIFT 11 /* EQ3_B4_GAIN - [15:11] */
-#define WM5100_EQ3_B4_GAIN_WIDTH 5 /* EQ3_B4_GAIN - [15:11] */
-#define WM5100_EQ3_B5_GAIN_MASK 0x07C0 /* EQ3_B5_GAIN - [10:6] */
-#define WM5100_EQ3_B5_GAIN_SHIFT 6 /* EQ3_B5_GAIN - [10:6] */
-#define WM5100_EQ3_B5_GAIN_WIDTH 5 /* EQ3_B5_GAIN - [10:6] */
-
-/*
- * R3646 (0xE3E) - EQ3_3
- */
-#define WM5100_EQ3_B1_A_MASK 0xFFFF /* EQ3_B1_A - [15:0] */
-#define WM5100_EQ3_B1_A_SHIFT 0 /* EQ3_B1_A - [15:0] */
-#define WM5100_EQ3_B1_A_WIDTH 16 /* EQ3_B1_A - [15:0] */
-
-/*
- * R3647 (0xE3F) - EQ3_4
- */
-#define WM5100_EQ3_B1_B_MASK 0xFFFF /* EQ3_B1_B - [15:0] */
-#define WM5100_EQ3_B1_B_SHIFT 0 /* EQ3_B1_B - [15:0] */
-#define WM5100_EQ3_B1_B_WIDTH 16 /* EQ3_B1_B - [15:0] */
-
-/*
- * R3648 (0xE40) - EQ3_5
- */
-#define WM5100_EQ3_B1_PG_MASK 0xFFFF /* EQ3_B1_PG - [15:0] */
-#define WM5100_EQ3_B1_PG_SHIFT 0 /* EQ3_B1_PG - [15:0] */
-#define WM5100_EQ3_B1_PG_WIDTH 16 /* EQ3_B1_PG - [15:0] */
-
-/*
- * R3649 (0xE41) - EQ3_6
- */
-#define WM5100_EQ3_B2_A_MASK 0xFFFF /* EQ3_B2_A - [15:0] */
-#define WM5100_EQ3_B2_A_SHIFT 0 /* EQ3_B2_A - [15:0] */
-#define WM5100_EQ3_B2_A_WIDTH 16 /* EQ3_B2_A - [15:0] */
-
-/*
- * R3650 (0xE42) - EQ3_7
- */
-#define WM5100_EQ3_B2_B_MASK 0xFFFF /* EQ3_B2_B - [15:0] */
-#define WM5100_EQ3_B2_B_SHIFT 0 /* EQ3_B2_B - [15:0] */
-#define WM5100_EQ3_B2_B_WIDTH 16 /* EQ3_B2_B - [15:0] */
-
-/*
- * R3651 (0xE43) - EQ3_8
- */
-#define WM5100_EQ3_B2_C_MASK 0xFFFF /* EQ3_B2_C - [15:0] */
-#define WM5100_EQ3_B2_C_SHIFT 0 /* EQ3_B2_C - [15:0] */
-#define WM5100_EQ3_B2_C_WIDTH 16 /* EQ3_B2_C - [15:0] */
-
-/*
- * R3652 (0xE44) - EQ3_9
- */
-#define WM5100_EQ3_B2_PG_MASK 0xFFFF /* EQ3_B2_PG - [15:0] */
-#define WM5100_EQ3_B2_PG_SHIFT 0 /* EQ3_B2_PG - [15:0] */
-#define WM5100_EQ3_B2_PG_WIDTH 16 /* EQ3_B2_PG - [15:0] */
-
-/*
- * R3653 (0xE45) - EQ3_10
- */
-#define WM5100_EQ3_B3_A_MASK 0xFFFF /* EQ3_B3_A - [15:0] */
-#define WM5100_EQ3_B3_A_SHIFT 0 /* EQ3_B3_A - [15:0] */
-#define WM5100_EQ3_B3_A_WIDTH 16 /* EQ3_B3_A - [15:0] */
-
-/*
- * R3654 (0xE46) - EQ3_11
- */
-#define WM5100_EQ3_B3_B_MASK 0xFFFF /* EQ3_B3_B - [15:0] */
-#define WM5100_EQ3_B3_B_SHIFT 0 /* EQ3_B3_B - [15:0] */
-#define WM5100_EQ3_B3_B_WIDTH 16 /* EQ3_B3_B - [15:0] */
-
-/*
- * R3655 (0xE47) - EQ3_12
- */
-#define WM5100_EQ3_B3_C_MASK 0xFFFF /* EQ3_B3_C - [15:0] */
-#define WM5100_EQ3_B3_C_SHIFT 0 /* EQ3_B3_C - [15:0] */
-#define WM5100_EQ3_B3_C_WIDTH 16 /* EQ3_B3_C - [15:0] */
-
-/*
- * R3656 (0xE48) - EQ3_13
- */
-#define WM5100_EQ3_B3_PG_MASK 0xFFFF /* EQ3_B3_PG - [15:0] */
-#define WM5100_EQ3_B3_PG_SHIFT 0 /* EQ3_B3_PG - [15:0] */
-#define WM5100_EQ3_B3_PG_WIDTH 16 /* EQ3_B3_PG - [15:0] */
-
-/*
- * R3657 (0xE49) - EQ3_14
- */
-#define WM5100_EQ3_B4_A_MASK 0xFFFF /* EQ3_B4_A - [15:0] */
-#define WM5100_EQ3_B4_A_SHIFT 0 /* EQ3_B4_A - [15:0] */
-#define WM5100_EQ3_B4_A_WIDTH 16 /* EQ3_B4_A - [15:0] */
-
-/*
- * R3658 (0xE4A) - EQ3_15
- */
-#define WM5100_EQ3_B4_B_MASK 0xFFFF /* EQ3_B4_B - [15:0] */
-#define WM5100_EQ3_B4_B_SHIFT 0 /* EQ3_B4_B - [15:0] */
-#define WM5100_EQ3_B4_B_WIDTH 16 /* EQ3_B4_B - [15:0] */
-
-/*
- * R3659 (0xE4B) - EQ3_16
- */
-#define WM5100_EQ3_B4_C_MASK 0xFFFF /* EQ3_B4_C - [15:0] */
-#define WM5100_EQ3_B4_C_SHIFT 0 /* EQ3_B4_C - [15:0] */
-#define WM5100_EQ3_B4_C_WIDTH 16 /* EQ3_B4_C - [15:0] */
-
-/*
- * R3660 (0xE4C) - EQ3_17
- */
-#define WM5100_EQ3_B4_PG_MASK 0xFFFF /* EQ3_B4_PG - [15:0] */
-#define WM5100_EQ3_B4_PG_SHIFT 0 /* EQ3_B4_PG - [15:0] */
-#define WM5100_EQ3_B4_PG_WIDTH 16 /* EQ3_B4_PG - [15:0] */
-
-/*
- * R3661 (0xE4D) - EQ3_18
- */
-#define WM5100_EQ3_B5_A_MASK 0xFFFF /* EQ3_B5_A - [15:0] */
-#define WM5100_EQ3_B5_A_SHIFT 0 /* EQ3_B5_A - [15:0] */
-#define WM5100_EQ3_B5_A_WIDTH 16 /* EQ3_B5_A - [15:0] */
-
-/*
- * R3662 (0xE4E) - EQ3_19
- */
-#define WM5100_EQ3_B5_B_MASK 0xFFFF /* EQ3_B5_B - [15:0] */
-#define WM5100_EQ3_B5_B_SHIFT 0 /* EQ3_B5_B - [15:0] */
-#define WM5100_EQ3_B5_B_WIDTH 16 /* EQ3_B5_B - [15:0] */
-
-/*
- * R3663 (0xE4F) - EQ3_20
- */
-#define WM5100_EQ3_B5_PG_MASK 0xFFFF /* EQ3_B5_PG - [15:0] */
-#define WM5100_EQ3_B5_PG_SHIFT 0 /* EQ3_B5_PG - [15:0] */
-#define WM5100_EQ3_B5_PG_WIDTH 16 /* EQ3_B5_PG - [15:0] */
-
-/*
- * R3666 (0xE52) - EQ4_1
- */
-#define WM5100_EQ4_B1_GAIN_MASK 0xF800 /* EQ4_B1_GAIN - [15:11] */
-#define WM5100_EQ4_B1_GAIN_SHIFT 11 /* EQ4_B1_GAIN - [15:11] */
-#define WM5100_EQ4_B1_GAIN_WIDTH 5 /* EQ4_B1_GAIN - [15:11] */
-#define WM5100_EQ4_B2_GAIN_MASK 0x07C0 /* EQ4_B2_GAIN - [10:6] */
-#define WM5100_EQ4_B2_GAIN_SHIFT 6 /* EQ4_B2_GAIN - [10:6] */
-#define WM5100_EQ4_B2_GAIN_WIDTH 5 /* EQ4_B2_GAIN - [10:6] */
-#define WM5100_EQ4_B3_GAIN_MASK 0x003E /* EQ4_B3_GAIN - [5:1] */
-#define WM5100_EQ4_B3_GAIN_SHIFT 1 /* EQ4_B3_GAIN - [5:1] */
-#define WM5100_EQ4_B3_GAIN_WIDTH 5 /* EQ4_B3_GAIN - [5:1] */
-#define WM5100_EQ4_ENA 0x0001 /* EQ4_ENA */
-#define WM5100_EQ4_ENA_MASK 0x0001 /* EQ4_ENA */
-#define WM5100_EQ4_ENA_SHIFT 0 /* EQ4_ENA */
-#define WM5100_EQ4_ENA_WIDTH 1 /* EQ4_ENA */
-
-/*
- * R3667 (0xE53) - EQ4_2
- */
-#define WM5100_EQ4_B4_GAIN_MASK 0xF800 /* EQ4_B4_GAIN - [15:11] */
-#define WM5100_EQ4_B4_GAIN_SHIFT 11 /* EQ4_B4_GAIN - [15:11] */
-#define WM5100_EQ4_B4_GAIN_WIDTH 5 /* EQ4_B4_GAIN - [15:11] */
-#define WM5100_EQ4_B5_GAIN_MASK 0x07C0 /* EQ4_B5_GAIN - [10:6] */
-#define WM5100_EQ4_B5_GAIN_SHIFT 6 /* EQ4_B5_GAIN - [10:6] */
-#define WM5100_EQ4_B5_GAIN_WIDTH 5 /* EQ4_B5_GAIN - [10:6] */
-
-/*
- * R3668 (0xE54) - EQ4_3
- */
-#define WM5100_EQ4_B1_A_MASK 0xFFFF /* EQ4_B1_A - [15:0] */
-#define WM5100_EQ4_B1_A_SHIFT 0 /* EQ4_B1_A - [15:0] */
-#define WM5100_EQ4_B1_A_WIDTH 16 /* EQ4_B1_A - [15:0] */
-
-/*
- * R3669 (0xE55) - EQ4_4
- */
-#define WM5100_EQ4_B1_B_MASK 0xFFFF /* EQ4_B1_B - [15:0] */
-#define WM5100_EQ4_B1_B_SHIFT 0 /* EQ4_B1_B - [15:0] */
-#define WM5100_EQ4_B1_B_WIDTH 16 /* EQ4_B1_B - [15:0] */
-
-/*
- * R3670 (0xE56) - EQ4_5
- */
-#define WM5100_EQ4_B1_PG_MASK 0xFFFF /* EQ4_B1_PG - [15:0] */
-#define WM5100_EQ4_B1_PG_SHIFT 0 /* EQ4_B1_PG - [15:0] */
-#define WM5100_EQ4_B1_PG_WIDTH 16 /* EQ4_B1_PG - [15:0] */
-
-/*
- * R3671 (0xE57) - EQ4_6
- */
-#define WM5100_EQ4_B2_A_MASK 0xFFFF /* EQ4_B2_A - [15:0] */
-#define WM5100_EQ4_B2_A_SHIFT 0 /* EQ4_B2_A - [15:0] */
-#define WM5100_EQ4_B2_A_WIDTH 16 /* EQ4_B2_A - [15:0] */
-
-/*
- * R3672 (0xE58) - EQ4_7
- */
-#define WM5100_EQ4_B2_B_MASK 0xFFFF /* EQ4_B2_B - [15:0] */
-#define WM5100_EQ4_B2_B_SHIFT 0 /* EQ4_B2_B - [15:0] */
-#define WM5100_EQ4_B2_B_WIDTH 16 /* EQ4_B2_B - [15:0] */
-
-/*
- * R3673 (0xE59) - EQ4_8
- */
-#define WM5100_EQ4_B2_C_MASK 0xFFFF /* EQ4_B2_C - [15:0] */
-#define WM5100_EQ4_B2_C_SHIFT 0 /* EQ4_B2_C - [15:0] */
-#define WM5100_EQ4_B2_C_WIDTH 16 /* EQ4_B2_C - [15:0] */
-
-/*
- * R3674 (0xE5A) - EQ4_9
- */
-#define WM5100_EQ4_B2_PG_MASK 0xFFFF /* EQ4_B2_PG - [15:0] */
-#define WM5100_EQ4_B2_PG_SHIFT 0 /* EQ4_B2_PG - [15:0] */
-#define WM5100_EQ4_B2_PG_WIDTH 16 /* EQ4_B2_PG - [15:0] */
-
-/*
- * R3675 (0xE5B) - EQ4_10
- */
-#define WM5100_EQ4_B3_A_MASK 0xFFFF /* EQ4_B3_A - [15:0] */
-#define WM5100_EQ4_B3_A_SHIFT 0 /* EQ4_B3_A - [15:0] */
-#define WM5100_EQ4_B3_A_WIDTH 16 /* EQ4_B3_A - [15:0] */
-
-/*
- * R3676 (0xE5C) - EQ4_11
- */
-#define WM5100_EQ4_B3_B_MASK 0xFFFF /* EQ4_B3_B - [15:0] */
-#define WM5100_EQ4_B3_B_SHIFT 0 /* EQ4_B3_B - [15:0] */
-#define WM5100_EQ4_B3_B_WIDTH 16 /* EQ4_B3_B - [15:0] */
-
-/*
- * R3677 (0xE5D) - EQ4_12
- */
-#define WM5100_EQ4_B3_C_MASK 0xFFFF /* EQ4_B3_C - [15:0] */
-#define WM5100_EQ4_B3_C_SHIFT 0 /* EQ4_B3_C - [15:0] */
-#define WM5100_EQ4_B3_C_WIDTH 16 /* EQ4_B3_C - [15:0] */
-
-/*
- * R3678 (0xE5E) - EQ4_13
- */
-#define WM5100_EQ4_B3_PG_MASK 0xFFFF /* EQ4_B3_PG - [15:0] */
-#define WM5100_EQ4_B3_PG_SHIFT 0 /* EQ4_B3_PG - [15:0] */
-#define WM5100_EQ4_B3_PG_WIDTH 16 /* EQ4_B3_PG - [15:0] */
-
-/*
- * R3679 (0xE5F) - EQ4_14
- */
-#define WM5100_EQ4_B4_A_MASK 0xFFFF /* EQ4_B4_A - [15:0] */
-#define WM5100_EQ4_B4_A_SHIFT 0 /* EQ4_B4_A - [15:0] */
-#define WM5100_EQ4_B4_A_WIDTH 16 /* EQ4_B4_A - [15:0] */
-
-/*
- * R3680 (0xE60) - EQ4_15
- */
-#define WM5100_EQ4_B4_B_MASK 0xFFFF /* EQ4_B4_B - [15:0] */
-#define WM5100_EQ4_B4_B_SHIFT 0 /* EQ4_B4_B - [15:0] */
-#define WM5100_EQ4_B4_B_WIDTH 16 /* EQ4_B4_B - [15:0] */
-
-/*
- * R3681 (0xE61) - EQ4_16
- */
-#define WM5100_EQ4_B4_C_MASK 0xFFFF /* EQ4_B4_C - [15:0] */
-#define WM5100_EQ4_B4_C_SHIFT 0 /* EQ4_B4_C - [15:0] */
-#define WM5100_EQ4_B4_C_WIDTH 16 /* EQ4_B4_C - [15:0] */
-
-/*
- * R3682 (0xE62) - EQ4_17
- */
-#define WM5100_EQ4_B4_PG_MASK 0xFFFF /* EQ4_B4_PG - [15:0] */
-#define WM5100_EQ4_B4_PG_SHIFT 0 /* EQ4_B4_PG - [15:0] */
-#define WM5100_EQ4_B4_PG_WIDTH 16 /* EQ4_B4_PG - [15:0] */
-
-/*
- * R3683 (0xE63) - EQ4_18
- */
-#define WM5100_EQ4_B5_A_MASK 0xFFFF /* EQ4_B5_A - [15:0] */
-#define WM5100_EQ4_B5_A_SHIFT 0 /* EQ4_B5_A - [15:0] */
-#define WM5100_EQ4_B5_A_WIDTH 16 /* EQ4_B5_A - [15:0] */
-
-/*
- * R3684 (0xE64) - EQ4_19
- */
-#define WM5100_EQ4_B5_B_MASK 0xFFFF /* EQ4_B5_B - [15:0] */
-#define WM5100_EQ4_B5_B_SHIFT 0 /* EQ4_B5_B - [15:0] */
-#define WM5100_EQ4_B5_B_WIDTH 16 /* EQ4_B5_B - [15:0] */
-
-/*
- * R3685 (0xE65) - EQ4_20
- */
-#define WM5100_EQ4_B5_PG_MASK 0xFFFF /* EQ4_B5_PG - [15:0] */
-#define WM5100_EQ4_B5_PG_SHIFT 0 /* EQ4_B5_PG - [15:0] */
-#define WM5100_EQ4_B5_PG_WIDTH 16 /* EQ4_B5_PG - [15:0] */
-
-/*
- * R3712 (0xE80) - DRC1 ctrl1
- */
-#define WM5100_DRC_SIG_DET_RMS_MASK 0xF800 /* DRC_SIG_DET_RMS - [15:11] */
-#define WM5100_DRC_SIG_DET_RMS_SHIFT 11 /* DRC_SIG_DET_RMS - [15:11] */
-#define WM5100_DRC_SIG_DET_RMS_WIDTH 5 /* DRC_SIG_DET_RMS - [15:11] */
-#define WM5100_DRC_SIG_DET_PK_MASK 0x0600 /* DRC_SIG_DET_PK - [10:9] */
-#define WM5100_DRC_SIG_DET_PK_SHIFT 9 /* DRC_SIG_DET_PK - [10:9] */
-#define WM5100_DRC_SIG_DET_PK_WIDTH 2 /* DRC_SIG_DET_PK - [10:9] */
-#define WM5100_DRC_NG_ENA 0x0100 /* DRC_NG_ENA */
-#define WM5100_DRC_NG_ENA_MASK 0x0100 /* DRC_NG_ENA */
-#define WM5100_DRC_NG_ENA_SHIFT 8 /* DRC_NG_ENA */
-#define WM5100_DRC_NG_ENA_WIDTH 1 /* DRC_NG_ENA */
-#define WM5100_DRC_SIG_DET_MODE 0x0080 /* DRC_SIG_DET_MODE */
-#define WM5100_DRC_SIG_DET_MODE_MASK 0x0080 /* DRC_SIG_DET_MODE */
-#define WM5100_DRC_SIG_DET_MODE_SHIFT 7 /* DRC_SIG_DET_MODE */
-#define WM5100_DRC_SIG_DET_MODE_WIDTH 1 /* DRC_SIG_DET_MODE */
-#define WM5100_DRC_SIG_DET 0x0040 /* DRC_SIG_DET */
-#define WM5100_DRC_SIG_DET_MASK 0x0040 /* DRC_SIG_DET */
-#define WM5100_DRC_SIG_DET_SHIFT 6 /* DRC_SIG_DET */
-#define WM5100_DRC_SIG_DET_WIDTH 1 /* DRC_SIG_DET */
-#define WM5100_DRC_KNEE2_OP_ENA 0x0020 /* DRC_KNEE2_OP_ENA */
-#define WM5100_DRC_KNEE2_OP_ENA_MASK 0x0020 /* DRC_KNEE2_OP_ENA */
-#define WM5100_DRC_KNEE2_OP_ENA_SHIFT 5 /* DRC_KNEE2_OP_ENA */
-#define WM5100_DRC_KNEE2_OP_ENA_WIDTH 1 /* DRC_KNEE2_OP_ENA */
-#define WM5100_DRC_QR 0x0010 /* DRC_QR */
-#define WM5100_DRC_QR_MASK 0x0010 /* DRC_QR */
-#define WM5100_DRC_QR_SHIFT 4 /* DRC_QR */
-#define WM5100_DRC_QR_WIDTH 1 /* DRC_QR */
-#define WM5100_DRC_ANTICLIP 0x0008 /* DRC_ANTICLIP */
-#define WM5100_DRC_ANTICLIP_MASK 0x0008 /* DRC_ANTICLIP */
-#define WM5100_DRC_ANTICLIP_SHIFT 3 /* DRC_ANTICLIP */
-#define WM5100_DRC_ANTICLIP_WIDTH 1 /* DRC_ANTICLIP */
-#define WM5100_DRCL_ENA 0x0002 /* DRCL_ENA */
-#define WM5100_DRCL_ENA_MASK 0x0002 /* DRCL_ENA */
-#define WM5100_DRCL_ENA_SHIFT 1 /* DRCL_ENA */
-#define WM5100_DRCL_ENA_WIDTH 1 /* DRCL_ENA */
-#define WM5100_DRCR_ENA 0x0001 /* DRCR_ENA */
-#define WM5100_DRCR_ENA_MASK 0x0001 /* DRCR_ENA */
-#define WM5100_DRCR_ENA_SHIFT 0 /* DRCR_ENA */
-#define WM5100_DRCR_ENA_WIDTH 1 /* DRCR_ENA */
-
-/*
- * R3713 (0xE81) - DRC1 ctrl2
- */
-#define WM5100_DRC_ATK_MASK 0x1E00 /* DRC_ATK - [12:9] */
-#define WM5100_DRC_ATK_SHIFT 9 /* DRC_ATK - [12:9] */
-#define WM5100_DRC_ATK_WIDTH 4 /* DRC_ATK - [12:9] */
-#define WM5100_DRC_DCY_MASK 0x01E0 /* DRC_DCY - [8:5] */
-#define WM5100_DRC_DCY_SHIFT 5 /* DRC_DCY - [8:5] */
-#define WM5100_DRC_DCY_WIDTH 4 /* DRC_DCY - [8:5] */
-#define WM5100_DRC_MINGAIN_MASK 0x001C /* DRC_MINGAIN - [4:2] */
-#define WM5100_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [4:2] */
-#define WM5100_DRC_MINGAIN_WIDTH 3 /* DRC_MINGAIN - [4:2] */
-#define WM5100_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */
-#define WM5100_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */
-#define WM5100_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */
-
-/*
- * R3714 (0xE82) - DRC1 ctrl3
- */
-#define WM5100_DRC_NG_MINGAIN_MASK 0xF000 /* DRC_NG_MINGAIN - [15:12] */
-#define WM5100_DRC_NG_MINGAIN_SHIFT 12 /* DRC_NG_MINGAIN - [15:12] */
-#define WM5100_DRC_NG_MINGAIN_WIDTH 4 /* DRC_NG_MINGAIN - [15:12] */
-#define WM5100_DRC_NG_EXP_MASK 0x0C00 /* DRC_NG_EXP - [11:10] */
-#define WM5100_DRC_NG_EXP_SHIFT 10 /* DRC_NG_EXP - [11:10] */
-#define WM5100_DRC_NG_EXP_WIDTH 2 /* DRC_NG_EXP - [11:10] */
-#define WM5100_DRC_QR_THR_MASK 0x0300 /* DRC_QR_THR - [9:8] */
-#define WM5100_DRC_QR_THR_SHIFT 8 /* DRC_QR_THR - [9:8] */
-#define WM5100_DRC_QR_THR_WIDTH 2 /* DRC_QR_THR - [9:8] */
-#define WM5100_DRC_QR_DCY_MASK 0x00C0 /* DRC_QR_DCY - [7:6] */
-#define WM5100_DRC_QR_DCY_SHIFT 6 /* DRC_QR_DCY - [7:6] */
-#define WM5100_DRC_QR_DCY_WIDTH 2 /* DRC_QR_DCY - [7:6] */
-#define WM5100_DRC_HI_COMP_MASK 0x0038 /* DRC_HI_COMP - [5:3] */
-#define WM5100_DRC_HI_COMP_SHIFT 3 /* DRC_HI_COMP - [5:3] */
-#define WM5100_DRC_HI_COMP_WIDTH 3 /* DRC_HI_COMP - [5:3] */
-#define WM5100_DRC_LO_COMP_MASK 0x0007 /* DRC_LO_COMP - [2:0] */
-#define WM5100_DRC_LO_COMP_SHIFT 0 /* DRC_LO_COMP - [2:0] */
-#define WM5100_DRC_LO_COMP_WIDTH 3 /* DRC_LO_COMP - [2:0] */
-
-/*
- * R3715 (0xE83) - DRC1 ctrl4
- */
-#define WM5100_DRC_KNEE_IP_MASK 0x07E0 /* DRC_KNEE_IP - [10:5] */
-#define WM5100_DRC_KNEE_IP_SHIFT 5 /* DRC_KNEE_IP - [10:5] */
-#define WM5100_DRC_KNEE_IP_WIDTH 6 /* DRC_KNEE_IP - [10:5] */
-#define WM5100_DRC_KNEE_OP_MASK 0x001F /* DRC_KNEE_OP - [4:0] */
-#define WM5100_DRC_KNEE_OP_SHIFT 0 /* DRC_KNEE_OP - [4:0] */
-#define WM5100_DRC_KNEE_OP_WIDTH 5 /* DRC_KNEE_OP - [4:0] */
-
-/*
- * R3716 (0xE84) - DRC1 ctrl5
- */
-#define WM5100_DRC_KNEE2_IP_MASK 0x03E0 /* DRC_KNEE2_IP - [9:5] */
-#define WM5100_DRC_KNEE2_IP_SHIFT 5 /* DRC_KNEE2_IP - [9:5] */
-#define WM5100_DRC_KNEE2_IP_WIDTH 5 /* DRC_KNEE2_IP - [9:5] */
-#define WM5100_DRC_KNEE2_OP_MASK 0x001F /* DRC_KNEE2_OP - [4:0] */
-#define WM5100_DRC_KNEE2_OP_SHIFT 0 /* DRC_KNEE2_OP - [4:0] */
-#define WM5100_DRC_KNEE2_OP_WIDTH 5 /* DRC_KNEE2_OP - [4:0] */
-
-/*
- * R3776 (0xEC0) - HPLPF1_1
- */
-#define WM5100_LHPF1_MODE 0x0002 /* LHPF1_MODE */
-#define WM5100_LHPF1_MODE_MASK 0x0002 /* LHPF1_MODE */
-#define WM5100_LHPF1_MODE_SHIFT 1 /* LHPF1_MODE */
-#define WM5100_LHPF1_MODE_WIDTH 1 /* LHPF1_MODE */
-#define WM5100_LHPF1_ENA 0x0001 /* LHPF1_ENA */
-#define WM5100_LHPF1_ENA_MASK 0x0001 /* LHPF1_ENA */
-#define WM5100_LHPF1_ENA_SHIFT 0 /* LHPF1_ENA */
-#define WM5100_LHPF1_ENA_WIDTH 1 /* LHPF1_ENA */
-
-/*
- * R3777 (0xEC1) - HPLPF1_2
- */
-#define WM5100_LHPF1_COEFF_MASK 0xFFFF /* LHPF1_COEFF - [15:0] */
-#define WM5100_LHPF1_COEFF_SHIFT 0 /* LHPF1_COEFF - [15:0] */
-#define WM5100_LHPF1_COEFF_WIDTH 16 /* LHPF1_COEFF - [15:0] */
-
-/*
- * R3780 (0xEC4) - HPLPF2_1
- */
-#define WM5100_LHPF2_MODE 0x0002 /* LHPF2_MODE */
-#define WM5100_LHPF2_MODE_MASK 0x0002 /* LHPF2_MODE */
-#define WM5100_LHPF2_MODE_SHIFT 1 /* LHPF2_MODE */
-#define WM5100_LHPF2_MODE_WIDTH 1 /* LHPF2_MODE */
-#define WM5100_LHPF2_ENA 0x0001 /* LHPF2_ENA */
-#define WM5100_LHPF2_ENA_MASK 0x0001 /* LHPF2_ENA */
-#define WM5100_LHPF2_ENA_SHIFT 0 /* LHPF2_ENA */
-#define WM5100_LHPF2_ENA_WIDTH 1 /* LHPF2_ENA */
-
-/*
- * R3781 (0xEC5) - HPLPF2_2
- */
-#define WM5100_LHPF2_COEFF_MASK 0xFFFF /* LHPF2_COEFF - [15:0] */
-#define WM5100_LHPF2_COEFF_SHIFT 0 /* LHPF2_COEFF - [15:0] */
-#define WM5100_LHPF2_COEFF_WIDTH 16 /* LHPF2_COEFF - [15:0] */
-
-/*
- * R3784 (0xEC8) - HPLPF3_1
- */
-#define WM5100_LHPF3_MODE 0x0002 /* LHPF3_MODE */
-#define WM5100_LHPF3_MODE_MASK 0x0002 /* LHPF3_MODE */
-#define WM5100_LHPF3_MODE_SHIFT 1 /* LHPF3_MODE */
-#define WM5100_LHPF3_MODE_WIDTH 1 /* LHPF3_MODE */
-#define WM5100_LHPF3_ENA 0x0001 /* LHPF3_ENA */
-#define WM5100_LHPF3_ENA_MASK 0x0001 /* LHPF3_ENA */
-#define WM5100_LHPF3_ENA_SHIFT 0 /* LHPF3_ENA */
-#define WM5100_LHPF3_ENA_WIDTH 1 /* LHPF3_ENA */
-
-/*
- * R3785 (0xEC9) - HPLPF3_2
- */
-#define WM5100_LHPF3_COEFF_MASK 0xFFFF /* LHPF3_COEFF - [15:0] */
-#define WM5100_LHPF3_COEFF_SHIFT 0 /* LHPF3_COEFF - [15:0] */
-#define WM5100_LHPF3_COEFF_WIDTH 16 /* LHPF3_COEFF - [15:0] */
-
-/*
- * R3788 (0xECC) - HPLPF4_1
- */
-#define WM5100_LHPF4_MODE 0x0002 /* LHPF4_MODE */
-#define WM5100_LHPF4_MODE_MASK 0x0002 /* LHPF4_MODE */
-#define WM5100_LHPF4_MODE_SHIFT 1 /* LHPF4_MODE */
-#define WM5100_LHPF4_MODE_WIDTH 1 /* LHPF4_MODE */
-#define WM5100_LHPF4_ENA 0x0001 /* LHPF4_ENA */
-#define WM5100_LHPF4_ENA_MASK 0x0001 /* LHPF4_ENA */
-#define WM5100_LHPF4_ENA_SHIFT 0 /* LHPF4_ENA */
-#define WM5100_LHPF4_ENA_WIDTH 1 /* LHPF4_ENA */
-
-/*
- * R3789 (0xECD) - HPLPF4_2
- */
-#define WM5100_LHPF4_COEFF_MASK 0xFFFF /* LHPF4_COEFF - [15:0] */
-#define WM5100_LHPF4_COEFF_SHIFT 0 /* LHPF4_COEFF - [15:0] */
-#define WM5100_LHPF4_COEFF_WIDTH 16 /* LHPF4_COEFF - [15:0] */
-
-/*
- * R16384 (0x4000) - DSP1 DM 0
- */
-#define WM5100_DSP1_DM_START_1_MASK 0x00FF /* DSP1_DM_START - [7:0] */
-#define WM5100_DSP1_DM_START_1_SHIFT 0 /* DSP1_DM_START - [7:0] */
-#define WM5100_DSP1_DM_START_1_WIDTH 8 /* DSP1_DM_START - [7:0] */
-
-/*
- * R16385 (0x4001) - DSP1 DM 1
- */
-#define WM5100_DSP1_DM_START_MASK 0xFFFF /* DSP1_DM_START - [15:0] */
-#define WM5100_DSP1_DM_START_SHIFT 0 /* DSP1_DM_START - [15:0] */
-#define WM5100_DSP1_DM_START_WIDTH 16 /* DSP1_DM_START - [15:0] */
-
-/*
- * R16386 (0x4002) - DSP1 DM 2
- */
-#define WM5100_DSP1_DM_1_1_MASK 0x00FF /* DSP1_DM_1 - [7:0] */
-#define WM5100_DSP1_DM_1_1_SHIFT 0 /* DSP1_DM_1 - [7:0] */
-#define WM5100_DSP1_DM_1_1_WIDTH 8 /* DSP1_DM_1 - [7:0] */
-
-/*
- * R16387 (0x4003) - DSP1 DM 3
- */
-#define WM5100_DSP1_DM_1_MASK 0xFFFF /* DSP1_DM_1 - [15:0] */
-#define WM5100_DSP1_DM_1_SHIFT 0 /* DSP1_DM_1 - [15:0] */
-#define WM5100_DSP1_DM_1_WIDTH 16 /* DSP1_DM_1 - [15:0] */
-
-/*
- * R16892 (0x41FC) - DSP1 DM 508
- */
-#define WM5100_DSP1_DM_254_1_MASK 0x00FF /* DSP1_DM_254 - [7:0] */
-#define WM5100_DSP1_DM_254_1_SHIFT 0 /* DSP1_DM_254 - [7:0] */
-#define WM5100_DSP1_DM_254_1_WIDTH 8 /* DSP1_DM_254 - [7:0] */
-
-/*
- * R16893 (0x41FD) - DSP1 DM 509
- */
-#define WM5100_DSP1_DM_254_MASK 0xFFFF /* DSP1_DM_254 - [15:0] */
-#define WM5100_DSP1_DM_254_SHIFT 0 /* DSP1_DM_254 - [15:0] */
-#define WM5100_DSP1_DM_254_WIDTH 16 /* DSP1_DM_254 - [15:0] */
-
-/*
- * R16894 (0x41FE) - DSP1 DM 510
- */
-#define WM5100_DSP1_DM_END_1_MASK 0x00FF /* DSP1_DM_END - [7:0] */
-#define WM5100_DSP1_DM_END_1_SHIFT 0 /* DSP1_DM_END - [7:0] */
-#define WM5100_DSP1_DM_END_1_WIDTH 8 /* DSP1_DM_END - [7:0] */
-
-/*
- * R16895 (0x41FF) - DSP1 DM 511
- */
-#define WM5100_DSP1_DM_END_MASK 0xFFFF /* DSP1_DM_END - [15:0] */
-#define WM5100_DSP1_DM_END_SHIFT 0 /* DSP1_DM_END - [15:0] */
-#define WM5100_DSP1_DM_END_WIDTH 16 /* DSP1_DM_END - [15:0] */
-
-/*
- * R18432 (0x4800) - DSP1 PM 0
- */
-#define WM5100_DSP1_PM_START_2_MASK 0x00FF /* DSP1_PM_START - [7:0] */
-#define WM5100_DSP1_PM_START_2_SHIFT 0 /* DSP1_PM_START - [7:0] */
-#define WM5100_DSP1_PM_START_2_WIDTH 8 /* DSP1_PM_START - [7:0] */
-
-/*
- * R18433 (0x4801) - DSP1 PM 1
- */
-#define WM5100_DSP1_PM_START_1_MASK 0xFFFF /* DSP1_PM_START - [15:0] */
-#define WM5100_DSP1_PM_START_1_SHIFT 0 /* DSP1_PM_START - [15:0] */
-#define WM5100_DSP1_PM_START_1_WIDTH 16 /* DSP1_PM_START - [15:0] */
-
-/*
- * R18434 (0x4802) - DSP1 PM 2
- */
-#define WM5100_DSP1_PM_START_MASK 0xFFFF /* DSP1_PM_START - [15:0] */
-#define WM5100_DSP1_PM_START_SHIFT 0 /* DSP1_PM_START - [15:0] */
-#define WM5100_DSP1_PM_START_WIDTH 16 /* DSP1_PM_START - [15:0] */
-
-/*
- * R18435 (0x4803) - DSP1 PM 3
- */
-#define WM5100_DSP1_PM_1_2_MASK 0x00FF /* DSP1_PM_1 - [7:0] */
-#define WM5100_DSP1_PM_1_2_SHIFT 0 /* DSP1_PM_1 - [7:0] */
-#define WM5100_DSP1_PM_1_2_WIDTH 8 /* DSP1_PM_1 - [7:0] */
-
-/*
- * R18436 (0x4804) - DSP1 PM 4
- */
-#define WM5100_DSP1_PM_1_1_MASK 0xFFFF /* DSP1_PM_1 - [15:0] */
-#define WM5100_DSP1_PM_1_1_SHIFT 0 /* DSP1_PM_1 - [15:0] */
-#define WM5100_DSP1_PM_1_1_WIDTH 16 /* DSP1_PM_1 - [15:0] */
-
-/*
- * R18437 (0x4805) - DSP1 PM 5
- */
-#define WM5100_DSP1_PM_1_MASK 0xFFFF /* DSP1_PM_1 - [15:0] */
-#define WM5100_DSP1_PM_1_SHIFT 0 /* DSP1_PM_1 - [15:0] */
-#define WM5100_DSP1_PM_1_WIDTH 16 /* DSP1_PM_1 - [15:0] */
-
-/*
- * R19962 (0x4DFA) - DSP1 PM 1530
- */
-#define WM5100_DSP1_PM_510_2_MASK 0x00FF /* DSP1_PM_510 - [7:0] */
-#define WM5100_DSP1_PM_510_2_SHIFT 0 /* DSP1_PM_510 - [7:0] */
-#define WM5100_DSP1_PM_510_2_WIDTH 8 /* DSP1_PM_510 - [7:0] */
-
-/*
- * R19963 (0x4DFB) - DSP1 PM 1531
- */
-#define WM5100_DSP1_PM_510_1_MASK 0xFFFF /* DSP1_PM_510 - [15:0] */
-#define WM5100_DSP1_PM_510_1_SHIFT 0 /* DSP1_PM_510 - [15:0] */
-#define WM5100_DSP1_PM_510_1_WIDTH 16 /* DSP1_PM_510 - [15:0] */
-
-/*
- * R19964 (0x4DFC) - DSP1 PM 1532
- */
-#define WM5100_DSP1_PM_510_MASK 0xFFFF /* DSP1_PM_510 - [15:0] */
-#define WM5100_DSP1_PM_510_SHIFT 0 /* DSP1_PM_510 - [15:0] */
-#define WM5100_DSP1_PM_510_WIDTH 16 /* DSP1_PM_510 - [15:0] */
-
-/*
- * R19965 (0x4DFD) - DSP1 PM 1533
- */
-#define WM5100_DSP1_PM_END_2_MASK 0x00FF /* DSP1_PM_END - [7:0] */
-#define WM5100_DSP1_PM_END_2_SHIFT 0 /* DSP1_PM_END - [7:0] */
-#define WM5100_DSP1_PM_END_2_WIDTH 8 /* DSP1_PM_END - [7:0] */
-
-/*
- * R19966 (0x4DFE) - DSP1 PM 1534
- */
-#define WM5100_DSP1_PM_END_1_MASK 0xFFFF /* DSP1_PM_END - [15:0] */
-#define WM5100_DSP1_PM_END_1_SHIFT 0 /* DSP1_PM_END - [15:0] */
-#define WM5100_DSP1_PM_END_1_WIDTH 16 /* DSP1_PM_END - [15:0] */
-
-/*
- * R19967 (0x4DFF) - DSP1 PM 1535
- */
-#define WM5100_DSP1_PM_END_MASK 0xFFFF /* DSP1_PM_END - [15:0] */
-#define WM5100_DSP1_PM_END_SHIFT 0 /* DSP1_PM_END - [15:0] */
-#define WM5100_DSP1_PM_END_WIDTH 16 /* DSP1_PM_END - [15:0] */
-
-/*
- * R20480 (0x5000) - DSP1 ZM 0
- */
-#define WM5100_DSP1_ZM_START_1_MASK 0x00FF /* DSP1_ZM_START - [7:0] */
-#define WM5100_DSP1_ZM_START_1_SHIFT 0 /* DSP1_ZM_START - [7:0] */
-#define WM5100_DSP1_ZM_START_1_WIDTH 8 /* DSP1_ZM_START - [7:0] */
-
-/*
- * R20481 (0x5001) - DSP1 ZM 1
- */
-#define WM5100_DSP1_ZM_START_MASK 0xFFFF /* DSP1_ZM_START - [15:0] */
-#define WM5100_DSP1_ZM_START_SHIFT 0 /* DSP1_ZM_START - [15:0] */
-#define WM5100_DSP1_ZM_START_WIDTH 16 /* DSP1_ZM_START - [15:0] */
-
-/*
- * R20482 (0x5002) - DSP1 ZM 2
- */
-#define WM5100_DSP1_ZM_1_1_MASK 0x00FF /* DSP1_ZM_1 - [7:0] */
-#define WM5100_DSP1_ZM_1_1_SHIFT 0 /* DSP1_ZM_1 - [7:0] */
-#define WM5100_DSP1_ZM_1_1_WIDTH 8 /* DSP1_ZM_1 - [7:0] */
-
-/*
- * R20483 (0x5003) - DSP1 ZM 3
- */
-#define WM5100_DSP1_ZM_1_MASK 0xFFFF /* DSP1_ZM_1 - [15:0] */
-#define WM5100_DSP1_ZM_1_SHIFT 0 /* DSP1_ZM_1 - [15:0] */
-#define WM5100_DSP1_ZM_1_WIDTH 16 /* DSP1_ZM_1 - [15:0] */
-
-/*
- * R22524 (0x57FC) - DSP1 ZM 2044
- */
-#define WM5100_DSP1_ZM_1022_1_MASK 0x00FF /* DSP1_ZM_1022 - [7:0] */
-#define WM5100_DSP1_ZM_1022_1_SHIFT 0 /* DSP1_ZM_1022 - [7:0] */
-#define WM5100_DSP1_ZM_1022_1_WIDTH 8 /* DSP1_ZM_1022 - [7:0] */
-
-/*
- * R22525 (0x57FD) - DSP1 ZM 2045
- */
-#define WM5100_DSP1_ZM_1022_MASK 0xFFFF /* DSP1_ZM_1022 - [15:0] */
-#define WM5100_DSP1_ZM_1022_SHIFT 0 /* DSP1_ZM_1022 - [15:0] */
-#define WM5100_DSP1_ZM_1022_WIDTH 16 /* DSP1_ZM_1022 - [15:0] */
-
-/*
- * R22526 (0x57FE) - DSP1 ZM 2046
- */
-#define WM5100_DSP1_ZM_END_1_MASK 0x00FF /* DSP1_ZM_END - [7:0] */
-#define WM5100_DSP1_ZM_END_1_SHIFT 0 /* DSP1_ZM_END - [7:0] */
-#define WM5100_DSP1_ZM_END_1_WIDTH 8 /* DSP1_ZM_END - [7:0] */
-
-/*
- * R22527 (0x57FF) - DSP1 ZM 2047
- */
-#define WM5100_DSP1_ZM_END_MASK 0xFFFF /* DSP1_ZM_END - [15:0] */
-#define WM5100_DSP1_ZM_END_SHIFT 0 /* DSP1_ZM_END - [15:0] */
-#define WM5100_DSP1_ZM_END_WIDTH 16 /* DSP1_ZM_END - [15:0] */
-
-/*
- * R24576 (0x6000) - DSP2 DM 0
- */
-#define WM5100_DSP2_DM_START_1_MASK 0x00FF /* DSP2_DM_START - [7:0] */
-#define WM5100_DSP2_DM_START_1_SHIFT 0 /* DSP2_DM_START - [7:0] */
-#define WM5100_DSP2_DM_START_1_WIDTH 8 /* DSP2_DM_START - [7:0] */
-
-/*
- * R24577 (0x6001) - DSP2 DM 1
- */
-#define WM5100_DSP2_DM_START_MASK 0xFFFF /* DSP2_DM_START - [15:0] */
-#define WM5100_DSP2_DM_START_SHIFT 0 /* DSP2_DM_START - [15:0] */
-#define WM5100_DSP2_DM_START_WIDTH 16 /* DSP2_DM_START - [15:0] */
-
-/*
- * R24578 (0x6002) - DSP2 DM 2
- */
-#define WM5100_DSP2_DM_1_1_MASK 0x00FF /* DSP2_DM_1 - [7:0] */
-#define WM5100_DSP2_DM_1_1_SHIFT 0 /* DSP2_DM_1 - [7:0] */
-#define WM5100_DSP2_DM_1_1_WIDTH 8 /* DSP2_DM_1 - [7:0] */
-
-/*
- * R24579 (0x6003) - DSP2 DM 3
- */
-#define WM5100_DSP2_DM_1_MASK 0xFFFF /* DSP2_DM_1 - [15:0] */
-#define WM5100_DSP2_DM_1_SHIFT 0 /* DSP2_DM_1 - [15:0] */
-#define WM5100_DSP2_DM_1_WIDTH 16 /* DSP2_DM_1 - [15:0] */
-
-/*
- * R25084 (0x61FC) - DSP2 DM 508
- */
-#define WM5100_DSP2_DM_254_1_MASK 0x00FF /* DSP2_DM_254 - [7:0] */
-#define WM5100_DSP2_DM_254_1_SHIFT 0 /* DSP2_DM_254 - [7:0] */
-#define WM5100_DSP2_DM_254_1_WIDTH 8 /* DSP2_DM_254 - [7:0] */
-
-/*
- * R25085 (0x61FD) - DSP2 DM 509
- */
-#define WM5100_DSP2_DM_254_MASK 0xFFFF /* DSP2_DM_254 - [15:0] */
-#define WM5100_DSP2_DM_254_SHIFT 0 /* DSP2_DM_254 - [15:0] */
-#define WM5100_DSP2_DM_254_WIDTH 16 /* DSP2_DM_254 - [15:0] */
-
-/*
- * R25086 (0x61FE) - DSP2 DM 510
- */
-#define WM5100_DSP2_DM_END_1_MASK 0x00FF /* DSP2_DM_END - [7:0] */
-#define WM5100_DSP2_DM_END_1_SHIFT 0 /* DSP2_DM_END - [7:0] */
-#define WM5100_DSP2_DM_END_1_WIDTH 8 /* DSP2_DM_END - [7:0] */
-
-/*
- * R25087 (0x61FF) - DSP2 DM 511
- */
-#define WM5100_DSP2_DM_END_MASK 0xFFFF /* DSP2_DM_END - [15:0] */
-#define WM5100_DSP2_DM_END_SHIFT 0 /* DSP2_DM_END - [15:0] */
-#define WM5100_DSP2_DM_END_WIDTH 16 /* DSP2_DM_END - [15:0] */
-
-/*
- * R26624 (0x6800) - DSP2 PM 0
- */
-#define WM5100_DSP2_PM_START_2_MASK 0x00FF /* DSP2_PM_START - [7:0] */
-#define WM5100_DSP2_PM_START_2_SHIFT 0 /* DSP2_PM_START - [7:0] */
-#define WM5100_DSP2_PM_START_2_WIDTH 8 /* DSP2_PM_START - [7:0] */
-
-/*
- * R26625 (0x6801) - DSP2 PM 1
- */
-#define WM5100_DSP2_PM_START_1_MASK 0xFFFF /* DSP2_PM_START - [15:0] */
-#define WM5100_DSP2_PM_START_1_SHIFT 0 /* DSP2_PM_START - [15:0] */
-#define WM5100_DSP2_PM_START_1_WIDTH 16 /* DSP2_PM_START - [15:0] */
-
-/*
- * R26626 (0x6802) - DSP2 PM 2
- */
-#define WM5100_DSP2_PM_START_MASK 0xFFFF /* DSP2_PM_START - [15:0] */
-#define WM5100_DSP2_PM_START_SHIFT 0 /* DSP2_PM_START - [15:0] */
-#define WM5100_DSP2_PM_START_WIDTH 16 /* DSP2_PM_START - [15:0] */
-
-/*
- * R26627 (0x6803) - DSP2 PM 3
- */
-#define WM5100_DSP2_PM_1_2_MASK 0x00FF /* DSP2_PM_1 - [7:0] */
-#define WM5100_DSP2_PM_1_2_SHIFT 0 /* DSP2_PM_1 - [7:0] */
-#define WM5100_DSP2_PM_1_2_WIDTH 8 /* DSP2_PM_1 - [7:0] */
-
-/*
- * R26628 (0x6804) - DSP2 PM 4
- */
-#define WM5100_DSP2_PM_1_1_MASK 0xFFFF /* DSP2_PM_1 - [15:0] */
-#define WM5100_DSP2_PM_1_1_SHIFT 0 /* DSP2_PM_1 - [15:0] */
-#define WM5100_DSP2_PM_1_1_WIDTH 16 /* DSP2_PM_1 - [15:0] */
-
-/*
- * R26629 (0x6805) - DSP2 PM 5
- */
-#define WM5100_DSP2_PM_1_MASK 0xFFFF /* DSP2_PM_1 - [15:0] */
-#define WM5100_DSP2_PM_1_SHIFT 0 /* DSP2_PM_1 - [15:0] */
-#define WM5100_DSP2_PM_1_WIDTH 16 /* DSP2_PM_1 - [15:0] */
-
-/*
- * R28154 (0x6DFA) - DSP2 PM 1530
- */
-#define WM5100_DSP2_PM_510_2_MASK 0x00FF /* DSP2_PM_510 - [7:0] */
-#define WM5100_DSP2_PM_510_2_SHIFT 0 /* DSP2_PM_510 - [7:0] */
-#define WM5100_DSP2_PM_510_2_WIDTH 8 /* DSP2_PM_510 - [7:0] */
-
-/*
- * R28155 (0x6DFB) - DSP2 PM 1531
- */
-#define WM5100_DSP2_PM_510_1_MASK 0xFFFF /* DSP2_PM_510 - [15:0] */
-#define WM5100_DSP2_PM_510_1_SHIFT 0 /* DSP2_PM_510 - [15:0] */
-#define WM5100_DSP2_PM_510_1_WIDTH 16 /* DSP2_PM_510 - [15:0] */
-
-/*
- * R28156 (0x6DFC) - DSP2 PM 1532
- */
-#define WM5100_DSP2_PM_510_MASK 0xFFFF /* DSP2_PM_510 - [15:0] */
-#define WM5100_DSP2_PM_510_SHIFT 0 /* DSP2_PM_510 - [15:0] */
-#define WM5100_DSP2_PM_510_WIDTH 16 /* DSP2_PM_510 - [15:0] */
-
-/*
- * R28157 (0x6DFD) - DSP2 PM 1533
- */
-#define WM5100_DSP2_PM_END_2_MASK 0x00FF /* DSP2_PM_END - [7:0] */
-#define WM5100_DSP2_PM_END_2_SHIFT 0 /* DSP2_PM_END - [7:0] */
-#define WM5100_DSP2_PM_END_2_WIDTH 8 /* DSP2_PM_END - [7:0] */
-
-/*
- * R28158 (0x6DFE) - DSP2 PM 1534
- */
-#define WM5100_DSP2_PM_END_1_MASK 0xFFFF /* DSP2_PM_END - [15:0] */
-#define WM5100_DSP2_PM_END_1_SHIFT 0 /* DSP2_PM_END - [15:0] */
-#define WM5100_DSP2_PM_END_1_WIDTH 16 /* DSP2_PM_END - [15:0] */
-
-/*
- * R28159 (0x6DFF) - DSP2 PM 1535
- */
-#define WM5100_DSP2_PM_END_MASK 0xFFFF /* DSP2_PM_END - [15:0] */
-#define WM5100_DSP2_PM_END_SHIFT 0 /* DSP2_PM_END - [15:0] */
-#define WM5100_DSP2_PM_END_WIDTH 16 /* DSP2_PM_END - [15:0] */
-
-/*
- * R28672 (0x7000) - DSP2 ZM 0
- */
-#define WM5100_DSP2_ZM_START_1_MASK 0x00FF /* DSP2_ZM_START - [7:0] */
-#define WM5100_DSP2_ZM_START_1_SHIFT 0 /* DSP2_ZM_START - [7:0] */
-#define WM5100_DSP2_ZM_START_1_WIDTH 8 /* DSP2_ZM_START - [7:0] */
-
-/*
- * R28673 (0x7001) - DSP2 ZM 1
- */
-#define WM5100_DSP2_ZM_START_MASK 0xFFFF /* DSP2_ZM_START - [15:0] */
-#define WM5100_DSP2_ZM_START_SHIFT 0 /* DSP2_ZM_START - [15:0] */
-#define WM5100_DSP2_ZM_START_WIDTH 16 /* DSP2_ZM_START - [15:0] */
-
-/*
- * R28674 (0x7002) - DSP2 ZM 2
- */
-#define WM5100_DSP2_ZM_1_1_MASK 0x00FF /* DSP2_ZM_1 - [7:0] */
-#define WM5100_DSP2_ZM_1_1_SHIFT 0 /* DSP2_ZM_1 - [7:0] */
-#define WM5100_DSP2_ZM_1_1_WIDTH 8 /* DSP2_ZM_1 - [7:0] */
-
-/*
- * R28675 (0x7003) - DSP2 ZM 3
- */
-#define WM5100_DSP2_ZM_1_MASK 0xFFFF /* DSP2_ZM_1 - [15:0] */
-#define WM5100_DSP2_ZM_1_SHIFT 0 /* DSP2_ZM_1 - [15:0] */
-#define WM5100_DSP2_ZM_1_WIDTH 16 /* DSP2_ZM_1 - [15:0] */
-
-/*
- * R30716 (0x77FC) - DSP2 ZM 2044
- */
-#define WM5100_DSP2_ZM_1022_1_MASK 0x00FF /* DSP2_ZM_1022 - [7:0] */
-#define WM5100_DSP2_ZM_1022_1_SHIFT 0 /* DSP2_ZM_1022 - [7:0] */
-#define WM5100_DSP2_ZM_1022_1_WIDTH 8 /* DSP2_ZM_1022 - [7:0] */
-
-/*
- * R30717 (0x77FD) - DSP2 ZM 2045
- */
-#define WM5100_DSP2_ZM_1022_MASK 0xFFFF /* DSP2_ZM_1022 - [15:0] */
-#define WM5100_DSP2_ZM_1022_SHIFT 0 /* DSP2_ZM_1022 - [15:0] */
-#define WM5100_DSP2_ZM_1022_WIDTH 16 /* DSP2_ZM_1022 - [15:0] */
-
-/*
- * R30718 (0x77FE) - DSP2 ZM 2046
- */
-#define WM5100_DSP2_ZM_END_1_MASK 0x00FF /* DSP2_ZM_END - [7:0] */
-#define WM5100_DSP2_ZM_END_1_SHIFT 0 /* DSP2_ZM_END - [7:0] */
-#define WM5100_DSP2_ZM_END_1_WIDTH 8 /* DSP2_ZM_END - [7:0] */
-
-/*
- * R30719 (0x77FF) - DSP2 ZM 2047
- */
-#define WM5100_DSP2_ZM_END_MASK 0xFFFF /* DSP2_ZM_END - [15:0] */
-#define WM5100_DSP2_ZM_END_SHIFT 0 /* DSP2_ZM_END - [15:0] */
-#define WM5100_DSP2_ZM_END_WIDTH 16 /* DSP2_ZM_END - [15:0] */
-
-/*
- * R32768 (0x8000) - DSP3 DM 0
- */
-#define WM5100_DSP3_DM_START_1_MASK 0x00FF /* DSP3_DM_START - [7:0] */
-#define WM5100_DSP3_DM_START_1_SHIFT 0 /* DSP3_DM_START - [7:0] */
-#define WM5100_DSP3_DM_START_1_WIDTH 8 /* DSP3_DM_START - [7:0] */
-
-/*
- * R32769 (0x8001) - DSP3 DM 1
- */
-#define WM5100_DSP3_DM_START_MASK 0xFFFF /* DSP3_DM_START - [15:0] */
-#define WM5100_DSP3_DM_START_SHIFT 0 /* DSP3_DM_START - [15:0] */
-#define WM5100_DSP3_DM_START_WIDTH 16 /* DSP3_DM_START - [15:0] */
-
-/*
- * R32770 (0x8002) - DSP3 DM 2
- */
-#define WM5100_DSP3_DM_1_1_MASK 0x00FF /* DSP3_DM_1 - [7:0] */
-#define WM5100_DSP3_DM_1_1_SHIFT 0 /* DSP3_DM_1 - [7:0] */
-#define WM5100_DSP3_DM_1_1_WIDTH 8 /* DSP3_DM_1 - [7:0] */
-
-/*
- * R32771 (0x8003) - DSP3 DM 3
- */
-#define WM5100_DSP3_DM_1_MASK 0xFFFF /* DSP3_DM_1 - [15:0] */
-#define WM5100_DSP3_DM_1_SHIFT 0 /* DSP3_DM_1 - [15:0] */
-#define WM5100_DSP3_DM_1_WIDTH 16 /* DSP3_DM_1 - [15:0] */
-
-/*
- * R33276 (0x81FC) - DSP3 DM 508
- */
-#define WM5100_DSP3_DM_254_1_MASK 0x00FF /* DSP3_DM_254 - [7:0] */
-#define WM5100_DSP3_DM_254_1_SHIFT 0 /* DSP3_DM_254 - [7:0] */
-#define WM5100_DSP3_DM_254_1_WIDTH 8 /* DSP3_DM_254 - [7:0] */
-
-/*
- * R33277 (0x81FD) - DSP3 DM 509
- */
-#define WM5100_DSP3_DM_254_MASK 0xFFFF /* DSP3_DM_254 - [15:0] */
-#define WM5100_DSP3_DM_254_SHIFT 0 /* DSP3_DM_254 - [15:0] */
-#define WM5100_DSP3_DM_254_WIDTH 16 /* DSP3_DM_254 - [15:0] */
-
-/*
- * R33278 (0x81FE) - DSP3 DM 510
- */
-#define WM5100_DSP3_DM_END_1_MASK 0x00FF /* DSP3_DM_END - [7:0] */
-#define WM5100_DSP3_DM_END_1_SHIFT 0 /* DSP3_DM_END - [7:0] */
-#define WM5100_DSP3_DM_END_1_WIDTH 8 /* DSP3_DM_END - [7:0] */
-
-/*
- * R33279 (0x81FF) - DSP3 DM 511
- */
-#define WM5100_DSP3_DM_END_MASK 0xFFFF /* DSP3_DM_END - [15:0] */
-#define WM5100_DSP3_DM_END_SHIFT 0 /* DSP3_DM_END - [15:0] */
-#define WM5100_DSP3_DM_END_WIDTH 16 /* DSP3_DM_END - [15:0] */
-
-/*
- * R34816 (0x8800) - DSP3 PM 0
- */
-#define WM5100_DSP3_PM_START_2_MASK 0x00FF /* DSP3_PM_START - [7:0] */
-#define WM5100_DSP3_PM_START_2_SHIFT 0 /* DSP3_PM_START - [7:0] */
-#define WM5100_DSP3_PM_START_2_WIDTH 8 /* DSP3_PM_START - [7:0] */
-
-/*
- * R34817 (0x8801) - DSP3 PM 1
- */
-#define WM5100_DSP3_PM_START_1_MASK 0xFFFF /* DSP3_PM_START - [15:0] */
-#define WM5100_DSP3_PM_START_1_SHIFT 0 /* DSP3_PM_START - [15:0] */
-#define WM5100_DSP3_PM_START_1_WIDTH 16 /* DSP3_PM_START - [15:0] */
-
-/*
- * R34818 (0x8802) - DSP3 PM 2
- */
-#define WM5100_DSP3_PM_START_MASK 0xFFFF /* DSP3_PM_START - [15:0] */
-#define WM5100_DSP3_PM_START_SHIFT 0 /* DSP3_PM_START - [15:0] */
-#define WM5100_DSP3_PM_START_WIDTH 16 /* DSP3_PM_START - [15:0] */
-
-/*
- * R34819 (0x8803) - DSP3 PM 3
- */
-#define WM5100_DSP3_PM_1_2_MASK 0x00FF /* DSP3_PM_1 - [7:0] */
-#define WM5100_DSP3_PM_1_2_SHIFT 0 /* DSP3_PM_1 - [7:0] */
-#define WM5100_DSP3_PM_1_2_WIDTH 8 /* DSP3_PM_1 - [7:0] */
-
-/*
- * R34820 (0x8804) - DSP3 PM 4
- */
-#define WM5100_DSP3_PM_1_1_MASK 0xFFFF /* DSP3_PM_1 - [15:0] */
-#define WM5100_DSP3_PM_1_1_SHIFT 0 /* DSP3_PM_1 - [15:0] */
-#define WM5100_DSP3_PM_1_1_WIDTH 16 /* DSP3_PM_1 - [15:0] */
-
-/*
- * R34821 (0x8805) - DSP3 PM 5
- */
-#define WM5100_DSP3_PM_1_MASK 0xFFFF /* DSP3_PM_1 - [15:0] */
-#define WM5100_DSP3_PM_1_SHIFT 0 /* DSP3_PM_1 - [15:0] */
-#define WM5100_DSP3_PM_1_WIDTH 16 /* DSP3_PM_1 - [15:0] */
-
-/*
- * R36346 (0x8DFA) - DSP3 PM 1530
- */
-#define WM5100_DSP3_PM_510_2_MASK 0x00FF /* DSP3_PM_510 - [7:0] */
-#define WM5100_DSP3_PM_510_2_SHIFT 0 /* DSP3_PM_510 - [7:0] */
-#define WM5100_DSP3_PM_510_2_WIDTH 8 /* DSP3_PM_510 - [7:0] */
-
-/*
- * R36347 (0x8DFB) - DSP3 PM 1531
- */
-#define WM5100_DSP3_PM_510_1_MASK 0xFFFF /* DSP3_PM_510 - [15:0] */
-#define WM5100_DSP3_PM_510_1_SHIFT 0 /* DSP3_PM_510 - [15:0] */
-#define WM5100_DSP3_PM_510_1_WIDTH 16 /* DSP3_PM_510 - [15:0] */
-
-/*
- * R36348 (0x8DFC) - DSP3 PM 1532
- */
-#define WM5100_DSP3_PM_510_MASK 0xFFFF /* DSP3_PM_510 - [15:0] */
-#define WM5100_DSP3_PM_510_SHIFT 0 /* DSP3_PM_510 - [15:0] */
-#define WM5100_DSP3_PM_510_WIDTH 16 /* DSP3_PM_510 - [15:0] */
-
-/*
- * R36349 (0x8DFD) - DSP3 PM 1533
- */
-#define WM5100_DSP3_PM_END_2_MASK 0x00FF /* DSP3_PM_END - [7:0] */
-#define WM5100_DSP3_PM_END_2_SHIFT 0 /* DSP3_PM_END - [7:0] */
-#define WM5100_DSP3_PM_END_2_WIDTH 8 /* DSP3_PM_END - [7:0] */
-
-/*
- * R36350 (0x8DFE) - DSP3 PM 1534
- */
-#define WM5100_DSP3_PM_END_1_MASK 0xFFFF /* DSP3_PM_END - [15:0] */
-#define WM5100_DSP3_PM_END_1_SHIFT 0 /* DSP3_PM_END - [15:0] */
-#define WM5100_DSP3_PM_END_1_WIDTH 16 /* DSP3_PM_END - [15:0] */
-
-/*
- * R36351 (0x8DFF) - DSP3 PM 1535
- */
-#define WM5100_DSP3_PM_END_MASK 0xFFFF /* DSP3_PM_END - [15:0] */
-#define WM5100_DSP3_PM_END_SHIFT 0 /* DSP3_PM_END - [15:0] */
-#define WM5100_DSP3_PM_END_WIDTH 16 /* DSP3_PM_END - [15:0] */
-
-/*
- * R36864 (0x9000) - DSP3 ZM 0
- */
-#define WM5100_DSP3_ZM_START_1_MASK 0x00FF /* DSP3_ZM_START - [7:0] */
-#define WM5100_DSP3_ZM_START_1_SHIFT 0 /* DSP3_ZM_START - [7:0] */
-#define WM5100_DSP3_ZM_START_1_WIDTH 8 /* DSP3_ZM_START - [7:0] */
-
-/*
- * R36865 (0x9001) - DSP3 ZM 1
- */
-#define WM5100_DSP3_ZM_START_MASK 0xFFFF /* DSP3_ZM_START - [15:0] */
-#define WM5100_DSP3_ZM_START_SHIFT 0 /* DSP3_ZM_START - [15:0] */
-#define WM5100_DSP3_ZM_START_WIDTH 16 /* DSP3_ZM_START - [15:0] */
-
-/*
- * R36866 (0x9002) - DSP3 ZM 2
- */
-#define WM5100_DSP3_ZM_1_1_MASK 0x00FF /* DSP3_ZM_1 - [7:0] */
-#define WM5100_DSP3_ZM_1_1_SHIFT 0 /* DSP3_ZM_1 - [7:0] */
-#define WM5100_DSP3_ZM_1_1_WIDTH 8 /* DSP3_ZM_1 - [7:0] */
-
-/*
- * R36867 (0x9003) - DSP3 ZM 3
- */
-#define WM5100_DSP3_ZM_1_MASK 0xFFFF /* DSP3_ZM_1 - [15:0] */
-#define WM5100_DSP3_ZM_1_SHIFT 0 /* DSP3_ZM_1 - [15:0] */
-#define WM5100_DSP3_ZM_1_WIDTH 16 /* DSP3_ZM_1 - [15:0] */
-
-/*
- * R38908 (0x97FC) - DSP3 ZM 2044
- */
-#define WM5100_DSP3_ZM_1022_1_MASK 0x00FF /* DSP3_ZM_1022 - [7:0] */
-#define WM5100_DSP3_ZM_1022_1_SHIFT 0 /* DSP3_ZM_1022 - [7:0] */
-#define WM5100_DSP3_ZM_1022_1_WIDTH 8 /* DSP3_ZM_1022 - [7:0] */
-
-/*
- * R38909 (0x97FD) - DSP3 ZM 2045
- */
-#define WM5100_DSP3_ZM_1022_MASK 0xFFFF /* DSP3_ZM_1022 - [15:0] */
-#define WM5100_DSP3_ZM_1022_SHIFT 0 /* DSP3_ZM_1022 - [15:0] */
-#define WM5100_DSP3_ZM_1022_WIDTH 16 /* DSP3_ZM_1022 - [15:0] */
-
-/*
- * R38910 (0x97FE) - DSP3 ZM 2046
- */
-#define WM5100_DSP3_ZM_END_1_MASK 0x00FF /* DSP3_ZM_END - [7:0] */
-#define WM5100_DSP3_ZM_END_1_SHIFT 0 /* DSP3_ZM_END - [7:0] */
-#define WM5100_DSP3_ZM_END_1_WIDTH 8 /* DSP3_ZM_END - [7:0] */
-
-/*
- * R38911 (0x97FF) - DSP3 ZM 2047
- */
-#define WM5100_DSP3_ZM_END_MASK 0xFFFF /* DSP3_ZM_END - [15:0] */
-#define WM5100_DSP3_ZM_END_SHIFT 0 /* DSP3_ZM_END - [15:0] */
-#define WM5100_DSP3_ZM_END_WIDTH 16 /* DSP3_ZM_END - [15:0] */
-
-bool wm5100_readable_register(struct device *dev, unsigned int reg);
-bool wm5100_volatile_register(struct device *dev, unsigned int reg);
-
-extern struct reg_default wm5100_reg_defaults[WM5100_REGISTER_COUNT];
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8350.c b/ANDROID_3.4.5/sound/soc/codecs/wm8350.c
deleted file mode 100644
index aa12c6b6..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8350.c
+++ /dev/null
@@ -1,1697 +0,0 @@
-/*
- * wm8350.c -- WM8350 ALSA SoC audio driver
- *
- * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
- *
- * Author: Liam Girdwood <lrg@slimlogic.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/platform_device.h>
-#include <linux/mfd/wm8350/audio.h>
-#include <linux/mfd/wm8350/core.h>
-#include <linux/regulator/consumer.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <trace/events/asoc.h>
-
-#include "wm8350.h"
-
-#define WM8350_OUTn_0dB 0x39
-
-#define WM8350_RAMP_NONE 0
-#define WM8350_RAMP_UP 1
-#define WM8350_RAMP_DOWN 2
-
-/* We only include the analogue supplies here; the digital supplies
- * need to be available well before this driver can be probed.
- */
-static const char *supply_names[] = {
- "AVDD",
- "HPVDD",
-};
-
-struct wm8350_output {
- u16 active;
- u16 left_vol;
- u16 right_vol;
- u16 ramp;
- u16 mute;
-};
-
-struct wm8350_jack_data {
- struct snd_soc_jack *jack;
- struct delayed_work work;
- int report;
- int short_report;
-};
-
-struct wm8350_data {
- struct wm8350 *wm8350;
- struct wm8350_output out1;
- struct wm8350_output out2;
- struct wm8350_jack_data hpl;
- struct wm8350_jack_data hpr;
- struct wm8350_jack_data mic;
- struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
- int fll_freq_out;
- int fll_freq_in;
-};
-
-static unsigned int wm8350_codec_cache_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- struct wm8350 *wm8350 = codec->control_data;
- return wm8350->reg_cache[reg];
-}
-
-static unsigned int wm8350_codec_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- struct wm8350 *wm8350 = codec->control_data;
- return wm8350_reg_read(wm8350, reg);
-}
-
-static int wm8350_codec_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- struct wm8350 *wm8350 = codec->control_data;
- return wm8350_reg_write(wm8350, reg, value);
-}
-
-/*
- * Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown.
- */
-static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec)
-{
- struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
- struct wm8350_output *out1 = &wm8350_data->out1;
- struct wm8350 *wm8350 = codec->control_data;
- int left_complete = 0, right_complete = 0;
- u16 reg, val;
-
- /* left channel */
- reg = wm8350_reg_read(wm8350, WM8350_LOUT1_VOLUME);
- val = (reg & WM8350_OUT1L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
-
- if (out1->ramp == WM8350_RAMP_UP) {
- /* ramp step up */
- if (val < out1->left_vol) {
- val++;
- reg &= ~WM8350_OUT1L_VOL_MASK;
- wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME,
- reg | (val << WM8350_OUT1L_VOL_SHIFT));
- } else
- left_complete = 1;
- } else if (out1->ramp == WM8350_RAMP_DOWN) {
- /* ramp step down */
- if (val > 0) {
- val--;
- reg &= ~WM8350_OUT1L_VOL_MASK;
- wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME,
- reg | (val << WM8350_OUT1L_VOL_SHIFT));
- } else
- left_complete = 1;
- } else
- return 1;
-
- /* right channel */
- reg = wm8350_reg_read(wm8350, WM8350_ROUT1_VOLUME);
- val = (reg & WM8350_OUT1R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
- if (out1->ramp == WM8350_RAMP_UP) {
- /* ramp step up */
- if (val < out1->right_vol) {
- val++;
- reg &= ~WM8350_OUT1R_VOL_MASK;
- wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME,
- reg | (val << WM8350_OUT1R_VOL_SHIFT));
- } else
- right_complete = 1;
- } else if (out1->ramp == WM8350_RAMP_DOWN) {
- /* ramp step down */
- if (val > 0) {
- val--;
- reg &= ~WM8350_OUT1R_VOL_MASK;
- wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME,
- reg | (val << WM8350_OUT1R_VOL_SHIFT));
- } else
- right_complete = 1;
- }
-
- /* only hit the update bit if either volume has changed this step */
- if (!left_complete || !right_complete)
- wm8350_set_bits(wm8350, WM8350_LOUT1_VOLUME, WM8350_OUT1_VU);
-
- return left_complete & right_complete;
-}
-
-/*
- * Ramp OUT2 PGA volume to minimise pops at stream startup and shutdown.
- */
-static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec)
-{
- struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
- struct wm8350_output *out2 = &wm8350_data->out2;
- struct wm8350 *wm8350 = codec->control_data;
- int left_complete = 0, right_complete = 0;
- u16 reg, val;
-
- /* left channel */
- reg = wm8350_reg_read(wm8350, WM8350_LOUT2_VOLUME);
- val = (reg & WM8350_OUT2L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
- if (out2->ramp == WM8350_RAMP_UP) {
- /* ramp step up */
- if (val < out2->left_vol) {
- val++;
- reg &= ~WM8350_OUT2L_VOL_MASK;
- wm8350_reg_write(wm8350, WM8350_LOUT2_VOLUME,
- reg | (val << WM8350_OUT1L_VOL_SHIFT));
- } else
- left_complete = 1;
- } else if (out2->ramp == WM8350_RAMP_DOWN) {
- /* ramp step down */
- if (val > 0) {
- val--;
- reg &= ~WM8350_OUT2L_VOL_MASK;
- wm8350_reg_write(wm8350, WM8350_LOUT2_VOLUME,
- reg | (val << WM8350_OUT1L_VOL_SHIFT));
- } else
- left_complete = 1;
- } else
- return 1;
-
- /* right channel */
- reg = wm8350_reg_read(wm8350, WM8350_ROUT2_VOLUME);
- val = (reg & WM8350_OUT2R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
- if (out2->ramp == WM8350_RAMP_UP) {
- /* ramp step up */
- if (val < out2->right_vol) {
- val++;
- reg &= ~WM8350_OUT2R_VOL_MASK;
- wm8350_reg_write(wm8350, WM8350_ROUT2_VOLUME,
- reg | (val << WM8350_OUT1R_VOL_SHIFT));
- } else
- right_complete = 1;
- } else if (out2->ramp == WM8350_RAMP_DOWN) {
- /* ramp step down */
- if (val > 0) {
- val--;
- reg &= ~WM8350_OUT2R_VOL_MASK;
- wm8350_reg_write(wm8350, WM8350_ROUT2_VOLUME,
- reg | (val << WM8350_OUT1R_VOL_SHIFT));
- } else
- right_complete = 1;
- }
-
- /* only hit the update bit if either volume has changed this step */
- if (!left_complete || !right_complete)
- wm8350_set_bits(wm8350, WM8350_LOUT2_VOLUME, WM8350_OUT2_VU);
-
- return left_complete & right_complete;
-}
-
-/*
- * This work ramps both output PGAs at stream start/stop time to
- * minimise pop associated with DAPM power switching.
- * It's best to enable Zero Cross when ramping occurs to minimise any
- * zipper noises.
- */
-static void wm8350_pga_work(struct work_struct *work)
-{
- struct snd_soc_dapm_context *dapm =
- container_of(work, struct snd_soc_dapm_context, delayed_work.work);
- struct snd_soc_codec *codec = dapm->codec;
- struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
- struct wm8350_output *out1 = &wm8350_data->out1,
- *out2 = &wm8350_data->out2;
- int i, out1_complete, out2_complete;
-
- /* do we need to ramp at all ? */
- if (out1->ramp == WM8350_RAMP_NONE && out2->ramp == WM8350_RAMP_NONE)
- return;
-
- /* PGA volumes have 6 bits of resolution to ramp */
- for (i = 0; i <= 63; i++) {
- out1_complete = 1, out2_complete = 1;
- if (out1->ramp != WM8350_RAMP_NONE)
- out1_complete = wm8350_out1_ramp_step(codec);
- if (out2->ramp != WM8350_RAMP_NONE)
- out2_complete = wm8350_out2_ramp_step(codec);
-
- /* ramp finished ? */
- if (out1_complete && out2_complete)
- break;
-
- /* we need to delay longer on the up ramp */
- if (out1->ramp == WM8350_RAMP_UP ||
- out2->ramp == WM8350_RAMP_UP) {
- /* delay is longer over 0dB as increases are larger */
- if (i >= WM8350_OUTn_0dB)
- schedule_timeout_interruptible(msecs_to_jiffies
- (2));
- else
- schedule_timeout_interruptible(msecs_to_jiffies
- (1));
- } else
- udelay(50); /* doesn't matter if we delay longer */
- }
-
- out1->ramp = WM8350_RAMP_NONE;
- out2->ramp = WM8350_RAMP_NONE;
-}
-
-/*
- * WM8350 Controls
- */
-
-static int pga_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
- struct wm8350_output *out;
-
- switch (w->shift) {
- case 0:
- case 1:
- out = &wm8350_data->out1;
- break;
- case 2:
- case 3:
- out = &wm8350_data->out2;
- break;
-
- default:
- BUG();
- return -1;
- }
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- out->ramp = WM8350_RAMP_UP;
- out->active = 1;
-
- if (!delayed_work_pending(&codec->dapm.delayed_work))
- schedule_delayed_work(&codec->dapm.delayed_work,
- msecs_to_jiffies(1));
- break;
-
- case SND_SOC_DAPM_PRE_PMD:
- out->ramp = WM8350_RAMP_DOWN;
- out->active = 0;
-
- if (!delayed_work_pending(&codec->dapm.delayed_work))
- schedule_delayed_work(&codec->dapm.delayed_work,
- msecs_to_jiffies(1));
- break;
- }
-
- return 0;
-}
-
-static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec);
- struct wm8350_output *out = NULL;
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- int ret;
- unsigned int reg = mc->reg;
- u16 val;
-
- /* For OUT1 and OUT2 we shadow the values and only actually write
- * them out when active in order to ensure the amplifier comes on
- * as quietly as possible. */
- switch (reg) {
- case WM8350_LOUT1_VOLUME:
- out = &wm8350_priv->out1;
- break;
- case WM8350_LOUT2_VOLUME:
- out = &wm8350_priv->out2;
- break;
- default:
- break;
- }
-
- if (out) {
- out->left_vol = ucontrol->value.integer.value[0];
- out->right_vol = ucontrol->value.integer.value[1];
- if (!out->active)
- return 1;
- }
-
- ret = snd_soc_put_volsw(kcontrol, ucontrol);
- if (ret < 0)
- return ret;
-
- /* now hit the volume update bits (always bit 8) */
- val = wm8350_codec_read(codec, reg);
- wm8350_codec_write(codec, reg, val | WM8350_OUT1_VU);
- return 1;
-}
-
-static int wm8350_get_volsw_2r(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec);
- struct wm8350_output *out1 = &wm8350_priv->out1;
- struct wm8350_output *out2 = &wm8350_priv->out2;
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- unsigned int reg = mc->reg;
-
- /* If these are cached registers use the cache */
- switch (reg) {
- case WM8350_LOUT1_VOLUME:
- ucontrol->value.integer.value[0] = out1->left_vol;
- ucontrol->value.integer.value[1] = out1->right_vol;
- return 0;
-
- case WM8350_LOUT2_VOLUME:
- ucontrol->value.integer.value[0] = out2->left_vol;
- ucontrol->value.integer.value[1] = out2->right_vol;
- return 0;
-
- default:
- break;
- }
-
- return snd_soc_get_volsw(kcontrol, ucontrol);
-}
-
-static const char *wm8350_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
-static const char *wm8350_pol[] = { "Normal", "Inv R", "Inv L", "Inv L & R" };
-static const char *wm8350_dacmutem[] = { "Normal", "Soft" };
-static const char *wm8350_dacmutes[] = { "Fast", "Slow" };
-static const char *wm8350_adcfilter[] = { "None", "High Pass" };
-static const char *wm8350_adchp[] = { "44.1kHz", "8kHz", "16kHz", "32kHz" };
-static const char *wm8350_lr[] = { "Left", "Right" };
-
-static const struct soc_enum wm8350_enum[] = {
- SOC_ENUM_SINGLE(WM8350_DAC_CONTROL, 4, 4, wm8350_deemp),
- SOC_ENUM_SINGLE(WM8350_DAC_CONTROL, 0, 4, wm8350_pol),
- SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 14, 2, wm8350_dacmutem),
- SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 13, 2, wm8350_dacmutes),
- SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 15, 2, wm8350_adcfilter),
- SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 8, 4, wm8350_adchp),
- SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 0, 4, wm8350_pol),
- SOC_ENUM_SINGLE(WM8350_INPUT_MIXER_VOLUME, 15, 2, wm8350_lr),
-};
-
-static DECLARE_TLV_DB_SCALE(pre_amp_tlv, -1200, 3525, 0);
-static DECLARE_TLV_DB_SCALE(out_pga_tlv, -5700, 600, 0);
-static DECLARE_TLV_DB_SCALE(dac_pcm_tlv, -7163, 36, 1);
-static DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -12700, 50, 1);
-static DECLARE_TLV_DB_SCALE(out_mix_tlv, -1500, 300, 1);
-
-static const unsigned int capture_sd_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 12, TLV_DB_SCALE_ITEM(-3600, 300, 1),
- 13, 15, TLV_DB_SCALE_ITEM(0, 0, 0),
-};
-
-static const struct snd_kcontrol_new wm8350_snd_controls[] = {
- SOC_ENUM("Playback Deemphasis", wm8350_enum[0]),
- SOC_ENUM("Playback DAC Inversion", wm8350_enum[1]),
- SOC_DOUBLE_R_EXT_TLV("Playback PCM Volume",
- WM8350_DAC_DIGITAL_VOLUME_L,
- WM8350_DAC_DIGITAL_VOLUME_R,
- 0, 255, 0, wm8350_get_volsw_2r,
- wm8350_put_volsw_2r_vu, dac_pcm_tlv),
- SOC_ENUM("Playback PCM Mute Function", wm8350_enum[2]),
- SOC_ENUM("Playback PCM Mute Speed", wm8350_enum[3]),
- SOC_ENUM("Capture PCM Filter", wm8350_enum[4]),
- SOC_ENUM("Capture PCM HP Filter", wm8350_enum[5]),
- SOC_ENUM("Capture ADC Inversion", wm8350_enum[6]),
- SOC_DOUBLE_R_EXT_TLV("Capture PCM Volume",
- WM8350_ADC_DIGITAL_VOLUME_L,
- WM8350_ADC_DIGITAL_VOLUME_R,
- 0, 255, 0, wm8350_get_volsw_2r,
- wm8350_put_volsw_2r_vu, adc_pcm_tlv),
- SOC_DOUBLE_TLV("Capture Sidetone Volume",
- WM8350_ADC_DIVIDER,
- 8, 4, 15, 1, capture_sd_tlv),
- SOC_DOUBLE_R_EXT_TLV("Capture Volume",
- WM8350_LEFT_INPUT_VOLUME,
- WM8350_RIGHT_INPUT_VOLUME,
- 2, 63, 0, wm8350_get_volsw_2r,
- wm8350_put_volsw_2r_vu, pre_amp_tlv),
- SOC_DOUBLE_R("Capture ZC Switch",
- WM8350_LEFT_INPUT_VOLUME,
- WM8350_RIGHT_INPUT_VOLUME, 13, 1, 0),
- SOC_SINGLE_TLV("Left Input Left Sidetone Volume",
- WM8350_OUTPUT_LEFT_MIXER_VOLUME, 1, 7, 0, out_mix_tlv),
- SOC_SINGLE_TLV("Left Input Right Sidetone Volume",
- WM8350_OUTPUT_LEFT_MIXER_VOLUME,
- 5, 7, 0, out_mix_tlv),
- SOC_SINGLE_TLV("Left Input Bypass Volume",
- WM8350_OUTPUT_LEFT_MIXER_VOLUME,
- 9, 7, 0, out_mix_tlv),
- SOC_SINGLE_TLV("Right Input Left Sidetone Volume",
- WM8350_OUTPUT_RIGHT_MIXER_VOLUME,
- 1, 7, 0, out_mix_tlv),
- SOC_SINGLE_TLV("Right Input Right Sidetone Volume",
- WM8350_OUTPUT_RIGHT_MIXER_VOLUME,
- 5, 7, 0, out_mix_tlv),
- SOC_SINGLE_TLV("Right Input Bypass Volume",
- WM8350_OUTPUT_RIGHT_MIXER_VOLUME,
- 13, 7, 0, out_mix_tlv),
- SOC_SINGLE("Left Input Mixer +20dB Switch",
- WM8350_INPUT_MIXER_VOLUME_L, 0, 1, 0),
- SOC_SINGLE("Right Input Mixer +20dB Switch",
- WM8350_INPUT_MIXER_VOLUME_R, 0, 1, 0),
- SOC_SINGLE_TLV("Out4 Capture Volume",
- WM8350_INPUT_MIXER_VOLUME,
- 1, 7, 0, out_mix_tlv),
- SOC_DOUBLE_R_EXT_TLV("Out1 Playback Volume",
- WM8350_LOUT1_VOLUME,
- WM8350_ROUT1_VOLUME,
- 2, 63, 0, wm8350_get_volsw_2r,
- wm8350_put_volsw_2r_vu, out_pga_tlv),
- SOC_DOUBLE_R("Out1 Playback ZC Switch",
- WM8350_LOUT1_VOLUME,
- WM8350_ROUT1_VOLUME, 13, 1, 0),
- SOC_DOUBLE_R_EXT_TLV("Out2 Playback Volume",
- WM8350_LOUT2_VOLUME,
- WM8350_ROUT2_VOLUME,
- 2, 63, 0, wm8350_get_volsw_2r,
- wm8350_put_volsw_2r_vu, out_pga_tlv),
- SOC_DOUBLE_R("Out2 Playback ZC Switch", WM8350_LOUT2_VOLUME,
- WM8350_ROUT2_VOLUME, 13, 1, 0),
- SOC_SINGLE("Out2 Right Invert Switch", WM8350_ROUT2_VOLUME, 10, 1, 0),
- SOC_SINGLE_TLV("Out2 Beep Volume", WM8350_BEEP_VOLUME,
- 5, 7, 0, out_mix_tlv),
-
- SOC_DOUBLE_R("Out1 Playback Switch",
- WM8350_LOUT1_VOLUME,
- WM8350_ROUT1_VOLUME,
- 14, 1, 1),
- SOC_DOUBLE_R("Out2 Playback Switch",
- WM8350_LOUT2_VOLUME,
- WM8350_ROUT2_VOLUME,
- 14, 1, 1),
-};
-
-/*
- * DAPM Controls
- */
-
-/* Left Playback Mixer */
-static const struct snd_kcontrol_new wm8350_left_play_mixer_controls[] = {
- SOC_DAPM_SINGLE("Playback Switch",
- WM8350_LEFT_MIXER_CONTROL, 11, 1, 0),
- SOC_DAPM_SINGLE("Left Bypass Switch",
- WM8350_LEFT_MIXER_CONTROL, 2, 1, 0),
- SOC_DAPM_SINGLE("Right Playback Switch",
- WM8350_LEFT_MIXER_CONTROL, 12, 1, 0),
- SOC_DAPM_SINGLE("Left Sidetone Switch",
- WM8350_LEFT_MIXER_CONTROL, 0, 1, 0),
- SOC_DAPM_SINGLE("Right Sidetone Switch",
- WM8350_LEFT_MIXER_CONTROL, 1, 1, 0),
-};
-
-/* Right Playback Mixer */
-static const struct snd_kcontrol_new wm8350_right_play_mixer_controls[] = {
- SOC_DAPM_SINGLE("Playback Switch",
- WM8350_RIGHT_MIXER_CONTROL, 12, 1, 0),
- SOC_DAPM_SINGLE("Right Bypass Switch",
- WM8350_RIGHT_MIXER_CONTROL, 3, 1, 0),
- SOC_DAPM_SINGLE("Left Playback Switch",
- WM8350_RIGHT_MIXER_CONTROL, 11, 1, 0),
- SOC_DAPM_SINGLE("Left Sidetone Switch",
- WM8350_RIGHT_MIXER_CONTROL, 0, 1, 0),
- SOC_DAPM_SINGLE("Right Sidetone Switch",
- WM8350_RIGHT_MIXER_CONTROL, 1, 1, 0),
-};
-
-/* Out4 Mixer */
-static const struct snd_kcontrol_new wm8350_out4_mixer_controls[] = {
- SOC_DAPM_SINGLE("Right Playback Switch",
- WM8350_OUT4_MIXER_CONTROL, 12, 1, 0),
- SOC_DAPM_SINGLE("Left Playback Switch",
- WM8350_OUT4_MIXER_CONTROL, 11, 1, 0),
- SOC_DAPM_SINGLE("Right Capture Switch",
- WM8350_OUT4_MIXER_CONTROL, 9, 1, 0),
- SOC_DAPM_SINGLE("Out3 Playback Switch",
- WM8350_OUT4_MIXER_CONTROL, 2, 1, 0),
- SOC_DAPM_SINGLE("Right Mixer Switch",
- WM8350_OUT4_MIXER_CONTROL, 1, 1, 0),
- SOC_DAPM_SINGLE("Left Mixer Switch",
- WM8350_OUT4_MIXER_CONTROL, 0, 1, 0),
-};
-
-/* Out3 Mixer */
-static const struct snd_kcontrol_new wm8350_out3_mixer_controls[] = {
- SOC_DAPM_SINGLE("Left Playback Switch",
- WM8350_OUT3_MIXER_CONTROL, 11, 1, 0),
- SOC_DAPM_SINGLE("Left Capture Switch",
- WM8350_OUT3_MIXER_CONTROL, 8, 1, 0),
- SOC_DAPM_SINGLE("Out4 Playback Switch",
- WM8350_OUT3_MIXER_CONTROL, 3, 1, 0),
- SOC_DAPM_SINGLE("Left Mixer Switch",
- WM8350_OUT3_MIXER_CONTROL, 0, 1, 0),
-};
-
-/* Left Input Mixer */
-static const struct snd_kcontrol_new wm8350_left_capt_mixer_controls[] = {
- SOC_DAPM_SINGLE_TLV("L2 Capture Volume",
- WM8350_INPUT_MIXER_VOLUME_L, 1, 7, 0, out_mix_tlv),
- SOC_DAPM_SINGLE_TLV("L3 Capture Volume",
- WM8350_INPUT_MIXER_VOLUME_L, 9, 7, 0, out_mix_tlv),
- SOC_DAPM_SINGLE("PGA Capture Switch",
- WM8350_LEFT_INPUT_VOLUME, 14, 1, 1),
-};
-
-/* Right Input Mixer */
-static const struct snd_kcontrol_new wm8350_right_capt_mixer_controls[] = {
- SOC_DAPM_SINGLE_TLV("L2 Capture Volume",
- WM8350_INPUT_MIXER_VOLUME_R, 5, 7, 0, out_mix_tlv),
- SOC_DAPM_SINGLE_TLV("L3 Capture Volume",
- WM8350_INPUT_MIXER_VOLUME_R, 13, 7, 0, out_mix_tlv),
- SOC_DAPM_SINGLE("PGA Capture Switch",
- WM8350_RIGHT_INPUT_VOLUME, 14, 1, 1),
-};
-
-/* Left Mic Mixer */
-static const struct snd_kcontrol_new wm8350_left_mic_mixer_controls[] = {
- SOC_DAPM_SINGLE("INN Capture Switch", WM8350_INPUT_CONTROL, 1, 1, 0),
- SOC_DAPM_SINGLE("INP Capture Switch", WM8350_INPUT_CONTROL, 0, 1, 0),
- SOC_DAPM_SINGLE("IN2 Capture Switch", WM8350_INPUT_CONTROL, 2, 1, 0),
-};
-
-/* Right Mic Mixer */
-static const struct snd_kcontrol_new wm8350_right_mic_mixer_controls[] = {
- SOC_DAPM_SINGLE("INN Capture Switch", WM8350_INPUT_CONTROL, 9, 1, 0),
- SOC_DAPM_SINGLE("INP Capture Switch", WM8350_INPUT_CONTROL, 8, 1, 0),
- SOC_DAPM_SINGLE("IN2 Capture Switch", WM8350_INPUT_CONTROL, 10, 1, 0),
-};
-
-/* Beep Switch */
-static const struct snd_kcontrol_new wm8350_beep_switch_controls =
-SOC_DAPM_SINGLE("Switch", WM8350_BEEP_VOLUME, 15, 1, 1);
-
-/* Out4 Capture Mux */
-static const struct snd_kcontrol_new wm8350_out4_capture_controls =
-SOC_DAPM_ENUM("Route", wm8350_enum[7]);
-
-static const struct snd_soc_dapm_widget wm8350_dapm_widgets[] = {
-
- SND_SOC_DAPM_PGA("IN3R PGA", WM8350_POWER_MGMT_2, 11, 0, NULL, 0),
- SND_SOC_DAPM_PGA("IN3L PGA", WM8350_POWER_MGMT_2, 10, 0, NULL, 0),
- SND_SOC_DAPM_PGA_E("Right Out2 PGA", WM8350_POWER_MGMT_3, 3, 0, NULL,
- 0, pga_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
- SND_SOC_DAPM_PGA_E("Left Out2 PGA", WM8350_POWER_MGMT_3, 2, 0, NULL, 0,
- pga_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
- SND_SOC_DAPM_PGA_E("Right Out1 PGA", WM8350_POWER_MGMT_3, 1, 0, NULL,
- 0, pga_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
- SND_SOC_DAPM_PGA_E("Left Out1 PGA", WM8350_POWER_MGMT_3, 0, 0, NULL, 0,
- pga_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-
- SND_SOC_DAPM_MIXER("Right Capture Mixer", WM8350_POWER_MGMT_2,
- 7, 0, &wm8350_right_capt_mixer_controls[0],
- ARRAY_SIZE(wm8350_right_capt_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Left Capture Mixer", WM8350_POWER_MGMT_2,
- 6, 0, &wm8350_left_capt_mixer_controls[0],
- ARRAY_SIZE(wm8350_left_capt_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Out4 Mixer", WM8350_POWER_MGMT_2, 5, 0,
- &wm8350_out4_mixer_controls[0],
- ARRAY_SIZE(wm8350_out4_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Out3 Mixer", WM8350_POWER_MGMT_2, 4, 0,
- &wm8350_out3_mixer_controls[0],
- ARRAY_SIZE(wm8350_out3_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Right Playback Mixer", WM8350_POWER_MGMT_2, 1, 0,
- &wm8350_right_play_mixer_controls[0],
- ARRAY_SIZE(wm8350_right_play_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Left Playback Mixer", WM8350_POWER_MGMT_2, 0, 0,
- &wm8350_left_play_mixer_controls[0],
- ARRAY_SIZE(wm8350_left_play_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Left Mic Mixer", WM8350_POWER_MGMT_2, 8, 0,
- &wm8350_left_mic_mixer_controls[0],
- ARRAY_SIZE(wm8350_left_mic_mixer_controls)),
-
- SND_SOC_DAPM_MIXER("Right Mic Mixer", WM8350_POWER_MGMT_2, 9, 0,
- &wm8350_right_mic_mixer_controls[0],
- ARRAY_SIZE(wm8350_right_mic_mixer_controls)),
-
- /* virtual mixer for Beep and Out2R */
- SND_SOC_DAPM_MIXER("Out2 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-
- SND_SOC_DAPM_SWITCH("Beep", WM8350_POWER_MGMT_3, 7, 0,
- &wm8350_beep_switch_controls),
-
- SND_SOC_DAPM_ADC("Right ADC", "Right Capture",
- WM8350_POWER_MGMT_4, 3, 0),
- SND_SOC_DAPM_ADC("Left ADC", "Left Capture",
- WM8350_POWER_MGMT_4, 2, 0),
- SND_SOC_DAPM_DAC("Right DAC", "Right Playback",
- WM8350_POWER_MGMT_4, 5, 0),
- SND_SOC_DAPM_DAC("Left DAC", "Left Playback",
- WM8350_POWER_MGMT_4, 4, 0),
-
- SND_SOC_DAPM_MICBIAS("Mic Bias", WM8350_POWER_MGMT_1, 4, 0),
-
- SND_SOC_DAPM_MUX("Out4 Capture Channel", SND_SOC_NOPM, 0, 0,
- &wm8350_out4_capture_controls),
-
- SND_SOC_DAPM_OUTPUT("OUT1R"),
- SND_SOC_DAPM_OUTPUT("OUT1L"),
- SND_SOC_DAPM_OUTPUT("OUT2R"),
- SND_SOC_DAPM_OUTPUT("OUT2L"),
- SND_SOC_DAPM_OUTPUT("OUT3"),
- SND_SOC_DAPM_OUTPUT("OUT4"),
-
- SND_SOC_DAPM_INPUT("IN1RN"),
- SND_SOC_DAPM_INPUT("IN1RP"),
- SND_SOC_DAPM_INPUT("IN2R"),
- SND_SOC_DAPM_INPUT("IN1LP"),
- SND_SOC_DAPM_INPUT("IN1LN"),
- SND_SOC_DAPM_INPUT("IN2L"),
- SND_SOC_DAPM_INPUT("IN3R"),
- SND_SOC_DAPM_INPUT("IN3L"),
-};
-
-static const struct snd_soc_dapm_route wm8350_dapm_routes[] = {
-
- /* left playback mixer */
- {"Left Playback Mixer", "Playback Switch", "Left DAC"},
- {"Left Playback Mixer", "Left Bypass Switch", "IN3L PGA"},
- {"Left Playback Mixer", "Right Playback Switch", "Right DAC"},
- {"Left Playback Mixer", "Left Sidetone Switch", "Left Mic Mixer"},
- {"Left Playback Mixer", "Right Sidetone Switch", "Right Mic Mixer"},
-
- /* right playback mixer */
- {"Right Playback Mixer", "Playback Switch", "Right DAC"},
- {"Right Playback Mixer", "Right Bypass Switch", "IN3R PGA"},
- {"Right Playback Mixer", "Left Playback Switch", "Left DAC"},
- {"Right Playback Mixer", "Left Sidetone Switch", "Left Mic Mixer"},
- {"Right Playback Mixer", "Right Sidetone Switch", "Right Mic Mixer"},
-
- /* out4 playback mixer */
- {"Out4 Mixer", "Right Playback Switch", "Right DAC"},
- {"Out4 Mixer", "Left Playback Switch", "Left DAC"},
- {"Out4 Mixer", "Right Capture Switch", "Right Capture Mixer"},
- {"Out4 Mixer", "Out3 Playback Switch", "Out3 Mixer"},
- {"Out4 Mixer", "Right Mixer Switch", "Right Playback Mixer"},
- {"Out4 Mixer", "Left Mixer Switch", "Left Playback Mixer"},
- {"OUT4", NULL, "Out4 Mixer"},
-
- /* out3 playback mixer */
- {"Out3 Mixer", "Left Playback Switch", "Left DAC"},
- {"Out3 Mixer", "Left Capture Switch", "Left Capture Mixer"},
- {"Out3 Mixer", "Left Mixer Switch", "Left Playback Mixer"},
- {"Out3 Mixer", "Out4 Playback Switch", "Out4 Mixer"},
- {"OUT3", NULL, "Out3 Mixer"},
-
- /* out2 */
- {"Right Out2 PGA", NULL, "Right Playback Mixer"},
- {"Left Out2 PGA", NULL, "Left Playback Mixer"},
- {"OUT2L", NULL, "Left Out2 PGA"},
- {"OUT2R", NULL, "Right Out2 PGA"},
-
- /* out1 */
- {"Right Out1 PGA", NULL, "Right Playback Mixer"},
- {"Left Out1 PGA", NULL, "Left Playback Mixer"},
- {"OUT1L", NULL, "Left Out1 PGA"},
- {"OUT1R", NULL, "Right Out1 PGA"},
-
- /* ADCs */
- {"Left ADC", NULL, "Left Capture Mixer"},
- {"Right ADC", NULL, "Right Capture Mixer"},
-
- /* Left capture mixer */
- {"Left Capture Mixer", "L2 Capture Volume", "IN2L"},
- {"Left Capture Mixer", "L3 Capture Volume", "IN3L PGA"},
- {"Left Capture Mixer", "PGA Capture Switch", "Left Mic Mixer"},
- {"Left Capture Mixer", NULL, "Out4 Capture Channel"},
-
- /* Right capture mixer */
- {"Right Capture Mixer", "L2 Capture Volume", "IN2R"},
- {"Right Capture Mixer", "L3 Capture Volume", "IN3R PGA"},
- {"Right Capture Mixer", "PGA Capture Switch", "Right Mic Mixer"},
- {"Right Capture Mixer", NULL, "Out4 Capture Channel"},
-
- /* L3 Inputs */
- {"IN3L PGA", NULL, "IN3L"},
- {"IN3R PGA", NULL, "IN3R"},
-
- /* Left Mic mixer */
- {"Left Mic Mixer", "INN Capture Switch", "IN1LN"},
- {"Left Mic Mixer", "INP Capture Switch", "IN1LP"},
- {"Left Mic Mixer", "IN2 Capture Switch", "IN2L"},
-
- /* Right Mic mixer */
- {"Right Mic Mixer", "INN Capture Switch", "IN1RN"},
- {"Right Mic Mixer", "INP Capture Switch", "IN1RP"},
- {"Right Mic Mixer", "IN2 Capture Switch", "IN2R"},
-
- /* out 4 capture */
- {"Out4 Capture Channel", NULL, "Out4 Mixer"},
-
- /* Beep */
- {"Beep", NULL, "IN3R PGA"},
-};
-
-static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8350 *wm8350 = codec->control_data;
- u16 fll_4;
-
- switch (clk_id) {
- case WM8350_MCLK_SEL_MCLK:
- wm8350_clear_bits(wm8350, WM8350_CLOCK_CONTROL_1,
- WM8350_MCLK_SEL);
- break;
- case WM8350_MCLK_SEL_PLL_MCLK:
- case WM8350_MCLK_SEL_PLL_DAC:
- case WM8350_MCLK_SEL_PLL_ADC:
- case WM8350_MCLK_SEL_PLL_32K:
- wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_1,
- WM8350_MCLK_SEL);
- fll_4 = wm8350_codec_read(codec, WM8350_FLL_CONTROL_4) &
- ~WM8350_FLL_CLK_SRC_MASK;
- wm8350_codec_write(codec, WM8350_FLL_CONTROL_4, fll_4 | clk_id);
- break;
- }
-
- /* MCLK direction */
- if (dir == SND_SOC_CLOCK_OUT)
- wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_2,
- WM8350_MCLK_DIR);
- else
- wm8350_clear_bits(wm8350, WM8350_CLOCK_CONTROL_2,
- WM8350_MCLK_DIR);
-
- return 0;
-}
-
-static int wm8350_set_clkdiv(struct snd_soc_dai *codec_dai, int div_id, int div)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 val;
-
- switch (div_id) {
- case WM8350_ADC_CLKDIV:
- val = wm8350_codec_read(codec, WM8350_ADC_DIVIDER) &
- ~WM8350_ADC_CLKDIV_MASK;
- wm8350_codec_write(codec, WM8350_ADC_DIVIDER, val | div);
- break;
- case WM8350_DAC_CLKDIV:
- val = wm8350_codec_read(codec, WM8350_DAC_CLOCK_CONTROL) &
- ~WM8350_DAC_CLKDIV_MASK;
- wm8350_codec_write(codec, WM8350_DAC_CLOCK_CONTROL, val | div);
- break;
- case WM8350_BCLK_CLKDIV:
- val = wm8350_codec_read(codec, WM8350_CLOCK_CONTROL_1) &
- ~WM8350_BCLK_DIV_MASK;
- wm8350_codec_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
- break;
- case WM8350_OPCLK_CLKDIV:
- val = wm8350_codec_read(codec, WM8350_CLOCK_CONTROL_1) &
- ~WM8350_OPCLK_DIV_MASK;
- wm8350_codec_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
- break;
- case WM8350_SYS_CLKDIV:
- val = wm8350_codec_read(codec, WM8350_CLOCK_CONTROL_1) &
- ~WM8350_MCLK_DIV_MASK;
- wm8350_codec_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
- break;
- case WM8350_DACLR_CLKDIV:
- val = wm8350_codec_read(codec, WM8350_DAC_LR_RATE) &
- ~WM8350_DACLRC_RATE_MASK;
- wm8350_codec_write(codec, WM8350_DAC_LR_RATE, val | div);
- break;
- case WM8350_ADCLR_CLKDIV:
- val = wm8350_codec_read(codec, WM8350_ADC_LR_RATE) &
- ~WM8350_ADCLRC_RATE_MASK;
- wm8350_codec_write(codec, WM8350_ADC_LR_RATE, val | div);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int wm8350_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 iface = wm8350_codec_read(codec, WM8350_AI_FORMATING) &
- ~(WM8350_AIF_BCLK_INV | WM8350_AIF_LRCLK_INV | WM8350_AIF_FMT_MASK);
- u16 master = wm8350_codec_read(codec, WM8350_AI_DAC_CONTROL) &
- ~WM8350_BCLK_MSTR;
- u16 dac_lrc = wm8350_codec_read(codec, WM8350_DAC_LR_RATE) &
- ~WM8350_DACLRC_ENA;
- u16 adc_lrc = wm8350_codec_read(codec, WM8350_ADC_LR_RATE) &
- ~WM8350_ADCLRC_ENA;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- master |= WM8350_BCLK_MSTR;
- dac_lrc |= WM8350_DACLRC_ENA;
- adc_lrc |= WM8350_ADCLRC_ENA;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= 0x2 << 8;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= 0x1 << 8;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= 0x3 << 8;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- iface |= 0x3 << 8 | WM8350_AIF_LRCLK_INV;
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= WM8350_AIF_LRCLK_INV | WM8350_AIF_BCLK_INV;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= WM8350_AIF_BCLK_INV;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- iface |= WM8350_AIF_LRCLK_INV;
- break;
- default:
- return -EINVAL;
- }
-
- wm8350_codec_write(codec, WM8350_AI_FORMATING, iface);
- wm8350_codec_write(codec, WM8350_AI_DAC_CONTROL, master);
- wm8350_codec_write(codec, WM8350_DAC_LR_RATE, dac_lrc);
- wm8350_codec_write(codec, WM8350_ADC_LR_RATE, adc_lrc);
- return 0;
-}
-
-static int wm8350_pcm_trigger(struct snd_pcm_substream *substream,
- int cmd, struct snd_soc_dai *codec_dai)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- int master = wm8350_codec_cache_read(codec, WM8350_AI_DAC_CONTROL) &
- WM8350_BCLK_MSTR;
- int enabled = 0;
-
- /* Check that the DACs or ADCs are enabled since they are
- * required for LRC in master mode. The DACs or ADCs need a
- * valid audio path i.e. pin -> ADC or DAC -> pin before
- * the LRC will be enabled in master mode. */
- if (!master || cmd != SNDRV_PCM_TRIGGER_START)
- return 0;
-
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- enabled = wm8350_codec_cache_read(codec, WM8350_POWER_MGMT_4) &
- (WM8350_ADCR_ENA | WM8350_ADCL_ENA);
- } else {
- enabled = wm8350_codec_cache_read(codec, WM8350_POWER_MGMT_4) &
- (WM8350_DACR_ENA | WM8350_DACL_ENA);
- }
-
- if (!enabled) {
- dev_err(codec->dev,
- "%s: invalid audio path - no clocks available\n",
- __func__);
- return -EINVAL;
- }
- return 0;
-}
-
-static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *codec_dai)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8350 *wm8350 = codec->control_data;
- u16 iface = wm8350_codec_read(codec, WM8350_AI_FORMATING) &
- ~WM8350_AIF_WL_MASK;
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= 0x1 << 10;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface |= 0x2 << 10;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- iface |= 0x3 << 10;
- break;
- }
-
- wm8350_codec_write(codec, WM8350_AI_FORMATING, iface);
-
- /* The sloping stopband filter is recommended for use with
- * lower sample rates to improve performance.
- */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (params_rate(params) < 24000)
- wm8350_set_bits(wm8350, WM8350_DAC_MUTE_VOLUME,
- WM8350_DAC_SB_FILT);
- else
- wm8350_clear_bits(wm8350, WM8350_DAC_MUTE_VOLUME,
- WM8350_DAC_SB_FILT);
- }
-
- return 0;
-}
-
-static int wm8350_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8350 *wm8350 = codec->control_data;
-
- if (mute)
- wm8350_set_bits(wm8350, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA);
- else
- wm8350_clear_bits(wm8350, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA);
- return 0;
-}
-
-/* FLL divisors */
-struct _fll_div {
- int div; /* FLL_OUTDIV */
- int n;
- int k;
- int ratio; /* FLL_FRATIO */
-};
-
-/* The size in bits of the fll divide multiplied by 10
- * to allow rounding later */
-#define FIXED_FLL_SIZE ((1 << 16) * 10)
-
-static inline int fll_factors(struct _fll_div *fll_div, unsigned int input,
- unsigned int output)
-{
- u64 Kpart;
- unsigned int t1, t2, K, Nmod;
-
- if (output >= 2815250 && output <= 3125000)
- fll_div->div = 0x4;
- else if (output >= 5625000 && output <= 6250000)
- fll_div->div = 0x3;
- else if (output >= 11250000 && output <= 12500000)
- fll_div->div = 0x2;
- else if (output >= 22500000 && output <= 25000000)
- fll_div->div = 0x1;
- else {
- printk(KERN_ERR "wm8350: fll freq %d out of range\n", output);
- return -EINVAL;
- }
-
- if (input > 48000)
- fll_div->ratio = 1;
- else
- fll_div->ratio = 8;
-
- t1 = output * (1 << (fll_div->div + 1));
- t2 = input * fll_div->ratio;
-
- fll_div->n = t1 / t2;
- Nmod = t1 % t2;
-
- if (Nmod) {
- Kpart = FIXED_FLL_SIZE * (long long)Nmod;
- do_div(Kpart, t2);
- K = Kpart & 0xFFFFFFFF;
-
- /* Check if we need to round */
- if ((K % 10) >= 5)
- K += 5;
-
- /* Move down to proper range now rounding is done */
- K /= 10;
- fll_div->k = K;
- } else
- fll_div->k = 0;
-
- return 0;
-}
-
-static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
- int pll_id, int source, unsigned int freq_in,
- unsigned int freq_out)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8350 *wm8350 = codec->control_data;
- struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
- struct _fll_div fll_div;
- int ret = 0;
- u16 fll_1, fll_4;
-
- if (freq_in == priv->fll_freq_in && freq_out == priv->fll_freq_out)
- return 0;
-
- /* power down FLL - we need to do this for reconfiguration */
- wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4,
- WM8350_FLL_ENA | WM8350_FLL_OSC_ENA);
-
- if (freq_out == 0 || freq_in == 0)
- return ret;
-
- ret = fll_factors(&fll_div, freq_in, freq_out);
- if (ret < 0)
- return ret;
- dev_dbg(wm8350->dev,
- "FLL in %u FLL out %u N 0x%x K 0x%x div %d ratio %d",
- freq_in, freq_out, fll_div.n, fll_div.k, fll_div.div,
- fll_div.ratio);
-
- /* set up N.K & dividers */
- fll_1 = wm8350_codec_read(codec, WM8350_FLL_CONTROL_1) &
- ~(WM8350_FLL_OUTDIV_MASK | WM8350_FLL_RSP_RATE_MASK | 0xc000);
- wm8350_codec_write(codec, WM8350_FLL_CONTROL_1,
- fll_1 | (fll_div.div << 8) | 0x50);
- wm8350_codec_write(codec, WM8350_FLL_CONTROL_2,
- (fll_div.ratio << 11) | (fll_div.
- n & WM8350_FLL_N_MASK));
- wm8350_codec_write(codec, WM8350_FLL_CONTROL_3, fll_div.k);
- fll_4 = wm8350_codec_read(codec, WM8350_FLL_CONTROL_4) &
- ~(WM8350_FLL_FRAC | WM8350_FLL_SLOW_LOCK_REF);
- wm8350_codec_write(codec, WM8350_FLL_CONTROL_4,
- fll_4 | (fll_div.k ? WM8350_FLL_FRAC : 0) |
- (fll_div.ratio == 8 ? WM8350_FLL_SLOW_LOCK_REF : 0));
-
- /* power FLL on */
- wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_FLL_OSC_ENA);
- wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_FLL_ENA);
-
- priv->fll_freq_out = freq_out;
- priv->fll_freq_in = freq_in;
-
- return 0;
-}
-
-static int wm8350_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct wm8350 *wm8350 = codec->control_data;
- struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
- struct wm8350_audio_platform_data *platform =
- wm8350->codec.platform_data;
- u16 pm1;
- int ret;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
- ~(WM8350_VMID_MASK | WM8350_CODEC_ISEL_MASK);
- wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
- pm1 | WM8350_VMID_50K |
- platform->codec_current_on << 14);
- break;
-
- case SND_SOC_BIAS_PREPARE:
- pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1);
- pm1 &= ~WM8350_VMID_MASK;
- wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
- pm1 | WM8350_VMID_50K);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies),
- priv->supplies);
- if (ret != 0)
- return ret;
-
- /* Enable the system clock */
- wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4,
- WM8350_SYSCLK_ENA);
-
- /* mute DAC & outputs */
- wm8350_set_bits(wm8350, WM8350_DAC_MUTE,
- WM8350_DAC_MUTE_ENA);
-
- /* discharge cap memory */
- wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
- platform->dis_out1 |
- (platform->dis_out2 << 2) |
- (platform->dis_out3 << 4) |
- (platform->dis_out4 << 6));
-
- /* wait for discharge */
- schedule_timeout_interruptible(msecs_to_jiffies
- (platform->
- cap_discharge_msecs));
-
- /* enable antipop */
- wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
- (platform->vmid_s_curve << 8));
-
- /* ramp up vmid */
- wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
- (platform->
- codec_current_charge << 14) |
- WM8350_VMID_5K | WM8350_VMIDEN |
- WM8350_VBUFEN);
-
- /* wait for vmid */
- schedule_timeout_interruptible(msecs_to_jiffies
- (platform->
- vmid_charge_msecs));
-
- /* turn on vmid 300k */
- pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
- ~(WM8350_VMID_MASK | WM8350_CODEC_ISEL_MASK);
- pm1 |= WM8350_VMID_300K |
- (platform->codec_current_standby << 14);
- wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
- pm1);
-
-
- /* enable analogue bias */
- pm1 |= WM8350_BIASEN;
- wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1, pm1);
-
- /* disable antipop */
- wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL, 0);
-
- } else {
- /* turn on vmid 300k and reduce current */
- pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
- ~(WM8350_VMID_MASK | WM8350_CODEC_ISEL_MASK);
- wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
- pm1 | WM8350_VMID_300K |
- (platform->
- codec_current_standby << 14));
-
- }
- break;
-
- case SND_SOC_BIAS_OFF:
-
- /* mute DAC & enable outputs */
- wm8350_set_bits(wm8350, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA);
-
- wm8350_set_bits(wm8350, WM8350_POWER_MGMT_3,
- WM8350_OUT1L_ENA | WM8350_OUT1R_ENA |
- WM8350_OUT2L_ENA | WM8350_OUT2R_ENA);
-
- /* enable anti pop S curve */
- wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
- (platform->vmid_s_curve << 8));
-
- /* turn off vmid */
- pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
- ~WM8350_VMIDEN;
- wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1, pm1);
-
- /* wait */
- schedule_timeout_interruptible(msecs_to_jiffies
- (platform->
- vmid_discharge_msecs));
-
- wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
- (platform->vmid_s_curve << 8) |
- platform->dis_out1 |
- (platform->dis_out2 << 2) |
- (platform->dis_out3 << 4) |
- (platform->dis_out4 << 6));
-
- /* turn off VBuf and drain */
- pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
- ~(WM8350_VBUFEN | WM8350_VMID_MASK);
- wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
- pm1 | WM8350_OUTPUT_DRAIN_EN);
-
- /* wait */
- schedule_timeout_interruptible(msecs_to_jiffies
- (platform->drain_msecs));
-
- pm1 &= ~WM8350_BIASEN;
- wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1, pm1);
-
- /* disable anti-pop */
- wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL, 0);
-
- wm8350_clear_bits(wm8350, WM8350_LOUT1_VOLUME,
- WM8350_OUT1L_ENA);
- wm8350_clear_bits(wm8350, WM8350_ROUT1_VOLUME,
- WM8350_OUT1R_ENA);
- wm8350_clear_bits(wm8350, WM8350_LOUT2_VOLUME,
- WM8350_OUT2L_ENA);
- wm8350_clear_bits(wm8350, WM8350_ROUT2_VOLUME,
- WM8350_OUT2R_ENA);
-
- /* disable clock gen */
- wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4,
- WM8350_SYSCLK_ENA);
-
- regulator_bulk_disable(ARRAY_SIZE(priv->supplies),
- priv->supplies);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-static int wm8350_suspend(struct snd_soc_codec *codec)
-{
- wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm8350_resume(struct snd_soc_codec *codec)
-{
- wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-
-static void wm8350_hp_work(struct wm8350_data *priv,
- struct wm8350_jack_data *jack,
- u16 mask)
-{
- struct wm8350 *wm8350 = priv->wm8350;
- u16 reg;
- int report;
-
- reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
- if (reg & mask)
- report = jack->report;
- else
- report = 0;
-
- snd_soc_jack_report(jack->jack, report, jack->report);
-
-}
-
-static void wm8350_hpl_work(struct work_struct *work)
-{
- struct wm8350_data *priv =
- container_of(work, struct wm8350_data, hpl.work.work);
-
- wm8350_hp_work(priv, &priv->hpl, WM8350_JACK_L_LVL);
-}
-
-static void wm8350_hpr_work(struct work_struct *work)
-{
- struct wm8350_data *priv =
- container_of(work, struct wm8350_data, hpr.work.work);
-
- wm8350_hp_work(priv, &priv->hpr, WM8350_JACK_R_LVL);
-}
-
-static irqreturn_t wm8350_hp_jack_handler(int irq, void *data)
-{
- struct wm8350_data *priv = data;
- struct wm8350 *wm8350 = priv->wm8350;
- struct wm8350_jack_data *jack = NULL;
-
- switch (irq - wm8350->irq_base) {
- case WM8350_IRQ_CODEC_JCK_DET_L:
-#ifndef CONFIG_SND_SOC_WM8350_MODULE
- trace_snd_soc_jack_irq("WM8350 HPL");
-#endif
- jack = &priv->hpl;
- break;
-
- case WM8350_IRQ_CODEC_JCK_DET_R:
-#ifndef CONFIG_SND_SOC_WM8350_MODULE
- trace_snd_soc_jack_irq("WM8350 HPR");
-#endif
- jack = &priv->hpr;
- break;
-
- default:
- BUG();
- }
-
- if (device_may_wakeup(wm8350->dev))
- pm_wakeup_event(wm8350->dev, 250);
-
- schedule_delayed_work(&jack->work, 200);
-
- return IRQ_HANDLED;
-}
-
-/**
- * wm8350_hp_jack_detect - Enable headphone jack detection.
- *
- * @codec: WM8350 codec
- * @which: left or right jack detect signal
- * @jack: jack to report detection events on
- * @report: value to report
- *
- * Enables the headphone jack detection of the WM8350. If no report
- * is specified then detection is disabled.
- */
-int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
- struct snd_soc_jack *jack, int report)
-{
- struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
- struct wm8350 *wm8350 = codec->control_data;
- int irq;
- int ena;
-
- switch (which) {
- case WM8350_JDL:
- priv->hpl.jack = jack;
- priv->hpl.report = report;
- irq = WM8350_IRQ_CODEC_JCK_DET_L;
- ena = WM8350_JDL_ENA;
- break;
-
- case WM8350_JDR:
- priv->hpr.jack = jack;
- priv->hpr.report = report;
- irq = WM8350_IRQ_CODEC_JCK_DET_R;
- ena = WM8350_JDR_ENA;
- break;
-
- default:
- return -EINVAL;
- }
-
- if (report) {
- wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
- wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena);
- } else {
- wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, ena);
- }
-
- /* Sync status */
- wm8350_hp_jack_handler(irq + wm8350->irq_base, priv);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect);
-
-static irqreturn_t wm8350_mic_handler(int irq, void *data)
-{
- struct wm8350_data *priv = data;
- struct wm8350 *wm8350 = priv->wm8350;
- u16 reg;
- int report = 0;
-
-#ifndef CONFIG_SND_SOC_WM8350_MODULE
- trace_snd_soc_jack_irq("WM8350 mic");
-#endif
-
- reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
- if (reg & WM8350_JACK_MICSCD_LVL)
- report |= priv->mic.short_report;
- if (reg & WM8350_JACK_MICSD_LVL)
- report |= priv->mic.report;
-
- snd_soc_jack_report(priv->mic.jack, report,
- priv->mic.report | priv->mic.short_report);
-
- return IRQ_HANDLED;
-}
-
-/**
- * wm8350_mic_jack_detect - Enable microphone jack detection.
- *
- * @codec: WM8350 codec
- * @jack: jack to report detection events on
- * @detect_report: value to report when presence detected
- * @short_report: value to report when microphone short detected
- *
- * Enables the microphone jack detection of the WM8350. If both reports
- * are specified as zero then detection is disabled.
- */
-int wm8350_mic_jack_detect(struct snd_soc_codec *codec,
- struct snd_soc_jack *jack,
- int detect_report, int short_report)
-{
- struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
- struct wm8350 *wm8350 = codec->control_data;
-
- priv->mic.jack = jack;
- priv->mic.report = detect_report;
- priv->mic.short_report = short_report;
-
- if (detect_report || short_report) {
- wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
- wm8350_set_bits(wm8350, WM8350_POWER_MGMT_1,
- WM8350_MIC_DET_ENA);
- } else {
- wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_1,
- WM8350_MIC_DET_ENA);
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(wm8350_mic_jack_detect);
-
-#define WM8350_RATES (SNDRV_PCM_RATE_8000_96000)
-
-#define WM8350_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
- SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops wm8350_dai_ops = {
- .hw_params = wm8350_pcm_hw_params,
- .digital_mute = wm8350_mute,
- .trigger = wm8350_pcm_trigger,
- .set_fmt = wm8350_set_dai_fmt,
- .set_sysclk = wm8350_set_dai_sysclk,
- .set_pll = wm8350_set_fll,
- .set_clkdiv = wm8350_set_clkdiv,
-};
-
-static struct snd_soc_dai_driver wm8350_dai = {
- .name = "wm8350-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8350_RATES,
- .formats = WM8350_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8350_RATES,
- .formats = WM8350_FORMATS,
- },
- .ops = &wm8350_dai_ops,
-};
-
-static int wm8350_codec_probe(struct snd_soc_codec *codec)
-{
- struct wm8350 *wm8350 = dev_get_platdata(codec->dev);
- struct wm8350_data *priv;
- struct wm8350_output *out1;
- struct wm8350_output *out2;
- int ret, i;
-
- if (wm8350->codec.platform_data == NULL) {
- dev_err(codec->dev, "No audio platform data supplied\n");
- return -EINVAL;
- }
-
- priv = devm_kzalloc(codec->dev, sizeof(struct wm8350_data),
- GFP_KERNEL);
- if (priv == NULL)
- return -ENOMEM;
- snd_soc_codec_set_drvdata(codec, priv);
-
- priv->wm8350 = wm8350;
-
- for (i = 0; i < ARRAY_SIZE(supply_names); i++)
- priv->supplies[i].supply = supply_names[i];
-
- ret = regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies),
- priv->supplies);
- if (ret != 0)
- return ret;
-
- codec->control_data = wm8350;
-
- /* Put the codec into reset if it wasn't already */
- wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
-
- INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8350_pga_work);
- INIT_DELAYED_WORK(&priv->hpl.work, wm8350_hpl_work);
- INIT_DELAYED_WORK(&priv->hpr.work, wm8350_hpr_work);
-
- /* Enable the codec */
- wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
-
- /* Enable robust clocking mode in ADC */
- wm8350_codec_write(codec, WM8350_SECURITY, 0xa7);
- wm8350_codec_write(codec, 0xde, 0x13);
- wm8350_codec_write(codec, WM8350_SECURITY, 0);
-
- /* read OUT1 & OUT2 volumes */
- out1 = &priv->out1;
- out2 = &priv->out2;
- out1->left_vol = (wm8350_reg_read(wm8350, WM8350_LOUT1_VOLUME) &
- WM8350_OUT1L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
- out1->right_vol = (wm8350_reg_read(wm8350, WM8350_ROUT1_VOLUME) &
- WM8350_OUT1R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
- out2->left_vol = (wm8350_reg_read(wm8350, WM8350_LOUT2_VOLUME) &
- WM8350_OUT2L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
- out2->right_vol = (wm8350_reg_read(wm8350, WM8350_ROUT2_VOLUME) &
- WM8350_OUT2R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
- wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME, 0);
- wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME, 0);
- wm8350_reg_write(wm8350, WM8350_LOUT2_VOLUME, 0);
- wm8350_reg_write(wm8350, WM8350_ROUT2_VOLUME, 0);
-
- /* Latch VU bits & mute */
- wm8350_set_bits(wm8350, WM8350_LOUT1_VOLUME,
- WM8350_OUT1_VU | WM8350_OUT1L_MUTE);
- wm8350_set_bits(wm8350, WM8350_LOUT2_VOLUME,
- WM8350_OUT2_VU | WM8350_OUT2L_MUTE);
- wm8350_set_bits(wm8350, WM8350_ROUT1_VOLUME,
- WM8350_OUT1_VU | WM8350_OUT1R_MUTE);
- wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME,
- WM8350_OUT2_VU | WM8350_OUT2R_MUTE);
-
- /* Make sure AIF tristating is disabled by default */
- wm8350_clear_bits(wm8350, WM8350_AI_FORMATING, WM8350_AIF_TRI);
-
- /* Make sure we've got a sane companding setup too */
- wm8350_clear_bits(wm8350, WM8350_ADC_DAC_COMP,
- WM8350_DAC_COMP | WM8350_LOOPBACK);
-
- /* Make sure jack detect is disabled to start off with */
- wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
- WM8350_JDL_ENA | WM8350_JDR_ENA);
-
- wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L,
- wm8350_hp_jack_handler, 0, "Left jack detect",
- priv);
- wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R,
- wm8350_hp_jack_handler, 0, "Right jack detect",
- priv);
- wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICSCD,
- wm8350_mic_handler, 0, "Microphone short", priv);
- wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICD,
- wm8350_mic_handler, 0, "Microphone detect", priv);
-
-
- wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-
-static int wm8350_codec_remove(struct snd_soc_codec *codec)
-{
- struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
- struct wm8350 *wm8350 = dev_get_platdata(codec->dev);
-
- wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
- WM8350_JDL_ENA | WM8350_JDR_ENA);
- wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
-
- wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_MICD, priv);
- wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_MICSCD, priv);
- wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, priv);
- wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, priv);
-
- priv->hpl.jack = NULL;
- priv->hpr.jack = NULL;
- priv->mic.jack = NULL;
-
- cancel_delayed_work_sync(&priv->hpl.work);
- cancel_delayed_work_sync(&priv->hpr.work);
-
- /* if there was any work waiting then we run it now and
- * wait for its completion */
- flush_delayed_work_sync(&codec->dapm.delayed_work);
-
- wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
-
- regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8350 = {
- .probe = wm8350_codec_probe,
- .remove = wm8350_codec_remove,
- .suspend = wm8350_suspend,
- .resume = wm8350_resume,
- .read = wm8350_codec_read,
- .write = wm8350_codec_write,
- .set_bias_level = wm8350_set_bias_level,
-
- .controls = wm8350_snd_controls,
- .num_controls = ARRAY_SIZE(wm8350_snd_controls),
- .dapm_widgets = wm8350_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8350_dapm_widgets),
- .dapm_routes = wm8350_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm8350_dapm_routes),
-};
-
-static int __devinit wm8350_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8350,
- &wm8350_dai, 1);
-}
-
-static int __devexit wm8350_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver wm8350_codec_driver = {
- .driver = {
- .name = "wm8350-codec",
- .owner = THIS_MODULE,
- },
- .probe = wm8350_probe,
- .remove = __devexit_p(wm8350_remove),
-};
-
-module_platform_driver(wm8350_codec_driver);
-
-MODULE_DESCRIPTION("ASoC WM8350 driver");
-MODULE_AUTHOR("Liam Girdwood");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:wm8350-codec");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8350.h b/ANDROID_3.4.5/sound/soc/codecs/wm8350.h
deleted file mode 100644
index 74108eb8..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8350.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * wm8350.h - WM8903 audio codec interface
- *
- * Copyright 2008 Wolfson Microelectronics PLC.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#ifndef _WM8350_H
-#define _WM8350_H
-
-#include <sound/soc.h>
-#include <linux/mfd/wm8350/audio.h>
-
-enum wm8350_jack {
- WM8350_JDL = 1,
- WM8350_JDR = 2,
-};
-
-int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
- struct snd_soc_jack *jack, int report);
-int wm8350_mic_jack_detect(struct snd_soc_codec *codec,
- struct snd_soc_jack *jack,
- int detect_report, int short_report);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8400.c b/ANDROID_3.4.5/sound/soc/codecs/wm8400.c
deleted file mode 100644
index 898979d2..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8400.c
+++ /dev/null
@@ -1,1469 +0,0 @@
-/*
- * wm8400.c -- WM8400 ALSA Soc Audio driver
- *
- * Copyright 2008, 2009 Wolfson Microelectronics PLC.
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/consumer.h>
-#include <linux/mfd/wm8400-audio.h>
-#include <linux/mfd/wm8400-private.h>
-#include <linux/mfd/core.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "wm8400.h"
-
-/* Fake register for internal state */
-#define WM8400_INTDRIVBITS (WM8400_REGISTER_COUNT + 1)
-#define WM8400_INMIXL_PWR 0
-#define WM8400_AINLMUX_PWR 1
-#define WM8400_INMIXR_PWR 2
-#define WM8400_AINRMUX_PWR 3
-
-static struct regulator_bulk_data power[] = {
- {
- .supply = "I2S1VDD",
- },
- {
- .supply = "I2S2VDD",
- },
- {
- .supply = "DCVDD",
- },
- {
- .supply = "AVDD",
- },
- {
- .supply = "FLLVDD",
- },
- {
- .supply = "HPVDD",
- },
- {
- .supply = "SPKVDD",
- },
-};
-
-/* codec private data */
-struct wm8400_priv {
- struct snd_soc_codec *codec;
- struct wm8400 *wm8400;
- u16 fake_register;
- unsigned int sysclk;
- unsigned int pcmclk;
- struct work_struct work;
- int fll_in, fll_out;
-};
-
-static inline unsigned int wm8400_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
-
- if (reg == WM8400_INTDRIVBITS)
- return wm8400->fake_register;
- else
- return wm8400_reg_read(wm8400->wm8400, reg);
-}
-
-/*
- * write to the wm8400 register space
- */
-static int wm8400_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
-
- if (reg == WM8400_INTDRIVBITS) {
- wm8400->fake_register = value;
- return 0;
- } else
- return wm8400_set_bits(wm8400->wm8400, reg, 0xffff, value);
-}
-
-static void wm8400_codec_reset(struct snd_soc_codec *codec)
-{
- struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
-
- wm8400_reset_codec_reg_cache(wm8400->wm8400);
-}
-
-static const DECLARE_TLV_DB_SCALE(rec_mix_tlv, -1500, 600, 0);
-
-static const DECLARE_TLV_DB_SCALE(in_pga_tlv, -1650, 3000, 0);
-
-static const DECLARE_TLV_DB_SCALE(out_mix_tlv, -2100, 0, 0);
-
-static const DECLARE_TLV_DB_SCALE(out_pga_tlv, -7300, 600, 0);
-
-static const DECLARE_TLV_DB_SCALE(out_omix_tlv, -600, 0, 0);
-
-static const DECLARE_TLV_DB_SCALE(out_dac_tlv, -7163, 0, 0);
-
-static const DECLARE_TLV_DB_SCALE(in_adc_tlv, -7163, 1763, 0);
-
-static const DECLARE_TLV_DB_SCALE(out_sidetone_tlv, -3600, 0, 0);
-
-static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- int reg = mc->reg;
- int ret;
- u16 val;
-
- ret = snd_soc_put_volsw(kcontrol, ucontrol);
- if (ret < 0)
- return ret;
-
- /* now hit the volume update bits (always bit 8) */
- val = wm8400_read(codec, reg);
- return wm8400_write(codec, reg, val | 0x0100);
-}
-
-#define WM8400_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert, tlv_array) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
- .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
- SNDRV_CTL_ELEM_ACCESS_READWRITE,\
- .tlv.p = (tlv_array), \
- .info = snd_soc_info_volsw, \
- .get = snd_soc_get_volsw, .put = wm8400_outpga_put_volsw_vu, \
- .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
-
-
-static const char *wm8400_digital_sidetone[] =
- {"None", "Left ADC", "Right ADC", "Reserved"};
-
-static const struct soc_enum wm8400_left_digital_sidetone_enum =
-SOC_ENUM_SINGLE(WM8400_DIGITAL_SIDE_TONE,
- WM8400_ADC_TO_DACL_SHIFT, 2, wm8400_digital_sidetone);
-
-static const struct soc_enum wm8400_right_digital_sidetone_enum =
-SOC_ENUM_SINGLE(WM8400_DIGITAL_SIDE_TONE,
- WM8400_ADC_TO_DACR_SHIFT, 2, wm8400_digital_sidetone);
-
-static const char *wm8400_adcmode[] =
- {"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"};
-
-static const struct soc_enum wm8400_right_adcmode_enum =
-SOC_ENUM_SINGLE(WM8400_ADC_CTRL, WM8400_ADC_HPF_CUT_SHIFT, 3, wm8400_adcmode);
-
-static const struct snd_kcontrol_new wm8400_snd_controls[] = {
-/* INMIXL */
-SOC_SINGLE("LIN12 PGA Boost", WM8400_INPUT_MIXER3, WM8400_L12MNBST_SHIFT,
- 1, 0),
-SOC_SINGLE("LIN34 PGA Boost", WM8400_INPUT_MIXER3, WM8400_L34MNBST_SHIFT,
- 1, 0),
-/* INMIXR */
-SOC_SINGLE("RIN12 PGA Boost", WM8400_INPUT_MIXER3, WM8400_R12MNBST_SHIFT,
- 1, 0),
-SOC_SINGLE("RIN34 PGA Boost", WM8400_INPUT_MIXER3, WM8400_R34MNBST_SHIFT,
- 1, 0),
-
-/* LOMIX */
-SOC_SINGLE_TLV("LOMIX LIN3 Bypass Volume", WM8400_OUTPUT_MIXER3,
- WM8400_LLI3LOVOL_SHIFT, 7, 0, out_mix_tlv),
-SOC_SINGLE_TLV("LOMIX RIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER3,
- WM8400_LR12LOVOL_SHIFT, 7, 0, out_mix_tlv),
-SOC_SINGLE_TLV("LOMIX LIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER3,
- WM8400_LL12LOVOL_SHIFT, 7, 0, out_mix_tlv),
-SOC_SINGLE_TLV("LOMIX RIN3 Bypass Volume", WM8400_OUTPUT_MIXER5,
- WM8400_LRI3LOVOL_SHIFT, 7, 0, out_mix_tlv),
-SOC_SINGLE_TLV("LOMIX AINRMUX Bypass Volume", WM8400_OUTPUT_MIXER5,
- WM8400_LRBLOVOL_SHIFT, 7, 0, out_mix_tlv),
-SOC_SINGLE_TLV("LOMIX AINLMUX Bypass Volume", WM8400_OUTPUT_MIXER5,
- WM8400_LRBLOVOL_SHIFT, 7, 0, out_mix_tlv),
-
-/* ROMIX */
-SOC_SINGLE_TLV("ROMIX RIN3 Bypass Volume", WM8400_OUTPUT_MIXER4,
- WM8400_RRI3ROVOL_SHIFT, 7, 0, out_mix_tlv),
-SOC_SINGLE_TLV("ROMIX LIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER4,
- WM8400_RL12ROVOL_SHIFT, 7, 0, out_mix_tlv),
-SOC_SINGLE_TLV("ROMIX RIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER4,
- WM8400_RR12ROVOL_SHIFT, 7, 0, out_mix_tlv),
-SOC_SINGLE_TLV("ROMIX LIN3 Bypass Volume", WM8400_OUTPUT_MIXER6,
- WM8400_RLI3ROVOL_SHIFT, 7, 0, out_mix_tlv),
-SOC_SINGLE_TLV("ROMIX AINLMUX Bypass Volume", WM8400_OUTPUT_MIXER6,
- WM8400_RLBROVOL_SHIFT, 7, 0, out_mix_tlv),
-SOC_SINGLE_TLV("ROMIX AINRMUX Bypass Volume", WM8400_OUTPUT_MIXER6,
- WM8400_RRBROVOL_SHIFT, 7, 0, out_mix_tlv),
-
-/* LOUT */
-WM8400_OUTPGA_SINGLE_R_TLV("LOUT Volume", WM8400_LEFT_OUTPUT_VOLUME,
- WM8400_LOUTVOL_SHIFT, WM8400_LOUTVOL_MASK, 0, out_pga_tlv),
-SOC_SINGLE("LOUT ZC", WM8400_LEFT_OUTPUT_VOLUME, WM8400_LOZC_SHIFT, 1, 0),
-
-/* ROUT */
-WM8400_OUTPGA_SINGLE_R_TLV("ROUT Volume", WM8400_RIGHT_OUTPUT_VOLUME,
- WM8400_ROUTVOL_SHIFT, WM8400_ROUTVOL_MASK, 0, out_pga_tlv),
-SOC_SINGLE("ROUT ZC", WM8400_RIGHT_OUTPUT_VOLUME, WM8400_ROZC_SHIFT, 1, 0),
-
-/* LOPGA */
-WM8400_OUTPGA_SINGLE_R_TLV("LOPGA Volume", WM8400_LEFT_OPGA_VOLUME,
- WM8400_LOPGAVOL_SHIFT, WM8400_LOPGAVOL_MASK, 0, out_pga_tlv),
-SOC_SINGLE("LOPGA ZC Switch", WM8400_LEFT_OPGA_VOLUME,
- WM8400_LOPGAZC_SHIFT, 1, 0),
-
-/* ROPGA */
-WM8400_OUTPGA_SINGLE_R_TLV("ROPGA Volume", WM8400_RIGHT_OPGA_VOLUME,
- WM8400_ROPGAVOL_SHIFT, WM8400_ROPGAVOL_MASK, 0, out_pga_tlv),
-SOC_SINGLE("ROPGA ZC Switch", WM8400_RIGHT_OPGA_VOLUME,
- WM8400_ROPGAZC_SHIFT, 1, 0),
-
-SOC_SINGLE("LON Mute Switch", WM8400_LINE_OUTPUTS_VOLUME,
- WM8400_LONMUTE_SHIFT, 1, 0),
-SOC_SINGLE("LOP Mute Switch", WM8400_LINE_OUTPUTS_VOLUME,
- WM8400_LOPMUTE_SHIFT, 1, 0),
-SOC_SINGLE("LOP Attenuation Switch", WM8400_LINE_OUTPUTS_VOLUME,
- WM8400_LOATTN_SHIFT, 1, 0),
-SOC_SINGLE("RON Mute Switch", WM8400_LINE_OUTPUTS_VOLUME,
- WM8400_RONMUTE_SHIFT, 1, 0),
-SOC_SINGLE("ROP Mute Switch", WM8400_LINE_OUTPUTS_VOLUME,
- WM8400_ROPMUTE_SHIFT, 1, 0),
-SOC_SINGLE("ROP Attenuation Switch", WM8400_LINE_OUTPUTS_VOLUME,
- WM8400_ROATTN_SHIFT, 1, 0),
-
-SOC_SINGLE("OUT3 Mute Switch", WM8400_OUT3_4_VOLUME,
- WM8400_OUT3MUTE_SHIFT, 1, 0),
-SOC_SINGLE("OUT3 Attenuation Switch", WM8400_OUT3_4_VOLUME,
- WM8400_OUT3ATTN_SHIFT, 1, 0),
-
-SOC_SINGLE("OUT4 Mute Switch", WM8400_OUT3_4_VOLUME,
- WM8400_OUT4MUTE_SHIFT, 1, 0),
-SOC_SINGLE("OUT4 Attenuation Switch", WM8400_OUT3_4_VOLUME,
- WM8400_OUT4ATTN_SHIFT, 1, 0),
-
-SOC_SINGLE("Speaker Mode Switch", WM8400_CLASSD1,
- WM8400_CDMODE_SHIFT, 1, 0),
-
-SOC_SINGLE("Speaker Output Attenuation Volume", WM8400_SPEAKER_VOLUME,
- WM8400_SPKATTN_SHIFT, WM8400_SPKATTN_MASK, 0),
-SOC_SINGLE("Speaker DC Boost Volume", WM8400_CLASSD3,
- WM8400_DCGAIN_SHIFT, 6, 0),
-SOC_SINGLE("Speaker AC Boost Volume", WM8400_CLASSD3,
- WM8400_ACGAIN_SHIFT, 6, 0),
-
-WM8400_OUTPGA_SINGLE_R_TLV("Left DAC Digital Volume",
- WM8400_LEFT_DAC_DIGITAL_VOLUME, WM8400_DACL_VOL_SHIFT,
- 127, 0, out_dac_tlv),
-
-WM8400_OUTPGA_SINGLE_R_TLV("Right DAC Digital Volume",
- WM8400_RIGHT_DAC_DIGITAL_VOLUME, WM8400_DACR_VOL_SHIFT,
- 127, 0, out_dac_tlv),
-
-SOC_ENUM("Left Digital Sidetone", wm8400_left_digital_sidetone_enum),
-SOC_ENUM("Right Digital Sidetone", wm8400_right_digital_sidetone_enum),
-
-SOC_SINGLE_TLV("Left Digital Sidetone Volume", WM8400_DIGITAL_SIDE_TONE,
- WM8400_ADCL_DAC_SVOL_SHIFT, 15, 0, out_sidetone_tlv),
-SOC_SINGLE_TLV("Right Digital Sidetone Volume", WM8400_DIGITAL_SIDE_TONE,
- WM8400_ADCR_DAC_SVOL_SHIFT, 15, 0, out_sidetone_tlv),
-
-SOC_SINGLE("ADC Digital High Pass Filter Switch", WM8400_ADC_CTRL,
- WM8400_ADC_HPF_ENA_SHIFT, 1, 0),
-
-SOC_ENUM("ADC HPF Mode", wm8400_right_adcmode_enum),
-
-WM8400_OUTPGA_SINGLE_R_TLV("Left ADC Digital Volume",
- WM8400_LEFT_ADC_DIGITAL_VOLUME,
- WM8400_ADCL_VOL_SHIFT,
- WM8400_ADCL_VOL_MASK,
- 0,
- in_adc_tlv),
-
-WM8400_OUTPGA_SINGLE_R_TLV("Right ADC Digital Volume",
- WM8400_RIGHT_ADC_DIGITAL_VOLUME,
- WM8400_ADCR_VOL_SHIFT,
- WM8400_ADCR_VOL_MASK,
- 0,
- in_adc_tlv),
-
-WM8400_OUTPGA_SINGLE_R_TLV("LIN12 Volume",
- WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
- WM8400_LIN12VOL_SHIFT,
- WM8400_LIN12VOL_MASK,
- 0,
- in_pga_tlv),
-
-SOC_SINGLE("LIN12 ZC Switch", WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
- WM8400_LI12ZC_SHIFT, 1, 0),
-
-SOC_SINGLE("LIN12 Mute Switch", WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
- WM8400_LI12MUTE_SHIFT, 1, 0),
-
-WM8400_OUTPGA_SINGLE_R_TLV("LIN34 Volume",
- WM8400_LEFT_LINE_INPUT_3_4_VOLUME,
- WM8400_LIN34VOL_SHIFT,
- WM8400_LIN34VOL_MASK,
- 0,
- in_pga_tlv),
-
-SOC_SINGLE("LIN34 ZC Switch", WM8400_LEFT_LINE_INPUT_3_4_VOLUME,
- WM8400_LI34ZC_SHIFT, 1, 0),
-
-SOC_SINGLE("LIN34 Mute Switch", WM8400_LEFT_LINE_INPUT_3_4_VOLUME,
- WM8400_LI34MUTE_SHIFT, 1, 0),
-
-WM8400_OUTPGA_SINGLE_R_TLV("RIN12 Volume",
- WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
- WM8400_RIN12VOL_SHIFT,
- WM8400_RIN12VOL_MASK,
- 0,
- in_pga_tlv),
-
-SOC_SINGLE("RIN12 ZC Switch", WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
- WM8400_RI12ZC_SHIFT, 1, 0),
-
-SOC_SINGLE("RIN12 Mute Switch", WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
- WM8400_RI12MUTE_SHIFT, 1, 0),
-
-WM8400_OUTPGA_SINGLE_R_TLV("RIN34 Volume",
- WM8400_RIGHT_LINE_INPUT_3_4_VOLUME,
- WM8400_RIN34VOL_SHIFT,
- WM8400_RIN34VOL_MASK,
- 0,
- in_pga_tlv),
-
-SOC_SINGLE("RIN34 ZC Switch", WM8400_RIGHT_LINE_INPUT_3_4_VOLUME,
- WM8400_RI34ZC_SHIFT, 1, 0),
-
-SOC_SINGLE("RIN34 Mute Switch", WM8400_RIGHT_LINE_INPUT_3_4_VOLUME,
- WM8400_RI34MUTE_SHIFT, 1, 0),
-
-};
-
-/*
- * _DAPM_ Controls
- */
-
-static int inmixer_event (struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- u16 reg, fakepower;
-
- reg = wm8400_read(w->codec, WM8400_POWER_MANAGEMENT_2);
- fakepower = wm8400_read(w->codec, WM8400_INTDRIVBITS);
-
- if (fakepower & ((1 << WM8400_INMIXL_PWR) |
- (1 << WM8400_AINLMUX_PWR))) {
- reg |= WM8400_AINL_ENA;
- } else {
- reg &= ~WM8400_AINL_ENA;
- }
-
- if (fakepower & ((1 << WM8400_INMIXR_PWR) |
- (1 << WM8400_AINRMUX_PWR))) {
- reg |= WM8400_AINR_ENA;
- } else {
- reg &= ~WM8400_AINR_ENA;
- }
- wm8400_write(w->codec, WM8400_POWER_MANAGEMENT_2, reg);
-
- return 0;
-}
-
-static int outmixer_event (struct snd_soc_dapm_widget *w,
- struct snd_kcontrol * kcontrol, int event)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- u32 reg_shift = mc->shift;
- int ret = 0;
- u16 reg;
-
- switch (reg_shift) {
- case WM8400_SPEAKER_MIXER | (WM8400_LDSPK << 8) :
- reg = wm8400_read(w->codec, WM8400_OUTPUT_MIXER1);
- if (reg & WM8400_LDLO) {
- printk(KERN_WARNING
- "Cannot set as Output Mixer 1 LDLO Set\n");
- ret = -1;
- }
- break;
- case WM8400_SPEAKER_MIXER | (WM8400_RDSPK << 8):
- reg = wm8400_read(w->codec, WM8400_OUTPUT_MIXER2);
- if (reg & WM8400_RDRO) {
- printk(KERN_WARNING
- "Cannot set as Output Mixer 2 RDRO Set\n");
- ret = -1;
- }
- break;
- case WM8400_OUTPUT_MIXER1 | (WM8400_LDLO << 8):
- reg = wm8400_read(w->codec, WM8400_SPEAKER_MIXER);
- if (reg & WM8400_LDSPK) {
- printk(KERN_WARNING
- "Cannot set as Speaker Mixer LDSPK Set\n");
- ret = -1;
- }
- break;
- case WM8400_OUTPUT_MIXER2 | (WM8400_RDRO << 8):
- reg = wm8400_read(w->codec, WM8400_SPEAKER_MIXER);
- if (reg & WM8400_RDSPK) {
- printk(KERN_WARNING
- "Cannot set as Speaker Mixer RDSPK Set\n");
- ret = -1;
- }
- break;
- }
-
- return ret;
-}
-
-/* INMIX dB values */
-static const unsigned int in_mix_tlv[] = {
- TLV_DB_RANGE_HEAD(1),
- 0,7, TLV_DB_SCALE_ITEM(-1200, 600, 0),
-};
-
-/* Left In PGA Connections */
-static const struct snd_kcontrol_new wm8400_dapm_lin12_pga_controls[] = {
-SOC_DAPM_SINGLE("LIN1 Switch", WM8400_INPUT_MIXER2, WM8400_LMN1_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LIN2 Switch", WM8400_INPUT_MIXER2, WM8400_LMP2_SHIFT, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8400_dapm_lin34_pga_controls[] = {
-SOC_DAPM_SINGLE("LIN3 Switch", WM8400_INPUT_MIXER2, WM8400_LMN3_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LIN4 Switch", WM8400_INPUT_MIXER2, WM8400_LMP4_SHIFT, 1, 0),
-};
-
-/* Right In PGA Connections */
-static const struct snd_kcontrol_new wm8400_dapm_rin12_pga_controls[] = {
-SOC_DAPM_SINGLE("RIN1 Switch", WM8400_INPUT_MIXER2, WM8400_RMN1_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("RIN2 Switch", WM8400_INPUT_MIXER2, WM8400_RMP2_SHIFT, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8400_dapm_rin34_pga_controls[] = {
-SOC_DAPM_SINGLE("RIN3 Switch", WM8400_INPUT_MIXER2, WM8400_RMN3_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("RIN4 Switch", WM8400_INPUT_MIXER2, WM8400_RMP4_SHIFT, 1, 0),
-};
-
-/* INMIXL */
-static const struct snd_kcontrol_new wm8400_dapm_inmixl_controls[] = {
-SOC_DAPM_SINGLE_TLV("Record Left Volume", WM8400_INPUT_MIXER3,
- WM8400_LDBVOL_SHIFT, WM8400_LDBVOL_MASK, 0, in_mix_tlv),
-SOC_DAPM_SINGLE_TLV("LIN2 Volume", WM8400_INPUT_MIXER5, WM8400_LI2BVOL_SHIFT,
- 7, 0, in_mix_tlv),
-SOC_DAPM_SINGLE("LINPGA12 Switch", WM8400_INPUT_MIXER3, WM8400_L12MNB_SHIFT,
- 1, 0),
-SOC_DAPM_SINGLE("LINPGA34 Switch", WM8400_INPUT_MIXER3, WM8400_L34MNB_SHIFT,
- 1, 0),
-};
-
-/* INMIXR */
-static const struct snd_kcontrol_new wm8400_dapm_inmixr_controls[] = {
-SOC_DAPM_SINGLE_TLV("Record Right Volume", WM8400_INPUT_MIXER4,
- WM8400_RDBVOL_SHIFT, WM8400_RDBVOL_MASK, 0, in_mix_tlv),
-SOC_DAPM_SINGLE_TLV("RIN2 Volume", WM8400_INPUT_MIXER6, WM8400_RI2BVOL_SHIFT,
- 7, 0, in_mix_tlv),
-SOC_DAPM_SINGLE("RINPGA12 Switch", WM8400_INPUT_MIXER3, WM8400_L12MNB_SHIFT,
- 1, 0),
-SOC_DAPM_SINGLE("RINPGA34 Switch", WM8400_INPUT_MIXER3, WM8400_L34MNB_SHIFT,
- 1, 0),
-};
-
-/* AINLMUX */
-static const char *wm8400_ainlmux[] =
- {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"};
-
-static const struct soc_enum wm8400_ainlmux_enum =
-SOC_ENUM_SINGLE( WM8400_INPUT_MIXER1, WM8400_AINLMODE_SHIFT,
- ARRAY_SIZE(wm8400_ainlmux), wm8400_ainlmux);
-
-static const struct snd_kcontrol_new wm8400_dapm_ainlmux_controls =
-SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum);
-
-/* DIFFINL */
-
-/* AINRMUX */
-static const char *wm8400_ainrmux[] =
- {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"};
-
-static const struct soc_enum wm8400_ainrmux_enum =
-SOC_ENUM_SINGLE( WM8400_INPUT_MIXER1, WM8400_AINRMODE_SHIFT,
- ARRAY_SIZE(wm8400_ainrmux), wm8400_ainrmux);
-
-static const struct snd_kcontrol_new wm8400_dapm_ainrmux_controls =
-SOC_DAPM_ENUM("Route", wm8400_ainrmux_enum);
-
-/* RXVOICE */
-static const struct snd_kcontrol_new wm8400_dapm_rxvoice_controls[] = {
-SOC_DAPM_SINGLE_TLV("LIN4/RXN", WM8400_INPUT_MIXER5, WM8400_LR4BVOL_SHIFT,
- WM8400_LR4BVOL_MASK, 0, in_mix_tlv),
-SOC_DAPM_SINGLE_TLV("RIN4/RXP", WM8400_INPUT_MIXER6, WM8400_RL4BVOL_SHIFT,
- WM8400_RL4BVOL_MASK, 0, in_mix_tlv),
-};
-
-/* LOMIX */
-static const struct snd_kcontrol_new wm8400_dapm_lomix_controls[] = {
-SOC_DAPM_SINGLE("LOMIX Right ADC Bypass Switch", WM8400_OUTPUT_MIXER1,
- WM8400_LRBLO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LOMIX Left ADC Bypass Switch", WM8400_OUTPUT_MIXER1,
- WM8400_LLBLO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LOMIX RIN3 Bypass Switch", WM8400_OUTPUT_MIXER1,
- WM8400_LRI3LO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LOMIX LIN3 Bypass Switch", WM8400_OUTPUT_MIXER1,
- WM8400_LLI3LO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LOMIX RIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER1,
- WM8400_LR12LO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LOMIX LIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER1,
- WM8400_LL12LO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LOMIX Left DAC Switch", WM8400_OUTPUT_MIXER1,
- WM8400_LDLO_SHIFT, 1, 0),
-};
-
-/* ROMIX */
-static const struct snd_kcontrol_new wm8400_dapm_romix_controls[] = {
-SOC_DAPM_SINGLE("ROMIX Left ADC Bypass Switch", WM8400_OUTPUT_MIXER2,
- WM8400_RLBRO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("ROMIX Right ADC Bypass Switch", WM8400_OUTPUT_MIXER2,
- WM8400_RRBRO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("ROMIX LIN3 Bypass Switch", WM8400_OUTPUT_MIXER2,
- WM8400_RLI3RO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("ROMIX RIN3 Bypass Switch", WM8400_OUTPUT_MIXER2,
- WM8400_RRI3RO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("ROMIX LIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER2,
- WM8400_RL12RO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("ROMIX RIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER2,
- WM8400_RR12RO_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("ROMIX Right DAC Switch", WM8400_OUTPUT_MIXER2,
- WM8400_RDRO_SHIFT, 1, 0),
-};
-
-/* LONMIX */
-static const struct snd_kcontrol_new wm8400_dapm_lonmix_controls[] = {
-SOC_DAPM_SINGLE("LONMIX Left Mixer PGA Switch", WM8400_LINE_MIXER1,
- WM8400_LLOPGALON_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LONMIX Right Mixer PGA Switch", WM8400_LINE_MIXER1,
- WM8400_LROPGALON_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LONMIX Inverted LOP Switch", WM8400_LINE_MIXER1,
- WM8400_LOPLON_SHIFT, 1, 0),
-};
-
-/* LOPMIX */
-static const struct snd_kcontrol_new wm8400_dapm_lopmix_controls[] = {
-SOC_DAPM_SINGLE("LOPMIX Right Mic Bypass Switch", WM8400_LINE_MIXER1,
- WM8400_LR12LOP_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LOPMIX Left Mic Bypass Switch", WM8400_LINE_MIXER1,
- WM8400_LL12LOP_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("LOPMIX Left Mixer PGA Switch", WM8400_LINE_MIXER1,
- WM8400_LLOPGALOP_SHIFT, 1, 0),
-};
-
-/* RONMIX */
-static const struct snd_kcontrol_new wm8400_dapm_ronmix_controls[] = {
-SOC_DAPM_SINGLE("RONMIX Right Mixer PGA Switch", WM8400_LINE_MIXER2,
- WM8400_RROPGARON_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("RONMIX Left Mixer PGA Switch", WM8400_LINE_MIXER2,
- WM8400_RLOPGARON_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("RONMIX Inverted ROP Switch", WM8400_LINE_MIXER2,
- WM8400_ROPRON_SHIFT, 1, 0),
-};
-
-/* ROPMIX */
-static const struct snd_kcontrol_new wm8400_dapm_ropmix_controls[] = {
-SOC_DAPM_SINGLE("ROPMIX Left Mic Bypass Switch", WM8400_LINE_MIXER2,
- WM8400_RL12ROP_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("ROPMIX Right Mic Bypass Switch", WM8400_LINE_MIXER2,
- WM8400_RR12ROP_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("ROPMIX Right Mixer PGA Switch", WM8400_LINE_MIXER2,
- WM8400_RROPGAROP_SHIFT, 1, 0),
-};
-
-/* OUT3MIX */
-static const struct snd_kcontrol_new wm8400_dapm_out3mix_controls[] = {
-SOC_DAPM_SINGLE("OUT3MIX LIN4/RXP Bypass Switch", WM8400_OUT3_4_MIXER,
- WM8400_LI4O3_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("OUT3MIX Left Out PGA Switch", WM8400_OUT3_4_MIXER,
- WM8400_LPGAO3_SHIFT, 1, 0),
-};
-
-/* OUT4MIX */
-static const struct snd_kcontrol_new wm8400_dapm_out4mix_controls[] = {
-SOC_DAPM_SINGLE("OUT4MIX Right Out PGA Switch", WM8400_OUT3_4_MIXER,
- WM8400_RPGAO4_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("OUT4MIX RIN4/RXP Bypass Switch", WM8400_OUT3_4_MIXER,
- WM8400_RI4O4_SHIFT, 1, 0),
-};
-
-/* SPKMIX */
-static const struct snd_kcontrol_new wm8400_dapm_spkmix_controls[] = {
-SOC_DAPM_SINGLE("SPKMIX LIN2 Bypass Switch", WM8400_SPEAKER_MIXER,
- WM8400_LI2SPK_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX LADC Bypass Switch", WM8400_SPEAKER_MIXER,
- WM8400_LB2SPK_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX Left Mixer PGA Switch", WM8400_SPEAKER_MIXER,
- WM8400_LOPGASPK_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX Left DAC Switch", WM8400_SPEAKER_MIXER,
- WM8400_LDSPK_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX Right DAC Switch", WM8400_SPEAKER_MIXER,
- WM8400_RDSPK_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX Right Mixer PGA Switch", WM8400_SPEAKER_MIXER,
- WM8400_ROPGASPK_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX RADC Bypass Switch", WM8400_SPEAKER_MIXER,
- WM8400_RL12ROP_SHIFT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX RIN2 Bypass Switch", WM8400_SPEAKER_MIXER,
- WM8400_RI2SPK_SHIFT, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget wm8400_dapm_widgets[] = {
-/* Input Side */
-/* Input Lines */
-SND_SOC_DAPM_INPUT("LIN1"),
-SND_SOC_DAPM_INPUT("LIN2"),
-SND_SOC_DAPM_INPUT("LIN3"),
-SND_SOC_DAPM_INPUT("LIN4/RXN"),
-SND_SOC_DAPM_INPUT("RIN3"),
-SND_SOC_DAPM_INPUT("RIN4/RXP"),
-SND_SOC_DAPM_INPUT("RIN1"),
-SND_SOC_DAPM_INPUT("RIN2"),
-SND_SOC_DAPM_INPUT("Internal ADC Source"),
-
-/* DACs */
-SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8400_POWER_MANAGEMENT_2,
- WM8400_ADCL_ENA_SHIFT, 0),
-SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8400_POWER_MANAGEMENT_2,
- WM8400_ADCR_ENA_SHIFT, 0),
-
-/* Input PGAs */
-SND_SOC_DAPM_MIXER("LIN12 PGA", WM8400_POWER_MANAGEMENT_2,
- WM8400_LIN12_ENA_SHIFT,
- 0, &wm8400_dapm_lin12_pga_controls[0],
- ARRAY_SIZE(wm8400_dapm_lin12_pga_controls)),
-SND_SOC_DAPM_MIXER("LIN34 PGA", WM8400_POWER_MANAGEMENT_2,
- WM8400_LIN34_ENA_SHIFT,
- 0, &wm8400_dapm_lin34_pga_controls[0],
- ARRAY_SIZE(wm8400_dapm_lin34_pga_controls)),
-SND_SOC_DAPM_MIXER("RIN12 PGA", WM8400_POWER_MANAGEMENT_2,
- WM8400_RIN12_ENA_SHIFT,
- 0, &wm8400_dapm_rin12_pga_controls[0],
- ARRAY_SIZE(wm8400_dapm_rin12_pga_controls)),
-SND_SOC_DAPM_MIXER("RIN34 PGA", WM8400_POWER_MANAGEMENT_2,
- WM8400_RIN34_ENA_SHIFT,
- 0, &wm8400_dapm_rin34_pga_controls[0],
- ARRAY_SIZE(wm8400_dapm_rin34_pga_controls)),
-
-/* INMIXL */
-SND_SOC_DAPM_MIXER_E("INMIXL", WM8400_INTDRIVBITS, WM8400_INMIXL_PWR, 0,
- &wm8400_dapm_inmixl_controls[0],
- ARRAY_SIZE(wm8400_dapm_inmixl_controls),
- inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
-/* AINLMUX */
-SND_SOC_DAPM_MUX_E("AILNMUX", WM8400_INTDRIVBITS, WM8400_AINLMUX_PWR, 0,
- &wm8400_dapm_ainlmux_controls, inmixer_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
-/* INMIXR */
-SND_SOC_DAPM_MIXER_E("INMIXR", WM8400_INTDRIVBITS, WM8400_INMIXR_PWR, 0,
- &wm8400_dapm_inmixr_controls[0],
- ARRAY_SIZE(wm8400_dapm_inmixr_controls),
- inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
-/* AINRMUX */
-SND_SOC_DAPM_MUX_E("AIRNMUX", WM8400_INTDRIVBITS, WM8400_AINRMUX_PWR, 0,
- &wm8400_dapm_ainrmux_controls, inmixer_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
-/* Output Side */
-/* DACs */
-SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8400_POWER_MANAGEMENT_3,
- WM8400_DACL_ENA_SHIFT, 0),
-SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8400_POWER_MANAGEMENT_3,
- WM8400_DACR_ENA_SHIFT, 0),
-
-/* LOMIX */
-SND_SOC_DAPM_MIXER_E("LOMIX", WM8400_POWER_MANAGEMENT_3,
- WM8400_LOMIX_ENA_SHIFT,
- 0, &wm8400_dapm_lomix_controls[0],
- ARRAY_SIZE(wm8400_dapm_lomix_controls),
- outmixer_event, SND_SOC_DAPM_PRE_REG),
-
-/* LONMIX */
-SND_SOC_DAPM_MIXER("LONMIX", WM8400_POWER_MANAGEMENT_3, WM8400_LON_ENA_SHIFT,
- 0, &wm8400_dapm_lonmix_controls[0],
- ARRAY_SIZE(wm8400_dapm_lonmix_controls)),
-
-/* LOPMIX */
-SND_SOC_DAPM_MIXER("LOPMIX", WM8400_POWER_MANAGEMENT_3, WM8400_LOP_ENA_SHIFT,
- 0, &wm8400_dapm_lopmix_controls[0],
- ARRAY_SIZE(wm8400_dapm_lopmix_controls)),
-
-/* OUT3MIX */
-SND_SOC_DAPM_MIXER("OUT3MIX", WM8400_POWER_MANAGEMENT_1, WM8400_OUT3_ENA_SHIFT,
- 0, &wm8400_dapm_out3mix_controls[0],
- ARRAY_SIZE(wm8400_dapm_out3mix_controls)),
-
-/* SPKMIX */
-SND_SOC_DAPM_MIXER_E("SPKMIX", WM8400_POWER_MANAGEMENT_1, WM8400_SPK_ENA_SHIFT,
- 0, &wm8400_dapm_spkmix_controls[0],
- ARRAY_SIZE(wm8400_dapm_spkmix_controls), outmixer_event,
- SND_SOC_DAPM_PRE_REG),
-
-/* OUT4MIX */
-SND_SOC_DAPM_MIXER("OUT4MIX", WM8400_POWER_MANAGEMENT_1, WM8400_OUT4_ENA_SHIFT,
- 0, &wm8400_dapm_out4mix_controls[0],
- ARRAY_SIZE(wm8400_dapm_out4mix_controls)),
-
-/* ROPMIX */
-SND_SOC_DAPM_MIXER("ROPMIX", WM8400_POWER_MANAGEMENT_3, WM8400_ROP_ENA_SHIFT,
- 0, &wm8400_dapm_ropmix_controls[0],
- ARRAY_SIZE(wm8400_dapm_ropmix_controls)),
-
-/* RONMIX */
-SND_SOC_DAPM_MIXER("RONMIX", WM8400_POWER_MANAGEMENT_3, WM8400_RON_ENA_SHIFT,
- 0, &wm8400_dapm_ronmix_controls[0],
- ARRAY_SIZE(wm8400_dapm_ronmix_controls)),
-
-/* ROMIX */
-SND_SOC_DAPM_MIXER_E("ROMIX", WM8400_POWER_MANAGEMENT_3,
- WM8400_ROMIX_ENA_SHIFT,
- 0, &wm8400_dapm_romix_controls[0],
- ARRAY_SIZE(wm8400_dapm_romix_controls),
- outmixer_event, SND_SOC_DAPM_PRE_REG),
-
-/* LOUT PGA */
-SND_SOC_DAPM_PGA("LOUT PGA", WM8400_POWER_MANAGEMENT_1, WM8400_LOUT_ENA_SHIFT,
- 0, NULL, 0),
-
-/* ROUT PGA */
-SND_SOC_DAPM_PGA("ROUT PGA", WM8400_POWER_MANAGEMENT_1, WM8400_ROUT_ENA_SHIFT,
- 0, NULL, 0),
-
-/* LOPGA */
-SND_SOC_DAPM_PGA("LOPGA", WM8400_POWER_MANAGEMENT_3, WM8400_LOPGA_ENA_SHIFT, 0,
- NULL, 0),
-
-/* ROPGA */
-SND_SOC_DAPM_PGA("ROPGA", WM8400_POWER_MANAGEMENT_3, WM8400_ROPGA_ENA_SHIFT, 0,
- NULL, 0),
-
-/* MICBIAS */
-SND_SOC_DAPM_SUPPLY("MICBIAS", WM8400_POWER_MANAGEMENT_1,
- WM8400_MIC1BIAS_ENA_SHIFT, 0, NULL, 0),
-
-SND_SOC_DAPM_OUTPUT("LON"),
-SND_SOC_DAPM_OUTPUT("LOP"),
-SND_SOC_DAPM_OUTPUT("OUT3"),
-SND_SOC_DAPM_OUTPUT("LOUT"),
-SND_SOC_DAPM_OUTPUT("SPKN"),
-SND_SOC_DAPM_OUTPUT("SPKP"),
-SND_SOC_DAPM_OUTPUT("ROUT"),
-SND_SOC_DAPM_OUTPUT("OUT4"),
-SND_SOC_DAPM_OUTPUT("ROP"),
-SND_SOC_DAPM_OUTPUT("RON"),
-
-SND_SOC_DAPM_OUTPUT("Internal DAC Sink"),
-};
-
-static const struct snd_soc_dapm_route wm8400_dapm_routes[] = {
- /* Make DACs turn on when playing even if not mixed into any outputs */
- {"Internal DAC Sink", NULL, "Left DAC"},
- {"Internal DAC Sink", NULL, "Right DAC"},
-
- /* Make ADCs turn on when recording
- * even if not mixed from any inputs */
- {"Left ADC", NULL, "Internal ADC Source"},
- {"Right ADC", NULL, "Internal ADC Source"},
-
- /* Input Side */
- /* LIN12 PGA */
- {"LIN12 PGA", "LIN1 Switch", "LIN1"},
- {"LIN12 PGA", "LIN2 Switch", "LIN2"},
- /* LIN34 PGA */
- {"LIN34 PGA", "LIN3 Switch", "LIN3"},
- {"LIN34 PGA", "LIN4 Switch", "LIN4/RXN"},
- /* INMIXL */
- {"INMIXL", "Record Left Volume", "LOMIX"},
- {"INMIXL", "LIN2 Volume", "LIN2"},
- {"INMIXL", "LINPGA12 Switch", "LIN12 PGA"},
- {"INMIXL", "LINPGA34 Switch", "LIN34 PGA"},
- /* AILNMUX */
- {"AILNMUX", "INMIXL Mix", "INMIXL"},
- {"AILNMUX", "DIFFINL Mix", "LIN12 PGA"},
- {"AILNMUX", "DIFFINL Mix", "LIN34 PGA"},
- {"AILNMUX", "RXVOICE Mix", "LIN4/RXN"},
- {"AILNMUX", "RXVOICE Mix", "RIN4/RXP"},
- /* ADC */
- {"Left ADC", NULL, "AILNMUX"},
-
- /* RIN12 PGA */
- {"RIN12 PGA", "RIN1 Switch", "RIN1"},
- {"RIN12 PGA", "RIN2 Switch", "RIN2"},
- /* RIN34 PGA */
- {"RIN34 PGA", "RIN3 Switch", "RIN3"},
- {"RIN34 PGA", "RIN4 Switch", "RIN4/RXP"},
- /* INMIXL */
- {"INMIXR", "Record Right Volume", "ROMIX"},
- {"INMIXR", "RIN2 Volume", "RIN2"},
- {"INMIXR", "RINPGA12 Switch", "RIN12 PGA"},
- {"INMIXR", "RINPGA34 Switch", "RIN34 PGA"},
- /* AIRNMUX */
- {"AIRNMUX", "INMIXR Mix", "INMIXR"},
- {"AIRNMUX", "DIFFINR Mix", "RIN12 PGA"},
- {"AIRNMUX", "DIFFINR Mix", "RIN34 PGA"},
- {"AIRNMUX", "RXVOICE Mix", "LIN4/RXN"},
- {"AIRNMUX", "RXVOICE Mix", "RIN4/RXP"},
- /* ADC */
- {"Right ADC", NULL, "AIRNMUX"},
-
- /* LOMIX */
- {"LOMIX", "LOMIX RIN3 Bypass Switch", "RIN3"},
- {"LOMIX", "LOMIX LIN3 Bypass Switch", "LIN3"},
- {"LOMIX", "LOMIX LIN12 PGA Bypass Switch", "LIN12 PGA"},
- {"LOMIX", "LOMIX RIN12 PGA Bypass Switch", "RIN12 PGA"},
- {"LOMIX", "LOMIX Right ADC Bypass Switch", "AIRNMUX"},
- {"LOMIX", "LOMIX Left ADC Bypass Switch", "AILNMUX"},
- {"LOMIX", "LOMIX Left DAC Switch", "Left DAC"},
-
- /* ROMIX */
- {"ROMIX", "ROMIX RIN3 Bypass Switch", "RIN3"},
- {"ROMIX", "ROMIX LIN3 Bypass Switch", "LIN3"},
- {"ROMIX", "ROMIX LIN12 PGA Bypass Switch", "LIN12 PGA"},
- {"ROMIX", "ROMIX RIN12 PGA Bypass Switch", "RIN12 PGA"},
- {"ROMIX", "ROMIX Right ADC Bypass Switch", "AIRNMUX"},
- {"ROMIX", "ROMIX Left ADC Bypass Switch", "AILNMUX"},
- {"ROMIX", "ROMIX Right DAC Switch", "Right DAC"},
-
- /* SPKMIX */
- {"SPKMIX", "SPKMIX LIN2 Bypass Switch", "LIN2"},
- {"SPKMIX", "SPKMIX RIN2 Bypass Switch", "RIN2"},
- {"SPKMIX", "SPKMIX LADC Bypass Switch", "AILNMUX"},
- {"SPKMIX", "SPKMIX RADC Bypass Switch", "AIRNMUX"},
- {"SPKMIX", "SPKMIX Left Mixer PGA Switch", "LOPGA"},
- {"SPKMIX", "SPKMIX Right Mixer PGA Switch", "ROPGA"},
- {"SPKMIX", "SPKMIX Right DAC Switch", "Right DAC"},
- {"SPKMIX", "SPKMIX Left DAC Switch", "Right DAC"},
-
- /* LONMIX */
- {"LONMIX", "LONMIX Left Mixer PGA Switch", "LOPGA"},
- {"LONMIX", "LONMIX Right Mixer PGA Switch", "ROPGA"},
- {"LONMIX", "LONMIX Inverted LOP Switch", "LOPMIX"},
-
- /* LOPMIX */
- {"LOPMIX", "LOPMIX Right Mic Bypass Switch", "RIN12 PGA"},
- {"LOPMIX", "LOPMIX Left Mic Bypass Switch", "LIN12 PGA"},
- {"LOPMIX", "LOPMIX Left Mixer PGA Switch", "LOPGA"},
-
- /* OUT3MIX */
- {"OUT3MIX", "OUT3MIX LIN4/RXP Bypass Switch", "LIN4/RXN"},
- {"OUT3MIX", "OUT3MIX Left Out PGA Switch", "LOPGA"},
-
- /* OUT4MIX */
- {"OUT4MIX", "OUT4MIX Right Out PGA Switch", "ROPGA"},
- {"OUT4MIX", "OUT4MIX RIN4/RXP Bypass Switch", "RIN4/RXP"},
-
- /* RONMIX */
- {"RONMIX", "RONMIX Right Mixer PGA Switch", "ROPGA"},
- {"RONMIX", "RONMIX Left Mixer PGA Switch", "LOPGA"},
- {"RONMIX", "RONMIX Inverted ROP Switch", "ROPMIX"},
-
- /* ROPMIX */
- {"ROPMIX", "ROPMIX Left Mic Bypass Switch", "LIN12 PGA"},
- {"ROPMIX", "ROPMIX Right Mic Bypass Switch", "RIN12 PGA"},
- {"ROPMIX", "ROPMIX Right Mixer PGA Switch", "ROPGA"},
-
- /* Out Mixer PGAs */
- {"LOPGA", NULL, "LOMIX"},
- {"ROPGA", NULL, "ROMIX"},
-
- {"LOUT PGA", NULL, "LOMIX"},
- {"ROUT PGA", NULL, "ROMIX"},
-
- /* Output Pins */
- {"LON", NULL, "LONMIX"},
- {"LOP", NULL, "LOPMIX"},
- {"OUT3", NULL, "OUT3MIX"},
- {"LOUT", NULL, "LOUT PGA"},
- {"SPKN", NULL, "SPKMIX"},
- {"ROUT", NULL, "ROUT PGA"},
- {"OUT4", NULL, "OUT4MIX"},
- {"ROP", NULL, "ROPMIX"},
- {"RON", NULL, "RONMIX"},
-};
-
-/*
- * Clock after FLL and dividers
- */
-static int wm8400_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
-
- wm8400->sysclk = freq;
- return 0;
-}
-
-struct fll_factors {
- u16 n;
- u16 k;
- u16 outdiv;
- u16 fratio;
- u16 freq_ref;
-};
-
-#define FIXED_FLL_SIZE ((1 << 16) * 10)
-
-static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors,
- unsigned int Fref, unsigned int Fout)
-{
- u64 Kpart;
- unsigned int K, Nmod, target;
-
- factors->outdiv = 2;
- while (Fout * factors->outdiv < 90000000 ||
- Fout * factors->outdiv > 100000000) {
- factors->outdiv *= 2;
- if (factors->outdiv > 32) {
- dev_err(wm8400->wm8400->dev,
- "Unsupported FLL output frequency %uHz\n",
- Fout);
- return -EINVAL;
- }
- }
- target = Fout * factors->outdiv;
- factors->outdiv = factors->outdiv >> 2;
-
- if (Fref < 48000)
- factors->freq_ref = 1;
- else
- factors->freq_ref = 0;
-
- if (Fref < 1000000)
- factors->fratio = 9;
- else
- factors->fratio = 0;
-
- /* Ensure we have a fractional part */
- do {
- if (Fref < 1000000)
- factors->fratio--;
- else
- factors->fratio++;
-
- if (factors->fratio < 1 || factors->fratio > 8) {
- dev_err(wm8400->wm8400->dev,
- "Unable to calculate FRATIO\n");
- return -EINVAL;
- }
-
- factors->n = target / (Fref * factors->fratio);
- Nmod = target % (Fref * factors->fratio);
- } while (Nmod == 0);
-
- /* Calculate fractional part - scale up so we can round. */
- Kpart = FIXED_FLL_SIZE * (long long)Nmod;
-
- do_div(Kpart, (Fref * factors->fratio));
-
- K = Kpart & 0xFFFFFFFF;
-
- if ((K % 10) >= 5)
- K += 5;
-
- /* Move down to proper range now rounding is done */
- factors->k = K / 10;
-
- dev_dbg(wm8400->wm8400->dev,
- "FLL: Fref=%u Fout=%u N=%x K=%x, FRATIO=%x OUTDIV=%x\n",
- Fref, Fout,
- factors->n, factors->k, factors->fratio, factors->outdiv);
-
- return 0;
-}
-
-static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
- int source, unsigned int freq_in,
- unsigned int freq_out)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
- struct fll_factors factors;
- int ret;
- u16 reg;
-
- if (freq_in == wm8400->fll_in && freq_out == wm8400->fll_out)
- return 0;
-
- if (freq_out) {
- ret = fll_factors(wm8400, &factors, freq_in, freq_out);
- if (ret != 0)
- return ret;
- } else {
- /* Bodge GCC 4.4.0 uninitialised variable warning - it
- * doesn't seem capable of working out that we exit if
- * freq_out is 0 before any of the uses. */
- memset(&factors, 0, sizeof(factors));
- }
-
- wm8400->fll_out = freq_out;
- wm8400->fll_in = freq_in;
-
- /* We *must* disable the FLL before any changes */
- reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_2);
- reg &= ~WM8400_FLL_ENA;
- wm8400_write(codec, WM8400_POWER_MANAGEMENT_2, reg);
-
- reg = wm8400_read(codec, WM8400_FLL_CONTROL_1);
- reg &= ~WM8400_FLL_OSC_ENA;
- wm8400_write(codec, WM8400_FLL_CONTROL_1, reg);
-
- if (!freq_out)
- return 0;
-
- reg &= ~(WM8400_FLL_REF_FREQ | WM8400_FLL_FRATIO_MASK);
- reg |= WM8400_FLL_FRAC | factors.fratio;
- reg |= factors.freq_ref << WM8400_FLL_REF_FREQ_SHIFT;
- wm8400_write(codec, WM8400_FLL_CONTROL_1, reg);
-
- wm8400_write(codec, WM8400_FLL_CONTROL_2, factors.k);
- wm8400_write(codec, WM8400_FLL_CONTROL_3, factors.n);
-
- reg = wm8400_read(codec, WM8400_FLL_CONTROL_4);
- reg &= ~WM8400_FLL_OUTDIV_MASK;
- reg |= factors.outdiv;
- wm8400_write(codec, WM8400_FLL_CONTROL_4, reg);
-
- return 0;
-}
-
-/*
- * Sets ADC and Voice DAC format.
- */
-static int wm8400_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 audio1, audio3;
-
- audio1 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_1);
- audio3 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_3);
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- audio3 &= ~WM8400_AIF_MSTR1;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- audio3 |= WM8400_AIF_MSTR1;
- break;
- default:
- return -EINVAL;
- }
-
- audio1 &= ~WM8400_AIF_FMT_MASK;
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- audio1 |= WM8400_AIF_FMT_I2S;
- audio1 &= ~WM8400_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- audio1 |= WM8400_AIF_FMT_RIGHTJ;
- audio1 &= ~WM8400_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- audio1 |= WM8400_AIF_FMT_LEFTJ;
- audio1 &= ~WM8400_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- audio1 |= WM8400_AIF_FMT_DSP;
- audio1 &= ~WM8400_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- audio1 |= WM8400_AIF_FMT_DSP | WM8400_AIF_LRCLK_INV;
- break;
- default:
- return -EINVAL;
- }
-
- wm8400_write(codec, WM8400_AUDIO_INTERFACE_1, audio1);
- wm8400_write(codec, WM8400_AUDIO_INTERFACE_3, audio3);
- return 0;
-}
-
-static int wm8400_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
- int div_id, int div)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 reg;
-
- switch (div_id) {
- case WM8400_MCLK_DIV:
- reg = wm8400_read(codec, WM8400_CLOCKING_2) &
- ~WM8400_MCLK_DIV_MASK;
- wm8400_write(codec, WM8400_CLOCKING_2, reg | div);
- break;
- case WM8400_DACCLK_DIV:
- reg = wm8400_read(codec, WM8400_CLOCKING_2) &
- ~WM8400_DAC_CLKDIV_MASK;
- wm8400_write(codec, WM8400_CLOCKING_2, reg | div);
- break;
- case WM8400_ADCCLK_DIV:
- reg = wm8400_read(codec, WM8400_CLOCKING_2) &
- ~WM8400_ADC_CLKDIV_MASK;
- wm8400_write(codec, WM8400_CLOCKING_2, reg | div);
- break;
- case WM8400_BCLK_DIV:
- reg = wm8400_read(codec, WM8400_CLOCKING_1) &
- ~WM8400_BCLK_DIV_MASK;
- wm8400_write(codec, WM8400_CLOCKING_1, reg | div);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * Set PCM DAI bit size and sample rate.
- */
-static int wm8400_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- u16 audio1 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_1);
-
- audio1 &= ~WM8400_AIF_WL_MASK;
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- audio1 |= WM8400_AIF_WL_20BITS;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- audio1 |= WM8400_AIF_WL_24BITS;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- audio1 |= WM8400_AIF_WL_32BITS;
- break;
- }
-
- wm8400_write(codec, WM8400_AUDIO_INTERFACE_1, audio1);
- return 0;
-}
-
-static int wm8400_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 val = wm8400_read(codec, WM8400_DAC_CTRL) & ~WM8400_DAC_MUTE;
-
- if (mute)
- wm8400_write(codec, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE);
- else
- wm8400_write(codec, WM8400_DAC_CTRL, val);
-
- return 0;
-}
-
-/* TODO: set bias for best performance at standby */
-static int wm8400_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
- u16 val;
- int ret;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- /* VMID=2*50k */
- val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1) &
- ~WM8400_VMID_MODE_MASK;
- wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val | 0x2);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = regulator_bulk_enable(ARRAY_SIZE(power),
- &power[0]);
- if (ret != 0) {
- dev_err(wm8400->wm8400->dev,
- "Failed to enable regulators: %d\n",
- ret);
- return ret;
- }
-
- wm8400_write(codec, WM8400_POWER_MANAGEMENT_1,
- WM8400_CODEC_ENA | WM8400_SYSCLK_ENA);
-
- /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */
- wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
- WM8400_BUFDCOPEN | WM8400_POBCTRL);
-
- msleep(50);
-
- /* Enable VREF & VMID at 2x50k */
- val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1);
- val |= 0x2 | WM8400_VREF_ENA;
- wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val);
-
- /* Enable BUFIOEN */
- wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
- WM8400_BUFDCOPEN | WM8400_POBCTRL |
- WM8400_BUFIOEN);
-
- /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
- wm8400_write(codec, WM8400_ANTIPOP2, WM8400_BUFIOEN);
- }
-
- /* VMID=2*300k */
- val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1) &
- ~WM8400_VMID_MODE_MASK;
- wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val | 0x4);
- break;
-
- case SND_SOC_BIAS_OFF:
- /* Enable POBCTRL and SOFT_ST */
- wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
- WM8400_POBCTRL | WM8400_BUFIOEN);
-
- /* Enable POBCTRL, SOFT_ST and BUFDCOPEN */
- wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
- WM8400_BUFDCOPEN | WM8400_POBCTRL |
- WM8400_BUFIOEN);
-
- /* mute DAC */
- val = wm8400_read(codec, WM8400_DAC_CTRL);
- wm8400_write(codec, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE);
-
- /* Enable any disabled outputs */
- val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1);
- val |= WM8400_SPK_ENA | WM8400_OUT3_ENA |
- WM8400_OUT4_ENA | WM8400_LOUT_ENA |
- WM8400_ROUT_ENA;
- wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val);
-
- /* Disable VMID */
- val &= ~WM8400_VMID_MODE_MASK;
- wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val);
-
- msleep(300);
-
- /* Enable all output discharge bits */
- wm8400_write(codec, WM8400_ANTIPOP1, WM8400_DIS_LLINE |
- WM8400_DIS_RLINE | WM8400_DIS_OUT3 |
- WM8400_DIS_OUT4 | WM8400_DIS_LOUT |
- WM8400_DIS_ROUT);
-
- /* Disable VREF */
- val &= ~WM8400_VREF_ENA;
- wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val);
-
- /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
- wm8400_write(codec, WM8400_ANTIPOP2, 0x0);
-
- ret = regulator_bulk_disable(ARRAY_SIZE(power),
- &power[0]);
- if (ret != 0)
- return ret;
-
- break;
- }
-
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define WM8400_RATES SNDRV_PCM_RATE_8000_96000
-
-#define WM8400_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops wm8400_dai_ops = {
- .hw_params = wm8400_hw_params,
- .digital_mute = wm8400_mute,
- .set_fmt = wm8400_set_dai_fmt,
- .set_clkdiv = wm8400_set_dai_clkdiv,
- .set_sysclk = wm8400_set_dai_sysclk,
- .set_pll = wm8400_set_dai_pll,
-};
-
-/*
- * The WM8400 supports 2 different and mutually exclusive DAI
- * configurations.
- *
- * 1. ADC/DAC on Primary Interface
- * 2. ADC on Primary Interface/DAC on secondary
- */
-static struct snd_soc_dai_driver wm8400_dai = {
-/* ADC/DAC on primary */
- .name = "wm8400-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8400_RATES,
- .formats = WM8400_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8400_RATES,
- .formats = WM8400_FORMATS,
- },
- .ops = &wm8400_dai_ops,
-};
-
-static int wm8400_suspend(struct snd_soc_codec *codec)
-{
- wm8400_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int wm8400_resume(struct snd_soc_codec *codec)
-{
- wm8400_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-
-static void wm8400_probe_deferred(struct work_struct *work)
-{
- struct wm8400_priv *priv = container_of(work, struct wm8400_priv,
- work);
- struct snd_soc_codec *codec = priv->codec;
-
- /* charge output caps */
- wm8400_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-}
-
-static int wm8400_codec_probe(struct snd_soc_codec *codec)
-{
- struct wm8400 *wm8400 = dev_get_platdata(codec->dev);
- struct wm8400_priv *priv;
- int ret;
- u16 reg;
-
- priv = devm_kzalloc(codec->dev, sizeof(struct wm8400_priv),
- GFP_KERNEL);
- if (priv == NULL)
- return -ENOMEM;
-
- snd_soc_codec_set_drvdata(codec, priv);
- codec->control_data = priv->wm8400 = wm8400;
- priv->codec = codec;
-
- ret = regulator_bulk_get(wm8400->dev,
- ARRAY_SIZE(power), &power[0]);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to get regulators: %d\n", ret);
- return ret;
- }
-
- INIT_WORK(&priv->work, wm8400_probe_deferred);
-
- wm8400_codec_reset(codec);
-
- reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1);
- wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, reg | WM8400_CODEC_ENA);
-
- /* Latch volume update bits */
- reg = wm8400_read(codec, WM8400_LEFT_LINE_INPUT_1_2_VOLUME);
- wm8400_write(codec, WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
- reg & WM8400_IPVU);
- reg = wm8400_read(codec, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME);
- wm8400_write(codec, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
- reg & WM8400_IPVU);
-
- wm8400_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
- wm8400_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
-
- if (!schedule_work(&priv->work)) {
- ret = -EINVAL;
- goto err_regulator;
- }
- return 0;
-
-err_regulator:
- regulator_bulk_free(ARRAY_SIZE(power), power);
- return ret;
-}
-
-static int wm8400_codec_remove(struct snd_soc_codec *codec)
-{
- u16 reg;
-
- reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1);
- wm8400_write(codec, WM8400_POWER_MANAGEMENT_1,
- reg & (~WM8400_CODEC_ENA));
-
- regulator_bulk_free(ARRAY_SIZE(power), power);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8400 = {
- .probe = wm8400_codec_probe,
- .remove = wm8400_codec_remove,
- .suspend = wm8400_suspend,
- .resume = wm8400_resume,
- .read = wm8400_read,
- .write = wm8400_write,
- .set_bias_level = wm8400_set_bias_level,
-
- .controls = wm8400_snd_controls,
- .num_controls = ARRAY_SIZE(wm8400_snd_controls),
- .dapm_widgets = wm8400_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8400_dapm_widgets),
- .dapm_routes = wm8400_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm8400_dapm_routes),
-};
-
-static int __devinit wm8400_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8400,
- &wm8400_dai, 1);
-}
-
-static int __devexit wm8400_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver wm8400_codec_driver = {
- .driver = {
- .name = "wm8400-codec",
- .owner = THIS_MODULE,
- },
- .probe = wm8400_probe,
- .remove = __devexit_p(wm8400_remove),
-};
-
-module_platform_driver(wm8400_codec_driver);
-
-MODULE_DESCRIPTION("ASoC WM8400 driver");
-MODULE_AUTHOR("Mark Brown");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:wm8400-codec");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8400.h b/ANDROID_3.4.5/sound/soc/codecs/wm8400.h
deleted file mode 100644
index 521adb19..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8400.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * wm8400.h -- audio driver for WM8400
- *
- * Copyright 2008 Wolfson Microelectronics PLC.
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#ifndef _WM8400_CODEC_H
-#define _WM8400_CODEC_H
-
-#define WM8400_MCLK_DIV 0
-#define WM8400_DACCLK_DIV 1
-#define WM8400_ADCCLK_DIV 2
-#define WM8400_BCLK_DIV 3
-
-#define WM8400_MCLK_DIV_1 0x400
-#define WM8400_MCLK_DIV_2 0x800
-
-#define WM8400_DAC_CLKDIV_1 0x00
-#define WM8400_DAC_CLKDIV_1_5 0x04
-#define WM8400_DAC_CLKDIV_2 0x08
-#define WM8400_DAC_CLKDIV_3 0x0c
-#define WM8400_DAC_CLKDIV_4 0x10
-#define WM8400_DAC_CLKDIV_5_5 0x14
-#define WM8400_DAC_CLKDIV_6 0x18
-
-#define WM8400_ADC_CLKDIV_1 0x00
-#define WM8400_ADC_CLKDIV_1_5 0x20
-#define WM8400_ADC_CLKDIV_2 0x40
-#define WM8400_ADC_CLKDIV_3 0x60
-#define WM8400_ADC_CLKDIV_4 0x80
-#define WM8400_ADC_CLKDIV_5_5 0xa0
-#define WM8400_ADC_CLKDIV_6 0xc0
-
-
-#define WM8400_BCLK_DIV_1 (0x0 << 1)
-#define WM8400_BCLK_DIV_1_5 (0x1 << 1)
-#define WM8400_BCLK_DIV_2 (0x2 << 1)
-#define WM8400_BCLK_DIV_3 (0x3 << 1)
-#define WM8400_BCLK_DIV_4 (0x4 << 1)
-#define WM8400_BCLK_DIV_5_5 (0x5 << 1)
-#define WM8400_BCLK_DIV_6 (0x6 << 1)
-#define WM8400_BCLK_DIV_8 (0x7 << 1)
-#define WM8400_BCLK_DIV_11 (0x8 << 1)
-#define WM8400_BCLK_DIV_12 (0x9 << 1)
-#define WM8400_BCLK_DIV_16 (0xA << 1)
-#define WM8400_BCLK_DIV_22 (0xB << 1)
-#define WM8400_BCLK_DIV_24 (0xC << 1)
-#define WM8400_BCLK_DIV_32 (0xD << 1)
-#define WM8400_BCLK_DIV_44 (0xE << 1)
-#define WM8400_BCLK_DIV_48 (0xF << 1)
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8510.c b/ANDROID_3.4.5/sound/soc/codecs/wm8510.c
deleted file mode 100644
index 9166126b..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8510.c
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * wm8510.c -- WM8510 ALSA Soc Audio driver
- *
- * Copyright 2006 Wolfson Microelectronics PLC.
- *
- * Author: Liam Girdwood <lrg@slimlogic.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/of_device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-
-#include "wm8510.h"
-
-/*
- * wm8510 register cache
- * We can't read the WM8510 register space when we are
- * using 2 wire for device control, so we cache them instead.
- */
-static const u16 wm8510_reg[WM8510_CACHEREGNUM] = {
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0050, 0x0000, 0x0140, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x00ff,
- 0x0000, 0x0000, 0x0100, 0x00ff,
- 0x0000, 0x0000, 0x012c, 0x002c,
- 0x002c, 0x002c, 0x002c, 0x0000,
- 0x0032, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0038, 0x000b, 0x0032, 0x0000,
- 0x0008, 0x000c, 0x0093, 0x00e9,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0003, 0x0010, 0x0000, 0x0000,
- 0x0000, 0x0002, 0x0001, 0x0000,
- 0x0000, 0x0000, 0x0039, 0x0000,
- 0x0001,
-};
-
-#define WM8510_POWER1_BIASEN 0x08
-#define WM8510_POWER1_BUFIOEN 0x10
-
-#define wm8510_reset(c) snd_soc_write(c, WM8510_RESET, 0)
-
-/* codec private data */
-struct wm8510_priv {
- enum snd_soc_control_type control_type;
-};
-
-static const char *wm8510_companding[] = { "Off", "NC", "u-law", "A-law" };
-static const char *wm8510_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
-static const char *wm8510_alc[] = { "ALC", "Limiter" };
-
-static const struct soc_enum wm8510_enum[] = {
- SOC_ENUM_SINGLE(WM8510_COMP, 1, 4, wm8510_companding), /* adc */
- SOC_ENUM_SINGLE(WM8510_COMP, 3, 4, wm8510_companding), /* dac */
- SOC_ENUM_SINGLE(WM8510_DAC, 4, 4, wm8510_deemp),
- SOC_ENUM_SINGLE(WM8510_ALC3, 8, 2, wm8510_alc),
-};
-
-static const struct snd_kcontrol_new wm8510_snd_controls[] = {
-
-SOC_SINGLE("Digital Loopback Switch", WM8510_COMP, 0, 1, 0),
-
-SOC_ENUM("DAC Companding", wm8510_enum[1]),
-SOC_ENUM("ADC Companding", wm8510_enum[0]),
-
-SOC_ENUM("Playback De-emphasis", wm8510_enum[2]),
-SOC_SINGLE("DAC Inversion Switch", WM8510_DAC, 0, 1, 0),
-
-SOC_SINGLE("Master Playback Volume", WM8510_DACVOL, 0, 127, 0),
-
-SOC_SINGLE("High Pass Filter Switch", WM8510_ADC, 8, 1, 0),
-SOC_SINGLE("High Pass Cut Off", WM8510_ADC, 4, 7, 0),
-SOC_SINGLE("ADC Inversion Switch", WM8510_COMP, 0, 1, 0),
-
-SOC_SINGLE("Capture Volume", WM8510_ADCVOL, 0, 127, 0),
-
-SOC_SINGLE("DAC Playback Limiter Switch", WM8510_DACLIM1, 8, 1, 0),
-SOC_SINGLE("DAC Playback Limiter Decay", WM8510_DACLIM1, 4, 15, 0),
-SOC_SINGLE("DAC Playback Limiter Attack", WM8510_DACLIM1, 0, 15, 0),
-
-SOC_SINGLE("DAC Playback Limiter Threshold", WM8510_DACLIM2, 4, 7, 0),
-SOC_SINGLE("DAC Playback Limiter Boost", WM8510_DACLIM2, 0, 15, 0),
-
-SOC_SINGLE("ALC Enable Switch", WM8510_ALC1, 8, 1, 0),
-SOC_SINGLE("ALC Capture Max Gain", WM8510_ALC1, 3, 7, 0),
-SOC_SINGLE("ALC Capture Min Gain", WM8510_ALC1, 0, 7, 0),
-
-SOC_SINGLE("ALC Capture ZC Switch", WM8510_ALC2, 8, 1, 0),
-SOC_SINGLE("ALC Capture Hold", WM8510_ALC2, 4, 7, 0),
-SOC_SINGLE("ALC Capture Target", WM8510_ALC2, 0, 15, 0),
-
-SOC_ENUM("ALC Capture Mode", wm8510_enum[3]),
-SOC_SINGLE("ALC Capture Decay", WM8510_ALC3, 4, 15, 0),
-SOC_SINGLE("ALC Capture Attack", WM8510_ALC3, 0, 15, 0),
-
-SOC_SINGLE("ALC Capture Noise Gate Switch", WM8510_NGATE, 3, 1, 0),
-SOC_SINGLE("ALC Capture Noise Gate Threshold", WM8510_NGATE, 0, 7, 0),
-
-SOC_SINGLE("Capture PGA ZC Switch", WM8510_INPPGA, 7, 1, 0),
-SOC_SINGLE("Capture PGA Volume", WM8510_INPPGA, 0, 63, 0),
-
-SOC_SINGLE("Speaker Playback ZC Switch", WM8510_SPKVOL, 7, 1, 0),
-SOC_SINGLE("Speaker Playback Switch", WM8510_SPKVOL, 6, 1, 1),
-SOC_SINGLE("Speaker Playback Volume", WM8510_SPKVOL, 0, 63, 0),
-SOC_SINGLE("Speaker Boost", WM8510_OUTPUT, 2, 1, 0),
-
-SOC_SINGLE("Capture Boost(+20dB)", WM8510_ADCBOOST, 8, 1, 0),
-SOC_SINGLE("Mono Playback Switch", WM8510_MONOMIX, 6, 1, 1),
-};
-
-/* Speaker Output Mixer */
-static const struct snd_kcontrol_new wm8510_speaker_mixer_controls[] = {
-SOC_DAPM_SINGLE("Line Bypass Switch", WM8510_SPKMIX, 1, 1, 0),
-SOC_DAPM_SINGLE("Aux Playback Switch", WM8510_SPKMIX, 5, 1, 0),
-SOC_DAPM_SINGLE("PCM Playback Switch", WM8510_SPKMIX, 0, 1, 0),
-};
-
-/* Mono Output Mixer */
-static const struct snd_kcontrol_new wm8510_mono_mixer_controls[] = {
-SOC_DAPM_SINGLE("Line Bypass Switch", WM8510_MONOMIX, 1, 1, 0),
-SOC_DAPM_SINGLE("Aux Playback Switch", WM8510_MONOMIX, 2, 1, 0),
-SOC_DAPM_SINGLE("PCM Playback Switch", WM8510_MONOMIX, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8510_boost_controls[] = {
-SOC_DAPM_SINGLE("Mic PGA Switch", WM8510_INPPGA, 6, 1, 1),
-SOC_DAPM_SINGLE("Aux Volume", WM8510_ADCBOOST, 0, 7, 0),
-SOC_DAPM_SINGLE("Mic Volume", WM8510_ADCBOOST, 4, 7, 0),
-};
-
-static const struct snd_kcontrol_new wm8510_micpga_controls[] = {
-SOC_DAPM_SINGLE("MICP Switch", WM8510_INPUT, 0, 1, 0),
-SOC_DAPM_SINGLE("MICN Switch", WM8510_INPUT, 1, 1, 0),
-SOC_DAPM_SINGLE("AUX Switch", WM8510_INPUT, 2, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget wm8510_dapm_widgets[] = {
-SND_SOC_DAPM_MIXER("Speaker Mixer", WM8510_POWER3, 2, 0,
- &wm8510_speaker_mixer_controls[0],
- ARRAY_SIZE(wm8510_speaker_mixer_controls)),
-SND_SOC_DAPM_MIXER("Mono Mixer", WM8510_POWER3, 3, 0,
- &wm8510_mono_mixer_controls[0],
- ARRAY_SIZE(wm8510_mono_mixer_controls)),
-SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8510_POWER3, 0, 0),
-SND_SOC_DAPM_ADC("ADC", "HiFi Capture", WM8510_POWER2, 0, 0),
-SND_SOC_DAPM_PGA("Aux Input", WM8510_POWER1, 6, 0, NULL, 0),
-SND_SOC_DAPM_PGA("SpkN Out", WM8510_POWER3, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA("SpkP Out", WM8510_POWER3, 6, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Mono Out", WM8510_POWER3, 7, 0, NULL, 0),
-
-SND_SOC_DAPM_MIXER("Mic PGA", WM8510_POWER2, 2, 0,
- &wm8510_micpga_controls[0],
- ARRAY_SIZE(wm8510_micpga_controls)),
-SND_SOC_DAPM_MIXER("Boost Mixer", WM8510_POWER2, 4, 0,
- &wm8510_boost_controls[0],
- ARRAY_SIZE(wm8510_boost_controls)),
-
-SND_SOC_DAPM_MICBIAS("Mic Bias", WM8510_POWER1, 4, 0),
-
-SND_SOC_DAPM_INPUT("MICN"),
-SND_SOC_DAPM_INPUT("MICP"),
-SND_SOC_DAPM_INPUT("AUX"),
-SND_SOC_DAPM_OUTPUT("MONOOUT"),
-SND_SOC_DAPM_OUTPUT("SPKOUTP"),
-SND_SOC_DAPM_OUTPUT("SPKOUTN"),
-};
-
-static const struct snd_soc_dapm_route wm8510_dapm_routes[] = {
- /* Mono output mixer */
- {"Mono Mixer", "PCM Playback Switch", "DAC"},
- {"Mono Mixer", "Aux Playback Switch", "Aux Input"},
- {"Mono Mixer", "Line Bypass Switch", "Boost Mixer"},
-
- /* Speaker output mixer */
- {"Speaker Mixer", "PCM Playback Switch", "DAC"},
- {"Speaker Mixer", "Aux Playback Switch", "Aux Input"},
- {"Speaker Mixer", "Line Bypass Switch", "Boost Mixer"},
-
- /* Outputs */
- {"Mono Out", NULL, "Mono Mixer"},
- {"MONOOUT", NULL, "Mono Out"},
- {"SpkN Out", NULL, "Speaker Mixer"},
- {"SpkP Out", NULL, "Speaker Mixer"},
- {"SPKOUTN", NULL, "SpkN Out"},
- {"SPKOUTP", NULL, "SpkP Out"},
-
- /* Microphone PGA */
- {"Mic PGA", "MICN Switch", "MICN"},
- {"Mic PGA", "MICP Switch", "MICP"},
- { "Mic PGA", "AUX Switch", "Aux Input" },
-
- /* Boost Mixer */
- {"Boost Mixer", "Mic PGA Switch", "Mic PGA"},
- {"Boost Mixer", "Mic Volume", "MICP"},
- {"Boost Mixer", "Aux Volume", "Aux Input"},
-
- {"ADC", NULL, "Boost Mixer"},
-};
-
-struct pll_ {
- unsigned int pre_div:4; /* prescale - 1 */
- unsigned int n:4;
- unsigned int k;
-};
-
-static struct pll_ pll_div;
-
-/* The size in bits of the pll divide multiplied by 10
- * to allow rounding later */
-#define FIXED_PLL_SIZE ((1 << 24) * 10)
-
-static void pll_factors(unsigned int target, unsigned int source)
-{
- unsigned long long Kpart;
- unsigned int K, Ndiv, Nmod;
-
- Ndiv = target / source;
- if (Ndiv < 6) {
- source >>= 1;
- pll_div.pre_div = 1;
- Ndiv = target / source;
- } else
- pll_div.pre_div = 0;
-
- if ((Ndiv < 6) || (Ndiv > 12))
- printk(KERN_WARNING
- "WM8510 N value %u outwith recommended range!d\n",
- Ndiv);
-
- pll_div.n = Ndiv;
- Nmod = target % source;
- Kpart = FIXED_PLL_SIZE * (long long)Nmod;
-
- do_div(Kpart, source);
-
- K = Kpart & 0xFFFFFFFF;
-
- /* Check if we need to round */
- if ((K % 10) >= 5)
- K += 5;
-
- /* Move down to proper range now rounding is done */
- K /= 10;
-
- pll_div.k = K;
-}
-
-static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
- int source, unsigned int freq_in, unsigned int freq_out)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 reg;
-
- if (freq_in == 0 || freq_out == 0) {
- /* Clock CODEC directly from MCLK */
- reg = snd_soc_read(codec, WM8510_CLOCK);
- snd_soc_write(codec, WM8510_CLOCK, reg & 0x0ff);
-
- /* Turn off PLL */
- reg = snd_soc_read(codec, WM8510_POWER1);
- snd_soc_write(codec, WM8510_POWER1, reg & 0x1df);
- return 0;
- }
-
- pll_factors(freq_out*4, freq_in);
-
- snd_soc_write(codec, WM8510_PLLN, (pll_div.pre_div << 4) | pll_div.n);
- snd_soc_write(codec, WM8510_PLLK1, pll_div.k >> 18);
- snd_soc_write(codec, WM8510_PLLK2, (pll_div.k >> 9) & 0x1ff);
- snd_soc_write(codec, WM8510_PLLK3, pll_div.k & 0x1ff);
- reg = snd_soc_read(codec, WM8510_POWER1);
- snd_soc_write(codec, WM8510_POWER1, reg | 0x020);
-
- /* Run CODEC from PLL instead of MCLK */
- reg = snd_soc_read(codec, WM8510_CLOCK);
- snd_soc_write(codec, WM8510_CLOCK, reg | 0x100);
-
- return 0;
-}
-
-/*
- * Configure WM8510 clock dividers.
- */
-static int wm8510_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
- int div_id, int div)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 reg;
-
- switch (div_id) {
- case WM8510_OPCLKDIV:
- reg = snd_soc_read(codec, WM8510_GPIO) & 0x1cf;
- snd_soc_write(codec, WM8510_GPIO, reg | div);
- break;
- case WM8510_MCLKDIV:
- reg = snd_soc_read(codec, WM8510_CLOCK) & 0x11f;
- snd_soc_write(codec, WM8510_CLOCK, reg | div);
- break;
- case WM8510_ADCCLK:
- reg = snd_soc_read(codec, WM8510_ADC) & 0x1f7;
- snd_soc_write(codec, WM8510_ADC, reg | div);
- break;
- case WM8510_DACCLK:
- reg = snd_soc_read(codec, WM8510_DAC) & 0x1f7;
- snd_soc_write(codec, WM8510_DAC, reg | div);
- break;
- case WM8510_BCLKDIV:
- reg = snd_soc_read(codec, WM8510_CLOCK) & 0x1e3;
- snd_soc_write(codec, WM8510_CLOCK, reg | div);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int wm8510_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 iface = 0;
- u16 clk = snd_soc_read(codec, WM8510_CLOCK) & 0x1fe;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- clk |= 0x0001;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= 0x0010;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= 0x0008;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= 0x00018;
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= 0x0180;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= 0x0100;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- iface |= 0x0080;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM8510_IFACE, iface);
- snd_soc_write(codec, WM8510_CLOCK, clk);
- return 0;
-}
-
-static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- u16 iface = snd_soc_read(codec, WM8510_IFACE) & 0x19f;
- u16 adn = snd_soc_read(codec, WM8510_ADD) & 0x1f1;
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= 0x0020;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface |= 0x0040;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- iface |= 0x0060;
- break;
- }
-
- /* filter coefficient */
- switch (params_rate(params)) {
- case 8000:
- adn |= 0x5 << 1;
- break;
- case 11025:
- adn |= 0x4 << 1;
- break;
- case 16000:
- adn |= 0x3 << 1;
- break;
- case 22050:
- adn |= 0x2 << 1;
- break;
- case 32000:
- adn |= 0x1 << 1;
- break;
- case 44100:
- case 48000:
- break;
- }
-
- snd_soc_write(codec, WM8510_IFACE, iface);
- snd_soc_write(codec, WM8510_ADD, adn);
- return 0;
-}
-
-static int wm8510_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 mute_reg = snd_soc_read(codec, WM8510_DAC) & 0xffbf;
-
- if (mute)
- snd_soc_write(codec, WM8510_DAC, mute_reg | 0x40);
- else
- snd_soc_write(codec, WM8510_DAC, mute_reg);
- return 0;
-}
-
-/* liam need to make this lower power with dapm */
-static int wm8510_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- u16 power1 = snd_soc_read(codec, WM8510_POWER1) & ~0x3;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- case SND_SOC_BIAS_PREPARE:
- power1 |= 0x1; /* VMID 50k */
- snd_soc_write(codec, WM8510_POWER1, power1);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN;
-
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- snd_soc_cache_sync(codec);
-
- /* Initial cap charge at VMID 5k */
- snd_soc_write(codec, WM8510_POWER1, power1 | 0x3);
- mdelay(100);
- }
-
- power1 |= 0x2; /* VMID 500k */
- snd_soc_write(codec, WM8510_POWER1, power1);
- break;
-
- case SND_SOC_BIAS_OFF:
- snd_soc_write(codec, WM8510_POWER1, 0);
- snd_soc_write(codec, WM8510_POWER2, 0);
- snd_soc_write(codec, WM8510_POWER3, 0);
- break;
- }
-
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define WM8510_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
-
-#define WM8510_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops wm8510_dai_ops = {
- .hw_params = wm8510_pcm_hw_params,
- .digital_mute = wm8510_mute,
- .set_fmt = wm8510_set_dai_fmt,
- .set_clkdiv = wm8510_set_dai_clkdiv,
- .set_pll = wm8510_set_dai_pll,
-};
-
-static struct snd_soc_dai_driver wm8510_dai = {
- .name = "wm8510-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = WM8510_RATES,
- .formats = WM8510_FORMATS,},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = WM8510_RATES,
- .formats = WM8510_FORMATS,},
- .ops = &wm8510_dai_ops,
- .symmetric_rates = 1,
-};
-
-static int wm8510_suspend(struct snd_soc_codec *codec)
-{
- wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm8510_resume(struct snd_soc_codec *codec)
-{
- wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-
-static int wm8510_probe(struct snd_soc_codec *codec)
-{
- struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8510->control_type);
- if (ret < 0) {
- printk(KERN_ERR "wm8510: failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- wm8510_reset(codec);
-
- /* power on device */
- wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return ret;
-}
-
-/* power down chip */
-static int wm8510_remove(struct snd_soc_codec *codec)
-{
- struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec);
-
- wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF);
- kfree(wm8510);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8510 = {
- .probe = wm8510_probe,
- .remove = wm8510_remove,
- .suspend = wm8510_suspend,
- .resume = wm8510_resume,
- .set_bias_level = wm8510_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8510_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_default =wm8510_reg,
-
- .controls = wm8510_snd_controls,
- .num_controls = ARRAY_SIZE(wm8510_snd_controls),
- .dapm_widgets = wm8510_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8510_dapm_widgets),
- .dapm_routes = wm8510_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm8510_dapm_routes),
-};
-
-static const struct of_device_id wm8510_of_match[] = {
- { .compatible = "wlf,wm8510" },
- { },
-};
-
-#if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8510_spi_probe(struct spi_device *spi)
-{
- struct wm8510_priv *wm8510;
- int ret;
-
- wm8510 = kzalloc(sizeof(struct wm8510_priv), GFP_KERNEL);
- if (wm8510 == NULL)
- return -ENOMEM;
-
- wm8510->control_type = SND_SOC_SPI;
- spi_set_drvdata(spi, wm8510);
-
- ret = snd_soc_register_codec(&spi->dev,
- &soc_codec_dev_wm8510, &wm8510_dai, 1);
- if (ret < 0)
- kfree(wm8510);
- return ret;
-}
-
-static int __devexit wm8510_spi_remove(struct spi_device *spi)
-{
- snd_soc_unregister_codec(&spi->dev);
- return 0;
-}
-
-static struct spi_driver wm8510_spi_driver = {
- .driver = {
- .name = "wm8510",
- .owner = THIS_MODULE,
- .of_match_table = wm8510_of_match,
- },
- .probe = wm8510_spi_probe,
- .remove = __devexit_p(wm8510_spi_remove),
-};
-#endif /* CONFIG_SPI_MASTER */
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8510_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8510_priv *wm8510;
- int ret;
-
- wm8510 = kzalloc(sizeof(struct wm8510_priv), GFP_KERNEL);
- if (wm8510 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm8510);
- wm8510->control_type = SND_SOC_I2C;
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8510, &wm8510_dai, 1);
- if (ret < 0)
- kfree(wm8510);
- return ret;
-}
-
-static __devexit int wm8510_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static const struct i2c_device_id wm8510_i2c_id[] = {
- { "wm8510", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8510_i2c_id);
-
-static struct i2c_driver wm8510_i2c_driver = {
- .driver = {
- .name = "wm8510",
- .owner = THIS_MODULE,
- .of_match_table = wm8510_of_match,
- },
- .probe = wm8510_i2c_probe,
- .remove = __devexit_p(wm8510_i2c_remove),
- .id_table = wm8510_i2c_id,
-};
-#endif
-
-static int __init wm8510_modinit(void)
-{
- int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&wm8510_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8510 I2C driver: %d\n",
- ret);
- }
-#endif
-#if defined(CONFIG_SPI_MASTER)
- ret = spi_register_driver(&wm8510_spi_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8510 SPI driver: %d\n",
- ret);
- }
-#endif
- return ret;
-}
-module_init(wm8510_modinit);
-
-static void __exit wm8510_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&wm8510_i2c_driver);
-#endif
-#if defined(CONFIG_SPI_MASTER)
- spi_unregister_driver(&wm8510_spi_driver);
-#endif
-}
-module_exit(wm8510_exit);
-
-MODULE_DESCRIPTION("ASoC WM8510 driver");
-MODULE_AUTHOR("Liam Girdwood");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8510.h b/ANDROID_3.4.5/sound/soc/codecs/wm8510.h
deleted file mode 100644
index b3e26ed9..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8510.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * wm8510.h -- WM8510 Soc Audio driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8510_H
-#define _WM8510_H
-
-/* WM8510 register space */
-
-#define WM8510_RESET 0x0
-#define WM8510_POWER1 0x1
-#define WM8510_POWER2 0x2
-#define WM8510_POWER3 0x3
-#define WM8510_IFACE 0x4
-#define WM8510_COMP 0x5
-#define WM8510_CLOCK 0x6
-#define WM8510_ADD 0x7
-#define WM8510_GPIO 0x8
-#define WM8510_DAC 0xa
-#define WM8510_DACVOL 0xb
-#define WM8510_ADC 0xe
-#define WM8510_ADCVOL 0xf
-#define WM8510_EQ1 0x12
-#define WM8510_EQ2 0x13
-#define WM8510_EQ3 0x14
-#define WM8510_EQ4 0x15
-#define WM8510_EQ5 0x16
-#define WM8510_DACLIM1 0x18
-#define WM8510_DACLIM2 0x19
-#define WM8510_NOTCH1 0x1b
-#define WM8510_NOTCH2 0x1c
-#define WM8510_NOTCH3 0x1d
-#define WM8510_NOTCH4 0x1e
-#define WM8510_ALC1 0x20
-#define WM8510_ALC2 0x21
-#define WM8510_ALC3 0x22
-#define WM8510_NGATE 0x23
-#define WM8510_PLLN 0x24
-#define WM8510_PLLK1 0x25
-#define WM8510_PLLK2 0x26
-#define WM8510_PLLK3 0x27
-#define WM8510_ATTEN 0x28
-#define WM8510_INPUT 0x2c
-#define WM8510_INPPGA 0x2d
-#define WM8510_ADCBOOST 0x2f
-#define WM8510_OUTPUT 0x31
-#define WM8510_SPKMIX 0x32
-#define WM8510_SPKVOL 0x36
-#define WM8510_MONOMIX 0x38
-
-#define WM8510_CACHEREGNUM 57
-
-/* Clock divider Id's */
-#define WM8510_OPCLKDIV 0
-#define WM8510_MCLKDIV 1
-#define WM8510_ADCCLK 2
-#define WM8510_DACCLK 3
-#define WM8510_BCLKDIV 4
-
-/* DAC clock dividers */
-#define WM8510_DACCLK_F2 (1 << 3)
-#define WM8510_DACCLK_F4 (0 << 3)
-
-/* ADC clock dividers */
-#define WM8510_ADCCLK_F2 (1 << 3)
-#define WM8510_ADCCLK_F4 (0 << 3)
-
-/* PLL Out dividers */
-#define WM8510_OPCLKDIV_1 (0 << 4)
-#define WM8510_OPCLKDIV_2 (1 << 4)
-#define WM8510_OPCLKDIV_3 (2 << 4)
-#define WM8510_OPCLKDIV_4 (3 << 4)
-
-/* BCLK clock dividers */
-#define WM8510_BCLKDIV_1 (0 << 2)
-#define WM8510_BCLKDIV_2 (1 << 2)
-#define WM8510_BCLKDIV_4 (2 << 2)
-#define WM8510_BCLKDIV_8 (3 << 2)
-#define WM8510_BCLKDIV_16 (4 << 2)
-#define WM8510_BCLKDIV_32 (5 << 2)
-
-/* MCLK clock dividers */
-#define WM8510_MCLKDIV_1 (0 << 5)
-#define WM8510_MCLKDIV_1_5 (1 << 5)
-#define WM8510_MCLKDIV_2 (2 << 5)
-#define WM8510_MCLKDIV_3 (3 << 5)
-#define WM8510_MCLKDIV_4 (4 << 5)
-#define WM8510_MCLKDIV_6 (5 << 5)
-#define WM8510_MCLKDIV_8 (6 << 5)
-#define WM8510_MCLKDIV_12 (7 << 5)
-
-struct wm8510_setup_data {
- int spi;
- int i2c_bus;
- unsigned short i2c_address;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8523.c b/ANDROID_3.4.5/sound/soc/codecs/wm8523.c
deleted file mode 100644
index 7fea2c3b..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8523.c
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
- * wm8523.c -- WM8523 ALSA SoC Audio driver
- *
- * Copyright 2009 Wolfson Microelectronics plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <linux/of_device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "wm8523.h"
-
-#define WM8523_NUM_SUPPLIES 2
-static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = {
- "AVDD",
- "LINEVDD",
-};
-
-#define WM8523_NUM_RATES 7
-
-/* codec private data */
-struct wm8523_priv {
- enum snd_soc_control_type control_type;
- struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES];
- unsigned int sysclk;
- unsigned int rate_constraint_list[WM8523_NUM_RATES];
- struct snd_pcm_hw_constraint_list rate_constraint;
-};
-
-static const u16 wm8523_reg[WM8523_REGISTER_COUNT] = {
- 0x8523, /* R0 - DEVICE_ID */
- 0x0001, /* R1 - REVISION */
- 0x0000, /* R2 - PSCTRL1 */
- 0x1812, /* R3 - AIF_CTRL1 */
- 0x0000, /* R4 - AIF_CTRL2 */
- 0x0001, /* R5 - DAC_CTRL3 */
- 0x0190, /* R6 - DAC_GAINL */
- 0x0190, /* R7 - DAC_GAINR */
- 0x0000, /* R8 - ZERO_DETECT */
-};
-
-static int wm8523_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
-{
- switch (reg) {
- case WM8523_DEVICE_ID:
- case WM8523_REVISION:
- return 1;
- default:
- return 0;
- }
-}
-
-static int wm8523_reset(struct snd_soc_codec *codec)
-{
- return snd_soc_write(codec, WM8523_DEVICE_ID, 0);
-}
-
-static const DECLARE_TLV_DB_SCALE(dac_tlv, -10000, 25, 0);
-
-static const char *wm8523_zd_count_text[] = {
- "1024",
- "2048",
-};
-
-static const struct soc_enum wm8523_zc_count =
- SOC_ENUM_SINGLE(WM8523_ZERO_DETECT, 0, 2, wm8523_zd_count_text);
-
-static const struct snd_kcontrol_new wm8523_controls[] = {
-SOC_DOUBLE_R_TLV("Playback Volume", WM8523_DAC_GAINL, WM8523_DAC_GAINR,
- 0, 448, 0, dac_tlv),
-SOC_SINGLE("ZC Switch", WM8523_DAC_CTRL3, 4, 1, 0),
-SOC_SINGLE("Playback Deemphasis Switch", WM8523_AIF_CTRL1, 8, 1, 0),
-SOC_DOUBLE("Playback Switch", WM8523_DAC_CTRL3, 2, 3, 1, 1),
-SOC_SINGLE("Volume Ramp Up Switch", WM8523_DAC_CTRL3, 1, 1, 0),
-SOC_SINGLE("Volume Ramp Down Switch", WM8523_DAC_CTRL3, 0, 1, 0),
-SOC_ENUM("Zero Detect Count", wm8523_zc_count),
-};
-
-static const struct snd_soc_dapm_widget wm8523_dapm_widgets[] = {
-SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_OUTPUT("LINEVOUTL"),
-SND_SOC_DAPM_OUTPUT("LINEVOUTR"),
-};
-
-static const struct snd_soc_dapm_route wm8523_dapm_routes[] = {
- { "LINEVOUTL", NULL, "DAC" },
- { "LINEVOUTR", NULL, "DAC" },
-};
-
-static struct {
- int value;
- int ratio;
-} lrclk_ratios[WM8523_NUM_RATES] = {
- { 1, 128 },
- { 2, 192 },
- { 3, 256 },
- { 4, 384 },
- { 5, 512 },
- { 6, 768 },
- { 7, 1152 },
-};
-
-static int wm8523_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
-
- /* The set of sample rates that can be supported depends on the
- * MCLK supplied to the CODEC - enforce this.
- */
- if (!wm8523->sysclk) {
- dev_err(codec->dev,
- "No MCLK configured, call set_sysclk() on init\n");
- return -EINVAL;
- }
-
- snd_pcm_hw_constraint_list(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- &wm8523->rate_constraint);
-
- return 0;
-}
-
-static int wm8523_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
- int i;
- u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1);
- u16 aifctrl2 = snd_soc_read(codec, WM8523_AIF_CTRL2);
-
- /* Find a supported LRCLK ratio */
- for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
- if (wm8523->sysclk / params_rate(params) ==
- lrclk_ratios[i].ratio)
- break;
- }
-
- /* Should never happen, should be handled by constraints */
- if (i == ARRAY_SIZE(lrclk_ratios)) {
- dev_err(codec->dev, "MCLK/fs ratio %d unsupported\n",
- wm8523->sysclk / params_rate(params));
- return -EINVAL;
- }
-
- aifctrl2 &= ~WM8523_SR_MASK;
- aifctrl2 |= lrclk_ratios[i].value;
-
- aifctrl1 &= ~WM8523_WL_MASK;
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- aifctrl1 |= 0x8;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- aifctrl1 |= 0x10;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- aifctrl1 |= 0x18;
- break;
- }
-
- snd_soc_write(codec, WM8523_AIF_CTRL1, aifctrl1);
- snd_soc_write(codec, WM8523_AIF_CTRL2, aifctrl2);
-
- return 0;
-}
-
-static int wm8523_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
- unsigned int val;
- int i;
-
- wm8523->sysclk = freq;
-
- wm8523->rate_constraint.count = 0;
- for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
- val = freq / lrclk_ratios[i].ratio;
- /* Check that it's a standard rate since core can't
- * cope with others and having the odd rates confuses
- * constraint matching.
- */
- switch (val) {
- case 8000:
- case 11025:
- case 16000:
- case 22050:
- case 32000:
- case 44100:
- case 48000:
- case 64000:
- case 88200:
- case 96000:
- case 176400:
- case 192000:
- dev_dbg(codec->dev, "Supported sample rate: %dHz\n",
- val);
- wm8523->rate_constraint_list[i] = val;
- wm8523->rate_constraint.count++;
- break;
- default:
- dev_dbg(codec->dev, "Skipping sample rate: %dHz\n",
- val);
- }
- }
-
- /* Need at least one supported rate... */
- if (wm8523->rate_constraint.count == 0)
- return -EINVAL;
-
- return 0;
-}
-
-
-static int wm8523_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1);
-
- aifctrl1 &= ~(WM8523_BCLK_INV_MASK | WM8523_LRCLK_INV_MASK |
- WM8523_FMT_MASK | WM8523_AIF_MSTR_MASK);
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- aifctrl1 |= WM8523_AIF_MSTR;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- aifctrl1 |= 0x0002;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- aifctrl1 |= 0x0001;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- aifctrl1 |= 0x0003;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- aifctrl1 |= 0x0023;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- aifctrl1 |= WM8523_BCLK_INV | WM8523_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- aifctrl1 |= WM8523_BCLK_INV;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- aifctrl1 |= WM8523_LRCLK_INV;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM8523_AIF_CTRL1, aifctrl1);
-
- return 0;
-}
-
-static int wm8523_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
- u16 *reg_cache = codec->reg_cache;
- int ret, i;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- /* Full power on */
- snd_soc_update_bits(codec, WM8523_PSCTRL1,
- WM8523_SYS_ENA_MASK, 3);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
- wm8523->supplies);
- if (ret != 0) {
- dev_err(codec->dev,
- "Failed to enable supplies: %d\n",
- ret);
- return ret;
- }
-
- /* Initial power up */
- snd_soc_update_bits(codec, WM8523_PSCTRL1,
- WM8523_SYS_ENA_MASK, 1);
-
- /* Sync back default/cached values */
- for (i = WM8523_AIF_CTRL1;
- i < WM8523_MAX_REGISTER; i++)
- snd_soc_write(codec, i, reg_cache[i]);
-
-
- msleep(100);
- }
-
- /* Power up to mute */
- snd_soc_update_bits(codec, WM8523_PSCTRL1,
- WM8523_SYS_ENA_MASK, 2);
-
- break;
-
- case SND_SOC_BIAS_OFF:
- /* The chip runs through the power down sequence for us. */
- snd_soc_update_bits(codec, WM8523_PSCTRL1,
- WM8523_SYS_ENA_MASK, 0);
- msleep(100);
-
- regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies),
- wm8523->supplies);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define WM8523_RATES SNDRV_PCM_RATE_8000_192000
-
-#define WM8523_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops wm8523_dai_ops = {
- .startup = wm8523_startup,
- .hw_params = wm8523_hw_params,
- .set_sysclk = wm8523_set_dai_sysclk,
- .set_fmt = wm8523_set_dai_fmt,
-};
-
-static struct snd_soc_dai_driver wm8523_dai = {
- .name = "wm8523-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2, /* Mono modes not yet supported */
- .channels_max = 2,
- .rates = WM8523_RATES,
- .formats = WM8523_FORMATS,
- },
- .ops = &wm8523_dai_ops,
-};
-
-#ifdef CONFIG_PM
-static int wm8523_suspend(struct snd_soc_codec *codec)
-{
- wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm8523_resume(struct snd_soc_codec *codec)
-{
- wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-#else
-#define wm8523_suspend NULL
-#define wm8523_resume NULL
-#endif
-
-static int wm8523_probe(struct snd_soc_codec *codec)
-{
- struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
- int ret, i;
-
- wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0];
- wm8523->rate_constraint.count =
- ARRAY_SIZE(wm8523->rate_constraint_list);
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8523->control_type);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++)
- wm8523->supplies[i].supply = wm8523_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8523->supplies),
- wm8523->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- return ret;
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
- wm8523->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
- goto err_get;
- }
-
- ret = snd_soc_read(codec, WM8523_DEVICE_ID);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to read ID register\n");
- goto err_enable;
- }
- if (ret != wm8523_reg[WM8523_DEVICE_ID]) {
- dev_err(codec->dev, "Device is not a WM8523, ID is %x\n", ret);
- ret = -EINVAL;
- goto err_enable;
- }
-
- ret = snd_soc_read(codec, WM8523_REVISION);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to read revision register\n");
- goto err_enable;
- }
- dev_info(codec->dev, "revision %c\n",
- (ret & WM8523_CHIP_REV_MASK) + 'A');
-
- ret = wm8523_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- goto err_enable;
- }
-
- /* Change some default settings - latch VU and enable ZC */
- snd_soc_update_bits(codec, WM8523_DAC_GAINR,
- WM8523_DACR_VU, WM8523_DACR_VU);
- snd_soc_update_bits(codec, WM8523_DAC_CTRL3, WM8523_ZC, WM8523_ZC);
-
- wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* Bias level configuration will have done an extra enable */
- regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
-
- return 0;
-
-err_enable:
- regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
-err_get:
- regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
-
- return ret;
-}
-
-static int wm8523_remove(struct snd_soc_codec *codec)
-{
- struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
-
- wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF);
- regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8523 = {
- .probe = wm8523_probe,
- .remove = wm8523_remove,
- .suspend = wm8523_suspend,
- .resume = wm8523_resume,
- .set_bias_level = wm8523_set_bias_level,
- .reg_cache_size = WM8523_REGISTER_COUNT,
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8523_reg,
- .volatile_register = wm8523_volatile_register,
-
- .controls = wm8523_controls,
- .num_controls = ARRAY_SIZE(wm8523_controls),
- .dapm_widgets = wm8523_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8523_dapm_widgets),
- .dapm_routes = wm8523_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm8523_dapm_routes),
-};
-
-static const struct of_device_id wm8523_of_match[] = {
- { .compatible = "wlf,wm8523" },
- { },
-};
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8523_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8523_priv *wm8523;
- int ret;
-
- wm8523 = kzalloc(sizeof(struct wm8523_priv), GFP_KERNEL);
- if (wm8523 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm8523);
- wm8523->control_type = SND_SOC_I2C;
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8523, &wm8523_dai, 1);
- if (ret < 0)
- kfree(wm8523);
- return ret;
-
-}
-
-static __devexit int wm8523_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-static const struct i2c_device_id wm8523_i2c_id[] = {
- { "wm8523", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8523_i2c_id);
-
-static struct i2c_driver wm8523_i2c_driver = {
- .driver = {
- .name = "wm8523",
- .owner = THIS_MODULE,
- .of_match_table = wm8523_of_match,
- },
- .probe = wm8523_i2c_probe,
- .remove = __devexit_p(wm8523_i2c_remove),
- .id_table = wm8523_i2c_id,
-};
-#endif
-
-static int __init wm8523_modinit(void)
-{
- int ret;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&wm8523_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8523 I2C driver: %d\n",
- ret);
- }
-#endif
- return 0;
-}
-module_init(wm8523_modinit);
-
-static void __exit wm8523_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&wm8523_i2c_driver);
-#endif
-}
-module_exit(wm8523_exit);
-
-MODULE_DESCRIPTION("ASoC WM8523 driver");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8523.h b/ANDROID_3.4.5/sound/soc/codecs/wm8523.h
deleted file mode 100644
index 4d5b1eb8..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8523.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * wm8523.h -- WM8423 ASoC driver
- *
- * Copyright 2009 Wolfson Microelectronics, plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * Based on wm8753.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8523_H
-#define _WM8523_H
-
-/*
- * Register values.
- */
-#define WM8523_DEVICE_ID 0x00
-#define WM8523_REVISION 0x01
-#define WM8523_PSCTRL1 0x02
-#define WM8523_AIF_CTRL1 0x03
-#define WM8523_AIF_CTRL2 0x04
-#define WM8523_DAC_CTRL3 0x05
-#define WM8523_DAC_GAINL 0x06
-#define WM8523_DAC_GAINR 0x07
-#define WM8523_ZERO_DETECT 0x08
-
-#define WM8523_REGISTER_COUNT 9
-#define WM8523_MAX_REGISTER 0x08
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - DEVICE_ID
- */
-#define WM8523_CHIP_ID_MASK 0xFFFF /* CHIP_ID - [15:0] */
-#define WM8523_CHIP_ID_SHIFT 0 /* CHIP_ID - [15:0] */
-#define WM8523_CHIP_ID_WIDTH 16 /* CHIP_ID - [15:0] */
-
-/*
- * R1 (0x01) - REVISION
- */
-#define WM8523_CHIP_REV_MASK 0x0007 /* CHIP_REV - [2:0] */
-#define WM8523_CHIP_REV_SHIFT 0 /* CHIP_REV - [2:0] */
-#define WM8523_CHIP_REV_WIDTH 3 /* CHIP_REV - [2:0] */
-
-/*
- * R2 (0x02) - PSCTRL1
- */
-#define WM8523_SYS_ENA_MASK 0x0003 /* SYS_ENA - [1:0] */
-#define WM8523_SYS_ENA_SHIFT 0 /* SYS_ENA - [1:0] */
-#define WM8523_SYS_ENA_WIDTH 2 /* SYS_ENA - [1:0] */
-
-/*
- * R3 (0x03) - AIF_CTRL1
- */
-#define WM8523_TDM_MODE_MASK 0x1800 /* TDM_MODE - [12:11] */
-#define WM8523_TDM_MODE_SHIFT 11 /* TDM_MODE - [12:11] */
-#define WM8523_TDM_MODE_WIDTH 2 /* TDM_MODE - [12:11] */
-#define WM8523_TDM_SLOT_MASK 0x0600 /* TDM_SLOT - [10:9] */
-#define WM8523_TDM_SLOT_SHIFT 9 /* TDM_SLOT - [10:9] */
-#define WM8523_TDM_SLOT_WIDTH 2 /* TDM_SLOT - [10:9] */
-#define WM8523_DEEMPH 0x0100 /* DEEMPH */
-#define WM8523_DEEMPH_MASK 0x0100 /* DEEMPH */
-#define WM8523_DEEMPH_SHIFT 8 /* DEEMPH */
-#define WM8523_DEEMPH_WIDTH 1 /* DEEMPH */
-#define WM8523_AIF_MSTR 0x0080 /* AIF_MSTR */
-#define WM8523_AIF_MSTR_MASK 0x0080 /* AIF_MSTR */
-#define WM8523_AIF_MSTR_SHIFT 7 /* AIF_MSTR */
-#define WM8523_AIF_MSTR_WIDTH 1 /* AIF_MSTR */
-#define WM8523_LRCLK_INV 0x0040 /* LRCLK_INV */
-#define WM8523_LRCLK_INV_MASK 0x0040 /* LRCLK_INV */
-#define WM8523_LRCLK_INV_SHIFT 6 /* LRCLK_INV */
-#define WM8523_LRCLK_INV_WIDTH 1 /* LRCLK_INV */
-#define WM8523_BCLK_INV 0x0020 /* BCLK_INV */
-#define WM8523_BCLK_INV_MASK 0x0020 /* BCLK_INV */
-#define WM8523_BCLK_INV_SHIFT 5 /* BCLK_INV */
-#define WM8523_BCLK_INV_WIDTH 1 /* BCLK_INV */
-#define WM8523_WL_MASK 0x0018 /* WL - [4:3] */
-#define WM8523_WL_SHIFT 3 /* WL - [4:3] */
-#define WM8523_WL_WIDTH 2 /* WL - [4:3] */
-#define WM8523_FMT_MASK 0x0007 /* FMT - [2:0] */
-#define WM8523_FMT_SHIFT 0 /* FMT - [2:0] */
-#define WM8523_FMT_WIDTH 3 /* FMT - [2:0] */
-
-/*
- * R4 (0x04) - AIF_CTRL2
- */
-#define WM8523_DAC_OP_MUX_MASK 0x00C0 /* DAC_OP_MUX - [7:6] */
-#define WM8523_DAC_OP_MUX_SHIFT 6 /* DAC_OP_MUX - [7:6] */
-#define WM8523_DAC_OP_MUX_WIDTH 2 /* DAC_OP_MUX - [7:6] */
-#define WM8523_BCLKDIV_MASK 0x0038 /* BCLKDIV - [5:3] */
-#define WM8523_BCLKDIV_SHIFT 3 /* BCLKDIV - [5:3] */
-#define WM8523_BCLKDIV_WIDTH 3 /* BCLKDIV - [5:3] */
-#define WM8523_SR_MASK 0x0007 /* SR - [2:0] */
-#define WM8523_SR_SHIFT 0 /* SR - [2:0] */
-#define WM8523_SR_WIDTH 3 /* SR - [2:0] */
-
-/*
- * R5 (0x05) - DAC_CTRL3
- */
-#define WM8523_ZC 0x0010 /* ZC */
-#define WM8523_ZC_MASK 0x0010 /* ZC */
-#define WM8523_ZC_SHIFT 4 /* ZC */
-#define WM8523_ZC_WIDTH 1 /* ZC */
-#define WM8523_DACR 0x0008 /* DACR */
-#define WM8523_DACR_MASK 0x0008 /* DACR */
-#define WM8523_DACR_SHIFT 3 /* DACR */
-#define WM8523_DACR_WIDTH 1 /* DACR */
-#define WM8523_DACL 0x0004 /* DACL */
-#define WM8523_DACL_MASK 0x0004 /* DACL */
-#define WM8523_DACL_SHIFT 2 /* DACL */
-#define WM8523_DACL_WIDTH 1 /* DACL */
-#define WM8523_VOL_UP_RAMP 0x0002 /* VOL_UP_RAMP */
-#define WM8523_VOL_UP_RAMP_MASK 0x0002 /* VOL_UP_RAMP */
-#define WM8523_VOL_UP_RAMP_SHIFT 1 /* VOL_UP_RAMP */
-#define WM8523_VOL_UP_RAMP_WIDTH 1 /* VOL_UP_RAMP */
-#define WM8523_VOL_DOWN_RAMP 0x0001 /* VOL_DOWN_RAMP */
-#define WM8523_VOL_DOWN_RAMP_MASK 0x0001 /* VOL_DOWN_RAMP */
-#define WM8523_VOL_DOWN_RAMP_SHIFT 0 /* VOL_DOWN_RAMP */
-#define WM8523_VOL_DOWN_RAMP_WIDTH 1 /* VOL_DOWN_RAMP */
-
-/*
- * R6 (0x06) - DAC_GAINL
- */
-#define WM8523_DACL_VU 0x0200 /* DACL_VU */
-#define WM8523_DACL_VU_MASK 0x0200 /* DACL_VU */
-#define WM8523_DACL_VU_SHIFT 9 /* DACL_VU */
-#define WM8523_DACL_VU_WIDTH 1 /* DACL_VU */
-#define WM8523_DACL_VOL_MASK 0x01FF /* DACL_VOL - [8:0] */
-#define WM8523_DACL_VOL_SHIFT 0 /* DACL_VOL - [8:0] */
-#define WM8523_DACL_VOL_WIDTH 9 /* DACL_VOL - [8:0] */
-
-/*
- * R7 (0x07) - DAC_GAINR
- */
-#define WM8523_DACR_VU 0x0200 /* DACR_VU */
-#define WM8523_DACR_VU_MASK 0x0200 /* DACR_VU */
-#define WM8523_DACR_VU_SHIFT 9 /* DACR_VU */
-#define WM8523_DACR_VU_WIDTH 1 /* DACR_VU */
-#define WM8523_DACR_VOL_MASK 0x01FF /* DACR_VOL - [8:0] */
-#define WM8523_DACR_VOL_SHIFT 0 /* DACR_VOL - [8:0] */
-#define WM8523_DACR_VOL_WIDTH 9 /* DACR_VOL - [8:0] */
-
-/*
- * R8 (0x08) - ZERO_DETECT
- */
-#define WM8523_ZD_COUNT_MASK 0x0003 /* ZD_COUNT - [1:0] */
-#define WM8523_ZD_COUNT_SHIFT 0 /* ZD_COUNT - [1:0] */
-#define WM8523_ZD_COUNT_WIDTH 2 /* ZD_COUNT - [1:0] */
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8580.c b/ANDROID_3.4.5/sound/soc/codecs/wm8580.c
deleted file mode 100644
index 21128516..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8580.c
+++ /dev/null
@@ -1,966 +0,0 @@
-/*
- * wm8580.c -- WM8580 ALSA Soc Audio driver
- *
- * Copyright 2008, 2009 Wolfson Microelectronics PLC.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * Notes:
- * The WM8580 is a multichannel codec with S/PDIF support, featuring six
- * DAC channels and two ADC channels.
- *
- * Currently only the primary audio interface is supported - S/PDIF and
- * the secondary audio interfaces are not.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <linux/of_device.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/tlv.h>
-#include <sound/initval.h>
-#include <asm/div64.h>
-
-#include "wm8580.h"
-
-/* WM8580 register space */
-#define WM8580_PLLA1 0x00
-#define WM8580_PLLA2 0x01
-#define WM8580_PLLA3 0x02
-#define WM8580_PLLA4 0x03
-#define WM8580_PLLB1 0x04
-#define WM8580_PLLB2 0x05
-#define WM8580_PLLB3 0x06
-#define WM8580_PLLB4 0x07
-#define WM8580_CLKSEL 0x08
-#define WM8580_PAIF1 0x09
-#define WM8580_PAIF2 0x0A
-#define WM8580_SAIF1 0x0B
-#define WM8580_PAIF3 0x0C
-#define WM8580_PAIF4 0x0D
-#define WM8580_SAIF2 0x0E
-#define WM8580_DAC_CONTROL1 0x0F
-#define WM8580_DAC_CONTROL2 0x10
-#define WM8580_DAC_CONTROL3 0x11
-#define WM8580_DAC_CONTROL4 0x12
-#define WM8580_DAC_CONTROL5 0x13
-#define WM8580_DIGITAL_ATTENUATION_DACL1 0x14
-#define WM8580_DIGITAL_ATTENUATION_DACR1 0x15
-#define WM8580_DIGITAL_ATTENUATION_DACL2 0x16
-#define WM8580_DIGITAL_ATTENUATION_DACR2 0x17
-#define WM8580_DIGITAL_ATTENUATION_DACL3 0x18
-#define WM8580_DIGITAL_ATTENUATION_DACR3 0x19
-#define WM8580_MASTER_DIGITAL_ATTENUATION 0x1C
-#define WM8580_ADC_CONTROL1 0x1D
-#define WM8580_SPDTXCHAN0 0x1E
-#define WM8580_SPDTXCHAN1 0x1F
-#define WM8580_SPDTXCHAN2 0x20
-#define WM8580_SPDTXCHAN3 0x21
-#define WM8580_SPDTXCHAN4 0x22
-#define WM8580_SPDTXCHAN5 0x23
-#define WM8580_SPDMODE 0x24
-#define WM8580_INTMASK 0x25
-#define WM8580_GPO1 0x26
-#define WM8580_GPO2 0x27
-#define WM8580_GPO3 0x28
-#define WM8580_GPO4 0x29
-#define WM8580_GPO5 0x2A
-#define WM8580_INTSTAT 0x2B
-#define WM8580_SPDRXCHAN1 0x2C
-#define WM8580_SPDRXCHAN2 0x2D
-#define WM8580_SPDRXCHAN3 0x2E
-#define WM8580_SPDRXCHAN4 0x2F
-#define WM8580_SPDRXCHAN5 0x30
-#define WM8580_SPDSTAT 0x31
-#define WM8580_PWRDN1 0x32
-#define WM8580_PWRDN2 0x33
-#define WM8580_READBACK 0x34
-#define WM8580_RESET 0x35
-
-#define WM8580_MAX_REGISTER 0x35
-
-#define WM8580_DACOSR 0x40
-
-/* PLLB4 (register 7h) */
-#define WM8580_PLLB4_MCLKOUTSRC_MASK 0x60
-#define WM8580_PLLB4_MCLKOUTSRC_PLLA 0x20
-#define WM8580_PLLB4_MCLKOUTSRC_PLLB 0x40
-#define WM8580_PLLB4_MCLKOUTSRC_OSC 0x60
-
-#define WM8580_PLLB4_CLKOUTSRC_MASK 0x180
-#define WM8580_PLLB4_CLKOUTSRC_PLLACLK 0x080
-#define WM8580_PLLB4_CLKOUTSRC_PLLBCLK 0x100
-#define WM8580_PLLB4_CLKOUTSRC_OSCCLK 0x180
-
-/* CLKSEL (register 8h) */
-#define WM8580_CLKSEL_DAC_CLKSEL_MASK 0x03
-#define WM8580_CLKSEL_DAC_CLKSEL_PLLA 0x01
-#define WM8580_CLKSEL_DAC_CLKSEL_PLLB 0x02
-
-/* AIF control 1 (registers 9h-bh) */
-#define WM8580_AIF_RATE_MASK 0x7
-#define WM8580_AIF_BCLKSEL_MASK 0x18
-
-#define WM8580_AIF_MS 0x20
-
-#define WM8580_AIF_CLKSRC_MASK 0xc0
-#define WM8580_AIF_CLKSRC_PLLA 0x40
-#define WM8580_AIF_CLKSRC_PLLB 0x40
-#define WM8580_AIF_CLKSRC_MCLK 0xc0
-
-/* AIF control 2 (registers ch-eh) */
-#define WM8580_AIF_FMT_MASK 0x03
-#define WM8580_AIF_FMT_RIGHTJ 0x00
-#define WM8580_AIF_FMT_LEFTJ 0x01
-#define WM8580_AIF_FMT_I2S 0x02
-#define WM8580_AIF_FMT_DSP 0x03
-
-#define WM8580_AIF_LENGTH_MASK 0x0c
-#define WM8580_AIF_LENGTH_16 0x00
-#define WM8580_AIF_LENGTH_20 0x04
-#define WM8580_AIF_LENGTH_24 0x08
-#define WM8580_AIF_LENGTH_32 0x0c
-
-#define WM8580_AIF_LRP 0x10
-#define WM8580_AIF_BCP 0x20
-
-/* Powerdown Register 1 (register 32h) */
-#define WM8580_PWRDN1_PWDN 0x001
-#define WM8580_PWRDN1_ALLDACPD 0x040
-
-/* Powerdown Register 2 (register 33h) */
-#define WM8580_PWRDN2_OSSCPD 0x001
-#define WM8580_PWRDN2_PLLAPD 0x002
-#define WM8580_PWRDN2_PLLBPD 0x004
-#define WM8580_PWRDN2_SPDIFPD 0x008
-#define WM8580_PWRDN2_SPDIFTXD 0x010
-#define WM8580_PWRDN2_SPDIFRXD 0x020
-
-#define WM8580_DAC_CONTROL5_MUTEALL 0x10
-
-/*
- * wm8580 register cache
- * We can't read the WM8580 register space when we
- * are using 2 wire for device control, so we cache them instead.
- */
-static const u16 wm8580_reg[] = {
- 0x0121, 0x017e, 0x007d, 0x0014, /*R3*/
- 0x0121, 0x017e, 0x007d, 0x0194, /*R7*/
- 0x0010, 0x0002, 0x0002, 0x00c2, /*R11*/
- 0x0182, 0x0082, 0x000a, 0x0024, /*R15*/
- 0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/
- 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/
- 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R27*/
- 0x01f0, 0x0040, 0x0000, 0x0000, /*R31(0x1F)*/
- 0x0000, 0x0000, 0x0031, 0x000b, /*R35*/
- 0x0039, 0x0000, 0x0010, 0x0032, /*R39*/
- 0x0054, 0x0076, 0x0098, 0x0000, /*R43(0x2B)*/
- 0x0000, 0x0000, 0x0000, 0x0000, /*R47*/
- 0x0000, 0x0000, 0x005e, 0x003e, /*R51(0x33)*/
- 0x0000, 0x0000 /*R53*/
-};
-
-struct pll_state {
- unsigned int in;
- unsigned int out;
-};
-
-#define WM8580_NUM_SUPPLIES 3
-static const char *wm8580_supply_names[WM8580_NUM_SUPPLIES] = {
- "AVDD",
- "DVDD",
- "PVDD",
-};
-
-/* codec private data */
-struct wm8580_priv {
- enum snd_soc_control_type control_type;
- struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES];
- struct pll_state a;
- struct pll_state b;
- int sysclk[2];
-};
-
-static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
-
-static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- u16 *reg_cache = codec->reg_cache;
- unsigned int reg = mc->reg;
- unsigned int reg2 = mc->rreg;
- int ret;
-
- /* Clear the register cache so we write without VU set */
- reg_cache[reg] = 0;
- reg_cache[reg2] = 0;
-
- ret = snd_soc_put_volsw(kcontrol, ucontrol);
- if (ret < 0)
- return ret;
-
- /* Now write again with the volume update bit set */
- snd_soc_update_bits(codec, reg, 0x100, 0x100);
- snd_soc_update_bits(codec, reg2, 0x100, 0x100);
-
- return 0;
-}
-
-static const struct snd_kcontrol_new wm8580_snd_controls[] = {
-SOC_DOUBLE_R_EXT_TLV("DAC1 Playback Volume",
- WM8580_DIGITAL_ATTENUATION_DACL1,
- WM8580_DIGITAL_ATTENUATION_DACR1,
- 0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv),
-SOC_DOUBLE_R_EXT_TLV("DAC2 Playback Volume",
- WM8580_DIGITAL_ATTENUATION_DACL2,
- WM8580_DIGITAL_ATTENUATION_DACR2,
- 0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv),
-SOC_DOUBLE_R_EXT_TLV("DAC3 Playback Volume",
- WM8580_DIGITAL_ATTENUATION_DACL3,
- WM8580_DIGITAL_ATTENUATION_DACR3,
- 0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv),
-
-SOC_SINGLE("DAC1 Deemphasis Switch", WM8580_DAC_CONTROL3, 0, 1, 0),
-SOC_SINGLE("DAC2 Deemphasis Switch", WM8580_DAC_CONTROL3, 1, 1, 0),
-SOC_SINGLE("DAC3 Deemphasis Switch", WM8580_DAC_CONTROL3, 2, 1, 0),
-
-SOC_DOUBLE("DAC1 Invert Switch", WM8580_DAC_CONTROL4, 0, 1, 1, 0),
-SOC_DOUBLE("DAC2 Invert Switch", WM8580_DAC_CONTROL4, 2, 3, 1, 0),
-SOC_DOUBLE("DAC3 Invert Switch", WM8580_DAC_CONTROL4, 4, 5, 1, 0),
-
-SOC_SINGLE("DAC ZC Switch", WM8580_DAC_CONTROL5, 5, 1, 0),
-SOC_SINGLE("DAC1 Switch", WM8580_DAC_CONTROL5, 0, 1, 1),
-SOC_SINGLE("DAC2 Switch", WM8580_DAC_CONTROL5, 1, 1, 1),
-SOC_SINGLE("DAC3 Switch", WM8580_DAC_CONTROL5, 2, 1, 1),
-
-SOC_DOUBLE("Capture Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 1),
-SOC_SINGLE("Capture High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = {
-SND_SOC_DAPM_DAC("DAC1", "Playback", WM8580_PWRDN1, 2, 1),
-SND_SOC_DAPM_DAC("DAC2", "Playback", WM8580_PWRDN1, 3, 1),
-SND_SOC_DAPM_DAC("DAC3", "Playback", WM8580_PWRDN1, 4, 1),
-
-SND_SOC_DAPM_OUTPUT("VOUT1L"),
-SND_SOC_DAPM_OUTPUT("VOUT1R"),
-SND_SOC_DAPM_OUTPUT("VOUT2L"),
-SND_SOC_DAPM_OUTPUT("VOUT2R"),
-SND_SOC_DAPM_OUTPUT("VOUT3L"),
-SND_SOC_DAPM_OUTPUT("VOUT3R"),
-
-SND_SOC_DAPM_ADC("ADC", "Capture", WM8580_PWRDN1, 1, 1),
-
-SND_SOC_DAPM_INPUT("AINL"),
-SND_SOC_DAPM_INPUT("AINR"),
-};
-
-static const struct snd_soc_dapm_route wm8580_dapm_routes[] = {
- { "VOUT1L", NULL, "DAC1" },
- { "VOUT1R", NULL, "DAC1" },
-
- { "VOUT2L", NULL, "DAC2" },
- { "VOUT2R", NULL, "DAC2" },
-
- { "VOUT3L", NULL, "DAC3" },
- { "VOUT3R", NULL, "DAC3" },
-
- { "ADC", NULL, "AINL" },
- { "ADC", NULL, "AINR" },
-};
-
-/* PLL divisors */
-struct _pll_div {
- u32 prescale:1;
- u32 postscale:1;
- u32 freqmode:2;
- u32 n:4;
- u32 k:24;
-};
-
-/* The size in bits of the pll divide */
-#define FIXED_PLL_SIZE (1 << 22)
-
-/* PLL rate to output rate divisions */
-static struct {
- unsigned int div;
- unsigned int freqmode;
- unsigned int postscale;
-} post_table[] = {
- { 2, 0, 0 },
- { 4, 0, 1 },
- { 4, 1, 0 },
- { 8, 1, 1 },
- { 8, 2, 0 },
- { 16, 2, 1 },
- { 12, 3, 0 },
- { 24, 3, 1 }
-};
-
-static int pll_factors(struct _pll_div *pll_div, unsigned int target,
- unsigned int source)
-{
- u64 Kpart;
- unsigned int K, Ndiv, Nmod;
- int i;
-
- pr_debug("wm8580: PLL %uHz->%uHz\n", source, target);
-
- /* Scale the output frequency up; the PLL should run in the
- * region of 90-100MHz.
- */
- for (i = 0; i < ARRAY_SIZE(post_table); i++) {
- if (target * post_table[i].div >= 90000000 &&
- target * post_table[i].div <= 100000000) {
- pll_div->freqmode = post_table[i].freqmode;
- pll_div->postscale = post_table[i].postscale;
- target *= post_table[i].div;
- break;
- }
- }
-
- if (i == ARRAY_SIZE(post_table)) {
- printk(KERN_ERR "wm8580: Unable to scale output frequency "
- "%u\n", target);
- return -EINVAL;
- }
-
- Ndiv = target / source;
-
- if (Ndiv < 5) {
- source /= 2;
- pll_div->prescale = 1;
- Ndiv = target / source;
- } else
- pll_div->prescale = 0;
-
- if ((Ndiv < 5) || (Ndiv > 13)) {
- printk(KERN_ERR
- "WM8580 N=%u outside supported range\n", Ndiv);
- return -EINVAL;
- }
-
- pll_div->n = Ndiv;
- Nmod = target % source;
- Kpart = FIXED_PLL_SIZE * (long long)Nmod;
-
- do_div(Kpart, source);
-
- K = Kpart & 0xFFFFFFFF;
-
- pll_div->k = K;
-
- pr_debug("PLL %x.%x prescale %d freqmode %d postscale %d\n",
- pll_div->n, pll_div->k, pll_div->prescale, pll_div->freqmode,
- pll_div->postscale);
-
- return 0;
-}
-
-static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
- int source, unsigned int freq_in, unsigned int freq_out)
-{
- int offset;
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
- struct pll_state *state;
- struct _pll_div pll_div;
- unsigned int reg;
- unsigned int pwr_mask;
- int ret;
-
- /* GCC isn't able to work out the ifs below for initialising/using
- * pll_div so suppress warnings.
- */
- memset(&pll_div, 0, sizeof(pll_div));
-
- switch (pll_id) {
- case WM8580_PLLA:
- state = &wm8580->a;
- offset = 0;
- pwr_mask = WM8580_PWRDN2_PLLAPD;
- break;
- case WM8580_PLLB:
- state = &wm8580->b;
- offset = 4;
- pwr_mask = WM8580_PWRDN2_PLLBPD;
- break;
- default:
- return -ENODEV;
- }
-
- if (freq_in && freq_out) {
- ret = pll_factors(&pll_div, freq_out, freq_in);
- if (ret != 0)
- return ret;
- }
-
- state->in = freq_in;
- state->out = freq_out;
-
- /* Always disable the PLL - it is not safe to leave it running
- * while reprogramming it.
- */
- snd_soc_update_bits(codec, WM8580_PWRDN2, pwr_mask, pwr_mask);
-
- if (!freq_in || !freq_out)
- return 0;
-
- snd_soc_write(codec, WM8580_PLLA1 + offset, pll_div.k & 0x1ff);
- snd_soc_write(codec, WM8580_PLLA2 + offset, (pll_div.k >> 9) & 0x1ff);
- snd_soc_write(codec, WM8580_PLLA3 + offset,
- (pll_div.k >> 18 & 0xf) | (pll_div.n << 4));
-
- reg = snd_soc_read(codec, WM8580_PLLA4 + offset);
- reg &= ~0x1b;
- reg |= pll_div.prescale | pll_div.postscale << 1 |
- pll_div.freqmode << 3;
-
- snd_soc_write(codec, WM8580_PLLA4 + offset, reg);
-
- /* All done, turn it on */
- snd_soc_update_bits(codec, WM8580_PWRDN2, pwr_mask, 0);
-
- return 0;
-}
-
-static const int wm8580_sysclk_ratios[] = {
- 128, 192, 256, 384, 512, 768, 1152,
-};
-
-/*
- * Set PCM DAI bit size and sample rate.
- */
-static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
- u16 paifa = 0;
- u16 paifb = 0;
- int i, ratio, osr;
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- paifa |= 0x8;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- paifa |= 0x0;
- paifb |= WM8580_AIF_LENGTH_20;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- paifa |= 0x0;
- paifb |= WM8580_AIF_LENGTH_24;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- paifa |= 0x0;
- paifb |= WM8580_AIF_LENGTH_32;
- break;
- default:
- return -EINVAL;
- }
-
- /* Look up the SYSCLK ratio; accept only exact matches */
- ratio = wm8580->sysclk[dai->driver->id] / params_rate(params);
- for (i = 0; i < ARRAY_SIZE(wm8580_sysclk_ratios); i++)
- if (ratio == wm8580_sysclk_ratios[i])
- break;
- if (i == ARRAY_SIZE(wm8580_sysclk_ratios)) {
- dev_err(codec->dev, "Invalid clock ratio %d/%d\n",
- wm8580->sysclk[dai->driver->id], params_rate(params));
- return -EINVAL;
- }
- paifa |= i;
- dev_dbg(codec->dev, "Running at %dfs with %dHz clock\n",
- wm8580_sysclk_ratios[i], wm8580->sysclk[dai->driver->id]);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- switch (ratio) {
- case 128:
- case 192:
- osr = WM8580_DACOSR;
- dev_dbg(codec->dev, "Selecting 64x OSR\n");
- break;
- default:
- osr = 0;
- dev_dbg(codec->dev, "Selecting 128x OSR\n");
- break;
- }
-
- snd_soc_update_bits(codec, WM8580_PAIF3, WM8580_DACOSR, osr);
- }
-
- snd_soc_update_bits(codec, WM8580_PAIF1 + dai->driver->id,
- WM8580_AIF_RATE_MASK | WM8580_AIF_BCLKSEL_MASK,
- paifa);
- snd_soc_update_bits(codec, WM8580_PAIF3 + dai->driver->id,
- WM8580_AIF_LENGTH_MASK, paifb);
- return 0;
-}
-
-static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- unsigned int aifa;
- unsigned int aifb;
- int can_invert_lrclk;
-
- aifa = snd_soc_read(codec, WM8580_PAIF1 + codec_dai->driver->id);
- aifb = snd_soc_read(codec, WM8580_PAIF3 + codec_dai->driver->id);
-
- aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP);
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- aifa &= ~WM8580_AIF_MS;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- aifa |= WM8580_AIF_MS;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- can_invert_lrclk = 1;
- aifb |= WM8580_AIF_FMT_I2S;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- can_invert_lrclk = 1;
- aifb |= WM8580_AIF_FMT_RIGHTJ;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- can_invert_lrclk = 1;
- aifb |= WM8580_AIF_FMT_LEFTJ;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- can_invert_lrclk = 0;
- aifb |= WM8580_AIF_FMT_DSP;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- can_invert_lrclk = 0;
- aifb |= WM8580_AIF_FMT_DSP;
- aifb |= WM8580_AIF_LRP;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
-
- case SND_SOC_DAIFMT_IB_IF:
- if (!can_invert_lrclk)
- return -EINVAL;
- aifb |= WM8580_AIF_BCP;
- aifb |= WM8580_AIF_LRP;
- break;
-
- case SND_SOC_DAIFMT_IB_NF:
- aifb |= WM8580_AIF_BCP;
- break;
-
- case SND_SOC_DAIFMT_NB_IF:
- if (!can_invert_lrclk)
- return -EINVAL;
- aifb |= WM8580_AIF_LRP;
- break;
-
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM8580_PAIF1 + codec_dai->driver->id, aifa);
- snd_soc_write(codec, WM8580_PAIF3 + codec_dai->driver->id, aifb);
-
- return 0;
-}
-
-static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
- int div_id, int div)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- unsigned int reg;
-
- switch (div_id) {
- case WM8580_MCLK:
- reg = snd_soc_read(codec, WM8580_PLLB4);
- reg &= ~WM8580_PLLB4_MCLKOUTSRC_MASK;
-
- switch (div) {
- case WM8580_CLKSRC_MCLK:
- /* Input */
- break;
-
- case WM8580_CLKSRC_PLLA:
- reg |= WM8580_PLLB4_MCLKOUTSRC_PLLA;
- break;
- case WM8580_CLKSRC_PLLB:
- reg |= WM8580_PLLB4_MCLKOUTSRC_PLLB;
- break;
-
- case WM8580_CLKSRC_OSC:
- reg |= WM8580_PLLB4_MCLKOUTSRC_OSC;
- break;
-
- default:
- return -EINVAL;
- }
- snd_soc_write(codec, WM8580_PLLB4, reg);
- break;
-
- case WM8580_CLKOUTSRC:
- reg = snd_soc_read(codec, WM8580_PLLB4);
- reg &= ~WM8580_PLLB4_CLKOUTSRC_MASK;
-
- switch (div) {
- case WM8580_CLKSRC_NONE:
- break;
-
- case WM8580_CLKSRC_PLLA:
- reg |= WM8580_PLLB4_CLKOUTSRC_PLLACLK;
- break;
-
- case WM8580_CLKSRC_PLLB:
- reg |= WM8580_PLLB4_CLKOUTSRC_PLLBCLK;
- break;
-
- case WM8580_CLKSRC_OSC:
- reg |= WM8580_PLLB4_CLKOUTSRC_OSCCLK;
- break;
-
- default:
- return -EINVAL;
- }
- snd_soc_write(codec, WM8580_PLLB4, reg);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id,
- unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
- int ret, sel, sel_mask, sel_shift;
-
- switch (dai->driver->id) {
- case WM8580_DAI_PAIFRX:
- sel_mask = 0x3;
- sel_shift = 0;
- break;
-
- case WM8580_DAI_PAIFTX:
- sel_mask = 0xc;
- sel_shift = 2;
- break;
-
- default:
- BUG_ON("Unknown DAI driver ID\n");
- return -EINVAL;
- }
-
- switch (clk_id) {
- case WM8580_CLKSRC_ADCMCLK:
- if (dai->driver->id != WM8580_DAI_PAIFTX)
- return -EINVAL;
- sel = 0 << sel_shift;
- break;
- case WM8580_CLKSRC_PLLA:
- sel = 1 << sel_shift;
- break;
- case WM8580_CLKSRC_PLLB:
- sel = 2 << sel_shift;
- break;
- case WM8580_CLKSRC_MCLK:
- sel = 3 << sel_shift;
- break;
- default:
- dev_err(codec->dev, "Unknown clock %d\n", clk_id);
- return -EINVAL;
- }
-
- /* We really should validate PLL settings but not yet */
- wm8580->sysclk[dai->driver->id] = freq;
-
- ret = snd_soc_update_bits(codec, WM8580_CLKSEL, sel_mask, sel);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- unsigned int reg;
-
- reg = snd_soc_read(codec, WM8580_DAC_CONTROL5);
-
- if (mute)
- reg |= WM8580_DAC_CONTROL5_MUTEALL;
- else
- reg &= ~WM8580_DAC_CONTROL5_MUTEALL;
-
- snd_soc_write(codec, WM8580_DAC_CONTROL5, reg);
-
- return 0;
-}
-
-static int wm8580_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- switch (level) {
- case SND_SOC_BIAS_ON:
- case SND_SOC_BIAS_PREPARE:
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- /* Power up and get individual control of the DACs */
- snd_soc_update_bits(codec, WM8580_PWRDN1,
- WM8580_PWRDN1_PWDN |
- WM8580_PWRDN1_ALLDACPD, 0);
-
- /* Make VMID high impedance */
- snd_soc_update_bits(codec, WM8580_ADC_CONTROL1,
- 0x100, 0);
- }
- break;
-
- case SND_SOC_BIAS_OFF:
- snd_soc_update_bits(codec, WM8580_PWRDN1,
- WM8580_PWRDN1_PWDN, WM8580_PWRDN1_PWDN);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define WM8580_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops wm8580_dai_ops_playback = {
- .set_sysclk = wm8580_set_sysclk,
- .hw_params = wm8580_paif_hw_params,
- .set_fmt = wm8580_set_paif_dai_fmt,
- .set_clkdiv = wm8580_set_dai_clkdiv,
- .set_pll = wm8580_set_dai_pll,
- .digital_mute = wm8580_digital_mute,
-};
-
-static const struct snd_soc_dai_ops wm8580_dai_ops_capture = {
- .set_sysclk = wm8580_set_sysclk,
- .hw_params = wm8580_paif_hw_params,
- .set_fmt = wm8580_set_paif_dai_fmt,
- .set_clkdiv = wm8580_set_dai_clkdiv,
- .set_pll = wm8580_set_dai_pll,
-};
-
-static struct snd_soc_dai_driver wm8580_dai[] = {
- {
- .name = "wm8580-hifi-playback",
- .id = WM8580_DAI_PAIFRX,
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 6,
- .rates = SNDRV_PCM_RATE_8000_192000,
- .formats = WM8580_FORMATS,
- },
- .ops = &wm8580_dai_ops_playback,
- },
- {
- .name = "wm8580-hifi-capture",
- .id = WM8580_DAI_PAIFTX,
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_192000,
- .formats = WM8580_FORMATS,
- },
- .ops = &wm8580_dai_ops_capture,
- },
-};
-
-static int wm8580_probe(struct snd_soc_codec *codec)
-{
- struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
- int ret = 0,i;
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8580->control_type);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++)
- wm8580->supplies[i].supply = wm8580_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8580->supplies),
- wm8580->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- return ret;
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies),
- wm8580->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
- goto err_regulator_get;
- }
-
- /* Get the codec into a known state */
- ret = snd_soc_write(codec, WM8580_RESET, 0);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to reset codec: %d\n", ret);
- goto err_regulator_enable;
- }
-
- wm8580_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-
-err_regulator_enable:
- regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
-err_regulator_get:
- regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
- return ret;
-}
-
-/* power down chip */
-static int wm8580_remove(struct snd_soc_codec *codec)
-{
- struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
-
- wm8580_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
- regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
- .probe = wm8580_probe,
- .remove = wm8580_remove,
- .set_bias_level = wm8580_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8580_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8580_reg,
-
- .controls = wm8580_snd_controls,
- .num_controls = ARRAY_SIZE(wm8580_snd_controls),
- .dapm_widgets = wm8580_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8580_dapm_widgets),
- .dapm_routes = wm8580_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm8580_dapm_routes),
-};
-
-static const struct of_device_id wm8580_of_match[] = {
- { .compatible = "wlf,wm8580" },
- { },
-};
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static int wm8580_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8580_priv *wm8580;
- int ret;
-
- wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL);
- if (wm8580 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm8580);
- wm8580->control_type = SND_SOC_I2C;
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8580, wm8580_dai, ARRAY_SIZE(wm8580_dai));
- if (ret < 0)
- kfree(wm8580);
- return ret;
-}
-
-static int wm8580_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-static const struct i2c_device_id wm8580_i2c_id[] = {
- { "wm8580", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);
-
-static struct i2c_driver wm8580_i2c_driver = {
- .driver = {
- .name = "wm8580",
- .owner = THIS_MODULE,
- .of_match_table = wm8580_of_match,
- },
- .probe = wm8580_i2c_probe,
- .remove = wm8580_i2c_remove,
- .id_table = wm8580_i2c_id,
-};
-#endif
-
-static int __init wm8580_modinit(void)
-{
- int ret = 0;
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&wm8580_i2c_driver);
- if (ret != 0) {
- pr_err("Failed to register WM8580 I2C driver: %d\n", ret);
- }
-#endif
-
- return ret;
-}
-module_init(wm8580_modinit);
-
-static void __exit wm8580_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&wm8580_i2c_driver);
-#endif
-}
-module_exit(wm8580_exit);
-
-MODULE_DESCRIPTION("ASoC WM8580 driver");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8580.h b/ANDROID_3.4.5/sound/soc/codecs/wm8580.h
deleted file mode 100644
index 1d34656d..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8580.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * wm8580.h -- audio driver for WM8580
- *
- * Copyright 2008 Samsung Electronics.
- * Author: Ryu Euiyoul
- * ryu.real@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#ifndef _WM8580_H
-#define _WM8580_H
-
-#define WM8580_PLLA 1
-#define WM8580_PLLB 2
-
-#define WM8580_MCLK 1
-#define WM8580_CLKOUTSRC 2
-
-#define WM8580_CLKSRC_MCLK 1
-#define WM8580_CLKSRC_PLLA 2
-#define WM8580_CLKSRC_PLLB 3
-#define WM8580_CLKSRC_OSC 4
-#define WM8580_CLKSRC_NONE 5
-#define WM8580_CLKSRC_ADCMCLK 6
-
-#define WM8580_DAI_PAIFRX 0
-#define WM8580_DAI_PAIFTX 1
-
-#endif
-
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8711.c b/ANDROID_3.4.5/sound/soc/codecs/wm8711.c
deleted file mode 100644
index 0b76d1dc..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8711.c
+++ /dev/null
@@ -1,529 +0,0 @@
-/*
- * wm8711.c -- WM8711 ALSA SoC Audio driver
- *
- * Copyright 2006 Wolfson Microelectronics
- *
- * Author: Mike Arthur <Mike.Arthur@wolfsonmicro.com>
- *
- * Based on wm8731.c by Richard Purdie
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/of_device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/tlv.h>
-#include <sound/initval.h>
-
-#include "wm8711.h"
-
-/* codec private data */
-struct wm8711_priv {
- enum snd_soc_control_type bus_type;
- unsigned int sysclk;
-};
-
-/*
- * wm8711 register cache
- * We can't read the WM8711 register space when we are
- * using 2 wire for device control, so we cache them instead.
- * There is no point in caching the reset register
- */
-static const u16 wm8711_reg[WM8711_CACHEREGNUM] = {
- 0x0079, 0x0079, 0x000a, 0x0008,
- 0x009f, 0x000a, 0x0000, 0x0000
-};
-
-#define wm8711_reset(c) snd_soc_write(c, WM8711_RESET, 0)
-
-static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
-
-static const struct snd_kcontrol_new wm8711_snd_controls[] = {
-
-SOC_DOUBLE_R_TLV("Master Playback Volume", WM8711_LOUT1V, WM8711_ROUT1V,
- 0, 127, 0, out_tlv),
-SOC_DOUBLE_R("Master Playback ZC Switch", WM8711_LOUT1V, WM8711_ROUT1V,
- 7, 1, 0),
-
-};
-
-/* Output Mixer */
-static const struct snd_kcontrol_new wm8711_output_mixer_controls[] = {
-SOC_DAPM_SINGLE("Line Bypass Switch", WM8711_APANA, 3, 1, 0),
-SOC_DAPM_SINGLE("HiFi Playback Switch", WM8711_APANA, 4, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget wm8711_dapm_widgets[] = {
-SND_SOC_DAPM_MIXER("Output Mixer", WM8711_PWR, 4, 1,
- &wm8711_output_mixer_controls[0],
- ARRAY_SIZE(wm8711_output_mixer_controls)),
-SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8711_PWR, 3, 1),
-SND_SOC_DAPM_OUTPUT("LOUT"),
-SND_SOC_DAPM_OUTPUT("LHPOUT"),
-SND_SOC_DAPM_OUTPUT("ROUT"),
-SND_SOC_DAPM_OUTPUT("RHPOUT"),
-};
-
-static const struct snd_soc_dapm_route wm8711_intercon[] = {
- /* output mixer */
- {"Output Mixer", "Line Bypass Switch", "Line Input"},
- {"Output Mixer", "HiFi Playback Switch", "DAC"},
-
- /* outputs */
- {"RHPOUT", NULL, "Output Mixer"},
- {"ROUT", NULL, "Output Mixer"},
- {"LHPOUT", NULL, "Output Mixer"},
- {"LOUT", NULL, "Output Mixer"},
-};
-
-struct _coeff_div {
- u32 mclk;
- u32 rate;
- u16 fs;
- u8 sr:4;
- u8 bosr:1;
- u8 usb:1;
-};
-
-/* codec mclk clock divider coefficients */
-static const struct _coeff_div coeff_div[] = {
- /* 48k */
- {12288000, 48000, 256, 0x0, 0x0, 0x0},
- {18432000, 48000, 384, 0x0, 0x1, 0x0},
- {12000000, 48000, 250, 0x0, 0x0, 0x1},
-
- /* 32k */
- {12288000, 32000, 384, 0x6, 0x0, 0x0},
- {18432000, 32000, 576, 0x6, 0x1, 0x0},
- {12000000, 32000, 375, 0x6, 0x0, 0x1},
-
- /* 8k */
- {12288000, 8000, 1536, 0x3, 0x0, 0x0},
- {18432000, 8000, 2304, 0x3, 0x1, 0x0},
- {11289600, 8000, 1408, 0xb, 0x0, 0x0},
- {16934400, 8000, 2112, 0xb, 0x1, 0x0},
- {12000000, 8000, 1500, 0x3, 0x0, 0x1},
-
- /* 96k */
- {12288000, 96000, 128, 0x7, 0x0, 0x0},
- {18432000, 96000, 192, 0x7, 0x1, 0x0},
- {12000000, 96000, 125, 0x7, 0x0, 0x1},
-
- /* 44.1k */
- {11289600, 44100, 256, 0x8, 0x0, 0x0},
- {16934400, 44100, 384, 0x8, 0x1, 0x0},
- {12000000, 44100, 272, 0x8, 0x1, 0x1},
-
- /* 88.2k */
- {11289600, 88200, 128, 0xf, 0x0, 0x0},
- {16934400, 88200, 192, 0xf, 0x1, 0x0},
- {12000000, 88200, 136, 0xf, 0x1, 0x1},
-};
-
-static inline int get_coeff(int mclk, int rate)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
- if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
- return i;
- }
- return 0;
-}
-
-static int wm8711_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
- u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfff3;
- int i = get_coeff(wm8711->sysclk, params_rate(params));
- u16 srate = (coeff_div[i].sr << 2) |
- (coeff_div[i].bosr << 1) | coeff_div[i].usb;
-
- snd_soc_write(codec, WM8711_SRATE, srate);
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= 0x0004;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface |= 0x0008;
- break;
- }
-
- snd_soc_write(codec, WM8711_IFACE, iface);
- return 0;
-}
-
-static int wm8711_pcm_prepare(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
-
- /* set active */
- snd_soc_write(codec, WM8711_ACTIVE, 0x0001);
-
- return 0;
-}
-
-static void wm8711_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
-
- /* deactivate */
- if (!codec->active) {
- udelay(50);
- snd_soc_write(codec, WM8711_ACTIVE, 0x0);
- }
-}
-
-static int wm8711_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 mute_reg = snd_soc_read(codec, WM8711_APDIGI) & 0xfff7;
-
- if (mute)
- snd_soc_write(codec, WM8711_APDIGI, mute_reg | 0x8);
- else
- snd_soc_write(codec, WM8711_APDIGI, mute_reg);
-
- return 0;
-}
-
-static int wm8711_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
-
- switch (freq) {
- case 11289600:
- case 12000000:
- case 12288000:
- case 16934400:
- case 18432000:
- wm8711->sysclk = freq;
- return 0;
- }
- return -EINVAL;
-}
-
-static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0x000c;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- iface |= 0x0040;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= 0x0002;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= 0x0001;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= 0x0003;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- iface |= 0x0013;
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= 0x0090;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= 0x0080;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- iface |= 0x0010;
- break;
- default:
- return -EINVAL;
- }
-
- /* set iface */
- snd_soc_write(codec, WM8711_IFACE, iface);
- return 0;
-}
-
-static int wm8711_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- u16 reg = snd_soc_read(codec, WM8711_PWR) & 0xff7f;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- snd_soc_write(codec, WM8711_PWR, reg);
- break;
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
- snd_soc_cache_sync(codec);
-
- snd_soc_write(codec, WM8711_PWR, reg | 0x0040);
- break;
- case SND_SOC_BIAS_OFF:
- snd_soc_write(codec, WM8711_ACTIVE, 0x0);
- snd_soc_write(codec, WM8711_PWR, 0xffff);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define WM8711_RATES SNDRV_PCM_RATE_8000_96000
-
-#define WM8711_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops wm8711_ops = {
- .prepare = wm8711_pcm_prepare,
- .hw_params = wm8711_hw_params,
- .shutdown = wm8711_shutdown,
- .digital_mute = wm8711_mute,
- .set_sysclk = wm8711_set_dai_sysclk,
- .set_fmt = wm8711_set_dai_fmt,
-};
-
-static struct snd_soc_dai_driver wm8711_dai = {
- .name = "wm8711-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8711_RATES,
- .formats = WM8711_FORMATS,
- },
- .ops = &wm8711_ops,
-};
-
-static int wm8711_suspend(struct snd_soc_codec *codec)
-{
- snd_soc_write(codec, WM8711_ACTIVE, 0x0);
- wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm8711_resume(struct snd_soc_codec *codec)
-{
- wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-
-static int wm8711_probe(struct snd_soc_codec *codec)
-{
- struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8711->bus_type);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- ret = wm8711_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- return ret;
- }
-
- wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* Latch the update bits */
- snd_soc_update_bits(codec, WM8711_LOUT1V, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8711_ROUT1V, 0x0100, 0x0100);
-
- return ret;
-
-}
-
-/* power down chip */
-static int wm8711_remove(struct snd_soc_codec *codec)
-{
- wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8711 = {
- .probe = wm8711_probe,
- .remove = wm8711_remove,
- .suspend = wm8711_suspend,
- .resume = wm8711_resume,
- .set_bias_level = wm8711_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8711_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8711_reg,
- .controls = wm8711_snd_controls,
- .num_controls = ARRAY_SIZE(wm8711_snd_controls),
- .dapm_widgets = wm8711_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8711_dapm_widgets),
- .dapm_routes = wm8711_intercon,
- .num_dapm_routes = ARRAY_SIZE(wm8711_intercon),
-};
-
-static const struct of_device_id wm8711_of_match[] = {
- { .compatible = "wlf,wm8711", },
- { }
-};
-MODULE_DEVICE_TABLE(of, wm8711_of_match);
-
-#if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8711_spi_probe(struct spi_device *spi)
-{
- struct wm8711_priv *wm8711;
- int ret;
-
- wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
- if (wm8711 == NULL)
- return -ENOMEM;
-
- spi_set_drvdata(spi, wm8711);
- wm8711->bus_type = SND_SOC_SPI;
-
- ret = snd_soc_register_codec(&spi->dev,
- &soc_codec_dev_wm8711, &wm8711_dai, 1);
- if (ret < 0)
- kfree(wm8711);
- return ret;
-}
-
-static int __devexit wm8711_spi_remove(struct spi_device *spi)
-{
- snd_soc_unregister_codec(&spi->dev);
- kfree(spi_get_drvdata(spi));
- return 0;
-}
-
-static struct spi_driver wm8711_spi_driver = {
- .driver = {
- .name = "wm8711",
- .owner = THIS_MODULE,
- .of_match_table = wm8711_of_match,
- },
- .probe = wm8711_spi_probe,
- .remove = __devexit_p(wm8711_spi_remove),
-};
-#endif /* CONFIG_SPI_MASTER */
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8711_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct wm8711_priv *wm8711;
- int ret;
-
- wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
- if (wm8711 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(client, wm8711);
- wm8711->bus_type = SND_SOC_I2C;
-
- ret = snd_soc_register_codec(&client->dev,
- &soc_codec_dev_wm8711, &wm8711_dai, 1);
- if (ret < 0)
- kfree(wm8711);
- return ret;
-}
-
-static __devexit int wm8711_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-static const struct i2c_device_id wm8711_i2c_id[] = {
- { "wm8711", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8711_i2c_id);
-
-static struct i2c_driver wm8711_i2c_driver = {
- .driver = {
- .name = "wm8711",
- .owner = THIS_MODULE,
- .of_match_table = wm8711_of_match,
- },
- .probe = wm8711_i2c_probe,
- .remove = __devexit_p(wm8711_i2c_remove),
- .id_table = wm8711_i2c_id,
-};
-#endif
-
-static int __init wm8711_modinit(void)
-{
- int ret;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&wm8711_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8711 I2C driver: %d\n",
- ret);
- }
-#endif
-#if defined(CONFIG_SPI_MASTER)
- ret = spi_register_driver(&wm8711_spi_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8711 SPI driver: %d\n",
- ret);
- }
-#endif
- return 0;
-}
-module_init(wm8711_modinit);
-
-static void __exit wm8711_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&wm8711_i2c_driver);
-#endif
-#if defined(CONFIG_SPI_MASTER)
- spi_unregister_driver(&wm8711_spi_driver);
-#endif
-}
-module_exit(wm8711_exit);
-
-MODULE_DESCRIPTION("ASoC WM8711 driver");
-MODULE_AUTHOR("Mike Arthur");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8711.h b/ANDROID_3.4.5/sound/soc/codecs/wm8711.h
deleted file mode 100644
index a61db985..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8711.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * wm8711.h -- WM8711 Soc Audio driver
- *
- * Copyright 2006 Wolfson Microelectronics
- *
- * Author: Mike Arthur <linux@wolfsonmicro.com>
- *
- * Based on wm8731.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8711_H
-#define _WM8711_H
-
-/* WM8711 register space */
-
-#define WM8711_LOUT1V 0x02
-#define WM8711_ROUT1V 0x03
-#define WM8711_APANA 0x04
-#define WM8711_APDIGI 0x05
-#define WM8711_PWR 0x06
-#define WM8711_IFACE 0x07
-#define WM8711_SRATE 0x08
-#define WM8711_ACTIVE 0x09
-#define WM8711_RESET 0x0f
-
-#define WM8711_CACHEREGNUM 8
-
-#define WM8711_SYSCLK 0
-#define WM8711_DAI 0
-
-struct wm8711_setup_data {
- unsigned short i2c_address;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8727.c b/ANDROID_3.4.5/sound/soc/codecs/wm8727.c
deleted file mode 100644
index e8170562..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8727.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * wm8727.c
- *
- * Created on: 15-Oct-2009
- * Author: neil.jones@imgtec.com
- *
- * Copyright (C) 2009 Imagination Technologies Ltd.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-/*
- * Note this is a simple chip with no configuration interface, sample rate is
- * determined automatically by examining the Master clock and Bit clock ratios
- */
-#define WM8727_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |\
- SNDRV_PCM_RATE_192000)
-
-
-static struct snd_soc_dai_driver wm8727_dai = {
- .name = "wm8727-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = WM8727_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
- },
-};
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8727;
-
-static __devinit int wm8727_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev,
- &soc_codec_dev_wm8727, &wm8727_dai, 1);
-}
-
-static int __devexit wm8727_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver wm8727_codec_driver = {
- .driver = {
- .name = "wm8727",
- .owner = THIS_MODULE,
- },
-
- .probe = wm8727_probe,
- .remove = __devexit_p(wm8727_remove),
-};
-
-module_platform_driver(wm8727_codec_driver);
-
-MODULE_DESCRIPTION("ASoC wm8727 driver");
-MODULE_AUTHOR("Neil Jones");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8728.c b/ANDROID_3.4.5/sound/soc/codecs/wm8728.c
deleted file mode 100644
index fc3d59e4..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8728.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * wm8728.c -- WM8728 ALSA SoC Audio driver
- *
- * Copyright 2008 Wolfson Microelectronics plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/of_device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "wm8728.h"
-
-/*
- * We can't read the WM8728 register space so we cache them instead.
- * Note that the defaults here aren't the physical defaults, we latch
- * the volume update bits, mute the output and enable infinite zero
- * detect.
- */
-static const u16 wm8728_reg_defaults[] = {
- 0x1ff,
- 0x1ff,
- 0x001,
- 0x100,
-};
-
-/* codec private data */
-struct wm8728_priv {
- enum snd_soc_control_type control_type;
-};
-
-static const DECLARE_TLV_DB_SCALE(wm8728_tlv, -12750, 50, 1);
-
-static const struct snd_kcontrol_new wm8728_snd_controls[] = {
-
-SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8728_DACLVOL, WM8728_DACRVOL,
- 0, 255, 0, wm8728_tlv),
-
-SOC_SINGLE("Deemphasis", WM8728_DACCTL, 1, 1, 0),
-};
-
-/*
- * DAPM controls.
- */
-static const struct snd_soc_dapm_widget wm8728_dapm_widgets[] = {
-SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_OUTPUT("VOUTL"),
-SND_SOC_DAPM_OUTPUT("VOUTR"),
-};
-
-static const struct snd_soc_dapm_route wm8728_intercon[] = {
- {"VOUTL", NULL, "DAC"},
- {"VOUTR", NULL, "DAC"},
-};
-
-static int wm8728_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 mute_reg = snd_soc_read(codec, WM8728_DACCTL);
-
- if (mute)
- snd_soc_write(codec, WM8728_DACCTL, mute_reg | 1);
- else
- snd_soc_write(codec, WM8728_DACCTL, mute_reg & ~1);
-
- return 0;
-}
-
-static int wm8728_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- u16 dac = snd_soc_read(codec, WM8728_DACCTL);
-
- dac &= ~0x18;
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- dac |= 0x10;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- dac |= 0x08;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM8728_DACCTL, dac);
-
- return 0;
-}
-
-static int wm8728_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 iface = snd_soc_read(codec, WM8728_IFCTL);
-
- /* Currently only I2S is supported by the driver, though the
- * hardware is more flexible.
- */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= 1;
- break;
- default:
- return -EINVAL;
- }
-
- /* The hardware only support full slave mode */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- iface &= ~0x22;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= 0x20;
- iface &= ~0x02;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- iface |= 0x02;
- iface &= ~0x20;
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= 0x22;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM8728_IFCTL, iface);
- return 0;
-}
-
-static int wm8728_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- u16 reg;
- int i;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- case SND_SOC_BIAS_PREPARE:
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- /* Power everything up... */
- reg = snd_soc_read(codec, WM8728_DACCTL);
- snd_soc_write(codec, WM8728_DACCTL, reg & ~0x4);
-
- /* ..then sync in the register cache. */
- for (i = 0; i < ARRAY_SIZE(wm8728_reg_defaults); i++)
- snd_soc_write(codec, i,
- snd_soc_read(codec, i));
- }
- break;
-
- case SND_SOC_BIAS_OFF:
- reg = snd_soc_read(codec, WM8728_DACCTL);
- snd_soc_write(codec, WM8728_DACCTL, reg | 0x4);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define WM8728_RATES (SNDRV_PCM_RATE_8000_192000)
-
-#define WM8728_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops wm8728_dai_ops = {
- .hw_params = wm8728_hw_params,
- .digital_mute = wm8728_mute,
- .set_fmt = wm8728_set_dai_fmt,
-};
-
-static struct snd_soc_dai_driver wm8728_dai = {
- .name = "wm8728-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = WM8728_RATES,
- .formats = WM8728_FORMATS,
- },
- .ops = &wm8728_dai_ops,
-};
-
-static int wm8728_suspend(struct snd_soc_codec *codec)
-{
- wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int wm8728_resume(struct snd_soc_codec *codec)
-{
- wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-
-static int wm8728_probe(struct snd_soc_codec *codec)
-{
- struct wm8728_priv *wm8728 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8728->control_type);
- if (ret < 0) {
- printk(KERN_ERR "wm8728: failed to configure cache I/O: %d\n",
- ret);
- return ret;
- }
-
- /* power on device */
- wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return ret;
-}
-
-static int wm8728_remove(struct snd_soc_codec *codec)
-{
- wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8728 = {
- .probe = wm8728_probe,
- .remove = wm8728_remove,
- .suspend = wm8728_suspend,
- .resume = wm8728_resume,
- .set_bias_level = wm8728_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8728_reg_defaults,
- .controls = wm8728_snd_controls,
- .num_controls = ARRAY_SIZE(wm8728_snd_controls),
- .dapm_widgets = wm8728_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8728_dapm_widgets),
- .dapm_routes = wm8728_intercon,
- .num_dapm_routes = ARRAY_SIZE(wm8728_intercon),
-};
-
-static const struct of_device_id wm8728_of_match[] = {
- { .compatible = "wlf,wm8728", },
- { }
-};
-MODULE_DEVICE_TABLE(of, wm8728_of_match);
-
-#if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8728_spi_probe(struct spi_device *spi)
-{
- struct wm8728_priv *wm8728;
- int ret;
-
- wm8728 = kzalloc(sizeof(struct wm8728_priv), GFP_KERNEL);
- if (wm8728 == NULL)
- return -ENOMEM;
-
- wm8728->control_type = SND_SOC_SPI;
- spi_set_drvdata(spi, wm8728);
-
- ret = snd_soc_register_codec(&spi->dev,
- &soc_codec_dev_wm8728, &wm8728_dai, 1);
- if (ret < 0)
- kfree(wm8728);
- return ret;
-}
-
-static int __devexit wm8728_spi_remove(struct spi_device *spi)
-{
- snd_soc_unregister_codec(&spi->dev);
- kfree(spi_get_drvdata(spi));
- return 0;
-}
-
-static struct spi_driver wm8728_spi_driver = {
- .driver = {
- .name = "wm8728",
- .owner = THIS_MODULE,
- .of_match_table = wm8728_of_match,
- },
- .probe = wm8728_spi_probe,
- .remove = __devexit_p(wm8728_spi_remove),
-};
-#endif /* CONFIG_SPI_MASTER */
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8728_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8728_priv *wm8728;
- int ret;
-
- wm8728 = kzalloc(sizeof(struct wm8728_priv), GFP_KERNEL);
- if (wm8728 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm8728);
- wm8728->control_type = SND_SOC_I2C;
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8728, &wm8728_dai, 1);
- if (ret < 0)
- kfree(wm8728);
- return ret;
-}
-
-static __devexit int wm8728_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-static const struct i2c_device_id wm8728_i2c_id[] = {
- { "wm8728", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8728_i2c_id);
-
-static struct i2c_driver wm8728_i2c_driver = {
- .driver = {
- .name = "wm8728",
- .owner = THIS_MODULE,
- .of_match_table = wm8728_of_match,
- },
- .probe = wm8728_i2c_probe,
- .remove = __devexit_p(wm8728_i2c_remove),
- .id_table = wm8728_i2c_id,
-};
-#endif
-
-static int __init wm8728_modinit(void)
-{
- int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&wm8728_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8728 I2C driver: %d\n",
- ret);
- }
-#endif
-#if defined(CONFIG_SPI_MASTER)
- ret = spi_register_driver(&wm8728_spi_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8728 SPI driver: %d\n",
- ret);
- }
-#endif
- return ret;
-}
-module_init(wm8728_modinit);
-
-static void __exit wm8728_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&wm8728_i2c_driver);
-#endif
-#if defined(CONFIG_SPI_MASTER)
- spi_unregister_driver(&wm8728_spi_driver);
-#endif
-}
-module_exit(wm8728_exit);
-
-MODULE_DESCRIPTION("ASoC WM8728 driver");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8728.h b/ANDROID_3.4.5/sound/soc/codecs/wm8728.h
deleted file mode 100644
index 8aea362f..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8728.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * wm8728.h -- WM8728 ASoC codec driver
- *
- * Copyright 2008 Wolfson Microelectronics plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8728_H
-#define _WM8728_H
-
-#define WM8728_DACLVOL 0x00
-#define WM8728_DACRVOL 0x01
-#define WM8728_DACCTL 0x02
-#define WM8728_IFCTL 0x03
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8731.c b/ANDROID_3.4.5/sound/soc/codecs/wm8731.c
deleted file mode 100644
index a32caa72..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8731.c
+++ /dev/null
@@ -1,787 +0,0 @@
-/*
- * wm8731.c -- WM8731 ALSA SoC Audio driver
- *
- * Copyright 2005 Openedhand Ltd.
- *
- * Author: Richard Purdie <richard@openedhand.com>
- *
- * Based on wm8753.c by Liam Girdwood
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/regmap.h>
-#include <linux/regulator/consumer.h>
-#include <linux/spi/spi.h>
-#include <linux/of_device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "wm8731.h"
-
-#define WM8731_NUM_SUPPLIES 4
-static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
- "AVDD",
- "HPVDD",
- "DCVDD",
- "DBVDD",
-};
-
-/* codec private data */
-struct wm8731_priv {
- struct regmap *regmap;
- struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES];
- unsigned int sysclk;
- int sysclk_type;
- int playback_fs;
- bool deemph;
-};
-
-
-/*
- * wm8731 register cache
- */
-static const struct reg_default wm8731_reg_defaults[] = {
- { 0, 0x0097 },
- { 1, 0x0097 },
- { 2, 0x0079 },
- { 3, 0x0079 },
- { 4, 0x000a },
- { 5, 0x0008 },
- { 6, 0x009f },
- { 7, 0x000a },
- { 8, 0x0000 },
- { 9, 0x0000 },
-};
-
-static bool wm8731_volatile(struct device *dev, unsigned int reg)
-{
- return reg == WM8731_RESET;
-}
-
-static bool wm8731_writeable(struct device *dev, unsigned int reg)
-{
- return reg <= WM8731_RESET;
-}
-
-#define wm8731_reset(c) snd_soc_write(c, WM8731_RESET, 0)
-
-static const char *wm8731_input_select[] = {"Line In", "Mic"};
-
-static const struct soc_enum wm8731_insel_enum =
- SOC_ENUM_SINGLE(WM8731_APANA, 2, 2, wm8731_input_select);
-
-static int wm8731_deemph[] = { 0, 32000, 44100, 48000 };
-
-static int wm8731_set_deemph(struct snd_soc_codec *codec)
-{
- struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
- int val, i, best;
-
- /* If we're using deemphasis select the nearest available sample
- * rate.
- */
- if (wm8731->deemph) {
- best = 1;
- for (i = 2; i < ARRAY_SIZE(wm8731_deemph); i++) {
- if (abs(wm8731_deemph[i] - wm8731->playback_fs) <
- abs(wm8731_deemph[best] - wm8731->playback_fs))
- best = i;
- }
-
- val = best << 1;
- } else {
- best = 0;
- val = 0;
- }
-
- dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n",
- best, wm8731_deemph[best]);
-
- return snd_soc_update_bits(codec, WM8731_APDIGI, 0x6, val);
-}
-
-static int wm8731_get_deemph(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.enumerated.item[0] = wm8731->deemph;
-
- return 0;
-}
-
-static int wm8731_put_deemph(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
- int deemph = ucontrol->value.enumerated.item[0];
- int ret = 0;
-
- if (deemph > 1)
- return -EINVAL;
-
- mutex_lock(&codec->mutex);
- if (wm8731->deemph != deemph) {
- wm8731->deemph = deemph;
-
- wm8731_set_deemph(codec);
-
- ret = 1;
- }
- mutex_unlock(&codec->mutex);
-
- return ret;
-}
-
-static const DECLARE_TLV_DB_SCALE(in_tlv, -3450, 150, 0);
-static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -1500, 300, 0);
-static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
-static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 2000, 0);
-
-static const struct snd_kcontrol_new wm8731_snd_controls[] = {
-
-SOC_DOUBLE_R_TLV("Master Playback Volume", WM8731_LOUT1V, WM8731_ROUT1V,
- 0, 127, 0, out_tlv),
-SOC_DOUBLE_R("Master Playback ZC Switch", WM8731_LOUT1V, WM8731_ROUT1V,
- 7, 1, 0),
-
-SOC_DOUBLE_R_TLV("Capture Volume", WM8731_LINVOL, WM8731_RINVOL, 0, 31, 0,
- in_tlv),
-SOC_DOUBLE_R("Line Capture Switch", WM8731_LINVOL, WM8731_RINVOL, 7, 1, 1),
-
-SOC_SINGLE_TLV("Mic Boost Volume", WM8731_APANA, 0, 1, 0, mic_tlv),
-SOC_SINGLE("Mic Capture Switch", WM8731_APANA, 1, 1, 1),
-
-SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1,
- sidetone_tlv),
-
-SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1),
-SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0),
-
-SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0,
- wm8731_get_deemph, wm8731_put_deemph),
-};
-
-/* Output Mixer */
-static const struct snd_kcontrol_new wm8731_output_mixer_controls[] = {
-SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0),
-SOC_DAPM_SINGLE("Mic Sidetone Switch", WM8731_APANA, 5, 1, 0),
-SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0),
-};
-
-/* Input mux */
-static const struct snd_kcontrol_new wm8731_input_mux_controls =
-SOC_DAPM_ENUM("Input Select", wm8731_insel_enum);
-
-static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = {
-SND_SOC_DAPM_SUPPLY("ACTIVE",WM8731_ACTIVE, 0, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("OSC", WM8731_PWR, 5, 1, NULL, 0),
-SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1,
- &wm8731_output_mixer_controls[0],
- ARRAY_SIZE(wm8731_output_mixer_controls)),
-SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8731_PWR, 3, 1),
-SND_SOC_DAPM_OUTPUT("LOUT"),
-SND_SOC_DAPM_OUTPUT("LHPOUT"),
-SND_SOC_DAPM_OUTPUT("ROUT"),
-SND_SOC_DAPM_OUTPUT("RHPOUT"),
-SND_SOC_DAPM_ADC("ADC", "HiFi Capture", WM8731_PWR, 2, 1),
-SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, &wm8731_input_mux_controls),
-SND_SOC_DAPM_PGA("Line Input", WM8731_PWR, 0, 1, NULL, 0),
-SND_SOC_DAPM_MICBIAS("Mic Bias", WM8731_PWR, 1, 1),
-SND_SOC_DAPM_INPUT("MICIN"),
-SND_SOC_DAPM_INPUT("RLINEIN"),
-SND_SOC_DAPM_INPUT("LLINEIN"),
-};
-
-static int wm8731_check_osc(struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink)
-{
- struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(source->codec);
-
- return wm8731->sysclk_type == WM8731_SYSCLK_XTAL;
-}
-
-static const struct snd_soc_dapm_route wm8731_intercon[] = {
- {"DAC", NULL, "OSC", wm8731_check_osc},
- {"ADC", NULL, "OSC", wm8731_check_osc},
- {"DAC", NULL, "ACTIVE"},
- {"ADC", NULL, "ACTIVE"},
-
- /* output mixer */
- {"Output Mixer", "Line Bypass Switch", "Line Input"},
- {"Output Mixer", "HiFi Playback Switch", "DAC"},
- {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"},
-
- /* outputs */
- {"RHPOUT", NULL, "Output Mixer"},
- {"ROUT", NULL, "Output Mixer"},
- {"LHPOUT", NULL, "Output Mixer"},
- {"LOUT", NULL, "Output Mixer"},
-
- /* input mux */
- {"Input Mux", "Line In", "Line Input"},
- {"Input Mux", "Mic", "Mic Bias"},
- {"ADC", NULL, "Input Mux"},
-
- /* inputs */
- {"Line Input", NULL, "LLINEIN"},
- {"Line Input", NULL, "RLINEIN"},
- {"Mic Bias", NULL, "MICIN"},
-};
-
-struct _coeff_div {
- u32 mclk;
- u32 rate;
- u16 fs;
- u8 sr:4;
- u8 bosr:1;
- u8 usb:1;
-};
-
-/* codec mclk clock divider coefficients */
-static const struct _coeff_div coeff_div[] = {
- /* 48k */
- {12288000, 48000, 256, 0x0, 0x0, 0x0},
- {18432000, 48000, 384, 0x0, 0x1, 0x0},
- {12000000, 48000, 250, 0x0, 0x0, 0x1},
-
- /* 32k */
- {12288000, 32000, 384, 0x6, 0x0, 0x0},
- {18432000, 32000, 576, 0x6, 0x1, 0x0},
- {12000000, 32000, 375, 0x6, 0x0, 0x1},
-
- /* 8k */
- {12288000, 8000, 1536, 0x3, 0x0, 0x0},
- {18432000, 8000, 2304, 0x3, 0x1, 0x0},
- {11289600, 8000, 1408, 0xb, 0x0, 0x0},
- {16934400, 8000, 2112, 0xb, 0x1, 0x0},
- {12000000, 8000, 1500, 0x3, 0x0, 0x1},
-
- /* 96k */
- {12288000, 96000, 128, 0x7, 0x0, 0x0},
- {18432000, 96000, 192, 0x7, 0x1, 0x0},
- {12000000, 96000, 125, 0x7, 0x0, 0x1},
-
- /* 44.1k */
- {11289600, 44100, 256, 0x8, 0x0, 0x0},
- {16934400, 44100, 384, 0x8, 0x1, 0x0},
- {12000000, 44100, 272, 0x8, 0x1, 0x1},
-
- /* 88.2k */
- {11289600, 88200, 128, 0xf, 0x0, 0x0},
- {16934400, 88200, 192, 0xf, 0x1, 0x0},
- {12000000, 88200, 136, 0xf, 0x1, 0x1},
-};
-
-static inline int get_coeff(int mclk, int rate)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
- if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
- return i;
- }
- return 0;
-}
-
-static int wm8731_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
- u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3;
- int i = get_coeff(wm8731->sysclk, params_rate(params));
- u16 srate = (coeff_div[i].sr << 2) |
- (coeff_div[i].bosr << 1) | coeff_div[i].usb;
-
- wm8731->playback_fs = params_rate(params);
-
- snd_soc_write(codec, WM8731_SRATE, srate);
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= 0x0004;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface |= 0x0008;
- break;
- }
-
- wm8731_set_deemph(codec);
-
- snd_soc_write(codec, WM8731_IFACE, iface);
- return 0;
-}
-
-static int wm8731_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 mute_reg = snd_soc_read(codec, WM8731_APDIGI) & 0xfff7;
-
- if (mute)
- snd_soc_write(codec, WM8731_APDIGI, mute_reg | 0x8);
- else
- snd_soc_write(codec, WM8731_APDIGI, mute_reg);
- return 0;
-}
-
-static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
-
- switch (clk_id) {
- case WM8731_SYSCLK_XTAL:
- case WM8731_SYSCLK_MCLK:
- wm8731->sysclk_type = clk_id;
- break;
- default:
- return -EINVAL;
- }
-
- switch (freq) {
- case 11289600:
- case 12000000:
- case 12288000:
- case 16934400:
- case 18432000:
- wm8731->sysclk = freq;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_dapm_sync(&codec->dapm);
-
- return 0;
-}
-
-
-static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 iface = 0;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- iface |= 0x0040;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= 0x0002;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= 0x0001;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= 0x0003;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- iface |= 0x0013;
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= 0x0090;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= 0x0080;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- iface |= 0x0010;
- break;
- default:
- return -EINVAL;
- }
-
- /* set iface */
- snd_soc_write(codec, WM8731_IFACE, iface);
- return 0;
-}
-
-static int wm8731_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
- int ret;
- u16 reg;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
- wm8731->supplies);
- if (ret != 0)
- return ret;
-
- regcache_sync(wm8731->regmap);
- }
-
- /* Clear PWROFF, gate CLKOUT, everything else as-is */
- reg = snd_soc_read(codec, WM8731_PWR) & 0xff7f;
- snd_soc_write(codec, WM8731_PWR, reg | 0x0040);
- break;
- case SND_SOC_BIAS_OFF:
- snd_soc_write(codec, WM8731_PWR, 0xffff);
- regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies),
- wm8731->supplies);
- regcache_mark_dirty(wm8731->regmap);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define WM8731_RATES SNDRV_PCM_RATE_8000_96000
-
-#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops wm8731_dai_ops = {
- .hw_params = wm8731_hw_params,
- .digital_mute = wm8731_mute,
- .set_sysclk = wm8731_set_dai_sysclk,
- .set_fmt = wm8731_set_dai_fmt,
-};
-
-static struct snd_soc_dai_driver wm8731_dai = {
- .name = "wm8731-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8731_RATES,
- .formats = WM8731_FORMATS,},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8731_RATES,
- .formats = WM8731_FORMATS,},
- .ops = &wm8731_dai_ops,
- .symmetric_rates = 1,
-};
-
-#ifdef CONFIG_PM
-static int wm8731_suspend(struct snd_soc_codec *codec)
-{
- wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int wm8731_resume(struct snd_soc_codec *codec)
-{
- wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-#else
-#define wm8731_suspend NULL
-#define wm8731_resume NULL
-#endif
-
-static int wm8731_probe(struct snd_soc_codec *codec)
-{
- struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
- int ret = 0, i;
-
- codec->control_data = wm8731->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++)
- wm8731->supplies[i].supply = wm8731_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8731->supplies),
- wm8731->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- return ret;
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
- wm8731->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
- goto err_regulator_get;
- }
-
- ret = wm8731_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
- goto err_regulator_enable;
- }
-
- wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* Latch the update bits */
- snd_soc_update_bits(codec, WM8731_LOUT1V, 0x100, 0);
- snd_soc_update_bits(codec, WM8731_ROUT1V, 0x100, 0);
- snd_soc_update_bits(codec, WM8731_LINVOL, 0x100, 0);
- snd_soc_update_bits(codec, WM8731_RINVOL, 0x100, 0);
-
- /* Disable bypass path by default */
- snd_soc_update_bits(codec, WM8731_APANA, 0x8, 0);
-
- /* Regulators will have been enabled by bias management */
- regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
-
- return 0;
-
-err_regulator_enable:
- regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
-err_regulator_get:
- regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
-
- return ret;
-}
-
-/* power down chip */
-static int wm8731_remove(struct snd_soc_codec *codec)
-{
- struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
-
- wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
- regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
- .probe = wm8731_probe,
- .remove = wm8731_remove,
- .suspend = wm8731_suspend,
- .resume = wm8731_resume,
- .set_bias_level = wm8731_set_bias_level,
- .dapm_widgets = wm8731_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets),
- .dapm_routes = wm8731_intercon,
- .num_dapm_routes = ARRAY_SIZE(wm8731_intercon),
- .controls = wm8731_snd_controls,
- .num_controls = ARRAY_SIZE(wm8731_snd_controls),
-};
-
-static const struct of_device_id wm8731_of_match[] = {
- { .compatible = "wlf,wm8731", },
- { }
-};
-
-MODULE_DEVICE_TABLE(of, wm8731_of_match);
-
-static const struct regmap_config wm8731_regmap = {
- .reg_bits = 7,
- .val_bits = 9,
-
- .max_register = WM8731_RESET,
- .volatile_reg = wm8731_volatile,
- .writeable_reg = wm8731_writeable,
-
- .cache_type = REGCACHE_RBTREE,
- .reg_defaults = wm8731_reg_defaults,
- .num_reg_defaults = ARRAY_SIZE(wm8731_reg_defaults),
-};
-
-#if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8731_spi_probe(struct spi_device *spi)
-{
- struct wm8731_priv *wm8731;
- int ret;
-
- wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
- if (wm8731 == NULL)
- return -ENOMEM;
-
- wm8731->regmap = regmap_init_spi(spi, &wm8731_regmap);
- if (IS_ERR(wm8731->regmap)) {
- ret = PTR_ERR(wm8731->regmap);
- dev_err(&spi->dev, "Failed to allocate register map: %d\n",
- ret);
- goto err;
- }
-
- spi_set_drvdata(spi, wm8731);
-
- ret = snd_soc_register_codec(&spi->dev,
- &soc_codec_dev_wm8731, &wm8731_dai, 1);
- if (ret != 0) {
- dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret);
- goto err_regmap;
- }
-
- return 0;
-
-err_regmap:
- regmap_exit(wm8731->regmap);
-err:
- kfree(wm8731);
- return ret;
-}
-
-static int __devexit wm8731_spi_remove(struct spi_device *spi)
-{
- struct wm8731_priv *wm8731 = spi_get_drvdata(spi);
-
- snd_soc_unregister_codec(&spi->dev);
- regmap_exit(wm8731->regmap);
- kfree(wm8731);
- return 0;
-}
-
-static struct spi_driver wm8731_spi_driver = {
- .driver = {
- .name = "wm8731",
- .owner = THIS_MODULE,
- .of_match_table = wm8731_of_match,
- },
- .probe = wm8731_spi_probe,
- .remove = __devexit_p(wm8731_spi_remove),
-};
-#endif /* CONFIG_SPI_MASTER */
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8731_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8731_priv *wm8731;
- int ret;
-
- wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
- if (wm8731 == NULL)
- return -ENOMEM;
-
- wm8731->regmap = regmap_init_i2c(i2c, &wm8731_regmap);
- if (IS_ERR(wm8731->regmap)) {
- ret = PTR_ERR(wm8731->regmap);
- dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
- ret);
- goto err;
- }
-
- i2c_set_clientdata(i2c, wm8731);
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8731, &wm8731_dai, 1);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
- goto err_regmap;
- }
-
- return 0;
-
-err_regmap:
- regmap_exit(wm8731->regmap);
-err:
- kfree(wm8731);
- return ret;
-}
-
-static __devexit int wm8731_i2c_remove(struct i2c_client *client)
-{
- struct wm8731_priv *wm8731 = i2c_get_clientdata(client);
- snd_soc_unregister_codec(&client->dev);
- regmap_exit(wm8731->regmap);
- kfree(wm8731);
- return 0;
-}
-
-static const struct i2c_device_id wm8731_i2c_id[] = {
- { "wm8731", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id);
-
-static struct i2c_driver wm8731_i2c_driver = {
- .driver = {
- .name = "wm8731",
- .owner = THIS_MODULE,
- .of_match_table = wm8731_of_match,
- },
- .probe = wm8731_i2c_probe,
- .remove = __devexit_p(wm8731_i2c_remove),
- .id_table = wm8731_i2c_id,
-};
-#endif
-
-static int __init wm8731_modinit(void)
-{
- int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&wm8731_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8731 I2C driver: %d\n",
- ret);
- }
-#endif
-#if defined(CONFIG_SPI_MASTER)
- ret = spi_register_driver(&wm8731_spi_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8731 SPI driver: %d\n",
- ret);
- }
-#endif
- return ret;
-}
-module_init(wm8731_modinit);
-
-static void __exit wm8731_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&wm8731_i2c_driver);
-#endif
-#if defined(CONFIG_SPI_MASTER)
- spi_unregister_driver(&wm8731_spi_driver);
-#endif
-}
-module_exit(wm8731_exit);
-
-MODULE_DESCRIPTION("ASoC WM8731 driver");
-MODULE_AUTHOR("Richard Purdie");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8731.h b/ANDROID_3.4.5/sound/soc/codecs/wm8731.h
deleted file mode 100644
index e9c0c76a..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8731.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * wm8731.h -- WM8731 Soc Audio driver
- *
- * Copyright 2005 Openedhand Ltd.
- *
- * Author: Richard Purdie <richard@openedhand.com>
- *
- * Based on wm8753.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8731_H
-#define _WM8731_H
-
-/* WM8731 register space */
-
-#define WM8731_LINVOL 0x00
-#define WM8731_RINVOL 0x01
-#define WM8731_LOUT1V 0x02
-#define WM8731_ROUT1V 0x03
-#define WM8731_APANA 0x04
-#define WM8731_APDIGI 0x05
-#define WM8731_PWR 0x06
-#define WM8731_IFACE 0x07
-#define WM8731_SRATE 0x08
-#define WM8731_ACTIVE 0x09
-#define WM8731_RESET 0x0f
-
-#define WM8731_CACHEREGNUM 10
-
-#define WM8731_SYSCLK_XTAL 1
-#define WM8731_SYSCLK_MCLK 2
-
-#define WM8731_DAI 0
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8737.c b/ANDROID_3.4.5/sound/soc/codecs/wm8737.c
deleted file mode 100644
index 4fe9d191..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8737.c
+++ /dev/null
@@ -1,763 +0,0 @@
-/*
- * wm8737.c -- WM8737 ALSA SoC Audio driver
- *
- * Copyright 2010 Wolfson Microelectronics plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/regulator/consumer.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/of_device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "wm8737.h"
-
-#define WM8737_NUM_SUPPLIES 4
-static const char *wm8737_supply_names[WM8737_NUM_SUPPLIES] = {
- "DCVDD",
- "DBVDD",
- "AVDD",
- "MVDD",
-};
-
-/* codec private data */
-struct wm8737_priv {
- enum snd_soc_control_type control_type;
- struct regulator_bulk_data supplies[WM8737_NUM_SUPPLIES];
- unsigned int mclk;
-};
-
-static const u16 wm8737_reg[WM8737_REGISTER_COUNT] = {
- 0x00C3, /* R0 - Left PGA volume */
- 0x00C3, /* R1 - Right PGA volume */
- 0x0007, /* R2 - AUDIO path L */
- 0x0007, /* R3 - AUDIO path R */
- 0x0000, /* R4 - 3D Enhance */
- 0x0000, /* R5 - ADC Control */
- 0x0000, /* R6 - Power Management */
- 0x000A, /* R7 - Audio Format */
- 0x0000, /* R8 - Clocking */
- 0x000F, /* R9 - MIC Preamp Control */
- 0x0003, /* R10 - Misc Bias Control */
- 0x0000, /* R11 - Noise Gate */
- 0x007C, /* R12 - ALC1 */
- 0x0000, /* R13 - ALC2 */
- 0x0032, /* R14 - ALC3 */
-};
-
-static int wm8737_reset(struct snd_soc_codec *codec)
-{
- return snd_soc_write(codec, WM8737_RESET, 0);
-}
-
-static const unsigned int micboost_tlv[] = {
- TLV_DB_RANGE_HEAD(4),
- 0, 0, TLV_DB_SCALE_ITEM(1300, 0, 0),
- 1, 1, TLV_DB_SCALE_ITEM(1800, 0, 0),
- 2, 2, TLV_DB_SCALE_ITEM(2800, 0, 0),
- 3, 3, TLV_DB_SCALE_ITEM(3300, 0, 0),
-};
-static const DECLARE_TLV_DB_SCALE(pga_tlv, -9750, 50, 1);
-static const DECLARE_TLV_DB_SCALE(adc_tlv, -600, 600, 0);
-static const DECLARE_TLV_DB_SCALE(ng_tlv, -7800, 600, 0);
-static const DECLARE_TLV_DB_SCALE(alc_max_tlv, -1200, 600, 0);
-static const DECLARE_TLV_DB_SCALE(alc_target_tlv, -1800, 100, 0);
-
-static const char *micbias_enum_text[] = {
- "25%",
- "50%",
- "75%",
- "100%",
-};
-
-static const struct soc_enum micbias_enum =
- SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 0, 4, micbias_enum_text);
-
-static const char *low_cutoff_text[] = {
- "Low", "High"
-};
-
-static const struct soc_enum low_3d =
- SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 6, 2, low_cutoff_text);
-
-static const char *high_cutoff_text[] = {
- "High", "Low"
-};
-
-static const struct soc_enum high_3d =
- SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 5, 2, high_cutoff_text);
-
-static const char *alc_fn_text[] = {
- "Disabled", "Right", "Left", "Stereo"
-};
-
-static const struct soc_enum alc_fn =
- SOC_ENUM_SINGLE(WM8737_ALC1, 7, 4, alc_fn_text);
-
-static const char *alc_hold_text[] = {
- "0", "2.67ms", "5.33ms", "10.66ms", "21.32ms", "42.64ms", "85.28ms",
- "170.56ms", "341.12ms", "682.24ms", "1.364s", "2.728s", "5.458s",
- "10.916s", "21.832s", "43.691s"
-};
-
-static const struct soc_enum alc_hold =
- SOC_ENUM_SINGLE(WM8737_ALC2, 0, 16, alc_hold_text);
-
-static const char *alc_atk_text[] = {
- "8.4ms", "16.8ms", "33.6ms", "67.2ms", "134.4ms", "268.8ms", "537.6ms",
- "1.075s", "2.15s", "4.3s", "8.6s"
-};
-
-static const struct soc_enum alc_atk =
- SOC_ENUM_SINGLE(WM8737_ALC3, 0, 11, alc_atk_text);
-
-static const char *alc_dcy_text[] = {
- "33.6ms", "67.2ms", "134.4ms", "268.8ms", "537.6ms", "1.075s", "2.15s",
- "4.3s", "8.6s", "17.2s", "34.41s"
-};
-
-static const struct soc_enum alc_dcy =
- SOC_ENUM_SINGLE(WM8737_ALC3, 4, 11, alc_dcy_text);
-
-static const struct snd_kcontrol_new wm8737_snd_controls[] = {
-SOC_DOUBLE_R_TLV("Mic Boost Volume", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
- 6, 3, 0, micboost_tlv),
-SOC_DOUBLE_R("Mic Boost Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
- 4, 1, 0),
-SOC_DOUBLE("Mic ZC Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
- 3, 1, 0),
-
-SOC_DOUBLE_R_TLV("Capture Volume", WM8737_LEFT_PGA_VOLUME,
- WM8737_RIGHT_PGA_VOLUME, 0, 255, 0, pga_tlv),
-SOC_DOUBLE("Capture ZC Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
- 2, 1, 0),
-
-SOC_DOUBLE("INPUT1 DC Bias Switch", WM8737_MISC_BIAS_CONTROL, 0, 1, 1, 0),
-
-SOC_ENUM("Mic PGA Bias", micbias_enum),
-SOC_SINGLE("ADC Low Power Switch", WM8737_ADC_CONTROL, 2, 1, 0),
-SOC_SINGLE("High Pass Filter Switch", WM8737_ADC_CONTROL, 0, 1, 1),
-SOC_DOUBLE("Polarity Invert Switch", WM8737_ADC_CONTROL, 5, 6, 1, 0),
-
-SOC_SINGLE("3D Switch", WM8737_3D_ENHANCE, 0, 1, 0),
-SOC_SINGLE("3D Depth", WM8737_3D_ENHANCE, 1, 15, 0),
-SOC_ENUM("3D Low Cut-off", low_3d),
-SOC_ENUM("3D High Cut-off", low_3d),
-SOC_SINGLE_TLV("3D ADC Volume", WM8737_3D_ENHANCE, 7, 1, 1, adc_tlv),
-
-SOC_SINGLE("Noise Gate Switch", WM8737_NOISE_GATE, 0, 1, 0),
-SOC_SINGLE_TLV("Noise Gate Threshold Volume", WM8737_NOISE_GATE, 2, 7, 0,
- ng_tlv),
-
-SOC_ENUM("ALC", alc_fn),
-SOC_SINGLE_TLV("ALC Max Gain Volume", WM8737_ALC1, 4, 7, 0, alc_max_tlv),
-SOC_SINGLE_TLV("ALC Target Volume", WM8737_ALC1, 0, 15, 0, alc_target_tlv),
-SOC_ENUM("ALC Hold Time", alc_hold),
-SOC_SINGLE("ALC ZC Switch", WM8737_ALC2, 4, 1, 0),
-SOC_ENUM("ALC Attack Time", alc_atk),
-SOC_ENUM("ALC Decay Time", alc_dcy),
-};
-
-static const char *linsel_text[] = {
- "LINPUT1", "LINPUT2", "LINPUT3", "LINPUT1 DC",
-};
-
-static const struct soc_enum linsel_enum =
- SOC_ENUM_SINGLE(WM8737_AUDIO_PATH_L, 7, 4, linsel_text);
-
-static const struct snd_kcontrol_new linsel_mux =
- SOC_DAPM_ENUM("LINSEL", linsel_enum);
-
-
-static const char *rinsel_text[] = {
- "RINPUT1", "RINPUT2", "RINPUT3", "RINPUT1 DC",
-};
-
-static const struct soc_enum rinsel_enum =
- SOC_ENUM_SINGLE(WM8737_AUDIO_PATH_R, 7, 4, rinsel_text);
-
-static const struct snd_kcontrol_new rinsel_mux =
- SOC_DAPM_ENUM("RINSEL", rinsel_enum);
-
-static const char *bypass_text[] = {
- "Direct", "Preamp"
-};
-
-static const struct soc_enum lbypass_enum =
- SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 2, 2, bypass_text);
-
-static const struct snd_kcontrol_new lbypass_mux =
- SOC_DAPM_ENUM("Left Bypass", lbypass_enum);
-
-
-static const struct soc_enum rbypass_enum =
- SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 3, 2, bypass_text);
-
-static const struct snd_kcontrol_new rbypass_mux =
- SOC_DAPM_ENUM("Left Bypass", rbypass_enum);
-
-static const struct snd_soc_dapm_widget wm8737_dapm_widgets[] = {
-SND_SOC_DAPM_INPUT("LINPUT1"),
-SND_SOC_DAPM_INPUT("LINPUT2"),
-SND_SOC_DAPM_INPUT("LINPUT3"),
-SND_SOC_DAPM_INPUT("RINPUT1"),
-SND_SOC_DAPM_INPUT("RINPUT2"),
-SND_SOC_DAPM_INPUT("RINPUT3"),
-SND_SOC_DAPM_INPUT("LACIN"),
-SND_SOC_DAPM_INPUT("RACIN"),
-
-SND_SOC_DAPM_MUX("LINSEL", SND_SOC_NOPM, 0, 0, &linsel_mux),
-SND_SOC_DAPM_MUX("RINSEL", SND_SOC_NOPM, 0, 0, &rinsel_mux),
-
-SND_SOC_DAPM_MUX("Left Preamp Mux", SND_SOC_NOPM, 0, 0, &lbypass_mux),
-SND_SOC_DAPM_MUX("Right Preamp Mux", SND_SOC_NOPM, 0, 0, &rbypass_mux),
-
-SND_SOC_DAPM_PGA("PGAL", WM8737_POWER_MANAGEMENT, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA("PGAR", WM8737_POWER_MANAGEMENT, 4, 0, NULL, 0),
-
-SND_SOC_DAPM_DAC("ADCL", NULL, WM8737_POWER_MANAGEMENT, 3, 0),
-SND_SOC_DAPM_DAC("ADCR", NULL, WM8737_POWER_MANAGEMENT, 2, 0),
-
-SND_SOC_DAPM_AIF_OUT("AIF", "Capture", 0, WM8737_POWER_MANAGEMENT, 6, 0),
-};
-
-static const struct snd_soc_dapm_route intercon[] = {
- { "LINSEL", "LINPUT1", "LINPUT1" },
- { "LINSEL", "LINPUT2", "LINPUT2" },
- { "LINSEL", "LINPUT3", "LINPUT3" },
- { "LINSEL", "LINPUT1 DC", "LINPUT1" },
-
- { "RINSEL", "RINPUT1", "RINPUT1" },
- { "RINSEL", "RINPUT2", "RINPUT2" },
- { "RINSEL", "RINPUT3", "RINPUT3" },
- { "RINSEL", "RINPUT1 DC", "RINPUT1" },
-
- { "Left Preamp Mux", "Preamp", "LINSEL" },
- { "Left Preamp Mux", "Direct", "LACIN" },
-
- { "Right Preamp Mux", "Preamp", "RINSEL" },
- { "Right Preamp Mux", "Direct", "RACIN" },
-
- { "PGAL", NULL, "Left Preamp Mux" },
- { "PGAR", NULL, "Right Preamp Mux" },
-
- { "ADCL", NULL, "PGAL" },
- { "ADCR", NULL, "PGAR" },
-
- { "AIF", NULL, "ADCL" },
- { "AIF", NULL, "ADCR" },
-};
-
-static int wm8737_add_widgets(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_new_controls(dapm, wm8737_dapm_widgets,
- ARRAY_SIZE(wm8737_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
-
- return 0;
-}
-
-/* codec mclk clock divider coefficients */
-static const struct {
- u32 mclk;
- u32 rate;
- u8 usb;
- u8 sr;
-} coeff_div[] = {
- { 12288000, 8000, 0, 0x4 },
- { 12288000, 12000, 0, 0x8 },
- { 12288000, 16000, 0, 0xa },
- { 12288000, 24000, 0, 0x1c },
- { 12288000, 32000, 0, 0xc },
- { 12288000, 48000, 0, 0 },
- { 12288000, 96000, 0, 0xe },
-
- { 11289600, 8000, 0, 0x14 },
- { 11289600, 11025, 0, 0x18 },
- { 11289600, 22050, 0, 0x1a },
- { 11289600, 44100, 0, 0x10 },
- { 11289600, 88200, 0, 0x1e },
-
- { 18432000, 8000, 0, 0x5 },
- { 18432000, 12000, 0, 0x9 },
- { 18432000, 16000, 0, 0xb },
- { 18432000, 24000, 0, 0x1b },
- { 18432000, 32000, 0, 0xd },
- { 18432000, 48000, 0, 0x1 },
- { 18432000, 96000, 0, 0x1f },
-
- { 16934400, 8000, 0, 0x15 },
- { 16934400, 11025, 0, 0x19 },
- { 16934400, 22050, 0, 0x1b },
- { 16934400, 44100, 0, 0x11 },
- { 16934400, 88200, 0, 0x1f },
-
- { 12000000, 8000, 1, 0x4 },
- { 12000000, 11025, 1, 0x19 },
- { 12000000, 12000, 1, 0x8 },
- { 12000000, 16000, 1, 0xa },
- { 12000000, 22050, 1, 0x1b },
- { 12000000, 24000, 1, 0x1c },
- { 12000000, 32000, 1, 0xc },
- { 12000000, 44100, 1, 0x11 },
- { 12000000, 48000, 1, 0x0 },
- { 12000000, 88200, 1, 0x1f },
- { 12000000, 96000, 1, 0xe },
-};
-
-static int wm8737_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
- int i;
- u16 clocking = 0;
- u16 af = 0;
-
- for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
- if (coeff_div[i].rate != params_rate(params))
- continue;
-
- if (coeff_div[i].mclk == wm8737->mclk)
- break;
-
- if (coeff_div[i].mclk == wm8737->mclk * 2) {
- clocking |= WM8737_CLKDIV2;
- break;
- }
- }
-
- if (i == ARRAY_SIZE(coeff_div)) {
- dev_err(codec->dev, "%dHz MCLK can't support %dHz\n",
- wm8737->mclk, params_rate(params));
- return -EINVAL;
- }
-
- clocking |= coeff_div[i].usb | (coeff_div[i].sr << WM8737_SR_SHIFT);
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- af |= 0x8;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- af |= 0x10;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- af |= 0x18;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT, WM8737_WL_MASK, af);
- snd_soc_update_bits(codec, WM8737_CLOCKING,
- WM8737_USB_MODE | WM8737_CLKDIV2 | WM8737_SR_MASK,
- clocking);
-
- return 0;
-}
-
-static int wm8737_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
- int i;
-
- for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
- if (freq == coeff_div[i].mclk ||
- freq == coeff_div[i].mclk * 2) {
- wm8737->mclk = freq;
- return 0;
- }
- }
-
- dev_err(codec->dev, "MCLK rate %dHz not supported\n", freq);
-
- return -EINVAL;
-}
-
-
-static int wm8737_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 af = 0;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- af |= WM8737_MS;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- af |= 0x2;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- af |= 0x1;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- af |= 0x3;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- af |= 0x13;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_NB_IF:
- af |= WM8737_LRP;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT,
- WM8737_FORMAT_MASK | WM8737_LRP | WM8737_MS, af);
-
- return 0;
-}
-
-static int wm8737_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- /* VMID at 2*75k */
- snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
- WM8737_VMIDSEL_MASK, 0);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
- wm8737->supplies);
- if (ret != 0) {
- dev_err(codec->dev,
- "Failed to enable supplies: %d\n",
- ret);
- return ret;
- }
-
- snd_soc_cache_sync(codec);
-
- /* Fast VMID ramp at 2*2.5k */
- snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
- WM8737_VMIDSEL_MASK, 0x4);
-
- /* Bring VMID up */
- snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT,
- WM8737_VMID_MASK |
- WM8737_VREF_MASK,
- WM8737_VMID_MASK |
- WM8737_VREF_MASK);
-
- msleep(500);
- }
-
- /* VMID at 2*300k */
- snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
- WM8737_VMIDSEL_MASK, 2);
-
- break;
-
- case SND_SOC_BIAS_OFF:
- snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT,
- WM8737_VMID_MASK | WM8737_VREF_MASK, 0);
-
- regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies),
- wm8737->supplies);
- break;
- }
-
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define WM8737_RATES SNDRV_PCM_RATE_8000_96000
-
-#define WM8737_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops wm8737_dai_ops = {
- .hw_params = wm8737_hw_params,
- .set_sysclk = wm8737_set_dai_sysclk,
- .set_fmt = wm8737_set_dai_fmt,
-};
-
-static struct snd_soc_dai_driver wm8737_dai = {
- .name = "wm8737",
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2, /* Mono modes not yet supported */
- .channels_max = 2,
- .rates = WM8737_RATES,
- .formats = WM8737_FORMATS,
- },
- .ops = &wm8737_dai_ops,
-};
-
-#ifdef CONFIG_PM
-static int wm8737_suspend(struct snd_soc_codec *codec)
-{
- wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm8737_resume(struct snd_soc_codec *codec)
-{
- wm8737_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-#else
-#define wm8737_suspend NULL
-#define wm8737_resume NULL
-#endif
-
-static int wm8737_probe(struct snd_soc_codec *codec)
-{
- struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
- int ret, i;
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8737->control_type);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++)
- wm8737->supplies[i].supply = wm8737_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8737->supplies),
- wm8737->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- return ret;
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
- wm8737->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
- goto err_get;
- }
-
- ret = wm8737_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- goto err_enable;
- }
-
- snd_soc_update_bits(codec, WM8737_LEFT_PGA_VOLUME, WM8737_LVU,
- WM8737_LVU);
- snd_soc_update_bits(codec, WM8737_RIGHT_PGA_VOLUME, WM8737_RVU,
- WM8737_RVU);
-
- wm8737_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* Bias level configuration will have done an extra enable */
- regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
-
- snd_soc_add_codec_controls(codec, wm8737_snd_controls,
- ARRAY_SIZE(wm8737_snd_controls));
- wm8737_add_widgets(codec);
-
- return 0;
-
-err_enable:
- regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
-err_get:
- regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
-
- return ret;
-}
-
-static int wm8737_remove(struct snd_soc_codec *codec)
-{
- struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
-
- wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF);
- regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8737 = {
- .probe = wm8737_probe,
- .remove = wm8737_remove,
- .suspend = wm8737_suspend,
- .resume = wm8737_resume,
- .set_bias_level = wm8737_set_bias_level,
-
- .reg_cache_size = WM8737_REGISTER_COUNT - 1, /* Skip reset */
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8737_reg,
-};
-
-static const struct of_device_id wm8737_of_match[] = {
- { .compatible = "wlf,wm8737", },
- { }
-};
-
-MODULE_DEVICE_TABLE(of, wm8737_of_match);
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8737_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8737_priv *wm8737;
- int ret;
-
- wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL);
- if (wm8737 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm8737);
- wm8737->control_type = SND_SOC_I2C;
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8737, &wm8737_dai, 1);
- if (ret < 0)
- kfree(wm8737);
- return ret;
-
-}
-
-static __devexit int wm8737_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-static const struct i2c_device_id wm8737_i2c_id[] = {
- { "wm8737", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8737_i2c_id);
-
-static struct i2c_driver wm8737_i2c_driver = {
- .driver = {
- .name = "wm8737",
- .owner = THIS_MODULE,
- .of_match_table = wm8737_of_match,
- },
- .probe = wm8737_i2c_probe,
- .remove = __devexit_p(wm8737_i2c_remove),
- .id_table = wm8737_i2c_id,
-};
-#endif
-
-#if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8737_spi_probe(struct spi_device *spi)
-{
- struct wm8737_priv *wm8737;
- int ret;
-
- wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL);
- if (wm8737 == NULL)
- return -ENOMEM;
-
- wm8737->control_type = SND_SOC_SPI;
- spi_set_drvdata(spi, wm8737);
-
- ret = snd_soc_register_codec(&spi->dev,
- &soc_codec_dev_wm8737, &wm8737_dai, 1);
- if (ret < 0)
- kfree(wm8737);
- return ret;
-}
-
-static int __devexit wm8737_spi_remove(struct spi_device *spi)
-{
- snd_soc_unregister_codec(&spi->dev);
- kfree(spi_get_drvdata(spi));
- return 0;
-}
-
-static struct spi_driver wm8737_spi_driver = {
- .driver = {
- .name = "wm8737",
- .owner = THIS_MODULE,
- .of_match_table = wm8737_of_match,
- },
- .probe = wm8737_spi_probe,
- .remove = __devexit_p(wm8737_spi_remove),
-};
-#endif /* CONFIG_SPI_MASTER */
-
-static int __init wm8737_modinit(void)
-{
- int ret;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&wm8737_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8737 I2C driver: %d\n",
- ret);
- }
-#endif
-#if defined(CONFIG_SPI_MASTER)
- ret = spi_register_driver(&wm8737_spi_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8737 SPI driver: %d\n",
- ret);
- }
-#endif
- return 0;
-}
-module_init(wm8737_modinit);
-
-static void __exit wm8737_exit(void)
-{
-#if defined(CONFIG_SPI_MASTER)
- spi_unregister_driver(&wm8737_spi_driver);
-#endif
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&wm8737_i2c_driver);
-#endif
-}
-module_exit(wm8737_exit);
-
-MODULE_DESCRIPTION("ASoC WM8737 driver");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8737.h b/ANDROID_3.4.5/sound/soc/codecs/wm8737.h
deleted file mode 100644
index 23d14c8f..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8737.h
+++ /dev/null
@@ -1,322 +0,0 @@
-#ifndef _WM8737_H
-#define _WM8737_H
-
-/*
- * wm8737.c -- WM8523 ALSA SoC Audio driver
- *
- * Copyright 2010 Wolfson Microelectronics plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-/*
- * Register values.
- */
-#define WM8737_LEFT_PGA_VOLUME 0x00
-#define WM8737_RIGHT_PGA_VOLUME 0x01
-#define WM8737_AUDIO_PATH_L 0x02
-#define WM8737_AUDIO_PATH_R 0x03
-#define WM8737_3D_ENHANCE 0x04
-#define WM8737_ADC_CONTROL 0x05
-#define WM8737_POWER_MANAGEMENT 0x06
-#define WM8737_AUDIO_FORMAT 0x07
-#define WM8737_CLOCKING 0x08
-#define WM8737_MIC_PREAMP_CONTROL 0x09
-#define WM8737_MISC_BIAS_CONTROL 0x0A
-#define WM8737_NOISE_GATE 0x0B
-#define WM8737_ALC1 0x0C
-#define WM8737_ALC2 0x0D
-#define WM8737_ALC3 0x0E
-#define WM8737_RESET 0x0F
-
-#define WM8737_REGISTER_COUNT 16
-#define WM8737_MAX_REGISTER 0x0F
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - Left PGA volume
- */
-#define WM8737_LVU 0x0100 /* LVU */
-#define WM8737_LVU_MASK 0x0100 /* LVU */
-#define WM8737_LVU_SHIFT 8 /* LVU */
-#define WM8737_LVU_WIDTH 1 /* LVU */
-#define WM8737_LINVOL_MASK 0x00FF /* LINVOL - [7:0] */
-#define WM8737_LINVOL_SHIFT 0 /* LINVOL - [7:0] */
-#define WM8737_LINVOL_WIDTH 8 /* LINVOL - [7:0] */
-
-/*
- * R1 (0x01) - Right PGA volume
- */
-#define WM8737_RVU 0x0100 /* RVU */
-#define WM8737_RVU_MASK 0x0100 /* RVU */
-#define WM8737_RVU_SHIFT 8 /* RVU */
-#define WM8737_RVU_WIDTH 1 /* RVU */
-#define WM8737_RINVOL_MASK 0x00FF /* RINVOL - [7:0] */
-#define WM8737_RINVOL_SHIFT 0 /* RINVOL - [7:0] */
-#define WM8737_RINVOL_WIDTH 8 /* RINVOL - [7:0] */
-
-/*
- * R2 (0x02) - AUDIO path L
- */
-#define WM8737_LINSEL_MASK 0x0180 /* LINSEL - [8:7] */
-#define WM8737_LINSEL_SHIFT 7 /* LINSEL - [8:7] */
-#define WM8737_LINSEL_WIDTH 2 /* LINSEL - [8:7] */
-#define WM8737_LMICBOOST_MASK 0x0060 /* LMICBOOST - [6:5] */
-#define WM8737_LMICBOOST_SHIFT 5 /* LMICBOOST - [6:5] */
-#define WM8737_LMICBOOST_WIDTH 2 /* LMICBOOST - [6:5] */
-#define WM8737_LMBE 0x0010 /* LMBE */
-#define WM8737_LMBE_MASK 0x0010 /* LMBE */
-#define WM8737_LMBE_SHIFT 4 /* LMBE */
-#define WM8737_LMBE_WIDTH 1 /* LMBE */
-#define WM8737_LMZC 0x0008 /* LMZC */
-#define WM8737_LMZC_MASK 0x0008 /* LMZC */
-#define WM8737_LMZC_SHIFT 3 /* LMZC */
-#define WM8737_LMZC_WIDTH 1 /* LMZC */
-#define WM8737_LPZC 0x0004 /* LPZC */
-#define WM8737_LPZC_MASK 0x0004 /* LPZC */
-#define WM8737_LPZC_SHIFT 2 /* LPZC */
-#define WM8737_LPZC_WIDTH 1 /* LPZC */
-#define WM8737_LZCTO_MASK 0x0003 /* LZCTO - [1:0] */
-#define WM8737_LZCTO_SHIFT 0 /* LZCTO - [1:0] */
-#define WM8737_LZCTO_WIDTH 2 /* LZCTO - [1:0] */
-
-/*
- * R3 (0x03) - AUDIO path R
- */
-#define WM8737_RINSEL_MASK 0x0180 /* RINSEL - [8:7] */
-#define WM8737_RINSEL_SHIFT 7 /* RINSEL - [8:7] */
-#define WM8737_RINSEL_WIDTH 2 /* RINSEL - [8:7] */
-#define WM8737_RMICBOOST_MASK 0x0060 /* RMICBOOST - [6:5] */
-#define WM8737_RMICBOOST_SHIFT 5 /* RMICBOOST - [6:5] */
-#define WM8737_RMICBOOST_WIDTH 2 /* RMICBOOST - [6:5] */
-#define WM8737_RMBE 0x0010 /* RMBE */
-#define WM8737_RMBE_MASK 0x0010 /* RMBE */
-#define WM8737_RMBE_SHIFT 4 /* RMBE */
-#define WM8737_RMBE_WIDTH 1 /* RMBE */
-#define WM8737_RMZC 0x0008 /* RMZC */
-#define WM8737_RMZC_MASK 0x0008 /* RMZC */
-#define WM8737_RMZC_SHIFT 3 /* RMZC */
-#define WM8737_RMZC_WIDTH 1 /* RMZC */
-#define WM8737_RPZC 0x0004 /* RPZC */
-#define WM8737_RPZC_MASK 0x0004 /* RPZC */
-#define WM8737_RPZC_SHIFT 2 /* RPZC */
-#define WM8737_RPZC_WIDTH 1 /* RPZC */
-#define WM8737_RZCTO_MASK 0x0003 /* RZCTO - [1:0] */
-#define WM8737_RZCTO_SHIFT 0 /* RZCTO - [1:0] */
-#define WM8737_RZCTO_WIDTH 2 /* RZCTO - [1:0] */
-
-/*
- * R4 (0x04) - 3D Enhance
- */
-#define WM8737_DIV2 0x0080 /* DIV2 */
-#define WM8737_DIV2_MASK 0x0080 /* DIV2 */
-#define WM8737_DIV2_SHIFT 7 /* DIV2 */
-#define WM8737_DIV2_WIDTH 1 /* DIV2 */
-#define WM8737_3DLC 0x0040 /* 3DLC */
-#define WM8737_3DLC_MASK 0x0040 /* 3DLC */
-#define WM8737_3DLC_SHIFT 6 /* 3DLC */
-#define WM8737_3DLC_WIDTH 1 /* 3DLC */
-#define WM8737_3DUC 0x0020 /* 3DUC */
-#define WM8737_3DUC_MASK 0x0020 /* 3DUC */
-#define WM8737_3DUC_SHIFT 5 /* 3DUC */
-#define WM8737_3DUC_WIDTH 1 /* 3DUC */
-#define WM8737_3DDEPTH_MASK 0x001E /* 3DDEPTH - [4:1] */
-#define WM8737_3DDEPTH_SHIFT 1 /* 3DDEPTH - [4:1] */
-#define WM8737_3DDEPTH_WIDTH 4 /* 3DDEPTH - [4:1] */
-#define WM8737_3DE 0x0001 /* 3DE */
-#define WM8737_3DE_MASK 0x0001 /* 3DE */
-#define WM8737_3DE_SHIFT 0 /* 3DE */
-#define WM8737_3DE_WIDTH 1 /* 3DE */
-
-/*
- * R5 (0x05) - ADC Control
- */
-#define WM8737_MONOMIX_MASK 0x0180 /* MONOMIX - [8:7] */
-#define WM8737_MONOMIX_SHIFT 7 /* MONOMIX - [8:7] */
-#define WM8737_MONOMIX_WIDTH 2 /* MONOMIX - [8:7] */
-#define WM8737_POLARITY_MASK 0x0060 /* POLARITY - [6:5] */
-#define WM8737_POLARITY_SHIFT 5 /* POLARITY - [6:5] */
-#define WM8737_POLARITY_WIDTH 2 /* POLARITY - [6:5] */
-#define WM8737_HPOR 0x0010 /* HPOR */
-#define WM8737_HPOR_MASK 0x0010 /* HPOR */
-#define WM8737_HPOR_SHIFT 4 /* HPOR */
-#define WM8737_HPOR_WIDTH 1 /* HPOR */
-#define WM8737_LP 0x0004 /* LP */
-#define WM8737_LP_MASK 0x0004 /* LP */
-#define WM8737_LP_SHIFT 2 /* LP */
-#define WM8737_LP_WIDTH 1 /* LP */
-#define WM8737_MONOUT 0x0002 /* MONOUT */
-#define WM8737_MONOUT_MASK 0x0002 /* MONOUT */
-#define WM8737_MONOUT_SHIFT 1 /* MONOUT */
-#define WM8737_MONOUT_WIDTH 1 /* MONOUT */
-#define WM8737_ADCHPD 0x0001 /* ADCHPD */
-#define WM8737_ADCHPD_MASK 0x0001 /* ADCHPD */
-#define WM8737_ADCHPD_SHIFT 0 /* ADCHPD */
-#define WM8737_ADCHPD_WIDTH 1 /* ADCHPD */
-
-/*
- * R6 (0x06) - Power Management
- */
-#define WM8737_VMID 0x0100 /* VMID */
-#define WM8737_VMID_MASK 0x0100 /* VMID */
-#define WM8737_VMID_SHIFT 8 /* VMID */
-#define WM8737_VMID_WIDTH 1 /* VMID */
-#define WM8737_VREF 0x0080 /* VREF */
-#define WM8737_VREF_MASK 0x0080 /* VREF */
-#define WM8737_VREF_SHIFT 7 /* VREF */
-#define WM8737_VREF_WIDTH 1 /* VREF */
-#define WM8737_AI 0x0040 /* AI */
-#define WM8737_AI_MASK 0x0040 /* AI */
-#define WM8737_AI_SHIFT 6 /* AI */
-#define WM8737_AI_WIDTH 1 /* AI */
-#define WM8737_PGL 0x0020 /* PGL */
-#define WM8737_PGL_MASK 0x0020 /* PGL */
-#define WM8737_PGL_SHIFT 5 /* PGL */
-#define WM8737_PGL_WIDTH 1 /* PGL */
-#define WM8737_PGR 0x0010 /* PGR */
-#define WM8737_PGR_MASK 0x0010 /* PGR */
-#define WM8737_PGR_SHIFT 4 /* PGR */
-#define WM8737_PGR_WIDTH 1 /* PGR */
-#define WM8737_ADL 0x0008 /* ADL */
-#define WM8737_ADL_MASK 0x0008 /* ADL */
-#define WM8737_ADL_SHIFT 3 /* ADL */
-#define WM8737_ADL_WIDTH 1 /* ADL */
-#define WM8737_ADR 0x0004 /* ADR */
-#define WM8737_ADR_MASK 0x0004 /* ADR */
-#define WM8737_ADR_SHIFT 2 /* ADR */
-#define WM8737_ADR_WIDTH 1 /* ADR */
-#define WM8737_MICBIAS_MASK 0x0003 /* MICBIAS - [1:0] */
-#define WM8737_MICBIAS_SHIFT 0 /* MICBIAS - [1:0] */
-#define WM8737_MICBIAS_WIDTH 2 /* MICBIAS - [1:0] */
-
-/*
- * R7 (0x07) - Audio Format
- */
-#define WM8737_SDODIS 0x0080 /* SDODIS */
-#define WM8737_SDODIS_MASK 0x0080 /* SDODIS */
-#define WM8737_SDODIS_SHIFT 7 /* SDODIS */
-#define WM8737_SDODIS_WIDTH 1 /* SDODIS */
-#define WM8737_MS 0x0040 /* MS */
-#define WM8737_MS_MASK 0x0040 /* MS */
-#define WM8737_MS_SHIFT 6 /* MS */
-#define WM8737_MS_WIDTH 1 /* MS */
-#define WM8737_LRP 0x0010 /* LRP */
-#define WM8737_LRP_MASK 0x0010 /* LRP */
-#define WM8737_LRP_SHIFT 4 /* LRP */
-#define WM8737_LRP_WIDTH 1 /* LRP */
-#define WM8737_WL_MASK 0x000C /* WL - [3:2] */
-#define WM8737_WL_SHIFT 2 /* WL - [3:2] */
-#define WM8737_WL_WIDTH 2 /* WL - [3:2] */
-#define WM8737_FORMAT_MASK 0x0003 /* FORMAT - [1:0] */
-#define WM8737_FORMAT_SHIFT 0 /* FORMAT - [1:0] */
-#define WM8737_FORMAT_WIDTH 2 /* FORMAT - [1:0] */
-
-/*
- * R8 (0x08) - Clocking
- */
-#define WM8737_AUTODETECT 0x0080 /* AUTODETECT */
-#define WM8737_AUTODETECT_MASK 0x0080 /* AUTODETECT */
-#define WM8737_AUTODETECT_SHIFT 7 /* AUTODETECT */
-#define WM8737_AUTODETECT_WIDTH 1 /* AUTODETECT */
-#define WM8737_CLKDIV2 0x0040 /* CLKDIV2 */
-#define WM8737_CLKDIV2_MASK 0x0040 /* CLKDIV2 */
-#define WM8737_CLKDIV2_SHIFT 6 /* CLKDIV2 */
-#define WM8737_CLKDIV2_WIDTH 1 /* CLKDIV2 */
-#define WM8737_SR_MASK 0x003E /* SR - [5:1] */
-#define WM8737_SR_SHIFT 1 /* SR - [5:1] */
-#define WM8737_SR_WIDTH 5 /* SR - [5:1] */
-#define WM8737_USB_MODE 0x0001 /* USB MODE */
-#define WM8737_USB_MODE_MASK 0x0001 /* USB MODE */
-#define WM8737_USB_MODE_SHIFT 0 /* USB MODE */
-#define WM8737_USB_MODE_WIDTH 1 /* USB MODE */
-
-/*
- * R9 (0x09) - MIC Preamp Control
- */
-#define WM8737_RBYPEN 0x0008 /* RBYPEN */
-#define WM8737_RBYPEN_MASK 0x0008 /* RBYPEN */
-#define WM8737_RBYPEN_SHIFT 3 /* RBYPEN */
-#define WM8737_RBYPEN_WIDTH 1 /* RBYPEN */
-#define WM8737_LBYPEN 0x0004 /* LBYPEN */
-#define WM8737_LBYPEN_MASK 0x0004 /* LBYPEN */
-#define WM8737_LBYPEN_SHIFT 2 /* LBYPEN */
-#define WM8737_LBYPEN_WIDTH 1 /* LBYPEN */
-#define WM8737_MBCTRL_MASK 0x0003 /* MBCTRL - [1:0] */
-#define WM8737_MBCTRL_SHIFT 0 /* MBCTRL - [1:0] */
-#define WM8737_MBCTRL_WIDTH 2 /* MBCTRL - [1:0] */
-
-/*
- * R10 (0x0A) - Misc Bias Control
- */
-#define WM8737_VMIDSEL_MASK 0x000C /* VMIDSEL - [3:2] */
-#define WM8737_VMIDSEL_SHIFT 2 /* VMIDSEL - [3:2] */
-#define WM8737_VMIDSEL_WIDTH 2 /* VMIDSEL - [3:2] */
-#define WM8737_LINPUT1_DC_BIAS_ENABLE 0x0002 /* LINPUT1 DC BIAS ENABLE */
-#define WM8737_LINPUT1_DC_BIAS_ENABLE_MASK 0x0002 /* LINPUT1 DC BIAS ENABLE */
-#define WM8737_LINPUT1_DC_BIAS_ENABLE_SHIFT 1 /* LINPUT1 DC BIAS ENABLE */
-#define WM8737_LINPUT1_DC_BIAS_ENABLE_WIDTH 1 /* LINPUT1 DC BIAS ENABLE */
-#define WM8737_RINPUT1_DC_BIAS_ENABLE 0x0001 /* RINPUT1 DC BIAS ENABLE */
-#define WM8737_RINPUT1_DC_BIAS_ENABLE_MASK 0x0001 /* RINPUT1 DC BIAS ENABLE */
-#define WM8737_RINPUT1_DC_BIAS_ENABLE_SHIFT 0 /* RINPUT1 DC BIAS ENABLE */
-#define WM8737_RINPUT1_DC_BIAS_ENABLE_WIDTH 1 /* RINPUT1 DC BIAS ENABLE */
-
-/*
- * R11 (0x0B) - Noise Gate
- */
-#define WM8737_NGTH_MASK 0x001C /* NGTH - [4:2] */
-#define WM8737_NGTH_SHIFT 2 /* NGTH - [4:2] */
-#define WM8737_NGTH_WIDTH 3 /* NGTH - [4:2] */
-#define WM8737_NGAT 0x0001 /* NGAT */
-#define WM8737_NGAT_MASK 0x0001 /* NGAT */
-#define WM8737_NGAT_SHIFT 0 /* NGAT */
-#define WM8737_NGAT_WIDTH 1 /* NGAT */
-
-/*
- * R12 (0x0C) - ALC1
- */
-#define WM8737_ALCSEL_MASK 0x0180 /* ALCSEL - [8:7] */
-#define WM8737_ALCSEL_SHIFT 7 /* ALCSEL - [8:7] */
-#define WM8737_ALCSEL_WIDTH 2 /* ALCSEL - [8:7] */
-#define WM8737_MAX_GAIN_MASK 0x0070 /* MAX GAIN - [6:4] */
-#define WM8737_MAX_GAIN_SHIFT 4 /* MAX GAIN - [6:4] */
-#define WM8737_MAX_GAIN_WIDTH 3 /* MAX GAIN - [6:4] */
-#define WM8737_ALCL_MASK 0x000F /* ALCL - [3:0] */
-#define WM8737_ALCL_SHIFT 0 /* ALCL - [3:0] */
-#define WM8737_ALCL_WIDTH 4 /* ALCL - [3:0] */
-
-/*
- * R13 (0x0D) - ALC2
- */
-#define WM8737_ALCZCE 0x0010 /* ALCZCE */
-#define WM8737_ALCZCE_MASK 0x0010 /* ALCZCE */
-#define WM8737_ALCZCE_SHIFT 4 /* ALCZCE */
-#define WM8737_ALCZCE_WIDTH 1 /* ALCZCE */
-#define WM8737_HLD_MASK 0x000F /* HLD - [3:0] */
-#define WM8737_HLD_SHIFT 0 /* HLD - [3:0] */
-#define WM8737_HLD_WIDTH 4 /* HLD - [3:0] */
-
-/*
- * R14 (0x0E) - ALC3
- */
-#define WM8737_DCY_MASK 0x00F0 /* DCY - [7:4] */
-#define WM8737_DCY_SHIFT 4 /* DCY - [7:4] */
-#define WM8737_DCY_WIDTH 4 /* DCY - [7:4] */
-#define WM8737_ATK_MASK 0x000F /* ATK - [3:0] */
-#define WM8737_ATK_SHIFT 0 /* ATK - [3:0] */
-#define WM8737_ATK_WIDTH 4 /* ATK - [3:0] */
-
-/*
- * R15 (0x0F) - Reset
- */
-#define WM8737_RESET_MASK 0x01FF /* RESET - [8:0] */
-#define WM8737_RESET_SHIFT 0 /* RESET - [8:0] */
-#define WM8737_RESET_WIDTH 9 /* RESET - [8:0] */
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8741.c b/ANDROID_3.4.5/sound/soc/codecs/wm8741.c
deleted file mode 100644
index 3941f50b..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8741.c
+++ /dev/null
@@ -1,606 +0,0 @@
-/*
- * wm8741.c -- WM8741 ALSA SoC Audio driver
- *
- * Copyright 2010 Wolfson Microelectronics plc
- *
- * Author: Ian Lartey <ian@opensource.wolfsonmicro.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/spi/spi.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <linux/of_device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "wm8741.h"
-
-#define WM8741_NUM_SUPPLIES 2
-static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {
- "AVDD",
- "DVDD",
-};
-
-#define WM8741_NUM_RATES 6
-
-/* codec private data */
-struct wm8741_priv {
- enum snd_soc_control_type control_type;
- struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES];
- unsigned int sysclk;
- struct snd_pcm_hw_constraint_list *sysclk_constraints;
-};
-
-static const u16 wm8741_reg_defaults[WM8741_REGISTER_COUNT] = {
- 0x0000, /* R0 - DACLLSB Attenuation */
- 0x0000, /* R1 - DACLMSB Attenuation */
- 0x0000, /* R2 - DACRLSB Attenuation */
- 0x0000, /* R3 - DACRMSB Attenuation */
- 0x0000, /* R4 - Volume Control */
- 0x000A, /* R5 - Format Control */
- 0x0000, /* R6 - Filter Control */
- 0x0000, /* R7 - Mode Control 1 */
- 0x0002, /* R8 - Mode Control 2 */
- 0x0000, /* R9 - Reset */
- 0x0002, /* R32 - ADDITONAL_CONTROL_1 */
-};
-
-
-static int wm8741_reset(struct snd_soc_codec *codec)
-{
- return snd_soc_write(codec, WM8741_RESET, 0);
-}
-
-static const DECLARE_TLV_DB_SCALE(dac_tlv_fine, -12700, 13, 0);
-static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 400, 0);
-
-static const struct snd_kcontrol_new wm8741_snd_controls[] = {
-SOC_DOUBLE_R_TLV("Fine Playback Volume", WM8741_DACLLSB_ATTENUATION,
- WM8741_DACRLSB_ATTENUATION, 1, 255, 1, dac_tlv_fine),
-SOC_DOUBLE_R_TLV("Playback Volume", WM8741_DACLMSB_ATTENUATION,
- WM8741_DACRMSB_ATTENUATION, 0, 511, 1, dac_tlv),
-};
-
-static const struct snd_soc_dapm_widget wm8741_dapm_widgets[] = {
-SND_SOC_DAPM_DAC("DACL", "Playback", SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_DAC("DACR", "Playback", SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_OUTPUT("VOUTLP"),
-SND_SOC_DAPM_OUTPUT("VOUTLN"),
-SND_SOC_DAPM_OUTPUT("VOUTRP"),
-SND_SOC_DAPM_OUTPUT("VOUTRN"),
-};
-
-static const struct snd_soc_dapm_route wm8741_dapm_routes[] = {
- { "VOUTLP", NULL, "DACL" },
- { "VOUTLN", NULL, "DACL" },
- { "VOUTRP", NULL, "DACR" },
- { "VOUTRN", NULL, "DACR" },
-};
-
-static struct {
- int value;
- int ratio;
-} lrclk_ratios[WM8741_NUM_RATES] = {
- { 1, 128 },
- { 2, 192 },
- { 3, 256 },
- { 4, 384 },
- { 5, 512 },
- { 6, 768 },
-};
-
-static unsigned int rates_11289[] = {
- 44100, 88235,
-};
-
-static struct snd_pcm_hw_constraint_list constraints_11289 = {
- .count = ARRAY_SIZE(rates_11289),
- .list = rates_11289,
-};
-
-static unsigned int rates_12288[] = {
- 32000, 48000, 96000,
-};
-
-static struct snd_pcm_hw_constraint_list constraints_12288 = {
- .count = ARRAY_SIZE(rates_12288),
- .list = rates_12288,
-};
-
-static unsigned int rates_16384[] = {
- 32000,
-};
-
-static struct snd_pcm_hw_constraint_list constraints_16384 = {
- .count = ARRAY_SIZE(rates_16384),
- .list = rates_16384,
-};
-
-static unsigned int rates_16934[] = {
- 44100, 88235,
-};
-
-static struct snd_pcm_hw_constraint_list constraints_16934 = {
- .count = ARRAY_SIZE(rates_16934),
- .list = rates_16934,
-};
-
-static unsigned int rates_18432[] = {
- 48000, 96000,
-};
-
-static struct snd_pcm_hw_constraint_list constraints_18432 = {
- .count = ARRAY_SIZE(rates_18432),
- .list = rates_18432,
-};
-
-static unsigned int rates_22579[] = {
- 44100, 88235, 1764000
-};
-
-static struct snd_pcm_hw_constraint_list constraints_22579 = {
- .count = ARRAY_SIZE(rates_22579),
- .list = rates_22579,
-};
-
-static unsigned int rates_24576[] = {
- 32000, 48000, 96000, 192000
-};
-
-static struct snd_pcm_hw_constraint_list constraints_24576 = {
- .count = ARRAY_SIZE(rates_24576),
- .list = rates_24576,
-};
-
-static unsigned int rates_36864[] = {
- 48000, 96000, 19200
-};
-
-static struct snd_pcm_hw_constraint_list constraints_36864 = {
- .count = ARRAY_SIZE(rates_36864),
- .list = rates_36864,
-};
-
-
-static int wm8741_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
-
- /* The set of sample rates that can be supported depends on the
- * MCLK supplied to the CODEC - enforce this.
- */
- if (!wm8741->sysclk) {
- dev_err(codec->dev,
- "No MCLK configured, call set_sysclk() on init\n");
- return -EINVAL;
- }
-
- snd_pcm_hw_constraint_list(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- wm8741->sysclk_constraints);
-
- return 0;
-}
-
-static int wm8741_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
- u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC;
- int i;
-
- /* Find a supported LRCLK ratio */
- for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
- if (wm8741->sysclk / params_rate(params) ==
- lrclk_ratios[i].ratio)
- break;
- }
-
- /* Should never happen, should be handled by constraints */
- if (i == ARRAY_SIZE(lrclk_ratios)) {
- dev_err(codec->dev, "MCLK/fs ratio %d unsupported\n",
- wm8741->sysclk / params_rate(params));
- return -EINVAL;
- }
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= 0x0001;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface |= 0x0002;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- iface |= 0x0003;
- break;
- default:
- dev_dbg(codec->dev, "wm8741_hw_params: Unsupported bit size param = %d",
- params_format(params));
- return -EINVAL;
- }
-
- dev_dbg(codec->dev, "wm8741_hw_params: bit size param = %d",
- params_format(params));
-
- snd_soc_write(codec, WM8741_FORMAT_CONTROL, iface);
- return 0;
-}
-
-static int wm8741_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
-
- dev_dbg(codec->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq);
-
- switch (freq) {
- case 11289600:
- wm8741->sysclk_constraints = &constraints_11289;
- wm8741->sysclk = freq;
- return 0;
-
- case 12288000:
- wm8741->sysclk_constraints = &constraints_12288;
- wm8741->sysclk = freq;
- return 0;
-
- case 16384000:
- wm8741->sysclk_constraints = &constraints_16384;
- wm8741->sysclk = freq;
- return 0;
-
- case 16934400:
- wm8741->sysclk_constraints = &constraints_16934;
- wm8741->sysclk = freq;
- return 0;
-
- case 18432000:
- wm8741->sysclk_constraints = &constraints_18432;
- wm8741->sysclk = freq;
- return 0;
-
- case 22579200:
- case 33868800:
- wm8741->sysclk_constraints = &constraints_22579;
- wm8741->sysclk = freq;
- return 0;
-
- case 24576000:
- wm8741->sysclk_constraints = &constraints_24576;
- wm8741->sysclk = freq;
- return 0;
-
- case 36864000:
- wm8741->sysclk_constraints = &constraints_36864;
- wm8741->sysclk = freq;
- return 0;
- }
- return -EINVAL;
-}
-
-static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1C3;
-
- /* check master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= 0x0008;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= 0x0004;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= 0x000C;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- iface |= 0x001C;
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= 0x0010;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= 0x0020;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- iface |= 0x0030;
- break;
- default:
- return -EINVAL;
- }
-
-
- dev_dbg(codec->dev, "wm8741_set_dai_fmt: Format=%x, Clock Inv=%x\n",
- fmt & SND_SOC_DAIFMT_FORMAT_MASK,
- ((fmt & SND_SOC_DAIFMT_INV_MASK)));
-
- snd_soc_write(codec, WM8741_FORMAT_CONTROL, iface);
- return 0;
-}
-
-#define WM8741_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | \
- SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | \
- SNDRV_PCM_RATE_192000)
-
-#define WM8741_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops wm8741_dai_ops = {
- .startup = wm8741_startup,
- .hw_params = wm8741_hw_params,
- .set_sysclk = wm8741_set_dai_sysclk,
- .set_fmt = wm8741_set_dai_fmt,
-};
-
-static struct snd_soc_dai_driver wm8741_dai = {
- .name = "wm8741",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2, /* Mono modes not yet supported */
- .channels_max = 2,
- .rates = WM8741_RATES,
- .formats = WM8741_FORMATS,
- },
- .ops = &wm8741_dai_ops,
-};
-
-#ifdef CONFIG_PM
-static int wm8741_resume(struct snd_soc_codec *codec)
-{
- snd_soc_cache_sync(codec);
- return 0;
-}
-#else
-#define wm8741_suspend NULL
-#define wm8741_resume NULL
-#endif
-
-static int wm8741_probe(struct snd_soc_codec *codec)
-{
- struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
- int ret = 0;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
- wm8741->supplies[i].supply = wm8741_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8741->supplies),
- wm8741->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- goto err;
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),
- wm8741->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
- goto err_get;
- }
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err_enable;
- }
-
- ret = wm8741_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- goto err_enable;
- }
-
- /* Change some default settings - latch VU */
- snd_soc_update_bits(codec, WM8741_DACLLSB_ATTENUATION,
- WM8741_UPDATELL, WM8741_UPDATELL);
- snd_soc_update_bits(codec, WM8741_DACLMSB_ATTENUATION,
- WM8741_UPDATELM, WM8741_UPDATELM);
- snd_soc_update_bits(codec, WM8741_DACRLSB_ATTENUATION,
- WM8741_UPDATERL, WM8741_UPDATERL);
- snd_soc_update_bits(codec, WM8741_DACRMSB_ATTENUATION,
- WM8741_UPDATERM, WM8741_UPDATERM);
-
- dev_dbg(codec->dev, "Successful registration\n");
- return ret;
-
-err_enable:
- regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
-err_get:
- regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
-err:
- return ret;
-}
-
-static int wm8741_remove(struct snd_soc_codec *codec)
-{
- struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
-
- regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
- regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8741 = {
- .probe = wm8741_probe,
- .remove = wm8741_remove,
- .resume = wm8741_resume,
- .reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8741_reg_defaults,
-
- .controls = wm8741_snd_controls,
- .num_controls = ARRAY_SIZE(wm8741_snd_controls),
- .dapm_widgets = wm8741_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8741_dapm_widgets),
- .dapm_routes = wm8741_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm8741_dapm_routes),
-};
-
-static const struct of_device_id wm8741_of_match[] = {
- { .compatible = "wlf,wm8741", },
- { }
-};
-MODULE_DEVICE_TABLE(of, wm8741_of_match);
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static int wm8741_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8741_priv *wm8741;
- int ret;
-
- wm8741 = devm_kzalloc(&i2c->dev, sizeof(struct wm8741_priv),
- GFP_KERNEL);
- if (wm8741 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm8741);
- wm8741->control_type = SND_SOC_I2C;
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8741, &wm8741_dai, 1);
-
- return ret;
-}
-
-static int wm8741_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static const struct i2c_device_id wm8741_i2c_id[] = {
- { "wm8741", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8741_i2c_id);
-
-static struct i2c_driver wm8741_i2c_driver = {
- .driver = {
- .name = "wm8741",
- .owner = THIS_MODULE,
- .of_match_table = wm8741_of_match,
- },
- .probe = wm8741_i2c_probe,
- .remove = wm8741_i2c_remove,
- .id_table = wm8741_i2c_id,
-};
-#endif
-
-#if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8741_spi_probe(struct spi_device *spi)
-{
- struct wm8741_priv *wm8741;
- int ret;
-
- wm8741 = devm_kzalloc(&spi->dev, sizeof(struct wm8741_priv),
- GFP_KERNEL);
- if (wm8741 == NULL)
- return -ENOMEM;
-
- wm8741->control_type = SND_SOC_SPI;
- spi_set_drvdata(spi, wm8741);
-
- ret = snd_soc_register_codec(&spi->dev,
- &soc_codec_dev_wm8741, &wm8741_dai, 1);
- return ret;
-}
-
-static int __devexit wm8741_spi_remove(struct spi_device *spi)
-{
- snd_soc_unregister_codec(&spi->dev);
- return 0;
-}
-
-static struct spi_driver wm8741_spi_driver = {
- .driver = {
- .name = "wm8741",
- .owner = THIS_MODULE,
- .of_match_table = wm8741_of_match,
- },
- .probe = wm8741_spi_probe,
- .remove = __devexit_p(wm8741_spi_remove),
-};
-#endif /* CONFIG_SPI_MASTER */
-
-static int __init wm8741_modinit(void)
-{
- int ret = 0;
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&wm8741_i2c_driver);
- if (ret != 0)
- pr_err("Failed to register WM8741 I2C driver: %d\n", ret);
-#endif
-#if defined(CONFIG_SPI_MASTER)
- ret = spi_register_driver(&wm8741_spi_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8741 SPI driver: %d\n",
- ret);
- }
-#endif
-
- return ret;
-}
-module_init(wm8741_modinit);
-
-static void __exit wm8741_exit(void)
-{
-#if defined(CONFIG_SPI_MASTER)
- spi_unregister_driver(&wm8741_spi_driver);
-#endif
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&wm8741_i2c_driver);
-#endif
-}
-module_exit(wm8741_exit);
-
-MODULE_DESCRIPTION("ASoC WM8741 driver");
-MODULE_AUTHOR("Ian Lartey <ian@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8741.h b/ANDROID_3.4.5/sound/soc/codecs/wm8741.h
deleted file mode 100644
index 56c1b1d4..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8741.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * wm8741.h -- WM8423 ASoC driver
- *
- * Copyright 2010 Wolfson Microelectronics, plc
- *
- * Author: Ian Lartey <ian@opensource.wolfsonmicro.com>
- *
- * Based on wm8753.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8741_H
-#define _WM8741_H
-
-/*
- * Register values.
- */
-#define WM8741_DACLLSB_ATTENUATION 0x00
-#define WM8741_DACLMSB_ATTENUATION 0x01
-#define WM8741_DACRLSB_ATTENUATION 0x02
-#define WM8741_DACRMSB_ATTENUATION 0x03
-#define WM8741_VOLUME_CONTROL 0x04
-#define WM8741_FORMAT_CONTROL 0x05
-#define WM8741_FILTER_CONTROL 0x06
-#define WM8741_MODE_CONTROL_1 0x07
-#define WM8741_MODE_CONTROL_2 0x08
-#define WM8741_RESET 0x09
-#define WM8741_ADDITIONAL_CONTROL_1 0x20
-
-#define WM8741_REGISTER_COUNT 11
-#define WM8741_MAX_REGISTER 0x20
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - DACLLSB_ATTENUATION
- */
-#define WM8741_UPDATELL 0x0020 /* UPDATELL */
-#define WM8741_UPDATELL_MASK 0x0020 /* UPDATELL */
-#define WM8741_UPDATELL_SHIFT 5 /* UPDATELL */
-#define WM8741_UPDATELL_WIDTH 1 /* UPDATELL */
-#define WM8741_LAT_4_0_MASK 0x001F /* LAT[4:0] - [4:0] */
-#define WM8741_LAT_4_0_SHIFT 0 /* LAT[4:0] - [4:0] */
-#define WM8741_LAT_4_0_WIDTH 5 /* LAT[4:0] - [4:0] */
-
-/*
- * R1 (0x01) - DACLMSB_ATTENUATION
- */
-#define WM8741_UPDATELM 0x0020 /* UPDATELM */
-#define WM8741_UPDATELM_MASK 0x0020 /* UPDATELM */
-#define WM8741_UPDATELM_SHIFT 5 /* UPDATELM */
-#define WM8741_UPDATELM_WIDTH 1 /* UPDATELM */
-#define WM8741_LAT_9_5_0_MASK 0x001F /* LAT[9:5] - [4:0] */
-#define WM8741_LAT_9_5_0_SHIFT 0 /* LAT[9:5] - [4:0] */
-#define WM8741_LAT_9_5_0_WIDTH 5 /* LAT[9:5] - [4:0] */
-
-/*
- * R2 (0x02) - DACRLSB_ATTENUATION
- */
-#define WM8741_UPDATERL 0x0020 /* UPDATERL */
-#define WM8741_UPDATERL_MASK 0x0020 /* UPDATERL */
-#define WM8741_UPDATERL_SHIFT 5 /* UPDATERL */
-#define WM8741_UPDATERL_WIDTH 1 /* UPDATERL */
-#define WM8741_RAT_4_0_MASK 0x001F /* RAT[4:0] - [4:0] */
-#define WM8741_RAT_4_0_SHIFT 0 /* RAT[4:0] - [4:0] */
-#define WM8741_RAT_4_0_WIDTH 5 /* RAT[4:0] - [4:0] */
-
-/*
- * R3 (0x03) - DACRMSB_ATTENUATION
- */
-#define WM8741_UPDATERM 0x0020 /* UPDATERM */
-#define WM8741_UPDATERM_MASK 0x0020 /* UPDATERM */
-#define WM8741_UPDATERM_SHIFT 5 /* UPDATERM */
-#define WM8741_UPDATERM_WIDTH 1 /* UPDATERM */
-#define WM8741_RAT_9_5_0_MASK 0x001F /* RAT[9:5] - [4:0] */
-#define WM8741_RAT_9_5_0_SHIFT 0 /* RAT[9:5] - [4:0] */
-#define WM8741_RAT_9_5_0_WIDTH 5 /* RAT[9:5] - [4:0] */
-
-/*
- * R4 (0x04) - VOLUME_CONTROL
- */
-#define WM8741_AMUTE 0x0080 /* AMUTE */
-#define WM8741_AMUTE_MASK 0x0080 /* AMUTE */
-#define WM8741_AMUTE_SHIFT 7 /* AMUTE */
-#define WM8741_AMUTE_WIDTH 1 /* AMUTE */
-#define WM8741_ZFLAG_MASK 0x0060 /* ZFLAG - [6:5] */
-#define WM8741_ZFLAG_SHIFT 5 /* ZFLAG - [6:5] */
-#define WM8741_ZFLAG_WIDTH 2 /* ZFLAG - [6:5] */
-#define WM8741_IZD 0x0010 /* IZD */
-#define WM8741_IZD_MASK 0x0010 /* IZD */
-#define WM8741_IZD_SHIFT 4 /* IZD */
-#define WM8741_IZD_WIDTH 1 /* IZD */
-#define WM8741_SOFT 0x0008 /* SOFT MUTE */
-#define WM8741_SOFT_MASK 0x0008 /* SOFT MUTE */
-#define WM8741_SOFT_SHIFT 3 /* SOFT MUTE */
-#define WM8741_SOFT_WIDTH 1 /* SOFT MUTE */
-#define WM8741_ATC 0x0004 /* ATC */
-#define WM8741_ATC_MASK 0x0004 /* ATC */
-#define WM8741_ATC_SHIFT 2 /* ATC */
-#define WM8741_ATC_WIDTH 1 /* ATC */
-#define WM8741_ATT2DB 0x0002 /* ATT2DB */
-#define WM8741_ATT2DB_MASK 0x0002 /* ATT2DB */
-#define WM8741_ATT2DB_SHIFT 1 /* ATT2DB */
-#define WM8741_ATT2DB_WIDTH 1 /* ATT2DB */
-#define WM8741_VOL_RAMP 0x0001 /* VOL_RAMP */
-#define WM8741_VOL_RAMP_MASK 0x0001 /* VOL_RAMP */
-#define WM8741_VOL_RAMP_SHIFT 0 /* VOL_RAMP */
-#define WM8741_VOL_RAMP_WIDTH 1 /* VOL_RAMP */
-
-/*
- * R5 (0x05) - FORMAT_CONTROL
- */
-#define WM8741_PWDN 0x0080 /* PWDN */
-#define WM8741_PWDN_MASK 0x0080 /* PWDN */
-#define WM8741_PWDN_SHIFT 7 /* PWDN */
-#define WM8741_PWDN_WIDTH 1 /* PWDN */
-#define WM8741_REV 0x0040 /* REV */
-#define WM8741_REV_MASK 0x0040 /* REV */
-#define WM8741_REV_SHIFT 6 /* REV */
-#define WM8741_REV_WIDTH 1 /* REV */
-#define WM8741_BCP 0x0020 /* BCP */
-#define WM8741_BCP_MASK 0x0020 /* BCP */
-#define WM8741_BCP_SHIFT 5 /* BCP */
-#define WM8741_BCP_WIDTH 1 /* BCP */
-#define WM8741_LRP 0x0010 /* LRP */
-#define WM8741_LRP_MASK 0x0010 /* LRP */
-#define WM8741_LRP_SHIFT 4 /* LRP */
-#define WM8741_LRP_WIDTH 1 /* LRP */
-#define WM8741_FMT_MASK 0x000C /* FMT - [3:2] */
-#define WM8741_FMT_SHIFT 2 /* FMT - [3:2] */
-#define WM8741_FMT_WIDTH 2 /* FMT - [3:2] */
-#define WM8741_IWL_MASK 0x0003 /* IWL - [1:0] */
-#define WM8741_IWL_SHIFT 0 /* IWL - [1:0] */
-#define WM8741_IWL_WIDTH 2 /* IWL - [1:0] */
-
-/*
- * R6 (0x06) - FILTER_CONTROL
- */
-#define WM8741_ZFLAG_HI 0x0080 /* ZFLAG_HI */
-#define WM8741_ZFLAG_HI_MASK 0x0080 /* ZFLAG_HI */
-#define WM8741_ZFLAG_HI_SHIFT 7 /* ZFLAG_HI */
-#define WM8741_ZFLAG_HI_WIDTH 1 /* ZFLAG_HI */
-#define WM8741_DEEMPH_MASK 0x0060 /* DEEMPH - [6:5] */
-#define WM8741_DEEMPH_SHIFT 5 /* DEEMPH - [6:5] */
-#define WM8741_DEEMPH_WIDTH 2 /* DEEMPH - [6:5] */
-#define WM8741_DSDFILT_MASK 0x0018 /* DSDFILT - [4:3] */
-#define WM8741_DSDFILT_SHIFT 3 /* DSDFILT - [4:3] */
-#define WM8741_DSDFILT_WIDTH 2 /* DSDFILT - [4:3] */
-#define WM8741_FIRSEL_MASK 0x0007 /* FIRSEL - [2:0] */
-#define WM8741_FIRSEL_SHIFT 0 /* FIRSEL - [2:0] */
-#define WM8741_FIRSEL_WIDTH 3 /* FIRSEL - [2:0] */
-
-/*
- * R7 (0x07) - MODE_CONTROL_1
- */
-#define WM8741_MODE8X 0x0080 /* MODE8X */
-#define WM8741_MODE8X_MASK 0x0080 /* MODE8X */
-#define WM8741_MODE8X_SHIFT 7 /* MODE8X */
-#define WM8741_MODE8X_WIDTH 1 /* MODE8X */
-#define WM8741_OSR_MASK 0x0060 /* OSR - [6:5] */
-#define WM8741_OSR_SHIFT 5 /* OSR - [6:5] */
-#define WM8741_OSR_WIDTH 2 /* OSR - [6:5] */
-#define WM8741_SR_MASK 0x001C /* SR - [4:2] */
-#define WM8741_SR_SHIFT 2 /* SR - [4:2] */
-#define WM8741_SR_WIDTH 3 /* SR - [4:2] */
-#define WM8741_MODESEL_MASK 0x0003 /* MODESEL - [1:0] */
-#define WM8741_MODESEL_SHIFT 0 /* MODESEL - [1:0] */
-#define WM8741_MODESEL_WIDTH 2 /* MODESEL - [1:0] */
-
-/*
- * R8 (0x08) - MODE_CONTROL_2
- */
-#define WM8741_DSD_GAIN 0x0040 /* DSD_GAIN */
-#define WM8741_DSD_GAIN_MASK 0x0040 /* DSD_GAIN */
-#define WM8741_DSD_GAIN_SHIFT 6 /* DSD_GAIN */
-#define WM8741_DSD_GAIN_WIDTH 1 /* DSD_GAIN */
-#define WM8741_SDOUT 0x0020 /* SDOUT */
-#define WM8741_SDOUT_MASK 0x0020 /* SDOUT */
-#define WM8741_SDOUT_SHIFT 5 /* SDOUT */
-#define WM8741_SDOUT_WIDTH 1 /* SDOUT */
-#define WM8741_DOUT 0x0010 /* DOUT */
-#define WM8741_DOUT_MASK 0x0010 /* DOUT */
-#define WM8741_DOUT_SHIFT 4 /* DOUT */
-#define WM8741_DOUT_WIDTH 1 /* DOUT */
-#define WM8741_DIFF_MASK 0x000C /* DIFF - [3:2] */
-#define WM8741_DIFF_SHIFT 2 /* DIFF - [3:2] */
-#define WM8741_DIFF_WIDTH 2 /* DIFF - [3:2] */
-#define WM8741_DITHER_MASK 0x0003 /* DITHER - [1:0] */
-#define WM8741_DITHER_SHIFT 0 /* DITHER - [1:0] */
-#define WM8741_DITHER_WIDTH 2 /* DITHER - [1:0] */
-
-/*
- * R32 (0x20) - ADDITONAL_CONTROL_1
- */
-#define WM8741_DSD_LEVEL 0x0002 /* DSD_LEVEL */
-#define WM8741_DSD_LEVEL_MASK 0x0002 /* DSD_LEVEL */
-#define WM8741_DSD_LEVEL_SHIFT 1 /* DSD_LEVEL */
-#define WM8741_DSD_LEVEL_WIDTH 1 /* DSD_LEVEL */
-#define WM8741_DSD_NO_NOTCH 0x0001 /* DSD_NO_NOTCH */
-#define WM8741_DSD_NO_NOTCH_MASK 0x0001 /* DSD_NO_NOTCH */
-#define WM8741_DSD_NO_NOTCH_SHIFT 0 /* DSD_NO_NOTCH */
-#define WM8741_DSD_NO_NOTCH_WIDTH 1 /* DSD_NO_NOTCH */
-
-#define WM8741_SYSCLK 0
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8750.c b/ANDROID_3.4.5/sound/soc/codecs/wm8750.c
deleted file mode 100644
index e4c50ce7..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8750.c
+++ /dev/null
@@ -1,857 +0,0 @@
-/*
- * wm8750.c -- WM8750 ALSA SoC audio driver
- *
- * Copyright 2005 Openedhand Ltd.
- *
- * Author: Richard Purdie <richard@openedhand.com>
- *
- * Based on WM8753.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/of_device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-
-#include "wm8750.h"
-
-/*
- * wm8750 register cache
- * We can't read the WM8750 register space when we
- * are using 2 wire for device control, so we cache them instead.
- */
-static const u16 wm8750_reg[] = {
- 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */
- 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */
- 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */
- 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */
- 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */
- 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */
- 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */
- 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */
- 0x0079, 0x0079, 0x0079, /* 40 */
-};
-
-/* codec private data */
-struct wm8750_priv {
- unsigned int sysclk;
- enum snd_soc_control_type control_type;
-};
-
-#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0)
-
-/*
- * WM8750 Controls
- */
-static const char *wm8750_bass[] = {"Linear Control", "Adaptive Boost"};
-static const char *wm8750_bass_filter[] = { "130Hz @ 48kHz", "200Hz @ 48kHz" };
-static const char *wm8750_treble[] = {"8kHz", "4kHz"};
-static const char *wm8750_3d_lc[] = {"200Hz", "500Hz"};
-static const char *wm8750_3d_uc[] = {"2.2kHz", "1.5kHz"};
-static const char *wm8750_3d_func[] = {"Capture", "Playback"};
-static const char *wm8750_alc_func[] = {"Off", "Right", "Left", "Stereo"};
-static const char *wm8750_ng_type[] = {"Constant PGA Gain",
- "Mute ADC Output"};
-static const char *wm8750_line_mux[] = {"Line 1", "Line 2", "Line 3", "PGA",
- "Differential"};
-static const char *wm8750_pga_sel[] = {"Line 1", "Line 2", "Line 3",
- "Differential"};
-static const char *wm8750_out3[] = {"VREF", "ROUT1 + Vol", "MonoOut",
- "ROUT1"};
-static const char *wm8750_diff_sel[] = {"Line 1", "Line 2"};
-static const char *wm8750_adcpol[] = {"Normal", "L Invert", "R Invert",
- "L + R Invert"};
-static const char *wm8750_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
-static const char *wm8750_mono_mux[] = {"Stereo", "Mono (Left)",
- "Mono (Right)", "Digital Mono"};
-
-static const struct soc_enum wm8750_enum[] = {
-SOC_ENUM_SINGLE(WM8750_BASS, 7, 2, wm8750_bass),
-SOC_ENUM_SINGLE(WM8750_BASS, 6, 2, wm8750_bass_filter),
-SOC_ENUM_SINGLE(WM8750_TREBLE, 6, 2, wm8750_treble),
-SOC_ENUM_SINGLE(WM8750_3D, 5, 2, wm8750_3d_lc),
-SOC_ENUM_SINGLE(WM8750_3D, 6, 2, wm8750_3d_uc),
-SOC_ENUM_SINGLE(WM8750_3D, 7, 2, wm8750_3d_func),
-SOC_ENUM_SINGLE(WM8750_ALC1, 7, 4, wm8750_alc_func),
-SOC_ENUM_SINGLE(WM8750_NGATE, 1, 2, wm8750_ng_type),
-SOC_ENUM_SINGLE(WM8750_LOUTM1, 0, 5, wm8750_line_mux),
-SOC_ENUM_SINGLE(WM8750_ROUTM1, 0, 5, wm8750_line_mux),
-SOC_ENUM_SINGLE(WM8750_LADCIN, 6, 4, wm8750_pga_sel), /* 10 */
-SOC_ENUM_SINGLE(WM8750_RADCIN, 6, 4, wm8750_pga_sel),
-SOC_ENUM_SINGLE(WM8750_ADCTL2, 7, 4, wm8750_out3),
-SOC_ENUM_SINGLE(WM8750_ADCIN, 8, 2, wm8750_diff_sel),
-SOC_ENUM_SINGLE(WM8750_ADCDAC, 5, 4, wm8750_adcpol),
-SOC_ENUM_SINGLE(WM8750_ADCDAC, 1, 4, wm8750_deemph),
-SOC_ENUM_SINGLE(WM8750_ADCIN, 6, 4, wm8750_mono_mux), /* 16 */
-
-};
-
-static const struct snd_kcontrol_new wm8750_snd_controls[] = {
-
-SOC_DOUBLE_R("Capture Volume", WM8750_LINVOL, WM8750_RINVOL, 0, 63, 0),
-SOC_DOUBLE_R("Capture ZC Switch", WM8750_LINVOL, WM8750_RINVOL, 6, 1, 0),
-SOC_DOUBLE_R("Capture Switch", WM8750_LINVOL, WM8750_RINVOL, 7, 1, 1),
-
-SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8750_LOUT1V,
- WM8750_ROUT1V, 7, 1, 0),
-SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8750_LOUT2V,
- WM8750_ROUT2V, 7, 1, 0),
-
-SOC_ENUM("Playback De-emphasis", wm8750_enum[15]),
-
-SOC_ENUM("Capture Polarity", wm8750_enum[14]),
-SOC_SINGLE("Playback 6dB Attenuate", WM8750_ADCDAC, 7, 1, 0),
-SOC_SINGLE("Capture 6dB Attenuate", WM8750_ADCDAC, 8, 1, 0),
-
-SOC_DOUBLE_R("PCM Volume", WM8750_LDAC, WM8750_RDAC, 0, 255, 0),
-
-SOC_ENUM("Bass Boost", wm8750_enum[0]),
-SOC_ENUM("Bass Filter", wm8750_enum[1]),
-SOC_SINGLE("Bass Volume", WM8750_BASS, 0, 15, 1),
-
-SOC_SINGLE("Treble Volume", WM8750_TREBLE, 0, 15, 1),
-SOC_ENUM("Treble Cut-off", wm8750_enum[2]),
-
-SOC_SINGLE("3D Switch", WM8750_3D, 0, 1, 0),
-SOC_SINGLE("3D Volume", WM8750_3D, 1, 15, 0),
-SOC_ENUM("3D Lower Cut-off", wm8750_enum[3]),
-SOC_ENUM("3D Upper Cut-off", wm8750_enum[4]),
-SOC_ENUM("3D Mode", wm8750_enum[5]),
-
-SOC_SINGLE("ALC Capture Target Volume", WM8750_ALC1, 0, 7, 0),
-SOC_SINGLE("ALC Capture Max Volume", WM8750_ALC1, 4, 7, 0),
-SOC_ENUM("ALC Capture Function", wm8750_enum[6]),
-SOC_SINGLE("ALC Capture ZC Switch", WM8750_ALC2, 7, 1, 0),
-SOC_SINGLE("ALC Capture Hold Time", WM8750_ALC2, 0, 15, 0),
-SOC_SINGLE("ALC Capture Decay Time", WM8750_ALC3, 4, 15, 0),
-SOC_SINGLE("ALC Capture Attack Time", WM8750_ALC3, 0, 15, 0),
-SOC_SINGLE("ALC Capture NG Threshold", WM8750_NGATE, 3, 31, 0),
-SOC_ENUM("ALC Capture NG Type", wm8750_enum[4]),
-SOC_SINGLE("ALC Capture NG Switch", WM8750_NGATE, 0, 1, 0),
-
-SOC_SINGLE("Left ADC Capture Volume", WM8750_LADC, 0, 255, 0),
-SOC_SINGLE("Right ADC Capture Volume", WM8750_RADC, 0, 255, 0),
-
-SOC_SINGLE("ZC Timeout Switch", WM8750_ADCTL1, 0, 1, 0),
-SOC_SINGLE("Playback Invert Switch", WM8750_ADCTL1, 1, 1, 0),
-
-SOC_SINGLE("Right Speaker Playback Invert Switch", WM8750_ADCTL2, 4, 1, 0),
-
-/* Unimplemented */
-/* ADCDAC Bit 0 - ADCHPD */
-/* ADCDAC Bit 4 - HPOR */
-/* ADCTL1 Bit 2,3 - DATSEL */
-/* ADCTL1 Bit 4,5 - DMONOMIX */
-/* ADCTL1 Bit 6,7 - VSEL */
-/* ADCTL2 Bit 2 - LRCM */
-/* ADCTL2 Bit 3 - TRI */
-/* ADCTL3 Bit 5 - HPFLREN */
-/* ADCTL3 Bit 6 - VROI */
-/* ADCTL3 Bit 7,8 - ADCLRM */
-/* ADCIN Bit 4 - LDCM */
-/* ADCIN Bit 5 - RDCM */
-
-SOC_DOUBLE_R("Mic Boost", WM8750_LADCIN, WM8750_RADCIN, 4, 3, 0),
-
-SOC_DOUBLE_R("Bypass Left Playback Volume", WM8750_LOUTM1,
- WM8750_LOUTM2, 4, 7, 1),
-SOC_DOUBLE_R("Bypass Right Playback Volume", WM8750_ROUTM1,
- WM8750_ROUTM2, 4, 7, 1),
-SOC_DOUBLE_R("Bypass Mono Playback Volume", WM8750_MOUTM1,
- WM8750_MOUTM2, 4, 7, 1),
-
-SOC_SINGLE("Mono Playback ZC Switch", WM8750_MOUTV, 7, 1, 0),
-
-SOC_DOUBLE_R("Headphone Playback Volume", WM8750_LOUT1V, WM8750_ROUT1V,
- 0, 127, 0),
-SOC_DOUBLE_R("Speaker Playback Volume", WM8750_LOUT2V, WM8750_ROUT2V,
- 0, 127, 0),
-
-SOC_SINGLE("Mono Playback Volume", WM8750_MOUTV, 0, 127, 0),
-
-};
-
-/*
- * DAPM Controls
- */
-
-/* Left Mixer */
-static const struct snd_kcontrol_new wm8750_left_mixer_controls[] = {
-SOC_DAPM_SINGLE("Playback Switch", WM8750_LOUTM1, 8, 1, 0),
-SOC_DAPM_SINGLE("Left Bypass Switch", WM8750_LOUTM1, 7, 1, 0),
-SOC_DAPM_SINGLE("Right Playback Switch", WM8750_LOUTM2, 8, 1, 0),
-SOC_DAPM_SINGLE("Right Bypass Switch", WM8750_LOUTM2, 7, 1, 0),
-};
-
-/* Right Mixer */
-static const struct snd_kcontrol_new wm8750_right_mixer_controls[] = {
-SOC_DAPM_SINGLE("Left Playback Switch", WM8750_ROUTM1, 8, 1, 0),
-SOC_DAPM_SINGLE("Left Bypass Switch", WM8750_ROUTM1, 7, 1, 0),
-SOC_DAPM_SINGLE("Playback Switch", WM8750_ROUTM2, 8, 1, 0),
-SOC_DAPM_SINGLE("Right Bypass Switch", WM8750_ROUTM2, 7, 1, 0),
-};
-
-/* Mono Mixer */
-static const struct snd_kcontrol_new wm8750_mono_mixer_controls[] = {
-SOC_DAPM_SINGLE("Left Playback Switch", WM8750_MOUTM1, 8, 1, 0),
-SOC_DAPM_SINGLE("Left Bypass Switch", WM8750_MOUTM1, 7, 1, 0),
-SOC_DAPM_SINGLE("Right Playback Switch", WM8750_MOUTM2, 8, 1, 0),
-SOC_DAPM_SINGLE("Right Bypass Switch", WM8750_MOUTM2, 7, 1, 0),
-};
-
-/* Left Line Mux */
-static const struct snd_kcontrol_new wm8750_left_line_controls =
-SOC_DAPM_ENUM("Route", wm8750_enum[8]);
-
-/* Right Line Mux */
-static const struct snd_kcontrol_new wm8750_right_line_controls =
-SOC_DAPM_ENUM("Route", wm8750_enum[9]);
-
-/* Left PGA Mux */
-static const struct snd_kcontrol_new wm8750_left_pga_controls =
-SOC_DAPM_ENUM("Route", wm8750_enum[10]);
-
-/* Right PGA Mux */
-static const struct snd_kcontrol_new wm8750_right_pga_controls =
-SOC_DAPM_ENUM("Route", wm8750_enum[11]);
-
-/* Out 3 Mux */
-static const struct snd_kcontrol_new wm8750_out3_controls =
-SOC_DAPM_ENUM("Route", wm8750_enum[12]);
-
-/* Differential Mux */
-static const struct snd_kcontrol_new wm8750_diffmux_controls =
-SOC_DAPM_ENUM("Route", wm8750_enum[13]);
-
-/* Mono ADC Mux */
-static const struct snd_kcontrol_new wm8750_monomux_controls =
-SOC_DAPM_ENUM("Route", wm8750_enum[16]);
-
-static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = {
- SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
- &wm8750_left_mixer_controls[0],
- ARRAY_SIZE(wm8750_left_mixer_controls)),
- SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
- &wm8750_right_mixer_controls[0],
- ARRAY_SIZE(wm8750_right_mixer_controls)),
- SND_SOC_DAPM_MIXER("Mono Mixer", WM8750_PWR2, 2, 0,
- &wm8750_mono_mixer_controls[0],
- ARRAY_SIZE(wm8750_mono_mixer_controls)),
-
- SND_SOC_DAPM_PGA("Right Out 2", WM8750_PWR2, 3, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Left Out 2", WM8750_PWR2, 4, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Right Out 1", WM8750_PWR2, 5, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Left Out 1", WM8750_PWR2, 6, 0, NULL, 0),
- SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8750_PWR2, 7, 0),
- SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8750_PWR2, 8, 0),
-
- SND_SOC_DAPM_MICBIAS("Mic Bias", WM8750_PWR1, 1, 0),
- SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8750_PWR1, 2, 0),
- SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8750_PWR1, 3, 0),
-
- SND_SOC_DAPM_MUX("Left PGA Mux", WM8750_PWR1, 5, 0,
- &wm8750_left_pga_controls),
- SND_SOC_DAPM_MUX("Right PGA Mux", WM8750_PWR1, 4, 0,
- &wm8750_right_pga_controls),
- SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0,
- &wm8750_left_line_controls),
- SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0,
- &wm8750_right_line_controls),
-
- SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 0, &wm8750_out3_controls),
- SND_SOC_DAPM_PGA("Out 3", WM8750_PWR2, 1, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Mono Out 1", WM8750_PWR2, 2, 0, NULL, 0),
-
- SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0,
- &wm8750_diffmux_controls),
- SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0,
- &wm8750_monomux_controls),
- SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0,
- &wm8750_monomux_controls),
-
- SND_SOC_DAPM_OUTPUT("LOUT1"),
- SND_SOC_DAPM_OUTPUT("ROUT1"),
- SND_SOC_DAPM_OUTPUT("LOUT2"),
- SND_SOC_DAPM_OUTPUT("ROUT2"),
- SND_SOC_DAPM_OUTPUT("MONO1"),
- SND_SOC_DAPM_OUTPUT("OUT3"),
- SND_SOC_DAPM_OUTPUT("VREF"),
-
- SND_SOC_DAPM_INPUT("LINPUT1"),
- SND_SOC_DAPM_INPUT("LINPUT2"),
- SND_SOC_DAPM_INPUT("LINPUT3"),
- SND_SOC_DAPM_INPUT("RINPUT1"),
- SND_SOC_DAPM_INPUT("RINPUT2"),
- SND_SOC_DAPM_INPUT("RINPUT3"),
-};
-
-static const struct snd_soc_dapm_route wm8750_dapm_routes[] = {
- /* left mixer */
- {"Left Mixer", "Playback Switch", "Left DAC"},
- {"Left Mixer", "Left Bypass Switch", "Left Line Mux"},
- {"Left Mixer", "Right Playback Switch", "Right DAC"},
- {"Left Mixer", "Right Bypass Switch", "Right Line Mux"},
-
- /* right mixer */
- {"Right Mixer", "Left Playback Switch", "Left DAC"},
- {"Right Mixer", "Left Bypass Switch", "Left Line Mux"},
- {"Right Mixer", "Playback Switch", "Right DAC"},
- {"Right Mixer", "Right Bypass Switch", "Right Line Mux"},
-
- /* left out 1 */
- {"Left Out 1", NULL, "Left Mixer"},
- {"LOUT1", NULL, "Left Out 1"},
-
- /* left out 2 */
- {"Left Out 2", NULL, "Left Mixer"},
- {"LOUT2", NULL, "Left Out 2"},
-
- /* right out 1 */
- {"Right Out 1", NULL, "Right Mixer"},
- {"ROUT1", NULL, "Right Out 1"},
-
- /* right out 2 */
- {"Right Out 2", NULL, "Right Mixer"},
- {"ROUT2", NULL, "Right Out 2"},
-
- /* mono mixer */
- {"Mono Mixer", "Left Playback Switch", "Left DAC"},
- {"Mono Mixer", "Left Bypass Switch", "Left Line Mux"},
- {"Mono Mixer", "Right Playback Switch", "Right DAC"},
- {"Mono Mixer", "Right Bypass Switch", "Right Line Mux"},
-
- /* mono out */
- {"Mono Out 1", NULL, "Mono Mixer"},
- {"MONO1", NULL, "Mono Out 1"},
-
- /* out 3 */
- {"Out3 Mux", "VREF", "VREF"},
- {"Out3 Mux", "ROUT1 + Vol", "ROUT1"},
- {"Out3 Mux", "ROUT1", "Right Mixer"},
- {"Out3 Mux", "MonoOut", "MONO1"},
- {"Out 3", NULL, "Out3 Mux"},
- {"OUT3", NULL, "Out 3"},
-
- /* Left Line Mux */
- {"Left Line Mux", "Line 1", "LINPUT1"},
- {"Left Line Mux", "Line 2", "LINPUT2"},
- {"Left Line Mux", "Line 3", "LINPUT3"},
- {"Left Line Mux", "PGA", "Left PGA Mux"},
- {"Left Line Mux", "Differential", "Differential Mux"},
-
- /* Right Line Mux */
- {"Right Line Mux", "Line 1", "RINPUT1"},
- {"Right Line Mux", "Line 2", "RINPUT2"},
- {"Right Line Mux", "Line 3", "RINPUT3"},
- {"Right Line Mux", "PGA", "Right PGA Mux"},
- {"Right Line Mux", "Differential", "Differential Mux"},
-
- /* Left PGA Mux */
- {"Left PGA Mux", "Line 1", "LINPUT1"},
- {"Left PGA Mux", "Line 2", "LINPUT2"},
- {"Left PGA Mux", "Line 3", "LINPUT3"},
- {"Left PGA Mux", "Differential", "Differential Mux"},
-
- /* Right PGA Mux */
- {"Right PGA Mux", "Line 1", "RINPUT1"},
- {"Right PGA Mux", "Line 2", "RINPUT2"},
- {"Right PGA Mux", "Line 3", "RINPUT3"},
- {"Right PGA Mux", "Differential", "Differential Mux"},
-
- /* Differential Mux */
- {"Differential Mux", "Line 1", "LINPUT1"},
- {"Differential Mux", "Line 1", "RINPUT1"},
- {"Differential Mux", "Line 2", "LINPUT2"},
- {"Differential Mux", "Line 2", "RINPUT2"},
-
- /* Left ADC Mux */
- {"Left ADC Mux", "Stereo", "Left PGA Mux"},
- {"Left ADC Mux", "Mono (Left)", "Left PGA Mux"},
- {"Left ADC Mux", "Digital Mono", "Left PGA Mux"},
-
- /* Right ADC Mux */
- {"Right ADC Mux", "Stereo", "Right PGA Mux"},
- {"Right ADC Mux", "Mono (Right)", "Right PGA Mux"},
- {"Right ADC Mux", "Digital Mono", "Right PGA Mux"},
-
- /* ADC */
- {"Left ADC", NULL, "Left ADC Mux"},
- {"Right ADC", NULL, "Right ADC Mux"},
-};
-
-struct _coeff_div {
- u32 mclk;
- u32 rate;
- u16 fs;
- u8 sr:5;
- u8 usb:1;
-};
-
-/* codec hifi mclk clock divider coefficients */
-static const struct _coeff_div coeff_div[] = {
- /* 8k */
- {12288000, 8000, 1536, 0x6, 0x0},
- {11289600, 8000, 1408, 0x16, 0x0},
- {18432000, 8000, 2304, 0x7, 0x0},
- {16934400, 8000, 2112, 0x17, 0x0},
- {12000000, 8000, 1500, 0x6, 0x1},
-
- /* 11.025k */
- {11289600, 11025, 1024, 0x18, 0x0},
- {16934400, 11025, 1536, 0x19, 0x0},
- {12000000, 11025, 1088, 0x19, 0x1},
-
- /* 16k */
- {12288000, 16000, 768, 0xa, 0x0},
- {18432000, 16000, 1152, 0xb, 0x0},
- {12000000, 16000, 750, 0xa, 0x1},
-
- /* 22.05k */
- {11289600, 22050, 512, 0x1a, 0x0},
- {16934400, 22050, 768, 0x1b, 0x0},
- {12000000, 22050, 544, 0x1b, 0x1},
-
- /* 32k */
- {12288000, 32000, 384, 0xc, 0x0},
- {18432000, 32000, 576, 0xd, 0x0},
- {12000000, 32000, 375, 0xa, 0x1},
-
- /* 44.1k */
- {11289600, 44100, 256, 0x10, 0x0},
- {16934400, 44100, 384, 0x11, 0x0},
- {12000000, 44100, 272, 0x11, 0x1},
-
- /* 48k */
- {12288000, 48000, 256, 0x0, 0x0},
- {18432000, 48000, 384, 0x1, 0x0},
- {12000000, 48000, 250, 0x0, 0x1},
-
- /* 88.2k */
- {11289600, 88200, 128, 0x1e, 0x0},
- {16934400, 88200, 192, 0x1f, 0x0},
- {12000000, 88200, 136, 0x1f, 0x1},
-
- /* 96k */
- {12288000, 96000, 128, 0xe, 0x0},
- {18432000, 96000, 192, 0xf, 0x0},
- {12000000, 96000, 125, 0xe, 0x1},
-};
-
-static inline int get_coeff(int mclk, int rate)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
- if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
- return i;
- }
-
- printk(KERN_ERR "wm8750: could not get coeff for mclk %d @ rate %d\n",
- mclk, rate);
- return -EINVAL;
-}
-
-static int wm8750_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
-
- switch (freq) {
- case 11289600:
- case 12000000:
- case 12288000:
- case 16934400:
- case 18432000:
- wm8750->sysclk = freq;
- return 0;
- }
- return -EINVAL;
-}
-
-static int wm8750_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 iface = 0;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- iface = 0x0040;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= 0x0002;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= 0x0001;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= 0x0003;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- iface |= 0x0013;
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= 0x0090;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= 0x0080;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- iface |= 0x0010;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM8750_IFACE, iface);
- return 0;
-}
-
-static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
- u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3;
- u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0;
- int coeff = get_coeff(wm8750->sysclk, params_rate(params));
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= 0x0004;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface |= 0x0008;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- iface |= 0x000c;
- break;
- }
-
- /* set iface & srate */
- snd_soc_write(codec, WM8750_IFACE, iface);
- if (coeff >= 0)
- snd_soc_write(codec, WM8750_SRATE, srate |
- (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
-
- return 0;
-}
-
-static int wm8750_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 mute_reg = snd_soc_read(codec, WM8750_ADCDAC) & 0xfff7;
-
- if (mute)
- snd_soc_write(codec, WM8750_ADCDAC, mute_reg | 0x8);
- else
- snd_soc_write(codec, WM8750_ADCDAC, mute_reg);
- return 0;
-}
-
-static int wm8750_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- u16 pwr_reg = snd_soc_read(codec, WM8750_PWR1) & 0xfe3e;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- /* set vmid to 50k and unmute dac */
- snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x00c0);
- break;
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- snd_soc_cache_sync(codec);
-
- /* Set VMID to 5k */
- snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
-
- /* ...and ramp */
- msleep(1000);
- }
-
- /* mute dac and set vmid to 500k, enable VREF */
- snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x0141);
- break;
- case SND_SOC_BIAS_OFF:
- snd_soc_write(codec, WM8750_PWR1, 0x0001);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define WM8750_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
-
-#define WM8750_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops wm8750_dai_ops = {
- .hw_params = wm8750_pcm_hw_params,
- .digital_mute = wm8750_mute,
- .set_fmt = wm8750_set_dai_fmt,
- .set_sysclk = wm8750_set_dai_sysclk,
-};
-
-static struct snd_soc_dai_driver wm8750_dai = {
- .name = "wm8750-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8750_RATES,
- .formats = WM8750_FORMATS,},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8750_RATES,
- .formats = WM8750_FORMATS,},
- .ops = &wm8750_dai_ops,
-};
-
-static int wm8750_suspend(struct snd_soc_codec *codec)
-{
- wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm8750_resume(struct snd_soc_codec *codec)
-{
- wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-
-static int wm8750_probe(struct snd_soc_codec *codec)
-{
- struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8750->control_type);
- if (ret < 0) {
- printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- ret = wm8750_reset(codec);
- if (ret < 0) {
- printk(KERN_ERR "wm8750: failed to reset: %d\n", ret);
- return ret;
- }
-
- /* charge output caps */
- wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* set the update bits */
- snd_soc_update_bits(codec, WM8750_LDAC, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8750_RDAC, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8750_LOUT1V, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8750_ROUT1V, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8750_LOUT2V, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8750_ROUT2V, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8750_LINVOL, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8750_RINVOL, 0x0100, 0x0100);
-
- return ret;
-}
-
-static int wm8750_remove(struct snd_soc_codec *codec)
-{
- wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8750 = {
- .probe = wm8750_probe,
- .remove = wm8750_remove,
- .suspend = wm8750_suspend,
- .resume = wm8750_resume,
- .set_bias_level = wm8750_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8750_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8750_reg,
-
- .controls = wm8750_snd_controls,
- .num_controls = ARRAY_SIZE(wm8750_snd_controls),
- .dapm_widgets = wm8750_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets),
- .dapm_routes = wm8750_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm8750_dapm_routes),
-};
-
-static const struct of_device_id wm8750_of_match[] = {
- { .compatible = "wlf,wm8750", },
- { .compatible = "wlf,wm8987", },
- { }
-};
-MODULE_DEVICE_TABLE(of, wm8750_of_match);
-
-#if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8750_spi_probe(struct spi_device *spi)
-{
- struct wm8750_priv *wm8750;
- int ret;
-
- wm8750 = devm_kzalloc(&spi->dev, sizeof(struct wm8750_priv),
- GFP_KERNEL);
- if (wm8750 == NULL)
- return -ENOMEM;
-
- wm8750->control_type = SND_SOC_SPI;
- spi_set_drvdata(spi, wm8750);
-
- ret = snd_soc_register_codec(&spi->dev,
- &soc_codec_dev_wm8750, &wm8750_dai, 1);
- return ret;
-}
-
-static int __devexit wm8750_spi_remove(struct spi_device *spi)
-{
- snd_soc_unregister_codec(&spi->dev);
- return 0;
-}
-
-static const struct spi_device_id wm8750_spi_ids[] = {
- { "wm8750", 0 },
- { "wm8987", 0 },
- { },
-};
-MODULE_DEVICE_TABLE(spi, wm8750_spi_ids);
-
-static struct spi_driver wm8750_spi_driver = {
- .driver = {
- .name = "wm8750",
- .owner = THIS_MODULE,
- .of_match_table = wm8750_of_match,
- },
- .id_table = wm8750_spi_ids,
- .probe = wm8750_spi_probe,
- .remove = __devexit_p(wm8750_spi_remove),
-};
-#endif /* CONFIG_SPI_MASTER */
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8750_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8750_priv *wm8750;
- int ret;
-
- wm8750 = devm_kzalloc(&i2c->dev, sizeof(struct wm8750_priv),
- GFP_KERNEL);
- if (wm8750 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm8750);
- wm8750->control_type = SND_SOC_I2C;
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8750, &wm8750_dai, 1);
- return ret;
-}
-
-static __devexit int wm8750_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static const struct i2c_device_id wm8750_i2c_id[] = {
- { "wm8750", 0 },
- { "wm8987", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
-
-static struct i2c_driver wm8750_i2c_driver = {
- .driver = {
- .name = "wm8750",
- .owner = THIS_MODULE,
- .of_match_table = wm8750_of_match,
- },
- .probe = wm8750_i2c_probe,
- .remove = __devexit_p(wm8750_i2c_remove),
- .id_table = wm8750_i2c_id,
-};
-#endif
-
-static int __init wm8750_modinit(void)
-{
- int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&wm8750_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8750 I2C driver: %d\n",
- ret);
- }
-#endif
-#if defined(CONFIG_SPI_MASTER)
- ret = spi_register_driver(&wm8750_spi_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8750 SPI driver: %d\n",
- ret);
- }
-#endif
- return ret;
-}
-module_init(wm8750_modinit);
-
-static void __exit wm8750_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&wm8750_i2c_driver);
-#endif
-#if defined(CONFIG_SPI_MASTER)
- spi_unregister_driver(&wm8750_spi_driver);
-#endif
-}
-module_exit(wm8750_exit);
-
-MODULE_DESCRIPTION("ASoC WM8750 driver");
-MODULE_AUTHOR("Liam Girdwood");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8750.h b/ANDROID_3.4.5/sound/soc/codecs/wm8750.h
deleted file mode 100644
index 121427c0..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8750.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2005 Openedhand Ltd.
- *
- * Author: Richard Purdie <richard@openedhand.com>
- *
- * Based on WM8753.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#ifndef _WM8750_H
-#define _WM8750_H
-
-/* WM8750 register space */
-
-#define WM8750_LINVOL 0x00
-#define WM8750_RINVOL 0x01
-#define WM8750_LOUT1V 0x02
-#define WM8750_ROUT1V 0x03
-#define WM8750_ADCDAC 0x05
-#define WM8750_IFACE 0x07
-#define WM8750_SRATE 0x08
-#define WM8750_LDAC 0x0a
-#define WM8750_RDAC 0x0b
-#define WM8750_BASS 0x0c
-#define WM8750_TREBLE 0x0d
-#define WM8750_RESET 0x0f
-#define WM8750_3D 0x10
-#define WM8750_ALC1 0x11
-#define WM8750_ALC2 0x12
-#define WM8750_ALC3 0x13
-#define WM8750_NGATE 0x14
-#define WM8750_LADC 0x15
-#define WM8750_RADC 0x16
-#define WM8750_ADCTL1 0x17
-#define WM8750_ADCTL2 0x18
-#define WM8750_PWR1 0x19
-#define WM8750_PWR2 0x1a
-#define WM8750_ADCTL3 0x1b
-#define WM8750_ADCIN 0x1f
-#define WM8750_LADCIN 0x20
-#define WM8750_RADCIN 0x21
-#define WM8750_LOUTM1 0x22
-#define WM8750_LOUTM2 0x23
-#define WM8750_ROUTM1 0x24
-#define WM8750_ROUTM2 0x25
-#define WM8750_MOUTM1 0x26
-#define WM8750_MOUTM2 0x27
-#define WM8750_LOUT2V 0x28
-#define WM8750_ROUT2V 0x29
-#define WM8750_MOUTV 0x2a
-
-#define WM8750_CACHE_REGNUM 0x2a
-
-#define WM8750_SYSCLK 0
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8753.c b/ANDROID_3.4.5/sound/soc/codecs/wm8753.c
deleted file mode 100644
index e27e7b62..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8753.c
+++ /dev/null
@@ -1,1709 +0,0 @@
-/*
- * wm8753.c -- WM8753 ALSA Soc Audio driver
- *
- * Copyright 2003 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood <lrg@slimlogic.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * Notes:
- * The WM8753 is a low power, high quality stereo codec with integrated PCM
- * codec designed for portable digital telephony applications.
- *
- * Dual DAI:-
- *
- * This driver support 2 DAI PCM's. This makes the default PCM available for
- * HiFi audio (e.g. MP3, ogg) playback/capture and the other PCM available for
- * voice.
- *
- * Please note that the voice PCM can be connected directly to a Bluetooth
- * codec or GSM modem and thus cannot be read or written to, although it is
- * available to be configured with snd_hw_params(), etc and kcontrols in the
- * normal alsa manner.
- *
- * Fast DAI switching:-
- *
- * The driver can now fast switch between the DAI configurations via a
- * an alsa kcontrol. This allows the PCM to remain open.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/of_device.h>
-#include <linux/regmap.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <asm/div64.h>
-
-#include "wm8753.h"
-
-static int caps_charge = 2000;
-module_param(caps_charge, int, 0);
-MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)");
-
-static int wm8753_hifi_write_dai_fmt(struct snd_soc_codec *codec,
- unsigned int fmt);
-static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec,
- unsigned int fmt);
-
-/*
- * wm8753 register cache
- * We can't read the WM8753 register space when we
- * are using 2 wire for device control, so we cache them instead.
- */
-static const struct reg_default wm8753_reg_defaults[] = {
- { 0x00, 0x0000 },
- { 0x01, 0x0008 },
- { 0x02, 0x0000 },
- { 0x03, 0x000a },
- { 0x04, 0x000a },
- { 0x05, 0x0033 },
- { 0x06, 0x0000 },
- { 0x07, 0x0007 },
- { 0x08, 0x00ff },
- { 0x09, 0x00ff },
- { 0x0a, 0x000f },
- { 0x0b, 0x000f },
- { 0x0c, 0x007b },
- { 0x0d, 0x0000 },
- { 0x0e, 0x0032 },
- { 0x0f, 0x0000 },
- { 0x10, 0x00c3 },
- { 0x11, 0x00c3 },
- { 0x12, 0x00c0 },
- { 0x13, 0x0000 },
- { 0x14, 0x0000 },
- { 0x15, 0x0000 },
- { 0x16, 0x0000 },
- { 0x17, 0x0000 },
- { 0x18, 0x0000 },
- { 0x19, 0x0000 },
- { 0x1a, 0x0000 },
- { 0x1b, 0x0000 },
- { 0x1c, 0x0000 },
- { 0x1d, 0x0000 },
- { 0x1e, 0x0000 },
- { 0x1f, 0x0000 },
- { 0x20, 0x0055 },
- { 0x21, 0x0005 },
- { 0x22, 0x0050 },
- { 0x23, 0x0055 },
- { 0x24, 0x0050 },
- { 0x25, 0x0055 },
- { 0x26, 0x0050 },
- { 0x27, 0x0055 },
- { 0x28, 0x0079 },
- { 0x29, 0x0079 },
- { 0x2a, 0x0079 },
- { 0x2b, 0x0079 },
- { 0x2c, 0x0079 },
- { 0x2d, 0x0000 },
- { 0x2e, 0x0000 },
- { 0x2f, 0x0000 },
- { 0x30, 0x0000 },
- { 0x31, 0x0097 },
- { 0x32, 0x0097 },
- { 0x33, 0x0000 },
- { 0x34, 0x0004 },
- { 0x35, 0x0000 },
- { 0x36, 0x0083 },
- { 0x37, 0x0024 },
- { 0x38, 0x01ba },
- { 0x39, 0x0000 },
- { 0x3a, 0x0083 },
- { 0x3b, 0x0024 },
- { 0x3c, 0x01ba },
- { 0x3d, 0x0000 },
- { 0x3e, 0x0000 },
- { 0x3f, 0x0000 },
-};
-
-static bool wm8753_volatile(struct device *dev, unsigned int reg)
-{
- return reg == WM8753_RESET;
-}
-
-static bool wm8753_writeable(struct device *dev, unsigned int reg)
-{
- return reg <= WM8753_ADCTL2;
-}
-
-/* codec private data */
-struct wm8753_priv {
- struct regmap *regmap;
- unsigned int sysclk;
- unsigned int pcmclk;
-
- unsigned int voice_fmt;
- unsigned int hifi_fmt;
-
- int dai_func;
-};
-
-#define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0)
-
-/*
- * WM8753 Controls
- */
-static const char *wm8753_base[] = {"Linear Control", "Adaptive Boost"};
-static const char *wm8753_base_filter[] =
- {"130Hz @ 48kHz", "200Hz @ 48kHz", "100Hz @ 16kHz", "400Hz @ 48kHz",
- "100Hz @ 8kHz", "200Hz @ 8kHz"};
-static const char *wm8753_treble[] = {"8kHz", "4kHz"};
-static const char *wm8753_alc_func[] = {"Off", "Right", "Left", "Stereo"};
-static const char *wm8753_ng_type[] = {"Constant PGA Gain", "Mute ADC Output"};
-static const char *wm8753_3d_func[] = {"Capture", "Playback"};
-static const char *wm8753_3d_uc[] = {"2.2kHz", "1.5kHz"};
-static const char *wm8753_3d_lc[] = {"200Hz", "500Hz"};
-static const char *wm8753_deemp[] = {"None", "32kHz", "44.1kHz", "48kHz"};
-static const char *wm8753_mono_mix[] = {"Stereo", "Left", "Right", "Mono"};
-static const char *wm8753_dac_phase[] = {"Non Inverted", "Inverted"};
-static const char *wm8753_line_mix[] = {"Line 1 + 2", "Line 1 - 2",
- "Line 1", "Line 2"};
-static const char *wm8753_mono_mux[] = {"Line Mix", "Rx Mix"};
-static const char *wm8753_right_mux[] = {"Line 2", "Rx Mix"};
-static const char *wm8753_left_mux[] = {"Line 1", "Rx Mix"};
-static const char *wm8753_rxmsel[] = {"RXP - RXN", "RXP + RXN", "RXP", "RXN"};
-static const char *wm8753_sidetone_mux[] = {"Left PGA", "Mic 1", "Mic 2",
- "Right PGA"};
-static const char *wm8753_mono2_src[] = {"Inverted Mono 1", "Left", "Right",
- "Left + Right"};
-static const char *wm8753_out3[] = {"VREF", "ROUT2", "Left + Right"};
-static const char *wm8753_out4[] = {"VREF", "Capture ST", "LOUT2"};
-static const char *wm8753_radcsel[] = {"PGA", "Line or RXP-RXN", "Sidetone"};
-static const char *wm8753_ladcsel[] = {"PGA", "Line or RXP-RXN", "Line"};
-static const char *wm8753_mono_adc[] = {"Stereo", "Analogue Mix Left",
- "Analogue Mix Right", "Digital Mono Mix"};
-static const char *wm8753_adc_hp[] = {"3.4Hz @ 48kHz", "82Hz @ 16k",
- "82Hz @ 8kHz", "170Hz @ 8kHz"};
-static const char *wm8753_adc_filter[] = {"HiFi", "Voice"};
-static const char *wm8753_mic_sel[] = {"Mic 1", "Mic 2", "Mic 3"};
-static const char *wm8753_dai_mode[] = {"DAI 0", "DAI 1", "DAI 2", "DAI 3"};
-static const char *wm8753_dat_sel[] = {"Stereo", "Left ADC", "Right ADC",
- "Channel Swap"};
-static const char *wm8753_rout2_phase[] = {"Non Inverted", "Inverted"};
-
-static const struct soc_enum wm8753_enum[] = {
-SOC_ENUM_SINGLE(WM8753_BASS, 7, 2, wm8753_base),
-SOC_ENUM_SINGLE(WM8753_BASS, 4, 6, wm8753_base_filter),
-SOC_ENUM_SINGLE(WM8753_TREBLE, 6, 2, wm8753_treble),
-SOC_ENUM_SINGLE(WM8753_ALC1, 7, 4, wm8753_alc_func),
-SOC_ENUM_SINGLE(WM8753_NGATE, 1, 2, wm8753_ng_type),
-SOC_ENUM_SINGLE(WM8753_3D, 7, 2, wm8753_3d_func),
-SOC_ENUM_SINGLE(WM8753_3D, 6, 2, wm8753_3d_uc),
-SOC_ENUM_SINGLE(WM8753_3D, 5, 2, wm8753_3d_lc),
-SOC_ENUM_SINGLE(WM8753_DAC, 1, 4, wm8753_deemp),
-SOC_ENUM_SINGLE(WM8753_DAC, 4, 4, wm8753_mono_mix),
-SOC_ENUM_SINGLE(WM8753_DAC, 6, 2, wm8753_dac_phase),
-SOC_ENUM_SINGLE(WM8753_INCTL1, 3, 4, wm8753_line_mix),
-SOC_ENUM_SINGLE(WM8753_INCTL1, 2, 2, wm8753_mono_mux),
-SOC_ENUM_SINGLE(WM8753_INCTL1, 1, 2, wm8753_right_mux),
-SOC_ENUM_SINGLE(WM8753_INCTL1, 0, 2, wm8753_left_mux),
-SOC_ENUM_SINGLE(WM8753_INCTL2, 6, 4, wm8753_rxmsel),
-SOC_ENUM_SINGLE(WM8753_INCTL2, 4, 4, wm8753_sidetone_mux),
-SOC_ENUM_SINGLE(WM8753_OUTCTL, 7, 4, wm8753_mono2_src),
-SOC_ENUM_SINGLE(WM8753_OUTCTL, 0, 3, wm8753_out3),
-SOC_ENUM_SINGLE(WM8753_ADCTL2, 7, 3, wm8753_out4),
-SOC_ENUM_SINGLE(WM8753_ADCIN, 2, 3, wm8753_radcsel),
-SOC_ENUM_SINGLE(WM8753_ADCIN, 0, 3, wm8753_ladcsel),
-SOC_ENUM_SINGLE(WM8753_ADCIN, 4, 4, wm8753_mono_adc),
-SOC_ENUM_SINGLE(WM8753_ADC, 2, 4, wm8753_adc_hp),
-SOC_ENUM_SINGLE(WM8753_ADC, 4, 2, wm8753_adc_filter),
-SOC_ENUM_SINGLE(WM8753_MICBIAS, 6, 3, wm8753_mic_sel),
-SOC_ENUM_SINGLE(WM8753_IOCTL, 2, 4, wm8753_dai_mode),
-SOC_ENUM_SINGLE(WM8753_ADC, 7, 4, wm8753_dat_sel),
-SOC_ENUM_SINGLE(WM8753_OUTCTL, 2, 2, wm8753_rout2_phase),
-};
-
-
-static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.integer.value[0] = wm8753->dai_func;
- return 0;
-}
-
-static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
- u16 ioctl;
-
- if (wm8753->dai_func == ucontrol->value.integer.value[0])
- return 0;
-
- if (codec->active)
- return -EBUSY;
-
- ioctl = snd_soc_read(codec, WM8753_IOCTL);
-
- wm8753->dai_func = ucontrol->value.integer.value[0];
-
- if (((ioctl >> 2) & 0x3) == wm8753->dai_func)
- return 1;
-
- ioctl = (ioctl & 0x1f3) | (wm8753->dai_func << 2);
- snd_soc_write(codec, WM8753_IOCTL, ioctl);
-
-
- wm8753_hifi_write_dai_fmt(codec, wm8753->hifi_fmt);
- wm8753_voice_write_dai_fmt(codec, wm8753->voice_fmt);
-
- return 1;
-}
-
-static const DECLARE_TLV_DB_SCALE(rec_mix_tlv, -1500, 300, 0);
-static const DECLARE_TLV_DB_SCALE(mic_preamp_tlv, 1200, 600, 0);
-static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1);
-static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
-static const unsigned int out_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- /* 0000000 - 0101111 = "Analogue mute" */
- 0, 48, TLV_DB_SCALE_ITEM(-25500, 0, 0),
- 48, 127, TLV_DB_SCALE_ITEM(-7300, 100, 0),
-};
-static const DECLARE_TLV_DB_SCALE(mix_tlv, -1500, 300, 0);
-static const DECLARE_TLV_DB_SCALE(voice_mix_tlv, -1200, 300, 0);
-static const DECLARE_TLV_DB_SCALE(pga_tlv, -1725, 75, 0);
-
-static const struct snd_kcontrol_new wm8753_snd_controls[] = {
-SOC_DOUBLE_R_TLV("PCM Volume", WM8753_LDAC, WM8753_RDAC, 0, 255, 0, dac_tlv),
-
-SOC_DOUBLE_R_TLV("ADC Capture Volume", WM8753_LADC, WM8753_RADC, 0, 255, 0,
- adc_tlv),
-
-SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8753_LOUT1V, WM8753_ROUT1V,
- 0, 127, 0, out_tlv),
-SOC_DOUBLE_R_TLV("Speaker Playback Volume", WM8753_LOUT2V, WM8753_ROUT2V, 0,
- 127, 0, out_tlv),
-
-SOC_SINGLE_TLV("Mono Playback Volume", WM8753_MOUTV, 0, 127, 0, out_tlv),
-
-SOC_DOUBLE_R_TLV("Bypass Playback Volume", WM8753_LOUTM1, WM8753_ROUTM1, 4, 7,
- 1, mix_tlv),
-SOC_DOUBLE_R_TLV("Sidetone Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 4,
- 7, 1, mix_tlv),
-SOC_DOUBLE_R_TLV("Voice Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 0, 7,
- 1, voice_mix_tlv),
-
-SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8753_LOUT1V, WM8753_ROUT1V, 7,
- 1, 0),
-SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8753_LOUT2V, WM8753_ROUT2V, 7,
- 1, 0),
-
-SOC_SINGLE_TLV("Mono Bypass Playback Volume", WM8753_MOUTM1, 4, 7, 1, mix_tlv),
-SOC_SINGLE_TLV("Mono Sidetone Playback Volume", WM8753_MOUTM2, 4, 7, 1,
- mix_tlv),
-SOC_SINGLE_TLV("Mono Voice Playback Volume", WM8753_MOUTM2, 0, 7, 1,
- voice_mix_tlv),
-SOC_SINGLE("Mono Playback ZC Switch", WM8753_MOUTV, 7, 1, 0),
-
-SOC_ENUM("Bass Boost", wm8753_enum[0]),
-SOC_ENUM("Bass Filter", wm8753_enum[1]),
-SOC_SINGLE("Bass Volume", WM8753_BASS, 0, 15, 1),
-
-SOC_SINGLE("Treble Volume", WM8753_TREBLE, 0, 15, 1),
-SOC_ENUM("Treble Cut-off", wm8753_enum[2]),
-
-SOC_DOUBLE_TLV("Sidetone Capture Volume", WM8753_RECMIX1, 0, 4, 7, 1,
- rec_mix_tlv),
-SOC_SINGLE_TLV("Voice Sidetone Capture Volume", WM8753_RECMIX2, 0, 7, 1,
- rec_mix_tlv),
-
-SOC_DOUBLE_R_TLV("Capture Volume", WM8753_LINVOL, WM8753_RINVOL, 0, 63, 0,
- pga_tlv),
-SOC_DOUBLE_R("Capture ZC Switch", WM8753_LINVOL, WM8753_RINVOL, 6, 1, 0),
-SOC_DOUBLE_R("Capture Switch", WM8753_LINVOL, WM8753_RINVOL, 7, 1, 1),
-
-SOC_ENUM("Capture Filter Select", wm8753_enum[23]),
-SOC_ENUM("Capture Filter Cut-off", wm8753_enum[24]),
-SOC_SINGLE("Capture Filter Switch", WM8753_ADC, 0, 1, 1),
-
-SOC_SINGLE("ALC Capture Target Volume", WM8753_ALC1, 0, 7, 0),
-SOC_SINGLE("ALC Capture Max Volume", WM8753_ALC1, 4, 7, 0),
-SOC_ENUM("ALC Capture Function", wm8753_enum[3]),
-SOC_SINGLE("ALC Capture ZC Switch", WM8753_ALC2, 8, 1, 0),
-SOC_SINGLE("ALC Capture Hold Time", WM8753_ALC2, 0, 15, 1),
-SOC_SINGLE("ALC Capture Decay Time", WM8753_ALC3, 4, 15, 1),
-SOC_SINGLE("ALC Capture Attack Time", WM8753_ALC3, 0, 15, 0),
-SOC_SINGLE("ALC Capture NG Threshold", WM8753_NGATE, 3, 31, 0),
-SOC_ENUM("ALC Capture NG Type", wm8753_enum[4]),
-SOC_SINGLE("ALC Capture NG Switch", WM8753_NGATE, 0, 1, 0),
-
-SOC_ENUM("3D Function", wm8753_enum[5]),
-SOC_ENUM("3D Upper Cut-off", wm8753_enum[6]),
-SOC_ENUM("3D Lower Cut-off", wm8753_enum[7]),
-SOC_SINGLE("3D Volume", WM8753_3D, 1, 15, 0),
-SOC_SINGLE("3D Switch", WM8753_3D, 0, 1, 0),
-
-SOC_SINGLE("Capture 6dB Attenuate", WM8753_ADCTL1, 2, 1, 0),
-SOC_SINGLE("Playback 6dB Attenuate", WM8753_ADCTL1, 1, 1, 0),
-
-SOC_ENUM("De-emphasis", wm8753_enum[8]),
-SOC_ENUM("Playback Mono Mix", wm8753_enum[9]),
-SOC_ENUM("Playback Phase", wm8753_enum[10]),
-
-SOC_SINGLE_TLV("Mic2 Capture Volume", WM8753_INCTL1, 7, 3, 0, mic_preamp_tlv),
-SOC_SINGLE_TLV("Mic1 Capture Volume", WM8753_INCTL1, 5, 3, 0, mic_preamp_tlv),
-
-SOC_ENUM_EXT("DAI Mode", wm8753_enum[26], wm8753_get_dai, wm8753_set_dai),
-
-SOC_ENUM("ADC Data Select", wm8753_enum[27]),
-SOC_ENUM("ROUT2 Phase", wm8753_enum[28]),
-};
-
-/*
- * _DAPM_ Controls
- */
-
-/* Left Mixer */
-static const struct snd_kcontrol_new wm8753_left_mixer_controls[] = {
-SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_LOUTM2, 8, 1, 0),
-SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_LOUTM2, 7, 1, 0),
-SOC_DAPM_SINGLE("Left Playback Switch", WM8753_LOUTM1, 8, 1, 0),
-SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_LOUTM1, 7, 1, 0),
-};
-
-/* Right mixer */
-static const struct snd_kcontrol_new wm8753_right_mixer_controls[] = {
-SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_ROUTM2, 8, 1, 0),
-SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_ROUTM2, 7, 1, 0),
-SOC_DAPM_SINGLE("Right Playback Switch", WM8753_ROUTM1, 8, 1, 0),
-SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_ROUTM1, 7, 1, 0),
-};
-
-/* Mono mixer */
-static const struct snd_kcontrol_new wm8753_mono_mixer_controls[] = {
-SOC_DAPM_SINGLE("Left Playback Switch", WM8753_MOUTM1, 8, 1, 0),
-SOC_DAPM_SINGLE("Right Playback Switch", WM8753_MOUTM2, 8, 1, 0),
-SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_MOUTM2, 3, 1, 0),
-SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_MOUTM2, 7, 1, 0),
-SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_MOUTM1, 7, 1, 0),
-};
-
-/* Mono 2 Mux */
-static const struct snd_kcontrol_new wm8753_mono2_controls =
-SOC_DAPM_ENUM("Route", wm8753_enum[17]);
-
-/* Out 3 Mux */
-static const struct snd_kcontrol_new wm8753_out3_controls =
-SOC_DAPM_ENUM("Route", wm8753_enum[18]);
-
-/* Out 4 Mux */
-static const struct snd_kcontrol_new wm8753_out4_controls =
-SOC_DAPM_ENUM("Route", wm8753_enum[19]);
-
-/* ADC Mono Mix */
-static const struct snd_kcontrol_new wm8753_adc_mono_controls =
-SOC_DAPM_ENUM("Route", wm8753_enum[22]);
-
-/* Record mixer */
-static const struct snd_kcontrol_new wm8753_record_mixer_controls[] = {
-SOC_DAPM_SINGLE("Voice Capture Switch", WM8753_RECMIX2, 3, 1, 0),
-SOC_DAPM_SINGLE("Left Capture Switch", WM8753_RECMIX1, 3, 1, 0),
-SOC_DAPM_SINGLE("Right Capture Switch", WM8753_RECMIX1, 7, 1, 0),
-};
-
-/* Left ADC mux */
-static const struct snd_kcontrol_new wm8753_adc_left_controls =
-SOC_DAPM_ENUM("Route", wm8753_enum[21]);
-
-/* Right ADC mux */
-static const struct snd_kcontrol_new wm8753_adc_right_controls =
-SOC_DAPM_ENUM("Route", wm8753_enum[20]);
-
-/* MIC mux */
-static const struct snd_kcontrol_new wm8753_mic_mux_controls =
-SOC_DAPM_ENUM("Route", wm8753_enum[16]);
-
-/* ALC mixer */
-static const struct snd_kcontrol_new wm8753_alc_mixer_controls[] = {
-SOC_DAPM_SINGLE("Line Capture Switch", WM8753_INCTL2, 3, 1, 0),
-SOC_DAPM_SINGLE("Mic2 Capture Switch", WM8753_INCTL2, 2, 1, 0),
-SOC_DAPM_SINGLE("Mic1 Capture Switch", WM8753_INCTL2, 1, 1, 0),
-SOC_DAPM_SINGLE("Rx Capture Switch", WM8753_INCTL2, 0, 1, 0),
-};
-
-/* Left Line mux */
-static const struct snd_kcontrol_new wm8753_line_left_controls =
-SOC_DAPM_ENUM("Route", wm8753_enum[14]);
-
-/* Right Line mux */
-static const struct snd_kcontrol_new wm8753_line_right_controls =
-SOC_DAPM_ENUM("Route", wm8753_enum[13]);
-
-/* Mono Line mux */
-static const struct snd_kcontrol_new wm8753_line_mono_controls =
-SOC_DAPM_ENUM("Route", wm8753_enum[12]);
-
-/* Line mux and mixer */
-static const struct snd_kcontrol_new wm8753_line_mux_mix_controls =
-SOC_DAPM_ENUM("Route", wm8753_enum[11]);
-
-/* Rx mux and mixer */
-static const struct snd_kcontrol_new wm8753_rx_mux_mix_controls =
-SOC_DAPM_ENUM("Route", wm8753_enum[15]);
-
-/* Mic Selector Mux */
-static const struct snd_kcontrol_new wm8753_mic_sel_mux_controls =
-SOC_DAPM_ENUM("Route", wm8753_enum[25]);
-
-static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = {
-SND_SOC_DAPM_MICBIAS("Mic Bias", WM8753_PWR1, 5, 0),
-SND_SOC_DAPM_MIXER("Left Mixer", WM8753_PWR4, 0, 0,
- &wm8753_left_mixer_controls[0], ARRAY_SIZE(wm8753_left_mixer_controls)),
-SND_SOC_DAPM_PGA("Left Out 1", WM8753_PWR3, 8, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Left Out 2", WM8753_PWR3, 6, 0, NULL, 0),
-SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", WM8753_PWR1, 3, 0),
-SND_SOC_DAPM_OUTPUT("LOUT1"),
-SND_SOC_DAPM_OUTPUT("LOUT2"),
-SND_SOC_DAPM_MIXER("Right Mixer", WM8753_PWR4, 1, 0,
- &wm8753_right_mixer_controls[0], ARRAY_SIZE(wm8753_right_mixer_controls)),
-SND_SOC_DAPM_PGA("Right Out 1", WM8753_PWR3, 7, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right Out 2", WM8753_PWR3, 5, 0, NULL, 0),
-SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", WM8753_PWR1, 2, 0),
-SND_SOC_DAPM_OUTPUT("ROUT1"),
-SND_SOC_DAPM_OUTPUT("ROUT2"),
-SND_SOC_DAPM_MIXER("Mono Mixer", WM8753_PWR4, 2, 0,
- &wm8753_mono_mixer_controls[0], ARRAY_SIZE(wm8753_mono_mixer_controls)),
-SND_SOC_DAPM_PGA("Mono Out 1", WM8753_PWR3, 2, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Mono Out 2", WM8753_PWR3, 1, 0, NULL, 0),
-SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", WM8753_PWR1, 4, 0),
-SND_SOC_DAPM_OUTPUT("MONO1"),
-SND_SOC_DAPM_MUX("Mono 2 Mux", SND_SOC_NOPM, 0, 0, &wm8753_mono2_controls),
-SND_SOC_DAPM_OUTPUT("MONO2"),
-SND_SOC_DAPM_MIXER("Out3 Left + Right", -1, 0, 0, NULL, 0),
-SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 0, &wm8753_out3_controls),
-SND_SOC_DAPM_PGA("Out 3", WM8753_PWR3, 4, 0, NULL, 0),
-SND_SOC_DAPM_OUTPUT("OUT3"),
-SND_SOC_DAPM_MUX("Out4 Mux", SND_SOC_NOPM, 0, 0, &wm8753_out4_controls),
-SND_SOC_DAPM_PGA("Out 4", WM8753_PWR3, 3, 0, NULL, 0),
-SND_SOC_DAPM_OUTPUT("OUT4"),
-SND_SOC_DAPM_MIXER("Playback Mixer", WM8753_PWR4, 3, 0,
- &wm8753_record_mixer_controls[0],
- ARRAY_SIZE(wm8753_record_mixer_controls)),
-SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8753_PWR2, 3, 0),
-SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8753_PWR2, 2, 0),
-SND_SOC_DAPM_MUX("Capture Left Mixer", SND_SOC_NOPM, 0, 0,
- &wm8753_adc_mono_controls),
-SND_SOC_DAPM_MUX("Capture Right Mixer", SND_SOC_NOPM, 0, 0,
- &wm8753_adc_mono_controls),
-SND_SOC_DAPM_MUX("Capture Left Mux", SND_SOC_NOPM, 0, 0,
- &wm8753_adc_left_controls),
-SND_SOC_DAPM_MUX("Capture Right Mux", SND_SOC_NOPM, 0, 0,
- &wm8753_adc_right_controls),
-SND_SOC_DAPM_MUX("Mic Sidetone Mux", SND_SOC_NOPM, 0, 0,
- &wm8753_mic_mux_controls),
-SND_SOC_DAPM_PGA("Left Capture Volume", WM8753_PWR2, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right Capture Volume", WM8753_PWR2, 4, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("ALC Mixer", WM8753_PWR2, 6, 0,
- &wm8753_alc_mixer_controls[0], ARRAY_SIZE(wm8753_alc_mixer_controls)),
-SND_SOC_DAPM_MUX("Line Left Mux", SND_SOC_NOPM, 0, 0,
- &wm8753_line_left_controls),
-SND_SOC_DAPM_MUX("Line Right Mux", SND_SOC_NOPM, 0, 0,
- &wm8753_line_right_controls),
-SND_SOC_DAPM_MUX("Line Mono Mux", SND_SOC_NOPM, 0, 0,
- &wm8753_line_mono_controls),
-SND_SOC_DAPM_MUX("Line Mixer", WM8753_PWR2, 0, 0,
- &wm8753_line_mux_mix_controls),
-SND_SOC_DAPM_MUX("Rx Mixer", WM8753_PWR2, 1, 0,
- &wm8753_rx_mux_mix_controls),
-SND_SOC_DAPM_PGA("Mic 1 Volume", WM8753_PWR2, 8, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Mic 2 Volume", WM8753_PWR2, 7, 0, NULL, 0),
-SND_SOC_DAPM_MUX("Mic Selection Mux", SND_SOC_NOPM, 0, 0,
- &wm8753_mic_sel_mux_controls),
-SND_SOC_DAPM_INPUT("LINE1"),
-SND_SOC_DAPM_INPUT("LINE2"),
-SND_SOC_DAPM_INPUT("RXP"),
-SND_SOC_DAPM_INPUT("RXN"),
-SND_SOC_DAPM_INPUT("ACIN"),
-SND_SOC_DAPM_OUTPUT("ACOP"),
-SND_SOC_DAPM_INPUT("MIC1N"),
-SND_SOC_DAPM_INPUT("MIC1"),
-SND_SOC_DAPM_INPUT("MIC2N"),
-SND_SOC_DAPM_INPUT("MIC2"),
-SND_SOC_DAPM_VMID("VREF"),
-};
-
-static const struct snd_soc_dapm_route wm8753_dapm_routes[] = {
- /* left mixer */
- {"Left Mixer", "Left Playback Switch", "Left DAC"},
- {"Left Mixer", "Voice Playback Switch", "Voice DAC"},
- {"Left Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
- {"Left Mixer", "Bypass Playback Switch", "Line Left Mux"},
-
- /* right mixer */
- {"Right Mixer", "Right Playback Switch", "Right DAC"},
- {"Right Mixer", "Voice Playback Switch", "Voice DAC"},
- {"Right Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
- {"Right Mixer", "Bypass Playback Switch", "Line Right Mux"},
-
- /* mono mixer */
- {"Mono Mixer", "Voice Playback Switch", "Voice DAC"},
- {"Mono Mixer", "Left Playback Switch", "Left DAC"},
- {"Mono Mixer", "Right Playback Switch", "Right DAC"},
- {"Mono Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
- {"Mono Mixer", "Bypass Playback Switch", "Line Mono Mux"},
-
- /* left out */
- {"Left Out 1", NULL, "Left Mixer"},
- {"Left Out 2", NULL, "Left Mixer"},
- {"LOUT1", NULL, "Left Out 1"},
- {"LOUT2", NULL, "Left Out 2"},
-
- /* right out */
- {"Right Out 1", NULL, "Right Mixer"},
- {"Right Out 2", NULL, "Right Mixer"},
- {"ROUT1", NULL, "Right Out 1"},
- {"ROUT2", NULL, "Right Out 2"},
-
- /* mono 1 out */
- {"Mono Out 1", NULL, "Mono Mixer"},
- {"MONO1", NULL, "Mono Out 1"},
-
- /* mono 2 out */
- {"Mono 2 Mux", "Left + Right", "Out3 Left + Right"},
- {"Mono 2 Mux", "Inverted Mono 1", "MONO1"},
- {"Mono 2 Mux", "Left", "Left Mixer"},
- {"Mono 2 Mux", "Right", "Right Mixer"},
- {"Mono Out 2", NULL, "Mono 2 Mux"},
- {"MONO2", NULL, "Mono Out 2"},
-
- /* out 3 */
- {"Out3 Left + Right", NULL, "Left Mixer"},
- {"Out3 Left + Right", NULL, "Right Mixer"},
- {"Out3 Mux", "VREF", "VREF"},
- {"Out3 Mux", "Left + Right", "Out3 Left + Right"},
- {"Out3 Mux", "ROUT2", "ROUT2"},
- {"Out 3", NULL, "Out3 Mux"},
- {"OUT3", NULL, "Out 3"},
-
- /* out 4 */
- {"Out4 Mux", "VREF", "VREF"},
- {"Out4 Mux", "Capture ST", "Playback Mixer"},
- {"Out4 Mux", "LOUT2", "LOUT2"},
- {"Out 4", NULL, "Out4 Mux"},
- {"OUT4", NULL, "Out 4"},
-
- /* record mixer */
- {"Playback Mixer", "Left Capture Switch", "Left Mixer"},
- {"Playback Mixer", "Voice Capture Switch", "Mono Mixer"},
- {"Playback Mixer", "Right Capture Switch", "Right Mixer"},
-
- /* Mic/SideTone Mux */
- {"Mic Sidetone Mux", "Left PGA", "Left Capture Volume"},
- {"Mic Sidetone Mux", "Right PGA", "Right Capture Volume"},
- {"Mic Sidetone Mux", "Mic 1", "Mic 1 Volume"},
- {"Mic Sidetone Mux", "Mic 2", "Mic 2 Volume"},
-
- /* Capture Left Mux */
- {"Capture Left Mux", "PGA", "Left Capture Volume"},
- {"Capture Left Mux", "Line or RXP-RXN", "Line Left Mux"},
- {"Capture Left Mux", "Line", "LINE1"},
-
- /* Capture Right Mux */
- {"Capture Right Mux", "PGA", "Right Capture Volume"},
- {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"},
- {"Capture Right Mux", "Sidetone", "Playback Mixer"},
-
- /* Mono Capture mixer-mux */
- {"Capture Right Mixer", "Stereo", "Capture Right Mux"},
- {"Capture Left Mixer", "Stereo", "Capture Left Mux"},
- {"Capture Left Mixer", "Analogue Mix Left", "Capture Left Mux"},
- {"Capture Left Mixer", "Analogue Mix Left", "Capture Right Mux"},
- {"Capture Right Mixer", "Analogue Mix Right", "Capture Left Mux"},
- {"Capture Right Mixer", "Analogue Mix Right", "Capture Right Mux"},
- {"Capture Left Mixer", "Digital Mono Mix", "Capture Left Mux"},
- {"Capture Left Mixer", "Digital Mono Mix", "Capture Right Mux"},
- {"Capture Right Mixer", "Digital Mono Mix", "Capture Left Mux"},
- {"Capture Right Mixer", "Digital Mono Mix", "Capture Right Mux"},
-
- /* ADC */
- {"Left ADC", NULL, "Capture Left Mixer"},
- {"Right ADC", NULL, "Capture Right Mixer"},
-
- /* Left Capture Volume */
- {"Left Capture Volume", NULL, "ACIN"},
-
- /* Right Capture Volume */
- {"Right Capture Volume", NULL, "Mic 2 Volume"},
-
- /* ALC Mixer */
- {"ALC Mixer", "Line Capture Switch", "Line Mixer"},
- {"ALC Mixer", "Mic2 Capture Switch", "Mic 2 Volume"},
- {"ALC Mixer", "Mic1 Capture Switch", "Mic 1 Volume"},
- {"ALC Mixer", "Rx Capture Switch", "Rx Mixer"},
-
- /* Line Left Mux */
- {"Line Left Mux", "Line 1", "LINE1"},
- {"Line Left Mux", "Rx Mix", "Rx Mixer"},
-
- /* Line Right Mux */
- {"Line Right Mux", "Line 2", "LINE2"},
- {"Line Right Mux", "Rx Mix", "Rx Mixer"},
-
- /* Line Mono Mux */
- {"Line Mono Mux", "Line Mix", "Line Mixer"},
- {"Line Mono Mux", "Rx Mix", "Rx Mixer"},
-
- /* Line Mixer/Mux */
- {"Line Mixer", "Line 1 + 2", "LINE1"},
- {"Line Mixer", "Line 1 - 2", "LINE1"},
- {"Line Mixer", "Line 1 + 2", "LINE2"},
- {"Line Mixer", "Line 1 - 2", "LINE2"},
- {"Line Mixer", "Line 1", "LINE1"},
- {"Line Mixer", "Line 2", "LINE2"},
-
- /* Rx Mixer/Mux */
- {"Rx Mixer", "RXP - RXN", "RXP"},
- {"Rx Mixer", "RXP + RXN", "RXP"},
- {"Rx Mixer", "RXP - RXN", "RXN"},
- {"Rx Mixer", "RXP + RXN", "RXN"},
- {"Rx Mixer", "RXP", "RXP"},
- {"Rx Mixer", "RXN", "RXN"},
-
- /* Mic 1 Volume */
- {"Mic 1 Volume", NULL, "MIC1N"},
- {"Mic 1 Volume", NULL, "Mic Selection Mux"},
-
- /* Mic 2 Volume */
- {"Mic 2 Volume", NULL, "MIC2N"},
- {"Mic 2 Volume", NULL, "MIC2"},
-
- /* Mic Selector Mux */
- {"Mic Selection Mux", "Mic 1", "MIC1"},
- {"Mic Selection Mux", "Mic 2", "MIC2N"},
- {"Mic Selection Mux", "Mic 3", "MIC2"},
-
- /* ACOP */
- {"ACOP", NULL, "ALC Mixer"},
-};
-
-/* PLL divisors */
-struct _pll_div {
- u32 div2:1;
- u32 n:4;
- u32 k:24;
-};
-
-/* The size in bits of the pll divide multiplied by 10
- * to allow rounding later */
-#define FIXED_PLL_SIZE ((1 << 22) * 10)
-
-static void pll_factors(struct _pll_div *pll_div, unsigned int target,
- unsigned int source)
-{
- u64 Kpart;
- unsigned int K, Ndiv, Nmod;
-
- Ndiv = target / source;
- if (Ndiv < 6) {
- source >>= 1;
- pll_div->div2 = 1;
- Ndiv = target / source;
- } else
- pll_div->div2 = 0;
-
- if ((Ndiv < 6) || (Ndiv > 12))
- printk(KERN_WARNING
- "wm8753: unsupported N = %u\n", Ndiv);
-
- pll_div->n = Ndiv;
- Nmod = target % source;
- Kpart = FIXED_PLL_SIZE * (long long)Nmod;
-
- do_div(Kpart, source);
-
- K = Kpart & 0xFFFFFFFF;
-
- /* Check if we need to round */
- if ((K % 10) >= 5)
- K += 5;
-
- /* Move down to proper range now rounding is done */
- K /= 10;
-
- pll_div->k = K;
-}
-
-static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
- int source, unsigned int freq_in, unsigned int freq_out)
-{
- u16 reg, enable;
- int offset;
- struct snd_soc_codec *codec = codec_dai->codec;
-
- if (pll_id < WM8753_PLL1 || pll_id > WM8753_PLL2)
- return -ENODEV;
-
- if (pll_id == WM8753_PLL1) {
- offset = 0;
- enable = 0x10;
- reg = snd_soc_read(codec, WM8753_CLOCK) & 0xffef;
- } else {
- offset = 4;
- enable = 0x8;
- reg = snd_soc_read(codec, WM8753_CLOCK) & 0xfff7;
- }
-
- if (!freq_in || !freq_out) {
- /* disable PLL */
- snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0026);
- snd_soc_write(codec, WM8753_CLOCK, reg);
- return 0;
- } else {
- u16 value = 0;
- struct _pll_div pll_div;
-
- pll_factors(&pll_div, freq_out * 8, freq_in);
-
- /* set up N and K PLL divisor ratios */
- /* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */
- value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18);
- snd_soc_write(codec, WM8753_PLL1CTL2 + offset, value);
-
- /* bits 8:0 = PLL_K[17:9] */
- value = (pll_div.k & 0x03fe00) >> 9;
- snd_soc_write(codec, WM8753_PLL1CTL3 + offset, value);
-
- /* bits 8:0 = PLL_K[8:0] */
- value = pll_div.k & 0x0001ff;
- snd_soc_write(codec, WM8753_PLL1CTL4 + offset, value);
-
- /* set PLL as input and enable */
- snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 |
- (pll_div.div2 << 3));
- snd_soc_write(codec, WM8753_CLOCK, reg | enable);
- }
- return 0;
-}
-
-struct _coeff_div {
- u32 mclk;
- u32 rate;
- u8 sr:5;
- u8 usb:1;
-};
-
-/* codec hifi mclk (after PLL) clock divider coefficients */
-static const struct _coeff_div coeff_div[] = {
- /* 8k */
- {12288000, 8000, 0x6, 0x0},
- {11289600, 8000, 0x16, 0x0},
- {18432000, 8000, 0x7, 0x0},
- {16934400, 8000, 0x17, 0x0},
- {12000000, 8000, 0x6, 0x1},
-
- /* 11.025k */
- {11289600, 11025, 0x18, 0x0},
- {16934400, 11025, 0x19, 0x0},
- {12000000, 11025, 0x19, 0x1},
-
- /* 16k */
- {12288000, 16000, 0xa, 0x0},
- {18432000, 16000, 0xb, 0x0},
- {12000000, 16000, 0xa, 0x1},
-
- /* 22.05k */
- {11289600, 22050, 0x1a, 0x0},
- {16934400, 22050, 0x1b, 0x0},
- {12000000, 22050, 0x1b, 0x1},
-
- /* 32k */
- {12288000, 32000, 0xc, 0x0},
- {18432000, 32000, 0xd, 0x0},
- {12000000, 32000, 0xa, 0x1},
-
- /* 44.1k */
- {11289600, 44100, 0x10, 0x0},
- {16934400, 44100, 0x11, 0x0},
- {12000000, 44100, 0x11, 0x1},
-
- /* 48k */
- {12288000, 48000, 0x0, 0x0},
- {18432000, 48000, 0x1, 0x0},
- {12000000, 48000, 0x0, 0x1},
-
- /* 88.2k */
- {11289600, 88200, 0x1e, 0x0},
- {16934400, 88200, 0x1f, 0x0},
- {12000000, 88200, 0x1f, 0x1},
-
- /* 96k */
- {12288000, 96000, 0xe, 0x0},
- {18432000, 96000, 0xf, 0x0},
- {12000000, 96000, 0xe, 0x1},
-};
-
-static int get_coeff(int mclk, int rate)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
- if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
- return i;
- }
- return -EINVAL;
-}
-
-/*
- * Clock after PLL and dividers
- */
-static int wm8753_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
-
- switch (freq) {
- case 11289600:
- case 12000000:
- case 12288000:
- case 16934400:
- case 18432000:
- if (clk_id == WM8753_MCLK) {
- wm8753->sysclk = freq;
- return 0;
- } else if (clk_id == WM8753_PCMCLK) {
- wm8753->pcmclk = freq;
- return 0;
- }
- break;
- }
- return -EINVAL;
-}
-
-/*
- * Set's ADC and Voice DAC format.
- */
-static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_codec *codec,
- unsigned int fmt)
-{
- u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01ec;
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- voice |= 0x0002;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- voice |= 0x0001;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- voice |= 0x0003;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- voice |= 0x0013;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM8753_PCM, voice);
- return 0;
-}
-
-/*
- * Set PCM DAI bit size and sample rate.
- */
-static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
- u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01f3;
- u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x017f;
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- voice |= 0x0004;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- voice |= 0x0008;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- voice |= 0x000c;
- break;
- }
-
- /* sample rate */
- if (params_rate(params) * 384 == wm8753->pcmclk)
- srate |= 0x80;
- snd_soc_write(codec, WM8753_SRATE1, srate);
-
- snd_soc_write(codec, WM8753_PCM, voice);
- return 0;
-}
-
-/*
- * Set's PCM dai fmt and BCLK.
- */
-static int wm8753_pcm_set_dai_fmt(struct snd_soc_codec *codec,
- unsigned int fmt)
-{
- u16 voice, ioctl;
-
- voice = snd_soc_read(codec, WM8753_PCM) & 0x011f;
- ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x015d;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- ioctl |= 0x2;
- case SND_SOC_DAIFMT_CBM_CFS:
- voice |= 0x0040;
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- case SND_SOC_DAIFMT_DSP_B:
- /* frame inversion not valid for DSP modes */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_NF:
- voice |= 0x0080;
- break;
- default:
- return -EINVAL;
- }
- break;
- case SND_SOC_DAIFMT_I2S:
- case SND_SOC_DAIFMT_RIGHT_J:
- case SND_SOC_DAIFMT_LEFT_J:
- voice &= ~0x0010;
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- voice |= 0x0090;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- voice |= 0x0080;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- voice |= 0x0010;
- break;
- default:
- return -EINVAL;
- }
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM8753_PCM, voice);
- snd_soc_write(codec, WM8753_IOCTL, ioctl);
- return 0;
-}
-
-static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
- int div_id, int div)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 reg;
-
- switch (div_id) {
- case WM8753_PCMDIV:
- reg = snd_soc_read(codec, WM8753_CLOCK) & 0x003f;
- snd_soc_write(codec, WM8753_CLOCK, reg | div);
- break;
- case WM8753_BCLKDIV:
- reg = snd_soc_read(codec, WM8753_SRATE2) & 0x01c7;
- snd_soc_write(codec, WM8753_SRATE2, reg | div);
- break;
- case WM8753_VXCLKDIV:
- reg = snd_soc_read(codec, WM8753_SRATE2) & 0x003f;
- snd_soc_write(codec, WM8753_SRATE2, reg | div);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-/*
- * Set's HiFi DAC format.
- */
-static int wm8753_hdac_set_dai_fmt(struct snd_soc_codec *codec,
- unsigned int fmt)
-{
- u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01e0;
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- hifi |= 0x0002;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- hifi |= 0x0001;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- hifi |= 0x0003;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- hifi |= 0x0013;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM8753_HIFI, hifi);
- return 0;
-}
-
-/*
- * Set's I2S DAI format.
- */
-static int wm8753_i2s_set_dai_fmt(struct snd_soc_codec *codec,
- unsigned int fmt)
-{
- u16 ioctl, hifi;
-
- hifi = snd_soc_read(codec, WM8753_HIFI) & 0x011f;
- ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x00ae;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- ioctl |= 0x1;
- case SND_SOC_DAIFMT_CBM_CFS:
- hifi |= 0x0040;
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- case SND_SOC_DAIFMT_DSP_B:
- /* frame inversion not valid for DSP modes */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_NF:
- hifi |= 0x0080;
- break;
- default:
- return -EINVAL;
- }
- break;
- case SND_SOC_DAIFMT_I2S:
- case SND_SOC_DAIFMT_RIGHT_J:
- case SND_SOC_DAIFMT_LEFT_J:
- hifi &= ~0x0010;
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- hifi |= 0x0090;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- hifi |= 0x0080;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- hifi |= 0x0010;
- break;
- default:
- return -EINVAL;
- }
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM8753_HIFI, hifi);
- snd_soc_write(codec, WM8753_IOCTL, ioctl);
- return 0;
-}
-
-/*
- * Set PCM DAI bit size and sample rate.
- */
-static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
- u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x01c0;
- u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01f3;
- int coeff;
-
- /* is digital filter coefficient valid ? */
- coeff = get_coeff(wm8753->sysclk, params_rate(params));
- if (coeff < 0) {
- printk(KERN_ERR "wm8753 invalid MCLK or rate\n");
- return coeff;
- }
- snd_soc_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
- coeff_div[coeff].usb);
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- hifi |= 0x0004;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- hifi |= 0x0008;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- hifi |= 0x000c;
- break;
- }
-
- snd_soc_write(codec, WM8753_HIFI, hifi);
- return 0;
-}
-
-static int wm8753_mode1v_set_dai_fmt(struct snd_soc_codec *codec,
- unsigned int fmt)
-{
- u16 clock;
-
- /* set clk source as pcmclk */
- clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
- snd_soc_write(codec, WM8753_CLOCK, clock);
-
- return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
-}
-
-static int wm8753_mode1h_set_dai_fmt(struct snd_soc_codec *codec,
- unsigned int fmt)
-{
- return wm8753_hdac_set_dai_fmt(codec, fmt);
-}
-
-static int wm8753_mode2_set_dai_fmt(struct snd_soc_codec *codec,
- unsigned int fmt)
-{
- u16 clock;
-
- /* set clk source as pcmclk */
- clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
- snd_soc_write(codec, WM8753_CLOCK, clock);
-
- return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
-}
-
-static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_codec *codec,
- unsigned int fmt)
-{
- u16 clock;
-
- /* set clk source as mclk */
- clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
- snd_soc_write(codec, WM8753_CLOCK, clock | 0x4);
-
- if (wm8753_hdac_set_dai_fmt(codec, fmt) < 0)
- return -EINVAL;
- return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
-}
-
-static int wm8753_hifi_write_dai_fmt(struct snd_soc_codec *codec,
- unsigned int fmt)
-{
- struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
- int ret = 0;
-
- switch (wm8753->dai_func) {
- case 0:
- ret = wm8753_mode1h_set_dai_fmt(codec, fmt);
- break;
- case 1:
- ret = wm8753_mode2_set_dai_fmt(codec, fmt);
- break;
- case 2:
- case 3:
- ret = wm8753_mode3_4_set_dai_fmt(codec, fmt);
- break;
- default:
- break;
- }
- if (ret)
- return ret;
-
- return wm8753_i2s_set_dai_fmt(codec, fmt);
-}
-
-static int wm8753_hifi_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
-
- wm8753->hifi_fmt = fmt;
-
- return wm8753_hifi_write_dai_fmt(codec, fmt);
-};
-
-static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec,
- unsigned int fmt)
-{
- struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
- int ret = 0;
-
- if (wm8753->dai_func != 0)
- return 0;
-
- ret = wm8753_mode1v_set_dai_fmt(codec, fmt);
- if (ret)
- return ret;
- ret = wm8753_pcm_set_dai_fmt(codec, fmt);
- if (ret)
- return ret;
-
- return 0;
-};
-
-static int wm8753_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
-
- wm8753->voice_fmt = fmt;
-
- return wm8753_voice_write_dai_fmt(codec, fmt);
-};
-
-static int wm8753_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 mute_reg = snd_soc_read(codec, WM8753_DAC) & 0xfff7;
- struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
-
- /* the digital mute covers the HiFi and Voice DAC's on the WM8753.
- * make sure we check if they are not both active when we mute */
- if (mute && wm8753->dai_func == 1) {
- if (!codec->active)
- snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
- } else {
- if (mute)
- snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
- else
- snd_soc_write(codec, WM8753_DAC, mute_reg);
- }
-
- return 0;
-}
-
-static int wm8753_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- /* set vmid to 50k and unmute dac */
- snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
- break;
- case SND_SOC_BIAS_PREPARE:
- /* set vmid to 5k for quick power up */
- snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
- break;
- case SND_SOC_BIAS_STANDBY:
- /* mute dac and set vmid to 500k, enable VREF */
- snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
- break;
- case SND_SOC_BIAS_OFF:
- snd_soc_write(codec, WM8753_PWR1, 0x0001);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define WM8753_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
- SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
-
-#define WM8753_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE)
-
-/*
- * The WM8753 supports up to 4 different and mutually exclusive DAI
- * configurations. This gives 2 PCM's available for use, hifi and voice.
- * NOTE: The Voice PCM cannot play or capture audio to the CPU as it's DAI
- * is connected between the wm8753 and a BT codec or GSM modem.
- *
- * 1. Voice over PCM DAI - HIFI DAC over HIFI DAI
- * 2. Voice over HIFI DAI - HIFI disabled
- * 3. Voice disabled - HIFI over HIFI
- * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture
- */
-static const struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode = {
- .hw_params = wm8753_i2s_hw_params,
- .digital_mute = wm8753_mute,
- .set_fmt = wm8753_hifi_set_dai_fmt,
- .set_clkdiv = wm8753_set_dai_clkdiv,
- .set_pll = wm8753_set_dai_pll,
- .set_sysclk = wm8753_set_dai_sysclk,
-};
-
-static const struct snd_soc_dai_ops wm8753_dai_ops_voice_mode = {
- .hw_params = wm8753_pcm_hw_params,
- .digital_mute = wm8753_mute,
- .set_fmt = wm8753_voice_set_dai_fmt,
- .set_clkdiv = wm8753_set_dai_clkdiv,
- .set_pll = wm8753_set_dai_pll,
- .set_sysclk = wm8753_set_dai_sysclk,
-};
-
-static struct snd_soc_dai_driver wm8753_dai[] = {
-/* DAI HiFi mode 1 */
-{ .name = "wm8753-hifi",
- .playback = {
- .stream_name = "HiFi Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8753_RATES,
- .formats = WM8753_FORMATS
- },
- .capture = { /* dummy for fast DAI switching */
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8753_RATES,
- .formats = WM8753_FORMATS
- },
- .ops = &wm8753_dai_ops_hifi_mode,
-},
-/* DAI Voice mode 1 */
-{ .name = "wm8753-voice",
- .playback = {
- .stream_name = "Voice Playback",
- .channels_min = 1,
- .channels_max = 1,
- .rates = WM8753_RATES,
- .formats = WM8753_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8753_RATES,
- .formats = WM8753_FORMATS,
- },
- .ops = &wm8753_dai_ops_voice_mode,
-},
-};
-
-static void wm8753_work(struct work_struct *work)
-{
- struct snd_soc_dapm_context *dapm =
- container_of(work, struct snd_soc_dapm_context,
- delayed_work.work);
- struct snd_soc_codec *codec = dapm->codec;
- wm8753_set_bias_level(codec, dapm->bias_level);
-}
-
-static int wm8753_suspend(struct snd_soc_codec *codec)
-{
- wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
- codec->cache_sync = 1;
- return 0;
-}
-
-static int wm8753_resume(struct snd_soc_codec *codec)
-{
- struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
-
- regcache_sync(wm8753->regmap);
-
- wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* charge wm8753 caps */
- if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
- wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
- codec->dapm.bias_level = SND_SOC_BIAS_ON;
- schedule_delayed_work(&codec->dapm.delayed_work,
- msecs_to_jiffies(caps_charge));
- }
-
- return 0;
-}
-
-static int wm8753_probe(struct snd_soc_codec *codec)
-{
- struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work);
-
- codec->control_data = wm8753->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- ret = wm8753_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
- return ret;
- }
-
- wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- wm8753->dai_func = 0;
-
- /* charge output caps */
- wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
- schedule_delayed_work(&codec->dapm.delayed_work,
- msecs_to_jiffies(caps_charge));
-
- /* set the update bits */
- snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8753_LADC, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8753_RADC, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8753_LOUT1V, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8753_ROUT1V, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8753_LOUT2V, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8753_ROUT2V, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8753_LINVOL, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8753_RINVOL, 0x0100, 0x0100);
-
- return 0;
-}
-
-/* power down chip */
-static int wm8753_remove(struct snd_soc_codec *codec)
-{
- flush_delayed_work_sync(&codec->dapm.delayed_work);
- wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
- .probe = wm8753_probe,
- .remove = wm8753_remove,
- .suspend = wm8753_suspend,
- .resume = wm8753_resume,
- .set_bias_level = wm8753_set_bias_level,
-
- .controls = wm8753_snd_controls,
- .num_controls = ARRAY_SIZE(wm8753_snd_controls),
- .dapm_widgets = wm8753_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8753_dapm_widgets),
- .dapm_routes = wm8753_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm8753_dapm_routes),
-};
-
-static const struct of_device_id wm8753_of_match[] = {
- { .compatible = "wlf,wm8753", },
- { }
-};
-MODULE_DEVICE_TABLE(of, wm8753_of_match);
-
-static const struct regmap_config wm8753_regmap = {
- .reg_bits = 7,
- .val_bits = 9,
-
- .max_register = WM8753_ADCTL2,
- .writeable_reg = wm8753_writeable,
- .volatile_reg = wm8753_volatile,
-
- .cache_type = REGCACHE_RBTREE,
- .reg_defaults = wm8753_reg_defaults,
- .num_reg_defaults = ARRAY_SIZE(wm8753_reg_defaults),
-};
-
-#if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8753_spi_probe(struct spi_device *spi)
-{
- struct wm8753_priv *wm8753;
- int ret;
-
- wm8753 = devm_kzalloc(&spi->dev, sizeof(struct wm8753_priv),
- GFP_KERNEL);
- if (wm8753 == NULL)
- return -ENOMEM;
-
- spi_set_drvdata(spi, wm8753);
-
- wm8753->regmap = regmap_init_spi(spi, &wm8753_regmap);
- if (IS_ERR(wm8753->regmap)) {
- ret = PTR_ERR(wm8753->regmap);
- dev_err(&spi->dev, "Failed to allocate register map: %d\n",
- ret);
- goto err;
- }
-
- ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8753,
- wm8753_dai, ARRAY_SIZE(wm8753_dai));
- if (ret != 0) {
- dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret);
- goto err_regmap;
- }
-
- return 0;
-
-err_regmap:
- regmap_exit(wm8753->regmap);
-err:
- return ret;
-}
-
-static int __devexit wm8753_spi_remove(struct spi_device *spi)
-{
- struct wm8753_priv *wm8753 = spi_get_drvdata(spi);
-
- snd_soc_unregister_codec(&spi->dev);
- regmap_exit(wm8753->regmap);
- kfree(wm8753);
- return 0;
-}
-
-static struct spi_driver wm8753_spi_driver = {
- .driver = {
- .name = "wm8753",
- .owner = THIS_MODULE,
- .of_match_table = wm8753_of_match,
- },
- .probe = wm8753_spi_probe,
- .remove = __devexit_p(wm8753_spi_remove),
-};
-#endif /* CONFIG_SPI_MASTER */
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8753_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8753_priv *wm8753;
- int ret;
-
- wm8753 = devm_kzalloc(&i2c->dev, sizeof(struct wm8753_priv),
- GFP_KERNEL);
- if (wm8753 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm8753);
-
- wm8753->regmap = regmap_init_i2c(i2c, &wm8753_regmap);
- if (IS_ERR(wm8753->regmap)) {
- ret = PTR_ERR(wm8753->regmap);
- dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
- ret);
- goto err;
- }
-
- ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8753,
- wm8753_dai, ARRAY_SIZE(wm8753_dai));
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
- goto err_regmap;
- }
-
- return 0;
-
-err_regmap:
- regmap_exit(wm8753->regmap);
-err:
- return ret;
-}
-
-static __devexit int wm8753_i2c_remove(struct i2c_client *client)
-{
- struct wm8753_priv *wm8753 = i2c_get_clientdata(client);
-
- snd_soc_unregister_codec(&client->dev);
- regmap_exit(wm8753->regmap);
- return 0;
-}
-
-static const struct i2c_device_id wm8753_i2c_id[] = {
- { "wm8753", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id);
-
-static struct i2c_driver wm8753_i2c_driver = {
- .driver = {
- .name = "wm8753",
- .owner = THIS_MODULE,
- .of_match_table = wm8753_of_match,
- },
- .probe = wm8753_i2c_probe,
- .remove = __devexit_p(wm8753_i2c_remove),
- .id_table = wm8753_i2c_id,
-};
-#endif
-
-static int __init wm8753_modinit(void)
-{
- int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&wm8753_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8753 I2C driver: %d\n",
- ret);
- }
-#endif
-#if defined(CONFIG_SPI_MASTER)
- ret = spi_register_driver(&wm8753_spi_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8753 SPI driver: %d\n",
- ret);
- }
-#endif
- return ret;
-}
-module_init(wm8753_modinit);
-
-static void __exit wm8753_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&wm8753_i2c_driver);
-#endif
-#if defined(CONFIG_SPI_MASTER)
- spi_unregister_driver(&wm8753_spi_driver);
-#endif
-}
-module_exit(wm8753_exit);
-
-MODULE_DESCRIPTION("ASoC WM8753 driver");
-MODULE_AUTHOR("Liam Girdwood");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8753.h b/ANDROID_3.4.5/sound/soc/codecs/wm8753.h
deleted file mode 100644
index 94edac14..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8753.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * wm8753.h -- audio driver for WM8753
- *
- * Copyright 2003 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood <lrg@slimlogic.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#ifndef _WM8753_H
-#define _WM8753_H
-
-/* WM8753 register space */
-
-#define WM8753_DAC 0x01
-#define WM8753_ADC 0x02
-#define WM8753_PCM 0x03
-#define WM8753_HIFI 0x04
-#define WM8753_IOCTL 0x05
-#define WM8753_SRATE1 0x06
-#define WM8753_SRATE2 0x07
-#define WM8753_LDAC 0x08
-#define WM8753_RDAC 0x09
-#define WM8753_BASS 0x0a
-#define WM8753_TREBLE 0x0b
-#define WM8753_ALC1 0x0c
-#define WM8753_ALC2 0x0d
-#define WM8753_ALC3 0x0e
-#define WM8753_NGATE 0x0f
-#define WM8753_LADC 0x10
-#define WM8753_RADC 0x11
-#define WM8753_ADCTL1 0x12
-#define WM8753_3D 0x13
-#define WM8753_PWR1 0x14
-#define WM8753_PWR2 0x15
-#define WM8753_PWR3 0x16
-#define WM8753_PWR4 0x17
-#define WM8753_ID 0x18
-#define WM8753_INTPOL 0x19
-#define WM8753_INTEN 0x1a
-#define WM8753_GPIO1 0x1b
-#define WM8753_GPIO2 0x1c
-#define WM8753_RESET 0x1f
-#define WM8753_RECMIX1 0x20
-#define WM8753_RECMIX2 0x21
-#define WM8753_LOUTM1 0x22
-#define WM8753_LOUTM2 0x23
-#define WM8753_ROUTM1 0x24
-#define WM8753_ROUTM2 0x25
-#define WM8753_MOUTM1 0x26
-#define WM8753_MOUTM2 0x27
-#define WM8753_LOUT1V 0x28
-#define WM8753_ROUT1V 0x29
-#define WM8753_LOUT2V 0x2a
-#define WM8753_ROUT2V 0x2b
-#define WM8753_MOUTV 0x2c
-#define WM8753_OUTCTL 0x2d
-#define WM8753_ADCIN 0x2e
-#define WM8753_INCTL1 0x2f
-#define WM8753_INCTL2 0x30
-#define WM8753_LINVOL 0x31
-#define WM8753_RINVOL 0x32
-#define WM8753_MICBIAS 0x33
-#define WM8753_CLOCK 0x34
-#define WM8753_PLL1CTL1 0x35
-#define WM8753_PLL1CTL2 0x36
-#define WM8753_PLL1CTL3 0x37
-#define WM8753_PLL1CTL4 0x38
-#define WM8753_PLL2CTL1 0x39
-#define WM8753_PLL2CTL2 0x3a
-#define WM8753_PLL2CTL3 0x3b
-#define WM8753_PLL2CTL4 0x3c
-#define WM8753_BIASCTL 0x3d
-#define WM8753_ADCTL2 0x3f
-
-#define WM8753_PLL1 0
-#define WM8753_PLL2 1
-
-/* clock inputs */
-#define WM8753_MCLK 0
-#define WM8753_PCMCLK 1
-
-/* clock divider id's */
-#define WM8753_PCMDIV 0
-#define WM8753_BCLKDIV 1
-#define WM8753_VXCLKDIV 2
-
-/* PCM clock dividers */
-#define WM8753_PCM_DIV_1 (0 << 6)
-#define WM8753_PCM_DIV_3 (2 << 6)
-#define WM8753_PCM_DIV_5_5 (3 << 6)
-#define WM8753_PCM_DIV_2 (4 << 6)
-#define WM8753_PCM_DIV_4 (5 << 6)
-#define WM8753_PCM_DIV_6 (6 << 6)
-#define WM8753_PCM_DIV_8 (7 << 6)
-
-/* BCLK clock dividers */
-#define WM8753_BCLK_DIV_1 (0 << 3)
-#define WM8753_BCLK_DIV_2 (1 << 3)
-#define WM8753_BCLK_DIV_4 (2 << 3)
-#define WM8753_BCLK_DIV_8 (3 << 3)
-#define WM8753_BCLK_DIV_16 (4 << 3)
-
-/* VXCLK clock dividers */
-#define WM8753_VXCLK_DIV_1 (0 << 6)
-#define WM8753_VXCLK_DIV_2 (1 << 6)
-#define WM8753_VXCLK_DIV_4 (2 << 6)
-#define WM8753_VXCLK_DIV_8 (3 << 6)
-#define WM8753_VXCLK_DIV_16 (4 << 6)
-
-#define WM8753_DAI_HIFI 0
-#define WM8753_DAI_VOICE 1
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8770.c b/ANDROID_3.4.5/sound/soc/codecs/wm8770.c
deleted file mode 100644
index a5127b4f..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8770.c
+++ /dev/null
@@ -1,748 +0,0 @@
-/*
- * wm8770.c -- WM8770 ALSA SoC Audio driver
- *
- * Copyright 2010 Wolfson Microelectronics plc
- *
- * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/of_device.h>
-#include <linux/pm.h>
-#include <linux/spi/spi.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "wm8770.h"
-
-#define WM8770_NUM_SUPPLIES 3
-static const char *wm8770_supply_names[WM8770_NUM_SUPPLIES] = {
- "AVDD1",
- "AVDD2",
- "DVDD"
-};
-
-static const u16 wm8770_reg_defs[WM8770_CACHEREGNUM] = {
- 0x7f, 0x7f, 0x7f, 0x7f,
- 0x7f, 0x7f, 0x7f, 0x7f,
- 0x7f, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0, 0x90, 0,
- 0, 0x22, 0x22, 0x3e,
- 0xc, 0xc, 0x100, 0x189,
- 0x189, 0x8770
-};
-
-struct wm8770_priv {
- enum snd_soc_control_type control_type;
- struct regulator_bulk_data supplies[WM8770_NUM_SUPPLIES];
- struct notifier_block disable_nb[WM8770_NUM_SUPPLIES];
- struct snd_soc_codec *codec;
- int sysclk;
-};
-
-static int vout12supply_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event);
-static int vout34supply_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event);
-
-/*
- * We can't use the same notifier block for more than one supply and
- * there's no way I can see to get from a callback to the caller
- * except container_of().
- */
-#define WM8770_REGULATOR_EVENT(n) \
-static int wm8770_regulator_event_##n(struct notifier_block *nb, \
- unsigned long event, void *data) \
-{ \
- struct wm8770_priv *wm8770 = container_of(nb, struct wm8770_priv, \
- disable_nb[n]); \
- if (event & REGULATOR_EVENT_DISABLE) { \
- wm8770->codec->cache_sync = 1; \
- } \
- return 0; \
-}
-
-WM8770_REGULATOR_EVENT(0)
-WM8770_REGULATOR_EVENT(1)
-WM8770_REGULATOR_EVENT(2)
-
-static const DECLARE_TLV_DB_SCALE(adc_tlv, -1200, 100, 0);
-static const DECLARE_TLV_DB_SCALE(dac_dig_tlv, -12750, 50, 1);
-static const DECLARE_TLV_DB_SCALE(dac_alg_tlv, -12700, 100, 1);
-
-static const char *dac_phase_text[][2] = {
- { "DAC1 Normal", "DAC1 Inverted" },
- { "DAC2 Normal", "DAC2 Inverted" },
- { "DAC3 Normal", "DAC3 Inverted" },
- { "DAC4 Normal", "DAC4 Inverted" },
-};
-
-static const struct soc_enum dac_phase[] = {
- SOC_ENUM_DOUBLE(WM8770_DACPHASE, 0, 1, 2, dac_phase_text[0]),
- SOC_ENUM_DOUBLE(WM8770_DACPHASE, 2, 3, 2, dac_phase_text[1]),
- SOC_ENUM_DOUBLE(WM8770_DACPHASE, 4, 5, 2, dac_phase_text[2]),
- SOC_ENUM_DOUBLE(WM8770_DACPHASE, 6, 7, 2, dac_phase_text[3]),
-};
-
-static const struct snd_kcontrol_new wm8770_snd_controls[] = {
- /* global DAC playback controls */
- SOC_SINGLE_TLV("DAC Playback Volume", WM8770_MSDIGVOL, 0, 255, 0,
- dac_dig_tlv),
- SOC_SINGLE("DAC Playback Switch", WM8770_DACMUTE, 4, 1, 1),
- SOC_SINGLE("DAC Playback ZC Switch", WM8770_DACCTRL1, 0, 1, 0),
-
- /* global VOUT playback controls */
- SOC_SINGLE_TLV("VOUT Playback Volume", WM8770_MSALGVOL, 0, 127, 0,
- dac_alg_tlv),
- SOC_SINGLE("VOUT Playback ZC Switch", WM8770_MSALGVOL, 7, 1, 0),
-
- /* VOUT1/2/3/4 specific controls */
- SOC_DOUBLE_R_TLV("VOUT1 Playback Volume", WM8770_VOUT1LVOL,
- WM8770_VOUT1RVOL, 0, 127, 0, dac_alg_tlv),
- SOC_DOUBLE_R("VOUT1 Playback ZC Switch", WM8770_VOUT1LVOL,
- WM8770_VOUT1RVOL, 7, 1, 0),
- SOC_DOUBLE_R_TLV("VOUT2 Playback Volume", WM8770_VOUT2LVOL,
- WM8770_VOUT2RVOL, 0, 127, 0, dac_alg_tlv),
- SOC_DOUBLE_R("VOUT2 Playback ZC Switch", WM8770_VOUT2LVOL,
- WM8770_VOUT2RVOL, 7, 1, 0),
- SOC_DOUBLE_R_TLV("VOUT3 Playback Volume", WM8770_VOUT3LVOL,
- WM8770_VOUT3RVOL, 0, 127, 0, dac_alg_tlv),
- SOC_DOUBLE_R("VOUT3 Playback ZC Switch", WM8770_VOUT3LVOL,
- WM8770_VOUT3RVOL, 7, 1, 0),
- SOC_DOUBLE_R_TLV("VOUT4 Playback Volume", WM8770_VOUT4LVOL,
- WM8770_VOUT4RVOL, 0, 127, 0, dac_alg_tlv),
- SOC_DOUBLE_R("VOUT4 Playback ZC Switch", WM8770_VOUT4LVOL,
- WM8770_VOUT4RVOL, 7, 1, 0),
-
- /* DAC1/2/3/4 specific controls */
- SOC_DOUBLE_R_TLV("DAC1 Playback Volume", WM8770_DAC1LVOL,
- WM8770_DAC1RVOL, 0, 255, 0, dac_dig_tlv),
- SOC_SINGLE("DAC1 Deemphasis Switch", WM8770_DACCTRL2, 0, 1, 0),
- SOC_ENUM("DAC1 Phase", dac_phase[0]),
- SOC_DOUBLE_R_TLV("DAC2 Playback Volume", WM8770_DAC2LVOL,
- WM8770_DAC2RVOL, 0, 255, 0, dac_dig_tlv),
- SOC_SINGLE("DAC2 Deemphasis Switch", WM8770_DACCTRL2, 1, 1, 0),
- SOC_ENUM("DAC2 Phase", dac_phase[1]),
- SOC_DOUBLE_R_TLV("DAC3 Playback Volume", WM8770_DAC3LVOL,
- WM8770_DAC3RVOL, 0, 255, 0, dac_dig_tlv),
- SOC_SINGLE("DAC3 Deemphasis Switch", WM8770_DACCTRL2, 2, 1, 0),
- SOC_ENUM("DAC3 Phase", dac_phase[2]),
- SOC_DOUBLE_R_TLV("DAC4 Playback Volume", WM8770_DAC4LVOL,
- WM8770_DAC4RVOL, 0, 255, 0, dac_dig_tlv),
- SOC_SINGLE("DAC4 Deemphasis Switch", WM8770_DACCTRL2, 3, 1, 0),
- SOC_ENUM("DAC4 Phase", dac_phase[3]),
-
- /* ADC specific controls */
- SOC_DOUBLE_R_TLV("Capture Volume", WM8770_ADCLCTRL, WM8770_ADCRCTRL,
- 0, 31, 0, adc_tlv),
- SOC_DOUBLE_R("Capture Switch", WM8770_ADCLCTRL, WM8770_ADCRCTRL,
- 5, 1, 1),
-
- /* other controls */
- SOC_SINGLE("ADC 128x Oversampling Switch", WM8770_MSTRCTRL, 3, 1, 0),
- SOC_SINGLE("ADC Highpass Filter Switch", WM8770_IFACECTRL, 8, 1, 1)
-};
-
-static const char *ain_text[] = {
- "AIN1", "AIN2", "AIN3", "AIN4",
- "AIN5", "AIN6", "AIN7", "AIN8"
-};
-
-static const struct soc_enum ain_enum =
- SOC_ENUM_DOUBLE(WM8770_ADCMUX, 0, 4, 8, ain_text);
-
-static const struct snd_kcontrol_new ain_mux =
- SOC_DAPM_ENUM("Capture Mux", ain_enum);
-
-static const struct snd_kcontrol_new vout1_mix_controls[] = {
- SOC_DAPM_SINGLE("DAC1 Switch", WM8770_OUTMUX1, 0, 1, 0),
- SOC_DAPM_SINGLE("AUX1 Switch", WM8770_OUTMUX1, 1, 1, 0),
- SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX1, 2, 1, 0)
-};
-
-static const struct snd_kcontrol_new vout2_mix_controls[] = {
- SOC_DAPM_SINGLE("DAC2 Switch", WM8770_OUTMUX1, 3, 1, 0),
- SOC_DAPM_SINGLE("AUX2 Switch", WM8770_OUTMUX1, 4, 1, 0),
- SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX1, 5, 1, 0)
-};
-
-static const struct snd_kcontrol_new vout3_mix_controls[] = {
- SOC_DAPM_SINGLE("DAC3 Switch", WM8770_OUTMUX2, 0, 1, 0),
- SOC_DAPM_SINGLE("AUX3 Switch", WM8770_OUTMUX2, 1, 1, 0),
- SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX2, 2, 1, 0)
-};
-
-static const struct snd_kcontrol_new vout4_mix_controls[] = {
- SOC_DAPM_SINGLE("DAC4 Switch", WM8770_OUTMUX2, 3, 1, 0),
- SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX2, 4, 1, 0)
-};
-
-static const struct snd_soc_dapm_widget wm8770_dapm_widgets[] = {
- SND_SOC_DAPM_INPUT("AUX1"),
- SND_SOC_DAPM_INPUT("AUX2"),
- SND_SOC_DAPM_INPUT("AUX3"),
-
- SND_SOC_DAPM_INPUT("AIN1"),
- SND_SOC_DAPM_INPUT("AIN2"),
- SND_SOC_DAPM_INPUT("AIN3"),
- SND_SOC_DAPM_INPUT("AIN4"),
- SND_SOC_DAPM_INPUT("AIN5"),
- SND_SOC_DAPM_INPUT("AIN6"),
- SND_SOC_DAPM_INPUT("AIN7"),
- SND_SOC_DAPM_INPUT("AIN8"),
-
- SND_SOC_DAPM_MUX("Capture Mux", WM8770_ADCMUX, 8, 1, &ain_mux),
-
- SND_SOC_DAPM_ADC("ADC", "Capture", WM8770_PWDNCTRL, 1, 1),
-
- SND_SOC_DAPM_DAC("DAC1", "Playback", WM8770_PWDNCTRL, 2, 1),
- SND_SOC_DAPM_DAC("DAC2", "Playback", WM8770_PWDNCTRL, 3, 1),
- SND_SOC_DAPM_DAC("DAC3", "Playback", WM8770_PWDNCTRL, 4, 1),
- SND_SOC_DAPM_DAC("DAC4", "Playback", WM8770_PWDNCTRL, 5, 1),
-
- SND_SOC_DAPM_SUPPLY("VOUT12 Supply", SND_SOC_NOPM, 0, 0,
- vout12supply_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_SUPPLY("VOUT34 Supply", SND_SOC_NOPM, 0, 0,
- vout34supply_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_MIXER("VOUT1 Mixer", SND_SOC_NOPM, 0, 0,
- vout1_mix_controls, ARRAY_SIZE(vout1_mix_controls)),
- SND_SOC_DAPM_MIXER("VOUT2 Mixer", SND_SOC_NOPM, 0, 0,
- vout2_mix_controls, ARRAY_SIZE(vout2_mix_controls)),
- SND_SOC_DAPM_MIXER("VOUT3 Mixer", SND_SOC_NOPM, 0, 0,
- vout3_mix_controls, ARRAY_SIZE(vout3_mix_controls)),
- SND_SOC_DAPM_MIXER("VOUT4 Mixer", SND_SOC_NOPM, 0, 0,
- vout4_mix_controls, ARRAY_SIZE(vout4_mix_controls)),
-
- SND_SOC_DAPM_OUTPUT("VOUT1"),
- SND_SOC_DAPM_OUTPUT("VOUT2"),
- SND_SOC_DAPM_OUTPUT("VOUT3"),
- SND_SOC_DAPM_OUTPUT("VOUT4")
-};
-
-static const struct snd_soc_dapm_route wm8770_intercon[] = {
- { "Capture Mux", "AIN1", "AIN1" },
- { "Capture Mux", "AIN2", "AIN2" },
- { "Capture Mux", "AIN3", "AIN3" },
- { "Capture Mux", "AIN4", "AIN4" },
- { "Capture Mux", "AIN5", "AIN5" },
- { "Capture Mux", "AIN6", "AIN6" },
- { "Capture Mux", "AIN7", "AIN7" },
- { "Capture Mux", "AIN8", "AIN8" },
-
- { "ADC", NULL, "Capture Mux" },
-
- { "VOUT1 Mixer", NULL, "VOUT12 Supply" },
- { "VOUT1 Mixer", "DAC1 Switch", "DAC1" },
- { "VOUT1 Mixer", "AUX1 Switch", "AUX1" },
- { "VOUT1 Mixer", "Bypass Switch", "Capture Mux" },
-
- { "VOUT2 Mixer", NULL, "VOUT12 Supply" },
- { "VOUT2 Mixer", "DAC2 Switch", "DAC2" },
- { "VOUT2 Mixer", "AUX2 Switch", "AUX2" },
- { "VOUT2 Mixer", "Bypass Switch", "Capture Mux" },
-
- { "VOUT3 Mixer", NULL, "VOUT34 Supply" },
- { "VOUT3 Mixer", "DAC3 Switch", "DAC3" },
- { "VOUT3 Mixer", "AUX3 Switch", "AUX3" },
- { "VOUT3 Mixer", "Bypass Switch", "Capture Mux" },
-
- { "VOUT4 Mixer", NULL, "VOUT34 Supply" },
- { "VOUT4 Mixer", "DAC4 Switch", "DAC4" },
- { "VOUT4 Mixer", "Bypass Switch", "Capture Mux" },
-
- { "VOUT1", NULL, "VOUT1 Mixer" },
- { "VOUT2", NULL, "VOUT2 Mixer" },
- { "VOUT3", NULL, "VOUT3 Mixer" },
- { "VOUT4", NULL, "VOUT4 Mixer" }
-};
-
-static int vout12supply_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec;
-
- codec = w->codec;
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- snd_soc_update_bits(codec, WM8770_OUTMUX1, 0x180, 0);
- break;
- case SND_SOC_DAPM_POST_PMD:
- snd_soc_update_bits(codec, WM8770_OUTMUX1, 0x180, 0x180);
- break;
- }
-
- return 0;
-}
-
-static int vout34supply_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec;
-
- codec = w->codec;
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- snd_soc_update_bits(codec, WM8770_OUTMUX2, 0x180, 0);
- break;
- case SND_SOC_DAPM_POST_PMD:
- snd_soc_update_bits(codec, WM8770_OUTMUX2, 0x180, 0x180);
- break;
- }
-
- return 0;
-}
-
-static int wm8770_reset(struct snd_soc_codec *codec)
-{
- return snd_soc_write(codec, WM8770_RESET, 0);
-}
-
-static int wm8770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec;
- int iface, master;
-
- codec = dai->codec;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- master = 0x100;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- master = 0;
- break;
- default:
- return -EINVAL;
- }
-
- iface = 0;
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= 0x2;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= 0x1;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= 0xc;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= 0x8;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- iface |= 0x4;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, WM8770_IFACECTRL, 0xf, iface);
- snd_soc_update_bits(codec, WM8770_MSTRCTRL, 0x100, master);
-
- return 0;
-}
-
-static const int mclk_ratios[] = {
- 128,
- 192,
- 256,
- 384,
- 512,
- 768
-};
-
-static int wm8770_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec;
- struct wm8770_priv *wm8770;
- int i;
- int iface;
- int shift;
- int ratio;
-
- codec = dai->codec;
- wm8770 = snd_soc_codec_get_drvdata(codec);
-
- iface = 0;
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= 0x10;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface |= 0x20;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- iface |= 0x30;
- break;
- }
-
- switch (substream->stream) {
- case SNDRV_PCM_STREAM_PLAYBACK:
- i = 0;
- shift = 4;
- break;
- case SNDRV_PCM_STREAM_CAPTURE:
- i = 2;
- shift = 0;
- break;
- default:
- return -EINVAL;
- }
-
- /* Only need to set MCLK/LRCLK ratio if we're master */
- if (snd_soc_read(codec, WM8770_MSTRCTRL) & 0x100) {
- for (; i < ARRAY_SIZE(mclk_ratios); ++i) {
- ratio = wm8770->sysclk / params_rate(params);
- if (ratio == mclk_ratios[i])
- break;
- }
-
- if (i == ARRAY_SIZE(mclk_ratios)) {
- dev_err(codec->dev,
- "Unable to configure MCLK ratio %d/%d\n",
- wm8770->sysclk, params_rate(params));
- return -EINVAL;
- }
-
- dev_dbg(codec->dev, "MCLK is %dfs\n", mclk_ratios[i]);
-
- snd_soc_update_bits(codec, WM8770_MSTRCTRL, 0x7 << shift,
- i << shift);
- }
-
- snd_soc_update_bits(codec, WM8770_IFACECTRL, 0x30, iface);
-
- return 0;
-}
-
-static int wm8770_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec;
-
- codec = dai->codec;
- return snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10,
- !!mute << 4);
-}
-
-static int wm8770_set_sysclk(struct snd_soc_dai *dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec;
- struct wm8770_priv *wm8770;
-
- codec = dai->codec;
- wm8770 = snd_soc_codec_get_drvdata(codec);
- wm8770->sysclk = freq;
- return 0;
-}
-
-static void wm8770_sync_cache(struct snd_soc_codec *codec)
-{
- int i;
- u16 *cache;
-
- if (!codec->cache_sync)
- return;
-
- codec->cache_only = 0;
- cache = codec->reg_cache;
- for (i = 0; i < codec->driver->reg_cache_size; i++) {
- if (i == WM8770_RESET || cache[i] == wm8770_reg_defs[i])
- continue;
- snd_soc_write(codec, i, cache[i]);
- }
- codec->cache_sync = 0;
-}
-
-static int wm8770_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- int ret;
- struct wm8770_priv *wm8770;
-
- wm8770 = snd_soc_codec_get_drvdata(codec);
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies),
- wm8770->supplies);
- if (ret) {
- dev_err(codec->dev,
- "Failed to enable supplies: %d\n",
- ret);
- return ret;
- }
- wm8770_sync_cache(codec);
- /* global powerup */
- snd_soc_write(codec, WM8770_PWDNCTRL, 0);
- }
- break;
- case SND_SOC_BIAS_OFF:
- /* global powerdown */
- snd_soc_write(codec, WM8770_PWDNCTRL, 1);
- regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies),
- wm8770->supplies);
- break;
- }
-
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define WM8770_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops wm8770_dai_ops = {
- .digital_mute = wm8770_mute,
- .hw_params = wm8770_hw_params,
- .set_fmt = wm8770_set_fmt,
- .set_sysclk = wm8770_set_sysclk,
-};
-
-static struct snd_soc_dai_driver wm8770_dai = {
- .name = "wm8770-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_192000,
- .formats = WM8770_FORMATS
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = WM8770_FORMATS
- },
- .ops = &wm8770_dai_ops,
- .symmetric_rates = 1
-};
-
-#ifdef CONFIG_PM
-static int wm8770_suspend(struct snd_soc_codec *codec)
-{
- wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm8770_resume(struct snd_soc_codec *codec)
-{
- wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-#else
-#define wm8770_suspend NULL
-#define wm8770_resume NULL
-#endif
-
-static int wm8770_probe(struct snd_soc_codec *codec)
-{
- struct wm8770_priv *wm8770;
- int ret;
- int i;
-
- wm8770 = snd_soc_codec_get_drvdata(codec);
- wm8770->codec = codec;
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8770->control_type);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++)
- wm8770->supplies[i].supply = wm8770_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8770->supplies),
- wm8770->supplies);
- if (ret) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- return ret;
- }
-
- wm8770->disable_nb[0].notifier_call = wm8770_regulator_event_0;
- wm8770->disable_nb[1].notifier_call = wm8770_regulator_event_1;
- wm8770->disable_nb[2].notifier_call = wm8770_regulator_event_2;
-
- /* This should really be moved into the regulator core */
- for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) {
- ret = regulator_register_notifier(wm8770->supplies[i].consumer,
- &wm8770->disable_nb[i]);
- if (ret) {
- dev_err(codec->dev,
- "Failed to register regulator notifier: %d\n",
- ret);
- }
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies),
- wm8770->supplies);
- if (ret) {
- dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
- goto err_reg_get;
- }
-
- ret = wm8770_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
- goto err_reg_enable;
- }
-
- wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* latch the volume update bits */
- snd_soc_update_bits(codec, WM8770_MSDIGVOL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8770_MSALGVOL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8770_VOUT1RVOL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8770_VOUT2RVOL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8770_VOUT3RVOL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8770_VOUT4RVOL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8770_DAC1RVOL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8770_DAC2RVOL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8770_DAC3RVOL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8770_DAC4RVOL, 0x100, 0x100);
-
- /* mute all DACs */
- snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10);
-
- snd_soc_add_codec_controls(codec, wm8770_snd_controls,
- ARRAY_SIZE(wm8770_snd_controls));
- snd_soc_dapm_new_controls(&codec->dapm, wm8770_dapm_widgets,
- ARRAY_SIZE(wm8770_dapm_widgets));
- snd_soc_dapm_add_routes(&codec->dapm, wm8770_intercon,
- ARRAY_SIZE(wm8770_intercon));
- return 0;
-
-err_reg_enable:
- regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies), wm8770->supplies);
-err_reg_get:
- regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies);
- return ret;
-}
-
-static int wm8770_remove(struct snd_soc_codec *codec)
-{
- struct wm8770_priv *wm8770;
- int i;
-
- wm8770 = snd_soc_codec_get_drvdata(codec);
- wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- for (i = 0; i < ARRAY_SIZE(wm8770->supplies); ++i)
- regulator_unregister_notifier(wm8770->supplies[i].consumer,
- &wm8770->disable_nb[i]);
- regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8770 = {
- .probe = wm8770_probe,
- .remove = wm8770_remove,
- .suspend = wm8770_suspend,
- .resume = wm8770_resume,
- .set_bias_level = wm8770_set_bias_level,
- .idle_bias_off = true,
- .reg_cache_size = ARRAY_SIZE(wm8770_reg_defs),
- .reg_word_size = sizeof (u16),
- .reg_cache_default = wm8770_reg_defs
-};
-
-static const struct of_device_id wm8770_of_match[] = {
- { .compatible = "wlf,wm8770", },
- { }
-};
-MODULE_DEVICE_TABLE(of, wm8770_of_match);
-
-static int __devinit wm8770_spi_probe(struct spi_device *spi)
-{
- struct wm8770_priv *wm8770;
- int ret;
-
- wm8770 = devm_kzalloc(&spi->dev, sizeof(struct wm8770_priv),
- GFP_KERNEL);
- if (!wm8770)
- return -ENOMEM;
-
- wm8770->control_type = SND_SOC_SPI;
- spi_set_drvdata(spi, wm8770);
-
- ret = snd_soc_register_codec(&spi->dev,
- &soc_codec_dev_wm8770, &wm8770_dai, 1);
-
- return ret;
-}
-
-static int __devexit wm8770_spi_remove(struct spi_device *spi)
-{
- snd_soc_unregister_codec(&spi->dev);
- return 0;
-}
-
-static struct spi_driver wm8770_spi_driver = {
- .driver = {
- .name = "wm8770",
- .owner = THIS_MODULE,
- .of_match_table = wm8770_of_match,
- },
- .probe = wm8770_spi_probe,
- .remove = __devexit_p(wm8770_spi_remove)
-};
-
-static int __init wm8770_modinit(void)
-{
- int ret = 0;
-
- ret = spi_register_driver(&wm8770_spi_driver);
- if (ret) {
- printk(KERN_ERR "Failed to register wm8770 SPI driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(wm8770_modinit);
-
-static void __exit wm8770_exit(void)
-{
- spi_unregister_driver(&wm8770_spi_driver);
-}
-module_exit(wm8770_exit);
-
-MODULE_DESCRIPTION("ASoC WM8770 driver");
-MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8770.h b/ANDROID_3.4.5/sound/soc/codecs/wm8770.h
deleted file mode 100644
index 5f1b3bda..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8770.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * wm8770.h -- WM8770 ASoC driver
- *
- * Copyright 2010 Wolfson Microelectronics plc
- *
- * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8770_H
-#define _WM8770_H
-
-/* Registers */
-#define WM8770_VOUT1LVOL 0
-#define WM8770_VOUT1RVOL 0x1
-#define WM8770_VOUT2LVOL 0x2
-#define WM8770_VOUT2RVOL 0x3
-#define WM8770_VOUT3LVOL 0x4
-#define WM8770_VOUT3RVOL 0x5
-#define WM8770_VOUT4LVOL 0x6
-#define WM8770_VOUT4RVOL 0x7
-#define WM8770_MSALGVOL 0x8
-#define WM8770_DAC1LVOL 0x9
-#define WM8770_DAC1RVOL 0xa
-#define WM8770_DAC2LVOL 0xb
-#define WM8770_DAC2RVOL 0xc
-#define WM8770_DAC3LVOL 0xd
-#define WM8770_DAC3RVOL 0xe
-#define WM8770_DAC4LVOL 0xf
-#define WM8770_DAC4RVOL 0x10
-#define WM8770_MSDIGVOL 0x11
-#define WM8770_DACPHASE 0x12
-#define WM8770_DACCTRL1 0x13
-#define WM8770_DACMUTE 0x14
-#define WM8770_DACCTRL2 0x15
-#define WM8770_IFACECTRL 0x16
-#define WM8770_MSTRCTRL 0x17
-#define WM8770_PWDNCTRL 0x18
-#define WM8770_ADCLCTRL 0x19
-#define WM8770_ADCRCTRL 0x1a
-#define WM8770_ADCMUX 0x1b
-#define WM8770_OUTMUX1 0x1c
-#define WM8770_OUTMUX2 0x1d
-#define WM8770_RESET 0x31
-
-#define WM8770_CACHEREGNUM 0x20
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8776.c b/ANDROID_3.4.5/sound/soc/codecs/wm8776.c
deleted file mode 100644
index a19db5a0..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8776.c
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
- * wm8776.c -- WM8776 ALSA SoC Audio driver
- *
- * Copyright 2009 Wolfson Microelectronics plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * TODO: Input ALC/limiter support
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/of_device.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "wm8776.h"
-
-enum wm8776_chip_type {
- WM8775 = 1,
- WM8776,
-};
-
-/* codec private data */
-struct wm8776_priv {
- enum snd_soc_control_type control_type;
- int sysclk[2];
-};
-
-static const u16 wm8776_reg[WM8776_CACHEREGNUM] = {
- 0x79, 0x79, 0x79, 0xff, 0xff, /* 4 */
- 0xff, 0x00, 0x90, 0x00, 0x00, /* 9 */
- 0x22, 0x22, 0x22, 0x08, 0xcf, /* 14 */
- 0xcf, 0x7b, 0x00, 0x32, 0x00, /* 19 */
- 0xa6, 0x01, 0x01
-};
-
-static int wm8776_reset(struct snd_soc_codec *codec)
-{
- return snd_soc_write(codec, WM8776_RESET, 0);
-}
-
-static const DECLARE_TLV_DB_SCALE(hp_tlv, -12100, 100, 1);
-static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
-static const DECLARE_TLV_DB_SCALE(adc_tlv, -10350, 50, 1);
-
-static const struct snd_kcontrol_new wm8776_snd_controls[] = {
-SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8776_HPLVOL, WM8776_HPRVOL,
- 0, 127, 0, hp_tlv),
-SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8776_DACLVOL, WM8776_DACRVOL,
- 0, 255, 0, dac_tlv),
-SOC_SINGLE("Digital Playback ZC Switch", WM8776_DACCTRL1, 0, 1, 0),
-
-SOC_SINGLE("Deemphasis Switch", WM8776_DACCTRL2, 0, 1, 0),
-
-SOC_DOUBLE_R_TLV("Capture Volume", WM8776_ADCLVOL, WM8776_ADCRVOL,
- 0, 255, 0, adc_tlv),
-SOC_DOUBLE("Capture Switch", WM8776_ADCMUX, 7, 6, 1, 1),
-SOC_DOUBLE_R("Capture ZC Switch", WM8776_ADCLVOL, WM8776_ADCRVOL, 8, 1, 0),
-SOC_SINGLE("Capture HPF Switch", WM8776_ADCIFCTRL, 8, 1, 1),
-};
-
-static const struct snd_kcontrol_new inmix_controls[] = {
-SOC_DAPM_SINGLE("AIN1 Switch", WM8776_ADCMUX, 0, 1, 0),
-SOC_DAPM_SINGLE("AIN2 Switch", WM8776_ADCMUX, 1, 1, 0),
-SOC_DAPM_SINGLE("AIN3 Switch", WM8776_ADCMUX, 2, 1, 0),
-SOC_DAPM_SINGLE("AIN4 Switch", WM8776_ADCMUX, 3, 1, 0),
-SOC_DAPM_SINGLE("AIN5 Switch", WM8776_ADCMUX, 4, 1, 0),
-};
-
-static const struct snd_kcontrol_new outmix_controls[] = {
-SOC_DAPM_SINGLE("DAC Switch", WM8776_OUTMUX, 0, 1, 0),
-SOC_DAPM_SINGLE("AUX Switch", WM8776_OUTMUX, 1, 1, 0),
-SOC_DAPM_SINGLE("Bypass Switch", WM8776_OUTMUX, 2, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget wm8776_dapm_widgets[] = {
-SND_SOC_DAPM_INPUT("AUX"),
-
-SND_SOC_DAPM_INPUT("AIN1"),
-SND_SOC_DAPM_INPUT("AIN2"),
-SND_SOC_DAPM_INPUT("AIN3"),
-SND_SOC_DAPM_INPUT("AIN4"),
-SND_SOC_DAPM_INPUT("AIN5"),
-
-SND_SOC_DAPM_MIXER("Input Mixer", WM8776_PWRDOWN, 6, 1,
- inmix_controls, ARRAY_SIZE(inmix_controls)),
-
-SND_SOC_DAPM_ADC("ADC", "Capture", WM8776_PWRDOWN, 1, 1),
-SND_SOC_DAPM_DAC("DAC", "Playback", WM8776_PWRDOWN, 2, 1),
-
-SND_SOC_DAPM_MIXER("Output Mixer", SND_SOC_NOPM, 0, 0,
- outmix_controls, ARRAY_SIZE(outmix_controls)),
-
-SND_SOC_DAPM_PGA("Headphone PGA", WM8776_PWRDOWN, 3, 1, NULL, 0),
-
-SND_SOC_DAPM_OUTPUT("VOUT"),
-
-SND_SOC_DAPM_OUTPUT("HPOUTL"),
-SND_SOC_DAPM_OUTPUT("HPOUTR"),
-};
-
-static const struct snd_soc_dapm_route routes[] = {
- { "Input Mixer", "AIN1 Switch", "AIN1" },
- { "Input Mixer", "AIN2 Switch", "AIN2" },
- { "Input Mixer", "AIN3 Switch", "AIN3" },
- { "Input Mixer", "AIN4 Switch", "AIN4" },
- { "Input Mixer", "AIN5 Switch", "AIN5" },
-
- { "ADC", NULL, "Input Mixer" },
-
- { "Output Mixer", "DAC Switch", "DAC" },
- { "Output Mixer", "AUX Switch", "AUX" },
- { "Output Mixer", "Bypass Switch", "Input Mixer" },
-
- { "VOUT", NULL, "Output Mixer" },
-
- { "Headphone PGA", NULL, "Output Mixer" },
-
- { "HPOUTL", NULL, "Headphone PGA" },
- { "HPOUTR", NULL, "Headphone PGA" },
-};
-
-static int wm8776_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = dai->codec;
- int reg, iface, master;
-
- switch (dai->driver->id) {
- case WM8776_DAI_DAC:
- reg = WM8776_DACIFCTRL;
- master = 0x80;
- break;
- case WM8776_DAI_ADC:
- reg = WM8776_ADCIFCTRL;
- master = 0x100;
- break;
- default:
- return -EINVAL;
- }
-
- iface = 0;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- master = 0;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= 0x0002;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= 0x0001;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= 0x00c;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= 0x008;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- iface |= 0x004;
- break;
- default:
- return -EINVAL;
- }
-
- /* Finally, write out the values */
- snd_soc_update_bits(codec, reg, 0xf, iface);
- snd_soc_update_bits(codec, WM8776_MSTRCTRL, 0x180, master);
-
- return 0;
-}
-
-static int mclk_ratios[] = {
- 128,
- 192,
- 256,
- 384,
- 512,
- 768,
-};
-
-static int wm8776_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
- int iface_reg, iface;
- int ratio_shift, master;
- int i;
-
- switch (dai->driver->id) {
- case WM8776_DAI_DAC:
- iface_reg = WM8776_DACIFCTRL;
- master = 0x80;
- ratio_shift = 4;
- break;
- case WM8776_DAI_ADC:
- iface_reg = WM8776_ADCIFCTRL;
- master = 0x100;
- ratio_shift = 0;
- break;
- default:
- return -EINVAL;
- }
-
- /* Set word length */
- switch (snd_pcm_format_width(params_format(params))) {
- case 16:
- iface = 0;
- break;
- case 20:
- iface = 0x10;
- break;
- case 24:
- iface = 0x20;
- break;
- case 32:
- iface = 0x30;
- break;
- default:
- dev_err(codec->dev, "Unsupported sample size: %i\n",
- snd_pcm_format_width(params_format(params)));
- return -EINVAL;
- }
-
- /* Only need to set MCLK/LRCLK ratio if we're master */
- if (snd_soc_read(codec, WM8776_MSTRCTRL) & master) {
- for (i = 0; i < ARRAY_SIZE(mclk_ratios); i++) {
- if (wm8776->sysclk[dai->driver->id] / params_rate(params)
- == mclk_ratios[i])
- break;
- }
-
- if (i == ARRAY_SIZE(mclk_ratios)) {
- dev_err(codec->dev,
- "Unable to configure MCLK ratio %d/%d\n",
- wm8776->sysclk[dai->driver->id], params_rate(params));
- return -EINVAL;
- }
-
- dev_dbg(codec->dev, "MCLK is %dfs\n", mclk_ratios[i]);
-
- snd_soc_update_bits(codec, WM8776_MSTRCTRL,
- 0x7 << ratio_shift, i << ratio_shift);
- } else {
- dev_dbg(codec->dev, "DAI in slave mode\n");
- }
-
- snd_soc_update_bits(codec, iface_reg, 0x30, iface);
-
- return 0;
-}
-
-static int wm8776_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
-
- return snd_soc_write(codec, WM8776_DACMUTE, !!mute);
-}
-
-static int wm8776_set_sysclk(struct snd_soc_dai *dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
-
- BUG_ON(dai->driver->id >= ARRAY_SIZE(wm8776->sysclk));
-
- wm8776->sysclk[dai->driver->id] = freq;
-
- return 0;
-}
-
-static int wm8776_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- snd_soc_cache_sync(codec);
-
- /* Disable the global powerdown; DAPM does the rest */
- snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0);
- }
-
- break;
- case SND_SOC_BIAS_OFF:
- snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 1);
- break;
- }
-
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define WM8776_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops wm8776_dac_ops = {
- .digital_mute = wm8776_mute,
- .hw_params = wm8776_hw_params,
- .set_fmt = wm8776_set_fmt,
- .set_sysclk = wm8776_set_sysclk,
-};
-
-static const struct snd_soc_dai_ops wm8776_adc_ops = {
- .hw_params = wm8776_hw_params,
- .set_fmt = wm8776_set_fmt,
- .set_sysclk = wm8776_set_sysclk,
-};
-
-static struct snd_soc_dai_driver wm8776_dai[] = {
- {
- .name = "wm8776-hifi-playback",
- .id = WM8776_DAI_DAC,
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 32000,
- .rate_max = 192000,
- .formats = WM8776_FORMATS,
- },
- .ops = &wm8776_dac_ops,
- },
- {
- .name = "wm8776-hifi-capture",
- .id = WM8776_DAI_ADC,
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 32000,
- .rate_max = 96000,
- .formats = WM8776_FORMATS,
- },
- .ops = &wm8776_adc_ops,
- },
-};
-
-#ifdef CONFIG_PM
-static int wm8776_suspend(struct snd_soc_codec *codec)
-{
- wm8776_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int wm8776_resume(struct snd_soc_codec *codec)
-{
- wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-#else
-#define wm8776_suspend NULL
-#define wm8776_resume NULL
-#endif
-
-static int wm8776_probe(struct snd_soc_codec *codec)
-{
- struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
- int ret = 0;
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8776->control_type);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- ret = wm8776_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
- return ret;
- }
-
- wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* Latch the update bits; right channel only since we always
- * update both. */
- snd_soc_update_bits(codec, WM8776_HPRVOL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8776_DACRVOL, 0x100, 0x100);
-
- return ret;
-}
-
-/* power down chip */
-static int wm8776_remove(struct snd_soc_codec *codec)
-{
- wm8776_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8776 = {
- .probe = wm8776_probe,
- .remove = wm8776_remove,
- .suspend = wm8776_suspend,
- .resume = wm8776_resume,
- .set_bias_level = wm8776_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8776_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8776_reg,
-
- .controls = wm8776_snd_controls,
- .num_controls = ARRAY_SIZE(wm8776_snd_controls),
- .dapm_widgets = wm8776_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8776_dapm_widgets),
- .dapm_routes = routes,
- .num_dapm_routes = ARRAY_SIZE(routes),
-};
-
-static const struct of_device_id wm8776_of_match[] = {
- { .compatible = "wlf,wm8776", },
- { }
-};
-MODULE_DEVICE_TABLE(of, wm8776_of_match);
-
-#if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8776_spi_probe(struct spi_device *spi)
-{
- struct wm8776_priv *wm8776;
- int ret;
-
- wm8776 = devm_kzalloc(&spi->dev, sizeof(struct wm8776_priv),
- GFP_KERNEL);
- if (wm8776 == NULL)
- return -ENOMEM;
-
- wm8776->control_type = SND_SOC_SPI;
- spi_set_drvdata(spi, wm8776);
-
- ret = snd_soc_register_codec(&spi->dev,
- &soc_codec_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai));
-
- return ret;
-}
-
-static int __devexit wm8776_spi_remove(struct spi_device *spi)
-{
- snd_soc_unregister_codec(&spi->dev);
- return 0;
-}
-
-static struct spi_driver wm8776_spi_driver = {
- .driver = {
- .name = "wm8776",
- .owner = THIS_MODULE,
- .of_match_table = wm8776_of_match,
- },
- .probe = wm8776_spi_probe,
- .remove = __devexit_p(wm8776_spi_remove),
-};
-#endif /* CONFIG_SPI_MASTER */
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8776_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8776_priv *wm8776;
- int ret;
-
- wm8776 = devm_kzalloc(&i2c->dev, sizeof(struct wm8776_priv),
- GFP_KERNEL);
- if (wm8776 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm8776);
- wm8776->control_type = SND_SOC_I2C;
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai));
-
- return ret;
-}
-
-static __devexit int wm8776_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static const struct i2c_device_id wm8776_i2c_id[] = {
- { "wm8775", WM8775 },
- { "wm8776", WM8776 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8776_i2c_id);
-
-static struct i2c_driver wm8776_i2c_driver = {
- .driver = {
- .name = "wm8776",
- .owner = THIS_MODULE,
- .of_match_table = wm8776_of_match,
- },
- .probe = wm8776_i2c_probe,
- .remove = __devexit_p(wm8776_i2c_remove),
- .id_table = wm8776_i2c_id,
-};
-#endif
-
-static int __init wm8776_modinit(void)
-{
- int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&wm8776_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8776 I2C driver: %d\n",
- ret);
- }
-#endif
-#if defined(CONFIG_SPI_MASTER)
- ret = spi_register_driver(&wm8776_spi_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8776 SPI driver: %d\n",
- ret);
- }
-#endif
- return ret;
-}
-module_init(wm8776_modinit);
-
-static void __exit wm8776_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&wm8776_i2c_driver);
-#endif
-#if defined(CONFIG_SPI_MASTER)
- spi_unregister_driver(&wm8776_spi_driver);
-#endif
-}
-module_exit(wm8776_exit);
-
-MODULE_DESCRIPTION("ASoC WM8776 driver");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8776.h b/ANDROID_3.4.5/sound/soc/codecs/wm8776.h
deleted file mode 100644
index 4cf1c8e0..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8776.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * wm8776.h -- WM8776 ASoC driver
- *
- * Copyright 2009 Wolfson Microelectronics plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8776_H
-#define _WM8776_H
-
-/* Registers */
-
-#define WM8776_HPLVOL 0x00
-#define WM8776_HPRVOL 0x01
-#define WM8776_HPMASTER 0x02
-#define WM8776_DACLVOL 0x03
-#define WM8776_DACRVOL 0x04
-#define WM8776_DACMASTER 0x05
-#define WM8776_PHASESWAP 0x06
-#define WM8776_DACCTRL1 0x07
-#define WM8776_DACMUTE 0x08
-#define WM8776_DACCTRL2 0x09
-#define WM8776_DACIFCTRL 0x0a
-#define WM8776_ADCIFCTRL 0x0b
-#define WM8776_MSTRCTRL 0x0c
-#define WM8776_PWRDOWN 0x0d
-#define WM8776_ADCLVOL 0x0e
-#define WM8776_ADCRVOL 0x0f
-#define WM8776_ALCCTRL1 0x10
-#define WM8776_ALCCTRL2 0x11
-#define WM8776_ALCCTRL3 0x12
-#define WM8776_NOISEGATE 0x13
-#define WM8776_LIMITER 0x14
-#define WM8776_ADCMUX 0x15
-#define WM8776_OUTMUX 0x16
-#define WM8776_RESET 0x17
-
-#define WM8776_CACHEREGNUM 0x17
-
-#define WM8776_DAI_DAC 0
-#define WM8776_DAI_ADC 1
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8782.c b/ANDROID_3.4.5/sound/soc/codecs/wm8782.c
deleted file mode 100644
index 3fdea98f..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8782.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * sound/soc/codecs/wm8782.c
- * simple, strap-pin configured 24bit 2ch ADC
- *
- * Copyright: 2011 Raumfeld GmbH
- * Author: Johannes Stezenbach <js@sig21.net>
- *
- * based on ad73311.c
- * Copyright: Analog Device Inc.
- * Author: Cliff Cai <cliff.cai@analog.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-static struct snd_soc_dai_driver wm8782_dai = {
- .name = "wm8782",
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 2,
- /* For configurations with FSAMPEN=0 */
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S20_3LE |
- SNDRV_PCM_FMTBIT_S24_LE,
- },
-};
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8782;
-
-static __devinit int wm8782_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev,
- &soc_codec_dev_wm8782, &wm8782_dai, 1);
-}
-
-static int __devexit wm8782_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver wm8782_codec_driver = {
- .driver = {
- .name = "wm8782",
- .owner = THIS_MODULE,
- },
- .probe = wm8782_probe,
- .remove = __devexit_p(wm8782_remove),
-};
-
-module_platform_driver(wm8782_codec_driver);
-
-MODULE_DESCRIPTION("ASoC WM8782 driver");
-MODULE_AUTHOR("Johannes Stezenbach <js@sig21.net>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8804.c b/ANDROID_3.4.5/sound/soc/codecs/wm8804.c
deleted file mode 100644
index 6bd1b767..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8804.c
+++ /dev/null
@@ -1,841 +0,0 @@
-/*
- * wm8804.c -- WM8804 S/PDIF transceiver driver
- *
- * Copyright 2010 Wolfson Microelectronics plc
- *
- * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/of_device.h>
-#include <linux/spi/spi.h>
-#include <linux/regmap.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "wm8804.h"
-
-#define WM8804_NUM_SUPPLIES 2
-static const char *wm8804_supply_names[WM8804_NUM_SUPPLIES] = {
- "PVDD",
- "DVDD"
-};
-
-static const struct reg_default wm8804_reg_defaults[] = {
- { 3, 0x21 }, /* R3 - PLL1 */
- { 4, 0xFD }, /* R4 - PLL2 */
- { 5, 0x36 }, /* R5 - PLL3 */
- { 6, 0x07 }, /* R6 - PLL4 */
- { 7, 0x16 }, /* R7 - PLL5 */
- { 8, 0x18 }, /* R8 - PLL6 */
- { 9, 0xFF }, /* R9 - SPDMODE */
- { 10, 0x00 }, /* R10 - INTMASK */
- { 18, 0x00 }, /* R18 - SPDTX1 */
- { 19, 0x00 }, /* R19 - SPDTX2 */
- { 20, 0x00 }, /* R20 - SPDTX3 */
- { 21, 0x71 }, /* R21 - SPDTX4 */
- { 22, 0x0B }, /* R22 - SPDTX5 */
- { 23, 0x70 }, /* R23 - GPO0 */
- { 24, 0x57 }, /* R24 - GPO1 */
- { 26, 0x42 }, /* R26 - GPO2 */
- { 27, 0x06 }, /* R27 - AIFTX */
- { 28, 0x06 }, /* R28 - AIFRX */
- { 29, 0x80 }, /* R29 - SPDRX1 */
- { 30, 0x07 }, /* R30 - PWRDN */
-};
-
-struct wm8804_priv {
- struct regmap *regmap;
- struct regulator_bulk_data supplies[WM8804_NUM_SUPPLIES];
- struct notifier_block disable_nb[WM8804_NUM_SUPPLIES];
-};
-
-static int txsrc_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-
-static int txsrc_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-
-/*
- * We can't use the same notifier block for more than one supply and
- * there's no way I can see to get from a callback to the caller
- * except container_of().
- */
-#define WM8804_REGULATOR_EVENT(n) \
-static int wm8804_regulator_event_##n(struct notifier_block *nb, \
- unsigned long event, void *data) \
-{ \
- struct wm8804_priv *wm8804 = container_of(nb, struct wm8804_priv, \
- disable_nb[n]); \
- if (event & REGULATOR_EVENT_DISABLE) { \
- regcache_mark_dirty(wm8804->regmap); \
- } \
- return 0; \
-}
-
-WM8804_REGULATOR_EVENT(0)
-WM8804_REGULATOR_EVENT(1)
-
-static const char *txsrc_text[] = { "S/PDIF RX", "AIF" };
-static const SOC_ENUM_SINGLE_EXT_DECL(txsrc, txsrc_text);
-
-static const struct snd_kcontrol_new wm8804_snd_controls[] = {
- SOC_ENUM_EXT("Input Source", txsrc, txsrc_get, txsrc_put),
- SOC_SINGLE("TX Playback Switch", WM8804_PWRDN, 2, 1, 1),
- SOC_SINGLE("AIF Playback Switch", WM8804_PWRDN, 4, 1, 1)
-};
-
-static int txsrc_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec;
- unsigned int src;
-
- codec = snd_kcontrol_chip(kcontrol);
- src = snd_soc_read(codec, WM8804_SPDTX4);
- if (src & 0x40)
- ucontrol->value.integer.value[0] = 1;
- else
- ucontrol->value.integer.value[0] = 0;
-
- return 0;
-}
-
-static int txsrc_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec;
- unsigned int src, txpwr;
-
- codec = snd_kcontrol_chip(kcontrol);
-
- if (ucontrol->value.integer.value[0] != 0
- && ucontrol->value.integer.value[0] != 1)
- return -EINVAL;
-
- src = snd_soc_read(codec, WM8804_SPDTX4);
- switch ((src & 0x40) >> 6) {
- case 0:
- if (!ucontrol->value.integer.value[0])
- return 0;
- break;
- case 1:
- if (ucontrol->value.integer.value[1])
- return 0;
- break;
- }
-
- /* save the current power state of the transmitter */
- txpwr = snd_soc_read(codec, WM8804_PWRDN) & 0x4;
- /* power down the transmitter */
- snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x4);
- /* set the tx source */
- snd_soc_update_bits(codec, WM8804_SPDTX4, 0x40,
- ucontrol->value.integer.value[0] << 6);
-
- if (ucontrol->value.integer.value[0]) {
- /* power down the receiver */
- snd_soc_update_bits(codec, WM8804_PWRDN, 0x2, 0x2);
- /* power up the AIF */
- snd_soc_update_bits(codec, WM8804_PWRDN, 0x10, 0);
- } else {
- /* don't power down the AIF -- may be used as an output */
- /* power up the receiver */
- snd_soc_update_bits(codec, WM8804_PWRDN, 0x2, 0);
- }
-
- /* restore the transmitter's configuration */
- snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, txpwr);
-
- return 0;
-}
-
-static bool wm8804_volatile(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM8804_RST_DEVID1:
- case WM8804_DEVID2:
- case WM8804_DEVREV:
- case WM8804_INTSTAT:
- case WM8804_SPDSTAT:
- case WM8804_RXCHAN1:
- case WM8804_RXCHAN2:
- case WM8804_RXCHAN3:
- case WM8804_RXCHAN4:
- case WM8804_RXCHAN5:
- return true;
- default:
- return false;
- }
-}
-
-static int wm8804_reset(struct snd_soc_codec *codec)
-{
- return snd_soc_write(codec, WM8804_RST_DEVID1, 0x0);
-}
-
-static int wm8804_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec;
- u16 format, master, bcp, lrp;
-
- codec = dai->codec;
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- format = 0x2;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- format = 0x0;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- format = 0x1;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- case SND_SOC_DAIFMT_DSP_B:
- format = 0x3;
- break;
- default:
- dev_err(dai->dev, "Unknown dai format\n");
- return -EINVAL;
- }
-
- /* set data format */
- snd_soc_update_bits(codec, WM8804_AIFTX, 0x3, format);
- snd_soc_update_bits(codec, WM8804_AIFRX, 0x3, format);
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- master = 1;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- master = 0;
- break;
- default:
- dev_err(dai->dev, "Unknown master/slave configuration\n");
- return -EINVAL;
- }
-
- /* set master/slave mode */
- snd_soc_update_bits(codec, WM8804_AIFRX, 0x40, master << 6);
-
- bcp = lrp = 0;
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- bcp = lrp = 1;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- bcp = 1;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- lrp = 1;
- break;
- default:
- dev_err(dai->dev, "Unknown polarity configuration\n");
- return -EINVAL;
- }
-
- /* set frame inversion */
- snd_soc_update_bits(codec, WM8804_AIFTX, 0x10 | 0x20,
- (bcp << 4) | (lrp << 5));
- snd_soc_update_bits(codec, WM8804_AIFRX, 0x10 | 0x20,
- (bcp << 4) | (lrp << 5));
- return 0;
-}
-
-static int wm8804_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec;
- u16 blen;
-
- codec = dai->codec;
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- blen = 0x0;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- blen = 0x1;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- blen = 0x2;
- break;
- default:
- dev_err(dai->dev, "Unsupported word length: %u\n",
- params_format(params));
- return -EINVAL;
- }
-
- /* set word length */
- snd_soc_update_bits(codec, WM8804_AIFTX, 0xc, blen << 2);
- snd_soc_update_bits(codec, WM8804_AIFRX, 0xc, blen << 2);
-
- return 0;
-}
-
-struct pll_div {
- u32 prescale:1;
- u32 mclkdiv:1;
- u32 freqmode:2;
- u32 n:4;
- u32 k:22;
-};
-
-/* PLL rate to output rate divisions */
-static struct {
- unsigned int div;
- unsigned int freqmode;
- unsigned int mclkdiv;
-} post_table[] = {
- { 2, 0, 0 },
- { 4, 0, 1 },
- { 4, 1, 0 },
- { 8, 1, 1 },
- { 8, 2, 0 },
- { 16, 2, 1 },
- { 12, 3, 0 },
- { 24, 3, 1 }
-};
-
-#define FIXED_PLL_SIZE ((1ULL << 22) * 10)
-static int pll_factors(struct pll_div *pll_div, unsigned int target,
- unsigned int source)
-{
- u64 Kpart;
- unsigned long int K, Ndiv, Nmod, tmp;
- int i;
-
- /*
- * Scale the output frequency up; the PLL should run in the
- * region of 90-100MHz.
- */
- for (i = 0; i < ARRAY_SIZE(post_table); i++) {
- tmp = target * post_table[i].div;
- if (tmp >= 90000000 && tmp <= 100000000) {
- pll_div->freqmode = post_table[i].freqmode;
- pll_div->mclkdiv = post_table[i].mclkdiv;
- target *= post_table[i].div;
- break;
- }
- }
-
- if (i == ARRAY_SIZE(post_table)) {
- pr_err("%s: Unable to scale output frequency: %uHz\n",
- __func__, target);
- return -EINVAL;
- }
-
- pll_div->prescale = 0;
- Ndiv = target / source;
- if (Ndiv < 5) {
- source >>= 1;
- pll_div->prescale = 1;
- Ndiv = target / source;
- }
-
- if (Ndiv < 5 || Ndiv > 13) {
- pr_err("%s: WM8804 N value is not within the recommended range: %lu\n",
- __func__, Ndiv);
- return -EINVAL;
- }
- pll_div->n = Ndiv;
-
- Nmod = target % source;
- Kpart = FIXED_PLL_SIZE * (u64)Nmod;
-
- do_div(Kpart, source);
-
- K = Kpart & 0xffffffff;
- if ((K % 10) >= 5)
- K += 5;
- K /= 10;
- pll_div->k = K;
-
- return 0;
-}
-
-static int wm8804_set_pll(struct snd_soc_dai *dai, int pll_id,
- int source, unsigned int freq_in,
- unsigned int freq_out)
-{
- struct snd_soc_codec *codec;
-
- codec = dai->codec;
- if (!freq_in || !freq_out) {
- /* disable the PLL */
- snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0x1);
- return 0;
- } else {
- int ret;
- struct pll_div pll_div;
-
- ret = pll_factors(&pll_div, freq_out, freq_in);
- if (ret)
- return ret;
-
- /* power down the PLL before reprogramming it */
- snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0x1);
-
- if (!freq_in || !freq_out)
- return 0;
-
- /* set PLLN and PRESCALE */
- snd_soc_update_bits(codec, WM8804_PLL4, 0xf | 0x10,
- pll_div.n | (pll_div.prescale << 4));
- /* set mclkdiv and freqmode */
- snd_soc_update_bits(codec, WM8804_PLL5, 0x3 | 0x8,
- pll_div.freqmode | (pll_div.mclkdiv << 3));
- /* set PLLK */
- snd_soc_write(codec, WM8804_PLL1, pll_div.k & 0xff);
- snd_soc_write(codec, WM8804_PLL2, (pll_div.k >> 8) & 0xff);
- snd_soc_write(codec, WM8804_PLL3, pll_div.k >> 16);
-
- /* power up the PLL */
- snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0);
- }
-
- return 0;
-}
-
-static int wm8804_set_sysclk(struct snd_soc_dai *dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec;
-
- codec = dai->codec;
-
- switch (clk_id) {
- case WM8804_TX_CLKSRC_MCLK:
- if ((freq >= 10000000 && freq <= 14400000)
- || (freq >= 16280000 && freq <= 27000000))
- snd_soc_update_bits(codec, WM8804_PLL6, 0x80, 0x80);
- else {
- dev_err(dai->dev, "OSCCLOCK is not within the "
- "recommended range: %uHz\n", freq);
- return -EINVAL;
- }
- break;
- case WM8804_TX_CLKSRC_PLL:
- snd_soc_update_bits(codec, WM8804_PLL6, 0x80, 0);
- break;
- case WM8804_CLKOUT_SRC_CLK1:
- snd_soc_update_bits(codec, WM8804_PLL6, 0x8, 0);
- break;
- case WM8804_CLKOUT_SRC_OSCCLK:
- snd_soc_update_bits(codec, WM8804_PLL6, 0x8, 0x8);
- break;
- default:
- dev_err(dai->dev, "Unknown clock source: %d\n", clk_id);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int wm8804_set_clkdiv(struct snd_soc_dai *dai,
- int div_id, int div)
-{
- struct snd_soc_codec *codec;
-
- codec = dai->codec;
- switch (div_id) {
- case WM8804_CLKOUT_DIV:
- snd_soc_update_bits(codec, WM8804_PLL5, 0x30,
- (div & 0x3) << 4);
- break;
- default:
- dev_err(dai->dev, "Unknown clock divider: %d\n", div_id);
- return -EINVAL;
- }
- return 0;
-}
-
-static int wm8804_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- int ret;
- struct wm8804_priv *wm8804;
-
- wm8804 = snd_soc_codec_get_drvdata(codec);
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
- case SND_SOC_BIAS_PREPARE:
- /* power up the OSC and the PLL */
- snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0);
- break;
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies),
- wm8804->supplies);
- if (ret) {
- dev_err(codec->dev,
- "Failed to enable supplies: %d\n",
- ret);
- return ret;
- }
- regcache_sync(wm8804->regmap);
- }
- /* power down the OSC and the PLL */
- snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0x9);
- break;
- case SND_SOC_BIAS_OFF:
- /* power down the OSC and the PLL */
- snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0x9);
- regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies),
- wm8804->supplies);
- break;
- }
-
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int wm8804_suspend(struct snd_soc_codec *codec)
-{
- wm8804_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm8804_resume(struct snd_soc_codec *codec)
-{
- wm8804_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-#else
-#define wm8804_suspend NULL
-#define wm8804_resume NULL
-#endif
-
-static int wm8804_remove(struct snd_soc_codec *codec)
-{
- struct wm8804_priv *wm8804;
- int i;
-
- wm8804 = snd_soc_codec_get_drvdata(codec);
- wm8804_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- for (i = 0; i < ARRAY_SIZE(wm8804->supplies); ++i)
- regulator_unregister_notifier(wm8804->supplies[i].consumer,
- &wm8804->disable_nb[i]);
- regulator_bulk_free(ARRAY_SIZE(wm8804->supplies), wm8804->supplies);
- return 0;
-}
-
-static int wm8804_probe(struct snd_soc_codec *codec)
-{
- struct wm8804_priv *wm8804;
- int i, id1, id2, ret;
-
- wm8804 = snd_soc_codec_get_drvdata(codec);
-
- codec->control_data = wm8804->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
- return ret;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++)
- wm8804->supplies[i].supply = wm8804_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8804->supplies),
- wm8804->supplies);
- if (ret) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- return ret;
- }
-
- wm8804->disable_nb[0].notifier_call = wm8804_regulator_event_0;
- wm8804->disable_nb[1].notifier_call = wm8804_regulator_event_1;
-
- /* This should really be moved into the regulator core */
- for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) {
- ret = regulator_register_notifier(wm8804->supplies[i].consumer,
- &wm8804->disable_nb[i]);
- if (ret != 0) {
- dev_err(codec->dev,
- "Failed to register regulator notifier: %d\n",
- ret);
- }
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies),
- wm8804->supplies);
- if (ret) {
- dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
- goto err_reg_get;
- }
-
- id1 = snd_soc_read(codec, WM8804_RST_DEVID1);
- if (id1 < 0) {
- dev_err(codec->dev, "Failed to read device ID: %d\n", id1);
- ret = id1;
- goto err_reg_enable;
- }
-
- id2 = snd_soc_read(codec, WM8804_DEVID2);
- if (id2 < 0) {
- dev_err(codec->dev, "Failed to read device ID: %d\n", id2);
- ret = id2;
- goto err_reg_enable;
- }
-
- id2 = (id2 << 8) | id1;
-
- if (id2 != 0x8805) {
- dev_err(codec->dev, "Invalid device ID: %#x\n", id2);
- ret = -EINVAL;
- goto err_reg_enable;
- }
-
- ret = snd_soc_read(codec, WM8804_DEVREV);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to read device revision: %d\n",
- ret);
- goto err_reg_enable;
- }
- dev_info(codec->dev, "revision %c\n", ret + 'A');
-
- ret = wm8804_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
- goto err_reg_enable;
- }
-
- wm8804_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-
-err_reg_enable:
- regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies), wm8804->supplies);
-err_reg_get:
- regulator_bulk_free(ARRAY_SIZE(wm8804->supplies), wm8804->supplies);
- return ret;
-}
-
-static const struct snd_soc_dai_ops wm8804_dai_ops = {
- .hw_params = wm8804_hw_params,
- .set_fmt = wm8804_set_fmt,
- .set_sysclk = wm8804_set_sysclk,
- .set_clkdiv = wm8804_set_clkdiv,
- .set_pll = wm8804_set_pll
-};
-
-#define WM8804_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
- SNDRV_PCM_FMTBIT_S24_LE)
-
-#define WM8804_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \
- SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
- SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000)
-
-static struct snd_soc_dai_driver wm8804_dai = {
- .name = "wm8804-spdif",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = WM8804_RATES,
- .formats = WM8804_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = WM8804_RATES,
- .formats = WM8804_FORMATS,
- },
- .ops = &wm8804_dai_ops,
- .symmetric_rates = 1
-};
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8804 = {
- .probe = wm8804_probe,
- .remove = wm8804_remove,
- .suspend = wm8804_suspend,
- .resume = wm8804_resume,
- .set_bias_level = wm8804_set_bias_level,
- .idle_bias_off = true,
-
- .controls = wm8804_snd_controls,
- .num_controls = ARRAY_SIZE(wm8804_snd_controls),
-};
-
-static const struct of_device_id wm8804_of_match[] = {
- { .compatible = "wlf,wm8804", },
- { }
-};
-MODULE_DEVICE_TABLE(of, wm8804_of_match);
-
-static struct regmap_config wm8804_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
-
- .max_register = WM8804_MAX_REGISTER,
- .volatile_reg = wm8804_volatile,
-
- .cache_type = REGCACHE_RBTREE,
- .reg_defaults = wm8804_reg_defaults,
- .num_reg_defaults = ARRAY_SIZE(wm8804_reg_defaults),
-};
-
-#if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8804_spi_probe(struct spi_device *spi)
-{
- struct wm8804_priv *wm8804;
- int ret;
-
- wm8804 = devm_kzalloc(&spi->dev, sizeof *wm8804, GFP_KERNEL);
- if (!wm8804)
- return -ENOMEM;
-
- wm8804->regmap = regmap_init_spi(spi, &wm8804_regmap_config);
- if (IS_ERR(wm8804->regmap)) {
- ret = PTR_ERR(wm8804->regmap);
- return ret;
- }
-
- spi_set_drvdata(spi, wm8804);
-
- ret = snd_soc_register_codec(&spi->dev,
- &soc_codec_dev_wm8804, &wm8804_dai, 1);
-
- return ret;
-}
-
-static int __devexit wm8804_spi_remove(struct spi_device *spi)
-{
- struct wm8804_priv *wm8804 = spi_get_drvdata(spi);
- snd_soc_unregister_codec(&spi->dev);
- regmap_exit(wm8804->regmap);
- return 0;
-}
-
-static struct spi_driver wm8804_spi_driver = {
- .driver = {
- .name = "wm8804",
- .owner = THIS_MODULE,
- .of_match_table = wm8804_of_match,
- },
- .probe = wm8804_spi_probe,
- .remove = __devexit_p(wm8804_spi_remove)
-};
-#endif
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8804_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8804_priv *wm8804;
- int ret;
-
- wm8804 = devm_kzalloc(&i2c->dev, sizeof *wm8804, GFP_KERNEL);
- if (!wm8804)
- return -ENOMEM;
-
- wm8804->regmap = regmap_init_i2c(i2c, &wm8804_regmap_config);
- if (IS_ERR(wm8804->regmap)) {
- ret = PTR_ERR(wm8804->regmap);
- return ret;
- }
-
- i2c_set_clientdata(i2c, wm8804);
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8804, &wm8804_dai, 1);
- if (ret != 0)
- goto err;
-
- return 0;
-
-err:
- regmap_exit(wm8804->regmap);
- return ret;
-}
-
-static __devexit int wm8804_i2c_remove(struct i2c_client *i2c)
-{
- struct wm8804_priv *wm8804 = i2c_get_clientdata(i2c);
-
- snd_soc_unregister_codec(&i2c->dev);
- regmap_exit(wm8804->regmap);
-
- return 0;
-}
-
-static const struct i2c_device_id wm8804_i2c_id[] = {
- { "wm8804", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8804_i2c_id);
-
-static struct i2c_driver wm8804_i2c_driver = {
- .driver = {
- .name = "wm8804",
- .owner = THIS_MODULE,
- .of_match_table = wm8804_of_match,
- },
- .probe = wm8804_i2c_probe,
- .remove = __devexit_p(wm8804_i2c_remove),
- .id_table = wm8804_i2c_id
-};
-#endif
-
-static int __init wm8804_modinit(void)
-{
- int ret = 0;
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&wm8804_i2c_driver);
- if (ret) {
- printk(KERN_ERR "Failed to register wm8804 I2C driver: %d\n",
- ret);
- }
-#endif
-#if defined(CONFIG_SPI_MASTER)
- ret = spi_register_driver(&wm8804_spi_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8804 SPI driver: %d\n",
- ret);
- }
-#endif
- return ret;
-}
-module_init(wm8804_modinit);
-
-static void __exit wm8804_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&wm8804_i2c_driver);
-#endif
-#if defined(CONFIG_SPI_MASTER)
- spi_unregister_driver(&wm8804_spi_driver);
-#endif
-}
-module_exit(wm8804_exit);
-
-MODULE_DESCRIPTION("ASoC WM8804 driver");
-MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8804.h b/ANDROID_3.4.5/sound/soc/codecs/wm8804.h
deleted file mode 100644
index 8ec14f55..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8804.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * wm8804.h -- WM8804 S/PDIF transceiver driver
- *
- * Copyright 2010 Wolfson Microelectronics plc
- *
- * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8804_H
-#define _WM8804_H
-
-/*
- * Register values.
- */
-#define WM8804_RST_DEVID1 0x00
-#define WM8804_DEVID2 0x01
-#define WM8804_DEVREV 0x02
-#define WM8804_PLL1 0x03
-#define WM8804_PLL2 0x04
-#define WM8804_PLL3 0x05
-#define WM8804_PLL4 0x06
-#define WM8804_PLL5 0x07
-#define WM8804_PLL6 0x08
-#define WM8804_SPDMODE 0x09
-#define WM8804_INTMASK 0x0A
-#define WM8804_INTSTAT 0x0B
-#define WM8804_SPDSTAT 0x0C
-#define WM8804_RXCHAN1 0x0D
-#define WM8804_RXCHAN2 0x0E
-#define WM8804_RXCHAN3 0x0F
-#define WM8804_RXCHAN4 0x10
-#define WM8804_RXCHAN5 0x11
-#define WM8804_SPDTX1 0x12
-#define WM8804_SPDTX2 0x13
-#define WM8804_SPDTX3 0x14
-#define WM8804_SPDTX4 0x15
-#define WM8804_SPDTX5 0x16
-#define WM8804_GPO0 0x17
-#define WM8804_GPO1 0x18
-#define WM8804_GPO2 0x1A
-#define WM8804_AIFTX 0x1B
-#define WM8804_AIFRX 0x1C
-#define WM8804_SPDRX1 0x1D
-#define WM8804_PWRDN 0x1E
-
-#define WM8804_REGISTER_COUNT 30
-#define WM8804_MAX_REGISTER 0x1E
-
-#define WM8804_TX_CLKSRC_MCLK 1
-#define WM8804_TX_CLKSRC_PLL 2
-
-#define WM8804_CLKOUT_SRC_CLK1 3
-#define WM8804_CLKOUT_SRC_OSCCLK 4
-
-#define WM8804_CLKOUT_DIV 1
-
-#endif /* _WM8804_H */
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8900.c b/ANDROID_3.4.5/sound/soc/codecs/wm8900.c
deleted file mode 100644
index f18c554e..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8900.c
+++ /dev/null
@@ -1,1340 +0,0 @@
-/*
- * wm8900.c -- WM8900 ALSA Soc Audio driver
- *
- * Copyright 2007, 2008 Wolfson Microelectronics PLC.
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * TODO:
- * - Tristating.
- * - TDM.
- * - Jack detect.
- * - FLL source configuration, currently only MCLK is supported.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "wm8900.h"
-
-/* WM8900 register space */
-#define WM8900_REG_RESET 0x0
-#define WM8900_REG_ID 0x0
-#define WM8900_REG_POWER1 0x1
-#define WM8900_REG_POWER2 0x2
-#define WM8900_REG_POWER3 0x3
-#define WM8900_REG_AUDIO1 0x4
-#define WM8900_REG_AUDIO2 0x5
-#define WM8900_REG_CLOCKING1 0x6
-#define WM8900_REG_CLOCKING2 0x7
-#define WM8900_REG_AUDIO3 0x8
-#define WM8900_REG_AUDIO4 0x9
-#define WM8900_REG_DACCTRL 0xa
-#define WM8900_REG_LDAC_DV 0xb
-#define WM8900_REG_RDAC_DV 0xc
-#define WM8900_REG_SIDETONE 0xd
-#define WM8900_REG_ADCCTRL 0xe
-#define WM8900_REG_LADC_DV 0xf
-#define WM8900_REG_RADC_DV 0x10
-#define WM8900_REG_GPIO 0x12
-#define WM8900_REG_INCTL 0x15
-#define WM8900_REG_LINVOL 0x16
-#define WM8900_REG_RINVOL 0x17
-#define WM8900_REG_INBOOSTMIX1 0x18
-#define WM8900_REG_INBOOSTMIX2 0x19
-#define WM8900_REG_ADCPATH 0x1a
-#define WM8900_REG_AUXBOOST 0x1b
-#define WM8900_REG_ADDCTL 0x1e
-#define WM8900_REG_FLLCTL1 0x24
-#define WM8900_REG_FLLCTL2 0x25
-#define WM8900_REG_FLLCTL3 0x26
-#define WM8900_REG_FLLCTL4 0x27
-#define WM8900_REG_FLLCTL5 0x28
-#define WM8900_REG_FLLCTL6 0x29
-#define WM8900_REG_LOUTMIXCTL1 0x2c
-#define WM8900_REG_ROUTMIXCTL1 0x2d
-#define WM8900_REG_BYPASS1 0x2e
-#define WM8900_REG_BYPASS2 0x2f
-#define WM8900_REG_AUXOUT_CTL 0x30
-#define WM8900_REG_LOUT1CTL 0x33
-#define WM8900_REG_ROUT1CTL 0x34
-#define WM8900_REG_LOUT2CTL 0x35
-#define WM8900_REG_ROUT2CTL 0x36
-#define WM8900_REG_HPCTL1 0x3a
-#define WM8900_REG_OUTBIASCTL 0x73
-
-#define WM8900_MAXREG 0x80
-
-#define WM8900_REG_ADDCTL_OUT1_DIS 0x80
-#define WM8900_REG_ADDCTL_OUT2_DIS 0x40
-#define WM8900_REG_ADDCTL_VMID_DIS 0x20
-#define WM8900_REG_ADDCTL_BIAS_SRC 0x10
-#define WM8900_REG_ADDCTL_VMID_SOFTST 0x04
-#define WM8900_REG_ADDCTL_TEMP_SD 0x02
-
-#define WM8900_REG_GPIO_TEMP_ENA 0x2
-
-#define WM8900_REG_POWER1_STARTUP_BIAS_ENA 0x0100
-#define WM8900_REG_POWER1_BIAS_ENA 0x0008
-#define WM8900_REG_POWER1_VMID_BUF_ENA 0x0004
-#define WM8900_REG_POWER1_FLL_ENA 0x0040
-
-#define WM8900_REG_POWER2_SYSCLK_ENA 0x8000
-#define WM8900_REG_POWER2_ADCL_ENA 0x0002
-#define WM8900_REG_POWER2_ADCR_ENA 0x0001
-
-#define WM8900_REG_POWER3_DACL_ENA 0x0002
-#define WM8900_REG_POWER3_DACR_ENA 0x0001
-
-#define WM8900_REG_AUDIO1_AIF_FMT_MASK 0x0018
-#define WM8900_REG_AUDIO1_LRCLK_INV 0x0080
-#define WM8900_REG_AUDIO1_BCLK_INV 0x0100
-
-#define WM8900_REG_CLOCKING1_BCLK_DIR 0x1
-#define WM8900_REG_CLOCKING1_MCLK_SRC 0x100
-#define WM8900_REG_CLOCKING1_BCLK_MASK 0x01e
-#define WM8900_REG_CLOCKING1_OPCLK_MASK 0x7000
-
-#define WM8900_REG_CLOCKING2_ADC_CLKDIV 0xe0
-#define WM8900_REG_CLOCKING2_DAC_CLKDIV 0x1c
-
-#define WM8900_REG_DACCTRL_MUTE 0x004
-#define WM8900_REG_DACCTRL_DAC_SB_FILT 0x100
-#define WM8900_REG_DACCTRL_AIF_LRCLKRATE 0x400
-
-#define WM8900_REG_AUDIO3_ADCLRC_DIR 0x0800
-
-#define WM8900_REG_AUDIO4_DACLRC_DIR 0x0800
-
-#define WM8900_REG_FLLCTL1_OSC_ENA 0x100
-
-#define WM8900_REG_FLLCTL6_FLL_SLOW_LOCK_REF 0x100
-
-#define WM8900_REG_HPCTL1_HP_IPSTAGE_ENA 0x80
-#define WM8900_REG_HPCTL1_HP_OPSTAGE_ENA 0x40
-#define WM8900_REG_HPCTL1_HP_CLAMP_IP 0x20
-#define WM8900_REG_HPCTL1_HP_CLAMP_OP 0x10
-#define WM8900_REG_HPCTL1_HP_SHORT 0x08
-#define WM8900_REG_HPCTL1_HP_SHORT2 0x04
-
-#define WM8900_LRC_MASK 0x03ff
-
-struct wm8900_priv {
- enum snd_soc_control_type control_type;
-
- u32 fll_in; /* FLL input frequency */
- u32 fll_out; /* FLL output frequency */
-};
-
-/*
- * wm8900 register cache. We can't read the entire register space and we
- * have slow control buses so we cache the registers.
- */
-static const u16 wm8900_reg_defaults[WM8900_MAXREG] = {
- 0x8900, 0x0000,
- 0xc000, 0x0000,
- 0x4050, 0x4000,
- 0x0008, 0x0000,
- 0x0040, 0x0040,
- 0x1004, 0x00c0,
- 0x00c0, 0x0000,
- 0x0100, 0x00c0,
- 0x00c0, 0x0000,
- 0xb001, 0x0000,
- 0x0000, 0x0044,
- 0x004c, 0x004c,
- 0x0044, 0x0044,
- 0x0000, 0x0044,
- 0x0000, 0x0000,
- 0x0002, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0008, 0x0000,
- 0x0000, 0x0008,
- 0x0097, 0x0100,
- 0x0000, 0x0000,
- 0x0050, 0x0050,
- 0x0055, 0x0055,
- 0x0055, 0x0000,
- 0x0000, 0x0079,
- 0x0079, 0x0079,
- 0x0079, 0x0000,
- /* Remaining registers all zero */
-};
-
-static int wm8900_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
-{
- switch (reg) {
- case WM8900_REG_ID:
- return 1;
- default:
- return 0;
- }
-}
-
-static void wm8900_reset(struct snd_soc_codec *codec)
-{
- snd_soc_write(codec, WM8900_REG_RESET, 0);
-
- memcpy(codec->reg_cache, wm8900_reg_defaults,
- sizeof(wm8900_reg_defaults));
-}
-
-static int wm8900_hp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- u16 hpctl1 = snd_soc_read(codec, WM8900_REG_HPCTL1);
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- /* Clamp headphone outputs */
- hpctl1 = WM8900_REG_HPCTL1_HP_CLAMP_IP |
- WM8900_REG_HPCTL1_HP_CLAMP_OP;
- snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
- break;
-
- case SND_SOC_DAPM_POST_PMU:
- /* Enable the input stage */
- hpctl1 &= ~WM8900_REG_HPCTL1_HP_CLAMP_IP;
- hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT |
- WM8900_REG_HPCTL1_HP_SHORT2 |
- WM8900_REG_HPCTL1_HP_IPSTAGE_ENA;
- snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
-
- msleep(400);
-
- /* Enable the output stage */
- hpctl1 &= ~WM8900_REG_HPCTL1_HP_CLAMP_OP;
- hpctl1 |= WM8900_REG_HPCTL1_HP_OPSTAGE_ENA;
- snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
-
- /* Remove the shorts */
- hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT2;
- snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
- hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT;
- snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
- break;
-
- case SND_SOC_DAPM_PRE_PMD:
- /* Short the output */
- hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT;
- snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
-
- /* Disable the output stage */
- hpctl1 &= ~WM8900_REG_HPCTL1_HP_OPSTAGE_ENA;
- snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
-
- /* Clamp the outputs and power down input */
- hpctl1 |= WM8900_REG_HPCTL1_HP_CLAMP_IP |
- WM8900_REG_HPCTL1_HP_CLAMP_OP;
- hpctl1 &= ~WM8900_REG_HPCTL1_HP_IPSTAGE_ENA;
- snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
- break;
-
- case SND_SOC_DAPM_POST_PMD:
- /* Disable everything */
- snd_soc_write(codec, WM8900_REG_HPCTL1, 0);
- break;
-
- default:
- BUG();
- }
-
- return 0;
-}
-
-static const DECLARE_TLV_DB_SCALE(out_pga_tlv, -5700, 100, 0);
-
-static const DECLARE_TLV_DB_SCALE(out_mix_tlv, -1500, 300, 0);
-
-static const DECLARE_TLV_DB_SCALE(in_boost_tlv, -1200, 600, 0);
-
-static const DECLARE_TLV_DB_SCALE(in_pga_tlv, -1200, 100, 0);
-
-static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0);
-
-static const DECLARE_TLV_DB_SCALE(dac_tlv, -7200, 75, 1);
-
-static const DECLARE_TLV_DB_SCALE(adc_svol_tlv, -3600, 300, 0);
-
-static const DECLARE_TLV_DB_SCALE(adc_tlv, -7200, 75, 1);
-
-static const char *mic_bias_level_txt[] = { "0.9*AVDD", "0.65*AVDD" };
-
-static const struct soc_enum mic_bias_level =
-SOC_ENUM_SINGLE(WM8900_REG_INCTL, 8, 2, mic_bias_level_txt);
-
-static const char *dac_mute_rate_txt[] = { "Fast", "Slow" };
-
-static const struct soc_enum dac_mute_rate =
-SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 7, 2, dac_mute_rate_txt);
-
-static const char *dac_deemphasis_txt[] = {
- "Disabled", "32kHz", "44.1kHz", "48kHz"
-};
-
-static const struct soc_enum dac_deemphasis =
-SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 4, 4, dac_deemphasis_txt);
-
-static const char *adc_hpf_cut_txt[] = {
- "Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"
-};
-
-static const struct soc_enum adc_hpf_cut =
-SOC_ENUM_SINGLE(WM8900_REG_ADCCTRL, 5, 4, adc_hpf_cut_txt);
-
-static const char *lr_txt[] = {
- "Left", "Right"
-};
-
-static const struct soc_enum aifl_src =
-SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 15, 2, lr_txt);
-
-static const struct soc_enum aifr_src =
-SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 14, 2, lr_txt);
-
-static const struct soc_enum dacl_src =
-SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 15, 2, lr_txt);
-
-static const struct soc_enum dacr_src =
-SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 14, 2, lr_txt);
-
-static const char *sidetone_txt[] = {
- "Disabled", "Left ADC", "Right ADC"
-};
-
-static const struct soc_enum dacl_sidetone =
-SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 2, 3, sidetone_txt);
-
-static const struct soc_enum dacr_sidetone =
-SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 0, 3, sidetone_txt);
-
-static const struct snd_kcontrol_new wm8900_snd_controls[] = {
-SOC_ENUM("Mic Bias Level", mic_bias_level),
-
-SOC_SINGLE_TLV("Left Input PGA Volume", WM8900_REG_LINVOL, 0, 31, 0,
- in_pga_tlv),
-SOC_SINGLE("Left Input PGA Switch", WM8900_REG_LINVOL, 6, 1, 1),
-SOC_SINGLE("Left Input PGA ZC Switch", WM8900_REG_LINVOL, 7, 1, 0),
-
-SOC_SINGLE_TLV("Right Input PGA Volume", WM8900_REG_RINVOL, 0, 31, 0,
- in_pga_tlv),
-SOC_SINGLE("Right Input PGA Switch", WM8900_REG_RINVOL, 6, 1, 1),
-SOC_SINGLE("Right Input PGA ZC Switch", WM8900_REG_RINVOL, 7, 1, 0),
-
-SOC_SINGLE("DAC Soft Mute Switch", WM8900_REG_DACCTRL, 6, 1, 1),
-SOC_ENUM("DAC Mute Rate", dac_mute_rate),
-SOC_SINGLE("DAC Mono Switch", WM8900_REG_DACCTRL, 9, 1, 0),
-SOC_ENUM("DAC Deemphasis", dac_deemphasis),
-SOC_SINGLE("DAC Sigma-Delta Modulator Clock Switch", WM8900_REG_DACCTRL,
- 12, 1, 0),
-
-SOC_SINGLE("ADC HPF Switch", WM8900_REG_ADCCTRL, 8, 1, 0),
-SOC_ENUM("ADC HPF Cut-Off", adc_hpf_cut),
-SOC_DOUBLE("ADC Invert Switch", WM8900_REG_ADCCTRL, 1, 0, 1, 0),
-SOC_SINGLE_TLV("Left ADC Sidetone Volume", WM8900_REG_SIDETONE, 9, 12, 0,
- adc_svol_tlv),
-SOC_SINGLE_TLV("Right ADC Sidetone Volume", WM8900_REG_SIDETONE, 5, 12, 0,
- adc_svol_tlv),
-SOC_ENUM("Left Digital Audio Source", aifl_src),
-SOC_ENUM("Right Digital Audio Source", aifr_src),
-
-SOC_SINGLE_TLV("DAC Input Boost Volume", WM8900_REG_AUDIO2, 10, 4, 0,
- dac_boost_tlv),
-SOC_ENUM("Left DAC Source", dacl_src),
-SOC_ENUM("Right DAC Source", dacr_src),
-SOC_ENUM("Left DAC Sidetone", dacl_sidetone),
-SOC_ENUM("Right DAC Sidetone", dacr_sidetone),
-SOC_DOUBLE("DAC Invert Switch", WM8900_REG_DACCTRL, 1, 0, 1, 0),
-
-SOC_DOUBLE_R_TLV("Digital Playback Volume",
- WM8900_REG_LDAC_DV, WM8900_REG_RDAC_DV,
- 1, 96, 0, dac_tlv),
-SOC_DOUBLE_R_TLV("Digital Capture Volume",
- WM8900_REG_LADC_DV, WM8900_REG_RADC_DV, 1, 119, 0, adc_tlv),
-
-SOC_SINGLE_TLV("LINPUT3 Bypass Volume", WM8900_REG_LOUTMIXCTL1, 4, 7, 0,
- out_mix_tlv),
-SOC_SINGLE_TLV("RINPUT3 Bypass Volume", WM8900_REG_ROUTMIXCTL1, 4, 7, 0,
- out_mix_tlv),
-SOC_SINGLE_TLV("Left AUX Bypass Volume", WM8900_REG_AUXOUT_CTL, 4, 7, 0,
- out_mix_tlv),
-SOC_SINGLE_TLV("Right AUX Bypass Volume", WM8900_REG_AUXOUT_CTL, 0, 7, 0,
- out_mix_tlv),
-
-SOC_SINGLE_TLV("LeftIn to RightOut Mixer Volume", WM8900_REG_BYPASS1, 0, 7, 0,
- out_mix_tlv),
-SOC_SINGLE_TLV("LeftIn to LeftOut Mixer Volume", WM8900_REG_BYPASS1, 4, 7, 0,
- out_mix_tlv),
-SOC_SINGLE_TLV("RightIn to LeftOut Mixer Volume", WM8900_REG_BYPASS2, 0, 7, 0,
- out_mix_tlv),
-SOC_SINGLE_TLV("RightIn to RightOut Mixer Volume", WM8900_REG_BYPASS2, 4, 7, 0,
- out_mix_tlv),
-
-SOC_SINGLE_TLV("IN2L Boost Volume", WM8900_REG_INBOOSTMIX1, 0, 3, 0,
- in_boost_tlv),
-SOC_SINGLE_TLV("IN3L Boost Volume", WM8900_REG_INBOOSTMIX1, 4, 3, 0,
- in_boost_tlv),
-SOC_SINGLE_TLV("IN2R Boost Volume", WM8900_REG_INBOOSTMIX2, 0, 3, 0,
- in_boost_tlv),
-SOC_SINGLE_TLV("IN3R Boost Volume", WM8900_REG_INBOOSTMIX2, 4, 3, 0,
- in_boost_tlv),
-SOC_SINGLE_TLV("Left AUX Boost Volume", WM8900_REG_AUXBOOST, 4, 3, 0,
- in_boost_tlv),
-SOC_SINGLE_TLV("Right AUX Boost Volume", WM8900_REG_AUXBOOST, 0, 3, 0,
- in_boost_tlv),
-
-SOC_DOUBLE_R_TLV("LINEOUT1 Volume", WM8900_REG_LOUT1CTL, WM8900_REG_ROUT1CTL,
- 0, 63, 0, out_pga_tlv),
-SOC_DOUBLE_R("LINEOUT1 Switch", WM8900_REG_LOUT1CTL, WM8900_REG_ROUT1CTL,
- 6, 1, 1),
-SOC_DOUBLE_R("LINEOUT1 ZC Switch", WM8900_REG_LOUT1CTL, WM8900_REG_ROUT1CTL,
- 7, 1, 0),
-
-SOC_DOUBLE_R_TLV("LINEOUT2 Volume",
- WM8900_REG_LOUT2CTL, WM8900_REG_ROUT2CTL,
- 0, 63, 0, out_pga_tlv),
-SOC_DOUBLE_R("LINEOUT2 Switch",
- WM8900_REG_LOUT2CTL, WM8900_REG_ROUT2CTL, 6, 1, 1),
-SOC_DOUBLE_R("LINEOUT2 ZC Switch",
- WM8900_REG_LOUT2CTL, WM8900_REG_ROUT2CTL, 7, 1, 0),
-SOC_SINGLE("LINEOUT2 LP -12dB", WM8900_REG_LOUTMIXCTL1,
- 0, 1, 1),
-
-};
-
-static const struct snd_kcontrol_new wm8900_dapm_loutput2_control =
-SOC_DAPM_SINGLE("LINEOUT2L Switch", WM8900_REG_POWER3, 6, 1, 0);
-
-static const struct snd_kcontrol_new wm8900_dapm_routput2_control =
-SOC_DAPM_SINGLE("LINEOUT2R Switch", WM8900_REG_POWER3, 5, 1, 0);
-
-static const struct snd_kcontrol_new wm8900_loutmix_controls[] = {
-SOC_DAPM_SINGLE("LINPUT3 Bypass Switch", WM8900_REG_LOUTMIXCTL1, 7, 1, 0),
-SOC_DAPM_SINGLE("AUX Bypass Switch", WM8900_REG_AUXOUT_CTL, 7, 1, 0),
-SOC_DAPM_SINGLE("Left Input Mixer Switch", WM8900_REG_BYPASS1, 7, 1, 0),
-SOC_DAPM_SINGLE("Right Input Mixer Switch", WM8900_REG_BYPASS2, 3, 1, 0),
-SOC_DAPM_SINGLE("DACL Switch", WM8900_REG_LOUTMIXCTL1, 8, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8900_routmix_controls[] = {
-SOC_DAPM_SINGLE("RINPUT3 Bypass Switch", WM8900_REG_ROUTMIXCTL1, 7, 1, 0),
-SOC_DAPM_SINGLE("AUX Bypass Switch", WM8900_REG_AUXOUT_CTL, 3, 1, 0),
-SOC_DAPM_SINGLE("Left Input Mixer Switch", WM8900_REG_BYPASS1, 3, 1, 0),
-SOC_DAPM_SINGLE("Right Input Mixer Switch", WM8900_REG_BYPASS2, 7, 1, 0),
-SOC_DAPM_SINGLE("DACR Switch", WM8900_REG_ROUTMIXCTL1, 8, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8900_linmix_controls[] = {
-SOC_DAPM_SINGLE("LINPUT2 Switch", WM8900_REG_INBOOSTMIX1, 2, 1, 1),
-SOC_DAPM_SINGLE("LINPUT3 Switch", WM8900_REG_INBOOSTMIX1, 6, 1, 1),
-SOC_DAPM_SINGLE("AUX Switch", WM8900_REG_AUXBOOST, 6, 1, 1),
-SOC_DAPM_SINGLE("Input PGA Switch", WM8900_REG_ADCPATH, 6, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8900_rinmix_controls[] = {
-SOC_DAPM_SINGLE("RINPUT2 Switch", WM8900_REG_INBOOSTMIX2, 2, 1, 1),
-SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INBOOSTMIX2, 6, 1, 1),
-SOC_DAPM_SINGLE("AUX Switch", WM8900_REG_AUXBOOST, 2, 1, 1),
-SOC_DAPM_SINGLE("Input PGA Switch", WM8900_REG_ADCPATH, 2, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8900_linpga_controls[] = {
-SOC_DAPM_SINGLE("LINPUT1 Switch", WM8900_REG_INCTL, 6, 1, 0),
-SOC_DAPM_SINGLE("LINPUT2 Switch", WM8900_REG_INCTL, 5, 1, 0),
-SOC_DAPM_SINGLE("LINPUT3 Switch", WM8900_REG_INCTL, 4, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8900_rinpga_controls[] = {
-SOC_DAPM_SINGLE("RINPUT1 Switch", WM8900_REG_INCTL, 2, 1, 0),
-SOC_DAPM_SINGLE("RINPUT2 Switch", WM8900_REG_INCTL, 1, 1, 0),
-SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INCTL, 0, 1, 0),
-};
-
-static const char *wm9700_lp_mux[] = { "Disabled", "Enabled" };
-
-static const struct soc_enum wm8900_lineout2_lp_mux =
-SOC_ENUM_SINGLE(WM8900_REG_LOUTMIXCTL1, 1, 2, wm9700_lp_mux);
-
-static const struct snd_kcontrol_new wm8900_lineout2_lp =
-SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux);
-
-static const struct snd_soc_dapm_widget wm8900_dapm_widgets[] = {
-
-/* Externally visible pins */
-SND_SOC_DAPM_OUTPUT("LINEOUT1L"),
-SND_SOC_DAPM_OUTPUT("LINEOUT1R"),
-SND_SOC_DAPM_OUTPUT("LINEOUT2L"),
-SND_SOC_DAPM_OUTPUT("LINEOUT2R"),
-SND_SOC_DAPM_OUTPUT("HP_L"),
-SND_SOC_DAPM_OUTPUT("HP_R"),
-
-SND_SOC_DAPM_INPUT("RINPUT1"),
-SND_SOC_DAPM_INPUT("LINPUT1"),
-SND_SOC_DAPM_INPUT("RINPUT2"),
-SND_SOC_DAPM_INPUT("LINPUT2"),
-SND_SOC_DAPM_INPUT("RINPUT3"),
-SND_SOC_DAPM_INPUT("LINPUT3"),
-SND_SOC_DAPM_INPUT("AUX"),
-
-SND_SOC_DAPM_VMID("VMID"),
-
-/* Input */
-SND_SOC_DAPM_MIXER("Left Input PGA", WM8900_REG_POWER2, 3, 0,
- wm8900_linpga_controls,
- ARRAY_SIZE(wm8900_linpga_controls)),
-SND_SOC_DAPM_MIXER("Right Input PGA", WM8900_REG_POWER2, 2, 0,
- wm8900_rinpga_controls,
- ARRAY_SIZE(wm8900_rinpga_controls)),
-
-SND_SOC_DAPM_MIXER("Left Input Mixer", WM8900_REG_POWER2, 5, 0,
- wm8900_linmix_controls,
- ARRAY_SIZE(wm8900_linmix_controls)),
-SND_SOC_DAPM_MIXER("Right Input Mixer", WM8900_REG_POWER2, 4, 0,
- wm8900_rinmix_controls,
- ARRAY_SIZE(wm8900_rinmix_controls)),
-
-SND_SOC_DAPM_SUPPLY("Mic Bias", WM8900_REG_POWER1, 4, 0, NULL, 0),
-
-SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8900_REG_POWER2, 1, 0),
-SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8900_REG_POWER2, 0, 0),
-
-/* Output */
-SND_SOC_DAPM_DAC("DACL", "Left HiFi Playback", WM8900_REG_POWER3, 1, 0),
-SND_SOC_DAPM_DAC("DACR", "Right HiFi Playback", WM8900_REG_POWER3, 0, 0),
-
-SND_SOC_DAPM_PGA_E("Headphone Amplifier", WM8900_REG_POWER3, 7, 0, NULL, 0,
- wm8900_hp_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
-
-SND_SOC_DAPM_PGA("LINEOUT1L PGA", WM8900_REG_POWER2, 8, 0, NULL, 0),
-SND_SOC_DAPM_PGA("LINEOUT1R PGA", WM8900_REG_POWER2, 7, 0, NULL, 0),
-
-SND_SOC_DAPM_MUX("LINEOUT2 LP", SND_SOC_NOPM, 0, 0, &wm8900_lineout2_lp),
-SND_SOC_DAPM_PGA("LINEOUT2L PGA", WM8900_REG_POWER3, 6, 0, NULL, 0),
-SND_SOC_DAPM_PGA("LINEOUT2R PGA", WM8900_REG_POWER3, 5, 0, NULL, 0),
-
-SND_SOC_DAPM_MIXER("Left Output Mixer", WM8900_REG_POWER3, 3, 0,
- wm8900_loutmix_controls,
- ARRAY_SIZE(wm8900_loutmix_controls)),
-SND_SOC_DAPM_MIXER("Right Output Mixer", WM8900_REG_POWER3, 2, 0,
- wm8900_routmix_controls,
- ARRAY_SIZE(wm8900_routmix_controls)),
-};
-
-/* Target, Path, Source */
-static const struct snd_soc_dapm_route wm8900_dapm_routes[] = {
-/* Inputs */
-{"Left Input PGA", "LINPUT1 Switch", "LINPUT1"},
-{"Left Input PGA", "LINPUT2 Switch", "LINPUT2"},
-{"Left Input PGA", "LINPUT3 Switch", "LINPUT3"},
-
-{"Right Input PGA", "RINPUT1 Switch", "RINPUT1"},
-{"Right Input PGA", "RINPUT2 Switch", "RINPUT2"},
-{"Right Input PGA", "RINPUT3 Switch", "RINPUT3"},
-
-{"Left Input Mixer", "LINPUT2 Switch", "LINPUT2"},
-{"Left Input Mixer", "LINPUT3 Switch", "LINPUT3"},
-{"Left Input Mixer", "AUX Switch", "AUX"},
-{"Left Input Mixer", "Input PGA Switch", "Left Input PGA"},
-
-{"Right Input Mixer", "RINPUT2 Switch", "RINPUT2"},
-{"Right Input Mixer", "RINPUT3 Switch", "RINPUT3"},
-{"Right Input Mixer", "AUX Switch", "AUX"},
-{"Right Input Mixer", "Input PGA Switch", "Right Input PGA"},
-
-{"ADCL", NULL, "Left Input Mixer"},
-{"ADCR", NULL, "Right Input Mixer"},
-
-/* Outputs */
-{"LINEOUT1L", NULL, "LINEOUT1L PGA"},
-{"LINEOUT1L PGA", NULL, "Left Output Mixer"},
-{"LINEOUT1R", NULL, "LINEOUT1R PGA"},
-{"LINEOUT1R PGA", NULL, "Right Output Mixer"},
-
-{"LINEOUT2L PGA", NULL, "Left Output Mixer"},
-{"LINEOUT2 LP", "Disabled", "LINEOUT2L PGA"},
-{"LINEOUT2 LP", "Enabled", "Left Output Mixer"},
-{"LINEOUT2L", NULL, "LINEOUT2 LP"},
-
-{"LINEOUT2R PGA", NULL, "Right Output Mixer"},
-{"LINEOUT2 LP", "Disabled", "LINEOUT2R PGA"},
-{"LINEOUT2 LP", "Enabled", "Right Output Mixer"},
-{"LINEOUT2R", NULL, "LINEOUT2 LP"},
-
-{"Left Output Mixer", "LINPUT3 Bypass Switch", "LINPUT3"},
-{"Left Output Mixer", "AUX Bypass Switch", "AUX"},
-{"Left Output Mixer", "Left Input Mixer Switch", "Left Input Mixer"},
-{"Left Output Mixer", "Right Input Mixer Switch", "Right Input Mixer"},
-{"Left Output Mixer", "DACL Switch", "DACL"},
-
-{"Right Output Mixer", "RINPUT3 Bypass Switch", "RINPUT3"},
-{"Right Output Mixer", "AUX Bypass Switch", "AUX"},
-{"Right Output Mixer", "Left Input Mixer Switch", "Left Input Mixer"},
-{"Right Output Mixer", "Right Input Mixer Switch", "Right Input Mixer"},
-{"Right Output Mixer", "DACR Switch", "DACR"},
-
-/* Note that the headphone output stage needs to be connected
- * externally to LINEOUT2 via DC blocking capacitors. Other
- * configurations are not supported.
- *
- * Note also that left and right headphone paths are treated as a
- * mono path.
- */
-{"Headphone Amplifier", NULL, "LINEOUT2 LP"},
-{"Headphone Amplifier", NULL, "LINEOUT2 LP"},
-{"HP_L", NULL, "Headphone Amplifier"},
-{"HP_R", NULL, "Headphone Amplifier"},
-};
-
-static int wm8900_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- u16 reg;
-
- reg = snd_soc_read(codec, WM8900_REG_AUDIO1) & ~0x60;
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- reg |= 0x20;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- reg |= 0x40;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- reg |= 0x60;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM8900_REG_AUDIO1, reg);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- reg = snd_soc_read(codec, WM8900_REG_DACCTRL);
-
- if (params_rate(params) <= 24000)
- reg |= WM8900_REG_DACCTRL_DAC_SB_FILT;
- else
- reg &= ~WM8900_REG_DACCTRL_DAC_SB_FILT;
-
- snd_soc_write(codec, WM8900_REG_DACCTRL, reg);
- }
-
- return 0;
-}
-
-/* FLL divisors */
-struct _fll_div {
- u16 fll_ratio;
- u16 fllclk_div;
- u16 fll_slow_lock_ref;
- u16 n;
- u16 k;
-};
-
-/* The size in bits of the FLL divide multiplied by 10
- * to allow rounding later */
-#define FIXED_FLL_SIZE ((1 << 16) * 10)
-
-static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
- unsigned int Fout)
-{
- u64 Kpart;
- unsigned int K, Ndiv, Nmod, target;
- unsigned int div;
-
- BUG_ON(!Fout);
-
- /* The FLL must run at 90-100MHz which is then scaled down to
- * the output value by FLLCLK_DIV. */
- target = Fout;
- div = 1;
- while (target < 90000000) {
- div *= 2;
- target *= 2;
- }
-
- if (target > 100000000)
- printk(KERN_WARNING "wm8900: FLL rate %u out of range, Fref=%u"
- " Fout=%u\n", target, Fref, Fout);
- if (div > 32) {
- printk(KERN_ERR "wm8900: Invalid FLL division rate %u, "
- "Fref=%u, Fout=%u, target=%u\n",
- div, Fref, Fout, target);
- return -EINVAL;
- }
-
- fll_div->fllclk_div = div >> 2;
-
- if (Fref < 48000)
- fll_div->fll_slow_lock_ref = 1;
- else
- fll_div->fll_slow_lock_ref = 0;
-
- Ndiv = target / Fref;
-
- if (Fref < 1000000)
- fll_div->fll_ratio = 8;
- else
- fll_div->fll_ratio = 1;
-
- fll_div->n = Ndiv / fll_div->fll_ratio;
- Nmod = (target / fll_div->fll_ratio) % Fref;
-
- /* Calculate fractional part - scale up so we can round. */
- Kpart = FIXED_FLL_SIZE * (long long)Nmod;
-
- do_div(Kpart, Fref);
-
- K = Kpart & 0xFFFFFFFF;
-
- if ((K % 10) >= 5)
- K += 5;
-
- /* Move down to proper range now rounding is done */
- fll_div->k = K / 10;
-
- BUG_ON(target != Fout * (fll_div->fllclk_div << 2));
- BUG_ON(!K && target != Fref * fll_div->fll_ratio * fll_div->n);
-
- return 0;
-}
-
-static int wm8900_set_fll(struct snd_soc_codec *codec,
- int fll_id, unsigned int freq_in, unsigned int freq_out)
-{
- struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
- struct _fll_div fll_div;
-
- if (wm8900->fll_in == freq_in && wm8900->fll_out == freq_out)
- return 0;
-
- /* The digital side should be disabled during any change. */
- snd_soc_update_bits(codec, WM8900_REG_POWER1,
- WM8900_REG_POWER1_FLL_ENA, 0);
-
- /* Disable the FLL? */
- if (!freq_in || !freq_out) {
- snd_soc_update_bits(codec, WM8900_REG_CLOCKING1,
- WM8900_REG_CLOCKING1_MCLK_SRC, 0);
- snd_soc_update_bits(codec, WM8900_REG_FLLCTL1,
- WM8900_REG_FLLCTL1_OSC_ENA, 0);
- wm8900->fll_in = freq_in;
- wm8900->fll_out = freq_out;
-
- return 0;
- }
-
- if (fll_factors(&fll_div, freq_in, freq_out) != 0)
- goto reenable;
-
- wm8900->fll_in = freq_in;
- wm8900->fll_out = freq_out;
-
- /* The osclilator *MUST* be enabled before we enable the
- * digital circuit. */
- snd_soc_write(codec, WM8900_REG_FLLCTL1,
- fll_div.fll_ratio | WM8900_REG_FLLCTL1_OSC_ENA);
-
- snd_soc_write(codec, WM8900_REG_FLLCTL4, fll_div.n >> 5);
- snd_soc_write(codec, WM8900_REG_FLLCTL5,
- (fll_div.fllclk_div << 6) | (fll_div.n & 0x1f));
-
- if (fll_div.k) {
- snd_soc_write(codec, WM8900_REG_FLLCTL2,
- (fll_div.k >> 8) | 0x100);
- snd_soc_write(codec, WM8900_REG_FLLCTL3, fll_div.k & 0xff);
- } else
- snd_soc_write(codec, WM8900_REG_FLLCTL2, 0);
-
- if (fll_div.fll_slow_lock_ref)
- snd_soc_write(codec, WM8900_REG_FLLCTL6,
- WM8900_REG_FLLCTL6_FLL_SLOW_LOCK_REF);
- else
- snd_soc_write(codec, WM8900_REG_FLLCTL6, 0);
-
- snd_soc_update_bits(codec, WM8900_REG_POWER1,
- WM8900_REG_POWER1_FLL_ENA,
- WM8900_REG_POWER1_FLL_ENA);
-
-reenable:
- snd_soc_update_bits(codec, WM8900_REG_CLOCKING1,
- WM8900_REG_CLOCKING1_MCLK_SRC,
- WM8900_REG_CLOCKING1_MCLK_SRC);
- return 0;
-}
-
-static int wm8900_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
- int source, unsigned int freq_in, unsigned int freq_out)
-{
- return wm8900_set_fll(codec_dai->codec, pll_id, freq_in, freq_out);
-}
-
-static int wm8900_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
- int div_id, int div)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
-
- switch (div_id) {
- case WM8900_BCLK_DIV:
- snd_soc_update_bits(codec, WM8900_REG_CLOCKING1,
- WM8900_REG_CLOCKING1_BCLK_MASK, div);
- break;
- case WM8900_OPCLK_DIV:
- snd_soc_update_bits(codec, WM8900_REG_CLOCKING1,
- WM8900_REG_CLOCKING1_OPCLK_MASK, div);
- break;
- case WM8900_DAC_LRCLK:
- snd_soc_update_bits(codec, WM8900_REG_AUDIO4,
- WM8900_LRC_MASK, div);
- break;
- case WM8900_ADC_LRCLK:
- snd_soc_update_bits(codec, WM8900_REG_AUDIO3,
- WM8900_LRC_MASK, div);
- break;
- case WM8900_DAC_CLKDIV:
- snd_soc_update_bits(codec, WM8900_REG_CLOCKING2,
- WM8900_REG_CLOCKING2_DAC_CLKDIV, div);
- break;
- case WM8900_ADC_CLKDIV:
- snd_soc_update_bits(codec, WM8900_REG_CLOCKING2,
- WM8900_REG_CLOCKING2_ADC_CLKDIV, div);
- break;
- case WM8900_LRCLK_MODE:
- snd_soc_update_bits(codec, WM8900_REG_DACCTRL,
- WM8900_REG_DACCTRL_AIF_LRCLKRATE, div);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-
-static int wm8900_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- unsigned int clocking1, aif1, aif3, aif4;
-
- clocking1 = snd_soc_read(codec, WM8900_REG_CLOCKING1);
- aif1 = snd_soc_read(codec, WM8900_REG_AUDIO1);
- aif3 = snd_soc_read(codec, WM8900_REG_AUDIO3);
- aif4 = snd_soc_read(codec, WM8900_REG_AUDIO4);
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- clocking1 &= ~WM8900_REG_CLOCKING1_BCLK_DIR;
- aif3 &= ~WM8900_REG_AUDIO3_ADCLRC_DIR;
- aif4 &= ~WM8900_REG_AUDIO4_DACLRC_DIR;
- break;
- case SND_SOC_DAIFMT_CBS_CFM:
- clocking1 &= ~WM8900_REG_CLOCKING1_BCLK_DIR;
- aif3 |= WM8900_REG_AUDIO3_ADCLRC_DIR;
- aif4 |= WM8900_REG_AUDIO4_DACLRC_DIR;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- clocking1 |= WM8900_REG_CLOCKING1_BCLK_DIR;
- aif3 |= WM8900_REG_AUDIO3_ADCLRC_DIR;
- aif4 |= WM8900_REG_AUDIO4_DACLRC_DIR;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- clocking1 |= WM8900_REG_CLOCKING1_BCLK_DIR;
- aif3 &= ~WM8900_REG_AUDIO3_ADCLRC_DIR;
- aif4 &= ~WM8900_REG_AUDIO4_DACLRC_DIR;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- aif1 |= WM8900_REG_AUDIO1_AIF_FMT_MASK;
- aif1 &= ~WM8900_REG_AUDIO1_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- aif1 |= WM8900_REG_AUDIO1_AIF_FMT_MASK;
- aif1 |= WM8900_REG_AUDIO1_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_I2S:
- aif1 &= ~WM8900_REG_AUDIO1_AIF_FMT_MASK;
- aif1 |= 0x10;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- aif1 &= ~WM8900_REG_AUDIO1_AIF_FMT_MASK;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- aif1 &= ~WM8900_REG_AUDIO1_AIF_FMT_MASK;
- aif1 |= 0x8;
- break;
- default:
- return -EINVAL;
- }
-
- /* Clock inversion */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- case SND_SOC_DAIFMT_DSP_B:
- /* frame inversion not valid for DSP modes */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- aif1 &= ~WM8900_REG_AUDIO1_BCLK_INV;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- aif1 |= WM8900_REG_AUDIO1_BCLK_INV;
- break;
- default:
- return -EINVAL;
- }
- break;
- case SND_SOC_DAIFMT_I2S:
- case SND_SOC_DAIFMT_RIGHT_J:
- case SND_SOC_DAIFMT_LEFT_J:
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- aif1 &= ~WM8900_REG_AUDIO1_BCLK_INV;
- aif1 &= ~WM8900_REG_AUDIO1_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_IB_IF:
- aif1 |= WM8900_REG_AUDIO1_BCLK_INV;
- aif1 |= WM8900_REG_AUDIO1_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- aif1 |= WM8900_REG_AUDIO1_BCLK_INV;
- aif1 &= ~WM8900_REG_AUDIO1_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- aif1 &= ~WM8900_REG_AUDIO1_BCLK_INV;
- aif1 |= WM8900_REG_AUDIO1_LRCLK_INV;
- break;
- default:
- return -EINVAL;
- }
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM8900_REG_CLOCKING1, clocking1);
- snd_soc_write(codec, WM8900_REG_AUDIO1, aif1);
- snd_soc_write(codec, WM8900_REG_AUDIO3, aif3);
- snd_soc_write(codec, WM8900_REG_AUDIO4, aif4);
-
- return 0;
-}
-
-static int wm8900_digital_mute(struct snd_soc_dai *codec_dai, int mute)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 reg;
-
- reg = snd_soc_read(codec, WM8900_REG_DACCTRL);
-
- if (mute)
- reg |= WM8900_REG_DACCTRL_MUTE;
- else
- reg &= ~WM8900_REG_DACCTRL_MUTE;
-
- snd_soc_write(codec, WM8900_REG_DACCTRL, reg);
-
- return 0;
-}
-
-#define WM8900_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
-
-#define WM8900_PCM_FORMATS \
- (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \
- SNDRV_PCM_FORMAT_S24_LE)
-
-static const struct snd_soc_dai_ops wm8900_dai_ops = {
- .hw_params = wm8900_hw_params,
- .set_clkdiv = wm8900_set_dai_clkdiv,
- .set_pll = wm8900_set_dai_pll,
- .set_fmt = wm8900_set_dai_fmt,
- .digital_mute = wm8900_digital_mute,
-};
-
-static struct snd_soc_dai_driver wm8900_dai = {
- .name = "wm8900-hifi",
- .playback = {
- .stream_name = "HiFi Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8900_RATES,
- .formats = WM8900_PCM_FORMATS,
- },
- .capture = {
- .stream_name = "HiFi Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8900_RATES,
- .formats = WM8900_PCM_FORMATS,
- },
- .ops = &wm8900_dai_ops,
-};
-
-static int wm8900_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- u16 reg;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- /* Enable thermal shutdown */
- snd_soc_update_bits(codec, WM8900_REG_GPIO,
- WM8900_REG_GPIO_TEMP_ENA,
- WM8900_REG_GPIO_TEMP_ENA);
- snd_soc_update_bits(codec, WM8900_REG_ADDCTL,
- WM8900_REG_ADDCTL_TEMP_SD,
- WM8900_REG_ADDCTL_TEMP_SD);
- break;
-
- case SND_SOC_BIAS_PREPARE:
- break;
-
- case SND_SOC_BIAS_STANDBY:
- /* Charge capacitors if initial power up */
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- /* STARTUP_BIAS_ENA on */
- snd_soc_write(codec, WM8900_REG_POWER1,
- WM8900_REG_POWER1_STARTUP_BIAS_ENA);
-
- /* Startup bias mode */
- snd_soc_write(codec, WM8900_REG_ADDCTL,
- WM8900_REG_ADDCTL_BIAS_SRC |
- WM8900_REG_ADDCTL_VMID_SOFTST);
-
- /* VMID 2x50k */
- snd_soc_write(codec, WM8900_REG_POWER1,
- WM8900_REG_POWER1_STARTUP_BIAS_ENA | 0x1);
-
- /* Allow capacitors to charge */
- schedule_timeout_interruptible(msecs_to_jiffies(400));
-
- /* Enable bias */
- snd_soc_write(codec, WM8900_REG_POWER1,
- WM8900_REG_POWER1_STARTUP_BIAS_ENA |
- WM8900_REG_POWER1_BIAS_ENA | 0x1);
-
- snd_soc_write(codec, WM8900_REG_ADDCTL, 0);
-
- snd_soc_write(codec, WM8900_REG_POWER1,
- WM8900_REG_POWER1_BIAS_ENA | 0x1);
- }
-
- reg = snd_soc_read(codec, WM8900_REG_POWER1);
- snd_soc_write(codec, WM8900_REG_POWER1,
- (reg & WM8900_REG_POWER1_FLL_ENA) |
- WM8900_REG_POWER1_BIAS_ENA | 0x1);
- snd_soc_write(codec, WM8900_REG_POWER2,
- WM8900_REG_POWER2_SYSCLK_ENA);
- snd_soc_write(codec, WM8900_REG_POWER3, 0);
- break;
-
- case SND_SOC_BIAS_OFF:
- /* Startup bias enable */
- reg = snd_soc_read(codec, WM8900_REG_POWER1);
- snd_soc_write(codec, WM8900_REG_POWER1,
- reg & WM8900_REG_POWER1_STARTUP_BIAS_ENA);
- snd_soc_write(codec, WM8900_REG_ADDCTL,
- WM8900_REG_ADDCTL_BIAS_SRC |
- WM8900_REG_ADDCTL_VMID_SOFTST);
-
- /* Discharge caps */
- snd_soc_write(codec, WM8900_REG_POWER1,
- WM8900_REG_POWER1_STARTUP_BIAS_ENA);
- schedule_timeout_interruptible(msecs_to_jiffies(500));
-
- /* Remove clamp */
- snd_soc_write(codec, WM8900_REG_HPCTL1, 0);
-
- /* Power down */
- snd_soc_write(codec, WM8900_REG_ADDCTL, 0);
- snd_soc_write(codec, WM8900_REG_POWER1, 0);
- snd_soc_write(codec, WM8900_REG_POWER2, 0);
- snd_soc_write(codec, WM8900_REG_POWER3, 0);
-
- /* Need to let things settle before stopping the clock
- * to ensure that restart works, see "Stopping the
- * master clock" in the datasheet. */
- schedule_timeout_interruptible(msecs_to_jiffies(1));
- snd_soc_write(codec, WM8900_REG_POWER2,
- WM8900_REG_POWER2_SYSCLK_ENA);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-static int wm8900_suspend(struct snd_soc_codec *codec)
-{
- struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
- int fll_out = wm8900->fll_out;
- int fll_in = wm8900->fll_in;
- int ret;
-
- /* Stop the FLL in an orderly fashion */
- ret = wm8900_set_fll(codec, 0, 0, 0);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to stop FLL\n");
- return ret;
- }
-
- wm8900->fll_out = fll_out;
- wm8900->fll_in = fll_in;
-
- wm8900_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int wm8900_resume(struct snd_soc_codec *codec)
-{
- struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
- u16 *cache;
- int i, ret;
-
- cache = kmemdup(codec->reg_cache, sizeof(wm8900_reg_defaults),
- GFP_KERNEL);
-
- wm8900_reset(codec);
- wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* Restart the FLL? */
- if (wm8900->fll_out) {
- int fll_out = wm8900->fll_out;
- int fll_in = wm8900->fll_in;
-
- wm8900->fll_in = 0;
- wm8900->fll_out = 0;
-
- ret = wm8900_set_fll(codec, 0, fll_in, fll_out);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to restart FLL\n");
- kfree(cache);
- return ret;
- }
- }
-
- if (cache) {
- for (i = 0; i < WM8900_MAXREG; i++)
- snd_soc_write(codec, i, cache[i]);
- kfree(cache);
- } else
- dev_err(codec->dev, "Unable to allocate register cache\n");
-
- return 0;
-}
-
-static int wm8900_probe(struct snd_soc_codec *codec)
-{
- struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
- int ret = 0, reg;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8900->control_type);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- reg = snd_soc_read(codec, WM8900_REG_ID);
- if (reg != 0x8900) {
- dev_err(codec->dev, "Device is not a WM8900 - ID %x\n", reg);
- return -ENODEV;
- }
-
- wm8900_reset(codec);
-
- /* Turn the chip on */
- wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* Latch the volume update bits */
- snd_soc_update_bits(codec, WM8900_REG_LINVOL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8900_REG_RINVOL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8900_REG_LOUT1CTL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8900_REG_ROUT1CTL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8900_REG_LOUT2CTL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8900_REG_ROUT2CTL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8900_REG_LDAC_DV, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8900_REG_RDAC_DV, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8900_REG_LADC_DV, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8900_REG_RADC_DV, 0x100, 0x100);
-
- /* Set the DAC and mixer output bias */
- snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
-
- return 0;
-}
-
-/* power down chip */
-static int wm8900_remove(struct snd_soc_codec *codec)
-{
- wm8900_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8900 = {
- .probe = wm8900_probe,
- .remove = wm8900_remove,
- .suspend = wm8900_suspend,
- .resume = wm8900_resume,
- .set_bias_level = wm8900_set_bias_level,
- .volatile_register = wm8900_volatile_register,
- .reg_cache_size = ARRAY_SIZE(wm8900_reg_defaults),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8900_reg_defaults,
-
- .controls = wm8900_snd_controls,
- .num_controls = ARRAY_SIZE(wm8900_snd_controls),
- .dapm_widgets = wm8900_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8900_dapm_widgets),
- .dapm_routes = wm8900_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm8900_dapm_routes),
-};
-
-#if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8900_spi_probe(struct spi_device *spi)
-{
- struct wm8900_priv *wm8900;
- int ret;
-
- wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
- if (wm8900 == NULL)
- return -ENOMEM;
-
- wm8900->control_type = SND_SOC_SPI;
- spi_set_drvdata(spi, wm8900);
-
- ret = snd_soc_register_codec(&spi->dev,
- &soc_codec_dev_wm8900, &wm8900_dai, 1);
- if (ret < 0)
- kfree(wm8900);
- return ret;
-}
-
-static int __devexit wm8900_spi_remove(struct spi_device *spi)
-{
- snd_soc_unregister_codec(&spi->dev);
- kfree(spi_get_drvdata(spi));
- return 0;
-}
-
-static struct spi_driver wm8900_spi_driver = {
- .driver = {
- .name = "wm8900",
- .owner = THIS_MODULE,
- },
- .probe = wm8900_spi_probe,
- .remove = __devexit_p(wm8900_spi_remove),
-};
-#endif /* CONFIG_SPI_MASTER */
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8900_priv *wm8900;
- int ret;
-
- wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
- if (wm8900 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm8900);
- wm8900->control_type = SND_SOC_I2C;
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8900, &wm8900_dai, 1);
- if (ret < 0)
- kfree(wm8900);
- return ret;
-}
-
-static __devexit int wm8900_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-static const struct i2c_device_id wm8900_i2c_id[] = {
- { "wm8900", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8900_i2c_id);
-
-static struct i2c_driver wm8900_i2c_driver = {
- .driver = {
- .name = "wm8900",
- .owner = THIS_MODULE,
- },
- .probe = wm8900_i2c_probe,
- .remove = __devexit_p(wm8900_i2c_remove),
- .id_table = wm8900_i2c_id,
-};
-#endif
-
-static int __init wm8900_modinit(void)
-{
- int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&wm8900_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8900 I2C driver: %d\n",
- ret);
- }
-#endif
-#if defined(CONFIG_SPI_MASTER)
- ret = spi_register_driver(&wm8900_spi_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8900 SPI driver: %d\n",
- ret);
- }
-#endif
- return ret;
-}
-module_init(wm8900_modinit);
-
-static void __exit wm8900_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&wm8900_i2c_driver);
-#endif
-#if defined(CONFIG_SPI_MASTER)
- spi_unregister_driver(&wm8900_spi_driver);
-#endif
-}
-module_exit(wm8900_exit);
-
-MODULE_DESCRIPTION("ASoC WM8900 driver");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8900.h b/ANDROID_3.4.5/sound/soc/codecs/wm8900.h
deleted file mode 100644
index 583f257e..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8900.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * wm8900.h -- WM890 Soc Audio driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8900_H
-#define _WM8900_H
-
-#define WM8900_FLL 1
-
-#define WM8900_BCLK_DIV 1
-#define WM8900_ADC_CLKDIV 2
-#define WM8900_DAC_CLKDIV 3
-#define WM8900_ADC_LRCLK 4
-#define WM8900_DAC_LRCLK 5
-#define WM8900_OPCLK_DIV 6
-#define WM8900_LRCLK_MODE 7
-
-#define WM8900_BCLK_DIV_1 0x00
-#define WM8900_BCLK_DIV_1_5 0x02
-#define WM8900_BCLK_DIV_2 0x04
-#define WM8900_BCLK_DIV_3 0x06
-#define WM8900_BCLK_DIV_4 0x08
-#define WM8900_BCLK_DIV_5_5 0x0a
-#define WM8900_BCLK_DIV_6 0x0c
-#define WM8900_BCLK_DIV_8 0x0e
-#define WM8900_BCLK_DIV_11 0x10
-#define WM8900_BCLK_DIV_12 0x12
-#define WM8900_BCLK_DIV_16 0x14
-#define WM8900_BCLK_DIV_22 0x16
-#define WM8900_BCLK_DIV_24 0x18
-#define WM8900_BCLK_DIV_32 0x1a
-#define WM8900_BCLK_DIV_44 0x1c
-#define WM8900_BCLK_DIV_48 0x1e
-
-#define WM8900_ADC_CLKDIV_1 0x00
-#define WM8900_ADC_CLKDIV_1_5 0x20
-#define WM8900_ADC_CLKDIV_2 0x40
-#define WM8900_ADC_CLKDIV_3 0x60
-#define WM8900_ADC_CLKDIV_4 0x80
-#define WM8900_ADC_CLKDIV_5_5 0xa0
-#define WM8900_ADC_CLKDIV_6 0xc0
-
-#define WM8900_DAC_CLKDIV_1 0x00
-#define WM8900_DAC_CLKDIV_1_5 0x04
-#define WM8900_DAC_CLKDIV_2 0x08
-#define WM8900_DAC_CLKDIV_3 0x0c
-#define WM8900_DAC_CLKDIV_4 0x10
-#define WM8900_DAC_CLKDIV_5_5 0x14
-#define WM8900_DAC_CLKDIV_6 0x18
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8903.c b/ANDROID_3.4.5/sound/soc/codecs/wm8903.c
deleted file mode 100644
index c91fb2f9..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8903.c
+++ /dev/null
@@ -1,2257 +0,0 @@
-/*
- * wm8903.c -- WM8903 ALSA SoC Audio driver
- *
- * Copyright 2008 Wolfson Microelectronics
- * Copyright 2011 NVIDIA, Inc.
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * TODO:
- * - TDM mode configuration.
- * - Digital microphone support.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/completion.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/regmap.h>
-#include <linux/slab.h>
-#include <linux/irq.h>
-#include <sound/core.h>
-#include <sound/jack.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/tlv.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/wm8903.h>
-#include <trace/events/asoc.h>
-
-#include "wm8903.h"
-
-/* Register defaults at reset */
-static const struct reg_default wm8903_reg_defaults[] = {
- { 4, 0x0018 }, /* R4 - Bias Control 0 */
- { 5, 0x0000 }, /* R5 - VMID Control 0 */
- { 6, 0x0000 }, /* R6 - Mic Bias Control 0 */
- { 8, 0x0001 }, /* R8 - Analogue DAC 0 */
- { 10, 0x0001 }, /* R10 - Analogue ADC 0 */
- { 12, 0x0000 }, /* R12 - Power Management 0 */
- { 13, 0x0000 }, /* R13 - Power Management 1 */
- { 14, 0x0000 }, /* R14 - Power Management 2 */
- { 15, 0x0000 }, /* R15 - Power Management 3 */
- { 16, 0x0000 }, /* R16 - Power Management 4 */
- { 17, 0x0000 }, /* R17 - Power Management 5 */
- { 18, 0x0000 }, /* R18 - Power Management 6 */
- { 20, 0x0400 }, /* R20 - Clock Rates 0 */
- { 21, 0x0D07 }, /* R21 - Clock Rates 1 */
- { 22, 0x0000 }, /* R22 - Clock Rates 2 */
- { 24, 0x0050 }, /* R24 - Audio Interface 0 */
- { 25, 0x0242 }, /* R25 - Audio Interface 1 */
- { 26, 0x0008 }, /* R26 - Audio Interface 2 */
- { 27, 0x0022 }, /* R27 - Audio Interface 3 */
- { 30, 0x00C0 }, /* R30 - DAC Digital Volume Left */
- { 31, 0x00C0 }, /* R31 - DAC Digital Volume Right */
- { 32, 0x0000 }, /* R32 - DAC Digital 0 */
- { 33, 0x0000 }, /* R33 - DAC Digital 1 */
- { 36, 0x00C0 }, /* R36 - ADC Digital Volume Left */
- { 37, 0x00C0 }, /* R37 - ADC Digital Volume Right */
- { 38, 0x0000 }, /* R38 - ADC Digital 0 */
- { 39, 0x0073 }, /* R39 - Digital Microphone 0 */
- { 40, 0x09BF }, /* R40 - DRC 0 */
- { 41, 0x3241 }, /* R41 - DRC 1 */
- { 42, 0x0020 }, /* R42 - DRC 2 */
- { 43, 0x0000 }, /* R43 - DRC 3 */
- { 44, 0x0085 }, /* R44 - Analogue Left Input 0 */
- { 45, 0x0085 }, /* R45 - Analogue Right Input 0 */
- { 46, 0x0044 }, /* R46 - Analogue Left Input 1 */
- { 47, 0x0044 }, /* R47 - Analogue Right Input 1 */
- { 50, 0x0008 }, /* R50 - Analogue Left Mix 0 */
- { 51, 0x0004 }, /* R51 - Analogue Right Mix 0 */
- { 52, 0x0000 }, /* R52 - Analogue Spk Mix Left 0 */
- { 53, 0x0000 }, /* R53 - Analogue Spk Mix Left 1 */
- { 54, 0x0000 }, /* R54 - Analogue Spk Mix Right 0 */
- { 55, 0x0000 }, /* R55 - Analogue Spk Mix Right 1 */
- { 57, 0x002D }, /* R57 - Analogue OUT1 Left */
- { 58, 0x002D }, /* R58 - Analogue OUT1 Right */
- { 59, 0x0039 }, /* R59 - Analogue OUT2 Left */
- { 60, 0x0039 }, /* R60 - Analogue OUT2 Right */
- { 62, 0x0139 }, /* R62 - Analogue OUT3 Left */
- { 63, 0x0139 }, /* R63 - Analogue OUT3 Right */
- { 64, 0x0000 }, /* R65 - Analogue SPK Output Control 0 */
- { 67, 0x0010 }, /* R67 - DC Servo 0 */
- { 69, 0x00A4 }, /* R69 - DC Servo 2 */
- { 90, 0x0000 }, /* R90 - Analogue HP 0 */
- { 94, 0x0000 }, /* R94 - Analogue Lineout 0 */
- { 98, 0x0000 }, /* R98 - Charge Pump 0 */
- { 104, 0x0000 }, /* R104 - Class W 0 */
- { 108, 0x0000 }, /* R108 - Write Sequencer 0 */
- { 109, 0x0000 }, /* R109 - Write Sequencer 1 */
- { 110, 0x0000 }, /* R110 - Write Sequencer 2 */
- { 111, 0x0000 }, /* R111 - Write Sequencer 3 */
- { 112, 0x0000 }, /* R112 - Write Sequencer 4 */
- { 114, 0x0000 }, /* R114 - Control Interface */
- { 116, 0x00A8 }, /* R116 - GPIO Control 1 */
- { 117, 0x00A8 }, /* R117 - GPIO Control 2 */
- { 118, 0x00A8 }, /* R118 - GPIO Control 3 */
- { 119, 0x0220 }, /* R119 - GPIO Control 4 */
- { 120, 0x01A0 }, /* R120 - GPIO Control 5 */
- { 122, 0xFFFF }, /* R122 - Interrupt Status 1 Mask */
- { 123, 0x0000 }, /* R123 - Interrupt Polarity 1 */
- { 126, 0x0000 }, /* R126 - Interrupt Control */
- { 129, 0x0000 }, /* R129 - Control Interface Test 1 */
- { 149, 0x6810 }, /* R149 - Charge Pump Test 1 */
- { 164, 0x0028 }, /* R164 - Clock Rate Test 4 */
- { 172, 0x0000 }, /* R172 - Analogue Output Bias 0 */
-};
-
-struct wm8903_priv {
- struct wm8903_platform_data *pdata;
- struct snd_soc_codec *codec;
- struct regmap *regmap;
-
- int sysclk;
- int irq;
-
- int fs;
- int deemph;
-
- int dcs_pending;
- int dcs_cache[4];
-
- /* Reference count */
- int class_w_users;
-
- struct snd_soc_jack *mic_jack;
- int mic_det;
- int mic_short;
- int mic_last_report;
- int mic_delay;
-
-#ifdef CONFIG_GPIOLIB
- struct gpio_chip gpio_chip;
-#endif
-};
-
-static bool wm8903_readable_register(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM8903_SW_RESET_AND_ID:
- case WM8903_REVISION_NUMBER:
- case WM8903_BIAS_CONTROL_0:
- case WM8903_VMID_CONTROL_0:
- case WM8903_MIC_BIAS_CONTROL_0:
- case WM8903_ANALOGUE_DAC_0:
- case WM8903_ANALOGUE_ADC_0:
- case WM8903_POWER_MANAGEMENT_0:
- case WM8903_POWER_MANAGEMENT_1:
- case WM8903_POWER_MANAGEMENT_2:
- case WM8903_POWER_MANAGEMENT_3:
- case WM8903_POWER_MANAGEMENT_4:
- case WM8903_POWER_MANAGEMENT_5:
- case WM8903_POWER_MANAGEMENT_6:
- case WM8903_CLOCK_RATES_0:
- case WM8903_CLOCK_RATES_1:
- case WM8903_CLOCK_RATES_2:
- case WM8903_AUDIO_INTERFACE_0:
- case WM8903_AUDIO_INTERFACE_1:
- case WM8903_AUDIO_INTERFACE_2:
- case WM8903_AUDIO_INTERFACE_3:
- case WM8903_DAC_DIGITAL_VOLUME_LEFT:
- case WM8903_DAC_DIGITAL_VOLUME_RIGHT:
- case WM8903_DAC_DIGITAL_0:
- case WM8903_DAC_DIGITAL_1:
- case WM8903_ADC_DIGITAL_VOLUME_LEFT:
- case WM8903_ADC_DIGITAL_VOLUME_RIGHT:
- case WM8903_ADC_DIGITAL_0:
- case WM8903_DIGITAL_MICROPHONE_0:
- case WM8903_DRC_0:
- case WM8903_DRC_1:
- case WM8903_DRC_2:
- case WM8903_DRC_3:
- case WM8903_ANALOGUE_LEFT_INPUT_0:
- case WM8903_ANALOGUE_RIGHT_INPUT_0:
- case WM8903_ANALOGUE_LEFT_INPUT_1:
- case WM8903_ANALOGUE_RIGHT_INPUT_1:
- case WM8903_ANALOGUE_LEFT_MIX_0:
- case WM8903_ANALOGUE_RIGHT_MIX_0:
- case WM8903_ANALOGUE_SPK_MIX_LEFT_0:
- case WM8903_ANALOGUE_SPK_MIX_LEFT_1:
- case WM8903_ANALOGUE_SPK_MIX_RIGHT_0:
- case WM8903_ANALOGUE_SPK_MIX_RIGHT_1:
- case WM8903_ANALOGUE_OUT1_LEFT:
- case WM8903_ANALOGUE_OUT1_RIGHT:
- case WM8903_ANALOGUE_OUT2_LEFT:
- case WM8903_ANALOGUE_OUT2_RIGHT:
- case WM8903_ANALOGUE_OUT3_LEFT:
- case WM8903_ANALOGUE_OUT3_RIGHT:
- case WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0:
- case WM8903_DC_SERVO_0:
- case WM8903_DC_SERVO_2:
- case WM8903_DC_SERVO_READBACK_1:
- case WM8903_DC_SERVO_READBACK_2:
- case WM8903_DC_SERVO_READBACK_3:
- case WM8903_DC_SERVO_READBACK_4:
- case WM8903_ANALOGUE_HP_0:
- case WM8903_ANALOGUE_LINEOUT_0:
- case WM8903_CHARGE_PUMP_0:
- case WM8903_CLASS_W_0:
- case WM8903_WRITE_SEQUENCER_0:
- case WM8903_WRITE_SEQUENCER_1:
- case WM8903_WRITE_SEQUENCER_2:
- case WM8903_WRITE_SEQUENCER_3:
- case WM8903_WRITE_SEQUENCER_4:
- case WM8903_CONTROL_INTERFACE:
- case WM8903_GPIO_CONTROL_1:
- case WM8903_GPIO_CONTROL_2:
- case WM8903_GPIO_CONTROL_3:
- case WM8903_GPIO_CONTROL_4:
- case WM8903_GPIO_CONTROL_5:
- case WM8903_INTERRUPT_STATUS_1:
- case WM8903_INTERRUPT_STATUS_1_MASK:
- case WM8903_INTERRUPT_POLARITY_1:
- case WM8903_INTERRUPT_CONTROL:
- case WM8903_CLOCK_RATE_TEST_4:
- case WM8903_ANALOGUE_OUTPUT_BIAS_0:
- return true;
- default:
- return false;
- }
-}
-
-static bool wm8903_volatile_register(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM8903_SW_RESET_AND_ID:
- case WM8903_REVISION_NUMBER:
- case WM8903_INTERRUPT_STATUS_1:
- case WM8903_WRITE_SEQUENCER_4:
- case WM8903_DC_SERVO_READBACK_1:
- case WM8903_DC_SERVO_READBACK_2:
- case WM8903_DC_SERVO_READBACK_3:
- case WM8903_DC_SERVO_READBACK_4:
- return 1;
-
- default:
- return 0;
- }
-}
-
-static int wm8903_cp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- WARN_ON(event != SND_SOC_DAPM_POST_PMU);
- mdelay(4);
-
- return 0;
-}
-
-static int wm8903_dcs_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- wm8903->dcs_pending |= 1 << w->shift;
- break;
- case SND_SOC_DAPM_PRE_PMD:
- snd_soc_update_bits(codec, WM8903_DC_SERVO_0,
- 1 << w->shift, 0);
- break;
- }
-
- return 0;
-}
-
-#define WM8903_DCS_MODE_WRITE_STOP 0
-#define WM8903_DCS_MODE_START_STOP 2
-
-static void wm8903_seq_notifier(struct snd_soc_dapm_context *dapm,
- enum snd_soc_dapm_type event, int subseq)
-{
- struct snd_soc_codec *codec = container_of(dapm,
- struct snd_soc_codec, dapm);
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
- int dcs_mode = WM8903_DCS_MODE_WRITE_STOP;
- int i, val;
-
- /* Complete any pending DC servo starts */
- if (wm8903->dcs_pending) {
- dev_dbg(codec->dev, "Starting DC servo for %x\n",
- wm8903->dcs_pending);
-
- /* If we've no cached values then we need to do startup */
- for (i = 0; i < ARRAY_SIZE(wm8903->dcs_cache); i++) {
- if (!(wm8903->dcs_pending & (1 << i)))
- continue;
-
- if (wm8903->dcs_cache[i]) {
- dev_dbg(codec->dev,
- "Restore DC servo %d value %x\n",
- 3 - i, wm8903->dcs_cache[i]);
-
- snd_soc_write(codec, WM8903_DC_SERVO_4 + i,
- wm8903->dcs_cache[i] & 0xff);
- } else {
- dev_dbg(codec->dev,
- "Calibrate DC servo %d\n", 3 - i);
- dcs_mode = WM8903_DCS_MODE_START_STOP;
- }
- }
-
- /* Don't trust the cache for analogue */
- if (wm8903->class_w_users)
- dcs_mode = WM8903_DCS_MODE_START_STOP;
-
- snd_soc_update_bits(codec, WM8903_DC_SERVO_2,
- WM8903_DCS_MODE_MASK, dcs_mode);
-
- snd_soc_update_bits(codec, WM8903_DC_SERVO_0,
- WM8903_DCS_ENA_MASK, wm8903->dcs_pending);
-
- switch (dcs_mode) {
- case WM8903_DCS_MODE_WRITE_STOP:
- break;
-
- case WM8903_DCS_MODE_START_STOP:
- msleep(270);
-
- /* Cache the measured offsets for digital */
- if (wm8903->class_w_users)
- break;
-
- for (i = 0; i < ARRAY_SIZE(wm8903->dcs_cache); i++) {
- if (!(wm8903->dcs_pending & (1 << i)))
- continue;
-
- val = snd_soc_read(codec,
- WM8903_DC_SERVO_READBACK_1 + i);
- dev_dbg(codec->dev, "DC servo %d: %x\n",
- 3 - i, val);
- wm8903->dcs_cache[i] = val;
- }
- break;
-
- default:
- pr_warn("DCS mode %d delay not set\n", dcs_mode);
- break;
- }
-
- wm8903->dcs_pending = 0;
- }
-}
-
-/*
- * When used with DAC outputs only the WM8903 charge pump supports
- * operation in class W mode, providing very low power consumption
- * when used with digital sources. Enable and disable this mode
- * automatically depending on the mixer configuration.
- *
- * All the relevant controls are simple switches.
- */
-static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
- struct snd_soc_dapm_widget *widget = wlist->widgets[0];
- struct snd_soc_codec *codec = widget->codec;
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
- u16 reg;
- int ret;
-
- reg = snd_soc_read(codec, WM8903_CLASS_W_0);
-
- /* Turn it off if we're about to enable bypass */
- if (ucontrol->value.integer.value[0]) {
- if (wm8903->class_w_users == 0) {
- dev_dbg(codec->dev, "Disabling Class W\n");
- snd_soc_write(codec, WM8903_CLASS_W_0, reg &
- ~(WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V));
- }
- wm8903->class_w_users++;
- }
-
- /* Implement the change */
- ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
-
- /* If we've just disabled the last bypass path turn Class W on */
- if (!ucontrol->value.integer.value[0]) {
- if (wm8903->class_w_users == 1) {
- dev_dbg(codec->dev, "Enabling Class W\n");
- snd_soc_write(codec, WM8903_CLASS_W_0, reg |
- WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
- }
- wm8903->class_w_users--;
- }
-
- dev_dbg(codec->dev, "Bypass use count now %d\n",
- wm8903->class_w_users);
-
- return ret;
-}
-
-#define SOC_DAPM_SINGLE_W(xname, reg, shift, max, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_soc_info_volsw, \
- .get = snd_soc_dapm_get_volsw, .put = wm8903_class_w_put, \
- .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
-
-
-static int wm8903_deemph[] = { 0, 32000, 44100, 48000 };
-
-static int wm8903_set_deemph(struct snd_soc_codec *codec)
-{
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
- int val, i, best;
-
- /* If we're using deemphasis select the nearest available sample
- * rate.
- */
- if (wm8903->deemph) {
- best = 1;
- for (i = 2; i < ARRAY_SIZE(wm8903_deemph); i++) {
- if (abs(wm8903_deemph[i] - wm8903->fs) <
- abs(wm8903_deemph[best] - wm8903->fs))
- best = i;
- }
-
- val = best << WM8903_DEEMPH_SHIFT;
- } else {
- best = 0;
- val = 0;
- }
-
- dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n",
- best, wm8903_deemph[best]);
-
- return snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1,
- WM8903_DEEMPH_MASK, val);
-}
-
-static int wm8903_get_deemph(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.enumerated.item[0] = wm8903->deemph;
-
- return 0;
-}
-
-static int wm8903_put_deemph(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
- int deemph = ucontrol->value.enumerated.item[0];
- int ret = 0;
-
- if (deemph > 1)
- return -EINVAL;
-
- mutex_lock(&codec->mutex);
- if (wm8903->deemph != deemph) {
- wm8903->deemph = deemph;
-
- wm8903_set_deemph(codec);
-
- ret = 1;
- }
- mutex_unlock(&codec->mutex);
-
- return ret;
-}
-
-/* ALSA can only do steps of .01dB */
-static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
-
-static const DECLARE_TLV_DB_SCALE(digital_sidetone_tlv, -3600, 300, 0);
-static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
-
-static const DECLARE_TLV_DB_SCALE(drc_tlv_thresh, 0, 75, 0);
-static const DECLARE_TLV_DB_SCALE(drc_tlv_amp, -2250, 75, 0);
-static const DECLARE_TLV_DB_SCALE(drc_tlv_min, 0, 600, 0);
-static const DECLARE_TLV_DB_SCALE(drc_tlv_max, 1200, 600, 0);
-static const DECLARE_TLV_DB_SCALE(drc_tlv_startup, -300, 50, 0);
-
-static const char *hpf_mode_text[] = {
- "Hi-fi", "Voice 1", "Voice 2", "Voice 3"
-};
-
-static const struct soc_enum hpf_mode =
- SOC_ENUM_SINGLE(WM8903_ADC_DIGITAL_0, 5, 4, hpf_mode_text);
-
-static const char *osr_text[] = {
- "Low power", "High performance"
-};
-
-static const struct soc_enum adc_osr =
- SOC_ENUM_SINGLE(WM8903_ANALOGUE_ADC_0, 0, 2, osr_text);
-
-static const struct soc_enum dac_osr =
- SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 0, 2, osr_text);
-
-static const char *drc_slope_text[] = {
- "1", "1/2", "1/4", "1/8", "1/16", "0"
-};
-
-static const struct soc_enum drc_slope_r0 =
- SOC_ENUM_SINGLE(WM8903_DRC_2, 3, 6, drc_slope_text);
-
-static const struct soc_enum drc_slope_r1 =
- SOC_ENUM_SINGLE(WM8903_DRC_2, 0, 6, drc_slope_text);
-
-static const char *drc_attack_text[] = {
- "instantaneous",
- "363us", "762us", "1.45ms", "2.9ms", "5.8ms", "11.6ms", "23.2ms",
- "46.4ms", "92.8ms", "185.6ms"
-};
-
-static const struct soc_enum drc_attack =
- SOC_ENUM_SINGLE(WM8903_DRC_1, 12, 11, drc_attack_text);
-
-static const char *drc_decay_text[] = {
- "186ms", "372ms", "743ms", "1.49s", "2.97s", "5.94s", "11.89s",
- "23.87s", "47.56s"
-};
-
-static const struct soc_enum drc_decay =
- SOC_ENUM_SINGLE(WM8903_DRC_1, 8, 9, drc_decay_text);
-
-static const char *drc_ff_delay_text[] = {
- "5 samples", "9 samples"
-};
-
-static const struct soc_enum drc_ff_delay =
- SOC_ENUM_SINGLE(WM8903_DRC_0, 5, 2, drc_ff_delay_text);
-
-static const char *drc_qr_decay_text[] = {
- "0.725ms", "1.45ms", "5.8ms"
-};
-
-static const struct soc_enum drc_qr_decay =
- SOC_ENUM_SINGLE(WM8903_DRC_1, 4, 3, drc_qr_decay_text);
-
-static const char *drc_smoothing_text[] = {
- "Low", "Medium", "High"
-};
-
-static const struct soc_enum drc_smoothing =
- SOC_ENUM_SINGLE(WM8903_DRC_0, 11, 3, drc_smoothing_text);
-
-static const char *soft_mute_text[] = {
- "Fast (fs/2)", "Slow (fs/32)"
-};
-
-static const struct soc_enum soft_mute =
- SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 10, 2, soft_mute_text);
-
-static const char *mute_mode_text[] = {
- "Hard", "Soft"
-};
-
-static const struct soc_enum mute_mode =
- SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 9, 2, mute_mode_text);
-
-static const char *companding_text[] = {
- "ulaw", "alaw"
-};
-
-static const struct soc_enum dac_companding =
- SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 0, 2, companding_text);
-
-static const struct soc_enum adc_companding =
- SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 2, 2, companding_text);
-
-static const char *input_mode_text[] = {
- "Single-Ended", "Differential Line", "Differential Mic"
-};
-
-static const struct soc_enum linput_mode_enum =
- SOC_ENUM_SINGLE(WM8903_ANALOGUE_LEFT_INPUT_1, 0, 3, input_mode_text);
-
-static const struct soc_enum rinput_mode_enum =
- SOC_ENUM_SINGLE(WM8903_ANALOGUE_RIGHT_INPUT_1, 0, 3, input_mode_text);
-
-static const char *linput_mux_text[] = {
- "IN1L", "IN2L", "IN3L"
-};
-
-static const struct soc_enum linput_enum =
- SOC_ENUM_SINGLE(WM8903_ANALOGUE_LEFT_INPUT_1, 2, 3, linput_mux_text);
-
-static const struct soc_enum linput_inv_enum =
- SOC_ENUM_SINGLE(WM8903_ANALOGUE_LEFT_INPUT_1, 4, 3, linput_mux_text);
-
-static const char *rinput_mux_text[] = {
- "IN1R", "IN2R", "IN3R"
-};
-
-static const struct soc_enum rinput_enum =
- SOC_ENUM_SINGLE(WM8903_ANALOGUE_RIGHT_INPUT_1, 2, 3, rinput_mux_text);
-
-static const struct soc_enum rinput_inv_enum =
- SOC_ENUM_SINGLE(WM8903_ANALOGUE_RIGHT_INPUT_1, 4, 3, rinput_mux_text);
-
-
-static const char *sidetone_text[] = {
- "None", "Left", "Right"
-};
-
-static const struct soc_enum lsidetone_enum =
- SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 2, 3, sidetone_text);
-
-static const struct soc_enum rsidetone_enum =
- SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text);
-
-static const char *adcinput_text[] = {
- "ADC", "DMIC"
-};
-
-static const struct soc_enum adcinput_enum =
- SOC_ENUM_SINGLE(WM8903_CLOCK_RATE_TEST_4, 9, 2, adcinput_text);
-
-static const char *aif_text[] = {
- "Left", "Right"
-};
-
-static const struct soc_enum lcapture_enum =
- SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 7, 2, aif_text);
-
-static const struct soc_enum rcapture_enum =
- SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 6, 2, aif_text);
-
-static const struct soc_enum lplay_enum =
- SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 5, 2, aif_text);
-
-static const struct soc_enum rplay_enum =
- SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 4, 2, aif_text);
-
-static const struct snd_kcontrol_new wm8903_snd_controls[] = {
-
-/* Input PGAs - No TLV since the scale depends on PGA mode */
-SOC_SINGLE("Left Input PGA Switch", WM8903_ANALOGUE_LEFT_INPUT_0,
- 7, 1, 1),
-SOC_SINGLE("Left Input PGA Volume", WM8903_ANALOGUE_LEFT_INPUT_0,
- 0, 31, 0),
-SOC_SINGLE("Left Input PGA Common Mode Switch", WM8903_ANALOGUE_LEFT_INPUT_1,
- 6, 1, 0),
-
-SOC_SINGLE("Right Input PGA Switch", WM8903_ANALOGUE_RIGHT_INPUT_0,
- 7, 1, 1),
-SOC_SINGLE("Right Input PGA Volume", WM8903_ANALOGUE_RIGHT_INPUT_0,
- 0, 31, 0),
-SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1,
- 6, 1, 0),
-
-/* ADCs */
-SOC_ENUM("ADC OSR", adc_osr),
-SOC_SINGLE("HPF Switch", WM8903_ADC_DIGITAL_0, 4, 1, 0),
-SOC_ENUM("HPF Mode", hpf_mode),
-SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0),
-SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0),
-SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1),
-SOC_SINGLE_TLV("DRC Compressor Threshold Volume", WM8903_DRC_3, 5, 124, 1,
- drc_tlv_thresh),
-SOC_SINGLE_TLV("DRC Volume", WM8903_DRC_3, 0, 30, 1, drc_tlv_amp),
-SOC_SINGLE_TLV("DRC Minimum Gain Volume", WM8903_DRC_1, 2, 3, 1, drc_tlv_min),
-SOC_SINGLE_TLV("DRC Maximum Gain Volume", WM8903_DRC_1, 0, 3, 0, drc_tlv_max),
-SOC_ENUM("DRC Attack Rate", drc_attack),
-SOC_ENUM("DRC Decay Rate", drc_decay),
-SOC_ENUM("DRC FF Delay", drc_ff_delay),
-SOC_SINGLE("DRC Anticlip Switch", WM8903_DRC_0, 1, 1, 0),
-SOC_SINGLE("DRC QR Switch", WM8903_DRC_0, 2, 1, 0),
-SOC_SINGLE_TLV("DRC QR Threshold Volume", WM8903_DRC_0, 6, 3, 0, drc_tlv_max),
-SOC_ENUM("DRC QR Decay Rate", drc_qr_decay),
-SOC_SINGLE("DRC Smoothing Switch", WM8903_DRC_0, 3, 1, 0),
-SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8903_DRC_0, 0, 1, 0),
-SOC_ENUM("DRC Smoothing Threshold", drc_smoothing),
-SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup),
-
-SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT,
- WM8903_ADC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv),
-SOC_ENUM("ADC Companding Mode", adc_companding),
-SOC_SINGLE("ADC Companding Switch", WM8903_AUDIO_INTERFACE_0, 3, 1, 0),
-
-SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8903_DAC_DIGITAL_0, 4, 8,
- 12, 0, digital_sidetone_tlv),
-
-/* DAC */
-SOC_ENUM("DAC OSR", dac_osr),
-SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT,
- WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv),
-SOC_ENUM("DAC Soft Mute Rate", soft_mute),
-SOC_ENUM("DAC Mute Mode", mute_mode),
-SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0),
-SOC_ENUM("DAC Companding Mode", dac_companding),
-SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0),
-SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0,
- wm8903_get_deemph, wm8903_put_deemph),
-
-/* Headphones */
-SOC_DOUBLE_R("Headphone Switch",
- WM8903_ANALOGUE_OUT1_LEFT, WM8903_ANALOGUE_OUT1_RIGHT,
- 8, 1, 1),
-SOC_DOUBLE_R("Headphone ZC Switch",
- WM8903_ANALOGUE_OUT1_LEFT, WM8903_ANALOGUE_OUT1_RIGHT,
- 6, 1, 0),
-SOC_DOUBLE_R_TLV("Headphone Volume",
- WM8903_ANALOGUE_OUT1_LEFT, WM8903_ANALOGUE_OUT1_RIGHT,
- 0, 63, 0, out_tlv),
-
-/* Line out */
-SOC_DOUBLE_R("Line Out Switch",
- WM8903_ANALOGUE_OUT2_LEFT, WM8903_ANALOGUE_OUT2_RIGHT,
- 8, 1, 1),
-SOC_DOUBLE_R("Line Out ZC Switch",
- WM8903_ANALOGUE_OUT2_LEFT, WM8903_ANALOGUE_OUT2_RIGHT,
- 6, 1, 0),
-SOC_DOUBLE_R_TLV("Line Out Volume",
- WM8903_ANALOGUE_OUT2_LEFT, WM8903_ANALOGUE_OUT2_RIGHT,
- 0, 63, 0, out_tlv),
-
-/* Speaker */
-SOC_DOUBLE_R("Speaker Switch",
- WM8903_ANALOGUE_OUT3_LEFT, WM8903_ANALOGUE_OUT3_RIGHT, 8, 1, 1),
-SOC_DOUBLE_R("Speaker ZC Switch",
- WM8903_ANALOGUE_OUT3_LEFT, WM8903_ANALOGUE_OUT3_RIGHT, 6, 1, 0),
-SOC_DOUBLE_R_TLV("Speaker Volume",
- WM8903_ANALOGUE_OUT3_LEFT, WM8903_ANALOGUE_OUT3_RIGHT,
- 0, 63, 0, out_tlv),
-};
-
-static const struct snd_kcontrol_new linput_mode_mux =
- SOC_DAPM_ENUM("Left Input Mode Mux", linput_mode_enum);
-
-static const struct snd_kcontrol_new rinput_mode_mux =
- SOC_DAPM_ENUM("Right Input Mode Mux", rinput_mode_enum);
-
-static const struct snd_kcontrol_new linput_mux =
- SOC_DAPM_ENUM("Left Input Mux", linput_enum);
-
-static const struct snd_kcontrol_new linput_inv_mux =
- SOC_DAPM_ENUM("Left Inverting Input Mux", linput_inv_enum);
-
-static const struct snd_kcontrol_new rinput_mux =
- SOC_DAPM_ENUM("Right Input Mux", rinput_enum);
-
-static const struct snd_kcontrol_new rinput_inv_mux =
- SOC_DAPM_ENUM("Right Inverting Input Mux", rinput_inv_enum);
-
-static const struct snd_kcontrol_new lsidetone_mux =
- SOC_DAPM_ENUM("DACL Sidetone Mux", lsidetone_enum);
-
-static const struct snd_kcontrol_new rsidetone_mux =
- SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum);
-
-static const struct snd_kcontrol_new adcinput_mux =
- SOC_DAPM_ENUM("ADC Input", adcinput_enum);
-
-static const struct snd_kcontrol_new lcapture_mux =
- SOC_DAPM_ENUM("Left Capture Mux", lcapture_enum);
-
-static const struct snd_kcontrol_new rcapture_mux =
- SOC_DAPM_ENUM("Right Capture Mux", rcapture_enum);
-
-static const struct snd_kcontrol_new lplay_mux =
- SOC_DAPM_ENUM("Left Playback Mux", lplay_enum);
-
-static const struct snd_kcontrol_new rplay_mux =
- SOC_DAPM_ENUM("Right Playback Mux", rplay_enum);
-
-static const struct snd_kcontrol_new left_output_mixer[] = {
-SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0),
-SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0),
-SOC_DAPM_SINGLE_W("Left Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 1, 1, 0),
-SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new right_output_mixer[] = {
-SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 3, 1, 0),
-SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 2, 1, 0),
-SOC_DAPM_SINGLE_W("Left Bypass Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 1, 1, 0),
-SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new left_speaker_mixer[] = {
-SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 3, 1, 0),
-SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 2, 1, 0),
-SOC_DAPM_SINGLE("Left Bypass Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 1, 1, 0),
-SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new right_speaker_mixer[] = {
-SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0, 3, 1, 0),
-SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0, 2, 1, 0),
-SOC_DAPM_SINGLE("Left Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0,
- 1, 1, 0),
-SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0,
- 0, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget wm8903_dapm_widgets[] = {
-SND_SOC_DAPM_INPUT("IN1L"),
-SND_SOC_DAPM_INPUT("IN1R"),
-SND_SOC_DAPM_INPUT("IN2L"),
-SND_SOC_DAPM_INPUT("IN2R"),
-SND_SOC_DAPM_INPUT("IN3L"),
-SND_SOC_DAPM_INPUT("IN3R"),
-SND_SOC_DAPM_INPUT("DMICDAT"),
-
-SND_SOC_DAPM_OUTPUT("HPOUTL"),
-SND_SOC_DAPM_OUTPUT("HPOUTR"),
-SND_SOC_DAPM_OUTPUT("LINEOUTL"),
-SND_SOC_DAPM_OUTPUT("LINEOUTR"),
-SND_SOC_DAPM_OUTPUT("LOP"),
-SND_SOC_DAPM_OUTPUT("LON"),
-SND_SOC_DAPM_OUTPUT("ROP"),
-SND_SOC_DAPM_OUTPUT("RON"),
-
-SND_SOC_DAPM_SUPPLY("MICBIAS", WM8903_MIC_BIAS_CONTROL_0, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_MUX("Left Input Mux", SND_SOC_NOPM, 0, 0, &linput_mux),
-SND_SOC_DAPM_MUX("Left Input Inverting Mux", SND_SOC_NOPM, 0, 0,
- &linput_inv_mux),
-SND_SOC_DAPM_MUX("Left Input Mode Mux", SND_SOC_NOPM, 0, 0, &linput_mode_mux),
-
-SND_SOC_DAPM_MUX("Right Input Mux", SND_SOC_NOPM, 0, 0, &rinput_mux),
-SND_SOC_DAPM_MUX("Right Input Inverting Mux", SND_SOC_NOPM, 0, 0,
- &rinput_inv_mux),
-SND_SOC_DAPM_MUX("Right Input Mode Mux", SND_SOC_NOPM, 0, 0, &rinput_mode_mux),
-
-SND_SOC_DAPM_PGA("Left Input PGA", WM8903_POWER_MANAGEMENT_0, 1, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_MUX("Left ADC Input", SND_SOC_NOPM, 0, 0, &adcinput_mux),
-SND_SOC_DAPM_MUX("Right ADC Input", SND_SOC_NOPM, 0, 0, &adcinput_mux),
-
-SND_SOC_DAPM_ADC("ADCL", NULL, WM8903_POWER_MANAGEMENT_6, 1, 0),
-SND_SOC_DAPM_ADC("ADCR", NULL, WM8903_POWER_MANAGEMENT_6, 0, 0),
-
-SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lcapture_mux),
-SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rcapture_mux),
-
-SND_SOC_DAPM_AIF_OUT("AIFTXL", "Left HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_AIF_OUT("AIFTXR", "Right HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
-
-SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &lsidetone_mux),
-SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &rsidetone_mux),
-
-SND_SOC_DAPM_AIF_IN("AIFRXL", "Left Playback", 0, SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_AIF_IN("AIFRXR", "Right Playback", 0, SND_SOC_NOPM, 0, 0),
-
-SND_SOC_DAPM_MUX("Left Playback Mux", SND_SOC_NOPM, 0, 0, &lplay_mux),
-SND_SOC_DAPM_MUX("Right Playback Mux", SND_SOC_NOPM, 0, 0, &rplay_mux),
-
-SND_SOC_DAPM_DAC("DACL", NULL, WM8903_POWER_MANAGEMENT_6, 3, 0),
-SND_SOC_DAPM_DAC("DACR", NULL, WM8903_POWER_MANAGEMENT_6, 2, 0),
-
-SND_SOC_DAPM_MIXER("Left Output Mixer", WM8903_POWER_MANAGEMENT_1, 1, 0,
- left_output_mixer, ARRAY_SIZE(left_output_mixer)),
-SND_SOC_DAPM_MIXER("Right Output Mixer", WM8903_POWER_MANAGEMENT_1, 0, 0,
- right_output_mixer, ARRAY_SIZE(right_output_mixer)),
-
-SND_SOC_DAPM_MIXER("Left Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 1, 0,
- left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
-SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0,
- right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
-
-SND_SOC_DAPM_PGA_S("Left Headphone Output PGA", 0, WM8903_POWER_MANAGEMENT_2,
- 1, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("Right Headphone Output PGA", 0, WM8903_POWER_MANAGEMENT_2,
- 0, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA_S("Left Line Output PGA", 0, WM8903_POWER_MANAGEMENT_3, 1, 0,
- NULL, 0),
-SND_SOC_DAPM_PGA_S("Right Line Output PGA", 0, WM8903_POWER_MANAGEMENT_3, 0, 0,
- NULL, 0),
-
-SND_SOC_DAPM_PGA_S("HPL_RMV_SHORT", 4, WM8903_ANALOGUE_HP_0, 7, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPL_ENA_OUTP", 3, WM8903_ANALOGUE_HP_0, 6, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPL_ENA_DLY", 2, WM8903_ANALOGUE_HP_0, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPL_ENA", 1, WM8903_ANALOGUE_HP_0, 4, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPR_RMV_SHORT", 4, WM8903_ANALOGUE_HP_0, 3, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPR_ENA_OUTP", 3, WM8903_ANALOGUE_HP_0, 2, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPR_ENA_DLY", 2, WM8903_ANALOGUE_HP_0, 1, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPR_ENA", 1, WM8903_ANALOGUE_HP_0, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA_S("LINEOUTL_RMV_SHORT", 4, WM8903_ANALOGUE_LINEOUT_0, 7, 0,
- NULL, 0),
-SND_SOC_DAPM_PGA_S("LINEOUTL_ENA_OUTP", 3, WM8903_ANALOGUE_LINEOUT_0, 6, 0,
- NULL, 0),
-SND_SOC_DAPM_PGA_S("LINEOUTL_ENA_DLY", 2, WM8903_ANALOGUE_LINEOUT_0, 5, 0,
- NULL, 0),
-SND_SOC_DAPM_PGA_S("LINEOUTL_ENA", 1, WM8903_ANALOGUE_LINEOUT_0, 4, 0,
- NULL, 0),
-SND_SOC_DAPM_PGA_S("LINEOUTR_RMV_SHORT", 4, WM8903_ANALOGUE_LINEOUT_0, 3, 0,
- NULL, 0),
-SND_SOC_DAPM_PGA_S("LINEOUTR_ENA_OUTP", 3, WM8903_ANALOGUE_LINEOUT_0, 2, 0,
- NULL, 0),
-SND_SOC_DAPM_PGA_S("LINEOUTR_ENA_DLY", 2, WM8903_ANALOGUE_LINEOUT_0, 1, 0,
- NULL, 0),
-SND_SOC_DAPM_PGA_S("LINEOUTR_ENA", 1, WM8903_ANALOGUE_LINEOUT_0, 0, 0,
- NULL, 0),
-
-SND_SOC_DAPM_SUPPLY("DCS Master", WM8903_DC_SERVO_0, 4, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPL_DCS", 3, SND_SOC_NOPM, 3, 0, wm8903_dcs_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-SND_SOC_DAPM_PGA_S("HPR_DCS", 3, SND_SOC_NOPM, 2, 0, wm8903_dcs_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-SND_SOC_DAPM_PGA_S("LINEOUTL_DCS", 3, SND_SOC_NOPM, 1, 0, wm8903_dcs_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-SND_SOC_DAPM_PGA_S("LINEOUTR_DCS", 3, SND_SOC_NOPM, 0, 0, wm8903_dcs_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-
-SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0,
- NULL, 0),
-SND_SOC_DAPM_PGA("Right Speaker PGA", WM8903_POWER_MANAGEMENT_5, 0, 0,
- NULL, 0),
-
-SND_SOC_DAPM_SUPPLY("Charge Pump", WM8903_CHARGE_PUMP_0, 0, 0,
- wm8903_cp_event, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8903_CLOCK_RATES_2, 2, 0, NULL, 0),
-};
-
-static const struct snd_soc_dapm_route wm8903_intercon[] = {
-
- { "CLK_DSP", NULL, "CLK_SYS" },
- { "MICBIAS", NULL, "CLK_SYS" },
- { "HPL_DCS", NULL, "CLK_SYS" },
- { "HPR_DCS", NULL, "CLK_SYS" },
- { "LINEOUTL_DCS", NULL, "CLK_SYS" },
- { "LINEOUTR_DCS", NULL, "CLK_SYS" },
-
- { "Left Input Mux", "IN1L", "IN1L" },
- { "Left Input Mux", "IN2L", "IN2L" },
- { "Left Input Mux", "IN3L", "IN3L" },
-
- { "Left Input Inverting Mux", "IN1L", "IN1L" },
- { "Left Input Inverting Mux", "IN2L", "IN2L" },
- { "Left Input Inverting Mux", "IN3L", "IN3L" },
-
- { "Right Input Mux", "IN1R", "IN1R" },
- { "Right Input Mux", "IN2R", "IN2R" },
- { "Right Input Mux", "IN3R", "IN3R" },
-
- { "Right Input Inverting Mux", "IN1R", "IN1R" },
- { "Right Input Inverting Mux", "IN2R", "IN2R" },
- { "Right Input Inverting Mux", "IN3R", "IN3R" },
-
- { "Left Input Mode Mux", "Single-Ended", "Left Input Inverting Mux" },
- { "Left Input Mode Mux", "Differential Line",
- "Left Input Mux" },
- { "Left Input Mode Mux", "Differential Line",
- "Left Input Inverting Mux" },
- { "Left Input Mode Mux", "Differential Mic",
- "Left Input Mux" },
- { "Left Input Mode Mux", "Differential Mic",
- "Left Input Inverting Mux" },
-
- { "Right Input Mode Mux", "Single-Ended",
- "Right Input Inverting Mux" },
- { "Right Input Mode Mux", "Differential Line",
- "Right Input Mux" },
- { "Right Input Mode Mux", "Differential Line",
- "Right Input Inverting Mux" },
- { "Right Input Mode Mux", "Differential Mic",
- "Right Input Mux" },
- { "Right Input Mode Mux", "Differential Mic",
- "Right Input Inverting Mux" },
-
- { "Left Input PGA", NULL, "Left Input Mode Mux" },
- { "Right Input PGA", NULL, "Right Input Mode Mux" },
-
- { "Left ADC Input", "ADC", "Left Input PGA" },
- { "Left ADC Input", "DMIC", "DMICDAT" },
- { "Right ADC Input", "ADC", "Right Input PGA" },
- { "Right ADC Input", "DMIC", "DMICDAT" },
-
- { "Left Capture Mux", "Left", "ADCL" },
- { "Left Capture Mux", "Right", "ADCR" },
-
- { "Right Capture Mux", "Left", "ADCL" },
- { "Right Capture Mux", "Right", "ADCR" },
-
- { "AIFTXL", NULL, "Left Capture Mux" },
- { "AIFTXR", NULL, "Right Capture Mux" },
-
- { "ADCL", NULL, "Left ADC Input" },
- { "ADCL", NULL, "CLK_DSP" },
- { "ADCR", NULL, "Right ADC Input" },
- { "ADCR", NULL, "CLK_DSP" },
-
- { "Left Playback Mux", "Left", "AIFRXL" },
- { "Left Playback Mux", "Right", "AIFRXR" },
-
- { "Right Playback Mux", "Left", "AIFRXL" },
- { "Right Playback Mux", "Right", "AIFRXR" },
-
- { "DACL Sidetone", "Left", "ADCL" },
- { "DACL Sidetone", "Right", "ADCR" },
- { "DACR Sidetone", "Left", "ADCL" },
- { "DACR Sidetone", "Right", "ADCR" },
-
- { "DACL", NULL, "Left Playback Mux" },
- { "DACL", NULL, "DACL Sidetone" },
- { "DACL", NULL, "CLK_DSP" },
-
- { "DACR", NULL, "Right Playback Mux" },
- { "DACR", NULL, "DACR Sidetone" },
- { "DACR", NULL, "CLK_DSP" },
-
- { "Left Output Mixer", "Left Bypass Switch", "Left Input PGA" },
- { "Left Output Mixer", "Right Bypass Switch", "Right Input PGA" },
- { "Left Output Mixer", "DACL Switch", "DACL" },
- { "Left Output Mixer", "DACR Switch", "DACR" },
-
- { "Right Output Mixer", "Left Bypass Switch", "Left Input PGA" },
- { "Right Output Mixer", "Right Bypass Switch", "Right Input PGA" },
- { "Right Output Mixer", "DACL Switch", "DACL" },
- { "Right Output Mixer", "DACR Switch", "DACR" },
-
- { "Left Speaker Mixer", "Left Bypass Switch", "Left Input PGA" },
- { "Left Speaker Mixer", "Right Bypass Switch", "Right Input PGA" },
- { "Left Speaker Mixer", "DACL Switch", "DACL" },
- { "Left Speaker Mixer", "DACR Switch", "DACR" },
-
- { "Right Speaker Mixer", "Left Bypass Switch", "Left Input PGA" },
- { "Right Speaker Mixer", "Right Bypass Switch", "Right Input PGA" },
- { "Right Speaker Mixer", "DACL Switch", "DACL" },
- { "Right Speaker Mixer", "DACR Switch", "DACR" },
-
- { "Left Line Output PGA", NULL, "Left Output Mixer" },
- { "Right Line Output PGA", NULL, "Right Output Mixer" },
-
- { "Left Headphone Output PGA", NULL, "Left Output Mixer" },
- { "Right Headphone Output PGA", NULL, "Right Output Mixer" },
-
- { "Left Speaker PGA", NULL, "Left Speaker Mixer" },
- { "Right Speaker PGA", NULL, "Right Speaker Mixer" },
-
- { "HPL_ENA", NULL, "Left Headphone Output PGA" },
- { "HPR_ENA", NULL, "Right Headphone Output PGA" },
- { "HPL_ENA_DLY", NULL, "HPL_ENA" },
- { "HPR_ENA_DLY", NULL, "HPR_ENA" },
- { "LINEOUTL_ENA", NULL, "Left Line Output PGA" },
- { "LINEOUTR_ENA", NULL, "Right Line Output PGA" },
- { "LINEOUTL_ENA_DLY", NULL, "LINEOUTL_ENA" },
- { "LINEOUTR_ENA_DLY", NULL, "LINEOUTR_ENA" },
-
- { "HPL_DCS", NULL, "DCS Master" },
- { "HPR_DCS", NULL, "DCS Master" },
- { "LINEOUTL_DCS", NULL, "DCS Master" },
- { "LINEOUTR_DCS", NULL, "DCS Master" },
-
- { "HPL_DCS", NULL, "HPL_ENA_DLY" },
- { "HPR_DCS", NULL, "HPR_ENA_DLY" },
- { "LINEOUTL_DCS", NULL, "LINEOUTL_ENA_DLY" },
- { "LINEOUTR_DCS", NULL, "LINEOUTR_ENA_DLY" },
-
- { "HPL_ENA_OUTP", NULL, "HPL_DCS" },
- { "HPR_ENA_OUTP", NULL, "HPR_DCS" },
- { "LINEOUTL_ENA_OUTP", NULL, "LINEOUTL_DCS" },
- { "LINEOUTR_ENA_OUTP", NULL, "LINEOUTR_DCS" },
-
- { "HPL_RMV_SHORT", NULL, "HPL_ENA_OUTP" },
- { "HPR_RMV_SHORT", NULL, "HPR_ENA_OUTP" },
- { "LINEOUTL_RMV_SHORT", NULL, "LINEOUTL_ENA_OUTP" },
- { "LINEOUTR_RMV_SHORT", NULL, "LINEOUTR_ENA_OUTP" },
-
- { "HPOUTL", NULL, "HPL_RMV_SHORT" },
- { "HPOUTR", NULL, "HPR_RMV_SHORT" },
- { "LINEOUTL", NULL, "LINEOUTL_RMV_SHORT" },
- { "LINEOUTR", NULL, "LINEOUTR_RMV_SHORT" },
-
- { "LOP", NULL, "Left Speaker PGA" },
- { "LON", NULL, "Left Speaker PGA" },
-
- { "ROP", NULL, "Right Speaker PGA" },
- { "RON", NULL, "Right Speaker PGA" },
-
- { "Left Headphone Output PGA", NULL, "Charge Pump" },
- { "Right Headphone Output PGA", NULL, "Charge Pump" },
- { "Left Line Output PGA", NULL, "Charge Pump" },
- { "Right Line Output PGA", NULL, "Charge Pump" },
-};
-
-static int wm8903_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
- WM8903_VMID_RES_MASK,
- WM8903_VMID_RES_50K);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
- WM8903_POBCTRL | WM8903_ISEL_MASK |
- WM8903_STARTUP_BIAS_ENA |
- WM8903_BIAS_ENA,
- WM8903_POBCTRL |
- (2 << WM8903_ISEL_SHIFT) |
- WM8903_STARTUP_BIAS_ENA);
-
- snd_soc_update_bits(codec,
- WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0,
- WM8903_SPK_DISCHARGE,
- WM8903_SPK_DISCHARGE);
-
- msleep(33);
-
- snd_soc_update_bits(codec, WM8903_POWER_MANAGEMENT_5,
- WM8903_SPKL_ENA | WM8903_SPKR_ENA,
- WM8903_SPKL_ENA | WM8903_SPKR_ENA);
-
- snd_soc_update_bits(codec,
- WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0,
- WM8903_SPK_DISCHARGE, 0);
-
- snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
- WM8903_VMID_TIE_ENA |
- WM8903_BUFIO_ENA |
- WM8903_VMID_IO_ENA |
- WM8903_VMID_SOFT_MASK |
- WM8903_VMID_RES_MASK |
- WM8903_VMID_BUF_ENA,
- WM8903_VMID_TIE_ENA |
- WM8903_BUFIO_ENA |
- WM8903_VMID_IO_ENA |
- (2 << WM8903_VMID_SOFT_SHIFT) |
- WM8903_VMID_RES_250K |
- WM8903_VMID_BUF_ENA);
-
- msleep(129);
-
- snd_soc_update_bits(codec, WM8903_POWER_MANAGEMENT_5,
- WM8903_SPKL_ENA | WM8903_SPKR_ENA,
- 0);
-
- snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
- WM8903_VMID_SOFT_MASK, 0);
-
- snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
- WM8903_VMID_RES_MASK,
- WM8903_VMID_RES_50K);
-
- snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
- WM8903_BIAS_ENA | WM8903_POBCTRL,
- WM8903_BIAS_ENA);
-
- /* By default no bypass paths are enabled so
- * enable Class W support.
- */
- dev_dbg(codec->dev, "Enabling Class W\n");
- snd_soc_update_bits(codec, WM8903_CLASS_W_0,
- WM8903_CP_DYN_FREQ |
- WM8903_CP_DYN_V,
- WM8903_CP_DYN_FREQ |
- WM8903_CP_DYN_V);
- }
-
- snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
- WM8903_VMID_RES_MASK,
- WM8903_VMID_RES_250K);
- break;
-
- case SND_SOC_BIAS_OFF:
- snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
- WM8903_BIAS_ENA, 0);
-
- snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
- WM8903_VMID_SOFT_MASK,
- 2 << WM8903_VMID_SOFT_SHIFT);
-
- snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
- WM8903_VMID_BUF_ENA, 0);
-
- msleep(290);
-
- snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
- WM8903_VMID_TIE_ENA | WM8903_BUFIO_ENA |
- WM8903_VMID_IO_ENA | WM8903_VMID_RES_MASK |
- WM8903_VMID_SOFT_MASK |
- WM8903_VMID_BUF_ENA, 0);
-
- snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
- WM8903_STARTUP_BIAS_ENA, 0);
- break;
- }
-
- codec->dapm.bias_level = level;
-
- return 0;
-}
-
-static int wm8903_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
-
- wm8903->sysclk = freq;
-
- return 0;
-}
-
-static int wm8903_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 aif1 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_1);
-
- aif1 &= ~(WM8903_LRCLK_DIR | WM8903_BCLK_DIR | WM8903_AIF_FMT_MASK |
- WM8903_AIF_LRCLK_INV | WM8903_AIF_BCLK_INV);
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- case SND_SOC_DAIFMT_CBS_CFM:
- aif1 |= WM8903_LRCLK_DIR;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- aif1 |= WM8903_LRCLK_DIR | WM8903_BCLK_DIR;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- aif1 |= WM8903_BCLK_DIR;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- aif1 |= 0x3;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- aif1 |= 0x3 | WM8903_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_I2S:
- aif1 |= 0x2;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- aif1 |= 0x1;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- break;
- default:
- return -EINVAL;
- }
-
- /* Clock inversion */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- case SND_SOC_DAIFMT_DSP_B:
- /* frame inversion not valid for DSP modes */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_NF:
- aif1 |= WM8903_AIF_BCLK_INV;
- break;
- default:
- return -EINVAL;
- }
- break;
- case SND_SOC_DAIFMT_I2S:
- case SND_SOC_DAIFMT_RIGHT_J:
- case SND_SOC_DAIFMT_LEFT_J:
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- aif1 |= WM8903_AIF_BCLK_INV | WM8903_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- aif1 |= WM8903_AIF_BCLK_INV;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- aif1 |= WM8903_AIF_LRCLK_INV;
- break;
- default:
- return -EINVAL;
- }
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
-
- return 0;
-}
-
-static int wm8903_digital_mute(struct snd_soc_dai *codec_dai, int mute)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 reg;
-
- reg = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
-
- if (mute)
- reg |= WM8903_DAC_MUTE;
- else
- reg &= ~WM8903_DAC_MUTE;
-
- snd_soc_write(codec, WM8903_DAC_DIGITAL_1, reg);
-
- return 0;
-}
-
-/* Lookup table for CLK_SYS/fs ratio. 256fs or more is recommended
- * for optimal performance so we list the lower rates first and match
- * on the last match we find. */
-static struct {
- int div;
- int rate;
- int mode;
- int mclk_div;
-} clk_sys_ratios[] = {
- { 64, 0x0, 0x0, 1 },
- { 68, 0x0, 0x1, 1 },
- { 125, 0x0, 0x2, 1 },
- { 128, 0x1, 0x0, 1 },
- { 136, 0x1, 0x1, 1 },
- { 192, 0x2, 0x0, 1 },
- { 204, 0x2, 0x1, 1 },
-
- { 64, 0x0, 0x0, 2 },
- { 68, 0x0, 0x1, 2 },
- { 125, 0x0, 0x2, 2 },
- { 128, 0x1, 0x0, 2 },
- { 136, 0x1, 0x1, 2 },
- { 192, 0x2, 0x0, 2 },
- { 204, 0x2, 0x1, 2 },
-
- { 250, 0x2, 0x2, 1 },
- { 256, 0x3, 0x0, 1 },
- { 272, 0x3, 0x1, 1 },
- { 384, 0x4, 0x0, 1 },
- { 408, 0x4, 0x1, 1 },
- { 375, 0x4, 0x2, 1 },
- { 512, 0x5, 0x0, 1 },
- { 544, 0x5, 0x1, 1 },
- { 500, 0x5, 0x2, 1 },
- { 768, 0x6, 0x0, 1 },
- { 816, 0x6, 0x1, 1 },
- { 750, 0x6, 0x2, 1 },
- { 1024, 0x7, 0x0, 1 },
- { 1088, 0x7, 0x1, 1 },
- { 1000, 0x7, 0x2, 1 },
- { 1408, 0x8, 0x0, 1 },
- { 1496, 0x8, 0x1, 1 },
- { 1536, 0x9, 0x0, 1 },
- { 1632, 0x9, 0x1, 1 },
- { 1500, 0x9, 0x2, 1 },
-
- { 250, 0x2, 0x2, 2 },
- { 256, 0x3, 0x0, 2 },
- { 272, 0x3, 0x1, 2 },
- { 384, 0x4, 0x0, 2 },
- { 408, 0x4, 0x1, 2 },
- { 375, 0x4, 0x2, 2 },
- { 512, 0x5, 0x0, 2 },
- { 544, 0x5, 0x1, 2 },
- { 500, 0x5, 0x2, 2 },
- { 768, 0x6, 0x0, 2 },
- { 816, 0x6, 0x1, 2 },
- { 750, 0x6, 0x2, 2 },
- { 1024, 0x7, 0x0, 2 },
- { 1088, 0x7, 0x1, 2 },
- { 1000, 0x7, 0x2, 2 },
- { 1408, 0x8, 0x0, 2 },
- { 1496, 0x8, 0x1, 2 },
- { 1536, 0x9, 0x0, 2 },
- { 1632, 0x9, 0x1, 2 },
- { 1500, 0x9, 0x2, 2 },
-};
-
-/* CLK_SYS/BCLK ratios - multiplied by 10 due to .5s */
-static struct {
- int ratio;
- int div;
-} bclk_divs[] = {
- { 10, 0 },
- { 20, 2 },
- { 30, 3 },
- { 40, 4 },
- { 50, 5 },
- { 60, 7 },
- { 80, 8 },
- { 100, 9 },
- { 120, 11 },
- { 160, 12 },
- { 200, 13 },
- { 220, 14 },
- { 240, 15 },
- { 300, 17 },
- { 320, 18 },
- { 440, 19 },
- { 480, 20 },
-};
-
-/* Sample rates for DSP */
-static struct {
- int rate;
- int value;
-} sample_rates[] = {
- { 8000, 0 },
- { 11025, 1 },
- { 12000, 2 },
- { 16000, 3 },
- { 22050, 4 },
- { 24000, 5 },
- { 32000, 6 },
- { 44100, 7 },
- { 48000, 8 },
- { 88200, 9 },
- { 96000, 10 },
- { 0, 0 },
-};
-
-static int wm8903_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec =rtd->codec;
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
- int fs = params_rate(params);
- int bclk;
- int bclk_div;
- int i;
- int dsp_config;
- int clk_config;
- int best_val;
- int cur_val;
- int clk_sys;
-
- u16 aif1 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_1);
- u16 aif2 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_2);
- u16 aif3 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_3);
- u16 clock0 = snd_soc_read(codec, WM8903_CLOCK_RATES_0);
- u16 clock1 = snd_soc_read(codec, WM8903_CLOCK_RATES_1);
- u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
-
- /* Enable sloping stopband filter for low sample rates */
- if (fs <= 24000)
- dac_digital1 |= WM8903_DAC_SB_FILT;
- else
- dac_digital1 &= ~WM8903_DAC_SB_FILT;
-
- /* Configure sample rate logic for DSP - choose nearest rate */
- dsp_config = 0;
- best_val = abs(sample_rates[dsp_config].rate - fs);
- for (i = 1; i < ARRAY_SIZE(sample_rates); i++) {
- cur_val = abs(sample_rates[i].rate - fs);
- if (cur_val <= best_val) {
- dsp_config = i;
- best_val = cur_val;
- }
- }
-
- dev_dbg(codec->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate);
- clock1 &= ~WM8903_SAMPLE_RATE_MASK;
- clock1 |= sample_rates[dsp_config].value;
-
- aif1 &= ~WM8903_AIF_WL_MASK;
- bclk = 2 * fs;
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- bclk *= 16;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- bclk *= 20;
- aif1 |= 0x4;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- bclk *= 24;
- aif1 |= 0x8;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- bclk *= 32;
- aif1 |= 0xc;
- break;
- default:
- return -EINVAL;
- }
-
- dev_dbg(codec->dev, "MCLK = %dHz, target sample rate = %dHz\n",
- wm8903->sysclk, fs);
-
- /* We may not have an MCLK which allows us to generate exactly
- * the clock we want, particularly with USB derived inputs, so
- * approximate.
- */
- clk_config = 0;
- best_val = abs((wm8903->sysclk /
- (clk_sys_ratios[0].mclk_div *
- clk_sys_ratios[0].div)) - fs);
- for (i = 1; i < ARRAY_SIZE(clk_sys_ratios); i++) {
- cur_val = abs((wm8903->sysclk /
- (clk_sys_ratios[i].mclk_div *
- clk_sys_ratios[i].div)) - fs);
-
- if (cur_val <= best_val) {
- clk_config = i;
- best_val = cur_val;
- }
- }
-
- if (clk_sys_ratios[clk_config].mclk_div == 2) {
- clock0 |= WM8903_MCLKDIV2;
- clk_sys = wm8903->sysclk / 2;
- } else {
- clock0 &= ~WM8903_MCLKDIV2;
- clk_sys = wm8903->sysclk;
- }
-
- clock1 &= ~(WM8903_CLK_SYS_RATE_MASK |
- WM8903_CLK_SYS_MODE_MASK);
- clock1 |= clk_sys_ratios[clk_config].rate << WM8903_CLK_SYS_RATE_SHIFT;
- clock1 |= clk_sys_ratios[clk_config].mode << WM8903_CLK_SYS_MODE_SHIFT;
-
- dev_dbg(codec->dev, "CLK_SYS_RATE=%x, CLK_SYS_MODE=%x div=%d\n",
- clk_sys_ratios[clk_config].rate,
- clk_sys_ratios[clk_config].mode,
- clk_sys_ratios[clk_config].div);
-
- dev_dbg(codec->dev, "Actual CLK_SYS = %dHz\n", clk_sys);
-
- /* We may not get quite the right frequency if using
- * approximate clocks so look for the closest match that is
- * higher than the target (we need to ensure that there enough
- * BCLKs to clock out the samples).
- */
- bclk_div = 0;
- best_val = ((clk_sys * 10) / bclk_divs[0].ratio) - bclk;
- i = 1;
- while (i < ARRAY_SIZE(bclk_divs)) {
- cur_val = ((clk_sys * 10) / bclk_divs[i].ratio) - bclk;
- if (cur_val < 0) /* BCLK table is sorted */
- break;
- bclk_div = i;
- best_val = cur_val;
- i++;
- }
-
- aif2 &= ~WM8903_BCLK_DIV_MASK;
- aif3 &= ~WM8903_LRCLK_RATE_MASK;
-
- dev_dbg(codec->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n",
- bclk_divs[bclk_div].ratio / 10, bclk,
- (clk_sys * 10) / bclk_divs[bclk_div].ratio);
-
- aif2 |= bclk_divs[bclk_div].div;
- aif3 |= bclk / fs;
-
- wm8903->fs = params_rate(params);
- wm8903_set_deemph(codec);
-
- snd_soc_write(codec, WM8903_CLOCK_RATES_0, clock0);
- snd_soc_write(codec, WM8903_CLOCK_RATES_1, clock1);
- snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
- snd_soc_write(codec, WM8903_AUDIO_INTERFACE_2, aif2);
- snd_soc_write(codec, WM8903_AUDIO_INTERFACE_3, aif3);
- snd_soc_write(codec, WM8903_DAC_DIGITAL_1, dac_digital1);
-
- return 0;
-}
-
-/**
- * wm8903_mic_detect - Enable microphone detection via the WM8903 IRQ
- *
- * @codec: WM8903 codec
- * @jack: jack to report detection events on
- * @det: value to report for presence detection
- * @shrt: value to report for short detection
- *
- * Enable microphone detection via IRQ on the WM8903. If GPIOs are
- * being used to bring out signals to the processor then only platform
- * data configuration is needed for WM8903 and processor GPIOs should
- * be configured using snd_soc_jack_add_gpios() instead.
- *
- * The current threasholds for detection should be configured using
- * micdet_cfg in the platform data. Using this function will force on
- * the microphone bias for the device.
- */
-int wm8903_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
- int det, int shrt)
-{
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
- int irq_mask = WM8903_MICDET_EINT | WM8903_MICSHRT_EINT;
-
- dev_dbg(codec->dev, "Enabling microphone detection: %x %x\n",
- det, shrt);
-
- /* Store the configuration */
- wm8903->mic_jack = jack;
- wm8903->mic_det = det;
- wm8903->mic_short = shrt;
-
- /* Enable interrupts we've got a report configured for */
- if (det)
- irq_mask &= ~WM8903_MICDET_EINT;
- if (shrt)
- irq_mask &= ~WM8903_MICSHRT_EINT;
-
- snd_soc_update_bits(codec, WM8903_INTERRUPT_STATUS_1_MASK,
- WM8903_MICDET_EINT | WM8903_MICSHRT_EINT,
- irq_mask);
-
- if (det || shrt) {
- /* Enable mic detection, this may not have been set through
- * platform data (eg, if the defaults are OK). */
- snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
- WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
- snd_soc_update_bits(codec, WM8903_MIC_BIAS_CONTROL_0,
- WM8903_MICDET_ENA, WM8903_MICDET_ENA);
- } else {
- snd_soc_update_bits(codec, WM8903_MIC_BIAS_CONTROL_0,
- WM8903_MICDET_ENA, 0);
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(wm8903_mic_detect);
-
-static irqreturn_t wm8903_irq(int irq, void *data)
-{
- struct snd_soc_codec *codec = data;
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
- int mic_report;
- int int_pol;
- int int_val = 0;
- int mask = ~snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1_MASK);
-
- int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask;
-
- if (int_val & WM8903_WSEQ_BUSY_EINT) {
- dev_warn(codec->dev, "Write sequencer done\n");
- }
-
- /*
- * The rest is microphone jack detection. We need to manually
- * invert the polarity of the interrupt after each event - to
- * simplify the code keep track of the last state we reported
- * and just invert the relevant bits in both the report and
- * the polarity register.
- */
- mic_report = wm8903->mic_last_report;
- int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1);
-
-#ifndef CONFIG_SND_SOC_WM8903_MODULE
- if (int_val & (WM8903_MICSHRT_EINT | WM8903_MICDET_EINT))
- trace_snd_soc_jack_irq(dev_name(codec->dev));
-#endif
-
- if (int_val & WM8903_MICSHRT_EINT) {
- dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol);
-
- mic_report ^= wm8903->mic_short;
- int_pol ^= WM8903_MICSHRT_INV;
- }
-
- if (int_val & WM8903_MICDET_EINT) {
- dev_dbg(codec->dev, "Microphone detect (pol=%x)\n", int_pol);
-
- mic_report ^= wm8903->mic_det;
- int_pol ^= WM8903_MICDET_INV;
-
- msleep(wm8903->mic_delay);
- }
-
- snd_soc_update_bits(codec, WM8903_INTERRUPT_POLARITY_1,
- WM8903_MICSHRT_INV | WM8903_MICDET_INV, int_pol);
-
- snd_soc_jack_report(wm8903->mic_jack, mic_report,
- wm8903->mic_short | wm8903->mic_det);
-
- wm8903->mic_last_report = mic_report;
-
- return IRQ_HANDLED;
-}
-
-#define WM8903_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\
- SNDRV_PCM_RATE_11025 | \
- SNDRV_PCM_RATE_16000 | \
- SNDRV_PCM_RATE_22050 | \
- SNDRV_PCM_RATE_32000 | \
- SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000 | \
- SNDRV_PCM_RATE_88200 | \
- SNDRV_PCM_RATE_96000)
-
-#define WM8903_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
- SNDRV_PCM_RATE_11025 | \
- SNDRV_PCM_RATE_16000 | \
- SNDRV_PCM_RATE_22050 | \
- SNDRV_PCM_RATE_32000 | \
- SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000)
-
-#define WM8903_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
- SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops wm8903_dai_ops = {
- .hw_params = wm8903_hw_params,
- .digital_mute = wm8903_digital_mute,
- .set_fmt = wm8903_set_dai_fmt,
- .set_sysclk = wm8903_set_dai_sysclk,
-};
-
-static struct snd_soc_dai_driver wm8903_dai = {
- .name = "wm8903-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = WM8903_PLAYBACK_RATES,
- .formats = WM8903_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = WM8903_CAPTURE_RATES,
- .formats = WM8903_FORMATS,
- },
- .ops = &wm8903_dai_ops,
- .symmetric_rates = 1,
-};
-
-static int wm8903_suspend(struct snd_soc_codec *codec)
-{
- wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int wm8903_resume(struct snd_soc_codec *codec)
-{
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
-
- regcache_sync(wm8903->regmap);
-
- wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-
-#ifdef CONFIG_GPIOLIB
-static inline struct wm8903_priv *gpio_to_wm8903(struct gpio_chip *chip)
-{
- return container_of(chip, struct wm8903_priv, gpio_chip);
-}
-
-static int wm8903_gpio_request(struct gpio_chip *chip, unsigned offset)
-{
- if (offset >= WM8903_NUM_GPIO)
- return -EINVAL;
-
- return 0;
-}
-
-static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
-{
- struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
- struct snd_soc_codec *codec = wm8903->codec;
- unsigned int mask, val;
- int ret;
-
- mask = WM8903_GP1_FN_MASK | WM8903_GP1_DIR_MASK;
- val = (WM8903_GPn_FN_GPIO_INPUT << WM8903_GP1_FN_SHIFT) |
- WM8903_GP1_DIR;
-
- ret = snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
- mask, val);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int wm8903_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
- struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
- struct snd_soc_codec *codec = wm8903->codec;
- int reg;
-
- reg = snd_soc_read(codec, WM8903_GPIO_CONTROL_1 + offset);
-
- return (reg & WM8903_GP1_LVL_MASK) >> WM8903_GP1_LVL_SHIFT;
-}
-
-static int wm8903_gpio_direction_out(struct gpio_chip *chip,
- unsigned offset, int value)
-{
- struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
- struct snd_soc_codec *codec = wm8903->codec;
- unsigned int mask, val;
- int ret;
-
- mask = WM8903_GP1_FN_MASK | WM8903_GP1_DIR_MASK | WM8903_GP1_LVL_MASK;
- val = (WM8903_GPn_FN_GPIO_OUTPUT << WM8903_GP1_FN_SHIFT) |
- (value << WM8903_GP2_LVL_SHIFT);
-
- ret = snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
- mask, val);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-{
- struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
- struct snd_soc_codec *codec = wm8903->codec;
-
- snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
- WM8903_GP1_LVL_MASK,
- !!value << WM8903_GP1_LVL_SHIFT);
-}
-
-static struct gpio_chip wm8903_template_chip = {
- .label = "wm8903",
- .owner = THIS_MODULE,
- .request = wm8903_gpio_request,
- .direction_input = wm8903_gpio_direction_in,
- .get = wm8903_gpio_get,
- .direction_output = wm8903_gpio_direction_out,
- .set = wm8903_gpio_set,
- .can_sleep = 1,
-};
-
-static void wm8903_init_gpio(struct snd_soc_codec *codec)
-{
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
- struct wm8903_platform_data *pdata = wm8903->pdata;
- int ret;
-
- wm8903->gpio_chip = wm8903_template_chip;
- wm8903->gpio_chip.ngpio = WM8903_NUM_GPIO;
- wm8903->gpio_chip.dev = codec->dev;
-
- if (pdata->gpio_base)
- wm8903->gpio_chip.base = pdata->gpio_base;
- else
- wm8903->gpio_chip.base = -1;
-
- ret = gpiochip_add(&wm8903->gpio_chip);
- if (ret != 0)
- dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
-}
-
-static void wm8903_free_gpio(struct snd_soc_codec *codec)
-{
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- ret = gpiochip_remove(&wm8903->gpio_chip);
- if (ret != 0)
- dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
-}
-#else
-static void wm8903_init_gpio(struct snd_soc_codec *codec)
-{
-}
-
-static void wm8903_free_gpio(struct snd_soc_codec *codec)
-{
-}
-#endif
-
-static int wm8903_probe(struct snd_soc_codec *codec)
-{
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
- struct wm8903_platform_data *pdata = wm8903->pdata;
- int ret, i;
- int trigger, irq_pol;
- u16 val;
- bool mic_gpio = false;
-
- wm8903->codec = codec;
- codec->control_data = wm8903->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- /* Set up GPIOs, detect if any are MIC detect outputs */
- for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) {
- if ((!pdata->gpio_cfg[i]) ||
- (pdata->gpio_cfg[i] > WM8903_GPIO_CONFIG_ZERO))
- continue;
-
- snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i,
- pdata->gpio_cfg[i] & 0x7fff);
-
- val = (pdata->gpio_cfg[i] & WM8903_GP1_FN_MASK)
- >> WM8903_GP1_FN_SHIFT;
-
- switch (val) {
- case WM8903_GPn_FN_MICBIAS_CURRENT_DETECT:
- case WM8903_GPn_FN_MICBIAS_SHORT_DETECT:
- mic_gpio = true;
- break;
- default:
- break;
- }
- }
-
- /* Set up microphone detection */
- snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0,
- pdata->micdet_cfg);
-
- /* Microphone detection needs the WSEQ clock */
- if (pdata->micdet_cfg)
- snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
- WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
-
- /* If microphone detection is enabled by pdata but
- * detected via IRQ then interrupts can be lost before
- * the machine driver has set up microphone detection
- * IRQs as the IRQs are clear on read. The detection
- * will be enabled when the machine driver configures.
- */
- WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA));
-
- wm8903->mic_delay = pdata->micdet_delay;
-
- if (wm8903->irq) {
- if (pdata->irq_active_low) {
- trigger = IRQF_TRIGGER_LOW;
- irq_pol = WM8903_IRQ_POL;
- } else {
- trigger = IRQF_TRIGGER_HIGH;
- irq_pol = 0;
- }
-
- snd_soc_update_bits(codec, WM8903_INTERRUPT_CONTROL,
- WM8903_IRQ_POL, irq_pol);
-
- ret = request_threaded_irq(wm8903->irq, NULL, wm8903_irq,
- trigger | IRQF_ONESHOT,
- "wm8903", codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request IRQ: %d\n",
- ret);
- return ret;
- }
-
- /* Enable write sequencer interrupts */
- snd_soc_update_bits(codec, WM8903_INTERRUPT_STATUS_1_MASK,
- WM8903_IM_WSEQ_BUSY_EINT, 0);
- }
-
- /* power on device */
- wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* Latch volume update bits */
- val = snd_soc_read(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT);
- val |= WM8903_ADCVU;
- snd_soc_write(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT, val);
- snd_soc_write(codec, WM8903_ADC_DIGITAL_VOLUME_RIGHT, val);
-
- val = snd_soc_read(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT);
- val |= WM8903_DACVU;
- snd_soc_write(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT, val);
- snd_soc_write(codec, WM8903_DAC_DIGITAL_VOLUME_RIGHT, val);
-
- val = snd_soc_read(codec, WM8903_ANALOGUE_OUT1_LEFT);
- val |= WM8903_HPOUTVU;
- snd_soc_write(codec, WM8903_ANALOGUE_OUT1_LEFT, val);
- snd_soc_write(codec, WM8903_ANALOGUE_OUT1_RIGHT, val);
-
- val = snd_soc_read(codec, WM8903_ANALOGUE_OUT2_LEFT);
- val |= WM8903_LINEOUTVU;
- snd_soc_write(codec, WM8903_ANALOGUE_OUT2_LEFT, val);
- snd_soc_write(codec, WM8903_ANALOGUE_OUT2_RIGHT, val);
-
- val = snd_soc_read(codec, WM8903_ANALOGUE_OUT3_LEFT);
- val |= WM8903_SPKVU;
- snd_soc_write(codec, WM8903_ANALOGUE_OUT3_LEFT, val);
- snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val);
-
- /* Enable DAC soft mute by default */
- snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1,
- WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE,
- WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE);
-
- wm8903_init_gpio(codec);
-
- return ret;
-}
-
-/* power down chip */
-static int wm8903_remove(struct snd_soc_codec *codec)
-{
- struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
-
- wm8903_free_gpio(codec);
- wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
- if (wm8903->irq)
- free_irq(wm8903->irq, codec);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8903 = {
- .probe = wm8903_probe,
- .remove = wm8903_remove,
- .suspend = wm8903_suspend,
- .resume = wm8903_resume,
- .set_bias_level = wm8903_set_bias_level,
- .seq_notifier = wm8903_seq_notifier,
- .controls = wm8903_snd_controls,
- .num_controls = ARRAY_SIZE(wm8903_snd_controls),
- .dapm_widgets = wm8903_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8903_dapm_widgets),
- .dapm_routes = wm8903_intercon,
- .num_dapm_routes = ARRAY_SIZE(wm8903_intercon),
-};
-
-static const struct regmap_config wm8903_regmap = {
- .reg_bits = 8,
- .val_bits = 16,
-
- .max_register = WM8903_MAX_REGISTER,
- .volatile_reg = wm8903_volatile_register,
- .readable_reg = wm8903_readable_register,
-
- .cache_type = REGCACHE_RBTREE,
- .reg_defaults = wm8903_reg_defaults,
- .num_reg_defaults = ARRAY_SIZE(wm8903_reg_defaults),
-};
-
-static int wm8903_set_pdata_irq_trigger(struct i2c_client *i2c,
- struct wm8903_platform_data *pdata)
-{
- struct irq_data *irq_data = irq_get_irq_data(i2c->irq);
- if (!irq_data) {
- dev_err(&i2c->dev, "Invalid IRQ: %d\n",
- i2c->irq);
- return -EINVAL;
- }
-
- switch (irqd_get_trigger_type(irq_data)) {
- case IRQ_TYPE_NONE:
- default:
- /*
- * We assume the controller imposes no restrictions,
- * so we are able to select active-high
- */
- /* Fall-through */
- case IRQ_TYPE_LEVEL_HIGH:
- pdata->irq_active_low = false;
- break;
- case IRQ_TYPE_LEVEL_LOW:
- pdata->irq_active_low = true;
- break;
- }
-
- return 0;
-}
-
-static int wm8903_set_pdata_from_of(struct i2c_client *i2c,
- struct wm8903_platform_data *pdata)
-{
- const struct device_node *np = i2c->dev.of_node;
- u32 val32;
- int i;
-
- if (of_property_read_u32(np, "micdet-cfg", &val32) >= 0)
- pdata->micdet_cfg = val32;
-
- if (of_property_read_u32(np, "micdet-delay", &val32) >= 0)
- pdata->micdet_delay = val32;
-
- if (of_property_read_u32_array(np, "gpio-cfg", pdata->gpio_cfg,
- ARRAY_SIZE(pdata->gpio_cfg)) >= 0) {
- /*
- * In device tree: 0 means "write 0",
- * 0xffffffff means "don't touch".
- *
- * In platform data: 0 means "don't touch",
- * 0x8000 means "write 0".
- *
- * Note: WM8903_GPIO_CONFIG_ZERO == 0x8000.
- *
- * Convert from DT to pdata representation here,
- * so no other code needs to change.
- */
- for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) {
- if (pdata->gpio_cfg[i] == 0) {
- pdata->gpio_cfg[i] = WM8903_GPIO_CONFIG_ZERO;
- } else if (pdata->gpio_cfg[i] == 0xffffffff) {
- pdata->gpio_cfg[i] = 0;
- } else if (pdata->gpio_cfg[i] > 0x7fff) {
- dev_err(&i2c->dev, "Invalid gpio-cfg[%d] %x\n",
- i, pdata->gpio_cfg[i]);
- return -EINVAL;
- }
- }
- }
-
- return 0;
-}
-
-static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev);
- struct wm8903_priv *wm8903;
- unsigned int val;
- int ret;
-
- wm8903 = devm_kzalloc(&i2c->dev, sizeof(struct wm8903_priv),
- GFP_KERNEL);
- if (wm8903 == NULL)
- return -ENOMEM;
-
- wm8903->regmap = regmap_init_i2c(i2c, &wm8903_regmap);
- if (IS_ERR(wm8903->regmap)) {
- ret = PTR_ERR(wm8903->regmap);
- dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
- ret);
- return ret;
- }
-
- i2c_set_clientdata(i2c, wm8903);
- wm8903->irq = i2c->irq;
-
- /* If no platform data was supplied, create storage for defaults */
- if (pdata) {
- wm8903->pdata = pdata;
- } else {
- wm8903->pdata = devm_kzalloc(&i2c->dev,
- sizeof(struct wm8903_platform_data),
- GFP_KERNEL);
- if (wm8903->pdata == NULL) {
- dev_err(&i2c->dev, "Failed to allocate pdata\n");
- return -ENOMEM;
- }
-
- if (i2c->irq) {
- ret = wm8903_set_pdata_irq_trigger(i2c, wm8903->pdata);
- if (ret != 0)
- return ret;
- }
-
- if (i2c->dev.of_node) {
- ret = wm8903_set_pdata_from_of(i2c, wm8903->pdata);
- if (ret != 0)
- return ret;
- }
- }
-
- ret = regmap_read(wm8903->regmap, WM8903_SW_RESET_AND_ID, &val);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret);
- goto err;
- }
- if (val != 0x8903) {
- dev_err(&i2c->dev, "Device with ID %x is not a WM8903\n", val);
- ret = -ENODEV;
- goto err;
- }
-
- ret = regmap_read(wm8903->regmap, WM8903_REVISION_NUMBER, &val);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to read chip revision: %d\n", ret);
- goto err;
- }
- dev_info(&i2c->dev, "WM8903 revision %c\n",
- (val & WM8903_CHIP_REV_MASK) + 'A');
-
- /* Reset the device */
- regmap_write(wm8903->regmap, WM8903_SW_RESET_AND_ID, 0x8903);
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8903, &wm8903_dai, 1);
- if (ret != 0)
- goto err;
-
- return 0;
-err:
- regmap_exit(wm8903->regmap);
- return ret;
-}
-
-static __devexit int wm8903_i2c_remove(struct i2c_client *client)
-{
- struct wm8903_priv *wm8903 = i2c_get_clientdata(client);
-
- regmap_exit(wm8903->regmap);
- snd_soc_unregister_codec(&client->dev);
-
- return 0;
-}
-
-static const struct of_device_id wm8903_of_match[] = {
- { .compatible = "wlf,wm8903", },
- {},
-};
-MODULE_DEVICE_TABLE(of, wm8903_of_match);
-
-static const struct i2c_device_id wm8903_i2c_id[] = {
- { "wm8903", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8903_i2c_id);
-
-static struct i2c_driver wm8903_i2c_driver = {
- .driver = {
- .name = "wm8903",
- .owner = THIS_MODULE,
- .of_match_table = wm8903_of_match,
- },
- .probe = wm8903_i2c_probe,
- .remove = __devexit_p(wm8903_i2c_remove),
- .id_table = wm8903_i2c_id,
-};
-
-static int __init wm8903_modinit(void)
-{
- int ret = 0;
- ret = i2c_add_driver(&wm8903_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8903 I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(wm8903_modinit);
-
-static void __exit wm8903_exit(void)
-{
- i2c_del_driver(&wm8903_i2c_driver);
-}
-module_exit(wm8903_exit);
-
-MODULE_DESCRIPTION("ASoC WM8903 driver");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8903.h b/ANDROID_3.4.5/sound/soc/codecs/wm8903.h
deleted file mode 100644
index db949311..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8903.h
+++ /dev/null
@@ -1,1225 +0,0 @@
-/*
- * wm8903.h - WM8903 audio codec interface
- *
- * Copyright 2008 Wolfson Microelectronics PLC.
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#ifndef _WM8903_H
-#define _WM8903_H
-
-#include <linux/i2c.h>
-
-extern int wm8903_mic_detect(struct snd_soc_codec *codec,
- struct snd_soc_jack *jack,
- int det, int shrt);
-
-
-/*
- * Register values.
- */
-#define WM8903_SW_RESET_AND_ID 0x00
-#define WM8903_REVISION_NUMBER 0x01
-#define WM8903_BIAS_CONTROL_0 0x04
-#define WM8903_VMID_CONTROL_0 0x05
-#define WM8903_MIC_BIAS_CONTROL_0 0x06
-#define WM8903_ANALOGUE_DAC_0 0x08
-#define WM8903_ANALOGUE_ADC_0 0x0A
-#define WM8903_POWER_MANAGEMENT_0 0x0C
-#define WM8903_POWER_MANAGEMENT_1 0x0D
-#define WM8903_POWER_MANAGEMENT_2 0x0E
-#define WM8903_POWER_MANAGEMENT_3 0x0F
-#define WM8903_POWER_MANAGEMENT_4 0x10
-#define WM8903_POWER_MANAGEMENT_5 0x11
-#define WM8903_POWER_MANAGEMENT_6 0x12
-#define WM8903_CLOCK_RATES_0 0x14
-#define WM8903_CLOCK_RATES_1 0x15
-#define WM8903_CLOCK_RATES_2 0x16
-#define WM8903_AUDIO_INTERFACE_0 0x18
-#define WM8903_AUDIO_INTERFACE_1 0x19
-#define WM8903_AUDIO_INTERFACE_2 0x1A
-#define WM8903_AUDIO_INTERFACE_3 0x1B
-#define WM8903_DAC_DIGITAL_VOLUME_LEFT 0x1E
-#define WM8903_DAC_DIGITAL_VOLUME_RIGHT 0x1F
-#define WM8903_DAC_DIGITAL_0 0x20
-#define WM8903_DAC_DIGITAL_1 0x21
-#define WM8903_ADC_DIGITAL_VOLUME_LEFT 0x24
-#define WM8903_ADC_DIGITAL_VOLUME_RIGHT 0x25
-#define WM8903_ADC_DIGITAL_0 0x26
-#define WM8903_DIGITAL_MICROPHONE_0 0x27
-#define WM8903_DRC_0 0x28
-#define WM8903_DRC_1 0x29
-#define WM8903_DRC_2 0x2A
-#define WM8903_DRC_3 0x2B
-#define WM8903_ANALOGUE_LEFT_INPUT_0 0x2C
-#define WM8903_ANALOGUE_RIGHT_INPUT_0 0x2D
-#define WM8903_ANALOGUE_LEFT_INPUT_1 0x2E
-#define WM8903_ANALOGUE_RIGHT_INPUT_1 0x2F
-#define WM8903_ANALOGUE_LEFT_MIX_0 0x32
-#define WM8903_ANALOGUE_RIGHT_MIX_0 0x33
-#define WM8903_ANALOGUE_SPK_MIX_LEFT_0 0x34
-#define WM8903_ANALOGUE_SPK_MIX_LEFT_1 0x35
-#define WM8903_ANALOGUE_SPK_MIX_RIGHT_0 0x36
-#define WM8903_ANALOGUE_SPK_MIX_RIGHT_1 0x37
-#define WM8903_ANALOGUE_OUT1_LEFT 0x39
-#define WM8903_ANALOGUE_OUT1_RIGHT 0x3A
-#define WM8903_ANALOGUE_OUT2_LEFT 0x3B
-#define WM8903_ANALOGUE_OUT2_RIGHT 0x3C
-#define WM8903_ANALOGUE_OUT3_LEFT 0x3E
-#define WM8903_ANALOGUE_OUT3_RIGHT 0x3F
-#define WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0 0x41
-#define WM8903_DC_SERVO_0 0x43
-#define WM8903_DC_SERVO_2 0x45
-#define WM8903_DC_SERVO_4 0x47
-#define WM8903_DC_SERVO_5 0x48
-#define WM8903_DC_SERVO_6 0x49
-#define WM8903_DC_SERVO_7 0x4A
-#define WM8903_DC_SERVO_READBACK_1 0x51
-#define WM8903_DC_SERVO_READBACK_2 0x52
-#define WM8903_DC_SERVO_READBACK_3 0x53
-#define WM8903_DC_SERVO_READBACK_4 0x54
-#define WM8903_ANALOGUE_HP_0 0x5A
-#define WM8903_ANALOGUE_LINEOUT_0 0x5E
-#define WM8903_CHARGE_PUMP_0 0x62
-#define WM8903_CLASS_W_0 0x68
-#define WM8903_WRITE_SEQUENCER_0 0x6C
-#define WM8903_WRITE_SEQUENCER_1 0x6D
-#define WM8903_WRITE_SEQUENCER_2 0x6E
-#define WM8903_WRITE_SEQUENCER_3 0x6F
-#define WM8903_WRITE_SEQUENCER_4 0x70
-#define WM8903_CONTROL_INTERFACE 0x72
-#define WM8903_GPIO_CONTROL_1 0x74
-#define WM8903_GPIO_CONTROL_2 0x75
-#define WM8903_GPIO_CONTROL_3 0x76
-#define WM8903_GPIO_CONTROL_4 0x77
-#define WM8903_GPIO_CONTROL_5 0x78
-#define WM8903_INTERRUPT_STATUS_1 0x79
-#define WM8903_INTERRUPT_STATUS_1_MASK 0x7A
-#define WM8903_INTERRUPT_POLARITY_1 0x7B
-#define WM8903_INTERRUPT_CONTROL 0x7E
-#define WM8903_CLOCK_RATE_TEST_4 0xA4
-#define WM8903_ANALOGUE_OUTPUT_BIAS_0 0xAC
-
-#define WM8903_REGISTER_COUNT 75
-#define WM8903_MAX_REGISTER 0xAC
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - SW Reset and ID
- */
-#define WM8903_SW_RESET_DEV_ID1_MASK 0xFFFF /* SW_RESET_DEV_ID1 - [15:0] */
-#define WM8903_SW_RESET_DEV_ID1_SHIFT 0 /* SW_RESET_DEV_ID1 - [15:0] */
-#define WM8903_SW_RESET_DEV_ID1_WIDTH 16 /* SW_RESET_DEV_ID1 - [15:0] */
-
-/*
- * R1 (0x01) - Revision Number
- */
-#define WM8903_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */
-#define WM8903_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */
-#define WM8903_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */
-
-/*
- * R4 (0x04) - Bias Control 0
- */
-#define WM8903_POBCTRL 0x0010 /* POBCTRL */
-#define WM8903_POBCTRL_MASK 0x0010 /* POBCTRL */
-#define WM8903_POBCTRL_SHIFT 4 /* POBCTRL */
-#define WM8903_POBCTRL_WIDTH 1 /* POBCTRL */
-#define WM8903_ISEL_MASK 0x000C /* ISEL - [3:2] */
-#define WM8903_ISEL_SHIFT 2 /* ISEL - [3:2] */
-#define WM8903_ISEL_WIDTH 2 /* ISEL - [3:2] */
-#define WM8903_STARTUP_BIAS_ENA 0x0002 /* STARTUP_BIAS_ENA */
-#define WM8903_STARTUP_BIAS_ENA_MASK 0x0002 /* STARTUP_BIAS_ENA */
-#define WM8903_STARTUP_BIAS_ENA_SHIFT 1 /* STARTUP_BIAS_ENA */
-#define WM8903_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */
-#define WM8903_BIAS_ENA 0x0001 /* BIAS_ENA */
-#define WM8903_BIAS_ENA_MASK 0x0001 /* BIAS_ENA */
-#define WM8903_BIAS_ENA_SHIFT 0 /* BIAS_ENA */
-#define WM8903_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
-
-/*
- * R5 (0x05) - VMID Control 0
- */
-#define WM8903_VMID_TIE_ENA 0x0080 /* VMID_TIE_ENA */
-#define WM8903_VMID_TIE_ENA_MASK 0x0080 /* VMID_TIE_ENA */
-#define WM8903_VMID_TIE_ENA_SHIFT 7 /* VMID_TIE_ENA */
-#define WM8903_VMID_TIE_ENA_WIDTH 1 /* VMID_TIE_ENA */
-#define WM8903_BUFIO_ENA 0x0040 /* BUFIO_ENA */
-#define WM8903_BUFIO_ENA_MASK 0x0040 /* BUFIO_ENA */
-#define WM8903_BUFIO_ENA_SHIFT 6 /* BUFIO_ENA */
-#define WM8903_BUFIO_ENA_WIDTH 1 /* BUFIO_ENA */
-#define WM8903_VMID_IO_ENA 0x0020 /* VMID_IO_ENA */
-#define WM8903_VMID_IO_ENA_MASK 0x0020 /* VMID_IO_ENA */
-#define WM8903_VMID_IO_ENA_SHIFT 5 /* VMID_IO_ENA */
-#define WM8903_VMID_IO_ENA_WIDTH 1 /* VMID_IO_ENA */
-#define WM8903_VMID_SOFT_MASK 0x0018 /* VMID_SOFT - [4:3] */
-#define WM8903_VMID_SOFT_SHIFT 3 /* VMID_SOFT - [4:3] */
-#define WM8903_VMID_SOFT_WIDTH 2 /* VMID_SOFT - [4:3] */
-#define WM8903_VMID_RES_MASK 0x0006 /* VMID_RES - [2:1] */
-#define WM8903_VMID_RES_SHIFT 1 /* VMID_RES - [2:1] */
-#define WM8903_VMID_RES_WIDTH 2 /* VMID_RES - [2:1] */
-#define WM8903_VMID_BUF_ENA 0x0001 /* VMID_BUF_ENA */
-#define WM8903_VMID_BUF_ENA_MASK 0x0001 /* VMID_BUF_ENA */
-#define WM8903_VMID_BUF_ENA_SHIFT 0 /* VMID_BUF_ENA */
-#define WM8903_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
-
-#define WM8903_VMID_RES_50K 2
-#define WM8903_VMID_RES_250K 3
-#define WM8903_VMID_RES_5K 6
-
-/*
- * R8 (0x08) - Analogue DAC 0
- */
-#define WM8903_DACBIAS_SEL_MASK 0x0018 /* DACBIAS_SEL - [4:3] */
-#define WM8903_DACBIAS_SEL_SHIFT 3 /* DACBIAS_SEL - [4:3] */
-#define WM8903_DACBIAS_SEL_WIDTH 2 /* DACBIAS_SEL - [4:3] */
-#define WM8903_DACVMID_BIAS_SEL_MASK 0x0006 /* DACVMID_BIAS_SEL - [2:1] */
-#define WM8903_DACVMID_BIAS_SEL_SHIFT 1 /* DACVMID_BIAS_SEL - [2:1] */
-#define WM8903_DACVMID_BIAS_SEL_WIDTH 2 /* DACVMID_BIAS_SEL - [2:1] */
-
-/*
- * R10 (0x0A) - Analogue ADC 0
- */
-#define WM8903_ADC_OSR128 0x0001 /* ADC_OSR128 */
-#define WM8903_ADC_OSR128_MASK 0x0001 /* ADC_OSR128 */
-#define WM8903_ADC_OSR128_SHIFT 0 /* ADC_OSR128 */
-#define WM8903_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
-
-/*
- * R12 (0x0C) - Power Management 0
- */
-#define WM8903_INL_ENA 0x0002 /* INL_ENA */
-#define WM8903_INL_ENA_MASK 0x0002 /* INL_ENA */
-#define WM8903_INL_ENA_SHIFT 1 /* INL_ENA */
-#define WM8903_INL_ENA_WIDTH 1 /* INL_ENA */
-#define WM8903_INR_ENA 0x0001 /* INR_ENA */
-#define WM8903_INR_ENA_MASK 0x0001 /* INR_ENA */
-#define WM8903_INR_ENA_SHIFT 0 /* INR_ENA */
-#define WM8903_INR_ENA_WIDTH 1 /* INR_ENA */
-
-/*
- * R13 (0x0D) - Power Management 1
- */
-#define WM8903_MIXOUTL_ENA 0x0002 /* MIXOUTL_ENA */
-#define WM8903_MIXOUTL_ENA_MASK 0x0002 /* MIXOUTL_ENA */
-#define WM8903_MIXOUTL_ENA_SHIFT 1 /* MIXOUTL_ENA */
-#define WM8903_MIXOUTL_ENA_WIDTH 1 /* MIXOUTL_ENA */
-#define WM8903_MIXOUTR_ENA 0x0001 /* MIXOUTR_ENA */
-#define WM8903_MIXOUTR_ENA_MASK 0x0001 /* MIXOUTR_ENA */
-#define WM8903_MIXOUTR_ENA_SHIFT 0 /* MIXOUTR_ENA */
-#define WM8903_MIXOUTR_ENA_WIDTH 1 /* MIXOUTR_ENA */
-
-/*
- * R14 (0x0E) - Power Management 2
- */
-#define WM8903_HPL_PGA_ENA 0x0002 /* HPL_PGA_ENA */
-#define WM8903_HPL_PGA_ENA_MASK 0x0002 /* HPL_PGA_ENA */
-#define WM8903_HPL_PGA_ENA_SHIFT 1 /* HPL_PGA_ENA */
-#define WM8903_HPL_PGA_ENA_WIDTH 1 /* HPL_PGA_ENA */
-#define WM8903_HPR_PGA_ENA 0x0001 /* HPR_PGA_ENA */
-#define WM8903_HPR_PGA_ENA_MASK 0x0001 /* HPR_PGA_ENA */
-#define WM8903_HPR_PGA_ENA_SHIFT 0 /* HPR_PGA_ENA */
-#define WM8903_HPR_PGA_ENA_WIDTH 1 /* HPR_PGA_ENA */
-
-/*
- * R15 (0x0F) - Power Management 3
- */
-#define WM8903_LINEOUTL_PGA_ENA 0x0002 /* LINEOUTL_PGA_ENA */
-#define WM8903_LINEOUTL_PGA_ENA_MASK 0x0002 /* LINEOUTL_PGA_ENA */
-#define WM8903_LINEOUTL_PGA_ENA_SHIFT 1 /* LINEOUTL_PGA_ENA */
-#define WM8903_LINEOUTL_PGA_ENA_WIDTH 1 /* LINEOUTL_PGA_ENA */
-#define WM8903_LINEOUTR_PGA_ENA 0x0001 /* LINEOUTR_PGA_ENA */
-#define WM8903_LINEOUTR_PGA_ENA_MASK 0x0001 /* LINEOUTR_PGA_ENA */
-#define WM8903_LINEOUTR_PGA_ENA_SHIFT 0 /* LINEOUTR_PGA_ENA */
-#define WM8903_LINEOUTR_PGA_ENA_WIDTH 1 /* LINEOUTR_PGA_ENA */
-
-/*
- * R16 (0x10) - Power Management 4
- */
-#define WM8903_MIXSPKL_ENA 0x0002 /* MIXSPKL_ENA */
-#define WM8903_MIXSPKL_ENA_MASK 0x0002 /* MIXSPKL_ENA */
-#define WM8903_MIXSPKL_ENA_SHIFT 1 /* MIXSPKL_ENA */
-#define WM8903_MIXSPKL_ENA_WIDTH 1 /* MIXSPKL_ENA */
-#define WM8903_MIXSPKR_ENA 0x0001 /* MIXSPKR_ENA */
-#define WM8903_MIXSPKR_ENA_MASK 0x0001 /* MIXSPKR_ENA */
-#define WM8903_MIXSPKR_ENA_SHIFT 0 /* MIXSPKR_ENA */
-#define WM8903_MIXSPKR_ENA_WIDTH 1 /* MIXSPKR_ENA */
-
-/*
- * R17 (0x11) - Power Management 5
- */
-#define WM8903_SPKL_ENA 0x0002 /* SPKL_ENA */
-#define WM8903_SPKL_ENA_MASK 0x0002 /* SPKL_ENA */
-#define WM8903_SPKL_ENA_SHIFT 1 /* SPKL_ENA */
-#define WM8903_SPKL_ENA_WIDTH 1 /* SPKL_ENA */
-#define WM8903_SPKR_ENA 0x0001 /* SPKR_ENA */
-#define WM8903_SPKR_ENA_MASK 0x0001 /* SPKR_ENA */
-#define WM8903_SPKR_ENA_SHIFT 0 /* SPKR_ENA */
-#define WM8903_SPKR_ENA_WIDTH 1 /* SPKR_ENA */
-
-/*
- * R18 (0x12) - Power Management 6
- */
-#define WM8903_DACL_ENA 0x0008 /* DACL_ENA */
-#define WM8903_DACL_ENA_MASK 0x0008 /* DACL_ENA */
-#define WM8903_DACL_ENA_SHIFT 3 /* DACL_ENA */
-#define WM8903_DACL_ENA_WIDTH 1 /* DACL_ENA */
-#define WM8903_DACR_ENA 0x0004 /* DACR_ENA */
-#define WM8903_DACR_ENA_MASK 0x0004 /* DACR_ENA */
-#define WM8903_DACR_ENA_SHIFT 2 /* DACR_ENA */
-#define WM8903_DACR_ENA_WIDTH 1 /* DACR_ENA */
-#define WM8903_ADCL_ENA 0x0002 /* ADCL_ENA */
-#define WM8903_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
-#define WM8903_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
-#define WM8903_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
-#define WM8903_ADCR_ENA 0x0001 /* ADCR_ENA */
-#define WM8903_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
-#define WM8903_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
-#define WM8903_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
-
-/*
- * R20 (0x14) - Clock Rates 0
- */
-#define WM8903_MCLKDIV2 0x0001 /* MCLKDIV2 */
-#define WM8903_MCLKDIV2_MASK 0x0001 /* MCLKDIV2 */
-#define WM8903_MCLKDIV2_SHIFT 0 /* MCLKDIV2 */
-#define WM8903_MCLKDIV2_WIDTH 1 /* MCLKDIV2 */
-
-/*
- * R21 (0x15) - Clock Rates 1
- */
-#define WM8903_CLK_SYS_RATE_MASK 0x3C00 /* CLK_SYS_RATE - [13:10] */
-#define WM8903_CLK_SYS_RATE_SHIFT 10 /* CLK_SYS_RATE - [13:10] */
-#define WM8903_CLK_SYS_RATE_WIDTH 4 /* CLK_SYS_RATE - [13:10] */
-#define WM8903_CLK_SYS_MODE_MASK 0x0300 /* CLK_SYS_MODE - [9:8] */
-#define WM8903_CLK_SYS_MODE_SHIFT 8 /* CLK_SYS_MODE - [9:8] */
-#define WM8903_CLK_SYS_MODE_WIDTH 2 /* CLK_SYS_MODE - [9:8] */
-#define WM8903_SAMPLE_RATE_MASK 0x000F /* SAMPLE_RATE - [3:0] */
-#define WM8903_SAMPLE_RATE_SHIFT 0 /* SAMPLE_RATE - [3:0] */
-#define WM8903_SAMPLE_RATE_WIDTH 4 /* SAMPLE_RATE - [3:0] */
-
-/*
- * R22 (0x16) - Clock Rates 2
- */
-#define WM8903_CLK_SYS_ENA 0x0004 /* CLK_SYS_ENA */
-#define WM8903_CLK_SYS_ENA_MASK 0x0004 /* CLK_SYS_ENA */
-#define WM8903_CLK_SYS_ENA_SHIFT 2 /* CLK_SYS_ENA */
-#define WM8903_CLK_SYS_ENA_WIDTH 1 /* CLK_SYS_ENA */
-#define WM8903_CLK_DSP_ENA 0x0002 /* CLK_DSP_ENA */
-#define WM8903_CLK_DSP_ENA_MASK 0x0002 /* CLK_DSP_ENA */
-#define WM8903_CLK_DSP_ENA_SHIFT 1 /* CLK_DSP_ENA */
-#define WM8903_CLK_DSP_ENA_WIDTH 1 /* CLK_DSP_ENA */
-#define WM8903_TO_ENA 0x0001 /* TO_ENA */
-#define WM8903_TO_ENA_MASK 0x0001 /* TO_ENA */
-#define WM8903_TO_ENA_SHIFT 0 /* TO_ENA */
-#define WM8903_TO_ENA_WIDTH 1 /* TO_ENA */
-
-/*
- * R24 (0x18) - Audio Interface 0
- */
-#define WM8903_DACL_DATINV 0x1000 /* DACL_DATINV */
-#define WM8903_DACL_DATINV_MASK 0x1000 /* DACL_DATINV */
-#define WM8903_DACL_DATINV_SHIFT 12 /* DACL_DATINV */
-#define WM8903_DACL_DATINV_WIDTH 1 /* DACL_DATINV */
-#define WM8903_DACR_DATINV 0x0800 /* DACR_DATINV */
-#define WM8903_DACR_DATINV_MASK 0x0800 /* DACR_DATINV */
-#define WM8903_DACR_DATINV_SHIFT 11 /* DACR_DATINV */
-#define WM8903_DACR_DATINV_WIDTH 1 /* DACR_DATINV */
-#define WM8903_DAC_BOOST_MASK 0x0600 /* DAC_BOOST - [10:9] */
-#define WM8903_DAC_BOOST_SHIFT 9 /* DAC_BOOST - [10:9] */
-#define WM8903_DAC_BOOST_WIDTH 2 /* DAC_BOOST - [10:9] */
-#define WM8903_LOOPBACK 0x0100 /* LOOPBACK */
-#define WM8903_LOOPBACK_MASK 0x0100 /* LOOPBACK */
-#define WM8903_LOOPBACK_SHIFT 8 /* LOOPBACK */
-#define WM8903_LOOPBACK_WIDTH 1 /* LOOPBACK */
-#define WM8903_AIFADCL_SRC 0x0080 /* AIFADCL_SRC */
-#define WM8903_AIFADCL_SRC_MASK 0x0080 /* AIFADCL_SRC */
-#define WM8903_AIFADCL_SRC_SHIFT 7 /* AIFADCL_SRC */
-#define WM8903_AIFADCL_SRC_WIDTH 1 /* AIFADCL_SRC */
-#define WM8903_AIFADCR_SRC 0x0040 /* AIFADCR_SRC */
-#define WM8903_AIFADCR_SRC_MASK 0x0040 /* AIFADCR_SRC */
-#define WM8903_AIFADCR_SRC_SHIFT 6 /* AIFADCR_SRC */
-#define WM8903_AIFADCR_SRC_WIDTH 1 /* AIFADCR_SRC */
-#define WM8903_AIFDACL_SRC 0x0020 /* AIFDACL_SRC */
-#define WM8903_AIFDACL_SRC_MASK 0x0020 /* AIFDACL_SRC */
-#define WM8903_AIFDACL_SRC_SHIFT 5 /* AIFDACL_SRC */
-#define WM8903_AIFDACL_SRC_WIDTH 1 /* AIFDACL_SRC */
-#define WM8903_AIFDACR_SRC 0x0010 /* AIFDACR_SRC */
-#define WM8903_AIFDACR_SRC_MASK 0x0010 /* AIFDACR_SRC */
-#define WM8903_AIFDACR_SRC_SHIFT 4 /* AIFDACR_SRC */
-#define WM8903_AIFDACR_SRC_WIDTH 1 /* AIFDACR_SRC */
-#define WM8903_ADC_COMP 0x0008 /* ADC_COMP */
-#define WM8903_ADC_COMP_MASK 0x0008 /* ADC_COMP */
-#define WM8903_ADC_COMP_SHIFT 3 /* ADC_COMP */
-#define WM8903_ADC_COMP_WIDTH 1 /* ADC_COMP */
-#define WM8903_ADC_COMPMODE 0x0004 /* ADC_COMPMODE */
-#define WM8903_ADC_COMPMODE_MASK 0x0004 /* ADC_COMPMODE */
-#define WM8903_ADC_COMPMODE_SHIFT 2 /* ADC_COMPMODE */
-#define WM8903_ADC_COMPMODE_WIDTH 1 /* ADC_COMPMODE */
-#define WM8903_DAC_COMP 0x0002 /* DAC_COMP */
-#define WM8903_DAC_COMP_MASK 0x0002 /* DAC_COMP */
-#define WM8903_DAC_COMP_SHIFT 1 /* DAC_COMP */
-#define WM8903_DAC_COMP_WIDTH 1 /* DAC_COMP */
-#define WM8903_DAC_COMPMODE 0x0001 /* DAC_COMPMODE */
-#define WM8903_DAC_COMPMODE_MASK 0x0001 /* DAC_COMPMODE */
-#define WM8903_DAC_COMPMODE_SHIFT 0 /* DAC_COMPMODE */
-#define WM8903_DAC_COMPMODE_WIDTH 1 /* DAC_COMPMODE */
-
-/*
- * R25 (0x19) - Audio Interface 1
- */
-#define WM8903_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */
-#define WM8903_AIFDAC_TDM_MASK 0x2000 /* AIFDAC_TDM */
-#define WM8903_AIFDAC_TDM_SHIFT 13 /* AIFDAC_TDM */
-#define WM8903_AIFDAC_TDM_WIDTH 1 /* AIFDAC_TDM */
-#define WM8903_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */
-#define WM8903_AIFDAC_TDM_CHAN_MASK 0x1000 /* AIFDAC_TDM_CHAN */
-#define WM8903_AIFDAC_TDM_CHAN_SHIFT 12 /* AIFDAC_TDM_CHAN */
-#define WM8903_AIFDAC_TDM_CHAN_WIDTH 1 /* AIFDAC_TDM_CHAN */
-#define WM8903_AIFADC_TDM 0x0800 /* AIFADC_TDM */
-#define WM8903_AIFADC_TDM_MASK 0x0800 /* AIFADC_TDM */
-#define WM8903_AIFADC_TDM_SHIFT 11 /* AIFADC_TDM */
-#define WM8903_AIFADC_TDM_WIDTH 1 /* AIFADC_TDM */
-#define WM8903_AIFADC_TDM_CHAN 0x0400 /* AIFADC_TDM_CHAN */
-#define WM8903_AIFADC_TDM_CHAN_MASK 0x0400 /* AIFADC_TDM_CHAN */
-#define WM8903_AIFADC_TDM_CHAN_SHIFT 10 /* AIFADC_TDM_CHAN */
-#define WM8903_AIFADC_TDM_CHAN_WIDTH 1 /* AIFADC_TDM_CHAN */
-#define WM8903_LRCLK_DIR 0x0200 /* LRCLK_DIR */
-#define WM8903_LRCLK_DIR_MASK 0x0200 /* LRCLK_DIR */
-#define WM8903_LRCLK_DIR_SHIFT 9 /* LRCLK_DIR */
-#define WM8903_LRCLK_DIR_WIDTH 1 /* LRCLK_DIR */
-#define WM8903_AIF_BCLK_INV 0x0080 /* AIF_BCLK_INV */
-#define WM8903_AIF_BCLK_INV_MASK 0x0080 /* AIF_BCLK_INV */
-#define WM8903_AIF_BCLK_INV_SHIFT 7 /* AIF_BCLK_INV */
-#define WM8903_AIF_BCLK_INV_WIDTH 1 /* AIF_BCLK_INV */
-#define WM8903_BCLK_DIR 0x0040 /* BCLK_DIR */
-#define WM8903_BCLK_DIR_MASK 0x0040 /* BCLK_DIR */
-#define WM8903_BCLK_DIR_SHIFT 6 /* BCLK_DIR */
-#define WM8903_BCLK_DIR_WIDTH 1 /* BCLK_DIR */
-#define WM8903_AIF_LRCLK_INV 0x0010 /* AIF_LRCLK_INV */
-#define WM8903_AIF_LRCLK_INV_MASK 0x0010 /* AIF_LRCLK_INV */
-#define WM8903_AIF_LRCLK_INV_SHIFT 4 /* AIF_LRCLK_INV */
-#define WM8903_AIF_LRCLK_INV_WIDTH 1 /* AIF_LRCLK_INV */
-#define WM8903_AIF_WL_MASK 0x000C /* AIF_WL - [3:2] */
-#define WM8903_AIF_WL_SHIFT 2 /* AIF_WL - [3:2] */
-#define WM8903_AIF_WL_WIDTH 2 /* AIF_WL - [3:2] */
-#define WM8903_AIF_FMT_MASK 0x0003 /* AIF_FMT - [1:0] */
-#define WM8903_AIF_FMT_SHIFT 0 /* AIF_FMT - [1:0] */
-#define WM8903_AIF_FMT_WIDTH 2 /* AIF_FMT - [1:0] */
-
-/*
- * R26 (0x1A) - Audio Interface 2
- */
-#define WM8903_BCLK_DIV_MASK 0x001F /* BCLK_DIV - [4:0] */
-#define WM8903_BCLK_DIV_SHIFT 0 /* BCLK_DIV - [4:0] */
-#define WM8903_BCLK_DIV_WIDTH 5 /* BCLK_DIV - [4:0] */
-
-/*
- * R27 (0x1B) - Audio Interface 3
- */
-#define WM8903_LRCLK_RATE_MASK 0x07FF /* LRCLK_RATE - [10:0] */
-#define WM8903_LRCLK_RATE_SHIFT 0 /* LRCLK_RATE - [10:0] */
-#define WM8903_LRCLK_RATE_WIDTH 11 /* LRCLK_RATE - [10:0] */
-
-/*
- * R30 (0x1E) - DAC Digital Volume Left
- */
-#define WM8903_DACVU 0x0100 /* DACVU */
-#define WM8903_DACVU_MASK 0x0100 /* DACVU */
-#define WM8903_DACVU_SHIFT 8 /* DACVU */
-#define WM8903_DACVU_WIDTH 1 /* DACVU */
-#define WM8903_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
-#define WM8903_DACL_VOL_SHIFT 0 /* DACL_VOL - [7:0] */
-#define WM8903_DACL_VOL_WIDTH 8 /* DACL_VOL - [7:0] */
-
-/*
- * R31 (0x1F) - DAC Digital Volume Right
- */
-#define WM8903_DACVU 0x0100 /* DACVU */
-#define WM8903_DACVU_MASK 0x0100 /* DACVU */
-#define WM8903_DACVU_SHIFT 8 /* DACVU */
-#define WM8903_DACVU_WIDTH 1 /* DACVU */
-#define WM8903_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
-#define WM8903_DACR_VOL_SHIFT 0 /* DACR_VOL - [7:0] */
-#define WM8903_DACR_VOL_WIDTH 8 /* DACR_VOL - [7:0] */
-
-/*
- * R32 (0x20) - DAC Digital 0
- */
-#define WM8903_ADCL_DAC_SVOL_MASK 0x0F00 /* ADCL_DAC_SVOL - [11:8] */
-#define WM8903_ADCL_DAC_SVOL_SHIFT 8 /* ADCL_DAC_SVOL - [11:8] */
-#define WM8903_ADCL_DAC_SVOL_WIDTH 4 /* ADCL_DAC_SVOL - [11:8] */
-#define WM8903_ADCR_DAC_SVOL_MASK 0x00F0 /* ADCR_DAC_SVOL - [7:4] */
-#define WM8903_ADCR_DAC_SVOL_SHIFT 4 /* ADCR_DAC_SVOL - [7:4] */
-#define WM8903_ADCR_DAC_SVOL_WIDTH 4 /* ADCR_DAC_SVOL - [7:4] */
-#define WM8903_ADC_TO_DACL_MASK 0x000C /* ADC_TO_DACL - [3:2] */
-#define WM8903_ADC_TO_DACL_SHIFT 2 /* ADC_TO_DACL - [3:2] */
-#define WM8903_ADC_TO_DACL_WIDTH 2 /* ADC_TO_DACL - [3:2] */
-#define WM8903_ADC_TO_DACR_MASK 0x0003 /* ADC_TO_DACR - [1:0] */
-#define WM8903_ADC_TO_DACR_SHIFT 0 /* ADC_TO_DACR - [1:0] */
-#define WM8903_ADC_TO_DACR_WIDTH 2 /* ADC_TO_DACR - [1:0] */
-
-/*
- * R33 (0x21) - DAC Digital 1
- */
-#define WM8903_DAC_MONO 0x1000 /* DAC_MONO */
-#define WM8903_DAC_MONO_MASK 0x1000 /* DAC_MONO */
-#define WM8903_DAC_MONO_SHIFT 12 /* DAC_MONO */
-#define WM8903_DAC_MONO_WIDTH 1 /* DAC_MONO */
-#define WM8903_DAC_SB_FILT 0x0800 /* DAC_SB_FILT */
-#define WM8903_DAC_SB_FILT_MASK 0x0800 /* DAC_SB_FILT */
-#define WM8903_DAC_SB_FILT_SHIFT 11 /* DAC_SB_FILT */
-#define WM8903_DAC_SB_FILT_WIDTH 1 /* DAC_SB_FILT */
-#define WM8903_DAC_MUTERATE 0x0400 /* DAC_MUTERATE */
-#define WM8903_DAC_MUTERATE_MASK 0x0400 /* DAC_MUTERATE */
-#define WM8903_DAC_MUTERATE_SHIFT 10 /* DAC_MUTERATE */
-#define WM8903_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
-#define WM8903_DAC_MUTEMODE 0x0200 /* DAC_MUTEMODE */
-#define WM8903_DAC_MUTEMODE_MASK 0x0200 /* DAC_MUTEMODE */
-#define WM8903_DAC_MUTEMODE_SHIFT 9 /* DAC_MUTEMODE */
-#define WM8903_DAC_MUTEMODE_WIDTH 1 /* DAC_MUTEMODE */
-#define WM8903_DAC_MUTE 0x0008 /* DAC_MUTE */
-#define WM8903_DAC_MUTE_MASK 0x0008 /* DAC_MUTE */
-#define WM8903_DAC_MUTE_SHIFT 3 /* DAC_MUTE */
-#define WM8903_DAC_MUTE_WIDTH 1 /* DAC_MUTE */
-#define WM8903_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */
-#define WM8903_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */
-#define WM8903_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */
-
-/*
- * R36 (0x24) - ADC Digital Volume Left
- */
-#define WM8903_ADCVU 0x0100 /* ADCVU */
-#define WM8903_ADCVU_MASK 0x0100 /* ADCVU */
-#define WM8903_ADCVU_SHIFT 8 /* ADCVU */
-#define WM8903_ADCVU_WIDTH 1 /* ADCVU */
-#define WM8903_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
-#define WM8903_ADCL_VOL_SHIFT 0 /* ADCL_VOL - [7:0] */
-#define WM8903_ADCL_VOL_WIDTH 8 /* ADCL_VOL - [7:0] */
-
-/*
- * R37 (0x25) - ADC Digital Volume Right
- */
-#define WM8903_ADCVU 0x0100 /* ADCVU */
-#define WM8903_ADCVU_MASK 0x0100 /* ADCVU */
-#define WM8903_ADCVU_SHIFT 8 /* ADCVU */
-#define WM8903_ADCVU_WIDTH 1 /* ADCVU */
-#define WM8903_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
-#define WM8903_ADCR_VOL_SHIFT 0 /* ADCR_VOL - [7:0] */
-#define WM8903_ADCR_VOL_WIDTH 8 /* ADCR_VOL - [7:0] */
-
-/*
- * R38 (0x26) - ADC Digital 0
- */
-#define WM8903_ADC_HPF_CUT_MASK 0x0060 /* ADC_HPF_CUT - [6:5] */
-#define WM8903_ADC_HPF_CUT_SHIFT 5 /* ADC_HPF_CUT - [6:5] */
-#define WM8903_ADC_HPF_CUT_WIDTH 2 /* ADC_HPF_CUT - [6:5] */
-#define WM8903_ADC_HPF_ENA 0x0010 /* ADC_HPF_ENA */
-#define WM8903_ADC_HPF_ENA_MASK 0x0010 /* ADC_HPF_ENA */
-#define WM8903_ADC_HPF_ENA_SHIFT 4 /* ADC_HPF_ENA */
-#define WM8903_ADC_HPF_ENA_WIDTH 1 /* ADC_HPF_ENA */
-#define WM8903_ADCL_DATINV 0x0002 /* ADCL_DATINV */
-#define WM8903_ADCL_DATINV_MASK 0x0002 /* ADCL_DATINV */
-#define WM8903_ADCL_DATINV_SHIFT 1 /* ADCL_DATINV */
-#define WM8903_ADCL_DATINV_WIDTH 1 /* ADCL_DATINV */
-#define WM8903_ADCR_DATINV 0x0001 /* ADCR_DATINV */
-#define WM8903_ADCR_DATINV_MASK 0x0001 /* ADCR_DATINV */
-#define WM8903_ADCR_DATINV_SHIFT 0 /* ADCR_DATINV */
-#define WM8903_ADCR_DATINV_WIDTH 1 /* ADCR_DATINV */
-
-/*
- * R39 (0x27) - Digital Microphone 0
- */
-#define WM8903_DIGMIC_MODE_SEL 0x0100 /* DIGMIC_MODE_SEL */
-#define WM8903_DIGMIC_MODE_SEL_MASK 0x0100 /* DIGMIC_MODE_SEL */
-#define WM8903_DIGMIC_MODE_SEL_SHIFT 8 /* DIGMIC_MODE_SEL */
-#define WM8903_DIGMIC_MODE_SEL_WIDTH 1 /* DIGMIC_MODE_SEL */
-#define WM8903_DIGMIC_CLK_SEL_L_MASK 0x00C0 /* DIGMIC_CLK_SEL_L - [7:6] */
-#define WM8903_DIGMIC_CLK_SEL_L_SHIFT 6 /* DIGMIC_CLK_SEL_L - [7:6] */
-#define WM8903_DIGMIC_CLK_SEL_L_WIDTH 2 /* DIGMIC_CLK_SEL_L - [7:6] */
-#define WM8903_DIGMIC_CLK_SEL_R_MASK 0x0030 /* DIGMIC_CLK_SEL_R - [5:4] */
-#define WM8903_DIGMIC_CLK_SEL_R_SHIFT 4 /* DIGMIC_CLK_SEL_R - [5:4] */
-#define WM8903_DIGMIC_CLK_SEL_R_WIDTH 2 /* DIGMIC_CLK_SEL_R - [5:4] */
-#define WM8903_DIGMIC_CLK_SEL_RT_MASK 0x000C /* DIGMIC_CLK_SEL_RT - [3:2] */
-#define WM8903_DIGMIC_CLK_SEL_RT_SHIFT 2 /* DIGMIC_CLK_SEL_RT - [3:2] */
-#define WM8903_DIGMIC_CLK_SEL_RT_WIDTH 2 /* DIGMIC_CLK_SEL_RT - [3:2] */
-#define WM8903_DIGMIC_CLK_SEL_MASK 0x0003 /* DIGMIC_CLK_SEL - [1:0] */
-#define WM8903_DIGMIC_CLK_SEL_SHIFT 0 /* DIGMIC_CLK_SEL - [1:0] */
-#define WM8903_DIGMIC_CLK_SEL_WIDTH 2 /* DIGMIC_CLK_SEL - [1:0] */
-
-/*
- * R40 (0x28) - DRC 0
- */
-#define WM8903_DRC_ENA 0x8000 /* DRC_ENA */
-#define WM8903_DRC_ENA_MASK 0x8000 /* DRC_ENA */
-#define WM8903_DRC_ENA_SHIFT 15 /* DRC_ENA */
-#define WM8903_DRC_ENA_WIDTH 1 /* DRC_ENA */
-#define WM8903_DRC_THRESH_HYST_MASK 0x1800 /* DRC_THRESH_HYST - [12:11] */
-#define WM8903_DRC_THRESH_HYST_SHIFT 11 /* DRC_THRESH_HYST - [12:11] */
-#define WM8903_DRC_THRESH_HYST_WIDTH 2 /* DRC_THRESH_HYST - [12:11] */
-#define WM8903_DRC_STARTUP_GAIN_MASK 0x07C0 /* DRC_STARTUP_GAIN - [10:6] */
-#define WM8903_DRC_STARTUP_GAIN_SHIFT 6 /* DRC_STARTUP_GAIN - [10:6] */
-#define WM8903_DRC_STARTUP_GAIN_WIDTH 5 /* DRC_STARTUP_GAIN - [10:6] */
-#define WM8903_DRC_FF_DELAY 0x0020 /* DRC_FF_DELAY */
-#define WM8903_DRC_FF_DELAY_MASK 0x0020 /* DRC_FF_DELAY */
-#define WM8903_DRC_FF_DELAY_SHIFT 5 /* DRC_FF_DELAY */
-#define WM8903_DRC_FF_DELAY_WIDTH 1 /* DRC_FF_DELAY */
-#define WM8903_DRC_SMOOTH_ENA 0x0008 /* DRC_SMOOTH_ENA */
-#define WM8903_DRC_SMOOTH_ENA_MASK 0x0008 /* DRC_SMOOTH_ENA */
-#define WM8903_DRC_SMOOTH_ENA_SHIFT 3 /* DRC_SMOOTH_ENA */
-#define WM8903_DRC_SMOOTH_ENA_WIDTH 1 /* DRC_SMOOTH_ENA */
-#define WM8903_DRC_QR_ENA 0x0004 /* DRC_QR_ENA */
-#define WM8903_DRC_QR_ENA_MASK 0x0004 /* DRC_QR_ENA */
-#define WM8903_DRC_QR_ENA_SHIFT 2 /* DRC_QR_ENA */
-#define WM8903_DRC_QR_ENA_WIDTH 1 /* DRC_QR_ENA */
-#define WM8903_DRC_ANTICLIP_ENA 0x0002 /* DRC_ANTICLIP_ENA */
-#define WM8903_DRC_ANTICLIP_ENA_MASK 0x0002 /* DRC_ANTICLIP_ENA */
-#define WM8903_DRC_ANTICLIP_ENA_SHIFT 1 /* DRC_ANTICLIP_ENA */
-#define WM8903_DRC_ANTICLIP_ENA_WIDTH 1 /* DRC_ANTICLIP_ENA */
-#define WM8903_DRC_HYST_ENA 0x0001 /* DRC_HYST_ENA */
-#define WM8903_DRC_HYST_ENA_MASK 0x0001 /* DRC_HYST_ENA */
-#define WM8903_DRC_HYST_ENA_SHIFT 0 /* DRC_HYST_ENA */
-#define WM8903_DRC_HYST_ENA_WIDTH 1 /* DRC_HYST_ENA */
-
-/*
- * R41 (0x29) - DRC 1
- */
-#define WM8903_DRC_ATTACK_RATE_MASK 0xF000 /* DRC_ATTACK_RATE - [15:12] */
-#define WM8903_DRC_ATTACK_RATE_SHIFT 12 /* DRC_ATTACK_RATE - [15:12] */
-#define WM8903_DRC_ATTACK_RATE_WIDTH 4 /* DRC_ATTACK_RATE - [15:12] */
-#define WM8903_DRC_DECAY_RATE_MASK 0x0F00 /* DRC_DECAY_RATE - [11:8] */
-#define WM8903_DRC_DECAY_RATE_SHIFT 8 /* DRC_DECAY_RATE - [11:8] */
-#define WM8903_DRC_DECAY_RATE_WIDTH 4 /* DRC_DECAY_RATE - [11:8] */
-#define WM8903_DRC_THRESH_QR_MASK 0x00C0 /* DRC_THRESH_QR - [7:6] */
-#define WM8903_DRC_THRESH_QR_SHIFT 6 /* DRC_THRESH_QR - [7:6] */
-#define WM8903_DRC_THRESH_QR_WIDTH 2 /* DRC_THRESH_QR - [7:6] */
-#define WM8903_DRC_RATE_QR_MASK 0x0030 /* DRC_RATE_QR - [5:4] */
-#define WM8903_DRC_RATE_QR_SHIFT 4 /* DRC_RATE_QR - [5:4] */
-#define WM8903_DRC_RATE_QR_WIDTH 2 /* DRC_RATE_QR - [5:4] */
-#define WM8903_DRC_MINGAIN_MASK 0x000C /* DRC_MINGAIN - [3:2] */
-#define WM8903_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [3:2] */
-#define WM8903_DRC_MINGAIN_WIDTH 2 /* DRC_MINGAIN - [3:2] */
-#define WM8903_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */
-#define WM8903_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */
-#define WM8903_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */
-
-/*
- * R42 (0x2A) - DRC 2
- */
-#define WM8903_DRC_R0_SLOPE_COMP_MASK 0x0038 /* DRC_R0_SLOPE_COMP - [5:3] */
-#define WM8903_DRC_R0_SLOPE_COMP_SHIFT 3 /* DRC_R0_SLOPE_COMP - [5:3] */
-#define WM8903_DRC_R0_SLOPE_COMP_WIDTH 3 /* DRC_R0_SLOPE_COMP - [5:3] */
-#define WM8903_DRC_R1_SLOPE_COMP_MASK 0x0007 /* DRC_R1_SLOPE_COMP - [2:0] */
-#define WM8903_DRC_R1_SLOPE_COMP_SHIFT 0 /* DRC_R1_SLOPE_COMP - [2:0] */
-#define WM8903_DRC_R1_SLOPE_COMP_WIDTH 3 /* DRC_R1_SLOPE_COMP - [2:0] */
-
-/*
- * R43 (0x2B) - DRC 3
- */
-#define WM8903_DRC_THRESH_COMP_MASK 0x07E0 /* DRC_THRESH_COMP - [10:5] */
-#define WM8903_DRC_THRESH_COMP_SHIFT 5 /* DRC_THRESH_COMP - [10:5] */
-#define WM8903_DRC_THRESH_COMP_WIDTH 6 /* DRC_THRESH_COMP - [10:5] */
-#define WM8903_DRC_AMP_COMP_MASK 0x001F /* DRC_AMP_COMP - [4:0] */
-#define WM8903_DRC_AMP_COMP_SHIFT 0 /* DRC_AMP_COMP - [4:0] */
-#define WM8903_DRC_AMP_COMP_WIDTH 5 /* DRC_AMP_COMP - [4:0] */
-
-/*
- * R44 (0x2C) - Analogue Left Input 0
- */
-#define WM8903_LINMUTE 0x0080 /* LINMUTE */
-#define WM8903_LINMUTE_MASK 0x0080 /* LINMUTE */
-#define WM8903_LINMUTE_SHIFT 7 /* LINMUTE */
-#define WM8903_LINMUTE_WIDTH 1 /* LINMUTE */
-#define WM8903_LIN_VOL_MASK 0x001F /* LIN_VOL - [4:0] */
-#define WM8903_LIN_VOL_SHIFT 0 /* LIN_VOL - [4:0] */
-#define WM8903_LIN_VOL_WIDTH 5 /* LIN_VOL - [4:0] */
-
-/*
- * R45 (0x2D) - Analogue Right Input 0
- */
-#define WM8903_RINMUTE 0x0080 /* RINMUTE */
-#define WM8903_RINMUTE_MASK 0x0080 /* RINMUTE */
-#define WM8903_RINMUTE_SHIFT 7 /* RINMUTE */
-#define WM8903_RINMUTE_WIDTH 1 /* RINMUTE */
-#define WM8903_RIN_VOL_MASK 0x001F /* RIN_VOL - [4:0] */
-#define WM8903_RIN_VOL_SHIFT 0 /* RIN_VOL - [4:0] */
-#define WM8903_RIN_VOL_WIDTH 5 /* RIN_VOL - [4:0] */
-
-/*
- * R46 (0x2E) - Analogue Left Input 1
- */
-#define WM8903_INL_CM_ENA 0x0040 /* INL_CM_ENA */
-#define WM8903_INL_CM_ENA_MASK 0x0040 /* INL_CM_ENA */
-#define WM8903_INL_CM_ENA_SHIFT 6 /* INL_CM_ENA */
-#define WM8903_INL_CM_ENA_WIDTH 1 /* INL_CM_ENA */
-#define WM8903_L_IP_SEL_N_MASK 0x0030 /* L_IP_SEL_N - [5:4] */
-#define WM8903_L_IP_SEL_N_SHIFT 4 /* L_IP_SEL_N - [5:4] */
-#define WM8903_L_IP_SEL_N_WIDTH 2 /* L_IP_SEL_N - [5:4] */
-#define WM8903_L_IP_SEL_P_MASK 0x000C /* L_IP_SEL_P - [3:2] */
-#define WM8903_L_IP_SEL_P_SHIFT 2 /* L_IP_SEL_P - [3:2] */
-#define WM8903_L_IP_SEL_P_WIDTH 2 /* L_IP_SEL_P - [3:2] */
-#define WM8903_L_MODE_MASK 0x0003 /* L_MODE - [1:0] */
-#define WM8903_L_MODE_SHIFT 0 /* L_MODE - [1:0] */
-#define WM8903_L_MODE_WIDTH 2 /* L_MODE - [1:0] */
-
-/*
- * R47 (0x2F) - Analogue Right Input 1
- */
-#define WM8903_INR_CM_ENA 0x0040 /* INR_CM_ENA */
-#define WM8903_INR_CM_ENA_MASK 0x0040 /* INR_CM_ENA */
-#define WM8903_INR_CM_ENA_SHIFT 6 /* INR_CM_ENA */
-#define WM8903_INR_CM_ENA_WIDTH 1 /* INR_CM_ENA */
-#define WM8903_R_IP_SEL_N_MASK 0x0030 /* R_IP_SEL_N - [5:4] */
-#define WM8903_R_IP_SEL_N_SHIFT 4 /* R_IP_SEL_N - [5:4] */
-#define WM8903_R_IP_SEL_N_WIDTH 2 /* R_IP_SEL_N - [5:4] */
-#define WM8903_R_IP_SEL_P_MASK 0x000C /* R_IP_SEL_P - [3:2] */
-#define WM8903_R_IP_SEL_P_SHIFT 2 /* R_IP_SEL_P - [3:2] */
-#define WM8903_R_IP_SEL_P_WIDTH 2 /* R_IP_SEL_P - [3:2] */
-#define WM8903_R_MODE_MASK 0x0003 /* R_MODE - [1:0] */
-#define WM8903_R_MODE_SHIFT 0 /* R_MODE - [1:0] */
-#define WM8903_R_MODE_WIDTH 2 /* R_MODE - [1:0] */
-
-/*
- * R50 (0x32) - Analogue Left Mix 0
- */
-#define WM8903_DACL_TO_MIXOUTL 0x0008 /* DACL_TO_MIXOUTL */
-#define WM8903_DACL_TO_MIXOUTL_MASK 0x0008 /* DACL_TO_MIXOUTL */
-#define WM8903_DACL_TO_MIXOUTL_SHIFT 3 /* DACL_TO_MIXOUTL */
-#define WM8903_DACL_TO_MIXOUTL_WIDTH 1 /* DACL_TO_MIXOUTL */
-#define WM8903_DACR_TO_MIXOUTL 0x0004 /* DACR_TO_MIXOUTL */
-#define WM8903_DACR_TO_MIXOUTL_MASK 0x0004 /* DACR_TO_MIXOUTL */
-#define WM8903_DACR_TO_MIXOUTL_SHIFT 2 /* DACR_TO_MIXOUTL */
-#define WM8903_DACR_TO_MIXOUTL_WIDTH 1 /* DACR_TO_MIXOUTL */
-#define WM8903_BYPASSL_TO_MIXOUTL 0x0002 /* BYPASSL_TO_MIXOUTL */
-#define WM8903_BYPASSL_TO_MIXOUTL_MASK 0x0002 /* BYPASSL_TO_MIXOUTL */
-#define WM8903_BYPASSL_TO_MIXOUTL_SHIFT 1 /* BYPASSL_TO_MIXOUTL */
-#define WM8903_BYPASSL_TO_MIXOUTL_WIDTH 1 /* BYPASSL_TO_MIXOUTL */
-#define WM8903_BYPASSR_TO_MIXOUTL 0x0001 /* BYPASSR_TO_MIXOUTL */
-#define WM8903_BYPASSR_TO_MIXOUTL_MASK 0x0001 /* BYPASSR_TO_MIXOUTL */
-#define WM8903_BYPASSR_TO_MIXOUTL_SHIFT 0 /* BYPASSR_TO_MIXOUTL */
-#define WM8903_BYPASSR_TO_MIXOUTL_WIDTH 1 /* BYPASSR_TO_MIXOUTL */
-
-/*
- * R51 (0x33) - Analogue Right Mix 0
- */
-#define WM8903_DACL_TO_MIXOUTR 0x0008 /* DACL_TO_MIXOUTR */
-#define WM8903_DACL_TO_MIXOUTR_MASK 0x0008 /* DACL_TO_MIXOUTR */
-#define WM8903_DACL_TO_MIXOUTR_SHIFT 3 /* DACL_TO_MIXOUTR */
-#define WM8903_DACL_TO_MIXOUTR_WIDTH 1 /* DACL_TO_MIXOUTR */
-#define WM8903_DACR_TO_MIXOUTR 0x0004 /* DACR_TO_MIXOUTR */
-#define WM8903_DACR_TO_MIXOUTR_MASK 0x0004 /* DACR_TO_MIXOUTR */
-#define WM8903_DACR_TO_MIXOUTR_SHIFT 2 /* DACR_TO_MIXOUTR */
-#define WM8903_DACR_TO_MIXOUTR_WIDTH 1 /* DACR_TO_MIXOUTR */
-#define WM8903_BYPASSL_TO_MIXOUTR 0x0002 /* BYPASSL_TO_MIXOUTR */
-#define WM8903_BYPASSL_TO_MIXOUTR_MASK 0x0002 /* BYPASSL_TO_MIXOUTR */
-#define WM8903_BYPASSL_TO_MIXOUTR_SHIFT 1 /* BYPASSL_TO_MIXOUTR */
-#define WM8903_BYPASSL_TO_MIXOUTR_WIDTH 1 /* BYPASSL_TO_MIXOUTR */
-#define WM8903_BYPASSR_TO_MIXOUTR 0x0001 /* BYPASSR_TO_MIXOUTR */
-#define WM8903_BYPASSR_TO_MIXOUTR_MASK 0x0001 /* BYPASSR_TO_MIXOUTR */
-#define WM8903_BYPASSR_TO_MIXOUTR_SHIFT 0 /* BYPASSR_TO_MIXOUTR */
-#define WM8903_BYPASSR_TO_MIXOUTR_WIDTH 1 /* BYPASSR_TO_MIXOUTR */
-
-/*
- * R52 (0x34) - Analogue Spk Mix Left 0
- */
-#define WM8903_DACL_TO_MIXSPKL 0x0008 /* DACL_TO_MIXSPKL */
-#define WM8903_DACL_TO_MIXSPKL_MASK 0x0008 /* DACL_TO_MIXSPKL */
-#define WM8903_DACL_TO_MIXSPKL_SHIFT 3 /* DACL_TO_MIXSPKL */
-#define WM8903_DACL_TO_MIXSPKL_WIDTH 1 /* DACL_TO_MIXSPKL */
-#define WM8903_DACR_TO_MIXSPKL 0x0004 /* DACR_TO_MIXSPKL */
-#define WM8903_DACR_TO_MIXSPKL_MASK 0x0004 /* DACR_TO_MIXSPKL */
-#define WM8903_DACR_TO_MIXSPKL_SHIFT 2 /* DACR_TO_MIXSPKL */
-#define WM8903_DACR_TO_MIXSPKL_WIDTH 1 /* DACR_TO_MIXSPKL */
-#define WM8903_BYPASSL_TO_MIXSPKL 0x0002 /* BYPASSL_TO_MIXSPKL */
-#define WM8903_BYPASSL_TO_MIXSPKL_MASK 0x0002 /* BYPASSL_TO_MIXSPKL */
-#define WM8903_BYPASSL_TO_MIXSPKL_SHIFT 1 /* BYPASSL_TO_MIXSPKL */
-#define WM8903_BYPASSL_TO_MIXSPKL_WIDTH 1 /* BYPASSL_TO_MIXSPKL */
-#define WM8903_BYPASSR_TO_MIXSPKL 0x0001 /* BYPASSR_TO_MIXSPKL */
-#define WM8903_BYPASSR_TO_MIXSPKL_MASK 0x0001 /* BYPASSR_TO_MIXSPKL */
-#define WM8903_BYPASSR_TO_MIXSPKL_SHIFT 0 /* BYPASSR_TO_MIXSPKL */
-#define WM8903_BYPASSR_TO_MIXSPKL_WIDTH 1 /* BYPASSR_TO_MIXSPKL */
-
-/*
- * R53 (0x35) - Analogue Spk Mix Left 1
- */
-#define WM8903_DACL_MIXSPKL_VOL 0x0008 /* DACL_MIXSPKL_VOL */
-#define WM8903_DACL_MIXSPKL_VOL_MASK 0x0008 /* DACL_MIXSPKL_VOL */
-#define WM8903_DACL_MIXSPKL_VOL_SHIFT 3 /* DACL_MIXSPKL_VOL */
-#define WM8903_DACL_MIXSPKL_VOL_WIDTH 1 /* DACL_MIXSPKL_VOL */
-#define WM8903_DACR_MIXSPKL_VOL 0x0004 /* DACR_MIXSPKL_VOL */
-#define WM8903_DACR_MIXSPKL_VOL_MASK 0x0004 /* DACR_MIXSPKL_VOL */
-#define WM8903_DACR_MIXSPKL_VOL_SHIFT 2 /* DACR_MIXSPKL_VOL */
-#define WM8903_DACR_MIXSPKL_VOL_WIDTH 1 /* DACR_MIXSPKL_VOL */
-#define WM8903_BYPASSL_MIXSPKL_VOL 0x0002 /* BYPASSL_MIXSPKL_VOL */
-#define WM8903_BYPASSL_MIXSPKL_VOL_MASK 0x0002 /* BYPASSL_MIXSPKL_VOL */
-#define WM8903_BYPASSL_MIXSPKL_VOL_SHIFT 1 /* BYPASSL_MIXSPKL_VOL */
-#define WM8903_BYPASSL_MIXSPKL_VOL_WIDTH 1 /* BYPASSL_MIXSPKL_VOL */
-#define WM8903_BYPASSR_MIXSPKL_VOL 0x0001 /* BYPASSR_MIXSPKL_VOL */
-#define WM8903_BYPASSR_MIXSPKL_VOL_MASK 0x0001 /* BYPASSR_MIXSPKL_VOL */
-#define WM8903_BYPASSR_MIXSPKL_VOL_SHIFT 0 /* BYPASSR_MIXSPKL_VOL */
-#define WM8903_BYPASSR_MIXSPKL_VOL_WIDTH 1 /* BYPASSR_MIXSPKL_VOL */
-
-/*
- * R54 (0x36) - Analogue Spk Mix Right 0
- */
-#define WM8903_DACL_TO_MIXSPKR 0x0008 /* DACL_TO_MIXSPKR */
-#define WM8903_DACL_TO_MIXSPKR_MASK 0x0008 /* DACL_TO_MIXSPKR */
-#define WM8903_DACL_TO_MIXSPKR_SHIFT 3 /* DACL_TO_MIXSPKR */
-#define WM8903_DACL_TO_MIXSPKR_WIDTH 1 /* DACL_TO_MIXSPKR */
-#define WM8903_DACR_TO_MIXSPKR 0x0004 /* DACR_TO_MIXSPKR */
-#define WM8903_DACR_TO_MIXSPKR_MASK 0x0004 /* DACR_TO_MIXSPKR */
-#define WM8903_DACR_TO_MIXSPKR_SHIFT 2 /* DACR_TO_MIXSPKR */
-#define WM8903_DACR_TO_MIXSPKR_WIDTH 1 /* DACR_TO_MIXSPKR */
-#define WM8903_BYPASSL_TO_MIXSPKR 0x0002 /* BYPASSL_TO_MIXSPKR */
-#define WM8903_BYPASSL_TO_MIXSPKR_MASK 0x0002 /* BYPASSL_TO_MIXSPKR */
-#define WM8903_BYPASSL_TO_MIXSPKR_SHIFT 1 /* BYPASSL_TO_MIXSPKR */
-#define WM8903_BYPASSL_TO_MIXSPKR_WIDTH 1 /* BYPASSL_TO_MIXSPKR */
-#define WM8903_BYPASSR_TO_MIXSPKR 0x0001 /* BYPASSR_TO_MIXSPKR */
-#define WM8903_BYPASSR_TO_MIXSPKR_MASK 0x0001 /* BYPASSR_TO_MIXSPKR */
-#define WM8903_BYPASSR_TO_MIXSPKR_SHIFT 0 /* BYPASSR_TO_MIXSPKR */
-#define WM8903_BYPASSR_TO_MIXSPKR_WIDTH 1 /* BYPASSR_TO_MIXSPKR */
-
-/*
- * R55 (0x37) - Analogue Spk Mix Right 1
- */
-#define WM8903_DACL_MIXSPKR_VOL 0x0008 /* DACL_MIXSPKR_VOL */
-#define WM8903_DACL_MIXSPKR_VOL_MASK 0x0008 /* DACL_MIXSPKR_VOL */
-#define WM8903_DACL_MIXSPKR_VOL_SHIFT 3 /* DACL_MIXSPKR_VOL */
-#define WM8903_DACL_MIXSPKR_VOL_WIDTH 1 /* DACL_MIXSPKR_VOL */
-#define WM8903_DACR_MIXSPKR_VOL 0x0004 /* DACR_MIXSPKR_VOL */
-#define WM8903_DACR_MIXSPKR_VOL_MASK 0x0004 /* DACR_MIXSPKR_VOL */
-#define WM8903_DACR_MIXSPKR_VOL_SHIFT 2 /* DACR_MIXSPKR_VOL */
-#define WM8903_DACR_MIXSPKR_VOL_WIDTH 1 /* DACR_MIXSPKR_VOL */
-#define WM8903_BYPASSL_MIXSPKR_VOL 0x0002 /* BYPASSL_MIXSPKR_VOL */
-#define WM8903_BYPASSL_MIXSPKR_VOL_MASK 0x0002 /* BYPASSL_MIXSPKR_VOL */
-#define WM8903_BYPASSL_MIXSPKR_VOL_SHIFT 1 /* BYPASSL_MIXSPKR_VOL */
-#define WM8903_BYPASSL_MIXSPKR_VOL_WIDTH 1 /* BYPASSL_MIXSPKR_VOL */
-#define WM8903_BYPASSR_MIXSPKR_VOL 0x0001 /* BYPASSR_MIXSPKR_VOL */
-#define WM8903_BYPASSR_MIXSPKR_VOL_MASK 0x0001 /* BYPASSR_MIXSPKR_VOL */
-#define WM8903_BYPASSR_MIXSPKR_VOL_SHIFT 0 /* BYPASSR_MIXSPKR_VOL */
-#define WM8903_BYPASSR_MIXSPKR_VOL_WIDTH 1 /* BYPASSR_MIXSPKR_VOL */
-
-/*
- * R57 (0x39) - Analogue OUT1 Left
- */
-#define WM8903_HPL_MUTE 0x0100 /* HPL_MUTE */
-#define WM8903_HPL_MUTE_MASK 0x0100 /* HPL_MUTE */
-#define WM8903_HPL_MUTE_SHIFT 8 /* HPL_MUTE */
-#define WM8903_HPL_MUTE_WIDTH 1 /* HPL_MUTE */
-#define WM8903_HPOUTVU 0x0080 /* HPOUTVU */
-#define WM8903_HPOUTVU_MASK 0x0080 /* HPOUTVU */
-#define WM8903_HPOUTVU_SHIFT 7 /* HPOUTVU */
-#define WM8903_HPOUTVU_WIDTH 1 /* HPOUTVU */
-#define WM8903_HPOUTLZC 0x0040 /* HPOUTLZC */
-#define WM8903_HPOUTLZC_MASK 0x0040 /* HPOUTLZC */
-#define WM8903_HPOUTLZC_SHIFT 6 /* HPOUTLZC */
-#define WM8903_HPOUTLZC_WIDTH 1 /* HPOUTLZC */
-#define WM8903_HPOUTL_VOL_MASK 0x003F /* HPOUTL_VOL - [5:0] */
-#define WM8903_HPOUTL_VOL_SHIFT 0 /* HPOUTL_VOL - [5:0] */
-#define WM8903_HPOUTL_VOL_WIDTH 6 /* HPOUTL_VOL - [5:0] */
-
-/*
- * R58 (0x3A) - Analogue OUT1 Right
- */
-#define WM8903_HPR_MUTE 0x0100 /* HPR_MUTE */
-#define WM8903_HPR_MUTE_MASK 0x0100 /* HPR_MUTE */
-#define WM8903_HPR_MUTE_SHIFT 8 /* HPR_MUTE */
-#define WM8903_HPR_MUTE_WIDTH 1 /* HPR_MUTE */
-#define WM8903_HPOUTVU 0x0080 /* HPOUTVU */
-#define WM8903_HPOUTVU_MASK 0x0080 /* HPOUTVU */
-#define WM8903_HPOUTVU_SHIFT 7 /* HPOUTVU */
-#define WM8903_HPOUTVU_WIDTH 1 /* HPOUTVU */
-#define WM8903_HPOUTRZC 0x0040 /* HPOUTRZC */
-#define WM8903_HPOUTRZC_MASK 0x0040 /* HPOUTRZC */
-#define WM8903_HPOUTRZC_SHIFT 6 /* HPOUTRZC */
-#define WM8903_HPOUTRZC_WIDTH 1 /* HPOUTRZC */
-#define WM8903_HPOUTR_VOL_MASK 0x003F /* HPOUTR_VOL - [5:0] */
-#define WM8903_HPOUTR_VOL_SHIFT 0 /* HPOUTR_VOL - [5:0] */
-#define WM8903_HPOUTR_VOL_WIDTH 6 /* HPOUTR_VOL - [5:0] */
-
-/*
- * R59 (0x3B) - Analogue OUT2 Left
- */
-#define WM8903_LINEOUTL_MUTE 0x0100 /* LINEOUTL_MUTE */
-#define WM8903_LINEOUTL_MUTE_MASK 0x0100 /* LINEOUTL_MUTE */
-#define WM8903_LINEOUTL_MUTE_SHIFT 8 /* LINEOUTL_MUTE */
-#define WM8903_LINEOUTL_MUTE_WIDTH 1 /* LINEOUTL_MUTE */
-#define WM8903_LINEOUTVU 0x0080 /* LINEOUTVU */
-#define WM8903_LINEOUTVU_MASK 0x0080 /* LINEOUTVU */
-#define WM8903_LINEOUTVU_SHIFT 7 /* LINEOUTVU */
-#define WM8903_LINEOUTVU_WIDTH 1 /* LINEOUTVU */
-#define WM8903_LINEOUTLZC 0x0040 /* LINEOUTLZC */
-#define WM8903_LINEOUTLZC_MASK 0x0040 /* LINEOUTLZC */
-#define WM8903_LINEOUTLZC_SHIFT 6 /* LINEOUTLZC */
-#define WM8903_LINEOUTLZC_WIDTH 1 /* LINEOUTLZC */
-#define WM8903_LINEOUTL_VOL_MASK 0x003F /* LINEOUTL_VOL - [5:0] */
-#define WM8903_LINEOUTL_VOL_SHIFT 0 /* LINEOUTL_VOL - [5:0] */
-#define WM8903_LINEOUTL_VOL_WIDTH 6 /* LINEOUTL_VOL - [5:0] */
-
-/*
- * R60 (0x3C) - Analogue OUT2 Right
- */
-#define WM8903_LINEOUTR_MUTE 0x0100 /* LINEOUTR_MUTE */
-#define WM8903_LINEOUTR_MUTE_MASK 0x0100 /* LINEOUTR_MUTE */
-#define WM8903_LINEOUTR_MUTE_SHIFT 8 /* LINEOUTR_MUTE */
-#define WM8903_LINEOUTR_MUTE_WIDTH 1 /* LINEOUTR_MUTE */
-#define WM8903_LINEOUTVU 0x0080 /* LINEOUTVU */
-#define WM8903_LINEOUTVU_MASK 0x0080 /* LINEOUTVU */
-#define WM8903_LINEOUTVU_SHIFT 7 /* LINEOUTVU */
-#define WM8903_LINEOUTVU_WIDTH 1 /* LINEOUTVU */
-#define WM8903_LINEOUTRZC 0x0040 /* LINEOUTRZC */
-#define WM8903_LINEOUTRZC_MASK 0x0040 /* LINEOUTRZC */
-#define WM8903_LINEOUTRZC_SHIFT 6 /* LINEOUTRZC */
-#define WM8903_LINEOUTRZC_WIDTH 1 /* LINEOUTRZC */
-#define WM8903_LINEOUTR_VOL_MASK 0x003F /* LINEOUTR_VOL - [5:0] */
-#define WM8903_LINEOUTR_VOL_SHIFT 0 /* LINEOUTR_VOL - [5:0] */
-#define WM8903_LINEOUTR_VOL_WIDTH 6 /* LINEOUTR_VOL - [5:0] */
-
-/*
- * R62 (0x3E) - Analogue OUT3 Left
- */
-#define WM8903_SPKL_MUTE 0x0100 /* SPKL_MUTE */
-#define WM8903_SPKL_MUTE_MASK 0x0100 /* SPKL_MUTE */
-#define WM8903_SPKL_MUTE_SHIFT 8 /* SPKL_MUTE */
-#define WM8903_SPKL_MUTE_WIDTH 1 /* SPKL_MUTE */
-#define WM8903_SPKVU 0x0080 /* SPKVU */
-#define WM8903_SPKVU_MASK 0x0080 /* SPKVU */
-#define WM8903_SPKVU_SHIFT 7 /* SPKVU */
-#define WM8903_SPKVU_WIDTH 1 /* SPKVU */
-#define WM8903_SPKLZC 0x0040 /* SPKLZC */
-#define WM8903_SPKLZC_MASK 0x0040 /* SPKLZC */
-#define WM8903_SPKLZC_SHIFT 6 /* SPKLZC */
-#define WM8903_SPKLZC_WIDTH 1 /* SPKLZC */
-#define WM8903_SPKL_VOL_MASK 0x003F /* SPKL_VOL - [5:0] */
-#define WM8903_SPKL_VOL_SHIFT 0 /* SPKL_VOL - [5:0] */
-#define WM8903_SPKL_VOL_WIDTH 6 /* SPKL_VOL - [5:0] */
-
-/*
- * R63 (0x3F) - Analogue OUT3 Right
- */
-#define WM8903_SPKR_MUTE 0x0100 /* SPKR_MUTE */
-#define WM8903_SPKR_MUTE_MASK 0x0100 /* SPKR_MUTE */
-#define WM8903_SPKR_MUTE_SHIFT 8 /* SPKR_MUTE */
-#define WM8903_SPKR_MUTE_WIDTH 1 /* SPKR_MUTE */
-#define WM8903_SPKVU 0x0080 /* SPKVU */
-#define WM8903_SPKVU_MASK 0x0080 /* SPKVU */
-#define WM8903_SPKVU_SHIFT 7 /* SPKVU */
-#define WM8903_SPKVU_WIDTH 1 /* SPKVU */
-#define WM8903_SPKRZC 0x0040 /* SPKRZC */
-#define WM8903_SPKRZC_MASK 0x0040 /* SPKRZC */
-#define WM8903_SPKRZC_SHIFT 6 /* SPKRZC */
-#define WM8903_SPKRZC_WIDTH 1 /* SPKRZC */
-#define WM8903_SPKR_VOL_MASK 0x003F /* SPKR_VOL - [5:0] */
-#define WM8903_SPKR_VOL_SHIFT 0 /* SPKR_VOL - [5:0] */
-#define WM8903_SPKR_VOL_WIDTH 6 /* SPKR_VOL - [5:0] */
-
-/*
- * R65 (0x41) - Analogue SPK Output Control 0
- */
-#define WM8903_SPK_DISCHARGE 0x0002 /* SPK_DISCHARGE */
-#define WM8903_SPK_DISCHARGE_MASK 0x0002 /* SPK_DISCHARGE */
-#define WM8903_SPK_DISCHARGE_SHIFT 1 /* SPK_DISCHARGE */
-#define WM8903_SPK_DISCHARGE_WIDTH 1 /* SPK_DISCHARGE */
-#define WM8903_VROI 0x0001 /* VROI */
-#define WM8903_VROI_MASK 0x0001 /* VROI */
-#define WM8903_VROI_SHIFT 0 /* VROI */
-#define WM8903_VROI_WIDTH 1 /* VROI */
-
-/*
- * R67 (0x43) - DC Servo 0
- */
-#define WM8903_DCS_MASTER_ENA 0x0010 /* DCS_MASTER_ENA */
-#define WM8903_DCS_MASTER_ENA_MASK 0x0010 /* DCS_MASTER_ENA */
-#define WM8903_DCS_MASTER_ENA_SHIFT 4 /* DCS_MASTER_ENA */
-#define WM8903_DCS_MASTER_ENA_WIDTH 1 /* DCS_MASTER_ENA */
-#define WM8903_DCS_ENA_MASK 0x000F /* DCS_ENA - [3:0] */
-#define WM8903_DCS_ENA_SHIFT 0 /* DCS_ENA - [3:0] */
-#define WM8903_DCS_ENA_WIDTH 4 /* DCS_ENA - [3:0] */
-
-/*
- * R69 (0x45) - DC Servo 2
- */
-#define WM8903_DCS_MODE_MASK 0x0003 /* DCS_MODE - [1:0] */
-#define WM8903_DCS_MODE_SHIFT 0 /* DCS_MODE - [1:0] */
-#define WM8903_DCS_MODE_WIDTH 2 /* DCS_MODE - [1:0] */
-
-/*
- * R90 (0x5A) - Analogue HP 0
- */
-#define WM8903_HPL_RMV_SHORT 0x0080 /* HPL_RMV_SHORT */
-#define WM8903_HPL_RMV_SHORT_MASK 0x0080 /* HPL_RMV_SHORT */
-#define WM8903_HPL_RMV_SHORT_SHIFT 7 /* HPL_RMV_SHORT */
-#define WM8903_HPL_RMV_SHORT_WIDTH 1 /* HPL_RMV_SHORT */
-#define WM8903_HPL_ENA_OUTP 0x0040 /* HPL_ENA_OUTP */
-#define WM8903_HPL_ENA_OUTP_MASK 0x0040 /* HPL_ENA_OUTP */
-#define WM8903_HPL_ENA_OUTP_SHIFT 6 /* HPL_ENA_OUTP */
-#define WM8903_HPL_ENA_OUTP_WIDTH 1 /* HPL_ENA_OUTP */
-#define WM8903_HPL_ENA_DLY 0x0020 /* HPL_ENA_DLY */
-#define WM8903_HPL_ENA_DLY_MASK 0x0020 /* HPL_ENA_DLY */
-#define WM8903_HPL_ENA_DLY_SHIFT 5 /* HPL_ENA_DLY */
-#define WM8903_HPL_ENA_DLY_WIDTH 1 /* HPL_ENA_DLY */
-#define WM8903_HPL_ENA 0x0010 /* HPL_ENA */
-#define WM8903_HPL_ENA_MASK 0x0010 /* HPL_ENA */
-#define WM8903_HPL_ENA_SHIFT 4 /* HPL_ENA */
-#define WM8903_HPL_ENA_WIDTH 1 /* HPL_ENA */
-#define WM8903_HPR_RMV_SHORT 0x0008 /* HPR_RMV_SHORT */
-#define WM8903_HPR_RMV_SHORT_MASK 0x0008 /* HPR_RMV_SHORT */
-#define WM8903_HPR_RMV_SHORT_SHIFT 3 /* HPR_RMV_SHORT */
-#define WM8903_HPR_RMV_SHORT_WIDTH 1 /* HPR_RMV_SHORT */
-#define WM8903_HPR_ENA_OUTP 0x0004 /* HPR_ENA_OUTP */
-#define WM8903_HPR_ENA_OUTP_MASK 0x0004 /* HPR_ENA_OUTP */
-#define WM8903_HPR_ENA_OUTP_SHIFT 2 /* HPR_ENA_OUTP */
-#define WM8903_HPR_ENA_OUTP_WIDTH 1 /* HPR_ENA_OUTP */
-#define WM8903_HPR_ENA_DLY 0x0002 /* HPR_ENA_DLY */
-#define WM8903_HPR_ENA_DLY_MASK 0x0002 /* HPR_ENA_DLY */
-#define WM8903_HPR_ENA_DLY_SHIFT 1 /* HPR_ENA_DLY */
-#define WM8903_HPR_ENA_DLY_WIDTH 1 /* HPR_ENA_DLY */
-#define WM8903_HPR_ENA 0x0001 /* HPR_ENA */
-#define WM8903_HPR_ENA_MASK 0x0001 /* HPR_ENA */
-#define WM8903_HPR_ENA_SHIFT 0 /* HPR_ENA */
-#define WM8903_HPR_ENA_WIDTH 1 /* HPR_ENA */
-
-/*
- * R94 (0x5E) - Analogue Lineout 0
- */
-#define WM8903_LINEOUTL_RMV_SHORT 0x0080 /* LINEOUTL_RMV_SHORT */
-#define WM8903_LINEOUTL_RMV_SHORT_MASK 0x0080 /* LINEOUTL_RMV_SHORT */
-#define WM8903_LINEOUTL_RMV_SHORT_SHIFT 7 /* LINEOUTL_RMV_SHORT */
-#define WM8903_LINEOUTL_RMV_SHORT_WIDTH 1 /* LINEOUTL_RMV_SHORT */
-#define WM8903_LINEOUTL_ENA_OUTP 0x0040 /* LINEOUTL_ENA_OUTP */
-#define WM8903_LINEOUTL_ENA_OUTP_MASK 0x0040 /* LINEOUTL_ENA_OUTP */
-#define WM8903_LINEOUTL_ENA_OUTP_SHIFT 6 /* LINEOUTL_ENA_OUTP */
-#define WM8903_LINEOUTL_ENA_OUTP_WIDTH 1 /* LINEOUTL_ENA_OUTP */
-#define WM8903_LINEOUTL_ENA_DLY 0x0020 /* LINEOUTL_ENA_DLY */
-#define WM8903_LINEOUTL_ENA_DLY_MASK 0x0020 /* LINEOUTL_ENA_DLY */
-#define WM8903_LINEOUTL_ENA_DLY_SHIFT 5 /* LINEOUTL_ENA_DLY */
-#define WM8903_LINEOUTL_ENA_DLY_WIDTH 1 /* LINEOUTL_ENA_DLY */
-#define WM8903_LINEOUTL_ENA 0x0010 /* LINEOUTL_ENA */
-#define WM8903_LINEOUTL_ENA_MASK 0x0010 /* LINEOUTL_ENA */
-#define WM8903_LINEOUTL_ENA_SHIFT 4 /* LINEOUTL_ENA */
-#define WM8903_LINEOUTL_ENA_WIDTH 1 /* LINEOUTL_ENA */
-#define WM8903_LINEOUTR_RMV_SHORT 0x0008 /* LINEOUTR_RMV_SHORT */
-#define WM8903_LINEOUTR_RMV_SHORT_MASK 0x0008 /* LINEOUTR_RMV_SHORT */
-#define WM8903_LINEOUTR_RMV_SHORT_SHIFT 3 /* LINEOUTR_RMV_SHORT */
-#define WM8903_LINEOUTR_RMV_SHORT_WIDTH 1 /* LINEOUTR_RMV_SHORT */
-#define WM8903_LINEOUTR_ENA_OUTP 0x0004 /* LINEOUTR_ENA_OUTP */
-#define WM8903_LINEOUTR_ENA_OUTP_MASK 0x0004 /* LINEOUTR_ENA_OUTP */
-#define WM8903_LINEOUTR_ENA_OUTP_SHIFT 2 /* LINEOUTR_ENA_OUTP */
-#define WM8903_LINEOUTR_ENA_OUTP_WIDTH 1 /* LINEOUTR_ENA_OUTP */
-#define WM8903_LINEOUTR_ENA_DLY 0x0002 /* LINEOUTR_ENA_DLY */
-#define WM8903_LINEOUTR_ENA_DLY_MASK 0x0002 /* LINEOUTR_ENA_DLY */
-#define WM8903_LINEOUTR_ENA_DLY_SHIFT 1 /* LINEOUTR_ENA_DLY */
-#define WM8903_LINEOUTR_ENA_DLY_WIDTH 1 /* LINEOUTR_ENA_DLY */
-#define WM8903_LINEOUTR_ENA 0x0001 /* LINEOUTR_ENA */
-#define WM8903_LINEOUTR_ENA_MASK 0x0001 /* LINEOUTR_ENA */
-#define WM8903_LINEOUTR_ENA_SHIFT 0 /* LINEOUTR_ENA */
-#define WM8903_LINEOUTR_ENA_WIDTH 1 /* LINEOUTR_ENA */
-
-/*
- * R98 (0x62) - Charge Pump 0
- */
-#define WM8903_CP_ENA 0x0001 /* CP_ENA */
-#define WM8903_CP_ENA_MASK 0x0001 /* CP_ENA */
-#define WM8903_CP_ENA_SHIFT 0 /* CP_ENA */
-#define WM8903_CP_ENA_WIDTH 1 /* CP_ENA */
-
-/*
- * R104 (0x68) - Class W 0
- */
-#define WM8903_CP_DYN_FREQ 0x0002 /* CP_DYN_FREQ */
-#define WM8903_CP_DYN_FREQ_MASK 0x0002 /* CP_DYN_FREQ */
-#define WM8903_CP_DYN_FREQ_SHIFT 1 /* CP_DYN_FREQ */
-#define WM8903_CP_DYN_FREQ_WIDTH 1 /* CP_DYN_FREQ */
-#define WM8903_CP_DYN_V 0x0001 /* CP_DYN_V */
-#define WM8903_CP_DYN_V_MASK 0x0001 /* CP_DYN_V */
-#define WM8903_CP_DYN_V_SHIFT 0 /* CP_DYN_V */
-#define WM8903_CP_DYN_V_WIDTH 1 /* CP_DYN_V */
-
-/*
- * R108 (0x6C) - Write Sequencer 0
- */
-#define WM8903_WSEQ_ENA 0x0100 /* WSEQ_ENA */
-#define WM8903_WSEQ_ENA_MASK 0x0100 /* WSEQ_ENA */
-#define WM8903_WSEQ_ENA_SHIFT 8 /* WSEQ_ENA */
-#define WM8903_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
-#define WM8903_WSEQ_WRITE_INDEX_MASK 0x001F /* WSEQ_WRITE_INDEX - [4:0] */
-#define WM8903_WSEQ_WRITE_INDEX_SHIFT 0 /* WSEQ_WRITE_INDEX - [4:0] */
-#define WM8903_WSEQ_WRITE_INDEX_WIDTH 5 /* WSEQ_WRITE_INDEX - [4:0] */
-
-/*
- * R109 (0x6D) - Write Sequencer 1
- */
-#define WM8903_WSEQ_DATA_WIDTH_MASK 0x7000 /* WSEQ_DATA_WIDTH - [14:12] */
-#define WM8903_WSEQ_DATA_WIDTH_SHIFT 12 /* WSEQ_DATA_WIDTH - [14:12] */
-#define WM8903_WSEQ_DATA_WIDTH_WIDTH 3 /* WSEQ_DATA_WIDTH - [14:12] */
-#define WM8903_WSEQ_DATA_START_MASK 0x0F00 /* WSEQ_DATA_START - [11:8] */
-#define WM8903_WSEQ_DATA_START_SHIFT 8 /* WSEQ_DATA_START - [11:8] */
-#define WM8903_WSEQ_DATA_START_WIDTH 4 /* WSEQ_DATA_START - [11:8] */
-#define WM8903_WSEQ_ADDR_MASK 0x00FF /* WSEQ_ADDR - [7:0] */
-#define WM8903_WSEQ_ADDR_SHIFT 0 /* WSEQ_ADDR - [7:0] */
-#define WM8903_WSEQ_ADDR_WIDTH 8 /* WSEQ_ADDR - [7:0] */
-
-/*
- * R110 (0x6E) - Write Sequencer 2
- */
-#define WM8903_WSEQ_EOS 0x4000 /* WSEQ_EOS */
-#define WM8903_WSEQ_EOS_MASK 0x4000 /* WSEQ_EOS */
-#define WM8903_WSEQ_EOS_SHIFT 14 /* WSEQ_EOS */
-#define WM8903_WSEQ_EOS_WIDTH 1 /* WSEQ_EOS */
-#define WM8903_WSEQ_DELAY_MASK 0x0F00 /* WSEQ_DELAY - [11:8] */
-#define WM8903_WSEQ_DELAY_SHIFT 8 /* WSEQ_DELAY - [11:8] */
-#define WM8903_WSEQ_DELAY_WIDTH 4 /* WSEQ_DELAY - [11:8] */
-#define WM8903_WSEQ_DATA_MASK 0x00FF /* WSEQ_DATA - [7:0] */
-#define WM8903_WSEQ_DATA_SHIFT 0 /* WSEQ_DATA - [7:0] */
-#define WM8903_WSEQ_DATA_WIDTH 8 /* WSEQ_DATA - [7:0] */
-
-/*
- * R111 (0x6F) - Write Sequencer 3
- */
-#define WM8903_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
-#define WM8903_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
-#define WM8903_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
-#define WM8903_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
-#define WM8903_WSEQ_START 0x0100 /* WSEQ_START */
-#define WM8903_WSEQ_START_MASK 0x0100 /* WSEQ_START */
-#define WM8903_WSEQ_START_SHIFT 8 /* WSEQ_START */
-#define WM8903_WSEQ_START_WIDTH 1 /* WSEQ_START */
-#define WM8903_WSEQ_START_INDEX_MASK 0x003F /* WSEQ_START_INDEX - [5:0] */
-#define WM8903_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [5:0] */
-#define WM8903_WSEQ_START_INDEX_WIDTH 6 /* WSEQ_START_INDEX - [5:0] */
-
-/*
- * R112 (0x70) - Write Sequencer 4
- */
-#define WM8903_WSEQ_CURRENT_INDEX_MASK 0x03F0 /* WSEQ_CURRENT_INDEX - [9:4] */
-#define WM8903_WSEQ_CURRENT_INDEX_SHIFT 4 /* WSEQ_CURRENT_INDEX - [9:4] */
-#define WM8903_WSEQ_CURRENT_INDEX_WIDTH 6 /* WSEQ_CURRENT_INDEX - [9:4] */
-#define WM8903_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
-#define WM8903_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
-#define WM8903_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
-#define WM8903_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
-
-/*
- * R114 (0x72) - Control Interface
- */
-#define WM8903_MASK_WRITE_ENA 0x0001 /* MASK_WRITE_ENA */
-#define WM8903_MASK_WRITE_ENA_MASK 0x0001 /* MASK_WRITE_ENA */
-#define WM8903_MASK_WRITE_ENA_SHIFT 0 /* MASK_WRITE_ENA */
-#define WM8903_MASK_WRITE_ENA_WIDTH 1 /* MASK_WRITE_ENA */
-
-/*
- * R121 (0x79) - Interrupt Status 1
- */
-#define WM8903_MICSHRT_EINT 0x8000 /* MICSHRT_EINT */
-#define WM8903_MICSHRT_EINT_MASK 0x8000 /* MICSHRT_EINT */
-#define WM8903_MICSHRT_EINT_SHIFT 15 /* MICSHRT_EINT */
-#define WM8903_MICSHRT_EINT_WIDTH 1 /* MICSHRT_EINT */
-#define WM8903_MICDET_EINT 0x4000 /* MICDET_EINT */
-#define WM8903_MICDET_EINT_MASK 0x4000 /* MICDET_EINT */
-#define WM8903_MICDET_EINT_SHIFT 14 /* MICDET_EINT */
-#define WM8903_MICDET_EINT_WIDTH 1 /* MICDET_EINT */
-#define WM8903_WSEQ_BUSY_EINT 0x2000 /* WSEQ_BUSY_EINT */
-#define WM8903_WSEQ_BUSY_EINT_MASK 0x2000 /* WSEQ_BUSY_EINT */
-#define WM8903_WSEQ_BUSY_EINT_SHIFT 13 /* WSEQ_BUSY_EINT */
-#define WM8903_WSEQ_BUSY_EINT_WIDTH 1 /* WSEQ_BUSY_EINT */
-#define WM8903_GP5_EINT 0x0010 /* GP5_EINT */
-#define WM8903_GP5_EINT_MASK 0x0010 /* GP5_EINT */
-#define WM8903_GP5_EINT_SHIFT 4 /* GP5_EINT */
-#define WM8903_GP5_EINT_WIDTH 1 /* GP5_EINT */
-#define WM8903_GP4_EINT 0x0008 /* GP4_EINT */
-#define WM8903_GP4_EINT_MASK 0x0008 /* GP4_EINT */
-#define WM8903_GP4_EINT_SHIFT 3 /* GP4_EINT */
-#define WM8903_GP4_EINT_WIDTH 1 /* GP4_EINT */
-#define WM8903_GP3_EINT 0x0004 /* GP3_EINT */
-#define WM8903_GP3_EINT_MASK 0x0004 /* GP3_EINT */
-#define WM8903_GP3_EINT_SHIFT 2 /* GP3_EINT */
-#define WM8903_GP3_EINT_WIDTH 1 /* GP3_EINT */
-#define WM8903_GP2_EINT 0x0002 /* GP2_EINT */
-#define WM8903_GP2_EINT_MASK 0x0002 /* GP2_EINT */
-#define WM8903_GP2_EINT_SHIFT 1 /* GP2_EINT */
-#define WM8903_GP2_EINT_WIDTH 1 /* GP2_EINT */
-#define WM8903_GP1_EINT 0x0001 /* GP1_EINT */
-#define WM8903_GP1_EINT_MASK 0x0001 /* GP1_EINT */
-#define WM8903_GP1_EINT_SHIFT 0 /* GP1_EINT */
-#define WM8903_GP1_EINT_WIDTH 1 /* GP1_EINT */
-
-/*
- * R122 (0x7A) - Interrupt Status 1 Mask
- */
-#define WM8903_IM_MICSHRT_EINT 0x8000 /* IM_MICSHRT_EINT */
-#define WM8903_IM_MICSHRT_EINT_MASK 0x8000 /* IM_MICSHRT_EINT */
-#define WM8903_IM_MICSHRT_EINT_SHIFT 15 /* IM_MICSHRT_EINT */
-#define WM8903_IM_MICSHRT_EINT_WIDTH 1 /* IM_MICSHRT_EINT */
-#define WM8903_IM_MICDET_EINT 0x4000 /* IM_MICDET_EINT */
-#define WM8903_IM_MICDET_EINT_MASK 0x4000 /* IM_MICDET_EINT */
-#define WM8903_IM_MICDET_EINT_SHIFT 14 /* IM_MICDET_EINT */
-#define WM8903_IM_MICDET_EINT_WIDTH 1 /* IM_MICDET_EINT */
-#define WM8903_IM_WSEQ_BUSY_EINT 0x2000 /* IM_WSEQ_BUSY_EINT */
-#define WM8903_IM_WSEQ_BUSY_EINT_MASK 0x2000 /* IM_WSEQ_BUSY_EINT */
-#define WM8903_IM_WSEQ_BUSY_EINT_SHIFT 13 /* IM_WSEQ_BUSY_EINT */
-#define WM8903_IM_WSEQ_BUSY_EINT_WIDTH 1 /* IM_WSEQ_BUSY_EINT */
-#define WM8903_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
-#define WM8903_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
-#define WM8903_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
-#define WM8903_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
-#define WM8903_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
-#define WM8903_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
-#define WM8903_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
-#define WM8903_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
-#define WM8903_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
-#define WM8903_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
-#define WM8903_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
-#define WM8903_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
-#define WM8903_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
-#define WM8903_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
-#define WM8903_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
-#define WM8903_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
-#define WM8903_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
-#define WM8903_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
-#define WM8903_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
-#define WM8903_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
-
-/*
- * R123 (0x7B) - Interrupt Polarity 1
- */
-#define WM8903_MICSHRT_INV 0x8000 /* MICSHRT_INV */
-#define WM8903_MICSHRT_INV_MASK 0x8000 /* MICSHRT_INV */
-#define WM8903_MICSHRT_INV_SHIFT 15 /* MICSHRT_INV */
-#define WM8903_MICSHRT_INV_WIDTH 1 /* MICSHRT_INV */
-#define WM8903_MICDET_INV 0x4000 /* MICDET_INV */
-#define WM8903_MICDET_INV_MASK 0x4000 /* MICDET_INV */
-#define WM8903_MICDET_INV_SHIFT 14 /* MICDET_INV */
-#define WM8903_MICDET_INV_WIDTH 1 /* MICDET_INV */
-
-/*
- * R126 (0x7E) - Interrupt Control
- */
-#define WM8903_IRQ_POL 0x0001 /* IRQ_POL */
-#define WM8903_IRQ_POL_MASK 0x0001 /* IRQ_POL */
-#define WM8903_IRQ_POL_SHIFT 0 /* IRQ_POL */
-#define WM8903_IRQ_POL_WIDTH 1 /* IRQ_POL */
-
-/*
- * R164 (0xA4) - Clock Rate Test 4
- */
-#define WM8903_ADC_DIG_MIC 0x0200 /* ADC_DIG_MIC */
-#define WM8903_ADC_DIG_MIC_MASK 0x0200 /* ADC_DIG_MIC */
-#define WM8903_ADC_DIG_MIC_SHIFT 9 /* ADC_DIG_MIC */
-#define WM8903_ADC_DIG_MIC_WIDTH 1 /* ADC_DIG_MIC */
-
-/*
- * R172 (0xAC) - Analogue Output Bias 0
- */
-#define WM8903_PGA_BIAS_MASK 0x0070 /* PGA_BIAS - [6:4] */
-#define WM8903_PGA_BIAS_SHIFT 4 /* PGA_BIAS - [6:4] */
-#define WM8903_PGA_BIAS_WIDTH 3 /* PGA_BIAS - [6:4] */
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8904.c b/ANDROID_3.4.5/sound/soc/codecs/wm8904.c
deleted file mode 100644
index 4e190b59..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8904.c
+++ /dev/null
@@ -1,2339 +0,0 @@
-/*
- * wm8904.c -- WM8904 ALSA SoC Audio driver
- *
- * Copyright 2009 Wolfson Microelectronics plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/regmap.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <sound/wm8904.h>
-
-#include "wm8904.h"
-
-enum wm8904_type {
- WM8904,
- WM8912,
-};
-
-#define WM8904_NUM_DCS_CHANNELS 4
-
-#define WM8904_NUM_SUPPLIES 5
-static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
- "DCVDD",
- "DBVDD",
- "AVDD",
- "CPVDD",
- "MICVDD",
-};
-
-/* codec private data */
-struct wm8904_priv {
- struct regmap *regmap;
-
- enum wm8904_type devtype;
-
- struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES];
-
- struct wm8904_pdata *pdata;
-
- int deemph;
-
- /* Platform provided DRC configuration */
- const char **drc_texts;
- int drc_cfg;
- struct soc_enum drc_enum;
-
- /* Platform provided ReTune mobile configuration */
- int num_retune_mobile_texts;
- const char **retune_mobile_texts;
- int retune_mobile_cfg;
- struct soc_enum retune_mobile_enum;
-
- /* FLL setup */
- int fll_src;
- int fll_fref;
- int fll_fout;
-
- /* Clocking configuration */
- unsigned int mclk_rate;
- int sysclk_src;
- unsigned int sysclk_rate;
-
- int tdm_width;
- int tdm_slots;
- int bclk;
- int fs;
-
- /* DC servo configuration - cached offset values */
- int dcs_state[WM8904_NUM_DCS_CHANNELS];
-};
-
-static const struct reg_default wm8904_reg_defaults[] = {
- { 4, 0x0018 }, /* R4 - Bias Control 0 */
- { 5, 0x0000 }, /* R5 - VMID Control 0 */
- { 6, 0x0000 }, /* R6 - Mic Bias Control 0 */
- { 7, 0x0000 }, /* R7 - Mic Bias Control 1 */
- { 8, 0x0001 }, /* R8 - Analogue DAC 0 */
- { 9, 0x9696 }, /* R9 - mic Filter Control */
- { 10, 0x0001 }, /* R10 - Analogue ADC 0 */
- { 12, 0x0000 }, /* R12 - Power Management 0 */
- { 14, 0x0000 }, /* R14 - Power Management 2 */
- { 15, 0x0000 }, /* R15 - Power Management 3 */
- { 18, 0x0000 }, /* R18 - Power Management 6 */
- { 19, 0x945E }, /* R20 - Clock Rates 0 */
- { 21, 0x0C05 }, /* R21 - Clock Rates 1 */
- { 22, 0x0006 }, /* R22 - Clock Rates 2 */
- { 24, 0x0050 }, /* R24 - Audio Interface 0 */
- { 25, 0x000A }, /* R25 - Audio Interface 1 */
- { 26, 0x00E4 }, /* R26 - Audio Interface 2 */
- { 27, 0x0040 }, /* R27 - Audio Interface 3 */
- { 30, 0x00C0 }, /* R30 - DAC Digital Volume Left */
- { 31, 0x00C0 }, /* R31 - DAC Digital Volume Right */
- { 32, 0x0000 }, /* R32 - DAC Digital 0 */
- { 33, 0x0008 }, /* R33 - DAC Digital 1 */
- { 36, 0x00C0 }, /* R36 - ADC Digital Volume Left */
- { 37, 0x00C0 }, /* R37 - ADC Digital Volume Right */
- { 38, 0x0010 }, /* R38 - ADC Digital 0 */
- { 39, 0x0000 }, /* R39 - Digital Microphone 0 */
- { 40, 0x01AF }, /* R40 - DRC 0 */
- { 41, 0x3248 }, /* R41 - DRC 1 */
- { 42, 0x0000 }, /* R42 - DRC 2 */
- { 43, 0x0000 }, /* R43 - DRC 3 */
- { 44, 0x0085 }, /* R44 - Analogue Left Input 0 */
- { 45, 0x0085 }, /* R45 - Analogue Right Input 0 */
- { 46, 0x0044 }, /* R46 - Analogue Left Input 1 */
- { 47, 0x0044 }, /* R47 - Analogue Right Input 1 */
- { 57, 0x002D }, /* R57 - Analogue OUT1 Left */
- { 58, 0x002D }, /* R58 - Analogue OUT1 Right */
- { 59, 0x0039 }, /* R59 - Analogue OUT2 Left */
- { 60, 0x0039 }, /* R60 - Analogue OUT2 Right */
- { 61, 0x0000 }, /* R61 - Analogue OUT12 ZC */
- { 67, 0x0000 }, /* R67 - DC Servo 0 */
- { 69, 0xAAAA }, /* R69 - DC Servo 2 */
- { 71, 0xAAAA }, /* R71 - DC Servo 4 */
- { 72, 0xAAAA }, /* R72 - DC Servo 5 */
- { 90, 0x0000 }, /* R90 - Analogue HP 0 */
- { 94, 0x0000 }, /* R94 - Analogue Lineout 0 */
- { 98, 0x0000 }, /* R98 - Charge Pump 0 */
- { 104, 0x0004 }, /* R104 - Class W 0 */
- { 108, 0x0000 }, /* R108 - Write Sequencer 0 */
- { 109, 0x0000 }, /* R109 - Write Sequencer 1 */
- { 110, 0x0000 }, /* R110 - Write Sequencer 2 */
- { 111, 0x0000 }, /* R111 - Write Sequencer 3 */
- { 112, 0x0000 }, /* R112 - Write Sequencer 4 */
- { 116, 0x0000 }, /* R116 - FLL Control 1 */
- { 117, 0x0007 }, /* R117 - FLL Control 2 */
- { 118, 0x0000 }, /* R118 - FLL Control 3 */
- { 119, 0x2EE0 }, /* R119 - FLL Control 4 */
- { 120, 0x0004 }, /* R120 - FLL Control 5 */
- { 121, 0x0014 }, /* R121 - GPIO Control 1 */
- { 122, 0x0010 }, /* R122 - GPIO Control 2 */
- { 123, 0x0010 }, /* R123 - GPIO Control 3 */
- { 124, 0x0000 }, /* R124 - GPIO Control 4 */
- { 126, 0x0000 }, /* R126 - Digital Pulls */
- { 128, 0xFFFF }, /* R128 - Interrupt Status Mask */
- { 129, 0x0000 }, /* R129 - Interrupt Polarity */
- { 130, 0x0000 }, /* R130 - Interrupt Debounce */
- { 134, 0x0000 }, /* R134 - EQ1 */
- { 135, 0x000C }, /* R135 - EQ2 */
- { 136, 0x000C }, /* R136 - EQ3 */
- { 137, 0x000C }, /* R137 - EQ4 */
- { 138, 0x000C }, /* R138 - EQ5 */
- { 139, 0x000C }, /* R139 - EQ6 */
- { 140, 0x0FCA }, /* R140 - EQ7 */
- { 141, 0x0400 }, /* R141 - EQ8 */
- { 142, 0x00D8 }, /* R142 - EQ9 */
- { 143, 0x1EB5 }, /* R143 - EQ10 */
- { 144, 0xF145 }, /* R144 - EQ11 */
- { 145, 0x0B75 }, /* R145 - EQ12 */
- { 146, 0x01C5 }, /* R146 - EQ13 */
- { 147, 0x1C58 }, /* R147 - EQ14 */
- { 148, 0xF373 }, /* R148 - EQ15 */
- { 149, 0x0A54 }, /* R149 - EQ16 */
- { 150, 0x0558 }, /* R150 - EQ17 */
- { 151, 0x168E }, /* R151 - EQ18 */
- { 152, 0xF829 }, /* R152 - EQ19 */
- { 153, 0x07AD }, /* R153 - EQ20 */
- { 154, 0x1103 }, /* R154 - EQ21 */
- { 155, 0x0564 }, /* R155 - EQ22 */
- { 156, 0x0559 }, /* R156 - EQ23 */
- { 157, 0x4000 }, /* R157 - EQ24 */
- { 161, 0x0000 }, /* R161 - Control Interface Test 1 */
- { 204, 0x0000 }, /* R204 - Analogue Output Bias 0 */
- { 247, 0x0000 }, /* R247 - FLL NCO Test 0 */
- { 248, 0x0019 }, /* R248 - FLL NCO Test 1 */
-};
-
-static bool wm8904_volatile_register(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM8904_SW_RESET_AND_ID:
- case WM8904_REVISION:
- case WM8904_DC_SERVO_1:
- case WM8904_DC_SERVO_6:
- case WM8904_DC_SERVO_7:
- case WM8904_DC_SERVO_8:
- case WM8904_DC_SERVO_9:
- case WM8904_DC_SERVO_READBACK_0:
- case WM8904_INTERRUPT_STATUS:
- return true;
- default:
- return false;
- }
-}
-
-static bool wm8904_readable_register(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM8904_SW_RESET_AND_ID:
- case WM8904_REVISION:
- case WM8904_BIAS_CONTROL_0:
- case WM8904_VMID_CONTROL_0:
- case WM8904_MIC_BIAS_CONTROL_0:
- case WM8904_MIC_BIAS_CONTROL_1:
- case WM8904_ANALOGUE_DAC_0:
- case WM8904_MIC_FILTER_CONTROL:
- case WM8904_ANALOGUE_ADC_0:
- case WM8904_POWER_MANAGEMENT_0:
- case WM8904_POWER_MANAGEMENT_2:
- case WM8904_POWER_MANAGEMENT_3:
- case WM8904_POWER_MANAGEMENT_6:
- case WM8904_CLOCK_RATES_0:
- case WM8904_CLOCK_RATES_1:
- case WM8904_CLOCK_RATES_2:
- case WM8904_AUDIO_INTERFACE_0:
- case WM8904_AUDIO_INTERFACE_1:
- case WM8904_AUDIO_INTERFACE_2:
- case WM8904_AUDIO_INTERFACE_3:
- case WM8904_DAC_DIGITAL_VOLUME_LEFT:
- case WM8904_DAC_DIGITAL_VOLUME_RIGHT:
- case WM8904_DAC_DIGITAL_0:
- case WM8904_DAC_DIGITAL_1:
- case WM8904_ADC_DIGITAL_VOLUME_LEFT:
- case WM8904_ADC_DIGITAL_VOLUME_RIGHT:
- case WM8904_ADC_DIGITAL_0:
- case WM8904_DIGITAL_MICROPHONE_0:
- case WM8904_DRC_0:
- case WM8904_DRC_1:
- case WM8904_DRC_2:
- case WM8904_DRC_3:
- case WM8904_ANALOGUE_LEFT_INPUT_0:
- case WM8904_ANALOGUE_RIGHT_INPUT_0:
- case WM8904_ANALOGUE_LEFT_INPUT_1:
- case WM8904_ANALOGUE_RIGHT_INPUT_1:
- case WM8904_ANALOGUE_OUT1_LEFT:
- case WM8904_ANALOGUE_OUT1_RIGHT:
- case WM8904_ANALOGUE_OUT2_LEFT:
- case WM8904_ANALOGUE_OUT2_RIGHT:
- case WM8904_ANALOGUE_OUT12_ZC:
- case WM8904_DC_SERVO_0:
- case WM8904_DC_SERVO_1:
- case WM8904_DC_SERVO_2:
- case WM8904_DC_SERVO_4:
- case WM8904_DC_SERVO_5:
- case WM8904_DC_SERVO_6:
- case WM8904_DC_SERVO_7:
- case WM8904_DC_SERVO_8:
- case WM8904_DC_SERVO_9:
- case WM8904_DC_SERVO_READBACK_0:
- case WM8904_ANALOGUE_HP_0:
- case WM8904_ANALOGUE_LINEOUT_0:
- case WM8904_CHARGE_PUMP_0:
- case WM8904_CLASS_W_0:
- case WM8904_WRITE_SEQUENCER_0:
- case WM8904_WRITE_SEQUENCER_1:
- case WM8904_WRITE_SEQUENCER_2:
- case WM8904_WRITE_SEQUENCER_3:
- case WM8904_WRITE_SEQUENCER_4:
- case WM8904_FLL_CONTROL_1:
- case WM8904_FLL_CONTROL_2:
- case WM8904_FLL_CONTROL_3:
- case WM8904_FLL_CONTROL_4:
- case WM8904_FLL_CONTROL_5:
- case WM8904_GPIO_CONTROL_1:
- case WM8904_GPIO_CONTROL_2:
- case WM8904_GPIO_CONTROL_3:
- case WM8904_GPIO_CONTROL_4:
- case WM8904_DIGITAL_PULLS:
- case WM8904_INTERRUPT_STATUS:
- case WM8904_INTERRUPT_STATUS_MASK:
- case WM8904_INTERRUPT_POLARITY:
- case WM8904_INTERRUPT_DEBOUNCE:
- case WM8904_EQ1:
- case WM8904_EQ2:
- case WM8904_EQ3:
- case WM8904_EQ4:
- case WM8904_EQ5:
- case WM8904_EQ6:
- case WM8904_EQ7:
- case WM8904_EQ8:
- case WM8904_EQ9:
- case WM8904_EQ10:
- case WM8904_EQ11:
- case WM8904_EQ12:
- case WM8904_EQ13:
- case WM8904_EQ14:
- case WM8904_EQ15:
- case WM8904_EQ16:
- case WM8904_EQ17:
- case WM8904_EQ18:
- case WM8904_EQ19:
- case WM8904_EQ20:
- case WM8904_EQ21:
- case WM8904_EQ22:
- case WM8904_EQ23:
- case WM8904_EQ24:
- case WM8904_CONTROL_INTERFACE_TEST_1:
- case WM8904_ADC_TEST_0:
- case WM8904_ANALOGUE_OUTPUT_BIAS_0:
- case WM8904_FLL_NCO_TEST_0:
- case WM8904_FLL_NCO_TEST_1:
- return true;
- default:
- return true;
- }
-}
-
-static int wm8904_reset(struct snd_soc_codec *codec)
-{
- return snd_soc_write(codec, WM8904_SW_RESET_AND_ID, 0);
-}
-
-static int wm8904_configure_clocking(struct snd_soc_codec *codec)
-{
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- unsigned int clock0, clock2, rate;
-
- /* Gate the clock while we're updating to avoid misclocking */
- clock2 = snd_soc_read(codec, WM8904_CLOCK_RATES_2);
- snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
- WM8904_SYSCLK_SRC, 0);
-
- /* This should be done on init() for bypass paths */
- switch (wm8904->sysclk_src) {
- case WM8904_CLK_MCLK:
- dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8904->mclk_rate);
-
- clock2 &= ~WM8904_SYSCLK_SRC;
- rate = wm8904->mclk_rate;
-
- /* Ensure the FLL is stopped */
- snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
- WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
- break;
-
- case WM8904_CLK_FLL:
- dev_dbg(codec->dev, "Using %dHz FLL clock\n",
- wm8904->fll_fout);
-
- clock2 |= WM8904_SYSCLK_SRC;
- rate = wm8904->fll_fout;
- break;
-
- default:
- dev_err(codec->dev, "System clock not configured\n");
- return -EINVAL;
- }
-
- /* SYSCLK shouldn't be over 13.5MHz */
- if (rate > 13500000) {
- clock0 = WM8904_MCLK_DIV;
- wm8904->sysclk_rate = rate / 2;
- } else {
- clock0 = 0;
- wm8904->sysclk_rate = rate;
- }
-
- snd_soc_update_bits(codec, WM8904_CLOCK_RATES_0, WM8904_MCLK_DIV,
- clock0);
-
- snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
- WM8904_CLK_SYS_ENA | WM8904_SYSCLK_SRC, clock2);
-
- dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm8904->sysclk_rate);
-
- return 0;
-}
-
-static void wm8904_set_drc(struct snd_soc_codec *codec)
-{
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- struct wm8904_pdata *pdata = wm8904->pdata;
- int save, i;
-
- /* Save any enables; the configuration should clear them. */
- save = snd_soc_read(codec, WM8904_DRC_0);
-
- for (i = 0; i < WM8904_DRC_REGS; i++)
- snd_soc_update_bits(codec, WM8904_DRC_0 + i, 0xffff,
- pdata->drc_cfgs[wm8904->drc_cfg].regs[i]);
-
- /* Reenable the DRC */
- snd_soc_update_bits(codec, WM8904_DRC_0,
- WM8904_DRC_ENA | WM8904_DRC_DAC_PATH, save);
-}
-
-static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- struct wm8904_pdata *pdata = wm8904->pdata;
- int value = ucontrol->value.integer.value[0];
-
- if (value >= pdata->num_drc_cfgs)
- return -EINVAL;
-
- wm8904->drc_cfg = value;
-
- wm8904_set_drc(codec);
-
- return 0;
-}
-
-static int wm8904_get_drc_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.enumerated.item[0] = wm8904->drc_cfg;
-
- return 0;
-}
-
-static void wm8904_set_retune_mobile(struct snd_soc_codec *codec)
-{
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- struct wm8904_pdata *pdata = wm8904->pdata;
- int best, best_val, save, i, cfg;
-
- if (!pdata || !wm8904->num_retune_mobile_texts)
- return;
-
- /* Find the version of the currently selected configuration
- * with the nearest sample rate. */
- cfg = wm8904->retune_mobile_cfg;
- best = 0;
- best_val = INT_MAX;
- for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
- if (strcmp(pdata->retune_mobile_cfgs[i].name,
- wm8904->retune_mobile_texts[cfg]) == 0 &&
- abs(pdata->retune_mobile_cfgs[i].rate
- - wm8904->fs) < best_val) {
- best = i;
- best_val = abs(pdata->retune_mobile_cfgs[i].rate
- - wm8904->fs);
- }
- }
-
- dev_dbg(codec->dev, "ReTune Mobile %s/%dHz for %dHz sample rate\n",
- pdata->retune_mobile_cfgs[best].name,
- pdata->retune_mobile_cfgs[best].rate,
- wm8904->fs);
-
- /* The EQ will be disabled while reconfiguring it, remember the
- * current configuration.
- */
- save = snd_soc_read(codec, WM8904_EQ1);
-
- for (i = 0; i < WM8904_EQ_REGS; i++)
- snd_soc_update_bits(codec, WM8904_EQ1 + i, 0xffff,
- pdata->retune_mobile_cfgs[best].regs[i]);
-
- snd_soc_update_bits(codec, WM8904_EQ1, WM8904_EQ_ENA, save);
-}
-
-static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- struct wm8904_pdata *pdata = wm8904->pdata;
- int value = ucontrol->value.integer.value[0];
-
- if (value >= pdata->num_retune_mobile_cfgs)
- return -EINVAL;
-
- wm8904->retune_mobile_cfg = value;
-
- wm8904_set_retune_mobile(codec);
-
- return 0;
-}
-
-static int wm8904_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.enumerated.item[0] = wm8904->retune_mobile_cfg;
-
- return 0;
-}
-
-static int deemph_settings[] = { 0, 32000, 44100, 48000 };
-
-static int wm8904_set_deemph(struct snd_soc_codec *codec)
-{
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- int val, i, best;
-
- /* If we're using deemphasis select the nearest available sample
- * rate.
- */
- if (wm8904->deemph) {
- best = 1;
- for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) {
- if (abs(deemph_settings[i] - wm8904->fs) <
- abs(deemph_settings[best] - wm8904->fs))
- best = i;
- }
-
- val = best << WM8904_DEEMPH_SHIFT;
- } else {
- val = 0;
- }
-
- dev_dbg(codec->dev, "Set deemphasis %d\n", val);
-
- return snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1,
- WM8904_DEEMPH_MASK, val);
-}
-
-static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.enumerated.item[0] = wm8904->deemph;
- return 0;
-}
-
-static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- int deemph = ucontrol->value.enumerated.item[0];
-
- if (deemph > 1)
- return -EINVAL;
-
- wm8904->deemph = deemph;
-
- return wm8904_set_deemph(codec);
-}
-
-static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0);
-static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
-static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
-static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 300, 0);
-static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
-
-static const char *input_mode_text[] = {
- "Single-Ended", "Differential Line", "Differential Mic"
-};
-
-static const struct soc_enum lin_mode =
- SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 0, 3, input_mode_text);
-
-static const struct soc_enum rin_mode =
- SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 0, 3, input_mode_text);
-
-static const char *hpf_mode_text[] = {
- "Hi-fi", "Voice 1", "Voice 2", "Voice 3"
-};
-
-static const struct soc_enum hpf_mode =
- SOC_ENUM_SINGLE(WM8904_ADC_DIGITAL_0, 5, 4, hpf_mode_text);
-
-static int wm8904_adc_osr_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int val;
- int ret;
-
- ret = snd_soc_put_volsw(kcontrol, ucontrol);
- if (ret < 0)
- return ret;
-
- if (ucontrol->value.integer.value[0])
- val = 0;
- else
- val = WM8904_ADC_128_OSR_TST_MODE | WM8904_ADC_BIASX1P5;
-
- snd_soc_update_bits(codec, WM8904_ADC_TEST_0,
- WM8904_ADC_128_OSR_TST_MODE | WM8904_ADC_BIASX1P5,
- val);
-
- return ret;
-}
-
-static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = {
-SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT,
- WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv),
-
-SOC_ENUM("Left Caputure Mode", lin_mode),
-SOC_ENUM("Right Capture Mode", rin_mode),
-
-/* No TLV since it depends on mode */
-SOC_DOUBLE_R("Capture Volume", WM8904_ANALOGUE_LEFT_INPUT_0,
- WM8904_ANALOGUE_RIGHT_INPUT_0, 0, 31, 0),
-SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0,
- WM8904_ANALOGUE_RIGHT_INPUT_0, 7, 1, 1),
-
-SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0),
-SOC_ENUM("High Pass Filter Mode", hpf_mode),
-
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "ADC 128x OSR Switch",
- .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,
- .put = wm8904_adc_osr_put,
- .private_value = SOC_SINGLE_VALUE(WM8904_ANALOGUE_ADC_0, 0, 1, 0),
-},
-};
-
-static const char *drc_path_text[] = {
- "ADC", "DAC"
-};
-
-static const struct soc_enum drc_path =
- SOC_ENUM_SINGLE(WM8904_DRC_0, 14, 2, drc_path_text);
-
-static const struct snd_kcontrol_new wm8904_dac_snd_controls[] = {
-SOC_SINGLE_TLV("Digital Playback Boost Volume",
- WM8904_AUDIO_INTERFACE_0, 9, 3, 0, dac_boost_tlv),
-SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8904_DAC_DIGITAL_VOLUME_LEFT,
- WM8904_DAC_DIGITAL_VOLUME_RIGHT, 1, 96, 0, digital_tlv),
-
-SOC_DOUBLE_R_TLV("Headphone Volume", WM8904_ANALOGUE_OUT1_LEFT,
- WM8904_ANALOGUE_OUT1_RIGHT, 0, 63, 0, out_tlv),
-SOC_DOUBLE_R("Headphone Switch", WM8904_ANALOGUE_OUT1_LEFT,
- WM8904_ANALOGUE_OUT1_RIGHT, 8, 1, 1),
-SOC_DOUBLE_R("Headphone ZC Switch", WM8904_ANALOGUE_OUT1_LEFT,
- WM8904_ANALOGUE_OUT1_RIGHT, 6, 1, 0),
-
-SOC_DOUBLE_R_TLV("Line Output Volume", WM8904_ANALOGUE_OUT2_LEFT,
- WM8904_ANALOGUE_OUT2_RIGHT, 0, 63, 0, out_tlv),
-SOC_DOUBLE_R("Line Output Switch", WM8904_ANALOGUE_OUT2_LEFT,
- WM8904_ANALOGUE_OUT2_RIGHT, 8, 1, 1),
-SOC_DOUBLE_R("Line Output ZC Switch", WM8904_ANALOGUE_OUT2_LEFT,
- WM8904_ANALOGUE_OUT2_RIGHT, 6, 1, 0),
-
-SOC_SINGLE("EQ Switch", WM8904_EQ1, 0, 1, 0),
-SOC_SINGLE("DRC Switch", WM8904_DRC_0, 15, 1, 0),
-SOC_ENUM("DRC Path", drc_path),
-SOC_SINGLE("DAC OSRx2 Switch", WM8904_DAC_DIGITAL_1, 6, 1, 0),
-SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0,
- wm8904_get_deemph, wm8904_put_deemph),
-};
-
-static const struct snd_kcontrol_new wm8904_snd_controls[] = {
-SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8904_DAC_DIGITAL_0, 4, 8, 15, 0,
- sidetone_tlv),
-};
-
-static const struct snd_kcontrol_new wm8904_eq_controls[] = {
-SOC_SINGLE_TLV("EQ1 Volume", WM8904_EQ2, 0, 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ2 Volume", WM8904_EQ3, 0, 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ3 Volume", WM8904_EQ4, 0, 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ4 Volume", WM8904_EQ5, 0, 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ5 Volume", WM8904_EQ6, 0, 24, 0, eq_tlv),
-};
-
-static int cp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- BUG_ON(event != SND_SOC_DAPM_POST_PMU);
-
- /* Maximum startup time */
- udelay(500);
-
- return 0;
-}
-
-static int sysclk_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- /* If we're using the FLL then we only start it when
- * required; we assume that the configuration has been
- * done previously and all we need to do is kick it
- * off.
- */
- switch (wm8904->sysclk_src) {
- case WM8904_CLK_FLL:
- snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
- WM8904_FLL_OSC_ENA,
- WM8904_FLL_OSC_ENA);
-
- snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
- WM8904_FLL_ENA,
- WM8904_FLL_ENA);
- break;
-
- default:
- break;
- }
- break;
-
- case SND_SOC_DAPM_POST_PMD:
- snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
- WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
- break;
- }
-
- return 0;
-}
-
-static int out_pga_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- int reg, val;
- int dcs_mask;
- int dcs_l, dcs_r;
- int dcs_l_reg, dcs_r_reg;
- int timeout;
- int pwr_reg;
-
- /* This code is shared between HP and LINEOUT; we do all our
- * power management in stereo pairs to avoid latency issues so
- * we reuse shift to identify which rather than strcmp() the
- * name. */
- reg = w->shift;
-
- switch (reg) {
- case WM8904_ANALOGUE_HP_0:
- pwr_reg = WM8904_POWER_MANAGEMENT_2;
- dcs_mask = WM8904_DCS_ENA_CHAN_0 | WM8904_DCS_ENA_CHAN_1;
- dcs_r_reg = WM8904_DC_SERVO_8;
- dcs_l_reg = WM8904_DC_SERVO_9;
- dcs_l = 0;
- dcs_r = 1;
- break;
- case WM8904_ANALOGUE_LINEOUT_0:
- pwr_reg = WM8904_POWER_MANAGEMENT_3;
- dcs_mask = WM8904_DCS_ENA_CHAN_2 | WM8904_DCS_ENA_CHAN_3;
- dcs_r_reg = WM8904_DC_SERVO_6;
- dcs_l_reg = WM8904_DC_SERVO_7;
- dcs_l = 2;
- dcs_r = 3;
- break;
- default:
- BUG();
- return -EINVAL;
- }
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- /* Power on the PGAs */
- snd_soc_update_bits(codec, pwr_reg,
- WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA,
- WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA);
-
- /* Power on the amplifier */
- snd_soc_update_bits(codec, reg,
- WM8904_HPL_ENA | WM8904_HPR_ENA,
- WM8904_HPL_ENA | WM8904_HPR_ENA);
-
-
- /* Enable the first stage */
- snd_soc_update_bits(codec, reg,
- WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY,
- WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY);
-
- /* Power up the DC servo */
- snd_soc_update_bits(codec, WM8904_DC_SERVO_0,
- dcs_mask, dcs_mask);
-
- /* Either calibrate the DC servo or restore cached state
- * if we have that.
- */
- if (wm8904->dcs_state[dcs_l] || wm8904->dcs_state[dcs_r]) {
- dev_dbg(codec->dev, "Restoring DC servo state\n");
-
- snd_soc_write(codec, dcs_l_reg,
- wm8904->dcs_state[dcs_l]);
- snd_soc_write(codec, dcs_r_reg,
- wm8904->dcs_state[dcs_r]);
-
- snd_soc_write(codec, WM8904_DC_SERVO_1, dcs_mask);
-
- timeout = 20;
- } else {
- dev_dbg(codec->dev, "Calibrating DC servo\n");
-
- snd_soc_write(codec, WM8904_DC_SERVO_1,
- dcs_mask << WM8904_DCS_TRIG_STARTUP_0_SHIFT);
-
- timeout = 500;
- }
-
- /* Wait for DC servo to complete */
- dcs_mask <<= WM8904_DCS_CAL_COMPLETE_SHIFT;
- do {
- val = snd_soc_read(codec, WM8904_DC_SERVO_READBACK_0);
- if ((val & dcs_mask) == dcs_mask)
- break;
-
- msleep(1);
- } while (--timeout);
-
- if ((val & dcs_mask) != dcs_mask)
- dev_warn(codec->dev, "DC servo timed out\n");
- else
- dev_dbg(codec->dev, "DC servo ready\n");
-
- /* Enable the output stage */
- snd_soc_update_bits(codec, reg,
- WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP,
- WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP);
- break;
-
- case SND_SOC_DAPM_POST_PMU:
- /* Unshort the output itself */
- snd_soc_update_bits(codec, reg,
- WM8904_HPL_RMV_SHORT |
- WM8904_HPR_RMV_SHORT,
- WM8904_HPL_RMV_SHORT |
- WM8904_HPR_RMV_SHORT);
-
- break;
-
- case SND_SOC_DAPM_PRE_PMD:
- /* Short the output */
- snd_soc_update_bits(codec, reg,
- WM8904_HPL_RMV_SHORT |
- WM8904_HPR_RMV_SHORT, 0);
- break;
-
- case SND_SOC_DAPM_POST_PMD:
- /* Cache the DC servo configuration; this will be
- * invalidated if we change the configuration. */
- wm8904->dcs_state[dcs_l] = snd_soc_read(codec, dcs_l_reg);
- wm8904->dcs_state[dcs_r] = snd_soc_read(codec, dcs_r_reg);
-
- snd_soc_update_bits(codec, WM8904_DC_SERVO_0,
- dcs_mask, 0);
-
- /* Disable the amplifier input and output stages */
- snd_soc_update_bits(codec, reg,
- WM8904_HPL_ENA | WM8904_HPR_ENA |
- WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY |
- WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP,
- 0);
-
- /* PGAs too */
- snd_soc_update_bits(codec, pwr_reg,
- WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA,
- 0);
- break;
- }
-
- return 0;
-}
-
-static const char *lin_text[] = {
- "IN1L", "IN2L", "IN3L"
-};
-
-static const struct soc_enum lin_enum =
- SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 2, 3, lin_text);
-
-static const struct snd_kcontrol_new lin_mux =
- SOC_DAPM_ENUM("Left Capture Mux", lin_enum);
-
-static const struct soc_enum lin_inv_enum =
- SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 4, 3, lin_text);
-
-static const struct snd_kcontrol_new lin_inv_mux =
- SOC_DAPM_ENUM("Left Capture Inveting Mux", lin_inv_enum);
-
-static const char *rin_text[] = {
- "IN1R", "IN2R", "IN3R"
-};
-
-static const struct soc_enum rin_enum =
- SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 2, 3, rin_text);
-
-static const struct snd_kcontrol_new rin_mux =
- SOC_DAPM_ENUM("Right Capture Mux", rin_enum);
-
-static const struct soc_enum rin_inv_enum =
- SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 4, 3, rin_text);
-
-static const struct snd_kcontrol_new rin_inv_mux =
- SOC_DAPM_ENUM("Right Capture Inveting Mux", rin_inv_enum);
-
-static const char *aif_text[] = {
- "Left", "Right"
-};
-
-static const struct soc_enum aifoutl_enum =
- SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 7, 2, aif_text);
-
-static const struct snd_kcontrol_new aifoutl_mux =
- SOC_DAPM_ENUM("AIFOUTL Mux", aifoutl_enum);
-
-static const struct soc_enum aifoutr_enum =
- SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 6, 2, aif_text);
-
-static const struct snd_kcontrol_new aifoutr_mux =
- SOC_DAPM_ENUM("AIFOUTR Mux", aifoutr_enum);
-
-static const struct soc_enum aifinl_enum =
- SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 5, 2, aif_text);
-
-static const struct snd_kcontrol_new aifinl_mux =
- SOC_DAPM_ENUM("AIFINL Mux", aifinl_enum);
-
-static const struct soc_enum aifinr_enum =
- SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 4, 2, aif_text);
-
-static const struct snd_kcontrol_new aifinr_mux =
- SOC_DAPM_ENUM("AIFINR Mux", aifinr_enum);
-
-static const struct snd_soc_dapm_widget wm8904_core_dapm_widgets[] = {
-SND_SOC_DAPM_SUPPLY("SYSCLK", WM8904_CLOCK_RATES_2, 2, 0, sysclk_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8904_CLOCK_RATES_2, 1, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("TOCLK", WM8904_CLOCK_RATES_2, 0, 0, NULL, 0),
-};
-
-static const struct snd_soc_dapm_widget wm8904_adc_dapm_widgets[] = {
-SND_SOC_DAPM_INPUT("IN1L"),
-SND_SOC_DAPM_INPUT("IN1R"),
-SND_SOC_DAPM_INPUT("IN2L"),
-SND_SOC_DAPM_INPUT("IN2R"),
-SND_SOC_DAPM_INPUT("IN3L"),
-SND_SOC_DAPM_INPUT("IN3R"),
-
-SND_SOC_DAPM_SUPPLY("MICBIAS", WM8904_MIC_BIAS_CONTROL_0, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lin_mux),
-SND_SOC_DAPM_MUX("Left Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
- &lin_inv_mux),
-SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rin_mux),
-SND_SOC_DAPM_MUX("Right Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
- &rin_inv_mux),
-
-SND_SOC_DAPM_PGA("Left Capture PGA", WM8904_POWER_MANAGEMENT_0, 1, 0,
- NULL, 0),
-SND_SOC_DAPM_PGA("Right Capture PGA", WM8904_POWER_MANAGEMENT_0, 0, 0,
- NULL, 0),
-
-SND_SOC_DAPM_ADC("ADCL", NULL, WM8904_POWER_MANAGEMENT_6, 1, 0),
-SND_SOC_DAPM_ADC("ADCR", NULL, WM8904_POWER_MANAGEMENT_6, 0, 0),
-
-SND_SOC_DAPM_MUX("AIFOUTL Mux", SND_SOC_NOPM, 0, 0, &aifoutl_mux),
-SND_SOC_DAPM_MUX("AIFOUTR Mux", SND_SOC_NOPM, 0, 0, &aifoutr_mux),
-
-SND_SOC_DAPM_AIF_OUT("AIFOUTL", "Capture", 0, SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_AIF_OUT("AIFOUTR", "Capture", 1, SND_SOC_NOPM, 0, 0),
-};
-
-static const struct snd_soc_dapm_widget wm8904_dac_dapm_widgets[] = {
-SND_SOC_DAPM_AIF_IN("AIFINL", "Playback", 0, SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_AIF_IN("AIFINR", "Playback", 1, SND_SOC_NOPM, 0, 0),
-
-SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &aifinl_mux),
-SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &aifinr_mux),
-
-SND_SOC_DAPM_DAC("DACL", NULL, WM8904_POWER_MANAGEMENT_6, 3, 0),
-SND_SOC_DAPM_DAC("DACR", NULL, WM8904_POWER_MANAGEMENT_6, 2, 0),
-
-SND_SOC_DAPM_SUPPLY("Charge pump", WM8904_CHARGE_PUMP_0, 0, 0, cp_event,
- SND_SOC_DAPM_POST_PMU),
-
-SND_SOC_DAPM_PGA("HPL PGA", SND_SOC_NOPM, 1, 0, NULL, 0),
-SND_SOC_DAPM_PGA("HPR PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA("LINEL PGA", SND_SOC_NOPM, 1, 0, NULL, 0),
-SND_SOC_DAPM_PGA("LINER PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA_E("Headphone Output", SND_SOC_NOPM, WM8904_ANALOGUE_HP_0,
- 0, NULL, 0, out_pga_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
-SND_SOC_DAPM_PGA_E("Line Output", SND_SOC_NOPM, WM8904_ANALOGUE_LINEOUT_0,
- 0, NULL, 0, out_pga_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
-
-SND_SOC_DAPM_OUTPUT("HPOUTL"),
-SND_SOC_DAPM_OUTPUT("HPOUTR"),
-SND_SOC_DAPM_OUTPUT("LINEOUTL"),
-SND_SOC_DAPM_OUTPUT("LINEOUTR"),
-};
-
-static const char *out_mux_text[] = {
- "DAC", "Bypass"
-};
-
-static const struct soc_enum hpl_enum =
- SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 3, 2, out_mux_text);
-
-static const struct snd_kcontrol_new hpl_mux =
- SOC_DAPM_ENUM("HPL Mux", hpl_enum);
-
-static const struct soc_enum hpr_enum =
- SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 2, 2, out_mux_text);
-
-static const struct snd_kcontrol_new hpr_mux =
- SOC_DAPM_ENUM("HPR Mux", hpr_enum);
-
-static const struct soc_enum linel_enum =
- SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 1, 2, out_mux_text);
-
-static const struct snd_kcontrol_new linel_mux =
- SOC_DAPM_ENUM("LINEL Mux", linel_enum);
-
-static const struct soc_enum liner_enum =
- SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 0, 2, out_mux_text);
-
-static const struct snd_kcontrol_new liner_mux =
- SOC_DAPM_ENUM("LINEL Mux", liner_enum);
-
-static const char *sidetone_text[] = {
- "None", "Left", "Right"
-};
-
-static const struct soc_enum dacl_sidetone_enum =
- SOC_ENUM_SINGLE(WM8904_DAC_DIGITAL_0, 2, 3, sidetone_text);
-
-static const struct snd_kcontrol_new dacl_sidetone_mux =
- SOC_DAPM_ENUM("Left Sidetone Mux", dacl_sidetone_enum);
-
-static const struct soc_enum dacr_sidetone_enum =
- SOC_ENUM_SINGLE(WM8904_DAC_DIGITAL_0, 0, 3, sidetone_text);
-
-static const struct snd_kcontrol_new dacr_sidetone_mux =
- SOC_DAPM_ENUM("Right Sidetone Mux", dacr_sidetone_enum);
-
-static const struct snd_soc_dapm_widget wm8904_dapm_widgets[] = {
-SND_SOC_DAPM_SUPPLY("Class G", WM8904_CLASS_W_0, 0, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Left Bypass", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right Bypass", SND_SOC_NOPM, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &dacl_sidetone_mux),
-SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &dacr_sidetone_mux),
-
-SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
-SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
-SND_SOC_DAPM_MUX("LINEL Mux", SND_SOC_NOPM, 0, 0, &linel_mux),
-SND_SOC_DAPM_MUX("LINER Mux", SND_SOC_NOPM, 0, 0, &liner_mux),
-};
-
-static const struct snd_soc_dapm_route core_intercon[] = {
- { "CLK_DSP", NULL, "SYSCLK" },
- { "TOCLK", NULL, "SYSCLK" },
-};
-
-static const struct snd_soc_dapm_route adc_intercon[] = {
- { "Left Capture Mux", "IN1L", "IN1L" },
- { "Left Capture Mux", "IN2L", "IN2L" },
- { "Left Capture Mux", "IN3L", "IN3L" },
-
- { "Left Capture Inverting Mux", "IN1L", "IN1L" },
- { "Left Capture Inverting Mux", "IN2L", "IN2L" },
- { "Left Capture Inverting Mux", "IN3L", "IN3L" },
-
- { "Right Capture Mux", "IN1R", "IN1R" },
- { "Right Capture Mux", "IN2R", "IN2R" },
- { "Right Capture Mux", "IN3R", "IN3R" },
-
- { "Right Capture Inverting Mux", "IN1R", "IN1R" },
- { "Right Capture Inverting Mux", "IN2R", "IN2R" },
- { "Right Capture Inverting Mux", "IN3R", "IN3R" },
-
- { "Left Capture PGA", NULL, "Left Capture Mux" },
- { "Left Capture PGA", NULL, "Left Capture Inverting Mux" },
-
- { "Right Capture PGA", NULL, "Right Capture Mux" },
- { "Right Capture PGA", NULL, "Right Capture Inverting Mux" },
-
- { "AIFOUTL", "Left", "ADCL" },
- { "AIFOUTL", "Right", "ADCR" },
- { "AIFOUTR", "Left", "ADCL" },
- { "AIFOUTR", "Right", "ADCR" },
-
- { "ADCL", NULL, "CLK_DSP" },
- { "ADCL", NULL, "Left Capture PGA" },
-
- { "ADCR", NULL, "CLK_DSP" },
- { "ADCR", NULL, "Right Capture PGA" },
-};
-
-static const struct snd_soc_dapm_route dac_intercon[] = {
- { "DACL", "Right", "AIFINR" },
- { "DACL", "Left", "AIFINL" },
- { "DACL", NULL, "CLK_DSP" },
-
- { "DACR", "Right", "AIFINR" },
- { "DACR", "Left", "AIFINL" },
- { "DACR", NULL, "CLK_DSP" },
-
- { "Charge pump", NULL, "SYSCLK" },
-
- { "Headphone Output", NULL, "HPL PGA" },
- { "Headphone Output", NULL, "HPR PGA" },
- { "Headphone Output", NULL, "Charge pump" },
- { "Headphone Output", NULL, "TOCLK" },
-
- { "Line Output", NULL, "LINEL PGA" },
- { "Line Output", NULL, "LINER PGA" },
- { "Line Output", NULL, "Charge pump" },
- { "Line Output", NULL, "TOCLK" },
-
- { "HPOUTL", NULL, "Headphone Output" },
- { "HPOUTR", NULL, "Headphone Output" },
-
- { "LINEOUTL", NULL, "Line Output" },
- { "LINEOUTR", NULL, "Line Output" },
-};
-
-static const struct snd_soc_dapm_route wm8904_intercon[] = {
- { "Left Sidetone", "Left", "ADCL" },
- { "Left Sidetone", "Right", "ADCR" },
- { "DACL", NULL, "Left Sidetone" },
-
- { "Right Sidetone", "Left", "ADCL" },
- { "Right Sidetone", "Right", "ADCR" },
- { "DACR", NULL, "Right Sidetone" },
-
- { "Left Bypass", NULL, "Class G" },
- { "Left Bypass", NULL, "Left Capture PGA" },
-
- { "Right Bypass", NULL, "Class G" },
- { "Right Bypass", NULL, "Right Capture PGA" },
-
- { "HPL Mux", "DAC", "DACL" },
- { "HPL Mux", "Bypass", "Left Bypass" },
-
- { "HPR Mux", "DAC", "DACR" },
- { "HPR Mux", "Bypass", "Right Bypass" },
-
- { "LINEL Mux", "DAC", "DACL" },
- { "LINEL Mux", "Bypass", "Left Bypass" },
-
- { "LINER Mux", "DAC", "DACR" },
- { "LINER Mux", "Bypass", "Right Bypass" },
-
- { "HPL PGA", NULL, "HPL Mux" },
- { "HPR PGA", NULL, "HPR Mux" },
-
- { "LINEL PGA", NULL, "LINEL Mux" },
- { "LINER PGA", NULL, "LINER Mux" },
-};
-
-static const struct snd_soc_dapm_route wm8912_intercon[] = {
- { "HPL PGA", NULL, "DACL" },
- { "HPR PGA", NULL, "DACR" },
-
- { "LINEL PGA", NULL, "DACL" },
- { "LINER PGA", NULL, "DACR" },
-};
-
-static int wm8904_add_widgets(struct snd_soc_codec *codec)
-{
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_new_controls(dapm, wm8904_core_dapm_widgets,
- ARRAY_SIZE(wm8904_core_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, core_intercon,
- ARRAY_SIZE(core_intercon));
-
- switch (wm8904->devtype) {
- case WM8904:
- snd_soc_add_codec_controls(codec, wm8904_adc_snd_controls,
- ARRAY_SIZE(wm8904_adc_snd_controls));
- snd_soc_add_codec_controls(codec, wm8904_dac_snd_controls,
- ARRAY_SIZE(wm8904_dac_snd_controls));
- snd_soc_add_codec_controls(codec, wm8904_snd_controls,
- ARRAY_SIZE(wm8904_snd_controls));
-
- snd_soc_dapm_new_controls(dapm, wm8904_adc_dapm_widgets,
- ARRAY_SIZE(wm8904_adc_dapm_widgets));
- snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets,
- ARRAY_SIZE(wm8904_dac_dapm_widgets));
- snd_soc_dapm_new_controls(dapm, wm8904_dapm_widgets,
- ARRAY_SIZE(wm8904_dapm_widgets));
-
- snd_soc_dapm_add_routes(dapm, core_intercon,
- ARRAY_SIZE(core_intercon));
- snd_soc_dapm_add_routes(dapm, adc_intercon,
- ARRAY_SIZE(adc_intercon));
- snd_soc_dapm_add_routes(dapm, dac_intercon,
- ARRAY_SIZE(dac_intercon));
- snd_soc_dapm_add_routes(dapm, wm8904_intercon,
- ARRAY_SIZE(wm8904_intercon));
- break;
-
- case WM8912:
- snd_soc_add_codec_controls(codec, wm8904_dac_snd_controls,
- ARRAY_SIZE(wm8904_dac_snd_controls));
-
- snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets,
- ARRAY_SIZE(wm8904_dac_dapm_widgets));
-
- snd_soc_dapm_add_routes(dapm, dac_intercon,
- ARRAY_SIZE(dac_intercon));
- snd_soc_dapm_add_routes(dapm, wm8912_intercon,
- ARRAY_SIZE(wm8912_intercon));
- break;
- }
-
- snd_soc_dapm_new_widgets(dapm);
- return 0;
-}
-
-static struct {
- int ratio;
- unsigned int clk_sys_rate;
-} clk_sys_rates[] = {
- { 64, 0 },
- { 128, 1 },
- { 192, 2 },
- { 256, 3 },
- { 384, 4 },
- { 512, 5 },
- { 786, 6 },
- { 1024, 7 },
- { 1408, 8 },
- { 1536, 9 },
-};
-
-static struct {
- int rate;
- int sample_rate;
-} sample_rates[] = {
- { 8000, 0 },
- { 11025, 1 },
- { 12000, 1 },
- { 16000, 2 },
- { 22050, 3 },
- { 24000, 3 },
- { 32000, 4 },
- { 44100, 5 },
- { 48000, 5 },
-};
-
-static struct {
- int div; /* *10 due to .5s */
- int bclk_div;
-} bclk_divs[] = {
- { 10, 0 },
- { 15, 1 },
- { 20, 2 },
- { 30, 3 },
- { 40, 4 },
- { 50, 5 },
- { 55, 6 },
- { 60, 7 },
- { 80, 8 },
- { 100, 9 },
- { 110, 10 },
- { 120, 11 },
- { 160, 12 },
- { 200, 13 },
- { 220, 14 },
- { 240, 16 },
- { 200, 17 },
- { 320, 18 },
- { 440, 19 },
- { 480, 20 },
-};
-
-
-static int wm8904_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- int ret, i, best, best_val, cur_val;
- unsigned int aif1 = 0;
- unsigned int aif2 = 0;
- unsigned int aif3 = 0;
- unsigned int clock1 = 0;
- unsigned int dac_digital1 = 0;
-
- /* What BCLK do we need? */
- wm8904->fs = params_rate(params);
- if (wm8904->tdm_slots) {
- dev_dbg(codec->dev, "Configuring for %d %d bit TDM slots\n",
- wm8904->tdm_slots, wm8904->tdm_width);
- wm8904->bclk = snd_soc_calc_bclk(wm8904->fs,
- wm8904->tdm_width, 2,
- wm8904->tdm_slots);
- } else {
- wm8904->bclk = snd_soc_params_to_bclk(params);
- }
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- aif1 |= 0x40;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- aif1 |= 0x80;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- aif1 |= 0xc0;
- break;
- default:
- return -EINVAL;
- }
-
-
- dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm8904->bclk);
-
- ret = wm8904_configure_clocking(codec);
- if (ret != 0)
- return ret;
-
- /* Select nearest CLK_SYS_RATE */
- best = 0;
- best_val = abs((wm8904->sysclk_rate / clk_sys_rates[0].ratio)
- - wm8904->fs);
- for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
- cur_val = abs((wm8904->sysclk_rate /
- clk_sys_rates[i].ratio) - wm8904->fs);
- if (cur_val < best_val) {
- best = i;
- best_val = cur_val;
- }
- }
- dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n",
- clk_sys_rates[best].ratio);
- clock1 |= (clk_sys_rates[best].clk_sys_rate
- << WM8904_CLK_SYS_RATE_SHIFT);
-
- /* SAMPLE_RATE */
- best = 0;
- best_val = abs(wm8904->fs - sample_rates[0].rate);
- for (i = 1; i < ARRAY_SIZE(sample_rates); i++) {
- /* Closest match */
- cur_val = abs(wm8904->fs - sample_rates[i].rate);
- if (cur_val < best_val) {
- best = i;
- best_val = cur_val;
- }
- }
- dev_dbg(codec->dev, "Selected SAMPLE_RATE of %dHz\n",
- sample_rates[best].rate);
- clock1 |= (sample_rates[best].sample_rate
- << WM8904_SAMPLE_RATE_SHIFT);
-
- /* Enable sloping stopband filter for low sample rates */
- if (wm8904->fs <= 24000)
- dac_digital1 |= WM8904_DAC_SB_FILT;
-
- /* BCLK_DIV */
- best = 0;
- best_val = INT_MAX;
- for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
- cur_val = ((wm8904->sysclk_rate * 10) / bclk_divs[i].div)
- - wm8904->bclk;
- if (cur_val < 0) /* Table is sorted */
- break;
- if (cur_val < best_val) {
- best = i;
- best_val = cur_val;
- }
- }
- wm8904->bclk = (wm8904->sysclk_rate * 10) / bclk_divs[best].div;
- dev_dbg(codec->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n",
- bclk_divs[best].div, wm8904->bclk);
- aif2 |= bclk_divs[best].bclk_div;
-
- /* LRCLK is a simple fraction of BCLK */
- dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8904->bclk / wm8904->fs);
- aif3 |= wm8904->bclk / wm8904->fs;
-
- /* Apply the settings */
- snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1,
- WM8904_DAC_SB_FILT, dac_digital1);
- snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
- WM8904_AIF_WL_MASK, aif1);
- snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_2,
- WM8904_BCLK_DIV_MASK, aif2);
- snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_3,
- WM8904_LRCLK_RATE_MASK, aif3);
- snd_soc_update_bits(codec, WM8904_CLOCK_RATES_1,
- WM8904_SAMPLE_RATE_MASK |
- WM8904_CLK_SYS_RATE_MASK, clock1);
-
- /* Update filters for the new settings */
- wm8904_set_retune_mobile(codec);
- wm8904_set_deemph(codec);
-
- return 0;
-}
-
-
-static int wm8904_set_sysclk(struct snd_soc_dai *dai, int clk_id,
- unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8904_priv *priv = snd_soc_codec_get_drvdata(codec);
-
- switch (clk_id) {
- case WM8904_CLK_MCLK:
- priv->sysclk_src = clk_id;
- priv->mclk_rate = freq;
- break;
-
- case WM8904_CLK_FLL:
- priv->sysclk_src = clk_id;
- break;
-
- default:
- return -EINVAL;
- }
-
- dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
-
- wm8904_configure_clocking(codec);
-
- return 0;
-}
-
-static int wm8904_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = dai->codec;
- unsigned int aif1 = 0;
- unsigned int aif3 = 0;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- case SND_SOC_DAIFMT_CBS_CFM:
- aif3 |= WM8904_LRCLK_DIR;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- aif1 |= WM8904_BCLK_DIR;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- aif1 |= WM8904_BCLK_DIR;
- aif3 |= WM8904_LRCLK_DIR;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_B:
- aif1 |= WM8904_AIF_LRCLK_INV;
- case SND_SOC_DAIFMT_DSP_A:
- aif1 |= 0x3;
- break;
- case SND_SOC_DAIFMT_I2S:
- aif1 |= 0x2;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- aif1 |= 0x1;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- case SND_SOC_DAIFMT_DSP_B:
- /* frame inversion not valid for DSP modes */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_NF:
- aif1 |= WM8904_AIF_BCLK_INV;
- break;
- default:
- return -EINVAL;
- }
- break;
-
- case SND_SOC_DAIFMT_I2S:
- case SND_SOC_DAIFMT_RIGHT_J:
- case SND_SOC_DAIFMT_LEFT_J:
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- aif1 |= WM8904_AIF_BCLK_INV | WM8904_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- aif1 |= WM8904_AIF_BCLK_INV;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- aif1 |= WM8904_AIF_LRCLK_INV;
- break;
- default:
- return -EINVAL;
- }
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
- WM8904_AIF_BCLK_INV | WM8904_AIF_LRCLK_INV |
- WM8904_AIF_FMT_MASK | WM8904_BCLK_DIR, aif1);
- snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_3,
- WM8904_LRCLK_DIR, aif3);
-
- return 0;
-}
-
-
-static int wm8904_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
- unsigned int rx_mask, int slots, int slot_width)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- int aif1 = 0;
-
- /* Don't need to validate anything if we're turning off TDM */
- if (slots == 0)
- goto out;
-
- /* Note that we allow configurations we can't handle ourselves -
- * for example, we can generate clocks for slots 2 and up even if
- * we can't use those slots ourselves.
- */
- aif1 |= WM8904_AIFADC_TDM | WM8904_AIFDAC_TDM;
-
- switch (rx_mask) {
- case 3:
- break;
- case 0xc:
- aif1 |= WM8904_AIFADC_TDM_CHAN;
- break;
- default:
- return -EINVAL;
- }
-
-
- switch (tx_mask) {
- case 3:
- break;
- case 0xc:
- aif1 |= WM8904_AIFDAC_TDM_CHAN;
- break;
- default:
- return -EINVAL;
- }
-
-out:
- wm8904->tdm_width = slot_width;
- wm8904->tdm_slots = slots / 2;
-
- snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
- WM8904_AIFADC_TDM | WM8904_AIFADC_TDM_CHAN |
- WM8904_AIFDAC_TDM | WM8904_AIFDAC_TDM_CHAN, aif1);
-
- return 0;
-}
-
-struct _fll_div {
- u16 fll_fratio;
- u16 fll_outdiv;
- u16 fll_clk_ref_div;
- u16 n;
- u16 k;
-};
-
-/* The size in bits of the FLL divide multiplied by 10
- * to allow rounding later */
-#define FIXED_FLL_SIZE ((1 << 16) * 10)
-
-static struct {
- unsigned int min;
- unsigned int max;
- u16 fll_fratio;
- int ratio;
-} fll_fratios[] = {
- { 0, 64000, 4, 16 },
- { 64000, 128000, 3, 8 },
- { 128000, 256000, 2, 4 },
- { 256000, 1000000, 1, 2 },
- { 1000000, 13500000, 0, 1 },
-};
-
-static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
- unsigned int Fout)
-{
- u64 Kpart;
- unsigned int K, Ndiv, Nmod, target;
- unsigned int div;
- int i;
-
- /* Fref must be <=13.5MHz */
- div = 1;
- fll_div->fll_clk_ref_div = 0;
- while ((Fref / div) > 13500000) {
- div *= 2;
- fll_div->fll_clk_ref_div++;
-
- if (div > 8) {
- pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
- Fref);
- return -EINVAL;
- }
- }
-
- pr_debug("Fref=%u Fout=%u\n", Fref, Fout);
-
- /* Apply the division for our remaining calculations */
- Fref /= div;
-
- /* Fvco should be 90-100MHz; don't check the upper bound */
- div = 4;
- while (Fout * div < 90000000) {
- div++;
- if (div > 64) {
- pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
- Fout);
- return -EINVAL;
- }
- }
- target = Fout * div;
- fll_div->fll_outdiv = div - 1;
-
- pr_debug("Fvco=%dHz\n", target);
-
- /* Find an appropriate FLL_FRATIO and factor it out of the target */
- for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
- if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
- fll_div->fll_fratio = fll_fratios[i].fll_fratio;
- target /= fll_fratios[i].ratio;
- break;
- }
- }
- if (i == ARRAY_SIZE(fll_fratios)) {
- pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
- return -EINVAL;
- }
-
- /* Now, calculate N.K */
- Ndiv = target / Fref;
-
- fll_div->n = Ndiv;
- Nmod = target % Fref;
- pr_debug("Nmod=%d\n", Nmod);
-
- /* Calculate fractional part - scale up so we can round. */
- Kpart = FIXED_FLL_SIZE * (long long)Nmod;
-
- do_div(Kpart, Fref);
-
- K = Kpart & 0xFFFFFFFF;
-
- if ((K % 10) >= 5)
- K += 5;
-
- /* Move down to proper range now rounding is done */
- fll_div->k = K / 10;
-
- pr_debug("N=%x K=%x FLL_FRATIO=%x FLL_OUTDIV=%x FLL_CLK_REF_DIV=%x\n",
- fll_div->n, fll_div->k,
- fll_div->fll_fratio, fll_div->fll_outdiv,
- fll_div->fll_clk_ref_div);
-
- return 0;
-}
-
-static int wm8904_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
- unsigned int Fref, unsigned int Fout)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- struct _fll_div fll_div;
- int ret, val;
- int clock2, fll1;
-
- /* Any change? */
- if (source == wm8904->fll_src && Fref == wm8904->fll_fref &&
- Fout == wm8904->fll_fout)
- return 0;
-
- clock2 = snd_soc_read(codec, WM8904_CLOCK_RATES_2);
-
- if (Fout == 0) {
- dev_dbg(codec->dev, "FLL disabled\n");
-
- wm8904->fll_fref = 0;
- wm8904->fll_fout = 0;
-
- /* Gate SYSCLK to avoid glitches */
- snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
- WM8904_CLK_SYS_ENA, 0);
-
- snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
- WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
-
- goto out;
- }
-
- /* Validate the FLL ID */
- switch (source) {
- case WM8904_FLL_MCLK:
- case WM8904_FLL_LRCLK:
- case WM8904_FLL_BCLK:
- ret = fll_factors(&fll_div, Fref, Fout);
- if (ret != 0)
- return ret;
- break;
-
- case WM8904_FLL_FREE_RUNNING:
- dev_dbg(codec->dev, "Using free running FLL\n");
- /* Force 12MHz and output/4 for now */
- Fout = 12000000;
- Fref = 12000000;
-
- memset(&fll_div, 0, sizeof(fll_div));
- fll_div.fll_outdiv = 3;
- break;
-
- default:
- dev_err(codec->dev, "Unknown FLL ID %d\n", fll_id);
- return -EINVAL;
- }
-
- /* Save current state then disable the FLL and SYSCLK to avoid
- * misclocking */
- fll1 = snd_soc_read(codec, WM8904_FLL_CONTROL_1);
- snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
- WM8904_CLK_SYS_ENA, 0);
- snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
- WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
-
- /* Unlock forced oscilator control to switch it on/off */
- snd_soc_update_bits(codec, WM8904_CONTROL_INTERFACE_TEST_1,
- WM8904_USER_KEY, WM8904_USER_KEY);
-
- if (fll_id == WM8904_FLL_FREE_RUNNING) {
- val = WM8904_FLL_FRC_NCO;
- } else {
- val = 0;
- }
-
- snd_soc_update_bits(codec, WM8904_FLL_NCO_TEST_1, WM8904_FLL_FRC_NCO,
- val);
- snd_soc_update_bits(codec, WM8904_CONTROL_INTERFACE_TEST_1,
- WM8904_USER_KEY, 0);
-
- switch (fll_id) {
- case WM8904_FLL_MCLK:
- snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
- WM8904_FLL_CLK_REF_SRC_MASK, 0);
- break;
-
- case WM8904_FLL_LRCLK:
- snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
- WM8904_FLL_CLK_REF_SRC_MASK, 1);
- break;
-
- case WM8904_FLL_BCLK:
- snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
- WM8904_FLL_CLK_REF_SRC_MASK, 2);
- break;
- }
-
- if (fll_div.k)
- val = WM8904_FLL_FRACN_ENA;
- else
- val = 0;
- snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
- WM8904_FLL_FRACN_ENA, val);
-
- snd_soc_update_bits(codec, WM8904_FLL_CONTROL_2,
- WM8904_FLL_OUTDIV_MASK | WM8904_FLL_FRATIO_MASK,
- (fll_div.fll_outdiv << WM8904_FLL_OUTDIV_SHIFT) |
- (fll_div.fll_fratio << WM8904_FLL_FRATIO_SHIFT));
-
- snd_soc_write(codec, WM8904_FLL_CONTROL_3, fll_div.k);
-
- snd_soc_update_bits(codec, WM8904_FLL_CONTROL_4, WM8904_FLL_N_MASK,
- fll_div.n << WM8904_FLL_N_SHIFT);
-
- snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
- WM8904_FLL_CLK_REF_DIV_MASK,
- fll_div.fll_clk_ref_div
- << WM8904_FLL_CLK_REF_DIV_SHIFT);
-
- dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
-
- wm8904->fll_fref = Fref;
- wm8904->fll_fout = Fout;
- wm8904->fll_src = source;
-
- /* Enable the FLL if it was previously active */
- snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
- WM8904_FLL_OSC_ENA, fll1);
- snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
- WM8904_FLL_ENA, fll1);
-
-out:
- /* Reenable SYSCLK if it was previously active */
- snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
- WM8904_CLK_SYS_ENA, clock2);
-
- return 0;
-}
-
-static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- int val;
-
- if (mute)
- val = WM8904_DAC_MUTE;
- else
- val = 0;
-
- snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1, WM8904_DAC_MUTE, val);
-
- return 0;
-}
-
-static int wm8904_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- /* VMID resistance 2*50k */
- snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
- WM8904_VMID_RES_MASK,
- 0x1 << WM8904_VMID_RES_SHIFT);
-
- /* Normal bias current */
- snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
- WM8904_ISEL_MASK, 2 << WM8904_ISEL_SHIFT);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
- wm8904->supplies);
- if (ret != 0) {
- dev_err(codec->dev,
- "Failed to enable supplies: %d\n",
- ret);
- return ret;
- }
-
- regcache_sync(wm8904->regmap);
-
- /* Enable bias */
- snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
- WM8904_BIAS_ENA, WM8904_BIAS_ENA);
-
- /* Enable VMID, VMID buffering, 2*5k resistance */
- snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
- WM8904_VMID_ENA |
- WM8904_VMID_RES_MASK,
- WM8904_VMID_ENA |
- 0x3 << WM8904_VMID_RES_SHIFT);
-
- /* Let VMID ramp */
- msleep(1);
- }
-
- /* Maintain VMID with 2*250k */
- snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
- WM8904_VMID_RES_MASK,
- 0x2 << WM8904_VMID_RES_SHIFT);
-
- /* Bias current *0.5 */
- snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
- WM8904_ISEL_MASK, 0);
- break;
-
- case SND_SOC_BIAS_OFF:
- /* Turn off VMID */
- snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
- WM8904_VMID_RES_MASK | WM8904_VMID_ENA, 0);
-
- /* Stop bias generation */
- snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
- WM8904_BIAS_ENA, 0);
-
-#ifdef CONFIG_REGULATOR
- /* Post 2.6.34 we will be able to get a callback when
- * the regulators are disabled which we can use but
- * for now just assume that the power will be cut if
- * the regulator API is in use.
- */
- codec->cache_sync = 1;
-#endif
-
- regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies),
- wm8904->supplies);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define WM8904_RATES SNDRV_PCM_RATE_8000_96000
-
-#define WM8904_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops wm8904_dai_ops = {
- .set_sysclk = wm8904_set_sysclk,
- .set_fmt = wm8904_set_fmt,
- .set_tdm_slot = wm8904_set_tdm_slot,
- .set_pll = wm8904_set_fll,
- .hw_params = wm8904_hw_params,
- .digital_mute = wm8904_digital_mute,
-};
-
-static struct snd_soc_dai_driver wm8904_dai = {
- .name = "wm8904-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = WM8904_RATES,
- .formats = WM8904_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = WM8904_RATES,
- .formats = WM8904_FORMATS,
- },
- .ops = &wm8904_dai_ops,
- .symmetric_rates = 1,
-};
-
-#ifdef CONFIG_PM
-static int wm8904_suspend(struct snd_soc_codec *codec)
-{
- wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int wm8904_resume(struct snd_soc_codec *codec)
-{
- wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-#else
-#define wm8904_suspend NULL
-#define wm8904_resume NULL
-#endif
-
-static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec)
-{
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- struct wm8904_pdata *pdata = wm8904->pdata;
- struct snd_kcontrol_new control =
- SOC_ENUM_EXT("EQ Mode",
- wm8904->retune_mobile_enum,
- wm8904_get_retune_mobile_enum,
- wm8904_put_retune_mobile_enum);
- int ret, i, j;
- const char **t;
-
- /* We need an array of texts for the enum API but the number
- * of texts is likely to be less than the number of
- * configurations due to the sample rate dependency of the
- * configurations. */
- wm8904->num_retune_mobile_texts = 0;
- wm8904->retune_mobile_texts = NULL;
- for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
- for (j = 0; j < wm8904->num_retune_mobile_texts; j++) {
- if (strcmp(pdata->retune_mobile_cfgs[i].name,
- wm8904->retune_mobile_texts[j]) == 0)
- break;
- }
-
- if (j != wm8904->num_retune_mobile_texts)
- continue;
-
- /* Expand the array... */
- t = krealloc(wm8904->retune_mobile_texts,
- sizeof(char *) *
- (wm8904->num_retune_mobile_texts + 1),
- GFP_KERNEL);
- if (t == NULL)
- continue;
-
- /* ...store the new entry... */
- t[wm8904->num_retune_mobile_texts] =
- pdata->retune_mobile_cfgs[i].name;
-
- /* ...and remember the new version. */
- wm8904->num_retune_mobile_texts++;
- wm8904->retune_mobile_texts = t;
- }
-
- dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
- wm8904->num_retune_mobile_texts);
-
- wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts;
- wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts;
-
- ret = snd_soc_add_codec_controls(codec, &control, 1);
- if (ret != 0)
- dev_err(codec->dev,
- "Failed to add ReTune Mobile control: %d\n", ret);
-}
-
-static void wm8904_handle_pdata(struct snd_soc_codec *codec)
-{
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- struct wm8904_pdata *pdata = wm8904->pdata;
- int ret, i;
-
- if (!pdata) {
- snd_soc_add_codec_controls(codec, wm8904_eq_controls,
- ARRAY_SIZE(wm8904_eq_controls));
- return;
- }
-
- dev_dbg(codec->dev, "%d DRC configurations\n", pdata->num_drc_cfgs);
-
- if (pdata->num_drc_cfgs) {
- struct snd_kcontrol_new control =
- SOC_ENUM_EXT("DRC Mode", wm8904->drc_enum,
- wm8904_get_drc_enum, wm8904_put_drc_enum);
-
- /* We need an array of texts for the enum API */
- wm8904->drc_texts = kmalloc(sizeof(char *)
- * pdata->num_drc_cfgs, GFP_KERNEL);
- if (!wm8904->drc_texts) {
- dev_err(codec->dev,
- "Failed to allocate %d DRC config texts\n",
- pdata->num_drc_cfgs);
- return;
- }
-
- for (i = 0; i < pdata->num_drc_cfgs; i++)
- wm8904->drc_texts[i] = pdata->drc_cfgs[i].name;
-
- wm8904->drc_enum.max = pdata->num_drc_cfgs;
- wm8904->drc_enum.texts = wm8904->drc_texts;
-
- ret = snd_soc_add_codec_controls(codec, &control, 1);
- if (ret != 0)
- dev_err(codec->dev,
- "Failed to add DRC mode control: %d\n", ret);
-
- wm8904_set_drc(codec);
- }
-
- dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
- pdata->num_retune_mobile_cfgs);
-
- if (pdata->num_retune_mobile_cfgs)
- wm8904_handle_retune_mobile_pdata(codec);
- else
- snd_soc_add_codec_controls(codec, wm8904_eq_controls,
- ARRAY_SIZE(wm8904_eq_controls));
-}
-
-
-static int wm8904_probe(struct snd_soc_codec *codec)
-{
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
- struct wm8904_pdata *pdata = wm8904->pdata;
- int ret, i;
-
- codec->cache_sync = 1;
- codec->control_data = wm8904->regmap;
-
- switch (wm8904->devtype) {
- case WM8904:
- break;
- case WM8912:
- memset(&wm8904_dai.capture, 0, sizeof(wm8904_dai.capture));
- break;
- default:
- dev_err(codec->dev, "Unknown device type %d\n",
- wm8904->devtype);
- return -EINVAL;
- }
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++)
- wm8904->supplies[i].supply = wm8904_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8904->supplies),
- wm8904->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- return ret;
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
- wm8904->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
- goto err_get;
- }
-
- ret = snd_soc_read(codec, WM8904_SW_RESET_AND_ID);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to read ID register\n");
- goto err_enable;
- }
- if (ret != 0x8904) {
- dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret);
- ret = -EINVAL;
- goto err_enable;
- }
-
- ret = snd_soc_read(codec, WM8904_REVISION);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to read device revision: %d\n",
- ret);
- goto err_enable;
- }
- dev_info(codec->dev, "revision %c\n", ret + 'A');
-
- ret = wm8904_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- goto err_enable;
- }
-
- /* Change some default settings - latch VU and enable ZC */
- snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_LEFT,
- WM8904_ADC_VU, WM8904_ADC_VU);
- snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_RIGHT,
- WM8904_ADC_VU, WM8904_ADC_VU);
- snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_VOLUME_LEFT,
- WM8904_DAC_VU, WM8904_DAC_VU);
- snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_VOLUME_RIGHT,
- WM8904_DAC_VU, WM8904_DAC_VU);
- snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT1_LEFT,
- WM8904_HPOUT_VU | WM8904_HPOUTLZC,
- WM8904_HPOUT_VU | WM8904_HPOUTLZC);
- snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT1_RIGHT,
- WM8904_HPOUT_VU | WM8904_HPOUTRZC,
- WM8904_HPOUT_VU | WM8904_HPOUTRZC);
- snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT2_LEFT,
- WM8904_LINEOUT_VU | WM8904_LINEOUTLZC,
- WM8904_LINEOUT_VU | WM8904_LINEOUTLZC);
- snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT2_RIGHT,
- WM8904_LINEOUT_VU | WM8904_LINEOUTRZC,
- WM8904_LINEOUT_VU | WM8904_LINEOUTRZC);
- snd_soc_update_bits(codec, WM8904_CLOCK_RATES_0,
- WM8904_SR_MODE, 0);
-
- /* Apply configuration from the platform data. */
- if (wm8904->pdata) {
- for (i = 0; i < WM8904_GPIO_REGS; i++) {
- if (!pdata->gpio_cfg[i])
- continue;
-
- regmap_update_bits(wm8904->regmap,
- WM8904_GPIO_CONTROL_1 + i,
- 0xffff,
- pdata->gpio_cfg[i]);
- }
-
- /* Zero is the default value for these anyway */
- for (i = 0; i < WM8904_MIC_REGS; i++)
- regmap_update_bits(wm8904->regmap,
- WM8904_MIC_BIAS_CONTROL_0 + i,
- 0xffff,
- pdata->mic_cfg[i]);
- }
-
- /* Set Class W by default - this will be managed by the Class
- * G widget at runtime where bypass paths are available.
- */
- snd_soc_update_bits(codec, WM8904_CLASS_W_0,
- WM8904_CP_DYN_PWR, WM8904_CP_DYN_PWR);
-
- /* Use normal bias source */
- snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
- WM8904_POBCTRL, 0);
-
- wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* Bias level configuration will have done an extra enable */
- regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
-
- wm8904_handle_pdata(codec);
-
- wm8904_add_widgets(codec);
-
- return 0;
-
-err_enable:
- regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
-err_get:
- regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
- return ret;
-}
-
-static int wm8904_remove(struct snd_soc_codec *codec)
-{
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
-
- wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
- regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
- kfree(wm8904->retune_mobile_texts);
- kfree(wm8904->drc_texts);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8904 = {
- .probe = wm8904_probe,
- .remove = wm8904_remove,
- .suspend = wm8904_suspend,
- .resume = wm8904_resume,
- .set_bias_level = wm8904_set_bias_level,
- .idle_bias_off = true,
-};
-
-static const struct regmap_config wm8904_regmap = {
- .reg_bits = 8,
- .val_bits = 16,
-
- .max_register = WM8904_MAX_REGISTER,
- .volatile_reg = wm8904_volatile_register,
- .readable_reg = wm8904_readable_register,
-
- .cache_type = REGCACHE_RBTREE,
- .reg_defaults = wm8904_reg_defaults,
- .num_reg_defaults = ARRAY_SIZE(wm8904_reg_defaults),
-};
-
-static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8904_priv *wm8904;
- int ret;
-
- wm8904 = devm_kzalloc(&i2c->dev, sizeof(struct wm8904_priv),
- GFP_KERNEL);
- if (wm8904 == NULL)
- return -ENOMEM;
-
- wm8904->regmap = regmap_init_i2c(i2c, &wm8904_regmap);
- if (IS_ERR(wm8904->regmap)) {
- ret = PTR_ERR(wm8904->regmap);
- dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
- ret);
- return ret;
- }
-
- wm8904->devtype = id->driver_data;
- i2c_set_clientdata(i2c, wm8904);
- wm8904->pdata = i2c->dev.platform_data;
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8904, &wm8904_dai, 1);
- if (ret != 0)
- goto err;
-
- return 0;
-
-err:
- regmap_exit(wm8904->regmap);
- return ret;
-}
-
-static __devexit int wm8904_i2c_remove(struct i2c_client *client)
-{
- struct wm8904_priv *wm8904 = i2c_get_clientdata(client);
- snd_soc_unregister_codec(&client->dev);
- regmap_exit(wm8904->regmap);
- return 0;
-}
-
-static const struct i2c_device_id wm8904_i2c_id[] = {
- { "wm8904", WM8904 },
- { "wm8912", WM8912 },
- { "wm8918", WM8904 }, /* Actually a subset, updates to follow */
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id);
-
-static struct i2c_driver wm8904_i2c_driver = {
- .driver = {
- .name = "wm8904",
- .owner = THIS_MODULE,
- },
- .probe = wm8904_i2c_probe,
- .remove = __devexit_p(wm8904_i2c_remove),
- .id_table = wm8904_i2c_id,
-};
-
-static int __init wm8904_modinit(void)
-{
- int ret = 0;
- ret = i2c_add_driver(&wm8904_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8904 I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(wm8904_modinit);
-
-static void __exit wm8904_exit(void)
-{
- i2c_del_driver(&wm8904_i2c_driver);
-}
-module_exit(wm8904_exit);
-
-MODULE_DESCRIPTION("ASoC WM8904 driver");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8904.h b/ANDROID_3.4.5/sound/soc/codecs/wm8904.h
deleted file mode 100644
index c29a0e81..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8904.h
+++ /dev/null
@@ -1,1592 +0,0 @@
-/*
- * wm8904.h -- WM8904 ASoC driver
- *
- * Copyright 2009 Wolfson Microelectronics, plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8904_H
-#define _WM8904_H
-
-#define WM8904_CLK_MCLK 1
-#define WM8904_CLK_FLL 2
-
-#define WM8904_FLL_MCLK 1
-#define WM8904_FLL_BCLK 2
-#define WM8904_FLL_LRCLK 3
-#define WM8904_FLL_FREE_RUNNING 4
-
-/*
- * Register values.
- */
-#define WM8904_SW_RESET_AND_ID 0x00
-#define WM8904_REVISION 0x01
-#define WM8904_BIAS_CONTROL_0 0x04
-#define WM8904_VMID_CONTROL_0 0x05
-#define WM8904_MIC_BIAS_CONTROL_0 0x06
-#define WM8904_MIC_BIAS_CONTROL_1 0x07
-#define WM8904_ANALOGUE_DAC_0 0x08
-#define WM8904_MIC_FILTER_CONTROL 0x09
-#define WM8904_ANALOGUE_ADC_0 0x0A
-#define WM8904_POWER_MANAGEMENT_0 0x0C
-#define WM8904_POWER_MANAGEMENT_2 0x0E
-#define WM8904_POWER_MANAGEMENT_3 0x0F
-#define WM8904_POWER_MANAGEMENT_6 0x12
-#define WM8904_CLOCK_RATES_0 0x14
-#define WM8904_CLOCK_RATES_1 0x15
-#define WM8904_CLOCK_RATES_2 0x16
-#define WM8904_AUDIO_INTERFACE_0 0x18
-#define WM8904_AUDIO_INTERFACE_1 0x19
-#define WM8904_AUDIO_INTERFACE_2 0x1A
-#define WM8904_AUDIO_INTERFACE_3 0x1B
-#define WM8904_DAC_DIGITAL_VOLUME_LEFT 0x1E
-#define WM8904_DAC_DIGITAL_VOLUME_RIGHT 0x1F
-#define WM8904_DAC_DIGITAL_0 0x20
-#define WM8904_DAC_DIGITAL_1 0x21
-#define WM8904_ADC_DIGITAL_VOLUME_LEFT 0x24
-#define WM8904_ADC_DIGITAL_VOLUME_RIGHT 0x25
-#define WM8904_ADC_DIGITAL_0 0x26
-#define WM8904_DIGITAL_MICROPHONE_0 0x27
-#define WM8904_DRC_0 0x28
-#define WM8904_DRC_1 0x29
-#define WM8904_DRC_2 0x2A
-#define WM8904_DRC_3 0x2B
-#define WM8904_ANALOGUE_LEFT_INPUT_0 0x2C
-#define WM8904_ANALOGUE_RIGHT_INPUT_0 0x2D
-#define WM8904_ANALOGUE_LEFT_INPUT_1 0x2E
-#define WM8904_ANALOGUE_RIGHT_INPUT_1 0x2F
-#define WM8904_ANALOGUE_OUT1_LEFT 0x39
-#define WM8904_ANALOGUE_OUT1_RIGHT 0x3A
-#define WM8904_ANALOGUE_OUT2_LEFT 0x3B
-#define WM8904_ANALOGUE_OUT2_RIGHT 0x3C
-#define WM8904_ANALOGUE_OUT12_ZC 0x3D
-#define WM8904_DC_SERVO_0 0x43
-#define WM8904_DC_SERVO_1 0x44
-#define WM8904_DC_SERVO_2 0x45
-#define WM8904_DC_SERVO_4 0x47
-#define WM8904_DC_SERVO_5 0x48
-#define WM8904_DC_SERVO_6 0x49
-#define WM8904_DC_SERVO_7 0x4A
-#define WM8904_DC_SERVO_8 0x4B
-#define WM8904_DC_SERVO_9 0x4C
-#define WM8904_DC_SERVO_READBACK_0 0x4D
-#define WM8904_ANALOGUE_HP_0 0x5A
-#define WM8904_ANALOGUE_LINEOUT_0 0x5E
-#define WM8904_CHARGE_PUMP_0 0x62
-#define WM8904_CLASS_W_0 0x68
-#define WM8904_WRITE_SEQUENCER_0 0x6C
-#define WM8904_WRITE_SEQUENCER_1 0x6D
-#define WM8904_WRITE_SEQUENCER_2 0x6E
-#define WM8904_WRITE_SEQUENCER_3 0x6F
-#define WM8904_WRITE_SEQUENCER_4 0x70
-#define WM8904_FLL_CONTROL_1 0x74
-#define WM8904_FLL_CONTROL_2 0x75
-#define WM8904_FLL_CONTROL_3 0x76
-#define WM8904_FLL_CONTROL_4 0x77
-#define WM8904_FLL_CONTROL_5 0x78
-#define WM8904_GPIO_CONTROL_1 0x79
-#define WM8904_GPIO_CONTROL_2 0x7A
-#define WM8904_GPIO_CONTROL_3 0x7B
-#define WM8904_GPIO_CONTROL_4 0x7C
-#define WM8904_DIGITAL_PULLS 0x7E
-#define WM8904_INTERRUPT_STATUS 0x7F
-#define WM8904_INTERRUPT_STATUS_MASK 0x80
-#define WM8904_INTERRUPT_POLARITY 0x81
-#define WM8904_INTERRUPT_DEBOUNCE 0x82
-#define WM8904_EQ1 0x86
-#define WM8904_EQ2 0x87
-#define WM8904_EQ3 0x88
-#define WM8904_EQ4 0x89
-#define WM8904_EQ5 0x8A
-#define WM8904_EQ6 0x8B
-#define WM8904_EQ7 0x8C
-#define WM8904_EQ8 0x8D
-#define WM8904_EQ9 0x8E
-#define WM8904_EQ10 0x8F
-#define WM8904_EQ11 0x90
-#define WM8904_EQ12 0x91
-#define WM8904_EQ13 0x92
-#define WM8904_EQ14 0x93
-#define WM8904_EQ15 0x94
-#define WM8904_EQ16 0x95
-#define WM8904_EQ17 0x96
-#define WM8904_EQ18 0x97
-#define WM8904_EQ19 0x98
-#define WM8904_EQ20 0x99
-#define WM8904_EQ21 0x9A
-#define WM8904_EQ22 0x9B
-#define WM8904_EQ23 0x9C
-#define WM8904_EQ24 0x9D
-#define WM8904_CONTROL_INTERFACE_TEST_1 0xA1
-#define WM8904_ADC_TEST_0 0xC6
-#define WM8904_ANALOGUE_OUTPUT_BIAS_0 0xCC
-#define WM8904_FLL_NCO_TEST_0 0xF7
-#define WM8904_FLL_NCO_TEST_1 0xF8
-
-#define WM8904_REGISTER_COUNT 101
-#define WM8904_MAX_REGISTER 0xF8
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - SW Reset and ID
- */
-#define WM8904_SW_RST_DEV_ID1_MASK 0xFFFF /* SW_RST_DEV_ID1 - [15:0] */
-#define WM8904_SW_RST_DEV_ID1_SHIFT 0 /* SW_RST_DEV_ID1 - [15:0] */
-#define WM8904_SW_RST_DEV_ID1_WIDTH 16 /* SW_RST_DEV_ID1 - [15:0] */
-
-/*
- * R1 (0x01) - Revision
- */
-#define WM8904_REVISION_MASK 0x000F /* REVISION - [3:0] */
-#define WM8904_REVISION_SHIFT 0 /* REVISION - [3:0] */
-#define WM8904_REVISION_WIDTH 16 /* REVISION - [3:0] */
-
-/*
- * R4 (0x04) - Bias Control 0
- */
-#define WM8904_POBCTRL 0x0010 /* POBCTRL */
-#define WM8904_POBCTRL_MASK 0x0010 /* POBCTRL */
-#define WM8904_POBCTRL_SHIFT 4 /* POBCTRL */
-#define WM8904_POBCTRL_WIDTH 1 /* POBCTRL */
-#define WM8904_ISEL_MASK 0x000C /* ISEL - [3:2] */
-#define WM8904_ISEL_SHIFT 2 /* ISEL - [3:2] */
-#define WM8904_ISEL_WIDTH 2 /* ISEL - [3:2] */
-#define WM8904_STARTUP_BIAS_ENA 0x0002 /* STARTUP_BIAS_ENA */
-#define WM8904_STARTUP_BIAS_ENA_MASK 0x0002 /* STARTUP_BIAS_ENA */
-#define WM8904_STARTUP_BIAS_ENA_SHIFT 1 /* STARTUP_BIAS_ENA */
-#define WM8904_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */
-#define WM8904_BIAS_ENA 0x0001 /* BIAS_ENA */
-#define WM8904_BIAS_ENA_MASK 0x0001 /* BIAS_ENA */
-#define WM8904_BIAS_ENA_SHIFT 0 /* BIAS_ENA */
-#define WM8904_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
-
-/*
- * R5 (0x05) - VMID Control 0
- */
-#define WM8904_VMID_BUF_ENA 0x0040 /* VMID_BUF_ENA */
-#define WM8904_VMID_BUF_ENA_MASK 0x0040 /* VMID_BUF_ENA */
-#define WM8904_VMID_BUF_ENA_SHIFT 6 /* VMID_BUF_ENA */
-#define WM8904_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
-#define WM8904_VMID_RES_MASK 0x0006 /* VMID_RES - [2:1] */
-#define WM8904_VMID_RES_SHIFT 1 /* VMID_RES - [2:1] */
-#define WM8904_VMID_RES_WIDTH 2 /* VMID_RES - [2:1] */
-#define WM8904_VMID_ENA 0x0001 /* VMID_ENA */
-#define WM8904_VMID_ENA_MASK 0x0001 /* VMID_ENA */
-#define WM8904_VMID_ENA_SHIFT 0 /* VMID_ENA */
-#define WM8904_VMID_ENA_WIDTH 1 /* VMID_ENA */
-
-/*
- * R8 (0x08) - Analogue DAC 0
- */
-#define WM8904_DAC_BIAS_SEL_MASK 0x0018 /* DAC_BIAS_SEL - [4:3] */
-#define WM8904_DAC_BIAS_SEL_SHIFT 3 /* DAC_BIAS_SEL - [4:3] */
-#define WM8904_DAC_BIAS_SEL_WIDTH 2 /* DAC_BIAS_SEL - [4:3] */
-#define WM8904_DAC_VMID_BIAS_SEL_MASK 0x0006 /* DAC_VMID_BIAS_SEL - [2:1] */
-#define WM8904_DAC_VMID_BIAS_SEL_SHIFT 1 /* DAC_VMID_BIAS_SEL - [2:1] */
-#define WM8904_DAC_VMID_BIAS_SEL_WIDTH 2 /* DAC_VMID_BIAS_SEL - [2:1] */
-
-/*
- * R9 (0x09) - mic Filter Control
- */
-#define WM8904_MIC_DET_SET_THRESHOLD_MASK 0xF000 /* MIC_DET_SET_THRESHOLD - [15:12] */
-#define WM8904_MIC_DET_SET_THRESHOLD_SHIFT 12 /* MIC_DET_SET_THRESHOLD - [15:12] */
-#define WM8904_MIC_DET_SET_THRESHOLD_WIDTH 4 /* MIC_DET_SET_THRESHOLD - [15:12] */
-#define WM8904_MIC_DET_RESET_THRESHOLD_MASK 0x0F00 /* MIC_DET_RESET_THRESHOLD - [11:8] */
-#define WM8904_MIC_DET_RESET_THRESHOLD_SHIFT 8 /* MIC_DET_RESET_THRESHOLD - [11:8] */
-#define WM8904_MIC_DET_RESET_THRESHOLD_WIDTH 4 /* MIC_DET_RESET_THRESHOLD - [11:8] */
-#define WM8904_MIC_SHORT_SET_THRESHOLD_MASK 0x00F0 /* MIC_SHORT_SET_THRESHOLD - [7:4] */
-#define WM8904_MIC_SHORT_SET_THRESHOLD_SHIFT 4 /* MIC_SHORT_SET_THRESHOLD - [7:4] */
-#define WM8904_MIC_SHORT_SET_THRESHOLD_WIDTH 4 /* MIC_SHORT_SET_THRESHOLD - [7:4] */
-#define WM8904_MIC_SHORT_RESET_THRESHOLD_MASK 0x000F /* MIC_SHORT_RESET_THRESHOLD - [3:0] */
-#define WM8904_MIC_SHORT_RESET_THRESHOLD_SHIFT 0 /* MIC_SHORT_RESET_THRESHOLD - [3:0] */
-#define WM8904_MIC_SHORT_RESET_THRESHOLD_WIDTH 4 /* MIC_SHORT_RESET_THRESHOLD - [3:0] */
-
-/*
- * R10 (0x0A) - Analogue ADC 0
- */
-#define WM8904_ADC_OSR128 0x0001 /* ADC_OSR128 */
-#define WM8904_ADC_OSR128_MASK 0x0001 /* ADC_OSR128 */
-#define WM8904_ADC_OSR128_SHIFT 0 /* ADC_OSR128 */
-#define WM8904_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
-
-/*
- * R12 (0x0C) - Power Management 0
- */
-#define WM8904_INL_ENA 0x0002 /* INL_ENA */
-#define WM8904_INL_ENA_MASK 0x0002 /* INL_ENA */
-#define WM8904_INL_ENA_SHIFT 1 /* INL_ENA */
-#define WM8904_INL_ENA_WIDTH 1 /* INL_ENA */
-#define WM8904_INR_ENA 0x0001 /* INR_ENA */
-#define WM8904_INR_ENA_MASK 0x0001 /* INR_ENA */
-#define WM8904_INR_ENA_SHIFT 0 /* INR_ENA */
-#define WM8904_INR_ENA_WIDTH 1 /* INR_ENA */
-
-/*
- * R14 (0x0E) - Power Management 2
- */
-#define WM8904_HPL_PGA_ENA 0x0002 /* HPL_PGA_ENA */
-#define WM8904_HPL_PGA_ENA_MASK 0x0002 /* HPL_PGA_ENA */
-#define WM8904_HPL_PGA_ENA_SHIFT 1 /* HPL_PGA_ENA */
-#define WM8904_HPL_PGA_ENA_WIDTH 1 /* HPL_PGA_ENA */
-#define WM8904_HPR_PGA_ENA 0x0001 /* HPR_PGA_ENA */
-#define WM8904_HPR_PGA_ENA_MASK 0x0001 /* HPR_PGA_ENA */
-#define WM8904_HPR_PGA_ENA_SHIFT 0 /* HPR_PGA_ENA */
-#define WM8904_HPR_PGA_ENA_WIDTH 1 /* HPR_PGA_ENA */
-
-/*
- * R15 (0x0F) - Power Management 3
- */
-#define WM8904_LINEOUTL_PGA_ENA 0x0002 /* LINEOUTL_PGA_ENA */
-#define WM8904_LINEOUTL_PGA_ENA_MASK 0x0002 /* LINEOUTL_PGA_ENA */
-#define WM8904_LINEOUTL_PGA_ENA_SHIFT 1 /* LINEOUTL_PGA_ENA */
-#define WM8904_LINEOUTL_PGA_ENA_WIDTH 1 /* LINEOUTL_PGA_ENA */
-#define WM8904_LINEOUTR_PGA_ENA 0x0001 /* LINEOUTR_PGA_ENA */
-#define WM8904_LINEOUTR_PGA_ENA_MASK 0x0001 /* LINEOUTR_PGA_ENA */
-#define WM8904_LINEOUTR_PGA_ENA_SHIFT 0 /* LINEOUTR_PGA_ENA */
-#define WM8904_LINEOUTR_PGA_ENA_WIDTH 1 /* LINEOUTR_PGA_ENA */
-
-/*
- * R18 (0x12) - Power Management 6
- */
-#define WM8904_DACL_ENA 0x0008 /* DACL_ENA */
-#define WM8904_DACL_ENA_MASK 0x0008 /* DACL_ENA */
-#define WM8904_DACL_ENA_SHIFT 3 /* DACL_ENA */
-#define WM8904_DACL_ENA_WIDTH 1 /* DACL_ENA */
-#define WM8904_DACR_ENA 0x0004 /* DACR_ENA */
-#define WM8904_DACR_ENA_MASK 0x0004 /* DACR_ENA */
-#define WM8904_DACR_ENA_SHIFT 2 /* DACR_ENA */
-#define WM8904_DACR_ENA_WIDTH 1 /* DACR_ENA */
-#define WM8904_ADCL_ENA 0x0002 /* ADCL_ENA */
-#define WM8904_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
-#define WM8904_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
-#define WM8904_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
-#define WM8904_ADCR_ENA 0x0001 /* ADCR_ENA */
-#define WM8904_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
-#define WM8904_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
-#define WM8904_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
-
-/*
- * R20 (0x14) - Clock Rates 0
- */
-#define WM8904_TOCLK_RATE_DIV16 0x4000 /* TOCLK_RATE_DIV16 */
-#define WM8904_TOCLK_RATE_DIV16_MASK 0x4000 /* TOCLK_RATE_DIV16 */
-#define WM8904_TOCLK_RATE_DIV16_SHIFT 14 /* TOCLK_RATE_DIV16 */
-#define WM8904_TOCLK_RATE_DIV16_WIDTH 1 /* TOCLK_RATE_DIV16 */
-#define WM8904_TOCLK_RATE_X4 0x2000 /* TOCLK_RATE_X4 */
-#define WM8904_TOCLK_RATE_X4_MASK 0x2000 /* TOCLK_RATE_X4 */
-#define WM8904_TOCLK_RATE_X4_SHIFT 13 /* TOCLK_RATE_X4 */
-#define WM8904_TOCLK_RATE_X4_WIDTH 1 /* TOCLK_RATE_X4 */
-#define WM8904_SR_MODE 0x1000 /* SR_MODE */
-#define WM8904_SR_MODE_MASK 0x1000 /* SR_MODE */
-#define WM8904_SR_MODE_SHIFT 12 /* SR_MODE */
-#define WM8904_SR_MODE_WIDTH 1 /* SR_MODE */
-#define WM8904_MCLK_DIV 0x0001 /* MCLK_DIV */
-#define WM8904_MCLK_DIV_MASK 0x0001 /* MCLK_DIV */
-#define WM8904_MCLK_DIV_SHIFT 0 /* MCLK_DIV */
-#define WM8904_MCLK_DIV_WIDTH 1 /* MCLK_DIV */
-
-/*
- * R21 (0x15) - Clock Rates 1
- */
-#define WM8904_CLK_SYS_RATE_MASK 0x3C00 /* CLK_SYS_RATE - [13:10] */
-#define WM8904_CLK_SYS_RATE_SHIFT 10 /* CLK_SYS_RATE - [13:10] */
-#define WM8904_CLK_SYS_RATE_WIDTH 4 /* CLK_SYS_RATE - [13:10] */
-#define WM8904_SAMPLE_RATE_MASK 0x0007 /* SAMPLE_RATE - [2:0] */
-#define WM8904_SAMPLE_RATE_SHIFT 0 /* SAMPLE_RATE - [2:0] */
-#define WM8904_SAMPLE_RATE_WIDTH 3 /* SAMPLE_RATE - [2:0] */
-
-/*
- * R22 (0x16) - Clock Rates 2
- */
-#define WM8904_MCLK_INV 0x8000 /* MCLK_INV */
-#define WM8904_MCLK_INV_MASK 0x8000 /* MCLK_INV */
-#define WM8904_MCLK_INV_SHIFT 15 /* MCLK_INV */
-#define WM8904_MCLK_INV_WIDTH 1 /* MCLK_INV */
-#define WM8904_SYSCLK_SRC 0x4000 /* SYSCLK_SRC */
-#define WM8904_SYSCLK_SRC_MASK 0x4000 /* SYSCLK_SRC */
-#define WM8904_SYSCLK_SRC_SHIFT 14 /* SYSCLK_SRC */
-#define WM8904_SYSCLK_SRC_WIDTH 1 /* SYSCLK_SRC */
-#define WM8904_TOCLK_RATE 0x1000 /* TOCLK_RATE */
-#define WM8904_TOCLK_RATE_MASK 0x1000 /* TOCLK_RATE */
-#define WM8904_TOCLK_RATE_SHIFT 12 /* TOCLK_RATE */
-#define WM8904_TOCLK_RATE_WIDTH 1 /* TOCLK_RATE */
-#define WM8904_OPCLK_ENA 0x0008 /* OPCLK_ENA */
-#define WM8904_OPCLK_ENA_MASK 0x0008 /* OPCLK_ENA */
-#define WM8904_OPCLK_ENA_SHIFT 3 /* OPCLK_ENA */
-#define WM8904_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
-#define WM8904_CLK_SYS_ENA 0x0004 /* CLK_SYS_ENA */
-#define WM8904_CLK_SYS_ENA_MASK 0x0004 /* CLK_SYS_ENA */
-#define WM8904_CLK_SYS_ENA_SHIFT 2 /* CLK_SYS_ENA */
-#define WM8904_CLK_SYS_ENA_WIDTH 1 /* CLK_SYS_ENA */
-#define WM8904_CLK_DSP_ENA 0x0002 /* CLK_DSP_ENA */
-#define WM8904_CLK_DSP_ENA_MASK 0x0002 /* CLK_DSP_ENA */
-#define WM8904_CLK_DSP_ENA_SHIFT 1 /* CLK_DSP_ENA */
-#define WM8904_CLK_DSP_ENA_WIDTH 1 /* CLK_DSP_ENA */
-#define WM8904_TOCLK_ENA 0x0001 /* TOCLK_ENA */
-#define WM8904_TOCLK_ENA_MASK 0x0001 /* TOCLK_ENA */
-#define WM8904_TOCLK_ENA_SHIFT 0 /* TOCLK_ENA */
-#define WM8904_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
-
-/*
- * R24 (0x18) - Audio Interface 0
- */
-#define WM8904_DACL_DATINV 0x1000 /* DACL_DATINV */
-#define WM8904_DACL_DATINV_MASK 0x1000 /* DACL_DATINV */
-#define WM8904_DACL_DATINV_SHIFT 12 /* DACL_DATINV */
-#define WM8904_DACL_DATINV_WIDTH 1 /* DACL_DATINV */
-#define WM8904_DACR_DATINV 0x0800 /* DACR_DATINV */
-#define WM8904_DACR_DATINV_MASK 0x0800 /* DACR_DATINV */
-#define WM8904_DACR_DATINV_SHIFT 11 /* DACR_DATINV */
-#define WM8904_DACR_DATINV_WIDTH 1 /* DACR_DATINV */
-#define WM8904_DAC_BOOST_MASK 0x0600 /* DAC_BOOST - [10:9] */
-#define WM8904_DAC_BOOST_SHIFT 9 /* DAC_BOOST - [10:9] */
-#define WM8904_DAC_BOOST_WIDTH 2 /* DAC_BOOST - [10:9] */
-#define WM8904_LOOPBACK 0x0100 /* LOOPBACK */
-#define WM8904_LOOPBACK_MASK 0x0100 /* LOOPBACK */
-#define WM8904_LOOPBACK_SHIFT 8 /* LOOPBACK */
-#define WM8904_LOOPBACK_WIDTH 1 /* LOOPBACK */
-#define WM8904_AIFADCL_SRC 0x0080 /* AIFADCL_SRC */
-#define WM8904_AIFADCL_SRC_MASK 0x0080 /* AIFADCL_SRC */
-#define WM8904_AIFADCL_SRC_SHIFT 7 /* AIFADCL_SRC */
-#define WM8904_AIFADCL_SRC_WIDTH 1 /* AIFADCL_SRC */
-#define WM8904_AIFADCR_SRC 0x0040 /* AIFADCR_SRC */
-#define WM8904_AIFADCR_SRC_MASK 0x0040 /* AIFADCR_SRC */
-#define WM8904_AIFADCR_SRC_SHIFT 6 /* AIFADCR_SRC */
-#define WM8904_AIFADCR_SRC_WIDTH 1 /* AIFADCR_SRC */
-#define WM8904_AIFDACL_SRC 0x0020 /* AIFDACL_SRC */
-#define WM8904_AIFDACL_SRC_MASK 0x0020 /* AIFDACL_SRC */
-#define WM8904_AIFDACL_SRC_SHIFT 5 /* AIFDACL_SRC */
-#define WM8904_AIFDACL_SRC_WIDTH 1 /* AIFDACL_SRC */
-#define WM8904_AIFDACR_SRC 0x0010 /* AIFDACR_SRC */
-#define WM8904_AIFDACR_SRC_MASK 0x0010 /* AIFDACR_SRC */
-#define WM8904_AIFDACR_SRC_SHIFT 4 /* AIFDACR_SRC */
-#define WM8904_AIFDACR_SRC_WIDTH 1 /* AIFDACR_SRC */
-#define WM8904_ADC_COMP 0x0008 /* ADC_COMP */
-#define WM8904_ADC_COMP_MASK 0x0008 /* ADC_COMP */
-#define WM8904_ADC_COMP_SHIFT 3 /* ADC_COMP */
-#define WM8904_ADC_COMP_WIDTH 1 /* ADC_COMP */
-#define WM8904_ADC_COMPMODE 0x0004 /* ADC_COMPMODE */
-#define WM8904_ADC_COMPMODE_MASK 0x0004 /* ADC_COMPMODE */
-#define WM8904_ADC_COMPMODE_SHIFT 2 /* ADC_COMPMODE */
-#define WM8904_ADC_COMPMODE_WIDTH 1 /* ADC_COMPMODE */
-#define WM8904_DAC_COMP 0x0002 /* DAC_COMP */
-#define WM8904_DAC_COMP_MASK 0x0002 /* DAC_COMP */
-#define WM8904_DAC_COMP_SHIFT 1 /* DAC_COMP */
-#define WM8904_DAC_COMP_WIDTH 1 /* DAC_COMP */
-#define WM8904_DAC_COMPMODE 0x0001 /* DAC_COMPMODE */
-#define WM8904_DAC_COMPMODE_MASK 0x0001 /* DAC_COMPMODE */
-#define WM8904_DAC_COMPMODE_SHIFT 0 /* DAC_COMPMODE */
-#define WM8904_DAC_COMPMODE_WIDTH 1 /* DAC_COMPMODE */
-
-/*
- * R25 (0x19) - Audio Interface 1
- */
-#define WM8904_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */
-#define WM8904_AIFDAC_TDM_MASK 0x2000 /* AIFDAC_TDM */
-#define WM8904_AIFDAC_TDM_SHIFT 13 /* AIFDAC_TDM */
-#define WM8904_AIFDAC_TDM_WIDTH 1 /* AIFDAC_TDM */
-#define WM8904_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */
-#define WM8904_AIFDAC_TDM_CHAN_MASK 0x1000 /* AIFDAC_TDM_CHAN */
-#define WM8904_AIFDAC_TDM_CHAN_SHIFT 12 /* AIFDAC_TDM_CHAN */
-#define WM8904_AIFDAC_TDM_CHAN_WIDTH 1 /* AIFDAC_TDM_CHAN */
-#define WM8904_AIFADC_TDM 0x0800 /* AIFADC_TDM */
-#define WM8904_AIFADC_TDM_MASK 0x0800 /* AIFADC_TDM */
-#define WM8904_AIFADC_TDM_SHIFT 11 /* AIFADC_TDM */
-#define WM8904_AIFADC_TDM_WIDTH 1 /* AIFADC_TDM */
-#define WM8904_AIFADC_TDM_CHAN 0x0400 /* AIFADC_TDM_CHAN */
-#define WM8904_AIFADC_TDM_CHAN_MASK 0x0400 /* AIFADC_TDM_CHAN */
-#define WM8904_AIFADC_TDM_CHAN_SHIFT 10 /* AIFADC_TDM_CHAN */
-#define WM8904_AIFADC_TDM_CHAN_WIDTH 1 /* AIFADC_TDM_CHAN */
-#define WM8904_AIF_TRIS 0x0100 /* AIF_TRIS */
-#define WM8904_AIF_TRIS_MASK 0x0100 /* AIF_TRIS */
-#define WM8904_AIF_TRIS_SHIFT 8 /* AIF_TRIS */
-#define WM8904_AIF_TRIS_WIDTH 1 /* AIF_TRIS */
-#define WM8904_AIF_BCLK_INV 0x0080 /* AIF_BCLK_INV */
-#define WM8904_AIF_BCLK_INV_MASK 0x0080 /* AIF_BCLK_INV */
-#define WM8904_AIF_BCLK_INV_SHIFT 7 /* AIF_BCLK_INV */
-#define WM8904_AIF_BCLK_INV_WIDTH 1 /* AIF_BCLK_INV */
-#define WM8904_BCLK_DIR 0x0040 /* BCLK_DIR */
-#define WM8904_BCLK_DIR_MASK 0x0040 /* BCLK_DIR */
-#define WM8904_BCLK_DIR_SHIFT 6 /* BCLK_DIR */
-#define WM8904_BCLK_DIR_WIDTH 1 /* BCLK_DIR */
-#define WM8904_AIF_LRCLK_INV 0x0010 /* AIF_LRCLK_INV */
-#define WM8904_AIF_LRCLK_INV_MASK 0x0010 /* AIF_LRCLK_INV */
-#define WM8904_AIF_LRCLK_INV_SHIFT 4 /* AIF_LRCLK_INV */
-#define WM8904_AIF_LRCLK_INV_WIDTH 1 /* AIF_LRCLK_INV */
-#define WM8904_AIF_WL_MASK 0x000C /* AIF_WL - [3:2] */
-#define WM8904_AIF_WL_SHIFT 2 /* AIF_WL - [3:2] */
-#define WM8904_AIF_WL_WIDTH 2 /* AIF_WL - [3:2] */
-#define WM8904_AIF_FMT_MASK 0x0003 /* AIF_FMT - [1:0] */
-#define WM8904_AIF_FMT_SHIFT 0 /* AIF_FMT - [1:0] */
-#define WM8904_AIF_FMT_WIDTH 2 /* AIF_FMT - [1:0] */
-
-/*
- * R26 (0x1A) - Audio Interface 2
- */
-#define WM8904_OPCLK_DIV_MASK 0x0F00 /* OPCLK_DIV - [11:8] */
-#define WM8904_OPCLK_DIV_SHIFT 8 /* OPCLK_DIV - [11:8] */
-#define WM8904_OPCLK_DIV_WIDTH 4 /* OPCLK_DIV - [11:8] */
-#define WM8904_BCLK_DIV_MASK 0x001F /* BCLK_DIV - [4:0] */
-#define WM8904_BCLK_DIV_SHIFT 0 /* BCLK_DIV - [4:0] */
-#define WM8904_BCLK_DIV_WIDTH 5 /* BCLK_DIV - [4:0] */
-
-/*
- * R27 (0x1B) - Audio Interface 3
- */
-#define WM8904_LRCLK_DIR 0x0800 /* LRCLK_DIR */
-#define WM8904_LRCLK_DIR_MASK 0x0800 /* LRCLK_DIR */
-#define WM8904_LRCLK_DIR_SHIFT 11 /* LRCLK_DIR */
-#define WM8904_LRCLK_DIR_WIDTH 1 /* LRCLK_DIR */
-#define WM8904_LRCLK_RATE_MASK 0x07FF /* LRCLK_RATE - [10:0] */
-#define WM8904_LRCLK_RATE_SHIFT 0 /* LRCLK_RATE - [10:0] */
-#define WM8904_LRCLK_RATE_WIDTH 11 /* LRCLK_RATE - [10:0] */
-
-/*
- * R30 (0x1E) - DAC Digital Volume Left
- */
-#define WM8904_DAC_VU 0x0100 /* DAC_VU */
-#define WM8904_DAC_VU_MASK 0x0100 /* DAC_VU */
-#define WM8904_DAC_VU_SHIFT 8 /* DAC_VU */
-#define WM8904_DAC_VU_WIDTH 1 /* DAC_VU */
-#define WM8904_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
-#define WM8904_DACL_VOL_SHIFT 0 /* DACL_VOL - [7:0] */
-#define WM8904_DACL_VOL_WIDTH 8 /* DACL_VOL - [7:0] */
-
-/*
- * R31 (0x1F) - DAC Digital Volume Right
- */
-#define WM8904_DAC_VU 0x0100 /* DAC_VU */
-#define WM8904_DAC_VU_MASK 0x0100 /* DAC_VU */
-#define WM8904_DAC_VU_SHIFT 8 /* DAC_VU */
-#define WM8904_DAC_VU_WIDTH 1 /* DAC_VU */
-#define WM8904_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
-#define WM8904_DACR_VOL_SHIFT 0 /* DACR_VOL - [7:0] */
-#define WM8904_DACR_VOL_WIDTH 8 /* DACR_VOL - [7:0] */
-
-/*
- * R32 (0x20) - DAC Digital 0
- */
-#define WM8904_ADCL_DAC_SVOL_MASK 0x0F00 /* ADCL_DAC_SVOL - [11:8] */
-#define WM8904_ADCL_DAC_SVOL_SHIFT 8 /* ADCL_DAC_SVOL - [11:8] */
-#define WM8904_ADCL_DAC_SVOL_WIDTH 4 /* ADCL_DAC_SVOL - [11:8] */
-#define WM8904_ADCR_DAC_SVOL_MASK 0x00F0 /* ADCR_DAC_SVOL - [7:4] */
-#define WM8904_ADCR_DAC_SVOL_SHIFT 4 /* ADCR_DAC_SVOL - [7:4] */
-#define WM8904_ADCR_DAC_SVOL_WIDTH 4 /* ADCR_DAC_SVOL - [7:4] */
-#define WM8904_ADC_TO_DACL_MASK 0x000C /* ADC_TO_DACL - [3:2] */
-#define WM8904_ADC_TO_DACL_SHIFT 2 /* ADC_TO_DACL - [3:2] */
-#define WM8904_ADC_TO_DACL_WIDTH 2 /* ADC_TO_DACL - [3:2] */
-#define WM8904_ADC_TO_DACR_MASK 0x0003 /* ADC_TO_DACR - [1:0] */
-#define WM8904_ADC_TO_DACR_SHIFT 0 /* ADC_TO_DACR - [1:0] */
-#define WM8904_ADC_TO_DACR_WIDTH 2 /* ADC_TO_DACR - [1:0] */
-
-/*
- * R33 (0x21) - DAC Digital 1
- */
-#define WM8904_DAC_MONO 0x1000 /* DAC_MONO */
-#define WM8904_DAC_MONO_MASK 0x1000 /* DAC_MONO */
-#define WM8904_DAC_MONO_SHIFT 12 /* DAC_MONO */
-#define WM8904_DAC_MONO_WIDTH 1 /* DAC_MONO */
-#define WM8904_DAC_SB_FILT 0x0800 /* DAC_SB_FILT */
-#define WM8904_DAC_SB_FILT_MASK 0x0800 /* DAC_SB_FILT */
-#define WM8904_DAC_SB_FILT_SHIFT 11 /* DAC_SB_FILT */
-#define WM8904_DAC_SB_FILT_WIDTH 1 /* DAC_SB_FILT */
-#define WM8904_DAC_MUTERATE 0x0400 /* DAC_MUTERATE */
-#define WM8904_DAC_MUTERATE_MASK 0x0400 /* DAC_MUTERATE */
-#define WM8904_DAC_MUTERATE_SHIFT 10 /* DAC_MUTERATE */
-#define WM8904_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
-#define WM8904_DAC_UNMUTE_RAMP 0x0200 /* DAC_UNMUTE_RAMP */
-#define WM8904_DAC_UNMUTE_RAMP_MASK 0x0200 /* DAC_UNMUTE_RAMP */
-#define WM8904_DAC_UNMUTE_RAMP_SHIFT 9 /* DAC_UNMUTE_RAMP */
-#define WM8904_DAC_UNMUTE_RAMP_WIDTH 1 /* DAC_UNMUTE_RAMP */
-#define WM8904_DAC_OSR128 0x0040 /* DAC_OSR128 */
-#define WM8904_DAC_OSR128_MASK 0x0040 /* DAC_OSR128 */
-#define WM8904_DAC_OSR128_SHIFT 6 /* DAC_OSR128 */
-#define WM8904_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
-#define WM8904_DAC_MUTE 0x0008 /* DAC_MUTE */
-#define WM8904_DAC_MUTE_MASK 0x0008 /* DAC_MUTE */
-#define WM8904_DAC_MUTE_SHIFT 3 /* DAC_MUTE */
-#define WM8904_DAC_MUTE_WIDTH 1 /* DAC_MUTE */
-#define WM8904_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */
-#define WM8904_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */
-#define WM8904_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */
-
-/*
- * R36 (0x24) - ADC Digital Volume Left
- */
-#define WM8904_ADC_VU 0x0100 /* ADC_VU */
-#define WM8904_ADC_VU_MASK 0x0100 /* ADC_VU */
-#define WM8904_ADC_VU_SHIFT 8 /* ADC_VU */
-#define WM8904_ADC_VU_WIDTH 1 /* ADC_VU */
-#define WM8904_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
-#define WM8904_ADCL_VOL_SHIFT 0 /* ADCL_VOL - [7:0] */
-#define WM8904_ADCL_VOL_WIDTH 8 /* ADCL_VOL - [7:0] */
-
-/*
- * R37 (0x25) - ADC Digital Volume Right
- */
-#define WM8904_ADC_VU 0x0100 /* ADC_VU */
-#define WM8904_ADC_VU_MASK 0x0100 /* ADC_VU */
-#define WM8904_ADC_VU_SHIFT 8 /* ADC_VU */
-#define WM8904_ADC_VU_WIDTH 1 /* ADC_VU */
-#define WM8904_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
-#define WM8904_ADCR_VOL_SHIFT 0 /* ADCR_VOL - [7:0] */
-#define WM8904_ADCR_VOL_WIDTH 8 /* ADCR_VOL - [7:0] */
-
-/*
- * R38 (0x26) - ADC Digital 0
- */
-#define WM8904_ADC_HPF_CUT_MASK 0x0060 /* ADC_HPF_CUT - [6:5] */
-#define WM8904_ADC_HPF_CUT_SHIFT 5 /* ADC_HPF_CUT - [6:5] */
-#define WM8904_ADC_HPF_CUT_WIDTH 2 /* ADC_HPF_CUT - [6:5] */
-#define WM8904_ADC_HPF 0x0010 /* ADC_HPF */
-#define WM8904_ADC_HPF_MASK 0x0010 /* ADC_HPF */
-#define WM8904_ADC_HPF_SHIFT 4 /* ADC_HPF */
-#define WM8904_ADC_HPF_WIDTH 1 /* ADC_HPF */
-#define WM8904_ADCL_DATINV 0x0002 /* ADCL_DATINV */
-#define WM8904_ADCL_DATINV_MASK 0x0002 /* ADCL_DATINV */
-#define WM8904_ADCL_DATINV_SHIFT 1 /* ADCL_DATINV */
-#define WM8904_ADCL_DATINV_WIDTH 1 /* ADCL_DATINV */
-#define WM8904_ADCR_DATINV 0x0001 /* ADCR_DATINV */
-#define WM8904_ADCR_DATINV_MASK 0x0001 /* ADCR_DATINV */
-#define WM8904_ADCR_DATINV_SHIFT 0 /* ADCR_DATINV */
-#define WM8904_ADCR_DATINV_WIDTH 1 /* ADCR_DATINV */
-
-/*
- * R39 (0x27) - Digital Microphone 0
- */
-#define WM8904_DMIC_ENA 0x1000 /* DMIC_ENA */
-#define WM8904_DMIC_ENA_MASK 0x1000 /* DMIC_ENA */
-#define WM8904_DMIC_ENA_SHIFT 12 /* DMIC_ENA */
-#define WM8904_DMIC_ENA_WIDTH 1 /* DMIC_ENA */
-#define WM8904_DMIC_SRC 0x0800 /* DMIC_SRC */
-#define WM8904_DMIC_SRC_MASK 0x0800 /* DMIC_SRC */
-#define WM8904_DMIC_SRC_SHIFT 11 /* DMIC_SRC */
-#define WM8904_DMIC_SRC_WIDTH 1 /* DMIC_SRC */
-
-/*
- * R40 (0x28) - DRC 0
- */
-#define WM8904_DRC_ENA 0x8000 /* DRC_ENA */
-#define WM8904_DRC_ENA_MASK 0x8000 /* DRC_ENA */
-#define WM8904_DRC_ENA_SHIFT 15 /* DRC_ENA */
-#define WM8904_DRC_ENA_WIDTH 1 /* DRC_ENA */
-#define WM8904_DRC_DAC_PATH 0x4000 /* DRC_DAC_PATH */
-#define WM8904_DRC_DAC_PATH_MASK 0x4000 /* DRC_DAC_PATH */
-#define WM8904_DRC_DAC_PATH_SHIFT 14 /* DRC_DAC_PATH */
-#define WM8904_DRC_DAC_PATH_WIDTH 1 /* DRC_DAC_PATH */
-#define WM8904_DRC_GS_HYST_LVL_MASK 0x1800 /* DRC_GS_HYST_LVL - [12:11] */
-#define WM8904_DRC_GS_HYST_LVL_SHIFT 11 /* DRC_GS_HYST_LVL - [12:11] */
-#define WM8904_DRC_GS_HYST_LVL_WIDTH 2 /* DRC_GS_HYST_LVL - [12:11] */
-#define WM8904_DRC_STARTUP_GAIN_MASK 0x07C0 /* DRC_STARTUP_GAIN - [10:6] */
-#define WM8904_DRC_STARTUP_GAIN_SHIFT 6 /* DRC_STARTUP_GAIN - [10:6] */
-#define WM8904_DRC_STARTUP_GAIN_WIDTH 5 /* DRC_STARTUP_GAIN - [10:6] */
-#define WM8904_DRC_FF_DELAY 0x0020 /* DRC_FF_DELAY */
-#define WM8904_DRC_FF_DELAY_MASK 0x0020 /* DRC_FF_DELAY */
-#define WM8904_DRC_FF_DELAY_SHIFT 5 /* DRC_FF_DELAY */
-#define WM8904_DRC_FF_DELAY_WIDTH 1 /* DRC_FF_DELAY */
-#define WM8904_DRC_GS_ENA 0x0008 /* DRC_GS_ENA */
-#define WM8904_DRC_GS_ENA_MASK 0x0008 /* DRC_GS_ENA */
-#define WM8904_DRC_GS_ENA_SHIFT 3 /* DRC_GS_ENA */
-#define WM8904_DRC_GS_ENA_WIDTH 1 /* DRC_GS_ENA */
-#define WM8904_DRC_QR 0x0004 /* DRC_QR */
-#define WM8904_DRC_QR_MASK 0x0004 /* DRC_QR */
-#define WM8904_DRC_QR_SHIFT 2 /* DRC_QR */
-#define WM8904_DRC_QR_WIDTH 1 /* DRC_QR */
-#define WM8904_DRC_ANTICLIP 0x0002 /* DRC_ANTICLIP */
-#define WM8904_DRC_ANTICLIP_MASK 0x0002 /* DRC_ANTICLIP */
-#define WM8904_DRC_ANTICLIP_SHIFT 1 /* DRC_ANTICLIP */
-#define WM8904_DRC_ANTICLIP_WIDTH 1 /* DRC_ANTICLIP */
-#define WM8904_DRC_GS_HYST 0x0001 /* DRC_GS_HYST */
-#define WM8904_DRC_GS_HYST_MASK 0x0001 /* DRC_GS_HYST */
-#define WM8904_DRC_GS_HYST_SHIFT 0 /* DRC_GS_HYST */
-#define WM8904_DRC_GS_HYST_WIDTH 1 /* DRC_GS_HYST */
-
-/*
- * R41 (0x29) - DRC 1
- */
-#define WM8904_DRC_ATK_MASK 0xF000 /* DRC_ATK - [15:12] */
-#define WM8904_DRC_ATK_SHIFT 12 /* DRC_ATK - [15:12] */
-#define WM8904_DRC_ATK_WIDTH 4 /* DRC_ATK - [15:12] */
-#define WM8904_DRC_DCY_MASK 0x0F00 /* DRC_DCY - [11:8] */
-#define WM8904_DRC_DCY_SHIFT 8 /* DRC_DCY - [11:8] */
-#define WM8904_DRC_DCY_WIDTH 4 /* DRC_DCY - [11:8] */
-#define WM8904_DRC_QR_THR_MASK 0x00C0 /* DRC_QR_THR - [7:6] */
-#define WM8904_DRC_QR_THR_SHIFT 6 /* DRC_QR_THR - [7:6] */
-#define WM8904_DRC_QR_THR_WIDTH 2 /* DRC_QR_THR - [7:6] */
-#define WM8904_DRC_QR_DCY_MASK 0x0030 /* DRC_QR_DCY - [5:4] */
-#define WM8904_DRC_QR_DCY_SHIFT 4 /* DRC_QR_DCY - [5:4] */
-#define WM8904_DRC_QR_DCY_WIDTH 2 /* DRC_QR_DCY - [5:4] */
-#define WM8904_DRC_MINGAIN_MASK 0x000C /* DRC_MINGAIN - [3:2] */
-#define WM8904_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [3:2] */
-#define WM8904_DRC_MINGAIN_WIDTH 2 /* DRC_MINGAIN - [3:2] */
-#define WM8904_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */
-#define WM8904_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */
-#define WM8904_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */
-
-/*
- * R42 (0x2A) - DRC 2
- */
-#define WM8904_DRC_HI_COMP_MASK 0x0038 /* DRC_HI_COMP - [5:3] */
-#define WM8904_DRC_HI_COMP_SHIFT 3 /* DRC_HI_COMP - [5:3] */
-#define WM8904_DRC_HI_COMP_WIDTH 3 /* DRC_HI_COMP - [5:3] */
-#define WM8904_DRC_LO_COMP_MASK 0x0007 /* DRC_LO_COMP - [2:0] */
-#define WM8904_DRC_LO_COMP_SHIFT 0 /* DRC_LO_COMP - [2:0] */
-#define WM8904_DRC_LO_COMP_WIDTH 3 /* DRC_LO_COMP - [2:0] */
-
-/*
- * R43 (0x2B) - DRC 3
- */
-#define WM8904_DRC_KNEE_IP_MASK 0x07E0 /* DRC_KNEE_IP - [10:5] */
-#define WM8904_DRC_KNEE_IP_SHIFT 5 /* DRC_KNEE_IP - [10:5] */
-#define WM8904_DRC_KNEE_IP_WIDTH 6 /* DRC_KNEE_IP - [10:5] */
-#define WM8904_DRC_KNEE_OP_MASK 0x001F /* DRC_KNEE_OP - [4:0] */
-#define WM8904_DRC_KNEE_OP_SHIFT 0 /* DRC_KNEE_OP - [4:0] */
-#define WM8904_DRC_KNEE_OP_WIDTH 5 /* DRC_KNEE_OP - [4:0] */
-
-/*
- * R44 (0x2C) - Analogue Left Input 0
- */
-#define WM8904_LINMUTE 0x0080 /* LINMUTE */
-#define WM8904_LINMUTE_MASK 0x0080 /* LINMUTE */
-#define WM8904_LINMUTE_SHIFT 7 /* LINMUTE */
-#define WM8904_LINMUTE_WIDTH 1 /* LINMUTE */
-#define WM8904_LIN_VOL_MASK 0x001F /* LIN_VOL - [4:0] */
-#define WM8904_LIN_VOL_SHIFT 0 /* LIN_VOL - [4:0] */
-#define WM8904_LIN_VOL_WIDTH 5 /* LIN_VOL - [4:0] */
-
-/*
- * R45 (0x2D) - Analogue Right Input 0
- */
-#define WM8904_RINMUTE 0x0080 /* RINMUTE */
-#define WM8904_RINMUTE_MASK 0x0080 /* RINMUTE */
-#define WM8904_RINMUTE_SHIFT 7 /* RINMUTE */
-#define WM8904_RINMUTE_WIDTH 1 /* RINMUTE */
-#define WM8904_RIN_VOL_MASK 0x001F /* RIN_VOL - [4:0] */
-#define WM8904_RIN_VOL_SHIFT 0 /* RIN_VOL - [4:0] */
-#define WM8904_RIN_VOL_WIDTH 5 /* RIN_VOL - [4:0] */
-
-/*
- * R46 (0x2E) - Analogue Left Input 1
- */
-#define WM8904_INL_CM_ENA 0x0040 /* INL_CM_ENA */
-#define WM8904_INL_CM_ENA_MASK 0x0040 /* INL_CM_ENA */
-#define WM8904_INL_CM_ENA_SHIFT 6 /* INL_CM_ENA */
-#define WM8904_INL_CM_ENA_WIDTH 1 /* INL_CM_ENA */
-#define WM8904_L_IP_SEL_N_MASK 0x0030 /* L_IP_SEL_N - [5:4] */
-#define WM8904_L_IP_SEL_N_SHIFT 4 /* L_IP_SEL_N - [5:4] */
-#define WM8904_L_IP_SEL_N_WIDTH 2 /* L_IP_SEL_N - [5:4] */
-#define WM8904_L_IP_SEL_P_MASK 0x000C /* L_IP_SEL_P - [3:2] */
-#define WM8904_L_IP_SEL_P_SHIFT 2 /* L_IP_SEL_P - [3:2] */
-#define WM8904_L_IP_SEL_P_WIDTH 2 /* L_IP_SEL_P - [3:2] */
-#define WM8904_L_MODE_MASK 0x0003 /* L_MODE - [1:0] */
-#define WM8904_L_MODE_SHIFT 0 /* L_MODE - [1:0] */
-#define WM8904_L_MODE_WIDTH 2 /* L_MODE - [1:0] */
-
-/*
- * R47 (0x2F) - Analogue Right Input 1
- */
-#define WM8904_INR_CM_ENA 0x0040 /* INR_CM_ENA */
-#define WM8904_INR_CM_ENA_MASK 0x0040 /* INR_CM_ENA */
-#define WM8904_INR_CM_ENA_SHIFT 6 /* INR_CM_ENA */
-#define WM8904_INR_CM_ENA_WIDTH 1 /* INR_CM_ENA */
-#define WM8904_R_IP_SEL_N_MASK 0x0030 /* R_IP_SEL_N - [5:4] */
-#define WM8904_R_IP_SEL_N_SHIFT 4 /* R_IP_SEL_N - [5:4] */
-#define WM8904_R_IP_SEL_N_WIDTH 2 /* R_IP_SEL_N - [5:4] */
-#define WM8904_R_IP_SEL_P_MASK 0x000C /* R_IP_SEL_P - [3:2] */
-#define WM8904_R_IP_SEL_P_SHIFT 2 /* R_IP_SEL_P - [3:2] */
-#define WM8904_R_IP_SEL_P_WIDTH 2 /* R_IP_SEL_P - [3:2] */
-#define WM8904_R_MODE_MASK 0x0003 /* R_MODE - [1:0] */
-#define WM8904_R_MODE_SHIFT 0 /* R_MODE - [1:0] */
-#define WM8904_R_MODE_WIDTH 2 /* R_MODE - [1:0] */
-
-/*
- * R57 (0x39) - Analogue OUT1 Left
- */
-#define WM8904_HPOUTL_MUTE 0x0100 /* HPOUTL_MUTE */
-#define WM8904_HPOUTL_MUTE_MASK 0x0100 /* HPOUTL_MUTE */
-#define WM8904_HPOUTL_MUTE_SHIFT 8 /* HPOUTL_MUTE */
-#define WM8904_HPOUTL_MUTE_WIDTH 1 /* HPOUTL_MUTE */
-#define WM8904_HPOUT_VU 0x0080 /* HPOUT_VU */
-#define WM8904_HPOUT_VU_MASK 0x0080 /* HPOUT_VU */
-#define WM8904_HPOUT_VU_SHIFT 7 /* HPOUT_VU */
-#define WM8904_HPOUT_VU_WIDTH 1 /* HPOUT_VU */
-#define WM8904_HPOUTLZC 0x0040 /* HPOUTLZC */
-#define WM8904_HPOUTLZC_MASK 0x0040 /* HPOUTLZC */
-#define WM8904_HPOUTLZC_SHIFT 6 /* HPOUTLZC */
-#define WM8904_HPOUTLZC_WIDTH 1 /* HPOUTLZC */
-#define WM8904_HPOUTL_VOL_MASK 0x003F /* HPOUTL_VOL - [5:0] */
-#define WM8904_HPOUTL_VOL_SHIFT 0 /* HPOUTL_VOL - [5:0] */
-#define WM8904_HPOUTL_VOL_WIDTH 6 /* HPOUTL_VOL - [5:0] */
-
-/*
- * R58 (0x3A) - Analogue OUT1 Right
- */
-#define WM8904_HPOUTR_MUTE 0x0100 /* HPOUTR_MUTE */
-#define WM8904_HPOUTR_MUTE_MASK 0x0100 /* HPOUTR_MUTE */
-#define WM8904_HPOUTR_MUTE_SHIFT 8 /* HPOUTR_MUTE */
-#define WM8904_HPOUTR_MUTE_WIDTH 1 /* HPOUTR_MUTE */
-#define WM8904_HPOUT_VU 0x0080 /* HPOUT_VU */
-#define WM8904_HPOUT_VU_MASK 0x0080 /* HPOUT_VU */
-#define WM8904_HPOUT_VU_SHIFT 7 /* HPOUT_VU */
-#define WM8904_HPOUT_VU_WIDTH 1 /* HPOUT_VU */
-#define WM8904_HPOUTRZC 0x0040 /* HPOUTRZC */
-#define WM8904_HPOUTRZC_MASK 0x0040 /* HPOUTRZC */
-#define WM8904_HPOUTRZC_SHIFT 6 /* HPOUTRZC */
-#define WM8904_HPOUTRZC_WIDTH 1 /* HPOUTRZC */
-#define WM8904_HPOUTR_VOL_MASK 0x003F /* HPOUTR_VOL - [5:0] */
-#define WM8904_HPOUTR_VOL_SHIFT 0 /* HPOUTR_VOL - [5:0] */
-#define WM8904_HPOUTR_VOL_WIDTH 6 /* HPOUTR_VOL - [5:0] */
-
-/*
- * R59 (0x3B) - Analogue OUT2 Left
- */
-#define WM8904_LINEOUTL_MUTE 0x0100 /* LINEOUTL_MUTE */
-#define WM8904_LINEOUTL_MUTE_MASK 0x0100 /* LINEOUTL_MUTE */
-#define WM8904_LINEOUTL_MUTE_SHIFT 8 /* LINEOUTL_MUTE */
-#define WM8904_LINEOUTL_MUTE_WIDTH 1 /* LINEOUTL_MUTE */
-#define WM8904_LINEOUT_VU 0x0080 /* LINEOUT_VU */
-#define WM8904_LINEOUT_VU_MASK 0x0080 /* LINEOUT_VU */
-#define WM8904_LINEOUT_VU_SHIFT 7 /* LINEOUT_VU */
-#define WM8904_LINEOUT_VU_WIDTH 1 /* LINEOUT_VU */
-#define WM8904_LINEOUTLZC 0x0040 /* LINEOUTLZC */
-#define WM8904_LINEOUTLZC_MASK 0x0040 /* LINEOUTLZC */
-#define WM8904_LINEOUTLZC_SHIFT 6 /* LINEOUTLZC */
-#define WM8904_LINEOUTLZC_WIDTH 1 /* LINEOUTLZC */
-#define WM8904_LINEOUTL_VOL_MASK 0x003F /* LINEOUTL_VOL - [5:0] */
-#define WM8904_LINEOUTL_VOL_SHIFT 0 /* LINEOUTL_VOL - [5:0] */
-#define WM8904_LINEOUTL_VOL_WIDTH 6 /* LINEOUTL_VOL - [5:0] */
-
-/*
- * R60 (0x3C) - Analogue OUT2 Right
- */
-#define WM8904_LINEOUTR_MUTE 0x0100 /* LINEOUTR_MUTE */
-#define WM8904_LINEOUTR_MUTE_MASK 0x0100 /* LINEOUTR_MUTE */
-#define WM8904_LINEOUTR_MUTE_SHIFT 8 /* LINEOUTR_MUTE */
-#define WM8904_LINEOUTR_MUTE_WIDTH 1 /* LINEOUTR_MUTE */
-#define WM8904_LINEOUT_VU 0x0080 /* LINEOUT_VU */
-#define WM8904_LINEOUT_VU_MASK 0x0080 /* LINEOUT_VU */
-#define WM8904_LINEOUT_VU_SHIFT 7 /* LINEOUT_VU */
-#define WM8904_LINEOUT_VU_WIDTH 1 /* LINEOUT_VU */
-#define WM8904_LINEOUTRZC 0x0040 /* LINEOUTRZC */
-#define WM8904_LINEOUTRZC_MASK 0x0040 /* LINEOUTRZC */
-#define WM8904_LINEOUTRZC_SHIFT 6 /* LINEOUTRZC */
-#define WM8904_LINEOUTRZC_WIDTH 1 /* LINEOUTRZC */
-#define WM8904_LINEOUTR_VOL_MASK 0x003F /* LINEOUTR_VOL - [5:0] */
-#define WM8904_LINEOUTR_VOL_SHIFT 0 /* LINEOUTR_VOL - [5:0] */
-#define WM8904_LINEOUTR_VOL_WIDTH 6 /* LINEOUTR_VOL - [5:0] */
-
-/*
- * R61 (0x3D) - Analogue OUT12 ZC
- */
-#define WM8904_HPL_BYP_ENA 0x0008 /* HPL_BYP_ENA */
-#define WM8904_HPL_BYP_ENA_MASK 0x0008 /* HPL_BYP_ENA */
-#define WM8904_HPL_BYP_ENA_SHIFT 3 /* HPL_BYP_ENA */
-#define WM8904_HPL_BYP_ENA_WIDTH 1 /* HPL_BYP_ENA */
-#define WM8904_HPR_BYP_ENA 0x0004 /* HPR_BYP_ENA */
-#define WM8904_HPR_BYP_ENA_MASK 0x0004 /* HPR_BYP_ENA */
-#define WM8904_HPR_BYP_ENA_SHIFT 2 /* HPR_BYP_ENA */
-#define WM8904_HPR_BYP_ENA_WIDTH 1 /* HPR_BYP_ENA */
-#define WM8904_LINEOUTL_BYP_ENA 0x0002 /* LINEOUTL_BYP_ENA */
-#define WM8904_LINEOUTL_BYP_ENA_MASK 0x0002 /* LINEOUTL_BYP_ENA */
-#define WM8904_LINEOUTL_BYP_ENA_SHIFT 1 /* LINEOUTL_BYP_ENA */
-#define WM8904_LINEOUTL_BYP_ENA_WIDTH 1 /* LINEOUTL_BYP_ENA */
-#define WM8904_LINEOUTR_BYP_ENA 0x0001 /* LINEOUTR_BYP_ENA */
-#define WM8904_LINEOUTR_BYP_ENA_MASK 0x0001 /* LINEOUTR_BYP_ENA */
-#define WM8904_LINEOUTR_BYP_ENA_SHIFT 0 /* LINEOUTR_BYP_ENA */
-#define WM8904_LINEOUTR_BYP_ENA_WIDTH 1 /* LINEOUTR_BYP_ENA */
-
-/*
- * R67 (0x43) - DC Servo 0
- */
-#define WM8904_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */
-#define WM8904_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */
-#define WM8904_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */
-#define WM8904_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */
-#define WM8904_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */
-#define WM8904_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */
-#define WM8904_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */
-#define WM8904_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */
-#define WM8904_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
-#define WM8904_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
-#define WM8904_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
-#define WM8904_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
-#define WM8904_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
-#define WM8904_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
-#define WM8904_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
-#define WM8904_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
-
-/*
- * R68 (0x44) - DC Servo 1
- */
-#define WM8904_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */
-#define WM8904_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */
-#define WM8904_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */
-#define WM8904_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */
-#define WM8904_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */
-#define WM8904_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */
-#define WM8904_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */
-#define WM8904_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */
-#define WM8904_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
-#define WM8904_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
-#define WM8904_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
-#define WM8904_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
-#define WM8904_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
-#define WM8904_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
-#define WM8904_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
-#define WM8904_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
-#define WM8904_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */
-#define WM8904_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */
-#define WM8904_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */
-#define WM8904_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */
-#define WM8904_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */
-#define WM8904_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */
-#define WM8904_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */
-#define WM8904_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */
-#define WM8904_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
-#define WM8904_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
-#define WM8904_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
-#define WM8904_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
-#define WM8904_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
-#define WM8904_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
-#define WM8904_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
-#define WM8904_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
-#define WM8904_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */
-#define WM8904_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */
-#define WM8904_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */
-#define WM8904_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */
-#define WM8904_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */
-#define WM8904_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */
-#define WM8904_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */
-#define WM8904_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */
-#define WM8904_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
-#define WM8904_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
-#define WM8904_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
-#define WM8904_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
-#define WM8904_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
-#define WM8904_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
-#define WM8904_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
-#define WM8904_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
-#define WM8904_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */
-#define WM8904_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */
-#define WM8904_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */
-#define WM8904_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */
-#define WM8904_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */
-#define WM8904_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */
-#define WM8904_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */
-#define WM8904_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */
-#define WM8904_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */
-#define WM8904_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */
-#define WM8904_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */
-#define WM8904_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
-#define WM8904_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */
-#define WM8904_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */
-#define WM8904_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */
-#define WM8904_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
-
-/*
- * R69 (0x45) - DC Servo 2
- */
-#define WM8904_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */
-#define WM8904_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */
-#define WM8904_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */
-#define WM8904_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
-#define WM8904_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
-#define WM8904_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
-
-/*
- * R71 (0x47) - DC Servo 4
- */
-#define WM8904_DCS_SERIES_NO_23_MASK 0x007F /* DCS_SERIES_NO_23 - [6:0] */
-#define WM8904_DCS_SERIES_NO_23_SHIFT 0 /* DCS_SERIES_NO_23 - [6:0] */
-#define WM8904_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [6:0] */
-
-/*
- * R72 (0x48) - DC Servo 5
- */
-#define WM8904_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */
-#define WM8904_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */
-#define WM8904_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */
-
-/*
- * R73 (0x49) - DC Servo 6
- */
-#define WM8904_DCS_DAC_WR_VAL_3_MASK 0x00FF /* DCS_DAC_WR_VAL_3 - [7:0] */
-#define WM8904_DCS_DAC_WR_VAL_3_SHIFT 0 /* DCS_DAC_WR_VAL_3 - [7:0] */
-#define WM8904_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [7:0] */
-
-/*
- * R74 (0x4A) - DC Servo 7
- */
-#define WM8904_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */
-#define WM8904_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */
-#define WM8904_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */
-
-/*
- * R75 (0x4B) - DC Servo 8
- */
-#define WM8904_DCS_DAC_WR_VAL_1_MASK 0x00FF /* DCS_DAC_WR_VAL_1 - [7:0] */
-#define WM8904_DCS_DAC_WR_VAL_1_SHIFT 0 /* DCS_DAC_WR_VAL_1 - [7:0] */
-#define WM8904_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [7:0] */
-
-/*
- * R76 (0x4C) - DC Servo 9
- */
-#define WM8904_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
-#define WM8904_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
-#define WM8904_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
-
-/*
- * R77 (0x4D) - DC Servo Readback 0
- */
-#define WM8904_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */
-#define WM8904_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */
-#define WM8904_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */
-#define WM8904_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */
-#define WM8904_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
-#define WM8904_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
-#define WM8904_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */
-#define WM8904_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */
-#define WM8904_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */
-
-/*
- * R90 (0x5A) - Analogue HP 0
- */
-#define WM8904_HPL_RMV_SHORT 0x0080 /* HPL_RMV_SHORT */
-#define WM8904_HPL_RMV_SHORT_MASK 0x0080 /* HPL_RMV_SHORT */
-#define WM8904_HPL_RMV_SHORT_SHIFT 7 /* HPL_RMV_SHORT */
-#define WM8904_HPL_RMV_SHORT_WIDTH 1 /* HPL_RMV_SHORT */
-#define WM8904_HPL_ENA_OUTP 0x0040 /* HPL_ENA_OUTP */
-#define WM8904_HPL_ENA_OUTP_MASK 0x0040 /* HPL_ENA_OUTP */
-#define WM8904_HPL_ENA_OUTP_SHIFT 6 /* HPL_ENA_OUTP */
-#define WM8904_HPL_ENA_OUTP_WIDTH 1 /* HPL_ENA_OUTP */
-#define WM8904_HPL_ENA_DLY 0x0020 /* HPL_ENA_DLY */
-#define WM8904_HPL_ENA_DLY_MASK 0x0020 /* HPL_ENA_DLY */
-#define WM8904_HPL_ENA_DLY_SHIFT 5 /* HPL_ENA_DLY */
-#define WM8904_HPL_ENA_DLY_WIDTH 1 /* HPL_ENA_DLY */
-#define WM8904_HPL_ENA 0x0010 /* HPL_ENA */
-#define WM8904_HPL_ENA_MASK 0x0010 /* HPL_ENA */
-#define WM8904_HPL_ENA_SHIFT 4 /* HPL_ENA */
-#define WM8904_HPL_ENA_WIDTH 1 /* HPL_ENA */
-#define WM8904_HPR_RMV_SHORT 0x0008 /* HPR_RMV_SHORT */
-#define WM8904_HPR_RMV_SHORT_MASK 0x0008 /* HPR_RMV_SHORT */
-#define WM8904_HPR_RMV_SHORT_SHIFT 3 /* HPR_RMV_SHORT */
-#define WM8904_HPR_RMV_SHORT_WIDTH 1 /* HPR_RMV_SHORT */
-#define WM8904_HPR_ENA_OUTP 0x0004 /* HPR_ENA_OUTP */
-#define WM8904_HPR_ENA_OUTP_MASK 0x0004 /* HPR_ENA_OUTP */
-#define WM8904_HPR_ENA_OUTP_SHIFT 2 /* HPR_ENA_OUTP */
-#define WM8904_HPR_ENA_OUTP_WIDTH 1 /* HPR_ENA_OUTP */
-#define WM8904_HPR_ENA_DLY 0x0002 /* HPR_ENA_DLY */
-#define WM8904_HPR_ENA_DLY_MASK 0x0002 /* HPR_ENA_DLY */
-#define WM8904_HPR_ENA_DLY_SHIFT 1 /* HPR_ENA_DLY */
-#define WM8904_HPR_ENA_DLY_WIDTH 1 /* HPR_ENA_DLY */
-#define WM8904_HPR_ENA 0x0001 /* HPR_ENA */
-#define WM8904_HPR_ENA_MASK 0x0001 /* HPR_ENA */
-#define WM8904_HPR_ENA_SHIFT 0 /* HPR_ENA */
-#define WM8904_HPR_ENA_WIDTH 1 /* HPR_ENA */
-
-/*
- * R94 (0x5E) - Analogue Lineout 0
- */
-#define WM8904_LINEOUTL_RMV_SHORT 0x0080 /* LINEOUTL_RMV_SHORT */
-#define WM8904_LINEOUTL_RMV_SHORT_MASK 0x0080 /* LINEOUTL_RMV_SHORT */
-#define WM8904_LINEOUTL_RMV_SHORT_SHIFT 7 /* LINEOUTL_RMV_SHORT */
-#define WM8904_LINEOUTL_RMV_SHORT_WIDTH 1 /* LINEOUTL_RMV_SHORT */
-#define WM8904_LINEOUTL_ENA_OUTP 0x0040 /* LINEOUTL_ENA_OUTP */
-#define WM8904_LINEOUTL_ENA_OUTP_MASK 0x0040 /* LINEOUTL_ENA_OUTP */
-#define WM8904_LINEOUTL_ENA_OUTP_SHIFT 6 /* LINEOUTL_ENA_OUTP */
-#define WM8904_LINEOUTL_ENA_OUTP_WIDTH 1 /* LINEOUTL_ENA_OUTP */
-#define WM8904_LINEOUTL_ENA_DLY 0x0020 /* LINEOUTL_ENA_DLY */
-#define WM8904_LINEOUTL_ENA_DLY_MASK 0x0020 /* LINEOUTL_ENA_DLY */
-#define WM8904_LINEOUTL_ENA_DLY_SHIFT 5 /* LINEOUTL_ENA_DLY */
-#define WM8904_LINEOUTL_ENA_DLY_WIDTH 1 /* LINEOUTL_ENA_DLY */
-#define WM8904_LINEOUTL_ENA 0x0010 /* LINEOUTL_ENA */
-#define WM8904_LINEOUTL_ENA_MASK 0x0010 /* LINEOUTL_ENA */
-#define WM8904_LINEOUTL_ENA_SHIFT 4 /* LINEOUTL_ENA */
-#define WM8904_LINEOUTL_ENA_WIDTH 1 /* LINEOUTL_ENA */
-#define WM8904_LINEOUTR_RMV_SHORT 0x0008 /* LINEOUTR_RMV_SHORT */
-#define WM8904_LINEOUTR_RMV_SHORT_MASK 0x0008 /* LINEOUTR_RMV_SHORT */
-#define WM8904_LINEOUTR_RMV_SHORT_SHIFT 3 /* LINEOUTR_RMV_SHORT */
-#define WM8904_LINEOUTR_RMV_SHORT_WIDTH 1 /* LINEOUTR_RMV_SHORT */
-#define WM8904_LINEOUTR_ENA_OUTP 0x0004 /* LINEOUTR_ENA_OUTP */
-#define WM8904_LINEOUTR_ENA_OUTP_MASK 0x0004 /* LINEOUTR_ENA_OUTP */
-#define WM8904_LINEOUTR_ENA_OUTP_SHIFT 2 /* LINEOUTR_ENA_OUTP */
-#define WM8904_LINEOUTR_ENA_OUTP_WIDTH 1 /* LINEOUTR_ENA_OUTP */
-#define WM8904_LINEOUTR_ENA_DLY 0x0002 /* LINEOUTR_ENA_DLY */
-#define WM8904_LINEOUTR_ENA_DLY_MASK 0x0002 /* LINEOUTR_ENA_DLY */
-#define WM8904_LINEOUTR_ENA_DLY_SHIFT 1 /* LINEOUTR_ENA_DLY */
-#define WM8904_LINEOUTR_ENA_DLY_WIDTH 1 /* LINEOUTR_ENA_DLY */
-#define WM8904_LINEOUTR_ENA 0x0001 /* LINEOUTR_ENA */
-#define WM8904_LINEOUTR_ENA_MASK 0x0001 /* LINEOUTR_ENA */
-#define WM8904_LINEOUTR_ENA_SHIFT 0 /* LINEOUTR_ENA */
-#define WM8904_LINEOUTR_ENA_WIDTH 1 /* LINEOUTR_ENA */
-
-/*
- * R98 (0x62) - Charge Pump 0
- */
-#define WM8904_CP_ENA 0x0001 /* CP_ENA */
-#define WM8904_CP_ENA_MASK 0x0001 /* CP_ENA */
-#define WM8904_CP_ENA_SHIFT 0 /* CP_ENA */
-#define WM8904_CP_ENA_WIDTH 1 /* CP_ENA */
-
-/*
- * R104 (0x68) - Class W 0
- */
-#define WM8904_CP_DYN_PWR 0x0001 /* CP_DYN_PWR */
-#define WM8904_CP_DYN_PWR_MASK 0x0001 /* CP_DYN_PWR */
-#define WM8904_CP_DYN_PWR_SHIFT 0 /* CP_DYN_PWR */
-#define WM8904_CP_DYN_PWR_WIDTH 1 /* CP_DYN_PWR */
-
-/*
- * R108 (0x6C) - Write Sequencer 0
- */
-#define WM8904_WSEQ_ENA 0x0100 /* WSEQ_ENA */
-#define WM8904_WSEQ_ENA_MASK 0x0100 /* WSEQ_ENA */
-#define WM8904_WSEQ_ENA_SHIFT 8 /* WSEQ_ENA */
-#define WM8904_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
-#define WM8904_WSEQ_WRITE_INDEX_MASK 0x001F /* WSEQ_WRITE_INDEX - [4:0] */
-#define WM8904_WSEQ_WRITE_INDEX_SHIFT 0 /* WSEQ_WRITE_INDEX - [4:0] */
-#define WM8904_WSEQ_WRITE_INDEX_WIDTH 5 /* WSEQ_WRITE_INDEX - [4:0] */
-
-/*
- * R109 (0x6D) - Write Sequencer 1
- */
-#define WM8904_WSEQ_DATA_WIDTH_MASK 0x7000 /* WSEQ_DATA_WIDTH - [14:12] */
-#define WM8904_WSEQ_DATA_WIDTH_SHIFT 12 /* WSEQ_DATA_WIDTH - [14:12] */
-#define WM8904_WSEQ_DATA_WIDTH_WIDTH 3 /* WSEQ_DATA_WIDTH - [14:12] */
-#define WM8904_WSEQ_DATA_START_MASK 0x0F00 /* WSEQ_DATA_START - [11:8] */
-#define WM8904_WSEQ_DATA_START_SHIFT 8 /* WSEQ_DATA_START - [11:8] */
-#define WM8904_WSEQ_DATA_START_WIDTH 4 /* WSEQ_DATA_START - [11:8] */
-#define WM8904_WSEQ_ADDR_MASK 0x00FF /* WSEQ_ADDR - [7:0] */
-#define WM8904_WSEQ_ADDR_SHIFT 0 /* WSEQ_ADDR - [7:0] */
-#define WM8904_WSEQ_ADDR_WIDTH 8 /* WSEQ_ADDR - [7:0] */
-
-/*
- * R110 (0x6E) - Write Sequencer 2
- */
-#define WM8904_WSEQ_EOS 0x4000 /* WSEQ_EOS */
-#define WM8904_WSEQ_EOS_MASK 0x4000 /* WSEQ_EOS */
-#define WM8904_WSEQ_EOS_SHIFT 14 /* WSEQ_EOS */
-#define WM8904_WSEQ_EOS_WIDTH 1 /* WSEQ_EOS */
-#define WM8904_WSEQ_DELAY_MASK 0x0F00 /* WSEQ_DELAY - [11:8] */
-#define WM8904_WSEQ_DELAY_SHIFT 8 /* WSEQ_DELAY - [11:8] */
-#define WM8904_WSEQ_DELAY_WIDTH 4 /* WSEQ_DELAY - [11:8] */
-#define WM8904_WSEQ_DATA_MASK 0x00FF /* WSEQ_DATA - [7:0] */
-#define WM8904_WSEQ_DATA_SHIFT 0 /* WSEQ_DATA - [7:0] */
-#define WM8904_WSEQ_DATA_WIDTH 8 /* WSEQ_DATA - [7:0] */
-
-/*
- * R111 (0x6F) - Write Sequencer 3
- */
-#define WM8904_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
-#define WM8904_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
-#define WM8904_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
-#define WM8904_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
-#define WM8904_WSEQ_START 0x0100 /* WSEQ_START */
-#define WM8904_WSEQ_START_MASK 0x0100 /* WSEQ_START */
-#define WM8904_WSEQ_START_SHIFT 8 /* WSEQ_START */
-#define WM8904_WSEQ_START_WIDTH 1 /* WSEQ_START */
-#define WM8904_WSEQ_START_INDEX_MASK 0x003F /* WSEQ_START_INDEX - [5:0] */
-#define WM8904_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [5:0] */
-#define WM8904_WSEQ_START_INDEX_WIDTH 6 /* WSEQ_START_INDEX - [5:0] */
-
-/*
- * R112 (0x70) - Write Sequencer 4
- */
-#define WM8904_WSEQ_CURRENT_INDEX_MASK 0x03F0 /* WSEQ_CURRENT_INDEX - [9:4] */
-#define WM8904_WSEQ_CURRENT_INDEX_SHIFT 4 /* WSEQ_CURRENT_INDEX - [9:4] */
-#define WM8904_WSEQ_CURRENT_INDEX_WIDTH 6 /* WSEQ_CURRENT_INDEX - [9:4] */
-#define WM8904_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
-#define WM8904_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
-#define WM8904_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
-#define WM8904_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
-
-/*
- * R116 (0x74) - FLL Control 1
- */
-#define WM8904_FLL_FRACN_ENA 0x0004 /* FLL_FRACN_ENA */
-#define WM8904_FLL_FRACN_ENA_MASK 0x0004 /* FLL_FRACN_ENA */
-#define WM8904_FLL_FRACN_ENA_SHIFT 2 /* FLL_FRACN_ENA */
-#define WM8904_FLL_FRACN_ENA_WIDTH 1 /* FLL_FRACN_ENA */
-#define WM8904_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */
-#define WM8904_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */
-#define WM8904_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */
-#define WM8904_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */
-#define WM8904_FLL_ENA 0x0001 /* FLL_ENA */
-#define WM8904_FLL_ENA_MASK 0x0001 /* FLL_ENA */
-#define WM8904_FLL_ENA_SHIFT 0 /* FLL_ENA */
-#define WM8904_FLL_ENA_WIDTH 1 /* FLL_ENA */
-
-/*
- * R117 (0x75) - FLL Control 2
- */
-#define WM8904_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */
-#define WM8904_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */
-#define WM8904_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */
-#define WM8904_FLL_CTRL_RATE_MASK 0x0070 /* FLL_CTRL_RATE - [6:4] */
-#define WM8904_FLL_CTRL_RATE_SHIFT 4 /* FLL_CTRL_RATE - [6:4] */
-#define WM8904_FLL_CTRL_RATE_WIDTH 3 /* FLL_CTRL_RATE - [6:4] */
-#define WM8904_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
-#define WM8904_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
-#define WM8904_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
-
-/*
- * R118 (0x76) - FLL Control 3
- */
-#define WM8904_FLL_K_MASK 0xFFFF /* FLL_K - [15:0] */
-#define WM8904_FLL_K_SHIFT 0 /* FLL_K - [15:0] */
-#define WM8904_FLL_K_WIDTH 16 /* FLL_K - [15:0] */
-
-/*
- * R119 (0x77) - FLL Control 4
- */
-#define WM8904_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */
-#define WM8904_FLL_N_SHIFT 5 /* FLL_N - [14:5] */
-#define WM8904_FLL_N_WIDTH 10 /* FLL_N - [14:5] */
-#define WM8904_FLL_GAIN_MASK 0x000F /* FLL_GAIN - [3:0] */
-#define WM8904_FLL_GAIN_SHIFT 0 /* FLL_GAIN - [3:0] */
-#define WM8904_FLL_GAIN_WIDTH 4 /* FLL_GAIN - [3:0] */
-
-/*
- * R120 (0x78) - FLL Control 5
- */
-#define WM8904_FLL_CLK_REF_DIV_MASK 0x0018 /* FLL_CLK_REF_DIV - [4:3] */
-#define WM8904_FLL_CLK_REF_DIV_SHIFT 3 /* FLL_CLK_REF_DIV - [4:3] */
-#define WM8904_FLL_CLK_REF_DIV_WIDTH 2 /* FLL_CLK_REF_DIV - [4:3] */
-#define WM8904_FLL_CLK_REF_SRC_MASK 0x0003 /* FLL_CLK_REF_SRC - [1:0] */
-#define WM8904_FLL_CLK_REF_SRC_SHIFT 0 /* FLL_CLK_REF_SRC - [1:0] */
-#define WM8904_FLL_CLK_REF_SRC_WIDTH 2 /* FLL_CLK_REF_SRC - [1:0] */
-
-/*
- * R126 (0x7E) - Digital Pulls
- */
-#define WM8904_MCLK_PU 0x0080 /* MCLK_PU */
-#define WM8904_MCLK_PU_MASK 0x0080 /* MCLK_PU */
-#define WM8904_MCLK_PU_SHIFT 7 /* MCLK_PU */
-#define WM8904_MCLK_PU_WIDTH 1 /* MCLK_PU */
-#define WM8904_MCLK_PD 0x0040 /* MCLK_PD */
-#define WM8904_MCLK_PD_MASK 0x0040 /* MCLK_PD */
-#define WM8904_MCLK_PD_SHIFT 6 /* MCLK_PD */
-#define WM8904_MCLK_PD_WIDTH 1 /* MCLK_PD */
-#define WM8904_DACDAT_PU 0x0020 /* DACDAT_PU */
-#define WM8904_DACDAT_PU_MASK 0x0020 /* DACDAT_PU */
-#define WM8904_DACDAT_PU_SHIFT 5 /* DACDAT_PU */
-#define WM8904_DACDAT_PU_WIDTH 1 /* DACDAT_PU */
-#define WM8904_DACDAT_PD 0x0010 /* DACDAT_PD */
-#define WM8904_DACDAT_PD_MASK 0x0010 /* DACDAT_PD */
-#define WM8904_DACDAT_PD_SHIFT 4 /* DACDAT_PD */
-#define WM8904_DACDAT_PD_WIDTH 1 /* DACDAT_PD */
-#define WM8904_LRCLK_PU 0x0008 /* LRCLK_PU */
-#define WM8904_LRCLK_PU_MASK 0x0008 /* LRCLK_PU */
-#define WM8904_LRCLK_PU_SHIFT 3 /* LRCLK_PU */
-#define WM8904_LRCLK_PU_WIDTH 1 /* LRCLK_PU */
-#define WM8904_LRCLK_PD 0x0004 /* LRCLK_PD */
-#define WM8904_LRCLK_PD_MASK 0x0004 /* LRCLK_PD */
-#define WM8904_LRCLK_PD_SHIFT 2 /* LRCLK_PD */
-#define WM8904_LRCLK_PD_WIDTH 1 /* LRCLK_PD */
-#define WM8904_BCLK_PU 0x0002 /* BCLK_PU */
-#define WM8904_BCLK_PU_MASK 0x0002 /* BCLK_PU */
-#define WM8904_BCLK_PU_SHIFT 1 /* BCLK_PU */
-#define WM8904_BCLK_PU_WIDTH 1 /* BCLK_PU */
-#define WM8904_BCLK_PD 0x0001 /* BCLK_PD */
-#define WM8904_BCLK_PD_MASK 0x0001 /* BCLK_PD */
-#define WM8904_BCLK_PD_SHIFT 0 /* BCLK_PD */
-#define WM8904_BCLK_PD_WIDTH 1 /* BCLK_PD */
-
-/*
- * R127 (0x7F) - Interrupt Status
- */
-#define WM8904_IRQ 0x0400 /* IRQ */
-#define WM8904_IRQ_MASK 0x0400 /* IRQ */
-#define WM8904_IRQ_SHIFT 10 /* IRQ */
-#define WM8904_IRQ_WIDTH 1 /* IRQ */
-#define WM8904_GPIO_BCLK_EINT 0x0200 /* GPIO_BCLK_EINT */
-#define WM8904_GPIO_BCLK_EINT_MASK 0x0200 /* GPIO_BCLK_EINT */
-#define WM8904_GPIO_BCLK_EINT_SHIFT 9 /* GPIO_BCLK_EINT */
-#define WM8904_GPIO_BCLK_EINT_WIDTH 1 /* GPIO_BCLK_EINT */
-#define WM8904_WSEQ_EINT 0x0100 /* WSEQ_EINT */
-#define WM8904_WSEQ_EINT_MASK 0x0100 /* WSEQ_EINT */
-#define WM8904_WSEQ_EINT_SHIFT 8 /* WSEQ_EINT */
-#define WM8904_WSEQ_EINT_WIDTH 1 /* WSEQ_EINT */
-#define WM8904_GPIO3_EINT 0x0080 /* GPIO3_EINT */
-#define WM8904_GPIO3_EINT_MASK 0x0080 /* GPIO3_EINT */
-#define WM8904_GPIO3_EINT_SHIFT 7 /* GPIO3_EINT */
-#define WM8904_GPIO3_EINT_WIDTH 1 /* GPIO3_EINT */
-#define WM8904_GPIO2_EINT 0x0040 /* GPIO2_EINT */
-#define WM8904_GPIO2_EINT_MASK 0x0040 /* GPIO2_EINT */
-#define WM8904_GPIO2_EINT_SHIFT 6 /* GPIO2_EINT */
-#define WM8904_GPIO2_EINT_WIDTH 1 /* GPIO2_EINT */
-#define WM8904_GPIO1_EINT 0x0020 /* GPIO1_EINT */
-#define WM8904_GPIO1_EINT_MASK 0x0020 /* GPIO1_EINT */
-#define WM8904_GPIO1_EINT_SHIFT 5 /* GPIO1_EINT */
-#define WM8904_GPIO1_EINT_WIDTH 1 /* GPIO1_EINT */
-#define WM8904_GPI8_EINT 0x0010 /* GPI8_EINT */
-#define WM8904_GPI8_EINT_MASK 0x0010 /* GPI8_EINT */
-#define WM8904_GPI8_EINT_SHIFT 4 /* GPI8_EINT */
-#define WM8904_GPI8_EINT_WIDTH 1 /* GPI8_EINT */
-#define WM8904_GPI7_EINT 0x0008 /* GPI7_EINT */
-#define WM8904_GPI7_EINT_MASK 0x0008 /* GPI7_EINT */
-#define WM8904_GPI7_EINT_SHIFT 3 /* GPI7_EINT */
-#define WM8904_GPI7_EINT_WIDTH 1 /* GPI7_EINT */
-#define WM8904_FLL_LOCK_EINT 0x0004 /* FLL_LOCK_EINT */
-#define WM8904_FLL_LOCK_EINT_MASK 0x0004 /* FLL_LOCK_EINT */
-#define WM8904_FLL_LOCK_EINT_SHIFT 2 /* FLL_LOCK_EINT */
-#define WM8904_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */
-#define WM8904_MIC_SHRT_EINT 0x0002 /* MIC_SHRT_EINT */
-#define WM8904_MIC_SHRT_EINT_MASK 0x0002 /* MIC_SHRT_EINT */
-#define WM8904_MIC_SHRT_EINT_SHIFT 1 /* MIC_SHRT_EINT */
-#define WM8904_MIC_SHRT_EINT_WIDTH 1 /* MIC_SHRT_EINT */
-#define WM8904_MIC_DET_EINT 0x0001 /* MIC_DET_EINT */
-#define WM8904_MIC_DET_EINT_MASK 0x0001 /* MIC_DET_EINT */
-#define WM8904_MIC_DET_EINT_SHIFT 0 /* MIC_DET_EINT */
-#define WM8904_MIC_DET_EINT_WIDTH 1 /* MIC_DET_EINT */
-
-/*
- * R128 (0x80) - Interrupt Status Mask
- */
-#define WM8904_IM_GPIO_BCLK_EINT 0x0200 /* IM_GPIO_BCLK_EINT */
-#define WM8904_IM_GPIO_BCLK_EINT_MASK 0x0200 /* IM_GPIO_BCLK_EINT */
-#define WM8904_IM_GPIO_BCLK_EINT_SHIFT 9 /* IM_GPIO_BCLK_EINT */
-#define WM8904_IM_GPIO_BCLK_EINT_WIDTH 1 /* IM_GPIO_BCLK_EINT */
-#define WM8904_IM_WSEQ_EINT 0x0100 /* IM_WSEQ_EINT */
-#define WM8904_IM_WSEQ_EINT_MASK 0x0100 /* IM_WSEQ_EINT */
-#define WM8904_IM_WSEQ_EINT_SHIFT 8 /* IM_WSEQ_EINT */
-#define WM8904_IM_WSEQ_EINT_WIDTH 1 /* IM_WSEQ_EINT */
-#define WM8904_IM_GPIO3_EINT 0x0080 /* IM_GPIO3_EINT */
-#define WM8904_IM_GPIO3_EINT_MASK 0x0080 /* IM_GPIO3_EINT */
-#define WM8904_IM_GPIO3_EINT_SHIFT 7 /* IM_GPIO3_EINT */
-#define WM8904_IM_GPIO3_EINT_WIDTH 1 /* IM_GPIO3_EINT */
-#define WM8904_IM_GPIO2_EINT 0x0040 /* IM_GPIO2_EINT */
-#define WM8904_IM_GPIO2_EINT_MASK 0x0040 /* IM_GPIO2_EINT */
-#define WM8904_IM_GPIO2_EINT_SHIFT 6 /* IM_GPIO2_EINT */
-#define WM8904_IM_GPIO2_EINT_WIDTH 1 /* IM_GPIO2_EINT */
-#define WM8904_IM_GPIO1_EINT 0x0020 /* IM_GPIO1_EINT */
-#define WM8904_IM_GPIO1_EINT_MASK 0x0020 /* IM_GPIO1_EINT */
-#define WM8904_IM_GPIO1_EINT_SHIFT 5 /* IM_GPIO1_EINT */
-#define WM8904_IM_GPIO1_EINT_WIDTH 1 /* IM_GPIO1_EINT */
-#define WM8904_IM_GPI8_EINT 0x0010 /* IM_GPI8_EINT */
-#define WM8904_IM_GPI8_EINT_MASK 0x0010 /* IM_GPI8_EINT */
-#define WM8904_IM_GPI8_EINT_SHIFT 4 /* IM_GPI8_EINT */
-#define WM8904_IM_GPI8_EINT_WIDTH 1 /* IM_GPI8_EINT */
-#define WM8904_IM_GPI7_EINT 0x0008 /* IM_GPI7_EINT */
-#define WM8904_IM_GPI7_EINT_MASK 0x0008 /* IM_GPI7_EINT */
-#define WM8904_IM_GPI7_EINT_SHIFT 3 /* IM_GPI7_EINT */
-#define WM8904_IM_GPI7_EINT_WIDTH 1 /* IM_GPI7_EINT */
-#define WM8904_IM_FLL_LOCK_EINT 0x0004 /* IM_FLL_LOCK_EINT */
-#define WM8904_IM_FLL_LOCK_EINT_MASK 0x0004 /* IM_FLL_LOCK_EINT */
-#define WM8904_IM_FLL_LOCK_EINT_SHIFT 2 /* IM_FLL_LOCK_EINT */
-#define WM8904_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */
-#define WM8904_IM_MIC_SHRT_EINT 0x0002 /* IM_MIC_SHRT_EINT */
-#define WM8904_IM_MIC_SHRT_EINT_MASK 0x0002 /* IM_MIC_SHRT_EINT */
-#define WM8904_IM_MIC_SHRT_EINT_SHIFT 1 /* IM_MIC_SHRT_EINT */
-#define WM8904_IM_MIC_SHRT_EINT_WIDTH 1 /* IM_MIC_SHRT_EINT */
-#define WM8904_IM_MIC_DET_EINT 0x0001 /* IM_MIC_DET_EINT */
-#define WM8904_IM_MIC_DET_EINT_MASK 0x0001 /* IM_MIC_DET_EINT */
-#define WM8904_IM_MIC_DET_EINT_SHIFT 0 /* IM_MIC_DET_EINT */
-#define WM8904_IM_MIC_DET_EINT_WIDTH 1 /* IM_MIC_DET_EINT */
-
-/*
- * R129 (0x81) - Interrupt Polarity
- */
-#define WM8904_GPIO_BCLK_EINT_POL 0x0200 /* GPIO_BCLK_EINT_POL */
-#define WM8904_GPIO_BCLK_EINT_POL_MASK 0x0200 /* GPIO_BCLK_EINT_POL */
-#define WM8904_GPIO_BCLK_EINT_POL_SHIFT 9 /* GPIO_BCLK_EINT_POL */
-#define WM8904_GPIO_BCLK_EINT_POL_WIDTH 1 /* GPIO_BCLK_EINT_POL */
-#define WM8904_WSEQ_EINT_POL 0x0100 /* WSEQ_EINT_POL */
-#define WM8904_WSEQ_EINT_POL_MASK 0x0100 /* WSEQ_EINT_POL */
-#define WM8904_WSEQ_EINT_POL_SHIFT 8 /* WSEQ_EINT_POL */
-#define WM8904_WSEQ_EINT_POL_WIDTH 1 /* WSEQ_EINT_POL */
-#define WM8904_GPIO3_EINT_POL 0x0080 /* GPIO3_EINT_POL */
-#define WM8904_GPIO3_EINT_POL_MASK 0x0080 /* GPIO3_EINT_POL */
-#define WM8904_GPIO3_EINT_POL_SHIFT 7 /* GPIO3_EINT_POL */
-#define WM8904_GPIO3_EINT_POL_WIDTH 1 /* GPIO3_EINT_POL */
-#define WM8904_GPIO2_EINT_POL 0x0040 /* GPIO2_EINT_POL */
-#define WM8904_GPIO2_EINT_POL_MASK 0x0040 /* GPIO2_EINT_POL */
-#define WM8904_GPIO2_EINT_POL_SHIFT 6 /* GPIO2_EINT_POL */
-#define WM8904_GPIO2_EINT_POL_WIDTH 1 /* GPIO2_EINT_POL */
-#define WM8904_GPIO1_EINT_POL 0x0020 /* GPIO1_EINT_POL */
-#define WM8904_GPIO1_EINT_POL_MASK 0x0020 /* GPIO1_EINT_POL */
-#define WM8904_GPIO1_EINT_POL_SHIFT 5 /* GPIO1_EINT_POL */
-#define WM8904_GPIO1_EINT_POL_WIDTH 1 /* GPIO1_EINT_POL */
-#define WM8904_GPI8_EINT_POL 0x0010 /* GPI8_EINT_POL */
-#define WM8904_GPI8_EINT_POL_MASK 0x0010 /* GPI8_EINT_POL */
-#define WM8904_GPI8_EINT_POL_SHIFT 4 /* GPI8_EINT_POL */
-#define WM8904_GPI8_EINT_POL_WIDTH 1 /* GPI8_EINT_POL */
-#define WM8904_GPI7_EINT_POL 0x0008 /* GPI7_EINT_POL */
-#define WM8904_GPI7_EINT_POL_MASK 0x0008 /* GPI7_EINT_POL */
-#define WM8904_GPI7_EINT_POL_SHIFT 3 /* GPI7_EINT_POL */
-#define WM8904_GPI7_EINT_POL_WIDTH 1 /* GPI7_EINT_POL */
-#define WM8904_FLL_LOCK_EINT_POL 0x0004 /* FLL_LOCK_EINT_POL */
-#define WM8904_FLL_LOCK_EINT_POL_MASK 0x0004 /* FLL_LOCK_EINT_POL */
-#define WM8904_FLL_LOCK_EINT_POL_SHIFT 2 /* FLL_LOCK_EINT_POL */
-#define WM8904_FLL_LOCK_EINT_POL_WIDTH 1 /* FLL_LOCK_EINT_POL */
-#define WM8904_MIC_SHRT_EINT_POL 0x0002 /* MIC_SHRT_EINT_POL */
-#define WM8904_MIC_SHRT_EINT_POL_MASK 0x0002 /* MIC_SHRT_EINT_POL */
-#define WM8904_MIC_SHRT_EINT_POL_SHIFT 1 /* MIC_SHRT_EINT_POL */
-#define WM8904_MIC_SHRT_EINT_POL_WIDTH 1 /* MIC_SHRT_EINT_POL */
-#define WM8904_MIC_DET_EINT_POL 0x0001 /* MIC_DET_EINT_POL */
-#define WM8904_MIC_DET_EINT_POL_MASK 0x0001 /* MIC_DET_EINT_POL */
-#define WM8904_MIC_DET_EINT_POL_SHIFT 0 /* MIC_DET_EINT_POL */
-#define WM8904_MIC_DET_EINT_POL_WIDTH 1 /* MIC_DET_EINT_POL */
-
-/*
- * R130 (0x82) - Interrupt Debounce
- */
-#define WM8904_GPIO_BCLK_EINT_DB 0x0200 /* GPIO_BCLK_EINT_DB */
-#define WM8904_GPIO_BCLK_EINT_DB_MASK 0x0200 /* GPIO_BCLK_EINT_DB */
-#define WM8904_GPIO_BCLK_EINT_DB_SHIFT 9 /* GPIO_BCLK_EINT_DB */
-#define WM8904_GPIO_BCLK_EINT_DB_WIDTH 1 /* GPIO_BCLK_EINT_DB */
-#define WM8904_WSEQ_EINT_DB 0x0100 /* WSEQ_EINT_DB */
-#define WM8904_WSEQ_EINT_DB_MASK 0x0100 /* WSEQ_EINT_DB */
-#define WM8904_WSEQ_EINT_DB_SHIFT 8 /* WSEQ_EINT_DB */
-#define WM8904_WSEQ_EINT_DB_WIDTH 1 /* WSEQ_EINT_DB */
-#define WM8904_GPIO3_EINT_DB 0x0080 /* GPIO3_EINT_DB */
-#define WM8904_GPIO3_EINT_DB_MASK 0x0080 /* GPIO3_EINT_DB */
-#define WM8904_GPIO3_EINT_DB_SHIFT 7 /* GPIO3_EINT_DB */
-#define WM8904_GPIO3_EINT_DB_WIDTH 1 /* GPIO3_EINT_DB */
-#define WM8904_GPIO2_EINT_DB 0x0040 /* GPIO2_EINT_DB */
-#define WM8904_GPIO2_EINT_DB_MASK 0x0040 /* GPIO2_EINT_DB */
-#define WM8904_GPIO2_EINT_DB_SHIFT 6 /* GPIO2_EINT_DB */
-#define WM8904_GPIO2_EINT_DB_WIDTH 1 /* GPIO2_EINT_DB */
-#define WM8904_GPIO1_EINT_DB 0x0020 /* GPIO1_EINT_DB */
-#define WM8904_GPIO1_EINT_DB_MASK 0x0020 /* GPIO1_EINT_DB */
-#define WM8904_GPIO1_EINT_DB_SHIFT 5 /* GPIO1_EINT_DB */
-#define WM8904_GPIO1_EINT_DB_WIDTH 1 /* GPIO1_EINT_DB */
-#define WM8904_GPI8_EINT_DB 0x0010 /* GPI8_EINT_DB */
-#define WM8904_GPI8_EINT_DB_MASK 0x0010 /* GPI8_EINT_DB */
-#define WM8904_GPI8_EINT_DB_SHIFT 4 /* GPI8_EINT_DB */
-#define WM8904_GPI8_EINT_DB_WIDTH 1 /* GPI8_EINT_DB */
-#define WM8904_GPI7_EINT_DB 0x0008 /* GPI7_EINT_DB */
-#define WM8904_GPI7_EINT_DB_MASK 0x0008 /* GPI7_EINT_DB */
-#define WM8904_GPI7_EINT_DB_SHIFT 3 /* GPI7_EINT_DB */
-#define WM8904_GPI7_EINT_DB_WIDTH 1 /* GPI7_EINT_DB */
-#define WM8904_FLL_LOCK_EINT_DB 0x0004 /* FLL_LOCK_EINT_DB */
-#define WM8904_FLL_LOCK_EINT_DB_MASK 0x0004 /* FLL_LOCK_EINT_DB */
-#define WM8904_FLL_LOCK_EINT_DB_SHIFT 2 /* FLL_LOCK_EINT_DB */
-#define WM8904_FLL_LOCK_EINT_DB_WIDTH 1 /* FLL_LOCK_EINT_DB */
-#define WM8904_MIC_SHRT_EINT_DB 0x0002 /* MIC_SHRT_EINT_DB */
-#define WM8904_MIC_SHRT_EINT_DB_MASK 0x0002 /* MIC_SHRT_EINT_DB */
-#define WM8904_MIC_SHRT_EINT_DB_SHIFT 1 /* MIC_SHRT_EINT_DB */
-#define WM8904_MIC_SHRT_EINT_DB_WIDTH 1 /* MIC_SHRT_EINT_DB */
-#define WM8904_MIC_DET_EINT_DB 0x0001 /* MIC_DET_EINT_DB */
-#define WM8904_MIC_DET_EINT_DB_MASK 0x0001 /* MIC_DET_EINT_DB */
-#define WM8904_MIC_DET_EINT_DB_SHIFT 0 /* MIC_DET_EINT_DB */
-#define WM8904_MIC_DET_EINT_DB_WIDTH 1 /* MIC_DET_EINT_DB */
-
-/*
- * R134 (0x86) - EQ1
- */
-#define WM8904_EQ_ENA 0x0001 /* EQ_ENA */
-#define WM8904_EQ_ENA_MASK 0x0001 /* EQ_ENA */
-#define WM8904_EQ_ENA_SHIFT 0 /* EQ_ENA */
-#define WM8904_EQ_ENA_WIDTH 1 /* EQ_ENA */
-
-/*
- * R135 (0x87) - EQ2
- */
-#define WM8904_EQ_B1_GAIN_MASK 0x001F /* EQ_B1_GAIN - [4:0] */
-#define WM8904_EQ_B1_GAIN_SHIFT 0 /* EQ_B1_GAIN - [4:0] */
-#define WM8904_EQ_B1_GAIN_WIDTH 5 /* EQ_B1_GAIN - [4:0] */
-
-/*
- * R136 (0x88) - EQ3
- */
-#define WM8904_EQ_B2_GAIN_MASK 0x001F /* EQ_B2_GAIN - [4:0] */
-#define WM8904_EQ_B2_GAIN_SHIFT 0 /* EQ_B2_GAIN - [4:0] */
-#define WM8904_EQ_B2_GAIN_WIDTH 5 /* EQ_B2_GAIN - [4:0] */
-
-/*
- * R137 (0x89) - EQ4
- */
-#define WM8904_EQ_B3_GAIN_MASK 0x001F /* EQ_B3_GAIN - [4:0] */
-#define WM8904_EQ_B3_GAIN_SHIFT 0 /* EQ_B3_GAIN - [4:0] */
-#define WM8904_EQ_B3_GAIN_WIDTH 5 /* EQ_B3_GAIN - [4:0] */
-
-/*
- * R138 (0x8A) - EQ5
- */
-#define WM8904_EQ_B4_GAIN_MASK 0x001F /* EQ_B4_GAIN - [4:0] */
-#define WM8904_EQ_B4_GAIN_SHIFT 0 /* EQ_B4_GAIN - [4:0] */
-#define WM8904_EQ_B4_GAIN_WIDTH 5 /* EQ_B4_GAIN - [4:0] */
-
-/*
- * R139 (0x8B) - EQ6
- */
-#define WM8904_EQ_B5_GAIN_MASK 0x001F /* EQ_B5_GAIN - [4:0] */
-#define WM8904_EQ_B5_GAIN_SHIFT 0 /* EQ_B5_GAIN - [4:0] */
-#define WM8904_EQ_B5_GAIN_WIDTH 5 /* EQ_B5_GAIN - [4:0] */
-
-/*
- * R140 (0x8C) - EQ7
- */
-#define WM8904_EQ_B1_A_MASK 0xFFFF /* EQ_B1_A - [15:0] */
-#define WM8904_EQ_B1_A_SHIFT 0 /* EQ_B1_A - [15:0] */
-#define WM8904_EQ_B1_A_WIDTH 16 /* EQ_B1_A - [15:0] */
-
-/*
- * R141 (0x8D) - EQ8
- */
-#define WM8904_EQ_B1_B_MASK 0xFFFF /* EQ_B1_B - [15:0] */
-#define WM8904_EQ_B1_B_SHIFT 0 /* EQ_B1_B - [15:0] */
-#define WM8904_EQ_B1_B_WIDTH 16 /* EQ_B1_B - [15:0] */
-
-/*
- * R142 (0x8E) - EQ9
- */
-#define WM8904_EQ_B1_PG_MASK 0xFFFF /* EQ_B1_PG - [15:0] */
-#define WM8904_EQ_B1_PG_SHIFT 0 /* EQ_B1_PG - [15:0] */
-#define WM8904_EQ_B1_PG_WIDTH 16 /* EQ_B1_PG - [15:0] */
-
-/*
- * R143 (0x8F) - EQ10
- */
-#define WM8904_EQ_B2_A_MASK 0xFFFF /* EQ_B2_A - [15:0] */
-#define WM8904_EQ_B2_A_SHIFT 0 /* EQ_B2_A - [15:0] */
-#define WM8904_EQ_B2_A_WIDTH 16 /* EQ_B2_A - [15:0] */
-
-/*
- * R144 (0x90) - EQ11
- */
-#define WM8904_EQ_B2_B_MASK 0xFFFF /* EQ_B2_B - [15:0] */
-#define WM8904_EQ_B2_B_SHIFT 0 /* EQ_B2_B - [15:0] */
-#define WM8904_EQ_B2_B_WIDTH 16 /* EQ_B2_B - [15:0] */
-
-/*
- * R145 (0x91) - EQ12
- */
-#define WM8904_EQ_B2_C_MASK 0xFFFF /* EQ_B2_C - [15:0] */
-#define WM8904_EQ_B2_C_SHIFT 0 /* EQ_B2_C - [15:0] */
-#define WM8904_EQ_B2_C_WIDTH 16 /* EQ_B2_C - [15:0] */
-
-/*
- * R146 (0x92) - EQ13
- */
-#define WM8904_EQ_B2_PG_MASK 0xFFFF /* EQ_B2_PG - [15:0] */
-#define WM8904_EQ_B2_PG_SHIFT 0 /* EQ_B2_PG - [15:0] */
-#define WM8904_EQ_B2_PG_WIDTH 16 /* EQ_B2_PG - [15:0] */
-
-/*
- * R147 (0x93) - EQ14
- */
-#define WM8904_EQ_B3_A_MASK 0xFFFF /* EQ_B3_A - [15:0] */
-#define WM8904_EQ_B3_A_SHIFT 0 /* EQ_B3_A - [15:0] */
-#define WM8904_EQ_B3_A_WIDTH 16 /* EQ_B3_A - [15:0] */
-
-/*
- * R148 (0x94) - EQ15
- */
-#define WM8904_EQ_B3_B_MASK 0xFFFF /* EQ_B3_B - [15:0] */
-#define WM8904_EQ_B3_B_SHIFT 0 /* EQ_B3_B - [15:0] */
-#define WM8904_EQ_B3_B_WIDTH 16 /* EQ_B3_B - [15:0] */
-
-/*
- * R149 (0x95) - EQ16
- */
-#define WM8904_EQ_B3_C_MASK 0xFFFF /* EQ_B3_C - [15:0] */
-#define WM8904_EQ_B3_C_SHIFT 0 /* EQ_B3_C - [15:0] */
-#define WM8904_EQ_B3_C_WIDTH 16 /* EQ_B3_C - [15:0] */
-
-/*
- * R150 (0x96) - EQ17
- */
-#define WM8904_EQ_B3_PG_MASK 0xFFFF /* EQ_B3_PG - [15:0] */
-#define WM8904_EQ_B3_PG_SHIFT 0 /* EQ_B3_PG - [15:0] */
-#define WM8904_EQ_B3_PG_WIDTH 16 /* EQ_B3_PG - [15:0] */
-
-/*
- * R151 (0x97) - EQ18
- */
-#define WM8904_EQ_B4_A_MASK 0xFFFF /* EQ_B4_A - [15:0] */
-#define WM8904_EQ_B4_A_SHIFT 0 /* EQ_B4_A - [15:0] */
-#define WM8904_EQ_B4_A_WIDTH 16 /* EQ_B4_A - [15:0] */
-
-/*
- * R152 (0x98) - EQ19
- */
-#define WM8904_EQ_B4_B_MASK 0xFFFF /* EQ_B4_B - [15:0] */
-#define WM8904_EQ_B4_B_SHIFT 0 /* EQ_B4_B - [15:0] */
-#define WM8904_EQ_B4_B_WIDTH 16 /* EQ_B4_B - [15:0] */
-
-/*
- * R153 (0x99) - EQ20
- */
-#define WM8904_EQ_B4_C_MASK 0xFFFF /* EQ_B4_C - [15:0] */
-#define WM8904_EQ_B4_C_SHIFT 0 /* EQ_B4_C - [15:0] */
-#define WM8904_EQ_B4_C_WIDTH 16 /* EQ_B4_C - [15:0] */
-
-/*
- * R154 (0x9A) - EQ21
- */
-#define WM8904_EQ_B4_PG_MASK 0xFFFF /* EQ_B4_PG - [15:0] */
-#define WM8904_EQ_B4_PG_SHIFT 0 /* EQ_B4_PG - [15:0] */
-#define WM8904_EQ_B4_PG_WIDTH 16 /* EQ_B4_PG - [15:0] */
-
-/*
- * R155 (0x9B) - EQ22
- */
-#define WM8904_EQ_B5_A_MASK 0xFFFF /* EQ_B5_A - [15:0] */
-#define WM8904_EQ_B5_A_SHIFT 0 /* EQ_B5_A - [15:0] */
-#define WM8904_EQ_B5_A_WIDTH 16 /* EQ_B5_A - [15:0] */
-
-/*
- * R156 (0x9C) - EQ23
- */
-#define WM8904_EQ_B5_B_MASK 0xFFFF /* EQ_B5_B - [15:0] */
-#define WM8904_EQ_B5_B_SHIFT 0 /* EQ_B5_B - [15:0] */
-#define WM8904_EQ_B5_B_WIDTH 16 /* EQ_B5_B - [15:0] */
-
-/*
- * R157 (0x9D) - EQ24
- */
-#define WM8904_EQ_B5_PG_MASK 0xFFFF /* EQ_B5_PG - [15:0] */
-#define WM8904_EQ_B5_PG_SHIFT 0 /* EQ_B5_PG - [15:0] */
-#define WM8904_EQ_B5_PG_WIDTH 16 /* EQ_B5_PG - [15:0] */
-
-/*
- * R161 (0xA1) - Control Interface Test 1
- */
-#define WM8904_USER_KEY 0x0002 /* USER_KEY */
-#define WM8904_USER_KEY_MASK 0x0002 /* USER_KEY */
-#define WM8904_USER_KEY_SHIFT 1 /* USER_KEY */
-#define WM8904_USER_KEY_WIDTH 1 /* USER_KEY */
-
-/*
- * R198 (0xC6) - ADC Test 0
- */
-#define WM8904_ADC_128_OSR_TST_MODE 0x0004 /* ADC_128_OSR_TST_MODE */
-#define WM8904_ADC_128_OSR_TST_MODE_SHIFT 2 /* ADC_128_OSR_TST_MODE */
-#define WM8904_ADC_128_OSR_TST_MODE_WIDTH 1 /* ADC_128_OSR_TST_MODE */
-#define WM8904_ADC_BIASX1P5 0x0001 /* ADC_BIASX1P5 */
-#define WM8904_ADC_BIASX1P5_SHIFT 0 /* ADC_BIASX1P5 */
-#define WM8904_ADC_BIASX1P5_WIDTH 1 /* ADC_BIASX1P5 */
-
-/*
- * R204 (0xCC) - Analogue Output Bias 0
- */
-#define WM8904_PGA_BIAS_MASK 0x0070 /* PGA_BIAS - [6:4] */
-#define WM8904_PGA_BIAS_SHIFT 4 /* PGA_BIAS - [6:4] */
-#define WM8904_PGA_BIAS_WIDTH 3 /* PGA_BIAS - [6:4] */
-
-/*
- * R247 (0xF7) - FLL NCO Test 0
- */
-#define WM8904_FLL_FRC_NCO 0x0001 /* FLL_FRC_NCO */
-#define WM8904_FLL_FRC_NCO_MASK 0x0001 /* FLL_FRC_NCO */
-#define WM8904_FLL_FRC_NCO_SHIFT 0 /* FLL_FRC_NCO */
-#define WM8904_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */
-
-/*
- * R248 (0xF8) - FLL NCO Test 1
- */
-#define WM8904_FLL_FRC_NCO_VAL_MASK 0x003F /* FLL_FRC_NCO_VAL - [5:0] */
-#define WM8904_FLL_FRC_NCO_VAL_SHIFT 0 /* FLL_FRC_NCO_VAL - [5:0] */
-#define WM8904_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [5:0] */
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8940.c b/ANDROID_3.4.5/sound/soc/codecs/wm8940.c
deleted file mode 100644
index d2883aff..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8940.c
+++ /dev/null
@@ -1,809 +0,0 @@
-/*
- * wm8940.c -- WM8940 ALSA Soc Audio driver
- *
- * Author: Jonathan Cameron <jic23@cam.ac.uk>
- *
- * Based on wm8510.c
- * Copyright 2006 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood <lrg@slimlogic.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Not currently handled:
- * Notch filter control
- * AUXMode (inverting vs mixer)
- * No means to obtain current gain if alc enabled.
- * No use made of gpio
- * Fast VMID discharge for power down
- * Soft Start
- * DLR and ALR Swaps not enabled
- * Digital Sidetone not supported
- */
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "wm8940.h"
-
-struct wm8940_priv {
- unsigned int sysclk;
- enum snd_soc_control_type control_type;
-};
-
-static int wm8940_volatile_register(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- switch (reg) {
- case WM8940_SOFTRESET:
- return 1;
- default:
- return 0;
- }
-}
-
-static u16 wm8940_reg_defaults[] = {
- 0x8940, /* Soft Reset */
- 0x0000, /* Power 1 */
- 0x0000, /* Power 2 */
- 0x0000, /* Power 3 */
- 0x0010, /* Interface Control */
- 0x0000, /* Companding Control */
- 0x0140, /* Clock Control */
- 0x0000, /* Additional Controls */
- 0x0000, /* GPIO Control */
- 0x0002, /* Auto Increment Control */
- 0x0000, /* DAC Control */
- 0x00FF, /* DAC Volume */
- 0,
- 0,
- 0x0100, /* ADC Control */
- 0x00FF, /* ADC Volume */
- 0x0000, /* Notch Filter 1 Control 1 */
- 0x0000, /* Notch Filter 1 Control 2 */
- 0x0000, /* Notch Filter 2 Control 1 */
- 0x0000, /* Notch Filter 2 Control 2 */
- 0x0000, /* Notch Filter 3 Control 1 */
- 0x0000, /* Notch Filter 3 Control 2 */
- 0x0000, /* Notch Filter 4 Control 1 */
- 0x0000, /* Notch Filter 4 Control 2 */
- 0x0032, /* DAC Limit Control 1 */
- 0x0000, /* DAC Limit Control 2 */
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0x0038, /* ALC Control 1 */
- 0x000B, /* ALC Control 2 */
- 0x0032, /* ALC Control 3 */
- 0x0000, /* Noise Gate */
- 0x0041, /* PLLN */
- 0x000C, /* PLLK1 */
- 0x0093, /* PLLK2 */
- 0x00E9, /* PLLK3 */
- 0,
- 0,
- 0x0030, /* ALC Control 4 */
- 0,
- 0x0002, /* Input Control */
- 0x0050, /* PGA Gain */
- 0,
- 0x0002, /* ADC Boost Control */
- 0,
- 0x0002, /* Output Control */
- 0x0000, /* Speaker Mixer Control */
- 0,
- 0,
- 0,
- 0x0079, /* Speaker Volume */
- 0,
- 0x0000, /* Mono Mixer Control */
-};
-
-static const char *wm8940_companding[] = { "Off", "NC", "u-law", "A-law" };
-static const struct soc_enum wm8940_adc_companding_enum
-= SOC_ENUM_SINGLE(WM8940_COMPANDINGCTL, 1, 4, wm8940_companding);
-static const struct soc_enum wm8940_dac_companding_enum
-= SOC_ENUM_SINGLE(WM8940_COMPANDINGCTL, 3, 4, wm8940_companding);
-
-static const char *wm8940_alc_mode_text[] = {"ALC", "Limiter"};
-static const struct soc_enum wm8940_alc_mode_enum
-= SOC_ENUM_SINGLE(WM8940_ALC3, 8, 2, wm8940_alc_mode_text);
-
-static const char *wm8940_mic_bias_level_text[] = {"0.9", "0.65"};
-static const struct soc_enum wm8940_mic_bias_level_enum
-= SOC_ENUM_SINGLE(WM8940_INPUTCTL, 8, 2, wm8940_mic_bias_level_text);
-
-static const char *wm8940_filter_mode_text[] = {"Audio", "Application"};
-static const struct soc_enum wm8940_filter_mode_enum
-= SOC_ENUM_SINGLE(WM8940_ADC, 7, 2, wm8940_filter_mode_text);
-
-static DECLARE_TLV_DB_SCALE(wm8940_spk_vol_tlv, -5700, 100, 1);
-static DECLARE_TLV_DB_SCALE(wm8940_att_tlv, -1000, 1000, 0);
-static DECLARE_TLV_DB_SCALE(wm8940_pga_vol_tlv, -1200, 75, 0);
-static DECLARE_TLV_DB_SCALE(wm8940_alc_min_tlv, -1200, 600, 0);
-static DECLARE_TLV_DB_SCALE(wm8940_alc_max_tlv, 675, 600, 0);
-static DECLARE_TLV_DB_SCALE(wm8940_alc_tar_tlv, -2250, 50, 0);
-static DECLARE_TLV_DB_SCALE(wm8940_lim_boost_tlv, 0, 100, 0);
-static DECLARE_TLV_DB_SCALE(wm8940_lim_thresh_tlv, -600, 100, 0);
-static DECLARE_TLV_DB_SCALE(wm8940_adc_tlv, -12750, 50, 1);
-static DECLARE_TLV_DB_SCALE(wm8940_capture_boost_vol_tlv, 0, 2000, 0);
-
-static const struct snd_kcontrol_new wm8940_snd_controls[] = {
- SOC_SINGLE("Digital Loopback Switch", WM8940_COMPANDINGCTL,
- 6, 1, 0),
- SOC_ENUM("DAC Companding", wm8940_dac_companding_enum),
- SOC_ENUM("ADC Companding", wm8940_adc_companding_enum),
-
- SOC_ENUM("ALC Mode", wm8940_alc_mode_enum),
- SOC_SINGLE("ALC Switch", WM8940_ALC1, 8, 1, 0),
- SOC_SINGLE_TLV("ALC Capture Max Gain", WM8940_ALC1,
- 3, 7, 1, wm8940_alc_max_tlv),
- SOC_SINGLE_TLV("ALC Capture Min Gain", WM8940_ALC1,
- 0, 7, 0, wm8940_alc_min_tlv),
- SOC_SINGLE_TLV("ALC Capture Target", WM8940_ALC2,
- 0, 14, 0, wm8940_alc_tar_tlv),
- SOC_SINGLE("ALC Capture Hold", WM8940_ALC2, 4, 10, 0),
- SOC_SINGLE("ALC Capture Decay", WM8940_ALC3, 4, 10, 0),
- SOC_SINGLE("ALC Capture Attach", WM8940_ALC3, 0, 10, 0),
- SOC_SINGLE("ALC ZC Switch", WM8940_ALC4, 1, 1, 0),
- SOC_SINGLE("ALC Capture Noise Gate Switch", WM8940_NOISEGATE,
- 3, 1, 0),
- SOC_SINGLE("ALC Capture Noise Gate Threshold", WM8940_NOISEGATE,
- 0, 7, 0),
-
- SOC_SINGLE("DAC Playback Limiter Switch", WM8940_DACLIM1, 8, 1, 0),
- SOC_SINGLE("DAC Playback Limiter Attack", WM8940_DACLIM1, 0, 9, 0),
- SOC_SINGLE("DAC Playback Limiter Decay", WM8940_DACLIM1, 4, 11, 0),
- SOC_SINGLE_TLV("DAC Playback Limiter Threshold", WM8940_DACLIM2,
- 4, 9, 1, wm8940_lim_thresh_tlv),
- SOC_SINGLE_TLV("DAC Playback Limiter Boost", WM8940_DACLIM2,
- 0, 12, 0, wm8940_lim_boost_tlv),
-
- SOC_SINGLE("Capture PGA ZC Switch", WM8940_PGAGAIN, 7, 1, 0),
- SOC_SINGLE_TLV("Capture PGA Volume", WM8940_PGAGAIN,
- 0, 63, 0, wm8940_pga_vol_tlv),
- SOC_SINGLE_TLV("Digital Playback Volume", WM8940_DACVOL,
- 0, 255, 0, wm8940_adc_tlv),
- SOC_SINGLE_TLV("Digital Capture Volume", WM8940_ADCVOL,
- 0, 255, 0, wm8940_adc_tlv),
- SOC_ENUM("Mic Bias Level", wm8940_mic_bias_level_enum),
- SOC_SINGLE_TLV("Capture Boost Volue", WM8940_ADCBOOST,
- 8, 1, 0, wm8940_capture_boost_vol_tlv),
- SOC_SINGLE_TLV("Speaker Playback Volume", WM8940_SPKVOL,
- 0, 63, 0, wm8940_spk_vol_tlv),
- SOC_SINGLE("Speaker Playback Switch", WM8940_SPKVOL, 6, 1, 1),
-
- SOC_SINGLE_TLV("Speaker Mixer Line Bypass Volume", WM8940_SPKVOL,
- 8, 1, 1, wm8940_att_tlv),
- SOC_SINGLE("Speaker Playback ZC Switch", WM8940_SPKVOL, 7, 1, 0),
-
- SOC_SINGLE("Mono Out Switch", WM8940_MONOMIX, 6, 1, 1),
- SOC_SINGLE_TLV("Mono Mixer Line Bypass Volume", WM8940_MONOMIX,
- 7, 1, 1, wm8940_att_tlv),
-
- SOC_SINGLE("High Pass Filter Switch", WM8940_ADC, 8, 1, 0),
- SOC_ENUM("High Pass Filter Mode", wm8940_filter_mode_enum),
- SOC_SINGLE("High Pass Filter Cut Off", WM8940_ADC, 4, 7, 0),
- SOC_SINGLE("ADC Inversion Switch", WM8940_ADC, 0, 1, 0),
- SOC_SINGLE("DAC Inversion Switch", WM8940_DAC, 0, 1, 0),
- SOC_SINGLE("DAC Auto Mute Switch", WM8940_DAC, 2, 1, 0),
- SOC_SINGLE("ZC Timeout Clock Switch", WM8940_ADDCNTRL, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8940_speaker_mixer_controls[] = {
- SOC_DAPM_SINGLE("Line Bypass Switch", WM8940_SPKMIX, 1, 1, 0),
- SOC_DAPM_SINGLE("Aux Playback Switch", WM8940_SPKMIX, 5, 1, 0),
- SOC_DAPM_SINGLE("PCM Playback Switch", WM8940_SPKMIX, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8940_mono_mixer_controls[] = {
- SOC_DAPM_SINGLE("Line Bypass Switch", WM8940_MONOMIX, 1, 1, 0),
- SOC_DAPM_SINGLE("Aux Playback Switch", WM8940_MONOMIX, 2, 1, 0),
- SOC_DAPM_SINGLE("PCM Playback Switch", WM8940_MONOMIX, 0, 1, 0),
-};
-
-static DECLARE_TLV_DB_SCALE(wm8940_boost_vol_tlv, -1500, 300, 1);
-static const struct snd_kcontrol_new wm8940_input_boost_controls[] = {
- SOC_DAPM_SINGLE("Mic PGA Switch", WM8940_PGAGAIN, 6, 1, 1),
- SOC_DAPM_SINGLE_TLV("Aux Volume", WM8940_ADCBOOST,
- 0, 7, 0, wm8940_boost_vol_tlv),
- SOC_DAPM_SINGLE_TLV("Mic Volume", WM8940_ADCBOOST,
- 4, 7, 0, wm8940_boost_vol_tlv),
-};
-
-static const struct snd_kcontrol_new wm8940_micpga_controls[] = {
- SOC_DAPM_SINGLE("AUX Switch", WM8940_INPUTCTL, 2, 1, 0),
- SOC_DAPM_SINGLE("MICP Switch", WM8940_INPUTCTL, 0, 1, 0),
- SOC_DAPM_SINGLE("MICN Switch", WM8940_INPUTCTL, 1, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget wm8940_dapm_widgets[] = {
- SND_SOC_DAPM_MIXER("Speaker Mixer", WM8940_POWER3, 2, 0,
- &wm8940_speaker_mixer_controls[0],
- ARRAY_SIZE(wm8940_speaker_mixer_controls)),
- SND_SOC_DAPM_MIXER("Mono Mixer", WM8940_POWER3, 3, 0,
- &wm8940_mono_mixer_controls[0],
- ARRAY_SIZE(wm8940_mono_mixer_controls)),
- SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8940_POWER3, 0, 0),
-
- SND_SOC_DAPM_PGA("SpkN Out", WM8940_POWER3, 5, 0, NULL, 0),
- SND_SOC_DAPM_PGA("SpkP Out", WM8940_POWER3, 6, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Mono Out", WM8940_POWER3, 7, 0, NULL, 0),
- SND_SOC_DAPM_OUTPUT("MONOOUT"),
- SND_SOC_DAPM_OUTPUT("SPKOUTP"),
- SND_SOC_DAPM_OUTPUT("SPKOUTN"),
-
- SND_SOC_DAPM_PGA("Aux Input", WM8940_POWER1, 6, 0, NULL, 0),
- SND_SOC_DAPM_ADC("ADC", "HiFi Capture", WM8940_POWER2, 0, 0),
- SND_SOC_DAPM_MIXER("Mic PGA", WM8940_POWER2, 2, 0,
- &wm8940_micpga_controls[0],
- ARRAY_SIZE(wm8940_micpga_controls)),
- SND_SOC_DAPM_MIXER("Boost Mixer", WM8940_POWER2, 4, 0,
- &wm8940_input_boost_controls[0],
- ARRAY_SIZE(wm8940_input_boost_controls)),
- SND_SOC_DAPM_MICBIAS("Mic Bias", WM8940_POWER1, 4, 0),
-
- SND_SOC_DAPM_INPUT("MICN"),
- SND_SOC_DAPM_INPUT("MICP"),
- SND_SOC_DAPM_INPUT("AUX"),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- /* Mono output mixer */
- {"Mono Mixer", "PCM Playback Switch", "DAC"},
- {"Mono Mixer", "Aux Playback Switch", "Aux Input"},
- {"Mono Mixer", "Line Bypass Switch", "Boost Mixer"},
-
- /* Speaker output mixer */
- {"Speaker Mixer", "PCM Playback Switch", "DAC"},
- {"Speaker Mixer", "Aux Playback Switch", "Aux Input"},
- {"Speaker Mixer", "Line Bypass Switch", "Boost Mixer"},
-
- /* Outputs */
- {"Mono Out", NULL, "Mono Mixer"},
- {"MONOOUT", NULL, "Mono Out"},
- {"SpkN Out", NULL, "Speaker Mixer"},
- {"SpkP Out", NULL, "Speaker Mixer"},
- {"SPKOUTN", NULL, "SpkN Out"},
- {"SPKOUTP", NULL, "SpkP Out"},
-
- /* Microphone PGA */
- {"Mic PGA", "MICN Switch", "MICN"},
- {"Mic PGA", "MICP Switch", "MICP"},
- {"Mic PGA", "AUX Switch", "AUX"},
-
- /* Boost Mixer */
- {"Boost Mixer", "Mic PGA Switch", "Mic PGA"},
- {"Boost Mixer", "Mic Volume", "MICP"},
- {"Boost Mixer", "Aux Volume", "Aux Input"},
-
- {"ADC", NULL, "Boost Mixer"},
-};
-
-static int wm8940_add_widgets(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret;
-
- ret = snd_soc_dapm_new_controls(dapm, wm8940_dapm_widgets,
- ARRAY_SIZE(wm8940_dapm_widgets));
- if (ret)
- goto error_ret;
- ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
-error_ret:
- return ret;
-}
-
-#define wm8940_reset(c) snd_soc_write(c, WM8940_SOFTRESET, 0);
-
-static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFE67;
- u16 clk = snd_soc_read(codec, WM8940_CLOCK) & 0x1fe;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- clk |= 1;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
- snd_soc_write(codec, WM8940_CLOCK, clk);
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= (2 << 3);
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= (1 << 3);
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= (3 << 3);
- break;
- case SND_SOC_DAIFMT_DSP_B:
- iface |= (3 << 3) | (1 << 7);
- break;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_NB_IF:
- iface |= (1 << 7);
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= (1 << 8);
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= (1 << 8) | (1 << 7);
- break;
- }
-
- snd_soc_write(codec, WM8940_IFACE, iface);
-
- return 0;
-}
-
-static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFD9F;
- u16 addcntrl = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFF1;
- u16 companding = snd_soc_read(codec,
- WM8940_COMPANDINGCTL) & 0xFFDF;
- int ret;
-
- /* LoutR control */
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE
- && params_channels(params) == 2)
- iface |= (1 << 9);
-
- switch (params_rate(params)) {
- case 8000:
- addcntrl |= (0x5 << 1);
- break;
- case 11025:
- addcntrl |= (0x4 << 1);
- break;
- case 16000:
- addcntrl |= (0x3 << 1);
- break;
- case 22050:
- addcntrl |= (0x2 << 1);
- break;
- case 32000:
- addcntrl |= (0x1 << 1);
- break;
- case 44100:
- case 48000:
- break;
- }
- ret = snd_soc_write(codec, WM8940_ADDCNTRL, addcntrl);
- if (ret)
- goto error_ret;
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S8:
- companding = companding | (1 << 5);
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= (1 << 5);
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface |= (2 << 5);
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- iface |= (3 << 5);
- break;
- }
- ret = snd_soc_write(codec, WM8940_COMPANDINGCTL, companding);
- if (ret)
- goto error_ret;
- ret = snd_soc_write(codec, WM8940_IFACE, iface);
-
-error_ret:
- return ret;
-}
-
-static int wm8940_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 mute_reg = snd_soc_read(codec, WM8940_DAC) & 0xffbf;
-
- if (mute)
- mute_reg |= 0x40;
-
- return snd_soc_write(codec, WM8940_DAC, mute_reg);
-}
-
-static int wm8940_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- u16 val;
- u16 pwr_reg = snd_soc_read(codec, WM8940_POWER1) & 0x1F0;
- int ret = 0;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- /* ensure bufioen and biasen */
- pwr_reg |= (1 << 2) | (1 << 3);
- /* Enable thermal shutdown */
- val = snd_soc_read(codec, WM8940_OUTPUTCTL);
- ret = snd_soc_write(codec, WM8940_OUTPUTCTL, val | 0x2);
- if (ret)
- break;
- /* set vmid to 75k */
- ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x1);
- break;
- case SND_SOC_BIAS_PREPARE:
- /* ensure bufioen and biasen */
- pwr_reg |= (1 << 2) | (1 << 3);
- ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x1);
- break;
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = snd_soc_cache_sync(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
- return ret;
- }
- }
-
- /* ensure bufioen and biasen */
- pwr_reg |= (1 << 2) | (1 << 3);
- /* set vmid to 300k for standby */
- ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x2);
- break;
- case SND_SOC_BIAS_OFF:
- ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg);
- break;
- }
-
- codec->dapm.bias_level = level;
-
- return ret;
-}
-
-struct pll_ {
- unsigned int pre_scale:2;
- unsigned int n:4;
- unsigned int k;
-};
-
-static struct pll_ pll_div;
-
-/* The size in bits of the pll divide multiplied by 10
- * to allow rounding later */
-#define FIXED_PLL_SIZE ((1 << 24) * 10)
-static void pll_factors(unsigned int target, unsigned int source)
-{
- unsigned long long Kpart;
- unsigned int K, Ndiv, Nmod;
- /* The left shift ist to avoid accuracy loss when right shifting */
- Ndiv = target / source;
-
- if (Ndiv > 12) {
- source <<= 1;
- /* Multiply by 2 */
- pll_div.pre_scale = 0;
- Ndiv = target / source;
- } else if (Ndiv < 3) {
- source >>= 2;
- /* Divide by 4 */
- pll_div.pre_scale = 3;
- Ndiv = target / source;
- } else if (Ndiv < 6) {
- source >>= 1;
- /* divide by 2 */
- pll_div.pre_scale = 2;
- Ndiv = target / source;
- } else
- pll_div.pre_scale = 1;
-
- if ((Ndiv < 6) || (Ndiv > 12))
- printk(KERN_WARNING
- "WM8940 N value %d outwith recommended range!d\n",
- Ndiv);
-
- pll_div.n = Ndiv;
- Nmod = target % source;
- Kpart = FIXED_PLL_SIZE * (long long)Nmod;
-
- do_div(Kpart, source);
-
- K = Kpart & 0xFFFFFFFF;
-
- /* Check if we need to round */
- if ((K % 10) >= 5)
- K += 5;
-
- /* Move down to proper range now rounding is done */
- K /= 10;
-
- pll_div.k = K;
-}
-
-/* Untested at the moment */
-static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
- int source, unsigned int freq_in, unsigned int freq_out)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 reg;
-
- /* Turn off PLL */
- reg = snd_soc_read(codec, WM8940_POWER1);
- snd_soc_write(codec, WM8940_POWER1, reg & 0x1df);
-
- if (freq_in == 0 || freq_out == 0) {
- /* Clock CODEC directly from MCLK */
- reg = snd_soc_read(codec, WM8940_CLOCK);
- snd_soc_write(codec, WM8940_CLOCK, reg & 0x0ff);
- /* Pll power down */
- snd_soc_write(codec, WM8940_PLLN, (1 << 7));
- return 0;
- }
-
- /* Pll is followed by a frequency divide by 4 */
- pll_factors(freq_out*4, freq_in);
- if (pll_div.k)
- snd_soc_write(codec, WM8940_PLLN,
- (pll_div.pre_scale << 4) | pll_div.n | (1 << 6));
- else /* No factional component */
- snd_soc_write(codec, WM8940_PLLN,
- (pll_div.pre_scale << 4) | pll_div.n);
- snd_soc_write(codec, WM8940_PLLK1, pll_div.k >> 18);
- snd_soc_write(codec, WM8940_PLLK2, (pll_div.k >> 9) & 0x1ff);
- snd_soc_write(codec, WM8940_PLLK3, pll_div.k & 0x1ff);
- /* Enable the PLL */
- reg = snd_soc_read(codec, WM8940_POWER1);
- snd_soc_write(codec, WM8940_POWER1, reg | 0x020);
-
- /* Run CODEC from PLL instead of MCLK */
- reg = snd_soc_read(codec, WM8940_CLOCK);
- snd_soc_write(codec, WM8940_CLOCK, reg | 0x100);
-
- return 0;
-}
-
-static int wm8940_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8940_priv *wm8940 = snd_soc_codec_get_drvdata(codec);
-
- switch (freq) {
- case 11289600:
- case 12000000:
- case 12288000:
- case 16934400:
- case 18432000:
- wm8940->sysclk = freq;
- return 0;
- }
- return -EINVAL;
-}
-
-static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
- int div_id, int div)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 reg;
- int ret = 0;
-
- switch (div_id) {
- case WM8940_BCLKDIV:
- reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFFE3;
- ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 2));
- break;
- case WM8940_MCLKDIV:
- reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFF1F;
- ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 5));
- break;
- case WM8940_OPCLKDIV:
- reg = snd_soc_read(codec, WM8940_GPIO) & 0xFFCF;
- ret = snd_soc_write(codec, WM8940_GPIO, reg | (div << 4));
- break;
- }
- return ret;
-}
-
-#define WM8940_RATES SNDRV_PCM_RATE_8000_48000
-
-#define WM8940_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
- SNDRV_PCM_FMTBIT_S16_LE | \
- SNDRV_PCM_FMTBIT_S20_3LE | \
- SNDRV_PCM_FMTBIT_S24_LE | \
- SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops wm8940_dai_ops = {
- .hw_params = wm8940_i2s_hw_params,
- .set_sysclk = wm8940_set_dai_sysclk,
- .digital_mute = wm8940_mute,
- .set_fmt = wm8940_set_dai_fmt,
- .set_clkdiv = wm8940_set_dai_clkdiv,
- .set_pll = wm8940_set_dai_pll,
-};
-
-static struct snd_soc_dai_driver wm8940_dai = {
- .name = "wm8940-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8940_RATES,
- .formats = WM8940_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8940_RATES,
- .formats = WM8940_FORMATS,
- },
- .ops = &wm8940_dai_ops,
- .symmetric_rates = 1,
-};
-
-static int wm8940_suspend(struct snd_soc_codec *codec)
-{
- return wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF);
-}
-
-static int wm8940_resume(struct snd_soc_codec *codec)
-{
- wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-
-static int wm8940_probe(struct snd_soc_codec *codec)
-{
- struct wm8940_priv *wm8940 = snd_soc_codec_get_drvdata(codec);
- struct wm8940_setup_data *pdata = codec->dev->platform_data;
- int ret;
- u16 reg;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8940->control_type);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- ret = wm8940_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- return ret;
- }
-
- wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- ret = snd_soc_write(codec, WM8940_POWER1, 0x180);
- if (ret < 0)
- return ret;
-
- if (!pdata)
- dev_warn(codec->dev, "No platform data supplied\n");
- else {
- reg = snd_soc_read(codec, WM8940_OUTPUTCTL);
- ret = snd_soc_write(codec, WM8940_OUTPUTCTL, reg | pdata->vroi);
- if (ret < 0)
- return ret;
- }
-
- ret = snd_soc_add_codec_controls(codec, wm8940_snd_controls,
- ARRAY_SIZE(wm8940_snd_controls));
- if (ret)
- return ret;
- ret = wm8940_add_widgets(codec);
- return ret;
-}
-
-static int wm8940_remove(struct snd_soc_codec *codec)
-{
- wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8940 = {
- .probe = wm8940_probe,
- .remove = wm8940_remove,
- .suspend = wm8940_suspend,
- .resume = wm8940_resume,
- .set_bias_level = wm8940_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8940_reg_defaults,
- .volatile_register = wm8940_volatile_register,
-};
-
-static __devinit int wm8940_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8940_priv *wm8940;
- int ret;
-
- wm8940 = devm_kzalloc(&i2c->dev, sizeof(struct wm8940_priv),
- GFP_KERNEL);
- if (wm8940 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm8940);
- wm8940->control_type = SND_SOC_I2C;
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8940, &wm8940_dai, 1);
-
- return ret;
-}
-
-static __devexit int wm8940_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
-
- return 0;
-}
-
-static const struct i2c_device_id wm8940_i2c_id[] = {
- { "wm8940", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8940_i2c_id);
-
-static struct i2c_driver wm8940_i2c_driver = {
- .driver = {
- .name = "wm8940",
- .owner = THIS_MODULE,
- },
- .probe = wm8940_i2c_probe,
- .remove = __devexit_p(wm8940_i2c_remove),
- .id_table = wm8940_i2c_id,
-};
-
-static int __init wm8940_modinit(void)
-{
- int ret = 0;
- ret = i2c_add_driver(&wm8940_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8940 I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(wm8940_modinit);
-
-static void __exit wm8940_exit(void)
-{
- i2c_del_driver(&wm8940_i2c_driver);
-}
-module_exit(wm8940_exit);
-
-MODULE_DESCRIPTION("ASoC WM8940 driver");
-MODULE_AUTHOR("Jonathan Cameron");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8940.h b/ANDROID_3.4.5/sound/soc/codecs/wm8940.h
deleted file mode 100644
index 907fe192..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8940.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * wm8940.h -- WM8940 Soc Audio driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8940_H
-#define _WM8940_H
-
-struct wm8940_setup_data {
- /* Vref to analogue output resistance */
-#define WM8940_VROI_1K 0
-#define WM8940_VROI_30K 1
- unsigned int vroi:1;
-};
-
-/* WM8940 register space */
-#define WM8940_SOFTRESET 0x00
-#define WM8940_POWER1 0x01
-#define WM8940_POWER2 0x02
-#define WM8940_POWER3 0x03
-#define WM8940_IFACE 0x04
-#define WM8940_COMPANDINGCTL 0x05
-#define WM8940_CLOCK 0x06
-#define WM8940_ADDCNTRL 0x07
-#define WM8940_GPIO 0x08
-#define WM8940_CTLINT 0x09
-#define WM8940_DAC 0x0A
-#define WM8940_DACVOL 0x0B
-
-#define WM8940_ADC 0x0E
-#define WM8940_ADCVOL 0x0F
-#define WM8940_NOTCH1 0x10
-#define WM8940_NOTCH2 0x11
-#define WM8940_NOTCH3 0x12
-#define WM8940_NOTCH4 0x13
-#define WM8940_NOTCH5 0x14
-#define WM8940_NOTCH6 0x15
-#define WM8940_NOTCH7 0x16
-#define WM8940_NOTCH8 0x17
-#define WM8940_DACLIM1 0x18
-#define WM8940_DACLIM2 0x19
-
-#define WM8940_ALC1 0x20
-#define WM8940_ALC2 0x21
-#define WM8940_ALC3 0x22
-#define WM8940_NOISEGATE 0x23
-#define WM8940_PLLN 0x24
-#define WM8940_PLLK1 0x25
-#define WM8940_PLLK2 0x26
-#define WM8940_PLLK3 0x27
-
-#define WM8940_ALC4 0x2A
-
-#define WM8940_INPUTCTL 0x2C
-#define WM8940_PGAGAIN 0x2D
-
-#define WM8940_ADCBOOST 0x2F
-
-#define WM8940_OUTPUTCTL 0x31
-#define WM8940_SPKMIX 0x32
-
-#define WM8940_SPKVOL 0x36
-
-#define WM8940_MONOMIX 0x38
-
-#define WM8940_CACHEREGNUM 0x57
-
-
-/* Clock divider Id's */
-#define WM8940_BCLKDIV 0
-#define WM8940_MCLKDIV 1
-#define WM8940_OPCLKDIV 2
-
-/* MCLK clock dividers */
-#define WM8940_MCLKDIV_1 0
-#define WM8940_MCLKDIV_1_5 1
-#define WM8940_MCLKDIV_2 2
-#define WM8940_MCLKDIV_3 3
-#define WM8940_MCLKDIV_4 4
-#define WM8940_MCLKDIV_6 5
-#define WM8940_MCLKDIV_8 6
-#define WM8940_MCLKDIV_12 7
-
-/* BCLK clock dividers */
-#define WM8940_BCLKDIV_1 0
-#define WM8940_BCLKDIV_2 1
-#define WM8940_BCLKDIV_4 2
-#define WM8940_BCLKDIV_8 3
-#define WM8940_BCLKDIV_16 4
-#define WM8940_BCLKDIV_32 5
-
-/* PLL Out Dividers */
-#define WM8940_OPCLKDIV_1 0
-#define WM8940_OPCLKDIV_2 1
-#define WM8940_OPCLKDIV_3 2
-#define WM8940_OPCLKDIV_4 3
-
-#endif /* _WM8940_H */
-
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8955.c b/ANDROID_3.4.5/sound/soc/codecs/wm8955.c
deleted file mode 100644
index 61fe9743..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8955.c
+++ /dev/null
@@ -1,1094 +0,0 @@
-/*
- * wm8955.c -- WM8955 ALSA SoC Audio driver
- *
- * Copyright 2009 Wolfson Microelectronics plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/regmap.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <sound/wm8955.h>
-
-#include "wm8955.h"
-
-#define WM8955_NUM_SUPPLIES 4
-static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = {
- "DCVDD",
- "DBVDD",
- "HPVDD",
- "AVDD",
-};
-
-/* codec private data */
-struct wm8955_priv {
- struct regmap *regmap;
-
- unsigned int mclk_rate;
-
- int deemph;
- int fs;
-
- struct regulator_bulk_data supplies[WM8955_NUM_SUPPLIES];
-};
-
-static const struct reg_default wm8955_reg_defaults[] = {
- { 2, 0x0079 }, /* R2 - LOUT1 volume */
- { 3, 0x0079 }, /* R3 - ROUT1 volume */
- { 5, 0x0008 }, /* R5 - DAC Control */
- { 7, 0x000A }, /* R7 - Audio Interface */
- { 8, 0x0000 }, /* R8 - Sample Rate */
- { 10, 0x00FF }, /* R10 - Left DAC volume */
- { 11, 0x00FF }, /* R11 - Right DAC volume */
- { 12, 0x000F }, /* R12 - Bass control */
- { 13, 0x000F }, /* R13 - Treble control */
- { 23, 0x00C1 }, /* R23 - Additional control (1) */
- { 24, 0x0000 }, /* R24 - Additional control (2) */
- { 25, 0x0000 }, /* R25 - Power Management (1) */
- { 26, 0x0000 }, /* R26 - Power Management (2) */
- { 27, 0x0000 }, /* R27 - Additional Control (3) */
- { 34, 0x0050 }, /* R34 - Left out Mix (1) */
- { 35, 0x0050 }, /* R35 - Left out Mix (2) */
- { 36, 0x0050 }, /* R36 - Right out Mix (1) */
- { 37, 0x0050 }, /* R37 - Right Out Mix (2) */
- { 38, 0x0050 }, /* R38 - Mono out Mix (1) */
- { 39, 0x0050 }, /* R39 - Mono out Mix (2) */
- { 40, 0x0079 }, /* R40 - LOUT2 volume */
- { 41, 0x0079 }, /* R41 - ROUT2 volume */
- { 42, 0x0079 }, /* R42 - MONOOUT volume */
- { 43, 0x0000 }, /* R43 - Clocking / PLL */
- { 44, 0x0103 }, /* R44 - PLL Control 1 */
- { 45, 0x0024 }, /* R45 - PLL Control 2 */
- { 46, 0x01BA }, /* R46 - PLL Control 3 */
- { 59, 0x0000 }, /* R59 - PLL Control 4 */
-};
-
-static bool wm8955_writeable(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM8955_LOUT1_VOLUME:
- case WM8955_ROUT1_VOLUME:
- case WM8955_DAC_CONTROL:
- case WM8955_AUDIO_INTERFACE:
- case WM8955_SAMPLE_RATE:
- case WM8955_LEFT_DAC_VOLUME:
- case WM8955_RIGHT_DAC_VOLUME:
- case WM8955_BASS_CONTROL:
- case WM8955_TREBLE_CONTROL:
- case WM8955_RESET:
- case WM8955_ADDITIONAL_CONTROL_1:
- case WM8955_ADDITIONAL_CONTROL_2:
- case WM8955_POWER_MANAGEMENT_1:
- case WM8955_POWER_MANAGEMENT_2:
- case WM8955_ADDITIONAL_CONTROL_3:
- case WM8955_LEFT_OUT_MIX_1:
- case WM8955_LEFT_OUT_MIX_2:
- case WM8955_RIGHT_OUT_MIX_1:
- case WM8955_RIGHT_OUT_MIX_2:
- case WM8955_MONO_OUT_MIX_1:
- case WM8955_MONO_OUT_MIX_2:
- case WM8955_LOUT2_VOLUME:
- case WM8955_ROUT2_VOLUME:
- case WM8955_MONOOUT_VOLUME:
- case WM8955_CLOCKING_PLL:
- case WM8955_PLL_CONTROL_1:
- case WM8955_PLL_CONTROL_2:
- case WM8955_PLL_CONTROL_3:
- case WM8955_PLL_CONTROL_4:
- return true;
- default:
- return false;
- }
-}
-
-static bool wm8955_volatile(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM8955_RESET:
- return true;
- default:
- return false;
- }
-}
-
-static int wm8955_reset(struct snd_soc_codec *codec)
-{
- return snd_soc_write(codec, WM8955_RESET, 0);
-}
-
-struct pll_factors {
- int n;
- int k;
- int outdiv;
-};
-
-/* The size in bits of the FLL divide multiplied by 10
- * to allow rounding later */
-#define FIXED_FLL_SIZE ((1 << 22) * 10)
-
-static int wm8995_pll_factors(struct device *dev,
- int Fref, int Fout, struct pll_factors *pll)
-{
- u64 Kpart;
- unsigned int K, Ndiv, Nmod, target;
-
- dev_dbg(dev, "Fref=%u Fout=%u\n", Fref, Fout);
-
- /* The oscilator should run at should be 90-100MHz, and
- * there's a divide by 4 plus an optional divide by 2 in the
- * output path to generate the system clock. The clock table
- * is sortd so we should always generate a suitable target. */
- target = Fout * 4;
- if (target < 90000000) {
- pll->outdiv = 1;
- target *= 2;
- } else {
- pll->outdiv = 0;
- }
-
- WARN_ON(target < 90000000 || target > 100000000);
-
- dev_dbg(dev, "Fvco=%dHz\n", target);
-
- /* Now, calculate N.K */
- Ndiv = target / Fref;
-
- pll->n = Ndiv;
- Nmod = target % Fref;
- dev_dbg(dev, "Nmod=%d\n", Nmod);
-
- /* Calculate fractional part - scale up so we can round. */
- Kpart = FIXED_FLL_SIZE * (long long)Nmod;
-
- do_div(Kpart, Fref);
-
- K = Kpart & 0xFFFFFFFF;
-
- if ((K % 10) >= 5)
- K += 5;
-
- /* Move down to proper range now rounding is done */
- pll->k = K / 10;
-
- dev_dbg(dev, "N=%x K=%x OUTDIV=%x\n", pll->n, pll->k, pll->outdiv);
-
- return 0;
-}
-
-/* Lookup table specifying SRATE (table 25 in datasheet); some of the
- * output frequencies have been rounded to the standard frequencies
- * they are intended to match where the error is slight. */
-static struct {
- int mclk;
- int fs;
- int usb;
- int sr;
-} clock_cfgs[] = {
- { 18432000, 8000, 0, 3, },
- { 18432000, 12000, 0, 9, },
- { 18432000, 16000, 0, 11, },
- { 18432000, 24000, 0, 29, },
- { 18432000, 32000, 0, 13, },
- { 18432000, 48000, 0, 1, },
- { 18432000, 96000, 0, 15, },
-
- { 16934400, 8018, 0, 19, },
- { 16934400, 11025, 0, 25, },
- { 16934400, 22050, 0, 27, },
- { 16934400, 44100, 0, 17, },
- { 16934400, 88200, 0, 31, },
-
- { 12000000, 8000, 1, 2, },
- { 12000000, 11025, 1, 25, },
- { 12000000, 12000, 1, 8, },
- { 12000000, 16000, 1, 10, },
- { 12000000, 22050, 1, 27, },
- { 12000000, 24000, 1, 28, },
- { 12000000, 32000, 1, 12, },
- { 12000000, 44100, 1, 17, },
- { 12000000, 48000, 1, 0, },
- { 12000000, 88200, 1, 31, },
- { 12000000, 96000, 1, 14, },
-
- { 12288000, 8000, 0, 2, },
- { 12288000, 12000, 0, 8, },
- { 12288000, 16000, 0, 10, },
- { 12288000, 24000, 0, 28, },
- { 12288000, 32000, 0, 12, },
- { 12288000, 48000, 0, 0, },
- { 12288000, 96000, 0, 14, },
-
- { 12289600, 8018, 0, 18, },
- { 12289600, 11025, 0, 24, },
- { 12289600, 22050, 0, 26, },
- { 11289600, 44100, 0, 16, },
- { 11289600, 88200, 0, 31, },
-};
-
-static int wm8955_configure_clocking(struct snd_soc_codec *codec)
-{
- struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
- int i, ret, val;
- int clocking = 0;
- int srate = 0;
- int sr = -1;
- struct pll_factors pll;
-
- /* If we're not running a sample rate currently just pick one */
- if (wm8955->fs == 0)
- wm8955->fs = 8000;
-
- /* Can we generate an exact output? */
- for (i = 0; i < ARRAY_SIZE(clock_cfgs); i++) {
- if (wm8955->fs != clock_cfgs[i].fs)
- continue;
- sr = i;
-
- if (wm8955->mclk_rate == clock_cfgs[i].mclk)
- break;
- }
-
- /* We should never get here with an unsupported sample rate */
- if (sr == -1) {
- dev_err(codec->dev, "Sample rate %dHz unsupported\n",
- wm8955->fs);
- WARN_ON(sr == -1);
- return -EINVAL;
- }
-
- if (i == ARRAY_SIZE(clock_cfgs)) {
- /* If we can't generate the right clock from MCLK then
- * we should configure the PLL to supply us with an
- * appropriate clock.
- */
- clocking |= WM8955_MCLKSEL;
-
- /* Use the last divider configuration we saw for the
- * sample rate. */
- ret = wm8995_pll_factors(codec->dev, wm8955->mclk_rate,
- clock_cfgs[sr].mclk, &pll);
- if (ret != 0) {
- dev_err(codec->dev,
- "Unable to generate %dHz from %dHz MCLK\n",
- wm8955->fs, wm8955->mclk_rate);
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, WM8955_PLL_CONTROL_1,
- WM8955_N_MASK | WM8955_K_21_18_MASK,
- (pll.n << WM8955_N_SHIFT) |
- pll.k >> 18);
- snd_soc_update_bits(codec, WM8955_PLL_CONTROL_2,
- WM8955_K_17_9_MASK,
- (pll.k >> 9) & WM8955_K_17_9_MASK);
- snd_soc_update_bits(codec, WM8955_PLL_CONTROL_2,
- WM8955_K_8_0_MASK,
- pll.k & WM8955_K_8_0_MASK);
- if (pll.k)
- snd_soc_update_bits(codec, WM8955_PLL_CONTROL_4,
- WM8955_KEN, WM8955_KEN);
- else
- snd_soc_update_bits(codec, WM8955_PLL_CONTROL_4,
- WM8955_KEN, 0);
-
- if (pll.outdiv)
- val = WM8955_PLL_RB | WM8955_PLLOUTDIV2;
- else
- val = WM8955_PLL_RB;
-
- /* Now start the PLL running */
- snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
- WM8955_PLL_RB | WM8955_PLLOUTDIV2, val);
- snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
- WM8955_PLLEN, WM8955_PLLEN);
- }
-
- srate = clock_cfgs[sr].usb | (clock_cfgs[sr].sr << WM8955_SR_SHIFT);
-
- snd_soc_update_bits(codec, WM8955_SAMPLE_RATE,
- WM8955_USB | WM8955_SR_MASK, srate);
- snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
- WM8955_MCLKSEL, clocking);
-
- return 0;
-}
-
-static int wm8955_sysclk(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- int ret = 0;
-
- /* Always disable the clocks - if we're doing reconfiguration this
- * avoids misclocking.
- */
- snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
- WM8955_DIGENB, 0);
- snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
- WM8955_PLL_RB | WM8955_PLLEN, 0);
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMD:
- break;
- case SND_SOC_DAPM_PRE_PMU:
- ret = wm8955_configure_clocking(codec);
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-static int deemph_settings[] = { 0, 32000, 44100, 48000 };
-
-static int wm8955_set_deemph(struct snd_soc_codec *codec)
-{
- struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
- int val, i, best;
-
- /* If we're using deemphasis select the nearest available sample
- * rate.
- */
- if (wm8955->deemph) {
- best = 1;
- for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) {
- if (abs(deemph_settings[i] - wm8955->fs) <
- abs(deemph_settings[best] - wm8955->fs))
- best = i;
- }
-
- val = best << WM8955_DEEMPH_SHIFT;
- } else {
- val = 0;
- }
-
- dev_dbg(codec->dev, "Set deemphasis %d\n", val);
-
- return snd_soc_update_bits(codec, WM8955_DAC_CONTROL,
- WM8955_DEEMPH_MASK, val);
-}
-
-static int wm8955_get_deemph(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.enumerated.item[0] = wm8955->deemph;
- return 0;
-}
-
-static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
- int deemph = ucontrol->value.enumerated.item[0];
-
- if (deemph > 1)
- return -EINVAL;
-
- wm8955->deemph = deemph;
-
- return wm8955_set_deemph(codec);
-}
-
-static const char *bass_mode_text[] = {
- "Linear", "Adaptive",
-};
-
-static const struct soc_enum bass_mode =
- SOC_ENUM_SINGLE(WM8955_BASS_CONTROL, 7, 2, bass_mode_text);
-
-static const char *bass_cutoff_text[] = {
- "Low", "High"
-};
-
-static const struct soc_enum bass_cutoff =
- SOC_ENUM_SINGLE(WM8955_BASS_CONTROL, 6, 2, bass_cutoff_text);
-
-static const char *treble_cutoff_text[] = {
- "High", "Low"
-};
-
-static const struct soc_enum treble_cutoff =
- SOC_ENUM_SINGLE(WM8955_TREBLE_CONTROL, 6, 2, treble_cutoff_text);
-
-static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);
-static const DECLARE_TLV_DB_SCALE(atten_tlv, -600, 600, 0);
-static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
-static const DECLARE_TLV_DB_SCALE(mono_tlv, -2100, 300, 0);
-static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
-static const DECLARE_TLV_DB_SCALE(treble_tlv, -1200, 150, 1);
-
-static const struct snd_kcontrol_new wm8955_snd_controls[] = {
-SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8955_LEFT_DAC_VOLUME,
- WM8955_RIGHT_DAC_VOLUME, 0, 255, 0, digital_tlv),
-SOC_SINGLE_TLV("Playback Attenuation Volume", WM8955_DAC_CONTROL, 7, 1, 1,
- atten_tlv),
-SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0,
- wm8955_get_deemph, wm8955_put_deemph),
-
-SOC_ENUM("Bass Mode", bass_mode),
-SOC_ENUM("Bass Cutoff", bass_cutoff),
-SOC_SINGLE("Bass Volume", WM8955_BASS_CONTROL, 0, 15, 1),
-
-SOC_ENUM("Treble Cutoff", treble_cutoff),
-SOC_SINGLE_TLV("Treble Volume", WM8955_TREBLE_CONTROL, 0, 14, 1, treble_tlv),
-
-SOC_SINGLE_TLV("Left Bypass Volume", WM8955_LEFT_OUT_MIX_1, 4, 7, 1,
- bypass_tlv),
-SOC_SINGLE_TLV("Left Mono Volume", WM8955_LEFT_OUT_MIX_2, 4, 7, 1,
- bypass_tlv),
-
-SOC_SINGLE_TLV("Right Mono Volume", WM8955_RIGHT_OUT_MIX_1, 4, 7, 1,
- bypass_tlv),
-SOC_SINGLE_TLV("Right Bypass Volume", WM8955_RIGHT_OUT_MIX_2, 4, 7, 1,
- bypass_tlv),
-
-/* Not a stereo pair so they line up with the DAPM switches */
-SOC_SINGLE_TLV("Mono Left Bypass Volume", WM8955_MONO_OUT_MIX_1, 4, 7, 1,
- mono_tlv),
-SOC_SINGLE_TLV("Mono Right Bypass Volume", WM8955_MONO_OUT_MIX_2, 4, 7, 1,
- mono_tlv),
-
-SOC_DOUBLE_R_TLV("Headphone Volume", WM8955_LOUT1_VOLUME,
- WM8955_ROUT1_VOLUME, 0, 127, 0, out_tlv),
-SOC_DOUBLE_R("Headphone ZC Switch", WM8955_LOUT1_VOLUME,
- WM8955_ROUT1_VOLUME, 7, 1, 0),
-
-SOC_DOUBLE_R_TLV("Speaker Volume", WM8955_LOUT2_VOLUME,
- WM8955_ROUT2_VOLUME, 0, 127, 0, out_tlv),
-SOC_DOUBLE_R("Speaker ZC Switch", WM8955_LOUT2_VOLUME,
- WM8955_ROUT2_VOLUME, 7, 1, 0),
-
-SOC_SINGLE_TLV("Mono Volume", WM8955_MONOOUT_VOLUME, 0, 127, 0, out_tlv),
-SOC_SINGLE("Mono ZC Switch", WM8955_MONOOUT_VOLUME, 7, 1, 0),
-};
-
-static const struct snd_kcontrol_new lmixer[] = {
-SOC_DAPM_SINGLE("Playback Switch", WM8955_LEFT_OUT_MIX_1, 8, 1, 0),
-SOC_DAPM_SINGLE("Bypass Switch", WM8955_LEFT_OUT_MIX_1, 7, 1, 0),
-SOC_DAPM_SINGLE("Right Playback Switch", WM8955_LEFT_OUT_MIX_2, 8, 1, 0),
-SOC_DAPM_SINGLE("Mono Switch", WM8955_LEFT_OUT_MIX_2, 7, 1, 0),
-};
-
-static const struct snd_kcontrol_new rmixer[] = {
-SOC_DAPM_SINGLE("Left Playback Switch", WM8955_RIGHT_OUT_MIX_1, 8, 1, 0),
-SOC_DAPM_SINGLE("Mono Switch", WM8955_RIGHT_OUT_MIX_1, 7, 1, 0),
-SOC_DAPM_SINGLE("Playback Switch", WM8955_RIGHT_OUT_MIX_2, 8, 1, 0),
-SOC_DAPM_SINGLE("Bypass Switch", WM8955_RIGHT_OUT_MIX_2, 7, 1, 0),
-};
-
-static const struct snd_kcontrol_new mmixer[] = {
-SOC_DAPM_SINGLE("Left Playback Switch", WM8955_MONO_OUT_MIX_1, 8, 1, 0),
-SOC_DAPM_SINGLE("Left Bypass Switch", WM8955_MONO_OUT_MIX_1, 7, 1, 0),
-SOC_DAPM_SINGLE("Right Playback Switch", WM8955_MONO_OUT_MIX_2, 8, 1, 0),
-SOC_DAPM_SINGLE("Right Bypass Switch", WM8955_MONO_OUT_MIX_2, 7, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget wm8955_dapm_widgets[] = {
-SND_SOC_DAPM_INPUT("MONOIN-"),
-SND_SOC_DAPM_INPUT("MONOIN+"),
-SND_SOC_DAPM_INPUT("LINEINR"),
-SND_SOC_DAPM_INPUT("LINEINL"),
-
-SND_SOC_DAPM_PGA("Mono Input", SND_SOC_NOPM, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_SUPPLY("SYSCLK", WM8955_POWER_MANAGEMENT_1, 0, 1, wm8955_sysclk,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-SND_SOC_DAPM_SUPPLY("TSDEN", WM8955_ADDITIONAL_CONTROL_1, 8, 0, NULL, 0),
-
-SND_SOC_DAPM_DAC("DACL", "Playback", WM8955_POWER_MANAGEMENT_2, 8, 0),
-SND_SOC_DAPM_DAC("DACR", "Playback", WM8955_POWER_MANAGEMENT_2, 7, 0),
-
-SND_SOC_DAPM_PGA("LOUT1 PGA", WM8955_POWER_MANAGEMENT_2, 6, 0, NULL, 0),
-SND_SOC_DAPM_PGA("ROUT1 PGA", WM8955_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA("LOUT2 PGA", WM8955_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
-SND_SOC_DAPM_PGA("ROUT2 PGA", WM8955_POWER_MANAGEMENT_2, 3, 0, NULL, 0),
-SND_SOC_DAPM_PGA("MOUT PGA", WM8955_POWER_MANAGEMENT_2, 2, 0, NULL, 0),
-SND_SOC_DAPM_PGA("OUT3 PGA", WM8955_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
-
-/* The names are chosen to make the control names nice */
-SND_SOC_DAPM_MIXER("Left", SND_SOC_NOPM, 0, 0,
- lmixer, ARRAY_SIZE(lmixer)),
-SND_SOC_DAPM_MIXER("Right", SND_SOC_NOPM, 0, 0,
- rmixer, ARRAY_SIZE(rmixer)),
-SND_SOC_DAPM_MIXER("Mono", SND_SOC_NOPM, 0, 0,
- mmixer, ARRAY_SIZE(mmixer)),
-
-SND_SOC_DAPM_OUTPUT("LOUT1"),
-SND_SOC_DAPM_OUTPUT("ROUT1"),
-SND_SOC_DAPM_OUTPUT("LOUT2"),
-SND_SOC_DAPM_OUTPUT("ROUT2"),
-SND_SOC_DAPM_OUTPUT("MONOOUT"),
-SND_SOC_DAPM_OUTPUT("OUT3"),
-};
-
-static const struct snd_soc_dapm_route wm8955_dapm_routes[] = {
- { "DACL", NULL, "SYSCLK" },
- { "DACR", NULL, "SYSCLK" },
-
- { "Mono Input", NULL, "MONOIN-" },
- { "Mono Input", NULL, "MONOIN+" },
-
- { "Left", "Playback Switch", "DACL" },
- { "Left", "Right Playback Switch", "DACR" },
- { "Left", "Bypass Switch", "LINEINL" },
- { "Left", "Mono Switch", "Mono Input" },
-
- { "Right", "Playback Switch", "DACR" },
- { "Right", "Left Playback Switch", "DACL" },
- { "Right", "Bypass Switch", "LINEINR" },
- { "Right", "Mono Switch", "Mono Input" },
-
- { "Mono", "Left Playback Switch", "DACL" },
- { "Mono", "Right Playback Switch", "DACR" },
- { "Mono", "Left Bypass Switch", "LINEINL" },
- { "Mono", "Right Bypass Switch", "LINEINR" },
-
- { "LOUT1 PGA", NULL, "Left" },
- { "LOUT1", NULL, "TSDEN" },
- { "LOUT1", NULL, "LOUT1 PGA" },
-
- { "ROUT1 PGA", NULL, "Right" },
- { "ROUT1", NULL, "TSDEN" },
- { "ROUT1", NULL, "ROUT1 PGA" },
-
- { "LOUT2 PGA", NULL, "Left" },
- { "LOUT2", NULL, "TSDEN" },
- { "LOUT2", NULL, "LOUT2 PGA" },
-
- { "ROUT2 PGA", NULL, "Right" },
- { "ROUT2", NULL, "TSDEN" },
- { "ROUT2", NULL, "ROUT2 PGA" },
-
- { "MOUT PGA", NULL, "Mono" },
- { "MONOOUT", NULL, "MOUT PGA" },
-
- /* OUT3 not currently implemented */
- { "OUT3", NULL, "OUT3 PGA" },
-};
-
-static int wm8955_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
- int ret;
- int wl;
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- wl = 0;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- wl = 0x4;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- wl = 0x8;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- wl = 0xc;
- break;
- default:
- return -EINVAL;
- }
- snd_soc_update_bits(codec, WM8955_AUDIO_INTERFACE,
- WM8955_WL_MASK, wl);
-
- wm8955->fs = params_rate(params);
- wm8955_set_deemph(codec);
-
- /* If the chip is clocked then disable the clocks and force a
- * reconfiguration, otherwise DAPM will power up the
- * clocks for us later. */
- ret = snd_soc_read(codec, WM8955_POWER_MANAGEMENT_1);
- if (ret < 0)
- return ret;
- if (ret & WM8955_DIGENB) {
- snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
- WM8955_DIGENB, 0);
- snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
- WM8955_PLL_RB | WM8955_PLLEN, 0);
-
- wm8955_configure_clocking(codec);
- }
-
- return 0;
-}
-
-
-static int wm8955_set_sysclk(struct snd_soc_dai *dai, int clk_id,
- unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8955_priv *priv = snd_soc_codec_get_drvdata(codec);
- int div;
-
- switch (clk_id) {
- case WM8955_CLK_MCLK:
- if (freq > 15000000) {
- priv->mclk_rate = freq /= 2;
- div = WM8955_MCLKDIV2;
- } else {
- priv->mclk_rate = freq;
- div = 0;
- }
-
- snd_soc_update_bits(codec, WM8955_SAMPLE_RATE,
- WM8955_MCLKDIV2, div);
- break;
-
- default:
- return -EINVAL;
- }
-
- dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
-
- return 0;
-}
-
-static int wm8955_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 aif = 0;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- aif |= WM8955_MS;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_B:
- aif |= WM8955_LRP;
- case SND_SOC_DAIFMT_DSP_A:
- aif |= 0x3;
- break;
- case SND_SOC_DAIFMT_I2S:
- aif |= 0x2;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- aif |= 0x1;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- case SND_SOC_DAIFMT_DSP_B:
- /* frame inversion not valid for DSP modes */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_NF:
- aif |= WM8955_BCLKINV;
- break;
- default:
- return -EINVAL;
- }
- break;
-
- case SND_SOC_DAIFMT_I2S:
- case SND_SOC_DAIFMT_RIGHT_J:
- case SND_SOC_DAIFMT_LEFT_J:
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- aif |= WM8955_BCLKINV | WM8955_LRP;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- aif |= WM8955_BCLKINV;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- aif |= WM8955_LRP;
- break;
- default:
- return -EINVAL;
- }
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, WM8955_AUDIO_INTERFACE,
- WM8955_MS | WM8955_FORMAT_MASK | WM8955_BCLKINV |
- WM8955_LRP, aif);
-
- return 0;
-}
-
-
-static int wm8955_digital_mute(struct snd_soc_dai *codec_dai, int mute)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- int val;
-
- if (mute)
- val = WM8955_DACMU;
- else
- val = 0;
-
- snd_soc_update_bits(codec, WM8955_DAC_CONTROL, WM8955_DACMU, val);
-
- return 0;
-}
-
-static int wm8955_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- /* VMID resistance 2*50k */
- snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
- WM8955_VMIDSEL_MASK,
- 0x1 << WM8955_VMIDSEL_SHIFT);
-
- /* Default bias current */
- snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_1,
- WM8955_VSEL_MASK,
- 0x2 << WM8955_VSEL_SHIFT);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
- wm8955->supplies);
- if (ret != 0) {
- dev_err(codec->dev,
- "Failed to enable supplies: %d\n",
- ret);
- return ret;
- }
-
- regcache_sync(wm8955->regmap);
-
- /* Enable VREF and VMID */
- snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
- WM8955_VREF |
- WM8955_VMIDSEL_MASK,
- WM8955_VREF |
- 0x3 << WM8955_VREF_SHIFT);
-
- /* Let VMID ramp */
- msleep(500);
-
- /* High resistance VROI to maintain outputs */
- snd_soc_update_bits(codec,
- WM8955_ADDITIONAL_CONTROL_3,
- WM8955_VROI, WM8955_VROI);
- }
-
- /* Maintain VMID with 2*250k */
- snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
- WM8955_VMIDSEL_MASK,
- 0x2 << WM8955_VMIDSEL_SHIFT);
-
- /* Minimum bias current */
- snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_1,
- WM8955_VSEL_MASK, 0);
- break;
-
- case SND_SOC_BIAS_OFF:
- /* Low resistance VROI to help discharge */
- snd_soc_update_bits(codec,
- WM8955_ADDITIONAL_CONTROL_3,
- WM8955_VROI, 0);
-
- /* Turn off VMID and VREF */
- snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
- WM8955_VREF |
- WM8955_VMIDSEL_MASK, 0);
-
- regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies),
- wm8955->supplies);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define WM8955_RATES SNDRV_PCM_RATE_8000_96000
-
-#define WM8955_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops wm8955_dai_ops = {
- .set_sysclk = wm8955_set_sysclk,
- .set_fmt = wm8955_set_fmt,
- .hw_params = wm8955_hw_params,
- .digital_mute = wm8955_digital_mute,
-};
-
-static struct snd_soc_dai_driver wm8955_dai = {
- .name = "wm8955-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = WM8955_RATES,
- .formats = WM8955_FORMATS,
- },
- .ops = &wm8955_dai_ops,
-};
-
-#ifdef CONFIG_PM
-static int wm8955_suspend(struct snd_soc_codec *codec)
-{
- struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
-
- wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- regcache_mark_dirty(wm8955->regmap);
-
- return 0;
-}
-
-static int wm8955_resume(struct snd_soc_codec *codec)
-{
- wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-#else
-#define wm8955_suspend NULL
-#define wm8955_resume NULL
-#endif
-
-static int wm8955_probe(struct snd_soc_codec *codec)
-{
- struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
- struct wm8955_pdata *pdata = dev_get_platdata(codec->dev);
- int ret, i;
-
- codec->control_data = wm8955->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm8955->supplies); i++)
- wm8955->supplies[i].supply = wm8955_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8955->supplies),
- wm8955->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- return ret;
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
- wm8955->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
- goto err_get;
- }
-
- ret = wm8955_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
- goto err_enable;
- }
-
- /* Change some default settings - latch VU and enable ZC */
- snd_soc_update_bits(codec, WM8955_LEFT_DAC_VOLUME,
- WM8955_LDVU, WM8955_LDVU);
- snd_soc_update_bits(codec, WM8955_RIGHT_DAC_VOLUME,
- WM8955_RDVU, WM8955_RDVU);
- snd_soc_update_bits(codec, WM8955_LOUT1_VOLUME,
- WM8955_LO1VU | WM8955_LO1ZC,
- WM8955_LO1VU | WM8955_LO1ZC);
- snd_soc_update_bits(codec, WM8955_ROUT1_VOLUME,
- WM8955_RO1VU | WM8955_RO1ZC,
- WM8955_RO1VU | WM8955_RO1ZC);
- snd_soc_update_bits(codec, WM8955_LOUT2_VOLUME,
- WM8955_LO2VU | WM8955_LO2ZC,
- WM8955_LO2VU | WM8955_LO2ZC);
- snd_soc_update_bits(codec, WM8955_ROUT2_VOLUME,
- WM8955_RO2VU | WM8955_RO2ZC,
- WM8955_RO2VU | WM8955_RO2ZC);
- snd_soc_update_bits(codec, WM8955_MONOOUT_VOLUME,
- WM8955_MOZC, WM8955_MOZC);
-
- /* Also enable adaptive bass boost by default */
- snd_soc_update_bits(codec, WM8955_BASS_CONTROL, WM8955_BB, WM8955_BB);
-
- /* Set platform data values */
- if (pdata) {
- if (pdata->out2_speaker)
- snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_2,
- WM8955_ROUT2INV, WM8955_ROUT2INV);
-
- if (pdata->monoin_diff)
- snd_soc_update_bits(codec, WM8955_MONO_OUT_MIX_1,
- WM8955_DMEN, WM8955_DMEN);
- }
-
- wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* Bias level configuration will have done an extra enable */
- regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
-
- return 0;
-
-err_enable:
- regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
-err_get:
- regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
- return ret;
-}
-
-static int wm8955_remove(struct snd_soc_codec *codec)
-{
- struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
-
- wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF);
- regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8955 = {
- .probe = wm8955_probe,
- .remove = wm8955_remove,
- .suspend = wm8955_suspend,
- .resume = wm8955_resume,
- .set_bias_level = wm8955_set_bias_level,
-
- .controls = wm8955_snd_controls,
- .num_controls = ARRAY_SIZE(wm8955_snd_controls),
- .dapm_widgets = wm8955_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8955_dapm_widgets),
- .dapm_routes = wm8955_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm8955_dapm_routes),
-};
-
-static const struct regmap_config wm8955_regmap = {
- .reg_bits = 7,
- .val_bits = 9,
-
- .max_register = WM8955_MAX_REGISTER,
- .volatile_reg = wm8955_volatile,
- .writeable_reg = wm8955_writeable,
-
- .cache_type = REGCACHE_RBTREE,
- .reg_defaults = wm8955_reg_defaults,
- .num_reg_defaults = ARRAY_SIZE(wm8955_reg_defaults),
-};
-
-static __devinit int wm8955_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8955_priv *wm8955;
- int ret;
-
- wm8955 = devm_kzalloc(&i2c->dev, sizeof(struct wm8955_priv),
- GFP_KERNEL);
- if (wm8955 == NULL)
- return -ENOMEM;
-
- wm8955->regmap = regmap_init_i2c(i2c, &wm8955_regmap);
- if (IS_ERR(wm8955->regmap)) {
- ret = PTR_ERR(wm8955->regmap);
- dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
- ret);
- return ret;
- }
-
- i2c_set_clientdata(i2c, wm8955);
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8955, &wm8955_dai, 1);
- if (ret != 0)
- goto err;
-
- return ret;
-
-err:
- regmap_exit(wm8955->regmap);
- return ret;
-}
-
-static __devexit int wm8955_i2c_remove(struct i2c_client *client)
-{
- struct wm8955_priv *wm8955 = i2c_get_clientdata(client);
-
- snd_soc_unregister_codec(&client->dev);
- regmap_exit(wm8955->regmap);
-
- return 0;
-}
-
-static const struct i2c_device_id wm8955_i2c_id[] = {
- { "wm8955", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8955_i2c_id);
-
-static struct i2c_driver wm8955_i2c_driver = {
- .driver = {
- .name = "wm8955",
- .owner = THIS_MODULE,
- },
- .probe = wm8955_i2c_probe,
- .remove = __devexit_p(wm8955_i2c_remove),
- .id_table = wm8955_i2c_id,
-};
-
-static int __init wm8955_modinit(void)
-{
- int ret = 0;
- ret = i2c_add_driver(&wm8955_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8955 I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(wm8955_modinit);
-
-static void __exit wm8955_exit(void)
-{
- i2c_del_driver(&wm8955_i2c_driver);
-}
-module_exit(wm8955_exit);
-
-MODULE_DESCRIPTION("ASoC WM8955 driver");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8955.h b/ANDROID_3.4.5/sound/soc/codecs/wm8955.h
deleted file mode 100644
index d13fd5c5..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8955.h
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * wm8955.h -- WM8904 ASoC driver
- *
- * Copyright 2009 Wolfson Microelectronics, plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8955_H
-#define _WM8955_H
-
-#define WM8955_CLK_MCLK 1
-
-/*
- * Register values.
- */
-#define WM8955_LOUT1_VOLUME 0x02
-#define WM8955_ROUT1_VOLUME 0x03
-#define WM8955_DAC_CONTROL 0x05
-#define WM8955_AUDIO_INTERFACE 0x07
-#define WM8955_SAMPLE_RATE 0x08
-#define WM8955_LEFT_DAC_VOLUME 0x0A
-#define WM8955_RIGHT_DAC_VOLUME 0x0B
-#define WM8955_BASS_CONTROL 0x0C
-#define WM8955_TREBLE_CONTROL 0x0D
-#define WM8955_RESET 0x0F
-#define WM8955_ADDITIONAL_CONTROL_1 0x17
-#define WM8955_ADDITIONAL_CONTROL_2 0x18
-#define WM8955_POWER_MANAGEMENT_1 0x19
-#define WM8955_POWER_MANAGEMENT_2 0x1A
-#define WM8955_ADDITIONAL_CONTROL_3 0x1B
-#define WM8955_LEFT_OUT_MIX_1 0x22
-#define WM8955_LEFT_OUT_MIX_2 0x23
-#define WM8955_RIGHT_OUT_MIX_1 0x24
-#define WM8955_RIGHT_OUT_MIX_2 0x25
-#define WM8955_MONO_OUT_MIX_1 0x26
-#define WM8955_MONO_OUT_MIX_2 0x27
-#define WM8955_LOUT2_VOLUME 0x28
-#define WM8955_ROUT2_VOLUME 0x29
-#define WM8955_MONOOUT_VOLUME 0x2A
-#define WM8955_CLOCKING_PLL 0x2B
-#define WM8955_PLL_CONTROL_1 0x2C
-#define WM8955_PLL_CONTROL_2 0x2D
-#define WM8955_PLL_CONTROL_3 0x2E
-#define WM8955_PLL_CONTROL_4 0x3B
-
-#define WM8955_REGISTER_COUNT 29
-#define WM8955_MAX_REGISTER 0x3B
-
-/*
- * Field Definitions.
- */
-
-/*
- * R2 (0x02) - LOUT1 volume
- */
-#define WM8955_LO1VU 0x0100 /* LO1VU */
-#define WM8955_LO1VU_MASK 0x0100 /* LO1VU */
-#define WM8955_LO1VU_SHIFT 8 /* LO1VU */
-#define WM8955_LO1VU_WIDTH 1 /* LO1VU */
-#define WM8955_LO1ZC 0x0080 /* LO1ZC */
-#define WM8955_LO1ZC_MASK 0x0080 /* LO1ZC */
-#define WM8955_LO1ZC_SHIFT 7 /* LO1ZC */
-#define WM8955_LO1ZC_WIDTH 1 /* LO1ZC */
-#define WM8955_LOUTVOL_MASK 0x007F /* LOUTVOL - [6:0] */
-#define WM8955_LOUTVOL_SHIFT 0 /* LOUTVOL - [6:0] */
-#define WM8955_LOUTVOL_WIDTH 7 /* LOUTVOL - [6:0] */
-
-/*
- * R3 (0x03) - ROUT1 volume
- */
-#define WM8955_RO1VU 0x0100 /* RO1VU */
-#define WM8955_RO1VU_MASK 0x0100 /* RO1VU */
-#define WM8955_RO1VU_SHIFT 8 /* RO1VU */
-#define WM8955_RO1VU_WIDTH 1 /* RO1VU */
-#define WM8955_RO1ZC 0x0080 /* RO1ZC */
-#define WM8955_RO1ZC_MASK 0x0080 /* RO1ZC */
-#define WM8955_RO1ZC_SHIFT 7 /* RO1ZC */
-#define WM8955_RO1ZC_WIDTH 1 /* RO1ZC */
-#define WM8955_ROUTVOL_MASK 0x007F /* ROUTVOL - [6:0] */
-#define WM8955_ROUTVOL_SHIFT 0 /* ROUTVOL - [6:0] */
-#define WM8955_ROUTVOL_WIDTH 7 /* ROUTVOL - [6:0] */
-
-/*
- * R5 (0x05) - DAC Control
- */
-#define WM8955_DAT 0x0080 /* DAT */
-#define WM8955_DAT_MASK 0x0080 /* DAT */
-#define WM8955_DAT_SHIFT 7 /* DAT */
-#define WM8955_DAT_WIDTH 1 /* DAT */
-#define WM8955_DACMU 0x0008 /* DACMU */
-#define WM8955_DACMU_MASK 0x0008 /* DACMU */
-#define WM8955_DACMU_SHIFT 3 /* DACMU */
-#define WM8955_DACMU_WIDTH 1 /* DACMU */
-#define WM8955_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */
-#define WM8955_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */
-#define WM8955_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */
-
-/*
- * R7 (0x07) - Audio Interface
- */
-#define WM8955_BCLKINV 0x0080 /* BCLKINV */
-#define WM8955_BCLKINV_MASK 0x0080 /* BCLKINV */
-#define WM8955_BCLKINV_SHIFT 7 /* BCLKINV */
-#define WM8955_BCLKINV_WIDTH 1 /* BCLKINV */
-#define WM8955_MS 0x0040 /* MS */
-#define WM8955_MS_MASK 0x0040 /* MS */
-#define WM8955_MS_SHIFT 6 /* MS */
-#define WM8955_MS_WIDTH 1 /* MS */
-#define WM8955_LRSWAP 0x0020 /* LRSWAP */
-#define WM8955_LRSWAP_MASK 0x0020 /* LRSWAP */
-#define WM8955_LRSWAP_SHIFT 5 /* LRSWAP */
-#define WM8955_LRSWAP_WIDTH 1 /* LRSWAP */
-#define WM8955_LRP 0x0010 /* LRP */
-#define WM8955_LRP_MASK 0x0010 /* LRP */
-#define WM8955_LRP_SHIFT 4 /* LRP */
-#define WM8955_LRP_WIDTH 1 /* LRP */
-#define WM8955_WL_MASK 0x000C /* WL - [3:2] */
-#define WM8955_WL_SHIFT 2 /* WL - [3:2] */
-#define WM8955_WL_WIDTH 2 /* WL - [3:2] */
-#define WM8955_FORMAT_MASK 0x0003 /* FORMAT - [1:0] */
-#define WM8955_FORMAT_SHIFT 0 /* FORMAT - [1:0] */
-#define WM8955_FORMAT_WIDTH 2 /* FORMAT - [1:0] */
-
-/*
- * R8 (0x08) - Sample Rate
- */
-#define WM8955_BCLKDIV2 0x0080 /* BCLKDIV2 */
-#define WM8955_BCLKDIV2_MASK 0x0080 /* BCLKDIV2 */
-#define WM8955_BCLKDIV2_SHIFT 7 /* BCLKDIV2 */
-#define WM8955_BCLKDIV2_WIDTH 1 /* BCLKDIV2 */
-#define WM8955_MCLKDIV2 0x0040 /* MCLKDIV2 */
-#define WM8955_MCLKDIV2_MASK 0x0040 /* MCLKDIV2 */
-#define WM8955_MCLKDIV2_SHIFT 6 /* MCLKDIV2 */
-#define WM8955_MCLKDIV2_WIDTH 1 /* MCLKDIV2 */
-#define WM8955_SR_MASK 0x003E /* SR - [5:1] */
-#define WM8955_SR_SHIFT 1 /* SR - [5:1] */
-#define WM8955_SR_WIDTH 5 /* SR - [5:1] */
-#define WM8955_USB 0x0001 /* USB */
-#define WM8955_USB_MASK 0x0001 /* USB */
-#define WM8955_USB_SHIFT 0 /* USB */
-#define WM8955_USB_WIDTH 1 /* USB */
-
-/*
- * R10 (0x0A) - Left DAC volume
- */
-#define WM8955_LDVU 0x0100 /* LDVU */
-#define WM8955_LDVU_MASK 0x0100 /* LDVU */
-#define WM8955_LDVU_SHIFT 8 /* LDVU */
-#define WM8955_LDVU_WIDTH 1 /* LDVU */
-#define WM8955_LDACVOL_MASK 0x00FF /* LDACVOL - [7:0] */
-#define WM8955_LDACVOL_SHIFT 0 /* LDACVOL - [7:0] */
-#define WM8955_LDACVOL_WIDTH 8 /* LDACVOL - [7:0] */
-
-/*
- * R11 (0x0B) - Right DAC volume
- */
-#define WM8955_RDVU 0x0100 /* RDVU */
-#define WM8955_RDVU_MASK 0x0100 /* RDVU */
-#define WM8955_RDVU_SHIFT 8 /* RDVU */
-#define WM8955_RDVU_WIDTH 1 /* RDVU */
-#define WM8955_RDACVOL_MASK 0x00FF /* RDACVOL - [7:0] */
-#define WM8955_RDACVOL_SHIFT 0 /* RDACVOL - [7:0] */
-#define WM8955_RDACVOL_WIDTH 8 /* RDACVOL - [7:0] */
-
-/*
- * R12 (0x0C) - Bass control
- */
-#define WM8955_BB 0x0080 /* BB */
-#define WM8955_BB_MASK 0x0080 /* BB */
-#define WM8955_BB_SHIFT 7 /* BB */
-#define WM8955_BB_WIDTH 1 /* BB */
-#define WM8955_BC 0x0040 /* BC */
-#define WM8955_BC_MASK 0x0040 /* BC */
-#define WM8955_BC_SHIFT 6 /* BC */
-#define WM8955_BC_WIDTH 1 /* BC */
-#define WM8955_BASS_MASK 0x000F /* BASS - [3:0] */
-#define WM8955_BASS_SHIFT 0 /* BASS - [3:0] */
-#define WM8955_BASS_WIDTH 4 /* BASS - [3:0] */
-
-/*
- * R13 (0x0D) - Treble control
- */
-#define WM8955_TC 0x0040 /* TC */
-#define WM8955_TC_MASK 0x0040 /* TC */
-#define WM8955_TC_SHIFT 6 /* TC */
-#define WM8955_TC_WIDTH 1 /* TC */
-#define WM8955_TRBL_MASK 0x000F /* TRBL - [3:0] */
-#define WM8955_TRBL_SHIFT 0 /* TRBL - [3:0] */
-#define WM8955_TRBL_WIDTH 4 /* TRBL - [3:0] */
-
-/*
- * R15 (0x0F) - Reset
- */
-#define WM8955_RESET_MASK 0x01FF /* RESET - [8:0] */
-#define WM8955_RESET_SHIFT 0 /* RESET - [8:0] */
-#define WM8955_RESET_WIDTH 9 /* RESET - [8:0] */
-
-/*
- * R23 (0x17) - Additional control (1)
- */
-#define WM8955_TSDEN 0x0100 /* TSDEN */
-#define WM8955_TSDEN_MASK 0x0100 /* TSDEN */
-#define WM8955_TSDEN_SHIFT 8 /* TSDEN */
-#define WM8955_TSDEN_WIDTH 1 /* TSDEN */
-#define WM8955_VSEL_MASK 0x00C0 /* VSEL - [7:6] */
-#define WM8955_VSEL_SHIFT 6 /* VSEL - [7:6] */
-#define WM8955_VSEL_WIDTH 2 /* VSEL - [7:6] */
-#define WM8955_DMONOMIX_MASK 0x0030 /* DMONOMIX - [5:4] */
-#define WM8955_DMONOMIX_SHIFT 4 /* DMONOMIX - [5:4] */
-#define WM8955_DMONOMIX_WIDTH 2 /* DMONOMIX - [5:4] */
-#define WM8955_DACINV 0x0002 /* DACINV */
-#define WM8955_DACINV_MASK 0x0002 /* DACINV */
-#define WM8955_DACINV_SHIFT 1 /* DACINV */
-#define WM8955_DACINV_WIDTH 1 /* DACINV */
-#define WM8955_TOEN 0x0001 /* TOEN */
-#define WM8955_TOEN_MASK 0x0001 /* TOEN */
-#define WM8955_TOEN_SHIFT 0 /* TOEN */
-#define WM8955_TOEN_WIDTH 1 /* TOEN */
-
-/*
- * R24 (0x18) - Additional control (2)
- */
-#define WM8955_OUT3SW_MASK 0x0180 /* OUT3SW - [8:7] */
-#define WM8955_OUT3SW_SHIFT 7 /* OUT3SW - [8:7] */
-#define WM8955_OUT3SW_WIDTH 2 /* OUT3SW - [8:7] */
-#define WM8955_ROUT2INV 0x0010 /* ROUT2INV */
-#define WM8955_ROUT2INV_MASK 0x0010 /* ROUT2INV */
-#define WM8955_ROUT2INV_SHIFT 4 /* ROUT2INV */
-#define WM8955_ROUT2INV_WIDTH 1 /* ROUT2INV */
-#define WM8955_DACOSR 0x0001 /* DACOSR */
-#define WM8955_DACOSR_MASK 0x0001 /* DACOSR */
-#define WM8955_DACOSR_SHIFT 0 /* DACOSR */
-#define WM8955_DACOSR_WIDTH 1 /* DACOSR */
-
-/*
- * R25 (0x19) - Power Management (1)
- */
-#define WM8955_VMIDSEL_MASK 0x0180 /* VMIDSEL - [8:7] */
-#define WM8955_VMIDSEL_SHIFT 7 /* VMIDSEL - [8:7] */
-#define WM8955_VMIDSEL_WIDTH 2 /* VMIDSEL - [8:7] */
-#define WM8955_VREF 0x0040 /* VREF */
-#define WM8955_VREF_MASK 0x0040 /* VREF */
-#define WM8955_VREF_SHIFT 6 /* VREF */
-#define WM8955_VREF_WIDTH 1 /* VREF */
-#define WM8955_DIGENB 0x0001 /* DIGENB */
-#define WM8955_DIGENB_MASK 0x0001 /* DIGENB */
-#define WM8955_DIGENB_SHIFT 0 /* DIGENB */
-#define WM8955_DIGENB_WIDTH 1 /* DIGENB */
-
-/*
- * R26 (0x1A) - Power Management (2)
- */
-#define WM8955_DACL 0x0100 /* DACL */
-#define WM8955_DACL_MASK 0x0100 /* DACL */
-#define WM8955_DACL_SHIFT 8 /* DACL */
-#define WM8955_DACL_WIDTH 1 /* DACL */
-#define WM8955_DACR 0x0080 /* DACR */
-#define WM8955_DACR_MASK 0x0080 /* DACR */
-#define WM8955_DACR_SHIFT 7 /* DACR */
-#define WM8955_DACR_WIDTH 1 /* DACR */
-#define WM8955_LOUT1 0x0040 /* LOUT1 */
-#define WM8955_LOUT1_MASK 0x0040 /* LOUT1 */
-#define WM8955_LOUT1_SHIFT 6 /* LOUT1 */
-#define WM8955_LOUT1_WIDTH 1 /* LOUT1 */
-#define WM8955_ROUT1 0x0020 /* ROUT1 */
-#define WM8955_ROUT1_MASK 0x0020 /* ROUT1 */
-#define WM8955_ROUT1_SHIFT 5 /* ROUT1 */
-#define WM8955_ROUT1_WIDTH 1 /* ROUT1 */
-#define WM8955_LOUT2 0x0010 /* LOUT2 */
-#define WM8955_LOUT2_MASK 0x0010 /* LOUT2 */
-#define WM8955_LOUT2_SHIFT 4 /* LOUT2 */
-#define WM8955_LOUT2_WIDTH 1 /* LOUT2 */
-#define WM8955_ROUT2 0x0008 /* ROUT2 */
-#define WM8955_ROUT2_MASK 0x0008 /* ROUT2 */
-#define WM8955_ROUT2_SHIFT 3 /* ROUT2 */
-#define WM8955_ROUT2_WIDTH 1 /* ROUT2 */
-#define WM8955_MONO 0x0004 /* MONO */
-#define WM8955_MONO_MASK 0x0004 /* MONO */
-#define WM8955_MONO_SHIFT 2 /* MONO */
-#define WM8955_MONO_WIDTH 1 /* MONO */
-#define WM8955_OUT3 0x0002 /* OUT3 */
-#define WM8955_OUT3_MASK 0x0002 /* OUT3 */
-#define WM8955_OUT3_SHIFT 1 /* OUT3 */
-#define WM8955_OUT3_WIDTH 1 /* OUT3 */
-
-/*
- * R27 (0x1B) - Additional Control (3)
- */
-#define WM8955_VROI 0x0040 /* VROI */
-#define WM8955_VROI_MASK 0x0040 /* VROI */
-#define WM8955_VROI_SHIFT 6 /* VROI */
-#define WM8955_VROI_WIDTH 1 /* VROI */
-
-/*
- * R34 (0x22) - Left out Mix (1)
- */
-#define WM8955_LD2LO 0x0100 /* LD2LO */
-#define WM8955_LD2LO_MASK 0x0100 /* LD2LO */
-#define WM8955_LD2LO_SHIFT 8 /* LD2LO */
-#define WM8955_LD2LO_WIDTH 1 /* LD2LO */
-#define WM8955_LI2LO 0x0080 /* LI2LO */
-#define WM8955_LI2LO_MASK 0x0080 /* LI2LO */
-#define WM8955_LI2LO_SHIFT 7 /* LI2LO */
-#define WM8955_LI2LO_WIDTH 1 /* LI2LO */
-#define WM8955_LI2LOVOL_MASK 0x0070 /* LI2LOVOL - [6:4] */
-#define WM8955_LI2LOVOL_SHIFT 4 /* LI2LOVOL - [6:4] */
-#define WM8955_LI2LOVOL_WIDTH 3 /* LI2LOVOL - [6:4] */
-
-/*
- * R35 (0x23) - Left out Mix (2)
- */
-#define WM8955_RD2LO 0x0100 /* RD2LO */
-#define WM8955_RD2LO_MASK 0x0100 /* RD2LO */
-#define WM8955_RD2LO_SHIFT 8 /* RD2LO */
-#define WM8955_RD2LO_WIDTH 1 /* RD2LO */
-#define WM8955_RI2LO 0x0080 /* RI2LO */
-#define WM8955_RI2LO_MASK 0x0080 /* RI2LO */
-#define WM8955_RI2LO_SHIFT 7 /* RI2LO */
-#define WM8955_RI2LO_WIDTH 1 /* RI2LO */
-#define WM8955_RI2LOVOL_MASK 0x0070 /* RI2LOVOL - [6:4] */
-#define WM8955_RI2LOVOL_SHIFT 4 /* RI2LOVOL - [6:4] */
-#define WM8955_RI2LOVOL_WIDTH 3 /* RI2LOVOL - [6:4] */
-
-/*
- * R36 (0x24) - Right out Mix (1)
- */
-#define WM8955_LD2RO 0x0100 /* LD2RO */
-#define WM8955_LD2RO_MASK 0x0100 /* LD2RO */
-#define WM8955_LD2RO_SHIFT 8 /* LD2RO */
-#define WM8955_LD2RO_WIDTH 1 /* LD2RO */
-#define WM8955_LI2RO 0x0080 /* LI2RO */
-#define WM8955_LI2RO_MASK 0x0080 /* LI2RO */
-#define WM8955_LI2RO_SHIFT 7 /* LI2RO */
-#define WM8955_LI2RO_WIDTH 1 /* LI2RO */
-#define WM8955_LI2ROVOL_MASK 0x0070 /* LI2ROVOL - [6:4] */
-#define WM8955_LI2ROVOL_SHIFT 4 /* LI2ROVOL - [6:4] */
-#define WM8955_LI2ROVOL_WIDTH 3 /* LI2ROVOL - [6:4] */
-
-/*
- * R37 (0x25) - Right Out Mix (2)
- */
-#define WM8955_RD2RO 0x0100 /* RD2RO */
-#define WM8955_RD2RO_MASK 0x0100 /* RD2RO */
-#define WM8955_RD2RO_SHIFT 8 /* RD2RO */
-#define WM8955_RD2RO_WIDTH 1 /* RD2RO */
-#define WM8955_RI2RO 0x0080 /* RI2RO */
-#define WM8955_RI2RO_MASK 0x0080 /* RI2RO */
-#define WM8955_RI2RO_SHIFT 7 /* RI2RO */
-#define WM8955_RI2RO_WIDTH 1 /* RI2RO */
-#define WM8955_RI2ROVOL_MASK 0x0070 /* RI2ROVOL - [6:4] */
-#define WM8955_RI2ROVOL_SHIFT 4 /* RI2ROVOL - [6:4] */
-#define WM8955_RI2ROVOL_WIDTH 3 /* RI2ROVOL - [6:4] */
-
-/*
- * R38 (0x26) - Mono out Mix (1)
- */
-#define WM8955_LD2MO 0x0100 /* LD2MO */
-#define WM8955_LD2MO_MASK 0x0100 /* LD2MO */
-#define WM8955_LD2MO_SHIFT 8 /* LD2MO */
-#define WM8955_LD2MO_WIDTH 1 /* LD2MO */
-#define WM8955_LI2MO 0x0080 /* LI2MO */
-#define WM8955_LI2MO_MASK 0x0080 /* LI2MO */
-#define WM8955_LI2MO_SHIFT 7 /* LI2MO */
-#define WM8955_LI2MO_WIDTH 1 /* LI2MO */
-#define WM8955_LI2MOVOL_MASK 0x0070 /* LI2MOVOL - [6:4] */
-#define WM8955_LI2MOVOL_SHIFT 4 /* LI2MOVOL - [6:4] */
-#define WM8955_LI2MOVOL_WIDTH 3 /* LI2MOVOL - [6:4] */
-#define WM8955_DMEN 0x0001 /* DMEN */
-#define WM8955_DMEN_MASK 0x0001 /* DMEN */
-#define WM8955_DMEN_SHIFT 0 /* DMEN */
-#define WM8955_DMEN_WIDTH 1 /* DMEN */
-
-/*
- * R39 (0x27) - Mono out Mix (2)
- */
-#define WM8955_RD2MO 0x0100 /* RD2MO */
-#define WM8955_RD2MO_MASK 0x0100 /* RD2MO */
-#define WM8955_RD2MO_SHIFT 8 /* RD2MO */
-#define WM8955_RD2MO_WIDTH 1 /* RD2MO */
-#define WM8955_RI2MO 0x0080 /* RI2MO */
-#define WM8955_RI2MO_MASK 0x0080 /* RI2MO */
-#define WM8955_RI2MO_SHIFT 7 /* RI2MO */
-#define WM8955_RI2MO_WIDTH 1 /* RI2MO */
-#define WM8955_RI2MOVOL_MASK 0x0070 /* RI2MOVOL - [6:4] */
-#define WM8955_RI2MOVOL_SHIFT 4 /* RI2MOVOL - [6:4] */
-#define WM8955_RI2MOVOL_WIDTH 3 /* RI2MOVOL - [6:4] */
-
-/*
- * R40 (0x28) - LOUT2 volume
- */
-#define WM8955_LO2VU 0x0100 /* LO2VU */
-#define WM8955_LO2VU_MASK 0x0100 /* LO2VU */
-#define WM8955_LO2VU_SHIFT 8 /* LO2VU */
-#define WM8955_LO2VU_WIDTH 1 /* LO2VU */
-#define WM8955_LO2ZC 0x0080 /* LO2ZC */
-#define WM8955_LO2ZC_MASK 0x0080 /* LO2ZC */
-#define WM8955_LO2ZC_SHIFT 7 /* LO2ZC */
-#define WM8955_LO2ZC_WIDTH 1 /* LO2ZC */
-#define WM8955_LOUT2VOL_MASK 0x007F /* LOUT2VOL - [6:0] */
-#define WM8955_LOUT2VOL_SHIFT 0 /* LOUT2VOL - [6:0] */
-#define WM8955_LOUT2VOL_WIDTH 7 /* LOUT2VOL - [6:0] */
-
-/*
- * R41 (0x29) - ROUT2 volume
- */
-#define WM8955_RO2VU 0x0100 /* RO2VU */
-#define WM8955_RO2VU_MASK 0x0100 /* RO2VU */
-#define WM8955_RO2VU_SHIFT 8 /* RO2VU */
-#define WM8955_RO2VU_WIDTH 1 /* RO2VU */
-#define WM8955_RO2ZC 0x0080 /* RO2ZC */
-#define WM8955_RO2ZC_MASK 0x0080 /* RO2ZC */
-#define WM8955_RO2ZC_SHIFT 7 /* RO2ZC */
-#define WM8955_RO2ZC_WIDTH 1 /* RO2ZC */
-#define WM8955_ROUT2VOL_MASK 0x007F /* ROUT2VOL - [6:0] */
-#define WM8955_ROUT2VOL_SHIFT 0 /* ROUT2VOL - [6:0] */
-#define WM8955_ROUT2VOL_WIDTH 7 /* ROUT2VOL - [6:0] */
-
-/*
- * R42 (0x2A) - MONOOUT volume
- */
-#define WM8955_MOZC 0x0080 /* MOZC */
-#define WM8955_MOZC_MASK 0x0080 /* MOZC */
-#define WM8955_MOZC_SHIFT 7 /* MOZC */
-#define WM8955_MOZC_WIDTH 1 /* MOZC */
-#define WM8955_MOUTVOL_MASK 0x007F /* MOUTVOL - [6:0] */
-#define WM8955_MOUTVOL_SHIFT 0 /* MOUTVOL - [6:0] */
-#define WM8955_MOUTVOL_WIDTH 7 /* MOUTVOL - [6:0] */
-
-/*
- * R43 (0x2B) - Clocking / PLL
- */
-#define WM8955_MCLKSEL 0x0100 /* MCLKSEL */
-#define WM8955_MCLKSEL_MASK 0x0100 /* MCLKSEL */
-#define WM8955_MCLKSEL_SHIFT 8 /* MCLKSEL */
-#define WM8955_MCLKSEL_WIDTH 1 /* MCLKSEL */
-#define WM8955_PLLOUTDIV2 0x0020 /* PLLOUTDIV2 */
-#define WM8955_PLLOUTDIV2_MASK 0x0020 /* PLLOUTDIV2 */
-#define WM8955_PLLOUTDIV2_SHIFT 5 /* PLLOUTDIV2 */
-#define WM8955_PLLOUTDIV2_WIDTH 1 /* PLLOUTDIV2 */
-#define WM8955_PLL_RB 0x0010 /* PLL_RB */
-#define WM8955_PLL_RB_MASK 0x0010 /* PLL_RB */
-#define WM8955_PLL_RB_SHIFT 4 /* PLL_RB */
-#define WM8955_PLL_RB_WIDTH 1 /* PLL_RB */
-#define WM8955_PLLEN 0x0008 /* PLLEN */
-#define WM8955_PLLEN_MASK 0x0008 /* PLLEN */
-#define WM8955_PLLEN_SHIFT 3 /* PLLEN */
-#define WM8955_PLLEN_WIDTH 1 /* PLLEN */
-
-/*
- * R44 (0x2C) - PLL Control 1
- */
-#define WM8955_N_MASK 0x01E0 /* N - [8:5] */
-#define WM8955_N_SHIFT 5 /* N - [8:5] */
-#define WM8955_N_WIDTH 4 /* N - [8:5] */
-#define WM8955_K_21_18_MASK 0x000F /* K(21:18) - [3:0] */
-#define WM8955_K_21_18_SHIFT 0 /* K(21:18) - [3:0] */
-#define WM8955_K_21_18_WIDTH 4 /* K(21:18) - [3:0] */
-
-/*
- * R45 (0x2D) - PLL Control 2
- */
-#define WM8955_K_17_9_MASK 0x01FF /* K(17:9) - [8:0] */
-#define WM8955_K_17_9_SHIFT 0 /* K(17:9) - [8:0] */
-#define WM8955_K_17_9_WIDTH 9 /* K(17:9) - [8:0] */
-
-/*
- * R46 (0x2E) - PLL Control 3
- */
-#define WM8955_K_8_0_MASK 0x01FF /* K(8:0) - [8:0] */
-#define WM8955_K_8_0_SHIFT 0 /* K(8:0) - [8:0] */
-#define WM8955_K_8_0_WIDTH 9 /* K(8:0) - [8:0] */
-
-/*
- * R59 (0x3B) - PLL Control 4
- */
-#define WM8955_KEN 0x0080 /* KEN */
-#define WM8955_KEN_MASK 0x0080 /* KEN */
-#define WM8955_KEN_SHIFT 7 /* KEN */
-#define WM8955_KEN_WIDTH 1 /* KEN */
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8958-dsp2.c b/ANDROID_3.4.5/sound/soc/codecs/wm8958-dsp2.c
deleted file mode 100644
index 1332692e..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8958-dsp2.c
+++ /dev/null
@@ -1,1054 +0,0 @@
-/*
- * wm8958-dsp2.c -- WM8958 DSP2 support
- *
- * Copyright 2011 Wolfson Microelectronics plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <trace/events/asoc.h>
-
-#include <linux/mfd/wm8994/core.h>
-#include <linux/mfd/wm8994/registers.h>
-#include <linux/mfd/wm8994/pdata.h>
-#include <linux/mfd/wm8994/gpio.h>
-
-#include "wm8994.h"
-
-#define WM_FW_BLOCK_INFO 0xff
-#define WM_FW_BLOCK_PM 0x00
-#define WM_FW_BLOCK_X 0x01
-#define WM_FW_BLOCK_Y 0x02
-#define WM_FW_BLOCK_Z 0x03
-#define WM_FW_BLOCK_I 0x06
-#define WM_FW_BLOCK_A 0x08
-#define WM_FW_BLOCK_C 0x0c
-
-static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name,
- const struct firmware *fw, bool check)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- u64 data64;
- u32 data32;
- const u8 *data;
- char *str;
- size_t block_len, len;
- int ret = 0;
-
- /* Suppress unneeded downloads */
- if (wm8994->cur_fw == fw)
- return 0;
-
- if (fw->size < 32) {
- dev_err(codec->dev, "%s: firmware too short (%zd bytes)\n",
- name, fw->size);
- goto err;
- }
-
- if (memcmp(fw->data, "WMFW", 4) != 0) {
- memcpy(&data32, fw->data, sizeof(data32));
- data32 = be32_to_cpu(data32);
- dev_err(codec->dev, "%s: firmware has bad file magic %08x\n",
- name, data32);
- goto err;
- }
-
- memcpy(&data32, fw->data + 4, sizeof(data32));
- len = be32_to_cpu(data32);
-
- memcpy(&data32, fw->data + 8, sizeof(data32));
- data32 = be32_to_cpu(data32);
- if ((data32 >> 24) & 0xff) {
- dev_err(codec->dev, "%s: unsupported firmware version %d\n",
- name, (data32 >> 24) & 0xff);
- goto err;
- }
- if ((data32 & 0xffff) != 8958) {
- dev_err(codec->dev, "%s: unsupported target device %d\n",
- name, data32 & 0xffff);
- goto err;
- }
- if (((data32 >> 16) & 0xff) != 0xc) {
- dev_err(codec->dev, "%s: unsupported target core %d\n",
- name, (data32 >> 16) & 0xff);
- goto err;
- }
-
- if (check) {
- memcpy(&data64, fw->data + 24, sizeof(u64));
- dev_info(codec->dev, "%s timestamp %llx\n",
- name, be64_to_cpu(data64));
- } else {
- snd_soc_write(codec, 0x102, 0x2);
- snd_soc_write(codec, 0x900, 0x2);
- }
-
- data = fw->data + len;
- len = fw->size - len;
- while (len) {
- if (len < 12) {
- dev_err(codec->dev, "%s short data block of %zd\n",
- name, len);
- goto err;
- }
-
- memcpy(&data32, data + 4, sizeof(data32));
- block_len = be32_to_cpu(data32);
- if (block_len + 8 > len) {
- dev_err(codec->dev, "%zd byte block longer than file\n",
- block_len);
- goto err;
- }
- if (block_len == 0) {
- dev_err(codec->dev, "Zero length block\n");
- goto err;
- }
-
- memcpy(&data32, data, sizeof(data32));
- data32 = be32_to_cpu(data32);
-
- switch ((data32 >> 24) & 0xff) {
- case WM_FW_BLOCK_INFO:
- /* Informational text */
- if (!check)
- break;
-
- str = kzalloc(block_len + 1, GFP_KERNEL);
- if (str) {
- memcpy(str, data + 8, block_len);
- dev_info(codec->dev, "%s: %s\n", name, str);
- kfree(str);
- } else {
- dev_err(codec->dev, "Out of memory\n");
- }
- break;
- case WM_FW_BLOCK_PM:
- case WM_FW_BLOCK_X:
- case WM_FW_BLOCK_Y:
- case WM_FW_BLOCK_Z:
- case WM_FW_BLOCK_I:
- case WM_FW_BLOCK_A:
- case WM_FW_BLOCK_C:
- dev_dbg(codec->dev, "%s: %zd bytes of %x@%x\n", name,
- block_len, (data32 >> 24) & 0xff,
- data32 & 0xffffff);
-
- if (check)
- break;
-
- data32 &= 0xffffff;
-
- wm8994_bulk_write(codec->control_data,
- data32 & 0xffffff,
- block_len / 2,
- (void *)(data + 8));
-
- break;
- default:
- dev_warn(codec->dev, "%s: unknown block type %d\n",
- name, (data32 >> 24) & 0xff);
- break;
- }
-
- /* Round up to the next 32 bit word */
- block_len += block_len % 4;
-
- data += block_len + 8;
- len -= block_len + 8;
- }
-
- if (!check) {
- dev_dbg(codec->dev, "%s: download done\n", name);
- wm8994->cur_fw = fw;
- } else {
- dev_info(codec->dev, "%s: got firmware\n", name);
- }
-
- goto ok;
-
-err:
- ret = -EINVAL;
-ok:
- if (!check) {
- snd_soc_write(codec, 0x900, 0x0);
- snd_soc_write(codec, 0x102, 0x0);
- }
-
- return ret;
-}
-
-static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994_pdata *pdata = wm8994->pdata;
- int i;
-
- /* If the DSP is already running then noop */
- if (snd_soc_read(codec, WM8958_DSP2_PROGRAM) & WM8958_DSP2_ENA)
- return;
-
- /* If we have MBC firmware download it */
- if (wm8994->mbc)
- wm8958_dsp2_fw(codec, "MBC", wm8994->mbc, false);
-
- snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
- WM8958_DSP2_ENA, WM8958_DSP2_ENA);
-
- /* If we've got user supplied MBC settings use them */
- if (pdata && pdata->num_mbc_cfgs) {
- struct wm8958_mbc_cfg *cfg
- = &pdata->mbc_cfgs[wm8994->mbc_cfg];
-
- for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++)
- snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1,
- cfg->coeff_regs[i]);
-
- for (i = 0; i < ARRAY_SIZE(cfg->cutoff_regs); i++)
- snd_soc_write(codec,
- i + WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1,
- cfg->cutoff_regs[i]);
- }
-
- /* Run the DSP */
- snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
- WM8958_DSP2_RUNR);
-
- /* And we're off! */
- snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
- WM8958_MBC_ENA |
- WM8958_MBC_SEL_MASK,
- path << WM8958_MBC_SEL_SHIFT |
- WM8958_MBC_ENA);
-}
-
-static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994_pdata *pdata = wm8994->pdata;
- int i, ena;
-
- if (wm8994->mbc_vss)
- wm8958_dsp2_fw(codec, "MBC+VSS", wm8994->mbc_vss, false);
-
- snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
- WM8958_DSP2_ENA, WM8958_DSP2_ENA);
-
- /* If we've got user supplied settings use them */
- if (pdata && pdata->num_mbc_cfgs) {
- struct wm8958_mbc_cfg *cfg
- = &pdata->mbc_cfgs[wm8994->mbc_cfg];
-
- for (i = 0; i < ARRAY_SIZE(cfg->combined_regs); i++)
- snd_soc_write(codec, i + 0x2800,
- cfg->combined_regs[i]);
- }
-
- if (pdata && pdata->num_vss_cfgs) {
- struct wm8958_vss_cfg *cfg
- = &pdata->vss_cfgs[wm8994->vss_cfg];
-
- for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
- snd_soc_write(codec, i + 0x2600, cfg->regs[i]);
- }
-
- if (pdata && pdata->num_vss_hpf_cfgs) {
- struct wm8958_vss_hpf_cfg *cfg
- = &pdata->vss_hpf_cfgs[wm8994->vss_hpf_cfg];
-
- for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
- snd_soc_write(codec, i + 0x2400, cfg->regs[i]);
- }
-
- /* Run the DSP */
- snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
- WM8958_DSP2_RUNR);
-
- /* Enable the algorithms we've selected */
- ena = 0;
- if (wm8994->mbc_ena[path])
- ena |= 0x8;
- if (wm8994->hpf2_ena[path])
- ena |= 0x4;
- if (wm8994->hpf1_ena[path])
- ena |= 0x2;
- if (wm8994->vss_ena[path])
- ena |= 0x1;
-
- snd_soc_write(codec, 0x2201, ena);
-
- /* Switch the DSP into the data path */
- snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
- WM8958_MBC_SEL_MASK | WM8958_MBC_ENA,
- path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA);
-}
-
-static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994_pdata *pdata = wm8994->pdata;
- int i;
-
- wm8958_dsp2_fw(codec, "ENH_EQ", wm8994->enh_eq, false);
-
- snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
- WM8958_DSP2_ENA, WM8958_DSP2_ENA);
-
- /* If we've got user supplied settings use them */
- if (pdata && pdata->num_enh_eq_cfgs) {
- struct wm8958_enh_eq_cfg *cfg
- = &pdata->enh_eq_cfgs[wm8994->enh_eq_cfg];
-
- for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
- snd_soc_write(codec, i + 0x2200,
- cfg->regs[i]);
- }
-
- /* Run the DSP */
- snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
- WM8958_DSP2_RUNR);
-
- /* Switch the DSP into the data path */
- snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
- WM8958_MBC_SEL_MASK | WM8958_MBC_ENA,
- path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA);
-}
-
-static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- int pwr_reg = snd_soc_read(codec, WM8994_POWER_MANAGEMENT_5);
- int ena, reg, aif;
-
- switch (path) {
- case 0:
- pwr_reg &= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA);
- aif = 0;
- break;
- case 1:
- pwr_reg &= (WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA);
- aif = 0;
- break;
- case 2:
- pwr_reg &= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA);
- aif = 1;
- break;
- default:
- BUG();
- return;
- }
-
- /* Do we have both an active AIF and an active algorithm? */
- ena = wm8994->mbc_ena[path] || wm8994->vss_ena[path] ||
- wm8994->hpf1_ena[path] || wm8994->hpf2_ena[path] ||
- wm8994->enh_eq_ena[path];
- if (!pwr_reg)
- ena = 0;
-
- reg = snd_soc_read(codec, WM8958_DSP2_PROGRAM);
-
- dev_dbg(codec->dev, "DSP path %d %d startup: %d, power: %x, DSP: %x\n",
- path, wm8994->dsp_active, start, pwr_reg, reg);
-
- if (start && ena) {
- /* If the DSP is already running then noop */
- if (reg & WM8958_DSP2_ENA)
- return;
-
- /* If either AIFnCLK is not yet enabled postpone */
- if (!(snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
- & WM8994_AIF1CLK_ENA_MASK) &&
- !(snd_soc_read(codec, WM8994_AIF2_CLOCKING_1)
- & WM8994_AIF2CLK_ENA_MASK))
- return;
-
- /* Switch the clock over to the appropriate AIF */
- snd_soc_update_bits(codec, WM8994_CLOCKING_1,
- WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA,
- aif << WM8958_DSP2CLK_SRC_SHIFT |
- WM8958_DSP2CLK_ENA);
-
- if (wm8994->enh_eq_ena[path])
- wm8958_dsp_start_enh_eq(codec, path);
- else if (wm8994->vss_ena[path] || wm8994->hpf1_ena[path] ||
- wm8994->hpf2_ena[path])
- wm8958_dsp_start_vss(codec, path);
- else if (wm8994->mbc_ena[path])
- wm8958_dsp_start_mbc(codec, path);
-
- wm8994->dsp_active = path;
-
- dev_dbg(codec->dev, "DSP running in path %d\n", path);
- }
-
- if (!start && wm8994->dsp_active == path) {
- /* If the DSP is already stopped then noop */
- if (!(reg & WM8958_DSP2_ENA))
- return;
-
- snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
- WM8958_MBC_ENA, 0);
- snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
- WM8958_DSP2_STOP);
- snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
- WM8958_DSP2_ENA, 0);
- snd_soc_update_bits(codec, WM8994_CLOCKING_1,
- WM8958_DSP2CLK_ENA, 0);
-
- wm8994->dsp_active = -1;
-
- dev_dbg(codec->dev, "DSP stopped\n");
- }
-}
-
-int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- int i;
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- case SND_SOC_DAPM_PRE_PMU:
- for (i = 0; i < 3; i++)
- wm8958_dsp_apply(codec, i, 1);
- break;
- case SND_SOC_DAPM_POST_PMD:
- case SND_SOC_DAPM_PRE_PMD:
- for (i = 0; i < 3; i++)
- wm8958_dsp_apply(codec, i, 0);
- break;
- }
-
- return 0;
-}
-
-/* Check if DSP2 is in use on another AIF */
-static int wm8958_dsp2_busy(struct wm8994_priv *wm8994, int aif)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(wm8994->mbc_ena); i++) {
- if (i == aif)
- continue;
- if (wm8994->mbc_ena[i] || wm8994->vss_ena[i] ||
- wm8994->hpf1_ena[i] || wm8994->hpf2_ena[i])
- return 1;
- }
-
- return 0;
-}
-
-static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994_pdata *pdata = wm8994->pdata;
- int value = ucontrol->value.integer.value[0];
- int reg;
-
- /* Don't allow on the fly reconfiguration */
- reg = snd_soc_read(codec, WM8994_CLOCKING_1);
- if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
- return -EBUSY;
-
- if (value >= pdata->num_mbc_cfgs)
- return -EINVAL;
-
- wm8994->mbc_cfg = value;
-
- return 0;
-}
-
-static int wm8958_get_mbc_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg;
-
- return 0;
-}
-
-static int wm8958_mbc_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int wm8958_mbc_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int mbc = kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc];
-
- return 0;
-}
-
-static int wm8958_mbc_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int mbc = kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- if (wm8994->mbc_ena[mbc] == ucontrol->value.integer.value[0])
- return 0;
-
- if (ucontrol->value.integer.value[0] > 1)
- return -EINVAL;
-
- if (wm8958_dsp2_busy(wm8994, mbc)) {
- dev_dbg(codec->dev, "DSP2 active on %d already\n", mbc);
- return -EBUSY;
- }
-
- if (wm8994->enh_eq_ena[mbc])
- return -EBUSY;
-
- wm8994->mbc_ena[mbc] = ucontrol->value.integer.value[0];
-
- wm8958_dsp_apply(codec, mbc, wm8994->mbc_ena[mbc]);
-
- return 0;
-}
-
-#define WM8958_MBC_SWITCH(xname, xval) {\
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
- .info = wm8958_mbc_info, \
- .get = wm8958_mbc_get, .put = wm8958_mbc_put, \
- .private_value = xval }
-
-static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994_pdata *pdata = wm8994->pdata;
- int value = ucontrol->value.integer.value[0];
- int reg;
-
- /* Don't allow on the fly reconfiguration */
- reg = snd_soc_read(codec, WM8994_CLOCKING_1);
- if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
- return -EBUSY;
-
- if (value >= pdata->num_vss_cfgs)
- return -EINVAL;
-
- wm8994->vss_cfg = value;
-
- return 0;
-}
-
-static int wm8958_get_vss_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.enumerated.item[0] = wm8994->vss_cfg;
-
- return 0;
-}
-
-static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994_pdata *pdata = wm8994->pdata;
- int value = ucontrol->value.integer.value[0];
- int reg;
-
- /* Don't allow on the fly reconfiguration */
- reg = snd_soc_read(codec, WM8994_CLOCKING_1);
- if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
- return -EBUSY;
-
- if (value >= pdata->num_vss_hpf_cfgs)
- return -EINVAL;
-
- wm8994->vss_hpf_cfg = value;
-
- return 0;
-}
-
-static int wm8958_get_vss_hpf_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.enumerated.item[0] = wm8994->vss_hpf_cfg;
-
- return 0;
-}
-
-static int wm8958_vss_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int wm8958_vss_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int vss = kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.integer.value[0] = wm8994->vss_ena[vss];
-
- return 0;
-}
-
-static int wm8958_vss_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int vss = kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- if (wm8994->vss_ena[vss] == ucontrol->value.integer.value[0])
- return 0;
-
- if (ucontrol->value.integer.value[0] > 1)
- return -EINVAL;
-
- if (!wm8994->mbc_vss)
- return -ENODEV;
-
- if (wm8958_dsp2_busy(wm8994, vss)) {
- dev_dbg(codec->dev, "DSP2 active on %d already\n", vss);
- return -EBUSY;
- }
-
- if (wm8994->enh_eq_ena[vss])
- return -EBUSY;
-
- wm8994->vss_ena[vss] = ucontrol->value.integer.value[0];
-
- wm8958_dsp_apply(codec, vss, wm8994->vss_ena[vss]);
-
- return 0;
-}
-
-
-#define WM8958_VSS_SWITCH(xname, xval) {\
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
- .info = wm8958_vss_info, \
- .get = wm8958_vss_get, .put = wm8958_vss_put, \
- .private_value = xval }
-
-static int wm8958_hpf_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int wm8958_hpf_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int hpf = kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- if (hpf < 3)
- ucontrol->value.integer.value[0] = wm8994->hpf1_ena[hpf % 3];
- else
- ucontrol->value.integer.value[0] = wm8994->hpf2_ena[hpf % 3];
-
- return 0;
-}
-
-static int wm8958_hpf_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int hpf = kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- if (hpf < 3) {
- if (wm8994->hpf1_ena[hpf % 3] ==
- ucontrol->value.integer.value[0])
- return 0;
- } else {
- if (wm8994->hpf2_ena[hpf % 3] ==
- ucontrol->value.integer.value[0])
- return 0;
- }
-
- if (ucontrol->value.integer.value[0] > 1)
- return -EINVAL;
-
- if (!wm8994->mbc_vss)
- return -ENODEV;
-
- if (wm8958_dsp2_busy(wm8994, hpf % 3)) {
- dev_dbg(codec->dev, "DSP2 active on %d already\n", hpf);
- return -EBUSY;
- }
-
- if (wm8994->enh_eq_ena[hpf % 3])
- return -EBUSY;
-
- if (hpf < 3)
- wm8994->hpf1_ena[hpf % 3] = ucontrol->value.integer.value[0];
- else
- wm8994->hpf2_ena[hpf % 3] = ucontrol->value.integer.value[0];
-
- wm8958_dsp_apply(codec, hpf % 3, ucontrol->value.integer.value[0]);
-
- return 0;
-}
-
-#define WM8958_HPF_SWITCH(xname, xval) {\
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
- .info = wm8958_hpf_info, \
- .get = wm8958_hpf_get, .put = wm8958_hpf_put, \
- .private_value = xval }
-
-static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994_pdata *pdata = wm8994->pdata;
- int value = ucontrol->value.integer.value[0];
- int reg;
-
- /* Don't allow on the fly reconfiguration */
- reg = snd_soc_read(codec, WM8994_CLOCKING_1);
- if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
- return -EBUSY;
-
- if (value >= pdata->num_enh_eq_cfgs)
- return -EINVAL;
-
- wm8994->enh_eq_cfg = value;
-
- return 0;
-}
-
-static int wm8958_get_enh_eq_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.enumerated.item[0] = wm8994->enh_eq_cfg;
-
- return 0;
-}
-
-static int wm8958_enh_eq_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-static int wm8958_enh_eq_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int eq = kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.integer.value[0] = wm8994->enh_eq_ena[eq];
-
- return 0;
-}
-
-static int wm8958_enh_eq_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int eq = kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- if (wm8994->enh_eq_ena[eq] == ucontrol->value.integer.value[0])
- return 0;
-
- if (ucontrol->value.integer.value[0] > 1)
- return -EINVAL;
-
- if (!wm8994->enh_eq)
- return -ENODEV;
-
- if (wm8958_dsp2_busy(wm8994, eq)) {
- dev_dbg(codec->dev, "DSP2 active on %d already\n", eq);
- return -EBUSY;
- }
-
- if (wm8994->mbc_ena[eq] || wm8994->vss_ena[eq] ||
- wm8994->hpf1_ena[eq] || wm8994->hpf2_ena[eq])
- return -EBUSY;
-
- wm8994->enh_eq_ena[eq] = ucontrol->value.integer.value[0];
-
- wm8958_dsp_apply(codec, eq, ucontrol->value.integer.value[0]);
-
- return 0;
-}
-
-#define WM8958_ENH_EQ_SWITCH(xname, xval) {\
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
- .info = wm8958_enh_eq_info, \
- .get = wm8958_enh_eq_get, .put = wm8958_enh_eq_put, \
- .private_value = xval }
-
-static const struct snd_kcontrol_new wm8958_mbc_snd_controls[] = {
-WM8958_MBC_SWITCH("AIF1DAC1 MBC Switch", 0),
-WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1),
-WM8958_MBC_SWITCH("AIF2DAC MBC Switch", 2),
-};
-
-static const struct snd_kcontrol_new wm8958_vss_snd_controls[] = {
-WM8958_VSS_SWITCH("AIF1DAC1 VSS Switch", 0),
-WM8958_VSS_SWITCH("AIF1DAC2 VSS Switch", 1),
-WM8958_VSS_SWITCH("AIF2DAC VSS Switch", 2),
-WM8958_HPF_SWITCH("AIF1DAC1 HPF1 Switch", 0),
-WM8958_HPF_SWITCH("AIF1DAC2 HPF1 Switch", 1),
-WM8958_HPF_SWITCH("AIF2DAC HPF1 Switch", 2),
-WM8958_HPF_SWITCH("AIF1DAC1 HPF2 Switch", 3),
-WM8958_HPF_SWITCH("AIF1DAC2 HPF2 Switch", 4),
-WM8958_HPF_SWITCH("AIF2DAC HPF2 Switch", 5),
-};
-
-static const struct snd_kcontrol_new wm8958_enh_eq_snd_controls[] = {
-WM8958_ENH_EQ_SWITCH("AIF1DAC1 Enhanced EQ Switch", 0),
-WM8958_ENH_EQ_SWITCH("AIF1DAC2 Enhanced EQ Switch", 1),
-WM8958_ENH_EQ_SWITCH("AIF2DAC Enhanced EQ Switch", 2),
-};
-
-static void wm8958_enh_eq_loaded(const struct firmware *fw, void *context)
-{
- struct snd_soc_codec *codec = context;
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- if (fw && (wm8958_dsp2_fw(codec, "ENH_EQ", fw, true) == 0)) {
- mutex_lock(&codec->mutex);
- wm8994->enh_eq = fw;
- mutex_unlock(&codec->mutex);
- }
-}
-
-static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context)
-{
- struct snd_soc_codec *codec = context;
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- if (fw && (wm8958_dsp2_fw(codec, "MBC+VSS", fw, true) == 0)) {
- mutex_lock(&codec->mutex);
- wm8994->mbc_vss = fw;
- mutex_unlock(&codec->mutex);
- }
-
- /* We can't have more than one request outstanding at once so
- * we daisy chain.
- */
- request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
- "wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL,
- codec, wm8958_enh_eq_loaded);
-}
-
-static void wm8958_mbc_loaded(const struct firmware *fw, void *context)
-{
- struct snd_soc_codec *codec = context;
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- if (wm8958_dsp2_fw(codec, "MBC", fw, true) != 0)
- return;
-
- mutex_lock(&codec->mutex);
- wm8994->mbc = fw;
- mutex_unlock(&codec->mutex);
-
- /* We can't have more than one request outstanding at once so
- * we daisy chain.
- */
- request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
- "wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL,
- codec, wm8958_mbc_vss_loaded);
-}
-
-void wm8958_dsp2_init(struct snd_soc_codec *codec)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994_pdata *pdata = wm8994->pdata;
- int ret, i;
-
- wm8994->dsp_active = -1;
-
- snd_soc_add_codec_controls(codec, wm8958_mbc_snd_controls,
- ARRAY_SIZE(wm8958_mbc_snd_controls));
- snd_soc_add_codec_controls(codec, wm8958_vss_snd_controls,
- ARRAY_SIZE(wm8958_vss_snd_controls));
- snd_soc_add_codec_controls(codec, wm8958_enh_eq_snd_controls,
- ARRAY_SIZE(wm8958_enh_eq_snd_controls));
-
-
- /* We don't *require* firmware and don't want to delay boot */
- request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
- "wm8958_mbc.wfw", codec->dev, GFP_KERNEL,
- codec, wm8958_mbc_loaded);
-
- if (!pdata)
- return;
-
- if (pdata->num_mbc_cfgs) {
- struct snd_kcontrol_new control[] = {
- SOC_ENUM_EXT("MBC Mode", wm8994->mbc_enum,
- wm8958_get_mbc_enum, wm8958_put_mbc_enum),
- };
-
- /* We need an array of texts for the enum API */
- wm8994->mbc_texts = kmalloc(sizeof(char *)
- * pdata->num_mbc_cfgs, GFP_KERNEL);
- if (!wm8994->mbc_texts) {
- dev_err(wm8994->codec->dev,
- "Failed to allocate %d MBC config texts\n",
- pdata->num_mbc_cfgs);
- return;
- }
-
- for (i = 0; i < pdata->num_mbc_cfgs; i++)
- wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name;
-
- wm8994->mbc_enum.max = pdata->num_mbc_cfgs;
- wm8994->mbc_enum.texts = wm8994->mbc_texts;
-
- ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
- if (ret != 0)
- dev_err(wm8994->codec->dev,
- "Failed to add MBC mode controls: %d\n", ret);
- }
-
- if (pdata->num_vss_cfgs) {
- struct snd_kcontrol_new control[] = {
- SOC_ENUM_EXT("VSS Mode", wm8994->vss_enum,
- wm8958_get_vss_enum, wm8958_put_vss_enum),
- };
-
- /* We need an array of texts for the enum API */
- wm8994->vss_texts = kmalloc(sizeof(char *)
- * pdata->num_vss_cfgs, GFP_KERNEL);
- if (!wm8994->vss_texts) {
- dev_err(wm8994->codec->dev,
- "Failed to allocate %d VSS config texts\n",
- pdata->num_vss_cfgs);
- return;
- }
-
- for (i = 0; i < pdata->num_vss_cfgs; i++)
- wm8994->vss_texts[i] = pdata->vss_cfgs[i].name;
-
- wm8994->vss_enum.max = pdata->num_vss_cfgs;
- wm8994->vss_enum.texts = wm8994->vss_texts;
-
- ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
- if (ret != 0)
- dev_err(wm8994->codec->dev,
- "Failed to add VSS mode controls: %d\n", ret);
- }
-
- if (pdata->num_vss_hpf_cfgs) {
- struct snd_kcontrol_new control[] = {
- SOC_ENUM_EXT("VSS HPF Mode", wm8994->vss_hpf_enum,
- wm8958_get_vss_hpf_enum,
- wm8958_put_vss_hpf_enum),
- };
-
- /* We need an array of texts for the enum API */
- wm8994->vss_hpf_texts = kmalloc(sizeof(char *)
- * pdata->num_vss_hpf_cfgs, GFP_KERNEL);
- if (!wm8994->vss_hpf_texts) {
- dev_err(wm8994->codec->dev,
- "Failed to allocate %d VSS HPF config texts\n",
- pdata->num_vss_hpf_cfgs);
- return;
- }
-
- for (i = 0; i < pdata->num_vss_hpf_cfgs; i++)
- wm8994->vss_hpf_texts[i] = pdata->vss_hpf_cfgs[i].name;
-
- wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs;
- wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts;
-
- ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
- if (ret != 0)
- dev_err(wm8994->codec->dev,
- "Failed to add VSS HPFmode controls: %d\n",
- ret);
- }
-
- if (pdata->num_enh_eq_cfgs) {
- struct snd_kcontrol_new control[] = {
- SOC_ENUM_EXT("Enhanced EQ Mode", wm8994->enh_eq_enum,
- wm8958_get_enh_eq_enum,
- wm8958_put_enh_eq_enum),
- };
-
- /* We need an array of texts for the enum API */
- wm8994->enh_eq_texts = kmalloc(sizeof(char *)
- * pdata->num_enh_eq_cfgs, GFP_KERNEL);
- if (!wm8994->enh_eq_texts) {
- dev_err(wm8994->codec->dev,
- "Failed to allocate %d enhanced EQ config texts\n",
- pdata->num_enh_eq_cfgs);
- return;
- }
-
- for (i = 0; i < pdata->num_enh_eq_cfgs; i++)
- wm8994->enh_eq_texts[i] = pdata->enh_eq_cfgs[i].name;
-
- wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs;
- wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts;
-
- ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
- if (ret != 0)
- dev_err(wm8994->codec->dev,
- "Failed to add enhanced EQ controls: %d\n",
- ret);
- }
-}
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8960.c b/ANDROID_3.4.5/sound/soc/codecs/wm8960.c
deleted file mode 100644
index 840d7208..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8960.c
+++ /dev/null
@@ -1,1032 +0,0 @@
-/*
- * wm8960.c -- WM8960 ALSA SoC Audio driver
- *
- * Author: Liam Girdwood
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <sound/wm8960.h>
-
-#include "wm8960.h"
-
-/* R25 - Power 1 */
-#define WM8960_VMID_MASK 0x180
-#define WM8960_VREF 0x40
-
-/* R26 - Power 2 */
-#define WM8960_PWR2_LOUT1 0x40
-#define WM8960_PWR2_ROUT1 0x20
-#define WM8960_PWR2_OUT3 0x02
-
-/* R28 - Anti-pop 1 */
-#define WM8960_POBCTRL 0x80
-#define WM8960_BUFDCOPEN 0x10
-#define WM8960_BUFIOEN 0x08
-#define WM8960_SOFT_ST 0x04
-#define WM8960_HPSTBY 0x01
-
-/* R29 - Anti-pop 2 */
-#define WM8960_DISOP 0x40
-#define WM8960_DRES_MASK 0x30
-
-/*
- * wm8960 register cache
- * We can't read the WM8960 register space when we are
- * using 2 wire for device control, so we cache them instead.
- */
-static const u16 wm8960_reg[WM8960_CACHEREGNUM] = {
- 0x0097, 0x0097, 0x0000, 0x0000,
- 0x0000, 0x0008, 0x0000, 0x000a,
- 0x01c0, 0x0000, 0x00ff, 0x00ff,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x007b, 0x0100, 0x0032,
- 0x0000, 0x00c3, 0x00c3, 0x01c0,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0100, 0x0100, 0x0050, 0x0050,
- 0x0050, 0x0050, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0040, 0x0000,
- 0x0000, 0x0050, 0x0050, 0x0000,
- 0x0002, 0x0037, 0x004d, 0x0080,
- 0x0008, 0x0031, 0x0026, 0x00e9,
-};
-
-struct wm8960_priv {
- enum snd_soc_control_type control_type;
- int (*set_bias_level)(struct snd_soc_codec *,
- enum snd_soc_bias_level level);
- struct snd_soc_dapm_widget *lout1;
- struct snd_soc_dapm_widget *rout1;
- struct snd_soc_dapm_widget *out3;
- bool deemph;
- int playback_fs;
-};
-
-#define wm8960_reset(c) snd_soc_write(c, WM8960_RESET, 0)
-
-/* enumerated controls */
-static const char *wm8960_polarity[] = {"No Inversion", "Left Inverted",
- "Right Inverted", "Stereo Inversion"};
-static const char *wm8960_3d_upper_cutoff[] = {"High", "Low"};
-static const char *wm8960_3d_lower_cutoff[] = {"Low", "High"};
-static const char *wm8960_alcfunc[] = {"Off", "Right", "Left", "Stereo"};
-static const char *wm8960_alcmode[] = {"ALC", "Limiter"};
-
-static const struct soc_enum wm8960_enum[] = {
- SOC_ENUM_SINGLE(WM8960_DACCTL1, 5, 4, wm8960_polarity),
- SOC_ENUM_SINGLE(WM8960_DACCTL2, 5, 4, wm8960_polarity),
- SOC_ENUM_SINGLE(WM8960_3D, 6, 2, wm8960_3d_upper_cutoff),
- SOC_ENUM_SINGLE(WM8960_3D, 5, 2, wm8960_3d_lower_cutoff),
- SOC_ENUM_SINGLE(WM8960_ALC1, 7, 4, wm8960_alcfunc),
- SOC_ENUM_SINGLE(WM8960_ALC3, 8, 2, wm8960_alcmode),
-};
-
-static const int deemph_settings[] = { 0, 32000, 44100, 48000 };
-
-static int wm8960_set_deemph(struct snd_soc_codec *codec)
-{
- struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
- int val, i, best;
-
- /* If we're using deemphasis select the nearest available sample
- * rate.
- */
- if (wm8960->deemph) {
- best = 1;
- for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) {
- if (abs(deemph_settings[i] - wm8960->playback_fs) <
- abs(deemph_settings[best] - wm8960->playback_fs))
- best = i;
- }
-
- val = best << 1;
- } else {
- val = 0;
- }
-
- dev_dbg(codec->dev, "Set deemphasis %d\n", val);
-
- return snd_soc_update_bits(codec, WM8960_DACCTL1,
- 0x6, val);
-}
-
-static int wm8960_get_deemph(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.enumerated.item[0] = wm8960->deemph;
- return 0;
-}
-
-static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
- int deemph = ucontrol->value.enumerated.item[0];
-
- if (deemph > 1)
- return -EINVAL;
-
- wm8960->deemph = deemph;
-
- return wm8960_set_deemph(codec);
-}
-
-static const DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 50, 0);
-static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1);
-static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0);
-static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
-
-static const struct snd_kcontrol_new wm8960_snd_controls[] = {
-SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL,
- 0, 63, 0, adc_tlv),
-SOC_DOUBLE_R("Capture Volume ZC Switch", WM8960_LINVOL, WM8960_RINVOL,
- 6, 1, 0),
-SOC_DOUBLE_R("Capture Switch", WM8960_LINVOL, WM8960_RINVOL,
- 7, 1, 0),
-
-SOC_DOUBLE_R_TLV("Playback Volume", WM8960_LDAC, WM8960_RDAC,
- 0, 255, 0, dac_tlv),
-
-SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8960_LOUT1, WM8960_ROUT1,
- 0, 127, 0, out_tlv),
-SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8960_LOUT1, WM8960_ROUT1,
- 7, 1, 0),
-
-SOC_DOUBLE_R_TLV("Speaker Playback Volume", WM8960_LOUT2, WM8960_ROUT2,
- 0, 127, 0, out_tlv),
-SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8960_LOUT2, WM8960_ROUT2,
- 7, 1, 0),
-SOC_SINGLE("Speaker DC Volume", WM8960_CLASSD3, 3, 5, 0),
-SOC_SINGLE("Speaker AC Volume", WM8960_CLASSD3, 0, 5, 0),
-
-SOC_SINGLE("PCM Playback -6dB Switch", WM8960_DACCTL1, 7, 1, 0),
-SOC_ENUM("ADC Polarity", wm8960_enum[0]),
-SOC_SINGLE("ADC High Pass Filter Switch", WM8960_DACCTL1, 0, 1, 0),
-
-SOC_ENUM("DAC Polarity", wm8960_enum[2]),
-SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0,
- wm8960_get_deemph, wm8960_put_deemph),
-
-SOC_ENUM("3D Filter Upper Cut-Off", wm8960_enum[2]),
-SOC_ENUM("3D Filter Lower Cut-Off", wm8960_enum[3]),
-SOC_SINGLE("3D Volume", WM8960_3D, 1, 15, 0),
-SOC_SINGLE("3D Switch", WM8960_3D, 0, 1, 0),
-
-SOC_ENUM("ALC Function", wm8960_enum[4]),
-SOC_SINGLE("ALC Max Gain", WM8960_ALC1, 4, 7, 0),
-SOC_SINGLE("ALC Target", WM8960_ALC1, 0, 15, 1),
-SOC_SINGLE("ALC Min Gain", WM8960_ALC2, 4, 7, 0),
-SOC_SINGLE("ALC Hold Time", WM8960_ALC2, 0, 15, 0),
-SOC_ENUM("ALC Mode", wm8960_enum[5]),
-SOC_SINGLE("ALC Decay", WM8960_ALC3, 4, 15, 0),
-SOC_SINGLE("ALC Attack", WM8960_ALC3, 0, 15, 0),
-
-SOC_SINGLE("Noise Gate Threshold", WM8960_NOISEG, 3, 31, 0),
-SOC_SINGLE("Noise Gate Switch", WM8960_NOISEG, 0, 1, 0),
-
-SOC_DOUBLE_R("ADC PCM Capture Volume", WM8960_LINPATH, WM8960_RINPATH,
- 0, 127, 0),
-
-SOC_SINGLE_TLV("Left Output Mixer Boost Bypass Volume",
- WM8960_BYPASS1, 4, 7, 1, bypass_tlv),
-SOC_SINGLE_TLV("Left Output Mixer LINPUT3 Volume",
- WM8960_LOUTMIX, 4, 7, 1, bypass_tlv),
-SOC_SINGLE_TLV("Right Output Mixer Boost Bypass Volume",
- WM8960_BYPASS2, 4, 7, 1, bypass_tlv),
-SOC_SINGLE_TLV("Right Output Mixer RINPUT3 Volume",
- WM8960_ROUTMIX, 4, 7, 1, bypass_tlv),
-};
-
-static const struct snd_kcontrol_new wm8960_lin_boost[] = {
-SOC_DAPM_SINGLE("LINPUT2 Switch", WM8960_LINPATH, 6, 1, 0),
-SOC_DAPM_SINGLE("LINPUT3 Switch", WM8960_LINPATH, 7, 1, 0),
-SOC_DAPM_SINGLE("LINPUT1 Switch", WM8960_LINPATH, 8, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8960_lin[] = {
-SOC_DAPM_SINGLE("Boost Switch", WM8960_LINPATH, 3, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8960_rin_boost[] = {
-SOC_DAPM_SINGLE("RINPUT2 Switch", WM8960_RINPATH, 6, 1, 0),
-SOC_DAPM_SINGLE("RINPUT3 Switch", WM8960_RINPATH, 7, 1, 0),
-SOC_DAPM_SINGLE("RINPUT1 Switch", WM8960_RINPATH, 8, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8960_rin[] = {
-SOC_DAPM_SINGLE("Boost Switch", WM8960_RINPATH, 3, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8960_loutput_mixer[] = {
-SOC_DAPM_SINGLE("PCM Playback Switch", WM8960_LOUTMIX, 8, 1, 0),
-SOC_DAPM_SINGLE("LINPUT3 Switch", WM8960_LOUTMIX, 7, 1, 0),
-SOC_DAPM_SINGLE("Boost Bypass Switch", WM8960_BYPASS1, 7, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8960_routput_mixer[] = {
-SOC_DAPM_SINGLE("PCM Playback Switch", WM8960_ROUTMIX, 8, 1, 0),
-SOC_DAPM_SINGLE("RINPUT3 Switch", WM8960_ROUTMIX, 7, 1, 0),
-SOC_DAPM_SINGLE("Boost Bypass Switch", WM8960_BYPASS2, 7, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8960_mono_out[] = {
-SOC_DAPM_SINGLE("Left Switch", WM8960_MONOMIX1, 7, 1, 0),
-SOC_DAPM_SINGLE("Right Switch", WM8960_MONOMIX2, 7, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget wm8960_dapm_widgets[] = {
-SND_SOC_DAPM_INPUT("LINPUT1"),
-SND_SOC_DAPM_INPUT("RINPUT1"),
-SND_SOC_DAPM_INPUT("LINPUT2"),
-SND_SOC_DAPM_INPUT("RINPUT2"),
-SND_SOC_DAPM_INPUT("LINPUT3"),
-SND_SOC_DAPM_INPUT("RINPUT3"),
-
-SND_SOC_DAPM_SUPPLY("MICB", WM8960_POWER1, 1, 0, NULL, 0),
-
-SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8960_POWER1, 5, 0,
- wm8960_lin_boost, ARRAY_SIZE(wm8960_lin_boost)),
-SND_SOC_DAPM_MIXER("Right Boost Mixer", WM8960_POWER1, 4, 0,
- wm8960_rin_boost, ARRAY_SIZE(wm8960_rin_boost)),
-
-SND_SOC_DAPM_MIXER("Left Input Mixer", WM8960_POWER3, 5, 0,
- wm8960_lin, ARRAY_SIZE(wm8960_lin)),
-SND_SOC_DAPM_MIXER("Right Input Mixer", WM8960_POWER3, 4, 0,
- wm8960_rin, ARRAY_SIZE(wm8960_rin)),
-
-SND_SOC_DAPM_ADC("Left ADC", "Capture", WM8960_POWER2, 3, 0),
-SND_SOC_DAPM_ADC("Right ADC", "Capture", WM8960_POWER2, 2, 0),
-
-SND_SOC_DAPM_DAC("Left DAC", "Playback", WM8960_POWER2, 8, 0),
-SND_SOC_DAPM_DAC("Right DAC", "Playback", WM8960_POWER2, 7, 0),
-
-SND_SOC_DAPM_MIXER("Left Output Mixer", WM8960_POWER3, 3, 0,
- &wm8960_loutput_mixer[0],
- ARRAY_SIZE(wm8960_loutput_mixer)),
-SND_SOC_DAPM_MIXER("Right Output Mixer", WM8960_POWER3, 2, 0,
- &wm8960_routput_mixer[0],
- ARRAY_SIZE(wm8960_routput_mixer)),
-
-SND_SOC_DAPM_PGA("LOUT1 PGA", WM8960_POWER2, 6, 0, NULL, 0),
-SND_SOC_DAPM_PGA("ROUT1 PGA", WM8960_POWER2, 5, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA("Left Speaker PGA", WM8960_POWER2, 4, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right Speaker PGA", WM8960_POWER2, 3, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA("Right Speaker Output", WM8960_CLASSD1, 7, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Left Speaker Output", WM8960_CLASSD1, 6, 0, NULL, 0),
-
-SND_SOC_DAPM_OUTPUT("SPK_LP"),
-SND_SOC_DAPM_OUTPUT("SPK_LN"),
-SND_SOC_DAPM_OUTPUT("HP_L"),
-SND_SOC_DAPM_OUTPUT("HP_R"),
-SND_SOC_DAPM_OUTPUT("SPK_RP"),
-SND_SOC_DAPM_OUTPUT("SPK_RN"),
-SND_SOC_DAPM_OUTPUT("OUT3"),
-};
-
-static const struct snd_soc_dapm_widget wm8960_dapm_widgets_out3[] = {
-SND_SOC_DAPM_MIXER("Mono Output Mixer", WM8960_POWER2, 1, 0,
- &wm8960_mono_out[0],
- ARRAY_SIZE(wm8960_mono_out)),
-};
-
-/* Represent OUT3 as a PGA so that it gets turned on with LOUT1/ROUT1 */
-static const struct snd_soc_dapm_widget wm8960_dapm_widgets_capless[] = {
-SND_SOC_DAPM_PGA("OUT3 VMID", WM8960_POWER2, 1, 0, NULL, 0),
-};
-
-static const struct snd_soc_dapm_route audio_paths[] = {
- { "Left Boost Mixer", "LINPUT1 Switch", "LINPUT1" },
- { "Left Boost Mixer", "LINPUT2 Switch", "LINPUT2" },
- { "Left Boost Mixer", "LINPUT3 Switch", "LINPUT3" },
-
- { "Left Input Mixer", "Boost Switch", "Left Boost Mixer", },
- { "Left Input Mixer", NULL, "LINPUT1", }, /* Really Boost Switch */
- { "Left Input Mixer", NULL, "LINPUT2" },
- { "Left Input Mixer", NULL, "LINPUT3" },
-
- { "Right Boost Mixer", "RINPUT1 Switch", "RINPUT1" },
- { "Right Boost Mixer", "RINPUT2 Switch", "RINPUT2" },
- { "Right Boost Mixer", "RINPUT3 Switch", "RINPUT3" },
-
- { "Right Input Mixer", "Boost Switch", "Right Boost Mixer", },
- { "Right Input Mixer", NULL, "RINPUT1", }, /* Really Boost Switch */
- { "Right Input Mixer", NULL, "RINPUT2" },
- { "Right Input Mixer", NULL, "LINPUT3" },
-
- { "Left ADC", NULL, "Left Input Mixer" },
- { "Right ADC", NULL, "Right Input Mixer" },
-
- { "Left Output Mixer", "LINPUT3 Switch", "LINPUT3" },
- { "Left Output Mixer", "Boost Bypass Switch", "Left Boost Mixer"} ,
- { "Left Output Mixer", "PCM Playback Switch", "Left DAC" },
-
- { "Right Output Mixer", "RINPUT3 Switch", "RINPUT3" },
- { "Right Output Mixer", "Boost Bypass Switch", "Right Boost Mixer" } ,
- { "Right Output Mixer", "PCM Playback Switch", "Right DAC" },
-
- { "LOUT1 PGA", NULL, "Left Output Mixer" },
- { "ROUT1 PGA", NULL, "Right Output Mixer" },
-
- { "HP_L", NULL, "LOUT1 PGA" },
- { "HP_R", NULL, "ROUT1 PGA" },
-
- { "Left Speaker PGA", NULL, "Left Output Mixer" },
- { "Right Speaker PGA", NULL, "Right Output Mixer" },
-
- { "Left Speaker Output", NULL, "Left Speaker PGA" },
- { "Right Speaker Output", NULL, "Right Speaker PGA" },
-
- { "SPK_LN", NULL, "Left Speaker Output" },
- { "SPK_LP", NULL, "Left Speaker Output" },
- { "SPK_RN", NULL, "Right Speaker Output" },
- { "SPK_RP", NULL, "Right Speaker Output" },
-};
-
-static const struct snd_soc_dapm_route audio_paths_out3[] = {
- { "Mono Output Mixer", "Left Switch", "Left Output Mixer" },
- { "Mono Output Mixer", "Right Switch", "Right Output Mixer" },
-
- { "OUT3", NULL, "Mono Output Mixer", }
-};
-
-static const struct snd_soc_dapm_route audio_paths_capless[] = {
- { "HP_L", NULL, "OUT3 VMID" },
- { "HP_R", NULL, "OUT3 VMID" },
-
- { "OUT3 VMID", NULL, "Left Output Mixer" },
- { "OUT3 VMID", NULL, "Right Output Mixer" },
-};
-
-static int wm8960_add_widgets(struct snd_soc_codec *codec)
-{
- struct wm8960_data *pdata = codec->dev->platform_data;
- struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- struct snd_soc_dapm_widget *w;
-
- snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets,
- ARRAY_SIZE(wm8960_dapm_widgets));
-
- snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
-
- /* In capless mode OUT3 is used to provide VMID for the
- * headphone outputs, otherwise it is used as a mono mixer.
- */
- if (pdata && pdata->capless) {
- snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets_capless,
- ARRAY_SIZE(wm8960_dapm_widgets_capless));
-
- snd_soc_dapm_add_routes(dapm, audio_paths_capless,
- ARRAY_SIZE(audio_paths_capless));
- } else {
- snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets_out3,
- ARRAY_SIZE(wm8960_dapm_widgets_out3));
-
- snd_soc_dapm_add_routes(dapm, audio_paths_out3,
- ARRAY_SIZE(audio_paths_out3));
- }
-
- /* We need to power up the headphone output stage out of
- * sequence for capless mode. To save scanning the widget
- * list each time to find the desired power state do so now
- * and save the result.
- */
- list_for_each_entry(w, &codec->card->widgets, list) {
- if (w->dapm != &codec->dapm)
- continue;
- if (strcmp(w->name, "LOUT1 PGA") == 0)
- wm8960->lout1 = w;
- if (strcmp(w->name, "ROUT1 PGA") == 0)
- wm8960->rout1 = w;
- if (strcmp(w->name, "OUT3 VMID") == 0)
- wm8960->out3 = w;
- }
-
- return 0;
-}
-
-static int wm8960_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 iface = 0;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- iface |= 0x0040;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= 0x0002;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= 0x0001;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= 0x0003;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- iface |= 0x0013;
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= 0x0090;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= 0x0080;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- iface |= 0x0010;
- break;
- default:
- return -EINVAL;
- }
-
- /* set iface */
- snd_soc_write(codec, WM8960_IFACE1, iface);
- return 0;
-}
-
-static struct {
- int rate;
- unsigned int val;
-} alc_rates[] = {
- { 48000, 0 },
- { 44100, 0 },
- { 32000, 1 },
- { 22050, 2 },
- { 24000, 2 },
- { 16000, 3 },
- { 11250, 4 },
- { 12000, 4 },
- { 8000, 5 },
-};
-
-static int wm8960_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
- u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3;
- int i;
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= 0x0004;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface |= 0x0008;
- break;
- }
-
- /* Update filters for the new rate */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- wm8960->playback_fs = params_rate(params);
- wm8960_set_deemph(codec);
- } else {
- for (i = 0; i < ARRAY_SIZE(alc_rates); i++)
- if (alc_rates[i].rate == params_rate(params))
- snd_soc_update_bits(codec,
- WM8960_ADDCTL3, 0x7,
- alc_rates[i].val);
- }
-
- /* set iface */
- snd_soc_write(codec, WM8960_IFACE1, iface);
- return 0;
-}
-
-static int wm8960_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
-
- if (mute)
- snd_soc_update_bits(codec, WM8960_DACCTL1, 0x8, 0x8);
- else
- snd_soc_update_bits(codec, WM8960_DACCTL1, 0x8, 0);
- return 0;
-}
-
-static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- /* Set VMID to 2x50k */
- snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x80);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- snd_soc_cache_sync(codec);
-
- /* Enable anti-pop features */
- snd_soc_write(codec, WM8960_APOP1,
- WM8960_POBCTRL | WM8960_SOFT_ST |
- WM8960_BUFDCOPEN | WM8960_BUFIOEN);
-
- /* Enable & ramp VMID at 2x50k */
- snd_soc_update_bits(codec, WM8960_POWER1, 0x80, 0x80);
- msleep(100);
-
- /* Enable VREF */
- snd_soc_update_bits(codec, WM8960_POWER1, WM8960_VREF,
- WM8960_VREF);
-
- /* Disable anti-pop features */
- snd_soc_write(codec, WM8960_APOP1, WM8960_BUFIOEN);
- }
-
- /* Set VMID to 2x250k */
- snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x100);
- break;
-
- case SND_SOC_BIAS_OFF:
- /* Enable anti-pop features */
- snd_soc_write(codec, WM8960_APOP1,
- WM8960_POBCTRL | WM8960_SOFT_ST |
- WM8960_BUFDCOPEN | WM8960_BUFIOEN);
-
- /* Disable VMID and VREF, let them discharge */
- snd_soc_write(codec, WM8960_POWER1, 0);
- msleep(600);
- break;
- }
-
- codec->dapm.bias_level = level;
-
- return 0;
-}
-
-static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
- int reg;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- switch (codec->dapm.bias_level) {
- case SND_SOC_BIAS_STANDBY:
- /* Enable anti pop mode */
- snd_soc_update_bits(codec, WM8960_APOP1,
- WM8960_POBCTRL | WM8960_SOFT_ST |
- WM8960_BUFDCOPEN,
- WM8960_POBCTRL | WM8960_SOFT_ST |
- WM8960_BUFDCOPEN);
-
- /* Enable LOUT1, ROUT1 and OUT3 if they're enabled */
- reg = 0;
- if (wm8960->lout1 && wm8960->lout1->power)
- reg |= WM8960_PWR2_LOUT1;
- if (wm8960->rout1 && wm8960->rout1->power)
- reg |= WM8960_PWR2_ROUT1;
- if (wm8960->out3 && wm8960->out3->power)
- reg |= WM8960_PWR2_OUT3;
- snd_soc_update_bits(codec, WM8960_POWER2,
- WM8960_PWR2_LOUT1 |
- WM8960_PWR2_ROUT1 |
- WM8960_PWR2_OUT3, reg);
-
- /* Enable VMID at 2*50k */
- snd_soc_update_bits(codec, WM8960_POWER1,
- WM8960_VMID_MASK, 0x80);
-
- /* Ramp */
- msleep(100);
-
- /* Enable VREF */
- snd_soc_update_bits(codec, WM8960_POWER1,
- WM8960_VREF, WM8960_VREF);
-
- msleep(100);
- break;
-
- case SND_SOC_BIAS_ON:
- /* Enable anti-pop mode */
- snd_soc_update_bits(codec, WM8960_APOP1,
- WM8960_POBCTRL | WM8960_SOFT_ST |
- WM8960_BUFDCOPEN,
- WM8960_POBCTRL | WM8960_SOFT_ST |
- WM8960_BUFDCOPEN);
-
- /* Disable VMID and VREF */
- snd_soc_update_bits(codec, WM8960_POWER1,
- WM8960_VREF | WM8960_VMID_MASK, 0);
- break;
-
- case SND_SOC_BIAS_OFF:
- snd_soc_cache_sync(codec);
- break;
- default:
- break;
- }
- break;
-
- case SND_SOC_BIAS_STANDBY:
- switch (codec->dapm.bias_level) {
- case SND_SOC_BIAS_PREPARE:
- /* Disable HP discharge */
- snd_soc_update_bits(codec, WM8960_APOP2,
- WM8960_DISOP | WM8960_DRES_MASK,
- 0);
-
- /* Disable anti-pop features */
- snd_soc_update_bits(codec, WM8960_APOP1,
- WM8960_POBCTRL | WM8960_SOFT_ST |
- WM8960_BUFDCOPEN,
- WM8960_POBCTRL | WM8960_SOFT_ST |
- WM8960_BUFDCOPEN);
- break;
-
- default:
- break;
- }
- break;
-
- case SND_SOC_BIAS_OFF:
- break;
- }
-
- codec->dapm.bias_level = level;
-
- return 0;
-}
-
-/* PLL divisors */
-struct _pll_div {
- u32 pre_div:1;
- u32 n:4;
- u32 k:24;
-};
-
-/* The size in bits of the pll divide multiplied by 10
- * to allow rounding later */
-#define FIXED_PLL_SIZE ((1 << 24) * 10)
-
-static int pll_factors(unsigned int source, unsigned int target,
- struct _pll_div *pll_div)
-{
- unsigned long long Kpart;
- unsigned int K, Ndiv, Nmod;
-
- pr_debug("WM8960 PLL: setting %dHz->%dHz\n", source, target);
-
- /* Scale up target to PLL operating frequency */
- target *= 4;
-
- Ndiv = target / source;
- if (Ndiv < 6) {
- source >>= 1;
- pll_div->pre_div = 1;
- Ndiv = target / source;
- } else
- pll_div->pre_div = 0;
-
- if ((Ndiv < 6) || (Ndiv > 12)) {
- pr_err("WM8960 PLL: Unsupported N=%d\n", Ndiv);
- return -EINVAL;
- }
-
- pll_div->n = Ndiv;
- Nmod = target % source;
- Kpart = FIXED_PLL_SIZE * (long long)Nmod;
-
- do_div(Kpart, source);
-
- K = Kpart & 0xFFFFFFFF;
-
- /* Check if we need to round */
- if ((K % 10) >= 5)
- K += 5;
-
- /* Move down to proper range now rounding is done */
- K /= 10;
-
- pll_div->k = K;
-
- pr_debug("WM8960 PLL: N=%x K=%x pre_div=%d\n",
- pll_div->n, pll_div->k, pll_div->pre_div);
-
- return 0;
-}
-
-static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
- int source, unsigned int freq_in, unsigned int freq_out)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 reg;
- static struct _pll_div pll_div;
- int ret;
-
- if (freq_in && freq_out) {
- ret = pll_factors(freq_in, freq_out, &pll_div);
- if (ret != 0)
- return ret;
- }
-
- /* Disable the PLL: even if we are changing the frequency the
- * PLL needs to be disabled while we do so. */
- snd_soc_update_bits(codec, WM8960_CLOCK1, 0x1, 0);
- snd_soc_update_bits(codec, WM8960_POWER2, 0x1, 0);
-
- if (!freq_in || !freq_out)
- return 0;
-
- reg = snd_soc_read(codec, WM8960_PLL1) & ~0x3f;
- reg |= pll_div.pre_div << 4;
- reg |= pll_div.n;
-
- if (pll_div.k) {
- reg |= 0x20;
-
- snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 18) & 0x3f);
- snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 9) & 0x1ff);
- snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0x1ff);
- }
- snd_soc_write(codec, WM8960_PLL1, reg);
-
- /* Turn it on */
- snd_soc_update_bits(codec, WM8960_POWER2, 0x1, 0x1);
- msleep(250);
- snd_soc_update_bits(codec, WM8960_CLOCK1, 0x1, 0x1);
-
- return 0;
-}
-
-static int wm8960_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
- int div_id, int div)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 reg;
-
- switch (div_id) {
- case WM8960_SYSCLKDIV:
- reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1f9;
- snd_soc_write(codec, WM8960_CLOCK1, reg | div);
- break;
- case WM8960_DACDIV:
- reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1c7;
- snd_soc_write(codec, WM8960_CLOCK1, reg | div);
- break;
- case WM8960_OPCLKDIV:
- reg = snd_soc_read(codec, WM8960_PLL1) & 0x03f;
- snd_soc_write(codec, WM8960_PLL1, reg | div);
- break;
- case WM8960_DCLKDIV:
- reg = snd_soc_read(codec, WM8960_CLOCK2) & 0x03f;
- snd_soc_write(codec, WM8960_CLOCK2, reg | div);
- break;
- case WM8960_TOCLKSEL:
- reg = snd_soc_read(codec, WM8960_ADDCTL1) & 0x1fd;
- snd_soc_write(codec, WM8960_ADDCTL1, reg | div);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int wm8960_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
-
- return wm8960->set_bias_level(codec, level);
-}
-
-#define WM8960_RATES SNDRV_PCM_RATE_8000_48000
-
-#define WM8960_FORMATS \
- (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops wm8960_dai_ops = {
- .hw_params = wm8960_hw_params,
- .digital_mute = wm8960_mute,
- .set_fmt = wm8960_set_dai_fmt,
- .set_clkdiv = wm8960_set_dai_clkdiv,
- .set_pll = wm8960_set_dai_pll,
-};
-
-static struct snd_soc_dai_driver wm8960_dai = {
- .name = "wm8960-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8960_RATES,
- .formats = WM8960_FORMATS,},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8960_RATES,
- .formats = WM8960_FORMATS,},
- .ops = &wm8960_dai_ops,
- .symmetric_rates = 1,
-};
-
-static int wm8960_suspend(struct snd_soc_codec *codec)
-{
- struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
-
- wm8960->set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm8960_resume(struct snd_soc_codec *codec)
-{
- struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
-
- wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-
-static int wm8960_probe(struct snd_soc_codec *codec)
-{
- struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
- struct wm8960_data *pdata = dev_get_platdata(codec->dev);
- int ret;
-
- wm8960->set_bias_level = wm8960_set_bias_level_out3;
-
- if (!pdata) {
- dev_warn(codec->dev, "No platform data supplied\n");
- } else {
- if (pdata->dres > WM8960_DRES_MAX) {
- dev_err(codec->dev, "Invalid DRES: %d\n", pdata->dres);
- pdata->dres = 0;
- }
-
- if (pdata->capless)
- wm8960->set_bias_level = wm8960_set_bias_level_capless;
- }
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8960->control_type);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- ret = wm8960_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- return ret;
- }
-
- wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* Latch the update bits */
- snd_soc_update_bits(codec, WM8960_LINVOL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8960_RINVOL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8960_LADC, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8960_RADC, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8960_LDAC, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8960_RDAC, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8960_LOUT1, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8960_ROUT1, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8960_LOUT2, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8960_ROUT2, 0x100, 0x100);
-
- snd_soc_add_codec_controls(codec, wm8960_snd_controls,
- ARRAY_SIZE(wm8960_snd_controls));
- wm8960_add_widgets(codec);
-
- return 0;
-}
-
-/* power down chip */
-static int wm8960_remove(struct snd_soc_codec *codec)
-{
- struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
-
- wm8960->set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8960 = {
- .probe = wm8960_probe,
- .remove = wm8960_remove,
- .suspend = wm8960_suspend,
- .resume = wm8960_resume,
- .set_bias_level = wm8960_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8960_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8960_reg,
-};
-
-static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8960_priv *wm8960;
- int ret;
-
- wm8960 = devm_kzalloc(&i2c->dev, sizeof(struct wm8960_priv),
- GFP_KERNEL);
- if (wm8960 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm8960);
- wm8960->control_type = SND_SOC_I2C;
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8960, &wm8960_dai, 1);
-
- return ret;
-}
-
-static __devexit int wm8960_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static const struct i2c_device_id wm8960_i2c_id[] = {
- { "wm8960", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8960_i2c_id);
-
-static struct i2c_driver wm8960_i2c_driver = {
- .driver = {
- .name = "wm8960",
- .owner = THIS_MODULE,
- },
- .probe = wm8960_i2c_probe,
- .remove = __devexit_p(wm8960_i2c_remove),
- .id_table = wm8960_i2c_id,
-};
-
-static int __init wm8960_modinit(void)
-{
- int ret = 0;
- ret = i2c_add_driver(&wm8960_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8960 I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(wm8960_modinit);
-
-static void __exit wm8960_exit(void)
-{
- i2c_del_driver(&wm8960_i2c_driver);
-}
-module_exit(wm8960_exit);
-
-MODULE_DESCRIPTION("ASoC WM8960 driver");
-MODULE_AUTHOR("Liam Girdwood");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8960.h b/ANDROID_3.4.5/sound/soc/codecs/wm8960.h
deleted file mode 100644
index 2d8163d7..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8960.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * wm8960.h -- WM8960 Soc Audio driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8960_H
-#define _WM8960_H
-
-/* WM8960 register space */
-
-
-#define WM8960_CACHEREGNUM 56
-
-#define WM8960_LINVOL 0x0
-#define WM8960_RINVOL 0x1
-#define WM8960_LOUT1 0x2
-#define WM8960_ROUT1 0x3
-#define WM8960_CLOCK1 0x4
-#define WM8960_DACCTL1 0x5
-#define WM8960_DACCTL2 0x6
-#define WM8960_IFACE1 0x7
-#define WM8960_CLOCK2 0x8
-#define WM8960_IFACE2 0x9
-#define WM8960_LDAC 0xa
-#define WM8960_RDAC 0xb
-
-#define WM8960_RESET 0xf
-#define WM8960_3D 0x10
-#define WM8960_ALC1 0x11
-#define WM8960_ALC2 0x12
-#define WM8960_ALC3 0x13
-#define WM8960_NOISEG 0x14
-#define WM8960_LADC 0x15
-#define WM8960_RADC 0x16
-#define WM8960_ADDCTL1 0x17
-#define WM8960_ADDCTL2 0x18
-#define WM8960_POWER1 0x19
-#define WM8960_POWER2 0x1a
-#define WM8960_ADDCTL3 0x1b
-#define WM8960_APOP1 0x1c
-#define WM8960_APOP2 0x1d
-
-#define WM8960_LINPATH 0x20
-#define WM8960_RINPATH 0x21
-#define WM8960_LOUTMIX 0x22
-
-#define WM8960_ROUTMIX 0x25
-#define WM8960_MONOMIX1 0x26
-#define WM8960_MONOMIX2 0x27
-#define WM8960_LOUT2 0x28
-#define WM8960_ROUT2 0x29
-#define WM8960_MONO 0x2a
-#define WM8960_INBMIX1 0x2b
-#define WM8960_INBMIX2 0x2c
-#define WM8960_BYPASS1 0x2d
-#define WM8960_BYPASS2 0x2e
-#define WM8960_POWER3 0x2f
-#define WM8960_ADDCTL4 0x30
-#define WM8960_CLASSD1 0x31
-
-#define WM8960_CLASSD3 0x33
-#define WM8960_PLL1 0x34
-#define WM8960_PLL2 0x35
-#define WM8960_PLL3 0x36
-#define WM8960_PLL4 0x37
-
-
-/*
- * WM8960 Clock dividers
- */
-#define WM8960_SYSCLKDIV 0
-#define WM8960_DACDIV 1
-#define WM8960_OPCLKDIV 2
-#define WM8960_DCLKDIV 3
-#define WM8960_TOCLKSEL 4
-
-#define WM8960_SYSCLK_DIV_1 (0 << 1)
-#define WM8960_SYSCLK_DIV_2 (2 << 1)
-
-#define WM8960_SYSCLK_MCLK (0 << 0)
-#define WM8960_SYSCLK_PLL (1 << 0)
-
-#define WM8960_DAC_DIV_1 (0 << 3)
-#define WM8960_DAC_DIV_1_5 (1 << 3)
-#define WM8960_DAC_DIV_2 (2 << 3)
-#define WM8960_DAC_DIV_3 (3 << 3)
-#define WM8960_DAC_DIV_4 (4 << 3)
-#define WM8960_DAC_DIV_5_5 (5 << 3)
-#define WM8960_DAC_DIV_6 (6 << 3)
-
-#define WM8960_DCLK_DIV_1_5 (0 << 6)
-#define WM8960_DCLK_DIV_2 (1 << 6)
-#define WM8960_DCLK_DIV_3 (2 << 6)
-#define WM8960_DCLK_DIV_4 (3 << 6)
-#define WM8960_DCLK_DIV_6 (4 << 6)
-#define WM8960_DCLK_DIV_8 (5 << 6)
-#define WM8960_DCLK_DIV_12 (6 << 6)
-#define WM8960_DCLK_DIV_16 (7 << 6)
-
-#define WM8960_TOCLK_F19 (0 << 1)
-#define WM8960_TOCLK_F21 (1 << 1)
-
-#define WM8960_OPCLK_DIV_1 (0 << 0)
-#define WM8960_OPCLK_DIV_2 (1 << 0)
-#define WM8960_OPCLK_DIV_3 (2 << 0)
-#define WM8960_OPCLK_DIV_4 (3 << 0)
-#define WM8960_OPCLK_DIV_5_5 (4 << 0)
-#define WM8960_OPCLK_DIV_6 (5 << 0)
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8961.c b/ANDROID_3.4.5/sound/soc/codecs/wm8961.c
deleted file mode 100644
index 05ea7c27..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8961.c
+++ /dev/null
@@ -1,1135 +0,0 @@
-/*
- * wm8961.c -- WM8961 ALSA SoC Audio driver
- *
- * Author: Mark Brown
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Currently unimplemented features:
- * - ALC
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "wm8961.h"
-
-#define WM8961_MAX_REGISTER 0xFC
-
-static u16 wm8961_reg_defaults[] = {
- 0x009F, /* R0 - Left Input volume */
- 0x009F, /* R1 - Right Input volume */
- 0x0000, /* R2 - LOUT1 volume */
- 0x0000, /* R3 - ROUT1 volume */
- 0x0020, /* R4 - Clocking1 */
- 0x0008, /* R5 - ADC & DAC Control 1 */
- 0x0000, /* R6 - ADC & DAC Control 2 */
- 0x000A, /* R7 - Audio Interface 0 */
- 0x01F4, /* R8 - Clocking2 */
- 0x0000, /* R9 - Audio Interface 1 */
- 0x00FF, /* R10 - Left DAC volume */
- 0x00FF, /* R11 - Right DAC volume */
- 0x0000, /* R12 */
- 0x0000, /* R13 */
- 0x0040, /* R14 - Audio Interface 2 */
- 0x0000, /* R15 - Software Reset */
- 0x0000, /* R16 */
- 0x007B, /* R17 - ALC1 */
- 0x0000, /* R18 - ALC2 */
- 0x0032, /* R19 - ALC3 */
- 0x0000, /* R20 - Noise Gate */
- 0x00C0, /* R21 - Left ADC volume */
- 0x00C0, /* R22 - Right ADC volume */
- 0x0120, /* R23 - Additional control(1) */
- 0x0000, /* R24 - Additional control(2) */
- 0x0000, /* R25 - Pwr Mgmt (1) */
- 0x0000, /* R26 - Pwr Mgmt (2) */
- 0x0000, /* R27 - Additional Control (3) */
- 0x0000, /* R28 - Anti-pop */
- 0x0000, /* R29 */
- 0x005F, /* R30 - Clocking 3 */
- 0x0000, /* R31 */
- 0x0000, /* R32 - ADCL signal path */
- 0x0000, /* R33 - ADCR signal path */
- 0x0000, /* R34 */
- 0x0000, /* R35 */
- 0x0000, /* R36 */
- 0x0000, /* R37 */
- 0x0000, /* R38 */
- 0x0000, /* R39 */
- 0x0000, /* R40 - LOUT2 volume */
- 0x0000, /* R41 - ROUT2 volume */
- 0x0000, /* R42 */
- 0x0000, /* R43 */
- 0x0000, /* R44 */
- 0x0000, /* R45 */
- 0x0000, /* R46 */
- 0x0000, /* R47 - Pwr Mgmt (3) */
- 0x0023, /* R48 - Additional Control (4) */
- 0x0000, /* R49 - Class D Control 1 */
- 0x0000, /* R50 */
- 0x0003, /* R51 - Class D Control 2 */
- 0x0000, /* R52 */
- 0x0000, /* R53 */
- 0x0000, /* R54 */
- 0x0000, /* R55 */
- 0x0106, /* R56 - Clocking 4 */
- 0x0000, /* R57 - DSP Sidetone 0 */
- 0x0000, /* R58 - DSP Sidetone 1 */
- 0x0000, /* R59 */
- 0x0000, /* R60 - DC Servo 0 */
- 0x0000, /* R61 - DC Servo 1 */
- 0x0000, /* R62 */
- 0x015E, /* R63 - DC Servo 3 */
- 0x0010, /* R64 */
- 0x0010, /* R65 - DC Servo 5 */
- 0x0000, /* R66 */
- 0x0001, /* R67 */
- 0x0003, /* R68 - Analogue PGA Bias */
- 0x0000, /* R69 - Analogue HP 0 */
- 0x0060, /* R70 */
- 0x01FB, /* R71 - Analogue HP 2 */
- 0x0000, /* R72 - Charge Pump 1 */
- 0x0065, /* R73 */
- 0x005F, /* R74 */
- 0x0059, /* R75 */
- 0x006B, /* R76 */
- 0x0038, /* R77 */
- 0x000C, /* R78 */
- 0x000A, /* R79 */
- 0x006B, /* R80 */
- 0x0000, /* R81 */
- 0x0000, /* R82 - Charge Pump B */
- 0x0087, /* R83 */
- 0x0000, /* R84 */
- 0x005C, /* R85 */
- 0x0000, /* R86 */
- 0x0000, /* R87 - Write Sequencer 1 */
- 0x0000, /* R88 - Write Sequencer 2 */
- 0x0000, /* R89 - Write Sequencer 3 */
- 0x0000, /* R90 - Write Sequencer 4 */
- 0x0000, /* R91 - Write Sequencer 5 */
- 0x0000, /* R92 - Write Sequencer 6 */
- 0x0000, /* R93 - Write Sequencer 7 */
- 0x0000, /* R94 */
- 0x0000, /* R95 */
- 0x0000, /* R96 */
- 0x0000, /* R97 */
- 0x0000, /* R98 */
- 0x0000, /* R99 */
- 0x0000, /* R100 */
- 0x0000, /* R101 */
- 0x0000, /* R102 */
- 0x0000, /* R103 */
- 0x0000, /* R104 */
- 0x0000, /* R105 */
- 0x0000, /* R106 */
- 0x0000, /* R107 */
- 0x0000, /* R108 */
- 0x0000, /* R109 */
- 0x0000, /* R110 */
- 0x0000, /* R111 */
- 0x0000, /* R112 */
- 0x0000, /* R113 */
- 0x0000, /* R114 */
- 0x0000, /* R115 */
- 0x0000, /* R116 */
- 0x0000, /* R117 */
- 0x0000, /* R118 */
- 0x0000, /* R119 */
- 0x0000, /* R120 */
- 0x0000, /* R121 */
- 0x0000, /* R122 */
- 0x0000, /* R123 */
- 0x0000, /* R124 */
- 0x0000, /* R125 */
- 0x0000, /* R126 */
- 0x0000, /* R127 */
- 0x0000, /* R128 */
- 0x0000, /* R129 */
- 0x0000, /* R130 */
- 0x0000, /* R131 */
- 0x0000, /* R132 */
- 0x0000, /* R133 */
- 0x0000, /* R134 */
- 0x0000, /* R135 */
- 0x0000, /* R136 */
- 0x0000, /* R137 */
- 0x0000, /* R138 */
- 0x0000, /* R139 */
- 0x0000, /* R140 */
- 0x0000, /* R141 */
- 0x0000, /* R142 */
- 0x0000, /* R143 */
- 0x0000, /* R144 */
- 0x0000, /* R145 */
- 0x0000, /* R146 */
- 0x0000, /* R147 */
- 0x0000, /* R148 */
- 0x0000, /* R149 */
- 0x0000, /* R150 */
- 0x0000, /* R151 */
- 0x0000, /* R152 */
- 0x0000, /* R153 */
- 0x0000, /* R154 */
- 0x0000, /* R155 */
- 0x0000, /* R156 */
- 0x0000, /* R157 */
- 0x0000, /* R158 */
- 0x0000, /* R159 */
- 0x0000, /* R160 */
- 0x0000, /* R161 */
- 0x0000, /* R162 */
- 0x0000, /* R163 */
- 0x0000, /* R164 */
- 0x0000, /* R165 */
- 0x0000, /* R166 */
- 0x0000, /* R167 */
- 0x0000, /* R168 */
- 0x0000, /* R169 */
- 0x0000, /* R170 */
- 0x0000, /* R171 */
- 0x0000, /* R172 */
- 0x0000, /* R173 */
- 0x0000, /* R174 */
- 0x0000, /* R175 */
- 0x0000, /* R176 */
- 0x0000, /* R177 */
- 0x0000, /* R178 */
- 0x0000, /* R179 */
- 0x0000, /* R180 */
- 0x0000, /* R181 */
- 0x0000, /* R182 */
- 0x0000, /* R183 */
- 0x0000, /* R184 */
- 0x0000, /* R185 */
- 0x0000, /* R186 */
- 0x0000, /* R187 */
- 0x0000, /* R188 */
- 0x0000, /* R189 */
- 0x0000, /* R190 */
- 0x0000, /* R191 */
- 0x0000, /* R192 */
- 0x0000, /* R193 */
- 0x0000, /* R194 */
- 0x0000, /* R195 */
- 0x0030, /* R196 */
- 0x0006, /* R197 */
- 0x0000, /* R198 */
- 0x0060, /* R199 */
- 0x0000, /* R200 */
- 0x003F, /* R201 */
- 0x0000, /* R202 */
- 0x0000, /* R203 */
- 0x0000, /* R204 */
- 0x0001, /* R205 */
- 0x0000, /* R206 */
- 0x0181, /* R207 */
- 0x0005, /* R208 */
- 0x0008, /* R209 */
- 0x0008, /* R210 */
- 0x0000, /* R211 */
- 0x013B, /* R212 */
- 0x0000, /* R213 */
- 0x0000, /* R214 */
- 0x0000, /* R215 */
- 0x0000, /* R216 */
- 0x0070, /* R217 */
- 0x0000, /* R218 */
- 0x0000, /* R219 */
- 0x0000, /* R220 */
- 0x0000, /* R221 */
- 0x0000, /* R222 */
- 0x0003, /* R223 */
- 0x0000, /* R224 */
- 0x0000, /* R225 */
- 0x0001, /* R226 */
- 0x0008, /* R227 */
- 0x0000, /* R228 */
- 0x0000, /* R229 */
- 0x0000, /* R230 */
- 0x0000, /* R231 */
- 0x0004, /* R232 */
- 0x0000, /* R233 */
- 0x0000, /* R234 */
- 0x0000, /* R235 */
- 0x0000, /* R236 */
- 0x0000, /* R237 */
- 0x0080, /* R238 */
- 0x0000, /* R239 */
- 0x0000, /* R240 */
- 0x0000, /* R241 */
- 0x0000, /* R242 */
- 0x0000, /* R243 */
- 0x0000, /* R244 */
- 0x0052, /* R245 */
- 0x0110, /* R246 */
- 0x0040, /* R247 */
- 0x0000, /* R248 */
- 0x0030, /* R249 */
- 0x0000, /* R250 */
- 0x0000, /* R251 */
- 0x0001, /* R252 - General test 1 */
-};
-
-struct wm8961_priv {
- enum snd_soc_control_type control_type;
- int sysclk;
-};
-
-static int wm8961_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
-{
- switch (reg) {
- case WM8961_SOFTWARE_RESET:
- case WM8961_WRITE_SEQUENCER_7:
- case WM8961_DC_SERVO_1:
- return 1;
-
- default:
- return 0;
- }
-}
-
-static int wm8961_reset(struct snd_soc_codec *codec)
-{
- return snd_soc_write(codec, WM8961_SOFTWARE_RESET, 0);
-}
-
-/*
- * The headphone output supports special anti-pop sequences giving
- * silent power up and power down.
- */
-static int wm8961_hp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- u16 hp_reg = snd_soc_read(codec, WM8961_ANALOGUE_HP_0);
- u16 cp_reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_1);
- u16 pwr_reg = snd_soc_read(codec, WM8961_PWR_MGMT_2);
- u16 dcs_reg = snd_soc_read(codec, WM8961_DC_SERVO_1);
- int timeout = 500;
-
- if (event & SND_SOC_DAPM_POST_PMU) {
- /* Make sure the output is shorted */
- hp_reg &= ~(WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT);
- snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
-
- /* Enable the charge pump */
- cp_reg |= WM8961_CP_ENA;
- snd_soc_write(codec, WM8961_CHARGE_PUMP_1, cp_reg);
- mdelay(5);
-
- /* Enable the PGA */
- pwr_reg |= WM8961_LOUT1_PGA | WM8961_ROUT1_PGA;
- snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);
-
- /* Enable the amplifier */
- hp_reg |= WM8961_HPR_ENA | WM8961_HPL_ENA;
- snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
-
- /* Second stage enable */
- hp_reg |= WM8961_HPR_ENA_DLY | WM8961_HPL_ENA_DLY;
- snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
-
- /* Enable the DC servo & trigger startup */
- dcs_reg |=
- WM8961_DCS_ENA_CHAN_HPR | WM8961_DCS_TRIG_STARTUP_HPR |
- WM8961_DCS_ENA_CHAN_HPL | WM8961_DCS_TRIG_STARTUP_HPL;
- dev_dbg(codec->dev, "Enabling DC servo\n");
-
- snd_soc_write(codec, WM8961_DC_SERVO_1, dcs_reg);
- do {
- msleep(1);
- dcs_reg = snd_soc_read(codec, WM8961_DC_SERVO_1);
- } while (--timeout &&
- dcs_reg & (WM8961_DCS_TRIG_STARTUP_HPR |
- WM8961_DCS_TRIG_STARTUP_HPL));
- if (dcs_reg & (WM8961_DCS_TRIG_STARTUP_HPR |
- WM8961_DCS_TRIG_STARTUP_HPL))
- dev_err(codec->dev, "DC servo timed out\n");
- else
- dev_dbg(codec->dev, "DC servo startup complete\n");
-
- /* Enable the output stage */
- hp_reg |= WM8961_HPR_ENA_OUTP | WM8961_HPL_ENA_OUTP;
- snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
-
- /* Remove the short on the output stage */
- hp_reg |= WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT;
- snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
- }
-
- if (event & SND_SOC_DAPM_PRE_PMD) {
- /* Short the output */
- hp_reg &= ~(WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT);
- snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
-
- /* Disable the output stage */
- hp_reg &= ~(WM8961_HPR_ENA_OUTP | WM8961_HPL_ENA_OUTP);
- snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
-
- /* Disable DC offset cancellation */
- dcs_reg &= ~(WM8961_DCS_ENA_CHAN_HPR |
- WM8961_DCS_ENA_CHAN_HPL);
- snd_soc_write(codec, WM8961_DC_SERVO_1, dcs_reg);
-
- /* Finish up */
- hp_reg &= ~(WM8961_HPR_ENA_DLY | WM8961_HPR_ENA |
- WM8961_HPL_ENA_DLY | WM8961_HPL_ENA);
- snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
-
- /* Disable the PGA */
- pwr_reg &= ~(WM8961_LOUT1_PGA | WM8961_ROUT1_PGA);
- snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);
-
- /* Disable the charge pump */
- dev_dbg(codec->dev, "Disabling charge pump\n");
- snd_soc_write(codec, WM8961_CHARGE_PUMP_1,
- cp_reg & ~WM8961_CP_ENA);
- }
-
- return 0;
-}
-
-static int wm8961_spk_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- u16 pwr_reg = snd_soc_read(codec, WM8961_PWR_MGMT_2);
- u16 spk_reg = snd_soc_read(codec, WM8961_CLASS_D_CONTROL_1);
-
- if (event & SND_SOC_DAPM_POST_PMU) {
- /* Enable the PGA */
- pwr_reg |= WM8961_SPKL_PGA | WM8961_SPKR_PGA;
- snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);
-
- /* Enable the amplifier */
- spk_reg |= WM8961_SPKL_ENA | WM8961_SPKR_ENA;
- snd_soc_write(codec, WM8961_CLASS_D_CONTROL_1, spk_reg);
- }
-
- if (event & SND_SOC_DAPM_PRE_PMD) {
- /* Disable the amplifier */
- spk_reg &= ~(WM8961_SPKL_ENA | WM8961_SPKR_ENA);
- snd_soc_write(codec, WM8961_CLASS_D_CONTROL_1, spk_reg);
-
- /* Disable the PGA */
- pwr_reg &= ~(WM8961_SPKL_PGA | WM8961_SPKR_PGA);
- snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);
- }
-
- return 0;
-}
-
-static const char *adc_hpf_text[] = {
- "Hi-fi", "Voice 1", "Voice 2", "Voice 3",
-};
-
-static const struct soc_enum adc_hpf =
- SOC_ENUM_SINGLE(WM8961_ADC_DAC_CONTROL_2, 7, 4, adc_hpf_text);
-
-static const char *dac_deemph_text[] = {
- "None", "32kHz", "44.1kHz", "48kHz",
-};
-
-static const struct soc_enum dac_deemph =
- SOC_ENUM_SINGLE(WM8961_ADC_DAC_CONTROL_1, 1, 4, dac_deemph_text);
-
-static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
-static const DECLARE_TLV_DB_SCALE(hp_sec_tlv, -700, 100, 0);
-static const DECLARE_TLV_DB_SCALE(adc_tlv, -7200, 75, 1);
-static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 300, 0);
-static unsigned int boost_tlv[] = {
- TLV_DB_RANGE_HEAD(4),
- 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
- 1, 1, TLV_DB_SCALE_ITEM(13, 0, 0),
- 2, 2, TLV_DB_SCALE_ITEM(20, 0, 0),
- 3, 3, TLV_DB_SCALE_ITEM(29, 0, 0),
-};
-static const DECLARE_TLV_DB_SCALE(pga_tlv, -2325, 75, 0);
-
-static const struct snd_kcontrol_new wm8961_snd_controls[] = {
-SOC_DOUBLE_R_TLV("Headphone Volume", WM8961_LOUT1_VOLUME, WM8961_ROUT1_VOLUME,
- 0, 127, 0, out_tlv),
-SOC_DOUBLE_TLV("Headphone Secondary Volume", WM8961_ANALOGUE_HP_2,
- 6, 3, 7, 0, hp_sec_tlv),
-SOC_DOUBLE_R("Headphone ZC Switch", WM8961_LOUT1_VOLUME, WM8961_ROUT1_VOLUME,
- 7, 1, 0),
-
-SOC_DOUBLE_R_TLV("Speaker Volume", WM8961_LOUT2_VOLUME, WM8961_ROUT2_VOLUME,
- 0, 127, 0, out_tlv),
-SOC_DOUBLE_R("Speaker ZC Switch", WM8961_LOUT2_VOLUME, WM8961_ROUT2_VOLUME,
- 7, 1, 0),
-SOC_SINGLE("Speaker AC Gain", WM8961_CLASS_D_CONTROL_2, 0, 7, 0),
-
-SOC_SINGLE("DAC x128 OSR Switch", WM8961_ADC_DAC_CONTROL_2, 0, 1, 0),
-SOC_ENUM("DAC Deemphasis", dac_deemph),
-SOC_SINGLE("DAC Soft Mute Switch", WM8961_ADC_DAC_CONTROL_2, 3, 1, 0),
-
-SOC_DOUBLE_R_TLV("Sidetone Volume", WM8961_DSP_SIDETONE_0,
- WM8961_DSP_SIDETONE_1, 4, 12, 0, sidetone_tlv),
-
-SOC_SINGLE("ADC High Pass Filter Switch", WM8961_ADC_DAC_CONTROL_1, 0, 1, 0),
-SOC_ENUM("ADC High Pass Filter Mode", adc_hpf),
-
-SOC_DOUBLE_R_TLV("Capture Volume",
- WM8961_LEFT_ADC_VOLUME, WM8961_RIGHT_ADC_VOLUME,
- 1, 119, 0, adc_tlv),
-SOC_DOUBLE_R_TLV("Capture Boost Volume",
- WM8961_ADCL_SIGNAL_PATH, WM8961_ADCR_SIGNAL_PATH,
- 4, 3, 0, boost_tlv),
-SOC_DOUBLE_R_TLV("Capture PGA Volume",
- WM8961_LEFT_INPUT_VOLUME, WM8961_RIGHT_INPUT_VOLUME,
- 0, 62, 0, pga_tlv),
-SOC_DOUBLE_R("Capture PGA ZC Switch",
- WM8961_LEFT_INPUT_VOLUME, WM8961_RIGHT_INPUT_VOLUME,
- 6, 1, 1),
-SOC_DOUBLE_R("Capture PGA Switch",
- WM8961_LEFT_INPUT_VOLUME, WM8961_RIGHT_INPUT_VOLUME,
- 7, 1, 1),
-};
-
-static const char *sidetone_text[] = {
- "None", "Left", "Right"
-};
-
-static const struct soc_enum dacl_sidetone =
- SOC_ENUM_SINGLE(WM8961_DSP_SIDETONE_0, 2, 3, sidetone_text);
-
-static const struct soc_enum dacr_sidetone =
- SOC_ENUM_SINGLE(WM8961_DSP_SIDETONE_1, 2, 3, sidetone_text);
-
-static const struct snd_kcontrol_new dacl_mux =
- SOC_DAPM_ENUM("DACL Sidetone", dacl_sidetone);
-
-static const struct snd_kcontrol_new dacr_mux =
- SOC_DAPM_ENUM("DACR Sidetone", dacr_sidetone);
-
-static const struct snd_soc_dapm_widget wm8961_dapm_widgets[] = {
-SND_SOC_DAPM_INPUT("LINPUT"),
-SND_SOC_DAPM_INPUT("RINPUT"),
-
-SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8961_CLOCKING2, 4, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA("Left Input", WM8961_PWR_MGMT_1, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right Input", WM8961_PWR_MGMT_1, 4, 0, NULL, 0),
-
-SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", WM8961_PWR_MGMT_1, 3, 0),
-SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", WM8961_PWR_MGMT_1, 2, 0),
-
-SND_SOC_DAPM_SUPPLY("MICBIAS", WM8961_PWR_MGMT_1, 1, 0, NULL, 0),
-
-SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &dacl_mux),
-SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &dacr_mux),
-
-SND_SOC_DAPM_DAC("DACL", "HiFi Playback", WM8961_PWR_MGMT_2, 8, 0),
-SND_SOC_DAPM_DAC("DACR", "HiFi Playback", WM8961_PWR_MGMT_2, 7, 0),
-
-/* Handle as a mono path for DCS */
-SND_SOC_DAPM_PGA_E("Headphone Output", SND_SOC_NOPM,
- 4, 0, NULL, 0, wm8961_hp_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-SND_SOC_DAPM_PGA_E("Speaker Output", SND_SOC_NOPM,
- 4, 0, NULL, 0, wm8961_spk_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-
-SND_SOC_DAPM_OUTPUT("HP_L"),
-SND_SOC_DAPM_OUTPUT("HP_R"),
-SND_SOC_DAPM_OUTPUT("SPK_LN"),
-SND_SOC_DAPM_OUTPUT("SPK_LP"),
-SND_SOC_DAPM_OUTPUT("SPK_RN"),
-SND_SOC_DAPM_OUTPUT("SPK_RP"),
-};
-
-
-static const struct snd_soc_dapm_route audio_paths[] = {
- { "DACL", NULL, "CLK_DSP" },
- { "DACL", NULL, "DACL Sidetone" },
- { "DACR", NULL, "CLK_DSP" },
- { "DACR", NULL, "DACR Sidetone" },
-
- { "DACL Sidetone", "Left", "ADCL" },
- { "DACL Sidetone", "Right", "ADCR" },
-
- { "DACR Sidetone", "Left", "ADCL" },
- { "DACR Sidetone", "Right", "ADCR" },
-
- { "HP_L", NULL, "Headphone Output" },
- { "HP_R", NULL, "Headphone Output" },
- { "Headphone Output", NULL, "DACL" },
- { "Headphone Output", NULL, "DACR" },
-
- { "SPK_LN", NULL, "Speaker Output" },
- { "SPK_LP", NULL, "Speaker Output" },
- { "SPK_RN", NULL, "Speaker Output" },
- { "SPK_RP", NULL, "Speaker Output" },
-
- { "Speaker Output", NULL, "DACL" },
- { "Speaker Output", NULL, "DACR" },
-
- { "ADCL", NULL, "Left Input" },
- { "ADCL", NULL, "CLK_DSP" },
- { "ADCR", NULL, "Right Input" },
- { "ADCR", NULL, "CLK_DSP" },
-
- { "Left Input", NULL, "LINPUT" },
- { "Right Input", NULL, "RINPUT" },
-
-};
-
-/* Values for CLK_SYS_RATE */
-static struct {
- int ratio;
- u16 val;
-} wm8961_clk_sys_ratio[] = {
- { 64, 0 },
- { 128, 1 },
- { 192, 2 },
- { 256, 3 },
- { 384, 4 },
- { 512, 5 },
- { 768, 6 },
- { 1024, 7 },
- { 1408, 8 },
- { 1536, 9 },
-};
-
-/* Values for SAMPLE_RATE */
-static struct {
- int rate;
- u16 val;
-} wm8961_srate[] = {
- { 48000, 0 },
- { 44100, 0 },
- { 32000, 1 },
- { 22050, 2 },
- { 24000, 2 },
- { 16000, 3 },
- { 11250, 4 },
- { 12000, 4 },
- { 8000, 5 },
-};
-
-static int wm8961_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8961_priv *wm8961 = snd_soc_codec_get_drvdata(codec);
- int i, best, target, fs;
- u16 reg;
-
- fs = params_rate(params);
-
- if (!wm8961->sysclk) {
- dev_err(codec->dev, "MCLK has not been specified\n");
- return -EINVAL;
- }
-
- /* Find the closest sample rate for the filters */
- best = 0;
- for (i = 0; i < ARRAY_SIZE(wm8961_srate); i++) {
- if (abs(wm8961_srate[i].rate - fs) <
- abs(wm8961_srate[best].rate - fs))
- best = i;
- }
- reg = snd_soc_read(codec, WM8961_ADDITIONAL_CONTROL_3);
- reg &= ~WM8961_SAMPLE_RATE_MASK;
- reg |= wm8961_srate[best].val;
- snd_soc_write(codec, WM8961_ADDITIONAL_CONTROL_3, reg);
- dev_dbg(codec->dev, "Selected SRATE %dHz for %dHz\n",
- wm8961_srate[best].rate, fs);
-
- /* Select a CLK_SYS/fs ratio equal to or higher than required */
- target = wm8961->sysclk / fs;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && target < 64) {
- dev_err(codec->dev,
- "SYSCLK must be at least 64*fs for DAC\n");
- return -EINVAL;
- }
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE && target < 256) {
- dev_err(codec->dev,
- "SYSCLK must be at least 256*fs for ADC\n");
- return -EINVAL;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm8961_clk_sys_ratio); i++) {
- if (wm8961_clk_sys_ratio[i].ratio >= target)
- break;
- }
- if (i == ARRAY_SIZE(wm8961_clk_sys_ratio)) {
- dev_err(codec->dev, "Unable to generate CLK_SYS_RATE\n");
- return -EINVAL;
- }
- dev_dbg(codec->dev, "Selected CLK_SYS_RATE of %d for %d/%d=%d\n",
- wm8961_clk_sys_ratio[i].ratio, wm8961->sysclk, fs,
- wm8961->sysclk / fs);
-
- reg = snd_soc_read(codec, WM8961_CLOCKING_4);
- reg &= ~WM8961_CLK_SYS_RATE_MASK;
- reg |= wm8961_clk_sys_ratio[i].val << WM8961_CLK_SYS_RATE_SHIFT;
- snd_soc_write(codec, WM8961_CLOCKING_4, reg);
-
- reg = snd_soc_read(codec, WM8961_AUDIO_INTERFACE_0);
- reg &= ~WM8961_WL_MASK;
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- reg |= 1 << WM8961_WL_SHIFT;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- reg |= 2 << WM8961_WL_SHIFT;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- reg |= 3 << WM8961_WL_SHIFT;
- break;
- default:
- return -EINVAL;
- }
- snd_soc_write(codec, WM8961_AUDIO_INTERFACE_0, reg);
-
- /* Sloping stop-band filter is recommended for <= 24kHz */
- reg = snd_soc_read(codec, WM8961_ADC_DAC_CONTROL_2);
- if (fs <= 24000)
- reg |= WM8961_DACSLOPE;
- else
- reg &= ~WM8961_DACSLOPE;
- snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_2, reg);
-
- return 0;
-}
-
-static int wm8961_set_sysclk(struct snd_soc_dai *dai, int clk_id,
- unsigned int freq,
- int dir)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8961_priv *wm8961 = snd_soc_codec_get_drvdata(codec);
- u16 reg = snd_soc_read(codec, WM8961_CLOCKING1);
-
- if (freq > 33000000) {
- dev_err(codec->dev, "MCLK must be <33MHz\n");
- return -EINVAL;
- }
-
- if (freq > 16500000) {
- dev_dbg(codec->dev, "Using MCLK/2 for %dHz MCLK\n", freq);
- reg |= WM8961_MCLKDIV;
- freq /= 2;
- } else {
- dev_dbg(codec->dev, "Using MCLK/1 for %dHz MCLK\n", freq);
- reg &= ~WM8961_MCLKDIV;
- }
-
- snd_soc_write(codec, WM8961_CLOCKING1, reg);
-
- wm8961->sysclk = freq;
-
- return 0;
-}
-
-static int wm8961_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 aif = snd_soc_read(codec, WM8961_AUDIO_INTERFACE_0);
-
- aif &= ~(WM8961_BCLKINV | WM8961_LRP |
- WM8961_MS | WM8961_FORMAT_MASK);
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- aif |= WM8961_MS;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
-
- case SND_SOC_DAIFMT_LEFT_J:
- aif |= 1;
- break;
-
- case SND_SOC_DAIFMT_I2S:
- aif |= 2;
- break;
-
- case SND_SOC_DAIFMT_DSP_B:
- aif |= WM8961_LRP;
- case SND_SOC_DAIFMT_DSP_A:
- aif |= 3;
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- case SND_SOC_DAIFMT_IB_NF:
- break;
- default:
- return -EINVAL;
- }
- break;
-
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_NB_IF:
- aif |= WM8961_LRP;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- aif |= WM8961_BCLKINV;
- break;
- case SND_SOC_DAIFMT_IB_IF:
- aif |= WM8961_BCLKINV | WM8961_LRP;
- break;
- default:
- return -EINVAL;
- }
-
- return snd_soc_write(codec, WM8961_AUDIO_INTERFACE_0, aif);
-}
-
-static int wm8961_set_tristate(struct snd_soc_dai *dai, int tristate)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 reg = snd_soc_read(codec, WM8961_ADDITIONAL_CONTROL_2);
-
- if (tristate)
- reg |= WM8961_TRIS;
- else
- reg &= ~WM8961_TRIS;
-
- return snd_soc_write(codec, WM8961_ADDITIONAL_CONTROL_2, reg);
-}
-
-static int wm8961_digital_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 reg = snd_soc_read(codec, WM8961_ADC_DAC_CONTROL_1);
-
- if (mute)
- reg |= WM8961_DACMU;
- else
- reg &= ~WM8961_DACMU;
-
- msleep(17);
-
- return snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_1, reg);
-}
-
-static int wm8961_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 reg;
-
- switch (div_id) {
- case WM8961_BCLK:
- reg = snd_soc_read(codec, WM8961_CLOCKING2);
- reg &= ~WM8961_BCLKDIV_MASK;
- reg |= div;
- snd_soc_write(codec, WM8961_CLOCKING2, reg);
- break;
-
- case WM8961_LRCLK:
- reg = snd_soc_read(codec, WM8961_AUDIO_INTERFACE_2);
- reg &= ~WM8961_LRCLK_RATE_MASK;
- reg |= div;
- snd_soc_write(codec, WM8961_AUDIO_INTERFACE_2, reg);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int wm8961_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- u16 reg;
-
- /* This is all slightly unusual since we have no bypass paths
- * and the output amplifier structure means we can just slam
- * the biases straight up rather than having to ramp them
- * slowly.
- */
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
- /* Enable bias generation */
- reg = snd_soc_read(codec, WM8961_ANTI_POP);
- reg |= WM8961_BUFIOEN | WM8961_BUFDCOPEN;
- snd_soc_write(codec, WM8961_ANTI_POP, reg);
-
- /* VMID=2*50k, VREF */
- reg = snd_soc_read(codec, WM8961_PWR_MGMT_1);
- reg &= ~WM8961_VMIDSEL_MASK;
- reg |= (1 << WM8961_VMIDSEL_SHIFT) | WM8961_VREF;
- snd_soc_write(codec, WM8961_PWR_MGMT_1, reg);
- }
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) {
- /* VREF off */
- reg = snd_soc_read(codec, WM8961_PWR_MGMT_1);
- reg &= ~WM8961_VREF;
- snd_soc_write(codec, WM8961_PWR_MGMT_1, reg);
-
- /* Bias generation off */
- reg = snd_soc_read(codec, WM8961_ANTI_POP);
- reg &= ~(WM8961_BUFIOEN | WM8961_BUFDCOPEN);
- snd_soc_write(codec, WM8961_ANTI_POP, reg);
-
- /* VMID off */
- reg = snd_soc_read(codec, WM8961_PWR_MGMT_1);
- reg &= ~WM8961_VMIDSEL_MASK;
- snd_soc_write(codec, WM8961_PWR_MGMT_1, reg);
- }
- break;
-
- case SND_SOC_BIAS_OFF:
- break;
- }
-
- codec->dapm.bias_level = level;
-
- return 0;
-}
-
-
-#define WM8961_RATES SNDRV_PCM_RATE_8000_48000
-
-#define WM8961_FORMATS \
- (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops wm8961_dai_ops = {
- .hw_params = wm8961_hw_params,
- .set_sysclk = wm8961_set_sysclk,
- .set_fmt = wm8961_set_fmt,
- .digital_mute = wm8961_digital_mute,
- .set_tristate = wm8961_set_tristate,
- .set_clkdiv = wm8961_set_clkdiv,
-};
-
-static struct snd_soc_dai_driver wm8961_dai = {
- .name = "wm8961-hifi",
- .playback = {
- .stream_name = "HiFi Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8961_RATES,
- .formats = WM8961_FORMATS,},
- .capture = {
- .stream_name = "HiFi Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8961_RATES,
- .formats = WM8961_FORMATS,},
- .ops = &wm8961_dai_ops,
-};
-
-static int wm8961_probe(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret = 0;
- u16 reg;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- reg = snd_soc_read(codec, WM8961_SOFTWARE_RESET);
- if (reg != 0x1801) {
- dev_err(codec->dev, "Device is not a WM8961: ID=0x%x\n", reg);
- return -EINVAL;
- }
-
- /* This isn't volatile - readback doesn't correspond to write */
- codec->cache_bypass = 1;
- reg = snd_soc_read(codec, WM8961_RIGHT_INPUT_VOLUME);
- codec->cache_bypass = 0;
- dev_info(codec->dev, "WM8961 family %d revision %c\n",
- (reg & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT,
- ((reg & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT)
- + 'A');
-
- ret = wm8961_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- return ret;
- }
-
- /* Enable class W */
- reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_B);
- reg |= WM8961_CP_DYN_PWR_MASK;
- snd_soc_write(codec, WM8961_CHARGE_PUMP_B, reg);
-
- /* Latch volume update bits (right channel only, we always
- * write both out) and default ZC on. */
- reg = snd_soc_read(codec, WM8961_ROUT1_VOLUME);
- snd_soc_write(codec, WM8961_ROUT1_VOLUME,
- reg | WM8961_LO1ZC | WM8961_OUT1VU);
- snd_soc_write(codec, WM8961_LOUT1_VOLUME, reg | WM8961_LO1ZC);
- reg = snd_soc_read(codec, WM8961_ROUT2_VOLUME);
- snd_soc_write(codec, WM8961_ROUT2_VOLUME,
- reg | WM8961_SPKRZC | WM8961_SPKVU);
- snd_soc_write(codec, WM8961_LOUT2_VOLUME, reg | WM8961_SPKLZC);
-
- reg = snd_soc_read(codec, WM8961_RIGHT_ADC_VOLUME);
- snd_soc_write(codec, WM8961_RIGHT_ADC_VOLUME, reg | WM8961_ADCVU);
- reg = snd_soc_read(codec, WM8961_RIGHT_INPUT_VOLUME);
- snd_soc_write(codec, WM8961_RIGHT_INPUT_VOLUME, reg | WM8961_IPVU);
-
- /* Use soft mute by default */
- reg = snd_soc_read(codec, WM8961_ADC_DAC_CONTROL_2);
- reg |= WM8961_DACSMM;
- snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_2, reg);
-
- /* Use automatic clocking mode by default; for now this is all
- * we support.
- */
- reg = snd_soc_read(codec, WM8961_CLOCKING_3);
- reg &= ~WM8961_MANUAL_MODE;
- snd_soc_write(codec, WM8961_CLOCKING_3, reg);
-
- wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- snd_soc_add_codec_controls(codec, wm8961_snd_controls,
- ARRAY_SIZE(wm8961_snd_controls));
- snd_soc_dapm_new_controls(dapm, wm8961_dapm_widgets,
- ARRAY_SIZE(wm8961_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
-
- return 0;
-}
-
-static int wm8961_remove(struct snd_soc_codec *codec)
-{
- wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int wm8961_suspend(struct snd_soc_codec *codec)
-{
- wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int wm8961_resume(struct snd_soc_codec *codec)
-{
- snd_soc_cache_sync(codec);
-
- wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-#else
-#define wm8961_suspend NULL
-#define wm8961_resume NULL
-#endif
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8961 = {
- .probe = wm8961_probe,
- .remove = wm8961_remove,
- .suspend = wm8961_suspend,
- .resume = wm8961_resume,
- .set_bias_level = wm8961_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8961_reg_defaults),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8961_reg_defaults,
- .volatile_register = wm8961_volatile_register,
-};
-
-static __devinit int wm8961_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8961_priv *wm8961;
- int ret;
-
- wm8961 = devm_kzalloc(&i2c->dev, sizeof(struct wm8961_priv),
- GFP_KERNEL);
- if (wm8961 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm8961);
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8961, &wm8961_dai, 1);
-
- return ret;
-}
-
-static __devexit int wm8961_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
-
- return 0;
-}
-
-static const struct i2c_device_id wm8961_i2c_id[] = {
- { "wm8961", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8961_i2c_id);
-
-static struct i2c_driver wm8961_i2c_driver = {
- .driver = {
- .name = "wm8961",
- .owner = THIS_MODULE,
- },
- .probe = wm8961_i2c_probe,
- .remove = __devexit_p(wm8961_i2c_remove),
- .id_table = wm8961_i2c_id,
-};
-
-static int __init wm8961_modinit(void)
-{
- int ret = 0;
- ret = i2c_add_driver(&wm8961_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8961 I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(wm8961_modinit);
-
-static void __exit wm8961_exit(void)
-{
- i2c_del_driver(&wm8961_i2c_driver);
-}
-module_exit(wm8961_exit);
-
-MODULE_DESCRIPTION("ASoC WM8961 driver");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8961.h b/ANDROID_3.4.5/sound/soc/codecs/wm8961.h
deleted file mode 100644
index 1d736e57..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8961.h
+++ /dev/null
@@ -1,863 +0,0 @@
-/*
- * wm8961.h -- WM8961 Soc Audio driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8961_H
-#define _WM8961_H
-
-#include <sound/soc.h>
-
-#define WM8961_BCLK 1
-#define WM8961_LRCLK 2
-
-#define WM8961_BCLK_DIV_1 0
-#define WM8961_BCLK_DIV_1_5 1
-#define WM8961_BCLK_DIV_2 2
-#define WM8961_BCLK_DIV_3 3
-#define WM8961_BCLK_DIV_4 4
-#define WM8961_BCLK_DIV_5_5 5
-#define WM8961_BCLK_DIV_6 6
-#define WM8961_BCLK_DIV_8 7
-#define WM8961_BCLK_DIV_11 8
-#define WM8961_BCLK_DIV_12 9
-#define WM8961_BCLK_DIV_16 10
-#define WM8961_BCLK_DIV_24 11
-#define WM8961_BCLK_DIV_32 13
-
-
-/*
- * Register values.
- */
-#define WM8961_LEFT_INPUT_VOLUME 0x00
-#define WM8961_RIGHT_INPUT_VOLUME 0x01
-#define WM8961_LOUT1_VOLUME 0x02
-#define WM8961_ROUT1_VOLUME 0x03
-#define WM8961_CLOCKING1 0x04
-#define WM8961_ADC_DAC_CONTROL_1 0x05
-#define WM8961_ADC_DAC_CONTROL_2 0x06
-#define WM8961_AUDIO_INTERFACE_0 0x07
-#define WM8961_CLOCKING2 0x08
-#define WM8961_AUDIO_INTERFACE_1 0x09
-#define WM8961_LEFT_DAC_VOLUME 0x0A
-#define WM8961_RIGHT_DAC_VOLUME 0x0B
-#define WM8961_AUDIO_INTERFACE_2 0x0E
-#define WM8961_SOFTWARE_RESET 0x0F
-#define WM8961_ALC1 0x11
-#define WM8961_ALC2 0x12
-#define WM8961_ALC3 0x13
-#define WM8961_NOISE_GATE 0x14
-#define WM8961_LEFT_ADC_VOLUME 0x15
-#define WM8961_RIGHT_ADC_VOLUME 0x16
-#define WM8961_ADDITIONAL_CONTROL_1 0x17
-#define WM8961_ADDITIONAL_CONTROL_2 0x18
-#define WM8961_PWR_MGMT_1 0x19
-#define WM8961_PWR_MGMT_2 0x1A
-#define WM8961_ADDITIONAL_CONTROL_3 0x1B
-#define WM8961_ANTI_POP 0x1C
-#define WM8961_CLOCKING_3 0x1E
-#define WM8961_ADCL_SIGNAL_PATH 0x20
-#define WM8961_ADCR_SIGNAL_PATH 0x21
-#define WM8961_LOUT2_VOLUME 0x28
-#define WM8961_ROUT2_VOLUME 0x29
-#define WM8961_PWR_MGMT_3 0x2F
-#define WM8961_ADDITIONAL_CONTROL_4 0x30
-#define WM8961_CLASS_D_CONTROL_1 0x31
-#define WM8961_CLASS_D_CONTROL_2 0x33
-#define WM8961_CLOCKING_4 0x38
-#define WM8961_DSP_SIDETONE_0 0x39
-#define WM8961_DSP_SIDETONE_1 0x3A
-#define WM8961_DC_SERVO_0 0x3C
-#define WM8961_DC_SERVO_1 0x3D
-#define WM8961_DC_SERVO_3 0x3F
-#define WM8961_DC_SERVO_5 0x41
-#define WM8961_ANALOGUE_PGA_BIAS 0x44
-#define WM8961_ANALOGUE_HP_0 0x45
-#define WM8961_ANALOGUE_HP_2 0x47
-#define WM8961_CHARGE_PUMP_1 0x48
-#define WM8961_CHARGE_PUMP_B 0x52
-#define WM8961_WRITE_SEQUENCER_1 0x57
-#define WM8961_WRITE_SEQUENCER_2 0x58
-#define WM8961_WRITE_SEQUENCER_3 0x59
-#define WM8961_WRITE_SEQUENCER_4 0x5A
-#define WM8961_WRITE_SEQUENCER_5 0x5B
-#define WM8961_WRITE_SEQUENCER_6 0x5C
-#define WM8961_WRITE_SEQUENCER_7 0x5D
-#define WM8961_GENERAL_TEST_1 0xFC
-
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - Left Input volume
- */
-#define WM8961_IPVU 0x0100 /* IPVU */
-#define WM8961_IPVU_MASK 0x0100 /* IPVU */
-#define WM8961_IPVU_SHIFT 8 /* IPVU */
-#define WM8961_IPVU_WIDTH 1 /* IPVU */
-#define WM8961_LINMUTE 0x0080 /* LINMUTE */
-#define WM8961_LINMUTE_MASK 0x0080 /* LINMUTE */
-#define WM8961_LINMUTE_SHIFT 7 /* LINMUTE */
-#define WM8961_LINMUTE_WIDTH 1 /* LINMUTE */
-#define WM8961_LIZC 0x0040 /* LIZC */
-#define WM8961_LIZC_MASK 0x0040 /* LIZC */
-#define WM8961_LIZC_SHIFT 6 /* LIZC */
-#define WM8961_LIZC_WIDTH 1 /* LIZC */
-#define WM8961_LINVOL_MASK 0x003F /* LINVOL - [5:0] */
-#define WM8961_LINVOL_SHIFT 0 /* LINVOL - [5:0] */
-#define WM8961_LINVOL_WIDTH 6 /* LINVOL - [5:0] */
-
-/*
- * R1 (0x01) - Right Input volume
- */
-#define WM8961_DEVICE_ID_MASK 0xF000 /* DEVICE_ID - [15:12] */
-#define WM8961_DEVICE_ID_SHIFT 12 /* DEVICE_ID - [15:12] */
-#define WM8961_DEVICE_ID_WIDTH 4 /* DEVICE_ID - [15:12] */
-#define WM8961_CHIP_REV_MASK 0x0E00 /* CHIP_REV - [11:9] */
-#define WM8961_CHIP_REV_SHIFT 9 /* CHIP_REV - [11:9] */
-#define WM8961_CHIP_REV_WIDTH 3 /* CHIP_REV - [11:9] */
-#define WM8961_IPVU 0x0100 /* IPVU */
-#define WM8961_IPVU_MASK 0x0100 /* IPVU */
-#define WM8961_IPVU_SHIFT 8 /* IPVU */
-#define WM8961_IPVU_WIDTH 1 /* IPVU */
-#define WM8961_RINMUTE 0x0080 /* RINMUTE */
-#define WM8961_RINMUTE_MASK 0x0080 /* RINMUTE */
-#define WM8961_RINMUTE_SHIFT 7 /* RINMUTE */
-#define WM8961_RINMUTE_WIDTH 1 /* RINMUTE */
-#define WM8961_RIZC 0x0040 /* RIZC */
-#define WM8961_RIZC_MASK 0x0040 /* RIZC */
-#define WM8961_RIZC_SHIFT 6 /* RIZC */
-#define WM8961_RIZC_WIDTH 1 /* RIZC */
-#define WM8961_RINVOL_MASK 0x003F /* RINVOL - [5:0] */
-#define WM8961_RINVOL_SHIFT 0 /* RINVOL - [5:0] */
-#define WM8961_RINVOL_WIDTH 6 /* RINVOL - [5:0] */
-
-/*
- * R2 (0x02) - LOUT1 volume
- */
-#define WM8961_OUT1VU 0x0100 /* OUT1VU */
-#define WM8961_OUT1VU_MASK 0x0100 /* OUT1VU */
-#define WM8961_OUT1VU_SHIFT 8 /* OUT1VU */
-#define WM8961_OUT1VU_WIDTH 1 /* OUT1VU */
-#define WM8961_LO1ZC 0x0080 /* LO1ZC */
-#define WM8961_LO1ZC_MASK 0x0080 /* LO1ZC */
-#define WM8961_LO1ZC_SHIFT 7 /* LO1ZC */
-#define WM8961_LO1ZC_WIDTH 1 /* LO1ZC */
-#define WM8961_LOUT1VOL_MASK 0x007F /* LOUT1VOL - [6:0] */
-#define WM8961_LOUT1VOL_SHIFT 0 /* LOUT1VOL - [6:0] */
-#define WM8961_LOUT1VOL_WIDTH 7 /* LOUT1VOL - [6:0] */
-
-/*
- * R3 (0x03) - ROUT1 volume
- */
-#define WM8961_OUT1VU 0x0100 /* OUT1VU */
-#define WM8961_OUT1VU_MASK 0x0100 /* OUT1VU */
-#define WM8961_OUT1VU_SHIFT 8 /* OUT1VU */
-#define WM8961_OUT1VU_WIDTH 1 /* OUT1VU */
-#define WM8961_RO1ZC 0x0080 /* RO1ZC */
-#define WM8961_RO1ZC_MASK 0x0080 /* RO1ZC */
-#define WM8961_RO1ZC_SHIFT 7 /* RO1ZC */
-#define WM8961_RO1ZC_WIDTH 1 /* RO1ZC */
-#define WM8961_ROUT1VOL_MASK 0x007F /* ROUT1VOL - [6:0] */
-#define WM8961_ROUT1VOL_SHIFT 0 /* ROUT1VOL - [6:0] */
-#define WM8961_ROUT1VOL_WIDTH 7 /* ROUT1VOL - [6:0] */
-
-/*
- * R4 (0x04) - Clocking1
- */
-#define WM8961_ADCDIV_MASK 0x01C0 /* ADCDIV - [8:6] */
-#define WM8961_ADCDIV_SHIFT 6 /* ADCDIV - [8:6] */
-#define WM8961_ADCDIV_WIDTH 3 /* ADCDIV - [8:6] */
-#define WM8961_DACDIV_MASK 0x0038 /* DACDIV - [5:3] */
-#define WM8961_DACDIV_SHIFT 3 /* DACDIV - [5:3] */
-#define WM8961_DACDIV_WIDTH 3 /* DACDIV - [5:3] */
-#define WM8961_MCLKDIV 0x0004 /* MCLKDIV */
-#define WM8961_MCLKDIV_MASK 0x0004 /* MCLKDIV */
-#define WM8961_MCLKDIV_SHIFT 2 /* MCLKDIV */
-#define WM8961_MCLKDIV_WIDTH 1 /* MCLKDIV */
-
-/*
- * R5 (0x05) - ADC & DAC Control 1
- */
-#define WM8961_ADCPOL_MASK 0x0060 /* ADCPOL - [6:5] */
-#define WM8961_ADCPOL_SHIFT 5 /* ADCPOL - [6:5] */
-#define WM8961_ADCPOL_WIDTH 2 /* ADCPOL - [6:5] */
-#define WM8961_DACMU 0x0008 /* DACMU */
-#define WM8961_DACMU_MASK 0x0008 /* DACMU */
-#define WM8961_DACMU_SHIFT 3 /* DACMU */
-#define WM8961_DACMU_WIDTH 1 /* DACMU */
-#define WM8961_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */
-#define WM8961_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */
-#define WM8961_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */
-#define WM8961_ADCHPD 0x0001 /* ADCHPD */
-#define WM8961_ADCHPD_MASK 0x0001 /* ADCHPD */
-#define WM8961_ADCHPD_SHIFT 0 /* ADCHPD */
-#define WM8961_ADCHPD_WIDTH 1 /* ADCHPD */
-
-/*
- * R6 (0x06) - ADC & DAC Control 2
- */
-#define WM8961_ADC_HPF_CUT_MASK 0x0180 /* ADC_HPF_CUT - [8:7] */
-#define WM8961_ADC_HPF_CUT_SHIFT 7 /* ADC_HPF_CUT - [8:7] */
-#define WM8961_ADC_HPF_CUT_WIDTH 2 /* ADC_HPF_CUT - [8:7] */
-#define WM8961_DACPOL_MASK 0x0060 /* DACPOL - [6:5] */
-#define WM8961_DACPOL_SHIFT 5 /* DACPOL - [6:5] */
-#define WM8961_DACPOL_WIDTH 2 /* DACPOL - [6:5] */
-#define WM8961_DACSMM 0x0008 /* DACSMM */
-#define WM8961_DACSMM_MASK 0x0008 /* DACSMM */
-#define WM8961_DACSMM_SHIFT 3 /* DACSMM */
-#define WM8961_DACSMM_WIDTH 1 /* DACSMM */
-#define WM8961_DACMR 0x0004 /* DACMR */
-#define WM8961_DACMR_MASK 0x0004 /* DACMR */
-#define WM8961_DACMR_SHIFT 2 /* DACMR */
-#define WM8961_DACMR_WIDTH 1 /* DACMR */
-#define WM8961_DACSLOPE 0x0002 /* DACSLOPE */
-#define WM8961_DACSLOPE_MASK 0x0002 /* DACSLOPE */
-#define WM8961_DACSLOPE_SHIFT 1 /* DACSLOPE */
-#define WM8961_DACSLOPE_WIDTH 1 /* DACSLOPE */
-#define WM8961_DAC_OSR128 0x0001 /* DAC_OSR128 */
-#define WM8961_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */
-#define WM8961_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */
-#define WM8961_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
-
-/*
- * R7 (0x07) - Audio Interface 0
- */
-#define WM8961_ALRSWAP 0x0100 /* ALRSWAP */
-#define WM8961_ALRSWAP_MASK 0x0100 /* ALRSWAP */
-#define WM8961_ALRSWAP_SHIFT 8 /* ALRSWAP */
-#define WM8961_ALRSWAP_WIDTH 1 /* ALRSWAP */
-#define WM8961_BCLKINV 0x0080 /* BCLKINV */
-#define WM8961_BCLKINV_MASK 0x0080 /* BCLKINV */
-#define WM8961_BCLKINV_SHIFT 7 /* BCLKINV */
-#define WM8961_BCLKINV_WIDTH 1 /* BCLKINV */
-#define WM8961_MS 0x0040 /* MS */
-#define WM8961_MS_MASK 0x0040 /* MS */
-#define WM8961_MS_SHIFT 6 /* MS */
-#define WM8961_MS_WIDTH 1 /* MS */
-#define WM8961_DLRSWAP 0x0020 /* DLRSWAP */
-#define WM8961_DLRSWAP_MASK 0x0020 /* DLRSWAP */
-#define WM8961_DLRSWAP_SHIFT 5 /* DLRSWAP */
-#define WM8961_DLRSWAP_WIDTH 1 /* DLRSWAP */
-#define WM8961_LRP 0x0010 /* LRP */
-#define WM8961_LRP_MASK 0x0010 /* LRP */
-#define WM8961_LRP_SHIFT 4 /* LRP */
-#define WM8961_LRP_WIDTH 1 /* LRP */
-#define WM8961_WL_MASK 0x000C /* WL - [3:2] */
-#define WM8961_WL_SHIFT 2 /* WL - [3:2] */
-#define WM8961_WL_WIDTH 2 /* WL - [3:2] */
-#define WM8961_FORMAT_MASK 0x0003 /* FORMAT - [1:0] */
-#define WM8961_FORMAT_SHIFT 0 /* FORMAT - [1:0] */
-#define WM8961_FORMAT_WIDTH 2 /* FORMAT - [1:0] */
-
-/*
- * R8 (0x08) - Clocking2
- */
-#define WM8961_DCLKDIV_MASK 0x01C0 /* DCLKDIV - [8:6] */
-#define WM8961_DCLKDIV_SHIFT 6 /* DCLKDIV - [8:6] */
-#define WM8961_DCLKDIV_WIDTH 3 /* DCLKDIV - [8:6] */
-#define WM8961_CLK_SYS_ENA 0x0020 /* CLK_SYS_ENA */
-#define WM8961_CLK_SYS_ENA_MASK 0x0020 /* CLK_SYS_ENA */
-#define WM8961_CLK_SYS_ENA_SHIFT 5 /* CLK_SYS_ENA */
-#define WM8961_CLK_SYS_ENA_WIDTH 1 /* CLK_SYS_ENA */
-#define WM8961_CLK_DSP_ENA 0x0010 /* CLK_DSP_ENA */
-#define WM8961_CLK_DSP_ENA_MASK 0x0010 /* CLK_DSP_ENA */
-#define WM8961_CLK_DSP_ENA_SHIFT 4 /* CLK_DSP_ENA */
-#define WM8961_CLK_DSP_ENA_WIDTH 1 /* CLK_DSP_ENA */
-#define WM8961_BCLKDIV_MASK 0x000F /* BCLKDIV - [3:0] */
-#define WM8961_BCLKDIV_SHIFT 0 /* BCLKDIV - [3:0] */
-#define WM8961_BCLKDIV_WIDTH 4 /* BCLKDIV - [3:0] */
-
-/*
- * R9 (0x09) - Audio Interface 1
- */
-#define WM8961_DACCOMP_MASK 0x0018 /* DACCOMP - [4:3] */
-#define WM8961_DACCOMP_SHIFT 3 /* DACCOMP - [4:3] */
-#define WM8961_DACCOMP_WIDTH 2 /* DACCOMP - [4:3] */
-#define WM8961_ADCCOMP_MASK 0x0006 /* ADCCOMP - [2:1] */
-#define WM8961_ADCCOMP_SHIFT 1 /* ADCCOMP - [2:1] */
-#define WM8961_ADCCOMP_WIDTH 2 /* ADCCOMP - [2:1] */
-#define WM8961_LOOPBACK 0x0001 /* LOOPBACK */
-#define WM8961_LOOPBACK_MASK 0x0001 /* LOOPBACK */
-#define WM8961_LOOPBACK_SHIFT 0 /* LOOPBACK */
-#define WM8961_LOOPBACK_WIDTH 1 /* LOOPBACK */
-
-/*
- * R10 (0x0A) - Left DAC volume
- */
-#define WM8961_DACVU 0x0100 /* DACVU */
-#define WM8961_DACVU_MASK 0x0100 /* DACVU */
-#define WM8961_DACVU_SHIFT 8 /* DACVU */
-#define WM8961_DACVU_WIDTH 1 /* DACVU */
-#define WM8961_LDACVOL_MASK 0x00FF /* LDACVOL - [7:0] */
-#define WM8961_LDACVOL_SHIFT 0 /* LDACVOL - [7:0] */
-#define WM8961_LDACVOL_WIDTH 8 /* LDACVOL - [7:0] */
-
-/*
- * R11 (0x0B) - Right DAC volume
- */
-#define WM8961_DACVU 0x0100 /* DACVU */
-#define WM8961_DACVU_MASK 0x0100 /* DACVU */
-#define WM8961_DACVU_SHIFT 8 /* DACVU */
-#define WM8961_DACVU_WIDTH 1 /* DACVU */
-#define WM8961_RDACVOL_MASK 0x00FF /* RDACVOL - [7:0] */
-#define WM8961_RDACVOL_SHIFT 0 /* RDACVOL - [7:0] */
-#define WM8961_RDACVOL_WIDTH 8 /* RDACVOL - [7:0] */
-
-/*
- * R14 (0x0E) - Audio Interface 2
- */
-#define WM8961_LRCLK_RATE_MASK 0x01FF /* LRCLK_RATE - [8:0] */
-#define WM8961_LRCLK_RATE_SHIFT 0 /* LRCLK_RATE - [8:0] */
-#define WM8961_LRCLK_RATE_WIDTH 9 /* LRCLK_RATE - [8:0] */
-
-/*
- * R15 (0x0F) - Software Reset
- */
-#define WM8961_SW_RST_DEV_ID1_MASK 0xFFFF /* SW_RST_DEV_ID1 - [15:0] */
-#define WM8961_SW_RST_DEV_ID1_SHIFT 0 /* SW_RST_DEV_ID1 - [15:0] */
-#define WM8961_SW_RST_DEV_ID1_WIDTH 16 /* SW_RST_DEV_ID1 - [15:0] */
-
-/*
- * R17 (0x11) - ALC1
- */
-#define WM8961_ALCSEL_MASK 0x0180 /* ALCSEL - [8:7] */
-#define WM8961_ALCSEL_SHIFT 7 /* ALCSEL - [8:7] */
-#define WM8961_ALCSEL_WIDTH 2 /* ALCSEL - [8:7] */
-#define WM8961_MAXGAIN_MASK 0x0070 /* MAXGAIN - [6:4] */
-#define WM8961_MAXGAIN_SHIFT 4 /* MAXGAIN - [6:4] */
-#define WM8961_MAXGAIN_WIDTH 3 /* MAXGAIN - [6:4] */
-#define WM8961_ALCL_MASK 0x000F /* ALCL - [3:0] */
-#define WM8961_ALCL_SHIFT 0 /* ALCL - [3:0] */
-#define WM8961_ALCL_WIDTH 4 /* ALCL - [3:0] */
-
-/*
- * R18 (0x12) - ALC2
- */
-#define WM8961_ALCZC 0x0080 /* ALCZC */
-#define WM8961_ALCZC_MASK 0x0080 /* ALCZC */
-#define WM8961_ALCZC_SHIFT 7 /* ALCZC */
-#define WM8961_ALCZC_WIDTH 1 /* ALCZC */
-#define WM8961_MINGAIN_MASK 0x0070 /* MINGAIN - [6:4] */
-#define WM8961_MINGAIN_SHIFT 4 /* MINGAIN - [6:4] */
-#define WM8961_MINGAIN_WIDTH 3 /* MINGAIN - [6:4] */
-#define WM8961_HLD_MASK 0x000F /* HLD - [3:0] */
-#define WM8961_HLD_SHIFT 0 /* HLD - [3:0] */
-#define WM8961_HLD_WIDTH 4 /* HLD - [3:0] */
-
-/*
- * R19 (0x13) - ALC3
- */
-#define WM8961_ALCMODE 0x0100 /* ALCMODE */
-#define WM8961_ALCMODE_MASK 0x0100 /* ALCMODE */
-#define WM8961_ALCMODE_SHIFT 8 /* ALCMODE */
-#define WM8961_ALCMODE_WIDTH 1 /* ALCMODE */
-#define WM8961_DCY_MASK 0x00F0 /* DCY - [7:4] */
-#define WM8961_DCY_SHIFT 4 /* DCY - [7:4] */
-#define WM8961_DCY_WIDTH 4 /* DCY - [7:4] */
-#define WM8961_ATK_MASK 0x000F /* ATK - [3:0] */
-#define WM8961_ATK_SHIFT 0 /* ATK - [3:0] */
-#define WM8961_ATK_WIDTH 4 /* ATK - [3:0] */
-
-/*
- * R20 (0x14) - Noise Gate
- */
-#define WM8961_NGTH_MASK 0x00F8 /* NGTH - [7:3] */
-#define WM8961_NGTH_SHIFT 3 /* NGTH - [7:3] */
-#define WM8961_NGTH_WIDTH 5 /* NGTH - [7:3] */
-#define WM8961_NGG 0x0002 /* NGG */
-#define WM8961_NGG_MASK 0x0002 /* NGG */
-#define WM8961_NGG_SHIFT 1 /* NGG */
-#define WM8961_NGG_WIDTH 1 /* NGG */
-#define WM8961_NGAT 0x0001 /* NGAT */
-#define WM8961_NGAT_MASK 0x0001 /* NGAT */
-#define WM8961_NGAT_SHIFT 0 /* NGAT */
-#define WM8961_NGAT_WIDTH 1 /* NGAT */
-
-/*
- * R21 (0x15) - Left ADC volume
- */
-#define WM8961_ADCVU 0x0100 /* ADCVU */
-#define WM8961_ADCVU_MASK 0x0100 /* ADCVU */
-#define WM8961_ADCVU_SHIFT 8 /* ADCVU */
-#define WM8961_ADCVU_WIDTH 1 /* ADCVU */
-#define WM8961_LADCVOL_MASK 0x00FF /* LADCVOL - [7:0] */
-#define WM8961_LADCVOL_SHIFT 0 /* LADCVOL - [7:0] */
-#define WM8961_LADCVOL_WIDTH 8 /* LADCVOL - [7:0] */
-
-/*
- * R22 (0x16) - Right ADC volume
- */
-#define WM8961_ADCVU 0x0100 /* ADCVU */
-#define WM8961_ADCVU_MASK 0x0100 /* ADCVU */
-#define WM8961_ADCVU_SHIFT 8 /* ADCVU */
-#define WM8961_ADCVU_WIDTH 1 /* ADCVU */
-#define WM8961_RADCVOL_MASK 0x00FF /* RADCVOL - [7:0] */
-#define WM8961_RADCVOL_SHIFT 0 /* RADCVOL - [7:0] */
-#define WM8961_RADCVOL_WIDTH 8 /* RADCVOL - [7:0] */
-
-/*
- * R23 (0x17) - Additional control(1)
- */
-#define WM8961_TSDEN 0x0100 /* TSDEN */
-#define WM8961_TSDEN_MASK 0x0100 /* TSDEN */
-#define WM8961_TSDEN_SHIFT 8 /* TSDEN */
-#define WM8961_TSDEN_WIDTH 1 /* TSDEN */
-#define WM8961_DMONOMIX 0x0010 /* DMONOMIX */
-#define WM8961_DMONOMIX_MASK 0x0010 /* DMONOMIX */
-#define WM8961_DMONOMIX_SHIFT 4 /* DMONOMIX */
-#define WM8961_DMONOMIX_WIDTH 1 /* DMONOMIX */
-#define WM8961_TOEN 0x0001 /* TOEN */
-#define WM8961_TOEN_MASK 0x0001 /* TOEN */
-#define WM8961_TOEN_SHIFT 0 /* TOEN */
-#define WM8961_TOEN_WIDTH 1 /* TOEN */
-
-/*
- * R24 (0x18) - Additional control(2)
- */
-#define WM8961_TRIS 0x0008 /* TRIS */
-#define WM8961_TRIS_MASK 0x0008 /* TRIS */
-#define WM8961_TRIS_SHIFT 3 /* TRIS */
-#define WM8961_TRIS_WIDTH 1 /* TRIS */
-
-/*
- * R25 (0x19) - Pwr Mgmt (1)
- */
-#define WM8961_VMIDSEL_MASK 0x0180 /* VMIDSEL - [8:7] */
-#define WM8961_VMIDSEL_SHIFT 7 /* VMIDSEL - [8:7] */
-#define WM8961_VMIDSEL_WIDTH 2 /* VMIDSEL - [8:7] */
-#define WM8961_VREF 0x0040 /* VREF */
-#define WM8961_VREF_MASK 0x0040 /* VREF */
-#define WM8961_VREF_SHIFT 6 /* VREF */
-#define WM8961_VREF_WIDTH 1 /* VREF */
-#define WM8961_AINL 0x0020 /* AINL */
-#define WM8961_AINL_MASK 0x0020 /* AINL */
-#define WM8961_AINL_SHIFT 5 /* AINL */
-#define WM8961_AINL_WIDTH 1 /* AINL */
-#define WM8961_AINR 0x0010 /* AINR */
-#define WM8961_AINR_MASK 0x0010 /* AINR */
-#define WM8961_AINR_SHIFT 4 /* AINR */
-#define WM8961_AINR_WIDTH 1 /* AINR */
-#define WM8961_ADCL 0x0008 /* ADCL */
-#define WM8961_ADCL_MASK 0x0008 /* ADCL */
-#define WM8961_ADCL_SHIFT 3 /* ADCL */
-#define WM8961_ADCL_WIDTH 1 /* ADCL */
-#define WM8961_ADCR 0x0004 /* ADCR */
-#define WM8961_ADCR_MASK 0x0004 /* ADCR */
-#define WM8961_ADCR_SHIFT 2 /* ADCR */
-#define WM8961_ADCR_WIDTH 1 /* ADCR */
-#define WM8961_MICB 0x0002 /* MICB */
-#define WM8961_MICB_MASK 0x0002 /* MICB */
-#define WM8961_MICB_SHIFT 1 /* MICB */
-#define WM8961_MICB_WIDTH 1 /* MICB */
-
-/*
- * R26 (0x1A) - Pwr Mgmt (2)
- */
-#define WM8961_DACL 0x0100 /* DACL */
-#define WM8961_DACL_MASK 0x0100 /* DACL */
-#define WM8961_DACL_SHIFT 8 /* DACL */
-#define WM8961_DACL_WIDTH 1 /* DACL */
-#define WM8961_DACR 0x0080 /* DACR */
-#define WM8961_DACR_MASK 0x0080 /* DACR */
-#define WM8961_DACR_SHIFT 7 /* DACR */
-#define WM8961_DACR_WIDTH 1 /* DACR */
-#define WM8961_LOUT1_PGA 0x0040 /* LOUT1_PGA */
-#define WM8961_LOUT1_PGA_MASK 0x0040 /* LOUT1_PGA */
-#define WM8961_LOUT1_PGA_SHIFT 6 /* LOUT1_PGA */
-#define WM8961_LOUT1_PGA_WIDTH 1 /* LOUT1_PGA */
-#define WM8961_ROUT1_PGA 0x0020 /* ROUT1_PGA */
-#define WM8961_ROUT1_PGA_MASK 0x0020 /* ROUT1_PGA */
-#define WM8961_ROUT1_PGA_SHIFT 5 /* ROUT1_PGA */
-#define WM8961_ROUT1_PGA_WIDTH 1 /* ROUT1_PGA */
-#define WM8961_SPKL_PGA 0x0010 /* SPKL_PGA */
-#define WM8961_SPKL_PGA_MASK 0x0010 /* SPKL_PGA */
-#define WM8961_SPKL_PGA_SHIFT 4 /* SPKL_PGA */
-#define WM8961_SPKL_PGA_WIDTH 1 /* SPKL_PGA */
-#define WM8961_SPKR_PGA 0x0008 /* SPKR_PGA */
-#define WM8961_SPKR_PGA_MASK 0x0008 /* SPKR_PGA */
-#define WM8961_SPKR_PGA_SHIFT 3 /* SPKR_PGA */
-#define WM8961_SPKR_PGA_WIDTH 1 /* SPKR_PGA */
-
-/*
- * R27 (0x1B) - Additional Control (3)
- */
-#define WM8961_SAMPLE_RATE_MASK 0x0007 /* SAMPLE_RATE - [2:0] */
-#define WM8961_SAMPLE_RATE_SHIFT 0 /* SAMPLE_RATE - [2:0] */
-#define WM8961_SAMPLE_RATE_WIDTH 3 /* SAMPLE_RATE - [2:0] */
-
-/*
- * R28 (0x1C) - Anti-pop
- */
-#define WM8961_BUFDCOPEN 0x0010 /* BUFDCOPEN */
-#define WM8961_BUFDCOPEN_MASK 0x0010 /* BUFDCOPEN */
-#define WM8961_BUFDCOPEN_SHIFT 4 /* BUFDCOPEN */
-#define WM8961_BUFDCOPEN_WIDTH 1 /* BUFDCOPEN */
-#define WM8961_BUFIOEN 0x0008 /* BUFIOEN */
-#define WM8961_BUFIOEN_MASK 0x0008 /* BUFIOEN */
-#define WM8961_BUFIOEN_SHIFT 3 /* BUFIOEN */
-#define WM8961_BUFIOEN_WIDTH 1 /* BUFIOEN */
-#define WM8961_SOFT_ST 0x0004 /* SOFT_ST */
-#define WM8961_SOFT_ST_MASK 0x0004 /* SOFT_ST */
-#define WM8961_SOFT_ST_SHIFT 2 /* SOFT_ST */
-#define WM8961_SOFT_ST_WIDTH 1 /* SOFT_ST */
-
-/*
- * R30 (0x1E) - Clocking 3
- */
-#define WM8961_CLK_TO_DIV_MASK 0x0180 /* CLK_TO_DIV - [8:7] */
-#define WM8961_CLK_TO_DIV_SHIFT 7 /* CLK_TO_DIV - [8:7] */
-#define WM8961_CLK_TO_DIV_WIDTH 2 /* CLK_TO_DIV - [8:7] */
-#define WM8961_CLK_256K_DIV_MASK 0x007E /* CLK_256K_DIV - [6:1] */
-#define WM8961_CLK_256K_DIV_SHIFT 1 /* CLK_256K_DIV - [6:1] */
-#define WM8961_CLK_256K_DIV_WIDTH 6 /* CLK_256K_DIV - [6:1] */
-#define WM8961_MANUAL_MODE 0x0001 /* MANUAL_MODE */
-#define WM8961_MANUAL_MODE_MASK 0x0001 /* MANUAL_MODE */
-#define WM8961_MANUAL_MODE_SHIFT 0 /* MANUAL_MODE */
-#define WM8961_MANUAL_MODE_WIDTH 1 /* MANUAL_MODE */
-
-/*
- * R32 (0x20) - ADCL signal path
- */
-#define WM8961_LMICBOOST_MASK 0x0030 /* LMICBOOST - [5:4] */
-#define WM8961_LMICBOOST_SHIFT 4 /* LMICBOOST - [5:4] */
-#define WM8961_LMICBOOST_WIDTH 2 /* LMICBOOST - [5:4] */
-
-/*
- * R33 (0x21) - ADCR signal path
- */
-#define WM8961_RMICBOOST_MASK 0x0030 /* RMICBOOST - [5:4] */
-#define WM8961_RMICBOOST_SHIFT 4 /* RMICBOOST - [5:4] */
-#define WM8961_RMICBOOST_WIDTH 2 /* RMICBOOST - [5:4] */
-
-/*
- * R40 (0x28) - LOUT2 volume
- */
-#define WM8961_SPKVU 0x0100 /* SPKVU */
-#define WM8961_SPKVU_MASK 0x0100 /* SPKVU */
-#define WM8961_SPKVU_SHIFT 8 /* SPKVU */
-#define WM8961_SPKVU_WIDTH 1 /* SPKVU */
-#define WM8961_SPKLZC 0x0080 /* SPKLZC */
-#define WM8961_SPKLZC_MASK 0x0080 /* SPKLZC */
-#define WM8961_SPKLZC_SHIFT 7 /* SPKLZC */
-#define WM8961_SPKLZC_WIDTH 1 /* SPKLZC */
-#define WM8961_SPKLVOL_MASK 0x007F /* SPKLVOL - [6:0] */
-#define WM8961_SPKLVOL_SHIFT 0 /* SPKLVOL - [6:0] */
-#define WM8961_SPKLVOL_WIDTH 7 /* SPKLVOL - [6:0] */
-
-/*
- * R41 (0x29) - ROUT2 volume
- */
-#define WM8961_SPKVU 0x0100 /* SPKVU */
-#define WM8961_SPKVU_MASK 0x0100 /* SPKVU */
-#define WM8961_SPKVU_SHIFT 8 /* SPKVU */
-#define WM8961_SPKVU_WIDTH 1 /* SPKVU */
-#define WM8961_SPKRZC 0x0080 /* SPKRZC */
-#define WM8961_SPKRZC_MASK 0x0080 /* SPKRZC */
-#define WM8961_SPKRZC_SHIFT 7 /* SPKRZC */
-#define WM8961_SPKRZC_WIDTH 1 /* SPKRZC */
-#define WM8961_SPKRVOL_MASK 0x007F /* SPKRVOL - [6:0] */
-#define WM8961_SPKRVOL_SHIFT 0 /* SPKRVOL - [6:0] */
-#define WM8961_SPKRVOL_WIDTH 7 /* SPKRVOL - [6:0] */
-
-/*
- * R47 (0x2F) - Pwr Mgmt (3)
- */
-#define WM8961_TEMP_SHUT 0x0002 /* TEMP_SHUT */
-#define WM8961_TEMP_SHUT_MASK 0x0002 /* TEMP_SHUT */
-#define WM8961_TEMP_SHUT_SHIFT 1 /* TEMP_SHUT */
-#define WM8961_TEMP_SHUT_WIDTH 1 /* TEMP_SHUT */
-#define WM8961_TEMP_WARN 0x0001 /* TEMP_WARN */
-#define WM8961_TEMP_WARN_MASK 0x0001 /* TEMP_WARN */
-#define WM8961_TEMP_WARN_SHIFT 0 /* TEMP_WARN */
-#define WM8961_TEMP_WARN_WIDTH 1 /* TEMP_WARN */
-
-/*
- * R48 (0x30) - Additional Control (4)
- */
-#define WM8961_TSENSEN 0x0002 /* TSENSEN */
-#define WM8961_TSENSEN_MASK 0x0002 /* TSENSEN */
-#define WM8961_TSENSEN_SHIFT 1 /* TSENSEN */
-#define WM8961_TSENSEN_WIDTH 1 /* TSENSEN */
-#define WM8961_MBSEL 0x0001 /* MBSEL */
-#define WM8961_MBSEL_MASK 0x0001 /* MBSEL */
-#define WM8961_MBSEL_SHIFT 0 /* MBSEL */
-#define WM8961_MBSEL_WIDTH 1 /* MBSEL */
-
-/*
- * R49 (0x31) - Class D Control 1
- */
-#define WM8961_SPKR_ENA 0x0080 /* SPKR_ENA */
-#define WM8961_SPKR_ENA_MASK 0x0080 /* SPKR_ENA */
-#define WM8961_SPKR_ENA_SHIFT 7 /* SPKR_ENA */
-#define WM8961_SPKR_ENA_WIDTH 1 /* SPKR_ENA */
-#define WM8961_SPKL_ENA 0x0040 /* SPKL_ENA */
-#define WM8961_SPKL_ENA_MASK 0x0040 /* SPKL_ENA */
-#define WM8961_SPKL_ENA_SHIFT 6 /* SPKL_ENA */
-#define WM8961_SPKL_ENA_WIDTH 1 /* SPKL_ENA */
-
-/*
- * R51 (0x33) - Class D Control 2
- */
-#define WM8961_CLASSD_ACGAIN_MASK 0x0007 /* CLASSD_ACGAIN - [2:0] */
-#define WM8961_CLASSD_ACGAIN_SHIFT 0 /* CLASSD_ACGAIN - [2:0] */
-#define WM8961_CLASSD_ACGAIN_WIDTH 3 /* CLASSD_ACGAIN - [2:0] */
-
-/*
- * R56 (0x38) - Clocking 4
- */
-#define WM8961_CLK_DCS_DIV_MASK 0x01E0 /* CLK_DCS_DIV - [8:5] */
-#define WM8961_CLK_DCS_DIV_SHIFT 5 /* CLK_DCS_DIV - [8:5] */
-#define WM8961_CLK_DCS_DIV_WIDTH 4 /* CLK_DCS_DIV - [8:5] */
-#define WM8961_CLK_SYS_RATE_MASK 0x001E /* CLK_SYS_RATE - [4:1] */
-#define WM8961_CLK_SYS_RATE_SHIFT 1 /* CLK_SYS_RATE - [4:1] */
-#define WM8961_CLK_SYS_RATE_WIDTH 4 /* CLK_SYS_RATE - [4:1] */
-
-/*
- * R57 (0x39) - DSP Sidetone 0
- */
-#define WM8961_ADCR_DAC_SVOL_MASK 0x00F0 /* ADCR_DAC_SVOL - [7:4] */
-#define WM8961_ADCR_DAC_SVOL_SHIFT 4 /* ADCR_DAC_SVOL - [7:4] */
-#define WM8961_ADCR_DAC_SVOL_WIDTH 4 /* ADCR_DAC_SVOL - [7:4] */
-#define WM8961_ADC_TO_DACR_MASK 0x000C /* ADC_TO_DACR - [3:2] */
-#define WM8961_ADC_TO_DACR_SHIFT 2 /* ADC_TO_DACR - [3:2] */
-#define WM8961_ADC_TO_DACR_WIDTH 2 /* ADC_TO_DACR - [3:2] */
-
-/*
- * R58 (0x3A) - DSP Sidetone 1
- */
-#define WM8961_ADCL_DAC_SVOL_MASK 0x00F0 /* ADCL_DAC_SVOL - [7:4] */
-#define WM8961_ADCL_DAC_SVOL_SHIFT 4 /* ADCL_DAC_SVOL - [7:4] */
-#define WM8961_ADCL_DAC_SVOL_WIDTH 4 /* ADCL_DAC_SVOL - [7:4] */
-#define WM8961_ADC_TO_DACL_MASK 0x000C /* ADC_TO_DACL - [3:2] */
-#define WM8961_ADC_TO_DACL_SHIFT 2 /* ADC_TO_DACL - [3:2] */
-#define WM8961_ADC_TO_DACL_WIDTH 2 /* ADC_TO_DACL - [3:2] */
-
-/*
- * R60 (0x3C) - DC Servo 0
- */
-#define WM8961_DCS_ENA_CHAN_INL 0x0080 /* DCS_ENA_CHAN_INL */
-#define WM8961_DCS_ENA_CHAN_INL_MASK 0x0080 /* DCS_ENA_CHAN_INL */
-#define WM8961_DCS_ENA_CHAN_INL_SHIFT 7 /* DCS_ENA_CHAN_INL */
-#define WM8961_DCS_ENA_CHAN_INL_WIDTH 1 /* DCS_ENA_CHAN_INL */
-#define WM8961_DCS_TRIG_STARTUP_INL 0x0040 /* DCS_TRIG_STARTUP_INL */
-#define WM8961_DCS_TRIG_STARTUP_INL_MASK 0x0040 /* DCS_TRIG_STARTUP_INL */
-#define WM8961_DCS_TRIG_STARTUP_INL_SHIFT 6 /* DCS_TRIG_STARTUP_INL */
-#define WM8961_DCS_TRIG_STARTUP_INL_WIDTH 1 /* DCS_TRIG_STARTUP_INL */
-#define WM8961_DCS_TRIG_SERIES_INL 0x0010 /* DCS_TRIG_SERIES_INL */
-#define WM8961_DCS_TRIG_SERIES_INL_MASK 0x0010 /* DCS_TRIG_SERIES_INL */
-#define WM8961_DCS_TRIG_SERIES_INL_SHIFT 4 /* DCS_TRIG_SERIES_INL */
-#define WM8961_DCS_TRIG_SERIES_INL_WIDTH 1 /* DCS_TRIG_SERIES_INL */
-#define WM8961_DCS_ENA_CHAN_INR 0x0008 /* DCS_ENA_CHAN_INR */
-#define WM8961_DCS_ENA_CHAN_INR_MASK 0x0008 /* DCS_ENA_CHAN_INR */
-#define WM8961_DCS_ENA_CHAN_INR_SHIFT 3 /* DCS_ENA_CHAN_INR */
-#define WM8961_DCS_ENA_CHAN_INR_WIDTH 1 /* DCS_ENA_CHAN_INR */
-#define WM8961_DCS_TRIG_STARTUP_INR 0x0004 /* DCS_TRIG_STARTUP_INR */
-#define WM8961_DCS_TRIG_STARTUP_INR_MASK 0x0004 /* DCS_TRIG_STARTUP_INR */
-#define WM8961_DCS_TRIG_STARTUP_INR_SHIFT 2 /* DCS_TRIG_STARTUP_INR */
-#define WM8961_DCS_TRIG_STARTUP_INR_WIDTH 1 /* DCS_TRIG_STARTUP_INR */
-#define WM8961_DCS_TRIG_SERIES_INR 0x0001 /* DCS_TRIG_SERIES_INR */
-#define WM8961_DCS_TRIG_SERIES_INR_MASK 0x0001 /* DCS_TRIG_SERIES_INR */
-#define WM8961_DCS_TRIG_SERIES_INR_SHIFT 0 /* DCS_TRIG_SERIES_INR */
-#define WM8961_DCS_TRIG_SERIES_INR_WIDTH 1 /* DCS_TRIG_SERIES_INR */
-
-/*
- * R61 (0x3D) - DC Servo 1
- */
-#define WM8961_DCS_ENA_CHAN_HPL 0x0080 /* DCS_ENA_CHAN_HPL */
-#define WM8961_DCS_ENA_CHAN_HPL_MASK 0x0080 /* DCS_ENA_CHAN_HPL */
-#define WM8961_DCS_ENA_CHAN_HPL_SHIFT 7 /* DCS_ENA_CHAN_HPL */
-#define WM8961_DCS_ENA_CHAN_HPL_WIDTH 1 /* DCS_ENA_CHAN_HPL */
-#define WM8961_DCS_TRIG_STARTUP_HPL 0x0040 /* DCS_TRIG_STARTUP_HPL */
-#define WM8961_DCS_TRIG_STARTUP_HPL_MASK 0x0040 /* DCS_TRIG_STARTUP_HPL */
-#define WM8961_DCS_TRIG_STARTUP_HPL_SHIFT 6 /* DCS_TRIG_STARTUP_HPL */
-#define WM8961_DCS_TRIG_STARTUP_HPL_WIDTH 1 /* DCS_TRIG_STARTUP_HPL */
-#define WM8961_DCS_TRIG_SERIES_HPL 0x0010 /* DCS_TRIG_SERIES_HPL */
-#define WM8961_DCS_TRIG_SERIES_HPL_MASK 0x0010 /* DCS_TRIG_SERIES_HPL */
-#define WM8961_DCS_TRIG_SERIES_HPL_SHIFT 4 /* DCS_TRIG_SERIES_HPL */
-#define WM8961_DCS_TRIG_SERIES_HPL_WIDTH 1 /* DCS_TRIG_SERIES_HPL */
-#define WM8961_DCS_ENA_CHAN_HPR 0x0008 /* DCS_ENA_CHAN_HPR */
-#define WM8961_DCS_ENA_CHAN_HPR_MASK 0x0008 /* DCS_ENA_CHAN_HPR */
-#define WM8961_DCS_ENA_CHAN_HPR_SHIFT 3 /* DCS_ENA_CHAN_HPR */
-#define WM8961_DCS_ENA_CHAN_HPR_WIDTH 1 /* DCS_ENA_CHAN_HPR */
-#define WM8961_DCS_TRIG_STARTUP_HPR 0x0004 /* DCS_TRIG_STARTUP_HPR */
-#define WM8961_DCS_TRIG_STARTUP_HPR_MASK 0x0004 /* DCS_TRIG_STARTUP_HPR */
-#define WM8961_DCS_TRIG_STARTUP_HPR_SHIFT 2 /* DCS_TRIG_STARTUP_HPR */
-#define WM8961_DCS_TRIG_STARTUP_HPR_WIDTH 1 /* DCS_TRIG_STARTUP_HPR */
-#define WM8961_DCS_TRIG_SERIES_HPR 0x0001 /* DCS_TRIG_SERIES_HPR */
-#define WM8961_DCS_TRIG_SERIES_HPR_MASK 0x0001 /* DCS_TRIG_SERIES_HPR */
-#define WM8961_DCS_TRIG_SERIES_HPR_SHIFT 0 /* DCS_TRIG_SERIES_HPR */
-#define WM8961_DCS_TRIG_SERIES_HPR_WIDTH 1 /* DCS_TRIG_SERIES_HPR */
-
-/*
- * R63 (0x3F) - DC Servo 3
- */
-#define WM8961_DCS_FILT_BW_SERIES_MASK 0x0030 /* DCS_FILT_BW_SERIES - [5:4] */
-#define WM8961_DCS_FILT_BW_SERIES_SHIFT 4 /* DCS_FILT_BW_SERIES - [5:4] */
-#define WM8961_DCS_FILT_BW_SERIES_WIDTH 2 /* DCS_FILT_BW_SERIES - [5:4] */
-
-/*
- * R65 (0x41) - DC Servo 5
- */
-#define WM8961_DCS_SERIES_NO_HP_MASK 0x007F /* DCS_SERIES_NO_HP - [6:0] */
-#define WM8961_DCS_SERIES_NO_HP_SHIFT 0 /* DCS_SERIES_NO_HP - [6:0] */
-#define WM8961_DCS_SERIES_NO_HP_WIDTH 7 /* DCS_SERIES_NO_HP - [6:0] */
-
-/*
- * R68 (0x44) - Analogue PGA Bias
- */
-#define WM8961_HP_PGAS_BIAS_MASK 0x0007 /* HP_PGAS_BIAS - [2:0] */
-#define WM8961_HP_PGAS_BIAS_SHIFT 0 /* HP_PGAS_BIAS - [2:0] */
-#define WM8961_HP_PGAS_BIAS_WIDTH 3 /* HP_PGAS_BIAS - [2:0] */
-
-/*
- * R69 (0x45) - Analogue HP 0
- */
-#define WM8961_HPL_RMV_SHORT 0x0080 /* HPL_RMV_SHORT */
-#define WM8961_HPL_RMV_SHORT_MASK 0x0080 /* HPL_RMV_SHORT */
-#define WM8961_HPL_RMV_SHORT_SHIFT 7 /* HPL_RMV_SHORT */
-#define WM8961_HPL_RMV_SHORT_WIDTH 1 /* HPL_RMV_SHORT */
-#define WM8961_HPL_ENA_OUTP 0x0040 /* HPL_ENA_OUTP */
-#define WM8961_HPL_ENA_OUTP_MASK 0x0040 /* HPL_ENA_OUTP */
-#define WM8961_HPL_ENA_OUTP_SHIFT 6 /* HPL_ENA_OUTP */
-#define WM8961_HPL_ENA_OUTP_WIDTH 1 /* HPL_ENA_OUTP */
-#define WM8961_HPL_ENA_DLY 0x0020 /* HPL_ENA_DLY */
-#define WM8961_HPL_ENA_DLY_MASK 0x0020 /* HPL_ENA_DLY */
-#define WM8961_HPL_ENA_DLY_SHIFT 5 /* HPL_ENA_DLY */
-#define WM8961_HPL_ENA_DLY_WIDTH 1 /* HPL_ENA_DLY */
-#define WM8961_HPL_ENA 0x0010 /* HPL_ENA */
-#define WM8961_HPL_ENA_MASK 0x0010 /* HPL_ENA */
-#define WM8961_HPL_ENA_SHIFT 4 /* HPL_ENA */
-#define WM8961_HPL_ENA_WIDTH 1 /* HPL_ENA */
-#define WM8961_HPR_RMV_SHORT 0x0008 /* HPR_RMV_SHORT */
-#define WM8961_HPR_RMV_SHORT_MASK 0x0008 /* HPR_RMV_SHORT */
-#define WM8961_HPR_RMV_SHORT_SHIFT 3 /* HPR_RMV_SHORT */
-#define WM8961_HPR_RMV_SHORT_WIDTH 1 /* HPR_RMV_SHORT */
-#define WM8961_HPR_ENA_OUTP 0x0004 /* HPR_ENA_OUTP */
-#define WM8961_HPR_ENA_OUTP_MASK 0x0004 /* HPR_ENA_OUTP */
-#define WM8961_HPR_ENA_OUTP_SHIFT 2 /* HPR_ENA_OUTP */
-#define WM8961_HPR_ENA_OUTP_WIDTH 1 /* HPR_ENA_OUTP */
-#define WM8961_HPR_ENA_DLY 0x0002 /* HPR_ENA_DLY */
-#define WM8961_HPR_ENA_DLY_MASK 0x0002 /* HPR_ENA_DLY */
-#define WM8961_HPR_ENA_DLY_SHIFT 1 /* HPR_ENA_DLY */
-#define WM8961_HPR_ENA_DLY_WIDTH 1 /* HPR_ENA_DLY */
-#define WM8961_HPR_ENA 0x0001 /* HPR_ENA */
-#define WM8961_HPR_ENA_MASK 0x0001 /* HPR_ENA */
-#define WM8961_HPR_ENA_SHIFT 0 /* HPR_ENA */
-#define WM8961_HPR_ENA_WIDTH 1 /* HPR_ENA */
-
-/*
- * R71 (0x47) - Analogue HP 2
- */
-#define WM8961_HPL_VOL_MASK 0x01C0 /* HPL_VOL - [8:6] */
-#define WM8961_HPL_VOL_SHIFT 6 /* HPL_VOL - [8:6] */
-#define WM8961_HPL_VOL_WIDTH 3 /* HPL_VOL - [8:6] */
-#define WM8961_HPR_VOL_MASK 0x0038 /* HPR_VOL - [5:3] */
-#define WM8961_HPR_VOL_SHIFT 3 /* HPR_VOL - [5:3] */
-#define WM8961_HPR_VOL_WIDTH 3 /* HPR_VOL - [5:3] */
-#define WM8961_HP_BIAS_BOOST_MASK 0x0007 /* HP_BIAS_BOOST - [2:0] */
-#define WM8961_HP_BIAS_BOOST_SHIFT 0 /* HP_BIAS_BOOST - [2:0] */
-#define WM8961_HP_BIAS_BOOST_WIDTH 3 /* HP_BIAS_BOOST - [2:0] */
-
-/*
- * R72 (0x48) - Charge Pump 1
- */
-#define WM8961_CP_ENA 0x0001 /* CP_ENA */
-#define WM8961_CP_ENA_MASK 0x0001 /* CP_ENA */
-#define WM8961_CP_ENA_SHIFT 0 /* CP_ENA */
-#define WM8961_CP_ENA_WIDTH 1 /* CP_ENA */
-
-/*
- * R82 (0x52) - Charge Pump B
- */
-#define WM8961_CP_DYN_PWR_MASK 0x0003 /* CP_DYN_PWR - [1:0] */
-#define WM8961_CP_DYN_PWR_SHIFT 0 /* CP_DYN_PWR - [1:0] */
-#define WM8961_CP_DYN_PWR_WIDTH 2 /* CP_DYN_PWR - [1:0] */
-
-/*
- * R87 (0x57) - Write Sequencer 1
- */
-#define WM8961_WSEQ_ENA 0x0020 /* WSEQ_ENA */
-#define WM8961_WSEQ_ENA_MASK 0x0020 /* WSEQ_ENA */
-#define WM8961_WSEQ_ENA_SHIFT 5 /* WSEQ_ENA */
-#define WM8961_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
-#define WM8961_WSEQ_WRITE_INDEX_MASK 0x001F /* WSEQ_WRITE_INDEX - [4:0] */
-#define WM8961_WSEQ_WRITE_INDEX_SHIFT 0 /* WSEQ_WRITE_INDEX - [4:0] */
-#define WM8961_WSEQ_WRITE_INDEX_WIDTH 5 /* WSEQ_WRITE_INDEX - [4:0] */
-
-/*
- * R88 (0x58) - Write Sequencer 2
- */
-#define WM8961_WSEQ_EOS 0x0100 /* WSEQ_EOS */
-#define WM8961_WSEQ_EOS_MASK 0x0100 /* WSEQ_EOS */
-#define WM8961_WSEQ_EOS_SHIFT 8 /* WSEQ_EOS */
-#define WM8961_WSEQ_EOS_WIDTH 1 /* WSEQ_EOS */
-#define WM8961_WSEQ_ADDR_MASK 0x00FF /* WSEQ_ADDR - [7:0] */
-#define WM8961_WSEQ_ADDR_SHIFT 0 /* WSEQ_ADDR - [7:0] */
-#define WM8961_WSEQ_ADDR_WIDTH 8 /* WSEQ_ADDR - [7:0] */
-
-/*
- * R89 (0x59) - Write Sequencer 3
- */
-#define WM8961_WSEQ_DATA_MASK 0x00FF /* WSEQ_DATA - [7:0] */
-#define WM8961_WSEQ_DATA_SHIFT 0 /* WSEQ_DATA - [7:0] */
-#define WM8961_WSEQ_DATA_WIDTH 8 /* WSEQ_DATA - [7:0] */
-
-/*
- * R90 (0x5A) - Write Sequencer 4
- */
-#define WM8961_WSEQ_ABORT 0x0100 /* WSEQ_ABORT */
-#define WM8961_WSEQ_ABORT_MASK 0x0100 /* WSEQ_ABORT */
-#define WM8961_WSEQ_ABORT_SHIFT 8 /* WSEQ_ABORT */
-#define WM8961_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
-#define WM8961_WSEQ_START 0x0080 /* WSEQ_START */
-#define WM8961_WSEQ_START_MASK 0x0080 /* WSEQ_START */
-#define WM8961_WSEQ_START_SHIFT 7 /* WSEQ_START */
-#define WM8961_WSEQ_START_WIDTH 1 /* WSEQ_START */
-#define WM8961_WSEQ_START_INDEX_MASK 0x003F /* WSEQ_START_INDEX - [5:0] */
-#define WM8961_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [5:0] */
-#define WM8961_WSEQ_START_INDEX_WIDTH 6 /* WSEQ_START_INDEX - [5:0] */
-
-/*
- * R91 (0x5B) - Write Sequencer 5
- */
-#define WM8961_WSEQ_DATA_WIDTH_MASK 0x0070 /* WSEQ_DATA_WIDTH - [6:4] */
-#define WM8961_WSEQ_DATA_WIDTH_SHIFT 4 /* WSEQ_DATA_WIDTH - [6:4] */
-#define WM8961_WSEQ_DATA_WIDTH_WIDTH 3 /* WSEQ_DATA_WIDTH - [6:4] */
-#define WM8961_WSEQ_DATA_START_MASK 0x000F /* WSEQ_DATA_START - [3:0] */
-#define WM8961_WSEQ_DATA_START_SHIFT 0 /* WSEQ_DATA_START - [3:0] */
-#define WM8961_WSEQ_DATA_START_WIDTH 4 /* WSEQ_DATA_START - [3:0] */
-
-/*
- * R92 (0x5C) - Write Sequencer 6
- */
-#define WM8961_WSEQ_DELAY_MASK 0x000F /* WSEQ_DELAY - [3:0] */
-#define WM8961_WSEQ_DELAY_SHIFT 0 /* WSEQ_DELAY - [3:0] */
-#define WM8961_WSEQ_DELAY_WIDTH 4 /* WSEQ_DELAY - [3:0] */
-
-/*
- * R93 (0x5D) - Write Sequencer 7
- */
-#define WM8961_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
-#define WM8961_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
-#define WM8961_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
-#define WM8961_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
-
-/*
- * R252 (0xFC) - General test 1
- */
-#define WM8961_ARA_ENA 0x0002 /* ARA_ENA */
-#define WM8961_ARA_ENA_MASK 0x0002 /* ARA_ENA */
-#define WM8961_ARA_ENA_SHIFT 1 /* ARA_ENA */
-#define WM8961_ARA_ENA_WIDTH 1 /* ARA_ENA */
-#define WM8961_AUTO_INC 0x0001 /* AUTO_INC */
-#define WM8961_AUTO_INC_MASK 0x0001 /* AUTO_INC */
-#define WM8961_AUTO_INC_SHIFT 0 /* AUTO_INC */
-#define WM8961_AUTO_INC_WIDTH 1 /* AUTO_INC */
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8962.c b/ANDROID_3.4.5/sound/soc/codecs/wm8962.c
deleted file mode 100644
index 15d467ff..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8962.c
+++ /dev/null
@@ -1,3778 +0,0 @@
-/*
- * wm8962.c -- WM8962 ALSA SoC Audio driver
- *
- * Copyright 2010 Wolfson Microelectronics plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/gcd.h>
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-#include <linux/input.h>
-#include <linux/pm_runtime.h>
-#include <linux/regmap.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <sound/core.h>
-#include <sound/jack.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <sound/wm8962.h>
-#include <trace/events/asoc.h>
-
-#include "wm8962.h"
-
-#define WM8962_NUM_SUPPLIES 8
-static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = {
- "DCVDD",
- "DBVDD",
- "AVDD",
- "CPVDD",
- "MICVDD",
- "PLLVDD",
- "SPKVDD1",
- "SPKVDD2",
-};
-
-/* codec private data */
-struct wm8962_priv {
- struct regmap *regmap;
- struct snd_soc_codec *codec;
-
- int sysclk;
- int sysclk_rate;
-
- int bclk; /* Desired BCLK */
- int lrclk;
-
- struct completion fll_lock;
- int fll_src;
- int fll_fref;
- int fll_fout;
-
- u16 dsp2_ena;
-
- struct delayed_work mic_work;
- struct snd_soc_jack *jack;
-
- struct regulator_bulk_data supplies[WM8962_NUM_SUPPLIES];
- struct notifier_block disable_nb[WM8962_NUM_SUPPLIES];
-
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
- struct input_dev *beep;
- struct work_struct beep_work;
- int beep_rate;
-#endif
-
-#ifdef CONFIG_GPIOLIB
- struct gpio_chip gpio_chip;
-#endif
-
- int irq;
-};
-
-/* We can't use the same notifier block for more than one supply and
- * there's no way I can see to get from a callback to the caller
- * except container_of().
- */
-#define WM8962_REGULATOR_EVENT(n) \
-static int wm8962_regulator_event_##n(struct notifier_block *nb, \
- unsigned long event, void *data) \
-{ \
- struct wm8962_priv *wm8962 = container_of(nb, struct wm8962_priv, \
- disable_nb[n]); \
- if (event & REGULATOR_EVENT_DISABLE) { \
- regcache_mark_dirty(wm8962->regmap); \
- } \
- return 0; \
-}
-
-WM8962_REGULATOR_EVENT(0)
-WM8962_REGULATOR_EVENT(1)
-WM8962_REGULATOR_EVENT(2)
-WM8962_REGULATOR_EVENT(3)
-WM8962_REGULATOR_EVENT(4)
-WM8962_REGULATOR_EVENT(5)
-WM8962_REGULATOR_EVENT(6)
-WM8962_REGULATOR_EVENT(7)
-
-static struct reg_default wm8962_reg[] = {
- { 0, 0x009F }, /* R0 - Left Input volume */
- { 1, 0x049F }, /* R1 - Right Input volume */
- { 2, 0x0000 }, /* R2 - HPOUTL volume */
- { 3, 0x0000 }, /* R3 - HPOUTR volume */
-
- { 5, 0x0018 }, /* R5 - ADC & DAC Control 1 */
- { 6, 0x2008 }, /* R6 - ADC & DAC Control 2 */
- { 7, 0x000A }, /* R7 - Audio Interface 0 */
-
- { 9, 0x0300 }, /* R9 - Audio Interface 1 */
- { 10, 0x00C0 }, /* R10 - Left DAC volume */
- { 11, 0x00C0 }, /* R11 - Right DAC volume */
-
- { 14, 0x0040 }, /* R14 - Audio Interface 2 */
- { 15, 0x6243 }, /* R15 - Software Reset */
-
- { 17, 0x007B }, /* R17 - ALC1 */
-
- { 19, 0x1C32 }, /* R19 - ALC3 */
- { 20, 0x3200 }, /* R20 - Noise Gate */
- { 21, 0x00C0 }, /* R21 - Left ADC volume */
- { 22, 0x00C0 }, /* R22 - Right ADC volume */
- { 23, 0x0160 }, /* R23 - Additional control(1) */
- { 24, 0x0000 }, /* R24 - Additional control(2) */
- { 25, 0x0000 }, /* R25 - Pwr Mgmt (1) */
- { 26, 0x0000 }, /* R26 - Pwr Mgmt (2) */
- { 27, 0x0010 }, /* R27 - Additional Control (3) */
- { 28, 0x0000 }, /* R28 - Anti-pop */
-
- { 30, 0x005E }, /* R30 - Clocking 3 */
- { 31, 0x0000 }, /* R31 - Input mixer control (1) */
- { 32, 0x0145 }, /* R32 - Left input mixer volume */
- { 33, 0x0145 }, /* R33 - Right input mixer volume */
- { 34, 0x0009 }, /* R34 - Input mixer control (2) */
- { 35, 0x0003 }, /* R35 - Input bias control */
- { 37, 0x0008 }, /* R37 - Left input PGA control */
- { 38, 0x0008 }, /* R38 - Right input PGA control */
-
- { 40, 0x0000 }, /* R40 - SPKOUTL volume */
- { 41, 0x0000 }, /* R41 - SPKOUTR volume */
-
- { 51, 0x0003 }, /* R51 - Class D Control 2 */
-
- { 56, 0x0506 }, /* R56 - Clocking 4 */
- { 57, 0x0000 }, /* R57 - DAC DSP Mixing (1) */
- { 58, 0x0000 }, /* R58 - DAC DSP Mixing (2) */
-
- { 60, 0x0300 }, /* R60 - DC Servo 0 */
- { 61, 0x0300 }, /* R61 - DC Servo 1 */
-
- { 64, 0x0810 }, /* R64 - DC Servo 4 */
-
- { 68, 0x001B }, /* R68 - Analogue PGA Bias */
- { 69, 0x0000 }, /* R69 - Analogue HP 0 */
-
- { 71, 0x01FB }, /* R71 - Analogue HP 2 */
- { 72, 0x0000 }, /* R72 - Charge Pump 1 */
-
- { 82, 0x0004 }, /* R82 - Charge Pump B */
-
- { 87, 0x0000 }, /* R87 - Write Sequencer Control 1 */
-
- { 90, 0x0000 }, /* R90 - Write Sequencer Control 2 */
-
- { 93, 0x0000 }, /* R93 - Write Sequencer Control 3 */
- { 94, 0x0000 }, /* R94 - Control Interface */
-
- { 99, 0x0000 }, /* R99 - Mixer Enables */
- { 100, 0x0000 }, /* R100 - Headphone Mixer (1) */
- { 101, 0x0000 }, /* R101 - Headphone Mixer (2) */
- { 102, 0x013F }, /* R102 - Headphone Mixer (3) */
- { 103, 0x013F }, /* R103 - Headphone Mixer (4) */
-
- { 105, 0x0000 }, /* R105 - Speaker Mixer (1) */
- { 106, 0x0000 }, /* R106 - Speaker Mixer (2) */
- { 107, 0x013F }, /* R107 - Speaker Mixer (3) */
- { 108, 0x013F }, /* R108 - Speaker Mixer (4) */
- { 109, 0x0003 }, /* R109 - Speaker Mixer (5) */
- { 110, 0x0002 }, /* R110 - Beep Generator (1) */
-
- { 115, 0x0006 }, /* R115 - Oscillator Trim (3) */
- { 116, 0x0026 }, /* R116 - Oscillator Trim (4) */
-
- { 119, 0x0000 }, /* R119 - Oscillator Trim (7) */
-
- { 124, 0x0011 }, /* R124 - Analogue Clocking1 */
- { 125, 0x004B }, /* R125 - Analogue Clocking2 */
- { 126, 0x000D }, /* R126 - Analogue Clocking3 */
- { 127, 0x0000 }, /* R127 - PLL Software Reset */
-
- { 131, 0x0000 }, /* R131 - PLL 4 */
-
- { 136, 0x0067 }, /* R136 - PLL 9 */
- { 137, 0x001C }, /* R137 - PLL 10 */
- { 138, 0x0071 }, /* R138 - PLL 11 */
- { 139, 0x00C7 }, /* R139 - PLL 12 */
- { 140, 0x0067 }, /* R140 - PLL 13 */
- { 141, 0x0048 }, /* R141 - PLL 14 */
- { 142, 0x0022 }, /* R142 - PLL 15 */
- { 143, 0x0097 }, /* R143 - PLL 16 */
-
- { 155, 0x000C }, /* R155 - FLL Control (1) */
- { 156, 0x0039 }, /* R156 - FLL Control (2) */
- { 157, 0x0180 }, /* R157 - FLL Control (3) */
-
- { 159, 0x0032 }, /* R159 - FLL Control (5) */
- { 160, 0x0018 }, /* R160 - FLL Control (6) */
- { 161, 0x007D }, /* R161 - FLL Control (7) */
- { 162, 0x0008 }, /* R162 - FLL Control (8) */
-
- { 252, 0x0005 }, /* R252 - General test 1 */
-
- { 256, 0x0000 }, /* R256 - DF1 */
- { 257, 0x0000 }, /* R257 - DF2 */
- { 258, 0x0000 }, /* R258 - DF3 */
- { 259, 0x0000 }, /* R259 - DF4 */
- { 260, 0x0000 }, /* R260 - DF5 */
- { 261, 0x0000 }, /* R261 - DF6 */
- { 262, 0x0000 }, /* R262 - DF7 */
-
- { 264, 0x0000 }, /* R264 - LHPF1 */
- { 265, 0x0000 }, /* R265 - LHPF2 */
-
- { 268, 0x0000 }, /* R268 - THREED1 */
- { 269, 0x0000 }, /* R269 - THREED2 */
- { 270, 0x0000 }, /* R270 - THREED3 */
- { 271, 0x0000 }, /* R271 - THREED4 */
-
- { 276, 0x000C }, /* R276 - DRC 1 */
- { 277, 0x0925 }, /* R277 - DRC 2 */
- { 278, 0x0000 }, /* R278 - DRC 3 */
- { 279, 0x0000 }, /* R279 - DRC 4 */
- { 280, 0x0000 }, /* R280 - DRC 5 */
-
- { 285, 0x0000 }, /* R285 - Tloopback */
-
- { 335, 0x0004 }, /* R335 - EQ1 */
- { 336, 0x6318 }, /* R336 - EQ2 */
- { 337, 0x6300 }, /* R337 - EQ3 */
- { 338, 0x0FCA }, /* R338 - EQ4 */
- { 339, 0x0400 }, /* R339 - EQ5 */
- { 340, 0x00D8 }, /* R340 - EQ6 */
- { 341, 0x1EB5 }, /* R341 - EQ7 */
- { 342, 0xF145 }, /* R342 - EQ8 */
- { 343, 0x0B75 }, /* R343 - EQ9 */
- { 344, 0x01C5 }, /* R344 - EQ10 */
- { 345, 0x1C58 }, /* R345 - EQ11 */
- { 346, 0xF373 }, /* R346 - EQ12 */
- { 347, 0x0A54 }, /* R347 - EQ13 */
- { 348, 0x0558 }, /* R348 - EQ14 */
- { 349, 0x168E }, /* R349 - EQ15 */
- { 350, 0xF829 }, /* R350 - EQ16 */
- { 351, 0x07AD }, /* R351 - EQ17 */
- { 352, 0x1103 }, /* R352 - EQ18 */
- { 353, 0x0564 }, /* R353 - EQ19 */
- { 354, 0x0559 }, /* R354 - EQ20 */
- { 355, 0x4000 }, /* R355 - EQ21 */
- { 356, 0x6318 }, /* R356 - EQ22 */
- { 357, 0x6300 }, /* R357 - EQ23 */
- { 358, 0x0FCA }, /* R358 - EQ24 */
- { 359, 0x0400 }, /* R359 - EQ25 */
- { 360, 0x00D8 }, /* R360 - EQ26 */
- { 361, 0x1EB5 }, /* R361 - EQ27 */
- { 362, 0xF145 }, /* R362 - EQ28 */
- { 363, 0x0B75 }, /* R363 - EQ29 */
- { 364, 0x01C5 }, /* R364 - EQ30 */
- { 365, 0x1C58 }, /* R365 - EQ31 */
- { 366, 0xF373 }, /* R366 - EQ32 */
- { 367, 0x0A54 }, /* R367 - EQ33 */
- { 368, 0x0558 }, /* R368 - EQ34 */
- { 369, 0x168E }, /* R369 - EQ35 */
- { 370, 0xF829 }, /* R370 - EQ36 */
- { 371, 0x07AD }, /* R371 - EQ37 */
- { 372, 0x1103 }, /* R372 - EQ38 */
- { 373, 0x0564 }, /* R373 - EQ39 */
- { 374, 0x0559 }, /* R374 - EQ40 */
- { 375, 0x4000 }, /* R375 - EQ41 */
-
- { 513, 0x0000 }, /* R513 - GPIO 2 */
- { 514, 0x0000 }, /* R514 - GPIO 3 */
-
- { 516, 0x8100 }, /* R516 - GPIO 5 */
- { 517, 0x8100 }, /* R517 - GPIO 6 */
-
- { 568, 0x0030 }, /* R568 - Interrupt Status 1 Mask */
- { 569, 0xFFED }, /* R569 - Interrupt Status 2 Mask */
-
- { 576, 0x0000 }, /* R576 - Interrupt Control */
-
- { 584, 0x002D }, /* R584 - IRQ Debounce */
-
- { 586, 0x0000 }, /* R586 - MICINT Source Pol */
-
- { 768, 0x1C00 }, /* R768 - DSP2 Power Management */
-
- { 8192, 0x0000 }, /* R8192 - DSP2 Instruction RAM 0 */
-
- { 9216, 0x0030 }, /* R9216 - DSP2 Address RAM 2 */
- { 9217, 0x0000 }, /* R9217 - DSP2 Address RAM 1 */
- { 9218, 0x0000 }, /* R9218 - DSP2 Address RAM 0 */
-
- { 12288, 0x0000 }, /* R12288 - DSP2 Data1 RAM 1 */
- { 12289, 0x0000 }, /* R12289 - DSP2 Data1 RAM 0 */
-
- { 13312, 0x0000 }, /* R13312 - DSP2 Data2 RAM 1 */
- { 13313, 0x0000 }, /* R13313 - DSP2 Data2 RAM 0 */
-
- { 14336, 0x0000 }, /* R14336 - DSP2 Data3 RAM 1 */
- { 14337, 0x0000 }, /* R14337 - DSP2 Data3 RAM 0 */
-
- { 15360, 0x000A }, /* R15360 - DSP2 Coeff RAM 0 */
-
- { 16384, 0x0000 }, /* R16384 - RETUNEADC_SHARED_COEFF_1 */
- { 16385, 0x0000 }, /* R16385 - RETUNEADC_SHARED_COEFF_0 */
- { 16386, 0x0000 }, /* R16386 - RETUNEDAC_SHARED_COEFF_1 */
- { 16387, 0x0000 }, /* R16387 - RETUNEDAC_SHARED_COEFF_0 */
- { 16388, 0x0000 }, /* R16388 - SOUNDSTAGE_ENABLES_1 */
- { 16389, 0x0000 }, /* R16389 - SOUNDSTAGE_ENABLES_0 */
-
- { 16896, 0x0002 }, /* R16896 - HDBASS_AI_1 */
- { 16897, 0xBD12 }, /* R16897 - HDBASS_AI_0 */
- { 16898, 0x007C }, /* R16898 - HDBASS_AR_1 */
- { 16899, 0x586C }, /* R16899 - HDBASS_AR_0 */
- { 16900, 0x0053 }, /* R16900 - HDBASS_B_1 */
- { 16901, 0x8121 }, /* R16901 - HDBASS_B_0 */
- { 16902, 0x003F }, /* R16902 - HDBASS_K_1 */
- { 16903, 0x8BD8 }, /* R16903 - HDBASS_K_0 */
- { 16904, 0x0032 }, /* R16904 - HDBASS_N1_1 */
- { 16905, 0xF52D }, /* R16905 - HDBASS_N1_0 */
- { 16906, 0x0065 }, /* R16906 - HDBASS_N2_1 */
- { 16907, 0xAC8C }, /* R16907 - HDBASS_N2_0 */
- { 16908, 0x006B }, /* R16908 - HDBASS_N3_1 */
- { 16909, 0xE087 }, /* R16909 - HDBASS_N3_0 */
- { 16910, 0x0072 }, /* R16910 - HDBASS_N4_1 */
- { 16911, 0x1483 }, /* R16911 - HDBASS_N4_0 */
- { 16912, 0x0072 }, /* R16912 - HDBASS_N5_1 */
- { 16913, 0x1483 }, /* R16913 - HDBASS_N5_0 */
- { 16914, 0x0043 }, /* R16914 - HDBASS_X1_1 */
- { 16915, 0x3525 }, /* R16915 - HDBASS_X1_0 */
- { 16916, 0x0006 }, /* R16916 - HDBASS_X2_1 */
- { 16917, 0x6A4A }, /* R16917 - HDBASS_X2_0 */
- { 16918, 0x0043 }, /* R16918 - HDBASS_X3_1 */
- { 16919, 0x6079 }, /* R16919 - HDBASS_X3_0 */
- { 16920, 0x0008 }, /* R16920 - HDBASS_ATK_1 */
- { 16921, 0x0000 }, /* R16921 - HDBASS_ATK_0 */
- { 16922, 0x0001 }, /* R16922 - HDBASS_DCY_1 */
- { 16923, 0x0000 }, /* R16923 - HDBASS_DCY_0 */
- { 16924, 0x0059 }, /* R16924 - HDBASS_PG_1 */
- { 16925, 0x999A }, /* R16925 - HDBASS_PG_0 */
-
- { 17048, 0x0083 }, /* R17408 - HPF_C_1 */
- { 17049, 0x98AD }, /* R17409 - HPF_C_0 */
-
- { 17920, 0x007F }, /* R17920 - ADCL_RETUNE_C1_1 */
- { 17921, 0xFFFF }, /* R17921 - ADCL_RETUNE_C1_0 */
- { 17922, 0x0000 }, /* R17922 - ADCL_RETUNE_C2_1 */
- { 17923, 0x0000 }, /* R17923 - ADCL_RETUNE_C2_0 */
- { 17924, 0x0000 }, /* R17924 - ADCL_RETUNE_C3_1 */
- { 17925, 0x0000 }, /* R17925 - ADCL_RETUNE_C3_0 */
- { 17926, 0x0000 }, /* R17926 - ADCL_RETUNE_C4_1 */
- { 17927, 0x0000 }, /* R17927 - ADCL_RETUNE_C4_0 */
- { 17928, 0x0000 }, /* R17928 - ADCL_RETUNE_C5_1 */
- { 17929, 0x0000 }, /* R17929 - ADCL_RETUNE_C5_0 */
- { 17930, 0x0000 }, /* R17930 - ADCL_RETUNE_C6_1 */
- { 17931, 0x0000 }, /* R17931 - ADCL_RETUNE_C6_0 */
- { 17932, 0x0000 }, /* R17932 - ADCL_RETUNE_C7_1 */
- { 17933, 0x0000 }, /* R17933 - ADCL_RETUNE_C7_0 */
- { 17934, 0x0000 }, /* R17934 - ADCL_RETUNE_C8_1 */
- { 17935, 0x0000 }, /* R17935 - ADCL_RETUNE_C8_0 */
- { 17936, 0x0000 }, /* R17936 - ADCL_RETUNE_C9_1 */
- { 17937, 0x0000 }, /* R17937 - ADCL_RETUNE_C9_0 */
- { 17938, 0x0000 }, /* R17938 - ADCL_RETUNE_C10_1 */
- { 17939, 0x0000 }, /* R17939 - ADCL_RETUNE_C10_0 */
- { 17940, 0x0000 }, /* R17940 - ADCL_RETUNE_C11_1 */
- { 17941, 0x0000 }, /* R17941 - ADCL_RETUNE_C11_0 */
- { 17942, 0x0000 }, /* R17942 - ADCL_RETUNE_C12_1 */
- { 17943, 0x0000 }, /* R17943 - ADCL_RETUNE_C12_0 */
- { 17944, 0x0000 }, /* R17944 - ADCL_RETUNE_C13_1 */
- { 17945, 0x0000 }, /* R17945 - ADCL_RETUNE_C13_0 */
- { 17946, 0x0000 }, /* R17946 - ADCL_RETUNE_C14_1 */
- { 17947, 0x0000 }, /* R17947 - ADCL_RETUNE_C14_0 */
- { 17948, 0x0000 }, /* R17948 - ADCL_RETUNE_C15_1 */
- { 17949, 0x0000 }, /* R17949 - ADCL_RETUNE_C15_0 */
- { 17950, 0x0000 }, /* R17950 - ADCL_RETUNE_C16_1 */
- { 17951, 0x0000 }, /* R17951 - ADCL_RETUNE_C16_0 */
- { 17952, 0x0000 }, /* R17952 - ADCL_RETUNE_C17_1 */
- { 17953, 0x0000 }, /* R17953 - ADCL_RETUNE_C17_0 */
- { 17954, 0x0000 }, /* R17954 - ADCL_RETUNE_C18_1 */
- { 17955, 0x0000 }, /* R17955 - ADCL_RETUNE_C18_0 */
- { 17956, 0x0000 }, /* R17956 - ADCL_RETUNE_C19_1 */
- { 17957, 0x0000 }, /* R17957 - ADCL_RETUNE_C19_0 */
- { 17958, 0x0000 }, /* R17958 - ADCL_RETUNE_C20_1 */
- { 17959, 0x0000 }, /* R17959 - ADCL_RETUNE_C20_0 */
- { 17960, 0x0000 }, /* R17960 - ADCL_RETUNE_C21_1 */
- { 17961, 0x0000 }, /* R17961 - ADCL_RETUNE_C21_0 */
- { 17962, 0x0000 }, /* R17962 - ADCL_RETUNE_C22_1 */
- { 17963, 0x0000 }, /* R17963 - ADCL_RETUNE_C22_0 */
- { 17964, 0x0000 }, /* R17964 - ADCL_RETUNE_C23_1 */
- { 17965, 0x0000 }, /* R17965 - ADCL_RETUNE_C23_0 */
- { 17966, 0x0000 }, /* R17966 - ADCL_RETUNE_C24_1 */
- { 17967, 0x0000 }, /* R17967 - ADCL_RETUNE_C24_0 */
- { 17968, 0x0000 }, /* R17968 - ADCL_RETUNE_C25_1 */
- { 17969, 0x0000 }, /* R17969 - ADCL_RETUNE_C25_0 */
- { 17970, 0x0000 }, /* R17970 - ADCL_RETUNE_C26_1 */
- { 17971, 0x0000 }, /* R17971 - ADCL_RETUNE_C26_0 */
- { 17972, 0x0000 }, /* R17972 - ADCL_RETUNE_C27_1 */
- { 17973, 0x0000 }, /* R17973 - ADCL_RETUNE_C27_0 */
- { 17974, 0x0000 }, /* R17974 - ADCL_RETUNE_C28_1 */
- { 17975, 0x0000 }, /* R17975 - ADCL_RETUNE_C28_0 */
- { 17976, 0x0000 }, /* R17976 - ADCL_RETUNE_C29_1 */
- { 17977, 0x0000 }, /* R17977 - ADCL_RETUNE_C29_0 */
- { 17978, 0x0000 }, /* R17978 - ADCL_RETUNE_C30_1 */
- { 17979, 0x0000 }, /* R17979 - ADCL_RETUNE_C30_0 */
- { 17980, 0x0000 }, /* R17980 - ADCL_RETUNE_C31_1 */
- { 17981, 0x0000 }, /* R17981 - ADCL_RETUNE_C31_0 */
- { 17982, 0x0000 }, /* R17982 - ADCL_RETUNE_C32_1 */
- { 17983, 0x0000 }, /* R17983 - ADCL_RETUNE_C32_0 */
-
- { 18432, 0x0020 }, /* R18432 - RETUNEADC_PG2_1 */
- { 18433, 0x0000 }, /* R18433 - RETUNEADC_PG2_0 */
- { 18434, 0x0040 }, /* R18434 - RETUNEADC_PG_1 */
- { 18435, 0x0000 }, /* R18435 - RETUNEADC_PG_0 */
-
- { 18944, 0x007F }, /* R18944 - ADCR_RETUNE_C1_1 */
- { 18945, 0xFFFF }, /* R18945 - ADCR_RETUNE_C1_0 */
- { 18946, 0x0000 }, /* R18946 - ADCR_RETUNE_C2_1 */
- { 18947, 0x0000 }, /* R18947 - ADCR_RETUNE_C2_0 */
- { 18948, 0x0000 }, /* R18948 - ADCR_RETUNE_C3_1 */
- { 18949, 0x0000 }, /* R18949 - ADCR_RETUNE_C3_0 */
- { 18950, 0x0000 }, /* R18950 - ADCR_RETUNE_C4_1 */
- { 18951, 0x0000 }, /* R18951 - ADCR_RETUNE_C4_0 */
- { 18952, 0x0000 }, /* R18952 - ADCR_RETUNE_C5_1 */
- { 18953, 0x0000 }, /* R18953 - ADCR_RETUNE_C5_0 */
- { 18954, 0x0000 }, /* R18954 - ADCR_RETUNE_C6_1 */
- { 18955, 0x0000 }, /* R18955 - ADCR_RETUNE_C6_0 */
- { 18956, 0x0000 }, /* R18956 - ADCR_RETUNE_C7_1 */
- { 18957, 0x0000 }, /* R18957 - ADCR_RETUNE_C7_0 */
- { 18958, 0x0000 }, /* R18958 - ADCR_RETUNE_C8_1 */
- { 18959, 0x0000 }, /* R18959 - ADCR_RETUNE_C8_0 */
- { 18960, 0x0000 }, /* R18960 - ADCR_RETUNE_C9_1 */
- { 18961, 0x0000 }, /* R18961 - ADCR_RETUNE_C9_0 */
- { 18962, 0x0000 }, /* R18962 - ADCR_RETUNE_C10_1 */
- { 18963, 0x0000 }, /* R18963 - ADCR_RETUNE_C10_0 */
- { 18964, 0x0000 }, /* R18964 - ADCR_RETUNE_C11_1 */
- { 18965, 0x0000 }, /* R18965 - ADCR_RETUNE_C11_0 */
- { 18966, 0x0000 }, /* R18966 - ADCR_RETUNE_C12_1 */
- { 18967, 0x0000 }, /* R18967 - ADCR_RETUNE_C12_0 */
- { 18968, 0x0000 }, /* R18968 - ADCR_RETUNE_C13_1 */
- { 18969, 0x0000 }, /* R18969 - ADCR_RETUNE_C13_0 */
- { 18970, 0x0000 }, /* R18970 - ADCR_RETUNE_C14_1 */
- { 18971, 0x0000 }, /* R18971 - ADCR_RETUNE_C14_0 */
- { 18972, 0x0000 }, /* R18972 - ADCR_RETUNE_C15_1 */
- { 18973, 0x0000 }, /* R18973 - ADCR_RETUNE_C15_0 */
- { 18974, 0x0000 }, /* R18974 - ADCR_RETUNE_C16_1 */
- { 18975, 0x0000 }, /* R18975 - ADCR_RETUNE_C16_0 */
- { 18976, 0x0000 }, /* R18976 - ADCR_RETUNE_C17_1 */
- { 18977, 0x0000 }, /* R18977 - ADCR_RETUNE_C17_0 */
- { 18978, 0x0000 }, /* R18978 - ADCR_RETUNE_C18_1 */
- { 18979, 0x0000 }, /* R18979 - ADCR_RETUNE_C18_0 */
- { 18980, 0x0000 }, /* R18980 - ADCR_RETUNE_C19_1 */
- { 18981, 0x0000 }, /* R18981 - ADCR_RETUNE_C19_0 */
- { 18982, 0x0000 }, /* R18982 - ADCR_RETUNE_C20_1 */
- { 18983, 0x0000 }, /* R18983 - ADCR_RETUNE_C20_0 */
- { 18984, 0x0000 }, /* R18984 - ADCR_RETUNE_C21_1 */
- { 18985, 0x0000 }, /* R18985 - ADCR_RETUNE_C21_0 */
- { 18986, 0x0000 }, /* R18986 - ADCR_RETUNE_C22_1 */
- { 18987, 0x0000 }, /* R18987 - ADCR_RETUNE_C22_0 */
- { 18988, 0x0000 }, /* R18988 - ADCR_RETUNE_C23_1 */
- { 18989, 0x0000 }, /* R18989 - ADCR_RETUNE_C23_0 */
- { 18990, 0x0000 }, /* R18990 - ADCR_RETUNE_C24_1 */
- { 18991, 0x0000 }, /* R18991 - ADCR_RETUNE_C24_0 */
- { 18992, 0x0000 }, /* R18992 - ADCR_RETUNE_C25_1 */
- { 18993, 0x0000 }, /* R18993 - ADCR_RETUNE_C25_0 */
- { 18994, 0x0000 }, /* R18994 - ADCR_RETUNE_C26_1 */
- { 18995, 0x0000 }, /* R18995 - ADCR_RETUNE_C26_0 */
- { 18996, 0x0000 }, /* R18996 - ADCR_RETUNE_C27_1 */
- { 18997, 0x0000 }, /* R18997 - ADCR_RETUNE_C27_0 */
- { 18998, 0x0000 }, /* R18998 - ADCR_RETUNE_C28_1 */
- { 18999, 0x0000 }, /* R18999 - ADCR_RETUNE_C28_0 */
- { 19000, 0x0000 }, /* R19000 - ADCR_RETUNE_C29_1 */
- { 19001, 0x0000 }, /* R19001 - ADCR_RETUNE_C29_0 */
- { 19002, 0x0000 }, /* R19002 - ADCR_RETUNE_C30_1 */
- { 19003, 0x0000 }, /* R19003 - ADCR_RETUNE_C30_0 */
- { 19004, 0x0000 }, /* R19004 - ADCR_RETUNE_C31_1 */
- { 19005, 0x0000 }, /* R19005 - ADCR_RETUNE_C31_0 */
- { 19006, 0x0000 }, /* R19006 - ADCR_RETUNE_C32_1 */
- { 19007, 0x0000 }, /* R19007 - ADCR_RETUNE_C32_0 */
-
- { 19456, 0x007F }, /* R19456 - DACL_RETUNE_C1_1 */
- { 19457, 0xFFFF }, /* R19457 - DACL_RETUNE_C1_0 */
- { 19458, 0x0000 }, /* R19458 - DACL_RETUNE_C2_1 */
- { 19459, 0x0000 }, /* R19459 - DACL_RETUNE_C2_0 */
- { 19460, 0x0000 }, /* R19460 - DACL_RETUNE_C3_1 */
- { 19461, 0x0000 }, /* R19461 - DACL_RETUNE_C3_0 */
- { 19462, 0x0000 }, /* R19462 - DACL_RETUNE_C4_1 */
- { 19463, 0x0000 }, /* R19463 - DACL_RETUNE_C4_0 */
- { 19464, 0x0000 }, /* R19464 - DACL_RETUNE_C5_1 */
- { 19465, 0x0000 }, /* R19465 - DACL_RETUNE_C5_0 */
- { 19466, 0x0000 }, /* R19466 - DACL_RETUNE_C6_1 */
- { 19467, 0x0000 }, /* R19467 - DACL_RETUNE_C6_0 */
- { 19468, 0x0000 }, /* R19468 - DACL_RETUNE_C7_1 */
- { 19469, 0x0000 }, /* R19469 - DACL_RETUNE_C7_0 */
- { 19470, 0x0000 }, /* R19470 - DACL_RETUNE_C8_1 */
- { 19471, 0x0000 }, /* R19471 - DACL_RETUNE_C8_0 */
- { 19472, 0x0000 }, /* R19472 - DACL_RETUNE_C9_1 */
- { 19473, 0x0000 }, /* R19473 - DACL_RETUNE_C9_0 */
- { 19474, 0x0000 }, /* R19474 - DACL_RETUNE_C10_1 */
- { 19475, 0x0000 }, /* R19475 - DACL_RETUNE_C10_0 */
- { 19476, 0x0000 }, /* R19476 - DACL_RETUNE_C11_1 */
- { 19477, 0x0000 }, /* R19477 - DACL_RETUNE_C11_0 */
- { 19478, 0x0000 }, /* R19478 - DACL_RETUNE_C12_1 */
- { 19479, 0x0000 }, /* R19479 - DACL_RETUNE_C12_0 */
- { 19480, 0x0000 }, /* R19480 - DACL_RETUNE_C13_1 */
- { 19481, 0x0000 }, /* R19481 - DACL_RETUNE_C13_0 */
- { 19482, 0x0000 }, /* R19482 - DACL_RETUNE_C14_1 */
- { 19483, 0x0000 }, /* R19483 - DACL_RETUNE_C14_0 */
- { 19484, 0x0000 }, /* R19484 - DACL_RETUNE_C15_1 */
- { 19485, 0x0000 }, /* R19485 - DACL_RETUNE_C15_0 */
- { 19486, 0x0000 }, /* R19486 - DACL_RETUNE_C16_1 */
- { 19487, 0x0000 }, /* R19487 - DACL_RETUNE_C16_0 */
- { 19488, 0x0000 }, /* R19488 - DACL_RETUNE_C17_1 */
- { 19489, 0x0000 }, /* R19489 - DACL_RETUNE_C17_0 */
- { 19490, 0x0000 }, /* R19490 - DACL_RETUNE_C18_1 */
- { 19491, 0x0000 }, /* R19491 - DACL_RETUNE_C18_0 */
- { 19492, 0x0000 }, /* R19492 - DACL_RETUNE_C19_1 */
- { 19493, 0x0000 }, /* R19493 - DACL_RETUNE_C19_0 */
- { 19494, 0x0000 }, /* R19494 - DACL_RETUNE_C20_1 */
- { 19495, 0x0000 }, /* R19495 - DACL_RETUNE_C20_0 */
- { 19496, 0x0000 }, /* R19496 - DACL_RETUNE_C21_1 */
- { 19497, 0x0000 }, /* R19497 - DACL_RETUNE_C21_0 */
- { 19498, 0x0000 }, /* R19498 - DACL_RETUNE_C22_1 */
- { 19499, 0x0000 }, /* R19499 - DACL_RETUNE_C22_0 */
- { 19500, 0x0000 }, /* R19500 - DACL_RETUNE_C23_1 */
- { 19501, 0x0000 }, /* R19501 - DACL_RETUNE_C23_0 */
- { 19502, 0x0000 }, /* R19502 - DACL_RETUNE_C24_1 */
- { 19503, 0x0000 }, /* R19503 - DACL_RETUNE_C24_0 */
- { 19504, 0x0000 }, /* R19504 - DACL_RETUNE_C25_1 */
- { 19505, 0x0000 }, /* R19505 - DACL_RETUNE_C25_0 */
- { 19506, 0x0000 }, /* R19506 - DACL_RETUNE_C26_1 */
- { 19507, 0x0000 }, /* R19507 - DACL_RETUNE_C26_0 */
- { 19508, 0x0000 }, /* R19508 - DACL_RETUNE_C27_1 */
- { 19509, 0x0000 }, /* R19509 - DACL_RETUNE_C27_0 */
- { 19510, 0x0000 }, /* R19510 - DACL_RETUNE_C28_1 */
- { 19511, 0x0000 }, /* R19511 - DACL_RETUNE_C28_0 */
- { 19512, 0x0000 }, /* R19512 - DACL_RETUNE_C29_1 */
- { 19513, 0x0000 }, /* R19513 - DACL_RETUNE_C29_0 */
- { 19514, 0x0000 }, /* R19514 - DACL_RETUNE_C30_1 */
- { 19515, 0x0000 }, /* R19515 - DACL_RETUNE_C30_0 */
- { 19516, 0x0000 }, /* R19516 - DACL_RETUNE_C31_1 */
- { 19517, 0x0000 }, /* R19517 - DACL_RETUNE_C31_0 */
- { 19518, 0x0000 }, /* R19518 - DACL_RETUNE_C32_1 */
- { 19519, 0x0000 }, /* R19519 - DACL_RETUNE_C32_0 */
-
- { 19968, 0x0020 }, /* R19968 - RETUNEDAC_PG2_1 */
- { 19969, 0x0000 }, /* R19969 - RETUNEDAC_PG2_0 */
- { 19970, 0x0040 }, /* R19970 - RETUNEDAC_PG_1 */
- { 19971, 0x0000 }, /* R19971 - RETUNEDAC_PG_0 */
-
- { 20480, 0x007F }, /* R20480 - DACR_RETUNE_C1_1 */
- { 20481, 0xFFFF }, /* R20481 - DACR_RETUNE_C1_0 */
- { 20482, 0x0000 }, /* R20482 - DACR_RETUNE_C2_1 */
- { 20483, 0x0000 }, /* R20483 - DACR_RETUNE_C2_0 */
- { 20484, 0x0000 }, /* R20484 - DACR_RETUNE_C3_1 */
- { 20485, 0x0000 }, /* R20485 - DACR_RETUNE_C3_0 */
- { 20486, 0x0000 }, /* R20486 - DACR_RETUNE_C4_1 */
- { 20487, 0x0000 }, /* R20487 - DACR_RETUNE_C4_0 */
- { 20488, 0x0000 }, /* R20488 - DACR_RETUNE_C5_1 */
- { 20489, 0x0000 }, /* R20489 - DACR_RETUNE_C5_0 */
- { 20490, 0x0000 }, /* R20490 - DACR_RETUNE_C6_1 */
- { 20491, 0x0000 }, /* R20491 - DACR_RETUNE_C6_0 */
- { 20492, 0x0000 }, /* R20492 - DACR_RETUNE_C7_1 */
- { 20493, 0x0000 }, /* R20493 - DACR_RETUNE_C7_0 */
- { 20494, 0x0000 }, /* R20494 - DACR_RETUNE_C8_1 */
- { 20495, 0x0000 }, /* R20495 - DACR_RETUNE_C8_0 */
- { 20496, 0x0000 }, /* R20496 - DACR_RETUNE_C9_1 */
- { 20497, 0x0000 }, /* R20497 - DACR_RETUNE_C9_0 */
- { 20498, 0x0000 }, /* R20498 - DACR_RETUNE_C10_1 */
- { 20499, 0x0000 }, /* R20499 - DACR_RETUNE_C10_0 */
- { 20500, 0x0000 }, /* R20500 - DACR_RETUNE_C11_1 */
- { 20501, 0x0000 }, /* R20501 - DACR_RETUNE_C11_0 */
- { 20502, 0x0000 }, /* R20502 - DACR_RETUNE_C12_1 */
- { 20503, 0x0000 }, /* R20503 - DACR_RETUNE_C12_0 */
- { 20504, 0x0000 }, /* R20504 - DACR_RETUNE_C13_1 */
- { 20505, 0x0000 }, /* R20505 - DACR_RETUNE_C13_0 */
- { 20506, 0x0000 }, /* R20506 - DACR_RETUNE_C14_1 */
- { 20507, 0x0000 }, /* R20507 - DACR_RETUNE_C14_0 */
- { 20508, 0x0000 }, /* R20508 - DACR_RETUNE_C15_1 */
- { 20509, 0x0000 }, /* R20509 - DACR_RETUNE_C15_0 */
- { 20510, 0x0000 }, /* R20510 - DACR_RETUNE_C16_1 */
- { 20511, 0x0000 }, /* R20511 - DACR_RETUNE_C16_0 */
- { 20512, 0x0000 }, /* R20512 - DACR_RETUNE_C17_1 */
- { 20513, 0x0000 }, /* R20513 - DACR_RETUNE_C17_0 */
- { 20514, 0x0000 }, /* R20514 - DACR_RETUNE_C18_1 */
- { 20515, 0x0000 }, /* R20515 - DACR_RETUNE_C18_0 */
- { 20516, 0x0000 }, /* R20516 - DACR_RETUNE_C19_1 */
- { 20517, 0x0000 }, /* R20517 - DACR_RETUNE_C19_0 */
- { 20518, 0x0000 }, /* R20518 - DACR_RETUNE_C20_1 */
- { 20519, 0x0000 }, /* R20519 - DACR_RETUNE_C20_0 */
- { 20520, 0x0000 }, /* R20520 - DACR_RETUNE_C21_1 */
- { 20521, 0x0000 }, /* R20521 - DACR_RETUNE_C21_0 */
- { 20522, 0x0000 }, /* R20522 - DACR_RETUNE_C22_1 */
- { 20523, 0x0000 }, /* R20523 - DACR_RETUNE_C22_0 */
- { 20524, 0x0000 }, /* R20524 - DACR_RETUNE_C23_1 */
- { 20525, 0x0000 }, /* R20525 - DACR_RETUNE_C23_0 */
- { 20526, 0x0000 }, /* R20526 - DACR_RETUNE_C24_1 */
- { 20527, 0x0000 }, /* R20527 - DACR_RETUNE_C24_0 */
- { 20528, 0x0000 }, /* R20528 - DACR_RETUNE_C25_1 */
- { 20529, 0x0000 }, /* R20529 - DACR_RETUNE_C25_0 */
- { 20530, 0x0000 }, /* R20530 - DACR_RETUNE_C26_1 */
- { 20531, 0x0000 }, /* R20531 - DACR_RETUNE_C26_0 */
- { 20532, 0x0000 }, /* R20532 - DACR_RETUNE_C27_1 */
- { 20533, 0x0000 }, /* R20533 - DACR_RETUNE_C27_0 */
- { 20534, 0x0000 }, /* R20534 - DACR_RETUNE_C28_1 */
- { 20535, 0x0000 }, /* R20535 - DACR_RETUNE_C28_0 */
- { 20536, 0x0000 }, /* R20536 - DACR_RETUNE_C29_1 */
- { 20537, 0x0000 }, /* R20537 - DACR_RETUNE_C29_0 */
- { 20538, 0x0000 }, /* R20538 - DACR_RETUNE_C30_1 */
- { 20539, 0x0000 }, /* R20539 - DACR_RETUNE_C30_0 */
- { 20540, 0x0000 }, /* R20540 - DACR_RETUNE_C31_1 */
- { 20541, 0x0000 }, /* R20541 - DACR_RETUNE_C31_0 */
- { 20542, 0x0000 }, /* R20542 - DACR_RETUNE_C32_1 */
- { 20543, 0x0000 }, /* R20543 - DACR_RETUNE_C32_0 */
-
- { 20992, 0x008C }, /* R20992 - VSS_XHD2_1 */
- { 20993, 0x0200 }, /* R20993 - VSS_XHD2_0 */
- { 20994, 0x0035 }, /* R20994 - VSS_XHD3_1 */
- { 20995, 0x0700 }, /* R20995 - VSS_XHD3_0 */
- { 20996, 0x003A }, /* R20996 - VSS_XHN1_1 */
- { 20997, 0x4100 }, /* R20997 - VSS_XHN1_0 */
- { 20998, 0x008B }, /* R20998 - VSS_XHN2_1 */
- { 20999, 0x7D00 }, /* R20999 - VSS_XHN2_0 */
- { 21000, 0x003A }, /* R21000 - VSS_XHN3_1 */
- { 21001, 0x4100 }, /* R21001 - VSS_XHN3_0 */
- { 21002, 0x008C }, /* R21002 - VSS_XLA_1 */
- { 21003, 0xFEE8 }, /* R21003 - VSS_XLA_0 */
- { 21004, 0x0078 }, /* R21004 - VSS_XLB_1 */
- { 21005, 0x0000 }, /* R21005 - VSS_XLB_0 */
- { 21006, 0x003F }, /* R21006 - VSS_XLG_1 */
- { 21007, 0xB260 }, /* R21007 - VSS_XLG_0 */
- { 21008, 0x002D }, /* R21008 - VSS_PG2_1 */
- { 21009, 0x1818 }, /* R21009 - VSS_PG2_0 */
- { 21010, 0x0020 }, /* R21010 - VSS_PG_1 */
- { 21011, 0x0000 }, /* R21011 - VSS_PG_0 */
- { 21012, 0x00F1 }, /* R21012 - VSS_XTD1_1 */
- { 21013, 0x8340 }, /* R21013 - VSS_XTD1_0 */
- { 21014, 0x00FB }, /* R21014 - VSS_XTD2_1 */
- { 21015, 0x8300 }, /* R21015 - VSS_XTD2_0 */
- { 21016, 0x00EE }, /* R21016 - VSS_XTD3_1 */
- { 21017, 0xAEC0 }, /* R21017 - VSS_XTD3_0 */
- { 21018, 0x00FB }, /* R21018 - VSS_XTD4_1 */
- { 21019, 0xAC40 }, /* R21019 - VSS_XTD4_0 */
- { 21020, 0x00F1 }, /* R21020 - VSS_XTD5_1 */
- { 21021, 0x7F80 }, /* R21021 - VSS_XTD5_0 */
- { 21022, 0x00F4 }, /* R21022 - VSS_XTD6_1 */
- { 21023, 0x3B40 }, /* R21023 - VSS_XTD6_0 */
- { 21024, 0x00F5 }, /* R21024 - VSS_XTD7_1 */
- { 21025, 0xFB00 }, /* R21025 - VSS_XTD7_0 */
- { 21026, 0x00EA }, /* R21026 - VSS_XTD8_1 */
- { 21027, 0x10C0 }, /* R21027 - VSS_XTD8_0 */
- { 21028, 0x00FC }, /* R21028 - VSS_XTD9_1 */
- { 21029, 0xC580 }, /* R21029 - VSS_XTD9_0 */
- { 21030, 0x00E2 }, /* R21030 - VSS_XTD10_1 */
- { 21031, 0x75C0 }, /* R21031 - VSS_XTD10_0 */
- { 21032, 0x0004 }, /* R21032 - VSS_XTD11_1 */
- { 21033, 0xB480 }, /* R21033 - VSS_XTD11_0 */
- { 21034, 0x00D4 }, /* R21034 - VSS_XTD12_1 */
- { 21035, 0xF980 }, /* R21035 - VSS_XTD12_0 */
- { 21036, 0x0004 }, /* R21036 - VSS_XTD13_1 */
- { 21037, 0x9140 }, /* R21037 - VSS_XTD13_0 */
- { 21038, 0x00D8 }, /* R21038 - VSS_XTD14_1 */
- { 21039, 0xA480 }, /* R21039 - VSS_XTD14_0 */
- { 21040, 0x0002 }, /* R21040 - VSS_XTD15_1 */
- { 21041, 0x3DC0 }, /* R21041 - VSS_XTD15_0 */
- { 21042, 0x00CF }, /* R21042 - VSS_XTD16_1 */
- { 21043, 0x7A80 }, /* R21043 - VSS_XTD16_0 */
- { 21044, 0x00DC }, /* R21044 - VSS_XTD17_1 */
- { 21045, 0x0600 }, /* R21045 - VSS_XTD17_0 */
- { 21046, 0x00F2 }, /* R21046 - VSS_XTD18_1 */
- { 21047, 0xDAC0 }, /* R21047 - VSS_XTD18_0 */
- { 21048, 0x00BA }, /* R21048 - VSS_XTD19_1 */
- { 21049, 0xF340 }, /* R21049 - VSS_XTD19_0 */
- { 21050, 0x000A }, /* R21050 - VSS_XTD20_1 */
- { 21051, 0x7940 }, /* R21051 - VSS_XTD20_0 */
- { 21052, 0x001C }, /* R21052 - VSS_XTD21_1 */
- { 21053, 0x0680 }, /* R21053 - VSS_XTD21_0 */
- { 21054, 0x00FD }, /* R21054 - VSS_XTD22_1 */
- { 21055, 0x2D00 }, /* R21055 - VSS_XTD22_0 */
- { 21056, 0x001C }, /* R21056 - VSS_XTD23_1 */
- { 21057, 0xE840 }, /* R21057 - VSS_XTD23_0 */
- { 21058, 0x000D }, /* R21058 - VSS_XTD24_1 */
- { 21059, 0xDC40 }, /* R21059 - VSS_XTD24_0 */
- { 21060, 0x00FC }, /* R21060 - VSS_XTD25_1 */
- { 21061, 0x9D00 }, /* R21061 - VSS_XTD25_0 */
- { 21062, 0x0009 }, /* R21062 - VSS_XTD26_1 */
- { 21063, 0x5580 }, /* R21063 - VSS_XTD26_0 */
- { 21064, 0x00FE }, /* R21064 - VSS_XTD27_1 */
- { 21065, 0x7E80 }, /* R21065 - VSS_XTD27_0 */
- { 21066, 0x000E }, /* R21066 - VSS_XTD28_1 */
- { 21067, 0xAB40 }, /* R21067 - VSS_XTD28_0 */
- { 21068, 0x00F9 }, /* R21068 - VSS_XTD29_1 */
- { 21069, 0x9880 }, /* R21069 - VSS_XTD29_0 */
- { 21070, 0x0009 }, /* R21070 - VSS_XTD30_1 */
- { 21071, 0x87C0 }, /* R21071 - VSS_XTD30_0 */
- { 21072, 0x00FD }, /* R21072 - VSS_XTD31_1 */
- { 21073, 0x2C40 }, /* R21073 - VSS_XTD31_0 */
- { 21074, 0x0009 }, /* R21074 - VSS_XTD32_1 */
- { 21075, 0x4800 }, /* R21075 - VSS_XTD32_0 */
- { 21076, 0x0003 }, /* R21076 - VSS_XTS1_1 */
- { 21077, 0x5F40 }, /* R21077 - VSS_XTS1_0 */
- { 21078, 0x0000 }, /* R21078 - VSS_XTS2_1 */
- { 21079, 0x8700 }, /* R21079 - VSS_XTS2_0 */
- { 21080, 0x00FA }, /* R21080 - VSS_XTS3_1 */
- { 21081, 0xE4C0 }, /* R21081 - VSS_XTS3_0 */
- { 21082, 0x0000 }, /* R21082 - VSS_XTS4_1 */
- { 21083, 0x0B40 }, /* R21083 - VSS_XTS4_0 */
- { 21084, 0x0004 }, /* R21084 - VSS_XTS5_1 */
- { 21085, 0xE180 }, /* R21085 - VSS_XTS5_0 */
- { 21086, 0x0001 }, /* R21086 - VSS_XTS6_1 */
- { 21087, 0x1F40 }, /* R21087 - VSS_XTS6_0 */
- { 21088, 0x00F8 }, /* R21088 - VSS_XTS7_1 */
- { 21089, 0xB000 }, /* R21089 - VSS_XTS7_0 */
- { 21090, 0x00FB }, /* R21090 - VSS_XTS8_1 */
- { 21091, 0xCBC0 }, /* R21091 - VSS_XTS8_0 */
- { 21092, 0x0004 }, /* R21092 - VSS_XTS9_1 */
- { 21093, 0xF380 }, /* R21093 - VSS_XTS9_0 */
- { 21094, 0x0007 }, /* R21094 - VSS_XTS10_1 */
- { 21095, 0xDF40 }, /* R21095 - VSS_XTS10_0 */
- { 21096, 0x00FF }, /* R21096 - VSS_XTS11_1 */
- { 21097, 0x0700 }, /* R21097 - VSS_XTS11_0 */
- { 21098, 0x00EF }, /* R21098 - VSS_XTS12_1 */
- { 21099, 0xD700 }, /* R21099 - VSS_XTS12_0 */
- { 21100, 0x00FB }, /* R21100 - VSS_XTS13_1 */
- { 21101, 0xAF40 }, /* R21101 - VSS_XTS13_0 */
- { 21102, 0x0010 }, /* R21102 - VSS_XTS14_1 */
- { 21103, 0x8A80 }, /* R21103 - VSS_XTS14_0 */
- { 21104, 0x0011 }, /* R21104 - VSS_XTS15_1 */
- { 21105, 0x07C0 }, /* R21105 - VSS_XTS15_0 */
- { 21106, 0x00E0 }, /* R21106 - VSS_XTS16_1 */
- { 21107, 0x0800 }, /* R21107 - VSS_XTS16_0 */
- { 21108, 0x00D2 }, /* R21108 - VSS_XTS17_1 */
- { 21109, 0x7600 }, /* R21109 - VSS_XTS17_0 */
- { 21110, 0x0020 }, /* R21110 - VSS_XTS18_1 */
- { 21111, 0xCF40 }, /* R21111 - VSS_XTS18_0 */
- { 21112, 0x0030 }, /* R21112 - VSS_XTS19_1 */
- { 21113, 0x2340 }, /* R21113 - VSS_XTS19_0 */
- { 21114, 0x00FD }, /* R21114 - VSS_XTS20_1 */
- { 21115, 0x69C0 }, /* R21115 - VSS_XTS20_0 */
- { 21116, 0x0028 }, /* R21116 - VSS_XTS21_1 */
- { 21117, 0x3500 }, /* R21117 - VSS_XTS21_0 */
- { 21118, 0x0006 }, /* R21118 - VSS_XTS22_1 */
- { 21119, 0x3300 }, /* R21119 - VSS_XTS22_0 */
- { 21120, 0x00D9 }, /* R21120 - VSS_XTS23_1 */
- { 21121, 0xF6C0 }, /* R21121 - VSS_XTS23_0 */
- { 21122, 0x00F3 }, /* R21122 - VSS_XTS24_1 */
- { 21123, 0x3340 }, /* R21123 - VSS_XTS24_0 */
- { 21124, 0x000F }, /* R21124 - VSS_XTS25_1 */
- { 21125, 0x4200 }, /* R21125 - VSS_XTS25_0 */
- { 21126, 0x0004 }, /* R21126 - VSS_XTS26_1 */
- { 21127, 0x0C80 }, /* R21127 - VSS_XTS26_0 */
- { 21128, 0x00FB }, /* R21128 - VSS_XTS27_1 */
- { 21129, 0x3F80 }, /* R21129 - VSS_XTS27_0 */
- { 21130, 0x00F7 }, /* R21130 - VSS_XTS28_1 */
- { 21131, 0x57C0 }, /* R21131 - VSS_XTS28_0 */
- { 21132, 0x0003 }, /* R21132 - VSS_XTS29_1 */
- { 21133, 0x5400 }, /* R21133 - VSS_XTS29_0 */
- { 21134, 0x0000 }, /* R21134 - VSS_XTS30_1 */
- { 21135, 0xC6C0 }, /* R21135 - VSS_XTS30_0 */
- { 21136, 0x0003 }, /* R21136 - VSS_XTS31_1 */
- { 21137, 0x12C0 }, /* R21137 - VSS_XTS31_0 */
- { 21138, 0x00FD }, /* R21138 - VSS_XTS32_1 */
- { 21139, 0x8580 }, /* R21139 - VSS_XTS32_0 */
-};
-
-static bool wm8962_volatile_register(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM8962_CLOCKING1:
- case WM8962_CLOCKING2:
- case WM8962_SOFTWARE_RESET:
- case WM8962_ALC2:
- case WM8962_THERMAL_SHUTDOWN_STATUS:
- case WM8962_ADDITIONAL_CONTROL_4:
- case WM8962_CLASS_D_CONTROL_1:
- case WM8962_DC_SERVO_6:
- case WM8962_INTERRUPT_STATUS_1:
- case WM8962_INTERRUPT_STATUS_2:
- case WM8962_DSP2_EXECCONTROL:
- return true;
- default:
- return false;
- }
-}
-
-static bool wm8962_readable_register(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM8962_LEFT_INPUT_VOLUME:
- case WM8962_RIGHT_INPUT_VOLUME:
- case WM8962_HPOUTL_VOLUME:
- case WM8962_HPOUTR_VOLUME:
- case WM8962_CLOCKING1:
- case WM8962_ADC_DAC_CONTROL_1:
- case WM8962_ADC_DAC_CONTROL_2:
- case WM8962_AUDIO_INTERFACE_0:
- case WM8962_CLOCKING2:
- case WM8962_AUDIO_INTERFACE_1:
- case WM8962_LEFT_DAC_VOLUME:
- case WM8962_RIGHT_DAC_VOLUME:
- case WM8962_AUDIO_INTERFACE_2:
- case WM8962_SOFTWARE_RESET:
- case WM8962_ALC1:
- case WM8962_ALC2:
- case WM8962_ALC3:
- case WM8962_NOISE_GATE:
- case WM8962_LEFT_ADC_VOLUME:
- case WM8962_RIGHT_ADC_VOLUME:
- case WM8962_ADDITIONAL_CONTROL_1:
- case WM8962_ADDITIONAL_CONTROL_2:
- case WM8962_PWR_MGMT_1:
- case WM8962_PWR_MGMT_2:
- case WM8962_ADDITIONAL_CONTROL_3:
- case WM8962_ANTI_POP:
- case WM8962_CLOCKING_3:
- case WM8962_INPUT_MIXER_CONTROL_1:
- case WM8962_LEFT_INPUT_MIXER_VOLUME:
- case WM8962_RIGHT_INPUT_MIXER_VOLUME:
- case WM8962_INPUT_MIXER_CONTROL_2:
- case WM8962_INPUT_BIAS_CONTROL:
- case WM8962_LEFT_INPUT_PGA_CONTROL:
- case WM8962_RIGHT_INPUT_PGA_CONTROL:
- case WM8962_SPKOUTL_VOLUME:
- case WM8962_SPKOUTR_VOLUME:
- case WM8962_THERMAL_SHUTDOWN_STATUS:
- case WM8962_ADDITIONAL_CONTROL_4:
- case WM8962_CLASS_D_CONTROL_1:
- case WM8962_CLASS_D_CONTROL_2:
- case WM8962_CLOCKING_4:
- case WM8962_DAC_DSP_MIXING_1:
- case WM8962_DAC_DSP_MIXING_2:
- case WM8962_DC_SERVO_0:
- case WM8962_DC_SERVO_1:
- case WM8962_DC_SERVO_4:
- case WM8962_DC_SERVO_6:
- case WM8962_ANALOGUE_PGA_BIAS:
- case WM8962_ANALOGUE_HP_0:
- case WM8962_ANALOGUE_HP_2:
- case WM8962_CHARGE_PUMP_1:
- case WM8962_CHARGE_PUMP_B:
- case WM8962_WRITE_SEQUENCER_CONTROL_1:
- case WM8962_WRITE_SEQUENCER_CONTROL_2:
- case WM8962_WRITE_SEQUENCER_CONTROL_3:
- case WM8962_CONTROL_INTERFACE:
- case WM8962_MIXER_ENABLES:
- case WM8962_HEADPHONE_MIXER_1:
- case WM8962_HEADPHONE_MIXER_2:
- case WM8962_HEADPHONE_MIXER_3:
- case WM8962_HEADPHONE_MIXER_4:
- case WM8962_SPEAKER_MIXER_1:
- case WM8962_SPEAKER_MIXER_2:
- case WM8962_SPEAKER_MIXER_3:
- case WM8962_SPEAKER_MIXER_4:
- case WM8962_SPEAKER_MIXER_5:
- case WM8962_BEEP_GENERATOR_1:
- case WM8962_OSCILLATOR_TRIM_3:
- case WM8962_OSCILLATOR_TRIM_4:
- case WM8962_OSCILLATOR_TRIM_7:
- case WM8962_ANALOGUE_CLOCKING1:
- case WM8962_ANALOGUE_CLOCKING2:
- case WM8962_ANALOGUE_CLOCKING3:
- case WM8962_PLL_SOFTWARE_RESET:
- case WM8962_PLL2:
- case WM8962_PLL_4:
- case WM8962_PLL_9:
- case WM8962_PLL_10:
- case WM8962_PLL_11:
- case WM8962_PLL_12:
- case WM8962_PLL_13:
- case WM8962_PLL_14:
- case WM8962_PLL_15:
- case WM8962_PLL_16:
- case WM8962_FLL_CONTROL_1:
- case WM8962_FLL_CONTROL_2:
- case WM8962_FLL_CONTROL_3:
- case WM8962_FLL_CONTROL_5:
- case WM8962_FLL_CONTROL_6:
- case WM8962_FLL_CONTROL_7:
- case WM8962_FLL_CONTROL_8:
- case WM8962_GENERAL_TEST_1:
- case WM8962_DF1:
- case WM8962_DF2:
- case WM8962_DF3:
- case WM8962_DF4:
- case WM8962_DF5:
- case WM8962_DF6:
- case WM8962_DF7:
- case WM8962_LHPF1:
- case WM8962_LHPF2:
- case WM8962_THREED1:
- case WM8962_THREED2:
- case WM8962_THREED3:
- case WM8962_THREED4:
- case WM8962_DRC_1:
- case WM8962_DRC_2:
- case WM8962_DRC_3:
- case WM8962_DRC_4:
- case WM8962_DRC_5:
- case WM8962_TLOOPBACK:
- case WM8962_EQ1:
- case WM8962_EQ2:
- case WM8962_EQ3:
- case WM8962_EQ4:
- case WM8962_EQ5:
- case WM8962_EQ6:
- case WM8962_EQ7:
- case WM8962_EQ8:
- case WM8962_EQ9:
- case WM8962_EQ10:
- case WM8962_EQ11:
- case WM8962_EQ12:
- case WM8962_EQ13:
- case WM8962_EQ14:
- case WM8962_EQ15:
- case WM8962_EQ16:
- case WM8962_EQ17:
- case WM8962_EQ18:
- case WM8962_EQ19:
- case WM8962_EQ20:
- case WM8962_EQ21:
- case WM8962_EQ22:
- case WM8962_EQ23:
- case WM8962_EQ24:
- case WM8962_EQ25:
- case WM8962_EQ26:
- case WM8962_EQ27:
- case WM8962_EQ28:
- case WM8962_EQ29:
- case WM8962_EQ30:
- case WM8962_EQ31:
- case WM8962_EQ32:
- case WM8962_EQ33:
- case WM8962_EQ34:
- case WM8962_EQ35:
- case WM8962_EQ36:
- case WM8962_EQ37:
- case WM8962_EQ38:
- case WM8962_EQ39:
- case WM8962_EQ40:
- case WM8962_EQ41:
- case WM8962_GPIO_BASE:
- case WM8962_GPIO_2:
- case WM8962_GPIO_3:
- case WM8962_GPIO_5:
- case WM8962_GPIO_6:
- case WM8962_INTERRUPT_STATUS_1:
- case WM8962_INTERRUPT_STATUS_2:
- case WM8962_INTERRUPT_STATUS_1_MASK:
- case WM8962_INTERRUPT_STATUS_2_MASK:
- case WM8962_INTERRUPT_CONTROL:
- case WM8962_IRQ_DEBOUNCE:
- case WM8962_MICINT_SOURCE_POL:
- case WM8962_DSP2_POWER_MANAGEMENT:
- case WM8962_DSP2_EXECCONTROL:
- case WM8962_DSP2_INSTRUCTION_RAM_0:
- case WM8962_DSP2_ADDRESS_RAM_2:
- case WM8962_DSP2_ADDRESS_RAM_1:
- case WM8962_DSP2_ADDRESS_RAM_0:
- case WM8962_DSP2_DATA1_RAM_1:
- case WM8962_DSP2_DATA1_RAM_0:
- case WM8962_DSP2_DATA2_RAM_1:
- case WM8962_DSP2_DATA2_RAM_0:
- case WM8962_DSP2_DATA3_RAM_1:
- case WM8962_DSP2_DATA3_RAM_0:
- case WM8962_DSP2_COEFF_RAM_0:
- case WM8962_RETUNEADC_SHARED_COEFF_1:
- case WM8962_RETUNEADC_SHARED_COEFF_0:
- case WM8962_RETUNEDAC_SHARED_COEFF_1:
- case WM8962_RETUNEDAC_SHARED_COEFF_0:
- case WM8962_SOUNDSTAGE_ENABLES_1:
- case WM8962_SOUNDSTAGE_ENABLES_0:
- case WM8962_HDBASS_AI_1:
- case WM8962_HDBASS_AI_0:
- case WM8962_HDBASS_AR_1:
- case WM8962_HDBASS_AR_0:
- case WM8962_HDBASS_B_1:
- case WM8962_HDBASS_B_0:
- case WM8962_HDBASS_K_1:
- case WM8962_HDBASS_K_0:
- case WM8962_HDBASS_N1_1:
- case WM8962_HDBASS_N1_0:
- case WM8962_HDBASS_N2_1:
- case WM8962_HDBASS_N2_0:
- case WM8962_HDBASS_N3_1:
- case WM8962_HDBASS_N3_0:
- case WM8962_HDBASS_N4_1:
- case WM8962_HDBASS_N4_0:
- case WM8962_HDBASS_N5_1:
- case WM8962_HDBASS_N5_0:
- case WM8962_HDBASS_X1_1:
- case WM8962_HDBASS_X1_0:
- case WM8962_HDBASS_X2_1:
- case WM8962_HDBASS_X2_0:
- case WM8962_HDBASS_X3_1:
- case WM8962_HDBASS_X3_0:
- case WM8962_HDBASS_ATK_1:
- case WM8962_HDBASS_ATK_0:
- case WM8962_HDBASS_DCY_1:
- case WM8962_HDBASS_DCY_0:
- case WM8962_HDBASS_PG_1:
- case WM8962_HDBASS_PG_0:
- case WM8962_HPF_C_1:
- case WM8962_HPF_C_0:
- case WM8962_ADCL_RETUNE_C1_1:
- case WM8962_ADCL_RETUNE_C1_0:
- case WM8962_ADCL_RETUNE_C2_1:
- case WM8962_ADCL_RETUNE_C2_0:
- case WM8962_ADCL_RETUNE_C3_1:
- case WM8962_ADCL_RETUNE_C3_0:
- case WM8962_ADCL_RETUNE_C4_1:
- case WM8962_ADCL_RETUNE_C4_0:
- case WM8962_ADCL_RETUNE_C5_1:
- case WM8962_ADCL_RETUNE_C5_0:
- case WM8962_ADCL_RETUNE_C6_1:
- case WM8962_ADCL_RETUNE_C6_0:
- case WM8962_ADCL_RETUNE_C7_1:
- case WM8962_ADCL_RETUNE_C7_0:
- case WM8962_ADCL_RETUNE_C8_1:
- case WM8962_ADCL_RETUNE_C8_0:
- case WM8962_ADCL_RETUNE_C9_1:
- case WM8962_ADCL_RETUNE_C9_0:
- case WM8962_ADCL_RETUNE_C10_1:
- case WM8962_ADCL_RETUNE_C10_0:
- case WM8962_ADCL_RETUNE_C11_1:
- case WM8962_ADCL_RETUNE_C11_0:
- case WM8962_ADCL_RETUNE_C12_1:
- case WM8962_ADCL_RETUNE_C12_0:
- case WM8962_ADCL_RETUNE_C13_1:
- case WM8962_ADCL_RETUNE_C13_0:
- case WM8962_ADCL_RETUNE_C14_1:
- case WM8962_ADCL_RETUNE_C14_0:
- case WM8962_ADCL_RETUNE_C15_1:
- case WM8962_ADCL_RETUNE_C15_0:
- case WM8962_ADCL_RETUNE_C16_1:
- case WM8962_ADCL_RETUNE_C16_0:
- case WM8962_ADCL_RETUNE_C17_1:
- case WM8962_ADCL_RETUNE_C17_0:
- case WM8962_ADCL_RETUNE_C18_1:
- case WM8962_ADCL_RETUNE_C18_0:
- case WM8962_ADCL_RETUNE_C19_1:
- case WM8962_ADCL_RETUNE_C19_0:
- case WM8962_ADCL_RETUNE_C20_1:
- case WM8962_ADCL_RETUNE_C20_0:
- case WM8962_ADCL_RETUNE_C21_1:
- case WM8962_ADCL_RETUNE_C21_0:
- case WM8962_ADCL_RETUNE_C22_1:
- case WM8962_ADCL_RETUNE_C22_0:
- case WM8962_ADCL_RETUNE_C23_1:
- case WM8962_ADCL_RETUNE_C23_0:
- case WM8962_ADCL_RETUNE_C24_1:
- case WM8962_ADCL_RETUNE_C24_0:
- case WM8962_ADCL_RETUNE_C25_1:
- case WM8962_ADCL_RETUNE_C25_0:
- case WM8962_ADCL_RETUNE_C26_1:
- case WM8962_ADCL_RETUNE_C26_0:
- case WM8962_ADCL_RETUNE_C27_1:
- case WM8962_ADCL_RETUNE_C27_0:
- case WM8962_ADCL_RETUNE_C28_1:
- case WM8962_ADCL_RETUNE_C28_0:
- case WM8962_ADCL_RETUNE_C29_1:
- case WM8962_ADCL_RETUNE_C29_0:
- case WM8962_ADCL_RETUNE_C30_1:
- case WM8962_ADCL_RETUNE_C30_0:
- case WM8962_ADCL_RETUNE_C31_1:
- case WM8962_ADCL_RETUNE_C31_0:
- case WM8962_ADCL_RETUNE_C32_1:
- case WM8962_ADCL_RETUNE_C32_0:
- case WM8962_RETUNEADC_PG2_1:
- case WM8962_RETUNEADC_PG2_0:
- case WM8962_RETUNEADC_PG_1:
- case WM8962_RETUNEADC_PG_0:
- case WM8962_ADCR_RETUNE_C1_1:
- case WM8962_ADCR_RETUNE_C1_0:
- case WM8962_ADCR_RETUNE_C2_1:
- case WM8962_ADCR_RETUNE_C2_0:
- case WM8962_ADCR_RETUNE_C3_1:
- case WM8962_ADCR_RETUNE_C3_0:
- case WM8962_ADCR_RETUNE_C4_1:
- case WM8962_ADCR_RETUNE_C4_0:
- case WM8962_ADCR_RETUNE_C5_1:
- case WM8962_ADCR_RETUNE_C5_0:
- case WM8962_ADCR_RETUNE_C6_1:
- case WM8962_ADCR_RETUNE_C6_0:
- case WM8962_ADCR_RETUNE_C7_1:
- case WM8962_ADCR_RETUNE_C7_0:
- case WM8962_ADCR_RETUNE_C8_1:
- case WM8962_ADCR_RETUNE_C8_0:
- case WM8962_ADCR_RETUNE_C9_1:
- case WM8962_ADCR_RETUNE_C9_0:
- case WM8962_ADCR_RETUNE_C10_1:
- case WM8962_ADCR_RETUNE_C10_0:
- case WM8962_ADCR_RETUNE_C11_1:
- case WM8962_ADCR_RETUNE_C11_0:
- case WM8962_ADCR_RETUNE_C12_1:
- case WM8962_ADCR_RETUNE_C12_0:
- case WM8962_ADCR_RETUNE_C13_1:
- case WM8962_ADCR_RETUNE_C13_0:
- case WM8962_ADCR_RETUNE_C14_1:
- case WM8962_ADCR_RETUNE_C14_0:
- case WM8962_ADCR_RETUNE_C15_1:
- case WM8962_ADCR_RETUNE_C15_0:
- case WM8962_ADCR_RETUNE_C16_1:
- case WM8962_ADCR_RETUNE_C16_0:
- case WM8962_ADCR_RETUNE_C17_1:
- case WM8962_ADCR_RETUNE_C17_0:
- case WM8962_ADCR_RETUNE_C18_1:
- case WM8962_ADCR_RETUNE_C18_0:
- case WM8962_ADCR_RETUNE_C19_1:
- case WM8962_ADCR_RETUNE_C19_0:
- case WM8962_ADCR_RETUNE_C20_1:
- case WM8962_ADCR_RETUNE_C20_0:
- case WM8962_ADCR_RETUNE_C21_1:
- case WM8962_ADCR_RETUNE_C21_0:
- case WM8962_ADCR_RETUNE_C22_1:
- case WM8962_ADCR_RETUNE_C22_0:
- case WM8962_ADCR_RETUNE_C23_1:
- case WM8962_ADCR_RETUNE_C23_0:
- case WM8962_ADCR_RETUNE_C24_1:
- case WM8962_ADCR_RETUNE_C24_0:
- case WM8962_ADCR_RETUNE_C25_1:
- case WM8962_ADCR_RETUNE_C25_0:
- case WM8962_ADCR_RETUNE_C26_1:
- case WM8962_ADCR_RETUNE_C26_0:
- case WM8962_ADCR_RETUNE_C27_1:
- case WM8962_ADCR_RETUNE_C27_0:
- case WM8962_ADCR_RETUNE_C28_1:
- case WM8962_ADCR_RETUNE_C28_0:
- case WM8962_ADCR_RETUNE_C29_1:
- case WM8962_ADCR_RETUNE_C29_0:
- case WM8962_ADCR_RETUNE_C30_1:
- case WM8962_ADCR_RETUNE_C30_0:
- case WM8962_ADCR_RETUNE_C31_1:
- case WM8962_ADCR_RETUNE_C31_0:
- case WM8962_ADCR_RETUNE_C32_1:
- case WM8962_ADCR_RETUNE_C32_0:
- case WM8962_DACL_RETUNE_C1_1:
- case WM8962_DACL_RETUNE_C1_0:
- case WM8962_DACL_RETUNE_C2_1:
- case WM8962_DACL_RETUNE_C2_0:
- case WM8962_DACL_RETUNE_C3_1:
- case WM8962_DACL_RETUNE_C3_0:
- case WM8962_DACL_RETUNE_C4_1:
- case WM8962_DACL_RETUNE_C4_0:
- case WM8962_DACL_RETUNE_C5_1:
- case WM8962_DACL_RETUNE_C5_0:
- case WM8962_DACL_RETUNE_C6_1:
- case WM8962_DACL_RETUNE_C6_0:
- case WM8962_DACL_RETUNE_C7_1:
- case WM8962_DACL_RETUNE_C7_0:
- case WM8962_DACL_RETUNE_C8_1:
- case WM8962_DACL_RETUNE_C8_0:
- case WM8962_DACL_RETUNE_C9_1:
- case WM8962_DACL_RETUNE_C9_0:
- case WM8962_DACL_RETUNE_C10_1:
- case WM8962_DACL_RETUNE_C10_0:
- case WM8962_DACL_RETUNE_C11_1:
- case WM8962_DACL_RETUNE_C11_0:
- case WM8962_DACL_RETUNE_C12_1:
- case WM8962_DACL_RETUNE_C12_0:
- case WM8962_DACL_RETUNE_C13_1:
- case WM8962_DACL_RETUNE_C13_0:
- case WM8962_DACL_RETUNE_C14_1:
- case WM8962_DACL_RETUNE_C14_0:
- case WM8962_DACL_RETUNE_C15_1:
- case WM8962_DACL_RETUNE_C15_0:
- case WM8962_DACL_RETUNE_C16_1:
- case WM8962_DACL_RETUNE_C16_0:
- case WM8962_DACL_RETUNE_C17_1:
- case WM8962_DACL_RETUNE_C17_0:
- case WM8962_DACL_RETUNE_C18_1:
- case WM8962_DACL_RETUNE_C18_0:
- case WM8962_DACL_RETUNE_C19_1:
- case WM8962_DACL_RETUNE_C19_0:
- case WM8962_DACL_RETUNE_C20_1:
- case WM8962_DACL_RETUNE_C20_0:
- case WM8962_DACL_RETUNE_C21_1:
- case WM8962_DACL_RETUNE_C21_0:
- case WM8962_DACL_RETUNE_C22_1:
- case WM8962_DACL_RETUNE_C22_0:
- case WM8962_DACL_RETUNE_C23_1:
- case WM8962_DACL_RETUNE_C23_0:
- case WM8962_DACL_RETUNE_C24_1:
- case WM8962_DACL_RETUNE_C24_0:
- case WM8962_DACL_RETUNE_C25_1:
- case WM8962_DACL_RETUNE_C25_0:
- case WM8962_DACL_RETUNE_C26_1:
- case WM8962_DACL_RETUNE_C26_0:
- case WM8962_DACL_RETUNE_C27_1:
- case WM8962_DACL_RETUNE_C27_0:
- case WM8962_DACL_RETUNE_C28_1:
- case WM8962_DACL_RETUNE_C28_0:
- case WM8962_DACL_RETUNE_C29_1:
- case WM8962_DACL_RETUNE_C29_0:
- case WM8962_DACL_RETUNE_C30_1:
- case WM8962_DACL_RETUNE_C30_0:
- case WM8962_DACL_RETUNE_C31_1:
- case WM8962_DACL_RETUNE_C31_0:
- case WM8962_DACL_RETUNE_C32_1:
- case WM8962_DACL_RETUNE_C32_0:
- case WM8962_RETUNEDAC_PG2_1:
- case WM8962_RETUNEDAC_PG2_0:
- case WM8962_RETUNEDAC_PG_1:
- case WM8962_RETUNEDAC_PG_0:
- case WM8962_DACR_RETUNE_C1_1:
- case WM8962_DACR_RETUNE_C1_0:
- case WM8962_DACR_RETUNE_C2_1:
- case WM8962_DACR_RETUNE_C2_0:
- case WM8962_DACR_RETUNE_C3_1:
- case WM8962_DACR_RETUNE_C3_0:
- case WM8962_DACR_RETUNE_C4_1:
- case WM8962_DACR_RETUNE_C4_0:
- case WM8962_DACR_RETUNE_C5_1:
- case WM8962_DACR_RETUNE_C5_0:
- case WM8962_DACR_RETUNE_C6_1:
- case WM8962_DACR_RETUNE_C6_0:
- case WM8962_DACR_RETUNE_C7_1:
- case WM8962_DACR_RETUNE_C7_0:
- case WM8962_DACR_RETUNE_C8_1:
- case WM8962_DACR_RETUNE_C8_0:
- case WM8962_DACR_RETUNE_C9_1:
- case WM8962_DACR_RETUNE_C9_0:
- case WM8962_DACR_RETUNE_C10_1:
- case WM8962_DACR_RETUNE_C10_0:
- case WM8962_DACR_RETUNE_C11_1:
- case WM8962_DACR_RETUNE_C11_0:
- case WM8962_DACR_RETUNE_C12_1:
- case WM8962_DACR_RETUNE_C12_0:
- case WM8962_DACR_RETUNE_C13_1:
- case WM8962_DACR_RETUNE_C13_0:
- case WM8962_DACR_RETUNE_C14_1:
- case WM8962_DACR_RETUNE_C14_0:
- case WM8962_DACR_RETUNE_C15_1:
- case WM8962_DACR_RETUNE_C15_0:
- case WM8962_DACR_RETUNE_C16_1:
- case WM8962_DACR_RETUNE_C16_0:
- case WM8962_DACR_RETUNE_C17_1:
- case WM8962_DACR_RETUNE_C17_0:
- case WM8962_DACR_RETUNE_C18_1:
- case WM8962_DACR_RETUNE_C18_0:
- case WM8962_DACR_RETUNE_C19_1:
- case WM8962_DACR_RETUNE_C19_0:
- case WM8962_DACR_RETUNE_C20_1:
- case WM8962_DACR_RETUNE_C20_0:
- case WM8962_DACR_RETUNE_C21_1:
- case WM8962_DACR_RETUNE_C21_0:
- case WM8962_DACR_RETUNE_C22_1:
- case WM8962_DACR_RETUNE_C22_0:
- case WM8962_DACR_RETUNE_C23_1:
- case WM8962_DACR_RETUNE_C23_0:
- case WM8962_DACR_RETUNE_C24_1:
- case WM8962_DACR_RETUNE_C24_0:
- case WM8962_DACR_RETUNE_C25_1:
- case WM8962_DACR_RETUNE_C25_0:
- case WM8962_DACR_RETUNE_C26_1:
- case WM8962_DACR_RETUNE_C26_0:
- case WM8962_DACR_RETUNE_C27_1:
- case WM8962_DACR_RETUNE_C27_0:
- case WM8962_DACR_RETUNE_C28_1:
- case WM8962_DACR_RETUNE_C28_0:
- case WM8962_DACR_RETUNE_C29_1:
- case WM8962_DACR_RETUNE_C29_0:
- case WM8962_DACR_RETUNE_C30_1:
- case WM8962_DACR_RETUNE_C30_0:
- case WM8962_DACR_RETUNE_C31_1:
- case WM8962_DACR_RETUNE_C31_0:
- case WM8962_DACR_RETUNE_C32_1:
- case WM8962_DACR_RETUNE_C32_0:
- case WM8962_VSS_XHD2_1:
- case WM8962_VSS_XHD2_0:
- case WM8962_VSS_XHD3_1:
- case WM8962_VSS_XHD3_0:
- case WM8962_VSS_XHN1_1:
- case WM8962_VSS_XHN1_0:
- case WM8962_VSS_XHN2_1:
- case WM8962_VSS_XHN2_0:
- case WM8962_VSS_XHN3_1:
- case WM8962_VSS_XHN3_0:
- case WM8962_VSS_XLA_1:
- case WM8962_VSS_XLA_0:
- case WM8962_VSS_XLB_1:
- case WM8962_VSS_XLB_0:
- case WM8962_VSS_XLG_1:
- case WM8962_VSS_XLG_0:
- case WM8962_VSS_PG2_1:
- case WM8962_VSS_PG2_0:
- case WM8962_VSS_PG_1:
- case WM8962_VSS_PG_0:
- case WM8962_VSS_XTD1_1:
- case WM8962_VSS_XTD1_0:
- case WM8962_VSS_XTD2_1:
- case WM8962_VSS_XTD2_0:
- case WM8962_VSS_XTD3_1:
- case WM8962_VSS_XTD3_0:
- case WM8962_VSS_XTD4_1:
- case WM8962_VSS_XTD4_0:
- case WM8962_VSS_XTD5_1:
- case WM8962_VSS_XTD5_0:
- case WM8962_VSS_XTD6_1:
- case WM8962_VSS_XTD6_0:
- case WM8962_VSS_XTD7_1:
- case WM8962_VSS_XTD7_0:
- case WM8962_VSS_XTD8_1:
- case WM8962_VSS_XTD8_0:
- case WM8962_VSS_XTD9_1:
- case WM8962_VSS_XTD9_0:
- case WM8962_VSS_XTD10_1:
- case WM8962_VSS_XTD10_0:
- case WM8962_VSS_XTD11_1:
- case WM8962_VSS_XTD11_0:
- case WM8962_VSS_XTD12_1:
- case WM8962_VSS_XTD12_0:
- case WM8962_VSS_XTD13_1:
- case WM8962_VSS_XTD13_0:
- case WM8962_VSS_XTD14_1:
- case WM8962_VSS_XTD14_0:
- case WM8962_VSS_XTD15_1:
- case WM8962_VSS_XTD15_0:
- case WM8962_VSS_XTD16_1:
- case WM8962_VSS_XTD16_0:
- case WM8962_VSS_XTD17_1:
- case WM8962_VSS_XTD17_0:
- case WM8962_VSS_XTD18_1:
- case WM8962_VSS_XTD18_0:
- case WM8962_VSS_XTD19_1:
- case WM8962_VSS_XTD19_0:
- case WM8962_VSS_XTD20_1:
- case WM8962_VSS_XTD20_0:
- case WM8962_VSS_XTD21_1:
- case WM8962_VSS_XTD21_0:
- case WM8962_VSS_XTD22_1:
- case WM8962_VSS_XTD22_0:
- case WM8962_VSS_XTD23_1:
- case WM8962_VSS_XTD23_0:
- case WM8962_VSS_XTD24_1:
- case WM8962_VSS_XTD24_0:
- case WM8962_VSS_XTD25_1:
- case WM8962_VSS_XTD25_0:
- case WM8962_VSS_XTD26_1:
- case WM8962_VSS_XTD26_0:
- case WM8962_VSS_XTD27_1:
- case WM8962_VSS_XTD27_0:
- case WM8962_VSS_XTD28_1:
- case WM8962_VSS_XTD28_0:
- case WM8962_VSS_XTD29_1:
- case WM8962_VSS_XTD29_0:
- case WM8962_VSS_XTD30_1:
- case WM8962_VSS_XTD30_0:
- case WM8962_VSS_XTD31_1:
- case WM8962_VSS_XTD31_0:
- case WM8962_VSS_XTD32_1:
- case WM8962_VSS_XTD32_0:
- case WM8962_VSS_XTS1_1:
- case WM8962_VSS_XTS1_0:
- case WM8962_VSS_XTS2_1:
- case WM8962_VSS_XTS2_0:
- case WM8962_VSS_XTS3_1:
- case WM8962_VSS_XTS3_0:
- case WM8962_VSS_XTS4_1:
- case WM8962_VSS_XTS4_0:
- case WM8962_VSS_XTS5_1:
- case WM8962_VSS_XTS5_0:
- case WM8962_VSS_XTS6_1:
- case WM8962_VSS_XTS6_0:
- case WM8962_VSS_XTS7_1:
- case WM8962_VSS_XTS7_0:
- case WM8962_VSS_XTS8_1:
- case WM8962_VSS_XTS8_0:
- case WM8962_VSS_XTS9_1:
- case WM8962_VSS_XTS9_0:
- case WM8962_VSS_XTS10_1:
- case WM8962_VSS_XTS10_0:
- case WM8962_VSS_XTS11_1:
- case WM8962_VSS_XTS11_0:
- case WM8962_VSS_XTS12_1:
- case WM8962_VSS_XTS12_0:
- case WM8962_VSS_XTS13_1:
- case WM8962_VSS_XTS13_0:
- case WM8962_VSS_XTS14_1:
- case WM8962_VSS_XTS14_0:
- case WM8962_VSS_XTS15_1:
- case WM8962_VSS_XTS15_0:
- case WM8962_VSS_XTS16_1:
- case WM8962_VSS_XTS16_0:
- case WM8962_VSS_XTS17_1:
- case WM8962_VSS_XTS17_0:
- case WM8962_VSS_XTS18_1:
- case WM8962_VSS_XTS18_0:
- case WM8962_VSS_XTS19_1:
- case WM8962_VSS_XTS19_0:
- case WM8962_VSS_XTS20_1:
- case WM8962_VSS_XTS20_0:
- case WM8962_VSS_XTS21_1:
- case WM8962_VSS_XTS21_0:
- case WM8962_VSS_XTS22_1:
- case WM8962_VSS_XTS22_0:
- case WM8962_VSS_XTS23_1:
- case WM8962_VSS_XTS23_0:
- case WM8962_VSS_XTS24_1:
- case WM8962_VSS_XTS24_0:
- case WM8962_VSS_XTS25_1:
- case WM8962_VSS_XTS25_0:
- case WM8962_VSS_XTS26_1:
- case WM8962_VSS_XTS26_0:
- case WM8962_VSS_XTS27_1:
- case WM8962_VSS_XTS27_0:
- case WM8962_VSS_XTS28_1:
- case WM8962_VSS_XTS28_0:
- case WM8962_VSS_XTS29_1:
- case WM8962_VSS_XTS29_0:
- case WM8962_VSS_XTS30_1:
- case WM8962_VSS_XTS30_0:
- case WM8962_VSS_XTS31_1:
- case WM8962_VSS_XTS31_0:
- case WM8962_VSS_XTS32_1:
- case WM8962_VSS_XTS32_0:
- return true;
- default:
- return false;
- }
-}
-
-static int wm8962_reset(struct wm8962_priv *wm8962)
-{
- int ret;
-
- ret = regmap_write(wm8962->regmap, WM8962_SOFTWARE_RESET, 0x6243);
- if (ret != 0)
- return ret;
-
- return regmap_write(wm8962->regmap, WM8962_PLL_SOFTWARE_RESET, 0);
-}
-
-static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0);
-static const DECLARE_TLV_DB_SCALE(mixin_tlv, -1500, 300, 0);
-static const unsigned int mixinpga_tlv[] = {
- TLV_DB_RANGE_HEAD(5),
- 0, 1, TLV_DB_SCALE_ITEM(0, 600, 0),
- 2, 2, TLV_DB_SCALE_ITEM(1300, 1300, 0),
- 3, 4, TLV_DB_SCALE_ITEM(1800, 200, 0),
- 5, 5, TLV_DB_SCALE_ITEM(2400, 0, 0),
- 6, 7, TLV_DB_SCALE_ITEM(2700, 300, 0),
-};
-static const DECLARE_TLV_DB_SCALE(beep_tlv, -9600, 600, 1);
-static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
-static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0);
-static const DECLARE_TLV_DB_SCALE(inmix_tlv, -600, 600, 0);
-static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
-static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
-static const DECLARE_TLV_DB_SCALE(hp_tlv, -700, 100, 0);
-static const unsigned int classd_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0),
- 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0),
-};
-static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
-
-static int wm8962_dsp2_write_config(struct snd_soc_codec *codec)
-{
- return 0;
-}
-
-static int wm8962_dsp2_set_enable(struct snd_soc_codec *codec, u16 val)
-{
- u16 adcl = snd_soc_read(codec, WM8962_LEFT_ADC_VOLUME);
- u16 adcr = snd_soc_read(codec, WM8962_RIGHT_ADC_VOLUME);
- u16 dac = snd_soc_read(codec, WM8962_ADC_DAC_CONTROL_1);
-
- /* Mute the ADCs and DACs */
- snd_soc_write(codec, WM8962_LEFT_ADC_VOLUME, 0);
- snd_soc_write(codec, WM8962_RIGHT_ADC_VOLUME, WM8962_ADC_VU);
- snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1,
- WM8962_DAC_MUTE, WM8962_DAC_MUTE);
-
- snd_soc_write(codec, WM8962_SOUNDSTAGE_ENABLES_0, val);
-
- /* Restore the ADCs and DACs */
- snd_soc_write(codec, WM8962_LEFT_ADC_VOLUME, adcl);
- snd_soc_write(codec, WM8962_RIGHT_ADC_VOLUME, adcr);
- snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1,
- WM8962_DAC_MUTE, dac);
-
- return 0;
-}
-
-static int wm8962_dsp2_start(struct snd_soc_codec *codec)
-{
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
-
- wm8962_dsp2_write_config(codec);
-
- snd_soc_write(codec, WM8962_DSP2_EXECCONTROL, WM8962_DSP2_RUNR);
-
- wm8962_dsp2_set_enable(codec, wm8962->dsp2_ena);
-
- return 0;
-}
-
-static int wm8962_dsp2_stop(struct snd_soc_codec *codec)
-{
- wm8962_dsp2_set_enable(codec, 0);
-
- snd_soc_write(codec, WM8962_DSP2_EXECCONTROL, WM8962_DSP2_STOP);
-
- return 0;
-}
-
-#define WM8962_DSP2_ENABLE(xname, xshift) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = wm8962_dsp2_ena_info, \
- .get = wm8962_dsp2_ena_get, .put = wm8962_dsp2_ena_put, \
- .private_value = xshift }
-
-static int wm8962_dsp2_ena_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
-
- return 0;
-}
-
-static int wm8962_dsp2_ena_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int shift = kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.integer.value[0] = !!(wm8962->dsp2_ena & 1 << shift);
-
- return 0;
-}
-
-static int wm8962_dsp2_ena_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int shift = kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
- int old = wm8962->dsp2_ena;
- int ret = 0;
- int dsp2_running = snd_soc_read(codec, WM8962_DSP2_POWER_MANAGEMENT) &
- WM8962_DSP2_ENA;
-
- mutex_lock(&codec->mutex);
-
- if (ucontrol->value.integer.value[0])
- wm8962->dsp2_ena |= 1 << shift;
- else
- wm8962->dsp2_ena &= ~(1 << shift);
-
- if (wm8962->dsp2_ena == old)
- goto out;
-
- ret = 1;
-
- if (dsp2_running) {
- if (wm8962->dsp2_ena)
- wm8962_dsp2_set_enable(codec, wm8962->dsp2_ena);
- else
- wm8962_dsp2_stop(codec);
- }
-
-out:
- mutex_unlock(&codec->mutex);
-
- return ret;
-}
-
-/* The VU bits for the headphones are in a different register to the mute
- * bits and only take effect on the PGA if it is actually powered.
- */
-static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- u16 *reg_cache = codec->reg_cache;
- int ret;
-
- /* Apply the update (if any) */
- ret = snd_soc_put_volsw(kcontrol, ucontrol);
- if (ret == 0)
- return 0;
-
- /* If the left PGA is enabled hit that VU bit... */
- if (snd_soc_read(codec, WM8962_PWR_MGMT_2) & WM8962_HPOUTL_PGA_ENA)
- return snd_soc_write(codec, WM8962_HPOUTL_VOLUME,
- reg_cache[WM8962_HPOUTL_VOLUME]);
-
- /* ...otherwise the right. The VU is stereo. */
- if (snd_soc_read(codec, WM8962_PWR_MGMT_2) & WM8962_HPOUTR_PGA_ENA)
- return snd_soc_write(codec, WM8962_HPOUTR_VOLUME,
- reg_cache[WM8962_HPOUTR_VOLUME]);
-
- return 0;
-}
-
-/* The VU bits for the speakers are in a different register to the mute
- * bits and only take effect on the PGA if it is actually powered.
- */
-static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- int ret;
-
- /* Apply the update (if any) */
- ret = snd_soc_put_volsw(kcontrol, ucontrol);
- if (ret == 0)
- return 0;
-
- /* If the left PGA is enabled hit that VU bit... */
- ret = snd_soc_read(codec, WM8962_PWR_MGMT_2);
- if (ret & WM8962_SPKOUTL_PGA_ENA) {
- snd_soc_write(codec, WM8962_SPKOUTL_VOLUME,
- snd_soc_read(codec, WM8962_SPKOUTL_VOLUME));
- return 1;
- }
-
- /* ...otherwise the right. The VU is stereo. */
- if (ret & WM8962_SPKOUTR_PGA_ENA)
- snd_soc_write(codec, WM8962_SPKOUTR_VOLUME,
- snd_soc_read(codec, WM8962_SPKOUTR_VOLUME));
-
- return 1;
-}
-
-static const char *cap_hpf_mode_text[] = {
- "Hi-fi", "Application"
-};
-
-static const struct soc_enum cap_hpf_mode =
- SOC_ENUM_SINGLE(WM8962_ADC_DAC_CONTROL_2, 10, 2, cap_hpf_mode_text);
-
-
-static const char *cap_lhpf_mode_text[] = {
- "LPF", "HPF"
-};
-
-static const struct soc_enum cap_lhpf_mode =
- SOC_ENUM_SINGLE(WM8962_LHPF1, 1, 2, cap_lhpf_mode_text);
-
-static const struct snd_kcontrol_new wm8962_snd_controls[] = {
-SOC_DOUBLE("Input Mixer Switch", WM8962_INPUT_MIXER_CONTROL_1, 3, 2, 1, 1),
-
-SOC_SINGLE_TLV("MIXINL IN2L Volume", WM8962_LEFT_INPUT_MIXER_VOLUME, 6, 7, 0,
- mixin_tlv),
-SOC_SINGLE_TLV("MIXINL PGA Volume", WM8962_LEFT_INPUT_MIXER_VOLUME, 3, 7, 0,
- mixinpga_tlv),
-SOC_SINGLE_TLV("MIXINL IN3L Volume", WM8962_LEFT_INPUT_MIXER_VOLUME, 0, 7, 0,
- mixin_tlv),
-
-SOC_SINGLE_TLV("MIXINR IN2R Volume", WM8962_RIGHT_INPUT_MIXER_VOLUME, 6, 7, 0,
- mixin_tlv),
-SOC_SINGLE_TLV("MIXINR PGA Volume", WM8962_RIGHT_INPUT_MIXER_VOLUME, 3, 7, 0,
- mixinpga_tlv),
-SOC_SINGLE_TLV("MIXINR IN3R Volume", WM8962_RIGHT_INPUT_MIXER_VOLUME, 0, 7, 0,
- mixin_tlv),
-
-SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8962_LEFT_ADC_VOLUME,
- WM8962_RIGHT_ADC_VOLUME, 1, 127, 0, digital_tlv),
-SOC_DOUBLE_R_TLV("Capture Volume", WM8962_LEFT_INPUT_VOLUME,
- WM8962_RIGHT_INPUT_VOLUME, 0, 63, 0, inpga_tlv),
-SOC_DOUBLE_R("Capture Switch", WM8962_LEFT_INPUT_VOLUME,
- WM8962_RIGHT_INPUT_VOLUME, 7, 1, 1),
-SOC_DOUBLE_R("Capture ZC Switch", WM8962_LEFT_INPUT_VOLUME,
- WM8962_RIGHT_INPUT_VOLUME, 6, 1, 1),
-SOC_SINGLE("Capture HPF Switch", WM8962_ADC_DAC_CONTROL_1, 0, 1, 1),
-SOC_ENUM("Capture HPF Mode", cap_hpf_mode),
-SOC_SINGLE("Capture HPF Cutoff", WM8962_ADC_DAC_CONTROL_2, 7, 7, 0),
-SOC_SINGLE("Capture LHPF Switch", WM8962_LHPF1, 0, 1, 0),
-SOC_ENUM("Capture LHPF Mode", cap_lhpf_mode),
-
-SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1,
- WM8962_DAC_DSP_MIXING_2, 4, 12, 0, st_tlv),
-
-SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8962_LEFT_DAC_VOLUME,
- WM8962_RIGHT_DAC_VOLUME, 1, 127, 0, digital_tlv),
-SOC_SINGLE("DAC High Performance Switch", WM8962_ADC_DAC_CONTROL_2, 0, 1, 0),
-SOC_SINGLE("DAC L/R Swap Switch", WM8962_AUDIO_INTERFACE_0, 5, 1, 0),
-SOC_SINGLE("ADC L/R Swap Switch", WM8962_AUDIO_INTERFACE_0, 8, 1, 0),
-
-SOC_SINGLE("ADC High Performance Switch", WM8962_ADDITIONAL_CONTROL_1,
- 5, 1, 0),
-
-SOC_SINGLE_TLV("Beep Volume", WM8962_BEEP_GENERATOR_1, 4, 15, 0, beep_tlv),
-
-SOC_DOUBLE_R_TLV("Headphone Volume", WM8962_HPOUTL_VOLUME,
- WM8962_HPOUTR_VOLUME, 0, 127, 0, out_tlv),
-SOC_DOUBLE_EXT("Headphone Switch", WM8962_PWR_MGMT_2, 1, 0, 1, 1,
- snd_soc_get_volsw, wm8962_put_hp_sw),
-SOC_DOUBLE_R("Headphone ZC Switch", WM8962_HPOUTL_VOLUME, WM8962_HPOUTR_VOLUME,
- 7, 1, 0),
-SOC_DOUBLE_TLV("Headphone Aux Volume", WM8962_ANALOGUE_HP_2, 3, 6, 7, 0,
- hp_tlv),
-
-SOC_DOUBLE_R("Headphone Mixer Switch", WM8962_HEADPHONE_MIXER_3,
- WM8962_HEADPHONE_MIXER_4, 8, 1, 1),
-
-SOC_SINGLE_TLV("HPMIXL IN4L Volume", WM8962_HEADPHONE_MIXER_3,
- 3, 7, 0, bypass_tlv),
-SOC_SINGLE_TLV("HPMIXL IN4R Volume", WM8962_HEADPHONE_MIXER_3,
- 0, 7, 0, bypass_tlv),
-SOC_SINGLE_TLV("HPMIXL MIXINL Volume", WM8962_HEADPHONE_MIXER_3,
- 7, 1, 1, inmix_tlv),
-SOC_SINGLE_TLV("HPMIXL MIXINR Volume", WM8962_HEADPHONE_MIXER_3,
- 6, 1, 1, inmix_tlv),
-
-SOC_SINGLE_TLV("HPMIXR IN4L Volume", WM8962_HEADPHONE_MIXER_4,
- 3, 7, 0, bypass_tlv),
-SOC_SINGLE_TLV("HPMIXR IN4R Volume", WM8962_HEADPHONE_MIXER_4,
- 0, 7, 0, bypass_tlv),
-SOC_SINGLE_TLV("HPMIXR MIXINL Volume", WM8962_HEADPHONE_MIXER_4,
- 7, 1, 1, inmix_tlv),
-SOC_SINGLE_TLV("HPMIXR MIXINR Volume", WM8962_HEADPHONE_MIXER_4,
- 6, 1, 1, inmix_tlv),
-
-SOC_SINGLE_TLV("Speaker Boost Volume", WM8962_CLASS_D_CONTROL_2, 0, 7, 0,
- classd_tlv),
-
-SOC_SINGLE("EQ Switch", WM8962_EQ1, WM8962_EQ_ENA_SHIFT, 1, 0),
-SOC_DOUBLE_R_TLV("EQ1 Volume", WM8962_EQ2, WM8962_EQ22,
- WM8962_EQL_B1_GAIN_SHIFT, 31, 0, eq_tlv),
-SOC_DOUBLE_R_TLV("EQ2 Volume", WM8962_EQ2, WM8962_EQ22,
- WM8962_EQL_B2_GAIN_SHIFT, 31, 0, eq_tlv),
-SOC_DOUBLE_R_TLV("EQ3 Volume", WM8962_EQ2, WM8962_EQ22,
- WM8962_EQL_B3_GAIN_SHIFT, 31, 0, eq_tlv),
-SOC_DOUBLE_R_TLV("EQ4 Volume", WM8962_EQ3, WM8962_EQ23,
- WM8962_EQL_B4_GAIN_SHIFT, 31, 0, eq_tlv),
-SOC_DOUBLE_R_TLV("EQ5 Volume", WM8962_EQ3, WM8962_EQ23,
- WM8962_EQL_B5_GAIN_SHIFT, 31, 0, eq_tlv),
-
-WM8962_DSP2_ENABLE("VSS Switch", WM8962_VSS_ENA_SHIFT),
-WM8962_DSP2_ENABLE("HPF1 Switch", WM8962_HPF1_ENA_SHIFT),
-WM8962_DSP2_ENABLE("HPF2 Switch", WM8962_HPF2_ENA_SHIFT),
-WM8962_DSP2_ENABLE("HD Bass Switch", WM8962_HDBASS_ENA_SHIFT),
-};
-
-static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = {
-SOC_SINGLE_TLV("Speaker Volume", WM8962_SPKOUTL_VOLUME, 0, 127, 0, out_tlv),
-SOC_SINGLE_EXT("Speaker Switch", WM8962_CLASS_D_CONTROL_1, 1, 1, 1,
- snd_soc_get_volsw, wm8962_put_spk_sw),
-SOC_SINGLE("Speaker ZC Switch", WM8962_SPKOUTL_VOLUME, 7, 1, 0),
-
-SOC_SINGLE("Speaker Mixer Switch", WM8962_SPEAKER_MIXER_3, 8, 1, 1),
-SOC_SINGLE_TLV("Speaker Mixer IN4L Volume", WM8962_SPEAKER_MIXER_3,
- 3, 7, 0, bypass_tlv),
-SOC_SINGLE_TLV("Speaker Mixer IN4R Volume", WM8962_SPEAKER_MIXER_3,
- 0, 7, 0, bypass_tlv),
-SOC_SINGLE_TLV("Speaker Mixer MIXINL Volume", WM8962_SPEAKER_MIXER_3,
- 7, 1, 1, inmix_tlv),
-SOC_SINGLE_TLV("Speaker Mixer MIXINR Volume", WM8962_SPEAKER_MIXER_3,
- 6, 1, 1, inmix_tlv),
-SOC_SINGLE_TLV("Speaker Mixer DACL Volume", WM8962_SPEAKER_MIXER_5,
- 7, 1, 0, inmix_tlv),
-SOC_SINGLE_TLV("Speaker Mixer DACR Volume", WM8962_SPEAKER_MIXER_5,
- 6, 1, 0, inmix_tlv),
-};
-
-static const struct snd_kcontrol_new wm8962_spk_stereo_controls[] = {
-SOC_DOUBLE_R_TLV("Speaker Volume", WM8962_SPKOUTL_VOLUME,
- WM8962_SPKOUTR_VOLUME, 0, 127, 0, out_tlv),
-SOC_DOUBLE_EXT("Speaker Switch", WM8962_CLASS_D_CONTROL_1, 1, 0, 1, 1,
- snd_soc_get_volsw, wm8962_put_spk_sw),
-SOC_DOUBLE_R("Speaker ZC Switch", WM8962_SPKOUTL_VOLUME, WM8962_SPKOUTR_VOLUME,
- 7, 1, 0),
-
-SOC_DOUBLE_R("Speaker Mixer Switch", WM8962_SPEAKER_MIXER_3,
- WM8962_SPEAKER_MIXER_4, 8, 1, 1),
-
-SOC_SINGLE_TLV("SPKOUTL Mixer IN4L Volume", WM8962_SPEAKER_MIXER_3,
- 3, 7, 0, bypass_tlv),
-SOC_SINGLE_TLV("SPKOUTL Mixer IN4R Volume", WM8962_SPEAKER_MIXER_3,
- 0, 7, 0, bypass_tlv),
-SOC_SINGLE_TLV("SPKOUTL Mixer MIXINL Volume", WM8962_SPEAKER_MIXER_3,
- 7, 1, 1, inmix_tlv),
-SOC_SINGLE_TLV("SPKOUTL Mixer MIXINR Volume", WM8962_SPEAKER_MIXER_3,
- 6, 1, 1, inmix_tlv),
-SOC_SINGLE_TLV("SPKOUTL Mixer DACL Volume", WM8962_SPEAKER_MIXER_5,
- 7, 1, 0, inmix_tlv),
-SOC_SINGLE_TLV("SPKOUTL Mixer DACR Volume", WM8962_SPEAKER_MIXER_5,
- 6, 1, 0, inmix_tlv),
-
-SOC_SINGLE_TLV("SPKOUTR Mixer IN4L Volume", WM8962_SPEAKER_MIXER_4,
- 3, 7, 0, bypass_tlv),
-SOC_SINGLE_TLV("SPKOUTR Mixer IN4R Volume", WM8962_SPEAKER_MIXER_4,
- 0, 7, 0, bypass_tlv),
-SOC_SINGLE_TLV("SPKOUTR Mixer MIXINL Volume", WM8962_SPEAKER_MIXER_4,
- 7, 1, 1, inmix_tlv),
-SOC_SINGLE_TLV("SPKOUTR Mixer MIXINR Volume", WM8962_SPEAKER_MIXER_4,
- 6, 1, 1, inmix_tlv),
-SOC_SINGLE_TLV("SPKOUTR Mixer DACL Volume", WM8962_SPEAKER_MIXER_5,
- 5, 1, 0, inmix_tlv),
-SOC_SINGLE_TLV("SPKOUTR Mixer DACR Volume", WM8962_SPEAKER_MIXER_5,
- 4, 1, 0, inmix_tlv),
-};
-
-static int cp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- msleep(5);
- break;
-
- default:
- BUG();
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int hp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- int timeout;
- int reg;
- int expected = (WM8962_DCS_STARTUP_DONE_HP1L |
- WM8962_DCS_STARTUP_DONE_HP1R);
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
- WM8962_HP1L_ENA | WM8962_HP1R_ENA,
- WM8962_HP1L_ENA | WM8962_HP1R_ENA);
- udelay(20);
-
- snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
- WM8962_HP1L_ENA_DLY | WM8962_HP1R_ENA_DLY,
- WM8962_HP1L_ENA_DLY | WM8962_HP1R_ENA_DLY);
-
- /* Start the DC servo */
- snd_soc_update_bits(codec, WM8962_DC_SERVO_1,
- WM8962_HP1L_DCS_ENA | WM8962_HP1R_DCS_ENA |
- WM8962_HP1L_DCS_STARTUP |
- WM8962_HP1R_DCS_STARTUP,
- WM8962_HP1L_DCS_ENA | WM8962_HP1R_DCS_ENA |
- WM8962_HP1L_DCS_STARTUP |
- WM8962_HP1R_DCS_STARTUP);
-
- /* Wait for it to complete, should be well under 100ms */
- timeout = 0;
- do {
- msleep(1);
- reg = snd_soc_read(codec, WM8962_DC_SERVO_6);
- if (reg < 0) {
- dev_err(codec->dev,
- "Failed to read DCS status: %d\n",
- reg);
- continue;
- }
- dev_dbg(codec->dev, "DCS status: %x\n", reg);
- } while (++timeout < 200 && (reg & expected) != expected);
-
- if ((reg & expected) != expected)
- dev_err(codec->dev, "DC servo timed out\n");
- else
- dev_dbg(codec->dev, "DC servo complete after %dms\n",
- timeout);
-
- snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
- WM8962_HP1L_ENA_OUTP |
- WM8962_HP1R_ENA_OUTP,
- WM8962_HP1L_ENA_OUTP |
- WM8962_HP1R_ENA_OUTP);
- udelay(20);
-
- snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
- WM8962_HP1L_RMV_SHORT |
- WM8962_HP1R_RMV_SHORT,
- WM8962_HP1L_RMV_SHORT |
- WM8962_HP1R_RMV_SHORT);
- break;
-
- case SND_SOC_DAPM_PRE_PMD:
- snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
- WM8962_HP1L_RMV_SHORT |
- WM8962_HP1R_RMV_SHORT, 0);
-
- udelay(20);
-
- snd_soc_update_bits(codec, WM8962_DC_SERVO_1,
- WM8962_HP1L_DCS_ENA | WM8962_HP1R_DCS_ENA |
- WM8962_HP1L_DCS_STARTUP |
- WM8962_HP1R_DCS_STARTUP,
- 0);
-
- snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
- WM8962_HP1L_ENA | WM8962_HP1R_ENA |
- WM8962_HP1L_ENA_DLY | WM8962_HP1R_ENA_DLY |
- WM8962_HP1L_ENA_OUTP |
- WM8962_HP1R_ENA_OUTP, 0);
-
- break;
-
- default:
- BUG();
- return -EINVAL;
-
- }
-
- return 0;
-}
-
-/* VU bits for the output PGAs only take effect while the PGA is powered */
-static int out_pga_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- int reg;
-
- switch (w->shift) {
- case WM8962_HPOUTR_PGA_ENA_SHIFT:
- reg = WM8962_HPOUTR_VOLUME;
- break;
- case WM8962_HPOUTL_PGA_ENA_SHIFT:
- reg = WM8962_HPOUTL_VOLUME;
- break;
- case WM8962_SPKOUTR_PGA_ENA_SHIFT:
- reg = WM8962_SPKOUTR_VOLUME;
- break;
- case WM8962_SPKOUTL_PGA_ENA_SHIFT:
- reg = WM8962_SPKOUTL_VOLUME;
- break;
- default:
- BUG();
- return -EINVAL;
- }
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- return snd_soc_write(codec, reg, snd_soc_read(codec, reg));
- default:
- BUG();
- return -EINVAL;
- }
-}
-
-static int dsp2_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- if (wm8962->dsp2_ena)
- wm8962_dsp2_start(codec);
- break;
-
- case SND_SOC_DAPM_PRE_PMD:
- if (wm8962->dsp2_ena)
- wm8962_dsp2_stop(codec);
- break;
-
- default:
- BUG();
- return -EINVAL;
- }
-
- return 0;
-}
-
-static const char *st_text[] = { "None", "Left", "Right" };
-
-static const struct soc_enum str_enum =
- SOC_ENUM_SINGLE(WM8962_DAC_DSP_MIXING_1, 2, 3, st_text);
-
-static const struct snd_kcontrol_new str_mux =
- SOC_DAPM_ENUM("Right Sidetone", str_enum);
-
-static const struct soc_enum stl_enum =
- SOC_ENUM_SINGLE(WM8962_DAC_DSP_MIXING_2, 2, 3, st_text);
-
-static const struct snd_kcontrol_new stl_mux =
- SOC_DAPM_ENUM("Left Sidetone", stl_enum);
-
-static const char *outmux_text[] = { "DAC", "Mixer" };
-
-static const struct soc_enum spkoutr_enum =
- SOC_ENUM_SINGLE(WM8962_SPEAKER_MIXER_2, 7, 2, outmux_text);
-
-static const struct snd_kcontrol_new spkoutr_mux =
- SOC_DAPM_ENUM("SPKOUTR Mux", spkoutr_enum);
-
-static const struct soc_enum spkoutl_enum =
- SOC_ENUM_SINGLE(WM8962_SPEAKER_MIXER_1, 7, 2, outmux_text);
-
-static const struct snd_kcontrol_new spkoutl_mux =
- SOC_DAPM_ENUM("SPKOUTL Mux", spkoutl_enum);
-
-static const struct soc_enum hpoutr_enum =
- SOC_ENUM_SINGLE(WM8962_HEADPHONE_MIXER_2, 7, 2, outmux_text);
-
-static const struct snd_kcontrol_new hpoutr_mux =
- SOC_DAPM_ENUM("HPOUTR Mux", hpoutr_enum);
-
-static const struct soc_enum hpoutl_enum =
- SOC_ENUM_SINGLE(WM8962_HEADPHONE_MIXER_1, 7, 2, outmux_text);
-
-static const struct snd_kcontrol_new hpoutl_mux =
- SOC_DAPM_ENUM("HPOUTL Mux", hpoutl_enum);
-
-static const struct snd_kcontrol_new inpgal[] = {
-SOC_DAPM_SINGLE("IN1L Switch", WM8962_LEFT_INPUT_PGA_CONTROL, 3, 1, 0),
-SOC_DAPM_SINGLE("IN2L Switch", WM8962_LEFT_INPUT_PGA_CONTROL, 2, 1, 0),
-SOC_DAPM_SINGLE("IN3L Switch", WM8962_LEFT_INPUT_PGA_CONTROL, 1, 1, 0),
-SOC_DAPM_SINGLE("IN4L Switch", WM8962_LEFT_INPUT_PGA_CONTROL, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new inpgar[] = {
-SOC_DAPM_SINGLE("IN1R Switch", WM8962_RIGHT_INPUT_PGA_CONTROL, 3, 1, 0),
-SOC_DAPM_SINGLE("IN2R Switch", WM8962_RIGHT_INPUT_PGA_CONTROL, 2, 1, 0),
-SOC_DAPM_SINGLE("IN3R Switch", WM8962_RIGHT_INPUT_PGA_CONTROL, 1, 1, 0),
-SOC_DAPM_SINGLE("IN4R Switch", WM8962_RIGHT_INPUT_PGA_CONTROL, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new mixinl[] = {
-SOC_DAPM_SINGLE("IN2L Switch", WM8962_INPUT_MIXER_CONTROL_2, 5, 1, 0),
-SOC_DAPM_SINGLE("IN3L Switch", WM8962_INPUT_MIXER_CONTROL_2, 4, 1, 0),
-SOC_DAPM_SINGLE("PGA Switch", WM8962_INPUT_MIXER_CONTROL_2, 3, 1, 0),
-};
-
-static const struct snd_kcontrol_new mixinr[] = {
-SOC_DAPM_SINGLE("IN2R Switch", WM8962_INPUT_MIXER_CONTROL_2, 2, 1, 0),
-SOC_DAPM_SINGLE("IN3R Switch", WM8962_INPUT_MIXER_CONTROL_2, 1, 1, 0),
-SOC_DAPM_SINGLE("PGA Switch", WM8962_INPUT_MIXER_CONTROL_2, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new hpmixl[] = {
-SOC_DAPM_SINGLE("DACL Switch", WM8962_HEADPHONE_MIXER_1, 5, 1, 0),
-SOC_DAPM_SINGLE("DACR Switch", WM8962_HEADPHONE_MIXER_1, 4, 1, 0),
-SOC_DAPM_SINGLE("MIXINL Switch", WM8962_HEADPHONE_MIXER_1, 3, 1, 0),
-SOC_DAPM_SINGLE("MIXINR Switch", WM8962_HEADPHONE_MIXER_1, 2, 1, 0),
-SOC_DAPM_SINGLE("IN4L Switch", WM8962_HEADPHONE_MIXER_1, 1, 1, 0),
-SOC_DAPM_SINGLE("IN4R Switch", WM8962_HEADPHONE_MIXER_1, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new hpmixr[] = {
-SOC_DAPM_SINGLE("DACL Switch", WM8962_HEADPHONE_MIXER_2, 5, 1, 0),
-SOC_DAPM_SINGLE("DACR Switch", WM8962_HEADPHONE_MIXER_2, 4, 1, 0),
-SOC_DAPM_SINGLE("MIXINL Switch", WM8962_HEADPHONE_MIXER_2, 3, 1, 0),
-SOC_DAPM_SINGLE("MIXINR Switch", WM8962_HEADPHONE_MIXER_2, 2, 1, 0),
-SOC_DAPM_SINGLE("IN4L Switch", WM8962_HEADPHONE_MIXER_2, 1, 1, 0),
-SOC_DAPM_SINGLE("IN4R Switch", WM8962_HEADPHONE_MIXER_2, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new spkmixl[] = {
-SOC_DAPM_SINGLE("DACL Switch", WM8962_SPEAKER_MIXER_1, 5, 1, 0),
-SOC_DAPM_SINGLE("DACR Switch", WM8962_SPEAKER_MIXER_1, 4, 1, 0),
-SOC_DAPM_SINGLE("MIXINL Switch", WM8962_SPEAKER_MIXER_1, 3, 1, 0),
-SOC_DAPM_SINGLE("MIXINR Switch", WM8962_SPEAKER_MIXER_1, 2, 1, 0),
-SOC_DAPM_SINGLE("IN4L Switch", WM8962_SPEAKER_MIXER_1, 1, 1, 0),
-SOC_DAPM_SINGLE("IN4R Switch", WM8962_SPEAKER_MIXER_1, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new spkmixr[] = {
-SOC_DAPM_SINGLE("DACL Switch", WM8962_SPEAKER_MIXER_2, 5, 1, 0),
-SOC_DAPM_SINGLE("DACR Switch", WM8962_SPEAKER_MIXER_2, 4, 1, 0),
-SOC_DAPM_SINGLE("MIXINL Switch", WM8962_SPEAKER_MIXER_2, 3, 1, 0),
-SOC_DAPM_SINGLE("MIXINR Switch", WM8962_SPEAKER_MIXER_2, 2, 1, 0),
-SOC_DAPM_SINGLE("IN4L Switch", WM8962_SPEAKER_MIXER_2, 1, 1, 0),
-SOC_DAPM_SINGLE("IN4R Switch", WM8962_SPEAKER_MIXER_2, 0, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget wm8962_dapm_widgets[] = {
-SND_SOC_DAPM_INPUT("IN1L"),
-SND_SOC_DAPM_INPUT("IN1R"),
-SND_SOC_DAPM_INPUT("IN2L"),
-SND_SOC_DAPM_INPUT("IN2R"),
-SND_SOC_DAPM_INPUT("IN3L"),
-SND_SOC_DAPM_INPUT("IN3R"),
-SND_SOC_DAPM_INPUT("IN4L"),
-SND_SOC_DAPM_INPUT("IN4R"),
-SND_SOC_DAPM_SIGGEN("Beep"),
-SND_SOC_DAPM_INPUT("DMICDAT"),
-
-SND_SOC_DAPM_SUPPLY("MICBIAS", WM8962_PWR_MGMT_1, 1, 0, NULL, 0),
-
-SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0),
-SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event,
- SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY_S("DSP2", 1, WM8962_DSP2_POWER_MANAGEMENT,
- WM8962_DSP2_ENA_SHIFT, 0, dsp2_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-SND_SOC_DAPM_SUPPLY("TEMP_HP", WM8962_ADDITIONAL_CONTROL_4, 2, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("TEMP_SPK", WM8962_ADDITIONAL_CONTROL_4, 1, 0, NULL, 0),
-
-SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0,
- inpgal, ARRAY_SIZE(inpgal)),
-SND_SOC_DAPM_MIXER("INPGAR", WM8962_RIGHT_INPUT_PGA_CONTROL, 4, 0,
- inpgar, ARRAY_SIZE(inpgar)),
-SND_SOC_DAPM_MIXER("MIXINL", WM8962_PWR_MGMT_1, 5, 0,
- mixinl, ARRAY_SIZE(mixinl)),
-SND_SOC_DAPM_MIXER("MIXINR", WM8962_PWR_MGMT_1, 4, 0,
- mixinr, ARRAY_SIZE(mixinr)),
-
-SND_SOC_DAPM_AIF_IN("DMIC_ENA", NULL, 0, WM8962_PWR_MGMT_1, 10, 0),
-
-SND_SOC_DAPM_ADC("ADCL", "Capture", WM8962_PWR_MGMT_1, 3, 0),
-SND_SOC_DAPM_ADC("ADCR", "Capture", WM8962_PWR_MGMT_1, 2, 0),
-
-SND_SOC_DAPM_MUX("STL", SND_SOC_NOPM, 0, 0, &stl_mux),
-SND_SOC_DAPM_MUX("STR", SND_SOC_NOPM, 0, 0, &str_mux),
-
-SND_SOC_DAPM_DAC("DACL", "Playback", WM8962_PWR_MGMT_2, 8, 0),
-SND_SOC_DAPM_DAC("DACR", "Playback", WM8962_PWR_MGMT_2, 7, 0),
-
-SND_SOC_DAPM_PGA("Left Bypass", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right Bypass", SND_SOC_NOPM, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_MIXER("HPMIXL", WM8962_MIXER_ENABLES, 3, 0,
- hpmixl, ARRAY_SIZE(hpmixl)),
-SND_SOC_DAPM_MIXER("HPMIXR", WM8962_MIXER_ENABLES, 2, 0,
- hpmixr, ARRAY_SIZE(hpmixr)),
-
-SND_SOC_DAPM_MUX_E("HPOUTL PGA", WM8962_PWR_MGMT_2, 6, 0, &hpoutl_mux,
- out_pga_event, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_MUX_E("HPOUTR PGA", WM8962_PWR_MGMT_2, 5, 0, &hpoutr_mux,
- out_pga_event, SND_SOC_DAPM_POST_PMU),
-
-SND_SOC_DAPM_PGA_E("HPOUT", SND_SOC_NOPM, 0, 0, NULL, 0, hp_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-
-SND_SOC_DAPM_OUTPUT("HPOUTL"),
-SND_SOC_DAPM_OUTPUT("HPOUTR"),
-};
-
-static const struct snd_soc_dapm_widget wm8962_dapm_spk_mono_widgets[] = {
-SND_SOC_DAPM_MIXER("Speaker Mixer", WM8962_MIXER_ENABLES, 1, 0,
- spkmixl, ARRAY_SIZE(spkmixl)),
-SND_SOC_DAPM_MUX_E("Speaker PGA", WM8962_PWR_MGMT_2, 4, 0, &spkoutl_mux,
- out_pga_event, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA("Speaker Output", WM8962_CLASS_D_CONTROL_1, 7, 0, NULL, 0),
-SND_SOC_DAPM_OUTPUT("SPKOUT"),
-};
-
-static const struct snd_soc_dapm_widget wm8962_dapm_spk_stereo_widgets[] = {
-SND_SOC_DAPM_MIXER("SPKOUTL Mixer", WM8962_MIXER_ENABLES, 1, 0,
- spkmixl, ARRAY_SIZE(spkmixl)),
-SND_SOC_DAPM_MIXER("SPKOUTR Mixer", WM8962_MIXER_ENABLES, 0, 0,
- spkmixr, ARRAY_SIZE(spkmixr)),
-
-SND_SOC_DAPM_MUX_E("SPKOUTL PGA", WM8962_PWR_MGMT_2, 4, 0, &spkoutl_mux,
- out_pga_event, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_MUX_E("SPKOUTR PGA", WM8962_PWR_MGMT_2, 3, 0, &spkoutr_mux,
- out_pga_event, SND_SOC_DAPM_POST_PMU),
-
-SND_SOC_DAPM_PGA("SPKOUTR Output", WM8962_CLASS_D_CONTROL_1, 7, 0, NULL, 0),
-SND_SOC_DAPM_PGA("SPKOUTL Output", WM8962_CLASS_D_CONTROL_1, 6, 0, NULL, 0),
-
-SND_SOC_DAPM_OUTPUT("SPKOUTL"),
-SND_SOC_DAPM_OUTPUT("SPKOUTR"),
-};
-
-static const struct snd_soc_dapm_route wm8962_intercon[] = {
- { "INPGAL", "IN1L Switch", "IN1L" },
- { "INPGAL", "IN2L Switch", "IN2L" },
- { "INPGAL", "IN3L Switch", "IN3L" },
- { "INPGAL", "IN4L Switch", "IN4L" },
-
- { "INPGAR", "IN1R Switch", "IN1R" },
- { "INPGAR", "IN2R Switch", "IN2R" },
- { "INPGAR", "IN3R Switch", "IN3R" },
- { "INPGAR", "IN4R Switch", "IN4R" },
-
- { "MIXINL", "IN2L Switch", "IN2L" },
- { "MIXINL", "IN3L Switch", "IN3L" },
- { "MIXINL", "PGA Switch", "INPGAL" },
-
- { "MIXINR", "IN2R Switch", "IN2R" },
- { "MIXINR", "IN3R Switch", "IN3R" },
- { "MIXINR", "PGA Switch", "INPGAR" },
-
- { "MICBIAS", NULL, "SYSCLK" },
-
- { "DMIC_ENA", NULL, "DMICDAT" },
-
- { "ADCL", NULL, "SYSCLK" },
- { "ADCL", NULL, "TOCLK" },
- { "ADCL", NULL, "MIXINL" },
- { "ADCL", NULL, "DMIC_ENA" },
- { "ADCL", NULL, "DSP2" },
-
- { "ADCR", NULL, "SYSCLK" },
- { "ADCR", NULL, "TOCLK" },
- { "ADCR", NULL, "MIXINR" },
- { "ADCR", NULL, "DMIC_ENA" },
- { "ADCR", NULL, "DSP2" },
-
- { "STL", "Left", "ADCL" },
- { "STL", "Right", "ADCR" },
- { "STL", NULL, "Class G" },
-
- { "STR", "Left", "ADCL" },
- { "STR", "Right", "ADCR" },
- { "STR", NULL, "Class G" },
-
- { "DACL", NULL, "SYSCLK" },
- { "DACL", NULL, "TOCLK" },
- { "DACL", NULL, "Beep" },
- { "DACL", NULL, "STL" },
- { "DACL", NULL, "DSP2" },
-
- { "DACR", NULL, "SYSCLK" },
- { "DACR", NULL, "TOCLK" },
- { "DACR", NULL, "Beep" },
- { "DACR", NULL, "STR" },
- { "DACR", NULL, "DSP2" },
-
- { "HPMIXL", "IN4L Switch", "IN4L" },
- { "HPMIXL", "IN4R Switch", "IN4R" },
- { "HPMIXL", "DACL Switch", "DACL" },
- { "HPMIXL", "DACR Switch", "DACR" },
- { "HPMIXL", "MIXINL Switch", "MIXINL" },
- { "HPMIXL", "MIXINR Switch", "MIXINR" },
-
- { "HPMIXR", "IN4L Switch", "IN4L" },
- { "HPMIXR", "IN4R Switch", "IN4R" },
- { "HPMIXR", "DACL Switch", "DACL" },
- { "HPMIXR", "DACR Switch", "DACR" },
- { "HPMIXR", "MIXINL Switch", "MIXINL" },
- { "HPMIXR", "MIXINR Switch", "MIXINR" },
-
- { "Left Bypass", NULL, "HPMIXL" },
- { "Left Bypass", NULL, "Class G" },
-
- { "Right Bypass", NULL, "HPMIXR" },
- { "Right Bypass", NULL, "Class G" },
-
- { "HPOUTL PGA", "Mixer", "Left Bypass" },
- { "HPOUTL PGA", "DAC", "DACL" },
-
- { "HPOUTR PGA", "Mixer", "Right Bypass" },
- { "HPOUTR PGA", "DAC", "DACR" },
-
- { "HPOUT", NULL, "HPOUTL PGA" },
- { "HPOUT", NULL, "HPOUTR PGA" },
- { "HPOUT", NULL, "Charge Pump" },
- { "HPOUT", NULL, "SYSCLK" },
- { "HPOUT", NULL, "TOCLK" },
-
- { "HPOUTL", NULL, "HPOUT" },
- { "HPOUTR", NULL, "HPOUT" },
-
- { "HPOUTL", NULL, "TEMP_HP" },
- { "HPOUTR", NULL, "TEMP_HP" },
-};
-
-static const struct snd_soc_dapm_route wm8962_spk_mono_intercon[] = {
- { "Speaker Mixer", "IN4L Switch", "IN4L" },
- { "Speaker Mixer", "IN4R Switch", "IN4R" },
- { "Speaker Mixer", "DACL Switch", "DACL" },
- { "Speaker Mixer", "DACR Switch", "DACR" },
- { "Speaker Mixer", "MIXINL Switch", "MIXINL" },
- { "Speaker Mixer", "MIXINR Switch", "MIXINR" },
-
- { "Speaker PGA", "Mixer", "Speaker Mixer" },
- { "Speaker PGA", "DAC", "DACL" },
-
- { "Speaker Output", NULL, "Speaker PGA" },
- { "Speaker Output", NULL, "SYSCLK" },
- { "Speaker Output", NULL, "TOCLK" },
- { "Speaker Output", NULL, "TEMP_SPK" },
-
- { "SPKOUT", NULL, "Speaker Output" },
-};
-
-static const struct snd_soc_dapm_route wm8962_spk_stereo_intercon[] = {
- { "SPKOUTL Mixer", "IN4L Switch", "IN4L" },
- { "SPKOUTL Mixer", "IN4R Switch", "IN4R" },
- { "SPKOUTL Mixer", "DACL Switch", "DACL" },
- { "SPKOUTL Mixer", "DACR Switch", "DACR" },
- { "SPKOUTL Mixer", "MIXINL Switch", "MIXINL" },
- { "SPKOUTL Mixer", "MIXINR Switch", "MIXINR" },
-
- { "SPKOUTR Mixer", "IN4L Switch", "IN4L" },
- { "SPKOUTR Mixer", "IN4R Switch", "IN4R" },
- { "SPKOUTR Mixer", "DACL Switch", "DACL" },
- { "SPKOUTR Mixer", "DACR Switch", "DACR" },
- { "SPKOUTR Mixer", "MIXINL Switch", "MIXINL" },
- { "SPKOUTR Mixer", "MIXINR Switch", "MIXINR" },
-
- { "SPKOUTL PGA", "Mixer", "SPKOUTL Mixer" },
- { "SPKOUTL PGA", "DAC", "DACL" },
-
- { "SPKOUTR PGA", "Mixer", "SPKOUTR Mixer" },
- { "SPKOUTR PGA", "DAC", "DACR" },
-
- { "SPKOUTL Output", NULL, "SPKOUTL PGA" },
- { "SPKOUTL Output", NULL, "SYSCLK" },
- { "SPKOUTL Output", NULL, "TOCLK" },
- { "SPKOUTL Output", NULL, "TEMP_SPK" },
-
- { "SPKOUTR Output", NULL, "SPKOUTR PGA" },
- { "SPKOUTR Output", NULL, "SYSCLK" },
- { "SPKOUTR Output", NULL, "TOCLK" },
- { "SPKOUTR Output", NULL, "TEMP_SPK" },
-
- { "SPKOUTL", NULL, "SPKOUTL Output" },
- { "SPKOUTR", NULL, "SPKOUTR Output" },
-};
-
-static int wm8962_add_widgets(struct snd_soc_codec *codec)
-{
- struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_add_codec_controls(codec, wm8962_snd_controls,
- ARRAY_SIZE(wm8962_snd_controls));
- if (pdata && pdata->spk_mono)
- snd_soc_add_codec_controls(codec, wm8962_spk_mono_controls,
- ARRAY_SIZE(wm8962_spk_mono_controls));
- else
- snd_soc_add_codec_controls(codec, wm8962_spk_stereo_controls,
- ARRAY_SIZE(wm8962_spk_stereo_controls));
-
-
- snd_soc_dapm_new_controls(dapm, wm8962_dapm_widgets,
- ARRAY_SIZE(wm8962_dapm_widgets));
- if (pdata && pdata->spk_mono)
- snd_soc_dapm_new_controls(dapm, wm8962_dapm_spk_mono_widgets,
- ARRAY_SIZE(wm8962_dapm_spk_mono_widgets));
- else
- snd_soc_dapm_new_controls(dapm, wm8962_dapm_spk_stereo_widgets,
- ARRAY_SIZE(wm8962_dapm_spk_stereo_widgets));
-
- snd_soc_dapm_add_routes(dapm, wm8962_intercon,
- ARRAY_SIZE(wm8962_intercon));
- if (pdata && pdata->spk_mono)
- snd_soc_dapm_add_routes(dapm, wm8962_spk_mono_intercon,
- ARRAY_SIZE(wm8962_spk_mono_intercon));
- else
- snd_soc_dapm_add_routes(dapm, wm8962_spk_stereo_intercon,
- ARRAY_SIZE(wm8962_spk_stereo_intercon));
-
-
- snd_soc_dapm_disable_pin(dapm, "Beep");
-
- return 0;
-}
-
-/* -1 for reserved values */
-static const int bclk_divs[] = {
- 1, -1, 2, 3, 4, -1, 6, 8, -1, 12, 16, 24, -1, 32, 32, 32
-};
-
-static const int sysclk_rates[] = {
- 64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536, 3072, 6144
-};
-
-static void wm8962_configure_bclk(struct snd_soc_codec *codec)
-{
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
- int dspclk, i;
- int clocking2 = 0;
- int clocking4 = 0;
- int aif2 = 0;
-
- if (!wm8962->sysclk_rate) {
- dev_dbg(codec->dev, "No SYSCLK configured\n");
- return;
- }
-
- if (!wm8962->bclk || !wm8962->lrclk) {
- dev_dbg(codec->dev, "No audio clocks configured\n");
- return;
- }
-
- for (i = 0; i < ARRAY_SIZE(sysclk_rates); i++) {
- if (sysclk_rates[i] == wm8962->sysclk_rate / wm8962->lrclk) {
- clocking4 |= i << WM8962_SYSCLK_RATE_SHIFT;
- break;
- }
- }
-
- if (i == ARRAY_SIZE(sysclk_rates)) {
- dev_err(codec->dev, "Unsupported sysclk ratio %d\n",
- wm8962->sysclk_rate / wm8962->lrclk);
- return;
- }
-
- dev_dbg(codec->dev, "Selected sysclk ratio %d\n", sysclk_rates[i]);
-
- snd_soc_update_bits(codec, WM8962_CLOCKING_4,
- WM8962_SYSCLK_RATE_MASK, clocking4);
-
- dspclk = snd_soc_read(codec, WM8962_CLOCKING1);
- if (dspclk < 0) {
- dev_err(codec->dev, "Failed to read DSPCLK: %d\n", dspclk);
- return;
- }
-
- dspclk = (dspclk & WM8962_DSPCLK_DIV_MASK) >> WM8962_DSPCLK_DIV_SHIFT;
- switch (dspclk) {
- case 0:
- dspclk = wm8962->sysclk_rate;
- break;
- case 1:
- dspclk = wm8962->sysclk_rate / 2;
- break;
- case 2:
- dspclk = wm8962->sysclk_rate / 4;
- break;
- default:
- dev_warn(codec->dev, "Unknown DSPCLK divisor read back\n");
- dspclk = wm8962->sysclk;
- }
-
- dev_dbg(codec->dev, "DSPCLK is %dHz, BCLK %d\n", dspclk, wm8962->bclk);
-
- /* We're expecting an exact match */
- for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
- if (bclk_divs[i] < 0)
- continue;
-
- if (dspclk / bclk_divs[i] == wm8962->bclk) {
- dev_dbg(codec->dev, "Selected BCLK_DIV %d for %dHz\n",
- bclk_divs[i], wm8962->bclk);
- clocking2 |= i;
- break;
- }
- }
- if (i == ARRAY_SIZE(bclk_divs)) {
- dev_err(codec->dev, "Unsupported BCLK ratio %d\n",
- dspclk / wm8962->bclk);
- return;
- }
-
- aif2 |= wm8962->bclk / wm8962->lrclk;
- dev_dbg(codec->dev, "Selected LRCLK divisor %d for %dHz\n",
- wm8962->bclk / wm8962->lrclk, wm8962->lrclk);
-
- snd_soc_update_bits(codec, WM8962_CLOCKING2,
- WM8962_BCLK_DIV_MASK, clocking2);
- snd_soc_update_bits(codec, WM8962_AUDIO_INTERFACE_2,
- WM8962_AIF_RATE_MASK, aif2);
-}
-
-static int wm8962_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- if (level == codec->dapm.bias_level)
- return 0;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- /* VMID 2*50k */
- snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
- WM8962_VMID_SEL_MASK, 0x80);
-
- wm8962_configure_bclk(codec);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- /* VMID 2*250k */
- snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
- WM8962_VMID_SEL_MASK, 0x100);
- break;
-
- case SND_SOC_BIAS_OFF:
- break;
- }
-
- codec->dapm.bias_level = level;
- return 0;
-}
-
-static const struct {
- int rate;
- int reg;
-} sr_vals[] = {
- { 48000, 0 },
- { 44100, 0 },
- { 32000, 1 },
- { 22050, 2 },
- { 24000, 2 },
- { 16000, 3 },
- { 11025, 4 },
- { 12000, 4 },
- { 8000, 5 },
- { 88200, 6 },
- { 96000, 6 },
-};
-
-static int wm8962_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
- int i;
- int aif0 = 0;
- int adctl3 = 0;
-
- wm8962->bclk = snd_soc_params_to_bclk(params);
- if (params_channels(params) == 1)
- wm8962->bclk *= 2;
-
- wm8962->lrclk = params_rate(params);
-
- for (i = 0; i < ARRAY_SIZE(sr_vals); i++) {
- if (sr_vals[i].rate == wm8962->lrclk) {
- adctl3 |= sr_vals[i].reg;
- break;
- }
- }
- if (i == ARRAY_SIZE(sr_vals)) {
- dev_err(codec->dev, "Unsupported rate %dHz\n", wm8962->lrclk);
- return -EINVAL;
- }
-
- if (wm8962->lrclk % 8000 == 0)
- adctl3 |= WM8962_SAMPLE_RATE_INT_MODE;
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- aif0 |= 0x4;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- aif0 |= 0x8;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- aif0 |= 0xc;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, WM8962_AUDIO_INTERFACE_0,
- WM8962_WL_MASK, aif0);
- snd_soc_update_bits(codec, WM8962_ADDITIONAL_CONTROL_3,
- WM8962_SAMPLE_RATE_INT_MODE |
- WM8962_SAMPLE_RATE_MASK, adctl3);
-
- if (codec->dapm.bias_level == SND_SOC_BIAS_ON)
- wm8962_configure_bclk(codec);
-
- return 0;
-}
-
-static int wm8962_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
- unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
- int src;
-
- switch (clk_id) {
- case WM8962_SYSCLK_MCLK:
- wm8962->sysclk = WM8962_SYSCLK_MCLK;
- src = 0;
- break;
- case WM8962_SYSCLK_FLL:
- wm8962->sysclk = WM8962_SYSCLK_FLL;
- src = 1 << WM8962_SYSCLK_SRC_SHIFT;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, WM8962_CLOCKING2, WM8962_SYSCLK_SRC_MASK,
- src);
-
- wm8962->sysclk_rate = freq;
-
- wm8962_configure_bclk(codec);
-
- return 0;
-}
-
-static int wm8962_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = dai->codec;
- int aif0 = 0;
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_B:
- aif0 |= WM8962_LRCLK_INV | 3;
- case SND_SOC_DAIFMT_DSP_A:
- aif0 |= 3;
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- case SND_SOC_DAIFMT_IB_NF:
- break;
- default:
- return -EINVAL;
- }
- break;
-
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- aif0 |= 1;
- break;
- case SND_SOC_DAIFMT_I2S:
- aif0 |= 2;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_NF:
- aif0 |= WM8962_BCLK_INV;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- aif0 |= WM8962_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_IB_IF:
- aif0 |= WM8962_BCLK_INV | WM8962_LRCLK_INV;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- aif0 |= WM8962_MSTR;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, WM8962_AUDIO_INTERFACE_0,
- WM8962_FMT_MASK | WM8962_BCLK_INV | WM8962_MSTR |
- WM8962_LRCLK_INV, aif0);
-
- return 0;
-}
-
-struct _fll_div {
- u16 fll_fratio;
- u16 fll_outdiv;
- u16 fll_refclk_div;
- u16 n;
- u16 theta;
- u16 lambda;
-};
-
-/* The size in bits of the FLL divide multiplied by 10
- * to allow rounding later */
-#define FIXED_FLL_SIZE ((1 << 16) * 10)
-
-static struct {
- unsigned int min;
- unsigned int max;
- u16 fll_fratio;
- int ratio;
-} fll_fratios[] = {
- { 0, 64000, 4, 16 },
- { 64000, 128000, 3, 8 },
- { 128000, 256000, 2, 4 },
- { 256000, 1000000, 1, 2 },
- { 1000000, 13500000, 0, 1 },
-};
-
-static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
- unsigned int Fout)
-{
- unsigned int target;
- unsigned int div;
- unsigned int fratio, gcd_fll;
- int i;
-
- /* Fref must be <=13.5MHz */
- div = 1;
- fll_div->fll_refclk_div = 0;
- while ((Fref / div) > 13500000) {
- div *= 2;
- fll_div->fll_refclk_div++;
-
- if (div > 4) {
- pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
- Fref);
- return -EINVAL;
- }
- }
-
- pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
-
- /* Apply the division for our remaining calculations */
- Fref /= div;
-
- /* Fvco should be 90-100MHz; don't check the upper bound */
- div = 2;
- while (Fout * div < 90000000) {
- div++;
- if (div > 64) {
- pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
- Fout);
- return -EINVAL;
- }
- }
- target = Fout * div;
- fll_div->fll_outdiv = div - 1;
-
- pr_debug("FLL Fvco=%dHz\n", target);
-
- /* Find an appropriate FLL_FRATIO and factor it out of the target */
- for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
- if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
- fll_div->fll_fratio = fll_fratios[i].fll_fratio;
- fratio = fll_fratios[i].ratio;
- break;
- }
- }
- if (i == ARRAY_SIZE(fll_fratios)) {
- pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
- return -EINVAL;
- }
-
- fll_div->n = target / (fratio * Fref);
-
- if (target % Fref == 0) {
- fll_div->theta = 0;
- fll_div->lambda = 0;
- } else {
- gcd_fll = gcd(target, fratio * Fref);
-
- fll_div->theta = (target - (fll_div->n * fratio * Fref))
- / gcd_fll;
- fll_div->lambda = (fratio * Fref) / gcd_fll;
- }
-
- pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
- fll_div->n, fll_div->theta, fll_div->lambda);
- pr_debug("FLL_FRATIO=%x FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
- fll_div->fll_fratio, fll_div->fll_outdiv,
- fll_div->fll_refclk_div);
-
- return 0;
-}
-
-static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
- unsigned int Fref, unsigned int Fout)
-{
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
- struct _fll_div fll_div;
- unsigned long timeout;
- int ret;
- int fll1 = 0;
-
- /* Any change? */
- if (source == wm8962->fll_src && Fref == wm8962->fll_fref &&
- Fout == wm8962->fll_fout)
- return 0;
-
- if (Fout == 0) {
- dev_dbg(codec->dev, "FLL disabled\n");
-
- wm8962->fll_fref = 0;
- wm8962->fll_fout = 0;
-
- snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
- WM8962_FLL_ENA, 0);
-
- pm_runtime_put(codec->dev);
-
- return 0;
- }
-
- ret = fll_factors(&fll_div, Fref, Fout);
- if (ret != 0)
- return ret;
-
- /* Parameters good, disable so we can reprogram */
- snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, 0);
-
- switch (fll_id) {
- case WM8962_FLL_MCLK:
- case WM8962_FLL_BCLK:
- case WM8962_FLL_OSC:
- fll1 |= (fll_id - 1) << WM8962_FLL_REFCLK_SRC_SHIFT;
- break;
- case WM8962_FLL_INT:
- snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
- WM8962_FLL_OSC_ENA, WM8962_FLL_OSC_ENA);
- snd_soc_update_bits(codec, WM8962_FLL_CONTROL_5,
- WM8962_FLL_FRC_NCO, WM8962_FLL_FRC_NCO);
- break;
- default:
- dev_err(codec->dev, "Unknown FLL source %d\n", ret);
- return -EINVAL;
- }
-
- if (fll_div.theta || fll_div.lambda)
- fll1 |= WM8962_FLL_FRAC;
-
- /* Stop the FLL while we reconfigure */
- snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, 0);
-
- snd_soc_update_bits(codec, WM8962_FLL_CONTROL_2,
- WM8962_FLL_OUTDIV_MASK |
- WM8962_FLL_REFCLK_DIV_MASK,
- (fll_div.fll_outdiv << WM8962_FLL_OUTDIV_SHIFT) |
- (fll_div.fll_refclk_div));
-
- snd_soc_update_bits(codec, WM8962_FLL_CONTROL_3,
- WM8962_FLL_FRATIO_MASK, fll_div.fll_fratio);
-
- snd_soc_write(codec, WM8962_FLL_CONTROL_6, fll_div.theta);
- snd_soc_write(codec, WM8962_FLL_CONTROL_7, fll_div.lambda);
- snd_soc_write(codec, WM8962_FLL_CONTROL_8, fll_div.n);
-
- try_wait_for_completion(&wm8962->fll_lock);
-
- pm_runtime_get_sync(codec->dev);
-
- snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
- WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK |
- WM8962_FLL_ENA, fll1 | WM8962_FLL_ENA);
-
- dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
-
- ret = 0;
-
- if (fll1 & WM8962_FLL_ENA) {
- /* This should be a massive overestimate but go even
- * higher if we'll error out
- */
- if (wm8962->irq)
- timeout = msecs_to_jiffies(5);
- else
- timeout = msecs_to_jiffies(1);
-
- timeout = wait_for_completion_timeout(&wm8962->fll_lock,
- timeout);
-
- if (timeout == 0 && wm8962->irq) {
- dev_err(codec->dev, "FLL lock timed out");
- ret = -ETIMEDOUT;
- }
- }
-
- wm8962->fll_fref = Fref;
- wm8962->fll_fout = Fout;
- wm8962->fll_src = source;
-
- return ret;
-}
-
-static int wm8962_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- int val;
-
- if (mute)
- val = WM8962_DAC_MUTE;
- else
- val = 0;
-
- return snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1,
- WM8962_DAC_MUTE, val);
-}
-
-#define WM8962_RATES SNDRV_PCM_RATE_8000_96000
-
-#define WM8962_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops wm8962_dai_ops = {
- .hw_params = wm8962_hw_params,
- .set_sysclk = wm8962_set_dai_sysclk,
- .set_fmt = wm8962_set_dai_fmt,
- .digital_mute = wm8962_mute,
-};
-
-static struct snd_soc_dai_driver wm8962_dai = {
- .name = "wm8962",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8962_RATES,
- .formats = WM8962_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8962_RATES,
- .formats = WM8962_FORMATS,
- },
- .ops = &wm8962_dai_ops,
- .symmetric_rates = 1,
-};
-
-static void wm8962_mic_work(struct work_struct *work)
-{
- struct wm8962_priv *wm8962 = container_of(work,
- struct wm8962_priv,
- mic_work.work);
- struct snd_soc_codec *codec = wm8962->codec;
- int status = 0;
- int irq_pol = 0;
- int reg;
-
- reg = snd_soc_read(codec, WM8962_ADDITIONAL_CONTROL_4);
-
- if (reg & WM8962_MICDET_STS) {
- status |= SND_JACK_MICROPHONE;
- irq_pol |= WM8962_MICD_IRQ_POL;
- }
-
- if (reg & WM8962_MICSHORT_STS) {
- status |= SND_JACK_BTN_0;
- irq_pol |= WM8962_MICSCD_IRQ_POL;
- }
-
- snd_soc_jack_report(wm8962->jack, status,
- SND_JACK_MICROPHONE | SND_JACK_BTN_0);
-
- snd_soc_update_bits(codec, WM8962_MICINT_SOURCE_POL,
- WM8962_MICSCD_IRQ_POL |
- WM8962_MICD_IRQ_POL, irq_pol);
-}
-
-static irqreturn_t wm8962_irq(int irq, void *data)
-{
- struct device *dev = data;
- struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
- unsigned int mask;
- unsigned int active;
- int reg, ret;
-
- ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2_MASK,
- &mask);
- if (ret != 0) {
- dev_err(dev, "Failed to read interrupt mask: %d\n",
- ret);
- return IRQ_NONE;
- }
-
- ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, &active);
- if (ret != 0) {
- dev_err(dev, "Failed to read interrupt: %d\n", ret);
- return IRQ_NONE;
- }
-
- active &= ~mask;
-
- if (!active)
- return IRQ_NONE;
-
- /* Acknowledge the interrupts */
- ret = regmap_write(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, active);
- if (ret != 0)
- dev_warn(dev, "Failed to ack interrupt: %d\n", ret);
-
- if (active & WM8962_FLL_LOCK_EINT) {
- dev_dbg(dev, "FLL locked\n");
- complete(&wm8962->fll_lock);
- }
-
- if (active & WM8962_FIFOS_ERR_EINT)
- dev_err(dev, "FIFO error\n");
-
- if (active & WM8962_TEMP_SHUT_EINT) {
- dev_crit(dev, "Thermal shutdown\n");
-
- ret = regmap_read(wm8962->regmap,
- WM8962_THERMAL_SHUTDOWN_STATUS, &reg);
- if (ret != 0) {
- dev_warn(dev, "Failed to read thermal status: %d\n",
- ret);
- reg = 0;
- }
-
- if (reg & WM8962_TEMP_ERR_HP)
- dev_crit(dev, "Headphone thermal error\n");
- if (reg & WM8962_TEMP_WARN_HP)
- dev_crit(dev, "Headphone thermal warning\n");
- if (reg & WM8962_TEMP_ERR_SPK)
- dev_crit(dev, "Speaker thermal error\n");
- if (reg & WM8962_TEMP_WARN_SPK)
- dev_crit(dev, "Speaker thermal warning\n");
- }
-
- if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) {
- dev_dbg(dev, "Microphone event detected\n");
-
-#ifndef CONFIG_SND_SOC_WM8962_MODULE
- trace_snd_soc_jack_irq(dev_name(dev));
-#endif
-
- pm_wakeup_event(dev, 300);
-
- schedule_delayed_work(&wm8962->mic_work,
- msecs_to_jiffies(250));
- }
-
- return IRQ_HANDLED;
-}
-
-/**
- * wm8962_mic_detect - Enable microphone detection via the WM8962 IRQ
- *
- * @codec: WM8962 codec
- * @jack: jack to report detection events on
- *
- * Enable microphone detection via IRQ on the WM8962. If GPIOs are
- * being used to bring out signals to the processor then only platform
- * data configuration is needed for WM8962 and processor GPIOs should
- * be configured using snd_soc_jack_add_gpios() instead.
- *
- * If no jack is supplied detection will be disabled.
- */
-int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
-{
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
- int irq_mask, enable;
-
- wm8962->jack = jack;
- if (jack) {
- irq_mask = 0;
- enable = WM8962_MICDET_ENA;
- } else {
- irq_mask = WM8962_MICD_EINT | WM8962_MICSCD_EINT;
- enable = 0;
- }
-
- snd_soc_update_bits(codec, WM8962_INTERRUPT_STATUS_2_MASK,
- WM8962_MICD_EINT | WM8962_MICSCD_EINT, irq_mask);
- snd_soc_update_bits(codec, WM8962_ADDITIONAL_CONTROL_4,
- WM8962_MICDET_ENA, enable);
-
- /* Send an initial empty report */
- snd_soc_jack_report(wm8962->jack, 0,
- SND_JACK_MICROPHONE | SND_JACK_BTN_0);
-
- if (jack) {
- snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK");
- snd_soc_dapm_force_enable_pin(&codec->dapm, "MICBIAS");
- } else {
- snd_soc_dapm_disable_pin(&codec->dapm, "SYSCLK");
- snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS");
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(wm8962_mic_detect);
-
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
-static int beep_rates[] = {
- 500, 1000, 2000, 4000,
-};
-
-static void wm8962_beep_work(struct work_struct *work)
-{
- struct wm8962_priv *wm8962 =
- container_of(work, struct wm8962_priv, beep_work);
- struct snd_soc_codec *codec = wm8962->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int i;
- int reg = 0;
- int best = 0;
-
- if (wm8962->beep_rate) {
- for (i = 0; i < ARRAY_SIZE(beep_rates); i++) {
- if (abs(wm8962->beep_rate - beep_rates[i]) <
- abs(wm8962->beep_rate - beep_rates[best]))
- best = i;
- }
-
- dev_dbg(codec->dev, "Set beep rate %dHz for requested %dHz\n",
- beep_rates[best], wm8962->beep_rate);
-
- reg = WM8962_BEEP_ENA | (best << WM8962_BEEP_RATE_SHIFT);
-
- snd_soc_dapm_enable_pin(dapm, "Beep");
- } else {
- dev_dbg(codec->dev, "Disabling beep\n");
- snd_soc_dapm_disable_pin(dapm, "Beep");
- }
-
- snd_soc_update_bits(codec, WM8962_BEEP_GENERATOR_1,
- WM8962_BEEP_ENA | WM8962_BEEP_RATE_MASK, reg);
-
- snd_soc_dapm_sync(dapm);
-}
-
-/* For usability define a way of injecting beep events for the device -
- * many systems will not have a keyboard.
- */
-static int wm8962_beep_event(struct input_dev *dev, unsigned int type,
- unsigned int code, int hz)
-{
- struct snd_soc_codec *codec = input_get_drvdata(dev);
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
-
- dev_dbg(codec->dev, "Beep event %x %x\n", code, hz);
-
- switch (code) {
- case SND_BELL:
- if (hz)
- hz = 1000;
- case SND_TONE:
- break;
- default:
- return -1;
- }
-
- /* Kick the beep from a workqueue */
- wm8962->beep_rate = hz;
- schedule_work(&wm8962->beep_work);
- return 0;
-}
-
-static ssize_t wm8962_beep_set(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
- long int time;
- int ret;
-
- ret = strict_strtol(buf, 10, &time);
- if (ret != 0)
- return ret;
-
- input_event(wm8962->beep, EV_SND, SND_TONE, time);
-
- return count;
-}
-
-static DEVICE_ATTR(beep, 0200, NULL, wm8962_beep_set);
-
-static void wm8962_init_beep(struct snd_soc_codec *codec)
-{
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- wm8962->beep = input_allocate_device();
- if (!wm8962->beep) {
- dev_err(codec->dev, "Failed to allocate beep device\n");
- return;
- }
-
- INIT_WORK(&wm8962->beep_work, wm8962_beep_work);
- wm8962->beep_rate = 0;
-
- wm8962->beep->name = "WM8962 Beep Generator";
- wm8962->beep->phys = dev_name(codec->dev);
- wm8962->beep->id.bustype = BUS_I2C;
-
- wm8962->beep->evbit[0] = BIT_MASK(EV_SND);
- wm8962->beep->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
- wm8962->beep->event = wm8962_beep_event;
- wm8962->beep->dev.parent = codec->dev;
- input_set_drvdata(wm8962->beep, codec);
-
- ret = input_register_device(wm8962->beep);
- if (ret != 0) {
- input_free_device(wm8962->beep);
- wm8962->beep = NULL;
- dev_err(codec->dev, "Failed to register beep device\n");
- }
-
- ret = device_create_file(codec->dev, &dev_attr_beep);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to create keyclick file: %d\n",
- ret);
- }
-}
-
-static void wm8962_free_beep(struct snd_soc_codec *codec)
-{
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
-
- device_remove_file(codec->dev, &dev_attr_beep);
- input_unregister_device(wm8962->beep);
- cancel_work_sync(&wm8962->beep_work);
- wm8962->beep = NULL;
-
- snd_soc_update_bits(codec, WM8962_BEEP_GENERATOR_1, WM8962_BEEP_ENA,0);
-}
-#else
-static void wm8962_init_beep(struct snd_soc_codec *codec)
-{
-}
-
-static void wm8962_free_beep(struct snd_soc_codec *codec)
-{
-}
-#endif
-
-static void wm8962_set_gpio_mode(struct snd_soc_codec *codec, int gpio)
-{
- int mask = 0;
- int val = 0;
-
- /* Some of the GPIOs are behind MFP configuration and need to
- * be put into GPIO mode. */
- switch (gpio) {
- case 2:
- mask = WM8962_CLKOUT2_SEL_MASK;
- val = 1 << WM8962_CLKOUT2_SEL_SHIFT;
- break;
- case 3:
- mask = WM8962_CLKOUT3_SEL_MASK;
- val = 1 << WM8962_CLKOUT3_SEL_SHIFT;
- break;
- default:
- break;
- }
-
- if (mask)
- snd_soc_update_bits(codec, WM8962_ANALOGUE_CLOCKING1,
- mask, val);
-}
-
-#ifdef CONFIG_GPIOLIB
-static inline struct wm8962_priv *gpio_to_wm8962(struct gpio_chip *chip)
-{
- return container_of(chip, struct wm8962_priv, gpio_chip);
-}
-
-static int wm8962_gpio_request(struct gpio_chip *chip, unsigned offset)
-{
- struct wm8962_priv *wm8962 = gpio_to_wm8962(chip);
- struct snd_soc_codec *codec = wm8962->codec;
-
- /* The WM8962 GPIOs aren't linearly numbered. For simplicity
- * we export linear numbers and error out if the unsupported
- * ones are requsted.
- */
- switch (offset + 1) {
- case 2:
- case 3:
- case 5:
- case 6:
- break;
- default:
- return -EINVAL;
- }
-
- wm8962_set_gpio_mode(codec, offset + 1);
-
- return 0;
-}
-
-static void wm8962_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-{
- struct wm8962_priv *wm8962 = gpio_to_wm8962(chip);
- struct snd_soc_codec *codec = wm8962->codec;
-
- snd_soc_update_bits(codec, WM8962_GPIO_BASE + offset,
- WM8962_GP2_LVL, !!value << WM8962_GP2_LVL_SHIFT);
-}
-
-static int wm8962_gpio_direction_out(struct gpio_chip *chip,
- unsigned offset, int value)
-{
- struct wm8962_priv *wm8962 = gpio_to_wm8962(chip);
- struct snd_soc_codec *codec = wm8962->codec;
- int ret, val;
-
- /* Force function 1 (logic output) */
- val = (1 << WM8962_GP2_FN_SHIFT) | (value << WM8962_GP2_LVL_SHIFT);
-
- ret = snd_soc_update_bits(codec, WM8962_GPIO_BASE + offset,
- WM8962_GP2_FN_MASK | WM8962_GP2_LVL, val);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct gpio_chip wm8962_template_chip = {
- .label = "wm8962",
- .owner = THIS_MODULE,
- .request = wm8962_gpio_request,
- .direction_output = wm8962_gpio_direction_out,
- .set = wm8962_gpio_set,
- .can_sleep = 1,
-};
-
-static void wm8962_init_gpio(struct snd_soc_codec *codec)
-{
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
- struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
- int ret;
-
- wm8962->gpio_chip = wm8962_template_chip;
- wm8962->gpio_chip.ngpio = WM8962_MAX_GPIO;
- wm8962->gpio_chip.dev = codec->dev;
-
- if (pdata && pdata->gpio_base)
- wm8962->gpio_chip.base = pdata->gpio_base;
- else
- wm8962->gpio_chip.base = -1;
-
- ret = gpiochip_add(&wm8962->gpio_chip);
- if (ret != 0)
- dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
-}
-
-static void wm8962_free_gpio(struct snd_soc_codec *codec)
-{
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- ret = gpiochip_remove(&wm8962->gpio_chip);
- if (ret != 0)
- dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
-}
-#else
-static void wm8962_init_gpio(struct snd_soc_codec *codec)
-{
-}
-
-static void wm8962_free_gpio(struct snd_soc_codec *codec)
-{
-}
-#endif
-
-static int wm8962_probe(struct snd_soc_codec *codec)
-{
- int ret;
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
- struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
- u16 *reg_cache = codec->reg_cache;
- int i, trigger, irq_pol;
- bool dmicclk, dmicdat;
-
- wm8962->codec = codec;
- codec->control_data = wm8962->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- wm8962->disable_nb[0].notifier_call = wm8962_regulator_event_0;
- wm8962->disable_nb[1].notifier_call = wm8962_regulator_event_1;
- wm8962->disable_nb[2].notifier_call = wm8962_regulator_event_2;
- wm8962->disable_nb[3].notifier_call = wm8962_regulator_event_3;
- wm8962->disable_nb[4].notifier_call = wm8962_regulator_event_4;
- wm8962->disable_nb[5].notifier_call = wm8962_regulator_event_5;
- wm8962->disable_nb[6].notifier_call = wm8962_regulator_event_6;
- wm8962->disable_nb[7].notifier_call = wm8962_regulator_event_7;
-
- /* This should really be moved into the regulator core */
- for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) {
- ret = regulator_register_notifier(wm8962->supplies[i].consumer,
- &wm8962->disable_nb[i]);
- if (ret != 0) {
- dev_err(codec->dev,
- "Failed to register regulator notifier: %d\n",
- ret);
- }
- }
-
- /* SYSCLK defaults to on; make sure it is off so we can safely
- * write to registers if the device is declocked.
- */
- snd_soc_update_bits(codec, WM8962_CLOCKING2, WM8962_SYSCLK_ENA, 0);
-
- /* Ensure we have soft control over all registers */
- snd_soc_update_bits(codec, WM8962_CLOCKING2,
- WM8962_CLKREG_OVD, WM8962_CLKREG_OVD);
-
- /* Ensure that the oscillator and PLLs are disabled */
- snd_soc_update_bits(codec, WM8962_PLL2,
- WM8962_OSC_ENA | WM8962_PLL2_ENA | WM8962_PLL3_ENA,
- 0);
-
- if (pdata) {
- /* Apply static configuration for GPIOs */
- for (i = 0; i < ARRAY_SIZE(pdata->gpio_init); i++)
- if (pdata->gpio_init[i]) {
- wm8962_set_gpio_mode(codec, i + 1);
- snd_soc_write(codec, 0x200 + i,
- pdata->gpio_init[i] & 0xffff);
- }
-
- /* Put the speakers into mono mode? */
- if (pdata->spk_mono)
- reg_cache[WM8962_CLASS_D_CONTROL_2]
- |= WM8962_SPK_MONO;
-
- /* Micbias setup, detection enable and detection
- * threasholds. */
- if (pdata->mic_cfg)
- snd_soc_update_bits(codec, WM8962_ADDITIONAL_CONTROL_4,
- WM8962_MICDET_ENA |
- WM8962_MICDET_THR_MASK |
- WM8962_MICSHORT_THR_MASK |
- WM8962_MICBIAS_LVL,
- pdata->mic_cfg);
- }
-
- /* Latch volume update bits */
- snd_soc_update_bits(codec, WM8962_LEFT_INPUT_VOLUME,
- WM8962_IN_VU, WM8962_IN_VU);
- snd_soc_update_bits(codec, WM8962_RIGHT_INPUT_VOLUME,
- WM8962_IN_VU, WM8962_IN_VU);
- snd_soc_update_bits(codec, WM8962_LEFT_ADC_VOLUME,
- WM8962_ADC_VU, WM8962_ADC_VU);
- snd_soc_update_bits(codec, WM8962_RIGHT_ADC_VOLUME,
- WM8962_ADC_VU, WM8962_ADC_VU);
- snd_soc_update_bits(codec, WM8962_LEFT_DAC_VOLUME,
- WM8962_DAC_VU, WM8962_DAC_VU);
- snd_soc_update_bits(codec, WM8962_RIGHT_DAC_VOLUME,
- WM8962_DAC_VU, WM8962_DAC_VU);
- snd_soc_update_bits(codec, WM8962_SPKOUTL_VOLUME,
- WM8962_SPKOUT_VU, WM8962_SPKOUT_VU);
- snd_soc_update_bits(codec, WM8962_SPKOUTR_VOLUME,
- WM8962_SPKOUT_VU, WM8962_SPKOUT_VU);
- snd_soc_update_bits(codec, WM8962_HPOUTL_VOLUME,
- WM8962_HPOUT_VU, WM8962_HPOUT_VU);
- snd_soc_update_bits(codec, WM8962_HPOUTR_VOLUME,
- WM8962_HPOUT_VU, WM8962_HPOUT_VU);
-
- /* Stereo control for EQ */
- snd_soc_update_bits(codec, WM8962_EQ1, WM8962_EQ_SHARED_COEFF, 0);
-
- /* Don't debouce interrupts so we don't need SYSCLK */
- snd_soc_update_bits(codec, WM8962_IRQ_DEBOUNCE,
- WM8962_FLL_LOCK_DB | WM8962_PLL3_LOCK_DB |
- WM8962_PLL2_LOCK_DB | WM8962_TEMP_SHUT_DB,
- 0);
-
- wm8962_add_widgets(codec);
-
- /* Save boards having to disable DMIC when not in use */
- dmicclk = false;
- dmicdat = false;
- for (i = 0; i < WM8962_MAX_GPIO; i++) {
- switch (snd_soc_read(codec, WM8962_GPIO_BASE + i)
- & WM8962_GP2_FN_MASK) {
- case WM8962_GPIO_FN_DMICCLK:
- dmicclk = true;
- break;
- case WM8962_GPIO_FN_DMICDAT:
- dmicdat = true;
- break;
- default:
- break;
- }
- }
- if (!dmicclk || !dmicdat) {
- dev_dbg(codec->dev, "DMIC not in use, disabling\n");
- snd_soc_dapm_nc_pin(&codec->dapm, "DMICDAT");
- }
- if (dmicclk != dmicdat)
- dev_warn(codec->dev, "DMIC GPIOs partially configured\n");
-
- wm8962_init_beep(codec);
- wm8962_init_gpio(codec);
-
- if (wm8962->irq) {
- if (pdata && pdata->irq_active_low) {
- trigger = IRQF_TRIGGER_LOW;
- irq_pol = WM8962_IRQ_POL;
- } else {
- trigger = IRQF_TRIGGER_HIGH;
- irq_pol = 0;
- }
-
- snd_soc_update_bits(codec, WM8962_INTERRUPT_CONTROL,
- WM8962_IRQ_POL, irq_pol);
-
- ret = request_threaded_irq(wm8962->irq, NULL, wm8962_irq,
- trigger | IRQF_ONESHOT,
- "wm8962", codec->dev);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request IRQ %d: %d\n",
- wm8962->irq, ret);
- wm8962->irq = 0;
- /* Non-fatal */
- } else {
- /* Enable some IRQs by default */
- snd_soc_update_bits(codec,
- WM8962_INTERRUPT_STATUS_2_MASK,
- WM8962_FLL_LOCK_EINT |
- WM8962_TEMP_SHUT_EINT |
- WM8962_FIFOS_ERR_EINT, 0);
- }
- }
-
- return 0;
-}
-
-static int wm8962_remove(struct snd_soc_codec *codec)
-{
- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
- int i;
-
- if (wm8962->irq)
- free_irq(wm8962->irq, codec);
-
- cancel_delayed_work_sync(&wm8962->mic_work);
-
- wm8962_free_gpio(codec);
- wm8962_free_beep(codec);
- for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
- regulator_unregister_notifier(wm8962->supplies[i].consumer,
- &wm8962->disable_nb[i]);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8962 = {
- .probe = wm8962_probe,
- .remove = wm8962_remove,
- .set_bias_level = wm8962_set_bias_level,
- .set_pll = wm8962_set_fll,
- .idle_bias_off = true,
-};
-
-/* Improve power consumption for IN4 DC measurement mode */
-static const struct reg_default wm8962_dc_measure[] = {
- { 0xfd, 0x1 },
- { 0xcc, 0x40 },
- { 0xfd, 0 },
-};
-
-static const struct regmap_config wm8962_regmap = {
- .reg_bits = 16,
- .val_bits = 16,
-
- .max_register = WM8962_MAX_REGISTER,
- .reg_defaults = wm8962_reg,
- .num_reg_defaults = ARRAY_SIZE(wm8962_reg),
- .volatile_reg = wm8962_volatile_register,
- .readable_reg = wm8962_readable_register,
- .cache_type = REGCACHE_RBTREE,
-};
-
-static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8962_pdata *pdata = dev_get_platdata(&i2c->dev);
- struct wm8962_priv *wm8962;
- unsigned int reg;
- int ret, i;
-
- wm8962 = devm_kzalloc(&i2c->dev, sizeof(struct wm8962_priv),
- GFP_KERNEL);
- if (wm8962 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm8962);
-
- INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work);
- init_completion(&wm8962->fll_lock);
- wm8962->irq = i2c->irq;
-
- for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
- wm8962->supplies[i].supply = wm8962_supply_names[i];
-
- ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8962->supplies),
- wm8962->supplies);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
- goto err;
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
- wm8962->supplies);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
- goto err_get;
- }
-
- wm8962->regmap = regmap_init_i2c(i2c, &wm8962_regmap);
- if (IS_ERR(wm8962->regmap)) {
- ret = PTR_ERR(wm8962->regmap);
- dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
- goto err_enable;
- }
-
- /*
- * We haven't marked the chip revision as volatile due to
- * sharing a register with the right input volume; explicitly
- * bypass the cache to read it.
- */
- regcache_cache_bypass(wm8962->regmap, true);
-
- ret = regmap_read(wm8962->regmap, WM8962_SOFTWARE_RESET, &reg);
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to read ID register\n");
- goto err_regmap;
- }
- if (reg != 0x6243) {
- dev_err(&i2c->dev,
- "Device is not a WM8962, ID %x != 0x6243\n", reg);
- ret = -EINVAL;
- goto err_regmap;
- }
-
- ret = regmap_read(wm8962->regmap, WM8962_RIGHT_INPUT_VOLUME, &reg);
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to read device revision: %d\n",
- ret);
- goto err_regmap;
- }
-
- dev_info(&i2c->dev, "customer id %x revision %c\n",
- (reg & WM8962_CUST_ID_MASK) >> WM8962_CUST_ID_SHIFT,
- ((reg & WM8962_CHIP_REV_MASK) >> WM8962_CHIP_REV_SHIFT)
- + 'A');
-
- regcache_cache_bypass(wm8962->regmap, false);
-
- ret = wm8962_reset(wm8962);
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to issue reset\n");
- goto err_regmap;
- }
-
- if (pdata && pdata->in4_dc_measure) {
- ret = regmap_register_patch(wm8962->regmap,
- wm8962_dc_measure,
- ARRAY_SIZE(wm8962_dc_measure));
- if (ret != 0)
- dev_err(&i2c->dev,
- "Failed to configure for DC mesurement: %d\n",
- ret);
- }
-
- pm_runtime_enable(&i2c->dev);
- pm_request_idle(&i2c->dev);
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8962, &wm8962_dai, 1);
- if (ret < 0)
- goto err_regmap;
-
- /* The drivers should power up as needed */
- regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
-
- return 0;
-
-err_regmap:
- regmap_exit(wm8962->regmap);
-err_enable:
- regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
-err_get:
- regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
-err:
- return ret;
-}
-
-static __devexit int wm8962_i2c_remove(struct i2c_client *client)
-{
- struct wm8962_priv *wm8962 = dev_get_drvdata(&client->dev);
-
- snd_soc_unregister_codec(&client->dev);
- regmap_exit(wm8962->regmap);
- regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
- return 0;
-}
-
-#ifdef CONFIG_PM_RUNTIME
-static int wm8962_runtime_resume(struct device *dev)
-{
- struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
- int ret;
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
- wm8962->supplies);
- if (ret != 0) {
- dev_err(dev,
- "Failed to enable supplies: %d\n", ret);
- return ret;
- }
-
- regcache_cache_only(wm8962->regmap, false);
- regcache_sync(wm8962->regmap);
-
- regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP,
- WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA,
- WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA);
-
- /* Bias enable at 2*50k for ramp */
- regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1,
- WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA,
- WM8962_BIAS_ENA | 0x180);
-
- msleep(5);
-
- /* VMID back to 2x250k for standby */
- regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1,
- WM8962_VMID_SEL_MASK, 0x100);
-
- return 0;
-}
-
-static int wm8962_runtime_suspend(struct device *dev)
-{
- struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
-
- regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1,
- WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA, 0);
-
- regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP,
- WM8962_STARTUP_BIAS_ENA |
- WM8962_VMID_BUF_ENA, 0);
-
- regcache_cache_only(wm8962->regmap, true);
-
- regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies),
- wm8962->supplies);
-
- return 0;
-}
-#endif
-
-static struct dev_pm_ops wm8962_pm = {
- SET_RUNTIME_PM_OPS(wm8962_runtime_suspend, wm8962_runtime_resume, NULL)
-};
-
-static const struct i2c_device_id wm8962_i2c_id[] = {
- { "wm8962", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8962_i2c_id);
-
-static struct i2c_driver wm8962_i2c_driver = {
- .driver = {
- .name = "wm8962",
- .owner = THIS_MODULE,
- .pm = &wm8962_pm,
- },
- .probe = wm8962_i2c_probe,
- .remove = __devexit_p(wm8962_i2c_remove),
- .id_table = wm8962_i2c_id,
-};
-
-module_i2c_driver(wm8962_i2c_driver);
-
-MODULE_DESCRIPTION("ASoC WM8962 driver");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8962.h b/ANDROID_3.4.5/sound/soc/codecs/wm8962.h
deleted file mode 100644
index a1a5d529..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8962.h
+++ /dev/null
@@ -1,3780 +0,0 @@
-/*
- * wm8962.h -- WM8962 ASoC driver
- *
- * Copyright 2010 Wolfson Microelectronics, plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8962_H
-#define _WM8962_H
-
-#include <asm/types.h>
-#include <sound/soc.h>
-
-#define WM8962_SYSCLK_MCLK 1
-#define WM8962_SYSCLK_FLL 2
-#define WM8962_SYSCLK_PLL3 3
-
-#define WM8962_FLL 1
-
-#define WM8962_FLL_MCLK 1
-#define WM8962_FLL_BCLK 2
-#define WM8962_FLL_OSC 3
-#define WM8962_FLL_INT 4
-
-/*
- * Register values.
- */
-#define WM8962_LEFT_INPUT_VOLUME 0x00
-#define WM8962_RIGHT_INPUT_VOLUME 0x01
-#define WM8962_HPOUTL_VOLUME 0x02
-#define WM8962_HPOUTR_VOLUME 0x03
-#define WM8962_CLOCKING1 0x04
-#define WM8962_ADC_DAC_CONTROL_1 0x05
-#define WM8962_ADC_DAC_CONTROL_2 0x06
-#define WM8962_AUDIO_INTERFACE_0 0x07
-#define WM8962_CLOCKING2 0x08
-#define WM8962_AUDIO_INTERFACE_1 0x09
-#define WM8962_LEFT_DAC_VOLUME 0x0A
-#define WM8962_RIGHT_DAC_VOLUME 0x0B
-#define WM8962_AUDIO_INTERFACE_2 0x0E
-#define WM8962_SOFTWARE_RESET 0x0F
-#define WM8962_ALC1 0x11
-#define WM8962_ALC2 0x12
-#define WM8962_ALC3 0x13
-#define WM8962_NOISE_GATE 0x14
-#define WM8962_LEFT_ADC_VOLUME 0x15
-#define WM8962_RIGHT_ADC_VOLUME 0x16
-#define WM8962_ADDITIONAL_CONTROL_1 0x17
-#define WM8962_ADDITIONAL_CONTROL_2 0x18
-#define WM8962_PWR_MGMT_1 0x19
-#define WM8962_PWR_MGMT_2 0x1A
-#define WM8962_ADDITIONAL_CONTROL_3 0x1B
-#define WM8962_ANTI_POP 0x1C
-#define WM8962_CLOCKING_3 0x1E
-#define WM8962_INPUT_MIXER_CONTROL_1 0x1F
-#define WM8962_LEFT_INPUT_MIXER_VOLUME 0x20
-#define WM8962_RIGHT_INPUT_MIXER_VOLUME 0x21
-#define WM8962_INPUT_MIXER_CONTROL_2 0x22
-#define WM8962_INPUT_BIAS_CONTROL 0x23
-#define WM8962_LEFT_INPUT_PGA_CONTROL 0x25
-#define WM8962_RIGHT_INPUT_PGA_CONTROL 0x26
-#define WM8962_SPKOUTL_VOLUME 0x28
-#define WM8962_SPKOUTR_VOLUME 0x29
-#define WM8962_THERMAL_SHUTDOWN_STATUS 0x2F
-#define WM8962_ADDITIONAL_CONTROL_4 0x30
-#define WM8962_CLASS_D_CONTROL_1 0x31
-#define WM8962_CLASS_D_CONTROL_2 0x33
-#define WM8962_CLOCKING_4 0x38
-#define WM8962_DAC_DSP_MIXING_1 0x39
-#define WM8962_DAC_DSP_MIXING_2 0x3A
-#define WM8962_DC_SERVO_0 0x3C
-#define WM8962_DC_SERVO_1 0x3D
-#define WM8962_DC_SERVO_4 0x40
-#define WM8962_DC_SERVO_6 0x42
-#define WM8962_ANALOGUE_PGA_BIAS 0x44
-#define WM8962_ANALOGUE_HP_0 0x45
-#define WM8962_ANALOGUE_HP_2 0x47
-#define WM8962_CHARGE_PUMP_1 0x48
-#define WM8962_CHARGE_PUMP_B 0x52
-#define WM8962_WRITE_SEQUENCER_CONTROL_1 0x57
-#define WM8962_WRITE_SEQUENCER_CONTROL_2 0x5A
-#define WM8962_WRITE_SEQUENCER_CONTROL_3 0x5D
-#define WM8962_CONTROL_INTERFACE 0x5E
-#define WM8962_MIXER_ENABLES 0x63
-#define WM8962_HEADPHONE_MIXER_1 0x64
-#define WM8962_HEADPHONE_MIXER_2 0x65
-#define WM8962_HEADPHONE_MIXER_3 0x66
-#define WM8962_HEADPHONE_MIXER_4 0x67
-#define WM8962_SPEAKER_MIXER_1 0x69
-#define WM8962_SPEAKER_MIXER_2 0x6A
-#define WM8962_SPEAKER_MIXER_3 0x6B
-#define WM8962_SPEAKER_MIXER_4 0x6C
-#define WM8962_SPEAKER_MIXER_5 0x6D
-#define WM8962_BEEP_GENERATOR_1 0x6E
-#define WM8962_OSCILLATOR_TRIM_3 0x73
-#define WM8962_OSCILLATOR_TRIM_4 0x74
-#define WM8962_OSCILLATOR_TRIM_7 0x77
-#define WM8962_ANALOGUE_CLOCKING1 0x7C
-#define WM8962_ANALOGUE_CLOCKING2 0x7D
-#define WM8962_ANALOGUE_CLOCKING3 0x7E
-#define WM8962_PLL_SOFTWARE_RESET 0x7F
-#define WM8962_PLL2 0x81
-#define WM8962_PLL_4 0x83
-#define WM8962_PLL_9 0x88
-#define WM8962_PLL_10 0x89
-#define WM8962_PLL_11 0x8A
-#define WM8962_PLL_12 0x8B
-#define WM8962_PLL_13 0x8C
-#define WM8962_PLL_14 0x8D
-#define WM8962_PLL_15 0x8E
-#define WM8962_PLL_16 0x8F
-#define WM8962_FLL_CONTROL_1 0x9B
-#define WM8962_FLL_CONTROL_2 0x9C
-#define WM8962_FLL_CONTROL_3 0x9D
-#define WM8962_FLL_CONTROL_5 0x9F
-#define WM8962_FLL_CONTROL_6 0xA0
-#define WM8962_FLL_CONTROL_7 0xA1
-#define WM8962_FLL_CONTROL_8 0xA2
-#define WM8962_GENERAL_TEST_1 0xFC
-#define WM8962_DF1 0x100
-#define WM8962_DF2 0x101
-#define WM8962_DF3 0x102
-#define WM8962_DF4 0x103
-#define WM8962_DF5 0x104
-#define WM8962_DF6 0x105
-#define WM8962_DF7 0x106
-#define WM8962_LHPF1 0x108
-#define WM8962_LHPF2 0x109
-#define WM8962_THREED1 0x10C
-#define WM8962_THREED2 0x10D
-#define WM8962_THREED3 0x10E
-#define WM8962_THREED4 0x10F
-#define WM8962_DRC_1 0x114
-#define WM8962_DRC_2 0x115
-#define WM8962_DRC_3 0x116
-#define WM8962_DRC_4 0x117
-#define WM8962_DRC_5 0x118
-#define WM8962_TLOOPBACK 0x11D
-#define WM8962_EQ1 0x14F
-#define WM8962_EQ2 0x150
-#define WM8962_EQ3 0x151
-#define WM8962_EQ4 0x152
-#define WM8962_EQ5 0x153
-#define WM8962_EQ6 0x154
-#define WM8962_EQ7 0x155
-#define WM8962_EQ8 0x156
-#define WM8962_EQ9 0x157
-#define WM8962_EQ10 0x158
-#define WM8962_EQ11 0x159
-#define WM8962_EQ12 0x15A
-#define WM8962_EQ13 0x15B
-#define WM8962_EQ14 0x15C
-#define WM8962_EQ15 0x15D
-#define WM8962_EQ16 0x15E
-#define WM8962_EQ17 0x15F
-#define WM8962_EQ18 0x160
-#define WM8962_EQ19 0x161
-#define WM8962_EQ20 0x162
-#define WM8962_EQ21 0x163
-#define WM8962_EQ22 0x164
-#define WM8962_EQ23 0x165
-#define WM8962_EQ24 0x166
-#define WM8962_EQ25 0x167
-#define WM8962_EQ26 0x168
-#define WM8962_EQ27 0x169
-#define WM8962_EQ28 0x16A
-#define WM8962_EQ29 0x16B
-#define WM8962_EQ30 0x16C
-#define WM8962_EQ31 0x16D
-#define WM8962_EQ32 0x16E
-#define WM8962_EQ33 0x16F
-#define WM8962_EQ34 0x170
-#define WM8962_EQ35 0x171
-#define WM8962_EQ36 0x172
-#define WM8962_EQ37 0x173
-#define WM8962_EQ38 0x174
-#define WM8962_EQ39 0x175
-#define WM8962_EQ40 0x176
-#define WM8962_EQ41 0x177
-#define WM8962_GPIO_BASE 0x200
-#define WM8962_GPIO_2 0x201
-#define WM8962_GPIO_3 0x202
-#define WM8962_GPIO_5 0x204
-#define WM8962_GPIO_6 0x205
-#define WM8962_INTERRUPT_STATUS_1 0x230
-#define WM8962_INTERRUPT_STATUS_2 0x231
-#define WM8962_INTERRUPT_STATUS_1_MASK 0x238
-#define WM8962_INTERRUPT_STATUS_2_MASK 0x239
-#define WM8962_INTERRUPT_CONTROL 0x240
-#define WM8962_IRQ_DEBOUNCE 0x248
-#define WM8962_MICINT_SOURCE_POL 0x24A
-#define WM8962_DSP2_POWER_MANAGEMENT 0x300
-#define WM8962_DSP2_EXECCONTROL 0x40D
-#define WM8962_WRITE_SEQUENCER_0 0x1000
-#define WM8962_WRITE_SEQUENCER_1 0x1001
-#define WM8962_WRITE_SEQUENCER_2 0x1002
-#define WM8962_WRITE_SEQUENCER_3 0x1003
-#define WM8962_WRITE_SEQUENCER_4 0x1004
-#define WM8962_WRITE_SEQUENCER_5 0x1005
-#define WM8962_WRITE_SEQUENCER_6 0x1006
-#define WM8962_WRITE_SEQUENCER_7 0x1007
-#define WM8962_WRITE_SEQUENCER_8 0x1008
-#define WM8962_WRITE_SEQUENCER_9 0x1009
-#define WM8962_WRITE_SEQUENCER_10 0x100A
-#define WM8962_WRITE_SEQUENCER_11 0x100B
-#define WM8962_WRITE_SEQUENCER_12 0x100C
-#define WM8962_WRITE_SEQUENCER_13 0x100D
-#define WM8962_WRITE_SEQUENCER_14 0x100E
-#define WM8962_WRITE_SEQUENCER_15 0x100F
-#define WM8962_WRITE_SEQUENCER_16 0x1010
-#define WM8962_WRITE_SEQUENCER_17 0x1011
-#define WM8962_WRITE_SEQUENCER_18 0x1012
-#define WM8962_WRITE_SEQUENCER_19 0x1013
-#define WM8962_WRITE_SEQUENCER_20 0x1014
-#define WM8962_WRITE_SEQUENCER_21 0x1015
-#define WM8962_WRITE_SEQUENCER_22 0x1016
-#define WM8962_WRITE_SEQUENCER_23 0x1017
-#define WM8962_WRITE_SEQUENCER_24 0x1018
-#define WM8962_WRITE_SEQUENCER_25 0x1019
-#define WM8962_WRITE_SEQUENCER_26 0x101A
-#define WM8962_WRITE_SEQUENCER_27 0x101B
-#define WM8962_WRITE_SEQUENCER_28 0x101C
-#define WM8962_WRITE_SEQUENCER_29 0x101D
-#define WM8962_WRITE_SEQUENCER_30 0x101E
-#define WM8962_WRITE_SEQUENCER_31 0x101F
-#define WM8962_WRITE_SEQUENCER_32 0x1020
-#define WM8962_WRITE_SEQUENCER_33 0x1021
-#define WM8962_WRITE_SEQUENCER_34 0x1022
-#define WM8962_WRITE_SEQUENCER_35 0x1023
-#define WM8962_WRITE_SEQUENCER_36 0x1024
-#define WM8962_WRITE_SEQUENCER_37 0x1025
-#define WM8962_WRITE_SEQUENCER_38 0x1026
-#define WM8962_WRITE_SEQUENCER_39 0x1027
-#define WM8962_WRITE_SEQUENCER_40 0x1028
-#define WM8962_WRITE_SEQUENCER_41 0x1029
-#define WM8962_WRITE_SEQUENCER_42 0x102A
-#define WM8962_WRITE_SEQUENCER_43 0x102B
-#define WM8962_WRITE_SEQUENCER_44 0x102C
-#define WM8962_WRITE_SEQUENCER_45 0x102D
-#define WM8962_WRITE_SEQUENCER_46 0x102E
-#define WM8962_WRITE_SEQUENCER_47 0x102F
-#define WM8962_WRITE_SEQUENCER_48 0x1030
-#define WM8962_WRITE_SEQUENCER_49 0x1031
-#define WM8962_WRITE_SEQUENCER_50 0x1032
-#define WM8962_WRITE_SEQUENCER_51 0x1033
-#define WM8962_WRITE_SEQUENCER_52 0x1034
-#define WM8962_WRITE_SEQUENCER_53 0x1035
-#define WM8962_WRITE_SEQUENCER_54 0x1036
-#define WM8962_WRITE_SEQUENCER_55 0x1037
-#define WM8962_WRITE_SEQUENCER_56 0x1038
-#define WM8962_WRITE_SEQUENCER_57 0x1039
-#define WM8962_WRITE_SEQUENCER_58 0x103A
-#define WM8962_WRITE_SEQUENCER_59 0x103B
-#define WM8962_WRITE_SEQUENCER_60 0x103C
-#define WM8962_WRITE_SEQUENCER_61 0x103D
-#define WM8962_WRITE_SEQUENCER_62 0x103E
-#define WM8962_WRITE_SEQUENCER_63 0x103F
-#define WM8962_WRITE_SEQUENCER_64 0x1040
-#define WM8962_WRITE_SEQUENCER_65 0x1041
-#define WM8962_WRITE_SEQUENCER_66 0x1042
-#define WM8962_WRITE_SEQUENCER_67 0x1043
-#define WM8962_WRITE_SEQUENCER_68 0x1044
-#define WM8962_WRITE_SEQUENCER_69 0x1045
-#define WM8962_WRITE_SEQUENCER_70 0x1046
-#define WM8962_WRITE_SEQUENCER_71 0x1047
-#define WM8962_WRITE_SEQUENCER_72 0x1048
-#define WM8962_WRITE_SEQUENCER_73 0x1049
-#define WM8962_WRITE_SEQUENCER_74 0x104A
-#define WM8962_WRITE_SEQUENCER_75 0x104B
-#define WM8962_WRITE_SEQUENCER_76 0x104C
-#define WM8962_WRITE_SEQUENCER_77 0x104D
-#define WM8962_WRITE_SEQUENCER_78 0x104E
-#define WM8962_WRITE_SEQUENCER_79 0x104F
-#define WM8962_WRITE_SEQUENCER_80 0x1050
-#define WM8962_WRITE_SEQUENCER_81 0x1051
-#define WM8962_WRITE_SEQUENCER_82 0x1052
-#define WM8962_WRITE_SEQUENCER_83 0x1053
-#define WM8962_WRITE_SEQUENCER_84 0x1054
-#define WM8962_WRITE_SEQUENCER_85 0x1055
-#define WM8962_WRITE_SEQUENCER_86 0x1056
-#define WM8962_WRITE_SEQUENCER_87 0x1057
-#define WM8962_WRITE_SEQUENCER_88 0x1058
-#define WM8962_WRITE_SEQUENCER_89 0x1059
-#define WM8962_WRITE_SEQUENCER_90 0x105A
-#define WM8962_WRITE_SEQUENCER_91 0x105B
-#define WM8962_WRITE_SEQUENCER_92 0x105C
-#define WM8962_WRITE_SEQUENCER_93 0x105D
-#define WM8962_WRITE_SEQUENCER_94 0x105E
-#define WM8962_WRITE_SEQUENCER_95 0x105F
-#define WM8962_WRITE_SEQUENCER_96 0x1060
-#define WM8962_WRITE_SEQUENCER_97 0x1061
-#define WM8962_WRITE_SEQUENCER_98 0x1062
-#define WM8962_WRITE_SEQUENCER_99 0x1063
-#define WM8962_WRITE_SEQUENCER_100 0x1064
-#define WM8962_WRITE_SEQUENCER_101 0x1065
-#define WM8962_WRITE_SEQUENCER_102 0x1066
-#define WM8962_WRITE_SEQUENCER_103 0x1067
-#define WM8962_WRITE_SEQUENCER_104 0x1068
-#define WM8962_WRITE_SEQUENCER_105 0x1069
-#define WM8962_WRITE_SEQUENCER_106 0x106A
-#define WM8962_WRITE_SEQUENCER_107 0x106B
-#define WM8962_WRITE_SEQUENCER_108 0x106C
-#define WM8962_WRITE_SEQUENCER_109 0x106D
-#define WM8962_WRITE_SEQUENCER_110 0x106E
-#define WM8962_WRITE_SEQUENCER_111 0x106F
-#define WM8962_WRITE_SEQUENCER_112 0x1070
-#define WM8962_WRITE_SEQUENCER_113 0x1071
-#define WM8962_WRITE_SEQUENCER_114 0x1072
-#define WM8962_WRITE_SEQUENCER_115 0x1073
-#define WM8962_WRITE_SEQUENCER_116 0x1074
-#define WM8962_WRITE_SEQUENCER_117 0x1075
-#define WM8962_WRITE_SEQUENCER_118 0x1076
-#define WM8962_WRITE_SEQUENCER_119 0x1077
-#define WM8962_WRITE_SEQUENCER_120 0x1078
-#define WM8962_WRITE_SEQUENCER_121 0x1079
-#define WM8962_WRITE_SEQUENCER_122 0x107A
-#define WM8962_WRITE_SEQUENCER_123 0x107B
-#define WM8962_WRITE_SEQUENCER_124 0x107C
-#define WM8962_WRITE_SEQUENCER_125 0x107D
-#define WM8962_WRITE_SEQUENCER_126 0x107E
-#define WM8962_WRITE_SEQUENCER_127 0x107F
-#define WM8962_WRITE_SEQUENCER_128 0x1080
-#define WM8962_WRITE_SEQUENCER_129 0x1081
-#define WM8962_WRITE_SEQUENCER_130 0x1082
-#define WM8962_WRITE_SEQUENCER_131 0x1083
-#define WM8962_WRITE_SEQUENCER_132 0x1084
-#define WM8962_WRITE_SEQUENCER_133 0x1085
-#define WM8962_WRITE_SEQUENCER_134 0x1086
-#define WM8962_WRITE_SEQUENCER_135 0x1087
-#define WM8962_WRITE_SEQUENCER_136 0x1088
-#define WM8962_WRITE_SEQUENCER_137 0x1089
-#define WM8962_WRITE_SEQUENCER_138 0x108A
-#define WM8962_WRITE_SEQUENCER_139 0x108B
-#define WM8962_WRITE_SEQUENCER_140 0x108C
-#define WM8962_WRITE_SEQUENCER_141 0x108D
-#define WM8962_WRITE_SEQUENCER_142 0x108E
-#define WM8962_WRITE_SEQUENCER_143 0x108F
-#define WM8962_WRITE_SEQUENCER_144 0x1090
-#define WM8962_WRITE_SEQUENCER_145 0x1091
-#define WM8962_WRITE_SEQUENCER_146 0x1092
-#define WM8962_WRITE_SEQUENCER_147 0x1093
-#define WM8962_WRITE_SEQUENCER_148 0x1094
-#define WM8962_WRITE_SEQUENCER_149 0x1095
-#define WM8962_WRITE_SEQUENCER_150 0x1096
-#define WM8962_WRITE_SEQUENCER_151 0x1097
-#define WM8962_WRITE_SEQUENCER_152 0x1098
-#define WM8962_WRITE_SEQUENCER_153 0x1099
-#define WM8962_WRITE_SEQUENCER_154 0x109A
-#define WM8962_WRITE_SEQUENCER_155 0x109B
-#define WM8962_WRITE_SEQUENCER_156 0x109C
-#define WM8962_WRITE_SEQUENCER_157 0x109D
-#define WM8962_WRITE_SEQUENCER_158 0x109E
-#define WM8962_WRITE_SEQUENCER_159 0x109F
-#define WM8962_WRITE_SEQUENCER_160 0x10A0
-#define WM8962_WRITE_SEQUENCER_161 0x10A1
-#define WM8962_WRITE_SEQUENCER_162 0x10A2
-#define WM8962_WRITE_SEQUENCER_163 0x10A3
-#define WM8962_WRITE_SEQUENCER_164 0x10A4
-#define WM8962_WRITE_SEQUENCER_165 0x10A5
-#define WM8962_WRITE_SEQUENCER_166 0x10A6
-#define WM8962_WRITE_SEQUENCER_167 0x10A7
-#define WM8962_WRITE_SEQUENCER_168 0x10A8
-#define WM8962_WRITE_SEQUENCER_169 0x10A9
-#define WM8962_WRITE_SEQUENCER_170 0x10AA
-#define WM8962_WRITE_SEQUENCER_171 0x10AB
-#define WM8962_WRITE_SEQUENCER_172 0x10AC
-#define WM8962_WRITE_SEQUENCER_173 0x10AD
-#define WM8962_WRITE_SEQUENCER_174 0x10AE
-#define WM8962_WRITE_SEQUENCER_175 0x10AF
-#define WM8962_WRITE_SEQUENCER_176 0x10B0
-#define WM8962_WRITE_SEQUENCER_177 0x10B1
-#define WM8962_WRITE_SEQUENCER_178 0x10B2
-#define WM8962_WRITE_SEQUENCER_179 0x10B3
-#define WM8962_WRITE_SEQUENCER_180 0x10B4
-#define WM8962_WRITE_SEQUENCER_181 0x10B5
-#define WM8962_WRITE_SEQUENCER_182 0x10B6
-#define WM8962_WRITE_SEQUENCER_183 0x10B7
-#define WM8962_WRITE_SEQUENCER_184 0x10B8
-#define WM8962_WRITE_SEQUENCER_185 0x10B9
-#define WM8962_WRITE_SEQUENCER_186 0x10BA
-#define WM8962_WRITE_SEQUENCER_187 0x10BB
-#define WM8962_WRITE_SEQUENCER_188 0x10BC
-#define WM8962_WRITE_SEQUENCER_189 0x10BD
-#define WM8962_WRITE_SEQUENCER_190 0x10BE
-#define WM8962_WRITE_SEQUENCER_191 0x10BF
-#define WM8962_WRITE_SEQUENCER_192 0x10C0
-#define WM8962_WRITE_SEQUENCER_193 0x10C1
-#define WM8962_WRITE_SEQUENCER_194 0x10C2
-#define WM8962_WRITE_SEQUENCER_195 0x10C3
-#define WM8962_WRITE_SEQUENCER_196 0x10C4
-#define WM8962_WRITE_SEQUENCER_197 0x10C5
-#define WM8962_WRITE_SEQUENCER_198 0x10C6
-#define WM8962_WRITE_SEQUENCER_199 0x10C7
-#define WM8962_WRITE_SEQUENCER_200 0x10C8
-#define WM8962_WRITE_SEQUENCER_201 0x10C9
-#define WM8962_WRITE_SEQUENCER_202 0x10CA
-#define WM8962_WRITE_SEQUENCER_203 0x10CB
-#define WM8962_WRITE_SEQUENCER_204 0x10CC
-#define WM8962_WRITE_SEQUENCER_205 0x10CD
-#define WM8962_WRITE_SEQUENCER_206 0x10CE
-#define WM8962_WRITE_SEQUENCER_207 0x10CF
-#define WM8962_WRITE_SEQUENCER_208 0x10D0
-#define WM8962_WRITE_SEQUENCER_209 0x10D1
-#define WM8962_WRITE_SEQUENCER_210 0x10D2
-#define WM8962_WRITE_SEQUENCER_211 0x10D3
-#define WM8962_WRITE_SEQUENCER_212 0x10D4
-#define WM8962_WRITE_SEQUENCER_213 0x10D5
-#define WM8962_WRITE_SEQUENCER_214 0x10D6
-#define WM8962_WRITE_SEQUENCER_215 0x10D7
-#define WM8962_WRITE_SEQUENCER_216 0x10D8
-#define WM8962_WRITE_SEQUENCER_217 0x10D9
-#define WM8962_WRITE_SEQUENCER_218 0x10DA
-#define WM8962_WRITE_SEQUENCER_219 0x10DB
-#define WM8962_WRITE_SEQUENCER_220 0x10DC
-#define WM8962_WRITE_SEQUENCER_221 0x10DD
-#define WM8962_WRITE_SEQUENCER_222 0x10DE
-#define WM8962_WRITE_SEQUENCER_223 0x10DF
-#define WM8962_WRITE_SEQUENCER_224 0x10E0
-#define WM8962_WRITE_SEQUENCER_225 0x10E1
-#define WM8962_WRITE_SEQUENCER_226 0x10E2
-#define WM8962_WRITE_SEQUENCER_227 0x10E3
-#define WM8962_WRITE_SEQUENCER_228 0x10E4
-#define WM8962_WRITE_SEQUENCER_229 0x10E5
-#define WM8962_WRITE_SEQUENCER_230 0x10E6
-#define WM8962_WRITE_SEQUENCER_231 0x10E7
-#define WM8962_WRITE_SEQUENCER_232 0x10E8
-#define WM8962_WRITE_SEQUENCER_233 0x10E9
-#define WM8962_WRITE_SEQUENCER_234 0x10EA
-#define WM8962_WRITE_SEQUENCER_235 0x10EB
-#define WM8962_WRITE_SEQUENCER_236 0x10EC
-#define WM8962_WRITE_SEQUENCER_237 0x10ED
-#define WM8962_WRITE_SEQUENCER_238 0x10EE
-#define WM8962_WRITE_SEQUENCER_239 0x10EF
-#define WM8962_WRITE_SEQUENCER_240 0x10F0
-#define WM8962_WRITE_SEQUENCER_241 0x10F1
-#define WM8962_WRITE_SEQUENCER_242 0x10F2
-#define WM8962_WRITE_SEQUENCER_243 0x10F3
-#define WM8962_WRITE_SEQUENCER_244 0x10F4
-#define WM8962_WRITE_SEQUENCER_245 0x10F5
-#define WM8962_WRITE_SEQUENCER_246 0x10F6
-#define WM8962_WRITE_SEQUENCER_247 0x10F7
-#define WM8962_WRITE_SEQUENCER_248 0x10F8
-#define WM8962_WRITE_SEQUENCER_249 0x10F9
-#define WM8962_WRITE_SEQUENCER_250 0x10FA
-#define WM8962_WRITE_SEQUENCER_251 0x10FB
-#define WM8962_WRITE_SEQUENCER_252 0x10FC
-#define WM8962_WRITE_SEQUENCER_253 0x10FD
-#define WM8962_WRITE_SEQUENCER_254 0x10FE
-#define WM8962_WRITE_SEQUENCER_255 0x10FF
-#define WM8962_WRITE_SEQUENCER_256 0x1100
-#define WM8962_WRITE_SEQUENCER_257 0x1101
-#define WM8962_WRITE_SEQUENCER_258 0x1102
-#define WM8962_WRITE_SEQUENCER_259 0x1103
-#define WM8962_WRITE_SEQUENCER_260 0x1104
-#define WM8962_WRITE_SEQUENCER_261 0x1105
-#define WM8962_WRITE_SEQUENCER_262 0x1106
-#define WM8962_WRITE_SEQUENCER_263 0x1107
-#define WM8962_WRITE_SEQUENCER_264 0x1108
-#define WM8962_WRITE_SEQUENCER_265 0x1109
-#define WM8962_WRITE_SEQUENCER_266 0x110A
-#define WM8962_WRITE_SEQUENCER_267 0x110B
-#define WM8962_WRITE_SEQUENCER_268 0x110C
-#define WM8962_WRITE_SEQUENCER_269 0x110D
-#define WM8962_WRITE_SEQUENCER_270 0x110E
-#define WM8962_WRITE_SEQUENCER_271 0x110F
-#define WM8962_WRITE_SEQUENCER_272 0x1110
-#define WM8962_WRITE_SEQUENCER_273 0x1111
-#define WM8962_WRITE_SEQUENCER_274 0x1112
-#define WM8962_WRITE_SEQUENCER_275 0x1113
-#define WM8962_WRITE_SEQUENCER_276 0x1114
-#define WM8962_WRITE_SEQUENCER_277 0x1115
-#define WM8962_WRITE_SEQUENCER_278 0x1116
-#define WM8962_WRITE_SEQUENCER_279 0x1117
-#define WM8962_WRITE_SEQUENCER_280 0x1118
-#define WM8962_WRITE_SEQUENCER_281 0x1119
-#define WM8962_WRITE_SEQUENCER_282 0x111A
-#define WM8962_WRITE_SEQUENCER_283 0x111B
-#define WM8962_WRITE_SEQUENCER_284 0x111C
-#define WM8962_WRITE_SEQUENCER_285 0x111D
-#define WM8962_WRITE_SEQUENCER_286 0x111E
-#define WM8962_WRITE_SEQUENCER_287 0x111F
-#define WM8962_WRITE_SEQUENCER_288 0x1120
-#define WM8962_WRITE_SEQUENCER_289 0x1121
-#define WM8962_WRITE_SEQUENCER_290 0x1122
-#define WM8962_WRITE_SEQUENCER_291 0x1123
-#define WM8962_WRITE_SEQUENCER_292 0x1124
-#define WM8962_WRITE_SEQUENCER_293 0x1125
-#define WM8962_WRITE_SEQUENCER_294 0x1126
-#define WM8962_WRITE_SEQUENCER_295 0x1127
-#define WM8962_WRITE_SEQUENCER_296 0x1128
-#define WM8962_WRITE_SEQUENCER_297 0x1129
-#define WM8962_WRITE_SEQUENCER_298 0x112A
-#define WM8962_WRITE_SEQUENCER_299 0x112B
-#define WM8962_WRITE_SEQUENCER_300 0x112C
-#define WM8962_WRITE_SEQUENCER_301 0x112D
-#define WM8962_WRITE_SEQUENCER_302 0x112E
-#define WM8962_WRITE_SEQUENCER_303 0x112F
-#define WM8962_WRITE_SEQUENCER_304 0x1130
-#define WM8962_WRITE_SEQUENCER_305 0x1131
-#define WM8962_WRITE_SEQUENCER_306 0x1132
-#define WM8962_WRITE_SEQUENCER_307 0x1133
-#define WM8962_WRITE_SEQUENCER_308 0x1134
-#define WM8962_WRITE_SEQUENCER_309 0x1135
-#define WM8962_WRITE_SEQUENCER_310 0x1136
-#define WM8962_WRITE_SEQUENCER_311 0x1137
-#define WM8962_WRITE_SEQUENCER_312 0x1138
-#define WM8962_WRITE_SEQUENCER_313 0x1139
-#define WM8962_WRITE_SEQUENCER_314 0x113A
-#define WM8962_WRITE_SEQUENCER_315 0x113B
-#define WM8962_WRITE_SEQUENCER_316 0x113C
-#define WM8962_WRITE_SEQUENCER_317 0x113D
-#define WM8962_WRITE_SEQUENCER_318 0x113E
-#define WM8962_WRITE_SEQUENCER_319 0x113F
-#define WM8962_WRITE_SEQUENCER_320 0x1140
-#define WM8962_WRITE_SEQUENCER_321 0x1141
-#define WM8962_WRITE_SEQUENCER_322 0x1142
-#define WM8962_WRITE_SEQUENCER_323 0x1143
-#define WM8962_WRITE_SEQUENCER_324 0x1144
-#define WM8962_WRITE_SEQUENCER_325 0x1145
-#define WM8962_WRITE_SEQUENCER_326 0x1146
-#define WM8962_WRITE_SEQUENCER_327 0x1147
-#define WM8962_WRITE_SEQUENCER_328 0x1148
-#define WM8962_WRITE_SEQUENCER_329 0x1149
-#define WM8962_WRITE_SEQUENCER_330 0x114A
-#define WM8962_WRITE_SEQUENCER_331 0x114B
-#define WM8962_WRITE_SEQUENCER_332 0x114C
-#define WM8962_WRITE_SEQUENCER_333 0x114D
-#define WM8962_WRITE_SEQUENCER_334 0x114E
-#define WM8962_WRITE_SEQUENCER_335 0x114F
-#define WM8962_WRITE_SEQUENCER_336 0x1150
-#define WM8962_WRITE_SEQUENCER_337 0x1151
-#define WM8962_WRITE_SEQUENCER_338 0x1152
-#define WM8962_WRITE_SEQUENCER_339 0x1153
-#define WM8962_WRITE_SEQUENCER_340 0x1154
-#define WM8962_WRITE_SEQUENCER_341 0x1155
-#define WM8962_WRITE_SEQUENCER_342 0x1156
-#define WM8962_WRITE_SEQUENCER_343 0x1157
-#define WM8962_WRITE_SEQUENCER_344 0x1158
-#define WM8962_WRITE_SEQUENCER_345 0x1159
-#define WM8962_WRITE_SEQUENCER_346 0x115A
-#define WM8962_WRITE_SEQUENCER_347 0x115B
-#define WM8962_WRITE_SEQUENCER_348 0x115C
-#define WM8962_WRITE_SEQUENCER_349 0x115D
-#define WM8962_WRITE_SEQUENCER_350 0x115E
-#define WM8962_WRITE_SEQUENCER_351 0x115F
-#define WM8962_WRITE_SEQUENCER_352 0x1160
-#define WM8962_WRITE_SEQUENCER_353 0x1161
-#define WM8962_WRITE_SEQUENCER_354 0x1162
-#define WM8962_WRITE_SEQUENCER_355 0x1163
-#define WM8962_WRITE_SEQUENCER_356 0x1164
-#define WM8962_WRITE_SEQUENCER_357 0x1165
-#define WM8962_WRITE_SEQUENCER_358 0x1166
-#define WM8962_WRITE_SEQUENCER_359 0x1167
-#define WM8962_WRITE_SEQUENCER_360 0x1168
-#define WM8962_WRITE_SEQUENCER_361 0x1169
-#define WM8962_WRITE_SEQUENCER_362 0x116A
-#define WM8962_WRITE_SEQUENCER_363 0x116B
-#define WM8962_WRITE_SEQUENCER_364 0x116C
-#define WM8962_WRITE_SEQUENCER_365 0x116D
-#define WM8962_WRITE_SEQUENCER_366 0x116E
-#define WM8962_WRITE_SEQUENCER_367 0x116F
-#define WM8962_WRITE_SEQUENCER_368 0x1170
-#define WM8962_WRITE_SEQUENCER_369 0x1171
-#define WM8962_WRITE_SEQUENCER_370 0x1172
-#define WM8962_WRITE_SEQUENCER_371 0x1173
-#define WM8962_WRITE_SEQUENCER_372 0x1174
-#define WM8962_WRITE_SEQUENCER_373 0x1175
-#define WM8962_WRITE_SEQUENCER_374 0x1176
-#define WM8962_WRITE_SEQUENCER_375 0x1177
-#define WM8962_WRITE_SEQUENCER_376 0x1178
-#define WM8962_WRITE_SEQUENCER_377 0x1179
-#define WM8962_WRITE_SEQUENCER_378 0x117A
-#define WM8962_WRITE_SEQUENCER_379 0x117B
-#define WM8962_WRITE_SEQUENCER_380 0x117C
-#define WM8962_WRITE_SEQUENCER_381 0x117D
-#define WM8962_WRITE_SEQUENCER_382 0x117E
-#define WM8962_WRITE_SEQUENCER_383 0x117F
-#define WM8962_WRITE_SEQUENCER_384 0x1180
-#define WM8962_WRITE_SEQUENCER_385 0x1181
-#define WM8962_WRITE_SEQUENCER_386 0x1182
-#define WM8962_WRITE_SEQUENCER_387 0x1183
-#define WM8962_WRITE_SEQUENCER_388 0x1184
-#define WM8962_WRITE_SEQUENCER_389 0x1185
-#define WM8962_WRITE_SEQUENCER_390 0x1186
-#define WM8962_WRITE_SEQUENCER_391 0x1187
-#define WM8962_WRITE_SEQUENCER_392 0x1188
-#define WM8962_WRITE_SEQUENCER_393 0x1189
-#define WM8962_WRITE_SEQUENCER_394 0x118A
-#define WM8962_WRITE_SEQUENCER_395 0x118B
-#define WM8962_WRITE_SEQUENCER_396 0x118C
-#define WM8962_WRITE_SEQUENCER_397 0x118D
-#define WM8962_WRITE_SEQUENCER_398 0x118E
-#define WM8962_WRITE_SEQUENCER_399 0x118F
-#define WM8962_WRITE_SEQUENCER_400 0x1190
-#define WM8962_WRITE_SEQUENCER_401 0x1191
-#define WM8962_WRITE_SEQUENCER_402 0x1192
-#define WM8962_WRITE_SEQUENCER_403 0x1193
-#define WM8962_WRITE_SEQUENCER_404 0x1194
-#define WM8962_WRITE_SEQUENCER_405 0x1195
-#define WM8962_WRITE_SEQUENCER_406 0x1196
-#define WM8962_WRITE_SEQUENCER_407 0x1197
-#define WM8962_WRITE_SEQUENCER_408 0x1198
-#define WM8962_WRITE_SEQUENCER_409 0x1199
-#define WM8962_WRITE_SEQUENCER_410 0x119A
-#define WM8962_WRITE_SEQUENCER_411 0x119B
-#define WM8962_WRITE_SEQUENCER_412 0x119C
-#define WM8962_WRITE_SEQUENCER_413 0x119D
-#define WM8962_WRITE_SEQUENCER_414 0x119E
-#define WM8962_WRITE_SEQUENCER_415 0x119F
-#define WM8962_WRITE_SEQUENCER_416 0x11A0
-#define WM8962_WRITE_SEQUENCER_417 0x11A1
-#define WM8962_WRITE_SEQUENCER_418 0x11A2
-#define WM8962_WRITE_SEQUENCER_419 0x11A3
-#define WM8962_WRITE_SEQUENCER_420 0x11A4
-#define WM8962_WRITE_SEQUENCER_421 0x11A5
-#define WM8962_WRITE_SEQUENCER_422 0x11A6
-#define WM8962_WRITE_SEQUENCER_423 0x11A7
-#define WM8962_WRITE_SEQUENCER_424 0x11A8
-#define WM8962_WRITE_SEQUENCER_425 0x11A9
-#define WM8962_WRITE_SEQUENCER_426 0x11AA
-#define WM8962_WRITE_SEQUENCER_427 0x11AB
-#define WM8962_WRITE_SEQUENCER_428 0x11AC
-#define WM8962_WRITE_SEQUENCER_429 0x11AD
-#define WM8962_WRITE_SEQUENCER_430 0x11AE
-#define WM8962_WRITE_SEQUENCER_431 0x11AF
-#define WM8962_WRITE_SEQUENCER_432 0x11B0
-#define WM8962_WRITE_SEQUENCER_433 0x11B1
-#define WM8962_WRITE_SEQUENCER_434 0x11B2
-#define WM8962_WRITE_SEQUENCER_435 0x11B3
-#define WM8962_WRITE_SEQUENCER_436 0x11B4
-#define WM8962_WRITE_SEQUENCER_437 0x11B5
-#define WM8962_WRITE_SEQUENCER_438 0x11B6
-#define WM8962_WRITE_SEQUENCER_439 0x11B7
-#define WM8962_WRITE_SEQUENCER_440 0x11B8
-#define WM8962_WRITE_SEQUENCER_441 0x11B9
-#define WM8962_WRITE_SEQUENCER_442 0x11BA
-#define WM8962_WRITE_SEQUENCER_443 0x11BB
-#define WM8962_WRITE_SEQUENCER_444 0x11BC
-#define WM8962_WRITE_SEQUENCER_445 0x11BD
-#define WM8962_WRITE_SEQUENCER_446 0x11BE
-#define WM8962_WRITE_SEQUENCER_447 0x11BF
-#define WM8962_WRITE_SEQUENCER_448 0x11C0
-#define WM8962_WRITE_SEQUENCER_449 0x11C1
-#define WM8962_WRITE_SEQUENCER_450 0x11C2
-#define WM8962_WRITE_SEQUENCER_451 0x11C3
-#define WM8962_WRITE_SEQUENCER_452 0x11C4
-#define WM8962_WRITE_SEQUENCER_453 0x11C5
-#define WM8962_WRITE_SEQUENCER_454 0x11C6
-#define WM8962_WRITE_SEQUENCER_455 0x11C7
-#define WM8962_WRITE_SEQUENCER_456 0x11C8
-#define WM8962_WRITE_SEQUENCER_457 0x11C9
-#define WM8962_WRITE_SEQUENCER_458 0x11CA
-#define WM8962_WRITE_SEQUENCER_459 0x11CB
-#define WM8962_WRITE_SEQUENCER_460 0x11CC
-#define WM8962_WRITE_SEQUENCER_461 0x11CD
-#define WM8962_WRITE_SEQUENCER_462 0x11CE
-#define WM8962_WRITE_SEQUENCER_463 0x11CF
-#define WM8962_WRITE_SEQUENCER_464 0x11D0
-#define WM8962_WRITE_SEQUENCER_465 0x11D1
-#define WM8962_WRITE_SEQUENCER_466 0x11D2
-#define WM8962_WRITE_SEQUENCER_467 0x11D3
-#define WM8962_WRITE_SEQUENCER_468 0x11D4
-#define WM8962_WRITE_SEQUENCER_469 0x11D5
-#define WM8962_WRITE_SEQUENCER_470 0x11D6
-#define WM8962_WRITE_SEQUENCER_471 0x11D7
-#define WM8962_WRITE_SEQUENCER_472 0x11D8
-#define WM8962_WRITE_SEQUENCER_473 0x11D9
-#define WM8962_WRITE_SEQUENCER_474 0x11DA
-#define WM8962_WRITE_SEQUENCER_475 0x11DB
-#define WM8962_WRITE_SEQUENCER_476 0x11DC
-#define WM8962_WRITE_SEQUENCER_477 0x11DD
-#define WM8962_WRITE_SEQUENCER_478 0x11DE
-#define WM8962_WRITE_SEQUENCER_479 0x11DF
-#define WM8962_WRITE_SEQUENCER_480 0x11E0
-#define WM8962_WRITE_SEQUENCER_481 0x11E1
-#define WM8962_WRITE_SEQUENCER_482 0x11E2
-#define WM8962_WRITE_SEQUENCER_483 0x11E3
-#define WM8962_WRITE_SEQUENCER_484 0x11E4
-#define WM8962_WRITE_SEQUENCER_485 0x11E5
-#define WM8962_WRITE_SEQUENCER_486 0x11E6
-#define WM8962_WRITE_SEQUENCER_487 0x11E7
-#define WM8962_WRITE_SEQUENCER_488 0x11E8
-#define WM8962_WRITE_SEQUENCER_489 0x11E9
-#define WM8962_WRITE_SEQUENCER_490 0x11EA
-#define WM8962_WRITE_SEQUENCER_491 0x11EB
-#define WM8962_WRITE_SEQUENCER_492 0x11EC
-#define WM8962_WRITE_SEQUENCER_493 0x11ED
-#define WM8962_WRITE_SEQUENCER_494 0x11EE
-#define WM8962_WRITE_SEQUENCER_495 0x11EF
-#define WM8962_WRITE_SEQUENCER_496 0x11F0
-#define WM8962_WRITE_SEQUENCER_497 0x11F1
-#define WM8962_WRITE_SEQUENCER_498 0x11F2
-#define WM8962_WRITE_SEQUENCER_499 0x11F3
-#define WM8962_WRITE_SEQUENCER_500 0x11F4
-#define WM8962_WRITE_SEQUENCER_501 0x11F5
-#define WM8962_WRITE_SEQUENCER_502 0x11F6
-#define WM8962_WRITE_SEQUENCER_503 0x11F7
-#define WM8962_WRITE_SEQUENCER_504 0x11F8
-#define WM8962_WRITE_SEQUENCER_505 0x11F9
-#define WM8962_WRITE_SEQUENCER_506 0x11FA
-#define WM8962_WRITE_SEQUENCER_507 0x11FB
-#define WM8962_WRITE_SEQUENCER_508 0x11FC
-#define WM8962_WRITE_SEQUENCER_509 0x11FD
-#define WM8962_WRITE_SEQUENCER_510 0x11FE
-#define WM8962_WRITE_SEQUENCER_511 0x11FF
-#define WM8962_DSP2_INSTRUCTION_RAM_0 0x2000
-#define WM8962_DSP2_ADDRESS_RAM_2 0x2400
-#define WM8962_DSP2_ADDRESS_RAM_1 0x2401
-#define WM8962_DSP2_ADDRESS_RAM_0 0x2402
-#define WM8962_DSP2_DATA1_RAM_1 0x3000
-#define WM8962_DSP2_DATA1_RAM_0 0x3001
-#define WM8962_DSP2_DATA2_RAM_1 0x3400
-#define WM8962_DSP2_DATA2_RAM_0 0x3401
-#define WM8962_DSP2_DATA3_RAM_1 0x3800
-#define WM8962_DSP2_DATA3_RAM_0 0x3801
-#define WM8962_DSP2_COEFF_RAM_0 0x3C00
-#define WM8962_RETUNEADC_SHARED_COEFF_1 0x4000
-#define WM8962_RETUNEADC_SHARED_COEFF_0 0x4001
-#define WM8962_RETUNEDAC_SHARED_COEFF_1 0x4002
-#define WM8962_RETUNEDAC_SHARED_COEFF_0 0x4003
-#define WM8962_SOUNDSTAGE_ENABLES_1 0x4004
-#define WM8962_SOUNDSTAGE_ENABLES_0 0x4005
-#define WM8962_HDBASS_AI_1 0x4200
-#define WM8962_HDBASS_AI_0 0x4201
-#define WM8962_HDBASS_AR_1 0x4202
-#define WM8962_HDBASS_AR_0 0x4203
-#define WM8962_HDBASS_B_1 0x4204
-#define WM8962_HDBASS_B_0 0x4205
-#define WM8962_HDBASS_K_1 0x4206
-#define WM8962_HDBASS_K_0 0x4207
-#define WM8962_HDBASS_N1_1 0x4208
-#define WM8962_HDBASS_N1_0 0x4209
-#define WM8962_HDBASS_N2_1 0x420A
-#define WM8962_HDBASS_N2_0 0x420B
-#define WM8962_HDBASS_N3_1 0x420C
-#define WM8962_HDBASS_N3_0 0x420D
-#define WM8962_HDBASS_N4_1 0x420E
-#define WM8962_HDBASS_N4_0 0x420F
-#define WM8962_HDBASS_N5_1 0x4210
-#define WM8962_HDBASS_N5_0 0x4211
-#define WM8962_HDBASS_X1_1 0x4212
-#define WM8962_HDBASS_X1_0 0x4213
-#define WM8962_HDBASS_X2_1 0x4214
-#define WM8962_HDBASS_X2_0 0x4215
-#define WM8962_HDBASS_X3_1 0x4216
-#define WM8962_HDBASS_X3_0 0x4217
-#define WM8962_HDBASS_ATK_1 0x4218
-#define WM8962_HDBASS_ATK_0 0x4219
-#define WM8962_HDBASS_DCY_1 0x421A
-#define WM8962_HDBASS_DCY_0 0x421B
-#define WM8962_HDBASS_PG_1 0x421C
-#define WM8962_HDBASS_PG_0 0x421D
-#define WM8962_HPF_C_1 0x4400
-#define WM8962_HPF_C_0 0x4401
-#define WM8962_ADCL_RETUNE_C1_1 0x4600
-#define WM8962_ADCL_RETUNE_C1_0 0x4601
-#define WM8962_ADCL_RETUNE_C2_1 0x4602
-#define WM8962_ADCL_RETUNE_C2_0 0x4603
-#define WM8962_ADCL_RETUNE_C3_1 0x4604
-#define WM8962_ADCL_RETUNE_C3_0 0x4605
-#define WM8962_ADCL_RETUNE_C4_1 0x4606
-#define WM8962_ADCL_RETUNE_C4_0 0x4607
-#define WM8962_ADCL_RETUNE_C5_1 0x4608
-#define WM8962_ADCL_RETUNE_C5_0 0x4609
-#define WM8962_ADCL_RETUNE_C6_1 0x460A
-#define WM8962_ADCL_RETUNE_C6_0 0x460B
-#define WM8962_ADCL_RETUNE_C7_1 0x460C
-#define WM8962_ADCL_RETUNE_C7_0 0x460D
-#define WM8962_ADCL_RETUNE_C8_1 0x460E
-#define WM8962_ADCL_RETUNE_C8_0 0x460F
-#define WM8962_ADCL_RETUNE_C9_1 0x4610
-#define WM8962_ADCL_RETUNE_C9_0 0x4611
-#define WM8962_ADCL_RETUNE_C10_1 0x4612
-#define WM8962_ADCL_RETUNE_C10_0 0x4613
-#define WM8962_ADCL_RETUNE_C11_1 0x4614
-#define WM8962_ADCL_RETUNE_C11_0 0x4615
-#define WM8962_ADCL_RETUNE_C12_1 0x4616
-#define WM8962_ADCL_RETUNE_C12_0 0x4617
-#define WM8962_ADCL_RETUNE_C13_1 0x4618
-#define WM8962_ADCL_RETUNE_C13_0 0x4619
-#define WM8962_ADCL_RETUNE_C14_1 0x461A
-#define WM8962_ADCL_RETUNE_C14_0 0x461B
-#define WM8962_ADCL_RETUNE_C15_1 0x461C
-#define WM8962_ADCL_RETUNE_C15_0 0x461D
-#define WM8962_ADCL_RETUNE_C16_1 0x461E
-#define WM8962_ADCL_RETUNE_C16_0 0x461F
-#define WM8962_ADCL_RETUNE_C17_1 0x4620
-#define WM8962_ADCL_RETUNE_C17_0 0x4621
-#define WM8962_ADCL_RETUNE_C18_1 0x4622
-#define WM8962_ADCL_RETUNE_C18_0 0x4623
-#define WM8962_ADCL_RETUNE_C19_1 0x4624
-#define WM8962_ADCL_RETUNE_C19_0 0x4625
-#define WM8962_ADCL_RETUNE_C20_1 0x4626
-#define WM8962_ADCL_RETUNE_C20_0 0x4627
-#define WM8962_ADCL_RETUNE_C21_1 0x4628
-#define WM8962_ADCL_RETUNE_C21_0 0x4629
-#define WM8962_ADCL_RETUNE_C22_1 0x462A
-#define WM8962_ADCL_RETUNE_C22_0 0x462B
-#define WM8962_ADCL_RETUNE_C23_1 0x462C
-#define WM8962_ADCL_RETUNE_C23_0 0x462D
-#define WM8962_ADCL_RETUNE_C24_1 0x462E
-#define WM8962_ADCL_RETUNE_C24_0 0x462F
-#define WM8962_ADCL_RETUNE_C25_1 0x4630
-#define WM8962_ADCL_RETUNE_C25_0 0x4631
-#define WM8962_ADCL_RETUNE_C26_1 0x4632
-#define WM8962_ADCL_RETUNE_C26_0 0x4633
-#define WM8962_ADCL_RETUNE_C27_1 0x4634
-#define WM8962_ADCL_RETUNE_C27_0 0x4635
-#define WM8962_ADCL_RETUNE_C28_1 0x4636
-#define WM8962_ADCL_RETUNE_C28_0 0x4637
-#define WM8962_ADCL_RETUNE_C29_1 0x4638
-#define WM8962_ADCL_RETUNE_C29_0 0x4639
-#define WM8962_ADCL_RETUNE_C30_1 0x463A
-#define WM8962_ADCL_RETUNE_C30_0 0x463B
-#define WM8962_ADCL_RETUNE_C31_1 0x463C
-#define WM8962_ADCL_RETUNE_C31_0 0x463D
-#define WM8962_ADCL_RETUNE_C32_1 0x463E
-#define WM8962_ADCL_RETUNE_C32_0 0x463F
-#define WM8962_RETUNEADC_PG2_1 0x4800
-#define WM8962_RETUNEADC_PG2_0 0x4801
-#define WM8962_RETUNEADC_PG_1 0x4802
-#define WM8962_RETUNEADC_PG_0 0x4803
-#define WM8962_ADCR_RETUNE_C1_1 0x4A00
-#define WM8962_ADCR_RETUNE_C1_0 0x4A01
-#define WM8962_ADCR_RETUNE_C2_1 0x4A02
-#define WM8962_ADCR_RETUNE_C2_0 0x4A03
-#define WM8962_ADCR_RETUNE_C3_1 0x4A04
-#define WM8962_ADCR_RETUNE_C3_0 0x4A05
-#define WM8962_ADCR_RETUNE_C4_1 0x4A06
-#define WM8962_ADCR_RETUNE_C4_0 0x4A07
-#define WM8962_ADCR_RETUNE_C5_1 0x4A08
-#define WM8962_ADCR_RETUNE_C5_0 0x4A09
-#define WM8962_ADCR_RETUNE_C6_1 0x4A0A
-#define WM8962_ADCR_RETUNE_C6_0 0x4A0B
-#define WM8962_ADCR_RETUNE_C7_1 0x4A0C
-#define WM8962_ADCR_RETUNE_C7_0 0x4A0D
-#define WM8962_ADCR_RETUNE_C8_1 0x4A0E
-#define WM8962_ADCR_RETUNE_C8_0 0x4A0F
-#define WM8962_ADCR_RETUNE_C9_1 0x4A10
-#define WM8962_ADCR_RETUNE_C9_0 0x4A11
-#define WM8962_ADCR_RETUNE_C10_1 0x4A12
-#define WM8962_ADCR_RETUNE_C10_0 0x4A13
-#define WM8962_ADCR_RETUNE_C11_1 0x4A14
-#define WM8962_ADCR_RETUNE_C11_0 0x4A15
-#define WM8962_ADCR_RETUNE_C12_1 0x4A16
-#define WM8962_ADCR_RETUNE_C12_0 0x4A17
-#define WM8962_ADCR_RETUNE_C13_1 0x4A18
-#define WM8962_ADCR_RETUNE_C13_0 0x4A19
-#define WM8962_ADCR_RETUNE_C14_1 0x4A1A
-#define WM8962_ADCR_RETUNE_C14_0 0x4A1B
-#define WM8962_ADCR_RETUNE_C15_1 0x4A1C
-#define WM8962_ADCR_RETUNE_C15_0 0x4A1D
-#define WM8962_ADCR_RETUNE_C16_1 0x4A1E
-#define WM8962_ADCR_RETUNE_C16_0 0x4A1F
-#define WM8962_ADCR_RETUNE_C17_1 0x4A20
-#define WM8962_ADCR_RETUNE_C17_0 0x4A21
-#define WM8962_ADCR_RETUNE_C18_1 0x4A22
-#define WM8962_ADCR_RETUNE_C18_0 0x4A23
-#define WM8962_ADCR_RETUNE_C19_1 0x4A24
-#define WM8962_ADCR_RETUNE_C19_0 0x4A25
-#define WM8962_ADCR_RETUNE_C20_1 0x4A26
-#define WM8962_ADCR_RETUNE_C20_0 0x4A27
-#define WM8962_ADCR_RETUNE_C21_1 0x4A28
-#define WM8962_ADCR_RETUNE_C21_0 0x4A29
-#define WM8962_ADCR_RETUNE_C22_1 0x4A2A
-#define WM8962_ADCR_RETUNE_C22_0 0x4A2B
-#define WM8962_ADCR_RETUNE_C23_1 0x4A2C
-#define WM8962_ADCR_RETUNE_C23_0 0x4A2D
-#define WM8962_ADCR_RETUNE_C24_1 0x4A2E
-#define WM8962_ADCR_RETUNE_C24_0 0x4A2F
-#define WM8962_ADCR_RETUNE_C25_1 0x4A30
-#define WM8962_ADCR_RETUNE_C25_0 0x4A31
-#define WM8962_ADCR_RETUNE_C26_1 0x4A32
-#define WM8962_ADCR_RETUNE_C26_0 0x4A33
-#define WM8962_ADCR_RETUNE_C27_1 0x4A34
-#define WM8962_ADCR_RETUNE_C27_0 0x4A35
-#define WM8962_ADCR_RETUNE_C28_1 0x4A36
-#define WM8962_ADCR_RETUNE_C28_0 0x4A37
-#define WM8962_ADCR_RETUNE_C29_1 0x4A38
-#define WM8962_ADCR_RETUNE_C29_0 0x4A39
-#define WM8962_ADCR_RETUNE_C30_1 0x4A3A
-#define WM8962_ADCR_RETUNE_C30_0 0x4A3B
-#define WM8962_ADCR_RETUNE_C31_1 0x4A3C
-#define WM8962_ADCR_RETUNE_C31_0 0x4A3D
-#define WM8962_ADCR_RETUNE_C32_1 0x4A3E
-#define WM8962_ADCR_RETUNE_C32_0 0x4A3F
-#define WM8962_DACL_RETUNE_C1_1 0x4C00
-#define WM8962_DACL_RETUNE_C1_0 0x4C01
-#define WM8962_DACL_RETUNE_C2_1 0x4C02
-#define WM8962_DACL_RETUNE_C2_0 0x4C03
-#define WM8962_DACL_RETUNE_C3_1 0x4C04
-#define WM8962_DACL_RETUNE_C3_0 0x4C05
-#define WM8962_DACL_RETUNE_C4_1 0x4C06
-#define WM8962_DACL_RETUNE_C4_0 0x4C07
-#define WM8962_DACL_RETUNE_C5_1 0x4C08
-#define WM8962_DACL_RETUNE_C5_0 0x4C09
-#define WM8962_DACL_RETUNE_C6_1 0x4C0A
-#define WM8962_DACL_RETUNE_C6_0 0x4C0B
-#define WM8962_DACL_RETUNE_C7_1 0x4C0C
-#define WM8962_DACL_RETUNE_C7_0 0x4C0D
-#define WM8962_DACL_RETUNE_C8_1 0x4C0E
-#define WM8962_DACL_RETUNE_C8_0 0x4C0F
-#define WM8962_DACL_RETUNE_C9_1 0x4C10
-#define WM8962_DACL_RETUNE_C9_0 0x4C11
-#define WM8962_DACL_RETUNE_C10_1 0x4C12
-#define WM8962_DACL_RETUNE_C10_0 0x4C13
-#define WM8962_DACL_RETUNE_C11_1 0x4C14
-#define WM8962_DACL_RETUNE_C11_0 0x4C15
-#define WM8962_DACL_RETUNE_C12_1 0x4C16
-#define WM8962_DACL_RETUNE_C12_0 0x4C17
-#define WM8962_DACL_RETUNE_C13_1 0x4C18
-#define WM8962_DACL_RETUNE_C13_0 0x4C19
-#define WM8962_DACL_RETUNE_C14_1 0x4C1A
-#define WM8962_DACL_RETUNE_C14_0 0x4C1B
-#define WM8962_DACL_RETUNE_C15_1 0x4C1C
-#define WM8962_DACL_RETUNE_C15_0 0x4C1D
-#define WM8962_DACL_RETUNE_C16_1 0x4C1E
-#define WM8962_DACL_RETUNE_C16_0 0x4C1F
-#define WM8962_DACL_RETUNE_C17_1 0x4C20
-#define WM8962_DACL_RETUNE_C17_0 0x4C21
-#define WM8962_DACL_RETUNE_C18_1 0x4C22
-#define WM8962_DACL_RETUNE_C18_0 0x4C23
-#define WM8962_DACL_RETUNE_C19_1 0x4C24
-#define WM8962_DACL_RETUNE_C19_0 0x4C25
-#define WM8962_DACL_RETUNE_C20_1 0x4C26
-#define WM8962_DACL_RETUNE_C20_0 0x4C27
-#define WM8962_DACL_RETUNE_C21_1 0x4C28
-#define WM8962_DACL_RETUNE_C21_0 0x4C29
-#define WM8962_DACL_RETUNE_C22_1 0x4C2A
-#define WM8962_DACL_RETUNE_C22_0 0x4C2B
-#define WM8962_DACL_RETUNE_C23_1 0x4C2C
-#define WM8962_DACL_RETUNE_C23_0 0x4C2D
-#define WM8962_DACL_RETUNE_C24_1 0x4C2E
-#define WM8962_DACL_RETUNE_C24_0 0x4C2F
-#define WM8962_DACL_RETUNE_C25_1 0x4C30
-#define WM8962_DACL_RETUNE_C25_0 0x4C31
-#define WM8962_DACL_RETUNE_C26_1 0x4C32
-#define WM8962_DACL_RETUNE_C26_0 0x4C33
-#define WM8962_DACL_RETUNE_C27_1 0x4C34
-#define WM8962_DACL_RETUNE_C27_0 0x4C35
-#define WM8962_DACL_RETUNE_C28_1 0x4C36
-#define WM8962_DACL_RETUNE_C28_0 0x4C37
-#define WM8962_DACL_RETUNE_C29_1 0x4C38
-#define WM8962_DACL_RETUNE_C29_0 0x4C39
-#define WM8962_DACL_RETUNE_C30_1 0x4C3A
-#define WM8962_DACL_RETUNE_C30_0 0x4C3B
-#define WM8962_DACL_RETUNE_C31_1 0x4C3C
-#define WM8962_DACL_RETUNE_C31_0 0x4C3D
-#define WM8962_DACL_RETUNE_C32_1 0x4C3E
-#define WM8962_DACL_RETUNE_C32_0 0x4C3F
-#define WM8962_RETUNEDAC_PG2_1 0x4E00
-#define WM8962_RETUNEDAC_PG2_0 0x4E01
-#define WM8962_RETUNEDAC_PG_1 0x4E02
-#define WM8962_RETUNEDAC_PG_0 0x4E03
-#define WM8962_DACR_RETUNE_C1_1 0x5000
-#define WM8962_DACR_RETUNE_C1_0 0x5001
-#define WM8962_DACR_RETUNE_C2_1 0x5002
-#define WM8962_DACR_RETUNE_C2_0 0x5003
-#define WM8962_DACR_RETUNE_C3_1 0x5004
-#define WM8962_DACR_RETUNE_C3_0 0x5005
-#define WM8962_DACR_RETUNE_C4_1 0x5006
-#define WM8962_DACR_RETUNE_C4_0 0x5007
-#define WM8962_DACR_RETUNE_C5_1 0x5008
-#define WM8962_DACR_RETUNE_C5_0 0x5009
-#define WM8962_DACR_RETUNE_C6_1 0x500A
-#define WM8962_DACR_RETUNE_C6_0 0x500B
-#define WM8962_DACR_RETUNE_C7_1 0x500C
-#define WM8962_DACR_RETUNE_C7_0 0x500D
-#define WM8962_DACR_RETUNE_C8_1 0x500E
-#define WM8962_DACR_RETUNE_C8_0 0x500F
-#define WM8962_DACR_RETUNE_C9_1 0x5010
-#define WM8962_DACR_RETUNE_C9_0 0x5011
-#define WM8962_DACR_RETUNE_C10_1 0x5012
-#define WM8962_DACR_RETUNE_C10_0 0x5013
-#define WM8962_DACR_RETUNE_C11_1 0x5014
-#define WM8962_DACR_RETUNE_C11_0 0x5015
-#define WM8962_DACR_RETUNE_C12_1 0x5016
-#define WM8962_DACR_RETUNE_C12_0 0x5017
-#define WM8962_DACR_RETUNE_C13_1 0x5018
-#define WM8962_DACR_RETUNE_C13_0 0x5019
-#define WM8962_DACR_RETUNE_C14_1 0x501A
-#define WM8962_DACR_RETUNE_C14_0 0x501B
-#define WM8962_DACR_RETUNE_C15_1 0x501C
-#define WM8962_DACR_RETUNE_C15_0 0x501D
-#define WM8962_DACR_RETUNE_C16_1 0x501E
-#define WM8962_DACR_RETUNE_C16_0 0x501F
-#define WM8962_DACR_RETUNE_C17_1 0x5020
-#define WM8962_DACR_RETUNE_C17_0 0x5021
-#define WM8962_DACR_RETUNE_C18_1 0x5022
-#define WM8962_DACR_RETUNE_C18_0 0x5023
-#define WM8962_DACR_RETUNE_C19_1 0x5024
-#define WM8962_DACR_RETUNE_C19_0 0x5025
-#define WM8962_DACR_RETUNE_C20_1 0x5026
-#define WM8962_DACR_RETUNE_C20_0 0x5027
-#define WM8962_DACR_RETUNE_C21_1 0x5028
-#define WM8962_DACR_RETUNE_C21_0 0x5029
-#define WM8962_DACR_RETUNE_C22_1 0x502A
-#define WM8962_DACR_RETUNE_C22_0 0x502B
-#define WM8962_DACR_RETUNE_C23_1 0x502C
-#define WM8962_DACR_RETUNE_C23_0 0x502D
-#define WM8962_DACR_RETUNE_C24_1 0x502E
-#define WM8962_DACR_RETUNE_C24_0 0x502F
-#define WM8962_DACR_RETUNE_C25_1 0x5030
-#define WM8962_DACR_RETUNE_C25_0 0x5031
-#define WM8962_DACR_RETUNE_C26_1 0x5032
-#define WM8962_DACR_RETUNE_C26_0 0x5033
-#define WM8962_DACR_RETUNE_C27_1 0x5034
-#define WM8962_DACR_RETUNE_C27_0 0x5035
-#define WM8962_DACR_RETUNE_C28_1 0x5036
-#define WM8962_DACR_RETUNE_C28_0 0x5037
-#define WM8962_DACR_RETUNE_C29_1 0x5038
-#define WM8962_DACR_RETUNE_C29_0 0x5039
-#define WM8962_DACR_RETUNE_C30_1 0x503A
-#define WM8962_DACR_RETUNE_C30_0 0x503B
-#define WM8962_DACR_RETUNE_C31_1 0x503C
-#define WM8962_DACR_RETUNE_C31_0 0x503D
-#define WM8962_DACR_RETUNE_C32_1 0x503E
-#define WM8962_DACR_RETUNE_C32_0 0x503F
-#define WM8962_VSS_XHD2_1 0x5200
-#define WM8962_VSS_XHD2_0 0x5201
-#define WM8962_VSS_XHD3_1 0x5202
-#define WM8962_VSS_XHD3_0 0x5203
-#define WM8962_VSS_XHN1_1 0x5204
-#define WM8962_VSS_XHN1_0 0x5205
-#define WM8962_VSS_XHN2_1 0x5206
-#define WM8962_VSS_XHN2_0 0x5207
-#define WM8962_VSS_XHN3_1 0x5208
-#define WM8962_VSS_XHN3_0 0x5209
-#define WM8962_VSS_XLA_1 0x520A
-#define WM8962_VSS_XLA_0 0x520B
-#define WM8962_VSS_XLB_1 0x520C
-#define WM8962_VSS_XLB_0 0x520D
-#define WM8962_VSS_XLG_1 0x520E
-#define WM8962_VSS_XLG_0 0x520F
-#define WM8962_VSS_PG2_1 0x5210
-#define WM8962_VSS_PG2_0 0x5211
-#define WM8962_VSS_PG_1 0x5212
-#define WM8962_VSS_PG_0 0x5213
-#define WM8962_VSS_XTD1_1 0x5214
-#define WM8962_VSS_XTD1_0 0x5215
-#define WM8962_VSS_XTD2_1 0x5216
-#define WM8962_VSS_XTD2_0 0x5217
-#define WM8962_VSS_XTD3_1 0x5218
-#define WM8962_VSS_XTD3_0 0x5219
-#define WM8962_VSS_XTD4_1 0x521A
-#define WM8962_VSS_XTD4_0 0x521B
-#define WM8962_VSS_XTD5_1 0x521C
-#define WM8962_VSS_XTD5_0 0x521D
-#define WM8962_VSS_XTD6_1 0x521E
-#define WM8962_VSS_XTD6_0 0x521F
-#define WM8962_VSS_XTD7_1 0x5220
-#define WM8962_VSS_XTD7_0 0x5221
-#define WM8962_VSS_XTD8_1 0x5222
-#define WM8962_VSS_XTD8_0 0x5223
-#define WM8962_VSS_XTD9_1 0x5224
-#define WM8962_VSS_XTD9_0 0x5225
-#define WM8962_VSS_XTD10_1 0x5226
-#define WM8962_VSS_XTD10_0 0x5227
-#define WM8962_VSS_XTD11_1 0x5228
-#define WM8962_VSS_XTD11_0 0x5229
-#define WM8962_VSS_XTD12_1 0x522A
-#define WM8962_VSS_XTD12_0 0x522B
-#define WM8962_VSS_XTD13_1 0x522C
-#define WM8962_VSS_XTD13_0 0x522D
-#define WM8962_VSS_XTD14_1 0x522E
-#define WM8962_VSS_XTD14_0 0x522F
-#define WM8962_VSS_XTD15_1 0x5230
-#define WM8962_VSS_XTD15_0 0x5231
-#define WM8962_VSS_XTD16_1 0x5232
-#define WM8962_VSS_XTD16_0 0x5233
-#define WM8962_VSS_XTD17_1 0x5234
-#define WM8962_VSS_XTD17_0 0x5235
-#define WM8962_VSS_XTD18_1 0x5236
-#define WM8962_VSS_XTD18_0 0x5237
-#define WM8962_VSS_XTD19_1 0x5238
-#define WM8962_VSS_XTD19_0 0x5239
-#define WM8962_VSS_XTD20_1 0x523A
-#define WM8962_VSS_XTD20_0 0x523B
-#define WM8962_VSS_XTD21_1 0x523C
-#define WM8962_VSS_XTD21_0 0x523D
-#define WM8962_VSS_XTD22_1 0x523E
-#define WM8962_VSS_XTD22_0 0x523F
-#define WM8962_VSS_XTD23_1 0x5240
-#define WM8962_VSS_XTD23_0 0x5241
-#define WM8962_VSS_XTD24_1 0x5242
-#define WM8962_VSS_XTD24_0 0x5243
-#define WM8962_VSS_XTD25_1 0x5244
-#define WM8962_VSS_XTD25_0 0x5245
-#define WM8962_VSS_XTD26_1 0x5246
-#define WM8962_VSS_XTD26_0 0x5247
-#define WM8962_VSS_XTD27_1 0x5248
-#define WM8962_VSS_XTD27_0 0x5249
-#define WM8962_VSS_XTD28_1 0x524A
-#define WM8962_VSS_XTD28_0 0x524B
-#define WM8962_VSS_XTD29_1 0x524C
-#define WM8962_VSS_XTD29_0 0x524D
-#define WM8962_VSS_XTD30_1 0x524E
-#define WM8962_VSS_XTD30_0 0x524F
-#define WM8962_VSS_XTD31_1 0x5250
-#define WM8962_VSS_XTD31_0 0x5251
-#define WM8962_VSS_XTD32_1 0x5252
-#define WM8962_VSS_XTD32_0 0x5253
-#define WM8962_VSS_XTS1_1 0x5254
-#define WM8962_VSS_XTS1_0 0x5255
-#define WM8962_VSS_XTS2_1 0x5256
-#define WM8962_VSS_XTS2_0 0x5257
-#define WM8962_VSS_XTS3_1 0x5258
-#define WM8962_VSS_XTS3_0 0x5259
-#define WM8962_VSS_XTS4_1 0x525A
-#define WM8962_VSS_XTS4_0 0x525B
-#define WM8962_VSS_XTS5_1 0x525C
-#define WM8962_VSS_XTS5_0 0x525D
-#define WM8962_VSS_XTS6_1 0x525E
-#define WM8962_VSS_XTS6_0 0x525F
-#define WM8962_VSS_XTS7_1 0x5260
-#define WM8962_VSS_XTS7_0 0x5261
-#define WM8962_VSS_XTS8_1 0x5262
-#define WM8962_VSS_XTS8_0 0x5263
-#define WM8962_VSS_XTS9_1 0x5264
-#define WM8962_VSS_XTS9_0 0x5265
-#define WM8962_VSS_XTS10_1 0x5266
-#define WM8962_VSS_XTS10_0 0x5267
-#define WM8962_VSS_XTS11_1 0x5268
-#define WM8962_VSS_XTS11_0 0x5269
-#define WM8962_VSS_XTS12_1 0x526A
-#define WM8962_VSS_XTS12_0 0x526B
-#define WM8962_VSS_XTS13_1 0x526C
-#define WM8962_VSS_XTS13_0 0x526D
-#define WM8962_VSS_XTS14_1 0x526E
-#define WM8962_VSS_XTS14_0 0x526F
-#define WM8962_VSS_XTS15_1 0x5270
-#define WM8962_VSS_XTS15_0 0x5271
-#define WM8962_VSS_XTS16_1 0x5272
-#define WM8962_VSS_XTS16_0 0x5273
-#define WM8962_VSS_XTS17_1 0x5274
-#define WM8962_VSS_XTS17_0 0x5275
-#define WM8962_VSS_XTS18_1 0x5276
-#define WM8962_VSS_XTS18_0 0x5277
-#define WM8962_VSS_XTS19_1 0x5278
-#define WM8962_VSS_XTS19_0 0x5279
-#define WM8962_VSS_XTS20_1 0x527A
-#define WM8962_VSS_XTS20_0 0x527B
-#define WM8962_VSS_XTS21_1 0x527C
-#define WM8962_VSS_XTS21_0 0x527D
-#define WM8962_VSS_XTS22_1 0x527E
-#define WM8962_VSS_XTS22_0 0x527F
-#define WM8962_VSS_XTS23_1 0x5280
-#define WM8962_VSS_XTS23_0 0x5281
-#define WM8962_VSS_XTS24_1 0x5282
-#define WM8962_VSS_XTS24_0 0x5283
-#define WM8962_VSS_XTS25_1 0x5284
-#define WM8962_VSS_XTS25_0 0x5285
-#define WM8962_VSS_XTS26_1 0x5286
-#define WM8962_VSS_XTS26_0 0x5287
-#define WM8962_VSS_XTS27_1 0x5288
-#define WM8962_VSS_XTS27_0 0x5289
-#define WM8962_VSS_XTS28_1 0x528A
-#define WM8962_VSS_XTS28_0 0x528B
-#define WM8962_VSS_XTS29_1 0x528C
-#define WM8962_VSS_XTS29_0 0x528D
-#define WM8962_VSS_XTS30_1 0x528E
-#define WM8962_VSS_XTS30_0 0x528F
-#define WM8962_VSS_XTS31_1 0x5290
-#define WM8962_VSS_XTS31_0 0x5291
-#define WM8962_VSS_XTS32_1 0x5292
-#define WM8962_VSS_XTS32_0 0x5293
-
-#define WM8962_REGISTER_COUNT 1138
-#define WM8962_MAX_REGISTER 0x5293
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - Left Input volume
- */
-#define WM8962_IN_VU 0x0100 /* IN_VU */
-#define WM8962_IN_VU_MASK 0x0100 /* IN_VU */
-#define WM8962_IN_VU_SHIFT 8 /* IN_VU */
-#define WM8962_IN_VU_WIDTH 1 /* IN_VU */
-#define WM8962_INPGAL_MUTE 0x0080 /* INPGAL_MUTE */
-#define WM8962_INPGAL_MUTE_MASK 0x0080 /* INPGAL_MUTE */
-#define WM8962_INPGAL_MUTE_SHIFT 7 /* INPGAL_MUTE */
-#define WM8962_INPGAL_MUTE_WIDTH 1 /* INPGAL_MUTE */
-#define WM8962_INL_ZC 0x0040 /* INL_ZC */
-#define WM8962_INL_ZC_MASK 0x0040 /* INL_ZC */
-#define WM8962_INL_ZC_SHIFT 6 /* INL_ZC */
-#define WM8962_INL_ZC_WIDTH 1 /* INL_ZC */
-#define WM8962_INL_VOL_MASK 0x003F /* INL_VOL - [5:0] */
-#define WM8962_INL_VOL_SHIFT 0 /* INL_VOL - [5:0] */
-#define WM8962_INL_VOL_WIDTH 6 /* INL_VOL - [5:0] */
-
-/*
- * R1 (0x01) - Right Input volume
- */
-#define WM8962_CUST_ID_MASK 0xF000 /* CUST_ID - [15:12] */
-#define WM8962_CUST_ID_SHIFT 12 /* CUST_ID - [15:12] */
-#define WM8962_CUST_ID_WIDTH 4 /* CUST_ID - [15:12] */
-#define WM8962_CHIP_REV_MASK 0x0E00 /* CHIP_REV - [11:9] */
-#define WM8962_CHIP_REV_SHIFT 9 /* CHIP_REV - [11:9] */
-#define WM8962_CHIP_REV_WIDTH 3 /* CHIP_REV - [11:9] */
-#define WM8962_IN_VU 0x0100 /* IN_VU */
-#define WM8962_IN_VU_MASK 0x0100 /* IN_VU */
-#define WM8962_IN_VU_SHIFT 8 /* IN_VU */
-#define WM8962_IN_VU_WIDTH 1 /* IN_VU */
-#define WM8962_INPGAR_MUTE 0x0080 /* INPGAR_MUTE */
-#define WM8962_INPGAR_MUTE_MASK 0x0080 /* INPGAR_MUTE */
-#define WM8962_INPGAR_MUTE_SHIFT 7 /* INPGAR_MUTE */
-#define WM8962_INPGAR_MUTE_WIDTH 1 /* INPGAR_MUTE */
-#define WM8962_INR_ZC 0x0040 /* INR_ZC */
-#define WM8962_INR_ZC_MASK 0x0040 /* INR_ZC */
-#define WM8962_INR_ZC_SHIFT 6 /* INR_ZC */
-#define WM8962_INR_ZC_WIDTH 1 /* INR_ZC */
-#define WM8962_INR_VOL_MASK 0x003F /* INR_VOL - [5:0] */
-#define WM8962_INR_VOL_SHIFT 0 /* INR_VOL - [5:0] */
-#define WM8962_INR_VOL_WIDTH 6 /* INR_VOL - [5:0] */
-
-/*
- * R2 (0x02) - HPOUTL volume
- */
-#define WM8962_HPOUT_VU 0x0100 /* HPOUT_VU */
-#define WM8962_HPOUT_VU_MASK 0x0100 /* HPOUT_VU */
-#define WM8962_HPOUT_VU_SHIFT 8 /* HPOUT_VU */
-#define WM8962_HPOUT_VU_WIDTH 1 /* HPOUT_VU */
-#define WM8962_HPOUTL_ZC 0x0080 /* HPOUTL_ZC */
-#define WM8962_HPOUTL_ZC_MASK 0x0080 /* HPOUTL_ZC */
-#define WM8962_HPOUTL_ZC_SHIFT 7 /* HPOUTL_ZC */
-#define WM8962_HPOUTL_ZC_WIDTH 1 /* HPOUTL_ZC */
-#define WM8962_HPOUTL_VOL_MASK 0x007F /* HPOUTL_VOL - [6:0] */
-#define WM8962_HPOUTL_VOL_SHIFT 0 /* HPOUTL_VOL - [6:0] */
-#define WM8962_HPOUTL_VOL_WIDTH 7 /* HPOUTL_VOL - [6:0] */
-
-/*
- * R3 (0x03) - HPOUTR volume
- */
-#define WM8962_HPOUT_VU 0x0100 /* HPOUT_VU */
-#define WM8962_HPOUT_VU_MASK 0x0100 /* HPOUT_VU */
-#define WM8962_HPOUT_VU_SHIFT 8 /* HPOUT_VU */
-#define WM8962_HPOUT_VU_WIDTH 1 /* HPOUT_VU */
-#define WM8962_HPOUTR_ZC 0x0080 /* HPOUTR_ZC */
-#define WM8962_HPOUTR_ZC_MASK 0x0080 /* HPOUTR_ZC */
-#define WM8962_HPOUTR_ZC_SHIFT 7 /* HPOUTR_ZC */
-#define WM8962_HPOUTR_ZC_WIDTH 1 /* HPOUTR_ZC */
-#define WM8962_HPOUTR_VOL_MASK 0x007F /* HPOUTR_VOL - [6:0] */
-#define WM8962_HPOUTR_VOL_SHIFT 0 /* HPOUTR_VOL - [6:0] */
-#define WM8962_HPOUTR_VOL_WIDTH 7 /* HPOUTR_VOL - [6:0] */
-
-/*
- * R4 (0x04) - Clocking1
- */
-#define WM8962_DSPCLK_DIV_MASK 0x0600 /* DSPCLK_DIV - [10:9] */
-#define WM8962_DSPCLK_DIV_SHIFT 9 /* DSPCLK_DIV - [10:9] */
-#define WM8962_DSPCLK_DIV_WIDTH 2 /* DSPCLK_DIV - [10:9] */
-#define WM8962_ADCSYS_CLK_DIV_MASK 0x01C0 /* ADCSYS_CLK_DIV - [8:6] */
-#define WM8962_ADCSYS_CLK_DIV_SHIFT 6 /* ADCSYS_CLK_DIV - [8:6] */
-#define WM8962_ADCSYS_CLK_DIV_WIDTH 3 /* ADCSYS_CLK_DIV - [8:6] */
-#define WM8962_DACSYS_CLK_DIV_MASK 0x0038 /* DACSYS_CLK_DIV - [5:3] */
-#define WM8962_DACSYS_CLK_DIV_SHIFT 3 /* DACSYS_CLK_DIV - [5:3] */
-#define WM8962_DACSYS_CLK_DIV_WIDTH 3 /* DACSYS_CLK_DIV - [5:3] */
-#define WM8962_MCLKDIV_MASK 0x0006 /* MCLKDIV - [2:1] */
-#define WM8962_MCLKDIV_SHIFT 1 /* MCLKDIV - [2:1] */
-#define WM8962_MCLKDIV_WIDTH 2 /* MCLKDIV - [2:1] */
-
-/*
- * R5 (0x05) - ADC & DAC Control 1
- */
-#define WM8962_ADCR_DAT_INV 0x0040 /* ADCR_DAT_INV */
-#define WM8962_ADCR_DAT_INV_MASK 0x0040 /* ADCR_DAT_INV */
-#define WM8962_ADCR_DAT_INV_SHIFT 6 /* ADCR_DAT_INV */
-#define WM8962_ADCR_DAT_INV_WIDTH 1 /* ADCR_DAT_INV */
-#define WM8962_ADCL_DAT_INV 0x0020 /* ADCL_DAT_INV */
-#define WM8962_ADCL_DAT_INV_MASK 0x0020 /* ADCL_DAT_INV */
-#define WM8962_ADCL_DAT_INV_SHIFT 5 /* ADCL_DAT_INV */
-#define WM8962_ADCL_DAT_INV_WIDTH 1 /* ADCL_DAT_INV */
-#define WM8962_DAC_MUTE_RAMP 0x0010 /* DAC_MUTE_RAMP */
-#define WM8962_DAC_MUTE_RAMP_MASK 0x0010 /* DAC_MUTE_RAMP */
-#define WM8962_DAC_MUTE_RAMP_SHIFT 4 /* DAC_MUTE_RAMP */
-#define WM8962_DAC_MUTE_RAMP_WIDTH 1 /* DAC_MUTE_RAMP */
-#define WM8962_DAC_MUTE 0x0008 /* DAC_MUTE */
-#define WM8962_DAC_MUTE_MASK 0x0008 /* DAC_MUTE */
-#define WM8962_DAC_MUTE_SHIFT 3 /* DAC_MUTE */
-#define WM8962_DAC_MUTE_WIDTH 1 /* DAC_MUTE */
-#define WM8962_DAC_DEEMP_MASK 0x0006 /* DAC_DEEMP - [2:1] */
-#define WM8962_DAC_DEEMP_SHIFT 1 /* DAC_DEEMP - [2:1] */
-#define WM8962_DAC_DEEMP_WIDTH 2 /* DAC_DEEMP - [2:1] */
-#define WM8962_ADC_HPF_DIS 0x0001 /* ADC_HPF_DIS */
-#define WM8962_ADC_HPF_DIS_MASK 0x0001 /* ADC_HPF_DIS */
-#define WM8962_ADC_HPF_DIS_SHIFT 0 /* ADC_HPF_DIS */
-#define WM8962_ADC_HPF_DIS_WIDTH 1 /* ADC_HPF_DIS */
-
-/*
- * R6 (0x06) - ADC & DAC Control 2
- */
-#define WM8962_ADC_HPF_SR_MASK 0x3000 /* ADC_HPF_SR - [13:12] */
-#define WM8962_ADC_HPF_SR_SHIFT 12 /* ADC_HPF_SR - [13:12] */
-#define WM8962_ADC_HPF_SR_WIDTH 2 /* ADC_HPF_SR - [13:12] */
-#define WM8962_ADC_HPF_MODE 0x0400 /* ADC_HPF_MODE */
-#define WM8962_ADC_HPF_MODE_MASK 0x0400 /* ADC_HPF_MODE */
-#define WM8962_ADC_HPF_MODE_SHIFT 10 /* ADC_HPF_MODE */
-#define WM8962_ADC_HPF_MODE_WIDTH 1 /* ADC_HPF_MODE */
-#define WM8962_ADC_HPF_CUT_MASK 0x0380 /* ADC_HPF_CUT - [9:7] */
-#define WM8962_ADC_HPF_CUT_SHIFT 7 /* ADC_HPF_CUT - [9:7] */
-#define WM8962_ADC_HPF_CUT_WIDTH 3 /* ADC_HPF_CUT - [9:7] */
-#define WM8962_DACR_DAT_INV 0x0040 /* DACR_DAT_INV */
-#define WM8962_DACR_DAT_INV_MASK 0x0040 /* DACR_DAT_INV */
-#define WM8962_DACR_DAT_INV_SHIFT 6 /* DACR_DAT_INV */
-#define WM8962_DACR_DAT_INV_WIDTH 1 /* DACR_DAT_INV */
-#define WM8962_DACL_DAT_INV 0x0020 /* DACL_DAT_INV */
-#define WM8962_DACL_DAT_INV_MASK 0x0020 /* DACL_DAT_INV */
-#define WM8962_DACL_DAT_INV_SHIFT 5 /* DACL_DAT_INV */
-#define WM8962_DACL_DAT_INV_WIDTH 1 /* DACL_DAT_INV */
-#define WM8962_DAC_UNMUTE_RAMP 0x0008 /* DAC_UNMUTE_RAMP */
-#define WM8962_DAC_UNMUTE_RAMP_MASK 0x0008 /* DAC_UNMUTE_RAMP */
-#define WM8962_DAC_UNMUTE_RAMP_SHIFT 3 /* DAC_UNMUTE_RAMP */
-#define WM8962_DAC_UNMUTE_RAMP_WIDTH 1 /* DAC_UNMUTE_RAMP */
-#define WM8962_DAC_MUTERATE 0x0004 /* DAC_MUTERATE */
-#define WM8962_DAC_MUTERATE_MASK 0x0004 /* DAC_MUTERATE */
-#define WM8962_DAC_MUTERATE_SHIFT 2 /* DAC_MUTERATE */
-#define WM8962_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
-#define WM8962_DAC_HP 0x0001 /* DAC_HP */
-#define WM8962_DAC_HP_MASK 0x0001 /* DAC_HP */
-#define WM8962_DAC_HP_SHIFT 0 /* DAC_HP */
-#define WM8962_DAC_HP_WIDTH 1 /* DAC_HP */
-
-/*
- * R7 (0x07) - Audio Interface 0
- */
-#define WM8962_AIFDAC_TDM_MODE 0x1000 /* AIFDAC_TDM_MODE */
-#define WM8962_AIFDAC_TDM_MODE_MASK 0x1000 /* AIFDAC_TDM_MODE */
-#define WM8962_AIFDAC_TDM_MODE_SHIFT 12 /* AIFDAC_TDM_MODE */
-#define WM8962_AIFDAC_TDM_MODE_WIDTH 1 /* AIFDAC_TDM_MODE */
-#define WM8962_AIFDAC_TDM_SLOT 0x0800 /* AIFDAC_TDM_SLOT */
-#define WM8962_AIFDAC_TDM_SLOT_MASK 0x0800 /* AIFDAC_TDM_SLOT */
-#define WM8962_AIFDAC_TDM_SLOT_SHIFT 11 /* AIFDAC_TDM_SLOT */
-#define WM8962_AIFDAC_TDM_SLOT_WIDTH 1 /* AIFDAC_TDM_SLOT */
-#define WM8962_AIFADC_TDM_MODE 0x0400 /* AIFADC_TDM_MODE */
-#define WM8962_AIFADC_TDM_MODE_MASK 0x0400 /* AIFADC_TDM_MODE */
-#define WM8962_AIFADC_TDM_MODE_SHIFT 10 /* AIFADC_TDM_MODE */
-#define WM8962_AIFADC_TDM_MODE_WIDTH 1 /* AIFADC_TDM_MODE */
-#define WM8962_AIFADC_TDM_SLOT 0x0200 /* AIFADC_TDM_SLOT */
-#define WM8962_AIFADC_TDM_SLOT_MASK 0x0200 /* AIFADC_TDM_SLOT */
-#define WM8962_AIFADC_TDM_SLOT_SHIFT 9 /* AIFADC_TDM_SLOT */
-#define WM8962_AIFADC_TDM_SLOT_WIDTH 1 /* AIFADC_TDM_SLOT */
-#define WM8962_ADC_LRSWAP 0x0100 /* ADC_LRSWAP */
-#define WM8962_ADC_LRSWAP_MASK 0x0100 /* ADC_LRSWAP */
-#define WM8962_ADC_LRSWAP_SHIFT 8 /* ADC_LRSWAP */
-#define WM8962_ADC_LRSWAP_WIDTH 1 /* ADC_LRSWAP */
-#define WM8962_BCLK_INV 0x0080 /* BCLK_INV */
-#define WM8962_BCLK_INV_MASK 0x0080 /* BCLK_INV */
-#define WM8962_BCLK_INV_SHIFT 7 /* BCLK_INV */
-#define WM8962_BCLK_INV_WIDTH 1 /* BCLK_INV */
-#define WM8962_MSTR 0x0040 /* MSTR */
-#define WM8962_MSTR_MASK 0x0040 /* MSTR */
-#define WM8962_MSTR_SHIFT 6 /* MSTR */
-#define WM8962_MSTR_WIDTH 1 /* MSTR */
-#define WM8962_DAC_LRSWAP 0x0020 /* DAC_LRSWAP */
-#define WM8962_DAC_LRSWAP_MASK 0x0020 /* DAC_LRSWAP */
-#define WM8962_DAC_LRSWAP_SHIFT 5 /* DAC_LRSWAP */
-#define WM8962_DAC_LRSWAP_WIDTH 1 /* DAC_LRSWAP */
-#define WM8962_LRCLK_INV 0x0010 /* LRCLK_INV */
-#define WM8962_LRCLK_INV_MASK 0x0010 /* LRCLK_INV */
-#define WM8962_LRCLK_INV_SHIFT 4 /* LRCLK_INV */
-#define WM8962_LRCLK_INV_WIDTH 1 /* LRCLK_INV */
-#define WM8962_WL_MASK 0x000C /* WL - [3:2] */
-#define WM8962_WL_SHIFT 2 /* WL - [3:2] */
-#define WM8962_WL_WIDTH 2 /* WL - [3:2] */
-#define WM8962_FMT_MASK 0x0003 /* FMT - [1:0] */
-#define WM8962_FMT_SHIFT 0 /* FMT - [1:0] */
-#define WM8962_FMT_WIDTH 2 /* FMT - [1:0] */
-
-/*
- * R8 (0x08) - Clocking2
- */
-#define WM8962_CLKREG_OVD 0x0800 /* CLKREG_OVD */
-#define WM8962_CLKREG_OVD_MASK 0x0800 /* CLKREG_OVD */
-#define WM8962_CLKREG_OVD_SHIFT 11 /* CLKREG_OVD */
-#define WM8962_CLKREG_OVD_WIDTH 1 /* CLKREG_OVD */
-#define WM8962_SYSCLK_SRC_MASK 0x0600 /* SYSCLK_SRC - [10:9] */
-#define WM8962_SYSCLK_SRC_SHIFT 9 /* SYSCLK_SRC - [10:9] */
-#define WM8962_SYSCLK_SRC_WIDTH 2 /* SYSCLK_SRC - [10:9] */
-#define WM8962_CLASSD_CLK_DIV_MASK 0x01C0 /* CLASSD_CLK_DIV - [8:6] */
-#define WM8962_CLASSD_CLK_DIV_SHIFT 6 /* CLASSD_CLK_DIV - [8:6] */
-#define WM8962_CLASSD_CLK_DIV_WIDTH 3 /* CLASSD_CLK_DIV - [8:6] */
-#define WM8962_SYSCLK_ENA 0x0020 /* SYSCLK_ENA */
-#define WM8962_SYSCLK_ENA_MASK 0x0020 /* SYSCLK_ENA */
-#define WM8962_SYSCLK_ENA_SHIFT 5 /* SYSCLK_ENA */
-#define WM8962_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */
-#define WM8962_BCLK_DIV_MASK 0x000F /* BCLK_DIV - [3:0] */
-#define WM8962_BCLK_DIV_SHIFT 0 /* BCLK_DIV - [3:0] */
-#define WM8962_BCLK_DIV_WIDTH 4 /* BCLK_DIV - [3:0] */
-
-/*
- * R9 (0x09) - Audio Interface 1
- */
-#define WM8962_AUTOMUTE_STS 0x0800 /* AUTOMUTE_STS */
-#define WM8962_AUTOMUTE_STS_MASK 0x0800 /* AUTOMUTE_STS */
-#define WM8962_AUTOMUTE_STS_SHIFT 11 /* AUTOMUTE_STS */
-#define WM8962_AUTOMUTE_STS_WIDTH 1 /* AUTOMUTE_STS */
-#define WM8962_DAC_AUTOMUTE_SAMPLES_MASK 0x0300 /* DAC_AUTOMUTE_SAMPLES - [9:8] */
-#define WM8962_DAC_AUTOMUTE_SAMPLES_SHIFT 8 /* DAC_AUTOMUTE_SAMPLES - [9:8] */
-#define WM8962_DAC_AUTOMUTE_SAMPLES_WIDTH 2 /* DAC_AUTOMUTE_SAMPLES - [9:8] */
-#define WM8962_DAC_AUTOMUTE 0x0080 /* DAC_AUTOMUTE */
-#define WM8962_DAC_AUTOMUTE_MASK 0x0080 /* DAC_AUTOMUTE */
-#define WM8962_DAC_AUTOMUTE_SHIFT 7 /* DAC_AUTOMUTE */
-#define WM8962_DAC_AUTOMUTE_WIDTH 1 /* DAC_AUTOMUTE */
-#define WM8962_DAC_COMP 0x0010 /* DAC_COMP */
-#define WM8962_DAC_COMP_MASK 0x0010 /* DAC_COMP */
-#define WM8962_DAC_COMP_SHIFT 4 /* DAC_COMP */
-#define WM8962_DAC_COMP_WIDTH 1 /* DAC_COMP */
-#define WM8962_DAC_COMPMODE 0x0008 /* DAC_COMPMODE */
-#define WM8962_DAC_COMPMODE_MASK 0x0008 /* DAC_COMPMODE */
-#define WM8962_DAC_COMPMODE_SHIFT 3 /* DAC_COMPMODE */
-#define WM8962_DAC_COMPMODE_WIDTH 1 /* DAC_COMPMODE */
-#define WM8962_ADC_COMP 0x0004 /* ADC_COMP */
-#define WM8962_ADC_COMP_MASK 0x0004 /* ADC_COMP */
-#define WM8962_ADC_COMP_SHIFT 2 /* ADC_COMP */
-#define WM8962_ADC_COMP_WIDTH 1 /* ADC_COMP */
-#define WM8962_ADC_COMPMODE 0x0002 /* ADC_COMPMODE */
-#define WM8962_ADC_COMPMODE_MASK 0x0002 /* ADC_COMPMODE */
-#define WM8962_ADC_COMPMODE_SHIFT 1 /* ADC_COMPMODE */
-#define WM8962_ADC_COMPMODE_WIDTH 1 /* ADC_COMPMODE */
-#define WM8962_LOOPBACK 0x0001 /* LOOPBACK */
-#define WM8962_LOOPBACK_MASK 0x0001 /* LOOPBACK */
-#define WM8962_LOOPBACK_SHIFT 0 /* LOOPBACK */
-#define WM8962_LOOPBACK_WIDTH 1 /* LOOPBACK */
-
-/*
- * R10 (0x0A) - Left DAC volume
- */
-#define WM8962_DAC_VU 0x0100 /* DAC_VU */
-#define WM8962_DAC_VU_MASK 0x0100 /* DAC_VU */
-#define WM8962_DAC_VU_SHIFT 8 /* DAC_VU */
-#define WM8962_DAC_VU_WIDTH 1 /* DAC_VU */
-#define WM8962_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
-#define WM8962_DACL_VOL_SHIFT 0 /* DACL_VOL - [7:0] */
-#define WM8962_DACL_VOL_WIDTH 8 /* DACL_VOL - [7:0] */
-
-/*
- * R11 (0x0B) - Right DAC volume
- */
-#define WM8962_DAC_VU 0x0100 /* DAC_VU */
-#define WM8962_DAC_VU_MASK 0x0100 /* DAC_VU */
-#define WM8962_DAC_VU_SHIFT 8 /* DAC_VU */
-#define WM8962_DAC_VU_WIDTH 1 /* DAC_VU */
-#define WM8962_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
-#define WM8962_DACR_VOL_SHIFT 0 /* DACR_VOL - [7:0] */
-#define WM8962_DACR_VOL_WIDTH 8 /* DACR_VOL - [7:0] */
-
-/*
- * R14 (0x0E) - Audio Interface 2
- */
-#define WM8962_AIF_RATE_MASK 0x07FF /* AIF_RATE - [10:0] */
-#define WM8962_AIF_RATE_SHIFT 0 /* AIF_RATE - [10:0] */
-#define WM8962_AIF_RATE_WIDTH 11 /* AIF_RATE - [10:0] */
-
-/*
- * R15 (0x0F) - Software Reset
- */
-#define WM8962_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
-#define WM8962_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
-#define WM8962_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
-
-/*
- * R17 (0x11) - ALC1
- */
-#define WM8962_ALC_INACTIVE_ENA 0x0400 /* ALC_INACTIVE_ENA */
-#define WM8962_ALC_INACTIVE_ENA_MASK 0x0400 /* ALC_INACTIVE_ENA */
-#define WM8962_ALC_INACTIVE_ENA_SHIFT 10 /* ALC_INACTIVE_ENA */
-#define WM8962_ALC_INACTIVE_ENA_WIDTH 1 /* ALC_INACTIVE_ENA */
-#define WM8962_ALC_LVL_MODE 0x0200 /* ALC_LVL_MODE */
-#define WM8962_ALC_LVL_MODE_MASK 0x0200 /* ALC_LVL_MODE */
-#define WM8962_ALC_LVL_MODE_SHIFT 9 /* ALC_LVL_MODE */
-#define WM8962_ALC_LVL_MODE_WIDTH 1 /* ALC_LVL_MODE */
-#define WM8962_ALCL_ENA 0x0100 /* ALCL_ENA */
-#define WM8962_ALCL_ENA_MASK 0x0100 /* ALCL_ENA */
-#define WM8962_ALCL_ENA_SHIFT 8 /* ALCL_ENA */
-#define WM8962_ALCL_ENA_WIDTH 1 /* ALCL_ENA */
-#define WM8962_ALCR_ENA 0x0080 /* ALCR_ENA */
-#define WM8962_ALCR_ENA_MASK 0x0080 /* ALCR_ENA */
-#define WM8962_ALCR_ENA_SHIFT 7 /* ALCR_ENA */
-#define WM8962_ALCR_ENA_WIDTH 1 /* ALCR_ENA */
-#define WM8962_ALC_MAXGAIN_MASK 0x0070 /* ALC_MAXGAIN - [6:4] */
-#define WM8962_ALC_MAXGAIN_SHIFT 4 /* ALC_MAXGAIN - [6:4] */
-#define WM8962_ALC_MAXGAIN_WIDTH 3 /* ALC_MAXGAIN - [6:4] */
-#define WM8962_ALC_LVL_MASK 0x000F /* ALC_LVL - [3:0] */
-#define WM8962_ALC_LVL_SHIFT 0 /* ALC_LVL - [3:0] */
-#define WM8962_ALC_LVL_WIDTH 4 /* ALC_LVL - [3:0] */
-
-/*
- * R18 (0x12) - ALC2
- */
-#define WM8962_ALC_LOCK_STS 0x8000 /* ALC_LOCK_STS */
-#define WM8962_ALC_LOCK_STS_MASK 0x8000 /* ALC_LOCK_STS */
-#define WM8962_ALC_LOCK_STS_SHIFT 15 /* ALC_LOCK_STS */
-#define WM8962_ALC_LOCK_STS_WIDTH 1 /* ALC_LOCK_STS */
-#define WM8962_ALC_THRESH_STS 0x4000 /* ALC_THRESH_STS */
-#define WM8962_ALC_THRESH_STS_MASK 0x4000 /* ALC_THRESH_STS */
-#define WM8962_ALC_THRESH_STS_SHIFT 14 /* ALC_THRESH_STS */
-#define WM8962_ALC_THRESH_STS_WIDTH 1 /* ALC_THRESH_STS */
-#define WM8962_ALC_SAT_STS 0x2000 /* ALC_SAT_STS */
-#define WM8962_ALC_SAT_STS_MASK 0x2000 /* ALC_SAT_STS */
-#define WM8962_ALC_SAT_STS_SHIFT 13 /* ALC_SAT_STS */
-#define WM8962_ALC_SAT_STS_WIDTH 1 /* ALC_SAT_STS */
-#define WM8962_ALC_PKOVR_STS 0x1000 /* ALC_PKOVR_STS */
-#define WM8962_ALC_PKOVR_STS_MASK 0x1000 /* ALC_PKOVR_STS */
-#define WM8962_ALC_PKOVR_STS_SHIFT 12 /* ALC_PKOVR_STS */
-#define WM8962_ALC_PKOVR_STS_WIDTH 1 /* ALC_PKOVR_STS */
-#define WM8962_ALC_NGATE_STS 0x0800 /* ALC_NGATE_STS */
-#define WM8962_ALC_NGATE_STS_MASK 0x0800 /* ALC_NGATE_STS */
-#define WM8962_ALC_NGATE_STS_SHIFT 11 /* ALC_NGATE_STS */
-#define WM8962_ALC_NGATE_STS_WIDTH 1 /* ALC_NGATE_STS */
-#define WM8962_ALC_ZC 0x0080 /* ALC_ZC */
-#define WM8962_ALC_ZC_MASK 0x0080 /* ALC_ZC */
-#define WM8962_ALC_ZC_SHIFT 7 /* ALC_ZC */
-#define WM8962_ALC_ZC_WIDTH 1 /* ALC_ZC */
-#define WM8962_ALC_MINGAIN_MASK 0x0070 /* ALC_MINGAIN - [6:4] */
-#define WM8962_ALC_MINGAIN_SHIFT 4 /* ALC_MINGAIN - [6:4] */
-#define WM8962_ALC_MINGAIN_WIDTH 3 /* ALC_MINGAIN - [6:4] */
-#define WM8962_ALC_HLD_MASK 0x000F /* ALC_HLD - [3:0] */
-#define WM8962_ALC_HLD_SHIFT 0 /* ALC_HLD - [3:0] */
-#define WM8962_ALC_HLD_WIDTH 4 /* ALC_HLD - [3:0] */
-
-/*
- * R19 (0x13) - ALC3
- */
-#define WM8962_ALC_NGATE_GAIN_MASK 0x1C00 /* ALC_NGATE_GAIN - [12:10] */
-#define WM8962_ALC_NGATE_GAIN_SHIFT 10 /* ALC_NGATE_GAIN - [12:10] */
-#define WM8962_ALC_NGATE_GAIN_WIDTH 3 /* ALC_NGATE_GAIN - [12:10] */
-#define WM8962_ALC_MODE 0x0100 /* ALC_MODE */
-#define WM8962_ALC_MODE_MASK 0x0100 /* ALC_MODE */
-#define WM8962_ALC_MODE_SHIFT 8 /* ALC_MODE */
-#define WM8962_ALC_MODE_WIDTH 1 /* ALC_MODE */
-#define WM8962_ALC_DCY_MASK 0x00F0 /* ALC_DCY - [7:4] */
-#define WM8962_ALC_DCY_SHIFT 4 /* ALC_DCY - [7:4] */
-#define WM8962_ALC_DCY_WIDTH 4 /* ALC_DCY - [7:4] */
-#define WM8962_ALC_ATK_MASK 0x000F /* ALC_ATK - [3:0] */
-#define WM8962_ALC_ATK_SHIFT 0 /* ALC_ATK - [3:0] */
-#define WM8962_ALC_ATK_WIDTH 4 /* ALC_ATK - [3:0] */
-
-/*
- * R20 (0x14) - Noise Gate
- */
-#define WM8962_ALC_NGATE_DCY_MASK 0xF000 /* ALC_NGATE_DCY - [15:12] */
-#define WM8962_ALC_NGATE_DCY_SHIFT 12 /* ALC_NGATE_DCY - [15:12] */
-#define WM8962_ALC_NGATE_DCY_WIDTH 4 /* ALC_NGATE_DCY - [15:12] */
-#define WM8962_ALC_NGATE_ATK_MASK 0x0F00 /* ALC_NGATE_ATK - [11:8] */
-#define WM8962_ALC_NGATE_ATK_SHIFT 8 /* ALC_NGATE_ATK - [11:8] */
-#define WM8962_ALC_NGATE_ATK_WIDTH 4 /* ALC_NGATE_ATK - [11:8] */
-#define WM8962_ALC_NGATE_THR_MASK 0x00F8 /* ALC_NGATE_THR - [7:3] */
-#define WM8962_ALC_NGATE_THR_SHIFT 3 /* ALC_NGATE_THR - [7:3] */
-#define WM8962_ALC_NGATE_THR_WIDTH 5 /* ALC_NGATE_THR - [7:3] */
-#define WM8962_ALC_NGATE_MODE_MASK 0x0006 /* ALC_NGATE_MODE - [2:1] */
-#define WM8962_ALC_NGATE_MODE_SHIFT 1 /* ALC_NGATE_MODE - [2:1] */
-#define WM8962_ALC_NGATE_MODE_WIDTH 2 /* ALC_NGATE_MODE - [2:1] */
-#define WM8962_ALC_NGATE_ENA 0x0001 /* ALC_NGATE_ENA */
-#define WM8962_ALC_NGATE_ENA_MASK 0x0001 /* ALC_NGATE_ENA */
-#define WM8962_ALC_NGATE_ENA_SHIFT 0 /* ALC_NGATE_ENA */
-#define WM8962_ALC_NGATE_ENA_WIDTH 1 /* ALC_NGATE_ENA */
-
-/*
- * R21 (0x15) - Left ADC volume
- */
-#define WM8962_ADC_VU 0x0100 /* ADC_VU */
-#define WM8962_ADC_VU_MASK 0x0100 /* ADC_VU */
-#define WM8962_ADC_VU_SHIFT 8 /* ADC_VU */
-#define WM8962_ADC_VU_WIDTH 1 /* ADC_VU */
-#define WM8962_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
-#define WM8962_ADCL_VOL_SHIFT 0 /* ADCL_VOL - [7:0] */
-#define WM8962_ADCL_VOL_WIDTH 8 /* ADCL_VOL - [7:0] */
-
-/*
- * R22 (0x16) - Right ADC volume
- */
-#define WM8962_ADC_VU 0x0100 /* ADC_VU */
-#define WM8962_ADC_VU_MASK 0x0100 /* ADC_VU */
-#define WM8962_ADC_VU_SHIFT 8 /* ADC_VU */
-#define WM8962_ADC_VU_WIDTH 1 /* ADC_VU */
-#define WM8962_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
-#define WM8962_ADCR_VOL_SHIFT 0 /* ADCR_VOL - [7:0] */
-#define WM8962_ADCR_VOL_WIDTH 8 /* ADCR_VOL - [7:0] */
-
-/*
- * R23 (0x17) - Additional control(1)
- */
-#define WM8962_THERR_ACT 0x0100 /* THERR_ACT */
-#define WM8962_THERR_ACT_MASK 0x0100 /* THERR_ACT */
-#define WM8962_THERR_ACT_SHIFT 8 /* THERR_ACT */
-#define WM8962_THERR_ACT_WIDTH 1 /* THERR_ACT */
-#define WM8962_ADC_BIAS 0x0040 /* ADC_BIAS */
-#define WM8962_ADC_BIAS_MASK 0x0040 /* ADC_BIAS */
-#define WM8962_ADC_BIAS_SHIFT 6 /* ADC_BIAS */
-#define WM8962_ADC_BIAS_WIDTH 1 /* ADC_BIAS */
-#define WM8962_ADC_HP 0x0020 /* ADC_HP */
-#define WM8962_ADC_HP_MASK 0x0020 /* ADC_HP */
-#define WM8962_ADC_HP_SHIFT 5 /* ADC_HP */
-#define WM8962_ADC_HP_WIDTH 1 /* ADC_HP */
-#define WM8962_TOCLK_ENA 0x0001 /* TOCLK_ENA */
-#define WM8962_TOCLK_ENA_MASK 0x0001 /* TOCLK_ENA */
-#define WM8962_TOCLK_ENA_SHIFT 0 /* TOCLK_ENA */
-#define WM8962_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
-
-/*
- * R24 (0x18) - Additional control(2)
- */
-#define WM8962_AIF_TRI 0x0008 /* AIF_TRI */
-#define WM8962_AIF_TRI_MASK 0x0008 /* AIF_TRI */
-#define WM8962_AIF_TRI_SHIFT 3 /* AIF_TRI */
-#define WM8962_AIF_TRI_WIDTH 1 /* AIF_TRI */
-
-/*
- * R25 (0x19) - Pwr Mgmt (1)
- */
-#define WM8962_DMIC_ENA 0x0400 /* DMIC_ENA */
-#define WM8962_DMIC_ENA_MASK 0x0400 /* DMIC_ENA */
-#define WM8962_DMIC_ENA_SHIFT 10 /* DMIC_ENA */
-#define WM8962_DMIC_ENA_WIDTH 1 /* DMIC_ENA */
-#define WM8962_OPCLK_ENA 0x0200 /* OPCLK_ENA */
-#define WM8962_OPCLK_ENA_MASK 0x0200 /* OPCLK_ENA */
-#define WM8962_OPCLK_ENA_SHIFT 9 /* OPCLK_ENA */
-#define WM8962_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
-#define WM8962_VMID_SEL_MASK 0x0180 /* VMID_SEL - [8:7] */
-#define WM8962_VMID_SEL_SHIFT 7 /* VMID_SEL - [8:7] */
-#define WM8962_VMID_SEL_WIDTH 2 /* VMID_SEL - [8:7] */
-#define WM8962_BIAS_ENA 0x0040 /* BIAS_ENA */
-#define WM8962_BIAS_ENA_MASK 0x0040 /* BIAS_ENA */
-#define WM8962_BIAS_ENA_SHIFT 6 /* BIAS_ENA */
-#define WM8962_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
-#define WM8962_INL_ENA 0x0020 /* INL_ENA */
-#define WM8962_INL_ENA_MASK 0x0020 /* INL_ENA */
-#define WM8962_INL_ENA_SHIFT 5 /* INL_ENA */
-#define WM8962_INL_ENA_WIDTH 1 /* INL_ENA */
-#define WM8962_INR_ENA 0x0010 /* INR_ENA */
-#define WM8962_INR_ENA_MASK 0x0010 /* INR_ENA */
-#define WM8962_INR_ENA_SHIFT 4 /* INR_ENA */
-#define WM8962_INR_ENA_WIDTH 1 /* INR_ENA */
-#define WM8962_ADCL_ENA 0x0008 /* ADCL_ENA */
-#define WM8962_ADCL_ENA_MASK 0x0008 /* ADCL_ENA */
-#define WM8962_ADCL_ENA_SHIFT 3 /* ADCL_ENA */
-#define WM8962_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
-#define WM8962_ADCR_ENA 0x0004 /* ADCR_ENA */
-#define WM8962_ADCR_ENA_MASK 0x0004 /* ADCR_ENA */
-#define WM8962_ADCR_ENA_SHIFT 2 /* ADCR_ENA */
-#define WM8962_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
-#define WM8962_MICBIAS_ENA 0x0002 /* MICBIAS_ENA */
-#define WM8962_MICBIAS_ENA_MASK 0x0002 /* MICBIAS_ENA */
-#define WM8962_MICBIAS_ENA_SHIFT 1 /* MICBIAS_ENA */
-#define WM8962_MICBIAS_ENA_WIDTH 1 /* MICBIAS_ENA */
-
-/*
- * R26 (0x1A) - Pwr Mgmt (2)
- */
-#define WM8962_DACL_ENA 0x0100 /* DACL_ENA */
-#define WM8962_DACL_ENA_MASK 0x0100 /* DACL_ENA */
-#define WM8962_DACL_ENA_SHIFT 8 /* DACL_ENA */
-#define WM8962_DACL_ENA_WIDTH 1 /* DACL_ENA */
-#define WM8962_DACR_ENA 0x0080 /* DACR_ENA */
-#define WM8962_DACR_ENA_MASK 0x0080 /* DACR_ENA */
-#define WM8962_DACR_ENA_SHIFT 7 /* DACR_ENA */
-#define WM8962_DACR_ENA_WIDTH 1 /* DACR_ENA */
-#define WM8962_HPOUTL_PGA_ENA 0x0040 /* HPOUTL_PGA_ENA */
-#define WM8962_HPOUTL_PGA_ENA_MASK 0x0040 /* HPOUTL_PGA_ENA */
-#define WM8962_HPOUTL_PGA_ENA_SHIFT 6 /* HPOUTL_PGA_ENA */
-#define WM8962_HPOUTL_PGA_ENA_WIDTH 1 /* HPOUTL_PGA_ENA */
-#define WM8962_HPOUTR_PGA_ENA 0x0020 /* HPOUTR_PGA_ENA */
-#define WM8962_HPOUTR_PGA_ENA_MASK 0x0020 /* HPOUTR_PGA_ENA */
-#define WM8962_HPOUTR_PGA_ENA_SHIFT 5 /* HPOUTR_PGA_ENA */
-#define WM8962_HPOUTR_PGA_ENA_WIDTH 1 /* HPOUTR_PGA_ENA */
-#define WM8962_SPKOUTL_PGA_ENA 0x0010 /* SPKOUTL_PGA_ENA */
-#define WM8962_SPKOUTL_PGA_ENA_MASK 0x0010 /* SPKOUTL_PGA_ENA */
-#define WM8962_SPKOUTL_PGA_ENA_SHIFT 4 /* SPKOUTL_PGA_ENA */
-#define WM8962_SPKOUTL_PGA_ENA_WIDTH 1 /* SPKOUTL_PGA_ENA */
-#define WM8962_SPKOUTR_PGA_ENA 0x0008 /* SPKOUTR_PGA_ENA */
-#define WM8962_SPKOUTR_PGA_ENA_MASK 0x0008 /* SPKOUTR_PGA_ENA */
-#define WM8962_SPKOUTR_PGA_ENA_SHIFT 3 /* SPKOUTR_PGA_ENA */
-#define WM8962_SPKOUTR_PGA_ENA_WIDTH 1 /* SPKOUTR_PGA_ENA */
-#define WM8962_HPOUTL_PGA_MUTE 0x0002 /* HPOUTL_PGA_MUTE */
-#define WM8962_HPOUTL_PGA_MUTE_MASK 0x0002 /* HPOUTL_PGA_MUTE */
-#define WM8962_HPOUTL_PGA_MUTE_SHIFT 1 /* HPOUTL_PGA_MUTE */
-#define WM8962_HPOUTL_PGA_MUTE_WIDTH 1 /* HPOUTL_PGA_MUTE */
-#define WM8962_HPOUTR_PGA_MUTE 0x0001 /* HPOUTR_PGA_MUTE */
-#define WM8962_HPOUTR_PGA_MUTE_MASK 0x0001 /* HPOUTR_PGA_MUTE */
-#define WM8962_HPOUTR_PGA_MUTE_SHIFT 0 /* HPOUTR_PGA_MUTE */
-#define WM8962_HPOUTR_PGA_MUTE_WIDTH 1 /* HPOUTR_PGA_MUTE */
-
-/*
- * R27 (0x1B) - Additional Control (3)
- */
-#define WM8962_SAMPLE_RATE_INT_MODE 0x0010 /* SAMPLE_RATE_INT_MODE */
-#define WM8962_SAMPLE_RATE_INT_MODE_MASK 0x0010 /* SAMPLE_RATE_INT_MODE */
-#define WM8962_SAMPLE_RATE_INT_MODE_SHIFT 4 /* SAMPLE_RATE_INT_MODE */
-#define WM8962_SAMPLE_RATE_INT_MODE_WIDTH 1 /* SAMPLE_RATE_INT_MODE */
-#define WM8962_SAMPLE_RATE_MASK 0x0007 /* SAMPLE_RATE - [2:0] */
-#define WM8962_SAMPLE_RATE_SHIFT 0 /* SAMPLE_RATE - [2:0] */
-#define WM8962_SAMPLE_RATE_WIDTH 3 /* SAMPLE_RATE - [2:0] */
-
-/*
- * R28 (0x1C) - Anti-pop
- */
-#define WM8962_STARTUP_BIAS_ENA 0x0010 /* STARTUP_BIAS_ENA */
-#define WM8962_STARTUP_BIAS_ENA_MASK 0x0010 /* STARTUP_BIAS_ENA */
-#define WM8962_STARTUP_BIAS_ENA_SHIFT 4 /* STARTUP_BIAS_ENA */
-#define WM8962_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */
-#define WM8962_VMID_BUF_ENA 0x0008 /* VMID_BUF_ENA */
-#define WM8962_VMID_BUF_ENA_MASK 0x0008 /* VMID_BUF_ENA */
-#define WM8962_VMID_BUF_ENA_SHIFT 3 /* VMID_BUF_ENA */
-#define WM8962_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
-#define WM8962_VMID_RAMP 0x0004 /* VMID_RAMP */
-#define WM8962_VMID_RAMP_MASK 0x0004 /* VMID_RAMP */
-#define WM8962_VMID_RAMP_SHIFT 2 /* VMID_RAMP */
-#define WM8962_VMID_RAMP_WIDTH 1 /* VMID_RAMP */
-
-/*
- * R30 (0x1E) - Clocking 3
- */
-#define WM8962_DBCLK_DIV_MASK 0xE000 /* DBCLK_DIV - [15:13] */
-#define WM8962_DBCLK_DIV_SHIFT 13 /* DBCLK_DIV - [15:13] */
-#define WM8962_DBCLK_DIV_WIDTH 3 /* DBCLK_DIV - [15:13] */
-#define WM8962_OPCLK_DIV_MASK 0x1C00 /* OPCLK_DIV - [12:10] */
-#define WM8962_OPCLK_DIV_SHIFT 10 /* OPCLK_DIV - [12:10] */
-#define WM8962_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [12:10] */
-#define WM8962_TOCLK_DIV_MASK 0x0380 /* TOCLK_DIV - [9:7] */
-#define WM8962_TOCLK_DIV_SHIFT 7 /* TOCLK_DIV - [9:7] */
-#define WM8962_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [9:7] */
-#define WM8962_F256KCLK_DIV_MASK 0x007E /* F256KCLK_DIV - [6:1] */
-#define WM8962_F256KCLK_DIV_SHIFT 1 /* F256KCLK_DIV - [6:1] */
-#define WM8962_F256KCLK_DIV_WIDTH 6 /* F256KCLK_DIV - [6:1] */
-
-/*
- * R31 (0x1F) - Input mixer control (1)
- */
-#define WM8962_MIXINL_MUTE 0x0008 /* MIXINL_MUTE */
-#define WM8962_MIXINL_MUTE_MASK 0x0008 /* MIXINL_MUTE */
-#define WM8962_MIXINL_MUTE_SHIFT 3 /* MIXINL_MUTE */
-#define WM8962_MIXINL_MUTE_WIDTH 1 /* MIXINL_MUTE */
-#define WM8962_MIXINR_MUTE 0x0004 /* MIXINR_MUTE */
-#define WM8962_MIXINR_MUTE_MASK 0x0004 /* MIXINR_MUTE */
-#define WM8962_MIXINR_MUTE_SHIFT 2 /* MIXINR_MUTE */
-#define WM8962_MIXINR_MUTE_WIDTH 1 /* MIXINR_MUTE */
-#define WM8962_MIXINL_ENA 0x0002 /* MIXINL_ENA */
-#define WM8962_MIXINL_ENA_MASK 0x0002 /* MIXINL_ENA */
-#define WM8962_MIXINL_ENA_SHIFT 1 /* MIXINL_ENA */
-#define WM8962_MIXINL_ENA_WIDTH 1 /* MIXINL_ENA */
-#define WM8962_MIXINR_ENA 0x0001 /* MIXINR_ENA */
-#define WM8962_MIXINR_ENA_MASK 0x0001 /* MIXINR_ENA */
-#define WM8962_MIXINR_ENA_SHIFT 0 /* MIXINR_ENA */
-#define WM8962_MIXINR_ENA_WIDTH 1 /* MIXINR_ENA */
-
-/*
- * R32 (0x20) - Left input mixer volume
- */
-#define WM8962_IN2L_MIXINL_VOL_MASK 0x01C0 /* IN2L_MIXINL_VOL - [8:6] */
-#define WM8962_IN2L_MIXINL_VOL_SHIFT 6 /* IN2L_MIXINL_VOL - [8:6] */
-#define WM8962_IN2L_MIXINL_VOL_WIDTH 3 /* IN2L_MIXINL_VOL - [8:6] */
-#define WM8962_INPGAL_MIXINL_VOL_MASK 0x0038 /* INPGAL_MIXINL_VOL - [5:3] */
-#define WM8962_INPGAL_MIXINL_VOL_SHIFT 3 /* INPGAL_MIXINL_VOL - [5:3] */
-#define WM8962_INPGAL_MIXINL_VOL_WIDTH 3 /* INPGAL_MIXINL_VOL - [5:3] */
-#define WM8962_IN3L_MIXINL_VOL_MASK 0x0007 /* IN3L_MIXINL_VOL - [2:0] */
-#define WM8962_IN3L_MIXINL_VOL_SHIFT 0 /* IN3L_MIXINL_VOL - [2:0] */
-#define WM8962_IN3L_MIXINL_VOL_WIDTH 3 /* IN3L_MIXINL_VOL - [2:0] */
-
-/*
- * R33 (0x21) - Right input mixer volume
- */
-#define WM8962_IN2R_MIXINR_VOL_MASK 0x01C0 /* IN2R_MIXINR_VOL - [8:6] */
-#define WM8962_IN2R_MIXINR_VOL_SHIFT 6 /* IN2R_MIXINR_VOL - [8:6] */
-#define WM8962_IN2R_MIXINR_VOL_WIDTH 3 /* IN2R_MIXINR_VOL - [8:6] */
-#define WM8962_INPGAR_MIXINR_VOL_MASK 0x0038 /* INPGAR_MIXINR_VOL - [5:3] */
-#define WM8962_INPGAR_MIXINR_VOL_SHIFT 3 /* INPGAR_MIXINR_VOL - [5:3] */
-#define WM8962_INPGAR_MIXINR_VOL_WIDTH 3 /* INPGAR_MIXINR_VOL - [5:3] */
-#define WM8962_IN3R_MIXINR_VOL_MASK 0x0007 /* IN3R_MIXINR_VOL - [2:0] */
-#define WM8962_IN3R_MIXINR_VOL_SHIFT 0 /* IN3R_MIXINR_VOL - [2:0] */
-#define WM8962_IN3R_MIXINR_VOL_WIDTH 3 /* IN3R_MIXINR_VOL - [2:0] */
-
-/*
- * R34 (0x22) - Input mixer control (2)
- */
-#define WM8962_IN2L_TO_MIXINL 0x0020 /* IN2L_TO_MIXINL */
-#define WM8962_IN2L_TO_MIXINL_MASK 0x0020 /* IN2L_TO_MIXINL */
-#define WM8962_IN2L_TO_MIXINL_SHIFT 5 /* IN2L_TO_MIXINL */
-#define WM8962_IN2L_TO_MIXINL_WIDTH 1 /* IN2L_TO_MIXINL */
-#define WM8962_IN3L_TO_MIXINL 0x0010 /* IN3L_TO_MIXINL */
-#define WM8962_IN3L_TO_MIXINL_MASK 0x0010 /* IN3L_TO_MIXINL */
-#define WM8962_IN3L_TO_MIXINL_SHIFT 4 /* IN3L_TO_MIXINL */
-#define WM8962_IN3L_TO_MIXINL_WIDTH 1 /* IN3L_TO_MIXINL */
-#define WM8962_INPGAL_TO_MIXINL 0x0008 /* INPGAL_TO_MIXINL */
-#define WM8962_INPGAL_TO_MIXINL_MASK 0x0008 /* INPGAL_TO_MIXINL */
-#define WM8962_INPGAL_TO_MIXINL_SHIFT 3 /* INPGAL_TO_MIXINL */
-#define WM8962_INPGAL_TO_MIXINL_WIDTH 1 /* INPGAL_TO_MIXINL */
-#define WM8962_IN2R_TO_MIXINR 0x0004 /* IN2R_TO_MIXINR */
-#define WM8962_IN2R_TO_MIXINR_MASK 0x0004 /* IN2R_TO_MIXINR */
-#define WM8962_IN2R_TO_MIXINR_SHIFT 2 /* IN2R_TO_MIXINR */
-#define WM8962_IN2R_TO_MIXINR_WIDTH 1 /* IN2R_TO_MIXINR */
-#define WM8962_IN3R_TO_MIXINR 0x0002 /* IN3R_TO_MIXINR */
-#define WM8962_IN3R_TO_MIXINR_MASK 0x0002 /* IN3R_TO_MIXINR */
-#define WM8962_IN3R_TO_MIXINR_SHIFT 1 /* IN3R_TO_MIXINR */
-#define WM8962_IN3R_TO_MIXINR_WIDTH 1 /* IN3R_TO_MIXINR */
-#define WM8962_INPGAR_TO_MIXINR 0x0001 /* INPGAR_TO_MIXINR */
-#define WM8962_INPGAR_TO_MIXINR_MASK 0x0001 /* INPGAR_TO_MIXINR */
-#define WM8962_INPGAR_TO_MIXINR_SHIFT 0 /* INPGAR_TO_MIXINR */
-#define WM8962_INPGAR_TO_MIXINR_WIDTH 1 /* INPGAR_TO_MIXINR */
-
-/*
- * R35 (0x23) - Input bias control
- */
-#define WM8962_MIXIN_BIAS_MASK 0x0038 /* MIXIN_BIAS - [5:3] */
-#define WM8962_MIXIN_BIAS_SHIFT 3 /* MIXIN_BIAS - [5:3] */
-#define WM8962_MIXIN_BIAS_WIDTH 3 /* MIXIN_BIAS - [5:3] */
-#define WM8962_INPGA_BIAS_MASK 0x0007 /* INPGA_BIAS - [2:0] */
-#define WM8962_INPGA_BIAS_SHIFT 0 /* INPGA_BIAS - [2:0] */
-#define WM8962_INPGA_BIAS_WIDTH 3 /* INPGA_BIAS - [2:0] */
-
-/*
- * R37 (0x25) - Left input PGA control
- */
-#define WM8962_INPGAL_ENA 0x0010 /* INPGAL_ENA */
-#define WM8962_INPGAL_ENA_MASK 0x0010 /* INPGAL_ENA */
-#define WM8962_INPGAL_ENA_SHIFT 4 /* INPGAL_ENA */
-#define WM8962_INPGAL_ENA_WIDTH 1 /* INPGAL_ENA */
-#define WM8962_IN1L_TO_INPGAL 0x0008 /* IN1L_TO_INPGAL */
-#define WM8962_IN1L_TO_INPGAL_MASK 0x0008 /* IN1L_TO_INPGAL */
-#define WM8962_IN1L_TO_INPGAL_SHIFT 3 /* IN1L_TO_INPGAL */
-#define WM8962_IN1L_TO_INPGAL_WIDTH 1 /* IN1L_TO_INPGAL */
-#define WM8962_IN2L_TO_INPGAL 0x0004 /* IN2L_TO_INPGAL */
-#define WM8962_IN2L_TO_INPGAL_MASK 0x0004 /* IN2L_TO_INPGAL */
-#define WM8962_IN2L_TO_INPGAL_SHIFT 2 /* IN2L_TO_INPGAL */
-#define WM8962_IN2L_TO_INPGAL_WIDTH 1 /* IN2L_TO_INPGAL */
-#define WM8962_IN3L_TO_INPGAL 0x0002 /* IN3L_TO_INPGAL */
-#define WM8962_IN3L_TO_INPGAL_MASK 0x0002 /* IN3L_TO_INPGAL */
-#define WM8962_IN3L_TO_INPGAL_SHIFT 1 /* IN3L_TO_INPGAL */
-#define WM8962_IN3L_TO_INPGAL_WIDTH 1 /* IN3L_TO_INPGAL */
-#define WM8962_IN4L_TO_INPGAL 0x0001 /* IN4L_TO_INPGAL */
-#define WM8962_IN4L_TO_INPGAL_MASK 0x0001 /* IN4L_TO_INPGAL */
-#define WM8962_IN4L_TO_INPGAL_SHIFT 0 /* IN4L_TO_INPGAL */
-#define WM8962_IN4L_TO_INPGAL_WIDTH 1 /* IN4L_TO_INPGAL */
-
-/*
- * R38 (0x26) - Right input PGA control
- */
-#define WM8962_INPGAR_ENA 0x0010 /* INPGAR_ENA */
-#define WM8962_INPGAR_ENA_MASK 0x0010 /* INPGAR_ENA */
-#define WM8962_INPGAR_ENA_SHIFT 4 /* INPGAR_ENA */
-#define WM8962_INPGAR_ENA_WIDTH 1 /* INPGAR_ENA */
-#define WM8962_IN1R_TO_INPGAR 0x0008 /* IN1R_TO_INPGAR */
-#define WM8962_IN1R_TO_INPGAR_MASK 0x0008 /* IN1R_TO_INPGAR */
-#define WM8962_IN1R_TO_INPGAR_SHIFT 3 /* IN1R_TO_INPGAR */
-#define WM8962_IN1R_TO_INPGAR_WIDTH 1 /* IN1R_TO_INPGAR */
-#define WM8962_IN2R_TO_INPGAR 0x0004 /* IN2R_TO_INPGAR */
-#define WM8962_IN2R_TO_INPGAR_MASK 0x0004 /* IN2R_TO_INPGAR */
-#define WM8962_IN2R_TO_INPGAR_SHIFT 2 /* IN2R_TO_INPGAR */
-#define WM8962_IN2R_TO_INPGAR_WIDTH 1 /* IN2R_TO_INPGAR */
-#define WM8962_IN3R_TO_INPGAR 0x0002 /* IN3R_TO_INPGAR */
-#define WM8962_IN3R_TO_INPGAR_MASK 0x0002 /* IN3R_TO_INPGAR */
-#define WM8962_IN3R_TO_INPGAR_SHIFT 1 /* IN3R_TO_INPGAR */
-#define WM8962_IN3R_TO_INPGAR_WIDTH 1 /* IN3R_TO_INPGAR */
-#define WM8962_IN4R_TO_INPGAR 0x0001 /* IN4R_TO_INPGAR */
-#define WM8962_IN4R_TO_INPGAR_MASK 0x0001 /* IN4R_TO_INPGAR */
-#define WM8962_IN4R_TO_INPGAR_SHIFT 0 /* IN4R_TO_INPGAR */
-#define WM8962_IN4R_TO_INPGAR_WIDTH 1 /* IN4R_TO_INPGAR */
-
-/*
- * R40 (0x28) - SPKOUTL volume
- */
-#define WM8962_SPKOUT_VU 0x0100 /* SPKOUT_VU */
-#define WM8962_SPKOUT_VU_MASK 0x0100 /* SPKOUT_VU */
-#define WM8962_SPKOUT_VU_SHIFT 8 /* SPKOUT_VU */
-#define WM8962_SPKOUT_VU_WIDTH 1 /* SPKOUT_VU */
-#define WM8962_SPKOUTL_ZC 0x0080 /* SPKOUTL_ZC */
-#define WM8962_SPKOUTL_ZC_MASK 0x0080 /* SPKOUTL_ZC */
-#define WM8962_SPKOUTL_ZC_SHIFT 7 /* SPKOUTL_ZC */
-#define WM8962_SPKOUTL_ZC_WIDTH 1 /* SPKOUTL_ZC */
-#define WM8962_SPKOUTL_VOL_MASK 0x007F /* SPKOUTL_VOL - [6:0] */
-#define WM8962_SPKOUTL_VOL_SHIFT 0 /* SPKOUTL_VOL - [6:0] */
-#define WM8962_SPKOUTL_VOL_WIDTH 7 /* SPKOUTL_VOL - [6:0] */
-
-/*
- * R41 (0x29) - SPKOUTR volume
- */
-#define WM8962_SPKOUTR_ZC 0x0080 /* SPKOUTR_ZC */
-#define WM8962_SPKOUTR_ZC_MASK 0x0080 /* SPKOUTR_ZC */
-#define WM8962_SPKOUTR_ZC_SHIFT 7 /* SPKOUTR_ZC */
-#define WM8962_SPKOUTR_ZC_WIDTH 1 /* SPKOUTR_ZC */
-#define WM8962_SPKOUTR_VOL_MASK 0x007F /* SPKOUTR_VOL - [6:0] */
-#define WM8962_SPKOUTR_VOL_SHIFT 0 /* SPKOUTR_VOL - [6:0] */
-#define WM8962_SPKOUTR_VOL_WIDTH 7 /* SPKOUTR_VOL - [6:0] */
-
-/*
- * R47 (0x2F) - Thermal Shutdown Status
- */
-#define WM8962_TEMP_ERR_HP 0x0008 /* TEMP_ERR_HP */
-#define WM8962_TEMP_ERR_HP_MASK 0x0008 /* TEMP_ERR_HP */
-#define WM8962_TEMP_ERR_HP_SHIFT 3 /* TEMP_ERR_HP */
-#define WM8962_TEMP_ERR_HP_WIDTH 1 /* TEMP_ERR_HP */
-#define WM8962_TEMP_WARN_HP 0x0004 /* TEMP_WARN_HP */
-#define WM8962_TEMP_WARN_HP_MASK 0x0004 /* TEMP_WARN_HP */
-#define WM8962_TEMP_WARN_HP_SHIFT 2 /* TEMP_WARN_HP */
-#define WM8962_TEMP_WARN_HP_WIDTH 1 /* TEMP_WARN_HP */
-#define WM8962_TEMP_ERR_SPK 0x0002 /* TEMP_ERR_SPK */
-#define WM8962_TEMP_ERR_SPK_MASK 0x0002 /* TEMP_ERR_SPK */
-#define WM8962_TEMP_ERR_SPK_SHIFT 1 /* TEMP_ERR_SPK */
-#define WM8962_TEMP_ERR_SPK_WIDTH 1 /* TEMP_ERR_SPK */
-#define WM8962_TEMP_WARN_SPK 0x0001 /* TEMP_WARN_SPK */
-#define WM8962_TEMP_WARN_SPK_MASK 0x0001 /* TEMP_WARN_SPK */
-#define WM8962_TEMP_WARN_SPK_SHIFT 0 /* TEMP_WARN_SPK */
-#define WM8962_TEMP_WARN_SPK_WIDTH 1 /* TEMP_WARN_SPK */
-
-/*
- * R48 (0x30) - Additional Control (4)
- */
-#define WM8962_MICDET_THR_MASK 0x7000 /* MICDET_THR - [14:12] */
-#define WM8962_MICDET_THR_SHIFT 12 /* MICDET_THR - [14:12] */
-#define WM8962_MICDET_THR_WIDTH 3 /* MICDET_THR - [14:12] */
-#define WM8962_MICSHORT_THR_MASK 0x0C00 /* MICSHORT_THR - [11:10] */
-#define WM8962_MICSHORT_THR_SHIFT 10 /* MICSHORT_THR - [11:10] */
-#define WM8962_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [11:10] */
-#define WM8962_MICDET_ENA 0x0200 /* MICDET_ENA */
-#define WM8962_MICDET_ENA_MASK 0x0200 /* MICDET_ENA */
-#define WM8962_MICDET_ENA_SHIFT 9 /* MICDET_ENA */
-#define WM8962_MICDET_ENA_WIDTH 1 /* MICDET_ENA */
-#define WM8962_MICDET_STS 0x0080 /* MICDET_STS */
-#define WM8962_MICDET_STS_MASK 0x0080 /* MICDET_STS */
-#define WM8962_MICDET_STS_SHIFT 7 /* MICDET_STS */
-#define WM8962_MICDET_STS_WIDTH 1 /* MICDET_STS */
-#define WM8962_MICSHORT_STS 0x0040 /* MICSHORT_STS */
-#define WM8962_MICSHORT_STS_MASK 0x0040 /* MICSHORT_STS */
-#define WM8962_MICSHORT_STS_SHIFT 6 /* MICSHORT_STS */
-#define WM8962_MICSHORT_STS_WIDTH 1 /* MICSHORT_STS */
-#define WM8962_TEMP_ENA_HP 0x0004 /* TEMP_ENA_HP */
-#define WM8962_TEMP_ENA_HP_MASK 0x0004 /* TEMP_ENA_HP */
-#define WM8962_TEMP_ENA_HP_SHIFT 2 /* TEMP_ENA_HP */
-#define WM8962_TEMP_ENA_HP_WIDTH 1 /* TEMP_ENA_HP */
-#define WM8962_TEMP_ENA_SPK 0x0002 /* TEMP_ENA_SPK */
-#define WM8962_TEMP_ENA_SPK_MASK 0x0002 /* TEMP_ENA_SPK */
-#define WM8962_TEMP_ENA_SPK_SHIFT 1 /* TEMP_ENA_SPK */
-#define WM8962_TEMP_ENA_SPK_WIDTH 1 /* TEMP_ENA_SPK */
-#define WM8962_MICBIAS_LVL 0x0001 /* MICBIAS_LVL */
-#define WM8962_MICBIAS_LVL_MASK 0x0001 /* MICBIAS_LVL */
-#define WM8962_MICBIAS_LVL_SHIFT 0 /* MICBIAS_LVL */
-#define WM8962_MICBIAS_LVL_WIDTH 1 /* MICBIAS_LVL */
-
-/*
- * R49 (0x31) - Class D Control 1
- */
-#define WM8962_SPKOUTR_ENA 0x0080 /* SPKOUTR_ENA */
-#define WM8962_SPKOUTR_ENA_MASK 0x0080 /* SPKOUTR_ENA */
-#define WM8962_SPKOUTR_ENA_SHIFT 7 /* SPKOUTR_ENA */
-#define WM8962_SPKOUTR_ENA_WIDTH 1 /* SPKOUTR_ENA */
-#define WM8962_SPKOUTL_ENA 0x0040 /* SPKOUTL_ENA */
-#define WM8962_SPKOUTL_ENA_MASK 0x0040 /* SPKOUTL_ENA */
-#define WM8962_SPKOUTL_ENA_SHIFT 6 /* SPKOUTL_ENA */
-#define WM8962_SPKOUTL_ENA_WIDTH 1 /* SPKOUTL_ENA */
-#define WM8962_SPKOUTL_PGA_MUTE 0x0002 /* SPKOUTL_PGA_MUTE */
-#define WM8962_SPKOUTL_PGA_MUTE_MASK 0x0002 /* SPKOUTL_PGA_MUTE */
-#define WM8962_SPKOUTL_PGA_MUTE_SHIFT 1 /* SPKOUTL_PGA_MUTE */
-#define WM8962_SPKOUTL_PGA_MUTE_WIDTH 1 /* SPKOUTL_PGA_MUTE */
-#define WM8962_SPKOUTR_PGA_MUTE 0x0001 /* SPKOUTR_PGA_MUTE */
-#define WM8962_SPKOUTR_PGA_MUTE_MASK 0x0001 /* SPKOUTR_PGA_MUTE */
-#define WM8962_SPKOUTR_PGA_MUTE_SHIFT 0 /* SPKOUTR_PGA_MUTE */
-#define WM8962_SPKOUTR_PGA_MUTE_WIDTH 1 /* SPKOUTR_PGA_MUTE */
-
-/*
- * R51 (0x33) - Class D Control 2
- */
-#define WM8962_SPK_MONO 0x0040 /* SPK_MONO */
-#define WM8962_SPK_MONO_MASK 0x0040 /* SPK_MONO */
-#define WM8962_SPK_MONO_SHIFT 6 /* SPK_MONO */
-#define WM8962_SPK_MONO_WIDTH 1 /* SPK_MONO */
-#define WM8962_CLASSD_VOL_MASK 0x0007 /* CLASSD_VOL - [2:0] */
-#define WM8962_CLASSD_VOL_SHIFT 0 /* CLASSD_VOL - [2:0] */
-#define WM8962_CLASSD_VOL_WIDTH 3 /* CLASSD_VOL - [2:0] */
-
-/*
- * R56 (0x38) - Clocking 4
- */
-#define WM8962_SYSCLK_RATE_MASK 0x001E /* SYSCLK_RATE - [4:1] */
-#define WM8962_SYSCLK_RATE_SHIFT 1 /* SYSCLK_RATE - [4:1] */
-#define WM8962_SYSCLK_RATE_WIDTH 4 /* SYSCLK_RATE - [4:1] */
-
-/*
- * R57 (0x39) - DAC DSP Mixing (1)
- */
-#define WM8962_DAC_MONOMIX 0x0200 /* DAC_MONOMIX */
-#define WM8962_DAC_MONOMIX_MASK 0x0200 /* DAC_MONOMIX */
-#define WM8962_DAC_MONOMIX_SHIFT 9 /* DAC_MONOMIX */
-#define WM8962_DAC_MONOMIX_WIDTH 1 /* DAC_MONOMIX */
-#define WM8962_ADCR_DAC_SVOL_MASK 0x00F0 /* ADCR_DAC_SVOL - [7:4] */
-#define WM8962_ADCR_DAC_SVOL_SHIFT 4 /* ADCR_DAC_SVOL - [7:4] */
-#define WM8962_ADCR_DAC_SVOL_WIDTH 4 /* ADCR_DAC_SVOL - [7:4] */
-#define WM8962_ADC_TO_DACR_MASK 0x000C /* ADC_TO_DACR - [3:2] */
-#define WM8962_ADC_TO_DACR_SHIFT 2 /* ADC_TO_DACR - [3:2] */
-#define WM8962_ADC_TO_DACR_WIDTH 2 /* ADC_TO_DACR - [3:2] */
-
-/*
- * R58 (0x3A) - DAC DSP Mixing (2)
- */
-#define WM8962_ADCL_DAC_SVOL_MASK 0x00F0 /* ADCL_DAC_SVOL - [7:4] */
-#define WM8962_ADCL_DAC_SVOL_SHIFT 4 /* ADCL_DAC_SVOL - [7:4] */
-#define WM8962_ADCL_DAC_SVOL_WIDTH 4 /* ADCL_DAC_SVOL - [7:4] */
-#define WM8962_ADC_TO_DACL_MASK 0x000C /* ADC_TO_DACL - [3:2] */
-#define WM8962_ADC_TO_DACL_SHIFT 2 /* ADC_TO_DACL - [3:2] */
-#define WM8962_ADC_TO_DACL_WIDTH 2 /* ADC_TO_DACL - [3:2] */
-
-/*
- * R60 (0x3C) - DC Servo 0
- */
-#define WM8962_INL_DCS_ENA 0x0080 /* INL_DCS_ENA */
-#define WM8962_INL_DCS_ENA_MASK 0x0080 /* INL_DCS_ENA */
-#define WM8962_INL_DCS_ENA_SHIFT 7 /* INL_DCS_ENA */
-#define WM8962_INL_DCS_ENA_WIDTH 1 /* INL_DCS_ENA */
-#define WM8962_INL_DCS_STARTUP 0x0040 /* INL_DCS_STARTUP */
-#define WM8962_INL_DCS_STARTUP_MASK 0x0040 /* INL_DCS_STARTUP */
-#define WM8962_INL_DCS_STARTUP_SHIFT 6 /* INL_DCS_STARTUP */
-#define WM8962_INL_DCS_STARTUP_WIDTH 1 /* INL_DCS_STARTUP */
-#define WM8962_INR_DCS_ENA 0x0008 /* INR_DCS_ENA */
-#define WM8962_INR_DCS_ENA_MASK 0x0008 /* INR_DCS_ENA */
-#define WM8962_INR_DCS_ENA_SHIFT 3 /* INR_DCS_ENA */
-#define WM8962_INR_DCS_ENA_WIDTH 1 /* INR_DCS_ENA */
-#define WM8962_INR_DCS_STARTUP 0x0004 /* INR_DCS_STARTUP */
-#define WM8962_INR_DCS_STARTUP_MASK 0x0004 /* INR_DCS_STARTUP */
-#define WM8962_INR_DCS_STARTUP_SHIFT 2 /* INR_DCS_STARTUP */
-#define WM8962_INR_DCS_STARTUP_WIDTH 1 /* INR_DCS_STARTUP */
-
-/*
- * R61 (0x3D) - DC Servo 1
- */
-#define WM8962_HP1L_DCS_ENA 0x0080 /* HP1L_DCS_ENA */
-#define WM8962_HP1L_DCS_ENA_MASK 0x0080 /* HP1L_DCS_ENA */
-#define WM8962_HP1L_DCS_ENA_SHIFT 7 /* HP1L_DCS_ENA */
-#define WM8962_HP1L_DCS_ENA_WIDTH 1 /* HP1L_DCS_ENA */
-#define WM8962_HP1L_DCS_STARTUP 0x0040 /* HP1L_DCS_STARTUP */
-#define WM8962_HP1L_DCS_STARTUP_MASK 0x0040 /* HP1L_DCS_STARTUP */
-#define WM8962_HP1L_DCS_STARTUP_SHIFT 6 /* HP1L_DCS_STARTUP */
-#define WM8962_HP1L_DCS_STARTUP_WIDTH 1 /* HP1L_DCS_STARTUP */
-#define WM8962_HP1L_DCS_SYNC 0x0010 /* HP1L_DCS_SYNC */
-#define WM8962_HP1L_DCS_SYNC_MASK 0x0010 /* HP1L_DCS_SYNC */
-#define WM8962_HP1L_DCS_SYNC_SHIFT 4 /* HP1L_DCS_SYNC */
-#define WM8962_HP1L_DCS_SYNC_WIDTH 1 /* HP1L_DCS_SYNC */
-#define WM8962_HP1R_DCS_ENA 0x0008 /* HP1R_DCS_ENA */
-#define WM8962_HP1R_DCS_ENA_MASK 0x0008 /* HP1R_DCS_ENA */
-#define WM8962_HP1R_DCS_ENA_SHIFT 3 /* HP1R_DCS_ENA */
-#define WM8962_HP1R_DCS_ENA_WIDTH 1 /* HP1R_DCS_ENA */
-#define WM8962_HP1R_DCS_STARTUP 0x0004 /* HP1R_DCS_STARTUP */
-#define WM8962_HP1R_DCS_STARTUP_MASK 0x0004 /* HP1R_DCS_STARTUP */
-#define WM8962_HP1R_DCS_STARTUP_SHIFT 2 /* HP1R_DCS_STARTUP */
-#define WM8962_HP1R_DCS_STARTUP_WIDTH 1 /* HP1R_DCS_STARTUP */
-#define WM8962_HP1R_DCS_SYNC 0x0001 /* HP1R_DCS_SYNC */
-#define WM8962_HP1R_DCS_SYNC_MASK 0x0001 /* HP1R_DCS_SYNC */
-#define WM8962_HP1R_DCS_SYNC_SHIFT 0 /* HP1R_DCS_SYNC */
-#define WM8962_HP1R_DCS_SYNC_WIDTH 1 /* HP1R_DCS_SYNC */
-
-/*
- * R64 (0x40) - DC Servo 4
- */
-#define WM8962_HP1_DCS_SYNC_STEPS_MASK 0x3F80 /* HP1_DCS_SYNC_STEPS - [13:7] */
-#define WM8962_HP1_DCS_SYNC_STEPS_SHIFT 7 /* HP1_DCS_SYNC_STEPS - [13:7] */
-#define WM8962_HP1_DCS_SYNC_STEPS_WIDTH 7 /* HP1_DCS_SYNC_STEPS - [13:7] */
-
-/*
- * R66 (0x42) - DC Servo 6
- */
-#define WM8962_DCS_STARTUP_DONE_INL 0x0400 /* DCS_STARTUP_DONE_INL */
-#define WM8962_DCS_STARTUP_DONE_INL_MASK 0x0400 /* DCS_STARTUP_DONE_INL */
-#define WM8962_DCS_STARTUP_DONE_INL_SHIFT 10 /* DCS_STARTUP_DONE_INL */
-#define WM8962_DCS_STARTUP_DONE_INL_WIDTH 1 /* DCS_STARTUP_DONE_INL */
-#define WM8962_DCS_STARTUP_DONE_INR 0x0200 /* DCS_STARTUP_DONE_INR */
-#define WM8962_DCS_STARTUP_DONE_INR_MASK 0x0200 /* DCS_STARTUP_DONE_INR */
-#define WM8962_DCS_STARTUP_DONE_INR_SHIFT 9 /* DCS_STARTUP_DONE_INR */
-#define WM8962_DCS_STARTUP_DONE_INR_WIDTH 1 /* DCS_STARTUP_DONE_INR */
-#define WM8962_DCS_STARTUP_DONE_HP1L 0x0100 /* DCS_STARTUP_DONE_HP1L */
-#define WM8962_DCS_STARTUP_DONE_HP1L_MASK 0x0100 /* DCS_STARTUP_DONE_HP1L */
-#define WM8962_DCS_STARTUP_DONE_HP1L_SHIFT 8 /* DCS_STARTUP_DONE_HP1L */
-#define WM8962_DCS_STARTUP_DONE_HP1L_WIDTH 1 /* DCS_STARTUP_DONE_HP1L */
-#define WM8962_DCS_STARTUP_DONE_HP1R 0x0080 /* DCS_STARTUP_DONE_HP1R */
-#define WM8962_DCS_STARTUP_DONE_HP1R_MASK 0x0080 /* DCS_STARTUP_DONE_HP1R */
-#define WM8962_DCS_STARTUP_DONE_HP1R_SHIFT 7 /* DCS_STARTUP_DONE_HP1R */
-#define WM8962_DCS_STARTUP_DONE_HP1R_WIDTH 1 /* DCS_STARTUP_DONE_HP1R */
-
-/*
- * R68 (0x44) - Analogue PGA Bias
- */
-#define WM8962_HP_PGAS_BIAS_MASK 0x0007 /* HP_PGAS_BIAS - [2:0] */
-#define WM8962_HP_PGAS_BIAS_SHIFT 0 /* HP_PGAS_BIAS - [2:0] */
-#define WM8962_HP_PGAS_BIAS_WIDTH 3 /* HP_PGAS_BIAS - [2:0] */
-
-/*
- * R69 (0x45) - Analogue HP 0
- */
-#define WM8962_HP1L_RMV_SHORT 0x0080 /* HP1L_RMV_SHORT */
-#define WM8962_HP1L_RMV_SHORT_MASK 0x0080 /* HP1L_RMV_SHORT */
-#define WM8962_HP1L_RMV_SHORT_SHIFT 7 /* HP1L_RMV_SHORT */
-#define WM8962_HP1L_RMV_SHORT_WIDTH 1 /* HP1L_RMV_SHORT */
-#define WM8962_HP1L_ENA_OUTP 0x0040 /* HP1L_ENA_OUTP */
-#define WM8962_HP1L_ENA_OUTP_MASK 0x0040 /* HP1L_ENA_OUTP */
-#define WM8962_HP1L_ENA_OUTP_SHIFT 6 /* HP1L_ENA_OUTP */
-#define WM8962_HP1L_ENA_OUTP_WIDTH 1 /* HP1L_ENA_OUTP */
-#define WM8962_HP1L_ENA_DLY 0x0020 /* HP1L_ENA_DLY */
-#define WM8962_HP1L_ENA_DLY_MASK 0x0020 /* HP1L_ENA_DLY */
-#define WM8962_HP1L_ENA_DLY_SHIFT 5 /* HP1L_ENA_DLY */
-#define WM8962_HP1L_ENA_DLY_WIDTH 1 /* HP1L_ENA_DLY */
-#define WM8962_HP1L_ENA 0x0010 /* HP1L_ENA */
-#define WM8962_HP1L_ENA_MASK 0x0010 /* HP1L_ENA */
-#define WM8962_HP1L_ENA_SHIFT 4 /* HP1L_ENA */
-#define WM8962_HP1L_ENA_WIDTH 1 /* HP1L_ENA */
-#define WM8962_HP1R_RMV_SHORT 0x0008 /* HP1R_RMV_SHORT */
-#define WM8962_HP1R_RMV_SHORT_MASK 0x0008 /* HP1R_RMV_SHORT */
-#define WM8962_HP1R_RMV_SHORT_SHIFT 3 /* HP1R_RMV_SHORT */
-#define WM8962_HP1R_RMV_SHORT_WIDTH 1 /* HP1R_RMV_SHORT */
-#define WM8962_HP1R_ENA_OUTP 0x0004 /* HP1R_ENA_OUTP */
-#define WM8962_HP1R_ENA_OUTP_MASK 0x0004 /* HP1R_ENA_OUTP */
-#define WM8962_HP1R_ENA_OUTP_SHIFT 2 /* HP1R_ENA_OUTP */
-#define WM8962_HP1R_ENA_OUTP_WIDTH 1 /* HP1R_ENA_OUTP */
-#define WM8962_HP1R_ENA_DLY 0x0002 /* HP1R_ENA_DLY */
-#define WM8962_HP1R_ENA_DLY_MASK 0x0002 /* HP1R_ENA_DLY */
-#define WM8962_HP1R_ENA_DLY_SHIFT 1 /* HP1R_ENA_DLY */
-#define WM8962_HP1R_ENA_DLY_WIDTH 1 /* HP1R_ENA_DLY */
-#define WM8962_HP1R_ENA 0x0001 /* HP1R_ENA */
-#define WM8962_HP1R_ENA_MASK 0x0001 /* HP1R_ENA */
-#define WM8962_HP1R_ENA_SHIFT 0 /* HP1R_ENA */
-#define WM8962_HP1R_ENA_WIDTH 1 /* HP1R_ENA */
-
-/*
- * R71 (0x47) - Analogue HP 2
- */
-#define WM8962_HP1L_VOL_MASK 0x01C0 /* HP1L_VOL - [8:6] */
-#define WM8962_HP1L_VOL_SHIFT 6 /* HP1L_VOL - [8:6] */
-#define WM8962_HP1L_VOL_WIDTH 3 /* HP1L_VOL - [8:6] */
-#define WM8962_HP1R_VOL_MASK 0x0038 /* HP1R_VOL - [5:3] */
-#define WM8962_HP1R_VOL_SHIFT 3 /* HP1R_VOL - [5:3] */
-#define WM8962_HP1R_VOL_WIDTH 3 /* HP1R_VOL - [5:3] */
-#define WM8962_HP_BIAS_BOOST_MASK 0x0007 /* HP_BIAS_BOOST - [2:0] */
-#define WM8962_HP_BIAS_BOOST_SHIFT 0 /* HP_BIAS_BOOST - [2:0] */
-#define WM8962_HP_BIAS_BOOST_WIDTH 3 /* HP_BIAS_BOOST - [2:0] */
-
-/*
- * R72 (0x48) - Charge Pump 1
- */
-#define WM8962_CP_ENA 0x0001 /* CP_ENA */
-#define WM8962_CP_ENA_MASK 0x0001 /* CP_ENA */
-#define WM8962_CP_ENA_SHIFT 0 /* CP_ENA */
-#define WM8962_CP_ENA_WIDTH 1 /* CP_ENA */
-
-/*
- * R82 (0x52) - Charge Pump B
- */
-#define WM8962_CP_DYN_PWR 0x0001 /* CP_DYN_PWR */
-#define WM8962_CP_DYN_PWR_MASK 0x0001 /* CP_DYN_PWR */
-#define WM8962_CP_DYN_PWR_SHIFT 0 /* CP_DYN_PWR */
-#define WM8962_CP_DYN_PWR_WIDTH 1 /* CP_DYN_PWR */
-
-/*
- * R87 (0x57) - Write Sequencer Control 1
- */
-#define WM8962_WSEQ_AUTOSEQ_ENA 0x0080 /* WSEQ_AUTOSEQ_ENA */
-#define WM8962_WSEQ_AUTOSEQ_ENA_MASK 0x0080 /* WSEQ_AUTOSEQ_ENA */
-#define WM8962_WSEQ_AUTOSEQ_ENA_SHIFT 7 /* WSEQ_AUTOSEQ_ENA */
-#define WM8962_WSEQ_AUTOSEQ_ENA_WIDTH 1 /* WSEQ_AUTOSEQ_ENA */
-#define WM8962_WSEQ_ENA 0x0020 /* WSEQ_ENA */
-#define WM8962_WSEQ_ENA_MASK 0x0020 /* WSEQ_ENA */
-#define WM8962_WSEQ_ENA_SHIFT 5 /* WSEQ_ENA */
-#define WM8962_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
-
-/*
- * R90 (0x5A) - Write Sequencer Control 2
- */
-#define WM8962_WSEQ_ABORT 0x0100 /* WSEQ_ABORT */
-#define WM8962_WSEQ_ABORT_MASK 0x0100 /* WSEQ_ABORT */
-#define WM8962_WSEQ_ABORT_SHIFT 8 /* WSEQ_ABORT */
-#define WM8962_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
-#define WM8962_WSEQ_START 0x0080 /* WSEQ_START */
-#define WM8962_WSEQ_START_MASK 0x0080 /* WSEQ_START */
-#define WM8962_WSEQ_START_SHIFT 7 /* WSEQ_START */
-#define WM8962_WSEQ_START_WIDTH 1 /* WSEQ_START */
-#define WM8962_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */
-#define WM8962_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */
-#define WM8962_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */
-
-/*
- * R93 (0x5D) - Write Sequencer Control 3
- */
-#define WM8962_WSEQ_CURRENT_INDEX_MASK 0x03F8 /* WSEQ_CURRENT_INDEX - [9:3] */
-#define WM8962_WSEQ_CURRENT_INDEX_SHIFT 3 /* WSEQ_CURRENT_INDEX - [9:3] */
-#define WM8962_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [9:3] */
-#define WM8962_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
-#define WM8962_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
-#define WM8962_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
-#define WM8962_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
-
-/*
- * R94 (0x5E) - Control Interface
- */
-#define WM8962_SPI_CONTRD 0x0040 /* SPI_CONTRD */
-#define WM8962_SPI_CONTRD_MASK 0x0040 /* SPI_CONTRD */
-#define WM8962_SPI_CONTRD_SHIFT 6 /* SPI_CONTRD */
-#define WM8962_SPI_CONTRD_WIDTH 1 /* SPI_CONTRD */
-#define WM8962_SPI_4WIRE 0x0020 /* SPI_4WIRE */
-#define WM8962_SPI_4WIRE_MASK 0x0020 /* SPI_4WIRE */
-#define WM8962_SPI_4WIRE_SHIFT 5 /* SPI_4WIRE */
-#define WM8962_SPI_4WIRE_WIDTH 1 /* SPI_4WIRE */
-#define WM8962_SPI_CFG 0x0010 /* SPI_CFG */
-#define WM8962_SPI_CFG_MASK 0x0010 /* SPI_CFG */
-#define WM8962_SPI_CFG_SHIFT 4 /* SPI_CFG */
-#define WM8962_SPI_CFG_WIDTH 1 /* SPI_CFG */
-
-/*
- * R99 (0x63) - Mixer Enables
- */
-#define WM8962_HPMIXL_ENA 0x0008 /* HPMIXL_ENA */
-#define WM8962_HPMIXL_ENA_MASK 0x0008 /* HPMIXL_ENA */
-#define WM8962_HPMIXL_ENA_SHIFT 3 /* HPMIXL_ENA */
-#define WM8962_HPMIXL_ENA_WIDTH 1 /* HPMIXL_ENA */
-#define WM8962_HPMIXR_ENA 0x0004 /* HPMIXR_ENA */
-#define WM8962_HPMIXR_ENA_MASK 0x0004 /* HPMIXR_ENA */
-#define WM8962_HPMIXR_ENA_SHIFT 2 /* HPMIXR_ENA */
-#define WM8962_HPMIXR_ENA_WIDTH 1 /* HPMIXR_ENA */
-#define WM8962_SPKMIXL_ENA 0x0002 /* SPKMIXL_ENA */
-#define WM8962_SPKMIXL_ENA_MASK 0x0002 /* SPKMIXL_ENA */
-#define WM8962_SPKMIXL_ENA_SHIFT 1 /* SPKMIXL_ENA */
-#define WM8962_SPKMIXL_ENA_WIDTH 1 /* SPKMIXL_ENA */
-#define WM8962_SPKMIXR_ENA 0x0001 /* SPKMIXR_ENA */
-#define WM8962_SPKMIXR_ENA_MASK 0x0001 /* SPKMIXR_ENA */
-#define WM8962_SPKMIXR_ENA_SHIFT 0 /* SPKMIXR_ENA */
-#define WM8962_SPKMIXR_ENA_WIDTH 1 /* SPKMIXR_ENA */
-
-/*
- * R100 (0x64) - Headphone Mixer (1)
- */
-#define WM8962_HPMIXL_TO_HPOUTL_PGA 0x0080 /* HPMIXL_TO_HPOUTL_PGA */
-#define WM8962_HPMIXL_TO_HPOUTL_PGA_MASK 0x0080 /* HPMIXL_TO_HPOUTL_PGA */
-#define WM8962_HPMIXL_TO_HPOUTL_PGA_SHIFT 7 /* HPMIXL_TO_HPOUTL_PGA */
-#define WM8962_HPMIXL_TO_HPOUTL_PGA_WIDTH 1 /* HPMIXL_TO_HPOUTL_PGA */
-#define WM8962_DACL_TO_HPMIXL 0x0020 /* DACL_TO_HPMIXL */
-#define WM8962_DACL_TO_HPMIXL_MASK 0x0020 /* DACL_TO_HPMIXL */
-#define WM8962_DACL_TO_HPMIXL_SHIFT 5 /* DACL_TO_HPMIXL */
-#define WM8962_DACL_TO_HPMIXL_WIDTH 1 /* DACL_TO_HPMIXL */
-#define WM8962_DACR_TO_HPMIXL 0x0010 /* DACR_TO_HPMIXL */
-#define WM8962_DACR_TO_HPMIXL_MASK 0x0010 /* DACR_TO_HPMIXL */
-#define WM8962_DACR_TO_HPMIXL_SHIFT 4 /* DACR_TO_HPMIXL */
-#define WM8962_DACR_TO_HPMIXL_WIDTH 1 /* DACR_TO_HPMIXL */
-#define WM8962_MIXINL_TO_HPMIXL 0x0008 /* MIXINL_TO_HPMIXL */
-#define WM8962_MIXINL_TO_HPMIXL_MASK 0x0008 /* MIXINL_TO_HPMIXL */
-#define WM8962_MIXINL_TO_HPMIXL_SHIFT 3 /* MIXINL_TO_HPMIXL */
-#define WM8962_MIXINL_TO_HPMIXL_WIDTH 1 /* MIXINL_TO_HPMIXL */
-#define WM8962_MIXINR_TO_HPMIXL 0x0004 /* MIXINR_TO_HPMIXL */
-#define WM8962_MIXINR_TO_HPMIXL_MASK 0x0004 /* MIXINR_TO_HPMIXL */
-#define WM8962_MIXINR_TO_HPMIXL_SHIFT 2 /* MIXINR_TO_HPMIXL */
-#define WM8962_MIXINR_TO_HPMIXL_WIDTH 1 /* MIXINR_TO_HPMIXL */
-#define WM8962_IN4L_TO_HPMIXL 0x0002 /* IN4L_TO_HPMIXL */
-#define WM8962_IN4L_TO_HPMIXL_MASK 0x0002 /* IN4L_TO_HPMIXL */
-#define WM8962_IN4L_TO_HPMIXL_SHIFT 1 /* IN4L_TO_HPMIXL */
-#define WM8962_IN4L_TO_HPMIXL_WIDTH 1 /* IN4L_TO_HPMIXL */
-#define WM8962_IN4R_TO_HPMIXL 0x0001 /* IN4R_TO_HPMIXL */
-#define WM8962_IN4R_TO_HPMIXL_MASK 0x0001 /* IN4R_TO_HPMIXL */
-#define WM8962_IN4R_TO_HPMIXL_SHIFT 0 /* IN4R_TO_HPMIXL */
-#define WM8962_IN4R_TO_HPMIXL_WIDTH 1 /* IN4R_TO_HPMIXL */
-
-/*
- * R101 (0x65) - Headphone Mixer (2)
- */
-#define WM8962_HPMIXR_TO_HPOUTR_PGA 0x0080 /* HPMIXR_TO_HPOUTR_PGA */
-#define WM8962_HPMIXR_TO_HPOUTR_PGA_MASK 0x0080 /* HPMIXR_TO_HPOUTR_PGA */
-#define WM8962_HPMIXR_TO_HPOUTR_PGA_SHIFT 7 /* HPMIXR_TO_HPOUTR_PGA */
-#define WM8962_HPMIXR_TO_HPOUTR_PGA_WIDTH 1 /* HPMIXR_TO_HPOUTR_PGA */
-#define WM8962_DACL_TO_HPMIXR 0x0020 /* DACL_TO_HPMIXR */
-#define WM8962_DACL_TO_HPMIXR_MASK 0x0020 /* DACL_TO_HPMIXR */
-#define WM8962_DACL_TO_HPMIXR_SHIFT 5 /* DACL_TO_HPMIXR */
-#define WM8962_DACL_TO_HPMIXR_WIDTH 1 /* DACL_TO_HPMIXR */
-#define WM8962_DACR_TO_HPMIXR 0x0010 /* DACR_TO_HPMIXR */
-#define WM8962_DACR_TO_HPMIXR_MASK 0x0010 /* DACR_TO_HPMIXR */
-#define WM8962_DACR_TO_HPMIXR_SHIFT 4 /* DACR_TO_HPMIXR */
-#define WM8962_DACR_TO_HPMIXR_WIDTH 1 /* DACR_TO_HPMIXR */
-#define WM8962_MIXINL_TO_HPMIXR 0x0008 /* MIXINL_TO_HPMIXR */
-#define WM8962_MIXINL_TO_HPMIXR_MASK 0x0008 /* MIXINL_TO_HPMIXR */
-#define WM8962_MIXINL_TO_HPMIXR_SHIFT 3 /* MIXINL_TO_HPMIXR */
-#define WM8962_MIXINL_TO_HPMIXR_WIDTH 1 /* MIXINL_TO_HPMIXR */
-#define WM8962_MIXINR_TO_HPMIXR 0x0004 /* MIXINR_TO_HPMIXR */
-#define WM8962_MIXINR_TO_HPMIXR_MASK 0x0004 /* MIXINR_TO_HPMIXR */
-#define WM8962_MIXINR_TO_HPMIXR_SHIFT 2 /* MIXINR_TO_HPMIXR */
-#define WM8962_MIXINR_TO_HPMIXR_WIDTH 1 /* MIXINR_TO_HPMIXR */
-#define WM8962_IN4L_TO_HPMIXR 0x0002 /* IN4L_TO_HPMIXR */
-#define WM8962_IN4L_TO_HPMIXR_MASK 0x0002 /* IN4L_TO_HPMIXR */
-#define WM8962_IN4L_TO_HPMIXR_SHIFT 1 /* IN4L_TO_HPMIXR */
-#define WM8962_IN4L_TO_HPMIXR_WIDTH 1 /* IN4L_TO_HPMIXR */
-#define WM8962_IN4R_TO_HPMIXR 0x0001 /* IN4R_TO_HPMIXR */
-#define WM8962_IN4R_TO_HPMIXR_MASK 0x0001 /* IN4R_TO_HPMIXR */
-#define WM8962_IN4R_TO_HPMIXR_SHIFT 0 /* IN4R_TO_HPMIXR */
-#define WM8962_IN4R_TO_HPMIXR_WIDTH 1 /* IN4R_TO_HPMIXR */
-
-/*
- * R102 (0x66) - Headphone Mixer (3)
- */
-#define WM8962_HPMIXL_MUTE 0x0100 /* HPMIXL_MUTE */
-#define WM8962_HPMIXL_MUTE_MASK 0x0100 /* HPMIXL_MUTE */
-#define WM8962_HPMIXL_MUTE_SHIFT 8 /* HPMIXL_MUTE */
-#define WM8962_HPMIXL_MUTE_WIDTH 1 /* HPMIXL_MUTE */
-#define WM8962_MIXINL_HPMIXL_VOL 0x0080 /* MIXINL_HPMIXL_VOL */
-#define WM8962_MIXINL_HPMIXL_VOL_MASK 0x0080 /* MIXINL_HPMIXL_VOL */
-#define WM8962_MIXINL_HPMIXL_VOL_SHIFT 7 /* MIXINL_HPMIXL_VOL */
-#define WM8962_MIXINL_HPMIXL_VOL_WIDTH 1 /* MIXINL_HPMIXL_VOL */
-#define WM8962_MIXINR_HPMIXL_VOL 0x0040 /* MIXINR_HPMIXL_VOL */
-#define WM8962_MIXINR_HPMIXL_VOL_MASK 0x0040 /* MIXINR_HPMIXL_VOL */
-#define WM8962_MIXINR_HPMIXL_VOL_SHIFT 6 /* MIXINR_HPMIXL_VOL */
-#define WM8962_MIXINR_HPMIXL_VOL_WIDTH 1 /* MIXINR_HPMIXL_VOL */
-#define WM8962_IN4L_HPMIXL_VOL_MASK 0x0038 /* IN4L_HPMIXL_VOL - [5:3] */
-#define WM8962_IN4L_HPMIXL_VOL_SHIFT 3 /* IN4L_HPMIXL_VOL - [5:3] */
-#define WM8962_IN4L_HPMIXL_VOL_WIDTH 3 /* IN4L_HPMIXL_VOL - [5:3] */
-#define WM8962_IN4R_HPMIXL_VOL_MASK 0x0007 /* IN4R_HPMIXL_VOL - [2:0] */
-#define WM8962_IN4R_HPMIXL_VOL_SHIFT 0 /* IN4R_HPMIXL_VOL - [2:0] */
-#define WM8962_IN4R_HPMIXL_VOL_WIDTH 3 /* IN4R_HPMIXL_VOL - [2:0] */
-
-/*
- * R103 (0x67) - Headphone Mixer (4)
- */
-#define WM8962_HPMIXR_MUTE 0x0100 /* HPMIXR_MUTE */
-#define WM8962_HPMIXR_MUTE_MASK 0x0100 /* HPMIXR_MUTE */
-#define WM8962_HPMIXR_MUTE_SHIFT 8 /* HPMIXR_MUTE */
-#define WM8962_HPMIXR_MUTE_WIDTH 1 /* HPMIXR_MUTE */
-#define WM8962_MIXINL_HPMIXR_VOL 0x0080 /* MIXINL_HPMIXR_VOL */
-#define WM8962_MIXINL_HPMIXR_VOL_MASK 0x0080 /* MIXINL_HPMIXR_VOL */
-#define WM8962_MIXINL_HPMIXR_VOL_SHIFT 7 /* MIXINL_HPMIXR_VOL */
-#define WM8962_MIXINL_HPMIXR_VOL_WIDTH 1 /* MIXINL_HPMIXR_VOL */
-#define WM8962_MIXINR_HPMIXR_VOL 0x0040 /* MIXINR_HPMIXR_VOL */
-#define WM8962_MIXINR_HPMIXR_VOL_MASK 0x0040 /* MIXINR_HPMIXR_VOL */
-#define WM8962_MIXINR_HPMIXR_VOL_SHIFT 6 /* MIXINR_HPMIXR_VOL */
-#define WM8962_MIXINR_HPMIXR_VOL_WIDTH 1 /* MIXINR_HPMIXR_VOL */
-#define WM8962_IN4L_HPMIXR_VOL_MASK 0x0038 /* IN4L_HPMIXR_VOL - [5:3] */
-#define WM8962_IN4L_HPMIXR_VOL_SHIFT 3 /* IN4L_HPMIXR_VOL - [5:3] */
-#define WM8962_IN4L_HPMIXR_VOL_WIDTH 3 /* IN4L_HPMIXR_VOL - [5:3] */
-#define WM8962_IN4R_HPMIXR_VOL_MASK 0x0007 /* IN4R_HPMIXR_VOL - [2:0] */
-#define WM8962_IN4R_HPMIXR_VOL_SHIFT 0 /* IN4R_HPMIXR_VOL - [2:0] */
-#define WM8962_IN4R_HPMIXR_VOL_WIDTH 3 /* IN4R_HPMIXR_VOL - [2:0] */
-
-/*
- * R105 (0x69) - Speaker Mixer (1)
- */
-#define WM8962_SPKMIXL_TO_SPKOUTL_PGA 0x0080 /* SPKMIXL_TO_SPKOUTL_PGA */
-#define WM8962_SPKMIXL_TO_SPKOUTL_PGA_MASK 0x0080 /* SPKMIXL_TO_SPKOUTL_PGA */
-#define WM8962_SPKMIXL_TO_SPKOUTL_PGA_SHIFT 7 /* SPKMIXL_TO_SPKOUTL_PGA */
-#define WM8962_SPKMIXL_TO_SPKOUTL_PGA_WIDTH 1 /* SPKMIXL_TO_SPKOUTL_PGA */
-#define WM8962_DACL_TO_SPKMIXL 0x0020 /* DACL_TO_SPKMIXL */
-#define WM8962_DACL_TO_SPKMIXL_MASK 0x0020 /* DACL_TO_SPKMIXL */
-#define WM8962_DACL_TO_SPKMIXL_SHIFT 5 /* DACL_TO_SPKMIXL */
-#define WM8962_DACL_TO_SPKMIXL_WIDTH 1 /* DACL_TO_SPKMIXL */
-#define WM8962_DACR_TO_SPKMIXL 0x0010 /* DACR_TO_SPKMIXL */
-#define WM8962_DACR_TO_SPKMIXL_MASK 0x0010 /* DACR_TO_SPKMIXL */
-#define WM8962_DACR_TO_SPKMIXL_SHIFT 4 /* DACR_TO_SPKMIXL */
-#define WM8962_DACR_TO_SPKMIXL_WIDTH 1 /* DACR_TO_SPKMIXL */
-#define WM8962_MIXINL_TO_SPKMIXL 0x0008 /* MIXINL_TO_SPKMIXL */
-#define WM8962_MIXINL_TO_SPKMIXL_MASK 0x0008 /* MIXINL_TO_SPKMIXL */
-#define WM8962_MIXINL_TO_SPKMIXL_SHIFT 3 /* MIXINL_TO_SPKMIXL */
-#define WM8962_MIXINL_TO_SPKMIXL_WIDTH 1 /* MIXINL_TO_SPKMIXL */
-#define WM8962_MIXINR_TO_SPKMIXL 0x0004 /* MIXINR_TO_SPKMIXL */
-#define WM8962_MIXINR_TO_SPKMIXL_MASK 0x0004 /* MIXINR_TO_SPKMIXL */
-#define WM8962_MIXINR_TO_SPKMIXL_SHIFT 2 /* MIXINR_TO_SPKMIXL */
-#define WM8962_MIXINR_TO_SPKMIXL_WIDTH 1 /* MIXINR_TO_SPKMIXL */
-#define WM8962_IN4L_TO_SPKMIXL 0x0002 /* IN4L_TO_SPKMIXL */
-#define WM8962_IN4L_TO_SPKMIXL_MASK 0x0002 /* IN4L_TO_SPKMIXL */
-#define WM8962_IN4L_TO_SPKMIXL_SHIFT 1 /* IN4L_TO_SPKMIXL */
-#define WM8962_IN4L_TO_SPKMIXL_WIDTH 1 /* IN4L_TO_SPKMIXL */
-#define WM8962_IN4R_TO_SPKMIXL 0x0001 /* IN4R_TO_SPKMIXL */
-#define WM8962_IN4R_TO_SPKMIXL_MASK 0x0001 /* IN4R_TO_SPKMIXL */
-#define WM8962_IN4R_TO_SPKMIXL_SHIFT 0 /* IN4R_TO_SPKMIXL */
-#define WM8962_IN4R_TO_SPKMIXL_WIDTH 1 /* IN4R_TO_SPKMIXL */
-
-/*
- * R106 (0x6A) - Speaker Mixer (2)
- */
-#define WM8962_SPKMIXR_TO_SPKOUTR_PGA 0x0080 /* SPKMIXR_TO_SPKOUTR_PGA */
-#define WM8962_SPKMIXR_TO_SPKOUTR_PGA_MASK 0x0080 /* SPKMIXR_TO_SPKOUTR_PGA */
-#define WM8962_SPKMIXR_TO_SPKOUTR_PGA_SHIFT 7 /* SPKMIXR_TO_SPKOUTR_PGA */
-#define WM8962_SPKMIXR_TO_SPKOUTR_PGA_WIDTH 1 /* SPKMIXR_TO_SPKOUTR_PGA */
-#define WM8962_DACL_TO_SPKMIXR 0x0020 /* DACL_TO_SPKMIXR */
-#define WM8962_DACL_TO_SPKMIXR_MASK 0x0020 /* DACL_TO_SPKMIXR */
-#define WM8962_DACL_TO_SPKMIXR_SHIFT 5 /* DACL_TO_SPKMIXR */
-#define WM8962_DACL_TO_SPKMIXR_WIDTH 1 /* DACL_TO_SPKMIXR */
-#define WM8962_DACR_TO_SPKMIXR 0x0010 /* DACR_TO_SPKMIXR */
-#define WM8962_DACR_TO_SPKMIXR_MASK 0x0010 /* DACR_TO_SPKMIXR */
-#define WM8962_DACR_TO_SPKMIXR_SHIFT 4 /* DACR_TO_SPKMIXR */
-#define WM8962_DACR_TO_SPKMIXR_WIDTH 1 /* DACR_TO_SPKMIXR */
-#define WM8962_MIXINL_TO_SPKMIXR 0x0008 /* MIXINL_TO_SPKMIXR */
-#define WM8962_MIXINL_TO_SPKMIXR_MASK 0x0008 /* MIXINL_TO_SPKMIXR */
-#define WM8962_MIXINL_TO_SPKMIXR_SHIFT 3 /* MIXINL_TO_SPKMIXR */
-#define WM8962_MIXINL_TO_SPKMIXR_WIDTH 1 /* MIXINL_TO_SPKMIXR */
-#define WM8962_MIXINR_TO_SPKMIXR 0x0004 /* MIXINR_TO_SPKMIXR */
-#define WM8962_MIXINR_TO_SPKMIXR_MASK 0x0004 /* MIXINR_TO_SPKMIXR */
-#define WM8962_MIXINR_TO_SPKMIXR_SHIFT 2 /* MIXINR_TO_SPKMIXR */
-#define WM8962_MIXINR_TO_SPKMIXR_WIDTH 1 /* MIXINR_TO_SPKMIXR */
-#define WM8962_IN4L_TO_SPKMIXR 0x0002 /* IN4L_TO_SPKMIXR */
-#define WM8962_IN4L_TO_SPKMIXR_MASK 0x0002 /* IN4L_TO_SPKMIXR */
-#define WM8962_IN4L_TO_SPKMIXR_SHIFT 1 /* IN4L_TO_SPKMIXR */
-#define WM8962_IN4L_TO_SPKMIXR_WIDTH 1 /* IN4L_TO_SPKMIXR */
-#define WM8962_IN4R_TO_SPKMIXR 0x0001 /* IN4R_TO_SPKMIXR */
-#define WM8962_IN4R_TO_SPKMIXR_MASK 0x0001 /* IN4R_TO_SPKMIXR */
-#define WM8962_IN4R_TO_SPKMIXR_SHIFT 0 /* IN4R_TO_SPKMIXR */
-#define WM8962_IN4R_TO_SPKMIXR_WIDTH 1 /* IN4R_TO_SPKMIXR */
-
-/*
- * R107 (0x6B) - Speaker Mixer (3)
- */
-#define WM8962_SPKMIXL_MUTE 0x0100 /* SPKMIXL_MUTE */
-#define WM8962_SPKMIXL_MUTE_MASK 0x0100 /* SPKMIXL_MUTE */
-#define WM8962_SPKMIXL_MUTE_SHIFT 8 /* SPKMIXL_MUTE */
-#define WM8962_SPKMIXL_MUTE_WIDTH 1 /* SPKMIXL_MUTE */
-#define WM8962_MIXINL_SPKMIXL_VOL 0x0080 /* MIXINL_SPKMIXL_VOL */
-#define WM8962_MIXINL_SPKMIXL_VOL_MASK 0x0080 /* MIXINL_SPKMIXL_VOL */
-#define WM8962_MIXINL_SPKMIXL_VOL_SHIFT 7 /* MIXINL_SPKMIXL_VOL */
-#define WM8962_MIXINL_SPKMIXL_VOL_WIDTH 1 /* MIXINL_SPKMIXL_VOL */
-#define WM8962_MIXINR_SPKMIXL_VOL 0x0040 /* MIXINR_SPKMIXL_VOL */
-#define WM8962_MIXINR_SPKMIXL_VOL_MASK 0x0040 /* MIXINR_SPKMIXL_VOL */
-#define WM8962_MIXINR_SPKMIXL_VOL_SHIFT 6 /* MIXINR_SPKMIXL_VOL */
-#define WM8962_MIXINR_SPKMIXL_VOL_WIDTH 1 /* MIXINR_SPKMIXL_VOL */
-#define WM8962_IN4L_SPKMIXL_VOL_MASK 0x0038 /* IN4L_SPKMIXL_VOL - [5:3] */
-#define WM8962_IN4L_SPKMIXL_VOL_SHIFT 3 /* IN4L_SPKMIXL_VOL - [5:3] */
-#define WM8962_IN4L_SPKMIXL_VOL_WIDTH 3 /* IN4L_SPKMIXL_VOL - [5:3] */
-#define WM8962_IN4R_SPKMIXL_VOL_MASK 0x0007 /* IN4R_SPKMIXL_VOL - [2:0] */
-#define WM8962_IN4R_SPKMIXL_VOL_SHIFT 0 /* IN4R_SPKMIXL_VOL - [2:0] */
-#define WM8962_IN4R_SPKMIXL_VOL_WIDTH 3 /* IN4R_SPKMIXL_VOL - [2:0] */
-
-/*
- * R108 (0x6C) - Speaker Mixer (4)
- */
-#define WM8962_SPKMIXR_MUTE 0x0100 /* SPKMIXR_MUTE */
-#define WM8962_SPKMIXR_MUTE_MASK 0x0100 /* SPKMIXR_MUTE */
-#define WM8962_SPKMIXR_MUTE_SHIFT 8 /* SPKMIXR_MUTE */
-#define WM8962_SPKMIXR_MUTE_WIDTH 1 /* SPKMIXR_MUTE */
-#define WM8962_MIXINL_SPKMIXR_VOL 0x0080 /* MIXINL_SPKMIXR_VOL */
-#define WM8962_MIXINL_SPKMIXR_VOL_MASK 0x0080 /* MIXINL_SPKMIXR_VOL */
-#define WM8962_MIXINL_SPKMIXR_VOL_SHIFT 7 /* MIXINL_SPKMIXR_VOL */
-#define WM8962_MIXINL_SPKMIXR_VOL_WIDTH 1 /* MIXINL_SPKMIXR_VOL */
-#define WM8962_MIXINR_SPKMIXR_VOL 0x0040 /* MIXINR_SPKMIXR_VOL */
-#define WM8962_MIXINR_SPKMIXR_VOL_MASK 0x0040 /* MIXINR_SPKMIXR_VOL */
-#define WM8962_MIXINR_SPKMIXR_VOL_SHIFT 6 /* MIXINR_SPKMIXR_VOL */
-#define WM8962_MIXINR_SPKMIXR_VOL_WIDTH 1 /* MIXINR_SPKMIXR_VOL */
-#define WM8962_IN4L_SPKMIXR_VOL_MASK 0x0038 /* IN4L_SPKMIXR_VOL - [5:3] */
-#define WM8962_IN4L_SPKMIXR_VOL_SHIFT 3 /* IN4L_SPKMIXR_VOL - [5:3] */
-#define WM8962_IN4L_SPKMIXR_VOL_WIDTH 3 /* IN4L_SPKMIXR_VOL - [5:3] */
-#define WM8962_IN4R_SPKMIXR_VOL_MASK 0x0007 /* IN4R_SPKMIXR_VOL - [2:0] */
-#define WM8962_IN4R_SPKMIXR_VOL_SHIFT 0 /* IN4R_SPKMIXR_VOL - [2:0] */
-#define WM8962_IN4R_SPKMIXR_VOL_WIDTH 3 /* IN4R_SPKMIXR_VOL - [2:0] */
-
-/*
- * R109 (0x6D) - Speaker Mixer (5)
- */
-#define WM8962_DACL_SPKMIXL_VOL 0x0080 /* DACL_SPKMIXL_VOL */
-#define WM8962_DACL_SPKMIXL_VOL_MASK 0x0080 /* DACL_SPKMIXL_VOL */
-#define WM8962_DACL_SPKMIXL_VOL_SHIFT 7 /* DACL_SPKMIXL_VOL */
-#define WM8962_DACL_SPKMIXL_VOL_WIDTH 1 /* DACL_SPKMIXL_VOL */
-#define WM8962_DACR_SPKMIXL_VOL 0x0040 /* DACR_SPKMIXL_VOL */
-#define WM8962_DACR_SPKMIXL_VOL_MASK 0x0040 /* DACR_SPKMIXL_VOL */
-#define WM8962_DACR_SPKMIXL_VOL_SHIFT 6 /* DACR_SPKMIXL_VOL */
-#define WM8962_DACR_SPKMIXL_VOL_WIDTH 1 /* DACR_SPKMIXL_VOL */
-#define WM8962_DACL_SPKMIXR_VOL 0x0020 /* DACL_SPKMIXR_VOL */
-#define WM8962_DACL_SPKMIXR_VOL_MASK 0x0020 /* DACL_SPKMIXR_VOL */
-#define WM8962_DACL_SPKMIXR_VOL_SHIFT 5 /* DACL_SPKMIXR_VOL */
-#define WM8962_DACL_SPKMIXR_VOL_WIDTH 1 /* DACL_SPKMIXR_VOL */
-#define WM8962_DACR_SPKMIXR_VOL 0x0010 /* DACR_SPKMIXR_VOL */
-#define WM8962_DACR_SPKMIXR_VOL_MASK 0x0010 /* DACR_SPKMIXR_VOL */
-#define WM8962_DACR_SPKMIXR_VOL_SHIFT 4 /* DACR_SPKMIXR_VOL */
-#define WM8962_DACR_SPKMIXR_VOL_WIDTH 1 /* DACR_SPKMIXR_VOL */
-
-/*
- * R110 (0x6E) - Beep Generator (1)
- */
-#define WM8962_BEEP_GAIN_MASK 0x00F0 /* BEEP_GAIN - [7:4] */
-#define WM8962_BEEP_GAIN_SHIFT 4 /* BEEP_GAIN - [7:4] */
-#define WM8962_BEEP_GAIN_WIDTH 4 /* BEEP_GAIN - [7:4] */
-#define WM8962_BEEP_RATE_MASK 0x0006 /* BEEP_RATE - [2:1] */
-#define WM8962_BEEP_RATE_SHIFT 1 /* BEEP_RATE - [2:1] */
-#define WM8962_BEEP_RATE_WIDTH 2 /* BEEP_RATE - [2:1] */
-#define WM8962_BEEP_ENA 0x0001 /* BEEP_ENA */
-#define WM8962_BEEP_ENA_MASK 0x0001 /* BEEP_ENA */
-#define WM8962_BEEP_ENA_SHIFT 0 /* BEEP_ENA */
-#define WM8962_BEEP_ENA_WIDTH 1 /* BEEP_ENA */
-
-/*
- * R115 (0x73) - Oscillator Trim (3)
- */
-#define WM8962_OSC_TRIM_XTI_MASK 0x001F /* OSC_TRIM_XTI - [4:0] */
-#define WM8962_OSC_TRIM_XTI_SHIFT 0 /* OSC_TRIM_XTI - [4:0] */
-#define WM8962_OSC_TRIM_XTI_WIDTH 5 /* OSC_TRIM_XTI - [4:0] */
-
-/*
- * R116 (0x74) - Oscillator Trim (4)
- */
-#define WM8962_OSC_TRIM_XTO_MASK 0x001F /* OSC_TRIM_XTO - [4:0] */
-#define WM8962_OSC_TRIM_XTO_SHIFT 0 /* OSC_TRIM_XTO - [4:0] */
-#define WM8962_OSC_TRIM_XTO_WIDTH 5 /* OSC_TRIM_XTO - [4:0] */
-
-/*
- * R119 (0x77) - Oscillator Trim (7)
- */
-#define WM8962_XTO_CAP_SEL_MASK 0x00F0 /* XTO_CAP_SEL - [7:4] */
-#define WM8962_XTO_CAP_SEL_SHIFT 4 /* XTO_CAP_SEL - [7:4] */
-#define WM8962_XTO_CAP_SEL_WIDTH 4 /* XTO_CAP_SEL - [7:4] */
-#define WM8962_XTI_CAP_SEL_MASK 0x000F /* XTI_CAP_SEL - [3:0] */
-#define WM8962_XTI_CAP_SEL_SHIFT 0 /* XTI_CAP_SEL - [3:0] */
-#define WM8962_XTI_CAP_SEL_WIDTH 4 /* XTI_CAP_SEL - [3:0] */
-
-/*
- * R124 (0x7C) - Analogue Clocking1
- */
-#define WM8962_CLKOUT2_SEL_MASK 0x0060 /* CLKOUT2_SEL - [6:5] */
-#define WM8962_CLKOUT2_SEL_SHIFT 5 /* CLKOUT2_SEL - [6:5] */
-#define WM8962_CLKOUT2_SEL_WIDTH 2 /* CLKOUT2_SEL - [6:5] */
-#define WM8962_CLKOUT3_SEL_MASK 0x0018 /* CLKOUT3_SEL - [4:3] */
-#define WM8962_CLKOUT3_SEL_SHIFT 3 /* CLKOUT3_SEL - [4:3] */
-#define WM8962_CLKOUT3_SEL_WIDTH 2 /* CLKOUT3_SEL - [4:3] */
-#define WM8962_CLKOUT5_SEL 0x0001 /* CLKOUT5_SEL */
-#define WM8962_CLKOUT5_SEL_MASK 0x0001 /* CLKOUT5_SEL */
-#define WM8962_CLKOUT5_SEL_SHIFT 0 /* CLKOUT5_SEL */
-#define WM8962_CLKOUT5_SEL_WIDTH 1 /* CLKOUT5_SEL */
-
-/*
- * R125 (0x7D) - Analogue Clocking2
- */
-#define WM8962_PLL2_OUTDIV 0x0080 /* PLL2_OUTDIV */
-#define WM8962_PLL2_OUTDIV_MASK 0x0080 /* PLL2_OUTDIV */
-#define WM8962_PLL2_OUTDIV_SHIFT 7 /* PLL2_OUTDIV */
-#define WM8962_PLL2_OUTDIV_WIDTH 1 /* PLL2_OUTDIV */
-#define WM8962_PLL3_OUTDIV 0x0040 /* PLL3_OUTDIV */
-#define WM8962_PLL3_OUTDIV_MASK 0x0040 /* PLL3_OUTDIV */
-#define WM8962_PLL3_OUTDIV_SHIFT 6 /* PLL3_OUTDIV */
-#define WM8962_PLL3_OUTDIV_WIDTH 1 /* PLL3_OUTDIV */
-#define WM8962_PLL_SYSCLK_DIV_MASK 0x0018 /* PLL_SYSCLK_DIV - [4:3] */
-#define WM8962_PLL_SYSCLK_DIV_SHIFT 3 /* PLL_SYSCLK_DIV - [4:3] */
-#define WM8962_PLL_SYSCLK_DIV_WIDTH 2 /* PLL_SYSCLK_DIV - [4:3] */
-#define WM8962_CLKOUT3_DIV 0x0004 /* CLKOUT3_DIV */
-#define WM8962_CLKOUT3_DIV_MASK 0x0004 /* CLKOUT3_DIV */
-#define WM8962_CLKOUT3_DIV_SHIFT 2 /* CLKOUT3_DIV */
-#define WM8962_CLKOUT3_DIV_WIDTH 1 /* CLKOUT3_DIV */
-#define WM8962_CLKOUT2_DIV 0x0002 /* CLKOUT2_DIV */
-#define WM8962_CLKOUT2_DIV_MASK 0x0002 /* CLKOUT2_DIV */
-#define WM8962_CLKOUT2_DIV_SHIFT 1 /* CLKOUT2_DIV */
-#define WM8962_CLKOUT2_DIV_WIDTH 1 /* CLKOUT2_DIV */
-#define WM8962_CLKOUT5_DIV 0x0001 /* CLKOUT5_DIV */
-#define WM8962_CLKOUT5_DIV_MASK 0x0001 /* CLKOUT5_DIV */
-#define WM8962_CLKOUT5_DIV_SHIFT 0 /* CLKOUT5_DIV */
-#define WM8962_CLKOUT5_DIV_WIDTH 1 /* CLKOUT5_DIV */
-
-/*
- * R126 (0x7E) - Analogue Clocking3
- */
-#define WM8962_CLKOUT2_OE 0x0008 /* CLKOUT2_OE */
-#define WM8962_CLKOUT2_OE_MASK 0x0008 /* CLKOUT2_OE */
-#define WM8962_CLKOUT2_OE_SHIFT 3 /* CLKOUT2_OE */
-#define WM8962_CLKOUT2_OE_WIDTH 1 /* CLKOUT2_OE */
-#define WM8962_CLKOUT3_OE 0x0004 /* CLKOUT3_OE */
-#define WM8962_CLKOUT3_OE_MASK 0x0004 /* CLKOUT3_OE */
-#define WM8962_CLKOUT3_OE_SHIFT 2 /* CLKOUT3_OE */
-#define WM8962_CLKOUT3_OE_WIDTH 1 /* CLKOUT3_OE */
-#define WM8962_CLKOUT5_OE 0x0001 /* CLKOUT5_OE */
-#define WM8962_CLKOUT5_OE_MASK 0x0001 /* CLKOUT5_OE */
-#define WM8962_CLKOUT5_OE_SHIFT 0 /* CLKOUT5_OE */
-#define WM8962_CLKOUT5_OE_WIDTH 1 /* CLKOUT5_OE */
-
-/*
- * R127 (0x7F) - PLL Software Reset
- */
-#define WM8962_SW_RESET_PLL_MASK 0xFFFF /* SW_RESET_PLL - [15:0] */
-#define WM8962_SW_RESET_PLL_SHIFT 0 /* SW_RESET_PLL - [15:0] */
-#define WM8962_SW_RESET_PLL_WIDTH 16 /* SW_RESET_PLL - [15:0] */
-
-/*
- * R129 (0x81) - PLL2
- */
-#define WM8962_OSC_ENA 0x0080 /* OSC_ENA */
-#define WM8962_OSC_ENA_MASK 0x0080 /* OSC_ENA */
-#define WM8962_OSC_ENA_SHIFT 7 /* OSC_ENA */
-#define WM8962_OSC_ENA_WIDTH 1 /* OSC_ENA */
-#define WM8962_PLL2_ENA 0x0020 /* PLL2_ENA */
-#define WM8962_PLL2_ENA_MASK 0x0020 /* PLL2_ENA */
-#define WM8962_PLL2_ENA_SHIFT 5 /* PLL2_ENA */
-#define WM8962_PLL2_ENA_WIDTH 1 /* PLL2_ENA */
-#define WM8962_PLL3_ENA 0x0010 /* PLL3_ENA */
-#define WM8962_PLL3_ENA_MASK 0x0010 /* PLL3_ENA */
-#define WM8962_PLL3_ENA_SHIFT 4 /* PLL3_ENA */
-#define WM8962_PLL3_ENA_WIDTH 1 /* PLL3_ENA */
-
-/*
- * R131 (0x83) - PLL 4
- */
-#define WM8962_PLL_CLK_SRC 0x0002 /* PLL_CLK_SRC */
-#define WM8962_PLL_CLK_SRC_MASK 0x0002 /* PLL_CLK_SRC */
-#define WM8962_PLL_CLK_SRC_SHIFT 1 /* PLL_CLK_SRC */
-#define WM8962_PLL_CLK_SRC_WIDTH 1 /* PLL_CLK_SRC */
-#define WM8962_FLL_TO_PLL3 0x0001 /* FLL_TO_PLL3 */
-#define WM8962_FLL_TO_PLL3_MASK 0x0001 /* FLL_TO_PLL3 */
-#define WM8962_FLL_TO_PLL3_SHIFT 0 /* FLL_TO_PLL3 */
-#define WM8962_FLL_TO_PLL3_WIDTH 1 /* FLL_TO_PLL3 */
-
-/*
- * R136 (0x88) - PLL 9
- */
-#define WM8962_PLL2_FRAC 0x0040 /* PLL2_FRAC */
-#define WM8962_PLL2_FRAC_MASK 0x0040 /* PLL2_FRAC */
-#define WM8962_PLL2_FRAC_SHIFT 6 /* PLL2_FRAC */
-#define WM8962_PLL2_FRAC_WIDTH 1 /* PLL2_FRAC */
-#define WM8962_PLL2_N_MASK 0x001F /* PLL2_N - [4:0] */
-#define WM8962_PLL2_N_SHIFT 0 /* PLL2_N - [4:0] */
-#define WM8962_PLL2_N_WIDTH 5 /* PLL2_N - [4:0] */
-
-/*
- * R137 (0x89) - PLL 10
- */
-#define WM8962_PLL2_K_MASK 0x00FF /* PLL2_K - [7:0] */
-#define WM8962_PLL2_K_SHIFT 0 /* PLL2_K - [7:0] */
-#define WM8962_PLL2_K_WIDTH 8 /* PLL2_K - [7:0] */
-
-/*
- * R138 (0x8A) - PLL 11
- */
-#define WM8962_PLL2_K_MASK 0x00FF /* PLL2_K - [7:0] */
-#define WM8962_PLL2_K_SHIFT 0 /* PLL2_K - [7:0] */
-#define WM8962_PLL2_K_WIDTH 8 /* PLL2_K - [7:0] */
-
-/*
- * R139 (0x8B) - PLL 12
- */
-#define WM8962_PLL2_K_MASK 0x00FF /* PLL2_K - [7:0] */
-#define WM8962_PLL2_K_SHIFT 0 /* PLL2_K - [7:0] */
-#define WM8962_PLL2_K_WIDTH 8 /* PLL2_K - [7:0] */
-
-/*
- * R140 (0x8C) - PLL 13
- */
-#define WM8962_PLL3_FRAC 0x0040 /* PLL3_FRAC */
-#define WM8962_PLL3_FRAC_MASK 0x0040 /* PLL3_FRAC */
-#define WM8962_PLL3_FRAC_SHIFT 6 /* PLL3_FRAC */
-#define WM8962_PLL3_FRAC_WIDTH 1 /* PLL3_FRAC */
-#define WM8962_PLL3_N_MASK 0x001F /* PLL3_N - [4:0] */
-#define WM8962_PLL3_N_SHIFT 0 /* PLL3_N - [4:0] */
-#define WM8962_PLL3_N_WIDTH 5 /* PLL3_N - [4:0] */
-
-/*
- * R141 (0x8D) - PLL 14
- */
-#define WM8962_PLL3_K_MASK 0x00FF /* PLL3_K - [7:0] */
-#define WM8962_PLL3_K_SHIFT 0 /* PLL3_K - [7:0] */
-#define WM8962_PLL3_K_WIDTH 8 /* PLL3_K - [7:0] */
-
-/*
- * R142 (0x8E) - PLL 15
- */
-#define WM8962_PLL3_K_MASK 0x00FF /* PLL3_K - [7:0] */
-#define WM8962_PLL3_K_SHIFT 0 /* PLL3_K - [7:0] */
-#define WM8962_PLL3_K_WIDTH 8 /* PLL3_K - [7:0] */
-
-/*
- * R143 (0x8F) - PLL 16
- */
-#define WM8962_PLL3_K_MASK 0x00FF /* PLL3_K - [7:0] */
-#define WM8962_PLL3_K_SHIFT 0 /* PLL3_K - [7:0] */
-#define WM8962_PLL3_K_WIDTH 8 /* PLL3_K - [7:0] */
-
-/*
- * R155 (0x9B) - FLL Control (1)
- */
-#define WM8962_FLL_REFCLK_SRC_MASK 0x0060 /* FLL_REFCLK_SRC - [6:5] */
-#define WM8962_FLL_REFCLK_SRC_SHIFT 5 /* FLL_REFCLK_SRC - [6:5] */
-#define WM8962_FLL_REFCLK_SRC_WIDTH 2 /* FLL_REFCLK_SRC - [6:5] */
-#define WM8962_FLL_FRAC 0x0004 /* FLL_FRAC */
-#define WM8962_FLL_FRAC_MASK 0x0004 /* FLL_FRAC */
-#define WM8962_FLL_FRAC_SHIFT 2 /* FLL_FRAC */
-#define WM8962_FLL_FRAC_WIDTH 1 /* FLL_FRAC */
-#define WM8962_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */
-#define WM8962_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */
-#define WM8962_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */
-#define WM8962_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */
-#define WM8962_FLL_ENA 0x0001 /* FLL_ENA */
-#define WM8962_FLL_ENA_MASK 0x0001 /* FLL_ENA */
-#define WM8962_FLL_ENA_SHIFT 0 /* FLL_ENA */
-#define WM8962_FLL_ENA_WIDTH 1 /* FLL_ENA */
-
-/*
- * R156 (0x9C) - FLL Control (2)
- */
-#define WM8962_FLL_OUTDIV_MASK 0x01F8 /* FLL_OUTDIV - [8:3] */
-#define WM8962_FLL_OUTDIV_SHIFT 3 /* FLL_OUTDIV - [8:3] */
-#define WM8962_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [8:3] */
-#define WM8962_FLL_REFCLK_DIV_MASK 0x0003 /* FLL_REFCLK_DIV - [1:0] */
-#define WM8962_FLL_REFCLK_DIV_SHIFT 0 /* FLL_REFCLK_DIV - [1:0] */
-#define WM8962_FLL_REFCLK_DIV_WIDTH 2 /* FLL_REFCLK_DIV - [1:0] */
-
-/*
- * R157 (0x9D) - FLL Control (3)
- */
-#define WM8962_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
-#define WM8962_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
-#define WM8962_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
-
-/*
- * R159 (0x9F) - FLL Control (5)
- */
-#define WM8962_FLL_FRC_NCO_VAL_MASK 0x007E /* FLL_FRC_NCO_VAL - [6:1] */
-#define WM8962_FLL_FRC_NCO_VAL_SHIFT 1 /* FLL_FRC_NCO_VAL - [6:1] */
-#define WM8962_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [6:1] */
-#define WM8962_FLL_FRC_NCO 0x0001 /* FLL_FRC_NCO */
-#define WM8962_FLL_FRC_NCO_MASK 0x0001 /* FLL_FRC_NCO */
-#define WM8962_FLL_FRC_NCO_SHIFT 0 /* FLL_FRC_NCO */
-#define WM8962_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */
-
-/*
- * R160 (0xA0) - FLL Control (6)
- */
-#define WM8962_FLL_THETA_MASK 0xFFFF /* FLL_THETA - [15:0] */
-#define WM8962_FLL_THETA_SHIFT 0 /* FLL_THETA - [15:0] */
-#define WM8962_FLL_THETA_WIDTH 16 /* FLL_THETA - [15:0] */
-
-/*
- * R161 (0xA1) - FLL Control (7)
- */
-#define WM8962_FLL_LAMBDA_MASK 0xFFFF /* FLL_LAMBDA - [15:0] */
-#define WM8962_FLL_LAMBDA_SHIFT 0 /* FLL_LAMBDA - [15:0] */
-#define WM8962_FLL_LAMBDA_WIDTH 16 /* FLL_LAMBDA - [15:0] */
-
-/*
- * R162 (0xA2) - FLL Control (8)
- */
-#define WM8962_FLL_N_MASK 0x03FF /* FLL_N - [9:0] */
-#define WM8962_FLL_N_SHIFT 0 /* FLL_N - [9:0] */
-#define WM8962_FLL_N_WIDTH 10 /* FLL_N - [9:0] */
-
-/*
- * R252 (0xFC) - General test 1
- */
-#define WM8962_REG_SYNC 0x0004 /* REG_SYNC */
-#define WM8962_REG_SYNC_MASK 0x0004 /* REG_SYNC */
-#define WM8962_REG_SYNC_SHIFT 2 /* REG_SYNC */
-#define WM8962_REG_SYNC_WIDTH 1 /* REG_SYNC */
-#define WM8962_AUTO_INC 0x0001 /* AUTO_INC */
-#define WM8962_AUTO_INC_MASK 0x0001 /* AUTO_INC */
-#define WM8962_AUTO_INC_SHIFT 0 /* AUTO_INC */
-#define WM8962_AUTO_INC_WIDTH 1 /* AUTO_INC */
-
-/*
- * R256 (0x100) - DF1
- */
-#define WM8962_DRC_DF1_ENA 0x0008 /* DRC_DF1_ENA */
-#define WM8962_DRC_DF1_ENA_MASK 0x0008 /* DRC_DF1_ENA */
-#define WM8962_DRC_DF1_ENA_SHIFT 3 /* DRC_DF1_ENA */
-#define WM8962_DRC_DF1_ENA_WIDTH 1 /* DRC_DF1_ENA */
-#define WM8962_DF1_SHARED_COEFF 0x0004 /* DF1_SHARED_COEFF */
-#define WM8962_DF1_SHARED_COEFF_MASK 0x0004 /* DF1_SHARED_COEFF */
-#define WM8962_DF1_SHARED_COEFF_SHIFT 2 /* DF1_SHARED_COEFF */
-#define WM8962_DF1_SHARED_COEFF_WIDTH 1 /* DF1_SHARED_COEFF */
-#define WM8962_DF1_SHARED_COEFF_SEL 0x0002 /* DF1_SHARED_COEFF_SEL */
-#define WM8962_DF1_SHARED_COEFF_SEL_MASK 0x0002 /* DF1_SHARED_COEFF_SEL */
-#define WM8962_DF1_SHARED_COEFF_SEL_SHIFT 1 /* DF1_SHARED_COEFF_SEL */
-#define WM8962_DF1_SHARED_COEFF_SEL_WIDTH 1 /* DF1_SHARED_COEFF_SEL */
-#define WM8962_DF1_ENA 0x0001 /* DF1_ENA */
-#define WM8962_DF1_ENA_MASK 0x0001 /* DF1_ENA */
-#define WM8962_DF1_ENA_SHIFT 0 /* DF1_ENA */
-#define WM8962_DF1_ENA_WIDTH 1 /* DF1_ENA */
-
-/*
- * R257 (0x101) - DF2
- */
-#define WM8962_DF1_COEFF_L0_MASK 0xFFFF /* DF1_COEFF_L0 - [15:0] */
-#define WM8962_DF1_COEFF_L0_SHIFT 0 /* DF1_COEFF_L0 - [15:0] */
-#define WM8962_DF1_COEFF_L0_WIDTH 16 /* DF1_COEFF_L0 - [15:0] */
-
-/*
- * R258 (0x102) - DF3
- */
-#define WM8962_DF1_COEFF_L1_MASK 0xFFFF /* DF1_COEFF_L1 - [15:0] */
-#define WM8962_DF1_COEFF_L1_SHIFT 0 /* DF1_COEFF_L1 - [15:0] */
-#define WM8962_DF1_COEFF_L1_WIDTH 16 /* DF1_COEFF_L1 - [15:0] */
-
-/*
- * R259 (0x103) - DF4
- */
-#define WM8962_DF1_COEFF_L2_MASK 0xFFFF /* DF1_COEFF_L2 - [15:0] */
-#define WM8962_DF1_COEFF_L2_SHIFT 0 /* DF1_COEFF_L2 - [15:0] */
-#define WM8962_DF1_COEFF_L2_WIDTH 16 /* DF1_COEFF_L2 - [15:0] */
-
-/*
- * R260 (0x104) - DF5
- */
-#define WM8962_DF1_COEFF_R0_MASK 0xFFFF /* DF1_COEFF_R0 - [15:0] */
-#define WM8962_DF1_COEFF_R0_SHIFT 0 /* DF1_COEFF_R0 - [15:0] */
-#define WM8962_DF1_COEFF_R0_WIDTH 16 /* DF1_COEFF_R0 - [15:0] */
-
-/*
- * R261 (0x105) - DF6
- */
-#define WM8962_DF1_COEFF_R1_MASK 0xFFFF /* DF1_COEFF_R1 - [15:0] */
-#define WM8962_DF1_COEFF_R1_SHIFT 0 /* DF1_COEFF_R1 - [15:0] */
-#define WM8962_DF1_COEFF_R1_WIDTH 16 /* DF1_COEFF_R1 - [15:0] */
-
-/*
- * R262 (0x106) - DF7
- */
-#define WM8962_DF1_COEFF_R2_MASK 0xFFFF /* DF1_COEFF_R2 - [15:0] */
-#define WM8962_DF1_COEFF_R2_SHIFT 0 /* DF1_COEFF_R2 - [15:0] */
-#define WM8962_DF1_COEFF_R2_WIDTH 16 /* DF1_COEFF_R2 - [15:0] */
-
-/*
- * R264 (0x108) - LHPF1
- */
-#define WM8962_LHPF_MODE 0x0002 /* LHPF_MODE */
-#define WM8962_LHPF_MODE_MASK 0x0002 /* LHPF_MODE */
-#define WM8962_LHPF_MODE_SHIFT 1 /* LHPF_MODE */
-#define WM8962_LHPF_MODE_WIDTH 1 /* LHPF_MODE */
-#define WM8962_LHPF_ENA 0x0001 /* LHPF_ENA */
-#define WM8962_LHPF_ENA_MASK 0x0001 /* LHPF_ENA */
-#define WM8962_LHPF_ENA_SHIFT 0 /* LHPF_ENA */
-#define WM8962_LHPF_ENA_WIDTH 1 /* LHPF_ENA */
-
-/*
- * R265 (0x109) - LHPF2
- */
-#define WM8962_LHPF_COEFF_MASK 0xFFFF /* LHPF_COEFF - [15:0] */
-#define WM8962_LHPF_COEFF_SHIFT 0 /* LHPF_COEFF - [15:0] */
-#define WM8962_LHPF_COEFF_WIDTH 16 /* LHPF_COEFF - [15:0] */
-
-/*
- * R268 (0x10C) - THREED1
- */
-#define WM8962_ADC_MONOMIX 0x0040 /* ADC_MONOMIX */
-#define WM8962_ADC_MONOMIX_MASK 0x0040 /* ADC_MONOMIX */
-#define WM8962_ADC_MONOMIX_SHIFT 6 /* ADC_MONOMIX */
-#define WM8962_ADC_MONOMIX_WIDTH 1 /* ADC_MONOMIX */
-#define WM8962_THREED_SIGN_L 0x0020 /* THREED_SIGN_L */
-#define WM8962_THREED_SIGN_L_MASK 0x0020 /* THREED_SIGN_L */
-#define WM8962_THREED_SIGN_L_SHIFT 5 /* THREED_SIGN_L */
-#define WM8962_THREED_SIGN_L_WIDTH 1 /* THREED_SIGN_L */
-#define WM8962_THREED_SIGN_R 0x0010 /* THREED_SIGN_R */
-#define WM8962_THREED_SIGN_R_MASK 0x0010 /* THREED_SIGN_R */
-#define WM8962_THREED_SIGN_R_SHIFT 4 /* THREED_SIGN_R */
-#define WM8962_THREED_SIGN_R_WIDTH 1 /* THREED_SIGN_R */
-#define WM8962_THREED_LHPF_MODE 0x0004 /* THREED_LHPF_MODE */
-#define WM8962_THREED_LHPF_MODE_MASK 0x0004 /* THREED_LHPF_MODE */
-#define WM8962_THREED_LHPF_MODE_SHIFT 2 /* THREED_LHPF_MODE */
-#define WM8962_THREED_LHPF_MODE_WIDTH 1 /* THREED_LHPF_MODE */
-#define WM8962_THREED_LHPF_ENA 0x0002 /* THREED_LHPF_ENA */
-#define WM8962_THREED_LHPF_ENA_MASK 0x0002 /* THREED_LHPF_ENA */
-#define WM8962_THREED_LHPF_ENA_SHIFT 1 /* THREED_LHPF_ENA */
-#define WM8962_THREED_LHPF_ENA_WIDTH 1 /* THREED_LHPF_ENA */
-#define WM8962_THREED_ENA 0x0001 /* THREED_ENA */
-#define WM8962_THREED_ENA_MASK 0x0001 /* THREED_ENA */
-#define WM8962_THREED_ENA_SHIFT 0 /* THREED_ENA */
-#define WM8962_THREED_ENA_WIDTH 1 /* THREED_ENA */
-
-/*
- * R269 (0x10D) - THREED2
- */
-#define WM8962_THREED_FGAINL_MASK 0xF800 /* THREED_FGAINL - [15:11] */
-#define WM8962_THREED_FGAINL_SHIFT 11 /* THREED_FGAINL - [15:11] */
-#define WM8962_THREED_FGAINL_WIDTH 5 /* THREED_FGAINL - [15:11] */
-#define WM8962_THREED_CGAINL_MASK 0x07C0 /* THREED_CGAINL - [10:6] */
-#define WM8962_THREED_CGAINL_SHIFT 6 /* THREED_CGAINL - [10:6] */
-#define WM8962_THREED_CGAINL_WIDTH 5 /* THREED_CGAINL - [10:6] */
-#define WM8962_THREED_DELAYL_MASK 0x003C /* THREED_DELAYL - [5:2] */
-#define WM8962_THREED_DELAYL_SHIFT 2 /* THREED_DELAYL - [5:2] */
-#define WM8962_THREED_DELAYL_WIDTH 4 /* THREED_DELAYL - [5:2] */
-
-/*
- * R270 (0x10E) - THREED3
- */
-#define WM8962_THREED_LHPF_COEFF_MASK 0xFFFF /* THREED_LHPF_COEFF - [15:0] */
-#define WM8962_THREED_LHPF_COEFF_SHIFT 0 /* THREED_LHPF_COEFF - [15:0] */
-#define WM8962_THREED_LHPF_COEFF_WIDTH 16 /* THREED_LHPF_COEFF - [15:0] */
-
-/*
- * R271 (0x10F) - THREED4
- */
-#define WM8962_THREED_FGAINR_MASK 0xF800 /* THREED_FGAINR - [15:11] */
-#define WM8962_THREED_FGAINR_SHIFT 11 /* THREED_FGAINR - [15:11] */
-#define WM8962_THREED_FGAINR_WIDTH 5 /* THREED_FGAINR - [15:11] */
-#define WM8962_THREED_CGAINR_MASK 0x07C0 /* THREED_CGAINR - [10:6] */
-#define WM8962_THREED_CGAINR_SHIFT 6 /* THREED_CGAINR - [10:6] */
-#define WM8962_THREED_CGAINR_WIDTH 5 /* THREED_CGAINR - [10:6] */
-#define WM8962_THREED_DELAYR_MASK 0x003C /* THREED_DELAYR - [5:2] */
-#define WM8962_THREED_DELAYR_SHIFT 2 /* THREED_DELAYR - [5:2] */
-#define WM8962_THREED_DELAYR_WIDTH 4 /* THREED_DELAYR - [5:2] */
-
-/*
- * R276 (0x114) - DRC 1
- */
-#define WM8962_DRC_SIG_DET_RMS_MASK 0x7C00 /* DRC_SIG_DET_RMS - [14:10] */
-#define WM8962_DRC_SIG_DET_RMS_SHIFT 10 /* DRC_SIG_DET_RMS - [14:10] */
-#define WM8962_DRC_SIG_DET_RMS_WIDTH 5 /* DRC_SIG_DET_RMS - [14:10] */
-#define WM8962_DRC_SIG_DET_PK_MASK 0x0300 /* DRC_SIG_DET_PK - [9:8] */
-#define WM8962_DRC_SIG_DET_PK_SHIFT 8 /* DRC_SIG_DET_PK - [9:8] */
-#define WM8962_DRC_SIG_DET_PK_WIDTH 2 /* DRC_SIG_DET_PK - [9:8] */
-#define WM8962_DRC_NG_ENA 0x0080 /* DRC_NG_ENA */
-#define WM8962_DRC_NG_ENA_MASK 0x0080 /* DRC_NG_ENA */
-#define WM8962_DRC_NG_ENA_SHIFT 7 /* DRC_NG_ENA */
-#define WM8962_DRC_NG_ENA_WIDTH 1 /* DRC_NG_ENA */
-#define WM8962_DRC_SIG_DET_MODE 0x0040 /* DRC_SIG_DET_MODE */
-#define WM8962_DRC_SIG_DET_MODE_MASK 0x0040 /* DRC_SIG_DET_MODE */
-#define WM8962_DRC_SIG_DET_MODE_SHIFT 6 /* DRC_SIG_DET_MODE */
-#define WM8962_DRC_SIG_DET_MODE_WIDTH 1 /* DRC_SIG_DET_MODE */
-#define WM8962_DRC_SIG_DET 0x0020 /* DRC_SIG_DET */
-#define WM8962_DRC_SIG_DET_MASK 0x0020 /* DRC_SIG_DET */
-#define WM8962_DRC_SIG_DET_SHIFT 5 /* DRC_SIG_DET */
-#define WM8962_DRC_SIG_DET_WIDTH 1 /* DRC_SIG_DET */
-#define WM8962_DRC_KNEE2_OP_ENA 0x0010 /* DRC_KNEE2_OP_ENA */
-#define WM8962_DRC_KNEE2_OP_ENA_MASK 0x0010 /* DRC_KNEE2_OP_ENA */
-#define WM8962_DRC_KNEE2_OP_ENA_SHIFT 4 /* DRC_KNEE2_OP_ENA */
-#define WM8962_DRC_KNEE2_OP_ENA_WIDTH 1 /* DRC_KNEE2_OP_ENA */
-#define WM8962_DRC_QR 0x0008 /* DRC_QR */
-#define WM8962_DRC_QR_MASK 0x0008 /* DRC_QR */
-#define WM8962_DRC_QR_SHIFT 3 /* DRC_QR */
-#define WM8962_DRC_QR_WIDTH 1 /* DRC_QR */
-#define WM8962_DRC_ANTICLIP 0x0004 /* DRC_ANTICLIP */
-#define WM8962_DRC_ANTICLIP_MASK 0x0004 /* DRC_ANTICLIP */
-#define WM8962_DRC_ANTICLIP_SHIFT 2 /* DRC_ANTICLIP */
-#define WM8962_DRC_ANTICLIP_WIDTH 1 /* DRC_ANTICLIP */
-#define WM8962_DRC_MODE 0x0002 /* DRC_MODE */
-#define WM8962_DRC_MODE_MASK 0x0002 /* DRC_MODE */
-#define WM8962_DRC_MODE_SHIFT 1 /* DRC_MODE */
-#define WM8962_DRC_MODE_WIDTH 1 /* DRC_MODE */
-#define WM8962_DRC_ENA 0x0001 /* DRC_ENA */
-#define WM8962_DRC_ENA_MASK 0x0001 /* DRC_ENA */
-#define WM8962_DRC_ENA_SHIFT 0 /* DRC_ENA */
-#define WM8962_DRC_ENA_WIDTH 1 /* DRC_ENA */
-
-/*
- * R277 (0x115) - DRC 2
- */
-#define WM8962_DRC_ATK_MASK 0x1E00 /* DRC_ATK - [12:9] */
-#define WM8962_DRC_ATK_SHIFT 9 /* DRC_ATK - [12:9] */
-#define WM8962_DRC_ATK_WIDTH 4 /* DRC_ATK - [12:9] */
-#define WM8962_DRC_DCY_MASK 0x01E0 /* DRC_DCY - [8:5] */
-#define WM8962_DRC_DCY_SHIFT 5 /* DRC_DCY - [8:5] */
-#define WM8962_DRC_DCY_WIDTH 4 /* DRC_DCY - [8:5] */
-#define WM8962_DRC_MINGAIN_MASK 0x001C /* DRC_MINGAIN - [4:2] */
-#define WM8962_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [4:2] */
-#define WM8962_DRC_MINGAIN_WIDTH 3 /* DRC_MINGAIN - [4:2] */
-#define WM8962_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */
-#define WM8962_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */
-#define WM8962_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */
-
-/*
- * R278 (0x116) - DRC 3
- */
-#define WM8962_DRC_NG_MINGAIN_MASK 0xF000 /* DRC_NG_MINGAIN - [15:12] */
-#define WM8962_DRC_NG_MINGAIN_SHIFT 12 /* DRC_NG_MINGAIN - [15:12] */
-#define WM8962_DRC_NG_MINGAIN_WIDTH 4 /* DRC_NG_MINGAIN - [15:12] */
-#define WM8962_DRC_QR_THR_MASK 0x0C00 /* DRC_QR_THR - [11:10] */
-#define WM8962_DRC_QR_THR_SHIFT 10 /* DRC_QR_THR - [11:10] */
-#define WM8962_DRC_QR_THR_WIDTH 2 /* DRC_QR_THR - [11:10] */
-#define WM8962_DRC_QR_DCY_MASK 0x0300 /* DRC_QR_DCY - [9:8] */
-#define WM8962_DRC_QR_DCY_SHIFT 8 /* DRC_QR_DCY - [9:8] */
-#define WM8962_DRC_QR_DCY_WIDTH 2 /* DRC_QR_DCY - [9:8] */
-#define WM8962_DRC_NG_EXP_MASK 0x00C0 /* DRC_NG_EXP - [7:6] */
-#define WM8962_DRC_NG_EXP_SHIFT 6 /* DRC_NG_EXP - [7:6] */
-#define WM8962_DRC_NG_EXP_WIDTH 2 /* DRC_NG_EXP - [7:6] */
-#define WM8962_DRC_HI_COMP_MASK 0x0038 /* DRC_HI_COMP - [5:3] */
-#define WM8962_DRC_HI_COMP_SHIFT 3 /* DRC_HI_COMP - [5:3] */
-#define WM8962_DRC_HI_COMP_WIDTH 3 /* DRC_HI_COMP - [5:3] */
-#define WM8962_DRC_LO_COMP_MASK 0x0007 /* DRC_LO_COMP - [2:0] */
-#define WM8962_DRC_LO_COMP_SHIFT 0 /* DRC_LO_COMP - [2:0] */
-#define WM8962_DRC_LO_COMP_WIDTH 3 /* DRC_LO_COMP - [2:0] */
-
-/*
- * R279 (0x117) - DRC 4
- */
-#define WM8962_DRC_KNEE_IP_MASK 0x07E0 /* DRC_KNEE_IP - [10:5] */
-#define WM8962_DRC_KNEE_IP_SHIFT 5 /* DRC_KNEE_IP - [10:5] */
-#define WM8962_DRC_KNEE_IP_WIDTH 6 /* DRC_KNEE_IP - [10:5] */
-#define WM8962_DRC_KNEE_OP_MASK 0x001F /* DRC_KNEE_OP - [4:0] */
-#define WM8962_DRC_KNEE_OP_SHIFT 0 /* DRC_KNEE_OP - [4:0] */
-#define WM8962_DRC_KNEE_OP_WIDTH 5 /* DRC_KNEE_OP - [4:0] */
-
-/*
- * R280 (0x118) - DRC 5
- */
-#define WM8962_DRC_KNEE2_IP_MASK 0x03E0 /* DRC_KNEE2_IP - [9:5] */
-#define WM8962_DRC_KNEE2_IP_SHIFT 5 /* DRC_KNEE2_IP - [9:5] */
-#define WM8962_DRC_KNEE2_IP_WIDTH 5 /* DRC_KNEE2_IP - [9:5] */
-#define WM8962_DRC_KNEE2_OP_MASK 0x001F /* DRC_KNEE2_OP - [4:0] */
-#define WM8962_DRC_KNEE2_OP_SHIFT 0 /* DRC_KNEE2_OP - [4:0] */
-#define WM8962_DRC_KNEE2_OP_WIDTH 5 /* DRC_KNEE2_OP - [4:0] */
-
-/*
- * R285 (0x11D) - Tloopback
- */
-#define WM8962_TLB_ENA 0x0002 /* TLB_ENA */
-#define WM8962_TLB_ENA_MASK 0x0002 /* TLB_ENA */
-#define WM8962_TLB_ENA_SHIFT 1 /* TLB_ENA */
-#define WM8962_TLB_ENA_WIDTH 1 /* TLB_ENA */
-#define WM8962_TLB_MODE 0x0001 /* TLB_MODE */
-#define WM8962_TLB_MODE_MASK 0x0001 /* TLB_MODE */
-#define WM8962_TLB_MODE_SHIFT 0 /* TLB_MODE */
-#define WM8962_TLB_MODE_WIDTH 1 /* TLB_MODE */
-
-/*
- * R335 (0x14F) - EQ1
- */
-#define WM8962_EQ_SHARED_COEFF 0x0004 /* EQ_SHARED_COEFF */
-#define WM8962_EQ_SHARED_COEFF_MASK 0x0004 /* EQ_SHARED_COEFF */
-#define WM8962_EQ_SHARED_COEFF_SHIFT 2 /* EQ_SHARED_COEFF */
-#define WM8962_EQ_SHARED_COEFF_WIDTH 1 /* EQ_SHARED_COEFF */
-#define WM8962_EQ_SHARED_COEFF_SEL 0x0002 /* EQ_SHARED_COEFF_SEL */
-#define WM8962_EQ_SHARED_COEFF_SEL_MASK 0x0002 /* EQ_SHARED_COEFF_SEL */
-#define WM8962_EQ_SHARED_COEFF_SEL_SHIFT 1 /* EQ_SHARED_COEFF_SEL */
-#define WM8962_EQ_SHARED_COEFF_SEL_WIDTH 1 /* EQ_SHARED_COEFF_SEL */
-#define WM8962_EQ_ENA 0x0001 /* EQ_ENA */
-#define WM8962_EQ_ENA_MASK 0x0001 /* EQ_ENA */
-#define WM8962_EQ_ENA_SHIFT 0 /* EQ_ENA */
-#define WM8962_EQ_ENA_WIDTH 1 /* EQ_ENA */
-
-/*
- * R336 (0x150) - EQ2
- */
-#define WM8962_EQL_B1_GAIN_MASK 0xF800 /* EQL_B1_GAIN - [15:11] */
-#define WM8962_EQL_B1_GAIN_SHIFT 11 /* EQL_B1_GAIN - [15:11] */
-#define WM8962_EQL_B1_GAIN_WIDTH 5 /* EQL_B1_GAIN - [15:11] */
-#define WM8962_EQL_B2_GAIN_MASK 0x07C0 /* EQL_B2_GAIN - [10:6] */
-#define WM8962_EQL_B2_GAIN_SHIFT 6 /* EQL_B2_GAIN - [10:6] */
-#define WM8962_EQL_B2_GAIN_WIDTH 5 /* EQL_B2_GAIN - [10:6] */
-#define WM8962_EQL_B3_GAIN_MASK 0x003E /* EQL_B3_GAIN - [5:1] */
-#define WM8962_EQL_B3_GAIN_SHIFT 1 /* EQL_B3_GAIN - [5:1] */
-#define WM8962_EQL_B3_GAIN_WIDTH 5 /* EQL_B3_GAIN - [5:1] */
-
-/*
- * R337 (0x151) - EQ3
- */
-#define WM8962_EQL_B4_GAIN_MASK 0xF800 /* EQL_B4_GAIN - [15:11] */
-#define WM8962_EQL_B4_GAIN_SHIFT 11 /* EQL_B4_GAIN - [15:11] */
-#define WM8962_EQL_B4_GAIN_WIDTH 5 /* EQL_B4_GAIN - [15:11] */
-#define WM8962_EQL_B5_GAIN_MASK 0x07C0 /* EQL_B5_GAIN - [10:6] */
-#define WM8962_EQL_B5_GAIN_SHIFT 6 /* EQL_B5_GAIN - [10:6] */
-#define WM8962_EQL_B5_GAIN_WIDTH 5 /* EQL_B5_GAIN - [10:6] */
-
-/*
- * R338 (0x152) - EQ4
- */
-#define WM8962_EQL_B1_A_MASK 0xFFFF /* EQL_B1_A - [15:0] */
-#define WM8962_EQL_B1_A_SHIFT 0 /* EQL_B1_A - [15:0] */
-#define WM8962_EQL_B1_A_WIDTH 16 /* EQL_B1_A - [15:0] */
-
-/*
- * R339 (0x153) - EQ5
- */
-#define WM8962_EQL_B1_B_MASK 0xFFFF /* EQL_B1_B - [15:0] */
-#define WM8962_EQL_B1_B_SHIFT 0 /* EQL_B1_B - [15:0] */
-#define WM8962_EQL_B1_B_WIDTH 16 /* EQL_B1_B - [15:0] */
-
-/*
- * R340 (0x154) - EQ6
- */
-#define WM8962_EQL_B1_PG_MASK 0xFFFF /* EQL_B1_PG - [15:0] */
-#define WM8962_EQL_B1_PG_SHIFT 0 /* EQL_B1_PG - [15:0] */
-#define WM8962_EQL_B1_PG_WIDTH 16 /* EQL_B1_PG - [15:0] */
-
-/*
- * R341 (0x155) - EQ7
- */
-#define WM8962_EQL_B2_A_MASK 0xFFFF /* EQL_B2_A - [15:0] */
-#define WM8962_EQL_B2_A_SHIFT 0 /* EQL_B2_A - [15:0] */
-#define WM8962_EQL_B2_A_WIDTH 16 /* EQL_B2_A - [15:0] */
-
-/*
- * R342 (0x156) - EQ8
- */
-#define WM8962_EQL_B2_B_MASK 0xFFFF /* EQL_B2_B - [15:0] */
-#define WM8962_EQL_B2_B_SHIFT 0 /* EQL_B2_B - [15:0] */
-#define WM8962_EQL_B2_B_WIDTH 16 /* EQL_B2_B - [15:0] */
-
-/*
- * R343 (0x157) - EQ9
- */
-#define WM8962_EQL_B2_C_MASK 0xFFFF /* EQL_B2_C - [15:0] */
-#define WM8962_EQL_B2_C_SHIFT 0 /* EQL_B2_C - [15:0] */
-#define WM8962_EQL_B2_C_WIDTH 16 /* EQL_B2_C - [15:0] */
-
-/*
- * R344 (0x158) - EQ10
- */
-#define WM8962_EQL_B2_PG_MASK 0xFFFF /* EQL_B2_PG - [15:0] */
-#define WM8962_EQL_B2_PG_SHIFT 0 /* EQL_B2_PG - [15:0] */
-#define WM8962_EQL_B2_PG_WIDTH 16 /* EQL_B2_PG - [15:0] */
-
-/*
- * R345 (0x159) - EQ11
- */
-#define WM8962_EQL_B3_A_MASK 0xFFFF /* EQL_B3_A - [15:0] */
-#define WM8962_EQL_B3_A_SHIFT 0 /* EQL_B3_A - [15:0] */
-#define WM8962_EQL_B3_A_WIDTH 16 /* EQL_B3_A - [15:0] */
-
-/*
- * R346 (0x15A) - EQ12
- */
-#define WM8962_EQL_B3_B_MASK 0xFFFF /* EQL_B3_B - [15:0] */
-#define WM8962_EQL_B3_B_SHIFT 0 /* EQL_B3_B - [15:0] */
-#define WM8962_EQL_B3_B_WIDTH 16 /* EQL_B3_B - [15:0] */
-
-/*
- * R347 (0x15B) - EQ13
- */
-#define WM8962_EQL_B3_C_MASK 0xFFFF /* EQL_B3_C - [15:0] */
-#define WM8962_EQL_B3_C_SHIFT 0 /* EQL_B3_C - [15:0] */
-#define WM8962_EQL_B3_C_WIDTH 16 /* EQL_B3_C - [15:0] */
-
-/*
- * R348 (0x15C) - EQ14
- */
-#define WM8962_EQL_B3_PG_MASK 0xFFFF /* EQL_B3_PG - [15:0] */
-#define WM8962_EQL_B3_PG_SHIFT 0 /* EQL_B3_PG - [15:0] */
-#define WM8962_EQL_B3_PG_WIDTH 16 /* EQL_B3_PG - [15:0] */
-
-/*
- * R349 (0x15D) - EQ15
- */
-#define WM8962_EQL_B4_A_MASK 0xFFFF /* EQL_B4_A - [15:0] */
-#define WM8962_EQL_B4_A_SHIFT 0 /* EQL_B4_A - [15:0] */
-#define WM8962_EQL_B4_A_WIDTH 16 /* EQL_B4_A - [15:0] */
-
-/*
- * R350 (0x15E) - EQ16
- */
-#define WM8962_EQL_B4_B_MASK 0xFFFF /* EQL_B4_B - [15:0] */
-#define WM8962_EQL_B4_B_SHIFT 0 /* EQL_B4_B - [15:0] */
-#define WM8962_EQL_B4_B_WIDTH 16 /* EQL_B4_B - [15:0] */
-
-/*
- * R351 (0x15F) - EQ17
- */
-#define WM8962_EQL_B4_C_MASK 0xFFFF /* EQL_B4_C - [15:0] */
-#define WM8962_EQL_B4_C_SHIFT 0 /* EQL_B4_C - [15:0] */
-#define WM8962_EQL_B4_C_WIDTH 16 /* EQL_B4_C - [15:0] */
-
-/*
- * R352 (0x160) - EQ18
- */
-#define WM8962_EQL_B4_PG_MASK 0xFFFF /* EQL_B4_PG - [15:0] */
-#define WM8962_EQL_B4_PG_SHIFT 0 /* EQL_B4_PG - [15:0] */
-#define WM8962_EQL_B4_PG_WIDTH 16 /* EQL_B4_PG - [15:0] */
-
-/*
- * R353 (0x161) - EQ19
- */
-#define WM8962_EQL_B5_A_MASK 0xFFFF /* EQL_B5_A - [15:0] */
-#define WM8962_EQL_B5_A_SHIFT 0 /* EQL_B5_A - [15:0] */
-#define WM8962_EQL_B5_A_WIDTH 16 /* EQL_B5_A - [15:0] */
-
-/*
- * R354 (0x162) - EQ20
- */
-#define WM8962_EQL_B5_B_MASK 0xFFFF /* EQL_B5_B - [15:0] */
-#define WM8962_EQL_B5_B_SHIFT 0 /* EQL_B5_B - [15:0] */
-#define WM8962_EQL_B5_B_WIDTH 16 /* EQL_B5_B - [15:0] */
-
-/*
- * R355 (0x163) - EQ21
- */
-#define WM8962_EQL_B5_PG_MASK 0xFFFF /* EQL_B5_PG - [15:0] */
-#define WM8962_EQL_B5_PG_SHIFT 0 /* EQL_B5_PG - [15:0] */
-#define WM8962_EQL_B5_PG_WIDTH 16 /* EQL_B5_PG - [15:0] */
-
-/*
- * R356 (0x164) - EQ22
- */
-#define WM8962_EQR_B1_GAIN_MASK 0xF800 /* EQR_B1_GAIN - [15:11] */
-#define WM8962_EQR_B1_GAIN_SHIFT 11 /* EQR_B1_GAIN - [15:11] */
-#define WM8962_EQR_B1_GAIN_WIDTH 5 /* EQR_B1_GAIN - [15:11] */
-#define WM8962_EQR_B2_GAIN_MASK 0x07C0 /* EQR_B2_GAIN - [10:6] */
-#define WM8962_EQR_B2_GAIN_SHIFT 6 /* EQR_B2_GAIN - [10:6] */
-#define WM8962_EQR_B2_GAIN_WIDTH 5 /* EQR_B2_GAIN - [10:6] */
-#define WM8962_EQR_B3_GAIN_MASK 0x003E /* EQR_B3_GAIN - [5:1] */
-#define WM8962_EQR_B3_GAIN_SHIFT 1 /* EQR_B3_GAIN - [5:1] */
-#define WM8962_EQR_B3_GAIN_WIDTH 5 /* EQR_B3_GAIN - [5:1] */
-
-/*
- * R357 (0x165) - EQ23
- */
-#define WM8962_EQR_B4_GAIN_MASK 0xF800 /* EQR_B4_GAIN - [15:11] */
-#define WM8962_EQR_B4_GAIN_SHIFT 11 /* EQR_B4_GAIN - [15:11] */
-#define WM8962_EQR_B4_GAIN_WIDTH 5 /* EQR_B4_GAIN - [15:11] */
-#define WM8962_EQR_B5_GAIN_MASK 0x07C0 /* EQR_B5_GAIN - [10:6] */
-#define WM8962_EQR_B5_GAIN_SHIFT 6 /* EQR_B5_GAIN - [10:6] */
-#define WM8962_EQR_B5_GAIN_WIDTH 5 /* EQR_B5_GAIN - [10:6] */
-
-/*
- * R358 (0x166) - EQ24
- */
-#define WM8962_EQR_B1_A_MASK 0xFFFF /* EQR_B1_A - [15:0] */
-#define WM8962_EQR_B1_A_SHIFT 0 /* EQR_B1_A - [15:0] */
-#define WM8962_EQR_B1_A_WIDTH 16 /* EQR_B1_A - [15:0] */
-
-/*
- * R359 (0x167) - EQ25
- */
-#define WM8962_EQR_B1_B_MASK 0xFFFF /* EQR_B1_B - [15:0] */
-#define WM8962_EQR_B1_B_SHIFT 0 /* EQR_B1_B - [15:0] */
-#define WM8962_EQR_B1_B_WIDTH 16 /* EQR_B1_B - [15:0] */
-
-/*
- * R360 (0x168) - EQ26
- */
-#define WM8962_EQR_B1_PG_MASK 0xFFFF /* EQR_B1_PG - [15:0] */
-#define WM8962_EQR_B1_PG_SHIFT 0 /* EQR_B1_PG - [15:0] */
-#define WM8962_EQR_B1_PG_WIDTH 16 /* EQR_B1_PG - [15:0] */
-
-/*
- * R361 (0x169) - EQ27
- */
-#define WM8962_EQR_B2_A_MASK 0xFFFF /* EQR_B2_A - [15:0] */
-#define WM8962_EQR_B2_A_SHIFT 0 /* EQR_B2_A - [15:0] */
-#define WM8962_EQR_B2_A_WIDTH 16 /* EQR_B2_A - [15:0] */
-
-/*
- * R362 (0x16A) - EQ28
- */
-#define WM8962_EQR_B2_B_MASK 0xFFFF /* EQR_B2_B - [15:0] */
-#define WM8962_EQR_B2_B_SHIFT 0 /* EQR_B2_B - [15:0] */
-#define WM8962_EQR_B2_B_WIDTH 16 /* EQR_B2_B - [15:0] */
-
-/*
- * R363 (0x16B) - EQ29
- */
-#define WM8962_EQR_B2_C_MASK 0xFFFF /* EQR_B2_C - [15:0] */
-#define WM8962_EQR_B2_C_SHIFT 0 /* EQR_B2_C - [15:0] */
-#define WM8962_EQR_B2_C_WIDTH 16 /* EQR_B2_C - [15:0] */
-
-/*
- * R364 (0x16C) - EQ30
- */
-#define WM8962_EQR_B2_PG_MASK 0xFFFF /* EQR_B2_PG - [15:0] */
-#define WM8962_EQR_B2_PG_SHIFT 0 /* EQR_B2_PG - [15:0] */
-#define WM8962_EQR_B2_PG_WIDTH 16 /* EQR_B2_PG - [15:0] */
-
-/*
- * R365 (0x16D) - EQ31
- */
-#define WM8962_EQR_B3_A_MASK 0xFFFF /* EQR_B3_A - [15:0] */
-#define WM8962_EQR_B3_A_SHIFT 0 /* EQR_B3_A - [15:0] */
-#define WM8962_EQR_B3_A_WIDTH 16 /* EQR_B3_A - [15:0] */
-
-/*
- * R366 (0x16E) - EQ32
- */
-#define WM8962_EQR_B3_B_MASK 0xFFFF /* EQR_B3_B - [15:0] */
-#define WM8962_EQR_B3_B_SHIFT 0 /* EQR_B3_B - [15:0] */
-#define WM8962_EQR_B3_B_WIDTH 16 /* EQR_B3_B - [15:0] */
-
-/*
- * R367 (0x16F) - EQ33
- */
-#define WM8962_EQR_B3_C_MASK 0xFFFF /* EQR_B3_C - [15:0] */
-#define WM8962_EQR_B3_C_SHIFT 0 /* EQR_B3_C - [15:0] */
-#define WM8962_EQR_B3_C_WIDTH 16 /* EQR_B3_C - [15:0] */
-
-/*
- * R368 (0x170) - EQ34
- */
-#define WM8962_EQR_B3_PG_MASK 0xFFFF /* EQR_B3_PG - [15:0] */
-#define WM8962_EQR_B3_PG_SHIFT 0 /* EQR_B3_PG - [15:0] */
-#define WM8962_EQR_B3_PG_WIDTH 16 /* EQR_B3_PG - [15:0] */
-
-/*
- * R369 (0x171) - EQ35
- */
-#define WM8962_EQR_B4_A_MASK 0xFFFF /* EQR_B4_A - [15:0] */
-#define WM8962_EQR_B4_A_SHIFT 0 /* EQR_B4_A - [15:0] */
-#define WM8962_EQR_B4_A_WIDTH 16 /* EQR_B4_A - [15:0] */
-
-/*
- * R370 (0x172) - EQ36
- */
-#define WM8962_EQR_B4_B_MASK 0xFFFF /* EQR_B4_B - [15:0] */
-#define WM8962_EQR_B4_B_SHIFT 0 /* EQR_B4_B - [15:0] */
-#define WM8962_EQR_B4_B_WIDTH 16 /* EQR_B4_B - [15:0] */
-
-/*
- * R371 (0x173) - EQ37
- */
-#define WM8962_EQR_B4_C_MASK 0xFFFF /* EQR_B4_C - [15:0] */
-#define WM8962_EQR_B4_C_SHIFT 0 /* EQR_B4_C - [15:0] */
-#define WM8962_EQR_B4_C_WIDTH 16 /* EQR_B4_C - [15:0] */
-
-/*
- * R372 (0x174) - EQ38
- */
-#define WM8962_EQR_B4_PG_MASK 0xFFFF /* EQR_B4_PG - [15:0] */
-#define WM8962_EQR_B4_PG_SHIFT 0 /* EQR_B4_PG - [15:0] */
-#define WM8962_EQR_B4_PG_WIDTH 16 /* EQR_B4_PG - [15:0] */
-
-/*
- * R373 (0x175) - EQ39
- */
-#define WM8962_EQR_B5_A_MASK 0xFFFF /* EQR_B5_A - [15:0] */
-#define WM8962_EQR_B5_A_SHIFT 0 /* EQR_B5_A - [15:0] */
-#define WM8962_EQR_B5_A_WIDTH 16 /* EQR_B5_A - [15:0] */
-
-/*
- * R374 (0x176) - EQ40
- */
-#define WM8962_EQR_B5_B_MASK 0xFFFF /* EQR_B5_B - [15:0] */
-#define WM8962_EQR_B5_B_SHIFT 0 /* EQR_B5_B - [15:0] */
-#define WM8962_EQR_B5_B_WIDTH 16 /* EQR_B5_B - [15:0] */
-
-/*
- * R375 (0x177) - EQ41
- */
-#define WM8962_EQR_B5_PG_MASK 0xFFFF /* EQR_B5_PG - [15:0] */
-#define WM8962_EQR_B5_PG_SHIFT 0 /* EQR_B5_PG - [15:0] */
-#define WM8962_EQR_B5_PG_WIDTH 16 /* EQR_B5_PG - [15:0] */
-
-/*
- * R513 (0x201) - GPIO 2
- */
-#define WM8962_GP2_POL 0x0400 /* GP2_POL */
-#define WM8962_GP2_POL_MASK 0x0400 /* GP2_POL */
-#define WM8962_GP2_POL_SHIFT 10 /* GP2_POL */
-#define WM8962_GP2_POL_WIDTH 1 /* GP2_POL */
-#define WM8962_GP2_LVL 0x0040 /* GP2_LVL */
-#define WM8962_GP2_LVL_MASK 0x0040 /* GP2_LVL */
-#define WM8962_GP2_LVL_SHIFT 6 /* GP2_LVL */
-#define WM8962_GP2_LVL_WIDTH 1 /* GP2_LVL */
-#define WM8962_GP2_FN_MASK 0x001F /* GP2_FN - [4:0] */
-#define WM8962_GP2_FN_SHIFT 0 /* GP2_FN - [4:0] */
-#define WM8962_GP2_FN_WIDTH 5 /* GP2_FN - [4:0] */
-
-/*
- * R514 (0x202) - GPIO 3
- */
-#define WM8962_GP3_POL 0x0400 /* GP3_POL */
-#define WM8962_GP3_POL_MASK 0x0400 /* GP3_POL */
-#define WM8962_GP3_POL_SHIFT 10 /* GP3_POL */
-#define WM8962_GP3_POL_WIDTH 1 /* GP3_POL */
-#define WM8962_GP3_LVL 0x0040 /* GP3_LVL */
-#define WM8962_GP3_LVL_MASK 0x0040 /* GP3_LVL */
-#define WM8962_GP3_LVL_SHIFT 6 /* GP3_LVL */
-#define WM8962_GP3_LVL_WIDTH 1 /* GP3_LVL */
-#define WM8962_GP3_FN_MASK 0x001F /* GP3_FN - [4:0] */
-#define WM8962_GP3_FN_SHIFT 0 /* GP3_FN - [4:0] */
-#define WM8962_GP3_FN_WIDTH 5 /* GP3_FN - [4:0] */
-
-/*
- * R516 (0x204) - GPIO 5
- */
-#define WM8962_GP5_DIR 0x8000 /* GP5_DIR */
-#define WM8962_GP5_DIR_MASK 0x8000 /* GP5_DIR */
-#define WM8962_GP5_DIR_SHIFT 15 /* GP5_DIR */
-#define WM8962_GP5_DIR_WIDTH 1 /* GP5_DIR */
-#define WM8962_GP5_PU 0x4000 /* GP5_PU */
-#define WM8962_GP5_PU_MASK 0x4000 /* GP5_PU */
-#define WM8962_GP5_PU_SHIFT 14 /* GP5_PU */
-#define WM8962_GP5_PU_WIDTH 1 /* GP5_PU */
-#define WM8962_GP5_PD 0x2000 /* GP5_PD */
-#define WM8962_GP5_PD_MASK 0x2000 /* GP5_PD */
-#define WM8962_GP5_PD_SHIFT 13 /* GP5_PD */
-#define WM8962_GP5_PD_WIDTH 1 /* GP5_PD */
-#define WM8962_GP5_POL 0x0400 /* GP5_POL */
-#define WM8962_GP5_POL_MASK 0x0400 /* GP5_POL */
-#define WM8962_GP5_POL_SHIFT 10 /* GP5_POL */
-#define WM8962_GP5_POL_WIDTH 1 /* GP5_POL */
-#define WM8962_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */
-#define WM8962_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */
-#define WM8962_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */
-#define WM8962_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
-#define WM8962_GP5_DB 0x0100 /* GP5_DB */
-#define WM8962_GP5_DB_MASK 0x0100 /* GP5_DB */
-#define WM8962_GP5_DB_SHIFT 8 /* GP5_DB */
-#define WM8962_GP5_DB_WIDTH 1 /* GP5_DB */
-#define WM8962_GP5_LVL 0x0040 /* GP5_LVL */
-#define WM8962_GP5_LVL_MASK 0x0040 /* GP5_LVL */
-#define WM8962_GP5_LVL_SHIFT 6 /* GP5_LVL */
-#define WM8962_GP5_LVL_WIDTH 1 /* GP5_LVL */
-#define WM8962_GP5_FN_MASK 0x001F /* GP5_FN - [4:0] */
-#define WM8962_GP5_FN_SHIFT 0 /* GP5_FN - [4:0] */
-#define WM8962_GP5_FN_WIDTH 5 /* GP5_FN - [4:0] */
-
-/*
- * R517 (0x205) - GPIO 6
- */
-#define WM8962_GP6_DIR 0x8000 /* GP6_DIR */
-#define WM8962_GP6_DIR_MASK 0x8000 /* GP6_DIR */
-#define WM8962_GP6_DIR_SHIFT 15 /* GP6_DIR */
-#define WM8962_GP6_DIR_WIDTH 1 /* GP6_DIR */
-#define WM8962_GP6_PU 0x4000 /* GP6_PU */
-#define WM8962_GP6_PU_MASK 0x4000 /* GP6_PU */
-#define WM8962_GP6_PU_SHIFT 14 /* GP6_PU */
-#define WM8962_GP6_PU_WIDTH 1 /* GP6_PU */
-#define WM8962_GP6_PD 0x2000 /* GP6_PD */
-#define WM8962_GP6_PD_MASK 0x2000 /* GP6_PD */
-#define WM8962_GP6_PD_SHIFT 13 /* GP6_PD */
-#define WM8962_GP6_PD_WIDTH 1 /* GP6_PD */
-#define WM8962_GP6_POL 0x0400 /* GP6_POL */
-#define WM8962_GP6_POL_MASK 0x0400 /* GP6_POL */
-#define WM8962_GP6_POL_SHIFT 10 /* GP6_POL */
-#define WM8962_GP6_POL_WIDTH 1 /* GP6_POL */
-#define WM8962_GP6_OP_CFG 0x0200 /* GP6_OP_CFG */
-#define WM8962_GP6_OP_CFG_MASK 0x0200 /* GP6_OP_CFG */
-#define WM8962_GP6_OP_CFG_SHIFT 9 /* GP6_OP_CFG */
-#define WM8962_GP6_OP_CFG_WIDTH 1 /* GP6_OP_CFG */
-#define WM8962_GP6_DB 0x0100 /* GP6_DB */
-#define WM8962_GP6_DB_MASK 0x0100 /* GP6_DB */
-#define WM8962_GP6_DB_SHIFT 8 /* GP6_DB */
-#define WM8962_GP6_DB_WIDTH 1 /* GP6_DB */
-#define WM8962_GP6_LVL 0x0040 /* GP6_LVL */
-#define WM8962_GP6_LVL_MASK 0x0040 /* GP6_LVL */
-#define WM8962_GP6_LVL_SHIFT 6 /* GP6_LVL */
-#define WM8962_GP6_LVL_WIDTH 1 /* GP6_LVL */
-#define WM8962_GP6_FN_MASK 0x001F /* GP6_FN - [4:0] */
-#define WM8962_GP6_FN_SHIFT 0 /* GP6_FN - [4:0] */
-#define WM8962_GP6_FN_WIDTH 5 /* GP6_FN - [4:0] */
-
-/*
- * R560 (0x230) - Interrupt Status 1
- */
-#define WM8962_GP6_EINT 0x0020 /* GP6_EINT */
-#define WM8962_GP6_EINT_MASK 0x0020 /* GP6_EINT */
-#define WM8962_GP6_EINT_SHIFT 5 /* GP6_EINT */
-#define WM8962_GP6_EINT_WIDTH 1 /* GP6_EINT */
-#define WM8962_GP5_EINT 0x0010 /* GP5_EINT */
-#define WM8962_GP5_EINT_MASK 0x0010 /* GP5_EINT */
-#define WM8962_GP5_EINT_SHIFT 4 /* GP5_EINT */
-#define WM8962_GP5_EINT_WIDTH 1 /* GP5_EINT */
-
-/*
- * R561 (0x231) - Interrupt Status 2
- */
-#define WM8962_MICSCD_EINT 0x8000 /* MICSCD_EINT */
-#define WM8962_MICSCD_EINT_MASK 0x8000 /* MICSCD_EINT */
-#define WM8962_MICSCD_EINT_SHIFT 15 /* MICSCD_EINT */
-#define WM8962_MICSCD_EINT_WIDTH 1 /* MICSCD_EINT */
-#define WM8962_MICD_EINT 0x4000 /* MICD_EINT */
-#define WM8962_MICD_EINT_MASK 0x4000 /* MICD_EINT */
-#define WM8962_MICD_EINT_SHIFT 14 /* MICD_EINT */
-#define WM8962_MICD_EINT_WIDTH 1 /* MICD_EINT */
-#define WM8962_FIFOS_ERR_EINT 0x2000 /* FIFOS_ERR_EINT */
-#define WM8962_FIFOS_ERR_EINT_MASK 0x2000 /* FIFOS_ERR_EINT */
-#define WM8962_FIFOS_ERR_EINT_SHIFT 13 /* FIFOS_ERR_EINT */
-#define WM8962_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */
-#define WM8962_ALC_LOCK_EINT 0x1000 /* ALC_LOCK_EINT */
-#define WM8962_ALC_LOCK_EINT_MASK 0x1000 /* ALC_LOCK_EINT */
-#define WM8962_ALC_LOCK_EINT_SHIFT 12 /* ALC_LOCK_EINT */
-#define WM8962_ALC_LOCK_EINT_WIDTH 1 /* ALC_LOCK_EINT */
-#define WM8962_ALC_THRESH_EINT 0x0800 /* ALC_THRESH_EINT */
-#define WM8962_ALC_THRESH_EINT_MASK 0x0800 /* ALC_THRESH_EINT */
-#define WM8962_ALC_THRESH_EINT_SHIFT 11 /* ALC_THRESH_EINT */
-#define WM8962_ALC_THRESH_EINT_WIDTH 1 /* ALC_THRESH_EINT */
-#define WM8962_ALC_SAT_EINT 0x0400 /* ALC_SAT_EINT */
-#define WM8962_ALC_SAT_EINT_MASK 0x0400 /* ALC_SAT_EINT */
-#define WM8962_ALC_SAT_EINT_SHIFT 10 /* ALC_SAT_EINT */
-#define WM8962_ALC_SAT_EINT_WIDTH 1 /* ALC_SAT_EINT */
-#define WM8962_ALC_PKOVR_EINT 0x0200 /* ALC_PKOVR_EINT */
-#define WM8962_ALC_PKOVR_EINT_MASK 0x0200 /* ALC_PKOVR_EINT */
-#define WM8962_ALC_PKOVR_EINT_SHIFT 9 /* ALC_PKOVR_EINT */
-#define WM8962_ALC_PKOVR_EINT_WIDTH 1 /* ALC_PKOVR_EINT */
-#define WM8962_ALC_NGATE_EINT 0x0100 /* ALC_NGATE_EINT */
-#define WM8962_ALC_NGATE_EINT_MASK 0x0100 /* ALC_NGATE_EINT */
-#define WM8962_ALC_NGATE_EINT_SHIFT 8 /* ALC_NGATE_EINT */
-#define WM8962_ALC_NGATE_EINT_WIDTH 1 /* ALC_NGATE_EINT */
-#define WM8962_WSEQ_DONE_EINT 0x0080 /* WSEQ_DONE_EINT */
-#define WM8962_WSEQ_DONE_EINT_MASK 0x0080 /* WSEQ_DONE_EINT */
-#define WM8962_WSEQ_DONE_EINT_SHIFT 7 /* WSEQ_DONE_EINT */
-#define WM8962_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */
-#define WM8962_DRC_ACTDET_EINT 0x0040 /* DRC_ACTDET_EINT */
-#define WM8962_DRC_ACTDET_EINT_MASK 0x0040 /* DRC_ACTDET_EINT */
-#define WM8962_DRC_ACTDET_EINT_SHIFT 6 /* DRC_ACTDET_EINT */
-#define WM8962_DRC_ACTDET_EINT_WIDTH 1 /* DRC_ACTDET_EINT */
-#define WM8962_FLL_LOCK_EINT 0x0020 /* FLL_LOCK_EINT */
-#define WM8962_FLL_LOCK_EINT_MASK 0x0020 /* FLL_LOCK_EINT */
-#define WM8962_FLL_LOCK_EINT_SHIFT 5 /* FLL_LOCK_EINT */
-#define WM8962_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */
-#define WM8962_PLL3_LOCK_EINT 0x0008 /* PLL3_LOCK_EINT */
-#define WM8962_PLL3_LOCK_EINT_MASK 0x0008 /* PLL3_LOCK_EINT */
-#define WM8962_PLL3_LOCK_EINT_SHIFT 3 /* PLL3_LOCK_EINT */
-#define WM8962_PLL3_LOCK_EINT_WIDTH 1 /* PLL3_LOCK_EINT */
-#define WM8962_PLL2_LOCK_EINT 0x0004 /* PLL2_LOCK_EINT */
-#define WM8962_PLL2_LOCK_EINT_MASK 0x0004 /* PLL2_LOCK_EINT */
-#define WM8962_PLL2_LOCK_EINT_SHIFT 2 /* PLL2_LOCK_EINT */
-#define WM8962_PLL2_LOCK_EINT_WIDTH 1 /* PLL2_LOCK_EINT */
-#define WM8962_TEMP_SHUT_EINT 0x0001 /* TEMP_SHUT_EINT */
-#define WM8962_TEMP_SHUT_EINT_MASK 0x0001 /* TEMP_SHUT_EINT */
-#define WM8962_TEMP_SHUT_EINT_SHIFT 0 /* TEMP_SHUT_EINT */
-#define WM8962_TEMP_SHUT_EINT_WIDTH 1 /* TEMP_SHUT_EINT */
-
-/*
- * R568 (0x238) - Interrupt Status 1 Mask
- */
-#define WM8962_IM_GP6_EINT 0x0020 /* IM_GP6_EINT */
-#define WM8962_IM_GP6_EINT_MASK 0x0020 /* IM_GP6_EINT */
-#define WM8962_IM_GP6_EINT_SHIFT 5 /* IM_GP6_EINT */
-#define WM8962_IM_GP6_EINT_WIDTH 1 /* IM_GP6_EINT */
-#define WM8962_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
-#define WM8962_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
-#define WM8962_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
-#define WM8962_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
-
-/*
- * R569 (0x239) - Interrupt Status 2 Mask
- */
-#define WM8962_IM_MICSCD_EINT 0x8000 /* IM_MICSCD_EINT */
-#define WM8962_IM_MICSCD_EINT_MASK 0x8000 /* IM_MICSCD_EINT */
-#define WM8962_IM_MICSCD_EINT_SHIFT 15 /* IM_MICSCD_EINT */
-#define WM8962_IM_MICSCD_EINT_WIDTH 1 /* IM_MICSCD_EINT */
-#define WM8962_IM_MICD_EINT 0x4000 /* IM_MICD_EINT */
-#define WM8962_IM_MICD_EINT_MASK 0x4000 /* IM_MICD_EINT */
-#define WM8962_IM_MICD_EINT_SHIFT 14 /* IM_MICD_EINT */
-#define WM8962_IM_MICD_EINT_WIDTH 1 /* IM_MICD_EINT */
-#define WM8962_IM_FIFOS_ERR_EINT 0x2000 /* IM_FIFOS_ERR_EINT */
-#define WM8962_IM_FIFOS_ERR_EINT_MASK 0x2000 /* IM_FIFOS_ERR_EINT */
-#define WM8962_IM_FIFOS_ERR_EINT_SHIFT 13 /* IM_FIFOS_ERR_EINT */
-#define WM8962_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */
-#define WM8962_IM_ALC_LOCK_EINT 0x1000 /* IM_ALC_LOCK_EINT */
-#define WM8962_IM_ALC_LOCK_EINT_MASK 0x1000 /* IM_ALC_LOCK_EINT */
-#define WM8962_IM_ALC_LOCK_EINT_SHIFT 12 /* IM_ALC_LOCK_EINT */
-#define WM8962_IM_ALC_LOCK_EINT_WIDTH 1 /* IM_ALC_LOCK_EINT */
-#define WM8962_IM_ALC_THRESH_EINT 0x0800 /* IM_ALC_THRESH_EINT */
-#define WM8962_IM_ALC_THRESH_EINT_MASK 0x0800 /* IM_ALC_THRESH_EINT */
-#define WM8962_IM_ALC_THRESH_EINT_SHIFT 11 /* IM_ALC_THRESH_EINT */
-#define WM8962_IM_ALC_THRESH_EINT_WIDTH 1 /* IM_ALC_THRESH_EINT */
-#define WM8962_IM_ALC_SAT_EINT 0x0400 /* IM_ALC_SAT_EINT */
-#define WM8962_IM_ALC_SAT_EINT_MASK 0x0400 /* IM_ALC_SAT_EINT */
-#define WM8962_IM_ALC_SAT_EINT_SHIFT 10 /* IM_ALC_SAT_EINT */
-#define WM8962_IM_ALC_SAT_EINT_WIDTH 1 /* IM_ALC_SAT_EINT */
-#define WM8962_IM_ALC_PKOVR_EINT 0x0200 /* IM_ALC_PKOVR_EINT */
-#define WM8962_IM_ALC_PKOVR_EINT_MASK 0x0200 /* IM_ALC_PKOVR_EINT */
-#define WM8962_IM_ALC_PKOVR_EINT_SHIFT 9 /* IM_ALC_PKOVR_EINT */
-#define WM8962_IM_ALC_PKOVR_EINT_WIDTH 1 /* IM_ALC_PKOVR_EINT */
-#define WM8962_IM_ALC_NGATE_EINT 0x0100 /* IM_ALC_NGATE_EINT */
-#define WM8962_IM_ALC_NGATE_EINT_MASK 0x0100 /* IM_ALC_NGATE_EINT */
-#define WM8962_IM_ALC_NGATE_EINT_SHIFT 8 /* IM_ALC_NGATE_EINT */
-#define WM8962_IM_ALC_NGATE_EINT_WIDTH 1 /* IM_ALC_NGATE_EINT */
-#define WM8962_IM_WSEQ_DONE_EINT 0x0080 /* IM_WSEQ_DONE_EINT */
-#define WM8962_IM_WSEQ_DONE_EINT_MASK 0x0080 /* IM_WSEQ_DONE_EINT */
-#define WM8962_IM_WSEQ_DONE_EINT_SHIFT 7 /* IM_WSEQ_DONE_EINT */
-#define WM8962_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */
-#define WM8962_IM_DRC_ACTDET_EINT 0x0040 /* IM_DRC_ACTDET_EINT */
-#define WM8962_IM_DRC_ACTDET_EINT_MASK 0x0040 /* IM_DRC_ACTDET_EINT */
-#define WM8962_IM_DRC_ACTDET_EINT_SHIFT 6 /* IM_DRC_ACTDET_EINT */
-#define WM8962_IM_DRC_ACTDET_EINT_WIDTH 1 /* IM_DRC_ACTDET_EINT */
-#define WM8962_IM_FLL_LOCK_EINT 0x0020 /* IM_FLL_LOCK_EINT */
-#define WM8962_IM_FLL_LOCK_EINT_MASK 0x0020 /* IM_FLL_LOCK_EINT */
-#define WM8962_IM_FLL_LOCK_EINT_SHIFT 5 /* IM_FLL_LOCK_EINT */
-#define WM8962_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */
-#define WM8962_IM_PLL3_LOCK_EINT 0x0008 /* IM_PLL3_LOCK_EINT */
-#define WM8962_IM_PLL3_LOCK_EINT_MASK 0x0008 /* IM_PLL3_LOCK_EINT */
-#define WM8962_IM_PLL3_LOCK_EINT_SHIFT 3 /* IM_PLL3_LOCK_EINT */
-#define WM8962_IM_PLL3_LOCK_EINT_WIDTH 1 /* IM_PLL3_LOCK_EINT */
-#define WM8962_IM_PLL2_LOCK_EINT 0x0004 /* IM_PLL2_LOCK_EINT */
-#define WM8962_IM_PLL2_LOCK_EINT_MASK 0x0004 /* IM_PLL2_LOCK_EINT */
-#define WM8962_IM_PLL2_LOCK_EINT_SHIFT 2 /* IM_PLL2_LOCK_EINT */
-#define WM8962_IM_PLL2_LOCK_EINT_WIDTH 1 /* IM_PLL2_LOCK_EINT */
-#define WM8962_IM_TEMP_SHUT_EINT 0x0001 /* IM_TEMP_SHUT_EINT */
-#define WM8962_IM_TEMP_SHUT_EINT_MASK 0x0001 /* IM_TEMP_SHUT_EINT */
-#define WM8962_IM_TEMP_SHUT_EINT_SHIFT 0 /* IM_TEMP_SHUT_EINT */
-#define WM8962_IM_TEMP_SHUT_EINT_WIDTH 1 /* IM_TEMP_SHUT_EINT */
-
-/*
- * R576 (0x240) - Interrupt Control
- */
-#define WM8962_IRQ_POL 0x0001 /* IRQ_POL */
-#define WM8962_IRQ_POL_MASK 0x0001 /* IRQ_POL */
-#define WM8962_IRQ_POL_SHIFT 0 /* IRQ_POL */
-#define WM8962_IRQ_POL_WIDTH 1 /* IRQ_POL */
-
-/*
- * R584 (0x248) - IRQ Debounce
- */
-#define WM8962_FLL_LOCK_DB 0x0020 /* FLL_LOCK_DB */
-#define WM8962_FLL_LOCK_DB_MASK 0x0020 /* FLL_LOCK_DB */
-#define WM8962_FLL_LOCK_DB_SHIFT 5 /* FLL_LOCK_DB */
-#define WM8962_FLL_LOCK_DB_WIDTH 1 /* FLL_LOCK_DB */
-#define WM8962_PLL3_LOCK_DB 0x0008 /* PLL3_LOCK_DB */
-#define WM8962_PLL3_LOCK_DB_MASK 0x0008 /* PLL3_LOCK_DB */
-#define WM8962_PLL3_LOCK_DB_SHIFT 3 /* PLL3_LOCK_DB */
-#define WM8962_PLL3_LOCK_DB_WIDTH 1 /* PLL3_LOCK_DB */
-#define WM8962_PLL2_LOCK_DB 0x0004 /* PLL2_LOCK_DB */
-#define WM8962_PLL2_LOCK_DB_MASK 0x0004 /* PLL2_LOCK_DB */
-#define WM8962_PLL2_LOCK_DB_SHIFT 2 /* PLL2_LOCK_DB */
-#define WM8962_PLL2_LOCK_DB_WIDTH 1 /* PLL2_LOCK_DB */
-#define WM8962_TEMP_SHUT_DB 0x0001 /* TEMP_SHUT_DB */
-#define WM8962_TEMP_SHUT_DB_MASK 0x0001 /* TEMP_SHUT_DB */
-#define WM8962_TEMP_SHUT_DB_SHIFT 0 /* TEMP_SHUT_DB */
-#define WM8962_TEMP_SHUT_DB_WIDTH 1 /* TEMP_SHUT_DB */
-
-/*
- * R586 (0x24A) - MICINT Source Pol
- */
-#define WM8962_MICSCD_IRQ_POL 0x8000 /* MICSCD_IRQ_POL */
-#define WM8962_MICSCD_IRQ_POL_MASK 0x8000 /* MICSCD_IRQ_POL */
-#define WM8962_MICSCD_IRQ_POL_SHIFT 15 /* MICSCD_IRQ_POL */
-#define WM8962_MICSCD_IRQ_POL_WIDTH 1 /* MICSCD_IRQ_POL */
-#define WM8962_MICD_IRQ_POL 0x4000 /* MICD_IRQ_POL */
-#define WM8962_MICD_IRQ_POL_MASK 0x4000 /* MICD_IRQ_POL */
-#define WM8962_MICD_IRQ_POL_SHIFT 14 /* MICD_IRQ_POL */
-#define WM8962_MICD_IRQ_POL_WIDTH 1 /* MICD_IRQ_POL */
-
-/*
- * R768 (0x300) - DSP2 Power Management
- */
-#define WM8962_DSP2_ENA 0x0001 /* DSP2_ENA */
-#define WM8962_DSP2_ENA_MASK 0x0001 /* DSP2_ENA */
-#define WM8962_DSP2_ENA_SHIFT 0 /* DSP2_ENA */
-#define WM8962_DSP2_ENA_WIDTH 1 /* DSP2_ENA */
-
-/*
- * R1037 (0x40D) - DSP2_ExecControl
- */
-#define WM8962_DSP2_STOPC 0x0020 /* DSP2_STOPC */
-#define WM8962_DSP2_STOPC_MASK 0x0020 /* DSP2_STOPC */
-#define WM8962_DSP2_STOPC_SHIFT 5 /* DSP2_STOPC */
-#define WM8962_DSP2_STOPC_WIDTH 1 /* DSP2_STOPC */
-#define WM8962_DSP2_STOPS 0x0010 /* DSP2_STOPS */
-#define WM8962_DSP2_STOPS_MASK 0x0010 /* DSP2_STOPS */
-#define WM8962_DSP2_STOPS_SHIFT 4 /* DSP2_STOPS */
-#define WM8962_DSP2_STOPS_WIDTH 1 /* DSP2_STOPS */
-#define WM8962_DSP2_STOPI 0x0008 /* DSP2_STOPI */
-#define WM8962_DSP2_STOPI_MASK 0x0008 /* DSP2_STOPI */
-#define WM8962_DSP2_STOPI_SHIFT 3 /* DSP2_STOPI */
-#define WM8962_DSP2_STOPI_WIDTH 1 /* DSP2_STOPI */
-#define WM8962_DSP2_STOP 0x0004 /* DSP2_STOP */
-#define WM8962_DSP2_STOP_MASK 0x0004 /* DSP2_STOP */
-#define WM8962_DSP2_STOP_SHIFT 2 /* DSP2_STOP */
-#define WM8962_DSP2_STOP_WIDTH 1 /* DSP2_STOP */
-#define WM8962_DSP2_RUNR 0x0002 /* DSP2_RUNR */
-#define WM8962_DSP2_RUNR_MASK 0x0002 /* DSP2_RUNR */
-#define WM8962_DSP2_RUNR_SHIFT 1 /* DSP2_RUNR */
-#define WM8962_DSP2_RUNR_WIDTH 1 /* DSP2_RUNR */
-#define WM8962_DSP2_RUN 0x0001 /* DSP2_RUN */
-#define WM8962_DSP2_RUN_MASK 0x0001 /* DSP2_RUN */
-#define WM8962_DSP2_RUN_SHIFT 0 /* DSP2_RUN */
-#define WM8962_DSP2_RUN_WIDTH 1 /* DSP2_RUN */
-
-/*
- * R8192 (0x2000) - DSP2 Instruction RAM 0
- */
-#define WM8962_DSP2_INSTR_RAM_1024_10_9_0_MASK 0x03FF /* DSP2_INSTR_RAM_1024_10_9_0 - [9:0] */
-#define WM8962_DSP2_INSTR_RAM_1024_10_9_0_SHIFT 0 /* DSP2_INSTR_RAM_1024_10_9_0 - [9:0] */
-#define WM8962_DSP2_INSTR_RAM_1024_10_9_0_WIDTH 10 /* DSP2_INSTR_RAM_1024_10_9_0 - [9:0] */
-
-/*
- * R9216 (0x2400) - DSP2 Address RAM 2
- */
-#define WM8962_DSP2_ADDR_RAM_1024_38_37_32_MASK 0x003F /* DSP2_ADDR_RAM_1024_38_37_32 - [5:0] */
-#define WM8962_DSP2_ADDR_RAM_1024_38_37_32_SHIFT 0 /* DSP2_ADDR_RAM_1024_38_37_32 - [5:0] */
-#define WM8962_DSP2_ADDR_RAM_1024_38_37_32_WIDTH 6 /* DSP2_ADDR_RAM_1024_38_37_32 - [5:0] */
-
-/*
- * R9217 (0x2401) - DSP2 Address RAM 1
- */
-#define WM8962_DSP2_ADDR_RAM_1024_38_31_16_MASK 0xFFFF /* DSP2_ADDR_RAM_1024_38_31_16 - [15:0] */
-#define WM8962_DSP2_ADDR_RAM_1024_38_31_16_SHIFT 0 /* DSP2_ADDR_RAM_1024_38_31_16 - [15:0] */
-#define WM8962_DSP2_ADDR_RAM_1024_38_31_16_WIDTH 16 /* DSP2_ADDR_RAM_1024_38_31_16 - [15:0] */
-
-/*
- * R9218 (0x2402) - DSP2 Address RAM 0
- */
-#define WM8962_DSP2_ADDR_RAM_1024_38_15_0_MASK 0xFFFF /* DSP2_ADDR_RAM_1024_38_15_0 - [15:0] */
-#define WM8962_DSP2_ADDR_RAM_1024_38_15_0_SHIFT 0 /* DSP2_ADDR_RAM_1024_38_15_0 - [15:0] */
-#define WM8962_DSP2_ADDR_RAM_1024_38_15_0_WIDTH 16 /* DSP2_ADDR_RAM_1024_38_15_0 - [15:0] */
-
-/*
- * R12288 (0x3000) - DSP2 Data1 RAM 1
- */
-#define WM8962_DSP2_DATA1_RAM_384_24_23_16_MASK 0x00FF /* DSP2_DATA1_RAM_384_24_23_16 - [7:0] */
-#define WM8962_DSP2_DATA1_RAM_384_24_23_16_SHIFT 0 /* DSP2_DATA1_RAM_384_24_23_16 - [7:0] */
-#define WM8962_DSP2_DATA1_RAM_384_24_23_16_WIDTH 8 /* DSP2_DATA1_RAM_384_24_23_16 - [7:0] */
-
-/*
- * R12289 (0x3001) - DSP2 Data1 RAM 0
- */
-#define WM8962_DSP2_DATA1_RAM_384_24_15_0_MASK 0xFFFF /* DSP2_DATA1_RAM_384_24_15_0 - [15:0] */
-#define WM8962_DSP2_DATA1_RAM_384_24_15_0_SHIFT 0 /* DSP2_DATA1_RAM_384_24_15_0 - [15:0] */
-#define WM8962_DSP2_DATA1_RAM_384_24_15_0_WIDTH 16 /* DSP2_DATA1_RAM_384_24_15_0 - [15:0] */
-
-/*
- * R13312 (0x3400) - DSP2 Data2 RAM 1
- */
-#define WM8962_DSP2_DATA2_RAM_384_24_23_16_MASK 0x00FF /* DSP2_DATA2_RAM_384_24_23_16 - [7:0] */
-#define WM8962_DSP2_DATA2_RAM_384_24_23_16_SHIFT 0 /* DSP2_DATA2_RAM_384_24_23_16 - [7:0] */
-#define WM8962_DSP2_DATA2_RAM_384_24_23_16_WIDTH 8 /* DSP2_DATA2_RAM_384_24_23_16 - [7:0] */
-
-/*
- * R13313 (0x3401) - DSP2 Data2 RAM 0
- */
-#define WM8962_DSP2_DATA2_RAM_384_24_15_0_MASK 0xFFFF /* DSP2_DATA2_RAM_384_24_15_0 - [15:0] */
-#define WM8962_DSP2_DATA2_RAM_384_24_15_0_SHIFT 0 /* DSP2_DATA2_RAM_384_24_15_0 - [15:0] */
-#define WM8962_DSP2_DATA2_RAM_384_24_15_0_WIDTH 16 /* DSP2_DATA2_RAM_384_24_15_0 - [15:0] */
-
-/*
- * R14336 (0x3800) - DSP2 Data3 RAM 1
- */
-#define WM8962_DSP2_DATA3_RAM_384_24_23_16_MASK 0x00FF /* DSP2_DATA3_RAM_384_24_23_16 - [7:0] */
-#define WM8962_DSP2_DATA3_RAM_384_24_23_16_SHIFT 0 /* DSP2_DATA3_RAM_384_24_23_16 - [7:0] */
-#define WM8962_DSP2_DATA3_RAM_384_24_23_16_WIDTH 8 /* DSP2_DATA3_RAM_384_24_23_16 - [7:0] */
-
-/*
- * R14337 (0x3801) - DSP2 Data3 RAM 0
- */
-#define WM8962_DSP2_DATA3_RAM_384_24_15_0_MASK 0xFFFF /* DSP2_DATA3_RAM_384_24_15_0 - [15:0] */
-#define WM8962_DSP2_DATA3_RAM_384_24_15_0_SHIFT 0 /* DSP2_DATA3_RAM_384_24_15_0 - [15:0] */
-#define WM8962_DSP2_DATA3_RAM_384_24_15_0_WIDTH 16 /* DSP2_DATA3_RAM_384_24_15_0 - [15:0] */
-
-/*
- * R15360 (0x3C00) - DSP2 Coeff RAM 0
- */
-#define WM8962_DSP2_CMAP_RAM_384_11_10_0_MASK 0x07FF /* DSP2_CMAP_RAM_384_11_10_0 - [10:0] */
-#define WM8962_DSP2_CMAP_RAM_384_11_10_0_SHIFT 0 /* DSP2_CMAP_RAM_384_11_10_0 - [10:0] */
-#define WM8962_DSP2_CMAP_RAM_384_11_10_0_WIDTH 11 /* DSP2_CMAP_RAM_384_11_10_0 - [10:0] */
-
-/*
- * R16384 (0x4000) - RETUNEADC_SHARED_COEFF_1
- */
-#define WM8962_ADC_RETUNE_SCV 0x0080 /* ADC_RETUNE_SCV */
-#define WM8962_ADC_RETUNE_SCV_MASK 0x0080 /* ADC_RETUNE_SCV */
-#define WM8962_ADC_RETUNE_SCV_SHIFT 7 /* ADC_RETUNE_SCV */
-#define WM8962_ADC_RETUNE_SCV_WIDTH 1 /* ADC_RETUNE_SCV */
-#define WM8962_RETUNEADC_SHARED_COEFF_22_16_MASK 0x007F /* RETUNEADC_SHARED_COEFF_22_16 - [6:0] */
-#define WM8962_RETUNEADC_SHARED_COEFF_22_16_SHIFT 0 /* RETUNEADC_SHARED_COEFF_22_16 - [6:0] */
-#define WM8962_RETUNEADC_SHARED_COEFF_22_16_WIDTH 7 /* RETUNEADC_SHARED_COEFF_22_16 - [6:0] */
-
-/*
- * R16385 (0x4001) - RETUNEADC_SHARED_COEFF_0
- */
-#define WM8962_RETUNEADC_SHARED_COEFF_15_00_MASK 0xFFFF /* RETUNEADC_SHARED_COEFF_15_00 - [15:0] */
-#define WM8962_RETUNEADC_SHARED_COEFF_15_00_SHIFT 0 /* RETUNEADC_SHARED_COEFF_15_00 - [15:0] */
-#define WM8962_RETUNEADC_SHARED_COEFF_15_00_WIDTH 16 /* RETUNEADC_SHARED_COEFF_15_00 - [15:0] */
-
-/*
- * R16386 (0x4002) - RETUNEDAC_SHARED_COEFF_1
- */
-#define WM8962_DAC_RETUNE_SCV 0x0080 /* DAC_RETUNE_SCV */
-#define WM8962_DAC_RETUNE_SCV_MASK 0x0080 /* DAC_RETUNE_SCV */
-#define WM8962_DAC_RETUNE_SCV_SHIFT 7 /* DAC_RETUNE_SCV */
-#define WM8962_DAC_RETUNE_SCV_WIDTH 1 /* DAC_RETUNE_SCV */
-#define WM8962_RETUNEDAC_SHARED_COEFF_23_16_MASK 0x007F /* RETUNEDAC_SHARED_COEFF_23_16 - [6:0] */
-#define WM8962_RETUNEDAC_SHARED_COEFF_23_16_SHIFT 0 /* RETUNEDAC_SHARED_COEFF_23_16 - [6:0] */
-#define WM8962_RETUNEDAC_SHARED_COEFF_23_16_WIDTH 7 /* RETUNEDAC_SHARED_COEFF_23_16 - [6:0] */
-
-/*
- * R16387 (0x4003) - RETUNEDAC_SHARED_COEFF_0
- */
-#define WM8962_RETUNEDAC_SHARED_COEFF_15_00_MASK 0xFFFF /* RETUNEDAC_SHARED_COEFF_15_00 - [15:0] */
-#define WM8962_RETUNEDAC_SHARED_COEFF_15_00_SHIFT 0 /* RETUNEDAC_SHARED_COEFF_15_00 - [15:0] */
-#define WM8962_RETUNEDAC_SHARED_COEFF_15_00_WIDTH 16 /* RETUNEDAC_SHARED_COEFF_15_00 - [15:0] */
-
-/*
- * R16388 (0x4004) - SOUNDSTAGE_ENABLES_1
- */
-#define WM8962_SOUNDSTAGE_ENABLES_23_16_MASK 0x00FF /* SOUNDSTAGE_ENABLES_23_16 - [7:0] */
-#define WM8962_SOUNDSTAGE_ENABLES_23_16_SHIFT 0 /* SOUNDSTAGE_ENABLES_23_16 - [7:0] */
-#define WM8962_SOUNDSTAGE_ENABLES_23_16_WIDTH 8 /* SOUNDSTAGE_ENABLES_23_16 - [7:0] */
-
-/*
- * R16389 (0x4005) - SOUNDSTAGE_ENABLES_0
- */
-#define WM8962_SOUNDSTAGE_ENABLES_15_06_MASK 0xFFC0 /* SOUNDSTAGE_ENABLES_15_06 - [15:6] */
-#define WM8962_SOUNDSTAGE_ENABLES_15_06_SHIFT 6 /* SOUNDSTAGE_ENABLES_15_06 - [15:6] */
-#define WM8962_SOUNDSTAGE_ENABLES_15_06_WIDTH 10 /* SOUNDSTAGE_ENABLES_15_06 - [15:6] */
-#define WM8962_RTN_ADC_ENA 0x0020 /* RTN_ADC_ENA */
-#define WM8962_RTN_ADC_ENA_MASK 0x0020 /* RTN_ADC_ENA */
-#define WM8962_RTN_ADC_ENA_SHIFT 5 /* RTN_ADC_ENA */
-#define WM8962_RTN_ADC_ENA_WIDTH 1 /* RTN_ADC_ENA */
-#define WM8962_RTN_DAC_ENA 0x0010 /* RTN_DAC_ENA */
-#define WM8962_RTN_DAC_ENA_MASK 0x0010 /* RTN_DAC_ENA */
-#define WM8962_RTN_DAC_ENA_SHIFT 4 /* RTN_DAC_ENA */
-#define WM8962_RTN_DAC_ENA_WIDTH 1 /* RTN_DAC_ENA */
-#define WM8962_HDBASS_ENA 0x0008 /* HDBASS_ENA */
-#define WM8962_HDBASS_ENA_MASK 0x0008 /* HDBASS_ENA */
-#define WM8962_HDBASS_ENA_SHIFT 3 /* HDBASS_ENA */
-#define WM8962_HDBASS_ENA_WIDTH 1 /* HDBASS_ENA */
-#define WM8962_HPF2_ENA 0x0004 /* HPF2_ENA */
-#define WM8962_HPF2_ENA_MASK 0x0004 /* HPF2_ENA */
-#define WM8962_HPF2_ENA_SHIFT 2 /* HPF2_ENA */
-#define WM8962_HPF2_ENA_WIDTH 1 /* HPF2_ENA */
-#define WM8962_HPF1_ENA 0x0002 /* HPF1_ENA */
-#define WM8962_HPF1_ENA_MASK 0x0002 /* HPF1_ENA */
-#define WM8962_HPF1_ENA_SHIFT 1 /* HPF1_ENA */
-#define WM8962_HPF1_ENA_WIDTH 1 /* HPF1_ENA */
-#define WM8962_VSS_ENA 0x0001 /* VSS_ENA */
-#define WM8962_VSS_ENA_MASK 0x0001 /* VSS_ENA */
-#define WM8962_VSS_ENA_SHIFT 0 /* VSS_ENA */
-#define WM8962_VSS_ENA_WIDTH 1 /* VSS_ENA */
-
-int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8971.c b/ANDROID_3.4.5/sound/soc/codecs/wm8971.c
deleted file mode 100644
index 28fe59e3..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8971.c
+++ /dev/null
@@ -1,745 +0,0 @@
-/*
- * wm8971.c -- WM8971 ALSA SoC Audio driver
- *
- * Copyright 2005 Lab126, Inc.
- *
- * Author: Kenneth Kiraly <kiraly@lab126.com>
- *
- * Based on wm8753.c by Liam Girdwood
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-
-#include "wm8971.h"
-
-#define WM8971_REG_COUNT 43
-
-static struct workqueue_struct *wm8971_workq = NULL;
-
-/* codec private data */
-struct wm8971_priv {
- enum snd_soc_control_type control_type;
- unsigned int sysclk;
-};
-
-/*
- * wm8971 register cache
- * We can't read the WM8971 register space when we
- * are using 2 wire for device control, so we cache them instead.
- */
-static const u16 wm8971_reg[] = {
- 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */
- 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */
- 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */
- 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */
- 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */
- 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */
- 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */
- 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */
- 0x0079, 0x0079, 0x0079, /* 40 */
-};
-
-#define wm8971_reset(c) snd_soc_write(c, WM8971_RESET, 0)
-
-/* WM8971 Controls */
-static const char *wm8971_bass[] = { "Linear Control", "Adaptive Boost" };
-static const char *wm8971_bass_filter[] = { "130Hz @ 48kHz",
- "200Hz @ 48kHz" };
-static const char *wm8971_treble[] = { "8kHz", "4kHz" };
-static const char *wm8971_alc_func[] = { "Off", "Right", "Left", "Stereo" };
-static const char *wm8971_ng_type[] = { "Constant PGA Gain",
- "Mute ADC Output" };
-static const char *wm8971_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
-static const char *wm8971_mono_mux[] = {"Stereo", "Mono (Left)",
- "Mono (Right)", "Digital Mono"};
-static const char *wm8971_dac_phase[] = { "Non Inverted", "Inverted" };
-static const char *wm8971_lline_mux[] = {"Line", "NC", "NC", "PGA",
- "Differential"};
-static const char *wm8971_rline_mux[] = {"Line", "Mic", "NC", "PGA",
- "Differential"};
-static const char *wm8971_lpga_sel[] = {"Line", "NC", "NC", "Differential"};
-static const char *wm8971_rpga_sel[] = {"Line", "Mic", "NC", "Differential"};
-static const char *wm8971_adcpol[] = {"Normal", "L Invert", "R Invert",
- "L + R Invert"};
-
-static const struct soc_enum wm8971_enum[] = {
- SOC_ENUM_SINGLE(WM8971_BASS, 7, 2, wm8971_bass), /* 0 */
- SOC_ENUM_SINGLE(WM8971_BASS, 6, 2, wm8971_bass_filter),
- SOC_ENUM_SINGLE(WM8971_TREBLE, 6, 2, wm8971_treble),
- SOC_ENUM_SINGLE(WM8971_ALC1, 7, 4, wm8971_alc_func),
- SOC_ENUM_SINGLE(WM8971_NGATE, 1, 2, wm8971_ng_type), /* 4 */
- SOC_ENUM_SINGLE(WM8971_ADCDAC, 1, 4, wm8971_deemp),
- SOC_ENUM_SINGLE(WM8971_ADCTL1, 4, 4, wm8971_mono_mux),
- SOC_ENUM_SINGLE(WM8971_ADCTL1, 1, 2, wm8971_dac_phase),
- SOC_ENUM_SINGLE(WM8971_LOUTM1, 0, 5, wm8971_lline_mux), /* 8 */
- SOC_ENUM_SINGLE(WM8971_ROUTM1, 0, 5, wm8971_rline_mux),
- SOC_ENUM_SINGLE(WM8971_LADCIN, 6, 4, wm8971_lpga_sel),
- SOC_ENUM_SINGLE(WM8971_RADCIN, 6, 4, wm8971_rpga_sel),
- SOC_ENUM_SINGLE(WM8971_ADCDAC, 5, 4, wm8971_adcpol), /* 12 */
- SOC_ENUM_SINGLE(WM8971_ADCIN, 6, 4, wm8971_mono_mux),
-};
-
-static const struct snd_kcontrol_new wm8971_snd_controls[] = {
- SOC_DOUBLE_R("Capture Volume", WM8971_LINVOL, WM8971_RINVOL, 0, 63, 0),
- SOC_DOUBLE_R("Capture ZC Switch", WM8971_LINVOL, WM8971_RINVOL,
- 6, 1, 0),
- SOC_DOUBLE_R("Capture Switch", WM8971_LINVOL, WM8971_RINVOL, 7, 1, 1),
-
- SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8971_LOUT1V,
- WM8971_ROUT1V, 7, 1, 0),
- SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8971_LOUT2V,
- WM8971_ROUT2V, 7, 1, 0),
- SOC_SINGLE("Mono Playback ZC Switch", WM8971_MOUTV, 7, 1, 0),
-
- SOC_DOUBLE_R("PCM Volume", WM8971_LDAC, WM8971_RDAC, 0, 255, 0),
-
- SOC_DOUBLE_R("Bypass Left Playback Volume", WM8971_LOUTM1,
- WM8971_LOUTM2, 4, 7, 1),
- SOC_DOUBLE_R("Bypass Right Playback Volume", WM8971_ROUTM1,
- WM8971_ROUTM2, 4, 7, 1),
- SOC_DOUBLE_R("Bypass Mono Playback Volume", WM8971_MOUTM1,
- WM8971_MOUTM2, 4, 7, 1),
-
- SOC_DOUBLE_R("Headphone Playback Volume", WM8971_LOUT1V,
- WM8971_ROUT1V, 0, 127, 0),
- SOC_DOUBLE_R("Speaker Playback Volume", WM8971_LOUT2V,
- WM8971_ROUT2V, 0, 127, 0),
-
- SOC_ENUM("Bass Boost", wm8971_enum[0]),
- SOC_ENUM("Bass Filter", wm8971_enum[1]),
- SOC_SINGLE("Bass Volume", WM8971_BASS, 0, 7, 1),
-
- SOC_SINGLE("Treble Volume", WM8971_TREBLE, 0, 7, 0),
- SOC_ENUM("Treble Cut-off", wm8971_enum[2]),
-
- SOC_SINGLE("Capture Filter Switch", WM8971_ADCDAC, 0, 1, 1),
-
- SOC_SINGLE("ALC Target Volume", WM8971_ALC1, 0, 7, 0),
- SOC_SINGLE("ALC Max Volume", WM8971_ALC1, 4, 7, 0),
-
- SOC_SINGLE("ALC Capture Target Volume", WM8971_ALC1, 0, 7, 0),
- SOC_SINGLE("ALC Capture Max Volume", WM8971_ALC1, 4, 7, 0),
- SOC_ENUM("ALC Capture Function", wm8971_enum[3]),
- SOC_SINGLE("ALC Capture ZC Switch", WM8971_ALC2, 7, 1, 0),
- SOC_SINGLE("ALC Capture Hold Time", WM8971_ALC2, 0, 15, 0),
- SOC_SINGLE("ALC Capture Decay Time", WM8971_ALC3, 4, 15, 0),
- SOC_SINGLE("ALC Capture Attack Time", WM8971_ALC3, 0, 15, 0),
- SOC_SINGLE("ALC Capture NG Threshold", WM8971_NGATE, 3, 31, 0),
- SOC_ENUM("ALC Capture NG Type", wm8971_enum[4]),
- SOC_SINGLE("ALC Capture NG Switch", WM8971_NGATE, 0, 1, 0),
-
- SOC_SINGLE("Capture 6dB Attenuate", WM8971_ADCDAC, 8, 1, 0),
- SOC_SINGLE("Playback 6dB Attenuate", WM8971_ADCDAC, 7, 1, 0),
-
- SOC_ENUM("Playback De-emphasis", wm8971_enum[5]),
- SOC_ENUM("Playback Function", wm8971_enum[6]),
- SOC_ENUM("Playback Phase", wm8971_enum[7]),
-
- SOC_DOUBLE_R("Mic Boost", WM8971_LADCIN, WM8971_RADCIN, 4, 3, 0),
-};
-
-/*
- * DAPM Controls
- */
-
-/* Left Mixer */
-static const struct snd_kcontrol_new wm8971_left_mixer_controls[] = {
-SOC_DAPM_SINGLE("Playback Switch", WM8971_LOUTM1, 8, 1, 0),
-SOC_DAPM_SINGLE("Left Bypass Switch", WM8971_LOUTM1, 7, 1, 0),
-SOC_DAPM_SINGLE("Right Playback Switch", WM8971_LOUTM2, 8, 1, 0),
-SOC_DAPM_SINGLE("Right Bypass Switch", WM8971_LOUTM2, 7, 1, 0),
-};
-
-/* Right Mixer */
-static const struct snd_kcontrol_new wm8971_right_mixer_controls[] = {
-SOC_DAPM_SINGLE("Left Playback Switch", WM8971_ROUTM1, 8, 1, 0),
-SOC_DAPM_SINGLE("Left Bypass Switch", WM8971_ROUTM1, 7, 1, 0),
-SOC_DAPM_SINGLE("Playback Switch", WM8971_ROUTM2, 8, 1, 0),
-SOC_DAPM_SINGLE("Right Bypass Switch", WM8971_ROUTM2, 7, 1, 0),
-};
-
-/* Mono Mixer */
-static const struct snd_kcontrol_new wm8971_mono_mixer_controls[] = {
-SOC_DAPM_SINGLE("Left Playback Switch", WM8971_MOUTM1, 8, 1, 0),
-SOC_DAPM_SINGLE("Left Bypass Switch", WM8971_MOUTM1, 7, 1, 0),
-SOC_DAPM_SINGLE("Right Playback Switch", WM8971_MOUTM2, 8, 1, 0),
-SOC_DAPM_SINGLE("Right Bypass Switch", WM8971_MOUTM2, 7, 1, 0),
-};
-
-/* Left Line Mux */
-static const struct snd_kcontrol_new wm8971_left_line_controls =
-SOC_DAPM_ENUM("Route", wm8971_enum[8]);
-
-/* Right Line Mux */
-static const struct snd_kcontrol_new wm8971_right_line_controls =
-SOC_DAPM_ENUM("Route", wm8971_enum[9]);
-
-/* Left PGA Mux */
-static const struct snd_kcontrol_new wm8971_left_pga_controls =
-SOC_DAPM_ENUM("Route", wm8971_enum[10]);
-
-/* Right PGA Mux */
-static const struct snd_kcontrol_new wm8971_right_pga_controls =
-SOC_DAPM_ENUM("Route", wm8971_enum[11]);
-
-/* Mono ADC Mux */
-static const struct snd_kcontrol_new wm8971_monomux_controls =
-SOC_DAPM_ENUM("Route", wm8971_enum[13]);
-
-static const struct snd_soc_dapm_widget wm8971_dapm_widgets[] = {
- SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
- &wm8971_left_mixer_controls[0],
- ARRAY_SIZE(wm8971_left_mixer_controls)),
- SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
- &wm8971_right_mixer_controls[0],
- ARRAY_SIZE(wm8971_right_mixer_controls)),
- SND_SOC_DAPM_MIXER("Mono Mixer", WM8971_PWR2, 2, 0,
- &wm8971_mono_mixer_controls[0],
- ARRAY_SIZE(wm8971_mono_mixer_controls)),
-
- SND_SOC_DAPM_PGA("Right Out 2", WM8971_PWR2, 3, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Left Out 2", WM8971_PWR2, 4, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Right Out 1", WM8971_PWR2, 5, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Left Out 1", WM8971_PWR2, 6, 0, NULL, 0),
- SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8971_PWR2, 7, 0),
- SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8971_PWR2, 8, 0),
- SND_SOC_DAPM_PGA("Mono Out 1", WM8971_PWR2, 2, 0, NULL, 0),
-
- SND_SOC_DAPM_SUPPLY("Mic Bias", WM8971_PWR1, 1, 0, NULL, 0),
- SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8971_PWR1, 2, 0),
- SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8971_PWR1, 3, 0),
-
- SND_SOC_DAPM_MUX("Left PGA Mux", WM8971_PWR1, 5, 0,
- &wm8971_left_pga_controls),
- SND_SOC_DAPM_MUX("Right PGA Mux", WM8971_PWR1, 4, 0,
- &wm8971_right_pga_controls),
- SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0,
- &wm8971_left_line_controls),
- SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0,
- &wm8971_right_line_controls),
-
- SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0,
- &wm8971_monomux_controls),
- SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0,
- &wm8971_monomux_controls),
-
- SND_SOC_DAPM_OUTPUT("LOUT1"),
- SND_SOC_DAPM_OUTPUT("ROUT1"),
- SND_SOC_DAPM_OUTPUT("LOUT2"),
- SND_SOC_DAPM_OUTPUT("ROUT2"),
- SND_SOC_DAPM_OUTPUT("MONO"),
-
- SND_SOC_DAPM_INPUT("LINPUT1"),
- SND_SOC_DAPM_INPUT("RINPUT1"),
- SND_SOC_DAPM_INPUT("MIC"),
-};
-
-static const struct snd_soc_dapm_route wm8971_dapm_routes[] = {
- /* left mixer */
- {"Left Mixer", "Playback Switch", "Left DAC"},
- {"Left Mixer", "Left Bypass Switch", "Left Line Mux"},
- {"Left Mixer", "Right Playback Switch", "Right DAC"},
- {"Left Mixer", "Right Bypass Switch", "Right Line Mux"},
-
- /* right mixer */
- {"Right Mixer", "Left Playback Switch", "Left DAC"},
- {"Right Mixer", "Left Bypass Switch", "Left Line Mux"},
- {"Right Mixer", "Playback Switch", "Right DAC"},
- {"Right Mixer", "Right Bypass Switch", "Right Line Mux"},
-
- /* left out 1 */
- {"Left Out 1", NULL, "Left Mixer"},
- {"LOUT1", NULL, "Left Out 1"},
-
- /* left out 2 */
- {"Left Out 2", NULL, "Left Mixer"},
- {"LOUT2", NULL, "Left Out 2"},
-
- /* right out 1 */
- {"Right Out 1", NULL, "Right Mixer"},
- {"ROUT1", NULL, "Right Out 1"},
-
- /* right out 2 */
- {"Right Out 2", NULL, "Right Mixer"},
- {"ROUT2", NULL, "Right Out 2"},
-
- /* mono mixer */
- {"Mono Mixer", "Left Playback Switch", "Left DAC"},
- {"Mono Mixer", "Left Bypass Switch", "Left Line Mux"},
- {"Mono Mixer", "Right Playback Switch", "Right DAC"},
- {"Mono Mixer", "Right Bypass Switch", "Right Line Mux"},
-
- /* mono out */
- {"Mono Out", NULL, "Mono Mixer"},
- {"MONO1", NULL, "Mono Out"},
-
- /* Left Line Mux */
- {"Left Line Mux", "Line", "LINPUT1"},
- {"Left Line Mux", "PGA", "Left PGA Mux"},
- {"Left Line Mux", "Differential", "Differential Mux"},
-
- /* Right Line Mux */
- {"Right Line Mux", "Line", "RINPUT1"},
- {"Right Line Mux", "Mic", "MIC"},
- {"Right Line Mux", "PGA", "Right PGA Mux"},
- {"Right Line Mux", "Differential", "Differential Mux"},
-
- /* Left PGA Mux */
- {"Left PGA Mux", "Line", "LINPUT1"},
- {"Left PGA Mux", "Differential", "Differential Mux"},
-
- /* Right PGA Mux */
- {"Right PGA Mux", "Line", "RINPUT1"},
- {"Right PGA Mux", "Differential", "Differential Mux"},
-
- /* Differential Mux */
- {"Differential Mux", "Line", "LINPUT1"},
- {"Differential Mux", "Line", "RINPUT1"},
-
- /* Left ADC Mux */
- {"Left ADC Mux", "Stereo", "Left PGA Mux"},
- {"Left ADC Mux", "Mono (Left)", "Left PGA Mux"},
- {"Left ADC Mux", "Digital Mono", "Left PGA Mux"},
-
- /* Right ADC Mux */
- {"Right ADC Mux", "Stereo", "Right PGA Mux"},
- {"Right ADC Mux", "Mono (Right)", "Right PGA Mux"},
- {"Right ADC Mux", "Digital Mono", "Right PGA Mux"},
-
- /* ADC */
- {"Left ADC", NULL, "Left ADC Mux"},
- {"Right ADC", NULL, "Right ADC Mux"},
-};
-
-struct _coeff_div {
- u32 mclk;
- u32 rate;
- u16 fs;
- u8 sr:5;
- u8 usb:1;
-};
-
-/* codec hifi mclk clock divider coefficients */
-static const struct _coeff_div coeff_div[] = {
- /* 8k */
- {12288000, 8000, 1536, 0x6, 0x0},
- {11289600, 8000, 1408, 0x16, 0x0},
- {18432000, 8000, 2304, 0x7, 0x0},
- {16934400, 8000, 2112, 0x17, 0x0},
- {12000000, 8000, 1500, 0x6, 0x1},
-
- /* 11.025k */
- {11289600, 11025, 1024, 0x18, 0x0},
- {16934400, 11025, 1536, 0x19, 0x0},
- {12000000, 11025, 1088, 0x19, 0x1},
-
- /* 16k */
- {12288000, 16000, 768, 0xa, 0x0},
- {18432000, 16000, 1152, 0xb, 0x0},
- {12000000, 16000, 750, 0xa, 0x1},
-
- /* 22.05k */
- {11289600, 22050, 512, 0x1a, 0x0},
- {16934400, 22050, 768, 0x1b, 0x0},
- {12000000, 22050, 544, 0x1b, 0x1},
-
- /* 32k */
- {12288000, 32000, 384, 0xc, 0x0},
- {18432000, 32000, 576, 0xd, 0x0},
- {12000000, 32000, 375, 0xa, 0x1},
-
- /* 44.1k */
- {11289600, 44100, 256, 0x10, 0x0},
- {16934400, 44100, 384, 0x11, 0x0},
- {12000000, 44100, 272, 0x11, 0x1},
-
- /* 48k */
- {12288000, 48000, 256, 0x0, 0x0},
- {18432000, 48000, 384, 0x1, 0x0},
- {12000000, 48000, 250, 0x0, 0x1},
-
- /* 88.2k */
- {11289600, 88200, 128, 0x1e, 0x0},
- {16934400, 88200, 192, 0x1f, 0x0},
- {12000000, 88200, 136, 0x1f, 0x1},
-
- /* 96k */
- {12288000, 96000, 128, 0xe, 0x0},
- {18432000, 96000, 192, 0xf, 0x0},
- {12000000, 96000, 125, 0xe, 0x1},
-};
-
-static int get_coeff(int mclk, int rate)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
- if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
- return i;
- }
- return -EINVAL;
-}
-
-static int wm8971_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
-
- switch (freq) {
- case 11289600:
- case 12000000:
- case 12288000:
- case 16934400:
- case 18432000:
- wm8971->sysclk = freq;
- return 0;
- }
- return -EINVAL;
-}
-
-static int wm8971_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 iface = 0;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- iface = 0x0040;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= 0x0002;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= 0x0001;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= 0x0003;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- iface |= 0x0013;
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= 0x0090;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= 0x0080;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- iface |= 0x0010;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM8971_IFACE, iface);
- return 0;
-}
-
-static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
- u16 iface = snd_soc_read(codec, WM8971_IFACE) & 0x1f3;
- u16 srate = snd_soc_read(codec, WM8971_SRATE) & 0x1c0;
- int coeff = get_coeff(wm8971->sysclk, params_rate(params));
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= 0x0004;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface |= 0x0008;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- iface |= 0x000c;
- break;
- }
-
- /* set iface & srate */
- snd_soc_write(codec, WM8971_IFACE, iface);
- if (coeff >= 0)
- snd_soc_write(codec, WM8971_SRATE, srate |
- (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
-
- return 0;
-}
-
-static int wm8971_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 mute_reg = snd_soc_read(codec, WM8971_ADCDAC) & 0xfff7;
-
- if (mute)
- snd_soc_write(codec, WM8971_ADCDAC, mute_reg | 0x8);
- else
- snd_soc_write(codec, WM8971_ADCDAC, mute_reg);
- return 0;
-}
-
-static int wm8971_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- u16 pwr_reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- /* set vmid to 50k and unmute dac */
- snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x00c1);
- break;
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
- snd_soc_cache_sync(codec);
-
- /* mute dac and set vmid to 500k, enable VREF */
- snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
- break;
- case SND_SOC_BIAS_OFF:
- snd_soc_write(codec, WM8971_PWR1, 0x0001);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define WM8971_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
-
-#define WM8971_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops wm8971_dai_ops = {
- .hw_params = wm8971_pcm_hw_params,
- .digital_mute = wm8971_mute,
- .set_fmt = wm8971_set_dai_fmt,
- .set_sysclk = wm8971_set_dai_sysclk,
-};
-
-static struct snd_soc_dai_driver wm8971_dai = {
- .name = "wm8971-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8971_RATES,
- .formats = WM8971_FORMATS,},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8971_RATES,
- .formats = WM8971_FORMATS,},
- .ops = &wm8971_dai_ops,
-};
-
-static void wm8971_work(struct work_struct *work)
-{
- struct snd_soc_dapm_context *dapm =
- container_of(work, struct snd_soc_dapm_context,
- delayed_work.work);
- struct snd_soc_codec *codec = dapm->codec;
- wm8971_set_bias_level(codec, codec->dapm.bias_level);
-}
-
-static int wm8971_suspend(struct snd_soc_codec *codec)
-{
- wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm8971_resume(struct snd_soc_codec *codec)
-{
- u16 reg;
-
- wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* charge wm8971 caps */
- if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
- reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
- snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
- codec->dapm.bias_level = SND_SOC_BIAS_ON;
- queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work,
- msecs_to_jiffies(1000));
- }
-
- return 0;
-}
-
-static int wm8971_probe(struct snd_soc_codec *codec)
-{
- struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
- int ret = 0;
- u16 reg;
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8971->control_type);
- if (ret < 0) {
- printk(KERN_ERR "wm8971: failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8971_work);
- wm8971_workq = create_workqueue("wm8971");
- if (wm8971_workq == NULL)
- return -ENOMEM;
-
- wm8971_reset(codec);
-
- /* charge output caps - set vmid to 5k for quick power up */
- reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
- snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
- codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
- queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work,
- msecs_to_jiffies(1000));
-
- /* set the update bits */
- snd_soc_update_bits(codec, WM8971_LDAC, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8971_RDAC, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8971_LOUT1V, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8971_ROUT1V, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8971_LOUT2V, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8971_ROUT2V, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8971_LINVOL, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8971_RINVOL, 0x0100, 0x0100);
-
- return ret;
-}
-
-
-/* power down chip */
-static int wm8971_remove(struct snd_soc_codec *codec)
-{
- wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- if (wm8971_workq)
- destroy_workqueue(wm8971_workq);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8971 = {
- .probe = wm8971_probe,
- .remove = wm8971_remove,
- .suspend = wm8971_suspend,
- .resume = wm8971_resume,
- .set_bias_level = wm8971_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8971_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8971_reg,
-
- .controls = wm8971_snd_controls,
- .num_controls = ARRAY_SIZE(wm8971_snd_controls),
- .dapm_widgets = wm8971_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8971_dapm_widgets),
- .dapm_routes = wm8971_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm8971_dapm_routes),
-};
-
-static __devinit int wm8971_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8971_priv *wm8971;
- int ret;
-
- wm8971 = devm_kzalloc(&i2c->dev, sizeof(struct wm8971_priv),
- GFP_KERNEL);
- if (wm8971 == NULL)
- return -ENOMEM;
-
- wm8971->control_type = SND_SOC_I2C;
- i2c_set_clientdata(i2c, wm8971);
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8971, &wm8971_dai, 1);
-
- return ret;
-}
-
-static __devexit int wm8971_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- return 0;
-}
-
-static const struct i2c_device_id wm8971_i2c_id[] = {
- { "wm8971", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8971_i2c_id);
-
-static struct i2c_driver wm8971_i2c_driver = {
- .driver = {
- .name = "wm8971",
- .owner = THIS_MODULE,
- },
- .probe = wm8971_i2c_probe,
- .remove = __devexit_p(wm8971_i2c_remove),
- .id_table = wm8971_i2c_id,
-};
-
-static int __init wm8971_modinit(void)
-{
- int ret = 0;
- ret = i2c_add_driver(&wm8971_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8971 I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(wm8971_modinit);
-
-static void __exit wm8971_exit(void)
-{
- i2c_del_driver(&wm8971_i2c_driver);
-}
-module_exit(wm8971_exit);
-
-MODULE_DESCRIPTION("ASoC WM8971 driver");
-MODULE_AUTHOR("Lab126");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8971.h b/ANDROID_3.4.5/sound/soc/codecs/wm8971.h
deleted file mode 100644
index f31c38fd..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8971.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * wm8971.h -- audio driver for WM8971
- *
- * Copyright 2005 Lab126, Inc.
- *
- * Author: Kenneth Kiraly <kiraly@lab126.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#ifndef _WM8971_H
-#define _WM8971_H
-
-#define WM8971_LINVOL 0x00
-#define WM8971_RINVOL 0x01
-#define WM8971_LOUT1V 0x02
-#define WM8971_ROUT1V 0x03
-#define WM8971_ADCDAC 0x05
-#define WM8971_IFACE 0x07
-#define WM8971_SRATE 0x08
-#define WM8971_LDAC 0x0a
-#define WM8971_RDAC 0x0b
-#define WM8971_BASS 0x0c
-#define WM8971_TREBLE 0x0d
-#define WM8971_RESET 0x0f
-#define WM8971_ALC1 0x11
-#define WM8971_ALC2 0x12
-#define WM8971_ALC3 0x13
-#define WM8971_NGATE 0x14
-#define WM8971_LADC 0x15
-#define WM8971_RADC 0x16
-#define WM8971_ADCTL1 0x17
-#define WM8971_ADCTL2 0x18
-#define WM8971_PWR1 0x19
-#define WM8971_PWR2 0x1a
-#define WM8971_ADCTL3 0x1b
-#define WM8971_ADCIN 0x1f
-#define WM8971_LADCIN 0x20
-#define WM8971_RADCIN 0x21
-#define WM8971_LOUTM1 0x22
-#define WM8971_LOUTM2 0x23
-#define WM8971_ROUTM1 0x24
-#define WM8971_ROUTM2 0x25
-#define WM8971_MOUTM1 0x26
-#define WM8971_MOUTM2 0x27
-#define WM8971_LOUT2V 0x28
-#define WM8971_ROUT2V 0x29
-#define WM8971_MOUTV 0x2A
-
-#define WM8971_SYSCLK 0
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8974.c b/ANDROID_3.4.5/sound/soc/codecs/wm8974.c
deleted file mode 100644
index d93c03f8..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8974.c
+++ /dev/null
@@ -1,682 +0,0 @@
-/*
- * wm8974.c -- WM8974 ALSA Soc Audio driver
- *
- * Copyright 2006-2009 Wolfson Microelectronics PLC.
- *
- * Author: Liam Girdwood <Liam.Girdwood@wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "wm8974.h"
-
-static const u16 wm8974_reg[WM8974_CACHEREGNUM] = {
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0050, 0x0000, 0x0140, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x00ff,
- 0x0000, 0x0000, 0x0100, 0x00ff,
- 0x0000, 0x0000, 0x012c, 0x002c,
- 0x002c, 0x002c, 0x002c, 0x0000,
- 0x0032, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0038, 0x000b, 0x0032, 0x0000,
- 0x0008, 0x000c, 0x0093, 0x00e9,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0003, 0x0010, 0x0000, 0x0000,
- 0x0000, 0x0002, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0039, 0x0000,
- 0x0000,
-};
-
-#define WM8974_POWER1_BIASEN 0x08
-#define WM8974_POWER1_BUFIOEN 0x04
-
-#define wm8974_reset(c) snd_soc_write(c, WM8974_RESET, 0)
-
-static const char *wm8974_companding[] = {"Off", "NC", "u-law", "A-law" };
-static const char *wm8974_deemp[] = {"None", "32kHz", "44.1kHz", "48kHz" };
-static const char *wm8974_eqmode[] = {"Capture", "Playback" };
-static const char *wm8974_bw[] = {"Narrow", "Wide" };
-static const char *wm8974_eq1[] = {"80Hz", "105Hz", "135Hz", "175Hz" };
-static const char *wm8974_eq2[] = {"230Hz", "300Hz", "385Hz", "500Hz" };
-static const char *wm8974_eq3[] = {"650Hz", "850Hz", "1.1kHz", "1.4kHz" };
-static const char *wm8974_eq4[] = {"1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz" };
-static const char *wm8974_eq5[] = {"5.3kHz", "6.9kHz", "9kHz", "11.7kHz" };
-static const char *wm8974_alc[] = {"ALC", "Limiter" };
-
-static const struct soc_enum wm8974_enum[] = {
- SOC_ENUM_SINGLE(WM8974_COMP, 1, 4, wm8974_companding), /* adc */
- SOC_ENUM_SINGLE(WM8974_COMP, 3, 4, wm8974_companding), /* dac */
- SOC_ENUM_SINGLE(WM8974_DAC, 4, 4, wm8974_deemp),
- SOC_ENUM_SINGLE(WM8974_EQ1, 8, 2, wm8974_eqmode),
-
- SOC_ENUM_SINGLE(WM8974_EQ1, 5, 4, wm8974_eq1),
- SOC_ENUM_SINGLE(WM8974_EQ2, 8, 2, wm8974_bw),
- SOC_ENUM_SINGLE(WM8974_EQ2, 5, 4, wm8974_eq2),
- SOC_ENUM_SINGLE(WM8974_EQ3, 8, 2, wm8974_bw),
-
- SOC_ENUM_SINGLE(WM8974_EQ3, 5, 4, wm8974_eq3),
- SOC_ENUM_SINGLE(WM8974_EQ4, 8, 2, wm8974_bw),
- SOC_ENUM_SINGLE(WM8974_EQ4, 5, 4, wm8974_eq4),
- SOC_ENUM_SINGLE(WM8974_EQ5, 8, 2, wm8974_bw),
-
- SOC_ENUM_SINGLE(WM8974_EQ5, 5, 4, wm8974_eq5),
- SOC_ENUM_SINGLE(WM8974_ALC3, 8, 2, wm8974_alc),
-};
-
-static const char *wm8974_auxmode_text[] = { "Buffer", "Mixer" };
-
-static const struct soc_enum wm8974_auxmode =
- SOC_ENUM_SINGLE(WM8974_INPUT, 3, 2, wm8974_auxmode_text);
-
-static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);
-static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
-static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0);
-static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0);
-
-static const struct snd_kcontrol_new wm8974_snd_controls[] = {
-
-SOC_SINGLE("Digital Loopback Switch", WM8974_COMP, 0, 1, 0),
-
-SOC_ENUM("DAC Companding", wm8974_enum[1]),
-SOC_ENUM("ADC Companding", wm8974_enum[0]),
-
-SOC_ENUM("Playback De-emphasis", wm8974_enum[2]),
-SOC_SINGLE("DAC Inversion Switch", WM8974_DAC, 0, 1, 0),
-
-SOC_SINGLE_TLV("PCM Volume", WM8974_DACVOL, 0, 255, 0, digital_tlv),
-
-SOC_SINGLE("High Pass Filter Switch", WM8974_ADC, 8, 1, 0),
-SOC_SINGLE("High Pass Cut Off", WM8974_ADC, 4, 7, 0),
-SOC_SINGLE("ADC Inversion Switch", WM8974_ADC, 0, 1, 0),
-
-SOC_SINGLE_TLV("Capture Volume", WM8974_ADCVOL, 0, 255, 0, digital_tlv),
-
-SOC_ENUM("Equaliser Function", wm8974_enum[3]),
-SOC_ENUM("EQ1 Cut Off", wm8974_enum[4]),
-SOC_SINGLE_TLV("EQ1 Volume", WM8974_EQ1, 0, 24, 1, eq_tlv),
-
-SOC_ENUM("Equaliser EQ2 Bandwith", wm8974_enum[5]),
-SOC_ENUM("EQ2 Cut Off", wm8974_enum[6]),
-SOC_SINGLE_TLV("EQ2 Volume", WM8974_EQ2, 0, 24, 1, eq_tlv),
-
-SOC_ENUM("Equaliser EQ3 Bandwith", wm8974_enum[7]),
-SOC_ENUM("EQ3 Cut Off", wm8974_enum[8]),
-SOC_SINGLE_TLV("EQ3 Volume", WM8974_EQ3, 0, 24, 1, eq_tlv),
-
-SOC_ENUM("Equaliser EQ4 Bandwith", wm8974_enum[9]),
-SOC_ENUM("EQ4 Cut Off", wm8974_enum[10]),
-SOC_SINGLE_TLV("EQ4 Volume", WM8974_EQ4, 0, 24, 1, eq_tlv),
-
-SOC_ENUM("Equaliser EQ5 Bandwith", wm8974_enum[11]),
-SOC_ENUM("EQ5 Cut Off", wm8974_enum[12]),
-SOC_SINGLE_TLV("EQ5 Volume", WM8974_EQ5, 0, 24, 1, eq_tlv),
-
-SOC_SINGLE("DAC Playback Limiter Switch", WM8974_DACLIM1, 8, 1, 0),
-SOC_SINGLE("DAC Playback Limiter Decay", WM8974_DACLIM1, 4, 15, 0),
-SOC_SINGLE("DAC Playback Limiter Attack", WM8974_DACLIM1, 0, 15, 0),
-
-SOC_SINGLE("DAC Playback Limiter Threshold", WM8974_DACLIM2, 4, 7, 0),
-SOC_SINGLE("DAC Playback Limiter Boost", WM8974_DACLIM2, 0, 15, 0),
-
-SOC_SINGLE("ALC Enable Switch", WM8974_ALC1, 8, 1, 0),
-SOC_SINGLE("ALC Capture Max Gain", WM8974_ALC1, 3, 7, 0),
-SOC_SINGLE("ALC Capture Min Gain", WM8974_ALC1, 0, 7, 0),
-
-SOC_SINGLE("ALC Capture ZC Switch", WM8974_ALC2, 8, 1, 0),
-SOC_SINGLE("ALC Capture Hold", WM8974_ALC2, 4, 7, 0),
-SOC_SINGLE("ALC Capture Target", WM8974_ALC2, 0, 15, 0),
-
-SOC_ENUM("ALC Capture Mode", wm8974_enum[13]),
-SOC_SINGLE("ALC Capture Decay", WM8974_ALC3, 4, 15, 0),
-SOC_SINGLE("ALC Capture Attack", WM8974_ALC3, 0, 15, 0),
-
-SOC_SINGLE("ALC Capture Noise Gate Switch", WM8974_NGATE, 3, 1, 0),
-SOC_SINGLE("ALC Capture Noise Gate Threshold", WM8974_NGATE, 0, 7, 0),
-
-SOC_SINGLE("Capture PGA ZC Switch", WM8974_INPPGA, 7, 1, 0),
-SOC_SINGLE_TLV("Capture PGA Volume", WM8974_INPPGA, 0, 63, 0, inpga_tlv),
-
-SOC_SINGLE("Speaker Playback ZC Switch", WM8974_SPKVOL, 7, 1, 0),
-SOC_SINGLE("Speaker Playback Switch", WM8974_SPKVOL, 6, 1, 1),
-SOC_SINGLE_TLV("Speaker Playback Volume", WM8974_SPKVOL, 0, 63, 0, spk_tlv),
-
-SOC_ENUM("Aux Mode", wm8974_auxmode),
-
-SOC_SINGLE("Capture Boost(+20dB)", WM8974_ADCBOOST, 8, 1, 0),
-SOC_SINGLE("Mono Playback Switch", WM8974_MONOMIX, 6, 1, 1),
-
-/* DAC / ADC oversampling */
-SOC_SINGLE("DAC 128x Oversampling Switch", WM8974_DAC, 8, 1, 0),
-SOC_SINGLE("ADC 128x Oversampling Switch", WM8974_ADC, 8, 1, 0),
-};
-
-/* Speaker Output Mixer */
-static const struct snd_kcontrol_new wm8974_speaker_mixer_controls[] = {
-SOC_DAPM_SINGLE("Line Bypass Switch", WM8974_SPKMIX, 1, 1, 0),
-SOC_DAPM_SINGLE("Aux Playback Switch", WM8974_SPKMIX, 5, 1, 0),
-SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_SPKMIX, 0, 1, 0),
-};
-
-/* Mono Output Mixer */
-static const struct snd_kcontrol_new wm8974_mono_mixer_controls[] = {
-SOC_DAPM_SINGLE("Line Bypass Switch", WM8974_MONOMIX, 1, 1, 0),
-SOC_DAPM_SINGLE("Aux Playback Switch", WM8974_MONOMIX, 2, 1, 0),
-SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_MONOMIX, 0, 1, 0),
-};
-
-/* Boost mixer */
-static const struct snd_kcontrol_new wm8974_boost_mixer[] = {
-SOC_DAPM_SINGLE("Aux Switch", WM8974_INPPGA, 6, 1, 0),
-};
-
-/* Input PGA */
-static const struct snd_kcontrol_new wm8974_inpga[] = {
-SOC_DAPM_SINGLE("Aux Switch", WM8974_INPUT, 2, 1, 0),
-SOC_DAPM_SINGLE("MicN Switch", WM8974_INPUT, 1, 1, 0),
-SOC_DAPM_SINGLE("MicP Switch", WM8974_INPUT, 0, 1, 0),
-};
-
-/* AUX Input boost vol */
-static const struct snd_kcontrol_new wm8974_aux_boost_controls =
-SOC_DAPM_SINGLE("Aux Volume", WM8974_ADCBOOST, 0, 7, 0);
-
-/* Mic Input boost vol */
-static const struct snd_kcontrol_new wm8974_mic_boost_controls =
-SOC_DAPM_SINGLE("Mic Volume", WM8974_ADCBOOST, 4, 7, 0);
-
-static const struct snd_soc_dapm_widget wm8974_dapm_widgets[] = {
-SND_SOC_DAPM_MIXER("Speaker Mixer", WM8974_POWER3, 2, 0,
- &wm8974_speaker_mixer_controls[0],
- ARRAY_SIZE(wm8974_speaker_mixer_controls)),
-SND_SOC_DAPM_MIXER("Mono Mixer", WM8974_POWER3, 3, 0,
- &wm8974_mono_mixer_controls[0],
- ARRAY_SIZE(wm8974_mono_mixer_controls)),
-SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8974_POWER3, 0, 0),
-SND_SOC_DAPM_ADC("ADC", "HiFi Capture", WM8974_POWER2, 0, 0),
-SND_SOC_DAPM_PGA("Aux Input", WM8974_POWER1, 6, 0, NULL, 0),
-SND_SOC_DAPM_PGA("SpkN Out", WM8974_POWER3, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA("SpkP Out", WM8974_POWER3, 6, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Mono Out", WM8974_POWER3, 7, 0, NULL, 0),
-
-SND_SOC_DAPM_MIXER("Input PGA", WM8974_POWER2, 2, 0, wm8974_inpga,
- ARRAY_SIZE(wm8974_inpga)),
-SND_SOC_DAPM_MIXER("Boost Mixer", WM8974_POWER2, 4, 0,
- wm8974_boost_mixer, ARRAY_SIZE(wm8974_boost_mixer)),
-
-SND_SOC_DAPM_SUPPLY("Mic Bias", WM8974_POWER1, 4, 0, NULL, 0),
-
-SND_SOC_DAPM_INPUT("MICN"),
-SND_SOC_DAPM_INPUT("MICP"),
-SND_SOC_DAPM_INPUT("AUX"),
-SND_SOC_DAPM_OUTPUT("MONOOUT"),
-SND_SOC_DAPM_OUTPUT("SPKOUTP"),
-SND_SOC_DAPM_OUTPUT("SPKOUTN"),
-};
-
-static const struct snd_soc_dapm_route wm8974_dapm_routes[] = {
- /* Mono output mixer */
- {"Mono Mixer", "PCM Playback Switch", "DAC"},
- {"Mono Mixer", "Aux Playback Switch", "Aux Input"},
- {"Mono Mixer", "Line Bypass Switch", "Boost Mixer"},
-
- /* Speaker output mixer */
- {"Speaker Mixer", "PCM Playback Switch", "DAC"},
- {"Speaker Mixer", "Aux Playback Switch", "Aux Input"},
- {"Speaker Mixer", "Line Bypass Switch", "Boost Mixer"},
-
- /* Outputs */
- {"Mono Out", NULL, "Mono Mixer"},
- {"MONOOUT", NULL, "Mono Out"},
- {"SpkN Out", NULL, "Speaker Mixer"},
- {"SpkP Out", NULL, "Speaker Mixer"},
- {"SPKOUTN", NULL, "SpkN Out"},
- {"SPKOUTP", NULL, "SpkP Out"},
-
- /* Boost Mixer */
- {"ADC", NULL, "Boost Mixer"},
- {"Boost Mixer", "Aux Switch", "Aux Input"},
- {"Boost Mixer", NULL, "Input PGA"},
- {"Boost Mixer", NULL, "MICP"},
-
- /* Input PGA */
- {"Input PGA", "Aux Switch", "Aux Input"},
- {"Input PGA", "MicN Switch", "MICN"},
- {"Input PGA", "MicP Switch", "MICP"},
-
- /* Inputs */
- {"Aux Input", NULL, "AUX"},
-};
-
-struct pll_ {
- unsigned int pre_div:1;
- unsigned int n:4;
- unsigned int k;
-};
-
-/* The size in bits of the pll divide multiplied by 10
- * to allow rounding later */
-#define FIXED_PLL_SIZE ((1 << 24) * 10)
-
-static void pll_factors(struct pll_ *pll_div,
- unsigned int target, unsigned int source)
-{
- unsigned long long Kpart;
- unsigned int K, Ndiv, Nmod;
-
- /* There is a fixed divide by 4 in the output path */
- target *= 4;
-
- Ndiv = target / source;
- if (Ndiv < 6) {
- source /= 2;
- pll_div->pre_div = 1;
- Ndiv = target / source;
- } else
- pll_div->pre_div = 0;
-
- if ((Ndiv < 6) || (Ndiv > 12))
- printk(KERN_WARNING
- "WM8974 N value %u outwith recommended range!\n",
- Ndiv);
-
- pll_div->n = Ndiv;
- Nmod = target % source;
- Kpart = FIXED_PLL_SIZE * (long long)Nmod;
-
- do_div(Kpart, source);
-
- K = Kpart & 0xFFFFFFFF;
-
- /* Check if we need to round */
- if ((K % 10) >= 5)
- K += 5;
-
- /* Move down to proper range now rounding is done */
- K /= 10;
-
- pll_div->k = K;
-}
-
-static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
- int source, unsigned int freq_in, unsigned int freq_out)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct pll_ pll_div;
- u16 reg;
-
- if (freq_in == 0 || freq_out == 0) {
- /* Clock CODEC directly from MCLK */
- reg = snd_soc_read(codec, WM8974_CLOCK);
- snd_soc_write(codec, WM8974_CLOCK, reg & 0x0ff);
-
- /* Turn off PLL */
- reg = snd_soc_read(codec, WM8974_POWER1);
- snd_soc_write(codec, WM8974_POWER1, reg & 0x1df);
- return 0;
- }
-
- pll_factors(&pll_div, freq_out, freq_in);
-
- snd_soc_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n);
- snd_soc_write(codec, WM8974_PLLK1, pll_div.k >> 18);
- snd_soc_write(codec, WM8974_PLLK2, (pll_div.k >> 9) & 0x1ff);
- snd_soc_write(codec, WM8974_PLLK3, pll_div.k & 0x1ff);
- reg = snd_soc_read(codec, WM8974_POWER1);
- snd_soc_write(codec, WM8974_POWER1, reg | 0x020);
-
- /* Run CODEC from PLL instead of MCLK */
- reg = snd_soc_read(codec, WM8974_CLOCK);
- snd_soc_write(codec, WM8974_CLOCK, reg | 0x100);
-
- return 0;
-}
-
-/*
- * Configure WM8974 clock dividers.
- */
-static int wm8974_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
- int div_id, int div)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 reg;
-
- switch (div_id) {
- case WM8974_OPCLKDIV:
- reg = snd_soc_read(codec, WM8974_GPIO) & 0x1cf;
- snd_soc_write(codec, WM8974_GPIO, reg | div);
- break;
- case WM8974_MCLKDIV:
- reg = snd_soc_read(codec, WM8974_CLOCK) & 0x11f;
- snd_soc_write(codec, WM8974_CLOCK, reg | div);
- break;
- case WM8974_BCLKDIV:
- reg = snd_soc_read(codec, WM8974_CLOCK) & 0x1e3;
- snd_soc_write(codec, WM8974_CLOCK, reg | div);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int wm8974_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 iface = 0;
- u16 clk = snd_soc_read(codec, WM8974_CLOCK) & 0x1fe;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- clk |= 0x0001;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= 0x0010;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= 0x0008;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= 0x00018;
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= 0x0180;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= 0x0100;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- iface |= 0x0080;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM8974_IFACE, iface);
- snd_soc_write(codec, WM8974_CLOCK, clk);
- return 0;
-}
-
-static int wm8974_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 iface = snd_soc_read(codec, WM8974_IFACE) & 0x19f;
- u16 adn = snd_soc_read(codec, WM8974_ADD) & 0x1f1;
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= 0x0020;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface |= 0x0040;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- iface |= 0x0060;
- break;
- }
-
- /* filter coefficient */
- switch (params_rate(params)) {
- case 8000:
- adn |= 0x5 << 1;
- break;
- case 11025:
- adn |= 0x4 << 1;
- break;
- case 16000:
- adn |= 0x3 << 1;
- break;
- case 22050:
- adn |= 0x2 << 1;
- break;
- case 32000:
- adn |= 0x1 << 1;
- break;
- case 44100:
- case 48000:
- break;
- }
-
- snd_soc_write(codec, WM8974_IFACE, iface);
- snd_soc_write(codec, WM8974_ADD, adn);
- return 0;
-}
-
-static int wm8974_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 mute_reg = snd_soc_read(codec, WM8974_DAC) & 0xffbf;
-
- if (mute)
- snd_soc_write(codec, WM8974_DAC, mute_reg | 0x40);
- else
- snd_soc_write(codec, WM8974_DAC, mute_reg);
- return 0;
-}
-
-/* liam need to make this lower power with dapm */
-static int wm8974_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- u16 power1 = snd_soc_read(codec, WM8974_POWER1) & ~0x3;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- case SND_SOC_BIAS_PREPARE:
- power1 |= 0x1; /* VMID 50k */
- snd_soc_write(codec, WM8974_POWER1, power1);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN;
-
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- snd_soc_cache_sync(codec);
-
- /* Initial cap charge at VMID 5k */
- snd_soc_write(codec, WM8974_POWER1, power1 | 0x3);
- mdelay(100);
- }
-
- power1 |= 0x2; /* VMID 500k */
- snd_soc_write(codec, WM8974_POWER1, power1);
- break;
-
- case SND_SOC_BIAS_OFF:
- snd_soc_write(codec, WM8974_POWER1, 0);
- snd_soc_write(codec, WM8974_POWER2, 0);
- snd_soc_write(codec, WM8974_POWER3, 0);
- break;
- }
-
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define WM8974_RATES (SNDRV_PCM_RATE_8000_48000)
-
-#define WM8974_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops wm8974_ops = {
- .hw_params = wm8974_pcm_hw_params,
- .digital_mute = wm8974_mute,
- .set_fmt = wm8974_set_dai_fmt,
- .set_clkdiv = wm8974_set_dai_clkdiv,
- .set_pll = wm8974_set_dai_pll,
-};
-
-static struct snd_soc_dai_driver wm8974_dai = {
- .name = "wm8974-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2, /* Only 1 channel of data */
- .rates = WM8974_RATES,
- .formats = WM8974_FORMATS,},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2, /* Only 1 channel of data */
- .rates = WM8974_RATES,
- .formats = WM8974_FORMATS,},
- .ops = &wm8974_ops,
- .symmetric_rates = 1,
-};
-
-static int wm8974_suspend(struct snd_soc_codec *codec)
-{
- wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm8974_resume(struct snd_soc_codec *codec)
-{
- wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-
-static int wm8974_probe(struct snd_soc_codec *codec)
-{
- int ret = 0;
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- ret = wm8974_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- return ret;
- }
-
- wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return ret;
-}
-
-/* power down chip */
-static int wm8974_remove(struct snd_soc_codec *codec)
-{
- wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8974 = {
- .probe = wm8974_probe,
- .remove = wm8974_remove,
- .suspend = wm8974_suspend,
- .resume = wm8974_resume,
- .set_bias_level = wm8974_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8974_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8974_reg,
-
- .controls = wm8974_snd_controls,
- .num_controls = ARRAY_SIZE(wm8974_snd_controls),
- .dapm_widgets = wm8974_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8974_dapm_widgets),
- .dapm_routes = wm8974_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm8974_dapm_routes),
-};
-
-static __devinit int wm8974_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- int ret;
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8974, &wm8974_dai, 1);
-
- return ret;
-}
-
-static __devexit int wm8974_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
-
- return 0;
-}
-
-static const struct i2c_device_id wm8974_i2c_id[] = {
- { "wm8974", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8974_i2c_id);
-
-static struct i2c_driver wm8974_i2c_driver = {
- .driver = {
- .name = "wm8974",
- .owner = THIS_MODULE,
- },
- .probe = wm8974_i2c_probe,
- .remove = __devexit_p(wm8974_i2c_remove),
- .id_table = wm8974_i2c_id,
-};
-
-static int __init wm8974_modinit(void)
-{
- int ret = 0;
- ret = i2c_add_driver(&wm8974_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8974 I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(wm8974_modinit);
-
-static void __exit wm8974_exit(void)
-{
- i2c_del_driver(&wm8974_i2c_driver);
-}
-module_exit(wm8974_exit);
-
-MODULE_DESCRIPTION("ASoC WM8974 driver");
-MODULE_AUTHOR("Liam Girdwood");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8974.h b/ANDROID_3.4.5/sound/soc/codecs/wm8974.h
deleted file mode 100644
index 3c94e7bb..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8974.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * wm8974.h -- WM8974 Soc Audio driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8974_H
-#define _WM8974_H
-
-/* WM8974 register space */
-
-#define WM8974_RESET 0x0
-#define WM8974_POWER1 0x1
-#define WM8974_POWER2 0x2
-#define WM8974_POWER3 0x3
-#define WM8974_IFACE 0x4
-#define WM8974_COMP 0x5
-#define WM8974_CLOCK 0x6
-#define WM8974_ADD 0x7
-#define WM8974_GPIO 0x8
-#define WM8974_DAC 0xa
-#define WM8974_DACVOL 0xb
-#define WM8974_ADC 0xe
-#define WM8974_ADCVOL 0xf
-#define WM8974_EQ1 0x12
-#define WM8974_EQ2 0x13
-#define WM8974_EQ3 0x14
-#define WM8974_EQ4 0x15
-#define WM8974_EQ5 0x16
-#define WM8974_DACLIM1 0x18
-#define WM8974_DACLIM2 0x19
-#define WM8974_NOTCH1 0x1b
-#define WM8974_NOTCH2 0x1c
-#define WM8974_NOTCH3 0x1d
-#define WM8974_NOTCH4 0x1e
-#define WM8974_ALC1 0x20
-#define WM8974_ALC2 0x21
-#define WM8974_ALC3 0x22
-#define WM8974_NGATE 0x23
-#define WM8974_PLLN 0x24
-#define WM8974_PLLK1 0x25
-#define WM8974_PLLK2 0x26
-#define WM8974_PLLK3 0x27
-#define WM8974_ATTEN 0x28
-#define WM8974_INPUT 0x2c
-#define WM8974_INPPGA 0x2d
-#define WM8974_ADCBOOST 0x2f
-#define WM8974_OUTPUT 0x31
-#define WM8974_SPKMIX 0x32
-#define WM8974_SPKVOL 0x36
-#define WM8974_MONOMIX 0x38
-
-#define WM8974_CACHEREGNUM 57
-
-/* Clock divider Id's */
-#define WM8974_OPCLKDIV 0
-#define WM8974_MCLKDIV 1
-#define WM8974_BCLKDIV 2
-
-/* PLL Out dividers */
-#define WM8974_OPCLKDIV_1 (0 << 4)
-#define WM8974_OPCLKDIV_2 (1 << 4)
-#define WM8974_OPCLKDIV_3 (2 << 4)
-#define WM8974_OPCLKDIV_4 (3 << 4)
-
-/* BCLK clock dividers */
-#define WM8974_BCLKDIV_1 (0 << 2)
-#define WM8974_BCLKDIV_2 (1 << 2)
-#define WM8974_BCLKDIV_4 (2 << 2)
-#define WM8974_BCLKDIV_8 (3 << 2)
-#define WM8974_BCLKDIV_16 (4 << 2)
-#define WM8974_BCLKDIV_32 (5 << 2)
-
-/* MCLK clock dividers */
-#define WM8974_MCLKDIV_1 (0 << 5)
-#define WM8974_MCLKDIV_1_5 (1 << 5)
-#define WM8974_MCLKDIV_2 (2 << 5)
-#define WM8974_MCLKDIV_3 (3 << 5)
-#define WM8974_MCLKDIV_4 (4 << 5)
-#define WM8974_MCLKDIV_6 (5 << 5)
-#define WM8974_MCLKDIV_8 (6 << 5)
-#define WM8974_MCLKDIV_12 (7 << 5)
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8978.c b/ANDROID_3.4.5/sound/soc/codecs/wm8978.c
deleted file mode 100644
index 72d5fdcd..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8978.c
+++ /dev/null
@@ -1,1129 +0,0 @@
-/*
- * wm8978.c -- WM8978 ALSA SoC Audio Codec driver
- *
- * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- * Copyright (C) 2007 Carlos Munoz <carlos@kenati.com>
- * Copyright 2006-2009 Wolfson Microelectronics PLC.
- * Based on wm8974 and wm8990 by Liam Girdwood <lrg@slimlogic.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/regmap.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <asm/div64.h>
-
-#include "wm8978.h"
-
-static const struct reg_default wm8978_reg_defaults[] = {
- { 1, 0x0000 },
- { 2, 0x0000 },
- { 3, 0x0000 },
- { 4, 0x0050 },
- { 5, 0x0000 },
- { 6, 0x0140 },
- { 7, 0x0000 },
- { 8, 0x0000 },
- { 9, 0x0000 },
- { 10, 0x0000 },
- { 11, 0x00ff },
- { 12, 0x00ff },
- { 13, 0x0000 },
- { 14, 0x0100 },
- { 15, 0x00ff },
- { 16, 0x00ff },
- { 17, 0x0000 },
- { 18, 0x012c },
- { 19, 0x002c },
- { 20, 0x002c },
- { 21, 0x002c },
- { 22, 0x002c },
- { 23, 0x0000 },
- { 24, 0x0032 },
- { 25, 0x0000 },
- { 26, 0x0000 },
- { 27, 0x0000 },
- { 28, 0x0000 },
- { 29, 0x0000 },
- { 30, 0x0000 },
- { 31, 0x0000 },
- { 32, 0x0038 },
- { 33, 0x000b },
- { 34, 0x0032 },
- { 35, 0x0000 },
- { 36, 0x0008 },
- { 37, 0x000c },
- { 38, 0x0093 },
- { 39, 0x00e9 },
- { 40, 0x0000 },
- { 41, 0x0000 },
- { 42, 0x0000 },
- { 43, 0x0000 },
- { 44, 0x0033 },
- { 45, 0x0010 },
- { 46, 0x0010 },
- { 47, 0x0100 },
- { 48, 0x0100 },
- { 49, 0x0002 },
- { 50, 0x0001 },
- { 51, 0x0001 },
- { 52, 0x0039 },
- { 53, 0x0039 },
- { 54, 0x0039 },
- { 55, 0x0039 },
- { 56, 0x0001 },
- { 57, 0x0001 },
-};
-
-static bool wm8978_volatile(struct device *dev, unsigned int reg)
-{
- return reg == WM8978_RESET;
-}
-
-/* codec private data */
-struct wm8978_priv {
- struct regmap *regmap;
- unsigned int f_pllout;
- unsigned int f_mclk;
- unsigned int f_256fs;
- unsigned int f_opclk;
- int mclk_idx;
- enum wm8978_sysclk_src sysclk;
-};
-
-static const char *wm8978_companding[] = {"Off", "NC", "u-law", "A-law"};
-static const char *wm8978_eqmode[] = {"Capture", "Playback"};
-static const char *wm8978_bw[] = {"Narrow", "Wide"};
-static const char *wm8978_eq1[] = {"80Hz", "105Hz", "135Hz", "175Hz"};
-static const char *wm8978_eq2[] = {"230Hz", "300Hz", "385Hz", "500Hz"};
-static const char *wm8978_eq3[] = {"650Hz", "850Hz", "1.1kHz", "1.4kHz"};
-static const char *wm8978_eq4[] = {"1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz"};
-static const char *wm8978_eq5[] = {"5.3kHz", "6.9kHz", "9kHz", "11.7kHz"};
-static const char *wm8978_alc3[] = {"ALC", "Limiter"};
-static const char *wm8978_alc1[] = {"Off", "Right", "Left", "Both"};
-
-static const SOC_ENUM_SINGLE_DECL(adc_compand, WM8978_COMPANDING_CONTROL, 1,
- wm8978_companding);
-static const SOC_ENUM_SINGLE_DECL(dac_compand, WM8978_COMPANDING_CONTROL, 3,
- wm8978_companding);
-static const SOC_ENUM_SINGLE_DECL(eqmode, WM8978_EQ1, 8, wm8978_eqmode);
-static const SOC_ENUM_SINGLE_DECL(eq1, WM8978_EQ1, 5, wm8978_eq1);
-static const SOC_ENUM_SINGLE_DECL(eq2bw, WM8978_EQ2, 8, wm8978_bw);
-static const SOC_ENUM_SINGLE_DECL(eq2, WM8978_EQ2, 5, wm8978_eq2);
-static const SOC_ENUM_SINGLE_DECL(eq3bw, WM8978_EQ3, 8, wm8978_bw);
-static const SOC_ENUM_SINGLE_DECL(eq3, WM8978_EQ3, 5, wm8978_eq3);
-static const SOC_ENUM_SINGLE_DECL(eq4bw, WM8978_EQ4, 8, wm8978_bw);
-static const SOC_ENUM_SINGLE_DECL(eq4, WM8978_EQ4, 5, wm8978_eq4);
-static const SOC_ENUM_SINGLE_DECL(eq5, WM8978_EQ5, 5, wm8978_eq5);
-static const SOC_ENUM_SINGLE_DECL(alc3, WM8978_ALC_CONTROL_3, 8, wm8978_alc3);
-static const SOC_ENUM_SINGLE_DECL(alc1, WM8978_ALC_CONTROL_1, 7, wm8978_alc1);
-
-static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);
-static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
-static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0);
-static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0);
-static const DECLARE_TLV_DB_SCALE(boost_tlv, -1500, 300, 1);
-static const DECLARE_TLV_DB_SCALE(limiter_tlv, 0, 100, 0);
-
-static const struct snd_kcontrol_new wm8978_snd_controls[] = {
-
- SOC_SINGLE("Digital Loopback Switch",
- WM8978_COMPANDING_CONTROL, 0, 1, 0),
-
- SOC_ENUM("ADC Companding", adc_compand),
- SOC_ENUM("DAC Companding", dac_compand),
-
- SOC_DOUBLE("DAC Inversion Switch", WM8978_DAC_CONTROL, 0, 1, 1, 0),
-
- SOC_DOUBLE_R_TLV("PCM Volume",
- WM8978_LEFT_DAC_DIGITAL_VOLUME, WM8978_RIGHT_DAC_DIGITAL_VOLUME,
- 0, 255, 0, digital_tlv),
-
- SOC_SINGLE("High Pass Filter Switch", WM8978_ADC_CONTROL, 8, 1, 0),
- SOC_SINGLE("High Pass Cut Off", WM8978_ADC_CONTROL, 4, 7, 0),
- SOC_DOUBLE("ADC Inversion Switch", WM8978_ADC_CONTROL, 0, 1, 1, 0),
-
- SOC_DOUBLE_R_TLV("ADC Volume",
- WM8978_LEFT_ADC_DIGITAL_VOLUME, WM8978_RIGHT_ADC_DIGITAL_VOLUME,
- 0, 255, 0, digital_tlv),
-
- SOC_ENUM("Equaliser Function", eqmode),
- SOC_ENUM("EQ1 Cut Off", eq1),
- SOC_SINGLE_TLV("EQ1 Volume", WM8978_EQ1, 0, 24, 1, eq_tlv),
-
- SOC_ENUM("Equaliser EQ2 Bandwith", eq2bw),
- SOC_ENUM("EQ2 Cut Off", eq2),
- SOC_SINGLE_TLV("EQ2 Volume", WM8978_EQ2, 0, 24, 1, eq_tlv),
-
- SOC_ENUM("Equaliser EQ3 Bandwith", eq3bw),
- SOC_ENUM("EQ3 Cut Off", eq3),
- SOC_SINGLE_TLV("EQ3 Volume", WM8978_EQ3, 0, 24, 1, eq_tlv),
-
- SOC_ENUM("Equaliser EQ4 Bandwith", eq4bw),
- SOC_ENUM("EQ4 Cut Off", eq4),
- SOC_SINGLE_TLV("EQ4 Volume", WM8978_EQ4, 0, 24, 1, eq_tlv),
-
- SOC_ENUM("EQ5 Cut Off", eq5),
- SOC_SINGLE_TLV("EQ5 Volume", WM8978_EQ5, 0, 24, 1, eq_tlv),
-
- SOC_SINGLE("DAC Playback Limiter Switch",
- WM8978_DAC_LIMITER_1, 8, 1, 0),
- SOC_SINGLE("DAC Playback Limiter Decay",
- WM8978_DAC_LIMITER_1, 4, 15, 0),
- SOC_SINGLE("DAC Playback Limiter Attack",
- WM8978_DAC_LIMITER_1, 0, 15, 0),
-
- SOC_SINGLE("DAC Playback Limiter Threshold",
- WM8978_DAC_LIMITER_2, 4, 7, 0),
- SOC_SINGLE_TLV("DAC Playback Limiter Volume",
- WM8978_DAC_LIMITER_2, 0, 12, 0, limiter_tlv),
-
- SOC_ENUM("ALC Enable Switch", alc1),
- SOC_SINGLE("ALC Capture Min Gain", WM8978_ALC_CONTROL_1, 0, 7, 0),
- SOC_SINGLE("ALC Capture Max Gain", WM8978_ALC_CONTROL_1, 3, 7, 0),
-
- SOC_SINGLE("ALC Capture Hold", WM8978_ALC_CONTROL_2, 4, 10, 0),
- SOC_SINGLE("ALC Capture Target", WM8978_ALC_CONTROL_2, 0, 15, 0),
-
- SOC_ENUM("ALC Capture Mode", alc3),
- SOC_SINGLE("ALC Capture Decay", WM8978_ALC_CONTROL_3, 4, 10, 0),
- SOC_SINGLE("ALC Capture Attack", WM8978_ALC_CONTROL_3, 0, 10, 0),
-
- SOC_SINGLE("ALC Capture Noise Gate Switch", WM8978_NOISE_GATE, 3, 1, 0),
- SOC_SINGLE("ALC Capture Noise Gate Threshold",
- WM8978_NOISE_GATE, 0, 7, 0),
-
- SOC_DOUBLE_R("Capture PGA ZC Switch",
- WM8978_LEFT_INP_PGA_CONTROL, WM8978_RIGHT_INP_PGA_CONTROL,
- 7, 1, 0),
-
- /* OUT1 - Headphones */
- SOC_DOUBLE_R("Headphone Playback ZC Switch",
- WM8978_LOUT1_HP_CONTROL, WM8978_ROUT1_HP_CONTROL, 7, 1, 0),
-
- SOC_DOUBLE_R_TLV("Headphone Playback Volume",
- WM8978_LOUT1_HP_CONTROL, WM8978_ROUT1_HP_CONTROL,
- 0, 63, 0, spk_tlv),
-
- /* OUT2 - Speakers */
- SOC_DOUBLE_R("Speaker Playback ZC Switch",
- WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL, 7, 1, 0),
-
- SOC_DOUBLE_R_TLV("Speaker Playback Volume",
- WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL,
- 0, 63, 0, spk_tlv),
-
- /* OUT3/4 - Line Output */
- SOC_DOUBLE_R("Line Playback Switch",
- WM8978_OUT3_MIXER_CONTROL, WM8978_OUT4_MIXER_CONTROL, 6, 1, 1),
-
- /* Mixer #3: Boost (Input) mixer */
- SOC_DOUBLE_R("PGA Boost (+20dB)",
- WM8978_LEFT_ADC_BOOST_CONTROL, WM8978_RIGHT_ADC_BOOST_CONTROL,
- 8, 1, 0),
- SOC_DOUBLE_R_TLV("L2/R2 Boost Volume",
- WM8978_LEFT_ADC_BOOST_CONTROL, WM8978_RIGHT_ADC_BOOST_CONTROL,
- 4, 7, 0, boost_tlv),
- SOC_DOUBLE_R_TLV("Aux Boost Volume",
- WM8978_LEFT_ADC_BOOST_CONTROL, WM8978_RIGHT_ADC_BOOST_CONTROL,
- 0, 7, 0, boost_tlv),
-
- /* Input PGA volume */
- SOC_DOUBLE_R_TLV("Input PGA Volume",
- WM8978_LEFT_INP_PGA_CONTROL, WM8978_RIGHT_INP_PGA_CONTROL,
- 0, 63, 0, inpga_tlv),
-
- /* Headphone */
- SOC_DOUBLE_R("Headphone Switch",
- WM8978_LOUT1_HP_CONTROL, WM8978_ROUT1_HP_CONTROL, 6, 1, 1),
-
- /* Speaker */
- SOC_DOUBLE_R("Speaker Switch",
- WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL, 6, 1, 1),
-
- /* DAC / ADC oversampling */
- SOC_SINGLE("DAC 128x Oversampling Switch", WM8978_DAC_CONTROL,
- 5, 1, 0),
- SOC_SINGLE("ADC 128x Oversampling Switch", WM8978_ADC_CONTROL,
- 5, 1, 0),
-};
-
-/* Mixer #1: Output (OUT1, OUT2) Mixer: mix AUX, Input mixer output and DAC */
-static const struct snd_kcontrol_new wm8978_left_out_mixer[] = {
- SOC_DAPM_SINGLE("Line Bypass Switch", WM8978_LEFT_MIXER_CONTROL, 1, 1, 0),
- SOC_DAPM_SINGLE("Aux Playback Switch", WM8978_LEFT_MIXER_CONTROL, 5, 1, 0),
- SOC_DAPM_SINGLE("PCM Playback Switch", WM8978_LEFT_MIXER_CONTROL, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8978_right_out_mixer[] = {
- SOC_DAPM_SINGLE("Line Bypass Switch", WM8978_RIGHT_MIXER_CONTROL, 1, 1, 0),
- SOC_DAPM_SINGLE("Aux Playback Switch", WM8978_RIGHT_MIXER_CONTROL, 5, 1, 0),
- SOC_DAPM_SINGLE("PCM Playback Switch", WM8978_RIGHT_MIXER_CONTROL, 0, 1, 0),
-};
-
-/* OUT3/OUT4 Mixer not implemented */
-
-/* Mixer #2: Input PGA Mute */
-static const struct snd_kcontrol_new wm8978_left_input_mixer[] = {
- SOC_DAPM_SINGLE("L2 Switch", WM8978_INPUT_CONTROL, 2, 1, 0),
- SOC_DAPM_SINGLE("MicN Switch", WM8978_INPUT_CONTROL, 1, 1, 0),
- SOC_DAPM_SINGLE("MicP Switch", WM8978_INPUT_CONTROL, 0, 1, 0),
-};
-static const struct snd_kcontrol_new wm8978_right_input_mixer[] = {
- SOC_DAPM_SINGLE("R2 Switch", WM8978_INPUT_CONTROL, 6, 1, 0),
- SOC_DAPM_SINGLE("MicN Switch", WM8978_INPUT_CONTROL, 5, 1, 0),
- SOC_DAPM_SINGLE("MicP Switch", WM8978_INPUT_CONTROL, 4, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget wm8978_dapm_widgets[] = {
- SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback",
- WM8978_POWER_MANAGEMENT_3, 0, 0),
- SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback",
- WM8978_POWER_MANAGEMENT_3, 1, 0),
- SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture",
- WM8978_POWER_MANAGEMENT_2, 0, 0),
- SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture",
- WM8978_POWER_MANAGEMENT_2, 1, 0),
-
- /* Mixer #1: OUT1,2 */
- SOC_MIXER_ARRAY("Left Output Mixer", WM8978_POWER_MANAGEMENT_3,
- 2, 0, wm8978_left_out_mixer),
- SOC_MIXER_ARRAY("Right Output Mixer", WM8978_POWER_MANAGEMENT_3,
- 3, 0, wm8978_right_out_mixer),
-
- SOC_MIXER_ARRAY("Left Input Mixer", WM8978_POWER_MANAGEMENT_2,
- 2, 0, wm8978_left_input_mixer),
- SOC_MIXER_ARRAY("Right Input Mixer", WM8978_POWER_MANAGEMENT_2,
- 3, 0, wm8978_right_input_mixer),
-
- SND_SOC_DAPM_PGA("Left Boost Mixer", WM8978_POWER_MANAGEMENT_2,
- 4, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Right Boost Mixer", WM8978_POWER_MANAGEMENT_2,
- 5, 0, NULL, 0),
-
- SND_SOC_DAPM_PGA("Left Capture PGA", WM8978_LEFT_INP_PGA_CONTROL,
- 6, 1, NULL, 0),
- SND_SOC_DAPM_PGA("Right Capture PGA", WM8978_RIGHT_INP_PGA_CONTROL,
- 6, 1, NULL, 0),
-
- SND_SOC_DAPM_PGA("Left Headphone Out", WM8978_POWER_MANAGEMENT_2,
- 7, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Right Headphone Out", WM8978_POWER_MANAGEMENT_2,
- 8, 0, NULL, 0),
-
- SND_SOC_DAPM_PGA("Left Speaker Out", WM8978_POWER_MANAGEMENT_3,
- 6, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Right Speaker Out", WM8978_POWER_MANAGEMENT_3,
- 5, 0, NULL, 0),
-
- SND_SOC_DAPM_MIXER("OUT4 VMID", WM8978_POWER_MANAGEMENT_3,
- 8, 0, NULL, 0),
-
- SND_SOC_DAPM_MICBIAS("Mic Bias", WM8978_POWER_MANAGEMENT_1, 4, 0),
-
- SND_SOC_DAPM_INPUT("LMICN"),
- SND_SOC_DAPM_INPUT("LMICP"),
- SND_SOC_DAPM_INPUT("RMICN"),
- SND_SOC_DAPM_INPUT("RMICP"),
- SND_SOC_DAPM_INPUT("LAUX"),
- SND_SOC_DAPM_INPUT("RAUX"),
- SND_SOC_DAPM_INPUT("L2"),
- SND_SOC_DAPM_INPUT("R2"),
- SND_SOC_DAPM_OUTPUT("LHP"),
- SND_SOC_DAPM_OUTPUT("RHP"),
- SND_SOC_DAPM_OUTPUT("LSPK"),
- SND_SOC_DAPM_OUTPUT("RSPK"),
-};
-
-static const struct snd_soc_dapm_route wm8978_dapm_routes[] = {
- /* Output mixer */
- {"Right Output Mixer", "PCM Playback Switch", "Right DAC"},
- {"Right Output Mixer", "Aux Playback Switch", "RAUX"},
- {"Right Output Mixer", "Line Bypass Switch", "Right Boost Mixer"},
-
- {"Left Output Mixer", "PCM Playback Switch", "Left DAC"},
- {"Left Output Mixer", "Aux Playback Switch", "LAUX"},
- {"Left Output Mixer", "Line Bypass Switch", "Left Boost Mixer"},
-
- /* Outputs */
- {"Right Headphone Out", NULL, "Right Output Mixer"},
- {"RHP", NULL, "Right Headphone Out"},
-
- {"Left Headphone Out", NULL, "Left Output Mixer"},
- {"LHP", NULL, "Left Headphone Out"},
-
- {"Right Speaker Out", NULL, "Right Output Mixer"},
- {"RSPK", NULL, "Right Speaker Out"},
-
- {"Left Speaker Out", NULL, "Left Output Mixer"},
- {"LSPK", NULL, "Left Speaker Out"},
-
- /* Boost Mixer */
- {"Right ADC", NULL, "Right Boost Mixer"},
-
- {"Right Boost Mixer", NULL, "RAUX"},
- {"Right Boost Mixer", NULL, "Right Capture PGA"},
- {"Right Boost Mixer", NULL, "R2"},
-
- {"Left ADC", NULL, "Left Boost Mixer"},
-
- {"Left Boost Mixer", NULL, "LAUX"},
- {"Left Boost Mixer", NULL, "Left Capture PGA"},
- {"Left Boost Mixer", NULL, "L2"},
-
- /* Input PGA */
- {"Right Capture PGA", NULL, "Right Input Mixer"},
- {"Left Capture PGA", NULL, "Left Input Mixer"},
-
- {"Right Input Mixer", "R2 Switch", "R2"},
- {"Right Input Mixer", "MicN Switch", "RMICN"},
- {"Right Input Mixer", "MicP Switch", "RMICP"},
-
- {"Left Input Mixer", "L2 Switch", "L2"},
- {"Left Input Mixer", "MicN Switch", "LMICN"},
- {"Left Input Mixer", "MicP Switch", "LMICP"},
-};
-
-/* PLL divisors */
-struct wm8978_pll_div {
- u32 k;
- u8 n;
- u8 div2;
-};
-
-#define FIXED_PLL_SIZE (1 << 24)
-
-static void pll_factors(struct snd_soc_codec *codec,
- struct wm8978_pll_div *pll_div, unsigned int target, unsigned int source)
-{
- u64 k_part;
- unsigned int k, n_div, n_mod;
-
- n_div = target / source;
- if (n_div < 6) {
- source >>= 1;
- pll_div->div2 = 1;
- n_div = target / source;
- } else {
- pll_div->div2 = 0;
- }
-
- if (n_div < 6 || n_div > 12)
- dev_warn(codec->dev,
- "WM8978 N value exceeds recommended range! N = %u\n",
- n_div);
-
- pll_div->n = n_div;
- n_mod = target - source * n_div;
- k_part = FIXED_PLL_SIZE * (long long)n_mod + source / 2;
-
- do_div(k_part, source);
-
- k = k_part & 0xFFFFFFFF;
-
- pll_div->k = k;
-}
-
-/* MCLK dividers */
-static const int mclk_numerator[] = {1, 3, 2, 3, 4, 6, 8, 12};
-static const int mclk_denominator[] = {1, 2, 1, 1, 1, 1, 1, 1};
-
-/*
- * find index >= idx, such that, for a given f_out,
- * 3 * f_mclk / 4 <= f_PLLOUT < 13 * f_mclk / 4
- * f_out can be f_256fs or f_opclk, currently only used for f_256fs. Can be
- * generalised for f_opclk with suitable coefficient arrays, but currently
- * the OPCLK divisor is calculated directly, not iteratively.
- */
-static int wm8978_enum_mclk(unsigned int f_out, unsigned int f_mclk,
- unsigned int *f_pllout)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(mclk_numerator); i++) {
- unsigned int f_pllout_x4 = 4 * f_out * mclk_numerator[i] /
- mclk_denominator[i];
- if (3 * f_mclk <= f_pllout_x4 && f_pllout_x4 < 13 * f_mclk) {
- *f_pllout = f_pllout_x4 / 4;
- return i;
- }
- }
-
- return -EINVAL;
-}
-
-/*
- * Calculate internal frequencies and dividers, according to Figure 40
- * "PLL and Clock Select Circuit" in WM8978 datasheet Rev. 2.6
- */
-static int wm8978_configure_pll(struct snd_soc_codec *codec)
-{
- struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
- struct wm8978_pll_div pll_div;
- unsigned int f_opclk = wm8978->f_opclk, f_mclk = wm8978->f_mclk,
- f_256fs = wm8978->f_256fs;
- unsigned int f2;
-
- if (!f_mclk)
- return -EINVAL;
-
- if (f_opclk) {
- unsigned int opclk_div;
- /* Cannot set up MCLK divider now, do later */
- wm8978->mclk_idx = -1;
-
- /*
- * The user needs OPCLK. Choose OPCLKDIV to put
- * 6 <= R = f2 / f1 < 13, 1 <= OPCLKDIV <= 4.
- * f_opclk = f_mclk * prescale * R / 4 / OPCLKDIV, where
- * prescale = 1, or prescale = 2. Prescale is calculated inside
- * pll_factors(). We have to select f_PLLOUT, such that
- * f_mclk * 3 / 4 <= f_PLLOUT < f_mclk * 13 / 4. Must be
- * f_mclk * 3 / 16 <= f_opclk < f_mclk * 13 / 4.
- */
- if (16 * f_opclk < 3 * f_mclk || 4 * f_opclk >= 13 * f_mclk)
- return -EINVAL;
-
- if (4 * f_opclk < 3 * f_mclk)
- /* Have to use OPCLKDIV */
- opclk_div = (3 * f_mclk / 4 + f_opclk - 1) / f_opclk;
- else
- opclk_div = 1;
-
- dev_dbg(codec->dev, "%s: OPCLKDIV=%d\n", __func__, opclk_div);
-
- snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 0x30,
- (opclk_div - 1) << 4);
-
- wm8978->f_pllout = f_opclk * opclk_div;
- } else if (f_256fs) {
- /*
- * Not using OPCLK, but PLL is used for the codec, choose R:
- * 6 <= R = f2 / f1 < 13, to put 1 <= MCLKDIV <= 12.
- * f_256fs = f_mclk * prescale * R / 4 / MCLKDIV, where
- * prescale = 1, or prescale = 2. Prescale is calculated inside
- * pll_factors(). We have to select f_PLLOUT, such that
- * f_mclk * 3 / 4 <= f_PLLOUT < f_mclk * 13 / 4. Must be
- * f_mclk * 3 / 48 <= f_256fs < f_mclk * 13 / 4. This means MCLK
- * must be 3.781MHz <= f_MCLK <= 32.768MHz
- */
- int idx = wm8978_enum_mclk(f_256fs, f_mclk, &wm8978->f_pllout);
- if (idx < 0)
- return idx;
-
- wm8978->mclk_idx = idx;
-
- /* GPIO1 into default mode as input - before configuring PLL */
- snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 0);
- } else {
- return -EINVAL;
- }
-
- f2 = wm8978->f_pllout * 4;
-
- dev_dbg(codec->dev, "%s: f_MCLK=%uHz, f_PLLOUT=%uHz\n", __func__,
- wm8978->f_mclk, wm8978->f_pllout);
-
- pll_factors(codec, &pll_div, f2, wm8978->f_mclk);
-
- dev_dbg(codec->dev, "%s: calculated PLL N=0x%x, K=0x%x, div2=%d\n",
- __func__, pll_div.n, pll_div.k, pll_div.div2);
-
- /* Turn PLL off for configuration... */
- snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0);
-
- snd_soc_write(codec, WM8978_PLL_N, (pll_div.div2 << 4) | pll_div.n);
- snd_soc_write(codec, WM8978_PLL_K1, pll_div.k >> 18);
- snd_soc_write(codec, WM8978_PLL_K2, (pll_div.k >> 9) & 0x1ff);
- snd_soc_write(codec, WM8978_PLL_K3, pll_div.k & 0x1ff);
-
- /* ...and on again */
- snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0x20);
-
- if (f_opclk)
- /* Output PLL (OPCLK) to GPIO1 */
- snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 4);
-
- return 0;
-}
-
-/*
- * Configure WM8978 clock dividers.
- */
-static int wm8978_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
- int div_id, int div)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
- int ret = 0;
-
- switch (div_id) {
- case WM8978_OPCLKRATE:
- wm8978->f_opclk = div;
-
- if (wm8978->f_mclk)
- /*
- * We know the MCLK frequency, the user has requested
- * OPCLK, configure the PLL based on that and start it
- * and OPCLK immediately. We will configure PLL to match
- * user-requested OPCLK frquency as good as possible.
- * In fact, it is likely, that matching the sampling
- * rate, when it becomes known, is more important, and
- * we will not be reconfiguring PLL then, because we
- * must not interrupt OPCLK. But it should be fine,
- * because typically the user will request OPCLK to run
- * at 256fs or 512fs, and for these cases we will also
- * find an exact MCLK divider configuration - it will
- * be equal to or double the OPCLK divisor.
- */
- ret = wm8978_configure_pll(codec);
- break;
- case WM8978_BCLKDIV:
- if (div & ~0x1c)
- return -EINVAL;
- snd_soc_update_bits(codec, WM8978_CLOCKING, 0x1c, div);
- break;
- default:
- return -EINVAL;
- }
-
- dev_dbg(codec->dev, "%s: ID %d, value %u\n", __func__, div_id, div);
-
- return ret;
-}
-
-/*
- * @freq: when .set_pll() us not used, freq is codec MCLK input frequency
- */
-static int wm8978_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
- unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
- int ret = 0;
-
- dev_dbg(codec->dev, "%s: ID %d, freq %u\n", __func__, clk_id, freq);
-
- if (freq) {
- wm8978->f_mclk = freq;
-
- /* Even if MCLK is used for system clock, might have to drive OPCLK */
- if (wm8978->f_opclk)
- ret = wm8978_configure_pll(codec);
-
- /* Our sysclk is fixed to 256 * fs, will configure in .hw_params() */
-
- if (!ret)
- wm8978->sysclk = clk_id;
- }
-
- if (wm8978->sysclk == WM8978_PLL && (!freq || clk_id == WM8978_MCLK)) {
- /* Clock CODEC directly from MCLK */
- snd_soc_update_bits(codec, WM8978_CLOCKING, 0x100, 0);
-
- /* GPIO1 into default mode as input - before configuring PLL */
- snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 0);
-
- /* Turn off PLL */
- snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0);
- wm8978->sysclk = WM8978_MCLK;
- wm8978->f_pllout = 0;
- wm8978->f_opclk = 0;
- }
-
- return ret;
-}
-
-/*
- * Set ADC and Voice DAC format.
- */
-static int wm8978_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- /*
- * BCLK polarity mask = 0x100, LRC clock polarity mask = 0x80,
- * Data Format mask = 0x18: all will be calculated anew
- */
- u16 iface = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x198;
- u16 clk = snd_soc_read(codec, WM8978_CLOCKING);
-
- dev_dbg(codec->dev, "%s\n", __func__);
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- clk |= 1;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- clk &= ~1;
- break;
- default:
- return -EINVAL;
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= 0x10;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= 0x8;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= 0x18;
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= 0x180;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= 0x100;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- iface |= 0x80;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM8978_AUDIO_INTERFACE, iface);
- snd_soc_write(codec, WM8978_CLOCKING, clk);
-
- return 0;
-}
-
-/*
- * Set PCM DAI bit size and sample rate.
- */
-static int wm8978_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
- /* Word length mask = 0x60 */
- u16 iface_ctl = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x60;
- /* Sampling rate mask = 0xe (for filters) */
- u16 add_ctl = snd_soc_read(codec, WM8978_ADDITIONAL_CONTROL) & ~0xe;
- u16 clking = snd_soc_read(codec, WM8978_CLOCKING);
- enum wm8978_sysclk_src current_clk_id = clking & 0x100 ?
- WM8978_PLL : WM8978_MCLK;
- unsigned int f_sel, diff, diff_best = INT_MAX;
- int i, best = 0;
-
- if (!wm8978->f_mclk)
- return -EINVAL;
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface_ctl |= 0x20;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface_ctl |= 0x40;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- iface_ctl |= 0x60;
- break;
- }
-
- /* filter coefficient */
- switch (params_rate(params)) {
- case 8000:
- add_ctl |= 0x5 << 1;
- break;
- case 11025:
- add_ctl |= 0x4 << 1;
- break;
- case 16000:
- add_ctl |= 0x3 << 1;
- break;
- case 22050:
- add_ctl |= 0x2 << 1;
- break;
- case 32000:
- add_ctl |= 0x1 << 1;
- break;
- case 44100:
- case 48000:
- break;
- }
-
- /* Sampling rate is known now, can configure the MCLK divider */
- wm8978->f_256fs = params_rate(params) * 256;
-
- if (wm8978->sysclk == WM8978_MCLK) {
- wm8978->mclk_idx = -1;
- f_sel = wm8978->f_mclk;
- } else {
- if (!wm8978->f_pllout) {
- /* We only enter here, if OPCLK is not used */
- int ret = wm8978_configure_pll(codec);
- if (ret < 0)
- return ret;
- }
- f_sel = wm8978->f_pllout;
- }
-
- if (wm8978->mclk_idx < 0) {
- /* Either MCLK is used directly, or OPCLK is used */
- if (f_sel < wm8978->f_256fs || f_sel > 12 * wm8978->f_256fs)
- return -EINVAL;
-
- for (i = 0; i < ARRAY_SIZE(mclk_numerator); i++) {
- diff = abs(wm8978->f_256fs * 3 -
- f_sel * 3 * mclk_denominator[i] / mclk_numerator[i]);
-
- if (diff < diff_best) {
- diff_best = diff;
- best = i;
- }
-
- if (!diff)
- break;
- }
- } else {
- /* OPCLK not used, codec driven by PLL */
- best = wm8978->mclk_idx;
- diff = 0;
- }
-
- if (diff)
- dev_warn(codec->dev, "Imprecise sampling rate: %uHz%s\n",
- f_sel * mclk_denominator[best] / mclk_numerator[best] / 256,
- wm8978->sysclk == WM8978_MCLK ?
- ", consider using PLL" : "");
-
- dev_dbg(codec->dev, "%s: fmt %d, rate %u, MCLK divisor #%d\n", __func__,
- params_format(params), params_rate(params), best);
-
- /* MCLK divisor mask = 0xe0 */
- snd_soc_update_bits(codec, WM8978_CLOCKING, 0xe0, best << 5);
-
- snd_soc_write(codec, WM8978_AUDIO_INTERFACE, iface_ctl);
- snd_soc_write(codec, WM8978_ADDITIONAL_CONTROL, add_ctl);
-
- if (wm8978->sysclk != current_clk_id) {
- if (wm8978->sysclk == WM8978_PLL)
- /* Run CODEC from PLL instead of MCLK */
- snd_soc_update_bits(codec, WM8978_CLOCKING,
- 0x100, 0x100);
- else
- /* Clock CODEC directly from MCLK */
- snd_soc_update_bits(codec, WM8978_CLOCKING, 0x100, 0);
- }
-
- return 0;
-}
-
-static int wm8978_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
-
- dev_dbg(codec->dev, "%s: %d\n", __func__, mute);
-
- if (mute)
- snd_soc_update_bits(codec, WM8978_DAC_CONTROL, 0x40, 0x40);
- else
- snd_soc_update_bits(codec, WM8978_DAC_CONTROL, 0x40, 0);
-
- return 0;
-}
-
-static int wm8978_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- u16 power1 = snd_soc_read(codec, WM8978_POWER_MANAGEMENT_1) & ~3;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- case SND_SOC_BIAS_PREPARE:
- power1 |= 1; /* VMID 75k */
- snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, power1);
- break;
- case SND_SOC_BIAS_STANDBY:
- /* bit 3: enable bias, bit 2: enable I/O tie off buffer */
- power1 |= 0xc;
-
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- /* Initial cap charge at VMID 5k */
- snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1,
- power1 | 0x3);
- mdelay(100);
- }
-
- power1 |= 0x2; /* VMID 500k */
- snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, power1);
- break;
- case SND_SOC_BIAS_OFF:
- /* Preserve PLL - OPCLK may be used by someone */
- snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, ~0x20, 0);
- snd_soc_write(codec, WM8978_POWER_MANAGEMENT_2, 0);
- snd_soc_write(codec, WM8978_POWER_MANAGEMENT_3, 0);
- break;
- }
-
- dev_dbg(codec->dev, "%s: %d, %x\n", __func__, level, power1);
-
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define WM8978_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops wm8978_dai_ops = {
- .hw_params = wm8978_hw_params,
- .digital_mute = wm8978_mute,
- .set_fmt = wm8978_set_dai_fmt,
- .set_clkdiv = wm8978_set_dai_clkdiv,
- .set_sysclk = wm8978_set_dai_sysclk,
-};
-
-/* Also supports 12kHz */
-static struct snd_soc_dai_driver wm8978_dai = {
- .name = "wm8978-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = WM8978_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = WM8978_FORMATS,
- },
- .ops = &wm8978_dai_ops,
-};
-
-static int wm8978_suspend(struct snd_soc_codec *codec)
-{
- struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
-
- wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF);
- /* Also switch PLL off */
- snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 0);
-
- regcache_mark_dirty(wm8978->regmap);
-
- return 0;
-}
-
-static int wm8978_resume(struct snd_soc_codec *codec)
-{
- struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
-
- /* Sync reg_cache with the hardware */
- regcache_sync(wm8978->regmap);
-
- wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- if (wm8978->f_pllout)
- /* Switch PLL on */
- snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0x20);
-
- return 0;
-}
-
-/*
- * These registers contain an "update" bit - bit 8. This means, for example,
- * that one can write new DAC digital volume for both channels, but only when
- * the update bit is set, will also the volume be updated - simultaneously for
- * both channels.
- */
-static const int update_reg[] = {
- WM8978_LEFT_DAC_DIGITAL_VOLUME,
- WM8978_RIGHT_DAC_DIGITAL_VOLUME,
- WM8978_LEFT_ADC_DIGITAL_VOLUME,
- WM8978_RIGHT_ADC_DIGITAL_VOLUME,
- WM8978_LEFT_INP_PGA_CONTROL,
- WM8978_RIGHT_INP_PGA_CONTROL,
- WM8978_LOUT1_HP_CONTROL,
- WM8978_ROUT1_HP_CONTROL,
- WM8978_LOUT2_SPK_CONTROL,
- WM8978_ROUT2_SPK_CONTROL,
-};
-
-static int wm8978_probe(struct snd_soc_codec *codec)
-{
- struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
- int ret = 0, i;
-
- /*
- * Set default system clock to PLL, it is more precise, this is also the
- * default hardware setting
- */
- wm8978->sysclk = WM8978_PLL;
- codec->control_data = wm8978->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- /*
- * Set the update bit in all registers, that have one. This way all
- * writes to those registers will also cause the update bit to be
- * written.
- */
- for (i = 0; i < ARRAY_SIZE(update_reg); i++)
- snd_soc_update_bits(codec, update_reg[i], 0x100, 0x100);
-
- wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-
-/* power down chip */
-static int wm8978_remove(struct snd_soc_codec *codec)
-{
- wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8978 = {
- .probe = wm8978_probe,
- .remove = wm8978_remove,
- .suspend = wm8978_suspend,
- .resume = wm8978_resume,
- .set_bias_level = wm8978_set_bias_level,
-
- .controls = wm8978_snd_controls,
- .num_controls = ARRAY_SIZE(wm8978_snd_controls),
- .dapm_widgets = wm8978_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8978_dapm_widgets),
- .dapm_routes = wm8978_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm8978_dapm_routes),
-};
-
-static const struct regmap_config wm8978_regmap_config = {
- .reg_bits = 7,
- .val_bits = 9,
-
- .max_register = WM8978_MAX_REGISTER,
- .volatile_reg = wm8978_volatile,
-
- .cache_type = REGCACHE_RBTREE,
- .reg_defaults = wm8978_reg_defaults,
- .num_reg_defaults = ARRAY_SIZE(wm8978_reg_defaults),
-};
-
-static __devinit int wm8978_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8978_priv *wm8978;
- int ret;
-
- wm8978 = devm_kzalloc(&i2c->dev, sizeof(struct wm8978_priv),
- GFP_KERNEL);
- if (wm8978 == NULL)
- return -ENOMEM;
-
- wm8978->regmap = regmap_init_i2c(i2c, &wm8978_regmap_config);
- if (IS_ERR(wm8978->regmap)) {
- ret = PTR_ERR(wm8978->regmap);
- dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
- return ret;
- }
-
- i2c_set_clientdata(i2c, wm8978);
-
- /* Reset the codec */
- ret = regmap_write(wm8978->regmap, WM8978_RESET, 0);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret);
- goto err;
- }
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8978, &wm8978_dai, 1);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
- goto err;
- }
-
- return 0;
-
-err:
- regmap_exit(wm8978->regmap);
- return ret;
-}
-
-static __devexit int wm8978_i2c_remove(struct i2c_client *client)
-{
- struct wm8978_priv *wm8978 = i2c_get_clientdata(client);
-
- snd_soc_unregister_codec(&client->dev);
- regmap_exit(wm8978->regmap);
-
- return 0;
-}
-
-static const struct i2c_device_id wm8978_i2c_id[] = {
- { "wm8978", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8978_i2c_id);
-
-static struct i2c_driver wm8978_i2c_driver = {
- .driver = {
- .name = "wm8978",
- .owner = THIS_MODULE,
- },
- .probe = wm8978_i2c_probe,
- .remove = __devexit_p(wm8978_i2c_remove),
- .id_table = wm8978_i2c_id,
-};
-
-static int __init wm8978_modinit(void)
-{
- int ret = 0;
- ret = i2c_add_driver(&wm8978_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8978 I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(wm8978_modinit);
-
-static void __exit wm8978_exit(void)
-{
- i2c_del_driver(&wm8978_i2c_driver);
-}
-module_exit(wm8978_exit);
-
-MODULE_DESCRIPTION("ASoC WM8978 codec driver");
-MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8978.h b/ANDROID_3.4.5/sound/soc/codecs/wm8978.h
deleted file mode 100644
index 6ae43495..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8978.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * wm8978.h -- codec driver for WM8978
- *
- * Copyright 2009 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __WM8978_H__
-#define __WM8978_H__
-
-/*
- * Register values.
- */
-#define WM8978_RESET 0x00
-#define WM8978_POWER_MANAGEMENT_1 0x01
-#define WM8978_POWER_MANAGEMENT_2 0x02
-#define WM8978_POWER_MANAGEMENT_3 0x03
-#define WM8978_AUDIO_INTERFACE 0x04
-#define WM8978_COMPANDING_CONTROL 0x05
-#define WM8978_CLOCKING 0x06
-#define WM8978_ADDITIONAL_CONTROL 0x07
-#define WM8978_GPIO_CONTROL 0x08
-#define WM8978_JACK_DETECT_CONTROL_1 0x09
-#define WM8978_DAC_CONTROL 0x0A
-#define WM8978_LEFT_DAC_DIGITAL_VOLUME 0x0B
-#define WM8978_RIGHT_DAC_DIGITAL_VOLUME 0x0C
-#define WM8978_JACK_DETECT_CONTROL_2 0x0D
-#define WM8978_ADC_CONTROL 0x0E
-#define WM8978_LEFT_ADC_DIGITAL_VOLUME 0x0F
-#define WM8978_RIGHT_ADC_DIGITAL_VOLUME 0x10
-#define WM8978_EQ1 0x12
-#define WM8978_EQ2 0x13
-#define WM8978_EQ3 0x14
-#define WM8978_EQ4 0x15
-#define WM8978_EQ5 0x16
-#define WM8978_DAC_LIMITER_1 0x18
-#define WM8978_DAC_LIMITER_2 0x19
-#define WM8978_NOTCH_FILTER_1 0x1b
-#define WM8978_NOTCH_FILTER_2 0x1c
-#define WM8978_NOTCH_FILTER_3 0x1d
-#define WM8978_NOTCH_FILTER_4 0x1e
-#define WM8978_ALC_CONTROL_1 0x20
-#define WM8978_ALC_CONTROL_2 0x21
-#define WM8978_ALC_CONTROL_3 0x22
-#define WM8978_NOISE_GATE 0x23
-#define WM8978_PLL_N 0x24
-#define WM8978_PLL_K1 0x25
-#define WM8978_PLL_K2 0x26
-#define WM8978_PLL_K3 0x27
-#define WM8978_3D_CONTROL 0x29
-#define WM8978_BEEP_CONTROL 0x2b
-#define WM8978_INPUT_CONTROL 0x2c
-#define WM8978_LEFT_INP_PGA_CONTROL 0x2d
-#define WM8978_RIGHT_INP_PGA_CONTROL 0x2e
-#define WM8978_LEFT_ADC_BOOST_CONTROL 0x2f
-#define WM8978_RIGHT_ADC_BOOST_CONTROL 0x30
-#define WM8978_OUTPUT_CONTROL 0x31
-#define WM8978_LEFT_MIXER_CONTROL 0x32
-#define WM8978_RIGHT_MIXER_CONTROL 0x33
-#define WM8978_LOUT1_HP_CONTROL 0x34
-#define WM8978_ROUT1_HP_CONTROL 0x35
-#define WM8978_LOUT2_SPK_CONTROL 0x36
-#define WM8978_ROUT2_SPK_CONTROL 0x37
-#define WM8978_OUT3_MIXER_CONTROL 0x38
-#define WM8978_OUT4_MIXER_CONTROL 0x39
-
-#define WM8978_MAX_REGISTER 0x39
-
-#define WM8978_CACHEREGNUM 58
-
-/* Clock divider Id's */
-enum wm8978_clk_id {
- WM8978_OPCLKRATE,
- WM8978_BCLKDIV,
-};
-
-enum wm8978_sysclk_src {
- WM8978_PLL,
- WM8978_MCLK
-};
-
-#endif /* __WM8978_H__ */
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8983.c b/ANDROID_3.4.5/sound/soc/codecs/wm8983.c
deleted file mode 100644
index 367388fd..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8983.c
+++ /dev/null
@@ -1,1199 +0,0 @@
-/*
- * wm8983.c -- WM8983 ALSA SoC Audio driver
- *
- * Copyright 2011 Wolfson Microelectronics plc
- *
- * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "wm8983.h"
-
-static const u16 wm8983_reg_defs[WM8983_MAX_REGISTER + 1] = {
- [0x00] = 0x0000, /* R0 - Software Reset */
- [0x01] = 0x0000, /* R1 - Power management 1 */
- [0x02] = 0x0000, /* R2 - Power management 2 */
- [0x03] = 0x0000, /* R3 - Power management 3 */
- [0x04] = 0x0050, /* R4 - Audio Interface */
- [0x05] = 0x0000, /* R5 - Companding control */
- [0x06] = 0x0140, /* R6 - Clock Gen control */
- [0x07] = 0x0000, /* R7 - Additional control */
- [0x08] = 0x0000, /* R8 - GPIO Control */
- [0x09] = 0x0000, /* R9 - Jack Detect Control 1 */
- [0x0A] = 0x0000, /* R10 - DAC Control */
- [0x0B] = 0x00FF, /* R11 - Left DAC digital Vol */
- [0x0C] = 0x00FF, /* R12 - Right DAC digital vol */
- [0x0D] = 0x0000, /* R13 - Jack Detect Control 2 */
- [0x0E] = 0x0100, /* R14 - ADC Control */
- [0x0F] = 0x00FF, /* R15 - Left ADC Digital Vol */
- [0x10] = 0x00FF, /* R16 - Right ADC Digital Vol */
- [0x12] = 0x012C, /* R18 - EQ1 - low shelf */
- [0x13] = 0x002C, /* R19 - EQ2 - peak 1 */
- [0x14] = 0x002C, /* R20 - EQ3 - peak 2 */
- [0x15] = 0x002C, /* R21 - EQ4 - peak 3 */
- [0x16] = 0x002C, /* R22 - EQ5 - high shelf */
- [0x18] = 0x0032, /* R24 - DAC Limiter 1 */
- [0x19] = 0x0000, /* R25 - DAC Limiter 2 */
- [0x1B] = 0x0000, /* R27 - Notch Filter 1 */
- [0x1C] = 0x0000, /* R28 - Notch Filter 2 */
- [0x1D] = 0x0000, /* R29 - Notch Filter 3 */
- [0x1E] = 0x0000, /* R30 - Notch Filter 4 */
- [0x20] = 0x0038, /* R32 - ALC control 1 */
- [0x21] = 0x000B, /* R33 - ALC control 2 */
- [0x22] = 0x0032, /* R34 - ALC control 3 */
- [0x23] = 0x0000, /* R35 - Noise Gate */
- [0x24] = 0x0008, /* R36 - PLL N */
- [0x25] = 0x000C, /* R37 - PLL K 1 */
- [0x26] = 0x0093, /* R38 - PLL K 2 */
- [0x27] = 0x00E9, /* R39 - PLL K 3 */
- [0x29] = 0x0000, /* R41 - 3D control */
- [0x2A] = 0x0000, /* R42 - OUT4 to ADC */
- [0x2B] = 0x0000, /* R43 - Beep control */
- [0x2C] = 0x0033, /* R44 - Input ctrl */
- [0x2D] = 0x0010, /* R45 - Left INP PGA gain ctrl */
- [0x2E] = 0x0010, /* R46 - Right INP PGA gain ctrl */
- [0x2F] = 0x0100, /* R47 - Left ADC BOOST ctrl */
- [0x30] = 0x0100, /* R48 - Right ADC BOOST ctrl */
- [0x31] = 0x0002, /* R49 - Output ctrl */
- [0x32] = 0x0001, /* R50 - Left mixer ctrl */
- [0x33] = 0x0001, /* R51 - Right mixer ctrl */
- [0x34] = 0x0039, /* R52 - LOUT1 (HP) volume ctrl */
- [0x35] = 0x0039, /* R53 - ROUT1 (HP) volume ctrl */
- [0x36] = 0x0039, /* R54 - LOUT2 (SPK) volume ctrl */
- [0x37] = 0x0039, /* R55 - ROUT2 (SPK) volume ctrl */
- [0x38] = 0x0001, /* R56 - OUT3 mixer ctrl */
- [0x39] = 0x0001, /* R57 - OUT4 (MONO) mix ctrl */
- [0x3D] = 0x0000 /* R61 - BIAS CTRL */
-};
-
-static const struct wm8983_reg_access {
- u16 read; /* Mask of readable bits */
- u16 write; /* Mask of writable bits */
-} wm8983_access_masks[WM8983_MAX_REGISTER + 1] = {
- [0x00] = { 0x0000, 0x01FF }, /* R0 - Software Reset */
- [0x01] = { 0x0000, 0x01FF }, /* R1 - Power management 1 */
- [0x02] = { 0x0000, 0x01FF }, /* R2 - Power management 2 */
- [0x03] = { 0x0000, 0x01EF }, /* R3 - Power management 3 */
- [0x04] = { 0x0000, 0x01FF }, /* R4 - Audio Interface */
- [0x05] = { 0x0000, 0x003F }, /* R5 - Companding control */
- [0x06] = { 0x0000, 0x01FD }, /* R6 - Clock Gen control */
- [0x07] = { 0x0000, 0x000F }, /* R7 - Additional control */
- [0x08] = { 0x0000, 0x003F }, /* R8 - GPIO Control */
- [0x09] = { 0x0000, 0x0070 }, /* R9 - Jack Detect Control 1 */
- [0x0A] = { 0x0000, 0x004F }, /* R10 - DAC Control */
- [0x0B] = { 0x0000, 0x01FF }, /* R11 - Left DAC digital Vol */
- [0x0C] = { 0x0000, 0x01FF }, /* R12 - Right DAC digital vol */
- [0x0D] = { 0x0000, 0x00FF }, /* R13 - Jack Detect Control 2 */
- [0x0E] = { 0x0000, 0x01FB }, /* R14 - ADC Control */
- [0x0F] = { 0x0000, 0x01FF }, /* R15 - Left ADC Digital Vol */
- [0x10] = { 0x0000, 0x01FF }, /* R16 - Right ADC Digital Vol */
- [0x12] = { 0x0000, 0x017F }, /* R18 - EQ1 - low shelf */
- [0x13] = { 0x0000, 0x017F }, /* R19 - EQ2 - peak 1 */
- [0x14] = { 0x0000, 0x017F }, /* R20 - EQ3 - peak 2 */
- [0x15] = { 0x0000, 0x017F }, /* R21 - EQ4 - peak 3 */
- [0x16] = { 0x0000, 0x007F }, /* R22 - EQ5 - high shelf */
- [0x18] = { 0x0000, 0x01FF }, /* R24 - DAC Limiter 1 */
- [0x19] = { 0x0000, 0x007F }, /* R25 - DAC Limiter 2 */
- [0x1B] = { 0x0000, 0x01FF }, /* R27 - Notch Filter 1 */
- [0x1C] = { 0x0000, 0x017F }, /* R28 - Notch Filter 2 */
- [0x1D] = { 0x0000, 0x017F }, /* R29 - Notch Filter 3 */
- [0x1E] = { 0x0000, 0x017F }, /* R30 - Notch Filter 4 */
- [0x20] = { 0x0000, 0x01BF }, /* R32 - ALC control 1 */
- [0x21] = { 0x0000, 0x00FF }, /* R33 - ALC control 2 */
- [0x22] = { 0x0000, 0x01FF }, /* R34 - ALC control 3 */
- [0x23] = { 0x0000, 0x000F }, /* R35 - Noise Gate */
- [0x24] = { 0x0000, 0x001F }, /* R36 - PLL N */
- [0x25] = { 0x0000, 0x003F }, /* R37 - PLL K 1 */
- [0x26] = { 0x0000, 0x01FF }, /* R38 - PLL K 2 */
- [0x27] = { 0x0000, 0x01FF }, /* R39 - PLL K 3 */
- [0x29] = { 0x0000, 0x000F }, /* R41 - 3D control */
- [0x2A] = { 0x0000, 0x01E7 }, /* R42 - OUT4 to ADC */
- [0x2B] = { 0x0000, 0x01BF }, /* R43 - Beep control */
- [0x2C] = { 0x0000, 0x0177 }, /* R44 - Input ctrl */
- [0x2D] = { 0x0000, 0x01FF }, /* R45 - Left INP PGA gain ctrl */
- [0x2E] = { 0x0000, 0x01FF }, /* R46 - Right INP PGA gain ctrl */
- [0x2F] = { 0x0000, 0x0177 }, /* R47 - Left ADC BOOST ctrl */
- [0x30] = { 0x0000, 0x0177 }, /* R48 - Right ADC BOOST ctrl */
- [0x31] = { 0x0000, 0x007F }, /* R49 - Output ctrl */
- [0x32] = { 0x0000, 0x01FF }, /* R50 - Left mixer ctrl */
- [0x33] = { 0x0000, 0x01FF }, /* R51 - Right mixer ctrl */
- [0x34] = { 0x0000, 0x01FF }, /* R52 - LOUT1 (HP) volume ctrl */
- [0x35] = { 0x0000, 0x01FF }, /* R53 - ROUT1 (HP) volume ctrl */
- [0x36] = { 0x0000, 0x01FF }, /* R54 - LOUT2 (SPK) volume ctrl */
- [0x37] = { 0x0000, 0x01FF }, /* R55 - ROUT2 (SPK) volume ctrl */
- [0x38] = { 0x0000, 0x004F }, /* R56 - OUT3 mixer ctrl */
- [0x39] = { 0x0000, 0x00FF }, /* R57 - OUT4 (MONO) mix ctrl */
- [0x3D] = { 0x0000, 0x0100 } /* R61 - BIAS CTRL */
-};
-
-/* vol/gain update regs */
-static const int vol_update_regs[] = {
- WM8983_LEFT_DAC_DIGITAL_VOL,
- WM8983_RIGHT_DAC_DIGITAL_VOL,
- WM8983_LEFT_ADC_DIGITAL_VOL,
- WM8983_RIGHT_ADC_DIGITAL_VOL,
- WM8983_LOUT1_HP_VOLUME_CTRL,
- WM8983_ROUT1_HP_VOLUME_CTRL,
- WM8983_LOUT2_SPK_VOLUME_CTRL,
- WM8983_ROUT2_SPK_VOLUME_CTRL,
- WM8983_LEFT_INP_PGA_GAIN_CTRL,
- WM8983_RIGHT_INP_PGA_GAIN_CTRL
-};
-
-struct wm8983_priv {
- enum snd_soc_control_type control_type;
- u32 sysclk;
- u32 bclk;
-};
-
-static const struct {
- int div;
- int ratio;
-} fs_ratios[] = {
- { 10, 128 },
- { 15, 192 },
- { 20, 256 },
- { 30, 384 },
- { 40, 512 },
- { 60, 768 },
- { 80, 1024 },
- { 120, 1536 }
-};
-
-static const int srates[] = { 48000, 32000, 24000, 16000, 12000, 8000 };
-
-static const int bclk_divs[] = {
- 1, 2, 4, 8, 16, 32
-};
-
-static int eqmode_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-static int eqmode_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-
-static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1);
-static const DECLARE_TLV_DB_SCALE(adc_tlv, -12700, 50, 1);
-static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
-static const DECLARE_TLV_DB_SCALE(lim_thresh_tlv, -600, 100, 0);
-static const DECLARE_TLV_DB_SCALE(lim_boost_tlv, 0, 100, 0);
-static const DECLARE_TLV_DB_SCALE(alc_min_tlv, -1200, 600, 0);
-static const DECLARE_TLV_DB_SCALE(alc_max_tlv, -675, 600, 0);
-static const DECLARE_TLV_DB_SCALE(alc_tar_tlv, -2250, 150, 0);
-static const DECLARE_TLV_DB_SCALE(pga_vol_tlv, -1200, 75, 0);
-static const DECLARE_TLV_DB_SCALE(boost_tlv, -1200, 300, 1);
-static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
-static const DECLARE_TLV_DB_SCALE(aux_tlv, -1500, 300, 0);
-static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
-static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0);
-
-static const char *alc_sel_text[] = { "Off", "Right", "Left", "Stereo" };
-static const SOC_ENUM_SINGLE_DECL(alc_sel, WM8983_ALC_CONTROL_1, 7,
- alc_sel_text);
-
-static const char *alc_mode_text[] = { "ALC", "Limiter" };
-static const SOC_ENUM_SINGLE_DECL(alc_mode, WM8983_ALC_CONTROL_3, 8,
- alc_mode_text);
-
-static const char *filter_mode_text[] = { "Audio", "Application" };
-static const SOC_ENUM_SINGLE_DECL(filter_mode, WM8983_ADC_CONTROL, 7,
- filter_mode_text);
-
-static const char *eq_bw_text[] = { "Narrow", "Wide" };
-static const char *eqmode_text[] = { "Capture", "Playback" };
-static const SOC_ENUM_SINGLE_EXT_DECL(eqmode, eqmode_text);
-
-static const char *eq1_cutoff_text[] = {
- "80Hz", "105Hz", "135Hz", "175Hz"
-};
-static const SOC_ENUM_SINGLE_DECL(eq1_cutoff, WM8983_EQ1_LOW_SHELF, 5,
- eq1_cutoff_text);
-static const char *eq2_cutoff_text[] = {
- "230Hz", "300Hz", "385Hz", "500Hz"
-};
-static const SOC_ENUM_SINGLE_DECL(eq2_bw, WM8983_EQ2_PEAK_1, 8, eq_bw_text);
-static const SOC_ENUM_SINGLE_DECL(eq2_cutoff, WM8983_EQ2_PEAK_1, 5,
- eq2_cutoff_text);
-static const char *eq3_cutoff_text[] = {
- "650Hz", "850Hz", "1.1kHz", "1.4kHz"
-};
-static const SOC_ENUM_SINGLE_DECL(eq3_bw, WM8983_EQ3_PEAK_2, 8, eq_bw_text);
-static const SOC_ENUM_SINGLE_DECL(eq3_cutoff, WM8983_EQ3_PEAK_2, 5,
- eq3_cutoff_text);
-static const char *eq4_cutoff_text[] = {
- "1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz"
-};
-static const SOC_ENUM_SINGLE_DECL(eq4_bw, WM8983_EQ4_PEAK_3, 8, eq_bw_text);
-static const SOC_ENUM_SINGLE_DECL(eq4_cutoff, WM8983_EQ4_PEAK_3, 5,
- eq4_cutoff_text);
-static const char *eq5_cutoff_text[] = {
- "5.3kHz", "6.9kHz", "9kHz", "11.7kHz"
-};
-static const SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8983_EQ5_HIGH_SHELF, 5,
- eq5_cutoff_text);
-
-static const char *depth_3d_text[] = {
- "Off",
- "6.67%",
- "13.3%",
- "20%",
- "26.7%",
- "33.3%",
- "40%",
- "46.6%",
- "53.3%",
- "60%",
- "66.7%",
- "73.3%",
- "80%",
- "86.7%",
- "93.3%",
- "100%"
-};
-static const SOC_ENUM_SINGLE_DECL(depth_3d, WM8983_3D_CONTROL, 0,
- depth_3d_text);
-
-static const struct snd_kcontrol_new wm8983_snd_controls[] = {
- SOC_SINGLE("Digital Loopback Switch", WM8983_COMPANDING_CONTROL,
- 0, 1, 0),
-
- SOC_ENUM("ALC Capture Function", alc_sel),
- SOC_SINGLE_TLV("ALC Capture Max Volume", WM8983_ALC_CONTROL_1,
- 3, 7, 0, alc_max_tlv),
- SOC_SINGLE_TLV("ALC Capture Min Volume", WM8983_ALC_CONTROL_1,
- 0, 7, 0, alc_min_tlv),
- SOC_SINGLE_TLV("ALC Capture Target Volume", WM8983_ALC_CONTROL_2,
- 0, 15, 0, alc_tar_tlv),
- SOC_SINGLE("ALC Capture Attack", WM8983_ALC_CONTROL_3, 0, 10, 0),
- SOC_SINGLE("ALC Capture Hold", WM8983_ALC_CONTROL_2, 4, 10, 0),
- SOC_SINGLE("ALC Capture Decay", WM8983_ALC_CONTROL_3, 4, 10, 0),
- SOC_ENUM("ALC Mode", alc_mode),
- SOC_SINGLE("ALC Capture NG Switch", WM8983_NOISE_GATE,
- 3, 1, 0),
- SOC_SINGLE("ALC Capture NG Threshold", WM8983_NOISE_GATE,
- 0, 7, 1),
-
- SOC_DOUBLE_R_TLV("Capture Volume", WM8983_LEFT_ADC_DIGITAL_VOL,
- WM8983_RIGHT_ADC_DIGITAL_VOL, 0, 255, 0, adc_tlv),
- SOC_DOUBLE_R("Capture PGA ZC Switch", WM8983_LEFT_INP_PGA_GAIN_CTRL,
- WM8983_RIGHT_INP_PGA_GAIN_CTRL, 7, 1, 0),
- SOC_DOUBLE_R_TLV("Capture PGA Volume", WM8983_LEFT_INP_PGA_GAIN_CTRL,
- WM8983_RIGHT_INP_PGA_GAIN_CTRL, 0, 63, 0, pga_vol_tlv),
-
- SOC_DOUBLE_R_TLV("Capture PGA Boost Volume",
- WM8983_LEFT_ADC_BOOST_CTRL, WM8983_RIGHT_ADC_BOOST_CTRL,
- 8, 1, 0, pga_boost_tlv),
-
- SOC_DOUBLE("ADC Inversion Switch", WM8983_ADC_CONTROL, 0, 1, 1, 0),
- SOC_SINGLE("ADC 128x Oversampling Switch", WM8983_ADC_CONTROL, 8, 1, 0),
-
- SOC_DOUBLE_R_TLV("Playback Volume", WM8983_LEFT_DAC_DIGITAL_VOL,
- WM8983_RIGHT_DAC_DIGITAL_VOL, 0, 255, 0, dac_tlv),
-
- SOC_SINGLE("DAC Playback Limiter Switch", WM8983_DAC_LIMITER_1, 8, 1, 0),
- SOC_SINGLE("DAC Playback Limiter Decay", WM8983_DAC_LIMITER_1, 4, 10, 0),
- SOC_SINGLE("DAC Playback Limiter Attack", WM8983_DAC_LIMITER_1, 0, 11, 0),
- SOC_SINGLE_TLV("DAC Playback Limiter Threshold", WM8983_DAC_LIMITER_2,
- 4, 7, 1, lim_thresh_tlv),
- SOC_SINGLE_TLV("DAC Playback Limiter Boost Volume", WM8983_DAC_LIMITER_2,
- 0, 12, 0, lim_boost_tlv),
- SOC_DOUBLE("DAC Inversion Switch", WM8983_DAC_CONTROL, 0, 1, 1, 0),
- SOC_SINGLE("DAC Auto Mute Switch", WM8983_DAC_CONTROL, 2, 1, 0),
- SOC_SINGLE("DAC 128x Oversampling Switch", WM8983_DAC_CONTROL, 3, 1, 0),
-
- SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8983_LOUT1_HP_VOLUME_CTRL,
- WM8983_ROUT1_HP_VOLUME_CTRL, 0, 63, 0, out_tlv),
- SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8983_LOUT1_HP_VOLUME_CTRL,
- WM8983_ROUT1_HP_VOLUME_CTRL, 7, 1, 0),
- SOC_DOUBLE_R("Headphone Switch", WM8983_LOUT1_HP_VOLUME_CTRL,
- WM8983_ROUT1_HP_VOLUME_CTRL, 6, 1, 1),
-
- SOC_DOUBLE_R_TLV("Speaker Playback Volume", WM8983_LOUT2_SPK_VOLUME_CTRL,
- WM8983_ROUT2_SPK_VOLUME_CTRL, 0, 63, 0, out_tlv),
- SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8983_LOUT2_SPK_VOLUME_CTRL,
- WM8983_ROUT2_SPK_VOLUME_CTRL, 7, 1, 0),
- SOC_DOUBLE_R("Speaker Switch", WM8983_LOUT2_SPK_VOLUME_CTRL,
- WM8983_ROUT2_SPK_VOLUME_CTRL, 6, 1, 1),
-
- SOC_SINGLE("OUT3 Switch", WM8983_OUT3_MIXER_CTRL,
- 6, 1, 1),
-
- SOC_SINGLE("OUT4 Switch", WM8983_OUT4_MONO_MIX_CTRL,
- 6, 1, 1),
-
- SOC_SINGLE("High Pass Filter Switch", WM8983_ADC_CONTROL, 8, 1, 0),
- SOC_ENUM("High Pass Filter Mode", filter_mode),
- SOC_SINGLE("High Pass Filter Cutoff", WM8983_ADC_CONTROL, 4, 7, 0),
-
- SOC_DOUBLE_R_TLV("Aux Bypass Volume",
- WM8983_LEFT_MIXER_CTRL, WM8983_RIGHT_MIXER_CTRL, 6, 7, 0,
- aux_tlv),
-
- SOC_DOUBLE_R_TLV("Input PGA Bypass Volume",
- WM8983_LEFT_MIXER_CTRL, WM8983_RIGHT_MIXER_CTRL, 2, 7, 0,
- bypass_tlv),
-
- SOC_ENUM_EXT("Equalizer Function", eqmode, eqmode_get, eqmode_put),
- SOC_ENUM("EQ1 Cutoff", eq1_cutoff),
- SOC_SINGLE_TLV("EQ1 Volume", WM8983_EQ1_LOW_SHELF, 0, 24, 1, eq_tlv),
- SOC_ENUM("EQ2 Bandwith", eq2_bw),
- SOC_ENUM("EQ2 Cutoff", eq2_cutoff),
- SOC_SINGLE_TLV("EQ2 Volume", WM8983_EQ2_PEAK_1, 0, 24, 1, eq_tlv),
- SOC_ENUM("EQ3 Bandwith", eq3_bw),
- SOC_ENUM("EQ3 Cutoff", eq3_cutoff),
- SOC_SINGLE_TLV("EQ3 Volume", WM8983_EQ3_PEAK_2, 0, 24, 1, eq_tlv),
- SOC_ENUM("EQ4 Bandwith", eq4_bw),
- SOC_ENUM("EQ4 Cutoff", eq4_cutoff),
- SOC_SINGLE_TLV("EQ4 Volume", WM8983_EQ4_PEAK_3, 0, 24, 1, eq_tlv),
- SOC_ENUM("EQ5 Cutoff", eq5_cutoff),
- SOC_SINGLE_TLV("EQ5 Volume", WM8983_EQ5_HIGH_SHELF, 0, 24, 1, eq_tlv),
-
- SOC_ENUM("3D Depth", depth_3d),
-};
-
-static const struct snd_kcontrol_new left_out_mixer[] = {
- SOC_DAPM_SINGLE("Line Switch", WM8983_LEFT_MIXER_CTRL, 1, 1, 0),
- SOC_DAPM_SINGLE("Aux Switch", WM8983_LEFT_MIXER_CTRL, 5, 1, 0),
- SOC_DAPM_SINGLE("PCM Switch", WM8983_LEFT_MIXER_CTRL, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new right_out_mixer[] = {
- SOC_DAPM_SINGLE("Line Switch", WM8983_RIGHT_MIXER_CTRL, 1, 1, 0),
- SOC_DAPM_SINGLE("Aux Switch", WM8983_RIGHT_MIXER_CTRL, 5, 1, 0),
- SOC_DAPM_SINGLE("PCM Switch", WM8983_RIGHT_MIXER_CTRL, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new left_input_mixer[] = {
- SOC_DAPM_SINGLE("L2 Switch", WM8983_INPUT_CTRL, 2, 1, 0),
- SOC_DAPM_SINGLE("MicN Switch", WM8983_INPUT_CTRL, 1, 1, 0),
- SOC_DAPM_SINGLE("MicP Switch", WM8983_INPUT_CTRL, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new right_input_mixer[] = {
- SOC_DAPM_SINGLE("R2 Switch", WM8983_INPUT_CTRL, 6, 1, 0),
- SOC_DAPM_SINGLE("MicN Switch", WM8983_INPUT_CTRL, 5, 1, 0),
- SOC_DAPM_SINGLE("MicP Switch", WM8983_INPUT_CTRL, 4, 1, 0),
-};
-
-static const struct snd_kcontrol_new left_boost_mixer[] = {
- SOC_DAPM_SINGLE_TLV("L2 Volume", WM8983_LEFT_ADC_BOOST_CTRL,
- 4, 7, 0, boost_tlv),
- SOC_DAPM_SINGLE_TLV("AUXL Volume", WM8983_LEFT_ADC_BOOST_CTRL,
- 0, 7, 0, boost_tlv)
-};
-
-static const struct snd_kcontrol_new out3_mixer[] = {
- SOC_DAPM_SINGLE("LMIX2OUT3 Switch", WM8983_OUT3_MIXER_CTRL,
- 1, 1, 0),
- SOC_DAPM_SINGLE("LDAC2OUT3 Switch", WM8983_OUT3_MIXER_CTRL,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new out4_mixer[] = {
- SOC_DAPM_SINGLE("LMIX2OUT4 Switch", WM8983_OUT4_MONO_MIX_CTRL,
- 4, 1, 0),
- SOC_DAPM_SINGLE("RMIX2OUT4 Switch", WM8983_OUT4_MONO_MIX_CTRL,
- 1, 1, 0),
- SOC_DAPM_SINGLE("LDAC2OUT4 Switch", WM8983_OUT4_MONO_MIX_CTRL,
- 3, 1, 0),
- SOC_DAPM_SINGLE("RDAC2OUT4 Switch", WM8983_OUT4_MONO_MIX_CTRL,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new right_boost_mixer[] = {
- SOC_DAPM_SINGLE_TLV("R2 Volume", WM8983_RIGHT_ADC_BOOST_CTRL,
- 4, 7, 0, boost_tlv),
- SOC_DAPM_SINGLE_TLV("AUXR Volume", WM8983_RIGHT_ADC_BOOST_CTRL,
- 0, 7, 0, boost_tlv)
-};
-
-static const struct snd_soc_dapm_widget wm8983_dapm_widgets[] = {
- SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8983_POWER_MANAGEMENT_3,
- 0, 0),
- SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8983_POWER_MANAGEMENT_3,
- 1, 0),
- SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8983_POWER_MANAGEMENT_2,
- 0, 0),
- SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8983_POWER_MANAGEMENT_2,
- 1, 0),
-
- SND_SOC_DAPM_MIXER("Left Output Mixer", WM8983_POWER_MANAGEMENT_3,
- 2, 0, left_out_mixer, ARRAY_SIZE(left_out_mixer)),
- SND_SOC_DAPM_MIXER("Right Output Mixer", WM8983_POWER_MANAGEMENT_3,
- 3, 0, right_out_mixer, ARRAY_SIZE(right_out_mixer)),
-
- SND_SOC_DAPM_MIXER("Left Input Mixer", WM8983_POWER_MANAGEMENT_2,
- 2, 0, left_input_mixer, ARRAY_SIZE(left_input_mixer)),
- SND_SOC_DAPM_MIXER("Right Input Mixer", WM8983_POWER_MANAGEMENT_2,
- 3, 0, right_input_mixer, ARRAY_SIZE(right_input_mixer)),
-
- SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8983_POWER_MANAGEMENT_2,
- 4, 0, left_boost_mixer, ARRAY_SIZE(left_boost_mixer)),
- SND_SOC_DAPM_MIXER("Right Boost Mixer", WM8983_POWER_MANAGEMENT_2,
- 5, 0, right_boost_mixer, ARRAY_SIZE(right_boost_mixer)),
-
- SND_SOC_DAPM_MIXER("OUT3 Mixer", WM8983_POWER_MANAGEMENT_1,
- 6, 0, out3_mixer, ARRAY_SIZE(out3_mixer)),
-
- SND_SOC_DAPM_MIXER("OUT4 Mixer", WM8983_POWER_MANAGEMENT_1,
- 7, 0, out4_mixer, ARRAY_SIZE(out4_mixer)),
-
- SND_SOC_DAPM_PGA("Left Capture PGA", WM8983_LEFT_INP_PGA_GAIN_CTRL,
- 6, 1, NULL, 0),
- SND_SOC_DAPM_PGA("Right Capture PGA", WM8983_RIGHT_INP_PGA_GAIN_CTRL,
- 6, 1, NULL, 0),
-
- SND_SOC_DAPM_PGA("Left Headphone Out", WM8983_POWER_MANAGEMENT_2,
- 7, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Right Headphone Out", WM8983_POWER_MANAGEMENT_2,
- 8, 0, NULL, 0),
-
- SND_SOC_DAPM_PGA("Left Speaker Out", WM8983_POWER_MANAGEMENT_3,
- 5, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Right Speaker Out", WM8983_POWER_MANAGEMENT_3,
- 6, 0, NULL, 0),
-
- SND_SOC_DAPM_PGA("OUT3 Out", WM8983_POWER_MANAGEMENT_3,
- 7, 0, NULL, 0),
-
- SND_SOC_DAPM_PGA("OUT4 Out", WM8983_POWER_MANAGEMENT_3,
- 8, 0, NULL, 0),
-
- SND_SOC_DAPM_SUPPLY("Mic Bias", WM8983_POWER_MANAGEMENT_1, 4, 0,
- NULL, 0),
-
- SND_SOC_DAPM_INPUT("LIN"),
- SND_SOC_DAPM_INPUT("LIP"),
- SND_SOC_DAPM_INPUT("RIN"),
- SND_SOC_DAPM_INPUT("RIP"),
- SND_SOC_DAPM_INPUT("AUXL"),
- SND_SOC_DAPM_INPUT("AUXR"),
- SND_SOC_DAPM_INPUT("L2"),
- SND_SOC_DAPM_INPUT("R2"),
- SND_SOC_DAPM_OUTPUT("HPL"),
- SND_SOC_DAPM_OUTPUT("HPR"),
- SND_SOC_DAPM_OUTPUT("SPKL"),
- SND_SOC_DAPM_OUTPUT("SPKR"),
- SND_SOC_DAPM_OUTPUT("OUT3"),
- SND_SOC_DAPM_OUTPUT("OUT4")
-};
-
-static const struct snd_soc_dapm_route wm8983_audio_map[] = {
- { "OUT3 Mixer", "LMIX2OUT3 Switch", "Left Output Mixer" },
- { "OUT3 Mixer", "LDAC2OUT3 Switch", "Left DAC" },
-
- { "OUT3 Out", NULL, "OUT3 Mixer" },
- { "OUT3", NULL, "OUT3 Out" },
-
- { "OUT4 Mixer", "LMIX2OUT4 Switch", "Left Output Mixer" },
- { "OUT4 Mixer", "RMIX2OUT4 Switch", "Right Output Mixer" },
- { "OUT4 Mixer", "LDAC2OUT4 Switch", "Left DAC" },
- { "OUT4 Mixer", "RDAC2OUT4 Switch", "Right DAC" },
-
- { "OUT4 Out", NULL, "OUT4 Mixer" },
- { "OUT4", NULL, "OUT4 Out" },
-
- { "Right Output Mixer", "PCM Switch", "Right DAC" },
- { "Right Output Mixer", "Aux Switch", "AUXR" },
- { "Right Output Mixer", "Line Switch", "Right Boost Mixer" },
-
- { "Left Output Mixer", "PCM Switch", "Left DAC" },
- { "Left Output Mixer", "Aux Switch", "AUXL" },
- { "Left Output Mixer", "Line Switch", "Left Boost Mixer" },
-
- { "Right Headphone Out", NULL, "Right Output Mixer" },
- { "HPR", NULL, "Right Headphone Out" },
-
- { "Left Headphone Out", NULL, "Left Output Mixer" },
- { "HPL", NULL, "Left Headphone Out" },
-
- { "Right Speaker Out", NULL, "Right Output Mixer" },
- { "SPKR", NULL, "Right Speaker Out" },
-
- { "Left Speaker Out", NULL, "Left Output Mixer" },
- { "SPKL", NULL, "Left Speaker Out" },
-
- { "Right ADC", NULL, "Right Boost Mixer" },
-
- { "Right Boost Mixer", "AUXR Volume", "AUXR" },
- { "Right Boost Mixer", NULL, "Right Capture PGA" },
- { "Right Boost Mixer", "R2 Volume", "R2" },
-
- { "Left ADC", NULL, "Left Boost Mixer" },
-
- { "Left Boost Mixer", "AUXL Volume", "AUXL" },
- { "Left Boost Mixer", NULL, "Left Capture PGA" },
- { "Left Boost Mixer", "L2 Volume", "L2" },
-
- { "Right Capture PGA", NULL, "Right Input Mixer" },
- { "Left Capture PGA", NULL, "Left Input Mixer" },
-
- { "Right Input Mixer", "R2 Switch", "R2" },
- { "Right Input Mixer", "MicN Switch", "RIN" },
- { "Right Input Mixer", "MicP Switch", "RIP" },
-
- { "Left Input Mixer", "L2 Switch", "L2" },
- { "Left Input Mixer", "MicN Switch", "LIN" },
- { "Left Input Mixer", "MicP Switch", "LIP" },
-};
-
-static int eqmode_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int reg;
-
- reg = snd_soc_read(codec, WM8983_EQ1_LOW_SHELF);
- if (reg & WM8983_EQ3DMODE)
- ucontrol->value.integer.value[0] = 1;
- else
- ucontrol->value.integer.value[0] = 0;
-
- return 0;
-}
-
-static int eqmode_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int regpwr2, regpwr3;
- unsigned int reg_eq;
-
- if (ucontrol->value.integer.value[0] != 0
- && ucontrol->value.integer.value[0] != 1)
- return -EINVAL;
-
- reg_eq = snd_soc_read(codec, WM8983_EQ1_LOW_SHELF);
- switch ((reg_eq & WM8983_EQ3DMODE) >> WM8983_EQ3DMODE_SHIFT) {
- case 0:
- if (!ucontrol->value.integer.value[0])
- return 0;
- break;
- case 1:
- if (ucontrol->value.integer.value[0])
- return 0;
- break;
- }
-
- regpwr2 = snd_soc_read(codec, WM8983_POWER_MANAGEMENT_2);
- regpwr3 = snd_soc_read(codec, WM8983_POWER_MANAGEMENT_3);
- /* disable the DACs and ADCs */
- snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_2,
- WM8983_ADCENR_MASK | WM8983_ADCENL_MASK, 0);
- snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_3,
- WM8983_DACENR_MASK | WM8983_DACENL_MASK, 0);
- /* set the desired eqmode */
- snd_soc_update_bits(codec, WM8983_EQ1_LOW_SHELF,
- WM8983_EQ3DMODE_MASK,
- ucontrol->value.integer.value[0]
- << WM8983_EQ3DMODE_SHIFT);
- /* restore DAC/ADC configuration */
- snd_soc_write(codec, WM8983_POWER_MANAGEMENT_2, regpwr2);
- snd_soc_write(codec, WM8983_POWER_MANAGEMENT_3, regpwr3);
- return 0;
-}
-
-static int wm8983_readable(struct snd_soc_codec *codec, unsigned int reg)
-{
- if (reg > WM8983_MAX_REGISTER)
- return 0;
-
- return wm8983_access_masks[reg].read != 0;
-}
-
-static int wm8983_dac_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
-
- return snd_soc_update_bits(codec, WM8983_DAC_CONTROL,
- WM8983_SOFTMUTE_MASK,
- !!mute << WM8983_SOFTMUTE_SHIFT);
-}
-
-static int wm8983_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 format, master, bcp, lrp;
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- format = 0x2;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- format = 0x0;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- format = 0x1;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- case SND_SOC_DAIFMT_DSP_B:
- format = 0x3;
- break;
- default:
- dev_err(dai->dev, "Unknown dai format\n");
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, WM8983_AUDIO_INTERFACE,
- WM8983_FMT_MASK, format << WM8983_FMT_SHIFT);
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- master = 1;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- master = 0;
- break;
- default:
- dev_err(dai->dev, "Unknown master/slave configuration\n");
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, WM8983_CLOCK_GEN_CONTROL,
- WM8983_MS_MASK, master << WM8983_MS_SHIFT);
-
- /* FIXME: We don't currently support DSP A/B modes */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- case SND_SOC_DAIFMT_DSP_B:
- dev_err(dai->dev, "DSP A/B modes are not supported\n");
- return -EINVAL;
- default:
- break;
- }
-
- bcp = lrp = 0;
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- bcp = lrp = 1;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- bcp = 1;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- lrp = 1;
- break;
- default:
- dev_err(dai->dev, "Unknown polarity configuration\n");
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, WM8983_AUDIO_INTERFACE,
- WM8983_LRCP_MASK, lrp << WM8983_LRCP_SHIFT);
- snd_soc_update_bits(codec, WM8983_AUDIO_INTERFACE,
- WM8983_BCP_MASK, bcp << WM8983_BCP_SHIFT);
- return 0;
-}
-
-static int wm8983_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- int i;
- struct snd_soc_codec *codec = dai->codec;
- struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec);
- u16 blen, srate_idx;
- u32 tmp;
- int srate_best;
- int ret;
-
- ret = snd_soc_params_to_bclk(params);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to convert params to bclk: %d\n", ret);
- return ret;
- }
-
- wm8983->bclk = ret;
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- blen = 0x0;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- blen = 0x1;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- blen = 0x2;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- blen = 0x3;
- break;
- default:
- dev_err(dai->dev, "Unsupported word length %u\n",
- params_format(params));
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, WM8983_AUDIO_INTERFACE,
- WM8983_WL_MASK, blen << WM8983_WL_SHIFT);
-
- /*
- * match to the nearest possible sample rate and rely
- * on the array index to configure the SR register
- */
- srate_idx = 0;
- srate_best = abs(srates[0] - params_rate(params));
- for (i = 1; i < ARRAY_SIZE(srates); ++i) {
- if (abs(srates[i] - params_rate(params)) >= srate_best)
- continue;
- srate_idx = i;
- srate_best = abs(srates[i] - params_rate(params));
- }
-
- dev_dbg(dai->dev, "Selected SRATE = %d\n", srates[srate_idx]);
- snd_soc_update_bits(codec, WM8983_ADDITIONAL_CONTROL,
- WM8983_SR_MASK, srate_idx << WM8983_SR_SHIFT);
-
- dev_dbg(dai->dev, "Target BCLK = %uHz\n", wm8983->bclk);
- dev_dbg(dai->dev, "SYSCLK = %uHz\n", wm8983->sysclk);
-
- for (i = 0; i < ARRAY_SIZE(fs_ratios); ++i) {
- if (wm8983->sysclk / params_rate(params)
- == fs_ratios[i].ratio)
- break;
- }
-
- if (i == ARRAY_SIZE(fs_ratios)) {
- dev_err(dai->dev, "Unable to configure MCLK ratio %u/%u\n",
- wm8983->sysclk, params_rate(params));
- return -EINVAL;
- }
-
- dev_dbg(dai->dev, "MCLK ratio = %dfs\n", fs_ratios[i].ratio);
- snd_soc_update_bits(codec, WM8983_CLOCK_GEN_CONTROL,
- WM8983_MCLKDIV_MASK, i << WM8983_MCLKDIV_SHIFT);
-
- /* select the appropriate bclk divider */
- tmp = (wm8983->sysclk / fs_ratios[i].div) * 10;
- for (i = 0; i < ARRAY_SIZE(bclk_divs); ++i) {
- if (wm8983->bclk == tmp / bclk_divs[i])
- break;
- }
-
- if (i == ARRAY_SIZE(bclk_divs)) {
- dev_err(dai->dev, "No matching BCLK divider found\n");
- return -EINVAL;
- }
-
- dev_dbg(dai->dev, "BCLK div = %d\n", i);
- snd_soc_update_bits(codec, WM8983_CLOCK_GEN_CONTROL,
- WM8983_BCLKDIV_MASK, i << WM8983_BCLKDIV_SHIFT);
-
- return 0;
-}
-
-struct pll_div {
- u32 div2:1;
- u32 n:4;
- u32 k:24;
-};
-
-#define FIXED_PLL_SIZE ((1ULL << 24) * 10)
-static int pll_factors(struct pll_div *pll_div, unsigned int target,
- unsigned int source)
-{
- u64 Kpart;
- unsigned long int K, Ndiv, Nmod;
-
- pll_div->div2 = 0;
- Ndiv = target / source;
- if (Ndiv < 6) {
- source >>= 1;
- pll_div->div2 = 1;
- Ndiv = target / source;
- }
-
- if (Ndiv < 6 || Ndiv > 12) {
- printk(KERN_ERR "%s: WM8983 N value is not within"
- " the recommended range: %lu\n", __func__, Ndiv);
- return -EINVAL;
- }
- pll_div->n = Ndiv;
-
- Nmod = target % source;
- Kpart = FIXED_PLL_SIZE * (u64)Nmod;
-
- do_div(Kpart, source);
-
- K = Kpart & 0xffffffff;
- if ((K % 10) >= 5)
- K += 5;
- K /= 10;
- pll_div->k = K;
- return 0;
-}
-
-static int wm8983_set_pll(struct snd_soc_dai *dai, int pll_id,
- int source, unsigned int freq_in,
- unsigned int freq_out)
-{
- int ret;
- struct snd_soc_codec *codec;
- struct pll_div pll_div;
-
- codec = dai->codec;
- if (freq_in && freq_out) {
- ret = pll_factors(&pll_div, freq_out * 4 * 2, freq_in);
- if (ret)
- return ret;
- }
-
- /* disable the PLL before re-programming it */
- snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
- WM8983_PLLEN_MASK, 0);
-
- if (!freq_in || !freq_out)
- return 0;
-
- /* set PLLN and PRESCALE */
- snd_soc_write(codec, WM8983_PLL_N,
- (pll_div.div2 << WM8983_PLL_PRESCALE_SHIFT)
- | pll_div.n);
- /* set PLLK */
- snd_soc_write(codec, WM8983_PLL_K_3, pll_div.k & 0x1ff);
- snd_soc_write(codec, WM8983_PLL_K_2, (pll_div.k >> 9) & 0x1ff);
- snd_soc_write(codec, WM8983_PLL_K_1, (pll_div.k >> 18));
- /* enable the PLL */
- snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
- WM8983_PLLEN_MASK, WM8983_PLLEN);
- return 0;
-}
-
-static int wm8983_set_sysclk(struct snd_soc_dai *dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec);
-
- switch (clk_id) {
- case WM8983_CLKSRC_MCLK:
- snd_soc_update_bits(codec, WM8983_CLOCK_GEN_CONTROL,
- WM8983_CLKSEL_MASK, 0);
- break;
- case WM8983_CLKSRC_PLL:
- snd_soc_update_bits(codec, WM8983_CLOCK_GEN_CONTROL,
- WM8983_CLKSEL_MASK, WM8983_CLKSEL);
- break;
- default:
- dev_err(dai->dev, "Unknown clock source: %d\n", clk_id);
- return -EINVAL;
- }
-
- wm8983->sysclk = freq;
- return 0;
-}
-
-static int wm8983_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- int ret;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- case SND_SOC_BIAS_PREPARE:
- /* VMID at 100k */
- snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
- WM8983_VMIDSEL_MASK,
- 1 << WM8983_VMIDSEL_SHIFT);
- break;
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = snd_soc_cache_sync(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
- return ret;
- }
- /* enable anti-pop features */
- snd_soc_update_bits(codec, WM8983_OUT4_TO_ADC,
- WM8983_POBCTRL_MASK | WM8983_DELEN_MASK,
- WM8983_POBCTRL | WM8983_DELEN);
- /* enable thermal shutdown */
- snd_soc_update_bits(codec, WM8983_OUTPUT_CTRL,
- WM8983_TSDEN_MASK, WM8983_TSDEN);
- /* enable BIASEN */
- snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
- WM8983_BIASEN_MASK, WM8983_BIASEN);
- /* VMID at 100k */
- snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
- WM8983_VMIDSEL_MASK,
- 1 << WM8983_VMIDSEL_SHIFT);
- msleep(250);
- /* disable anti-pop features */
- snd_soc_update_bits(codec, WM8983_OUT4_TO_ADC,
- WM8983_POBCTRL_MASK |
- WM8983_DELEN_MASK, 0);
- }
-
- /* VMID at 500k */
- snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
- WM8983_VMIDSEL_MASK,
- 2 << WM8983_VMIDSEL_SHIFT);
- break;
- case SND_SOC_BIAS_OFF:
- /* disable thermal shutdown */
- snd_soc_update_bits(codec, WM8983_OUTPUT_CTRL,
- WM8983_TSDEN_MASK, 0);
- /* disable VMIDSEL and BIASEN */
- snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
- WM8983_VMIDSEL_MASK | WM8983_BIASEN_MASK,
- 0);
- /* wait for VMID to discharge */
- msleep(100);
- snd_soc_write(codec, WM8983_POWER_MANAGEMENT_1, 0);
- snd_soc_write(codec, WM8983_POWER_MANAGEMENT_2, 0);
- snd_soc_write(codec, WM8983_POWER_MANAGEMENT_3, 0);
- break;
- }
-
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int wm8983_suspend(struct snd_soc_codec *codec)
-{
- wm8983_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm8983_resume(struct snd_soc_codec *codec)
-{
- wm8983_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-#else
-#define wm8983_suspend NULL
-#define wm8983_resume NULL
-#endif
-
-static int wm8983_remove(struct snd_soc_codec *codec)
-{
- wm8983_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm8983_probe(struct snd_soc_codec *codec)
-{
- int ret;
- struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec);
- int i;
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8983->control_type);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
- return ret;
- }
-
- ret = snd_soc_write(codec, WM8983_SOFTWARE_RESET, 0);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
- return ret;
- }
-
- /* set the vol/gain update bits */
- for (i = 0; i < ARRAY_SIZE(vol_update_regs); ++i)
- snd_soc_update_bits(codec, vol_update_regs[i],
- 0x100, 0x100);
-
- /* mute all outputs and set PGAs to minimum gain */
- for (i = WM8983_LOUT1_HP_VOLUME_CTRL;
- i <= WM8983_OUT4_MONO_MIX_CTRL; ++i)
- snd_soc_update_bits(codec, i, 0x40, 0x40);
-
- /* enable soft mute */
- snd_soc_update_bits(codec, WM8983_DAC_CONTROL,
- WM8983_SOFTMUTE_MASK,
- WM8983_SOFTMUTE);
-
- /* enable BIASCUT */
- snd_soc_update_bits(codec, WM8983_BIAS_CTRL,
- WM8983_BIASCUT, WM8983_BIASCUT);
- return 0;
-}
-
-static const struct snd_soc_dai_ops wm8983_dai_ops = {
- .digital_mute = wm8983_dac_mute,
- .hw_params = wm8983_hw_params,
- .set_fmt = wm8983_set_fmt,
- .set_sysclk = wm8983_set_sysclk,
- .set_pll = wm8983_set_pll
-};
-
-#define WM8983_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static struct snd_soc_dai_driver wm8983_dai = {
- .name = "wm8983-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = WM8983_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = WM8983_FORMATS,
- },
- .ops = &wm8983_dai_ops,
- .symmetric_rates = 1
-};
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8983 = {
- .probe = wm8983_probe,
- .remove = wm8983_remove,
- .suspend = wm8983_suspend,
- .resume = wm8983_resume,
- .set_bias_level = wm8983_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8983_reg_defs),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8983_reg_defs,
- .controls = wm8983_snd_controls,
- .num_controls = ARRAY_SIZE(wm8983_snd_controls),
- .dapm_widgets = wm8983_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8983_dapm_widgets),
- .dapm_routes = wm8983_audio_map,
- .num_dapm_routes = ARRAY_SIZE(wm8983_audio_map),
- .readable_register = wm8983_readable
-};
-
-#if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8983_spi_probe(struct spi_device *spi)
-{
- struct wm8983_priv *wm8983;
- int ret;
-
- wm8983 = kzalloc(sizeof *wm8983, GFP_KERNEL);
- if (!wm8983)
- return -ENOMEM;
-
- wm8983->control_type = SND_SOC_SPI;
- spi_set_drvdata(spi, wm8983);
-
- ret = snd_soc_register_codec(&spi->dev,
- &soc_codec_dev_wm8983, &wm8983_dai, 1);
- if (ret < 0)
- kfree(wm8983);
- return ret;
-}
-
-static int __devexit wm8983_spi_remove(struct spi_device *spi)
-{
- snd_soc_unregister_codec(&spi->dev);
- kfree(spi_get_drvdata(spi));
- return 0;
-}
-
-static struct spi_driver wm8983_spi_driver = {
- .driver = {
- .name = "wm8983",
- .owner = THIS_MODULE,
- },
- .probe = wm8983_spi_probe,
- .remove = __devexit_p(wm8983_spi_remove)
-};
-#endif
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8983_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8983_priv *wm8983;
- int ret;
-
- wm8983 = kzalloc(sizeof *wm8983, GFP_KERNEL);
- if (!wm8983)
- return -ENOMEM;
-
- wm8983->control_type = SND_SOC_I2C;
- i2c_set_clientdata(i2c, wm8983);
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8983, &wm8983_dai, 1);
- if (ret < 0)
- kfree(wm8983);
- return ret;
-}
-
-static __devexit int wm8983_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-static const struct i2c_device_id wm8983_i2c_id[] = {
- { "wm8983", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8983_i2c_id);
-
-static struct i2c_driver wm8983_i2c_driver = {
- .driver = {
- .name = "wm8983",
- .owner = THIS_MODULE,
- },
- .probe = wm8983_i2c_probe,
- .remove = __devexit_p(wm8983_i2c_remove),
- .id_table = wm8983_i2c_id
-};
-#endif
-
-static int __init wm8983_modinit(void)
-{
- int ret = 0;
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&wm8983_i2c_driver);
- if (ret) {
- printk(KERN_ERR "Failed to register wm8983 I2C driver: %d\n",
- ret);
- }
-#endif
-#if defined(CONFIG_SPI_MASTER)
- ret = spi_register_driver(&wm8983_spi_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8983 SPI driver: %d\n",
- ret);
- }
-#endif
- return ret;
-}
-module_init(wm8983_modinit);
-
-static void __exit wm8983_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&wm8983_i2c_driver);
-#endif
-#if defined(CONFIG_SPI_MASTER)
- spi_unregister_driver(&wm8983_spi_driver);
-#endif
-}
-module_exit(wm8983_exit);
-
-MODULE_DESCRIPTION("ASoC WM8983 driver");
-MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8983.h b/ANDROID_3.4.5/sound/soc/codecs/wm8983.h
deleted file mode 100644
index 71ee619c..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8983.h
+++ /dev/null
@@ -1,1029 +0,0 @@
-/*
- * wm8983.h -- WM8983 ALSA SoC Audio driver
- *
- * Copyright 2011 Wolfson Microelectronics plc
- *
- * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8983_H
-#define _WM8983_H
-
-/*
- * Register values.
- */
-#define WM8983_SOFTWARE_RESET 0x00
-#define WM8983_POWER_MANAGEMENT_1 0x01
-#define WM8983_POWER_MANAGEMENT_2 0x02
-#define WM8983_POWER_MANAGEMENT_3 0x03
-#define WM8983_AUDIO_INTERFACE 0x04
-#define WM8983_COMPANDING_CONTROL 0x05
-#define WM8983_CLOCK_GEN_CONTROL 0x06
-#define WM8983_ADDITIONAL_CONTROL 0x07
-#define WM8983_GPIO_CONTROL 0x08
-#define WM8983_JACK_DETECT_CONTROL_1 0x09
-#define WM8983_DAC_CONTROL 0x0A
-#define WM8983_LEFT_DAC_DIGITAL_VOL 0x0B
-#define WM8983_RIGHT_DAC_DIGITAL_VOL 0x0C
-#define WM8983_JACK_DETECT_CONTROL_2 0x0D
-#define WM8983_ADC_CONTROL 0x0E
-#define WM8983_LEFT_ADC_DIGITAL_VOL 0x0F
-#define WM8983_RIGHT_ADC_DIGITAL_VOL 0x10
-#define WM8983_EQ1_LOW_SHELF 0x12
-#define WM8983_EQ2_PEAK_1 0x13
-#define WM8983_EQ3_PEAK_2 0x14
-#define WM8983_EQ4_PEAK_3 0x15
-#define WM8983_EQ5_HIGH_SHELF 0x16
-#define WM8983_DAC_LIMITER_1 0x18
-#define WM8983_DAC_LIMITER_2 0x19
-#define WM8983_NOTCH_FILTER_1 0x1B
-#define WM8983_NOTCH_FILTER_2 0x1C
-#define WM8983_NOTCH_FILTER_3 0x1D
-#define WM8983_NOTCH_FILTER_4 0x1E
-#define WM8983_ALC_CONTROL_1 0x20
-#define WM8983_ALC_CONTROL_2 0x21
-#define WM8983_ALC_CONTROL_3 0x22
-#define WM8983_NOISE_GATE 0x23
-#define WM8983_PLL_N 0x24
-#define WM8983_PLL_K_1 0x25
-#define WM8983_PLL_K_2 0x26
-#define WM8983_PLL_K_3 0x27
-#define WM8983_3D_CONTROL 0x29
-#define WM8983_OUT4_TO_ADC 0x2A
-#define WM8983_BEEP_CONTROL 0x2B
-#define WM8983_INPUT_CTRL 0x2C
-#define WM8983_LEFT_INP_PGA_GAIN_CTRL 0x2D
-#define WM8983_RIGHT_INP_PGA_GAIN_CTRL 0x2E
-#define WM8983_LEFT_ADC_BOOST_CTRL 0x2F
-#define WM8983_RIGHT_ADC_BOOST_CTRL 0x30
-#define WM8983_OUTPUT_CTRL 0x31
-#define WM8983_LEFT_MIXER_CTRL 0x32
-#define WM8983_RIGHT_MIXER_CTRL 0x33
-#define WM8983_LOUT1_HP_VOLUME_CTRL 0x34
-#define WM8983_ROUT1_HP_VOLUME_CTRL 0x35
-#define WM8983_LOUT2_SPK_VOLUME_CTRL 0x36
-#define WM8983_ROUT2_SPK_VOLUME_CTRL 0x37
-#define WM8983_OUT3_MIXER_CTRL 0x38
-#define WM8983_OUT4_MONO_MIX_CTRL 0x39
-#define WM8983_BIAS_CTRL 0x3D
-
-#define WM8983_REGISTER_COUNT 59
-#define WM8983_MAX_REGISTER 0x3F
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - Software Reset
- */
-#define WM8983_SOFTWARE_RESET_MASK 0x01FF /* SOFTWARE_RESET - [8:0] */
-#define WM8983_SOFTWARE_RESET_SHIFT 0 /* SOFTWARE_RESET - [8:0] */
-#define WM8983_SOFTWARE_RESET_WIDTH 9 /* SOFTWARE_RESET - [8:0] */
-
-/*
- * R1 (0x01) - Power management 1
- */
-#define WM8983_BUFDCOPEN 0x0100 /* BUFDCOPEN */
-#define WM8983_BUFDCOPEN_MASK 0x0100 /* BUFDCOPEN */
-#define WM8983_BUFDCOPEN_SHIFT 8 /* BUFDCOPEN */
-#define WM8983_BUFDCOPEN_WIDTH 1 /* BUFDCOPEN */
-#define WM8983_OUT4MIXEN 0x0080 /* OUT4MIXEN */
-#define WM8983_OUT4MIXEN_MASK 0x0080 /* OUT4MIXEN */
-#define WM8983_OUT4MIXEN_SHIFT 7 /* OUT4MIXEN */
-#define WM8983_OUT4MIXEN_WIDTH 1 /* OUT4MIXEN */
-#define WM8983_OUT3MIXEN 0x0040 /* OUT3MIXEN */
-#define WM8983_OUT3MIXEN_MASK 0x0040 /* OUT3MIXEN */
-#define WM8983_OUT3MIXEN_SHIFT 6 /* OUT3MIXEN */
-#define WM8983_OUT3MIXEN_WIDTH 1 /* OUT3MIXEN */
-#define WM8983_PLLEN 0x0020 /* PLLEN */
-#define WM8983_PLLEN_MASK 0x0020 /* PLLEN */
-#define WM8983_PLLEN_SHIFT 5 /* PLLEN */
-#define WM8983_PLLEN_WIDTH 1 /* PLLEN */
-#define WM8983_MICBEN 0x0010 /* MICBEN */
-#define WM8983_MICBEN_MASK 0x0010 /* MICBEN */
-#define WM8983_MICBEN_SHIFT 4 /* MICBEN */
-#define WM8983_MICBEN_WIDTH 1 /* MICBEN */
-#define WM8983_BIASEN 0x0008 /* BIASEN */
-#define WM8983_BIASEN_MASK 0x0008 /* BIASEN */
-#define WM8983_BIASEN_SHIFT 3 /* BIASEN */
-#define WM8983_BIASEN_WIDTH 1 /* BIASEN */
-#define WM8983_BUFIOEN 0x0004 /* BUFIOEN */
-#define WM8983_BUFIOEN_MASK 0x0004 /* BUFIOEN */
-#define WM8983_BUFIOEN_SHIFT 2 /* BUFIOEN */
-#define WM8983_BUFIOEN_WIDTH 1 /* BUFIOEN */
-#define WM8983_VMIDSEL_MASK 0x0003 /* VMIDSEL - [1:0] */
-#define WM8983_VMIDSEL_SHIFT 0 /* VMIDSEL - [1:0] */
-#define WM8983_VMIDSEL_WIDTH 2 /* VMIDSEL - [1:0] */
-
-/*
- * R2 (0x02) - Power management 2
- */
-#define WM8983_ROUT1EN 0x0100 /* ROUT1EN */
-#define WM8983_ROUT1EN_MASK 0x0100 /* ROUT1EN */
-#define WM8983_ROUT1EN_SHIFT 8 /* ROUT1EN */
-#define WM8983_ROUT1EN_WIDTH 1 /* ROUT1EN */
-#define WM8983_LOUT1EN 0x0080 /* LOUT1EN */
-#define WM8983_LOUT1EN_MASK 0x0080 /* LOUT1EN */
-#define WM8983_LOUT1EN_SHIFT 7 /* LOUT1EN */
-#define WM8983_LOUT1EN_WIDTH 1 /* LOUT1EN */
-#define WM8983_SLEEP 0x0040 /* SLEEP */
-#define WM8983_SLEEP_MASK 0x0040 /* SLEEP */
-#define WM8983_SLEEP_SHIFT 6 /* SLEEP */
-#define WM8983_SLEEP_WIDTH 1 /* SLEEP */
-#define WM8983_BOOSTENR 0x0020 /* BOOSTENR */
-#define WM8983_BOOSTENR_MASK 0x0020 /* BOOSTENR */
-#define WM8983_BOOSTENR_SHIFT 5 /* BOOSTENR */
-#define WM8983_BOOSTENR_WIDTH 1 /* BOOSTENR */
-#define WM8983_BOOSTENL 0x0010 /* BOOSTENL */
-#define WM8983_BOOSTENL_MASK 0x0010 /* BOOSTENL */
-#define WM8983_BOOSTENL_SHIFT 4 /* BOOSTENL */
-#define WM8983_BOOSTENL_WIDTH 1 /* BOOSTENL */
-#define WM8983_INPGAENR 0x0008 /* INPGAENR */
-#define WM8983_INPGAENR_MASK 0x0008 /* INPGAENR */
-#define WM8983_INPGAENR_SHIFT 3 /* INPGAENR */
-#define WM8983_INPGAENR_WIDTH 1 /* INPGAENR */
-#define WM8983_INPPGAENL 0x0004 /* INPPGAENL */
-#define WM8983_INPPGAENL_MASK 0x0004 /* INPPGAENL */
-#define WM8983_INPPGAENL_SHIFT 2 /* INPPGAENL */
-#define WM8983_INPPGAENL_WIDTH 1 /* INPPGAENL */
-#define WM8983_ADCENR 0x0002 /* ADCENR */
-#define WM8983_ADCENR_MASK 0x0002 /* ADCENR */
-#define WM8983_ADCENR_SHIFT 1 /* ADCENR */
-#define WM8983_ADCENR_WIDTH 1 /* ADCENR */
-#define WM8983_ADCENL 0x0001 /* ADCENL */
-#define WM8983_ADCENL_MASK 0x0001 /* ADCENL */
-#define WM8983_ADCENL_SHIFT 0 /* ADCENL */
-#define WM8983_ADCENL_WIDTH 1 /* ADCENL */
-
-/*
- * R3 (0x03) - Power management 3
- */
-#define WM8983_OUT4EN 0x0100 /* OUT4EN */
-#define WM8983_OUT4EN_MASK 0x0100 /* OUT4EN */
-#define WM8983_OUT4EN_SHIFT 8 /* OUT4EN */
-#define WM8983_OUT4EN_WIDTH 1 /* OUT4EN */
-#define WM8983_OUT3EN 0x0080 /* OUT3EN */
-#define WM8983_OUT3EN_MASK 0x0080 /* OUT3EN */
-#define WM8983_OUT3EN_SHIFT 7 /* OUT3EN */
-#define WM8983_OUT3EN_WIDTH 1 /* OUT3EN */
-#define WM8983_LOUT2EN 0x0040 /* LOUT2EN */
-#define WM8983_LOUT2EN_MASK 0x0040 /* LOUT2EN */
-#define WM8983_LOUT2EN_SHIFT 6 /* LOUT2EN */
-#define WM8983_LOUT2EN_WIDTH 1 /* LOUT2EN */
-#define WM8983_ROUT2EN 0x0020 /* ROUT2EN */
-#define WM8983_ROUT2EN_MASK 0x0020 /* ROUT2EN */
-#define WM8983_ROUT2EN_SHIFT 5 /* ROUT2EN */
-#define WM8983_ROUT2EN_WIDTH 1 /* ROUT2EN */
-#define WM8983_RMIXEN 0x0008 /* RMIXEN */
-#define WM8983_RMIXEN_MASK 0x0008 /* RMIXEN */
-#define WM8983_RMIXEN_SHIFT 3 /* RMIXEN */
-#define WM8983_RMIXEN_WIDTH 1 /* RMIXEN */
-#define WM8983_LMIXEN 0x0004 /* LMIXEN */
-#define WM8983_LMIXEN_MASK 0x0004 /* LMIXEN */
-#define WM8983_LMIXEN_SHIFT 2 /* LMIXEN */
-#define WM8983_LMIXEN_WIDTH 1 /* LMIXEN */
-#define WM8983_DACENR 0x0002 /* DACENR */
-#define WM8983_DACENR_MASK 0x0002 /* DACENR */
-#define WM8983_DACENR_SHIFT 1 /* DACENR */
-#define WM8983_DACENR_WIDTH 1 /* DACENR */
-#define WM8983_DACENL 0x0001 /* DACENL */
-#define WM8983_DACENL_MASK 0x0001 /* DACENL */
-#define WM8983_DACENL_SHIFT 0 /* DACENL */
-#define WM8983_DACENL_WIDTH 1 /* DACENL */
-
-/*
- * R4 (0x04) - Audio Interface
- */
-#define WM8983_BCP 0x0100 /* BCP */
-#define WM8983_BCP_MASK 0x0100 /* BCP */
-#define WM8983_BCP_SHIFT 8 /* BCP */
-#define WM8983_BCP_WIDTH 1 /* BCP */
-#define WM8983_LRCP 0x0080 /* LRCP */
-#define WM8983_LRCP_MASK 0x0080 /* LRCP */
-#define WM8983_LRCP_SHIFT 7 /* LRCP */
-#define WM8983_LRCP_WIDTH 1 /* LRCP */
-#define WM8983_WL_MASK 0x0060 /* WL - [6:5] */
-#define WM8983_WL_SHIFT 5 /* WL - [6:5] */
-#define WM8983_WL_WIDTH 2 /* WL - [6:5] */
-#define WM8983_FMT_MASK 0x0018 /* FMT - [4:3] */
-#define WM8983_FMT_SHIFT 3 /* FMT - [4:3] */
-#define WM8983_FMT_WIDTH 2 /* FMT - [4:3] */
-#define WM8983_DLRSWAP 0x0004 /* DLRSWAP */
-#define WM8983_DLRSWAP_MASK 0x0004 /* DLRSWAP */
-#define WM8983_DLRSWAP_SHIFT 2 /* DLRSWAP */
-#define WM8983_DLRSWAP_WIDTH 1 /* DLRSWAP */
-#define WM8983_ALRSWAP 0x0002 /* ALRSWAP */
-#define WM8983_ALRSWAP_MASK 0x0002 /* ALRSWAP */
-#define WM8983_ALRSWAP_SHIFT 1 /* ALRSWAP */
-#define WM8983_ALRSWAP_WIDTH 1 /* ALRSWAP */
-#define WM8983_MONO 0x0001 /* MONO */
-#define WM8983_MONO_MASK 0x0001 /* MONO */
-#define WM8983_MONO_SHIFT 0 /* MONO */
-#define WM8983_MONO_WIDTH 1 /* MONO */
-
-/*
- * R5 (0x05) - Companding control
- */
-#define WM8983_WL8 0x0020 /* WL8 */
-#define WM8983_WL8_MASK 0x0020 /* WL8 */
-#define WM8983_WL8_SHIFT 5 /* WL8 */
-#define WM8983_WL8_WIDTH 1 /* WL8 */
-#define WM8983_DAC_COMP_MASK 0x0018 /* DAC_COMP - [4:3] */
-#define WM8983_DAC_COMP_SHIFT 3 /* DAC_COMP - [4:3] */
-#define WM8983_DAC_COMP_WIDTH 2 /* DAC_COMP - [4:3] */
-#define WM8983_ADC_COMP_MASK 0x0006 /* ADC_COMP - [2:1] */
-#define WM8983_ADC_COMP_SHIFT 1 /* ADC_COMP - [2:1] */
-#define WM8983_ADC_COMP_WIDTH 2 /* ADC_COMP - [2:1] */
-#define WM8983_LOOPBACK 0x0001 /* LOOPBACK */
-#define WM8983_LOOPBACK_MASK 0x0001 /* LOOPBACK */
-#define WM8983_LOOPBACK_SHIFT 0 /* LOOPBACK */
-#define WM8983_LOOPBACK_WIDTH 1 /* LOOPBACK */
-
-/*
- * R6 (0x06) - Clock Gen control
- */
-#define WM8983_CLKSEL 0x0100 /* CLKSEL */
-#define WM8983_CLKSEL_MASK 0x0100 /* CLKSEL */
-#define WM8983_CLKSEL_SHIFT 8 /* CLKSEL */
-#define WM8983_CLKSEL_WIDTH 1 /* CLKSEL */
-#define WM8983_MCLKDIV_MASK 0x00E0 /* MCLKDIV - [7:5] */
-#define WM8983_MCLKDIV_SHIFT 5 /* MCLKDIV - [7:5] */
-#define WM8983_MCLKDIV_WIDTH 3 /* MCLKDIV - [7:5] */
-#define WM8983_BCLKDIV_MASK 0x001C /* BCLKDIV - [4:2] */
-#define WM8983_BCLKDIV_SHIFT 2 /* BCLKDIV - [4:2] */
-#define WM8983_BCLKDIV_WIDTH 3 /* BCLKDIV - [4:2] */
-#define WM8983_MS 0x0001 /* MS */
-#define WM8983_MS_MASK 0x0001 /* MS */
-#define WM8983_MS_SHIFT 0 /* MS */
-#define WM8983_MS_WIDTH 1 /* MS */
-
-/*
- * R7 (0x07) - Additional control
- */
-#define WM8983_SR_MASK 0x000E /* SR - [3:1] */
-#define WM8983_SR_SHIFT 1 /* SR - [3:1] */
-#define WM8983_SR_WIDTH 3 /* SR - [3:1] */
-#define WM8983_SLOWCLKEN 0x0001 /* SLOWCLKEN */
-#define WM8983_SLOWCLKEN_MASK 0x0001 /* SLOWCLKEN */
-#define WM8983_SLOWCLKEN_SHIFT 0 /* SLOWCLKEN */
-#define WM8983_SLOWCLKEN_WIDTH 1 /* SLOWCLKEN */
-
-/*
- * R8 (0x08) - GPIO Control
- */
-#define WM8983_OPCLKDIV_MASK 0x0030 /* OPCLKDIV - [5:4] */
-#define WM8983_OPCLKDIV_SHIFT 4 /* OPCLKDIV - [5:4] */
-#define WM8983_OPCLKDIV_WIDTH 2 /* OPCLKDIV - [5:4] */
-#define WM8983_GPIO1POL 0x0008 /* GPIO1POL */
-#define WM8983_GPIO1POL_MASK 0x0008 /* GPIO1POL */
-#define WM8983_GPIO1POL_SHIFT 3 /* GPIO1POL */
-#define WM8983_GPIO1POL_WIDTH 1 /* GPIO1POL */
-#define WM8983_GPIO1SEL_MASK 0x0007 /* GPIO1SEL - [2:0] */
-#define WM8983_GPIO1SEL_SHIFT 0 /* GPIO1SEL - [2:0] */
-#define WM8983_GPIO1SEL_WIDTH 3 /* GPIO1SEL - [2:0] */
-
-/*
- * R9 (0x09) - Jack Detect Control 1
- */
-#define WM8983_JD_VMID1 0x0100 /* JD_VMID1 */
-#define WM8983_JD_VMID1_MASK 0x0100 /* JD_VMID1 */
-#define WM8983_JD_VMID1_SHIFT 8 /* JD_VMID1 */
-#define WM8983_JD_VMID1_WIDTH 1 /* JD_VMID1 */
-#define WM8983_JD_VMID0 0x0080 /* JD_VMID0 */
-#define WM8983_JD_VMID0_MASK 0x0080 /* JD_VMID0 */
-#define WM8983_JD_VMID0_SHIFT 7 /* JD_VMID0 */
-#define WM8983_JD_VMID0_WIDTH 1 /* JD_VMID0 */
-#define WM8983_JD_EN 0x0040 /* JD_EN */
-#define WM8983_JD_EN_MASK 0x0040 /* JD_EN */
-#define WM8983_JD_EN_SHIFT 6 /* JD_EN */
-#define WM8983_JD_EN_WIDTH 1 /* JD_EN */
-#define WM8983_JD_SEL_MASK 0x0030 /* JD_SEL - [5:4] */
-#define WM8983_JD_SEL_SHIFT 4 /* JD_SEL - [5:4] */
-#define WM8983_JD_SEL_WIDTH 2 /* JD_SEL - [5:4] */
-
-/*
- * R10 (0x0A) - DAC Control
- */
-#define WM8983_SOFTMUTE 0x0040 /* SOFTMUTE */
-#define WM8983_SOFTMUTE_MASK 0x0040 /* SOFTMUTE */
-#define WM8983_SOFTMUTE_SHIFT 6 /* SOFTMUTE */
-#define WM8983_SOFTMUTE_WIDTH 1 /* SOFTMUTE */
-#define WM8983_DACOSR128 0x0008 /* DACOSR128 */
-#define WM8983_DACOSR128_MASK 0x0008 /* DACOSR128 */
-#define WM8983_DACOSR128_SHIFT 3 /* DACOSR128 */
-#define WM8983_DACOSR128_WIDTH 1 /* DACOSR128 */
-#define WM8983_AMUTE 0x0004 /* AMUTE */
-#define WM8983_AMUTE_MASK 0x0004 /* AMUTE */
-#define WM8983_AMUTE_SHIFT 2 /* AMUTE */
-#define WM8983_AMUTE_WIDTH 1 /* AMUTE */
-#define WM8983_DACRPOL 0x0002 /* DACRPOL */
-#define WM8983_DACRPOL_MASK 0x0002 /* DACRPOL */
-#define WM8983_DACRPOL_SHIFT 1 /* DACRPOL */
-#define WM8983_DACRPOL_WIDTH 1 /* DACRPOL */
-#define WM8983_DACLPOL 0x0001 /* DACLPOL */
-#define WM8983_DACLPOL_MASK 0x0001 /* DACLPOL */
-#define WM8983_DACLPOL_SHIFT 0 /* DACLPOL */
-#define WM8983_DACLPOL_WIDTH 1 /* DACLPOL */
-
-/*
- * R11 (0x0B) - Left DAC digital Vol
- */
-#define WM8983_DACVU 0x0100 /* DACVU */
-#define WM8983_DACVU_MASK 0x0100 /* DACVU */
-#define WM8983_DACVU_SHIFT 8 /* DACVU */
-#define WM8983_DACVU_WIDTH 1 /* DACVU */
-#define WM8983_DACLVOL_MASK 0x00FF /* DACLVOL - [7:0] */
-#define WM8983_DACLVOL_SHIFT 0 /* DACLVOL - [7:0] */
-#define WM8983_DACLVOL_WIDTH 8 /* DACLVOL - [7:0] */
-
-/*
- * R12 (0x0C) - Right DAC digital vol
- */
-#define WM8983_DACVU 0x0100 /* DACVU */
-#define WM8983_DACVU_MASK 0x0100 /* DACVU */
-#define WM8983_DACVU_SHIFT 8 /* DACVU */
-#define WM8983_DACVU_WIDTH 1 /* DACVU */
-#define WM8983_DACRVOL_MASK 0x00FF /* DACRVOL - [7:0] */
-#define WM8983_DACRVOL_SHIFT 0 /* DACRVOL - [7:0] */
-#define WM8983_DACRVOL_WIDTH 8 /* DACRVOL - [7:0] */
-
-/*
- * R13 (0x0D) - Jack Detect Control 2
- */
-#define WM8983_JD_EN1_MASK 0x00F0 /* JD_EN1 - [7:4] */
-#define WM8983_JD_EN1_SHIFT 4 /* JD_EN1 - [7:4] */
-#define WM8983_JD_EN1_WIDTH 4 /* JD_EN1 - [7:4] */
-#define WM8983_JD_EN0_MASK 0x000F /* JD_EN0 - [3:0] */
-#define WM8983_JD_EN0_SHIFT 0 /* JD_EN0 - [3:0] */
-#define WM8983_JD_EN0_WIDTH 4 /* JD_EN0 - [3:0] */
-
-/*
- * R14 (0x0E) - ADC Control
- */
-#define WM8983_HPFEN 0x0100 /* HPFEN */
-#define WM8983_HPFEN_MASK 0x0100 /* HPFEN */
-#define WM8983_HPFEN_SHIFT 8 /* HPFEN */
-#define WM8983_HPFEN_WIDTH 1 /* HPFEN */
-#define WM8983_HPFAPP 0x0080 /* HPFAPP */
-#define WM8983_HPFAPP_MASK 0x0080 /* HPFAPP */
-#define WM8983_HPFAPP_SHIFT 7 /* HPFAPP */
-#define WM8983_HPFAPP_WIDTH 1 /* HPFAPP */
-#define WM8983_HPFCUT_MASK 0x0070 /* HPFCUT - [6:4] */
-#define WM8983_HPFCUT_SHIFT 4 /* HPFCUT - [6:4] */
-#define WM8983_HPFCUT_WIDTH 3 /* HPFCUT - [6:4] */
-#define WM8983_ADCOSR128 0x0008 /* ADCOSR128 */
-#define WM8983_ADCOSR128_MASK 0x0008 /* ADCOSR128 */
-#define WM8983_ADCOSR128_SHIFT 3 /* ADCOSR128 */
-#define WM8983_ADCOSR128_WIDTH 1 /* ADCOSR128 */
-#define WM8983_ADCRPOL 0x0002 /* ADCRPOL */
-#define WM8983_ADCRPOL_MASK 0x0002 /* ADCRPOL */
-#define WM8983_ADCRPOL_SHIFT 1 /* ADCRPOL */
-#define WM8983_ADCRPOL_WIDTH 1 /* ADCRPOL */
-#define WM8983_ADCLPOL 0x0001 /* ADCLPOL */
-#define WM8983_ADCLPOL_MASK 0x0001 /* ADCLPOL */
-#define WM8983_ADCLPOL_SHIFT 0 /* ADCLPOL */
-#define WM8983_ADCLPOL_WIDTH 1 /* ADCLPOL */
-
-/*
- * R15 (0x0F) - Left ADC Digital Vol
- */
-#define WM8983_ADCVU 0x0100 /* ADCVU */
-#define WM8983_ADCVU_MASK 0x0100 /* ADCVU */
-#define WM8983_ADCVU_SHIFT 8 /* ADCVU */
-#define WM8983_ADCVU_WIDTH 1 /* ADCVU */
-#define WM8983_ADCLVOL_MASK 0x00FF /* ADCLVOL - [7:0] */
-#define WM8983_ADCLVOL_SHIFT 0 /* ADCLVOL - [7:0] */
-#define WM8983_ADCLVOL_WIDTH 8 /* ADCLVOL - [7:0] */
-
-/*
- * R16 (0x10) - Right ADC Digital Vol
- */
-#define WM8983_ADCVU 0x0100 /* ADCVU */
-#define WM8983_ADCVU_MASK 0x0100 /* ADCVU */
-#define WM8983_ADCVU_SHIFT 8 /* ADCVU */
-#define WM8983_ADCVU_WIDTH 1 /* ADCVU */
-#define WM8983_ADCRVOL_MASK 0x00FF /* ADCRVOL - [7:0] */
-#define WM8983_ADCRVOL_SHIFT 0 /* ADCRVOL - [7:0] */
-#define WM8983_ADCRVOL_WIDTH 8 /* ADCRVOL - [7:0] */
-
-/*
- * R18 (0x12) - EQ1 - low shelf
- */
-#define WM8983_EQ3DMODE 0x0100 /* EQ3DMODE */
-#define WM8983_EQ3DMODE_MASK 0x0100 /* EQ3DMODE */
-#define WM8983_EQ3DMODE_SHIFT 8 /* EQ3DMODE */
-#define WM8983_EQ3DMODE_WIDTH 1 /* EQ3DMODE */
-#define WM8983_EQ1C_MASK 0x0060 /* EQ1C - [6:5] */
-#define WM8983_EQ1C_SHIFT 5 /* EQ1C - [6:5] */
-#define WM8983_EQ1C_WIDTH 2 /* EQ1C - [6:5] */
-#define WM8983_EQ1G_MASK 0x001F /* EQ1G - [4:0] */
-#define WM8983_EQ1G_SHIFT 0 /* EQ1G - [4:0] */
-#define WM8983_EQ1G_WIDTH 5 /* EQ1G - [4:0] */
-
-/*
- * R19 (0x13) - EQ2 - peak 1
- */
-#define WM8983_EQ2BW 0x0100 /* EQ2BW */
-#define WM8983_EQ2BW_MASK 0x0100 /* EQ2BW */
-#define WM8983_EQ2BW_SHIFT 8 /* EQ2BW */
-#define WM8983_EQ2BW_WIDTH 1 /* EQ2BW */
-#define WM8983_EQ2C_MASK 0x0060 /* EQ2C - [6:5] */
-#define WM8983_EQ2C_SHIFT 5 /* EQ2C - [6:5] */
-#define WM8983_EQ2C_WIDTH 2 /* EQ2C - [6:5] */
-#define WM8983_EQ2G_MASK 0x001F /* EQ2G - [4:0] */
-#define WM8983_EQ2G_SHIFT 0 /* EQ2G - [4:0] */
-#define WM8983_EQ2G_WIDTH 5 /* EQ2G - [4:0] */
-
-/*
- * R20 (0x14) - EQ3 - peak 2
- */
-#define WM8983_EQ3BW 0x0100 /* EQ3BW */
-#define WM8983_EQ3BW_MASK 0x0100 /* EQ3BW */
-#define WM8983_EQ3BW_SHIFT 8 /* EQ3BW */
-#define WM8983_EQ3BW_WIDTH 1 /* EQ3BW */
-#define WM8983_EQ3C_MASK 0x0060 /* EQ3C - [6:5] */
-#define WM8983_EQ3C_SHIFT 5 /* EQ3C - [6:5] */
-#define WM8983_EQ3C_WIDTH 2 /* EQ3C - [6:5] */
-#define WM8983_EQ3G_MASK 0x001F /* EQ3G - [4:0] */
-#define WM8983_EQ3G_SHIFT 0 /* EQ3G - [4:0] */
-#define WM8983_EQ3G_WIDTH 5 /* EQ3G - [4:0] */
-
-/*
- * R21 (0x15) - EQ4 - peak 3
- */
-#define WM8983_EQ4BW 0x0100 /* EQ4BW */
-#define WM8983_EQ4BW_MASK 0x0100 /* EQ4BW */
-#define WM8983_EQ4BW_SHIFT 8 /* EQ4BW */
-#define WM8983_EQ4BW_WIDTH 1 /* EQ4BW */
-#define WM8983_EQ4C_MASK 0x0060 /* EQ4C - [6:5] */
-#define WM8983_EQ4C_SHIFT 5 /* EQ4C - [6:5] */
-#define WM8983_EQ4C_WIDTH 2 /* EQ4C - [6:5] */
-#define WM8983_EQ4G_MASK 0x001F /* EQ4G - [4:0] */
-#define WM8983_EQ4G_SHIFT 0 /* EQ4G - [4:0] */
-#define WM8983_EQ4G_WIDTH 5 /* EQ4G - [4:0] */
-
-/*
- * R22 (0x16) - EQ5 - high shelf
- */
-#define WM8983_EQ5C_MASK 0x0060 /* EQ5C - [6:5] */
-#define WM8983_EQ5C_SHIFT 5 /* EQ5C - [6:5] */
-#define WM8983_EQ5C_WIDTH 2 /* EQ5C - [6:5] */
-#define WM8983_EQ5G_MASK 0x001F /* EQ5G - [4:0] */
-#define WM8983_EQ5G_SHIFT 0 /* EQ5G - [4:0] */
-#define WM8983_EQ5G_WIDTH 5 /* EQ5G - [4:0] */
-
-/*
- * R24 (0x18) - DAC Limiter 1
- */
-#define WM8983_LIMEN 0x0100 /* LIMEN */
-#define WM8983_LIMEN_MASK 0x0100 /* LIMEN */
-#define WM8983_LIMEN_SHIFT 8 /* LIMEN */
-#define WM8983_LIMEN_WIDTH 1 /* LIMEN */
-#define WM8983_LIMDCY_MASK 0x00F0 /* LIMDCY - [7:4] */
-#define WM8983_LIMDCY_SHIFT 4 /* LIMDCY - [7:4] */
-#define WM8983_LIMDCY_WIDTH 4 /* LIMDCY - [7:4] */
-#define WM8983_LIMATK_MASK 0x000F /* LIMATK - [3:0] */
-#define WM8983_LIMATK_SHIFT 0 /* LIMATK - [3:0] */
-#define WM8983_LIMATK_WIDTH 4 /* LIMATK - [3:0] */
-
-/*
- * R25 (0x19) - DAC Limiter 2
- */
-#define WM8983_LIMLVL_MASK 0x0070 /* LIMLVL - [6:4] */
-#define WM8983_LIMLVL_SHIFT 4 /* LIMLVL - [6:4] */
-#define WM8983_LIMLVL_WIDTH 3 /* LIMLVL - [6:4] */
-#define WM8983_LIMBOOST_MASK 0x000F /* LIMBOOST - [3:0] */
-#define WM8983_LIMBOOST_SHIFT 0 /* LIMBOOST - [3:0] */
-#define WM8983_LIMBOOST_WIDTH 4 /* LIMBOOST - [3:0] */
-
-/*
- * R27 (0x1B) - Notch Filter 1
- */
-#define WM8983_NFU 0x0100 /* NFU */
-#define WM8983_NFU_MASK 0x0100 /* NFU */
-#define WM8983_NFU_SHIFT 8 /* NFU */
-#define WM8983_NFU_WIDTH 1 /* NFU */
-#define WM8983_NFEN 0x0080 /* NFEN */
-#define WM8983_NFEN_MASK 0x0080 /* NFEN */
-#define WM8983_NFEN_SHIFT 7 /* NFEN */
-#define WM8983_NFEN_WIDTH 1 /* NFEN */
-#define WM8983_NFA0_13_7_MASK 0x007F /* NFA0(13:7) - [6:0] */
-#define WM8983_NFA0_13_7_SHIFT 0 /* NFA0(13:7) - [6:0] */
-#define WM8983_NFA0_13_7_WIDTH 7 /* NFA0(13:7) - [6:0] */
-
-/*
- * R28 (0x1C) - Notch Filter 2
- */
-#define WM8983_NFU 0x0100 /* NFU */
-#define WM8983_NFU_MASK 0x0100 /* NFU */
-#define WM8983_NFU_SHIFT 8 /* NFU */
-#define WM8983_NFU_WIDTH 1 /* NFU */
-#define WM8983_NFA0_6_0_MASK 0x007F /* NFA0(6:0) - [6:0] */
-#define WM8983_NFA0_6_0_SHIFT 0 /* NFA0(6:0) - [6:0] */
-#define WM8983_NFA0_6_0_WIDTH 7 /* NFA0(6:0) - [6:0] */
-
-/*
- * R29 (0x1D) - Notch Filter 3
- */
-#define WM8983_NFU 0x0100 /* NFU */
-#define WM8983_NFU_MASK 0x0100 /* NFU */
-#define WM8983_NFU_SHIFT 8 /* NFU */
-#define WM8983_NFU_WIDTH 1 /* NFU */
-#define WM8983_NFA1_13_7_MASK 0x007F /* NFA1(13:7) - [6:0] */
-#define WM8983_NFA1_13_7_SHIFT 0 /* NFA1(13:7) - [6:0] */
-#define WM8983_NFA1_13_7_WIDTH 7 /* NFA1(13:7) - [6:0] */
-
-/*
- * R30 (0x1E) - Notch Filter 4
- */
-#define WM8983_NFU 0x0100 /* NFU */
-#define WM8983_NFU_MASK 0x0100 /* NFU */
-#define WM8983_NFU_SHIFT 8 /* NFU */
-#define WM8983_NFU_WIDTH 1 /* NFU */
-#define WM8983_NFA1_6_0_MASK 0x007F /* NFA1(6:0) - [6:0] */
-#define WM8983_NFA1_6_0_SHIFT 0 /* NFA1(6:0) - [6:0] */
-#define WM8983_NFA1_6_0_WIDTH 7 /* NFA1(6:0) - [6:0] */
-
-/*
- * R32 (0x20) - ALC control 1
- */
-#define WM8983_ALCSEL_MASK 0x0180 /* ALCSEL - [8:7] */
-#define WM8983_ALCSEL_SHIFT 7 /* ALCSEL - [8:7] */
-#define WM8983_ALCSEL_WIDTH 2 /* ALCSEL - [8:7] */
-#define WM8983_ALCMAX_MASK 0x0038 /* ALCMAX - [5:3] */
-#define WM8983_ALCMAX_SHIFT 3 /* ALCMAX - [5:3] */
-#define WM8983_ALCMAX_WIDTH 3 /* ALCMAX - [5:3] */
-#define WM8983_ALCMIN_MASK 0x0007 /* ALCMIN - [2:0] */
-#define WM8983_ALCMIN_SHIFT 0 /* ALCMIN - [2:0] */
-#define WM8983_ALCMIN_WIDTH 3 /* ALCMIN - [2:0] */
-
-/*
- * R33 (0x21) - ALC control 2
- */
-#define WM8983_ALCHLD_MASK 0x00F0 /* ALCHLD - [7:4] */
-#define WM8983_ALCHLD_SHIFT 4 /* ALCHLD - [7:4] */
-#define WM8983_ALCHLD_WIDTH 4 /* ALCHLD - [7:4] */
-#define WM8983_ALCLVL_MASK 0x000F /* ALCLVL - [3:0] */
-#define WM8983_ALCLVL_SHIFT 0 /* ALCLVL - [3:0] */
-#define WM8983_ALCLVL_WIDTH 4 /* ALCLVL - [3:0] */
-
-/*
- * R34 (0x22) - ALC control 3
- */
-#define WM8983_ALCMODE 0x0100 /* ALCMODE */
-#define WM8983_ALCMODE_MASK 0x0100 /* ALCMODE */
-#define WM8983_ALCMODE_SHIFT 8 /* ALCMODE */
-#define WM8983_ALCMODE_WIDTH 1 /* ALCMODE */
-#define WM8983_ALCDCY_MASK 0x00F0 /* ALCDCY - [7:4] */
-#define WM8983_ALCDCY_SHIFT 4 /* ALCDCY - [7:4] */
-#define WM8983_ALCDCY_WIDTH 4 /* ALCDCY - [7:4] */
-#define WM8983_ALCATK_MASK 0x000F /* ALCATK - [3:0] */
-#define WM8983_ALCATK_SHIFT 0 /* ALCATK - [3:0] */
-#define WM8983_ALCATK_WIDTH 4 /* ALCATK - [3:0] */
-
-/*
- * R35 (0x23) - Noise Gate
- */
-#define WM8983_NGEN 0x0008 /* NGEN */
-#define WM8983_NGEN_MASK 0x0008 /* NGEN */
-#define WM8983_NGEN_SHIFT 3 /* NGEN */
-#define WM8983_NGEN_WIDTH 1 /* NGEN */
-#define WM8983_NGTH_MASK 0x0007 /* NGTH - [2:0] */
-#define WM8983_NGTH_SHIFT 0 /* NGTH - [2:0] */
-#define WM8983_NGTH_WIDTH 3 /* NGTH - [2:0] */
-
-/*
- * R36 (0x24) - PLL N
- */
-#define WM8983_PLL_PRESCALE 0x0010 /* PLL_PRESCALE */
-#define WM8983_PLL_PRESCALE_MASK 0x0010 /* PLL_PRESCALE */
-#define WM8983_PLL_PRESCALE_SHIFT 4 /* PLL_PRESCALE */
-#define WM8983_PLL_PRESCALE_WIDTH 1 /* PLL_PRESCALE */
-#define WM8983_PLLN_MASK 0x000F /* PLLN - [3:0] */
-#define WM8983_PLLN_SHIFT 0 /* PLLN - [3:0] */
-#define WM8983_PLLN_WIDTH 4 /* PLLN - [3:0] */
-
-/*
- * R37 (0x25) - PLL K 1
- */
-#define WM8983_PLLK_23_18_MASK 0x003F /* PLLK(23:18) - [5:0] */
-#define WM8983_PLLK_23_18_SHIFT 0 /* PLLK(23:18) - [5:0] */
-#define WM8983_PLLK_23_18_WIDTH 6 /* PLLK(23:18) - [5:0] */
-
-/*
- * R38 (0x26) - PLL K 2
- */
-#define WM8983_PLLK_17_9_MASK 0x01FF /* PLLK(17:9) - [8:0] */
-#define WM8983_PLLK_17_9_SHIFT 0 /* PLLK(17:9) - [8:0] */
-#define WM8983_PLLK_17_9_WIDTH 9 /* PLLK(17:9) - [8:0] */
-
-/*
- * R39 (0x27) - PLL K 3
- */
-#define WM8983_PLLK_8_0_MASK 0x01FF /* PLLK(8:0) - [8:0] */
-#define WM8983_PLLK_8_0_SHIFT 0 /* PLLK(8:0) - [8:0] */
-#define WM8983_PLLK_8_0_WIDTH 9 /* PLLK(8:0) - [8:0] */
-
-/*
- * R41 (0x29) - 3D control
- */
-#define WM8983_DEPTH3D_MASK 0x000F /* DEPTH3D - [3:0] */
-#define WM8983_DEPTH3D_SHIFT 0 /* DEPTH3D - [3:0] */
-#define WM8983_DEPTH3D_WIDTH 4 /* DEPTH3D - [3:0] */
-
-/*
- * R42 (0x2A) - OUT4 to ADC
- */
-#define WM8983_OUT4_2ADCVOL_MASK 0x01C0 /* OUT4_2ADCVOL - [8:6] */
-#define WM8983_OUT4_2ADCVOL_SHIFT 6 /* OUT4_2ADCVOL - [8:6] */
-#define WM8983_OUT4_2ADCVOL_WIDTH 3 /* OUT4_2ADCVOL - [8:6] */
-#define WM8983_OUT4_2LNR 0x0020 /* OUT4_2LNR */
-#define WM8983_OUT4_2LNR_MASK 0x0020 /* OUT4_2LNR */
-#define WM8983_OUT4_2LNR_SHIFT 5 /* OUT4_2LNR */
-#define WM8983_OUT4_2LNR_WIDTH 1 /* OUT4_2LNR */
-#define WM8983_POBCTRL 0x0004 /* POBCTRL */
-#define WM8983_POBCTRL_MASK 0x0004 /* POBCTRL */
-#define WM8983_POBCTRL_SHIFT 2 /* POBCTRL */
-#define WM8983_POBCTRL_WIDTH 1 /* POBCTRL */
-#define WM8983_DELEN 0x0002 /* DELEN */
-#define WM8983_DELEN_MASK 0x0002 /* DELEN */
-#define WM8983_DELEN_SHIFT 1 /* DELEN */
-#define WM8983_DELEN_WIDTH 1 /* DELEN */
-#define WM8983_OUT1DEL 0x0001 /* OUT1DEL */
-#define WM8983_OUT1DEL_MASK 0x0001 /* OUT1DEL */
-#define WM8983_OUT1DEL_SHIFT 0 /* OUT1DEL */
-#define WM8983_OUT1DEL_WIDTH 1 /* OUT1DEL */
-
-/*
- * R43 (0x2B) - Beep control
- */
-#define WM8983_BYPL2RMIX 0x0100 /* BYPL2RMIX */
-#define WM8983_BYPL2RMIX_MASK 0x0100 /* BYPL2RMIX */
-#define WM8983_BYPL2RMIX_SHIFT 8 /* BYPL2RMIX */
-#define WM8983_BYPL2RMIX_WIDTH 1 /* BYPL2RMIX */
-#define WM8983_BYPR2LMIX 0x0080 /* BYPR2LMIX */
-#define WM8983_BYPR2LMIX_MASK 0x0080 /* BYPR2LMIX */
-#define WM8983_BYPR2LMIX_SHIFT 7 /* BYPR2LMIX */
-#define WM8983_BYPR2LMIX_WIDTH 1 /* BYPR2LMIX */
-#define WM8983_MUTERPGA2INV 0x0020 /* MUTERPGA2INV */
-#define WM8983_MUTERPGA2INV_MASK 0x0020 /* MUTERPGA2INV */
-#define WM8983_MUTERPGA2INV_SHIFT 5 /* MUTERPGA2INV */
-#define WM8983_MUTERPGA2INV_WIDTH 1 /* MUTERPGA2INV */
-#define WM8983_INVROUT2 0x0010 /* INVROUT2 */
-#define WM8983_INVROUT2_MASK 0x0010 /* INVROUT2 */
-#define WM8983_INVROUT2_SHIFT 4 /* INVROUT2 */
-#define WM8983_INVROUT2_WIDTH 1 /* INVROUT2 */
-#define WM8983_BEEPVOL_MASK 0x000E /* BEEPVOL - [3:1] */
-#define WM8983_BEEPVOL_SHIFT 1 /* BEEPVOL - [3:1] */
-#define WM8983_BEEPVOL_WIDTH 3 /* BEEPVOL - [3:1] */
-#define WM8983_BEEPEN 0x0001 /* BEEPEN */
-#define WM8983_BEEPEN_MASK 0x0001 /* BEEPEN */
-#define WM8983_BEEPEN_SHIFT 0 /* BEEPEN */
-#define WM8983_BEEPEN_WIDTH 1 /* BEEPEN */
-
-/*
- * R44 (0x2C) - Input ctrl
- */
-#define WM8983_MBVSEL 0x0100 /* MBVSEL */
-#define WM8983_MBVSEL_MASK 0x0100 /* MBVSEL */
-#define WM8983_MBVSEL_SHIFT 8 /* MBVSEL */
-#define WM8983_MBVSEL_WIDTH 1 /* MBVSEL */
-#define WM8983_R2_2INPPGA 0x0040 /* R2_2INPPGA */
-#define WM8983_R2_2INPPGA_MASK 0x0040 /* R2_2INPPGA */
-#define WM8983_R2_2INPPGA_SHIFT 6 /* R2_2INPPGA */
-#define WM8983_R2_2INPPGA_WIDTH 1 /* R2_2INPPGA */
-#define WM8983_RIN2INPPGA 0x0020 /* RIN2INPPGA */
-#define WM8983_RIN2INPPGA_MASK 0x0020 /* RIN2INPPGA */
-#define WM8983_RIN2INPPGA_SHIFT 5 /* RIN2INPPGA */
-#define WM8983_RIN2INPPGA_WIDTH 1 /* RIN2INPPGA */
-#define WM8983_RIP2INPPGA 0x0010 /* RIP2INPPGA */
-#define WM8983_RIP2INPPGA_MASK 0x0010 /* RIP2INPPGA */
-#define WM8983_RIP2INPPGA_SHIFT 4 /* RIP2INPPGA */
-#define WM8983_RIP2INPPGA_WIDTH 1 /* RIP2INPPGA */
-#define WM8983_L2_2INPPGA 0x0004 /* L2_2INPPGA */
-#define WM8983_L2_2INPPGA_MASK 0x0004 /* L2_2INPPGA */
-#define WM8983_L2_2INPPGA_SHIFT 2 /* L2_2INPPGA */
-#define WM8983_L2_2INPPGA_WIDTH 1 /* L2_2INPPGA */
-#define WM8983_LIN2INPPGA 0x0002 /* LIN2INPPGA */
-#define WM8983_LIN2INPPGA_MASK 0x0002 /* LIN2INPPGA */
-#define WM8983_LIN2INPPGA_SHIFT 1 /* LIN2INPPGA */
-#define WM8983_LIN2INPPGA_WIDTH 1 /* LIN2INPPGA */
-#define WM8983_LIP2INPPGA 0x0001 /* LIP2INPPGA */
-#define WM8983_LIP2INPPGA_MASK 0x0001 /* LIP2INPPGA */
-#define WM8983_LIP2INPPGA_SHIFT 0 /* LIP2INPPGA */
-#define WM8983_LIP2INPPGA_WIDTH 1 /* LIP2INPPGA */
-
-/*
- * R45 (0x2D) - Left INP PGA gain ctrl
- */
-#define WM8983_INPGAVU 0x0100 /* INPGAVU */
-#define WM8983_INPGAVU_MASK 0x0100 /* INPGAVU */
-#define WM8983_INPGAVU_SHIFT 8 /* INPGAVU */
-#define WM8983_INPGAVU_WIDTH 1 /* INPGAVU */
-#define WM8983_INPPGAZCL 0x0080 /* INPPGAZCL */
-#define WM8983_INPPGAZCL_MASK 0x0080 /* INPPGAZCL */
-#define WM8983_INPPGAZCL_SHIFT 7 /* INPPGAZCL */
-#define WM8983_INPPGAZCL_WIDTH 1 /* INPPGAZCL */
-#define WM8983_INPPGAMUTEL 0x0040 /* INPPGAMUTEL */
-#define WM8983_INPPGAMUTEL_MASK 0x0040 /* INPPGAMUTEL */
-#define WM8983_INPPGAMUTEL_SHIFT 6 /* INPPGAMUTEL */
-#define WM8983_INPPGAMUTEL_WIDTH 1 /* INPPGAMUTEL */
-#define WM8983_INPPGAVOLL_MASK 0x003F /* INPPGAVOLL - [5:0] */
-#define WM8983_INPPGAVOLL_SHIFT 0 /* INPPGAVOLL - [5:0] */
-#define WM8983_INPPGAVOLL_WIDTH 6 /* INPPGAVOLL - [5:0] */
-
-/*
- * R46 (0x2E) - Right INP PGA gain ctrl
- */
-#define WM8983_INPGAVU 0x0100 /* INPGAVU */
-#define WM8983_INPGAVU_MASK 0x0100 /* INPGAVU */
-#define WM8983_INPGAVU_SHIFT 8 /* INPGAVU */
-#define WM8983_INPGAVU_WIDTH 1 /* INPGAVU */
-#define WM8983_INPPGAZCR 0x0080 /* INPPGAZCR */
-#define WM8983_INPPGAZCR_MASK 0x0080 /* INPPGAZCR */
-#define WM8983_INPPGAZCR_SHIFT 7 /* INPPGAZCR */
-#define WM8983_INPPGAZCR_WIDTH 1 /* INPPGAZCR */
-#define WM8983_INPPGAMUTER 0x0040 /* INPPGAMUTER */
-#define WM8983_INPPGAMUTER_MASK 0x0040 /* INPPGAMUTER */
-#define WM8983_INPPGAMUTER_SHIFT 6 /* INPPGAMUTER */
-#define WM8983_INPPGAMUTER_WIDTH 1 /* INPPGAMUTER */
-#define WM8983_INPPGAVOLR_MASK 0x003F /* INPPGAVOLR - [5:0] */
-#define WM8983_INPPGAVOLR_SHIFT 0 /* INPPGAVOLR - [5:0] */
-#define WM8983_INPPGAVOLR_WIDTH 6 /* INPPGAVOLR - [5:0] */
-
-/*
- * R47 (0x2F) - Left ADC BOOST ctrl
- */
-#define WM8983_PGABOOSTL 0x0100 /* PGABOOSTL */
-#define WM8983_PGABOOSTL_MASK 0x0100 /* PGABOOSTL */
-#define WM8983_PGABOOSTL_SHIFT 8 /* PGABOOSTL */
-#define WM8983_PGABOOSTL_WIDTH 1 /* PGABOOSTL */
-#define WM8983_L2_2BOOSTVOL_MASK 0x0070 /* L2_2BOOSTVOL - [6:4] */
-#define WM8983_L2_2BOOSTVOL_SHIFT 4 /* L2_2BOOSTVOL - [6:4] */
-#define WM8983_L2_2BOOSTVOL_WIDTH 3 /* L2_2BOOSTVOL - [6:4] */
-#define WM8983_AUXL2BOOSTVOL_MASK 0x0007 /* AUXL2BOOSTVOL - [2:0] */
-#define WM8983_AUXL2BOOSTVOL_SHIFT 0 /* AUXL2BOOSTVOL - [2:0] */
-#define WM8983_AUXL2BOOSTVOL_WIDTH 3 /* AUXL2BOOSTVOL - [2:0] */
-
-/*
- * R48 (0x30) - Right ADC BOOST ctrl
- */
-#define WM8983_PGABOOSTR 0x0100 /* PGABOOSTR */
-#define WM8983_PGABOOSTR_MASK 0x0100 /* PGABOOSTR */
-#define WM8983_PGABOOSTR_SHIFT 8 /* PGABOOSTR */
-#define WM8983_PGABOOSTR_WIDTH 1 /* PGABOOSTR */
-#define WM8983_R2_2BOOSTVOL_MASK 0x0070 /* R2_2BOOSTVOL - [6:4] */
-#define WM8983_R2_2BOOSTVOL_SHIFT 4 /* R2_2BOOSTVOL - [6:4] */
-#define WM8983_R2_2BOOSTVOL_WIDTH 3 /* R2_2BOOSTVOL - [6:4] */
-#define WM8983_AUXR2BOOSTVOL_MASK 0x0007 /* AUXR2BOOSTVOL - [2:0] */
-#define WM8983_AUXR2BOOSTVOL_SHIFT 0 /* AUXR2BOOSTVOL - [2:0] */
-#define WM8983_AUXR2BOOSTVOL_WIDTH 3 /* AUXR2BOOSTVOL - [2:0] */
-
-/*
- * R49 (0x31) - Output ctrl
- */
-#define WM8983_DACL2RMIX 0x0040 /* DACL2RMIX */
-#define WM8983_DACL2RMIX_MASK 0x0040 /* DACL2RMIX */
-#define WM8983_DACL2RMIX_SHIFT 6 /* DACL2RMIX */
-#define WM8983_DACL2RMIX_WIDTH 1 /* DACL2RMIX */
-#define WM8983_DACR2LMIX 0x0020 /* DACR2LMIX */
-#define WM8983_DACR2LMIX_MASK 0x0020 /* DACR2LMIX */
-#define WM8983_DACR2LMIX_SHIFT 5 /* DACR2LMIX */
-#define WM8983_DACR2LMIX_WIDTH 1 /* DACR2LMIX */
-#define WM8983_OUT4BOOST 0x0010 /* OUT4BOOST */
-#define WM8983_OUT4BOOST_MASK 0x0010 /* OUT4BOOST */
-#define WM8983_OUT4BOOST_SHIFT 4 /* OUT4BOOST */
-#define WM8983_OUT4BOOST_WIDTH 1 /* OUT4BOOST */
-#define WM8983_OUT3BOOST 0x0008 /* OUT3BOOST */
-#define WM8983_OUT3BOOST_MASK 0x0008 /* OUT3BOOST */
-#define WM8983_OUT3BOOST_SHIFT 3 /* OUT3BOOST */
-#define WM8983_OUT3BOOST_WIDTH 1 /* OUT3BOOST */
-#define WM8983_SPKBOOST 0x0004 /* SPKBOOST */
-#define WM8983_SPKBOOST_MASK 0x0004 /* SPKBOOST */
-#define WM8983_SPKBOOST_SHIFT 2 /* SPKBOOST */
-#define WM8983_SPKBOOST_WIDTH 1 /* SPKBOOST */
-#define WM8983_TSDEN 0x0002 /* TSDEN */
-#define WM8983_TSDEN_MASK 0x0002 /* TSDEN */
-#define WM8983_TSDEN_SHIFT 1 /* TSDEN */
-#define WM8983_TSDEN_WIDTH 1 /* TSDEN */
-#define WM8983_VROI 0x0001 /* VROI */
-#define WM8983_VROI_MASK 0x0001 /* VROI */
-#define WM8983_VROI_SHIFT 0 /* VROI */
-#define WM8983_VROI_WIDTH 1 /* VROI */
-
-/*
- * R50 (0x32) - Left mixer ctrl
- */
-#define WM8983_AUXLMIXVOL_MASK 0x01C0 /* AUXLMIXVOL - [8:6] */
-#define WM8983_AUXLMIXVOL_SHIFT 6 /* AUXLMIXVOL - [8:6] */
-#define WM8983_AUXLMIXVOL_WIDTH 3 /* AUXLMIXVOL - [8:6] */
-#define WM8983_AUXL2LMIX 0x0020 /* AUXL2LMIX */
-#define WM8983_AUXL2LMIX_MASK 0x0020 /* AUXL2LMIX */
-#define WM8983_AUXL2LMIX_SHIFT 5 /* AUXL2LMIX */
-#define WM8983_AUXL2LMIX_WIDTH 1 /* AUXL2LMIX */
-#define WM8983_BYPLMIXVOL_MASK 0x001C /* BYPLMIXVOL - [4:2] */
-#define WM8983_BYPLMIXVOL_SHIFT 2 /* BYPLMIXVOL - [4:2] */
-#define WM8983_BYPLMIXVOL_WIDTH 3 /* BYPLMIXVOL - [4:2] */
-#define WM8983_BYPL2LMIX 0x0002 /* BYPL2LMIX */
-#define WM8983_BYPL2LMIX_MASK 0x0002 /* BYPL2LMIX */
-#define WM8983_BYPL2LMIX_SHIFT 1 /* BYPL2LMIX */
-#define WM8983_BYPL2LMIX_WIDTH 1 /* BYPL2LMIX */
-#define WM8983_DACL2LMIX 0x0001 /* DACL2LMIX */
-#define WM8983_DACL2LMIX_MASK 0x0001 /* DACL2LMIX */
-#define WM8983_DACL2LMIX_SHIFT 0 /* DACL2LMIX */
-#define WM8983_DACL2LMIX_WIDTH 1 /* DACL2LMIX */
-
-/*
- * R51 (0x33) - Right mixer ctrl
- */
-#define WM8983_AUXRMIXVOL_MASK 0x01C0 /* AUXRMIXVOL - [8:6] */
-#define WM8983_AUXRMIXVOL_SHIFT 6 /* AUXRMIXVOL - [8:6] */
-#define WM8983_AUXRMIXVOL_WIDTH 3 /* AUXRMIXVOL - [8:6] */
-#define WM8983_AUXR2RMIX 0x0020 /* AUXR2RMIX */
-#define WM8983_AUXR2RMIX_MASK 0x0020 /* AUXR2RMIX */
-#define WM8983_AUXR2RMIX_SHIFT 5 /* AUXR2RMIX */
-#define WM8983_AUXR2RMIX_WIDTH 1 /* AUXR2RMIX */
-#define WM8983_BYPRMIXVOL_MASK 0x001C /* BYPRMIXVOL - [4:2] */
-#define WM8983_BYPRMIXVOL_SHIFT 2 /* BYPRMIXVOL - [4:2] */
-#define WM8983_BYPRMIXVOL_WIDTH 3 /* BYPRMIXVOL - [4:2] */
-#define WM8983_BYPR2RMIX 0x0002 /* BYPR2RMIX */
-#define WM8983_BYPR2RMIX_MASK 0x0002 /* BYPR2RMIX */
-#define WM8983_BYPR2RMIX_SHIFT 1 /* BYPR2RMIX */
-#define WM8983_BYPR2RMIX_WIDTH 1 /* BYPR2RMIX */
-#define WM8983_DACR2RMIX 0x0001 /* DACR2RMIX */
-#define WM8983_DACR2RMIX_MASK 0x0001 /* DACR2RMIX */
-#define WM8983_DACR2RMIX_SHIFT 0 /* DACR2RMIX */
-#define WM8983_DACR2RMIX_WIDTH 1 /* DACR2RMIX */
-
-/*
- * R52 (0x34) - LOUT1 (HP) volume ctrl
- */
-#define WM8983_OUT1VU 0x0100 /* OUT1VU */
-#define WM8983_OUT1VU_MASK 0x0100 /* OUT1VU */
-#define WM8983_OUT1VU_SHIFT 8 /* OUT1VU */
-#define WM8983_OUT1VU_WIDTH 1 /* OUT1VU */
-#define WM8983_LOUT1ZC 0x0080 /* LOUT1ZC */
-#define WM8983_LOUT1ZC_MASK 0x0080 /* LOUT1ZC */
-#define WM8983_LOUT1ZC_SHIFT 7 /* LOUT1ZC */
-#define WM8983_LOUT1ZC_WIDTH 1 /* LOUT1ZC */
-#define WM8983_LOUT1MUTE 0x0040 /* LOUT1MUTE */
-#define WM8983_LOUT1MUTE_MASK 0x0040 /* LOUT1MUTE */
-#define WM8983_LOUT1MUTE_SHIFT 6 /* LOUT1MUTE */
-#define WM8983_LOUT1MUTE_WIDTH 1 /* LOUT1MUTE */
-#define WM8983_LOUT1VOL_MASK 0x003F /* LOUT1VOL - [5:0] */
-#define WM8983_LOUT1VOL_SHIFT 0 /* LOUT1VOL - [5:0] */
-#define WM8983_LOUT1VOL_WIDTH 6 /* LOUT1VOL - [5:0] */
-
-/*
- * R53 (0x35) - ROUT1 (HP) volume ctrl
- */
-#define WM8983_OUT1VU 0x0100 /* OUT1VU */
-#define WM8983_OUT1VU_MASK 0x0100 /* OUT1VU */
-#define WM8983_OUT1VU_SHIFT 8 /* OUT1VU */
-#define WM8983_OUT1VU_WIDTH 1 /* OUT1VU */
-#define WM8983_ROUT1ZC 0x0080 /* ROUT1ZC */
-#define WM8983_ROUT1ZC_MASK 0x0080 /* ROUT1ZC */
-#define WM8983_ROUT1ZC_SHIFT 7 /* ROUT1ZC */
-#define WM8983_ROUT1ZC_WIDTH 1 /* ROUT1ZC */
-#define WM8983_ROUT1MUTE 0x0040 /* ROUT1MUTE */
-#define WM8983_ROUT1MUTE_MASK 0x0040 /* ROUT1MUTE */
-#define WM8983_ROUT1MUTE_SHIFT 6 /* ROUT1MUTE */
-#define WM8983_ROUT1MUTE_WIDTH 1 /* ROUT1MUTE */
-#define WM8983_ROUT1VOL_MASK 0x003F /* ROUT1VOL - [5:0] */
-#define WM8983_ROUT1VOL_SHIFT 0 /* ROUT1VOL - [5:0] */
-#define WM8983_ROUT1VOL_WIDTH 6 /* ROUT1VOL - [5:0] */
-
-/*
- * R54 (0x36) - LOUT2 (SPK) volume ctrl
- */
-#define WM8983_OUT2VU 0x0100 /* OUT2VU */
-#define WM8983_OUT2VU_MASK 0x0100 /* OUT2VU */
-#define WM8983_OUT2VU_SHIFT 8 /* OUT2VU */
-#define WM8983_OUT2VU_WIDTH 1 /* OUT2VU */
-#define WM8983_LOUT2ZC 0x0080 /* LOUT2ZC */
-#define WM8983_LOUT2ZC_MASK 0x0080 /* LOUT2ZC */
-#define WM8983_LOUT2ZC_SHIFT 7 /* LOUT2ZC */
-#define WM8983_LOUT2ZC_WIDTH 1 /* LOUT2ZC */
-#define WM8983_LOUT2MUTE 0x0040 /* LOUT2MUTE */
-#define WM8983_LOUT2MUTE_MASK 0x0040 /* LOUT2MUTE */
-#define WM8983_LOUT2MUTE_SHIFT 6 /* LOUT2MUTE */
-#define WM8983_LOUT2MUTE_WIDTH 1 /* LOUT2MUTE */
-#define WM8983_LOUT2VOL_MASK 0x003F /* LOUT2VOL - [5:0] */
-#define WM8983_LOUT2VOL_SHIFT 0 /* LOUT2VOL - [5:0] */
-#define WM8983_LOUT2VOL_WIDTH 6 /* LOUT2VOL - [5:0] */
-
-/*
- * R55 (0x37) - ROUT2 (SPK) volume ctrl
- */
-#define WM8983_OUT2VU 0x0100 /* OUT2VU */
-#define WM8983_OUT2VU_MASK 0x0100 /* OUT2VU */
-#define WM8983_OUT2VU_SHIFT 8 /* OUT2VU */
-#define WM8983_OUT2VU_WIDTH 1 /* OUT2VU */
-#define WM8983_ROUT2ZC 0x0080 /* ROUT2ZC */
-#define WM8983_ROUT2ZC_MASK 0x0080 /* ROUT2ZC */
-#define WM8983_ROUT2ZC_SHIFT 7 /* ROUT2ZC */
-#define WM8983_ROUT2ZC_WIDTH 1 /* ROUT2ZC */
-#define WM8983_ROUT2MUTE 0x0040 /* ROUT2MUTE */
-#define WM8983_ROUT2MUTE_MASK 0x0040 /* ROUT2MUTE */
-#define WM8983_ROUT2MUTE_SHIFT 6 /* ROUT2MUTE */
-#define WM8983_ROUT2MUTE_WIDTH 1 /* ROUT2MUTE */
-#define WM8983_ROUT2VOL_MASK 0x003F /* ROUT2VOL - [5:0] */
-#define WM8983_ROUT2VOL_SHIFT 0 /* ROUT2VOL - [5:0] */
-#define WM8983_ROUT2VOL_WIDTH 6 /* ROUT2VOL - [5:0] */
-
-/*
- * R56 (0x38) - OUT3 mixer ctrl
- */
-#define WM8983_OUT3MUTE 0x0040 /* OUT3MUTE */
-#define WM8983_OUT3MUTE_MASK 0x0040 /* OUT3MUTE */
-#define WM8983_OUT3MUTE_SHIFT 6 /* OUT3MUTE */
-#define WM8983_OUT3MUTE_WIDTH 1 /* OUT3MUTE */
-#define WM8983_OUT4_2OUT3 0x0008 /* OUT4_2OUT3 */
-#define WM8983_OUT4_2OUT3_MASK 0x0008 /* OUT4_2OUT3 */
-#define WM8983_OUT4_2OUT3_SHIFT 3 /* OUT4_2OUT3 */
-#define WM8983_OUT4_2OUT3_WIDTH 1 /* OUT4_2OUT3 */
-#define WM8983_BYPL2OUT3 0x0004 /* BYPL2OUT3 */
-#define WM8983_BYPL2OUT3_MASK 0x0004 /* BYPL2OUT3 */
-#define WM8983_BYPL2OUT3_SHIFT 2 /* BYPL2OUT3 */
-#define WM8983_BYPL2OUT3_WIDTH 1 /* BYPL2OUT3 */
-#define WM8983_LMIX2OUT3 0x0002 /* LMIX2OUT3 */
-#define WM8983_LMIX2OUT3_MASK 0x0002 /* LMIX2OUT3 */
-#define WM8983_LMIX2OUT3_SHIFT 1 /* LMIX2OUT3 */
-#define WM8983_LMIX2OUT3_WIDTH 1 /* LMIX2OUT3 */
-#define WM8983_LDAC2OUT3 0x0001 /* LDAC2OUT3 */
-#define WM8983_LDAC2OUT3_MASK 0x0001 /* LDAC2OUT3 */
-#define WM8983_LDAC2OUT3_SHIFT 0 /* LDAC2OUT3 */
-#define WM8983_LDAC2OUT3_WIDTH 1 /* LDAC2OUT3 */
-
-/*
- * R57 (0x39) - OUT4 (MONO) mix ctrl
- */
-#define WM8983_OUT3_2OUT4 0x0080 /* OUT3_2OUT4 */
-#define WM8983_OUT3_2OUT4_MASK 0x0080 /* OUT3_2OUT4 */
-#define WM8983_OUT3_2OUT4_SHIFT 7 /* OUT3_2OUT4 */
-#define WM8983_OUT3_2OUT4_WIDTH 1 /* OUT3_2OUT4 */
-#define WM8983_OUT4MUTE 0x0040 /* OUT4MUTE */
-#define WM8983_OUT4MUTE_MASK 0x0040 /* OUT4MUTE */
-#define WM8983_OUT4MUTE_SHIFT 6 /* OUT4MUTE */
-#define WM8983_OUT4MUTE_WIDTH 1 /* OUT4MUTE */
-#define WM8983_OUT4ATTN 0x0020 /* OUT4ATTN */
-#define WM8983_OUT4ATTN_MASK 0x0020 /* OUT4ATTN */
-#define WM8983_OUT4ATTN_SHIFT 5 /* OUT4ATTN */
-#define WM8983_OUT4ATTN_WIDTH 1 /* OUT4ATTN */
-#define WM8983_LMIX2OUT4 0x0010 /* LMIX2OUT4 */
-#define WM8983_LMIX2OUT4_MASK 0x0010 /* LMIX2OUT4 */
-#define WM8983_LMIX2OUT4_SHIFT 4 /* LMIX2OUT4 */
-#define WM8983_LMIX2OUT4_WIDTH 1 /* LMIX2OUT4 */
-#define WM8983_LDAC2OUT4 0x0008 /* LDAC2OUT4 */
-#define WM8983_LDAC2OUT4_MASK 0x0008 /* LDAC2OUT4 */
-#define WM8983_LDAC2OUT4_SHIFT 3 /* LDAC2OUT4 */
-#define WM8983_LDAC2OUT4_WIDTH 1 /* LDAC2OUT4 */
-#define WM8983_BYPR2OUT4 0x0004 /* BYPR2OUT4 */
-#define WM8983_BYPR2OUT4_MASK 0x0004 /* BYPR2OUT4 */
-#define WM8983_BYPR2OUT4_SHIFT 2 /* BYPR2OUT4 */
-#define WM8983_BYPR2OUT4_WIDTH 1 /* BYPR2OUT4 */
-#define WM8983_RMIX2OUT4 0x0002 /* RMIX2OUT4 */
-#define WM8983_RMIX2OUT4_MASK 0x0002 /* RMIX2OUT4 */
-#define WM8983_RMIX2OUT4_SHIFT 1 /* RMIX2OUT4 */
-#define WM8983_RMIX2OUT4_WIDTH 1 /* RMIX2OUT4 */
-#define WM8983_RDAC2OUT4 0x0001 /* RDAC2OUT4 */
-#define WM8983_RDAC2OUT4_MASK 0x0001 /* RDAC2OUT4 */
-#define WM8983_RDAC2OUT4_SHIFT 0 /* RDAC2OUT4 */
-#define WM8983_RDAC2OUT4_WIDTH 1 /* RDAC2OUT4 */
-
-/*
- * R61 (0x3D) - BIAS CTRL
- */
-#define WM8983_BIASCUT 0x0100 /* BIASCUT */
-#define WM8983_BIASCUT_MASK 0x0100 /* BIASCUT */
-#define WM8983_BIASCUT_SHIFT 8 /* BIASCUT */
-#define WM8983_BIASCUT_WIDTH 1 /* BIASCUT */
-#define WM8983_HALFIPBIAS 0x0080 /* HALFIPBIAS */
-#define WM8983_HALFIPBIAS_MASK 0x0080 /* HALFIPBIAS */
-#define WM8983_HALFIPBIAS_SHIFT 7 /* HALFIPBIAS */
-#define WM8983_HALFIPBIAS_WIDTH 1 /* HALFIPBIAS */
-#define WM8983_VBBIASTST_MASK 0x0060 /* VBBIASTST - [6:5] */
-#define WM8983_VBBIASTST_SHIFT 5 /* VBBIASTST - [6:5] */
-#define WM8983_VBBIASTST_WIDTH 2 /* VBBIASTST - [6:5] */
-#define WM8983_BUFBIAS_MASK 0x0018 /* BUFBIAS - [4:3] */
-#define WM8983_BUFBIAS_SHIFT 3 /* BUFBIAS - [4:3] */
-#define WM8983_BUFBIAS_WIDTH 2 /* BUFBIAS - [4:3] */
-#define WM8983_ADCBIAS_MASK 0x0006 /* ADCBIAS - [2:1] */
-#define WM8983_ADCBIAS_SHIFT 1 /* ADCBIAS - [2:1] */
-#define WM8983_ADCBIAS_WIDTH 2 /* ADCBIAS - [2:1] */
-#define WM8983_HALFOPBIAS 0x0001 /* HALFOPBIAS */
-#define WM8983_HALFOPBIAS_MASK 0x0001 /* HALFOPBIAS */
-#define WM8983_HALFOPBIAS_SHIFT 0 /* HALFOPBIAS */
-#define WM8983_HALFOPBIAS_WIDTH 1 /* HALFOPBIAS */
-
-enum clk_src {
- WM8983_CLKSRC_MCLK,
- WM8983_CLKSRC_PLL
-};
-
-#endif /* _WM8983_H */
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8985.c b/ANDROID_3.4.5/sound/soc/codecs/wm8985.c
deleted file mode 100644
index 14f66639..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8985.c
+++ /dev/null
@@ -1,1260 +0,0 @@
-/*
- * wm8985.c -- WM8985 ALSA SoC Audio driver
- *
- * Copyright 2010 Wolfson Microelectronics plc
- *
- * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * TODO:
- * o Add OUT3/OUT4 mixer controls.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/regmap.h>
-#include <linux/regulator/consumer.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "wm8985.h"
-
-#define WM8985_NUM_SUPPLIES 4
-static const char *wm8985_supply_names[WM8985_NUM_SUPPLIES] = {
- "DCVDD",
- "DBVDD",
- "AVDD1",
- "AVDD2"
-};
-
-static const struct reg_default wm8985_reg_defaults[] = {
- { 1, 0x0000 }, /* R1 - Power management 1 */
- { 2, 0x0000 }, /* R2 - Power management 2 */
- { 3, 0x0000 }, /* R3 - Power management 3 */
- { 4, 0x0050 }, /* R4 - Audio Interface */
- { 5, 0x0000 }, /* R5 - Companding control */
- { 6, 0x0140 }, /* R6 - Clock Gen control */
- { 7, 0x0000 }, /* R7 - Additional control */
- { 8, 0x0000 }, /* R8 - GPIO Control */
- { 9, 0x0000 }, /* R9 - Jack Detect Control 1 */
- { 10, 0x0000 }, /* R10 - DAC Control */
- { 11, 0x00FF }, /* R11 - Left DAC digital Vol */
- { 12, 0x00FF }, /* R12 - Right DAC digital vol */
- { 13, 0x0000 }, /* R13 - Jack Detect Control 2 */
- { 14, 0x0100 }, /* R14 - ADC Control */
- { 15, 0x00FF }, /* R15 - Left ADC Digital Vol */
- { 16, 0x00FF }, /* R16 - Right ADC Digital Vol */
- { 18, 0x012C }, /* R18 - EQ1 - low shelf */
- { 19, 0x002C }, /* R19 - EQ2 - peak 1 */
- { 20, 0x002C }, /* R20 - EQ3 - peak 2 */
- { 21, 0x002C }, /* R21 - EQ4 - peak 3 */
- { 22, 0x002C }, /* R22 - EQ5 - high shelf */
- { 24, 0x0032 }, /* R24 - DAC Limiter 1 */
- { 25, 0x0000 }, /* R25 - DAC Limiter 2 */
- { 27, 0x0000 }, /* R27 - Notch Filter 1 */
- { 28, 0x0000 }, /* R28 - Notch Filter 2 */
- { 29, 0x0000 }, /* R29 - Notch Filter 3 */
- { 30, 0x0000 }, /* R30 - Notch Filter 4 */
- { 32, 0x0038 }, /* R32 - ALC control 1 */
- { 33, 0x000B }, /* R33 - ALC control 2 */
- { 34, 0x0032 }, /* R34 - ALC control 3 */
- { 35, 0x0000 }, /* R35 - Noise Gate */
- { 36, 0x0008 }, /* R36 - PLL N */
- { 37, 0x000C }, /* R37 - PLL K 1 */
- { 38, 0x0093 }, /* R38 - PLL K 2 */
- { 39, 0x00E9 }, /* R39 - PLL K 3 */
- { 41, 0x0000 }, /* R41 - 3D control */
- { 42, 0x0000 }, /* R42 - OUT4 to ADC */
- { 43, 0x0000 }, /* R43 - Beep control */
- { 44, 0x0033 }, /* R44 - Input ctrl */
- { 45, 0x0010 }, /* R45 - Left INP PGA gain ctrl */
- { 46, 0x0010 }, /* R46 - Right INP PGA gain ctrl */
- { 47, 0x0100 }, /* R47 - Left ADC BOOST ctrl */
- { 48, 0x0100 }, /* R48 - Right ADC BOOST ctrl */
- { 49, 0x0002 }, /* R49 - Output ctrl */
- { 50, 0x0001 }, /* R50 - Left mixer ctrl */
- { 51, 0x0001 }, /* R51 - Right mixer ctrl */
- { 52, 0x0039 }, /* R52 - LOUT1 (HP) volume ctrl */
- { 53, 0x0039 }, /* R53 - ROUT1 (HP) volume ctrl */
- { 54, 0x0039 }, /* R54 - LOUT2 (SPK) volume ctrl */
- { 55, 0x0039 }, /* R55 - ROUT2 (SPK) volume ctrl */
- { 56, 0x0001 }, /* R56 - OUT3 mixer ctrl */
- { 57, 0x0001 }, /* R57 - OUT4 (MONO) mix ctrl */
- { 60, 0x0004 }, /* R60 - OUTPUT ctrl */
- { 61, 0x0000 }, /* R61 - BIAS CTRL */
-};
-
-static bool wm8985_writeable(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM8985_SOFTWARE_RESET:
- case WM8985_POWER_MANAGEMENT_1:
- case WM8985_POWER_MANAGEMENT_2:
- case WM8985_POWER_MANAGEMENT_3:
- case WM8985_AUDIO_INTERFACE:
- case WM8985_COMPANDING_CONTROL:
- case WM8985_CLOCK_GEN_CONTROL:
- case WM8985_ADDITIONAL_CONTROL:
- case WM8985_GPIO_CONTROL:
- case WM8985_JACK_DETECT_CONTROL_1:
- case WM8985_DAC_CONTROL:
- case WM8985_LEFT_DAC_DIGITAL_VOL:
- case WM8985_RIGHT_DAC_DIGITAL_VOL:
- case WM8985_JACK_DETECT_CONTROL_2:
- case WM8985_ADC_CONTROL:
- case WM8985_LEFT_ADC_DIGITAL_VOL:
- case WM8985_RIGHT_ADC_DIGITAL_VOL:
- case WM8985_EQ1_LOW_SHELF:
- case WM8985_EQ2_PEAK_1:
- case WM8985_EQ3_PEAK_2:
- case WM8985_EQ4_PEAK_3:
- case WM8985_EQ5_HIGH_SHELF:
- case WM8985_DAC_LIMITER_1:
- case WM8985_DAC_LIMITER_2:
- case WM8985_NOTCH_FILTER_1:
- case WM8985_NOTCH_FILTER_2:
- case WM8985_NOTCH_FILTER_3:
- case WM8985_NOTCH_FILTER_4:
- case WM8985_ALC_CONTROL_1:
- case WM8985_ALC_CONTROL_2:
- case WM8985_ALC_CONTROL_3:
- case WM8985_NOISE_GATE:
- case WM8985_PLL_N:
- case WM8985_PLL_K_1:
- case WM8985_PLL_K_2:
- case WM8985_PLL_K_3:
- case WM8985_3D_CONTROL:
- case WM8985_OUT4_TO_ADC:
- case WM8985_BEEP_CONTROL:
- case WM8985_INPUT_CTRL:
- case WM8985_LEFT_INP_PGA_GAIN_CTRL:
- case WM8985_RIGHT_INP_PGA_GAIN_CTRL:
- case WM8985_LEFT_ADC_BOOST_CTRL:
- case WM8985_RIGHT_ADC_BOOST_CTRL:
- case WM8985_OUTPUT_CTRL0:
- case WM8985_LEFT_MIXER_CTRL:
- case WM8985_RIGHT_MIXER_CTRL:
- case WM8985_LOUT1_HP_VOLUME_CTRL:
- case WM8985_ROUT1_HP_VOLUME_CTRL:
- case WM8985_LOUT2_SPK_VOLUME_CTRL:
- case WM8985_ROUT2_SPK_VOLUME_CTRL:
- case WM8985_OUT3_MIXER_CTRL:
- case WM8985_OUT4_MONO_MIX_CTRL:
- case WM8985_OUTPUT_CTRL1:
- case WM8985_BIAS_CTRL:
- return true;
- default:
- return false;
- }
-}
-
-/*
- * latch bit 8 of these registers to ensure instant
- * volume updates
- */
-static const int volume_update_regs[] = {
- WM8985_LEFT_DAC_DIGITAL_VOL,
- WM8985_RIGHT_DAC_DIGITAL_VOL,
- WM8985_LEFT_ADC_DIGITAL_VOL,
- WM8985_RIGHT_ADC_DIGITAL_VOL,
- WM8985_LOUT2_SPK_VOLUME_CTRL,
- WM8985_ROUT2_SPK_VOLUME_CTRL,
- WM8985_LOUT1_HP_VOLUME_CTRL,
- WM8985_ROUT1_HP_VOLUME_CTRL,
- WM8985_LEFT_INP_PGA_GAIN_CTRL,
- WM8985_RIGHT_INP_PGA_GAIN_CTRL
-};
-
-struct wm8985_priv {
- struct regmap *regmap;
- struct regulator_bulk_data supplies[WM8985_NUM_SUPPLIES];
- unsigned int sysclk;
- unsigned int bclk;
-};
-
-static const struct {
- int div;
- int ratio;
-} fs_ratios[] = {
- { 10, 128 },
- { 15, 192 },
- { 20, 256 },
- { 30, 384 },
- { 40, 512 },
- { 60, 768 },
- { 80, 1024 },
- { 120, 1536 }
-};
-
-static const int srates[] = { 48000, 32000, 24000, 16000, 12000, 8000 };
-
-static const int bclk_divs[] = {
- 1, 2, 4, 8, 16, 32
-};
-
-static int eqmode_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-static int eqmode_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-
-static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1);
-static const DECLARE_TLV_DB_SCALE(adc_tlv, -12700, 50, 1);
-static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
-static const DECLARE_TLV_DB_SCALE(lim_thresh_tlv, -600, 100, 0);
-static const DECLARE_TLV_DB_SCALE(lim_boost_tlv, 0, 100, 0);
-static const DECLARE_TLV_DB_SCALE(alc_min_tlv, -1200, 600, 0);
-static const DECLARE_TLV_DB_SCALE(alc_max_tlv, -675, 600, 0);
-static const DECLARE_TLV_DB_SCALE(alc_tar_tlv, -2250, 150, 0);
-static const DECLARE_TLV_DB_SCALE(pga_vol_tlv, -1200, 75, 0);
-static const DECLARE_TLV_DB_SCALE(boost_tlv, -1200, 300, 1);
-static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
-static const DECLARE_TLV_DB_SCALE(aux_tlv, -1500, 300, 0);
-static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
-static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0);
-
-static const char *alc_sel_text[] = { "Off", "Right", "Left", "Stereo" };
-static const SOC_ENUM_SINGLE_DECL(alc_sel, WM8985_ALC_CONTROL_1, 7,
- alc_sel_text);
-
-static const char *alc_mode_text[] = { "ALC", "Limiter" };
-static const SOC_ENUM_SINGLE_DECL(alc_mode, WM8985_ALC_CONTROL_3, 8,
- alc_mode_text);
-
-static const char *filter_mode_text[] = { "Audio", "Application" };
-static const SOC_ENUM_SINGLE_DECL(filter_mode, WM8985_ADC_CONTROL, 7,
- filter_mode_text);
-
-static const char *eq_bw_text[] = { "Narrow", "Wide" };
-static const char *eqmode_text[] = { "Capture", "Playback" };
-static const SOC_ENUM_SINGLE_EXT_DECL(eqmode, eqmode_text);
-
-static const char *eq1_cutoff_text[] = {
- "80Hz", "105Hz", "135Hz", "175Hz"
-};
-static const SOC_ENUM_SINGLE_DECL(eq1_cutoff, WM8985_EQ1_LOW_SHELF, 5,
- eq1_cutoff_text);
-static const char *eq2_cutoff_text[] = {
- "230Hz", "300Hz", "385Hz", "500Hz"
-};
-static const SOC_ENUM_SINGLE_DECL(eq2_bw, WM8985_EQ2_PEAK_1, 8, eq_bw_text);
-static const SOC_ENUM_SINGLE_DECL(eq2_cutoff, WM8985_EQ2_PEAK_1, 5,
- eq2_cutoff_text);
-static const char *eq3_cutoff_text[] = {
- "650Hz", "850Hz", "1.1kHz", "1.4kHz"
-};
-static const SOC_ENUM_SINGLE_DECL(eq3_bw, WM8985_EQ3_PEAK_2, 8, eq_bw_text);
-static const SOC_ENUM_SINGLE_DECL(eq3_cutoff, WM8985_EQ3_PEAK_2, 5,
- eq3_cutoff_text);
-static const char *eq4_cutoff_text[] = {
- "1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz"
-};
-static const SOC_ENUM_SINGLE_DECL(eq4_bw, WM8985_EQ4_PEAK_3, 8, eq_bw_text);
-static const SOC_ENUM_SINGLE_DECL(eq4_cutoff, WM8985_EQ4_PEAK_3, 5,
- eq4_cutoff_text);
-static const char *eq5_cutoff_text[] = {
- "5.3kHz", "6.9kHz", "9kHz", "11.7kHz"
-};
-static const SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8985_EQ5_HIGH_SHELF, 5,
- eq5_cutoff_text);
-
-static const char *speaker_mode_text[] = { "Class A/B", "Class D" };
-static const SOC_ENUM_SINGLE_DECL(speaker_mode, 0x17, 8, speaker_mode_text);
-
-static const char *depth_3d_text[] = {
- "Off",
- "6.67%",
- "13.3%",
- "20%",
- "26.7%",
- "33.3%",
- "40%",
- "46.6%",
- "53.3%",
- "60%",
- "66.7%",
- "73.3%",
- "80%",
- "86.7%",
- "93.3%",
- "100%"
-};
-static const SOC_ENUM_SINGLE_DECL(depth_3d, WM8985_3D_CONTROL, 0,
- depth_3d_text);
-
-static const struct snd_kcontrol_new wm8985_snd_controls[] = {
- SOC_SINGLE("Digital Loopback Switch", WM8985_COMPANDING_CONTROL,
- 0, 1, 0),
-
- SOC_ENUM("ALC Capture Function", alc_sel),
- SOC_SINGLE_TLV("ALC Capture Max Volume", WM8985_ALC_CONTROL_1,
- 3, 7, 0, alc_max_tlv),
- SOC_SINGLE_TLV("ALC Capture Min Volume", WM8985_ALC_CONTROL_1,
- 0, 7, 0, alc_min_tlv),
- SOC_SINGLE_TLV("ALC Capture Target Volume", WM8985_ALC_CONTROL_2,
- 0, 15, 0, alc_tar_tlv),
- SOC_SINGLE("ALC Capture Attack", WM8985_ALC_CONTROL_3, 0, 10, 0),
- SOC_SINGLE("ALC Capture Hold", WM8985_ALC_CONTROL_2, 4, 10, 0),
- SOC_SINGLE("ALC Capture Decay", WM8985_ALC_CONTROL_3, 4, 10, 0),
- SOC_ENUM("ALC Mode", alc_mode),
- SOC_SINGLE("ALC Capture NG Switch", WM8985_NOISE_GATE,
- 3, 1, 0),
- SOC_SINGLE("ALC Capture NG Threshold", WM8985_NOISE_GATE,
- 0, 7, 1),
-
- SOC_DOUBLE_R_TLV("Capture Volume", WM8985_LEFT_ADC_DIGITAL_VOL,
- WM8985_RIGHT_ADC_DIGITAL_VOL, 0, 255, 0, adc_tlv),
- SOC_DOUBLE_R("Capture PGA ZC Switch", WM8985_LEFT_INP_PGA_GAIN_CTRL,
- WM8985_RIGHT_INP_PGA_GAIN_CTRL, 7, 1, 0),
- SOC_DOUBLE_R_TLV("Capture PGA Volume", WM8985_LEFT_INP_PGA_GAIN_CTRL,
- WM8985_RIGHT_INP_PGA_GAIN_CTRL, 0, 63, 0, pga_vol_tlv),
-
- SOC_DOUBLE_R_TLV("Capture PGA Boost Volume",
- WM8985_LEFT_ADC_BOOST_CTRL, WM8985_RIGHT_ADC_BOOST_CTRL,
- 8, 1, 0, pga_boost_tlv),
-
- SOC_DOUBLE("ADC Inversion Switch", WM8985_ADC_CONTROL, 0, 1, 1, 0),
- SOC_SINGLE("ADC 128x Oversampling Switch", WM8985_ADC_CONTROL, 8, 1, 0),
-
- SOC_DOUBLE_R_TLV("Playback Volume", WM8985_LEFT_DAC_DIGITAL_VOL,
- WM8985_RIGHT_DAC_DIGITAL_VOL, 0, 255, 0, dac_tlv),
-
- SOC_SINGLE("DAC Playback Limiter Switch", WM8985_DAC_LIMITER_1, 8, 1, 0),
- SOC_SINGLE("DAC Playback Limiter Decay", WM8985_DAC_LIMITER_1, 4, 10, 0),
- SOC_SINGLE("DAC Playback Limiter Attack", WM8985_DAC_LIMITER_1, 0, 11, 0),
- SOC_SINGLE_TLV("DAC Playback Limiter Threshold", WM8985_DAC_LIMITER_2,
- 4, 7, 1, lim_thresh_tlv),
- SOC_SINGLE_TLV("DAC Playback Limiter Boost Volume", WM8985_DAC_LIMITER_2,
- 0, 12, 0, lim_boost_tlv),
- SOC_DOUBLE("DAC Inversion Switch", WM8985_DAC_CONTROL, 0, 1, 1, 0),
- SOC_SINGLE("DAC Auto Mute Switch", WM8985_DAC_CONTROL, 2, 1, 0),
- SOC_SINGLE("DAC 128x Oversampling Switch", WM8985_DAC_CONTROL, 3, 1, 0),
-
- SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8985_LOUT1_HP_VOLUME_CTRL,
- WM8985_ROUT1_HP_VOLUME_CTRL, 0, 63, 0, out_tlv),
- SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8985_LOUT1_HP_VOLUME_CTRL,
- WM8985_ROUT1_HP_VOLUME_CTRL, 7, 1, 0),
- SOC_DOUBLE_R("Headphone Switch", WM8985_LOUT1_HP_VOLUME_CTRL,
- WM8985_ROUT1_HP_VOLUME_CTRL, 6, 1, 1),
-
- SOC_DOUBLE_R_TLV("Speaker Playback Volume", WM8985_LOUT2_SPK_VOLUME_CTRL,
- WM8985_ROUT2_SPK_VOLUME_CTRL, 0, 63, 0, out_tlv),
- SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8985_LOUT2_SPK_VOLUME_CTRL,
- WM8985_ROUT2_SPK_VOLUME_CTRL, 7, 1, 0),
- SOC_DOUBLE_R("Speaker Switch", WM8985_LOUT2_SPK_VOLUME_CTRL,
- WM8985_ROUT2_SPK_VOLUME_CTRL, 6, 1, 1),
-
- SOC_SINGLE("High Pass Filter Switch", WM8985_ADC_CONTROL, 8, 1, 0),
- SOC_ENUM("High Pass Filter Mode", filter_mode),
- SOC_SINGLE("High Pass Filter Cutoff", WM8985_ADC_CONTROL, 4, 7, 0),
-
- SOC_DOUBLE_R_TLV("Aux Bypass Volume",
- WM8985_LEFT_MIXER_CTRL, WM8985_RIGHT_MIXER_CTRL, 6, 7, 0,
- aux_tlv),
-
- SOC_DOUBLE_R_TLV("Input PGA Bypass Volume",
- WM8985_LEFT_MIXER_CTRL, WM8985_RIGHT_MIXER_CTRL, 2, 7, 0,
- bypass_tlv),
-
- SOC_ENUM_EXT("Equalizer Function", eqmode, eqmode_get, eqmode_put),
- SOC_ENUM("EQ1 Cutoff", eq1_cutoff),
- SOC_SINGLE_TLV("EQ1 Volume", WM8985_EQ1_LOW_SHELF, 0, 24, 1, eq_tlv),
- SOC_ENUM("EQ2 Bandwith", eq2_bw),
- SOC_ENUM("EQ2 Cutoff", eq2_cutoff),
- SOC_SINGLE_TLV("EQ2 Volume", WM8985_EQ2_PEAK_1, 0, 24, 1, eq_tlv),
- SOC_ENUM("EQ3 Bandwith", eq3_bw),
- SOC_ENUM("EQ3 Cutoff", eq3_cutoff),
- SOC_SINGLE_TLV("EQ3 Volume", WM8985_EQ3_PEAK_2, 0, 24, 1, eq_tlv),
- SOC_ENUM("EQ4 Bandwith", eq4_bw),
- SOC_ENUM("EQ4 Cutoff", eq4_cutoff),
- SOC_SINGLE_TLV("EQ4 Volume", WM8985_EQ4_PEAK_3, 0, 24, 1, eq_tlv),
- SOC_ENUM("EQ5 Cutoff", eq5_cutoff),
- SOC_SINGLE_TLV("EQ5 Volume", WM8985_EQ5_HIGH_SHELF, 0, 24, 1, eq_tlv),
-
- SOC_ENUM("3D Depth", depth_3d),
-
- SOC_ENUM("Speaker Mode", speaker_mode)
-};
-
-static const struct snd_kcontrol_new left_out_mixer[] = {
- SOC_DAPM_SINGLE("Line Switch", WM8985_LEFT_MIXER_CTRL, 1, 1, 0),
- SOC_DAPM_SINGLE("Aux Switch", WM8985_LEFT_MIXER_CTRL, 5, 1, 0),
- SOC_DAPM_SINGLE("PCM Switch", WM8985_LEFT_MIXER_CTRL, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new right_out_mixer[] = {
- SOC_DAPM_SINGLE("Line Switch", WM8985_RIGHT_MIXER_CTRL, 1, 1, 0),
- SOC_DAPM_SINGLE("Aux Switch", WM8985_RIGHT_MIXER_CTRL, 5, 1, 0),
- SOC_DAPM_SINGLE("PCM Switch", WM8985_RIGHT_MIXER_CTRL, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new left_input_mixer[] = {
- SOC_DAPM_SINGLE("L2 Switch", WM8985_INPUT_CTRL, 2, 1, 0),
- SOC_DAPM_SINGLE("MicN Switch", WM8985_INPUT_CTRL, 1, 1, 0),
- SOC_DAPM_SINGLE("MicP Switch", WM8985_INPUT_CTRL, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new right_input_mixer[] = {
- SOC_DAPM_SINGLE("R2 Switch", WM8985_INPUT_CTRL, 6, 1, 0),
- SOC_DAPM_SINGLE("MicN Switch", WM8985_INPUT_CTRL, 5, 1, 0),
- SOC_DAPM_SINGLE("MicP Switch", WM8985_INPUT_CTRL, 4, 1, 0),
-};
-
-static const struct snd_kcontrol_new left_boost_mixer[] = {
- SOC_DAPM_SINGLE_TLV("L2 Volume", WM8985_LEFT_ADC_BOOST_CTRL,
- 4, 7, 0, boost_tlv),
- SOC_DAPM_SINGLE_TLV("AUXL Volume", WM8985_LEFT_ADC_BOOST_CTRL,
- 0, 7, 0, boost_tlv)
-};
-
-static const struct snd_kcontrol_new right_boost_mixer[] = {
- SOC_DAPM_SINGLE_TLV("R2 Volume", WM8985_RIGHT_ADC_BOOST_CTRL,
- 4, 7, 0, boost_tlv),
- SOC_DAPM_SINGLE_TLV("AUXR Volume", WM8985_RIGHT_ADC_BOOST_CTRL,
- 0, 7, 0, boost_tlv)
-};
-
-static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = {
- SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8985_POWER_MANAGEMENT_3,
- 0, 0),
- SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8985_POWER_MANAGEMENT_3,
- 1, 0),
- SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8985_POWER_MANAGEMENT_2,
- 0, 0),
- SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8985_POWER_MANAGEMENT_2,
- 1, 0),
-
- SND_SOC_DAPM_MIXER("Left Output Mixer", WM8985_POWER_MANAGEMENT_3,
- 2, 0, left_out_mixer, ARRAY_SIZE(left_out_mixer)),
- SND_SOC_DAPM_MIXER("Right Output Mixer", WM8985_POWER_MANAGEMENT_3,
- 3, 0, right_out_mixer, ARRAY_SIZE(right_out_mixer)),
-
- SND_SOC_DAPM_MIXER("Left Input Mixer", WM8985_POWER_MANAGEMENT_2,
- 2, 0, left_input_mixer, ARRAY_SIZE(left_input_mixer)),
- SND_SOC_DAPM_MIXER("Right Input Mixer", WM8985_POWER_MANAGEMENT_2,
- 3, 0, right_input_mixer, ARRAY_SIZE(right_input_mixer)),
-
- SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8985_POWER_MANAGEMENT_2,
- 4, 0, left_boost_mixer, ARRAY_SIZE(left_boost_mixer)),
- SND_SOC_DAPM_MIXER("Right Boost Mixer", WM8985_POWER_MANAGEMENT_2,
- 5, 0, right_boost_mixer, ARRAY_SIZE(right_boost_mixer)),
-
- SND_SOC_DAPM_PGA("Left Capture PGA", WM8985_LEFT_INP_PGA_GAIN_CTRL,
- 6, 1, NULL, 0),
- SND_SOC_DAPM_PGA("Right Capture PGA", WM8985_RIGHT_INP_PGA_GAIN_CTRL,
- 6, 1, NULL, 0),
-
- SND_SOC_DAPM_PGA("Left Headphone Out", WM8985_POWER_MANAGEMENT_2,
- 7, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Right Headphone Out", WM8985_POWER_MANAGEMENT_2,
- 8, 0, NULL, 0),
-
- SND_SOC_DAPM_PGA("Left Speaker Out", WM8985_POWER_MANAGEMENT_3,
- 5, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Right Speaker Out", WM8985_POWER_MANAGEMENT_3,
- 6, 0, NULL, 0),
-
- SND_SOC_DAPM_SUPPLY("Mic Bias", WM8985_POWER_MANAGEMENT_1, 4, 0,
- NULL, 0),
-
- SND_SOC_DAPM_INPUT("LIN"),
- SND_SOC_DAPM_INPUT("LIP"),
- SND_SOC_DAPM_INPUT("RIN"),
- SND_SOC_DAPM_INPUT("RIP"),
- SND_SOC_DAPM_INPUT("AUXL"),
- SND_SOC_DAPM_INPUT("AUXR"),
- SND_SOC_DAPM_INPUT("L2"),
- SND_SOC_DAPM_INPUT("R2"),
- SND_SOC_DAPM_OUTPUT("HPL"),
- SND_SOC_DAPM_OUTPUT("HPR"),
- SND_SOC_DAPM_OUTPUT("SPKL"),
- SND_SOC_DAPM_OUTPUT("SPKR")
-};
-
-static const struct snd_soc_dapm_route wm8985_dapm_routes[] = {
- { "Right Output Mixer", "PCM Switch", "Right DAC" },
- { "Right Output Mixer", "Aux Switch", "AUXR" },
- { "Right Output Mixer", "Line Switch", "Right Boost Mixer" },
-
- { "Left Output Mixer", "PCM Switch", "Left DAC" },
- { "Left Output Mixer", "Aux Switch", "AUXL" },
- { "Left Output Mixer", "Line Switch", "Left Boost Mixer" },
-
- { "Right Headphone Out", NULL, "Right Output Mixer" },
- { "HPR", NULL, "Right Headphone Out" },
-
- { "Left Headphone Out", NULL, "Left Output Mixer" },
- { "HPL", NULL, "Left Headphone Out" },
-
- { "Right Speaker Out", NULL, "Right Output Mixer" },
- { "SPKR", NULL, "Right Speaker Out" },
-
- { "Left Speaker Out", NULL, "Left Output Mixer" },
- { "SPKL", NULL, "Left Speaker Out" },
-
- { "Right ADC", NULL, "Right Boost Mixer" },
-
- { "Right Boost Mixer", "AUXR Volume", "AUXR" },
- { "Right Boost Mixer", NULL, "Right Capture PGA" },
- { "Right Boost Mixer", "R2 Volume", "R2" },
-
- { "Left ADC", NULL, "Left Boost Mixer" },
-
- { "Left Boost Mixer", "AUXL Volume", "AUXL" },
- { "Left Boost Mixer", NULL, "Left Capture PGA" },
- { "Left Boost Mixer", "L2 Volume", "L2" },
-
- { "Right Capture PGA", NULL, "Right Input Mixer" },
- { "Left Capture PGA", NULL, "Left Input Mixer" },
-
- { "Right Input Mixer", "R2 Switch", "R2" },
- { "Right Input Mixer", "MicN Switch", "RIN" },
- { "Right Input Mixer", "MicP Switch", "RIP" },
-
- { "Left Input Mixer", "L2 Switch", "L2" },
- { "Left Input Mixer", "MicN Switch", "LIN" },
- { "Left Input Mixer", "MicP Switch", "LIP" },
-};
-
-static int eqmode_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int reg;
-
- reg = snd_soc_read(codec, WM8985_EQ1_LOW_SHELF);
- if (reg & WM8985_EQ3DMODE)
- ucontrol->value.integer.value[0] = 1;
- else
- ucontrol->value.integer.value[0] = 0;
-
- return 0;
-}
-
-static int eqmode_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int regpwr2, regpwr3;
- unsigned int reg_eq;
-
- if (ucontrol->value.integer.value[0] != 0
- && ucontrol->value.integer.value[0] != 1)
- return -EINVAL;
-
- reg_eq = snd_soc_read(codec, WM8985_EQ1_LOW_SHELF);
- switch ((reg_eq & WM8985_EQ3DMODE) >> WM8985_EQ3DMODE_SHIFT) {
- case 0:
- if (!ucontrol->value.integer.value[0])
- return 0;
- break;
- case 1:
- if (ucontrol->value.integer.value[0])
- return 0;
- break;
- }
-
- regpwr2 = snd_soc_read(codec, WM8985_POWER_MANAGEMENT_2);
- regpwr3 = snd_soc_read(codec, WM8985_POWER_MANAGEMENT_3);
- /* disable the DACs and ADCs */
- snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_2,
- WM8985_ADCENR_MASK | WM8985_ADCENL_MASK, 0);
- snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_3,
- WM8985_DACENR_MASK | WM8985_DACENL_MASK, 0);
- snd_soc_update_bits(codec, WM8985_ADDITIONAL_CONTROL,
- WM8985_M128ENB_MASK, WM8985_M128ENB);
- /* set the desired eqmode */
- snd_soc_update_bits(codec, WM8985_EQ1_LOW_SHELF,
- WM8985_EQ3DMODE_MASK,
- ucontrol->value.integer.value[0]
- << WM8985_EQ3DMODE_SHIFT);
- /* restore DAC/ADC configuration */
- snd_soc_write(codec, WM8985_POWER_MANAGEMENT_2, regpwr2);
- snd_soc_write(codec, WM8985_POWER_MANAGEMENT_3, regpwr3);
- return 0;
-}
-
-static int wm8985_reset(struct snd_soc_codec *codec)
-{
- return snd_soc_write(codec, WM8985_SOFTWARE_RESET, 0x0);
-}
-
-static int wm8985_dac_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
-
- return snd_soc_update_bits(codec, WM8985_DAC_CONTROL,
- WM8985_SOFTMUTE_MASK,
- !!mute << WM8985_SOFTMUTE_SHIFT);
-}
-
-static int wm8985_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec;
- u16 format, master, bcp, lrp;
-
- codec = dai->codec;
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- format = 0x2;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- format = 0x0;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- format = 0x1;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- case SND_SOC_DAIFMT_DSP_B:
- format = 0x3;
- break;
- default:
- dev_err(dai->dev, "Unknown dai format\n");
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, WM8985_AUDIO_INTERFACE,
- WM8985_FMT_MASK, format << WM8985_FMT_SHIFT);
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- master = 1;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- master = 0;
- break;
- default:
- dev_err(dai->dev, "Unknown master/slave configuration\n");
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
- WM8985_MS_MASK, master << WM8985_MS_SHIFT);
-
- /* frame inversion is not valid for dsp modes */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- case SND_SOC_DAIFMT_DSP_B:
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_IB_IF:
- case SND_SOC_DAIFMT_NB_IF:
- return -EINVAL;
- default:
- break;
- }
- break;
- default:
- break;
- }
-
- bcp = lrp = 0;
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- bcp = lrp = 1;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- bcp = 1;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- lrp = 1;
- break;
- default:
- dev_err(dai->dev, "Unknown polarity configuration\n");
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, WM8985_AUDIO_INTERFACE,
- WM8985_LRP_MASK, lrp << WM8985_LRP_SHIFT);
- snd_soc_update_bits(codec, WM8985_AUDIO_INTERFACE,
- WM8985_BCP_MASK, bcp << WM8985_BCP_SHIFT);
- return 0;
-}
-
-static int wm8985_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- int i;
- struct snd_soc_codec *codec;
- struct wm8985_priv *wm8985;
- u16 blen, srate_idx;
- unsigned int tmp;
- int srate_best;
-
- codec = dai->codec;
- wm8985 = snd_soc_codec_get_drvdata(codec);
-
- wm8985->bclk = snd_soc_params_to_bclk(params);
- if ((int)wm8985->bclk < 0)
- return wm8985->bclk;
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- blen = 0x0;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- blen = 0x1;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- blen = 0x2;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- blen = 0x3;
- break;
- default:
- dev_err(dai->dev, "Unsupported word length %u\n",
- params_format(params));
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, WM8985_AUDIO_INTERFACE,
- WM8985_WL_MASK, blen << WM8985_WL_SHIFT);
-
- /*
- * match to the nearest possible sample rate and rely
- * on the array index to configure the SR register
- */
- srate_idx = 0;
- srate_best = abs(srates[0] - params_rate(params));
- for (i = 1; i < ARRAY_SIZE(srates); ++i) {
- if (abs(srates[i] - params_rate(params)) >= srate_best)
- continue;
- srate_idx = i;
- srate_best = abs(srates[i] - params_rate(params));
- }
-
- dev_dbg(dai->dev, "Selected SRATE = %d\n", srates[srate_idx]);
- snd_soc_update_bits(codec, WM8985_ADDITIONAL_CONTROL,
- WM8985_SR_MASK, srate_idx << WM8985_SR_SHIFT);
-
- dev_dbg(dai->dev, "Target BCLK = %uHz\n", wm8985->bclk);
- dev_dbg(dai->dev, "SYSCLK = %uHz\n", wm8985->sysclk);
-
- for (i = 0; i < ARRAY_SIZE(fs_ratios); ++i) {
- if (wm8985->sysclk / params_rate(params)
- == fs_ratios[i].ratio)
- break;
- }
-
- if (i == ARRAY_SIZE(fs_ratios)) {
- dev_err(dai->dev, "Unable to configure MCLK ratio %u/%u\n",
- wm8985->sysclk, params_rate(params));
- return -EINVAL;
- }
-
- dev_dbg(dai->dev, "MCLK ratio = %dfs\n", fs_ratios[i].ratio);
- snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
- WM8985_MCLKDIV_MASK, i << WM8985_MCLKDIV_SHIFT);
-
- /* select the appropriate bclk divider */
- tmp = (wm8985->sysclk / fs_ratios[i].div) * 10;
- for (i = 0; i < ARRAY_SIZE(bclk_divs); ++i) {
- if (wm8985->bclk == tmp / bclk_divs[i])
- break;
- }
-
- if (i == ARRAY_SIZE(bclk_divs)) {
- dev_err(dai->dev, "No matching BCLK divider found\n");
- return -EINVAL;
- }
-
- dev_dbg(dai->dev, "BCLK div = %d\n", i);
- snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
- WM8985_BCLKDIV_MASK, i << WM8985_BCLKDIV_SHIFT);
- return 0;
-}
-
-struct pll_div {
- u32 div2:1;
- u32 n:4;
- u32 k:24;
-};
-
-#define FIXED_PLL_SIZE ((1ULL << 24) * 10)
-static int pll_factors(struct pll_div *pll_div, unsigned int target,
- unsigned int source)
-{
- u64 Kpart;
- unsigned long int K, Ndiv, Nmod;
-
- pll_div->div2 = 0;
- Ndiv = target / source;
- if (Ndiv < 6) {
- source >>= 1;
- pll_div->div2 = 1;
- Ndiv = target / source;
- }
-
- if (Ndiv < 6 || Ndiv > 12) {
- printk(KERN_ERR "%s: WM8985 N value is not within"
- " the recommended range: %lu\n", __func__, Ndiv);
- return -EINVAL;
- }
- pll_div->n = Ndiv;
-
- Nmod = target % source;
- Kpart = FIXED_PLL_SIZE * (u64)Nmod;
-
- do_div(Kpart, source);
-
- K = Kpart & 0xffffffff;
- if ((K % 10) >= 5)
- K += 5;
- K /= 10;
- pll_div->k = K;
-
- return 0;
-}
-
-static int wm8985_set_pll(struct snd_soc_dai *dai, int pll_id,
- int source, unsigned int freq_in,
- unsigned int freq_out)
-{
- int ret;
- struct snd_soc_codec *codec;
- struct pll_div pll_div;
-
- codec = dai->codec;
- if (freq_in && freq_out) {
- ret = pll_factors(&pll_div, freq_out * 4 * 2, freq_in);
- if (ret)
- return ret;
- }
-
- /* disable the PLL before reprogramming it */
- snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
- WM8985_PLLEN_MASK, 0);
-
- if (!freq_in || !freq_out)
- return 0;
-
- /* set PLLN and PRESCALE */
- snd_soc_write(codec, WM8985_PLL_N,
- (pll_div.div2 << WM8985_PLL_PRESCALE_SHIFT)
- | pll_div.n);
- /* set PLLK */
- snd_soc_write(codec, WM8985_PLL_K_3, pll_div.k & 0x1ff);
- snd_soc_write(codec, WM8985_PLL_K_2, (pll_div.k >> 9) & 0x1ff);
- snd_soc_write(codec, WM8985_PLL_K_1, (pll_div.k >> 18));
- /* set the source of the clock to be the PLL */
- snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
- WM8985_CLKSEL_MASK, WM8985_CLKSEL);
- /* enable the PLL */
- snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
- WM8985_PLLEN_MASK, WM8985_PLLEN);
- return 0;
-}
-
-static int wm8985_set_sysclk(struct snd_soc_dai *dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec;
- struct wm8985_priv *wm8985;
-
- codec = dai->codec;
- wm8985 = snd_soc_codec_get_drvdata(codec);
-
- switch (clk_id) {
- case WM8985_CLKSRC_MCLK:
- snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
- WM8985_CLKSEL_MASK, 0);
- snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
- WM8985_PLLEN_MASK, 0);
- break;
- case WM8985_CLKSRC_PLL:
- snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
- WM8985_CLKSEL_MASK, WM8985_CLKSEL);
- break;
- default:
- dev_err(dai->dev, "Unknown clock source %d\n", clk_id);
- return -EINVAL;
- }
-
- wm8985->sysclk = freq;
- return 0;
-}
-
-static int wm8985_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- int ret;
- struct wm8985_priv *wm8985;
-
- wm8985 = snd_soc_codec_get_drvdata(codec);
- switch (level) {
- case SND_SOC_BIAS_ON:
- case SND_SOC_BIAS_PREPARE:
- /* VMID at 75k */
- snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
- WM8985_VMIDSEL_MASK,
- 1 << WM8985_VMIDSEL_SHIFT);
- break;
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8985->supplies),
- wm8985->supplies);
- if (ret) {
- dev_err(codec->dev,
- "Failed to enable supplies: %d\n",
- ret);
- return ret;
- }
-
- regcache_sync(wm8985->regmap);
-
- /* enable anti-pop features */
- snd_soc_update_bits(codec, WM8985_OUT4_TO_ADC,
- WM8985_POBCTRL_MASK,
- WM8985_POBCTRL);
- /* enable thermal shutdown */
- snd_soc_update_bits(codec, WM8985_OUTPUT_CTRL0,
- WM8985_TSDEN_MASK, WM8985_TSDEN);
- snd_soc_update_bits(codec, WM8985_OUTPUT_CTRL0,
- WM8985_TSOPCTRL_MASK,
- WM8985_TSOPCTRL);
- /* enable BIASEN */
- snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
- WM8985_BIASEN_MASK, WM8985_BIASEN);
- /* VMID at 75k */
- snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
- WM8985_VMIDSEL_MASK,
- 1 << WM8985_VMIDSEL_SHIFT);
- msleep(500);
- /* disable anti-pop features */
- snd_soc_update_bits(codec, WM8985_OUT4_TO_ADC,
- WM8985_POBCTRL_MASK, 0);
- }
- /* VMID at 300k */
- snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
- WM8985_VMIDSEL_MASK,
- 2 << WM8985_VMIDSEL_SHIFT);
- break;
- case SND_SOC_BIAS_OFF:
- /* disable thermal shutdown */
- snd_soc_update_bits(codec, WM8985_OUTPUT_CTRL0,
- WM8985_TSOPCTRL_MASK, 0);
- snd_soc_update_bits(codec, WM8985_OUTPUT_CTRL0,
- WM8985_TSDEN_MASK, 0);
- /* disable VMIDSEL and BIASEN */
- snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
- WM8985_VMIDSEL_MASK | WM8985_BIASEN_MASK,
- 0);
- snd_soc_write(codec, WM8985_POWER_MANAGEMENT_1, 0);
- snd_soc_write(codec, WM8985_POWER_MANAGEMENT_2, 0);
- snd_soc_write(codec, WM8985_POWER_MANAGEMENT_3, 0);
-
- regcache_mark_dirty(wm8985->regmap);
-
- regulator_bulk_disable(ARRAY_SIZE(wm8985->supplies),
- wm8985->supplies);
- break;
- }
-
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int wm8985_suspend(struct snd_soc_codec *codec)
-{
- wm8985_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm8985_resume(struct snd_soc_codec *codec)
-{
- wm8985_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-#else
-#define wm8985_suspend NULL
-#define wm8985_resume NULL
-#endif
-
-static int wm8985_remove(struct snd_soc_codec *codec)
-{
- struct wm8985_priv *wm8985;
-
- wm8985 = snd_soc_codec_get_drvdata(codec);
- wm8985_set_bias_level(codec, SND_SOC_BIAS_OFF);
- regulator_bulk_free(ARRAY_SIZE(wm8985->supplies), wm8985->supplies);
- return 0;
-}
-
-static int wm8985_probe(struct snd_soc_codec *codec)
-{
- size_t i;
- struct wm8985_priv *wm8985;
- int ret;
-
- wm8985 = snd_soc_codec_get_drvdata(codec);
- codec->control_data = wm8985->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
- return ret;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm8985->supplies); i++)
- wm8985->supplies[i].supply = wm8985_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8985->supplies),
- wm8985->supplies);
- if (ret) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- return ret;
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8985->supplies),
- wm8985->supplies);
- if (ret) {
- dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
- goto err_reg_get;
- }
-
- ret = wm8985_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
- goto err_reg_enable;
- }
-
- /* latch volume update bits */
- for (i = 0; i < ARRAY_SIZE(volume_update_regs); ++i)
- snd_soc_update_bits(codec, volume_update_regs[i],
- 0x100, 0x100);
- /* enable BIASCUT */
- snd_soc_update_bits(codec, WM8985_BIAS_CTRL, WM8985_BIASCUT,
- WM8985_BIASCUT);
-
- wm8985_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-
-err_reg_enable:
- regulator_bulk_disable(ARRAY_SIZE(wm8985->supplies), wm8985->supplies);
-err_reg_get:
- regulator_bulk_free(ARRAY_SIZE(wm8985->supplies), wm8985->supplies);
- return ret;
-}
-
-static const struct snd_soc_dai_ops wm8985_dai_ops = {
- .digital_mute = wm8985_dac_mute,
- .hw_params = wm8985_hw_params,
- .set_fmt = wm8985_set_fmt,
- .set_sysclk = wm8985_set_sysclk,
- .set_pll = wm8985_set_pll
-};
-
-#define WM8985_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static struct snd_soc_dai_driver wm8985_dai = {
- .name = "wm8985-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = WM8985_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = WM8985_FORMATS,
- },
- .ops = &wm8985_dai_ops,
- .symmetric_rates = 1
-};
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8985 = {
- .probe = wm8985_probe,
- .remove = wm8985_remove,
- .suspend = wm8985_suspend,
- .resume = wm8985_resume,
- .set_bias_level = wm8985_set_bias_level,
-
- .controls = wm8985_snd_controls,
- .num_controls = ARRAY_SIZE(wm8985_snd_controls),
- .dapm_widgets = wm8985_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8985_dapm_widgets),
- .dapm_routes = wm8985_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm8985_dapm_routes),
-};
-
-static const struct regmap_config wm8985_regmap = {
- .reg_bits = 7,
- .val_bits = 9,
-
- .max_register = WM8985_MAX_REGISTER,
- .writeable_reg = wm8985_writeable,
-
- .cache_type = REGCACHE_RBTREE,
- .reg_defaults = wm8985_reg_defaults,
- .num_reg_defaults = ARRAY_SIZE(wm8985_reg_defaults),
-};
-
-#if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8985_spi_probe(struct spi_device *spi)
-{
- struct wm8985_priv *wm8985;
- int ret;
-
- wm8985 = devm_kzalloc(&spi->dev, sizeof *wm8985, GFP_KERNEL);
- if (!wm8985)
- return -ENOMEM;
-
- spi_set_drvdata(spi, wm8985);
-
- wm8985->regmap = regmap_init_spi(spi, &wm8985_regmap);
- if (IS_ERR(wm8985->regmap)) {
- ret = PTR_ERR(wm8985->regmap);
- dev_err(&spi->dev, "Failed to allocate register map: %d\n",
- ret);
- goto err;
- }
-
- ret = snd_soc_register_codec(&spi->dev,
- &soc_codec_dev_wm8985, &wm8985_dai, 1);
- if (ret != 0)
- goto err;
-
- return 0;
-
-err:
- regmap_exit(wm8985->regmap);
- return ret;
-}
-
-static int __devexit wm8985_spi_remove(struct spi_device *spi)
-{
- struct wm8985_priv *wm8985 = spi_get_drvdata(spi);
-
- snd_soc_unregister_codec(&spi->dev);
- regmap_exit(wm8985->regmap);
-
- return 0;
-}
-
-static struct spi_driver wm8985_spi_driver = {
- .driver = {
- .name = "wm8985",
- .owner = THIS_MODULE,
- },
- .probe = wm8985_spi_probe,
- .remove = __devexit_p(wm8985_spi_remove)
-};
-#endif
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8985_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8985_priv *wm8985;
- int ret;
-
- wm8985 = devm_kzalloc(&i2c->dev, sizeof *wm8985, GFP_KERNEL);
- if (!wm8985)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm8985);
-
- wm8985->regmap = regmap_init_i2c(i2c, &wm8985_regmap);
- if (IS_ERR(wm8985->regmap)) {
- ret = PTR_ERR(wm8985->regmap);
- dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
- ret);
- goto err;
- }
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8985, &wm8985_dai, 1);
- if (ret != 0)
- goto err;
-
- return 0;
-
-err:
- regmap_exit(wm8985->regmap);
- return ret;
-}
-
-static __devexit int wm8985_i2c_remove(struct i2c_client *i2c)
-{
- struct wm8985_priv *wm8985 = i2c_get_clientdata(i2c);
-
- snd_soc_unregister_codec(&i2c->dev);
- regmap_exit(wm8985->regmap);
-
- return 0;
-}
-
-static const struct i2c_device_id wm8985_i2c_id[] = {
- { "wm8985", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8985_i2c_id);
-
-static struct i2c_driver wm8985_i2c_driver = {
- .driver = {
- .name = "wm8985",
- .owner = THIS_MODULE,
- },
- .probe = wm8985_i2c_probe,
- .remove = __devexit_p(wm8985_i2c_remove),
- .id_table = wm8985_i2c_id
-};
-#endif
-
-static int __init wm8985_modinit(void)
-{
- int ret = 0;
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&wm8985_i2c_driver);
- if (ret) {
- printk(KERN_ERR "Failed to register wm8985 I2C driver: %d\n",
- ret);
- }
-#endif
-#if defined(CONFIG_SPI_MASTER)
- ret = spi_register_driver(&wm8985_spi_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8985 SPI driver: %d\n",
- ret);
- }
-#endif
- return ret;
-}
-module_init(wm8985_modinit);
-
-static void __exit wm8985_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&wm8985_i2c_driver);
-#endif
-#if defined(CONFIG_SPI_MASTER)
- spi_unregister_driver(&wm8985_spi_driver);
-#endif
-}
-module_exit(wm8985_exit);
-
-MODULE_DESCRIPTION("ASoC WM8985 driver");
-MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8985.h b/ANDROID_3.4.5/sound/soc/codecs/wm8985.h
deleted file mode 100644
index 2e71ff50..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8985.h
+++ /dev/null
@@ -1,1045 +0,0 @@
-/*
- * wm8985.h -- WM8985 ASoC driver
- *
- * Copyright 2010 Wolfson Microelectronics plc
- *
- * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8985_H
-#define _WM8985_H
-
-#define WM8985_SOFTWARE_RESET 0x00
-#define WM8985_POWER_MANAGEMENT_1 0x01
-#define WM8985_POWER_MANAGEMENT_2 0x02
-#define WM8985_POWER_MANAGEMENT_3 0x03
-#define WM8985_AUDIO_INTERFACE 0x04
-#define WM8985_COMPANDING_CONTROL 0x05
-#define WM8985_CLOCK_GEN_CONTROL 0x06
-#define WM8985_ADDITIONAL_CONTROL 0x07
-#define WM8985_GPIO_CONTROL 0x08
-#define WM8985_JACK_DETECT_CONTROL_1 0x09
-#define WM8985_DAC_CONTROL 0x0A
-#define WM8985_LEFT_DAC_DIGITAL_VOL 0x0B
-#define WM8985_RIGHT_DAC_DIGITAL_VOL 0x0C
-#define WM8985_JACK_DETECT_CONTROL_2 0x0D
-#define WM8985_ADC_CONTROL 0x0E
-#define WM8985_LEFT_ADC_DIGITAL_VOL 0x0F
-#define WM8985_RIGHT_ADC_DIGITAL_VOL 0x10
-#define WM8985_EQ1_LOW_SHELF 0x12
-#define WM8985_EQ2_PEAK_1 0x13
-#define WM8985_EQ3_PEAK_2 0x14
-#define WM8985_EQ4_PEAK_3 0x15
-#define WM8985_EQ5_HIGH_SHELF 0x16
-#define WM8985_DAC_LIMITER_1 0x18
-#define WM8985_DAC_LIMITER_2 0x19
-#define WM8985_NOTCH_FILTER_1 0x1B
-#define WM8985_NOTCH_FILTER_2 0x1C
-#define WM8985_NOTCH_FILTER_3 0x1D
-#define WM8985_NOTCH_FILTER_4 0x1E
-#define WM8985_ALC_CONTROL_1 0x20
-#define WM8985_ALC_CONTROL_2 0x21
-#define WM8985_ALC_CONTROL_3 0x22
-#define WM8985_NOISE_GATE 0x23
-#define WM8985_PLL_N 0x24
-#define WM8985_PLL_K_1 0x25
-#define WM8985_PLL_K_2 0x26
-#define WM8985_PLL_K_3 0x27
-#define WM8985_3D_CONTROL 0x29
-#define WM8985_OUT4_TO_ADC 0x2A
-#define WM8985_BEEP_CONTROL 0x2B
-#define WM8985_INPUT_CTRL 0x2C
-#define WM8985_LEFT_INP_PGA_GAIN_CTRL 0x2D
-#define WM8985_RIGHT_INP_PGA_GAIN_CTRL 0x2E
-#define WM8985_LEFT_ADC_BOOST_CTRL 0x2F
-#define WM8985_RIGHT_ADC_BOOST_CTRL 0x30
-#define WM8985_OUTPUT_CTRL0 0x31
-#define WM8985_LEFT_MIXER_CTRL 0x32
-#define WM8985_RIGHT_MIXER_CTRL 0x33
-#define WM8985_LOUT1_HP_VOLUME_CTRL 0x34
-#define WM8985_ROUT1_HP_VOLUME_CTRL 0x35
-#define WM8985_LOUT2_SPK_VOLUME_CTRL 0x36
-#define WM8985_ROUT2_SPK_VOLUME_CTRL 0x37
-#define WM8985_OUT3_MIXER_CTRL 0x38
-#define WM8985_OUT4_MONO_MIX_CTRL 0x39
-#define WM8985_OUTPUT_CTRL1 0x3C
-#define WM8985_BIAS_CTRL 0x3D
-
-#define WM8985_REGISTER_COUNT 59
-#define WM8985_MAX_REGISTER 0x3F
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - Software Reset
- */
-#define WM8985_SOFTWARE_RESET_MASK 0x01FF /* SOFTWARE_RESET - [8:0] */
-#define WM8985_SOFTWARE_RESET_SHIFT 0 /* SOFTWARE_RESET - [8:0] */
-#define WM8985_SOFTWARE_RESET_WIDTH 9 /* SOFTWARE_RESET - [8:0] */
-
-/*
- * R1 (0x01) - Power management 1
- */
-#define WM8985_OUT4MIXEN 0x0080 /* OUT4MIXEN */
-#define WM8985_OUT4MIXEN_MASK 0x0080 /* OUT4MIXEN */
-#define WM8985_OUT4MIXEN_SHIFT 7 /* OUT4MIXEN */
-#define WM8985_OUT4MIXEN_WIDTH 1 /* OUT4MIXEN */
-#define WM8985_OUT3MIXEN 0x0040 /* OUT3MIXEN */
-#define WM8985_OUT3MIXEN_MASK 0x0040 /* OUT3MIXEN */
-#define WM8985_OUT3MIXEN_SHIFT 6 /* OUT3MIXEN */
-#define WM8985_OUT3MIXEN_WIDTH 1 /* OUT3MIXEN */
-#define WM8985_PLLEN 0x0020 /* PLLEN */
-#define WM8985_PLLEN_MASK 0x0020 /* PLLEN */
-#define WM8985_PLLEN_SHIFT 5 /* PLLEN */
-#define WM8985_PLLEN_WIDTH 1 /* PLLEN */
-#define WM8985_MICBEN 0x0010 /* MICBEN */
-#define WM8985_MICBEN_MASK 0x0010 /* MICBEN */
-#define WM8985_MICBEN_SHIFT 4 /* MICBEN */
-#define WM8985_MICBEN_WIDTH 1 /* MICBEN */
-#define WM8985_BIASEN 0x0008 /* BIASEN */
-#define WM8985_BIASEN_MASK 0x0008 /* BIASEN */
-#define WM8985_BIASEN_SHIFT 3 /* BIASEN */
-#define WM8985_BIASEN_WIDTH 1 /* BIASEN */
-#define WM8985_BUFIOEN 0x0004 /* BUFIOEN */
-#define WM8985_BUFIOEN_MASK 0x0004 /* BUFIOEN */
-#define WM8985_BUFIOEN_SHIFT 2 /* BUFIOEN */
-#define WM8985_BUFIOEN_WIDTH 1 /* BUFIOEN */
-#define WM8985_VMIDSEL 0x0003 /* VMIDSEL */
-#define WM8985_VMIDSEL_MASK 0x0003 /* VMIDSEL - [1:0] */
-#define WM8985_VMIDSEL_SHIFT 0 /* VMIDSEL - [1:0] */
-#define WM8985_VMIDSEL_WIDTH 2 /* VMIDSEL - [1:0] */
-
-/*
- * R2 (0x02) - Power management 2
- */
-#define WM8985_ROUT1EN 0x0100 /* ROUT1EN */
-#define WM8985_ROUT1EN_MASK 0x0100 /* ROUT1EN */
-#define WM8985_ROUT1EN_SHIFT 8 /* ROUT1EN */
-#define WM8985_ROUT1EN_WIDTH 1 /* ROUT1EN */
-#define WM8985_LOUT1EN 0x0080 /* LOUT1EN */
-#define WM8985_LOUT1EN_MASK 0x0080 /* LOUT1EN */
-#define WM8985_LOUT1EN_SHIFT 7 /* LOUT1EN */
-#define WM8985_LOUT1EN_WIDTH 1 /* LOUT1EN */
-#define WM8985_SLEEP 0x0040 /* SLEEP */
-#define WM8985_SLEEP_MASK 0x0040 /* SLEEP */
-#define WM8985_SLEEP_SHIFT 6 /* SLEEP */
-#define WM8985_SLEEP_WIDTH 1 /* SLEEP */
-#define WM8985_BOOSTENR 0x0020 /* BOOSTENR */
-#define WM8985_BOOSTENR_MASK 0x0020 /* BOOSTENR */
-#define WM8985_BOOSTENR_SHIFT 5 /* BOOSTENR */
-#define WM8985_BOOSTENR_WIDTH 1 /* BOOSTENR */
-#define WM8985_BOOSTENL 0x0010 /* BOOSTENL */
-#define WM8985_BOOSTENL_MASK 0x0010 /* BOOSTENL */
-#define WM8985_BOOSTENL_SHIFT 4 /* BOOSTENL */
-#define WM8985_BOOSTENL_WIDTH 1 /* BOOSTENL */
-#define WM8985_INPGAENR 0x0008 /* INPGAENR */
-#define WM8985_INPGAENR_MASK 0x0008 /* INPGAENR */
-#define WM8985_INPGAENR_SHIFT 3 /* INPGAENR */
-#define WM8985_INPGAENR_WIDTH 1 /* INPGAENR */
-#define WM8985_INPPGAENL 0x0004 /* INPPGAENL */
-#define WM8985_INPPGAENL_MASK 0x0004 /* INPPGAENL */
-#define WM8985_INPPGAENL_SHIFT 2 /* INPPGAENL */
-#define WM8985_INPPGAENL_WIDTH 1 /* INPPGAENL */
-#define WM8985_ADCENR 0x0002 /* ADCENR */
-#define WM8985_ADCENR_MASK 0x0002 /* ADCENR */
-#define WM8985_ADCENR_SHIFT 1 /* ADCENR */
-#define WM8985_ADCENR_WIDTH 1 /* ADCENR */
-#define WM8985_ADCENL 0x0001 /* ADCENL */
-#define WM8985_ADCENL_MASK 0x0001 /* ADCENL */
-#define WM8985_ADCENL_SHIFT 0 /* ADCENL */
-#define WM8985_ADCENL_WIDTH 1 /* ADCENL */
-
-/*
- * R3 (0x03) - Power management 3
- */
-#define WM8985_OUT4EN 0x0100 /* OUT4EN */
-#define WM8985_OUT4EN_MASK 0x0100 /* OUT4EN */
-#define WM8985_OUT4EN_SHIFT 8 /* OUT4EN */
-#define WM8985_OUT4EN_WIDTH 1 /* OUT4EN */
-#define WM8985_OUT3EN 0x0080 /* OUT3EN */
-#define WM8985_OUT3EN_MASK 0x0080 /* OUT3EN */
-#define WM8985_OUT3EN_SHIFT 7 /* OUT3EN */
-#define WM8985_OUT3EN_WIDTH 1 /* OUT3EN */
-#define WM8985_ROUT2EN 0x0040 /* ROUT2EN */
-#define WM8985_ROUT2EN_MASK 0x0040 /* ROUT2EN */
-#define WM8985_ROUT2EN_SHIFT 6 /* ROUT2EN */
-#define WM8985_ROUT2EN_WIDTH 1 /* ROUT2EN */
-#define WM8985_LOUT2EN 0x0020 /* LOUT2EN */
-#define WM8985_LOUT2EN_MASK 0x0020 /* LOUT2EN */
-#define WM8985_LOUT2EN_SHIFT 5 /* LOUT2EN */
-#define WM8985_LOUT2EN_WIDTH 1 /* LOUT2EN */
-#define WM8985_RMIXEN 0x0008 /* RMIXEN */
-#define WM8985_RMIXEN_MASK 0x0008 /* RMIXEN */
-#define WM8985_RMIXEN_SHIFT 3 /* RMIXEN */
-#define WM8985_RMIXEN_WIDTH 1 /* RMIXEN */
-#define WM8985_LMIXEN 0x0004 /* LMIXEN */
-#define WM8985_LMIXEN_MASK 0x0004 /* LMIXEN */
-#define WM8985_LMIXEN_SHIFT 2 /* LMIXEN */
-#define WM8985_LMIXEN_WIDTH 1 /* LMIXEN */
-#define WM8985_DACENR 0x0002 /* DACENR */
-#define WM8985_DACENR_MASK 0x0002 /* DACENR */
-#define WM8985_DACENR_SHIFT 1 /* DACENR */
-#define WM8985_DACENR_WIDTH 1 /* DACENR */
-#define WM8985_DACENL 0x0001 /* DACENL */
-#define WM8985_DACENL_MASK 0x0001 /* DACENL */
-#define WM8985_DACENL_SHIFT 0 /* DACENL */
-#define WM8985_DACENL_WIDTH 1 /* DACENL */
-
-/*
- * R4 (0x04) - Audio Interface
- */
-#define WM8985_BCP 0x0100 /* BCP */
-#define WM8985_BCP_MASK 0x0100 /* BCP */
-#define WM8985_BCP_SHIFT 8 /* BCP */
-#define WM8985_BCP_WIDTH 1 /* BCP */
-#define WM8985_LRP 0x0080 /* LRP */
-#define WM8985_LRP_MASK 0x0080 /* LRP */
-#define WM8985_LRP_SHIFT 7 /* LRP */
-#define WM8985_LRP_WIDTH 1 /* LRP */
-#define WM8985_WL_MASK 0x0060 /* WL - [6:5] */
-#define WM8985_WL_SHIFT 5 /* WL - [6:5] */
-#define WM8985_WL_WIDTH 2 /* WL - [6:5] */
-#define WM8985_FMT_MASK 0x0018 /* FMT - [4:3] */
-#define WM8985_FMT_SHIFT 3 /* FMT - [4:3] */
-#define WM8985_FMT_WIDTH 2 /* FMT - [4:3] */
-#define WM8985_DLRSWAP 0x0004 /* DLRSWAP */
-#define WM8985_DLRSWAP_MASK 0x0004 /* DLRSWAP */
-#define WM8985_DLRSWAP_SHIFT 2 /* DLRSWAP */
-#define WM8985_DLRSWAP_WIDTH 1 /* DLRSWAP */
-#define WM8985_ALRSWAP 0x0002 /* ALRSWAP */
-#define WM8985_ALRSWAP_MASK 0x0002 /* ALRSWAP */
-#define WM8985_ALRSWAP_SHIFT 1 /* ALRSWAP */
-#define WM8985_ALRSWAP_WIDTH 1 /* ALRSWAP */
-#define WM8985_MONO 0x0001 /* MONO */
-#define WM8985_MONO_MASK 0x0001 /* MONO */
-#define WM8985_MONO_SHIFT 0 /* MONO */
-#define WM8985_MONO_WIDTH 1 /* MONO */
-
-/*
- * R5 (0x05) - Companding control
- */
-#define WM8985_WL8 0x0020 /* WL8 */
-#define WM8985_WL8_MASK 0x0020 /* WL8 */
-#define WM8985_WL8_SHIFT 5 /* WL8 */
-#define WM8985_WL8_WIDTH 1 /* WL8 */
-#define WM8985_DAC_COMP_MASK 0x0018 /* DAC_COMP - [4:3] */
-#define WM8985_DAC_COMP_SHIFT 3 /* DAC_COMP - [4:3] */
-#define WM8985_DAC_COMP_WIDTH 2 /* DAC_COMP - [4:3] */
-#define WM8985_ADC_COMP_MASK 0x0006 /* ADC_COMP - [2:1] */
-#define WM8985_ADC_COMP_SHIFT 1 /* ADC_COMP - [2:1] */
-#define WM8985_ADC_COMP_WIDTH 2 /* ADC_COMP - [2:1] */
-#define WM8985_LOOPBACK 0x0001 /* LOOPBACK */
-#define WM8985_LOOPBACK_MASK 0x0001 /* LOOPBACK */
-#define WM8985_LOOPBACK_SHIFT 0 /* LOOPBACK */
-#define WM8985_LOOPBACK_WIDTH 1 /* LOOPBACK */
-
-/*
- * R6 (0x06) - Clock Gen control
- */
-#define WM8985_CLKSEL 0x0100 /* CLKSEL */
-#define WM8985_CLKSEL_MASK 0x0100 /* CLKSEL */
-#define WM8985_CLKSEL_SHIFT 8 /* CLKSEL */
-#define WM8985_CLKSEL_WIDTH 1 /* CLKSEL */
-#define WM8985_MCLKDIV_MASK 0x00E0 /* MCLKDIV - [7:5] */
-#define WM8985_MCLKDIV_SHIFT 5 /* MCLKDIV - [7:5] */
-#define WM8985_MCLKDIV_WIDTH 3 /* MCLKDIV - [7:5] */
-#define WM8985_BCLKDIV_MASK 0x001C /* BCLKDIV - [4:2] */
-#define WM8985_BCLKDIV_SHIFT 2 /* BCLKDIV - [4:2] */
-#define WM8985_BCLKDIV_WIDTH 3 /* BCLKDIV - [4:2] */
-#define WM8985_MS 0x0001 /* MS */
-#define WM8985_MS_MASK 0x0001 /* MS */
-#define WM8985_MS_SHIFT 0 /* MS */
-#define WM8985_MS_WIDTH 1 /* MS */
-
-/*
- * R7 (0x07) - Additional control
- */
-#define WM8985_M128ENB 0x0100 /* M128ENB */
-#define WM8985_M128ENB_MASK 0x0100 /* M128ENB */
-#define WM8985_M128ENB_SHIFT 8 /* M128ENB */
-#define WM8985_M128ENB_WIDTH 1 /* M128ENB */
-#define WM8985_DCLKDIV_MASK 0x00F0 /* DCLKDIV - [7:4] */
-#define WM8985_DCLKDIV_SHIFT 4 /* DCLKDIV - [7:4] */
-#define WM8985_DCLKDIV_WIDTH 4 /* DCLKDIV - [7:4] */
-#define WM8985_SR_MASK 0x000E /* SR - [3:1] */
-#define WM8985_SR_SHIFT 1 /* SR - [3:1] */
-#define WM8985_SR_WIDTH 3 /* SR - [3:1] */
-#define WM8985_SLOWCLKEN 0x0001 /* SLOWCLKEN */
-#define WM8985_SLOWCLKEN_MASK 0x0001 /* SLOWCLKEN */
-#define WM8985_SLOWCLKEN_SHIFT 0 /* SLOWCLKEN */
-#define WM8985_SLOWCLKEN_WIDTH 1 /* SLOWCLKEN */
-
-/*
- * R8 (0x08) - GPIO Control
- */
-#define WM8985_GPIO1GP 0x0100 /* GPIO1GP */
-#define WM8985_GPIO1GP_MASK 0x0100 /* GPIO1GP */
-#define WM8985_GPIO1GP_SHIFT 8 /* GPIO1GP */
-#define WM8985_GPIO1GP_WIDTH 1 /* GPIO1GP */
-#define WM8985_GPIO1GPU 0x0080 /* GPIO1GPU */
-#define WM8985_GPIO1GPU_MASK 0x0080 /* GPIO1GPU */
-#define WM8985_GPIO1GPU_SHIFT 7 /* GPIO1GPU */
-#define WM8985_GPIO1GPU_WIDTH 1 /* GPIO1GPU */
-#define WM8985_GPIO1GPD 0x0040 /* GPIO1GPD */
-#define WM8985_GPIO1GPD_MASK 0x0040 /* GPIO1GPD */
-#define WM8985_GPIO1GPD_SHIFT 6 /* GPIO1GPD */
-#define WM8985_GPIO1GPD_WIDTH 1 /* GPIO1GPD */
-#define WM8985_GPIO1POL 0x0008 /* GPIO1POL */
-#define WM8985_GPIO1POL_MASK 0x0008 /* GPIO1POL */
-#define WM8985_GPIO1POL_SHIFT 3 /* GPIO1POL */
-#define WM8985_GPIO1POL_WIDTH 1 /* GPIO1POL */
-#define WM8985_GPIO1SEL_MASK 0x0007 /* GPIO1SEL - [2:0] */
-#define WM8985_GPIO1SEL_SHIFT 0 /* GPIO1SEL - [2:0] */
-#define WM8985_GPIO1SEL_WIDTH 3 /* GPIO1SEL - [2:0] */
-
-/*
- * R9 (0x09) - Jack Detect Control 1
- */
-#define WM8985_JD_EN 0x0040 /* JD_EN */
-#define WM8985_JD_EN_MASK 0x0040 /* JD_EN */
-#define WM8985_JD_EN_SHIFT 6 /* JD_EN */
-#define WM8985_JD_EN_WIDTH 1 /* JD_EN */
-#define WM8985_JD_SEL_MASK 0x0030 /* JD_SEL - [5:4] */
-#define WM8985_JD_SEL_SHIFT 4 /* JD_SEL - [5:4] */
-#define WM8985_JD_SEL_WIDTH 2 /* JD_SEL - [5:4] */
-
-/*
- * R10 (0x0A) - DAC Control
- */
-#define WM8985_SOFTMUTE 0x0040 /* SOFTMUTE */
-#define WM8985_SOFTMUTE_MASK 0x0040 /* SOFTMUTE */
-#define WM8985_SOFTMUTE_SHIFT 6 /* SOFTMUTE */
-#define WM8985_SOFTMUTE_WIDTH 1 /* SOFTMUTE */
-#define WM8985_DACOSR128 0x0008 /* DACOSR128 */
-#define WM8985_DACOSR128_MASK 0x0008 /* DACOSR128 */
-#define WM8985_DACOSR128_SHIFT 3 /* DACOSR128 */
-#define WM8985_DACOSR128_WIDTH 1 /* DACOSR128 */
-#define WM8985_AMUTE 0x0004 /* AMUTE */
-#define WM8985_AMUTE_MASK 0x0004 /* AMUTE */
-#define WM8985_AMUTE_SHIFT 2 /* AMUTE */
-#define WM8985_AMUTE_WIDTH 1 /* AMUTE */
-#define WM8985_DACPOLR 0x0002 /* DACPOLR */
-#define WM8985_DACPOLR_MASK 0x0002 /* DACPOLR */
-#define WM8985_DACPOLR_SHIFT 1 /* DACPOLR */
-#define WM8985_DACPOLR_WIDTH 1 /* DACPOLR */
-#define WM8985_DACPOLL 0x0001 /* DACPOLL */
-#define WM8985_DACPOLL_MASK 0x0001 /* DACPOLL */
-#define WM8985_DACPOLL_SHIFT 0 /* DACPOLL */
-#define WM8985_DACPOLL_WIDTH 1 /* DACPOLL */
-
-/*
- * R11 (0x0B) - Left DAC digital Vol
- */
-#define WM8985_DACVU 0x0100 /* DACVU */
-#define WM8985_DACVU_MASK 0x0100 /* DACVU */
-#define WM8985_DACVU_SHIFT 8 /* DACVU */
-#define WM8985_DACVU_WIDTH 1 /* DACVU */
-#define WM8985_DACVOLL_MASK 0x00FF /* DACVOLL - [7:0] */
-#define WM8985_DACVOLL_SHIFT 0 /* DACVOLL - [7:0] */
-#define WM8985_DACVOLL_WIDTH 8 /* DACVOLL - [7:0] */
-
-/*
- * R12 (0x0C) - Right DAC digital vol
- */
-#define WM8985_DACVU 0x0100 /* DACVU */
-#define WM8985_DACVU_MASK 0x0100 /* DACVU */
-#define WM8985_DACVU_SHIFT 8 /* DACVU */
-#define WM8985_DACVU_WIDTH 1 /* DACVU */
-#define WM8985_DACVOLR_MASK 0x00FF /* DACVOLR - [7:0] */
-#define WM8985_DACVOLR_SHIFT 0 /* DACVOLR - [7:0] */
-#define WM8985_DACVOLR_WIDTH 8 /* DACVOLR - [7:0] */
-
-/*
- * R13 (0x0D) - Jack Detect Control 2
- */
-#define WM8985_JD_EN1_MASK 0x00F0 /* JD_EN1 - [7:4] */
-#define WM8985_JD_EN1_SHIFT 4 /* JD_EN1 - [7:4] */
-#define WM8985_JD_EN1_WIDTH 4 /* JD_EN1 - [7:4] */
-#define WM8985_JD_EN0_MASK 0x000F /* JD_EN0 - [3:0] */
-#define WM8985_JD_EN0_SHIFT 0 /* JD_EN0 - [3:0] */
-#define WM8985_JD_EN0_WIDTH 4 /* JD_EN0 - [3:0] */
-
-/*
- * R14 (0x0E) - ADC Control
- */
-#define WM8985_HPFEN 0x0100 /* HPFEN */
-#define WM8985_HPFEN_MASK 0x0100 /* HPFEN */
-#define WM8985_HPFEN_SHIFT 8 /* HPFEN */
-#define WM8985_HPFEN_WIDTH 1 /* HPFEN */
-#define WM8985_HPFAPP 0x0080 /* HPFAPP */
-#define WM8985_HPFAPP_MASK 0x0080 /* HPFAPP */
-#define WM8985_HPFAPP_SHIFT 7 /* HPFAPP */
-#define WM8985_HPFAPP_WIDTH 1 /* HPFAPP */
-#define WM8985_HPFCUT_MASK 0x0070 /* HPFCUT - [6:4] */
-#define WM8985_HPFCUT_SHIFT 4 /* HPFCUT - [6:4] */
-#define WM8985_HPFCUT_WIDTH 3 /* HPFCUT - [6:4] */
-#define WM8985_ADCOSR128 0x0008 /* ADCOSR128 */
-#define WM8985_ADCOSR128_MASK 0x0008 /* ADCOSR128 */
-#define WM8985_ADCOSR128_SHIFT 3 /* ADCOSR128 */
-#define WM8985_ADCOSR128_WIDTH 1 /* ADCOSR128 */
-#define WM8985_ADCRPOL 0x0002 /* ADCRPOL */
-#define WM8985_ADCRPOL_MASK 0x0002 /* ADCRPOL */
-#define WM8985_ADCRPOL_SHIFT 1 /* ADCRPOL */
-#define WM8985_ADCRPOL_WIDTH 1 /* ADCRPOL */
-#define WM8985_ADCLPOL 0x0001 /* ADCLPOL */
-#define WM8985_ADCLPOL_MASK 0x0001 /* ADCLPOL */
-#define WM8985_ADCLPOL_SHIFT 0 /* ADCLPOL */
-#define WM8985_ADCLPOL_WIDTH 1 /* ADCLPOL */
-
-/*
- * R15 (0x0F) - Left ADC Digital Vol
- */
-#define WM8985_ADCVU 0x0100 /* ADCVU */
-#define WM8985_ADCVU_MASK 0x0100 /* ADCVU */
-#define WM8985_ADCVU_SHIFT 8 /* ADCVU */
-#define WM8985_ADCVU_WIDTH 1 /* ADCVU */
-#define WM8985_ADCVOLL_MASK 0x00FF /* ADCVOLL - [7:0] */
-#define WM8985_ADCVOLL_SHIFT 0 /* ADCVOLL - [7:0] */
-#define WM8985_ADCVOLL_WIDTH 8 /* ADCVOLL - [7:0] */
-
-/*
- * R16 (0x10) - Right ADC Digital Vol
- */
-#define WM8985_ADCVU 0x0100 /* ADCVU */
-#define WM8985_ADCVU_MASK 0x0100 /* ADCVU */
-#define WM8985_ADCVU_SHIFT 8 /* ADCVU */
-#define WM8985_ADCVU_WIDTH 1 /* ADCVU */
-#define WM8985_ADCVOLR_MASK 0x00FF /* ADCVOLR - [7:0] */
-#define WM8985_ADCVOLR_SHIFT 0 /* ADCVOLR - [7:0] */
-#define WM8985_ADCVOLR_WIDTH 8 /* ADCVOLR - [7:0] */
-
-/*
- * R18 (0x12) - EQ1 - low shelf
- */
-#define WM8985_EQ3DMODE 0x0100 /* EQ3DMODE */
-#define WM8985_EQ3DMODE_MASK 0x0100 /* EQ3DMODE */
-#define WM8985_EQ3DMODE_SHIFT 8 /* EQ3DMODE */
-#define WM8985_EQ3DMODE_WIDTH 1 /* EQ3DMODE */
-#define WM8985_EQ1C_MASK 0x0060 /* EQ1C - [6:5] */
-#define WM8985_EQ1C_SHIFT 5 /* EQ1C - [6:5] */
-#define WM8985_EQ1C_WIDTH 2 /* EQ1C - [6:5] */
-#define WM8985_EQ1G_MASK 0x001F /* EQ1G - [4:0] */
-#define WM8985_EQ1G_SHIFT 0 /* EQ1G - [4:0] */
-#define WM8985_EQ1G_WIDTH 5 /* EQ1G - [4:0] */
-
-/*
- * R19 (0x13) - EQ2 - peak 1
- */
-#define WM8985_EQ2BW 0x0100 /* EQ2BW */
-#define WM8985_EQ2BW_MASK 0x0100 /* EQ2BW */
-#define WM8985_EQ2BW_SHIFT 8 /* EQ2BW */
-#define WM8985_EQ2BW_WIDTH 1 /* EQ2BW */
-#define WM8985_EQ2C_MASK 0x0060 /* EQ2C - [6:5] */
-#define WM8985_EQ2C_SHIFT 5 /* EQ2C - [6:5] */
-#define WM8985_EQ2C_WIDTH 2 /* EQ2C - [6:5] */
-#define WM8985_EQ2G_MASK 0x001F /* EQ2G - [4:0] */
-#define WM8985_EQ2G_SHIFT 0 /* EQ2G - [4:0] */
-#define WM8985_EQ2G_WIDTH 5 /* EQ2G - [4:0] */
-
-/*
- * R20 (0x14) - EQ3 - peak 2
- */
-#define WM8985_EQ3BW 0x0100 /* EQ3BW */
-#define WM8985_EQ3BW_MASK 0x0100 /* EQ3BW */
-#define WM8985_EQ3BW_SHIFT 8 /* EQ3BW */
-#define WM8985_EQ3BW_WIDTH 1 /* EQ3BW */
-#define WM8985_EQ3C_MASK 0x0060 /* EQ3C - [6:5] */
-#define WM8985_EQ3C_SHIFT 5 /* EQ3C - [6:5] */
-#define WM8985_EQ3C_WIDTH 2 /* EQ3C - [6:5] */
-#define WM8985_EQ3G_MASK 0x001F /* EQ3G - [4:0] */
-#define WM8985_EQ3G_SHIFT 0 /* EQ3G - [4:0] */
-#define WM8985_EQ3G_WIDTH 5 /* EQ3G - [4:0] */
-
-/*
- * R21 (0x15) - EQ4 - peak 3
- */
-#define WM8985_EQ4BW 0x0100 /* EQ4BW */
-#define WM8985_EQ4BW_MASK 0x0100 /* EQ4BW */
-#define WM8985_EQ4BW_SHIFT 8 /* EQ4BW */
-#define WM8985_EQ4BW_WIDTH 1 /* EQ4BW */
-#define WM8985_EQ4C_MASK 0x0060 /* EQ4C - [6:5] */
-#define WM8985_EQ4C_SHIFT 5 /* EQ4C - [6:5] */
-#define WM8985_EQ4C_WIDTH 2 /* EQ4C - [6:5] */
-#define WM8985_EQ4G_MASK 0x001F /* EQ4G - [4:0] */
-#define WM8985_EQ4G_SHIFT 0 /* EQ4G - [4:0] */
-#define WM8985_EQ4G_WIDTH 5 /* EQ4G - [4:0] */
-
-/*
- * R22 (0x16) - EQ5 - high shelf
- */
-#define WM8985_EQ5C_MASK 0x0060 /* EQ5C - [6:5] */
-#define WM8985_EQ5C_SHIFT 5 /* EQ5C - [6:5] */
-#define WM8985_EQ5C_WIDTH 2 /* EQ5C - [6:5] */
-#define WM8985_EQ5G_MASK 0x001F /* EQ5G - [4:0] */
-#define WM8985_EQ5G_SHIFT 0 /* EQ5G - [4:0] */
-#define WM8985_EQ5G_WIDTH 5 /* EQ5G - [4:0] */
-
-/*
- * R24 (0x18) - DAC Limiter 1
- */
-#define WM8985_LIMEN 0x0100 /* LIMEN */
-#define WM8985_LIMEN_MASK 0x0100 /* LIMEN */
-#define WM8985_LIMEN_SHIFT 8 /* LIMEN */
-#define WM8985_LIMEN_WIDTH 1 /* LIMEN */
-#define WM8985_LIMDCY_MASK 0x00F0 /* LIMDCY - [7:4] */
-#define WM8985_LIMDCY_SHIFT 4 /* LIMDCY - [7:4] */
-#define WM8985_LIMDCY_WIDTH 4 /* LIMDCY - [7:4] */
-#define WM8985_LIMATK_MASK 0x000F /* LIMATK - [3:0] */
-#define WM8985_LIMATK_SHIFT 0 /* LIMATK - [3:0] */
-#define WM8985_LIMATK_WIDTH 4 /* LIMATK - [3:0] */
-
-/*
- * R25 (0x19) - DAC Limiter 2
- */
-#define WM8985_LIMLVL_MASK 0x0070 /* LIMLVL - [6:4] */
-#define WM8985_LIMLVL_SHIFT 4 /* LIMLVL - [6:4] */
-#define WM8985_LIMLVL_WIDTH 3 /* LIMLVL - [6:4] */
-#define WM8985_LIMBOOST_MASK 0x000F /* LIMBOOST - [3:0] */
-#define WM8985_LIMBOOST_SHIFT 0 /* LIMBOOST - [3:0] */
-#define WM8985_LIMBOOST_WIDTH 4 /* LIMBOOST - [3:0] */
-
-/*
- * R27 (0x1B) - Notch Filter 1
- */
-#define WM8985_NFU 0x0100 /* NFU */
-#define WM8985_NFU_MASK 0x0100 /* NFU */
-#define WM8985_NFU_SHIFT 8 /* NFU */
-#define WM8985_NFU_WIDTH 1 /* NFU */
-#define WM8985_NFEN 0x0080 /* NFEN */
-#define WM8985_NFEN_MASK 0x0080 /* NFEN */
-#define WM8985_NFEN_SHIFT 7 /* NFEN */
-#define WM8985_NFEN_WIDTH 1 /* NFEN */
-#define WM8985_NFA0_13_7_MASK 0x007F /* NFA0(13:7) - [6:0] */
-#define WM8985_NFA0_13_7_SHIFT 0 /* NFA0(13:7) - [6:0] */
-#define WM8985_NFA0_13_7_WIDTH 7 /* NFA0(13:7) - [6:0] */
-
-/*
- * R28 (0x1C) - Notch Filter 2
- */
-#define WM8985_NFU 0x0100 /* NFU */
-#define WM8985_NFU_MASK 0x0100 /* NFU */
-#define WM8985_NFU_SHIFT 8 /* NFU */
-#define WM8985_NFU_WIDTH 1 /* NFU */
-#define WM8985_NFA0_6_0_MASK 0x007F /* NFA0(6:0) - [6:0] */
-#define WM8985_NFA0_6_0_SHIFT 0 /* NFA0(6:0) - [6:0] */
-#define WM8985_NFA0_6_0_WIDTH 7 /* NFA0(6:0) - [6:0] */
-
-/*
- * R29 (0x1D) - Notch Filter 3
- */
-#define WM8985_NFU 0x0100 /* NFU */
-#define WM8985_NFU_MASK 0x0100 /* NFU */
-#define WM8985_NFU_SHIFT 8 /* NFU */
-#define WM8985_NFU_WIDTH 1 /* NFU */
-#define WM8985_NFA1_13_7_MASK 0x007F /* NFA1(13:7) - [6:0] */
-#define WM8985_NFA1_13_7_SHIFT 0 /* NFA1(13:7) - [6:0] */
-#define WM8985_NFA1_13_7_WIDTH 7 /* NFA1(13:7) - [6:0] */
-
-/*
- * R30 (0x1E) - Notch Filter 4
- */
-#define WM8985_NFU 0x0100 /* NFU */
-#define WM8985_NFU_MASK 0x0100 /* NFU */
-#define WM8985_NFU_SHIFT 8 /* NFU */
-#define WM8985_NFU_WIDTH 1 /* NFU */
-#define WM8985_NFA1_6_0_MASK 0x007F /* NFA1(6:0) - [6:0] */
-#define WM8985_NFA1_6_0_SHIFT 0 /* NFA1(6:0) - [6:0] */
-#define WM8985_NFA1_6_0_WIDTH 7 /* NFA1(6:0) - [6:0] */
-
-/*
- * R32 (0x20) - ALC control 1
- */
-#define WM8985_ALCSEL_MASK 0x0180 /* ALCSEL - [8:7] */
-#define WM8985_ALCSEL_SHIFT 7 /* ALCSEL - [8:7] */
-#define WM8985_ALCSEL_WIDTH 2 /* ALCSEL - [8:7] */
-#define WM8985_ALCMAX_MASK 0x0038 /* ALCMAX - [5:3] */
-#define WM8985_ALCMAX_SHIFT 3 /* ALCMAX - [5:3] */
-#define WM8985_ALCMAX_WIDTH 3 /* ALCMAX - [5:3] */
-#define WM8985_ALCMIN_MASK 0x0007 /* ALCMIN - [2:0] */
-#define WM8985_ALCMIN_SHIFT 0 /* ALCMIN - [2:0] */
-#define WM8985_ALCMIN_WIDTH 3 /* ALCMIN - [2:0] */
-
-/*
- * R33 (0x21) - ALC control 2
- */
-#define WM8985_ALCHLD_MASK 0x00F0 /* ALCHLD - [7:4] */
-#define WM8985_ALCHLD_SHIFT 4 /* ALCHLD - [7:4] */
-#define WM8985_ALCHLD_WIDTH 4 /* ALCHLD - [7:4] */
-#define WM8985_ALCLVL_MASK 0x000F /* ALCLVL - [3:0] */
-#define WM8985_ALCLVL_SHIFT 0 /* ALCLVL - [3:0] */
-#define WM8985_ALCLVL_WIDTH 4 /* ALCLVL - [3:0] */
-
-/*
- * R34 (0x22) - ALC control 3
- */
-#define WM8985_ALCMODE 0x0100 /* ALCMODE */
-#define WM8985_ALCMODE_MASK 0x0100 /* ALCMODE */
-#define WM8985_ALCMODE_SHIFT 8 /* ALCMODE */
-#define WM8985_ALCMODE_WIDTH 1 /* ALCMODE */
-#define WM8985_ALCDCY_MASK 0x00F0 /* ALCDCY - [7:4] */
-#define WM8985_ALCDCY_SHIFT 4 /* ALCDCY - [7:4] */
-#define WM8985_ALCDCY_WIDTH 4 /* ALCDCY - [7:4] */
-#define WM8985_ALCATK_MASK 0x000F /* ALCATK - [3:0] */
-#define WM8985_ALCATK_SHIFT 0 /* ALCATK - [3:0] */
-#define WM8985_ALCATK_WIDTH 4 /* ALCATK - [3:0] */
-
-/*
- * R35 (0x23) - Noise Gate
- */
-#define WM8985_NGEN 0x0008 /* NGEN */
-#define WM8985_NGEN_MASK 0x0008 /* NGEN */
-#define WM8985_NGEN_SHIFT 3 /* NGEN */
-#define WM8985_NGEN_WIDTH 1 /* NGEN */
-#define WM8985_NGTH_MASK 0x0007 /* NGTH - [2:0] */
-#define WM8985_NGTH_SHIFT 0 /* NGTH - [2:0] */
-#define WM8985_NGTH_WIDTH 3 /* NGTH - [2:0] */
-
-/*
- * R36 (0x24) - PLL N
- */
-#define WM8985_PLL_PRESCALE 0x0010 /* PLL_PRESCALE */
-#define WM8985_PLL_PRESCALE_MASK 0x0010 /* PLL_PRESCALE */
-#define WM8985_PLL_PRESCALE_SHIFT 4 /* PLL_PRESCALE */
-#define WM8985_PLL_PRESCALE_WIDTH 1 /* PLL_PRESCALE */
-#define WM8985_PLLN_MASK 0x000F /* PLLN - [3:0] */
-#define WM8985_PLLN_SHIFT 0 /* PLLN - [3:0] */
-#define WM8985_PLLN_WIDTH 4 /* PLLN - [3:0] */
-
-/*
- * R37 (0x25) - PLL K 1
- */
-#define WM8985_PLLK_23_18_MASK 0x003F /* PLLK(23:18) - [5:0] */
-#define WM8985_PLLK_23_18_SHIFT 0 /* PLLK(23:18) - [5:0] */
-#define WM8985_PLLK_23_18_WIDTH 6 /* PLLK(23:18) - [5:0] */
-
-/*
- * R38 (0x26) - PLL K 2
- */
-#define WM8985_PLLK_17_9_MASK 0x01FF /* PLLK(17:9) - [8:0] */
-#define WM8985_PLLK_17_9_SHIFT 0 /* PLLK(17:9) - [8:0] */
-#define WM8985_PLLK_17_9_WIDTH 9 /* PLLK(17:9) - [8:0] */
-
-/*
- * R39 (0x27) - PLL K 3
- */
-#define WM8985_PLLK_8_0_MASK 0x01FF /* PLLK(8:0) - [8:0] */
-#define WM8985_PLLK_8_0_SHIFT 0 /* PLLK(8:0) - [8:0] */
-#define WM8985_PLLK_8_0_WIDTH 9 /* PLLK(8:0) - [8:0] */
-
-/*
- * R41 (0x29) - 3D control
- */
-#define WM8985_DEPTH3D_MASK 0x000F /* DEPTH3D - [3:0] */
-#define WM8985_DEPTH3D_SHIFT 0 /* DEPTH3D - [3:0] */
-#define WM8985_DEPTH3D_WIDTH 4 /* DEPTH3D - [3:0] */
-
-/*
- * R42 (0x2A) - OUT4 to ADC
- */
-#define WM8985_OUT4_2ADCVOL_MASK 0x01C0 /* OUT4_2ADCVOL - [8:6] */
-#define WM8985_OUT4_2ADCVOL_SHIFT 6 /* OUT4_2ADCVOL - [8:6] */
-#define WM8985_OUT4_2ADCVOL_WIDTH 3 /* OUT4_2ADCVOL - [8:6] */
-#define WM8985_OUT4_2LNR 0x0020 /* OUT4_2LNR */
-#define WM8985_OUT4_2LNR_MASK 0x0020 /* OUT4_2LNR */
-#define WM8985_OUT4_2LNR_SHIFT 5 /* OUT4_2LNR */
-#define WM8985_OUT4_2LNR_WIDTH 1 /* OUT4_2LNR */
-#define WM8985_POBCTRL 0x0004 /* POBCTRL */
-#define WM8985_POBCTRL_MASK 0x0004 /* POBCTRL */
-#define WM8985_POBCTRL_SHIFT 2 /* POBCTRL */
-#define WM8985_POBCTRL_WIDTH 1 /* POBCTRL */
-#define WM8985_DELEN 0x0002 /* DELEN */
-#define WM8985_DELEN_MASK 0x0002 /* DELEN */
-#define WM8985_DELEN_SHIFT 1 /* DELEN */
-#define WM8985_DELEN_WIDTH 1 /* DELEN */
-#define WM8985_OUT1DEL 0x0001 /* OUT1DEL */
-#define WM8985_OUT1DEL_MASK 0x0001 /* OUT1DEL */
-#define WM8985_OUT1DEL_SHIFT 0 /* OUT1DEL */
-#define WM8985_OUT1DEL_WIDTH 1 /* OUT1DEL */
-
-/*
- * R43 (0x2B) - Beep control
- */
-#define WM8985_BYPL2RMIX 0x0100 /* BYPL2RMIX */
-#define WM8985_BYPL2RMIX_MASK 0x0100 /* BYPL2RMIX */
-#define WM8985_BYPL2RMIX_SHIFT 8 /* BYPL2RMIX */
-#define WM8985_BYPL2RMIX_WIDTH 1 /* BYPL2RMIX */
-#define WM8985_BYPR2LMIX 0x0080 /* BYPR2LMIX */
-#define WM8985_BYPR2LMIX_MASK 0x0080 /* BYPR2LMIX */
-#define WM8985_BYPR2LMIX_SHIFT 7 /* BYPR2LMIX */
-#define WM8985_BYPR2LMIX_WIDTH 1 /* BYPR2LMIX */
-#define WM8985_MUTERPGA2INV 0x0020 /* MUTERPGA2INV */
-#define WM8985_MUTERPGA2INV_MASK 0x0020 /* MUTERPGA2INV */
-#define WM8985_MUTERPGA2INV_SHIFT 5 /* MUTERPGA2INV */
-#define WM8985_MUTERPGA2INV_WIDTH 1 /* MUTERPGA2INV */
-#define WM8985_INVROUT2 0x0010 /* INVROUT2 */
-#define WM8985_INVROUT2_MASK 0x0010 /* INVROUT2 */
-#define WM8985_INVROUT2_SHIFT 4 /* INVROUT2 */
-#define WM8985_INVROUT2_WIDTH 1 /* INVROUT2 */
-#define WM8985_BEEPVOL_MASK 0x000E /* BEEPVOL - [3:1] */
-#define WM8985_BEEPVOL_SHIFT 1 /* BEEPVOL - [3:1] */
-#define WM8985_BEEPVOL_WIDTH 3 /* BEEPVOL - [3:1] */
-#define WM8985_BEEPEN 0x0001 /* BEEPEN */
-#define WM8985_BEEPEN_MASK 0x0001 /* BEEPEN */
-#define WM8985_BEEPEN_SHIFT 0 /* BEEPEN */
-#define WM8985_BEEPEN_WIDTH 1 /* BEEPEN */
-
-/*
- * R44 (0x2C) - Input ctrl
- */
-#define WM8985_MBVSEL 0x0100 /* MBVSEL */
-#define WM8985_MBVSEL_MASK 0x0100 /* MBVSEL */
-#define WM8985_MBVSEL_SHIFT 8 /* MBVSEL */
-#define WM8985_MBVSEL_WIDTH 1 /* MBVSEL */
-#define WM8985_R2_2INPPGA 0x0040 /* R2_2INPPGA */
-#define WM8985_R2_2INPPGA_MASK 0x0040 /* R2_2INPPGA */
-#define WM8985_R2_2INPPGA_SHIFT 6 /* R2_2INPPGA */
-#define WM8985_R2_2INPPGA_WIDTH 1 /* R2_2INPPGA */
-#define WM8985_RIN2INPPGA 0x0020 /* RIN2INPPGA */
-#define WM8985_RIN2INPPGA_MASK 0x0020 /* RIN2INPPGA */
-#define WM8985_RIN2INPPGA_SHIFT 5 /* RIN2INPPGA */
-#define WM8985_RIN2INPPGA_WIDTH 1 /* RIN2INPPGA */
-#define WM8985_RIP2INPPGA 0x0010 /* RIP2INPPGA */
-#define WM8985_RIP2INPPGA_MASK 0x0010 /* RIP2INPPGA */
-#define WM8985_RIP2INPPGA_SHIFT 4 /* RIP2INPPGA */
-#define WM8985_RIP2INPPGA_WIDTH 1 /* RIP2INPPGA */
-#define WM8985_L2_2INPPGA 0x0004 /* L2_2INPPGA */
-#define WM8985_L2_2INPPGA_MASK 0x0004 /* L2_2INPPGA */
-#define WM8985_L2_2INPPGA_SHIFT 2 /* L2_2INPPGA */
-#define WM8985_L2_2INPPGA_WIDTH 1 /* L2_2INPPGA */
-#define WM8985_LIN2INPPGA 0x0002 /* LIN2INPPGA */
-#define WM8985_LIN2INPPGA_MASK 0x0002 /* LIN2INPPGA */
-#define WM8985_LIN2INPPGA_SHIFT 1 /* LIN2INPPGA */
-#define WM8985_LIN2INPPGA_WIDTH 1 /* LIN2INPPGA */
-#define WM8985_LIP2INPPGA 0x0001 /* LIP2INPPGA */
-#define WM8985_LIP2INPPGA_MASK 0x0001 /* LIP2INPPGA */
-#define WM8985_LIP2INPPGA_SHIFT 0 /* LIP2INPPGA */
-#define WM8985_LIP2INPPGA_WIDTH 1 /* LIP2INPPGA */
-
-/*
- * R45 (0x2D) - Left INP PGA gain ctrl
- */
-#define WM8985_INPGAVU 0x0100 /* INPGAVU */
-#define WM8985_INPGAVU_MASK 0x0100 /* INPGAVU */
-#define WM8985_INPGAVU_SHIFT 8 /* INPGAVU */
-#define WM8985_INPGAVU_WIDTH 1 /* INPGAVU */
-#define WM8985_INPPGAZCL 0x0080 /* INPPGAZCL */
-#define WM8985_INPPGAZCL_MASK 0x0080 /* INPPGAZCL */
-#define WM8985_INPPGAZCL_SHIFT 7 /* INPPGAZCL */
-#define WM8985_INPPGAZCL_WIDTH 1 /* INPPGAZCL */
-#define WM8985_INPPGAMUTEL 0x0040 /* INPPGAMUTEL */
-#define WM8985_INPPGAMUTEL_MASK 0x0040 /* INPPGAMUTEL */
-#define WM8985_INPPGAMUTEL_SHIFT 6 /* INPPGAMUTEL */
-#define WM8985_INPPGAMUTEL_WIDTH 1 /* INPPGAMUTEL */
-#define WM8985_INPPGAVOLL_MASK 0x003F /* INPPGAVOLL - [5:0] */
-#define WM8985_INPPGAVOLL_SHIFT 0 /* INPPGAVOLL - [5:0] */
-#define WM8985_INPPGAVOLL_WIDTH 6 /* INPPGAVOLL - [5:0] */
-
-/*
- * R46 (0x2E) - Right INP PGA gain ctrl
- */
-#define WM8985_INPGAVU 0x0100 /* INPGAVU */
-#define WM8985_INPGAVU_MASK 0x0100 /* INPGAVU */
-#define WM8985_INPGAVU_SHIFT 8 /* INPGAVU */
-#define WM8985_INPGAVU_WIDTH 1 /* INPGAVU */
-#define WM8985_INPPGAZCR 0x0080 /* INPPGAZCR */
-#define WM8985_INPPGAZCR_MASK 0x0080 /* INPPGAZCR */
-#define WM8985_INPPGAZCR_SHIFT 7 /* INPPGAZCR */
-#define WM8985_INPPGAZCR_WIDTH 1 /* INPPGAZCR */
-#define WM8985_INPPGAMUTER 0x0040 /* INPPGAMUTER */
-#define WM8985_INPPGAMUTER_MASK 0x0040 /* INPPGAMUTER */
-#define WM8985_INPPGAMUTER_SHIFT 6 /* INPPGAMUTER */
-#define WM8985_INPPGAMUTER_WIDTH 1 /* INPPGAMUTER */
-#define WM8985_INPPGAVOLR_MASK 0x003F /* INPPGAVOLR - [5:0] */
-#define WM8985_INPPGAVOLR_SHIFT 0 /* INPPGAVOLR - [5:0] */
-#define WM8985_INPPGAVOLR_WIDTH 6 /* INPPGAVOLR - [5:0] */
-
-/*
- * R47 (0x2F) - Left ADC BOOST ctrl
- */
-#define WM8985_PGABOOSTL 0x0100 /* PGABOOSTL */
-#define WM8985_PGABOOSTL_MASK 0x0100 /* PGABOOSTL */
-#define WM8985_PGABOOSTL_SHIFT 8 /* PGABOOSTL */
-#define WM8985_PGABOOSTL_WIDTH 1 /* PGABOOSTL */
-#define WM8985_L2_2BOOSTVOL_MASK 0x0070 /* L2_2BOOSTVOL - [6:4] */
-#define WM8985_L2_2BOOSTVOL_SHIFT 4 /* L2_2BOOSTVOL - [6:4] */
-#define WM8985_L2_2BOOSTVOL_WIDTH 3 /* L2_2BOOSTVOL - [6:4] */
-#define WM8985_AUXL2BOOSTVOL_MASK 0x0007 /* AUXL2BOOSTVOL - [2:0] */
-#define WM8985_AUXL2BOOSTVOL_SHIFT 0 /* AUXL2BOOSTVOL - [2:0] */
-#define WM8985_AUXL2BOOSTVOL_WIDTH 3 /* AUXL2BOOSTVOL - [2:0] */
-
-/*
- * R48 (0x30) - Right ADC BOOST ctrl
- */
-#define WM8985_PGABOOSTR 0x0100 /* PGABOOSTR */
-#define WM8985_PGABOOSTR_MASK 0x0100 /* PGABOOSTR */
-#define WM8985_PGABOOSTR_SHIFT 8 /* PGABOOSTR */
-#define WM8985_PGABOOSTR_WIDTH 1 /* PGABOOSTR */
-#define WM8985_R2_2BOOSTVOL_MASK 0x0070 /* R2_2BOOSTVOL - [6:4] */
-#define WM8985_R2_2BOOSTVOL_SHIFT 4 /* R2_2BOOSTVOL - [6:4] */
-#define WM8985_R2_2BOOSTVOL_WIDTH 3 /* R2_2BOOSTVOL - [6:4] */
-#define WM8985_AUXR2BOOSTVOL_MASK 0x0007 /* AUXR2BOOSTVOL - [2:0] */
-#define WM8985_AUXR2BOOSTVOL_SHIFT 0 /* AUXR2BOOSTVOL - [2:0] */
-#define WM8985_AUXR2BOOSTVOL_WIDTH 3 /* AUXR2BOOSTVOL - [2:0] */
-
-/*
- * R49 (0x31) - Output ctrl
- */
-#define WM8985_DACL2RMIX 0x0040 /* DACL2RMIX */
-#define WM8985_DACL2RMIX_MASK 0x0040 /* DACL2RMIX */
-#define WM8985_DACL2RMIX_SHIFT 6 /* DACL2RMIX */
-#define WM8985_DACL2RMIX_WIDTH 1 /* DACL2RMIX */
-#define WM8985_DACR2LMIX 0x0020 /* DACR2LMIX */
-#define WM8985_DACR2LMIX_MASK 0x0020 /* DACR2LMIX */
-#define WM8985_DACR2LMIX_SHIFT 5 /* DACR2LMIX */
-#define WM8985_DACR2LMIX_WIDTH 1 /* DACR2LMIX */
-#define WM8985_OUT4BOOST 0x0010 /* OUT4BOOST */
-#define WM8985_OUT4BOOST_MASK 0x0010 /* OUT4BOOST */
-#define WM8985_OUT4BOOST_SHIFT 4 /* OUT4BOOST */
-#define WM8985_OUT4BOOST_WIDTH 1 /* OUT4BOOST */
-#define WM8985_OUT3BOOST 0x0008 /* OUT3BOOST */
-#define WM8985_OUT3BOOST_MASK 0x0008 /* OUT3BOOST */
-#define WM8985_OUT3BOOST_SHIFT 3 /* OUT3BOOST */
-#define WM8985_OUT3BOOST_WIDTH 1 /* OUT3BOOST */
-#define WM8985_TSOPCTRL 0x0004 /* TSOPCTRL */
-#define WM8985_TSOPCTRL_MASK 0x0004 /* TSOPCTRL */
-#define WM8985_TSOPCTRL_SHIFT 2 /* TSOPCTRL */
-#define WM8985_TSOPCTRL_WIDTH 1 /* TSOPCTRL */
-#define WM8985_TSDEN 0x0002 /* TSDEN */
-#define WM8985_TSDEN_MASK 0x0002 /* TSDEN */
-#define WM8985_TSDEN_SHIFT 1 /* TSDEN */
-#define WM8985_TSDEN_WIDTH 1 /* TSDEN */
-#define WM8985_VROI 0x0001 /* VROI */
-#define WM8985_VROI_MASK 0x0001 /* VROI */
-#define WM8985_VROI_SHIFT 0 /* VROI */
-#define WM8985_VROI_WIDTH 1 /* VROI */
-
-/*
- * R50 (0x32) - Left mixer ctrl
- */
-#define WM8985_AUXLMIXVOL_MASK 0x01C0 /* AUXLMIXVOL - [8:6] */
-#define WM8985_AUXLMIXVOL_SHIFT 6 /* AUXLMIXVOL - [8:6] */
-#define WM8985_AUXLMIXVOL_WIDTH 3 /* AUXLMIXVOL - [8:6] */
-#define WM8985_AUXL2LMIX 0x0020 /* AUXL2LMIX */
-#define WM8985_AUXL2LMIX_MASK 0x0020 /* AUXL2LMIX */
-#define WM8985_AUXL2LMIX_SHIFT 5 /* AUXL2LMIX */
-#define WM8985_AUXL2LMIX_WIDTH 1 /* AUXL2LMIX */
-#define WM8985_BYPLMIXVOL_MASK 0x001C /* BYPLMIXVOL - [4:2] */
-#define WM8985_BYPLMIXVOL_SHIFT 2 /* BYPLMIXVOL - [4:2] */
-#define WM8985_BYPLMIXVOL_WIDTH 3 /* BYPLMIXVOL - [4:2] */
-#define WM8985_BYPL2LMIX 0x0002 /* BYPL2LMIX */
-#define WM8985_BYPL2LMIX_MASK 0x0002 /* BYPL2LMIX */
-#define WM8985_BYPL2LMIX_SHIFT 1 /* BYPL2LMIX */
-#define WM8985_BYPL2LMIX_WIDTH 1 /* BYPL2LMIX */
-#define WM8985_DACL2LMIX 0x0001 /* DACL2LMIX */
-#define WM8985_DACL2LMIX_MASK 0x0001 /* DACL2LMIX */
-#define WM8985_DACL2LMIX_SHIFT 0 /* DACL2LMIX */
-#define WM8985_DACL2LMIX_WIDTH 1 /* DACL2LMIX */
-
-/*
- * R51 (0x33) - Right mixer ctrl
- */
-#define WM8985_AUXRMIXVOL_MASK 0x01C0 /* AUXRMIXVOL - [8:6] */
-#define WM8985_AUXRMIXVOL_SHIFT 6 /* AUXRMIXVOL - [8:6] */
-#define WM8985_AUXRMIXVOL_WIDTH 3 /* AUXRMIXVOL - [8:6] */
-#define WM8985_AUXR2RMIX 0x0020 /* AUXR2RMIX */
-#define WM8985_AUXR2RMIX_MASK 0x0020 /* AUXR2RMIX */
-#define WM8985_AUXR2RMIX_SHIFT 5 /* AUXR2RMIX */
-#define WM8985_AUXR2RMIX_WIDTH 1 /* AUXR2RMIX */
-#define WM8985_BYPRMIXVOL_MASK 0x001C /* BYPRMIXVOL - [4:2] */
-#define WM8985_BYPRMIXVOL_SHIFT 2 /* BYPRMIXVOL - [4:2] */
-#define WM8985_BYPRMIXVOL_WIDTH 3 /* BYPRMIXVOL - [4:2] */
-#define WM8985_BYPR2RMIX 0x0002 /* BYPR2RMIX */
-#define WM8985_BYPR2RMIX_MASK 0x0002 /* BYPR2RMIX */
-#define WM8985_BYPR2RMIX_SHIFT 1 /* BYPR2RMIX */
-#define WM8985_BYPR2RMIX_WIDTH 1 /* BYPR2RMIX */
-#define WM8985_DACR2RMIX 0x0001 /* DACR2RMIX */
-#define WM8985_DACR2RMIX_MASK 0x0001 /* DACR2RMIX */
-#define WM8985_DACR2RMIX_SHIFT 0 /* DACR2RMIX */
-#define WM8985_DACR2RMIX_WIDTH 1 /* DACR2RMIX */
-
-/*
- * R52 (0x34) - LOUT1 (HP) volume ctrl
- */
-#define WM8985_OUT1VU 0x0100 /* OUT1VU */
-#define WM8985_OUT1VU_MASK 0x0100 /* OUT1VU */
-#define WM8985_OUT1VU_SHIFT 8 /* OUT1VU */
-#define WM8985_OUT1VU_WIDTH 1 /* OUT1VU */
-#define WM8985_LOUT1ZC 0x0080 /* LOUT1ZC */
-#define WM8985_LOUT1ZC_MASK 0x0080 /* LOUT1ZC */
-#define WM8985_LOUT1ZC_SHIFT 7 /* LOUT1ZC */
-#define WM8985_LOUT1ZC_WIDTH 1 /* LOUT1ZC */
-#define WM8985_LOUT1MUTE 0x0040 /* LOUT1MUTE */
-#define WM8985_LOUT1MUTE_MASK 0x0040 /* LOUT1MUTE */
-#define WM8985_LOUT1MUTE_SHIFT 6 /* LOUT1MUTE */
-#define WM8985_LOUT1MUTE_WIDTH 1 /* LOUT1MUTE */
-#define WM8985_LOUT1VOL_MASK 0x003F /* LOUT1VOL - [5:0] */
-#define WM8985_LOUT1VOL_SHIFT 0 /* LOUT1VOL - [5:0] */
-#define WM8985_LOUT1VOL_WIDTH 6 /* LOUT1VOL - [5:0] */
-
-/*
- * R53 (0x35) - ROUT1 (HP) volume ctrl
- */
-#define WM8985_OUT1VU 0x0100 /* OUT1VU */
-#define WM8985_OUT1VU_MASK 0x0100 /* OUT1VU */
-#define WM8985_OUT1VU_SHIFT 8 /* OUT1VU */
-#define WM8985_OUT1VU_WIDTH 1 /* OUT1VU */
-#define WM8985_ROUT1ZC 0x0080 /* ROUT1ZC */
-#define WM8985_ROUT1ZC_MASK 0x0080 /* ROUT1ZC */
-#define WM8985_ROUT1ZC_SHIFT 7 /* ROUT1ZC */
-#define WM8985_ROUT1ZC_WIDTH 1 /* ROUT1ZC */
-#define WM8985_ROUT1MUTE 0x0040 /* ROUT1MUTE */
-#define WM8985_ROUT1MUTE_MASK 0x0040 /* ROUT1MUTE */
-#define WM8985_ROUT1MUTE_SHIFT 6 /* ROUT1MUTE */
-#define WM8985_ROUT1MUTE_WIDTH 1 /* ROUT1MUTE */
-#define WM8985_ROUT1VOL_MASK 0x003F /* ROUT1VOL - [5:0] */
-#define WM8985_ROUT1VOL_SHIFT 0 /* ROUT1VOL - [5:0] */
-#define WM8985_ROUT1VOL_WIDTH 6 /* ROUT1VOL - [5:0] */
-
-/*
- * R54 (0x36) - LOUT2 (SPK) volume ctrl
- */
-#define WM8985_OUT2VU 0x0100 /* OUT2VU */
-#define WM8985_OUT2VU_MASK 0x0100 /* OUT2VU */
-#define WM8985_OUT2VU_SHIFT 8 /* OUT2VU */
-#define WM8985_OUT2VU_WIDTH 1 /* OUT2VU */
-#define WM8985_LOUT2ZC 0x0080 /* LOUT2ZC */
-#define WM8985_LOUT2ZC_MASK 0x0080 /* LOUT2ZC */
-#define WM8985_LOUT2ZC_SHIFT 7 /* LOUT2ZC */
-#define WM8985_LOUT2ZC_WIDTH 1 /* LOUT2ZC */
-#define WM8985_LOUT2MUTE 0x0040 /* LOUT2MUTE */
-#define WM8985_LOUT2MUTE_MASK 0x0040 /* LOUT2MUTE */
-#define WM8985_LOUT2MUTE_SHIFT 6 /* LOUT2MUTE */
-#define WM8985_LOUT2MUTE_WIDTH 1 /* LOUT2MUTE */
-#define WM8985_LOUT2VOL_MASK 0x003F /* LOUT2VOL - [5:0] */
-#define WM8985_LOUT2VOL_SHIFT 0 /* LOUT2VOL - [5:0] */
-#define WM8985_LOUT2VOL_WIDTH 6 /* LOUT2VOL - [5:0] */
-
-/*
- * R55 (0x37) - ROUT2 (SPK) volume ctrl
- */
-#define WM8985_OUT2VU 0x0100 /* OUT2VU */
-#define WM8985_OUT2VU_MASK 0x0100 /* OUT2VU */
-#define WM8985_OUT2VU_SHIFT 8 /* OUT2VU */
-#define WM8985_OUT2VU_WIDTH 1 /* OUT2VU */
-#define WM8985_ROUT2ZC 0x0080 /* ROUT2ZC */
-#define WM8985_ROUT2ZC_MASK 0x0080 /* ROUT2ZC */
-#define WM8985_ROUT2ZC_SHIFT 7 /* ROUT2ZC */
-#define WM8985_ROUT2ZC_WIDTH 1 /* ROUT2ZC */
-#define WM8985_ROUT2MUTE 0x0040 /* ROUT2MUTE */
-#define WM8985_ROUT2MUTE_MASK 0x0040 /* ROUT2MUTE */
-#define WM8985_ROUT2MUTE_SHIFT 6 /* ROUT2MUTE */
-#define WM8985_ROUT2MUTE_WIDTH 1 /* ROUT2MUTE */
-#define WM8985_ROUT2VOL_MASK 0x003F /* ROUT2VOL - [5:0] */
-#define WM8985_ROUT2VOL_SHIFT 0 /* ROUT2VOL - [5:0] */
-#define WM8985_ROUT2VOL_WIDTH 6 /* ROUT2VOL - [5:0] */
-
-/*
- * R56 (0x38) - OUT3 mixer ctrl
- */
-#define WM8985_OUT3MUTE 0x0040 /* OUT3MUTE */
-#define WM8985_OUT3MUTE_MASK 0x0040 /* OUT3MUTE */
-#define WM8985_OUT3MUTE_SHIFT 6 /* OUT3MUTE */
-#define WM8985_OUT3MUTE_WIDTH 1 /* OUT3MUTE */
-#define WM8985_OUT4_2OUT3 0x0008 /* OUT4_2OUT3 */
-#define WM8985_OUT4_2OUT3_MASK 0x0008 /* OUT4_2OUT3 */
-#define WM8985_OUT4_2OUT3_SHIFT 3 /* OUT4_2OUT3 */
-#define WM8985_OUT4_2OUT3_WIDTH 1 /* OUT4_2OUT3 */
-#define WM8985_BYPL2OUT3 0x0004 /* BYPL2OUT3 */
-#define WM8985_BYPL2OUT3_MASK 0x0004 /* BYPL2OUT3 */
-#define WM8985_BYPL2OUT3_SHIFT 2 /* BYPL2OUT3 */
-#define WM8985_BYPL2OUT3_WIDTH 1 /* BYPL2OUT3 */
-#define WM8985_LMIX2OUT3 0x0002 /* LMIX2OUT3 */
-#define WM8985_LMIX2OUT3_MASK 0x0002 /* LMIX2OUT3 */
-#define WM8985_LMIX2OUT3_SHIFT 1 /* LMIX2OUT3 */
-#define WM8985_LMIX2OUT3_WIDTH 1 /* LMIX2OUT3 */
-#define WM8985_LDAC2OUT3 0x0001 /* LDAC2OUT3 */
-#define WM8985_LDAC2OUT3_MASK 0x0001 /* LDAC2OUT3 */
-#define WM8985_LDAC2OUT3_SHIFT 0 /* LDAC2OUT3 */
-#define WM8985_LDAC2OUT3_WIDTH 1 /* LDAC2OUT3 */
-
-/*
- * R57 (0x39) - OUT4 (MONO) mix ctrl
- */
-#define WM8985_OUT3_2OUT4 0x0080 /* OUT3_2OUT4 */
-#define WM8985_OUT3_2OUT4_MASK 0x0080 /* OUT3_2OUT4 */
-#define WM8985_OUT3_2OUT4_SHIFT 7 /* OUT3_2OUT4 */
-#define WM8985_OUT3_2OUT4_WIDTH 1 /* OUT3_2OUT4 */
-#define WM8985_OUT4MUTE 0x0040 /* OUT4MUTE */
-#define WM8985_OUT4MUTE_MASK 0x0040 /* OUT4MUTE */
-#define WM8985_OUT4MUTE_SHIFT 6 /* OUT4MUTE */
-#define WM8985_OUT4MUTE_WIDTH 1 /* OUT4MUTE */
-#define WM8985_OUT4ATTN 0x0020 /* OUT4ATTN */
-#define WM8985_OUT4ATTN_MASK 0x0020 /* OUT4ATTN */
-#define WM8985_OUT4ATTN_SHIFT 5 /* OUT4ATTN */
-#define WM8985_OUT4ATTN_WIDTH 1 /* OUT4ATTN */
-#define WM8985_LMIX2OUT4 0x0010 /* LMIX2OUT4 */
-#define WM8985_LMIX2OUT4_MASK 0x0010 /* LMIX2OUT4 */
-#define WM8985_LMIX2OUT4_SHIFT 4 /* LMIX2OUT4 */
-#define WM8985_LMIX2OUT4_WIDTH 1 /* LMIX2OUT4 */
-#define WM8985_LDAC2OUT4 0x0008 /* LDAC2OUT4 */
-#define WM8985_LDAC2OUT4_MASK 0x0008 /* LDAC2OUT4 */
-#define WM8985_LDAC2OUT4_SHIFT 3 /* LDAC2OUT4 */
-#define WM8985_LDAC2OUT4_WIDTH 1 /* LDAC2OUT4 */
-#define WM8985_BYPR2OUT4 0x0004 /* BYPR2OUT4 */
-#define WM8985_BYPR2OUT4_MASK 0x0004 /* BYPR2OUT4 */
-#define WM8985_BYPR2OUT4_SHIFT 2 /* BYPR2OUT4 */
-#define WM8985_BYPR2OUT4_WIDTH 1 /* BYPR2OUT4 */
-#define WM8985_RMIX2OUT4 0x0002 /* RMIX2OUT4 */
-#define WM8985_RMIX2OUT4_MASK 0x0002 /* RMIX2OUT4 */
-#define WM8985_RMIX2OUT4_SHIFT 1 /* RMIX2OUT4 */
-#define WM8985_RMIX2OUT4_WIDTH 1 /* RMIX2OUT4 */
-#define WM8985_RDAC2OUT4 0x0001 /* RDAC2OUT4 */
-#define WM8985_RDAC2OUT4_MASK 0x0001 /* RDAC2OUT4 */
-#define WM8985_RDAC2OUT4_SHIFT 0 /* RDAC2OUT4 */
-#define WM8985_RDAC2OUT4_WIDTH 1 /* RDAC2OUT4 */
-
-/*
- * R60 (0x3C) - OUTPUT ctrl
- */
-#define WM8985_VIDBUFFTST_MASK 0x01E0 /* VIDBUFFTST - [8:5] */
-#define WM8985_VIDBUFFTST_SHIFT 5 /* VIDBUFFTST - [8:5] */
-#define WM8985_VIDBUFFTST_WIDTH 4 /* VIDBUFFTST - [8:5] */
-#define WM8985_HPTOG 0x0008 /* HPTOG */
-#define WM8985_HPTOG_MASK 0x0008 /* HPTOG */
-#define WM8985_HPTOG_SHIFT 3 /* HPTOG */
-#define WM8985_HPTOG_WIDTH 1 /* HPTOG */
-
-/*
- * R61 (0x3D) - BIAS CTRL
- */
-#define WM8985_BIASCUT 0x0100 /* BIASCUT */
-#define WM8985_BIASCUT_MASK 0x0100 /* BIASCUT */
-#define WM8985_BIASCUT_SHIFT 8 /* BIASCUT */
-#define WM8985_BIASCUT_WIDTH 1 /* BIASCUT */
-#define WM8985_HALFIPBIAS 0x0080 /* HALFIPBIAS */
-#define WM8985_HALFIPBIAS_MASK 0x0080 /* HALFIPBIAS */
-#define WM8985_HALFIPBIAS_SHIFT 7 /* HALFIPBIAS */
-#define WM8985_HALFIPBIAS_WIDTH 1 /* HALFIPBIAS */
-#define WM8985_VBBIASTST_MASK 0x0060 /* VBBIASTST - [6:5] */
-#define WM8985_VBBIASTST_SHIFT 5 /* VBBIASTST - [6:5] */
-#define WM8985_VBBIASTST_WIDTH 2 /* VBBIASTST - [6:5] */
-#define WM8985_BUFBIAS_MASK 0x0018 /* BUFBIAS - [4:3] */
-#define WM8985_BUFBIAS_SHIFT 3 /* BUFBIAS - [4:3] */
-#define WM8985_BUFBIAS_WIDTH 2 /* BUFBIAS - [4:3] */
-#define WM8985_ADCBIAS_MASK 0x0006 /* ADCBIAS - [2:1] */
-#define WM8985_ADCBIAS_SHIFT 1 /* ADCBIAS - [2:1] */
-#define WM8985_ADCBIAS_WIDTH 2 /* ADCBIAS - [2:1] */
-#define WM8985_HALFOPBIAS 0x0001 /* HALFOPBIAS */
-#define WM8985_HALFOPBIAS_MASK 0x0001 /* HALFOPBIAS */
-#define WM8985_HALFOPBIAS_SHIFT 0 /* HALFOPBIAS */
-#define WM8985_HALFOPBIAS_WIDTH 1 /* HALFOPBIAS */
-
-enum clk_src {
- WM8985_CLKSRC_MCLK,
- WM8985_CLKSRC_PLL
-};
-
-#define WM8985_PLL 0
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8988.c b/ANDROID_3.4.5/sound/soc/codecs/wm8988.c
deleted file mode 100644
index 6cdf6a2b..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8988.c
+++ /dev/null
@@ -1,1010 +0,0 @@
-/*
- * wm8988.c -- WM8988 ALSA SoC audio driver
- *
- * Copyright 2009 Wolfson Microelectronics plc
- * Copyright 2005 Openedhand Ltd.
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/tlv.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-
-#include "wm8988.h"
-
-/*
- * wm8988 register cache
- * We can't read the WM8988 register space when we
- * are using 2 wire for device control, so we cache them instead.
- */
-static const struct reg_default wm8988_reg_defaults[] = {
- { 0, 0x0097 },
- { 1, 0x0097 },
- { 2, 0x0079 },
- { 3, 0x0079 },
- { 5, 0x0008 },
- { 7, 0x000a },
- { 8, 0x0000 },
- { 10, 0x00ff },
- { 11, 0x00ff },
- { 12, 0x000f },
- { 13, 0x000f },
- { 16, 0x0000 },
- { 17, 0x007b },
- { 18, 0x0000 },
- { 19, 0x0032 },
- { 20, 0x0000 },
- { 21, 0x00c3 },
- { 22, 0x00c3 },
- { 23, 0x00c0 },
- { 24, 0x0000 },
- { 25, 0x0000 },
- { 26, 0x0000 },
- { 27, 0x0000 },
- { 31, 0x0000 },
- { 32, 0x0000 },
- { 33, 0x0000 },
- { 34, 0x0050 },
- { 35, 0x0050 },
- { 36, 0x0050 },
- { 37, 0x0050 },
- { 40, 0x0079 },
- { 41, 0x0079 },
- { 42, 0x0079 },
-};
-
-static bool wm8988_writeable(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM8988_LINVOL:
- case WM8988_RINVOL:
- case WM8988_LOUT1V:
- case WM8988_ROUT1V:
- case WM8988_ADCDAC:
- case WM8988_IFACE:
- case WM8988_SRATE:
- case WM8988_LDAC:
- case WM8988_RDAC:
- case WM8988_BASS:
- case WM8988_TREBLE:
- case WM8988_RESET:
- case WM8988_3D:
- case WM8988_ALC1:
- case WM8988_ALC2:
- case WM8988_ALC3:
- case WM8988_NGATE:
- case WM8988_LADC:
- case WM8988_RADC:
- case WM8988_ADCTL1:
- case WM8988_ADCTL2:
- case WM8988_PWR1:
- case WM8988_PWR2:
- case WM8988_ADCTL3:
- case WM8988_ADCIN:
- case WM8988_LADCIN:
- case WM8988_RADCIN:
- case WM8988_LOUTM1:
- case WM8988_LOUTM2:
- case WM8988_ROUTM1:
- case WM8988_ROUTM2:
- case WM8988_LOUT2V:
- case WM8988_ROUT2V:
- case WM8988_LPPB:
- return true;
- default:
- return false;
- }
-}
-
-/* codec private data */
-struct wm8988_priv {
- struct regmap *regmap;
- unsigned int sysclk;
- struct snd_pcm_hw_constraint_list *sysclk_constraints;
-};
-
-#define wm8988_reset(c) snd_soc_write(c, WM8988_RESET, 0)
-
-/*
- * WM8988 Controls
- */
-
-static const char *bass_boost_txt[] = {"Linear Control", "Adaptive Boost"};
-static const struct soc_enum bass_boost =
- SOC_ENUM_SINGLE(WM8988_BASS, 7, 2, bass_boost_txt);
-
-static const char *bass_filter_txt[] = { "130Hz @ 48kHz", "200Hz @ 48kHz" };
-static const struct soc_enum bass_filter =
- SOC_ENUM_SINGLE(WM8988_BASS, 6, 2, bass_filter_txt);
-
-static const char *treble_txt[] = {"8kHz", "4kHz"};
-static const struct soc_enum treble =
- SOC_ENUM_SINGLE(WM8988_TREBLE, 6, 2, treble_txt);
-
-static const char *stereo_3d_lc_txt[] = {"200Hz", "500Hz"};
-static const struct soc_enum stereo_3d_lc =
- SOC_ENUM_SINGLE(WM8988_3D, 5, 2, stereo_3d_lc_txt);
-
-static const char *stereo_3d_uc_txt[] = {"2.2kHz", "1.5kHz"};
-static const struct soc_enum stereo_3d_uc =
- SOC_ENUM_SINGLE(WM8988_3D, 6, 2, stereo_3d_uc_txt);
-
-static const char *stereo_3d_func_txt[] = {"Capture", "Playback"};
-static const struct soc_enum stereo_3d_func =
- SOC_ENUM_SINGLE(WM8988_3D, 7, 2, stereo_3d_func_txt);
-
-static const char *alc_func_txt[] = {"Off", "Right", "Left", "Stereo"};
-static const struct soc_enum alc_func =
- SOC_ENUM_SINGLE(WM8988_ALC1, 7, 4, alc_func_txt);
-
-static const char *ng_type_txt[] = {"Constant PGA Gain",
- "Mute ADC Output"};
-static const struct soc_enum ng_type =
- SOC_ENUM_SINGLE(WM8988_NGATE, 1, 2, ng_type_txt);
-
-static const char *deemph_txt[] = {"None", "32Khz", "44.1Khz", "48Khz"};
-static const struct soc_enum deemph =
- SOC_ENUM_SINGLE(WM8988_ADCDAC, 1, 4, deemph_txt);
-
-static const char *adcpol_txt[] = {"Normal", "L Invert", "R Invert",
- "L + R Invert"};
-static const struct soc_enum adcpol =
- SOC_ENUM_SINGLE(WM8988_ADCDAC, 5, 4, adcpol_txt);
-
-static const DECLARE_TLV_DB_SCALE(pga_tlv, -1725, 75, 0);
-static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1);
-static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
-static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
-static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
-
-static const struct snd_kcontrol_new wm8988_snd_controls[] = {
-
-SOC_ENUM("Bass Boost", bass_boost),
-SOC_ENUM("Bass Filter", bass_filter),
-SOC_SINGLE("Bass Volume", WM8988_BASS, 0, 15, 1),
-
-SOC_SINGLE("Treble Volume", WM8988_TREBLE, 0, 15, 0),
-SOC_ENUM("Treble Cut-off", treble),
-
-SOC_SINGLE("3D Switch", WM8988_3D, 0, 1, 0),
-SOC_SINGLE("3D Volume", WM8988_3D, 1, 15, 0),
-SOC_ENUM("3D Lower Cut-off", stereo_3d_lc),
-SOC_ENUM("3D Upper Cut-off", stereo_3d_uc),
-SOC_ENUM("3D Mode", stereo_3d_func),
-
-SOC_SINGLE("ALC Capture Target Volume", WM8988_ALC1, 0, 7, 0),
-SOC_SINGLE("ALC Capture Max Volume", WM8988_ALC1, 4, 7, 0),
-SOC_ENUM("ALC Capture Function", alc_func),
-SOC_SINGLE("ALC Capture ZC Switch", WM8988_ALC2, 7, 1, 0),
-SOC_SINGLE("ALC Capture Hold Time", WM8988_ALC2, 0, 15, 0),
-SOC_SINGLE("ALC Capture Decay Time", WM8988_ALC3, 4, 15, 0),
-SOC_SINGLE("ALC Capture Attack Time", WM8988_ALC3, 0, 15, 0),
-SOC_SINGLE("ALC Capture NG Threshold", WM8988_NGATE, 3, 31, 0),
-SOC_ENUM("ALC Capture NG Type", ng_type),
-SOC_SINGLE("ALC Capture NG Switch", WM8988_NGATE, 0, 1, 0),
-
-SOC_SINGLE("ZC Timeout Switch", WM8988_ADCTL1, 0, 1, 0),
-
-SOC_DOUBLE_R_TLV("Capture Digital Volume", WM8988_LADC, WM8988_RADC,
- 0, 255, 0, adc_tlv),
-SOC_DOUBLE_R_TLV("Capture Volume", WM8988_LINVOL, WM8988_RINVOL,
- 0, 63, 0, pga_tlv),
-SOC_DOUBLE_R("Capture ZC Switch", WM8988_LINVOL, WM8988_RINVOL, 6, 1, 0),
-SOC_DOUBLE_R("Capture Switch", WM8988_LINVOL, WM8988_RINVOL, 7, 1, 1),
-
-SOC_ENUM("Playback De-emphasis", deemph),
-
-SOC_ENUM("Capture Polarity", adcpol),
-SOC_SINGLE("Playback 6dB Attenuate", WM8988_ADCDAC, 7, 1, 0),
-SOC_SINGLE("Capture 6dB Attenuate", WM8988_ADCDAC, 8, 1, 0),
-
-SOC_DOUBLE_R_TLV("PCM Volume", WM8988_LDAC, WM8988_RDAC, 0, 255, 0, dac_tlv),
-
-SOC_SINGLE_TLV("Left Mixer Left Bypass Volume", WM8988_LOUTM1, 4, 7, 1,
- bypass_tlv),
-SOC_SINGLE_TLV("Left Mixer Right Bypass Volume", WM8988_LOUTM2, 4, 7, 1,
- bypass_tlv),
-SOC_SINGLE_TLV("Right Mixer Left Bypass Volume", WM8988_ROUTM1, 4, 7, 1,
- bypass_tlv),
-SOC_SINGLE_TLV("Right Mixer Right Bypass Volume", WM8988_ROUTM2, 4, 7, 1,
- bypass_tlv),
-
-SOC_DOUBLE_R("Output 1 Playback ZC Switch", WM8988_LOUT1V,
- WM8988_ROUT1V, 7, 1, 0),
-SOC_DOUBLE_R_TLV("Output 1 Playback Volume", WM8988_LOUT1V, WM8988_ROUT1V,
- 0, 127, 0, out_tlv),
-
-SOC_DOUBLE_R("Output 2 Playback ZC Switch", WM8988_LOUT2V,
- WM8988_ROUT2V, 7, 1, 0),
-SOC_DOUBLE_R_TLV("Output 2 Playback Volume", WM8988_LOUT2V, WM8988_ROUT2V,
- 0, 127, 0, out_tlv),
-
-};
-
-/*
- * DAPM Controls
- */
-
-static int wm8988_lrc_control(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- u16 adctl2 = snd_soc_read(codec, WM8988_ADCTL2);
-
- /* Use the DAC to gate LRC if active, otherwise use ADC */
- if (snd_soc_read(codec, WM8988_PWR2) & 0x180)
- adctl2 &= ~0x4;
- else
- adctl2 |= 0x4;
-
- return snd_soc_write(codec, WM8988_ADCTL2, adctl2);
-}
-
-static const char *wm8988_line_texts[] = {
- "Line 1", "Line 2", "PGA", "Differential"};
-
-static const unsigned int wm8988_line_values[] = {
- 0, 1, 3, 4};
-
-static const struct soc_enum wm8988_lline_enum =
- SOC_VALUE_ENUM_SINGLE(WM8988_LOUTM1, 0, 7,
- ARRAY_SIZE(wm8988_line_texts),
- wm8988_line_texts,
- wm8988_line_values);
-static const struct snd_kcontrol_new wm8988_left_line_controls =
- SOC_DAPM_VALUE_ENUM("Route", wm8988_lline_enum);
-
-static const struct soc_enum wm8988_rline_enum =
- SOC_VALUE_ENUM_SINGLE(WM8988_ROUTM1, 0, 7,
- ARRAY_SIZE(wm8988_line_texts),
- wm8988_line_texts,
- wm8988_line_values);
-static const struct snd_kcontrol_new wm8988_right_line_controls =
- SOC_DAPM_VALUE_ENUM("Route", wm8988_lline_enum);
-
-/* Left Mixer */
-static const struct snd_kcontrol_new wm8988_left_mixer_controls[] = {
- SOC_DAPM_SINGLE("Playback Switch", WM8988_LOUTM1, 8, 1, 0),
- SOC_DAPM_SINGLE("Left Bypass Switch", WM8988_LOUTM1, 7, 1, 0),
- SOC_DAPM_SINGLE("Right Playback Switch", WM8988_LOUTM2, 8, 1, 0),
- SOC_DAPM_SINGLE("Right Bypass Switch", WM8988_LOUTM2, 7, 1, 0),
-};
-
-/* Right Mixer */
-static const struct snd_kcontrol_new wm8988_right_mixer_controls[] = {
- SOC_DAPM_SINGLE("Left Playback Switch", WM8988_ROUTM1, 8, 1, 0),
- SOC_DAPM_SINGLE("Left Bypass Switch", WM8988_ROUTM1, 7, 1, 0),
- SOC_DAPM_SINGLE("Playback Switch", WM8988_ROUTM2, 8, 1, 0),
- SOC_DAPM_SINGLE("Right Bypass Switch", WM8988_ROUTM2, 7, 1, 0),
-};
-
-static const char *wm8988_pga_sel[] = {"Line 1", "Line 2", "Differential"};
-static const unsigned int wm8988_pga_val[] = { 0, 1, 3 };
-
-/* Left PGA Mux */
-static const struct soc_enum wm8988_lpga_enum =
- SOC_VALUE_ENUM_SINGLE(WM8988_LADCIN, 6, 3,
- ARRAY_SIZE(wm8988_pga_sel),
- wm8988_pga_sel,
- wm8988_pga_val);
-static const struct snd_kcontrol_new wm8988_left_pga_controls =
- SOC_DAPM_VALUE_ENUM("Route", wm8988_lpga_enum);
-
-/* Right PGA Mux */
-static const struct soc_enum wm8988_rpga_enum =
- SOC_VALUE_ENUM_SINGLE(WM8988_RADCIN, 6, 3,
- ARRAY_SIZE(wm8988_pga_sel),
- wm8988_pga_sel,
- wm8988_pga_val);
-static const struct snd_kcontrol_new wm8988_right_pga_controls =
- SOC_DAPM_VALUE_ENUM("Route", wm8988_rpga_enum);
-
-/* Differential Mux */
-static const char *wm8988_diff_sel[] = {"Line 1", "Line 2"};
-static const struct soc_enum diffmux =
- SOC_ENUM_SINGLE(WM8988_ADCIN, 8, 2, wm8988_diff_sel);
-static const struct snd_kcontrol_new wm8988_diffmux_controls =
- SOC_DAPM_ENUM("Route", diffmux);
-
-/* Mono ADC Mux */
-static const char *wm8988_mono_mux[] = {"Stereo", "Mono (Left)",
- "Mono (Right)", "Digital Mono"};
-static const struct soc_enum monomux =
- SOC_ENUM_SINGLE(WM8988_ADCIN, 6, 4, wm8988_mono_mux);
-static const struct snd_kcontrol_new wm8988_monomux_controls =
- SOC_DAPM_ENUM("Route", monomux);
-
-static const struct snd_soc_dapm_widget wm8988_dapm_widgets[] = {
- SND_SOC_DAPM_SUPPLY("Mic Bias", WM8988_PWR1, 1, 0, NULL, 0),
-
- SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0,
- &wm8988_diffmux_controls),
- SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0,
- &wm8988_monomux_controls),
- SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0,
- &wm8988_monomux_controls),
-
- SND_SOC_DAPM_MUX("Left PGA Mux", WM8988_PWR1, 5, 0,
- &wm8988_left_pga_controls),
- SND_SOC_DAPM_MUX("Right PGA Mux", WM8988_PWR1, 4, 0,
- &wm8988_right_pga_controls),
-
- SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0,
- &wm8988_left_line_controls),
- SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0,
- &wm8988_right_line_controls),
-
- SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8988_PWR1, 2, 0),
- SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8988_PWR1, 3, 0),
-
- SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8988_PWR2, 7, 0),
- SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8988_PWR2, 8, 0),
-
- SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
- &wm8988_left_mixer_controls[0],
- ARRAY_SIZE(wm8988_left_mixer_controls)),
- SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
- &wm8988_right_mixer_controls[0],
- ARRAY_SIZE(wm8988_right_mixer_controls)),
-
- SND_SOC_DAPM_PGA("Right Out 2", WM8988_PWR2, 3, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Left Out 2", WM8988_PWR2, 4, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Right Out 1", WM8988_PWR2, 5, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Left Out 1", WM8988_PWR2, 6, 0, NULL, 0),
-
- SND_SOC_DAPM_POST("LRC control", wm8988_lrc_control),
-
- SND_SOC_DAPM_OUTPUT("LOUT1"),
- SND_SOC_DAPM_OUTPUT("ROUT1"),
- SND_SOC_DAPM_OUTPUT("LOUT2"),
- SND_SOC_DAPM_OUTPUT("ROUT2"),
- SND_SOC_DAPM_OUTPUT("VREF"),
-
- SND_SOC_DAPM_INPUT("LINPUT1"),
- SND_SOC_DAPM_INPUT("LINPUT2"),
- SND_SOC_DAPM_INPUT("RINPUT1"),
- SND_SOC_DAPM_INPUT("RINPUT2"),
-};
-
-static const struct snd_soc_dapm_route wm8988_dapm_routes[] = {
-
- { "Left Line Mux", "Line 1", "LINPUT1" },
- { "Left Line Mux", "Line 2", "LINPUT2" },
- { "Left Line Mux", "PGA", "Left PGA Mux" },
- { "Left Line Mux", "Differential", "Differential Mux" },
-
- { "Right Line Mux", "Line 1", "RINPUT1" },
- { "Right Line Mux", "Line 2", "RINPUT2" },
- { "Right Line Mux", "PGA", "Right PGA Mux" },
- { "Right Line Mux", "Differential", "Differential Mux" },
-
- { "Left PGA Mux", "Line 1", "LINPUT1" },
- { "Left PGA Mux", "Line 2", "LINPUT2" },
- { "Left PGA Mux", "Differential", "Differential Mux" },
-
- { "Right PGA Mux", "Line 1", "RINPUT1" },
- { "Right PGA Mux", "Line 2", "RINPUT2" },
- { "Right PGA Mux", "Differential", "Differential Mux" },
-
- { "Differential Mux", "Line 1", "LINPUT1" },
- { "Differential Mux", "Line 1", "RINPUT1" },
- { "Differential Mux", "Line 2", "LINPUT2" },
- { "Differential Mux", "Line 2", "RINPUT2" },
-
- { "Left ADC Mux", "Stereo", "Left PGA Mux" },
- { "Left ADC Mux", "Mono (Left)", "Left PGA Mux" },
- { "Left ADC Mux", "Digital Mono", "Left PGA Mux" },
-
- { "Right ADC Mux", "Stereo", "Right PGA Mux" },
- { "Right ADC Mux", "Mono (Right)", "Right PGA Mux" },
- { "Right ADC Mux", "Digital Mono", "Right PGA Mux" },
-
- { "Left ADC", NULL, "Left ADC Mux" },
- { "Right ADC", NULL, "Right ADC Mux" },
-
- { "Left Line Mux", "Line 1", "LINPUT1" },
- { "Left Line Mux", "Line 2", "LINPUT2" },
- { "Left Line Mux", "PGA", "Left PGA Mux" },
- { "Left Line Mux", "Differential", "Differential Mux" },
-
- { "Right Line Mux", "Line 1", "RINPUT1" },
- { "Right Line Mux", "Line 2", "RINPUT2" },
- { "Right Line Mux", "PGA", "Right PGA Mux" },
- { "Right Line Mux", "Differential", "Differential Mux" },
-
- { "Left Mixer", "Playback Switch", "Left DAC" },
- { "Left Mixer", "Left Bypass Switch", "Left Line Mux" },
- { "Left Mixer", "Right Playback Switch", "Right DAC" },
- { "Left Mixer", "Right Bypass Switch", "Right Line Mux" },
-
- { "Right Mixer", "Left Playback Switch", "Left DAC" },
- { "Right Mixer", "Left Bypass Switch", "Left Line Mux" },
- { "Right Mixer", "Playback Switch", "Right DAC" },
- { "Right Mixer", "Right Bypass Switch", "Right Line Mux" },
-
- { "Left Out 1", NULL, "Left Mixer" },
- { "LOUT1", NULL, "Left Out 1" },
- { "Right Out 1", NULL, "Right Mixer" },
- { "ROUT1", NULL, "Right Out 1" },
-
- { "Left Out 2", NULL, "Left Mixer" },
- { "LOUT2", NULL, "Left Out 2" },
- { "Right Out 2", NULL, "Right Mixer" },
- { "ROUT2", NULL, "Right Out 2" },
-};
-
-struct _coeff_div {
- u32 mclk;
- u32 rate;
- u16 fs;
- u8 sr:5;
- u8 usb:1;
-};
-
-/* codec hifi mclk clock divider coefficients */
-static const struct _coeff_div coeff_div[] = {
- /* 8k */
- {12288000, 8000, 1536, 0x6, 0x0},
- {11289600, 8000, 1408, 0x16, 0x0},
- {18432000, 8000, 2304, 0x7, 0x0},
- {16934400, 8000, 2112, 0x17, 0x0},
- {12000000, 8000, 1500, 0x6, 0x1},
-
- /* 11.025k */
- {11289600, 11025, 1024, 0x18, 0x0},
- {16934400, 11025, 1536, 0x19, 0x0},
- {12000000, 11025, 1088, 0x19, 0x1},
-
- /* 16k */
- {12288000, 16000, 768, 0xa, 0x0},
- {18432000, 16000, 1152, 0xb, 0x0},
- {12000000, 16000, 750, 0xa, 0x1},
-
- /* 22.05k */
- {11289600, 22050, 512, 0x1a, 0x0},
- {16934400, 22050, 768, 0x1b, 0x0},
- {12000000, 22050, 544, 0x1b, 0x1},
-
- /* 32k */
- {12288000, 32000, 384, 0xc, 0x0},
- {18432000, 32000, 576, 0xd, 0x0},
- {12000000, 32000, 375, 0xa, 0x1},
-
- /* 44.1k */
- {11289600, 44100, 256, 0x10, 0x0},
- {16934400, 44100, 384, 0x11, 0x0},
- {12000000, 44100, 272, 0x11, 0x1},
-
- /* 48k */
- {12288000, 48000, 256, 0x0, 0x0},
- {18432000, 48000, 384, 0x1, 0x0},
- {12000000, 48000, 250, 0x0, 0x1},
-
- /* 88.2k */
- {11289600, 88200, 128, 0x1e, 0x0},
- {16934400, 88200, 192, 0x1f, 0x0},
- {12000000, 88200, 136, 0x1f, 0x1},
-
- /* 96k */
- {12288000, 96000, 128, 0xe, 0x0},
- {18432000, 96000, 192, 0xf, 0x0},
- {12000000, 96000, 125, 0xe, 0x1},
-};
-
-static inline int get_coeff(int mclk, int rate)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
- if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
- return i;
- }
-
- return -EINVAL;
-}
-
-/* The set of rates we can generate from the above for each SYSCLK */
-
-static unsigned int rates_12288[] = {
- 8000, 12000, 16000, 24000, 24000, 32000, 48000, 96000,
-};
-
-static struct snd_pcm_hw_constraint_list constraints_12288 = {
- .count = ARRAY_SIZE(rates_12288),
- .list = rates_12288,
-};
-
-static unsigned int rates_112896[] = {
- 8000, 11025, 22050, 44100,
-};
-
-static struct snd_pcm_hw_constraint_list constraints_112896 = {
- .count = ARRAY_SIZE(rates_112896),
- .list = rates_112896,
-};
-
-static unsigned int rates_12[] = {
- 8000, 11025, 12000, 16000, 22050, 2400, 32000, 41100, 48000,
- 48000, 88235, 96000,
-};
-
-static struct snd_pcm_hw_constraint_list constraints_12 = {
- .count = ARRAY_SIZE(rates_12),
- .list = rates_12,
-};
-
-/*
- * Note that this should be called from init rather than from hw_params.
- */
-static int wm8988_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
-
- switch (freq) {
- case 11289600:
- case 18432000:
- case 22579200:
- case 36864000:
- wm8988->sysclk_constraints = &constraints_112896;
- wm8988->sysclk = freq;
- return 0;
-
- case 12288000:
- case 16934400:
- case 24576000:
- case 33868800:
- wm8988->sysclk_constraints = &constraints_12288;
- wm8988->sysclk = freq;
- return 0;
-
- case 12000000:
- case 24000000:
- wm8988->sysclk_constraints = &constraints_12;
- wm8988->sysclk = freq;
- return 0;
- }
- return -EINVAL;
-}
-
-static int wm8988_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 iface = 0;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- iface = 0x0040;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= 0x0002;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= 0x0001;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= 0x0003;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- iface |= 0x0013;
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= 0x0090;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= 0x0080;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- iface |= 0x0010;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM8988_IFACE, iface);
- return 0;
-}
-
-static int wm8988_pcm_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
-
- /* The set of sample rates that can be supported depends on the
- * MCLK supplied to the CODEC - enforce this.
- */
- if (!wm8988->sysclk) {
- dev_err(codec->dev,
- "No MCLK configured, call set_sysclk() on init\n");
- return -EINVAL;
- }
-
- snd_pcm_hw_constraint_list(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- wm8988->sysclk_constraints);
-
- return 0;
-}
-
-static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
- u16 iface = snd_soc_read(codec, WM8988_IFACE) & 0x1f3;
- u16 srate = snd_soc_read(codec, WM8988_SRATE) & 0x180;
- int coeff;
-
- coeff = get_coeff(wm8988->sysclk, params_rate(params));
- if (coeff < 0) {
- coeff = get_coeff(wm8988->sysclk / 2, params_rate(params));
- srate |= 0x40;
- }
- if (coeff < 0) {
- dev_err(codec->dev,
- "Unable to configure sample rate %dHz with %dHz MCLK\n",
- params_rate(params), wm8988->sysclk);
- return coeff;
- }
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= 0x0004;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface |= 0x0008;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- iface |= 0x000c;
- break;
- }
-
- /* set iface & srate */
- snd_soc_write(codec, WM8988_IFACE, iface);
- if (coeff >= 0)
- snd_soc_write(codec, WM8988_SRATE, srate |
- (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
-
- return 0;
-}
-
-static int wm8988_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 mute_reg = snd_soc_read(codec, WM8988_ADCDAC) & 0xfff7;
-
- if (mute)
- snd_soc_write(codec, WM8988_ADCDAC, mute_reg | 0x8);
- else
- snd_soc_write(codec, WM8988_ADCDAC, mute_reg);
- return 0;
-}
-
-static int wm8988_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
- u16 pwr_reg = snd_soc_read(codec, WM8988_PWR1) & ~0x1c1;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- /* VREF, VMID=2x50k, digital enabled */
- snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x00c0);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- regcache_sync(wm8988->regmap);
-
- /* VREF, VMID=2x5k */
- snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1);
-
- /* Charge caps */
- msleep(100);
- }
-
- /* VREF, VMID=2*500k, digital stopped */
- snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x0141);
- break;
-
- case SND_SOC_BIAS_OFF:
- snd_soc_write(codec, WM8988_PWR1, 0x0000);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define WM8988_RATES SNDRV_PCM_RATE_8000_96000
-
-#define WM8988_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops wm8988_ops = {
- .startup = wm8988_pcm_startup,
- .hw_params = wm8988_pcm_hw_params,
- .set_fmt = wm8988_set_dai_fmt,
- .set_sysclk = wm8988_set_dai_sysclk,
- .digital_mute = wm8988_mute,
-};
-
-static struct snd_soc_dai_driver wm8988_dai = {
- .name = "wm8988-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8988_RATES,
- .formats = WM8988_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8988_RATES,
- .formats = WM8988_FORMATS,
- },
- .ops = &wm8988_ops,
- .symmetric_rates = 1,
-};
-
-static int wm8988_suspend(struct snd_soc_codec *codec)
-{
- struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
-
- wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF);
- regcache_mark_dirty(wm8988->regmap);
- return 0;
-}
-
-static int wm8988_resume(struct snd_soc_codec *codec)
-{
- wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-
-static int wm8988_probe(struct snd_soc_codec *codec)
-{
- struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
- int ret = 0;
-
- codec->control_data = wm8988->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- ret = wm8988_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- return ret;
- }
-
- /* set the update bits (we always update left then right) */
- snd_soc_update_bits(codec, WM8988_RADC, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8988_RDAC, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8988_ROUT1V, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8988_ROUT2V, 0x0100, 0x0100);
- snd_soc_update_bits(codec, WM8988_RINVOL, 0x0100, 0x0100);
-
- wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-
-static int wm8988_remove(struct snd_soc_codec *codec)
-{
- wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8988 = {
- .probe = wm8988_probe,
- .remove = wm8988_remove,
- .suspend = wm8988_suspend,
- .resume = wm8988_resume,
- .set_bias_level = wm8988_set_bias_level,
-
- .controls = wm8988_snd_controls,
- .num_controls = ARRAY_SIZE(wm8988_snd_controls),
- .dapm_widgets = wm8988_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8988_dapm_widgets),
- .dapm_routes = wm8988_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes),
-};
-
-static struct regmap_config wm8988_regmap = {
- .reg_bits = 7,
- .val_bits = 9,
-
- .max_register = WM8988_LPPB,
- .writeable_reg = wm8988_writeable,
-
- .cache_type = REGCACHE_RBTREE,
- .reg_defaults = wm8988_reg_defaults,
- .num_reg_defaults = ARRAY_SIZE(wm8988_reg_defaults),
-};
-
-#if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8988_spi_probe(struct spi_device *spi)
-{
- struct wm8988_priv *wm8988;
- int ret;
-
- wm8988 = devm_kzalloc(&spi->dev, sizeof(struct wm8988_priv),
- GFP_KERNEL);
- if (wm8988 == NULL)
- return -ENOMEM;
-
- wm8988->regmap = regmap_init_spi(spi, &wm8988_regmap);
- if (IS_ERR(wm8988->regmap)) {
- ret = PTR_ERR(wm8988->regmap);
- dev_err(&spi->dev, "Failed to init regmap: %d\n", ret);
- return ret;
- }
-
- spi_set_drvdata(spi, wm8988);
-
- ret = snd_soc_register_codec(&spi->dev,
- &soc_codec_dev_wm8988, &wm8988_dai, 1);
- if (ret != 0)
- regmap_exit(wm8988->regmap);
-
- return ret;
-}
-
-static int __devexit wm8988_spi_remove(struct spi_device *spi)
-{
- struct wm8988_priv *wm8988 = spi_get_drvdata(spi);
- snd_soc_unregister_codec(&spi->dev);
- regmap_exit(wm8988->regmap);
- return 0;
-}
-
-static struct spi_driver wm8988_spi_driver = {
- .driver = {
- .name = "wm8988",
- .owner = THIS_MODULE,
- },
- .probe = wm8988_spi_probe,
- .remove = __devexit_p(wm8988_spi_remove),
-};
-#endif /* CONFIG_SPI_MASTER */
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8988_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8988_priv *wm8988;
- int ret;
-
- wm8988 = devm_kzalloc(&i2c->dev, sizeof(struct wm8988_priv),
- GFP_KERNEL);
- if (wm8988 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm8988);
-
- wm8988->regmap = regmap_init_i2c(i2c, &wm8988_regmap);
- if (IS_ERR(wm8988->regmap)) {
- ret = PTR_ERR(wm8988->regmap);
- dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
- return ret;
- }
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8988, &wm8988_dai, 1);
- if (ret != 0)
- regmap_exit(wm8988->regmap);
-
- return ret;
-}
-
-static __devexit int wm8988_i2c_remove(struct i2c_client *client)
-{
- struct wm8988_priv *wm8988 = i2c_get_clientdata(client);
- snd_soc_unregister_codec(&client->dev);
- regmap_exit(wm8988->regmap);
- return 0;
-}
-
-static const struct i2c_device_id wm8988_i2c_id[] = {
- { "wm8988", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id);
-
-static struct i2c_driver wm8988_i2c_driver = {
- .driver = {
- .name = "wm8988",
- .owner = THIS_MODULE,
- },
- .probe = wm8988_i2c_probe,
- .remove = __devexit_p(wm8988_i2c_remove),
- .id_table = wm8988_i2c_id,
-};
-#endif
-
-static int __init wm8988_modinit(void)
-{
- int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&wm8988_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8988 I2C driver: %d\n",
- ret);
- }
-#endif
-#if defined(CONFIG_SPI_MASTER)
- ret = spi_register_driver(&wm8988_spi_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8988 SPI driver: %d\n",
- ret);
- }
-#endif
- return ret;
-}
-module_init(wm8988_modinit);
-
-static void __exit wm8988_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&wm8988_i2c_driver);
-#endif
-#if defined(CONFIG_SPI_MASTER)
- spi_unregister_driver(&wm8988_spi_driver);
-#endif
-}
-module_exit(wm8988_exit);
-
-
-MODULE_DESCRIPTION("ASoC WM8988 driver");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8988.h b/ANDROID_3.4.5/sound/soc/codecs/wm8988.h
deleted file mode 100644
index 5c04024e..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8988.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2005 Openedhand Ltd.
- *
- * Author: Richard Purdie <richard@openedhand.com>
- *
- * Based on WM8753.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#ifndef _WM8988_H
-#define _WM8988_H
-
-/* WM8988 register space */
-
-#define WM8988_LINVOL 0x00
-#define WM8988_RINVOL 0x01
-#define WM8988_LOUT1V 0x02
-#define WM8988_ROUT1V 0x03
-#define WM8988_ADCDAC 0x05
-#define WM8988_IFACE 0x07
-#define WM8988_SRATE 0x08
-#define WM8988_LDAC 0x0a
-#define WM8988_RDAC 0x0b
-#define WM8988_BASS 0x0c
-#define WM8988_TREBLE 0x0d
-#define WM8988_RESET 0x0f
-#define WM8988_3D 0x10
-#define WM8988_ALC1 0x11
-#define WM8988_ALC2 0x12
-#define WM8988_ALC3 0x13
-#define WM8988_NGATE 0x14
-#define WM8988_LADC 0x15
-#define WM8988_RADC 0x16
-#define WM8988_ADCTL1 0x17
-#define WM8988_ADCTL2 0x18
-#define WM8988_PWR1 0x19
-#define WM8988_PWR2 0x1a
-#define WM8988_ADCTL3 0x1b
-#define WM8988_ADCIN 0x1f
-#define WM8988_LADCIN 0x20
-#define WM8988_RADCIN 0x21
-#define WM8988_LOUTM1 0x22
-#define WM8988_LOUTM2 0x23
-#define WM8988_ROUTM1 0x24
-#define WM8988_ROUTM2 0x25
-#define WM8988_LOUT2V 0x28
-#define WM8988_ROUT2V 0x29
-#define WM8988_LPPB 0x43
-#define WM8988_NUM_REG 0x44
-
-#define WM8988_SYSCLK 0
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8990.c b/ANDROID_3.4.5/sound/soc/codecs/wm8990.c
deleted file mode 100644
index 9d242351..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8990.c
+++ /dev/null
@@ -1,1453 +0,0 @@
-/*
- * wm8990.c -- WM8990 ALSA Soc Audio driver
- *
- * Copyright 2008 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood <lrg@slimlogic.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <asm/div64.h>
-
-#include "wm8990.h"
-
-/* codec private data */
-struct wm8990_priv {
- enum snd_soc_control_type control_type;
- unsigned int sysclk;
- unsigned int pcmclk;
-};
-
-static int wm8990_volatile_register(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- switch (reg) {
- case WM8990_RESET:
- return 1;
- default:
- return 0;
- }
-}
-
-static const u16 wm8990_reg[] = {
- 0x8990, /* R0 - Reset */
- 0x0000, /* R1 - Power Management (1) */
- 0x6000, /* R2 - Power Management (2) */
- 0x0000, /* R3 - Power Management (3) */
- 0x4050, /* R4 - Audio Interface (1) */
- 0x4000, /* R5 - Audio Interface (2) */
- 0x01C8, /* R6 - Clocking (1) */
- 0x0000, /* R7 - Clocking (2) */
- 0x0040, /* R8 - Audio Interface (3) */
- 0x0040, /* R9 - Audio Interface (4) */
- 0x0004, /* R10 - DAC CTRL */
- 0x00C0, /* R11 - Left DAC Digital Volume */
- 0x00C0, /* R12 - Right DAC Digital Volume */
- 0x0000, /* R13 - Digital Side Tone */
- 0x0100, /* R14 - ADC CTRL */
- 0x00C0, /* R15 - Left ADC Digital Volume */
- 0x00C0, /* R16 - Right ADC Digital Volume */
- 0x0000, /* R17 */
- 0x0000, /* R18 - GPIO CTRL 1 */
- 0x1000, /* R19 - GPIO1 & GPIO2 */
- 0x1010, /* R20 - GPIO3 & GPIO4 */
- 0x1010, /* R21 - GPIO5 & GPIO6 */
- 0x8000, /* R22 - GPIOCTRL 2 */
- 0x0800, /* R23 - GPIO_POL */
- 0x008B, /* R24 - Left Line Input 1&2 Volume */
- 0x008B, /* R25 - Left Line Input 3&4 Volume */
- 0x008B, /* R26 - Right Line Input 1&2 Volume */
- 0x008B, /* R27 - Right Line Input 3&4 Volume */
- 0x0000, /* R28 - Left Output Volume */
- 0x0000, /* R29 - Right Output Volume */
- 0x0066, /* R30 - Line Outputs Volume */
- 0x0022, /* R31 - Out3/4 Volume */
- 0x0079, /* R32 - Left OPGA Volume */
- 0x0079, /* R33 - Right OPGA Volume */
- 0x0003, /* R34 - Speaker Volume */
- 0x0003, /* R35 - ClassD1 */
- 0x0000, /* R36 */
- 0x0100, /* R37 - ClassD3 */
- 0x0079, /* R38 - ClassD4 */
- 0x0000, /* R39 - Input Mixer1 */
- 0x0000, /* R40 - Input Mixer2 */
- 0x0000, /* R41 - Input Mixer3 */
- 0x0000, /* R42 - Input Mixer4 */
- 0x0000, /* R43 - Input Mixer5 */
- 0x0000, /* R44 - Input Mixer6 */
- 0x0000, /* R45 - Output Mixer1 */
- 0x0000, /* R46 - Output Mixer2 */
- 0x0000, /* R47 - Output Mixer3 */
- 0x0000, /* R48 - Output Mixer4 */
- 0x0000, /* R49 - Output Mixer5 */
- 0x0000, /* R50 - Output Mixer6 */
- 0x0180, /* R51 - Out3/4 Mixer */
- 0x0000, /* R52 - Line Mixer1 */
- 0x0000, /* R53 - Line Mixer2 */
- 0x0000, /* R54 - Speaker Mixer */
- 0x0000, /* R55 - Additional Control */
- 0x0000, /* R56 - AntiPOP1 */
- 0x0000, /* R57 - AntiPOP2 */
- 0x0000, /* R58 - MICBIAS */
- 0x0000, /* R59 */
- 0x0008, /* R60 - PLL1 */
- 0x0031, /* R61 - PLL2 */
- 0x0026, /* R62 - PLL3 */
- 0x0000, /* R63 - Driver internal */
-};
-
-#define wm8990_reset(c) snd_soc_write(c, WM8990_RESET, 0)
-
-static const DECLARE_TLV_DB_SCALE(rec_mix_tlv, -1500, 600, 0);
-
-static const DECLARE_TLV_DB_SCALE(in_pga_tlv, -1650, 3000, 0);
-
-static const DECLARE_TLV_DB_SCALE(out_mix_tlv, 0, -2100, 0);
-
-static const DECLARE_TLV_DB_SCALE(out_pga_tlv, -7300, 600, 0);
-
-static const DECLARE_TLV_DB_SCALE(out_omix_tlv, -600, 0, 0);
-
-static const DECLARE_TLV_DB_SCALE(out_dac_tlv, -7163, 0, 0);
-
-static const DECLARE_TLV_DB_SCALE(in_adc_tlv, -7163, 1763, 0);
-
-static const DECLARE_TLV_DB_SCALE(out_sidetone_tlv, -3600, 0, 0);
-
-static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- int reg = mc->reg;
- int ret;
- u16 val;
-
- ret = snd_soc_put_volsw(kcontrol, ucontrol);
- if (ret < 0)
- return ret;
-
- /* now hit the volume update bits (always bit 8) */
- val = snd_soc_read(codec, reg);
- return snd_soc_write(codec, reg, val | 0x0100);
-}
-
-#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\
- tlv_array) {\
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
- .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
- SNDRV_CTL_ELEM_ACCESS_READWRITE,\
- .tlv.p = (tlv_array), \
- .info = snd_soc_info_volsw, \
- .get = snd_soc_get_volsw, .put = wm899x_outpga_put_volsw_vu, \
- .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
-
-
-static const char *wm8990_digital_sidetone[] =
- {"None", "Left ADC", "Right ADC", "Reserved"};
-
-static const struct soc_enum wm8990_left_digital_sidetone_enum =
-SOC_ENUM_SINGLE(WM8990_DIGITAL_SIDE_TONE,
- WM8990_ADC_TO_DACL_SHIFT,
- WM8990_ADC_TO_DACL_MASK,
- wm8990_digital_sidetone);
-
-static const struct soc_enum wm8990_right_digital_sidetone_enum =
-SOC_ENUM_SINGLE(WM8990_DIGITAL_SIDE_TONE,
- WM8990_ADC_TO_DACR_SHIFT,
- WM8990_ADC_TO_DACR_MASK,
- wm8990_digital_sidetone);
-
-static const char *wm8990_adcmode[] =
- {"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"};
-
-static const struct soc_enum wm8990_right_adcmode_enum =
-SOC_ENUM_SINGLE(WM8990_ADC_CTRL,
- WM8990_ADC_HPF_CUT_SHIFT,
- WM8990_ADC_HPF_CUT_MASK,
- wm8990_adcmode);
-
-static const struct snd_kcontrol_new wm8990_snd_controls[] = {
-/* INMIXL */
-SOC_SINGLE("LIN12 PGA Boost", WM8990_INPUT_MIXER3, WM8990_L12MNBST_BIT, 1, 0),
-SOC_SINGLE("LIN34 PGA Boost", WM8990_INPUT_MIXER3, WM8990_L34MNBST_BIT, 1, 0),
-/* INMIXR */
-SOC_SINGLE("RIN12 PGA Boost", WM8990_INPUT_MIXER3, WM8990_R12MNBST_BIT, 1, 0),
-SOC_SINGLE("RIN34 PGA Boost", WM8990_INPUT_MIXER3, WM8990_R34MNBST_BIT, 1, 0),
-
-/* LOMIX */
-SOC_SINGLE_TLV("LOMIX LIN3 Bypass Volume", WM8990_OUTPUT_MIXER3,
- WM8990_LLI3LOVOL_SHIFT, WM8990_LLI3LOVOL_MASK, 1, out_mix_tlv),
-SOC_SINGLE_TLV("LOMIX RIN12 PGA Bypass Volume", WM8990_OUTPUT_MIXER3,
- WM8990_LR12LOVOL_SHIFT, WM8990_LR12LOVOL_MASK, 1, out_mix_tlv),
-SOC_SINGLE_TLV("LOMIX LIN12 PGA Bypass Volume", WM8990_OUTPUT_MIXER3,
- WM8990_LL12LOVOL_SHIFT, WM8990_LL12LOVOL_MASK, 1, out_mix_tlv),
-SOC_SINGLE_TLV("LOMIX RIN3 Bypass Volume", WM8990_OUTPUT_MIXER5,
- WM8990_LRI3LOVOL_SHIFT, WM8990_LRI3LOVOL_MASK, 1, out_mix_tlv),
-SOC_SINGLE_TLV("LOMIX AINRMUX Bypass Volume", WM8990_OUTPUT_MIXER5,
- WM8990_LRBLOVOL_SHIFT, WM8990_LRBLOVOL_MASK, 1, out_mix_tlv),
-SOC_SINGLE_TLV("LOMIX AINLMUX Bypass Volume", WM8990_OUTPUT_MIXER5,
- WM8990_LRBLOVOL_SHIFT, WM8990_LRBLOVOL_MASK, 1, out_mix_tlv),
-
-/* ROMIX */
-SOC_SINGLE_TLV("ROMIX RIN3 Bypass Volume", WM8990_OUTPUT_MIXER4,
- WM8990_RRI3ROVOL_SHIFT, WM8990_RRI3ROVOL_MASK, 1, out_mix_tlv),
-SOC_SINGLE_TLV("ROMIX LIN12 PGA Bypass Volume", WM8990_OUTPUT_MIXER4,
- WM8990_RL12ROVOL_SHIFT, WM8990_RL12ROVOL_MASK, 1, out_mix_tlv),
-SOC_SINGLE_TLV("ROMIX RIN12 PGA Bypass Volume", WM8990_OUTPUT_MIXER4,
- WM8990_RR12ROVOL_SHIFT, WM8990_RR12ROVOL_MASK, 1, out_mix_tlv),
-SOC_SINGLE_TLV("ROMIX LIN3 Bypass Volume", WM8990_OUTPUT_MIXER6,
- WM8990_RLI3ROVOL_SHIFT, WM8990_RLI3ROVOL_MASK, 1, out_mix_tlv),
-SOC_SINGLE_TLV("ROMIX AINLMUX Bypass Volume", WM8990_OUTPUT_MIXER6,
- WM8990_RLBROVOL_SHIFT, WM8990_RLBROVOL_MASK, 1, out_mix_tlv),
-SOC_SINGLE_TLV("ROMIX AINRMUX Bypass Volume", WM8990_OUTPUT_MIXER6,
- WM8990_RRBROVOL_SHIFT, WM8990_RRBROVOL_MASK, 1, out_mix_tlv),
-
-/* LOUT */
-SOC_WM899X_OUTPGA_SINGLE_R_TLV("LOUT Volume", WM8990_LEFT_OUTPUT_VOLUME,
- WM8990_LOUTVOL_SHIFT, WM8990_LOUTVOL_MASK, 0, out_pga_tlv),
-SOC_SINGLE("LOUT ZC", WM8990_LEFT_OUTPUT_VOLUME, WM8990_LOZC_BIT, 1, 0),
-
-/* ROUT */
-SOC_WM899X_OUTPGA_SINGLE_R_TLV("ROUT Volume", WM8990_RIGHT_OUTPUT_VOLUME,
- WM8990_ROUTVOL_SHIFT, WM8990_ROUTVOL_MASK, 0, out_pga_tlv),
-SOC_SINGLE("ROUT ZC", WM8990_RIGHT_OUTPUT_VOLUME, WM8990_ROZC_BIT, 1, 0),
-
-/* LOPGA */
-SOC_WM899X_OUTPGA_SINGLE_R_TLV("LOPGA Volume", WM8990_LEFT_OPGA_VOLUME,
- WM8990_LOPGAVOL_SHIFT, WM8990_LOPGAVOL_MASK, 0, out_pga_tlv),
-SOC_SINGLE("LOPGA ZC Switch", WM8990_LEFT_OPGA_VOLUME,
- WM8990_LOPGAZC_BIT, 1, 0),
-
-/* ROPGA */
-SOC_WM899X_OUTPGA_SINGLE_R_TLV("ROPGA Volume", WM8990_RIGHT_OPGA_VOLUME,
- WM8990_ROPGAVOL_SHIFT, WM8990_ROPGAVOL_MASK, 0, out_pga_tlv),
-SOC_SINGLE("ROPGA ZC Switch", WM8990_RIGHT_OPGA_VOLUME,
- WM8990_ROPGAZC_BIT, 1, 0),
-
-SOC_SINGLE("LON Mute Switch", WM8990_LINE_OUTPUTS_VOLUME,
- WM8990_LONMUTE_BIT, 1, 0),
-SOC_SINGLE("LOP Mute Switch", WM8990_LINE_OUTPUTS_VOLUME,
- WM8990_LOPMUTE_BIT, 1, 0),
-SOC_SINGLE("LOP Attenuation Switch", WM8990_LINE_OUTPUTS_VOLUME,
- WM8990_LOATTN_BIT, 1, 0),
-SOC_SINGLE("RON Mute Switch", WM8990_LINE_OUTPUTS_VOLUME,
- WM8990_RONMUTE_BIT, 1, 0),
-SOC_SINGLE("ROP Mute Switch", WM8990_LINE_OUTPUTS_VOLUME,
- WM8990_ROPMUTE_BIT, 1, 0),
-SOC_SINGLE("ROP Attenuation Switch", WM8990_LINE_OUTPUTS_VOLUME,
- WM8990_ROATTN_BIT, 1, 0),
-
-SOC_SINGLE("OUT3 Mute Switch", WM8990_OUT3_4_VOLUME,
- WM8990_OUT3MUTE_BIT, 1, 0),
-SOC_SINGLE("OUT3 Attenuation Switch", WM8990_OUT3_4_VOLUME,
- WM8990_OUT3ATTN_BIT, 1, 0),
-
-SOC_SINGLE("OUT4 Mute Switch", WM8990_OUT3_4_VOLUME,
- WM8990_OUT4MUTE_BIT, 1, 0),
-SOC_SINGLE("OUT4 Attenuation Switch", WM8990_OUT3_4_VOLUME,
- WM8990_OUT4ATTN_BIT, 1, 0),
-
-SOC_SINGLE("Speaker Mode Switch", WM8990_CLASSD1,
- WM8990_CDMODE_BIT, 1, 0),
-
-SOC_SINGLE("Speaker Output Attenuation Volume", WM8990_SPEAKER_VOLUME,
- WM8990_SPKATTN_SHIFT, WM8990_SPKATTN_MASK, 0),
-SOC_SINGLE("Speaker DC Boost Volume", WM8990_CLASSD3,
- WM8990_DCGAIN_SHIFT, WM8990_DCGAIN_MASK, 0),
-SOC_SINGLE("Speaker AC Boost Volume", WM8990_CLASSD3,
- WM8990_ACGAIN_SHIFT, WM8990_ACGAIN_MASK, 0),
-SOC_SINGLE_TLV("Speaker Volume", WM8990_CLASSD4,
- WM8990_SPKVOL_SHIFT, WM8990_SPKVOL_MASK, 0, out_pga_tlv),
-SOC_SINGLE("Speaker ZC Switch", WM8990_CLASSD4,
- WM8990_SPKZC_SHIFT, WM8990_SPKZC_MASK, 0),
-
-SOC_WM899X_OUTPGA_SINGLE_R_TLV("Left DAC Digital Volume",
- WM8990_LEFT_DAC_DIGITAL_VOLUME,
- WM8990_DACL_VOL_SHIFT,
- WM8990_DACL_VOL_MASK,
- 0,
- out_dac_tlv),
-
-SOC_WM899X_OUTPGA_SINGLE_R_TLV("Right DAC Digital Volume",
- WM8990_RIGHT_DAC_DIGITAL_VOLUME,
- WM8990_DACR_VOL_SHIFT,
- WM8990_DACR_VOL_MASK,
- 0,
- out_dac_tlv),
-
-SOC_ENUM("Left Digital Sidetone", wm8990_left_digital_sidetone_enum),
-SOC_ENUM("Right Digital Sidetone", wm8990_right_digital_sidetone_enum),
-
-SOC_SINGLE_TLV("Left Digital Sidetone Volume", WM8990_DIGITAL_SIDE_TONE,
- WM8990_ADCL_DAC_SVOL_SHIFT, WM8990_ADCL_DAC_SVOL_MASK, 0,
- out_sidetone_tlv),
-SOC_SINGLE_TLV("Right Digital Sidetone Volume", WM8990_DIGITAL_SIDE_TONE,
- WM8990_ADCR_DAC_SVOL_SHIFT, WM8990_ADCR_DAC_SVOL_MASK, 0,
- out_sidetone_tlv),
-
-SOC_SINGLE("ADC Digital High Pass Filter Switch", WM8990_ADC_CTRL,
- WM8990_ADC_HPF_ENA_BIT, 1, 0),
-
-SOC_ENUM("ADC HPF Mode", wm8990_right_adcmode_enum),
-
-SOC_WM899X_OUTPGA_SINGLE_R_TLV("Left ADC Digital Volume",
- WM8990_LEFT_ADC_DIGITAL_VOLUME,
- WM8990_ADCL_VOL_SHIFT,
- WM8990_ADCL_VOL_MASK,
- 0,
- in_adc_tlv),
-
-SOC_WM899X_OUTPGA_SINGLE_R_TLV("Right ADC Digital Volume",
- WM8990_RIGHT_ADC_DIGITAL_VOLUME,
- WM8990_ADCR_VOL_SHIFT,
- WM8990_ADCR_VOL_MASK,
- 0,
- in_adc_tlv),
-
-SOC_WM899X_OUTPGA_SINGLE_R_TLV("LIN12 Volume",
- WM8990_LEFT_LINE_INPUT_1_2_VOLUME,
- WM8990_LIN12VOL_SHIFT,
- WM8990_LIN12VOL_MASK,
- 0,
- in_pga_tlv),
-
-SOC_SINGLE("LIN12 ZC Switch", WM8990_LEFT_LINE_INPUT_1_2_VOLUME,
- WM8990_LI12ZC_BIT, 1, 0),
-
-SOC_SINGLE("LIN12 Mute Switch", WM8990_LEFT_LINE_INPUT_1_2_VOLUME,
- WM8990_LI12MUTE_BIT, 1, 0),
-
-SOC_WM899X_OUTPGA_SINGLE_R_TLV("LIN34 Volume",
- WM8990_LEFT_LINE_INPUT_3_4_VOLUME,
- WM8990_LIN34VOL_SHIFT,
- WM8990_LIN34VOL_MASK,
- 0,
- in_pga_tlv),
-
-SOC_SINGLE("LIN34 ZC Switch", WM8990_LEFT_LINE_INPUT_3_4_VOLUME,
- WM8990_LI34ZC_BIT, 1, 0),
-
-SOC_SINGLE("LIN34 Mute Switch", WM8990_LEFT_LINE_INPUT_3_4_VOLUME,
- WM8990_LI34MUTE_BIT, 1, 0),
-
-SOC_WM899X_OUTPGA_SINGLE_R_TLV("RIN12 Volume",
- WM8990_RIGHT_LINE_INPUT_1_2_VOLUME,
- WM8990_RIN12VOL_SHIFT,
- WM8990_RIN12VOL_MASK,
- 0,
- in_pga_tlv),
-
-SOC_SINGLE("RIN12 ZC Switch", WM8990_RIGHT_LINE_INPUT_1_2_VOLUME,
- WM8990_RI12ZC_BIT, 1, 0),
-
-SOC_SINGLE("RIN12 Mute Switch", WM8990_RIGHT_LINE_INPUT_1_2_VOLUME,
- WM8990_RI12MUTE_BIT, 1, 0),
-
-SOC_WM899X_OUTPGA_SINGLE_R_TLV("RIN34 Volume",
- WM8990_RIGHT_LINE_INPUT_3_4_VOLUME,
- WM8990_RIN34VOL_SHIFT,
- WM8990_RIN34VOL_MASK,
- 0,
- in_pga_tlv),
-
-SOC_SINGLE("RIN34 ZC Switch", WM8990_RIGHT_LINE_INPUT_3_4_VOLUME,
- WM8990_RI34ZC_BIT, 1, 0),
-
-SOC_SINGLE("RIN34 Mute Switch", WM8990_RIGHT_LINE_INPUT_3_4_VOLUME,
- WM8990_RI34MUTE_BIT, 1, 0),
-
-};
-
-/*
- * _DAPM_ Controls
- */
-
-static int inmixer_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- u16 reg, fakepower;
-
- reg = snd_soc_read(w->codec, WM8990_POWER_MANAGEMENT_2);
- fakepower = snd_soc_read(w->codec, WM8990_INTDRIVBITS);
-
- if (fakepower & ((1 << WM8990_INMIXL_PWR_BIT) |
- (1 << WM8990_AINLMUX_PWR_BIT))) {
- reg |= WM8990_AINL_ENA;
- } else {
- reg &= ~WM8990_AINL_ENA;
- }
-
- if (fakepower & ((1 << WM8990_INMIXR_PWR_BIT) |
- (1 << WM8990_AINRMUX_PWR_BIT))) {
- reg |= WM8990_AINR_ENA;
- } else {
- reg &= ~WM8990_AINR_ENA;
- }
- snd_soc_write(w->codec, WM8990_POWER_MANAGEMENT_2, reg);
-
- return 0;
-}
-
-static int outmixer_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- u32 reg_shift = kcontrol->private_value & 0xfff;
- int ret = 0;
- u16 reg;
-
- switch (reg_shift) {
- case WM8990_SPEAKER_MIXER | (WM8990_LDSPK_BIT << 8) :
- reg = snd_soc_read(w->codec, WM8990_OUTPUT_MIXER1);
- if (reg & WM8990_LDLO) {
- printk(KERN_WARNING
- "Cannot set as Output Mixer 1 LDLO Set\n");
- ret = -1;
- }
- break;
- case WM8990_SPEAKER_MIXER | (WM8990_RDSPK_BIT << 8):
- reg = snd_soc_read(w->codec, WM8990_OUTPUT_MIXER2);
- if (reg & WM8990_RDRO) {
- printk(KERN_WARNING
- "Cannot set as Output Mixer 2 RDRO Set\n");
- ret = -1;
- }
- break;
- case WM8990_OUTPUT_MIXER1 | (WM8990_LDLO_BIT << 8):
- reg = snd_soc_read(w->codec, WM8990_SPEAKER_MIXER);
- if (reg & WM8990_LDSPK) {
- printk(KERN_WARNING
- "Cannot set as Speaker Mixer LDSPK Set\n");
- ret = -1;
- }
- break;
- case WM8990_OUTPUT_MIXER2 | (WM8990_RDRO_BIT << 8):
- reg = snd_soc_read(w->codec, WM8990_SPEAKER_MIXER);
- if (reg & WM8990_RDSPK) {
- printk(KERN_WARNING
- "Cannot set as Speaker Mixer RDSPK Set\n");
- ret = -1;
- }
- break;
- }
-
- return ret;
-}
-
-/* INMIX dB values */
-static const unsigned int in_mix_tlv[] = {
- TLV_DB_RANGE_HEAD(1),
- 0, 7, TLV_DB_SCALE_ITEM(-1200, 600, 0),
-};
-
-/* Left In PGA Connections */
-static const struct snd_kcontrol_new wm8990_dapm_lin12_pga_controls[] = {
-SOC_DAPM_SINGLE("LIN1 Switch", WM8990_INPUT_MIXER2, WM8990_LMN1_BIT, 1, 0),
-SOC_DAPM_SINGLE("LIN2 Switch", WM8990_INPUT_MIXER2, WM8990_LMP2_BIT, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8990_dapm_lin34_pga_controls[] = {
-SOC_DAPM_SINGLE("LIN3 Switch", WM8990_INPUT_MIXER2, WM8990_LMN3_BIT, 1, 0),
-SOC_DAPM_SINGLE("LIN4 Switch", WM8990_INPUT_MIXER2, WM8990_LMP4_BIT, 1, 0),
-};
-
-/* Right In PGA Connections */
-static const struct snd_kcontrol_new wm8990_dapm_rin12_pga_controls[] = {
-SOC_DAPM_SINGLE("RIN1 Switch", WM8990_INPUT_MIXER2, WM8990_RMN1_BIT, 1, 0),
-SOC_DAPM_SINGLE("RIN2 Switch", WM8990_INPUT_MIXER2, WM8990_RMP2_BIT, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8990_dapm_rin34_pga_controls[] = {
-SOC_DAPM_SINGLE("RIN3 Switch", WM8990_INPUT_MIXER2, WM8990_RMN3_BIT, 1, 0),
-SOC_DAPM_SINGLE("RIN4 Switch", WM8990_INPUT_MIXER2, WM8990_RMP4_BIT, 1, 0),
-};
-
-/* INMIXL */
-static const struct snd_kcontrol_new wm8990_dapm_inmixl_controls[] = {
-SOC_DAPM_SINGLE_TLV("Record Left Volume", WM8990_INPUT_MIXER3,
- WM8990_LDBVOL_SHIFT, WM8990_LDBVOL_MASK, 0, in_mix_tlv),
-SOC_DAPM_SINGLE_TLV("LIN2 Volume", WM8990_INPUT_MIXER5, WM8990_LI2BVOL_SHIFT,
- 7, 0, in_mix_tlv),
-SOC_DAPM_SINGLE("LINPGA12 Switch", WM8990_INPUT_MIXER3, WM8990_L12MNB_BIT,
- 1, 0),
-SOC_DAPM_SINGLE("LINPGA34 Switch", WM8990_INPUT_MIXER3, WM8990_L34MNB_BIT,
- 1, 0),
-};
-
-/* INMIXR */
-static const struct snd_kcontrol_new wm8990_dapm_inmixr_controls[] = {
-SOC_DAPM_SINGLE_TLV("Record Right Volume", WM8990_INPUT_MIXER4,
- WM8990_RDBVOL_SHIFT, WM8990_RDBVOL_MASK, 0, in_mix_tlv),
-SOC_DAPM_SINGLE_TLV("RIN2 Volume", WM8990_INPUT_MIXER6, WM8990_RI2BVOL_SHIFT,
- 7, 0, in_mix_tlv),
-SOC_DAPM_SINGLE("RINPGA12 Switch", WM8990_INPUT_MIXER3, WM8990_L12MNB_BIT,
- 1, 0),
-SOC_DAPM_SINGLE("RINPGA34 Switch", WM8990_INPUT_MIXER3, WM8990_L34MNB_BIT,
- 1, 0),
-};
-
-/* AINLMUX */
-static const char *wm8990_ainlmux[] =
- {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"};
-
-static const struct soc_enum wm8990_ainlmux_enum =
-SOC_ENUM_SINGLE(WM8990_INPUT_MIXER1, WM8990_AINLMODE_SHIFT,
- ARRAY_SIZE(wm8990_ainlmux), wm8990_ainlmux);
-
-static const struct snd_kcontrol_new wm8990_dapm_ainlmux_controls =
-SOC_DAPM_ENUM("Route", wm8990_ainlmux_enum);
-
-/* DIFFINL */
-
-/* AINRMUX */
-static const char *wm8990_ainrmux[] =
- {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"};
-
-static const struct soc_enum wm8990_ainrmux_enum =
-SOC_ENUM_SINGLE(WM8990_INPUT_MIXER1, WM8990_AINRMODE_SHIFT,
- ARRAY_SIZE(wm8990_ainrmux), wm8990_ainrmux);
-
-static const struct snd_kcontrol_new wm8990_dapm_ainrmux_controls =
-SOC_DAPM_ENUM("Route", wm8990_ainrmux_enum);
-
-/* RXVOICE */
-static const struct snd_kcontrol_new wm8990_dapm_rxvoice_controls[] = {
-SOC_DAPM_SINGLE_TLV("LIN4/RXN", WM8990_INPUT_MIXER5, WM8990_LR4BVOL_SHIFT,
- WM8990_LR4BVOL_MASK, 0, in_mix_tlv),
-SOC_DAPM_SINGLE_TLV("RIN4/RXP", WM8990_INPUT_MIXER6, WM8990_RL4BVOL_SHIFT,
- WM8990_RL4BVOL_MASK, 0, in_mix_tlv),
-};
-
-/* LOMIX */
-static const struct snd_kcontrol_new wm8990_dapm_lomix_controls[] = {
-SOC_DAPM_SINGLE("LOMIX Right ADC Bypass Switch", WM8990_OUTPUT_MIXER1,
- WM8990_LRBLO_BIT, 1, 0),
-SOC_DAPM_SINGLE("LOMIX Left ADC Bypass Switch", WM8990_OUTPUT_MIXER1,
- WM8990_LLBLO_BIT, 1, 0),
-SOC_DAPM_SINGLE("LOMIX RIN3 Bypass Switch", WM8990_OUTPUT_MIXER1,
- WM8990_LRI3LO_BIT, 1, 0),
-SOC_DAPM_SINGLE("LOMIX LIN3 Bypass Switch", WM8990_OUTPUT_MIXER1,
- WM8990_LLI3LO_BIT, 1, 0),
-SOC_DAPM_SINGLE("LOMIX RIN12 PGA Bypass Switch", WM8990_OUTPUT_MIXER1,
- WM8990_LR12LO_BIT, 1, 0),
-SOC_DAPM_SINGLE("LOMIX LIN12 PGA Bypass Switch", WM8990_OUTPUT_MIXER1,
- WM8990_LL12LO_BIT, 1, 0),
-SOC_DAPM_SINGLE("LOMIX Left DAC Switch", WM8990_OUTPUT_MIXER1,
- WM8990_LDLO_BIT, 1, 0),
-};
-
-/* ROMIX */
-static const struct snd_kcontrol_new wm8990_dapm_romix_controls[] = {
-SOC_DAPM_SINGLE("ROMIX Left ADC Bypass Switch", WM8990_OUTPUT_MIXER2,
- WM8990_RLBRO_BIT, 1, 0),
-SOC_DAPM_SINGLE("ROMIX Right ADC Bypass Switch", WM8990_OUTPUT_MIXER2,
- WM8990_RRBRO_BIT, 1, 0),
-SOC_DAPM_SINGLE("ROMIX LIN3 Bypass Switch", WM8990_OUTPUT_MIXER2,
- WM8990_RLI3RO_BIT, 1, 0),
-SOC_DAPM_SINGLE("ROMIX RIN3 Bypass Switch", WM8990_OUTPUT_MIXER2,
- WM8990_RRI3RO_BIT, 1, 0),
-SOC_DAPM_SINGLE("ROMIX LIN12 PGA Bypass Switch", WM8990_OUTPUT_MIXER2,
- WM8990_RL12RO_BIT, 1, 0),
-SOC_DAPM_SINGLE("ROMIX RIN12 PGA Bypass Switch", WM8990_OUTPUT_MIXER2,
- WM8990_RR12RO_BIT, 1, 0),
-SOC_DAPM_SINGLE("ROMIX Right DAC Switch", WM8990_OUTPUT_MIXER2,
- WM8990_RDRO_BIT, 1, 0),
-};
-
-/* LONMIX */
-static const struct snd_kcontrol_new wm8990_dapm_lonmix_controls[] = {
-SOC_DAPM_SINGLE("LONMIX Left Mixer PGA Switch", WM8990_LINE_MIXER1,
- WM8990_LLOPGALON_BIT, 1, 0),
-SOC_DAPM_SINGLE("LONMIX Right Mixer PGA Switch", WM8990_LINE_MIXER1,
- WM8990_LROPGALON_BIT, 1, 0),
-SOC_DAPM_SINGLE("LONMIX Inverted LOP Switch", WM8990_LINE_MIXER1,
- WM8990_LOPLON_BIT, 1, 0),
-};
-
-/* LOPMIX */
-static const struct snd_kcontrol_new wm8990_dapm_lopmix_controls[] = {
-SOC_DAPM_SINGLE("LOPMIX Right Mic Bypass Switch", WM8990_LINE_MIXER1,
- WM8990_LR12LOP_BIT, 1, 0),
-SOC_DAPM_SINGLE("LOPMIX Left Mic Bypass Switch", WM8990_LINE_MIXER1,
- WM8990_LL12LOP_BIT, 1, 0),
-SOC_DAPM_SINGLE("LOPMIX Left Mixer PGA Switch", WM8990_LINE_MIXER1,
- WM8990_LLOPGALOP_BIT, 1, 0),
-};
-
-/* RONMIX */
-static const struct snd_kcontrol_new wm8990_dapm_ronmix_controls[] = {
-SOC_DAPM_SINGLE("RONMIX Right Mixer PGA Switch", WM8990_LINE_MIXER2,
- WM8990_RROPGARON_BIT, 1, 0),
-SOC_DAPM_SINGLE("RONMIX Left Mixer PGA Switch", WM8990_LINE_MIXER2,
- WM8990_RLOPGARON_BIT, 1, 0),
-SOC_DAPM_SINGLE("RONMIX Inverted ROP Switch", WM8990_LINE_MIXER2,
- WM8990_ROPRON_BIT, 1, 0),
-};
-
-/* ROPMIX */
-static const struct snd_kcontrol_new wm8990_dapm_ropmix_controls[] = {
-SOC_DAPM_SINGLE("ROPMIX Left Mic Bypass Switch", WM8990_LINE_MIXER2,
- WM8990_RL12ROP_BIT, 1, 0),
-SOC_DAPM_SINGLE("ROPMIX Right Mic Bypass Switch", WM8990_LINE_MIXER2,
- WM8990_RR12ROP_BIT, 1, 0),
-SOC_DAPM_SINGLE("ROPMIX Right Mixer PGA Switch", WM8990_LINE_MIXER2,
- WM8990_RROPGAROP_BIT, 1, 0),
-};
-
-/* OUT3MIX */
-static const struct snd_kcontrol_new wm8990_dapm_out3mix_controls[] = {
-SOC_DAPM_SINGLE("OUT3MIX LIN4/RXP Bypass Switch", WM8990_OUT3_4_MIXER,
- WM8990_LI4O3_BIT, 1, 0),
-SOC_DAPM_SINGLE("OUT3MIX Left Out PGA Switch", WM8990_OUT3_4_MIXER,
- WM8990_LPGAO3_BIT, 1, 0),
-};
-
-/* OUT4MIX */
-static const struct snd_kcontrol_new wm8990_dapm_out4mix_controls[] = {
-SOC_DAPM_SINGLE("OUT4MIX Right Out PGA Switch", WM8990_OUT3_4_MIXER,
- WM8990_RPGAO4_BIT, 1, 0),
-SOC_DAPM_SINGLE("OUT4MIX RIN4/RXP Bypass Switch", WM8990_OUT3_4_MIXER,
- WM8990_RI4O4_BIT, 1, 0),
-};
-
-/* SPKMIX */
-static const struct snd_kcontrol_new wm8990_dapm_spkmix_controls[] = {
-SOC_DAPM_SINGLE("SPKMIX LIN2 Bypass Switch", WM8990_SPEAKER_MIXER,
- WM8990_LI2SPK_BIT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX LADC Bypass Switch", WM8990_SPEAKER_MIXER,
- WM8990_LB2SPK_BIT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX Left Mixer PGA Switch", WM8990_SPEAKER_MIXER,
- WM8990_LOPGASPK_BIT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX Left DAC Switch", WM8990_SPEAKER_MIXER,
- WM8990_LDSPK_BIT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX Right DAC Switch", WM8990_SPEAKER_MIXER,
- WM8990_RDSPK_BIT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX Right Mixer PGA Switch", WM8990_SPEAKER_MIXER,
- WM8990_ROPGASPK_BIT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX RADC Bypass Switch", WM8990_SPEAKER_MIXER,
- WM8990_RL12ROP_BIT, 1, 0),
-SOC_DAPM_SINGLE("SPKMIX RIN2 Bypass Switch", WM8990_SPEAKER_MIXER,
- WM8990_RI2SPK_BIT, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget wm8990_dapm_widgets[] = {
-/* Input Side */
-/* Input Lines */
-SND_SOC_DAPM_INPUT("LIN1"),
-SND_SOC_DAPM_INPUT("LIN2"),
-SND_SOC_DAPM_INPUT("LIN3"),
-SND_SOC_DAPM_INPUT("LIN4/RXN"),
-SND_SOC_DAPM_INPUT("RIN3"),
-SND_SOC_DAPM_INPUT("RIN4/RXP"),
-SND_SOC_DAPM_INPUT("RIN1"),
-SND_SOC_DAPM_INPUT("RIN2"),
-SND_SOC_DAPM_INPUT("Internal ADC Source"),
-
-/* DACs */
-SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8990_POWER_MANAGEMENT_2,
- WM8990_ADCL_ENA_BIT, 0),
-SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8990_POWER_MANAGEMENT_2,
- WM8990_ADCR_ENA_BIT, 0),
-
-/* Input PGAs */
-SND_SOC_DAPM_MIXER("LIN12 PGA", WM8990_POWER_MANAGEMENT_2, WM8990_LIN12_ENA_BIT,
- 0, &wm8990_dapm_lin12_pga_controls[0],
- ARRAY_SIZE(wm8990_dapm_lin12_pga_controls)),
-SND_SOC_DAPM_MIXER("LIN34 PGA", WM8990_POWER_MANAGEMENT_2, WM8990_LIN34_ENA_BIT,
- 0, &wm8990_dapm_lin34_pga_controls[0],
- ARRAY_SIZE(wm8990_dapm_lin34_pga_controls)),
-SND_SOC_DAPM_MIXER("RIN12 PGA", WM8990_POWER_MANAGEMENT_2, WM8990_RIN12_ENA_BIT,
- 0, &wm8990_dapm_rin12_pga_controls[0],
- ARRAY_SIZE(wm8990_dapm_rin12_pga_controls)),
-SND_SOC_DAPM_MIXER("RIN34 PGA", WM8990_POWER_MANAGEMENT_2, WM8990_RIN34_ENA_BIT,
- 0, &wm8990_dapm_rin34_pga_controls[0],
- ARRAY_SIZE(wm8990_dapm_rin34_pga_controls)),
-
-/* INMIXL */
-SND_SOC_DAPM_MIXER_E("INMIXL", WM8990_INTDRIVBITS, WM8990_INMIXL_PWR_BIT, 0,
- &wm8990_dapm_inmixl_controls[0],
- ARRAY_SIZE(wm8990_dapm_inmixl_controls),
- inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
-/* AINLMUX */
-SND_SOC_DAPM_MUX_E("AINLMUX", WM8990_INTDRIVBITS, WM8990_AINLMUX_PWR_BIT, 0,
- &wm8990_dapm_ainlmux_controls, inmixer_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
-/* INMIXR */
-SND_SOC_DAPM_MIXER_E("INMIXR", WM8990_INTDRIVBITS, WM8990_INMIXR_PWR_BIT, 0,
- &wm8990_dapm_inmixr_controls[0],
- ARRAY_SIZE(wm8990_dapm_inmixr_controls),
- inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
-/* AINRMUX */
-SND_SOC_DAPM_MUX_E("AINRMUX", WM8990_INTDRIVBITS, WM8990_AINRMUX_PWR_BIT, 0,
- &wm8990_dapm_ainrmux_controls, inmixer_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
-/* Output Side */
-/* DACs */
-SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8990_POWER_MANAGEMENT_3,
- WM8990_DACL_ENA_BIT, 0),
-SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8990_POWER_MANAGEMENT_3,
- WM8990_DACR_ENA_BIT, 0),
-
-/* LOMIX */
-SND_SOC_DAPM_MIXER_E("LOMIX", WM8990_POWER_MANAGEMENT_3, WM8990_LOMIX_ENA_BIT,
- 0, &wm8990_dapm_lomix_controls[0],
- ARRAY_SIZE(wm8990_dapm_lomix_controls),
- outmixer_event, SND_SOC_DAPM_PRE_REG),
-
-/* LONMIX */
-SND_SOC_DAPM_MIXER("LONMIX", WM8990_POWER_MANAGEMENT_3, WM8990_LON_ENA_BIT, 0,
- &wm8990_dapm_lonmix_controls[0],
- ARRAY_SIZE(wm8990_dapm_lonmix_controls)),
-
-/* LOPMIX */
-SND_SOC_DAPM_MIXER("LOPMIX", WM8990_POWER_MANAGEMENT_3, WM8990_LOP_ENA_BIT, 0,
- &wm8990_dapm_lopmix_controls[0],
- ARRAY_SIZE(wm8990_dapm_lopmix_controls)),
-
-/* OUT3MIX */
-SND_SOC_DAPM_MIXER("OUT3MIX", WM8990_POWER_MANAGEMENT_1, WM8990_OUT3_ENA_BIT, 0,
- &wm8990_dapm_out3mix_controls[0],
- ARRAY_SIZE(wm8990_dapm_out3mix_controls)),
-
-/* SPKMIX */
-SND_SOC_DAPM_MIXER_E("SPKMIX", WM8990_POWER_MANAGEMENT_1, WM8990_SPK_ENA_BIT, 0,
- &wm8990_dapm_spkmix_controls[0],
- ARRAY_SIZE(wm8990_dapm_spkmix_controls), outmixer_event,
- SND_SOC_DAPM_PRE_REG),
-
-/* OUT4MIX */
-SND_SOC_DAPM_MIXER("OUT4MIX", WM8990_POWER_MANAGEMENT_1, WM8990_OUT4_ENA_BIT, 0,
- &wm8990_dapm_out4mix_controls[0],
- ARRAY_SIZE(wm8990_dapm_out4mix_controls)),
-
-/* ROPMIX */
-SND_SOC_DAPM_MIXER("ROPMIX", WM8990_POWER_MANAGEMENT_3, WM8990_ROP_ENA_BIT, 0,
- &wm8990_dapm_ropmix_controls[0],
- ARRAY_SIZE(wm8990_dapm_ropmix_controls)),
-
-/* RONMIX */
-SND_SOC_DAPM_MIXER("RONMIX", WM8990_POWER_MANAGEMENT_3, WM8990_RON_ENA_BIT, 0,
- &wm8990_dapm_ronmix_controls[0],
- ARRAY_SIZE(wm8990_dapm_ronmix_controls)),
-
-/* ROMIX */
-SND_SOC_DAPM_MIXER_E("ROMIX", WM8990_POWER_MANAGEMENT_3, WM8990_ROMIX_ENA_BIT,
- 0, &wm8990_dapm_romix_controls[0],
- ARRAY_SIZE(wm8990_dapm_romix_controls),
- outmixer_event, SND_SOC_DAPM_PRE_REG),
-
-/* LOUT PGA */
-SND_SOC_DAPM_PGA("LOUT PGA", WM8990_POWER_MANAGEMENT_1, WM8990_LOUT_ENA_BIT, 0,
- NULL, 0),
-
-/* ROUT PGA */
-SND_SOC_DAPM_PGA("ROUT PGA", WM8990_POWER_MANAGEMENT_1, WM8990_ROUT_ENA_BIT, 0,
- NULL, 0),
-
-/* LOPGA */
-SND_SOC_DAPM_PGA("LOPGA", WM8990_POWER_MANAGEMENT_3, WM8990_LOPGA_ENA_BIT, 0,
- NULL, 0),
-
-/* ROPGA */
-SND_SOC_DAPM_PGA("ROPGA", WM8990_POWER_MANAGEMENT_3, WM8990_ROPGA_ENA_BIT, 0,
- NULL, 0),
-
-/* MICBIAS */
-SND_SOC_DAPM_SUPPLY("MICBIAS", WM8990_POWER_MANAGEMENT_1,
- WM8990_MICBIAS_ENA_BIT, 0, NULL, 0),
-
-SND_SOC_DAPM_OUTPUT("LON"),
-SND_SOC_DAPM_OUTPUT("LOP"),
-SND_SOC_DAPM_OUTPUT("OUT3"),
-SND_SOC_DAPM_OUTPUT("LOUT"),
-SND_SOC_DAPM_OUTPUT("SPKN"),
-SND_SOC_DAPM_OUTPUT("SPKP"),
-SND_SOC_DAPM_OUTPUT("ROUT"),
-SND_SOC_DAPM_OUTPUT("OUT4"),
-SND_SOC_DAPM_OUTPUT("ROP"),
-SND_SOC_DAPM_OUTPUT("RON"),
-
-SND_SOC_DAPM_OUTPUT("Internal DAC Sink"),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- /* Make DACs turn on when playing even if not mixed into any outputs */
- {"Internal DAC Sink", NULL, "Left DAC"},
- {"Internal DAC Sink", NULL, "Right DAC"},
-
- /* Make ADCs turn on when recording even if not mixed from any inputs */
- {"Left ADC", NULL, "Internal ADC Source"},
- {"Right ADC", NULL, "Internal ADC Source"},
-
- /* Input Side */
- /* LIN12 PGA */
- {"LIN12 PGA", "LIN1 Switch", "LIN1"},
- {"LIN12 PGA", "LIN2 Switch", "LIN2"},
- /* LIN34 PGA */
- {"LIN34 PGA", "LIN3 Switch", "LIN3"},
- {"LIN34 PGA", "LIN4 Switch", "LIN4/RXN"},
- /* INMIXL */
- {"INMIXL", "Record Left Volume", "LOMIX"},
- {"INMIXL", "LIN2 Volume", "LIN2"},
- {"INMIXL", "LINPGA12 Switch", "LIN12 PGA"},
- {"INMIXL", "LINPGA34 Switch", "LIN34 PGA"},
- /* AINLMUX */
- {"AINLMUX", "INMIXL Mix", "INMIXL"},
- {"AINLMUX", "DIFFINL Mix", "LIN12 PGA"},
- {"AINLMUX", "DIFFINL Mix", "LIN34 PGA"},
- {"AINLMUX", "RXVOICE Mix", "LIN4/RXN"},
- {"AINLMUX", "RXVOICE Mix", "RIN4/RXP"},
- /* ADC */
- {"Left ADC", NULL, "AINLMUX"},
-
- /* RIN12 PGA */
- {"RIN12 PGA", "RIN1 Switch", "RIN1"},
- {"RIN12 PGA", "RIN2 Switch", "RIN2"},
- /* RIN34 PGA */
- {"RIN34 PGA", "RIN3 Switch", "RIN3"},
- {"RIN34 PGA", "RIN4 Switch", "RIN4/RXP"},
- /* INMIXL */
- {"INMIXR", "Record Right Volume", "ROMIX"},
- {"INMIXR", "RIN2 Volume", "RIN2"},
- {"INMIXR", "RINPGA12 Switch", "RIN12 PGA"},
- {"INMIXR", "RINPGA34 Switch", "RIN34 PGA"},
- /* AINRMUX */
- {"AINRMUX", "INMIXR Mix", "INMIXR"},
- {"AINRMUX", "DIFFINR Mix", "RIN12 PGA"},
- {"AINRMUX", "DIFFINR Mix", "RIN34 PGA"},
- {"AINRMUX", "RXVOICE Mix", "LIN4/RXN"},
- {"AINRMUX", "RXVOICE Mix", "RIN4/RXP"},
- /* ADC */
- {"Right ADC", NULL, "AINRMUX"},
-
- /* LOMIX */
- {"LOMIX", "LOMIX RIN3 Bypass Switch", "RIN3"},
- {"LOMIX", "LOMIX LIN3 Bypass Switch", "LIN3"},
- {"LOMIX", "LOMIX LIN12 PGA Bypass Switch", "LIN12 PGA"},
- {"LOMIX", "LOMIX RIN12 PGA Bypass Switch", "RIN12 PGA"},
- {"LOMIX", "LOMIX Right ADC Bypass Switch", "AINRMUX"},
- {"LOMIX", "LOMIX Left ADC Bypass Switch", "AINLMUX"},
- {"LOMIX", "LOMIX Left DAC Switch", "Left DAC"},
-
- /* ROMIX */
- {"ROMIX", "ROMIX RIN3 Bypass Switch", "RIN3"},
- {"ROMIX", "ROMIX LIN3 Bypass Switch", "LIN3"},
- {"ROMIX", "ROMIX LIN12 PGA Bypass Switch", "LIN12 PGA"},
- {"ROMIX", "ROMIX RIN12 PGA Bypass Switch", "RIN12 PGA"},
- {"ROMIX", "ROMIX Right ADC Bypass Switch", "AINRMUX"},
- {"ROMIX", "ROMIX Left ADC Bypass Switch", "AINLMUX"},
- {"ROMIX", "ROMIX Right DAC Switch", "Right DAC"},
-
- /* SPKMIX */
- {"SPKMIX", "SPKMIX LIN2 Bypass Switch", "LIN2"},
- {"SPKMIX", "SPKMIX RIN2 Bypass Switch", "RIN2"},
- {"SPKMIX", "SPKMIX LADC Bypass Switch", "AINLMUX"},
- {"SPKMIX", "SPKMIX RADC Bypass Switch", "AINRMUX"},
- {"SPKMIX", "SPKMIX Left Mixer PGA Switch", "LOPGA"},
- {"SPKMIX", "SPKMIX Right Mixer PGA Switch", "ROPGA"},
- {"SPKMIX", "SPKMIX Right DAC Switch", "Right DAC"},
- {"SPKMIX", "SPKMIX Left DAC Switch", "Left DAC"},
-
- /* LONMIX */
- {"LONMIX", "LONMIX Left Mixer PGA Switch", "LOPGA"},
- {"LONMIX", "LONMIX Right Mixer PGA Switch", "ROPGA"},
- {"LONMIX", "LONMIX Inverted LOP Switch", "LOPMIX"},
-
- /* LOPMIX */
- {"LOPMIX", "LOPMIX Right Mic Bypass Switch", "RIN12 PGA"},
- {"LOPMIX", "LOPMIX Left Mic Bypass Switch", "LIN12 PGA"},
- {"LOPMIX", "LOPMIX Left Mixer PGA Switch", "LOPGA"},
-
- /* OUT3MIX */
- {"OUT3MIX", "OUT3MIX LIN4/RXP Bypass Switch", "LIN4/RXN"},
- {"OUT3MIX", "OUT3MIX Left Out PGA Switch", "LOPGA"},
-
- /* OUT4MIX */
- {"OUT4MIX", "OUT4MIX Right Out PGA Switch", "ROPGA"},
- {"OUT4MIX", "OUT4MIX RIN4/RXP Bypass Switch", "RIN4/RXP"},
-
- /* RONMIX */
- {"RONMIX", "RONMIX Right Mixer PGA Switch", "ROPGA"},
- {"RONMIX", "RONMIX Left Mixer PGA Switch", "LOPGA"},
- {"RONMIX", "RONMIX Inverted ROP Switch", "ROPMIX"},
-
- /* ROPMIX */
- {"ROPMIX", "ROPMIX Left Mic Bypass Switch", "LIN12 PGA"},
- {"ROPMIX", "ROPMIX Right Mic Bypass Switch", "RIN12 PGA"},
- {"ROPMIX", "ROPMIX Right Mixer PGA Switch", "ROPGA"},
-
- /* Out Mixer PGAs */
- {"LOPGA", NULL, "LOMIX"},
- {"ROPGA", NULL, "ROMIX"},
-
- {"LOUT PGA", NULL, "LOMIX"},
- {"ROUT PGA", NULL, "ROMIX"},
-
- /* Output Pins */
- {"LON", NULL, "LONMIX"},
- {"LOP", NULL, "LOPMIX"},
- {"OUT3", NULL, "OUT3MIX"},
- {"LOUT", NULL, "LOUT PGA"},
- {"SPKN", NULL, "SPKMIX"},
- {"ROUT", NULL, "ROUT PGA"},
- {"OUT4", NULL, "OUT4MIX"},
- {"ROP", NULL, "ROPMIX"},
- {"RON", NULL, "RONMIX"},
-};
-
-static int wm8990_add_widgets(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_new_controls(dapm, wm8990_dapm_widgets,
- ARRAY_SIZE(wm8990_dapm_widgets));
- /* set up the WM8990 audio map */
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
- return 0;
-}
-
-/* PLL divisors */
-struct _pll_div {
- u32 div2;
- u32 n;
- u32 k;
-};
-
-/* The size in bits of the pll divide multiplied by 10
- * to allow rounding later */
-#define FIXED_PLL_SIZE ((1 << 16) * 10)
-
-static void pll_factors(struct _pll_div *pll_div, unsigned int target,
- unsigned int source)
-{
- u64 Kpart;
- unsigned int K, Ndiv, Nmod;
-
-
- Ndiv = target / source;
- if (Ndiv < 6) {
- source >>= 1;
- pll_div->div2 = 1;
- Ndiv = target / source;
- } else
- pll_div->div2 = 0;
-
- if ((Ndiv < 6) || (Ndiv > 12))
- printk(KERN_WARNING
- "WM8990 N value outwith recommended range! N = %u\n", Ndiv);
-
- pll_div->n = Ndiv;
- Nmod = target % source;
- Kpart = FIXED_PLL_SIZE * (long long)Nmod;
-
- do_div(Kpart, source);
-
- K = Kpart & 0xFFFFFFFF;
-
- /* Check if we need to round */
- if ((K % 10) >= 5)
- K += 5;
-
- /* Move down to proper range now rounding is done */
- K /= 10;
-
- pll_div->k = K;
-}
-
-static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
- int source, unsigned int freq_in, unsigned int freq_out)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct _pll_div pll_div;
-
- if (freq_in && freq_out) {
- pll_factors(&pll_div, freq_out * 4, freq_in);
-
- /* Turn on PLL */
- snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_2,
- WM8990_PLL_ENA, WM8990_PLL_ENA);
-
- /* sysclk comes from PLL */
- snd_soc_update_bits(codec, WM8990_CLOCKING_2,
- WM8990_SYSCLK_SRC, WM8990_SYSCLK_SRC);
-
- /* set up N , fractional mode and pre-divisor if necessary */
- snd_soc_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM |
- (pll_div.div2?WM8990_PRESCALE:0));
- snd_soc_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8));
- snd_soc_write(codec, WM8990_PLL3, (u8)(pll_div.k & 0xFF));
- } else {
- /* Turn off PLL */
- snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_2,
- WM8990_PLL_ENA, 0);
- }
- return 0;
-}
-
-/*
- * Clock after PLL and dividers
- */
-static int wm8990_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8990_priv *wm8990 = snd_soc_codec_get_drvdata(codec);
-
- wm8990->sysclk = freq;
- return 0;
-}
-
-/*
- * Set's ADC and Voice DAC format.
- */
-static int wm8990_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 audio1, audio3;
-
- audio1 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_1);
- audio3 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_3);
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- audio3 &= ~WM8990_AIF_MSTR1;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- audio3 |= WM8990_AIF_MSTR1;
- break;
- default:
- return -EINVAL;
- }
-
- audio1 &= ~WM8990_AIF_FMT_MASK;
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- audio1 |= WM8990_AIF_TMF_I2S;
- audio1 &= ~WM8990_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- audio1 |= WM8990_AIF_TMF_RIGHTJ;
- audio1 &= ~WM8990_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- audio1 |= WM8990_AIF_TMF_LEFTJ;
- audio1 &= ~WM8990_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- audio1 |= WM8990_AIF_TMF_DSP;
- audio1 &= ~WM8990_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- audio1 |= WM8990_AIF_TMF_DSP | WM8990_AIF_LRCLK_INV;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM8990_AUDIO_INTERFACE_1, audio1);
- snd_soc_write(codec, WM8990_AUDIO_INTERFACE_3, audio3);
- return 0;
-}
-
-static int wm8990_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
- int div_id, int div)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
-
- switch (div_id) {
- case WM8990_MCLK_DIV:
- snd_soc_update_bits(codec, WM8990_CLOCKING_2,
- WM8990_MCLK_DIV_MASK, div);
- break;
- case WM8990_DACCLK_DIV:
- snd_soc_update_bits(codec, WM8990_CLOCKING_2,
- WM8990_DAC_CLKDIV_MASK, div);
- break;
- case WM8990_ADCCLK_DIV:
- snd_soc_update_bits(codec, WM8990_CLOCKING_2,
- WM8990_ADC_CLKDIV_MASK, div);
- break;
- case WM8990_BCLK_DIV:
- snd_soc_update_bits(codec, WM8990_CLOCKING_1,
- WM8990_BCLK_DIV_MASK, div);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * Set PCM DAI bit size and sample rate.
- */
-static int wm8990_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- u16 audio1 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_1);
-
- audio1 &= ~WM8990_AIF_WL_MASK;
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- audio1 |= WM8990_AIF_WL_20BITS;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- audio1 |= WM8990_AIF_WL_24BITS;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- audio1 |= WM8990_AIF_WL_32BITS;
- break;
- }
-
- snd_soc_write(codec, WM8990_AUDIO_INTERFACE_1, audio1);
- return 0;
-}
-
-static int wm8990_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 val;
-
- val = snd_soc_read(codec, WM8990_DAC_CTRL) & ~WM8990_DAC_MUTE;
-
- if (mute)
- snd_soc_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE);
- else
- snd_soc_write(codec, WM8990_DAC_CTRL, val);
-
- return 0;
-}
-
-static int wm8990_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- int ret;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- /* VMID=2*50k */
- snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_1,
- WM8990_VMID_MODE_MASK, 0x2);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = snd_soc_cache_sync(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
- return ret;
- }
-
- /* Enable all output discharge bits */
- snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
- WM8990_DIS_RLINE | WM8990_DIS_OUT3 |
- WM8990_DIS_OUT4 | WM8990_DIS_LOUT |
- WM8990_DIS_ROUT);
-
- /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */
- snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
- WM8990_BUFDCOPEN | WM8990_POBCTRL |
- WM8990_VMIDTOG);
-
- /* Delay to allow output caps to discharge */
- msleep(300);
-
- /* Disable VMIDTOG */
- snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
- WM8990_BUFDCOPEN | WM8990_POBCTRL);
-
- /* disable all output discharge bits */
- snd_soc_write(codec, WM8990_ANTIPOP1, 0);
-
- /* Enable outputs */
- snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1b00);
-
- msleep(50);
-
- /* Enable VMID at 2x50k */
- snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f02);
-
- msleep(100);
-
- /* Enable VREF */
- snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03);
-
- msleep(600);
-
- /* Enable BUFIOEN */
- snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
- WM8990_BUFDCOPEN | WM8990_POBCTRL |
- WM8990_BUFIOEN);
-
- /* Disable outputs */
- snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x3);
-
- /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
- snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_BUFIOEN);
-
- /* Enable workaround for ADC clocking issue. */
- snd_soc_write(codec, WM8990_EXT_ACCESS_ENA, 0x2);
- snd_soc_write(codec, WM8990_EXT_CTL1, 0xa003);
- snd_soc_write(codec, WM8990_EXT_ACCESS_ENA, 0);
- }
-
- /* VMID=2*250k */
- snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_1,
- WM8990_VMID_MODE_MASK, 0x4);
- break;
-
- case SND_SOC_BIAS_OFF:
- /* Enable POBCTRL and SOFT_ST */
- snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
- WM8990_POBCTRL | WM8990_BUFIOEN);
-
- /* Enable POBCTRL, SOFT_ST and BUFDCOPEN */
- snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
- WM8990_BUFDCOPEN | WM8990_POBCTRL |
- WM8990_BUFIOEN);
-
- /* mute DAC */
- snd_soc_update_bits(codec, WM8990_DAC_CTRL,
- WM8990_DAC_MUTE, WM8990_DAC_MUTE);
-
- /* Enable any disabled outputs */
- snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03);
-
- /* Disable VMID */
- snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f01);
-
- msleep(300);
-
- /* Enable all output discharge bits */
- snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
- WM8990_DIS_RLINE | WM8990_DIS_OUT3 |
- WM8990_DIS_OUT4 | WM8990_DIS_LOUT |
- WM8990_DIS_ROUT);
-
- /* Disable VREF */
- snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x0);
-
- /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
- snd_soc_write(codec, WM8990_ANTIPOP2, 0x0);
- break;
- }
-
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#define WM8990_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000)
-
-#define WM8990_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-/*
- * The WM8990 supports 2 different and mutually exclusive DAI
- * configurations.
- *
- * 1. ADC/DAC on Primary Interface
- * 2. ADC on Primary Interface/DAC on secondary
- */
-static const struct snd_soc_dai_ops wm8990_dai_ops = {
- .hw_params = wm8990_hw_params,
- .digital_mute = wm8990_mute,
- .set_fmt = wm8990_set_dai_fmt,
- .set_clkdiv = wm8990_set_dai_clkdiv,
- .set_pll = wm8990_set_dai_pll,
- .set_sysclk = wm8990_set_dai_sysclk,
-};
-
-static struct snd_soc_dai_driver wm8990_dai = {
-/* ADC/DAC on primary */
- .name = "wm8990-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8990_RATES,
- .formats = WM8990_FORMATS,},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8990_RATES,
- .formats = WM8990_FORMATS,},
- .ops = &wm8990_dai_ops,
-};
-
-static int wm8990_suspend(struct snd_soc_codec *codec)
-{
- wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm8990_resume(struct snd_soc_codec *codec)
-{
- wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-
-/*
- * initialise the WM8990 driver
- * register the mixer and dsp interfaces with the kernel
- */
-static int wm8990_probe(struct snd_soc_codec *codec)
-{
- int ret;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
- if (ret < 0) {
- printk(KERN_ERR "wm8990: failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- wm8990_reset(codec);
-
- /* charge output caps */
- wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- snd_soc_update_bits(codec, WM8990_AUDIO_INTERFACE_4,
- WM8990_ALRCGPIO1, WM8990_ALRCGPIO1);
-
- snd_soc_update_bits(codec, WM8990_GPIO1_GPIO2,
- WM8990_GPIO1_SEL_MASK, 1);
-
- snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_2,
- WM8990_OPCLK_ENA, WM8990_OPCLK_ENA);
-
- snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
- snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
-
- snd_soc_add_codec_controls(codec, wm8990_snd_controls,
- ARRAY_SIZE(wm8990_snd_controls));
- wm8990_add_widgets(codec);
-
- return 0;
-}
-
-/* power down chip */
-static int wm8990_remove(struct snd_soc_codec *codec)
-{
- wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8990 = {
- .probe = wm8990_probe,
- .remove = wm8990_remove,
- .suspend = wm8990_suspend,
- .resume = wm8990_resume,
- .set_bias_level = wm8990_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8990_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8990_reg,
- .volatile_register = wm8990_volatile_register,
-};
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8990_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8990_priv *wm8990;
- int ret;
-
- wm8990 = kzalloc(sizeof(struct wm8990_priv), GFP_KERNEL);
- if (wm8990 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm8990);
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8990, &wm8990_dai, 1);
- if (ret < 0)
- kfree(wm8990);
- return ret;
-}
-
-static __devexit int wm8990_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-static const struct i2c_device_id wm8990_i2c_id[] = {
- { "wm8990", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8990_i2c_id);
-
-static struct i2c_driver wm8990_i2c_driver = {
- .driver = {
- .name = "wm8990",
- .owner = THIS_MODULE,
- },
- .probe = wm8990_i2c_probe,
- .remove = __devexit_p(wm8990_i2c_remove),
- .id_table = wm8990_i2c_id,
-};
-#endif
-
-static int __init wm8990_modinit(void)
-{
- int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&wm8990_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8990 I2C driver: %d\n",
- ret);
- }
-#endif
- return ret;
-}
-module_init(wm8990_modinit);
-
-static void __exit wm8990_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&wm8990_i2c_driver);
-#endif
-}
-module_exit(wm8990_exit);
-
-MODULE_DESCRIPTION("ASoC WM8990 driver");
-MODULE_AUTHOR("Liam Girdwood");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8990.h b/ANDROID_3.4.5/sound/soc/codecs/wm8990.h
deleted file mode 100644
index 77c98a4b..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8990.h
+++ /dev/null
@@ -1,835 +0,0 @@
-/*
- * wm8990.h -- audio driver for WM8990
- *
- * Copyright 2007 Wolfson Microelectronics PLC.
- * Author: Graeme Gregory
- * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#ifndef __WM8990REGISTERDEFS_H__
-#define __WM8990REGISTERDEFS_H__
-
-/*
- * Register values.
- */
-#define WM8990_RESET 0x00
-#define WM8990_POWER_MANAGEMENT_1 0x01
-#define WM8990_POWER_MANAGEMENT_2 0x02
-#define WM8990_POWER_MANAGEMENT_3 0x03
-#define WM8990_AUDIO_INTERFACE_1 0x04
-#define WM8990_AUDIO_INTERFACE_2 0x05
-#define WM8990_CLOCKING_1 0x06
-#define WM8990_CLOCKING_2 0x07
-#define WM8990_AUDIO_INTERFACE_3 0x08
-#define WM8990_AUDIO_INTERFACE_4 0x09
-#define WM8990_DAC_CTRL 0x0A
-#define WM8990_LEFT_DAC_DIGITAL_VOLUME 0x0B
-#define WM8990_RIGHT_DAC_DIGITAL_VOLUME 0x0C
-#define WM8990_DIGITAL_SIDE_TONE 0x0D
-#define WM8990_ADC_CTRL 0x0E
-#define WM8990_LEFT_ADC_DIGITAL_VOLUME 0x0F
-#define WM8990_RIGHT_ADC_DIGITAL_VOLUME 0x10
-#define WM8990_GPIO_CTRL_1 0x12
-#define WM8990_GPIO1_GPIO2 0x13
-#define WM8990_GPIO3_GPIO4 0x14
-#define WM8990_GPIO5_GPIO6 0x15
-#define WM8990_GPIOCTRL_2 0x16
-#define WM8990_GPIO_POL 0x17
-#define WM8990_LEFT_LINE_INPUT_1_2_VOLUME 0x18
-#define WM8990_LEFT_LINE_INPUT_3_4_VOLUME 0x19
-#define WM8990_RIGHT_LINE_INPUT_1_2_VOLUME 0x1A
-#define WM8990_RIGHT_LINE_INPUT_3_4_VOLUME 0x1B
-#define WM8990_LEFT_OUTPUT_VOLUME 0x1C
-#define WM8990_RIGHT_OUTPUT_VOLUME 0x1D
-#define WM8990_LINE_OUTPUTS_VOLUME 0x1E
-#define WM8990_OUT3_4_VOLUME 0x1F
-#define WM8990_LEFT_OPGA_VOLUME 0x20
-#define WM8990_RIGHT_OPGA_VOLUME 0x21
-#define WM8990_SPEAKER_VOLUME 0x22
-#define WM8990_CLASSD1 0x23
-#define WM8990_CLASSD3 0x25
-#define WM8990_CLASSD4 0x26
-#define WM8990_INPUT_MIXER1 0x27
-#define WM8990_INPUT_MIXER2 0x28
-#define WM8990_INPUT_MIXER3 0x29
-#define WM8990_INPUT_MIXER4 0x2A
-#define WM8990_INPUT_MIXER5 0x2B
-#define WM8990_INPUT_MIXER6 0x2C
-#define WM8990_OUTPUT_MIXER1 0x2D
-#define WM8990_OUTPUT_MIXER2 0x2E
-#define WM8990_OUTPUT_MIXER3 0x2F
-#define WM8990_OUTPUT_MIXER4 0x30
-#define WM8990_OUTPUT_MIXER5 0x31
-#define WM8990_OUTPUT_MIXER6 0x32
-#define WM8990_OUT3_4_MIXER 0x33
-#define WM8990_LINE_MIXER1 0x34
-#define WM8990_LINE_MIXER2 0x35
-#define WM8990_SPEAKER_MIXER 0x36
-#define WM8990_ADDITIONAL_CONTROL 0x37
-#define WM8990_ANTIPOP1 0x38
-#define WM8990_ANTIPOP2 0x39
-#define WM8990_MICBIAS 0x3A
-#define WM8990_PLL1 0x3C
-#define WM8990_PLL2 0x3D
-#define WM8990_PLL3 0x3E
-#define WM8990_INTDRIVBITS 0x3F
-
-#define WM8990_EXT_ACCESS_ENA 0x75
-#define WM8990_EXT_CTL1 0x7a
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - Reset
- */
-#define WM8990_SW_RESET_CHIP_ID_MASK 0xFFFF /* SW_RESET_CHIP_ID */
-
-/*
- * R1 (0x01) - Power Management (1)
- */
-#define WM8990_SPK_ENA 0x1000 /* SPK_ENA */
-#define WM8990_SPK_ENA_BIT 12
-#define WM8990_OUT3_ENA 0x0800 /* OUT3_ENA */
-#define WM8990_OUT3_ENA_BIT 11
-#define WM8990_OUT4_ENA 0x0400 /* OUT4_ENA */
-#define WM8990_OUT4_ENA_BIT 10
-#define WM8990_LOUT_ENA 0x0200 /* LOUT_ENA */
-#define WM8990_LOUT_ENA_BIT 9
-#define WM8990_ROUT_ENA 0x0100 /* ROUT_ENA */
-#define WM8990_ROUT_ENA_BIT 8
-#define WM8990_MICBIAS_ENA 0x0010 /* MICBIAS_ENA */
-#define WM8990_MICBIAS_ENA_BIT 4
-#define WM8990_VMID_MODE_MASK 0x0006 /* VMID_MODE - [2:1] */
-#define WM8990_VREF_ENA 0x0001 /* VREF_ENA */
-#define WM8990_VREF_ENA_BIT 0
-
-/*
- * R2 (0x02) - Power Management (2)
- */
-#define WM8990_PLL_ENA 0x8000 /* PLL_ENA */
-#define WM8990_PLL_ENA_BIT 15
-#define WM8990_TSHUT_ENA 0x4000 /* TSHUT_ENA */
-#define WM8990_TSHUT_ENA_BIT 14
-#define WM8990_TSHUT_OPDIS 0x2000 /* TSHUT_OPDIS */
-#define WM8990_TSHUT_OPDIS_BIT 13
-#define WM8990_OPCLK_ENA 0x0800 /* OPCLK_ENA */
-#define WM8990_OPCLK_ENA_BIT 11
-#define WM8990_AINL_ENA 0x0200 /* AINL_ENA */
-#define WM8990_AINL_ENA_BIT 9
-#define WM8990_AINR_ENA 0x0100 /* AINR_ENA */
-#define WM8990_AINR_ENA_BIT 8
-#define WM8990_LIN34_ENA 0x0080 /* LIN34_ENA */
-#define WM8990_LIN34_ENA_BIT 7
-#define WM8990_LIN12_ENA 0x0040 /* LIN12_ENA */
-#define WM8990_LIN12_ENA_BIT 6
-#define WM8990_RIN34_ENA 0x0020 /* RIN34_ENA */
-#define WM8990_RIN34_ENA_BIT 5
-#define WM8990_RIN12_ENA 0x0010 /* RIN12_ENA */
-#define WM8990_RIN12_ENA_BIT 4
-#define WM8990_ADCL_ENA 0x0002 /* ADCL_ENA */
-#define WM8990_ADCL_ENA_BIT 1
-#define WM8990_ADCR_ENA 0x0001 /* ADCR_ENA */
-#define WM8990_ADCR_ENA_BIT 0
-
-/*
- * R3 (0x03) - Power Management (3)
- */
-#define WM8990_LON_ENA 0x2000 /* LON_ENA */
-#define WM8990_LON_ENA_BIT 13
-#define WM8990_LOP_ENA 0x1000 /* LOP_ENA */
-#define WM8990_LOP_ENA_BIT 12
-#define WM8990_RON_ENA 0x0800 /* RON_ENA */
-#define WM8990_RON_ENA_BIT 11
-#define WM8990_ROP_ENA 0x0400 /* ROP_ENA */
-#define WM8990_ROP_ENA_BIT 10
-#define WM8990_LOPGA_ENA 0x0080 /* LOPGA_ENA */
-#define WM8990_LOPGA_ENA_BIT 7
-#define WM8990_ROPGA_ENA 0x0040 /* ROPGA_ENA */
-#define WM8990_ROPGA_ENA_BIT 6
-#define WM8990_LOMIX_ENA 0x0020 /* LOMIX_ENA */
-#define WM8990_LOMIX_ENA_BIT 5
-#define WM8990_ROMIX_ENA 0x0010 /* ROMIX_ENA */
-#define WM8990_ROMIX_ENA_BIT 4
-#define WM8990_DACL_ENA 0x0002 /* DACL_ENA */
-#define WM8990_DACL_ENA_BIT 1
-#define WM8990_DACR_ENA 0x0001 /* DACR_ENA */
-#define WM8990_DACR_ENA_BIT 0
-
-/*
- * R4 (0x04) - Audio Interface (1)
- */
-#define WM8990_AIFADCL_SRC 0x8000 /* AIFADCL_SRC */
-#define WM8990_AIFADCR_SRC 0x4000 /* AIFADCR_SRC */
-#define WM8990_AIFADC_TDM 0x2000 /* AIFADC_TDM */
-#define WM8990_AIFADC_TDM_CHAN 0x1000 /* AIFADC_TDM_CHAN */
-#define WM8990_AIF_BCLK_INV 0x0100 /* AIF_BCLK_INV */
-#define WM8990_AIF_LRCLK_INV 0x0080 /* AIF_LRCLK_INV */
-#define WM8990_AIF_WL_MASK 0x0060 /* AIF_WL - [6:5] */
-#define WM8990_AIF_WL_16BITS (0 << 5)
-#define WM8990_AIF_WL_20BITS (1 << 5)
-#define WM8990_AIF_WL_24BITS (2 << 5)
-#define WM8990_AIF_WL_32BITS (3 << 5)
-#define WM8990_AIF_FMT_MASK 0x0018 /* AIF_FMT - [4:3] */
-#define WM8990_AIF_TMF_RIGHTJ (0 << 3)
-#define WM8990_AIF_TMF_LEFTJ (1 << 3)
-#define WM8990_AIF_TMF_I2S (2 << 3)
-#define WM8990_AIF_TMF_DSP (3 << 3)
-
-/*
- * R5 (0x05) - Audio Interface (2)
- */
-#define WM8990_DACL_SRC 0x8000 /* DACL_SRC */
-#define WM8990_DACR_SRC 0x4000 /* DACR_SRC */
-#define WM8990_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */
-#define WM8990_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */
-#define WM8990_DAC_BOOST_MASK 0x0C00 /* DAC_BOOST */
-#define WM8990_DAC_COMP 0x0010 /* DAC_COMP */
-#define WM8990_DAC_COMPMODE 0x0008 /* DAC_COMPMODE */
-#define WM8990_ADC_COMP 0x0004 /* ADC_COMP */
-#define WM8990_ADC_COMPMODE 0x0002 /* ADC_COMPMODE */
-#define WM8990_LOOPBACK 0x0001 /* LOOPBACK */
-
-/*
- * R6 (0x06) - Clocking (1)
- */
-#define WM8990_TOCLK_RATE 0x8000 /* TOCLK_RATE */
-#define WM8990_TOCLK_ENA 0x4000 /* TOCLK_ENA */
-#define WM8990_OPCLKDIV_MASK 0x1E00 /* OPCLKDIV - [12:9] */
-#define WM8990_DCLKDIV_MASK 0x01C0 /* DCLKDIV - [8:6] */
-#define WM8990_BCLK_DIV_MASK 0x001E /* BCLK_DIV - [4:1] */
-#define WM8990_BCLK_DIV_1 (0x0 << 1)
-#define WM8990_BCLK_DIV_1_5 (0x1 << 1)
-#define WM8990_BCLK_DIV_2 (0x2 << 1)
-#define WM8990_BCLK_DIV_3 (0x3 << 1)
-#define WM8990_BCLK_DIV_4 (0x4 << 1)
-#define WM8990_BCLK_DIV_5_5 (0x5 << 1)
-#define WM8990_BCLK_DIV_6 (0x6 << 1)
-#define WM8990_BCLK_DIV_8 (0x7 << 1)
-#define WM8990_BCLK_DIV_11 (0x8 << 1)
-#define WM8990_BCLK_DIV_12 (0x9 << 1)
-#define WM8990_BCLK_DIV_16 (0xA << 1)
-#define WM8990_BCLK_DIV_22 (0xB << 1)
-#define WM8990_BCLK_DIV_24 (0xC << 1)
-#define WM8990_BCLK_DIV_32 (0xD << 1)
-#define WM8990_BCLK_DIV_44 (0xE << 1)
-#define WM8990_BCLK_DIV_48 (0xF << 1)
-
-/*
- * R7 (0x07) - Clocking (2)
- */
-#define WM8990_MCLK_SRC 0x8000 /* MCLK_SRC */
-#define WM8990_SYSCLK_SRC 0x4000 /* SYSCLK_SRC */
-#define WM8990_CLK_FORCE 0x2000 /* CLK_FORCE */
-#define WM8990_MCLK_DIV_MASK 0x1800 /* MCLK_DIV - [12:11] */
-#define WM8990_MCLK_DIV_1 (0 << 11)
-#define WM8990_MCLK_DIV_2 (2 << 11)
-#define WM8990_MCLK_INV 0x0400 /* MCLK_INV */
-#define WM8990_ADC_CLKDIV_MASK 0x00E0 /* ADC_CLKDIV */
-#define WM8990_ADC_CLKDIV_1 (0 << 5)
-#define WM8990_ADC_CLKDIV_1_5 (1 << 5)
-#define WM8990_ADC_CLKDIV_2 (2 << 5)
-#define WM8990_ADC_CLKDIV_3 (3 << 5)
-#define WM8990_ADC_CLKDIV_4 (4 << 5)
-#define WM8990_ADC_CLKDIV_5_5 (5 << 5)
-#define WM8990_ADC_CLKDIV_6 (6 << 5)
-#define WM8990_DAC_CLKDIV_MASK 0x001C /* DAC_CLKDIV - [4:2] */
-#define WM8990_DAC_CLKDIV_1 (0 << 2)
-#define WM8990_DAC_CLKDIV_1_5 (1 << 2)
-#define WM8990_DAC_CLKDIV_2 (2 << 2)
-#define WM8990_DAC_CLKDIV_3 (3 << 2)
-#define WM8990_DAC_CLKDIV_4 (4 << 2)
-#define WM8990_DAC_CLKDIV_5_5 (5 << 2)
-#define WM8990_DAC_CLKDIV_6 (6 << 2)
-
-/*
- * R8 (0x08) - Audio Interface (3)
- */
-#define WM8990_AIF_MSTR1 0x8000 /* AIF_MSTR1 */
-#define WM8990_AIF_MSTR2 0x4000 /* AIF_MSTR2 */
-#define WM8990_AIF_SEL 0x2000 /* AIF_SEL */
-#define WM8990_ADCLRC_DIR 0x0800 /* ADCLRC_DIR */
-#define WM8990_ADCLRC_RATE_MASK 0x07FF /* ADCLRC_RATE */
-
-/*
- * R9 (0x09) - Audio Interface (4)
- */
-#define WM8990_ALRCGPIO1 0x8000 /* ALRCGPIO1 */
-#define WM8990_ALRCBGPIO6 0x4000 /* ALRCBGPIO6 */
-#define WM8990_AIF_TRIS 0x2000 /* AIF_TRIS */
-#define WM8990_DACLRC_DIR 0x0800 /* DACLRC_DIR */
-#define WM8990_DACLRC_RATE_MASK 0x07FF /* DACLRC_RATE */
-
-/*
- * R10 (0x0A) - DAC CTRL
- */
-#define WM8990_AIF_LRCLKRATE 0x0400 /* AIF_LRCLKRATE */
-#define WM8990_DAC_MONO 0x0200 /* DAC_MONO */
-#define WM8990_DAC_SB_FILT 0x0100 /* DAC_SB_FILT */
-#define WM8990_DAC_MUTERATE 0x0080 /* DAC_MUTERATE */
-#define WM8990_DAC_MUTEMODE 0x0040 /* DAC_MUTEMODE */
-#define WM8990_DEEMP_MASK 0x0030 /* DEEMP - [5:4] */
-#define WM8990_DAC_MUTE 0x0004 /* DAC_MUTE */
-#define WM8990_DACL_DATINV 0x0002 /* DACL_DATINV */
-#define WM8990_DACR_DATINV 0x0001 /* DACR_DATINV */
-
-/*
- * R11 (0x0B) - Left DAC Digital Volume
- */
-#define WM8990_DAC_VU 0x0100 /* DAC_VU */
-#define WM8990_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
-#define WM8990_DACL_VOL_SHIFT 0
-/*
- * R12 (0x0C) - Right DAC Digital Volume
- */
-#define WM8990_DAC_VU 0x0100 /* DAC_VU */
-#define WM8990_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
-#define WM8990_DACR_VOL_SHIFT 0
-/*
- * R13 (0x0D) - Digital Side Tone
- */
-#define WM8990_ADCL_DAC_SVOL_MASK 0x0F /* ADCL_DAC_SVOL */
-#define WM8990_ADCL_DAC_SVOL_SHIFT 9
-#define WM8990_ADCR_DAC_SVOL_MASK 0x0F /* ADCR_DAC_SVOL */
-#define WM8990_ADCR_DAC_SVOL_SHIFT 5
-#define WM8990_ADC_TO_DACL_MASK 0x03 /* ADC_TO_DACL - [3:2] */
-#define WM8990_ADC_TO_DACL_SHIFT 2
-#define WM8990_ADC_TO_DACR_MASK 0x03 /* ADC_TO_DACR - [1:0] */
-#define WM8990_ADC_TO_DACR_SHIFT 0
-
-/*
- * R14 (0x0E) - ADC CTRL
- */
-#define WM8990_ADC_HPF_ENA 0x0100 /* ADC_HPF_ENA */
-#define WM8990_ADC_HPF_ENA_BIT 8
-#define WM8990_ADC_HPF_CUT_MASK 0x03 /* ADC_HPF_CUT - [6:5] */
-#define WM8990_ADC_HPF_CUT_SHIFT 5
-#define WM8990_ADCL_DATINV 0x0002 /* ADCL_DATINV */
-#define WM8990_ADCL_DATINV_BIT 1
-#define WM8990_ADCR_DATINV 0x0001 /* ADCR_DATINV */
-#define WM8990_ADCR_DATINV_BIT 0
-
-/*
- * R15 (0x0F) - Left ADC Digital Volume
- */
-#define WM8990_ADC_VU 0x0100 /* ADC_VU */
-#define WM8990_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
-#define WM8990_ADCL_VOL_SHIFT 0
-
-/*
- * R16 (0x10) - Right ADC Digital Volume
- */
-#define WM8990_ADC_VU 0x0100 /* ADC_VU */
-#define WM8990_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
-#define WM8990_ADCR_VOL_SHIFT 0
-
-/*
- * R18 (0x12) - GPIO CTRL 1
- */
-#define WM8990_IRQ 0x1000 /* IRQ */
-#define WM8990_TEMPOK 0x0800 /* TEMPOK */
-#define WM8990_MICSHRT 0x0400 /* MICSHRT */
-#define WM8990_MICDET 0x0200 /* MICDET */
-#define WM8990_PLL_LCK 0x0100 /* PLL_LCK */
-#define WM8990_GPI8_STATUS 0x0080 /* GPI8_STATUS */
-#define WM8990_GPI7_STATUS 0x0040 /* GPI7_STATUS */
-#define WM8990_GPIO6_STATUS 0x0020 /* GPIO6_STATUS */
-#define WM8990_GPIO5_STATUS 0x0010 /* GPIO5_STATUS */
-#define WM8990_GPIO4_STATUS 0x0008 /* GPIO4_STATUS */
-#define WM8990_GPIO3_STATUS 0x0004 /* GPIO3_STATUS */
-#define WM8990_GPIO2_STATUS 0x0002 /* GPIO2_STATUS */
-#define WM8990_GPIO1_STATUS 0x0001 /* GPIO1_STATUS */
-
-/*
- * R19 (0x13) - GPIO1 & GPIO2
- */
-#define WM8990_GPIO2_DEB_ENA 0x8000 /* GPIO2_DEB_ENA */
-#define WM8990_GPIO2_IRQ_ENA 0x4000 /* GPIO2_IRQ_ENA */
-#define WM8990_GPIO2_PU 0x2000 /* GPIO2_PU */
-#define WM8990_GPIO2_PD 0x1000 /* GPIO2_PD */
-#define WM8990_GPIO2_SEL_MASK 0x0F00 /* GPIO2_SEL - [11:8] */
-#define WM8990_GPIO1_DEB_ENA 0x0080 /* GPIO1_DEB_ENA */
-#define WM8990_GPIO1_IRQ_ENA 0x0040 /* GPIO1_IRQ_ENA */
-#define WM8990_GPIO1_PU 0x0020 /* GPIO1_PU */
-#define WM8990_GPIO1_PD 0x0010 /* GPIO1_PD */
-#define WM8990_GPIO1_SEL_MASK 0x000F /* GPIO1_SEL - [3:0] */
-
-/*
- * R20 (0x14) - GPIO3 & GPIO4
- */
-#define WM8990_GPIO4_DEB_ENA 0x8000 /* GPIO4_DEB_ENA */
-#define WM8990_GPIO4_IRQ_ENA 0x4000 /* GPIO4_IRQ_ENA */
-#define WM8990_GPIO4_PU 0x2000 /* GPIO4_PU */
-#define WM8990_GPIO4_PD 0x1000 /* GPIO4_PD */
-#define WM8990_GPIO4_SEL_MASK 0x0F00 /* GPIO4_SEL - [11:8] */
-#define WM8990_GPIO3_DEB_ENA 0x0080 /* GPIO3_DEB_ENA */
-#define WM8990_GPIO3_IRQ_ENA 0x0040 /* GPIO3_IRQ_ENA */
-#define WM8990_GPIO3_PU 0x0020 /* GPIO3_PU */
-#define WM8990_GPIO3_PD 0x0010 /* GPIO3_PD */
-#define WM8990_GPIO3_SEL_MASK 0x000F /* GPIO3_SEL - [3:0] */
-
-/*
- * R21 (0x15) - GPIO5 & GPIO6
- */
-#define WM8990_GPIO6_DEB_ENA 0x8000 /* GPIO6_DEB_ENA */
-#define WM8990_GPIO6_IRQ_ENA 0x4000 /* GPIO6_IRQ_ENA */
-#define WM8990_GPIO6_PU 0x2000 /* GPIO6_PU */
-#define WM8990_GPIO6_PD 0x1000 /* GPIO6_PD */
-#define WM8990_GPIO6_SEL_MASK 0x0F00 /* GPIO6_SEL - [11:8] */
-#define WM8990_GPIO5_DEB_ENA 0x0080 /* GPIO5_DEB_ENA */
-#define WM8990_GPIO5_IRQ_ENA 0x0040 /* GPIO5_IRQ_ENA */
-#define WM8990_GPIO5_PU 0x0020 /* GPIO5_PU */
-#define WM8990_GPIO5_PD 0x0010 /* GPIO5_PD */
-#define WM8990_GPIO5_SEL_MASK 0x000F /* GPIO5_SEL - [3:0] */
-
-/*
- * R22 (0x16) - GPIOCTRL 2
- */
-#define WM8990_RD_3W_ENA 0x8000 /* RD_3W_ENA */
-#define WM8990_MODE_3W4W 0x4000 /* MODE_3W4W */
-#define WM8990_TEMPOK_IRQ_ENA 0x0800 /* TEMPOK_IRQ_ENA */
-#define WM8990_MICSHRT_IRQ_ENA 0x0400 /* MICSHRT_IRQ_ENA */
-#define WM8990_MICDET_IRQ_ENA 0x0200 /* MICDET_IRQ_ENA */
-#define WM8990_PLL_LCK_IRQ_ENA 0x0100 /* PLL_LCK_IRQ_ENA */
-#define WM8990_GPI8_DEB_ENA 0x0080 /* GPI8_DEB_ENA */
-#define WM8990_GPI8_IRQ_ENA 0x0040 /* GPI8_IRQ_ENA */
-#define WM8990_GPI8_ENA 0x0010 /* GPI8_ENA */
-#define WM8990_GPI7_DEB_ENA 0x0008 /* GPI7_DEB_ENA */
-#define WM8990_GPI7_IRQ_ENA 0x0004 /* GPI7_IRQ_ENA */
-#define WM8990_GPI7_ENA 0x0001 /* GPI7_ENA */
-
-/*
- * R23 (0x17) - GPIO_POL
- */
-#define WM8990_IRQ_INV 0x1000 /* IRQ_INV */
-#define WM8990_TEMPOK_POL 0x0800 /* TEMPOK_POL */
-#define WM8990_MICSHRT_POL 0x0400 /* MICSHRT_POL */
-#define WM8990_MICDET_POL 0x0200 /* MICDET_POL */
-#define WM8990_PLL_LCK_POL 0x0100 /* PLL_LCK_POL */
-#define WM8990_GPI8_POL 0x0080 /* GPI8_POL */
-#define WM8990_GPI7_POL 0x0040 /* GPI7_POL */
-#define WM8990_GPIO6_POL 0x0020 /* GPIO6_POL */
-#define WM8990_GPIO5_POL 0x0010 /* GPIO5_POL */
-#define WM8990_GPIO4_POL 0x0008 /* GPIO4_POL */
-#define WM8990_GPIO3_POL 0x0004 /* GPIO3_POL */
-#define WM8990_GPIO2_POL 0x0002 /* GPIO2_POL */
-#define WM8990_GPIO1_POL 0x0001 /* GPIO1_POL */
-
-/*
- * R24 (0x18) - Left Line Input 1&2 Volume
- */
-#define WM8990_IPVU 0x0100 /* IPVU */
-#define WM8990_LI12MUTE 0x0080 /* LI12MUTE */
-#define WM8990_LI12MUTE_BIT 7
-#define WM8990_LI12ZC 0x0040 /* LI12ZC */
-#define WM8990_LI12ZC_BIT 6
-#define WM8990_LIN12VOL_MASK 0x001F /* LIN12VOL - [4:0] */
-#define WM8990_LIN12VOL_SHIFT 0
-/*
- * R25 (0x19) - Left Line Input 3&4 Volume
- */
-#define WM8990_IPVU 0x0100 /* IPVU */
-#define WM8990_LI34MUTE 0x0080 /* LI34MUTE */
-#define WM8990_LI34MUTE_BIT 7
-#define WM8990_LI34ZC 0x0040 /* LI34ZC */
-#define WM8990_LI34ZC_BIT 6
-#define WM8990_LIN34VOL_MASK 0x001F /* LIN34VOL - [4:0] */
-#define WM8990_LIN34VOL_SHIFT 0
-
-/*
- * R26 (0x1A) - Right Line Input 1&2 Volume
- */
-#define WM8990_IPVU 0x0100 /* IPVU */
-#define WM8990_RI12MUTE 0x0080 /* RI12MUTE */
-#define WM8990_RI12MUTE_BIT 7
-#define WM8990_RI12ZC 0x0040 /* RI12ZC */
-#define WM8990_RI12ZC_BIT 6
-#define WM8990_RIN12VOL_MASK 0x001F /* RIN12VOL - [4:0] */
-#define WM8990_RIN12VOL_SHIFT 0
-
-/*
- * R27 (0x1B) - Right Line Input 3&4 Volume
- */
-#define WM8990_IPVU 0x0100 /* IPVU */
-#define WM8990_RI34MUTE 0x0080 /* RI34MUTE */
-#define WM8990_RI34MUTE_BIT 7
-#define WM8990_RI34ZC 0x0040 /* RI34ZC */
-#define WM8990_RI34ZC_BIT 6
-#define WM8990_RIN34VOL_MASK 0x001F /* RIN34VOL - [4:0] */
-#define WM8990_RIN34VOL_SHIFT 0
-
-/*
- * R28 (0x1C) - Left Output Volume
- */
-#define WM8990_OPVU 0x0100 /* OPVU */
-#define WM8990_LOZC 0x0080 /* LOZC */
-#define WM8990_LOZC_BIT 7
-#define WM8990_LOUTVOL_MASK 0x007F /* LOUTVOL - [6:0] */
-#define WM8990_LOUTVOL_SHIFT 0
-/*
- * R29 (0x1D) - Right Output Volume
- */
-#define WM8990_OPVU 0x0100 /* OPVU */
-#define WM8990_ROZC 0x0080 /* ROZC */
-#define WM8990_ROZC_BIT 7
-#define WM8990_ROUTVOL_MASK 0x007F /* ROUTVOL - [6:0] */
-#define WM8990_ROUTVOL_SHIFT 0
-/*
- * R30 (0x1E) - Line Outputs Volume
- */
-#define WM8990_LONMUTE 0x0040 /* LONMUTE */
-#define WM8990_LONMUTE_BIT 6
-#define WM8990_LOPMUTE 0x0020 /* LOPMUTE */
-#define WM8990_LOPMUTE_BIT 5
-#define WM8990_LOATTN 0x0010 /* LOATTN */
-#define WM8990_LOATTN_BIT 4
-#define WM8990_RONMUTE 0x0004 /* RONMUTE */
-#define WM8990_RONMUTE_BIT 2
-#define WM8990_ROPMUTE 0x0002 /* ROPMUTE */
-#define WM8990_ROPMUTE_BIT 1
-#define WM8990_ROATTN 0x0001 /* ROATTN */
-#define WM8990_ROATTN_BIT 0
-
-/*
- * R31 (0x1F) - Out3/4 Volume
- */
-#define WM8990_OUT3MUTE 0x0020 /* OUT3MUTE */
-#define WM8990_OUT3MUTE_BIT 5
-#define WM8990_OUT3ATTN 0x0010 /* OUT3ATTN */
-#define WM8990_OUT3ATTN_BIT 4
-#define WM8990_OUT4MUTE 0x0002 /* OUT4MUTE */
-#define WM8990_OUT4MUTE_BIT 1
-#define WM8990_OUT4ATTN 0x0001 /* OUT4ATTN */
-#define WM8990_OUT4ATTN_BIT 0
-
-/*
- * R32 (0x20) - Left OPGA Volume
- */
-#define WM8990_OPVU 0x0100 /* OPVU */
-#define WM8990_LOPGAZC 0x0080 /* LOPGAZC */
-#define WM8990_LOPGAZC_BIT 7
-#define WM8990_LOPGAVOL_MASK 0x007F /* LOPGAVOL - [6:0] */
-#define WM8990_LOPGAVOL_SHIFT 0
-
-/*
- * R33 (0x21) - Right OPGA Volume
- */
-#define WM8990_OPVU 0x0100 /* OPVU */
-#define WM8990_ROPGAZC 0x0080 /* ROPGAZC */
-#define WM8990_ROPGAZC_BIT 7
-#define WM8990_ROPGAVOL_MASK 0x007F /* ROPGAVOL - [6:0] */
-#define WM8990_ROPGAVOL_SHIFT 0
-/*
- * R34 (0x22) - Speaker Volume
- */
-#define WM8990_SPKATTN_MASK 0x0003 /* SPKATTN - [1:0] */
-#define WM8990_SPKATTN_SHIFT 0
-
-/*
- * R35 (0x23) - ClassD1
- */
-#define WM8990_CDMODE 0x0100 /* CDMODE */
-#define WM8990_CDMODE_BIT 8
-
-/*
- * R37 (0x25) - ClassD3
- */
-#define WM8990_DCGAIN_MASK 0x0007 /* DCGAIN - [5:3] */
-#define WM8990_DCGAIN_SHIFT 3
-#define WM8990_ACGAIN_MASK 0x0007 /* ACGAIN - [2:0] */
-#define WM8990_ACGAIN_SHIFT 0
-
-/*
- * R38 (0x26) - ClassD4
- */
-#define WM8990_SPKZC_MASK 0x0001 /* SPKZC */
-#define WM8990_SPKZC_SHIFT 7 /* SPKZC */
-#define WM8990_SPKVOL_MASK 0x007F /* SPKVOL - [6:0] */
-#define WM8990_SPKVOL_SHIFT 0 /* SPKVOL - [6:0] */
-
-/*
- * R39 (0x27) - Input Mixer1
- */
-#define WM8990_AINLMODE_MASK 0x000C /* AINLMODE - [3:2] */
-#define WM8990_AINLMODE_SHIFT 2
-#define WM8990_AINRMODE_MASK 0x0003 /* AINRMODE - [1:0] */
-#define WM8990_AINRMODE_SHIFT 0
-
-/*
- * R40 (0x28) - Input Mixer2
- */
-#define WM8990_LMP4 0x0080 /* LMP4 */
-#define WM8990_LMP4_BIT 7 /* LMP4 */
-#define WM8990_LMN3 0x0040 /* LMN3 */
-#define WM8990_LMN3_BIT 6 /* LMN3 */
-#define WM8990_LMP2 0x0020 /* LMP2 */
-#define WM8990_LMP2_BIT 5 /* LMP2 */
-#define WM8990_LMN1 0x0010 /* LMN1 */
-#define WM8990_LMN1_BIT 4 /* LMN1 */
-#define WM8990_RMP4 0x0008 /* RMP4 */
-#define WM8990_RMP4_BIT 3 /* RMP4 */
-#define WM8990_RMN3 0x0004 /* RMN3 */
-#define WM8990_RMN3_BIT 2 /* RMN3 */
-#define WM8990_RMP2 0x0002 /* RMP2 */
-#define WM8990_RMP2_BIT 1 /* RMP2 */
-#define WM8990_RMN1 0x0001 /* RMN1 */
-#define WM8990_RMN1_BIT 0 /* RMN1 */
-
-/*
- * R41 (0x29) - Input Mixer3
- */
-#define WM8990_L34MNB 0x0100 /* L34MNB */
-#define WM8990_L34MNB_BIT 8
-#define WM8990_L34MNBST 0x0080 /* L34MNBST */
-#define WM8990_L34MNBST_BIT 7
-#define WM8990_L12MNB 0x0020 /* L12MNB */
-#define WM8990_L12MNB_BIT 5
-#define WM8990_L12MNBST 0x0010 /* L12MNBST */
-#define WM8990_L12MNBST_BIT 4
-#define WM8990_LDBVOL_MASK 0x0007 /* LDBVOL - [2:0] */
-#define WM8990_LDBVOL_SHIFT 0
-
-/*
- * R42 (0x2A) - Input Mixer4
- */
-#define WM8990_R34MNB 0x0100 /* R34MNB */
-#define WM8990_R34MNB_BIT 8
-#define WM8990_R34MNBST 0x0080 /* R34MNBST */
-#define WM8990_R34MNBST_BIT 7
-#define WM8990_R12MNB 0x0020 /* R12MNB */
-#define WM8990_R12MNB_BIT 5
-#define WM8990_R12MNBST 0x0010 /* R12MNBST */
-#define WM8990_R12MNBST_BIT 4
-#define WM8990_RDBVOL_MASK 0x0007 /* RDBVOL - [2:0] */
-#define WM8990_RDBVOL_SHIFT 0
-
-/*
- * R43 (0x2B) - Input Mixer5
- */
-#define WM8990_LI2BVOL_MASK 0x07 /* LI2BVOL - [8:6] */
-#define WM8990_LI2BVOL_SHIFT 6
-#define WM8990_LR4BVOL_MASK 0x07 /* LR4BVOL - [5:3] */
-#define WM8990_LR4BVOL_SHIFT 3
-#define WM8990_LL4BVOL_MASK 0x07 /* LL4BVOL - [2:0] */
-#define WM8990_LL4BVOL_SHIFT 0
-
-/*
- * R44 (0x2C) - Input Mixer6
- */
-#define WM8990_RI2BVOL_MASK 0x07 /* RI2BVOL - [8:6] */
-#define WM8990_RI2BVOL_SHIFT 6
-#define WM8990_RL4BVOL_MASK 0x07 /* RL4BVOL - [5:3] */
-#define WM8990_RL4BVOL_SHIFT 3
-#define WM8990_RR4BVOL_MASK 0x07 /* RR4BVOL - [2:0] */
-#define WM8990_RR4BVOL_SHIFT 0
-
-/*
- * R45 (0x2D) - Output Mixer1
- */
-#define WM8990_LRBLO 0x0080 /* LRBLO */
-#define WM8990_LRBLO_BIT 7
-#define WM8990_LLBLO 0x0040 /* LLBLO */
-#define WM8990_LLBLO_BIT 6
-#define WM8990_LRI3LO 0x0020 /* LRI3LO */
-#define WM8990_LRI3LO_BIT 5
-#define WM8990_LLI3LO 0x0010 /* LLI3LO */
-#define WM8990_LLI3LO_BIT 4
-#define WM8990_LR12LO 0x0008 /* LR12LO */
-#define WM8990_LR12LO_BIT 3
-#define WM8990_LL12LO 0x0004 /* LL12LO */
-#define WM8990_LL12LO_BIT 2
-#define WM8990_LDLO 0x0001 /* LDLO */
-#define WM8990_LDLO_BIT 0
-
-/*
- * R46 (0x2E) - Output Mixer2
- */
-#define WM8990_RLBRO 0x0080 /* RLBRO */
-#define WM8990_RLBRO_BIT 7
-#define WM8990_RRBRO 0x0040 /* RRBRO */
-#define WM8990_RRBRO_BIT 6
-#define WM8990_RLI3RO 0x0020 /* RLI3RO */
-#define WM8990_RLI3RO_BIT 5
-#define WM8990_RRI3RO 0x0010 /* RRI3RO */
-#define WM8990_RRI3RO_BIT 4
-#define WM8990_RL12RO 0x0008 /* RL12RO */
-#define WM8990_RL12RO_BIT 3
-#define WM8990_RR12RO 0x0004 /* RR12RO */
-#define WM8990_RR12RO_BIT 2
-#define WM8990_RDRO 0x0001 /* RDRO */
-#define WM8990_RDRO_BIT 0
-
-/*
- * R47 (0x2F) - Output Mixer3
- */
-#define WM8990_LLI3LOVOL_MASK 0x07 /* LLI3LOVOL - [8:6] */
-#define WM8990_LLI3LOVOL_SHIFT 6
-#define WM8990_LR12LOVOL_MASK 0x07 /* LR12LOVOL - [5:3] */
-#define WM8990_LR12LOVOL_SHIFT 3
-#define WM8990_LL12LOVOL_MASK 0x07 /* LL12LOVOL - [2:0] */
-#define WM8990_LL12LOVOL_SHIFT 0
-
-/*
- * R48 (0x30) - Output Mixer4
- */
-#define WM8990_RRI3ROVOL_MASK 0x07 /* RRI3ROVOL - [8:6] */
-#define WM8990_RRI3ROVOL_SHIFT 6
-#define WM8990_RL12ROVOL_MASK 0x07 /* RL12ROVOL - [5:3] */
-#define WM8990_RL12ROVOL_SHIFT 3
-#define WM8990_RR12ROVOL_MASK 0x07 /* RR12ROVOL - [2:0] */
-#define WM8990_RR12ROVOL_SHIFT 0
-
-/*
- * R49 (0x31) - Output Mixer5
- */
-#define WM8990_LRI3LOVOL_MASK 0x07 /* LRI3LOVOL - [8:6] */
-#define WM8990_LRI3LOVOL_SHIFT 6
-#define WM8990_LRBLOVOL_MASK 0x07 /* LRBLOVOL - [5:3] */
-#define WM8990_LRBLOVOL_SHIFT 3
-#define WM8990_LLBLOVOL_MASK 0x07 /* LLBLOVOL - [2:0] */
-#define WM8990_LLBLOVOL_SHIFT 0
-
-/*
- * R50 (0x32) - Output Mixer6
- */
-#define WM8990_RLI3ROVOL_MASK 0x07 /* RLI3ROVOL - [8:6] */
-#define WM8990_RLI3ROVOL_SHIFT 6
-#define WM8990_RLBROVOL_MASK 0x07 /* RLBROVOL - [5:3] */
-#define WM8990_RLBROVOL_SHIFT 3
-#define WM8990_RRBROVOL_MASK 0x07 /* RRBROVOL - [2:0] */
-#define WM8990_RRBROVOL_SHIFT 0
-
-/*
- * R51 (0x33) - Out3/4 Mixer
- */
-#define WM8990_VSEL_MASK 0x0180 /* VSEL - [8:7] */
-#define WM8990_LI4O3 0x0020 /* LI4O3 */
-#define WM8990_LI4O3_BIT 5
-#define WM8990_LPGAO3 0x0010 /* LPGAO3 */
-#define WM8990_LPGAO3_BIT 4
-#define WM8990_RI4O4 0x0002 /* RI4O4 */
-#define WM8990_RI4O4_BIT 1
-#define WM8990_RPGAO4 0x0001 /* RPGAO4 */
-#define WM8990_RPGAO4_BIT 0
-/*
- * R52 (0x34) - Line Mixer1
- */
-#define WM8990_LLOPGALON 0x0040 /* LLOPGALON */
-#define WM8990_LLOPGALON_BIT 6
-#define WM8990_LROPGALON 0x0020 /* LROPGALON */
-#define WM8990_LROPGALON_BIT 5
-#define WM8990_LOPLON 0x0010 /* LOPLON */
-#define WM8990_LOPLON_BIT 4
-#define WM8990_LR12LOP 0x0004 /* LR12LOP */
-#define WM8990_LR12LOP_BIT 2
-#define WM8990_LL12LOP 0x0002 /* LL12LOP */
-#define WM8990_LL12LOP_BIT 1
-#define WM8990_LLOPGALOP 0x0001 /* LLOPGALOP */
-#define WM8990_LLOPGALOP_BIT 0
-/*
- * R53 (0x35) - Line Mixer2
- */
-#define WM8990_RROPGARON 0x0040 /* RROPGARON */
-#define WM8990_RROPGARON_BIT 6
-#define WM8990_RLOPGARON 0x0020 /* RLOPGARON */
-#define WM8990_RLOPGARON_BIT 5
-#define WM8990_ROPRON 0x0010 /* ROPRON */
-#define WM8990_ROPRON_BIT 4
-#define WM8990_RL12ROP 0x0004 /* RL12ROP */
-#define WM8990_RL12ROP_BIT 2
-#define WM8990_RR12ROP 0x0002 /* RR12ROP */
-#define WM8990_RR12ROP_BIT 1
-#define WM8990_RROPGAROP 0x0001 /* RROPGAROP */
-#define WM8990_RROPGAROP_BIT 0
-
-/*
- * R54 (0x36) - Speaker Mixer
- */
-#define WM8990_LB2SPK 0x0080 /* LB2SPK */
-#define WM8990_LB2SPK_BIT 7
-#define WM8990_RB2SPK 0x0040 /* RB2SPK */
-#define WM8990_RB2SPK_BIT 6
-#define WM8990_LI2SPK 0x0020 /* LI2SPK */
-#define WM8990_LI2SPK_BIT 5
-#define WM8990_RI2SPK 0x0010 /* RI2SPK */
-#define WM8990_RI2SPK_BIT 4
-#define WM8990_LOPGASPK 0x0008 /* LOPGASPK */
-#define WM8990_LOPGASPK_BIT 3
-#define WM8990_ROPGASPK 0x0004 /* ROPGASPK */
-#define WM8990_ROPGASPK_BIT 2
-#define WM8990_LDSPK 0x0002 /* LDSPK */
-#define WM8990_LDSPK_BIT 1
-#define WM8990_RDSPK 0x0001 /* RDSPK */
-#define WM8990_RDSPK_BIT 0
-
-/*
- * R55 (0x37) - Additional Control
- */
-#define WM8990_VROI 0x0001 /* VROI */
-
-/*
- * R56 (0x38) - AntiPOP1
- */
-#define WM8990_DIS_LLINE 0x0020 /* DIS_LLINE */
-#define WM8990_DIS_RLINE 0x0010 /* DIS_RLINE */
-#define WM8990_DIS_OUT3 0x0008 /* DIS_OUT3 */
-#define WM8990_DIS_OUT4 0x0004 /* DIS_OUT4 */
-#define WM8990_DIS_LOUT 0x0002 /* DIS_LOUT */
-#define WM8990_DIS_ROUT 0x0001 /* DIS_ROUT */
-
-/*
- * R57 (0x39) - AntiPOP2
- */
-#define WM8990_SOFTST 0x0040 /* SOFTST */
-#define WM8990_BUFIOEN 0x0008 /* BUFIOEN */
-#define WM8990_BUFDCOPEN 0x0004 /* BUFDCOPEN */
-#define WM8990_POBCTRL 0x0002 /* POBCTRL */
-#define WM8990_VMIDTOG 0x0001 /* VMIDTOG */
-
-/*
- * R58 (0x3A) - MICBIAS
- */
-#define WM8990_MCDSCTH_MASK 0x00C0 /* MCDSCTH - [7:6] */
-#define WM8990_MCDTHR_MASK 0x0038 /* MCDTHR - [5:3] */
-#define WM8990_MCD 0x0004 /* MCD */
-#define WM8990_MBSEL 0x0001 /* MBSEL */
-
-/*
- * R60 (0x3C) - PLL1
- */
-#define WM8990_SDM 0x0080 /* SDM */
-#define WM8990_PRESCALE 0x0040 /* PRESCALE */
-#define WM8990_PLLN_MASK 0x000F /* PLLN - [3:0] */
-
-/*
- * R61 (0x3D) - PLL2
- */
-#define WM8990_PLLK1_MASK 0x00FF /* PLLK1 - [7:0] */
-
-/*
- * R62 (0x3E) - PLL3
- */
-#define WM8990_PLLK2_MASK 0x00FF /* PLLK2 - [7:0] */
-
-/*
- * R63 (0x3F) - Internal Driver Bits
- */
-#define WM8990_INMIXL_PWR_BIT 0
-#define WM8990_AINLMUX_PWR_BIT 1
-#define WM8990_INMIXR_PWR_BIT 2
-#define WM8990_AINRMUX_PWR_BIT 3
-
-#define WM8990_MCLK_DIV 0
-#define WM8990_DACCLK_DIV 1
-#define WM8990_ADCCLK_DIV 2
-#define WM8990_BCLK_DIV 3
-
-#endif /* __WM8990REGISTERDEFS_H__ */
-/*------------------------------ END OF FILE ---------------------------------*/
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8991.c b/ANDROID_3.4.5/sound/soc/codecs/wm8991.c
deleted file mode 100644
index 9ac31ba9..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8991.c
+++ /dev/null
@@ -1,1423 +0,0 @@
-/*
- * wm8991.c -- WM8991 ALSA Soc Audio driver
- *
- * Copyright 2007-2010 Wolfson Microelectronics PLC.
- * Author: Graeme Gregory
- * Graeme.Gregory@wolfsonmicro.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <asm/div64.h>
-
-#include "wm8991.h"
-
-struct wm8991_priv {
- enum snd_soc_control_type control_type;
- unsigned int pcmclk;
-};
-
-static const u16 wm8991_reg_defs[] = {
- 0x8991, /* R0 - Reset */
- 0x0000, /* R1 - Power Management (1) */
- 0x6000, /* R2 - Power Management (2) */
- 0x0000, /* R3 - Power Management (3) */
- 0x4050, /* R4 - Audio Interface (1) */
- 0x4000, /* R5 - Audio Interface (2) */
- 0x01C8, /* R6 - Clocking (1) */
- 0x0000, /* R7 - Clocking (2) */
- 0x0040, /* R8 - Audio Interface (3) */
- 0x0040, /* R9 - Audio Interface (4) */
- 0x0004, /* R10 - DAC CTRL */
- 0x00C0, /* R11 - Left DAC Digital Volume */
- 0x00C0, /* R12 - Right DAC Digital Volume */
- 0x0000, /* R13 - Digital Side Tone */
- 0x0100, /* R14 - ADC CTRL */
- 0x00C0, /* R15 - Left ADC Digital Volume */
- 0x00C0, /* R16 - Right ADC Digital Volume */
- 0x0000, /* R17 */
- 0x0000, /* R18 - GPIO CTRL 1 */
- 0x1000, /* R19 - GPIO1 & GPIO2 */
- 0x1010, /* R20 - GPIO3 & GPIO4 */
- 0x1010, /* R21 - GPIO5 & GPIO6 */
- 0x8000, /* R22 - GPIOCTRL 2 */
- 0x0800, /* R23 - GPIO_POL */
- 0x008B, /* R24 - Left Line Input 1&2 Volume */
- 0x008B, /* R25 - Left Line Input 3&4 Volume */
- 0x008B, /* R26 - Right Line Input 1&2 Volume */
- 0x008B, /* R27 - Right Line Input 3&4 Volume */
- 0x0000, /* R28 - Left Output Volume */
- 0x0000, /* R29 - Right Output Volume */
- 0x0066, /* R30 - Line Outputs Volume */
- 0x0022, /* R31 - Out3/4 Volume */
- 0x0079, /* R32 - Left OPGA Volume */
- 0x0079, /* R33 - Right OPGA Volume */
- 0x0003, /* R34 - Speaker Volume */
- 0x0003, /* R35 - ClassD1 */
- 0x0000, /* R36 */
- 0x0100, /* R37 - ClassD3 */
- 0x0000, /* R38 */
- 0x0000, /* R39 - Input Mixer1 */
- 0x0000, /* R40 - Input Mixer2 */
- 0x0000, /* R41 - Input Mixer3 */
- 0x0000, /* R42 - Input Mixer4 */
- 0x0000, /* R43 - Input Mixer5 */
- 0x0000, /* R44 - Input Mixer6 */
- 0x0000, /* R45 - Output Mixer1 */
- 0x0000, /* R46 - Output Mixer2 */
- 0x0000, /* R47 - Output Mixer3 */
- 0x0000, /* R48 - Output Mixer4 */
- 0x0000, /* R49 - Output Mixer5 */
- 0x0000, /* R50 - Output Mixer6 */
- 0x0180, /* R51 - Out3/4 Mixer */
- 0x0000, /* R52 - Line Mixer1 */
- 0x0000, /* R53 - Line Mixer2 */
- 0x0000, /* R54 - Speaker Mixer */
- 0x0000, /* R55 - Additional Control */
- 0x0000, /* R56 - AntiPOP1 */
- 0x0000, /* R57 - AntiPOP2 */
- 0x0000, /* R58 - MICBIAS */
- 0x0000, /* R59 */
- 0x0008, /* R60 - PLL1 */
- 0x0031, /* R61 - PLL2 */
- 0x0026, /* R62 - PLL3 */
-};
-
-#define wm8991_reset(c) snd_soc_write(c, WM8991_RESET, 0)
-
-static const unsigned int rec_mix_tlv[] = {
- TLV_DB_RANGE_HEAD(1),
- 0, 7, TLV_DB_LINEAR_ITEM(-1500, 600),
-};
-
-static const unsigned int in_pga_tlv[] = {
- TLV_DB_RANGE_HEAD(1),
- 0, 0x1F, TLV_DB_LINEAR_ITEM(-1650, 3000),
-};
-
-static const unsigned int out_mix_tlv[] = {
- TLV_DB_RANGE_HEAD(1),
- 0, 7, TLV_DB_LINEAR_ITEM(0, -2100),
-};
-
-static const unsigned int out_pga_tlv[] = {
- TLV_DB_RANGE_HEAD(1),
- 0, 127, TLV_DB_LINEAR_ITEM(-7300, 600),
-};
-
-static const unsigned int out_omix_tlv[] = {
- TLV_DB_RANGE_HEAD(1),
- 0, 7, TLV_DB_LINEAR_ITEM(-600, 0),
-};
-
-static const unsigned int out_dac_tlv[] = {
- TLV_DB_RANGE_HEAD(1),
- 0, 255, TLV_DB_LINEAR_ITEM(-7163, 0),
-};
-
-static const unsigned int in_adc_tlv[] = {
- TLV_DB_RANGE_HEAD(1),
- 0, 255, TLV_DB_LINEAR_ITEM(-7163, 1763),
-};
-
-static const unsigned int out_sidetone_tlv[] = {
- TLV_DB_RANGE_HEAD(1),
- 0, 31, TLV_DB_LINEAR_ITEM(-3600, 0),
-};
-
-static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int ret;
- u16 val;
-
- ret = snd_soc_put_volsw(kcontrol, ucontrol);
- if (ret < 0)
- return ret;
-
- /* now hit the volume update bits (always bit 8) */
- val = snd_soc_read(codec, reg);
- return snd_soc_write(codec, reg, val | 0x0100);
-}
-
-static const char *wm8991_digital_sidetone[] =
-{"None", "Left ADC", "Right ADC", "Reserved"};
-
-static const struct soc_enum wm8991_left_digital_sidetone_enum =
- SOC_ENUM_SINGLE(WM8991_DIGITAL_SIDE_TONE,
- WM8991_ADC_TO_DACL_SHIFT,
- WM8991_ADC_TO_DACL_MASK,
- wm8991_digital_sidetone);
-
-static const struct soc_enum wm8991_right_digital_sidetone_enum =
- SOC_ENUM_SINGLE(WM8991_DIGITAL_SIDE_TONE,
- WM8991_ADC_TO_DACR_SHIFT,
- WM8991_ADC_TO_DACR_MASK,
- wm8991_digital_sidetone);
-
-static const char *wm8991_adcmode[] =
-{"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"};
-
-static const struct soc_enum wm8991_right_adcmode_enum =
- SOC_ENUM_SINGLE(WM8991_ADC_CTRL,
- WM8991_ADC_HPF_CUT_SHIFT,
- WM8991_ADC_HPF_CUT_MASK,
- wm8991_adcmode);
-
-static const struct snd_kcontrol_new wm8991_snd_controls[] = {
- /* INMIXL */
- SOC_SINGLE("LIN12 PGA Boost", WM8991_INPUT_MIXER3, WM8991_L12MNBST_BIT, 1, 0),
- SOC_SINGLE("LIN34 PGA Boost", WM8991_INPUT_MIXER3, WM8991_L34MNBST_BIT, 1, 0),
- /* INMIXR */
- SOC_SINGLE("RIN12 PGA Boost", WM8991_INPUT_MIXER3, WM8991_R12MNBST_BIT, 1, 0),
- SOC_SINGLE("RIN34 PGA Boost", WM8991_INPUT_MIXER3, WM8991_R34MNBST_BIT, 1, 0),
-
- /* LOMIX */
- SOC_SINGLE_TLV("LOMIX LIN3 Bypass Volume", WM8991_OUTPUT_MIXER3,
- WM8991_LLI3LOVOL_SHIFT, WM8991_LLI3LOVOL_MASK, 1, out_mix_tlv),
- SOC_SINGLE_TLV("LOMIX RIN12 PGA Bypass Volume", WM8991_OUTPUT_MIXER3,
- WM8991_LR12LOVOL_SHIFT, WM8991_LR12LOVOL_MASK, 1, out_mix_tlv),
- SOC_SINGLE_TLV("LOMIX LIN12 PGA Bypass Volume", WM8991_OUTPUT_MIXER3,
- WM8991_LL12LOVOL_SHIFT, WM8991_LL12LOVOL_MASK, 1, out_mix_tlv),
- SOC_SINGLE_TLV("LOMIX RIN3 Bypass Volume", WM8991_OUTPUT_MIXER5,
- WM8991_LRI3LOVOL_SHIFT, WM8991_LRI3LOVOL_MASK, 1, out_mix_tlv),
- SOC_SINGLE_TLV("LOMIX AINRMUX Bypass Volume", WM8991_OUTPUT_MIXER5,
- WM8991_LRBLOVOL_SHIFT, WM8991_LRBLOVOL_MASK, 1, out_mix_tlv),
- SOC_SINGLE_TLV("LOMIX AINLMUX Bypass Volume", WM8991_OUTPUT_MIXER5,
- WM8991_LRBLOVOL_SHIFT, WM8991_LRBLOVOL_MASK, 1, out_mix_tlv),
-
- /* ROMIX */
- SOC_SINGLE_TLV("ROMIX RIN3 Bypass Volume", WM8991_OUTPUT_MIXER4,
- WM8991_RRI3ROVOL_SHIFT, WM8991_RRI3ROVOL_MASK, 1, out_mix_tlv),
- SOC_SINGLE_TLV("ROMIX LIN12 PGA Bypass Volume", WM8991_OUTPUT_MIXER4,
- WM8991_RL12ROVOL_SHIFT, WM8991_RL12ROVOL_MASK, 1, out_mix_tlv),
- SOC_SINGLE_TLV("ROMIX RIN12 PGA Bypass Volume", WM8991_OUTPUT_MIXER4,
- WM8991_RR12ROVOL_SHIFT, WM8991_RR12ROVOL_MASK, 1, out_mix_tlv),
- SOC_SINGLE_TLV("ROMIX LIN3 Bypass Volume", WM8991_OUTPUT_MIXER6,
- WM8991_RLI3ROVOL_SHIFT, WM8991_RLI3ROVOL_MASK, 1, out_mix_tlv),
- SOC_SINGLE_TLV("ROMIX AINLMUX Bypass Volume", WM8991_OUTPUT_MIXER6,
- WM8991_RLBROVOL_SHIFT, WM8991_RLBROVOL_MASK, 1, out_mix_tlv),
- SOC_SINGLE_TLV("ROMIX AINRMUX Bypass Volume", WM8991_OUTPUT_MIXER6,
- WM8991_RRBROVOL_SHIFT, WM8991_RRBROVOL_MASK, 1, out_mix_tlv),
-
- /* LOUT */
- SOC_WM899X_OUTPGA_SINGLE_R_TLV("LOUT Volume", WM8991_LEFT_OUTPUT_VOLUME,
- WM8991_LOUTVOL_SHIFT, WM8991_LOUTVOL_MASK, 0, out_pga_tlv),
- SOC_SINGLE("LOUT ZC", WM8991_LEFT_OUTPUT_VOLUME, WM8991_LOZC_BIT, 1, 0),
-
- /* ROUT */
- SOC_WM899X_OUTPGA_SINGLE_R_TLV("ROUT Volume", WM8991_RIGHT_OUTPUT_VOLUME,
- WM8991_ROUTVOL_SHIFT, WM8991_ROUTVOL_MASK, 0, out_pga_tlv),
- SOC_SINGLE("ROUT ZC", WM8991_RIGHT_OUTPUT_VOLUME, WM8991_ROZC_BIT, 1, 0),
-
- /* LOPGA */
- SOC_WM899X_OUTPGA_SINGLE_R_TLV("LOPGA Volume", WM8991_LEFT_OPGA_VOLUME,
- WM8991_LOPGAVOL_SHIFT, WM8991_LOPGAVOL_MASK, 0, out_pga_tlv),
- SOC_SINGLE("LOPGA ZC Switch", WM8991_LEFT_OPGA_VOLUME,
- WM8991_LOPGAZC_BIT, 1, 0),
-
- /* ROPGA */
- SOC_WM899X_OUTPGA_SINGLE_R_TLV("ROPGA Volume", WM8991_RIGHT_OPGA_VOLUME,
- WM8991_ROPGAVOL_SHIFT, WM8991_ROPGAVOL_MASK, 0, out_pga_tlv),
- SOC_SINGLE("ROPGA ZC Switch", WM8991_RIGHT_OPGA_VOLUME,
- WM8991_ROPGAZC_BIT, 1, 0),
-
- SOC_SINGLE("LON Mute Switch", WM8991_LINE_OUTPUTS_VOLUME,
- WM8991_LONMUTE_BIT, 1, 0),
- SOC_SINGLE("LOP Mute Switch", WM8991_LINE_OUTPUTS_VOLUME,
- WM8991_LOPMUTE_BIT, 1, 0),
- SOC_SINGLE("LOP Attenuation Switch", WM8991_LINE_OUTPUTS_VOLUME,
- WM8991_LOATTN_BIT, 1, 0),
- SOC_SINGLE("RON Mute Switch", WM8991_LINE_OUTPUTS_VOLUME,
- WM8991_RONMUTE_BIT, 1, 0),
- SOC_SINGLE("ROP Mute Switch", WM8991_LINE_OUTPUTS_VOLUME,
- WM8991_ROPMUTE_BIT, 1, 0),
- SOC_SINGLE("ROP Attenuation Switch", WM8991_LINE_OUTPUTS_VOLUME,
- WM8991_ROATTN_BIT, 1, 0),
-
- SOC_SINGLE("OUT3 Mute Switch", WM8991_OUT3_4_VOLUME,
- WM8991_OUT3MUTE_BIT, 1, 0),
- SOC_SINGLE("OUT3 Attenuation Switch", WM8991_OUT3_4_VOLUME,
- WM8991_OUT3ATTN_BIT, 1, 0),
-
- SOC_SINGLE("OUT4 Mute Switch", WM8991_OUT3_4_VOLUME,
- WM8991_OUT4MUTE_BIT, 1, 0),
- SOC_SINGLE("OUT4 Attenuation Switch", WM8991_OUT3_4_VOLUME,
- WM8991_OUT4ATTN_BIT, 1, 0),
-
- SOC_SINGLE("Speaker Mode Switch", WM8991_CLASSD1,
- WM8991_CDMODE_BIT, 1, 0),
-
- SOC_SINGLE("Speaker Output Attenuation Volume", WM8991_SPEAKER_VOLUME,
- WM8991_SPKVOL_SHIFT, WM8991_SPKVOL_MASK, 0),
- SOC_SINGLE("Speaker DC Boost Volume", WM8991_CLASSD3,
- WM8991_DCGAIN_SHIFT, WM8991_DCGAIN_MASK, 0),
- SOC_SINGLE("Speaker AC Boost Volume", WM8991_CLASSD3,
- WM8991_ACGAIN_SHIFT, WM8991_ACGAIN_MASK, 0),
-
- SOC_WM899X_OUTPGA_SINGLE_R_TLV("Left DAC Digital Volume",
- WM8991_LEFT_DAC_DIGITAL_VOLUME,
- WM8991_DACL_VOL_SHIFT,
- WM8991_DACL_VOL_MASK,
- 0,
- out_dac_tlv),
-
- SOC_WM899X_OUTPGA_SINGLE_R_TLV("Right DAC Digital Volume",
- WM8991_RIGHT_DAC_DIGITAL_VOLUME,
- WM8991_DACR_VOL_SHIFT,
- WM8991_DACR_VOL_MASK,
- 0,
- out_dac_tlv),
-
- SOC_ENUM("Left Digital Sidetone", wm8991_left_digital_sidetone_enum),
- SOC_ENUM("Right Digital Sidetone", wm8991_right_digital_sidetone_enum),
-
- SOC_SINGLE_TLV("Left Digital Sidetone Volume", WM8991_DIGITAL_SIDE_TONE,
- WM8991_ADCL_DAC_SVOL_SHIFT, WM8991_ADCL_DAC_SVOL_MASK, 0,
- out_sidetone_tlv),
- SOC_SINGLE_TLV("Right Digital Sidetone Volume", WM8991_DIGITAL_SIDE_TONE,
- WM8991_ADCR_DAC_SVOL_SHIFT, WM8991_ADCR_DAC_SVOL_MASK, 0,
- out_sidetone_tlv),
-
- SOC_SINGLE("ADC Digital High Pass Filter Switch", WM8991_ADC_CTRL,
- WM8991_ADC_HPF_ENA_BIT, 1, 0),
-
- SOC_ENUM("ADC HPF Mode", wm8991_right_adcmode_enum),
-
- SOC_WM899X_OUTPGA_SINGLE_R_TLV("Left ADC Digital Volume",
- WM8991_LEFT_ADC_DIGITAL_VOLUME,
- WM8991_ADCL_VOL_SHIFT,
- WM8991_ADCL_VOL_MASK,
- 0,
- in_adc_tlv),
-
- SOC_WM899X_OUTPGA_SINGLE_R_TLV("Right ADC Digital Volume",
- WM8991_RIGHT_ADC_DIGITAL_VOLUME,
- WM8991_ADCR_VOL_SHIFT,
- WM8991_ADCR_VOL_MASK,
- 0,
- in_adc_tlv),
-
- SOC_WM899X_OUTPGA_SINGLE_R_TLV("LIN12 Volume",
- WM8991_LEFT_LINE_INPUT_1_2_VOLUME,
- WM8991_LIN12VOL_SHIFT,
- WM8991_LIN12VOL_MASK,
- 0,
- in_pga_tlv),
-
- SOC_SINGLE("LIN12 ZC Switch", WM8991_LEFT_LINE_INPUT_1_2_VOLUME,
- WM8991_LI12ZC_BIT, 1, 0),
-
- SOC_SINGLE("LIN12 Mute Switch", WM8991_LEFT_LINE_INPUT_1_2_VOLUME,
- WM8991_LI12MUTE_BIT, 1, 0),
-
- SOC_WM899X_OUTPGA_SINGLE_R_TLV("LIN34 Volume",
- WM8991_LEFT_LINE_INPUT_3_4_VOLUME,
- WM8991_LIN34VOL_SHIFT,
- WM8991_LIN34VOL_MASK,
- 0,
- in_pga_tlv),
-
- SOC_SINGLE("LIN34 ZC Switch", WM8991_LEFT_LINE_INPUT_3_4_VOLUME,
- WM8991_LI34ZC_BIT, 1, 0),
-
- SOC_SINGLE("LIN34 Mute Switch", WM8991_LEFT_LINE_INPUT_3_4_VOLUME,
- WM8991_LI34MUTE_BIT, 1, 0),
-
- SOC_WM899X_OUTPGA_SINGLE_R_TLV("RIN12 Volume",
- WM8991_RIGHT_LINE_INPUT_1_2_VOLUME,
- WM8991_RIN12VOL_SHIFT,
- WM8991_RIN12VOL_MASK,
- 0,
- in_pga_tlv),
-
- SOC_SINGLE("RIN12 ZC Switch", WM8991_RIGHT_LINE_INPUT_1_2_VOLUME,
- WM8991_RI12ZC_BIT, 1, 0),
-
- SOC_SINGLE("RIN12 Mute Switch", WM8991_RIGHT_LINE_INPUT_1_2_VOLUME,
- WM8991_RI12MUTE_BIT, 1, 0),
-
- SOC_WM899X_OUTPGA_SINGLE_R_TLV("RIN34 Volume",
- WM8991_RIGHT_LINE_INPUT_3_4_VOLUME,
- WM8991_RIN34VOL_SHIFT,
- WM8991_RIN34VOL_MASK,
- 0,
- in_pga_tlv),
-
- SOC_SINGLE("RIN34 ZC Switch", WM8991_RIGHT_LINE_INPUT_3_4_VOLUME,
- WM8991_RI34ZC_BIT, 1, 0),
-
- SOC_SINGLE("RIN34 Mute Switch", WM8991_RIGHT_LINE_INPUT_3_4_VOLUME,
- WM8991_RI34MUTE_BIT, 1, 0),
-};
-
-/*
- * _DAPM_ Controls
- */
-static int inmixer_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- u16 reg, fakepower;
-
- reg = snd_soc_read(w->codec, WM8991_POWER_MANAGEMENT_2);
- fakepower = snd_soc_read(w->codec, WM8991_INTDRIVBITS);
-
- if (fakepower & ((1 << WM8991_INMIXL_PWR_BIT) |
- (1 << WM8991_AINLMUX_PWR_BIT)))
- reg |= WM8991_AINL_ENA;
- else
- reg &= ~WM8991_AINL_ENA;
-
- if (fakepower & ((1 << WM8991_INMIXR_PWR_BIT) |
- (1 << WM8991_AINRMUX_PWR_BIT)))
- reg |= WM8991_AINR_ENA;
- else
- reg &= ~WM8991_AINR_ENA;
-
- snd_soc_write(w->codec, WM8991_POWER_MANAGEMENT_2, reg);
- return 0;
-}
-
-static int outmixer_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- u32 reg_shift = kcontrol->private_value & 0xfff;
- int ret = 0;
- u16 reg;
-
- switch (reg_shift) {
- case WM8991_SPEAKER_MIXER | (WM8991_LDSPK_BIT << 8):
- reg = snd_soc_read(w->codec, WM8991_OUTPUT_MIXER1);
- if (reg & WM8991_LDLO) {
- printk(KERN_WARNING
- "Cannot set as Output Mixer 1 LDLO Set\n");
- ret = -1;
- }
- break;
-
- case WM8991_SPEAKER_MIXER | (WM8991_RDSPK_BIT << 8):
- reg = snd_soc_read(w->codec, WM8991_OUTPUT_MIXER2);
- if (reg & WM8991_RDRO) {
- printk(KERN_WARNING
- "Cannot set as Output Mixer 2 RDRO Set\n");
- ret = -1;
- }
- break;
-
- case WM8991_OUTPUT_MIXER1 | (WM8991_LDLO_BIT << 8):
- reg = snd_soc_read(w->codec, WM8991_SPEAKER_MIXER);
- if (reg & WM8991_LDSPK) {
- printk(KERN_WARNING
- "Cannot set as Speaker Mixer LDSPK Set\n");
- ret = -1;
- }
- break;
-
- case WM8991_OUTPUT_MIXER2 | (WM8991_RDRO_BIT << 8):
- reg = snd_soc_read(w->codec, WM8991_SPEAKER_MIXER);
- if (reg & WM8991_RDSPK) {
- printk(KERN_WARNING
- "Cannot set as Speaker Mixer RDSPK Set\n");
- ret = -1;
- }
- break;
- }
-
- return ret;
-}
-
-/* INMIX dB values */
-static const unsigned int in_mix_tlv[] = {
- TLV_DB_RANGE_HEAD(1),
- 0, 7, TLV_DB_LINEAR_ITEM(-1200, 600),
-};
-
-/* Left In PGA Connections */
-static const struct snd_kcontrol_new wm8991_dapm_lin12_pga_controls[] = {
- SOC_DAPM_SINGLE("LIN1 Switch", WM8991_INPUT_MIXER2, WM8991_LMN1_BIT, 1, 0),
- SOC_DAPM_SINGLE("LIN2 Switch", WM8991_INPUT_MIXER2, WM8991_LMP2_BIT, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8991_dapm_lin34_pga_controls[] = {
- SOC_DAPM_SINGLE("LIN3 Switch", WM8991_INPUT_MIXER2, WM8991_LMN3_BIT, 1, 0),
- SOC_DAPM_SINGLE("LIN4 Switch", WM8991_INPUT_MIXER2, WM8991_LMP4_BIT, 1, 0),
-};
-
-/* Right In PGA Connections */
-static const struct snd_kcontrol_new wm8991_dapm_rin12_pga_controls[] = {
- SOC_DAPM_SINGLE("RIN1 Switch", WM8991_INPUT_MIXER2, WM8991_RMN1_BIT, 1, 0),
- SOC_DAPM_SINGLE("RIN2 Switch", WM8991_INPUT_MIXER2, WM8991_RMP2_BIT, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8991_dapm_rin34_pga_controls[] = {
- SOC_DAPM_SINGLE("RIN3 Switch", WM8991_INPUT_MIXER2, WM8991_RMN3_BIT, 1, 0),
- SOC_DAPM_SINGLE("RIN4 Switch", WM8991_INPUT_MIXER2, WM8991_RMP4_BIT, 1, 0),
-};
-
-/* INMIXL */
-static const struct snd_kcontrol_new wm8991_dapm_inmixl_controls[] = {
- SOC_DAPM_SINGLE_TLV("Record Left Volume", WM8991_INPUT_MIXER3,
- WM8991_LDBVOL_SHIFT, WM8991_LDBVOL_MASK, 0, in_mix_tlv),
- SOC_DAPM_SINGLE_TLV("LIN2 Volume", WM8991_INPUT_MIXER5, WM8991_LI2BVOL_SHIFT,
- 7, 0, in_mix_tlv),
- SOC_DAPM_SINGLE("LINPGA12 Switch", WM8991_INPUT_MIXER3, WM8991_L12MNB_BIT,
- 1, 0),
- SOC_DAPM_SINGLE("LINPGA34 Switch", WM8991_INPUT_MIXER3, WM8991_L34MNB_BIT,
- 1, 0),
-};
-
-/* INMIXR */
-static const struct snd_kcontrol_new wm8991_dapm_inmixr_controls[] = {
- SOC_DAPM_SINGLE_TLV("Record Right Volume", WM8991_INPUT_MIXER4,
- WM8991_RDBVOL_SHIFT, WM8991_RDBVOL_MASK, 0, in_mix_tlv),
- SOC_DAPM_SINGLE_TLV("RIN2 Volume", WM8991_INPUT_MIXER6, WM8991_RI2BVOL_SHIFT,
- 7, 0, in_mix_tlv),
- SOC_DAPM_SINGLE("RINPGA12 Switch", WM8991_INPUT_MIXER3, WM8991_L12MNB_BIT,
- 1, 0),
- SOC_DAPM_SINGLE("RINPGA34 Switch", WM8991_INPUT_MIXER3, WM8991_L34MNB_BIT,
- 1, 0),
-};
-
-/* AINLMUX */
-static const char *wm8991_ainlmux[] =
-{"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"};
-
-static const struct soc_enum wm8991_ainlmux_enum =
- SOC_ENUM_SINGLE(WM8991_INPUT_MIXER1, WM8991_AINLMODE_SHIFT,
- ARRAY_SIZE(wm8991_ainlmux), wm8991_ainlmux);
-
-static const struct snd_kcontrol_new wm8991_dapm_ainlmux_controls =
- SOC_DAPM_ENUM("Route", wm8991_ainlmux_enum);
-
-/* DIFFINL */
-
-/* AINRMUX */
-static const char *wm8991_ainrmux[] =
-{"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"};
-
-static const struct soc_enum wm8991_ainrmux_enum =
- SOC_ENUM_SINGLE(WM8991_INPUT_MIXER1, WM8991_AINRMODE_SHIFT,
- ARRAY_SIZE(wm8991_ainrmux), wm8991_ainrmux);
-
-static const struct snd_kcontrol_new wm8991_dapm_ainrmux_controls =
- SOC_DAPM_ENUM("Route", wm8991_ainrmux_enum);
-
-/* RXVOICE */
-static const struct snd_kcontrol_new wm8991_dapm_rxvoice_controls[] = {
- SOC_DAPM_SINGLE_TLV("LIN4RXN", WM8991_INPUT_MIXER5, WM8991_LR4BVOL_SHIFT,
- WM8991_LR4BVOL_MASK, 0, in_mix_tlv),
- SOC_DAPM_SINGLE_TLV("RIN4RXP", WM8991_INPUT_MIXER6, WM8991_RL4BVOL_SHIFT,
- WM8991_RL4BVOL_MASK, 0, in_mix_tlv),
-};
-
-/* LOMIX */
-static const struct snd_kcontrol_new wm8991_dapm_lomix_controls[] = {
- SOC_DAPM_SINGLE("LOMIX Right ADC Bypass Switch", WM8991_OUTPUT_MIXER1,
- WM8991_LRBLO_BIT, 1, 0),
- SOC_DAPM_SINGLE("LOMIX Left ADC Bypass Switch", WM8991_OUTPUT_MIXER1,
- WM8991_LLBLO_BIT, 1, 0),
- SOC_DAPM_SINGLE("LOMIX RIN3 Bypass Switch", WM8991_OUTPUT_MIXER1,
- WM8991_LRI3LO_BIT, 1, 0),
- SOC_DAPM_SINGLE("LOMIX LIN3 Bypass Switch", WM8991_OUTPUT_MIXER1,
- WM8991_LLI3LO_BIT, 1, 0),
- SOC_DAPM_SINGLE("LOMIX RIN12 PGA Bypass Switch", WM8991_OUTPUT_MIXER1,
- WM8991_LR12LO_BIT, 1, 0),
- SOC_DAPM_SINGLE("LOMIX LIN12 PGA Bypass Switch", WM8991_OUTPUT_MIXER1,
- WM8991_LL12LO_BIT, 1, 0),
- SOC_DAPM_SINGLE("LOMIX Left DAC Switch", WM8991_OUTPUT_MIXER1,
- WM8991_LDLO_BIT, 1, 0),
-};
-
-/* ROMIX */
-static const struct snd_kcontrol_new wm8991_dapm_romix_controls[] = {
- SOC_DAPM_SINGLE("ROMIX Left ADC Bypass Switch", WM8991_OUTPUT_MIXER2,
- WM8991_RLBRO_BIT, 1, 0),
- SOC_DAPM_SINGLE("ROMIX Right ADC Bypass Switch", WM8991_OUTPUT_MIXER2,
- WM8991_RRBRO_BIT, 1, 0),
- SOC_DAPM_SINGLE("ROMIX LIN3 Bypass Switch", WM8991_OUTPUT_MIXER2,
- WM8991_RLI3RO_BIT, 1, 0),
- SOC_DAPM_SINGLE("ROMIX RIN3 Bypass Switch", WM8991_OUTPUT_MIXER2,
- WM8991_RRI3RO_BIT, 1, 0),
- SOC_DAPM_SINGLE("ROMIX LIN12 PGA Bypass Switch", WM8991_OUTPUT_MIXER2,
- WM8991_RL12RO_BIT, 1, 0),
- SOC_DAPM_SINGLE("ROMIX RIN12 PGA Bypass Switch", WM8991_OUTPUT_MIXER2,
- WM8991_RR12RO_BIT, 1, 0),
- SOC_DAPM_SINGLE("ROMIX Right DAC Switch", WM8991_OUTPUT_MIXER2,
- WM8991_RDRO_BIT, 1, 0),
-};
-
-/* LONMIX */
-static const struct snd_kcontrol_new wm8991_dapm_lonmix_controls[] = {
- SOC_DAPM_SINGLE("LONMIX Left Mixer PGA Switch", WM8991_LINE_MIXER1,
- WM8991_LLOPGALON_BIT, 1, 0),
- SOC_DAPM_SINGLE("LONMIX Right Mixer PGA Switch", WM8991_LINE_MIXER1,
- WM8991_LROPGALON_BIT, 1, 0),
- SOC_DAPM_SINGLE("LONMIX Inverted LOP Switch", WM8991_LINE_MIXER1,
- WM8991_LOPLON_BIT, 1, 0),
-};
-
-/* LOPMIX */
-static const struct snd_kcontrol_new wm8991_dapm_lopmix_controls[] = {
- SOC_DAPM_SINGLE("LOPMIX Right Mic Bypass Switch", WM8991_LINE_MIXER1,
- WM8991_LR12LOP_BIT, 1, 0),
- SOC_DAPM_SINGLE("LOPMIX Left Mic Bypass Switch", WM8991_LINE_MIXER1,
- WM8991_LL12LOP_BIT, 1, 0),
- SOC_DAPM_SINGLE("LOPMIX Left Mixer PGA Switch", WM8991_LINE_MIXER1,
- WM8991_LLOPGALOP_BIT, 1, 0),
-};
-
-/* RONMIX */
-static const struct snd_kcontrol_new wm8991_dapm_ronmix_controls[] = {
- SOC_DAPM_SINGLE("RONMIX Right Mixer PGA Switch", WM8991_LINE_MIXER2,
- WM8991_RROPGARON_BIT, 1, 0),
- SOC_DAPM_SINGLE("RONMIX Left Mixer PGA Switch", WM8991_LINE_MIXER2,
- WM8991_RLOPGARON_BIT, 1, 0),
- SOC_DAPM_SINGLE("RONMIX Inverted ROP Switch", WM8991_LINE_MIXER2,
- WM8991_ROPRON_BIT, 1, 0),
-};
-
-/* ROPMIX */
-static const struct snd_kcontrol_new wm8991_dapm_ropmix_controls[] = {
- SOC_DAPM_SINGLE("ROPMIX Left Mic Bypass Switch", WM8991_LINE_MIXER2,
- WM8991_RL12ROP_BIT, 1, 0),
- SOC_DAPM_SINGLE("ROPMIX Right Mic Bypass Switch", WM8991_LINE_MIXER2,
- WM8991_RR12ROP_BIT, 1, 0),
- SOC_DAPM_SINGLE("ROPMIX Right Mixer PGA Switch", WM8991_LINE_MIXER2,
- WM8991_RROPGAROP_BIT, 1, 0),
-};
-
-/* OUT3MIX */
-static const struct snd_kcontrol_new wm8991_dapm_out3mix_controls[] = {
- SOC_DAPM_SINGLE("OUT3MIX LIN4RXN Bypass Switch", WM8991_OUT3_4_MIXER,
- WM8991_LI4O3_BIT, 1, 0),
- SOC_DAPM_SINGLE("OUT3MIX Left Out PGA Switch", WM8991_OUT3_4_MIXER,
- WM8991_LPGAO3_BIT, 1, 0),
-};
-
-/* OUT4MIX */
-static const struct snd_kcontrol_new wm8991_dapm_out4mix_controls[] = {
- SOC_DAPM_SINGLE("OUT4MIX Right Out PGA Switch", WM8991_OUT3_4_MIXER,
- WM8991_RPGAO4_BIT, 1, 0),
- SOC_DAPM_SINGLE("OUT4MIX RIN4RXP Bypass Switch", WM8991_OUT3_4_MIXER,
- WM8991_RI4O4_BIT, 1, 0),
-};
-
-/* SPKMIX */
-static const struct snd_kcontrol_new wm8991_dapm_spkmix_controls[] = {
- SOC_DAPM_SINGLE("SPKMIX LIN2 Bypass Switch", WM8991_SPEAKER_MIXER,
- WM8991_LI2SPK_BIT, 1, 0),
- SOC_DAPM_SINGLE("SPKMIX LADC Bypass Switch", WM8991_SPEAKER_MIXER,
- WM8991_LB2SPK_BIT, 1, 0),
- SOC_DAPM_SINGLE("SPKMIX Left Mixer PGA Switch", WM8991_SPEAKER_MIXER,
- WM8991_LOPGASPK_BIT, 1, 0),
- SOC_DAPM_SINGLE("SPKMIX Left DAC Switch", WM8991_SPEAKER_MIXER,
- WM8991_LDSPK_BIT, 1, 0),
- SOC_DAPM_SINGLE("SPKMIX Right DAC Switch", WM8991_SPEAKER_MIXER,
- WM8991_RDSPK_BIT, 1, 0),
- SOC_DAPM_SINGLE("SPKMIX Right Mixer PGA Switch", WM8991_SPEAKER_MIXER,
- WM8991_ROPGASPK_BIT, 1, 0),
- SOC_DAPM_SINGLE("SPKMIX RADC Bypass Switch", WM8991_SPEAKER_MIXER,
- WM8991_RL12ROP_BIT, 1, 0),
- SOC_DAPM_SINGLE("SPKMIX RIN2 Bypass Switch", WM8991_SPEAKER_MIXER,
- WM8991_RI2SPK_BIT, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget wm8991_dapm_widgets[] = {
- /* Input Side */
- /* Input Lines */
- SND_SOC_DAPM_INPUT("LIN1"),
- SND_SOC_DAPM_INPUT("LIN2"),
- SND_SOC_DAPM_INPUT("LIN3"),
- SND_SOC_DAPM_INPUT("LIN4RXN"),
- SND_SOC_DAPM_INPUT("RIN3"),
- SND_SOC_DAPM_INPUT("RIN4RXP"),
- SND_SOC_DAPM_INPUT("RIN1"),
- SND_SOC_DAPM_INPUT("RIN2"),
- SND_SOC_DAPM_INPUT("Internal ADC Source"),
-
- /* DACs */
- SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8991_POWER_MANAGEMENT_2,
- WM8991_ADCL_ENA_BIT, 0),
- SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8991_POWER_MANAGEMENT_2,
- WM8991_ADCR_ENA_BIT, 0),
-
- /* Input PGAs */
- SND_SOC_DAPM_MIXER("LIN12 PGA", WM8991_POWER_MANAGEMENT_2, WM8991_LIN12_ENA_BIT,
- 0, &wm8991_dapm_lin12_pga_controls[0],
- ARRAY_SIZE(wm8991_dapm_lin12_pga_controls)),
- SND_SOC_DAPM_MIXER("LIN34 PGA", WM8991_POWER_MANAGEMENT_2, WM8991_LIN34_ENA_BIT,
- 0, &wm8991_dapm_lin34_pga_controls[0],
- ARRAY_SIZE(wm8991_dapm_lin34_pga_controls)),
- SND_SOC_DAPM_MIXER("RIN12 PGA", WM8991_POWER_MANAGEMENT_2, WM8991_RIN12_ENA_BIT,
- 0, &wm8991_dapm_rin12_pga_controls[0],
- ARRAY_SIZE(wm8991_dapm_rin12_pga_controls)),
- SND_SOC_DAPM_MIXER("RIN34 PGA", WM8991_POWER_MANAGEMENT_2, WM8991_RIN34_ENA_BIT,
- 0, &wm8991_dapm_rin34_pga_controls[0],
- ARRAY_SIZE(wm8991_dapm_rin34_pga_controls)),
-
- /* INMIXL */
- SND_SOC_DAPM_MIXER_E("INMIXL", WM8991_INTDRIVBITS, WM8991_INMIXL_PWR_BIT, 0,
- &wm8991_dapm_inmixl_controls[0],
- ARRAY_SIZE(wm8991_dapm_inmixl_controls),
- inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- /* AINLMUX */
- SND_SOC_DAPM_MUX_E("AINLMUX", WM8991_INTDRIVBITS, WM8991_AINLMUX_PWR_BIT, 0,
- &wm8991_dapm_ainlmux_controls, inmixer_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- /* INMIXR */
- SND_SOC_DAPM_MIXER_E("INMIXR", WM8991_INTDRIVBITS, WM8991_INMIXR_PWR_BIT, 0,
- &wm8991_dapm_inmixr_controls[0],
- ARRAY_SIZE(wm8991_dapm_inmixr_controls),
- inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- /* AINRMUX */
- SND_SOC_DAPM_MUX_E("AINRMUX", WM8991_INTDRIVBITS, WM8991_AINRMUX_PWR_BIT, 0,
- &wm8991_dapm_ainrmux_controls, inmixer_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- /* Output Side */
- /* DACs */
- SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8991_POWER_MANAGEMENT_3,
- WM8991_DACL_ENA_BIT, 0),
- SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8991_POWER_MANAGEMENT_3,
- WM8991_DACR_ENA_BIT, 0),
-
- /* LOMIX */
- SND_SOC_DAPM_MIXER_E("LOMIX", WM8991_POWER_MANAGEMENT_3, WM8991_LOMIX_ENA_BIT,
- 0, &wm8991_dapm_lomix_controls[0],
- ARRAY_SIZE(wm8991_dapm_lomix_controls),
- outmixer_event, SND_SOC_DAPM_PRE_REG),
-
- /* LONMIX */
- SND_SOC_DAPM_MIXER("LONMIX", WM8991_POWER_MANAGEMENT_3, WM8991_LON_ENA_BIT, 0,
- &wm8991_dapm_lonmix_controls[0],
- ARRAY_SIZE(wm8991_dapm_lonmix_controls)),
-
- /* LOPMIX */
- SND_SOC_DAPM_MIXER("LOPMIX", WM8991_POWER_MANAGEMENT_3, WM8991_LOP_ENA_BIT, 0,
- &wm8991_dapm_lopmix_controls[0],
- ARRAY_SIZE(wm8991_dapm_lopmix_controls)),
-
- /* OUT3MIX */
- SND_SOC_DAPM_MIXER("OUT3MIX", WM8991_POWER_MANAGEMENT_1, WM8991_OUT3_ENA_BIT, 0,
- &wm8991_dapm_out3mix_controls[0],
- ARRAY_SIZE(wm8991_dapm_out3mix_controls)),
-
- /* SPKMIX */
- SND_SOC_DAPM_MIXER_E("SPKMIX", WM8991_POWER_MANAGEMENT_1, WM8991_SPK_ENA_BIT, 0,
- &wm8991_dapm_spkmix_controls[0],
- ARRAY_SIZE(wm8991_dapm_spkmix_controls), outmixer_event,
- SND_SOC_DAPM_PRE_REG),
-
- /* OUT4MIX */
- SND_SOC_DAPM_MIXER("OUT4MIX", WM8991_POWER_MANAGEMENT_1, WM8991_OUT4_ENA_BIT, 0,
- &wm8991_dapm_out4mix_controls[0],
- ARRAY_SIZE(wm8991_dapm_out4mix_controls)),
-
- /* ROPMIX */
- SND_SOC_DAPM_MIXER("ROPMIX", WM8991_POWER_MANAGEMENT_3, WM8991_ROP_ENA_BIT, 0,
- &wm8991_dapm_ropmix_controls[0],
- ARRAY_SIZE(wm8991_dapm_ropmix_controls)),
-
- /* RONMIX */
- SND_SOC_DAPM_MIXER("RONMIX", WM8991_POWER_MANAGEMENT_3, WM8991_RON_ENA_BIT, 0,
- &wm8991_dapm_ronmix_controls[0],
- ARRAY_SIZE(wm8991_dapm_ronmix_controls)),
-
- /* ROMIX */
- SND_SOC_DAPM_MIXER_E("ROMIX", WM8991_POWER_MANAGEMENT_3, WM8991_ROMIX_ENA_BIT,
- 0, &wm8991_dapm_romix_controls[0],
- ARRAY_SIZE(wm8991_dapm_romix_controls),
- outmixer_event, SND_SOC_DAPM_PRE_REG),
-
- /* LOUT PGA */
- SND_SOC_DAPM_PGA("LOUT PGA", WM8991_POWER_MANAGEMENT_1, WM8991_LOUT_ENA_BIT, 0,
- NULL, 0),
-
- /* ROUT PGA */
- SND_SOC_DAPM_PGA("ROUT PGA", WM8991_POWER_MANAGEMENT_1, WM8991_ROUT_ENA_BIT, 0,
- NULL, 0),
-
- /* LOPGA */
- SND_SOC_DAPM_PGA("LOPGA", WM8991_POWER_MANAGEMENT_3, WM8991_LOPGA_ENA_BIT, 0,
- NULL, 0),
-
- /* ROPGA */
- SND_SOC_DAPM_PGA("ROPGA", WM8991_POWER_MANAGEMENT_3, WM8991_ROPGA_ENA_BIT, 0,
- NULL, 0),
-
- /* MICBIAS */
- SND_SOC_DAPM_SUPPLY("MICBIAS", WM8991_POWER_MANAGEMENT_1,
- WM8991_MICBIAS_ENA_BIT, 0, NULL, 0),
-
- SND_SOC_DAPM_OUTPUT("LON"),
- SND_SOC_DAPM_OUTPUT("LOP"),
- SND_SOC_DAPM_OUTPUT("OUT3"),
- SND_SOC_DAPM_OUTPUT("LOUT"),
- SND_SOC_DAPM_OUTPUT("SPKN"),
- SND_SOC_DAPM_OUTPUT("SPKP"),
- SND_SOC_DAPM_OUTPUT("ROUT"),
- SND_SOC_DAPM_OUTPUT("OUT4"),
- SND_SOC_DAPM_OUTPUT("ROP"),
- SND_SOC_DAPM_OUTPUT("RON"),
- SND_SOC_DAPM_OUTPUT("OUT"),
-
- SND_SOC_DAPM_OUTPUT("Internal DAC Sink"),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- /* Make DACs turn on when playing even if not mixed into any outputs */
- {"Internal DAC Sink", NULL, "Left DAC"},
- {"Internal DAC Sink", NULL, "Right DAC"},
-
- /* Make ADCs turn on when recording even if not mixed from any inputs */
- {"Left ADC", NULL, "Internal ADC Source"},
- {"Right ADC", NULL, "Internal ADC Source"},
-
- /* Input Side */
- /* LIN12 PGA */
- {"LIN12 PGA", "LIN1 Switch", "LIN1"},
- {"LIN12 PGA", "LIN2 Switch", "LIN2"},
- /* LIN34 PGA */
- {"LIN34 PGA", "LIN3 Switch", "LIN3"},
- {"LIN34 PGA", "LIN4 Switch", "LIN4RXN"},
- /* INMIXL */
- {"INMIXL", "Record Left Volume", "LOMIX"},
- {"INMIXL", "LIN2 Volume", "LIN2"},
- {"INMIXL", "LINPGA12 Switch", "LIN12 PGA"},
- {"INMIXL", "LINPGA34 Switch", "LIN34 PGA"},
- /* AINLMUX */
- {"AINLMUX", "INMIXL Mix", "INMIXL"},
- {"AINLMUX", "DIFFINL Mix", "LIN12 PGA"},
- {"AINLMUX", "DIFFINL Mix", "LIN34 PGA"},
- {"AINLMUX", "RXVOICE Mix", "LIN4RXN"},
- {"AINLMUX", "RXVOICE Mix", "RIN4RXP"},
- /* ADC */
- {"Left ADC", NULL, "AINLMUX"},
-
- /* RIN12 PGA */
- {"RIN12 PGA", "RIN1 Switch", "RIN1"},
- {"RIN12 PGA", "RIN2 Switch", "RIN2"},
- /* RIN34 PGA */
- {"RIN34 PGA", "RIN3 Switch", "RIN3"},
- {"RIN34 PGA", "RIN4 Switch", "RIN4RXP"},
- /* INMIXL */
- {"INMIXR", "Record Right Volume", "ROMIX"},
- {"INMIXR", "RIN2 Volume", "RIN2"},
- {"INMIXR", "RINPGA12 Switch", "RIN12 PGA"},
- {"INMIXR", "RINPGA34 Switch", "RIN34 PGA"},
- /* AINRMUX */
- {"AINRMUX", "INMIXR Mix", "INMIXR"},
- {"AINRMUX", "DIFFINR Mix", "RIN12 PGA"},
- {"AINRMUX", "DIFFINR Mix", "RIN34 PGA"},
- {"AINRMUX", "RXVOICE Mix", "LIN4RXN"},
- {"AINRMUX", "RXVOICE Mix", "RIN4RXP"},
- /* ADC */
- {"Right ADC", NULL, "AINRMUX"},
-
- /* LOMIX */
- {"LOMIX", "LOMIX RIN3 Bypass Switch", "RIN3"},
- {"LOMIX", "LOMIX LIN3 Bypass Switch", "LIN3"},
- {"LOMIX", "LOMIX LIN12 PGA Bypass Switch", "LIN12 PGA"},
- {"LOMIX", "LOMIX RIN12 PGA Bypass Switch", "RIN12 PGA"},
- {"LOMIX", "LOMIX Right ADC Bypass Switch", "AINRMUX"},
- {"LOMIX", "LOMIX Left ADC Bypass Switch", "AINLMUX"},
- {"LOMIX", "LOMIX Left DAC Switch", "Left DAC"},
-
- /* ROMIX */
- {"ROMIX", "ROMIX RIN3 Bypass Switch", "RIN3"},
- {"ROMIX", "ROMIX LIN3 Bypass Switch", "LIN3"},
- {"ROMIX", "ROMIX LIN12 PGA Bypass Switch", "LIN12 PGA"},
- {"ROMIX", "ROMIX RIN12 PGA Bypass Switch", "RIN12 PGA"},
- {"ROMIX", "ROMIX Right ADC Bypass Switch", "AINRMUX"},
- {"ROMIX", "ROMIX Left ADC Bypass Switch", "AINLMUX"},
- {"ROMIX", "ROMIX Right DAC Switch", "Right DAC"},
-
- /* SPKMIX */
- {"SPKMIX", "SPKMIX LIN2 Bypass Switch", "LIN2"},
- {"SPKMIX", "SPKMIX RIN2 Bypass Switch", "RIN2"},
- {"SPKMIX", "SPKMIX LADC Bypass Switch", "AINLMUX"},
- {"SPKMIX", "SPKMIX RADC Bypass Switch", "AINRMUX"},
- {"SPKMIX", "SPKMIX Left Mixer PGA Switch", "LOPGA"},
- {"SPKMIX", "SPKMIX Right Mixer PGA Switch", "ROPGA"},
- {"SPKMIX", "SPKMIX Right DAC Switch", "Right DAC"},
- {"SPKMIX", "SPKMIX Left DAC Switch", "Right DAC"},
-
- /* LONMIX */
- {"LONMIX", "LONMIX Left Mixer PGA Switch", "LOPGA"},
- {"LONMIX", "LONMIX Right Mixer PGA Switch", "ROPGA"},
- {"LONMIX", "LONMIX Inverted LOP Switch", "LOPMIX"},
-
- /* LOPMIX */
- {"LOPMIX", "LOPMIX Right Mic Bypass Switch", "RIN12 PGA"},
- {"LOPMIX", "LOPMIX Left Mic Bypass Switch", "LIN12 PGA"},
- {"LOPMIX", "LOPMIX Left Mixer PGA Switch", "LOPGA"},
-
- /* OUT3MIX */
- {"OUT3MIX", "OUT3MIX LIN4RXN Bypass Switch", "LIN4RXN"},
- {"OUT3MIX", "OUT3MIX Left Out PGA Switch", "LOPGA"},
-
- /* OUT4MIX */
- {"OUT4MIX", "OUT4MIX Right Out PGA Switch", "ROPGA"},
- {"OUT4MIX", "OUT4MIX RIN4RXP Bypass Switch", "RIN4RXP"},
-
- /* RONMIX */
- {"RONMIX", "RONMIX Right Mixer PGA Switch", "ROPGA"},
- {"RONMIX", "RONMIX Left Mixer PGA Switch", "LOPGA"},
- {"RONMIX", "RONMIX Inverted ROP Switch", "ROPMIX"},
-
- /* ROPMIX */
- {"ROPMIX", "ROPMIX Left Mic Bypass Switch", "LIN12 PGA"},
- {"ROPMIX", "ROPMIX Right Mic Bypass Switch", "RIN12 PGA"},
- {"ROPMIX", "ROPMIX Right Mixer PGA Switch", "ROPGA"},
-
- /* Out Mixer PGAs */
- {"LOPGA", NULL, "LOMIX"},
- {"ROPGA", NULL, "ROMIX"},
-
- {"LOUT PGA", NULL, "LOMIX"},
- {"ROUT PGA", NULL, "ROMIX"},
-
- /* Output Pins */
- {"LON", NULL, "LONMIX"},
- {"LOP", NULL, "LOPMIX"},
- {"OUT", NULL, "OUT3MIX"},
- {"LOUT", NULL, "LOUT PGA"},
- {"SPKN", NULL, "SPKMIX"},
- {"ROUT", NULL, "ROUT PGA"},
- {"OUT4", NULL, "OUT4MIX"},
- {"ROP", NULL, "ROPMIX"},
- {"RON", NULL, "RONMIX"},
-};
-
-/* PLL divisors */
-struct _pll_div {
- u32 div2;
- u32 n;
- u32 k;
-};
-
-/* The size in bits of the pll divide multiplied by 10
- * to allow rounding later */
-#define FIXED_PLL_SIZE ((1 << 16) * 10)
-
-static void pll_factors(struct _pll_div *pll_div, unsigned int target,
- unsigned int source)
-{
- u64 Kpart;
- unsigned int K, Ndiv, Nmod;
-
-
- Ndiv = target / source;
- if (Ndiv < 6) {
- source >>= 1;
- pll_div->div2 = 1;
- Ndiv = target / source;
- } else
- pll_div->div2 = 0;
-
- if ((Ndiv < 6) || (Ndiv > 12))
- printk(KERN_WARNING
- "WM8991 N value outwith recommended range! N = %d\n", Ndiv);
-
- pll_div->n = Ndiv;
- Nmod = target % source;
- Kpart = FIXED_PLL_SIZE * (long long)Nmod;
-
- do_div(Kpart, source);
-
- K = Kpart & 0xFFFFFFFF;
-
- /* Check if we need to round */
- if ((K % 10) >= 5)
- K += 5;
-
- /* Move down to proper range now rounding is done */
- K /= 10;
-
- pll_div->k = K;
-}
-
-static int wm8991_set_dai_pll(struct snd_soc_dai *codec_dai,
- int pll_id, int src, unsigned int freq_in, unsigned int freq_out)
-{
- u16 reg;
- struct snd_soc_codec *codec = codec_dai->codec;
- struct _pll_div pll_div;
-
- if (freq_in && freq_out) {
- pll_factors(&pll_div, freq_out * 4, freq_in);
-
- /* Turn on PLL */
- reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_2);
- reg |= WM8991_PLL_ENA;
- snd_soc_write(codec, WM8991_POWER_MANAGEMENT_2, reg);
-
- /* sysclk comes from PLL */
- reg = snd_soc_read(codec, WM8991_CLOCKING_2);
- snd_soc_write(codec, WM8991_CLOCKING_2, reg | WM8991_SYSCLK_SRC);
-
- /* set up N , fractional mode and pre-divisor if necessary */
- snd_soc_write(codec, WM8991_PLL1, pll_div.n | WM8991_SDM |
- (pll_div.div2 ? WM8991_PRESCALE : 0));
- snd_soc_write(codec, WM8991_PLL2, (u8)(pll_div.k>>8));
- snd_soc_write(codec, WM8991_PLL3, (u8)(pll_div.k & 0xFF));
- } else {
- /* Turn on PLL */
- reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_2);
- reg &= ~WM8991_PLL_ENA;
- snd_soc_write(codec, WM8991_POWER_MANAGEMENT_2, reg);
- }
- return 0;
-}
-
-/*
- * Set's ADC and Voice DAC format.
- */
-static int wm8991_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 audio1, audio3;
-
- audio1 = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_1);
- audio3 = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_3);
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- audio3 &= ~WM8991_AIF_MSTR1;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- audio3 |= WM8991_AIF_MSTR1;
- break;
- default:
- return -EINVAL;
- }
-
- audio1 &= ~WM8991_AIF_FMT_MASK;
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- audio1 |= WM8991_AIF_TMF_I2S;
- audio1 &= ~WM8991_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- audio1 |= WM8991_AIF_TMF_RIGHTJ;
- audio1 &= ~WM8991_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- audio1 |= WM8991_AIF_TMF_LEFTJ;
- audio1 &= ~WM8991_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- audio1 |= WM8991_AIF_TMF_DSP;
- audio1 &= ~WM8991_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- audio1 |= WM8991_AIF_TMF_DSP | WM8991_AIF_LRCLK_INV;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM8991_AUDIO_INTERFACE_1, audio1);
- snd_soc_write(codec, WM8991_AUDIO_INTERFACE_3, audio3);
- return 0;
-}
-
-static int wm8991_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
- int div_id, int div)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 reg;
-
- switch (div_id) {
- case WM8991_MCLK_DIV:
- reg = snd_soc_read(codec, WM8991_CLOCKING_2) &
- ~WM8991_MCLK_DIV_MASK;
- snd_soc_write(codec, WM8991_CLOCKING_2, reg | div);
- break;
- case WM8991_DACCLK_DIV:
- reg = snd_soc_read(codec, WM8991_CLOCKING_2) &
- ~WM8991_DAC_CLKDIV_MASK;
- snd_soc_write(codec, WM8991_CLOCKING_2, reg | div);
- break;
- case WM8991_ADCCLK_DIV:
- reg = snd_soc_read(codec, WM8991_CLOCKING_2) &
- ~WM8991_ADC_CLKDIV_MASK;
- snd_soc_write(codec, WM8991_CLOCKING_2, reg | div);
- break;
- case WM8991_BCLK_DIV:
- reg = snd_soc_read(codec, WM8991_CLOCKING_1) &
- ~WM8991_BCLK_DIV_MASK;
- snd_soc_write(codec, WM8991_CLOCKING_1, reg | div);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * Set PCM DAI bit size and sample rate.
- */
-static int wm8991_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 audio1 = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_1);
-
- audio1 &= ~WM8991_AIF_WL_MASK;
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- audio1 |= WM8991_AIF_WL_20BITS;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- audio1 |= WM8991_AIF_WL_24BITS;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- audio1 |= WM8991_AIF_WL_32BITS;
- break;
- }
-
- snd_soc_write(codec, WM8991_AUDIO_INTERFACE_1, audio1);
- return 0;
-}
-
-static int wm8991_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 val;
-
- val = snd_soc_read(codec, WM8991_DAC_CTRL) & ~WM8991_DAC_MUTE;
- if (mute)
- snd_soc_write(codec, WM8991_DAC_CTRL, val | WM8991_DAC_MUTE);
- else
- snd_soc_write(codec, WM8991_DAC_CTRL, val);
- return 0;
-}
-
-static int wm8991_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- u16 val;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- /* VMID=2*50k */
- val = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_1) &
- ~WM8991_VMID_MODE_MASK;
- snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, val | 0x2);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- snd_soc_cache_sync(codec);
- /* Enable all output discharge bits */
- snd_soc_write(codec, WM8991_ANTIPOP1, WM8991_DIS_LLINE |
- WM8991_DIS_RLINE | WM8991_DIS_OUT3 |
- WM8991_DIS_OUT4 | WM8991_DIS_LOUT |
- WM8991_DIS_ROUT);
-
- /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */
- snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
- WM8991_BUFDCOPEN | WM8991_POBCTRL |
- WM8991_VMIDTOG);
-
- /* Delay to allow output caps to discharge */
- msleep(300);
-
- /* Disable VMIDTOG */
- snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
- WM8991_BUFDCOPEN | WM8991_POBCTRL);
-
- /* disable all output discharge bits */
- snd_soc_write(codec, WM8991_ANTIPOP1, 0);
-
- /* Enable outputs */
- snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1b00);
-
- msleep(50);
-
- /* Enable VMID at 2x50k */
- snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1f02);
-
- msleep(100);
-
- /* Enable VREF */
- snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1f03);
-
- msleep(600);
-
- /* Enable BUFIOEN */
- snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
- WM8991_BUFDCOPEN | WM8991_POBCTRL |
- WM8991_BUFIOEN);
-
- /* Disable outputs */
- snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x3);
-
- /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
- snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_BUFIOEN);
- }
-
- /* VMID=2*250k */
- val = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_1) &
- ~WM8991_VMID_MODE_MASK;
- snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, val | 0x4);
- break;
-
- case SND_SOC_BIAS_OFF:
- /* Enable POBCTRL and SOFT_ST */
- snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
- WM8991_POBCTRL | WM8991_BUFIOEN);
-
- /* Enable POBCTRL, SOFT_ST and BUFDCOPEN */
- snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
- WM8991_BUFDCOPEN | WM8991_POBCTRL |
- WM8991_BUFIOEN);
-
- /* mute DAC */
- val = snd_soc_read(codec, WM8991_DAC_CTRL);
- snd_soc_write(codec, WM8991_DAC_CTRL, val | WM8991_DAC_MUTE);
-
- /* Enable any disabled outputs */
- snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1f03);
-
- /* Disable VMID */
- snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1f01);
-
- msleep(300);
-
- /* Enable all output discharge bits */
- snd_soc_write(codec, WM8991_ANTIPOP1, WM8991_DIS_LLINE |
- WM8991_DIS_RLINE | WM8991_DIS_OUT3 |
- WM8991_DIS_OUT4 | WM8991_DIS_LOUT |
- WM8991_DIS_ROUT);
-
- /* Disable VREF */
- snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x0);
-
- /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
- snd_soc_write(codec, WM8991_ANTIPOP2, 0x0);
- codec->cache_sync = 1;
- break;
- }
-
- codec->dapm.bias_level = level;
- return 0;
-}
-
-static int wm8991_suspend(struct snd_soc_codec *codec)
-{
- wm8991_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm8991_resume(struct snd_soc_codec *codec)
-{
- wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-
-/* power down chip */
-static int wm8991_remove(struct snd_soc_codec *codec)
-{
- wm8991_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm8991_probe(struct snd_soc_codec *codec)
-{
- struct wm8991_priv *wm8991;
- int ret;
-
- wm8991 = snd_soc_codec_get_drvdata(codec);
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8991->control_type);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
- return ret;
- }
-
- ret = wm8991_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- return ret;
- }
-
- wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- snd_soc_update_bits(codec, WM8991_AUDIO_INTERFACE_4,
- WM8991_ALRCGPIO1, WM8991_ALRCGPIO1);
-
- snd_soc_update_bits(codec, WM8991_GPIO1_GPIO2,
- WM8991_GPIO1_SEL_MASK, 1);
-
- snd_soc_update_bits(codec, WM8991_POWER_MANAGEMENT_1,
- WM8991_VREF_ENA | WM8991_VMID_MODE_MASK,
- WM8991_VREF_ENA | WM8991_VMID_MODE_MASK);
-
- snd_soc_update_bits(codec, WM8991_POWER_MANAGEMENT_2,
- WM8991_OPCLK_ENA, WM8991_OPCLK_ENA);
-
- snd_soc_write(codec, WM8991_DAC_CTRL, 0);
- snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
- snd_soc_write(codec, WM8991_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
-
- snd_soc_add_codec_controls(codec, wm8991_snd_controls,
- ARRAY_SIZE(wm8991_snd_controls));
-
- snd_soc_dapm_new_controls(&codec->dapm, wm8991_dapm_widgets,
- ARRAY_SIZE(wm8991_dapm_widgets));
- snd_soc_dapm_add_routes(&codec->dapm, audio_map,
- ARRAY_SIZE(audio_map));
- return 0;
-}
-
-#define WM8991_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops wm8991_ops = {
- .hw_params = wm8991_hw_params,
- .digital_mute = wm8991_mute,
- .set_fmt = wm8991_set_dai_fmt,
- .set_clkdiv = wm8991_set_dai_clkdiv,
- .set_pll = wm8991_set_dai_pll
-};
-
-/*
- * The WM8991 supports 2 different and mutually exclusive DAI
- * configurations.
- *
- * 1. ADC/DAC on Primary Interface
- * 2. ADC on Primary Interface/DAC on secondary
- */
-static struct snd_soc_dai_driver wm8991_dai = {
- /* ADC/DAC on primary */
- .name = "wm8991",
- .id = 1,
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = WM8991_FORMATS
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = WM8991_FORMATS
- },
- .ops = &wm8991_ops
-};
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8991 = {
- .probe = wm8991_probe,
- .remove = wm8991_remove,
- .suspend = wm8991_suspend,
- .resume = wm8991_resume,
- .set_bias_level = wm8991_set_bias_level,
- .reg_cache_size = WM8991_MAX_REGISTER + 1,
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8991_reg_defs
-};
-
-static __devinit int wm8991_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8991_priv *wm8991;
- int ret;
-
- wm8991 = kzalloc(sizeof *wm8991, GFP_KERNEL);
- if (!wm8991)
- return -ENOMEM;
-
- wm8991->control_type = SND_SOC_I2C;
- i2c_set_clientdata(i2c, wm8991);
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8991, &wm8991_dai, 1);
- if (ret < 0)
- kfree(wm8991);
- return ret;
-}
-
-static __devexit int wm8991_i2c_remove(struct i2c_client *client)
-{
- snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-static const struct i2c_device_id wm8991_i2c_id[] = {
- { "wm8991", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8991_i2c_id);
-
-static struct i2c_driver wm8991_i2c_driver = {
- .driver = {
- .name = "wm8991",
- .owner = THIS_MODULE,
- },
- .probe = wm8991_i2c_probe,
- .remove = __devexit_p(wm8991_i2c_remove),
- .id_table = wm8991_i2c_id,
-};
-
-static int __init wm8991_modinit(void)
-{
- int ret;
- ret = i2c_add_driver(&wm8991_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8991 I2C driver: %d\n",
- ret);
- }
- return 0;
-}
-module_init(wm8991_modinit);
-
-static void __exit wm8991_exit(void)
-{
- i2c_del_driver(&wm8991_i2c_driver);
-}
-module_exit(wm8991_exit);
-
-MODULE_DESCRIPTION("ASoC WM8991 driver");
-MODULE_AUTHOR("Graeme Gregory");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8991.h b/ANDROID_3.4.5/sound/soc/codecs/wm8991.h
deleted file mode 100644
index 8a942efd..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8991.h
+++ /dev/null
@@ -1,833 +0,0 @@
-/*
- * wm8991.h -- audio driver for WM8991
- *
- * Copyright 2007 Wolfson Microelectronics PLC.
- * Author: Graeme Gregory
- * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#ifndef _WM8991_H
-#define _WM8991_H
-
-/*
- * Register values.
- */
-#define WM8991_RESET 0x00
-#define WM8991_POWER_MANAGEMENT_1 0x01
-#define WM8991_POWER_MANAGEMENT_2 0x02
-#define WM8991_POWER_MANAGEMENT_3 0x03
-#define WM8991_AUDIO_INTERFACE_1 0x04
-#define WM8991_AUDIO_INTERFACE_2 0x05
-#define WM8991_CLOCKING_1 0x06
-#define WM8991_CLOCKING_2 0x07
-#define WM8991_AUDIO_INTERFACE_3 0x08
-#define WM8991_AUDIO_INTERFACE_4 0x09
-#define WM8991_DAC_CTRL 0x0A
-#define WM8991_LEFT_DAC_DIGITAL_VOLUME 0x0B
-#define WM8991_RIGHT_DAC_DIGITAL_VOLUME 0x0C
-#define WM8991_DIGITAL_SIDE_TONE 0x0D
-#define WM8991_ADC_CTRL 0x0E
-#define WM8991_LEFT_ADC_DIGITAL_VOLUME 0x0F
-#define WM8991_RIGHT_ADC_DIGITAL_VOLUME 0x10
-#define WM8991_GPIO_CTRL_1 0x12
-#define WM8991_GPIO1_GPIO2 0x13
-#define WM8991_GPIO3_GPIO4 0x14
-#define WM8991_GPIO5_GPIO6 0x15
-#define WM8991_GPIOCTRL_2 0x16
-#define WM8991_GPIO_POL 0x17
-#define WM8991_LEFT_LINE_INPUT_1_2_VOLUME 0x18
-#define WM8991_LEFT_LINE_INPUT_3_4_VOLUME 0x19
-#define WM8991_RIGHT_LINE_INPUT_1_2_VOLUME 0x1A
-#define WM8991_RIGHT_LINE_INPUT_3_4_VOLUME 0x1B
-#define WM8991_LEFT_OUTPUT_VOLUME 0x1C
-#define WM8991_RIGHT_OUTPUT_VOLUME 0x1D
-#define WM8991_LINE_OUTPUTS_VOLUME 0x1E
-#define WM8991_OUT3_4_VOLUME 0x1F
-#define WM8991_LEFT_OPGA_VOLUME 0x20
-#define WM8991_RIGHT_OPGA_VOLUME 0x21
-#define WM8991_SPEAKER_VOLUME 0x22
-#define WM8991_CLASSD1 0x23
-#define WM8991_CLASSD3 0x25
-#define WM8991_INPUT_MIXER1 0x27
-#define WM8991_INPUT_MIXER2 0x28
-#define WM8991_INPUT_MIXER3 0x29
-#define WM8991_INPUT_MIXER4 0x2A
-#define WM8991_INPUT_MIXER5 0x2B
-#define WM8991_INPUT_MIXER6 0x2C
-#define WM8991_OUTPUT_MIXER1 0x2D
-#define WM8991_OUTPUT_MIXER2 0x2E
-#define WM8991_OUTPUT_MIXER3 0x2F
-#define WM8991_OUTPUT_MIXER4 0x30
-#define WM8991_OUTPUT_MIXER5 0x31
-#define WM8991_OUTPUT_MIXER6 0x32
-#define WM8991_OUT3_4_MIXER 0x33
-#define WM8991_LINE_MIXER1 0x34
-#define WM8991_LINE_MIXER2 0x35
-#define WM8991_SPEAKER_MIXER 0x36
-#define WM8991_ADDITIONAL_CONTROL 0x37
-#define WM8991_ANTIPOP1 0x38
-#define WM8991_ANTIPOP2 0x39
-#define WM8991_MICBIAS 0x3A
-#define WM8991_PLL1 0x3C
-#define WM8991_PLL2 0x3D
-#define WM8991_PLL3 0x3E
-#define WM8991_INTDRIVBITS 0x3F
-
-#define WM8991_REGISTER_COUNT 60
-#define WM8991_MAX_REGISTER 0x3F
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - Reset
- */
-#define WM8991_SW_RESET_CHIP_ID_MASK 0xFFFF /* SW_RESET_CHIP_ID - [15:0] */
-
-/*
- * R1 (0x01) - Power Management (1)
- */
-#define WM8991_SPK_ENA 0x1000 /* SPK_ENA */
-#define WM8991_SPK_ENA_BIT 12
-#define WM8991_OUT3_ENA 0x0800 /* OUT3_ENA */
-#define WM8991_OUT3_ENA_BIT 11
-#define WM8991_OUT4_ENA 0x0400 /* OUT4_ENA */
-#define WM8991_OUT4_ENA_BIT 10
-#define WM8991_LOUT_ENA 0x0200 /* LOUT_ENA */
-#define WM8991_LOUT_ENA_BIT 9
-#define WM8991_ROUT_ENA 0x0100 /* ROUT_ENA */
-#define WM8991_ROUT_ENA_BIT 8
-#define WM8991_MICBIAS_ENA 0x0010 /* MICBIAS_ENA */
-#define WM8991_MICBIAS_ENA_BIT 4
-#define WM8991_VMID_MODE_MASK 0x0006 /* VMID_MODE - [2:1] */
-#define WM8991_VREF_ENA 0x0001 /* VREF_ENA */
-#define WM8991_VREF_ENA_BIT 0
-
-/*
- * R2 (0x02) - Power Management (2)
- */
-#define WM8991_PLL_ENA 0x8000 /* PLL_ENA */
-#define WM8991_PLL_ENA_BIT 15
-#define WM8991_TSHUT_ENA 0x4000 /* TSHUT_ENA */
-#define WM8991_TSHUT_ENA_BIT 14
-#define WM8991_TSHUT_OPDIS 0x2000 /* TSHUT_OPDIS */
-#define WM8991_TSHUT_OPDIS_BIT 13
-#define WM8991_OPCLK_ENA 0x0800 /* OPCLK_ENA */
-#define WM8991_OPCLK_ENA_BIT 11
-#define WM8991_AINL_ENA 0x0200 /* AINL_ENA */
-#define WM8991_AINL_ENA_BIT 9
-#define WM8991_AINR_ENA 0x0100 /* AINR_ENA */
-#define WM8991_AINR_ENA_BIT 8
-#define WM8991_LIN34_ENA 0x0080 /* LIN34_ENA */
-#define WM8991_LIN34_ENA_BIT 7
-#define WM8991_LIN12_ENA 0x0040 /* LIN12_ENA */
-#define WM8991_LIN12_ENA_BIT 6
-#define WM8991_RIN34_ENA 0x0020 /* RIN34_ENA */
-#define WM8991_RIN34_ENA_BIT 5
-#define WM8991_RIN12_ENA 0x0010 /* RIN12_ENA */
-#define WM8991_RIN12_ENA_BIT 4
-#define WM8991_ADCL_ENA 0x0002 /* ADCL_ENA */
-#define WM8991_ADCL_ENA_BIT 1
-#define WM8991_ADCR_ENA 0x0001 /* ADCR_ENA */
-#define WM8991_ADCR_ENA_BIT 0
-
-/*
- * R3 (0x03) - Power Management (3)
- */
-#define WM8991_LON_ENA 0x2000 /* LON_ENA */
-#define WM8991_LON_ENA_BIT 13
-#define WM8991_LOP_ENA 0x1000 /* LOP_ENA */
-#define WM8991_LOP_ENA_BIT 12
-#define WM8991_RON_ENA 0x0800 /* RON_ENA */
-#define WM8991_RON_ENA_BIT 11
-#define WM8991_ROP_ENA 0x0400 /* ROP_ENA */
-#define WM8991_ROP_ENA_BIT 10
-#define WM8991_LOPGA_ENA 0x0080 /* LOPGA_ENA */
-#define WM8991_LOPGA_ENA_BIT 7
-#define WM8991_ROPGA_ENA 0x0040 /* ROPGA_ENA */
-#define WM8991_ROPGA_ENA_BIT 6
-#define WM8991_LOMIX_ENA 0x0020 /* LOMIX_ENA */
-#define WM8991_LOMIX_ENA_BIT 5
-#define WM8991_ROMIX_ENA 0x0010 /* ROMIX_ENA */
-#define WM8991_ROMIX_ENA_BIT 4
-#define WM8991_DACL_ENA 0x0002 /* DACL_ENA */
-#define WM8991_DACL_ENA_BIT 1
-#define WM8991_DACR_ENA 0x0001 /* DACR_ENA */
-#define WM8991_DACR_ENA_BIT 0
-
-/*
- * R4 (0x04) - Audio Interface (1)
- */
-#define WM8991_AIFADCL_SRC 0x8000 /* AIFADCL_SRC */
-#define WM8991_AIFADCR_SRC 0x4000 /* AIFADCR_SRC */
-#define WM8991_AIFADC_TDM 0x2000 /* AIFADC_TDM */
-#define WM8991_AIFADC_TDM_CHAN 0x1000 /* AIFADC_TDM_CHAN */
-#define WM8991_AIF_BCLK_INV 0x0100 /* AIF_BCLK_INV */
-#define WM8991_AIF_LRCLK_INV 0x0080 /* AIF_LRCLK_INV */
-#define WM8991_AIF_WL_MASK 0x0060 /* AIF_WL - [6:5] */
-#define WM8991_AIF_WL_16BITS (0 << 5)
-#define WM8991_AIF_WL_20BITS (1 << 5)
-#define WM8991_AIF_WL_24BITS (2 << 5)
-#define WM8991_AIF_WL_32BITS (3 << 5)
-#define WM8991_AIF_FMT_MASK 0x0018 /* AIF_FMT - [4:3] */
-#define WM8991_AIF_TMF_RIGHTJ (0 << 3)
-#define WM8991_AIF_TMF_LEFTJ (1 << 3)
-#define WM8991_AIF_TMF_I2S (2 << 3)
-#define WM8991_AIF_TMF_DSP (3 << 3)
-
-/*
- * R5 (0x05) - Audio Interface (2)
- */
-#define WM8991_DACL_SRC 0x8000 /* DACL_SRC */
-#define WM8991_DACR_SRC 0x4000 /* DACR_SRC */
-#define WM8991_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */
-#define WM8991_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */
-#define WM8991_DAC_BOOST_MASK 0x0C00 /* DAC_BOOST - [11:10] */
-#define WM8991_DAC_COMP 0x0010 /* DAC_COMP */
-#define WM8991_DAC_COMPMODE 0x0008 /* DAC_COMPMODE */
-#define WM8991_ADC_COMP 0x0004 /* ADC_COMP */
-#define WM8991_ADC_COMPMODE 0x0002 /* ADC_COMPMODE */
-#define WM8991_LOOPBACK 0x0001 /* LOOPBACK */
-
-/*
- * R6 (0x06) - Clocking (1)
- */
-#define WM8991_TOCLK_RATE 0x8000 /* TOCLK_RATE */
-#define WM8991_TOCLK_ENA 0x4000 /* TOCLK_ENA */
-#define WM8991_OPCLKDIV_MASK 0x1E00 /* OPCLKDIV - [12:9] */
-#define WM8991_DCLKDIV_MASK 0x01C0 /* DCLKDIV - [8:6] */
-#define WM8991_BCLK_DIV_MASK 0x001E /* BCLK_DIV - [4:1] */
-#define WM8991_BCLK_DIV_1 (0x0 << 1)
-#define WM8991_BCLK_DIV_1_5 (0x1 << 1)
-#define WM8991_BCLK_DIV_2 (0x2 << 1)
-#define WM8991_BCLK_DIV_3 (0x3 << 1)
-#define WM8991_BCLK_DIV_4 (0x4 << 1)
-#define WM8991_BCLK_DIV_5_5 (0x5 << 1)
-#define WM8991_BCLK_DIV_6 (0x6 << 1)
-#define WM8991_BCLK_DIV_8 (0x7 << 1)
-#define WM8991_BCLK_DIV_11 (0x8 << 1)
-#define WM8991_BCLK_DIV_12 (0x9 << 1)
-#define WM8991_BCLK_DIV_16 (0xA << 1)
-#define WM8991_BCLK_DIV_22 (0xB << 1)
-#define WM8991_BCLK_DIV_24 (0xC << 1)
-#define WM8991_BCLK_DIV_32 (0xD << 1)
-#define WM8991_BCLK_DIV_44 (0xE << 1)
-#define WM8991_BCLK_DIV_48 (0xF << 1)
-
-/*
- * R7 (0x07) - Clocking (2)
- */
-#define WM8991_MCLK_SRC 0x8000 /* MCLK_SRC */
-#define WM8991_SYSCLK_SRC 0x4000 /* SYSCLK_SRC */
-#define WM8991_CLK_FORCE 0x2000 /* CLK_FORCE */
-#define WM8991_MCLK_DIV_MASK 0x1800 /* MCLK_DIV - [12:11] */
-#define WM8991_MCLK_DIV_1 (0 << 11)
-#define WM8991_MCLK_DIV_2 ( 2 << 11)
-#define WM8991_MCLK_INV 0x0400 /* MCLK_INV */
-#define WM8991_ADC_CLKDIV_MASK 0x00E0 /* ADC_CLKDIV - [7:5] */
-#define WM8991_ADC_CLKDIV_1 (0 << 5)
-#define WM8991_ADC_CLKDIV_1_5 (1 << 5)
-#define WM8991_ADC_CLKDIV_2 (2 << 5)
-#define WM8991_ADC_CLKDIV_3 (3 << 5)
-#define WM8991_ADC_CLKDIV_4 (4 << 5)
-#define WM8991_ADC_CLKDIV_5_5 (5 << 5)
-#define WM8991_ADC_CLKDIV_6 (6 << 5)
-#define WM8991_DAC_CLKDIV_MASK 0x001C /* DAC_CLKDIV - [4:2] */
-#define WM8991_DAC_CLKDIV_1 (0 << 2)
-#define WM8991_DAC_CLKDIV_1_5 (1 << 2)
-#define WM8991_DAC_CLKDIV_2 (2 << 2)
-#define WM8991_DAC_CLKDIV_3 (3 << 2)
-#define WM8991_DAC_CLKDIV_4 (4 << 2)
-#define WM8991_DAC_CLKDIV_5_5 (5 << 2)
-#define WM8991_DAC_CLKDIV_6 (6 << 2)
-
-/*
- * R8 (0x08) - Audio Interface (3)
- */
-#define WM8991_AIF_MSTR1 0x8000 /* AIF_MSTR1 */
-#define WM8991_AIF_MSTR2 0x4000 /* AIF_MSTR2 */
-#define WM8991_AIF_SEL 0x2000 /* AIF_SEL */
-#define WM8991_ADCLRC_DIR 0x0800 /* ADCLRC_DIR */
-#define WM8991_ADCLRC_RATE_MASK 0x07FF /* ADCLRC_RATE - [10:0] */
-
-/*
- * R9 (0x09) - Audio Interface (4)
- */
-#define WM8991_ALRCGPIO1 0x8000 /* ALRCGPIO1 */
-#define WM8991_ALRCBGPIO6 0x4000 /* ALRCBGPIO6 */
-#define WM8991_AIF_TRIS 0x2000 /* AIF_TRIS */
-#define WM8991_DACLRC_DIR 0x0800 /* DACLRC_DIR */
-#define WM8991_DACLRC_RATE_MASK 0x07FF /* DACLRC_RATE - [10:0] */
-
-/*
- * R10 (0x0A) - DAC CTRL
- */
-#define WM8991_AIF_LRCLKRATE 0x0400 /* AIF_LRCLKRATE */
-#define WM8991_DAC_MONO 0x0200 /* DAC_MONO */
-#define WM8991_DAC_SB_FILT 0x0100 /* DAC_SB_FILT */
-#define WM8991_DAC_MUTERATE 0x0080 /* DAC_MUTERATE */
-#define WM8991_DAC_MUTEMODE 0x0040 /* DAC_MUTEMODE */
-#define WM8991_DEEMP_MASK 0x0030 /* DEEMP - [5:4] */
-#define WM8991_DAC_MUTE 0x0004 /* DAC_MUTE */
-#define WM8991_DACL_DATINV 0x0002 /* DACL_DATINV */
-#define WM8991_DACR_DATINV 0x0001 /* DACR_DATINV */
-
-/*
- * R11 (0x0B) - Left DAC Digital Volume
- */
-#define WM8991_DAC_VU 0x0100 /* DAC_VU */
-#define WM8991_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
-#define WM8991_DACL_VOL_SHIFT 0
-/*
- * R12 (0x0C) - Right DAC Digital Volume
- */
-#define WM8991_DAC_VU 0x0100 /* DAC_VU */
-#define WM8991_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
-#define WM8991_DACR_VOL_SHIFT 0
-/*
- * R13 (0x0D) - Digital Side Tone
- */
-#define WM8991_ADCL_DAC_SVOL_MASK 0x0F /* ADCL_DAC_SVOL - [12:9] */
-#define WM8991_ADCL_DAC_SVOL_SHIFT 9
-#define WM8991_ADCR_DAC_SVOL_MASK 0x0F /* ADCR_DAC_SVOL - [8:5] */
-#define WM8991_ADCR_DAC_SVOL_SHIFT 5
-#define WM8991_ADC_TO_DACL_MASK 0x03 /* ADC_TO_DACL - [3:2] */
-#define WM8991_ADC_TO_DACL_SHIFT 2
-#define WM8991_ADC_TO_DACR_MASK 0x03 /* ADC_TO_DACR - [1:0] */
-#define WM8991_ADC_TO_DACR_SHIFT 0
-
-/*
- * R14 (0x0E) - ADC CTRL
- */
-#define WM8991_ADC_HPF_ENA 0x0100 /* ADC_HPF_ENA */
-#define WM8991_ADC_HPF_ENA_BIT 8
-#define WM8991_ADC_HPF_CUT_MASK 0x03 /* ADC_HPF_CUT - [6:5] */
-#define WM8991_ADC_HPF_CUT_SHIFT 5
-#define WM8991_ADCL_DATINV 0x0002 /* ADCL_DATINV */
-#define WM8991_ADCL_DATINV_BIT 1
-#define WM8991_ADCR_DATINV 0x0001 /* ADCR_DATINV */
-#define WM8991_ADCR_DATINV_BIT 0
-
-/*
- * R15 (0x0F) - Left ADC Digital Volume
- */
-#define WM8991_ADC_VU 0x0100 /* ADC_VU */
-#define WM8991_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
-#define WM8991_ADCL_VOL_SHIFT 0
-
-/*
- * R16 (0x10) - Right ADC Digital Volume
- */
-#define WM8991_ADC_VU 0x0100 /* ADC_VU */
-#define WM8991_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
-#define WM8991_ADCR_VOL_SHIFT 0
-
-/*
- * R18 (0x12) - GPIO CTRL 1
- */
-#define WM8991_IRQ 0x1000 /* IRQ */
-#define WM8991_TEMPOK 0x0800 /* TEMPOK */
-#define WM8991_MICSHRT 0x0400 /* MICSHRT */
-#define WM8991_MICDET 0x0200 /* MICDET */
-#define WM8991_PLL_LCK 0x0100 /* PLL_LCK */
-#define WM8991_GPI8_STATUS 0x0080 /* GPI8_STATUS */
-#define WM8991_GPI7_STATUS 0x0040 /* GPI7_STATUS */
-#define WM8991_GPIO6_STATUS 0x0020 /* GPIO6_STATUS */
-#define WM8991_GPIO5_STATUS 0x0010 /* GPIO5_STATUS */
-#define WM8991_GPIO4_STATUS 0x0008 /* GPIO4_STATUS */
-#define WM8991_GPIO3_STATUS 0x0004 /* GPIO3_STATUS */
-#define WM8991_GPIO2_STATUS 0x0002 /* GPIO2_STATUS */
-#define WM8991_GPIO1_STATUS 0x0001 /* GPIO1_STATUS */
-
-/*
- * R19 (0x13) - GPIO1 & GPIO2
- */
-#define WM8991_GPIO2_DEB_ENA 0x8000 /* GPIO2_DEB_ENA */
-#define WM8991_GPIO2_IRQ_ENA 0x4000 /* GPIO2_IRQ_ENA */
-#define WM8991_GPIO2_PU 0x2000 /* GPIO2_PU */
-#define WM8991_GPIO2_PD 0x1000 /* GPIO2_PD */
-#define WM8991_GPIO2_SEL_MASK 0x0F00 /* GPIO2_SEL - [11:8] */
-#define WM8991_GPIO1_DEB_ENA 0x0080 /* GPIO1_DEB_ENA */
-#define WM8991_GPIO1_IRQ_ENA 0x0040 /* GPIO1_IRQ_ENA */
-#define WM8991_GPIO1_PU 0x0020 /* GPIO1_PU */
-#define WM8991_GPIO1_PD 0x0010 /* GPIO1_PD */
-#define WM8991_GPIO1_SEL_MASK 0x000F /* GPIO1_SEL - [3:0] */
-
-/*
- * R20 (0x14) - GPIO3 & GPIO4
- */
-#define WM8991_GPIO4_DEB_ENA 0x8000 /* GPIO4_DEB_ENA */
-#define WM8991_GPIO4_IRQ_ENA 0x4000 /* GPIO4_IRQ_ENA */
-#define WM8991_GPIO4_PU 0x2000 /* GPIO4_PU */
-#define WM8991_GPIO4_PD 0x1000 /* GPIO4_PD */
-#define WM8991_GPIO4_SEL_MASK 0x0F00 /* GPIO4_SEL - [11:8] */
-#define WM8991_GPIO3_DEB_ENA 0x0080 /* GPIO3_DEB_ENA */
-#define WM8991_GPIO3_IRQ_ENA 0x0040 /* GPIO3_IRQ_ENA */
-#define WM8991_GPIO3_PU 0x0020 /* GPIO3_PU */
-#define WM8991_GPIO3_PD 0x0010 /* GPIO3_PD */
-#define WM8991_GPIO3_SEL_MASK 0x000F /* GPIO3_SEL - [3:0] */
-
-/*
- * R21 (0x15) - GPIO5 & GPIO6
- */
-#define WM8991_GPIO6_DEB_ENA 0x8000 /* GPIO6_DEB_ENA */
-#define WM8991_GPIO6_IRQ_ENA 0x4000 /* GPIO6_IRQ_ENA */
-#define WM8991_GPIO6_PU 0x2000 /* GPIO6_PU */
-#define WM8991_GPIO6_PD 0x1000 /* GPIO6_PD */
-#define WM8991_GPIO6_SEL_MASK 0x0F00 /* GPIO6_SEL - [11:8] */
-#define WM8991_GPIO5_DEB_ENA 0x0080 /* GPIO5_DEB_ENA */
-#define WM8991_GPIO5_IRQ_ENA 0x0040 /* GPIO5_IRQ_ENA */
-#define WM8991_GPIO5_PU 0x0020 /* GPIO5_PU */
-#define WM8991_GPIO5_PD 0x0010 /* GPIO5_PD */
-#define WM8991_GPIO5_SEL_MASK 0x000F /* GPIO5_SEL - [3:0] */
-
-/*
- * R22 (0x16) - GPIOCTRL 2
- */
-#define WM8991_RD_3W_ENA 0x8000 /* RD_3W_ENA */
-#define WM8991_MODE_3W4W 0x4000 /* MODE_3W4W */
-#define WM8991_TEMPOK_IRQ_ENA 0x0800 /* TEMPOK_IRQ_ENA */
-#define WM8991_MICSHRT_IRQ_ENA 0x0400 /* MICSHRT_IRQ_ENA */
-#define WM8991_MICDET_IRQ_ENA 0x0200 /* MICDET_IRQ_ENA */
-#define WM8991_PLL_LCK_IRQ_ENA 0x0100 /* PLL_LCK_IRQ_ENA */
-#define WM8991_GPI8_DEB_ENA 0x0080 /* GPI8_DEB_ENA */
-#define WM8991_GPI8_IRQ_ENA 0x0040 /* GPI8_IRQ_ENA */
-#define WM8991_GPI8_ENA 0x0010 /* GPI8_ENA */
-#define WM8991_GPI7_DEB_ENA 0x0008 /* GPI7_DEB_ENA */
-#define WM8991_GPI7_IRQ_ENA 0x0004 /* GPI7_IRQ_ENA */
-#define WM8991_GPI7_ENA 0x0001 /* GPI7_ENA */
-
-/*
- * R23 (0x17) - GPIO_POL
- */
-#define WM8991_IRQ_INV 0x1000 /* IRQ_INV */
-#define WM8991_TEMPOK_POL 0x0800 /* TEMPOK_POL */
-#define WM8991_MICSHRT_POL 0x0400 /* MICSHRT_POL */
-#define WM8991_MICDET_POL 0x0200 /* MICDET_POL */
-#define WM8991_PLL_LCK_POL 0x0100 /* PLL_LCK_POL */
-#define WM8991_GPI8_POL 0x0080 /* GPI8_POL */
-#define WM8991_GPI7_POL 0x0040 /* GPI7_POL */
-#define WM8991_GPIO6_POL 0x0020 /* GPIO6_POL */
-#define WM8991_GPIO5_POL 0x0010 /* GPIO5_POL */
-#define WM8991_GPIO4_POL 0x0008 /* GPIO4_POL */
-#define WM8991_GPIO3_POL 0x0004 /* GPIO3_POL */
-#define WM8991_GPIO2_POL 0x0002 /* GPIO2_POL */
-#define WM8991_GPIO1_POL 0x0001 /* GPIO1_POL */
-
-/*
- * R24 (0x18) - Left Line Input 1&2 Volume
- */
-#define WM8991_IPVU 0x0100 /* IPVU */
-#define WM8991_LI12MUTE 0x0080 /* LI12MUTE */
-#define WM8991_LI12MUTE_BIT 7
-#define WM8991_LI12ZC 0x0040 /* LI12ZC */
-#define WM8991_LI12ZC_BIT 6
-#define WM8991_LIN12VOL_MASK 0x001F /* LIN12VOL - [4:0] */
-#define WM8991_LIN12VOL_SHIFT 0
-/*
- * R25 (0x19) - Left Line Input 3&4 Volume
- */
-#define WM8991_IPVU 0x0100 /* IPVU */
-#define WM8991_LI34MUTE 0x0080 /* LI34MUTE */
-#define WM8991_LI34MUTE_BIT 7
-#define WM8991_LI34ZC 0x0040 /* LI34ZC */
-#define WM8991_LI34ZC_BIT 6
-#define WM8991_LIN34VOL_MASK 0x001F /* LIN34VOL - [4:0] */
-#define WM8991_LIN34VOL_SHIFT 0
-
-/*
- * R26 (0x1A) - Right Line Input 1&2 Volume
- */
-#define WM8991_IPVU 0x0100 /* IPVU */
-#define WM8991_RI12MUTE 0x0080 /* RI12MUTE */
-#define WM8991_RI12MUTE_BIT 7
-#define WM8991_RI12ZC 0x0040 /* RI12ZC */
-#define WM8991_RI12ZC_BIT 6
-#define WM8991_RIN12VOL_MASK 0x001F /* RIN12VOL - [4:0] */
-#define WM8991_RIN12VOL_SHIFT 0
-
-/*
- * R27 (0x1B) - Right Line Input 3&4 Volume
- */
-#define WM8991_IPVU 0x0100 /* IPVU */
-#define WM8991_RI34MUTE 0x0080 /* RI34MUTE */
-#define WM8991_RI34MUTE_BIT 7
-#define WM8991_RI34ZC 0x0040 /* RI34ZC */
-#define WM8991_RI34ZC_BIT 6
-#define WM8991_RIN34VOL_MASK 0x001F /* RIN34VOL - [4:0] */
-#define WM8991_RIN34VOL_SHIFT 0
-
-/*
- * R28 (0x1C) - Left Output Volume
- */
-#define WM8991_OPVU 0x0100 /* OPVU */
-#define WM8991_LOZC 0x0080 /* LOZC */
-#define WM8991_LOZC_BIT 7
-#define WM8991_LOUTVOL_MASK 0x007F /* LOUTVOL - [6:0] */
-#define WM8991_LOUTVOL_SHIFT 0
-/*
- * R29 (0x1D) - Right Output Volume
- */
-#define WM8991_OPVU 0x0100 /* OPVU */
-#define WM8991_ROZC 0x0080 /* ROZC */
-#define WM8991_ROZC_BIT 7
-#define WM8991_ROUTVOL_MASK 0x007F /* ROUTVOL - [6:0] */
-#define WM8991_ROUTVOL_SHIFT 0
-/*
- * R30 (0x1E) - Line Outputs Volume
- */
-#define WM8991_LONMUTE 0x0040 /* LONMUTE */
-#define WM8991_LONMUTE_BIT 6
-#define WM8991_LOPMUTE 0x0020 /* LOPMUTE */
-#define WM8991_LOPMUTE_BIT 5
-#define WM8991_LOATTN 0x0010 /* LOATTN */
-#define WM8991_LOATTN_BIT 4
-#define WM8991_RONMUTE 0x0004 /* RONMUTE */
-#define WM8991_RONMUTE_BIT 2
-#define WM8991_ROPMUTE 0x0002 /* ROPMUTE */
-#define WM8991_ROPMUTE_BIT 1
-#define WM8991_ROATTN 0x0001 /* ROATTN */
-#define WM8991_ROATTN_BIT 0
-
-/*
- * R31 (0x1F) - Out3/4 Volume
- */
-#define WM8991_OUT3MUTE 0x0020 /* OUT3MUTE */
-#define WM8991_OUT3MUTE_BIT 5
-#define WM8991_OUT3ATTN 0x0010 /* OUT3ATTN */
-#define WM8991_OUT3ATTN_BIT 4
-#define WM8991_OUT4MUTE 0x0002 /* OUT4MUTE */
-#define WM8991_OUT4MUTE_BIT 1
-#define WM8991_OUT4ATTN 0x0001 /* OUT4ATTN */
-#define WM8991_OUT4ATTN_BIT 0
-
-/*
- * R32 (0x20) - Left OPGA Volume
- */
-#define WM8991_OPVU 0x0100 /* OPVU */
-#define WM8991_LOPGAZC 0x0080 /* LOPGAZC */
-#define WM8991_LOPGAZC_BIT 7
-#define WM8991_LOPGAVOL_MASK 0x007F /* LOPGAVOL - [6:0] */
-#define WM8991_LOPGAVOL_SHIFT 0
-
-/*
- * R33 (0x21) - Right OPGA Volume
- */
-#define WM8991_OPVU 0x0100 /* OPVU */
-#define WM8991_ROPGAZC 0x0080 /* ROPGAZC */
-#define WM8991_ROPGAZC_BIT 7
-#define WM8991_ROPGAVOL_MASK 0x007F /* ROPGAVOL - [6:0] */
-#define WM8991_ROPGAVOL_SHIFT 0
-/*
- * R34 (0x22) - Speaker Volume
- */
-#define WM8991_SPKVOL_MASK 0x0003 /* SPKVOL - [1:0] */
-#define WM8991_SPKVOL_SHIFT 0
-
-/*
- * R35 (0x23) - ClassD1
- */
-#define WM8991_CDMODE 0x0100 /* CDMODE */
-#define WM8991_CDMODE_BIT 8
-
-/*
- * R37 (0x25) - ClassD3
- */
-#define WM8991_DCGAIN_MASK 0x0007 /* DCGAIN - [5:3] */
-#define WM8991_DCGAIN_SHIFT 3
-#define WM8991_ACGAIN_MASK 0x0007 /* ACGAIN - [2:0] */
-#define WM8991_ACGAIN_SHIFT 0
-/*
- * R39 (0x27) - Input Mixer1
- */
-#define WM8991_AINLMODE_MASK 0x000C /* AINLMODE - [3:2] */
-#define WM8991_AINLMODE_SHIFT 2
-#define WM8991_AINRMODE_MASK 0x0003 /* AINRMODE - [1:0] */
-#define WM8991_AINRMODE_SHIFT 0
-
-/*
- * R40 (0x28) - Input Mixer2
- */
-#define WM8991_LMP4 0x0080 /* LMP4 */
-#define WM8991_LMP4_BIT 7 /* LMP4 */
-#define WM8991_LMN3 0x0040 /* LMN3 */
-#define WM8991_LMN3_BIT 6 /* LMN3 */
-#define WM8991_LMP2 0x0020 /* LMP2 */
-#define WM8991_LMP2_BIT 5 /* LMP2 */
-#define WM8991_LMN1 0x0010 /* LMN1 */
-#define WM8991_LMN1_BIT 4 /* LMN1 */
-#define WM8991_RMP4 0x0008 /* RMP4 */
-#define WM8991_RMP4_BIT 3 /* RMP4 */
-#define WM8991_RMN3 0x0004 /* RMN3 */
-#define WM8991_RMN3_BIT 2 /* RMN3 */
-#define WM8991_RMP2 0x0002 /* RMP2 */
-#define WM8991_RMP2_BIT 1 /* RMP2 */
-#define WM8991_RMN1 0x0001 /* RMN1 */
-#define WM8991_RMN1_BIT 0 /* RMN1 */
-
-/*
- * R41 (0x29) - Input Mixer3
- */
-#define WM8991_L34MNB 0x0100 /* L34MNB */
-#define WM8991_L34MNB_BIT 8
-#define WM8991_L34MNBST 0x0080 /* L34MNBST */
-#define WM8991_L34MNBST_BIT 7
-#define WM8991_L12MNB 0x0020 /* L12MNB */
-#define WM8991_L12MNB_BIT 5
-#define WM8991_L12MNBST 0x0010 /* L12MNBST */
-#define WM8991_L12MNBST_BIT 4
-#define WM8991_LDBVOL_MASK 0x0007 /* LDBVOL - [2:0] */
-#define WM8991_LDBVOL_SHIFT 0
-
-/*
- * R42 (0x2A) - Input Mixer4
- */
-#define WM8991_R34MNB 0x0100 /* R34MNB */
-#define WM8991_R34MNB_BIT 8
-#define WM8991_R34MNBST 0x0080 /* R34MNBST */
-#define WM8991_R34MNBST_BIT 7
-#define WM8991_R12MNB 0x0020 /* R12MNB */
-#define WM8991_R12MNB_BIT 5
-#define WM8991_R12MNBST 0x0010 /* R12MNBST */
-#define WM8991_R12MNBST_BIT 4
-#define WM8991_RDBVOL_MASK 0x0007 /* RDBVOL - [2:0] */
-#define WM8991_RDBVOL_SHIFT 0
-
-/*
- * R43 (0x2B) - Input Mixer5
- */
-#define WM8991_LI2BVOL_MASK 0x07 /* LI2BVOL - [8:6] */
-#define WM8991_LI2BVOL_SHIFT 6
-#define WM8991_LR4BVOL_MASK 0x07 /* LR4BVOL - [5:3] */
-#define WM8991_LR4BVOL_SHIFT 3
-#define WM8991_LL4BVOL_MASK 0x07 /* LL4BVOL - [2:0] */
-#define WM8991_LL4BVOL_SHIFT 0
-
-/*
- * R44 (0x2C) - Input Mixer6
- */
-#define WM8991_RI2BVOL_MASK 0x07 /* RI2BVOL - [8:6] */
-#define WM8991_RI2BVOL_SHIFT 6
-#define WM8991_RL4BVOL_MASK 0x07 /* RL4BVOL - [5:3] */
-#define WM8991_RL4BVOL_SHIFT 3
-#define WM8991_RR4BVOL_MASK 0x07 /* RR4BVOL - [2:0] */
-#define WM8991_RR4BVOL_SHIFT 0
-
-/*
- * R45 (0x2D) - Output Mixer1
- */
-#define WM8991_LRBLO 0x0080 /* LRBLO */
-#define WM8991_LRBLO_BIT 7
-#define WM8991_LLBLO 0x0040 /* LLBLO */
-#define WM8991_LLBLO_BIT 6
-#define WM8991_LRI3LO 0x0020 /* LRI3LO */
-#define WM8991_LRI3LO_BIT 5
-#define WM8991_LLI3LO 0x0010 /* LLI3LO */
-#define WM8991_LLI3LO_BIT 4
-#define WM8991_LR12LO 0x0008 /* LR12LO */
-#define WM8991_LR12LO_BIT 3
-#define WM8991_LL12LO 0x0004 /* LL12LO */
-#define WM8991_LL12LO_BIT 2
-#define WM8991_LDLO 0x0001 /* LDLO */
-#define WM8991_LDLO_BIT 0
-
-/*
- * R46 (0x2E) - Output Mixer2
- */
-#define WM8991_RLBRO 0x0080 /* RLBRO */
-#define WM8991_RLBRO_BIT 7
-#define WM8991_RRBRO 0x0040 /* RRBRO */
-#define WM8991_RRBRO_BIT 6
-#define WM8991_RLI3RO 0x0020 /* RLI3RO */
-#define WM8991_RLI3RO_BIT 5
-#define WM8991_RRI3RO 0x0010 /* RRI3RO */
-#define WM8991_RRI3RO_BIT 4
-#define WM8991_RL12RO 0x0008 /* RL12RO */
-#define WM8991_RL12RO_BIT 3
-#define WM8991_RR12RO 0x0004 /* RR12RO */
-#define WM8991_RR12RO_BIT 2
-#define WM8991_RDRO 0x0001 /* RDRO */
-#define WM8991_RDRO_BIT 0
-
-/*
- * R47 (0x2F) - Output Mixer3
- */
-#define WM8991_LLI3LOVOL_MASK 0x07 /* LLI3LOVOL - [8:6] */
-#define WM8991_LLI3LOVOL_SHIFT 6
-#define WM8991_LR12LOVOL_MASK 0x07 /* LR12LOVOL - [5:3] */
-#define WM8991_LR12LOVOL_SHIFT 3
-#define WM8991_LL12LOVOL_MASK 0x07 /* LL12LOVOL - [2:0] */
-#define WM8991_LL12LOVOL_SHIFT 0
-
-/*
- * R48 (0x30) - Output Mixer4
- */
-#define WM8991_RRI3ROVOL_MASK 0x07 /* RRI3ROVOL - [8:6] */
-#define WM8991_RRI3ROVOL_SHIFT 6
-#define WM8991_RL12ROVOL_MASK 0x07 /* RL12ROVOL - [5:3] */
-#define WM8991_RL12ROVOL_SHIFT 3
-#define WM8991_RR12ROVOL_MASK 0x07 /* RR12ROVOL - [2:0] */
-#define WM8991_RR12ROVOL_SHIFT 0
-
-/*
- * R49 (0x31) - Output Mixer5
- */
-#define WM8991_LRI3LOVOL_MASK 0x07 /* LRI3LOVOL - [8:6] */
-#define WM8991_LRI3LOVOL_SHIFT 6
-#define WM8991_LRBLOVOL_MASK 0x07 /* LRBLOVOL - [5:3] */
-#define WM8991_LRBLOVOL_SHIFT 3
-#define WM8991_LLBLOVOL_MASK 0x07 /* LLBLOVOL - [2:0] */
-#define WM8991_LLBLOVOL_SHIFT 0
-
-/*
- * R50 (0x32) - Output Mixer6
- */
-#define WM8991_RLI3ROVOL_MASK 0x07 /* RLI3ROVOL - [8:6] */
-#define WM8991_RLI3ROVOL_SHIFT 6
-#define WM8991_RLBROVOL_MASK 0x07 /* RLBROVOL - [5:3] */
-#define WM8991_RLBROVOL_SHIFT 3
-#define WM8991_RRBROVOL_MASK 0x07 /* RRBROVOL - [2:0] */
-#define WM8991_RRBROVOL_SHIFT 0
-
-/*
- * R51 (0x33) - Out3/4 Mixer
- */
-#define WM8991_VSEL_MASK 0x0180 /* VSEL - [8:7] */
-#define WM8991_LI4O3 0x0020 /* LI4O3 */
-#define WM8991_LI4O3_BIT 5
-#define WM8991_LPGAO3 0x0010 /* LPGAO3 */
-#define WM8991_LPGAO3_BIT 4
-#define WM8991_RI4O4 0x0002 /* RI4O4 */
-#define WM8991_RI4O4_BIT 1
-#define WM8991_RPGAO4 0x0001 /* RPGAO4 */
-#define WM8991_RPGAO4_BIT 0
-/*
- * R52 (0x34) - Line Mixer1
- */
-#define WM8991_LLOPGALON 0x0040 /* LLOPGALON */
-#define WM8991_LLOPGALON_BIT 6
-#define WM8991_LROPGALON 0x0020 /* LROPGALON */
-#define WM8991_LROPGALON_BIT 5
-#define WM8991_LOPLON 0x0010 /* LOPLON */
-#define WM8991_LOPLON_BIT 4
-#define WM8991_LR12LOP 0x0004 /* LR12LOP */
-#define WM8991_LR12LOP_BIT 2
-#define WM8991_LL12LOP 0x0002 /* LL12LOP */
-#define WM8991_LL12LOP_BIT 1
-#define WM8991_LLOPGALOP 0x0001 /* LLOPGALOP */
-#define WM8991_LLOPGALOP_BIT 0
-/*
- * R53 (0x35) - Line Mixer2
- */
-#define WM8991_RROPGARON 0x0040 /* RROPGARON */
-#define WM8991_RROPGARON_BIT 6
-#define WM8991_RLOPGARON 0x0020 /* RLOPGARON */
-#define WM8991_RLOPGARON_BIT 5
-#define WM8991_ROPRON 0x0010 /* ROPRON */
-#define WM8991_ROPRON_BIT 4
-#define WM8991_RL12ROP 0x0004 /* RL12ROP */
-#define WM8991_RL12ROP_BIT 2
-#define WM8991_RR12ROP 0x0002 /* RR12ROP */
-#define WM8991_RR12ROP_BIT 1
-#define WM8991_RROPGAROP 0x0001 /* RROPGAROP */
-#define WM8991_RROPGAROP_BIT 0
-
-/*
- * R54 (0x36) - Speaker Mixer
- */
-#define WM8991_LB2SPK 0x0080 /* LB2SPK */
-#define WM8991_LB2SPK_BIT 7
-#define WM8991_RB2SPK 0x0040 /* RB2SPK */
-#define WM8991_RB2SPK_BIT 6
-#define WM8991_LI2SPK 0x0020 /* LI2SPK */
-#define WM8991_LI2SPK_BIT 5
-#define WM8991_RI2SPK 0x0010 /* RI2SPK */
-#define WM8991_RI2SPK_BIT 4
-#define WM8991_LOPGASPK 0x0008 /* LOPGASPK */
-#define WM8991_LOPGASPK_BIT 3
-#define WM8991_ROPGASPK 0x0004 /* ROPGASPK */
-#define WM8991_ROPGASPK_BIT 2
-#define WM8991_LDSPK 0x0002 /* LDSPK */
-#define WM8991_LDSPK_BIT 1
-#define WM8991_RDSPK 0x0001 /* RDSPK */
-#define WM8991_RDSPK_BIT 0
-
-/*
- * R55 (0x37) - Additional Control
- */
-#define WM8991_VROI 0x0001 /* VROI */
-
-/*
- * R56 (0x38) - AntiPOP1
- */
-#define WM8991_DIS_LLINE 0x0020 /* DIS_LLINE */
-#define WM8991_DIS_RLINE 0x0010 /* DIS_RLINE */
-#define WM8991_DIS_OUT3 0x0008 /* DIS_OUT3 */
-#define WM8991_DIS_OUT4 0x0004 /* DIS_OUT4 */
-#define WM8991_DIS_LOUT 0x0002 /* DIS_LOUT */
-#define WM8991_DIS_ROUT 0x0001 /* DIS_ROUT */
-
-/*
- * R57 (0x39) - AntiPOP2
- */
-#define WM8991_SOFTST 0x0040 /* SOFTST */
-#define WM8991_BUFIOEN 0x0008 /* BUFIOEN */
-#define WM8991_BUFDCOPEN 0x0004 /* BUFDCOPEN */
-#define WM8991_POBCTRL 0x0002 /* POBCTRL */
-#define WM8991_VMIDTOG 0x0001 /* VMIDTOG */
-
-/*
- * R58 (0x3A) - MICBIAS
- */
-#define WM8991_MCDSCTH_MASK 0x00C0 /* MCDSCTH - [7:6] */
-#define WM8991_MCDTHR_MASK 0x0038 /* MCDTHR - [5:3] */
-#define WM8991_MCD 0x0004 /* MCD */
-#define WM8991_MBSEL 0x0001 /* MBSEL */
-
-/*
- * R60 (0x3C) - PLL1
- */
-#define WM8991_SDM 0x0080 /* SDM */
-#define WM8991_PRESCALE 0x0040 /* PRESCALE */
-#define WM8991_PLLN_MASK 0x000F /* PLLN - [3:0] */
-
-/*
- * R61 (0x3D) - PLL2
- */
-#define WM8991_PLLK1_MASK 0x00FF /* PLLK1 - [7:0] */
-
-/*
- * R62 (0x3E) - PLL3
- */
-#define WM8991_PLLK2_MASK 0x00FF /* PLLK2 - [7:0] */
-
-/*
- * R63 (0x3F) - Internal Driver Bits
- */
-#define WM8991_INMIXL_PWR_BIT 0
-#define WM8991_AINLMUX_PWR_BIT 1
-#define WM8991_INMIXR_PWR_BIT 2
-#define WM8991_AINRMUX_PWR_BIT 3
-
-#define WM8991_MCLK_DIV 0
-#define WM8991_DACCLK_DIV 1
-#define WM8991_ADCCLK_DIV 2
-#define WM8991_BCLK_DIV 3
-
-#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\
- tlv_array) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
- .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
- SNDRV_CTL_ELEM_ACCESS_READWRITE,\
- .tlv.p = (tlv_array), \
- .info = snd_soc_info_volsw, \
- .get = snd_soc_get_volsw, .put = wm899x_outpga_put_volsw_vu, \
- .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
-
-#endif /* _WM8991_H */
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8993.c b/ANDROID_3.4.5/sound/soc/codecs/wm8993.c
deleted file mode 100644
index d256a934..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8993.c
+++ /dev/null
@@ -1,1866 +0,0 @@
-/*
- * wm8993.c -- WM8993 ALSA SoC audio driver
- *
- * Copyright 2009, 2010 Wolfson Microelectronics plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/regmap.h>
-#include <linux/regulator/consumer.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/tlv.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/wm8993.h>
-
-#include "wm8993.h"
-#include "wm_hubs.h"
-
-#define WM8993_NUM_SUPPLIES 6
-static const char *wm8993_supply_names[WM8993_NUM_SUPPLIES] = {
- "DCVDD",
- "DBVDD",
- "AVDD1",
- "AVDD2",
- "CPVDD",
- "SPKVDD",
-};
-
-static struct reg_default wm8993_reg_defaults[] = {
- { 1, 0x0000 }, /* R1 - Power Management (1) */
- { 2, 0x6000 }, /* R2 - Power Management (2) */
- { 3, 0x0000 }, /* R3 - Power Management (3) */
- { 4, 0x4050 }, /* R4 - Audio Interface (1) */
- { 5, 0x4000 }, /* R5 - Audio Interface (2) */
- { 6, 0x01C8 }, /* R6 - Clocking 1 */
- { 7, 0x0000 }, /* R7 - Clocking 2 */
- { 8, 0x0000 }, /* R8 - Audio Interface (3) */
- { 9, 0x0040 }, /* R9 - Audio Interface (4) */
- { 10, 0x0004 }, /* R10 - DAC CTRL */
- { 11, 0x00C0 }, /* R11 - Left DAC Digital Volume */
- { 12, 0x00C0 }, /* R12 - Right DAC Digital Volume */
- { 13, 0x0000 }, /* R13 - Digital Side Tone */
- { 14, 0x0300 }, /* R14 - ADC CTRL */
- { 15, 0x00C0 }, /* R15 - Left ADC Digital Volume */
- { 16, 0x00C0 }, /* R16 - Right ADC Digital Volume */
- { 18, 0x0000 }, /* R18 - GPIO CTRL 1 */
- { 19, 0x0010 }, /* R19 - GPIO1 */
- { 20, 0x0000 }, /* R20 - IRQ_DEBOUNCE */
- { 21, 0x0000 }, /* R21 - Inputs Clamp */
- { 22, 0x8000 }, /* R22 - GPIOCTRL 2 */
- { 23, 0x0800 }, /* R23 - GPIO_POL */
- { 24, 0x008B }, /* R24 - Left Line Input 1&2 Volume */
- { 25, 0x008B }, /* R25 - Left Line Input 3&4 Volume */
- { 26, 0x008B }, /* R26 - Right Line Input 1&2 Volume */
- { 27, 0x008B }, /* R27 - Right Line Input 3&4 Volume */
- { 28, 0x006D }, /* R28 - Left Output Volume */
- { 29, 0x006D }, /* R29 - Right Output Volume */
- { 30, 0x0066 }, /* R30 - Line Outputs Volume */
- { 31, 0x0020 }, /* R31 - HPOUT2 Volume */
- { 32, 0x0079 }, /* R32 - Left OPGA Volume */
- { 33, 0x0079 }, /* R33 - Right OPGA Volume */
- { 34, 0x0003 }, /* R34 - SPKMIXL Attenuation */
- { 35, 0x0003 }, /* R35 - SPKMIXR Attenuation */
- { 36, 0x0011 }, /* R36 - SPKOUT Mixers */
- { 37, 0x0100 }, /* R37 - SPKOUT Boost */
- { 38, 0x0079 }, /* R38 - Speaker Volume Left */
- { 39, 0x0079 }, /* R39 - Speaker Volume Right */
- { 40, 0x0000 }, /* R40 - Input Mixer2 */
- { 41, 0x0000 }, /* R41 - Input Mixer3 */
- { 42, 0x0000 }, /* R42 - Input Mixer4 */
- { 43, 0x0000 }, /* R43 - Input Mixer5 */
- { 44, 0x0000 }, /* R44 - Input Mixer6 */
- { 45, 0x0000 }, /* R45 - Output Mixer1 */
- { 46, 0x0000 }, /* R46 - Output Mixer2 */
- { 47, 0x0000 }, /* R47 - Output Mixer3 */
- { 48, 0x0000 }, /* R48 - Output Mixer4 */
- { 49, 0x0000 }, /* R49 - Output Mixer5 */
- { 50, 0x0000 }, /* R50 - Output Mixer6 */
- { 51, 0x0000 }, /* R51 - HPOUT2 Mixer */
- { 52, 0x0000 }, /* R52 - Line Mixer1 */
- { 53, 0x0000 }, /* R53 - Line Mixer2 */
- { 54, 0x0000 }, /* R54 - Speaker Mixer */
- { 55, 0x0000 }, /* R55 - Additional Control */
- { 56, 0x0000 }, /* R56 - AntiPOP1 */
- { 57, 0x0000 }, /* R57 - AntiPOP2 */
- { 58, 0x0000 }, /* R58 - MICBIAS */
- { 60, 0x0000 }, /* R60 - FLL Control 1 */
- { 61, 0x0000 }, /* R61 - FLL Control 2 */
- { 62, 0x0000 }, /* R62 - FLL Control 3 */
- { 63, 0x2EE0 }, /* R63 - FLL Control 4 */
- { 64, 0x0002 }, /* R64 - FLL Control 5 */
- { 65, 0x2287 }, /* R65 - Clocking 3 */
- { 66, 0x025F }, /* R66 - Clocking 4 */
- { 67, 0x0000 }, /* R67 - MW Slave Control */
- { 69, 0x0002 }, /* R69 - Bus Control 1 */
- { 70, 0x0000 }, /* R70 - Write Sequencer 0 */
- { 71, 0x0000 }, /* R71 - Write Sequencer 1 */
- { 72, 0x0000 }, /* R72 - Write Sequencer 2 */
- { 73, 0x0000 }, /* R73 - Write Sequencer 3 */
- { 74, 0x0000 }, /* R74 - Write Sequencer 4 */
- { 75, 0x0000 }, /* R75 - Write Sequencer 5 */
- { 76, 0x1F25 }, /* R76 - Charge Pump 1 */
- { 81, 0x0000 }, /* R81 - Class W 0 */
- { 85, 0x054A }, /* R85 - DC Servo 1 */
- { 87, 0x0000 }, /* R87 - DC Servo 3 */
- { 96, 0x0100 }, /* R96 - Analogue HP 0 */
- { 98, 0x0000 }, /* R98 - EQ1 */
- { 99, 0x000C }, /* R99 - EQ2 */
- { 100, 0x000C }, /* R100 - EQ3 */
- { 101, 0x000C }, /* R101 - EQ4 */
- { 102, 0x000C }, /* R102 - EQ5 */
- { 103, 0x000C }, /* R103 - EQ6 */
- { 104, 0x0FCA }, /* R104 - EQ7 */
- { 105, 0x0400 }, /* R105 - EQ8 */
- { 106, 0x00D8 }, /* R106 - EQ9 */
- { 107, 0x1EB5 }, /* R107 - EQ10 */
- { 108, 0xF145 }, /* R108 - EQ11 */
- { 109, 0x0B75 }, /* R109 - EQ12 */
- { 110, 0x01C5 }, /* R110 - EQ13 */
- { 111, 0x1C58 }, /* R111 - EQ14 */
- { 112, 0xF373 }, /* R112 - EQ15 */
- { 113, 0x0A54 }, /* R113 - EQ16 */
- { 114, 0x0558 }, /* R114 - EQ17 */
- { 115, 0x168E }, /* R115 - EQ18 */
- { 116, 0xF829 }, /* R116 - EQ19 */
- { 117, 0x07AD }, /* R117 - EQ20 */
- { 118, 0x1103 }, /* R118 - EQ21 */
- { 119, 0x0564 }, /* R119 - EQ22 */
- { 120, 0x0559 }, /* R120 - EQ23 */
- { 121, 0x4000 }, /* R121 - EQ24 */
- { 122, 0x0000 }, /* R122 - Digital Pulls */
- { 123, 0x0F08 }, /* R123 - DRC Control 1 */
- { 124, 0x0000 }, /* R124 - DRC Control 2 */
- { 125, 0x0080 }, /* R125 - DRC Control 3 */
- { 126, 0x0000 }, /* R126 - DRC Control 4 */
-};
-
-static struct {
- int ratio;
- int clk_sys_rate;
-} clk_sys_rates[] = {
- { 64, 0 },
- { 128, 1 },
- { 192, 2 },
- { 256, 3 },
- { 384, 4 },
- { 512, 5 },
- { 768, 6 },
- { 1024, 7 },
- { 1408, 8 },
- { 1536, 9 },
-};
-
-static struct {
- int rate;
- int sample_rate;
-} sample_rates[] = {
- { 8000, 0 },
- { 11025, 1 },
- { 12000, 1 },
- { 16000, 2 },
- { 22050, 3 },
- { 24000, 3 },
- { 32000, 4 },
- { 44100, 5 },
- { 48000, 5 },
-};
-
-static struct {
- int div; /* *10 due to .5s */
- int bclk_div;
-} bclk_divs[] = {
- { 10, 0 },
- { 15, 1 },
- { 20, 2 },
- { 30, 3 },
- { 40, 4 },
- { 55, 5 },
- { 60, 6 },
- { 80, 7 },
- { 110, 8 },
- { 120, 9 },
- { 160, 10 },
- { 220, 11 },
- { 240, 12 },
- { 320, 13 },
- { 440, 14 },
- { 480, 15 },
-};
-
-struct wm8993_priv {
- struct wm_hubs_data hubs_data;
- struct device *dev;
- struct regmap *regmap;
- struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES];
- struct wm8993_platform_data pdata;
- struct completion fll_lock;
- int master;
- int sysclk_source;
- int tdm_slots;
- int tdm_width;
- unsigned int mclk_rate;
- unsigned int sysclk_rate;
- unsigned int fs;
- unsigned int bclk;
- int class_w_users;
- unsigned int fll_fref;
- unsigned int fll_fout;
- int fll_src;
-};
-
-static bool wm8993_volatile(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM8993_SOFTWARE_RESET:
- case WM8993_GPIO_CTRL_1:
- case WM8993_DC_SERVO_0:
- case WM8993_DC_SERVO_READBACK_0:
- case WM8993_DC_SERVO_READBACK_1:
- case WM8993_DC_SERVO_READBACK_2:
- return true;
- default:
- return false;
- }
-}
-
-static bool wm8993_readable(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM8993_SOFTWARE_RESET:
- case WM8993_POWER_MANAGEMENT_1:
- case WM8993_POWER_MANAGEMENT_2:
- case WM8993_POWER_MANAGEMENT_3:
- case WM8993_AUDIO_INTERFACE_1:
- case WM8993_AUDIO_INTERFACE_2:
- case WM8993_CLOCKING_1:
- case WM8993_CLOCKING_2:
- case WM8993_AUDIO_INTERFACE_3:
- case WM8993_AUDIO_INTERFACE_4:
- case WM8993_DAC_CTRL:
- case WM8993_LEFT_DAC_DIGITAL_VOLUME:
- case WM8993_RIGHT_DAC_DIGITAL_VOLUME:
- case WM8993_DIGITAL_SIDE_TONE:
- case WM8993_ADC_CTRL:
- case WM8993_LEFT_ADC_DIGITAL_VOLUME:
- case WM8993_RIGHT_ADC_DIGITAL_VOLUME:
- case WM8993_GPIO_CTRL_1:
- case WM8993_GPIO1:
- case WM8993_IRQ_DEBOUNCE:
- case WM8993_GPIOCTRL_2:
- case WM8993_GPIO_POL:
- case WM8993_LEFT_LINE_INPUT_1_2_VOLUME:
- case WM8993_LEFT_LINE_INPUT_3_4_VOLUME:
- case WM8993_RIGHT_LINE_INPUT_1_2_VOLUME:
- case WM8993_RIGHT_LINE_INPUT_3_4_VOLUME:
- case WM8993_LEFT_OUTPUT_VOLUME:
- case WM8993_RIGHT_OUTPUT_VOLUME:
- case WM8993_LINE_OUTPUTS_VOLUME:
- case WM8993_HPOUT2_VOLUME:
- case WM8993_LEFT_OPGA_VOLUME:
- case WM8993_RIGHT_OPGA_VOLUME:
- case WM8993_SPKMIXL_ATTENUATION:
- case WM8993_SPKMIXR_ATTENUATION:
- case WM8993_SPKOUT_MIXERS:
- case WM8993_SPKOUT_BOOST:
- case WM8993_SPEAKER_VOLUME_LEFT:
- case WM8993_SPEAKER_VOLUME_RIGHT:
- case WM8993_INPUT_MIXER2:
- case WM8993_INPUT_MIXER3:
- case WM8993_INPUT_MIXER4:
- case WM8993_INPUT_MIXER5:
- case WM8993_INPUT_MIXER6:
- case WM8993_OUTPUT_MIXER1:
- case WM8993_OUTPUT_MIXER2:
- case WM8993_OUTPUT_MIXER3:
- case WM8993_OUTPUT_MIXER4:
- case WM8993_OUTPUT_MIXER5:
- case WM8993_OUTPUT_MIXER6:
- case WM8993_HPOUT2_MIXER:
- case WM8993_LINE_MIXER1:
- case WM8993_LINE_MIXER2:
- case WM8993_SPEAKER_MIXER:
- case WM8993_ADDITIONAL_CONTROL:
- case WM8993_ANTIPOP1:
- case WM8993_ANTIPOP2:
- case WM8993_MICBIAS:
- case WM8993_FLL_CONTROL_1:
- case WM8993_FLL_CONTROL_2:
- case WM8993_FLL_CONTROL_3:
- case WM8993_FLL_CONTROL_4:
- case WM8993_FLL_CONTROL_5:
- case WM8993_CLOCKING_3:
- case WM8993_CLOCKING_4:
- case WM8993_MW_SLAVE_CONTROL:
- case WM8993_BUS_CONTROL_1:
- case WM8993_WRITE_SEQUENCER_0:
- case WM8993_WRITE_SEQUENCER_1:
- case WM8993_WRITE_SEQUENCER_2:
- case WM8993_WRITE_SEQUENCER_3:
- case WM8993_WRITE_SEQUENCER_4:
- case WM8993_WRITE_SEQUENCER_5:
- case WM8993_CHARGE_PUMP_1:
- case WM8993_CLASS_W_0:
- case WM8993_DC_SERVO_0:
- case WM8993_DC_SERVO_1:
- case WM8993_DC_SERVO_3:
- case WM8993_DC_SERVO_READBACK_0:
- case WM8993_DC_SERVO_READBACK_1:
- case WM8993_DC_SERVO_READBACK_2:
- case WM8993_ANALOGUE_HP_0:
- case WM8993_EQ1:
- case WM8993_EQ2:
- case WM8993_EQ3:
- case WM8993_EQ4:
- case WM8993_EQ5:
- case WM8993_EQ6:
- case WM8993_EQ7:
- case WM8993_EQ8:
- case WM8993_EQ9:
- case WM8993_EQ10:
- case WM8993_EQ11:
- case WM8993_EQ12:
- case WM8993_EQ13:
- case WM8993_EQ14:
- case WM8993_EQ15:
- case WM8993_EQ16:
- case WM8993_EQ17:
- case WM8993_EQ18:
- case WM8993_EQ19:
- case WM8993_EQ20:
- case WM8993_EQ21:
- case WM8993_EQ22:
- case WM8993_EQ23:
- case WM8993_EQ24:
- case WM8993_DIGITAL_PULLS:
- case WM8993_DRC_CONTROL_1:
- case WM8993_DRC_CONTROL_2:
- case WM8993_DRC_CONTROL_3:
- case WM8993_DRC_CONTROL_4:
- return true;
- default:
- return false;
- }
-}
-
-struct _fll_div {
- u16 fll_fratio;
- u16 fll_outdiv;
- u16 fll_clk_ref_div;
- u16 n;
- u16 k;
-};
-
-/* The size in bits of the FLL divide multiplied by 10
- * to allow rounding later */
-#define FIXED_FLL_SIZE ((1 << 16) * 10)
-
-static struct {
- unsigned int min;
- unsigned int max;
- u16 fll_fratio;
- int ratio;
-} fll_fratios[] = {
- { 0, 64000, 4, 16 },
- { 64000, 128000, 3, 8 },
- { 128000, 256000, 2, 4 },
- { 256000, 1000000, 1, 2 },
- { 1000000, 13500000, 0, 1 },
-};
-
-static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
- unsigned int Fout)
-{
- u64 Kpart;
- unsigned int K, Ndiv, Nmod, target;
- unsigned int div;
- int i;
-
- /* Fref must be <=13.5MHz */
- div = 1;
- fll_div->fll_clk_ref_div = 0;
- while ((Fref / div) > 13500000) {
- div *= 2;
- fll_div->fll_clk_ref_div++;
-
- if (div > 8) {
- pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
- Fref);
- return -EINVAL;
- }
- }
-
- pr_debug("Fref=%u Fout=%u\n", Fref, Fout);
-
- /* Apply the division for our remaining calculations */
- Fref /= div;
-
- /* Fvco should be 90-100MHz; don't check the upper bound */
- div = 0;
- target = Fout * 2;
- while (target < 90000000) {
- div++;
- target *= 2;
- if (div > 7) {
- pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
- Fout);
- return -EINVAL;
- }
- }
- fll_div->fll_outdiv = div;
-
- pr_debug("Fvco=%dHz\n", target);
-
- /* Find an appropriate FLL_FRATIO and factor it out of the target */
- for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
- if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
- fll_div->fll_fratio = fll_fratios[i].fll_fratio;
- target /= fll_fratios[i].ratio;
- break;
- }
- }
- if (i == ARRAY_SIZE(fll_fratios)) {
- pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
- return -EINVAL;
- }
-
- /* Now, calculate N.K */
- Ndiv = target / Fref;
-
- fll_div->n = Ndiv;
- Nmod = target % Fref;
- pr_debug("Nmod=%d\n", Nmod);
-
- /* Calculate fractional part - scale up so we can round. */
- Kpart = FIXED_FLL_SIZE * (long long)Nmod;
-
- do_div(Kpart, Fref);
-
- K = Kpart & 0xFFFFFFFF;
-
- if ((K % 10) >= 5)
- K += 5;
-
- /* Move down to proper range now rounding is done */
- fll_div->k = K / 10;
-
- pr_debug("N=%x K=%x FLL_FRATIO=%x FLL_OUTDIV=%x FLL_CLK_REF_DIV=%x\n",
- fll_div->n, fll_div->k,
- fll_div->fll_fratio, fll_div->fll_outdiv,
- fll_div->fll_clk_ref_div);
-
- return 0;
-}
-
-static int _wm8993_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
- unsigned int Fref, unsigned int Fout)
-{
- struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
- struct i2c_client *i2c = to_i2c_client(codec->dev);
- u16 reg1, reg4, reg5;
- struct _fll_div fll_div;
- unsigned int timeout;
- int ret;
-
- /* Any change? */
- if (Fref == wm8993->fll_fref && Fout == wm8993->fll_fout)
- return 0;
-
- /* Disable the FLL */
- if (Fout == 0) {
- dev_dbg(codec->dev, "FLL disabled\n");
- wm8993->fll_fref = 0;
- wm8993->fll_fout = 0;
-
- reg1 = snd_soc_read(codec, WM8993_FLL_CONTROL_1);
- reg1 &= ~WM8993_FLL_ENA;
- snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
-
- return 0;
- }
-
- ret = fll_factors(&fll_div, Fref, Fout);
- if (ret != 0)
- return ret;
-
- reg5 = snd_soc_read(codec, WM8993_FLL_CONTROL_5);
- reg5 &= ~WM8993_FLL_CLK_SRC_MASK;
-
- switch (fll_id) {
- case WM8993_FLL_MCLK:
- break;
-
- case WM8993_FLL_LRCLK:
- reg5 |= 1;
- break;
-
- case WM8993_FLL_BCLK:
- reg5 |= 2;
- break;
-
- default:
- dev_err(codec->dev, "Unknown FLL ID %d\n", fll_id);
- return -EINVAL;
- }
-
- /* Any FLL configuration change requires that the FLL be
- * disabled first. */
- reg1 = snd_soc_read(codec, WM8993_FLL_CONTROL_1);
- reg1 &= ~WM8993_FLL_ENA;
- snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
-
- /* Apply the configuration */
- if (fll_div.k)
- reg1 |= WM8993_FLL_FRAC_MASK;
- else
- reg1 &= ~WM8993_FLL_FRAC_MASK;
- snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
-
- snd_soc_write(codec, WM8993_FLL_CONTROL_2,
- (fll_div.fll_outdiv << WM8993_FLL_OUTDIV_SHIFT) |
- (fll_div.fll_fratio << WM8993_FLL_FRATIO_SHIFT));
- snd_soc_write(codec, WM8993_FLL_CONTROL_3, fll_div.k);
-
- reg4 = snd_soc_read(codec, WM8993_FLL_CONTROL_4);
- reg4 &= ~WM8993_FLL_N_MASK;
- reg4 |= fll_div.n << WM8993_FLL_N_SHIFT;
- snd_soc_write(codec, WM8993_FLL_CONTROL_4, reg4);
-
- reg5 &= ~WM8993_FLL_CLK_REF_DIV_MASK;
- reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT;
- snd_soc_write(codec, WM8993_FLL_CONTROL_5, reg5);
-
- /* If we've got an interrupt wired up make sure we get it */
- if (i2c->irq)
- timeout = msecs_to_jiffies(20);
- else if (Fref < 1000000)
- timeout = msecs_to_jiffies(3);
- else
- timeout = msecs_to_jiffies(1);
-
- try_wait_for_completion(&wm8993->fll_lock);
-
- /* Enable the FLL */
- snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA);
-
- timeout = wait_for_completion_timeout(&wm8993->fll_lock, timeout);
- if (i2c->irq && !timeout)
- dev_warn(codec->dev, "Timed out waiting for FLL\n");
-
- dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout);
-
- wm8993->fll_fref = Fref;
- wm8993->fll_fout = Fout;
- wm8993->fll_src = source;
-
- return 0;
-}
-
-static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
- unsigned int Fref, unsigned int Fout)
-{
- return _wm8993_set_fll(dai->codec, fll_id, source, Fref, Fout);
-}
-
-static int configure_clock(struct snd_soc_codec *codec)
-{
- struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
- unsigned int reg;
-
- /* This should be done on init() for bypass paths */
- switch (wm8993->sysclk_source) {
- case WM8993_SYSCLK_MCLK:
- dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate);
-
- reg = snd_soc_read(codec, WM8993_CLOCKING_2);
- reg &= ~(WM8993_MCLK_DIV | WM8993_SYSCLK_SRC);
- if (wm8993->mclk_rate > 13500000) {
- reg |= WM8993_MCLK_DIV;
- wm8993->sysclk_rate = wm8993->mclk_rate / 2;
- } else {
- reg &= ~WM8993_MCLK_DIV;
- wm8993->sysclk_rate = wm8993->mclk_rate;
- }
- snd_soc_write(codec, WM8993_CLOCKING_2, reg);
- break;
-
- case WM8993_SYSCLK_FLL:
- dev_dbg(codec->dev, "Using %dHz FLL clock\n",
- wm8993->fll_fout);
-
- reg = snd_soc_read(codec, WM8993_CLOCKING_2);
- reg |= WM8993_SYSCLK_SRC;
- if (wm8993->fll_fout > 13500000) {
- reg |= WM8993_MCLK_DIV;
- wm8993->sysclk_rate = wm8993->fll_fout / 2;
- } else {
- reg &= ~WM8993_MCLK_DIV;
- wm8993->sysclk_rate = wm8993->fll_fout;
- }
- snd_soc_write(codec, WM8993_CLOCKING_2, reg);
- break;
-
- default:
- dev_err(codec->dev, "System clock not configured\n");
- return -EINVAL;
- }
-
- dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm8993->sysclk_rate);
-
- return 0;
-}
-
-static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 300, 0);
-static const DECLARE_TLV_DB_SCALE(drc_comp_threash, -4500, 75, 0);
-static const DECLARE_TLV_DB_SCALE(drc_comp_amp, -2250, 75, 0);
-static const DECLARE_TLV_DB_SCALE(drc_min_tlv, -1800, 600, 0);
-static const unsigned int drc_max_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 2, TLV_DB_SCALE_ITEM(1200, 600, 0),
- 3, 3, TLV_DB_SCALE_ITEM(3600, 0, 0),
-};
-static const DECLARE_TLV_DB_SCALE(drc_qr_tlv, 1200, 600, 0);
-static const DECLARE_TLV_DB_SCALE(drc_startup_tlv, -1800, 300, 0);
-static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
-static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
-static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0);
-
-static const char *dac_deemph_text[] = {
- "None",
- "32kHz",
- "44.1kHz",
- "48kHz",
-};
-
-static const struct soc_enum dac_deemph =
- SOC_ENUM_SINGLE(WM8993_DAC_CTRL, 4, 4, dac_deemph_text);
-
-static const char *adc_hpf_text[] = {
- "Hi-Fi",
- "Voice 1",
- "Voice 2",
- "Voice 3",
-};
-
-static const struct soc_enum adc_hpf =
- SOC_ENUM_SINGLE(WM8993_ADC_CTRL, 5, 4, adc_hpf_text);
-
-static const char *drc_path_text[] = {
- "ADC",
- "DAC"
-};
-
-static const struct soc_enum drc_path =
- SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_1, 14, 2, drc_path_text);
-
-static const char *drc_r0_text[] = {
- "1",
- "1/2",
- "1/4",
- "1/8",
- "1/16",
- "0",
-};
-
-static const struct soc_enum drc_r0 =
- SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_3, 8, 6, drc_r0_text);
-
-static const char *drc_r1_text[] = {
- "1",
- "1/2",
- "1/4",
- "1/8",
- "0",
-};
-
-static const struct soc_enum drc_r1 =
- SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_4, 13, 5, drc_r1_text);
-
-static const char *drc_attack_text[] = {
- "Reserved",
- "181us",
- "363us",
- "726us",
- "1.45ms",
- "2.9ms",
- "5.8ms",
- "11.6ms",
- "23.2ms",
- "46.4ms",
- "92.8ms",
- "185.6ms",
-};
-
-static const struct soc_enum drc_attack =
- SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_2, 12, 12, drc_attack_text);
-
-static const char *drc_decay_text[] = {
- "186ms",
- "372ms",
- "743ms",
- "1.49s",
- "2.97ms",
- "5.94ms",
- "11.89ms",
- "23.78ms",
- "47.56ms",
-};
-
-static const struct soc_enum drc_decay =
- SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_2, 8, 9, drc_decay_text);
-
-static const char *drc_ff_text[] = {
- "5 samples",
- "9 samples",
-};
-
-static const struct soc_enum drc_ff =
- SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_3, 7, 2, drc_ff_text);
-
-static const char *drc_qr_rate_text[] = {
- "0.725ms",
- "1.45ms",
- "5.8ms",
-};
-
-static const struct soc_enum drc_qr_rate =
- SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_3, 0, 3, drc_qr_rate_text);
-
-static const char *drc_smooth_text[] = {
- "Low",
- "Medium",
- "High",
-};
-
-static const struct soc_enum drc_smooth =
- SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_1, 4, 3, drc_smooth_text);
-
-static const struct snd_kcontrol_new wm8993_snd_controls[] = {
-SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8993_DIGITAL_SIDE_TONE,
- 5, 9, 12, 0, sidetone_tlv),
-
-SOC_SINGLE("DRC Switch", WM8993_DRC_CONTROL_1, 15, 1, 0),
-SOC_ENUM("DRC Path", drc_path),
-SOC_SINGLE_TLV("DRC Compressor Threshold Volume", WM8993_DRC_CONTROL_2,
- 2, 60, 1, drc_comp_threash),
-SOC_SINGLE_TLV("DRC Compressor Amplitude Volume", WM8993_DRC_CONTROL_3,
- 11, 30, 1, drc_comp_amp),
-SOC_ENUM("DRC R0", drc_r0),
-SOC_ENUM("DRC R1", drc_r1),
-SOC_SINGLE_TLV("DRC Minimum Volume", WM8993_DRC_CONTROL_1, 2, 3, 1,
- drc_min_tlv),
-SOC_SINGLE_TLV("DRC Maximum Volume", WM8993_DRC_CONTROL_1, 0, 3, 0,
- drc_max_tlv),
-SOC_ENUM("DRC Attack Rate", drc_attack),
-SOC_ENUM("DRC Decay Rate", drc_decay),
-SOC_ENUM("DRC FF Delay", drc_ff),
-SOC_SINGLE("DRC Anti-clip Switch", WM8993_DRC_CONTROL_1, 9, 1, 0),
-SOC_SINGLE("DRC Quick Release Switch", WM8993_DRC_CONTROL_1, 10, 1, 0),
-SOC_SINGLE_TLV("DRC Quick Release Volume", WM8993_DRC_CONTROL_3, 2, 3, 0,
- drc_qr_tlv),
-SOC_ENUM("DRC Quick Release Rate", drc_qr_rate),
-SOC_SINGLE("DRC Smoothing Switch", WM8993_DRC_CONTROL_1, 11, 1, 0),
-SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8993_DRC_CONTROL_1, 8, 1, 0),
-SOC_ENUM("DRC Smoothing Hysteresis Threshold", drc_smooth),
-SOC_SINGLE_TLV("DRC Startup Volume", WM8993_DRC_CONTROL_4, 8, 18, 0,
- drc_startup_tlv),
-
-SOC_SINGLE("EQ Switch", WM8993_EQ1, 0, 1, 0),
-
-SOC_DOUBLE_R_TLV("Capture Volume", WM8993_LEFT_ADC_DIGITAL_VOLUME,
- WM8993_RIGHT_ADC_DIGITAL_VOLUME, 1, 96, 0, digital_tlv),
-SOC_SINGLE("ADC High Pass Filter Switch", WM8993_ADC_CTRL, 8, 1, 0),
-SOC_ENUM("ADC High Pass Filter Mode", adc_hpf),
-
-SOC_DOUBLE_R_TLV("Playback Volume", WM8993_LEFT_DAC_DIGITAL_VOLUME,
- WM8993_RIGHT_DAC_DIGITAL_VOLUME, 1, 96, 0, digital_tlv),
-SOC_SINGLE_TLV("Playback Boost Volume", WM8993_AUDIO_INTERFACE_2, 10, 3, 0,
- dac_boost_tlv),
-SOC_ENUM("DAC Deemphasis", dac_deemph),
-
-SOC_SINGLE_TLV("SPKL DAC Volume", WM8993_SPKMIXL_ATTENUATION,
- 2, 1, 1, wm_hubs_spkmix_tlv),
-
-SOC_SINGLE_TLV("SPKR DAC Volume", WM8993_SPKMIXR_ATTENUATION,
- 2, 1, 1, wm_hubs_spkmix_tlv),
-};
-
-static const struct snd_kcontrol_new wm8993_eq_controls[] = {
-SOC_SINGLE_TLV("EQ1 Volume", WM8993_EQ2, 0, 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ2 Volume", WM8993_EQ3, 0, 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ3 Volume", WM8993_EQ4, 0, 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ4 Volume", WM8993_EQ5, 0, 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ5 Volume", WM8993_EQ6, 0, 24, 0, eq_tlv),
-};
-
-static int clk_sys_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- return configure_clock(codec);
-
- case SND_SOC_DAPM_POST_PMD:
- break;
- }
-
- return 0;
-}
-
-/*
- * When used with DAC outputs only the WM8993 charge pump supports
- * operation in class W mode, providing very low power consumption
- * when used with digital sources. Enable and disable this mode
- * automatically depending on the mixer configuration.
- *
- * Currently the only supported paths are the direct DAC->headphone
- * paths (which provide minimum power consumption anyway).
- */
-static int class_w_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
- struct snd_soc_dapm_widget *widget = wlist->widgets[0];
- struct snd_soc_codec *codec = widget->codec;
- struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- /* Turn it off if we're using the main output mixer */
- if (ucontrol->value.integer.value[0] == 0) {
- if (wm8993->class_w_users == 0) {
- dev_dbg(codec->dev, "Disabling Class W\n");
- snd_soc_update_bits(codec, WM8993_CLASS_W_0,
- WM8993_CP_DYN_FREQ |
- WM8993_CP_DYN_V,
- 0);
- }
- wm8993->class_w_users++;
- wm8993->hubs_data.class_w = true;
- }
-
- /* Implement the change */
- ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
-
- /* Enable it if we're using the direct DAC path */
- if (ucontrol->value.integer.value[0] == 1) {
- if (wm8993->class_w_users == 1) {
- dev_dbg(codec->dev, "Enabling Class W\n");
- snd_soc_update_bits(codec, WM8993_CLASS_W_0,
- WM8993_CP_DYN_FREQ |
- WM8993_CP_DYN_V,
- WM8993_CP_DYN_FREQ |
- WM8993_CP_DYN_V);
- }
- wm8993->class_w_users--;
- wm8993->hubs_data.class_w = false;
- }
-
- dev_dbg(codec->dev, "Indirect DAC use count now %d\n",
- wm8993->class_w_users);
-
- return ret;
-}
-
-#define SOC_DAPM_ENUM_W(xname, xenum) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_soc_info_enum_double, \
- .get = snd_soc_dapm_get_enum_double, \
- .put = class_w_put, \
- .private_value = (unsigned long)&xenum }
-
-static const char *hp_mux_text[] = {
- "Mixer",
- "DAC",
-};
-
-static const struct soc_enum hpl_enum =
- SOC_ENUM_SINGLE(WM8993_OUTPUT_MIXER1, 8, 2, hp_mux_text);
-
-static const struct snd_kcontrol_new hpl_mux =
- SOC_DAPM_ENUM_W("Left Headphone Mux", hpl_enum);
-
-static const struct soc_enum hpr_enum =
- SOC_ENUM_SINGLE(WM8993_OUTPUT_MIXER2, 8, 2, hp_mux_text);
-
-static const struct snd_kcontrol_new hpr_mux =
- SOC_DAPM_ENUM_W("Right Headphone Mux", hpr_enum);
-
-static const struct snd_kcontrol_new left_speaker_mixer[] = {
-SOC_DAPM_SINGLE("Input Switch", WM8993_SPEAKER_MIXER, 7, 1, 0),
-SOC_DAPM_SINGLE("IN1LP Switch", WM8993_SPEAKER_MIXER, 5, 1, 0),
-SOC_DAPM_SINGLE("Output Switch", WM8993_SPEAKER_MIXER, 3, 1, 0),
-SOC_DAPM_SINGLE("DAC Switch", WM8993_SPEAKER_MIXER, 6, 1, 0),
-};
-
-static const struct snd_kcontrol_new right_speaker_mixer[] = {
-SOC_DAPM_SINGLE("Input Switch", WM8993_SPEAKER_MIXER, 6, 1, 0),
-SOC_DAPM_SINGLE("IN1RP Switch", WM8993_SPEAKER_MIXER, 4, 1, 0),
-SOC_DAPM_SINGLE("Output Switch", WM8993_SPEAKER_MIXER, 2, 1, 0),
-SOC_DAPM_SINGLE("DAC Switch", WM8993_SPEAKER_MIXER, 0, 1, 0),
-};
-
-static const char *aif_text[] = {
- "Left", "Right"
-};
-
-static const struct soc_enum aifoutl_enum =
- SOC_ENUM_SINGLE(WM8993_AUDIO_INTERFACE_1, 15, 2, aif_text);
-
-static const struct snd_kcontrol_new aifoutl_mux =
- SOC_DAPM_ENUM("AIFOUTL Mux", aifoutl_enum);
-
-static const struct soc_enum aifoutr_enum =
- SOC_ENUM_SINGLE(WM8993_AUDIO_INTERFACE_1, 14, 2, aif_text);
-
-static const struct snd_kcontrol_new aifoutr_mux =
- SOC_DAPM_ENUM("AIFOUTR Mux", aifoutr_enum);
-
-static const struct soc_enum aifinl_enum =
- SOC_ENUM_SINGLE(WM8993_AUDIO_INTERFACE_2, 15, 2, aif_text);
-
-static const struct snd_kcontrol_new aifinl_mux =
- SOC_DAPM_ENUM("AIFINL Mux", aifinl_enum);
-
-static const struct soc_enum aifinr_enum =
- SOC_ENUM_SINGLE(WM8993_AUDIO_INTERFACE_2, 14, 2, aif_text);
-
-static const struct snd_kcontrol_new aifinr_mux =
- SOC_DAPM_ENUM("AIFINR Mux", aifinr_enum);
-
-static const char *sidetone_text[] = {
- "None", "Left", "Right"
-};
-
-static const struct soc_enum sidetonel_enum =
- SOC_ENUM_SINGLE(WM8993_DIGITAL_SIDE_TONE, 2, 3, sidetone_text);
-
-static const struct snd_kcontrol_new sidetonel_mux =
- SOC_DAPM_ENUM("Left Sidetone", sidetonel_enum);
-
-static const struct soc_enum sidetoner_enum =
- SOC_ENUM_SINGLE(WM8993_DIGITAL_SIDE_TONE, 0, 3, sidetone_text);
-
-static const struct snd_kcontrol_new sidetoner_mux =
- SOC_DAPM_ENUM("Right Sidetone", sidetoner_enum);
-
-static const struct snd_soc_dapm_widget wm8993_dapm_widgets[] = {
-SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8993_BUS_CONTROL_1, 1, 0, clk_sys_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-SND_SOC_DAPM_SUPPLY("TOCLK", WM8993_CLOCKING_1, 14, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8993_CLOCKING_3, 0, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_ADC("ADCL", NULL, WM8993_POWER_MANAGEMENT_2, 1, 0),
-SND_SOC_DAPM_ADC("ADCR", NULL, WM8993_POWER_MANAGEMENT_2, 0, 0),
-
-SND_SOC_DAPM_MUX("AIFOUTL Mux", SND_SOC_NOPM, 0, 0, &aifoutl_mux),
-SND_SOC_DAPM_MUX("AIFOUTR Mux", SND_SOC_NOPM, 0, 0, &aifoutr_mux),
-
-SND_SOC_DAPM_AIF_OUT("AIFOUTL", "Capture", 0, SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_AIF_OUT("AIFOUTR", "Capture", 1, SND_SOC_NOPM, 0, 0),
-
-SND_SOC_DAPM_AIF_IN("AIFINL", "Playback", 0, SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_AIF_IN("AIFINR", "Playback", 1, SND_SOC_NOPM, 0, 0),
-
-SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &aifinl_mux),
-SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &aifinr_mux),
-
-SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &sidetonel_mux),
-SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &sidetoner_mux),
-
-SND_SOC_DAPM_DAC("DACL", NULL, WM8993_POWER_MANAGEMENT_3, 1, 0),
-SND_SOC_DAPM_DAC("DACR", NULL, WM8993_POWER_MANAGEMENT_3, 0, 0),
-
-SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
-SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
-
-SND_SOC_DAPM_MIXER("SPKL", WM8993_POWER_MANAGEMENT_3, 8, 0,
- left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
-SND_SOC_DAPM_MIXER("SPKR", WM8993_POWER_MANAGEMENT_3, 9, 0,
- right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
-SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0),
-};
-
-static const struct snd_soc_dapm_route routes[] = {
- { "MICBIAS1", NULL, "VMID" },
- { "MICBIAS2", NULL, "VMID" },
-
- { "ADCL", NULL, "CLK_SYS" },
- { "ADCL", NULL, "CLK_DSP" },
- { "ADCR", NULL, "CLK_SYS" },
- { "ADCR", NULL, "CLK_DSP" },
-
- { "AIFOUTL Mux", "Left", "ADCL" },
- { "AIFOUTL Mux", "Right", "ADCR" },
- { "AIFOUTR Mux", "Left", "ADCL" },
- { "AIFOUTR Mux", "Right", "ADCR" },
-
- { "AIFOUTL", NULL, "AIFOUTL Mux" },
- { "AIFOUTR", NULL, "AIFOUTR Mux" },
-
- { "DACL Mux", "Left", "AIFINL" },
- { "DACL Mux", "Right", "AIFINR" },
- { "DACR Mux", "Left", "AIFINL" },
- { "DACR Mux", "Right", "AIFINR" },
-
- { "DACL Sidetone", "Left", "ADCL" },
- { "DACL Sidetone", "Right", "ADCR" },
- { "DACR Sidetone", "Left", "ADCL" },
- { "DACR Sidetone", "Right", "ADCR" },
-
- { "DACL", NULL, "CLK_SYS" },
- { "DACL", NULL, "CLK_DSP" },
- { "DACL", NULL, "DACL Mux" },
- { "DACL", NULL, "DACL Sidetone" },
- { "DACR", NULL, "CLK_SYS" },
- { "DACR", NULL, "CLK_DSP" },
- { "DACR", NULL, "DACR Mux" },
- { "DACR", NULL, "DACR Sidetone" },
-
- { "Left Output Mixer", "DAC Switch", "DACL" },
-
- { "Right Output Mixer", "DAC Switch", "DACR" },
-
- { "Left Output PGA", NULL, "CLK_SYS" },
-
- { "Right Output PGA", NULL, "CLK_SYS" },
-
- { "SPKL", "DAC Switch", "DACL" },
- { "SPKL", NULL, "CLK_SYS" },
-
- { "SPKR", "DAC Switch", "DACR" },
- { "SPKR", NULL, "CLK_SYS" },
-
- { "Left Headphone Mux", "DAC", "DACL" },
- { "Right Headphone Mux", "DAC", "DACR" },
-};
-
-static int wm8993_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- wm_hubs_set_bias_level(codec, level);
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- case SND_SOC_BIAS_PREPARE:
- /* VMID=2*40k */
- snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
- WM8993_VMID_SEL_MASK, 0x2);
- snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_2,
- WM8993_TSHUT_ENA, WM8993_TSHUT_ENA);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
- wm8993->supplies);
- if (ret != 0)
- return ret;
-
- regcache_cache_only(wm8993->regmap, false);
- regcache_sync(wm8993->regmap);
-
- wm_hubs_vmid_ena(codec);
-
- /* Bring up VMID with fast soft start */
- snd_soc_update_bits(codec, WM8993_ANTIPOP2,
- WM8993_STARTUP_BIAS_ENA |
- WM8993_VMID_BUF_ENA |
- WM8993_VMID_RAMP_MASK |
- WM8993_BIAS_SRC,
- WM8993_STARTUP_BIAS_ENA |
- WM8993_VMID_BUF_ENA |
- WM8993_VMID_RAMP_MASK |
- WM8993_BIAS_SRC);
-
- /* If either line output is single ended we
- * need the VMID buffer */
- if (!wm8993->pdata.lineout1_diff ||
- !wm8993->pdata.lineout2_diff)
- snd_soc_update_bits(codec, WM8993_ANTIPOP1,
- WM8993_LINEOUT_VMID_BUF_ENA,
- WM8993_LINEOUT_VMID_BUF_ENA);
-
- /* VMID=2*40k */
- snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
- WM8993_VMID_SEL_MASK |
- WM8993_BIAS_ENA,
- WM8993_BIAS_ENA | 0x2);
- msleep(32);
-
- /* Switch to normal bias */
- snd_soc_update_bits(codec, WM8993_ANTIPOP2,
- WM8993_BIAS_SRC |
- WM8993_STARTUP_BIAS_ENA, 0);
- }
-
- /* VMID=2*240k */
- snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
- WM8993_VMID_SEL_MASK, 0x4);
-
- snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_2,
- WM8993_TSHUT_ENA, 0);
- break;
-
- case SND_SOC_BIAS_OFF:
- snd_soc_update_bits(codec, WM8993_ANTIPOP1,
- WM8993_LINEOUT_VMID_BUF_ENA, 0);
-
- snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
- WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA,
- 0);
-
- snd_soc_update_bits(codec, WM8993_ANTIPOP2,
- WM8993_STARTUP_BIAS_ENA |
- WM8993_VMID_BUF_ENA |
- WM8993_VMID_RAMP_MASK |
- WM8993_BIAS_SRC, 0);
-
- regcache_cache_only(wm8993->regmap, true);
- regcache_mark_dirty(wm8993->regmap);
-
- regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies),
- wm8993->supplies);
- break;
- }
-
- codec->dapm.bias_level = level;
-
- return 0;
-}
-
-static int wm8993_set_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
-
- switch (clk_id) {
- case WM8993_SYSCLK_MCLK:
- wm8993->mclk_rate = freq;
- case WM8993_SYSCLK_FLL:
- wm8993->sysclk_source = clk_id;
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
- unsigned int aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1);
- unsigned int aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4);
-
- aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV |
- WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK);
- aif4 &= ~WM8993_LRCLK_DIR;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- wm8993->master = 0;
- break;
- case SND_SOC_DAIFMT_CBS_CFM:
- aif4 |= WM8993_LRCLK_DIR;
- wm8993->master = 1;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- aif1 |= WM8993_BCLK_DIR;
- wm8993->master = 1;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- aif1 |= WM8993_BCLK_DIR;
- aif4 |= WM8993_LRCLK_DIR;
- wm8993->master = 1;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_B:
- aif1 |= WM8993_AIF_LRCLK_INV;
- case SND_SOC_DAIFMT_DSP_A:
- aif1 |= 0x18;
- break;
- case SND_SOC_DAIFMT_I2S:
- aif1 |= 0x10;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- aif1 |= 0x8;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- case SND_SOC_DAIFMT_DSP_B:
- /* frame inversion not valid for DSP modes */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_NF:
- aif1 |= WM8993_AIF_BCLK_INV;
- break;
- default:
- return -EINVAL;
- }
- break;
-
- case SND_SOC_DAIFMT_I2S:
- case SND_SOC_DAIFMT_RIGHT_J:
- case SND_SOC_DAIFMT_LEFT_J:
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- aif1 |= WM8993_AIF_BCLK_INV | WM8993_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- aif1 |= WM8993_AIF_BCLK_INV;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- aif1 |= WM8993_AIF_LRCLK_INV;
- break;
- default:
- return -EINVAL;
- }
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM8993_AUDIO_INTERFACE_1, aif1);
- snd_soc_write(codec, WM8993_AUDIO_INTERFACE_4, aif4);
-
- return 0;
-}
-
-static int wm8993_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
- int ret, i, best, best_val, cur_val;
- unsigned int clocking1, clocking3, aif1, aif4;
-
- clocking1 = snd_soc_read(codec, WM8993_CLOCKING_1);
- clocking1 &= ~WM8993_BCLK_DIV_MASK;
-
- clocking3 = snd_soc_read(codec, WM8993_CLOCKING_3);
- clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK);
-
- aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1);
- aif1 &= ~WM8993_AIF_WL_MASK;
-
- aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4);
- aif4 &= ~WM8993_LRCLK_RATE_MASK;
-
- /* What BCLK do we need? */
- wm8993->fs = params_rate(params);
- wm8993->bclk = 2 * wm8993->fs;
- if (wm8993->tdm_slots) {
- dev_dbg(codec->dev, "Configuring for %d %d bit TDM slots\n",
- wm8993->tdm_slots, wm8993->tdm_width);
- wm8993->bclk *= wm8993->tdm_width * wm8993->tdm_slots;
- } else {
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- wm8993->bclk *= 16;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- wm8993->bclk *= 20;
- aif1 |= 0x8;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- wm8993->bclk *= 24;
- aif1 |= 0x10;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- wm8993->bclk *= 32;
- aif1 |= 0x18;
- break;
- default:
- return -EINVAL;
- }
- }
-
- dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm8993->bclk);
-
- ret = configure_clock(codec);
- if (ret != 0)
- return ret;
-
- /* Select nearest CLK_SYS_RATE */
- best = 0;
- best_val = abs((wm8993->sysclk_rate / clk_sys_rates[0].ratio)
- - wm8993->fs);
- for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
- cur_val = abs((wm8993->sysclk_rate /
- clk_sys_rates[i].ratio) - wm8993->fs);
- if (cur_val < best_val) {
- best = i;
- best_val = cur_val;
- }
- }
- dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n",
- clk_sys_rates[best].ratio);
- clocking3 |= (clk_sys_rates[best].clk_sys_rate
- << WM8993_CLK_SYS_RATE_SHIFT);
-
- /* SAMPLE_RATE */
- best = 0;
- best_val = abs(wm8993->fs - sample_rates[0].rate);
- for (i = 1; i < ARRAY_SIZE(sample_rates); i++) {
- /* Closest match */
- cur_val = abs(wm8993->fs - sample_rates[i].rate);
- if (cur_val < best_val) {
- best = i;
- best_val = cur_val;
- }
- }
- dev_dbg(codec->dev, "Selected SAMPLE_RATE of %dHz\n",
- sample_rates[best].rate);
- clocking3 |= (sample_rates[best].sample_rate
- << WM8993_SAMPLE_RATE_SHIFT);
-
- /* BCLK_DIV */
- best = 0;
- best_val = INT_MAX;
- for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
- cur_val = ((wm8993->sysclk_rate * 10) / bclk_divs[i].div)
- - wm8993->bclk;
- if (cur_val < 0) /* Table is sorted */
- break;
- if (cur_val < best_val) {
- best = i;
- best_val = cur_val;
- }
- }
- wm8993->bclk = (wm8993->sysclk_rate * 10) / bclk_divs[best].div;
- dev_dbg(codec->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n",
- bclk_divs[best].div, wm8993->bclk);
- clocking1 |= bclk_divs[best].bclk_div << WM8993_BCLK_DIV_SHIFT;
-
- /* LRCLK is a simple fraction of BCLK */
- dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8993->bclk / wm8993->fs);
- aif4 |= wm8993->bclk / wm8993->fs;
-
- snd_soc_write(codec, WM8993_CLOCKING_1, clocking1);
- snd_soc_write(codec, WM8993_CLOCKING_3, clocking3);
- snd_soc_write(codec, WM8993_AUDIO_INTERFACE_1, aif1);
- snd_soc_write(codec, WM8993_AUDIO_INTERFACE_4, aif4);
-
- /* ReTune Mobile? */
- if (wm8993->pdata.num_retune_configs) {
- u16 eq1 = snd_soc_read(codec, WM8993_EQ1);
- struct wm8993_retune_mobile_setting *s;
-
- best = 0;
- best_val = abs(wm8993->pdata.retune_configs[0].rate
- - wm8993->fs);
- for (i = 0; i < wm8993->pdata.num_retune_configs; i++) {
- cur_val = abs(wm8993->pdata.retune_configs[i].rate
- - wm8993->fs);
- if (cur_val < best_val) {
- best_val = cur_val;
- best = i;
- }
- }
- s = &wm8993->pdata.retune_configs[best];
-
- dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n",
- s->name, s->rate);
-
- /* Disable EQ while we reconfigure */
- snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, 0);
-
- for (i = 1; i < ARRAY_SIZE(s->config); i++)
- snd_soc_write(codec, WM8993_EQ1 + i, s->config[i]);
-
- snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, eq1);
- }
-
- return 0;
-}
-
-static int wm8993_digital_mute(struct snd_soc_dai *codec_dai, int mute)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- unsigned int reg;
-
- reg = snd_soc_read(codec, WM8993_DAC_CTRL);
-
- if (mute)
- reg |= WM8993_DAC_MUTE;
- else
- reg &= ~WM8993_DAC_MUTE;
-
- snd_soc_write(codec, WM8993_DAC_CTRL, reg);
-
- return 0;
-}
-
-static int wm8993_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
- unsigned int rx_mask, int slots, int slot_width)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
- int aif1 = 0;
- int aif2 = 0;
-
- /* Don't need to validate anything if we're turning off TDM */
- if (slots == 0) {
- wm8993->tdm_slots = 0;
- goto out;
- }
-
- /* Note that we allow configurations we can't handle ourselves -
- * for example, we can generate clocks for slots 2 and up even if
- * we can't use those slots ourselves.
- */
- aif1 |= WM8993_AIFADC_TDM;
- aif2 |= WM8993_AIFDAC_TDM;
-
- switch (rx_mask) {
- case 3:
- break;
- case 0xc:
- aif1 |= WM8993_AIFADC_TDM_CHAN;
- break;
- default:
- return -EINVAL;
- }
-
-
- switch (tx_mask) {
- case 3:
- break;
- case 0xc:
- aif2 |= WM8993_AIFDAC_TDM_CHAN;
- break;
- default:
- return -EINVAL;
- }
-
-out:
- wm8993->tdm_width = slot_width;
- wm8993->tdm_slots = slots / 2;
-
- snd_soc_update_bits(codec, WM8993_AUDIO_INTERFACE_1,
- WM8993_AIFADC_TDM | WM8993_AIFADC_TDM_CHAN, aif1);
- snd_soc_update_bits(codec, WM8993_AUDIO_INTERFACE_2,
- WM8993_AIFDAC_TDM | WM8993_AIFDAC_TDM_CHAN, aif2);
-
- return 0;
-}
-
-static irqreturn_t wm8993_irq(int irq, void *data)
-{
- struct wm8993_priv *wm8993 = data;
- int mask, val, ret;
-
- ret = regmap_read(wm8993->regmap, WM8993_GPIO_CTRL_1, &val);
- if (ret != 0) {
- dev_err(wm8993->dev, "Failed to read interrupt status: %d\n",
- ret);
- return IRQ_NONE;
- }
-
- ret = regmap_read(wm8993->regmap, WM8993_GPIOCTRL_2, &mask);
- if (ret != 0) {
- dev_err(wm8993->dev, "Failed to read interrupt mask: %d\n",
- ret);
- return IRQ_NONE;
- }
-
- /* The IRQ pin status is visible in the register too */
- val &= ~(mask | WM8993_IRQ);
- if (!val)
- return IRQ_NONE;
-
- if (val & WM8993_TEMPOK_EINT)
- dev_crit(wm8993->dev, "Thermal warning\n");
-
- if (val & WM8993_FLL_LOCK_EINT) {
- dev_dbg(wm8993->dev, "FLL locked\n");
- complete(&wm8993->fll_lock);
- }
-
- ret = regmap_write(wm8993->regmap, WM8993_GPIO_CTRL_1, val);
- if (ret != 0)
- dev_err(wm8993->dev, "Failed to ack interrupt: %d\n", ret);
-
- return IRQ_HANDLED;
-}
-
-static const struct snd_soc_dai_ops wm8993_ops = {
- .set_sysclk = wm8993_set_sysclk,
- .set_fmt = wm8993_set_dai_fmt,
- .hw_params = wm8993_hw_params,
- .digital_mute = wm8993_digital_mute,
- .set_pll = wm8993_set_fll,
- .set_tdm_slot = wm8993_set_tdm_slot,
-};
-
-#define WM8993_RATES SNDRV_PCM_RATE_8000_48000
-
-#define WM8993_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
- SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE |\
- SNDRV_PCM_FMTBIT_S32_LE)
-
-static struct snd_soc_dai_driver wm8993_dai = {
- .name = "wm8993-hifi",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8993_RATES,
- .formats = WM8993_FORMATS,
- .sig_bits = 24,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8993_RATES,
- .formats = WM8993_FORMATS,
- .sig_bits = 24,
- },
- .ops = &wm8993_ops,
- .symmetric_rates = 1,
-};
-
-static int wm8993_probe(struct snd_soc_codec *codec)
-{
- struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret;
-
- wm8993->hubs_data.hp_startup_mode = 1;
- wm8993->hubs_data.dcs_codes_l = -2;
- wm8993->hubs_data.dcs_codes_r = -2;
- wm8993->hubs_data.series_startup = 1;
-
- codec->control_data = wm8993->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- /* By default we're using the output mixers */
- wm8993->class_w_users = 2;
-
- /* Latch volume update bits and default ZC on */
- snd_soc_update_bits(codec, WM8993_RIGHT_DAC_DIGITAL_VOLUME,
- WM8993_DAC_VU, WM8993_DAC_VU);
- snd_soc_update_bits(codec, WM8993_RIGHT_ADC_DIGITAL_VOLUME,
- WM8993_ADC_VU, WM8993_ADC_VU);
-
- /* Manualy manage the HPOUT sequencing for independent stereo
- * control. */
- snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
- WM8993_HPOUT1_AUTO_PU, 0);
-
- /* Use automatic clock configuration */
- snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0);
-
- wm_hubs_handle_analogue_pdata(codec, wm8993->pdata.lineout1_diff,
- wm8993->pdata.lineout2_diff,
- wm8993->pdata.lineout1fb,
- wm8993->pdata.lineout2fb,
- wm8993->pdata.jd_scthr,
- wm8993->pdata.jd_thr,
- wm8993->pdata.micbias1_lvl,
- wm8993->pdata.micbias2_lvl);
-
- ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- if (ret != 0)
- return ret;
-
- snd_soc_add_codec_controls(codec, wm8993_snd_controls,
- ARRAY_SIZE(wm8993_snd_controls));
- if (wm8993->pdata.num_retune_configs != 0) {
- dev_dbg(codec->dev, "Using ReTune Mobile\n");
- } else {
- dev_dbg(codec->dev, "No ReTune Mobile, using normal EQ\n");
- snd_soc_add_codec_controls(codec, wm8993_eq_controls,
- ARRAY_SIZE(wm8993_eq_controls));
- }
-
- snd_soc_dapm_new_controls(dapm, wm8993_dapm_widgets,
- ARRAY_SIZE(wm8993_dapm_widgets));
- wm_hubs_add_analogue_controls(codec);
-
- snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
- wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff,
- wm8993->pdata.lineout2_diff);
-
- /* If the line outputs are differential then we aren't presenting
- * VMID as an output and can disable it.
- */
- if (wm8993->pdata.lineout1_diff && wm8993->pdata.lineout2_diff)
- codec->dapm.idle_bias_off = 1;
-
- return 0;
-
-}
-
-static int wm8993_remove(struct snd_soc_codec *codec)
-{
- struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
-
- wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
- regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int wm8993_suspend(struct snd_soc_codec *codec)
-{
- struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
- int fll_fout = wm8993->fll_fout;
- int fll_fref = wm8993->fll_fref;
- int ret;
-
- /* Stop the FLL in an orderly fashion */
- ret = _wm8993_set_fll(codec, 0, 0, 0, 0);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to stop FLL\n");
- return ret;
- }
-
- wm8993->fll_fout = fll_fout;
- wm8993->fll_fref = fll_fref;
-
- wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int wm8993_resume(struct snd_soc_codec *codec)
-{
- struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* Restart the FLL? */
- if (wm8993->fll_fout) {
- int fll_fout = wm8993->fll_fout;
- int fll_fref = wm8993->fll_fref;
-
- wm8993->fll_fref = 0;
- wm8993->fll_fout = 0;
-
- ret = _wm8993_set_fll(codec, 0, wm8993->fll_src,
- fll_fref, fll_fout);
- if (ret != 0)
- dev_err(codec->dev, "Failed to restart FLL\n");
- }
-
- return 0;
-}
-#else
-#define wm8993_suspend NULL
-#define wm8993_resume NULL
-#endif
-
-/* Tune DC servo configuration */
-static struct reg_default wm8993_regmap_patch[] = {
- { 0x44, 3 },
- { 0x56, 3 },
- { 0x44, 0 },
-};
-
-static const struct regmap_config wm8993_regmap = {
- .reg_bits = 8,
- .val_bits = 16,
-
- .max_register = WM8993_MAX_REGISTER,
- .volatile_reg = wm8993_volatile,
- .readable_reg = wm8993_readable,
-
- .cache_type = REGCACHE_RBTREE,
- .reg_defaults = wm8993_reg_defaults,
- .num_reg_defaults = ARRAY_SIZE(wm8993_reg_defaults),
-};
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8993 = {
- .probe = wm8993_probe,
- .remove = wm8993_remove,
- .suspend = wm8993_suspend,
- .resume = wm8993_resume,
- .set_bias_level = wm8993_set_bias_level,
-};
-
-static __devinit int wm8993_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8993_priv *wm8993;
- unsigned int reg;
- int ret, i;
-
- wm8993 = devm_kzalloc(&i2c->dev, sizeof(struct wm8993_priv),
- GFP_KERNEL);
- if (wm8993 == NULL)
- return -ENOMEM;
-
- wm8993->dev = &i2c->dev;
- init_completion(&wm8993->fll_lock);
-
- wm8993->regmap = regmap_init_i2c(i2c, &wm8993_regmap);
- if (IS_ERR(wm8993->regmap)) {
- ret = PTR_ERR(wm8993->regmap);
- dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
- return ret;
- }
-
- i2c_set_clientdata(i2c, wm8993);
-
- for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++)
- wm8993->supplies[i].supply = wm8993_supply_names[i];
-
- ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8993->supplies),
- wm8993->supplies);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
- goto err;
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
- wm8993->supplies);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
- goto err_get;
- }
-
- ret = regmap_read(wm8993->regmap, WM8993_SOFTWARE_RESET, &reg);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret);
- goto err_enable;
- }
-
- if (reg != 0x8993) {
- dev_err(&i2c->dev, "Invalid ID register value %x\n", reg);
- ret = -EINVAL;
- goto err_enable;
- }
-
- ret = regmap_write(wm8993->regmap, WM8993_SOFTWARE_RESET, 0xffff);
- if (ret != 0)
- goto err_enable;
-
- ret = regmap_register_patch(wm8993->regmap, wm8993_regmap_patch,
- ARRAY_SIZE(wm8993_regmap_patch));
- if (ret != 0)
- dev_warn(wm8993->dev, "Failed to apply regmap patch: %d\n",
- ret);
-
- if (i2c->irq) {
- /* Put GPIO1 into interrupt mode (only GPIO1 can output IRQ) */
- ret = regmap_update_bits(wm8993->regmap, WM8993_GPIO1,
- WM8993_GPIO1_PD |
- WM8993_GPIO1_SEL_MASK, 7);
- if (ret != 0)
- goto err_enable;
-
- ret = request_threaded_irq(i2c->irq, NULL, wm8993_irq,
- IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
- "wm8993", wm8993);
- if (ret != 0)
- goto err_enable;
-
- }
-
- regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
-
- regcache_cache_only(wm8993->regmap, true);
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8993, &wm8993_dai, 1);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
- goto err_irq;
- }
-
- return 0;
-
-err_irq:
- if (i2c->irq)
- free_irq(i2c->irq, wm8993);
-err_enable:
- regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
-err_get:
- regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
-err:
- regmap_exit(wm8993->regmap);
- return ret;
-}
-
-static __devexit int wm8993_i2c_remove(struct i2c_client *i2c)
-{
- struct wm8993_priv *wm8993 = i2c_get_clientdata(i2c);
-
- snd_soc_unregister_codec(&i2c->dev);
- if (i2c->irq)
- free_irq(i2c->irq, wm8993);
- regmap_exit(wm8993->regmap);
- regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
- regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
-
- return 0;
-}
-
-static const struct i2c_device_id wm8993_i2c_id[] = {
- { "wm8993", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8993_i2c_id);
-
-static struct i2c_driver wm8993_i2c_driver = {
- .driver = {
- .name = "wm8993",
- .owner = THIS_MODULE,
- },
- .probe = wm8993_i2c_probe,
- .remove = __devexit_p(wm8993_i2c_remove),
- .id_table = wm8993_i2c_id,
-};
-
-module_i2c_driver(wm8993_i2c_driver);
-
-MODULE_DESCRIPTION("ASoC WM8993 driver");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8993.h b/ANDROID_3.4.5/sound/soc/codecs/wm8993.h
deleted file mode 100644
index 4478b40c..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8993.h
+++ /dev/null
@@ -1,2138 +0,0 @@
-#ifndef WM8993_H
-#define WM8993_H
-
-#define WM8993_SYSCLK_MCLK 1
-#define WM8993_SYSCLK_FLL 2
-
-#define WM8993_FLL_MCLK 1
-#define WM8993_FLL_BCLK 2
-#define WM8993_FLL_LRCLK 3
-
-/*
- * Register values.
- */
-#define WM8993_SOFTWARE_RESET 0x00
-#define WM8993_POWER_MANAGEMENT_1 0x01
-#define WM8993_POWER_MANAGEMENT_2 0x02
-#define WM8993_POWER_MANAGEMENT_3 0x03
-#define WM8993_AUDIO_INTERFACE_1 0x04
-#define WM8993_AUDIO_INTERFACE_2 0x05
-#define WM8993_CLOCKING_1 0x06
-#define WM8993_CLOCKING_2 0x07
-#define WM8993_AUDIO_INTERFACE_3 0x08
-#define WM8993_AUDIO_INTERFACE_4 0x09
-#define WM8993_DAC_CTRL 0x0A
-#define WM8993_LEFT_DAC_DIGITAL_VOLUME 0x0B
-#define WM8993_RIGHT_DAC_DIGITAL_VOLUME 0x0C
-#define WM8993_DIGITAL_SIDE_TONE 0x0D
-#define WM8993_ADC_CTRL 0x0E
-#define WM8993_LEFT_ADC_DIGITAL_VOLUME 0x0F
-#define WM8993_RIGHT_ADC_DIGITAL_VOLUME 0x10
-#define WM8993_GPIO_CTRL_1 0x12
-#define WM8993_GPIO1 0x13
-#define WM8993_IRQ_DEBOUNCE 0x14
-#define WM8993_INPUTS_CLAMP_REG 0x15
-#define WM8993_GPIOCTRL_2 0x16
-#define WM8993_GPIO_POL 0x17
-#define WM8993_LEFT_LINE_INPUT_1_2_VOLUME 0x18
-#define WM8993_LEFT_LINE_INPUT_3_4_VOLUME 0x19
-#define WM8993_RIGHT_LINE_INPUT_1_2_VOLUME 0x1A
-#define WM8993_RIGHT_LINE_INPUT_3_4_VOLUME 0x1B
-#define WM8993_LEFT_OUTPUT_VOLUME 0x1C
-#define WM8993_RIGHT_OUTPUT_VOLUME 0x1D
-#define WM8993_LINE_OUTPUTS_VOLUME 0x1E
-#define WM8993_HPOUT2_VOLUME 0x1F
-#define WM8993_LEFT_OPGA_VOLUME 0x20
-#define WM8993_RIGHT_OPGA_VOLUME 0x21
-#define WM8993_SPKMIXL_ATTENUATION 0x22
-#define WM8993_SPKMIXR_ATTENUATION 0x23
-#define WM8993_SPKOUT_MIXERS 0x24
-#define WM8993_SPKOUT_BOOST 0x25
-#define WM8993_SPEAKER_VOLUME_LEFT 0x26
-#define WM8993_SPEAKER_VOLUME_RIGHT 0x27
-#define WM8993_INPUT_MIXER2 0x28
-#define WM8993_INPUT_MIXER3 0x29
-#define WM8993_INPUT_MIXER4 0x2A
-#define WM8993_INPUT_MIXER5 0x2B
-#define WM8993_INPUT_MIXER6 0x2C
-#define WM8993_OUTPUT_MIXER1 0x2D
-#define WM8993_OUTPUT_MIXER2 0x2E
-#define WM8993_OUTPUT_MIXER3 0x2F
-#define WM8993_OUTPUT_MIXER4 0x30
-#define WM8993_OUTPUT_MIXER5 0x31
-#define WM8993_OUTPUT_MIXER6 0x32
-#define WM8993_HPOUT2_MIXER 0x33
-#define WM8993_LINE_MIXER1 0x34
-#define WM8993_LINE_MIXER2 0x35
-#define WM8993_SPEAKER_MIXER 0x36
-#define WM8993_ADDITIONAL_CONTROL 0x37
-#define WM8993_ANTIPOP1 0x38
-#define WM8993_ANTIPOP2 0x39
-#define WM8993_MICBIAS 0x3A
-#define WM8993_FLL_CONTROL_1 0x3C
-#define WM8993_FLL_CONTROL_2 0x3D
-#define WM8993_FLL_CONTROL_3 0x3E
-#define WM8993_FLL_CONTROL_4 0x3F
-#define WM8993_FLL_CONTROL_5 0x40
-#define WM8993_CLOCKING_3 0x41
-#define WM8993_CLOCKING_4 0x42
-#define WM8993_MW_SLAVE_CONTROL 0x43
-#define WM8993_BUS_CONTROL_1 0x45
-#define WM8993_WRITE_SEQUENCER_0 0x46
-#define WM8993_WRITE_SEQUENCER_1 0x47
-#define WM8993_WRITE_SEQUENCER_2 0x48
-#define WM8993_WRITE_SEQUENCER_3 0x49
-#define WM8993_WRITE_SEQUENCER_4 0x4A
-#define WM8993_WRITE_SEQUENCER_5 0x4B
-#define WM8993_CHARGE_PUMP_1 0x4C
-#define WM8993_CLASS_W_0 0x51
-#define WM8993_DC_SERVO_0 0x54
-#define WM8993_DC_SERVO_1 0x55
-#define WM8993_DC_SERVO_3 0x57
-#define WM8993_DC_SERVO_READBACK_0 0x58
-#define WM8993_DC_SERVO_READBACK_1 0x59
-#define WM8993_DC_SERVO_READBACK_2 0x5A
-#define WM8993_ANALOGUE_HP_0 0x60
-#define WM8993_EQ1 0x62
-#define WM8993_EQ2 0x63
-#define WM8993_EQ3 0x64
-#define WM8993_EQ4 0x65
-#define WM8993_EQ5 0x66
-#define WM8993_EQ6 0x67
-#define WM8993_EQ7 0x68
-#define WM8993_EQ8 0x69
-#define WM8993_EQ9 0x6A
-#define WM8993_EQ10 0x6B
-#define WM8993_EQ11 0x6C
-#define WM8993_EQ12 0x6D
-#define WM8993_EQ13 0x6E
-#define WM8993_EQ14 0x6F
-#define WM8993_EQ15 0x70
-#define WM8993_EQ16 0x71
-#define WM8993_EQ17 0x72
-#define WM8993_EQ18 0x73
-#define WM8993_EQ19 0x74
-#define WM8993_EQ20 0x75
-#define WM8993_EQ21 0x76
-#define WM8993_EQ22 0x77
-#define WM8993_EQ23 0x78
-#define WM8993_EQ24 0x79
-#define WM8993_DIGITAL_PULLS 0x7A
-#define WM8993_DRC_CONTROL_1 0x7B
-#define WM8993_DRC_CONTROL_2 0x7C
-#define WM8993_DRC_CONTROL_3 0x7D
-#define WM8993_DRC_CONTROL_4 0x7E
-
-#define WM8993_REGISTER_COUNT 0x7F
-#define WM8993_MAX_REGISTER 0x7E
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - Software Reset
- */
-#define WM8993_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
-#define WM8993_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
-#define WM8993_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
-
-/*
- * R1 (0x01) - Power Management (1)
- */
-#define WM8993_SPKOUTR_ENA 0x2000 /* SPKOUTR_ENA */
-#define WM8993_SPKOUTR_ENA_MASK 0x2000 /* SPKOUTR_ENA */
-#define WM8993_SPKOUTR_ENA_SHIFT 13 /* SPKOUTR_ENA */
-#define WM8993_SPKOUTR_ENA_WIDTH 1 /* SPKOUTR_ENA */
-#define WM8993_SPKOUTL_ENA 0x1000 /* SPKOUTL_ENA */
-#define WM8993_SPKOUTL_ENA_MASK 0x1000 /* SPKOUTL_ENA */
-#define WM8993_SPKOUTL_ENA_SHIFT 12 /* SPKOUTL_ENA */
-#define WM8993_SPKOUTL_ENA_WIDTH 1 /* SPKOUTL_ENA */
-#define WM8993_HPOUT2_ENA 0x0800 /* HPOUT2_ENA */
-#define WM8993_HPOUT2_ENA_MASK 0x0800 /* HPOUT2_ENA */
-#define WM8993_HPOUT2_ENA_SHIFT 11 /* HPOUT2_ENA */
-#define WM8993_HPOUT2_ENA_WIDTH 1 /* HPOUT2_ENA */
-#define WM8993_HPOUT1L_ENA 0x0200 /* HPOUT1L_ENA */
-#define WM8993_HPOUT1L_ENA_MASK 0x0200 /* HPOUT1L_ENA */
-#define WM8993_HPOUT1L_ENA_SHIFT 9 /* HPOUT1L_ENA */
-#define WM8993_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */
-#define WM8993_HPOUT1R_ENA 0x0100 /* HPOUT1R_ENA */
-#define WM8993_HPOUT1R_ENA_MASK 0x0100 /* HPOUT1R_ENA */
-#define WM8993_HPOUT1R_ENA_SHIFT 8 /* HPOUT1R_ENA */
-#define WM8993_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */
-#define WM8993_MICB2_ENA 0x0020 /* MICB2_ENA */
-#define WM8993_MICB2_ENA_MASK 0x0020 /* MICB2_ENA */
-#define WM8993_MICB2_ENA_SHIFT 5 /* MICB2_ENA */
-#define WM8993_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
-#define WM8993_MICB1_ENA 0x0010 /* MICB1_ENA */
-#define WM8993_MICB1_ENA_MASK 0x0010 /* MICB1_ENA */
-#define WM8993_MICB1_ENA_SHIFT 4 /* MICB1_ENA */
-#define WM8993_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
-#define WM8993_VMID_SEL_MASK 0x0006 /* VMID_SEL - [2:1] */
-#define WM8993_VMID_SEL_SHIFT 1 /* VMID_SEL - [2:1] */
-#define WM8993_VMID_SEL_WIDTH 2 /* VMID_SEL - [2:1] */
-#define WM8993_BIAS_ENA 0x0001 /* BIAS_ENA */
-#define WM8993_BIAS_ENA_MASK 0x0001 /* BIAS_ENA */
-#define WM8993_BIAS_ENA_SHIFT 0 /* BIAS_ENA */
-#define WM8993_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
-
-/*
- * R2 (0x02) - Power Management (2)
- */
-#define WM8993_TSHUT_ENA 0x4000 /* TSHUT_ENA */
-#define WM8993_TSHUT_ENA_MASK 0x4000 /* TSHUT_ENA */
-#define WM8993_TSHUT_ENA_SHIFT 14 /* TSHUT_ENA */
-#define WM8993_TSHUT_ENA_WIDTH 1 /* TSHUT_ENA */
-#define WM8993_TSHUT_OPDIS 0x2000 /* TSHUT_OPDIS */
-#define WM8993_TSHUT_OPDIS_MASK 0x2000 /* TSHUT_OPDIS */
-#define WM8993_TSHUT_OPDIS_SHIFT 13 /* TSHUT_OPDIS */
-#define WM8993_TSHUT_OPDIS_WIDTH 1 /* TSHUT_OPDIS */
-#define WM8993_OPCLK_ENA 0x0800 /* OPCLK_ENA */
-#define WM8993_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */
-#define WM8993_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */
-#define WM8993_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
-#define WM8993_MIXINL_ENA 0x0200 /* MIXINL_ENA */
-#define WM8993_MIXINL_ENA_MASK 0x0200 /* MIXINL_ENA */
-#define WM8993_MIXINL_ENA_SHIFT 9 /* MIXINL_ENA */
-#define WM8993_MIXINL_ENA_WIDTH 1 /* MIXINL_ENA */
-#define WM8993_MIXINR_ENA 0x0100 /* MIXINR_ENA */
-#define WM8993_MIXINR_ENA_MASK 0x0100 /* MIXINR_ENA */
-#define WM8993_MIXINR_ENA_SHIFT 8 /* MIXINR_ENA */
-#define WM8993_MIXINR_ENA_WIDTH 1 /* MIXINR_ENA */
-#define WM8993_IN2L_ENA 0x0080 /* IN2L_ENA */
-#define WM8993_IN2L_ENA_MASK 0x0080 /* IN2L_ENA */
-#define WM8993_IN2L_ENA_SHIFT 7 /* IN2L_ENA */
-#define WM8993_IN2L_ENA_WIDTH 1 /* IN2L_ENA */
-#define WM8993_IN1L_ENA 0x0040 /* IN1L_ENA */
-#define WM8993_IN1L_ENA_MASK 0x0040 /* IN1L_ENA */
-#define WM8993_IN1L_ENA_SHIFT 6 /* IN1L_ENA */
-#define WM8993_IN1L_ENA_WIDTH 1 /* IN1L_ENA */
-#define WM8993_IN2R_ENA 0x0020 /* IN2R_ENA */
-#define WM8993_IN2R_ENA_MASK 0x0020 /* IN2R_ENA */
-#define WM8993_IN2R_ENA_SHIFT 5 /* IN2R_ENA */
-#define WM8993_IN2R_ENA_WIDTH 1 /* IN2R_ENA */
-#define WM8993_IN1R_ENA 0x0010 /* IN1R_ENA */
-#define WM8993_IN1R_ENA_MASK 0x0010 /* IN1R_ENA */
-#define WM8993_IN1R_ENA_SHIFT 4 /* IN1R_ENA */
-#define WM8993_IN1R_ENA_WIDTH 1 /* IN1R_ENA */
-#define WM8993_ADCL_ENA 0x0002 /* ADCL_ENA */
-#define WM8993_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
-#define WM8993_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
-#define WM8993_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
-#define WM8993_ADCR_ENA 0x0001 /* ADCR_ENA */
-#define WM8993_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
-#define WM8993_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
-#define WM8993_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
-
-/*
- * R3 (0x03) - Power Management (3)
- */
-#define WM8993_LINEOUT1N_ENA 0x2000 /* LINEOUT1N_ENA */
-#define WM8993_LINEOUT1N_ENA_MASK 0x2000 /* LINEOUT1N_ENA */
-#define WM8993_LINEOUT1N_ENA_SHIFT 13 /* LINEOUT1N_ENA */
-#define WM8993_LINEOUT1N_ENA_WIDTH 1 /* LINEOUT1N_ENA */
-#define WM8993_LINEOUT1P_ENA 0x1000 /* LINEOUT1P_ENA */
-#define WM8993_LINEOUT1P_ENA_MASK 0x1000 /* LINEOUT1P_ENA */
-#define WM8993_LINEOUT1P_ENA_SHIFT 12 /* LINEOUT1P_ENA */
-#define WM8993_LINEOUT1P_ENA_WIDTH 1 /* LINEOUT1P_ENA */
-#define WM8993_LINEOUT2N_ENA 0x0800 /* LINEOUT2N_ENA */
-#define WM8993_LINEOUT2N_ENA_MASK 0x0800 /* LINEOUT2N_ENA */
-#define WM8993_LINEOUT2N_ENA_SHIFT 11 /* LINEOUT2N_ENA */
-#define WM8993_LINEOUT2N_ENA_WIDTH 1 /* LINEOUT2N_ENA */
-#define WM8993_LINEOUT2P_ENA 0x0400 /* LINEOUT2P_ENA */
-#define WM8993_LINEOUT2P_ENA_MASK 0x0400 /* LINEOUT2P_ENA */
-#define WM8993_LINEOUT2P_ENA_SHIFT 10 /* LINEOUT2P_ENA */
-#define WM8993_LINEOUT2P_ENA_WIDTH 1 /* LINEOUT2P_ENA */
-#define WM8993_SPKRVOL_ENA 0x0200 /* SPKRVOL_ENA */
-#define WM8993_SPKRVOL_ENA_MASK 0x0200 /* SPKRVOL_ENA */
-#define WM8993_SPKRVOL_ENA_SHIFT 9 /* SPKRVOL_ENA */
-#define WM8993_SPKRVOL_ENA_WIDTH 1 /* SPKRVOL_ENA */
-#define WM8993_SPKLVOL_ENA 0x0100 /* SPKLVOL_ENA */
-#define WM8993_SPKLVOL_ENA_MASK 0x0100 /* SPKLVOL_ENA */
-#define WM8993_SPKLVOL_ENA_SHIFT 8 /* SPKLVOL_ENA */
-#define WM8993_SPKLVOL_ENA_WIDTH 1 /* SPKLVOL_ENA */
-#define WM8993_MIXOUTLVOL_ENA 0x0080 /* MIXOUTLVOL_ENA */
-#define WM8993_MIXOUTLVOL_ENA_MASK 0x0080 /* MIXOUTLVOL_ENA */
-#define WM8993_MIXOUTLVOL_ENA_SHIFT 7 /* MIXOUTLVOL_ENA */
-#define WM8993_MIXOUTLVOL_ENA_WIDTH 1 /* MIXOUTLVOL_ENA */
-#define WM8993_MIXOUTRVOL_ENA 0x0040 /* MIXOUTRVOL_ENA */
-#define WM8993_MIXOUTRVOL_ENA_MASK 0x0040 /* MIXOUTRVOL_ENA */
-#define WM8993_MIXOUTRVOL_ENA_SHIFT 6 /* MIXOUTRVOL_ENA */
-#define WM8993_MIXOUTRVOL_ENA_WIDTH 1 /* MIXOUTRVOL_ENA */
-#define WM8993_MIXOUTL_ENA 0x0020 /* MIXOUTL_ENA */
-#define WM8993_MIXOUTL_ENA_MASK 0x0020 /* MIXOUTL_ENA */
-#define WM8993_MIXOUTL_ENA_SHIFT 5 /* MIXOUTL_ENA */
-#define WM8993_MIXOUTL_ENA_WIDTH 1 /* MIXOUTL_ENA */
-#define WM8993_MIXOUTR_ENA 0x0010 /* MIXOUTR_ENA */
-#define WM8993_MIXOUTR_ENA_MASK 0x0010 /* MIXOUTR_ENA */
-#define WM8993_MIXOUTR_ENA_SHIFT 4 /* MIXOUTR_ENA */
-#define WM8993_MIXOUTR_ENA_WIDTH 1 /* MIXOUTR_ENA */
-#define WM8993_DACL_ENA 0x0002 /* DACL_ENA */
-#define WM8993_DACL_ENA_MASK 0x0002 /* DACL_ENA */
-#define WM8993_DACL_ENA_SHIFT 1 /* DACL_ENA */
-#define WM8993_DACL_ENA_WIDTH 1 /* DACL_ENA */
-#define WM8993_DACR_ENA 0x0001 /* DACR_ENA */
-#define WM8993_DACR_ENA_MASK 0x0001 /* DACR_ENA */
-#define WM8993_DACR_ENA_SHIFT 0 /* DACR_ENA */
-#define WM8993_DACR_ENA_WIDTH 1 /* DACR_ENA */
-
-/*
- * R4 (0x04) - Audio Interface (1)
- */
-#define WM8993_AIFADCL_SRC 0x8000 /* AIFADCL_SRC */
-#define WM8993_AIFADCL_SRC_MASK 0x8000 /* AIFADCL_SRC */
-#define WM8993_AIFADCL_SRC_SHIFT 15 /* AIFADCL_SRC */
-#define WM8993_AIFADCL_SRC_WIDTH 1 /* AIFADCL_SRC */
-#define WM8993_AIFADCR_SRC 0x4000 /* AIFADCR_SRC */
-#define WM8993_AIFADCR_SRC_MASK 0x4000 /* AIFADCR_SRC */
-#define WM8993_AIFADCR_SRC_SHIFT 14 /* AIFADCR_SRC */
-#define WM8993_AIFADCR_SRC_WIDTH 1 /* AIFADCR_SRC */
-#define WM8993_AIFADC_TDM 0x2000 /* AIFADC_TDM */
-#define WM8993_AIFADC_TDM_MASK 0x2000 /* AIFADC_TDM */
-#define WM8993_AIFADC_TDM_SHIFT 13 /* AIFADC_TDM */
-#define WM8993_AIFADC_TDM_WIDTH 1 /* AIFADC_TDM */
-#define WM8993_AIFADC_TDM_CHAN 0x1000 /* AIFADC_TDM_CHAN */
-#define WM8993_AIFADC_TDM_CHAN_MASK 0x1000 /* AIFADC_TDM_CHAN */
-#define WM8993_AIFADC_TDM_CHAN_SHIFT 12 /* AIFADC_TDM_CHAN */
-#define WM8993_AIFADC_TDM_CHAN_WIDTH 1 /* AIFADC_TDM_CHAN */
-#define WM8993_BCLK_DIR 0x0200 /* BCLK_DIR */
-#define WM8993_BCLK_DIR_MASK 0x0200 /* BCLK_DIR */
-#define WM8993_BCLK_DIR_SHIFT 9 /* BCLK_DIR */
-#define WM8993_BCLK_DIR_WIDTH 1 /* BCLK_DIR */
-#define WM8993_AIF_BCLK_INV 0x0100 /* AIF_BCLK_INV */
-#define WM8993_AIF_BCLK_INV_MASK 0x0100 /* AIF_BCLK_INV */
-#define WM8993_AIF_BCLK_INV_SHIFT 8 /* AIF_BCLK_INV */
-#define WM8993_AIF_BCLK_INV_WIDTH 1 /* AIF_BCLK_INV */
-#define WM8993_AIF_LRCLK_INV 0x0080 /* AIF_LRCLK_INV */
-#define WM8993_AIF_LRCLK_INV_MASK 0x0080 /* AIF_LRCLK_INV */
-#define WM8993_AIF_LRCLK_INV_SHIFT 7 /* AIF_LRCLK_INV */
-#define WM8993_AIF_LRCLK_INV_WIDTH 1 /* AIF_LRCLK_INV */
-#define WM8993_AIF_WL_MASK 0x0060 /* AIF_WL - [6:5] */
-#define WM8993_AIF_WL_SHIFT 5 /* AIF_WL - [6:5] */
-#define WM8993_AIF_WL_WIDTH 2 /* AIF_WL - [6:5] */
-#define WM8993_AIF_FMT_MASK 0x0018 /* AIF_FMT - [4:3] */
-#define WM8993_AIF_FMT_SHIFT 3 /* AIF_FMT - [4:3] */
-#define WM8993_AIF_FMT_WIDTH 2 /* AIF_FMT - [4:3] */
-
-/*
- * R5 (0x05) - Audio Interface (2)
- */
-#define WM8993_AIFDACL_SRC 0x8000 /* AIFDACL_SRC */
-#define WM8993_AIFDACL_SRC_MASK 0x8000 /* AIFDACL_SRC */
-#define WM8993_AIFDACL_SRC_SHIFT 15 /* AIFDACL_SRC */
-#define WM8993_AIFDACL_SRC_WIDTH 1 /* AIFDACL_SRC */
-#define WM8993_AIFDACR_SRC 0x4000 /* AIFDACR_SRC */
-#define WM8993_AIFDACR_SRC_MASK 0x4000 /* AIFDACR_SRC */
-#define WM8993_AIFDACR_SRC_SHIFT 14 /* AIFDACR_SRC */
-#define WM8993_AIFDACR_SRC_WIDTH 1 /* AIFDACR_SRC */
-#define WM8993_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */
-#define WM8993_AIFDAC_TDM_MASK 0x2000 /* AIFDAC_TDM */
-#define WM8993_AIFDAC_TDM_SHIFT 13 /* AIFDAC_TDM */
-#define WM8993_AIFDAC_TDM_WIDTH 1 /* AIFDAC_TDM */
-#define WM8993_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */
-#define WM8993_AIFDAC_TDM_CHAN_MASK 0x1000 /* AIFDAC_TDM_CHAN */
-#define WM8993_AIFDAC_TDM_CHAN_SHIFT 12 /* AIFDAC_TDM_CHAN */
-#define WM8993_AIFDAC_TDM_CHAN_WIDTH 1 /* AIFDAC_TDM_CHAN */
-#define WM8993_DAC_BOOST_MASK 0x0C00 /* DAC_BOOST - [11:10] */
-#define WM8993_DAC_BOOST_SHIFT 10 /* DAC_BOOST - [11:10] */
-#define WM8993_DAC_BOOST_WIDTH 2 /* DAC_BOOST - [11:10] */
-#define WM8993_DAC_COMP 0x0010 /* DAC_COMP */
-#define WM8993_DAC_COMP_MASK 0x0010 /* DAC_COMP */
-#define WM8993_DAC_COMP_SHIFT 4 /* DAC_COMP */
-#define WM8993_DAC_COMP_WIDTH 1 /* DAC_COMP */
-#define WM8993_DAC_COMPMODE 0x0008 /* DAC_COMPMODE */
-#define WM8993_DAC_COMPMODE_MASK 0x0008 /* DAC_COMPMODE */
-#define WM8993_DAC_COMPMODE_SHIFT 3 /* DAC_COMPMODE */
-#define WM8993_DAC_COMPMODE_WIDTH 1 /* DAC_COMPMODE */
-#define WM8993_ADC_COMP 0x0004 /* ADC_COMP */
-#define WM8993_ADC_COMP_MASK 0x0004 /* ADC_COMP */
-#define WM8993_ADC_COMP_SHIFT 2 /* ADC_COMP */
-#define WM8993_ADC_COMP_WIDTH 1 /* ADC_COMP */
-#define WM8993_ADC_COMPMODE 0x0002 /* ADC_COMPMODE */
-#define WM8993_ADC_COMPMODE_MASK 0x0002 /* ADC_COMPMODE */
-#define WM8993_ADC_COMPMODE_SHIFT 1 /* ADC_COMPMODE */
-#define WM8993_ADC_COMPMODE_WIDTH 1 /* ADC_COMPMODE */
-#define WM8993_LOOPBACK 0x0001 /* LOOPBACK */
-#define WM8993_LOOPBACK_MASK 0x0001 /* LOOPBACK */
-#define WM8993_LOOPBACK_SHIFT 0 /* LOOPBACK */
-#define WM8993_LOOPBACK_WIDTH 1 /* LOOPBACK */
-
-/*
- * R6 (0x06) - Clocking 1
- */
-#define WM8993_TOCLK_RATE 0x8000 /* TOCLK_RATE */
-#define WM8993_TOCLK_RATE_MASK 0x8000 /* TOCLK_RATE */
-#define WM8993_TOCLK_RATE_SHIFT 15 /* TOCLK_RATE */
-#define WM8993_TOCLK_RATE_WIDTH 1 /* TOCLK_RATE */
-#define WM8993_TOCLK_ENA 0x4000 /* TOCLK_ENA */
-#define WM8993_TOCLK_ENA_MASK 0x4000 /* TOCLK_ENA */
-#define WM8993_TOCLK_ENA_SHIFT 14 /* TOCLK_ENA */
-#define WM8993_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
-#define WM8993_OPCLK_DIV_MASK 0x1E00 /* OPCLK_DIV - [12:9] */
-#define WM8993_OPCLK_DIV_SHIFT 9 /* OPCLK_DIV - [12:9] */
-#define WM8993_OPCLK_DIV_WIDTH 4 /* OPCLK_DIV - [12:9] */
-#define WM8993_DCLK_DIV_MASK 0x01C0 /* DCLK_DIV - [8:6] */
-#define WM8993_DCLK_DIV_SHIFT 6 /* DCLK_DIV - [8:6] */
-#define WM8993_DCLK_DIV_WIDTH 3 /* DCLK_DIV - [8:6] */
-#define WM8993_BCLK_DIV_MASK 0x001E /* BCLK_DIV - [4:1] */
-#define WM8993_BCLK_DIV_SHIFT 1 /* BCLK_DIV - [4:1] */
-#define WM8993_BCLK_DIV_WIDTH 4 /* BCLK_DIV - [4:1] */
-
-/*
- * R7 (0x07) - Clocking 2
- */
-#define WM8993_MCLK_SRC 0x8000 /* MCLK_SRC */
-#define WM8993_MCLK_SRC_MASK 0x8000 /* MCLK_SRC */
-#define WM8993_MCLK_SRC_SHIFT 15 /* MCLK_SRC */
-#define WM8993_MCLK_SRC_WIDTH 1 /* MCLK_SRC */
-#define WM8993_SYSCLK_SRC 0x4000 /* SYSCLK_SRC */
-#define WM8993_SYSCLK_SRC_MASK 0x4000 /* SYSCLK_SRC */
-#define WM8993_SYSCLK_SRC_SHIFT 14 /* SYSCLK_SRC */
-#define WM8993_SYSCLK_SRC_WIDTH 1 /* SYSCLK_SRC */
-#define WM8993_MCLK_DIV 0x1000 /* MCLK_DIV */
-#define WM8993_MCLK_DIV_MASK 0x1000 /* MCLK_DIV */
-#define WM8993_MCLK_DIV_SHIFT 12 /* MCLK_DIV */
-#define WM8993_MCLK_DIV_WIDTH 1 /* MCLK_DIV */
-#define WM8993_MCLK_INV 0x0400 /* MCLK_INV */
-#define WM8993_MCLK_INV_MASK 0x0400 /* MCLK_INV */
-#define WM8993_MCLK_INV_SHIFT 10 /* MCLK_INV */
-#define WM8993_MCLK_INV_WIDTH 1 /* MCLK_INV */
-#define WM8993_ADC_DIV_MASK 0x00E0 /* ADC_DIV - [7:5] */
-#define WM8993_ADC_DIV_SHIFT 5 /* ADC_DIV - [7:5] */
-#define WM8993_ADC_DIV_WIDTH 3 /* ADC_DIV - [7:5] */
-#define WM8993_DAC_DIV_MASK 0x001C /* DAC_DIV - [4:2] */
-#define WM8993_DAC_DIV_SHIFT 2 /* DAC_DIV - [4:2] */
-#define WM8993_DAC_DIV_WIDTH 3 /* DAC_DIV - [4:2] */
-
-/*
- * R8 (0x08) - Audio Interface (3)
- */
-#define WM8993_AIF_MSTR1 0x8000 /* AIF_MSTR1 */
-#define WM8993_AIF_MSTR1_MASK 0x8000 /* AIF_MSTR1 */
-#define WM8993_AIF_MSTR1_SHIFT 15 /* AIF_MSTR1 */
-#define WM8993_AIF_MSTR1_WIDTH 1 /* AIF_MSTR1 */
-
-/*
- * R9 (0x09) - Audio Interface (4)
- */
-#define WM8993_AIF_TRIS 0x2000 /* AIF_TRIS */
-#define WM8993_AIF_TRIS_MASK 0x2000 /* AIF_TRIS */
-#define WM8993_AIF_TRIS_SHIFT 13 /* AIF_TRIS */
-#define WM8993_AIF_TRIS_WIDTH 1 /* AIF_TRIS */
-#define WM8993_LRCLK_DIR 0x0800 /* LRCLK_DIR */
-#define WM8993_LRCLK_DIR_MASK 0x0800 /* LRCLK_DIR */
-#define WM8993_LRCLK_DIR_SHIFT 11 /* LRCLK_DIR */
-#define WM8993_LRCLK_DIR_WIDTH 1 /* LRCLK_DIR */
-#define WM8993_LRCLK_RATE_MASK 0x07FF /* LRCLK_RATE - [10:0] */
-#define WM8993_LRCLK_RATE_SHIFT 0 /* LRCLK_RATE - [10:0] */
-#define WM8993_LRCLK_RATE_WIDTH 11 /* LRCLK_RATE - [10:0] */
-
-/*
- * R10 (0x0A) - DAC CTRL
- */
-#define WM8993_DAC_OSR128 0x2000 /* DAC_OSR128 */
-#define WM8993_DAC_OSR128_MASK 0x2000 /* DAC_OSR128 */
-#define WM8993_DAC_OSR128_SHIFT 13 /* DAC_OSR128 */
-#define WM8993_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
-#define WM8993_DAC_MONO 0x0200 /* DAC_MONO */
-#define WM8993_DAC_MONO_MASK 0x0200 /* DAC_MONO */
-#define WM8993_DAC_MONO_SHIFT 9 /* DAC_MONO */
-#define WM8993_DAC_MONO_WIDTH 1 /* DAC_MONO */
-#define WM8993_DAC_SB_FILT 0x0100 /* DAC_SB_FILT */
-#define WM8993_DAC_SB_FILT_MASK 0x0100 /* DAC_SB_FILT */
-#define WM8993_DAC_SB_FILT_SHIFT 8 /* DAC_SB_FILT */
-#define WM8993_DAC_SB_FILT_WIDTH 1 /* DAC_SB_FILT */
-#define WM8993_DAC_MUTERATE 0x0080 /* DAC_MUTERATE */
-#define WM8993_DAC_MUTERATE_MASK 0x0080 /* DAC_MUTERATE */
-#define WM8993_DAC_MUTERATE_SHIFT 7 /* DAC_MUTERATE */
-#define WM8993_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
-#define WM8993_DAC_UNMUTE_RAMP 0x0040 /* DAC_UNMUTE_RAMP */
-#define WM8993_DAC_UNMUTE_RAMP_MASK 0x0040 /* DAC_UNMUTE_RAMP */
-#define WM8993_DAC_UNMUTE_RAMP_SHIFT 6 /* DAC_UNMUTE_RAMP */
-#define WM8993_DAC_UNMUTE_RAMP_WIDTH 1 /* DAC_UNMUTE_RAMP */
-#define WM8993_DEEMPH_MASK 0x0030 /* DEEMPH - [5:4] */
-#define WM8993_DEEMPH_SHIFT 4 /* DEEMPH - [5:4] */
-#define WM8993_DEEMPH_WIDTH 2 /* DEEMPH - [5:4] */
-#define WM8993_DAC_MUTE 0x0004 /* DAC_MUTE */
-#define WM8993_DAC_MUTE_MASK 0x0004 /* DAC_MUTE */
-#define WM8993_DAC_MUTE_SHIFT 2 /* DAC_MUTE */
-#define WM8993_DAC_MUTE_WIDTH 1 /* DAC_MUTE */
-#define WM8993_DACL_DATINV 0x0002 /* DACL_DATINV */
-#define WM8993_DACL_DATINV_MASK 0x0002 /* DACL_DATINV */
-#define WM8993_DACL_DATINV_SHIFT 1 /* DACL_DATINV */
-#define WM8993_DACL_DATINV_WIDTH 1 /* DACL_DATINV */
-#define WM8993_DACR_DATINV 0x0001 /* DACR_DATINV */
-#define WM8993_DACR_DATINV_MASK 0x0001 /* DACR_DATINV */
-#define WM8993_DACR_DATINV_SHIFT 0 /* DACR_DATINV */
-#define WM8993_DACR_DATINV_WIDTH 1 /* DACR_DATINV */
-
-/*
- * R11 (0x0B) - Left DAC Digital Volume
- */
-#define WM8993_DAC_VU 0x0100 /* DAC_VU */
-#define WM8993_DAC_VU_MASK 0x0100 /* DAC_VU */
-#define WM8993_DAC_VU_SHIFT 8 /* DAC_VU */
-#define WM8993_DAC_VU_WIDTH 1 /* DAC_VU */
-#define WM8993_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
-#define WM8993_DACL_VOL_SHIFT 0 /* DACL_VOL - [7:0] */
-#define WM8993_DACL_VOL_WIDTH 8 /* DACL_VOL - [7:0] */
-
-/*
- * R12 (0x0C) - Right DAC Digital Volume
- */
-#define WM8993_DAC_VU 0x0100 /* DAC_VU */
-#define WM8993_DAC_VU_MASK 0x0100 /* DAC_VU */
-#define WM8993_DAC_VU_SHIFT 8 /* DAC_VU */
-#define WM8993_DAC_VU_WIDTH 1 /* DAC_VU */
-#define WM8993_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
-#define WM8993_DACR_VOL_SHIFT 0 /* DACR_VOL - [7:0] */
-#define WM8993_DACR_VOL_WIDTH 8 /* DACR_VOL - [7:0] */
-
-/*
- * R13 (0x0D) - Digital Side Tone
- */
-#define WM8993_ADCL_DAC_SVOL_MASK 0x1E00 /* ADCL_DAC_SVOL - [12:9] */
-#define WM8993_ADCL_DAC_SVOL_SHIFT 9 /* ADCL_DAC_SVOL - [12:9] */
-#define WM8993_ADCL_DAC_SVOL_WIDTH 4 /* ADCL_DAC_SVOL - [12:9] */
-#define WM8993_ADCR_DAC_SVOL_MASK 0x01E0 /* ADCR_DAC_SVOL - [8:5] */
-#define WM8993_ADCR_DAC_SVOL_SHIFT 5 /* ADCR_DAC_SVOL - [8:5] */
-#define WM8993_ADCR_DAC_SVOL_WIDTH 4 /* ADCR_DAC_SVOL - [8:5] */
-#define WM8993_ADC_TO_DACL_MASK 0x000C /* ADC_TO_DACL - [3:2] */
-#define WM8993_ADC_TO_DACL_SHIFT 2 /* ADC_TO_DACL - [3:2] */
-#define WM8993_ADC_TO_DACL_WIDTH 2 /* ADC_TO_DACL - [3:2] */
-#define WM8993_ADC_TO_DACR_MASK 0x0003 /* ADC_TO_DACR - [1:0] */
-#define WM8993_ADC_TO_DACR_SHIFT 0 /* ADC_TO_DACR - [1:0] */
-#define WM8993_ADC_TO_DACR_WIDTH 2 /* ADC_TO_DACR - [1:0] */
-
-/*
- * R14 (0x0E) - ADC CTRL
- */
-#define WM8993_ADC_OSR128 0x0200 /* ADC_OSR128 */
-#define WM8993_ADC_OSR128_MASK 0x0200 /* ADC_OSR128 */
-#define WM8993_ADC_OSR128_SHIFT 9 /* ADC_OSR128 */
-#define WM8993_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
-#define WM8993_ADC_HPF 0x0100 /* ADC_HPF */
-#define WM8993_ADC_HPF_MASK 0x0100 /* ADC_HPF */
-#define WM8993_ADC_HPF_SHIFT 8 /* ADC_HPF */
-#define WM8993_ADC_HPF_WIDTH 1 /* ADC_HPF */
-#define WM8993_ADC_HPF_CUT_MASK 0x0060 /* ADC_HPF_CUT - [6:5] */
-#define WM8993_ADC_HPF_CUT_SHIFT 5 /* ADC_HPF_CUT - [6:5] */
-#define WM8993_ADC_HPF_CUT_WIDTH 2 /* ADC_HPF_CUT - [6:5] */
-#define WM8993_ADCL_DATINV 0x0002 /* ADCL_DATINV */
-#define WM8993_ADCL_DATINV_MASK 0x0002 /* ADCL_DATINV */
-#define WM8993_ADCL_DATINV_SHIFT 1 /* ADCL_DATINV */
-#define WM8993_ADCL_DATINV_WIDTH 1 /* ADCL_DATINV */
-#define WM8993_ADCR_DATINV 0x0001 /* ADCR_DATINV */
-#define WM8993_ADCR_DATINV_MASK 0x0001 /* ADCR_DATINV */
-#define WM8993_ADCR_DATINV_SHIFT 0 /* ADCR_DATINV */
-#define WM8993_ADCR_DATINV_WIDTH 1 /* ADCR_DATINV */
-
-/*
- * R15 (0x0F) - Left ADC Digital Volume
- */
-#define WM8993_ADC_VU 0x0100 /* ADC_VU */
-#define WM8993_ADC_VU_MASK 0x0100 /* ADC_VU */
-#define WM8993_ADC_VU_SHIFT 8 /* ADC_VU */
-#define WM8993_ADC_VU_WIDTH 1 /* ADC_VU */
-#define WM8993_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
-#define WM8993_ADCL_VOL_SHIFT 0 /* ADCL_VOL - [7:0] */
-#define WM8993_ADCL_VOL_WIDTH 8 /* ADCL_VOL - [7:0] */
-
-/*
- * R16 (0x10) - Right ADC Digital Volume
- */
-#define WM8993_ADC_VU 0x0100 /* ADC_VU */
-#define WM8993_ADC_VU_MASK 0x0100 /* ADC_VU */
-#define WM8993_ADC_VU_SHIFT 8 /* ADC_VU */
-#define WM8993_ADC_VU_WIDTH 1 /* ADC_VU */
-#define WM8993_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
-#define WM8993_ADCR_VOL_SHIFT 0 /* ADCR_VOL - [7:0] */
-#define WM8993_ADCR_VOL_WIDTH 8 /* ADCR_VOL - [7:0] */
-
-/*
- * R18 (0x12) - GPIO CTRL 1
- */
-#define WM8993_JD2_SC_EINT 0x8000 /* JD2_SC_EINT */
-#define WM8993_JD2_SC_EINT_MASK 0x8000 /* JD2_SC_EINT */
-#define WM8993_JD2_SC_EINT_SHIFT 15 /* JD2_SC_EINT */
-#define WM8993_JD2_SC_EINT_WIDTH 1 /* JD2_SC_EINT */
-#define WM8993_JD2_EINT 0x4000 /* JD2_EINT */
-#define WM8993_JD2_EINT_MASK 0x4000 /* JD2_EINT */
-#define WM8993_JD2_EINT_SHIFT 14 /* JD2_EINT */
-#define WM8993_JD2_EINT_WIDTH 1 /* JD2_EINT */
-#define WM8993_WSEQ_EINT 0x2000 /* WSEQ_EINT */
-#define WM8993_WSEQ_EINT_MASK 0x2000 /* WSEQ_EINT */
-#define WM8993_WSEQ_EINT_SHIFT 13 /* WSEQ_EINT */
-#define WM8993_WSEQ_EINT_WIDTH 1 /* WSEQ_EINT */
-#define WM8993_IRQ 0x1000 /* IRQ */
-#define WM8993_IRQ_MASK 0x1000 /* IRQ */
-#define WM8993_IRQ_SHIFT 12 /* IRQ */
-#define WM8993_IRQ_WIDTH 1 /* IRQ */
-#define WM8993_TEMPOK_EINT 0x0800 /* TEMPOK_EINT */
-#define WM8993_TEMPOK_EINT_MASK 0x0800 /* TEMPOK_EINT */
-#define WM8993_TEMPOK_EINT_SHIFT 11 /* TEMPOK_EINT */
-#define WM8993_TEMPOK_EINT_WIDTH 1 /* TEMPOK_EINT */
-#define WM8993_JD1_SC_EINT 0x0400 /* JD1_SC_EINT */
-#define WM8993_JD1_SC_EINT_MASK 0x0400 /* JD1_SC_EINT */
-#define WM8993_JD1_SC_EINT_SHIFT 10 /* JD1_SC_EINT */
-#define WM8993_JD1_SC_EINT_WIDTH 1 /* JD1_SC_EINT */
-#define WM8993_JD1_EINT 0x0200 /* JD1_EINT */
-#define WM8993_JD1_EINT_MASK 0x0200 /* JD1_EINT */
-#define WM8993_JD1_EINT_SHIFT 9 /* JD1_EINT */
-#define WM8993_JD1_EINT_WIDTH 1 /* JD1_EINT */
-#define WM8993_FLL_LOCK_EINT 0x0100 /* FLL_LOCK_EINT */
-#define WM8993_FLL_LOCK_EINT_MASK 0x0100 /* FLL_LOCK_EINT */
-#define WM8993_FLL_LOCK_EINT_SHIFT 8 /* FLL_LOCK_EINT */
-#define WM8993_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */
-#define WM8993_GPI8_EINT 0x0080 /* GPI8_EINT */
-#define WM8993_GPI8_EINT_MASK 0x0080 /* GPI8_EINT */
-#define WM8993_GPI8_EINT_SHIFT 7 /* GPI8_EINT */
-#define WM8993_GPI8_EINT_WIDTH 1 /* GPI8_EINT */
-#define WM8993_GPI7_EINT 0x0040 /* GPI7_EINT */
-#define WM8993_GPI7_EINT_MASK 0x0040 /* GPI7_EINT */
-#define WM8993_GPI7_EINT_SHIFT 6 /* GPI7_EINT */
-#define WM8993_GPI7_EINT_WIDTH 1 /* GPI7_EINT */
-#define WM8993_GPIO1_EINT 0x0001 /* GPIO1_EINT */
-#define WM8993_GPIO1_EINT_MASK 0x0001 /* GPIO1_EINT */
-#define WM8993_GPIO1_EINT_SHIFT 0 /* GPIO1_EINT */
-#define WM8993_GPIO1_EINT_WIDTH 1 /* GPIO1_EINT */
-
-/*
- * R19 (0x13) - GPIO1
- */
-#define WM8993_GPIO1_PU 0x0020 /* GPIO1_PU */
-#define WM8993_GPIO1_PU_MASK 0x0020 /* GPIO1_PU */
-#define WM8993_GPIO1_PU_SHIFT 5 /* GPIO1_PU */
-#define WM8993_GPIO1_PU_WIDTH 1 /* GPIO1_PU */
-#define WM8993_GPIO1_PD 0x0010 /* GPIO1_PD */
-#define WM8993_GPIO1_PD_MASK 0x0010 /* GPIO1_PD */
-#define WM8993_GPIO1_PD_SHIFT 4 /* GPIO1_PD */
-#define WM8993_GPIO1_PD_WIDTH 1 /* GPIO1_PD */
-#define WM8993_GPIO1_SEL_MASK 0x000F /* GPIO1_SEL - [3:0] */
-#define WM8993_GPIO1_SEL_SHIFT 0 /* GPIO1_SEL - [3:0] */
-#define WM8993_GPIO1_SEL_WIDTH 4 /* GPIO1_SEL - [3:0] */
-
-/*
- * R20 (0x14) - IRQ_DEBOUNCE
- */
-#define WM8993_JD2_SC_DB 0x8000 /* JD2_SC_DB */
-#define WM8993_JD2_SC_DB_MASK 0x8000 /* JD2_SC_DB */
-#define WM8993_JD2_SC_DB_SHIFT 15 /* JD2_SC_DB */
-#define WM8993_JD2_SC_DB_WIDTH 1 /* JD2_SC_DB */
-#define WM8993_JD2_DB 0x4000 /* JD2_DB */
-#define WM8993_JD2_DB_MASK 0x4000 /* JD2_DB */
-#define WM8993_JD2_DB_SHIFT 14 /* JD2_DB */
-#define WM8993_JD2_DB_WIDTH 1 /* JD2_DB */
-#define WM8993_WSEQ_DB 0x2000 /* WSEQ_DB */
-#define WM8993_WSEQ_DB_MASK 0x2000 /* WSEQ_DB */
-#define WM8993_WSEQ_DB_SHIFT 13 /* WSEQ_DB */
-#define WM8993_WSEQ_DB_WIDTH 1 /* WSEQ_DB */
-#define WM8993_TEMPOK_DB 0x0800 /* TEMPOK_DB */
-#define WM8993_TEMPOK_DB_MASK 0x0800 /* TEMPOK_DB */
-#define WM8993_TEMPOK_DB_SHIFT 11 /* TEMPOK_DB */
-#define WM8993_TEMPOK_DB_WIDTH 1 /* TEMPOK_DB */
-#define WM8993_JD1_SC_DB 0x0400 /* JD1_SC_DB */
-#define WM8993_JD1_SC_DB_MASK 0x0400 /* JD1_SC_DB */
-#define WM8993_JD1_SC_DB_SHIFT 10 /* JD1_SC_DB */
-#define WM8993_JD1_SC_DB_WIDTH 1 /* JD1_SC_DB */
-#define WM8993_JD1_DB 0x0200 /* JD1_DB */
-#define WM8993_JD1_DB_MASK 0x0200 /* JD1_DB */
-#define WM8993_JD1_DB_SHIFT 9 /* JD1_DB */
-#define WM8993_JD1_DB_WIDTH 1 /* JD1_DB */
-#define WM8993_FLL_LOCK_DB 0x0100 /* FLL_LOCK_DB */
-#define WM8993_FLL_LOCK_DB_MASK 0x0100 /* FLL_LOCK_DB */
-#define WM8993_FLL_LOCK_DB_SHIFT 8 /* FLL_LOCK_DB */
-#define WM8993_FLL_LOCK_DB_WIDTH 1 /* FLL_LOCK_DB */
-#define WM8993_GPI8_DB 0x0080 /* GPI8_DB */
-#define WM8993_GPI8_DB_MASK 0x0080 /* GPI8_DB */
-#define WM8993_GPI8_DB_SHIFT 7 /* GPI8_DB */
-#define WM8993_GPI8_DB_WIDTH 1 /* GPI8_DB */
-#define WM8993_GPI7_DB 0x0008 /* GPI7_DB */
-#define WM8993_GPI7_DB_MASK 0x0008 /* GPI7_DB */
-#define WM8993_GPI7_DB_SHIFT 3 /* GPI7_DB */
-#define WM8993_GPI7_DB_WIDTH 1 /* GPI7_DB */
-#define WM8993_GPIO1_DB 0x0001 /* GPIO1_DB */
-#define WM8993_GPIO1_DB_MASK 0x0001 /* GPIO1_DB */
-#define WM8993_GPIO1_DB_SHIFT 0 /* GPIO1_DB */
-#define WM8993_GPIO1_DB_WIDTH 1 /* GPIO1_DB */
-
-/*
- * R21 (0x15) - Inputs Clamp
- */
-#define WM8993_INPUTS_CLAMP 0x0040 /* INPUTS_CLAMP */
-#define WM8993_INPUTS_CLAMP_MASK 0x0040 /* INPUTS_CLAMP */
-#define WM8993_INPUTS_CLAMP_SHIFT 7 /* INPUTS_CLAMP */
-#define WM8993_INPUTS_CLAMP_WIDTH 1 /* INPUTS_CLAMP */
-
-/*
- * R22 (0x16) - GPIOCTRL 2
- */
-#define WM8993_IM_JD2_EINT 0x2000 /* IM_JD2_EINT */
-#define WM8993_IM_JD2_EINT_MASK 0x2000 /* IM_JD2_EINT */
-#define WM8993_IM_JD2_EINT_SHIFT 13 /* IM_JD2_EINT */
-#define WM8993_IM_JD2_EINT_WIDTH 1 /* IM_JD2_EINT */
-#define WM8993_IM_JD2_SC_EINT 0x1000 /* IM_JD2_SC_EINT */
-#define WM8993_IM_JD2_SC_EINT_MASK 0x1000 /* IM_JD2_SC_EINT */
-#define WM8993_IM_JD2_SC_EINT_SHIFT 12 /* IM_JD2_SC_EINT */
-#define WM8993_IM_JD2_SC_EINT_WIDTH 1 /* IM_JD2_SC_EINT */
-#define WM8993_IM_TEMPOK_EINT 0x0800 /* IM_TEMPOK_EINT */
-#define WM8993_IM_TEMPOK_EINT_MASK 0x0800 /* IM_TEMPOK_EINT */
-#define WM8993_IM_TEMPOK_EINT_SHIFT 11 /* IM_TEMPOK_EINT */
-#define WM8993_IM_TEMPOK_EINT_WIDTH 1 /* IM_TEMPOK_EINT */
-#define WM8993_IM_JD1_SC_EINT 0x0400 /* IM_JD1_SC_EINT */
-#define WM8993_IM_JD1_SC_EINT_MASK 0x0400 /* IM_JD1_SC_EINT */
-#define WM8993_IM_JD1_SC_EINT_SHIFT 10 /* IM_JD1_SC_EINT */
-#define WM8993_IM_JD1_SC_EINT_WIDTH 1 /* IM_JD1_SC_EINT */
-#define WM8993_IM_JD1_EINT 0x0200 /* IM_JD1_EINT */
-#define WM8993_IM_JD1_EINT_MASK 0x0200 /* IM_JD1_EINT */
-#define WM8993_IM_JD1_EINT_SHIFT 9 /* IM_JD1_EINT */
-#define WM8993_IM_JD1_EINT_WIDTH 1 /* IM_JD1_EINT */
-#define WM8993_IM_FLL_LOCK_EINT 0x0100 /* IM_FLL_LOCK_EINT */
-#define WM8993_IM_FLL_LOCK_EINT_MASK 0x0100 /* IM_FLL_LOCK_EINT */
-#define WM8993_IM_FLL_LOCK_EINT_SHIFT 8 /* IM_FLL_LOCK_EINT */
-#define WM8993_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */
-#define WM8993_IM_GPI8_EINT 0x0040 /* IM_GPI8_EINT */
-#define WM8993_IM_GPI8_EINT_MASK 0x0040 /* IM_GPI8_EINT */
-#define WM8993_IM_GPI8_EINT_SHIFT 6 /* IM_GPI8_EINT */
-#define WM8993_IM_GPI8_EINT_WIDTH 1 /* IM_GPI8_EINT */
-#define WM8993_IM_GPIO1_EINT 0x0020 /* IM_GPIO1_EINT */
-#define WM8993_IM_GPIO1_EINT_MASK 0x0020 /* IM_GPIO1_EINT */
-#define WM8993_IM_GPIO1_EINT_SHIFT 5 /* IM_GPIO1_EINT */
-#define WM8993_IM_GPIO1_EINT_WIDTH 1 /* IM_GPIO1_EINT */
-#define WM8993_GPI8_ENA 0x0010 /* GPI8_ENA */
-#define WM8993_GPI8_ENA_MASK 0x0010 /* GPI8_ENA */
-#define WM8993_GPI8_ENA_SHIFT 4 /* GPI8_ENA */
-#define WM8993_GPI8_ENA_WIDTH 1 /* GPI8_ENA */
-#define WM8993_IM_GPI7_EINT 0x0004 /* IM_GPI7_EINT */
-#define WM8993_IM_GPI7_EINT_MASK 0x0004 /* IM_GPI7_EINT */
-#define WM8993_IM_GPI7_EINT_SHIFT 2 /* IM_GPI7_EINT */
-#define WM8993_IM_GPI7_EINT_WIDTH 1 /* IM_GPI7_EINT */
-#define WM8993_IM_WSEQ_EINT 0x0002 /* IM_WSEQ_EINT */
-#define WM8993_IM_WSEQ_EINT_MASK 0x0002 /* IM_WSEQ_EINT */
-#define WM8993_IM_WSEQ_EINT_SHIFT 1 /* IM_WSEQ_EINT */
-#define WM8993_IM_WSEQ_EINT_WIDTH 1 /* IM_WSEQ_EINT */
-#define WM8993_GPI7_ENA 0x0001 /* GPI7_ENA */
-#define WM8993_GPI7_ENA_MASK 0x0001 /* GPI7_ENA */
-#define WM8993_GPI7_ENA_SHIFT 0 /* GPI7_ENA */
-#define WM8993_GPI7_ENA_WIDTH 1 /* GPI7_ENA */
-
-/*
- * R23 (0x17) - GPIO_POL
- */
-#define WM8993_JD2_SC_POL 0x8000 /* JD2_SC_POL */
-#define WM8993_JD2_SC_POL_MASK 0x8000 /* JD2_SC_POL */
-#define WM8993_JD2_SC_POL_SHIFT 15 /* JD2_SC_POL */
-#define WM8993_JD2_SC_POL_WIDTH 1 /* JD2_SC_POL */
-#define WM8993_JD2_POL 0x4000 /* JD2_POL */
-#define WM8993_JD2_POL_MASK 0x4000 /* JD2_POL */
-#define WM8993_JD2_POL_SHIFT 14 /* JD2_POL */
-#define WM8993_JD2_POL_WIDTH 1 /* JD2_POL */
-#define WM8993_WSEQ_POL 0x2000 /* WSEQ_POL */
-#define WM8993_WSEQ_POL_MASK 0x2000 /* WSEQ_POL */
-#define WM8993_WSEQ_POL_SHIFT 13 /* WSEQ_POL */
-#define WM8993_WSEQ_POL_WIDTH 1 /* WSEQ_POL */
-#define WM8993_IRQ_POL 0x1000 /* IRQ_POL */
-#define WM8993_IRQ_POL_MASK 0x1000 /* IRQ_POL */
-#define WM8993_IRQ_POL_SHIFT 12 /* IRQ_POL */
-#define WM8993_IRQ_POL_WIDTH 1 /* IRQ_POL */
-#define WM8993_TEMPOK_POL 0x0800 /* TEMPOK_POL */
-#define WM8993_TEMPOK_POL_MASK 0x0800 /* TEMPOK_POL */
-#define WM8993_TEMPOK_POL_SHIFT 11 /* TEMPOK_POL */
-#define WM8993_TEMPOK_POL_WIDTH 1 /* TEMPOK_POL */
-#define WM8993_JD1_SC_POL 0x0400 /* JD1_SC_POL */
-#define WM8993_JD1_SC_POL_MASK 0x0400 /* JD1_SC_POL */
-#define WM8993_JD1_SC_POL_SHIFT 10 /* JD1_SC_POL */
-#define WM8993_JD1_SC_POL_WIDTH 1 /* JD1_SC_POL */
-#define WM8993_JD1_POL 0x0200 /* JD1_POL */
-#define WM8993_JD1_POL_MASK 0x0200 /* JD1_POL */
-#define WM8993_JD1_POL_SHIFT 9 /* JD1_POL */
-#define WM8993_JD1_POL_WIDTH 1 /* JD1_POL */
-#define WM8993_FLL_LOCK_POL 0x0100 /* FLL_LOCK_POL */
-#define WM8993_FLL_LOCK_POL_MASK 0x0100 /* FLL_LOCK_POL */
-#define WM8993_FLL_LOCK_POL_SHIFT 8 /* FLL_LOCK_POL */
-#define WM8993_FLL_LOCK_POL_WIDTH 1 /* FLL_LOCK_POL */
-#define WM8993_GPI8_POL 0x0080 /* GPI8_POL */
-#define WM8993_GPI8_POL_MASK 0x0080 /* GPI8_POL */
-#define WM8993_GPI8_POL_SHIFT 7 /* GPI8_POL */
-#define WM8993_GPI8_POL_WIDTH 1 /* GPI8_POL */
-#define WM8993_GPI7_POL 0x0040 /* GPI7_POL */
-#define WM8993_GPI7_POL_MASK 0x0040 /* GPI7_POL */
-#define WM8993_GPI7_POL_SHIFT 6 /* GPI7_POL */
-#define WM8993_GPI7_POL_WIDTH 1 /* GPI7_POL */
-#define WM8993_GPIO1_POL 0x0001 /* GPIO1_POL */
-#define WM8993_GPIO1_POL_MASK 0x0001 /* GPIO1_POL */
-#define WM8993_GPIO1_POL_SHIFT 0 /* GPIO1_POL */
-#define WM8993_GPIO1_POL_WIDTH 1 /* GPIO1_POL */
-
-/*
- * R24 (0x18) - Left Line Input 1&2 Volume
- */
-#define WM8993_IN1_VU 0x0100 /* IN1_VU */
-#define WM8993_IN1_VU_MASK 0x0100 /* IN1_VU */
-#define WM8993_IN1_VU_SHIFT 8 /* IN1_VU */
-#define WM8993_IN1_VU_WIDTH 1 /* IN1_VU */
-#define WM8993_IN1L_MUTE 0x0080 /* IN1L_MUTE */
-#define WM8993_IN1L_MUTE_MASK 0x0080 /* IN1L_MUTE */
-#define WM8993_IN1L_MUTE_SHIFT 7 /* IN1L_MUTE */
-#define WM8993_IN1L_MUTE_WIDTH 1 /* IN1L_MUTE */
-#define WM8993_IN1L_ZC 0x0040 /* IN1L_ZC */
-#define WM8993_IN1L_ZC_MASK 0x0040 /* IN1L_ZC */
-#define WM8993_IN1L_ZC_SHIFT 6 /* IN1L_ZC */
-#define WM8993_IN1L_ZC_WIDTH 1 /* IN1L_ZC */
-#define WM8993_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */
-#define WM8993_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */
-#define WM8993_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */
-
-/*
- * R25 (0x19) - Left Line Input 3&4 Volume
- */
-#define WM8993_IN2_VU 0x0100 /* IN2_VU */
-#define WM8993_IN2_VU_MASK 0x0100 /* IN2_VU */
-#define WM8993_IN2_VU_SHIFT 8 /* IN2_VU */
-#define WM8993_IN2_VU_WIDTH 1 /* IN2_VU */
-#define WM8993_IN2L_MUTE 0x0080 /* IN2L_MUTE */
-#define WM8993_IN2L_MUTE_MASK 0x0080 /* IN2L_MUTE */
-#define WM8993_IN2L_MUTE_SHIFT 7 /* IN2L_MUTE */
-#define WM8993_IN2L_MUTE_WIDTH 1 /* IN2L_MUTE */
-#define WM8993_IN2L_ZC 0x0040 /* IN2L_ZC */
-#define WM8993_IN2L_ZC_MASK 0x0040 /* IN2L_ZC */
-#define WM8993_IN2L_ZC_SHIFT 6 /* IN2L_ZC */
-#define WM8993_IN2L_ZC_WIDTH 1 /* IN2L_ZC */
-#define WM8993_IN2L_VOL_MASK 0x001F /* IN2L_VOL - [4:0] */
-#define WM8993_IN2L_VOL_SHIFT 0 /* IN2L_VOL - [4:0] */
-#define WM8993_IN2L_VOL_WIDTH 5 /* IN2L_VOL - [4:0] */
-
-/*
- * R26 (0x1A) - Right Line Input 1&2 Volume
- */
-#define WM8993_IN1_VU 0x0100 /* IN1_VU */
-#define WM8993_IN1_VU_MASK 0x0100 /* IN1_VU */
-#define WM8993_IN1_VU_SHIFT 8 /* IN1_VU */
-#define WM8993_IN1_VU_WIDTH 1 /* IN1_VU */
-#define WM8993_IN1R_MUTE 0x0080 /* IN1R_MUTE */
-#define WM8993_IN1R_MUTE_MASK 0x0080 /* IN1R_MUTE */
-#define WM8993_IN1R_MUTE_SHIFT 7 /* IN1R_MUTE */
-#define WM8993_IN1R_MUTE_WIDTH 1 /* IN1R_MUTE */
-#define WM8993_IN1R_ZC 0x0040 /* IN1R_ZC */
-#define WM8993_IN1R_ZC_MASK 0x0040 /* IN1R_ZC */
-#define WM8993_IN1R_ZC_SHIFT 6 /* IN1R_ZC */
-#define WM8993_IN1R_ZC_WIDTH 1 /* IN1R_ZC */
-#define WM8993_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */
-#define WM8993_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */
-#define WM8993_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */
-
-/*
- * R27 (0x1B) - Right Line Input 3&4 Volume
- */
-#define WM8993_IN2_VU 0x0100 /* IN2_VU */
-#define WM8993_IN2_VU_MASK 0x0100 /* IN2_VU */
-#define WM8993_IN2_VU_SHIFT 8 /* IN2_VU */
-#define WM8993_IN2_VU_WIDTH 1 /* IN2_VU */
-#define WM8993_IN2R_MUTE 0x0080 /* IN2R_MUTE */
-#define WM8993_IN2R_MUTE_MASK 0x0080 /* IN2R_MUTE */
-#define WM8993_IN2R_MUTE_SHIFT 7 /* IN2R_MUTE */
-#define WM8993_IN2R_MUTE_WIDTH 1 /* IN2R_MUTE */
-#define WM8993_IN2R_ZC 0x0040 /* IN2R_ZC */
-#define WM8993_IN2R_ZC_MASK 0x0040 /* IN2R_ZC */
-#define WM8993_IN2R_ZC_SHIFT 6 /* IN2R_ZC */
-#define WM8993_IN2R_ZC_WIDTH 1 /* IN2R_ZC */
-#define WM8993_IN2R_VOL_MASK 0x001F /* IN2R_VOL - [4:0] */
-#define WM8993_IN2R_VOL_SHIFT 0 /* IN2R_VOL - [4:0] */
-#define WM8993_IN2R_VOL_WIDTH 5 /* IN2R_VOL - [4:0] */
-
-/*
- * R28 (0x1C) - Left Output Volume
- */
-#define WM8993_HPOUT1_VU 0x0100 /* HPOUT1_VU */
-#define WM8993_HPOUT1_VU_MASK 0x0100 /* HPOUT1_VU */
-#define WM8993_HPOUT1_VU_SHIFT 8 /* HPOUT1_VU */
-#define WM8993_HPOUT1_VU_WIDTH 1 /* HPOUT1_VU */
-#define WM8993_HPOUT1L_ZC 0x0080 /* HPOUT1L_ZC */
-#define WM8993_HPOUT1L_ZC_MASK 0x0080 /* HPOUT1L_ZC */
-#define WM8993_HPOUT1L_ZC_SHIFT 7 /* HPOUT1L_ZC */
-#define WM8993_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */
-#define WM8993_HPOUT1L_MUTE_N 0x0040 /* HPOUT1L_MUTE_N */
-#define WM8993_HPOUT1L_MUTE_N_MASK 0x0040 /* HPOUT1L_MUTE_N */
-#define WM8993_HPOUT1L_MUTE_N_SHIFT 6 /* HPOUT1L_MUTE_N */
-#define WM8993_HPOUT1L_MUTE_N_WIDTH 1 /* HPOUT1L_MUTE_N */
-#define WM8993_HPOUT1L_VOL_MASK 0x003F /* HPOUT1L_VOL - [5:0] */
-#define WM8993_HPOUT1L_VOL_SHIFT 0 /* HPOUT1L_VOL - [5:0] */
-#define WM8993_HPOUT1L_VOL_WIDTH 6 /* HPOUT1L_VOL - [5:0] */
-
-/*
- * R29 (0x1D) - Right Output Volume
- */
-#define WM8993_HPOUT1_VU 0x0100 /* HPOUT1_VU */
-#define WM8993_HPOUT1_VU_MASK 0x0100 /* HPOUT1_VU */
-#define WM8993_HPOUT1_VU_SHIFT 8 /* HPOUT1_VU */
-#define WM8993_HPOUT1_VU_WIDTH 1 /* HPOUT1_VU */
-#define WM8993_HPOUT1R_ZC 0x0080 /* HPOUT1R_ZC */
-#define WM8993_HPOUT1R_ZC_MASK 0x0080 /* HPOUT1R_ZC */
-#define WM8993_HPOUT1R_ZC_SHIFT 7 /* HPOUT1R_ZC */
-#define WM8993_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */
-#define WM8993_HPOUT1R_MUTE_N 0x0040 /* HPOUT1R_MUTE_N */
-#define WM8993_HPOUT1R_MUTE_N_MASK 0x0040 /* HPOUT1R_MUTE_N */
-#define WM8993_HPOUT1R_MUTE_N_SHIFT 6 /* HPOUT1R_MUTE_N */
-#define WM8993_HPOUT1R_MUTE_N_WIDTH 1 /* HPOUT1R_MUTE_N */
-#define WM8993_HPOUT1R_VOL_MASK 0x003F /* HPOUT1R_VOL - [5:0] */
-#define WM8993_HPOUT1R_VOL_SHIFT 0 /* HPOUT1R_VOL - [5:0] */
-#define WM8993_HPOUT1R_VOL_WIDTH 6 /* HPOUT1R_VOL - [5:0] */
-
-/*
- * R30 (0x1E) - Line Outputs Volume
- */
-#define WM8993_LINEOUT1N_MUTE 0x0040 /* LINEOUT1N_MUTE */
-#define WM8993_LINEOUT1N_MUTE_MASK 0x0040 /* LINEOUT1N_MUTE */
-#define WM8993_LINEOUT1N_MUTE_SHIFT 6 /* LINEOUT1N_MUTE */
-#define WM8993_LINEOUT1N_MUTE_WIDTH 1 /* LINEOUT1N_MUTE */
-#define WM8993_LINEOUT1P_MUTE 0x0020 /* LINEOUT1P_MUTE */
-#define WM8993_LINEOUT1P_MUTE_MASK 0x0020 /* LINEOUT1P_MUTE */
-#define WM8993_LINEOUT1P_MUTE_SHIFT 5 /* LINEOUT1P_MUTE */
-#define WM8993_LINEOUT1P_MUTE_WIDTH 1 /* LINEOUT1P_MUTE */
-#define WM8993_LINEOUT1_VOL 0x0010 /* LINEOUT1_VOL */
-#define WM8993_LINEOUT1_VOL_MASK 0x0010 /* LINEOUT1_VOL */
-#define WM8993_LINEOUT1_VOL_SHIFT 4 /* LINEOUT1_VOL */
-#define WM8993_LINEOUT1_VOL_WIDTH 1 /* LINEOUT1_VOL */
-#define WM8993_LINEOUT2N_MUTE 0x0004 /* LINEOUT2N_MUTE */
-#define WM8993_LINEOUT2N_MUTE_MASK 0x0004 /* LINEOUT2N_MUTE */
-#define WM8993_LINEOUT2N_MUTE_SHIFT 2 /* LINEOUT2N_MUTE */
-#define WM8993_LINEOUT2N_MUTE_WIDTH 1 /* LINEOUT2N_MUTE */
-#define WM8993_LINEOUT2P_MUTE 0x0002 /* LINEOUT2P_MUTE */
-#define WM8993_LINEOUT2P_MUTE_MASK 0x0002 /* LINEOUT2P_MUTE */
-#define WM8993_LINEOUT2P_MUTE_SHIFT 1 /* LINEOUT2P_MUTE */
-#define WM8993_LINEOUT2P_MUTE_WIDTH 1 /* LINEOUT2P_MUTE */
-#define WM8993_LINEOUT2_VOL 0x0001 /* LINEOUT2_VOL */
-#define WM8993_LINEOUT2_VOL_MASK 0x0001 /* LINEOUT2_VOL */
-#define WM8993_LINEOUT2_VOL_SHIFT 0 /* LINEOUT2_VOL */
-#define WM8993_LINEOUT2_VOL_WIDTH 1 /* LINEOUT2_VOL */
-
-/*
- * R31 (0x1F) - HPOUT2 Volume
- */
-#define WM8993_HPOUT2_MUTE 0x0020 /* HPOUT2_MUTE */
-#define WM8993_HPOUT2_MUTE_MASK 0x0020 /* HPOUT2_MUTE */
-#define WM8993_HPOUT2_MUTE_SHIFT 5 /* HPOUT2_MUTE */
-#define WM8993_HPOUT2_MUTE_WIDTH 1 /* HPOUT2_MUTE */
-#define WM8993_HPOUT2_VOL 0x0010 /* HPOUT2_VOL */
-#define WM8993_HPOUT2_VOL_MASK 0x0010 /* HPOUT2_VOL */
-#define WM8993_HPOUT2_VOL_SHIFT 4 /* HPOUT2_VOL */
-#define WM8993_HPOUT2_VOL_WIDTH 1 /* HPOUT2_VOL */
-
-/*
- * R32 (0x20) - Left OPGA Volume
- */
-#define WM8993_MIXOUT_VU 0x0100 /* MIXOUT_VU */
-#define WM8993_MIXOUT_VU_MASK 0x0100 /* MIXOUT_VU */
-#define WM8993_MIXOUT_VU_SHIFT 8 /* MIXOUT_VU */
-#define WM8993_MIXOUT_VU_WIDTH 1 /* MIXOUT_VU */
-#define WM8993_MIXOUTL_ZC 0x0080 /* MIXOUTL_ZC */
-#define WM8993_MIXOUTL_ZC_MASK 0x0080 /* MIXOUTL_ZC */
-#define WM8993_MIXOUTL_ZC_SHIFT 7 /* MIXOUTL_ZC */
-#define WM8993_MIXOUTL_ZC_WIDTH 1 /* MIXOUTL_ZC */
-#define WM8993_MIXOUTL_MUTE_N 0x0040 /* MIXOUTL_MUTE_N */
-#define WM8993_MIXOUTL_MUTE_N_MASK 0x0040 /* MIXOUTL_MUTE_N */
-#define WM8993_MIXOUTL_MUTE_N_SHIFT 6 /* MIXOUTL_MUTE_N */
-#define WM8993_MIXOUTL_MUTE_N_WIDTH 1 /* MIXOUTL_MUTE_N */
-#define WM8993_MIXOUTL_VOL_MASK 0x003F /* MIXOUTL_VOL - [5:0] */
-#define WM8993_MIXOUTL_VOL_SHIFT 0 /* MIXOUTL_VOL - [5:0] */
-#define WM8993_MIXOUTL_VOL_WIDTH 6 /* MIXOUTL_VOL - [5:0] */
-
-/*
- * R33 (0x21) - Right OPGA Volume
- */
-#define WM8993_MIXOUT_VU 0x0100 /* MIXOUT_VU */
-#define WM8993_MIXOUT_VU_MASK 0x0100 /* MIXOUT_VU */
-#define WM8993_MIXOUT_VU_SHIFT 8 /* MIXOUT_VU */
-#define WM8993_MIXOUT_VU_WIDTH 1 /* MIXOUT_VU */
-#define WM8993_MIXOUTR_ZC 0x0080 /* MIXOUTR_ZC */
-#define WM8993_MIXOUTR_ZC_MASK 0x0080 /* MIXOUTR_ZC */
-#define WM8993_MIXOUTR_ZC_SHIFT 7 /* MIXOUTR_ZC */
-#define WM8993_MIXOUTR_ZC_WIDTH 1 /* MIXOUTR_ZC */
-#define WM8993_MIXOUTR_MUTE_N 0x0040 /* MIXOUTR_MUTE_N */
-#define WM8993_MIXOUTR_MUTE_N_MASK 0x0040 /* MIXOUTR_MUTE_N */
-#define WM8993_MIXOUTR_MUTE_N_SHIFT 6 /* MIXOUTR_MUTE_N */
-#define WM8993_MIXOUTR_MUTE_N_WIDTH 1 /* MIXOUTR_MUTE_N */
-#define WM8993_MIXOUTR_VOL_MASK 0x003F /* MIXOUTR_VOL - [5:0] */
-#define WM8993_MIXOUTR_VOL_SHIFT 0 /* MIXOUTR_VOL - [5:0] */
-#define WM8993_MIXOUTR_VOL_WIDTH 6 /* MIXOUTR_VOL - [5:0] */
-
-/*
- * R34 (0x22) - SPKMIXL Attenuation
- */
-#define WM8993_MIXINL_SPKMIXL_VOL 0x0020 /* MIXINL_SPKMIXL_VOL */
-#define WM8993_MIXINL_SPKMIXL_VOL_MASK 0x0020 /* MIXINL_SPKMIXL_VOL */
-#define WM8993_MIXINL_SPKMIXL_VOL_SHIFT 5 /* MIXINL_SPKMIXL_VOL */
-#define WM8993_MIXINL_SPKMIXL_VOL_WIDTH 1 /* MIXINL_SPKMIXL_VOL */
-#define WM8993_IN1LP_SPKMIXL_VOL 0x0010 /* IN1LP_SPKMIXL_VOL */
-#define WM8993_IN1LP_SPKMIXL_VOL_MASK 0x0010 /* IN1LP_SPKMIXL_VOL */
-#define WM8993_IN1LP_SPKMIXL_VOL_SHIFT 4 /* IN1LP_SPKMIXL_VOL */
-#define WM8993_IN1LP_SPKMIXL_VOL_WIDTH 1 /* IN1LP_SPKMIXL_VOL */
-#define WM8993_MIXOUTL_SPKMIXL_VOL 0x0008 /* MIXOUTL_SPKMIXL_VOL */
-#define WM8993_MIXOUTL_SPKMIXL_VOL_MASK 0x0008 /* MIXOUTL_SPKMIXL_VOL */
-#define WM8993_MIXOUTL_SPKMIXL_VOL_SHIFT 3 /* MIXOUTL_SPKMIXL_VOL */
-#define WM8993_MIXOUTL_SPKMIXL_VOL_WIDTH 1 /* MIXOUTL_SPKMIXL_VOL */
-#define WM8993_DACL_SPKMIXL_VOL 0x0004 /* DACL_SPKMIXL_VOL */
-#define WM8993_DACL_SPKMIXL_VOL_MASK 0x0004 /* DACL_SPKMIXL_VOL */
-#define WM8993_DACL_SPKMIXL_VOL_SHIFT 2 /* DACL_SPKMIXL_VOL */
-#define WM8993_DACL_SPKMIXL_VOL_WIDTH 1 /* DACL_SPKMIXL_VOL */
-#define WM8993_SPKMIXL_VOL_MASK 0x0003 /* SPKMIXL_VOL - [1:0] */
-#define WM8993_SPKMIXL_VOL_SHIFT 0 /* SPKMIXL_VOL - [1:0] */
-#define WM8993_SPKMIXL_VOL_WIDTH 2 /* SPKMIXL_VOL - [1:0] */
-
-/*
- * R35 (0x23) - SPKMIXR Attenuation
- */
-#define WM8993_SPKOUT_CLASSAB_MODE 0x0100 /* SPKOUT_CLASSAB_MODE */
-#define WM8993_SPKOUT_CLASSAB_MODE_MASK 0x0100 /* SPKOUT_CLASSAB_MODE */
-#define WM8993_SPKOUT_CLASSAB_MODE_SHIFT 8 /* SPKOUT_CLASSAB_MODE */
-#define WM8993_SPKOUT_CLASSAB_MODE_WIDTH 1 /* SPKOUT_CLASSAB_MODE */
-#define WM8993_MIXINR_SPKMIXR_VOL 0x0020 /* MIXINR_SPKMIXR_VOL */
-#define WM8993_MIXINR_SPKMIXR_VOL_MASK 0x0020 /* MIXINR_SPKMIXR_VOL */
-#define WM8993_MIXINR_SPKMIXR_VOL_SHIFT 5 /* MIXINR_SPKMIXR_VOL */
-#define WM8993_MIXINR_SPKMIXR_VOL_WIDTH 1 /* MIXINR_SPKMIXR_VOL */
-#define WM8993_IN1RP_SPKMIXR_VOL 0x0010 /* IN1RP_SPKMIXR_VOL */
-#define WM8993_IN1RP_SPKMIXR_VOL_MASK 0x0010 /* IN1RP_SPKMIXR_VOL */
-#define WM8993_IN1RP_SPKMIXR_VOL_SHIFT 4 /* IN1RP_SPKMIXR_VOL */
-#define WM8993_IN1RP_SPKMIXR_VOL_WIDTH 1 /* IN1RP_SPKMIXR_VOL */
-#define WM8993_MIXOUTR_SPKMIXR_VOL 0x0008 /* MIXOUTR_SPKMIXR_VOL */
-#define WM8993_MIXOUTR_SPKMIXR_VOL_MASK 0x0008 /* MIXOUTR_SPKMIXR_VOL */
-#define WM8993_MIXOUTR_SPKMIXR_VOL_SHIFT 3 /* MIXOUTR_SPKMIXR_VOL */
-#define WM8993_MIXOUTR_SPKMIXR_VOL_WIDTH 1 /* MIXOUTR_SPKMIXR_VOL */
-#define WM8993_DACR_SPKMIXR_VOL 0x0004 /* DACR_SPKMIXR_VOL */
-#define WM8993_DACR_SPKMIXR_VOL_MASK 0x0004 /* DACR_SPKMIXR_VOL */
-#define WM8993_DACR_SPKMIXR_VOL_SHIFT 2 /* DACR_SPKMIXR_VOL */
-#define WM8993_DACR_SPKMIXR_VOL_WIDTH 1 /* DACR_SPKMIXR_VOL */
-#define WM8993_SPKMIXR_VOL_MASK 0x0003 /* SPKMIXR_VOL - [1:0] */
-#define WM8993_SPKMIXR_VOL_SHIFT 0 /* SPKMIXR_VOL - [1:0] */
-#define WM8993_SPKMIXR_VOL_WIDTH 2 /* SPKMIXR_VOL - [1:0] */
-
-/*
- * R36 (0x24) - SPKOUT Mixers
- */
-#define WM8993_VRX_TO_SPKOUTL 0x0020 /* VRX_TO_SPKOUTL */
-#define WM8993_VRX_TO_SPKOUTL_MASK 0x0020 /* VRX_TO_SPKOUTL */
-#define WM8993_VRX_TO_SPKOUTL_SHIFT 5 /* VRX_TO_SPKOUTL */
-#define WM8993_VRX_TO_SPKOUTL_WIDTH 1 /* VRX_TO_SPKOUTL */
-#define WM8993_SPKMIXL_TO_SPKOUTL 0x0010 /* SPKMIXL_TO_SPKOUTL */
-#define WM8993_SPKMIXL_TO_SPKOUTL_MASK 0x0010 /* SPKMIXL_TO_SPKOUTL */
-#define WM8993_SPKMIXL_TO_SPKOUTL_SHIFT 4 /* SPKMIXL_TO_SPKOUTL */
-#define WM8993_SPKMIXL_TO_SPKOUTL_WIDTH 1 /* SPKMIXL_TO_SPKOUTL */
-#define WM8993_SPKMIXR_TO_SPKOUTL 0x0008 /* SPKMIXR_TO_SPKOUTL */
-#define WM8993_SPKMIXR_TO_SPKOUTL_MASK 0x0008 /* SPKMIXR_TO_SPKOUTL */
-#define WM8993_SPKMIXR_TO_SPKOUTL_SHIFT 3 /* SPKMIXR_TO_SPKOUTL */
-#define WM8993_SPKMIXR_TO_SPKOUTL_WIDTH 1 /* SPKMIXR_TO_SPKOUTL */
-#define WM8993_VRX_TO_SPKOUTR 0x0004 /* VRX_TO_SPKOUTR */
-#define WM8993_VRX_TO_SPKOUTR_MASK 0x0004 /* VRX_TO_SPKOUTR */
-#define WM8993_VRX_TO_SPKOUTR_SHIFT 2 /* VRX_TO_SPKOUTR */
-#define WM8993_VRX_TO_SPKOUTR_WIDTH 1 /* VRX_TO_SPKOUTR */
-#define WM8993_SPKMIXL_TO_SPKOUTR 0x0002 /* SPKMIXL_TO_SPKOUTR */
-#define WM8993_SPKMIXL_TO_SPKOUTR_MASK 0x0002 /* SPKMIXL_TO_SPKOUTR */
-#define WM8993_SPKMIXL_TO_SPKOUTR_SHIFT 1 /* SPKMIXL_TO_SPKOUTR */
-#define WM8993_SPKMIXL_TO_SPKOUTR_WIDTH 1 /* SPKMIXL_TO_SPKOUTR */
-#define WM8993_SPKMIXR_TO_SPKOUTR 0x0001 /* SPKMIXR_TO_SPKOUTR */
-#define WM8993_SPKMIXR_TO_SPKOUTR_MASK 0x0001 /* SPKMIXR_TO_SPKOUTR */
-#define WM8993_SPKMIXR_TO_SPKOUTR_SHIFT 0 /* SPKMIXR_TO_SPKOUTR */
-#define WM8993_SPKMIXR_TO_SPKOUTR_WIDTH 1 /* SPKMIXR_TO_SPKOUTR */
-
-/*
- * R37 (0x25) - SPKOUT Boost
- */
-#define WM8993_SPKOUTL_BOOST_MASK 0x0038 /* SPKOUTL_BOOST - [5:3] */
-#define WM8993_SPKOUTL_BOOST_SHIFT 3 /* SPKOUTL_BOOST - [5:3] */
-#define WM8993_SPKOUTL_BOOST_WIDTH 3 /* SPKOUTL_BOOST - [5:3] */
-#define WM8993_SPKOUTR_BOOST_MASK 0x0007 /* SPKOUTR_BOOST - [2:0] */
-#define WM8993_SPKOUTR_BOOST_SHIFT 0 /* SPKOUTR_BOOST - [2:0] */
-#define WM8993_SPKOUTR_BOOST_WIDTH 3 /* SPKOUTR_BOOST - [2:0] */
-
-/*
- * R38 (0x26) - Speaker Volume Left
- */
-#define WM8993_SPKOUT_VU 0x0100 /* SPKOUT_VU */
-#define WM8993_SPKOUT_VU_MASK 0x0100 /* SPKOUT_VU */
-#define WM8993_SPKOUT_VU_SHIFT 8 /* SPKOUT_VU */
-#define WM8993_SPKOUT_VU_WIDTH 1 /* SPKOUT_VU */
-#define WM8993_SPKOUTL_ZC 0x0080 /* SPKOUTL_ZC */
-#define WM8993_SPKOUTL_ZC_MASK 0x0080 /* SPKOUTL_ZC */
-#define WM8993_SPKOUTL_ZC_SHIFT 7 /* SPKOUTL_ZC */
-#define WM8993_SPKOUTL_ZC_WIDTH 1 /* SPKOUTL_ZC */
-#define WM8993_SPKOUTL_MUTE_N 0x0040 /* SPKOUTL_MUTE_N */
-#define WM8993_SPKOUTL_MUTE_N_MASK 0x0040 /* SPKOUTL_MUTE_N */
-#define WM8993_SPKOUTL_MUTE_N_SHIFT 6 /* SPKOUTL_MUTE_N */
-#define WM8993_SPKOUTL_MUTE_N_WIDTH 1 /* SPKOUTL_MUTE_N */
-#define WM8993_SPKOUTL_VOL_MASK 0x003F /* SPKOUTL_VOL - [5:0] */
-#define WM8993_SPKOUTL_VOL_SHIFT 0 /* SPKOUTL_VOL - [5:0] */
-#define WM8993_SPKOUTL_VOL_WIDTH 6 /* SPKOUTL_VOL - [5:0] */
-
-/*
- * R39 (0x27) - Speaker Volume Right
- */
-#define WM8993_SPKOUT_VU 0x0100 /* SPKOUT_VU */
-#define WM8993_SPKOUT_VU_MASK 0x0100 /* SPKOUT_VU */
-#define WM8993_SPKOUT_VU_SHIFT 8 /* SPKOUT_VU */
-#define WM8993_SPKOUT_VU_WIDTH 1 /* SPKOUT_VU */
-#define WM8993_SPKOUTR_ZC 0x0080 /* SPKOUTR_ZC */
-#define WM8993_SPKOUTR_ZC_MASK 0x0080 /* SPKOUTR_ZC */
-#define WM8993_SPKOUTR_ZC_SHIFT 7 /* SPKOUTR_ZC */
-#define WM8993_SPKOUTR_ZC_WIDTH 1 /* SPKOUTR_ZC */
-#define WM8993_SPKOUTR_MUTE_N 0x0040 /* SPKOUTR_MUTE_N */
-#define WM8993_SPKOUTR_MUTE_N_MASK 0x0040 /* SPKOUTR_MUTE_N */
-#define WM8993_SPKOUTR_MUTE_N_SHIFT 6 /* SPKOUTR_MUTE_N */
-#define WM8993_SPKOUTR_MUTE_N_WIDTH 1 /* SPKOUTR_MUTE_N */
-#define WM8993_SPKOUTR_VOL_MASK 0x003F /* SPKOUTR_VOL - [5:0] */
-#define WM8993_SPKOUTR_VOL_SHIFT 0 /* SPKOUTR_VOL - [5:0] */
-#define WM8993_SPKOUTR_VOL_WIDTH 6 /* SPKOUTR_VOL - [5:0] */
-
-/*
- * R40 (0x28) - Input Mixer2
- */
-#define WM8993_IN2LP_TO_IN2L 0x0080 /* IN2LP_TO_IN2L */
-#define WM8993_IN2LP_TO_IN2L_MASK 0x0080 /* IN2LP_TO_IN2L */
-#define WM8993_IN2LP_TO_IN2L_SHIFT 7 /* IN2LP_TO_IN2L */
-#define WM8993_IN2LP_TO_IN2L_WIDTH 1 /* IN2LP_TO_IN2L */
-#define WM8993_IN2LN_TO_IN2L 0x0040 /* IN2LN_TO_IN2L */
-#define WM8993_IN2LN_TO_IN2L_MASK 0x0040 /* IN2LN_TO_IN2L */
-#define WM8993_IN2LN_TO_IN2L_SHIFT 6 /* IN2LN_TO_IN2L */
-#define WM8993_IN2LN_TO_IN2L_WIDTH 1 /* IN2LN_TO_IN2L */
-#define WM8993_IN1LP_TO_IN1L 0x0020 /* IN1LP_TO_IN1L */
-#define WM8993_IN1LP_TO_IN1L_MASK 0x0020 /* IN1LP_TO_IN1L */
-#define WM8993_IN1LP_TO_IN1L_SHIFT 5 /* IN1LP_TO_IN1L */
-#define WM8993_IN1LP_TO_IN1L_WIDTH 1 /* IN1LP_TO_IN1L */
-#define WM8993_IN1LN_TO_IN1L 0x0010 /* IN1LN_TO_IN1L */
-#define WM8993_IN1LN_TO_IN1L_MASK 0x0010 /* IN1LN_TO_IN1L */
-#define WM8993_IN1LN_TO_IN1L_SHIFT 4 /* IN1LN_TO_IN1L */
-#define WM8993_IN1LN_TO_IN1L_WIDTH 1 /* IN1LN_TO_IN1L */
-#define WM8993_IN2RP_TO_IN2R 0x0008 /* IN2RP_TO_IN2R */
-#define WM8993_IN2RP_TO_IN2R_MASK 0x0008 /* IN2RP_TO_IN2R */
-#define WM8993_IN2RP_TO_IN2R_SHIFT 3 /* IN2RP_TO_IN2R */
-#define WM8993_IN2RP_TO_IN2R_WIDTH 1 /* IN2RP_TO_IN2R */
-#define WM8993_IN2RN_TO_IN2R 0x0004 /* IN2RN_TO_IN2R */
-#define WM8993_IN2RN_TO_IN2R_MASK 0x0004 /* IN2RN_TO_IN2R */
-#define WM8993_IN2RN_TO_IN2R_SHIFT 2 /* IN2RN_TO_IN2R */
-#define WM8993_IN2RN_TO_IN2R_WIDTH 1 /* IN2RN_TO_IN2R */
-#define WM8993_IN1RP_TO_IN1R 0x0002 /* IN1RP_TO_IN1R */
-#define WM8993_IN1RP_TO_IN1R_MASK 0x0002 /* IN1RP_TO_IN1R */
-#define WM8993_IN1RP_TO_IN1R_SHIFT 1 /* IN1RP_TO_IN1R */
-#define WM8993_IN1RP_TO_IN1R_WIDTH 1 /* IN1RP_TO_IN1R */
-#define WM8993_IN1RN_TO_IN1R 0x0001 /* IN1RN_TO_IN1R */
-#define WM8993_IN1RN_TO_IN1R_MASK 0x0001 /* IN1RN_TO_IN1R */
-#define WM8993_IN1RN_TO_IN1R_SHIFT 0 /* IN1RN_TO_IN1R */
-#define WM8993_IN1RN_TO_IN1R_WIDTH 1 /* IN1RN_TO_IN1R */
-
-/*
- * R41 (0x29) - Input Mixer3
- */
-#define WM8993_IN2L_TO_MIXINL 0x0100 /* IN2L_TO_MIXINL */
-#define WM8993_IN2L_TO_MIXINL_MASK 0x0100 /* IN2L_TO_MIXINL */
-#define WM8993_IN2L_TO_MIXINL_SHIFT 8 /* IN2L_TO_MIXINL */
-#define WM8993_IN2L_TO_MIXINL_WIDTH 1 /* IN2L_TO_MIXINL */
-#define WM8993_IN2L_MIXINL_VOL 0x0080 /* IN2L_MIXINL_VOL */
-#define WM8993_IN2L_MIXINL_VOL_MASK 0x0080 /* IN2L_MIXINL_VOL */
-#define WM8993_IN2L_MIXINL_VOL_SHIFT 7 /* IN2L_MIXINL_VOL */
-#define WM8993_IN2L_MIXINL_VOL_WIDTH 1 /* IN2L_MIXINL_VOL */
-#define WM8993_IN1L_TO_MIXINL 0x0020 /* IN1L_TO_MIXINL */
-#define WM8993_IN1L_TO_MIXINL_MASK 0x0020 /* IN1L_TO_MIXINL */
-#define WM8993_IN1L_TO_MIXINL_SHIFT 5 /* IN1L_TO_MIXINL */
-#define WM8993_IN1L_TO_MIXINL_WIDTH 1 /* IN1L_TO_MIXINL */
-#define WM8993_IN1L_MIXINL_VOL 0x0010 /* IN1L_MIXINL_VOL */
-#define WM8993_IN1L_MIXINL_VOL_MASK 0x0010 /* IN1L_MIXINL_VOL */
-#define WM8993_IN1L_MIXINL_VOL_SHIFT 4 /* IN1L_MIXINL_VOL */
-#define WM8993_IN1L_MIXINL_VOL_WIDTH 1 /* IN1L_MIXINL_VOL */
-#define WM8993_MIXOUTL_MIXINL_VOL_MASK 0x0007 /* MIXOUTL_MIXINL_VOL - [2:0] */
-#define WM8993_MIXOUTL_MIXINL_VOL_SHIFT 0 /* MIXOUTL_MIXINL_VOL - [2:0] */
-#define WM8993_MIXOUTL_MIXINL_VOL_WIDTH 3 /* MIXOUTL_MIXINL_VOL - [2:0] */
-
-/*
- * R42 (0x2A) - Input Mixer4
- */
-#define WM8993_IN2R_TO_MIXINR 0x0100 /* IN2R_TO_MIXINR */
-#define WM8993_IN2R_TO_MIXINR_MASK 0x0100 /* IN2R_TO_MIXINR */
-#define WM8993_IN2R_TO_MIXINR_SHIFT 8 /* IN2R_TO_MIXINR */
-#define WM8993_IN2R_TO_MIXINR_WIDTH 1 /* IN2R_TO_MIXINR */
-#define WM8993_IN2R_MIXINR_VOL 0x0080 /* IN2R_MIXINR_VOL */
-#define WM8993_IN2R_MIXINR_VOL_MASK 0x0080 /* IN2R_MIXINR_VOL */
-#define WM8993_IN2R_MIXINR_VOL_SHIFT 7 /* IN2R_MIXINR_VOL */
-#define WM8993_IN2R_MIXINR_VOL_WIDTH 1 /* IN2R_MIXINR_VOL */
-#define WM8993_IN1R_TO_MIXINR 0x0020 /* IN1R_TO_MIXINR */
-#define WM8993_IN1R_TO_MIXINR_MASK 0x0020 /* IN1R_TO_MIXINR */
-#define WM8993_IN1R_TO_MIXINR_SHIFT 5 /* IN1R_TO_MIXINR */
-#define WM8993_IN1R_TO_MIXINR_WIDTH 1 /* IN1R_TO_MIXINR */
-#define WM8993_IN1R_MIXINR_VOL 0x0010 /* IN1R_MIXINR_VOL */
-#define WM8993_IN1R_MIXINR_VOL_MASK 0x0010 /* IN1R_MIXINR_VOL */
-#define WM8993_IN1R_MIXINR_VOL_SHIFT 4 /* IN1R_MIXINR_VOL */
-#define WM8993_IN1R_MIXINR_VOL_WIDTH 1 /* IN1R_MIXINR_VOL */
-#define WM8993_MIXOUTR_MIXINR_VOL_MASK 0x0007 /* MIXOUTR_MIXINR_VOL - [2:0] */
-#define WM8993_MIXOUTR_MIXINR_VOL_SHIFT 0 /* MIXOUTR_MIXINR_VOL - [2:0] */
-#define WM8993_MIXOUTR_MIXINR_VOL_WIDTH 3 /* MIXOUTR_MIXINR_VOL - [2:0] */
-
-/*
- * R43 (0x2B) - Input Mixer5
- */
-#define WM8993_IN1LP_MIXINL_VOL_MASK 0x01C0 /* IN1LP_MIXINL_VOL - [8:6] */
-#define WM8993_IN1LP_MIXINL_VOL_SHIFT 6 /* IN1LP_MIXINL_VOL - [8:6] */
-#define WM8993_IN1LP_MIXINL_VOL_WIDTH 3 /* IN1LP_MIXINL_VOL - [8:6] */
-#define WM8993_VRX_MIXINL_VOL_MASK 0x0007 /* VRX_MIXINL_VOL - [2:0] */
-#define WM8993_VRX_MIXINL_VOL_SHIFT 0 /* VRX_MIXINL_VOL - [2:0] */
-#define WM8993_VRX_MIXINL_VOL_WIDTH 3 /* VRX_MIXINL_VOL - [2:0] */
-
-/*
- * R44 (0x2C) - Input Mixer6
- */
-#define WM8993_IN1RP_MIXINR_VOL_MASK 0x01C0 /* IN1RP_MIXINR_VOL - [8:6] */
-#define WM8993_IN1RP_MIXINR_VOL_SHIFT 6 /* IN1RP_MIXINR_VOL - [8:6] */
-#define WM8993_IN1RP_MIXINR_VOL_WIDTH 3 /* IN1RP_MIXINR_VOL - [8:6] */
-#define WM8993_VRX_MIXINR_VOL_MASK 0x0007 /* VRX_MIXINR_VOL - [2:0] */
-#define WM8993_VRX_MIXINR_VOL_SHIFT 0 /* VRX_MIXINR_VOL - [2:0] */
-#define WM8993_VRX_MIXINR_VOL_WIDTH 3 /* VRX_MIXINR_VOL - [2:0] */
-
-/*
- * R45 (0x2D) - Output Mixer1
- */
-#define WM8993_DACL_TO_HPOUT1L 0x0100 /* DACL_TO_HPOUT1L */
-#define WM8993_DACL_TO_HPOUT1L_MASK 0x0100 /* DACL_TO_HPOUT1L */
-#define WM8993_DACL_TO_HPOUT1L_SHIFT 8 /* DACL_TO_HPOUT1L */
-#define WM8993_DACL_TO_HPOUT1L_WIDTH 1 /* DACL_TO_HPOUT1L */
-#define WM8993_MIXINR_TO_MIXOUTL 0x0080 /* MIXINR_TO_MIXOUTL */
-#define WM8993_MIXINR_TO_MIXOUTL_MASK 0x0080 /* MIXINR_TO_MIXOUTL */
-#define WM8993_MIXINR_TO_MIXOUTL_SHIFT 7 /* MIXINR_TO_MIXOUTL */
-#define WM8993_MIXINR_TO_MIXOUTL_WIDTH 1 /* MIXINR_TO_MIXOUTL */
-#define WM8993_MIXINL_TO_MIXOUTL 0x0040 /* MIXINL_TO_MIXOUTL */
-#define WM8993_MIXINL_TO_MIXOUTL_MASK 0x0040 /* MIXINL_TO_MIXOUTL */
-#define WM8993_MIXINL_TO_MIXOUTL_SHIFT 6 /* MIXINL_TO_MIXOUTL */
-#define WM8993_MIXINL_TO_MIXOUTL_WIDTH 1 /* MIXINL_TO_MIXOUTL */
-#define WM8993_IN2RN_TO_MIXOUTL 0x0020 /* IN2RN_TO_MIXOUTL */
-#define WM8993_IN2RN_TO_MIXOUTL_MASK 0x0020 /* IN2RN_TO_MIXOUTL */
-#define WM8993_IN2RN_TO_MIXOUTL_SHIFT 5 /* IN2RN_TO_MIXOUTL */
-#define WM8993_IN2RN_TO_MIXOUTL_WIDTH 1 /* IN2RN_TO_MIXOUTL */
-#define WM8993_IN2LN_TO_MIXOUTL 0x0010 /* IN2LN_TO_MIXOUTL */
-#define WM8993_IN2LN_TO_MIXOUTL_MASK 0x0010 /* IN2LN_TO_MIXOUTL */
-#define WM8993_IN2LN_TO_MIXOUTL_SHIFT 4 /* IN2LN_TO_MIXOUTL */
-#define WM8993_IN2LN_TO_MIXOUTL_WIDTH 1 /* IN2LN_TO_MIXOUTL */
-#define WM8993_IN1R_TO_MIXOUTL 0x0008 /* IN1R_TO_MIXOUTL */
-#define WM8993_IN1R_TO_MIXOUTL_MASK 0x0008 /* IN1R_TO_MIXOUTL */
-#define WM8993_IN1R_TO_MIXOUTL_SHIFT 3 /* IN1R_TO_MIXOUTL */
-#define WM8993_IN1R_TO_MIXOUTL_WIDTH 1 /* IN1R_TO_MIXOUTL */
-#define WM8993_IN1L_TO_MIXOUTL 0x0004 /* IN1L_TO_MIXOUTL */
-#define WM8993_IN1L_TO_MIXOUTL_MASK 0x0004 /* IN1L_TO_MIXOUTL */
-#define WM8993_IN1L_TO_MIXOUTL_SHIFT 2 /* IN1L_TO_MIXOUTL */
-#define WM8993_IN1L_TO_MIXOUTL_WIDTH 1 /* IN1L_TO_MIXOUTL */
-#define WM8993_IN2LP_TO_MIXOUTL 0x0002 /* IN2LP_TO_MIXOUTL */
-#define WM8993_IN2LP_TO_MIXOUTL_MASK 0x0002 /* IN2LP_TO_MIXOUTL */
-#define WM8993_IN2LP_TO_MIXOUTL_SHIFT 1 /* IN2LP_TO_MIXOUTL */
-#define WM8993_IN2LP_TO_MIXOUTL_WIDTH 1 /* IN2LP_TO_MIXOUTL */
-#define WM8993_DACL_TO_MIXOUTL 0x0001 /* DACL_TO_MIXOUTL */
-#define WM8993_DACL_TO_MIXOUTL_MASK 0x0001 /* DACL_TO_MIXOUTL */
-#define WM8993_DACL_TO_MIXOUTL_SHIFT 0 /* DACL_TO_MIXOUTL */
-#define WM8993_DACL_TO_MIXOUTL_WIDTH 1 /* DACL_TO_MIXOUTL */
-
-/*
- * R46 (0x2E) - Output Mixer2
- */
-#define WM8993_DACR_TO_HPOUT1R 0x0100 /* DACR_TO_HPOUT1R */
-#define WM8993_DACR_TO_HPOUT1R_MASK 0x0100 /* DACR_TO_HPOUT1R */
-#define WM8993_DACR_TO_HPOUT1R_SHIFT 8 /* DACR_TO_HPOUT1R */
-#define WM8993_DACR_TO_HPOUT1R_WIDTH 1 /* DACR_TO_HPOUT1R */
-#define WM8993_MIXINL_TO_MIXOUTR 0x0080 /* MIXINL_TO_MIXOUTR */
-#define WM8993_MIXINL_TO_MIXOUTR_MASK 0x0080 /* MIXINL_TO_MIXOUTR */
-#define WM8993_MIXINL_TO_MIXOUTR_SHIFT 7 /* MIXINL_TO_MIXOUTR */
-#define WM8993_MIXINL_TO_MIXOUTR_WIDTH 1 /* MIXINL_TO_MIXOUTR */
-#define WM8993_MIXINR_TO_MIXOUTR 0x0040 /* MIXINR_TO_MIXOUTR */
-#define WM8993_MIXINR_TO_MIXOUTR_MASK 0x0040 /* MIXINR_TO_MIXOUTR */
-#define WM8993_MIXINR_TO_MIXOUTR_SHIFT 6 /* MIXINR_TO_MIXOUTR */
-#define WM8993_MIXINR_TO_MIXOUTR_WIDTH 1 /* MIXINR_TO_MIXOUTR */
-#define WM8993_IN2LN_TO_MIXOUTR 0x0020 /* IN2LN_TO_MIXOUTR */
-#define WM8993_IN2LN_TO_MIXOUTR_MASK 0x0020 /* IN2LN_TO_MIXOUTR */
-#define WM8993_IN2LN_TO_MIXOUTR_SHIFT 5 /* IN2LN_TO_MIXOUTR */
-#define WM8993_IN2LN_TO_MIXOUTR_WIDTH 1 /* IN2LN_TO_MIXOUTR */
-#define WM8993_IN2RN_TO_MIXOUTR 0x0010 /* IN2RN_TO_MIXOUTR */
-#define WM8993_IN2RN_TO_MIXOUTR_MASK 0x0010 /* IN2RN_TO_MIXOUTR */
-#define WM8993_IN2RN_TO_MIXOUTR_SHIFT 4 /* IN2RN_TO_MIXOUTR */
-#define WM8993_IN2RN_TO_MIXOUTR_WIDTH 1 /* IN2RN_TO_MIXOUTR */
-#define WM8993_IN1L_TO_MIXOUTR 0x0008 /* IN1L_TO_MIXOUTR */
-#define WM8993_IN1L_TO_MIXOUTR_MASK 0x0008 /* IN1L_TO_MIXOUTR */
-#define WM8993_IN1L_TO_MIXOUTR_SHIFT 3 /* IN1L_TO_MIXOUTR */
-#define WM8993_IN1L_TO_MIXOUTR_WIDTH 1 /* IN1L_TO_MIXOUTR */
-#define WM8993_IN1R_TO_MIXOUTR 0x0004 /* IN1R_TO_MIXOUTR */
-#define WM8993_IN1R_TO_MIXOUTR_MASK 0x0004 /* IN1R_TO_MIXOUTR */
-#define WM8993_IN1R_TO_MIXOUTR_SHIFT 2 /* IN1R_TO_MIXOUTR */
-#define WM8993_IN1R_TO_MIXOUTR_WIDTH 1 /* IN1R_TO_MIXOUTR */
-#define WM8993_IN2RP_TO_MIXOUTR 0x0002 /* IN2RP_TO_MIXOUTR */
-#define WM8993_IN2RP_TO_MIXOUTR_MASK 0x0002 /* IN2RP_TO_MIXOUTR */
-#define WM8993_IN2RP_TO_MIXOUTR_SHIFT 1 /* IN2RP_TO_MIXOUTR */
-#define WM8993_IN2RP_TO_MIXOUTR_WIDTH 1 /* IN2RP_TO_MIXOUTR */
-#define WM8993_DACR_TO_MIXOUTR 0x0001 /* DACR_TO_MIXOUTR */
-#define WM8993_DACR_TO_MIXOUTR_MASK 0x0001 /* DACR_TO_MIXOUTR */
-#define WM8993_DACR_TO_MIXOUTR_SHIFT 0 /* DACR_TO_MIXOUTR */
-#define WM8993_DACR_TO_MIXOUTR_WIDTH 1 /* DACR_TO_MIXOUTR */
-
-/*
- * R47 (0x2F) - Output Mixer3
- */
-#define WM8993_IN2LP_MIXOUTL_VOL_MASK 0x0E00 /* IN2LP_MIXOUTL_VOL - [11:9] */
-#define WM8993_IN2LP_MIXOUTL_VOL_SHIFT 9 /* IN2LP_MIXOUTL_VOL - [11:9] */
-#define WM8993_IN2LP_MIXOUTL_VOL_WIDTH 3 /* IN2LP_MIXOUTL_VOL - [11:9] */
-#define WM8993_IN2LN_MIXOUTL_VOL_MASK 0x01C0 /* IN2LN_MIXOUTL_VOL - [8:6] */
-#define WM8993_IN2LN_MIXOUTL_VOL_SHIFT 6 /* IN2LN_MIXOUTL_VOL - [8:6] */
-#define WM8993_IN2LN_MIXOUTL_VOL_WIDTH 3 /* IN2LN_MIXOUTL_VOL - [8:6] */
-#define WM8993_IN1R_MIXOUTL_VOL_MASK 0x0038 /* IN1R_MIXOUTL_VOL - [5:3] */
-#define WM8993_IN1R_MIXOUTL_VOL_SHIFT 3 /* IN1R_MIXOUTL_VOL - [5:3] */
-#define WM8993_IN1R_MIXOUTL_VOL_WIDTH 3 /* IN1R_MIXOUTL_VOL - [5:3] */
-#define WM8993_IN1L_MIXOUTL_VOL_MASK 0x0007 /* IN1L_MIXOUTL_VOL - [2:0] */
-#define WM8993_IN1L_MIXOUTL_VOL_SHIFT 0 /* IN1L_MIXOUTL_VOL - [2:0] */
-#define WM8993_IN1L_MIXOUTL_VOL_WIDTH 3 /* IN1L_MIXOUTL_VOL - [2:0] */
-
-/*
- * R48 (0x30) - Output Mixer4
- */
-#define WM8993_IN2RP_MIXOUTR_VOL_MASK 0x0E00 /* IN2RP_MIXOUTR_VOL - [11:9] */
-#define WM8993_IN2RP_MIXOUTR_VOL_SHIFT 9 /* IN2RP_MIXOUTR_VOL - [11:9] */
-#define WM8993_IN2RP_MIXOUTR_VOL_WIDTH 3 /* IN2RP_MIXOUTR_VOL - [11:9] */
-#define WM8993_IN2RN_MIXOUTR_VOL_MASK 0x01C0 /* IN2RN_MIXOUTR_VOL - [8:6] */
-#define WM8993_IN2RN_MIXOUTR_VOL_SHIFT 6 /* IN2RN_MIXOUTR_VOL - [8:6] */
-#define WM8993_IN2RN_MIXOUTR_VOL_WIDTH 3 /* IN2RN_MIXOUTR_VOL - [8:6] */
-#define WM8993_IN1L_MIXOUTR_VOL_MASK 0x0038 /* IN1L_MIXOUTR_VOL - [5:3] */
-#define WM8993_IN1L_MIXOUTR_VOL_SHIFT 3 /* IN1L_MIXOUTR_VOL - [5:3] */
-#define WM8993_IN1L_MIXOUTR_VOL_WIDTH 3 /* IN1L_MIXOUTR_VOL - [5:3] */
-#define WM8993_IN1R_MIXOUTR_VOL_MASK 0x0007 /* IN1R_MIXOUTR_VOL - [2:0] */
-#define WM8993_IN1R_MIXOUTR_VOL_SHIFT 0 /* IN1R_MIXOUTR_VOL - [2:0] */
-#define WM8993_IN1R_MIXOUTR_VOL_WIDTH 3 /* IN1R_MIXOUTR_VOL - [2:0] */
-
-/*
- * R49 (0x31) - Output Mixer5
- */
-#define WM8993_DACL_MIXOUTL_VOL_MASK 0x0E00 /* DACL_MIXOUTL_VOL - [11:9] */
-#define WM8993_DACL_MIXOUTL_VOL_SHIFT 9 /* DACL_MIXOUTL_VOL - [11:9] */
-#define WM8993_DACL_MIXOUTL_VOL_WIDTH 3 /* DACL_MIXOUTL_VOL - [11:9] */
-#define WM8993_IN2RN_MIXOUTL_VOL_MASK 0x01C0 /* IN2RN_MIXOUTL_VOL - [8:6] */
-#define WM8993_IN2RN_MIXOUTL_VOL_SHIFT 6 /* IN2RN_MIXOUTL_VOL - [8:6] */
-#define WM8993_IN2RN_MIXOUTL_VOL_WIDTH 3 /* IN2RN_MIXOUTL_VOL - [8:6] */
-#define WM8993_MIXINR_MIXOUTL_VOL_MASK 0x0038 /* MIXINR_MIXOUTL_VOL - [5:3] */
-#define WM8993_MIXINR_MIXOUTL_VOL_SHIFT 3 /* MIXINR_MIXOUTL_VOL - [5:3] */
-#define WM8993_MIXINR_MIXOUTL_VOL_WIDTH 3 /* MIXINR_MIXOUTL_VOL - [5:3] */
-#define WM8993_MIXINL_MIXOUTL_VOL_MASK 0x0007 /* MIXINL_MIXOUTL_VOL - [2:0] */
-#define WM8993_MIXINL_MIXOUTL_VOL_SHIFT 0 /* MIXINL_MIXOUTL_VOL - [2:0] */
-#define WM8993_MIXINL_MIXOUTL_VOL_WIDTH 3 /* MIXINL_MIXOUTL_VOL - [2:0] */
-
-/*
- * R50 (0x32) - Output Mixer6
- */
-#define WM8993_DACR_MIXOUTR_VOL_MASK 0x0E00 /* DACR_MIXOUTR_VOL - [11:9] */
-#define WM8993_DACR_MIXOUTR_VOL_SHIFT 9 /* DACR_MIXOUTR_VOL - [11:9] */
-#define WM8993_DACR_MIXOUTR_VOL_WIDTH 3 /* DACR_MIXOUTR_VOL - [11:9] */
-#define WM8993_IN2LN_MIXOUTR_VOL_MASK 0x01C0 /* IN2LN_MIXOUTR_VOL - [8:6] */
-#define WM8993_IN2LN_MIXOUTR_VOL_SHIFT 6 /* IN2LN_MIXOUTR_VOL - [8:6] */
-#define WM8993_IN2LN_MIXOUTR_VOL_WIDTH 3 /* IN2LN_MIXOUTR_VOL - [8:6] */
-#define WM8993_MIXINL_MIXOUTR_VOL_MASK 0x0038 /* MIXINL_MIXOUTR_VOL - [5:3] */
-#define WM8993_MIXINL_MIXOUTR_VOL_SHIFT 3 /* MIXINL_MIXOUTR_VOL - [5:3] */
-#define WM8993_MIXINL_MIXOUTR_VOL_WIDTH 3 /* MIXINL_MIXOUTR_VOL - [5:3] */
-#define WM8993_MIXINR_MIXOUTR_VOL_MASK 0x0007 /* MIXINR_MIXOUTR_VOL - [2:0] */
-#define WM8993_MIXINR_MIXOUTR_VOL_SHIFT 0 /* MIXINR_MIXOUTR_VOL - [2:0] */
-#define WM8993_MIXINR_MIXOUTR_VOL_WIDTH 3 /* MIXINR_MIXOUTR_VOL - [2:0] */
-
-/*
- * R51 (0x33) - HPOUT2 Mixer
- */
-#define WM8993_VRX_TO_HPOUT2 0x0020 /* VRX_TO_HPOUT2 */
-#define WM8993_VRX_TO_HPOUT2_MASK 0x0020 /* VRX_TO_HPOUT2 */
-#define WM8993_VRX_TO_HPOUT2_SHIFT 5 /* VRX_TO_HPOUT2 */
-#define WM8993_VRX_TO_HPOUT2_WIDTH 1 /* VRX_TO_HPOUT2 */
-#define WM8993_MIXOUTLVOL_TO_HPOUT2 0x0010 /* MIXOUTLVOL_TO_HPOUT2 */
-#define WM8993_MIXOUTLVOL_TO_HPOUT2_MASK 0x0010 /* MIXOUTLVOL_TO_HPOUT2 */
-#define WM8993_MIXOUTLVOL_TO_HPOUT2_SHIFT 4 /* MIXOUTLVOL_TO_HPOUT2 */
-#define WM8993_MIXOUTLVOL_TO_HPOUT2_WIDTH 1 /* MIXOUTLVOL_TO_HPOUT2 */
-#define WM8993_MIXOUTRVOL_TO_HPOUT2 0x0008 /* MIXOUTRVOL_TO_HPOUT2 */
-#define WM8993_MIXOUTRVOL_TO_HPOUT2_MASK 0x0008 /* MIXOUTRVOL_TO_HPOUT2 */
-#define WM8993_MIXOUTRVOL_TO_HPOUT2_SHIFT 3 /* MIXOUTRVOL_TO_HPOUT2 */
-#define WM8993_MIXOUTRVOL_TO_HPOUT2_WIDTH 1 /* MIXOUTRVOL_TO_HPOUT2 */
-
-/*
- * R52 (0x34) - Line Mixer1
- */
-#define WM8993_MIXOUTL_TO_LINEOUT1N 0x0040 /* MIXOUTL_TO_LINEOUT1N */
-#define WM8993_MIXOUTL_TO_LINEOUT1N_MASK 0x0040 /* MIXOUTL_TO_LINEOUT1N */
-#define WM8993_MIXOUTL_TO_LINEOUT1N_SHIFT 6 /* MIXOUTL_TO_LINEOUT1N */
-#define WM8993_MIXOUTL_TO_LINEOUT1N_WIDTH 1 /* MIXOUTL_TO_LINEOUT1N */
-#define WM8993_MIXOUTR_TO_LINEOUT1N 0x0020 /* MIXOUTR_TO_LINEOUT1N */
-#define WM8993_MIXOUTR_TO_LINEOUT1N_MASK 0x0020 /* MIXOUTR_TO_LINEOUT1N */
-#define WM8993_MIXOUTR_TO_LINEOUT1N_SHIFT 5 /* MIXOUTR_TO_LINEOUT1N */
-#define WM8993_MIXOUTR_TO_LINEOUT1N_WIDTH 1 /* MIXOUTR_TO_LINEOUT1N */
-#define WM8993_LINEOUT1_MODE 0x0010 /* LINEOUT1_MODE */
-#define WM8993_LINEOUT1_MODE_MASK 0x0010 /* LINEOUT1_MODE */
-#define WM8993_LINEOUT1_MODE_SHIFT 4 /* LINEOUT1_MODE */
-#define WM8993_LINEOUT1_MODE_WIDTH 1 /* LINEOUT1_MODE */
-#define WM8993_IN1R_TO_LINEOUT1P 0x0004 /* IN1R_TO_LINEOUT1P */
-#define WM8993_IN1R_TO_LINEOUT1P_MASK 0x0004 /* IN1R_TO_LINEOUT1P */
-#define WM8993_IN1R_TO_LINEOUT1P_SHIFT 2 /* IN1R_TO_LINEOUT1P */
-#define WM8993_IN1R_TO_LINEOUT1P_WIDTH 1 /* IN1R_TO_LINEOUT1P */
-#define WM8993_IN1L_TO_LINEOUT1P 0x0002 /* IN1L_TO_LINEOUT1P */
-#define WM8993_IN1L_TO_LINEOUT1P_MASK 0x0002 /* IN1L_TO_LINEOUT1P */
-#define WM8993_IN1L_TO_LINEOUT1P_SHIFT 1 /* IN1L_TO_LINEOUT1P */
-#define WM8993_IN1L_TO_LINEOUT1P_WIDTH 1 /* IN1L_TO_LINEOUT1P */
-#define WM8993_MIXOUTL_TO_LINEOUT1P 0x0001 /* MIXOUTL_TO_LINEOUT1P */
-#define WM8993_MIXOUTL_TO_LINEOUT1P_MASK 0x0001 /* MIXOUTL_TO_LINEOUT1P */
-#define WM8993_MIXOUTL_TO_LINEOUT1P_SHIFT 0 /* MIXOUTL_TO_LINEOUT1P */
-#define WM8993_MIXOUTL_TO_LINEOUT1P_WIDTH 1 /* MIXOUTL_TO_LINEOUT1P */
-
-/*
- * R53 (0x35) - Line Mixer2
- */
-#define WM8993_MIXOUTR_TO_LINEOUT2N 0x0040 /* MIXOUTR_TO_LINEOUT2N */
-#define WM8993_MIXOUTR_TO_LINEOUT2N_MASK 0x0040 /* MIXOUTR_TO_LINEOUT2N */
-#define WM8993_MIXOUTR_TO_LINEOUT2N_SHIFT 6 /* MIXOUTR_TO_LINEOUT2N */
-#define WM8993_MIXOUTR_TO_LINEOUT2N_WIDTH 1 /* MIXOUTR_TO_LINEOUT2N */
-#define WM8993_MIXOUTL_TO_LINEOUT2N 0x0020 /* MIXOUTL_TO_LINEOUT2N */
-#define WM8993_MIXOUTL_TO_LINEOUT2N_MASK 0x0020 /* MIXOUTL_TO_LINEOUT2N */
-#define WM8993_MIXOUTL_TO_LINEOUT2N_SHIFT 5 /* MIXOUTL_TO_LINEOUT2N */
-#define WM8993_MIXOUTL_TO_LINEOUT2N_WIDTH 1 /* MIXOUTL_TO_LINEOUT2N */
-#define WM8993_LINEOUT2_MODE 0x0010 /* LINEOUT2_MODE */
-#define WM8993_LINEOUT2_MODE_MASK 0x0010 /* LINEOUT2_MODE */
-#define WM8993_LINEOUT2_MODE_SHIFT 4 /* LINEOUT2_MODE */
-#define WM8993_LINEOUT2_MODE_WIDTH 1 /* LINEOUT2_MODE */
-#define WM8993_IN1L_TO_LINEOUT2P 0x0004 /* IN1L_TO_LINEOUT2P */
-#define WM8993_IN1L_TO_LINEOUT2P_MASK 0x0004 /* IN1L_TO_LINEOUT2P */
-#define WM8993_IN1L_TO_LINEOUT2P_SHIFT 2 /* IN1L_TO_LINEOUT2P */
-#define WM8993_IN1L_TO_LINEOUT2P_WIDTH 1 /* IN1L_TO_LINEOUT2P */
-#define WM8993_IN1R_TO_LINEOUT2P 0x0002 /* IN1R_TO_LINEOUT2P */
-#define WM8993_IN1R_TO_LINEOUT2P_MASK 0x0002 /* IN1R_TO_LINEOUT2P */
-#define WM8993_IN1R_TO_LINEOUT2P_SHIFT 1 /* IN1R_TO_LINEOUT2P */
-#define WM8993_IN1R_TO_LINEOUT2P_WIDTH 1 /* IN1R_TO_LINEOUT2P */
-#define WM8993_MIXOUTR_TO_LINEOUT2P 0x0001 /* MIXOUTR_TO_LINEOUT2P */
-#define WM8993_MIXOUTR_TO_LINEOUT2P_MASK 0x0001 /* MIXOUTR_TO_LINEOUT2P */
-#define WM8993_MIXOUTR_TO_LINEOUT2P_SHIFT 0 /* MIXOUTR_TO_LINEOUT2P */
-#define WM8993_MIXOUTR_TO_LINEOUT2P_WIDTH 1 /* MIXOUTR_TO_LINEOUT2P */
-
-/*
- * R54 (0x36) - Speaker Mixer
- */
-#define WM8993_SPKAB_REF_SEL 0x0100 /* SPKAB_REF_SEL */
-#define WM8993_SPKAB_REF_SEL_MASK 0x0100 /* SPKAB_REF_SEL */
-#define WM8993_SPKAB_REF_SEL_SHIFT 8 /* SPKAB_REF_SEL */
-#define WM8993_SPKAB_REF_SEL_WIDTH 1 /* SPKAB_REF_SEL */
-#define WM8993_MIXINL_TO_SPKMIXL 0x0080 /* MIXINL_TO_SPKMIXL */
-#define WM8993_MIXINL_TO_SPKMIXL_MASK 0x0080 /* MIXINL_TO_SPKMIXL */
-#define WM8993_MIXINL_TO_SPKMIXL_SHIFT 7 /* MIXINL_TO_SPKMIXL */
-#define WM8993_MIXINL_TO_SPKMIXL_WIDTH 1 /* MIXINL_TO_SPKMIXL */
-#define WM8993_MIXINR_TO_SPKMIXR 0x0040 /* MIXINR_TO_SPKMIXR */
-#define WM8993_MIXINR_TO_SPKMIXR_MASK 0x0040 /* MIXINR_TO_SPKMIXR */
-#define WM8993_MIXINR_TO_SPKMIXR_SHIFT 6 /* MIXINR_TO_SPKMIXR */
-#define WM8993_MIXINR_TO_SPKMIXR_WIDTH 1 /* MIXINR_TO_SPKMIXR */
-#define WM8993_IN1LP_TO_SPKMIXL 0x0020 /* IN1LP_TO_SPKMIXL */
-#define WM8993_IN1LP_TO_SPKMIXL_MASK 0x0020 /* IN1LP_TO_SPKMIXL */
-#define WM8993_IN1LP_TO_SPKMIXL_SHIFT 5 /* IN1LP_TO_SPKMIXL */
-#define WM8993_IN1LP_TO_SPKMIXL_WIDTH 1 /* IN1LP_TO_SPKMIXL */
-#define WM8993_IN1RP_TO_SPKMIXR 0x0010 /* IN1RP_TO_SPKMIXR */
-#define WM8993_IN1RP_TO_SPKMIXR_MASK 0x0010 /* IN1RP_TO_SPKMIXR */
-#define WM8993_IN1RP_TO_SPKMIXR_SHIFT 4 /* IN1RP_TO_SPKMIXR */
-#define WM8993_IN1RP_TO_SPKMIXR_WIDTH 1 /* IN1RP_TO_SPKMIXR */
-#define WM8993_MIXOUTL_TO_SPKMIXL 0x0008 /* MIXOUTL_TO_SPKMIXL */
-#define WM8993_MIXOUTL_TO_SPKMIXL_MASK 0x0008 /* MIXOUTL_TO_SPKMIXL */
-#define WM8993_MIXOUTL_TO_SPKMIXL_SHIFT 3 /* MIXOUTL_TO_SPKMIXL */
-#define WM8993_MIXOUTL_TO_SPKMIXL_WIDTH 1 /* MIXOUTL_TO_SPKMIXL */
-#define WM8993_MIXOUTR_TO_SPKMIXR 0x0004 /* MIXOUTR_TO_SPKMIXR */
-#define WM8993_MIXOUTR_TO_SPKMIXR_MASK 0x0004 /* MIXOUTR_TO_SPKMIXR */
-#define WM8993_MIXOUTR_TO_SPKMIXR_SHIFT 2 /* MIXOUTR_TO_SPKMIXR */
-#define WM8993_MIXOUTR_TO_SPKMIXR_WIDTH 1 /* MIXOUTR_TO_SPKMIXR */
-#define WM8993_DACL_TO_SPKMIXL 0x0002 /* DACL_TO_SPKMIXL */
-#define WM8993_DACL_TO_SPKMIXL_MASK 0x0002 /* DACL_TO_SPKMIXL */
-#define WM8993_DACL_TO_SPKMIXL_SHIFT 1 /* DACL_TO_SPKMIXL */
-#define WM8993_DACL_TO_SPKMIXL_WIDTH 1 /* DACL_TO_SPKMIXL */
-#define WM8993_DACR_TO_SPKMIXR 0x0001 /* DACR_TO_SPKMIXR */
-#define WM8993_DACR_TO_SPKMIXR_MASK 0x0001 /* DACR_TO_SPKMIXR */
-#define WM8993_DACR_TO_SPKMIXR_SHIFT 0 /* DACR_TO_SPKMIXR */
-#define WM8993_DACR_TO_SPKMIXR_WIDTH 1 /* DACR_TO_SPKMIXR */
-
-/*
- * R55 (0x37) - Additional Control
- */
-#define WM8993_LINEOUT1_FB 0x0080 /* LINEOUT1_FB */
-#define WM8993_LINEOUT1_FB_MASK 0x0080 /* LINEOUT1_FB */
-#define WM8993_LINEOUT1_FB_SHIFT 7 /* LINEOUT1_FB */
-#define WM8993_LINEOUT1_FB_WIDTH 1 /* LINEOUT1_FB */
-#define WM8993_LINEOUT2_FB 0x0040 /* LINEOUT2_FB */
-#define WM8993_LINEOUT2_FB_MASK 0x0040 /* LINEOUT2_FB */
-#define WM8993_LINEOUT2_FB_SHIFT 6 /* LINEOUT2_FB */
-#define WM8993_LINEOUT2_FB_WIDTH 1 /* LINEOUT2_FB */
-#define WM8993_VROI 0x0001 /* VROI */
-#define WM8993_VROI_MASK 0x0001 /* VROI */
-#define WM8993_VROI_SHIFT 0 /* VROI */
-#define WM8993_VROI_WIDTH 1 /* VROI */
-
-/*
- * R56 (0x38) - AntiPOP1
- */
-#define WM8993_LINEOUT_VMID_BUF_ENA 0x0080 /* LINEOUT_VMID_BUF_ENA */
-#define WM8993_LINEOUT_VMID_BUF_ENA_MASK 0x0080 /* LINEOUT_VMID_BUF_ENA */
-#define WM8993_LINEOUT_VMID_BUF_ENA_SHIFT 7 /* LINEOUT_VMID_BUF_ENA */
-#define WM8993_LINEOUT_VMID_BUF_ENA_WIDTH 1 /* LINEOUT_VMID_BUF_ENA */
-#define WM8993_HPOUT2_IN_ENA 0x0040 /* HPOUT2_IN_ENA */
-#define WM8993_HPOUT2_IN_ENA_MASK 0x0040 /* HPOUT2_IN_ENA */
-#define WM8993_HPOUT2_IN_ENA_SHIFT 6 /* HPOUT2_IN_ENA */
-#define WM8993_HPOUT2_IN_ENA_WIDTH 1 /* HPOUT2_IN_ENA */
-#define WM8993_LINEOUT1_DISCH 0x0020 /* LINEOUT1_DISCH */
-#define WM8993_LINEOUT1_DISCH_MASK 0x0020 /* LINEOUT1_DISCH */
-#define WM8993_LINEOUT1_DISCH_SHIFT 5 /* LINEOUT1_DISCH */
-#define WM8993_LINEOUT1_DISCH_WIDTH 1 /* LINEOUT1_DISCH */
-#define WM8993_LINEOUT2_DISCH 0x0010 /* LINEOUT2_DISCH */
-#define WM8993_LINEOUT2_DISCH_MASK 0x0010 /* LINEOUT2_DISCH */
-#define WM8993_LINEOUT2_DISCH_SHIFT 4 /* LINEOUT2_DISCH */
-#define WM8993_LINEOUT2_DISCH_WIDTH 1 /* LINEOUT2_DISCH */
-
-/*
- * R57 (0x39) - AntiPOP2
- */
-#define WM8993_VMID_RAMP_MASK 0x0060 /* VMID_RAMP - [6:5] */
-#define WM8993_VMID_RAMP_SHIFT 5 /* VMID_RAMP - [6:5] */
-#define WM8993_VMID_RAMP_WIDTH 2 /* VMID_RAMP - [6:5] */
-#define WM8993_VMID_BUF_ENA 0x0008 /* VMID_BUF_ENA */
-#define WM8993_VMID_BUF_ENA_MASK 0x0008 /* VMID_BUF_ENA */
-#define WM8993_VMID_BUF_ENA_SHIFT 3 /* VMID_BUF_ENA */
-#define WM8993_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
-#define WM8993_STARTUP_BIAS_ENA 0x0004 /* STARTUP_BIAS_ENA */
-#define WM8993_STARTUP_BIAS_ENA_MASK 0x0004 /* STARTUP_BIAS_ENA */
-#define WM8993_STARTUP_BIAS_ENA_SHIFT 2 /* STARTUP_BIAS_ENA */
-#define WM8993_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */
-#define WM8993_BIAS_SRC 0x0002 /* BIAS_SRC */
-#define WM8993_BIAS_SRC_MASK 0x0002 /* BIAS_SRC */
-#define WM8993_BIAS_SRC_SHIFT 1 /* BIAS_SRC */
-#define WM8993_BIAS_SRC_WIDTH 1 /* BIAS_SRC */
-#define WM8993_VMID_DISCH 0x0001 /* VMID_DISCH */
-#define WM8993_VMID_DISCH_MASK 0x0001 /* VMID_DISCH */
-#define WM8993_VMID_DISCH_SHIFT 0 /* VMID_DISCH */
-#define WM8993_VMID_DISCH_WIDTH 1 /* VMID_DISCH */
-
-/*
- * R58 (0x3A) - MICBIAS
- */
-#define WM8993_JD_SCTHR_MASK 0x00C0 /* JD_SCTHR - [7:6] */
-#define WM8993_JD_SCTHR_SHIFT 6 /* JD_SCTHR - [7:6] */
-#define WM8993_JD_SCTHR_WIDTH 2 /* JD_SCTHR - [7:6] */
-#define WM8993_JD_THR_MASK 0x0030 /* JD_THR - [5:4] */
-#define WM8993_JD_THR_SHIFT 4 /* JD_THR - [5:4] */
-#define WM8993_JD_THR_WIDTH 2 /* JD_THR - [5:4] */
-#define WM8993_JD_ENA 0x0004 /* JD_ENA */
-#define WM8993_JD_ENA_MASK 0x0004 /* JD_ENA */
-#define WM8993_JD_ENA_SHIFT 2 /* JD_ENA */
-#define WM8993_JD_ENA_WIDTH 1 /* JD_ENA */
-#define WM8993_MICB2_LVL 0x0002 /* MICB2_LVL */
-#define WM8993_MICB2_LVL_MASK 0x0002 /* MICB2_LVL */
-#define WM8993_MICB2_LVL_SHIFT 1 /* MICB2_LVL */
-#define WM8993_MICB2_LVL_WIDTH 1 /* MICB2_LVL */
-#define WM8993_MICB1_LVL 0x0001 /* MICB1_LVL */
-#define WM8993_MICB1_LVL_MASK 0x0001 /* MICB1_LVL */
-#define WM8993_MICB1_LVL_SHIFT 0 /* MICB1_LVL */
-#define WM8993_MICB1_LVL_WIDTH 1 /* MICB1_LVL */
-
-/*
- * R60 (0x3C) - FLL Control 1
- */
-#define WM8993_FLL_FRAC 0x0004 /* FLL_FRAC */
-#define WM8993_FLL_FRAC_MASK 0x0004 /* FLL_FRAC */
-#define WM8993_FLL_FRAC_SHIFT 2 /* FLL_FRAC */
-#define WM8993_FLL_FRAC_WIDTH 1 /* FLL_FRAC */
-#define WM8993_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */
-#define WM8993_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */
-#define WM8993_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */
-#define WM8993_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */
-#define WM8993_FLL_ENA 0x0001 /* FLL_ENA */
-#define WM8993_FLL_ENA_MASK 0x0001 /* FLL_ENA */
-#define WM8993_FLL_ENA_SHIFT 0 /* FLL_ENA */
-#define WM8993_FLL_ENA_WIDTH 1 /* FLL_ENA */
-
-/*
- * R61 (0x3D) - FLL Control 2
- */
-#define WM8993_FLL_OUTDIV_MASK 0x0700 /* FLL_OUTDIV - [10:8] */
-#define WM8993_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [10:8] */
-#define WM8993_FLL_OUTDIV_WIDTH 3 /* FLL_OUTDIV - [10:8] */
-#define WM8993_FLL_CTRL_RATE_MASK 0x0070 /* FLL_CTRL_RATE - [6:4] */
-#define WM8993_FLL_CTRL_RATE_SHIFT 4 /* FLL_CTRL_RATE - [6:4] */
-#define WM8993_FLL_CTRL_RATE_WIDTH 3 /* FLL_CTRL_RATE - [6:4] */
-#define WM8993_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
-#define WM8993_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
-#define WM8993_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
-
-/*
- * R62 (0x3E) - FLL Control 3
- */
-#define WM8993_FLL_K_MASK 0xFFFF /* FLL_K - [15:0] */
-#define WM8993_FLL_K_SHIFT 0 /* FLL_K - [15:0] */
-#define WM8993_FLL_K_WIDTH 16 /* FLL_K - [15:0] */
-
-/*
- * R63 (0x3F) - FLL Control 4
- */
-#define WM8993_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */
-#define WM8993_FLL_N_SHIFT 5 /* FLL_N - [14:5] */
-#define WM8993_FLL_N_WIDTH 10 /* FLL_N - [14:5] */
-#define WM8993_FLL_GAIN_MASK 0x000F /* FLL_GAIN - [3:0] */
-#define WM8993_FLL_GAIN_SHIFT 0 /* FLL_GAIN - [3:0] */
-#define WM8993_FLL_GAIN_WIDTH 4 /* FLL_GAIN - [3:0] */
-
-/*
- * R64 (0x40) - FLL Control 5
- */
-#define WM8993_FLL_FRC_NCO_VAL_MASK 0x1F80 /* FLL_FRC_NCO_VAL - [12:7] */
-#define WM8993_FLL_FRC_NCO_VAL_SHIFT 7 /* FLL_FRC_NCO_VAL - [12:7] */
-#define WM8993_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [12:7] */
-#define WM8993_FLL_FRC_NCO 0x0040 /* FLL_FRC_NCO */
-#define WM8993_FLL_FRC_NCO_MASK 0x0040 /* FLL_FRC_NCO */
-#define WM8993_FLL_FRC_NCO_SHIFT 6 /* FLL_FRC_NCO */
-#define WM8993_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */
-#define WM8993_FLL_CLK_REF_DIV_MASK 0x0018 /* FLL_CLK_REF_DIV - [4:3] */
-#define WM8993_FLL_CLK_REF_DIV_SHIFT 3 /* FLL_CLK_REF_DIV - [4:3] */
-#define WM8993_FLL_CLK_REF_DIV_WIDTH 2 /* FLL_CLK_REF_DIV - [4:3] */
-#define WM8993_FLL_CLK_SRC_MASK 0x0003 /* FLL_CLK_SRC - [1:0] */
-#define WM8993_FLL_CLK_SRC_SHIFT 0 /* FLL_CLK_SRC - [1:0] */
-#define WM8993_FLL_CLK_SRC_WIDTH 2 /* FLL_CLK_SRC - [1:0] */
-
-/*
- * R65 (0x41) - Clocking 3
- */
-#define WM8993_CLK_DCS_DIV_MASK 0x3C00 /* CLK_DCS_DIV - [13:10] */
-#define WM8993_CLK_DCS_DIV_SHIFT 10 /* CLK_DCS_DIV - [13:10] */
-#define WM8993_CLK_DCS_DIV_WIDTH 4 /* CLK_DCS_DIV - [13:10] */
-#define WM8993_SAMPLE_RATE_MASK 0x0380 /* SAMPLE_RATE - [9:7] */
-#define WM8993_SAMPLE_RATE_SHIFT 7 /* SAMPLE_RATE - [9:7] */
-#define WM8993_SAMPLE_RATE_WIDTH 3 /* SAMPLE_RATE - [9:7] */
-#define WM8993_CLK_SYS_RATE_MASK 0x001E /* CLK_SYS_RATE - [4:1] */
-#define WM8993_CLK_SYS_RATE_SHIFT 1 /* CLK_SYS_RATE - [4:1] */
-#define WM8993_CLK_SYS_RATE_WIDTH 4 /* CLK_SYS_RATE - [4:1] */
-#define WM8993_CLK_DSP_ENA 0x0001 /* CLK_DSP_ENA */
-#define WM8993_CLK_DSP_ENA_MASK 0x0001 /* CLK_DSP_ENA */
-#define WM8993_CLK_DSP_ENA_SHIFT 0 /* CLK_DSP_ENA */
-#define WM8993_CLK_DSP_ENA_WIDTH 1 /* CLK_DSP_ENA */
-
-/*
- * R66 (0x42) - Clocking 4
- */
-#define WM8993_DAC_DIV4 0x0200 /* DAC_DIV4 */
-#define WM8993_DAC_DIV4_MASK 0x0200 /* DAC_DIV4 */
-#define WM8993_DAC_DIV4_SHIFT 9 /* DAC_DIV4 */
-#define WM8993_DAC_DIV4_WIDTH 1 /* DAC_DIV4 */
-#define WM8993_CLK_256K_DIV_MASK 0x007E /* CLK_256K_DIV - [6:1] */
-#define WM8993_CLK_256K_DIV_SHIFT 1 /* CLK_256K_DIV - [6:1] */
-#define WM8993_CLK_256K_DIV_WIDTH 6 /* CLK_256K_DIV - [6:1] */
-#define WM8993_SR_MODE 0x0001 /* SR_MODE */
-#define WM8993_SR_MODE_MASK 0x0001 /* SR_MODE */
-#define WM8993_SR_MODE_SHIFT 0 /* SR_MODE */
-#define WM8993_SR_MODE_WIDTH 1 /* SR_MODE */
-
-/*
- * R67 (0x43) - MW Slave Control
- */
-#define WM8993_MASK_WRITE_ENA 0x0001 /* MASK_WRITE_ENA */
-#define WM8993_MASK_WRITE_ENA_MASK 0x0001 /* MASK_WRITE_ENA */
-#define WM8993_MASK_WRITE_ENA_SHIFT 0 /* MASK_WRITE_ENA */
-#define WM8993_MASK_WRITE_ENA_WIDTH 1 /* MASK_WRITE_ENA */
-
-/*
- * R69 (0x45) - Bus Control 1
- */
-#define WM8993_CLK_SYS_ENA 0x0002 /* CLK_SYS_ENA */
-#define WM8993_CLK_SYS_ENA_MASK 0x0002 /* CLK_SYS_ENA */
-#define WM8993_CLK_SYS_ENA_SHIFT 1 /* CLK_SYS_ENA */
-#define WM8993_CLK_SYS_ENA_WIDTH 1 /* CLK_SYS_ENA */
-
-/*
- * R70 (0x46) - Write Sequencer 0
- */
-#define WM8993_WSEQ_ENA 0x0100 /* WSEQ_ENA */
-#define WM8993_WSEQ_ENA_MASK 0x0100 /* WSEQ_ENA */
-#define WM8993_WSEQ_ENA_SHIFT 8 /* WSEQ_ENA */
-#define WM8993_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
-#define WM8993_WSEQ_WRITE_INDEX_MASK 0x001F /* WSEQ_WRITE_INDEX - [4:0] */
-#define WM8993_WSEQ_WRITE_INDEX_SHIFT 0 /* WSEQ_WRITE_INDEX - [4:0] */
-#define WM8993_WSEQ_WRITE_INDEX_WIDTH 5 /* WSEQ_WRITE_INDEX - [4:0] */
-
-/*
- * R71 (0x47) - Write Sequencer 1
- */
-#define WM8993_WSEQ_DATA_WIDTH_MASK 0x7000 /* WSEQ_DATA_WIDTH - [14:12] */
-#define WM8993_WSEQ_DATA_WIDTH_SHIFT 12 /* WSEQ_DATA_WIDTH - [14:12] */
-#define WM8993_WSEQ_DATA_WIDTH_WIDTH 3 /* WSEQ_DATA_WIDTH - [14:12] */
-#define WM8993_WSEQ_DATA_START_MASK 0x0F00 /* WSEQ_DATA_START - [11:8] */
-#define WM8993_WSEQ_DATA_START_SHIFT 8 /* WSEQ_DATA_START - [11:8] */
-#define WM8993_WSEQ_DATA_START_WIDTH 4 /* WSEQ_DATA_START - [11:8] */
-#define WM8993_WSEQ_ADDR_MASK 0x00FF /* WSEQ_ADDR - [7:0] */
-#define WM8993_WSEQ_ADDR_SHIFT 0 /* WSEQ_ADDR - [7:0] */
-#define WM8993_WSEQ_ADDR_WIDTH 8 /* WSEQ_ADDR - [7:0] */
-
-/*
- * R72 (0x48) - Write Sequencer 2
- */
-#define WM8993_WSEQ_EOS 0x4000 /* WSEQ_EOS */
-#define WM8993_WSEQ_EOS_MASK 0x4000 /* WSEQ_EOS */
-#define WM8993_WSEQ_EOS_SHIFT 14 /* WSEQ_EOS */
-#define WM8993_WSEQ_EOS_WIDTH 1 /* WSEQ_EOS */
-#define WM8993_WSEQ_DELAY_MASK 0x0F00 /* WSEQ_DELAY - [11:8] */
-#define WM8993_WSEQ_DELAY_SHIFT 8 /* WSEQ_DELAY - [11:8] */
-#define WM8993_WSEQ_DELAY_WIDTH 4 /* WSEQ_DELAY - [11:8] */
-#define WM8993_WSEQ_DATA_MASK 0x00FF /* WSEQ_DATA - [7:0] */
-#define WM8993_WSEQ_DATA_SHIFT 0 /* WSEQ_DATA - [7:0] */
-#define WM8993_WSEQ_DATA_WIDTH 8 /* WSEQ_DATA - [7:0] */
-
-/*
- * R73 (0x49) - Write Sequencer 3
- */
-#define WM8993_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
-#define WM8993_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
-#define WM8993_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
-#define WM8993_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
-#define WM8993_WSEQ_START 0x0100 /* WSEQ_START */
-#define WM8993_WSEQ_START_MASK 0x0100 /* WSEQ_START */
-#define WM8993_WSEQ_START_SHIFT 8 /* WSEQ_START */
-#define WM8993_WSEQ_START_WIDTH 1 /* WSEQ_START */
-#define WM8993_WSEQ_START_INDEX_MASK 0x003F /* WSEQ_START_INDEX - [5:0] */
-#define WM8993_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [5:0] */
-#define WM8993_WSEQ_START_INDEX_WIDTH 6 /* WSEQ_START_INDEX - [5:0] */
-
-/*
- * R74 (0x4A) - Write Sequencer 4
- */
-#define WM8993_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
-#define WM8993_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
-#define WM8993_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
-#define WM8993_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
-
-/*
- * R75 (0x4B) - Write Sequencer 5
- */
-#define WM8993_WSEQ_CURRENT_INDEX_MASK 0x003F /* WSEQ_CURRENT_INDEX - [5:0] */
-#define WM8993_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [5:0] */
-#define WM8993_WSEQ_CURRENT_INDEX_WIDTH 6 /* WSEQ_CURRENT_INDEX - [5:0] */
-
-/*
- * R76 (0x4C) - Charge Pump 1
- */
-#define WM8993_CP_ENA 0x8000 /* CP_ENA */
-#define WM8993_CP_ENA_MASK 0x8000 /* CP_ENA */
-#define WM8993_CP_ENA_SHIFT 15 /* CP_ENA */
-#define WM8993_CP_ENA_WIDTH 1 /* CP_ENA */
-
-/*
- * R81 (0x51) - Class W 0
- */
-#define WM8993_CP_DYN_FREQ 0x0002 /* CP_DYN_FREQ */
-#define WM8993_CP_DYN_FREQ_MASK 0x0002 /* CP_DYN_FREQ */
-#define WM8993_CP_DYN_FREQ_SHIFT 1 /* CP_DYN_FREQ */
-#define WM8993_CP_DYN_FREQ_WIDTH 1 /* CP_DYN_FREQ */
-#define WM8993_CP_DYN_V 0x0001 /* CP_DYN_V */
-#define WM8993_CP_DYN_V_MASK 0x0001 /* CP_DYN_V */
-#define WM8993_CP_DYN_V_SHIFT 0 /* CP_DYN_V */
-#define WM8993_CP_DYN_V_WIDTH 1 /* CP_DYN_V */
-
-/*
- * R84 (0x54) - DC Servo 0
- */
-#define WM8993_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
-#define WM8993_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
-#define WM8993_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
-#define WM8993_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
-#define WM8993_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
-#define WM8993_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
-#define WM8993_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
-#define WM8993_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
-#define WM8993_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
-#define WM8993_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
-#define WM8993_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
-#define WM8993_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
-#define WM8993_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
-#define WM8993_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
-#define WM8993_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
-#define WM8993_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
-#define WM8993_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
-#define WM8993_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
-#define WM8993_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
-#define WM8993_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
-#define WM8993_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
-#define WM8993_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
-#define WM8993_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
-#define WM8993_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
-#define WM8993_DCS_TRIG_DAC_WR_1 0x0008 /* DCS_TRIG_DAC_WR_1 */
-#define WM8993_DCS_TRIG_DAC_WR_1_MASK 0x0008 /* DCS_TRIG_DAC_WR_1 */
-#define WM8993_DCS_TRIG_DAC_WR_1_SHIFT 3 /* DCS_TRIG_DAC_WR_1 */
-#define WM8993_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
-#define WM8993_DCS_TRIG_DAC_WR_0 0x0004 /* DCS_TRIG_DAC_WR_0 */
-#define WM8993_DCS_TRIG_DAC_WR_0_MASK 0x0004 /* DCS_TRIG_DAC_WR_0 */
-#define WM8993_DCS_TRIG_DAC_WR_0_SHIFT 2 /* DCS_TRIG_DAC_WR_0 */
-#define WM8993_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
-#define WM8993_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
-#define WM8993_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
-#define WM8993_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
-#define WM8993_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
-#define WM8993_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
-#define WM8993_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
-#define WM8993_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
-#define WM8993_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
-
-/*
- * R85 (0x55) - DC Servo 1
- */
-#define WM8993_DCS_SERIES_NO_01_MASK 0x0FE0 /* DCS_SERIES_NO_01 - [11:5] */
-#define WM8993_DCS_SERIES_NO_01_SHIFT 5 /* DCS_SERIES_NO_01 - [11:5] */
-#define WM8993_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [11:5] */
-#define WM8993_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
-#define WM8993_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
-#define WM8993_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
-
-/*
- * R87 (0x57) - DC Servo 3
- */
-#define WM8993_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */
-#define WM8993_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
-#define WM8993_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
-#define WM8993_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
-#define WM8993_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
-#define WM8993_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
-
-/*
- * R88 (0x58) - DC Servo Readback 0
- */
-#define WM8993_DCS_DATAPATH_BUSY 0x4000 /* DCS_DATAPATH_BUSY */
-#define WM8993_DCS_DATAPATH_BUSY_MASK 0x4000 /* DCS_DATAPATH_BUSY */
-#define WM8993_DCS_DATAPATH_BUSY_SHIFT 14 /* DCS_DATAPATH_BUSY */
-#define WM8993_DCS_DATAPATH_BUSY_WIDTH 1 /* DCS_DATAPATH_BUSY */
-#define WM8993_DCS_CHANNEL_MASK 0x3000 /* DCS_CHANNEL - [13:12] */
-#define WM8993_DCS_CHANNEL_SHIFT 12 /* DCS_CHANNEL - [13:12] */
-#define WM8993_DCS_CHANNEL_WIDTH 2 /* DCS_CHANNEL - [13:12] */
-#define WM8993_DCS_CAL_COMPLETE_MASK 0x0300 /* DCS_CAL_COMPLETE - [9:8] */
-#define WM8993_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [9:8] */
-#define WM8993_DCS_CAL_COMPLETE_WIDTH 2 /* DCS_CAL_COMPLETE - [9:8] */
-#define WM8993_DCS_DAC_WR_COMPLETE_MASK 0x0030 /* DCS_DAC_WR_COMPLETE - [5:4] */
-#define WM8993_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [5:4] */
-#define WM8993_DCS_DAC_WR_COMPLETE_WIDTH 2 /* DCS_DAC_WR_COMPLETE - [5:4] */
-#define WM8993_DCS_STARTUP_COMPLETE_MASK 0x0003 /* DCS_STARTUP_COMPLETE - [1:0] */
-#define WM8993_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [1:0] */
-#define WM8993_DCS_STARTUP_COMPLETE_WIDTH 2 /* DCS_STARTUP_COMPLETE - [1:0] */
-
-/*
- * R89 (0x59) - DC Servo Readback 1
- */
-#define WM8993_DCS_INTEG_CHAN_1_MASK 0x00FF /* DCS_INTEG_CHAN_1 - [7:0] */
-#define WM8993_DCS_INTEG_CHAN_1_SHIFT 0 /* DCS_INTEG_CHAN_1 - [7:0] */
-#define WM8993_DCS_INTEG_CHAN_1_WIDTH 8 /* DCS_INTEG_CHAN_1 - [7:0] */
-
-/*
- * R90 (0x5A) - DC Servo Readback 2
- */
-#define WM8993_DCS_INTEG_CHAN_0_MASK 0x00FF /* DCS_INTEG_CHAN_0 - [7:0] */
-#define WM8993_DCS_INTEG_CHAN_0_SHIFT 0 /* DCS_INTEG_CHAN_0 - [7:0] */
-#define WM8993_DCS_INTEG_CHAN_0_WIDTH 8 /* DCS_INTEG_CHAN_0 - [7:0] */
-
-/*
- * R96 (0x60) - Analogue HP 0
- */
-#define WM8993_HPOUT1_AUTO_PU 0x0100 /* HPOUT1_AUTO_PU */
-#define WM8993_HPOUT1_AUTO_PU_MASK 0x0100 /* HPOUT1_AUTO_PU */
-#define WM8993_HPOUT1_AUTO_PU_SHIFT 8 /* HPOUT1_AUTO_PU */
-#define WM8993_HPOUT1_AUTO_PU_WIDTH 1 /* HPOUT1_AUTO_PU */
-#define WM8993_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
-#define WM8993_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
-#define WM8993_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
-#define WM8993_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */
-#define WM8993_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */
-#define WM8993_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */
-#define WM8993_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */
-#define WM8993_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */
-#define WM8993_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */
-#define WM8993_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */
-#define WM8993_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */
-#define WM8993_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */
-#define WM8993_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */
-#define WM8993_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */
-#define WM8993_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */
-#define WM8993_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */
-#define WM8993_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */
-#define WM8993_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */
-#define WM8993_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */
-#define WM8993_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */
-#define WM8993_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */
-#define WM8993_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */
-#define WM8993_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */
-#define WM8993_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
-
-/*
- * R98 (0x62) - EQ1
- */
-#define WM8993_EQ_ENA 0x0001 /* EQ_ENA */
-#define WM8993_EQ_ENA_MASK 0x0001 /* EQ_ENA */
-#define WM8993_EQ_ENA_SHIFT 0 /* EQ_ENA */
-#define WM8993_EQ_ENA_WIDTH 1 /* EQ_ENA */
-
-/*
- * R99 (0x63) - EQ2
- */
-#define WM8993_EQ_B1_GAIN_MASK 0x001F /* EQ_B1_GAIN - [4:0] */
-#define WM8993_EQ_B1_GAIN_SHIFT 0 /* EQ_B1_GAIN - [4:0] */
-#define WM8993_EQ_B1_GAIN_WIDTH 5 /* EQ_B1_GAIN - [4:0] */
-
-/*
- * R100 (0x64) - EQ3
- */
-#define WM8993_EQ_B2_GAIN_MASK 0x001F /* EQ_B2_GAIN - [4:0] */
-#define WM8993_EQ_B2_GAIN_SHIFT 0 /* EQ_B2_GAIN - [4:0] */
-#define WM8993_EQ_B2_GAIN_WIDTH 5 /* EQ_B2_GAIN - [4:0] */
-
-/*
- * R101 (0x65) - EQ4
- */
-#define WM8993_EQ_B3_GAIN_MASK 0x001F /* EQ_B3_GAIN - [4:0] */
-#define WM8993_EQ_B3_GAIN_SHIFT 0 /* EQ_B3_GAIN - [4:0] */
-#define WM8993_EQ_B3_GAIN_WIDTH 5 /* EQ_B3_GAIN - [4:0] */
-
-/*
- * R102 (0x66) - EQ5
- */
-#define WM8993_EQ_B4_GAIN_MASK 0x001F /* EQ_B4_GAIN - [4:0] */
-#define WM8993_EQ_B4_GAIN_SHIFT 0 /* EQ_B4_GAIN - [4:0] */
-#define WM8993_EQ_B4_GAIN_WIDTH 5 /* EQ_B4_GAIN - [4:0] */
-
-/*
- * R103 (0x67) - EQ6
- */
-#define WM8993_EQ_B5_GAIN_MASK 0x001F /* EQ_B5_GAIN - [4:0] */
-#define WM8993_EQ_B5_GAIN_SHIFT 0 /* EQ_B5_GAIN - [4:0] */
-#define WM8993_EQ_B5_GAIN_WIDTH 5 /* EQ_B5_GAIN - [4:0] */
-
-/*
- * R104 (0x68) - EQ7
- */
-#define WM8993_EQ_B1_A_MASK 0xFFFF /* EQ_B1_A - [15:0] */
-#define WM8993_EQ_B1_A_SHIFT 0 /* EQ_B1_A - [15:0] */
-#define WM8993_EQ_B1_A_WIDTH 16 /* EQ_B1_A - [15:0] */
-
-/*
- * R105 (0x69) - EQ8
- */
-#define WM8993_EQ_B1_B_MASK 0xFFFF /* EQ_B1_B - [15:0] */
-#define WM8993_EQ_B1_B_SHIFT 0 /* EQ_B1_B - [15:0] */
-#define WM8993_EQ_B1_B_WIDTH 16 /* EQ_B1_B - [15:0] */
-
-/*
- * R106 (0x6A) - EQ9
- */
-#define WM8993_EQ_B1_PG_MASK 0xFFFF /* EQ_B1_PG - [15:0] */
-#define WM8993_EQ_B1_PG_SHIFT 0 /* EQ_B1_PG - [15:0] */
-#define WM8993_EQ_B1_PG_WIDTH 16 /* EQ_B1_PG - [15:0] */
-
-/*
- * R107 (0x6B) - EQ10
- */
-#define WM8993_EQ_B2_A_MASK 0xFFFF /* EQ_B2_A - [15:0] */
-#define WM8993_EQ_B2_A_SHIFT 0 /* EQ_B2_A - [15:0] */
-#define WM8993_EQ_B2_A_WIDTH 16 /* EQ_B2_A - [15:0] */
-
-/*
- * R108 (0x6C) - EQ11
- */
-#define WM8993_EQ_B2_B_MASK 0xFFFF /* EQ_B2_B - [15:0] */
-#define WM8993_EQ_B2_B_SHIFT 0 /* EQ_B2_B - [15:0] */
-#define WM8993_EQ_B2_B_WIDTH 16 /* EQ_B2_B - [15:0] */
-
-/*
- * R109 (0x6D) - EQ12
- */
-#define WM8993_EQ_B2_C_MASK 0xFFFF /* EQ_B2_C - [15:0] */
-#define WM8993_EQ_B2_C_SHIFT 0 /* EQ_B2_C - [15:0] */
-#define WM8993_EQ_B2_C_WIDTH 16 /* EQ_B2_C - [15:0] */
-
-/*
- * R110 (0x6E) - EQ13
- */
-#define WM8993_EQ_B2_PG_MASK 0xFFFF /* EQ_B2_PG - [15:0] */
-#define WM8993_EQ_B2_PG_SHIFT 0 /* EQ_B2_PG - [15:0] */
-#define WM8993_EQ_B2_PG_WIDTH 16 /* EQ_B2_PG - [15:0] */
-
-/*
- * R111 (0x6F) - EQ14
- */
-#define WM8993_EQ_B3_A_MASK 0xFFFF /* EQ_B3_A - [15:0] */
-#define WM8993_EQ_B3_A_SHIFT 0 /* EQ_B3_A - [15:0] */
-#define WM8993_EQ_B3_A_WIDTH 16 /* EQ_B3_A - [15:0] */
-
-/*
- * R112 (0x70) - EQ15
- */
-#define WM8993_EQ_B3_B_MASK 0xFFFF /* EQ_B3_B - [15:0] */
-#define WM8993_EQ_B3_B_SHIFT 0 /* EQ_B3_B - [15:0] */
-#define WM8993_EQ_B3_B_WIDTH 16 /* EQ_B3_B - [15:0] */
-
-/*
- * R113 (0x71) - EQ16
- */
-#define WM8993_EQ_B3_C_MASK 0xFFFF /* EQ_B3_C - [15:0] */
-#define WM8993_EQ_B3_C_SHIFT 0 /* EQ_B3_C - [15:0] */
-#define WM8993_EQ_B3_C_WIDTH 16 /* EQ_B3_C - [15:0] */
-
-/*
- * R114 (0x72) - EQ17
- */
-#define WM8993_EQ_B3_PG_MASK 0xFFFF /* EQ_B3_PG - [15:0] */
-#define WM8993_EQ_B3_PG_SHIFT 0 /* EQ_B3_PG - [15:0] */
-#define WM8993_EQ_B3_PG_WIDTH 16 /* EQ_B3_PG - [15:0] */
-
-/*
- * R115 (0x73) - EQ18
- */
-#define WM8993_EQ_B4_A_MASK 0xFFFF /* EQ_B4_A - [15:0] */
-#define WM8993_EQ_B4_A_SHIFT 0 /* EQ_B4_A - [15:0] */
-#define WM8993_EQ_B4_A_WIDTH 16 /* EQ_B4_A - [15:0] */
-
-/*
- * R116 (0x74) - EQ19
- */
-#define WM8993_EQ_B4_B_MASK 0xFFFF /* EQ_B4_B - [15:0] */
-#define WM8993_EQ_B4_B_SHIFT 0 /* EQ_B4_B - [15:0] */
-#define WM8993_EQ_B4_B_WIDTH 16 /* EQ_B4_B - [15:0] */
-
-/*
- * R117 (0x75) - EQ20
- */
-#define WM8993_EQ_B4_C_MASK 0xFFFF /* EQ_B4_C - [15:0] */
-#define WM8993_EQ_B4_C_SHIFT 0 /* EQ_B4_C - [15:0] */
-#define WM8993_EQ_B4_C_WIDTH 16 /* EQ_B4_C - [15:0] */
-
-/*
- * R118 (0x76) - EQ21
- */
-#define WM8993_EQ_B4_PG_MASK 0xFFFF /* EQ_B4_PG - [15:0] */
-#define WM8993_EQ_B4_PG_SHIFT 0 /* EQ_B4_PG - [15:0] */
-#define WM8993_EQ_B4_PG_WIDTH 16 /* EQ_B4_PG - [15:0] */
-
-/*
- * R119 (0x77) - EQ22
- */
-#define WM8993_EQ_B5_A_MASK 0xFFFF /* EQ_B5_A - [15:0] */
-#define WM8993_EQ_B5_A_SHIFT 0 /* EQ_B5_A - [15:0] */
-#define WM8993_EQ_B5_A_WIDTH 16 /* EQ_B5_A - [15:0] */
-
-/*
- * R120 (0x78) - EQ23
- */
-#define WM8993_EQ_B5_B_MASK 0xFFFF /* EQ_B5_B - [15:0] */
-#define WM8993_EQ_B5_B_SHIFT 0 /* EQ_B5_B - [15:0] */
-#define WM8993_EQ_B5_B_WIDTH 16 /* EQ_B5_B - [15:0] */
-
-/*
- * R121 (0x79) - EQ24
- */
-#define WM8993_EQ_B5_PG_MASK 0xFFFF /* EQ_B5_PG - [15:0] */
-#define WM8993_EQ_B5_PG_SHIFT 0 /* EQ_B5_PG - [15:0] */
-#define WM8993_EQ_B5_PG_WIDTH 16 /* EQ_B5_PG - [15:0] */
-
-/*
- * R122 (0x7A) - Digital Pulls
- */
-#define WM8993_MCLK_PU 0x0080 /* MCLK_PU */
-#define WM8993_MCLK_PU_MASK 0x0080 /* MCLK_PU */
-#define WM8993_MCLK_PU_SHIFT 7 /* MCLK_PU */
-#define WM8993_MCLK_PU_WIDTH 1 /* MCLK_PU */
-#define WM8993_MCLK_PD 0x0040 /* MCLK_PD */
-#define WM8993_MCLK_PD_MASK 0x0040 /* MCLK_PD */
-#define WM8993_MCLK_PD_SHIFT 6 /* MCLK_PD */
-#define WM8993_MCLK_PD_WIDTH 1 /* MCLK_PD */
-#define WM8993_DACDAT_PU 0x0020 /* DACDAT_PU */
-#define WM8993_DACDAT_PU_MASK 0x0020 /* DACDAT_PU */
-#define WM8993_DACDAT_PU_SHIFT 5 /* DACDAT_PU */
-#define WM8993_DACDAT_PU_WIDTH 1 /* DACDAT_PU */
-#define WM8993_DACDAT_PD 0x0010 /* DACDAT_PD */
-#define WM8993_DACDAT_PD_MASK 0x0010 /* DACDAT_PD */
-#define WM8993_DACDAT_PD_SHIFT 4 /* DACDAT_PD */
-#define WM8993_DACDAT_PD_WIDTH 1 /* DACDAT_PD */
-#define WM8993_LRCLK_PU 0x0008 /* LRCLK_PU */
-#define WM8993_LRCLK_PU_MASK 0x0008 /* LRCLK_PU */
-#define WM8993_LRCLK_PU_SHIFT 3 /* LRCLK_PU */
-#define WM8993_LRCLK_PU_WIDTH 1 /* LRCLK_PU */
-#define WM8993_LRCLK_PD 0x0004 /* LRCLK_PD */
-#define WM8993_LRCLK_PD_MASK 0x0004 /* LRCLK_PD */
-#define WM8993_LRCLK_PD_SHIFT 2 /* LRCLK_PD */
-#define WM8993_LRCLK_PD_WIDTH 1 /* LRCLK_PD */
-#define WM8993_BCLK_PU 0x0002 /* BCLK_PU */
-#define WM8993_BCLK_PU_MASK 0x0002 /* BCLK_PU */
-#define WM8993_BCLK_PU_SHIFT 1 /* BCLK_PU */
-#define WM8993_BCLK_PU_WIDTH 1 /* BCLK_PU */
-#define WM8993_BCLK_PD 0x0001 /* BCLK_PD */
-#define WM8993_BCLK_PD_MASK 0x0001 /* BCLK_PD */
-#define WM8993_BCLK_PD_SHIFT 0 /* BCLK_PD */
-#define WM8993_BCLK_PD_WIDTH 1 /* BCLK_PD */
-
-/*
- * R123 (0x7B) - DRC Control 1
- */
-#define WM8993_DRC_ENA 0x8000 /* DRC_ENA */
-#define WM8993_DRC_ENA_MASK 0x8000 /* DRC_ENA */
-#define WM8993_DRC_ENA_SHIFT 15 /* DRC_ENA */
-#define WM8993_DRC_ENA_WIDTH 1 /* DRC_ENA */
-#define WM8993_DRC_DAC_PATH 0x4000 /* DRC_DAC_PATH */
-#define WM8993_DRC_DAC_PATH_MASK 0x4000 /* DRC_DAC_PATH */
-#define WM8993_DRC_DAC_PATH_SHIFT 14 /* DRC_DAC_PATH */
-#define WM8993_DRC_DAC_PATH_WIDTH 1 /* DRC_DAC_PATH */
-#define WM8993_DRC_SMOOTH_ENA 0x0800 /* DRC_SMOOTH_ENA */
-#define WM8993_DRC_SMOOTH_ENA_MASK 0x0800 /* DRC_SMOOTH_ENA */
-#define WM8993_DRC_SMOOTH_ENA_SHIFT 11 /* DRC_SMOOTH_ENA */
-#define WM8993_DRC_SMOOTH_ENA_WIDTH 1 /* DRC_SMOOTH_ENA */
-#define WM8993_DRC_QR_ENA 0x0400 /* DRC_QR_ENA */
-#define WM8993_DRC_QR_ENA_MASK 0x0400 /* DRC_QR_ENA */
-#define WM8993_DRC_QR_ENA_SHIFT 10 /* DRC_QR_ENA */
-#define WM8993_DRC_QR_ENA_WIDTH 1 /* DRC_QR_ENA */
-#define WM8993_DRC_ANTICLIP_ENA 0x0200 /* DRC_ANTICLIP_ENA */
-#define WM8993_DRC_ANTICLIP_ENA_MASK 0x0200 /* DRC_ANTICLIP_ENA */
-#define WM8993_DRC_ANTICLIP_ENA_SHIFT 9 /* DRC_ANTICLIP_ENA */
-#define WM8993_DRC_ANTICLIP_ENA_WIDTH 1 /* DRC_ANTICLIP_ENA */
-#define WM8993_DRC_HYST_ENA 0x0100 /* DRC_HYST_ENA */
-#define WM8993_DRC_HYST_ENA_MASK 0x0100 /* DRC_HYST_ENA */
-#define WM8993_DRC_HYST_ENA_SHIFT 8 /* DRC_HYST_ENA */
-#define WM8993_DRC_HYST_ENA_WIDTH 1 /* DRC_HYST_ENA */
-#define WM8993_DRC_THRESH_HYST_MASK 0x0030 /* DRC_THRESH_HYST - [5:4] */
-#define WM8993_DRC_THRESH_HYST_SHIFT 4 /* DRC_THRESH_HYST - [5:4] */
-#define WM8993_DRC_THRESH_HYST_WIDTH 2 /* DRC_THRESH_HYST - [5:4] */
-#define WM8993_DRC_MINGAIN_MASK 0x000C /* DRC_MINGAIN - [3:2] */
-#define WM8993_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [3:2] */
-#define WM8993_DRC_MINGAIN_WIDTH 2 /* DRC_MINGAIN - [3:2] */
-#define WM8993_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */
-#define WM8993_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */
-#define WM8993_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */
-
-/*
- * R124 (0x7C) - DRC Control 2
- */
-#define WM8993_DRC_ATTACK_RATE_MASK 0xF000 /* DRC_ATTACK_RATE - [15:12] */
-#define WM8993_DRC_ATTACK_RATE_SHIFT 12 /* DRC_ATTACK_RATE - [15:12] */
-#define WM8993_DRC_ATTACK_RATE_WIDTH 4 /* DRC_ATTACK_RATE - [15:12] */
-#define WM8993_DRC_DECAY_RATE_MASK 0x0F00 /* DRC_DECAY_RATE - [11:8] */
-#define WM8993_DRC_DECAY_RATE_SHIFT 8 /* DRC_DECAY_RATE - [11:8] */
-#define WM8993_DRC_DECAY_RATE_WIDTH 4 /* DRC_DECAY_RATE - [11:8] */
-#define WM8993_DRC_THRESH_COMP_MASK 0x00FC /* DRC_THRESH_COMP - [7:2] */
-#define WM8993_DRC_THRESH_COMP_SHIFT 2 /* DRC_THRESH_COMP - [7:2] */
-#define WM8993_DRC_THRESH_COMP_WIDTH 6 /* DRC_THRESH_COMP - [7:2] */
-
-/*
- * R125 (0x7D) - DRC Control 3
- */
-#define WM8993_DRC_AMP_COMP_MASK 0xF800 /* DRC_AMP_COMP - [15:11] */
-#define WM8993_DRC_AMP_COMP_SHIFT 11 /* DRC_AMP_COMP - [15:11] */
-#define WM8993_DRC_AMP_COMP_WIDTH 5 /* DRC_AMP_COMP - [15:11] */
-#define WM8993_DRC_R0_SLOPE_COMP_MASK 0x0700 /* DRC_R0_SLOPE_COMP - [10:8] */
-#define WM8993_DRC_R0_SLOPE_COMP_SHIFT 8 /* DRC_R0_SLOPE_COMP - [10:8] */
-#define WM8993_DRC_R0_SLOPE_COMP_WIDTH 3 /* DRC_R0_SLOPE_COMP - [10:8] */
-#define WM8993_DRC_FF_DELAY 0x0080 /* DRC_FF_DELAY */
-#define WM8993_DRC_FF_DELAY_MASK 0x0080 /* DRC_FF_DELAY */
-#define WM8993_DRC_FF_DELAY_SHIFT 7 /* DRC_FF_DELAY */
-#define WM8993_DRC_FF_DELAY_WIDTH 1 /* DRC_FF_DELAY */
-#define WM8993_DRC_THRESH_QR_MASK 0x000C /* DRC_THRESH_QR - [3:2] */
-#define WM8993_DRC_THRESH_QR_SHIFT 2 /* DRC_THRESH_QR - [3:2] */
-#define WM8993_DRC_THRESH_QR_WIDTH 2 /* DRC_THRESH_QR - [3:2] */
-#define WM8993_DRC_RATE_QR_MASK 0x0003 /* DRC_RATE_QR - [1:0] */
-#define WM8993_DRC_RATE_QR_SHIFT 0 /* DRC_RATE_QR - [1:0] */
-#define WM8993_DRC_RATE_QR_WIDTH 2 /* DRC_RATE_QR - [1:0] */
-
-/*
- * R126 (0x7E) - DRC Control 4
- */
-#define WM8993_DRC_R1_SLOPE_COMP_MASK 0xE000 /* DRC_R1_SLOPE_COMP - [15:13] */
-#define WM8993_DRC_R1_SLOPE_COMP_SHIFT 13 /* DRC_R1_SLOPE_COMP - [15:13] */
-#define WM8993_DRC_R1_SLOPE_COMP_WIDTH 3 /* DRC_R1_SLOPE_COMP - [15:13] */
-#define WM8993_DRC_STARTUP_GAIN_MASK 0x1F00 /* DRC_STARTUP_GAIN - [12:8] */
-#define WM8993_DRC_STARTUP_GAIN_SHIFT 8 /* DRC_STARTUP_GAIN - [12:8] */
-#define WM8993_DRC_STARTUP_GAIN_WIDTH 5 /* DRC_STARTUP_GAIN - [12:8] */
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8994.c b/ANDROID_3.4.5/sound/soc/codecs/wm8994.c
deleted file mode 100644
index ab30c796..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8994.c
+++ /dev/null
@@ -1,4391 +0,0 @@
-/*
- * wm8994.c -- WM8994 ALSA SoC Audio driver
- *
- * Copyright 2009 Wolfson Microelectronics plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/jack.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <trace/events/asoc.h>
-
-#include <linux/proc_fs.h>
-
-#include <linux/mfd/wm8994/core.h>
-#include <linux/mfd/wm8994/registers.h>
-#include <linux/mfd/wm8994/pdata.h>
-#include <linux/mfd/wm8994/gpio.h>
-
-#include "wm8994.h"
-#include "wm_hubs.h"
-
-#define WM1811_JACKDET_MODE_NONE 0x0000
-#define WM1811_JACKDET_MODE_JACK 0x0100
-#define WM1811_JACKDET_MODE_MIC 0x0080
-#define WM1811_JACKDET_MODE_AUDIO 0x0180
-
-#define WM8994_NUM_DRC 3
-#define WM8994_NUM_EQ 3
-
-static int aif1clk_on = 1;
-static struct proc_dir_entry *wm8994_proc;
-
-static struct {
- unsigned int reg;
- unsigned int mask;
-} wm8994_vu_bits[] = {
- { WM8994_LEFT_LINE_INPUT_1_2_VOLUME, WM8994_IN1_VU },
- { WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, WM8994_IN1_VU },
- { WM8994_LEFT_LINE_INPUT_3_4_VOLUME, WM8994_IN2_VU },
- { WM8994_RIGHT_LINE_INPUT_3_4_VOLUME, WM8994_IN2_VU },
- { WM8994_SPEAKER_VOLUME_LEFT, WM8994_SPKOUT_VU },
- { WM8994_SPEAKER_VOLUME_RIGHT, WM8994_SPKOUT_VU },
- { WM8994_LEFT_OUTPUT_VOLUME, WM8994_HPOUT1_VU },
- { WM8994_RIGHT_OUTPUT_VOLUME, WM8994_HPOUT1_VU },
- { WM8994_LEFT_OPGA_VOLUME, WM8994_MIXOUT_VU },
- { WM8994_RIGHT_OPGA_VOLUME, WM8994_MIXOUT_VU },
-
- { WM8994_AIF1_DAC1_LEFT_VOLUME, WM8994_AIF1DAC1_VU },
- { WM8994_AIF1_DAC1_RIGHT_VOLUME, WM8994_AIF1DAC1_VU },
- { WM8994_AIF1_DAC2_LEFT_VOLUME, WM8994_AIF1DAC2_VU },
- { WM8994_AIF1_DAC2_RIGHT_VOLUME, WM8994_AIF1DAC2_VU },
- { WM8994_AIF2_DAC_LEFT_VOLUME, WM8994_AIF2DAC_VU },
- { WM8994_AIF2_DAC_RIGHT_VOLUME, WM8994_AIF2DAC_VU },
- { WM8994_AIF1_ADC1_LEFT_VOLUME, WM8994_AIF1ADC1_VU },
- { WM8994_AIF1_ADC1_RIGHT_VOLUME, WM8994_AIF1ADC1_VU },
- { WM8994_AIF1_ADC2_LEFT_VOLUME, WM8994_AIF1ADC2_VU },
- { WM8994_AIF1_ADC2_RIGHT_VOLUME, WM8994_AIF1ADC2_VU },
- { WM8994_AIF2_ADC_LEFT_VOLUME, WM8994_AIF2ADC_VU },
- { WM8994_AIF2_ADC_RIGHT_VOLUME, WM8994_AIF1ADC2_VU },
- { WM8994_DAC1_LEFT_VOLUME, WM8994_DAC1_VU },
- { WM8994_DAC1_RIGHT_VOLUME, WM8994_DAC1_VU },
- { WM8994_DAC2_LEFT_VOLUME, WM8994_DAC2_VU },
- { WM8994_DAC2_RIGHT_VOLUME, WM8994_DAC2_VU },
-};
-
-static int wm8994_drc_base[] = {
- WM8994_AIF1_DRC1_1,
- WM8994_AIF1_DRC2_1,
- WM8994_AIF2_DRC_1,
-};
-
-static int wm8994_retune_mobile_base[] = {
- WM8994_AIF1_DAC1_EQ_GAINS_1,
- WM8994_AIF1_DAC2_EQ_GAINS_1,
- WM8994_AIF2_EQ_GAINS_1,
-};
-
-static void wm8958_default_micdet(u16 status, void *data);
-
-static const struct wm8958_micd_rate micdet_rates[] = {
- { 32768, true, 1, 4 },
- { 32768, false, 1, 1 },
- { 44100 * 256, true, 7, 10 },
- { 44100 * 256, false, 7, 10 },
-};
-
-static const struct wm8958_micd_rate jackdet_rates[] = {
- { 32768, true, 0, 1 },
- { 32768, false, 0, 1 },
- { 44100 * 256, true, 7, 10 },
- { 44100 * 256, false, 7, 10 },
-};
-
-static void wm8958_micd_set_rate(struct snd_soc_codec *codec)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- int best, i, sysclk, val;
- bool idle;
- const struct wm8958_micd_rate *rates;
- int num_rates;
-
- if (wm8994->jack_cb != wm8958_default_micdet)
- return;
-
- idle = !wm8994->jack_mic;
-
- sysclk = snd_soc_read(codec, WM8994_CLOCKING_1);
- if (sysclk & WM8994_SYSCLK_SRC)
- sysclk = wm8994->aifclk[1];
- else
- sysclk = wm8994->aifclk[0];
-
- if (wm8994->pdata && wm8994->pdata->micd_rates) {
- rates = wm8994->pdata->micd_rates;
- num_rates = wm8994->pdata->num_micd_rates;
- } else if (wm8994->jackdet) {
- rates = jackdet_rates;
- num_rates = ARRAY_SIZE(jackdet_rates);
- } else {
- rates = micdet_rates;
- num_rates = ARRAY_SIZE(micdet_rates);
- }
-
- best = 0;
- for (i = 0; i < num_rates; i++) {
- if (rates[i].idle != idle)
- continue;
- if (abs(rates[i].sysclk - sysclk) <
- abs(rates[best].sysclk - sysclk))
- best = i;
- else if (rates[best].idle != idle)
- best = i;
- }
-
- val = rates[best].start << WM8958_MICD_BIAS_STARTTIME_SHIFT
- | rates[best].rate << WM8958_MICD_RATE_SHIFT;
-
- snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
- WM8958_MICD_BIAS_STARTTIME_MASK |
- WM8958_MICD_RATE_MASK, val);
-}
-
-static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- int rate;
- int reg1 = 0;
- int offset;
-
- if (aif)
- offset = 4;
- else
- offset = 0;
-
- switch (wm8994->sysclk[aif]) {
- case WM8994_SYSCLK_MCLK1:
- rate = wm8994->mclk[0];
- break;
-
- case WM8994_SYSCLK_MCLK2:
- reg1 |= 0x8;
- rate = wm8994->mclk[1];
- break;
-
- case WM8994_SYSCLK_FLL1:
- reg1 |= 0x10;
- rate = wm8994->fll[0].out;
- break;
-
- case WM8994_SYSCLK_FLL2:
- reg1 |= 0x18;
- rate = wm8994->fll[1].out;
- break;
-
- default:
- return -EINVAL;
- }
-
- if (rate >= 13500000) {
- rate /= 2;
- reg1 |= WM8994_AIF1CLK_DIV;
-
- dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n",
- aif + 1, rate);
- }
-
- wm8994->aifclk[aif] = rate;
-
- snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1 + offset,
- WM8994_AIF1CLK_SRC_MASK | WM8994_AIF1CLK_DIV,
- reg1);
-
- return 0;
-}
-
-static int configure_clock(struct snd_soc_codec *codec)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- int change, new;
-
- /* Bring up the AIF clocks first */
- configure_aif_clock(codec, 0);
- configure_aif_clock(codec, 1);
-
- /* Then switch CLK_SYS over to the higher of them; a change
- * can only happen as a result of a clocking change which can
- * only be made outside of DAPM so we can safely redo the
- * clocking.
- */
-
- /* If they're equal it doesn't matter which is used */
- if (wm8994->aifclk[0] == wm8994->aifclk[1]) {
- wm8958_micd_set_rate(codec);
- return 0;
- }
-
- if (wm8994->aifclk[0] < wm8994->aifclk[1])
- new = WM8994_SYSCLK_SRC;
- else
- new = 0;
-
- change = snd_soc_update_bits(codec, WM8994_CLOCKING_1,
- WM8994_SYSCLK_SRC, new);
- if (change)
- snd_soc_dapm_sync(&codec->dapm);
-
- wm8958_micd_set_rate(codec);
-
- return 0;
-}
-
-static int check_clk_sys(struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink)
-{
- int reg = snd_soc_read(source->codec, WM8994_CLOCKING_1);
- const char *clk;
-
- /* Check what we're currently using for CLK_SYS */
- if (reg & WM8994_SYSCLK_SRC)
- clk = "AIF2CLK";
- else
- clk = "AIF1CLK";
-
- return strcmp(source->name, clk) == 0;
-}
-
-static const char *sidetone_hpf_text[] = {
- "2.7kHz", "1.35kHz", "675Hz", "370Hz", "180Hz", "90Hz", "45Hz"
-};
-
-static const struct soc_enum sidetone_hpf =
- SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text);
-
-static const char *adc_hpf_text[] = {
- "HiFi", "Voice 1", "Voice 2", "Voice 3"
-};
-
-static const struct soc_enum aif1adc1_hpf =
- SOC_ENUM_SINGLE(WM8994_AIF1_ADC1_FILTERS, 13, 4, adc_hpf_text);
-
-static const struct soc_enum aif1adc2_hpf =
- SOC_ENUM_SINGLE(WM8994_AIF1_ADC2_FILTERS, 13, 4, adc_hpf_text);
-
-static const struct soc_enum aif2adc_hpf =
- SOC_ENUM_SINGLE(WM8994_AIF2_ADC_FILTERS, 13, 4, adc_hpf_text);
-
-static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0);
-static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
-static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0);
-static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0);
-static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
-static const DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
-static const DECLARE_TLV_DB_SCALE(mixin_boost_tlv, 0, 900, 0);
-
-#define WM8994_DRC_SWITCH(xname, reg, shift) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
- .put = wm8994_put_drc_sw, \
- .private_value = SOC_SINGLE_VALUE(reg, shift, 1, 0) }
-
-static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- int mask, ret;
-
- /* Can't enable both ADC and DAC paths simultaneously */
- if (mc->shift == WM8994_AIF1DAC1_DRC_ENA_SHIFT)
- mask = WM8994_AIF1ADC1L_DRC_ENA_MASK |
- WM8994_AIF1ADC1R_DRC_ENA_MASK;
- else
- mask = WM8994_AIF1DAC1_DRC_ENA_MASK;
-
- ret = snd_soc_read(codec, mc->reg);
- if (ret < 0)
- return ret;
- if (ret & mask)
- return -EINVAL;
-
- return snd_soc_put_volsw(kcontrol, ucontrol);
-}
-
-static void wm8994_set_drc(struct snd_soc_codec *codec, int drc)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994_pdata *pdata = wm8994->pdata;
- int base = wm8994_drc_base[drc];
- int cfg = wm8994->drc_cfg[drc];
- int save, i;
-
- /* Save any enables; the configuration should clear them. */
- save = snd_soc_read(codec, base);
- save &= WM8994_AIF1DAC1_DRC_ENA | WM8994_AIF1ADC1L_DRC_ENA |
- WM8994_AIF1ADC1R_DRC_ENA;
-
- for (i = 0; i < WM8994_DRC_REGS; i++)
- snd_soc_update_bits(codec, base + i, 0xffff,
- pdata->drc_cfgs[cfg].regs[i]);
-
- snd_soc_update_bits(codec, base, WM8994_AIF1DAC1_DRC_ENA |
- WM8994_AIF1ADC1L_DRC_ENA |
- WM8994_AIF1ADC1R_DRC_ENA, save);
-}
-
-/* Icky as hell but saves code duplication */
-static int wm8994_get_drc(const char *name)
-{
- if (strcmp(name, "AIF1DRC1 Mode") == 0)
- return 0;
- if (strcmp(name, "AIF1DRC2 Mode") == 0)
- return 1;
- if (strcmp(name, "AIF2DRC Mode") == 0)
- return 2;
- return -EINVAL;
-}
-
-static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994_pdata *pdata = wm8994->pdata;
- int drc = wm8994_get_drc(kcontrol->id.name);
- int value = ucontrol->value.integer.value[0];
-
- if (drc < 0)
- return drc;
-
- if (value >= pdata->num_drc_cfgs)
- return -EINVAL;
-
- wm8994->drc_cfg[drc] = value;
-
- wm8994_set_drc(codec, drc);
-
- return 0;
-}
-
-static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- int drc = wm8994_get_drc(kcontrol->id.name);
-
- ucontrol->value.enumerated.item[0] = wm8994->drc_cfg[drc];
-
- return 0;
-}
-
-static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994_pdata *pdata = wm8994->pdata;
- int base = wm8994_retune_mobile_base[block];
- int iface, best, best_val, save, i, cfg;
-
- if (!pdata || !wm8994->num_retune_mobile_texts)
- return;
-
- switch (block) {
- case 0:
- case 1:
- iface = 0;
- break;
- case 2:
- iface = 1;
- break;
- default:
- return;
- }
-
- /* Find the version of the currently selected configuration
- * with the nearest sample rate. */
- cfg = wm8994->retune_mobile_cfg[block];
- best = 0;
- best_val = INT_MAX;
- for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
- if (strcmp(pdata->retune_mobile_cfgs[i].name,
- wm8994->retune_mobile_texts[cfg]) == 0 &&
- abs(pdata->retune_mobile_cfgs[i].rate
- - wm8994->dac_rates[iface]) < best_val) {
- best = i;
- best_val = abs(pdata->retune_mobile_cfgs[i].rate
- - wm8994->dac_rates[iface]);
- }
- }
-
- dev_dbg(codec->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n",
- block,
- pdata->retune_mobile_cfgs[best].name,
- pdata->retune_mobile_cfgs[best].rate,
- wm8994->dac_rates[iface]);
-
- /* The EQ will be disabled while reconfiguring it, remember the
- * current configuration.
- */
- save = snd_soc_read(codec, base);
- save &= WM8994_AIF1DAC1_EQ_ENA;
-
- for (i = 0; i < WM8994_EQ_REGS; i++)
- snd_soc_update_bits(codec, base + i, 0xffff,
- pdata->retune_mobile_cfgs[best].regs[i]);
-
- snd_soc_update_bits(codec, base, WM8994_AIF1DAC1_EQ_ENA, save);
-}
-
-/* Icky as hell but saves code duplication */
-static int wm8994_get_retune_mobile_block(const char *name)
-{
- if (strcmp(name, "AIF1.1 EQ Mode") == 0)
- return 0;
- if (strcmp(name, "AIF1.2 EQ Mode") == 0)
- return 1;
- if (strcmp(name, "AIF2 EQ Mode") == 0)
- return 2;
- return -EINVAL;
-}
-
-static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994_pdata *pdata = wm8994->pdata;
- int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
- int value = ucontrol->value.integer.value[0];
-
- if (block < 0)
- return block;
-
- if (value >= pdata->num_retune_mobile_cfgs)
- return -EINVAL;
-
- wm8994->retune_mobile_cfg[block] = value;
-
- wm8994_set_retune_mobile(codec, block);
-
- return 0;
-}
-
-static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
-
- ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block];
-
- return 0;
-}
-
-static const char *aif_chan_src_text[] = {
- "Left", "Right"
-};
-
-static const char *aif_mono_text[] = {
- "Stereo", "Mono"
-};
-
-static const struct soc_enum aif1adcl_src =
- SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 15, 2, aif_chan_src_text);
-
-static const struct soc_enum aif1adcr_src =
- SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 14, 2, aif_chan_src_text);
-
-static const struct soc_enum aif2adcl_src =
- SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 15, 2, aif_chan_src_text);
-
-static const struct soc_enum aif2adcr_src =
- SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 14, 2, aif_chan_src_text);
-
-static const struct soc_enum aif1dacl_src =
- SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 15, 2, aif_chan_src_text);
-
-static const struct soc_enum aif1dacr_src =
- SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 14, 2, aif_chan_src_text);
-
-static const struct soc_enum aif2dacl_src =
- SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 15, 2, aif_chan_src_text);
-
-static const struct soc_enum aif2dacr_src =
- SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aif_chan_src_text);
-
-static const struct soc_enum aif2dac_mono =
- SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 8, 2, aif_mono_text);
-
-static const char *osr_text[] = {
- "Low Power", "High Performance",
-};
-
-static const struct soc_enum dac_osr =
- SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 0, 2, osr_text);
-
-static const struct soc_enum adc_osr =
- SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 1, 2, osr_text);
-
-static const char *compand_mode_text[] = {
- "u-law", "a-law",
-};
-
-static const struct soc_enum aif2dac_compand_mode =
- SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 3, 2, compand_mode_text);
-
-static const struct soc_enum aif2adc_compand_mode =
- SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 1, 2, compand_mode_text);
-
-static const struct snd_kcontrol_new wm8994_snd_controls[] = {
-SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME,
- WM8994_AIF1_ADC1_RIGHT_VOLUME,
- 1, 119, 0, digital_tlv),
-SOC_DOUBLE_R_TLV("AIF1ADC2 Volume", WM8994_AIF1_ADC2_LEFT_VOLUME,
- WM8994_AIF1_ADC2_RIGHT_VOLUME,
- 1, 119, 0, digital_tlv),
-SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8994_AIF2_ADC_LEFT_VOLUME,
- WM8994_AIF2_ADC_RIGHT_VOLUME,
- 1, 119, 0, digital_tlv),
-
-SOC_ENUM("AIF1ADCL Source", aif1adcl_src),
-SOC_ENUM("AIF1ADCR Source", aif1adcr_src),
-SOC_ENUM("AIF2ADCL Source", aif2adcl_src),
-SOC_ENUM("AIF2ADCR Source", aif2adcr_src),
-
-SOC_ENUM("AIF1DACL Source", aif1dacl_src),
-SOC_ENUM("AIF1DACR Source", aif1dacr_src),
-SOC_ENUM("AIF2DACL Source", aif2dacl_src),
-SOC_ENUM("AIF2DACR Source", aif2dacr_src),
-
-SOC_ENUM("AIF2DAC Mono", aif2dac_mono),
-
-SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8994_AIF1_DAC1_LEFT_VOLUME,
- WM8994_AIF1_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
-SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8994_AIF1_DAC2_LEFT_VOLUME,
- WM8994_AIF1_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
-SOC_DOUBLE_R_TLV("AIF2DAC Volume", WM8994_AIF2_DAC_LEFT_VOLUME,
- WM8994_AIF2_DAC_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
-
-SOC_SINGLE_TLV("AIF1 Boost Volume", WM8994_AIF1_CONTROL_2, 10, 3, 0, aif_tlv),
-SOC_SINGLE_TLV("AIF2 Boost Volume", WM8994_AIF2_CONTROL_2, 10, 3, 0, aif_tlv),
-
-SOC_SINGLE("AIF1DAC1 EQ Switch", WM8994_AIF1_DAC1_EQ_GAINS_1, 0, 1, 0),
-SOC_SINGLE("AIF1DAC2 EQ Switch", WM8994_AIF1_DAC2_EQ_GAINS_1, 0, 1, 0),
-SOC_SINGLE("AIF2 EQ Switch", WM8994_AIF2_EQ_GAINS_1, 0, 1, 0),
-
-WM8994_DRC_SWITCH("AIF1DAC1 DRC Switch", WM8994_AIF1_DRC1_1, 2),
-WM8994_DRC_SWITCH("AIF1ADC1L DRC Switch", WM8994_AIF1_DRC1_1, 1),
-WM8994_DRC_SWITCH("AIF1ADC1R DRC Switch", WM8994_AIF1_DRC1_1, 0),
-
-WM8994_DRC_SWITCH("AIF1DAC2 DRC Switch", WM8994_AIF1_DRC2_1, 2),
-WM8994_DRC_SWITCH("AIF1ADC2L DRC Switch", WM8994_AIF1_DRC2_1, 1),
-WM8994_DRC_SWITCH("AIF1ADC2R DRC Switch", WM8994_AIF1_DRC2_1, 0),
-
-WM8994_DRC_SWITCH("AIF2DAC DRC Switch", WM8994_AIF2_DRC_1, 2),
-WM8994_DRC_SWITCH("AIF2ADCL DRC Switch", WM8994_AIF2_DRC_1, 1),
-WM8994_DRC_SWITCH("AIF2ADCR DRC Switch", WM8994_AIF2_DRC_1, 0),
-
-SOC_SINGLE_TLV("DAC1 Right Sidetone Volume", WM8994_DAC1_MIXER_VOLUMES,
- 5, 12, 0, st_tlv),
-SOC_SINGLE_TLV("DAC1 Left Sidetone Volume", WM8994_DAC1_MIXER_VOLUMES,
- 0, 12, 0, st_tlv),
-SOC_SINGLE_TLV("DAC2 Right Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES,
- 5, 12, 0, st_tlv),
-SOC_SINGLE_TLV("DAC2 Left Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES,
- 0, 12, 0, st_tlv),
-SOC_ENUM("Sidetone HPF Mux", sidetone_hpf),
-SOC_SINGLE("Sidetone HPF Switch", WM8994_SIDETONE, 6, 1, 0),
-
-SOC_ENUM("AIF1ADC1 HPF Mode", aif1adc1_hpf),
-SOC_DOUBLE("AIF1ADC1 HPF Switch", WM8994_AIF1_ADC1_FILTERS, 12, 11, 1, 0),
-
-SOC_ENUM("AIF1ADC2 HPF Mode", aif1adc2_hpf),
-SOC_DOUBLE("AIF1ADC2 HPF Switch", WM8994_AIF1_ADC2_FILTERS, 12, 11, 1, 0),
-
-SOC_ENUM("AIF2ADC HPF Mode", aif2adc_hpf),
-SOC_DOUBLE("AIF2ADC HPF Switch", WM8994_AIF2_ADC_FILTERS, 12, 11, 1, 0),
-
-SOC_ENUM("ADC OSR", adc_osr),
-SOC_ENUM("DAC OSR", dac_osr),
-
-SOC_DOUBLE_R_TLV("DAC1 Volume", WM8994_DAC1_LEFT_VOLUME,
- WM8994_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
-SOC_DOUBLE_R("DAC1 Switch", WM8994_DAC1_LEFT_VOLUME,
- WM8994_DAC1_RIGHT_VOLUME, 9, 1, 1),
-
-SOC_DOUBLE_R_TLV("DAC2 Volume", WM8994_DAC2_LEFT_VOLUME,
- WM8994_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
-SOC_DOUBLE_R("DAC2 Switch", WM8994_DAC2_LEFT_VOLUME,
- WM8994_DAC2_RIGHT_VOLUME, 9, 1, 1),
-
-SOC_SINGLE_TLV("SPKL DAC2 Volume", WM8994_SPKMIXL_ATTENUATION,
- 6, 1, 1, wm_hubs_spkmix_tlv),
-SOC_SINGLE_TLV("SPKL DAC1 Volume", WM8994_SPKMIXL_ATTENUATION,
- 2, 1, 1, wm_hubs_spkmix_tlv),
-
-SOC_SINGLE_TLV("SPKR DAC2 Volume", WM8994_SPKMIXR_ATTENUATION,
- 6, 1, 1, wm_hubs_spkmix_tlv),
-SOC_SINGLE_TLV("SPKR DAC1 Volume", WM8994_SPKMIXR_ATTENUATION,
- 2, 1, 1, wm_hubs_spkmix_tlv),
-
-SOC_SINGLE_TLV("AIF1DAC1 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2,
- 10, 15, 0, wm8994_3d_tlv),
-SOC_SINGLE("AIF1DAC1 3D Stereo Switch", WM8994_AIF1_DAC1_FILTERS_2,
- 8, 1, 0),
-SOC_SINGLE_TLV("AIF1DAC2 3D Stereo Volume", WM8994_AIF1_DAC2_FILTERS_2,
- 10, 15, 0, wm8994_3d_tlv),
-SOC_SINGLE("AIF1DAC2 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
- 8, 1, 0),
-SOC_SINGLE_TLV("AIF2DAC 3D Stereo Volume", WM8994_AIF2_DAC_FILTERS_2,
- 10, 15, 0, wm8994_3d_tlv),
-SOC_SINGLE("AIF2DAC 3D Stereo Switch", WM8994_AIF2_DAC_FILTERS_2,
- 8, 1, 0),
-
-SOC_SINGLE("MICBIAS2 Switch", WM8994_POWER_MANAGEMENT_1, 5, 1, 0),
-SOC_SINGLE("MICBIAS1 Switch", WM8994_POWER_MANAGEMENT_1, 4, 1, 0),
-
-SOC_SINGLE("AIF2DAC Compand Switch", WM8994_AIF2_CONTROL_2, 4, 1, 0),
-SOC_SINGLE("AIF2ADC Compand Switch", WM8994_AIF2_CONTROL_2, 2, 1, 0),
-
-SOC_ENUM("AIF2DAC Compand Mode", aif2dac_compand_mode),
-SOC_ENUM("AIF2ADC Compand Mode", aif2adc_compand_mode),
-};
-
-static const struct snd_kcontrol_new wm8994_eq_controls[] = {
-SOC_SINGLE_TLV("AIF1DAC1 EQ1 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 11, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("AIF1DAC1 EQ2 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 6, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("AIF1DAC1 EQ3 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 1, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("AIF1DAC1 EQ4 Volume", WM8994_AIF1_DAC1_EQ_GAINS_2, 11, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("AIF1DAC1 EQ5 Volume", WM8994_AIF1_DAC1_EQ_GAINS_2, 6, 31, 0,
- eq_tlv),
-
-SOC_SINGLE_TLV("AIF1DAC2 EQ1 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 11, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("AIF1DAC2 EQ2 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 6, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("AIF1DAC2 EQ3 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 1, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("AIF1DAC2 EQ4 Volume", WM8994_AIF1_DAC2_EQ_GAINS_2, 11, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("AIF1DAC2 EQ5 Volume", WM8994_AIF1_DAC2_EQ_GAINS_2, 6, 31, 0,
- eq_tlv),
-
-SOC_SINGLE_TLV("AIF2 EQ1 Volume", WM8994_AIF2_EQ_GAINS_1, 11, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("AIF2 EQ2 Volume", WM8994_AIF2_EQ_GAINS_1, 6, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("AIF2 EQ3 Volume", WM8994_AIF2_EQ_GAINS_1, 1, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("AIF2 EQ4 Volume", WM8994_AIF2_EQ_GAINS_2, 11, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
- eq_tlv),
-};
-
-static const char *wm8958_ng_text[] = {
- "30ms", "125ms", "250ms", "500ms",
-};
-
-static const struct soc_enum wm8958_aif1dac1_ng_hold =
- SOC_ENUM_SINGLE(WM8958_AIF1_DAC1_NOISE_GATE,
- WM8958_AIF1DAC1_NG_THR_SHIFT, 4, wm8958_ng_text);
-
-static const struct soc_enum wm8958_aif1dac2_ng_hold =
- SOC_ENUM_SINGLE(WM8958_AIF1_DAC2_NOISE_GATE,
- WM8958_AIF1DAC2_NG_THR_SHIFT, 4, wm8958_ng_text);
-
-static const struct soc_enum wm8958_aif2dac_ng_hold =
- SOC_ENUM_SINGLE(WM8958_AIF2_DAC_NOISE_GATE,
- WM8958_AIF2DAC_NG_THR_SHIFT, 4, wm8958_ng_text);
-
-static const struct snd_kcontrol_new wm8958_snd_controls[] = {
-SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv),
-
-SOC_SINGLE("AIF1DAC1 Noise Gate Switch", WM8958_AIF1_DAC1_NOISE_GATE,
- WM8958_AIF1DAC1_NG_ENA_SHIFT, 1, 0),
-SOC_ENUM("AIF1DAC1 Noise Gate Hold Time", wm8958_aif1dac1_ng_hold),
-SOC_SINGLE_TLV("AIF1DAC1 Noise Gate Threshold Volume",
- WM8958_AIF1_DAC1_NOISE_GATE, WM8958_AIF1DAC1_NG_THR_SHIFT,
- 7, 1, ng_tlv),
-
-SOC_SINGLE("AIF1DAC2 Noise Gate Switch", WM8958_AIF1_DAC2_NOISE_GATE,
- WM8958_AIF1DAC2_NG_ENA_SHIFT, 1, 0),
-SOC_ENUM("AIF1DAC2 Noise Gate Hold Time", wm8958_aif1dac2_ng_hold),
-SOC_SINGLE_TLV("AIF1DAC2 Noise Gate Threshold Volume",
- WM8958_AIF1_DAC2_NOISE_GATE, WM8958_AIF1DAC2_NG_THR_SHIFT,
- 7, 1, ng_tlv),
-
-SOC_SINGLE("AIF2DAC Noise Gate Switch", WM8958_AIF2_DAC_NOISE_GATE,
- WM8958_AIF2DAC_NG_ENA_SHIFT, 1, 0),
-SOC_ENUM("AIF2DAC Noise Gate Hold Time", wm8958_aif2dac_ng_hold),
-SOC_SINGLE_TLV("AIF2DAC Noise Gate Threshold Volume",
- WM8958_AIF2_DAC_NOISE_GATE, WM8958_AIF2DAC_NG_THR_SHIFT,
- 7, 1, ng_tlv),
-};
-
-static const struct snd_kcontrol_new wm1811_snd_controls[] = {
-SOC_SINGLE_TLV("MIXINL IN1LP Boost Volume", WM8994_INPUT_MIXER_1, 7, 1, 0,
- mixin_boost_tlv),
-SOC_SINGLE_TLV("MIXINL IN1RP Boost Volume", WM8994_INPUT_MIXER_1, 8, 1, 0,
- mixin_boost_tlv),
-};
-
-/* We run all mode setting through a function to enforce audio mode */
-static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- if (!wm8994->jackdet || !wm8994->jack_cb)
- return;
-
- if (wm8994->active_refcount)
- mode = WM1811_JACKDET_MODE_AUDIO;
-
- if (mode == wm8994->jackdet_mode)
- return;
-
- wm8994->jackdet_mode = mode;
-
- /* Always use audio mode to detect while the system is active */
- if (mode != WM1811_JACKDET_MODE_NONE)
- mode = WM1811_JACKDET_MODE_AUDIO;
-
- snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
- WM1811_JACKDET_MODE_MASK, mode);
-}
-
-static void active_reference(struct snd_soc_codec *codec)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- mutex_lock(&wm8994->accdet_lock);
-
- wm8994->active_refcount++;
-
- dev_dbg(codec->dev, "Active refcount incremented, now %d\n",
- wm8994->active_refcount);
-
- /* If we're using jack detection go into audio mode */
- wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_AUDIO);
-
- mutex_unlock(&wm8994->accdet_lock);
-}
-
-static void active_dereference(struct snd_soc_codec *codec)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- u16 mode;
-
- mutex_lock(&wm8994->accdet_lock);
-
- wm8994->active_refcount--;
-
- dev_dbg(codec->dev, "Active refcount decremented, now %d\n",
- wm8994->active_refcount);
-
- if (wm8994->active_refcount == 0) {
- /* Go into appropriate detection only mode */
- if (wm8994->jack_mic || wm8994->mic_detecting)
- mode = WM1811_JACKDET_MODE_MIC;
- else
- mode = WM1811_JACKDET_MODE_JACK;
-
- wm1811_jackdet_set_mode(codec, mode);
- }
-
- mutex_unlock(&wm8994->accdet_lock);
-}
-
-static int clk_sys_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- return configure_clock(codec);
-
- case SND_SOC_DAPM_POST_PMD:
- configure_clock(codec);
- break;
- }
-
- return 0;
-}
-
-static void vmid_reference(struct snd_soc_codec *codec)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- pm_runtime_get_sync(codec->dev);
-
- wm8994->vmid_refcount++;
-
- dev_dbg(codec->dev, "Referencing VMID, refcount is now %d\n",
- wm8994->vmid_refcount);
-
- if (wm8994->vmid_refcount == 1) {
- snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
- WM8994_LINEOUT1_DISCH |
- WM8994_LINEOUT2_DISCH, 0);
-
- wm_hubs_vmid_ena(codec);
-
- switch (wm8994->vmid_mode) {
- default:
- WARN_ON(0 == "Invalid VMID mode");
- case WM8994_VMID_NORMAL:
- /* Startup bias, VMID ramp & buffer */
- snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
- WM8994_BIAS_SRC |
- WM8994_VMID_DISCH |
- WM8994_STARTUP_BIAS_ENA |
- WM8994_VMID_BUF_ENA |
- WM8994_VMID_RAMP_MASK,
- WM8994_BIAS_SRC |
- WM8994_STARTUP_BIAS_ENA |
- WM8994_VMID_BUF_ENA |
- (0x3 << WM8994_VMID_RAMP_SHIFT));
-
- /* Main bias enable, VMID=2x40k */
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
- WM8994_BIAS_ENA |
- WM8994_VMID_SEL_MASK,
- WM8994_BIAS_ENA | 0x2);
-
- msleep(50);
-
- snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
- WM8994_VMID_RAMP_MASK |
- WM8994_BIAS_SRC,
- 0);
- break;
-
- case WM8994_VMID_FORCE:
- /* Startup bias, slow VMID ramp & buffer */
- snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
- WM8994_BIAS_SRC |
- WM8994_VMID_DISCH |
- WM8994_STARTUP_BIAS_ENA |
- WM8994_VMID_BUF_ENA |
- WM8994_VMID_RAMP_MASK,
- WM8994_BIAS_SRC |
- WM8994_STARTUP_BIAS_ENA |
- WM8994_VMID_BUF_ENA |
- (0x2 << WM8994_VMID_RAMP_SHIFT));
-
- /* Main bias enable, VMID=2x40k */
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
- WM8994_BIAS_ENA |
- WM8994_VMID_SEL_MASK,
- WM8994_BIAS_ENA | 0x2);
-
- msleep(400);
-
- snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
- WM8994_VMID_RAMP_MASK |
- WM8994_BIAS_SRC,
- 0);
- break;
- }
- }
-}
-
-static void vmid_dereference(struct snd_soc_codec *codec)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- wm8994->vmid_refcount--;
-
- dev_dbg(codec->dev, "Dereferencing VMID, refcount is now %d\n",
- wm8994->vmid_refcount);
-
- if (wm8994->vmid_refcount == 0) {
- if (wm8994->hubs.lineout1_se)
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3,
- WM8994_LINEOUT1N_ENA |
- WM8994_LINEOUT1P_ENA,
- WM8994_LINEOUT1N_ENA |
- WM8994_LINEOUT1P_ENA);
-
- if (wm8994->hubs.lineout2_se)
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3,
- WM8994_LINEOUT2N_ENA |
- WM8994_LINEOUT2P_ENA,
- WM8994_LINEOUT2N_ENA |
- WM8994_LINEOUT2P_ENA);
-
- /* Start discharging VMID */
- snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
- WM8994_BIAS_SRC |
- WM8994_VMID_DISCH,
- WM8994_BIAS_SRC |
- WM8994_VMID_DISCH);
-
- switch (wm8994->vmid_mode) {
- case WM8994_VMID_FORCE:
- msleep(350);
- break;
- default:
- break;
- }
-
- snd_soc_update_bits(codec, WM8994_ADDITIONAL_CONTROL,
- WM8994_VROI, WM8994_VROI);
-
- /* Active discharge */
- snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
- WM8994_LINEOUT1_DISCH |
- WM8994_LINEOUT2_DISCH,
- WM8994_LINEOUT1_DISCH |
- WM8994_LINEOUT2_DISCH);
-
- msleep(150);
-
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3,
- WM8994_LINEOUT1N_ENA |
- WM8994_LINEOUT1P_ENA |
- WM8994_LINEOUT2N_ENA |
- WM8994_LINEOUT2P_ENA, 0);
-
- snd_soc_update_bits(codec, WM8994_ADDITIONAL_CONTROL,
- WM8994_VROI, 0);
-
- /* Switch off startup biases */
- snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
- WM8994_BIAS_SRC |
- WM8994_STARTUP_BIAS_ENA |
- WM8994_VMID_BUF_ENA |
- WM8994_VMID_RAMP_MASK, 0);
-
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
- WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0);
-
- snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
- WM8994_VMID_RAMP_MASK, 0);
- }
-
- pm_runtime_put(codec->dev);
-}
-
-static int vmid_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- vmid_reference(codec);
- break;
-
- case SND_SOC_DAPM_POST_PMD:
- vmid_dereference(codec);
- break;
- }
-
- return 0;
-}
-
-static void wm8994_update_class_w(struct snd_soc_codec *codec)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- int enable = 1;
- int source = 0; /* GCC flow analysis can't track enable */
- int reg, reg_r;
-
- /* Only support direct DAC->headphone paths */
- reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_1);
- if (!(reg & WM8994_DAC1L_TO_HPOUT1L)) {
- dev_vdbg(codec->dev, "HPL connected to output mixer\n");
- enable = 0;
- }
-
- reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_2);
- if (!(reg & WM8994_DAC1R_TO_HPOUT1R)) {
- dev_vdbg(codec->dev, "HPR connected to output mixer\n");
- enable = 0;
- }
-
- /* We also need the same setting for L/R and only one path */
- reg = snd_soc_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
- switch (reg) {
- case WM8994_AIF2DACL_TO_DAC1L:
- dev_vdbg(codec->dev, "Class W source AIF2DAC\n");
- source = 2 << WM8994_CP_DYN_SRC_SEL_SHIFT;
- break;
- case WM8994_AIF1DAC2L_TO_DAC1L:
- dev_vdbg(codec->dev, "Class W source AIF1DAC2\n");
- source = 1 << WM8994_CP_DYN_SRC_SEL_SHIFT;
- break;
- case WM8994_AIF1DAC1L_TO_DAC1L:
- dev_vdbg(codec->dev, "Class W source AIF1DAC1\n");
- source = 0 << WM8994_CP_DYN_SRC_SEL_SHIFT;
- break;
- default:
- dev_vdbg(codec->dev, "DAC mixer setting: %x\n", reg);
- enable = 0;
- break;
- }
-
- reg_r = snd_soc_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
- if (reg_r != reg) {
- dev_vdbg(codec->dev, "Left and right DAC mixers different\n");
- enable = 0;
- }
-
- if (enable) {
- dev_dbg(codec->dev, "Class W enabled\n");
- snd_soc_update_bits(codec, WM8994_CLASS_W_1,
- WM8994_CP_DYN_PWR |
- WM8994_CP_DYN_SRC_SEL_MASK,
- source | WM8994_CP_DYN_PWR);
- wm8994->hubs.class_w = true;
-
- } else {
- dev_dbg(codec->dev, "Class W disabled\n");
- snd_soc_update_bits(codec, WM8994_CLASS_W_1,
- WM8994_CP_DYN_PWR, 0);
- wm8994->hubs.class_w = false;
- }
-}
-
-static int aif1clk_ev(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- struct wm8994 *control = codec->control_data;
- int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA;
- int i;
- int dac;
- int adc;
- int val;
-
- switch (control->type) {
- case WM8994:
- case WM8958:
- mask |= WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA;
- break;
- default:
- break;
- }
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- val = snd_soc_read(codec, WM8994_AIF1_CONTROL_1);
- if ((val & WM8994_AIF1ADCL_SRC) &&
- (val & WM8994_AIF1ADCR_SRC))
- adc = WM8994_AIF1ADC1R_ENA | WM8994_AIF1ADC2R_ENA;
- else if (!(val & WM8994_AIF1ADCL_SRC) &&
- !(val & WM8994_AIF1ADCR_SRC))
- adc = WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC2L_ENA;
- else
- adc = WM8994_AIF1ADC1R_ENA | WM8994_AIF1ADC2R_ENA |
- WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC2L_ENA;
-
- val = snd_soc_read(codec, WM8994_AIF1_CONTROL_2);
- if ((val & WM8994_AIF1DACL_SRC) &&
- (val & WM8994_AIF1DACR_SRC))
- dac = WM8994_AIF1DAC1R_ENA | WM8994_AIF1DAC2R_ENA;
- else if (!(val & WM8994_AIF1DACL_SRC) &&
- !(val & WM8994_AIF1DACR_SRC))
- dac = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC2L_ENA;
- else
- dac = WM8994_AIF1DAC1R_ENA | WM8994_AIF1DAC2R_ENA |
- WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC2L_ENA;
-
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4,
- mask, adc);
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
- mask, dac);
- snd_soc_update_bits(codec, WM8994_CLOCKING_1,
- WM8994_AIF1DSPCLK_ENA |
- WM8994_SYSDSPCLK_ENA,
- WM8994_AIF1DSPCLK_ENA |
- WM8994_SYSDSPCLK_ENA);
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, mask,
- WM8994_AIF1ADC1R_ENA |
- WM8994_AIF1ADC1L_ENA |
- WM8994_AIF1ADC2R_ENA |
- WM8994_AIF1ADC2L_ENA);
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, mask,
- WM8994_AIF1DAC1R_ENA |
- WM8994_AIF1DAC1L_ENA |
- WM8994_AIF1DAC2R_ENA |
- WM8994_AIF1DAC2L_ENA);
- break;
-
- case SND_SOC_DAPM_POST_PMU:
- for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++)
- snd_soc_write(codec, wm8994_vu_bits[i].reg,
- snd_soc_read(codec,
- wm8994_vu_bits[i].reg));
- break;
-
- case SND_SOC_DAPM_PRE_PMD:
- case SND_SOC_DAPM_POST_PMD:
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
- mask, 0);
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4,
- mask, 0);
-
- val = snd_soc_read(codec, WM8994_CLOCKING_1);
- if (val & WM8994_AIF2DSPCLK_ENA)
- val = WM8994_SYSDSPCLK_ENA;
- else
- val = 0;
- snd_soc_update_bits(codec, WM8994_CLOCKING_1,
- WM8994_SYSDSPCLK_ENA |
- WM8994_AIF1DSPCLK_ENA, val);
- break;
- }
-
- return 0;
-}
-
-static int aif2clk_ev(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- int i;
- int dac;
- int adc;
- int val;
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- val = snd_soc_read(codec, WM8994_AIF2_CONTROL_1);
- if ((val & WM8994_AIF2ADCL_SRC) &&
- (val & WM8994_AIF2ADCR_SRC))
- adc = WM8994_AIF2ADCR_ENA;
- else if (!(val & WM8994_AIF2ADCL_SRC) &&
- !(val & WM8994_AIF2ADCR_SRC))
- adc = WM8994_AIF2ADCL_ENA;
- else
- adc = WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA;
-
-
- val = snd_soc_read(codec, WM8994_AIF2_CONTROL_2);
- if ((val & WM8994_AIF2DACL_SRC) &&
- (val & WM8994_AIF2DACR_SRC))
- dac = WM8994_AIF2DACR_ENA;
- else if (!(val & WM8994_AIF2DACL_SRC) &&
- !(val & WM8994_AIF2DACR_SRC))
- dac = WM8994_AIF2DACL_ENA;
- else
- dac = WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA;
-
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4,
- WM8994_AIF2ADCL_ENA |
- WM8994_AIF2ADCR_ENA, adc);
- /*snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
- WM8994_AIF2DACL_ENA |
- WM8994_AIF2DACR_ENA, dac);*/
- snd_soc_update_bits(codec, WM8994_CLOCKING_1,
- WM8994_AIF2DSPCLK_ENA |
- WM8994_SYSDSPCLK_ENA,
- WM8994_AIF2DSPCLK_ENA |
- WM8994_SYSDSPCLK_ENA);
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4,
- WM8994_AIF2ADCL_ENA |
- WM8994_AIF2ADCR_ENA,
- WM8994_AIF2ADCL_ENA |
- WM8994_AIF2ADCR_ENA);
- /*snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
- WM8994_AIF2DACL_ENA |
- WM8994_AIF2DACR_ENA,
- WM8994_AIF2DACL_ENA |
- WM8994_AIF2DACR_ENA);*/
- break;
-
- case SND_SOC_DAPM_POST_PMU:
- for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++)
- snd_soc_write(codec, wm8994_vu_bits[i].reg,
- snd_soc_read(codec,
- wm8994_vu_bits[i].reg));
- break;
-
- case SND_SOC_DAPM_PRE_PMD:
- case SND_SOC_DAPM_POST_PMD:
- /*snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
- WM8994_AIF2DACL_ENA |
- WM8994_AIF2DACR_ENA, 0);*/
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4,
- WM8994_AIF2ADCL_ENA |
- WM8994_AIF2ADCR_ENA, 0);
-
- val = snd_soc_read(codec, WM8994_CLOCKING_1);
- if (val & WM8994_AIF1DSPCLK_ENA)
- val = WM8994_SYSDSPCLK_ENA;
- else
- val = 0;
- snd_soc_update_bits(codec, WM8994_CLOCKING_1,
- WM8994_SYSDSPCLK_ENA |
- WM8994_AIF2DSPCLK_ENA, val);
- break;
- }
-
- return 0;
-}
-
-static int aif1clk_late_ev(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- wm8994->aif1clk_enable = 1;
- break;
- case SND_SOC_DAPM_POST_PMD:
- wm8994->aif1clk_disable = 1;
- break;
- }
-
- return 0;
-}
-
-static int aif2clk_late_ev(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- wm8994->aif2clk_enable = 1;
- break;
- case SND_SOC_DAPM_POST_PMD:
- wm8994->aif2clk_disable = 1;
- break;
- }
-
- return 0;
-}
-
-static int late_enable_ev(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- if (wm8994->aif1clk_enable) {
- aif1clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMU);
- snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
- WM8994_AIF1CLK_ENA_MASK,
- WM8994_AIF1CLK_ENA);
- aif1clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMU);
- wm8994->aif1clk_enable = 0;
- }
- if (wm8994->aif2clk_enable) {
- aif2clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMU);
- snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
- WM8994_AIF2CLK_ENA_MASK,
- WM8994_AIF2CLK_ENA);
- aif2clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMU);
- wm8994->aif2clk_enable = 0;
- }
- break;
- }
-
- /* We may also have postponed startup of DSP, handle that. */
- wm8958_aif_ev(w, kcontrol, event);
-
- return 0;
-}
-
-static int late_disable_ev(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMD:
- if (wm8994->aif1clk_disable) {
-
- aif1clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMD);
- if (!aif1clk_on){
- snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
- WM8994_AIF1CLK_ENA_MASK, 0);
- }
- aif1clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMD);
-
- wm8994->aif1clk_disable = 0;
- }
- if (wm8994->aif2clk_disable) {
- aif2clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMD);
- snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
- WM8994_AIF2CLK_ENA_MASK, 0);
- aif2clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMD);
- wm8994->aif2clk_disable = 0;
- }
- break;
- }
-
- return 0;
-}
-
-static int adc_mux_ev(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- late_enable_ev(w, kcontrol, event);
- return 0;
-}
-
-static int micbias_ev(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- late_enable_ev(w, kcontrol, event);
- return 0;
-}
-
-static int dac_ev(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- unsigned int mask = 1 << w->shift;
-
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
- mask, mask);
- return 0;
-}
-
-static const char *hp_mux_text[] = {
- "Mixer",
- "DAC",
-};
-
-#define WM8994_HP_ENUM(xname, xenum) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_soc_info_enum_double, \
- .get = snd_soc_dapm_get_enum_double, \
- .put = wm8994_put_hp_enum, \
- .private_value = (unsigned long)&xenum }
-
-static int wm8994_put_hp_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
- struct snd_soc_dapm_widget *w = wlist->widgets[0];
- struct snd_soc_codec *codec = w->codec;
- int ret;
-
- ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
-
- wm8994_update_class_w(codec);
-
- return ret;
-}
-
-static const struct soc_enum hpl_enum =
- SOC_ENUM_SINGLE(WM8994_OUTPUT_MIXER_1, 8, 2, hp_mux_text);
-
-static const struct snd_kcontrol_new hpl_mux =
- WM8994_HP_ENUM("Left Headphone Mux", hpl_enum);
-
-static const struct soc_enum hpr_enum =
- SOC_ENUM_SINGLE(WM8994_OUTPUT_MIXER_2, 8, 2, hp_mux_text);
-
-static const struct snd_kcontrol_new hpr_mux =
- WM8994_HP_ENUM("Right Headphone Mux", hpr_enum);
-
-static const char *adc_mux_text[] = {
- "ADC",
- "DMIC",
-};
-
-static const struct soc_enum adc_enum =
- SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text);
-
-static const struct snd_kcontrol_new adcl_mux =
- SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum);
-
-static const struct snd_kcontrol_new adcr_mux =
- SOC_DAPM_ENUM_VIRT("ADCR Mux", adc_enum);
-
-static const struct snd_kcontrol_new left_speaker_mixer[] = {
-SOC_DAPM_SINGLE("DAC2 Switch", WM8994_SPEAKER_MIXER, 9, 1, 0),
-SOC_DAPM_SINGLE("Input Switch", WM8994_SPEAKER_MIXER, 7, 1, 0),
-SOC_DAPM_SINGLE("IN1LP Switch", WM8994_SPEAKER_MIXER, 5, 1, 0),
-SOC_DAPM_SINGLE("Output Switch", WM8994_SPEAKER_MIXER, 3, 1, 0),
-SOC_DAPM_SINGLE("DAC1 Switch", WM8994_SPEAKER_MIXER, 1, 1, 0),
-};
-
-static const struct snd_kcontrol_new right_speaker_mixer[] = {
-SOC_DAPM_SINGLE("DAC2 Switch", WM8994_SPEAKER_MIXER, 8, 1, 0),
-SOC_DAPM_SINGLE("Input Switch", WM8994_SPEAKER_MIXER, 6, 1, 0),
-SOC_DAPM_SINGLE("IN1RP Switch", WM8994_SPEAKER_MIXER, 4, 1, 0),
-SOC_DAPM_SINGLE("Output Switch", WM8994_SPEAKER_MIXER, 2, 1, 0),
-SOC_DAPM_SINGLE("DAC1 Switch", WM8994_SPEAKER_MIXER, 0, 1, 0),
-};
-
-/* Debugging; dump chip status after DAPM transitions */
-static int post_ev(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- dev_dbg(codec->dev, "SRC status: %x\n",
- snd_soc_read(codec,
- WM8994_RATE_STATUS));
- return 0;
-}
-
-static const struct snd_kcontrol_new aif1adc1l_mix[] = {
-SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING,
- 1, 1, 0),
-SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new aif1adc1r_mix[] = {
-SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING,
- 1, 1, 0),
-SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new aif1adc2l_mix[] = {
-SOC_DAPM_SINGLE("DMIC Switch", WM8994_AIF1_ADC2_LEFT_MIXER_ROUTING,
- 1, 1, 0),
-SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC2_LEFT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new aif1adc2r_mix[] = {
-SOC_DAPM_SINGLE("DMIC Switch", WM8994_AIF1_ADC2_RIGHT_MIXER_ROUTING,
- 1, 1, 0),
-SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC2_RIGHT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new aif2dac2l_mix[] = {
-SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
- 5, 1, 0),
-SOC_DAPM_SINGLE("Left Sidetone Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
- 4, 1, 0),
-SOC_DAPM_SINGLE("AIF2 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
- 2, 1, 0),
-SOC_DAPM_SINGLE("AIF1.2 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
- 1, 1, 0),
-SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new aif2dac2r_mix[] = {
-SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
- 5, 1, 0),
-SOC_DAPM_SINGLE("Left Sidetone Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
- 4, 1, 0),
-SOC_DAPM_SINGLE("AIF2 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
- 2, 1, 0),
-SOC_DAPM_SINGLE("AIF1.2 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
- 1, 1, 0),
-SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-#define WM8994_CLASS_W_SWITCH(xname, reg, shift, max, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_soc_info_volsw, \
- .get = snd_soc_dapm_get_volsw, .put = wm8994_put_class_w, \
- .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
-
-static int wm8994_put_class_w(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
- struct snd_soc_dapm_widget *w = wlist->widgets[0];
- struct snd_soc_codec *codec = w->codec;
- int ret;
-
- ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
-
- wm8994_update_class_w(codec);
-
- return ret;
-}
-
-static const struct snd_kcontrol_new dac1l_mix[] = {
-WM8994_CLASS_W_SWITCH("Right Sidetone Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
- 5, 1, 0),
-WM8994_CLASS_W_SWITCH("Left Sidetone Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
- 4, 1, 0),
-WM8994_CLASS_W_SWITCH("AIF2 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
- 2, 1, 0),
-WM8994_CLASS_W_SWITCH("AIF1.2 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
- 1, 1, 0),
-WM8994_CLASS_W_SWITCH("AIF1.1 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new dac1r_mix[] = {
-WM8994_CLASS_W_SWITCH("Right Sidetone Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
- 5, 1, 0),
-WM8994_CLASS_W_SWITCH("Left Sidetone Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
- 4, 1, 0),
-WM8994_CLASS_W_SWITCH("AIF2 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
- 2, 1, 0),
-WM8994_CLASS_W_SWITCH("AIF1.2 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
- 1, 1, 0),
-WM8994_CLASS_W_SWITCH("AIF1.1 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const char *sidetone_text[] = {
- "ADC/DMIC1", "DMIC2",
-};
-
-static const struct soc_enum sidetone1_enum =
- SOC_ENUM_SINGLE(WM8994_SIDETONE, 0, 2, sidetone_text);
-
-static const struct snd_kcontrol_new sidetone1_mux =
- SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum);
-
-static const struct soc_enum sidetone2_enum =
- SOC_ENUM_SINGLE(WM8994_SIDETONE, 1, 2, sidetone_text);
-
-static const struct snd_kcontrol_new sidetone2_mux =
- SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum);
-
-static const char *aif1dac_text[] = {
- "AIF1DACDAT", "AIF3DACDAT",
-};
-
-static const struct soc_enum aif1dac_enum =
- SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 0, 2, aif1dac_text);
-
-static const struct snd_kcontrol_new aif1dac_mux =
- SOC_DAPM_ENUM("AIF1DAC Mux", aif1dac_enum);
-
-static const char *aif2dac_text[] = {
- "AIF2DACDAT", "AIF3DACDAT",
-};
-
-static const struct soc_enum aif2dac_enum =
- SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 1, 2, aif2dac_text);
-
-static const struct snd_kcontrol_new aif2dac_mux =
- SOC_DAPM_ENUM("AIF2DAC Mux", aif2dac_enum);
-
-static const char *aif2adc_text[] = {
- "AIF2ADCDAT", "AIF3DACDAT",
-};
-
-static const struct soc_enum aif2adc_enum =
- SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 2, 2, aif2adc_text);
-
-static const struct snd_kcontrol_new aif2adc_mux =
- SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum);
-
-static const char *aif3adc_text[] = {
- "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", "Mono PCM",
-};
-
-static const struct soc_enum wm8994_aif3adc_enum =
- SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text);
-
-static const struct snd_kcontrol_new wm8994_aif3adc_mux =
- SOC_DAPM_ENUM("AIF3ADC Mux", wm8994_aif3adc_enum);
-
-static const struct soc_enum wm8958_aif3adc_enum =
- SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 4, aif3adc_text);
-
-static const struct snd_kcontrol_new wm8958_aif3adc_mux =
- SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum);
-
-static const char *mono_pcm_out_text[] = {
- "None", "AIF2ADCL", "AIF2ADCR",
-};
-
-static const struct soc_enum mono_pcm_out_enum =
- SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 9, 3, mono_pcm_out_text);
-
-static const struct snd_kcontrol_new mono_pcm_out_mux =
- SOC_DAPM_ENUM("Mono PCM Out Mux", mono_pcm_out_enum);
-
-static const char *aif2dac_src_text[] = {
- "AIF2", "AIF3",
-};
-
-/* Note that these two control shouldn't be simultaneously switched to AIF3 */
-static const struct soc_enum aif2dacl_src_enum =
- SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 7, 2, aif2dac_src_text);
-
-static const struct snd_kcontrol_new aif2dacl_src_mux =
- SOC_DAPM_ENUM("AIF2DACL Mux", aif2dacl_src_enum);
-
-static const struct soc_enum aif2dacr_src_enum =
- SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 8, 2, aif2dac_src_text);
-
-static const struct snd_kcontrol_new aif2dacr_src_mux =
- SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum);
-
-static const struct snd_soc_dapm_widget wm8994_lateclk_revd_widgets[] = {
-SND_SOC_DAPM_SUPPLY("AIF1CLK", SND_SOC_NOPM, 0, 0, aif1clk_late_ev,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-SND_SOC_DAPM_SUPPLY("AIF2CLK", SND_SOC_NOPM, 0, 0, aif2clk_late_ev,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
-SND_SOC_DAPM_PGA_E("Late DAC1L Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
- late_enable_ev, SND_SOC_DAPM_PRE_PMU),
-SND_SOC_DAPM_PGA_E("Late DAC1R Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
- late_enable_ev, SND_SOC_DAPM_PRE_PMU),
-SND_SOC_DAPM_PGA_E("Late DAC2L Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
- late_enable_ev, SND_SOC_DAPM_PRE_PMU),
-SND_SOC_DAPM_PGA_E("Late DAC2R Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
- late_enable_ev, SND_SOC_DAPM_PRE_PMU),
-SND_SOC_DAPM_PGA_E("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0,
- late_enable_ev, SND_SOC_DAPM_PRE_PMU),
-
-SND_SOC_DAPM_MIXER_E("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
- left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer),
- late_enable_ev, SND_SOC_DAPM_PRE_PMU),
-SND_SOC_DAPM_MIXER_E("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
- right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer),
- late_enable_ev, SND_SOC_DAPM_PRE_PMU),
-SND_SOC_DAPM_MUX_E("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux,
- late_enable_ev, SND_SOC_DAPM_PRE_PMU),
-SND_SOC_DAPM_MUX_E("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux,
- late_enable_ev, SND_SOC_DAPM_PRE_PMU),
-
-SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev)
-};
-
-static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = {
-SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, aif1clk_ev,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_PRE_PMD),
-SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, aif2clk_ev,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_PRE_PMD),
-SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
- left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
-SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
- right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
-SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
-SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
-};
-
-static const struct snd_soc_dapm_widget wm8994_dac_revd_widgets[] = {
-SND_SOC_DAPM_DAC_E("DAC2L", NULL, SND_SOC_NOPM, 3, 0,
- dac_ev, SND_SOC_DAPM_PRE_PMU),
-SND_SOC_DAPM_DAC_E("DAC2R", NULL, SND_SOC_NOPM, 2, 0,
- dac_ev, SND_SOC_DAPM_PRE_PMU),
-SND_SOC_DAPM_DAC_E("DAC1L", NULL, SND_SOC_NOPM, 1, 0,
- dac_ev, SND_SOC_DAPM_PRE_PMU),
-SND_SOC_DAPM_DAC_E("DAC1R", NULL, SND_SOC_NOPM, 0, 0,
- dac_ev, SND_SOC_DAPM_PRE_PMU),
-};
-
-static const struct snd_soc_dapm_widget wm8994_dac_widgets[] = {
-SND_SOC_DAPM_DAC("DAC2L", NULL, WM8994_POWER_MANAGEMENT_5, 3, 0),
-SND_SOC_DAPM_DAC("DAC2R", NULL, WM8994_POWER_MANAGEMENT_5, 2, 0),
-SND_SOC_DAPM_DAC("DAC1L", NULL, WM8994_POWER_MANAGEMENT_5, 1, 0),
-SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0),
-};
-
-static const struct snd_soc_dapm_widget wm8994_adc_revd_widgets[] = {
-SND_SOC_DAPM_VIRT_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux,
- adc_mux_ev, SND_SOC_DAPM_PRE_PMU),
-SND_SOC_DAPM_VIRT_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux,
- adc_mux_ev, SND_SOC_DAPM_PRE_PMU),
-};
-
-static const struct snd_soc_dapm_widget wm8994_adc_widgets[] = {
-SND_SOC_DAPM_VIRT_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux),
-SND_SOC_DAPM_VIRT_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux),
-};
-
-static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = {
-SND_SOC_DAPM_INPUT("DMIC1DAT"),
-SND_SOC_DAPM_INPUT("DMIC2DAT"),
-SND_SOC_DAPM_INPUT("Clock"),
-
-SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev,
- SND_SOC_DAPM_PRE_PMU),
-SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, vmid_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
-SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-
-SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM, 3, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("DSP2CLK", SND_SOC_NOPM, 2, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("DSPINTCLK", SND_SOC_NOPM, 1, 0, NULL, 0),
-
-SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", NULL,
- 0, SND_SOC_NOPM, 9, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", NULL,
- 0, SND_SOC_NOPM, 8, 0),
-SND_SOC_DAPM_AIF_IN_E("AIF1DAC1L", NULL, 0,
- SND_SOC_NOPM, 9, 0, wm8958_aif_ev,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-SND_SOC_DAPM_AIF_IN_E("AIF1DAC1R", NULL, 0,
- SND_SOC_NOPM, 8, 0, wm8958_aif_ev,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
-SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", NULL,
- 0, SND_SOC_NOPM, 11, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", NULL,
- 0, SND_SOC_NOPM, 10, 0),
-SND_SOC_DAPM_AIF_IN_E("AIF1DAC2L", NULL, 0,
- SND_SOC_NOPM, 11, 0, wm8958_aif_ev,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-SND_SOC_DAPM_AIF_IN_E("AIF1DAC2R", NULL, 0,
- SND_SOC_NOPM, 10, 0, wm8958_aif_ev,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
-SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0,
- aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)),
-SND_SOC_DAPM_MIXER("AIF1ADC1R Mixer", SND_SOC_NOPM, 0, 0,
- aif1adc1r_mix, ARRAY_SIZE(aif1adc1r_mix)),
-
-SND_SOC_DAPM_MIXER("AIF1ADC2L Mixer", SND_SOC_NOPM, 0, 0,
- aif1adc2l_mix, ARRAY_SIZE(aif1adc2l_mix)),
-SND_SOC_DAPM_MIXER("AIF1ADC2R Mixer", SND_SOC_NOPM, 0, 0,
- aif1adc2r_mix, ARRAY_SIZE(aif1adc2r_mix)),
-
-SND_SOC_DAPM_MIXER("AIF2DAC2L Mixer", SND_SOC_NOPM, 0, 0,
- aif2dac2l_mix, ARRAY_SIZE(aif2dac2l_mix)),
-SND_SOC_DAPM_MIXER("AIF2DAC2R Mixer", SND_SOC_NOPM, 0, 0,
- aif2dac2r_mix, ARRAY_SIZE(aif2dac2r_mix)),
-
-SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &sidetone1_mux),
-SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &sidetone2_mux),
-
-SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0,
- dac1l_mix, ARRAY_SIZE(dac1l_mix)),
-SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0,
- dac1r_mix, ARRAY_SIZE(dac1r_mix)),
-
-SND_SOC_DAPM_AIF_OUT("AIF2ADCL", NULL, 0,
- SND_SOC_NOPM, 13, 0),
-SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0,
- SND_SOC_NOPM, 12, 0),
-SND_SOC_DAPM_AIF_IN_E("AIF2DACL", NULL, 0,
- SND_SOC_NOPM, 13, 0, wm8958_aif_ev,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0,
- SND_SOC_NOPM, 12, 0, wm8958_aif_ev,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-
-SND_SOC_DAPM_AIF_IN("AIF1DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_AIF_IN("AIF2DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
-
-SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux),
-SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux),
-SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux),
-
-SND_SOC_DAPM_AIF_IN("AIF3DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_AIF_OUT("AIF3ADCDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
-
-SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0),
-
-SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8994_POWER_MANAGEMENT_4, 5, 0),
-SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8994_POWER_MANAGEMENT_4, 4, 0),
-SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8994_POWER_MANAGEMENT_4, 3, 0),
-SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8994_POWER_MANAGEMENT_4, 2, 0),
-
-/* Power is done with the muxes since the ADC power also controls the
- * downsampling chain, the chip will automatically manage the analogue
- * specific portions.
- */
-SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0),
-SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0),
-
-SND_SOC_DAPM_POST("Debug log", post_ev),
-};
-
-static const struct snd_soc_dapm_widget wm8994_specific_dapm_widgets[] = {
-SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &wm8994_aif3adc_mux),
-};
-
-static const struct snd_soc_dapm_widget wm8958_dapm_widgets[] = {
-SND_SOC_DAPM_MUX("Mono PCM Out Mux", SND_SOC_NOPM, 0, 0, &mono_pcm_out_mux),
-SND_SOC_DAPM_MUX("AIF2DACL Mux", SND_SOC_NOPM, 0, 0, &aif2dacl_src_mux),
-SND_SOC_DAPM_MUX("AIF2DACR Mux", SND_SOC_NOPM, 0, 0, &aif2dacr_src_mux),
-SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &wm8958_aif3adc_mux),
-};
-
-static const struct snd_soc_dapm_route intercon[] = {
- { "CLK_SYS", NULL, "AIF1CLK", check_clk_sys },
- { "CLK_SYS", NULL, "AIF2CLK", check_clk_sys },
-
- { "DSP1CLK", NULL, "CLK_SYS" },
- { "DSP2CLK", NULL, "CLK_SYS" },
- { "DSPINTCLK", NULL, "CLK_SYS" },
-
- { "AIF1ADC1L", NULL, "AIF1CLK" },
- { "AIF1ADC1L", NULL, "DSP1CLK" },
- { "AIF1ADC1R", NULL, "AIF1CLK" },
- { "AIF1ADC1R", NULL, "DSP1CLK" },
- { "AIF1ADC1R", NULL, "DSPINTCLK" },
-
- { "AIF1DAC1L", NULL, "AIF1CLK" },
- { "AIF1DAC1L", NULL, "DSP1CLK" },
- { "AIF1DAC1R", NULL, "AIF1CLK" },
- { "AIF1DAC1R", NULL, "DSP1CLK" },
- { "AIF1DAC1R", NULL, "DSPINTCLK" },
-
- { "AIF1ADC2L", NULL, "AIF1CLK" },
- { "AIF1ADC2L", NULL, "DSP1CLK" },
- { "AIF1ADC2R", NULL, "AIF1CLK" },
- { "AIF1ADC2R", NULL, "DSP1CLK" },
- { "AIF1ADC2R", NULL, "DSPINTCLK" },
-
- { "AIF1DAC2L", NULL, "AIF1CLK" },
- { "AIF1DAC2L", NULL, "DSP1CLK" },
- { "AIF1DAC2R", NULL, "AIF1CLK" },
- { "AIF1DAC2R", NULL, "DSP1CLK" },
- { "AIF1DAC2R", NULL, "DSPINTCLK" },
-
- { "AIF2ADCL", NULL, "AIF2CLK" },
- { "AIF2ADCL", NULL, "DSP2CLK" },
- { "AIF2ADCR", NULL, "AIF2CLK" },
- { "AIF2ADCR", NULL, "DSP2CLK" },
- { "AIF2ADCR", NULL, "DSPINTCLK" },
-
- { "AIF2DACL", NULL, "AIF2CLK" },
- { "AIF2DACL", NULL, "DSP2CLK" },
- { "AIF2DACR", NULL, "AIF2CLK" },
- { "AIF2DACR", NULL, "DSP2CLK" },
- { "AIF2DACR", NULL, "DSPINTCLK" },
-
- { "DMIC1L", NULL, "DMIC1DAT" },
- { "DMIC1L", NULL, "CLK_SYS" },
- { "DMIC1R", NULL, "DMIC1DAT" },
- { "DMIC1R", NULL, "CLK_SYS" },
- { "DMIC2L", NULL, "DMIC2DAT" },
- { "DMIC2L", NULL, "CLK_SYS" },
- { "DMIC2R", NULL, "DMIC2DAT" },
- { "DMIC2R", NULL, "CLK_SYS" },
-
- { "ADCL", NULL, "AIF1CLK" },
- { "ADCL", NULL, "DSP1CLK" },
- { "ADCL", NULL, "DSPINTCLK" },
-
- { "ADCR", NULL, "AIF1CLK" },
- { "ADCR", NULL, "DSP1CLK" },
- { "ADCR", NULL, "DSPINTCLK" },
-
- { "ADCL Mux", "ADC", "ADCL" },
- { "ADCL Mux", "DMIC", "DMIC1L" },
- { "ADCR Mux", "ADC", "ADCR" },
- { "ADCR Mux", "DMIC", "DMIC1R" },
-
- { "DAC1L", NULL, "AIF1CLK" },
- { "DAC1L", NULL, "DSP1CLK" },
- { "DAC1L", NULL, "DSPINTCLK" },
-
- { "DAC1R", NULL, "AIF1CLK" },
- { "DAC1R", NULL, "DSP1CLK" },
- { "DAC1R", NULL, "DSPINTCLK" },
-
- { "DAC2L", NULL, "AIF2CLK" },
- { "DAC2L", NULL, "DSP2CLK" },
- { "DAC2L", NULL, "DSPINTCLK" },
-
- { "DAC2R", NULL, "AIF2DACR" },
- { "DAC2R", NULL, "AIF2CLK" },
- { "DAC2R", NULL, "DSP2CLK" },
- { "DAC2R", NULL, "DSPINTCLK" },
-
- { "TOCLK", NULL, "CLK_SYS" },
-
- { "AIF1DACDAT", NULL, "AIF1 Playback" },
- { "AIF2DACDAT", NULL, "AIF2 Playback" },
- { "AIF3DACDAT", NULL, "AIF3 Playback" },
-
- { "AIF1 Capture", NULL, "AIF1ADCDAT" },
- { "AIF2 Capture", NULL, "AIF2ADCDAT" },
- { "AIF3 Capture", NULL, "AIF3ADCDAT" },
-
- /* AIF1 outputs */
- { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" },
- { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" },
- { "AIF1ADC1L Mixer", "AIF2 Switch", "AIF2DACL" },
-
- { "AIF1ADC1R", NULL, "AIF1ADC1R Mixer" },
- { "AIF1ADC1R Mixer", "ADC/DMIC Switch", "ADCR Mux" },
- { "AIF1ADC1R Mixer", "AIF2 Switch", "AIF2DACR" },
-
- { "AIF1ADC2L", NULL, "AIF1ADC2L Mixer" },
- { "AIF1ADC2L Mixer", "DMIC Switch", "DMIC2L" },
- { "AIF1ADC2L Mixer", "AIF2 Switch", "AIF2DACL" },
-
- { "AIF1ADC2R", NULL, "AIF1ADC2R Mixer" },
- { "AIF1ADC2R Mixer", "DMIC Switch", "DMIC2R" },
- { "AIF1ADC2R Mixer", "AIF2 Switch", "AIF2DACR" },
-
- /* Pin level routing for AIF3 */
- { "AIF1DAC1L", NULL, "AIF1DAC Mux" },
- { "AIF1DAC1R", NULL, "AIF1DAC Mux" },
- { "AIF1DAC2L", NULL, "AIF1DAC Mux" },
- { "AIF1DAC2R", NULL, "AIF1DAC Mux" },
-
- { "AIF1DAC Mux", "AIF1DACDAT", "AIF1DACDAT" },
- { "AIF1DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
- { "AIF2DAC Mux", "AIF2DACDAT", "AIF2DACDAT" },
- { "AIF2DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
- { "AIF2ADC Mux", "AIF2ADCDAT", "AIF2ADCL" },
- { "AIF2ADC Mux", "AIF2ADCDAT", "AIF2ADCR" },
- { "AIF2ADC Mux", "AIF3DACDAT", "AIF3ADCDAT" },
-
- { "AIF3ADC Mux", "AIF1ADCDAT", "AIF1ADCDAT" },
- { "AIF3ADC Mux", "AIF2ADCDAT", "AIF2ADCDAT" },
- { "AIF3ADC Mux", "AIF2DACDAT", "AIF2ADCDAT" },
-
- /* DAC1 inputs */
- { "DAC1L Mixer", "AIF2 Switch", "AIF2DACL" },
- { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
- { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
- { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
- { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
-
- { "DAC1R Mixer", "AIF2 Switch", "AIF2DACR" },
- { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
- { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
- { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" },
- { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" },
-
- /* DAC2/AIF2 outputs */
- { "AIF2ADCL", NULL, "AIF2DAC2L Mixer" },
- { "AIF2DAC2L Mixer", "AIF2 Switch", "AIF2DACL" },
- { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
- { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
- { "AIF2DAC2L Mixer", "Left Sidetone Switch", "Left Sidetone" },
- { "AIF2DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" },
-
- { "AIF2ADCR", NULL, "AIF2DAC2R Mixer" },
- { "AIF2DAC2R Mixer", "AIF2 Switch", "AIF2DACR" },
- { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
- { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
- { "AIF2DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" },
- { "AIF2DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" },
-
- { "AIF1ADCDAT", NULL, "AIF1ADC1L" },
- { "AIF1ADCDAT", NULL, "AIF1ADC1R" },
- { "AIF1ADCDAT", NULL, "AIF1ADC2L" },
- { "AIF1ADCDAT", NULL, "AIF1ADC2R" },
-
- { "AIF2ADCDAT", NULL, "AIF2ADC Mux" },
-
- /* AIF3 output */
- { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC1L" },
- { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC1R" },
- { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC2L" },
- { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC2R" },
- { "AIF3ADCDAT", "AIF2ADCDAT", "AIF2ADCL" },
- { "AIF3ADCDAT", "AIF2ADCDAT", "AIF2ADCR" },
- { "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACL" },
- { "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACR" },
-
- /* Sidetone */
- { "Left Sidetone", "ADC/DMIC1", "ADCL Mux" },
- { "Left Sidetone", "DMIC2", "DMIC2L" },
- { "Right Sidetone", "ADC/DMIC1", "ADCR Mux" },
- { "Right Sidetone", "DMIC2", "DMIC2R" },
-
- /* Output stages */
- { "Left Output Mixer", "DAC Switch", "DAC1L" },
- { "Right Output Mixer", "DAC Switch", "DAC1R" },
-
- { "SPKL", "DAC1 Switch", "DAC1L" },
- { "SPKL", "DAC2 Switch", "DAC2L" },
-
- { "SPKR", "DAC1 Switch", "DAC1R" },
- { "SPKR", "DAC2 Switch", "DAC2R" },
-
- { "Left Headphone Mux", "DAC", "DAC1L" },
- { "Right Headphone Mux", "DAC", "DAC1R" },
-};
-
-static const struct snd_soc_dapm_route wm8994_lateclk_revd_intercon[] = {
- { "DAC1L", NULL, "Late DAC1L Enable PGA" },
- { "Late DAC1L Enable PGA", NULL, "DAC1L Mixer" },
- { "DAC1R", NULL, "Late DAC1R Enable PGA" },
- { "Late DAC1R Enable PGA", NULL, "DAC1R Mixer" },
- { "DAC2L", NULL, "Late DAC2L Enable PGA" },
- { "Late DAC2L Enable PGA", NULL, "AIF2DAC2L Mixer" },
- { "DAC2R", NULL, "Late DAC2R Enable PGA" },
- { "Late DAC2R Enable PGA", NULL, "AIF2DAC2R Mixer" }
-};
-
-static const struct snd_soc_dapm_route wm8994_lateclk_intercon[] = {
- { "DAC1L", NULL, "DAC1L Mixer" },
- { "DAC1R", NULL, "DAC1R Mixer" },
- { "DAC2L", NULL, "AIF2DAC2L Mixer" },
- { "DAC2R", NULL, "AIF2DAC2R Mixer" },
-};
-
-static const struct snd_soc_dapm_route wm8994_revd_intercon[] = {
- { "AIF1DACDAT", NULL, "AIF2DACDAT" },
- { "AIF2DACDAT", NULL, "AIF1DACDAT" },
- { "AIF1ADCDAT", NULL, "AIF2ADCDAT" },
- { "AIF2ADCDAT", NULL, "AIF1ADCDAT" },
- { "MICBIAS1", NULL, "CLK_SYS" },
- { "MICBIAS1", NULL, "MICBIAS Supply" },
- { "MICBIAS2", NULL, "CLK_SYS" },
- { "MICBIAS2", NULL, "MICBIAS Supply" },
-};
-
-static const struct snd_soc_dapm_route wm8994_intercon[] = {
- { "AIF2DACL", NULL, "AIF2DAC Mux" },
- { "AIF2DACR", NULL, "AIF2DAC Mux" },
- { "MICBIAS1", NULL, "VMID" },
- { "MICBIAS2", NULL, "VMID" },
-};
-
-static const struct snd_soc_dapm_route wm8958_intercon[] = {
- { "AIF2DACL", NULL, "AIF2DACL Mux" },
- { "AIF2DACR", NULL, "AIF2DACR Mux" },
-
- { "AIF2DACL Mux", "AIF2", "AIF2DAC Mux" },
- { "AIF2DACL Mux", "AIF3", "AIF3DACDAT" },
- { "AIF2DACR Mux", "AIF2", "AIF2DAC Mux" },
- { "AIF2DACR Mux", "AIF3", "AIF3DACDAT" },
-
- { "Mono PCM Out Mux", "AIF2ADCL", "AIF2ADCL" },
- { "Mono PCM Out Mux", "AIF2ADCR", "AIF2ADCR" },
-
- { "AIF3ADC Mux", "Mono PCM", "Mono PCM Out Mux" },
-};
-
-/* The size in bits of the FLL divide multiplied by 10
- * to allow rounding later */
-#define FIXED_FLL_SIZE ((1 << 16) * 10)
-
-struct fll_div {
- u16 outdiv;
- u16 n;
- u16 k;
- u16 clk_ref_div;
- u16 fll_fratio;
-};
-
-static int wm8994_get_fll_config(struct fll_div *fll,
- int freq_in, int freq_out)
-{
- u64 Kpart;
- unsigned int K, Ndiv, Nmod;
-
- pr_debug("FLL input=%dHz, output=%dHz\n", freq_in, freq_out);
-
- /* Scale the input frequency down to <= 13.5MHz */
- fll->clk_ref_div = 0;
- while (freq_in > 13500000) {
- fll->clk_ref_div++;
- freq_in /= 2;
-
- if (fll->clk_ref_div > 3)
- return -EINVAL;
- }
- pr_debug("CLK_REF_DIV=%d, Fref=%dHz\n", fll->clk_ref_div, freq_in);
-
- /* Scale the output to give 90MHz<=Fvco<=100MHz */
- fll->outdiv = 3;
- while (freq_out * (fll->outdiv + 1) < 90000000) {
- fll->outdiv++;
- if (fll->outdiv > 63)
- return -EINVAL;
- }
- freq_out *= fll->outdiv + 1;
- pr_debug("OUTDIV=%d, Fvco=%dHz\n", fll->outdiv, freq_out);
-
- if (freq_in > 1000000) {
- fll->fll_fratio = 0;
- } else if (freq_in > 256000) {
- fll->fll_fratio = 1;
- freq_in *= 2;
- } else if (freq_in > 128000) {
- fll->fll_fratio = 2;
- freq_in *= 4;
- } else if (freq_in > 64000) {
- fll->fll_fratio = 3;
- freq_in *= 8;
- } else {
- fll->fll_fratio = 4;
- freq_in *= 16;
- }
- pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in);
-
- /* Now, calculate N.K */
- Ndiv = freq_out / freq_in;
-
- fll->n = Ndiv;
- Nmod = freq_out % freq_in;
- pr_debug("Nmod=%d\n", Nmod);
-
- /* Calculate fractional part - scale up so we can round. */
- Kpart = FIXED_FLL_SIZE * (long long)Nmod;
-
- do_div(Kpart, freq_in);
-
- K = Kpart & 0xFFFFFFFF;
-
- if ((K % 10) >= 5)
- K += 5;
-
- /* Move down to proper range now rounding is done */
- fll->k = K / 10;
-
- pr_debug("N=%x K=%x\n", fll->n, fll->k);
-
- return 0;
-}
-
-static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
- unsigned int freq_in, unsigned int freq_out)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994 *control = wm8994->wm8994;
- int reg_offset, ret;
- struct fll_div fll;
- u16 reg, aif1, aif2;
- unsigned long timeout;
- bool was_enabled;
-
- aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
- & WM8994_AIF1CLK_ENA;
-
- aif2 = snd_soc_read(codec, WM8994_AIF2_CLOCKING_1)
- & WM8994_AIF2CLK_ENA;
-
- switch (id) {
- case WM8994_FLL1:
- reg_offset = 0;
- id = 0;
- break;
- case WM8994_FLL2:
- reg_offset = 0x20;
- id = 1;
- break;
- default:
- return -EINVAL;
- }
-
- reg = snd_soc_read(codec, WM8994_FLL1_CONTROL_1 + reg_offset);
- was_enabled = reg & WM8994_FLL1_ENA;
-
- switch (src) {
- case 0:
- /* Allow no source specification when stopping */
- if (freq_out)
- return -EINVAL;
- src = wm8994->fll[id].src;
- break;
- case WM8994_FLL_SRC_MCLK1:
- case WM8994_FLL_SRC_MCLK2:
- case WM8994_FLL_SRC_LRCLK:
- case WM8994_FLL_SRC_BCLK:
- break;
- default:
- return -EINVAL;
- }
-
- /* Are we changing anything? */
- if (wm8994->fll[id].src == src &&
- wm8994->fll[id].in == freq_in && wm8994->fll[id].out == freq_out)
- return 0;
-
- /* If we're stopping the FLL redo the old config - no
- * registers will actually be written but we avoid GCC flow
- * analysis bugs spewing warnings.
- */
- if (freq_out)
- ret = wm8994_get_fll_config(&fll, freq_in, freq_out);
- else
- ret = wm8994_get_fll_config(&fll, wm8994->fll[id].in,
- wm8994->fll[id].out);
- if (ret < 0)
- return ret;
-
- /* Gate the AIF clocks while we reclock */
- snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
- WM8994_AIF1CLK_ENA, 0);
- snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
- WM8994_AIF2CLK_ENA, 0);
-
- /* We always need to disable the FLL while reconfiguring */
- snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
- WM8994_FLL1_ENA, 0);
-
- reg = (fll.outdiv << WM8994_FLL1_OUTDIV_SHIFT) |
- (fll.fll_fratio << WM8994_FLL1_FRATIO_SHIFT);
- snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_2 + reg_offset,
- WM8994_FLL1_OUTDIV_MASK |
- WM8994_FLL1_FRATIO_MASK, reg);
-
- snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_3 + reg_offset,
- WM8994_FLL1_K_MASK, fll.k);
-
- snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset,
- WM8994_FLL1_N_MASK,
- fll.n << WM8994_FLL1_N_SHIFT);
-
- snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset,
- WM8994_FLL1_REFCLK_DIV_MASK |
- WM8994_FLL1_REFCLK_SRC_MASK,
- (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) |
- (src - 1));
-
- /* Clear any pending completion from a previous failure */
- try_wait_for_completion(&wm8994->fll_locked[id]);
-
- /* Enable (with fractional mode if required) */
- if (freq_out) {
- /* Enable VMID if we need it */
- if (!was_enabled) {
- active_reference(codec);
-
- switch (control->type) {
- case WM8994:
- vmid_reference(codec);
- break;
- case WM8958:
- if (wm8994->revision < 1)
- vmid_reference(codec);
- break;
- default:
- break;
- }
- }
-
- if (fll.k)
- reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC;
- else
- reg = WM8994_FLL1_ENA;
- snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
- WM8994_FLL1_ENA | WM8994_FLL1_FRAC,
- reg);
-
- if (wm8994->fll_locked_irq) {
- timeout = wait_for_completion_timeout(&wm8994->fll_locked[id],
- msecs_to_jiffies(10));
- if (timeout == 0)
- dev_warn(codec->dev,
- "Timed out waiting for FLL lock\n");
- } else {
- msleep(5);
- }
- } else {
- if (was_enabled) {
- switch (control->type) {
- case WM8994:
- vmid_dereference(codec);
- break;
- case WM8958:
- if (wm8994->revision < 1)
- vmid_dereference(codec);
- break;
- default:
- break;
- }
-
- active_dereference(codec);
- }
- }
-
- wm8994->fll[id].in = freq_in;
- wm8994->fll[id].out = freq_out;
- wm8994->fll[id].src = src;
-
- /* Enable any gated AIF clocks */
- snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
- WM8994_AIF1CLK_ENA, aif1);
- snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
- WM8994_AIF2CLK_ENA, aif2);
-
- configure_clock(codec);
-
- return 0;
-}
-
-static irqreturn_t wm8994_fll_locked_irq(int irq, void *data)
-{
- struct completion *completion = data;
-
- complete(completion);
-
- return IRQ_HANDLED;
-}
-
-static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 };
-
-static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
- unsigned int freq_in, unsigned int freq_out)
-{
- return _wm8994_set_fll(dai->codec, id, src, freq_in, freq_out);
-}
-
-static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- int i;
-
- switch (dai->id) {
- case 1:
- case 2:
- break;
-
- default:
- /* AIF3 shares clocking with AIF1/2 */
- return -EINVAL;
- }
-
- switch (clk_id) {
- case WM8994_SYSCLK_MCLK1:
- wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK1;
- wm8994->mclk[0] = freq;
- dev_dbg(dai->dev, "AIF%d using MCLK1 at %uHz\n",
- dai->id, freq);
- break;
-
- case WM8994_SYSCLK_MCLK2:
- /* TODO: Set GPIO AF */
- wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK2;
- wm8994->mclk[1] = freq;
- dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n",
- dai->id, freq);
- break;
-
- case WM8994_SYSCLK_FLL1:
- wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_FLL1;
- dev_dbg(dai->dev, "AIF%d using FLL1\n", dai->id);
- break;
-
- case WM8994_SYSCLK_FLL2:
- wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_FLL2;
- dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id);
- break;
-
- case WM8994_SYSCLK_OPCLK:
- /* Special case - a division (times 10) is given and
- * no effect on main clocking.
- */
- if (freq) {
- for (i = 0; i < ARRAY_SIZE(opclk_divs); i++)
- if (opclk_divs[i] == freq)
- break;
- if (i == ARRAY_SIZE(opclk_divs))
- return -EINVAL;
- snd_soc_update_bits(codec, WM8994_CLOCKING_2,
- WM8994_OPCLK_DIV_MASK, i);
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_2,
- WM8994_OPCLK_ENA, WM8994_OPCLK_ENA);
- } else {
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_2,
- WM8994_OPCLK_ENA, 0);
- }
-
- default:
- return -EINVAL;
- }
-
- configure_clock(codec);
-
- return 0;
-}
-
-static int wm8994_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994 *control = wm8994->wm8994;
-
- wm_hubs_set_bias_level(codec, level);
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- /* MICBIAS into regulating mode */
- switch (control->type) {
- case WM8958:
- case WM1811:
- snd_soc_update_bits(codec, WM8958_MICBIAS1,
- WM8958_MICB1_MODE, 0);
- snd_soc_update_bits(codec, WM8958_MICBIAS2,
- WM8958_MICB2_MODE, 0);
- break;
- default:
- break;
- }
-
- if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY)
- active_reference(codec);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- switch (control->type) {
- case WM8958:
- if (wm8994->revision == 0) {
- /* Optimise performance for rev A */
- snd_soc_update_bits(codec,
- WM8958_CHARGE_PUMP_2,
- WM8958_CP_DISCH,
- WM8958_CP_DISCH);
- }
- break;
-
- default:
- break;
- }
-
- /* Discharge LINEOUT1 & 2 */
- snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
- WM8994_LINEOUT1_DISCH |
- WM8994_LINEOUT2_DISCH,
- WM8994_LINEOUT1_DISCH |
- WM8994_LINEOUT2_DISCH);
- }
-
- if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE)
- active_dereference(codec);
-
- /* MICBIAS into bypass mode on newer devices */
- switch (control->type) {
- case WM8958:
- case WM1811:
- snd_soc_update_bits(codec, WM8958_MICBIAS1,
- WM8958_MICB1_MODE,
- WM8958_MICB1_MODE);
- snd_soc_update_bits(codec, WM8958_MICBIAS2,
- WM8958_MICB2_MODE,
- WM8958_MICB2_MODE);
- break;
- default:
- break;
- }
- break;
-
- case SND_SOC_BIAS_OFF:
- if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY)
- wm8994->cur_fw = NULL;
- break;
- }
-
- codec->dapm.bias_level = level;
-
- return 0;
-}
-
-int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-
- switch (mode) {
- case WM8994_VMID_NORMAL:
- if (wm8994->hubs.lineout1_se) {
- snd_soc_dapm_disable_pin(&codec->dapm,
- "LINEOUT1N Driver");
- snd_soc_dapm_disable_pin(&codec->dapm,
- "LINEOUT1P Driver");
- }
- if (wm8994->hubs.lineout2_se) {
- snd_soc_dapm_disable_pin(&codec->dapm,
- "LINEOUT2N Driver");
- snd_soc_dapm_disable_pin(&codec->dapm,
- "LINEOUT2P Driver");
- }
-
- /* Do the sync with the old mode to allow it to clean up */
- snd_soc_dapm_sync(&codec->dapm);
- wm8994->vmid_mode = mode;
- break;
-
- case WM8994_VMID_FORCE:
- if (wm8994->hubs.lineout1_se) {
- snd_soc_dapm_force_enable_pin(&codec->dapm,
- "LINEOUT1N Driver");
- snd_soc_dapm_force_enable_pin(&codec->dapm,
- "LINEOUT1P Driver");
- }
- if (wm8994->hubs.lineout2_se) {
- snd_soc_dapm_force_enable_pin(&codec->dapm,
- "LINEOUT2N Driver");
- snd_soc_dapm_force_enable_pin(&codec->dapm,
- "LINEOUT2P Driver");
- }
-
- wm8994->vmid_mode = mode;
- snd_soc_dapm_sync(&codec->dapm);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994 *control = wm8994->wm8994;
- int ms_reg;
- int aif1_reg;
- int ms = 0;
- int aif1 = 0;
-
- switch (dai->id) {
- case 1:
- ms_reg = WM8994_AIF1_MASTER_SLAVE;
- aif1_reg = WM8994_AIF1_CONTROL_1;
- break;
- case 2:
- ms_reg = WM8994_AIF2_MASTER_SLAVE;
- aif1_reg = WM8994_AIF2_CONTROL_1;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- ms = WM8994_AIF1_MSTR;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_B:
- aif1 |= WM8994_AIF1_LRCLK_INV;
- case SND_SOC_DAIFMT_DSP_A:
- aif1 |= 0x18;
- break;
- case SND_SOC_DAIFMT_I2S:
- aif1 |= 0x10;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- aif1 |= 0x8;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- case SND_SOC_DAIFMT_DSP_B:
- /* frame inversion not valid for DSP modes */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_NF:
- aif1 |= WM8994_AIF1_BCLK_INV;
- break;
- default:
- return -EINVAL;
- }
- break;
-
- case SND_SOC_DAIFMT_I2S:
- case SND_SOC_DAIFMT_RIGHT_J:
- case SND_SOC_DAIFMT_LEFT_J:
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- aif1 |= WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- aif1 |= WM8994_AIF1_BCLK_INV;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- aif1 |= WM8994_AIF1_LRCLK_INV;
- break;
- default:
- return -EINVAL;
- }
- break;
- default:
- return -EINVAL;
- }
-
- /* The AIF2 format configuration needs to be mirrored to AIF3
- * on WM8958 if it's in use so just do it all the time. */
- switch (control->type) {
- case WM1811:
- case WM8958:
- if (dai->id == 2)
- snd_soc_update_bits(codec, WM8958_AIF3_CONTROL_1,
- WM8994_AIF1_LRCLK_INV |
- WM8958_AIF3_FMT_MASK, aif1);
- break;
-
- default:
- break;
- }
-
- snd_soc_update_bits(codec, aif1_reg,
- WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV |
- WM8994_AIF1_FMT_MASK,
- aif1);
- snd_soc_update_bits(codec, ms_reg, WM8994_AIF1_MSTR,
- ms);
-
- return 0;
-}
-
-static struct {
- int val, rate;
-} srs[] = {
- { 0, 8000 },
- { 1, 11025 },
- { 2, 12000 },
- { 3, 16000 },
- { 4, 22050 },
- { 5, 24000 },
- { 6, 32000 },
- { 7, 44100 },
- { 8, 48000 },
- { 9, 88200 },
- { 10, 96000 },
-};
-
-static int fs_ratios[] = {
- 64, 128, 192, 256, 348, 512, 768, 1024, 1408, 1536
-};
-
-static int bclk_divs[] = {
- 10, 15, 20, 30, 40, 50, 60, 80, 110, 120, 160, 220, 240, 320, 440, 480,
- 640, 880, 960, 1280, 1760, 1920
-};
-
-static int wm8994_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- int aif1_reg;
- int aif2_reg;
- int bclk_reg;
- int lrclk_reg;
- int rate_reg;
- int aif1 = 0;
- int aif2 = 0;
- int bclk = 0;
- int lrclk = 0;
- int rate_val = 0;
- int id = dai->id - 1;
-
- int i, cur_val, best_val, bclk_rate, best;
-
- switch (dai->id) {
- case 1:
- aif1_reg = WM8994_AIF1_CONTROL_1;
- aif2_reg = WM8994_AIF1_CONTROL_2;
- bclk_reg = WM8994_AIF1_BCLK;
- rate_reg = WM8994_AIF1_RATE;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
- wm8994->lrclk_shared[0]) {
- lrclk_reg = WM8994_AIF1DAC_LRCLK;
- } else {
- lrclk_reg = WM8994_AIF1ADC_LRCLK;
- dev_dbg(codec->dev, "AIF1 using split LRCLK\n");
- }
- break;
- case 2:
- aif1_reg = WM8994_AIF2_CONTROL_1;
- aif2_reg = WM8994_AIF2_CONTROL_2;
- bclk_reg = WM8994_AIF2_BCLK;
- rate_reg = WM8994_AIF2_RATE;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
- wm8994->lrclk_shared[1]) {
- lrclk_reg = WM8994_AIF2DAC_LRCLK;
- } else {
- lrclk_reg = WM8994_AIF2ADC_LRCLK;
- dev_dbg(codec->dev, "AIF2 using split LRCLK\n");
- }
- break;
- default:
- return -EINVAL;
- }
-
- bclk_rate = params_rate(params) * 4;
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- bclk_rate *= 16;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- bclk_rate *= 20;
- aif1 |= 0x20;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- bclk_rate *= 24;
- aif1 |= 0x40;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- bclk_rate *= 32;
- aif1 |= 0x60;
- break;
- default:
- return -EINVAL;
- }
-
- /* Try to find an appropriate sample rate; look for an exact match. */
- for (i = 0; i < ARRAY_SIZE(srs); i++)
- if (srs[i].rate == params_rate(params))
- break;
- if (i == ARRAY_SIZE(srs))
- return -EINVAL;
- rate_val |= srs[i].val << WM8994_AIF1_SR_SHIFT;
-
- dev_dbg(dai->dev, "Sample rate is %dHz\n", srs[i].rate);
- dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n",
- dai->id, wm8994->aifclk[id], bclk_rate);
-
- if (params_channels(params) == 1 &&
- (snd_soc_read(codec, aif1_reg) & 0x18) == 0x18)
- aif2 |= WM8994_AIF1_MONO;
-
- if (wm8994->aifclk[id] == 0) {
- dev_err(dai->dev, "AIF%dCLK not configured\n", dai->id);
- return -EINVAL;
- }
-
- /* AIFCLK/fs ratio; look for a close match in either direction */
- best = 0;
- best_val = abs((fs_ratios[0] * params_rate(params))
- - wm8994->aifclk[id]);
- for (i = 1; i < ARRAY_SIZE(fs_ratios); i++) {
- cur_val = abs((fs_ratios[i] * params_rate(params))
- - wm8994->aifclk[id]);
- if (cur_val >= best_val)
- continue;
- best = i;
- best_val = cur_val;
- }
- dev_dbg(dai->dev, "Selected AIF%dCLK/fs = %d\n",
- dai->id, fs_ratios[best]);
- rate_val |= best;
-
- /* We may not get quite the right frequency if using
- * approximate clocks so look for the closest match that is
- * higher than the target (we need to ensure that there enough
- * BCLKs to clock out the samples).
- */
- best = 0;
- for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
- cur_val = (wm8994->aifclk[id] * 10 / bclk_divs[i]) - bclk_rate;
- if (cur_val < 0) /* BCLK table is sorted */
- break;
- best = i;
- }
- bclk_rate = wm8994->aifclk[id] * 10 / bclk_divs[best];
- dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
- bclk_divs[best], bclk_rate);
- bclk |= best << WM8994_AIF1_BCLK_DIV_SHIFT;
-
- lrclk = bclk_rate / params_rate(params);
- if (!lrclk) {
- dev_err(dai->dev, "Unable to generate LRCLK from %dHz BCLK\n",
- bclk_rate);
- return -EINVAL;
- }
- dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
- lrclk, bclk_rate / lrclk);
-
- snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
- //snd_soc_update_bits(codec, aif2_reg, WM8994_AIF1_MONO, aif2);
- snd_soc_update_bits(codec, bclk_reg, WM8994_AIF1_BCLK_DIV_MASK, bclk);
- snd_soc_update_bits(codec, lrclk_reg, WM8994_AIF1DAC_RATE_MASK,
- lrclk);
- snd_soc_update_bits(codec, rate_reg, WM8994_AIF1_SR_MASK |
- WM8994_AIF1CLK_RATE_MASK, rate_val);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- switch (dai->id) {
- case 1:
- wm8994->dac_rates[0] = params_rate(params);
- wm8994_set_retune_mobile(codec, 0);
- wm8994_set_retune_mobile(codec, 1);
- break;
- case 2:
- wm8994->dac_rates[1] = params_rate(params);
- wm8994_set_retune_mobile(codec, 2);
- break;
- }
- }
-
- return 0;
-}
-
-static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994 *control = wm8994->wm8994;
- int aif1_reg;
- int aif1 = 0;
-
- switch (dai->id) {
- case 3:
- switch (control->type) {
- case WM1811:
- case WM8958:
- aif1_reg = WM8958_AIF3_CONTROL_1;
- break;
- default:
- return 0;
- }
- default:
- return 0;
- }
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- aif1 |= 0x20;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- aif1 |= 0x40;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- aif1 |= 0x60;
- break;
- default:
- return -EINVAL;
- }
-
- return snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
-}
-
-static void wm8994_aif_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- int rate_reg = 0;
-
- switch (dai->id) {
- case 1:
- rate_reg = WM8994_AIF1_RATE;
- break;
- case 2:
- rate_reg = WM8994_AIF2_RATE;
- break;
- default:
- break;
- }
-
- /* If the DAI is idle then configure the divider tree for the
- * lowest output rate to save a little power if the clock is
- * still active (eg, because it is system clock).
- */
- if (rate_reg && !dai->playback_active && !dai->capture_active)
- snd_soc_update_bits(codec, rate_reg,
- WM8994_AIF1_SR_MASK |
- WM8994_AIF1CLK_RATE_MASK, 0x9);
-}
-
-static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- int mute_reg;
- int reg;
-
- switch (codec_dai->id) {
- case 1:
- mute_reg = WM8994_AIF1_DAC1_FILTERS_1;
- break;
- case 2:
- mute_reg = WM8994_AIF2_DAC_FILTERS_1;
- break;
- default:
- return -EINVAL;
- }
-
- if (mute)
- reg = WM8994_AIF1DAC1_MUTE;
- else
- reg = 0;
-
- snd_soc_update_bits(codec, mute_reg, WM8994_AIF1DAC1_MUTE, reg);
-
- return 0;
-}
-
-static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- int reg, val, mask;
-
- switch (codec_dai->id) {
- case 1:
- reg = WM8994_AIF1_MASTER_SLAVE;
- mask = WM8994_AIF1_TRI;
- break;
- case 2:
- reg = WM8994_AIF2_MASTER_SLAVE;
- mask = WM8994_AIF2_TRI;
- break;
- case 3:
- reg = WM8994_POWER_MANAGEMENT_6;
- mask = WM8994_AIF3_TRI;
- break;
- default:
- return -EINVAL;
- }
-
- if (tristate)
- val = mask;
- else
- val = 0;
-
- return snd_soc_update_bits(codec, reg, mask, val);
-}
-
-static int wm8994_aif2_probe(struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
-
- /* Disable the pulls on the AIF if we're using it to save power. */
- snd_soc_update_bits(codec, WM8994_GPIO_3,
- WM8994_GPN_PU | WM8994_GPN_PD, 0);
- snd_soc_update_bits(codec, WM8994_GPIO_4,
- WM8994_GPN_PU | WM8994_GPN_PD, 0);
- snd_soc_update_bits(codec, WM8994_GPIO_5,
- WM8994_GPN_PU | WM8994_GPN_PD, 0);
-
- return 0;
-}
-
-#define WM8994_RATES SNDRV_PCM_RATE_8000_96000
-
-#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops wm8994_aif1_dai_ops = {
- .set_sysclk = wm8994_set_dai_sysclk,
- .set_fmt = wm8994_set_dai_fmt,
- .hw_params = wm8994_hw_params,
- .shutdown = wm8994_aif_shutdown,
- .digital_mute = wm8994_aif_mute,
- .set_pll = wm8994_set_fll,
- .set_tristate = wm8994_set_tristate,
-};
-
-static const struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
- .set_sysclk = wm8994_set_dai_sysclk,
- .set_fmt = wm8994_set_dai_fmt,
- .hw_params = wm8994_hw_params,
- .shutdown = wm8994_aif_shutdown,
- .digital_mute = wm8994_aif_mute,
- .set_pll = wm8994_set_fll,
- .set_tristate = wm8994_set_tristate,
-};
-
-static const struct snd_soc_dai_ops wm8994_aif3_dai_ops = {
- .hw_params = wm8994_aif3_hw_params,
- .set_tristate = wm8994_set_tristate,
-};
-
-static struct snd_soc_dai_driver wm8994_dai[] = {
- {
- .name = "wm8994-aif1",
- .id = 1,
- .playback = {
- .stream_name = "AIF1 Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8994_RATES,
- .formats = WM8994_FORMATS,
- .sig_bits = 24,
- },
- .capture = {
- .stream_name = "AIF1 Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8994_RATES,
- .formats = WM8994_FORMATS,
- .sig_bits = 24,
- },
- .ops = &wm8994_aif1_dai_ops,
- },
- {
- .name = "wm8994-aif2",
- .id = 2,
- .playback = {
- .stream_name = "AIF2 Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8994_RATES,
- .formats = WM8994_FORMATS,
- .sig_bits = 24,
- },
- .capture = {
- .stream_name = "AIF2 Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8994_RATES,
- .formats = WM8994_FORMATS,
- .sig_bits = 24,
- },
- .probe = wm8994_aif2_probe,
- .ops = &wm8994_aif2_dai_ops,
- },
- {
- .name = "wm8994-aif3",
- .id = 3,
- .playback = {
- .stream_name = "AIF3 Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8994_RATES,
- .formats = WM8994_FORMATS,
- .sig_bits = 24,
- },
- .capture = {
- .stream_name = "AIF3 Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8994_RATES,
- .formats = WM8994_FORMATS,
- .sig_bits = 24,
- },
- .ops = &wm8994_aif3_dai_ops,
- }
-};
-
-#ifdef CONFIG_PM
-static int wm8994_codec_suspend(struct snd_soc_codec *codec)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994 *control = wm8994->wm8994;
- int i, ret;
-
- switch (control->type) {
- case WM8994:
- snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0);
- if (aif1clk_on){
- snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
- WM8994_AIF1CLK_ENA_MASK, 0);
- //printk("<<<<%s\n", __FUNCTION__);
- } //add 2013-7-11
- break;
- case WM1811:
- snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
- WM1811_JACKDET_MODE_MASK, 0);
- /* Fall through */
- case WM8958:
- snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
- WM8958_MICD_ENA, 0);
- break;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
- memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i],
- sizeof(struct wm8994_fll_config));
- ret = _wm8994_set_fll(codec, i + 1, 0, 0, 0);
- if (ret < 0)
- dev_warn(codec->dev, "Failed to stop FLL%d: %d\n",
- i + 1, ret);
- }
-
- wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int wm8994_codec_resume(struct snd_soc_codec *codec)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994 *control = wm8994->wm8994;
- int i, ret;
- unsigned int val, mask;
-
- if (wm8994->revision < 4) {
- /* force a HW read */
- ret = regmap_read(control->regmap,
- WM8994_POWER_MANAGEMENT_5, &val);
-
- /* modify the cache only */
- codec->cache_only = 1;
- mask = WM8994_DAC1R_ENA | WM8994_DAC1L_ENA |
- WM8994_DAC2R_ENA | WM8994_DAC2L_ENA;
- val &= mask;
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
- mask, val);
- codec->cache_only = 0;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
- if (!wm8994->fll_suspend[i].out)
- continue;
-
- ret = _wm8994_set_fll(codec, i + 1,
- wm8994->fll_suspend[i].src,
- wm8994->fll_suspend[i].in,
- wm8994->fll_suspend[i].out);
- if (ret < 0)
- dev_warn(codec->dev, "Failed to restore FLL%d: %d\n",
- i + 1, ret);
- }
-
- switch (control->type) {
- case WM8994:
- if (wm8994->micdet[0].jack || wm8994->micdet[1].jack)
- snd_soc_update_bits(codec, WM8994_MICBIAS,
- WM8994_MICD_ENA, WM8994_MICD_ENA);
- break;
- case WM1811:
- if (wm8994->jackdet && wm8994->jack_cb) {
- /* Restart from idle */
- snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
- WM1811_JACKDET_MODE_MASK,
- WM1811_JACKDET_MODE_JACK);
- break;
- }
- break;
- case WM8958:
- if (wm8994->jack_cb)
- snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
- WM8958_MICD_ENA, WM8958_MICD_ENA);
- break;
- }
-
- return 0;
-}
-#else
-#define wm8994_codec_suspend NULL
-#define wm8994_codec_resume NULL
-#endif
-
-static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
-{
- struct snd_soc_codec *codec = wm8994->codec;
- struct wm8994_pdata *pdata = wm8994->pdata;
- struct snd_kcontrol_new controls[] = {
- SOC_ENUM_EXT("AIF1.1 EQ Mode",
- wm8994->retune_mobile_enum,
- wm8994_get_retune_mobile_enum,
- wm8994_put_retune_mobile_enum),
- SOC_ENUM_EXT("AIF1.2 EQ Mode",
- wm8994->retune_mobile_enum,
- wm8994_get_retune_mobile_enum,
- wm8994_put_retune_mobile_enum),
- SOC_ENUM_EXT("AIF2 EQ Mode",
- wm8994->retune_mobile_enum,
- wm8994_get_retune_mobile_enum,
- wm8994_put_retune_mobile_enum),
- };
- int ret, i, j;
- const char **t;
-
- /* We need an array of texts for the enum API but the number
- * of texts is likely to be less than the number of
- * configurations due to the sample rate dependency of the
- * configurations. */
- wm8994->num_retune_mobile_texts = 0;
- wm8994->retune_mobile_texts = NULL;
- for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
- for (j = 0; j < wm8994->num_retune_mobile_texts; j++) {
- if (strcmp(pdata->retune_mobile_cfgs[i].name,
- wm8994->retune_mobile_texts[j]) == 0)
- break;
- }
-
- if (j != wm8994->num_retune_mobile_texts)
- continue;
-
- /* Expand the array... */
- t = krealloc(wm8994->retune_mobile_texts,
- sizeof(char *) *
- (wm8994->num_retune_mobile_texts + 1),
- GFP_KERNEL);
- if (t == NULL)
- continue;
-
- /* ...store the new entry... */
- t[wm8994->num_retune_mobile_texts] =
- pdata->retune_mobile_cfgs[i].name;
-
- /* ...and remember the new version. */
- wm8994->num_retune_mobile_texts++;
- wm8994->retune_mobile_texts = t;
- }
-
- dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
- wm8994->num_retune_mobile_texts);
-
- wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts;
- wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts;
-
- ret = snd_soc_add_codec_controls(wm8994->codec, controls,
- ARRAY_SIZE(controls));
- if (ret != 0)
- dev_err(wm8994->codec->dev,
- "Failed to add ReTune Mobile controls: %d\n", ret);
-}
-
-static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
-{
- struct snd_soc_codec *codec = wm8994->codec;
- struct wm8994_pdata *pdata = wm8994->pdata;
- int ret, i;
-
- if (!pdata)
- return;
-
- wm_hubs_handle_analogue_pdata(codec, pdata->lineout1_diff,
- pdata->lineout2_diff,
- pdata->lineout1fb,
- pdata->lineout2fb,
- pdata->jd_scthr,
- pdata->jd_thr,
- pdata->micbias1_lvl,
- pdata->micbias2_lvl);
-
- dev_dbg(codec->dev, "%d DRC configurations\n", pdata->num_drc_cfgs);
-
- if (pdata->num_drc_cfgs) {
- struct snd_kcontrol_new controls[] = {
- SOC_ENUM_EXT("AIF1DRC1 Mode", wm8994->drc_enum,
- wm8994_get_drc_enum, wm8994_put_drc_enum),
- SOC_ENUM_EXT("AIF1DRC2 Mode", wm8994->drc_enum,
- wm8994_get_drc_enum, wm8994_put_drc_enum),
- SOC_ENUM_EXT("AIF2DRC Mode", wm8994->drc_enum,
- wm8994_get_drc_enum, wm8994_put_drc_enum),
- };
-
- /* We need an array of texts for the enum API */
- wm8994->drc_texts = devm_kzalloc(wm8994->codec->dev,
- sizeof(char *) * pdata->num_drc_cfgs, GFP_KERNEL);
- if (!wm8994->drc_texts) {
- dev_err(wm8994->codec->dev,
- "Failed to allocate %d DRC config texts\n",
- pdata->num_drc_cfgs);
- return;
- }
-
- for (i = 0; i < pdata->num_drc_cfgs; i++)
- wm8994->drc_texts[i] = pdata->drc_cfgs[i].name;
-
- wm8994->drc_enum.max = pdata->num_drc_cfgs;
- wm8994->drc_enum.texts = wm8994->drc_texts;
-
- ret = snd_soc_add_codec_controls(wm8994->codec, controls,
- ARRAY_SIZE(controls));
- if (ret != 0)
- dev_err(wm8994->codec->dev,
- "Failed to add DRC mode controls: %d\n", ret);
-
- for (i = 0; i < WM8994_NUM_DRC; i++)
- wm8994_set_drc(codec, i);
- }
-
- dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
- pdata->num_retune_mobile_cfgs);
-
- if (pdata->num_retune_mobile_cfgs)
- wm8994_handle_retune_mobile_pdata(wm8994);
- else
- snd_soc_add_codec_controls(wm8994->codec, wm8994_eq_controls,
- ARRAY_SIZE(wm8994_eq_controls));
-
- for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) {
- if (pdata->micbias[i]) {
- snd_soc_write(codec, WM8958_MICBIAS1 + i,
- pdata->micbias[i] & 0xffff);
- }
- }
-}
-
-/**
- * wm8994_mic_detect - Enable microphone detection via the WM8994 IRQ
- *
- * @codec: WM8994 codec
- * @jack: jack to report detection events on
- * @micbias: microphone bias to detect on
- *
- * Enable microphone detection via IRQ on the WM8994. If GPIOs are
- * being used to bring out signals to the processor then only platform
- * data configuration is needed for WM8994 and processor GPIOs should
- * be configured using snd_soc_jack_add_gpios() instead.
- *
- * Configuration of detection levels is available via the micbias1_lvl
- * and micbias2_lvl platform data members.
- */
-int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
- int micbias)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994_micdet *micdet;
- struct wm8994 *control = wm8994->wm8994;
- int reg, ret;
-
- if (control->type != WM8994) {
- dev_warn(codec->dev, "Not a WM8994\n");
- return -EINVAL;
- }
-
- switch (micbias) {
- case 1:
- micdet = &wm8994->micdet[0];
- if (jack)
- ret = snd_soc_dapm_force_enable_pin(&codec->dapm,
- "MICBIAS1");
- else
- ret = snd_soc_dapm_disable_pin(&codec->dapm,
- "MICBIAS1");
- break;
- case 2:
- micdet = &wm8994->micdet[1];
- if (jack)
- ret = snd_soc_dapm_force_enable_pin(&codec->dapm,
- "MICBIAS1");
- else
- ret = snd_soc_dapm_disable_pin(&codec->dapm,
- "MICBIAS1");
- break;
- default:
- dev_warn(codec->dev, "Invalid MICBIAS %d\n", micbias);
- return -EINVAL;
- }
-
- if (ret != 0)
- dev_warn(codec->dev, "Failed to configure MICBIAS%d: %d\n",
- micbias, ret);
-
- dev_dbg(codec->dev, "Configuring microphone detection on %d %p\n",
- micbias, jack);
-
- /* Store the configuration */
- micdet->jack = jack;
- micdet->detecting = true;
-
- /* If either of the jacks is set up then enable detection */
- if (wm8994->micdet[0].jack || wm8994->micdet[1].jack)
- reg = WM8994_MICD_ENA;
- else
- reg = 0;
-
- snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg);
-
- snd_soc_dapm_sync(&codec->dapm);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(wm8994_mic_detect);
-
-static irqreturn_t wm8994_mic_irq(int irq, void *data)
-{
- struct wm8994_priv *priv = data;
- struct snd_soc_codec *codec = priv->codec;
- int reg;
- int report;
-
-#ifndef CONFIG_SND_SOC_WM8994_MODULE
- trace_snd_soc_jack_irq(dev_name(codec->dev));
-#endif
-
- reg = snd_soc_read(codec, WM8994_INTERRUPT_RAW_STATUS_2);
- if (reg < 0) {
- dev_err(codec->dev, "Failed to read microphone status: %d\n",
- reg);
- return IRQ_HANDLED;
- }
-
- dev_dbg(codec->dev, "Microphone status: %x\n", reg);
-
- report = 0;
- if (reg & WM8994_MIC1_DET_STS) {
- if (priv->micdet[0].detecting)
- report = SND_JACK_HEADSET;
- }
- if (reg & WM8994_MIC1_SHRT_STS) {
- if (priv->micdet[0].detecting)
- report = SND_JACK_HEADPHONE;
- else
- report |= SND_JACK_BTN_0;
- }
- if (report)
- priv->micdet[0].detecting = false;
- else
- priv->micdet[0].detecting = true;
-
- snd_soc_jack_report(priv->micdet[0].jack, report,
- SND_JACK_HEADSET | SND_JACK_BTN_0);
-
- report = 0;
- if (reg & WM8994_MIC2_DET_STS) {
- if (priv->micdet[1].detecting)
- report = SND_JACK_HEADSET;
- }
- if (reg & WM8994_MIC2_SHRT_STS) {
- if (priv->micdet[1].detecting)
- report = SND_JACK_HEADPHONE;
- else
- report |= SND_JACK_BTN_0;
- }
- if (report)
- priv->micdet[1].detecting = false;
- else
- priv->micdet[1].detecting = true;
-
- snd_soc_jack_report(priv->micdet[1].jack, report,
- SND_JACK_HEADSET | SND_JACK_BTN_0);
-
- return IRQ_HANDLED;
-}
-
-/* Default microphone detection handler for WM8958 - the user can
- * override this if they wish.
- */
-static void wm8958_default_micdet(u16 status, void *data)
-{
- struct snd_soc_codec *codec = data;
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- int report;
-
- dev_dbg(codec->dev, "MICDET %x\n", status);
-
- /* Either nothing present or just starting detection */
- if (!(status & WM8958_MICD_STS)) {
- if (!wm8994->jackdet) {
- /* If nothing present then clear our statuses */
- dev_dbg(codec->dev, "Detected open circuit\n");
- wm8994->jack_mic = false;
- wm8994->mic_detecting = true;
-
- wm8958_micd_set_rate(codec);
-
- snd_soc_jack_report(wm8994->micdet[0].jack, 0,
- wm8994->btn_mask |
- SND_JACK_HEADSET);
- }
- return;
- }
-
- /* If the measurement is showing a high impedence we've got a
- * microphone.
- */
- if (wm8994->mic_detecting && (status & 0x600)) {
- dev_dbg(codec->dev, "Detected microphone\n");
-
- wm8994->mic_detecting = false;
- wm8994->jack_mic = true;
-
- wm8958_micd_set_rate(codec);
-
- snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADSET,
- SND_JACK_HEADSET);
- }
-
-
- if (wm8994->mic_detecting && status & 0xfc) {
- dev_dbg(codec->dev, "Detected headphone\n");
- wm8994->mic_detecting = false;
-
- wm8958_micd_set_rate(codec);
-
- snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE,
- SND_JACK_HEADSET);
-
- /* If we have jackdet that will detect removal */
- if (wm8994->jackdet) {
- mutex_lock(&wm8994->accdet_lock);
-
- snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
- WM8958_MICD_ENA, 0);
-
- wm1811_jackdet_set_mode(codec,
- WM1811_JACKDET_MODE_JACK);
-
- mutex_unlock(&wm8994->accdet_lock);
-
- if (wm8994->pdata->jd_ext_cap) {
- mutex_lock(&codec->mutex);
- snd_soc_dapm_disable_pin(&codec->dapm,
- "MICBIAS2");
- snd_soc_dapm_sync(&codec->dapm);
- mutex_unlock(&codec->mutex);
- }
- }
- }
-
- /* Report short circuit as a button */
- if (wm8994->jack_mic) {
- report = 0;
- if (status & 0x4)
- report |= SND_JACK_BTN_0;
-
- if (status & 0x8)
- report |= SND_JACK_BTN_1;
-
- if (status & 0x10)
- report |= SND_JACK_BTN_2;
-
- if (status & 0x20)
- report |= SND_JACK_BTN_3;
-
- if (status & 0x40)
- report |= SND_JACK_BTN_4;
-
- if (status & 0x80)
- report |= SND_JACK_BTN_5;
-
- snd_soc_jack_report(wm8994->micdet[0].jack, report,
- wm8994->btn_mask);
- }
-}
-
-static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
-{
- struct wm8994_priv *wm8994 = data;
- struct snd_soc_codec *codec = wm8994->codec;
- int reg;
- bool present;
-
- mutex_lock(&wm8994->accdet_lock);
-
- reg = snd_soc_read(codec, WM1811_JACKDET_CTRL);
- if (reg < 0) {
- dev_err(codec->dev, "Failed to read jack status: %d\n", reg);
- mutex_unlock(&wm8994->accdet_lock);
- return IRQ_NONE;
- }
-
- dev_dbg(codec->dev, "JACKDET %x\n", reg);
-
- present = reg & WM1811_JACKDET_LVL;
-
- if (present) {
- dev_dbg(codec->dev, "Jack detected\n");
-
- snd_soc_update_bits(codec, WM8958_MICBIAS2,
- WM8958_MICB2_DISCH, 0);
-
- /* Disable debounce while inserted */
- snd_soc_update_bits(codec, WM1811_JACKDET_CTRL,
- WM1811_JACKDET_DB, 0);
-
- /*
- * Start off measument of microphone impedence to find
- * out what's actually there.
- */
- wm8994->mic_detecting = true;
- wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC);
-
- snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
- WM8958_MICD_ENA, WM8958_MICD_ENA);
- } else {
- dev_dbg(codec->dev, "Jack not detected\n");
-
- snd_soc_update_bits(codec, WM8958_MICBIAS2,
- WM8958_MICB2_DISCH, WM8958_MICB2_DISCH);
-
- /* Enable debounce while removed */
- snd_soc_update_bits(codec, WM1811_JACKDET_CTRL,
- WM1811_JACKDET_DB, WM1811_JACKDET_DB);
-
- wm8994->mic_detecting = false;
- wm8994->jack_mic = false;
- snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
- WM8958_MICD_ENA, 0);
- wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_JACK);
- }
-
- mutex_unlock(&wm8994->accdet_lock);
-
- /* If required for an external cap force MICBIAS on */
- if (wm8994->pdata->jd_ext_cap) {
- mutex_lock(&codec->mutex);
-
- if (present)
- snd_soc_dapm_force_enable_pin(&codec->dapm,
- "MICBIAS2");
- else
- snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2");
-
- snd_soc_dapm_sync(&codec->dapm);
- mutex_unlock(&codec->mutex);
- }
-
- if (present)
- snd_soc_jack_report(wm8994->micdet[0].jack,
- SND_JACK_MECHANICAL, SND_JACK_MECHANICAL);
- else
- snd_soc_jack_report(wm8994->micdet[0].jack, 0,
- SND_JACK_MECHANICAL | SND_JACK_HEADSET |
- wm8994->btn_mask);
-
- return IRQ_HANDLED;
-}
-
-/**
- * wm8958_mic_detect - Enable microphone detection via the WM8958 IRQ
- *
- * @codec: WM8958 codec
- * @jack: jack to report detection events on
- *
- * Enable microphone detection functionality for the WM8958. By
- * default simple detection which supports the detection of up to 6
- * buttons plus video and microphone functionality is supported.
- *
- * The WM8958 has an advanced jack detection facility which is able to
- * support complex accessory detection, especially when used in
- * conjunction with external circuitry. In order to provide maximum
- * flexiblity a callback is provided which allows a completely custom
- * detection algorithm.
- */
-int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
- wm8958_micdet_cb cb, void *cb_data)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994 *control = wm8994->wm8994;
- u16 micd_lvl_sel;
-
- switch (control->type) {
- case WM1811:
- case WM8958:
- break;
- default:
- return -EINVAL;
- }
-
- if (jack) {
- if (!cb) {
- dev_dbg(codec->dev, "Using default micdet callback\n");
- cb = wm8958_default_micdet;
- cb_data = codec;
- }
-
- snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS");
- snd_soc_dapm_sync(&codec->dapm);
-
- wm8994->micdet[0].jack = jack;
- wm8994->jack_cb = cb;
- wm8994->jack_cb_data = cb_data;
-
- wm8994->mic_detecting = true;
- wm8994->jack_mic = false;
-
- wm8958_micd_set_rate(codec);
-
- /* Detect microphones and short circuits by default */
- if (wm8994->pdata->micd_lvl_sel)
- micd_lvl_sel = wm8994->pdata->micd_lvl_sel;
- else
- micd_lvl_sel = 0x41;
-
- wm8994->btn_mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 |
- SND_JACK_BTN_2 | SND_JACK_BTN_3 |
- SND_JACK_BTN_4 | SND_JACK_BTN_5;
-
- snd_soc_update_bits(codec, WM8958_MIC_DETECT_2,
- WM8958_MICD_LVL_SEL_MASK, micd_lvl_sel);
-
- WARN_ON(codec->dapm.bias_level > SND_SOC_BIAS_STANDBY);
-
- /*
- * If we can use jack detection start off with that,
- * otherwise jump straight to microphone detection.
- */
- if (wm8994->jackdet) {
- snd_soc_update_bits(codec, WM8958_MICBIAS2,
- WM8958_MICB2_DISCH,
- WM8958_MICB2_DISCH);
- snd_soc_update_bits(codec, WM8994_LDO_1,
- WM8994_LDO1_DISCH, 0);
- wm1811_jackdet_set_mode(codec,
- WM1811_JACKDET_MODE_JACK);
- } else {
- snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
- WM8958_MICD_ENA, WM8958_MICD_ENA);
- }
-
- } else {
- snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
- WM8958_MICD_ENA, 0);
- wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_NONE);
- snd_soc_dapm_disable_pin(&codec->dapm, "CLK_SYS");
- snd_soc_dapm_sync(&codec->dapm);
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(wm8958_mic_detect);
-
-static irqreturn_t wm8958_mic_irq(int irq, void *data)
-{
- struct wm8994_priv *wm8994 = data;
- struct snd_soc_codec *codec = wm8994->codec;
- int reg, count;
-
- /*
- * Jack detection may have detected a removal simulataneously
- * with an update of the MICDET status; if so it will have
- * stopped detection and we can ignore this interrupt.
- */
- if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA))
- return IRQ_HANDLED;
-
- /* We may occasionally read a detection without an impedence
- * range being provided - if that happens loop again.
- */
- count = 10;
- do {
- reg = snd_soc_read(codec, WM8958_MIC_DETECT_3);
- if (reg < 0) {
- dev_err(codec->dev,
- "Failed to read mic detect status: %d\n",
- reg);
- return IRQ_NONE;
- }
-
- if (!(reg & WM8958_MICD_VALID)) {
- dev_dbg(codec->dev, "Mic detect data not valid\n");
- goto out;
- }
-
- if (!(reg & WM8958_MICD_STS) || (reg & WM8958_MICD_LVL_MASK))
- break;
-
- msleep(1);
- } while (count--);
-
- if (count == 0)
- dev_warn(codec->dev, "No impedence range reported for jack\n");
-
-#ifndef CONFIG_SND_SOC_WM8994_MODULE
- trace_snd_soc_jack_irq(dev_name(codec->dev));
-#endif
-
- if (wm8994->jack_cb)
- wm8994->jack_cb(reg, wm8994->jack_cb_data);
- else
- dev_warn(codec->dev, "Accessory detection with no callback\n");
-
-out:
- return IRQ_HANDLED;
-}
-
-static irqreturn_t wm8994_fifo_error(int irq, void *data)
-{
- struct snd_soc_codec *codec = data;
-
- dev_err(codec->dev, "FIFO error\n");
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t wm8994_temp_warn(int irq, void *data)
-{
- struct snd_soc_codec *codec = data;
-
- dev_err(codec->dev, "Thermal warning\n");
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t wm8994_temp_shut(int irq, void *data)
-{
- struct snd_soc_codec *codec = data;
-
- dev_crit(codec->dev, "Thermal shutdown\n");
-
- return IRQ_HANDLED;
-}
-
-static int wm8994_readproc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
-#define WM8994_CACHE_SIZE 1570
-
- int ret;
- unsigned short reg;
- struct wm8994_priv *wm8994 = data;
-
- printk(KERN_INFO "\nwm8994 regs dump:\n");
- printk(KERN_INFO "\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
- for (reg = 0; reg < WM8994_CACHE_SIZE; reg++) {
- ret = wm8994_reg_read(wm8994->wm8994, reg);
- if (ret < 0) {
- printk(KERN_INFO "\nwm8994_reg_read reg[%04x] error\n", reg);
- goto out;
- }
- if (reg%4 == 0) printk("\n");
- printk("reg[%04x]=%04x ", reg, ret);
- }
-
- printk("\n\nGPIO Pin settings:\n");
- for (reg = WM8994_GPIO_1; reg < WM8994_GPIO_1+11; reg++) {
- ret = wm8994_reg_read(wm8994->wm8994, reg);
- if (ret < 0) {
- printk(KERN_INFO "\nwm8994_reg_read reg[%04x] error\n", reg);
- goto out;
- }
- if (reg%4 == 0) printk("\n");
- printk("reg[%04x]=%04x ", reg, ret);
- }
-
-out:
- printk(KERN_INFO "\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");
- return 0;
-}
-
-static int wm8994_codec_probe(struct snd_soc_codec *codec)
-{
- struct wm8994 *control = dev_get_drvdata(codec->dev->parent);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- unsigned int reg;
- int ret, i;
-
- wm8994->codec = codec;
- codec->control_data = control->regmap;
-
- snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
-
- wm8994->codec = codec;
-
- mutex_init(&wm8994->accdet_lock);
-
- for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
- init_completion(&wm8994->fll_locked[i]);
-
- if (wm8994->pdata && wm8994->pdata->micdet_irq)
- wm8994->micdet_irq = wm8994->pdata->micdet_irq;
- else if (wm8994->pdata && wm8994->pdata->irq_base)
- wm8994->micdet_irq = wm8994->pdata->irq_base +
- WM8994_IRQ_MIC1_DET;
-
- pm_runtime_enable(codec->dev);
- pm_runtime_idle(codec->dev);
-
- /* By default use idle_bias_off, will override for WM8994 */
- codec->dapm.idle_bias_off = 1;
-
- /* Set revision-specific configuration */
- wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION);
- switch (control->type) {
- case WM8994:
- /* Single ended line outputs should have VMID on. */
- if (!wm8994->pdata->lineout1_diff ||
- !wm8994->pdata->lineout2_diff)
- codec->dapm.idle_bias_off = 0;
-
- switch (wm8994->revision) {
- case 2:
- case 3:
- wm8994->hubs.dcs_codes_l = -5;
- wm8994->hubs.dcs_codes_r = -5;
- wm8994->hubs.hp_startup_mode = 1;
- wm8994->hubs.dcs_readback_mode = 1;
- wm8994->hubs.series_startup = 1;
- break;
- default:
- wm8994->hubs.dcs_readback_mode = 2;
- break;
- }
- break;
-
- case WM8958:
- wm8994->hubs.dcs_readback_mode = 1;
- wm8994->hubs.hp_startup_mode = 1;
- break;
-
- case WM1811:
- wm8994->hubs.dcs_readback_mode = 2;
- wm8994->hubs.no_series_update = 1;
- wm8994->hubs.hp_startup_mode = 1;
- wm8994->hubs.no_cache_class_w = true;
-
- switch (wm8994->revision) {
- case 0:
- case 1:
- case 2:
- case 3:
- wm8994->hubs.dcs_codes_l = -9;
- wm8994->hubs.dcs_codes_r = -7;
- break;
- default:
- break;
- }
-
- snd_soc_update_bits(codec, WM8994_ANALOGUE_HP_1,
- WM1811_HPOUT1_ATTN, WM1811_HPOUT1_ATTN);
- break;
-
- default:
- break;
- }
-
- wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_FIFOS_ERR,
- wm8994_fifo_error, "FIFO error", codec);
- wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_TEMP_WARN,
- wm8994_temp_warn, "Thermal warning", codec);
- wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT,
- wm8994_temp_shut, "Thermal shutdown", codec);
-
- ret = wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_DCS_DONE,
- wm_hubs_dcs_done, "DC servo done",
- &wm8994->hubs);
- if (ret == 0)
- wm8994->hubs.dcs_done_irq = true;
-
- switch (control->type) {
- case WM8994:
- if (wm8994->micdet_irq) {
- ret = request_threaded_irq(wm8994->micdet_irq, NULL,
- wm8994_mic_irq,
- IRQF_TRIGGER_RISING,
- "Mic1 detect",
- wm8994);
- if (ret != 0)
- dev_warn(codec->dev,
- "Failed to request Mic1 detect IRQ: %d\n",
- ret);
- }
-
- ret = wm8994_request_irq(wm8994->wm8994,
- WM8994_IRQ_MIC1_SHRT,
- wm8994_mic_irq, "Mic 1 short",
- wm8994);
- if (ret != 0)
- dev_warn(codec->dev,
- "Failed to request Mic1 short IRQ: %d\n",
- ret);
-
- ret = wm8994_request_irq(wm8994->wm8994,
- WM8994_IRQ_MIC2_DET,
- wm8994_mic_irq, "Mic 2 detect",
- wm8994);
- if (ret != 0)
- dev_warn(codec->dev,
- "Failed to request Mic2 detect IRQ: %d\n",
- ret);
-
- ret = wm8994_request_irq(wm8994->wm8994,
- WM8994_IRQ_MIC2_SHRT,
- wm8994_mic_irq, "Mic 2 short",
- wm8994);
- if (ret != 0)
- dev_warn(codec->dev,
- "Failed to request Mic2 short IRQ: %d\n",
- ret);
- break;
-
- case WM8958:
- case WM1811:
- if (wm8994->micdet_irq) {
- ret = request_threaded_irq(wm8994->micdet_irq, NULL,
- wm8958_mic_irq,
- IRQF_TRIGGER_RISING,
- "Mic detect",
- wm8994);
- if (ret != 0)
- dev_warn(codec->dev,
- "Failed to request Mic detect IRQ: %d\n",
- ret);
- }
- }
-
- switch (control->type) {
- case WM1811:
- if (wm8994->revision > 1) {
- ret = wm8994_request_irq(wm8994->wm8994,
- WM8994_IRQ_GPIO(6),
- wm1811_jackdet_irq, "JACKDET",
- wm8994);
- if (ret == 0)
- wm8994->jackdet = true;
- }
- break;
- default:
- break;
- }
-
- wm8994->fll_locked_irq = true;
- for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) {
- ret = wm8994_request_irq(wm8994->wm8994,
- WM8994_IRQ_FLL1_LOCK + i,
- wm8994_fll_locked_irq, "FLL lock",
- &wm8994->fll_locked[i]);
- if (ret != 0)
- wm8994->fll_locked_irq = false;
- }
-
- /* Make sure we can read from the GPIOs if they're inputs */
- pm_runtime_get_sync(codec->dev);
-
- /* Remember if AIFnLRCLK is configured as a GPIO. This should be
- * configured on init - if a system wants to do this dynamically
- * at runtime we can deal with that then.
- */
- ret = regmap_read(control->regmap, WM8994_GPIO_1, &reg);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to read GPIO1 state: %d\n", ret);
- goto err_irq;
- }
- if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
- wm8994->lrclk_shared[0] = 1;
- wm8994_dai[0].symmetric_rates = 1;
- } else {
- wm8994->lrclk_shared[0] = 0;
- }
-
- ret = regmap_read(control->regmap, WM8994_GPIO_6, &reg);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to read GPIO6 state: %d\n", ret);
- goto err_irq;
- }
- if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
- wm8994->lrclk_shared[1] = 1;
- wm8994_dai[1].symmetric_rates = 1;
- } else {
- wm8994->lrclk_shared[1] = 0;
- }
-
- pm_runtime_put(codec->dev);
-
- /* Latch volume update bits */
- for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++)
- snd_soc_update_bits(codec, wm8994_vu_bits[i].reg,
- wm8994_vu_bits[i].mask,
- wm8994_vu_bits[i].mask);
-
- /* Set the low bit of the 3D stereo depth so TLV matches */
- snd_soc_update_bits(codec, WM8994_AIF1_DAC1_FILTERS_2,
- 1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT,
- 1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT);
- snd_soc_update_bits(codec, WM8994_AIF1_DAC2_FILTERS_2,
- 1 << WM8994_AIF1DAC2_3D_GAIN_SHIFT,
- 1 << WM8994_AIF1DAC2_3D_GAIN_SHIFT);
- snd_soc_update_bits(codec, WM8994_AIF2_DAC_FILTERS_2,
- 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT,
- 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT);
-
- /* Unconditionally enable AIF1 ADC TDM mode on chips which can
- * use this; it only affects behaviour on idle TDM clock
- * cycles. */
- switch (control->type) {
- case WM8994:
- case WM8958:
- snd_soc_update_bits(codec, WM8994_AIF1_CONTROL_1,
- WM8994_AIF1ADC_TDM, WM8994_AIF1ADC_TDM);
- break;
- default:
- break;
- }
-
- /* Put MICBIAS into bypass mode by default on newer devices */
- switch (control->type) {
- case WM8958:
- case WM1811:
- snd_soc_update_bits(codec, WM8958_MICBIAS1,
- WM8958_MICB1_MODE, WM8958_MICB1_MODE);
- snd_soc_update_bits(codec, WM8958_MICBIAS2,
- WM8958_MICB2_MODE, WM8958_MICB2_MODE);
- break;
- default:
- break;
- }
-
- wm8994_update_class_w(codec);
-
- wm8994_handle_pdata(wm8994);
-
- wm_hubs_add_analogue_controls(codec);
- snd_soc_add_codec_controls(codec, wm8994_snd_controls,
- ARRAY_SIZE(wm8994_snd_controls));
- snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets,
- ARRAY_SIZE(wm8994_dapm_widgets));
-
- switch (control->type) {
- case WM8994:
- snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets,
- ARRAY_SIZE(wm8994_specific_dapm_widgets));
- if (wm8994->revision < 4) {
- snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets,
- ARRAY_SIZE(wm8994_lateclk_revd_widgets));
- snd_soc_dapm_new_controls(dapm, wm8994_adc_revd_widgets,
- ARRAY_SIZE(wm8994_adc_revd_widgets));
- snd_soc_dapm_new_controls(dapm, wm8994_dac_revd_widgets,
- ARRAY_SIZE(wm8994_dac_revd_widgets));
- } else {
- snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets,
- ARRAY_SIZE(wm8994_lateclk_widgets));
- snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets,
- ARRAY_SIZE(wm8994_adc_widgets));
- snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets,
- ARRAY_SIZE(wm8994_dac_widgets));
- }
- break;
- case WM8958:
- snd_soc_add_codec_controls(codec, wm8958_snd_controls,
- ARRAY_SIZE(wm8958_snd_controls));
- snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
- ARRAY_SIZE(wm8958_dapm_widgets));
- if (wm8994->revision < 1) {
- snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets,
- ARRAY_SIZE(wm8994_lateclk_revd_widgets));
- snd_soc_dapm_new_controls(dapm, wm8994_adc_revd_widgets,
- ARRAY_SIZE(wm8994_adc_revd_widgets));
- snd_soc_dapm_new_controls(dapm, wm8994_dac_revd_widgets,
- ARRAY_SIZE(wm8994_dac_revd_widgets));
- } else {
- snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets,
- ARRAY_SIZE(wm8994_lateclk_widgets));
- snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets,
- ARRAY_SIZE(wm8994_adc_widgets));
- snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets,
- ARRAY_SIZE(wm8994_dac_widgets));
- }
- break;
-
- case WM1811:
- snd_soc_add_codec_controls(codec, wm8958_snd_controls,
- ARRAY_SIZE(wm8958_snd_controls));
- snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
- ARRAY_SIZE(wm8958_dapm_widgets));
- snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets,
- ARRAY_SIZE(wm8994_lateclk_widgets));
- snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets,
- ARRAY_SIZE(wm8994_adc_widgets));
- snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets,
- ARRAY_SIZE(wm8994_dac_widgets));
- break;
- }
-
-
- wm_hubs_add_analogue_routes(codec, 0, 0);
- snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
-
- switch (control->type) {
- case WM8994:
- snd_soc_dapm_add_routes(dapm, wm8994_intercon,
- ARRAY_SIZE(wm8994_intercon));
-
- if (wm8994->revision < 4) {
- snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon,
- ARRAY_SIZE(wm8994_revd_intercon));
- snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon,
- ARRAY_SIZE(wm8994_lateclk_revd_intercon));
- } else {
- snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon,
- ARRAY_SIZE(wm8994_lateclk_intercon));
- }
- break;
- case WM8958:
- if (wm8994->revision < 1) {
- snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon,
- ARRAY_SIZE(wm8994_revd_intercon));
- snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon,
- ARRAY_SIZE(wm8994_lateclk_revd_intercon));
- } else {
- snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon,
- ARRAY_SIZE(wm8994_lateclk_intercon));
- snd_soc_dapm_add_routes(dapm, wm8958_intercon,
- ARRAY_SIZE(wm8958_intercon));
- }
-
- wm8958_dsp2_init(codec);
- break;
- case WM1811:
- snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon,
- ARRAY_SIZE(wm8994_lateclk_intercon));
- snd_soc_dapm_add_routes(dapm, wm8958_intercon,
- ARRAY_SIZE(wm8958_intercon));
- break;
- }
-
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
- WM8994_AIF2DACL_ENA |
- WM8994_AIF2DACR_ENA,
- WM8994_AIF2DACL_ENA |
- WM8994_AIF2DACR_ENA);
-
- wm8994_proc = create_proc_read_entry("wm8994_dumpregs", 0666, NULL,
- wm8994_readproc, wm8994);
-
- return 0;
-
-err_irq:
- if (wm8994->jackdet)
- wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_GPIO(6), wm8994);
- wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC2_SHRT, wm8994);
- wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC2_DET, wm8994);
- wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC1_SHRT, wm8994);
- if (wm8994->micdet_irq)
- free_irq(wm8994->micdet_irq, wm8994);
- for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
- wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FLL1_LOCK + i,
- &wm8994->fll_locked[i]);
- wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_DCS_DONE,
- &wm8994->hubs);
- wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FIFOS_ERR, codec);
- wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT, codec);
- wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_WARN, codec);
-
- return ret;
-}
-
-static int wm8994_codec_remove(struct snd_soc_codec *codec)
-{
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
- struct wm8994 *control = wm8994->wm8994;
- int i;
-
- wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- pm_runtime_disable(codec->dev);
-
- for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
- wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FLL1_LOCK + i,
- &wm8994->fll_locked[i]);
-
- wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_DCS_DONE,
- &wm8994->hubs);
- wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FIFOS_ERR, codec);
- wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT, codec);
- wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_WARN, codec);
-
- if (wm8994->jackdet)
- wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_GPIO(6), wm8994);
-
- switch (control->type) {
- case WM8994:
- if (wm8994->micdet_irq)
- free_irq(wm8994->micdet_irq, wm8994);
- wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC2_DET,
- wm8994);
- wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC1_SHRT,
- wm8994);
- wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC1_DET,
- wm8994);
- break;
-
- case WM1811:
- case WM8958:
- if (wm8994->micdet_irq)
- free_irq(wm8994->micdet_irq, wm8994);
- break;
- }
- if (wm8994->mbc)
- release_firmware(wm8994->mbc);
- if (wm8994->mbc_vss)
- release_firmware(wm8994->mbc_vss);
- if (wm8994->enh_eq)
- release_firmware(wm8994->enh_eq);
- kfree(wm8994->retune_mobile_texts);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
- .probe = wm8994_codec_probe,
- .remove = wm8994_codec_remove,
- .suspend = wm8994_codec_suspend,
- .resume = wm8994_codec_resume,
- .set_bias_level = wm8994_set_bias_level,
-};
-
-static int __devinit wm8994_probe(struct platform_device *pdev)
-{
- struct wm8994_priv *wm8994;
-
- wm8994 = devm_kzalloc(&pdev->dev, sizeof(struct wm8994_priv),
- GFP_KERNEL);
- if (wm8994 == NULL)
- return -ENOMEM;
- platform_set_drvdata(pdev, wm8994);
-
- wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent);
- wm8994->pdata = dev_get_platdata(pdev->dev.parent);
-
- return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994,
- wm8994_dai, ARRAY_SIZE(wm8994_dai));
-}
-
-static int __devexit wm8994_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int wm8994_suspend(struct device *dev)
-{
- struct wm8994_priv *wm8994 = dev_get_drvdata(dev);
-
- /* Drop down to power saving mode when system is suspended */
- if (wm8994->jackdet && !wm8994->active_refcount)
- regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2,
- WM1811_JACKDET_MODE_MASK,
- wm8994->jackdet_mode);
-
- return 0;
-}
-
-static int wm8994_resume(struct device *dev)
-{
- struct wm8994_priv *wm8994 = dev_get_drvdata(dev);
-
- if (wm8994->jackdet && wm8994->jack_cb)
- regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2,
- WM1811_JACKDET_MODE_MASK,
- WM1811_JACKDET_MODE_AUDIO);
-
- return 0;
-}
-#endif
-
-static const struct dev_pm_ops wm8994_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(wm8994_suspend, wm8994_resume)
-};
-
-static struct platform_driver wm8994_codec_driver = {
- .driver = {
- .name = "wm8994-codec",
- .owner = THIS_MODULE,
- .pm = &wm8994_pm_ops,
- },
- .probe = wm8994_probe,
- .remove = __devexit_p(wm8994_remove),
-};
-
-module_platform_driver(wm8994_codec_driver);
-
-MODULE_DESCRIPTION("ASoC WM8994 driver");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:wm8994-codec");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8994.h b/ANDROID_3.4.5/sound/soc/codecs/wm8994.h
deleted file mode 100644
index c7241129..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8994.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * wm8994.h -- WM8994 Soc Audio driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8994_H
-#define _WM8994_H
-
-#include <sound/soc.h>
-#include <linux/firmware.h>
-#include <linux/completion.h>
-
-#include "wm_hubs.h"
-
-/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */
-#define WM8994_SYSCLK_MCLK1 1
-#define WM8994_SYSCLK_MCLK2 2
-#define WM8994_SYSCLK_FLL1 3
-#define WM8994_SYSCLK_FLL2 4
-
-/* OPCLK is also configured with set_dai_sysclk, specify division*10 as rate. */
-#define WM8994_SYSCLK_OPCLK 5
-
-#define WM8994_FLL1 1
-#define WM8994_FLL2 2
-
-#define WM8994_FLL_SRC_MCLK1 1
-#define WM8994_FLL_SRC_MCLK2 2
-#define WM8994_FLL_SRC_LRCLK 3
-#define WM8994_FLL_SRC_BCLK 4
-
-enum wm8994_vmid_mode {
- WM8994_VMID_NORMAL,
- WM8994_VMID_FORCE,
-};
-
-typedef void (*wm8958_micdet_cb)(u16 status, void *data);
-
-int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
- int micbias);
-int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
- wm8958_micdet_cb cb, void *cb_data);
-
-int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode);
-
-int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event);
-
-void wm8958_dsp2_init(struct snd_soc_codec *codec);
-
-struct wm8994_micdet {
- struct snd_soc_jack *jack;
- bool detecting;
-};
-
-/* codec private data */
-struct wm8994_fll_config {
- int src;
- int in;
- int out;
-};
-
-#define WM8994_NUM_DRC 3
-#define WM8994_NUM_EQ 3
-
-struct wm8994;
-
-struct wm8994_priv {
- struct wm_hubs_data hubs;
- struct wm8994 *wm8994;
- struct snd_soc_codec *codec;
- int sysclk[2];
- int sysclk_rate[2];
- int mclk[2];
- int aifclk[2];
- struct wm8994_fll_config fll[2], fll_suspend[2];
- struct completion fll_locked[2];
- bool fll_locked_irq;
-
- int vmid_refcount;
- int active_refcount;
- enum wm8994_vmid_mode vmid_mode;
-
- int dac_rates[2];
- int lrclk_shared[2];
-
- int mbc_ena[3];
- int hpf1_ena[3];
- int hpf2_ena[3];
- int vss_ena[3];
- int enh_eq_ena[3];
-
- /* Platform dependant DRC configuration */
- const char **drc_texts;
- int drc_cfg[WM8994_NUM_DRC];
- struct soc_enum drc_enum;
-
- /* Platform dependant ReTune mobile configuration */
- int num_retune_mobile_texts;
- const char **retune_mobile_texts;
- int retune_mobile_cfg[WM8994_NUM_EQ];
- struct soc_enum retune_mobile_enum;
-
- /* Platform dependant MBC configuration */
- int mbc_cfg;
- const char **mbc_texts;
- struct soc_enum mbc_enum;
-
- /* Platform dependant VSS configuration */
- int vss_cfg;
- const char **vss_texts;
- struct soc_enum vss_enum;
-
- /* Platform dependant VSS HPF configuration */
- int vss_hpf_cfg;
- const char **vss_hpf_texts;
- struct soc_enum vss_hpf_enum;
-
- /* Platform dependant enhanced EQ configuration */
- int enh_eq_cfg;
- const char **enh_eq_texts;
- struct soc_enum enh_eq_enum;
-
- struct mutex accdet_lock;
- struct wm8994_micdet micdet[2];
- bool mic_detecting;
- bool jack_mic;
- int btn_mask;
- bool jackdet;
- int jackdet_mode;
-
- wm8958_micdet_cb jack_cb;
- void *jack_cb_data;
- int micdet_irq;
-
- int revision;
- struct wm8994_pdata *pdata;
-
- unsigned int aif1clk_enable:1;
- unsigned int aif2clk_enable:1;
-
- unsigned int aif1clk_disable:1;
- unsigned int aif2clk_disable:1;
-
- int dsp_active;
- const struct firmware *cur_fw;
- const struct firmware *mbc;
- const struct firmware *mbc_vss;
- const struct firmware *enh_eq;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8995.c b/ANDROID_3.4.5/sound/soc/codecs/wm8995.c
deleted file mode 100644
index 28c89b09..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8995.c
+++ /dev/null
@@ -1,2415 +0,0 @@
-/*
- * wm8995.c -- WM8995 ALSA SoC Audio driver
- *
- * Copyright 2010 Wolfson Microelectronics plc
- *
- * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
- *
- * Based on wm8994.c and wm_hubs.c by Mark Brown
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/regmap.h>
-#include <linux/spi/spi.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "wm8995.h"
-
-#define WM8995_NUM_SUPPLIES 8
-static const char *wm8995_supply_names[WM8995_NUM_SUPPLIES] = {
- "DCVDD",
- "DBVDD1",
- "DBVDD2",
- "DBVDD3",
- "AVDD1",
- "AVDD2",
- "CPVDD",
- "MICVDD"
-};
-
-static struct reg_default wm8995_reg_defaults[] = {
- { 0, 0x8995 },
- { 5, 0x0100 },
- { 16, 0x000b },
- { 17, 0x000b },
- { 24, 0x02c0 },
- { 25, 0x02c0 },
- { 26, 0x02c0 },
- { 27, 0x02c0 },
- { 28, 0x000f },
- { 32, 0x0005 },
- { 33, 0x0005 },
- { 40, 0x0003 },
- { 41, 0x0013 },
- { 48, 0x0004 },
- { 56, 0x09f8 },
- { 64, 0x1f25 },
- { 69, 0x0004 },
- { 82, 0xaaaa },
- { 84, 0x2a2a },
- { 146, 0x0060 },
- { 256, 0x0002 },
- { 257, 0x8004 },
- { 520, 0x0010 },
- { 528, 0x0083 },
- { 529, 0x0083 },
- { 548, 0x0c80 },
- { 580, 0x0c80 },
- { 768, 0x4050 },
- { 769, 0x4000 },
- { 771, 0x0040 },
- { 772, 0x0040 },
- { 773, 0x0040 },
- { 774, 0x0004 },
- { 775, 0x0100 },
- { 784, 0x4050 },
- { 785, 0x4000 },
- { 787, 0x0040 },
- { 788, 0x0040 },
- { 789, 0x0040 },
- { 1024, 0x00c0 },
- { 1025, 0x00c0 },
- { 1026, 0x00c0 },
- { 1027, 0x00c0 },
- { 1028, 0x00c0 },
- { 1029, 0x00c0 },
- { 1030, 0x00c0 },
- { 1031, 0x00c0 },
- { 1056, 0x0200 },
- { 1057, 0x0010 },
- { 1058, 0x0200 },
- { 1059, 0x0010 },
- { 1088, 0x0098 },
- { 1089, 0x0845 },
- { 1104, 0x0098 },
- { 1105, 0x0845 },
- { 1152, 0x6318 },
- { 1153, 0x6300 },
- { 1154, 0x0fca },
- { 1155, 0x0400 },
- { 1156, 0x00d8 },
- { 1157, 0x1eb5 },
- { 1158, 0xf145 },
- { 1159, 0x0b75 },
- { 1160, 0x01c5 },
- { 1161, 0x1c58 },
- { 1162, 0xf373 },
- { 1163, 0x0a54 },
- { 1164, 0x0558 },
- { 1165, 0x168e },
- { 1166, 0xf829 },
- { 1167, 0x07ad },
- { 1168, 0x1103 },
- { 1169, 0x0564 },
- { 1170, 0x0559 },
- { 1171, 0x4000 },
- { 1184, 0x6318 },
- { 1185, 0x6300 },
- { 1186, 0x0fca },
- { 1187, 0x0400 },
- { 1188, 0x00d8 },
- { 1189, 0x1eb5 },
- { 1190, 0xf145 },
- { 1191, 0x0b75 },
- { 1192, 0x01c5 },
- { 1193, 0x1c58 },
- { 1194, 0xf373 },
- { 1195, 0x0a54 },
- { 1196, 0x0558 },
- { 1197, 0x168e },
- { 1198, 0xf829 },
- { 1199, 0x07ad },
- { 1200, 0x1103 },
- { 1201, 0x0564 },
- { 1202, 0x0559 },
- { 1203, 0x4000 },
- { 1280, 0x00c0 },
- { 1281, 0x00c0 },
- { 1282, 0x00c0 },
- { 1283, 0x00c0 },
- { 1312, 0x0200 },
- { 1313, 0x0010 },
- { 1344, 0x0098 },
- { 1345, 0x0845 },
- { 1408, 0x6318 },
- { 1409, 0x6300 },
- { 1410, 0x0fca },
- { 1411, 0x0400 },
- { 1412, 0x00d8 },
- { 1413, 0x1eb5 },
- { 1414, 0xf145 },
- { 1415, 0x0b75 },
- { 1416, 0x01c5 },
- { 1417, 0x1c58 },
- { 1418, 0xf373 },
- { 1419, 0x0a54 },
- { 1420, 0x0558 },
- { 1421, 0x168e },
- { 1422, 0xf829 },
- { 1423, 0x07ad },
- { 1424, 0x1103 },
- { 1425, 0x0564 },
- { 1426, 0x0559 },
- { 1427, 0x4000 },
- { 1568, 0x0002 },
- { 1792, 0xa100 },
- { 1793, 0xa101 },
- { 1794, 0xa101 },
- { 1795, 0xa101 },
- { 1796, 0xa101 },
- { 1797, 0xa101 },
- { 1798, 0xa101 },
- { 1799, 0xa101 },
- { 1800, 0xa101 },
- { 1801, 0xa101 },
- { 1802, 0xa101 },
- { 1803, 0xa101 },
- { 1804, 0xa101 },
- { 1805, 0xa101 },
- { 1825, 0x0055 },
- { 1848, 0x3fff },
- { 1849, 0x1fff },
- { 2049, 0x0001 },
- { 2050, 0x0069 },
- { 2056, 0x0002 },
- { 2057, 0x0003 },
- { 2058, 0x0069 },
- { 12288, 0x0001 },
- { 12289, 0x0001 },
- { 12291, 0x0006 },
- { 12292, 0x0040 },
- { 12293, 0x0001 },
- { 12294, 0x000f },
- { 12295, 0x0006 },
- { 12296, 0x0001 },
- { 12297, 0x0003 },
- { 12298, 0x0104 },
- { 12300, 0x0060 },
- { 12301, 0x0011 },
- { 12302, 0x0401 },
- { 12304, 0x0050 },
- { 12305, 0x0003 },
- { 12306, 0x0100 },
- { 12308, 0x0051 },
- { 12309, 0x0003 },
- { 12310, 0x0104 },
- { 12311, 0x000a },
- { 12312, 0x0060 },
- { 12313, 0x003b },
- { 12314, 0x0502 },
- { 12315, 0x0100 },
- { 12316, 0x2fff },
- { 12320, 0x2fff },
- { 12324, 0x2fff },
- { 12328, 0x2fff },
- { 12332, 0x2fff },
- { 12336, 0x2fff },
- { 12340, 0x2fff },
- { 12344, 0x2fff },
- { 12348, 0x2fff },
- { 12352, 0x0001 },
- { 12353, 0x0001 },
- { 12355, 0x0006 },
- { 12356, 0x0040 },
- { 12357, 0x0001 },
- { 12358, 0x000f },
- { 12359, 0x0006 },
- { 12360, 0x0001 },
- { 12361, 0x0003 },
- { 12362, 0x0104 },
- { 12364, 0x0060 },
- { 12365, 0x0011 },
- { 12366, 0x0401 },
- { 12368, 0x0050 },
- { 12369, 0x0003 },
- { 12370, 0x0100 },
- { 12372, 0x0060 },
- { 12373, 0x003b },
- { 12374, 0x0502 },
- { 12375, 0x0100 },
- { 12376, 0x2fff },
- { 12380, 0x2fff },
- { 12384, 0x2fff },
- { 12388, 0x2fff },
- { 12392, 0x2fff },
- { 12396, 0x2fff },
- { 12400, 0x2fff },
- { 12404, 0x2fff },
- { 12408, 0x2fff },
- { 12412, 0x2fff },
- { 12416, 0x0001 },
- { 12417, 0x0001 },
- { 12419, 0x0006 },
- { 12420, 0x0040 },
- { 12421, 0x0001 },
- { 12422, 0x000f },
- { 12423, 0x0006 },
- { 12424, 0x0001 },
- { 12425, 0x0003 },
- { 12426, 0x0106 },
- { 12428, 0x0061 },
- { 12429, 0x0011 },
- { 12430, 0x0401 },
- { 12432, 0x0050 },
- { 12433, 0x0003 },
- { 12434, 0x0102 },
- { 12436, 0x0051 },
- { 12437, 0x0003 },
- { 12438, 0x0106 },
- { 12439, 0x000a },
- { 12440, 0x0061 },
- { 12441, 0x003b },
- { 12442, 0x0502 },
- { 12443, 0x0100 },
- { 12444, 0x2fff },
- { 12448, 0x2fff },
- { 12452, 0x2fff },
- { 12456, 0x2fff },
- { 12460, 0x2fff },
- { 12464, 0x2fff },
- { 12468, 0x2fff },
- { 12472, 0x2fff },
- { 12476, 0x2fff },
- { 12480, 0x0001 },
- { 12481, 0x0001 },
- { 12483, 0x0006 },
- { 12484, 0x0040 },
- { 12485, 0x0001 },
- { 12486, 0x000f },
- { 12487, 0x0006 },
- { 12488, 0x0001 },
- { 12489, 0x0003 },
- { 12490, 0x0106 },
- { 12492, 0x0061 },
- { 12493, 0x0011 },
- { 12494, 0x0401 },
- { 12496, 0x0050 },
- { 12497, 0x0003 },
- { 12498, 0x0102 },
- { 12500, 0x0061 },
- { 12501, 0x003b },
- { 12502, 0x0502 },
- { 12503, 0x0100 },
- { 12504, 0x2fff },
- { 12508, 0x2fff },
- { 12512, 0x2fff },
- { 12516, 0x2fff },
- { 12520, 0x2fff },
- { 12524, 0x2fff },
- { 12528, 0x2fff },
- { 12532, 0x2fff },
- { 12536, 0x2fff },
- { 12540, 0x2fff },
- { 12544, 0x0060 },
- { 12546, 0x0601 },
- { 12548, 0x0050 },
- { 12550, 0x0100 },
- { 12552, 0x0001 },
- { 12554, 0x0104 },
- { 12555, 0x0100 },
- { 12556, 0x2fff },
- { 12560, 0x2fff },
- { 12564, 0x2fff },
- { 12568, 0x2fff },
- { 12572, 0x2fff },
- { 12576, 0x2fff },
- { 12580, 0x2fff },
- { 12584, 0x2fff },
- { 12588, 0x2fff },
- { 12592, 0x2fff },
- { 12596, 0x2fff },
- { 12600, 0x2fff },
- { 12604, 0x2fff },
- { 12608, 0x0061 },
- { 12610, 0x0601 },
- { 12612, 0x0050 },
- { 12614, 0x0102 },
- { 12616, 0x0001 },
- { 12618, 0x0106 },
- { 12619, 0x0100 },
- { 12620, 0x2fff },
- { 12624, 0x2fff },
- { 12628, 0x2fff },
- { 12632, 0x2fff },
- { 12636, 0x2fff },
- { 12640, 0x2fff },
- { 12644, 0x2fff },
- { 12648, 0x2fff },
- { 12652, 0x2fff },
- { 12656, 0x2fff },
- { 12660, 0x2fff },
- { 12664, 0x2fff },
- { 12668, 0x2fff },
- { 12672, 0x0060 },
- { 12674, 0x0601 },
- { 12676, 0x0061 },
- { 12678, 0x0601 },
- { 12680, 0x0050 },
- { 12682, 0x0300 },
- { 12684, 0x0001 },
- { 12686, 0x0304 },
- { 12688, 0x0040 },
- { 12690, 0x000f },
- { 12692, 0x0001 },
- { 12695, 0x0100 },
-};
-
-struct fll_config {
- int src;
- int in;
- int out;
-};
-
-struct wm8995_priv {
- struct regmap *regmap;
- int sysclk[2];
- int mclk[2];
- int aifclk[2];
- struct fll_config fll[2], fll_suspend[2];
- struct regulator_bulk_data supplies[WM8995_NUM_SUPPLIES];
- struct notifier_block disable_nb[WM8995_NUM_SUPPLIES];
- struct snd_soc_codec *codec;
-};
-
-/*
- * We can't use the same notifier block for more than one supply and
- * there's no way I can see to get from a callback to the caller
- * except container_of().
- */
-#define WM8995_REGULATOR_EVENT(n) \
-static int wm8995_regulator_event_##n(struct notifier_block *nb, \
- unsigned long event, void *data) \
-{ \
- struct wm8995_priv *wm8995 = container_of(nb, struct wm8995_priv, \
- disable_nb[n]); \
- if (event & REGULATOR_EVENT_DISABLE) { \
- regcache_mark_dirty(wm8995->regmap); \
- } \
- return 0; \
-}
-
-WM8995_REGULATOR_EVENT(0)
-WM8995_REGULATOR_EVENT(1)
-WM8995_REGULATOR_EVENT(2)
-WM8995_REGULATOR_EVENT(3)
-WM8995_REGULATOR_EVENT(4)
-WM8995_REGULATOR_EVENT(5)
-WM8995_REGULATOR_EVENT(6)
-WM8995_REGULATOR_EVENT(7)
-
-static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
-static const DECLARE_TLV_DB_SCALE(in1lr_pga_tlv, -1650, 150, 0);
-static const DECLARE_TLV_DB_SCALE(in1l_boost_tlv, 0, 600, 0);
-static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 150, 0);
-
-static const char *in1l_text[] = {
- "Differential", "Single-ended IN1LN", "Single-ended IN1LP"
-};
-
-static const SOC_ENUM_SINGLE_DECL(in1l_enum, WM8995_LEFT_LINE_INPUT_CONTROL,
- 2, in1l_text);
-
-static const char *in1r_text[] = {
- "Differential", "Single-ended IN1RN", "Single-ended IN1RP"
-};
-
-static const SOC_ENUM_SINGLE_DECL(in1r_enum, WM8995_LEFT_LINE_INPUT_CONTROL,
- 0, in1r_text);
-
-static const char *dmic_src_text[] = {
- "DMICDAT1", "DMICDAT2", "DMICDAT3"
-};
-
-static const SOC_ENUM_SINGLE_DECL(dmic_src1_enum, WM8995_POWER_MANAGEMENT_5,
- 8, dmic_src_text);
-static const SOC_ENUM_SINGLE_DECL(dmic_src2_enum, WM8995_POWER_MANAGEMENT_5,
- 6, dmic_src_text);
-
-static const struct snd_kcontrol_new wm8995_snd_controls[] = {
- SOC_DOUBLE_R_TLV("DAC1 Volume", WM8995_DAC1_LEFT_VOLUME,
- WM8995_DAC1_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
- SOC_DOUBLE_R("DAC1 Switch", WM8995_DAC1_LEFT_VOLUME,
- WM8995_DAC1_RIGHT_VOLUME, 9, 1, 1),
-
- SOC_DOUBLE_R_TLV("DAC2 Volume", WM8995_DAC2_LEFT_VOLUME,
- WM8995_DAC2_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
- SOC_DOUBLE_R("DAC2 Switch", WM8995_DAC2_LEFT_VOLUME,
- WM8995_DAC2_RIGHT_VOLUME, 9, 1, 1),
-
- SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8995_AIF1_DAC1_LEFT_VOLUME,
- WM8995_AIF1_DAC1_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
- SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8995_AIF1_DAC2_LEFT_VOLUME,
- WM8995_AIF1_DAC2_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
- SOC_DOUBLE_R_TLV("AIF2DAC Volume", WM8995_AIF2_DAC_LEFT_VOLUME,
- WM8995_AIF2_DAC_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
-
- SOC_DOUBLE_R_TLV("IN1LR Volume", WM8995_LEFT_LINE_INPUT_1_VOLUME,
- WM8995_RIGHT_LINE_INPUT_1_VOLUME, 0, 31, 0, in1lr_pga_tlv),
-
- SOC_SINGLE_TLV("IN1L Boost", WM8995_LEFT_LINE_INPUT_CONTROL,
- 4, 3, 0, in1l_boost_tlv),
-
- SOC_ENUM("IN1L Mode", in1l_enum),
- SOC_ENUM("IN1R Mode", in1r_enum),
-
- SOC_ENUM("DMIC1 SRC", dmic_src1_enum),
- SOC_ENUM("DMIC2 SRC", dmic_src2_enum),
-
- SOC_DOUBLE_TLV("DAC1 Sidetone Volume", WM8995_DAC1_MIXER_VOLUMES, 0, 5,
- 24, 0, sidetone_tlv),
- SOC_DOUBLE_TLV("DAC2 Sidetone Volume", WM8995_DAC2_MIXER_VOLUMES, 0, 5,
- 24, 0, sidetone_tlv),
-
- SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8995_AIF1_ADC1_LEFT_VOLUME,
- WM8995_AIF1_ADC1_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
- SOC_DOUBLE_R_TLV("AIF1ADC2 Volume", WM8995_AIF1_ADC2_LEFT_VOLUME,
- WM8995_AIF1_ADC2_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
- SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8995_AIF2_ADC_LEFT_VOLUME,
- WM8995_AIF2_ADC_RIGHT_VOLUME, 0, 96, 0, digital_tlv)
-};
-
-static void wm8995_update_class_w(struct snd_soc_codec *codec)
-{
- int enable = 1;
- int source = 0; /* GCC flow analysis can't track enable */
- int reg, reg_r;
-
- /* We also need the same setting for L/R and only one path */
- reg = snd_soc_read(codec, WM8995_DAC1_LEFT_MIXER_ROUTING);
- switch (reg) {
- case WM8995_AIF2DACL_TO_DAC1L:
- dev_dbg(codec->dev, "Class W source AIF2DAC\n");
- source = 2 << WM8995_CP_DYN_SRC_SEL_SHIFT;
- break;
- case WM8995_AIF1DAC2L_TO_DAC1L:
- dev_dbg(codec->dev, "Class W source AIF1DAC2\n");
- source = 1 << WM8995_CP_DYN_SRC_SEL_SHIFT;
- break;
- case WM8995_AIF1DAC1L_TO_DAC1L:
- dev_dbg(codec->dev, "Class W source AIF1DAC1\n");
- source = 0 << WM8995_CP_DYN_SRC_SEL_SHIFT;
- break;
- default:
- dev_dbg(codec->dev, "DAC mixer setting: %x\n", reg);
- enable = 0;
- break;
- }
-
- reg_r = snd_soc_read(codec, WM8995_DAC1_RIGHT_MIXER_ROUTING);
- if (reg_r != reg) {
- dev_dbg(codec->dev, "Left and right DAC mixers different\n");
- enable = 0;
- }
-
- if (enable) {
- dev_dbg(codec->dev, "Class W enabled\n");
- snd_soc_update_bits(codec, WM8995_CLASS_W_1,
- WM8995_CP_DYN_PWR_MASK |
- WM8995_CP_DYN_SRC_SEL_MASK,
- source | WM8995_CP_DYN_PWR);
- } else {
- dev_dbg(codec->dev, "Class W disabled\n");
- snd_soc_update_bits(codec, WM8995_CLASS_W_1,
- WM8995_CP_DYN_PWR_MASK, 0);
- }
-}
-
-static int check_clk_sys(struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink)
-{
- unsigned int reg;
- const char *clk;
-
- reg = snd_soc_read(source->codec, WM8995_CLOCKING_1);
- /* Check what we're currently using for CLK_SYS */
- if (reg & WM8995_SYSCLK_SRC)
- clk = "AIF2CLK";
- else
- clk = "AIF1CLK";
- return !strcmp(source->name, clk);
-}
-
-static int wm8995_put_class_w(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
- struct snd_soc_dapm_widget *w = wlist->widgets[0];
- struct snd_soc_codec *codec;
- int ret;
-
- codec = w->codec;
- ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
- wm8995_update_class_w(codec);
- return ret;
-}
-
-static int hp_supply_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec;
- struct wm8995_priv *wm8995;
-
- codec = w->codec;
- wm8995 = snd_soc_codec_get_drvdata(codec);
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- /* Enable the headphone amp */
- snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
- WM8995_HPOUT1L_ENA_MASK |
- WM8995_HPOUT1R_ENA_MASK,
- WM8995_HPOUT1L_ENA |
- WM8995_HPOUT1R_ENA);
-
- /* Enable the second stage */
- snd_soc_update_bits(codec, WM8995_ANALOGUE_HP_1,
- WM8995_HPOUT1L_DLY_MASK |
- WM8995_HPOUT1R_DLY_MASK,
- WM8995_HPOUT1L_DLY |
- WM8995_HPOUT1R_DLY);
- break;
- case SND_SOC_DAPM_PRE_PMD:
- snd_soc_update_bits(codec, WM8995_CHARGE_PUMP_1,
- WM8995_CP_ENA_MASK, 0);
- break;
- }
-
- return 0;
-}
-
-static void dc_servo_cmd(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int val, unsigned int mask)
-{
- int timeout = 10;
-
- dev_dbg(codec->dev, "%s: reg = %#x, val = %#x, mask = %#x\n",
- __func__, reg, val, mask);
-
- snd_soc_write(codec, reg, val);
- while (timeout--) {
- msleep(10);
- val = snd_soc_read(codec, WM8995_DC_SERVO_READBACK_0);
- if ((val & mask) == mask)
- return;
- }
-
- dev_err(codec->dev, "Timed out waiting for DC Servo\n");
-}
-
-static int hp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec;
- unsigned int reg;
-
- codec = w->codec;
- reg = snd_soc_read(codec, WM8995_ANALOGUE_HP_1);
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- snd_soc_update_bits(codec, WM8995_CHARGE_PUMP_1,
- WM8995_CP_ENA_MASK, WM8995_CP_ENA);
-
- msleep(5);
-
- snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
- WM8995_HPOUT1L_ENA_MASK |
- WM8995_HPOUT1R_ENA_MASK,
- WM8995_HPOUT1L_ENA | WM8995_HPOUT1R_ENA);
-
- udelay(20);
-
- reg |= WM8995_HPOUT1L_DLY | WM8995_HPOUT1R_DLY;
- snd_soc_write(codec, WM8995_ANALOGUE_HP_1, reg);
-
- snd_soc_write(codec, WM8995_DC_SERVO_1, WM8995_DCS_ENA_CHAN_0 |
- WM8995_DCS_ENA_CHAN_1);
-
- dc_servo_cmd(codec, WM8995_DC_SERVO_2,
- WM8995_DCS_TRIG_STARTUP_0 |
- WM8995_DCS_TRIG_STARTUP_1,
- WM8995_DCS_TRIG_DAC_WR_0 |
- WM8995_DCS_TRIG_DAC_WR_1);
-
- reg |= WM8995_HPOUT1R_OUTP | WM8995_HPOUT1R_RMV_SHORT |
- WM8995_HPOUT1L_OUTP | WM8995_HPOUT1L_RMV_SHORT;
- snd_soc_write(codec, WM8995_ANALOGUE_HP_1, reg);
-
- break;
- case SND_SOC_DAPM_PRE_PMD:
- snd_soc_update_bits(codec, WM8995_ANALOGUE_HP_1,
- WM8995_HPOUT1L_OUTP_MASK |
- WM8995_HPOUT1R_OUTP_MASK |
- WM8995_HPOUT1L_RMV_SHORT_MASK |
- WM8995_HPOUT1R_RMV_SHORT_MASK, 0);
-
- snd_soc_update_bits(codec, WM8995_ANALOGUE_HP_1,
- WM8995_HPOUT1L_DLY_MASK |
- WM8995_HPOUT1R_DLY_MASK, 0);
-
- snd_soc_write(codec, WM8995_DC_SERVO_1, 0);
-
- snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
- WM8995_HPOUT1L_ENA_MASK |
- WM8995_HPOUT1R_ENA_MASK,
- 0);
- break;
- }
-
- return 0;
-}
-
-static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
-{
- struct wm8995_priv *wm8995;
- int rate;
- int reg1 = 0;
- int offset;
-
- wm8995 = snd_soc_codec_get_drvdata(codec);
-
- if (aif)
- offset = 4;
- else
- offset = 0;
-
- switch (wm8995->sysclk[aif]) {
- case WM8995_SYSCLK_MCLK1:
- rate = wm8995->mclk[0];
- break;
- case WM8995_SYSCLK_MCLK2:
- reg1 |= 0x8;
- rate = wm8995->mclk[1];
- break;
- case WM8995_SYSCLK_FLL1:
- reg1 |= 0x10;
- rate = wm8995->fll[0].out;
- break;
- case WM8995_SYSCLK_FLL2:
- reg1 |= 0x18;
- rate = wm8995->fll[1].out;
- break;
- default:
- return -EINVAL;
- }
-
- if (rate >= 13500000) {
- rate /= 2;
- reg1 |= WM8995_AIF1CLK_DIV;
-
- dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n",
- aif + 1, rate);
- }
-
- wm8995->aifclk[aif] = rate;
-
- snd_soc_update_bits(codec, WM8995_AIF1_CLOCKING_1 + offset,
- WM8995_AIF1CLK_SRC_MASK | WM8995_AIF1CLK_DIV_MASK,
- reg1);
- return 0;
-}
-
-static int configure_clock(struct snd_soc_codec *codec)
-{
- struct wm8995_priv *wm8995;
- int change, new;
-
- wm8995 = snd_soc_codec_get_drvdata(codec);
-
- /* Bring up the AIF clocks first */
- configure_aif_clock(codec, 0);
- configure_aif_clock(codec, 1);
-
- /*
- * Then switch CLK_SYS over to the higher of them; a change
- * can only happen as a result of a clocking change which can
- * only be made outside of DAPM so we can safely redo the
- * clocking.
- */
-
- /* If they're equal it doesn't matter which is used */
- if (wm8995->aifclk[0] == wm8995->aifclk[1])
- return 0;
-
- if (wm8995->aifclk[0] < wm8995->aifclk[1])
- new = WM8995_SYSCLK_SRC;
- else
- new = 0;
-
- change = snd_soc_update_bits(codec, WM8995_CLOCKING_1,
- WM8995_SYSCLK_SRC_MASK, new);
- if (!change)
- return 0;
-
- snd_soc_dapm_sync(&codec->dapm);
-
- return 0;
-}
-
-static int clk_sys_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec;
-
- codec = w->codec;
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- return configure_clock(codec);
-
- case SND_SOC_DAPM_POST_PMD:
- configure_clock(codec);
- break;
- }
-
- return 0;
-}
-
-static const char *sidetone_text[] = {
- "ADC/DMIC1", "DMIC2",
-};
-
-static const struct soc_enum sidetone1_enum =
- SOC_ENUM_SINGLE(WM8995_SIDETONE, 0, 2, sidetone_text);
-
-static const struct snd_kcontrol_new sidetone1_mux =
- SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum);
-
-static const struct soc_enum sidetone2_enum =
- SOC_ENUM_SINGLE(WM8995_SIDETONE, 1, 2, sidetone_text);
-
-static const struct snd_kcontrol_new sidetone2_mux =
- SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum);
-
-static const struct snd_kcontrol_new aif1adc1l_mix[] = {
- SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8995_AIF1_ADC1_LEFT_MIXER_ROUTING,
- 1, 1, 0),
- SOC_DAPM_SINGLE("AIF2 Switch", WM8995_AIF1_ADC1_LEFT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new aif1adc1r_mix[] = {
- SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8995_AIF1_ADC1_RIGHT_MIXER_ROUTING,
- 1, 1, 0),
- SOC_DAPM_SINGLE("AIF2 Switch", WM8995_AIF1_ADC1_RIGHT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new aif1adc2l_mix[] = {
- SOC_DAPM_SINGLE("DMIC Switch", WM8995_AIF1_ADC2_LEFT_MIXER_ROUTING,
- 1, 1, 0),
- SOC_DAPM_SINGLE("AIF2 Switch", WM8995_AIF1_ADC2_LEFT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new aif1adc2r_mix[] = {
- SOC_DAPM_SINGLE("DMIC Switch", WM8995_AIF1_ADC2_RIGHT_MIXER_ROUTING,
- 1, 1, 0),
- SOC_DAPM_SINGLE("AIF2 Switch", WM8995_AIF1_ADC2_RIGHT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new dac1l_mix[] = {
- WM8995_CLASS_W_SWITCH("Right Sidetone Switch", WM8995_DAC1_LEFT_MIXER_ROUTING,
- 5, 1, 0),
- WM8995_CLASS_W_SWITCH("Left Sidetone Switch", WM8995_DAC1_LEFT_MIXER_ROUTING,
- 4, 1, 0),
- WM8995_CLASS_W_SWITCH("AIF2 Switch", WM8995_DAC1_LEFT_MIXER_ROUTING,
- 2, 1, 0),
- WM8995_CLASS_W_SWITCH("AIF1.2 Switch", WM8995_DAC1_LEFT_MIXER_ROUTING,
- 1, 1, 0),
- WM8995_CLASS_W_SWITCH("AIF1.1 Switch", WM8995_DAC1_LEFT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new dac1r_mix[] = {
- WM8995_CLASS_W_SWITCH("Right Sidetone Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING,
- 5, 1, 0),
- WM8995_CLASS_W_SWITCH("Left Sidetone Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING,
- 4, 1, 0),
- WM8995_CLASS_W_SWITCH("AIF2 Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING,
- 2, 1, 0),
- WM8995_CLASS_W_SWITCH("AIF1.2 Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING,
- 1, 1, 0),
- WM8995_CLASS_W_SWITCH("AIF1.1 Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new aif2dac2l_mix[] = {
- SOC_DAPM_SINGLE("Right Sidetone Switch", WM8995_DAC2_LEFT_MIXER_ROUTING,
- 5, 1, 0),
- SOC_DAPM_SINGLE("Left Sidetone Switch", WM8995_DAC2_LEFT_MIXER_ROUTING,
- 4, 1, 0),
- SOC_DAPM_SINGLE("AIF2 Switch", WM8995_DAC2_LEFT_MIXER_ROUTING,
- 2, 1, 0),
- SOC_DAPM_SINGLE("AIF1.2 Switch", WM8995_DAC2_LEFT_MIXER_ROUTING,
- 1, 1, 0),
- SOC_DAPM_SINGLE("AIF1.1 Switch", WM8995_DAC2_LEFT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new aif2dac2r_mix[] = {
- SOC_DAPM_SINGLE("Right Sidetone Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING,
- 5, 1, 0),
- SOC_DAPM_SINGLE("Left Sidetone Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING,
- 4, 1, 0),
- SOC_DAPM_SINGLE("AIF2 Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING,
- 2, 1, 0),
- SOC_DAPM_SINGLE("AIF1.2 Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING,
- 1, 1, 0),
- SOC_DAPM_SINGLE("AIF1.1 Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new in1l_pga =
- SOC_DAPM_SINGLE("IN1L Switch", WM8995_POWER_MANAGEMENT_2, 5, 1, 0);
-
-static const struct snd_kcontrol_new in1r_pga =
- SOC_DAPM_SINGLE("IN1R Switch", WM8995_POWER_MANAGEMENT_2, 4, 1, 0);
-
-static const char *adc_mux_text[] = {
- "ADC",
- "DMIC",
-};
-
-static const struct soc_enum adc_enum =
- SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text);
-
-static const struct snd_kcontrol_new adcl_mux =
- SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum);
-
-static const struct snd_kcontrol_new adcr_mux =
- SOC_DAPM_ENUM_VIRT("ADCR Mux", adc_enum);
-
-static const char *spk_src_text[] = {
- "DAC1L", "DAC1R", "DAC2L", "DAC2R"
-};
-
-static const SOC_ENUM_SINGLE_DECL(spk1l_src_enum, WM8995_LEFT_PDM_SPEAKER_1,
- 0, spk_src_text);
-static const SOC_ENUM_SINGLE_DECL(spk1r_src_enum, WM8995_RIGHT_PDM_SPEAKER_1,
- 0, spk_src_text);
-static const SOC_ENUM_SINGLE_DECL(spk2l_src_enum, WM8995_LEFT_PDM_SPEAKER_2,
- 0, spk_src_text);
-static const SOC_ENUM_SINGLE_DECL(spk2r_src_enum, WM8995_RIGHT_PDM_SPEAKER_2,
- 0, spk_src_text);
-
-static const struct snd_kcontrol_new spk1l_mux =
- SOC_DAPM_ENUM("SPK1L SRC", spk1l_src_enum);
-static const struct snd_kcontrol_new spk1r_mux =
- SOC_DAPM_ENUM("SPK1R SRC", spk1r_src_enum);
-static const struct snd_kcontrol_new spk2l_mux =
- SOC_DAPM_ENUM("SPK2L SRC", spk2l_src_enum);
-static const struct snd_kcontrol_new spk2r_mux =
- SOC_DAPM_ENUM("SPK2R SRC", spk2r_src_enum);
-
-static const struct snd_soc_dapm_widget wm8995_dapm_widgets[] = {
- SND_SOC_DAPM_INPUT("DMIC1DAT"),
- SND_SOC_DAPM_INPUT("DMIC2DAT"),
-
- SND_SOC_DAPM_INPUT("IN1L"),
- SND_SOC_DAPM_INPUT("IN1R"),
-
- SND_SOC_DAPM_MIXER("IN1L PGA", SND_SOC_NOPM, 0, 0,
- &in1l_pga, 1),
- SND_SOC_DAPM_MIXER("IN1R PGA", SND_SOC_NOPM, 0, 0,
- &in1r_pga, 1),
-
- SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8995_POWER_MANAGEMENT_1, 8, 0,
- NULL, 0),
- SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8995_POWER_MANAGEMENT_1, 9, 0,
- NULL, 0),
-
- SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8995_AIF1_CLOCKING_1, 0, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8995_AIF2_CLOCKING_1, 0, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8995_CLOCKING_1, 3, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8995_CLOCKING_1, 2, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("SYSDSPCLK", WM8995_CLOCKING_1, 1, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-
- SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture", 0,
- WM8995_POWER_MANAGEMENT_3, 9, 0),
- SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture", 0,
- WM8995_POWER_MANAGEMENT_3, 8, 0),
- SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", "AIF1 Capture", 0,
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture",
- 0, WM8995_POWER_MANAGEMENT_3, 11, 0),
- SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture",
- 0, WM8995_POWER_MANAGEMENT_3, 10, 0),
-
- SND_SOC_DAPM_VIRT_MUX("ADCL Mux", SND_SOC_NOPM, 1, 0,
- &adcl_mux),
- SND_SOC_DAPM_VIRT_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0,
- &adcr_mux),
-
- SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8995_POWER_MANAGEMENT_3, 5, 0),
- SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8995_POWER_MANAGEMENT_3, 4, 0),
- SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8995_POWER_MANAGEMENT_3, 3, 0),
- SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8995_POWER_MANAGEMENT_3, 2, 0),
-
- SND_SOC_DAPM_ADC("ADCL", NULL, WM8995_POWER_MANAGEMENT_3, 1, 0),
- SND_SOC_DAPM_ADC("ADCR", NULL, WM8995_POWER_MANAGEMENT_3, 0, 0),
-
- SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0,
- aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)),
- SND_SOC_DAPM_MIXER("AIF1ADC1R Mixer", SND_SOC_NOPM, 0, 0,
- aif1adc1r_mix, ARRAY_SIZE(aif1adc1r_mix)),
- SND_SOC_DAPM_MIXER("AIF1ADC2L Mixer", SND_SOC_NOPM, 0, 0,
- aif1adc2l_mix, ARRAY_SIZE(aif1adc2l_mix)),
- SND_SOC_DAPM_MIXER("AIF1ADC2R Mixer", SND_SOC_NOPM, 0, 0,
- aif1adc2r_mix, ARRAY_SIZE(aif1adc2r_mix)),
-
- SND_SOC_DAPM_AIF_IN("AIF1DAC1L", NULL, 0, WM8995_POWER_MANAGEMENT_4,
- 9, 0),
- SND_SOC_DAPM_AIF_IN("AIF1DAC1R", NULL, 0, WM8995_POWER_MANAGEMENT_4,
- 8, 0),
- SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM,
- 0, 0),
-
- SND_SOC_DAPM_AIF_IN("AIF1DAC2L", NULL, 0, WM8995_POWER_MANAGEMENT_4,
- 11, 0),
- SND_SOC_DAPM_AIF_IN("AIF1DAC2R", NULL, 0, WM8995_POWER_MANAGEMENT_4,
- 10, 0),
-
- SND_SOC_DAPM_MIXER("AIF2DAC2L Mixer", SND_SOC_NOPM, 0, 0,
- aif2dac2l_mix, ARRAY_SIZE(aif2dac2l_mix)),
- SND_SOC_DAPM_MIXER("AIF2DAC2R Mixer", SND_SOC_NOPM, 0, 0,
- aif2dac2r_mix, ARRAY_SIZE(aif2dac2r_mix)),
-
- SND_SOC_DAPM_DAC("DAC2L", NULL, WM8995_POWER_MANAGEMENT_4, 3, 0),
- SND_SOC_DAPM_DAC("DAC2R", NULL, WM8995_POWER_MANAGEMENT_4, 2, 0),
- SND_SOC_DAPM_DAC("DAC1L", NULL, WM8995_POWER_MANAGEMENT_4, 1, 0),
- SND_SOC_DAPM_DAC("DAC1R", NULL, WM8995_POWER_MANAGEMENT_4, 0, 0),
-
- SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0, dac1l_mix,
- ARRAY_SIZE(dac1l_mix)),
- SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0, dac1r_mix,
- ARRAY_SIZE(dac1r_mix)),
-
- SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &sidetone1_mux),
- SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &sidetone2_mux),
-
- SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
- hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-
- SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0,
- hp_supply_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
-
- SND_SOC_DAPM_MUX("SPK1L Driver", WM8995_LEFT_PDM_SPEAKER_1,
- 4, 0, &spk1l_mux),
- SND_SOC_DAPM_MUX("SPK1R Driver", WM8995_RIGHT_PDM_SPEAKER_1,
- 4, 0, &spk1r_mux),
- SND_SOC_DAPM_MUX("SPK2L Driver", WM8995_LEFT_PDM_SPEAKER_2,
- 4, 0, &spk2l_mux),
- SND_SOC_DAPM_MUX("SPK2R Driver", WM8995_RIGHT_PDM_SPEAKER_2,
- 4, 0, &spk2r_mux),
-
- SND_SOC_DAPM_SUPPLY("LDO2", WM8995_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
-
- SND_SOC_DAPM_OUTPUT("HP1L"),
- SND_SOC_DAPM_OUTPUT("HP1R"),
- SND_SOC_DAPM_OUTPUT("SPK1L"),
- SND_SOC_DAPM_OUTPUT("SPK1R"),
- SND_SOC_DAPM_OUTPUT("SPK2L"),
- SND_SOC_DAPM_OUTPUT("SPK2R")
-};
-
-static const struct snd_soc_dapm_route wm8995_intercon[] = {
- { "CLK_SYS", NULL, "AIF1CLK", check_clk_sys },
- { "CLK_SYS", NULL, "AIF2CLK", check_clk_sys },
-
- { "DSP1CLK", NULL, "CLK_SYS" },
- { "DSP2CLK", NULL, "CLK_SYS" },
- { "SYSDSPCLK", NULL, "CLK_SYS" },
-
- { "AIF1ADC1L", NULL, "AIF1CLK" },
- { "AIF1ADC1L", NULL, "DSP1CLK" },
- { "AIF1ADC1R", NULL, "AIF1CLK" },
- { "AIF1ADC1R", NULL, "DSP1CLK" },
- { "AIF1ADC1R", NULL, "SYSDSPCLK" },
-
- { "AIF1ADC2L", NULL, "AIF1CLK" },
- { "AIF1ADC2L", NULL, "DSP1CLK" },
- { "AIF1ADC2R", NULL, "AIF1CLK" },
- { "AIF1ADC2R", NULL, "DSP1CLK" },
- { "AIF1ADC2R", NULL, "SYSDSPCLK" },
-
- { "DMIC1L", NULL, "DMIC1DAT" },
- { "DMIC1L", NULL, "CLK_SYS" },
- { "DMIC1R", NULL, "DMIC1DAT" },
- { "DMIC1R", NULL, "CLK_SYS" },
- { "DMIC2L", NULL, "DMIC2DAT" },
- { "DMIC2L", NULL, "CLK_SYS" },
- { "DMIC2R", NULL, "DMIC2DAT" },
- { "DMIC2R", NULL, "CLK_SYS" },
-
- { "ADCL", NULL, "AIF1CLK" },
- { "ADCL", NULL, "DSP1CLK" },
- { "ADCL", NULL, "SYSDSPCLK" },
-
- { "ADCR", NULL, "AIF1CLK" },
- { "ADCR", NULL, "DSP1CLK" },
- { "ADCR", NULL, "SYSDSPCLK" },
-
- { "IN1L PGA", "IN1L Switch", "IN1L" },
- { "IN1R PGA", "IN1R Switch", "IN1R" },
- { "IN1L PGA", NULL, "LDO2" },
- { "IN1R PGA", NULL, "LDO2" },
-
- { "ADCL", NULL, "IN1L PGA" },
- { "ADCR", NULL, "IN1R PGA" },
-
- { "ADCL Mux", "ADC", "ADCL" },
- { "ADCL Mux", "DMIC", "DMIC1L" },
- { "ADCR Mux", "ADC", "ADCR" },
- { "ADCR Mux", "DMIC", "DMIC1R" },
-
- /* AIF1 outputs */
- { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" },
- { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" },
-
- { "AIF1ADC1R", NULL, "AIF1ADC1R Mixer" },
- { "AIF1ADC1R Mixer", "ADC/DMIC Switch", "ADCR Mux" },
-
- { "AIF1ADC2L", NULL, "AIF1ADC2L Mixer" },
- { "AIF1ADC2L Mixer", "DMIC Switch", "DMIC2L" },
-
- { "AIF1ADC2R", NULL, "AIF1ADC2R Mixer" },
- { "AIF1ADC2R Mixer", "DMIC Switch", "DMIC2R" },
-
- /* Sidetone */
- { "Left Sidetone", "ADC/DMIC1", "AIF1ADC1L" },
- { "Left Sidetone", "DMIC2", "AIF1ADC2L" },
- { "Right Sidetone", "ADC/DMIC1", "AIF1ADC1R" },
- { "Right Sidetone", "DMIC2", "AIF1ADC2R" },
-
- { "AIF1DAC1L", NULL, "AIF1CLK" },
- { "AIF1DAC1L", NULL, "DSP1CLK" },
- { "AIF1DAC1R", NULL, "AIF1CLK" },
- { "AIF1DAC1R", NULL, "DSP1CLK" },
- { "AIF1DAC1R", NULL, "SYSDSPCLK" },
-
- { "AIF1DAC2L", NULL, "AIF1CLK" },
- { "AIF1DAC2L", NULL, "DSP1CLK" },
- { "AIF1DAC2R", NULL, "AIF1CLK" },
- { "AIF1DAC2R", NULL, "DSP1CLK" },
- { "AIF1DAC2R", NULL, "SYSDSPCLK" },
-
- { "DAC1L", NULL, "AIF1CLK" },
- { "DAC1L", NULL, "DSP1CLK" },
- { "DAC1L", NULL, "SYSDSPCLK" },
-
- { "DAC1R", NULL, "AIF1CLK" },
- { "DAC1R", NULL, "DSP1CLK" },
- { "DAC1R", NULL, "SYSDSPCLK" },
-
- { "AIF1DAC1L", NULL, "AIF1DACDAT" },
- { "AIF1DAC1R", NULL, "AIF1DACDAT" },
- { "AIF1DAC2L", NULL, "AIF1DACDAT" },
- { "AIF1DAC2R", NULL, "AIF1DACDAT" },
-
- /* DAC1 inputs */
- { "DAC1L", NULL, "DAC1L Mixer" },
- { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
- { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
- { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
- { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
-
- { "DAC1R", NULL, "DAC1R Mixer" },
- { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
- { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
- { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" },
- { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" },
-
- /* DAC2/AIF2 outputs */
- { "DAC2L", NULL, "AIF2DAC2L Mixer" },
- { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
- { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
-
- { "DAC2R", NULL, "AIF2DAC2R Mixer" },
- { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
- { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
-
- /* Output stages */
- { "Headphone PGA", NULL, "DAC1L" },
- { "Headphone PGA", NULL, "DAC1R" },
-
- { "Headphone PGA", NULL, "DAC2L" },
- { "Headphone PGA", NULL, "DAC2R" },
-
- { "Headphone PGA", NULL, "Headphone Supply" },
- { "Headphone PGA", NULL, "CLK_SYS" },
- { "Headphone PGA", NULL, "LDO2" },
-
- { "HP1L", NULL, "Headphone PGA" },
- { "HP1R", NULL, "Headphone PGA" },
-
- { "SPK1L Driver", "DAC1L", "DAC1L" },
- { "SPK1L Driver", "DAC1R", "DAC1R" },
- { "SPK1L Driver", "DAC2L", "DAC2L" },
- { "SPK1L Driver", "DAC2R", "DAC2R" },
- { "SPK1L Driver", NULL, "CLK_SYS" },
-
- { "SPK1R Driver", "DAC1L", "DAC1L" },
- { "SPK1R Driver", "DAC1R", "DAC1R" },
- { "SPK1R Driver", "DAC2L", "DAC2L" },
- { "SPK1R Driver", "DAC2R", "DAC2R" },
- { "SPK1R Driver", NULL, "CLK_SYS" },
-
- { "SPK2L Driver", "DAC1L", "DAC1L" },
- { "SPK2L Driver", "DAC1R", "DAC1R" },
- { "SPK2L Driver", "DAC2L", "DAC2L" },
- { "SPK2L Driver", "DAC2R", "DAC2R" },
- { "SPK2L Driver", NULL, "CLK_SYS" },
-
- { "SPK2R Driver", "DAC1L", "DAC1L" },
- { "SPK2R Driver", "DAC1R", "DAC1R" },
- { "SPK2R Driver", "DAC2L", "DAC2L" },
- { "SPK2R Driver", "DAC2R", "DAC2R" },
- { "SPK2R Driver", NULL, "CLK_SYS" },
-
- { "SPK1L", NULL, "SPK1L Driver" },
- { "SPK1R", NULL, "SPK1R Driver" },
- { "SPK2L", NULL, "SPK2L Driver" },
- { "SPK2R", NULL, "SPK2R Driver" }
-};
-
-static bool wm8995_readable(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM8995_SOFTWARE_RESET:
- case WM8995_POWER_MANAGEMENT_1:
- case WM8995_POWER_MANAGEMENT_2:
- case WM8995_POWER_MANAGEMENT_3:
- case WM8995_POWER_MANAGEMENT_4:
- case WM8995_POWER_MANAGEMENT_5:
- case WM8995_LEFT_LINE_INPUT_1_VOLUME:
- case WM8995_RIGHT_LINE_INPUT_1_VOLUME:
- case WM8995_LEFT_LINE_INPUT_CONTROL:
- case WM8995_DAC1_LEFT_VOLUME:
- case WM8995_DAC1_RIGHT_VOLUME:
- case WM8995_DAC2_LEFT_VOLUME:
- case WM8995_DAC2_RIGHT_VOLUME:
- case WM8995_OUTPUT_VOLUME_ZC_1:
- case WM8995_MICBIAS_1:
- case WM8995_MICBIAS_2:
- case WM8995_LDO_1:
- case WM8995_LDO_2:
- case WM8995_ACCESSORY_DETECT_MODE1:
- case WM8995_ACCESSORY_DETECT_MODE2:
- case WM8995_HEADPHONE_DETECT1:
- case WM8995_HEADPHONE_DETECT2:
- case WM8995_MIC_DETECT_1:
- case WM8995_MIC_DETECT_2:
- case WM8995_CHARGE_PUMP_1:
- case WM8995_CLASS_W_1:
- case WM8995_DC_SERVO_1:
- case WM8995_DC_SERVO_2:
- case WM8995_DC_SERVO_3:
- case WM8995_DC_SERVO_5:
- case WM8995_DC_SERVO_6:
- case WM8995_DC_SERVO_7:
- case WM8995_DC_SERVO_READBACK_0:
- case WM8995_ANALOGUE_HP_1:
- case WM8995_ANALOGUE_HP_2:
- case WM8995_CHIP_REVISION:
- case WM8995_CONTROL_INTERFACE_1:
- case WM8995_CONTROL_INTERFACE_2:
- case WM8995_WRITE_SEQUENCER_CTRL_1:
- case WM8995_WRITE_SEQUENCER_CTRL_2:
- case WM8995_AIF1_CLOCKING_1:
- case WM8995_AIF1_CLOCKING_2:
- case WM8995_AIF2_CLOCKING_1:
- case WM8995_AIF2_CLOCKING_2:
- case WM8995_CLOCKING_1:
- case WM8995_CLOCKING_2:
- case WM8995_AIF1_RATE:
- case WM8995_AIF2_RATE:
- case WM8995_RATE_STATUS:
- case WM8995_FLL1_CONTROL_1:
- case WM8995_FLL1_CONTROL_2:
- case WM8995_FLL1_CONTROL_3:
- case WM8995_FLL1_CONTROL_4:
- case WM8995_FLL1_CONTROL_5:
- case WM8995_FLL2_CONTROL_1:
- case WM8995_FLL2_CONTROL_2:
- case WM8995_FLL2_CONTROL_3:
- case WM8995_FLL2_CONTROL_4:
- case WM8995_FLL2_CONTROL_5:
- case WM8995_AIF1_CONTROL_1:
- case WM8995_AIF1_CONTROL_2:
- case WM8995_AIF1_MASTER_SLAVE:
- case WM8995_AIF1_BCLK:
- case WM8995_AIF1ADC_LRCLK:
- case WM8995_AIF1DAC_LRCLK:
- case WM8995_AIF1DAC_DATA:
- case WM8995_AIF1ADC_DATA:
- case WM8995_AIF2_CONTROL_1:
- case WM8995_AIF2_CONTROL_2:
- case WM8995_AIF2_MASTER_SLAVE:
- case WM8995_AIF2_BCLK:
- case WM8995_AIF2ADC_LRCLK:
- case WM8995_AIF2DAC_LRCLK:
- case WM8995_AIF2DAC_DATA:
- case WM8995_AIF2ADC_DATA:
- case WM8995_AIF1_ADC1_LEFT_VOLUME:
- case WM8995_AIF1_ADC1_RIGHT_VOLUME:
- case WM8995_AIF1_DAC1_LEFT_VOLUME:
- case WM8995_AIF1_DAC1_RIGHT_VOLUME:
- case WM8995_AIF1_ADC2_LEFT_VOLUME:
- case WM8995_AIF1_ADC2_RIGHT_VOLUME:
- case WM8995_AIF1_DAC2_LEFT_VOLUME:
- case WM8995_AIF1_DAC2_RIGHT_VOLUME:
- case WM8995_AIF1_ADC1_FILTERS:
- case WM8995_AIF1_ADC2_FILTERS:
- case WM8995_AIF1_DAC1_FILTERS_1:
- case WM8995_AIF1_DAC1_FILTERS_2:
- case WM8995_AIF1_DAC2_FILTERS_1:
- case WM8995_AIF1_DAC2_FILTERS_2:
- case WM8995_AIF1_DRC1_1:
- case WM8995_AIF1_DRC1_2:
- case WM8995_AIF1_DRC1_3:
- case WM8995_AIF1_DRC1_4:
- case WM8995_AIF1_DRC1_5:
- case WM8995_AIF1_DRC2_1:
- case WM8995_AIF1_DRC2_2:
- case WM8995_AIF1_DRC2_3:
- case WM8995_AIF1_DRC2_4:
- case WM8995_AIF1_DRC2_5:
- case WM8995_AIF1_DAC1_EQ_GAINS_1:
- case WM8995_AIF1_DAC1_EQ_GAINS_2:
- case WM8995_AIF1_DAC1_EQ_BAND_1_A:
- case WM8995_AIF1_DAC1_EQ_BAND_1_B:
- case WM8995_AIF1_DAC1_EQ_BAND_1_PG:
- case WM8995_AIF1_DAC1_EQ_BAND_2_A:
- case WM8995_AIF1_DAC1_EQ_BAND_2_B:
- case WM8995_AIF1_DAC1_EQ_BAND_2_C:
- case WM8995_AIF1_DAC1_EQ_BAND_2_PG:
- case WM8995_AIF1_DAC1_EQ_BAND_3_A:
- case WM8995_AIF1_DAC1_EQ_BAND_3_B:
- case WM8995_AIF1_DAC1_EQ_BAND_3_C:
- case WM8995_AIF1_DAC1_EQ_BAND_3_PG:
- case WM8995_AIF1_DAC1_EQ_BAND_4_A:
- case WM8995_AIF1_DAC1_EQ_BAND_4_B:
- case WM8995_AIF1_DAC1_EQ_BAND_4_C:
- case WM8995_AIF1_DAC1_EQ_BAND_4_PG:
- case WM8995_AIF1_DAC1_EQ_BAND_5_A:
- case WM8995_AIF1_DAC1_EQ_BAND_5_B:
- case WM8995_AIF1_DAC1_EQ_BAND_5_PG:
- case WM8995_AIF1_DAC2_EQ_GAINS_1:
- case WM8995_AIF1_DAC2_EQ_GAINS_2:
- case WM8995_AIF1_DAC2_EQ_BAND_1_A:
- case WM8995_AIF1_DAC2_EQ_BAND_1_B:
- case WM8995_AIF1_DAC2_EQ_BAND_1_PG:
- case WM8995_AIF1_DAC2_EQ_BAND_2_A:
- case WM8995_AIF1_DAC2_EQ_BAND_2_B:
- case WM8995_AIF1_DAC2_EQ_BAND_2_C:
- case WM8995_AIF1_DAC2_EQ_BAND_2_PG:
- case WM8995_AIF1_DAC2_EQ_BAND_3_A:
- case WM8995_AIF1_DAC2_EQ_BAND_3_B:
- case WM8995_AIF1_DAC2_EQ_BAND_3_C:
- case WM8995_AIF1_DAC2_EQ_BAND_3_PG:
- case WM8995_AIF1_DAC2_EQ_BAND_4_A:
- case WM8995_AIF1_DAC2_EQ_BAND_4_B:
- case WM8995_AIF1_DAC2_EQ_BAND_4_C:
- case WM8995_AIF1_DAC2_EQ_BAND_4_PG:
- case WM8995_AIF1_DAC2_EQ_BAND_5_A:
- case WM8995_AIF1_DAC2_EQ_BAND_5_B:
- case WM8995_AIF1_DAC2_EQ_BAND_5_PG:
- case WM8995_AIF2_ADC_LEFT_VOLUME:
- case WM8995_AIF2_ADC_RIGHT_VOLUME:
- case WM8995_AIF2_DAC_LEFT_VOLUME:
- case WM8995_AIF2_DAC_RIGHT_VOLUME:
- case WM8995_AIF2_ADC_FILTERS:
- case WM8995_AIF2_DAC_FILTERS_1:
- case WM8995_AIF2_DAC_FILTERS_2:
- case WM8995_AIF2_DRC_1:
- case WM8995_AIF2_DRC_2:
- case WM8995_AIF2_DRC_3:
- case WM8995_AIF2_DRC_4:
- case WM8995_AIF2_DRC_5:
- case WM8995_AIF2_EQ_GAINS_1:
- case WM8995_AIF2_EQ_GAINS_2:
- case WM8995_AIF2_EQ_BAND_1_A:
- case WM8995_AIF2_EQ_BAND_1_B:
- case WM8995_AIF2_EQ_BAND_1_PG:
- case WM8995_AIF2_EQ_BAND_2_A:
- case WM8995_AIF2_EQ_BAND_2_B:
- case WM8995_AIF2_EQ_BAND_2_C:
- case WM8995_AIF2_EQ_BAND_2_PG:
- case WM8995_AIF2_EQ_BAND_3_A:
- case WM8995_AIF2_EQ_BAND_3_B:
- case WM8995_AIF2_EQ_BAND_3_C:
- case WM8995_AIF2_EQ_BAND_3_PG:
- case WM8995_AIF2_EQ_BAND_4_A:
- case WM8995_AIF2_EQ_BAND_4_B:
- case WM8995_AIF2_EQ_BAND_4_C:
- case WM8995_AIF2_EQ_BAND_4_PG:
- case WM8995_AIF2_EQ_BAND_5_A:
- case WM8995_AIF2_EQ_BAND_5_B:
- case WM8995_AIF2_EQ_BAND_5_PG:
- case WM8995_DAC1_MIXER_VOLUMES:
- case WM8995_DAC1_LEFT_MIXER_ROUTING:
- case WM8995_DAC1_RIGHT_MIXER_ROUTING:
- case WM8995_DAC2_MIXER_VOLUMES:
- case WM8995_DAC2_LEFT_MIXER_ROUTING:
- case WM8995_DAC2_RIGHT_MIXER_ROUTING:
- case WM8995_AIF1_ADC1_LEFT_MIXER_ROUTING:
- case WM8995_AIF1_ADC1_RIGHT_MIXER_ROUTING:
- case WM8995_AIF1_ADC2_LEFT_MIXER_ROUTING:
- case WM8995_AIF1_ADC2_RIGHT_MIXER_ROUTING:
- case WM8995_DAC_SOFTMUTE:
- case WM8995_OVERSAMPLING:
- case WM8995_SIDETONE:
- case WM8995_GPIO_1:
- case WM8995_GPIO_2:
- case WM8995_GPIO_3:
- case WM8995_GPIO_4:
- case WM8995_GPIO_5:
- case WM8995_GPIO_6:
- case WM8995_GPIO_7:
- case WM8995_GPIO_8:
- case WM8995_GPIO_9:
- case WM8995_GPIO_10:
- case WM8995_GPIO_11:
- case WM8995_GPIO_12:
- case WM8995_GPIO_13:
- case WM8995_GPIO_14:
- case WM8995_PULL_CONTROL_1:
- case WM8995_PULL_CONTROL_2:
- case WM8995_INTERRUPT_STATUS_1:
- case WM8995_INTERRUPT_STATUS_2:
- case WM8995_INTERRUPT_RAW_STATUS_2:
- case WM8995_INTERRUPT_STATUS_1_MASK:
- case WM8995_INTERRUPT_STATUS_2_MASK:
- case WM8995_INTERRUPT_CONTROL:
- case WM8995_LEFT_PDM_SPEAKER_1:
- case WM8995_RIGHT_PDM_SPEAKER_1:
- case WM8995_PDM_SPEAKER_1_MUTE_SEQUENCE:
- case WM8995_LEFT_PDM_SPEAKER_2:
- case WM8995_RIGHT_PDM_SPEAKER_2:
- case WM8995_PDM_SPEAKER_2_MUTE_SEQUENCE:
- return true;
- default:
- return false;
- }
-}
-
-static bool wm8995_volatile(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM8995_SOFTWARE_RESET:
- case WM8995_DC_SERVO_READBACK_0:
- case WM8995_INTERRUPT_STATUS_1:
- case WM8995_INTERRUPT_STATUS_2:
- case WM8995_INTERRUPT_CONTROL:
- case WM8995_ACCESSORY_DETECT_MODE1:
- case WM8995_ACCESSORY_DETECT_MODE2:
- case WM8995_HEADPHONE_DETECT1:
- case WM8995_HEADPHONE_DETECT2:
- case WM8995_RATE_STATUS:
- return true;
- default:
- return false;
- }
-}
-
-static int wm8995_aif_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- int mute_reg;
-
- switch (dai->id) {
- case 0:
- mute_reg = WM8995_AIF1_DAC1_FILTERS_1;
- break;
- case 1:
- mute_reg = WM8995_AIF2_DAC_FILTERS_1;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, mute_reg, WM8995_AIF1DAC1_MUTE_MASK,
- !!mute << WM8995_AIF1DAC1_MUTE_SHIFT);
- return 0;
-}
-
-static int wm8995_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec;
- int master;
- int aif;
-
- codec = dai->codec;
-
- master = 0;
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- master = WM8995_AIF1_MSTR;
- break;
- default:
- dev_err(dai->dev, "Unknown master/slave configuration\n");
- return -EINVAL;
- }
-
- aif = 0;
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_B:
- aif |= WM8995_AIF1_LRCLK_INV;
- case SND_SOC_DAIFMT_DSP_A:
- aif |= (0x3 << WM8995_AIF1_FMT_SHIFT);
- break;
- case SND_SOC_DAIFMT_I2S:
- aif |= (0x2 << WM8995_AIF1_FMT_SHIFT);
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- aif |= (0x1 << WM8995_AIF1_FMT_SHIFT);
- break;
- default:
- dev_err(dai->dev, "Unknown dai format\n");
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- case SND_SOC_DAIFMT_DSP_B:
- /* frame inversion not valid for DSP modes */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_NF:
- aif |= WM8995_AIF1_BCLK_INV;
- break;
- default:
- return -EINVAL;
- }
- break;
-
- case SND_SOC_DAIFMT_I2S:
- case SND_SOC_DAIFMT_RIGHT_J:
- case SND_SOC_DAIFMT_LEFT_J:
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- aif |= WM8995_AIF1_BCLK_INV | WM8995_AIF1_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- aif |= WM8995_AIF1_BCLK_INV;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- aif |= WM8995_AIF1_LRCLK_INV;
- break;
- default:
- return -EINVAL;
- }
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, WM8995_AIF1_CONTROL_1,
- WM8995_AIF1_BCLK_INV_MASK |
- WM8995_AIF1_LRCLK_INV_MASK |
- WM8995_AIF1_FMT_MASK, aif);
- snd_soc_update_bits(codec, WM8995_AIF1_MASTER_SLAVE,
- WM8995_AIF1_MSTR_MASK, master);
- return 0;
-}
-
-static const int srs[] = {
- 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100,
- 48000, 88200, 96000
-};
-
-static const int fs_ratios[] = {
- -1 /* reserved */,
- 128, 192, 256, 384, 512, 768, 1024, 1408, 1536
-};
-
-static const int bclk_divs[] = {
- 10, 15, 20, 30, 40, 55, 60, 80, 110, 120, 160, 220, 240, 320, 440, 480
-};
-
-static int wm8995_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec;
- struct wm8995_priv *wm8995;
- int aif1_reg;
- int bclk_reg;
- int lrclk_reg;
- int rate_reg;
- int bclk_rate;
- int aif1;
- int lrclk, bclk;
- int i, rate_val, best, best_val, cur_val;
-
- codec = dai->codec;
- wm8995 = snd_soc_codec_get_drvdata(codec);
-
- switch (dai->id) {
- case 0:
- aif1_reg = WM8995_AIF1_CONTROL_1;
- bclk_reg = WM8995_AIF1_BCLK;
- rate_reg = WM8995_AIF1_RATE;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK /* ||
- wm8995->lrclk_shared[0] */) {
- lrclk_reg = WM8995_AIF1DAC_LRCLK;
- } else {
- lrclk_reg = WM8995_AIF1ADC_LRCLK;
- dev_dbg(codec->dev, "AIF1 using split LRCLK\n");
- }
- break;
- case 1:
- aif1_reg = WM8995_AIF2_CONTROL_1;
- bclk_reg = WM8995_AIF2_BCLK;
- rate_reg = WM8995_AIF2_RATE;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK /* ||
- wm8995->lrclk_shared[1] */) {
- lrclk_reg = WM8995_AIF2DAC_LRCLK;
- } else {
- lrclk_reg = WM8995_AIF2ADC_LRCLK;
- dev_dbg(codec->dev, "AIF2 using split LRCLK\n");
- }
- break;
- default:
- return -EINVAL;
- }
-
- bclk_rate = snd_soc_params_to_bclk(params);
- if (bclk_rate < 0)
- return bclk_rate;
-
- aif1 = 0;
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- aif1 |= (0x1 << WM8995_AIF1_WL_SHIFT);
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- aif1 |= (0x2 << WM8995_AIF1_WL_SHIFT);
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- aif1 |= (0x3 << WM8995_AIF1_WL_SHIFT);
- break;
- default:
- dev_err(dai->dev, "Unsupported word length %u\n",
- params_format(params));
- return -EINVAL;
- }
-
- /* try to find a suitable sample rate */
- for (i = 0; i < ARRAY_SIZE(srs); ++i)
- if (srs[i] == params_rate(params))
- break;
- if (i == ARRAY_SIZE(srs)) {
- dev_err(dai->dev, "Sample rate %d is not supported\n",
- params_rate(params));
- return -EINVAL;
- }
- rate_val = i << WM8995_AIF1_SR_SHIFT;
-
- dev_dbg(dai->dev, "Sample rate is %dHz\n", srs[i]);
- dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n",
- dai->id + 1, wm8995->aifclk[dai->id], bclk_rate);
-
- /* AIFCLK/fs ratio; look for a close match in either direction */
- best = 1;
- best_val = abs((fs_ratios[1] * params_rate(params))
- - wm8995->aifclk[dai->id]);
- for (i = 2; i < ARRAY_SIZE(fs_ratios); i++) {
- cur_val = abs((fs_ratios[i] * params_rate(params))
- - wm8995->aifclk[dai->id]);
- if (cur_val >= best_val)
- continue;
- best = i;
- best_val = cur_val;
- }
- rate_val |= best;
-
- dev_dbg(dai->dev, "Selected AIF%dCLK/fs = %d\n",
- dai->id + 1, fs_ratios[best]);
-
- /*
- * We may not get quite the right frequency if using
- * approximate clocks so look for the closest match that is
- * higher than the target (we need to ensure that there enough
- * BCLKs to clock out the samples).
- */
- best = 0;
- bclk = 0;
- for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
- cur_val = (wm8995->aifclk[dai->id] * 10 / bclk_divs[i]) - bclk_rate;
- if (cur_val < 0) /* BCLK table is sorted */
- break;
- best = i;
- }
- bclk |= best << WM8995_AIF1_BCLK_DIV_SHIFT;
-
- bclk_rate = wm8995->aifclk[dai->id] * 10 / bclk_divs[best];
- dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
- bclk_divs[best], bclk_rate);
-
- lrclk = bclk_rate / params_rate(params);
- dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
- lrclk, bclk_rate / lrclk);
-
- snd_soc_update_bits(codec, aif1_reg,
- WM8995_AIF1_WL_MASK, aif1);
- snd_soc_update_bits(codec, bclk_reg,
- WM8995_AIF1_BCLK_DIV_MASK, bclk);
- snd_soc_update_bits(codec, lrclk_reg,
- WM8995_AIF1DAC_RATE_MASK, lrclk);
- snd_soc_update_bits(codec, rate_reg,
- WM8995_AIF1_SR_MASK |
- WM8995_AIF1CLK_RATE_MASK, rate_val);
- return 0;
-}
-
-static int wm8995_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- int reg, val, mask;
-
- switch (codec_dai->id) {
- case 0:
- reg = WM8995_AIF1_MASTER_SLAVE;
- mask = WM8995_AIF1_TRI;
- break;
- case 1:
- reg = WM8995_AIF2_MASTER_SLAVE;
- mask = WM8995_AIF2_TRI;
- break;
- case 2:
- reg = WM8995_POWER_MANAGEMENT_5;
- mask = WM8995_AIF3_TRI;
- break;
- default:
- return -EINVAL;
- }
-
- if (tristate)
- val = mask;
- else
- val = 0;
-
- return snd_soc_update_bits(codec, reg, mask, val);
-}
-
-/* The size in bits of the FLL divide multiplied by 10
- * to allow rounding later */
-#define FIXED_FLL_SIZE ((1 << 16) * 10)
-
-struct fll_div {
- u16 outdiv;
- u16 n;
- u16 k;
- u16 clk_ref_div;
- u16 fll_fratio;
-};
-
-static int wm8995_get_fll_config(struct fll_div *fll,
- int freq_in, int freq_out)
-{
- u64 Kpart;
- unsigned int K, Ndiv, Nmod;
-
- pr_debug("FLL input=%dHz, output=%dHz\n", freq_in, freq_out);
-
- /* Scale the input frequency down to <= 13.5MHz */
- fll->clk_ref_div = 0;
- while (freq_in > 13500000) {
- fll->clk_ref_div++;
- freq_in /= 2;
-
- if (fll->clk_ref_div > 3)
- return -EINVAL;
- }
- pr_debug("CLK_REF_DIV=%d, Fref=%dHz\n", fll->clk_ref_div, freq_in);
-
- /* Scale the output to give 90MHz<=Fvco<=100MHz */
- fll->outdiv = 3;
- while (freq_out * (fll->outdiv + 1) < 90000000) {
- fll->outdiv++;
- if (fll->outdiv > 63)
- return -EINVAL;
- }
- freq_out *= fll->outdiv + 1;
- pr_debug("OUTDIV=%d, Fvco=%dHz\n", fll->outdiv, freq_out);
-
- if (freq_in > 1000000) {
- fll->fll_fratio = 0;
- } else if (freq_in > 256000) {
- fll->fll_fratio = 1;
- freq_in *= 2;
- } else if (freq_in > 128000) {
- fll->fll_fratio = 2;
- freq_in *= 4;
- } else if (freq_in > 64000) {
- fll->fll_fratio = 3;
- freq_in *= 8;
- } else {
- fll->fll_fratio = 4;
- freq_in *= 16;
- }
- pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in);
-
- /* Now, calculate N.K */
- Ndiv = freq_out / freq_in;
-
- fll->n = Ndiv;
- Nmod = freq_out % freq_in;
- pr_debug("Nmod=%d\n", Nmod);
-
- /* Calculate fractional part - scale up so we can round. */
- Kpart = FIXED_FLL_SIZE * (long long)Nmod;
-
- do_div(Kpart, freq_in);
-
- K = Kpart & 0xFFFFFFFF;
-
- if ((K % 10) >= 5)
- K += 5;
-
- /* Move down to proper range now rounding is done */
- fll->k = K / 10;
-
- pr_debug("N=%x K=%x\n", fll->n, fll->k);
-
- return 0;
-}
-
-static int wm8995_set_fll(struct snd_soc_dai *dai, int id,
- int src, unsigned int freq_in,
- unsigned int freq_out)
-{
- struct snd_soc_codec *codec;
- struct wm8995_priv *wm8995;
- int reg_offset, ret;
- struct fll_div fll;
- u16 reg, aif1, aif2;
-
- codec = dai->codec;
- wm8995 = snd_soc_codec_get_drvdata(codec);
-
- aif1 = snd_soc_read(codec, WM8995_AIF1_CLOCKING_1)
- & WM8995_AIF1CLK_ENA;
-
- aif2 = snd_soc_read(codec, WM8995_AIF2_CLOCKING_1)
- & WM8995_AIF2CLK_ENA;
-
- switch (id) {
- case WM8995_FLL1:
- reg_offset = 0;
- id = 0;
- break;
- case WM8995_FLL2:
- reg_offset = 0x20;
- id = 1;
- break;
- default:
- return -EINVAL;
- }
-
- switch (src) {
- case 0:
- /* Allow no source specification when stopping */
- if (freq_out)
- return -EINVAL;
- break;
- case WM8995_FLL_SRC_MCLK1:
- case WM8995_FLL_SRC_MCLK2:
- case WM8995_FLL_SRC_LRCLK:
- case WM8995_FLL_SRC_BCLK:
- break;
- default:
- return -EINVAL;
- }
-
- /* Are we changing anything? */
- if (wm8995->fll[id].src == src &&
- wm8995->fll[id].in == freq_in && wm8995->fll[id].out == freq_out)
- return 0;
-
- /* If we're stopping the FLL redo the old config - no
- * registers will actually be written but we avoid GCC flow
- * analysis bugs spewing warnings.
- */
- if (freq_out)
- ret = wm8995_get_fll_config(&fll, freq_in, freq_out);
- else
- ret = wm8995_get_fll_config(&fll, wm8995->fll[id].in,
- wm8995->fll[id].out);
- if (ret < 0)
- return ret;
-
- /* Gate the AIF clocks while we reclock */
- snd_soc_update_bits(codec, WM8995_AIF1_CLOCKING_1,
- WM8995_AIF1CLK_ENA_MASK, 0);
- snd_soc_update_bits(codec, WM8995_AIF2_CLOCKING_1,
- WM8995_AIF2CLK_ENA_MASK, 0);
-
- /* We always need to disable the FLL while reconfiguring */
- snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_1 + reg_offset,
- WM8995_FLL1_ENA_MASK, 0);
-
- reg = (fll.outdiv << WM8995_FLL1_OUTDIV_SHIFT) |
- (fll.fll_fratio << WM8995_FLL1_FRATIO_SHIFT);
- snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_2 + reg_offset,
- WM8995_FLL1_OUTDIV_MASK |
- WM8995_FLL1_FRATIO_MASK, reg);
-
- snd_soc_write(codec, WM8995_FLL1_CONTROL_3 + reg_offset, fll.k);
-
- snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_4 + reg_offset,
- WM8995_FLL1_N_MASK,
- fll.n << WM8995_FLL1_N_SHIFT);
-
- snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_5 + reg_offset,
- WM8995_FLL1_REFCLK_DIV_MASK |
- WM8995_FLL1_REFCLK_SRC_MASK,
- (fll.clk_ref_div << WM8995_FLL1_REFCLK_DIV_SHIFT) |
- (src - 1));
-
- if (freq_out)
- snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_1 + reg_offset,
- WM8995_FLL1_ENA_MASK, WM8995_FLL1_ENA);
-
- wm8995->fll[id].in = freq_in;
- wm8995->fll[id].out = freq_out;
- wm8995->fll[id].src = src;
-
- /* Enable any gated AIF clocks */
- snd_soc_update_bits(codec, WM8995_AIF1_CLOCKING_1,
- WM8995_AIF1CLK_ENA_MASK, aif1);
- snd_soc_update_bits(codec, WM8995_AIF2_CLOCKING_1,
- WM8995_AIF2CLK_ENA_MASK, aif2);
-
- configure_clock(codec);
-
- return 0;
-}
-
-static int wm8995_set_dai_sysclk(struct snd_soc_dai *dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec;
- struct wm8995_priv *wm8995;
-
- codec = dai->codec;
- wm8995 = snd_soc_codec_get_drvdata(codec);
-
- switch (dai->id) {
- case 0:
- case 1:
- break;
- default:
- /* AIF3 shares clocking with AIF1/2 */
- return -EINVAL;
- }
-
- switch (clk_id) {
- case WM8995_SYSCLK_MCLK1:
- wm8995->sysclk[dai->id] = WM8995_SYSCLK_MCLK1;
- wm8995->mclk[0] = freq;
- dev_dbg(dai->dev, "AIF%d using MCLK1 at %uHz\n",
- dai->id + 1, freq);
- break;
- case WM8995_SYSCLK_MCLK2:
- wm8995->sysclk[dai->id] = WM8995_SYSCLK_MCLK1;
- wm8995->mclk[1] = freq;
- dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n",
- dai->id + 1, freq);
- break;
- case WM8995_SYSCLK_FLL1:
- wm8995->sysclk[dai->id] = WM8995_SYSCLK_FLL1;
- dev_dbg(dai->dev, "AIF%d using FLL1\n", dai->id + 1);
- break;
- case WM8995_SYSCLK_FLL2:
- wm8995->sysclk[dai->id] = WM8995_SYSCLK_FLL2;
- dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id + 1);
- break;
- case WM8995_SYSCLK_OPCLK:
- default:
- dev_err(dai->dev, "Unknown clock source %d\n", clk_id);
- return -EINVAL;
- }
-
- configure_clock(codec);
-
- return 0;
-}
-
-static int wm8995_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct wm8995_priv *wm8995;
- int ret;
-
- wm8995 = snd_soc_codec_get_drvdata(codec);
- switch (level) {
- case SND_SOC_BIAS_ON:
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8995->supplies),
- wm8995->supplies);
- if (ret)
- return ret;
-
- ret = regcache_sync(wm8995->regmap);
- if (ret) {
- dev_err(codec->dev,
- "Failed to sync cache: %d\n", ret);
- return ret;
- }
-
- snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
- WM8995_BG_ENA_MASK, WM8995_BG_ENA);
- }
- break;
- case SND_SOC_BIAS_OFF:
- snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
- WM8995_BG_ENA_MASK, 0);
- regulator_bulk_disable(ARRAY_SIZE(wm8995->supplies),
- wm8995->supplies);
- break;
- }
-
- codec->dapm.bias_level = level;
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int wm8995_suspend(struct snd_soc_codec *codec)
-{
- wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm8995_resume(struct snd_soc_codec *codec)
-{
- wm8995_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-#else
-#define wm8995_suspend NULL
-#define wm8995_resume NULL
-#endif
-
-static int wm8995_remove(struct snd_soc_codec *codec)
-{
- struct wm8995_priv *wm8995;
- int i;
-
- wm8995 = snd_soc_codec_get_drvdata(codec);
- wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- for (i = 0; i < ARRAY_SIZE(wm8995->supplies); ++i)
- regulator_unregister_notifier(wm8995->supplies[i].consumer,
- &wm8995->disable_nb[i]);
-
- regulator_bulk_free(ARRAY_SIZE(wm8995->supplies), wm8995->supplies);
- return 0;
-}
-
-static int wm8995_probe(struct snd_soc_codec *codec)
-{
- struct wm8995_priv *wm8995;
- int i;
- int ret;
-
- wm8995 = snd_soc_codec_get_drvdata(codec);
- wm8995->codec = codec;
-
- codec->control_data = wm8995->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
- return ret;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm8995->supplies); i++)
- wm8995->supplies[i].supply = wm8995_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8995->supplies),
- wm8995->supplies);
- if (ret) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- return ret;
- }
-
- wm8995->disable_nb[0].notifier_call = wm8995_regulator_event_0;
- wm8995->disable_nb[1].notifier_call = wm8995_regulator_event_1;
- wm8995->disable_nb[2].notifier_call = wm8995_regulator_event_2;
- wm8995->disable_nb[3].notifier_call = wm8995_regulator_event_3;
- wm8995->disable_nb[4].notifier_call = wm8995_regulator_event_4;
- wm8995->disable_nb[5].notifier_call = wm8995_regulator_event_5;
- wm8995->disable_nb[6].notifier_call = wm8995_regulator_event_6;
- wm8995->disable_nb[7].notifier_call = wm8995_regulator_event_7;
-
- /* This should really be moved into the regulator core */
- for (i = 0; i < ARRAY_SIZE(wm8995->supplies); i++) {
- ret = regulator_register_notifier(wm8995->supplies[i].consumer,
- &wm8995->disable_nb[i]);
- if (ret) {
- dev_err(codec->dev,
- "Failed to register regulator notifier: %d\n",
- ret);
- }
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8995->supplies),
- wm8995->supplies);
- if (ret) {
- dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
- goto err_reg_get;
- }
-
- ret = snd_soc_read(codec, WM8995_SOFTWARE_RESET);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to read device ID: %d\n", ret);
- goto err_reg_enable;
- }
-
- if (ret != 0x8995) {
- dev_err(codec->dev, "Invalid device ID: %#x\n", ret);
- ret = -EINVAL;
- goto err_reg_enable;
- }
-
- ret = snd_soc_write(codec, WM8995_SOFTWARE_RESET, 0);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
- goto err_reg_enable;
- }
-
- wm8995_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* Latch volume updates (right only; we always do left then right). */
- snd_soc_update_bits(codec, WM8995_AIF1_DAC1_RIGHT_VOLUME,
- WM8995_AIF1DAC1_VU_MASK, WM8995_AIF1DAC1_VU);
- snd_soc_update_bits(codec, WM8995_AIF1_DAC2_RIGHT_VOLUME,
- WM8995_AIF1DAC2_VU_MASK, WM8995_AIF1DAC2_VU);
- snd_soc_update_bits(codec, WM8995_AIF2_DAC_RIGHT_VOLUME,
- WM8995_AIF2DAC_VU_MASK, WM8995_AIF2DAC_VU);
- snd_soc_update_bits(codec, WM8995_AIF1_ADC1_RIGHT_VOLUME,
- WM8995_AIF1ADC1_VU_MASK, WM8995_AIF1ADC1_VU);
- snd_soc_update_bits(codec, WM8995_AIF1_ADC2_RIGHT_VOLUME,
- WM8995_AIF1ADC2_VU_MASK, WM8995_AIF1ADC2_VU);
- snd_soc_update_bits(codec, WM8995_AIF2_ADC_RIGHT_VOLUME,
- WM8995_AIF2ADC_VU_MASK, WM8995_AIF1ADC2_VU);
- snd_soc_update_bits(codec, WM8995_DAC1_RIGHT_VOLUME,
- WM8995_DAC1_VU_MASK, WM8995_DAC1_VU);
- snd_soc_update_bits(codec, WM8995_DAC2_RIGHT_VOLUME,
- WM8995_DAC2_VU_MASK, WM8995_DAC2_VU);
- snd_soc_update_bits(codec, WM8995_RIGHT_LINE_INPUT_1_VOLUME,
- WM8995_IN1_VU_MASK, WM8995_IN1_VU);
-
- wm8995_update_class_w(codec);
-
- snd_soc_add_codec_controls(codec, wm8995_snd_controls,
- ARRAY_SIZE(wm8995_snd_controls));
- snd_soc_dapm_new_controls(&codec->dapm, wm8995_dapm_widgets,
- ARRAY_SIZE(wm8995_dapm_widgets));
- snd_soc_dapm_add_routes(&codec->dapm, wm8995_intercon,
- ARRAY_SIZE(wm8995_intercon));
-
- return 0;
-
-err_reg_enable:
- regulator_bulk_disable(ARRAY_SIZE(wm8995->supplies), wm8995->supplies);
-err_reg_get:
- regulator_bulk_free(ARRAY_SIZE(wm8995->supplies), wm8995->supplies);
- return ret;
-}
-
-#define WM8995_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops wm8995_aif1_dai_ops = {
- .set_sysclk = wm8995_set_dai_sysclk,
- .set_fmt = wm8995_set_dai_fmt,
- .hw_params = wm8995_hw_params,
- .digital_mute = wm8995_aif_mute,
- .set_pll = wm8995_set_fll,
- .set_tristate = wm8995_set_tristate,
-};
-
-static const struct snd_soc_dai_ops wm8995_aif2_dai_ops = {
- .set_sysclk = wm8995_set_dai_sysclk,
- .set_fmt = wm8995_set_dai_fmt,
- .hw_params = wm8995_hw_params,
- .digital_mute = wm8995_aif_mute,
- .set_pll = wm8995_set_fll,
- .set_tristate = wm8995_set_tristate,
-};
-
-static const struct snd_soc_dai_ops wm8995_aif3_dai_ops = {
- .set_tristate = wm8995_set_tristate,
-};
-
-static struct snd_soc_dai_driver wm8995_dai[] = {
- {
- .name = "wm8995-aif1",
- .playback = {
- .stream_name = "AIF1 Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = WM8995_FORMATS
- },
- .capture = {
- .stream_name = "AIF1 Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = WM8995_FORMATS
- },
- .ops = &wm8995_aif1_dai_ops
- },
- {
- .name = "wm8995-aif2",
- .playback = {
- .stream_name = "AIF2 Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = WM8995_FORMATS
- },
- .capture = {
- .stream_name = "AIF2 Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = WM8995_FORMATS
- },
- .ops = &wm8995_aif2_dai_ops
- },
- {
- .name = "wm8995-aif3",
- .playback = {
- .stream_name = "AIF3 Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = WM8995_FORMATS
- },
- .capture = {
- .stream_name = "AIF3 Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = WM8995_FORMATS
- },
- .ops = &wm8995_aif3_dai_ops
- }
-};
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8995 = {
- .probe = wm8995_probe,
- .remove = wm8995_remove,
- .suspend = wm8995_suspend,
- .resume = wm8995_resume,
- .set_bias_level = wm8995_set_bias_level,
- .idle_bias_off = true,
-};
-
-static struct regmap_config wm8995_regmap = {
- .reg_bits = 16,
- .val_bits = 16,
-
- .max_register = WM8995_MAX_REGISTER,
- .reg_defaults = wm8995_reg_defaults,
- .num_reg_defaults = ARRAY_SIZE(wm8995_reg_defaults),
- .volatile_reg = wm8995_volatile,
- .readable_reg = wm8995_readable,
- .cache_type = REGCACHE_RBTREE,
-};
-
-#if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8995_spi_probe(struct spi_device *spi)
-{
- struct wm8995_priv *wm8995;
- int ret;
-
- wm8995 = kzalloc(sizeof *wm8995, GFP_KERNEL);
- if (!wm8995)
- return -ENOMEM;
-
- spi_set_drvdata(spi, wm8995);
-
- wm8995->regmap = regmap_init_spi(spi, &wm8995_regmap);
- if (IS_ERR(wm8995->regmap)) {
- ret = PTR_ERR(wm8995->regmap);
- dev_err(&spi->dev, "Failed to register regmap: %d\n", ret);
- goto err_alloc;
- }
-
- ret = snd_soc_register_codec(&spi->dev,
- &soc_codec_dev_wm8995, wm8995_dai,
- ARRAY_SIZE(wm8995_dai));
- if (ret < 0)
- goto err_regmap;
-
- return ret;
-
-err_regmap:
- regmap_exit(wm8995->regmap);
-err_alloc:
- kfree(wm8995);
-
- return ret;
-}
-
-static int __devexit wm8995_spi_remove(struct spi_device *spi)
-{
- struct wm8995_priv *wm8995 = spi_get_drvdata(spi);
- snd_soc_unregister_codec(&spi->dev);
- regmap_exit(wm8995->regmap);
- kfree(wm8995);
- return 0;
-}
-
-static struct spi_driver wm8995_spi_driver = {
- .driver = {
- .name = "wm8995",
- .owner = THIS_MODULE,
- },
- .probe = wm8995_spi_probe,
- .remove = __devexit_p(wm8995_spi_remove)
-};
-#endif
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8995_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8995_priv *wm8995;
- int ret;
-
- wm8995 = kzalloc(sizeof *wm8995, GFP_KERNEL);
- if (!wm8995)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm8995);
-
- wm8995->regmap = regmap_init_i2c(i2c, &wm8995_regmap);
- if (IS_ERR(wm8995->regmap)) {
- ret = PTR_ERR(wm8995->regmap);
- dev_err(&i2c->dev, "Failed to register regmap: %d\n", ret);
- goto err_alloc;
- }
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8995, wm8995_dai,
- ARRAY_SIZE(wm8995_dai));
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
- goto err_regmap;
- }
-
- return ret;
-
-err_regmap:
- regmap_exit(wm8995->regmap);
-err_alloc:
- kfree(wm8995);
-
- return ret;
-}
-
-static __devexit int wm8995_i2c_remove(struct i2c_client *client)
-{
- struct wm8995_priv *wm8995 = i2c_get_clientdata(client);
-
- snd_soc_unregister_codec(&client->dev);
- regmap_exit(wm8995->regmap);
- kfree(wm8995);
- return 0;
-}
-
-static const struct i2c_device_id wm8995_i2c_id[] = {
- {"wm8995", 0},
- {}
-};
-
-MODULE_DEVICE_TABLE(i2c, wm8995_i2c_id);
-
-static struct i2c_driver wm8995_i2c_driver = {
- .driver = {
- .name = "wm8995",
- .owner = THIS_MODULE,
- },
- .probe = wm8995_i2c_probe,
- .remove = __devexit_p(wm8995_i2c_remove),
- .id_table = wm8995_i2c_id
-};
-#endif
-
-static int __init wm8995_modinit(void)
-{
- int ret = 0;
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- ret = i2c_add_driver(&wm8995_i2c_driver);
- if (ret) {
- printk(KERN_ERR "Failed to register wm8995 I2C driver: %d\n",
- ret);
- }
-#endif
-#if defined(CONFIG_SPI_MASTER)
- ret = spi_register_driver(&wm8995_spi_driver);
- if (ret) {
- printk(KERN_ERR "Failed to register wm8995 SPI driver: %d\n",
- ret);
- }
-#endif
- return ret;
-}
-
-module_init(wm8995_modinit);
-
-static void __exit wm8995_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&wm8995_i2c_driver);
-#endif
-#if defined(CONFIG_SPI_MASTER)
- spi_unregister_driver(&wm8995_spi_driver);
-#endif
-}
-
-module_exit(wm8995_exit);
-
-MODULE_DESCRIPTION("ASoC WM8995 driver");
-MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8995.h b/ANDROID_3.4.5/sound/soc/codecs/wm8995.h
deleted file mode 100644
index 5642121c..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8995.h
+++ /dev/null
@@ -1,4269 +0,0 @@
-/*
- * wm8995.h -- WM8995 ALSA SoC Audio driver
- *
- * Copyright 2010 Wolfson Microelectronics plc
- *
- * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM8995_H
-#define _WM8995_H
-
-#include <asm/types.h>
-
-/*
- * Register values.
- */
-#define WM8995_SOFTWARE_RESET 0x00
-#define WM8995_POWER_MANAGEMENT_1 0x01
-#define WM8995_POWER_MANAGEMENT_2 0x02
-#define WM8995_POWER_MANAGEMENT_3 0x03
-#define WM8995_POWER_MANAGEMENT_4 0x04
-#define WM8995_POWER_MANAGEMENT_5 0x05
-#define WM8995_LEFT_LINE_INPUT_1_VOLUME 0x10
-#define WM8995_RIGHT_LINE_INPUT_1_VOLUME 0x11
-#define WM8995_LEFT_LINE_INPUT_CONTROL 0x12
-#define WM8995_DAC1_LEFT_VOLUME 0x18
-#define WM8995_DAC1_RIGHT_VOLUME 0x19
-#define WM8995_DAC2_LEFT_VOLUME 0x1A
-#define WM8995_DAC2_RIGHT_VOLUME 0x1B
-#define WM8995_OUTPUT_VOLUME_ZC_1 0x1C
-#define WM8995_MICBIAS_1 0x20
-#define WM8995_MICBIAS_2 0x21
-#define WM8995_LDO_1 0x28
-#define WM8995_LDO_2 0x29
-#define WM8995_ACCESSORY_DETECT_MODE1 0x30
-#define WM8995_ACCESSORY_DETECT_MODE2 0x31
-#define WM8995_HEADPHONE_DETECT1 0x34
-#define WM8995_HEADPHONE_DETECT2 0x35
-#define WM8995_MIC_DETECT_1 0x38
-#define WM8995_MIC_DETECT_2 0x39
-#define WM8995_CHARGE_PUMP_1 0x40
-#define WM8995_CLASS_W_1 0x45
-#define WM8995_DC_SERVO_1 0x50
-#define WM8995_DC_SERVO_2 0x51
-#define WM8995_DC_SERVO_3 0x52
-#define WM8995_DC_SERVO_5 0x54
-#define WM8995_DC_SERVO_6 0x55
-#define WM8995_DC_SERVO_7 0x56
-#define WM8995_DC_SERVO_READBACK_0 0x57
-#define WM8995_ANALOGUE_HP_1 0x60
-#define WM8995_ANALOGUE_HP_2 0x61
-#define WM8995_CHIP_REVISION 0x100
-#define WM8995_CONTROL_INTERFACE_1 0x101
-#define WM8995_CONTROL_INTERFACE_2 0x102
-#define WM8995_WRITE_SEQUENCER_CTRL_1 0x110
-#define WM8995_WRITE_SEQUENCER_CTRL_2 0x111
-#define WM8995_AIF1_CLOCKING_1 0x200
-#define WM8995_AIF1_CLOCKING_2 0x201
-#define WM8995_AIF2_CLOCKING_1 0x204
-#define WM8995_AIF2_CLOCKING_2 0x205
-#define WM8995_CLOCKING_1 0x208
-#define WM8995_CLOCKING_2 0x209
-#define WM8995_AIF1_RATE 0x210
-#define WM8995_AIF2_RATE 0x211
-#define WM8995_RATE_STATUS 0x212
-#define WM8995_FLL1_CONTROL_1 0x220
-#define WM8995_FLL1_CONTROL_2 0x221
-#define WM8995_FLL1_CONTROL_3 0x222
-#define WM8995_FLL1_CONTROL_4 0x223
-#define WM8995_FLL1_CONTROL_5 0x224
-#define WM8995_FLL2_CONTROL_1 0x240
-#define WM8995_FLL2_CONTROL_2 0x241
-#define WM8995_FLL2_CONTROL_3 0x242
-#define WM8995_FLL2_CONTROL_4 0x243
-#define WM8995_FLL2_CONTROL_5 0x244
-#define WM8995_AIF1_CONTROL_1 0x300
-#define WM8995_AIF1_CONTROL_2 0x301
-#define WM8995_AIF1_MASTER_SLAVE 0x302
-#define WM8995_AIF1_BCLK 0x303
-#define WM8995_AIF1ADC_LRCLK 0x304
-#define WM8995_AIF1DAC_LRCLK 0x305
-#define WM8995_AIF1DAC_DATA 0x306
-#define WM8995_AIF1ADC_DATA 0x307
-#define WM8995_AIF2_CONTROL_1 0x310
-#define WM8995_AIF2_CONTROL_2 0x311
-#define WM8995_AIF2_MASTER_SLAVE 0x312
-#define WM8995_AIF2_BCLK 0x313
-#define WM8995_AIF2ADC_LRCLK 0x314
-#define WM8995_AIF2DAC_LRCLK 0x315
-#define WM8995_AIF2DAC_DATA 0x316
-#define WM8995_AIF2ADC_DATA 0x317
-#define WM8995_AIF1_ADC1_LEFT_VOLUME 0x400
-#define WM8995_AIF1_ADC1_RIGHT_VOLUME 0x401
-#define WM8995_AIF1_DAC1_LEFT_VOLUME 0x402
-#define WM8995_AIF1_DAC1_RIGHT_VOLUME 0x403
-#define WM8995_AIF1_ADC2_LEFT_VOLUME 0x404
-#define WM8995_AIF1_ADC2_RIGHT_VOLUME 0x405
-#define WM8995_AIF1_DAC2_LEFT_VOLUME 0x406
-#define WM8995_AIF1_DAC2_RIGHT_VOLUME 0x407
-#define WM8995_AIF1_ADC1_FILTERS 0x410
-#define WM8995_AIF1_ADC2_FILTERS 0x411
-#define WM8995_AIF1_DAC1_FILTERS_1 0x420
-#define WM8995_AIF1_DAC1_FILTERS_2 0x421
-#define WM8995_AIF1_DAC2_FILTERS_1 0x422
-#define WM8995_AIF1_DAC2_FILTERS_2 0x423
-#define WM8995_AIF1_DRC1_1 0x440
-#define WM8995_AIF1_DRC1_2 0x441
-#define WM8995_AIF1_DRC1_3 0x442
-#define WM8995_AIF1_DRC1_4 0x443
-#define WM8995_AIF1_DRC1_5 0x444
-#define WM8995_AIF1_DRC2_1 0x450
-#define WM8995_AIF1_DRC2_2 0x451
-#define WM8995_AIF1_DRC2_3 0x452
-#define WM8995_AIF1_DRC2_4 0x453
-#define WM8995_AIF1_DRC2_5 0x454
-#define WM8995_AIF1_DAC1_EQ_GAINS_1 0x480
-#define WM8995_AIF1_DAC1_EQ_GAINS_2 0x481
-#define WM8995_AIF1_DAC1_EQ_BAND_1_A 0x482
-#define WM8995_AIF1_DAC1_EQ_BAND_1_B 0x483
-#define WM8995_AIF1_DAC1_EQ_BAND_1_PG 0x484
-#define WM8995_AIF1_DAC1_EQ_BAND_2_A 0x485
-#define WM8995_AIF1_DAC1_EQ_BAND_2_B 0x486
-#define WM8995_AIF1_DAC1_EQ_BAND_2_C 0x487
-#define WM8995_AIF1_DAC1_EQ_BAND_2_PG 0x488
-#define WM8995_AIF1_DAC1_EQ_BAND_3_A 0x489
-#define WM8995_AIF1_DAC1_EQ_BAND_3_B 0x48A
-#define WM8995_AIF1_DAC1_EQ_BAND_3_C 0x48B
-#define WM8995_AIF1_DAC1_EQ_BAND_3_PG 0x48C
-#define WM8995_AIF1_DAC1_EQ_BAND_4_A 0x48D
-#define WM8995_AIF1_DAC1_EQ_BAND_4_B 0x48E
-#define WM8995_AIF1_DAC1_EQ_BAND_4_C 0x48F
-#define WM8995_AIF1_DAC1_EQ_BAND_4_PG 0x490
-#define WM8995_AIF1_DAC1_EQ_BAND_5_A 0x491
-#define WM8995_AIF1_DAC1_EQ_BAND_5_B 0x492
-#define WM8995_AIF1_DAC1_EQ_BAND_5_PG 0x493
-#define WM8995_AIF1_DAC2_EQ_GAINS_1 0x4A0
-#define WM8995_AIF1_DAC2_EQ_GAINS_2 0x4A1
-#define WM8995_AIF1_DAC2_EQ_BAND_1_A 0x4A2
-#define WM8995_AIF1_DAC2_EQ_BAND_1_B 0x4A3
-#define WM8995_AIF1_DAC2_EQ_BAND_1_PG 0x4A4
-#define WM8995_AIF1_DAC2_EQ_BAND_2_A 0x4A5
-#define WM8995_AIF1_DAC2_EQ_BAND_2_B 0x4A6
-#define WM8995_AIF1_DAC2_EQ_BAND_2_C 0x4A7
-#define WM8995_AIF1_DAC2_EQ_BAND_2_PG 0x4A8
-#define WM8995_AIF1_DAC2_EQ_BAND_3_A 0x4A9
-#define WM8995_AIF1_DAC2_EQ_BAND_3_B 0x4AA
-#define WM8995_AIF1_DAC2_EQ_BAND_3_C 0x4AB
-#define WM8995_AIF1_DAC2_EQ_BAND_3_PG 0x4AC
-#define WM8995_AIF1_DAC2_EQ_BAND_4_A 0x4AD
-#define WM8995_AIF1_DAC2_EQ_BAND_4_B 0x4AE
-#define WM8995_AIF1_DAC2_EQ_BAND_4_C 0x4AF
-#define WM8995_AIF1_DAC2_EQ_BAND_4_PG 0x4B0
-#define WM8995_AIF1_DAC2_EQ_BAND_5_A 0x4B1
-#define WM8995_AIF1_DAC2_EQ_BAND_5_B 0x4B2
-#define WM8995_AIF1_DAC2_EQ_BAND_5_PG 0x4B3
-#define WM8995_AIF2_ADC_LEFT_VOLUME 0x500
-#define WM8995_AIF2_ADC_RIGHT_VOLUME 0x501
-#define WM8995_AIF2_DAC_LEFT_VOLUME 0x502
-#define WM8995_AIF2_DAC_RIGHT_VOLUME 0x503
-#define WM8995_AIF2_ADC_FILTERS 0x510
-#define WM8995_AIF2_DAC_FILTERS_1 0x520
-#define WM8995_AIF2_DAC_FILTERS_2 0x521
-#define WM8995_AIF2_DRC_1 0x540
-#define WM8995_AIF2_DRC_2 0x541
-#define WM8995_AIF2_DRC_3 0x542
-#define WM8995_AIF2_DRC_4 0x543
-#define WM8995_AIF2_DRC_5 0x544
-#define WM8995_AIF2_EQ_GAINS_1 0x580
-#define WM8995_AIF2_EQ_GAINS_2 0x581
-#define WM8995_AIF2_EQ_BAND_1_A 0x582
-#define WM8995_AIF2_EQ_BAND_1_B 0x583
-#define WM8995_AIF2_EQ_BAND_1_PG 0x584
-#define WM8995_AIF2_EQ_BAND_2_A 0x585
-#define WM8995_AIF2_EQ_BAND_2_B 0x586
-#define WM8995_AIF2_EQ_BAND_2_C 0x587
-#define WM8995_AIF2_EQ_BAND_2_PG 0x588
-#define WM8995_AIF2_EQ_BAND_3_A 0x589
-#define WM8995_AIF2_EQ_BAND_3_B 0x58A
-#define WM8995_AIF2_EQ_BAND_3_C 0x58B
-#define WM8995_AIF2_EQ_BAND_3_PG 0x58C
-#define WM8995_AIF2_EQ_BAND_4_A 0x58D
-#define WM8995_AIF2_EQ_BAND_4_B 0x58E
-#define WM8995_AIF2_EQ_BAND_4_C 0x58F
-#define WM8995_AIF2_EQ_BAND_4_PG 0x590
-#define WM8995_AIF2_EQ_BAND_5_A 0x591
-#define WM8995_AIF2_EQ_BAND_5_B 0x592
-#define WM8995_AIF2_EQ_BAND_5_PG 0x593
-#define WM8995_DAC1_MIXER_VOLUMES 0x600
-#define WM8995_DAC1_LEFT_MIXER_ROUTING 0x601
-#define WM8995_DAC1_RIGHT_MIXER_ROUTING 0x602
-#define WM8995_DAC2_MIXER_VOLUMES 0x603
-#define WM8995_DAC2_LEFT_MIXER_ROUTING 0x604
-#define WM8995_DAC2_RIGHT_MIXER_ROUTING 0x605
-#define WM8995_AIF1_ADC1_LEFT_MIXER_ROUTING 0x606
-#define WM8995_AIF1_ADC1_RIGHT_MIXER_ROUTING 0x607
-#define WM8995_AIF1_ADC2_LEFT_MIXER_ROUTING 0x608
-#define WM8995_AIF1_ADC2_RIGHT_MIXER_ROUTING 0x609
-#define WM8995_DAC_SOFTMUTE 0x610
-#define WM8995_OVERSAMPLING 0x620
-#define WM8995_SIDETONE 0x621
-#define WM8995_GPIO_1 0x700
-#define WM8995_GPIO_2 0x701
-#define WM8995_GPIO_3 0x702
-#define WM8995_GPIO_4 0x703
-#define WM8995_GPIO_5 0x704
-#define WM8995_GPIO_6 0x705
-#define WM8995_GPIO_7 0x706
-#define WM8995_GPIO_8 0x707
-#define WM8995_GPIO_9 0x708
-#define WM8995_GPIO_10 0x709
-#define WM8995_GPIO_11 0x70A
-#define WM8995_GPIO_12 0x70B
-#define WM8995_GPIO_13 0x70C
-#define WM8995_GPIO_14 0x70D
-#define WM8995_PULL_CONTROL_1 0x720
-#define WM8995_PULL_CONTROL_2 0x721
-#define WM8995_INTERRUPT_STATUS_1 0x730
-#define WM8995_INTERRUPT_STATUS_2 0x731
-#define WM8995_INTERRUPT_RAW_STATUS_2 0x732
-#define WM8995_INTERRUPT_STATUS_1_MASK 0x738
-#define WM8995_INTERRUPT_STATUS_2_MASK 0x739
-#define WM8995_INTERRUPT_CONTROL 0x740
-#define WM8995_LEFT_PDM_SPEAKER_1 0x800
-#define WM8995_RIGHT_PDM_SPEAKER_1 0x801
-#define WM8995_PDM_SPEAKER_1_MUTE_SEQUENCE 0x802
-#define WM8995_LEFT_PDM_SPEAKER_2 0x808
-#define WM8995_RIGHT_PDM_SPEAKER_2 0x809
-#define WM8995_PDM_SPEAKER_2_MUTE_SEQUENCE 0x80A
-#define WM8995_WRITE_SEQUENCER_0 0x3000
-#define WM8995_WRITE_SEQUENCER_1 0x3001
-#define WM8995_WRITE_SEQUENCER_2 0x3002
-#define WM8995_WRITE_SEQUENCER_3 0x3003
-#define WM8995_WRITE_SEQUENCER_4 0x3004
-#define WM8995_WRITE_SEQUENCER_5 0x3005
-#define WM8995_WRITE_SEQUENCER_6 0x3006
-#define WM8995_WRITE_SEQUENCER_7 0x3007
-#define WM8995_WRITE_SEQUENCER_8 0x3008
-#define WM8995_WRITE_SEQUENCER_9 0x3009
-#define WM8995_WRITE_SEQUENCER_10 0x300A
-#define WM8995_WRITE_SEQUENCER_11 0x300B
-#define WM8995_WRITE_SEQUENCER_12 0x300C
-#define WM8995_WRITE_SEQUENCER_13 0x300D
-#define WM8995_WRITE_SEQUENCER_14 0x300E
-#define WM8995_WRITE_SEQUENCER_15 0x300F
-#define WM8995_WRITE_SEQUENCER_16 0x3010
-#define WM8995_WRITE_SEQUENCER_17 0x3011
-#define WM8995_WRITE_SEQUENCER_18 0x3012
-#define WM8995_WRITE_SEQUENCER_19 0x3013
-#define WM8995_WRITE_SEQUENCER_20 0x3014
-#define WM8995_WRITE_SEQUENCER_21 0x3015
-#define WM8995_WRITE_SEQUENCER_22 0x3016
-#define WM8995_WRITE_SEQUENCER_23 0x3017
-#define WM8995_WRITE_SEQUENCER_24 0x3018
-#define WM8995_WRITE_SEQUENCER_25 0x3019
-#define WM8995_WRITE_SEQUENCER_26 0x301A
-#define WM8995_WRITE_SEQUENCER_27 0x301B
-#define WM8995_WRITE_SEQUENCER_28 0x301C
-#define WM8995_WRITE_SEQUENCER_29 0x301D
-#define WM8995_WRITE_SEQUENCER_30 0x301E
-#define WM8995_WRITE_SEQUENCER_31 0x301F
-#define WM8995_WRITE_SEQUENCER_32 0x3020
-#define WM8995_WRITE_SEQUENCER_33 0x3021
-#define WM8995_WRITE_SEQUENCER_34 0x3022
-#define WM8995_WRITE_SEQUENCER_35 0x3023
-#define WM8995_WRITE_SEQUENCER_36 0x3024
-#define WM8995_WRITE_SEQUENCER_37 0x3025
-#define WM8995_WRITE_SEQUENCER_38 0x3026
-#define WM8995_WRITE_SEQUENCER_39 0x3027
-#define WM8995_WRITE_SEQUENCER_40 0x3028
-#define WM8995_WRITE_SEQUENCER_41 0x3029
-#define WM8995_WRITE_SEQUENCER_42 0x302A
-#define WM8995_WRITE_SEQUENCER_43 0x302B
-#define WM8995_WRITE_SEQUENCER_44 0x302C
-#define WM8995_WRITE_SEQUENCER_45 0x302D
-#define WM8995_WRITE_SEQUENCER_46 0x302E
-#define WM8995_WRITE_SEQUENCER_47 0x302F
-#define WM8995_WRITE_SEQUENCER_48 0x3030
-#define WM8995_WRITE_SEQUENCER_49 0x3031
-#define WM8995_WRITE_SEQUENCER_50 0x3032
-#define WM8995_WRITE_SEQUENCER_51 0x3033
-#define WM8995_WRITE_SEQUENCER_52 0x3034
-#define WM8995_WRITE_SEQUENCER_53 0x3035
-#define WM8995_WRITE_SEQUENCER_54 0x3036
-#define WM8995_WRITE_SEQUENCER_55 0x3037
-#define WM8995_WRITE_SEQUENCER_56 0x3038
-#define WM8995_WRITE_SEQUENCER_57 0x3039
-#define WM8995_WRITE_SEQUENCER_58 0x303A
-#define WM8995_WRITE_SEQUENCER_59 0x303B
-#define WM8995_WRITE_SEQUENCER_60 0x303C
-#define WM8995_WRITE_SEQUENCER_61 0x303D
-#define WM8995_WRITE_SEQUENCER_62 0x303E
-#define WM8995_WRITE_SEQUENCER_63 0x303F
-#define WM8995_WRITE_SEQUENCER_64 0x3040
-#define WM8995_WRITE_SEQUENCER_65 0x3041
-#define WM8995_WRITE_SEQUENCER_66 0x3042
-#define WM8995_WRITE_SEQUENCER_67 0x3043
-#define WM8995_WRITE_SEQUENCER_68 0x3044
-#define WM8995_WRITE_SEQUENCER_69 0x3045
-#define WM8995_WRITE_SEQUENCER_70 0x3046
-#define WM8995_WRITE_SEQUENCER_71 0x3047
-#define WM8995_WRITE_SEQUENCER_72 0x3048
-#define WM8995_WRITE_SEQUENCER_73 0x3049
-#define WM8995_WRITE_SEQUENCER_74 0x304A
-#define WM8995_WRITE_SEQUENCER_75 0x304B
-#define WM8995_WRITE_SEQUENCER_76 0x304C
-#define WM8995_WRITE_SEQUENCER_77 0x304D
-#define WM8995_WRITE_SEQUENCER_78 0x304E
-#define WM8995_WRITE_SEQUENCER_79 0x304F
-#define WM8995_WRITE_SEQUENCER_80 0x3050
-#define WM8995_WRITE_SEQUENCER_81 0x3051
-#define WM8995_WRITE_SEQUENCER_82 0x3052
-#define WM8995_WRITE_SEQUENCER_83 0x3053
-#define WM8995_WRITE_SEQUENCER_84 0x3054
-#define WM8995_WRITE_SEQUENCER_85 0x3055
-#define WM8995_WRITE_SEQUENCER_86 0x3056
-#define WM8995_WRITE_SEQUENCER_87 0x3057
-#define WM8995_WRITE_SEQUENCER_88 0x3058
-#define WM8995_WRITE_SEQUENCER_89 0x3059
-#define WM8995_WRITE_SEQUENCER_90 0x305A
-#define WM8995_WRITE_SEQUENCER_91 0x305B
-#define WM8995_WRITE_SEQUENCER_92 0x305C
-#define WM8995_WRITE_SEQUENCER_93 0x305D
-#define WM8995_WRITE_SEQUENCER_94 0x305E
-#define WM8995_WRITE_SEQUENCER_95 0x305F
-#define WM8995_WRITE_SEQUENCER_96 0x3060
-#define WM8995_WRITE_SEQUENCER_97 0x3061
-#define WM8995_WRITE_SEQUENCER_98 0x3062
-#define WM8995_WRITE_SEQUENCER_99 0x3063
-#define WM8995_WRITE_SEQUENCER_100 0x3064
-#define WM8995_WRITE_SEQUENCER_101 0x3065
-#define WM8995_WRITE_SEQUENCER_102 0x3066
-#define WM8995_WRITE_SEQUENCER_103 0x3067
-#define WM8995_WRITE_SEQUENCER_104 0x3068
-#define WM8995_WRITE_SEQUENCER_105 0x3069
-#define WM8995_WRITE_SEQUENCER_106 0x306A
-#define WM8995_WRITE_SEQUENCER_107 0x306B
-#define WM8995_WRITE_SEQUENCER_108 0x306C
-#define WM8995_WRITE_SEQUENCER_109 0x306D
-#define WM8995_WRITE_SEQUENCER_110 0x306E
-#define WM8995_WRITE_SEQUENCER_111 0x306F
-#define WM8995_WRITE_SEQUENCER_112 0x3070
-#define WM8995_WRITE_SEQUENCER_113 0x3071
-#define WM8995_WRITE_SEQUENCER_114 0x3072
-#define WM8995_WRITE_SEQUENCER_115 0x3073
-#define WM8995_WRITE_SEQUENCER_116 0x3074
-#define WM8995_WRITE_SEQUENCER_117 0x3075
-#define WM8995_WRITE_SEQUENCER_118 0x3076
-#define WM8995_WRITE_SEQUENCER_119 0x3077
-#define WM8995_WRITE_SEQUENCER_120 0x3078
-#define WM8995_WRITE_SEQUENCER_121 0x3079
-#define WM8995_WRITE_SEQUENCER_122 0x307A
-#define WM8995_WRITE_SEQUENCER_123 0x307B
-#define WM8995_WRITE_SEQUENCER_124 0x307C
-#define WM8995_WRITE_SEQUENCER_125 0x307D
-#define WM8995_WRITE_SEQUENCER_126 0x307E
-#define WM8995_WRITE_SEQUENCER_127 0x307F
-#define WM8995_WRITE_SEQUENCER_128 0x3080
-#define WM8995_WRITE_SEQUENCER_129 0x3081
-#define WM8995_WRITE_SEQUENCER_130 0x3082
-#define WM8995_WRITE_SEQUENCER_131 0x3083
-#define WM8995_WRITE_SEQUENCER_132 0x3084
-#define WM8995_WRITE_SEQUENCER_133 0x3085
-#define WM8995_WRITE_SEQUENCER_134 0x3086
-#define WM8995_WRITE_SEQUENCER_135 0x3087
-#define WM8995_WRITE_SEQUENCER_136 0x3088
-#define WM8995_WRITE_SEQUENCER_137 0x3089
-#define WM8995_WRITE_SEQUENCER_138 0x308A
-#define WM8995_WRITE_SEQUENCER_139 0x308B
-#define WM8995_WRITE_SEQUENCER_140 0x308C
-#define WM8995_WRITE_SEQUENCER_141 0x308D
-#define WM8995_WRITE_SEQUENCER_142 0x308E
-#define WM8995_WRITE_SEQUENCER_143 0x308F
-#define WM8995_WRITE_SEQUENCER_144 0x3090
-#define WM8995_WRITE_SEQUENCER_145 0x3091
-#define WM8995_WRITE_SEQUENCER_146 0x3092
-#define WM8995_WRITE_SEQUENCER_147 0x3093
-#define WM8995_WRITE_SEQUENCER_148 0x3094
-#define WM8995_WRITE_SEQUENCER_149 0x3095
-#define WM8995_WRITE_SEQUENCER_150 0x3096
-#define WM8995_WRITE_SEQUENCER_151 0x3097
-#define WM8995_WRITE_SEQUENCER_152 0x3098
-#define WM8995_WRITE_SEQUENCER_153 0x3099
-#define WM8995_WRITE_SEQUENCER_154 0x309A
-#define WM8995_WRITE_SEQUENCER_155 0x309B
-#define WM8995_WRITE_SEQUENCER_156 0x309C
-#define WM8995_WRITE_SEQUENCER_157 0x309D
-#define WM8995_WRITE_SEQUENCER_158 0x309E
-#define WM8995_WRITE_SEQUENCER_159 0x309F
-#define WM8995_WRITE_SEQUENCER_160 0x30A0
-#define WM8995_WRITE_SEQUENCER_161 0x30A1
-#define WM8995_WRITE_SEQUENCER_162 0x30A2
-#define WM8995_WRITE_SEQUENCER_163 0x30A3
-#define WM8995_WRITE_SEQUENCER_164 0x30A4
-#define WM8995_WRITE_SEQUENCER_165 0x30A5
-#define WM8995_WRITE_SEQUENCER_166 0x30A6
-#define WM8995_WRITE_SEQUENCER_167 0x30A7
-#define WM8995_WRITE_SEQUENCER_168 0x30A8
-#define WM8995_WRITE_SEQUENCER_169 0x30A9
-#define WM8995_WRITE_SEQUENCER_170 0x30AA
-#define WM8995_WRITE_SEQUENCER_171 0x30AB
-#define WM8995_WRITE_SEQUENCER_172 0x30AC
-#define WM8995_WRITE_SEQUENCER_173 0x30AD
-#define WM8995_WRITE_SEQUENCER_174 0x30AE
-#define WM8995_WRITE_SEQUENCER_175 0x30AF
-#define WM8995_WRITE_SEQUENCER_176 0x30B0
-#define WM8995_WRITE_SEQUENCER_177 0x30B1
-#define WM8995_WRITE_SEQUENCER_178 0x30B2
-#define WM8995_WRITE_SEQUENCER_179 0x30B3
-#define WM8995_WRITE_SEQUENCER_180 0x30B4
-#define WM8995_WRITE_SEQUENCER_181 0x30B5
-#define WM8995_WRITE_SEQUENCER_182 0x30B6
-#define WM8995_WRITE_SEQUENCER_183 0x30B7
-#define WM8995_WRITE_SEQUENCER_184 0x30B8
-#define WM8995_WRITE_SEQUENCER_185 0x30B9
-#define WM8995_WRITE_SEQUENCER_186 0x30BA
-#define WM8995_WRITE_SEQUENCER_187 0x30BB
-#define WM8995_WRITE_SEQUENCER_188 0x30BC
-#define WM8995_WRITE_SEQUENCER_189 0x30BD
-#define WM8995_WRITE_SEQUENCER_190 0x30BE
-#define WM8995_WRITE_SEQUENCER_191 0x30BF
-#define WM8995_WRITE_SEQUENCER_192 0x30C0
-#define WM8995_WRITE_SEQUENCER_193 0x30C1
-#define WM8995_WRITE_SEQUENCER_194 0x30C2
-#define WM8995_WRITE_SEQUENCER_195 0x30C3
-#define WM8995_WRITE_SEQUENCER_196 0x30C4
-#define WM8995_WRITE_SEQUENCER_197 0x30C5
-#define WM8995_WRITE_SEQUENCER_198 0x30C6
-#define WM8995_WRITE_SEQUENCER_199 0x30C7
-#define WM8995_WRITE_SEQUENCER_200 0x30C8
-#define WM8995_WRITE_SEQUENCER_201 0x30C9
-#define WM8995_WRITE_SEQUENCER_202 0x30CA
-#define WM8995_WRITE_SEQUENCER_203 0x30CB
-#define WM8995_WRITE_SEQUENCER_204 0x30CC
-#define WM8995_WRITE_SEQUENCER_205 0x30CD
-#define WM8995_WRITE_SEQUENCER_206 0x30CE
-#define WM8995_WRITE_SEQUENCER_207 0x30CF
-#define WM8995_WRITE_SEQUENCER_208 0x30D0
-#define WM8995_WRITE_SEQUENCER_209 0x30D1
-#define WM8995_WRITE_SEQUENCER_210 0x30D2
-#define WM8995_WRITE_SEQUENCER_211 0x30D3
-#define WM8995_WRITE_SEQUENCER_212 0x30D4
-#define WM8995_WRITE_SEQUENCER_213 0x30D5
-#define WM8995_WRITE_SEQUENCER_214 0x30D6
-#define WM8995_WRITE_SEQUENCER_215 0x30D7
-#define WM8995_WRITE_SEQUENCER_216 0x30D8
-#define WM8995_WRITE_SEQUENCER_217 0x30D9
-#define WM8995_WRITE_SEQUENCER_218 0x30DA
-#define WM8995_WRITE_SEQUENCER_219 0x30DB
-#define WM8995_WRITE_SEQUENCER_220 0x30DC
-#define WM8995_WRITE_SEQUENCER_221 0x30DD
-#define WM8995_WRITE_SEQUENCER_222 0x30DE
-#define WM8995_WRITE_SEQUENCER_223 0x30DF
-#define WM8995_WRITE_SEQUENCER_224 0x30E0
-#define WM8995_WRITE_SEQUENCER_225 0x30E1
-#define WM8995_WRITE_SEQUENCER_226 0x30E2
-#define WM8995_WRITE_SEQUENCER_227 0x30E3
-#define WM8995_WRITE_SEQUENCER_228 0x30E4
-#define WM8995_WRITE_SEQUENCER_229 0x30E5
-#define WM8995_WRITE_SEQUENCER_230 0x30E6
-#define WM8995_WRITE_SEQUENCER_231 0x30E7
-#define WM8995_WRITE_SEQUENCER_232 0x30E8
-#define WM8995_WRITE_SEQUENCER_233 0x30E9
-#define WM8995_WRITE_SEQUENCER_234 0x30EA
-#define WM8995_WRITE_SEQUENCER_235 0x30EB
-#define WM8995_WRITE_SEQUENCER_236 0x30EC
-#define WM8995_WRITE_SEQUENCER_237 0x30ED
-#define WM8995_WRITE_SEQUENCER_238 0x30EE
-#define WM8995_WRITE_SEQUENCER_239 0x30EF
-#define WM8995_WRITE_SEQUENCER_240 0x30F0
-#define WM8995_WRITE_SEQUENCER_241 0x30F1
-#define WM8995_WRITE_SEQUENCER_242 0x30F2
-#define WM8995_WRITE_SEQUENCER_243 0x30F3
-#define WM8995_WRITE_SEQUENCER_244 0x30F4
-#define WM8995_WRITE_SEQUENCER_245 0x30F5
-#define WM8995_WRITE_SEQUENCER_246 0x30F6
-#define WM8995_WRITE_SEQUENCER_247 0x30F7
-#define WM8995_WRITE_SEQUENCER_248 0x30F8
-#define WM8995_WRITE_SEQUENCER_249 0x30F9
-#define WM8995_WRITE_SEQUENCER_250 0x30FA
-#define WM8995_WRITE_SEQUENCER_251 0x30FB
-#define WM8995_WRITE_SEQUENCER_252 0x30FC
-#define WM8995_WRITE_SEQUENCER_253 0x30FD
-#define WM8995_WRITE_SEQUENCER_254 0x30FE
-#define WM8995_WRITE_SEQUENCER_255 0x30FF
-#define WM8995_WRITE_SEQUENCER_256 0x3100
-#define WM8995_WRITE_SEQUENCER_257 0x3101
-#define WM8995_WRITE_SEQUENCER_258 0x3102
-#define WM8995_WRITE_SEQUENCER_259 0x3103
-#define WM8995_WRITE_SEQUENCER_260 0x3104
-#define WM8995_WRITE_SEQUENCER_261 0x3105
-#define WM8995_WRITE_SEQUENCER_262 0x3106
-#define WM8995_WRITE_SEQUENCER_263 0x3107
-#define WM8995_WRITE_SEQUENCER_264 0x3108
-#define WM8995_WRITE_SEQUENCER_265 0x3109
-#define WM8995_WRITE_SEQUENCER_266 0x310A
-#define WM8995_WRITE_SEQUENCER_267 0x310B
-#define WM8995_WRITE_SEQUENCER_268 0x310C
-#define WM8995_WRITE_SEQUENCER_269 0x310D
-#define WM8995_WRITE_SEQUENCER_270 0x310E
-#define WM8995_WRITE_SEQUENCER_271 0x310F
-#define WM8995_WRITE_SEQUENCER_272 0x3110
-#define WM8995_WRITE_SEQUENCER_273 0x3111
-#define WM8995_WRITE_SEQUENCER_274 0x3112
-#define WM8995_WRITE_SEQUENCER_275 0x3113
-#define WM8995_WRITE_SEQUENCER_276 0x3114
-#define WM8995_WRITE_SEQUENCER_277 0x3115
-#define WM8995_WRITE_SEQUENCER_278 0x3116
-#define WM8995_WRITE_SEQUENCER_279 0x3117
-#define WM8995_WRITE_SEQUENCER_280 0x3118
-#define WM8995_WRITE_SEQUENCER_281 0x3119
-#define WM8995_WRITE_SEQUENCER_282 0x311A
-#define WM8995_WRITE_SEQUENCER_283 0x311B
-#define WM8995_WRITE_SEQUENCER_284 0x311C
-#define WM8995_WRITE_SEQUENCER_285 0x311D
-#define WM8995_WRITE_SEQUENCER_286 0x311E
-#define WM8995_WRITE_SEQUENCER_287 0x311F
-#define WM8995_WRITE_SEQUENCER_288 0x3120
-#define WM8995_WRITE_SEQUENCER_289 0x3121
-#define WM8995_WRITE_SEQUENCER_290 0x3122
-#define WM8995_WRITE_SEQUENCER_291 0x3123
-#define WM8995_WRITE_SEQUENCER_292 0x3124
-#define WM8995_WRITE_SEQUENCER_293 0x3125
-#define WM8995_WRITE_SEQUENCER_294 0x3126
-#define WM8995_WRITE_SEQUENCER_295 0x3127
-#define WM8995_WRITE_SEQUENCER_296 0x3128
-#define WM8995_WRITE_SEQUENCER_297 0x3129
-#define WM8995_WRITE_SEQUENCER_298 0x312A
-#define WM8995_WRITE_SEQUENCER_299 0x312B
-#define WM8995_WRITE_SEQUENCER_300 0x312C
-#define WM8995_WRITE_SEQUENCER_301 0x312D
-#define WM8995_WRITE_SEQUENCER_302 0x312E
-#define WM8995_WRITE_SEQUENCER_303 0x312F
-#define WM8995_WRITE_SEQUENCER_304 0x3130
-#define WM8995_WRITE_SEQUENCER_305 0x3131
-#define WM8995_WRITE_SEQUENCER_306 0x3132
-#define WM8995_WRITE_SEQUENCER_307 0x3133
-#define WM8995_WRITE_SEQUENCER_308 0x3134
-#define WM8995_WRITE_SEQUENCER_309 0x3135
-#define WM8995_WRITE_SEQUENCER_310 0x3136
-#define WM8995_WRITE_SEQUENCER_311 0x3137
-#define WM8995_WRITE_SEQUENCER_312 0x3138
-#define WM8995_WRITE_SEQUENCER_313 0x3139
-#define WM8995_WRITE_SEQUENCER_314 0x313A
-#define WM8995_WRITE_SEQUENCER_315 0x313B
-#define WM8995_WRITE_SEQUENCER_316 0x313C
-#define WM8995_WRITE_SEQUENCER_317 0x313D
-#define WM8995_WRITE_SEQUENCER_318 0x313E
-#define WM8995_WRITE_SEQUENCER_319 0x313F
-#define WM8995_WRITE_SEQUENCER_320 0x3140
-#define WM8995_WRITE_SEQUENCER_321 0x3141
-#define WM8995_WRITE_SEQUENCER_322 0x3142
-#define WM8995_WRITE_SEQUENCER_323 0x3143
-#define WM8995_WRITE_SEQUENCER_324 0x3144
-#define WM8995_WRITE_SEQUENCER_325 0x3145
-#define WM8995_WRITE_SEQUENCER_326 0x3146
-#define WM8995_WRITE_SEQUENCER_327 0x3147
-#define WM8995_WRITE_SEQUENCER_328 0x3148
-#define WM8995_WRITE_SEQUENCER_329 0x3149
-#define WM8995_WRITE_SEQUENCER_330 0x314A
-#define WM8995_WRITE_SEQUENCER_331 0x314B
-#define WM8995_WRITE_SEQUENCER_332 0x314C
-#define WM8995_WRITE_SEQUENCER_333 0x314D
-#define WM8995_WRITE_SEQUENCER_334 0x314E
-#define WM8995_WRITE_SEQUENCER_335 0x314F
-#define WM8995_WRITE_SEQUENCER_336 0x3150
-#define WM8995_WRITE_SEQUENCER_337 0x3151
-#define WM8995_WRITE_SEQUENCER_338 0x3152
-#define WM8995_WRITE_SEQUENCER_339 0x3153
-#define WM8995_WRITE_SEQUENCER_340 0x3154
-#define WM8995_WRITE_SEQUENCER_341 0x3155
-#define WM8995_WRITE_SEQUENCER_342 0x3156
-#define WM8995_WRITE_SEQUENCER_343 0x3157
-#define WM8995_WRITE_SEQUENCER_344 0x3158
-#define WM8995_WRITE_SEQUENCER_345 0x3159
-#define WM8995_WRITE_SEQUENCER_346 0x315A
-#define WM8995_WRITE_SEQUENCER_347 0x315B
-#define WM8995_WRITE_SEQUENCER_348 0x315C
-#define WM8995_WRITE_SEQUENCER_349 0x315D
-#define WM8995_WRITE_SEQUENCER_350 0x315E
-#define WM8995_WRITE_SEQUENCER_351 0x315F
-#define WM8995_WRITE_SEQUENCER_352 0x3160
-#define WM8995_WRITE_SEQUENCER_353 0x3161
-#define WM8995_WRITE_SEQUENCER_354 0x3162
-#define WM8995_WRITE_SEQUENCER_355 0x3163
-#define WM8995_WRITE_SEQUENCER_356 0x3164
-#define WM8995_WRITE_SEQUENCER_357 0x3165
-#define WM8995_WRITE_SEQUENCER_358 0x3166
-#define WM8995_WRITE_SEQUENCER_359 0x3167
-#define WM8995_WRITE_SEQUENCER_360 0x3168
-#define WM8995_WRITE_SEQUENCER_361 0x3169
-#define WM8995_WRITE_SEQUENCER_362 0x316A
-#define WM8995_WRITE_SEQUENCER_363 0x316B
-#define WM8995_WRITE_SEQUENCER_364 0x316C
-#define WM8995_WRITE_SEQUENCER_365 0x316D
-#define WM8995_WRITE_SEQUENCER_366 0x316E
-#define WM8995_WRITE_SEQUENCER_367 0x316F
-#define WM8995_WRITE_SEQUENCER_368 0x3170
-#define WM8995_WRITE_SEQUENCER_369 0x3171
-#define WM8995_WRITE_SEQUENCER_370 0x3172
-#define WM8995_WRITE_SEQUENCER_371 0x3173
-#define WM8995_WRITE_SEQUENCER_372 0x3174
-#define WM8995_WRITE_SEQUENCER_373 0x3175
-#define WM8995_WRITE_SEQUENCER_374 0x3176
-#define WM8995_WRITE_SEQUENCER_375 0x3177
-#define WM8995_WRITE_SEQUENCER_376 0x3178
-#define WM8995_WRITE_SEQUENCER_377 0x3179
-#define WM8995_WRITE_SEQUENCER_378 0x317A
-#define WM8995_WRITE_SEQUENCER_379 0x317B
-#define WM8995_WRITE_SEQUENCER_380 0x317C
-#define WM8995_WRITE_SEQUENCER_381 0x317D
-#define WM8995_WRITE_SEQUENCER_382 0x317E
-#define WM8995_WRITE_SEQUENCER_383 0x317F
-#define WM8995_WRITE_SEQUENCER_384 0x3180
-#define WM8995_WRITE_SEQUENCER_385 0x3181
-#define WM8995_WRITE_SEQUENCER_386 0x3182
-#define WM8995_WRITE_SEQUENCER_387 0x3183
-#define WM8995_WRITE_SEQUENCER_388 0x3184
-#define WM8995_WRITE_SEQUENCER_389 0x3185
-#define WM8995_WRITE_SEQUENCER_390 0x3186
-#define WM8995_WRITE_SEQUENCER_391 0x3187
-#define WM8995_WRITE_SEQUENCER_392 0x3188
-#define WM8995_WRITE_SEQUENCER_393 0x3189
-#define WM8995_WRITE_SEQUENCER_394 0x318A
-#define WM8995_WRITE_SEQUENCER_395 0x318B
-#define WM8995_WRITE_SEQUENCER_396 0x318C
-#define WM8995_WRITE_SEQUENCER_397 0x318D
-#define WM8995_WRITE_SEQUENCER_398 0x318E
-#define WM8995_WRITE_SEQUENCER_399 0x318F
-#define WM8995_WRITE_SEQUENCER_400 0x3190
-#define WM8995_WRITE_SEQUENCER_401 0x3191
-#define WM8995_WRITE_SEQUENCER_402 0x3192
-#define WM8995_WRITE_SEQUENCER_403 0x3193
-#define WM8995_WRITE_SEQUENCER_404 0x3194
-#define WM8995_WRITE_SEQUENCER_405 0x3195
-#define WM8995_WRITE_SEQUENCER_406 0x3196
-#define WM8995_WRITE_SEQUENCER_407 0x3197
-#define WM8995_WRITE_SEQUENCER_408 0x3198
-#define WM8995_WRITE_SEQUENCER_409 0x3199
-#define WM8995_WRITE_SEQUENCER_410 0x319A
-#define WM8995_WRITE_SEQUENCER_411 0x319B
-#define WM8995_WRITE_SEQUENCER_412 0x319C
-#define WM8995_WRITE_SEQUENCER_413 0x319D
-#define WM8995_WRITE_SEQUENCER_414 0x319E
-#define WM8995_WRITE_SEQUENCER_415 0x319F
-#define WM8995_WRITE_SEQUENCER_416 0x31A0
-#define WM8995_WRITE_SEQUENCER_417 0x31A1
-#define WM8995_WRITE_SEQUENCER_418 0x31A2
-#define WM8995_WRITE_SEQUENCER_419 0x31A3
-#define WM8995_WRITE_SEQUENCER_420 0x31A4
-#define WM8995_WRITE_SEQUENCER_421 0x31A5
-#define WM8995_WRITE_SEQUENCER_422 0x31A6
-#define WM8995_WRITE_SEQUENCER_423 0x31A7
-#define WM8995_WRITE_SEQUENCER_424 0x31A8
-#define WM8995_WRITE_SEQUENCER_425 0x31A9
-#define WM8995_WRITE_SEQUENCER_426 0x31AA
-#define WM8995_WRITE_SEQUENCER_427 0x31AB
-#define WM8995_WRITE_SEQUENCER_428 0x31AC
-#define WM8995_WRITE_SEQUENCER_429 0x31AD
-#define WM8995_WRITE_SEQUENCER_430 0x31AE
-#define WM8995_WRITE_SEQUENCER_431 0x31AF
-#define WM8995_WRITE_SEQUENCER_432 0x31B0
-#define WM8995_WRITE_SEQUENCER_433 0x31B1
-#define WM8995_WRITE_SEQUENCER_434 0x31B2
-#define WM8995_WRITE_SEQUENCER_435 0x31B3
-#define WM8995_WRITE_SEQUENCER_436 0x31B4
-#define WM8995_WRITE_SEQUENCER_437 0x31B5
-#define WM8995_WRITE_SEQUENCER_438 0x31B6
-#define WM8995_WRITE_SEQUENCER_439 0x31B7
-#define WM8995_WRITE_SEQUENCER_440 0x31B8
-#define WM8995_WRITE_SEQUENCER_441 0x31B9
-#define WM8995_WRITE_SEQUENCER_442 0x31BA
-#define WM8995_WRITE_SEQUENCER_443 0x31BB
-#define WM8995_WRITE_SEQUENCER_444 0x31BC
-#define WM8995_WRITE_SEQUENCER_445 0x31BD
-#define WM8995_WRITE_SEQUENCER_446 0x31BE
-#define WM8995_WRITE_SEQUENCER_447 0x31BF
-#define WM8995_WRITE_SEQUENCER_448 0x31C0
-#define WM8995_WRITE_SEQUENCER_449 0x31C1
-#define WM8995_WRITE_SEQUENCER_450 0x31C2
-#define WM8995_WRITE_SEQUENCER_451 0x31C3
-#define WM8995_WRITE_SEQUENCER_452 0x31C4
-#define WM8995_WRITE_SEQUENCER_453 0x31C5
-#define WM8995_WRITE_SEQUENCER_454 0x31C6
-#define WM8995_WRITE_SEQUENCER_455 0x31C7
-#define WM8995_WRITE_SEQUENCER_456 0x31C8
-#define WM8995_WRITE_SEQUENCER_457 0x31C9
-#define WM8995_WRITE_SEQUENCER_458 0x31CA
-#define WM8995_WRITE_SEQUENCER_459 0x31CB
-#define WM8995_WRITE_SEQUENCER_460 0x31CC
-#define WM8995_WRITE_SEQUENCER_461 0x31CD
-#define WM8995_WRITE_SEQUENCER_462 0x31CE
-#define WM8995_WRITE_SEQUENCER_463 0x31CF
-#define WM8995_WRITE_SEQUENCER_464 0x31D0
-#define WM8995_WRITE_SEQUENCER_465 0x31D1
-#define WM8995_WRITE_SEQUENCER_466 0x31D2
-#define WM8995_WRITE_SEQUENCER_467 0x31D3
-#define WM8995_WRITE_SEQUENCER_468 0x31D4
-#define WM8995_WRITE_SEQUENCER_469 0x31D5
-#define WM8995_WRITE_SEQUENCER_470 0x31D6
-#define WM8995_WRITE_SEQUENCER_471 0x31D7
-#define WM8995_WRITE_SEQUENCER_472 0x31D8
-#define WM8995_WRITE_SEQUENCER_473 0x31D9
-#define WM8995_WRITE_SEQUENCER_474 0x31DA
-#define WM8995_WRITE_SEQUENCER_475 0x31DB
-#define WM8995_WRITE_SEQUENCER_476 0x31DC
-#define WM8995_WRITE_SEQUENCER_477 0x31DD
-#define WM8995_WRITE_SEQUENCER_478 0x31DE
-#define WM8995_WRITE_SEQUENCER_479 0x31DF
-#define WM8995_WRITE_SEQUENCER_480 0x31E0
-#define WM8995_WRITE_SEQUENCER_481 0x31E1
-#define WM8995_WRITE_SEQUENCER_482 0x31E2
-#define WM8995_WRITE_SEQUENCER_483 0x31E3
-#define WM8995_WRITE_SEQUENCER_484 0x31E4
-#define WM8995_WRITE_SEQUENCER_485 0x31E5
-#define WM8995_WRITE_SEQUENCER_486 0x31E6
-#define WM8995_WRITE_SEQUENCER_487 0x31E7
-#define WM8995_WRITE_SEQUENCER_488 0x31E8
-#define WM8995_WRITE_SEQUENCER_489 0x31E9
-#define WM8995_WRITE_SEQUENCER_490 0x31EA
-#define WM8995_WRITE_SEQUENCER_491 0x31EB
-#define WM8995_WRITE_SEQUENCER_492 0x31EC
-#define WM8995_WRITE_SEQUENCER_493 0x31ED
-#define WM8995_WRITE_SEQUENCER_494 0x31EE
-#define WM8995_WRITE_SEQUENCER_495 0x31EF
-#define WM8995_WRITE_SEQUENCER_496 0x31F0
-#define WM8995_WRITE_SEQUENCER_497 0x31F1
-#define WM8995_WRITE_SEQUENCER_498 0x31F2
-#define WM8995_WRITE_SEQUENCER_499 0x31F3
-#define WM8995_WRITE_SEQUENCER_500 0x31F4
-#define WM8995_WRITE_SEQUENCER_501 0x31F5
-#define WM8995_WRITE_SEQUENCER_502 0x31F6
-#define WM8995_WRITE_SEQUENCER_503 0x31F7
-#define WM8995_WRITE_SEQUENCER_504 0x31F8
-#define WM8995_WRITE_SEQUENCER_505 0x31F9
-#define WM8995_WRITE_SEQUENCER_506 0x31FA
-#define WM8995_WRITE_SEQUENCER_507 0x31FB
-#define WM8995_WRITE_SEQUENCER_508 0x31FC
-#define WM8995_WRITE_SEQUENCER_509 0x31FD
-#define WM8995_WRITE_SEQUENCER_510 0x31FE
-#define WM8995_WRITE_SEQUENCER_511 0x31FF
-
-#define WM8995_REGISTER_COUNT 725
-#define WM8995_MAX_REGISTER 0x31FF
-
-#define WM8995_MAX_CACHED_REGISTER WM8995_MAX_REGISTER
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - Software Reset
- */
-#define WM8995_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
-#define WM8995_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
-#define WM8995_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
-
-/*
- * R1 (0x01) - Power Management (1)
- */
-#define WM8995_MICB2_ENA 0x0200 /* MICB2_ENA */
-#define WM8995_MICB2_ENA_MASK 0x0200 /* MICB2_ENA */
-#define WM8995_MICB2_ENA_SHIFT 9 /* MICB2_ENA */
-#define WM8995_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
-#define WM8995_MICB1_ENA 0x0100 /* MICB1_ENA */
-#define WM8995_MICB1_ENA_MASK 0x0100 /* MICB1_ENA */
-#define WM8995_MICB1_ENA_SHIFT 8 /* MICB1_ENA */
-#define WM8995_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
-#define WM8995_HPOUT2L_ENA 0x0080 /* HPOUT2L_ENA */
-#define WM8995_HPOUT2L_ENA_MASK 0x0080 /* HPOUT2L_ENA */
-#define WM8995_HPOUT2L_ENA_SHIFT 7 /* HPOUT2L_ENA */
-#define WM8995_HPOUT2L_ENA_WIDTH 1 /* HPOUT2L_ENA */
-#define WM8995_HPOUT2R_ENA 0x0040 /* HPOUT2R_ENA */
-#define WM8995_HPOUT2R_ENA_MASK 0x0040 /* HPOUT2R_ENA */
-#define WM8995_HPOUT2R_ENA_SHIFT 6 /* HPOUT2R_ENA */
-#define WM8995_HPOUT2R_ENA_WIDTH 1 /* HPOUT2R_ENA */
-#define WM8995_HPOUT1L_ENA 0x0020 /* HPOUT1L_ENA */
-#define WM8995_HPOUT1L_ENA_MASK 0x0020 /* HPOUT1L_ENA */
-#define WM8995_HPOUT1L_ENA_SHIFT 5 /* HPOUT1L_ENA */
-#define WM8995_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */
-#define WM8995_HPOUT1R_ENA 0x0010 /* HPOUT1R_ENA */
-#define WM8995_HPOUT1R_ENA_MASK 0x0010 /* HPOUT1R_ENA */
-#define WM8995_HPOUT1R_ENA_SHIFT 4 /* HPOUT1R_ENA */
-#define WM8995_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */
-#define WM8995_BG_ENA 0x0001 /* BG_ENA */
-#define WM8995_BG_ENA_MASK 0x0001 /* BG_ENA */
-#define WM8995_BG_ENA_SHIFT 0 /* BG_ENA */
-#define WM8995_BG_ENA_WIDTH 1 /* BG_ENA */
-
-/*
- * R2 (0x02) - Power Management (2)
- */
-#define WM8995_OPCLK_ENA 0x0800 /* OPCLK_ENA */
-#define WM8995_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */
-#define WM8995_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */
-#define WM8995_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
-#define WM8995_IN1L_ENA 0x0020 /* IN1L_ENA */
-#define WM8995_IN1L_ENA_MASK 0x0020 /* IN1L_ENA */
-#define WM8995_IN1L_ENA_SHIFT 5 /* IN1L_ENA */
-#define WM8995_IN1L_ENA_WIDTH 1 /* IN1L_ENA */
-#define WM8995_IN1R_ENA 0x0010 /* IN1R_ENA */
-#define WM8995_IN1R_ENA_MASK 0x0010 /* IN1R_ENA */
-#define WM8995_IN1R_ENA_SHIFT 4 /* IN1R_ENA */
-#define WM8995_IN1R_ENA_WIDTH 1 /* IN1R_ENA */
-#define WM8995_LDO2_ENA 0x0002 /* LDO2_ENA */
-#define WM8995_LDO2_ENA_MASK 0x0002 /* LDO2_ENA */
-#define WM8995_LDO2_ENA_SHIFT 1 /* LDO2_ENA */
-#define WM8995_LDO2_ENA_WIDTH 1 /* LDO2_ENA */
-
-/*
- * R3 (0x03) - Power Management (3)
- */
-#define WM8995_AIF2ADCL_ENA 0x2000 /* AIF2ADCL_ENA */
-#define WM8995_AIF2ADCL_ENA_MASK 0x2000 /* AIF2ADCL_ENA */
-#define WM8995_AIF2ADCL_ENA_SHIFT 13 /* AIF2ADCL_ENA */
-#define WM8995_AIF2ADCL_ENA_WIDTH 1 /* AIF2ADCL_ENA */
-#define WM8995_AIF2ADCR_ENA 0x1000 /* AIF2ADCR_ENA */
-#define WM8995_AIF2ADCR_ENA_MASK 0x1000 /* AIF2ADCR_ENA */
-#define WM8995_AIF2ADCR_ENA_SHIFT 12 /* AIF2ADCR_ENA */
-#define WM8995_AIF2ADCR_ENA_WIDTH 1 /* AIF2ADCR_ENA */
-#define WM8995_AIF1ADC2L_ENA 0x0800 /* AIF1ADC2L_ENA */
-#define WM8995_AIF1ADC2L_ENA_MASK 0x0800 /* AIF1ADC2L_ENA */
-#define WM8995_AIF1ADC2L_ENA_SHIFT 11 /* AIF1ADC2L_ENA */
-#define WM8995_AIF1ADC2L_ENA_WIDTH 1 /* AIF1ADC2L_ENA */
-#define WM8995_AIF1ADC2R_ENA 0x0400 /* AIF1ADC2R_ENA */
-#define WM8995_AIF1ADC2R_ENA_MASK 0x0400 /* AIF1ADC2R_ENA */
-#define WM8995_AIF1ADC2R_ENA_SHIFT 10 /* AIF1ADC2R_ENA */
-#define WM8995_AIF1ADC2R_ENA_WIDTH 1 /* AIF1ADC2R_ENA */
-#define WM8995_AIF1ADC1L_ENA 0x0200 /* AIF1ADC1L_ENA */
-#define WM8995_AIF1ADC1L_ENA_MASK 0x0200 /* AIF1ADC1L_ENA */
-#define WM8995_AIF1ADC1L_ENA_SHIFT 9 /* AIF1ADC1L_ENA */
-#define WM8995_AIF1ADC1L_ENA_WIDTH 1 /* AIF1ADC1L_ENA */
-#define WM8995_AIF1ADC1R_ENA 0x0100 /* AIF1ADC1R_ENA */
-#define WM8995_AIF1ADC1R_ENA_MASK 0x0100 /* AIF1ADC1R_ENA */
-#define WM8995_AIF1ADC1R_ENA_SHIFT 8 /* AIF1ADC1R_ENA */
-#define WM8995_AIF1ADC1R_ENA_WIDTH 1 /* AIF1ADC1R_ENA */
-#define WM8995_DMIC3L_ENA 0x0080 /* DMIC3L_ENA */
-#define WM8995_DMIC3L_ENA_MASK 0x0080 /* DMIC3L_ENA */
-#define WM8995_DMIC3L_ENA_SHIFT 7 /* DMIC3L_ENA */
-#define WM8995_DMIC3L_ENA_WIDTH 1 /* DMIC3L_ENA */
-#define WM8995_DMIC3R_ENA 0x0040 /* DMIC3R_ENA */
-#define WM8995_DMIC3R_ENA_MASK 0x0040 /* DMIC3R_ENA */
-#define WM8995_DMIC3R_ENA_SHIFT 6 /* DMIC3R_ENA */
-#define WM8995_DMIC3R_ENA_WIDTH 1 /* DMIC3R_ENA */
-#define WM8995_DMIC2L_ENA 0x0020 /* DMIC2L_ENA */
-#define WM8995_DMIC2L_ENA_MASK 0x0020 /* DMIC2L_ENA */
-#define WM8995_DMIC2L_ENA_SHIFT 5 /* DMIC2L_ENA */
-#define WM8995_DMIC2L_ENA_WIDTH 1 /* DMIC2L_ENA */
-#define WM8995_DMIC2R_ENA 0x0010 /* DMIC2R_ENA */
-#define WM8995_DMIC2R_ENA_MASK 0x0010 /* DMIC2R_ENA */
-#define WM8995_DMIC2R_ENA_SHIFT 4 /* DMIC2R_ENA */
-#define WM8995_DMIC2R_ENA_WIDTH 1 /* DMIC2R_ENA */
-#define WM8995_DMIC1L_ENA 0x0008 /* DMIC1L_ENA */
-#define WM8995_DMIC1L_ENA_MASK 0x0008 /* DMIC1L_ENA */
-#define WM8995_DMIC1L_ENA_SHIFT 3 /* DMIC1L_ENA */
-#define WM8995_DMIC1L_ENA_WIDTH 1 /* DMIC1L_ENA */
-#define WM8995_DMIC1R_ENA 0x0004 /* DMIC1R_ENA */
-#define WM8995_DMIC1R_ENA_MASK 0x0004 /* DMIC1R_ENA */
-#define WM8995_DMIC1R_ENA_SHIFT 2 /* DMIC1R_ENA */
-#define WM8995_DMIC1R_ENA_WIDTH 1 /* DMIC1R_ENA */
-#define WM8995_ADCL_ENA 0x0002 /* ADCL_ENA */
-#define WM8995_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
-#define WM8995_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
-#define WM8995_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
-#define WM8995_ADCR_ENA 0x0001 /* ADCR_ENA */
-#define WM8995_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
-#define WM8995_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
-#define WM8995_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
-
-/*
- * R4 (0x04) - Power Management (4)
- */
-#define WM8995_AIF2DACL_ENA 0x2000 /* AIF2DACL_ENA */
-#define WM8995_AIF2DACL_ENA_MASK 0x2000 /* AIF2DACL_ENA */
-#define WM8995_AIF2DACL_ENA_SHIFT 13 /* AIF2DACL_ENA */
-#define WM8995_AIF2DACL_ENA_WIDTH 1 /* AIF2DACL_ENA */
-#define WM8995_AIF2DACR_ENA 0x1000 /* AIF2DACR_ENA */
-#define WM8995_AIF2DACR_ENA_MASK 0x1000 /* AIF2DACR_ENA */
-#define WM8995_AIF2DACR_ENA_SHIFT 12 /* AIF2DACR_ENA */
-#define WM8995_AIF2DACR_ENA_WIDTH 1 /* AIF2DACR_ENA */
-#define WM8995_AIF1DAC2L_ENA 0x0800 /* AIF1DAC2L_ENA */
-#define WM8995_AIF1DAC2L_ENA_MASK 0x0800 /* AIF1DAC2L_ENA */
-#define WM8995_AIF1DAC2L_ENA_SHIFT 11 /* AIF1DAC2L_ENA */
-#define WM8995_AIF1DAC2L_ENA_WIDTH 1 /* AIF1DAC2L_ENA */
-#define WM8995_AIF1DAC2R_ENA 0x0400 /* AIF1DAC2R_ENA */
-#define WM8995_AIF1DAC2R_ENA_MASK 0x0400 /* AIF1DAC2R_ENA */
-#define WM8995_AIF1DAC2R_ENA_SHIFT 10 /* AIF1DAC2R_ENA */
-#define WM8995_AIF1DAC2R_ENA_WIDTH 1 /* AIF1DAC2R_ENA */
-#define WM8995_AIF1DAC1L_ENA 0x0200 /* AIF1DAC1L_ENA */
-#define WM8995_AIF1DAC1L_ENA_MASK 0x0200 /* AIF1DAC1L_ENA */
-#define WM8995_AIF1DAC1L_ENA_SHIFT 9 /* AIF1DAC1L_ENA */
-#define WM8995_AIF1DAC1L_ENA_WIDTH 1 /* AIF1DAC1L_ENA */
-#define WM8995_AIF1DAC1R_ENA 0x0100 /* AIF1DAC1R_ENA */
-#define WM8995_AIF1DAC1R_ENA_MASK 0x0100 /* AIF1DAC1R_ENA */
-#define WM8995_AIF1DAC1R_ENA_SHIFT 8 /* AIF1DAC1R_ENA */
-#define WM8995_AIF1DAC1R_ENA_WIDTH 1 /* AIF1DAC1R_ENA */
-#define WM8995_DAC2L_ENA 0x0008 /* DAC2L_ENA */
-#define WM8995_DAC2L_ENA_MASK 0x0008 /* DAC2L_ENA */
-#define WM8995_DAC2L_ENA_SHIFT 3 /* DAC2L_ENA */
-#define WM8995_DAC2L_ENA_WIDTH 1 /* DAC2L_ENA */
-#define WM8995_DAC2R_ENA 0x0004 /* DAC2R_ENA */
-#define WM8995_DAC2R_ENA_MASK 0x0004 /* DAC2R_ENA */
-#define WM8995_DAC2R_ENA_SHIFT 2 /* DAC2R_ENA */
-#define WM8995_DAC2R_ENA_WIDTH 1 /* DAC2R_ENA */
-#define WM8995_DAC1L_ENA 0x0002 /* DAC1L_ENA */
-#define WM8995_DAC1L_ENA_MASK 0x0002 /* DAC1L_ENA */
-#define WM8995_DAC1L_ENA_SHIFT 1 /* DAC1L_ENA */
-#define WM8995_DAC1L_ENA_WIDTH 1 /* DAC1L_ENA */
-#define WM8995_DAC1R_ENA 0x0001 /* DAC1R_ENA */
-#define WM8995_DAC1R_ENA_MASK 0x0001 /* DAC1R_ENA */
-#define WM8995_DAC1R_ENA_SHIFT 0 /* DAC1R_ENA */
-#define WM8995_DAC1R_ENA_WIDTH 1 /* DAC1R_ENA */
-
-/*
- * R5 (0x05) - Power Management (5)
- */
-#define WM8995_DMIC_SRC2_MASK 0x0300 /* DMIC_SRC2 - [9:8] */
-#define WM8995_DMIC_SRC2_SHIFT 8 /* DMIC_SRC2 - [9:8] */
-#define WM8995_DMIC_SRC2_WIDTH 2 /* DMIC_SRC2 - [9:8] */
-#define WM8995_DMIC_SRC1_MASK 0x00C0 /* DMIC_SRC1 - [7:6] */
-#define WM8995_DMIC_SRC1_SHIFT 6 /* DMIC_SRC1 - [7:6] */
-#define WM8995_DMIC_SRC1_WIDTH 2 /* DMIC_SRC1 - [7:6] */
-#define WM8995_AIF3_TRI 0x0020 /* AIF3_TRI */
-#define WM8995_AIF3_TRI_MASK 0x0020 /* AIF3_TRI */
-#define WM8995_AIF3_TRI_SHIFT 5 /* AIF3_TRI */
-#define WM8995_AIF3_TRI_WIDTH 1 /* AIF3_TRI */
-#define WM8995_AIF3_ADCDAT_SRC_MASK 0x0018 /* AIF3_ADCDAT_SRC - [4:3] */
-#define WM8995_AIF3_ADCDAT_SRC_SHIFT 3 /* AIF3_ADCDAT_SRC - [4:3] */
-#define WM8995_AIF3_ADCDAT_SRC_WIDTH 2 /* AIF3_ADCDAT_SRC - [4:3] */
-#define WM8995_AIF2_ADCDAT_SRC 0x0004 /* AIF2_ADCDAT_SRC */
-#define WM8995_AIF2_ADCDAT_SRC_MASK 0x0004 /* AIF2_ADCDAT_SRC */
-#define WM8995_AIF2_ADCDAT_SRC_SHIFT 2 /* AIF2_ADCDAT_SRC */
-#define WM8995_AIF2_ADCDAT_SRC_WIDTH 1 /* AIF2_ADCDAT_SRC */
-#define WM8995_AIF2_DACDAT_SRC 0x0002 /* AIF2_DACDAT_SRC */
-#define WM8995_AIF2_DACDAT_SRC_MASK 0x0002 /* AIF2_DACDAT_SRC */
-#define WM8995_AIF2_DACDAT_SRC_SHIFT 1 /* AIF2_DACDAT_SRC */
-#define WM8995_AIF2_DACDAT_SRC_WIDTH 1 /* AIF2_DACDAT_SRC */
-#define WM8995_AIF1_DACDAT_SRC 0x0001 /* AIF1_DACDAT_SRC */
-#define WM8995_AIF1_DACDAT_SRC_MASK 0x0001 /* AIF1_DACDAT_SRC */
-#define WM8995_AIF1_DACDAT_SRC_SHIFT 0 /* AIF1_DACDAT_SRC */
-#define WM8995_AIF1_DACDAT_SRC_WIDTH 1 /* AIF1_DACDAT_SRC */
-
-/*
- * R16 (0x10) - Left Line Input 1 Volume
- */
-#define WM8995_IN1_VU 0x0080 /* IN1_VU */
-#define WM8995_IN1_VU_MASK 0x0080 /* IN1_VU */
-#define WM8995_IN1_VU_SHIFT 7 /* IN1_VU */
-#define WM8995_IN1_VU_WIDTH 1 /* IN1_VU */
-#define WM8995_IN1L_ZC 0x0020 /* IN1L_ZC */
-#define WM8995_IN1L_ZC_MASK 0x0020 /* IN1L_ZC */
-#define WM8995_IN1L_ZC_SHIFT 5 /* IN1L_ZC */
-#define WM8995_IN1L_ZC_WIDTH 1 /* IN1L_ZC */
-#define WM8995_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */
-#define WM8995_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */
-#define WM8995_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */
-
-/*
- * R17 (0x11) - Right Line Input 1 Volume
- */
-#define WM8995_IN1_VU 0x0080 /* IN1_VU */
-#define WM8995_IN1_VU_MASK 0x0080 /* IN1_VU */
-#define WM8995_IN1_VU_SHIFT 7 /* IN1_VU */
-#define WM8995_IN1_VU_WIDTH 1 /* IN1_VU */
-#define WM8995_IN1R_ZC 0x0020 /* IN1R_ZC */
-#define WM8995_IN1R_ZC_MASK 0x0020 /* IN1R_ZC */
-#define WM8995_IN1R_ZC_SHIFT 5 /* IN1R_ZC */
-#define WM8995_IN1R_ZC_WIDTH 1 /* IN1R_ZC */
-#define WM8995_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */
-#define WM8995_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */
-#define WM8995_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */
-
-/*
- * R18 (0x12) - Left Line Input Control
- */
-#define WM8995_IN1L_BOOST_MASK 0x0030 /* IN1L_BOOST - [5:4] */
-#define WM8995_IN1L_BOOST_SHIFT 4 /* IN1L_BOOST - [5:4] */
-#define WM8995_IN1L_BOOST_WIDTH 2 /* IN1L_BOOST - [5:4] */
-#define WM8995_IN1L_MODE_MASK 0x000C /* IN1L_MODE - [3:2] */
-#define WM8995_IN1L_MODE_SHIFT 2 /* IN1L_MODE - [3:2] */
-#define WM8995_IN1L_MODE_WIDTH 2 /* IN1L_MODE - [3:2] */
-#define WM8995_IN1R_MODE_MASK 0x0003 /* IN1R_MODE - [1:0] */
-#define WM8995_IN1R_MODE_SHIFT 0 /* IN1R_MODE - [1:0] */
-#define WM8995_IN1R_MODE_WIDTH 2 /* IN1R_MODE - [1:0] */
-
-/*
- * R24 (0x18) - DAC1 Left Volume
- */
-#define WM8995_DAC1L_MUTE 0x0200 /* DAC1L_MUTE */
-#define WM8995_DAC1L_MUTE_MASK 0x0200 /* DAC1L_MUTE */
-#define WM8995_DAC1L_MUTE_SHIFT 9 /* DAC1L_MUTE */
-#define WM8995_DAC1L_MUTE_WIDTH 1 /* DAC1L_MUTE */
-#define WM8995_DAC1_VU 0x0100 /* DAC1_VU */
-#define WM8995_DAC1_VU_MASK 0x0100 /* DAC1_VU */
-#define WM8995_DAC1_VU_SHIFT 8 /* DAC1_VU */
-#define WM8995_DAC1_VU_WIDTH 1 /* DAC1_VU */
-#define WM8995_DAC1L_VOL_MASK 0x00FF /* DAC1L_VOL - [7:0] */
-#define WM8995_DAC1L_VOL_SHIFT 0 /* DAC1L_VOL - [7:0] */
-#define WM8995_DAC1L_VOL_WIDTH 8 /* DAC1L_VOL - [7:0] */
-
-/*
- * R25 (0x19) - DAC1 Right Volume
- */
-#define WM8995_DAC1R_MUTE 0x0200 /* DAC1R_MUTE */
-#define WM8995_DAC1R_MUTE_MASK 0x0200 /* DAC1R_MUTE */
-#define WM8995_DAC1R_MUTE_SHIFT 9 /* DAC1R_MUTE */
-#define WM8995_DAC1R_MUTE_WIDTH 1 /* DAC1R_MUTE */
-#define WM8995_DAC1_VU 0x0100 /* DAC1_VU */
-#define WM8995_DAC1_VU_MASK 0x0100 /* DAC1_VU */
-#define WM8995_DAC1_VU_SHIFT 8 /* DAC1_VU */
-#define WM8995_DAC1_VU_WIDTH 1 /* DAC1_VU */
-#define WM8995_DAC1R_VOL_MASK 0x00FF /* DAC1R_VOL - [7:0] */
-#define WM8995_DAC1R_VOL_SHIFT 0 /* DAC1R_VOL - [7:0] */
-#define WM8995_DAC1R_VOL_WIDTH 8 /* DAC1R_VOL - [7:0] */
-
-/*
- * R26 (0x1A) - DAC2 Left Volume
- */
-#define WM8995_DAC2L_MUTE 0x0200 /* DAC2L_MUTE */
-#define WM8995_DAC2L_MUTE_MASK 0x0200 /* DAC2L_MUTE */
-#define WM8995_DAC2L_MUTE_SHIFT 9 /* DAC2L_MUTE */
-#define WM8995_DAC2L_MUTE_WIDTH 1 /* DAC2L_MUTE */
-#define WM8995_DAC2_VU 0x0100 /* DAC2_VU */
-#define WM8995_DAC2_VU_MASK 0x0100 /* DAC2_VU */
-#define WM8995_DAC2_VU_SHIFT 8 /* DAC2_VU */
-#define WM8995_DAC2_VU_WIDTH 1 /* DAC2_VU */
-#define WM8995_DAC2L_VOL_MASK 0x00FF /* DAC2L_VOL - [7:0] */
-#define WM8995_DAC2L_VOL_SHIFT 0 /* DAC2L_VOL - [7:0] */
-#define WM8995_DAC2L_VOL_WIDTH 8 /* DAC2L_VOL - [7:0] */
-
-/*
- * R27 (0x1B) - DAC2 Right Volume
- */
-#define WM8995_DAC2R_MUTE 0x0200 /* DAC2R_MUTE */
-#define WM8995_DAC2R_MUTE_MASK 0x0200 /* DAC2R_MUTE */
-#define WM8995_DAC2R_MUTE_SHIFT 9 /* DAC2R_MUTE */
-#define WM8995_DAC2R_MUTE_WIDTH 1 /* DAC2R_MUTE */
-#define WM8995_DAC2_VU 0x0100 /* DAC2_VU */
-#define WM8995_DAC2_VU_MASK 0x0100 /* DAC2_VU */
-#define WM8995_DAC2_VU_SHIFT 8 /* DAC2_VU */
-#define WM8995_DAC2_VU_WIDTH 1 /* DAC2_VU */
-#define WM8995_DAC2R_VOL_MASK 0x00FF /* DAC2R_VOL - [7:0] */
-#define WM8995_DAC2R_VOL_SHIFT 0 /* DAC2R_VOL - [7:0] */
-#define WM8995_DAC2R_VOL_WIDTH 8 /* DAC2R_VOL - [7:0] */
-
-/*
- * R28 (0x1C) - Output Volume ZC (1)
- */
-#define WM8995_HPOUT2L_ZC 0x0008 /* HPOUT2L_ZC */
-#define WM8995_HPOUT2L_ZC_MASK 0x0008 /* HPOUT2L_ZC */
-#define WM8995_HPOUT2L_ZC_SHIFT 3 /* HPOUT2L_ZC */
-#define WM8995_HPOUT2L_ZC_WIDTH 1 /* HPOUT2L_ZC */
-#define WM8995_HPOUT2R_ZC 0x0004 /* HPOUT2R_ZC */
-#define WM8995_HPOUT2R_ZC_MASK 0x0004 /* HPOUT2R_ZC */
-#define WM8995_HPOUT2R_ZC_SHIFT 2 /* HPOUT2R_ZC */
-#define WM8995_HPOUT2R_ZC_WIDTH 1 /* HPOUT2R_ZC */
-#define WM8995_HPOUT1L_ZC 0x0002 /* HPOUT1L_ZC */
-#define WM8995_HPOUT1L_ZC_MASK 0x0002 /* HPOUT1L_ZC */
-#define WM8995_HPOUT1L_ZC_SHIFT 1 /* HPOUT1L_ZC */
-#define WM8995_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */
-#define WM8995_HPOUT1R_ZC 0x0001 /* HPOUT1R_ZC */
-#define WM8995_HPOUT1R_ZC_MASK 0x0001 /* HPOUT1R_ZC */
-#define WM8995_HPOUT1R_ZC_SHIFT 0 /* HPOUT1R_ZC */
-#define WM8995_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */
-
-/*
- * R32 (0x20) - MICBIAS (1)
- */
-#define WM8995_MICB1_MODE 0x0008 /* MICB1_MODE */
-#define WM8995_MICB1_MODE_MASK 0x0008 /* MICB1_MODE */
-#define WM8995_MICB1_MODE_SHIFT 3 /* MICB1_MODE */
-#define WM8995_MICB1_MODE_WIDTH 1 /* MICB1_MODE */
-#define WM8995_MICB1_LVL_MASK 0x0006 /* MICB1_LVL - [2:1] */
-#define WM8995_MICB1_LVL_SHIFT 1 /* MICB1_LVL - [2:1] */
-#define WM8995_MICB1_LVL_WIDTH 2 /* MICB1_LVL - [2:1] */
-#define WM8995_MICB1_DISCH 0x0001 /* MICB1_DISCH */
-#define WM8995_MICB1_DISCH_MASK 0x0001 /* MICB1_DISCH */
-#define WM8995_MICB1_DISCH_SHIFT 0 /* MICB1_DISCH */
-#define WM8995_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
-
-/*
- * R33 (0x21) - MICBIAS (2)
- */
-#define WM8995_MICB2_MODE 0x0008 /* MICB2_MODE */
-#define WM8995_MICB2_MODE_MASK 0x0008 /* MICB2_MODE */
-#define WM8995_MICB2_MODE_SHIFT 3 /* MICB2_MODE */
-#define WM8995_MICB2_MODE_WIDTH 1 /* MICB2_MODE */
-#define WM8995_MICB2_LVL_MASK 0x0006 /* MICB2_LVL - [2:1] */
-#define WM8995_MICB2_LVL_SHIFT 1 /* MICB2_LVL - [2:1] */
-#define WM8995_MICB2_LVL_WIDTH 2 /* MICB2_LVL - [2:1] */
-#define WM8995_MICB2_DISCH 0x0001 /* MICB2_DISCH */
-#define WM8995_MICB2_DISCH_MASK 0x0001 /* MICB2_DISCH */
-#define WM8995_MICB2_DISCH_SHIFT 0 /* MICB2_DISCH */
-#define WM8995_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
-
-/*
- * R40 (0x28) - LDO 1
- */
-#define WM8995_LDO1_MODE 0x0020 /* LDO1_MODE */
-#define WM8995_LDO1_MODE_MASK 0x0020 /* LDO1_MODE */
-#define WM8995_LDO1_MODE_SHIFT 5 /* LDO1_MODE */
-#define WM8995_LDO1_MODE_WIDTH 1 /* LDO1_MODE */
-#define WM8995_LDO1_VSEL_MASK 0x0006 /* LDO1_VSEL - [2:1] */
-#define WM8995_LDO1_VSEL_SHIFT 1 /* LDO1_VSEL - [2:1] */
-#define WM8995_LDO1_VSEL_WIDTH 2 /* LDO1_VSEL - [2:1] */
-#define WM8995_LDO1_DISCH 0x0001 /* LDO1_DISCH */
-#define WM8995_LDO1_DISCH_MASK 0x0001 /* LDO1_DISCH */
-#define WM8995_LDO1_DISCH_SHIFT 0 /* LDO1_DISCH */
-#define WM8995_LDO1_DISCH_WIDTH 1 /* LDO1_DISCH */
-
-/*
- * R41 (0x29) - LDO 2
- */
-#define WM8995_LDO2_MODE 0x0020 /* LDO2_MODE */
-#define WM8995_LDO2_MODE_MASK 0x0020 /* LDO2_MODE */
-#define WM8995_LDO2_MODE_SHIFT 5 /* LDO2_MODE */
-#define WM8995_LDO2_MODE_WIDTH 1 /* LDO2_MODE */
-#define WM8995_LDO2_VSEL_MASK 0x001E /* LDO2_VSEL - [4:1] */
-#define WM8995_LDO2_VSEL_SHIFT 1 /* LDO2_VSEL - [4:1] */
-#define WM8995_LDO2_VSEL_WIDTH 4 /* LDO2_VSEL - [4:1] */
-#define WM8995_LDO2_DISCH 0x0001 /* LDO2_DISCH */
-#define WM8995_LDO2_DISCH_MASK 0x0001 /* LDO2_DISCH */
-#define WM8995_LDO2_DISCH_SHIFT 0 /* LDO2_DISCH */
-#define WM8995_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */
-
-/*
- * R48 (0x30) - Accessory Detect Mode1
- */
-#define WM8995_JD_MODE_MASK 0x0003 /* JD_MODE - [1:0] */
-#define WM8995_JD_MODE_SHIFT 0 /* JD_MODE - [1:0] */
-#define WM8995_JD_MODE_WIDTH 2 /* JD_MODE - [1:0] */
-
-/*
- * R49 (0x31) - Accessory Detect Mode2
- */
-#define WM8995_VID_ENA 0x0001 /* VID_ENA */
-#define WM8995_VID_ENA_MASK 0x0001 /* VID_ENA */
-#define WM8995_VID_ENA_SHIFT 0 /* VID_ENA */
-#define WM8995_VID_ENA_WIDTH 1 /* VID_ENA */
-
-/*
- * R52 (0x34) - Headphone Detect1
- */
-#define WM8995_HP_RAMPRATE 0x0002 /* HP_RAMPRATE */
-#define WM8995_HP_RAMPRATE_MASK 0x0002 /* HP_RAMPRATE */
-#define WM8995_HP_RAMPRATE_SHIFT 1 /* HP_RAMPRATE */
-#define WM8995_HP_RAMPRATE_WIDTH 1 /* HP_RAMPRATE */
-#define WM8995_HP_POLL 0x0001 /* HP_POLL */
-#define WM8995_HP_POLL_MASK 0x0001 /* HP_POLL */
-#define WM8995_HP_POLL_SHIFT 0 /* HP_POLL */
-#define WM8995_HP_POLL_WIDTH 1 /* HP_POLL */
-
-/*
- * R53 (0x35) - Headphone Detect2
- */
-#define WM8995_HP_DONE 0x0080 /* HP_DONE */
-#define WM8995_HP_DONE_MASK 0x0080 /* HP_DONE */
-#define WM8995_HP_DONE_SHIFT 7 /* HP_DONE */
-#define WM8995_HP_DONE_WIDTH 1 /* HP_DONE */
-#define WM8995_HP_LVL_MASK 0x007F /* HP_LVL - [6:0] */
-#define WM8995_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */
-#define WM8995_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */
-
-/*
- * R56 (0x38) - Mic Detect (1)
- */
-#define WM8995_MICD_RATE_MASK 0x7800 /* MICD_RATE - [14:11] */
-#define WM8995_MICD_RATE_SHIFT 11 /* MICD_RATE - [14:11] */
-#define WM8995_MICD_RATE_WIDTH 4 /* MICD_RATE - [14:11] */
-#define WM8995_MICD_LVL_SEL_MASK 0x01F8 /* MICD_LVL_SEL - [8:3] */
-#define WM8995_MICD_LVL_SEL_SHIFT 3 /* MICD_LVL_SEL - [8:3] */
-#define WM8995_MICD_LVL_SEL_WIDTH 6 /* MICD_LVL_SEL - [8:3] */
-#define WM8995_MICD_DBTIME 0x0002 /* MICD_DBTIME */
-#define WM8995_MICD_DBTIME_MASK 0x0002 /* MICD_DBTIME */
-#define WM8995_MICD_DBTIME_SHIFT 1 /* MICD_DBTIME */
-#define WM8995_MICD_DBTIME_WIDTH 1 /* MICD_DBTIME */
-#define WM8995_MICD_ENA 0x0001 /* MICD_ENA */
-#define WM8995_MICD_ENA_MASK 0x0001 /* MICD_ENA */
-#define WM8995_MICD_ENA_SHIFT 0 /* MICD_ENA */
-#define WM8995_MICD_ENA_WIDTH 1 /* MICD_ENA */
-
-/*
- * R57 (0x39) - Mic Detect (2)
- */
-#define WM8995_MICD_LVL_MASK 0x01FC /* MICD_LVL - [8:2] */
-#define WM8995_MICD_LVL_SHIFT 2 /* MICD_LVL - [8:2] */
-#define WM8995_MICD_LVL_WIDTH 7 /* MICD_LVL - [8:2] */
-#define WM8995_MICD_VALID 0x0002 /* MICD_VALID */
-#define WM8995_MICD_VALID_MASK 0x0002 /* MICD_VALID */
-#define WM8995_MICD_VALID_SHIFT 1 /* MICD_VALID */
-#define WM8995_MICD_VALID_WIDTH 1 /* MICD_VALID */
-#define WM8995_MICD_STS 0x0001 /* MICD_STS */
-#define WM8995_MICD_STS_MASK 0x0001 /* MICD_STS */
-#define WM8995_MICD_STS_SHIFT 0 /* MICD_STS */
-#define WM8995_MICD_STS_WIDTH 1 /* MICD_STS */
-
-/*
- * R64 (0x40) - Charge Pump (1)
- */
-#define WM8995_CP_ENA 0x8000 /* CP_ENA */
-#define WM8995_CP_ENA_MASK 0x8000 /* CP_ENA */
-#define WM8995_CP_ENA_SHIFT 15 /* CP_ENA */
-#define WM8995_CP_ENA_WIDTH 1 /* CP_ENA */
-
-/*
- * R69 (0x45) - Class W (1)
- */
-#define WM8995_CP_DYN_SRC_SEL_MASK 0x0300 /* CP_DYN_SRC_SEL - [9:8] */
-#define WM8995_CP_DYN_SRC_SEL_SHIFT 8 /* CP_DYN_SRC_SEL - [9:8] */
-#define WM8995_CP_DYN_SRC_SEL_WIDTH 2 /* CP_DYN_SRC_SEL - [9:8] */
-#define WM8995_CP_DYN_PWR 0x0001 /* CP_DYN_PWR */
-#define WM8995_CP_DYN_PWR_MASK 0x0001 /* CP_DYN_PWR */
-#define WM8995_CP_DYN_PWR_SHIFT 0 /* CP_DYN_PWR */
-#define WM8995_CP_DYN_PWR_WIDTH 1 /* CP_DYN_PWR */
-
-/*
- * R80 (0x50) - DC Servo (1)
- */
-#define WM8995_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */
-#define WM8995_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */
-#define WM8995_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */
-#define WM8995_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */
-#define WM8995_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */
-#define WM8995_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */
-#define WM8995_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */
-#define WM8995_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */
-#define WM8995_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
-#define WM8995_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
-#define WM8995_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
-#define WM8995_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
-#define WM8995_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
-#define WM8995_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
-#define WM8995_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
-#define WM8995_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
-
-/*
- * R81 (0x51) - DC Servo (2)
- */
-#define WM8995_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */
-#define WM8995_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */
-#define WM8995_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */
-#define WM8995_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */
-#define WM8995_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */
-#define WM8995_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */
-#define WM8995_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */
-#define WM8995_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */
-#define WM8995_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
-#define WM8995_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
-#define WM8995_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
-#define WM8995_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
-#define WM8995_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
-#define WM8995_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
-#define WM8995_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
-#define WM8995_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
-#define WM8995_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */
-#define WM8995_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */
-#define WM8995_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */
-#define WM8995_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */
-#define WM8995_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */
-#define WM8995_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */
-#define WM8995_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */
-#define WM8995_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */
-#define WM8995_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
-#define WM8995_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
-#define WM8995_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
-#define WM8995_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
-#define WM8995_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
-#define WM8995_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
-#define WM8995_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
-#define WM8995_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
-#define WM8995_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */
-#define WM8995_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */
-#define WM8995_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */
-#define WM8995_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */
-#define WM8995_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */
-#define WM8995_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */
-#define WM8995_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */
-#define WM8995_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */
-#define WM8995_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
-#define WM8995_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
-#define WM8995_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
-#define WM8995_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
-#define WM8995_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
-#define WM8995_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
-#define WM8995_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
-#define WM8995_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
-#define WM8995_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */
-#define WM8995_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */
-#define WM8995_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */
-#define WM8995_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */
-#define WM8995_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */
-#define WM8995_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */
-#define WM8995_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */
-#define WM8995_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */
-#define WM8995_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */
-#define WM8995_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */
-#define WM8995_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */
-#define WM8995_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
-#define WM8995_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */
-#define WM8995_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */
-#define WM8995_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */
-#define WM8995_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
-
-/*
- * R82 (0x52) - DC Servo (3)
- */
-#define WM8995_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */
-#define WM8995_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */
-#define WM8995_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */
-#define WM8995_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
-#define WM8995_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
-#define WM8995_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
-
-/*
- * R84 (0x54) - DC Servo (5)
- */
-#define WM8995_DCS_SERIES_NO_23_MASK 0x7F00 /* DCS_SERIES_NO_23 - [14:8] */
-#define WM8995_DCS_SERIES_NO_23_SHIFT 8 /* DCS_SERIES_NO_23 - [14:8] */
-#define WM8995_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [14:8] */
-#define WM8995_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */
-#define WM8995_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */
-#define WM8995_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */
-
-/*
- * R85 (0x55) - DC Servo (6)
- */
-#define WM8995_DCS_DAC_WR_VAL_3_MASK 0xFF00 /* DCS_DAC_WR_VAL_3 - [15:8] */
-#define WM8995_DCS_DAC_WR_VAL_3_SHIFT 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
-#define WM8995_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
-#define WM8995_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */
-#define WM8995_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */
-#define WM8995_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */
-
-/*
- * R86 (0x56) - DC Servo (7)
- */
-#define WM8995_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */
-#define WM8995_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
-#define WM8995_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
-#define WM8995_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
-#define WM8995_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
-#define WM8995_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
-
-/*
- * R87 (0x57) - DC Servo Readback 0
- */
-#define WM8995_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */
-#define WM8995_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */
-#define WM8995_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */
-#define WM8995_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */
-#define WM8995_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
-#define WM8995_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
-#define WM8995_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */
-#define WM8995_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */
-#define WM8995_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */
-
-/*
- * R96 (0x60) - Analogue HP (1)
- */
-#define WM8995_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
-#define WM8995_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
-#define WM8995_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
-#define WM8995_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */
-#define WM8995_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */
-#define WM8995_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */
-#define WM8995_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */
-#define WM8995_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */
-#define WM8995_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */
-#define WM8995_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */
-#define WM8995_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */
-#define WM8995_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */
-#define WM8995_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */
-#define WM8995_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */
-#define WM8995_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */
-#define WM8995_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */
-#define WM8995_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */
-#define WM8995_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */
-#define WM8995_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */
-#define WM8995_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */
-#define WM8995_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */
-#define WM8995_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */
-#define WM8995_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */
-#define WM8995_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
-
-/*
- * R97 (0x61) - Analogue HP (2)
- */
-#define WM8995_HPOUT2L_RMV_SHORT 0x0080 /* HPOUT2L_RMV_SHORT */
-#define WM8995_HPOUT2L_RMV_SHORT_MASK 0x0080 /* HPOUT2L_RMV_SHORT */
-#define WM8995_HPOUT2L_RMV_SHORT_SHIFT 7 /* HPOUT2L_RMV_SHORT */
-#define WM8995_HPOUT2L_RMV_SHORT_WIDTH 1 /* HPOUT2L_RMV_SHORT */
-#define WM8995_HPOUT2L_OUTP 0x0040 /* HPOUT2L_OUTP */
-#define WM8995_HPOUT2L_OUTP_MASK 0x0040 /* HPOUT2L_OUTP */
-#define WM8995_HPOUT2L_OUTP_SHIFT 6 /* HPOUT2L_OUTP */
-#define WM8995_HPOUT2L_OUTP_WIDTH 1 /* HPOUT2L_OUTP */
-#define WM8995_HPOUT2L_DLY 0x0020 /* HPOUT2L_DLY */
-#define WM8995_HPOUT2L_DLY_MASK 0x0020 /* HPOUT2L_DLY */
-#define WM8995_HPOUT2L_DLY_SHIFT 5 /* HPOUT2L_DLY */
-#define WM8995_HPOUT2L_DLY_WIDTH 1 /* HPOUT2L_DLY */
-#define WM8995_HPOUT2R_RMV_SHORT 0x0008 /* HPOUT2R_RMV_SHORT */
-#define WM8995_HPOUT2R_RMV_SHORT_MASK 0x0008 /* HPOUT2R_RMV_SHORT */
-#define WM8995_HPOUT2R_RMV_SHORT_SHIFT 3 /* HPOUT2R_RMV_SHORT */
-#define WM8995_HPOUT2R_RMV_SHORT_WIDTH 1 /* HPOUT2R_RMV_SHORT */
-#define WM8995_HPOUT2R_OUTP 0x0004 /* HPOUT2R_OUTP */
-#define WM8995_HPOUT2R_OUTP_MASK 0x0004 /* HPOUT2R_OUTP */
-#define WM8995_HPOUT2R_OUTP_SHIFT 2 /* HPOUT2R_OUTP */
-#define WM8995_HPOUT2R_OUTP_WIDTH 1 /* HPOUT2R_OUTP */
-#define WM8995_HPOUT2R_DLY 0x0002 /* HPOUT2R_DLY */
-#define WM8995_HPOUT2R_DLY_MASK 0x0002 /* HPOUT2R_DLY */
-#define WM8995_HPOUT2R_DLY_SHIFT 1 /* HPOUT2R_DLY */
-#define WM8995_HPOUT2R_DLY_WIDTH 1 /* HPOUT2R_DLY */
-
-/*
- * R256 (0x100) - Chip Revision
- */
-#define WM8995_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */
-#define WM8995_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */
-#define WM8995_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */
-
-/*
- * R257 (0x101) - Control Interface (1)
- */
-#define WM8995_REG_SYNC 0x8000 /* REG_SYNC */
-#define WM8995_REG_SYNC_MASK 0x8000 /* REG_SYNC */
-#define WM8995_REG_SYNC_SHIFT 15 /* REG_SYNC */
-#define WM8995_REG_SYNC_WIDTH 1 /* REG_SYNC */
-#define WM8995_SPI_CONTRD 0x0040 /* SPI_CONTRD */
-#define WM8995_SPI_CONTRD_MASK 0x0040 /* SPI_CONTRD */
-#define WM8995_SPI_CONTRD_SHIFT 6 /* SPI_CONTRD */
-#define WM8995_SPI_CONTRD_WIDTH 1 /* SPI_CONTRD */
-#define WM8995_SPI_4WIRE 0x0020 /* SPI_4WIRE */
-#define WM8995_SPI_4WIRE_MASK 0x0020 /* SPI_4WIRE */
-#define WM8995_SPI_4WIRE_SHIFT 5 /* SPI_4WIRE */
-#define WM8995_SPI_4WIRE_WIDTH 1 /* SPI_4WIRE */
-#define WM8995_SPI_CFG 0x0010 /* SPI_CFG */
-#define WM8995_SPI_CFG_MASK 0x0010 /* SPI_CFG */
-#define WM8995_SPI_CFG_SHIFT 4 /* SPI_CFG */
-#define WM8995_SPI_CFG_WIDTH 1 /* SPI_CFG */
-#define WM8995_AUTO_INC 0x0004 /* AUTO_INC */
-#define WM8995_AUTO_INC_MASK 0x0004 /* AUTO_INC */
-#define WM8995_AUTO_INC_SHIFT 2 /* AUTO_INC */
-#define WM8995_AUTO_INC_WIDTH 1 /* AUTO_INC */
-
-/*
- * R258 (0x102) - Control Interface (2)
- */
-#define WM8995_CTRL_IF_SRC 0x0001 /* CTRL_IF_SRC */
-#define WM8995_CTRL_IF_SRC_MASK 0x0001 /* CTRL_IF_SRC */
-#define WM8995_CTRL_IF_SRC_SHIFT 0 /* CTRL_IF_SRC */
-#define WM8995_CTRL_IF_SRC_WIDTH 1 /* CTRL_IF_SRC */
-
-/*
- * R272 (0x110) - Write Sequencer Ctrl (1)
- */
-#define WM8995_WSEQ_ENA 0x8000 /* WSEQ_ENA */
-#define WM8995_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */
-#define WM8995_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */
-#define WM8995_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
-#define WM8995_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
-#define WM8995_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
-#define WM8995_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
-#define WM8995_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
-#define WM8995_WSEQ_START 0x0100 /* WSEQ_START */
-#define WM8995_WSEQ_START_MASK 0x0100 /* WSEQ_START */
-#define WM8995_WSEQ_START_SHIFT 8 /* WSEQ_START */
-#define WM8995_WSEQ_START_WIDTH 1 /* WSEQ_START */
-#define WM8995_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */
-#define WM8995_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */
-#define WM8995_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */
-
-/*
- * R273 (0x111) - Write Sequencer Ctrl (2)
- */
-#define WM8995_WSEQ_BUSY 0x0100 /* WSEQ_BUSY */
-#define WM8995_WSEQ_BUSY_MASK 0x0100 /* WSEQ_BUSY */
-#define WM8995_WSEQ_BUSY_SHIFT 8 /* WSEQ_BUSY */
-#define WM8995_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
-#define WM8995_WSEQ_CURRENT_INDEX_MASK 0x007F /* WSEQ_CURRENT_INDEX - [6:0] */
-#define WM8995_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [6:0] */
-#define WM8995_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [6:0] */
-
-/*
- * R512 (0x200) - AIF1 Clocking (1)
- */
-#define WM8995_AIF1CLK_SRC_MASK 0x0018 /* AIF1CLK_SRC - [4:3] */
-#define WM8995_AIF1CLK_SRC_SHIFT 3 /* AIF1CLK_SRC - [4:3] */
-#define WM8995_AIF1CLK_SRC_WIDTH 2 /* AIF1CLK_SRC - [4:3] */
-#define WM8995_AIF1CLK_INV 0x0004 /* AIF1CLK_INV */
-#define WM8995_AIF1CLK_INV_MASK 0x0004 /* AIF1CLK_INV */
-#define WM8995_AIF1CLK_INV_SHIFT 2 /* AIF1CLK_INV */
-#define WM8995_AIF1CLK_INV_WIDTH 1 /* AIF1CLK_INV */
-#define WM8995_AIF1CLK_DIV 0x0002 /* AIF1CLK_DIV */
-#define WM8995_AIF1CLK_DIV_MASK 0x0002 /* AIF1CLK_DIV */
-#define WM8995_AIF1CLK_DIV_SHIFT 1 /* AIF1CLK_DIV */
-#define WM8995_AIF1CLK_DIV_WIDTH 1 /* AIF1CLK_DIV */
-#define WM8995_AIF1CLK_ENA 0x0001 /* AIF1CLK_ENA */
-#define WM8995_AIF1CLK_ENA_MASK 0x0001 /* AIF1CLK_ENA */
-#define WM8995_AIF1CLK_ENA_SHIFT 0 /* AIF1CLK_ENA */
-#define WM8995_AIF1CLK_ENA_WIDTH 1 /* AIF1CLK_ENA */
-
-/*
- * R513 (0x201) - AIF1 Clocking (2)
- */
-#define WM8995_AIF1DAC_DIV_MASK 0x0038 /* AIF1DAC_DIV - [5:3] */
-#define WM8995_AIF1DAC_DIV_SHIFT 3 /* AIF1DAC_DIV - [5:3] */
-#define WM8995_AIF1DAC_DIV_WIDTH 3 /* AIF1DAC_DIV - [5:3] */
-#define WM8995_AIF1ADC_DIV_MASK 0x0007 /* AIF1ADC_DIV - [2:0] */
-#define WM8995_AIF1ADC_DIV_SHIFT 0 /* AIF1ADC_DIV - [2:0] */
-#define WM8995_AIF1ADC_DIV_WIDTH 3 /* AIF1ADC_DIV - [2:0] */
-
-/*
- * R516 (0x204) - AIF2 Clocking (1)
- */
-#define WM8995_AIF2CLK_SRC_MASK 0x0018 /* AIF2CLK_SRC - [4:3] */
-#define WM8995_AIF2CLK_SRC_SHIFT 3 /* AIF2CLK_SRC - [4:3] */
-#define WM8995_AIF2CLK_SRC_WIDTH 2 /* AIF2CLK_SRC - [4:3] */
-#define WM8995_AIF2CLK_INV 0x0004 /* AIF2CLK_INV */
-#define WM8995_AIF2CLK_INV_MASK 0x0004 /* AIF2CLK_INV */
-#define WM8995_AIF2CLK_INV_SHIFT 2 /* AIF2CLK_INV */
-#define WM8995_AIF2CLK_INV_WIDTH 1 /* AIF2CLK_INV */
-#define WM8995_AIF2CLK_DIV 0x0002 /* AIF2CLK_DIV */
-#define WM8995_AIF2CLK_DIV_MASK 0x0002 /* AIF2CLK_DIV */
-#define WM8995_AIF2CLK_DIV_SHIFT 1 /* AIF2CLK_DIV */
-#define WM8995_AIF2CLK_DIV_WIDTH 1 /* AIF2CLK_DIV */
-#define WM8995_AIF2CLK_ENA 0x0001 /* AIF2CLK_ENA */
-#define WM8995_AIF2CLK_ENA_MASK 0x0001 /* AIF2CLK_ENA */
-#define WM8995_AIF2CLK_ENA_SHIFT 0 /* AIF2CLK_ENA */
-#define WM8995_AIF2CLK_ENA_WIDTH 1 /* AIF2CLK_ENA */
-
-/*
- * R517 (0x205) - AIF2 Clocking (2)
- */
-#define WM8995_AIF2DAC_DIV_MASK 0x0038 /* AIF2DAC_DIV - [5:3] */
-#define WM8995_AIF2DAC_DIV_SHIFT 3 /* AIF2DAC_DIV - [5:3] */
-#define WM8995_AIF2DAC_DIV_WIDTH 3 /* AIF2DAC_DIV - [5:3] */
-#define WM8995_AIF2ADC_DIV_MASK 0x0007 /* AIF2ADC_DIV - [2:0] */
-#define WM8995_AIF2ADC_DIV_SHIFT 0 /* AIF2ADC_DIV - [2:0] */
-#define WM8995_AIF2ADC_DIV_WIDTH 3 /* AIF2ADC_DIV - [2:0] */
-
-/*
- * R520 (0x208) - Clocking (1)
- */
-#define WM8995_LFCLK_ENA 0x0020 /* LFCLK_ENA */
-#define WM8995_LFCLK_ENA_MASK 0x0020 /* LFCLK_ENA */
-#define WM8995_LFCLK_ENA_SHIFT 5 /* LFCLK_ENA */
-#define WM8995_LFCLK_ENA_WIDTH 1 /* LFCLK_ENA */
-#define WM8995_TOCLK_ENA 0x0010 /* TOCLK_ENA */
-#define WM8995_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */
-#define WM8995_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */
-#define WM8995_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
-#define WM8995_AIF1DSPCLK_ENA 0x0008 /* AIF1DSPCLK_ENA */
-#define WM8995_AIF1DSPCLK_ENA_MASK 0x0008 /* AIF1DSPCLK_ENA */
-#define WM8995_AIF1DSPCLK_ENA_SHIFT 3 /* AIF1DSPCLK_ENA */
-#define WM8995_AIF1DSPCLK_ENA_WIDTH 1 /* AIF1DSPCLK_ENA */
-#define WM8995_AIF2DSPCLK_ENA 0x0004 /* AIF2DSPCLK_ENA */
-#define WM8995_AIF2DSPCLK_ENA_MASK 0x0004 /* AIF2DSPCLK_ENA */
-#define WM8995_AIF2DSPCLK_ENA_SHIFT 2 /* AIF2DSPCLK_ENA */
-#define WM8995_AIF2DSPCLK_ENA_WIDTH 1 /* AIF2DSPCLK_ENA */
-#define WM8995_SYSDSPCLK_ENA 0x0002 /* SYSDSPCLK_ENA */
-#define WM8995_SYSDSPCLK_ENA_MASK 0x0002 /* SYSDSPCLK_ENA */
-#define WM8995_SYSDSPCLK_ENA_SHIFT 1 /* SYSDSPCLK_ENA */
-#define WM8995_SYSDSPCLK_ENA_WIDTH 1 /* SYSDSPCLK_ENA */
-#define WM8995_SYSCLK_SRC 0x0001 /* SYSCLK_SRC */
-#define WM8995_SYSCLK_SRC_MASK 0x0001 /* SYSCLK_SRC */
-#define WM8995_SYSCLK_SRC_SHIFT 0 /* SYSCLK_SRC */
-#define WM8995_SYSCLK_SRC_WIDTH 1 /* SYSCLK_SRC */
-
-/*
- * R521 (0x209) - Clocking (2)
- */
-#define WM8995_TOCLK_DIV_MASK 0x0700 /* TOCLK_DIV - [10:8] */
-#define WM8995_TOCLK_DIV_SHIFT 8 /* TOCLK_DIV - [10:8] */
-#define WM8995_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [10:8] */
-#define WM8995_DBCLK_DIV_MASK 0x00F0 /* DBCLK_DIV - [7:4] */
-#define WM8995_DBCLK_DIV_SHIFT 4 /* DBCLK_DIV - [7:4] */
-#define WM8995_DBCLK_DIV_WIDTH 4 /* DBCLK_DIV - [7:4] */
-#define WM8995_OPCLK_DIV_MASK 0x0007 /* OPCLK_DIV - [2:0] */
-#define WM8995_OPCLK_DIV_SHIFT 0 /* OPCLK_DIV - [2:0] */
-#define WM8995_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [2:0] */
-
-/*
- * R528 (0x210) - AIF1 Rate
- */
-#define WM8995_AIF1_SR_MASK 0x00F0 /* AIF1_SR - [7:4] */
-#define WM8995_AIF1_SR_SHIFT 4 /* AIF1_SR - [7:4] */
-#define WM8995_AIF1_SR_WIDTH 4 /* AIF1_SR - [7:4] */
-#define WM8995_AIF1CLK_RATE_MASK 0x000F /* AIF1CLK_RATE - [3:0] */
-#define WM8995_AIF1CLK_RATE_SHIFT 0 /* AIF1CLK_RATE - [3:0] */
-#define WM8995_AIF1CLK_RATE_WIDTH 4 /* AIF1CLK_RATE - [3:0] */
-
-/*
- * R529 (0x211) - AIF2 Rate
- */
-#define WM8995_AIF2_SR_MASK 0x00F0 /* AIF2_SR - [7:4] */
-#define WM8995_AIF2_SR_SHIFT 4 /* AIF2_SR - [7:4] */
-#define WM8995_AIF2_SR_WIDTH 4 /* AIF2_SR - [7:4] */
-#define WM8995_AIF2CLK_RATE_MASK 0x000F /* AIF2CLK_RATE - [3:0] */
-#define WM8995_AIF2CLK_RATE_SHIFT 0 /* AIF2CLK_RATE - [3:0] */
-#define WM8995_AIF2CLK_RATE_WIDTH 4 /* AIF2CLK_RATE - [3:0] */
-
-/*
- * R530 (0x212) - Rate Status
- */
-#define WM8995_SR_ERROR_MASK 0x000F /* SR_ERROR - [3:0] */
-#define WM8995_SR_ERROR_SHIFT 0 /* SR_ERROR - [3:0] */
-#define WM8995_SR_ERROR_WIDTH 4 /* SR_ERROR - [3:0] */
-
-/*
- * R544 (0x220) - FLL1 Control (1)
- */
-#define WM8995_FLL1_OSC_ENA 0x0002 /* FLL1_OSC_ENA */
-#define WM8995_FLL1_OSC_ENA_MASK 0x0002 /* FLL1_OSC_ENA */
-#define WM8995_FLL1_OSC_ENA_SHIFT 1 /* FLL1_OSC_ENA */
-#define WM8995_FLL1_OSC_ENA_WIDTH 1 /* FLL1_OSC_ENA */
-#define WM8995_FLL1_ENA 0x0001 /* FLL1_ENA */
-#define WM8995_FLL1_ENA_MASK 0x0001 /* FLL1_ENA */
-#define WM8995_FLL1_ENA_SHIFT 0 /* FLL1_ENA */
-#define WM8995_FLL1_ENA_WIDTH 1 /* FLL1_ENA */
-
-/*
- * R545 (0x221) - FLL1 Control (2)
- */
-#define WM8995_FLL1_OUTDIV_MASK 0x3F00 /* FLL1_OUTDIV - [13:8] */
-#define WM8995_FLL1_OUTDIV_SHIFT 8 /* FLL1_OUTDIV - [13:8] */
-#define WM8995_FLL1_OUTDIV_WIDTH 6 /* FLL1_OUTDIV - [13:8] */
-#define WM8995_FLL1_CTRL_RATE_MASK 0x0070 /* FLL1_CTRL_RATE - [6:4] */
-#define WM8995_FLL1_CTRL_RATE_SHIFT 4 /* FLL1_CTRL_RATE - [6:4] */
-#define WM8995_FLL1_CTRL_RATE_WIDTH 3 /* FLL1_CTRL_RATE - [6:4] */
-#define WM8995_FLL1_FRATIO_MASK 0x0007 /* FLL1_FRATIO - [2:0] */
-#define WM8995_FLL1_FRATIO_SHIFT 0 /* FLL1_FRATIO - [2:0] */
-#define WM8995_FLL1_FRATIO_WIDTH 3 /* FLL1_FRATIO - [2:0] */
-
-/*
- * R546 (0x222) - FLL1 Control (3)
- */
-#define WM8995_FLL1_K_MASK 0xFFFF /* FLL1_K - [15:0] */
-#define WM8995_FLL1_K_SHIFT 0 /* FLL1_K - [15:0] */
-#define WM8995_FLL1_K_WIDTH 16 /* FLL1_K - [15:0] */
-
-/*
- * R547 (0x223) - FLL1 Control (4)
- */
-#define WM8995_FLL1_N_MASK 0x7FE0 /* FLL1_N - [14:5] */
-#define WM8995_FLL1_N_SHIFT 5 /* FLL1_N - [14:5] */
-#define WM8995_FLL1_N_WIDTH 10 /* FLL1_N - [14:5] */
-#define WM8995_FLL1_LOOP_GAIN_MASK 0x000F /* FLL1_LOOP_GAIN - [3:0] */
-#define WM8995_FLL1_LOOP_GAIN_SHIFT 0 /* FLL1_LOOP_GAIN - [3:0] */
-#define WM8995_FLL1_LOOP_GAIN_WIDTH 4 /* FLL1_LOOP_GAIN - [3:0] */
-
-/*
- * R548 (0x224) - FLL1 Control (5)
- */
-#define WM8995_FLL1_FRC_NCO_VAL_MASK 0x1F80 /* FLL1_FRC_NCO_VAL - [12:7] */
-#define WM8995_FLL1_FRC_NCO_VAL_SHIFT 7 /* FLL1_FRC_NCO_VAL - [12:7] */
-#define WM8995_FLL1_FRC_NCO_VAL_WIDTH 6 /* FLL1_FRC_NCO_VAL - [12:7] */
-#define WM8995_FLL1_FRC_NCO 0x0040 /* FLL1_FRC_NCO */
-#define WM8995_FLL1_FRC_NCO_MASK 0x0040 /* FLL1_FRC_NCO */
-#define WM8995_FLL1_FRC_NCO_SHIFT 6 /* FLL1_FRC_NCO */
-#define WM8995_FLL1_FRC_NCO_WIDTH 1 /* FLL1_FRC_NCO */
-#define WM8995_FLL1_REFCLK_DIV_MASK 0x0018 /* FLL1_REFCLK_DIV - [4:3] */
-#define WM8995_FLL1_REFCLK_DIV_SHIFT 3 /* FLL1_REFCLK_DIV - [4:3] */
-#define WM8995_FLL1_REFCLK_DIV_WIDTH 2 /* FLL1_REFCLK_DIV - [4:3] */
-#define WM8995_FLL1_REFCLK_SRC_MASK 0x0003 /* FLL1_REFCLK_SRC - [1:0] */
-#define WM8995_FLL1_REFCLK_SRC_SHIFT 0 /* FLL1_REFCLK_SRC - [1:0] */
-#define WM8995_FLL1_REFCLK_SRC_WIDTH 2 /* FLL1_REFCLK_SRC - [1:0] */
-
-/*
- * R576 (0x240) - FLL2 Control (1)
- */
-#define WM8995_FLL2_OSC_ENA 0x0002 /* FLL2_OSC_ENA */
-#define WM8995_FLL2_OSC_ENA_MASK 0x0002 /* FLL2_OSC_ENA */
-#define WM8995_FLL2_OSC_ENA_SHIFT 1 /* FLL2_OSC_ENA */
-#define WM8995_FLL2_OSC_ENA_WIDTH 1 /* FLL2_OSC_ENA */
-#define WM8995_FLL2_ENA 0x0001 /* FLL2_ENA */
-#define WM8995_FLL2_ENA_MASK 0x0001 /* FLL2_ENA */
-#define WM8995_FLL2_ENA_SHIFT 0 /* FLL2_ENA */
-#define WM8995_FLL2_ENA_WIDTH 1 /* FLL2_ENA */
-
-/*
- * R577 (0x241) - FLL2 Control (2)
- */
-#define WM8995_FLL2_OUTDIV_MASK 0x3F00 /* FLL2_OUTDIV - [13:8] */
-#define WM8995_FLL2_OUTDIV_SHIFT 8 /* FLL2_OUTDIV - [13:8] */
-#define WM8995_FLL2_OUTDIV_WIDTH 6 /* FLL2_OUTDIV - [13:8] */
-#define WM8995_FLL2_CTRL_RATE_MASK 0x0070 /* FLL2_CTRL_RATE - [6:4] */
-#define WM8995_FLL2_CTRL_RATE_SHIFT 4 /* FLL2_CTRL_RATE - [6:4] */
-#define WM8995_FLL2_CTRL_RATE_WIDTH 3 /* FLL2_CTRL_RATE - [6:4] */
-#define WM8995_FLL2_FRATIO_MASK 0x0007 /* FLL2_FRATIO - [2:0] */
-#define WM8995_FLL2_FRATIO_SHIFT 0 /* FLL2_FRATIO - [2:0] */
-#define WM8995_FLL2_FRATIO_WIDTH 3 /* FLL2_FRATIO - [2:0] */
-
-/*
- * R578 (0x242) - FLL2 Control (3)
- */
-#define WM8995_FLL2_K_MASK 0xFFFF /* FLL2_K - [15:0] */
-#define WM8995_FLL2_K_SHIFT 0 /* FLL2_K - [15:0] */
-#define WM8995_FLL2_K_WIDTH 16 /* FLL2_K - [15:0] */
-
-/*
- * R579 (0x243) - FLL2 Control (4)
- */
-#define WM8995_FLL2_N_MASK 0x7FE0 /* FLL2_N - [14:5] */
-#define WM8995_FLL2_N_SHIFT 5 /* FLL2_N - [14:5] */
-#define WM8995_FLL2_N_WIDTH 10 /* FLL2_N - [14:5] */
-#define WM8995_FLL2_LOOP_GAIN_MASK 0x000F /* FLL2_LOOP_GAIN - [3:0] */
-#define WM8995_FLL2_LOOP_GAIN_SHIFT 0 /* FLL2_LOOP_GAIN - [3:0] */
-#define WM8995_FLL2_LOOP_GAIN_WIDTH 4 /* FLL2_LOOP_GAIN - [3:0] */
-
-/*
- * R580 (0x244) - FLL2 Control (5)
- */
-#define WM8995_FLL2_FRC_NCO_VAL_MASK 0x1F80 /* FLL2_FRC_NCO_VAL - [12:7] */
-#define WM8995_FLL2_FRC_NCO_VAL_SHIFT 7 /* FLL2_FRC_NCO_VAL - [12:7] */
-#define WM8995_FLL2_FRC_NCO_VAL_WIDTH 6 /* FLL2_FRC_NCO_VAL - [12:7] */
-#define WM8995_FLL2_FRC_NCO 0x0040 /* FLL2_FRC_NCO */
-#define WM8995_FLL2_FRC_NCO_MASK 0x0040 /* FLL2_FRC_NCO */
-#define WM8995_FLL2_FRC_NCO_SHIFT 6 /* FLL2_FRC_NCO */
-#define WM8995_FLL2_FRC_NCO_WIDTH 1 /* FLL2_FRC_NCO */
-#define WM8995_FLL2_REFCLK_DIV_MASK 0x0018 /* FLL2_REFCLK_DIV - [4:3] */
-#define WM8995_FLL2_REFCLK_DIV_SHIFT 3 /* FLL2_REFCLK_DIV - [4:3] */
-#define WM8995_FLL2_REFCLK_DIV_WIDTH 2 /* FLL2_REFCLK_DIV - [4:3] */
-#define WM8995_FLL2_REFCLK_SRC_MASK 0x0003 /* FLL2_REFCLK_SRC - [1:0] */
-#define WM8995_FLL2_REFCLK_SRC_SHIFT 0 /* FLL2_REFCLK_SRC - [1:0] */
-#define WM8995_FLL2_REFCLK_SRC_WIDTH 2 /* FLL2_REFCLK_SRC - [1:0] */
-
-/*
- * R768 (0x300) - AIF1 Control (1)
- */
-#define WM8995_AIF1ADCL_SRC 0x8000 /* AIF1ADCL_SRC */
-#define WM8995_AIF1ADCL_SRC_MASK 0x8000 /* AIF1ADCL_SRC */
-#define WM8995_AIF1ADCL_SRC_SHIFT 15 /* AIF1ADCL_SRC */
-#define WM8995_AIF1ADCL_SRC_WIDTH 1 /* AIF1ADCL_SRC */
-#define WM8995_AIF1ADCR_SRC 0x4000 /* AIF1ADCR_SRC */
-#define WM8995_AIF1ADCR_SRC_MASK 0x4000 /* AIF1ADCR_SRC */
-#define WM8995_AIF1ADCR_SRC_SHIFT 14 /* AIF1ADCR_SRC */
-#define WM8995_AIF1ADCR_SRC_WIDTH 1 /* AIF1ADCR_SRC */
-#define WM8995_AIF1ADC_TDM 0x2000 /* AIF1ADC_TDM */
-#define WM8995_AIF1ADC_TDM_MASK 0x2000 /* AIF1ADC_TDM */
-#define WM8995_AIF1ADC_TDM_SHIFT 13 /* AIF1ADC_TDM */
-#define WM8995_AIF1ADC_TDM_WIDTH 1 /* AIF1ADC_TDM */
-#define WM8995_AIF1_BCLK_INV 0x0100 /* AIF1_BCLK_INV */
-#define WM8995_AIF1_BCLK_INV_MASK 0x0100 /* AIF1_BCLK_INV */
-#define WM8995_AIF1_BCLK_INV_SHIFT 8 /* AIF1_BCLK_INV */
-#define WM8995_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */
-#define WM8995_AIF1_LRCLK_INV 0x0080 /* AIF1_LRCLK_INV */
-#define WM8995_AIF1_LRCLK_INV_MASK 0x0080 /* AIF1_LRCLK_INV */
-#define WM8995_AIF1_LRCLK_INV_SHIFT 7 /* AIF1_LRCLK_INV */
-#define WM8995_AIF1_LRCLK_INV_WIDTH 1 /* AIF1_LRCLK_INV */
-#define WM8995_AIF1_WL_MASK 0x0060 /* AIF1_WL - [6:5] */
-#define WM8995_AIF1_WL_SHIFT 5 /* AIF1_WL - [6:5] */
-#define WM8995_AIF1_WL_WIDTH 2 /* AIF1_WL - [6:5] */
-#define WM8995_AIF1_FMT_MASK 0x0018 /* AIF1_FMT - [4:3] */
-#define WM8995_AIF1_FMT_SHIFT 3 /* AIF1_FMT - [4:3] */
-#define WM8995_AIF1_FMT_WIDTH 2 /* AIF1_FMT - [4:3] */
-
-/*
- * R769 (0x301) - AIF1 Control (2)
- */
-#define WM8995_AIF1DACL_SRC 0x8000 /* AIF1DACL_SRC */
-#define WM8995_AIF1DACL_SRC_MASK 0x8000 /* AIF1DACL_SRC */
-#define WM8995_AIF1DACL_SRC_SHIFT 15 /* AIF1DACL_SRC */
-#define WM8995_AIF1DACL_SRC_WIDTH 1 /* AIF1DACL_SRC */
-#define WM8995_AIF1DACR_SRC 0x4000 /* AIF1DACR_SRC */
-#define WM8995_AIF1DACR_SRC_MASK 0x4000 /* AIF1DACR_SRC */
-#define WM8995_AIF1DACR_SRC_SHIFT 14 /* AIF1DACR_SRC */
-#define WM8995_AIF1DACR_SRC_WIDTH 1 /* AIF1DACR_SRC */
-#define WM8995_AIF1DAC_BOOST_MASK 0x0C00 /* AIF1DAC_BOOST - [11:10] */
-#define WM8995_AIF1DAC_BOOST_SHIFT 10 /* AIF1DAC_BOOST - [11:10] */
-#define WM8995_AIF1DAC_BOOST_WIDTH 2 /* AIF1DAC_BOOST - [11:10] */
-#define WM8995_AIF1DAC_COMP 0x0010 /* AIF1DAC_COMP */
-#define WM8995_AIF1DAC_COMP_MASK 0x0010 /* AIF1DAC_COMP */
-#define WM8995_AIF1DAC_COMP_SHIFT 4 /* AIF1DAC_COMP */
-#define WM8995_AIF1DAC_COMP_WIDTH 1 /* AIF1DAC_COMP */
-#define WM8995_AIF1DAC_COMPMODE 0x0008 /* AIF1DAC_COMPMODE */
-#define WM8995_AIF1DAC_COMPMODE_MASK 0x0008 /* AIF1DAC_COMPMODE */
-#define WM8995_AIF1DAC_COMPMODE_SHIFT 3 /* AIF1DAC_COMPMODE */
-#define WM8995_AIF1DAC_COMPMODE_WIDTH 1 /* AIF1DAC_COMPMODE */
-#define WM8995_AIF1ADC_COMP 0x0004 /* AIF1ADC_COMP */
-#define WM8995_AIF1ADC_COMP_MASK 0x0004 /* AIF1ADC_COMP */
-#define WM8995_AIF1ADC_COMP_SHIFT 2 /* AIF1ADC_COMP */
-#define WM8995_AIF1ADC_COMP_WIDTH 1 /* AIF1ADC_COMP */
-#define WM8995_AIF1ADC_COMPMODE 0x0002 /* AIF1ADC_COMPMODE */
-#define WM8995_AIF1ADC_COMPMODE_MASK 0x0002 /* AIF1ADC_COMPMODE */
-#define WM8995_AIF1ADC_COMPMODE_SHIFT 1 /* AIF1ADC_COMPMODE */
-#define WM8995_AIF1ADC_COMPMODE_WIDTH 1 /* AIF1ADC_COMPMODE */
-#define WM8995_AIF1_LOOPBACK 0x0001 /* AIF1_LOOPBACK */
-#define WM8995_AIF1_LOOPBACK_MASK 0x0001 /* AIF1_LOOPBACK */
-#define WM8995_AIF1_LOOPBACK_SHIFT 0 /* AIF1_LOOPBACK */
-#define WM8995_AIF1_LOOPBACK_WIDTH 1 /* AIF1_LOOPBACK */
-
-/*
- * R770 (0x302) - AIF1 Master/Slave
- */
-#define WM8995_AIF1_TRI 0x8000 /* AIF1_TRI */
-#define WM8995_AIF1_TRI_MASK 0x8000 /* AIF1_TRI */
-#define WM8995_AIF1_TRI_SHIFT 15 /* AIF1_TRI */
-#define WM8995_AIF1_TRI_WIDTH 1 /* AIF1_TRI */
-#define WM8995_AIF1_MSTR 0x4000 /* AIF1_MSTR */
-#define WM8995_AIF1_MSTR_MASK 0x4000 /* AIF1_MSTR */
-#define WM8995_AIF1_MSTR_SHIFT 14 /* AIF1_MSTR */
-#define WM8995_AIF1_MSTR_WIDTH 1 /* AIF1_MSTR */
-#define WM8995_AIF1_CLK_FRC 0x2000 /* AIF1_CLK_FRC */
-#define WM8995_AIF1_CLK_FRC_MASK 0x2000 /* AIF1_CLK_FRC */
-#define WM8995_AIF1_CLK_FRC_SHIFT 13 /* AIF1_CLK_FRC */
-#define WM8995_AIF1_CLK_FRC_WIDTH 1 /* AIF1_CLK_FRC */
-#define WM8995_AIF1_LRCLK_FRC 0x1000 /* AIF1_LRCLK_FRC */
-#define WM8995_AIF1_LRCLK_FRC_MASK 0x1000 /* AIF1_LRCLK_FRC */
-#define WM8995_AIF1_LRCLK_FRC_SHIFT 12 /* AIF1_LRCLK_FRC */
-#define WM8995_AIF1_LRCLK_FRC_WIDTH 1 /* AIF1_LRCLK_FRC */
-
-/*
- * R771 (0x303) - AIF1 BCLK
- */
-#define WM8995_AIF1_BCLK_DIV_MASK 0x00F0 /* AIF1_BCLK_DIV - [7:4] */
-#define WM8995_AIF1_BCLK_DIV_SHIFT 4 /* AIF1_BCLK_DIV - [7:4] */
-#define WM8995_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [7:4] */
-
-/*
- * R772 (0x304) - AIF1ADC LRCLK
- */
-#define WM8995_AIF1ADC_LRCLK_DIR 0x0800 /* AIF1ADC_LRCLK_DIR */
-#define WM8995_AIF1ADC_LRCLK_DIR_MASK 0x0800 /* AIF1ADC_LRCLK_DIR */
-#define WM8995_AIF1ADC_LRCLK_DIR_SHIFT 11 /* AIF1ADC_LRCLK_DIR */
-#define WM8995_AIF1ADC_LRCLK_DIR_WIDTH 1 /* AIF1ADC_LRCLK_DIR */
-#define WM8995_AIF1ADC_RATE_MASK 0x07FF /* AIF1ADC_RATE - [10:0] */
-#define WM8995_AIF1ADC_RATE_SHIFT 0 /* AIF1ADC_RATE - [10:0] */
-#define WM8995_AIF1ADC_RATE_WIDTH 11 /* AIF1ADC_RATE - [10:0] */
-
-/*
- * R773 (0x305) - AIF1DAC LRCLK
- */
-#define WM8995_AIF1DAC_LRCLK_DIR 0x0800 /* AIF1DAC_LRCLK_DIR */
-#define WM8995_AIF1DAC_LRCLK_DIR_MASK 0x0800 /* AIF1DAC_LRCLK_DIR */
-#define WM8995_AIF1DAC_LRCLK_DIR_SHIFT 11 /* AIF1DAC_LRCLK_DIR */
-#define WM8995_AIF1DAC_LRCLK_DIR_WIDTH 1 /* AIF1DAC_LRCLK_DIR */
-#define WM8995_AIF1DAC_RATE_MASK 0x07FF /* AIF1DAC_RATE - [10:0] */
-#define WM8995_AIF1DAC_RATE_SHIFT 0 /* AIF1DAC_RATE - [10:0] */
-#define WM8995_AIF1DAC_RATE_WIDTH 11 /* AIF1DAC_RATE - [10:0] */
-
-/*
- * R774 (0x306) - AIF1DAC Data
- */
-#define WM8995_AIF1DACL_DAT_INV 0x0002 /* AIF1DACL_DAT_INV */
-#define WM8995_AIF1DACL_DAT_INV_MASK 0x0002 /* AIF1DACL_DAT_INV */
-#define WM8995_AIF1DACL_DAT_INV_SHIFT 1 /* AIF1DACL_DAT_INV */
-#define WM8995_AIF1DACL_DAT_INV_WIDTH 1 /* AIF1DACL_DAT_INV */
-#define WM8995_AIF1DACR_DAT_INV 0x0001 /* AIF1DACR_DAT_INV */
-#define WM8995_AIF1DACR_DAT_INV_MASK 0x0001 /* AIF1DACR_DAT_INV */
-#define WM8995_AIF1DACR_DAT_INV_SHIFT 0 /* AIF1DACR_DAT_INV */
-#define WM8995_AIF1DACR_DAT_INV_WIDTH 1 /* AIF1DACR_DAT_INV */
-
-/*
- * R775 (0x307) - AIF1ADC Data
- */
-#define WM8995_AIF1ADCL_DAT_INV 0x0002 /* AIF1ADCL_DAT_INV */
-#define WM8995_AIF1ADCL_DAT_INV_MASK 0x0002 /* AIF1ADCL_DAT_INV */
-#define WM8995_AIF1ADCL_DAT_INV_SHIFT 1 /* AIF1ADCL_DAT_INV */
-#define WM8995_AIF1ADCL_DAT_INV_WIDTH 1 /* AIF1ADCL_DAT_INV */
-#define WM8995_AIF1ADCR_DAT_INV 0x0001 /* AIF1ADCR_DAT_INV */
-#define WM8995_AIF1ADCR_DAT_INV_MASK 0x0001 /* AIF1ADCR_DAT_INV */
-#define WM8995_AIF1ADCR_DAT_INV_SHIFT 0 /* AIF1ADCR_DAT_INV */
-#define WM8995_AIF1ADCR_DAT_INV_WIDTH 1 /* AIF1ADCR_DAT_INV */
-
-/*
- * R784 (0x310) - AIF2 Control (1)
- */
-#define WM8995_AIF2ADCL_SRC 0x8000 /* AIF2ADCL_SRC */
-#define WM8995_AIF2ADCL_SRC_MASK 0x8000 /* AIF2ADCL_SRC */
-#define WM8995_AIF2ADCL_SRC_SHIFT 15 /* AIF2ADCL_SRC */
-#define WM8995_AIF2ADCL_SRC_WIDTH 1 /* AIF2ADCL_SRC */
-#define WM8995_AIF2ADCR_SRC 0x4000 /* AIF2ADCR_SRC */
-#define WM8995_AIF2ADCR_SRC_MASK 0x4000 /* AIF2ADCR_SRC */
-#define WM8995_AIF2ADCR_SRC_SHIFT 14 /* AIF2ADCR_SRC */
-#define WM8995_AIF2ADCR_SRC_WIDTH 1 /* AIF2ADCR_SRC */
-#define WM8995_AIF2ADC_TDM 0x2000 /* AIF2ADC_TDM */
-#define WM8995_AIF2ADC_TDM_MASK 0x2000 /* AIF2ADC_TDM */
-#define WM8995_AIF2ADC_TDM_SHIFT 13 /* AIF2ADC_TDM */
-#define WM8995_AIF2ADC_TDM_WIDTH 1 /* AIF2ADC_TDM */
-#define WM8995_AIF2ADC_TDM_CHAN 0x1000 /* AIF2ADC_TDM_CHAN */
-#define WM8995_AIF2ADC_TDM_CHAN_MASK 0x1000 /* AIF2ADC_TDM_CHAN */
-#define WM8995_AIF2ADC_TDM_CHAN_SHIFT 12 /* AIF2ADC_TDM_CHAN */
-#define WM8995_AIF2ADC_TDM_CHAN_WIDTH 1 /* AIF2ADC_TDM_CHAN */
-#define WM8995_AIF2_BCLK_INV 0x0100 /* AIF2_BCLK_INV */
-#define WM8995_AIF2_BCLK_INV_MASK 0x0100 /* AIF2_BCLK_INV */
-#define WM8995_AIF2_BCLK_INV_SHIFT 8 /* AIF2_BCLK_INV */
-#define WM8995_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */
-#define WM8995_AIF2_LRCLK_INV 0x0080 /* AIF2_LRCLK_INV */
-#define WM8995_AIF2_LRCLK_INV_MASK 0x0080 /* AIF2_LRCLK_INV */
-#define WM8995_AIF2_LRCLK_INV_SHIFT 7 /* AIF2_LRCLK_INV */
-#define WM8995_AIF2_LRCLK_INV_WIDTH 1 /* AIF2_LRCLK_INV */
-#define WM8995_AIF2_WL_MASK 0x0060 /* AIF2_WL - [6:5] */
-#define WM8995_AIF2_WL_SHIFT 5 /* AIF2_WL - [6:5] */
-#define WM8995_AIF2_WL_WIDTH 2 /* AIF2_WL - [6:5] */
-#define WM8995_AIF2_FMT_MASK 0x0018 /* AIF2_FMT - [4:3] */
-#define WM8995_AIF2_FMT_SHIFT 3 /* AIF2_FMT - [4:3] */
-#define WM8995_AIF2_FMT_WIDTH 2 /* AIF2_FMT - [4:3] */
-
-/*
- * R785 (0x311) - AIF2 Control (2)
- */
-#define WM8995_AIF2DACL_SRC 0x8000 /* AIF2DACL_SRC */
-#define WM8995_AIF2DACL_SRC_MASK 0x8000 /* AIF2DACL_SRC */
-#define WM8995_AIF2DACL_SRC_SHIFT 15 /* AIF2DACL_SRC */
-#define WM8995_AIF2DACL_SRC_WIDTH 1 /* AIF2DACL_SRC */
-#define WM8995_AIF2DACR_SRC 0x4000 /* AIF2DACR_SRC */
-#define WM8995_AIF2DACR_SRC_MASK 0x4000 /* AIF2DACR_SRC */
-#define WM8995_AIF2DACR_SRC_SHIFT 14 /* AIF2DACR_SRC */
-#define WM8995_AIF2DACR_SRC_WIDTH 1 /* AIF2DACR_SRC */
-#define WM8995_AIF2DAC_TDM 0x2000 /* AIF2DAC_TDM */
-#define WM8995_AIF2DAC_TDM_MASK 0x2000 /* AIF2DAC_TDM */
-#define WM8995_AIF2DAC_TDM_SHIFT 13 /* AIF2DAC_TDM */
-#define WM8995_AIF2DAC_TDM_WIDTH 1 /* AIF2DAC_TDM */
-#define WM8995_AIF2DAC_TDM_CHAN 0x1000 /* AIF2DAC_TDM_CHAN */
-#define WM8995_AIF2DAC_TDM_CHAN_MASK 0x1000 /* AIF2DAC_TDM_CHAN */
-#define WM8995_AIF2DAC_TDM_CHAN_SHIFT 12 /* AIF2DAC_TDM_CHAN */
-#define WM8995_AIF2DAC_TDM_CHAN_WIDTH 1 /* AIF2DAC_TDM_CHAN */
-#define WM8995_AIF2DAC_BOOST_MASK 0x0C00 /* AIF2DAC_BOOST - [11:10] */
-#define WM8995_AIF2DAC_BOOST_SHIFT 10 /* AIF2DAC_BOOST - [11:10] */
-#define WM8995_AIF2DAC_BOOST_WIDTH 2 /* AIF2DAC_BOOST - [11:10] */
-#define WM8995_AIF2DAC_COMP 0x0010 /* AIF2DAC_COMP */
-#define WM8995_AIF2DAC_COMP_MASK 0x0010 /* AIF2DAC_COMP */
-#define WM8995_AIF2DAC_COMP_SHIFT 4 /* AIF2DAC_COMP */
-#define WM8995_AIF2DAC_COMP_WIDTH 1 /* AIF2DAC_COMP */
-#define WM8995_AIF2DAC_COMPMODE 0x0008 /* AIF2DAC_COMPMODE */
-#define WM8995_AIF2DAC_COMPMODE_MASK 0x0008 /* AIF2DAC_COMPMODE */
-#define WM8995_AIF2DAC_COMPMODE_SHIFT 3 /* AIF2DAC_COMPMODE */
-#define WM8995_AIF2DAC_COMPMODE_WIDTH 1 /* AIF2DAC_COMPMODE */
-#define WM8995_AIF2ADC_COMP 0x0004 /* AIF2ADC_COMP */
-#define WM8995_AIF2ADC_COMP_MASK 0x0004 /* AIF2ADC_COMP */
-#define WM8995_AIF2ADC_COMP_SHIFT 2 /* AIF2ADC_COMP */
-#define WM8995_AIF2ADC_COMP_WIDTH 1 /* AIF2ADC_COMP */
-#define WM8995_AIF2ADC_COMPMODE 0x0002 /* AIF2ADC_COMPMODE */
-#define WM8995_AIF2ADC_COMPMODE_MASK 0x0002 /* AIF2ADC_COMPMODE */
-#define WM8995_AIF2ADC_COMPMODE_SHIFT 1 /* AIF2ADC_COMPMODE */
-#define WM8995_AIF2ADC_COMPMODE_WIDTH 1 /* AIF2ADC_COMPMODE */
-#define WM8995_AIF2_LOOPBACK 0x0001 /* AIF2_LOOPBACK */
-#define WM8995_AIF2_LOOPBACK_MASK 0x0001 /* AIF2_LOOPBACK */
-#define WM8995_AIF2_LOOPBACK_SHIFT 0 /* AIF2_LOOPBACK */
-#define WM8995_AIF2_LOOPBACK_WIDTH 1 /* AIF2_LOOPBACK */
-
-/*
- * R786 (0x312) - AIF2 Master/Slave
- */
-#define WM8995_AIF2_TRI 0x8000 /* AIF2_TRI */
-#define WM8995_AIF2_TRI_MASK 0x8000 /* AIF2_TRI */
-#define WM8995_AIF2_TRI_SHIFT 15 /* AIF2_TRI */
-#define WM8995_AIF2_TRI_WIDTH 1 /* AIF2_TRI */
-#define WM8995_AIF2_MSTR 0x4000 /* AIF2_MSTR */
-#define WM8995_AIF2_MSTR_MASK 0x4000 /* AIF2_MSTR */
-#define WM8995_AIF2_MSTR_SHIFT 14 /* AIF2_MSTR */
-#define WM8995_AIF2_MSTR_WIDTH 1 /* AIF2_MSTR */
-#define WM8995_AIF2_CLK_FRC 0x2000 /* AIF2_CLK_FRC */
-#define WM8995_AIF2_CLK_FRC_MASK 0x2000 /* AIF2_CLK_FRC */
-#define WM8995_AIF2_CLK_FRC_SHIFT 13 /* AIF2_CLK_FRC */
-#define WM8995_AIF2_CLK_FRC_WIDTH 1 /* AIF2_CLK_FRC */
-#define WM8995_AIF2_LRCLK_FRC 0x1000 /* AIF2_LRCLK_FRC */
-#define WM8995_AIF2_LRCLK_FRC_MASK 0x1000 /* AIF2_LRCLK_FRC */
-#define WM8995_AIF2_LRCLK_FRC_SHIFT 12 /* AIF2_LRCLK_FRC */
-#define WM8995_AIF2_LRCLK_FRC_WIDTH 1 /* AIF2_LRCLK_FRC */
-
-/*
- * R787 (0x313) - AIF2 BCLK
- */
-#define WM8995_AIF2_BCLK_DIV_MASK 0x00F0 /* AIF2_BCLK_DIV - [7:4] */
-#define WM8995_AIF2_BCLK_DIV_SHIFT 4 /* AIF2_BCLK_DIV - [7:4] */
-#define WM8995_AIF2_BCLK_DIV_WIDTH 4 /* AIF2_BCLK_DIV - [7:4] */
-
-/*
- * R788 (0x314) - AIF2ADC LRCLK
- */
-#define WM8995_AIF2ADC_LRCLK_DIR 0x0800 /* AIF2ADC_LRCLK_DIR */
-#define WM8995_AIF2ADC_LRCLK_DIR_MASK 0x0800 /* AIF2ADC_LRCLK_DIR */
-#define WM8995_AIF2ADC_LRCLK_DIR_SHIFT 11 /* AIF2ADC_LRCLK_DIR */
-#define WM8995_AIF2ADC_LRCLK_DIR_WIDTH 1 /* AIF2ADC_LRCLK_DIR */
-#define WM8995_AIF2ADC_RATE_MASK 0x07FF /* AIF2ADC_RATE - [10:0] */
-#define WM8995_AIF2ADC_RATE_SHIFT 0 /* AIF2ADC_RATE - [10:0] */
-#define WM8995_AIF2ADC_RATE_WIDTH 11 /* AIF2ADC_RATE - [10:0] */
-
-/*
- * R789 (0x315) - AIF2DAC LRCLK
- */
-#define WM8995_AIF2DAC_LRCLK_DIR 0x0800 /* AIF2DAC_LRCLK_DIR */
-#define WM8995_AIF2DAC_LRCLK_DIR_MASK 0x0800 /* AIF2DAC_LRCLK_DIR */
-#define WM8995_AIF2DAC_LRCLK_DIR_SHIFT 11 /* AIF2DAC_LRCLK_DIR */
-#define WM8995_AIF2DAC_LRCLK_DIR_WIDTH 1 /* AIF2DAC_LRCLK_DIR */
-#define WM8995_AIF2DAC_RATE_MASK 0x07FF /* AIF2DAC_RATE - [10:0] */
-#define WM8995_AIF2DAC_RATE_SHIFT 0 /* AIF2DAC_RATE - [10:0] */
-#define WM8995_AIF2DAC_RATE_WIDTH 11 /* AIF2DAC_RATE - [10:0] */
-
-/*
- * R790 (0x316) - AIF2DAC Data
- */
-#define WM8995_AIF2DACL_DAT_INV 0x0002 /* AIF2DACL_DAT_INV */
-#define WM8995_AIF2DACL_DAT_INV_MASK 0x0002 /* AIF2DACL_DAT_INV */
-#define WM8995_AIF2DACL_DAT_INV_SHIFT 1 /* AIF2DACL_DAT_INV */
-#define WM8995_AIF2DACL_DAT_INV_WIDTH 1 /* AIF2DACL_DAT_INV */
-#define WM8995_AIF2DACR_DAT_INV 0x0001 /* AIF2DACR_DAT_INV */
-#define WM8995_AIF2DACR_DAT_INV_MASK 0x0001 /* AIF2DACR_DAT_INV */
-#define WM8995_AIF2DACR_DAT_INV_SHIFT 0 /* AIF2DACR_DAT_INV */
-#define WM8995_AIF2DACR_DAT_INV_WIDTH 1 /* AIF2DACR_DAT_INV */
-
-/*
- * R791 (0x317) - AIF2ADC Data
- */
-#define WM8995_AIF2ADCL_DAT_INV 0x0002 /* AIF2ADCL_DAT_INV */
-#define WM8995_AIF2ADCL_DAT_INV_MASK 0x0002 /* AIF2ADCL_DAT_INV */
-#define WM8995_AIF2ADCL_DAT_INV_SHIFT 1 /* AIF2ADCL_DAT_INV */
-#define WM8995_AIF2ADCL_DAT_INV_WIDTH 1 /* AIF2ADCL_DAT_INV */
-#define WM8995_AIF2ADCR_DAT_INV 0x0001 /* AIF2ADCR_DAT_INV */
-#define WM8995_AIF2ADCR_DAT_INV_MASK 0x0001 /* AIF2ADCR_DAT_INV */
-#define WM8995_AIF2ADCR_DAT_INV_SHIFT 0 /* AIF2ADCR_DAT_INV */
-#define WM8995_AIF2ADCR_DAT_INV_WIDTH 1 /* AIF2ADCR_DAT_INV */
-
-/*
- * R1024 (0x400) - AIF1 ADC1 Left Volume
- */
-#define WM8995_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */
-#define WM8995_AIF1ADC1_VU_MASK 0x0100 /* AIF1ADC1_VU */
-#define WM8995_AIF1ADC1_VU_SHIFT 8 /* AIF1ADC1_VU */
-#define WM8995_AIF1ADC1_VU_WIDTH 1 /* AIF1ADC1_VU */
-#define WM8995_AIF1ADC1L_VOL_MASK 0x00FF /* AIF1ADC1L_VOL - [7:0] */
-#define WM8995_AIF1ADC1L_VOL_SHIFT 0 /* AIF1ADC1L_VOL - [7:0] */
-#define WM8995_AIF1ADC1L_VOL_WIDTH 8 /* AIF1ADC1L_VOL - [7:0] */
-
-/*
- * R1025 (0x401) - AIF1 ADC1 Right Volume
- */
-#define WM8995_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */
-#define WM8995_AIF1ADC1_VU_MASK 0x0100 /* AIF1ADC1_VU */
-#define WM8995_AIF1ADC1_VU_SHIFT 8 /* AIF1ADC1_VU */
-#define WM8995_AIF1ADC1_VU_WIDTH 1 /* AIF1ADC1_VU */
-#define WM8995_AIF1ADC1R_VOL_MASK 0x00FF /* AIF1ADC1R_VOL - [7:0] */
-#define WM8995_AIF1ADC1R_VOL_SHIFT 0 /* AIF1ADC1R_VOL - [7:0] */
-#define WM8995_AIF1ADC1R_VOL_WIDTH 8 /* AIF1ADC1R_VOL - [7:0] */
-
-/*
- * R1026 (0x402) - AIF1 DAC1 Left Volume
- */
-#define WM8995_AIF1DAC1_VU 0x0100 /* AIF1DAC1_VU */
-#define WM8995_AIF1DAC1_VU_MASK 0x0100 /* AIF1DAC1_VU */
-#define WM8995_AIF1DAC1_VU_SHIFT 8 /* AIF1DAC1_VU */
-#define WM8995_AIF1DAC1_VU_WIDTH 1 /* AIF1DAC1_VU */
-#define WM8995_AIF1DAC1L_VOL_MASK 0x00FF /* AIF1DAC1L_VOL - [7:0] */
-#define WM8995_AIF1DAC1L_VOL_SHIFT 0 /* AIF1DAC1L_VOL - [7:0] */
-#define WM8995_AIF1DAC1L_VOL_WIDTH 8 /* AIF1DAC1L_VOL - [7:0] */
-
-/*
- * R1027 (0x403) - AIF1 DAC1 Right Volume
- */
-#define WM8995_AIF1DAC1_VU 0x0100 /* AIF1DAC1_VU */
-#define WM8995_AIF1DAC1_VU_MASK 0x0100 /* AIF1DAC1_VU */
-#define WM8995_AIF1DAC1_VU_SHIFT 8 /* AIF1DAC1_VU */
-#define WM8995_AIF1DAC1_VU_WIDTH 1 /* AIF1DAC1_VU */
-#define WM8995_AIF1DAC1R_VOL_MASK 0x00FF /* AIF1DAC1R_VOL - [7:0] */
-#define WM8995_AIF1DAC1R_VOL_SHIFT 0 /* AIF1DAC1R_VOL - [7:0] */
-#define WM8995_AIF1DAC1R_VOL_WIDTH 8 /* AIF1DAC1R_VOL - [7:0] */
-
-/*
- * R1028 (0x404) - AIF1 ADC2 Left Volume
- */
-#define WM8995_AIF1ADC2_VU 0x0100 /* AIF1ADC2_VU */
-#define WM8995_AIF1ADC2_VU_MASK 0x0100 /* AIF1ADC2_VU */
-#define WM8995_AIF1ADC2_VU_SHIFT 8 /* AIF1ADC2_VU */
-#define WM8995_AIF1ADC2_VU_WIDTH 1 /* AIF1ADC2_VU */
-#define WM8995_AIF1ADC2L_VOL_MASK 0x00FF /* AIF1ADC2L_VOL - [7:0] */
-#define WM8995_AIF1ADC2L_VOL_SHIFT 0 /* AIF1ADC2L_VOL - [7:0] */
-#define WM8995_AIF1ADC2L_VOL_WIDTH 8 /* AIF1ADC2L_VOL - [7:0] */
-
-/*
- * R1029 (0x405) - AIF1 ADC2 Right Volume
- */
-#define WM8995_AIF1ADC2_VU 0x0100 /* AIF1ADC2_VU */
-#define WM8995_AIF1ADC2_VU_MASK 0x0100 /* AIF1ADC2_VU */
-#define WM8995_AIF1ADC2_VU_SHIFT 8 /* AIF1ADC2_VU */
-#define WM8995_AIF1ADC2_VU_WIDTH 1 /* AIF1ADC2_VU */
-#define WM8995_AIF1ADC2R_VOL_MASK 0x00FF /* AIF1ADC2R_VOL - [7:0] */
-#define WM8995_AIF1ADC2R_VOL_SHIFT 0 /* AIF1ADC2R_VOL - [7:0] */
-#define WM8995_AIF1ADC2R_VOL_WIDTH 8 /* AIF1ADC2R_VOL - [7:0] */
-
-/*
- * R1030 (0x406) - AIF1 DAC2 Left Volume
- */
-#define WM8995_AIF1DAC2_VU 0x0100 /* AIF1DAC2_VU */
-#define WM8995_AIF1DAC2_VU_MASK 0x0100 /* AIF1DAC2_VU */
-#define WM8995_AIF1DAC2_VU_SHIFT 8 /* AIF1DAC2_VU */
-#define WM8995_AIF1DAC2_VU_WIDTH 1 /* AIF1DAC2_VU */
-#define WM8995_AIF1DAC2L_VOL_MASK 0x00FF /* AIF1DAC2L_VOL - [7:0] */
-#define WM8995_AIF1DAC2L_VOL_SHIFT 0 /* AIF1DAC2L_VOL - [7:0] */
-#define WM8995_AIF1DAC2L_VOL_WIDTH 8 /* AIF1DAC2L_VOL - [7:0] */
-
-/*
- * R1031 (0x407) - AIF1 DAC2 Right Volume
- */
-#define WM8995_AIF1DAC2_VU 0x0100 /* AIF1DAC2_VU */
-#define WM8995_AIF1DAC2_VU_MASK 0x0100 /* AIF1DAC2_VU */
-#define WM8995_AIF1DAC2_VU_SHIFT 8 /* AIF1DAC2_VU */
-#define WM8995_AIF1DAC2_VU_WIDTH 1 /* AIF1DAC2_VU */
-#define WM8995_AIF1DAC2R_VOL_MASK 0x00FF /* AIF1DAC2R_VOL - [7:0] */
-#define WM8995_AIF1DAC2R_VOL_SHIFT 0 /* AIF1DAC2R_VOL - [7:0] */
-#define WM8995_AIF1DAC2R_VOL_WIDTH 8 /* AIF1DAC2R_VOL - [7:0] */
-
-/*
- * R1040 (0x410) - AIF1 ADC1 Filters
- */
-#define WM8995_AIF1ADC_4FS 0x8000 /* AIF1ADC_4FS */
-#define WM8995_AIF1ADC_4FS_MASK 0x8000 /* AIF1ADC_4FS */
-#define WM8995_AIF1ADC_4FS_SHIFT 15 /* AIF1ADC_4FS */
-#define WM8995_AIF1ADC_4FS_WIDTH 1 /* AIF1ADC_4FS */
-#define WM8995_AIF1ADC1L_HPF 0x1000 /* AIF1ADC1L_HPF */
-#define WM8995_AIF1ADC1L_HPF_MASK 0x1000 /* AIF1ADC1L_HPF */
-#define WM8995_AIF1ADC1L_HPF_SHIFT 12 /* AIF1ADC1L_HPF */
-#define WM8995_AIF1ADC1L_HPF_WIDTH 1 /* AIF1ADC1L_HPF */
-#define WM8995_AIF1ADC1R_HPF 0x0800 /* AIF1ADC1R_HPF */
-#define WM8995_AIF1ADC1R_HPF_MASK 0x0800 /* AIF1ADC1R_HPF */
-#define WM8995_AIF1ADC1R_HPF_SHIFT 11 /* AIF1ADC1R_HPF */
-#define WM8995_AIF1ADC1R_HPF_WIDTH 1 /* AIF1ADC1R_HPF */
-#define WM8995_AIF1ADC1_HPF_MODE 0x0008 /* AIF1ADC1_HPF_MODE */
-#define WM8995_AIF1ADC1_HPF_MODE_MASK 0x0008 /* AIF1ADC1_HPF_MODE */
-#define WM8995_AIF1ADC1_HPF_MODE_SHIFT 3 /* AIF1ADC1_HPF_MODE */
-#define WM8995_AIF1ADC1_HPF_MODE_WIDTH 1 /* AIF1ADC1_HPF_MODE */
-#define WM8995_AIF1ADC1_HPF_CUT_MASK 0x0007 /* AIF1ADC1_HPF_CUT - [2:0] */
-#define WM8995_AIF1ADC1_HPF_CUT_SHIFT 0 /* AIF1ADC1_HPF_CUT - [2:0] */
-#define WM8995_AIF1ADC1_HPF_CUT_WIDTH 3 /* AIF1ADC1_HPF_CUT - [2:0] */
-
-/*
- * R1041 (0x411) - AIF1 ADC2 Filters
- */
-#define WM8995_AIF1ADC2L_HPF 0x1000 /* AIF1ADC2L_HPF */
-#define WM8995_AIF1ADC2L_HPF_MASK 0x1000 /* AIF1ADC2L_HPF */
-#define WM8995_AIF1ADC2L_HPF_SHIFT 12 /* AIF1ADC2L_HPF */
-#define WM8995_AIF1ADC2L_HPF_WIDTH 1 /* AIF1ADC2L_HPF */
-#define WM8995_AIF1ADC2R_HPF 0x0800 /* AIF1ADC2R_HPF */
-#define WM8995_AIF1ADC2R_HPF_MASK 0x0800 /* AIF1ADC2R_HPF */
-#define WM8995_AIF1ADC2R_HPF_SHIFT 11 /* AIF1ADC2R_HPF */
-#define WM8995_AIF1ADC2R_HPF_WIDTH 1 /* AIF1ADC2R_HPF */
-#define WM8995_AIF1ADC2_HPF_MODE 0x0008 /* AIF1ADC2_HPF_MODE */
-#define WM8995_AIF1ADC2_HPF_MODE_MASK 0x0008 /* AIF1ADC2_HPF_MODE */
-#define WM8995_AIF1ADC2_HPF_MODE_SHIFT 3 /* AIF1ADC2_HPF_MODE */
-#define WM8995_AIF1ADC2_HPF_MODE_WIDTH 1 /* AIF1ADC2_HPF_MODE */
-#define WM8995_AIF1ADC2_HPF_CUT_MASK 0x0007 /* AIF1ADC2_HPF_CUT - [2:0] */
-#define WM8995_AIF1ADC2_HPF_CUT_SHIFT 0 /* AIF1ADC2_HPF_CUT - [2:0] */
-#define WM8995_AIF1ADC2_HPF_CUT_WIDTH 3 /* AIF1ADC2_HPF_CUT - [2:0] */
-
-/*
- * R1056 (0x420) - AIF1 DAC1 Filters (1)
- */
-#define WM8995_AIF1DAC1_MUTE 0x0200 /* AIF1DAC1_MUTE */
-#define WM8995_AIF1DAC1_MUTE_MASK 0x0200 /* AIF1DAC1_MUTE */
-#define WM8995_AIF1DAC1_MUTE_SHIFT 9 /* AIF1DAC1_MUTE */
-#define WM8995_AIF1DAC1_MUTE_WIDTH 1 /* AIF1DAC1_MUTE */
-#define WM8995_AIF1DAC1_MONO 0x0080 /* AIF1DAC1_MONO */
-#define WM8995_AIF1DAC1_MONO_MASK 0x0080 /* AIF1DAC1_MONO */
-#define WM8995_AIF1DAC1_MONO_SHIFT 7 /* AIF1DAC1_MONO */
-#define WM8995_AIF1DAC1_MONO_WIDTH 1 /* AIF1DAC1_MONO */
-#define WM8995_AIF1DAC1_MUTERATE 0x0020 /* AIF1DAC1_MUTERATE */
-#define WM8995_AIF1DAC1_MUTERATE_MASK 0x0020 /* AIF1DAC1_MUTERATE */
-#define WM8995_AIF1DAC1_MUTERATE_SHIFT 5 /* AIF1DAC1_MUTERATE */
-#define WM8995_AIF1DAC1_MUTERATE_WIDTH 1 /* AIF1DAC1_MUTERATE */
-#define WM8995_AIF1DAC1_UNMUTE_RAMP 0x0010 /* AIF1DAC1_UNMUTE_RAMP */
-#define WM8995_AIF1DAC1_UNMUTE_RAMP_MASK 0x0010 /* AIF1DAC1_UNMUTE_RAMP */
-#define WM8995_AIF1DAC1_UNMUTE_RAMP_SHIFT 4 /* AIF1DAC1_UNMUTE_RAMP */
-#define WM8995_AIF1DAC1_UNMUTE_RAMP_WIDTH 1 /* AIF1DAC1_UNMUTE_RAMP */
-#define WM8995_AIF1DAC1_DEEMP_MASK 0x0006 /* AIF1DAC1_DEEMP - [2:1] */
-#define WM8995_AIF1DAC1_DEEMP_SHIFT 1 /* AIF1DAC1_DEEMP - [2:1] */
-#define WM8995_AIF1DAC1_DEEMP_WIDTH 2 /* AIF1DAC1_DEEMP - [2:1] */
-
-/*
- * R1057 (0x421) - AIF1 DAC1 Filters (2)
- */
-#define WM8995_AIF1DAC1_3D_GAIN_MASK 0x3E00 /* AIF1DAC1_3D_GAIN - [13:9] */
-#define WM8995_AIF1DAC1_3D_GAIN_SHIFT 9 /* AIF1DAC1_3D_GAIN - [13:9] */
-#define WM8995_AIF1DAC1_3D_GAIN_WIDTH 5 /* AIF1DAC1_3D_GAIN - [13:9] */
-#define WM8995_AIF1DAC1_3D_ENA 0x0100 /* AIF1DAC1_3D_ENA */
-#define WM8995_AIF1DAC1_3D_ENA_MASK 0x0100 /* AIF1DAC1_3D_ENA */
-#define WM8995_AIF1DAC1_3D_ENA_SHIFT 8 /* AIF1DAC1_3D_ENA */
-#define WM8995_AIF1DAC1_3D_ENA_WIDTH 1 /* AIF1DAC1_3D_ENA */
-
-/*
- * R1058 (0x422) - AIF1 DAC2 Filters (1)
- */
-#define WM8995_AIF1DAC2_MUTE 0x0200 /* AIF1DAC2_MUTE */
-#define WM8995_AIF1DAC2_MUTE_MASK 0x0200 /* AIF1DAC2_MUTE */
-#define WM8995_AIF1DAC2_MUTE_SHIFT 9 /* AIF1DAC2_MUTE */
-#define WM8995_AIF1DAC2_MUTE_WIDTH 1 /* AIF1DAC2_MUTE */
-#define WM8995_AIF1DAC2_MONO 0x0080 /* AIF1DAC2_MONO */
-#define WM8995_AIF1DAC2_MONO_MASK 0x0080 /* AIF1DAC2_MONO */
-#define WM8995_AIF1DAC2_MONO_SHIFT 7 /* AIF1DAC2_MONO */
-#define WM8995_AIF1DAC2_MONO_WIDTH 1 /* AIF1DAC2_MONO */
-#define WM8995_AIF1DAC2_MUTERATE 0x0020 /* AIF1DAC2_MUTERATE */
-#define WM8995_AIF1DAC2_MUTERATE_MASK 0x0020 /* AIF1DAC2_MUTERATE */
-#define WM8995_AIF1DAC2_MUTERATE_SHIFT 5 /* AIF1DAC2_MUTERATE */
-#define WM8995_AIF1DAC2_MUTERATE_WIDTH 1 /* AIF1DAC2_MUTERATE */
-#define WM8995_AIF1DAC2_UNMUTE_RAMP 0x0010 /* AIF1DAC2_UNMUTE_RAMP */
-#define WM8995_AIF1DAC2_UNMUTE_RAMP_MASK 0x0010 /* AIF1DAC2_UNMUTE_RAMP */
-#define WM8995_AIF1DAC2_UNMUTE_RAMP_SHIFT 4 /* AIF1DAC2_UNMUTE_RAMP */
-#define WM8995_AIF1DAC2_UNMUTE_RAMP_WIDTH 1 /* AIF1DAC2_UNMUTE_RAMP */
-#define WM8995_AIF1DAC2_DEEMP_MASK 0x0006 /* AIF1DAC2_DEEMP - [2:1] */
-#define WM8995_AIF1DAC2_DEEMP_SHIFT 1 /* AIF1DAC2_DEEMP - [2:1] */
-#define WM8995_AIF1DAC2_DEEMP_WIDTH 2 /* AIF1DAC2_DEEMP - [2:1] */
-
-/*
- * R1059 (0x423) - AIF1 DAC2 Filters (2)
- */
-#define WM8995_AIF1DAC2_3D_GAIN_MASK 0x3E00 /* AIF1DAC2_3D_GAIN - [13:9] */
-#define WM8995_AIF1DAC2_3D_GAIN_SHIFT 9 /* AIF1DAC2_3D_GAIN - [13:9] */
-#define WM8995_AIF1DAC2_3D_GAIN_WIDTH 5 /* AIF1DAC2_3D_GAIN - [13:9] */
-#define WM8995_AIF1DAC2_3D_ENA 0x0100 /* AIF1DAC2_3D_ENA */
-#define WM8995_AIF1DAC2_3D_ENA_MASK 0x0100 /* AIF1DAC2_3D_ENA */
-#define WM8995_AIF1DAC2_3D_ENA_SHIFT 8 /* AIF1DAC2_3D_ENA */
-#define WM8995_AIF1DAC2_3D_ENA_WIDTH 1 /* AIF1DAC2_3D_ENA */
-
-/*
- * R1088 (0x440) - AIF1 DRC1 (1)
- */
-#define WM8995_AIF1DRC1_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
-#define WM8995_AIF1DRC1_SIG_DET_RMS_SHIFT 11 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
-#define WM8995_AIF1DRC1_SIG_DET_RMS_WIDTH 5 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
-#define WM8995_AIF1DRC1_SIG_DET_PK_MASK 0x0600 /* AIF1DRC1_SIG_DET_PK - [10:9] */
-#define WM8995_AIF1DRC1_SIG_DET_PK_SHIFT 9 /* AIF1DRC1_SIG_DET_PK - [10:9] */
-#define WM8995_AIF1DRC1_SIG_DET_PK_WIDTH 2 /* AIF1DRC1_SIG_DET_PK - [10:9] */
-#define WM8995_AIF1DRC1_NG_ENA 0x0100 /* AIF1DRC1_NG_ENA */
-#define WM8995_AIF1DRC1_NG_ENA_MASK 0x0100 /* AIF1DRC1_NG_ENA */
-#define WM8995_AIF1DRC1_NG_ENA_SHIFT 8 /* AIF1DRC1_NG_ENA */
-#define WM8995_AIF1DRC1_NG_ENA_WIDTH 1 /* AIF1DRC1_NG_ENA */
-#define WM8995_AIF1DRC1_SIG_DET_MODE 0x0080 /* AIF1DRC1_SIG_DET_MODE */
-#define WM8995_AIF1DRC1_SIG_DET_MODE_MASK 0x0080 /* AIF1DRC1_SIG_DET_MODE */
-#define WM8995_AIF1DRC1_SIG_DET_MODE_SHIFT 7 /* AIF1DRC1_SIG_DET_MODE */
-#define WM8995_AIF1DRC1_SIG_DET_MODE_WIDTH 1 /* AIF1DRC1_SIG_DET_MODE */
-#define WM8995_AIF1DRC1_SIG_DET 0x0040 /* AIF1DRC1_SIG_DET */
-#define WM8995_AIF1DRC1_SIG_DET_MASK 0x0040 /* AIF1DRC1_SIG_DET */
-#define WM8995_AIF1DRC1_SIG_DET_SHIFT 6 /* AIF1DRC1_SIG_DET */
-#define WM8995_AIF1DRC1_SIG_DET_WIDTH 1 /* AIF1DRC1_SIG_DET */
-#define WM8995_AIF1DRC1_KNEE2_OP_ENA 0x0020 /* AIF1DRC1_KNEE2_OP_ENA */
-#define WM8995_AIF1DRC1_KNEE2_OP_ENA_MASK 0x0020 /* AIF1DRC1_KNEE2_OP_ENA */
-#define WM8995_AIF1DRC1_KNEE2_OP_ENA_SHIFT 5 /* AIF1DRC1_KNEE2_OP_ENA */
-#define WM8995_AIF1DRC1_KNEE2_OP_ENA_WIDTH 1 /* AIF1DRC1_KNEE2_OP_ENA */
-#define WM8995_AIF1DRC1_QR 0x0010 /* AIF1DRC1_QR */
-#define WM8995_AIF1DRC1_QR_MASK 0x0010 /* AIF1DRC1_QR */
-#define WM8995_AIF1DRC1_QR_SHIFT 4 /* AIF1DRC1_QR */
-#define WM8995_AIF1DRC1_QR_WIDTH 1 /* AIF1DRC1_QR */
-#define WM8995_AIF1DRC1_ANTICLIP 0x0008 /* AIF1DRC1_ANTICLIP */
-#define WM8995_AIF1DRC1_ANTICLIP_MASK 0x0008 /* AIF1DRC1_ANTICLIP */
-#define WM8995_AIF1DRC1_ANTICLIP_SHIFT 3 /* AIF1DRC1_ANTICLIP */
-#define WM8995_AIF1DRC1_ANTICLIP_WIDTH 1 /* AIF1DRC1_ANTICLIP */
-#define WM8995_AIF1DAC1_DRC_ENA 0x0004 /* AIF1DAC1_DRC_ENA */
-#define WM8995_AIF1DAC1_DRC_ENA_MASK 0x0004 /* AIF1DAC1_DRC_ENA */
-#define WM8995_AIF1DAC1_DRC_ENA_SHIFT 2 /* AIF1DAC1_DRC_ENA */
-#define WM8995_AIF1DAC1_DRC_ENA_WIDTH 1 /* AIF1DAC1_DRC_ENA */
-#define WM8995_AIF1ADC1L_DRC_ENA 0x0002 /* AIF1ADC1L_DRC_ENA */
-#define WM8995_AIF1ADC1L_DRC_ENA_MASK 0x0002 /* AIF1ADC1L_DRC_ENA */
-#define WM8995_AIF1ADC1L_DRC_ENA_SHIFT 1 /* AIF1ADC1L_DRC_ENA */
-#define WM8995_AIF1ADC1L_DRC_ENA_WIDTH 1 /* AIF1ADC1L_DRC_ENA */
-#define WM8995_AIF1ADC1R_DRC_ENA 0x0001 /* AIF1ADC1R_DRC_ENA */
-#define WM8995_AIF1ADC1R_DRC_ENA_MASK 0x0001 /* AIF1ADC1R_DRC_ENA */
-#define WM8995_AIF1ADC1R_DRC_ENA_SHIFT 0 /* AIF1ADC1R_DRC_ENA */
-#define WM8995_AIF1ADC1R_DRC_ENA_WIDTH 1 /* AIF1ADC1R_DRC_ENA */
-
-/*
- * R1089 (0x441) - AIF1 DRC1 (2)
- */
-#define WM8995_AIF1DRC1_ATK_MASK 0x1E00 /* AIF1DRC1_ATK - [12:9] */
-#define WM8995_AIF1DRC1_ATK_SHIFT 9 /* AIF1DRC1_ATK - [12:9] */
-#define WM8995_AIF1DRC1_ATK_WIDTH 4 /* AIF1DRC1_ATK - [12:9] */
-#define WM8995_AIF1DRC1_DCY_MASK 0x01E0 /* AIF1DRC1_DCY - [8:5] */
-#define WM8995_AIF1DRC1_DCY_SHIFT 5 /* AIF1DRC1_DCY - [8:5] */
-#define WM8995_AIF1DRC1_DCY_WIDTH 4 /* AIF1DRC1_DCY - [8:5] */
-#define WM8995_AIF1DRC1_MINGAIN_MASK 0x001C /* AIF1DRC1_MINGAIN - [4:2] */
-#define WM8995_AIF1DRC1_MINGAIN_SHIFT 2 /* AIF1DRC1_MINGAIN - [4:2] */
-#define WM8995_AIF1DRC1_MINGAIN_WIDTH 3 /* AIF1DRC1_MINGAIN - [4:2] */
-#define WM8995_AIF1DRC1_MAXGAIN_MASK 0x0003 /* AIF1DRC1_MAXGAIN - [1:0] */
-#define WM8995_AIF1DRC1_MAXGAIN_SHIFT 0 /* AIF1DRC1_MAXGAIN - [1:0] */
-#define WM8995_AIF1DRC1_MAXGAIN_WIDTH 2 /* AIF1DRC1_MAXGAIN - [1:0] */
-
-/*
- * R1090 (0x442) - AIF1 DRC1 (3)
- */
-#define WM8995_AIF1DRC1_NG_MINGAIN_MASK 0xF000 /* AIF1DRC1_NG_MINGAIN - [15:12] */
-#define WM8995_AIF1DRC1_NG_MINGAIN_SHIFT 12 /* AIF1DRC1_NG_MINGAIN - [15:12] */
-#define WM8995_AIF1DRC1_NG_MINGAIN_WIDTH 4 /* AIF1DRC1_NG_MINGAIN - [15:12] */
-#define WM8995_AIF1DRC1_NG_EXP_MASK 0x0C00 /* AIF1DRC1_NG_EXP - [11:10] */
-#define WM8995_AIF1DRC1_NG_EXP_SHIFT 10 /* AIF1DRC1_NG_EXP - [11:10] */
-#define WM8995_AIF1DRC1_NG_EXP_WIDTH 2 /* AIF1DRC1_NG_EXP - [11:10] */
-#define WM8995_AIF1DRC1_QR_THR_MASK 0x0300 /* AIF1DRC1_QR_THR - [9:8] */
-#define WM8995_AIF1DRC1_QR_THR_SHIFT 8 /* AIF1DRC1_QR_THR - [9:8] */
-#define WM8995_AIF1DRC1_QR_THR_WIDTH 2 /* AIF1DRC1_QR_THR - [9:8] */
-#define WM8995_AIF1DRC1_QR_DCY_MASK 0x00C0 /* AIF1DRC1_QR_DCY - [7:6] */
-#define WM8995_AIF1DRC1_QR_DCY_SHIFT 6 /* AIF1DRC1_QR_DCY - [7:6] */
-#define WM8995_AIF1DRC1_QR_DCY_WIDTH 2 /* AIF1DRC1_QR_DCY - [7:6] */
-#define WM8995_AIF1DRC1_HI_COMP_MASK 0x0038 /* AIF1DRC1_HI_COMP - [5:3] */
-#define WM8995_AIF1DRC1_HI_COMP_SHIFT 3 /* AIF1DRC1_HI_COMP - [5:3] */
-#define WM8995_AIF1DRC1_HI_COMP_WIDTH 3 /* AIF1DRC1_HI_COMP - [5:3] */
-#define WM8995_AIF1DRC1_LO_COMP_MASK 0x0007 /* AIF1DRC1_LO_COMP - [2:0] */
-#define WM8995_AIF1DRC1_LO_COMP_SHIFT 0 /* AIF1DRC1_LO_COMP - [2:0] */
-#define WM8995_AIF1DRC1_LO_COMP_WIDTH 3 /* AIF1DRC1_LO_COMP - [2:0] */
-
-/*
- * R1091 (0x443) - AIF1 DRC1 (4)
- */
-#define WM8995_AIF1DRC1_KNEE_IP_MASK 0x07E0 /* AIF1DRC1_KNEE_IP - [10:5] */
-#define WM8995_AIF1DRC1_KNEE_IP_SHIFT 5 /* AIF1DRC1_KNEE_IP - [10:5] */
-#define WM8995_AIF1DRC1_KNEE_IP_WIDTH 6 /* AIF1DRC1_KNEE_IP - [10:5] */
-#define WM8995_AIF1DRC1_KNEE_OP_MASK 0x001F /* AIF1DRC1_KNEE_OP - [4:0] */
-#define WM8995_AIF1DRC1_KNEE_OP_SHIFT 0 /* AIF1DRC1_KNEE_OP - [4:0] */
-#define WM8995_AIF1DRC1_KNEE_OP_WIDTH 5 /* AIF1DRC1_KNEE_OP - [4:0] */
-
-/*
- * R1092 (0x444) - AIF1 DRC1 (5)
- */
-#define WM8995_AIF1DRC1_KNEE2_IP_MASK 0x03E0 /* AIF1DRC1_KNEE2_IP - [9:5] */
-#define WM8995_AIF1DRC1_KNEE2_IP_SHIFT 5 /* AIF1DRC1_KNEE2_IP - [9:5] */
-#define WM8995_AIF1DRC1_KNEE2_IP_WIDTH 5 /* AIF1DRC1_KNEE2_IP - [9:5] */
-#define WM8995_AIF1DRC1_KNEE2_OP_MASK 0x001F /* AIF1DRC1_KNEE2_OP - [4:0] */
-#define WM8995_AIF1DRC1_KNEE2_OP_SHIFT 0 /* AIF1DRC1_KNEE2_OP - [4:0] */
-#define WM8995_AIF1DRC1_KNEE2_OP_WIDTH 5 /* AIF1DRC1_KNEE2_OP - [4:0] */
-
-/*
- * R1104 (0x450) - AIF1 DRC2 (1)
- */
-#define WM8995_AIF1DRC2_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
-#define WM8995_AIF1DRC2_SIG_DET_RMS_SHIFT 11 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
-#define WM8995_AIF1DRC2_SIG_DET_RMS_WIDTH 5 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
-#define WM8995_AIF1DRC2_SIG_DET_PK_MASK 0x0600 /* AIF1DRC2_SIG_DET_PK - [10:9] */
-#define WM8995_AIF1DRC2_SIG_DET_PK_SHIFT 9 /* AIF1DRC2_SIG_DET_PK - [10:9] */
-#define WM8995_AIF1DRC2_SIG_DET_PK_WIDTH 2 /* AIF1DRC2_SIG_DET_PK - [10:9] */
-#define WM8995_AIF1DRC2_NG_ENA 0x0100 /* AIF1DRC2_NG_ENA */
-#define WM8995_AIF1DRC2_NG_ENA_MASK 0x0100 /* AIF1DRC2_NG_ENA */
-#define WM8995_AIF1DRC2_NG_ENA_SHIFT 8 /* AIF1DRC2_NG_ENA */
-#define WM8995_AIF1DRC2_NG_ENA_WIDTH 1 /* AIF1DRC2_NG_ENA */
-#define WM8995_AIF1DRC2_SIG_DET_MODE 0x0080 /* AIF1DRC2_SIG_DET_MODE */
-#define WM8995_AIF1DRC2_SIG_DET_MODE_MASK 0x0080 /* AIF1DRC2_SIG_DET_MODE */
-#define WM8995_AIF1DRC2_SIG_DET_MODE_SHIFT 7 /* AIF1DRC2_SIG_DET_MODE */
-#define WM8995_AIF1DRC2_SIG_DET_MODE_WIDTH 1 /* AIF1DRC2_SIG_DET_MODE */
-#define WM8995_AIF1DRC2_SIG_DET 0x0040 /* AIF1DRC2_SIG_DET */
-#define WM8995_AIF1DRC2_SIG_DET_MASK 0x0040 /* AIF1DRC2_SIG_DET */
-#define WM8995_AIF1DRC2_SIG_DET_SHIFT 6 /* AIF1DRC2_SIG_DET */
-#define WM8995_AIF1DRC2_SIG_DET_WIDTH 1 /* AIF1DRC2_SIG_DET */
-#define WM8995_AIF1DRC2_KNEE2_OP_ENA 0x0020 /* AIF1DRC2_KNEE2_OP_ENA */
-#define WM8995_AIF1DRC2_KNEE2_OP_ENA_MASK 0x0020 /* AIF1DRC2_KNEE2_OP_ENA */
-#define WM8995_AIF1DRC2_KNEE2_OP_ENA_SHIFT 5 /* AIF1DRC2_KNEE2_OP_ENA */
-#define WM8995_AIF1DRC2_KNEE2_OP_ENA_WIDTH 1 /* AIF1DRC2_KNEE2_OP_ENA */
-#define WM8995_AIF1DRC2_QR 0x0010 /* AIF1DRC2_QR */
-#define WM8995_AIF1DRC2_QR_MASK 0x0010 /* AIF1DRC2_QR */
-#define WM8995_AIF1DRC2_QR_SHIFT 4 /* AIF1DRC2_QR */
-#define WM8995_AIF1DRC2_QR_WIDTH 1 /* AIF1DRC2_QR */
-#define WM8995_AIF1DRC2_ANTICLIP 0x0008 /* AIF1DRC2_ANTICLIP */
-#define WM8995_AIF1DRC2_ANTICLIP_MASK 0x0008 /* AIF1DRC2_ANTICLIP */
-#define WM8995_AIF1DRC2_ANTICLIP_SHIFT 3 /* AIF1DRC2_ANTICLIP */
-#define WM8995_AIF1DRC2_ANTICLIP_WIDTH 1 /* AIF1DRC2_ANTICLIP */
-#define WM8995_AIF1DAC2_DRC_ENA 0x0004 /* AIF1DAC2_DRC_ENA */
-#define WM8995_AIF1DAC2_DRC_ENA_MASK 0x0004 /* AIF1DAC2_DRC_ENA */
-#define WM8995_AIF1DAC2_DRC_ENA_SHIFT 2 /* AIF1DAC2_DRC_ENA */
-#define WM8995_AIF1DAC2_DRC_ENA_WIDTH 1 /* AIF1DAC2_DRC_ENA */
-#define WM8995_AIF1ADC2L_DRC_ENA 0x0002 /* AIF1ADC2L_DRC_ENA */
-#define WM8995_AIF1ADC2L_DRC_ENA_MASK 0x0002 /* AIF1ADC2L_DRC_ENA */
-#define WM8995_AIF1ADC2L_DRC_ENA_SHIFT 1 /* AIF1ADC2L_DRC_ENA */
-#define WM8995_AIF1ADC2L_DRC_ENA_WIDTH 1 /* AIF1ADC2L_DRC_ENA */
-#define WM8995_AIF1ADC2R_DRC_ENA 0x0001 /* AIF1ADC2R_DRC_ENA */
-#define WM8995_AIF1ADC2R_DRC_ENA_MASK 0x0001 /* AIF1ADC2R_DRC_ENA */
-#define WM8995_AIF1ADC2R_DRC_ENA_SHIFT 0 /* AIF1ADC2R_DRC_ENA */
-#define WM8995_AIF1ADC2R_DRC_ENA_WIDTH 1 /* AIF1ADC2R_DRC_ENA */
-
-/*
- * R1105 (0x451) - AIF1 DRC2 (2)
- */
-#define WM8995_AIF1DRC2_ATK_MASK 0x1E00 /* AIF1DRC2_ATK - [12:9] */
-#define WM8995_AIF1DRC2_ATK_SHIFT 9 /* AIF1DRC2_ATK - [12:9] */
-#define WM8995_AIF1DRC2_ATK_WIDTH 4 /* AIF1DRC2_ATK - [12:9] */
-#define WM8995_AIF1DRC2_DCY_MASK 0x01E0 /* AIF1DRC2_DCY - [8:5] */
-#define WM8995_AIF1DRC2_DCY_SHIFT 5 /* AIF1DRC2_DCY - [8:5] */
-#define WM8995_AIF1DRC2_DCY_WIDTH 4 /* AIF1DRC2_DCY - [8:5] */
-#define WM8995_AIF1DRC2_MINGAIN_MASK 0x001C /* AIF1DRC2_MINGAIN - [4:2] */
-#define WM8995_AIF1DRC2_MINGAIN_SHIFT 2 /* AIF1DRC2_MINGAIN - [4:2] */
-#define WM8995_AIF1DRC2_MINGAIN_WIDTH 3 /* AIF1DRC2_MINGAIN - [4:2] */
-#define WM8995_AIF1DRC2_MAXGAIN_MASK 0x0003 /* AIF1DRC2_MAXGAIN - [1:0] */
-#define WM8995_AIF1DRC2_MAXGAIN_SHIFT 0 /* AIF1DRC2_MAXGAIN - [1:0] */
-#define WM8995_AIF1DRC2_MAXGAIN_WIDTH 2 /* AIF1DRC2_MAXGAIN - [1:0] */
-
-/*
- * R1106 (0x452) - AIF1 DRC2 (3)
- */
-#define WM8995_AIF1DRC2_NG_MINGAIN_MASK 0xF000 /* AIF1DRC2_NG_MINGAIN - [15:12] */
-#define WM8995_AIF1DRC2_NG_MINGAIN_SHIFT 12 /* AIF1DRC2_NG_MINGAIN - [15:12] */
-#define WM8995_AIF1DRC2_NG_MINGAIN_WIDTH 4 /* AIF1DRC2_NG_MINGAIN - [15:12] */
-#define WM8995_AIF1DRC2_NG_EXP_MASK 0x0C00 /* AIF1DRC2_NG_EXP - [11:10] */
-#define WM8995_AIF1DRC2_NG_EXP_SHIFT 10 /* AIF1DRC2_NG_EXP - [11:10] */
-#define WM8995_AIF1DRC2_NG_EXP_WIDTH 2 /* AIF1DRC2_NG_EXP - [11:10] */
-#define WM8995_AIF1DRC2_QR_THR_MASK 0x0300 /* AIF1DRC2_QR_THR - [9:8] */
-#define WM8995_AIF1DRC2_QR_THR_SHIFT 8 /* AIF1DRC2_QR_THR - [9:8] */
-#define WM8995_AIF1DRC2_QR_THR_WIDTH 2 /* AIF1DRC2_QR_THR - [9:8] */
-#define WM8995_AIF1DRC2_QR_DCY_MASK 0x00C0 /* AIF1DRC2_QR_DCY - [7:6] */
-#define WM8995_AIF1DRC2_QR_DCY_SHIFT 6 /* AIF1DRC2_QR_DCY - [7:6] */
-#define WM8995_AIF1DRC2_QR_DCY_WIDTH 2 /* AIF1DRC2_QR_DCY - [7:6] */
-#define WM8995_AIF1DRC2_HI_COMP_MASK 0x0038 /* AIF1DRC2_HI_COMP - [5:3] */
-#define WM8995_AIF1DRC2_HI_COMP_SHIFT 3 /* AIF1DRC2_HI_COMP - [5:3] */
-#define WM8995_AIF1DRC2_HI_COMP_WIDTH 3 /* AIF1DRC2_HI_COMP - [5:3] */
-#define WM8995_AIF1DRC2_LO_COMP_MASK 0x0007 /* AIF1DRC2_LO_COMP - [2:0] */
-#define WM8995_AIF1DRC2_LO_COMP_SHIFT 0 /* AIF1DRC2_LO_COMP - [2:0] */
-#define WM8995_AIF1DRC2_LO_COMP_WIDTH 3 /* AIF1DRC2_LO_COMP - [2:0] */
-
-/*
- * R1107 (0x453) - AIF1 DRC2 (4)
- */
-#define WM8995_AIF1DRC2_KNEE_IP_MASK 0x07E0 /* AIF1DRC2_KNEE_IP - [10:5] */
-#define WM8995_AIF1DRC2_KNEE_IP_SHIFT 5 /* AIF1DRC2_KNEE_IP - [10:5] */
-#define WM8995_AIF1DRC2_KNEE_IP_WIDTH 6 /* AIF1DRC2_KNEE_IP - [10:5] */
-#define WM8995_AIF1DRC2_KNEE_OP_MASK 0x001F /* AIF1DRC2_KNEE_OP - [4:0] */
-#define WM8995_AIF1DRC2_KNEE_OP_SHIFT 0 /* AIF1DRC2_KNEE_OP - [4:0] */
-#define WM8995_AIF1DRC2_KNEE_OP_WIDTH 5 /* AIF1DRC2_KNEE_OP - [4:0] */
-
-/*
- * R1108 (0x454) - AIF1 DRC2 (5)
- */
-#define WM8995_AIF1DRC2_KNEE2_IP_MASK 0x03E0 /* AIF1DRC2_KNEE2_IP - [9:5] */
-#define WM8995_AIF1DRC2_KNEE2_IP_SHIFT 5 /* AIF1DRC2_KNEE2_IP - [9:5] */
-#define WM8995_AIF1DRC2_KNEE2_IP_WIDTH 5 /* AIF1DRC2_KNEE2_IP - [9:5] */
-#define WM8995_AIF1DRC2_KNEE2_OP_MASK 0x001F /* AIF1DRC2_KNEE2_OP - [4:0] */
-#define WM8995_AIF1DRC2_KNEE2_OP_SHIFT 0 /* AIF1DRC2_KNEE2_OP - [4:0] */
-#define WM8995_AIF1DRC2_KNEE2_OP_WIDTH 5 /* AIF1DRC2_KNEE2_OP - [4:0] */
-
-/*
- * R1152 (0x480) - AIF1 DAC1 EQ Gains (1)
- */
-#define WM8995_AIF1DAC1_EQ_B1_GAIN_MASK 0xF800 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
-#define WM8995_AIF1DAC1_EQ_B1_GAIN_SHIFT 11 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
-#define WM8995_AIF1DAC1_EQ_B1_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
-#define WM8995_AIF1DAC1_EQ_B2_GAIN_MASK 0x07C0 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
-#define WM8995_AIF1DAC1_EQ_B2_GAIN_SHIFT 6 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
-#define WM8995_AIF1DAC1_EQ_B2_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
-#define WM8995_AIF1DAC1_EQ_B3_GAIN_MASK 0x003E /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
-#define WM8995_AIF1DAC1_EQ_B3_GAIN_SHIFT 1 /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
-#define WM8995_AIF1DAC1_EQ_B3_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
-#define WM8995_AIF1DAC1_EQ_ENA 0x0001 /* AIF1DAC1_EQ_ENA */
-#define WM8995_AIF1DAC1_EQ_ENA_MASK 0x0001 /* AIF1DAC1_EQ_ENA */
-#define WM8995_AIF1DAC1_EQ_ENA_SHIFT 0 /* AIF1DAC1_EQ_ENA */
-#define WM8995_AIF1DAC1_EQ_ENA_WIDTH 1 /* AIF1DAC1_EQ_ENA */
-
-/*
- * R1153 (0x481) - AIF1 DAC1 EQ Gains (2)
- */
-#define WM8995_AIF1DAC1_EQ_B4_GAIN_MASK 0xF800 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
-#define WM8995_AIF1DAC1_EQ_B4_GAIN_SHIFT 11 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
-#define WM8995_AIF1DAC1_EQ_B4_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
-#define WM8995_AIF1DAC1_EQ_B5_GAIN_MASK 0x07C0 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
-#define WM8995_AIF1DAC1_EQ_B5_GAIN_SHIFT 6 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
-#define WM8995_AIF1DAC1_EQ_B5_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
-
-/*
- * R1154 (0x482) - AIF1 DAC1 EQ Band 1 A
- */
-#define WM8995_AIF1DAC1_EQ_B1_A_MASK 0xFFFF /* AIF1DAC1_EQ_B1_A - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B1_A_SHIFT 0 /* AIF1DAC1_EQ_B1_A - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B1_A_WIDTH 16 /* AIF1DAC1_EQ_B1_A - [15:0] */
-
-/*
- * R1155 (0x483) - AIF1 DAC1 EQ Band 1 B
- */
-#define WM8995_AIF1DAC1_EQ_B1_B_MASK 0xFFFF /* AIF1DAC1_EQ_B1_B - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B1_B_SHIFT 0 /* AIF1DAC1_EQ_B1_B - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B1_B_WIDTH 16 /* AIF1DAC1_EQ_B1_B - [15:0] */
-
-/*
- * R1156 (0x484) - AIF1 DAC1 EQ Band 1 PG
- */
-#define WM8995_AIF1DAC1_EQ_B1_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B1_PG - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B1_PG_SHIFT 0 /* AIF1DAC1_EQ_B1_PG - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B1_PG_WIDTH 16 /* AIF1DAC1_EQ_B1_PG - [15:0] */
-
-/*
- * R1157 (0x485) - AIF1 DAC1 EQ Band 2 A
- */
-#define WM8995_AIF1DAC1_EQ_B2_A_MASK 0xFFFF /* AIF1DAC1_EQ_B2_A - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B2_A_SHIFT 0 /* AIF1DAC1_EQ_B2_A - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B2_A_WIDTH 16 /* AIF1DAC1_EQ_B2_A - [15:0] */
-
-/*
- * R1158 (0x486) - AIF1 DAC1 EQ Band 2 B
- */
-#define WM8995_AIF1DAC1_EQ_B2_B_MASK 0xFFFF /* AIF1DAC1_EQ_B2_B - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B2_B_SHIFT 0 /* AIF1DAC1_EQ_B2_B - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B2_B_WIDTH 16 /* AIF1DAC1_EQ_B2_B - [15:0] */
-
-/*
- * R1159 (0x487) - AIF1 DAC1 EQ Band 2 C
- */
-#define WM8995_AIF1DAC1_EQ_B2_C_MASK 0xFFFF /* AIF1DAC1_EQ_B2_C - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B2_C_SHIFT 0 /* AIF1DAC1_EQ_B2_C - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B2_C_WIDTH 16 /* AIF1DAC1_EQ_B2_C - [15:0] */
-
-/*
- * R1160 (0x488) - AIF1 DAC1 EQ Band 2 PG
- */
-#define WM8995_AIF1DAC1_EQ_B2_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B2_PG - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B2_PG_SHIFT 0 /* AIF1DAC1_EQ_B2_PG - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B2_PG_WIDTH 16 /* AIF1DAC1_EQ_B2_PG - [15:0] */
-
-/*
- * R1161 (0x489) - AIF1 DAC1 EQ Band 3 A
- */
-#define WM8995_AIF1DAC1_EQ_B3_A_MASK 0xFFFF /* AIF1DAC1_EQ_B3_A - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B3_A_SHIFT 0 /* AIF1DAC1_EQ_B3_A - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B3_A_WIDTH 16 /* AIF1DAC1_EQ_B3_A - [15:0] */
-
-/*
- * R1162 (0x48A) - AIF1 DAC1 EQ Band 3 B
- */
-#define WM8995_AIF1DAC1_EQ_B3_B_MASK 0xFFFF /* AIF1DAC1_EQ_B3_B - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B3_B_SHIFT 0 /* AIF1DAC1_EQ_B3_B - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B3_B_WIDTH 16 /* AIF1DAC1_EQ_B3_B - [15:0] */
-
-/*
- * R1163 (0x48B) - AIF1 DAC1 EQ Band 3 C
- */
-#define WM8995_AIF1DAC1_EQ_B3_C_MASK 0xFFFF /* AIF1DAC1_EQ_B3_C - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B3_C_SHIFT 0 /* AIF1DAC1_EQ_B3_C - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B3_C_WIDTH 16 /* AIF1DAC1_EQ_B3_C - [15:0] */
-
-/*
- * R1164 (0x48C) - AIF1 DAC1 EQ Band 3 PG
- */
-#define WM8995_AIF1DAC1_EQ_B3_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B3_PG - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B3_PG_SHIFT 0 /* AIF1DAC1_EQ_B3_PG - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B3_PG_WIDTH 16 /* AIF1DAC1_EQ_B3_PG - [15:0] */
-
-/*
- * R1165 (0x48D) - AIF1 DAC1 EQ Band 4 A
- */
-#define WM8995_AIF1DAC1_EQ_B4_A_MASK 0xFFFF /* AIF1DAC1_EQ_B4_A - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B4_A_SHIFT 0 /* AIF1DAC1_EQ_B4_A - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B4_A_WIDTH 16 /* AIF1DAC1_EQ_B4_A - [15:0] */
-
-/*
- * R1166 (0x48E) - AIF1 DAC1 EQ Band 4 B
- */
-#define WM8995_AIF1DAC1_EQ_B4_B_MASK 0xFFFF /* AIF1DAC1_EQ_B4_B - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B4_B_SHIFT 0 /* AIF1DAC1_EQ_B4_B - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B4_B_WIDTH 16 /* AIF1DAC1_EQ_B4_B - [15:0] */
-
-/*
- * R1167 (0x48F) - AIF1 DAC1 EQ Band 4 C
- */
-#define WM8995_AIF1DAC1_EQ_B4_C_MASK 0xFFFF /* AIF1DAC1_EQ_B4_C - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B4_C_SHIFT 0 /* AIF1DAC1_EQ_B4_C - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B4_C_WIDTH 16 /* AIF1DAC1_EQ_B4_C - [15:0] */
-
-/*
- * R1168 (0x490) - AIF1 DAC1 EQ Band 4 PG
- */
-#define WM8995_AIF1DAC1_EQ_B4_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B4_PG - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B4_PG_SHIFT 0 /* AIF1DAC1_EQ_B4_PG - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B4_PG_WIDTH 16 /* AIF1DAC1_EQ_B4_PG - [15:0] */
-
-/*
- * R1169 (0x491) - AIF1 DAC1 EQ Band 5 A
- */
-#define WM8995_AIF1DAC1_EQ_B5_A_MASK 0xFFFF /* AIF1DAC1_EQ_B5_A - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B5_A_SHIFT 0 /* AIF1DAC1_EQ_B5_A - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B5_A_WIDTH 16 /* AIF1DAC1_EQ_B5_A - [15:0] */
-
-/*
- * R1170 (0x492) - AIF1 DAC1 EQ Band 5 B
- */
-#define WM8995_AIF1DAC1_EQ_B5_B_MASK 0xFFFF /* AIF1DAC1_EQ_B5_B - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B5_B_SHIFT 0 /* AIF1DAC1_EQ_B5_B - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B5_B_WIDTH 16 /* AIF1DAC1_EQ_B5_B - [15:0] */
-
-/*
- * R1171 (0x493) - AIF1 DAC1 EQ Band 5 PG
- */
-#define WM8995_AIF1DAC1_EQ_B5_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B5_PG - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B5_PG_SHIFT 0 /* AIF1DAC1_EQ_B5_PG - [15:0] */
-#define WM8995_AIF1DAC1_EQ_B5_PG_WIDTH 16 /* AIF1DAC1_EQ_B5_PG - [15:0] */
-
-/*
- * R1184 (0x4A0) - AIF1 DAC2 EQ Gains (1)
- */
-#define WM8995_AIF1DAC2_EQ_B1_GAIN_MASK 0xF800 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
-#define WM8995_AIF1DAC2_EQ_B1_GAIN_SHIFT 11 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
-#define WM8995_AIF1DAC2_EQ_B1_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
-#define WM8995_AIF1DAC2_EQ_B2_GAIN_MASK 0x07C0 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
-#define WM8995_AIF1DAC2_EQ_B2_GAIN_SHIFT 6 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
-#define WM8995_AIF1DAC2_EQ_B2_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
-#define WM8995_AIF1DAC2_EQ_B3_GAIN_MASK 0x003E /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
-#define WM8995_AIF1DAC2_EQ_B3_GAIN_SHIFT 1 /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
-#define WM8995_AIF1DAC2_EQ_B3_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
-#define WM8995_AIF1DAC2_EQ_ENA 0x0001 /* AIF1DAC2_EQ_ENA */
-#define WM8995_AIF1DAC2_EQ_ENA_MASK 0x0001 /* AIF1DAC2_EQ_ENA */
-#define WM8995_AIF1DAC2_EQ_ENA_SHIFT 0 /* AIF1DAC2_EQ_ENA */
-#define WM8995_AIF1DAC2_EQ_ENA_WIDTH 1 /* AIF1DAC2_EQ_ENA */
-
-/*
- * R1185 (0x4A1) - AIF1 DAC2 EQ Gains (2)
- */
-#define WM8995_AIF1DAC2_EQ_B4_GAIN_MASK 0xF800 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
-#define WM8995_AIF1DAC2_EQ_B4_GAIN_SHIFT 11 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
-#define WM8995_AIF1DAC2_EQ_B4_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
-#define WM8995_AIF1DAC2_EQ_B5_GAIN_MASK 0x07C0 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
-#define WM8995_AIF1DAC2_EQ_B5_GAIN_SHIFT 6 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
-#define WM8995_AIF1DAC2_EQ_B5_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
-
-/*
- * R1186 (0x4A2) - AIF1 DAC2 EQ Band 1 A
- */
-#define WM8995_AIF1DAC2_EQ_B1_A_MASK 0xFFFF /* AIF1DAC2_EQ_B1_A - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B1_A_SHIFT 0 /* AIF1DAC2_EQ_B1_A - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B1_A_WIDTH 16 /* AIF1DAC2_EQ_B1_A - [15:0] */
-
-/*
- * R1187 (0x4A3) - AIF1 DAC2 EQ Band 1 B
- */
-#define WM8995_AIF1DAC2_EQ_B1_B_MASK 0xFFFF /* AIF1DAC2_EQ_B1_B - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B1_B_SHIFT 0 /* AIF1DAC2_EQ_B1_B - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B1_B_WIDTH 16 /* AIF1DAC2_EQ_B1_B - [15:0] */
-
-/*
- * R1188 (0x4A4) - AIF1 DAC2 EQ Band 1 PG
- */
-#define WM8995_AIF1DAC2_EQ_B1_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B1_PG - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B1_PG_SHIFT 0 /* AIF1DAC2_EQ_B1_PG - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B1_PG_WIDTH 16 /* AIF1DAC2_EQ_B1_PG - [15:0] */
-
-/*
- * R1189 (0x4A5) - AIF1 DAC2 EQ Band 2 A
- */
-#define WM8995_AIF1DAC2_EQ_B2_A_MASK 0xFFFF /* AIF1DAC2_EQ_B2_A - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B2_A_SHIFT 0 /* AIF1DAC2_EQ_B2_A - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B2_A_WIDTH 16 /* AIF1DAC2_EQ_B2_A - [15:0] */
-
-/*
- * R1190 (0x4A6) - AIF1 DAC2 EQ Band 2 B
- */
-#define WM8995_AIF1DAC2_EQ_B2_B_MASK 0xFFFF /* AIF1DAC2_EQ_B2_B - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B2_B_SHIFT 0 /* AIF1DAC2_EQ_B2_B - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B2_B_WIDTH 16 /* AIF1DAC2_EQ_B2_B - [15:0] */
-
-/*
- * R1191 (0x4A7) - AIF1 DAC2 EQ Band 2 C
- */
-#define WM8995_AIF1DAC2_EQ_B2_C_MASK 0xFFFF /* AIF1DAC2_EQ_B2_C - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B2_C_SHIFT 0 /* AIF1DAC2_EQ_B2_C - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B2_C_WIDTH 16 /* AIF1DAC2_EQ_B2_C - [15:0] */
-
-/*
- * R1192 (0x4A8) - AIF1 DAC2 EQ Band 2 PG
- */
-#define WM8995_AIF1DAC2_EQ_B2_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B2_PG - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B2_PG_SHIFT 0 /* AIF1DAC2_EQ_B2_PG - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B2_PG_WIDTH 16 /* AIF1DAC2_EQ_B2_PG - [15:0] */
-
-/*
- * R1193 (0x4A9) - AIF1 DAC2 EQ Band 3 A
- */
-#define WM8995_AIF1DAC2_EQ_B3_A_MASK 0xFFFF /* AIF1DAC2_EQ_B3_A - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B3_A_SHIFT 0 /* AIF1DAC2_EQ_B3_A - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B3_A_WIDTH 16 /* AIF1DAC2_EQ_B3_A - [15:0] */
-
-/*
- * R1194 (0x4AA) - AIF1 DAC2 EQ Band 3 B
- */
-#define WM8995_AIF1DAC2_EQ_B3_B_MASK 0xFFFF /* AIF1DAC2_EQ_B3_B - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B3_B_SHIFT 0 /* AIF1DAC2_EQ_B3_B - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B3_B_WIDTH 16 /* AIF1DAC2_EQ_B3_B - [15:0] */
-
-/*
- * R1195 (0x4AB) - AIF1 DAC2 EQ Band 3 C
- */
-#define WM8995_AIF1DAC2_EQ_B3_C_MASK 0xFFFF /* AIF1DAC2_EQ_B3_C - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B3_C_SHIFT 0 /* AIF1DAC2_EQ_B3_C - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B3_C_WIDTH 16 /* AIF1DAC2_EQ_B3_C - [15:0] */
-
-/*
- * R1196 (0x4AC) - AIF1 DAC2 EQ Band 3 PG
- */
-#define WM8995_AIF1DAC2_EQ_B3_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B3_PG - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B3_PG_SHIFT 0 /* AIF1DAC2_EQ_B3_PG - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B3_PG_WIDTH 16 /* AIF1DAC2_EQ_B3_PG - [15:0] */
-
-/*
- * R1197 (0x4AD) - AIF1 DAC2 EQ Band 4 A
- */
-#define WM8995_AIF1DAC2_EQ_B4_A_MASK 0xFFFF /* AIF1DAC2_EQ_B4_A - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B4_A_SHIFT 0 /* AIF1DAC2_EQ_B4_A - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B4_A_WIDTH 16 /* AIF1DAC2_EQ_B4_A - [15:0] */
-
-/*
- * R1198 (0x4AE) - AIF1 DAC2 EQ Band 4 B
- */
-#define WM8995_AIF1DAC2_EQ_B4_B_MASK 0xFFFF /* AIF1DAC2_EQ_B4_B - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B4_B_SHIFT 0 /* AIF1DAC2_EQ_B4_B - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B4_B_WIDTH 16 /* AIF1DAC2_EQ_B4_B - [15:0] */
-
-/*
- * R1199 (0x4AF) - AIF1 DAC2 EQ Band 4 C
- */
-#define WM8995_AIF1DAC2_EQ_B4_C_MASK 0xFFFF /* AIF1DAC2_EQ_B4_C - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B4_C_SHIFT 0 /* AIF1DAC2_EQ_B4_C - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B4_C_WIDTH 16 /* AIF1DAC2_EQ_B4_C - [15:0] */
-
-/*
- * R1200 (0x4B0) - AIF1 DAC2 EQ Band 4 PG
- */
-#define WM8995_AIF1DAC2_EQ_B4_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B4_PG - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B4_PG_SHIFT 0 /* AIF1DAC2_EQ_B4_PG - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B4_PG_WIDTH 16 /* AIF1DAC2_EQ_B4_PG - [15:0] */
-
-/*
- * R1201 (0x4B1) - AIF1 DAC2 EQ Band 5 A
- */
-#define WM8995_AIF1DAC2_EQ_B5_A_MASK 0xFFFF /* AIF1DAC2_EQ_B5_A - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B5_A_SHIFT 0 /* AIF1DAC2_EQ_B5_A - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B5_A_WIDTH 16 /* AIF1DAC2_EQ_B5_A - [15:0] */
-
-/*
- * R1202 (0x4B2) - AIF1 DAC2 EQ Band 5 B
- */
-#define WM8995_AIF1DAC2_EQ_B5_B_MASK 0xFFFF /* AIF1DAC2_EQ_B5_B - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B5_B_SHIFT 0 /* AIF1DAC2_EQ_B5_B - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B5_B_WIDTH 16 /* AIF1DAC2_EQ_B5_B - [15:0] */
-
-/*
- * R1203 (0x4B3) - AIF1 DAC2 EQ Band 5 PG
- */
-#define WM8995_AIF1DAC2_EQ_B5_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B5_PG - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B5_PG_SHIFT 0 /* AIF1DAC2_EQ_B5_PG - [15:0] */
-#define WM8995_AIF1DAC2_EQ_B5_PG_WIDTH 16 /* AIF1DAC2_EQ_B5_PG - [15:0] */
-
-/*
- * R1280 (0x500) - AIF2 ADC Left Volume
- */
-#define WM8995_AIF2ADC_VU 0x0100 /* AIF2ADC_VU */
-#define WM8995_AIF2ADC_VU_MASK 0x0100 /* AIF2ADC_VU */
-#define WM8995_AIF2ADC_VU_SHIFT 8 /* AIF2ADC_VU */
-#define WM8995_AIF2ADC_VU_WIDTH 1 /* AIF2ADC_VU */
-#define WM8995_AIF2ADCL_VOL_MASK 0x00FF /* AIF2ADCL_VOL - [7:0] */
-#define WM8995_AIF2ADCL_VOL_SHIFT 0 /* AIF2ADCL_VOL - [7:0] */
-#define WM8995_AIF2ADCL_VOL_WIDTH 8 /* AIF2ADCL_VOL - [7:0] */
-
-/*
- * R1281 (0x501) - AIF2 ADC Right Volume
- */
-#define WM8995_AIF2ADC_VU 0x0100 /* AIF2ADC_VU */
-#define WM8995_AIF2ADC_VU_MASK 0x0100 /* AIF2ADC_VU */
-#define WM8995_AIF2ADC_VU_SHIFT 8 /* AIF2ADC_VU */
-#define WM8995_AIF2ADC_VU_WIDTH 1 /* AIF2ADC_VU */
-#define WM8995_AIF2ADCR_VOL_MASK 0x00FF /* AIF2ADCR_VOL - [7:0] */
-#define WM8995_AIF2ADCR_VOL_SHIFT 0 /* AIF2ADCR_VOL - [7:0] */
-#define WM8995_AIF2ADCR_VOL_WIDTH 8 /* AIF2ADCR_VOL - [7:0] */
-
-/*
- * R1282 (0x502) - AIF2 DAC Left Volume
- */
-#define WM8995_AIF2DAC_VU 0x0100 /* AIF2DAC_VU */
-#define WM8995_AIF2DAC_VU_MASK 0x0100 /* AIF2DAC_VU */
-#define WM8995_AIF2DAC_VU_SHIFT 8 /* AIF2DAC_VU */
-#define WM8995_AIF2DAC_VU_WIDTH 1 /* AIF2DAC_VU */
-#define WM8995_AIF2DACL_VOL_MASK 0x00FF /* AIF2DACL_VOL - [7:0] */
-#define WM8995_AIF2DACL_VOL_SHIFT 0 /* AIF2DACL_VOL - [7:0] */
-#define WM8995_AIF2DACL_VOL_WIDTH 8 /* AIF2DACL_VOL - [7:0] */
-
-/*
- * R1283 (0x503) - AIF2 DAC Right Volume
- */
-#define WM8995_AIF2DAC_VU 0x0100 /* AIF2DAC_VU */
-#define WM8995_AIF2DAC_VU_MASK 0x0100 /* AIF2DAC_VU */
-#define WM8995_AIF2DAC_VU_SHIFT 8 /* AIF2DAC_VU */
-#define WM8995_AIF2DAC_VU_WIDTH 1 /* AIF2DAC_VU */
-#define WM8995_AIF2DACR_VOL_MASK 0x00FF /* AIF2DACR_VOL - [7:0] */
-#define WM8995_AIF2DACR_VOL_SHIFT 0 /* AIF2DACR_VOL - [7:0] */
-#define WM8995_AIF2DACR_VOL_WIDTH 8 /* AIF2DACR_VOL - [7:0] */
-
-/*
- * R1296 (0x510) - AIF2 ADC Filters
- */
-#define WM8995_AIF2ADC_4FS 0x8000 /* AIF2ADC_4FS */
-#define WM8995_AIF2ADC_4FS_MASK 0x8000 /* AIF2ADC_4FS */
-#define WM8995_AIF2ADC_4FS_SHIFT 15 /* AIF2ADC_4FS */
-#define WM8995_AIF2ADC_4FS_WIDTH 1 /* AIF2ADC_4FS */
-#define WM8995_AIF2ADCL_HPF 0x1000 /* AIF2ADCL_HPF */
-#define WM8995_AIF2ADCL_HPF_MASK 0x1000 /* AIF2ADCL_HPF */
-#define WM8995_AIF2ADCL_HPF_SHIFT 12 /* AIF2ADCL_HPF */
-#define WM8995_AIF2ADCL_HPF_WIDTH 1 /* AIF2ADCL_HPF */
-#define WM8995_AIF2ADCR_HPF 0x0800 /* AIF2ADCR_HPF */
-#define WM8995_AIF2ADCR_HPF_MASK 0x0800 /* AIF2ADCR_HPF */
-#define WM8995_AIF2ADCR_HPF_SHIFT 11 /* AIF2ADCR_HPF */
-#define WM8995_AIF2ADCR_HPF_WIDTH 1 /* AIF2ADCR_HPF */
-#define WM8995_AIF2ADC_HPF_MODE 0x0008 /* AIF2ADC_HPF_MODE */
-#define WM8995_AIF2ADC_HPF_MODE_MASK 0x0008 /* AIF2ADC_HPF_MODE */
-#define WM8995_AIF2ADC_HPF_MODE_SHIFT 3 /* AIF2ADC_HPF_MODE */
-#define WM8995_AIF2ADC_HPF_MODE_WIDTH 1 /* AIF2ADC_HPF_MODE */
-#define WM8995_AIF2ADC_HPF_CUT_MASK 0x0007 /* AIF2ADC_HPF_CUT - [2:0] */
-#define WM8995_AIF2ADC_HPF_CUT_SHIFT 0 /* AIF2ADC_HPF_CUT - [2:0] */
-#define WM8995_AIF2ADC_HPF_CUT_WIDTH 3 /* AIF2ADC_HPF_CUT - [2:0] */
-
-/*
- * R1312 (0x520) - AIF2 DAC Filters (1)
- */
-#define WM8995_AIF2DAC_MUTE 0x0200 /* AIF2DAC_MUTE */
-#define WM8995_AIF2DAC_MUTE_MASK 0x0200 /* AIF2DAC_MUTE */
-#define WM8995_AIF2DAC_MUTE_SHIFT 9 /* AIF2DAC_MUTE */
-#define WM8995_AIF2DAC_MUTE_WIDTH 1 /* AIF2DAC_MUTE */
-#define WM8995_AIF2DAC_MONO 0x0080 /* AIF2DAC_MONO */
-#define WM8995_AIF2DAC_MONO_MASK 0x0080 /* AIF2DAC_MONO */
-#define WM8995_AIF2DAC_MONO_SHIFT 7 /* AIF2DAC_MONO */
-#define WM8995_AIF2DAC_MONO_WIDTH 1 /* AIF2DAC_MONO */
-#define WM8995_AIF2DAC_MUTERATE 0x0020 /* AIF2DAC_MUTERATE */
-#define WM8995_AIF2DAC_MUTERATE_MASK 0x0020 /* AIF2DAC_MUTERATE */
-#define WM8995_AIF2DAC_MUTERATE_SHIFT 5 /* AIF2DAC_MUTERATE */
-#define WM8995_AIF2DAC_MUTERATE_WIDTH 1 /* AIF2DAC_MUTERATE */
-#define WM8995_AIF2DAC_UNMUTE_RAMP 0x0010 /* AIF2DAC_UNMUTE_RAMP */
-#define WM8995_AIF2DAC_UNMUTE_RAMP_MASK 0x0010 /* AIF2DAC_UNMUTE_RAMP */
-#define WM8995_AIF2DAC_UNMUTE_RAMP_SHIFT 4 /* AIF2DAC_UNMUTE_RAMP */
-#define WM8995_AIF2DAC_UNMUTE_RAMP_WIDTH 1 /* AIF2DAC_UNMUTE_RAMP */
-#define WM8995_AIF2DAC_DEEMP_MASK 0x0006 /* AIF2DAC_DEEMP - [2:1] */
-#define WM8995_AIF2DAC_DEEMP_SHIFT 1 /* AIF2DAC_DEEMP - [2:1] */
-#define WM8995_AIF2DAC_DEEMP_WIDTH 2 /* AIF2DAC_DEEMP - [2:1] */
-
-/*
- * R1313 (0x521) - AIF2 DAC Filters (2)
- */
-#define WM8995_AIF2DAC_3D_GAIN_MASK 0x3E00 /* AIF2DAC_3D_GAIN - [13:9] */
-#define WM8995_AIF2DAC_3D_GAIN_SHIFT 9 /* AIF2DAC_3D_GAIN - [13:9] */
-#define WM8995_AIF2DAC_3D_GAIN_WIDTH 5 /* AIF2DAC_3D_GAIN - [13:9] */
-#define WM8995_AIF2DAC_3D_ENA 0x0100 /* AIF2DAC_3D_ENA */
-#define WM8995_AIF2DAC_3D_ENA_MASK 0x0100 /* AIF2DAC_3D_ENA */
-#define WM8995_AIF2DAC_3D_ENA_SHIFT 8 /* AIF2DAC_3D_ENA */
-#define WM8995_AIF2DAC_3D_ENA_WIDTH 1 /* AIF2DAC_3D_ENA */
-
-/*
- * R1344 (0x540) - AIF2 DRC (1)
- */
-#define WM8995_AIF2DRC_SIG_DET_RMS_MASK 0xF800 /* AIF2DRC_SIG_DET_RMS - [15:11] */
-#define WM8995_AIF2DRC_SIG_DET_RMS_SHIFT 11 /* AIF2DRC_SIG_DET_RMS - [15:11] */
-#define WM8995_AIF2DRC_SIG_DET_RMS_WIDTH 5 /* AIF2DRC_SIG_DET_RMS - [15:11] */
-#define WM8995_AIF2DRC_SIG_DET_PK_MASK 0x0600 /* AIF2DRC_SIG_DET_PK - [10:9] */
-#define WM8995_AIF2DRC_SIG_DET_PK_SHIFT 9 /* AIF2DRC_SIG_DET_PK - [10:9] */
-#define WM8995_AIF2DRC_SIG_DET_PK_WIDTH 2 /* AIF2DRC_SIG_DET_PK - [10:9] */
-#define WM8995_AIF2DRC_NG_ENA 0x0100 /* AIF2DRC_NG_ENA */
-#define WM8995_AIF2DRC_NG_ENA_MASK 0x0100 /* AIF2DRC_NG_ENA */
-#define WM8995_AIF2DRC_NG_ENA_SHIFT 8 /* AIF2DRC_NG_ENA */
-#define WM8995_AIF2DRC_NG_ENA_WIDTH 1 /* AIF2DRC_NG_ENA */
-#define WM8995_AIF2DRC_SIG_DET_MODE 0x0080 /* AIF2DRC_SIG_DET_MODE */
-#define WM8995_AIF2DRC_SIG_DET_MODE_MASK 0x0080 /* AIF2DRC_SIG_DET_MODE */
-#define WM8995_AIF2DRC_SIG_DET_MODE_SHIFT 7 /* AIF2DRC_SIG_DET_MODE */
-#define WM8995_AIF2DRC_SIG_DET_MODE_WIDTH 1 /* AIF2DRC_SIG_DET_MODE */
-#define WM8995_AIF2DRC_SIG_DET 0x0040 /* AIF2DRC_SIG_DET */
-#define WM8995_AIF2DRC_SIG_DET_MASK 0x0040 /* AIF2DRC_SIG_DET */
-#define WM8995_AIF2DRC_SIG_DET_SHIFT 6 /* AIF2DRC_SIG_DET */
-#define WM8995_AIF2DRC_SIG_DET_WIDTH 1 /* AIF2DRC_SIG_DET */
-#define WM8995_AIF2DRC_KNEE2_OP_ENA 0x0020 /* AIF2DRC_KNEE2_OP_ENA */
-#define WM8995_AIF2DRC_KNEE2_OP_ENA_MASK 0x0020 /* AIF2DRC_KNEE2_OP_ENA */
-#define WM8995_AIF2DRC_KNEE2_OP_ENA_SHIFT 5 /* AIF2DRC_KNEE2_OP_ENA */
-#define WM8995_AIF2DRC_KNEE2_OP_ENA_WIDTH 1 /* AIF2DRC_KNEE2_OP_ENA */
-#define WM8995_AIF2DRC_QR 0x0010 /* AIF2DRC_QR */
-#define WM8995_AIF2DRC_QR_MASK 0x0010 /* AIF2DRC_QR */
-#define WM8995_AIF2DRC_QR_SHIFT 4 /* AIF2DRC_QR */
-#define WM8995_AIF2DRC_QR_WIDTH 1 /* AIF2DRC_QR */
-#define WM8995_AIF2DRC_ANTICLIP 0x0008 /* AIF2DRC_ANTICLIP */
-#define WM8995_AIF2DRC_ANTICLIP_MASK 0x0008 /* AIF2DRC_ANTICLIP */
-#define WM8995_AIF2DRC_ANTICLIP_SHIFT 3 /* AIF2DRC_ANTICLIP */
-#define WM8995_AIF2DRC_ANTICLIP_WIDTH 1 /* AIF2DRC_ANTICLIP */
-#define WM8995_AIF2DAC_DRC_ENA 0x0004 /* AIF2DAC_DRC_ENA */
-#define WM8995_AIF2DAC_DRC_ENA_MASK 0x0004 /* AIF2DAC_DRC_ENA */
-#define WM8995_AIF2DAC_DRC_ENA_SHIFT 2 /* AIF2DAC_DRC_ENA */
-#define WM8995_AIF2DAC_DRC_ENA_WIDTH 1 /* AIF2DAC_DRC_ENA */
-#define WM8995_AIF2ADCL_DRC_ENA 0x0002 /* AIF2ADCL_DRC_ENA */
-#define WM8995_AIF2ADCL_DRC_ENA_MASK 0x0002 /* AIF2ADCL_DRC_ENA */
-#define WM8995_AIF2ADCL_DRC_ENA_SHIFT 1 /* AIF2ADCL_DRC_ENA */
-#define WM8995_AIF2ADCL_DRC_ENA_WIDTH 1 /* AIF2ADCL_DRC_ENA */
-#define WM8995_AIF2ADCR_DRC_ENA 0x0001 /* AIF2ADCR_DRC_ENA */
-#define WM8995_AIF2ADCR_DRC_ENA_MASK 0x0001 /* AIF2ADCR_DRC_ENA */
-#define WM8995_AIF2ADCR_DRC_ENA_SHIFT 0 /* AIF2ADCR_DRC_ENA */
-#define WM8995_AIF2ADCR_DRC_ENA_WIDTH 1 /* AIF2ADCR_DRC_ENA */
-
-/*
- * R1345 (0x541) - AIF2 DRC (2)
- */
-#define WM8995_AIF2DRC_ATK_MASK 0x1E00 /* AIF2DRC_ATK - [12:9] */
-#define WM8995_AIF2DRC_ATK_SHIFT 9 /* AIF2DRC_ATK - [12:9] */
-#define WM8995_AIF2DRC_ATK_WIDTH 4 /* AIF2DRC_ATK - [12:9] */
-#define WM8995_AIF2DRC_DCY_MASK 0x01E0 /* AIF2DRC_DCY - [8:5] */
-#define WM8995_AIF2DRC_DCY_SHIFT 5 /* AIF2DRC_DCY - [8:5] */
-#define WM8995_AIF2DRC_DCY_WIDTH 4 /* AIF2DRC_DCY - [8:5] */
-#define WM8995_AIF2DRC_MINGAIN_MASK 0x001C /* AIF2DRC_MINGAIN - [4:2] */
-#define WM8995_AIF2DRC_MINGAIN_SHIFT 2 /* AIF2DRC_MINGAIN - [4:2] */
-#define WM8995_AIF2DRC_MINGAIN_WIDTH 3 /* AIF2DRC_MINGAIN - [4:2] */
-#define WM8995_AIF2DRC_MAXGAIN_MASK 0x0003 /* AIF2DRC_MAXGAIN - [1:0] */
-#define WM8995_AIF2DRC_MAXGAIN_SHIFT 0 /* AIF2DRC_MAXGAIN - [1:0] */
-#define WM8995_AIF2DRC_MAXGAIN_WIDTH 2 /* AIF2DRC_MAXGAIN - [1:0] */
-
-/*
- * R1346 (0x542) - AIF2 DRC (3)
- */
-#define WM8995_AIF2DRC_NG_MINGAIN_MASK 0xF000 /* AIF2DRC_NG_MINGAIN - [15:12] */
-#define WM8995_AIF2DRC_NG_MINGAIN_SHIFT 12 /* AIF2DRC_NG_MINGAIN - [15:12] */
-#define WM8995_AIF2DRC_NG_MINGAIN_WIDTH 4 /* AIF2DRC_NG_MINGAIN - [15:12] */
-#define WM8995_AIF2DRC_NG_EXP_MASK 0x0C00 /* AIF2DRC_NG_EXP - [11:10] */
-#define WM8995_AIF2DRC_NG_EXP_SHIFT 10 /* AIF2DRC_NG_EXP - [11:10] */
-#define WM8995_AIF2DRC_NG_EXP_WIDTH 2 /* AIF2DRC_NG_EXP - [11:10] */
-#define WM8995_AIF2DRC_QR_THR_MASK 0x0300 /* AIF2DRC_QR_THR - [9:8] */
-#define WM8995_AIF2DRC_QR_THR_SHIFT 8 /* AIF2DRC_QR_THR - [9:8] */
-#define WM8995_AIF2DRC_QR_THR_WIDTH 2 /* AIF2DRC_QR_THR - [9:8] */
-#define WM8995_AIF2DRC_QR_DCY_MASK 0x00C0 /* AIF2DRC_QR_DCY - [7:6] */
-#define WM8995_AIF2DRC_QR_DCY_SHIFT 6 /* AIF2DRC_QR_DCY - [7:6] */
-#define WM8995_AIF2DRC_QR_DCY_WIDTH 2 /* AIF2DRC_QR_DCY - [7:6] */
-#define WM8995_AIF2DRC_HI_COMP_MASK 0x0038 /* AIF2DRC_HI_COMP - [5:3] */
-#define WM8995_AIF2DRC_HI_COMP_SHIFT 3 /* AIF2DRC_HI_COMP - [5:3] */
-#define WM8995_AIF2DRC_HI_COMP_WIDTH 3 /* AIF2DRC_HI_COMP - [5:3] */
-#define WM8995_AIF2DRC_LO_COMP_MASK 0x0007 /* AIF2DRC_LO_COMP - [2:0] */
-#define WM8995_AIF2DRC_LO_COMP_SHIFT 0 /* AIF2DRC_LO_COMP - [2:0] */
-#define WM8995_AIF2DRC_LO_COMP_WIDTH 3 /* AIF2DRC_LO_COMP - [2:0] */
-
-/*
- * R1347 (0x543) - AIF2 DRC (4)
- */
-#define WM8995_AIF2DRC_KNEE_IP_MASK 0x07E0 /* AIF2DRC_KNEE_IP - [10:5] */
-#define WM8995_AIF2DRC_KNEE_IP_SHIFT 5 /* AIF2DRC_KNEE_IP - [10:5] */
-#define WM8995_AIF2DRC_KNEE_IP_WIDTH 6 /* AIF2DRC_KNEE_IP - [10:5] */
-#define WM8995_AIF2DRC_KNEE_OP_MASK 0x001F /* AIF2DRC_KNEE_OP - [4:0] */
-#define WM8995_AIF2DRC_KNEE_OP_SHIFT 0 /* AIF2DRC_KNEE_OP - [4:0] */
-#define WM8995_AIF2DRC_KNEE_OP_WIDTH 5 /* AIF2DRC_KNEE_OP - [4:0] */
-
-/*
- * R1348 (0x544) - AIF2 DRC (5)
- */
-#define WM8995_AIF2DRC_KNEE2_IP_MASK 0x03E0 /* AIF2DRC_KNEE2_IP - [9:5] */
-#define WM8995_AIF2DRC_KNEE2_IP_SHIFT 5 /* AIF2DRC_KNEE2_IP - [9:5] */
-#define WM8995_AIF2DRC_KNEE2_IP_WIDTH 5 /* AIF2DRC_KNEE2_IP - [9:5] */
-#define WM8995_AIF2DRC_KNEE2_OP_MASK 0x001F /* AIF2DRC_KNEE2_OP - [4:0] */
-#define WM8995_AIF2DRC_KNEE2_OP_SHIFT 0 /* AIF2DRC_KNEE2_OP - [4:0] */
-#define WM8995_AIF2DRC_KNEE2_OP_WIDTH 5 /* AIF2DRC_KNEE2_OP - [4:0] */
-
-/*
- * R1408 (0x580) - AIF2 EQ Gains (1)
- */
-#define WM8995_AIF2DAC_EQ_B1_GAIN_MASK 0xF800 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
-#define WM8995_AIF2DAC_EQ_B1_GAIN_SHIFT 11 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
-#define WM8995_AIF2DAC_EQ_B1_GAIN_WIDTH 5 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
-#define WM8995_AIF2DAC_EQ_B2_GAIN_MASK 0x07C0 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
-#define WM8995_AIF2DAC_EQ_B2_GAIN_SHIFT 6 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
-#define WM8995_AIF2DAC_EQ_B2_GAIN_WIDTH 5 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
-#define WM8995_AIF2DAC_EQ_B3_GAIN_MASK 0x003E /* AIF2DAC_EQ_B3_GAIN - [5:1] */
-#define WM8995_AIF2DAC_EQ_B3_GAIN_SHIFT 1 /* AIF2DAC_EQ_B3_GAIN - [5:1] */
-#define WM8995_AIF2DAC_EQ_B3_GAIN_WIDTH 5 /* AIF2DAC_EQ_B3_GAIN - [5:1] */
-#define WM8995_AIF2DAC_EQ_ENA 0x0001 /* AIF2DAC_EQ_ENA */
-#define WM8995_AIF2DAC_EQ_ENA_MASK 0x0001 /* AIF2DAC_EQ_ENA */
-#define WM8995_AIF2DAC_EQ_ENA_SHIFT 0 /* AIF2DAC_EQ_ENA */
-#define WM8995_AIF2DAC_EQ_ENA_WIDTH 1 /* AIF2DAC_EQ_ENA */
-
-/*
- * R1409 (0x581) - AIF2 EQ Gains (2)
- */
-#define WM8995_AIF2DAC_EQ_B4_GAIN_MASK 0xF800 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
-#define WM8995_AIF2DAC_EQ_B4_GAIN_SHIFT 11 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
-#define WM8995_AIF2DAC_EQ_B4_GAIN_WIDTH 5 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
-#define WM8995_AIF2DAC_EQ_B5_GAIN_MASK 0x07C0 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
-#define WM8995_AIF2DAC_EQ_B5_GAIN_SHIFT 6 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
-#define WM8995_AIF2DAC_EQ_B5_GAIN_WIDTH 5 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
-
-/*
- * R1410 (0x582) - AIF2 EQ Band 1 A
- */
-#define WM8995_AIF2DAC_EQ_B1_A_MASK 0xFFFF /* AIF2DAC_EQ_B1_A - [15:0] */
-#define WM8995_AIF2DAC_EQ_B1_A_SHIFT 0 /* AIF2DAC_EQ_B1_A - [15:0] */
-#define WM8995_AIF2DAC_EQ_B1_A_WIDTH 16 /* AIF2DAC_EQ_B1_A - [15:0] */
-
-/*
- * R1411 (0x583) - AIF2 EQ Band 1 B
- */
-#define WM8995_AIF2DAC_EQ_B1_B_MASK 0xFFFF /* AIF2DAC_EQ_B1_B - [15:0] */
-#define WM8995_AIF2DAC_EQ_B1_B_SHIFT 0 /* AIF2DAC_EQ_B1_B - [15:0] */
-#define WM8995_AIF2DAC_EQ_B1_B_WIDTH 16 /* AIF2DAC_EQ_B1_B - [15:0] */
-
-/*
- * R1412 (0x584) - AIF2 EQ Band 1 PG
- */
-#define WM8995_AIF2DAC_EQ_B1_PG_MASK 0xFFFF /* AIF2DAC_EQ_B1_PG - [15:0] */
-#define WM8995_AIF2DAC_EQ_B1_PG_SHIFT 0 /* AIF2DAC_EQ_B1_PG - [15:0] */
-#define WM8995_AIF2DAC_EQ_B1_PG_WIDTH 16 /* AIF2DAC_EQ_B1_PG - [15:0] */
-
-/*
- * R1413 (0x585) - AIF2 EQ Band 2 A
- */
-#define WM8995_AIF2DAC_EQ_B2_A_MASK 0xFFFF /* AIF2DAC_EQ_B2_A - [15:0] */
-#define WM8995_AIF2DAC_EQ_B2_A_SHIFT 0 /* AIF2DAC_EQ_B2_A - [15:0] */
-#define WM8995_AIF2DAC_EQ_B2_A_WIDTH 16 /* AIF2DAC_EQ_B2_A - [15:0] */
-
-/*
- * R1414 (0x586) - AIF2 EQ Band 2 B
- */
-#define WM8995_AIF2DAC_EQ_B2_B_MASK 0xFFFF /* AIF2DAC_EQ_B2_B - [15:0] */
-#define WM8995_AIF2DAC_EQ_B2_B_SHIFT 0 /* AIF2DAC_EQ_B2_B - [15:0] */
-#define WM8995_AIF2DAC_EQ_B2_B_WIDTH 16 /* AIF2DAC_EQ_B2_B - [15:0] */
-
-/*
- * R1415 (0x587) - AIF2 EQ Band 2 C
- */
-#define WM8995_AIF2DAC_EQ_B2_C_MASK 0xFFFF /* AIF2DAC_EQ_B2_C - [15:0] */
-#define WM8995_AIF2DAC_EQ_B2_C_SHIFT 0 /* AIF2DAC_EQ_B2_C - [15:0] */
-#define WM8995_AIF2DAC_EQ_B2_C_WIDTH 16 /* AIF2DAC_EQ_B2_C - [15:0] */
-
-/*
- * R1416 (0x588) - AIF2 EQ Band 2 PG
- */
-#define WM8995_AIF2DAC_EQ_B2_PG_MASK 0xFFFF /* AIF2DAC_EQ_B2_PG - [15:0] */
-#define WM8995_AIF2DAC_EQ_B2_PG_SHIFT 0 /* AIF2DAC_EQ_B2_PG - [15:0] */
-#define WM8995_AIF2DAC_EQ_B2_PG_WIDTH 16 /* AIF2DAC_EQ_B2_PG - [15:0] */
-
-/*
- * R1417 (0x589) - AIF2 EQ Band 3 A
- */
-#define WM8995_AIF2DAC_EQ_B3_A_MASK 0xFFFF /* AIF2DAC_EQ_B3_A - [15:0] */
-#define WM8995_AIF2DAC_EQ_B3_A_SHIFT 0 /* AIF2DAC_EQ_B3_A - [15:0] */
-#define WM8995_AIF2DAC_EQ_B3_A_WIDTH 16 /* AIF2DAC_EQ_B3_A - [15:0] */
-
-/*
- * R1418 (0x58A) - AIF2 EQ Band 3 B
- */
-#define WM8995_AIF2DAC_EQ_B3_B_MASK 0xFFFF /* AIF2DAC_EQ_B3_B - [15:0] */
-#define WM8995_AIF2DAC_EQ_B3_B_SHIFT 0 /* AIF2DAC_EQ_B3_B - [15:0] */
-#define WM8995_AIF2DAC_EQ_B3_B_WIDTH 16 /* AIF2DAC_EQ_B3_B - [15:0] */
-
-/*
- * R1419 (0x58B) - AIF2 EQ Band 3 C
- */
-#define WM8995_AIF2DAC_EQ_B3_C_MASK 0xFFFF /* AIF2DAC_EQ_B3_C - [15:0] */
-#define WM8995_AIF2DAC_EQ_B3_C_SHIFT 0 /* AIF2DAC_EQ_B3_C - [15:0] */
-#define WM8995_AIF2DAC_EQ_B3_C_WIDTH 16 /* AIF2DAC_EQ_B3_C - [15:0] */
-
-/*
- * R1420 (0x58C) - AIF2 EQ Band 3 PG
- */
-#define WM8995_AIF2DAC_EQ_B3_PG_MASK 0xFFFF /* AIF2DAC_EQ_B3_PG - [15:0] */
-#define WM8995_AIF2DAC_EQ_B3_PG_SHIFT 0 /* AIF2DAC_EQ_B3_PG - [15:0] */
-#define WM8995_AIF2DAC_EQ_B3_PG_WIDTH 16 /* AIF2DAC_EQ_B3_PG - [15:0] */
-
-/*
- * R1421 (0x58D) - AIF2 EQ Band 4 A
- */
-#define WM8995_AIF2DAC_EQ_B4_A_MASK 0xFFFF /* AIF2DAC_EQ_B4_A - [15:0] */
-#define WM8995_AIF2DAC_EQ_B4_A_SHIFT 0 /* AIF2DAC_EQ_B4_A - [15:0] */
-#define WM8995_AIF2DAC_EQ_B4_A_WIDTH 16 /* AIF2DAC_EQ_B4_A - [15:0] */
-
-/*
- * R1422 (0x58E) - AIF2 EQ Band 4 B
- */
-#define WM8995_AIF2DAC_EQ_B4_B_MASK 0xFFFF /* AIF2DAC_EQ_B4_B - [15:0] */
-#define WM8995_AIF2DAC_EQ_B4_B_SHIFT 0 /* AIF2DAC_EQ_B4_B - [15:0] */
-#define WM8995_AIF2DAC_EQ_B4_B_WIDTH 16 /* AIF2DAC_EQ_B4_B - [15:0] */
-
-/*
- * R1423 (0x58F) - AIF2 EQ Band 4 C
- */
-#define WM8995_AIF2DAC_EQ_B4_C_MASK 0xFFFF /* AIF2DAC_EQ_B4_C - [15:0] */
-#define WM8995_AIF2DAC_EQ_B4_C_SHIFT 0 /* AIF2DAC_EQ_B4_C - [15:0] */
-#define WM8995_AIF2DAC_EQ_B4_C_WIDTH 16 /* AIF2DAC_EQ_B4_C - [15:0] */
-
-/*
- * R1424 (0x590) - AIF2 EQ Band 4 PG
- */
-#define WM8995_AIF2DAC_EQ_B4_PG_MASK 0xFFFF /* AIF2DAC_EQ_B4_PG - [15:0] */
-#define WM8995_AIF2DAC_EQ_B4_PG_SHIFT 0 /* AIF2DAC_EQ_B4_PG - [15:0] */
-#define WM8995_AIF2DAC_EQ_B4_PG_WIDTH 16 /* AIF2DAC_EQ_B4_PG - [15:0] */
-
-/*
- * R1425 (0x591) - AIF2 EQ Band 5 A
- */
-#define WM8995_AIF2DAC_EQ_B5_A_MASK 0xFFFF /* AIF2DAC_EQ_B5_A - [15:0] */
-#define WM8995_AIF2DAC_EQ_B5_A_SHIFT 0 /* AIF2DAC_EQ_B5_A - [15:0] */
-#define WM8995_AIF2DAC_EQ_B5_A_WIDTH 16 /* AIF2DAC_EQ_B5_A - [15:0] */
-
-/*
- * R1426 (0x592) - AIF2 EQ Band 5 B
- */
-#define WM8995_AIF2DAC_EQ_B5_B_MASK 0xFFFF /* AIF2DAC_EQ_B5_B - [15:0] */
-#define WM8995_AIF2DAC_EQ_B5_B_SHIFT 0 /* AIF2DAC_EQ_B5_B - [15:0] */
-#define WM8995_AIF2DAC_EQ_B5_B_WIDTH 16 /* AIF2DAC_EQ_B5_B - [15:0] */
-
-/*
- * R1427 (0x593) - AIF2 EQ Band 5 PG
- */
-#define WM8995_AIF2DAC_EQ_B5_PG_MASK 0xFFFF /* AIF2DAC_EQ_B5_PG - [15:0] */
-#define WM8995_AIF2DAC_EQ_B5_PG_SHIFT 0 /* AIF2DAC_EQ_B5_PG - [15:0] */
-#define WM8995_AIF2DAC_EQ_B5_PG_WIDTH 16 /* AIF2DAC_EQ_B5_PG - [15:0] */
-
-/*
- * R1536 (0x600) - DAC1 Mixer Volumes
- */
-#define WM8995_ADCR_DAC1_VOL_MASK 0x03E0 /* ADCR_DAC1_VOL - [9:5] */
-#define WM8995_ADCR_DAC1_VOL_SHIFT 5 /* ADCR_DAC1_VOL - [9:5] */
-#define WM8995_ADCR_DAC1_VOL_WIDTH 5 /* ADCR_DAC1_VOL - [9:5] */
-#define WM8995_ADCL_DAC1_VOL_MASK 0x001F /* ADCL_DAC1_VOL - [4:0] */
-#define WM8995_ADCL_DAC1_VOL_SHIFT 0 /* ADCL_DAC1_VOL - [4:0] */
-#define WM8995_ADCL_DAC1_VOL_WIDTH 5 /* ADCL_DAC1_VOL - [4:0] */
-
-/*
- * R1537 (0x601) - DAC1 Left Mixer Routing
- */
-#define WM8995_ADCR_TO_DAC1L 0x0020 /* ADCR_TO_DAC1L */
-#define WM8995_ADCR_TO_DAC1L_MASK 0x0020 /* ADCR_TO_DAC1L */
-#define WM8995_ADCR_TO_DAC1L_SHIFT 5 /* ADCR_TO_DAC1L */
-#define WM8995_ADCR_TO_DAC1L_WIDTH 1 /* ADCR_TO_DAC1L */
-#define WM8995_ADCL_TO_DAC1L 0x0010 /* ADCL_TO_DAC1L */
-#define WM8995_ADCL_TO_DAC1L_MASK 0x0010 /* ADCL_TO_DAC1L */
-#define WM8995_ADCL_TO_DAC1L_SHIFT 4 /* ADCL_TO_DAC1L */
-#define WM8995_ADCL_TO_DAC1L_WIDTH 1 /* ADCL_TO_DAC1L */
-#define WM8995_AIF2DACL_TO_DAC1L 0x0004 /* AIF2DACL_TO_DAC1L */
-#define WM8995_AIF2DACL_TO_DAC1L_MASK 0x0004 /* AIF2DACL_TO_DAC1L */
-#define WM8995_AIF2DACL_TO_DAC1L_SHIFT 2 /* AIF2DACL_TO_DAC1L */
-#define WM8995_AIF2DACL_TO_DAC1L_WIDTH 1 /* AIF2DACL_TO_DAC1L */
-#define WM8995_AIF1DAC2L_TO_DAC1L 0x0002 /* AIF1DAC2L_TO_DAC1L */
-#define WM8995_AIF1DAC2L_TO_DAC1L_MASK 0x0002 /* AIF1DAC2L_TO_DAC1L */
-#define WM8995_AIF1DAC2L_TO_DAC1L_SHIFT 1 /* AIF1DAC2L_TO_DAC1L */
-#define WM8995_AIF1DAC2L_TO_DAC1L_WIDTH 1 /* AIF1DAC2L_TO_DAC1L */
-#define WM8995_AIF1DAC1L_TO_DAC1L 0x0001 /* AIF1DAC1L_TO_DAC1L */
-#define WM8995_AIF1DAC1L_TO_DAC1L_MASK 0x0001 /* AIF1DAC1L_TO_DAC1L */
-#define WM8995_AIF1DAC1L_TO_DAC1L_SHIFT 0 /* AIF1DAC1L_TO_DAC1L */
-#define WM8995_AIF1DAC1L_TO_DAC1L_WIDTH 1 /* AIF1DAC1L_TO_DAC1L */
-
-/*
- * R1538 (0x602) - DAC1 Right Mixer Routing
- */
-#define WM8995_ADCR_TO_DAC1R 0x0020 /* ADCR_TO_DAC1R */
-#define WM8995_ADCR_TO_DAC1R_MASK 0x0020 /* ADCR_TO_DAC1R */
-#define WM8995_ADCR_TO_DAC1R_SHIFT 5 /* ADCR_TO_DAC1R */
-#define WM8995_ADCR_TO_DAC1R_WIDTH 1 /* ADCR_TO_DAC1R */
-#define WM8995_ADCL_TO_DAC1R 0x0010 /* ADCL_TO_DAC1R */
-#define WM8995_ADCL_TO_DAC1R_MASK 0x0010 /* ADCL_TO_DAC1R */
-#define WM8995_ADCL_TO_DAC1R_SHIFT 4 /* ADCL_TO_DAC1R */
-#define WM8995_ADCL_TO_DAC1R_WIDTH 1 /* ADCL_TO_DAC1R */
-#define WM8995_AIF2DACR_TO_DAC1R 0x0004 /* AIF2DACR_TO_DAC1R */
-#define WM8995_AIF2DACR_TO_DAC1R_MASK 0x0004 /* AIF2DACR_TO_DAC1R */
-#define WM8995_AIF2DACR_TO_DAC1R_SHIFT 2 /* AIF2DACR_TO_DAC1R */
-#define WM8995_AIF2DACR_TO_DAC1R_WIDTH 1 /* AIF2DACR_TO_DAC1R */
-#define WM8995_AIF1DAC2R_TO_DAC1R 0x0002 /* AIF1DAC2R_TO_DAC1R */
-#define WM8995_AIF1DAC2R_TO_DAC1R_MASK 0x0002 /* AIF1DAC2R_TO_DAC1R */
-#define WM8995_AIF1DAC2R_TO_DAC1R_SHIFT 1 /* AIF1DAC2R_TO_DAC1R */
-#define WM8995_AIF1DAC2R_TO_DAC1R_WIDTH 1 /* AIF1DAC2R_TO_DAC1R */
-#define WM8995_AIF1DAC1R_TO_DAC1R 0x0001 /* AIF1DAC1R_TO_DAC1R */
-#define WM8995_AIF1DAC1R_TO_DAC1R_MASK 0x0001 /* AIF1DAC1R_TO_DAC1R */
-#define WM8995_AIF1DAC1R_TO_DAC1R_SHIFT 0 /* AIF1DAC1R_TO_DAC1R */
-#define WM8995_AIF1DAC1R_TO_DAC1R_WIDTH 1 /* AIF1DAC1R_TO_DAC1R */
-
-/*
- * R1539 (0x603) - DAC2 Mixer Volumes
- */
-#define WM8995_ADCR_DAC2_VOL_MASK 0x03E0 /* ADCR_DAC2_VOL - [9:5] */
-#define WM8995_ADCR_DAC2_VOL_SHIFT 5 /* ADCR_DAC2_VOL - [9:5] */
-#define WM8995_ADCR_DAC2_VOL_WIDTH 5 /* ADCR_DAC2_VOL - [9:5] */
-#define WM8995_ADCL_DAC2_VOL_MASK 0x001F /* ADCL_DAC2_VOL - [4:0] */
-#define WM8995_ADCL_DAC2_VOL_SHIFT 0 /* ADCL_DAC2_VOL - [4:0] */
-#define WM8995_ADCL_DAC2_VOL_WIDTH 5 /* ADCL_DAC2_VOL - [4:0] */
-
-/*
- * R1540 (0x604) - DAC2 Left Mixer Routing
- */
-#define WM8995_ADCR_TO_DAC2L 0x0020 /* ADCR_TO_DAC2L */
-#define WM8995_ADCR_TO_DAC2L_MASK 0x0020 /* ADCR_TO_DAC2L */
-#define WM8995_ADCR_TO_DAC2L_SHIFT 5 /* ADCR_TO_DAC2L */
-#define WM8995_ADCR_TO_DAC2L_WIDTH 1 /* ADCR_TO_DAC2L */
-#define WM8995_ADCL_TO_DAC2L 0x0010 /* ADCL_TO_DAC2L */
-#define WM8995_ADCL_TO_DAC2L_MASK 0x0010 /* ADCL_TO_DAC2L */
-#define WM8995_ADCL_TO_DAC2L_SHIFT 4 /* ADCL_TO_DAC2L */
-#define WM8995_ADCL_TO_DAC2L_WIDTH 1 /* ADCL_TO_DAC2L */
-#define WM8995_AIF2DACL_TO_DAC2L 0x0004 /* AIF2DACL_TO_DAC2L */
-#define WM8995_AIF2DACL_TO_DAC2L_MASK 0x0004 /* AIF2DACL_TO_DAC2L */
-#define WM8995_AIF2DACL_TO_DAC2L_SHIFT 2 /* AIF2DACL_TO_DAC2L */
-#define WM8995_AIF2DACL_TO_DAC2L_WIDTH 1 /* AIF2DACL_TO_DAC2L */
-#define WM8995_AIF1DAC2L_TO_DAC2L 0x0002 /* AIF1DAC2L_TO_DAC2L */
-#define WM8995_AIF1DAC2L_TO_DAC2L_MASK 0x0002 /* AIF1DAC2L_TO_DAC2L */
-#define WM8995_AIF1DAC2L_TO_DAC2L_SHIFT 1 /* AIF1DAC2L_TO_DAC2L */
-#define WM8995_AIF1DAC2L_TO_DAC2L_WIDTH 1 /* AIF1DAC2L_TO_DAC2L */
-#define WM8995_AIF1DAC1L_TO_DAC2L 0x0001 /* AIF1DAC1L_TO_DAC2L */
-#define WM8995_AIF1DAC1L_TO_DAC2L_MASK 0x0001 /* AIF1DAC1L_TO_DAC2L */
-#define WM8995_AIF1DAC1L_TO_DAC2L_SHIFT 0 /* AIF1DAC1L_TO_DAC2L */
-#define WM8995_AIF1DAC1L_TO_DAC2L_WIDTH 1 /* AIF1DAC1L_TO_DAC2L */
-
-/*
- * R1541 (0x605) - DAC2 Right Mixer Routing
- */
-#define WM8995_ADCR_TO_DAC2R 0x0020 /* ADCR_TO_DAC2R */
-#define WM8995_ADCR_TO_DAC2R_MASK 0x0020 /* ADCR_TO_DAC2R */
-#define WM8995_ADCR_TO_DAC2R_SHIFT 5 /* ADCR_TO_DAC2R */
-#define WM8995_ADCR_TO_DAC2R_WIDTH 1 /* ADCR_TO_DAC2R */
-#define WM8995_ADCL_TO_DAC2R 0x0010 /* ADCL_TO_DAC2R */
-#define WM8995_ADCL_TO_DAC2R_MASK 0x0010 /* ADCL_TO_DAC2R */
-#define WM8995_ADCL_TO_DAC2R_SHIFT 4 /* ADCL_TO_DAC2R */
-#define WM8995_ADCL_TO_DAC2R_WIDTH 1 /* ADCL_TO_DAC2R */
-#define WM8995_AIF2DACR_TO_DAC2R 0x0004 /* AIF2DACR_TO_DAC2R */
-#define WM8995_AIF2DACR_TO_DAC2R_MASK 0x0004 /* AIF2DACR_TO_DAC2R */
-#define WM8995_AIF2DACR_TO_DAC2R_SHIFT 2 /* AIF2DACR_TO_DAC2R */
-#define WM8995_AIF2DACR_TO_DAC2R_WIDTH 1 /* AIF2DACR_TO_DAC2R */
-#define WM8995_AIF1DAC2R_TO_DAC2R 0x0002 /* AIF1DAC2R_TO_DAC2R */
-#define WM8995_AIF1DAC2R_TO_DAC2R_MASK 0x0002 /* AIF1DAC2R_TO_DAC2R */
-#define WM8995_AIF1DAC2R_TO_DAC2R_SHIFT 1 /* AIF1DAC2R_TO_DAC2R */
-#define WM8995_AIF1DAC2R_TO_DAC2R_WIDTH 1 /* AIF1DAC2R_TO_DAC2R */
-#define WM8995_AIF1DAC1R_TO_DAC2R 0x0001 /* AIF1DAC1R_TO_DAC2R */
-#define WM8995_AIF1DAC1R_TO_DAC2R_MASK 0x0001 /* AIF1DAC1R_TO_DAC2R */
-#define WM8995_AIF1DAC1R_TO_DAC2R_SHIFT 0 /* AIF1DAC1R_TO_DAC2R */
-#define WM8995_AIF1DAC1R_TO_DAC2R_WIDTH 1 /* AIF1DAC1R_TO_DAC2R */
-
-/*
- * R1542 (0x606) - AIF1 ADC1 Left Mixer Routing
- */
-#define WM8995_ADC1L_TO_AIF1ADC1L 0x0002 /* ADC1L_TO_AIF1ADC1L */
-#define WM8995_ADC1L_TO_AIF1ADC1L_MASK 0x0002 /* ADC1L_TO_AIF1ADC1L */
-#define WM8995_ADC1L_TO_AIF1ADC1L_SHIFT 1 /* ADC1L_TO_AIF1ADC1L */
-#define WM8995_ADC1L_TO_AIF1ADC1L_WIDTH 1 /* ADC1L_TO_AIF1ADC1L */
-#define WM8995_AIF2DACL_TO_AIF1ADC1L 0x0001 /* AIF2DACL_TO_AIF1ADC1L */
-#define WM8995_AIF2DACL_TO_AIF1ADC1L_MASK 0x0001 /* AIF2DACL_TO_AIF1ADC1L */
-#define WM8995_AIF2DACL_TO_AIF1ADC1L_SHIFT 0 /* AIF2DACL_TO_AIF1ADC1L */
-#define WM8995_AIF2DACL_TO_AIF1ADC1L_WIDTH 1 /* AIF2DACL_TO_AIF1ADC1L */
-
-/*
- * R1543 (0x607) - AIF1 ADC1 Right Mixer Routing
- */
-#define WM8995_ADC1R_TO_AIF1ADC1R 0x0002 /* ADC1R_TO_AIF1ADC1R */
-#define WM8995_ADC1R_TO_AIF1ADC1R_MASK 0x0002 /* ADC1R_TO_AIF1ADC1R */
-#define WM8995_ADC1R_TO_AIF1ADC1R_SHIFT 1 /* ADC1R_TO_AIF1ADC1R */
-#define WM8995_ADC1R_TO_AIF1ADC1R_WIDTH 1 /* ADC1R_TO_AIF1ADC1R */
-#define WM8995_AIF2DACR_TO_AIF1ADC1R 0x0001 /* AIF2DACR_TO_AIF1ADC1R */
-#define WM8995_AIF2DACR_TO_AIF1ADC1R_MASK 0x0001 /* AIF2DACR_TO_AIF1ADC1R */
-#define WM8995_AIF2DACR_TO_AIF1ADC1R_SHIFT 0 /* AIF2DACR_TO_AIF1ADC1R */
-#define WM8995_AIF2DACR_TO_AIF1ADC1R_WIDTH 1 /* AIF2DACR_TO_AIF1ADC1R */
-
-/*
- * R1544 (0x608) - AIF1 ADC2 Left Mixer Routing
- */
-#define WM8995_ADC2L_TO_AIF1ADC2L 0x0002 /* ADC2L_TO_AIF1ADC2L */
-#define WM8995_ADC2L_TO_AIF1ADC2L_MASK 0x0002 /* ADC2L_TO_AIF1ADC2L */
-#define WM8995_ADC2L_TO_AIF1ADC2L_SHIFT 1 /* ADC2L_TO_AIF1ADC2L */
-#define WM8995_ADC2L_TO_AIF1ADC2L_WIDTH 1 /* ADC2L_TO_AIF1ADC2L */
-#define WM8995_AIF2DACL_TO_AIF1ADC2L 0x0001 /* AIF2DACL_TO_AIF1ADC2L */
-#define WM8995_AIF2DACL_TO_AIF1ADC2L_MASK 0x0001 /* AIF2DACL_TO_AIF1ADC2L */
-#define WM8995_AIF2DACL_TO_AIF1ADC2L_SHIFT 0 /* AIF2DACL_TO_AIF1ADC2L */
-#define WM8995_AIF2DACL_TO_AIF1ADC2L_WIDTH 1 /* AIF2DACL_TO_AIF1ADC2L */
-
-/*
- * R1545 (0x609) - AIF1 ADC2 Right mixer Routing
- */
-#define WM8995_ADC2R_TO_AIF1ADC2R 0x0002 /* ADC2R_TO_AIF1ADC2R */
-#define WM8995_ADC2R_TO_AIF1ADC2R_MASK 0x0002 /* ADC2R_TO_AIF1ADC2R */
-#define WM8995_ADC2R_TO_AIF1ADC2R_SHIFT 1 /* ADC2R_TO_AIF1ADC2R */
-#define WM8995_ADC2R_TO_AIF1ADC2R_WIDTH 1 /* ADC2R_TO_AIF1ADC2R */
-#define WM8995_AIF2DACR_TO_AIF1ADC2R 0x0001 /* AIF2DACR_TO_AIF1ADC2R */
-#define WM8995_AIF2DACR_TO_AIF1ADC2R_MASK 0x0001 /* AIF2DACR_TO_AIF1ADC2R */
-#define WM8995_AIF2DACR_TO_AIF1ADC2R_SHIFT 0 /* AIF2DACR_TO_AIF1ADC2R */
-#define WM8995_AIF2DACR_TO_AIF1ADC2R_WIDTH 1 /* AIF2DACR_TO_AIF1ADC2R */
-
-/*
- * R1552 (0x610) - DAC Softmute
- */
-#define WM8995_DAC_SOFTMUTEMODE 0x0002 /* DAC_SOFTMUTEMODE */
-#define WM8995_DAC_SOFTMUTEMODE_MASK 0x0002 /* DAC_SOFTMUTEMODE */
-#define WM8995_DAC_SOFTMUTEMODE_SHIFT 1 /* DAC_SOFTMUTEMODE */
-#define WM8995_DAC_SOFTMUTEMODE_WIDTH 1 /* DAC_SOFTMUTEMODE */
-#define WM8995_DAC_MUTERATE 0x0001 /* DAC_MUTERATE */
-#define WM8995_DAC_MUTERATE_MASK 0x0001 /* DAC_MUTERATE */
-#define WM8995_DAC_MUTERATE_SHIFT 0 /* DAC_MUTERATE */
-#define WM8995_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
-
-/*
- * R1568 (0x620) - Oversampling
- */
-#define WM8995_ADC_OSR128 0x0002 /* ADC_OSR128 */
-#define WM8995_ADC_OSR128_MASK 0x0002 /* ADC_OSR128 */
-#define WM8995_ADC_OSR128_SHIFT 1 /* ADC_OSR128 */
-#define WM8995_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
-#define WM8995_DAC_OSR128 0x0001 /* DAC_OSR128 */
-#define WM8995_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */
-#define WM8995_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */
-#define WM8995_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
-
-/*
- * R1569 (0x621) - Sidetone
- */
-#define WM8995_ST_LPF 0x1000 /* ST_LPF */
-#define WM8995_ST_LPF_MASK 0x1000 /* ST_LPF */
-#define WM8995_ST_LPF_SHIFT 12 /* ST_LPF */
-#define WM8995_ST_LPF_WIDTH 1 /* ST_LPF */
-#define WM8995_ST_HPF_CUT_MASK 0x0380 /* ST_HPF_CUT - [9:7] */
-#define WM8995_ST_HPF_CUT_SHIFT 7 /* ST_HPF_CUT - [9:7] */
-#define WM8995_ST_HPF_CUT_WIDTH 3 /* ST_HPF_CUT - [9:7] */
-#define WM8995_ST_HPF 0x0040 /* ST_HPF */
-#define WM8995_ST_HPF_MASK 0x0040 /* ST_HPF */
-#define WM8995_ST_HPF_SHIFT 6 /* ST_HPF */
-#define WM8995_ST_HPF_WIDTH 1 /* ST_HPF */
-#define WM8995_STR_SEL 0x0002 /* STR_SEL */
-#define WM8995_STR_SEL_MASK 0x0002 /* STR_SEL */
-#define WM8995_STR_SEL_SHIFT 1 /* STR_SEL */
-#define WM8995_STR_SEL_WIDTH 1 /* STR_SEL */
-#define WM8995_STL_SEL 0x0001 /* STL_SEL */
-#define WM8995_STL_SEL_MASK 0x0001 /* STL_SEL */
-#define WM8995_STL_SEL_SHIFT 0 /* STL_SEL */
-#define WM8995_STL_SEL_WIDTH 1 /* STL_SEL */
-
-/*
- * R1792 (0x700) - GPIO 1
- */
-#define WM8995_GP1_DIR 0x8000 /* GP1_DIR */
-#define WM8995_GP1_DIR_MASK 0x8000 /* GP1_DIR */
-#define WM8995_GP1_DIR_SHIFT 15 /* GP1_DIR */
-#define WM8995_GP1_DIR_WIDTH 1 /* GP1_DIR */
-#define WM8995_GP1_PU 0x4000 /* GP1_PU */
-#define WM8995_GP1_PU_MASK 0x4000 /* GP1_PU */
-#define WM8995_GP1_PU_SHIFT 14 /* GP1_PU */
-#define WM8995_GP1_PU_WIDTH 1 /* GP1_PU */
-#define WM8995_GP1_PD 0x2000 /* GP1_PD */
-#define WM8995_GP1_PD_MASK 0x2000 /* GP1_PD */
-#define WM8995_GP1_PD_SHIFT 13 /* GP1_PD */
-#define WM8995_GP1_PD_WIDTH 1 /* GP1_PD */
-#define WM8995_GP1_POL 0x0400 /* GP1_POL */
-#define WM8995_GP1_POL_MASK 0x0400 /* GP1_POL */
-#define WM8995_GP1_POL_SHIFT 10 /* GP1_POL */
-#define WM8995_GP1_POL_WIDTH 1 /* GP1_POL */
-#define WM8995_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */
-#define WM8995_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */
-#define WM8995_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */
-#define WM8995_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
-#define WM8995_GP1_DB 0x0100 /* GP1_DB */
-#define WM8995_GP1_DB_MASK 0x0100 /* GP1_DB */
-#define WM8995_GP1_DB_SHIFT 8 /* GP1_DB */
-#define WM8995_GP1_DB_WIDTH 1 /* GP1_DB */
-#define WM8995_GP1_LVL 0x0040 /* GP1_LVL */
-#define WM8995_GP1_LVL_MASK 0x0040 /* GP1_LVL */
-#define WM8995_GP1_LVL_SHIFT 6 /* GP1_LVL */
-#define WM8995_GP1_LVL_WIDTH 1 /* GP1_LVL */
-#define WM8995_GP1_FN_MASK 0x001F /* GP1_FN - [4:0] */
-#define WM8995_GP1_FN_SHIFT 0 /* GP1_FN - [4:0] */
-#define WM8995_GP1_FN_WIDTH 5 /* GP1_FN - [4:0] */
-
-/*
- * R1793 (0x701) - GPIO 2
- */
-#define WM8995_GP2_DIR 0x8000 /* GP2_DIR */
-#define WM8995_GP2_DIR_MASK 0x8000 /* GP2_DIR */
-#define WM8995_GP2_DIR_SHIFT 15 /* GP2_DIR */
-#define WM8995_GP2_DIR_WIDTH 1 /* GP2_DIR */
-#define WM8995_GP2_PU 0x4000 /* GP2_PU */
-#define WM8995_GP2_PU_MASK 0x4000 /* GP2_PU */
-#define WM8995_GP2_PU_SHIFT 14 /* GP2_PU */
-#define WM8995_GP2_PU_WIDTH 1 /* GP2_PU */
-#define WM8995_GP2_PD 0x2000 /* GP2_PD */
-#define WM8995_GP2_PD_MASK 0x2000 /* GP2_PD */
-#define WM8995_GP2_PD_SHIFT 13 /* GP2_PD */
-#define WM8995_GP2_PD_WIDTH 1 /* GP2_PD */
-#define WM8995_GP2_POL 0x0400 /* GP2_POL */
-#define WM8995_GP2_POL_MASK 0x0400 /* GP2_POL */
-#define WM8995_GP2_POL_SHIFT 10 /* GP2_POL */
-#define WM8995_GP2_POL_WIDTH 1 /* GP2_POL */
-#define WM8995_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */
-#define WM8995_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */
-#define WM8995_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */
-#define WM8995_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
-#define WM8995_GP2_DB 0x0100 /* GP2_DB */
-#define WM8995_GP2_DB_MASK 0x0100 /* GP2_DB */
-#define WM8995_GP2_DB_SHIFT 8 /* GP2_DB */
-#define WM8995_GP2_DB_WIDTH 1 /* GP2_DB */
-#define WM8995_GP2_LVL 0x0040 /* GP2_LVL */
-#define WM8995_GP2_LVL_MASK 0x0040 /* GP2_LVL */
-#define WM8995_GP2_LVL_SHIFT 6 /* GP2_LVL */
-#define WM8995_GP2_LVL_WIDTH 1 /* GP2_LVL */
-#define WM8995_GP2_FN_MASK 0x001F /* GP2_FN - [4:0] */
-#define WM8995_GP2_FN_SHIFT 0 /* GP2_FN - [4:0] */
-#define WM8995_GP2_FN_WIDTH 5 /* GP2_FN - [4:0] */
-
-/*
- * R1794 (0x702) - GPIO 3
- */
-#define WM8995_GP3_DIR 0x8000 /* GP3_DIR */
-#define WM8995_GP3_DIR_MASK 0x8000 /* GP3_DIR */
-#define WM8995_GP3_DIR_SHIFT 15 /* GP3_DIR */
-#define WM8995_GP3_DIR_WIDTH 1 /* GP3_DIR */
-#define WM8995_GP3_PU 0x4000 /* GP3_PU */
-#define WM8995_GP3_PU_MASK 0x4000 /* GP3_PU */
-#define WM8995_GP3_PU_SHIFT 14 /* GP3_PU */
-#define WM8995_GP3_PU_WIDTH 1 /* GP3_PU */
-#define WM8995_GP3_PD 0x2000 /* GP3_PD */
-#define WM8995_GP3_PD_MASK 0x2000 /* GP3_PD */
-#define WM8995_GP3_PD_SHIFT 13 /* GP3_PD */
-#define WM8995_GP3_PD_WIDTH 1 /* GP3_PD */
-#define WM8995_GP3_POL 0x0400 /* GP3_POL */
-#define WM8995_GP3_POL_MASK 0x0400 /* GP3_POL */
-#define WM8995_GP3_POL_SHIFT 10 /* GP3_POL */
-#define WM8995_GP3_POL_WIDTH 1 /* GP3_POL */
-#define WM8995_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */
-#define WM8995_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */
-#define WM8995_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */
-#define WM8995_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
-#define WM8995_GP3_DB 0x0100 /* GP3_DB */
-#define WM8995_GP3_DB_MASK 0x0100 /* GP3_DB */
-#define WM8995_GP3_DB_SHIFT 8 /* GP3_DB */
-#define WM8995_GP3_DB_WIDTH 1 /* GP3_DB */
-#define WM8995_GP3_LVL 0x0040 /* GP3_LVL */
-#define WM8995_GP3_LVL_MASK 0x0040 /* GP3_LVL */
-#define WM8995_GP3_LVL_SHIFT 6 /* GP3_LVL */
-#define WM8995_GP3_LVL_WIDTH 1 /* GP3_LVL */
-#define WM8995_GP3_FN_MASK 0x001F /* GP3_FN - [4:0] */
-#define WM8995_GP3_FN_SHIFT 0 /* GP3_FN - [4:0] */
-#define WM8995_GP3_FN_WIDTH 5 /* GP3_FN - [4:0] */
-
-/*
- * R1795 (0x703) - GPIO 4
- */
-#define WM8995_GP4_DIR 0x8000 /* GP4_DIR */
-#define WM8995_GP4_DIR_MASK 0x8000 /* GP4_DIR */
-#define WM8995_GP4_DIR_SHIFT 15 /* GP4_DIR */
-#define WM8995_GP4_DIR_WIDTH 1 /* GP4_DIR */
-#define WM8995_GP4_PU 0x4000 /* GP4_PU */
-#define WM8995_GP4_PU_MASK 0x4000 /* GP4_PU */
-#define WM8995_GP4_PU_SHIFT 14 /* GP4_PU */
-#define WM8995_GP4_PU_WIDTH 1 /* GP4_PU */
-#define WM8995_GP4_PD 0x2000 /* GP4_PD */
-#define WM8995_GP4_PD_MASK 0x2000 /* GP4_PD */
-#define WM8995_GP4_PD_SHIFT 13 /* GP4_PD */
-#define WM8995_GP4_PD_WIDTH 1 /* GP4_PD */
-#define WM8995_GP4_POL 0x0400 /* GP4_POL */
-#define WM8995_GP4_POL_MASK 0x0400 /* GP4_POL */
-#define WM8995_GP4_POL_SHIFT 10 /* GP4_POL */
-#define WM8995_GP4_POL_WIDTH 1 /* GP4_POL */
-#define WM8995_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */
-#define WM8995_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */
-#define WM8995_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */
-#define WM8995_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
-#define WM8995_GP4_DB 0x0100 /* GP4_DB */
-#define WM8995_GP4_DB_MASK 0x0100 /* GP4_DB */
-#define WM8995_GP4_DB_SHIFT 8 /* GP4_DB */
-#define WM8995_GP4_DB_WIDTH 1 /* GP4_DB */
-#define WM8995_GP4_LVL 0x0040 /* GP4_LVL */
-#define WM8995_GP4_LVL_MASK 0x0040 /* GP4_LVL */
-#define WM8995_GP4_LVL_SHIFT 6 /* GP4_LVL */
-#define WM8995_GP4_LVL_WIDTH 1 /* GP4_LVL */
-#define WM8995_GP4_FN_MASK 0x001F /* GP4_FN - [4:0] */
-#define WM8995_GP4_FN_SHIFT 0 /* GP4_FN - [4:0] */
-#define WM8995_GP4_FN_WIDTH 5 /* GP4_FN - [4:0] */
-
-/*
- * R1796 (0x704) - GPIO 5
- */
-#define WM8995_GP5_DIR 0x8000 /* GP5_DIR */
-#define WM8995_GP5_DIR_MASK 0x8000 /* GP5_DIR */
-#define WM8995_GP5_DIR_SHIFT 15 /* GP5_DIR */
-#define WM8995_GP5_DIR_WIDTH 1 /* GP5_DIR */
-#define WM8995_GP5_PU 0x4000 /* GP5_PU */
-#define WM8995_GP5_PU_MASK 0x4000 /* GP5_PU */
-#define WM8995_GP5_PU_SHIFT 14 /* GP5_PU */
-#define WM8995_GP5_PU_WIDTH 1 /* GP5_PU */
-#define WM8995_GP5_PD 0x2000 /* GP5_PD */
-#define WM8995_GP5_PD_MASK 0x2000 /* GP5_PD */
-#define WM8995_GP5_PD_SHIFT 13 /* GP5_PD */
-#define WM8995_GP5_PD_WIDTH 1 /* GP5_PD */
-#define WM8995_GP5_POL 0x0400 /* GP5_POL */
-#define WM8995_GP5_POL_MASK 0x0400 /* GP5_POL */
-#define WM8995_GP5_POL_SHIFT 10 /* GP5_POL */
-#define WM8995_GP5_POL_WIDTH 1 /* GP5_POL */
-#define WM8995_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */
-#define WM8995_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */
-#define WM8995_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */
-#define WM8995_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
-#define WM8995_GP5_DB 0x0100 /* GP5_DB */
-#define WM8995_GP5_DB_MASK 0x0100 /* GP5_DB */
-#define WM8995_GP5_DB_SHIFT 8 /* GP5_DB */
-#define WM8995_GP5_DB_WIDTH 1 /* GP5_DB */
-#define WM8995_GP5_LVL 0x0040 /* GP5_LVL */
-#define WM8995_GP5_LVL_MASK 0x0040 /* GP5_LVL */
-#define WM8995_GP5_LVL_SHIFT 6 /* GP5_LVL */
-#define WM8995_GP5_LVL_WIDTH 1 /* GP5_LVL */
-#define WM8995_GP5_FN_MASK 0x001F /* GP5_FN - [4:0] */
-#define WM8995_GP5_FN_SHIFT 0 /* GP5_FN - [4:0] */
-#define WM8995_GP5_FN_WIDTH 5 /* GP5_FN - [4:0] */
-
-/*
- * R1797 (0x705) - GPIO 6
- */
-#define WM8995_GP6_DIR 0x8000 /* GP6_DIR */
-#define WM8995_GP6_DIR_MASK 0x8000 /* GP6_DIR */
-#define WM8995_GP6_DIR_SHIFT 15 /* GP6_DIR */
-#define WM8995_GP6_DIR_WIDTH 1 /* GP6_DIR */
-#define WM8995_GP6_PU 0x4000 /* GP6_PU */
-#define WM8995_GP6_PU_MASK 0x4000 /* GP6_PU */
-#define WM8995_GP6_PU_SHIFT 14 /* GP6_PU */
-#define WM8995_GP6_PU_WIDTH 1 /* GP6_PU */
-#define WM8995_GP6_PD 0x2000 /* GP6_PD */
-#define WM8995_GP6_PD_MASK 0x2000 /* GP6_PD */
-#define WM8995_GP6_PD_SHIFT 13 /* GP6_PD */
-#define WM8995_GP6_PD_WIDTH 1 /* GP6_PD */
-#define WM8995_GP6_POL 0x0400 /* GP6_POL */
-#define WM8995_GP6_POL_MASK 0x0400 /* GP6_POL */
-#define WM8995_GP6_POL_SHIFT 10 /* GP6_POL */
-#define WM8995_GP6_POL_WIDTH 1 /* GP6_POL */
-#define WM8995_GP6_OP_CFG 0x0200 /* GP6_OP_CFG */
-#define WM8995_GP6_OP_CFG_MASK 0x0200 /* GP6_OP_CFG */
-#define WM8995_GP6_OP_CFG_SHIFT 9 /* GP6_OP_CFG */
-#define WM8995_GP6_OP_CFG_WIDTH 1 /* GP6_OP_CFG */
-#define WM8995_GP6_DB 0x0100 /* GP6_DB */
-#define WM8995_GP6_DB_MASK 0x0100 /* GP6_DB */
-#define WM8995_GP6_DB_SHIFT 8 /* GP6_DB */
-#define WM8995_GP6_DB_WIDTH 1 /* GP6_DB */
-#define WM8995_GP6_LVL 0x0040 /* GP6_LVL */
-#define WM8995_GP6_LVL_MASK 0x0040 /* GP6_LVL */
-#define WM8995_GP6_LVL_SHIFT 6 /* GP6_LVL */
-#define WM8995_GP6_LVL_WIDTH 1 /* GP6_LVL */
-#define WM8995_GP6_FN_MASK 0x001F /* GP6_FN - [4:0] */
-#define WM8995_GP6_FN_SHIFT 0 /* GP6_FN - [4:0] */
-#define WM8995_GP6_FN_WIDTH 5 /* GP6_FN - [4:0] */
-
-/*
- * R1798 (0x706) - GPIO 7
- */
-#define WM8995_GP7_DIR 0x8000 /* GP7_DIR */
-#define WM8995_GP7_DIR_MASK 0x8000 /* GP7_DIR */
-#define WM8995_GP7_DIR_SHIFT 15 /* GP7_DIR */
-#define WM8995_GP7_DIR_WIDTH 1 /* GP7_DIR */
-#define WM8995_GP7_PU 0x4000 /* GP7_PU */
-#define WM8995_GP7_PU_MASK 0x4000 /* GP7_PU */
-#define WM8995_GP7_PU_SHIFT 14 /* GP7_PU */
-#define WM8995_GP7_PU_WIDTH 1 /* GP7_PU */
-#define WM8995_GP7_PD 0x2000 /* GP7_PD */
-#define WM8995_GP7_PD_MASK 0x2000 /* GP7_PD */
-#define WM8995_GP7_PD_SHIFT 13 /* GP7_PD */
-#define WM8995_GP7_PD_WIDTH 1 /* GP7_PD */
-#define WM8995_GP7_POL 0x0400 /* GP7_POL */
-#define WM8995_GP7_POL_MASK 0x0400 /* GP7_POL */
-#define WM8995_GP7_POL_SHIFT 10 /* GP7_POL */
-#define WM8995_GP7_POL_WIDTH 1 /* GP7_POL */
-#define WM8995_GP7_OP_CFG 0x0200 /* GP7_OP_CFG */
-#define WM8995_GP7_OP_CFG_MASK 0x0200 /* GP7_OP_CFG */
-#define WM8995_GP7_OP_CFG_SHIFT 9 /* GP7_OP_CFG */
-#define WM8995_GP7_OP_CFG_WIDTH 1 /* GP7_OP_CFG */
-#define WM8995_GP7_DB 0x0100 /* GP7_DB */
-#define WM8995_GP7_DB_MASK 0x0100 /* GP7_DB */
-#define WM8995_GP7_DB_SHIFT 8 /* GP7_DB */
-#define WM8995_GP7_DB_WIDTH 1 /* GP7_DB */
-#define WM8995_GP7_LVL 0x0040 /* GP7_LVL */
-#define WM8995_GP7_LVL_MASK 0x0040 /* GP7_LVL */
-#define WM8995_GP7_LVL_SHIFT 6 /* GP7_LVL */
-#define WM8995_GP7_LVL_WIDTH 1 /* GP7_LVL */
-#define WM8995_GP7_FN_MASK 0x001F /* GP7_FN - [4:0] */
-#define WM8995_GP7_FN_SHIFT 0 /* GP7_FN - [4:0] */
-#define WM8995_GP7_FN_WIDTH 5 /* GP7_FN - [4:0] */
-
-/*
- * R1799 (0x707) - GPIO 8
- */
-#define WM8995_GP8_DIR 0x8000 /* GP8_DIR */
-#define WM8995_GP8_DIR_MASK 0x8000 /* GP8_DIR */
-#define WM8995_GP8_DIR_SHIFT 15 /* GP8_DIR */
-#define WM8995_GP8_DIR_WIDTH 1 /* GP8_DIR */
-#define WM8995_GP8_PU 0x4000 /* GP8_PU */
-#define WM8995_GP8_PU_MASK 0x4000 /* GP8_PU */
-#define WM8995_GP8_PU_SHIFT 14 /* GP8_PU */
-#define WM8995_GP8_PU_WIDTH 1 /* GP8_PU */
-#define WM8995_GP8_PD 0x2000 /* GP8_PD */
-#define WM8995_GP8_PD_MASK 0x2000 /* GP8_PD */
-#define WM8995_GP8_PD_SHIFT 13 /* GP8_PD */
-#define WM8995_GP8_PD_WIDTH 1 /* GP8_PD */
-#define WM8995_GP8_POL 0x0400 /* GP8_POL */
-#define WM8995_GP8_POL_MASK 0x0400 /* GP8_POL */
-#define WM8995_GP8_POL_SHIFT 10 /* GP8_POL */
-#define WM8995_GP8_POL_WIDTH 1 /* GP8_POL */
-#define WM8995_GP8_OP_CFG 0x0200 /* GP8_OP_CFG */
-#define WM8995_GP8_OP_CFG_MASK 0x0200 /* GP8_OP_CFG */
-#define WM8995_GP8_OP_CFG_SHIFT 9 /* GP8_OP_CFG */
-#define WM8995_GP8_OP_CFG_WIDTH 1 /* GP8_OP_CFG */
-#define WM8995_GP8_DB 0x0100 /* GP8_DB */
-#define WM8995_GP8_DB_MASK 0x0100 /* GP8_DB */
-#define WM8995_GP8_DB_SHIFT 8 /* GP8_DB */
-#define WM8995_GP8_DB_WIDTH 1 /* GP8_DB */
-#define WM8995_GP8_LVL 0x0040 /* GP8_LVL */
-#define WM8995_GP8_LVL_MASK 0x0040 /* GP8_LVL */
-#define WM8995_GP8_LVL_SHIFT 6 /* GP8_LVL */
-#define WM8995_GP8_LVL_WIDTH 1 /* GP8_LVL */
-#define WM8995_GP8_FN_MASK 0x001F /* GP8_FN - [4:0] */
-#define WM8995_GP8_FN_SHIFT 0 /* GP8_FN - [4:0] */
-#define WM8995_GP8_FN_WIDTH 5 /* GP8_FN - [4:0] */
-
-/*
- * R1800 (0x708) - GPIO 9
- */
-#define WM8995_GP9_DIR 0x8000 /* GP9_DIR */
-#define WM8995_GP9_DIR_MASK 0x8000 /* GP9_DIR */
-#define WM8995_GP9_DIR_SHIFT 15 /* GP9_DIR */
-#define WM8995_GP9_DIR_WIDTH 1 /* GP9_DIR */
-#define WM8995_GP9_PU 0x4000 /* GP9_PU */
-#define WM8995_GP9_PU_MASK 0x4000 /* GP9_PU */
-#define WM8995_GP9_PU_SHIFT 14 /* GP9_PU */
-#define WM8995_GP9_PU_WIDTH 1 /* GP9_PU */
-#define WM8995_GP9_PD 0x2000 /* GP9_PD */
-#define WM8995_GP9_PD_MASK 0x2000 /* GP9_PD */
-#define WM8995_GP9_PD_SHIFT 13 /* GP9_PD */
-#define WM8995_GP9_PD_WIDTH 1 /* GP9_PD */
-#define WM8995_GP9_POL 0x0400 /* GP9_POL */
-#define WM8995_GP9_POL_MASK 0x0400 /* GP9_POL */
-#define WM8995_GP9_POL_SHIFT 10 /* GP9_POL */
-#define WM8995_GP9_POL_WIDTH 1 /* GP9_POL */
-#define WM8995_GP9_OP_CFG 0x0200 /* GP9_OP_CFG */
-#define WM8995_GP9_OP_CFG_MASK 0x0200 /* GP9_OP_CFG */
-#define WM8995_GP9_OP_CFG_SHIFT 9 /* GP9_OP_CFG */
-#define WM8995_GP9_OP_CFG_WIDTH 1 /* GP9_OP_CFG */
-#define WM8995_GP9_DB 0x0100 /* GP9_DB */
-#define WM8995_GP9_DB_MASK 0x0100 /* GP9_DB */
-#define WM8995_GP9_DB_SHIFT 8 /* GP9_DB */
-#define WM8995_GP9_DB_WIDTH 1 /* GP9_DB */
-#define WM8995_GP9_LVL 0x0040 /* GP9_LVL */
-#define WM8995_GP9_LVL_MASK 0x0040 /* GP9_LVL */
-#define WM8995_GP9_LVL_SHIFT 6 /* GP9_LVL */
-#define WM8995_GP9_LVL_WIDTH 1 /* GP9_LVL */
-#define WM8995_GP9_FN_MASK 0x001F /* GP9_FN - [4:0] */
-#define WM8995_GP9_FN_SHIFT 0 /* GP9_FN - [4:0] */
-#define WM8995_GP9_FN_WIDTH 5 /* GP9_FN - [4:0] */
-
-/*
- * R1801 (0x709) - GPIO 10
- */
-#define WM8995_GP10_DIR 0x8000 /* GP10_DIR */
-#define WM8995_GP10_DIR_MASK 0x8000 /* GP10_DIR */
-#define WM8995_GP10_DIR_SHIFT 15 /* GP10_DIR */
-#define WM8995_GP10_DIR_WIDTH 1 /* GP10_DIR */
-#define WM8995_GP10_PU 0x4000 /* GP10_PU */
-#define WM8995_GP10_PU_MASK 0x4000 /* GP10_PU */
-#define WM8995_GP10_PU_SHIFT 14 /* GP10_PU */
-#define WM8995_GP10_PU_WIDTH 1 /* GP10_PU */
-#define WM8995_GP10_PD 0x2000 /* GP10_PD */
-#define WM8995_GP10_PD_MASK 0x2000 /* GP10_PD */
-#define WM8995_GP10_PD_SHIFT 13 /* GP10_PD */
-#define WM8995_GP10_PD_WIDTH 1 /* GP10_PD */
-#define WM8995_GP10_POL 0x0400 /* GP10_POL */
-#define WM8995_GP10_POL_MASK 0x0400 /* GP10_POL */
-#define WM8995_GP10_POL_SHIFT 10 /* GP10_POL */
-#define WM8995_GP10_POL_WIDTH 1 /* GP10_POL */
-#define WM8995_GP10_OP_CFG 0x0200 /* GP10_OP_CFG */
-#define WM8995_GP10_OP_CFG_MASK 0x0200 /* GP10_OP_CFG */
-#define WM8995_GP10_OP_CFG_SHIFT 9 /* GP10_OP_CFG */
-#define WM8995_GP10_OP_CFG_WIDTH 1 /* GP10_OP_CFG */
-#define WM8995_GP10_DB 0x0100 /* GP10_DB */
-#define WM8995_GP10_DB_MASK 0x0100 /* GP10_DB */
-#define WM8995_GP10_DB_SHIFT 8 /* GP10_DB */
-#define WM8995_GP10_DB_WIDTH 1 /* GP10_DB */
-#define WM8995_GP10_LVL 0x0040 /* GP10_LVL */
-#define WM8995_GP10_LVL_MASK 0x0040 /* GP10_LVL */
-#define WM8995_GP10_LVL_SHIFT 6 /* GP10_LVL */
-#define WM8995_GP10_LVL_WIDTH 1 /* GP10_LVL */
-#define WM8995_GP10_FN_MASK 0x001F /* GP10_FN - [4:0] */
-#define WM8995_GP10_FN_SHIFT 0 /* GP10_FN - [4:0] */
-#define WM8995_GP10_FN_WIDTH 5 /* GP10_FN - [4:0] */
-
-/*
- * R1802 (0x70A) - GPIO 11
- */
-#define WM8995_GP11_DIR 0x8000 /* GP11_DIR */
-#define WM8995_GP11_DIR_MASK 0x8000 /* GP11_DIR */
-#define WM8995_GP11_DIR_SHIFT 15 /* GP11_DIR */
-#define WM8995_GP11_DIR_WIDTH 1 /* GP11_DIR */
-#define WM8995_GP11_PU 0x4000 /* GP11_PU */
-#define WM8995_GP11_PU_MASK 0x4000 /* GP11_PU */
-#define WM8995_GP11_PU_SHIFT 14 /* GP11_PU */
-#define WM8995_GP11_PU_WIDTH 1 /* GP11_PU */
-#define WM8995_GP11_PD 0x2000 /* GP11_PD */
-#define WM8995_GP11_PD_MASK 0x2000 /* GP11_PD */
-#define WM8995_GP11_PD_SHIFT 13 /* GP11_PD */
-#define WM8995_GP11_PD_WIDTH 1 /* GP11_PD */
-#define WM8995_GP11_POL 0x0400 /* GP11_POL */
-#define WM8995_GP11_POL_MASK 0x0400 /* GP11_POL */
-#define WM8995_GP11_POL_SHIFT 10 /* GP11_POL */
-#define WM8995_GP11_POL_WIDTH 1 /* GP11_POL */
-#define WM8995_GP11_OP_CFG 0x0200 /* GP11_OP_CFG */
-#define WM8995_GP11_OP_CFG_MASK 0x0200 /* GP11_OP_CFG */
-#define WM8995_GP11_OP_CFG_SHIFT 9 /* GP11_OP_CFG */
-#define WM8995_GP11_OP_CFG_WIDTH 1 /* GP11_OP_CFG */
-#define WM8995_GP11_DB 0x0100 /* GP11_DB */
-#define WM8995_GP11_DB_MASK 0x0100 /* GP11_DB */
-#define WM8995_GP11_DB_SHIFT 8 /* GP11_DB */
-#define WM8995_GP11_DB_WIDTH 1 /* GP11_DB */
-#define WM8995_GP11_LVL 0x0040 /* GP11_LVL */
-#define WM8995_GP11_LVL_MASK 0x0040 /* GP11_LVL */
-#define WM8995_GP11_LVL_SHIFT 6 /* GP11_LVL */
-#define WM8995_GP11_LVL_WIDTH 1 /* GP11_LVL */
-#define WM8995_GP11_FN_MASK 0x001F /* GP11_FN - [4:0] */
-#define WM8995_GP11_FN_SHIFT 0 /* GP11_FN - [4:0] */
-#define WM8995_GP11_FN_WIDTH 5 /* GP11_FN - [4:0] */
-
-/*
- * R1803 (0x70B) - GPIO 12
- */
-#define WM8995_GP12_DIR 0x8000 /* GP12_DIR */
-#define WM8995_GP12_DIR_MASK 0x8000 /* GP12_DIR */
-#define WM8995_GP12_DIR_SHIFT 15 /* GP12_DIR */
-#define WM8995_GP12_DIR_WIDTH 1 /* GP12_DIR */
-#define WM8995_GP12_PU 0x4000 /* GP12_PU */
-#define WM8995_GP12_PU_MASK 0x4000 /* GP12_PU */
-#define WM8995_GP12_PU_SHIFT 14 /* GP12_PU */
-#define WM8995_GP12_PU_WIDTH 1 /* GP12_PU */
-#define WM8995_GP12_PD 0x2000 /* GP12_PD */
-#define WM8995_GP12_PD_MASK 0x2000 /* GP12_PD */
-#define WM8995_GP12_PD_SHIFT 13 /* GP12_PD */
-#define WM8995_GP12_PD_WIDTH 1 /* GP12_PD */
-#define WM8995_GP12_POL 0x0400 /* GP12_POL */
-#define WM8995_GP12_POL_MASK 0x0400 /* GP12_POL */
-#define WM8995_GP12_POL_SHIFT 10 /* GP12_POL */
-#define WM8995_GP12_POL_WIDTH 1 /* GP12_POL */
-#define WM8995_GP12_OP_CFG 0x0200 /* GP12_OP_CFG */
-#define WM8995_GP12_OP_CFG_MASK 0x0200 /* GP12_OP_CFG */
-#define WM8995_GP12_OP_CFG_SHIFT 9 /* GP12_OP_CFG */
-#define WM8995_GP12_OP_CFG_WIDTH 1 /* GP12_OP_CFG */
-#define WM8995_GP12_DB 0x0100 /* GP12_DB */
-#define WM8995_GP12_DB_MASK 0x0100 /* GP12_DB */
-#define WM8995_GP12_DB_SHIFT 8 /* GP12_DB */
-#define WM8995_GP12_DB_WIDTH 1 /* GP12_DB */
-#define WM8995_GP12_LVL 0x0040 /* GP12_LVL */
-#define WM8995_GP12_LVL_MASK 0x0040 /* GP12_LVL */
-#define WM8995_GP12_LVL_SHIFT 6 /* GP12_LVL */
-#define WM8995_GP12_LVL_WIDTH 1 /* GP12_LVL */
-#define WM8995_GP12_FN_MASK 0x001F /* GP12_FN - [4:0] */
-#define WM8995_GP12_FN_SHIFT 0 /* GP12_FN - [4:0] */
-#define WM8995_GP12_FN_WIDTH 5 /* GP12_FN - [4:0] */
-
-/*
- * R1804 (0x70C) - GPIO 13
- */
-#define WM8995_GP13_DIR 0x8000 /* GP13_DIR */
-#define WM8995_GP13_DIR_MASK 0x8000 /* GP13_DIR */
-#define WM8995_GP13_DIR_SHIFT 15 /* GP13_DIR */
-#define WM8995_GP13_DIR_WIDTH 1 /* GP13_DIR */
-#define WM8995_GP13_PU 0x4000 /* GP13_PU */
-#define WM8995_GP13_PU_MASK 0x4000 /* GP13_PU */
-#define WM8995_GP13_PU_SHIFT 14 /* GP13_PU */
-#define WM8995_GP13_PU_WIDTH 1 /* GP13_PU */
-#define WM8995_GP13_PD 0x2000 /* GP13_PD */
-#define WM8995_GP13_PD_MASK 0x2000 /* GP13_PD */
-#define WM8995_GP13_PD_SHIFT 13 /* GP13_PD */
-#define WM8995_GP13_PD_WIDTH 1 /* GP13_PD */
-#define WM8995_GP13_POL 0x0400 /* GP13_POL */
-#define WM8995_GP13_POL_MASK 0x0400 /* GP13_POL */
-#define WM8995_GP13_POL_SHIFT 10 /* GP13_POL */
-#define WM8995_GP13_POL_WIDTH 1 /* GP13_POL */
-#define WM8995_GP13_OP_CFG 0x0200 /* GP13_OP_CFG */
-#define WM8995_GP13_OP_CFG_MASK 0x0200 /* GP13_OP_CFG */
-#define WM8995_GP13_OP_CFG_SHIFT 9 /* GP13_OP_CFG */
-#define WM8995_GP13_OP_CFG_WIDTH 1 /* GP13_OP_CFG */
-#define WM8995_GP13_DB 0x0100 /* GP13_DB */
-#define WM8995_GP13_DB_MASK 0x0100 /* GP13_DB */
-#define WM8995_GP13_DB_SHIFT 8 /* GP13_DB */
-#define WM8995_GP13_DB_WIDTH 1 /* GP13_DB */
-#define WM8995_GP13_LVL 0x0040 /* GP13_LVL */
-#define WM8995_GP13_LVL_MASK 0x0040 /* GP13_LVL */
-#define WM8995_GP13_LVL_SHIFT 6 /* GP13_LVL */
-#define WM8995_GP13_LVL_WIDTH 1 /* GP13_LVL */
-#define WM8995_GP13_FN_MASK 0x001F /* GP13_FN - [4:0] */
-#define WM8995_GP13_FN_SHIFT 0 /* GP13_FN - [4:0] */
-#define WM8995_GP13_FN_WIDTH 5 /* GP13_FN - [4:0] */
-
-/*
- * R1805 (0x70D) - GPIO 14
- */
-#define WM8995_GP14_DIR 0x8000 /* GP14_DIR */
-#define WM8995_GP14_DIR_MASK 0x8000 /* GP14_DIR */
-#define WM8995_GP14_DIR_SHIFT 15 /* GP14_DIR */
-#define WM8995_GP14_DIR_WIDTH 1 /* GP14_DIR */
-#define WM8995_GP14_PU 0x4000 /* GP14_PU */
-#define WM8995_GP14_PU_MASK 0x4000 /* GP14_PU */
-#define WM8995_GP14_PU_SHIFT 14 /* GP14_PU */
-#define WM8995_GP14_PU_WIDTH 1 /* GP14_PU */
-#define WM8995_GP14_PD 0x2000 /* GP14_PD */
-#define WM8995_GP14_PD_MASK 0x2000 /* GP14_PD */
-#define WM8995_GP14_PD_SHIFT 13 /* GP14_PD */
-#define WM8995_GP14_PD_WIDTH 1 /* GP14_PD */
-#define WM8995_GP14_POL 0x0400 /* GP14_POL */
-#define WM8995_GP14_POL_MASK 0x0400 /* GP14_POL */
-#define WM8995_GP14_POL_SHIFT 10 /* GP14_POL */
-#define WM8995_GP14_POL_WIDTH 1 /* GP14_POL */
-#define WM8995_GP14_OP_CFG 0x0200 /* GP14_OP_CFG */
-#define WM8995_GP14_OP_CFG_MASK 0x0200 /* GP14_OP_CFG */
-#define WM8995_GP14_OP_CFG_SHIFT 9 /* GP14_OP_CFG */
-#define WM8995_GP14_OP_CFG_WIDTH 1 /* GP14_OP_CFG */
-#define WM8995_GP14_DB 0x0100 /* GP14_DB */
-#define WM8995_GP14_DB_MASK 0x0100 /* GP14_DB */
-#define WM8995_GP14_DB_SHIFT 8 /* GP14_DB */
-#define WM8995_GP14_DB_WIDTH 1 /* GP14_DB */
-#define WM8995_GP14_LVL 0x0040 /* GP14_LVL */
-#define WM8995_GP14_LVL_MASK 0x0040 /* GP14_LVL */
-#define WM8995_GP14_LVL_SHIFT 6 /* GP14_LVL */
-#define WM8995_GP14_LVL_WIDTH 1 /* GP14_LVL */
-#define WM8995_GP14_FN_MASK 0x001F /* GP14_FN - [4:0] */
-#define WM8995_GP14_FN_SHIFT 0 /* GP14_FN - [4:0] */
-#define WM8995_GP14_FN_WIDTH 5 /* GP14_FN - [4:0] */
-
-/*
- * R1824 (0x720) - Pull Control (1)
- */
-#define WM8995_DMICDAT3_PD 0x4000 /* DMICDAT3_PD */
-#define WM8995_DMICDAT3_PD_MASK 0x4000 /* DMICDAT3_PD */
-#define WM8995_DMICDAT3_PD_SHIFT 14 /* DMICDAT3_PD */
-#define WM8995_DMICDAT3_PD_WIDTH 1 /* DMICDAT3_PD */
-#define WM8995_DMICDAT2_PD 0x1000 /* DMICDAT2_PD */
-#define WM8995_DMICDAT2_PD_MASK 0x1000 /* DMICDAT2_PD */
-#define WM8995_DMICDAT2_PD_SHIFT 12 /* DMICDAT2_PD */
-#define WM8995_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */
-#define WM8995_DMICDAT1_PD 0x0400 /* DMICDAT1_PD */
-#define WM8995_DMICDAT1_PD_MASK 0x0400 /* DMICDAT1_PD */
-#define WM8995_DMICDAT1_PD_SHIFT 10 /* DMICDAT1_PD */
-#define WM8995_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */
-#define WM8995_MCLK2_PU 0x0200 /* MCLK2_PU */
-#define WM8995_MCLK2_PU_MASK 0x0200 /* MCLK2_PU */
-#define WM8995_MCLK2_PU_SHIFT 9 /* MCLK2_PU */
-#define WM8995_MCLK2_PU_WIDTH 1 /* MCLK2_PU */
-#define WM8995_MCLK2_PD 0x0100 /* MCLK2_PD */
-#define WM8995_MCLK2_PD_MASK 0x0100 /* MCLK2_PD */
-#define WM8995_MCLK2_PD_SHIFT 8 /* MCLK2_PD */
-#define WM8995_MCLK2_PD_WIDTH 1 /* MCLK2_PD */
-#define WM8995_MCLK1_PU 0x0080 /* MCLK1_PU */
-#define WM8995_MCLK1_PU_MASK 0x0080 /* MCLK1_PU */
-#define WM8995_MCLK1_PU_SHIFT 7 /* MCLK1_PU */
-#define WM8995_MCLK1_PU_WIDTH 1 /* MCLK1_PU */
-#define WM8995_MCLK1_PD 0x0040 /* MCLK1_PD */
-#define WM8995_MCLK1_PD_MASK 0x0040 /* MCLK1_PD */
-#define WM8995_MCLK1_PD_SHIFT 6 /* MCLK1_PD */
-#define WM8995_MCLK1_PD_WIDTH 1 /* MCLK1_PD */
-#define WM8995_DACDAT1_PU 0x0020 /* DACDAT1_PU */
-#define WM8995_DACDAT1_PU_MASK 0x0020 /* DACDAT1_PU */
-#define WM8995_DACDAT1_PU_SHIFT 5 /* DACDAT1_PU */
-#define WM8995_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */
-#define WM8995_DACDAT1_PD 0x0010 /* DACDAT1_PD */
-#define WM8995_DACDAT1_PD_MASK 0x0010 /* DACDAT1_PD */
-#define WM8995_DACDAT1_PD_SHIFT 4 /* DACDAT1_PD */
-#define WM8995_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */
-#define WM8995_DACLRCLK1_PU 0x0008 /* DACLRCLK1_PU */
-#define WM8995_DACLRCLK1_PU_MASK 0x0008 /* DACLRCLK1_PU */
-#define WM8995_DACLRCLK1_PU_SHIFT 3 /* DACLRCLK1_PU */
-#define WM8995_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */
-#define WM8995_DACLRCLK1_PD 0x0004 /* DACLRCLK1_PD */
-#define WM8995_DACLRCLK1_PD_MASK 0x0004 /* DACLRCLK1_PD */
-#define WM8995_DACLRCLK1_PD_SHIFT 2 /* DACLRCLK1_PD */
-#define WM8995_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */
-#define WM8995_BCLK1_PU 0x0002 /* BCLK1_PU */
-#define WM8995_BCLK1_PU_MASK 0x0002 /* BCLK1_PU */
-#define WM8995_BCLK1_PU_SHIFT 1 /* BCLK1_PU */
-#define WM8995_BCLK1_PU_WIDTH 1 /* BCLK1_PU */
-#define WM8995_BCLK1_PD 0x0001 /* BCLK1_PD */
-#define WM8995_BCLK1_PD_MASK 0x0001 /* BCLK1_PD */
-#define WM8995_BCLK1_PD_SHIFT 0 /* BCLK1_PD */
-#define WM8995_BCLK1_PD_WIDTH 1 /* BCLK1_PD */
-
-/*
- * R1825 (0x721) - Pull Control (2)
- */
-#define WM8995_LDO1ENA_PD 0x0010 /* LDO1ENA_PD */
-#define WM8995_LDO1ENA_PD_MASK 0x0010 /* LDO1ENA_PD */
-#define WM8995_LDO1ENA_PD_SHIFT 4 /* LDO1ENA_PD */
-#define WM8995_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */
-#define WM8995_MODE_PD 0x0004 /* MODE_PD */
-#define WM8995_MODE_PD_MASK 0x0004 /* MODE_PD */
-#define WM8995_MODE_PD_SHIFT 2 /* MODE_PD */
-#define WM8995_MODE_PD_WIDTH 1 /* MODE_PD */
-#define WM8995_CSNADDR_PD 0x0001 /* CSNADDR_PD */
-#define WM8995_CSNADDR_PD_MASK 0x0001 /* CSNADDR_PD */
-#define WM8995_CSNADDR_PD_SHIFT 0 /* CSNADDR_PD */
-#define WM8995_CSNADDR_PD_WIDTH 1 /* CSNADDR_PD */
-
-/*
- * R1840 (0x730) - Interrupt Status 1
- */
-#define WM8995_GP14_EINT 0x2000 /* GP14_EINT */
-#define WM8995_GP14_EINT_MASK 0x2000 /* GP14_EINT */
-#define WM8995_GP14_EINT_SHIFT 13 /* GP14_EINT */
-#define WM8995_GP14_EINT_WIDTH 1 /* GP14_EINT */
-#define WM8995_GP13_EINT 0x1000 /* GP13_EINT */
-#define WM8995_GP13_EINT_MASK 0x1000 /* GP13_EINT */
-#define WM8995_GP13_EINT_SHIFT 12 /* GP13_EINT */
-#define WM8995_GP13_EINT_WIDTH 1 /* GP13_EINT */
-#define WM8995_GP12_EINT 0x0800 /* GP12_EINT */
-#define WM8995_GP12_EINT_MASK 0x0800 /* GP12_EINT */
-#define WM8995_GP12_EINT_SHIFT 11 /* GP12_EINT */
-#define WM8995_GP12_EINT_WIDTH 1 /* GP12_EINT */
-#define WM8995_GP11_EINT 0x0400 /* GP11_EINT */
-#define WM8995_GP11_EINT_MASK 0x0400 /* GP11_EINT */
-#define WM8995_GP11_EINT_SHIFT 10 /* GP11_EINT */
-#define WM8995_GP11_EINT_WIDTH 1 /* GP11_EINT */
-#define WM8995_GP10_EINT 0x0200 /* GP10_EINT */
-#define WM8995_GP10_EINT_MASK 0x0200 /* GP10_EINT */
-#define WM8995_GP10_EINT_SHIFT 9 /* GP10_EINT */
-#define WM8995_GP10_EINT_WIDTH 1 /* GP10_EINT */
-#define WM8995_GP9_EINT 0x0100 /* GP9_EINT */
-#define WM8995_GP9_EINT_MASK 0x0100 /* GP9_EINT */
-#define WM8995_GP9_EINT_SHIFT 8 /* GP9_EINT */
-#define WM8995_GP9_EINT_WIDTH 1 /* GP9_EINT */
-#define WM8995_GP8_EINT 0x0080 /* GP8_EINT */
-#define WM8995_GP8_EINT_MASK 0x0080 /* GP8_EINT */
-#define WM8995_GP8_EINT_SHIFT 7 /* GP8_EINT */
-#define WM8995_GP8_EINT_WIDTH 1 /* GP8_EINT */
-#define WM8995_GP7_EINT 0x0040 /* GP7_EINT */
-#define WM8995_GP7_EINT_MASK 0x0040 /* GP7_EINT */
-#define WM8995_GP7_EINT_SHIFT 6 /* GP7_EINT */
-#define WM8995_GP7_EINT_WIDTH 1 /* GP7_EINT */
-#define WM8995_GP6_EINT 0x0020 /* GP6_EINT */
-#define WM8995_GP6_EINT_MASK 0x0020 /* GP6_EINT */
-#define WM8995_GP6_EINT_SHIFT 5 /* GP6_EINT */
-#define WM8995_GP6_EINT_WIDTH 1 /* GP6_EINT */
-#define WM8995_GP5_EINT 0x0010 /* GP5_EINT */
-#define WM8995_GP5_EINT_MASK 0x0010 /* GP5_EINT */
-#define WM8995_GP5_EINT_SHIFT 4 /* GP5_EINT */
-#define WM8995_GP5_EINT_WIDTH 1 /* GP5_EINT */
-#define WM8995_GP4_EINT 0x0008 /* GP4_EINT */
-#define WM8995_GP4_EINT_MASK 0x0008 /* GP4_EINT */
-#define WM8995_GP4_EINT_SHIFT 3 /* GP4_EINT */
-#define WM8995_GP4_EINT_WIDTH 1 /* GP4_EINT */
-#define WM8995_GP3_EINT 0x0004 /* GP3_EINT */
-#define WM8995_GP3_EINT_MASK 0x0004 /* GP3_EINT */
-#define WM8995_GP3_EINT_SHIFT 2 /* GP3_EINT */
-#define WM8995_GP3_EINT_WIDTH 1 /* GP3_EINT */
-#define WM8995_GP2_EINT 0x0002 /* GP2_EINT */
-#define WM8995_GP2_EINT_MASK 0x0002 /* GP2_EINT */
-#define WM8995_GP2_EINT_SHIFT 1 /* GP2_EINT */
-#define WM8995_GP2_EINT_WIDTH 1 /* GP2_EINT */
-#define WM8995_GP1_EINT 0x0001 /* GP1_EINT */
-#define WM8995_GP1_EINT_MASK 0x0001 /* GP1_EINT */
-#define WM8995_GP1_EINT_SHIFT 0 /* GP1_EINT */
-#define WM8995_GP1_EINT_WIDTH 1 /* GP1_EINT */
-
-/*
- * R1841 (0x731) - Interrupt Status 2
- */
-#define WM8995_DCS_DONE_23_EINT 0x1000 /* DCS_DONE_23_EINT */
-#define WM8995_DCS_DONE_23_EINT_MASK 0x1000 /* DCS_DONE_23_EINT */
-#define WM8995_DCS_DONE_23_EINT_SHIFT 12 /* DCS_DONE_23_EINT */
-#define WM8995_DCS_DONE_23_EINT_WIDTH 1 /* DCS_DONE_23_EINT */
-#define WM8995_DCS_DONE_01_EINT 0x0800 /* DCS_DONE_01_EINT */
-#define WM8995_DCS_DONE_01_EINT_MASK 0x0800 /* DCS_DONE_01_EINT */
-#define WM8995_DCS_DONE_01_EINT_SHIFT 11 /* DCS_DONE_01_EINT */
-#define WM8995_DCS_DONE_01_EINT_WIDTH 1 /* DCS_DONE_01_EINT */
-#define WM8995_WSEQ_DONE_EINT 0x0400 /* WSEQ_DONE_EINT */
-#define WM8995_WSEQ_DONE_EINT_MASK 0x0400 /* WSEQ_DONE_EINT */
-#define WM8995_WSEQ_DONE_EINT_SHIFT 10 /* WSEQ_DONE_EINT */
-#define WM8995_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */
-#define WM8995_FIFOS_ERR_EINT 0x0200 /* FIFOS_ERR_EINT */
-#define WM8995_FIFOS_ERR_EINT_MASK 0x0200 /* FIFOS_ERR_EINT */
-#define WM8995_FIFOS_ERR_EINT_SHIFT 9 /* FIFOS_ERR_EINT */
-#define WM8995_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */
-#define WM8995_AIF2DRC_SIG_DET_EINT 0x0100 /* AIF2DRC_SIG_DET_EINT */
-#define WM8995_AIF2DRC_SIG_DET_EINT_MASK 0x0100 /* AIF2DRC_SIG_DET_EINT */
-#define WM8995_AIF2DRC_SIG_DET_EINT_SHIFT 8 /* AIF2DRC_SIG_DET_EINT */
-#define WM8995_AIF2DRC_SIG_DET_EINT_WIDTH 1 /* AIF2DRC_SIG_DET_EINT */
-#define WM8995_AIF1DRC2_SIG_DET_EINT 0x0080 /* AIF1DRC2_SIG_DET_EINT */
-#define WM8995_AIF1DRC2_SIG_DET_EINT_MASK 0x0080 /* AIF1DRC2_SIG_DET_EINT */
-#define WM8995_AIF1DRC2_SIG_DET_EINT_SHIFT 7 /* AIF1DRC2_SIG_DET_EINT */
-#define WM8995_AIF1DRC2_SIG_DET_EINT_WIDTH 1 /* AIF1DRC2_SIG_DET_EINT */
-#define WM8995_AIF1DRC1_SIG_DET_EINT 0x0040 /* AIF1DRC1_SIG_DET_EINT */
-#define WM8995_AIF1DRC1_SIG_DET_EINT_MASK 0x0040 /* AIF1DRC1_SIG_DET_EINT */
-#define WM8995_AIF1DRC1_SIG_DET_EINT_SHIFT 6 /* AIF1DRC1_SIG_DET_EINT */
-#define WM8995_AIF1DRC1_SIG_DET_EINT_WIDTH 1 /* AIF1DRC1_SIG_DET_EINT */
-#define WM8995_SRC2_LOCK_EINT 0x0020 /* SRC2_LOCK_EINT */
-#define WM8995_SRC2_LOCK_EINT_MASK 0x0020 /* SRC2_LOCK_EINT */
-#define WM8995_SRC2_LOCK_EINT_SHIFT 5 /* SRC2_LOCK_EINT */
-#define WM8995_SRC2_LOCK_EINT_WIDTH 1 /* SRC2_LOCK_EINT */
-#define WM8995_SRC1_LOCK_EINT 0x0010 /* SRC1_LOCK_EINT */
-#define WM8995_SRC1_LOCK_EINT_MASK 0x0010 /* SRC1_LOCK_EINT */
-#define WM8995_SRC1_LOCK_EINT_SHIFT 4 /* SRC1_LOCK_EINT */
-#define WM8995_SRC1_LOCK_EINT_WIDTH 1 /* SRC1_LOCK_EINT */
-#define WM8995_FLL2_LOCK_EINT 0x0008 /* FLL2_LOCK_EINT */
-#define WM8995_FLL2_LOCK_EINT_MASK 0x0008 /* FLL2_LOCK_EINT */
-#define WM8995_FLL2_LOCK_EINT_SHIFT 3 /* FLL2_LOCK_EINT */
-#define WM8995_FLL2_LOCK_EINT_WIDTH 1 /* FLL2_LOCK_EINT */
-#define WM8995_FLL1_LOCK_EINT 0x0004 /* FLL1_LOCK_EINT */
-#define WM8995_FLL1_LOCK_EINT_MASK 0x0004 /* FLL1_LOCK_EINT */
-#define WM8995_FLL1_LOCK_EINT_SHIFT 2 /* FLL1_LOCK_EINT */
-#define WM8995_FLL1_LOCK_EINT_WIDTH 1 /* FLL1_LOCK_EINT */
-#define WM8995_HP_DONE_EINT 0x0002 /* HP_DONE_EINT */
-#define WM8995_HP_DONE_EINT_MASK 0x0002 /* HP_DONE_EINT */
-#define WM8995_HP_DONE_EINT_SHIFT 1 /* HP_DONE_EINT */
-#define WM8995_HP_DONE_EINT_WIDTH 1 /* HP_DONE_EINT */
-#define WM8995_MICD_EINT 0x0001 /* MICD_EINT */
-#define WM8995_MICD_EINT_MASK 0x0001 /* MICD_EINT */
-#define WM8995_MICD_EINT_SHIFT 0 /* MICD_EINT */
-#define WM8995_MICD_EINT_WIDTH 1 /* MICD_EINT */
-
-/*
- * R1842 (0x732) - Interrupt Raw Status 2
- */
-#define WM8995_DCS_DONE_23_STS 0x1000 /* DCS_DONE_23_STS */
-#define WM8995_DCS_DONE_23_STS_MASK 0x1000 /* DCS_DONE_23_STS */
-#define WM8995_DCS_DONE_23_STS_SHIFT 12 /* DCS_DONE_23_STS */
-#define WM8995_DCS_DONE_23_STS_WIDTH 1 /* DCS_DONE_23_STS */
-#define WM8995_DCS_DONE_01_STS 0x0800 /* DCS_DONE_01_STS */
-#define WM8995_DCS_DONE_01_STS_MASK 0x0800 /* DCS_DONE_01_STS */
-#define WM8995_DCS_DONE_01_STS_SHIFT 11 /* DCS_DONE_01_STS */
-#define WM8995_DCS_DONE_01_STS_WIDTH 1 /* DCS_DONE_01_STS */
-#define WM8995_WSEQ_DONE_STS 0x0400 /* WSEQ_DONE_STS */
-#define WM8995_WSEQ_DONE_STS_MASK 0x0400 /* WSEQ_DONE_STS */
-#define WM8995_WSEQ_DONE_STS_SHIFT 10 /* WSEQ_DONE_STS */
-#define WM8995_WSEQ_DONE_STS_WIDTH 1 /* WSEQ_DONE_STS */
-#define WM8995_FIFOS_ERR_STS 0x0200 /* FIFOS_ERR_STS */
-#define WM8995_FIFOS_ERR_STS_MASK 0x0200 /* FIFOS_ERR_STS */
-#define WM8995_FIFOS_ERR_STS_SHIFT 9 /* FIFOS_ERR_STS */
-#define WM8995_FIFOS_ERR_STS_WIDTH 1 /* FIFOS_ERR_STS */
-#define WM8995_AIF2DRC_SIG_DET_STS 0x0100 /* AIF2DRC_SIG_DET_STS */
-#define WM8995_AIF2DRC_SIG_DET_STS_MASK 0x0100 /* AIF2DRC_SIG_DET_STS */
-#define WM8995_AIF2DRC_SIG_DET_STS_SHIFT 8 /* AIF2DRC_SIG_DET_STS */
-#define WM8995_AIF2DRC_SIG_DET_STS_WIDTH 1 /* AIF2DRC_SIG_DET_STS */
-#define WM8995_AIF1DRC2_SIG_DET_STS 0x0080 /* AIF1DRC2_SIG_DET_STS */
-#define WM8995_AIF1DRC2_SIG_DET_STS_MASK 0x0080 /* AIF1DRC2_SIG_DET_STS */
-#define WM8995_AIF1DRC2_SIG_DET_STS_SHIFT 7 /* AIF1DRC2_SIG_DET_STS */
-#define WM8995_AIF1DRC2_SIG_DET_STS_WIDTH 1 /* AIF1DRC2_SIG_DET_STS */
-#define WM8995_AIF1DRC1_SIG_DET_STS 0x0040 /* AIF1DRC1_SIG_DET_STS */
-#define WM8995_AIF1DRC1_SIG_DET_STS_MASK 0x0040 /* AIF1DRC1_SIG_DET_STS */
-#define WM8995_AIF1DRC1_SIG_DET_STS_SHIFT 6 /* AIF1DRC1_SIG_DET_STS */
-#define WM8995_AIF1DRC1_SIG_DET_STS_WIDTH 1 /* AIF1DRC1_SIG_DET_STS */
-#define WM8995_SRC2_LOCK_STS 0x0020 /* SRC2_LOCK_STS */
-#define WM8995_SRC2_LOCK_STS_MASK 0x0020 /* SRC2_LOCK_STS */
-#define WM8995_SRC2_LOCK_STS_SHIFT 5 /* SRC2_LOCK_STS */
-#define WM8995_SRC2_LOCK_STS_WIDTH 1 /* SRC2_LOCK_STS */
-#define WM8995_SRC1_LOCK_STS 0x0010 /* SRC1_LOCK_STS */
-#define WM8995_SRC1_LOCK_STS_MASK 0x0010 /* SRC1_LOCK_STS */
-#define WM8995_SRC1_LOCK_STS_SHIFT 4 /* SRC1_LOCK_STS */
-#define WM8995_SRC1_LOCK_STS_WIDTH 1 /* SRC1_LOCK_STS */
-#define WM8995_FLL2_LOCK_STS 0x0008 /* FLL2_LOCK_STS */
-#define WM8995_FLL2_LOCK_STS_MASK 0x0008 /* FLL2_LOCK_STS */
-#define WM8995_FLL2_LOCK_STS_SHIFT 3 /* FLL2_LOCK_STS */
-#define WM8995_FLL2_LOCK_STS_WIDTH 1 /* FLL2_LOCK_STS */
-#define WM8995_FLL1_LOCK_STS 0x0004 /* FLL1_LOCK_STS */
-#define WM8995_FLL1_LOCK_STS_MASK 0x0004 /* FLL1_LOCK_STS */
-#define WM8995_FLL1_LOCK_STS_SHIFT 2 /* FLL1_LOCK_STS */
-#define WM8995_FLL1_LOCK_STS_WIDTH 1 /* FLL1_LOCK_STS */
-
-/*
- * R1848 (0x738) - Interrupt Status 1 Mask
- */
-#define WM8995_IM_GP14_EINT 0x2000 /* IM_GP14_EINT */
-#define WM8995_IM_GP14_EINT_MASK 0x2000 /* IM_GP14_EINT */
-#define WM8995_IM_GP14_EINT_SHIFT 13 /* IM_GP14_EINT */
-#define WM8995_IM_GP14_EINT_WIDTH 1 /* IM_GP14_EINT */
-#define WM8995_IM_GP13_EINT 0x1000 /* IM_GP13_EINT */
-#define WM8995_IM_GP13_EINT_MASK 0x1000 /* IM_GP13_EINT */
-#define WM8995_IM_GP13_EINT_SHIFT 12 /* IM_GP13_EINT */
-#define WM8995_IM_GP13_EINT_WIDTH 1 /* IM_GP13_EINT */
-#define WM8995_IM_GP12_EINT 0x0800 /* IM_GP12_EINT */
-#define WM8995_IM_GP12_EINT_MASK 0x0800 /* IM_GP12_EINT */
-#define WM8995_IM_GP12_EINT_SHIFT 11 /* IM_GP12_EINT */
-#define WM8995_IM_GP12_EINT_WIDTH 1 /* IM_GP12_EINT */
-#define WM8995_IM_GP11_EINT 0x0400 /* IM_GP11_EINT */
-#define WM8995_IM_GP11_EINT_MASK 0x0400 /* IM_GP11_EINT */
-#define WM8995_IM_GP11_EINT_SHIFT 10 /* IM_GP11_EINT */
-#define WM8995_IM_GP11_EINT_WIDTH 1 /* IM_GP11_EINT */
-#define WM8995_IM_GP10_EINT 0x0200 /* IM_GP10_EINT */
-#define WM8995_IM_GP10_EINT_MASK 0x0200 /* IM_GP10_EINT */
-#define WM8995_IM_GP10_EINT_SHIFT 9 /* IM_GP10_EINT */
-#define WM8995_IM_GP10_EINT_WIDTH 1 /* IM_GP10_EINT */
-#define WM8995_IM_GP9_EINT 0x0100 /* IM_GP9_EINT */
-#define WM8995_IM_GP9_EINT_MASK 0x0100 /* IM_GP9_EINT */
-#define WM8995_IM_GP9_EINT_SHIFT 8 /* IM_GP9_EINT */
-#define WM8995_IM_GP9_EINT_WIDTH 1 /* IM_GP9_EINT */
-#define WM8995_IM_GP8_EINT 0x0080 /* IM_GP8_EINT */
-#define WM8995_IM_GP8_EINT_MASK 0x0080 /* IM_GP8_EINT */
-#define WM8995_IM_GP8_EINT_SHIFT 7 /* IM_GP8_EINT */
-#define WM8995_IM_GP8_EINT_WIDTH 1 /* IM_GP8_EINT */
-#define WM8995_IM_GP7_EINT 0x0040 /* IM_GP7_EINT */
-#define WM8995_IM_GP7_EINT_MASK 0x0040 /* IM_GP7_EINT */
-#define WM8995_IM_GP7_EINT_SHIFT 6 /* IM_GP7_EINT */
-#define WM8995_IM_GP7_EINT_WIDTH 1 /* IM_GP7_EINT */
-#define WM8995_IM_GP6_EINT 0x0020 /* IM_GP6_EINT */
-#define WM8995_IM_GP6_EINT_MASK 0x0020 /* IM_GP6_EINT */
-#define WM8995_IM_GP6_EINT_SHIFT 5 /* IM_GP6_EINT */
-#define WM8995_IM_GP6_EINT_WIDTH 1 /* IM_GP6_EINT */
-#define WM8995_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
-#define WM8995_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
-#define WM8995_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
-#define WM8995_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
-#define WM8995_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
-#define WM8995_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
-#define WM8995_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
-#define WM8995_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
-#define WM8995_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
-#define WM8995_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
-#define WM8995_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
-#define WM8995_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
-#define WM8995_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
-#define WM8995_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
-#define WM8995_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
-#define WM8995_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
-#define WM8995_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
-#define WM8995_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
-#define WM8995_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
-#define WM8995_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
-
-/*
- * R1849 (0x739) - Interrupt Status 2 Mask
- */
-#define WM8995_IM_DCS_DONE_23_EINT 0x1000 /* IM_DCS_DONE_23_EINT */
-#define WM8995_IM_DCS_DONE_23_EINT_MASK 0x1000 /* IM_DCS_DONE_23_EINT */
-#define WM8995_IM_DCS_DONE_23_EINT_SHIFT 12 /* IM_DCS_DONE_23_EINT */
-#define WM8995_IM_DCS_DONE_23_EINT_WIDTH 1 /* IM_DCS_DONE_23_EINT */
-#define WM8995_IM_DCS_DONE_01_EINT 0x0800 /* IM_DCS_DONE_01_EINT */
-#define WM8995_IM_DCS_DONE_01_EINT_MASK 0x0800 /* IM_DCS_DONE_01_EINT */
-#define WM8995_IM_DCS_DONE_01_EINT_SHIFT 11 /* IM_DCS_DONE_01_EINT */
-#define WM8995_IM_DCS_DONE_01_EINT_WIDTH 1 /* IM_DCS_DONE_01_EINT */
-#define WM8995_IM_WSEQ_DONE_EINT 0x0400 /* IM_WSEQ_DONE_EINT */
-#define WM8995_IM_WSEQ_DONE_EINT_MASK 0x0400 /* IM_WSEQ_DONE_EINT */
-#define WM8995_IM_WSEQ_DONE_EINT_SHIFT 10 /* IM_WSEQ_DONE_EINT */
-#define WM8995_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */
-#define WM8995_IM_FIFOS_ERR_EINT 0x0200 /* IM_FIFOS_ERR_EINT */
-#define WM8995_IM_FIFOS_ERR_EINT_MASK 0x0200 /* IM_FIFOS_ERR_EINT */
-#define WM8995_IM_FIFOS_ERR_EINT_SHIFT 9 /* IM_FIFOS_ERR_EINT */
-#define WM8995_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */
-#define WM8995_IM_AIF2DRC_SIG_DET_EINT 0x0100 /* IM_AIF2DRC_SIG_DET_EINT */
-#define WM8995_IM_AIF2DRC_SIG_DET_EINT_MASK 0x0100 /* IM_AIF2DRC_SIG_DET_EINT */
-#define WM8995_IM_AIF2DRC_SIG_DET_EINT_SHIFT 8 /* IM_AIF2DRC_SIG_DET_EINT */
-#define WM8995_IM_AIF2DRC_SIG_DET_EINT_WIDTH 1 /* IM_AIF2DRC_SIG_DET_EINT */
-#define WM8995_IM_AIF1DRC2_SIG_DET_EINT 0x0080 /* IM_AIF1DRC2_SIG_DET_EINT */
-#define WM8995_IM_AIF1DRC2_SIG_DET_EINT_MASK 0x0080 /* IM_AIF1DRC2_SIG_DET_EINT */
-#define WM8995_IM_AIF1DRC2_SIG_DET_EINT_SHIFT 7 /* IM_AIF1DRC2_SIG_DET_EINT */
-#define WM8995_IM_AIF1DRC2_SIG_DET_EINT_WIDTH 1 /* IM_AIF1DRC2_SIG_DET_EINT */
-#define WM8995_IM_AIF1DRC1_SIG_DET_EINT 0x0040 /* IM_AIF1DRC1_SIG_DET_EINT */
-#define WM8995_IM_AIF1DRC1_SIG_DET_EINT_MASK 0x0040 /* IM_AIF1DRC1_SIG_DET_EINT */
-#define WM8995_IM_AIF1DRC1_SIG_DET_EINT_SHIFT 6 /* IM_AIF1DRC1_SIG_DET_EINT */
-#define WM8995_IM_AIF1DRC1_SIG_DET_EINT_WIDTH 1 /* IM_AIF1DRC1_SIG_DET_EINT */
-#define WM8995_IM_SRC2_LOCK_EINT 0x0020 /* IM_SRC2_LOCK_EINT */
-#define WM8995_IM_SRC2_LOCK_EINT_MASK 0x0020 /* IM_SRC2_LOCK_EINT */
-#define WM8995_IM_SRC2_LOCK_EINT_SHIFT 5 /* IM_SRC2_LOCK_EINT */
-#define WM8995_IM_SRC2_LOCK_EINT_WIDTH 1 /* IM_SRC2_LOCK_EINT */
-#define WM8995_IM_SRC1_LOCK_EINT 0x0010 /* IM_SRC1_LOCK_EINT */
-#define WM8995_IM_SRC1_LOCK_EINT_MASK 0x0010 /* IM_SRC1_LOCK_EINT */
-#define WM8995_IM_SRC1_LOCK_EINT_SHIFT 4 /* IM_SRC1_LOCK_EINT */
-#define WM8995_IM_SRC1_LOCK_EINT_WIDTH 1 /* IM_SRC1_LOCK_EINT */
-#define WM8995_IM_FLL2_LOCK_EINT 0x0008 /* IM_FLL2_LOCK_EINT */
-#define WM8995_IM_FLL2_LOCK_EINT_MASK 0x0008 /* IM_FLL2_LOCK_EINT */
-#define WM8995_IM_FLL2_LOCK_EINT_SHIFT 3 /* IM_FLL2_LOCK_EINT */
-#define WM8995_IM_FLL2_LOCK_EINT_WIDTH 1 /* IM_FLL2_LOCK_EINT */
-#define WM8995_IM_FLL1_LOCK_EINT 0x0004 /* IM_FLL1_LOCK_EINT */
-#define WM8995_IM_FLL1_LOCK_EINT_MASK 0x0004 /* IM_FLL1_LOCK_EINT */
-#define WM8995_IM_FLL1_LOCK_EINT_SHIFT 2 /* IM_FLL1_LOCK_EINT */
-#define WM8995_IM_FLL1_LOCK_EINT_WIDTH 1 /* IM_FLL1_LOCK_EINT */
-#define WM8995_IM_HP_DONE_EINT 0x0002 /* IM_HP_DONE_EINT */
-#define WM8995_IM_HP_DONE_EINT_MASK 0x0002 /* IM_HP_DONE_EINT */
-#define WM8995_IM_HP_DONE_EINT_SHIFT 1 /* IM_HP_DONE_EINT */
-#define WM8995_IM_HP_DONE_EINT_WIDTH 1 /* IM_HP_DONE_EINT */
-#define WM8995_IM_MICD_EINT 0x0001 /* IM_MICD_EINT */
-#define WM8995_IM_MICD_EINT_MASK 0x0001 /* IM_MICD_EINT */
-#define WM8995_IM_MICD_EINT_SHIFT 0 /* IM_MICD_EINT */
-#define WM8995_IM_MICD_EINT_WIDTH 1 /* IM_MICD_EINT */
-
-/*
- * R1856 (0x740) - Interrupt Control
- */
-#define WM8995_IM_IRQ 0x0001 /* IM_IRQ */
-#define WM8995_IM_IRQ_MASK 0x0001 /* IM_IRQ */
-#define WM8995_IM_IRQ_SHIFT 0 /* IM_IRQ */
-#define WM8995_IM_IRQ_WIDTH 1 /* IM_IRQ */
-
-/*
- * R2048 (0x800) - Left PDM Speaker 1
- */
-#define WM8995_SPK1L_ENA 0x0010 /* SPK1L_ENA */
-#define WM8995_SPK1L_ENA_MASK 0x0010 /* SPK1L_ENA */
-#define WM8995_SPK1L_ENA_SHIFT 4 /* SPK1L_ENA */
-#define WM8995_SPK1L_ENA_WIDTH 1 /* SPK1L_ENA */
-#define WM8995_SPK1L_MUTE 0x0008 /* SPK1L_MUTE */
-#define WM8995_SPK1L_MUTE_MASK 0x0008 /* SPK1L_MUTE */
-#define WM8995_SPK1L_MUTE_SHIFT 3 /* SPK1L_MUTE */
-#define WM8995_SPK1L_MUTE_WIDTH 1 /* SPK1L_MUTE */
-#define WM8995_SPK1L_MUTE_ZC 0x0004 /* SPK1L_MUTE_ZC */
-#define WM8995_SPK1L_MUTE_ZC_MASK 0x0004 /* SPK1L_MUTE_ZC */
-#define WM8995_SPK1L_MUTE_ZC_SHIFT 2 /* SPK1L_MUTE_ZC */
-#define WM8995_SPK1L_MUTE_ZC_WIDTH 1 /* SPK1L_MUTE_ZC */
-#define WM8995_SPK1L_SRC_MASK 0x0003 /* SPK1L_SRC - [1:0] */
-#define WM8995_SPK1L_SRC_SHIFT 0 /* SPK1L_SRC - [1:0] */
-#define WM8995_SPK1L_SRC_WIDTH 2 /* SPK1L_SRC - [1:0] */
-
-/*
- * R2049 (0x801) - Right PDM Speaker 1
- */
-#define WM8995_SPK1R_ENA 0x0010 /* SPK1R_ENA */
-#define WM8995_SPK1R_ENA_MASK 0x0010 /* SPK1R_ENA */
-#define WM8995_SPK1R_ENA_SHIFT 4 /* SPK1R_ENA */
-#define WM8995_SPK1R_ENA_WIDTH 1 /* SPK1R_ENA */
-#define WM8995_SPK1R_MUTE 0x0008 /* SPK1R_MUTE */
-#define WM8995_SPK1R_MUTE_MASK 0x0008 /* SPK1R_MUTE */
-#define WM8995_SPK1R_MUTE_SHIFT 3 /* SPK1R_MUTE */
-#define WM8995_SPK1R_MUTE_WIDTH 1 /* SPK1R_MUTE */
-#define WM8995_SPK1R_MUTE_ZC 0x0004 /* SPK1R_MUTE_ZC */
-#define WM8995_SPK1R_MUTE_ZC_MASK 0x0004 /* SPK1R_MUTE_ZC */
-#define WM8995_SPK1R_MUTE_ZC_SHIFT 2 /* SPK1R_MUTE_ZC */
-#define WM8995_SPK1R_MUTE_ZC_WIDTH 1 /* SPK1R_MUTE_ZC */
-#define WM8995_SPK1R_SRC_MASK 0x0003 /* SPK1R_SRC - [1:0] */
-#define WM8995_SPK1R_SRC_SHIFT 0 /* SPK1R_SRC - [1:0] */
-#define WM8995_SPK1R_SRC_WIDTH 2 /* SPK1R_SRC - [1:0] */
-
-/*
- * R2050 (0x802) - PDM Speaker 1 Mute Sequence
- */
-#define WM8995_SPK1_MUTE_SEQ1_MASK 0x00FF /* SPK1_MUTE_SEQ1 - [7:0] */
-#define WM8995_SPK1_MUTE_SEQ1_SHIFT 0 /* SPK1_MUTE_SEQ1 - [7:0] */
-#define WM8995_SPK1_MUTE_SEQ1_WIDTH 8 /* SPK1_MUTE_SEQ1 - [7:0] */
-
-/*
- * R2056 (0x808) - Left PDM Speaker 2
- */
-#define WM8995_SPK2L_ENA 0x0010 /* SPK2L_ENA */
-#define WM8995_SPK2L_ENA_MASK 0x0010 /* SPK2L_ENA */
-#define WM8995_SPK2L_ENA_SHIFT 4 /* SPK2L_ENA */
-#define WM8995_SPK2L_ENA_WIDTH 1 /* SPK2L_ENA */
-#define WM8995_SPK2L_MUTE 0x0008 /* SPK2L_MUTE */
-#define WM8995_SPK2L_MUTE_MASK 0x0008 /* SPK2L_MUTE */
-#define WM8995_SPK2L_MUTE_SHIFT 3 /* SPK2L_MUTE */
-#define WM8995_SPK2L_MUTE_WIDTH 1 /* SPK2L_MUTE */
-#define WM8995_SPK2L_MUTE_ZC 0x0004 /* SPK2L_MUTE_ZC */
-#define WM8995_SPK2L_MUTE_ZC_MASK 0x0004 /* SPK2L_MUTE_ZC */
-#define WM8995_SPK2L_MUTE_ZC_SHIFT 2 /* SPK2L_MUTE_ZC */
-#define WM8995_SPK2L_MUTE_ZC_WIDTH 1 /* SPK2L_MUTE_ZC */
-#define WM8995_SPK2L_SRC_MASK 0x0003 /* SPK2L_SRC - [1:0] */
-#define WM8995_SPK2L_SRC_SHIFT 0 /* SPK2L_SRC - [1:0] */
-#define WM8995_SPK2L_SRC_WIDTH 2 /* SPK2L_SRC - [1:0] */
-
-/*
- * R2057 (0x809) - Right PDM Speaker 2
- */
-#define WM8995_SPK2R_ENA 0x0010 /* SPK2R_ENA */
-#define WM8995_SPK2R_ENA_MASK 0x0010 /* SPK2R_ENA */
-#define WM8995_SPK2R_ENA_SHIFT 4 /* SPK2R_ENA */
-#define WM8995_SPK2R_ENA_WIDTH 1 /* SPK2R_ENA */
-#define WM8995_SPK2R_MUTE 0x0008 /* SPK2R_MUTE */
-#define WM8995_SPK2R_MUTE_MASK 0x0008 /* SPK2R_MUTE */
-#define WM8995_SPK2R_MUTE_SHIFT 3 /* SPK2R_MUTE */
-#define WM8995_SPK2R_MUTE_WIDTH 1 /* SPK2R_MUTE */
-#define WM8995_SPK2R_MUTE_ZC 0x0004 /* SPK2R_MUTE_ZC */
-#define WM8995_SPK2R_MUTE_ZC_MASK 0x0004 /* SPK2R_MUTE_ZC */
-#define WM8995_SPK2R_MUTE_ZC_SHIFT 2 /* SPK2R_MUTE_ZC */
-#define WM8995_SPK2R_MUTE_ZC_WIDTH 1 /* SPK2R_MUTE_ZC */
-#define WM8995_SPK2R_SRC_MASK 0x0003 /* SPK2R_SRC - [1:0] */
-#define WM8995_SPK2R_SRC_SHIFT 0 /* SPK2R_SRC - [1:0] */
-#define WM8995_SPK2R_SRC_WIDTH 2 /* SPK2R_SRC - [1:0] */
-
-/*
- * R2058 (0x80A) - PDM Speaker 2 Mute Sequence
- */
-#define WM8995_SPK2_MUTE_SEQ1_MASK 0x00FF /* SPK2_MUTE_SEQ1 - [7:0] */
-#define WM8995_SPK2_MUTE_SEQ1_SHIFT 0 /* SPK2_MUTE_SEQ1 - [7:0] */
-#define WM8995_SPK2_MUTE_SEQ1_WIDTH 8 /* SPK2_MUTE_SEQ1 - [7:0] */
-
-#define WM8995_CLASS_W_SWITCH(xname, reg, shift, max, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_soc_info_volsw, \
- .get = snd_soc_dapm_get_volsw, .put = wm8995_put_class_w, \
- .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) \
-}
-
-struct wm8995_reg_access {
- u16 read;
- u16 write;
- u16 vol;
-};
-
-/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */
-enum clk_src {
- WM8995_SYSCLK_MCLK1 = 1,
- WM8995_SYSCLK_MCLK2,
- WM8995_SYSCLK_FLL1,
- WM8995_SYSCLK_FLL2,
- WM8995_SYSCLK_OPCLK
-};
-
-#define WM8995_FLL1 1
-#define WM8995_FLL2 2
-
-#define WM8995_FLL_SRC_MCLK1 1
-#define WM8995_FLL_SRC_MCLK2 2
-#define WM8995_FLL_SRC_LRCLK 3
-#define WM8995_FLL_SRC_BCLK 4
-
-#endif /* _WM8995_H */
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8996.c b/ANDROID_3.4.5/sound/soc/codecs/wm8996.c
deleted file mode 100644
index 1fd63549..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8996.c
+++ /dev/null
@@ -1,3265 +0,0 @@
-/*
- * wm8996.c - WM8996 audio codec interface
- *
- * Copyright 2011 Wolfson Microelectronics PLC.
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/completion.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/gcd.h>
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-#include <linux/regmap.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <sound/core.h>
-#include <sound/jack.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <trace/events/asoc.h>
-
-#include <sound/wm8996.h>
-#include "wm8996.h"
-
-#define WM8996_AIFS 2
-
-#define HPOUT1L 1
-#define HPOUT1R 2
-#define HPOUT2L 4
-#define HPOUT2R 8
-
-#define WM8996_NUM_SUPPLIES 3
-static const char *wm8996_supply_names[WM8996_NUM_SUPPLIES] = {
- "DBVDD",
- "AVDD1",
- "AVDD2",
-};
-
-struct wm8996_priv {
- struct device *dev;
- struct regmap *regmap;
- struct snd_soc_codec *codec;
-
- int ldo1ena;
-
- int sysclk;
- int sysclk_src;
-
- int fll_src;
- int fll_fref;
- int fll_fout;
-
- struct completion fll_lock;
-
- u16 dcs_pending;
- struct completion dcs_done;
-
- u16 hpout_ena;
- u16 hpout_pending;
-
- struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES];
- struct notifier_block disable_nb[WM8996_NUM_SUPPLIES];
- int bg_ena;
-
- struct wm8996_pdata pdata;
-
- int rx_rate[WM8996_AIFS];
- int bclk_rate[WM8996_AIFS];
-
- /* Platform dependant ReTune mobile configuration */
- int num_retune_mobile_texts;
- const char **retune_mobile_texts;
- int retune_mobile_cfg[2];
- struct soc_enum retune_mobile_enum;
-
- struct snd_soc_jack *jack;
- bool detecting;
- bool jack_mic;
- int jack_flips;
- wm8996_polarity_fn polarity_cb;
-
-#ifdef CONFIG_GPIOLIB
- struct gpio_chip gpio_chip;
-#endif
-};
-
-/* We can't use the same notifier block for more than one supply and
- * there's no way I can see to get from a callback to the caller
- * except container_of().
- */
-#define WM8996_REGULATOR_EVENT(n) \
-static int wm8996_regulator_event_##n(struct notifier_block *nb, \
- unsigned long event, void *data) \
-{ \
- struct wm8996_priv *wm8996 = container_of(nb, struct wm8996_priv, \
- disable_nb[n]); \
- if (event & REGULATOR_EVENT_DISABLE) { \
- regcache_mark_dirty(wm8996->regmap); \
- } \
- return 0; \
-}
-
-WM8996_REGULATOR_EVENT(0)
-WM8996_REGULATOR_EVENT(1)
-WM8996_REGULATOR_EVENT(2)
-
-static struct reg_default wm8996_reg[] = {
- { WM8996_POWER_MANAGEMENT_1, 0x0 },
- { WM8996_POWER_MANAGEMENT_2, 0x0 },
- { WM8996_POWER_MANAGEMENT_3, 0x0 },
- { WM8996_POWER_MANAGEMENT_4, 0x0 },
- { WM8996_POWER_MANAGEMENT_5, 0x0 },
- { WM8996_POWER_MANAGEMENT_6, 0x0 },
- { WM8996_POWER_MANAGEMENT_7, 0x10 },
- { WM8996_POWER_MANAGEMENT_8, 0x0 },
- { WM8996_LEFT_LINE_INPUT_VOLUME, 0x0 },
- { WM8996_RIGHT_LINE_INPUT_VOLUME, 0x0 },
- { WM8996_LINE_INPUT_CONTROL, 0x0 },
- { WM8996_DAC1_HPOUT1_VOLUME, 0x88 },
- { WM8996_DAC2_HPOUT2_VOLUME, 0x88 },
- { WM8996_DAC1_LEFT_VOLUME, 0x2c0 },
- { WM8996_DAC1_RIGHT_VOLUME, 0x2c0 },
- { WM8996_DAC2_LEFT_VOLUME, 0x2c0 },
- { WM8996_DAC2_RIGHT_VOLUME, 0x2c0 },
- { WM8996_OUTPUT1_LEFT_VOLUME, 0x80 },
- { WM8996_OUTPUT1_RIGHT_VOLUME, 0x80 },
- { WM8996_OUTPUT2_LEFT_VOLUME, 0x80 },
- { WM8996_OUTPUT2_RIGHT_VOLUME, 0x80 },
- { WM8996_MICBIAS_1, 0x39 },
- { WM8996_MICBIAS_2, 0x39 },
- { WM8996_LDO_1, 0x3 },
- { WM8996_LDO_2, 0x13 },
- { WM8996_ACCESSORY_DETECT_MODE_1, 0x4 },
- { WM8996_ACCESSORY_DETECT_MODE_2, 0x0 },
- { WM8996_HEADPHONE_DETECT_1, 0x20 },
- { WM8996_HEADPHONE_DETECT_2, 0x0 },
- { WM8996_MIC_DETECT_1, 0x7600 },
- { WM8996_MIC_DETECT_2, 0xbf },
- { WM8996_CHARGE_PUMP_1, 0x1f25 },
- { WM8996_CHARGE_PUMP_2, 0xab19 },
- { WM8996_DC_SERVO_1, 0x0 },
- { WM8996_DC_SERVO_3, 0x0 },
- { WM8996_DC_SERVO_5, 0x2a2a },
- { WM8996_DC_SERVO_6, 0x0 },
- { WM8996_DC_SERVO_7, 0x0 },
- { WM8996_ANALOGUE_HP_1, 0x0 },
- { WM8996_ANALOGUE_HP_2, 0x0 },
- { WM8996_CONTROL_INTERFACE_1, 0x8004 },
- { WM8996_WRITE_SEQUENCER_CTRL_1, 0x0 },
- { WM8996_WRITE_SEQUENCER_CTRL_2, 0x0 },
- { WM8996_AIF_CLOCKING_1, 0x0 },
- { WM8996_AIF_CLOCKING_2, 0x0 },
- { WM8996_CLOCKING_1, 0x10 },
- { WM8996_CLOCKING_2, 0x0 },
- { WM8996_AIF_RATE, 0x83 },
- { WM8996_FLL_CONTROL_1, 0x0 },
- { WM8996_FLL_CONTROL_2, 0x0 },
- { WM8996_FLL_CONTROL_3, 0x0 },
- { WM8996_FLL_CONTROL_4, 0x5dc0 },
- { WM8996_FLL_CONTROL_5, 0xc84 },
- { WM8996_FLL_EFS_1, 0x0 },
- { WM8996_FLL_EFS_2, 0x2 },
- { WM8996_AIF1_CONTROL, 0x0 },
- { WM8996_AIF1_BCLK, 0x0 },
- { WM8996_AIF1_TX_LRCLK_1, 0x80 },
- { WM8996_AIF1_TX_LRCLK_2, 0x8 },
- { WM8996_AIF1_RX_LRCLK_1, 0x80 },
- { WM8996_AIF1_RX_LRCLK_2, 0x0 },
- { WM8996_AIF1TX_DATA_CONFIGURATION_1, 0x1818 },
- { WM8996_AIF1TX_DATA_CONFIGURATION_2, 0 },
- { WM8996_AIF1RX_DATA_CONFIGURATION, 0x1818 },
- { WM8996_AIF1TX_CHANNEL_0_CONFIGURATION, 0x0 },
- { WM8996_AIF1TX_CHANNEL_1_CONFIGURATION, 0x0 },
- { WM8996_AIF1TX_CHANNEL_2_CONFIGURATION, 0x0 },
- { WM8996_AIF1TX_CHANNEL_3_CONFIGURATION, 0x0 },
- { WM8996_AIF1TX_CHANNEL_4_CONFIGURATION, 0x0 },
- { WM8996_AIF1TX_CHANNEL_5_CONFIGURATION, 0x0 },
- { WM8996_AIF1RX_CHANNEL_0_CONFIGURATION, 0x0 },
- { WM8996_AIF1RX_CHANNEL_1_CONFIGURATION, 0x0 },
- { WM8996_AIF1RX_CHANNEL_2_CONFIGURATION, 0x0 },
- { WM8996_AIF1RX_CHANNEL_3_CONFIGURATION, 0x0 },
- { WM8996_AIF1RX_CHANNEL_4_CONFIGURATION, 0x0 },
- { WM8996_AIF1RX_CHANNEL_5_CONFIGURATION, 0x0 },
- { WM8996_AIF1RX_MONO_CONFIGURATION, 0x0 },
- { WM8996_AIF1TX_TEST, 0x7 },
- { WM8996_AIF2_CONTROL, 0x0 },
- { WM8996_AIF2_BCLK, 0x0 },
- { WM8996_AIF2_TX_LRCLK_1, 0x80 },
- { WM8996_AIF2_TX_LRCLK_2, 0x8 },
- { WM8996_AIF2_RX_LRCLK_1, 0x80 },
- { WM8996_AIF2_RX_LRCLK_2, 0x0 },
- { WM8996_AIF2TX_DATA_CONFIGURATION_1, 0x1818 },
- { WM8996_AIF2RX_DATA_CONFIGURATION, 0x1818 },
- { WM8996_AIF2RX_DATA_CONFIGURATION, 0x0 },
- { WM8996_AIF2TX_CHANNEL_0_CONFIGURATION, 0x0 },
- { WM8996_AIF2TX_CHANNEL_1_CONFIGURATION, 0x0 },
- { WM8996_AIF2RX_CHANNEL_0_CONFIGURATION, 0x0 },
- { WM8996_AIF2RX_CHANNEL_1_CONFIGURATION, 0x0 },
- { WM8996_AIF2RX_MONO_CONFIGURATION, 0x0 },
- { WM8996_AIF2TX_TEST, 0x1 },
- { WM8996_DSP1_TX_LEFT_VOLUME, 0xc0 },
- { WM8996_DSP1_TX_RIGHT_VOLUME, 0xc0 },
- { WM8996_DSP1_RX_LEFT_VOLUME, 0xc0 },
- { WM8996_DSP1_RX_RIGHT_VOLUME, 0xc0 },
- { WM8996_DSP1_TX_FILTERS, 0x2000 },
- { WM8996_DSP1_RX_FILTERS_1, 0x200 },
- { WM8996_DSP1_RX_FILTERS_2, 0x10 },
- { WM8996_DSP1_DRC_1, 0x98 },
- { WM8996_DSP1_DRC_2, 0x845 },
- { WM8996_DSP1_RX_EQ_GAINS_1, 0x6318 },
- { WM8996_DSP1_RX_EQ_GAINS_2, 0x6300 },
- { WM8996_DSP1_RX_EQ_BAND_1_A, 0xfca },
- { WM8996_DSP1_RX_EQ_BAND_1_B, 0x400 },
- { WM8996_DSP1_RX_EQ_BAND_1_PG, 0xd8 },
- { WM8996_DSP1_RX_EQ_BAND_2_A, 0x1eb5 },
- { WM8996_DSP1_RX_EQ_BAND_2_B, 0xf145 },
- { WM8996_DSP1_RX_EQ_BAND_2_C, 0xb75 },
- { WM8996_DSP1_RX_EQ_BAND_2_PG, 0x1c5 },
- { WM8996_DSP1_RX_EQ_BAND_3_A, 0x1c58 },
- { WM8996_DSP1_RX_EQ_BAND_3_B, 0xf373 },
- { WM8996_DSP1_RX_EQ_BAND_3_C, 0xa54 },
- { WM8996_DSP1_RX_EQ_BAND_3_PG, 0x558 },
- { WM8996_DSP1_RX_EQ_BAND_4_A, 0x168e },
- { WM8996_DSP1_RX_EQ_BAND_4_B, 0xf829 },
- { WM8996_DSP1_RX_EQ_BAND_4_C, 0x7ad },
- { WM8996_DSP1_RX_EQ_BAND_4_PG, 0x1103 },
- { WM8996_DSP1_RX_EQ_BAND_5_A, 0x564 },
- { WM8996_DSP1_RX_EQ_BAND_5_B, 0x559 },
- { WM8996_DSP1_RX_EQ_BAND_5_PG, 0x4000 },
- { WM8996_DSP2_TX_LEFT_VOLUME, 0xc0 },
- { WM8996_DSP2_TX_RIGHT_VOLUME, 0xc0 },
- { WM8996_DSP2_RX_LEFT_VOLUME, 0xc0 },
- { WM8996_DSP2_RX_RIGHT_VOLUME, 0xc0 },
- { WM8996_DSP2_TX_FILTERS, 0x2000 },
- { WM8996_DSP2_RX_FILTERS_1, 0x200 },
- { WM8996_DSP2_RX_FILTERS_2, 0x10 },
- { WM8996_DSP2_DRC_1, 0x98 },
- { WM8996_DSP2_DRC_2, 0x845 },
- { WM8996_DSP2_RX_EQ_GAINS_1, 0x6318 },
- { WM8996_DSP2_RX_EQ_GAINS_2, 0x6300 },
- { WM8996_DSP2_RX_EQ_BAND_1_A, 0xfca },
- { WM8996_DSP2_RX_EQ_BAND_1_B, 0x400 },
- { WM8996_DSP2_RX_EQ_BAND_1_PG, 0xd8 },
- { WM8996_DSP2_RX_EQ_BAND_2_A, 0x1eb5 },
- { WM8996_DSP2_RX_EQ_BAND_2_B, 0xf145 },
- { WM8996_DSP2_RX_EQ_BAND_2_C, 0xb75 },
- { WM8996_DSP2_RX_EQ_BAND_2_PG, 0x1c5 },
- { WM8996_DSP2_RX_EQ_BAND_3_A, 0x1c58 },
- { WM8996_DSP2_RX_EQ_BAND_3_B, 0xf373 },
- { WM8996_DSP2_RX_EQ_BAND_3_C, 0xa54 },
- { WM8996_DSP2_RX_EQ_BAND_3_PG, 0x558 },
- { WM8996_DSP2_RX_EQ_BAND_4_A, 0x168e },
- { WM8996_DSP2_RX_EQ_BAND_4_B, 0xf829 },
- { WM8996_DSP2_RX_EQ_BAND_4_C, 0x7ad },
- { WM8996_DSP2_RX_EQ_BAND_4_PG, 0x1103 },
- { WM8996_DSP2_RX_EQ_BAND_5_A, 0x564 },
- { WM8996_DSP2_RX_EQ_BAND_5_B, 0x559 },
- { WM8996_DSP2_RX_EQ_BAND_5_PG, 0x4000 },
- { WM8996_DAC1_MIXER_VOLUMES, 0x0 },
- { WM8996_DAC1_LEFT_MIXER_ROUTING, 0x0 },
- { WM8996_DAC1_RIGHT_MIXER_ROUTING, 0x0 },
- { WM8996_DAC2_MIXER_VOLUMES, 0x0 },
- { WM8996_DAC2_LEFT_MIXER_ROUTING, 0x0 },
- { WM8996_DAC2_RIGHT_MIXER_ROUTING, 0x0 },
- { WM8996_DSP1_TX_LEFT_MIXER_ROUTING, 0x0 },
- { WM8996_DSP1_TX_RIGHT_MIXER_ROUTING, 0x0 },
- { WM8996_DSP2_TX_LEFT_MIXER_ROUTING, 0x0 },
- { WM8996_DSP2_TX_RIGHT_MIXER_ROUTING, 0x0 },
- { WM8996_DSP_TX_MIXER_SELECT, 0x0 },
- { WM8996_DAC_SOFTMUTE, 0x0 },
- { WM8996_OVERSAMPLING, 0xd },
- { WM8996_SIDETONE, 0x1040 },
- { WM8996_GPIO_1, 0xa101 },
- { WM8996_GPIO_2, 0xa101 },
- { WM8996_GPIO_3, 0xa101 },
- { WM8996_GPIO_4, 0xa101 },
- { WM8996_GPIO_5, 0xa101 },
- { WM8996_PULL_CONTROL_1, 0x0 },
- { WM8996_PULL_CONTROL_2, 0x140 },
- { WM8996_INTERRUPT_STATUS_1_MASK, 0x1f },
- { WM8996_INTERRUPT_STATUS_2_MASK, 0x1ecf },
- { WM8996_LEFT_PDM_SPEAKER, 0x0 },
- { WM8996_RIGHT_PDM_SPEAKER, 0x1 },
- { WM8996_PDM_SPEAKER_MUTE_SEQUENCE, 0x69 },
- { WM8996_PDM_SPEAKER_VOLUME, 0x66 },
- { WM8996_WRITE_SEQUENCER_0, 0x1 },
- { WM8996_WRITE_SEQUENCER_1, 0x1 },
- { WM8996_WRITE_SEQUENCER_3, 0x6 },
- { WM8996_WRITE_SEQUENCER_4, 0x40 },
- { WM8996_WRITE_SEQUENCER_5, 0x1 },
- { WM8996_WRITE_SEQUENCER_6, 0xf },
- { WM8996_WRITE_SEQUENCER_7, 0x6 },
- { WM8996_WRITE_SEQUENCER_8, 0x1 },
- { WM8996_WRITE_SEQUENCER_9, 0x3 },
- { WM8996_WRITE_SEQUENCER_10, 0x104 },
- { WM8996_WRITE_SEQUENCER_12, 0x60 },
- { WM8996_WRITE_SEQUENCER_13, 0x11 },
- { WM8996_WRITE_SEQUENCER_14, 0x401 },
- { WM8996_WRITE_SEQUENCER_16, 0x50 },
- { WM8996_WRITE_SEQUENCER_17, 0x3 },
- { WM8996_WRITE_SEQUENCER_18, 0x100 },
- { WM8996_WRITE_SEQUENCER_20, 0x51 },
- { WM8996_WRITE_SEQUENCER_21, 0x3 },
- { WM8996_WRITE_SEQUENCER_22, 0x104 },
- { WM8996_WRITE_SEQUENCER_23, 0xa },
- { WM8996_WRITE_SEQUENCER_24, 0x60 },
- { WM8996_WRITE_SEQUENCER_25, 0x3b },
- { WM8996_WRITE_SEQUENCER_26, 0x502 },
- { WM8996_WRITE_SEQUENCER_27, 0x100 },
- { WM8996_WRITE_SEQUENCER_28, 0x2fff },
- { WM8996_WRITE_SEQUENCER_32, 0x2fff },
- { WM8996_WRITE_SEQUENCER_36, 0x2fff },
- { WM8996_WRITE_SEQUENCER_40, 0x2fff },
- { WM8996_WRITE_SEQUENCER_44, 0x2fff },
- { WM8996_WRITE_SEQUENCER_48, 0x2fff },
- { WM8996_WRITE_SEQUENCER_52, 0x2fff },
- { WM8996_WRITE_SEQUENCER_56, 0x2fff },
- { WM8996_WRITE_SEQUENCER_60, 0x2fff },
- { WM8996_WRITE_SEQUENCER_64, 0x1 },
- { WM8996_WRITE_SEQUENCER_65, 0x1 },
- { WM8996_WRITE_SEQUENCER_67, 0x6 },
- { WM8996_WRITE_SEQUENCER_68, 0x40 },
- { WM8996_WRITE_SEQUENCER_69, 0x1 },
- { WM8996_WRITE_SEQUENCER_70, 0xf },
- { WM8996_WRITE_SEQUENCER_71, 0x6 },
- { WM8996_WRITE_SEQUENCER_72, 0x1 },
- { WM8996_WRITE_SEQUENCER_73, 0x3 },
- { WM8996_WRITE_SEQUENCER_74, 0x104 },
- { WM8996_WRITE_SEQUENCER_76, 0x60 },
- { WM8996_WRITE_SEQUENCER_77, 0x11 },
- { WM8996_WRITE_SEQUENCER_78, 0x401 },
- { WM8996_WRITE_SEQUENCER_80, 0x50 },
- { WM8996_WRITE_SEQUENCER_81, 0x3 },
- { WM8996_WRITE_SEQUENCER_82, 0x100 },
- { WM8996_WRITE_SEQUENCER_84, 0x60 },
- { WM8996_WRITE_SEQUENCER_85, 0x3b },
- { WM8996_WRITE_SEQUENCER_86, 0x502 },
- { WM8996_WRITE_SEQUENCER_87, 0x100 },
- { WM8996_WRITE_SEQUENCER_88, 0x2fff },
- { WM8996_WRITE_SEQUENCER_92, 0x2fff },
- { WM8996_WRITE_SEQUENCER_96, 0x2fff },
- { WM8996_WRITE_SEQUENCER_100, 0x2fff },
- { WM8996_WRITE_SEQUENCER_104, 0x2fff },
- { WM8996_WRITE_SEQUENCER_108, 0x2fff },
- { WM8996_WRITE_SEQUENCER_112, 0x2fff },
- { WM8996_WRITE_SEQUENCER_116, 0x2fff },
- { WM8996_WRITE_SEQUENCER_120, 0x2fff },
- { WM8996_WRITE_SEQUENCER_124, 0x2fff },
- { WM8996_WRITE_SEQUENCER_128, 0x1 },
- { WM8996_WRITE_SEQUENCER_129, 0x1 },
- { WM8996_WRITE_SEQUENCER_131, 0x6 },
- { WM8996_WRITE_SEQUENCER_132, 0x40 },
- { WM8996_WRITE_SEQUENCER_133, 0x1 },
- { WM8996_WRITE_SEQUENCER_134, 0xf },
- { WM8996_WRITE_SEQUENCER_135, 0x6 },
- { WM8996_WRITE_SEQUENCER_136, 0x1 },
- { WM8996_WRITE_SEQUENCER_137, 0x3 },
- { WM8996_WRITE_SEQUENCER_138, 0x106 },
- { WM8996_WRITE_SEQUENCER_140, 0x61 },
- { WM8996_WRITE_SEQUENCER_141, 0x11 },
- { WM8996_WRITE_SEQUENCER_142, 0x401 },
- { WM8996_WRITE_SEQUENCER_144, 0x50 },
- { WM8996_WRITE_SEQUENCER_145, 0x3 },
- { WM8996_WRITE_SEQUENCER_146, 0x102 },
- { WM8996_WRITE_SEQUENCER_148, 0x51 },
- { WM8996_WRITE_SEQUENCER_149, 0x3 },
- { WM8996_WRITE_SEQUENCER_150, 0x106 },
- { WM8996_WRITE_SEQUENCER_151, 0xa },
- { WM8996_WRITE_SEQUENCER_152, 0x61 },
- { WM8996_WRITE_SEQUENCER_153, 0x3b },
- { WM8996_WRITE_SEQUENCER_154, 0x502 },
- { WM8996_WRITE_SEQUENCER_155, 0x100 },
- { WM8996_WRITE_SEQUENCER_156, 0x2fff },
- { WM8996_WRITE_SEQUENCER_160, 0x2fff },
- { WM8996_WRITE_SEQUENCER_164, 0x2fff },
- { WM8996_WRITE_SEQUENCER_168, 0x2fff },
- { WM8996_WRITE_SEQUENCER_172, 0x2fff },
- { WM8996_WRITE_SEQUENCER_176, 0x2fff },
- { WM8996_WRITE_SEQUENCER_180, 0x2fff },
- { WM8996_WRITE_SEQUENCER_184, 0x2fff },
- { WM8996_WRITE_SEQUENCER_188, 0x2fff },
- { WM8996_WRITE_SEQUENCER_192, 0x1 },
- { WM8996_WRITE_SEQUENCER_193, 0x1 },
- { WM8996_WRITE_SEQUENCER_195, 0x6 },
- { WM8996_WRITE_SEQUENCER_196, 0x40 },
- { WM8996_WRITE_SEQUENCER_197, 0x1 },
- { WM8996_WRITE_SEQUENCER_198, 0xf },
- { WM8996_WRITE_SEQUENCER_199, 0x6 },
- { WM8996_WRITE_SEQUENCER_200, 0x1 },
- { WM8996_WRITE_SEQUENCER_201, 0x3 },
- { WM8996_WRITE_SEQUENCER_202, 0x106 },
- { WM8996_WRITE_SEQUENCER_204, 0x61 },
- { WM8996_WRITE_SEQUENCER_205, 0x11 },
- { WM8996_WRITE_SEQUENCER_206, 0x401 },
- { WM8996_WRITE_SEQUENCER_208, 0x50 },
- { WM8996_WRITE_SEQUENCER_209, 0x3 },
- { WM8996_WRITE_SEQUENCER_210, 0x102 },
- { WM8996_WRITE_SEQUENCER_212, 0x61 },
- { WM8996_WRITE_SEQUENCER_213, 0x3b },
- { WM8996_WRITE_SEQUENCER_214, 0x502 },
- { WM8996_WRITE_SEQUENCER_215, 0x100 },
- { WM8996_WRITE_SEQUENCER_216, 0x2fff },
- { WM8996_WRITE_SEQUENCER_220, 0x2fff },
- { WM8996_WRITE_SEQUENCER_224, 0x2fff },
- { WM8996_WRITE_SEQUENCER_228, 0x2fff },
- { WM8996_WRITE_SEQUENCER_232, 0x2fff },
- { WM8996_WRITE_SEQUENCER_236, 0x2fff },
- { WM8996_WRITE_SEQUENCER_240, 0x2fff },
- { WM8996_WRITE_SEQUENCER_244, 0x2fff },
- { WM8996_WRITE_SEQUENCER_248, 0x2fff },
- { WM8996_WRITE_SEQUENCER_252, 0x2fff },
- { WM8996_WRITE_SEQUENCER_256, 0x60 },
- { WM8996_WRITE_SEQUENCER_258, 0x601 },
- { WM8996_WRITE_SEQUENCER_260, 0x50 },
- { WM8996_WRITE_SEQUENCER_262, 0x100 },
- { WM8996_WRITE_SEQUENCER_264, 0x1 },
- { WM8996_WRITE_SEQUENCER_266, 0x104 },
- { WM8996_WRITE_SEQUENCER_267, 0x100 },
- { WM8996_WRITE_SEQUENCER_268, 0x2fff },
- { WM8996_WRITE_SEQUENCER_272, 0x2fff },
- { WM8996_WRITE_SEQUENCER_276, 0x2fff },
- { WM8996_WRITE_SEQUENCER_280, 0x2fff },
- { WM8996_WRITE_SEQUENCER_284, 0x2fff },
- { WM8996_WRITE_SEQUENCER_288, 0x2fff },
- { WM8996_WRITE_SEQUENCER_292, 0x2fff },
- { WM8996_WRITE_SEQUENCER_296, 0x2fff },
- { WM8996_WRITE_SEQUENCER_300, 0x2fff },
- { WM8996_WRITE_SEQUENCER_304, 0x2fff },
- { WM8996_WRITE_SEQUENCER_308, 0x2fff },
- { WM8996_WRITE_SEQUENCER_312, 0x2fff },
- { WM8996_WRITE_SEQUENCER_316, 0x2fff },
- { WM8996_WRITE_SEQUENCER_320, 0x61 },
- { WM8996_WRITE_SEQUENCER_322, 0x601 },
- { WM8996_WRITE_SEQUENCER_324, 0x50 },
- { WM8996_WRITE_SEQUENCER_326, 0x102 },
- { WM8996_WRITE_SEQUENCER_328, 0x1 },
- { WM8996_WRITE_SEQUENCER_330, 0x106 },
- { WM8996_WRITE_SEQUENCER_331, 0x100 },
- { WM8996_WRITE_SEQUENCER_332, 0x2fff },
- { WM8996_WRITE_SEQUENCER_336, 0x2fff },
- { WM8996_WRITE_SEQUENCER_340, 0x2fff },
- { WM8996_WRITE_SEQUENCER_344, 0x2fff },
- { WM8996_WRITE_SEQUENCER_348, 0x2fff },
- { WM8996_WRITE_SEQUENCER_352, 0x2fff },
- { WM8996_WRITE_SEQUENCER_356, 0x2fff },
- { WM8996_WRITE_SEQUENCER_360, 0x2fff },
- { WM8996_WRITE_SEQUENCER_364, 0x2fff },
- { WM8996_WRITE_SEQUENCER_368, 0x2fff },
- { WM8996_WRITE_SEQUENCER_372, 0x2fff },
- { WM8996_WRITE_SEQUENCER_376, 0x2fff },
- { WM8996_WRITE_SEQUENCER_380, 0x2fff },
- { WM8996_WRITE_SEQUENCER_384, 0x60 },
- { WM8996_WRITE_SEQUENCER_386, 0x601 },
- { WM8996_WRITE_SEQUENCER_388, 0x61 },
- { WM8996_WRITE_SEQUENCER_390, 0x601 },
- { WM8996_WRITE_SEQUENCER_392, 0x50 },
- { WM8996_WRITE_SEQUENCER_394, 0x300 },
- { WM8996_WRITE_SEQUENCER_396, 0x1 },
- { WM8996_WRITE_SEQUENCER_398, 0x304 },
- { WM8996_WRITE_SEQUENCER_400, 0x40 },
- { WM8996_WRITE_SEQUENCER_402, 0xf },
- { WM8996_WRITE_SEQUENCER_404, 0x1 },
- { WM8996_WRITE_SEQUENCER_407, 0x100 },
-};
-
-static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0);
-static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 150, 0);
-static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
-static const DECLARE_TLV_DB_SCALE(out_digital_tlv, -1200, 150, 0);
-static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0);
-static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0);
-static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
-static const DECLARE_TLV_DB_SCALE(threedstereo_tlv, -1600, 183, 1);
-
-static const char *sidetone_hpf_text[] = {
- "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz"
-};
-
-static const struct soc_enum sidetone_hpf =
- SOC_ENUM_SINGLE(WM8996_SIDETONE, 7, 7, sidetone_hpf_text);
-
-static const char *hpf_mode_text[] = {
- "HiFi", "Custom", "Voice"
-};
-
-static const struct soc_enum dsp1tx_hpf_mode =
- SOC_ENUM_SINGLE(WM8996_DSP1_TX_FILTERS, 3, 3, hpf_mode_text);
-
-static const struct soc_enum dsp2tx_hpf_mode =
- SOC_ENUM_SINGLE(WM8996_DSP2_TX_FILTERS, 3, 3, hpf_mode_text);
-
-static const char *hpf_cutoff_text[] = {
- "50Hz", "75Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
-};
-
-static const struct soc_enum dsp1tx_hpf_cutoff =
- SOC_ENUM_SINGLE(WM8996_DSP1_TX_FILTERS, 0, 7, hpf_cutoff_text);
-
-static const struct soc_enum dsp2tx_hpf_cutoff =
- SOC_ENUM_SINGLE(WM8996_DSP2_TX_FILTERS, 0, 7, hpf_cutoff_text);
-
-static void wm8996_set_retune_mobile(struct snd_soc_codec *codec, int block)
-{
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
- struct wm8996_pdata *pdata = &wm8996->pdata;
- int base, best, best_val, save, i, cfg, iface;
-
- if (!wm8996->num_retune_mobile_texts)
- return;
-
- switch (block) {
- case 0:
- base = WM8996_DSP1_RX_EQ_GAINS_1;
- if (snd_soc_read(codec, WM8996_POWER_MANAGEMENT_8) &
- WM8996_DSP1RX_SRC)
- iface = 1;
- else
- iface = 0;
- break;
- case 1:
- base = WM8996_DSP1_RX_EQ_GAINS_2;
- if (snd_soc_read(codec, WM8996_POWER_MANAGEMENT_8) &
- WM8996_DSP2RX_SRC)
- iface = 1;
- else
- iface = 0;
- break;
- default:
- return;
- }
-
- /* Find the version of the currently selected configuration
- * with the nearest sample rate. */
- cfg = wm8996->retune_mobile_cfg[block];
- best = 0;
- best_val = INT_MAX;
- for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
- if (strcmp(pdata->retune_mobile_cfgs[i].name,
- wm8996->retune_mobile_texts[cfg]) == 0 &&
- abs(pdata->retune_mobile_cfgs[i].rate
- - wm8996->rx_rate[iface]) < best_val) {
- best = i;
- best_val = abs(pdata->retune_mobile_cfgs[i].rate
- - wm8996->rx_rate[iface]);
- }
- }
-
- dev_dbg(codec->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n",
- block,
- pdata->retune_mobile_cfgs[best].name,
- pdata->retune_mobile_cfgs[best].rate,
- wm8996->rx_rate[iface]);
-
- /* The EQ will be disabled while reconfiguring it, remember the
- * current configuration.
- */
- save = snd_soc_read(codec, base);
- save &= WM8996_DSP1RX_EQ_ENA;
-
- for (i = 0; i < ARRAY_SIZE(pdata->retune_mobile_cfgs[best].regs); i++)
- snd_soc_update_bits(codec, base + i, 0xffff,
- pdata->retune_mobile_cfgs[best].regs[i]);
-
- snd_soc_update_bits(codec, base, WM8996_DSP1RX_EQ_ENA, save);
-}
-
-/* Icky as hell but saves code duplication */
-static int wm8996_get_retune_mobile_block(const char *name)
-{
- if (strcmp(name, "DSP1 EQ Mode") == 0)
- return 0;
- if (strcmp(name, "DSP2 EQ Mode") == 0)
- return 1;
- return -EINVAL;
-}
-
-static int wm8996_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
- struct wm8996_pdata *pdata = &wm8996->pdata;
- int block = wm8996_get_retune_mobile_block(kcontrol->id.name);
- int value = ucontrol->value.integer.value[0];
-
- if (block < 0)
- return block;
-
- if (value >= pdata->num_retune_mobile_cfgs)
- return -EINVAL;
-
- wm8996->retune_mobile_cfg[block] = value;
-
- wm8996_set_retune_mobile(codec, block);
-
- return 0;
-}
-
-static int wm8996_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
- int block = wm8996_get_retune_mobile_block(kcontrol->id.name);
-
- ucontrol->value.enumerated.item[0] = wm8996->retune_mobile_cfg[block];
-
- return 0;
-}
-
-static const struct snd_kcontrol_new wm8996_snd_controls[] = {
-SOC_DOUBLE_R_TLV("Capture Volume", WM8996_LEFT_LINE_INPUT_VOLUME,
- WM8996_RIGHT_LINE_INPUT_VOLUME, 0, 31, 0, inpga_tlv),
-SOC_DOUBLE_R("Capture ZC Switch", WM8996_LEFT_LINE_INPUT_VOLUME,
- WM8996_RIGHT_LINE_INPUT_VOLUME, 5, 1, 0),
-
-SOC_DOUBLE_TLV("DAC1 Sidetone Volume", WM8996_DAC1_MIXER_VOLUMES,
- 0, 5, 24, 0, sidetone_tlv),
-SOC_DOUBLE_TLV("DAC2 Sidetone Volume", WM8996_DAC2_MIXER_VOLUMES,
- 0, 5, 24, 0, sidetone_tlv),
-SOC_SINGLE("Sidetone LPF Switch", WM8996_SIDETONE, 12, 1, 0),
-SOC_ENUM("Sidetone HPF Cut-off", sidetone_hpf),
-SOC_SINGLE("Sidetone HPF Switch", WM8996_SIDETONE, 6, 1, 0),
-
-SOC_DOUBLE_R_TLV("DSP1 Capture Volume", WM8996_DSP1_TX_LEFT_VOLUME,
- WM8996_DSP1_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
-SOC_DOUBLE_R_TLV("DSP2 Capture Volume", WM8996_DSP2_TX_LEFT_VOLUME,
- WM8996_DSP2_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
-
-SOC_SINGLE("DSP1 Capture Notch Filter Switch", WM8996_DSP1_TX_FILTERS,
- 13, 1, 0),
-SOC_DOUBLE("DSP1 Capture HPF Switch", WM8996_DSP1_TX_FILTERS, 12, 11, 1, 0),
-SOC_ENUM("DSP1 Capture HPF Mode", dsp1tx_hpf_mode),
-SOC_ENUM("DSP1 Capture HPF Cutoff", dsp1tx_hpf_cutoff),
-
-SOC_SINGLE("DSP2 Capture Notch Filter Switch", WM8996_DSP2_TX_FILTERS,
- 13, 1, 0),
-SOC_DOUBLE("DSP2 Capture HPF Switch", WM8996_DSP2_TX_FILTERS, 12, 11, 1, 0),
-SOC_ENUM("DSP2 Capture HPF Mode", dsp2tx_hpf_mode),
-SOC_ENUM("DSP2 Capture HPF Cutoff", dsp2tx_hpf_cutoff),
-
-SOC_DOUBLE_R_TLV("DSP1 Playback Volume", WM8996_DSP1_RX_LEFT_VOLUME,
- WM8996_DSP1_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
-SOC_SINGLE("DSP1 Playback Switch", WM8996_DSP1_RX_FILTERS_1, 9, 1, 1),
-
-SOC_DOUBLE_R_TLV("DSP2 Playback Volume", WM8996_DSP2_RX_LEFT_VOLUME,
- WM8996_DSP2_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
-SOC_SINGLE("DSP2 Playback Switch", WM8996_DSP2_RX_FILTERS_1, 9, 1, 1),
-
-SOC_DOUBLE_R_TLV("DAC1 Volume", WM8996_DAC1_LEFT_VOLUME,
- WM8996_DAC1_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
-SOC_DOUBLE_R("DAC1 Switch", WM8996_DAC1_LEFT_VOLUME,
- WM8996_DAC1_RIGHT_VOLUME, 9, 1, 1),
-
-SOC_DOUBLE_R_TLV("DAC2 Volume", WM8996_DAC2_LEFT_VOLUME,
- WM8996_DAC2_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
-SOC_DOUBLE_R("DAC2 Switch", WM8996_DAC2_LEFT_VOLUME,
- WM8996_DAC2_RIGHT_VOLUME, 9, 1, 1),
-
-SOC_SINGLE("Speaker High Performance Switch", WM8996_OVERSAMPLING, 3, 1, 0),
-SOC_SINGLE("DMIC High Performance Switch", WM8996_OVERSAMPLING, 2, 1, 0),
-SOC_SINGLE("ADC High Performance Switch", WM8996_OVERSAMPLING, 1, 1, 0),
-SOC_SINGLE("DAC High Performance Switch", WM8996_OVERSAMPLING, 0, 1, 0),
-
-SOC_SINGLE("DAC Soft Mute Switch", WM8996_DAC_SOFTMUTE, 1, 1, 0),
-SOC_SINGLE("DAC Slow Soft Mute Switch", WM8996_DAC_SOFTMUTE, 0, 1, 0),
-
-SOC_SINGLE("DSP1 3D Stereo Switch", WM8996_DSP1_RX_FILTERS_2, 8, 1, 0),
-SOC_SINGLE("DSP2 3D Stereo Switch", WM8996_DSP2_RX_FILTERS_2, 8, 1, 0),
-
-SOC_SINGLE_TLV("DSP1 3D Stereo Volume", WM8996_DSP1_RX_FILTERS_2, 10, 15,
- 0, threedstereo_tlv),
-SOC_SINGLE_TLV("DSP2 3D Stereo Volume", WM8996_DSP2_RX_FILTERS_2, 10, 15,
- 0, threedstereo_tlv),
-
-SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8996_DAC1_HPOUT1_VOLUME, 0, 4,
- 8, 0, out_digital_tlv),
-SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8996_DAC2_HPOUT2_VOLUME, 0, 4,
- 8, 0, out_digital_tlv),
-
-SOC_DOUBLE_R_TLV("Output 1 Volume", WM8996_OUTPUT1_LEFT_VOLUME,
- WM8996_OUTPUT1_RIGHT_VOLUME, 0, 12, 0, out_tlv),
-SOC_DOUBLE_R("Output 1 ZC Switch", WM8996_OUTPUT1_LEFT_VOLUME,
- WM8996_OUTPUT1_RIGHT_VOLUME, 7, 1, 0),
-
-SOC_DOUBLE_R_TLV("Output 2 Volume", WM8996_OUTPUT2_LEFT_VOLUME,
- WM8996_OUTPUT2_RIGHT_VOLUME, 0, 12, 0, out_tlv),
-SOC_DOUBLE_R("Output 2 ZC Switch", WM8996_OUTPUT2_LEFT_VOLUME,
- WM8996_OUTPUT2_RIGHT_VOLUME, 7, 1, 0),
-
-SOC_DOUBLE_TLV("Speaker Volume", WM8996_PDM_SPEAKER_VOLUME, 0, 4, 8, 0,
- spk_tlv),
-SOC_DOUBLE_R("Speaker Switch", WM8996_LEFT_PDM_SPEAKER,
- WM8996_RIGHT_PDM_SPEAKER, 3, 1, 1),
-SOC_DOUBLE_R("Speaker ZC Switch", WM8996_LEFT_PDM_SPEAKER,
- WM8996_RIGHT_PDM_SPEAKER, 2, 1, 0),
-
-SOC_SINGLE("DSP1 EQ Switch", WM8996_DSP1_RX_EQ_GAINS_1, 0, 1, 0),
-SOC_SINGLE("DSP2 EQ Switch", WM8996_DSP2_RX_EQ_GAINS_1, 0, 1, 0),
-
-SOC_SINGLE("DSP1 DRC TXL Switch", WM8996_DSP1_DRC_1, 0, 1, 0),
-SOC_SINGLE("DSP1 DRC TXR Switch", WM8996_DSP1_DRC_1, 1, 1, 0),
-SOC_SINGLE("DSP1 DRC RX Switch", WM8996_DSP1_DRC_1, 2, 1, 0),
-SND_SOC_BYTES_MASK("DSP1 DRC", WM8996_DSP1_DRC_1, 5,
- WM8996_DSP1RX_DRC_ENA | WM8996_DSP1TXL_DRC_ENA |
- WM8996_DSP1TXR_DRC_ENA),
-
-SOC_SINGLE("DSP2 DRC TXL Switch", WM8996_DSP2_DRC_1, 0, 1, 0),
-SOC_SINGLE("DSP2 DRC TXR Switch", WM8996_DSP2_DRC_1, 1, 1, 0),
-SOC_SINGLE("DSP2 DRC RX Switch", WM8996_DSP2_DRC_1, 2, 1, 0),
-SND_SOC_BYTES_MASK("DSP2 DRC", WM8996_DSP2_DRC_1, 5,
- WM8996_DSP2RX_DRC_ENA | WM8996_DSP2TXL_DRC_ENA |
- WM8996_DSP2TXR_DRC_ENA),
-};
-
-static const struct snd_kcontrol_new wm8996_eq_controls[] = {
-SOC_SINGLE_TLV("DSP1 EQ B1 Volume", WM8996_DSP1_RX_EQ_GAINS_1, 11, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("DSP1 EQ B2 Volume", WM8996_DSP1_RX_EQ_GAINS_1, 6, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("DSP1 EQ B3 Volume", WM8996_DSP1_RX_EQ_GAINS_1, 1, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("DSP1 EQ B4 Volume", WM8996_DSP1_RX_EQ_GAINS_2, 11, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("DSP1 EQ B5 Volume", WM8996_DSP1_RX_EQ_GAINS_2, 6, 31, 0,
- eq_tlv),
-
-SOC_SINGLE_TLV("DSP2 EQ B1 Volume", WM8996_DSP2_RX_EQ_GAINS_1, 11, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("DSP2 EQ B2 Volume", WM8996_DSP2_RX_EQ_GAINS_1, 6, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("DSP2 EQ B3 Volume", WM8996_DSP2_RX_EQ_GAINS_1, 1, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("DSP2 EQ B4 Volume", WM8996_DSP2_RX_EQ_GAINS_2, 11, 31, 0,
- eq_tlv),
-SOC_SINGLE_TLV("DSP2 EQ B5 Volume", WM8996_DSP2_RX_EQ_GAINS_2, 6, 31, 0,
- eq_tlv),
-};
-
-static void wm8996_bg_enable(struct snd_soc_codec *codec)
-{
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
-
- wm8996->bg_ena++;
- if (wm8996->bg_ena == 1) {
- snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
- WM8996_BG_ENA, WM8996_BG_ENA);
- msleep(2);
- }
-}
-
-static void wm8996_bg_disable(struct snd_soc_codec *codec)
-{
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
-
- wm8996->bg_ena--;
- if (!wm8996->bg_ena)
- snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1,
- WM8996_BG_ENA, 0);
-}
-
-static int bg_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- int ret = 0;
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- wm8996_bg_enable(codec);
- break;
- case SND_SOC_DAPM_POST_PMD:
- wm8996_bg_disable(codec);
- break;
- default:
- BUG();
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int cp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- int ret = 0;
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- msleep(5);
- break;
- default:
- BUG();
- ret = -EINVAL;
- }
-
- return 0;
-}
-
-static int rmv_short_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(w->codec);
-
- /* Record which outputs we enabled */
- switch (event) {
- case SND_SOC_DAPM_PRE_PMD:
- wm8996->hpout_pending &= ~w->shift;
- break;
- case SND_SOC_DAPM_PRE_PMU:
- wm8996->hpout_pending |= w->shift;
- break;
- default:
- BUG();
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask)
-{
- struct i2c_client *i2c = to_i2c_client(codec->dev);
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
- int ret;
- unsigned long timeout = 200;
-
- snd_soc_write(codec, WM8996_DC_SERVO_2, mask);
-
- /* Use the interrupt if possible */
- do {
- if (i2c->irq) {
- timeout = wait_for_completion_timeout(&wm8996->dcs_done,
- msecs_to_jiffies(200));
- if (timeout == 0)
- dev_err(codec->dev, "DC servo timed out\n");
-
- } else {
- msleep(1);
- timeout--;
- }
-
- ret = snd_soc_read(codec, WM8996_DC_SERVO_2);
- dev_dbg(codec->dev, "DC servo state: %x\n", ret);
- } while (timeout && ret & mask);
-
- if (timeout == 0)
- dev_err(codec->dev, "DC servo timed out for %x\n", mask);
- else
- dev_dbg(codec->dev, "DC servo complete for %x\n", mask);
-}
-
-static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm,
- enum snd_soc_dapm_type event, int subseq)
-{
- struct snd_soc_codec *codec = container_of(dapm,
- struct snd_soc_codec, dapm);
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
- u16 val, mask;
-
- /* Complete any pending DC servo starts */
- if (wm8996->dcs_pending) {
- dev_dbg(codec->dev, "Starting DC servo for %x\n",
- wm8996->dcs_pending);
-
- /* Trigger a startup sequence */
- wait_for_dc_servo(codec, wm8996->dcs_pending
- << WM8996_DCS_TRIG_STARTUP_0_SHIFT);
-
- wm8996->dcs_pending = 0;
- }
-
- if (wm8996->hpout_pending != wm8996->hpout_ena) {
- dev_dbg(codec->dev, "Applying RMV_SHORTs %x->%x\n",
- wm8996->hpout_ena, wm8996->hpout_pending);
-
- val = 0;
- mask = 0;
- if (wm8996->hpout_pending & HPOUT1L) {
- val |= WM8996_HPOUT1L_RMV_SHORT | WM8996_HPOUT1L_OUTP;
- mask |= WM8996_HPOUT1L_RMV_SHORT | WM8996_HPOUT1L_OUTP;
- } else {
- mask |= WM8996_HPOUT1L_RMV_SHORT |
- WM8996_HPOUT1L_OUTP |
- WM8996_HPOUT1L_DLY;
- }
-
- if (wm8996->hpout_pending & HPOUT1R) {
- val |= WM8996_HPOUT1R_RMV_SHORT | WM8996_HPOUT1R_OUTP;
- mask |= WM8996_HPOUT1R_RMV_SHORT | WM8996_HPOUT1R_OUTP;
- } else {
- mask |= WM8996_HPOUT1R_RMV_SHORT |
- WM8996_HPOUT1R_OUTP |
- WM8996_HPOUT1R_DLY;
- }
-
- snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_1, mask, val);
-
- val = 0;
- mask = 0;
- if (wm8996->hpout_pending & HPOUT2L) {
- val |= WM8996_HPOUT2L_RMV_SHORT | WM8996_HPOUT2L_OUTP;
- mask |= WM8996_HPOUT2L_RMV_SHORT | WM8996_HPOUT2L_OUTP;
- } else {
- mask |= WM8996_HPOUT2L_RMV_SHORT |
- WM8996_HPOUT2L_OUTP |
- WM8996_HPOUT2L_DLY;
- }
-
- if (wm8996->hpout_pending & HPOUT2R) {
- val |= WM8996_HPOUT2R_RMV_SHORT | WM8996_HPOUT2R_OUTP;
- mask |= WM8996_HPOUT2R_RMV_SHORT | WM8996_HPOUT2R_OUTP;
- } else {
- mask |= WM8996_HPOUT2R_RMV_SHORT |
- WM8996_HPOUT2R_OUTP |
- WM8996_HPOUT2R_DLY;
- }
-
- snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_2, mask, val);
-
- wm8996->hpout_ena = wm8996->hpout_pending;
- }
-}
-
-static int dcs_start(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(w->codec);
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- wm8996->dcs_pending |= 1 << w->shift;
- break;
- default:
- BUG();
- return -EINVAL;
- }
-
- return 0;
-}
-
-static const char *sidetone_text[] = {
- "IN1", "IN2",
-};
-
-static const struct soc_enum left_sidetone_enum =
- SOC_ENUM_SINGLE(WM8996_SIDETONE, 0, 2, sidetone_text);
-
-static const struct snd_kcontrol_new left_sidetone =
- SOC_DAPM_ENUM("Left Sidetone", left_sidetone_enum);
-
-static const struct soc_enum right_sidetone_enum =
- SOC_ENUM_SINGLE(WM8996_SIDETONE, 1, 2, sidetone_text);
-
-static const struct snd_kcontrol_new right_sidetone =
- SOC_DAPM_ENUM("Right Sidetone", right_sidetone_enum);
-
-static const char *spk_text[] = {
- "DAC1L", "DAC1R", "DAC2L", "DAC2R"
-};
-
-static const struct soc_enum spkl_enum =
- SOC_ENUM_SINGLE(WM8996_LEFT_PDM_SPEAKER, 0, 4, spk_text);
-
-static const struct snd_kcontrol_new spkl_mux =
- SOC_DAPM_ENUM("SPKL", spkl_enum);
-
-static const struct soc_enum spkr_enum =
- SOC_ENUM_SINGLE(WM8996_RIGHT_PDM_SPEAKER, 0, 4, spk_text);
-
-static const struct snd_kcontrol_new spkr_mux =
- SOC_DAPM_ENUM("SPKR", spkr_enum);
-
-static const char *dsp1rx_text[] = {
- "AIF1", "AIF2"
-};
-
-static const struct soc_enum dsp1rx_enum =
- SOC_ENUM_SINGLE(WM8996_POWER_MANAGEMENT_8, 0, 2, dsp1rx_text);
-
-static const struct snd_kcontrol_new dsp1rx =
- SOC_DAPM_ENUM("DSP1RX", dsp1rx_enum);
-
-static const char *dsp2rx_text[] = {
- "AIF2", "AIF1"
-};
-
-static const struct soc_enum dsp2rx_enum =
- SOC_ENUM_SINGLE(WM8996_POWER_MANAGEMENT_8, 4, 2, dsp2rx_text);
-
-static const struct snd_kcontrol_new dsp2rx =
- SOC_DAPM_ENUM("DSP2RX", dsp2rx_enum);
-
-static const char *aif2tx_text[] = {
- "DSP2", "DSP1", "AIF1"
-};
-
-static const struct soc_enum aif2tx_enum =
- SOC_ENUM_SINGLE(WM8996_POWER_MANAGEMENT_8, 6, 3, aif2tx_text);
-
-static const struct snd_kcontrol_new aif2tx =
- SOC_DAPM_ENUM("AIF2TX", aif2tx_enum);
-
-static const char *inmux_text[] = {
- "ADC", "DMIC1", "DMIC2"
-};
-
-static const struct soc_enum in1_enum =
- SOC_ENUM_SINGLE(WM8996_POWER_MANAGEMENT_7, 0, 3, inmux_text);
-
-static const struct snd_kcontrol_new in1_mux =
- SOC_DAPM_ENUM("IN1 Mux", in1_enum);
-
-static const struct soc_enum in2_enum =
- SOC_ENUM_SINGLE(WM8996_POWER_MANAGEMENT_7, 4, 3, inmux_text);
-
-static const struct snd_kcontrol_new in2_mux =
- SOC_DAPM_ENUM("IN2 Mux", in2_enum);
-
-static const struct snd_kcontrol_new dac2r_mix[] = {
-SOC_DAPM_SINGLE("Right Sidetone Switch", WM8996_DAC2_RIGHT_MIXER_ROUTING,
- 5, 1, 0),
-SOC_DAPM_SINGLE("Left Sidetone Switch", WM8996_DAC2_RIGHT_MIXER_ROUTING,
- 4, 1, 0),
-SOC_DAPM_SINGLE("DSP2 Switch", WM8996_DAC2_RIGHT_MIXER_ROUTING, 1, 1, 0),
-SOC_DAPM_SINGLE("DSP1 Switch", WM8996_DAC2_RIGHT_MIXER_ROUTING, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new dac2l_mix[] = {
-SOC_DAPM_SINGLE("Right Sidetone Switch", WM8996_DAC2_LEFT_MIXER_ROUTING,
- 5, 1, 0),
-SOC_DAPM_SINGLE("Left Sidetone Switch", WM8996_DAC2_LEFT_MIXER_ROUTING,
- 4, 1, 0),
-SOC_DAPM_SINGLE("DSP2 Switch", WM8996_DAC2_LEFT_MIXER_ROUTING, 1, 1, 0),
-SOC_DAPM_SINGLE("DSP1 Switch", WM8996_DAC2_LEFT_MIXER_ROUTING, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new dac1r_mix[] = {
-SOC_DAPM_SINGLE("Right Sidetone Switch", WM8996_DAC1_RIGHT_MIXER_ROUTING,
- 5, 1, 0),
-SOC_DAPM_SINGLE("Left Sidetone Switch", WM8996_DAC1_RIGHT_MIXER_ROUTING,
- 4, 1, 0),
-SOC_DAPM_SINGLE("DSP2 Switch", WM8996_DAC1_RIGHT_MIXER_ROUTING, 1, 1, 0),
-SOC_DAPM_SINGLE("DSP1 Switch", WM8996_DAC1_RIGHT_MIXER_ROUTING, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new dac1l_mix[] = {
-SOC_DAPM_SINGLE("Right Sidetone Switch", WM8996_DAC1_LEFT_MIXER_ROUTING,
- 5, 1, 0),
-SOC_DAPM_SINGLE("Left Sidetone Switch", WM8996_DAC1_LEFT_MIXER_ROUTING,
- 4, 1, 0),
-SOC_DAPM_SINGLE("DSP2 Switch", WM8996_DAC1_LEFT_MIXER_ROUTING, 1, 1, 0),
-SOC_DAPM_SINGLE("DSP1 Switch", WM8996_DAC1_LEFT_MIXER_ROUTING, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new dsp1txl[] = {
-SOC_DAPM_SINGLE("IN1 Switch", WM8996_DSP1_TX_LEFT_MIXER_ROUTING,
- 1, 1, 0),
-SOC_DAPM_SINGLE("DAC Switch", WM8996_DSP1_TX_LEFT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new dsp1txr[] = {
-SOC_DAPM_SINGLE("IN1 Switch", WM8996_DSP1_TX_RIGHT_MIXER_ROUTING,
- 1, 1, 0),
-SOC_DAPM_SINGLE("DAC Switch", WM8996_DSP1_TX_RIGHT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new dsp2txl[] = {
-SOC_DAPM_SINGLE("IN1 Switch", WM8996_DSP2_TX_LEFT_MIXER_ROUTING,
- 1, 1, 0),
-SOC_DAPM_SINGLE("DAC Switch", WM8996_DSP2_TX_LEFT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new dsp2txr[] = {
-SOC_DAPM_SINGLE("IN1 Switch", WM8996_DSP2_TX_RIGHT_MIXER_ROUTING,
- 1, 1, 0),
-SOC_DAPM_SINGLE("DAC Switch", WM8996_DSP2_TX_RIGHT_MIXER_ROUTING,
- 0, 1, 0),
-};
-
-
-static const struct snd_soc_dapm_widget wm8996_dapm_widgets[] = {
-SND_SOC_DAPM_INPUT("IN1LN"),
-SND_SOC_DAPM_INPUT("IN1LP"),
-SND_SOC_DAPM_INPUT("IN1RN"),
-SND_SOC_DAPM_INPUT("IN1RP"),
-
-SND_SOC_DAPM_INPUT("IN2LN"),
-SND_SOC_DAPM_INPUT("IN2LP"),
-SND_SOC_DAPM_INPUT("IN2RN"),
-SND_SOC_DAPM_INPUT("IN2RP"),
-
-SND_SOC_DAPM_INPUT("DMIC1DAT"),
-SND_SOC_DAPM_INPUT("DMIC2DAT"),
-
-SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
-SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event,
- SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_SUPPLY("Bandgap", SND_SOC_NOPM, 0, 0, bg_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("MICB1 Audio", WM8996_MICBIAS_1, 4, 1, NULL, 0),
-SND_SOC_DAPM_SUPPLY("MICB2 Audio", WM8996_MICBIAS_2, 4, 1, NULL, 0),
-SND_SOC_DAPM_MICBIAS("MICB2", WM8996_POWER_MANAGEMENT_1, 9, 0),
-SND_SOC_DAPM_MICBIAS("MICB1", WM8996_POWER_MANAGEMENT_1, 8, 0),
-
-SND_SOC_DAPM_PGA("IN1L PGA", WM8996_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA("IN1R PGA", WM8996_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
-
-SND_SOC_DAPM_MUX("IN1L Mux", WM8996_POWER_MANAGEMENT_7, 2, 0, &in1_mux),
-SND_SOC_DAPM_MUX("IN1R Mux", WM8996_POWER_MANAGEMENT_7, 3, 0, &in1_mux),
-SND_SOC_DAPM_MUX("IN2L Mux", WM8996_POWER_MANAGEMENT_7, 6, 0, &in2_mux),
-SND_SOC_DAPM_MUX("IN2R Mux", WM8996_POWER_MANAGEMENT_7, 7, 0, &in2_mux),
-
-SND_SOC_DAPM_SUPPLY("DMIC2", WM8996_POWER_MANAGEMENT_7, 9, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("DMIC1", WM8996_POWER_MANAGEMENT_7, 8, 0, NULL, 0),
-
-SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8996_POWER_MANAGEMENT_3, 5, 0),
-SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8996_POWER_MANAGEMENT_3, 4, 0),
-SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8996_POWER_MANAGEMENT_3, 3, 0),
-SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8996_POWER_MANAGEMENT_3, 2, 0),
-
-SND_SOC_DAPM_ADC("ADCL", NULL, WM8996_POWER_MANAGEMENT_3, 1, 0),
-SND_SOC_DAPM_ADC("ADCR", NULL, WM8996_POWER_MANAGEMENT_3, 0, 0),
-
-SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &left_sidetone),
-SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &right_sidetone),
-
-SND_SOC_DAPM_AIF_IN("DSP2RXL", NULL, 0, WM8996_POWER_MANAGEMENT_3, 11, 0),
-SND_SOC_DAPM_AIF_IN("DSP2RXR", NULL, 1, WM8996_POWER_MANAGEMENT_3, 10, 0),
-SND_SOC_DAPM_AIF_IN("DSP1RXL", NULL, 0, WM8996_POWER_MANAGEMENT_3, 9, 0),
-SND_SOC_DAPM_AIF_IN("DSP1RXR", NULL, 1, WM8996_POWER_MANAGEMENT_3, 8, 0),
-
-SND_SOC_DAPM_MIXER("DSP2TXL", WM8996_POWER_MANAGEMENT_5, 11, 0,
- dsp2txl, ARRAY_SIZE(dsp2txl)),
-SND_SOC_DAPM_MIXER("DSP2TXR", WM8996_POWER_MANAGEMENT_5, 10, 0,
- dsp2txr, ARRAY_SIZE(dsp2txr)),
-SND_SOC_DAPM_MIXER("DSP1TXL", WM8996_POWER_MANAGEMENT_5, 9, 0,
- dsp1txl, ARRAY_SIZE(dsp1txl)),
-SND_SOC_DAPM_MIXER("DSP1TXR", WM8996_POWER_MANAGEMENT_5, 8, 0,
- dsp1txr, ARRAY_SIZE(dsp1txr)),
-
-SND_SOC_DAPM_MIXER("DAC2L Mixer", SND_SOC_NOPM, 0, 0,
- dac2l_mix, ARRAY_SIZE(dac2l_mix)),
-SND_SOC_DAPM_MIXER("DAC2R Mixer", SND_SOC_NOPM, 0, 0,
- dac2r_mix, ARRAY_SIZE(dac2r_mix)),
-SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0,
- dac1l_mix, ARRAY_SIZE(dac1l_mix)),
-SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0,
- dac1r_mix, ARRAY_SIZE(dac1r_mix)),
-
-SND_SOC_DAPM_DAC("DAC2L", NULL, WM8996_POWER_MANAGEMENT_5, 3, 0),
-SND_SOC_DAPM_DAC("DAC2R", NULL, WM8996_POWER_MANAGEMENT_5, 2, 0),
-SND_SOC_DAPM_DAC("DAC1L", NULL, WM8996_POWER_MANAGEMENT_5, 1, 0),
-SND_SOC_DAPM_DAC("DAC1R", NULL, WM8996_POWER_MANAGEMENT_5, 0, 0),
-
-SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0, WM8996_POWER_MANAGEMENT_4, 9, 0),
-SND_SOC_DAPM_AIF_IN("AIF2RX0", NULL, 1, WM8996_POWER_MANAGEMENT_4, 8, 0),
-
-SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0, WM8996_POWER_MANAGEMENT_6, 9, 0),
-SND_SOC_DAPM_AIF_OUT("AIF2TX0", NULL, 1, WM8996_POWER_MANAGEMENT_6, 8, 0),
-
-SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 5, WM8996_POWER_MANAGEMENT_4, 5, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 4, WM8996_POWER_MANAGEMENT_4, 4, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 3, WM8996_POWER_MANAGEMENT_4, 3, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 2, WM8996_POWER_MANAGEMENT_4, 2, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 1, WM8996_POWER_MANAGEMENT_4, 1, 0),
-SND_SOC_DAPM_AIF_IN("AIF1RX0", NULL, 0, WM8996_POWER_MANAGEMENT_4, 0, 0),
-
-SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 5, WM8996_POWER_MANAGEMENT_6, 5, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 4, WM8996_POWER_MANAGEMENT_6, 4, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 3, WM8996_POWER_MANAGEMENT_6, 3, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 2, WM8996_POWER_MANAGEMENT_6, 2, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 1, WM8996_POWER_MANAGEMENT_6, 1, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1TX0", NULL, 0, WM8996_POWER_MANAGEMENT_6, 0, 0),
-
-/* We route as stereo pairs so define some dummy widgets to squash
- * things down for now. RXA = 0,1, RXB = 2,3 and so on */
-SND_SOC_DAPM_PGA("AIF1RXA", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_PGA("AIF1RXB", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_PGA("AIF1RXC", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_PGA("AIF2RX", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_PGA("DSP2TX", SND_SOC_NOPM, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_MUX("DSP1RX", SND_SOC_NOPM, 0, 0, &dsp1rx),
-SND_SOC_DAPM_MUX("DSP2RX", SND_SOC_NOPM, 0, 0, &dsp2rx),
-SND_SOC_DAPM_MUX("AIF2TX", SND_SOC_NOPM, 0, 0, &aif2tx),
-
-SND_SOC_DAPM_MUX("SPKL", SND_SOC_NOPM, 0, 0, &spkl_mux),
-SND_SOC_DAPM_MUX("SPKR", SND_SOC_NOPM, 0, 0, &spkr_mux),
-SND_SOC_DAPM_PGA("SPKL PGA", WM8996_LEFT_PDM_SPEAKER, 4, 0, NULL, 0),
-SND_SOC_DAPM_PGA("SPKR PGA", WM8996_RIGHT_PDM_SPEAKER, 4, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA_S("HPOUT2L PGA", 0, WM8996_POWER_MANAGEMENT_1, 7, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPOUT2L_DLY", 1, WM8996_ANALOGUE_HP_2, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPOUT2L_DCS", 2, WM8996_DC_SERVO_1, 2, 0, dcs_start,
- SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_S("HPOUT2L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2L, 0,
- rmv_short_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
-
-SND_SOC_DAPM_PGA_S("HPOUT2R PGA", 0, WM8996_POWER_MANAGEMENT_1, 6, 0,NULL, 0),
-SND_SOC_DAPM_PGA_S("HPOUT2R_DLY", 1, WM8996_ANALOGUE_HP_2, 1, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPOUT2R_DCS", 2, WM8996_DC_SERVO_1, 3, 0, dcs_start,
- SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_S("HPOUT2R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2R, 0,
- rmv_short_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
-
-SND_SOC_DAPM_PGA_S("HPOUT1L PGA", 0, WM8996_POWER_MANAGEMENT_1, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPOUT1L_DLY", 1, WM8996_ANALOGUE_HP_1, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPOUT1L_DCS", 2, WM8996_DC_SERVO_1, 0, 0, dcs_start,
- SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_S("HPOUT1L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1L, 0,
- rmv_short_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
-
-SND_SOC_DAPM_PGA_S("HPOUT1R PGA", 0, WM8996_POWER_MANAGEMENT_1, 4, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPOUT1R_DLY", 1, WM8996_ANALOGUE_HP_1, 1, 0, NULL, 0),
-SND_SOC_DAPM_PGA_S("HPOUT1R_DCS", 2, WM8996_DC_SERVO_1, 1, 0, dcs_start,
- SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_S("HPOUT1R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1R, 0,
- rmv_short_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
-
-SND_SOC_DAPM_OUTPUT("HPOUT1L"),
-SND_SOC_DAPM_OUTPUT("HPOUT1R"),
-SND_SOC_DAPM_OUTPUT("HPOUT2L"),
-SND_SOC_DAPM_OUTPUT("HPOUT2R"),
-SND_SOC_DAPM_OUTPUT("SPKDAT"),
-};
-
-static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
- { "AIFCLK", NULL, "SYSCLK" },
- { "SYSDSPCLK", NULL, "SYSCLK" },
- { "Charge Pump", NULL, "SYSCLK" },
- { "Charge Pump", NULL, "CPVDD" },
-
- { "MICB1", NULL, "LDO2" },
- { "MICB1", NULL, "MICB1 Audio" },
- { "MICB1", NULL, "Bandgap" },
- { "MICB2", NULL, "LDO2" },
- { "MICB2", NULL, "MICB2 Audio" },
- { "MICB2", NULL, "Bandgap" },
-
- { "AIF1RX0", NULL, "AIF1 Playback" },
- { "AIF1RX1", NULL, "AIF1 Playback" },
- { "AIF1RX2", NULL, "AIF1 Playback" },
- { "AIF1RX3", NULL, "AIF1 Playback" },
- { "AIF1RX4", NULL, "AIF1 Playback" },
- { "AIF1RX5", NULL, "AIF1 Playback" },
-
- { "AIF2RX0", NULL, "AIF2 Playback" },
- { "AIF2RX1", NULL, "AIF2 Playback" },
-
- { "AIF1 Capture", NULL, "AIF1TX0" },
- { "AIF1 Capture", NULL, "AIF1TX1" },
- { "AIF1 Capture", NULL, "AIF1TX2" },
- { "AIF1 Capture", NULL, "AIF1TX3" },
- { "AIF1 Capture", NULL, "AIF1TX4" },
- { "AIF1 Capture", NULL, "AIF1TX5" },
-
- { "AIF2 Capture", NULL, "AIF2TX0" },
- { "AIF2 Capture", NULL, "AIF2TX1" },
-
- { "IN1L PGA", NULL, "IN2LN" },
- { "IN1L PGA", NULL, "IN2LP" },
- { "IN1L PGA", NULL, "IN1LN" },
- { "IN1L PGA", NULL, "IN1LP" },
- { "IN1L PGA", NULL, "Bandgap" },
-
- { "IN1R PGA", NULL, "IN2RN" },
- { "IN1R PGA", NULL, "IN2RP" },
- { "IN1R PGA", NULL, "IN1RN" },
- { "IN1R PGA", NULL, "IN1RP" },
- { "IN1R PGA", NULL, "Bandgap" },
-
- { "ADCL", NULL, "IN1L PGA" },
-
- { "ADCR", NULL, "IN1R PGA" },
-
- { "DMIC1L", NULL, "DMIC1DAT" },
- { "DMIC1R", NULL, "DMIC1DAT" },
- { "DMIC2L", NULL, "DMIC2DAT" },
- { "DMIC2R", NULL, "DMIC2DAT" },
-
- { "DMIC2L", NULL, "DMIC2" },
- { "DMIC2R", NULL, "DMIC2" },
- { "DMIC1L", NULL, "DMIC1" },
- { "DMIC1R", NULL, "DMIC1" },
-
- { "IN1L Mux", "ADC", "ADCL" },
- { "IN1L Mux", "DMIC1", "DMIC1L" },
- { "IN1L Mux", "DMIC2", "DMIC2L" },
-
- { "IN1R Mux", "ADC", "ADCR" },
- { "IN1R Mux", "DMIC1", "DMIC1R" },
- { "IN1R Mux", "DMIC2", "DMIC2R" },
-
- { "IN2L Mux", "ADC", "ADCL" },
- { "IN2L Mux", "DMIC1", "DMIC1L" },
- { "IN2L Mux", "DMIC2", "DMIC2L" },
-
- { "IN2R Mux", "ADC", "ADCR" },
- { "IN2R Mux", "DMIC1", "DMIC1R" },
- { "IN2R Mux", "DMIC2", "DMIC2R" },
-
- { "Left Sidetone", "IN1", "IN1L Mux" },
- { "Left Sidetone", "IN2", "IN2L Mux" },
-
- { "Right Sidetone", "IN1", "IN1R Mux" },
- { "Right Sidetone", "IN2", "IN2R Mux" },
-
- { "DSP1TXL", "IN1 Switch", "IN1L Mux" },
- { "DSP1TXR", "IN1 Switch", "IN1R Mux" },
-
- { "DSP2TXL", "IN1 Switch", "IN2L Mux" },
- { "DSP2TXR", "IN1 Switch", "IN2R Mux" },
-
- { "AIF1TX0", NULL, "DSP1TXL" },
- { "AIF1TX1", NULL, "DSP1TXR" },
- { "AIF1TX2", NULL, "DSP2TXL" },
- { "AIF1TX3", NULL, "DSP2TXR" },
- { "AIF1TX4", NULL, "AIF2RX0" },
- { "AIF1TX5", NULL, "AIF2RX1" },
-
- { "AIF1RX0", NULL, "AIFCLK" },
- { "AIF1RX1", NULL, "AIFCLK" },
- { "AIF1RX2", NULL, "AIFCLK" },
- { "AIF1RX3", NULL, "AIFCLK" },
- { "AIF1RX4", NULL, "AIFCLK" },
- { "AIF1RX5", NULL, "AIFCLK" },
-
- { "AIF2RX0", NULL, "AIFCLK" },
- { "AIF2RX1", NULL, "AIFCLK" },
-
- { "AIF1TX0", NULL, "AIFCLK" },
- { "AIF1TX1", NULL, "AIFCLK" },
- { "AIF1TX2", NULL, "AIFCLK" },
- { "AIF1TX3", NULL, "AIFCLK" },
- { "AIF1TX4", NULL, "AIFCLK" },
- { "AIF1TX5", NULL, "AIFCLK" },
-
- { "AIF2TX0", NULL, "AIFCLK" },
- { "AIF2TX1", NULL, "AIFCLK" },
-
- { "DSP1RXL", NULL, "SYSDSPCLK" },
- { "DSP1RXR", NULL, "SYSDSPCLK" },
- { "DSP2RXL", NULL, "SYSDSPCLK" },
- { "DSP2RXR", NULL, "SYSDSPCLK" },
- { "DSP1TXL", NULL, "SYSDSPCLK" },
- { "DSP1TXR", NULL, "SYSDSPCLK" },
- { "DSP2TXL", NULL, "SYSDSPCLK" },
- { "DSP2TXR", NULL, "SYSDSPCLK" },
-
- { "AIF1RXA", NULL, "AIF1RX0" },
- { "AIF1RXA", NULL, "AIF1RX1" },
- { "AIF1RXB", NULL, "AIF1RX2" },
- { "AIF1RXB", NULL, "AIF1RX3" },
- { "AIF1RXC", NULL, "AIF1RX4" },
- { "AIF1RXC", NULL, "AIF1RX5" },
-
- { "AIF2RX", NULL, "AIF2RX0" },
- { "AIF2RX", NULL, "AIF2RX1" },
-
- { "AIF2TX", "DSP2", "DSP2TX" },
- { "AIF2TX", "DSP1", "DSP1RX" },
- { "AIF2TX", "AIF1", "AIF1RXC" },
-
- { "DSP1RXL", NULL, "DSP1RX" },
- { "DSP1RXR", NULL, "DSP1RX" },
- { "DSP2RXL", NULL, "DSP2RX" },
- { "DSP2RXR", NULL, "DSP2RX" },
-
- { "DSP2TX", NULL, "DSP2TXL" },
- { "DSP2TX", NULL, "DSP2TXR" },
-
- { "DSP1RX", "AIF1", "AIF1RXA" },
- { "DSP1RX", "AIF2", "AIF2RX" },
-
- { "DSP2RX", "AIF1", "AIF1RXB" },
- { "DSP2RX", "AIF2", "AIF2RX" },
-
- { "DAC2L Mixer", "DSP2 Switch", "DSP2RXL" },
- { "DAC2L Mixer", "DSP1 Switch", "DSP1RXL" },
- { "DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" },
- { "DAC2L Mixer", "Left Sidetone Switch", "Left Sidetone" },
-
- { "DAC2R Mixer", "DSP2 Switch", "DSP2RXR" },
- { "DAC2R Mixer", "DSP1 Switch", "DSP1RXR" },
- { "DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" },
- { "DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" },
-
- { "DAC1L Mixer", "DSP2 Switch", "DSP2RXL" },
- { "DAC1L Mixer", "DSP1 Switch", "DSP1RXL" },
- { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
- { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
-
- { "DAC1R Mixer", "DSP2 Switch", "DSP2RXR" },
- { "DAC1R Mixer", "DSP1 Switch", "DSP1RXR" },
- { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" },
- { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" },
-
- { "DAC1L", NULL, "DAC1L Mixer" },
- { "DAC1R", NULL, "DAC1R Mixer" },
- { "DAC2L", NULL, "DAC2L Mixer" },
- { "DAC2R", NULL, "DAC2R Mixer" },
-
- { "HPOUT2L PGA", NULL, "Charge Pump" },
- { "HPOUT2L PGA", NULL, "Bandgap" },
- { "HPOUT2L PGA", NULL, "DAC2L" },
- { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" },
- { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" },
- { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_DCS" },
-
- { "HPOUT2R PGA", NULL, "Charge Pump" },
- { "HPOUT2R PGA", NULL, "Bandgap" },
- { "HPOUT2R PGA", NULL, "DAC2R" },
- { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" },
- { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" },
- { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_DCS" },
-
- { "HPOUT1L PGA", NULL, "Charge Pump" },
- { "HPOUT1L PGA", NULL, "Bandgap" },
- { "HPOUT1L PGA", NULL, "DAC1L" },
- { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" },
- { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" },
- { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_DCS" },
-
- { "HPOUT1R PGA", NULL, "Charge Pump" },
- { "HPOUT1R PGA", NULL, "Bandgap" },
- { "HPOUT1R PGA", NULL, "DAC1R" },
- { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" },
- { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" },
- { "HPOUT1R_RMV_SHORT", NULL, "HPOUT1R_DCS" },
-
- { "HPOUT2L", NULL, "HPOUT2L_RMV_SHORT" },
- { "HPOUT2R", NULL, "HPOUT2R_RMV_SHORT" },
- { "HPOUT1L", NULL, "HPOUT1L_RMV_SHORT" },
- { "HPOUT1R", NULL, "HPOUT1R_RMV_SHORT" },
-
- { "SPKL", "DAC1L", "DAC1L" },
- { "SPKL", "DAC1R", "DAC1R" },
- { "SPKL", "DAC2L", "DAC2L" },
- { "SPKL", "DAC2R", "DAC2R" },
-
- { "SPKR", "DAC1L", "DAC1L" },
- { "SPKR", "DAC1R", "DAC1R" },
- { "SPKR", "DAC2L", "DAC2L" },
- { "SPKR", "DAC2R", "DAC2R" },
-
- { "SPKL PGA", NULL, "SPKL" },
- { "SPKR PGA", NULL, "SPKR" },
-
- { "SPKDAT", NULL, "SPKL PGA" },
- { "SPKDAT", NULL, "SPKR PGA" },
-};
-
-static bool wm8996_readable_register(struct device *dev, unsigned int reg)
-{
- /* Due to the sparseness of the register map the compiler
- * output from an explicit switch statement ends up being much
- * more efficient than a table.
- */
- switch (reg) {
- case WM8996_SOFTWARE_RESET:
- case WM8996_POWER_MANAGEMENT_1:
- case WM8996_POWER_MANAGEMENT_2:
- case WM8996_POWER_MANAGEMENT_3:
- case WM8996_POWER_MANAGEMENT_4:
- case WM8996_POWER_MANAGEMENT_5:
- case WM8996_POWER_MANAGEMENT_6:
- case WM8996_POWER_MANAGEMENT_7:
- case WM8996_POWER_MANAGEMENT_8:
- case WM8996_LEFT_LINE_INPUT_VOLUME:
- case WM8996_RIGHT_LINE_INPUT_VOLUME:
- case WM8996_LINE_INPUT_CONTROL:
- case WM8996_DAC1_HPOUT1_VOLUME:
- case WM8996_DAC2_HPOUT2_VOLUME:
- case WM8996_DAC1_LEFT_VOLUME:
- case WM8996_DAC1_RIGHT_VOLUME:
- case WM8996_DAC2_LEFT_VOLUME:
- case WM8996_DAC2_RIGHT_VOLUME:
- case WM8996_OUTPUT1_LEFT_VOLUME:
- case WM8996_OUTPUT1_RIGHT_VOLUME:
- case WM8996_OUTPUT2_LEFT_VOLUME:
- case WM8996_OUTPUT2_RIGHT_VOLUME:
- case WM8996_MICBIAS_1:
- case WM8996_MICBIAS_2:
- case WM8996_LDO_1:
- case WM8996_LDO_2:
- case WM8996_ACCESSORY_DETECT_MODE_1:
- case WM8996_ACCESSORY_DETECT_MODE_2:
- case WM8996_HEADPHONE_DETECT_1:
- case WM8996_HEADPHONE_DETECT_2:
- case WM8996_MIC_DETECT_1:
- case WM8996_MIC_DETECT_2:
- case WM8996_MIC_DETECT_3:
- case WM8996_CHARGE_PUMP_1:
- case WM8996_CHARGE_PUMP_2:
- case WM8996_DC_SERVO_1:
- case WM8996_DC_SERVO_2:
- case WM8996_DC_SERVO_3:
- case WM8996_DC_SERVO_5:
- case WM8996_DC_SERVO_6:
- case WM8996_DC_SERVO_7:
- case WM8996_DC_SERVO_READBACK_0:
- case WM8996_ANALOGUE_HP_1:
- case WM8996_ANALOGUE_HP_2:
- case WM8996_CHIP_REVISION:
- case WM8996_CONTROL_INTERFACE_1:
- case WM8996_WRITE_SEQUENCER_CTRL_1:
- case WM8996_WRITE_SEQUENCER_CTRL_2:
- case WM8996_AIF_CLOCKING_1:
- case WM8996_AIF_CLOCKING_2:
- case WM8996_CLOCKING_1:
- case WM8996_CLOCKING_2:
- case WM8996_AIF_RATE:
- case WM8996_FLL_CONTROL_1:
- case WM8996_FLL_CONTROL_2:
- case WM8996_FLL_CONTROL_3:
- case WM8996_FLL_CONTROL_4:
- case WM8996_FLL_CONTROL_5:
- case WM8996_FLL_CONTROL_6:
- case WM8996_FLL_EFS_1:
- case WM8996_FLL_EFS_2:
- case WM8996_AIF1_CONTROL:
- case WM8996_AIF1_BCLK:
- case WM8996_AIF1_TX_LRCLK_1:
- case WM8996_AIF1_TX_LRCLK_2:
- case WM8996_AIF1_RX_LRCLK_1:
- case WM8996_AIF1_RX_LRCLK_2:
- case WM8996_AIF1TX_DATA_CONFIGURATION_1:
- case WM8996_AIF1TX_DATA_CONFIGURATION_2:
- case WM8996_AIF1RX_DATA_CONFIGURATION:
- case WM8996_AIF1TX_CHANNEL_0_CONFIGURATION:
- case WM8996_AIF1TX_CHANNEL_1_CONFIGURATION:
- case WM8996_AIF1TX_CHANNEL_2_CONFIGURATION:
- case WM8996_AIF1TX_CHANNEL_3_CONFIGURATION:
- case WM8996_AIF1TX_CHANNEL_4_CONFIGURATION:
- case WM8996_AIF1TX_CHANNEL_5_CONFIGURATION:
- case WM8996_AIF1RX_CHANNEL_0_CONFIGURATION:
- case WM8996_AIF1RX_CHANNEL_1_CONFIGURATION:
- case WM8996_AIF1RX_CHANNEL_2_CONFIGURATION:
- case WM8996_AIF1RX_CHANNEL_3_CONFIGURATION:
- case WM8996_AIF1RX_CHANNEL_4_CONFIGURATION:
- case WM8996_AIF1RX_CHANNEL_5_CONFIGURATION:
- case WM8996_AIF1RX_MONO_CONFIGURATION:
- case WM8996_AIF1TX_TEST:
- case WM8996_AIF2_CONTROL:
- case WM8996_AIF2_BCLK:
- case WM8996_AIF2_TX_LRCLK_1:
- case WM8996_AIF2_TX_LRCLK_2:
- case WM8996_AIF2_RX_LRCLK_1:
- case WM8996_AIF2_RX_LRCLK_2:
- case WM8996_AIF2TX_DATA_CONFIGURATION_1:
- case WM8996_AIF2TX_DATA_CONFIGURATION_2:
- case WM8996_AIF2RX_DATA_CONFIGURATION:
- case WM8996_AIF2TX_CHANNEL_0_CONFIGURATION:
- case WM8996_AIF2TX_CHANNEL_1_CONFIGURATION:
- case WM8996_AIF2RX_CHANNEL_0_CONFIGURATION:
- case WM8996_AIF2RX_CHANNEL_1_CONFIGURATION:
- case WM8996_AIF2RX_MONO_CONFIGURATION:
- case WM8996_AIF2TX_TEST:
- case WM8996_DSP1_TX_LEFT_VOLUME:
- case WM8996_DSP1_TX_RIGHT_VOLUME:
- case WM8996_DSP1_RX_LEFT_VOLUME:
- case WM8996_DSP1_RX_RIGHT_VOLUME:
- case WM8996_DSP1_TX_FILTERS:
- case WM8996_DSP1_RX_FILTERS_1:
- case WM8996_DSP1_RX_FILTERS_2:
- case WM8996_DSP1_DRC_1:
- case WM8996_DSP1_DRC_2:
- case WM8996_DSP1_DRC_3:
- case WM8996_DSP1_DRC_4:
- case WM8996_DSP1_DRC_5:
- case WM8996_DSP1_RX_EQ_GAINS_1:
- case WM8996_DSP1_RX_EQ_GAINS_2:
- case WM8996_DSP1_RX_EQ_BAND_1_A:
- case WM8996_DSP1_RX_EQ_BAND_1_B:
- case WM8996_DSP1_RX_EQ_BAND_1_PG:
- case WM8996_DSP1_RX_EQ_BAND_2_A:
- case WM8996_DSP1_RX_EQ_BAND_2_B:
- case WM8996_DSP1_RX_EQ_BAND_2_C:
- case WM8996_DSP1_RX_EQ_BAND_2_PG:
- case WM8996_DSP1_RX_EQ_BAND_3_A:
- case WM8996_DSP1_RX_EQ_BAND_3_B:
- case WM8996_DSP1_RX_EQ_BAND_3_C:
- case WM8996_DSP1_RX_EQ_BAND_3_PG:
- case WM8996_DSP1_RX_EQ_BAND_4_A:
- case WM8996_DSP1_RX_EQ_BAND_4_B:
- case WM8996_DSP1_RX_EQ_BAND_4_C:
- case WM8996_DSP1_RX_EQ_BAND_4_PG:
- case WM8996_DSP1_RX_EQ_BAND_5_A:
- case WM8996_DSP1_RX_EQ_BAND_5_B:
- case WM8996_DSP1_RX_EQ_BAND_5_PG:
- case WM8996_DSP2_TX_LEFT_VOLUME:
- case WM8996_DSP2_TX_RIGHT_VOLUME:
- case WM8996_DSP2_RX_LEFT_VOLUME:
- case WM8996_DSP2_RX_RIGHT_VOLUME:
- case WM8996_DSP2_TX_FILTERS:
- case WM8996_DSP2_RX_FILTERS_1:
- case WM8996_DSP2_RX_FILTERS_2:
- case WM8996_DSP2_DRC_1:
- case WM8996_DSP2_DRC_2:
- case WM8996_DSP2_DRC_3:
- case WM8996_DSP2_DRC_4:
- case WM8996_DSP2_DRC_5:
- case WM8996_DSP2_RX_EQ_GAINS_1:
- case WM8996_DSP2_RX_EQ_GAINS_2:
- case WM8996_DSP2_RX_EQ_BAND_1_A:
- case WM8996_DSP2_RX_EQ_BAND_1_B:
- case WM8996_DSP2_RX_EQ_BAND_1_PG:
- case WM8996_DSP2_RX_EQ_BAND_2_A:
- case WM8996_DSP2_RX_EQ_BAND_2_B:
- case WM8996_DSP2_RX_EQ_BAND_2_C:
- case WM8996_DSP2_RX_EQ_BAND_2_PG:
- case WM8996_DSP2_RX_EQ_BAND_3_A:
- case WM8996_DSP2_RX_EQ_BAND_3_B:
- case WM8996_DSP2_RX_EQ_BAND_3_C:
- case WM8996_DSP2_RX_EQ_BAND_3_PG:
- case WM8996_DSP2_RX_EQ_BAND_4_A:
- case WM8996_DSP2_RX_EQ_BAND_4_B:
- case WM8996_DSP2_RX_EQ_BAND_4_C:
- case WM8996_DSP2_RX_EQ_BAND_4_PG:
- case WM8996_DSP2_RX_EQ_BAND_5_A:
- case WM8996_DSP2_RX_EQ_BAND_5_B:
- case WM8996_DSP2_RX_EQ_BAND_5_PG:
- case WM8996_DAC1_MIXER_VOLUMES:
- case WM8996_DAC1_LEFT_MIXER_ROUTING:
- case WM8996_DAC1_RIGHT_MIXER_ROUTING:
- case WM8996_DAC2_MIXER_VOLUMES:
- case WM8996_DAC2_LEFT_MIXER_ROUTING:
- case WM8996_DAC2_RIGHT_MIXER_ROUTING:
- case WM8996_DSP1_TX_LEFT_MIXER_ROUTING:
- case WM8996_DSP1_TX_RIGHT_MIXER_ROUTING:
- case WM8996_DSP2_TX_LEFT_MIXER_ROUTING:
- case WM8996_DSP2_TX_RIGHT_MIXER_ROUTING:
- case WM8996_DSP_TX_MIXER_SELECT:
- case WM8996_DAC_SOFTMUTE:
- case WM8996_OVERSAMPLING:
- case WM8996_SIDETONE:
- case WM8996_GPIO_1:
- case WM8996_GPIO_2:
- case WM8996_GPIO_3:
- case WM8996_GPIO_4:
- case WM8996_GPIO_5:
- case WM8996_PULL_CONTROL_1:
- case WM8996_PULL_CONTROL_2:
- case WM8996_INTERRUPT_STATUS_1:
- case WM8996_INTERRUPT_STATUS_2:
- case WM8996_INTERRUPT_RAW_STATUS_2:
- case WM8996_INTERRUPT_STATUS_1_MASK:
- case WM8996_INTERRUPT_STATUS_2_MASK:
- case WM8996_INTERRUPT_CONTROL:
- case WM8996_LEFT_PDM_SPEAKER:
- case WM8996_RIGHT_PDM_SPEAKER:
- case WM8996_PDM_SPEAKER_MUTE_SEQUENCE:
- case WM8996_PDM_SPEAKER_VOLUME:
- return 1;
- default:
- return 0;
- }
-}
-
-static bool wm8996_volatile_register(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM8996_SOFTWARE_RESET:
- case WM8996_CHIP_REVISION:
- case WM8996_LDO_1:
- case WM8996_LDO_2:
- case WM8996_INTERRUPT_STATUS_1:
- case WM8996_INTERRUPT_STATUS_2:
- case WM8996_INTERRUPT_RAW_STATUS_2:
- case WM8996_DC_SERVO_READBACK_0:
- case WM8996_DC_SERVO_2:
- case WM8996_DC_SERVO_6:
- case WM8996_DC_SERVO_7:
- case WM8996_FLL_CONTROL_6:
- case WM8996_MIC_DETECT_3:
- case WM8996_HEADPHONE_DETECT_1:
- case WM8996_HEADPHONE_DETECT_2:
- return 1;
- default:
- return 0;
- }
-}
-
-static int wm8996_reset(struct wm8996_priv *wm8996)
-{
- if (wm8996->pdata.ldo_ena > 0) {
- gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
- gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1);
- return 0;
- } else {
- return regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET,
- 0x8915);
- }
-}
-
-static const int bclk_divs[] = {
- 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96
-};
-
-static void wm8996_update_bclk(struct snd_soc_codec *codec)
-{
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
- int aif, best, cur_val, bclk_rate, bclk_reg, i;
-
- /* Don't bother if we're in a low frequency idle mode that
- * can't support audio.
- */
- if (wm8996->sysclk < 64000)
- return;
-
- for (aif = 0; aif < WM8996_AIFS; aif++) {
- switch (aif) {
- case 0:
- bclk_reg = WM8996_AIF1_BCLK;
- break;
- case 1:
- bclk_reg = WM8996_AIF2_BCLK;
- break;
- }
-
- bclk_rate = wm8996->bclk_rate[aif];
-
- /* Pick a divisor for BCLK as close as we can get to ideal */
- best = 0;
- for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
- cur_val = (wm8996->sysclk / bclk_divs[i]) - bclk_rate;
- if (cur_val < 0) /* BCLK table is sorted */
- break;
- best = i;
- }
- bclk_rate = wm8996->sysclk / bclk_divs[best];
- dev_dbg(codec->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
- bclk_divs[best], bclk_rate);
-
- snd_soc_update_bits(codec, bclk_reg,
- WM8996_AIF1_BCLK_DIV_MASK, best);
- }
-}
-
-static int wm8996_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- case SND_SOC_BIAS_PREPARE:
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies),
- wm8996->supplies);
- if (ret != 0) {
- dev_err(codec->dev,
- "Failed to enable supplies: %d\n",
- ret);
- return ret;
- }
-
- if (wm8996->pdata.ldo_ena >= 0) {
- gpio_set_value_cansleep(wm8996->pdata.ldo_ena,
- 1);
- msleep(5);
- }
-
- regcache_cache_only(codec->control_data, false);
- regcache_sync(codec->control_data);
- }
- break;
-
- case SND_SOC_BIAS_OFF:
- regcache_cache_only(codec->control_data, true);
- if (wm8996->pdata.ldo_ena >= 0)
- gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
- regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies),
- wm8996->supplies);
- break;
- }
-
- codec->dapm.bias_level = level;
-
- return 0;
-}
-
-static int wm8996_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = dai->codec;
- int aifctrl = 0;
- int bclk = 0;
- int lrclk_tx = 0;
- int lrclk_rx = 0;
- int aifctrl_reg, bclk_reg, lrclk_tx_reg, lrclk_rx_reg;
-
- switch (dai->id) {
- case 0:
- aifctrl_reg = WM8996_AIF1_CONTROL;
- bclk_reg = WM8996_AIF1_BCLK;
- lrclk_tx_reg = WM8996_AIF1_TX_LRCLK_2;
- lrclk_rx_reg = WM8996_AIF1_RX_LRCLK_2;
- break;
- case 1:
- aifctrl_reg = WM8996_AIF2_CONTROL;
- bclk_reg = WM8996_AIF2_BCLK;
- lrclk_tx_reg = WM8996_AIF2_TX_LRCLK_2;
- lrclk_rx_reg = WM8996_AIF2_RX_LRCLK_2;
- break;
- default:
- BUG();
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_NF:
- bclk |= WM8996_AIF1_BCLK_INV;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- lrclk_tx |= WM8996_AIF1TX_LRCLK_INV;
- lrclk_rx |= WM8996_AIF1RX_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_IB_IF:
- bclk |= WM8996_AIF1_BCLK_INV;
- lrclk_tx |= WM8996_AIF1TX_LRCLK_INV;
- lrclk_rx |= WM8996_AIF1RX_LRCLK_INV;
- break;
- }
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- case SND_SOC_DAIFMT_CBS_CFM:
- lrclk_tx |= WM8996_AIF1TX_LRCLK_MSTR;
- lrclk_rx |= WM8996_AIF1RX_LRCLK_MSTR;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- bclk |= WM8996_AIF1_BCLK_MSTR;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- bclk |= WM8996_AIF1_BCLK_MSTR;
- lrclk_tx |= WM8996_AIF1TX_LRCLK_MSTR;
- lrclk_rx |= WM8996_AIF1RX_LRCLK_MSTR;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- break;
- case SND_SOC_DAIFMT_DSP_B:
- aifctrl |= 1;
- break;
- case SND_SOC_DAIFMT_I2S:
- aifctrl |= 2;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- aifctrl |= 3;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_update_bits(codec, aifctrl_reg, WM8996_AIF1_FMT_MASK, aifctrl);
- snd_soc_update_bits(codec, bclk_reg,
- WM8996_AIF1_BCLK_INV | WM8996_AIF1_BCLK_MSTR,
- bclk);
- snd_soc_update_bits(codec, lrclk_tx_reg,
- WM8996_AIF1TX_LRCLK_INV |
- WM8996_AIF1TX_LRCLK_MSTR,
- lrclk_tx);
- snd_soc_update_bits(codec, lrclk_rx_reg,
- WM8996_AIF1RX_LRCLK_INV |
- WM8996_AIF1RX_LRCLK_MSTR,
- lrclk_rx);
-
- return 0;
-}
-
-static const int dsp_divs[] = {
- 48000, 32000, 16000, 8000
-};
-
-static int wm8996_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
- int bits, i, bclk_rate, best;
- int aifdata = 0;
- int lrclk = 0;
- int dsp = 0;
- int aifdata_reg, lrclk_reg, dsp_shift;
-
- switch (dai->id) {
- case 0:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
- (snd_soc_read(codec, WM8996_GPIO_1)) & WM8996_GP1_FN_MASK) {
- aifdata_reg = WM8996_AIF1RX_DATA_CONFIGURATION;
- lrclk_reg = WM8996_AIF1_RX_LRCLK_1;
- } else {
- aifdata_reg = WM8996_AIF1TX_DATA_CONFIGURATION_1;
- lrclk_reg = WM8996_AIF1_TX_LRCLK_1;
- }
- dsp_shift = 0;
- break;
- case 1:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
- (snd_soc_read(codec, WM8996_GPIO_2)) & WM8996_GP2_FN_MASK) {
- aifdata_reg = WM8996_AIF2RX_DATA_CONFIGURATION;
- lrclk_reg = WM8996_AIF2_RX_LRCLK_1;
- } else {
- aifdata_reg = WM8996_AIF2TX_DATA_CONFIGURATION_1;
- lrclk_reg = WM8996_AIF2_TX_LRCLK_1;
- }
- dsp_shift = WM8996_DSP2_DIV_SHIFT;
- break;
- default:
- BUG();
- return -EINVAL;
- }
-
- bclk_rate = snd_soc_params_to_bclk(params);
- if (bclk_rate < 0) {
- dev_err(codec->dev, "Unsupported BCLK rate: %d\n", bclk_rate);
- return bclk_rate;
- }
-
- wm8996->bclk_rate[dai->id] = bclk_rate;
- wm8996->rx_rate[dai->id] = params_rate(params);
-
- /* Needs looking at for TDM */
- bits = snd_pcm_format_width(params_format(params));
- if (bits < 0)
- return bits;
- aifdata |= (bits << WM8996_AIF1TX_WL_SHIFT) | bits;
-
- best = 0;
- for (i = 0; i < ARRAY_SIZE(dsp_divs); i++) {
- if (abs(dsp_divs[i] - params_rate(params)) <
- abs(dsp_divs[best] - params_rate(params)))
- best = i;
- }
- dsp |= i << dsp_shift;
-
- wm8996_update_bclk(codec);
-
- lrclk = bclk_rate / params_rate(params);
- dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
- lrclk, bclk_rate / lrclk);
-
- snd_soc_update_bits(codec, aifdata_reg,
- WM8996_AIF1TX_WL_MASK |
- WM8996_AIF1TX_SLOT_LEN_MASK,
- aifdata);
- snd_soc_update_bits(codec, lrclk_reg, WM8996_AIF1RX_RATE_MASK,
- lrclk);
- snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_2,
- WM8996_DSP1_DIV_MASK << dsp_shift, dsp);
-
- return 0;
-}
-
-static int wm8996_set_sysclk(struct snd_soc_dai *dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
- int lfclk = 0;
- int ratediv = 0;
- int sync = WM8996_REG_SYNC;
- int src;
- int old;
-
- if (freq == wm8996->sysclk && clk_id == wm8996->sysclk_src)
- return 0;
-
- /* Disable SYSCLK while we reconfigure */
- old = snd_soc_read(codec, WM8996_AIF_CLOCKING_1) & WM8996_SYSCLK_ENA;
- snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_1,
- WM8996_SYSCLK_ENA, 0);
-
- switch (clk_id) {
- case WM8996_SYSCLK_MCLK1:
- wm8996->sysclk = freq;
- src = 0;
- break;
- case WM8996_SYSCLK_MCLK2:
- wm8996->sysclk = freq;
- src = 1;
- break;
- case WM8996_SYSCLK_FLL:
- wm8996->sysclk = freq;
- src = 2;
- break;
- default:
- dev_err(codec->dev, "Unsupported clock source %d\n", clk_id);
- return -EINVAL;
- }
-
- switch (wm8996->sysclk) {
- case 5644800:
- case 6144000:
- snd_soc_update_bits(codec, WM8996_AIF_RATE,
- WM8996_SYSCLK_RATE, 0);
- break;
- case 22579200:
- case 24576000:
- ratediv = WM8996_SYSCLK_DIV;
- wm8996->sysclk /= 2;
- case 11289600:
- case 12288000:
- snd_soc_update_bits(codec, WM8996_AIF_RATE,
- WM8996_SYSCLK_RATE, WM8996_SYSCLK_RATE);
- break;
- case 32000:
- case 32768:
- lfclk = WM8996_LFCLK_ENA;
- sync = 0;
- break;
- default:
- dev_warn(codec->dev, "Unsupported clock rate %dHz\n",
- wm8996->sysclk);
- return -EINVAL;
- }
-
- wm8996_update_bclk(codec);
-
- snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_1,
- WM8996_SYSCLK_SRC_MASK | WM8996_SYSCLK_DIV_MASK,
- src << WM8996_SYSCLK_SRC_SHIFT | ratediv);
- snd_soc_update_bits(codec, WM8996_CLOCKING_1, WM8996_LFCLK_ENA, lfclk);
- snd_soc_update_bits(codec, WM8996_CONTROL_INTERFACE_1,
- WM8996_REG_SYNC, sync);
- snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_1,
- WM8996_SYSCLK_ENA, old);
-
- wm8996->sysclk_src = clk_id;
-
- return 0;
-}
-
-struct _fll_div {
- u16 fll_fratio;
- u16 fll_outdiv;
- u16 fll_refclk_div;
- u16 fll_loop_gain;
- u16 fll_ref_freq;
- u16 n;
- u16 theta;
- u16 lambda;
-};
-
-static struct {
- unsigned int min;
- unsigned int max;
- u16 fll_fratio;
- int ratio;
-} fll_fratios[] = {
- { 0, 64000, 4, 16 },
- { 64000, 128000, 3, 8 },
- { 128000, 256000, 2, 4 },
- { 256000, 1000000, 1, 2 },
- { 1000000, 13500000, 0, 1 },
-};
-
-static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
- unsigned int Fout)
-{
- unsigned int target;
- unsigned int div;
- unsigned int fratio, gcd_fll;
- int i;
-
- /* Fref must be <=13.5MHz */
- div = 1;
- fll_div->fll_refclk_div = 0;
- while ((Fref / div) > 13500000) {
- div *= 2;
- fll_div->fll_refclk_div++;
-
- if (div > 8) {
- pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
- Fref);
- return -EINVAL;
- }
- }
-
- pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
-
- /* Apply the division for our remaining calculations */
- Fref /= div;
-
- if (Fref >= 3000000)
- fll_div->fll_loop_gain = 5;
- else
- fll_div->fll_loop_gain = 0;
-
- if (Fref >= 48000)
- fll_div->fll_ref_freq = 0;
- else
- fll_div->fll_ref_freq = 1;
-
- /* Fvco should be 90-100MHz; don't check the upper bound */
- div = 2;
- while (Fout * div < 90000000) {
- div++;
- if (div > 64) {
- pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
- Fout);
- return -EINVAL;
- }
- }
- target = Fout * div;
- fll_div->fll_outdiv = div - 1;
-
- pr_debug("FLL Fvco=%dHz\n", target);
-
- /* Find an appropraite FLL_FRATIO and factor it out of the target */
- for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
- if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
- fll_div->fll_fratio = fll_fratios[i].fll_fratio;
- fratio = fll_fratios[i].ratio;
- break;
- }
- }
- if (i == ARRAY_SIZE(fll_fratios)) {
- pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
- return -EINVAL;
- }
-
- fll_div->n = target / (fratio * Fref);
-
- if (target % Fref == 0) {
- fll_div->theta = 0;
- fll_div->lambda = 0;
- } else {
- gcd_fll = gcd(target, fratio * Fref);
-
- fll_div->theta = (target - (fll_div->n * fratio * Fref))
- / gcd_fll;
- fll_div->lambda = (fratio * Fref) / gcd_fll;
- }
-
- pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
- fll_div->n, fll_div->theta, fll_div->lambda);
- pr_debug("FLL_FRATIO=%x FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
- fll_div->fll_fratio, fll_div->fll_outdiv,
- fll_div->fll_refclk_div);
-
- return 0;
-}
-
-static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
- unsigned int Fref, unsigned int Fout)
-{
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
- struct i2c_client *i2c = to_i2c_client(codec->dev);
- struct _fll_div fll_div;
- unsigned long timeout;
- int ret, reg, retry;
-
- /* Any change? */
- if (source == wm8996->fll_src && Fref == wm8996->fll_fref &&
- Fout == wm8996->fll_fout)
- return 0;
-
- if (Fout == 0) {
- dev_dbg(codec->dev, "FLL disabled\n");
-
- wm8996->fll_fref = 0;
- wm8996->fll_fout = 0;
-
- snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1,
- WM8996_FLL_ENA, 0);
-
- wm8996_bg_disable(codec);
-
- return 0;
- }
-
- ret = fll_factors(&fll_div, Fref, Fout);
- if (ret != 0)
- return ret;
-
- switch (source) {
- case WM8996_FLL_MCLK1:
- reg = 0;
- break;
- case WM8996_FLL_MCLK2:
- reg = 1;
- break;
- case WM8996_FLL_DACLRCLK1:
- reg = 2;
- break;
- case WM8996_FLL_BCLK1:
- reg = 3;
- break;
- default:
- dev_err(codec->dev, "Unknown FLL source %d\n", ret);
- return -EINVAL;
- }
-
- reg |= fll_div.fll_refclk_div << WM8996_FLL_REFCLK_DIV_SHIFT;
- reg |= fll_div.fll_ref_freq << WM8996_FLL_REF_FREQ_SHIFT;
-
- snd_soc_update_bits(codec, WM8996_FLL_CONTROL_5,
- WM8996_FLL_REFCLK_DIV_MASK | WM8996_FLL_REF_FREQ |
- WM8996_FLL_REFCLK_SRC_MASK, reg);
-
- reg = 0;
- if (fll_div.theta || fll_div.lambda)
- reg |= WM8996_FLL_EFS_ENA | (3 << WM8996_FLL_LFSR_SEL_SHIFT);
- else
- reg |= 1 << WM8996_FLL_LFSR_SEL_SHIFT;
- snd_soc_write(codec, WM8996_FLL_EFS_2, reg);
-
- snd_soc_update_bits(codec, WM8996_FLL_CONTROL_2,
- WM8996_FLL_OUTDIV_MASK |
- WM8996_FLL_FRATIO_MASK,
- (fll_div.fll_outdiv << WM8996_FLL_OUTDIV_SHIFT) |
- (fll_div.fll_fratio));
-
- snd_soc_write(codec, WM8996_FLL_CONTROL_3, fll_div.theta);
-
- snd_soc_update_bits(codec, WM8996_FLL_CONTROL_4,
- WM8996_FLL_N_MASK | WM8996_FLL_LOOP_GAIN_MASK,
- (fll_div.n << WM8996_FLL_N_SHIFT) |
- fll_div.fll_loop_gain);
-
- snd_soc_write(codec, WM8996_FLL_EFS_1, fll_div.lambda);
-
- /* Enable the bandgap if it's not already enabled */
- ret = snd_soc_read(codec, WM8996_FLL_CONTROL_1);
- if (!(ret & WM8996_FLL_ENA))
- wm8996_bg_enable(codec);
-
- /* Clear any pending completions (eg, from failed startups) */
- try_wait_for_completion(&wm8996->fll_lock);
-
- snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1,
- WM8996_FLL_ENA, WM8996_FLL_ENA);
-
- /* The FLL supports live reconfiguration - kick that in case we were
- * already enabled.
- */
- snd_soc_write(codec, WM8996_FLL_CONTROL_6, WM8996_FLL_SWITCH_CLK);
-
- /* Wait for the FLL to lock, using the interrupt if possible */
- if (Fref > 1000000)
- timeout = usecs_to_jiffies(300);
- else
- timeout = msecs_to_jiffies(2);
-
- /* Allow substantially longer if we've actually got the IRQ, poll
- * at a slightly higher rate if we don't.
- */
- if (i2c->irq)
- timeout *= 10;
- else
- timeout /= 2;
-
- for (retry = 0; retry < 10; retry++) {
- ret = wait_for_completion_timeout(&wm8996->fll_lock,
- timeout);
- if (ret != 0) {
- WARN_ON(!i2c->irq);
- break;
- }
-
- ret = snd_soc_read(codec, WM8996_INTERRUPT_RAW_STATUS_2);
- if (ret & WM8996_FLL_LOCK_STS)
- break;
- }
- if (retry == 10) {
- dev_err(codec->dev, "Timed out waiting for FLL\n");
- ret = -ETIMEDOUT;
- }
-
- dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
-
- wm8996->fll_fref = Fref;
- wm8996->fll_fout = Fout;
- wm8996->fll_src = source;
-
- return ret;
-}
-
-#ifdef CONFIG_GPIOLIB
-static inline struct wm8996_priv *gpio_to_wm8996(struct gpio_chip *chip)
-{
- return container_of(chip, struct wm8996_priv, gpio_chip);
-}
-
-static void wm8996_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-{
- struct wm8996_priv *wm8996 = gpio_to_wm8996(chip);
-
- regmap_update_bits(wm8996->regmap, WM8996_GPIO_1 + offset,
- WM8996_GP1_LVL, !!value << WM8996_GP1_LVL_SHIFT);
-}
-
-static int wm8996_gpio_direction_out(struct gpio_chip *chip,
- unsigned offset, int value)
-{
- struct wm8996_priv *wm8996 = gpio_to_wm8996(chip);
- int val;
-
- val = (1 << WM8996_GP1_FN_SHIFT) | (!!value << WM8996_GP1_LVL_SHIFT);
-
- return regmap_update_bits(wm8996->regmap, WM8996_GPIO_1 + offset,
- WM8996_GP1_FN_MASK | WM8996_GP1_DIR |
- WM8996_GP1_LVL, val);
-}
-
-static int wm8996_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
- struct wm8996_priv *wm8996 = gpio_to_wm8996(chip);
- unsigned int reg;
- int ret;
-
- ret = regmap_read(wm8996->regmap, WM8996_GPIO_1 + offset, &reg);
- if (ret < 0)
- return ret;
-
- return (reg & WM8996_GP1_LVL) != 0;
-}
-
-static int wm8996_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
-{
- struct wm8996_priv *wm8996 = gpio_to_wm8996(chip);
-
- return regmap_update_bits(wm8996->regmap, WM8996_GPIO_1 + offset,
- WM8996_GP1_FN_MASK | WM8996_GP1_DIR,
- (1 << WM8996_GP1_FN_SHIFT) |
- (1 << WM8996_GP1_DIR_SHIFT));
-}
-
-static struct gpio_chip wm8996_template_chip = {
- .label = "wm8996",
- .owner = THIS_MODULE,
- .direction_output = wm8996_gpio_direction_out,
- .set = wm8996_gpio_set,
- .direction_input = wm8996_gpio_direction_in,
- .get = wm8996_gpio_get,
- .can_sleep = 1,
-};
-
-static void wm8996_init_gpio(struct wm8996_priv *wm8996)
-{
- int ret;
-
- wm8996->gpio_chip = wm8996_template_chip;
- wm8996->gpio_chip.ngpio = 5;
- wm8996->gpio_chip.dev = wm8996->dev;
-
- if (wm8996->pdata.gpio_base)
- wm8996->gpio_chip.base = wm8996->pdata.gpio_base;
- else
- wm8996->gpio_chip.base = -1;
-
- ret = gpiochip_add(&wm8996->gpio_chip);
- if (ret != 0)
- dev_err(wm8996->dev, "Failed to add GPIOs: %d\n", ret);
-}
-
-static void wm8996_free_gpio(struct wm8996_priv *wm8996)
-{
- int ret;
-
- ret = gpiochip_remove(&wm8996->gpio_chip);
- if (ret != 0)
- dev_err(wm8996->dev, "Failed to remove GPIOs: %d\n", ret);
-}
-#else
-static void wm8996_init_gpio(struct wm8996_priv *wm8996)
-{
-}
-
-static void wm8996_free_gpio(struct wm8996_priv *wm8996)
-{
-}
-#endif
-
-/**
- * wm8996_detect - Enable default WM8996 jack detection
- *
- * The WM8996 has advanced accessory detection support for headsets.
- * This function provides a default implementation which integrates
- * the majority of this functionality with minimal user configuration.
- *
- * This will detect headset, headphone and short circuit button and
- * will also detect inverted microphone ground connections and update
- * the polarity of the connections.
- */
-int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
- wm8996_polarity_fn polarity_cb)
-{
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
-
- wm8996->jack = jack;
- wm8996->detecting = true;
- wm8996->polarity_cb = polarity_cb;
- wm8996->jack_flips = 0;
-
- if (wm8996->polarity_cb)
- wm8996->polarity_cb(codec, 0);
-
- /* Clear discarge to avoid noise during detection */
- snd_soc_update_bits(codec, WM8996_MICBIAS_1,
- WM8996_MICB1_DISCH, 0);
- snd_soc_update_bits(codec, WM8996_MICBIAS_2,
- WM8996_MICB2_DISCH, 0);
-
- /* LDO2 powers the microphones, SYSCLK clocks detection */
- snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2");
- snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK");
-
- /* We start off just enabling microphone detection - even a
- * plain headphone will trigger detection.
- */
- snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
- WM8996_MICD_ENA, WM8996_MICD_ENA);
-
- /* Slowest detection rate, gives debounce for initial detection */
- snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
- WM8996_MICD_RATE_MASK,
- WM8996_MICD_RATE_MASK);
-
- /* Enable interrupts and we're off */
- snd_soc_update_bits(codec, WM8996_INTERRUPT_STATUS_2_MASK,
- WM8996_IM_MICD_EINT | WM8996_HP_DONE_EINT, 0);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(wm8996_detect);
-
-static void wm8996_hpdet_irq(struct snd_soc_codec *codec)
-{
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
- int val, reg, report;
-
- /* Assume headphone in error conditions; we need to report
- * something or we stall our state machine.
- */
- report = SND_JACK_HEADPHONE;
-
- reg = snd_soc_read(codec, WM8996_HEADPHONE_DETECT_2);
- if (reg < 0) {
- dev_err(codec->dev, "Failed to read HPDET status\n");
- goto out;
- }
-
- if (!(reg & WM8996_HP_DONE)) {
- dev_err(codec->dev, "Got HPDET IRQ but HPDET is busy\n");
- goto out;
- }
-
- val = reg & WM8996_HP_LVL_MASK;
-
- dev_dbg(codec->dev, "HPDET measured %d ohms\n", val);
-
- /* If we've got high enough impedence then report as line,
- * otherwise assume headphone.
- */
- if (val >= 126)
- report = SND_JACK_LINEOUT;
- else
- report = SND_JACK_HEADPHONE;
-
-out:
- if (wm8996->jack_mic)
- report |= SND_JACK_MICROPHONE;
-
- snd_soc_jack_report(wm8996->jack, report,
- SND_JACK_LINEOUT | SND_JACK_HEADSET);
-
- wm8996->detecting = false;
-
- /* If the output isn't running re-clamp it */
- if (!(snd_soc_read(codec, WM8996_POWER_MANAGEMENT_1) &
- (WM8996_HPOUT1L_ENA | WM8996_HPOUT1R_RMV_SHORT)))
- snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_1,
- WM8996_HPOUT1L_RMV_SHORT |
- WM8996_HPOUT1R_RMV_SHORT, 0);
-
- /* Go back to looking at the microphone */
- snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_1,
- WM8996_JD_MODE_MASK, 0);
- snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, WM8996_MICD_ENA,
- WM8996_MICD_ENA);
-
- snd_soc_dapm_disable_pin(&codec->dapm, "Bandgap");
- snd_soc_dapm_sync(&codec->dapm);
-}
-
-static void wm8996_hpdet_start(struct snd_soc_codec *codec)
-{
- /* Unclamp the output, we can't measure while we're shorting it */
- snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_1,
- WM8996_HPOUT1L_RMV_SHORT |
- WM8996_HPOUT1R_RMV_SHORT,
- WM8996_HPOUT1L_RMV_SHORT |
- WM8996_HPOUT1R_RMV_SHORT);
-
- /* We need bandgap for HPDET */
- snd_soc_dapm_force_enable_pin(&codec->dapm, "Bandgap");
- snd_soc_dapm_sync(&codec->dapm);
-
- /* Go into headphone detect left mode */
- snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, WM8996_MICD_ENA, 0);
- snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_1,
- WM8996_JD_MODE_MASK, 1);
-
- /* Trigger a measurement */
- snd_soc_update_bits(codec, WM8996_HEADPHONE_DETECT_1,
- WM8996_HP_POLL, WM8996_HP_POLL);
-}
-
-static void wm8996_report_headphone(struct snd_soc_codec *codec)
-{
- dev_dbg(codec->dev, "Headphone detected\n");
- wm8996_hpdet_start(codec);
-
- /* Increase the detection rate a bit for responsiveness. */
- snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
- WM8996_MICD_RATE_MASK |
- WM8996_MICD_BIAS_STARTTIME_MASK,
- 7 << WM8996_MICD_RATE_SHIFT |
- 7 << WM8996_MICD_BIAS_STARTTIME_SHIFT);
-}
-
-static void wm8996_micd(struct snd_soc_codec *codec)
-{
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
- int val, reg;
-
- val = snd_soc_read(codec, WM8996_MIC_DETECT_3);
-
- dev_dbg(codec->dev, "Microphone event: %x\n", val);
-
- if (!(val & WM8996_MICD_VALID)) {
- dev_warn(codec->dev, "Microphone detection state invalid\n");
- return;
- }
-
- /* No accessory, reset everything and report removal */
- if (!(val & WM8996_MICD_STS)) {
- dev_dbg(codec->dev, "Jack removal detected\n");
- wm8996->jack_mic = false;
- wm8996->detecting = true;
- wm8996->jack_flips = 0;
- snd_soc_jack_report(wm8996->jack, 0,
- SND_JACK_LINEOUT | SND_JACK_HEADSET |
- SND_JACK_BTN_0);
-
- snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
- WM8996_MICD_RATE_MASK |
- WM8996_MICD_BIAS_STARTTIME_MASK,
- WM8996_MICD_RATE_MASK |
- 9 << WM8996_MICD_BIAS_STARTTIME_SHIFT);
- return;
- }
-
- /* If the measurement is very high we've got a microphone,
- * either we just detected one or if we already reported then
- * we've got a button release event.
- */
- if (val & 0x400) {
- if (wm8996->detecting) {
- dev_dbg(codec->dev, "Microphone detected\n");
- wm8996->jack_mic = true;
- wm8996_hpdet_start(codec);
-
- /* Increase poll rate to give better responsiveness
- * for buttons */
- snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
- WM8996_MICD_RATE_MASK |
- WM8996_MICD_BIAS_STARTTIME_MASK,
- 5 << WM8996_MICD_RATE_SHIFT |
- 7 << WM8996_MICD_BIAS_STARTTIME_SHIFT);
- } else {
- dev_dbg(codec->dev, "Mic button up\n");
- snd_soc_jack_report(wm8996->jack, 0, SND_JACK_BTN_0);
- }
-
- return;
- }
-
- /* If we detected a lower impedence during initial startup
- * then we probably have the wrong polarity, flip it. Don't
- * do this for the lowest impedences to speed up detection of
- * plain headphones. If both polarities report a low
- * impedence then give up and report headphones.
- */
- if (wm8996->detecting && (val & 0x3f0)) {
- wm8996->jack_flips++;
-
- if (wm8996->jack_flips > 1) {
- wm8996_report_headphone(codec);
- return;
- }
-
- reg = snd_soc_read(codec, WM8996_ACCESSORY_DETECT_MODE_2);
- reg ^= WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC |
- WM8996_MICD_BIAS_SRC;
- snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_2,
- WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC |
- WM8996_MICD_BIAS_SRC, reg);
-
- if (wm8996->polarity_cb)
- wm8996->polarity_cb(codec,
- (reg & WM8996_MICD_SRC) != 0);
-
- dev_dbg(codec->dev, "Set microphone polarity to %d\n",
- (reg & WM8996_MICD_SRC) != 0);
-
- return;
- }
-
- /* Don't distinguish between buttons, just report any low
- * impedence as BTN_0.
- */
- if (val & 0x3fc) {
- if (wm8996->jack_mic) {
- dev_dbg(codec->dev, "Mic button detected\n");
- snd_soc_jack_report(wm8996->jack, SND_JACK_BTN_0,
- SND_JACK_BTN_0);
- } else if (wm8996->detecting) {
- wm8996_report_headphone(codec);
- }
- }
-}
-
-static irqreturn_t wm8996_irq(int irq, void *data)
-{
- struct snd_soc_codec *codec = data;
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
- int irq_val;
-
- irq_val = snd_soc_read(codec, WM8996_INTERRUPT_STATUS_2);
- if (irq_val < 0) {
- dev_err(codec->dev, "Failed to read IRQ status: %d\n",
- irq_val);
- return IRQ_NONE;
- }
- irq_val &= ~snd_soc_read(codec, WM8996_INTERRUPT_STATUS_2_MASK);
-
- if (!irq_val)
- return IRQ_NONE;
-
- snd_soc_write(codec, WM8996_INTERRUPT_STATUS_2, irq_val);
-
- if (irq_val & (WM8996_DCS_DONE_01_EINT | WM8996_DCS_DONE_23_EINT)) {
- dev_dbg(codec->dev, "DC servo IRQ\n");
- complete(&wm8996->dcs_done);
- }
-
- if (irq_val & WM8996_FIFOS_ERR_EINT)
- dev_err(codec->dev, "Digital core FIFO error\n");
-
- if (irq_val & WM8996_FLL_LOCK_EINT) {
- dev_dbg(codec->dev, "FLL locked\n");
- complete(&wm8996->fll_lock);
- }
-
- if (irq_val & WM8996_MICD_EINT)
- wm8996_micd(codec);
-
- if (irq_val & WM8996_HP_DONE_EINT)
- wm8996_hpdet_irq(codec);
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t wm8996_edge_irq(int irq, void *data)
-{
- irqreturn_t ret = IRQ_NONE;
- irqreturn_t val;
-
- do {
- val = wm8996_irq(irq, data);
- if (val != IRQ_NONE)
- ret = val;
- } while (val != IRQ_NONE);
-
- return ret;
-}
-
-static void wm8996_retune_mobile_pdata(struct snd_soc_codec *codec)
-{
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
- struct wm8996_pdata *pdata = &wm8996->pdata;
-
- struct snd_kcontrol_new controls[] = {
- SOC_ENUM_EXT("DSP1 EQ Mode",
- wm8996->retune_mobile_enum,
- wm8996_get_retune_mobile_enum,
- wm8996_put_retune_mobile_enum),
- SOC_ENUM_EXT("DSP2 EQ Mode",
- wm8996->retune_mobile_enum,
- wm8996_get_retune_mobile_enum,
- wm8996_put_retune_mobile_enum),
- };
- int ret, i, j;
- const char **t;
-
- /* We need an array of texts for the enum API but the number
- * of texts is likely to be less than the number of
- * configurations due to the sample rate dependency of the
- * configurations. */
- wm8996->num_retune_mobile_texts = 0;
- wm8996->retune_mobile_texts = NULL;
- for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
- for (j = 0; j < wm8996->num_retune_mobile_texts; j++) {
- if (strcmp(pdata->retune_mobile_cfgs[i].name,
- wm8996->retune_mobile_texts[j]) == 0)
- break;
- }
-
- if (j != wm8996->num_retune_mobile_texts)
- continue;
-
- /* Expand the array... */
- t = krealloc(wm8996->retune_mobile_texts,
- sizeof(char *) *
- (wm8996->num_retune_mobile_texts + 1),
- GFP_KERNEL);
- if (t == NULL)
- continue;
-
- /* ...store the new entry... */
- t[wm8996->num_retune_mobile_texts] =
- pdata->retune_mobile_cfgs[i].name;
-
- /* ...and remember the new version. */
- wm8996->num_retune_mobile_texts++;
- wm8996->retune_mobile_texts = t;
- }
-
- dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
- wm8996->num_retune_mobile_texts);
-
- wm8996->retune_mobile_enum.max = wm8996->num_retune_mobile_texts;
- wm8996->retune_mobile_enum.texts = wm8996->retune_mobile_texts;
-
- ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
- if (ret != 0)
- dev_err(codec->dev,
- "Failed to add ReTune Mobile controls: %d\n", ret);
-}
-
-static const struct regmap_config wm8996_regmap = {
- .reg_bits = 16,
- .val_bits = 16,
-
- .max_register = WM8996_MAX_REGISTER,
- .reg_defaults = wm8996_reg,
- .num_reg_defaults = ARRAY_SIZE(wm8996_reg),
- .volatile_reg = wm8996_volatile_register,
- .readable_reg = wm8996_readable_register,
- .cache_type = REGCACHE_RBTREE,
-};
-
-static int wm8996_probe(struct snd_soc_codec *codec)
-{
- int ret;
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
- struct i2c_client *i2c = to_i2c_client(codec->dev);
- int i, irq_flags;
-
- wm8996->codec = codec;
-
- init_completion(&wm8996->dcs_done);
- init_completion(&wm8996->fll_lock);
-
- codec->control_data = wm8996->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
- }
-
- wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0;
- wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1;
- wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2;
-
- /* This should really be moved into the regulator core */
- for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) {
- ret = regulator_register_notifier(wm8996->supplies[i].consumer,
- &wm8996->disable_nb[i]);
- if (ret != 0) {
- dev_err(codec->dev,
- "Failed to register regulator notifier: %d\n",
- ret);
- }
- }
-
- regcache_cache_only(codec->control_data, true);
-
- /* Apply platform data settings */
- snd_soc_update_bits(codec, WM8996_LINE_INPUT_CONTROL,
- WM8996_INL_MODE_MASK | WM8996_INR_MODE_MASK,
- wm8996->pdata.inl_mode << WM8996_INL_MODE_SHIFT |
- wm8996->pdata.inr_mode);
-
- for (i = 0; i < ARRAY_SIZE(wm8996->pdata.gpio_default); i++) {
- if (!wm8996->pdata.gpio_default[i])
- continue;
-
- snd_soc_write(codec, WM8996_GPIO_1 + i,
- wm8996->pdata.gpio_default[i] & 0xffff);
- }
-
- if (wm8996->pdata.spkmute_seq)
- snd_soc_update_bits(codec, WM8996_PDM_SPEAKER_MUTE_SEQUENCE,
- WM8996_SPK_MUTE_ENDIAN |
- WM8996_SPK_MUTE_SEQ1_MASK,
- wm8996->pdata.spkmute_seq);
-
- snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_2,
- WM8996_MICD_BIAS_SRC | WM8996_HPOUT1FB_SRC |
- WM8996_MICD_SRC, wm8996->pdata.micdet_def);
-
- /* Latch volume update bits */
- snd_soc_update_bits(codec, WM8996_LEFT_LINE_INPUT_VOLUME,
- WM8996_IN1_VU, WM8996_IN1_VU);
- snd_soc_update_bits(codec, WM8996_RIGHT_LINE_INPUT_VOLUME,
- WM8996_IN1_VU, WM8996_IN1_VU);
-
- snd_soc_update_bits(codec, WM8996_DAC1_LEFT_VOLUME,
- WM8996_DAC1_VU, WM8996_DAC1_VU);
- snd_soc_update_bits(codec, WM8996_DAC1_RIGHT_VOLUME,
- WM8996_DAC1_VU, WM8996_DAC1_VU);
- snd_soc_update_bits(codec, WM8996_DAC2_LEFT_VOLUME,
- WM8996_DAC2_VU, WM8996_DAC2_VU);
- snd_soc_update_bits(codec, WM8996_DAC2_RIGHT_VOLUME,
- WM8996_DAC2_VU, WM8996_DAC2_VU);
-
- snd_soc_update_bits(codec, WM8996_OUTPUT1_LEFT_VOLUME,
- WM8996_DAC1_VU, WM8996_DAC1_VU);
- snd_soc_update_bits(codec, WM8996_OUTPUT1_RIGHT_VOLUME,
- WM8996_DAC1_VU, WM8996_DAC1_VU);
- snd_soc_update_bits(codec, WM8996_OUTPUT2_LEFT_VOLUME,
- WM8996_DAC2_VU, WM8996_DAC2_VU);
- snd_soc_update_bits(codec, WM8996_OUTPUT2_RIGHT_VOLUME,
- WM8996_DAC2_VU, WM8996_DAC2_VU);
-
- snd_soc_update_bits(codec, WM8996_DSP1_TX_LEFT_VOLUME,
- WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);
- snd_soc_update_bits(codec, WM8996_DSP1_TX_RIGHT_VOLUME,
- WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);
- snd_soc_update_bits(codec, WM8996_DSP2_TX_LEFT_VOLUME,
- WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);
- snd_soc_update_bits(codec, WM8996_DSP2_TX_RIGHT_VOLUME,
- WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);
-
- snd_soc_update_bits(codec, WM8996_DSP1_RX_LEFT_VOLUME,
- WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);
- snd_soc_update_bits(codec, WM8996_DSP1_RX_RIGHT_VOLUME,
- WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);
- snd_soc_update_bits(codec, WM8996_DSP2_RX_LEFT_VOLUME,
- WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);
- snd_soc_update_bits(codec, WM8996_DSP2_RX_RIGHT_VOLUME,
- WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);
-
- /* No support currently for the underclocked TDM modes and
- * pick a default TDM layout with each channel pair working with
- * slots 0 and 1. */
- snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_0_CONFIGURATION,
- WM8996_AIF1RX_CHAN0_SLOTS_MASK |
- WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
- 1 << WM8996_AIF1RX_CHAN0_SLOTS_SHIFT | 0);
- snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_1_CONFIGURATION,
- WM8996_AIF1RX_CHAN1_SLOTS_MASK |
- WM8996_AIF1RX_CHAN1_START_SLOT_MASK,
- 1 << WM8996_AIF1RX_CHAN1_SLOTS_SHIFT | 1);
- snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_2_CONFIGURATION,
- WM8996_AIF1RX_CHAN2_SLOTS_MASK |
- WM8996_AIF1RX_CHAN2_START_SLOT_MASK,
- 1 << WM8996_AIF1RX_CHAN2_SLOTS_SHIFT | 0);
- snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_3_CONFIGURATION,
- WM8996_AIF1RX_CHAN3_SLOTS_MASK |
- WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
- 1 << WM8996_AIF1RX_CHAN3_SLOTS_SHIFT | 1);
- snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_4_CONFIGURATION,
- WM8996_AIF1RX_CHAN4_SLOTS_MASK |
- WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
- 1 << WM8996_AIF1RX_CHAN4_SLOTS_SHIFT | 0);
- snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_5_CONFIGURATION,
- WM8996_AIF1RX_CHAN5_SLOTS_MASK |
- WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
- 1 << WM8996_AIF1RX_CHAN5_SLOTS_SHIFT | 1);
-
- snd_soc_update_bits(codec, WM8996_AIF2RX_CHANNEL_0_CONFIGURATION,
- WM8996_AIF2RX_CHAN0_SLOTS_MASK |
- WM8996_AIF2RX_CHAN0_START_SLOT_MASK,
- 1 << WM8996_AIF2RX_CHAN0_SLOTS_SHIFT | 0);
- snd_soc_update_bits(codec, WM8996_AIF2RX_CHANNEL_1_CONFIGURATION,
- WM8996_AIF2RX_CHAN1_SLOTS_MASK |
- WM8996_AIF2RX_CHAN1_START_SLOT_MASK,
- 1 << WM8996_AIF2RX_CHAN1_SLOTS_SHIFT | 1);
-
- snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_0_CONFIGURATION,
- WM8996_AIF1TX_CHAN0_SLOTS_MASK |
- WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
- 1 << WM8996_AIF1TX_CHAN0_SLOTS_SHIFT | 0);
- snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,
- WM8996_AIF1TX_CHAN1_SLOTS_MASK |
- WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
- 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
- snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_2_CONFIGURATION,
- WM8996_AIF1TX_CHAN2_SLOTS_MASK |
- WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
- 1 << WM8996_AIF1TX_CHAN2_SLOTS_SHIFT | 0);
- snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_3_CONFIGURATION,
- WM8996_AIF1TX_CHAN3_SLOTS_MASK |
- WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
- 1 << WM8996_AIF1TX_CHAN3_SLOTS_SHIFT | 1);
- snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_4_CONFIGURATION,
- WM8996_AIF1TX_CHAN4_SLOTS_MASK |
- WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
- 1 << WM8996_AIF1TX_CHAN4_SLOTS_SHIFT | 0);
- snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_5_CONFIGURATION,
- WM8996_AIF1TX_CHAN5_SLOTS_MASK |
- WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
- 1 << WM8996_AIF1TX_CHAN5_SLOTS_SHIFT | 1);
-
- snd_soc_update_bits(codec, WM8996_AIF2TX_CHANNEL_0_CONFIGURATION,
- WM8996_AIF2TX_CHAN0_SLOTS_MASK |
- WM8996_AIF2TX_CHAN0_START_SLOT_MASK,
- 1 << WM8996_AIF2TX_CHAN0_SLOTS_SHIFT | 0);
- snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,
- WM8996_AIF2TX_CHAN1_SLOTS_MASK |
- WM8996_AIF2TX_CHAN1_START_SLOT_MASK,
- 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
-
- if (wm8996->pdata.num_retune_mobile_cfgs)
- wm8996_retune_mobile_pdata(codec);
- else
- snd_soc_add_codec_controls(codec, wm8996_eq_controls,
- ARRAY_SIZE(wm8996_eq_controls));
-
- /* If the TX LRCLK pins are not in LRCLK mode configure the
- * AIFs to source their clocks from the RX LRCLKs.
- */
- if ((snd_soc_read(codec, WM8996_GPIO_1)))
- snd_soc_update_bits(codec, WM8996_AIF1_TX_LRCLK_2,
- WM8996_AIF1TX_LRCLK_MODE,
- WM8996_AIF1TX_LRCLK_MODE);
-
- if ((snd_soc_read(codec, WM8996_GPIO_2)))
- snd_soc_update_bits(codec, WM8996_AIF2_TX_LRCLK_2,
- WM8996_AIF2TX_LRCLK_MODE,
- WM8996_AIF2TX_LRCLK_MODE);
-
- if (i2c->irq) {
- if (wm8996->pdata.irq_flags)
- irq_flags = wm8996->pdata.irq_flags;
- else
- irq_flags = IRQF_TRIGGER_LOW;
-
- irq_flags |= IRQF_ONESHOT;
-
- if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
- ret = request_threaded_irq(i2c->irq, NULL,
- wm8996_edge_irq,
- irq_flags, "wm8996", codec);
- else
- ret = request_threaded_irq(i2c->irq, NULL, wm8996_irq,
- irq_flags, "wm8996", codec);
-
- if (ret == 0) {
- /* Unmask the interrupt */
- snd_soc_update_bits(codec, WM8996_INTERRUPT_CONTROL,
- WM8996_IM_IRQ, 0);
-
- /* Enable error reporting and DC servo status */
- snd_soc_update_bits(codec,
- WM8996_INTERRUPT_STATUS_2_MASK,
- WM8996_IM_DCS_DONE_23_EINT |
- WM8996_IM_DCS_DONE_01_EINT |
- WM8996_IM_FLL_LOCK_EINT |
- WM8996_IM_FIFOS_ERR_EINT,
- 0);
- } else {
- dev_err(codec->dev, "Failed to request IRQ: %d\n",
- ret);
- }
- }
-
- return 0;
-
-err:
- return ret;
-}
-
-static int wm8996_remove(struct snd_soc_codec *codec)
-{
- struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
- struct i2c_client *i2c = to_i2c_client(codec->dev);
- int i;
-
- snd_soc_update_bits(codec, WM8996_INTERRUPT_CONTROL,
- WM8996_IM_IRQ, WM8996_IM_IRQ);
-
- if (i2c->irq)
- free_irq(i2c->irq, codec);
-
- for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
- regulator_unregister_notifier(wm8996->supplies[i].consumer,
- &wm8996->disable_nb[i]);
- regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm8996 = {
- .probe = wm8996_probe,
- .remove = wm8996_remove,
- .set_bias_level = wm8996_set_bias_level,
- .idle_bias_off = true,
- .seq_notifier = wm8996_seq_notifier,
- .controls = wm8996_snd_controls,
- .num_controls = ARRAY_SIZE(wm8996_snd_controls),
- .dapm_widgets = wm8996_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8996_dapm_widgets),
- .dapm_routes = wm8996_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes),
- .set_pll = wm8996_set_fll,
-};
-
-#define WM8996_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
- SNDRV_PCM_RATE_48000)
-#define WM8996_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
- SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\
- SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops wm8996_dai_ops = {
- .set_fmt = wm8996_set_fmt,
- .hw_params = wm8996_hw_params,
- .set_sysclk = wm8996_set_sysclk,
-};
-
-static struct snd_soc_dai_driver wm8996_dai[] = {
- {
- .name = "wm8996-aif1",
- .playback = {
- .stream_name = "AIF1 Playback",
- .channels_min = 1,
- .channels_max = 6,
- .rates = WM8996_RATES,
- .formats = WM8996_FORMATS,
- .sig_bits = 24,
- },
- .capture = {
- .stream_name = "AIF1 Capture",
- .channels_min = 1,
- .channels_max = 6,
- .rates = WM8996_RATES,
- .formats = WM8996_FORMATS,
- .sig_bits = 24,
- },
- .ops = &wm8996_dai_ops,
- },
- {
- .name = "wm8996-aif2",
- .playback = {
- .stream_name = "AIF2 Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8996_RATES,
- .formats = WM8996_FORMATS,
- .sig_bits = 24,
- },
- .capture = {
- .stream_name = "AIF2 Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8996_RATES,
- .formats = WM8996_FORMATS,
- .sig_bits = 24,
- },
- .ops = &wm8996_dai_ops,
- },
-};
-
-static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8996_priv *wm8996;
- int ret, i;
- unsigned int reg;
-
- wm8996 = devm_kzalloc(&i2c->dev, sizeof(struct wm8996_priv),
- GFP_KERNEL);
- if (wm8996 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm8996);
- wm8996->dev = &i2c->dev;
-
- if (dev_get_platdata(&i2c->dev))
- memcpy(&wm8996->pdata, dev_get_platdata(&i2c->dev),
- sizeof(wm8996->pdata));
-
- if (wm8996->pdata.ldo_ena > 0) {
- ret = gpio_request_one(wm8996->pdata.ldo_ena,
- GPIOF_OUT_INIT_LOW, "WM8996 ENA");
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to request GPIO %d: %d\n",
- wm8996->pdata.ldo_ena, ret);
- goto err;
- }
- }
-
- for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
- wm8996->supplies[i].supply = wm8996_supply_names[i];
-
- ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8996->supplies),
- wm8996->supplies);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
- goto err_gpio;
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies),
- wm8996->supplies);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
- goto err_gpio;
- }
-
- if (wm8996->pdata.ldo_ena > 0) {
- gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1);
- msleep(5);
- }
-
- wm8996->regmap = regmap_init_i2c(i2c, &wm8996_regmap);
- if (IS_ERR(wm8996->regmap)) {
- ret = PTR_ERR(wm8996->regmap);
- dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
- goto err_enable;
- }
-
- ret = regmap_read(wm8996->regmap, WM8996_SOFTWARE_RESET, &reg);
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);
- goto err_regmap;
- }
- if (reg != 0x8915) {
- dev_err(&i2c->dev, "Device is not a WM8996, ID %x\n", reg);
- ret = -EINVAL;
- goto err_regmap;
- }
-
- ret = regmap_read(wm8996->regmap, WM8996_CHIP_REVISION, &reg);
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to read device revision: %d\n",
- ret);
- goto err_regmap;
- }
-
- dev_info(&i2c->dev, "revision %c\n",
- (reg & WM8996_CHIP_REV_MASK) + 'A');
-
- regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
-
- ret = wm8996_reset(wm8996);
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to issue reset\n");
- goto err_regmap;
- }
-
- wm8996_init_gpio(wm8996);
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm8996, wm8996_dai,
- ARRAY_SIZE(wm8996_dai));
- if (ret < 0)
- goto err_gpiolib;
-
- return ret;
-
-err_gpiolib:
- wm8996_free_gpio(wm8996);
-err_regmap:
- regmap_exit(wm8996->regmap);
-err_enable:
- if (wm8996->pdata.ldo_ena > 0)
- gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
- regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
-err_gpio:
- if (wm8996->pdata.ldo_ena > 0)
- gpio_free(wm8996->pdata.ldo_ena);
-err:
-
- return ret;
-}
-
-static __devexit int wm8996_i2c_remove(struct i2c_client *client)
-{
- struct wm8996_priv *wm8996 = i2c_get_clientdata(client);
-
- snd_soc_unregister_codec(&client->dev);
- wm8996_free_gpio(wm8996);
- regmap_exit(wm8996->regmap);
- if (wm8996->pdata.ldo_ena > 0) {
- gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
- gpio_free(wm8996->pdata.ldo_ena);
- }
- return 0;
-}
-
-static const struct i2c_device_id wm8996_i2c_id[] = {
- { "wm8996", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8996_i2c_id);
-
-static struct i2c_driver wm8996_i2c_driver = {
- .driver = {
- .name = "wm8996",
- .owner = THIS_MODULE,
- },
- .probe = wm8996_i2c_probe,
- .remove = __devexit_p(wm8996_i2c_remove),
- .id_table = wm8996_i2c_id,
-};
-
-module_i2c_driver(wm8996_i2c_driver);
-
-MODULE_DESCRIPTION("ASoC WM8996 driver");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm8996.h b/ANDROID_3.4.5/sound/soc/codecs/wm8996.h
deleted file mode 100644
index de9ac3e4..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm8996.h
+++ /dev/null
@@ -1,3721 +0,0 @@
-/*
- * wm8996.h - WM8996 audio codec interface
- *
- * Copyright 2011 Wolfson Microelectronics PLC.
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#ifndef _WM8996_H
-#define _WM8996_H
-
-#define WM8996_SYSCLK_MCLK1 1
-#define WM8996_SYSCLK_MCLK2 2
-#define WM8996_SYSCLK_FLL 3
-
-#define WM8996_FLL_MCLK1 1
-#define WM8996_FLL_MCLK2 2
-#define WM8996_FLL_DACLRCLK1 3
-#define WM8996_FLL_BCLK1 4
-
-typedef void (*wm8996_polarity_fn)(struct snd_soc_codec *codec, int polarity);
-
-int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
- wm8996_polarity_fn polarity_cb);
-
-/*
- * Register values.
- */
-#define WM8996_SOFTWARE_RESET 0x00
-#define WM8996_POWER_MANAGEMENT_1 0x01
-#define WM8996_POWER_MANAGEMENT_2 0x02
-#define WM8996_POWER_MANAGEMENT_3 0x03
-#define WM8996_POWER_MANAGEMENT_4 0x04
-#define WM8996_POWER_MANAGEMENT_5 0x05
-#define WM8996_POWER_MANAGEMENT_6 0x06
-#define WM8996_POWER_MANAGEMENT_7 0x07
-#define WM8996_POWER_MANAGEMENT_8 0x08
-#define WM8996_LEFT_LINE_INPUT_VOLUME 0x10
-#define WM8996_RIGHT_LINE_INPUT_VOLUME 0x11
-#define WM8996_LINE_INPUT_CONTROL 0x12
-#define WM8996_DAC1_HPOUT1_VOLUME 0x15
-#define WM8996_DAC2_HPOUT2_VOLUME 0x16
-#define WM8996_DAC1_LEFT_VOLUME 0x18
-#define WM8996_DAC1_RIGHT_VOLUME 0x19
-#define WM8996_DAC2_LEFT_VOLUME 0x1A
-#define WM8996_DAC2_RIGHT_VOLUME 0x1B
-#define WM8996_OUTPUT1_LEFT_VOLUME 0x1C
-#define WM8996_OUTPUT1_RIGHT_VOLUME 0x1D
-#define WM8996_OUTPUT2_LEFT_VOLUME 0x1E
-#define WM8996_OUTPUT2_RIGHT_VOLUME 0x1F
-#define WM8996_MICBIAS_1 0x20
-#define WM8996_MICBIAS_2 0x21
-#define WM8996_LDO_1 0x28
-#define WM8996_LDO_2 0x29
-#define WM8996_ACCESSORY_DETECT_MODE_1 0x30
-#define WM8996_ACCESSORY_DETECT_MODE_2 0x31
-#define WM8996_HEADPHONE_DETECT_1 0x34
-#define WM8996_HEADPHONE_DETECT_2 0x35
-#define WM8996_MIC_DETECT_1 0x38
-#define WM8996_MIC_DETECT_2 0x39
-#define WM8996_MIC_DETECT_3 0x3A
-#define WM8996_CHARGE_PUMP_1 0x40
-#define WM8996_CHARGE_PUMP_2 0x41
-#define WM8996_DC_SERVO_1 0x50
-#define WM8996_DC_SERVO_2 0x51
-#define WM8996_DC_SERVO_3 0x52
-#define WM8996_DC_SERVO_5 0x54
-#define WM8996_DC_SERVO_6 0x55
-#define WM8996_DC_SERVO_7 0x56
-#define WM8996_DC_SERVO_READBACK_0 0x57
-#define WM8996_ANALOGUE_HP_1 0x60
-#define WM8996_ANALOGUE_HP_2 0x61
-#define WM8996_CHIP_REVISION 0x100
-#define WM8996_CONTROL_INTERFACE_1 0x101
-#define WM8996_WRITE_SEQUENCER_CTRL_1 0x110
-#define WM8996_WRITE_SEQUENCER_CTRL_2 0x111
-#define WM8996_AIF_CLOCKING_1 0x200
-#define WM8996_AIF_CLOCKING_2 0x201
-#define WM8996_CLOCKING_1 0x208
-#define WM8996_CLOCKING_2 0x209
-#define WM8996_AIF_RATE 0x210
-#define WM8996_FLL_CONTROL_1 0x220
-#define WM8996_FLL_CONTROL_2 0x221
-#define WM8996_FLL_CONTROL_3 0x222
-#define WM8996_FLL_CONTROL_4 0x223
-#define WM8996_FLL_CONTROL_5 0x224
-#define WM8996_FLL_CONTROL_6 0x225
-#define WM8996_FLL_EFS_1 0x226
-#define WM8996_FLL_EFS_2 0x227
-#define WM8996_AIF1_CONTROL 0x300
-#define WM8996_AIF1_BCLK 0x301
-#define WM8996_AIF1_TX_LRCLK_1 0x302
-#define WM8996_AIF1_TX_LRCLK_2 0x303
-#define WM8996_AIF1_RX_LRCLK_1 0x304
-#define WM8996_AIF1_RX_LRCLK_2 0x305
-#define WM8996_AIF1TX_DATA_CONFIGURATION_1 0x306
-#define WM8996_AIF1TX_DATA_CONFIGURATION_2 0x307
-#define WM8996_AIF1RX_DATA_CONFIGURATION 0x308
-#define WM8996_AIF1TX_CHANNEL_0_CONFIGURATION 0x309
-#define WM8996_AIF1TX_CHANNEL_1_CONFIGURATION 0x30A
-#define WM8996_AIF1TX_CHANNEL_2_CONFIGURATION 0x30B
-#define WM8996_AIF1TX_CHANNEL_3_CONFIGURATION 0x30C
-#define WM8996_AIF1TX_CHANNEL_4_CONFIGURATION 0x30D
-#define WM8996_AIF1TX_CHANNEL_5_CONFIGURATION 0x30E
-#define WM8996_AIF1RX_CHANNEL_0_CONFIGURATION 0x30F
-#define WM8996_AIF1RX_CHANNEL_1_CONFIGURATION 0x310
-#define WM8996_AIF1RX_CHANNEL_2_CONFIGURATION 0x311
-#define WM8996_AIF1RX_CHANNEL_3_CONFIGURATION 0x312
-#define WM8996_AIF1RX_CHANNEL_4_CONFIGURATION 0x313
-#define WM8996_AIF1RX_CHANNEL_5_CONFIGURATION 0x314
-#define WM8996_AIF1RX_MONO_CONFIGURATION 0x315
-#define WM8996_AIF1TX_TEST 0x31A
-#define WM8996_AIF2_CONTROL 0x320
-#define WM8996_AIF2_BCLK 0x321
-#define WM8996_AIF2_TX_LRCLK_1 0x322
-#define WM8996_AIF2_TX_LRCLK_2 0x323
-#define WM8996_AIF2_RX_LRCLK_1 0x324
-#define WM8996_AIF2_RX_LRCLK_2 0x325
-#define WM8996_AIF2TX_DATA_CONFIGURATION_1 0x326
-#define WM8996_AIF2TX_DATA_CONFIGURATION_2 0x327
-#define WM8996_AIF2RX_DATA_CONFIGURATION 0x328
-#define WM8996_AIF2TX_CHANNEL_0_CONFIGURATION 0x329
-#define WM8996_AIF2TX_CHANNEL_1_CONFIGURATION 0x32A
-#define WM8996_AIF2RX_CHANNEL_0_CONFIGURATION 0x32B
-#define WM8996_AIF2RX_CHANNEL_1_CONFIGURATION 0x32C
-#define WM8996_AIF2RX_MONO_CONFIGURATION 0x32D
-#define WM8996_AIF2TX_TEST 0x32F
-#define WM8996_DSP1_TX_LEFT_VOLUME 0x400
-#define WM8996_DSP1_TX_RIGHT_VOLUME 0x401
-#define WM8996_DSP1_RX_LEFT_VOLUME 0x402
-#define WM8996_DSP1_RX_RIGHT_VOLUME 0x403
-#define WM8996_DSP1_TX_FILTERS 0x410
-#define WM8996_DSP1_RX_FILTERS_1 0x420
-#define WM8996_DSP1_RX_FILTERS_2 0x421
-#define WM8996_DSP1_DRC_1 0x440
-#define WM8996_DSP1_DRC_2 0x441
-#define WM8996_DSP1_DRC_3 0x442
-#define WM8996_DSP1_DRC_4 0x443
-#define WM8996_DSP1_DRC_5 0x444
-#define WM8996_DSP1_RX_EQ_GAINS_1 0x480
-#define WM8996_DSP1_RX_EQ_GAINS_2 0x481
-#define WM8996_DSP1_RX_EQ_BAND_1_A 0x482
-#define WM8996_DSP1_RX_EQ_BAND_1_B 0x483
-#define WM8996_DSP1_RX_EQ_BAND_1_PG 0x484
-#define WM8996_DSP1_RX_EQ_BAND_2_A 0x485
-#define WM8996_DSP1_RX_EQ_BAND_2_B 0x486
-#define WM8996_DSP1_RX_EQ_BAND_2_C 0x487
-#define WM8996_DSP1_RX_EQ_BAND_2_PG 0x488
-#define WM8996_DSP1_RX_EQ_BAND_3_A 0x489
-#define WM8996_DSP1_RX_EQ_BAND_3_B 0x48A
-#define WM8996_DSP1_RX_EQ_BAND_3_C 0x48B
-#define WM8996_DSP1_RX_EQ_BAND_3_PG 0x48C
-#define WM8996_DSP1_RX_EQ_BAND_4_A 0x48D
-#define WM8996_DSP1_RX_EQ_BAND_4_B 0x48E
-#define WM8996_DSP1_RX_EQ_BAND_4_C 0x48F
-#define WM8996_DSP1_RX_EQ_BAND_4_PG 0x490
-#define WM8996_DSP1_RX_EQ_BAND_5_A 0x491
-#define WM8996_DSP1_RX_EQ_BAND_5_B 0x492
-#define WM8996_DSP1_RX_EQ_BAND_5_PG 0x493
-#define WM8996_DSP2_TX_LEFT_VOLUME 0x500
-#define WM8996_DSP2_TX_RIGHT_VOLUME 0x501
-#define WM8996_DSP2_RX_LEFT_VOLUME 0x502
-#define WM8996_DSP2_RX_RIGHT_VOLUME 0x503
-#define WM8996_DSP2_TX_FILTERS 0x510
-#define WM8996_DSP2_RX_FILTERS_1 0x520
-#define WM8996_DSP2_RX_FILTERS_2 0x521
-#define WM8996_DSP2_DRC_1 0x540
-#define WM8996_DSP2_DRC_2 0x541
-#define WM8996_DSP2_DRC_3 0x542
-#define WM8996_DSP2_DRC_4 0x543
-#define WM8996_DSP2_DRC_5 0x544
-#define WM8996_DSP2_RX_EQ_GAINS_1 0x580
-#define WM8996_DSP2_RX_EQ_GAINS_2 0x581
-#define WM8996_DSP2_RX_EQ_BAND_1_A 0x582
-#define WM8996_DSP2_RX_EQ_BAND_1_B 0x583
-#define WM8996_DSP2_RX_EQ_BAND_1_PG 0x584
-#define WM8996_DSP2_RX_EQ_BAND_2_A 0x585
-#define WM8996_DSP2_RX_EQ_BAND_2_B 0x586
-#define WM8996_DSP2_RX_EQ_BAND_2_C 0x587
-#define WM8996_DSP2_RX_EQ_BAND_2_PG 0x588
-#define WM8996_DSP2_RX_EQ_BAND_3_A 0x589
-#define WM8996_DSP2_RX_EQ_BAND_3_B 0x58A
-#define WM8996_DSP2_RX_EQ_BAND_3_C 0x58B
-#define WM8996_DSP2_RX_EQ_BAND_3_PG 0x58C
-#define WM8996_DSP2_RX_EQ_BAND_4_A 0x58D
-#define WM8996_DSP2_RX_EQ_BAND_4_B 0x58E
-#define WM8996_DSP2_RX_EQ_BAND_4_C 0x58F
-#define WM8996_DSP2_RX_EQ_BAND_4_PG 0x590
-#define WM8996_DSP2_RX_EQ_BAND_5_A 0x591
-#define WM8996_DSP2_RX_EQ_BAND_5_B 0x592
-#define WM8996_DSP2_RX_EQ_BAND_5_PG 0x593
-#define WM8996_DAC1_MIXER_VOLUMES 0x600
-#define WM8996_DAC1_LEFT_MIXER_ROUTING 0x601
-#define WM8996_DAC1_RIGHT_MIXER_ROUTING 0x602
-#define WM8996_DAC2_MIXER_VOLUMES 0x603
-#define WM8996_DAC2_LEFT_MIXER_ROUTING 0x604
-#define WM8996_DAC2_RIGHT_MIXER_ROUTING 0x605
-#define WM8996_DSP1_TX_LEFT_MIXER_ROUTING 0x606
-#define WM8996_DSP1_TX_RIGHT_MIXER_ROUTING 0x607
-#define WM8996_DSP2_TX_LEFT_MIXER_ROUTING 0x608
-#define WM8996_DSP2_TX_RIGHT_MIXER_ROUTING 0x609
-#define WM8996_DSP_TX_MIXER_SELECT 0x60A
-#define WM8996_DAC_SOFTMUTE 0x610
-#define WM8996_OVERSAMPLING 0x620
-#define WM8996_SIDETONE 0x621
-#define WM8996_GPIO_1 0x700
-#define WM8996_GPIO_2 0x701
-#define WM8996_GPIO_3 0x702
-#define WM8996_GPIO_4 0x703
-#define WM8996_GPIO_5 0x704
-#define WM8996_PULL_CONTROL_1 0x720
-#define WM8996_PULL_CONTROL_2 0x721
-#define WM8996_INTERRUPT_STATUS_1 0x730
-#define WM8996_INTERRUPT_STATUS_2 0x731
-#define WM8996_INTERRUPT_RAW_STATUS_2 0x732
-#define WM8996_INTERRUPT_STATUS_1_MASK 0x738
-#define WM8996_INTERRUPT_STATUS_2_MASK 0x739
-#define WM8996_INTERRUPT_CONTROL 0x740
-#define WM8996_LEFT_PDM_SPEAKER 0x800
-#define WM8996_RIGHT_PDM_SPEAKER 0x801
-#define WM8996_PDM_SPEAKER_MUTE_SEQUENCE 0x802
-#define WM8996_PDM_SPEAKER_VOLUME 0x803
-#define WM8996_WRITE_SEQUENCER_0 0x3000
-#define WM8996_WRITE_SEQUENCER_1 0x3001
-#define WM8996_WRITE_SEQUENCER_2 0x3002
-#define WM8996_WRITE_SEQUENCER_3 0x3003
-#define WM8996_WRITE_SEQUENCER_4 0x3004
-#define WM8996_WRITE_SEQUENCER_5 0x3005
-#define WM8996_WRITE_SEQUENCER_6 0x3006
-#define WM8996_WRITE_SEQUENCER_7 0x3007
-#define WM8996_WRITE_SEQUENCER_8 0x3008
-#define WM8996_WRITE_SEQUENCER_9 0x3009
-#define WM8996_WRITE_SEQUENCER_10 0x300A
-#define WM8996_WRITE_SEQUENCER_11 0x300B
-#define WM8996_WRITE_SEQUENCER_12 0x300C
-#define WM8996_WRITE_SEQUENCER_13 0x300D
-#define WM8996_WRITE_SEQUENCER_14 0x300E
-#define WM8996_WRITE_SEQUENCER_15 0x300F
-#define WM8996_WRITE_SEQUENCER_16 0x3010
-#define WM8996_WRITE_SEQUENCER_17 0x3011
-#define WM8996_WRITE_SEQUENCER_18 0x3012
-#define WM8996_WRITE_SEQUENCER_19 0x3013
-#define WM8996_WRITE_SEQUENCER_20 0x3014
-#define WM8996_WRITE_SEQUENCER_21 0x3015
-#define WM8996_WRITE_SEQUENCER_22 0x3016
-#define WM8996_WRITE_SEQUENCER_23 0x3017
-#define WM8996_WRITE_SEQUENCER_24 0x3018
-#define WM8996_WRITE_SEQUENCER_25 0x3019
-#define WM8996_WRITE_SEQUENCER_26 0x301A
-#define WM8996_WRITE_SEQUENCER_27 0x301B
-#define WM8996_WRITE_SEQUENCER_28 0x301C
-#define WM8996_WRITE_SEQUENCER_29 0x301D
-#define WM8996_WRITE_SEQUENCER_30 0x301E
-#define WM8996_WRITE_SEQUENCER_31 0x301F
-#define WM8996_WRITE_SEQUENCER_32 0x3020
-#define WM8996_WRITE_SEQUENCER_33 0x3021
-#define WM8996_WRITE_SEQUENCER_34 0x3022
-#define WM8996_WRITE_SEQUENCER_35 0x3023
-#define WM8996_WRITE_SEQUENCER_36 0x3024
-#define WM8996_WRITE_SEQUENCER_37 0x3025
-#define WM8996_WRITE_SEQUENCER_38 0x3026
-#define WM8996_WRITE_SEQUENCER_39 0x3027
-#define WM8996_WRITE_SEQUENCER_40 0x3028
-#define WM8996_WRITE_SEQUENCER_41 0x3029
-#define WM8996_WRITE_SEQUENCER_42 0x302A
-#define WM8996_WRITE_SEQUENCER_43 0x302B
-#define WM8996_WRITE_SEQUENCER_44 0x302C
-#define WM8996_WRITE_SEQUENCER_45 0x302D
-#define WM8996_WRITE_SEQUENCER_46 0x302E
-#define WM8996_WRITE_SEQUENCER_47 0x302F
-#define WM8996_WRITE_SEQUENCER_48 0x3030
-#define WM8996_WRITE_SEQUENCER_49 0x3031
-#define WM8996_WRITE_SEQUENCER_50 0x3032
-#define WM8996_WRITE_SEQUENCER_51 0x3033
-#define WM8996_WRITE_SEQUENCER_52 0x3034
-#define WM8996_WRITE_SEQUENCER_53 0x3035
-#define WM8996_WRITE_SEQUENCER_54 0x3036
-#define WM8996_WRITE_SEQUENCER_55 0x3037
-#define WM8996_WRITE_SEQUENCER_56 0x3038
-#define WM8996_WRITE_SEQUENCER_57 0x3039
-#define WM8996_WRITE_SEQUENCER_58 0x303A
-#define WM8996_WRITE_SEQUENCER_59 0x303B
-#define WM8996_WRITE_SEQUENCER_60 0x303C
-#define WM8996_WRITE_SEQUENCER_61 0x303D
-#define WM8996_WRITE_SEQUENCER_62 0x303E
-#define WM8996_WRITE_SEQUENCER_63 0x303F
-#define WM8996_WRITE_SEQUENCER_64 0x3040
-#define WM8996_WRITE_SEQUENCER_65 0x3041
-#define WM8996_WRITE_SEQUENCER_66 0x3042
-#define WM8996_WRITE_SEQUENCER_67 0x3043
-#define WM8996_WRITE_SEQUENCER_68 0x3044
-#define WM8996_WRITE_SEQUENCER_69 0x3045
-#define WM8996_WRITE_SEQUENCER_70 0x3046
-#define WM8996_WRITE_SEQUENCER_71 0x3047
-#define WM8996_WRITE_SEQUENCER_72 0x3048
-#define WM8996_WRITE_SEQUENCER_73 0x3049
-#define WM8996_WRITE_SEQUENCER_74 0x304A
-#define WM8996_WRITE_SEQUENCER_75 0x304B
-#define WM8996_WRITE_SEQUENCER_76 0x304C
-#define WM8996_WRITE_SEQUENCER_77 0x304D
-#define WM8996_WRITE_SEQUENCER_78 0x304E
-#define WM8996_WRITE_SEQUENCER_79 0x304F
-#define WM8996_WRITE_SEQUENCER_80 0x3050
-#define WM8996_WRITE_SEQUENCER_81 0x3051
-#define WM8996_WRITE_SEQUENCER_82 0x3052
-#define WM8996_WRITE_SEQUENCER_83 0x3053
-#define WM8996_WRITE_SEQUENCER_84 0x3054
-#define WM8996_WRITE_SEQUENCER_85 0x3055
-#define WM8996_WRITE_SEQUENCER_86 0x3056
-#define WM8996_WRITE_SEQUENCER_87 0x3057
-#define WM8996_WRITE_SEQUENCER_88 0x3058
-#define WM8996_WRITE_SEQUENCER_89 0x3059
-#define WM8996_WRITE_SEQUENCER_90 0x305A
-#define WM8996_WRITE_SEQUENCER_91 0x305B
-#define WM8996_WRITE_SEQUENCER_92 0x305C
-#define WM8996_WRITE_SEQUENCER_93 0x305D
-#define WM8996_WRITE_SEQUENCER_94 0x305E
-#define WM8996_WRITE_SEQUENCER_95 0x305F
-#define WM8996_WRITE_SEQUENCER_96 0x3060
-#define WM8996_WRITE_SEQUENCER_97 0x3061
-#define WM8996_WRITE_SEQUENCER_98 0x3062
-#define WM8996_WRITE_SEQUENCER_99 0x3063
-#define WM8996_WRITE_SEQUENCER_100 0x3064
-#define WM8996_WRITE_SEQUENCER_101 0x3065
-#define WM8996_WRITE_SEQUENCER_102 0x3066
-#define WM8996_WRITE_SEQUENCER_103 0x3067
-#define WM8996_WRITE_SEQUENCER_104 0x3068
-#define WM8996_WRITE_SEQUENCER_105 0x3069
-#define WM8996_WRITE_SEQUENCER_106 0x306A
-#define WM8996_WRITE_SEQUENCER_107 0x306B
-#define WM8996_WRITE_SEQUENCER_108 0x306C
-#define WM8996_WRITE_SEQUENCER_109 0x306D
-#define WM8996_WRITE_SEQUENCER_110 0x306E
-#define WM8996_WRITE_SEQUENCER_111 0x306F
-#define WM8996_WRITE_SEQUENCER_112 0x3070
-#define WM8996_WRITE_SEQUENCER_113 0x3071
-#define WM8996_WRITE_SEQUENCER_114 0x3072
-#define WM8996_WRITE_SEQUENCER_115 0x3073
-#define WM8996_WRITE_SEQUENCER_116 0x3074
-#define WM8996_WRITE_SEQUENCER_117 0x3075
-#define WM8996_WRITE_SEQUENCER_118 0x3076
-#define WM8996_WRITE_SEQUENCER_119 0x3077
-#define WM8996_WRITE_SEQUENCER_120 0x3078
-#define WM8996_WRITE_SEQUENCER_121 0x3079
-#define WM8996_WRITE_SEQUENCER_122 0x307A
-#define WM8996_WRITE_SEQUENCER_123 0x307B
-#define WM8996_WRITE_SEQUENCER_124 0x307C
-#define WM8996_WRITE_SEQUENCER_125 0x307D
-#define WM8996_WRITE_SEQUENCER_126 0x307E
-#define WM8996_WRITE_SEQUENCER_127 0x307F
-#define WM8996_WRITE_SEQUENCER_128 0x3080
-#define WM8996_WRITE_SEQUENCER_129 0x3081
-#define WM8996_WRITE_SEQUENCER_130 0x3082
-#define WM8996_WRITE_SEQUENCER_131 0x3083
-#define WM8996_WRITE_SEQUENCER_132 0x3084
-#define WM8996_WRITE_SEQUENCER_133 0x3085
-#define WM8996_WRITE_SEQUENCER_134 0x3086
-#define WM8996_WRITE_SEQUENCER_135 0x3087
-#define WM8996_WRITE_SEQUENCER_136 0x3088
-#define WM8996_WRITE_SEQUENCER_137 0x3089
-#define WM8996_WRITE_SEQUENCER_138 0x308A
-#define WM8996_WRITE_SEQUENCER_139 0x308B
-#define WM8996_WRITE_SEQUENCER_140 0x308C
-#define WM8996_WRITE_SEQUENCER_141 0x308D
-#define WM8996_WRITE_SEQUENCER_142 0x308E
-#define WM8996_WRITE_SEQUENCER_143 0x308F
-#define WM8996_WRITE_SEQUENCER_144 0x3090
-#define WM8996_WRITE_SEQUENCER_145 0x3091
-#define WM8996_WRITE_SEQUENCER_146 0x3092
-#define WM8996_WRITE_SEQUENCER_147 0x3093
-#define WM8996_WRITE_SEQUENCER_148 0x3094
-#define WM8996_WRITE_SEQUENCER_149 0x3095
-#define WM8996_WRITE_SEQUENCER_150 0x3096
-#define WM8996_WRITE_SEQUENCER_151 0x3097
-#define WM8996_WRITE_SEQUENCER_152 0x3098
-#define WM8996_WRITE_SEQUENCER_153 0x3099
-#define WM8996_WRITE_SEQUENCER_154 0x309A
-#define WM8996_WRITE_SEQUENCER_155 0x309B
-#define WM8996_WRITE_SEQUENCER_156 0x309C
-#define WM8996_WRITE_SEQUENCER_157 0x309D
-#define WM8996_WRITE_SEQUENCER_158 0x309E
-#define WM8996_WRITE_SEQUENCER_159 0x309F
-#define WM8996_WRITE_SEQUENCER_160 0x30A0
-#define WM8996_WRITE_SEQUENCER_161 0x30A1
-#define WM8996_WRITE_SEQUENCER_162 0x30A2
-#define WM8996_WRITE_SEQUENCER_163 0x30A3
-#define WM8996_WRITE_SEQUENCER_164 0x30A4
-#define WM8996_WRITE_SEQUENCER_165 0x30A5
-#define WM8996_WRITE_SEQUENCER_166 0x30A6
-#define WM8996_WRITE_SEQUENCER_167 0x30A7
-#define WM8996_WRITE_SEQUENCER_168 0x30A8
-#define WM8996_WRITE_SEQUENCER_169 0x30A9
-#define WM8996_WRITE_SEQUENCER_170 0x30AA
-#define WM8996_WRITE_SEQUENCER_171 0x30AB
-#define WM8996_WRITE_SEQUENCER_172 0x30AC
-#define WM8996_WRITE_SEQUENCER_173 0x30AD
-#define WM8996_WRITE_SEQUENCER_174 0x30AE
-#define WM8996_WRITE_SEQUENCER_175 0x30AF
-#define WM8996_WRITE_SEQUENCER_176 0x30B0
-#define WM8996_WRITE_SEQUENCER_177 0x30B1
-#define WM8996_WRITE_SEQUENCER_178 0x30B2
-#define WM8996_WRITE_SEQUENCER_179 0x30B3
-#define WM8996_WRITE_SEQUENCER_180 0x30B4
-#define WM8996_WRITE_SEQUENCER_181 0x30B5
-#define WM8996_WRITE_SEQUENCER_182 0x30B6
-#define WM8996_WRITE_SEQUENCER_183 0x30B7
-#define WM8996_WRITE_SEQUENCER_184 0x30B8
-#define WM8996_WRITE_SEQUENCER_185 0x30B9
-#define WM8996_WRITE_SEQUENCER_186 0x30BA
-#define WM8996_WRITE_SEQUENCER_187 0x30BB
-#define WM8996_WRITE_SEQUENCER_188 0x30BC
-#define WM8996_WRITE_SEQUENCER_189 0x30BD
-#define WM8996_WRITE_SEQUENCER_190 0x30BE
-#define WM8996_WRITE_SEQUENCER_191 0x30BF
-#define WM8996_WRITE_SEQUENCER_192 0x30C0
-#define WM8996_WRITE_SEQUENCER_193 0x30C1
-#define WM8996_WRITE_SEQUENCER_194 0x30C2
-#define WM8996_WRITE_SEQUENCER_195 0x30C3
-#define WM8996_WRITE_SEQUENCER_196 0x30C4
-#define WM8996_WRITE_SEQUENCER_197 0x30C5
-#define WM8996_WRITE_SEQUENCER_198 0x30C6
-#define WM8996_WRITE_SEQUENCER_199 0x30C7
-#define WM8996_WRITE_SEQUENCER_200 0x30C8
-#define WM8996_WRITE_SEQUENCER_201 0x30C9
-#define WM8996_WRITE_SEQUENCER_202 0x30CA
-#define WM8996_WRITE_SEQUENCER_203 0x30CB
-#define WM8996_WRITE_SEQUENCER_204 0x30CC
-#define WM8996_WRITE_SEQUENCER_205 0x30CD
-#define WM8996_WRITE_SEQUENCER_206 0x30CE
-#define WM8996_WRITE_SEQUENCER_207 0x30CF
-#define WM8996_WRITE_SEQUENCER_208 0x30D0
-#define WM8996_WRITE_SEQUENCER_209 0x30D1
-#define WM8996_WRITE_SEQUENCER_210 0x30D2
-#define WM8996_WRITE_SEQUENCER_211 0x30D3
-#define WM8996_WRITE_SEQUENCER_212 0x30D4
-#define WM8996_WRITE_SEQUENCER_213 0x30D5
-#define WM8996_WRITE_SEQUENCER_214 0x30D6
-#define WM8996_WRITE_SEQUENCER_215 0x30D7
-#define WM8996_WRITE_SEQUENCER_216 0x30D8
-#define WM8996_WRITE_SEQUENCER_217 0x30D9
-#define WM8996_WRITE_SEQUENCER_218 0x30DA
-#define WM8996_WRITE_SEQUENCER_219 0x30DB
-#define WM8996_WRITE_SEQUENCER_220 0x30DC
-#define WM8996_WRITE_SEQUENCER_221 0x30DD
-#define WM8996_WRITE_SEQUENCER_222 0x30DE
-#define WM8996_WRITE_SEQUENCER_223 0x30DF
-#define WM8996_WRITE_SEQUENCER_224 0x30E0
-#define WM8996_WRITE_SEQUENCER_225 0x30E1
-#define WM8996_WRITE_SEQUENCER_226 0x30E2
-#define WM8996_WRITE_SEQUENCER_227 0x30E3
-#define WM8996_WRITE_SEQUENCER_228 0x30E4
-#define WM8996_WRITE_SEQUENCER_229 0x30E5
-#define WM8996_WRITE_SEQUENCER_230 0x30E6
-#define WM8996_WRITE_SEQUENCER_231 0x30E7
-#define WM8996_WRITE_SEQUENCER_232 0x30E8
-#define WM8996_WRITE_SEQUENCER_233 0x30E9
-#define WM8996_WRITE_SEQUENCER_234 0x30EA
-#define WM8996_WRITE_SEQUENCER_235 0x30EB
-#define WM8996_WRITE_SEQUENCER_236 0x30EC
-#define WM8996_WRITE_SEQUENCER_237 0x30ED
-#define WM8996_WRITE_SEQUENCER_238 0x30EE
-#define WM8996_WRITE_SEQUENCER_239 0x30EF
-#define WM8996_WRITE_SEQUENCER_240 0x30F0
-#define WM8996_WRITE_SEQUENCER_241 0x30F1
-#define WM8996_WRITE_SEQUENCER_242 0x30F2
-#define WM8996_WRITE_SEQUENCER_243 0x30F3
-#define WM8996_WRITE_SEQUENCER_244 0x30F4
-#define WM8996_WRITE_SEQUENCER_245 0x30F5
-#define WM8996_WRITE_SEQUENCER_246 0x30F6
-#define WM8996_WRITE_SEQUENCER_247 0x30F7
-#define WM8996_WRITE_SEQUENCER_248 0x30F8
-#define WM8996_WRITE_SEQUENCER_249 0x30F9
-#define WM8996_WRITE_SEQUENCER_250 0x30FA
-#define WM8996_WRITE_SEQUENCER_251 0x30FB
-#define WM8996_WRITE_SEQUENCER_252 0x30FC
-#define WM8996_WRITE_SEQUENCER_253 0x30FD
-#define WM8996_WRITE_SEQUENCER_254 0x30FE
-#define WM8996_WRITE_SEQUENCER_255 0x30FF
-#define WM8996_WRITE_SEQUENCER_256 0x3100
-#define WM8996_WRITE_SEQUENCER_257 0x3101
-#define WM8996_WRITE_SEQUENCER_258 0x3102
-#define WM8996_WRITE_SEQUENCER_259 0x3103
-#define WM8996_WRITE_SEQUENCER_260 0x3104
-#define WM8996_WRITE_SEQUENCER_261 0x3105
-#define WM8996_WRITE_SEQUENCER_262 0x3106
-#define WM8996_WRITE_SEQUENCER_263 0x3107
-#define WM8996_WRITE_SEQUENCER_264 0x3108
-#define WM8996_WRITE_SEQUENCER_265 0x3109
-#define WM8996_WRITE_SEQUENCER_266 0x310A
-#define WM8996_WRITE_SEQUENCER_267 0x310B
-#define WM8996_WRITE_SEQUENCER_268 0x310C
-#define WM8996_WRITE_SEQUENCER_269 0x310D
-#define WM8996_WRITE_SEQUENCER_270 0x310E
-#define WM8996_WRITE_SEQUENCER_271 0x310F
-#define WM8996_WRITE_SEQUENCER_272 0x3110
-#define WM8996_WRITE_SEQUENCER_273 0x3111
-#define WM8996_WRITE_SEQUENCER_274 0x3112
-#define WM8996_WRITE_SEQUENCER_275 0x3113
-#define WM8996_WRITE_SEQUENCER_276 0x3114
-#define WM8996_WRITE_SEQUENCER_277 0x3115
-#define WM8996_WRITE_SEQUENCER_278 0x3116
-#define WM8996_WRITE_SEQUENCER_279 0x3117
-#define WM8996_WRITE_SEQUENCER_280 0x3118
-#define WM8996_WRITE_SEQUENCER_281 0x3119
-#define WM8996_WRITE_SEQUENCER_282 0x311A
-#define WM8996_WRITE_SEQUENCER_283 0x311B
-#define WM8996_WRITE_SEQUENCER_284 0x311C
-#define WM8996_WRITE_SEQUENCER_285 0x311D
-#define WM8996_WRITE_SEQUENCER_286 0x311E
-#define WM8996_WRITE_SEQUENCER_287 0x311F
-#define WM8996_WRITE_SEQUENCER_288 0x3120
-#define WM8996_WRITE_SEQUENCER_289 0x3121
-#define WM8996_WRITE_SEQUENCER_290 0x3122
-#define WM8996_WRITE_SEQUENCER_291 0x3123
-#define WM8996_WRITE_SEQUENCER_292 0x3124
-#define WM8996_WRITE_SEQUENCER_293 0x3125
-#define WM8996_WRITE_SEQUENCER_294 0x3126
-#define WM8996_WRITE_SEQUENCER_295 0x3127
-#define WM8996_WRITE_SEQUENCER_296 0x3128
-#define WM8996_WRITE_SEQUENCER_297 0x3129
-#define WM8996_WRITE_SEQUENCER_298 0x312A
-#define WM8996_WRITE_SEQUENCER_299 0x312B
-#define WM8996_WRITE_SEQUENCER_300 0x312C
-#define WM8996_WRITE_SEQUENCER_301 0x312D
-#define WM8996_WRITE_SEQUENCER_302 0x312E
-#define WM8996_WRITE_SEQUENCER_303 0x312F
-#define WM8996_WRITE_SEQUENCER_304 0x3130
-#define WM8996_WRITE_SEQUENCER_305 0x3131
-#define WM8996_WRITE_SEQUENCER_306 0x3132
-#define WM8996_WRITE_SEQUENCER_307 0x3133
-#define WM8996_WRITE_SEQUENCER_308 0x3134
-#define WM8996_WRITE_SEQUENCER_309 0x3135
-#define WM8996_WRITE_SEQUENCER_310 0x3136
-#define WM8996_WRITE_SEQUENCER_311 0x3137
-#define WM8996_WRITE_SEQUENCER_312 0x3138
-#define WM8996_WRITE_SEQUENCER_313 0x3139
-#define WM8996_WRITE_SEQUENCER_314 0x313A
-#define WM8996_WRITE_SEQUENCER_315 0x313B
-#define WM8996_WRITE_SEQUENCER_316 0x313C
-#define WM8996_WRITE_SEQUENCER_317 0x313D
-#define WM8996_WRITE_SEQUENCER_318 0x313E
-#define WM8996_WRITE_SEQUENCER_319 0x313F
-#define WM8996_WRITE_SEQUENCER_320 0x3140
-#define WM8996_WRITE_SEQUENCER_321 0x3141
-#define WM8996_WRITE_SEQUENCER_322 0x3142
-#define WM8996_WRITE_SEQUENCER_323 0x3143
-#define WM8996_WRITE_SEQUENCER_324 0x3144
-#define WM8996_WRITE_SEQUENCER_325 0x3145
-#define WM8996_WRITE_SEQUENCER_326 0x3146
-#define WM8996_WRITE_SEQUENCER_327 0x3147
-#define WM8996_WRITE_SEQUENCER_328 0x3148
-#define WM8996_WRITE_SEQUENCER_329 0x3149
-#define WM8996_WRITE_SEQUENCER_330 0x314A
-#define WM8996_WRITE_SEQUENCER_331 0x314B
-#define WM8996_WRITE_SEQUENCER_332 0x314C
-#define WM8996_WRITE_SEQUENCER_333 0x314D
-#define WM8996_WRITE_SEQUENCER_334 0x314E
-#define WM8996_WRITE_SEQUENCER_335 0x314F
-#define WM8996_WRITE_SEQUENCER_336 0x3150
-#define WM8996_WRITE_SEQUENCER_337 0x3151
-#define WM8996_WRITE_SEQUENCER_338 0x3152
-#define WM8996_WRITE_SEQUENCER_339 0x3153
-#define WM8996_WRITE_SEQUENCER_340 0x3154
-#define WM8996_WRITE_SEQUENCER_341 0x3155
-#define WM8996_WRITE_SEQUENCER_342 0x3156
-#define WM8996_WRITE_SEQUENCER_343 0x3157
-#define WM8996_WRITE_SEQUENCER_344 0x3158
-#define WM8996_WRITE_SEQUENCER_345 0x3159
-#define WM8996_WRITE_SEQUENCER_346 0x315A
-#define WM8996_WRITE_SEQUENCER_347 0x315B
-#define WM8996_WRITE_SEQUENCER_348 0x315C
-#define WM8996_WRITE_SEQUENCER_349 0x315D
-#define WM8996_WRITE_SEQUENCER_350 0x315E
-#define WM8996_WRITE_SEQUENCER_351 0x315F
-#define WM8996_WRITE_SEQUENCER_352 0x3160
-#define WM8996_WRITE_SEQUENCER_353 0x3161
-#define WM8996_WRITE_SEQUENCER_354 0x3162
-#define WM8996_WRITE_SEQUENCER_355 0x3163
-#define WM8996_WRITE_SEQUENCER_356 0x3164
-#define WM8996_WRITE_SEQUENCER_357 0x3165
-#define WM8996_WRITE_SEQUENCER_358 0x3166
-#define WM8996_WRITE_SEQUENCER_359 0x3167
-#define WM8996_WRITE_SEQUENCER_360 0x3168
-#define WM8996_WRITE_SEQUENCER_361 0x3169
-#define WM8996_WRITE_SEQUENCER_362 0x316A
-#define WM8996_WRITE_SEQUENCER_363 0x316B
-#define WM8996_WRITE_SEQUENCER_364 0x316C
-#define WM8996_WRITE_SEQUENCER_365 0x316D
-#define WM8996_WRITE_SEQUENCER_366 0x316E
-#define WM8996_WRITE_SEQUENCER_367 0x316F
-#define WM8996_WRITE_SEQUENCER_368 0x3170
-#define WM8996_WRITE_SEQUENCER_369 0x3171
-#define WM8996_WRITE_SEQUENCER_370 0x3172
-#define WM8996_WRITE_SEQUENCER_371 0x3173
-#define WM8996_WRITE_SEQUENCER_372 0x3174
-#define WM8996_WRITE_SEQUENCER_373 0x3175
-#define WM8996_WRITE_SEQUENCER_374 0x3176
-#define WM8996_WRITE_SEQUENCER_375 0x3177
-#define WM8996_WRITE_SEQUENCER_376 0x3178
-#define WM8996_WRITE_SEQUENCER_377 0x3179
-#define WM8996_WRITE_SEQUENCER_378 0x317A
-#define WM8996_WRITE_SEQUENCER_379 0x317B
-#define WM8996_WRITE_SEQUENCER_380 0x317C
-#define WM8996_WRITE_SEQUENCER_381 0x317D
-#define WM8996_WRITE_SEQUENCER_382 0x317E
-#define WM8996_WRITE_SEQUENCER_383 0x317F
-#define WM8996_WRITE_SEQUENCER_384 0x3180
-#define WM8996_WRITE_SEQUENCER_385 0x3181
-#define WM8996_WRITE_SEQUENCER_386 0x3182
-#define WM8996_WRITE_SEQUENCER_387 0x3183
-#define WM8996_WRITE_SEQUENCER_388 0x3184
-#define WM8996_WRITE_SEQUENCER_389 0x3185
-#define WM8996_WRITE_SEQUENCER_390 0x3186
-#define WM8996_WRITE_SEQUENCER_391 0x3187
-#define WM8996_WRITE_SEQUENCER_392 0x3188
-#define WM8996_WRITE_SEQUENCER_393 0x3189
-#define WM8996_WRITE_SEQUENCER_394 0x318A
-#define WM8996_WRITE_SEQUENCER_395 0x318B
-#define WM8996_WRITE_SEQUENCER_396 0x318C
-#define WM8996_WRITE_SEQUENCER_397 0x318D
-#define WM8996_WRITE_SEQUENCER_398 0x318E
-#define WM8996_WRITE_SEQUENCER_399 0x318F
-#define WM8996_WRITE_SEQUENCER_400 0x3190
-#define WM8996_WRITE_SEQUENCER_401 0x3191
-#define WM8996_WRITE_SEQUENCER_402 0x3192
-#define WM8996_WRITE_SEQUENCER_403 0x3193
-#define WM8996_WRITE_SEQUENCER_404 0x3194
-#define WM8996_WRITE_SEQUENCER_405 0x3195
-#define WM8996_WRITE_SEQUENCER_406 0x3196
-#define WM8996_WRITE_SEQUENCER_407 0x3197
-#define WM8996_WRITE_SEQUENCER_408 0x3198
-#define WM8996_WRITE_SEQUENCER_409 0x3199
-#define WM8996_WRITE_SEQUENCER_410 0x319A
-#define WM8996_WRITE_SEQUENCER_411 0x319B
-#define WM8996_WRITE_SEQUENCER_412 0x319C
-#define WM8996_WRITE_SEQUENCER_413 0x319D
-#define WM8996_WRITE_SEQUENCER_414 0x319E
-#define WM8996_WRITE_SEQUENCER_415 0x319F
-#define WM8996_WRITE_SEQUENCER_416 0x31A0
-#define WM8996_WRITE_SEQUENCER_417 0x31A1
-#define WM8996_WRITE_SEQUENCER_418 0x31A2
-#define WM8996_WRITE_SEQUENCER_419 0x31A3
-#define WM8996_WRITE_SEQUENCER_420 0x31A4
-#define WM8996_WRITE_SEQUENCER_421 0x31A5
-#define WM8996_WRITE_SEQUENCER_422 0x31A6
-#define WM8996_WRITE_SEQUENCER_423 0x31A7
-#define WM8996_WRITE_SEQUENCER_424 0x31A8
-#define WM8996_WRITE_SEQUENCER_425 0x31A9
-#define WM8996_WRITE_SEQUENCER_426 0x31AA
-#define WM8996_WRITE_SEQUENCER_427 0x31AB
-#define WM8996_WRITE_SEQUENCER_428 0x31AC
-#define WM8996_WRITE_SEQUENCER_429 0x31AD
-#define WM8996_WRITE_SEQUENCER_430 0x31AE
-#define WM8996_WRITE_SEQUENCER_431 0x31AF
-#define WM8996_WRITE_SEQUENCER_432 0x31B0
-#define WM8996_WRITE_SEQUENCER_433 0x31B1
-#define WM8996_WRITE_SEQUENCER_434 0x31B2
-#define WM8996_WRITE_SEQUENCER_435 0x31B3
-#define WM8996_WRITE_SEQUENCER_436 0x31B4
-#define WM8996_WRITE_SEQUENCER_437 0x31B5
-#define WM8996_WRITE_SEQUENCER_438 0x31B6
-#define WM8996_WRITE_SEQUENCER_439 0x31B7
-#define WM8996_WRITE_SEQUENCER_440 0x31B8
-#define WM8996_WRITE_SEQUENCER_441 0x31B9
-#define WM8996_WRITE_SEQUENCER_442 0x31BA
-#define WM8996_WRITE_SEQUENCER_443 0x31BB
-#define WM8996_WRITE_SEQUENCER_444 0x31BC
-#define WM8996_WRITE_SEQUENCER_445 0x31BD
-#define WM8996_WRITE_SEQUENCER_446 0x31BE
-#define WM8996_WRITE_SEQUENCER_447 0x31BF
-#define WM8996_WRITE_SEQUENCER_448 0x31C0
-#define WM8996_WRITE_SEQUENCER_449 0x31C1
-#define WM8996_WRITE_SEQUENCER_450 0x31C2
-#define WM8996_WRITE_SEQUENCER_451 0x31C3
-#define WM8996_WRITE_SEQUENCER_452 0x31C4
-#define WM8996_WRITE_SEQUENCER_453 0x31C5
-#define WM8996_WRITE_SEQUENCER_454 0x31C6
-#define WM8996_WRITE_SEQUENCER_455 0x31C7
-#define WM8996_WRITE_SEQUENCER_456 0x31C8
-#define WM8996_WRITE_SEQUENCER_457 0x31C9
-#define WM8996_WRITE_SEQUENCER_458 0x31CA
-#define WM8996_WRITE_SEQUENCER_459 0x31CB
-#define WM8996_WRITE_SEQUENCER_460 0x31CC
-#define WM8996_WRITE_SEQUENCER_461 0x31CD
-#define WM8996_WRITE_SEQUENCER_462 0x31CE
-#define WM8996_WRITE_SEQUENCER_463 0x31CF
-#define WM8996_WRITE_SEQUENCER_464 0x31D0
-#define WM8996_WRITE_SEQUENCER_465 0x31D1
-#define WM8996_WRITE_SEQUENCER_466 0x31D2
-#define WM8996_WRITE_SEQUENCER_467 0x31D3
-#define WM8996_WRITE_SEQUENCER_468 0x31D4
-#define WM8996_WRITE_SEQUENCER_469 0x31D5
-#define WM8996_WRITE_SEQUENCER_470 0x31D6
-#define WM8996_WRITE_SEQUENCER_471 0x31D7
-#define WM8996_WRITE_SEQUENCER_472 0x31D8
-#define WM8996_WRITE_SEQUENCER_473 0x31D9
-#define WM8996_WRITE_SEQUENCER_474 0x31DA
-#define WM8996_WRITE_SEQUENCER_475 0x31DB
-#define WM8996_WRITE_SEQUENCER_476 0x31DC
-#define WM8996_WRITE_SEQUENCER_477 0x31DD
-#define WM8996_WRITE_SEQUENCER_478 0x31DE
-#define WM8996_WRITE_SEQUENCER_479 0x31DF
-#define WM8996_WRITE_SEQUENCER_480 0x31E0
-#define WM8996_WRITE_SEQUENCER_481 0x31E1
-#define WM8996_WRITE_SEQUENCER_482 0x31E2
-#define WM8996_WRITE_SEQUENCER_483 0x31E3
-#define WM8996_WRITE_SEQUENCER_484 0x31E4
-#define WM8996_WRITE_SEQUENCER_485 0x31E5
-#define WM8996_WRITE_SEQUENCER_486 0x31E6
-#define WM8996_WRITE_SEQUENCER_487 0x31E7
-#define WM8996_WRITE_SEQUENCER_488 0x31E8
-#define WM8996_WRITE_SEQUENCER_489 0x31E9
-#define WM8996_WRITE_SEQUENCER_490 0x31EA
-#define WM8996_WRITE_SEQUENCER_491 0x31EB
-#define WM8996_WRITE_SEQUENCER_492 0x31EC
-#define WM8996_WRITE_SEQUENCER_493 0x31ED
-#define WM8996_WRITE_SEQUENCER_494 0x31EE
-#define WM8996_WRITE_SEQUENCER_495 0x31EF
-#define WM8996_WRITE_SEQUENCER_496 0x31F0
-#define WM8996_WRITE_SEQUENCER_497 0x31F1
-#define WM8996_WRITE_SEQUENCER_498 0x31F2
-#define WM8996_WRITE_SEQUENCER_499 0x31F3
-#define WM8996_WRITE_SEQUENCER_500 0x31F4
-#define WM8996_WRITE_SEQUENCER_501 0x31F5
-#define WM8996_WRITE_SEQUENCER_502 0x31F6
-#define WM8996_WRITE_SEQUENCER_503 0x31F7
-#define WM8996_WRITE_SEQUENCER_504 0x31F8
-#define WM8996_WRITE_SEQUENCER_505 0x31F9
-#define WM8996_WRITE_SEQUENCER_506 0x31FA
-#define WM8996_WRITE_SEQUENCER_507 0x31FB
-#define WM8996_WRITE_SEQUENCER_508 0x31FC
-#define WM8996_WRITE_SEQUENCER_509 0x31FD
-#define WM8996_WRITE_SEQUENCER_510 0x31FE
-#define WM8996_WRITE_SEQUENCER_511 0x31FF
-
-#define WM8996_REGISTER_COUNT 706
-#define WM8996_MAX_REGISTER 0x31FF
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - Software Reset
- */
-#define WM8996_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
-#define WM8996_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
-#define WM8996_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
-
-/*
- * R1 (0x01) - Power Management (1)
- */
-#define WM8996_MICB2_ENA 0x0200 /* MICB2_ENA */
-#define WM8996_MICB2_ENA_MASK 0x0200 /* MICB2_ENA */
-#define WM8996_MICB2_ENA_SHIFT 9 /* MICB2_ENA */
-#define WM8996_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
-#define WM8996_MICB1_ENA 0x0100 /* MICB1_ENA */
-#define WM8996_MICB1_ENA_MASK 0x0100 /* MICB1_ENA */
-#define WM8996_MICB1_ENA_SHIFT 8 /* MICB1_ENA */
-#define WM8996_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
-#define WM8996_HPOUT2L_ENA 0x0080 /* HPOUT2L_ENA */
-#define WM8996_HPOUT2L_ENA_MASK 0x0080 /* HPOUT2L_ENA */
-#define WM8996_HPOUT2L_ENA_SHIFT 7 /* HPOUT2L_ENA */
-#define WM8996_HPOUT2L_ENA_WIDTH 1 /* HPOUT2L_ENA */
-#define WM8996_HPOUT2R_ENA 0x0040 /* HPOUT2R_ENA */
-#define WM8996_HPOUT2R_ENA_MASK 0x0040 /* HPOUT2R_ENA */
-#define WM8996_HPOUT2R_ENA_SHIFT 6 /* HPOUT2R_ENA */
-#define WM8996_HPOUT2R_ENA_WIDTH 1 /* HPOUT2R_ENA */
-#define WM8996_HPOUT1L_ENA 0x0020 /* HPOUT1L_ENA */
-#define WM8996_HPOUT1L_ENA_MASK 0x0020 /* HPOUT1L_ENA */
-#define WM8996_HPOUT1L_ENA_SHIFT 5 /* HPOUT1L_ENA */
-#define WM8996_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */
-#define WM8996_HPOUT1R_ENA 0x0010 /* HPOUT1R_ENA */
-#define WM8996_HPOUT1R_ENA_MASK 0x0010 /* HPOUT1R_ENA */
-#define WM8996_HPOUT1R_ENA_SHIFT 4 /* HPOUT1R_ENA */
-#define WM8996_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */
-#define WM8996_BG_ENA 0x0001 /* BG_ENA */
-#define WM8996_BG_ENA_MASK 0x0001 /* BG_ENA */
-#define WM8996_BG_ENA_SHIFT 0 /* BG_ENA */
-#define WM8996_BG_ENA_WIDTH 1 /* BG_ENA */
-
-/*
- * R2 (0x02) - Power Management (2)
- */
-#define WM8996_OPCLK_ENA 0x0800 /* OPCLK_ENA */
-#define WM8996_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */
-#define WM8996_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */
-#define WM8996_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
-#define WM8996_INL_ENA 0x0020 /* INL_ENA */
-#define WM8996_INL_ENA_MASK 0x0020 /* INL_ENA */
-#define WM8996_INL_ENA_SHIFT 5 /* INL_ENA */
-#define WM8996_INL_ENA_WIDTH 1 /* INL_ENA */
-#define WM8996_INR_ENA 0x0010 /* INR_ENA */
-#define WM8996_INR_ENA_MASK 0x0010 /* INR_ENA */
-#define WM8996_INR_ENA_SHIFT 4 /* INR_ENA */
-#define WM8996_INR_ENA_WIDTH 1 /* INR_ENA */
-#define WM8996_LDO2_ENA 0x0002 /* LDO2_ENA */
-#define WM8996_LDO2_ENA_MASK 0x0002 /* LDO2_ENA */
-#define WM8996_LDO2_ENA_SHIFT 1 /* LDO2_ENA */
-#define WM8996_LDO2_ENA_WIDTH 1 /* LDO2_ENA */
-
-/*
- * R3 (0x03) - Power Management (3)
- */
-#define WM8996_DSP2RXL_ENA 0x0800 /* DSP2RXL_ENA */
-#define WM8996_DSP2RXL_ENA_MASK 0x0800 /* DSP2RXL_ENA */
-#define WM8996_DSP2RXL_ENA_SHIFT 11 /* DSP2RXL_ENA */
-#define WM8996_DSP2RXL_ENA_WIDTH 1 /* DSP2RXL_ENA */
-#define WM8996_DSP2RXR_ENA 0x0400 /* DSP2RXR_ENA */
-#define WM8996_DSP2RXR_ENA_MASK 0x0400 /* DSP2RXR_ENA */
-#define WM8996_DSP2RXR_ENA_SHIFT 10 /* DSP2RXR_ENA */
-#define WM8996_DSP2RXR_ENA_WIDTH 1 /* DSP2RXR_ENA */
-#define WM8996_DSP1RXL_ENA 0x0200 /* DSP1RXL_ENA */
-#define WM8996_DSP1RXL_ENA_MASK 0x0200 /* DSP1RXL_ENA */
-#define WM8996_DSP1RXL_ENA_SHIFT 9 /* DSP1RXL_ENA */
-#define WM8996_DSP1RXL_ENA_WIDTH 1 /* DSP1RXL_ENA */
-#define WM8996_DSP1RXR_ENA 0x0100 /* DSP1RXR_ENA */
-#define WM8996_DSP1RXR_ENA_MASK 0x0100 /* DSP1RXR_ENA */
-#define WM8996_DSP1RXR_ENA_SHIFT 8 /* DSP1RXR_ENA */
-#define WM8996_DSP1RXR_ENA_WIDTH 1 /* DSP1RXR_ENA */
-#define WM8996_DMIC2L_ENA 0x0020 /* DMIC2L_ENA */
-#define WM8996_DMIC2L_ENA_MASK 0x0020 /* DMIC2L_ENA */
-#define WM8996_DMIC2L_ENA_SHIFT 5 /* DMIC2L_ENA */
-#define WM8996_DMIC2L_ENA_WIDTH 1 /* DMIC2L_ENA */
-#define WM8996_DMIC2R_ENA 0x0010 /* DMIC2R_ENA */
-#define WM8996_DMIC2R_ENA_MASK 0x0010 /* DMIC2R_ENA */
-#define WM8996_DMIC2R_ENA_SHIFT 4 /* DMIC2R_ENA */
-#define WM8996_DMIC2R_ENA_WIDTH 1 /* DMIC2R_ENA */
-#define WM8996_DMIC1L_ENA 0x0008 /* DMIC1L_ENA */
-#define WM8996_DMIC1L_ENA_MASK 0x0008 /* DMIC1L_ENA */
-#define WM8996_DMIC1L_ENA_SHIFT 3 /* DMIC1L_ENA */
-#define WM8996_DMIC1L_ENA_WIDTH 1 /* DMIC1L_ENA */
-#define WM8996_DMIC1R_ENA 0x0004 /* DMIC1R_ENA */
-#define WM8996_DMIC1R_ENA_MASK 0x0004 /* DMIC1R_ENA */
-#define WM8996_DMIC1R_ENA_SHIFT 2 /* DMIC1R_ENA */
-#define WM8996_DMIC1R_ENA_WIDTH 1 /* DMIC1R_ENA */
-#define WM8996_ADCL_ENA 0x0002 /* ADCL_ENA */
-#define WM8996_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
-#define WM8996_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
-#define WM8996_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
-#define WM8996_ADCR_ENA 0x0001 /* ADCR_ENA */
-#define WM8996_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
-#define WM8996_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
-#define WM8996_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
-
-/*
- * R4 (0x04) - Power Management (4)
- */
-#define WM8996_AIF2RX_CHAN1_ENA 0x0200 /* AIF2RX_CHAN1_ENA */
-#define WM8996_AIF2RX_CHAN1_ENA_MASK 0x0200 /* AIF2RX_CHAN1_ENA */
-#define WM8996_AIF2RX_CHAN1_ENA_SHIFT 9 /* AIF2RX_CHAN1_ENA */
-#define WM8996_AIF2RX_CHAN1_ENA_WIDTH 1 /* AIF2RX_CHAN1_ENA */
-#define WM8996_AIF2RX_CHAN0_ENA 0x0100 /* AIF2RX_CHAN0_ENA */
-#define WM8996_AIF2RX_CHAN0_ENA_MASK 0x0100 /* AIF2RX_CHAN0_ENA */
-#define WM8996_AIF2RX_CHAN0_ENA_SHIFT 8 /* AIF2RX_CHAN0_ENA */
-#define WM8996_AIF2RX_CHAN0_ENA_WIDTH 1 /* AIF2RX_CHAN0_ENA */
-#define WM8996_AIF1RX_CHAN5_ENA 0x0020 /* AIF1RX_CHAN5_ENA */
-#define WM8996_AIF1RX_CHAN5_ENA_MASK 0x0020 /* AIF1RX_CHAN5_ENA */
-#define WM8996_AIF1RX_CHAN5_ENA_SHIFT 5 /* AIF1RX_CHAN5_ENA */
-#define WM8996_AIF1RX_CHAN5_ENA_WIDTH 1 /* AIF1RX_CHAN5_ENA */
-#define WM8996_AIF1RX_CHAN4_ENA 0x0010 /* AIF1RX_CHAN4_ENA */
-#define WM8996_AIF1RX_CHAN4_ENA_MASK 0x0010 /* AIF1RX_CHAN4_ENA */
-#define WM8996_AIF1RX_CHAN4_ENA_SHIFT 4 /* AIF1RX_CHAN4_ENA */
-#define WM8996_AIF1RX_CHAN4_ENA_WIDTH 1 /* AIF1RX_CHAN4_ENA */
-#define WM8996_AIF1RX_CHAN3_ENA 0x0008 /* AIF1RX_CHAN3_ENA */
-#define WM8996_AIF1RX_CHAN3_ENA_MASK 0x0008 /* AIF1RX_CHAN3_ENA */
-#define WM8996_AIF1RX_CHAN3_ENA_SHIFT 3 /* AIF1RX_CHAN3_ENA */
-#define WM8996_AIF1RX_CHAN3_ENA_WIDTH 1 /* AIF1RX_CHAN3_ENA */
-#define WM8996_AIF1RX_CHAN2_ENA 0x0004 /* AIF1RX_CHAN2_ENA */
-#define WM8996_AIF1RX_CHAN2_ENA_MASK 0x0004 /* AIF1RX_CHAN2_ENA */
-#define WM8996_AIF1RX_CHAN2_ENA_SHIFT 2 /* AIF1RX_CHAN2_ENA */
-#define WM8996_AIF1RX_CHAN2_ENA_WIDTH 1 /* AIF1RX_CHAN2_ENA */
-#define WM8996_AIF1RX_CHAN1_ENA 0x0002 /* AIF1RX_CHAN1_ENA */
-#define WM8996_AIF1RX_CHAN1_ENA_MASK 0x0002 /* AIF1RX_CHAN1_ENA */
-#define WM8996_AIF1RX_CHAN1_ENA_SHIFT 1 /* AIF1RX_CHAN1_ENA */
-#define WM8996_AIF1RX_CHAN1_ENA_WIDTH 1 /* AIF1RX_CHAN1_ENA */
-#define WM8996_AIF1RX_CHAN0_ENA 0x0001 /* AIF1RX_CHAN0_ENA */
-#define WM8996_AIF1RX_CHAN0_ENA_MASK 0x0001 /* AIF1RX_CHAN0_ENA */
-#define WM8996_AIF1RX_CHAN0_ENA_SHIFT 0 /* AIF1RX_CHAN0_ENA */
-#define WM8996_AIF1RX_CHAN0_ENA_WIDTH 1 /* AIF1RX_CHAN0_ENA */
-
-/*
- * R5 (0x05) - Power Management (5)
- */
-#define WM8996_DSP2TXL_ENA 0x0800 /* DSP2TXL_ENA */
-#define WM8996_DSP2TXL_ENA_MASK 0x0800 /* DSP2TXL_ENA */
-#define WM8996_DSP2TXL_ENA_SHIFT 11 /* DSP2TXL_ENA */
-#define WM8996_DSP2TXL_ENA_WIDTH 1 /* DSP2TXL_ENA */
-#define WM8996_DSP2TXR_ENA 0x0400 /* DSP2TXR_ENA */
-#define WM8996_DSP2TXR_ENA_MASK 0x0400 /* DSP2TXR_ENA */
-#define WM8996_DSP2TXR_ENA_SHIFT 10 /* DSP2TXR_ENA */
-#define WM8996_DSP2TXR_ENA_WIDTH 1 /* DSP2TXR_ENA */
-#define WM8996_DSP1TXL_ENA 0x0200 /* DSP1TXL_ENA */
-#define WM8996_DSP1TXL_ENA_MASK 0x0200 /* DSP1TXL_ENA */
-#define WM8996_DSP1TXL_ENA_SHIFT 9 /* DSP1TXL_ENA */
-#define WM8996_DSP1TXL_ENA_WIDTH 1 /* DSP1TXL_ENA */
-#define WM8996_DSP1TXR_ENA 0x0100 /* DSP1TXR_ENA */
-#define WM8996_DSP1TXR_ENA_MASK 0x0100 /* DSP1TXR_ENA */
-#define WM8996_DSP1TXR_ENA_SHIFT 8 /* DSP1TXR_ENA */
-#define WM8996_DSP1TXR_ENA_WIDTH 1 /* DSP1TXR_ENA */
-#define WM8996_DAC2L_ENA 0x0008 /* DAC2L_ENA */
-#define WM8996_DAC2L_ENA_MASK 0x0008 /* DAC2L_ENA */
-#define WM8996_DAC2L_ENA_SHIFT 3 /* DAC2L_ENA */
-#define WM8996_DAC2L_ENA_WIDTH 1 /* DAC2L_ENA */
-#define WM8996_DAC2R_ENA 0x0004 /* DAC2R_ENA */
-#define WM8996_DAC2R_ENA_MASK 0x0004 /* DAC2R_ENA */
-#define WM8996_DAC2R_ENA_SHIFT 2 /* DAC2R_ENA */
-#define WM8996_DAC2R_ENA_WIDTH 1 /* DAC2R_ENA */
-#define WM8996_DAC1L_ENA 0x0002 /* DAC1L_ENA */
-#define WM8996_DAC1L_ENA_MASK 0x0002 /* DAC1L_ENA */
-#define WM8996_DAC1L_ENA_SHIFT 1 /* DAC1L_ENA */
-#define WM8996_DAC1L_ENA_WIDTH 1 /* DAC1L_ENA */
-#define WM8996_DAC1R_ENA 0x0001 /* DAC1R_ENA */
-#define WM8996_DAC1R_ENA_MASK 0x0001 /* DAC1R_ENA */
-#define WM8996_DAC1R_ENA_SHIFT 0 /* DAC1R_ENA */
-#define WM8996_DAC1R_ENA_WIDTH 1 /* DAC1R_ENA */
-
-/*
- * R6 (0x06) - Power Management (6)
- */
-#define WM8996_AIF2TX_CHAN1_ENA 0x0200 /* AIF2TX_CHAN1_ENA */
-#define WM8996_AIF2TX_CHAN1_ENA_MASK 0x0200 /* AIF2TX_CHAN1_ENA */
-#define WM8996_AIF2TX_CHAN1_ENA_SHIFT 9 /* AIF2TX_CHAN1_ENA */
-#define WM8996_AIF2TX_CHAN1_ENA_WIDTH 1 /* AIF2TX_CHAN1_ENA */
-#define WM8996_AIF2TX_CHAN0_ENA 0x0100 /* AIF2TX_CHAN0_ENA */
-#define WM8996_AIF2TX_CHAN0_ENA_MASK 0x0100 /* AIF2TX_CHAN0_ENA */
-#define WM8996_AIF2TX_CHAN0_ENA_SHIFT 8 /* AIF2TX_CHAN0_ENA */
-#define WM8996_AIF2TX_CHAN0_ENA_WIDTH 1 /* AIF2TX_CHAN0_ENA */
-#define WM8996_AIF1TX_CHAN5_ENA 0x0020 /* AIF1TX_CHAN5_ENA */
-#define WM8996_AIF1TX_CHAN5_ENA_MASK 0x0020 /* AIF1TX_CHAN5_ENA */
-#define WM8996_AIF1TX_CHAN5_ENA_SHIFT 5 /* AIF1TX_CHAN5_ENA */
-#define WM8996_AIF1TX_CHAN5_ENA_WIDTH 1 /* AIF1TX_CHAN5_ENA */
-#define WM8996_AIF1TX_CHAN4_ENA 0x0010 /* AIF1TX_CHAN4_ENA */
-#define WM8996_AIF1TX_CHAN4_ENA_MASK 0x0010 /* AIF1TX_CHAN4_ENA */
-#define WM8996_AIF1TX_CHAN4_ENA_SHIFT 4 /* AIF1TX_CHAN4_ENA */
-#define WM8996_AIF1TX_CHAN4_ENA_WIDTH 1 /* AIF1TX_CHAN4_ENA */
-#define WM8996_AIF1TX_CHAN3_ENA 0x0008 /* AIF1TX_CHAN3_ENA */
-#define WM8996_AIF1TX_CHAN3_ENA_MASK 0x0008 /* AIF1TX_CHAN3_ENA */
-#define WM8996_AIF1TX_CHAN3_ENA_SHIFT 3 /* AIF1TX_CHAN3_ENA */
-#define WM8996_AIF1TX_CHAN3_ENA_WIDTH 1 /* AIF1TX_CHAN3_ENA */
-#define WM8996_AIF1TX_CHAN2_ENA 0x0004 /* AIF1TX_CHAN2_ENA */
-#define WM8996_AIF1TX_CHAN2_ENA_MASK 0x0004 /* AIF1TX_CHAN2_ENA */
-#define WM8996_AIF1TX_CHAN2_ENA_SHIFT 2 /* AIF1TX_CHAN2_ENA */
-#define WM8996_AIF1TX_CHAN2_ENA_WIDTH 1 /* AIF1TX_CHAN2_ENA */
-#define WM8996_AIF1TX_CHAN1_ENA 0x0002 /* AIF1TX_CHAN1_ENA */
-#define WM8996_AIF1TX_CHAN1_ENA_MASK 0x0002 /* AIF1TX_CHAN1_ENA */
-#define WM8996_AIF1TX_CHAN1_ENA_SHIFT 1 /* AIF1TX_CHAN1_ENA */
-#define WM8996_AIF1TX_CHAN1_ENA_WIDTH 1 /* AIF1TX_CHAN1_ENA */
-#define WM8996_AIF1TX_CHAN0_ENA 0x0001 /* AIF1TX_CHAN0_ENA */
-#define WM8996_AIF1TX_CHAN0_ENA_MASK 0x0001 /* AIF1TX_CHAN0_ENA */
-#define WM8996_AIF1TX_CHAN0_ENA_SHIFT 0 /* AIF1TX_CHAN0_ENA */
-#define WM8996_AIF1TX_CHAN0_ENA_WIDTH 1 /* AIF1TX_CHAN0_ENA */
-
-/*
- * R7 (0x07) - Power Management (7)
- */
-#define WM8996_DMIC2_FN 0x0200 /* DMIC2_FN */
-#define WM8996_DMIC2_FN_MASK 0x0200 /* DMIC2_FN */
-#define WM8996_DMIC2_FN_SHIFT 9 /* DMIC2_FN */
-#define WM8996_DMIC2_FN_WIDTH 1 /* DMIC2_FN */
-#define WM8996_DMIC1_FN 0x0100 /* DMIC1_FN */
-#define WM8996_DMIC1_FN_MASK 0x0100 /* DMIC1_FN */
-#define WM8996_DMIC1_FN_SHIFT 8 /* DMIC1_FN */
-#define WM8996_DMIC1_FN_WIDTH 1 /* DMIC1_FN */
-#define WM8996_ADC_DMIC_DSP2R_ENA 0x0080 /* ADC_DMIC_DSP2R_ENA */
-#define WM8996_ADC_DMIC_DSP2R_ENA_MASK 0x0080 /* ADC_DMIC_DSP2R_ENA */
-#define WM8996_ADC_DMIC_DSP2R_ENA_SHIFT 7 /* ADC_DMIC_DSP2R_ENA */
-#define WM8996_ADC_DMIC_DSP2R_ENA_WIDTH 1 /* ADC_DMIC_DSP2R_ENA */
-#define WM8996_ADC_DMIC_DSP2L_ENA 0x0040 /* ADC_DMIC_DSP2L_ENA */
-#define WM8996_ADC_DMIC_DSP2L_ENA_MASK 0x0040 /* ADC_DMIC_DSP2L_ENA */
-#define WM8996_ADC_DMIC_DSP2L_ENA_SHIFT 6 /* ADC_DMIC_DSP2L_ENA */
-#define WM8996_ADC_DMIC_DSP2L_ENA_WIDTH 1 /* ADC_DMIC_DSP2L_ENA */
-#define WM8996_ADC_DMIC_SRC2_MASK 0x0030 /* ADC_DMIC_SRC2 - [5:4] */
-#define WM8996_ADC_DMIC_SRC2_SHIFT 4 /* ADC_DMIC_SRC2 - [5:4] */
-#define WM8996_ADC_DMIC_SRC2_WIDTH 2 /* ADC_DMIC_SRC2 - [5:4] */
-#define WM8996_ADC_DMIC_DSP1R_ENA 0x0008 /* ADC_DMIC_DSP1R_ENA */
-#define WM8996_ADC_DMIC_DSP1R_ENA_MASK 0x0008 /* ADC_DMIC_DSP1R_ENA */
-#define WM8996_ADC_DMIC_DSP1R_ENA_SHIFT 3 /* ADC_DMIC_DSP1R_ENA */
-#define WM8996_ADC_DMIC_DSP1R_ENA_WIDTH 1 /* ADC_DMIC_DSP1R_ENA */
-#define WM8996_ADC_DMIC_DSP1L_ENA 0x0004 /* ADC_DMIC_DSP1L_ENA */
-#define WM8996_ADC_DMIC_DSP1L_ENA_MASK 0x0004 /* ADC_DMIC_DSP1L_ENA */
-#define WM8996_ADC_DMIC_DSP1L_ENA_SHIFT 2 /* ADC_DMIC_DSP1L_ENA */
-#define WM8996_ADC_DMIC_DSP1L_ENA_WIDTH 1 /* ADC_DMIC_DSP1L_ENA */
-#define WM8996_ADC_DMIC_SRC1_MASK 0x0003 /* ADC_DMIC_SRC1 - [1:0] */
-#define WM8996_ADC_DMIC_SRC1_SHIFT 0 /* ADC_DMIC_SRC1 - [1:0] */
-#define WM8996_ADC_DMIC_SRC1_WIDTH 2 /* ADC_DMIC_SRC1 - [1:0] */
-
-/*
- * R8 (0x08) - Power Management (8)
- */
-#define WM8996_AIF2TX_SRC_MASK 0x00C0 /* AIF2TX_SRC - [7:6] */
-#define WM8996_AIF2TX_SRC_SHIFT 6 /* AIF2TX_SRC - [7:6] */
-#define WM8996_AIF2TX_SRC_WIDTH 2 /* AIF2TX_SRC - [7:6] */
-#define WM8996_DSP2RX_SRC 0x0010 /* DSP2RX_SRC */
-#define WM8996_DSP2RX_SRC_MASK 0x0010 /* DSP2RX_SRC */
-#define WM8996_DSP2RX_SRC_SHIFT 4 /* DSP2RX_SRC */
-#define WM8996_DSP2RX_SRC_WIDTH 1 /* DSP2RX_SRC */
-#define WM8996_DSP1RX_SRC 0x0001 /* DSP1RX_SRC */
-#define WM8996_DSP1RX_SRC_MASK 0x0001 /* DSP1RX_SRC */
-#define WM8996_DSP1RX_SRC_SHIFT 0 /* DSP1RX_SRC */
-#define WM8996_DSP1RX_SRC_WIDTH 1 /* DSP1RX_SRC */
-
-/*
- * R16 (0x10) - Left Line Input Volume
- */
-#define WM8996_IN1_VU 0x0080 /* IN1_VU */
-#define WM8996_IN1_VU_MASK 0x0080 /* IN1_VU */
-#define WM8996_IN1_VU_SHIFT 7 /* IN1_VU */
-#define WM8996_IN1_VU_WIDTH 1 /* IN1_VU */
-#define WM8996_IN1L_ZC 0x0020 /* IN1L_ZC */
-#define WM8996_IN1L_ZC_MASK 0x0020 /* IN1L_ZC */
-#define WM8996_IN1L_ZC_SHIFT 5 /* IN1L_ZC */
-#define WM8996_IN1L_ZC_WIDTH 1 /* IN1L_ZC */
-#define WM8996_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */
-#define WM8996_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */
-#define WM8996_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */
-
-/*
- * R17 (0x11) - Right Line Input Volume
- */
-#define WM8996_IN1_VU 0x0080 /* IN1_VU */
-#define WM8996_IN1_VU_MASK 0x0080 /* IN1_VU */
-#define WM8996_IN1_VU_SHIFT 7 /* IN1_VU */
-#define WM8996_IN1_VU_WIDTH 1 /* IN1_VU */
-#define WM8996_IN1R_ZC 0x0020 /* IN1R_ZC */
-#define WM8996_IN1R_ZC_MASK 0x0020 /* IN1R_ZC */
-#define WM8996_IN1R_ZC_SHIFT 5 /* IN1R_ZC */
-#define WM8996_IN1R_ZC_WIDTH 1 /* IN1R_ZC */
-#define WM8996_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */
-#define WM8996_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */
-#define WM8996_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */
-
-/*
- * R18 (0x12) - Line Input Control
- */
-#define WM8996_INL_MODE_MASK 0x000C /* INL_MODE - [3:2] */
-#define WM8996_INL_MODE_SHIFT 2 /* INL_MODE - [3:2] */
-#define WM8996_INL_MODE_WIDTH 2 /* INL_MODE - [3:2] */
-#define WM8996_INR_MODE_MASK 0x0003 /* INR_MODE - [1:0] */
-#define WM8996_INR_MODE_SHIFT 0 /* INR_MODE - [1:0] */
-#define WM8996_INR_MODE_WIDTH 2 /* INR_MODE - [1:0] */
-
-/*
- * R21 (0x15) - DAC1 HPOUT1 Volume
- */
-#define WM8996_DAC1R_HPOUT1R_VOL_MASK 0x00F0 /* DAC1R_HPOUT1R_VOL - [7:4] */
-#define WM8996_DAC1R_HPOUT1R_VOL_SHIFT 4 /* DAC1R_HPOUT1R_VOL - [7:4] */
-#define WM8996_DAC1R_HPOUT1R_VOL_WIDTH 4 /* DAC1R_HPOUT1R_VOL - [7:4] */
-#define WM8996_DAC1L_HPOUT1L_VOL_MASK 0x000F /* DAC1L_HPOUT1L_VOL - [3:0] */
-#define WM8996_DAC1L_HPOUT1L_VOL_SHIFT 0 /* DAC1L_HPOUT1L_VOL - [3:0] */
-#define WM8996_DAC1L_HPOUT1L_VOL_WIDTH 4 /* DAC1L_HPOUT1L_VOL - [3:0] */
-
-/*
- * R22 (0x16) - DAC2 HPOUT2 Volume
- */
-#define WM8996_DAC2R_HPOUT2R_VOL_MASK 0x00F0 /* DAC2R_HPOUT2R_VOL - [7:4] */
-#define WM8996_DAC2R_HPOUT2R_VOL_SHIFT 4 /* DAC2R_HPOUT2R_VOL - [7:4] */
-#define WM8996_DAC2R_HPOUT2R_VOL_WIDTH 4 /* DAC2R_HPOUT2R_VOL - [7:4] */
-#define WM8996_DAC2L_HPOUT2L_VOL_MASK 0x000F /* DAC2L_HPOUT2L_VOL - [3:0] */
-#define WM8996_DAC2L_HPOUT2L_VOL_SHIFT 0 /* DAC2L_HPOUT2L_VOL - [3:0] */
-#define WM8996_DAC2L_HPOUT2L_VOL_WIDTH 4 /* DAC2L_HPOUT2L_VOL - [3:0] */
-
-/*
- * R24 (0x18) - DAC1 Left Volume
- */
-#define WM8996_DAC1L_MUTE 0x0200 /* DAC1L_MUTE */
-#define WM8996_DAC1L_MUTE_MASK 0x0200 /* DAC1L_MUTE */
-#define WM8996_DAC1L_MUTE_SHIFT 9 /* DAC1L_MUTE */
-#define WM8996_DAC1L_MUTE_WIDTH 1 /* DAC1L_MUTE */
-#define WM8996_DAC1_VU 0x0100 /* DAC1_VU */
-#define WM8996_DAC1_VU_MASK 0x0100 /* DAC1_VU */
-#define WM8996_DAC1_VU_SHIFT 8 /* DAC1_VU */
-#define WM8996_DAC1_VU_WIDTH 1 /* DAC1_VU */
-#define WM8996_DAC1L_VOL_MASK 0x00FF /* DAC1L_VOL - [7:0] */
-#define WM8996_DAC1L_VOL_SHIFT 0 /* DAC1L_VOL - [7:0] */
-#define WM8996_DAC1L_VOL_WIDTH 8 /* DAC1L_VOL - [7:0] */
-
-/*
- * R25 (0x19) - DAC1 Right Volume
- */
-#define WM8996_DAC1R_MUTE 0x0200 /* DAC1R_MUTE */
-#define WM8996_DAC1R_MUTE_MASK 0x0200 /* DAC1R_MUTE */
-#define WM8996_DAC1R_MUTE_SHIFT 9 /* DAC1R_MUTE */
-#define WM8996_DAC1R_MUTE_WIDTH 1 /* DAC1R_MUTE */
-#define WM8996_DAC1_VU 0x0100 /* DAC1_VU */
-#define WM8996_DAC1_VU_MASK 0x0100 /* DAC1_VU */
-#define WM8996_DAC1_VU_SHIFT 8 /* DAC1_VU */
-#define WM8996_DAC1_VU_WIDTH 1 /* DAC1_VU */
-#define WM8996_DAC1R_VOL_MASK 0x00FF /* DAC1R_VOL - [7:0] */
-#define WM8996_DAC1R_VOL_SHIFT 0 /* DAC1R_VOL - [7:0] */
-#define WM8996_DAC1R_VOL_WIDTH 8 /* DAC1R_VOL - [7:0] */
-
-/*
- * R26 (0x1A) - DAC2 Left Volume
- */
-#define WM8996_DAC2L_MUTE 0x0200 /* DAC2L_MUTE */
-#define WM8996_DAC2L_MUTE_MASK 0x0200 /* DAC2L_MUTE */
-#define WM8996_DAC2L_MUTE_SHIFT 9 /* DAC2L_MUTE */
-#define WM8996_DAC2L_MUTE_WIDTH 1 /* DAC2L_MUTE */
-#define WM8996_DAC2_VU 0x0100 /* DAC2_VU */
-#define WM8996_DAC2_VU_MASK 0x0100 /* DAC2_VU */
-#define WM8996_DAC2_VU_SHIFT 8 /* DAC2_VU */
-#define WM8996_DAC2_VU_WIDTH 1 /* DAC2_VU */
-#define WM8996_DAC2L_VOL_MASK 0x00FF /* DAC2L_VOL - [7:0] */
-#define WM8996_DAC2L_VOL_SHIFT 0 /* DAC2L_VOL - [7:0] */
-#define WM8996_DAC2L_VOL_WIDTH 8 /* DAC2L_VOL - [7:0] */
-
-/*
- * R27 (0x1B) - DAC2 Right Volume
- */
-#define WM8996_DAC2R_MUTE 0x0200 /* DAC2R_MUTE */
-#define WM8996_DAC2R_MUTE_MASK 0x0200 /* DAC2R_MUTE */
-#define WM8996_DAC2R_MUTE_SHIFT 9 /* DAC2R_MUTE */
-#define WM8996_DAC2R_MUTE_WIDTH 1 /* DAC2R_MUTE */
-#define WM8996_DAC2_VU 0x0100 /* DAC2_VU */
-#define WM8996_DAC2_VU_MASK 0x0100 /* DAC2_VU */
-#define WM8996_DAC2_VU_SHIFT 8 /* DAC2_VU */
-#define WM8996_DAC2_VU_WIDTH 1 /* DAC2_VU */
-#define WM8996_DAC2R_VOL_MASK 0x00FF /* DAC2R_VOL - [7:0] */
-#define WM8996_DAC2R_VOL_SHIFT 0 /* DAC2R_VOL - [7:0] */
-#define WM8996_DAC2R_VOL_WIDTH 8 /* DAC2R_VOL - [7:0] */
-
-/*
- * R28 (0x1C) - Output1 Left Volume
- */
-#define WM8996_DAC1_VU 0x0100 /* DAC1_VU */
-#define WM8996_DAC1_VU_MASK 0x0100 /* DAC1_VU */
-#define WM8996_DAC1_VU_SHIFT 8 /* DAC1_VU */
-#define WM8996_DAC1_VU_WIDTH 1 /* DAC1_VU */
-#define WM8996_HPOUT1L_ZC 0x0080 /* HPOUT1L_ZC */
-#define WM8996_HPOUT1L_ZC_MASK 0x0080 /* HPOUT1L_ZC */
-#define WM8996_HPOUT1L_ZC_SHIFT 7 /* HPOUT1L_ZC */
-#define WM8996_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */
-#define WM8996_HPOUT1L_VOL_MASK 0x000F /* HPOUT1L_VOL - [3:0] */
-#define WM8996_HPOUT1L_VOL_SHIFT 0 /* HPOUT1L_VOL - [3:0] */
-#define WM8996_HPOUT1L_VOL_WIDTH 4 /* HPOUT1L_VOL - [3:0] */
-
-/*
- * R29 (0x1D) - Output1 Right Volume
- */
-#define WM8996_DAC1_VU 0x0100 /* DAC1_VU */
-#define WM8996_DAC1_VU_MASK 0x0100 /* DAC1_VU */
-#define WM8996_DAC1_VU_SHIFT 8 /* DAC1_VU */
-#define WM8996_DAC1_VU_WIDTH 1 /* DAC1_VU */
-#define WM8996_HPOUT1R_ZC 0x0080 /* HPOUT1R_ZC */
-#define WM8996_HPOUT1R_ZC_MASK 0x0080 /* HPOUT1R_ZC */
-#define WM8996_HPOUT1R_ZC_SHIFT 7 /* HPOUT1R_ZC */
-#define WM8996_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */
-#define WM8996_HPOUT1R_VOL_MASK 0x000F /* HPOUT1R_VOL - [3:0] */
-#define WM8996_HPOUT1R_VOL_SHIFT 0 /* HPOUT1R_VOL - [3:0] */
-#define WM8996_HPOUT1R_VOL_WIDTH 4 /* HPOUT1R_VOL - [3:0] */
-
-/*
- * R30 (0x1E) - Output2 Left Volume
- */
-#define WM8996_DAC2_VU 0x0100 /* DAC2_VU */
-#define WM8996_DAC2_VU_MASK 0x0100 /* DAC2_VU */
-#define WM8996_DAC2_VU_SHIFT 8 /* DAC2_VU */
-#define WM8996_DAC2_VU_WIDTH 1 /* DAC2_VU */
-#define WM8996_HPOUT2L_ZC 0x0080 /* HPOUT2L_ZC */
-#define WM8996_HPOUT2L_ZC_MASK 0x0080 /* HPOUT2L_ZC */
-#define WM8996_HPOUT2L_ZC_SHIFT 7 /* HPOUT2L_ZC */
-#define WM8996_HPOUT2L_ZC_WIDTH 1 /* HPOUT2L_ZC */
-#define WM8996_HPOUT2L_VOL_MASK 0x000F /* HPOUT2L_VOL - [3:0] */
-#define WM8996_HPOUT2L_VOL_SHIFT 0 /* HPOUT2L_VOL - [3:0] */
-#define WM8996_HPOUT2L_VOL_WIDTH 4 /* HPOUT2L_VOL - [3:0] */
-
-/*
- * R31 (0x1F) - Output2 Right Volume
- */
-#define WM8996_DAC2_VU 0x0100 /* DAC2_VU */
-#define WM8996_DAC2_VU_MASK 0x0100 /* DAC2_VU */
-#define WM8996_DAC2_VU_SHIFT 8 /* DAC2_VU */
-#define WM8996_DAC2_VU_WIDTH 1 /* DAC2_VU */
-#define WM8996_HPOUT2R_ZC 0x0080 /* HPOUT2R_ZC */
-#define WM8996_HPOUT2R_ZC_MASK 0x0080 /* HPOUT2R_ZC */
-#define WM8996_HPOUT2R_ZC_SHIFT 7 /* HPOUT2R_ZC */
-#define WM8996_HPOUT2R_ZC_WIDTH 1 /* HPOUT2R_ZC */
-#define WM8996_HPOUT2R_VOL_MASK 0x000F /* HPOUT2R_VOL - [3:0] */
-#define WM8996_HPOUT2R_VOL_SHIFT 0 /* HPOUT2R_VOL - [3:0] */
-#define WM8996_HPOUT2R_VOL_WIDTH 4 /* HPOUT2R_VOL - [3:0] */
-
-/*
- * R32 (0x20) - MICBIAS (1)
- */
-#define WM8996_MICB1_RATE 0x0020 /* MICB1_RATE */
-#define WM8996_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */
-#define WM8996_MICB1_RATE_SHIFT 5 /* MICB1_RATE */
-#define WM8996_MICB1_RATE_WIDTH 1 /* MICB1_RATE */
-#define WM8996_MICB1_MODE 0x0010 /* MICB1_MODE */
-#define WM8996_MICB1_MODE_MASK 0x0010 /* MICB1_MODE */
-#define WM8996_MICB1_MODE_SHIFT 4 /* MICB1_MODE */
-#define WM8996_MICB1_MODE_WIDTH 1 /* MICB1_MODE */
-#define WM8996_MICB1_LVL_MASK 0x000E /* MICB1_LVL - [3:1] */
-#define WM8996_MICB1_LVL_SHIFT 1 /* MICB1_LVL - [3:1] */
-#define WM8996_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [3:1] */
-#define WM8996_MICB1_DISCH 0x0001 /* MICB1_DISCH */
-#define WM8996_MICB1_DISCH_MASK 0x0001 /* MICB1_DISCH */
-#define WM8996_MICB1_DISCH_SHIFT 0 /* MICB1_DISCH */
-#define WM8996_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
-
-/*
- * R33 (0x21) - MICBIAS (2)
- */
-#define WM8996_MICB2_RATE 0x0020 /* MICB2_RATE */
-#define WM8996_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */
-#define WM8996_MICB2_RATE_SHIFT 5 /* MICB2_RATE */
-#define WM8996_MICB2_RATE_WIDTH 1 /* MICB2_RATE */
-#define WM8996_MICB2_MODE 0x0010 /* MICB2_MODE */
-#define WM8996_MICB2_MODE_MASK 0x0010 /* MICB2_MODE */
-#define WM8996_MICB2_MODE_SHIFT 4 /* MICB2_MODE */
-#define WM8996_MICB2_MODE_WIDTH 1 /* MICB2_MODE */
-#define WM8996_MICB2_LVL_MASK 0x000E /* MICB2_LVL - [3:1] */
-#define WM8996_MICB2_LVL_SHIFT 1 /* MICB2_LVL - [3:1] */
-#define WM8996_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [3:1] */
-#define WM8996_MICB2_DISCH 0x0001 /* MICB2_DISCH */
-#define WM8996_MICB2_DISCH_MASK 0x0001 /* MICB2_DISCH */
-#define WM8996_MICB2_DISCH_SHIFT 0 /* MICB2_DISCH */
-#define WM8996_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
-
-/*
- * R40 (0x28) - LDO 1
- */
-#define WM8996_LDO1_MODE 0x0020 /* LDO1_MODE */
-#define WM8996_LDO1_MODE_MASK 0x0020 /* LDO1_MODE */
-#define WM8996_LDO1_MODE_SHIFT 5 /* LDO1_MODE */
-#define WM8996_LDO1_MODE_WIDTH 1 /* LDO1_MODE */
-#define WM8996_LDO1_VSEL_MASK 0x0006 /* LDO1_VSEL - [2:1] */
-#define WM8996_LDO1_VSEL_SHIFT 1 /* LDO1_VSEL - [2:1] */
-#define WM8996_LDO1_VSEL_WIDTH 2 /* LDO1_VSEL - [2:1] */
-#define WM8996_LDO1_DISCH 0x0001 /* LDO1_DISCH */
-#define WM8996_LDO1_DISCH_MASK 0x0001 /* LDO1_DISCH */
-#define WM8996_LDO1_DISCH_SHIFT 0 /* LDO1_DISCH */
-#define WM8996_LDO1_DISCH_WIDTH 1 /* LDO1_DISCH */
-
-/*
- * R41 (0x29) - LDO 2
- */
-#define WM8996_LDO2_MODE 0x0020 /* LDO2_MODE */
-#define WM8996_LDO2_MODE_MASK 0x0020 /* LDO2_MODE */
-#define WM8996_LDO2_MODE_SHIFT 5 /* LDO2_MODE */
-#define WM8996_LDO2_MODE_WIDTH 1 /* LDO2_MODE */
-#define WM8996_LDO2_VSEL_MASK 0x001E /* LDO2_VSEL - [4:1] */
-#define WM8996_LDO2_VSEL_SHIFT 1 /* LDO2_VSEL - [4:1] */
-#define WM8996_LDO2_VSEL_WIDTH 4 /* LDO2_VSEL - [4:1] */
-#define WM8996_LDO2_DISCH 0x0001 /* LDO2_DISCH */
-#define WM8996_LDO2_DISCH_MASK 0x0001 /* LDO2_DISCH */
-#define WM8996_LDO2_DISCH_SHIFT 0 /* LDO2_DISCH */
-#define WM8996_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */
-
-/*
- * R48 (0x30) - Accessory Detect Mode 1
- */
-#define WM8996_JD_MODE_MASK 0x0003 /* JD_MODE - [1:0] */
-#define WM8996_JD_MODE_SHIFT 0 /* JD_MODE - [1:0] */
-#define WM8996_JD_MODE_WIDTH 2 /* JD_MODE - [1:0] */
-
-/*
- * R49 (0x31) - Accessory Detect Mode 2
- */
-#define WM8996_HPOUT1FB_SRC 0x0004 /* HPOUT1FB_SRC */
-#define WM8996_HPOUT1FB_SRC_MASK 0x0004 /* HPOUT1FB_SRC */
-#define WM8996_HPOUT1FB_SRC_SHIFT 2 /* HPOUT1FB_SRC */
-#define WM8996_HPOUT1FB_SRC_WIDTH 1 /* HPOUT1FB_SRC */
-#define WM8996_MICD_SRC 0x0002 /* MICD_SRC */
-#define WM8996_MICD_SRC_MASK 0x0002 /* MICD_SRC */
-#define WM8996_MICD_SRC_SHIFT 1 /* MICD_SRC */
-#define WM8996_MICD_SRC_WIDTH 1 /* MICD_SRC */
-#define WM8996_MICD_BIAS_SRC 0x0001 /* MICD_BIAS_SRC */
-#define WM8996_MICD_BIAS_SRC_MASK 0x0001 /* MICD_BIAS_SRC */
-#define WM8996_MICD_BIAS_SRC_SHIFT 0 /* MICD_BIAS_SRC */
-#define WM8996_MICD_BIAS_SRC_WIDTH 1 /* MICD_BIAS_SRC */
-
-/*
- * R52 (0x34) - Headphone Detect 1
- */
-#define WM8996_HP_HOLDTIME_MASK 0x00E0 /* HP_HOLDTIME - [7:5] */
-#define WM8996_HP_HOLDTIME_SHIFT 5 /* HP_HOLDTIME - [7:5] */
-#define WM8996_HP_HOLDTIME_WIDTH 3 /* HP_HOLDTIME - [7:5] */
-#define WM8996_HP_CLK_DIV_MASK 0x0018 /* HP_CLK_DIV - [4:3] */
-#define WM8996_HP_CLK_DIV_SHIFT 3 /* HP_CLK_DIV - [4:3] */
-#define WM8996_HP_CLK_DIV_WIDTH 2 /* HP_CLK_DIV - [4:3] */
-#define WM8996_HP_STEP_SIZE 0x0002 /* HP_STEP_SIZE */
-#define WM8996_HP_STEP_SIZE_MASK 0x0002 /* HP_STEP_SIZE */
-#define WM8996_HP_STEP_SIZE_SHIFT 1 /* HP_STEP_SIZE */
-#define WM8996_HP_STEP_SIZE_WIDTH 1 /* HP_STEP_SIZE */
-#define WM8996_HP_POLL 0x0001 /* HP_POLL */
-#define WM8996_HP_POLL_MASK 0x0001 /* HP_POLL */
-#define WM8996_HP_POLL_SHIFT 0 /* HP_POLL */
-#define WM8996_HP_POLL_WIDTH 1 /* HP_POLL */
-
-/*
- * R53 (0x35) - Headphone Detect 2
- */
-#define WM8996_HP_DONE 0x0080 /* HP_DONE */
-#define WM8996_HP_DONE_MASK 0x0080 /* HP_DONE */
-#define WM8996_HP_DONE_SHIFT 7 /* HP_DONE */
-#define WM8996_HP_DONE_WIDTH 1 /* HP_DONE */
-#define WM8996_HP_LVL_MASK 0x007F /* HP_LVL - [6:0] */
-#define WM8996_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */
-#define WM8996_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */
-
-/*
- * R56 (0x38) - Mic Detect 1
- */
-#define WM8996_MICD_BIAS_STARTTIME_MASK 0xF000 /* MICD_BIAS_STARTTIME - [15:12] */
-#define WM8996_MICD_BIAS_STARTTIME_SHIFT 12 /* MICD_BIAS_STARTTIME - [15:12] */
-#define WM8996_MICD_BIAS_STARTTIME_WIDTH 4 /* MICD_BIAS_STARTTIME - [15:12] */
-#define WM8996_MICD_RATE_MASK 0x0F00 /* MICD_RATE - [11:8] */
-#define WM8996_MICD_RATE_SHIFT 8 /* MICD_RATE - [11:8] */
-#define WM8996_MICD_RATE_WIDTH 4 /* MICD_RATE - [11:8] */
-#define WM8996_MICD_DBTIME 0x0002 /* MICD_DBTIME */
-#define WM8996_MICD_DBTIME_MASK 0x0002 /* MICD_DBTIME */
-#define WM8996_MICD_DBTIME_SHIFT 1 /* MICD_DBTIME */
-#define WM8996_MICD_DBTIME_WIDTH 1 /* MICD_DBTIME */
-#define WM8996_MICD_ENA 0x0001 /* MICD_ENA */
-#define WM8996_MICD_ENA_MASK 0x0001 /* MICD_ENA */
-#define WM8996_MICD_ENA_SHIFT 0 /* MICD_ENA */
-#define WM8996_MICD_ENA_WIDTH 1 /* MICD_ENA */
-
-/*
- * R57 (0x39) - Mic Detect 2
- */
-#define WM8996_MICD_LVL_SEL_MASK 0x00FF /* MICD_LVL_SEL - [7:0] */
-#define WM8996_MICD_LVL_SEL_SHIFT 0 /* MICD_LVL_SEL - [7:0] */
-#define WM8996_MICD_LVL_SEL_WIDTH 8 /* MICD_LVL_SEL - [7:0] */
-
-/*
- * R58 (0x3A) - Mic Detect 3
- */
-#define WM8996_MICD_LVL_MASK 0x07FC /* MICD_LVL - [10:2] */
-#define WM8996_MICD_LVL_SHIFT 2 /* MICD_LVL - [10:2] */
-#define WM8996_MICD_LVL_WIDTH 9 /* MICD_LVL - [10:2] */
-#define WM8996_MICD_VALID 0x0002 /* MICD_VALID */
-#define WM8996_MICD_VALID_MASK 0x0002 /* MICD_VALID */
-#define WM8996_MICD_VALID_SHIFT 1 /* MICD_VALID */
-#define WM8996_MICD_VALID_WIDTH 1 /* MICD_VALID */
-#define WM8996_MICD_STS 0x0001 /* MICD_STS */
-#define WM8996_MICD_STS_MASK 0x0001 /* MICD_STS */
-#define WM8996_MICD_STS_SHIFT 0 /* MICD_STS */
-#define WM8996_MICD_STS_WIDTH 1 /* MICD_STS */
-
-/*
- * R64 (0x40) - Charge Pump (1)
- */
-#define WM8996_CP_ENA 0x8000 /* CP_ENA */
-#define WM8996_CP_ENA_MASK 0x8000 /* CP_ENA */
-#define WM8996_CP_ENA_SHIFT 15 /* CP_ENA */
-#define WM8996_CP_ENA_WIDTH 1 /* CP_ENA */
-
-/*
- * R65 (0x41) - Charge Pump (2)
- */
-#define WM8996_CP_DISCH 0x8000 /* CP_DISCH */
-#define WM8996_CP_DISCH_MASK 0x8000 /* CP_DISCH */
-#define WM8996_CP_DISCH_SHIFT 15 /* CP_DISCH */
-#define WM8996_CP_DISCH_WIDTH 1 /* CP_DISCH */
-
-/*
- * R80 (0x50) - DC Servo (1)
- */
-#define WM8996_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */
-#define WM8996_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */
-#define WM8996_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */
-#define WM8996_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */
-#define WM8996_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */
-#define WM8996_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */
-#define WM8996_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */
-#define WM8996_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */
-#define WM8996_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
-#define WM8996_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
-#define WM8996_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
-#define WM8996_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
-#define WM8996_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
-#define WM8996_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
-#define WM8996_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
-#define WM8996_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
-
-/*
- * R81 (0x51) - DC Servo (2)
- */
-#define WM8996_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */
-#define WM8996_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */
-#define WM8996_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */
-#define WM8996_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */
-#define WM8996_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */
-#define WM8996_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */
-#define WM8996_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */
-#define WM8996_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */
-#define WM8996_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
-#define WM8996_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
-#define WM8996_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
-#define WM8996_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
-#define WM8996_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
-#define WM8996_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
-#define WM8996_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
-#define WM8996_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
-#define WM8996_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */
-#define WM8996_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */
-#define WM8996_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */
-#define WM8996_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */
-#define WM8996_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */
-#define WM8996_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */
-#define WM8996_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */
-#define WM8996_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */
-#define WM8996_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
-#define WM8996_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
-#define WM8996_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
-#define WM8996_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
-#define WM8996_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
-#define WM8996_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
-#define WM8996_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
-#define WM8996_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
-#define WM8996_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */
-#define WM8996_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */
-#define WM8996_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */
-#define WM8996_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */
-#define WM8996_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */
-#define WM8996_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */
-#define WM8996_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */
-#define WM8996_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */
-#define WM8996_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
-#define WM8996_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
-#define WM8996_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
-#define WM8996_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
-#define WM8996_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
-#define WM8996_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
-#define WM8996_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
-#define WM8996_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
-#define WM8996_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */
-#define WM8996_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */
-#define WM8996_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */
-#define WM8996_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */
-#define WM8996_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */
-#define WM8996_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */
-#define WM8996_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */
-#define WM8996_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */
-#define WM8996_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */
-#define WM8996_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */
-#define WM8996_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */
-#define WM8996_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
-#define WM8996_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */
-#define WM8996_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */
-#define WM8996_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */
-#define WM8996_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
-
-/*
- * R82 (0x52) - DC Servo (3)
- */
-#define WM8996_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */
-#define WM8996_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */
-#define WM8996_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */
-#define WM8996_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
-#define WM8996_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
-#define WM8996_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
-
-/*
- * R84 (0x54) - DC Servo (5)
- */
-#define WM8996_DCS_SERIES_NO_23_MASK 0x7F00 /* DCS_SERIES_NO_23 - [14:8] */
-#define WM8996_DCS_SERIES_NO_23_SHIFT 8 /* DCS_SERIES_NO_23 - [14:8] */
-#define WM8996_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [14:8] */
-#define WM8996_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */
-#define WM8996_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */
-#define WM8996_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */
-
-/*
- * R85 (0x55) - DC Servo (6)
- */
-#define WM8996_DCS_DAC_WR_VAL_3_MASK 0xFF00 /* DCS_DAC_WR_VAL_3 - [15:8] */
-#define WM8996_DCS_DAC_WR_VAL_3_SHIFT 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
-#define WM8996_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
-#define WM8996_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */
-#define WM8996_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */
-#define WM8996_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */
-
-/*
- * R86 (0x56) - DC Servo (7)
- */
-#define WM8996_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */
-#define WM8996_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
-#define WM8996_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
-#define WM8996_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
-#define WM8996_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
-#define WM8996_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
-
-/*
- * R87 (0x57) - DC Servo Readback 0
- */
-#define WM8996_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */
-#define WM8996_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */
-#define WM8996_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */
-#define WM8996_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */
-#define WM8996_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
-#define WM8996_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
-#define WM8996_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */
-#define WM8996_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */
-#define WM8996_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */
-
-/*
- * R96 (0x60) - Analogue HP (1)
- */
-#define WM8996_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
-#define WM8996_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
-#define WM8996_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
-#define WM8996_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */
-#define WM8996_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */
-#define WM8996_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */
-#define WM8996_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */
-#define WM8996_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */
-#define WM8996_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */
-#define WM8996_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */
-#define WM8996_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */
-#define WM8996_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */
-#define WM8996_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */
-#define WM8996_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */
-#define WM8996_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */
-#define WM8996_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */
-#define WM8996_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */
-#define WM8996_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */
-#define WM8996_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */
-#define WM8996_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */
-#define WM8996_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */
-#define WM8996_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */
-#define WM8996_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */
-#define WM8996_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
-
-/*
- * R97 (0x61) - Analogue HP (2)
- */
-#define WM8996_HPOUT2L_RMV_SHORT 0x0080 /* HPOUT2L_RMV_SHORT */
-#define WM8996_HPOUT2L_RMV_SHORT_MASK 0x0080 /* HPOUT2L_RMV_SHORT */
-#define WM8996_HPOUT2L_RMV_SHORT_SHIFT 7 /* HPOUT2L_RMV_SHORT */
-#define WM8996_HPOUT2L_RMV_SHORT_WIDTH 1 /* HPOUT2L_RMV_SHORT */
-#define WM8996_HPOUT2L_OUTP 0x0040 /* HPOUT2L_OUTP */
-#define WM8996_HPOUT2L_OUTP_MASK 0x0040 /* HPOUT2L_OUTP */
-#define WM8996_HPOUT2L_OUTP_SHIFT 6 /* HPOUT2L_OUTP */
-#define WM8996_HPOUT2L_OUTP_WIDTH 1 /* HPOUT2L_OUTP */
-#define WM8996_HPOUT2L_DLY 0x0020 /* HPOUT2L_DLY */
-#define WM8996_HPOUT2L_DLY_MASK 0x0020 /* HPOUT2L_DLY */
-#define WM8996_HPOUT2L_DLY_SHIFT 5 /* HPOUT2L_DLY */
-#define WM8996_HPOUT2L_DLY_WIDTH 1 /* HPOUT2L_DLY */
-#define WM8996_HPOUT2R_RMV_SHORT 0x0008 /* HPOUT2R_RMV_SHORT */
-#define WM8996_HPOUT2R_RMV_SHORT_MASK 0x0008 /* HPOUT2R_RMV_SHORT */
-#define WM8996_HPOUT2R_RMV_SHORT_SHIFT 3 /* HPOUT2R_RMV_SHORT */
-#define WM8996_HPOUT2R_RMV_SHORT_WIDTH 1 /* HPOUT2R_RMV_SHORT */
-#define WM8996_HPOUT2R_OUTP 0x0004 /* HPOUT2R_OUTP */
-#define WM8996_HPOUT2R_OUTP_MASK 0x0004 /* HPOUT2R_OUTP */
-#define WM8996_HPOUT2R_OUTP_SHIFT 2 /* HPOUT2R_OUTP */
-#define WM8996_HPOUT2R_OUTP_WIDTH 1 /* HPOUT2R_OUTP */
-#define WM8996_HPOUT2R_DLY 0x0002 /* HPOUT2R_DLY */
-#define WM8996_HPOUT2R_DLY_MASK 0x0002 /* HPOUT2R_DLY */
-#define WM8996_HPOUT2R_DLY_SHIFT 1 /* HPOUT2R_DLY */
-#define WM8996_HPOUT2R_DLY_WIDTH 1 /* HPOUT2R_DLY */
-
-/*
- * R256 (0x100) - Chip Revision
- */
-#define WM8996_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */
-#define WM8996_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */
-#define WM8996_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */
-
-/*
- * R257 (0x101) - Control Interface (1)
- */
-#define WM8996_REG_SYNC 0x8000 /* REG_SYNC */
-#define WM8996_REG_SYNC_MASK 0x8000 /* REG_SYNC */
-#define WM8996_REG_SYNC_SHIFT 15 /* REG_SYNC */
-#define WM8996_REG_SYNC_WIDTH 1 /* REG_SYNC */
-#define WM8996_AUTO_INC 0x0004 /* AUTO_INC */
-#define WM8996_AUTO_INC_MASK 0x0004 /* AUTO_INC */
-#define WM8996_AUTO_INC_SHIFT 2 /* AUTO_INC */
-#define WM8996_AUTO_INC_WIDTH 1 /* AUTO_INC */
-
-/*
- * R272 (0x110) - Write Sequencer Ctrl (1)
- */
-#define WM8996_WSEQ_ENA 0x8000 /* WSEQ_ENA */
-#define WM8996_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */
-#define WM8996_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */
-#define WM8996_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
-#define WM8996_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
-#define WM8996_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
-#define WM8996_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
-#define WM8996_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
-#define WM8996_WSEQ_START 0x0100 /* WSEQ_START */
-#define WM8996_WSEQ_START_MASK 0x0100 /* WSEQ_START */
-#define WM8996_WSEQ_START_SHIFT 8 /* WSEQ_START */
-#define WM8996_WSEQ_START_WIDTH 1 /* WSEQ_START */
-#define WM8996_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */
-#define WM8996_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */
-#define WM8996_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */
-
-/*
- * R273 (0x111) - Write Sequencer Ctrl (2)
- */
-#define WM8996_WSEQ_BUSY 0x0100 /* WSEQ_BUSY */
-#define WM8996_WSEQ_BUSY_MASK 0x0100 /* WSEQ_BUSY */
-#define WM8996_WSEQ_BUSY_SHIFT 8 /* WSEQ_BUSY */
-#define WM8996_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
-#define WM8996_WSEQ_CURRENT_INDEX_MASK 0x007F /* WSEQ_CURRENT_INDEX - [6:0] */
-#define WM8996_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [6:0] */
-#define WM8996_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [6:0] */
-
-/*
- * R512 (0x200) - AIF Clocking (1)
- */
-#define WM8996_SYSCLK_SRC_MASK 0x0018 /* SYSCLK_SRC - [4:3] */
-#define WM8996_SYSCLK_SRC_SHIFT 3 /* SYSCLK_SRC - [4:3] */
-#define WM8996_SYSCLK_SRC_WIDTH 2 /* SYSCLK_SRC - [4:3] */
-#define WM8996_SYSCLK_INV 0x0004 /* SYSCLK_INV */
-#define WM8996_SYSCLK_INV_MASK 0x0004 /* SYSCLK_INV */
-#define WM8996_SYSCLK_INV_SHIFT 2 /* SYSCLK_INV */
-#define WM8996_SYSCLK_INV_WIDTH 1 /* SYSCLK_INV */
-#define WM8996_SYSCLK_DIV 0x0002 /* SYSCLK_DIV */
-#define WM8996_SYSCLK_DIV_MASK 0x0002 /* SYSCLK_DIV */
-#define WM8996_SYSCLK_DIV_SHIFT 1 /* SYSCLK_DIV */
-#define WM8996_SYSCLK_DIV_WIDTH 1 /* SYSCLK_DIV */
-#define WM8996_SYSCLK_ENA 0x0001 /* SYSCLK_ENA */
-#define WM8996_SYSCLK_ENA_MASK 0x0001 /* SYSCLK_ENA */
-#define WM8996_SYSCLK_ENA_SHIFT 0 /* SYSCLK_ENA */
-#define WM8996_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */
-
-/*
- * R513 (0x201) - AIF Clocking (2)
- */
-#define WM8996_DSP2_DIV_MASK 0x0018 /* DSP2_DIV - [4:3] */
-#define WM8996_DSP2_DIV_SHIFT 3 /* DSP2_DIV - [4:3] */
-#define WM8996_DSP2_DIV_WIDTH 2 /* DSP2_DIV - [4:3] */
-#define WM8996_DSP1_DIV_MASK 0x0003 /* DSP1_DIV - [1:0] */
-#define WM8996_DSP1_DIV_SHIFT 0 /* DSP1_DIV - [1:0] */
-#define WM8996_DSP1_DIV_WIDTH 2 /* DSP1_DIV - [1:0] */
-
-/*
- * R520 (0x208) - Clocking (1)
- */
-#define WM8996_LFCLK_ENA 0x0020 /* LFCLK_ENA */
-#define WM8996_LFCLK_ENA_MASK 0x0020 /* LFCLK_ENA */
-#define WM8996_LFCLK_ENA_SHIFT 5 /* LFCLK_ENA */
-#define WM8996_LFCLK_ENA_WIDTH 1 /* LFCLK_ENA */
-#define WM8996_TOCLK_ENA 0x0010 /* TOCLK_ENA */
-#define WM8996_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */
-#define WM8996_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */
-#define WM8996_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
-#define WM8996_AIFCLK_ENA 0x0004 /* AIFCLK_ENA */
-#define WM8996_AIFCLK_ENA_MASK 0x0004 /* AIFCLK_ENA */
-#define WM8996_AIFCLK_ENA_SHIFT 2 /* AIFCLK_ENA */
-#define WM8996_AIFCLK_ENA_WIDTH 1 /* AIFCLK_ENA */
-#define WM8996_SYSDSPCLK_ENA 0x0002 /* SYSDSPCLK_ENA */
-#define WM8996_SYSDSPCLK_ENA_MASK 0x0002 /* SYSDSPCLK_ENA */
-#define WM8996_SYSDSPCLK_ENA_SHIFT 1 /* SYSDSPCLK_ENA */
-#define WM8996_SYSDSPCLK_ENA_WIDTH 1 /* SYSDSPCLK_ENA */
-
-/*
- * R521 (0x209) - Clocking (2)
- */
-#define WM8996_TOCLK_DIV_MASK 0x0700 /* TOCLK_DIV - [10:8] */
-#define WM8996_TOCLK_DIV_SHIFT 8 /* TOCLK_DIV - [10:8] */
-#define WM8996_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [10:8] */
-#define WM8996_DBCLK_DIV_MASK 0x00F0 /* DBCLK_DIV - [7:4] */
-#define WM8996_DBCLK_DIV_SHIFT 4 /* DBCLK_DIV - [7:4] */
-#define WM8996_DBCLK_DIV_WIDTH 4 /* DBCLK_DIV - [7:4] */
-#define WM8996_OPCLK_DIV_MASK 0x0007 /* OPCLK_DIV - [2:0] */
-#define WM8996_OPCLK_DIV_SHIFT 0 /* OPCLK_DIV - [2:0] */
-#define WM8996_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [2:0] */
-
-/*
- * R528 (0x210) - AIF Rate
- */
-#define WM8996_SYSCLK_RATE 0x0001 /* SYSCLK_RATE */
-#define WM8996_SYSCLK_RATE_MASK 0x0001 /* SYSCLK_RATE */
-#define WM8996_SYSCLK_RATE_SHIFT 0 /* SYSCLK_RATE */
-#define WM8996_SYSCLK_RATE_WIDTH 1 /* SYSCLK_RATE */
-
-/*
- * R544 (0x220) - FLL Control (1)
- */
-#define WM8996_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */
-#define WM8996_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */
-#define WM8996_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */
-#define WM8996_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */
-#define WM8996_FLL_ENA 0x0001 /* FLL_ENA */
-#define WM8996_FLL_ENA_MASK 0x0001 /* FLL_ENA */
-#define WM8996_FLL_ENA_SHIFT 0 /* FLL_ENA */
-#define WM8996_FLL_ENA_WIDTH 1 /* FLL_ENA */
-
-/*
- * R545 (0x221) - FLL Control (2)
- */
-#define WM8996_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */
-#define WM8996_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */
-#define WM8996_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */
-#define WM8996_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
-#define WM8996_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
-#define WM8996_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
-
-/*
- * R546 (0x222) - FLL Control (3)
- */
-#define WM8996_FLL_THETA_MASK 0xFFFF /* FLL_THETA - [15:0] */
-#define WM8996_FLL_THETA_SHIFT 0 /* FLL_THETA - [15:0] */
-#define WM8996_FLL_THETA_WIDTH 16 /* FLL_THETA - [15:0] */
-
-/*
- * R547 (0x223) - FLL Control (4)
- */
-#define WM8996_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */
-#define WM8996_FLL_N_SHIFT 5 /* FLL_N - [14:5] */
-#define WM8996_FLL_N_WIDTH 10 /* FLL_N - [14:5] */
-#define WM8996_FLL_LOOP_GAIN_MASK 0x000F /* FLL_LOOP_GAIN - [3:0] */
-#define WM8996_FLL_LOOP_GAIN_SHIFT 0 /* FLL_LOOP_GAIN - [3:0] */
-#define WM8996_FLL_LOOP_GAIN_WIDTH 4 /* FLL_LOOP_GAIN - [3:0] */
-
-/*
- * R548 (0x224) - FLL Control (5)
- */
-#define WM8996_FLL_FRC_NCO_VAL_MASK 0x1F80 /* FLL_FRC_NCO_VAL - [12:7] */
-#define WM8996_FLL_FRC_NCO_VAL_SHIFT 7 /* FLL_FRC_NCO_VAL - [12:7] */
-#define WM8996_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [12:7] */
-#define WM8996_FLL_FRC_NCO 0x0040 /* FLL_FRC_NCO */
-#define WM8996_FLL_FRC_NCO_MASK 0x0040 /* FLL_FRC_NCO */
-#define WM8996_FLL_FRC_NCO_SHIFT 6 /* FLL_FRC_NCO */
-#define WM8996_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */
-#define WM8996_FLL_REFCLK_DIV_MASK 0x0018 /* FLL_REFCLK_DIV - [4:3] */
-#define WM8996_FLL_REFCLK_DIV_SHIFT 3 /* FLL_REFCLK_DIV - [4:3] */
-#define WM8996_FLL_REFCLK_DIV_WIDTH 2 /* FLL_REFCLK_DIV - [4:3] */
-#define WM8996_FLL_REF_FREQ 0x0004 /* FLL_REF_FREQ */
-#define WM8996_FLL_REF_FREQ_MASK 0x0004 /* FLL_REF_FREQ */
-#define WM8996_FLL_REF_FREQ_SHIFT 2 /* FLL_REF_FREQ */
-#define WM8996_FLL_REF_FREQ_WIDTH 1 /* FLL_REF_FREQ */
-#define WM8996_FLL_REFCLK_SRC_MASK 0x0003 /* FLL_REFCLK_SRC - [1:0] */
-#define WM8996_FLL_REFCLK_SRC_SHIFT 0 /* FLL_REFCLK_SRC - [1:0] */
-#define WM8996_FLL_REFCLK_SRC_WIDTH 2 /* FLL_REFCLK_SRC - [1:0] */
-
-/*
- * R549 (0x225) - FLL Control (6)
- */
-#define WM8996_FLL_REFCLK_SRC_STS_MASK 0x000C /* FLL_REFCLK_SRC_STS - [3:2] */
-#define WM8996_FLL_REFCLK_SRC_STS_SHIFT 2 /* FLL_REFCLK_SRC_STS - [3:2] */
-#define WM8996_FLL_REFCLK_SRC_STS_WIDTH 2 /* FLL_REFCLK_SRC_STS - [3:2] */
-#define WM8996_FLL_SWITCH_CLK 0x0001 /* FLL_SWITCH_CLK */
-#define WM8996_FLL_SWITCH_CLK_MASK 0x0001 /* FLL_SWITCH_CLK */
-#define WM8996_FLL_SWITCH_CLK_SHIFT 0 /* FLL_SWITCH_CLK */
-#define WM8996_FLL_SWITCH_CLK_WIDTH 1 /* FLL_SWITCH_CLK */
-
-/*
- * R550 (0x226) - FLL EFS 1
- */
-#define WM8996_FLL_LAMBDA_MASK 0xFFFF /* FLL_LAMBDA - [15:0] */
-#define WM8996_FLL_LAMBDA_SHIFT 0 /* FLL_LAMBDA - [15:0] */
-#define WM8996_FLL_LAMBDA_WIDTH 16 /* FLL_LAMBDA - [15:0] */
-
-/*
- * R551 (0x227) - FLL EFS 2
- */
-#define WM8996_FLL_LFSR_SEL_MASK 0x0006 /* FLL_LFSR_SEL - [2:1] */
-#define WM8996_FLL_LFSR_SEL_SHIFT 1 /* FLL_LFSR_SEL - [2:1] */
-#define WM8996_FLL_LFSR_SEL_WIDTH 2 /* FLL_LFSR_SEL - [2:1] */
-#define WM8996_FLL_EFS_ENA 0x0001 /* FLL_EFS_ENA */
-#define WM8996_FLL_EFS_ENA_MASK 0x0001 /* FLL_EFS_ENA */
-#define WM8996_FLL_EFS_ENA_SHIFT 0 /* FLL_EFS_ENA */
-#define WM8996_FLL_EFS_ENA_WIDTH 1 /* FLL_EFS_ENA */
-
-/*
- * R768 (0x300) - AIF1 Control
- */
-#define WM8996_AIF1_TRI 0x0004 /* AIF1_TRI */
-#define WM8996_AIF1_TRI_MASK 0x0004 /* AIF1_TRI */
-#define WM8996_AIF1_TRI_SHIFT 2 /* AIF1_TRI */
-#define WM8996_AIF1_TRI_WIDTH 1 /* AIF1_TRI */
-#define WM8996_AIF1_FMT_MASK 0x0003 /* AIF1_FMT - [1:0] */
-#define WM8996_AIF1_FMT_SHIFT 0 /* AIF1_FMT - [1:0] */
-#define WM8996_AIF1_FMT_WIDTH 2 /* AIF1_FMT - [1:0] */
-
-/*
- * R769 (0x301) - AIF1 BCLK
- */
-#define WM8996_AIF1_BCLK_INV 0x0400 /* AIF1_BCLK_INV */
-#define WM8996_AIF1_BCLK_INV_MASK 0x0400 /* AIF1_BCLK_INV */
-#define WM8996_AIF1_BCLK_INV_SHIFT 10 /* AIF1_BCLK_INV */
-#define WM8996_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */
-#define WM8996_AIF1_BCLK_FRC 0x0200 /* AIF1_BCLK_FRC */
-#define WM8996_AIF1_BCLK_FRC_MASK 0x0200 /* AIF1_BCLK_FRC */
-#define WM8996_AIF1_BCLK_FRC_SHIFT 9 /* AIF1_BCLK_FRC */
-#define WM8996_AIF1_BCLK_FRC_WIDTH 1 /* AIF1_BCLK_FRC */
-#define WM8996_AIF1_BCLK_MSTR 0x0100 /* AIF1_BCLK_MSTR */
-#define WM8996_AIF1_BCLK_MSTR_MASK 0x0100 /* AIF1_BCLK_MSTR */
-#define WM8996_AIF1_BCLK_MSTR_SHIFT 8 /* AIF1_BCLK_MSTR */
-#define WM8996_AIF1_BCLK_MSTR_WIDTH 1 /* AIF1_BCLK_MSTR */
-#define WM8996_AIF1_BCLK_DIV_MASK 0x000F /* AIF1_BCLK_DIV - [3:0] */
-#define WM8996_AIF1_BCLK_DIV_SHIFT 0 /* AIF1_BCLK_DIV - [3:0] */
-#define WM8996_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [3:0] */
-
-/*
- * R770 (0x302) - AIF1 TX LRCLK(1)
- */
-#define WM8996_AIF1TX_RATE_MASK 0x07FF /* AIF1TX_RATE - [10:0] */
-#define WM8996_AIF1TX_RATE_SHIFT 0 /* AIF1TX_RATE - [10:0] */
-#define WM8996_AIF1TX_RATE_WIDTH 11 /* AIF1TX_RATE - [10:0] */
-
-/*
- * R771 (0x303) - AIF1 TX LRCLK(2)
- */
-#define WM8996_AIF1TX_LRCLK_MODE 0x0008 /* AIF1TX_LRCLK_MODE */
-#define WM8996_AIF1TX_LRCLK_MODE_MASK 0x0008 /* AIF1TX_LRCLK_MODE */
-#define WM8996_AIF1TX_LRCLK_MODE_SHIFT 3 /* AIF1TX_LRCLK_MODE */
-#define WM8996_AIF1TX_LRCLK_MODE_WIDTH 1 /* AIF1TX_LRCLK_MODE */
-#define WM8996_AIF1TX_LRCLK_INV 0x0004 /* AIF1TX_LRCLK_INV */
-#define WM8996_AIF1TX_LRCLK_INV_MASK 0x0004 /* AIF1TX_LRCLK_INV */
-#define WM8996_AIF1TX_LRCLK_INV_SHIFT 2 /* AIF1TX_LRCLK_INV */
-#define WM8996_AIF1TX_LRCLK_INV_WIDTH 1 /* AIF1TX_LRCLK_INV */
-#define WM8996_AIF1TX_LRCLK_FRC 0x0002 /* AIF1TX_LRCLK_FRC */
-#define WM8996_AIF1TX_LRCLK_FRC_MASK 0x0002 /* AIF1TX_LRCLK_FRC */
-#define WM8996_AIF1TX_LRCLK_FRC_SHIFT 1 /* AIF1TX_LRCLK_FRC */
-#define WM8996_AIF1TX_LRCLK_FRC_WIDTH 1 /* AIF1TX_LRCLK_FRC */
-#define WM8996_AIF1TX_LRCLK_MSTR 0x0001 /* AIF1TX_LRCLK_MSTR */
-#define WM8996_AIF1TX_LRCLK_MSTR_MASK 0x0001 /* AIF1TX_LRCLK_MSTR */
-#define WM8996_AIF1TX_LRCLK_MSTR_SHIFT 0 /* AIF1TX_LRCLK_MSTR */
-#define WM8996_AIF1TX_LRCLK_MSTR_WIDTH 1 /* AIF1TX_LRCLK_MSTR */
-
-/*
- * R772 (0x304) - AIF1 RX LRCLK(1)
- */
-#define WM8996_AIF1RX_RATE_MASK 0x07FF /* AIF1RX_RATE - [10:0] */
-#define WM8996_AIF1RX_RATE_SHIFT 0 /* AIF1RX_RATE - [10:0] */
-#define WM8996_AIF1RX_RATE_WIDTH 11 /* AIF1RX_RATE - [10:0] */
-
-/*
- * R773 (0x305) - AIF1 RX LRCLK(2)
- */
-#define WM8996_AIF1RX_LRCLK_INV 0x0004 /* AIF1RX_LRCLK_INV */
-#define WM8996_AIF1RX_LRCLK_INV_MASK 0x0004 /* AIF1RX_LRCLK_INV */
-#define WM8996_AIF1RX_LRCLK_INV_SHIFT 2 /* AIF1RX_LRCLK_INV */
-#define WM8996_AIF1RX_LRCLK_INV_WIDTH 1 /* AIF1RX_LRCLK_INV */
-#define WM8996_AIF1RX_LRCLK_FRC 0x0002 /* AIF1RX_LRCLK_FRC */
-#define WM8996_AIF1RX_LRCLK_FRC_MASK 0x0002 /* AIF1RX_LRCLK_FRC */
-#define WM8996_AIF1RX_LRCLK_FRC_SHIFT 1 /* AIF1RX_LRCLK_FRC */
-#define WM8996_AIF1RX_LRCLK_FRC_WIDTH 1 /* AIF1RX_LRCLK_FRC */
-#define WM8996_AIF1RX_LRCLK_MSTR 0x0001 /* AIF1RX_LRCLK_MSTR */
-#define WM8996_AIF1RX_LRCLK_MSTR_MASK 0x0001 /* AIF1RX_LRCLK_MSTR */
-#define WM8996_AIF1RX_LRCLK_MSTR_SHIFT 0 /* AIF1RX_LRCLK_MSTR */
-#define WM8996_AIF1RX_LRCLK_MSTR_WIDTH 1 /* AIF1RX_LRCLK_MSTR */
-
-/*
- * R774 (0x306) - AIF1TX Data Configuration (1)
- */
-#define WM8996_AIF1TX_WL_MASK 0xFF00 /* AIF1TX_WL - [15:8] */
-#define WM8996_AIF1TX_WL_SHIFT 8 /* AIF1TX_WL - [15:8] */
-#define WM8996_AIF1TX_WL_WIDTH 8 /* AIF1TX_WL - [15:8] */
-#define WM8996_AIF1TX_SLOT_LEN_MASK 0x00FF /* AIF1TX_SLOT_LEN - [7:0] */
-#define WM8996_AIF1TX_SLOT_LEN_SHIFT 0 /* AIF1TX_SLOT_LEN - [7:0] */
-#define WM8996_AIF1TX_SLOT_LEN_WIDTH 8 /* AIF1TX_SLOT_LEN - [7:0] */
-
-/*
- * R775 (0x307) - AIF1TX Data Configuration (2)
- */
-#define WM8996_AIF1TX_DAT_TRI 0x0001 /* AIF1TX_DAT_TRI */
-#define WM8996_AIF1TX_DAT_TRI_MASK 0x0001 /* AIF1TX_DAT_TRI */
-#define WM8996_AIF1TX_DAT_TRI_SHIFT 0 /* AIF1TX_DAT_TRI */
-#define WM8996_AIF1TX_DAT_TRI_WIDTH 1 /* AIF1TX_DAT_TRI */
-
-/*
- * R776 (0x308) - AIF1RX Data Configuration
- */
-#define WM8996_AIF1RX_WL_MASK 0xFF00 /* AIF1RX_WL - [15:8] */
-#define WM8996_AIF1RX_WL_SHIFT 8 /* AIF1RX_WL - [15:8] */
-#define WM8996_AIF1RX_WL_WIDTH 8 /* AIF1RX_WL - [15:8] */
-#define WM8996_AIF1RX_SLOT_LEN_MASK 0x00FF /* AIF1RX_SLOT_LEN - [7:0] */
-#define WM8996_AIF1RX_SLOT_LEN_SHIFT 0 /* AIF1RX_SLOT_LEN - [7:0] */
-#define WM8996_AIF1RX_SLOT_LEN_WIDTH 8 /* AIF1RX_SLOT_LEN - [7:0] */
-
-/*
- * R777 (0x309) - AIF1TX Channel 0 Configuration
- */
-#define WM8996_AIF1TX_CHAN0_DAT_INV 0x8000 /* AIF1TX_CHAN0_DAT_INV */
-#define WM8996_AIF1TX_CHAN0_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN0_DAT_INV */
-#define WM8996_AIF1TX_CHAN0_DAT_INV_SHIFT 15 /* AIF1TX_CHAN0_DAT_INV */
-#define WM8996_AIF1TX_CHAN0_DAT_INV_WIDTH 1 /* AIF1TX_CHAN0_DAT_INV */
-#define WM8996_AIF1TX_CHAN0_SPACING_MASK 0x7E00 /* AIF1TX_CHAN0_SPACING - [14:9] */
-#define WM8996_AIF1TX_CHAN0_SPACING_SHIFT 9 /* AIF1TX_CHAN0_SPACING - [14:9] */
-#define WM8996_AIF1TX_CHAN0_SPACING_WIDTH 6 /* AIF1TX_CHAN0_SPACING - [14:9] */
-#define WM8996_AIF1TX_CHAN0_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN0_SLOTS - [8:6] */
-#define WM8996_AIF1TX_CHAN0_SLOTS_SHIFT 6 /* AIF1TX_CHAN0_SLOTS - [8:6] */
-#define WM8996_AIF1TX_CHAN0_SLOTS_WIDTH 3 /* AIF1TX_CHAN0_SLOTS - [8:6] */
-#define WM8996_AIF1TX_CHAN0_START_SLOT_MASK 0x003F /* AIF1TX_CHAN0_START_SLOT - [5:0] */
-#define WM8996_AIF1TX_CHAN0_START_SLOT_SHIFT 0 /* AIF1TX_CHAN0_START_SLOT - [5:0] */
-#define WM8996_AIF1TX_CHAN0_START_SLOT_WIDTH 6 /* AIF1TX_CHAN0_START_SLOT - [5:0] */
-
-/*
- * R778 (0x30A) - AIF1TX Channel 1 Configuration
- */
-#define WM8996_AIF1TX_CHAN1_DAT_INV 0x8000 /* AIF1TX_CHAN1_DAT_INV */
-#define WM8996_AIF1TX_CHAN1_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN1_DAT_INV */
-#define WM8996_AIF1TX_CHAN1_DAT_INV_SHIFT 15 /* AIF1TX_CHAN1_DAT_INV */
-#define WM8996_AIF1TX_CHAN1_DAT_INV_WIDTH 1 /* AIF1TX_CHAN1_DAT_INV */
-#define WM8996_AIF1TX_CHAN1_SPACING_MASK 0x7E00 /* AIF1TX_CHAN1_SPACING - [14:9] */
-#define WM8996_AIF1TX_CHAN1_SPACING_SHIFT 9 /* AIF1TX_CHAN1_SPACING - [14:9] */
-#define WM8996_AIF1TX_CHAN1_SPACING_WIDTH 6 /* AIF1TX_CHAN1_SPACING - [14:9] */
-#define WM8996_AIF1TX_CHAN1_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN1_SLOTS - [8:6] */
-#define WM8996_AIF1TX_CHAN1_SLOTS_SHIFT 6 /* AIF1TX_CHAN1_SLOTS - [8:6] */
-#define WM8996_AIF1TX_CHAN1_SLOTS_WIDTH 3 /* AIF1TX_CHAN1_SLOTS - [8:6] */
-#define WM8996_AIF1TX_CHAN1_START_SLOT_MASK 0x003F /* AIF1TX_CHAN1_START_SLOT - [5:0] */
-#define WM8996_AIF1TX_CHAN1_START_SLOT_SHIFT 0 /* AIF1TX_CHAN1_START_SLOT - [5:0] */
-#define WM8996_AIF1TX_CHAN1_START_SLOT_WIDTH 6 /* AIF1TX_CHAN1_START_SLOT - [5:0] */
-
-/*
- * R779 (0x30B) - AIF1TX Channel 2 Configuration
- */
-#define WM8996_AIF1TX_CHAN2_DAT_INV 0x8000 /* AIF1TX_CHAN2_DAT_INV */
-#define WM8996_AIF1TX_CHAN2_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN2_DAT_INV */
-#define WM8996_AIF1TX_CHAN2_DAT_INV_SHIFT 15 /* AIF1TX_CHAN2_DAT_INV */
-#define WM8996_AIF1TX_CHAN2_DAT_INV_WIDTH 1 /* AIF1TX_CHAN2_DAT_INV */
-#define WM8996_AIF1TX_CHAN2_SPACING_MASK 0x7E00 /* AIF1TX_CHAN2_SPACING - [14:9] */
-#define WM8996_AIF1TX_CHAN2_SPACING_SHIFT 9 /* AIF1TX_CHAN2_SPACING - [14:9] */
-#define WM8996_AIF1TX_CHAN2_SPACING_WIDTH 6 /* AIF1TX_CHAN2_SPACING - [14:9] */
-#define WM8996_AIF1TX_CHAN2_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN2_SLOTS - [8:6] */
-#define WM8996_AIF1TX_CHAN2_SLOTS_SHIFT 6 /* AIF1TX_CHAN2_SLOTS - [8:6] */
-#define WM8996_AIF1TX_CHAN2_SLOTS_WIDTH 3 /* AIF1TX_CHAN2_SLOTS - [8:6] */
-#define WM8996_AIF1TX_CHAN2_START_SLOT_MASK 0x003F /* AIF1TX_CHAN2_START_SLOT - [5:0] */
-#define WM8996_AIF1TX_CHAN2_START_SLOT_SHIFT 0 /* AIF1TX_CHAN2_START_SLOT - [5:0] */
-#define WM8996_AIF1TX_CHAN2_START_SLOT_WIDTH 6 /* AIF1TX_CHAN2_START_SLOT - [5:0] */
-
-/*
- * R780 (0x30C) - AIF1TX Channel 3 Configuration
- */
-#define WM8996_AIF1TX_CHAN3_DAT_INV 0x8000 /* AIF1TX_CHAN3_DAT_INV */
-#define WM8996_AIF1TX_CHAN3_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN3_DAT_INV */
-#define WM8996_AIF1TX_CHAN3_DAT_INV_SHIFT 15 /* AIF1TX_CHAN3_DAT_INV */
-#define WM8996_AIF1TX_CHAN3_DAT_INV_WIDTH 1 /* AIF1TX_CHAN3_DAT_INV */
-#define WM8996_AIF1TX_CHAN3_SPACING_MASK 0x7E00 /* AIF1TX_CHAN3_SPACING - [14:9] */
-#define WM8996_AIF1TX_CHAN3_SPACING_SHIFT 9 /* AIF1TX_CHAN3_SPACING - [14:9] */
-#define WM8996_AIF1TX_CHAN3_SPACING_WIDTH 6 /* AIF1TX_CHAN3_SPACING - [14:9] */
-#define WM8996_AIF1TX_CHAN3_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN3_SLOTS - [8:6] */
-#define WM8996_AIF1TX_CHAN3_SLOTS_SHIFT 6 /* AIF1TX_CHAN3_SLOTS - [8:6] */
-#define WM8996_AIF1TX_CHAN3_SLOTS_WIDTH 3 /* AIF1TX_CHAN3_SLOTS - [8:6] */
-#define WM8996_AIF1TX_CHAN3_START_SLOT_MASK 0x003F /* AIF1TX_CHAN3_START_SLOT - [5:0] */
-#define WM8996_AIF1TX_CHAN3_START_SLOT_SHIFT 0 /* AIF1TX_CHAN3_START_SLOT - [5:0] */
-#define WM8996_AIF1TX_CHAN3_START_SLOT_WIDTH 6 /* AIF1TX_CHAN3_START_SLOT - [5:0] */
-
-/*
- * R781 (0x30D) - AIF1TX Channel 4 Configuration
- */
-#define WM8996_AIF1TX_CHAN4_DAT_INV 0x8000 /* AIF1TX_CHAN4_DAT_INV */
-#define WM8996_AIF1TX_CHAN4_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN4_DAT_INV */
-#define WM8996_AIF1TX_CHAN4_DAT_INV_SHIFT 15 /* AIF1TX_CHAN4_DAT_INV */
-#define WM8996_AIF1TX_CHAN4_DAT_INV_WIDTH 1 /* AIF1TX_CHAN4_DAT_INV */
-#define WM8996_AIF1TX_CHAN4_SPACING_MASK 0x7E00 /* AIF1TX_CHAN4_SPACING - [14:9] */
-#define WM8996_AIF1TX_CHAN4_SPACING_SHIFT 9 /* AIF1TX_CHAN4_SPACING - [14:9] */
-#define WM8996_AIF1TX_CHAN4_SPACING_WIDTH 6 /* AIF1TX_CHAN4_SPACING - [14:9] */
-#define WM8996_AIF1TX_CHAN4_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN4_SLOTS - [8:6] */
-#define WM8996_AIF1TX_CHAN4_SLOTS_SHIFT 6 /* AIF1TX_CHAN4_SLOTS - [8:6] */
-#define WM8996_AIF1TX_CHAN4_SLOTS_WIDTH 3 /* AIF1TX_CHAN4_SLOTS - [8:6] */
-#define WM8996_AIF1TX_CHAN4_START_SLOT_MASK 0x003F /* AIF1TX_CHAN4_START_SLOT - [5:0] */
-#define WM8996_AIF1TX_CHAN4_START_SLOT_SHIFT 0 /* AIF1TX_CHAN4_START_SLOT - [5:0] */
-#define WM8996_AIF1TX_CHAN4_START_SLOT_WIDTH 6 /* AIF1TX_CHAN4_START_SLOT - [5:0] */
-
-/*
- * R782 (0x30E) - AIF1TX Channel 5 Configuration
- */
-#define WM8996_AIF1TX_CHAN5_DAT_INV 0x8000 /* AIF1TX_CHAN5_DAT_INV */
-#define WM8996_AIF1TX_CHAN5_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN5_DAT_INV */
-#define WM8996_AIF1TX_CHAN5_DAT_INV_SHIFT 15 /* AIF1TX_CHAN5_DAT_INV */
-#define WM8996_AIF1TX_CHAN5_DAT_INV_WIDTH 1 /* AIF1TX_CHAN5_DAT_INV */
-#define WM8996_AIF1TX_CHAN5_SPACING_MASK 0x7E00 /* AIF1TX_CHAN5_SPACING - [14:9] */
-#define WM8996_AIF1TX_CHAN5_SPACING_SHIFT 9 /* AIF1TX_CHAN5_SPACING - [14:9] */
-#define WM8996_AIF1TX_CHAN5_SPACING_WIDTH 6 /* AIF1TX_CHAN5_SPACING - [14:9] */
-#define WM8996_AIF1TX_CHAN5_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN5_SLOTS - [8:6] */
-#define WM8996_AIF1TX_CHAN5_SLOTS_SHIFT 6 /* AIF1TX_CHAN5_SLOTS - [8:6] */
-#define WM8996_AIF1TX_CHAN5_SLOTS_WIDTH 3 /* AIF1TX_CHAN5_SLOTS - [8:6] */
-#define WM8996_AIF1TX_CHAN5_START_SLOT_MASK 0x003F /* AIF1TX_CHAN5_START_SLOT - [5:0] */
-#define WM8996_AIF1TX_CHAN5_START_SLOT_SHIFT 0 /* AIF1TX_CHAN5_START_SLOT - [5:0] */
-#define WM8996_AIF1TX_CHAN5_START_SLOT_WIDTH 6 /* AIF1TX_CHAN5_START_SLOT - [5:0] */
-
-/*
- * R783 (0x30F) - AIF1RX Channel 0 Configuration
- */
-#define WM8996_AIF1RX_CHAN0_DAT_INV 0x8000 /* AIF1RX_CHAN0_DAT_INV */
-#define WM8996_AIF1RX_CHAN0_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN0_DAT_INV */
-#define WM8996_AIF1RX_CHAN0_DAT_INV_SHIFT 15 /* AIF1RX_CHAN0_DAT_INV */
-#define WM8996_AIF1RX_CHAN0_DAT_INV_WIDTH 1 /* AIF1RX_CHAN0_DAT_INV */
-#define WM8996_AIF1RX_CHAN0_SPACING_MASK 0x7E00 /* AIF1RX_CHAN0_SPACING - [14:9] */
-#define WM8996_AIF1RX_CHAN0_SPACING_SHIFT 9 /* AIF1RX_CHAN0_SPACING - [14:9] */
-#define WM8996_AIF1RX_CHAN0_SPACING_WIDTH 6 /* AIF1RX_CHAN0_SPACING - [14:9] */
-#define WM8996_AIF1RX_CHAN0_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN0_SLOTS - [8:6] */
-#define WM8996_AIF1RX_CHAN0_SLOTS_SHIFT 6 /* AIF1RX_CHAN0_SLOTS - [8:6] */
-#define WM8996_AIF1RX_CHAN0_SLOTS_WIDTH 3 /* AIF1RX_CHAN0_SLOTS - [8:6] */
-#define WM8996_AIF1RX_CHAN0_START_SLOT_MASK 0x003F /* AIF1RX_CHAN0_START_SLOT - [5:0] */
-#define WM8996_AIF1RX_CHAN0_START_SLOT_SHIFT 0 /* AIF1RX_CHAN0_START_SLOT - [5:0] */
-#define WM8996_AIF1RX_CHAN0_START_SLOT_WIDTH 6 /* AIF1RX_CHAN0_START_SLOT - [5:0] */
-
-/*
- * R784 (0x310) - AIF1RX Channel 1 Configuration
- */
-#define WM8996_AIF1RX_CHAN1_DAT_INV 0x8000 /* AIF1RX_CHAN1_DAT_INV */
-#define WM8996_AIF1RX_CHAN1_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN1_DAT_INV */
-#define WM8996_AIF1RX_CHAN1_DAT_INV_SHIFT 15 /* AIF1RX_CHAN1_DAT_INV */
-#define WM8996_AIF1RX_CHAN1_DAT_INV_WIDTH 1 /* AIF1RX_CHAN1_DAT_INV */
-#define WM8996_AIF1RX_CHAN1_SPACING_MASK 0x7E00 /* AIF1RX_CHAN1_SPACING - [14:9] */
-#define WM8996_AIF1RX_CHAN1_SPACING_SHIFT 9 /* AIF1RX_CHAN1_SPACING - [14:9] */
-#define WM8996_AIF1RX_CHAN1_SPACING_WIDTH 6 /* AIF1RX_CHAN1_SPACING - [14:9] */
-#define WM8996_AIF1RX_CHAN1_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN1_SLOTS - [8:6] */
-#define WM8996_AIF1RX_CHAN1_SLOTS_SHIFT 6 /* AIF1RX_CHAN1_SLOTS - [8:6] */
-#define WM8996_AIF1RX_CHAN1_SLOTS_WIDTH 3 /* AIF1RX_CHAN1_SLOTS - [8:6] */
-#define WM8996_AIF1RX_CHAN1_START_SLOT_MASK 0x003F /* AIF1RX_CHAN1_START_SLOT - [5:0] */
-#define WM8996_AIF1RX_CHAN1_START_SLOT_SHIFT 0 /* AIF1RX_CHAN1_START_SLOT - [5:0] */
-#define WM8996_AIF1RX_CHAN1_START_SLOT_WIDTH 6 /* AIF1RX_CHAN1_START_SLOT - [5:0] */
-
-/*
- * R785 (0x311) - AIF1RX Channel 2 Configuration
- */
-#define WM8996_AIF1RX_CHAN2_DAT_INV 0x8000 /* AIF1RX_CHAN2_DAT_INV */
-#define WM8996_AIF1RX_CHAN2_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN2_DAT_INV */
-#define WM8996_AIF1RX_CHAN2_DAT_INV_SHIFT 15 /* AIF1RX_CHAN2_DAT_INV */
-#define WM8996_AIF1RX_CHAN2_DAT_INV_WIDTH 1 /* AIF1RX_CHAN2_DAT_INV */
-#define WM8996_AIF1RX_CHAN2_SPACING_MASK 0x7E00 /* AIF1RX_CHAN2_SPACING - [14:9] */
-#define WM8996_AIF1RX_CHAN2_SPACING_SHIFT 9 /* AIF1RX_CHAN2_SPACING - [14:9] */
-#define WM8996_AIF1RX_CHAN2_SPACING_WIDTH 6 /* AIF1RX_CHAN2_SPACING - [14:9] */
-#define WM8996_AIF1RX_CHAN2_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN2_SLOTS - [8:6] */
-#define WM8996_AIF1RX_CHAN2_SLOTS_SHIFT 6 /* AIF1RX_CHAN2_SLOTS - [8:6] */
-#define WM8996_AIF1RX_CHAN2_SLOTS_WIDTH 3 /* AIF1RX_CHAN2_SLOTS - [8:6] */
-#define WM8996_AIF1RX_CHAN2_START_SLOT_MASK 0x003F /* AIF1RX_CHAN2_START_SLOT - [5:0] */
-#define WM8996_AIF1RX_CHAN2_START_SLOT_SHIFT 0 /* AIF1RX_CHAN2_START_SLOT - [5:0] */
-#define WM8996_AIF1RX_CHAN2_START_SLOT_WIDTH 6 /* AIF1RX_CHAN2_START_SLOT - [5:0] */
-
-/*
- * R786 (0x312) - AIF1RX Channel 3 Configuration
- */
-#define WM8996_AIF1RX_CHAN3_DAT_INV 0x8000 /* AIF1RX_CHAN3_DAT_INV */
-#define WM8996_AIF1RX_CHAN3_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN3_DAT_INV */
-#define WM8996_AIF1RX_CHAN3_DAT_INV_SHIFT 15 /* AIF1RX_CHAN3_DAT_INV */
-#define WM8996_AIF1RX_CHAN3_DAT_INV_WIDTH 1 /* AIF1RX_CHAN3_DAT_INV */
-#define WM8996_AIF1RX_CHAN3_SPACING_MASK 0x7E00 /* AIF1RX_CHAN3_SPACING - [14:9] */
-#define WM8996_AIF1RX_CHAN3_SPACING_SHIFT 9 /* AIF1RX_CHAN3_SPACING - [14:9] */
-#define WM8996_AIF1RX_CHAN3_SPACING_WIDTH 6 /* AIF1RX_CHAN3_SPACING - [14:9] */
-#define WM8996_AIF1RX_CHAN3_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN3_SLOTS - [8:6] */
-#define WM8996_AIF1RX_CHAN3_SLOTS_SHIFT 6 /* AIF1RX_CHAN3_SLOTS - [8:6] */
-#define WM8996_AIF1RX_CHAN3_SLOTS_WIDTH 3 /* AIF1RX_CHAN3_SLOTS - [8:6] */
-#define WM8996_AIF1RX_CHAN3_START_SLOT_MASK 0x003F /* AIF1RX_CHAN3_START_SLOT - [5:0] */
-#define WM8996_AIF1RX_CHAN3_START_SLOT_SHIFT 0 /* AIF1RX_CHAN3_START_SLOT - [5:0] */
-#define WM8996_AIF1RX_CHAN3_START_SLOT_WIDTH 6 /* AIF1RX_CHAN3_START_SLOT - [5:0] */
-
-/*
- * R787 (0x313) - AIF1RX Channel 4 Configuration
- */
-#define WM8996_AIF1RX_CHAN4_DAT_INV 0x8000 /* AIF1RX_CHAN4_DAT_INV */
-#define WM8996_AIF1RX_CHAN4_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN4_DAT_INV */
-#define WM8996_AIF1RX_CHAN4_DAT_INV_SHIFT 15 /* AIF1RX_CHAN4_DAT_INV */
-#define WM8996_AIF1RX_CHAN4_DAT_INV_WIDTH 1 /* AIF1RX_CHAN4_DAT_INV */
-#define WM8996_AIF1RX_CHAN4_SPACING_MASK 0x7E00 /* AIF1RX_CHAN4_SPACING - [14:9] */
-#define WM8996_AIF1RX_CHAN4_SPACING_SHIFT 9 /* AIF1RX_CHAN4_SPACING - [14:9] */
-#define WM8996_AIF1RX_CHAN4_SPACING_WIDTH 6 /* AIF1RX_CHAN4_SPACING - [14:9] */
-#define WM8996_AIF1RX_CHAN4_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN4_SLOTS - [8:6] */
-#define WM8996_AIF1RX_CHAN4_SLOTS_SHIFT 6 /* AIF1RX_CHAN4_SLOTS - [8:6] */
-#define WM8996_AIF1RX_CHAN4_SLOTS_WIDTH 3 /* AIF1RX_CHAN4_SLOTS - [8:6] */
-#define WM8996_AIF1RX_CHAN4_START_SLOT_MASK 0x003F /* AIF1RX_CHAN4_START_SLOT - [5:0] */
-#define WM8996_AIF1RX_CHAN4_START_SLOT_SHIFT 0 /* AIF1RX_CHAN4_START_SLOT - [5:0] */
-#define WM8996_AIF1RX_CHAN4_START_SLOT_WIDTH 6 /* AIF1RX_CHAN4_START_SLOT - [5:0] */
-
-/*
- * R788 (0x314) - AIF1RX Channel 5 Configuration
- */
-#define WM8996_AIF1RX_CHAN5_DAT_INV 0x8000 /* AIF1RX_CHAN5_DAT_INV */
-#define WM8996_AIF1RX_CHAN5_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN5_DAT_INV */
-#define WM8996_AIF1RX_CHAN5_DAT_INV_SHIFT 15 /* AIF1RX_CHAN5_DAT_INV */
-#define WM8996_AIF1RX_CHAN5_DAT_INV_WIDTH 1 /* AIF1RX_CHAN5_DAT_INV */
-#define WM8996_AIF1RX_CHAN5_SPACING_MASK 0x7E00 /* AIF1RX_CHAN5_SPACING - [14:9] */
-#define WM8996_AIF1RX_CHAN5_SPACING_SHIFT 9 /* AIF1RX_CHAN5_SPACING - [14:9] */
-#define WM8996_AIF1RX_CHAN5_SPACING_WIDTH 6 /* AIF1RX_CHAN5_SPACING - [14:9] */
-#define WM8996_AIF1RX_CHAN5_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN5_SLOTS - [8:6] */
-#define WM8996_AIF1RX_CHAN5_SLOTS_SHIFT 6 /* AIF1RX_CHAN5_SLOTS - [8:6] */
-#define WM8996_AIF1RX_CHAN5_SLOTS_WIDTH 3 /* AIF1RX_CHAN5_SLOTS - [8:6] */
-#define WM8996_AIF1RX_CHAN5_START_SLOT_MASK 0x003F /* AIF1RX_CHAN5_START_SLOT - [5:0] */
-#define WM8996_AIF1RX_CHAN5_START_SLOT_SHIFT 0 /* AIF1RX_CHAN5_START_SLOT - [5:0] */
-#define WM8996_AIF1RX_CHAN5_START_SLOT_WIDTH 6 /* AIF1RX_CHAN5_START_SLOT - [5:0] */
-
-/*
- * R789 (0x315) - AIF1RX Mono Configuration
- */
-#define WM8996_AIF1RX_CHAN4_MONO_MODE 0x0004 /* AIF1RX_CHAN4_MONO_MODE */
-#define WM8996_AIF1RX_CHAN4_MONO_MODE_MASK 0x0004 /* AIF1RX_CHAN4_MONO_MODE */
-#define WM8996_AIF1RX_CHAN4_MONO_MODE_SHIFT 2 /* AIF1RX_CHAN4_MONO_MODE */
-#define WM8996_AIF1RX_CHAN4_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN4_MONO_MODE */
-#define WM8996_AIF1RX_CHAN2_MONO_MODE 0x0002 /* AIF1RX_CHAN2_MONO_MODE */
-#define WM8996_AIF1RX_CHAN2_MONO_MODE_MASK 0x0002 /* AIF1RX_CHAN2_MONO_MODE */
-#define WM8996_AIF1RX_CHAN2_MONO_MODE_SHIFT 1 /* AIF1RX_CHAN2_MONO_MODE */
-#define WM8996_AIF1RX_CHAN2_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN2_MONO_MODE */
-#define WM8996_AIF1RX_CHAN0_MONO_MODE 0x0001 /* AIF1RX_CHAN0_MONO_MODE */
-#define WM8996_AIF1RX_CHAN0_MONO_MODE_MASK 0x0001 /* AIF1RX_CHAN0_MONO_MODE */
-#define WM8996_AIF1RX_CHAN0_MONO_MODE_SHIFT 0 /* AIF1RX_CHAN0_MONO_MODE */
-#define WM8996_AIF1RX_CHAN0_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN0_MONO_MODE */
-
-/*
- * R794 (0x31A) - AIF1TX Test
- */
-#define WM8996_AIF1TX45_DITHER_ENA 0x0004 /* AIF1TX45_DITHER_ENA */
-#define WM8996_AIF1TX45_DITHER_ENA_MASK 0x0004 /* AIF1TX45_DITHER_ENA */
-#define WM8996_AIF1TX45_DITHER_ENA_SHIFT 2 /* AIF1TX45_DITHER_ENA */
-#define WM8996_AIF1TX45_DITHER_ENA_WIDTH 1 /* AIF1TX45_DITHER_ENA */
-#define WM8996_AIF1TX23_DITHER_ENA 0x0002 /* AIF1TX23_DITHER_ENA */
-#define WM8996_AIF1TX23_DITHER_ENA_MASK 0x0002 /* AIF1TX23_DITHER_ENA */
-#define WM8996_AIF1TX23_DITHER_ENA_SHIFT 1 /* AIF1TX23_DITHER_ENA */
-#define WM8996_AIF1TX23_DITHER_ENA_WIDTH 1 /* AIF1TX23_DITHER_ENA */
-#define WM8996_AIF1TX01_DITHER_ENA 0x0001 /* AIF1TX01_DITHER_ENA */
-#define WM8996_AIF1TX01_DITHER_ENA_MASK 0x0001 /* AIF1TX01_DITHER_ENA */
-#define WM8996_AIF1TX01_DITHER_ENA_SHIFT 0 /* AIF1TX01_DITHER_ENA */
-#define WM8996_AIF1TX01_DITHER_ENA_WIDTH 1 /* AIF1TX01_DITHER_ENA */
-
-/*
- * R800 (0x320) - AIF2 Control
- */
-#define WM8996_AIF2_TRI 0x0004 /* AIF2_TRI */
-#define WM8996_AIF2_TRI_MASK 0x0004 /* AIF2_TRI */
-#define WM8996_AIF2_TRI_SHIFT 2 /* AIF2_TRI */
-#define WM8996_AIF2_TRI_WIDTH 1 /* AIF2_TRI */
-#define WM8996_AIF2_FMT_MASK 0x0003 /* AIF2_FMT - [1:0] */
-#define WM8996_AIF2_FMT_SHIFT 0 /* AIF2_FMT - [1:0] */
-#define WM8996_AIF2_FMT_WIDTH 2 /* AIF2_FMT - [1:0] */
-
-/*
- * R801 (0x321) - AIF2 BCLK
- */
-#define WM8996_AIF2_BCLK_INV 0x0400 /* AIF2_BCLK_INV */
-#define WM8996_AIF2_BCLK_INV_MASK 0x0400 /* AIF2_BCLK_INV */
-#define WM8996_AIF2_BCLK_INV_SHIFT 10 /* AIF2_BCLK_INV */
-#define WM8996_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */
-#define WM8996_AIF2_BCLK_FRC 0x0200 /* AIF2_BCLK_FRC */
-#define WM8996_AIF2_BCLK_FRC_MASK 0x0200 /* AIF2_BCLK_FRC */
-#define WM8996_AIF2_BCLK_FRC_SHIFT 9 /* AIF2_BCLK_FRC */
-#define WM8996_AIF2_BCLK_FRC_WIDTH 1 /* AIF2_BCLK_FRC */
-#define WM8996_AIF2_BCLK_MSTR 0x0100 /* AIF2_BCLK_MSTR */
-#define WM8996_AIF2_BCLK_MSTR_MASK 0x0100 /* AIF2_BCLK_MSTR */
-#define WM8996_AIF2_BCLK_MSTR_SHIFT 8 /* AIF2_BCLK_MSTR */
-#define WM8996_AIF2_BCLK_MSTR_WIDTH 1 /* AIF2_BCLK_MSTR */
-#define WM8996_AIF2_BCLK_DIV_MASK 0x000F /* AIF2_BCLK_DIV - [3:0] */
-#define WM8996_AIF2_BCLK_DIV_SHIFT 0 /* AIF2_BCLK_DIV - [3:0] */
-#define WM8996_AIF2_BCLK_DIV_WIDTH 4 /* AIF2_BCLK_DIV - [3:0] */
-
-/*
- * R802 (0x322) - AIF2 TX LRCLK(1)
- */
-#define WM8996_AIF2TX_RATE_MASK 0x07FF /* AIF2TX_RATE - [10:0] */
-#define WM8996_AIF2TX_RATE_SHIFT 0 /* AIF2TX_RATE - [10:0] */
-#define WM8996_AIF2TX_RATE_WIDTH 11 /* AIF2TX_RATE - [10:0] */
-
-/*
- * R803 (0x323) - AIF2 TX LRCLK(2)
- */
-#define WM8996_AIF2TX_LRCLK_MODE 0x0008 /* AIF2TX_LRCLK_MODE */
-#define WM8996_AIF2TX_LRCLK_MODE_MASK 0x0008 /* AIF2TX_LRCLK_MODE */
-#define WM8996_AIF2TX_LRCLK_MODE_SHIFT 3 /* AIF2TX_LRCLK_MODE */
-#define WM8996_AIF2TX_LRCLK_MODE_WIDTH 1 /* AIF2TX_LRCLK_MODE */
-#define WM8996_AIF2TX_LRCLK_INV 0x0004 /* AIF2TX_LRCLK_INV */
-#define WM8996_AIF2TX_LRCLK_INV_MASK 0x0004 /* AIF2TX_LRCLK_INV */
-#define WM8996_AIF2TX_LRCLK_INV_SHIFT 2 /* AIF2TX_LRCLK_INV */
-#define WM8996_AIF2TX_LRCLK_INV_WIDTH 1 /* AIF2TX_LRCLK_INV */
-#define WM8996_AIF2TX_LRCLK_FRC 0x0002 /* AIF2TX_LRCLK_FRC */
-#define WM8996_AIF2TX_LRCLK_FRC_MASK 0x0002 /* AIF2TX_LRCLK_FRC */
-#define WM8996_AIF2TX_LRCLK_FRC_SHIFT 1 /* AIF2TX_LRCLK_FRC */
-#define WM8996_AIF2TX_LRCLK_FRC_WIDTH 1 /* AIF2TX_LRCLK_FRC */
-#define WM8996_AIF2TX_LRCLK_MSTR 0x0001 /* AIF2TX_LRCLK_MSTR */
-#define WM8996_AIF2TX_LRCLK_MSTR_MASK 0x0001 /* AIF2TX_LRCLK_MSTR */
-#define WM8996_AIF2TX_LRCLK_MSTR_SHIFT 0 /* AIF2TX_LRCLK_MSTR */
-#define WM8996_AIF2TX_LRCLK_MSTR_WIDTH 1 /* AIF2TX_LRCLK_MSTR */
-
-/*
- * R804 (0x324) - AIF2 RX LRCLK(1)
- */
-#define WM8996_AIF2RX_RATE_MASK 0x07FF /* AIF2RX_RATE - [10:0] */
-#define WM8996_AIF2RX_RATE_SHIFT 0 /* AIF2RX_RATE - [10:0] */
-#define WM8996_AIF2RX_RATE_WIDTH 11 /* AIF2RX_RATE - [10:0] */
-
-/*
- * R805 (0x325) - AIF2 RX LRCLK(2)
- */
-#define WM8996_AIF2RX_LRCLK_INV 0x0004 /* AIF2RX_LRCLK_INV */
-#define WM8996_AIF2RX_LRCLK_INV_MASK 0x0004 /* AIF2RX_LRCLK_INV */
-#define WM8996_AIF2RX_LRCLK_INV_SHIFT 2 /* AIF2RX_LRCLK_INV */
-#define WM8996_AIF2RX_LRCLK_INV_WIDTH 1 /* AIF2RX_LRCLK_INV */
-#define WM8996_AIF2RX_LRCLK_FRC 0x0002 /* AIF2RX_LRCLK_FRC */
-#define WM8996_AIF2RX_LRCLK_FRC_MASK 0x0002 /* AIF2RX_LRCLK_FRC */
-#define WM8996_AIF2RX_LRCLK_FRC_SHIFT 1 /* AIF2RX_LRCLK_FRC */
-#define WM8996_AIF2RX_LRCLK_FRC_WIDTH 1 /* AIF2RX_LRCLK_FRC */
-#define WM8996_AIF2RX_LRCLK_MSTR 0x0001 /* AIF2RX_LRCLK_MSTR */
-#define WM8996_AIF2RX_LRCLK_MSTR_MASK 0x0001 /* AIF2RX_LRCLK_MSTR */
-#define WM8996_AIF2RX_LRCLK_MSTR_SHIFT 0 /* AIF2RX_LRCLK_MSTR */
-#define WM8996_AIF2RX_LRCLK_MSTR_WIDTH 1 /* AIF2RX_LRCLK_MSTR */
-
-/*
- * R806 (0x326) - AIF2TX Data Configuration (1)
- */
-#define WM8996_AIF2TX_WL_MASK 0xFF00 /* AIF2TX_WL - [15:8] */
-#define WM8996_AIF2TX_WL_SHIFT 8 /* AIF2TX_WL - [15:8] */
-#define WM8996_AIF2TX_WL_WIDTH 8 /* AIF2TX_WL - [15:8] */
-#define WM8996_AIF2TX_SLOT_LEN_MASK 0x00FF /* AIF2TX_SLOT_LEN - [7:0] */
-#define WM8996_AIF2TX_SLOT_LEN_SHIFT 0 /* AIF2TX_SLOT_LEN - [7:0] */
-#define WM8996_AIF2TX_SLOT_LEN_WIDTH 8 /* AIF2TX_SLOT_LEN - [7:0] */
-
-/*
- * R807 (0x327) - AIF2TX Data Configuration (2)
- */
-#define WM8996_AIF2TX_DAT_TRI 0x0001 /* AIF2TX_DAT_TRI */
-#define WM8996_AIF2TX_DAT_TRI_MASK 0x0001 /* AIF2TX_DAT_TRI */
-#define WM8996_AIF2TX_DAT_TRI_SHIFT 0 /* AIF2TX_DAT_TRI */
-#define WM8996_AIF2TX_DAT_TRI_WIDTH 1 /* AIF2TX_DAT_TRI */
-
-/*
- * R808 (0x328) - AIF2RX Data Configuration
- */
-#define WM8996_AIF2RX_WL_MASK 0xFF00 /* AIF2RX_WL - [15:8] */
-#define WM8996_AIF2RX_WL_SHIFT 8 /* AIF2RX_WL - [15:8] */
-#define WM8996_AIF2RX_WL_WIDTH 8 /* AIF2RX_WL - [15:8] */
-#define WM8996_AIF2RX_SLOT_LEN_MASK 0x00FF /* AIF2RX_SLOT_LEN - [7:0] */
-#define WM8996_AIF2RX_SLOT_LEN_SHIFT 0 /* AIF2RX_SLOT_LEN - [7:0] */
-#define WM8996_AIF2RX_SLOT_LEN_WIDTH 8 /* AIF2RX_SLOT_LEN - [7:0] */
-
-/*
- * R809 (0x329) - AIF2TX Channel 0 Configuration
- */
-#define WM8996_AIF2TX_CHAN0_DAT_INV 0x8000 /* AIF2TX_CHAN0_DAT_INV */
-#define WM8996_AIF2TX_CHAN0_DAT_INV_MASK 0x8000 /* AIF2TX_CHAN0_DAT_INV */
-#define WM8996_AIF2TX_CHAN0_DAT_INV_SHIFT 15 /* AIF2TX_CHAN0_DAT_INV */
-#define WM8996_AIF2TX_CHAN0_DAT_INV_WIDTH 1 /* AIF2TX_CHAN0_DAT_INV */
-#define WM8996_AIF2TX_CHAN0_SPACING_MASK 0x7E00 /* AIF2TX_CHAN0_SPACING - [14:9] */
-#define WM8996_AIF2TX_CHAN0_SPACING_SHIFT 9 /* AIF2TX_CHAN0_SPACING - [14:9] */
-#define WM8996_AIF2TX_CHAN0_SPACING_WIDTH 6 /* AIF2TX_CHAN0_SPACING - [14:9] */
-#define WM8996_AIF2TX_CHAN0_SLOTS_MASK 0x01C0 /* AIF2TX_CHAN0_SLOTS - [8:6] */
-#define WM8996_AIF2TX_CHAN0_SLOTS_SHIFT 6 /* AIF2TX_CHAN0_SLOTS - [8:6] */
-#define WM8996_AIF2TX_CHAN0_SLOTS_WIDTH 3 /* AIF2TX_CHAN0_SLOTS - [8:6] */
-#define WM8996_AIF2TX_CHAN0_START_SLOT_MASK 0x003F /* AIF2TX_CHAN0_START_SLOT - [5:0] */
-#define WM8996_AIF2TX_CHAN0_START_SLOT_SHIFT 0 /* AIF2TX_CHAN0_START_SLOT - [5:0] */
-#define WM8996_AIF2TX_CHAN0_START_SLOT_WIDTH 6 /* AIF2TX_CHAN0_START_SLOT - [5:0] */
-
-/*
- * R810 (0x32A) - AIF2TX Channel 1 Configuration
- */
-#define WM8996_AIF2TX_CHAN1_DAT_INV 0x8000 /* AIF2TX_CHAN1_DAT_INV */
-#define WM8996_AIF2TX_CHAN1_DAT_INV_MASK 0x8000 /* AIF2TX_CHAN1_DAT_INV */
-#define WM8996_AIF2TX_CHAN1_DAT_INV_SHIFT 15 /* AIF2TX_CHAN1_DAT_INV */
-#define WM8996_AIF2TX_CHAN1_DAT_INV_WIDTH 1 /* AIF2TX_CHAN1_DAT_INV */
-#define WM8996_AIF2TX_CHAN1_SPACING_MASK 0x7E00 /* AIF2TX_CHAN1_SPACING - [14:9] */
-#define WM8996_AIF2TX_CHAN1_SPACING_SHIFT 9 /* AIF2TX_CHAN1_SPACING - [14:9] */
-#define WM8996_AIF2TX_CHAN1_SPACING_WIDTH 6 /* AIF2TX_CHAN1_SPACING - [14:9] */
-#define WM8996_AIF2TX_CHAN1_SLOTS_MASK 0x01C0 /* AIF2TX_CHAN1_SLOTS - [8:6] */
-#define WM8996_AIF2TX_CHAN1_SLOTS_SHIFT 6 /* AIF2TX_CHAN1_SLOTS - [8:6] */
-#define WM8996_AIF2TX_CHAN1_SLOTS_WIDTH 3 /* AIF2TX_CHAN1_SLOTS - [8:6] */
-#define WM8996_AIF2TX_CHAN1_START_SLOT_MASK 0x003F /* AIF2TX_CHAN1_START_SLOT - [5:0] */
-#define WM8996_AIF2TX_CHAN1_START_SLOT_SHIFT 0 /* AIF2TX_CHAN1_START_SLOT - [5:0] */
-#define WM8996_AIF2TX_CHAN1_START_SLOT_WIDTH 6 /* AIF2TX_CHAN1_START_SLOT - [5:0] */
-
-/*
- * R811 (0x32B) - AIF2RX Channel 0 Configuration
- */
-#define WM8996_AIF2RX_CHAN0_DAT_INV 0x8000 /* AIF2RX_CHAN0_DAT_INV */
-#define WM8996_AIF2RX_CHAN0_DAT_INV_MASK 0x8000 /* AIF2RX_CHAN0_DAT_INV */
-#define WM8996_AIF2RX_CHAN0_DAT_INV_SHIFT 15 /* AIF2RX_CHAN0_DAT_INV */
-#define WM8996_AIF2RX_CHAN0_DAT_INV_WIDTH 1 /* AIF2RX_CHAN0_DAT_INV */
-#define WM8996_AIF2RX_CHAN0_SPACING_MASK 0x7E00 /* AIF2RX_CHAN0_SPACING - [14:9] */
-#define WM8996_AIF2RX_CHAN0_SPACING_SHIFT 9 /* AIF2RX_CHAN0_SPACING - [14:9] */
-#define WM8996_AIF2RX_CHAN0_SPACING_WIDTH 6 /* AIF2RX_CHAN0_SPACING - [14:9] */
-#define WM8996_AIF2RX_CHAN0_SLOTS_MASK 0x01C0 /* AIF2RX_CHAN0_SLOTS - [8:6] */
-#define WM8996_AIF2RX_CHAN0_SLOTS_SHIFT 6 /* AIF2RX_CHAN0_SLOTS - [8:6] */
-#define WM8996_AIF2RX_CHAN0_SLOTS_WIDTH 3 /* AIF2RX_CHAN0_SLOTS - [8:6] */
-#define WM8996_AIF2RX_CHAN0_START_SLOT_MASK 0x003F /* AIF2RX_CHAN0_START_SLOT - [5:0] */
-#define WM8996_AIF2RX_CHAN0_START_SLOT_SHIFT 0 /* AIF2RX_CHAN0_START_SLOT - [5:0] */
-#define WM8996_AIF2RX_CHAN0_START_SLOT_WIDTH 6 /* AIF2RX_CHAN0_START_SLOT - [5:0] */
-
-/*
- * R812 (0x32C) - AIF2RX Channel 1 Configuration
- */
-#define WM8996_AIF2RX_CHAN1_DAT_INV 0x8000 /* AIF2RX_CHAN1_DAT_INV */
-#define WM8996_AIF2RX_CHAN1_DAT_INV_MASK 0x8000 /* AIF2RX_CHAN1_DAT_INV */
-#define WM8996_AIF2RX_CHAN1_DAT_INV_SHIFT 15 /* AIF2RX_CHAN1_DAT_INV */
-#define WM8996_AIF2RX_CHAN1_DAT_INV_WIDTH 1 /* AIF2RX_CHAN1_DAT_INV */
-#define WM8996_AIF2RX_CHAN1_SPACING_MASK 0x7E00 /* AIF2RX_CHAN1_SPACING - [14:9] */
-#define WM8996_AIF2RX_CHAN1_SPACING_SHIFT 9 /* AIF2RX_CHAN1_SPACING - [14:9] */
-#define WM8996_AIF2RX_CHAN1_SPACING_WIDTH 6 /* AIF2RX_CHAN1_SPACING - [14:9] */
-#define WM8996_AIF2RX_CHAN1_SLOTS_MASK 0x01C0 /* AIF2RX_CHAN1_SLOTS - [8:6] */
-#define WM8996_AIF2RX_CHAN1_SLOTS_SHIFT 6 /* AIF2RX_CHAN1_SLOTS - [8:6] */
-#define WM8996_AIF2RX_CHAN1_SLOTS_WIDTH 3 /* AIF2RX_CHAN1_SLOTS - [8:6] */
-#define WM8996_AIF2RX_CHAN1_START_SLOT_MASK 0x003F /* AIF2RX_CHAN1_START_SLOT - [5:0] */
-#define WM8996_AIF2RX_CHAN1_START_SLOT_SHIFT 0 /* AIF2RX_CHAN1_START_SLOT - [5:0] */
-#define WM8996_AIF2RX_CHAN1_START_SLOT_WIDTH 6 /* AIF2RX_CHAN1_START_SLOT - [5:0] */
-
-/*
- * R813 (0x32D) - AIF2RX Mono Configuration
- */
-#define WM8996_AIF2RX_CHAN0_MONO_MODE 0x0001 /* AIF2RX_CHAN0_MONO_MODE */
-#define WM8996_AIF2RX_CHAN0_MONO_MODE_MASK 0x0001 /* AIF2RX_CHAN0_MONO_MODE */
-#define WM8996_AIF2RX_CHAN0_MONO_MODE_SHIFT 0 /* AIF2RX_CHAN0_MONO_MODE */
-#define WM8996_AIF2RX_CHAN0_MONO_MODE_WIDTH 1 /* AIF2RX_CHAN0_MONO_MODE */
-
-/*
- * R815 (0x32F) - AIF2TX Test
- */
-#define WM8996_AIF2TX_DITHER_ENA 0x0001 /* AIF2TX_DITHER_ENA */
-#define WM8996_AIF2TX_DITHER_ENA_MASK 0x0001 /* AIF2TX_DITHER_ENA */
-#define WM8996_AIF2TX_DITHER_ENA_SHIFT 0 /* AIF2TX_DITHER_ENA */
-#define WM8996_AIF2TX_DITHER_ENA_WIDTH 1 /* AIF2TX_DITHER_ENA */
-
-/*
- * R1024 (0x400) - DSP1 TX Left Volume
- */
-#define WM8996_DSP1TX_VU 0x0100 /* DSP1TX_VU */
-#define WM8996_DSP1TX_VU_MASK 0x0100 /* DSP1TX_VU */
-#define WM8996_DSP1TX_VU_SHIFT 8 /* DSP1TX_VU */
-#define WM8996_DSP1TX_VU_WIDTH 1 /* DSP1TX_VU */
-#define WM8996_DSP1TXL_VOL_MASK 0x00FF /* DSP1TXL_VOL - [7:0] */
-#define WM8996_DSP1TXL_VOL_SHIFT 0 /* DSP1TXL_VOL - [7:0] */
-#define WM8996_DSP1TXL_VOL_WIDTH 8 /* DSP1TXL_VOL - [7:0] */
-
-/*
- * R1025 (0x401) - DSP1 TX Right Volume
- */
-#define WM8996_DSP1TX_VU 0x0100 /* DSP1TX_VU */
-#define WM8996_DSP1TX_VU_MASK 0x0100 /* DSP1TX_VU */
-#define WM8996_DSP1TX_VU_SHIFT 8 /* DSP1TX_VU */
-#define WM8996_DSP1TX_VU_WIDTH 1 /* DSP1TX_VU */
-#define WM8996_DSP1TXR_VOL_MASK 0x00FF /* DSP1TXR_VOL - [7:0] */
-#define WM8996_DSP1TXR_VOL_SHIFT 0 /* DSP1TXR_VOL - [7:0] */
-#define WM8996_DSP1TXR_VOL_WIDTH 8 /* DSP1TXR_VOL - [7:0] */
-
-/*
- * R1026 (0x402) - DSP1 RX Left Volume
- */
-#define WM8996_DSP1RX_VU 0x0100 /* DSP1RX_VU */
-#define WM8996_DSP1RX_VU_MASK 0x0100 /* DSP1RX_VU */
-#define WM8996_DSP1RX_VU_SHIFT 8 /* DSP1RX_VU */
-#define WM8996_DSP1RX_VU_WIDTH 1 /* DSP1RX_VU */
-#define WM8996_DSP1RXL_VOL_MASK 0x00FF /* DSP1RXL_VOL - [7:0] */
-#define WM8996_DSP1RXL_VOL_SHIFT 0 /* DSP1RXL_VOL - [7:0] */
-#define WM8996_DSP1RXL_VOL_WIDTH 8 /* DSP1RXL_VOL - [7:0] */
-
-/*
- * R1027 (0x403) - DSP1 RX Right Volume
- */
-#define WM8996_DSP1RX_VU 0x0100 /* DSP1RX_VU */
-#define WM8996_DSP1RX_VU_MASK 0x0100 /* DSP1RX_VU */
-#define WM8996_DSP1RX_VU_SHIFT 8 /* DSP1RX_VU */
-#define WM8996_DSP1RX_VU_WIDTH 1 /* DSP1RX_VU */
-#define WM8996_DSP1RXR_VOL_MASK 0x00FF /* DSP1RXR_VOL - [7:0] */
-#define WM8996_DSP1RXR_VOL_SHIFT 0 /* DSP1RXR_VOL - [7:0] */
-#define WM8996_DSP1RXR_VOL_WIDTH 8 /* DSP1RXR_VOL - [7:0] */
-
-/*
- * R1040 (0x410) - DSP1 TX Filters
- */
-#define WM8996_DSP1TX_NF 0x2000 /* DSP1TX_NF */
-#define WM8996_DSP1TX_NF_MASK 0x2000 /* DSP1TX_NF */
-#define WM8996_DSP1TX_NF_SHIFT 13 /* DSP1TX_NF */
-#define WM8996_DSP1TX_NF_WIDTH 1 /* DSP1TX_NF */
-#define WM8996_DSP1TXL_HPF 0x1000 /* DSP1TXL_HPF */
-#define WM8996_DSP1TXL_HPF_MASK 0x1000 /* DSP1TXL_HPF */
-#define WM8996_DSP1TXL_HPF_SHIFT 12 /* DSP1TXL_HPF */
-#define WM8996_DSP1TXL_HPF_WIDTH 1 /* DSP1TXL_HPF */
-#define WM8996_DSP1TXR_HPF 0x0800 /* DSP1TXR_HPF */
-#define WM8996_DSP1TXR_HPF_MASK 0x0800 /* DSP1TXR_HPF */
-#define WM8996_DSP1TXR_HPF_SHIFT 11 /* DSP1TXR_HPF */
-#define WM8996_DSP1TXR_HPF_WIDTH 1 /* DSP1TXR_HPF */
-#define WM8996_DSP1TX_HPF_MODE_MASK 0x0018 /* DSP1TX_HPF_MODE - [4:3] */
-#define WM8996_DSP1TX_HPF_MODE_SHIFT 3 /* DSP1TX_HPF_MODE - [4:3] */
-#define WM8996_DSP1TX_HPF_MODE_WIDTH 2 /* DSP1TX_HPF_MODE - [4:3] */
-#define WM8996_DSP1TX_HPF_CUT_MASK 0x0007 /* DSP1TX_HPF_CUT - [2:0] */
-#define WM8996_DSP1TX_HPF_CUT_SHIFT 0 /* DSP1TX_HPF_CUT - [2:0] */
-#define WM8996_DSP1TX_HPF_CUT_WIDTH 3 /* DSP1TX_HPF_CUT - [2:0] */
-
-/*
- * R1056 (0x420) - DSP1 RX Filters (1)
- */
-#define WM8996_DSP1RX_MUTE 0x0200 /* DSP1RX_MUTE */
-#define WM8996_DSP1RX_MUTE_MASK 0x0200 /* DSP1RX_MUTE */
-#define WM8996_DSP1RX_MUTE_SHIFT 9 /* DSP1RX_MUTE */
-#define WM8996_DSP1RX_MUTE_WIDTH 1 /* DSP1RX_MUTE */
-#define WM8996_DSP1RX_MONO 0x0080 /* DSP1RX_MONO */
-#define WM8996_DSP1RX_MONO_MASK 0x0080 /* DSP1RX_MONO */
-#define WM8996_DSP1RX_MONO_SHIFT 7 /* DSP1RX_MONO */
-#define WM8996_DSP1RX_MONO_WIDTH 1 /* DSP1RX_MONO */
-#define WM8996_DSP1RX_MUTERATE 0x0020 /* DSP1RX_MUTERATE */
-#define WM8996_DSP1RX_MUTERATE_MASK 0x0020 /* DSP1RX_MUTERATE */
-#define WM8996_DSP1RX_MUTERATE_SHIFT 5 /* DSP1RX_MUTERATE */
-#define WM8996_DSP1RX_MUTERATE_WIDTH 1 /* DSP1RX_MUTERATE */
-#define WM8996_DSP1RX_UNMUTE_RAMP 0x0010 /* DSP1RX_UNMUTE_RAMP */
-#define WM8996_DSP1RX_UNMUTE_RAMP_MASK 0x0010 /* DSP1RX_UNMUTE_RAMP */
-#define WM8996_DSP1RX_UNMUTE_RAMP_SHIFT 4 /* DSP1RX_UNMUTE_RAMP */
-#define WM8996_DSP1RX_UNMUTE_RAMP_WIDTH 1 /* DSP1RX_UNMUTE_RAMP */
-
-/*
- * R1057 (0x421) - DSP1 RX Filters (2)
- */
-#define WM8996_DSP1RX_3D_GAIN_MASK 0x3E00 /* DSP1RX_3D_GAIN - [13:9] */
-#define WM8996_DSP1RX_3D_GAIN_SHIFT 9 /* DSP1RX_3D_GAIN - [13:9] */
-#define WM8996_DSP1RX_3D_GAIN_WIDTH 5 /* DSP1RX_3D_GAIN - [13:9] */
-#define WM8996_DSP1RX_3D_ENA 0x0100 /* DSP1RX_3D_ENA */
-#define WM8996_DSP1RX_3D_ENA_MASK 0x0100 /* DSP1RX_3D_ENA */
-#define WM8996_DSP1RX_3D_ENA_SHIFT 8 /* DSP1RX_3D_ENA */
-#define WM8996_DSP1RX_3D_ENA_WIDTH 1 /* DSP1RX_3D_ENA */
-
-/*
- * R1088 (0x440) - DSP1 DRC (1)
- */
-#define WM8996_DSP1DRC_SIG_DET_RMS_MASK 0xF800 /* DSP1DRC_SIG_DET_RMS - [15:11] */
-#define WM8996_DSP1DRC_SIG_DET_RMS_SHIFT 11 /* DSP1DRC_SIG_DET_RMS - [15:11] */
-#define WM8996_DSP1DRC_SIG_DET_RMS_WIDTH 5 /* DSP1DRC_SIG_DET_RMS - [15:11] */
-#define WM8996_DSP1DRC_SIG_DET_PK_MASK 0x0600 /* DSP1DRC_SIG_DET_PK - [10:9] */
-#define WM8996_DSP1DRC_SIG_DET_PK_SHIFT 9 /* DSP1DRC_SIG_DET_PK - [10:9] */
-#define WM8996_DSP1DRC_SIG_DET_PK_WIDTH 2 /* DSP1DRC_SIG_DET_PK - [10:9] */
-#define WM8996_DSP1DRC_NG_ENA 0x0100 /* DSP1DRC_NG_ENA */
-#define WM8996_DSP1DRC_NG_ENA_MASK 0x0100 /* DSP1DRC_NG_ENA */
-#define WM8996_DSP1DRC_NG_ENA_SHIFT 8 /* DSP1DRC_NG_ENA */
-#define WM8996_DSP1DRC_NG_ENA_WIDTH 1 /* DSP1DRC_NG_ENA */
-#define WM8996_DSP1DRC_SIG_DET_MODE 0x0080 /* DSP1DRC_SIG_DET_MODE */
-#define WM8996_DSP1DRC_SIG_DET_MODE_MASK 0x0080 /* DSP1DRC_SIG_DET_MODE */
-#define WM8996_DSP1DRC_SIG_DET_MODE_SHIFT 7 /* DSP1DRC_SIG_DET_MODE */
-#define WM8996_DSP1DRC_SIG_DET_MODE_WIDTH 1 /* DSP1DRC_SIG_DET_MODE */
-#define WM8996_DSP1DRC_SIG_DET 0x0040 /* DSP1DRC_SIG_DET */
-#define WM8996_DSP1DRC_SIG_DET_MASK 0x0040 /* DSP1DRC_SIG_DET */
-#define WM8996_DSP1DRC_SIG_DET_SHIFT 6 /* DSP1DRC_SIG_DET */
-#define WM8996_DSP1DRC_SIG_DET_WIDTH 1 /* DSP1DRC_SIG_DET */
-#define WM8996_DSP1DRC_KNEE2_OP_ENA 0x0020 /* DSP1DRC_KNEE2_OP_ENA */
-#define WM8996_DSP1DRC_KNEE2_OP_ENA_MASK 0x0020 /* DSP1DRC_KNEE2_OP_ENA */
-#define WM8996_DSP1DRC_KNEE2_OP_ENA_SHIFT 5 /* DSP1DRC_KNEE2_OP_ENA */
-#define WM8996_DSP1DRC_KNEE2_OP_ENA_WIDTH 1 /* DSP1DRC_KNEE2_OP_ENA */
-#define WM8996_DSP1DRC_QR 0x0010 /* DSP1DRC_QR */
-#define WM8996_DSP1DRC_QR_MASK 0x0010 /* DSP1DRC_QR */
-#define WM8996_DSP1DRC_QR_SHIFT 4 /* DSP1DRC_QR */
-#define WM8996_DSP1DRC_QR_WIDTH 1 /* DSP1DRC_QR */
-#define WM8996_DSP1DRC_ANTICLIP 0x0008 /* DSP1DRC_ANTICLIP */
-#define WM8996_DSP1DRC_ANTICLIP_MASK 0x0008 /* DSP1DRC_ANTICLIP */
-#define WM8996_DSP1DRC_ANTICLIP_SHIFT 3 /* DSP1DRC_ANTICLIP */
-#define WM8996_DSP1DRC_ANTICLIP_WIDTH 1 /* DSP1DRC_ANTICLIP */
-#define WM8996_DSP1RX_DRC_ENA 0x0004 /* DSP1RX_DRC_ENA */
-#define WM8996_DSP1RX_DRC_ENA_MASK 0x0004 /* DSP1RX_DRC_ENA */
-#define WM8996_DSP1RX_DRC_ENA_SHIFT 2 /* DSP1RX_DRC_ENA */
-#define WM8996_DSP1RX_DRC_ENA_WIDTH 1 /* DSP1RX_DRC_ENA */
-#define WM8996_DSP1TXL_DRC_ENA 0x0002 /* DSP1TXL_DRC_ENA */
-#define WM8996_DSP1TXL_DRC_ENA_MASK 0x0002 /* DSP1TXL_DRC_ENA */
-#define WM8996_DSP1TXL_DRC_ENA_SHIFT 1 /* DSP1TXL_DRC_ENA */
-#define WM8996_DSP1TXL_DRC_ENA_WIDTH 1 /* DSP1TXL_DRC_ENA */
-#define WM8996_DSP1TXR_DRC_ENA 0x0001 /* DSP1TXR_DRC_ENA */
-#define WM8996_DSP1TXR_DRC_ENA_MASK 0x0001 /* DSP1TXR_DRC_ENA */
-#define WM8996_DSP1TXR_DRC_ENA_SHIFT 0 /* DSP1TXR_DRC_ENA */
-#define WM8996_DSP1TXR_DRC_ENA_WIDTH 1 /* DSP1TXR_DRC_ENA */
-
-/*
- * R1089 (0x441) - DSP1 DRC (2)
- */
-#define WM8996_DSP1DRC_ATK_MASK 0x1E00 /* DSP1DRC_ATK - [12:9] */
-#define WM8996_DSP1DRC_ATK_SHIFT 9 /* DSP1DRC_ATK - [12:9] */
-#define WM8996_DSP1DRC_ATK_WIDTH 4 /* DSP1DRC_ATK - [12:9] */
-#define WM8996_DSP1DRC_DCY_MASK 0x01E0 /* DSP1DRC_DCY - [8:5] */
-#define WM8996_DSP1DRC_DCY_SHIFT 5 /* DSP1DRC_DCY - [8:5] */
-#define WM8996_DSP1DRC_DCY_WIDTH 4 /* DSP1DRC_DCY - [8:5] */
-#define WM8996_DSP1DRC_MINGAIN_MASK 0x001C /* DSP1DRC_MINGAIN - [4:2] */
-#define WM8996_DSP1DRC_MINGAIN_SHIFT 2 /* DSP1DRC_MINGAIN - [4:2] */
-#define WM8996_DSP1DRC_MINGAIN_WIDTH 3 /* DSP1DRC_MINGAIN - [4:2] */
-#define WM8996_DSP1DRC_MAXGAIN_MASK 0x0003 /* DSP1DRC_MAXGAIN - [1:0] */
-#define WM8996_DSP1DRC_MAXGAIN_SHIFT 0 /* DSP1DRC_MAXGAIN - [1:0] */
-#define WM8996_DSP1DRC_MAXGAIN_WIDTH 2 /* DSP1DRC_MAXGAIN - [1:0] */
-
-/*
- * R1090 (0x442) - DSP1 DRC (3)
- */
-#define WM8996_DSP1DRC_NG_MINGAIN_MASK 0xF000 /* DSP1DRC_NG_MINGAIN - [15:12] */
-#define WM8996_DSP1DRC_NG_MINGAIN_SHIFT 12 /* DSP1DRC_NG_MINGAIN - [15:12] */
-#define WM8996_DSP1DRC_NG_MINGAIN_WIDTH 4 /* DSP1DRC_NG_MINGAIN - [15:12] */
-#define WM8996_DSP1DRC_NG_EXP_MASK 0x0C00 /* DSP1DRC_NG_EXP - [11:10] */
-#define WM8996_DSP1DRC_NG_EXP_SHIFT 10 /* DSP1DRC_NG_EXP - [11:10] */
-#define WM8996_DSP1DRC_NG_EXP_WIDTH 2 /* DSP1DRC_NG_EXP - [11:10] */
-#define WM8996_DSP1DRC_QR_THR_MASK 0x0300 /* DSP1DRC_QR_THR - [9:8] */
-#define WM8996_DSP1DRC_QR_THR_SHIFT 8 /* DSP1DRC_QR_THR - [9:8] */
-#define WM8996_DSP1DRC_QR_THR_WIDTH 2 /* DSP1DRC_QR_THR - [9:8] */
-#define WM8996_DSP1DRC_QR_DCY_MASK 0x00C0 /* DSP1DRC_QR_DCY - [7:6] */
-#define WM8996_DSP1DRC_QR_DCY_SHIFT 6 /* DSP1DRC_QR_DCY - [7:6] */
-#define WM8996_DSP1DRC_QR_DCY_WIDTH 2 /* DSP1DRC_QR_DCY - [7:6] */
-#define WM8996_DSP1DRC_HI_COMP_MASK 0x0038 /* DSP1DRC_HI_COMP - [5:3] */
-#define WM8996_DSP1DRC_HI_COMP_SHIFT 3 /* DSP1DRC_HI_COMP - [5:3] */
-#define WM8996_DSP1DRC_HI_COMP_WIDTH 3 /* DSP1DRC_HI_COMP - [5:3] */
-#define WM8996_DSP1DRC_LO_COMP_MASK 0x0007 /* DSP1DRC_LO_COMP - [2:0] */
-#define WM8996_DSP1DRC_LO_COMP_SHIFT 0 /* DSP1DRC_LO_COMP - [2:0] */
-#define WM8996_DSP1DRC_LO_COMP_WIDTH 3 /* DSP1DRC_LO_COMP - [2:0] */
-
-/*
- * R1091 (0x443) - DSP1 DRC (4)
- */
-#define WM8996_DSP1DRC_KNEE_IP_MASK 0x07E0 /* DSP1DRC_KNEE_IP - [10:5] */
-#define WM8996_DSP1DRC_KNEE_IP_SHIFT 5 /* DSP1DRC_KNEE_IP - [10:5] */
-#define WM8996_DSP1DRC_KNEE_IP_WIDTH 6 /* DSP1DRC_KNEE_IP - [10:5] */
-#define WM8996_DSP1DRC_KNEE_OP_MASK 0x001F /* DSP1DRC_KNEE_OP - [4:0] */
-#define WM8996_DSP1DRC_KNEE_OP_SHIFT 0 /* DSP1DRC_KNEE_OP - [4:0] */
-#define WM8996_DSP1DRC_KNEE_OP_WIDTH 5 /* DSP1DRC_KNEE_OP - [4:0] */
-
-/*
- * R1092 (0x444) - DSP1 DRC (5)
- */
-#define WM8996_DSP1DRC_KNEE2_IP_MASK 0x03E0 /* DSP1DRC_KNEE2_IP - [9:5] */
-#define WM8996_DSP1DRC_KNEE2_IP_SHIFT 5 /* DSP1DRC_KNEE2_IP - [9:5] */
-#define WM8996_DSP1DRC_KNEE2_IP_WIDTH 5 /* DSP1DRC_KNEE2_IP - [9:5] */
-#define WM8996_DSP1DRC_KNEE2_OP_MASK 0x001F /* DSP1DRC_KNEE2_OP - [4:0] */
-#define WM8996_DSP1DRC_KNEE2_OP_SHIFT 0 /* DSP1DRC_KNEE2_OP - [4:0] */
-#define WM8996_DSP1DRC_KNEE2_OP_WIDTH 5 /* DSP1DRC_KNEE2_OP - [4:0] */
-
-/*
- * R1152 (0x480) - DSP1 RX EQ Gains (1)
- */
-#define WM8996_DSP1RX_EQ_B1_GAIN_MASK 0xF800 /* DSP1RX_EQ_B1_GAIN - [15:11] */
-#define WM8996_DSP1RX_EQ_B1_GAIN_SHIFT 11 /* DSP1RX_EQ_B1_GAIN - [15:11] */
-#define WM8996_DSP1RX_EQ_B1_GAIN_WIDTH 5 /* DSP1RX_EQ_B1_GAIN - [15:11] */
-#define WM8996_DSP1RX_EQ_B2_GAIN_MASK 0x07C0 /* DSP1RX_EQ_B2_GAIN - [10:6] */
-#define WM8996_DSP1RX_EQ_B2_GAIN_SHIFT 6 /* DSP1RX_EQ_B2_GAIN - [10:6] */
-#define WM8996_DSP1RX_EQ_B2_GAIN_WIDTH 5 /* DSP1RX_EQ_B2_GAIN - [10:6] */
-#define WM8996_DSP1RX_EQ_B3_GAIN_MASK 0x003E /* DSP1RX_EQ_B3_GAIN - [5:1] */
-#define WM8996_DSP1RX_EQ_B3_GAIN_SHIFT 1 /* DSP1RX_EQ_B3_GAIN - [5:1] */
-#define WM8996_DSP1RX_EQ_B3_GAIN_WIDTH 5 /* DSP1RX_EQ_B3_GAIN - [5:1] */
-#define WM8996_DSP1RX_EQ_ENA 0x0001 /* DSP1RX_EQ_ENA */
-#define WM8996_DSP1RX_EQ_ENA_MASK 0x0001 /* DSP1RX_EQ_ENA */
-#define WM8996_DSP1RX_EQ_ENA_SHIFT 0 /* DSP1RX_EQ_ENA */
-#define WM8996_DSP1RX_EQ_ENA_WIDTH 1 /* DSP1RX_EQ_ENA */
-
-/*
- * R1153 (0x481) - DSP1 RX EQ Gains (2)
- */
-#define WM8996_DSP1RX_EQ_B4_GAIN_MASK 0xF800 /* DSP1RX_EQ_B4_GAIN - [15:11] */
-#define WM8996_DSP1RX_EQ_B4_GAIN_SHIFT 11 /* DSP1RX_EQ_B4_GAIN - [15:11] */
-#define WM8996_DSP1RX_EQ_B4_GAIN_WIDTH 5 /* DSP1RX_EQ_B4_GAIN - [15:11] */
-#define WM8996_DSP1RX_EQ_B5_GAIN_MASK 0x07C0 /* DSP1RX_EQ_B5_GAIN - [10:6] */
-#define WM8996_DSP1RX_EQ_B5_GAIN_SHIFT 6 /* DSP1RX_EQ_B5_GAIN - [10:6] */
-#define WM8996_DSP1RX_EQ_B5_GAIN_WIDTH 5 /* DSP1RX_EQ_B5_GAIN - [10:6] */
-
-/*
- * R1154 (0x482) - DSP1 RX EQ Band 1 A
- */
-#define WM8996_DSP1RX_EQ_B1_A_MASK 0xFFFF /* DSP1RX_EQ_B1_A - [15:0] */
-#define WM8996_DSP1RX_EQ_B1_A_SHIFT 0 /* DSP1RX_EQ_B1_A - [15:0] */
-#define WM8996_DSP1RX_EQ_B1_A_WIDTH 16 /* DSP1RX_EQ_B1_A - [15:0] */
-
-/*
- * R1155 (0x483) - DSP1 RX EQ Band 1 B
- */
-#define WM8996_DSP1RX_EQ_B1_B_MASK 0xFFFF /* DSP1RX_EQ_B1_B - [15:0] */
-#define WM8996_DSP1RX_EQ_B1_B_SHIFT 0 /* DSP1RX_EQ_B1_B - [15:0] */
-#define WM8996_DSP1RX_EQ_B1_B_WIDTH 16 /* DSP1RX_EQ_B1_B - [15:0] */
-
-/*
- * R1156 (0x484) - DSP1 RX EQ Band 1 PG
- */
-#define WM8996_DSP1RX_EQ_B1_PG_MASK 0xFFFF /* DSP1RX_EQ_B1_PG - [15:0] */
-#define WM8996_DSP1RX_EQ_B1_PG_SHIFT 0 /* DSP1RX_EQ_B1_PG - [15:0] */
-#define WM8996_DSP1RX_EQ_B1_PG_WIDTH 16 /* DSP1RX_EQ_B1_PG - [15:0] */
-
-/*
- * R1157 (0x485) - DSP1 RX EQ Band 2 A
- */
-#define WM8996_DSP1RX_EQ_B2_A_MASK 0xFFFF /* DSP1RX_EQ_B2_A - [15:0] */
-#define WM8996_DSP1RX_EQ_B2_A_SHIFT 0 /* DSP1RX_EQ_B2_A - [15:0] */
-#define WM8996_DSP1RX_EQ_B2_A_WIDTH 16 /* DSP1RX_EQ_B2_A - [15:0] */
-
-/*
- * R1158 (0x486) - DSP1 RX EQ Band 2 B
- */
-#define WM8996_DSP1RX_EQ_B2_B_MASK 0xFFFF /* DSP1RX_EQ_B2_B - [15:0] */
-#define WM8996_DSP1RX_EQ_B2_B_SHIFT 0 /* DSP1RX_EQ_B2_B - [15:0] */
-#define WM8996_DSP1RX_EQ_B2_B_WIDTH 16 /* DSP1RX_EQ_B2_B - [15:0] */
-
-/*
- * R1159 (0x487) - DSP1 RX EQ Band 2 C
- */
-#define WM8996_DSP1RX_EQ_B2_C_MASK 0xFFFF /* DSP1RX_EQ_B2_C - [15:0] */
-#define WM8996_DSP1RX_EQ_B2_C_SHIFT 0 /* DSP1RX_EQ_B2_C - [15:0] */
-#define WM8996_DSP1RX_EQ_B2_C_WIDTH 16 /* DSP1RX_EQ_B2_C - [15:0] */
-
-/*
- * R1160 (0x488) - DSP1 RX EQ Band 2 PG
- */
-#define WM8996_DSP1RX_EQ_B2_PG_MASK 0xFFFF /* DSP1RX_EQ_B2_PG - [15:0] */
-#define WM8996_DSP1RX_EQ_B2_PG_SHIFT 0 /* DSP1RX_EQ_B2_PG - [15:0] */
-#define WM8996_DSP1RX_EQ_B2_PG_WIDTH 16 /* DSP1RX_EQ_B2_PG - [15:0] */
-
-/*
- * R1161 (0x489) - DSP1 RX EQ Band 3 A
- */
-#define WM8996_DSP1RX_EQ_B3_A_MASK 0xFFFF /* DSP1RX_EQ_B3_A - [15:0] */
-#define WM8996_DSP1RX_EQ_B3_A_SHIFT 0 /* DSP1RX_EQ_B3_A - [15:0] */
-#define WM8996_DSP1RX_EQ_B3_A_WIDTH 16 /* DSP1RX_EQ_B3_A - [15:0] */
-
-/*
- * R1162 (0x48A) - DSP1 RX EQ Band 3 B
- */
-#define WM8996_DSP1RX_EQ_B3_B_MASK 0xFFFF /* DSP1RX_EQ_B3_B - [15:0] */
-#define WM8996_DSP1RX_EQ_B3_B_SHIFT 0 /* DSP1RX_EQ_B3_B - [15:0] */
-#define WM8996_DSP1RX_EQ_B3_B_WIDTH 16 /* DSP1RX_EQ_B3_B - [15:0] */
-
-/*
- * R1163 (0x48B) - DSP1 RX EQ Band 3 C
- */
-#define WM8996_DSP1RX_EQ_B3_C_MASK 0xFFFF /* DSP1RX_EQ_B3_C - [15:0] */
-#define WM8996_DSP1RX_EQ_B3_C_SHIFT 0 /* DSP1RX_EQ_B3_C - [15:0] */
-#define WM8996_DSP1RX_EQ_B3_C_WIDTH 16 /* DSP1RX_EQ_B3_C - [15:0] */
-
-/*
- * R1164 (0x48C) - DSP1 RX EQ Band 3 PG
- */
-#define WM8996_DSP1RX_EQ_B3_PG_MASK 0xFFFF /* DSP1RX_EQ_B3_PG - [15:0] */
-#define WM8996_DSP1RX_EQ_B3_PG_SHIFT 0 /* DSP1RX_EQ_B3_PG - [15:0] */
-#define WM8996_DSP1RX_EQ_B3_PG_WIDTH 16 /* DSP1RX_EQ_B3_PG - [15:0] */
-
-/*
- * R1165 (0x48D) - DSP1 RX EQ Band 4 A
- */
-#define WM8996_DSP1RX_EQ_B4_A_MASK 0xFFFF /* DSP1RX_EQ_B4_A - [15:0] */
-#define WM8996_DSP1RX_EQ_B4_A_SHIFT 0 /* DSP1RX_EQ_B4_A - [15:0] */
-#define WM8996_DSP1RX_EQ_B4_A_WIDTH 16 /* DSP1RX_EQ_B4_A - [15:0] */
-
-/*
- * R1166 (0x48E) - DSP1 RX EQ Band 4 B
- */
-#define WM8996_DSP1RX_EQ_B4_B_MASK 0xFFFF /* DSP1RX_EQ_B4_B - [15:0] */
-#define WM8996_DSP1RX_EQ_B4_B_SHIFT 0 /* DSP1RX_EQ_B4_B - [15:0] */
-#define WM8996_DSP1RX_EQ_B4_B_WIDTH 16 /* DSP1RX_EQ_B4_B - [15:0] */
-
-/*
- * R1167 (0x48F) - DSP1 RX EQ Band 4 C
- */
-#define WM8996_DSP1RX_EQ_B4_C_MASK 0xFFFF /* DSP1RX_EQ_B4_C - [15:0] */
-#define WM8996_DSP1RX_EQ_B4_C_SHIFT 0 /* DSP1RX_EQ_B4_C - [15:0] */
-#define WM8996_DSP1RX_EQ_B4_C_WIDTH 16 /* DSP1RX_EQ_B4_C - [15:0] */
-
-/*
- * R1168 (0x490) - DSP1 RX EQ Band 4 PG
- */
-#define WM8996_DSP1RX_EQ_B4_PG_MASK 0xFFFF /* DSP1RX_EQ_B4_PG - [15:0] */
-#define WM8996_DSP1RX_EQ_B4_PG_SHIFT 0 /* DSP1RX_EQ_B4_PG - [15:0] */
-#define WM8996_DSP1RX_EQ_B4_PG_WIDTH 16 /* DSP1RX_EQ_B4_PG - [15:0] */
-
-/*
- * R1169 (0x491) - DSP1 RX EQ Band 5 A
- */
-#define WM8996_DSP1RX_EQ_B5_A_MASK 0xFFFF /* DSP1RX_EQ_B5_A - [15:0] */
-#define WM8996_DSP1RX_EQ_B5_A_SHIFT 0 /* DSP1RX_EQ_B5_A - [15:0] */
-#define WM8996_DSP1RX_EQ_B5_A_WIDTH 16 /* DSP1RX_EQ_B5_A - [15:0] */
-
-/*
- * R1170 (0x492) - DSP1 RX EQ Band 5 B
- */
-#define WM8996_DSP1RX_EQ_B5_B_MASK 0xFFFF /* DSP1RX_EQ_B5_B - [15:0] */
-#define WM8996_DSP1RX_EQ_B5_B_SHIFT 0 /* DSP1RX_EQ_B5_B - [15:0] */
-#define WM8996_DSP1RX_EQ_B5_B_WIDTH 16 /* DSP1RX_EQ_B5_B - [15:0] */
-
-/*
- * R1171 (0x493) - DSP1 RX EQ Band 5 PG
- */
-#define WM8996_DSP1RX_EQ_B5_PG_MASK 0xFFFF /* DSP1RX_EQ_B5_PG - [15:0] */
-#define WM8996_DSP1RX_EQ_B5_PG_SHIFT 0 /* DSP1RX_EQ_B5_PG - [15:0] */
-#define WM8996_DSP1RX_EQ_B5_PG_WIDTH 16 /* DSP1RX_EQ_B5_PG - [15:0] */
-
-/*
- * R1280 (0x500) - DSP2 TX Left Volume
- */
-#define WM8996_DSP2TX_VU 0x0100 /* DSP2TX_VU */
-#define WM8996_DSP2TX_VU_MASK 0x0100 /* DSP2TX_VU */
-#define WM8996_DSP2TX_VU_SHIFT 8 /* DSP2TX_VU */
-#define WM8996_DSP2TX_VU_WIDTH 1 /* DSP2TX_VU */
-#define WM8996_DSP2TXL_VOL_MASK 0x00FF /* DSP2TXL_VOL - [7:0] */
-#define WM8996_DSP2TXL_VOL_SHIFT 0 /* DSP2TXL_VOL - [7:0] */
-#define WM8996_DSP2TXL_VOL_WIDTH 8 /* DSP2TXL_VOL - [7:0] */
-
-/*
- * R1281 (0x501) - DSP2 TX Right Volume
- */
-#define WM8996_DSP2TX_VU 0x0100 /* DSP2TX_VU */
-#define WM8996_DSP2TX_VU_MASK 0x0100 /* DSP2TX_VU */
-#define WM8996_DSP2TX_VU_SHIFT 8 /* DSP2TX_VU */
-#define WM8996_DSP2TX_VU_WIDTH 1 /* DSP2TX_VU */
-#define WM8996_DSP2TXR_VOL_MASK 0x00FF /* DSP2TXR_VOL - [7:0] */
-#define WM8996_DSP2TXR_VOL_SHIFT 0 /* DSP2TXR_VOL - [7:0] */
-#define WM8996_DSP2TXR_VOL_WIDTH 8 /* DSP2TXR_VOL - [7:0] */
-
-/*
- * R1282 (0x502) - DSP2 RX Left Volume
- */
-#define WM8996_DSP2RX_VU 0x0100 /* DSP2RX_VU */
-#define WM8996_DSP2RX_VU_MASK 0x0100 /* DSP2RX_VU */
-#define WM8996_DSP2RX_VU_SHIFT 8 /* DSP2RX_VU */
-#define WM8996_DSP2RX_VU_WIDTH 1 /* DSP2RX_VU */
-#define WM8996_DSP2RXL_VOL_MASK 0x00FF /* DSP2RXL_VOL - [7:0] */
-#define WM8996_DSP2RXL_VOL_SHIFT 0 /* DSP2RXL_VOL - [7:0] */
-#define WM8996_DSP2RXL_VOL_WIDTH 8 /* DSP2RXL_VOL - [7:0] */
-
-/*
- * R1283 (0x503) - DSP2 RX Right Volume
- */
-#define WM8996_DSP2RX_VU 0x0100 /* DSP2RX_VU */
-#define WM8996_DSP2RX_VU_MASK 0x0100 /* DSP2RX_VU */
-#define WM8996_DSP2RX_VU_SHIFT 8 /* DSP2RX_VU */
-#define WM8996_DSP2RX_VU_WIDTH 1 /* DSP2RX_VU */
-#define WM8996_DSP2RXR_VOL_MASK 0x00FF /* DSP2RXR_VOL - [7:0] */
-#define WM8996_DSP2RXR_VOL_SHIFT 0 /* DSP2RXR_VOL - [7:0] */
-#define WM8996_DSP2RXR_VOL_WIDTH 8 /* DSP2RXR_VOL - [7:0] */
-
-/*
- * R1296 (0x510) - DSP2 TX Filters
- */
-#define WM8996_DSP2TX_NF 0x2000 /* DSP2TX_NF */
-#define WM8996_DSP2TX_NF_MASK 0x2000 /* DSP2TX_NF */
-#define WM8996_DSP2TX_NF_SHIFT 13 /* DSP2TX_NF */
-#define WM8996_DSP2TX_NF_WIDTH 1 /* DSP2TX_NF */
-#define WM8996_DSP2TXL_HPF 0x1000 /* DSP2TXL_HPF */
-#define WM8996_DSP2TXL_HPF_MASK 0x1000 /* DSP2TXL_HPF */
-#define WM8996_DSP2TXL_HPF_SHIFT 12 /* DSP2TXL_HPF */
-#define WM8996_DSP2TXL_HPF_WIDTH 1 /* DSP2TXL_HPF */
-#define WM8996_DSP2TXR_HPF 0x0800 /* DSP2TXR_HPF */
-#define WM8996_DSP2TXR_HPF_MASK 0x0800 /* DSP2TXR_HPF */
-#define WM8996_DSP2TXR_HPF_SHIFT 11 /* DSP2TXR_HPF */
-#define WM8996_DSP2TXR_HPF_WIDTH 1 /* DSP2TXR_HPF */
-#define WM8996_DSP2TX_HPF_MODE_MASK 0x0018 /* DSP2TX_HPF_MODE - [4:3] */
-#define WM8996_DSP2TX_HPF_MODE_SHIFT 3 /* DSP2TX_HPF_MODE - [4:3] */
-#define WM8996_DSP2TX_HPF_MODE_WIDTH 2 /* DSP2TX_HPF_MODE - [4:3] */
-#define WM8996_DSP2TX_HPF_CUT_MASK 0x0007 /* DSP2TX_HPF_CUT - [2:0] */
-#define WM8996_DSP2TX_HPF_CUT_SHIFT 0 /* DSP2TX_HPF_CUT - [2:0] */
-#define WM8996_DSP2TX_HPF_CUT_WIDTH 3 /* DSP2TX_HPF_CUT - [2:0] */
-
-/*
- * R1312 (0x520) - DSP2 RX Filters (1)
- */
-#define WM8996_DSP2RX_MUTE 0x0200 /* DSP2RX_MUTE */
-#define WM8996_DSP2RX_MUTE_MASK 0x0200 /* DSP2RX_MUTE */
-#define WM8996_DSP2RX_MUTE_SHIFT 9 /* DSP2RX_MUTE */
-#define WM8996_DSP2RX_MUTE_WIDTH 1 /* DSP2RX_MUTE */
-#define WM8996_DSP2RX_MONO 0x0080 /* DSP2RX_MONO */
-#define WM8996_DSP2RX_MONO_MASK 0x0080 /* DSP2RX_MONO */
-#define WM8996_DSP2RX_MONO_SHIFT 7 /* DSP2RX_MONO */
-#define WM8996_DSP2RX_MONO_WIDTH 1 /* DSP2RX_MONO */
-#define WM8996_DSP2RX_MUTERATE 0x0020 /* DSP2RX_MUTERATE */
-#define WM8996_DSP2RX_MUTERATE_MASK 0x0020 /* DSP2RX_MUTERATE */
-#define WM8996_DSP2RX_MUTERATE_SHIFT 5 /* DSP2RX_MUTERATE */
-#define WM8996_DSP2RX_MUTERATE_WIDTH 1 /* DSP2RX_MUTERATE */
-#define WM8996_DSP2RX_UNMUTE_RAMP 0x0010 /* DSP2RX_UNMUTE_RAMP */
-#define WM8996_DSP2RX_UNMUTE_RAMP_MASK 0x0010 /* DSP2RX_UNMUTE_RAMP */
-#define WM8996_DSP2RX_UNMUTE_RAMP_SHIFT 4 /* DSP2RX_UNMUTE_RAMP */
-#define WM8996_DSP2RX_UNMUTE_RAMP_WIDTH 1 /* DSP2RX_UNMUTE_RAMP */
-
-/*
- * R1313 (0x521) - DSP2 RX Filters (2)
- */
-#define WM8996_DSP2RX_3D_GAIN_MASK 0x3E00 /* DSP2RX_3D_GAIN - [13:9] */
-#define WM8996_DSP2RX_3D_GAIN_SHIFT 9 /* DSP2RX_3D_GAIN - [13:9] */
-#define WM8996_DSP2RX_3D_GAIN_WIDTH 5 /* DSP2RX_3D_GAIN - [13:9] */
-#define WM8996_DSP2RX_3D_ENA 0x0100 /* DSP2RX_3D_ENA */
-#define WM8996_DSP2RX_3D_ENA_MASK 0x0100 /* DSP2RX_3D_ENA */
-#define WM8996_DSP2RX_3D_ENA_SHIFT 8 /* DSP2RX_3D_ENA */
-#define WM8996_DSP2RX_3D_ENA_WIDTH 1 /* DSP2RX_3D_ENA */
-
-/*
- * R1344 (0x540) - DSP2 DRC (1)
- */
-#define WM8996_DSP2DRC_SIG_DET_RMS_MASK 0xF800 /* DSP2DRC_SIG_DET_RMS - [15:11] */
-#define WM8996_DSP2DRC_SIG_DET_RMS_SHIFT 11 /* DSP2DRC_SIG_DET_RMS - [15:11] */
-#define WM8996_DSP2DRC_SIG_DET_RMS_WIDTH 5 /* DSP2DRC_SIG_DET_RMS - [15:11] */
-#define WM8996_DSP2DRC_SIG_DET_PK_MASK 0x0600 /* DSP2DRC_SIG_DET_PK - [10:9] */
-#define WM8996_DSP2DRC_SIG_DET_PK_SHIFT 9 /* DSP2DRC_SIG_DET_PK - [10:9] */
-#define WM8996_DSP2DRC_SIG_DET_PK_WIDTH 2 /* DSP2DRC_SIG_DET_PK - [10:9] */
-#define WM8996_DSP2DRC_NG_ENA 0x0100 /* DSP2DRC_NG_ENA */
-#define WM8996_DSP2DRC_NG_ENA_MASK 0x0100 /* DSP2DRC_NG_ENA */
-#define WM8996_DSP2DRC_NG_ENA_SHIFT 8 /* DSP2DRC_NG_ENA */
-#define WM8996_DSP2DRC_NG_ENA_WIDTH 1 /* DSP2DRC_NG_ENA */
-#define WM8996_DSP2DRC_SIG_DET_MODE 0x0080 /* DSP2DRC_SIG_DET_MODE */
-#define WM8996_DSP2DRC_SIG_DET_MODE_MASK 0x0080 /* DSP2DRC_SIG_DET_MODE */
-#define WM8996_DSP2DRC_SIG_DET_MODE_SHIFT 7 /* DSP2DRC_SIG_DET_MODE */
-#define WM8996_DSP2DRC_SIG_DET_MODE_WIDTH 1 /* DSP2DRC_SIG_DET_MODE */
-#define WM8996_DSP2DRC_SIG_DET 0x0040 /* DSP2DRC_SIG_DET */
-#define WM8996_DSP2DRC_SIG_DET_MASK 0x0040 /* DSP2DRC_SIG_DET */
-#define WM8996_DSP2DRC_SIG_DET_SHIFT 6 /* DSP2DRC_SIG_DET */
-#define WM8996_DSP2DRC_SIG_DET_WIDTH 1 /* DSP2DRC_SIG_DET */
-#define WM8996_DSP2DRC_KNEE2_OP_ENA 0x0020 /* DSP2DRC_KNEE2_OP_ENA */
-#define WM8996_DSP2DRC_KNEE2_OP_ENA_MASK 0x0020 /* DSP2DRC_KNEE2_OP_ENA */
-#define WM8996_DSP2DRC_KNEE2_OP_ENA_SHIFT 5 /* DSP2DRC_KNEE2_OP_ENA */
-#define WM8996_DSP2DRC_KNEE2_OP_ENA_WIDTH 1 /* DSP2DRC_KNEE2_OP_ENA */
-#define WM8996_DSP2DRC_QR 0x0010 /* DSP2DRC_QR */
-#define WM8996_DSP2DRC_QR_MASK 0x0010 /* DSP2DRC_QR */
-#define WM8996_DSP2DRC_QR_SHIFT 4 /* DSP2DRC_QR */
-#define WM8996_DSP2DRC_QR_WIDTH 1 /* DSP2DRC_QR */
-#define WM8996_DSP2DRC_ANTICLIP 0x0008 /* DSP2DRC_ANTICLIP */
-#define WM8996_DSP2DRC_ANTICLIP_MASK 0x0008 /* DSP2DRC_ANTICLIP */
-#define WM8996_DSP2DRC_ANTICLIP_SHIFT 3 /* DSP2DRC_ANTICLIP */
-#define WM8996_DSP2DRC_ANTICLIP_WIDTH 1 /* DSP2DRC_ANTICLIP */
-#define WM8996_DSP2RX_DRC_ENA 0x0004 /* DSP2RX_DRC_ENA */
-#define WM8996_DSP2RX_DRC_ENA_MASK 0x0004 /* DSP2RX_DRC_ENA */
-#define WM8996_DSP2RX_DRC_ENA_SHIFT 2 /* DSP2RX_DRC_ENA */
-#define WM8996_DSP2RX_DRC_ENA_WIDTH 1 /* DSP2RX_DRC_ENA */
-#define WM8996_DSP2TXL_DRC_ENA 0x0002 /* DSP2TXL_DRC_ENA */
-#define WM8996_DSP2TXL_DRC_ENA_MASK 0x0002 /* DSP2TXL_DRC_ENA */
-#define WM8996_DSP2TXL_DRC_ENA_SHIFT 1 /* DSP2TXL_DRC_ENA */
-#define WM8996_DSP2TXL_DRC_ENA_WIDTH 1 /* DSP2TXL_DRC_ENA */
-#define WM8996_DSP2TXR_DRC_ENA 0x0001 /* DSP2TXR_DRC_ENA */
-#define WM8996_DSP2TXR_DRC_ENA_MASK 0x0001 /* DSP2TXR_DRC_ENA */
-#define WM8996_DSP2TXR_DRC_ENA_SHIFT 0 /* DSP2TXR_DRC_ENA */
-#define WM8996_DSP2TXR_DRC_ENA_WIDTH 1 /* DSP2TXR_DRC_ENA */
-
-/*
- * R1345 (0x541) - DSP2 DRC (2)
- */
-#define WM8996_DSP2DRC_ATK_MASK 0x1E00 /* DSP2DRC_ATK - [12:9] */
-#define WM8996_DSP2DRC_ATK_SHIFT 9 /* DSP2DRC_ATK - [12:9] */
-#define WM8996_DSP2DRC_ATK_WIDTH 4 /* DSP2DRC_ATK - [12:9] */
-#define WM8996_DSP2DRC_DCY_MASK 0x01E0 /* DSP2DRC_DCY - [8:5] */
-#define WM8996_DSP2DRC_DCY_SHIFT 5 /* DSP2DRC_DCY - [8:5] */
-#define WM8996_DSP2DRC_DCY_WIDTH 4 /* DSP2DRC_DCY - [8:5] */
-#define WM8996_DSP2DRC_MINGAIN_MASK 0x001C /* DSP2DRC_MINGAIN - [4:2] */
-#define WM8996_DSP2DRC_MINGAIN_SHIFT 2 /* DSP2DRC_MINGAIN - [4:2] */
-#define WM8996_DSP2DRC_MINGAIN_WIDTH 3 /* DSP2DRC_MINGAIN - [4:2] */
-#define WM8996_DSP2DRC_MAXGAIN_MASK 0x0003 /* DSP2DRC_MAXGAIN - [1:0] */
-#define WM8996_DSP2DRC_MAXGAIN_SHIFT 0 /* DSP2DRC_MAXGAIN - [1:0] */
-#define WM8996_DSP2DRC_MAXGAIN_WIDTH 2 /* DSP2DRC_MAXGAIN - [1:0] */
-
-/*
- * R1346 (0x542) - DSP2 DRC (3)
- */
-#define WM8996_DSP2DRC_NG_MINGAIN_MASK 0xF000 /* DSP2DRC_NG_MINGAIN - [15:12] */
-#define WM8996_DSP2DRC_NG_MINGAIN_SHIFT 12 /* DSP2DRC_NG_MINGAIN - [15:12] */
-#define WM8996_DSP2DRC_NG_MINGAIN_WIDTH 4 /* DSP2DRC_NG_MINGAIN - [15:12] */
-#define WM8996_DSP2DRC_NG_EXP_MASK 0x0C00 /* DSP2DRC_NG_EXP - [11:10] */
-#define WM8996_DSP2DRC_NG_EXP_SHIFT 10 /* DSP2DRC_NG_EXP - [11:10] */
-#define WM8996_DSP2DRC_NG_EXP_WIDTH 2 /* DSP2DRC_NG_EXP - [11:10] */
-#define WM8996_DSP2DRC_QR_THR_MASK 0x0300 /* DSP2DRC_QR_THR - [9:8] */
-#define WM8996_DSP2DRC_QR_THR_SHIFT 8 /* DSP2DRC_QR_THR - [9:8] */
-#define WM8996_DSP2DRC_QR_THR_WIDTH 2 /* DSP2DRC_QR_THR - [9:8] */
-#define WM8996_DSP2DRC_QR_DCY_MASK 0x00C0 /* DSP2DRC_QR_DCY - [7:6] */
-#define WM8996_DSP2DRC_QR_DCY_SHIFT 6 /* DSP2DRC_QR_DCY - [7:6] */
-#define WM8996_DSP2DRC_QR_DCY_WIDTH 2 /* DSP2DRC_QR_DCY - [7:6] */
-#define WM8996_DSP2DRC_HI_COMP_MASK 0x0038 /* DSP2DRC_HI_COMP - [5:3] */
-#define WM8996_DSP2DRC_HI_COMP_SHIFT 3 /* DSP2DRC_HI_COMP - [5:3] */
-#define WM8996_DSP2DRC_HI_COMP_WIDTH 3 /* DSP2DRC_HI_COMP - [5:3] */
-#define WM8996_DSP2DRC_LO_COMP_MASK 0x0007 /* DSP2DRC_LO_COMP - [2:0] */
-#define WM8996_DSP2DRC_LO_COMP_SHIFT 0 /* DSP2DRC_LO_COMP - [2:0] */
-#define WM8996_DSP2DRC_LO_COMP_WIDTH 3 /* DSP2DRC_LO_COMP - [2:0] */
-
-/*
- * R1347 (0x543) - DSP2 DRC (4)
- */
-#define WM8996_DSP2DRC_KNEE_IP_MASK 0x07E0 /* DSP2DRC_KNEE_IP - [10:5] */
-#define WM8996_DSP2DRC_KNEE_IP_SHIFT 5 /* DSP2DRC_KNEE_IP - [10:5] */
-#define WM8996_DSP2DRC_KNEE_IP_WIDTH 6 /* DSP2DRC_KNEE_IP - [10:5] */
-#define WM8996_DSP2DRC_KNEE_OP_MASK 0x001F /* DSP2DRC_KNEE_OP - [4:0] */
-#define WM8996_DSP2DRC_KNEE_OP_SHIFT 0 /* DSP2DRC_KNEE_OP - [4:0] */
-#define WM8996_DSP2DRC_KNEE_OP_WIDTH 5 /* DSP2DRC_KNEE_OP - [4:0] */
-
-/*
- * R1348 (0x544) - DSP2 DRC (5)
- */
-#define WM8996_DSP2DRC_KNEE2_IP_MASK 0x03E0 /* DSP2DRC_KNEE2_IP - [9:5] */
-#define WM8996_DSP2DRC_KNEE2_IP_SHIFT 5 /* DSP2DRC_KNEE2_IP - [9:5] */
-#define WM8996_DSP2DRC_KNEE2_IP_WIDTH 5 /* DSP2DRC_KNEE2_IP - [9:5] */
-#define WM8996_DSP2DRC_KNEE2_OP_MASK 0x001F /* DSP2DRC_KNEE2_OP - [4:0] */
-#define WM8996_DSP2DRC_KNEE2_OP_SHIFT 0 /* DSP2DRC_KNEE2_OP - [4:0] */
-#define WM8996_DSP2DRC_KNEE2_OP_WIDTH 5 /* DSP2DRC_KNEE2_OP - [4:0] */
-
-/*
- * R1408 (0x580) - DSP2 RX EQ Gains (1)
- */
-#define WM8996_DSP2RX_EQ_B1_GAIN_MASK 0xF800 /* DSP2RX_EQ_B1_GAIN - [15:11] */
-#define WM8996_DSP2RX_EQ_B1_GAIN_SHIFT 11 /* DSP2RX_EQ_B1_GAIN - [15:11] */
-#define WM8996_DSP2RX_EQ_B1_GAIN_WIDTH 5 /* DSP2RX_EQ_B1_GAIN - [15:11] */
-#define WM8996_DSP2RX_EQ_B2_GAIN_MASK 0x07C0 /* DSP2RX_EQ_B2_GAIN - [10:6] */
-#define WM8996_DSP2RX_EQ_B2_GAIN_SHIFT 6 /* DSP2RX_EQ_B2_GAIN - [10:6] */
-#define WM8996_DSP2RX_EQ_B2_GAIN_WIDTH 5 /* DSP2RX_EQ_B2_GAIN - [10:6] */
-#define WM8996_DSP2RX_EQ_B3_GAIN_MASK 0x003E /* DSP2RX_EQ_B3_GAIN - [5:1] */
-#define WM8996_DSP2RX_EQ_B3_GAIN_SHIFT 1 /* DSP2RX_EQ_B3_GAIN - [5:1] */
-#define WM8996_DSP2RX_EQ_B3_GAIN_WIDTH 5 /* DSP2RX_EQ_B3_GAIN - [5:1] */
-#define WM8996_DSP2RX_EQ_ENA 0x0001 /* DSP2RX_EQ_ENA */
-#define WM8996_DSP2RX_EQ_ENA_MASK 0x0001 /* DSP2RX_EQ_ENA */
-#define WM8996_DSP2RX_EQ_ENA_SHIFT 0 /* DSP2RX_EQ_ENA */
-#define WM8996_DSP2RX_EQ_ENA_WIDTH 1 /* DSP2RX_EQ_ENA */
-
-/*
- * R1409 (0x581) - DSP2 RX EQ Gains (2)
- */
-#define WM8996_DSP2RX_EQ_B4_GAIN_MASK 0xF800 /* DSP2RX_EQ_B4_GAIN - [15:11] */
-#define WM8996_DSP2RX_EQ_B4_GAIN_SHIFT 11 /* DSP2RX_EQ_B4_GAIN - [15:11] */
-#define WM8996_DSP2RX_EQ_B4_GAIN_WIDTH 5 /* DSP2RX_EQ_B4_GAIN - [15:11] */
-#define WM8996_DSP2RX_EQ_B5_GAIN_MASK 0x07C0 /* DSP2RX_EQ_B5_GAIN - [10:6] */
-#define WM8996_DSP2RX_EQ_B5_GAIN_SHIFT 6 /* DSP2RX_EQ_B5_GAIN - [10:6] */
-#define WM8996_DSP2RX_EQ_B5_GAIN_WIDTH 5 /* DSP2RX_EQ_B5_GAIN - [10:6] */
-
-/*
- * R1410 (0x582) - DSP2 RX EQ Band 1 A
- */
-#define WM8996_DSP2RX_EQ_B1_A_MASK 0xFFFF /* DSP2RX_EQ_B1_A - [15:0] */
-#define WM8996_DSP2RX_EQ_B1_A_SHIFT 0 /* DSP2RX_EQ_B1_A - [15:0] */
-#define WM8996_DSP2RX_EQ_B1_A_WIDTH 16 /* DSP2RX_EQ_B1_A - [15:0] */
-
-/*
- * R1411 (0x583) - DSP2 RX EQ Band 1 B
- */
-#define WM8996_DSP2RX_EQ_B1_B_MASK 0xFFFF /* DSP2RX_EQ_B1_B - [15:0] */
-#define WM8996_DSP2RX_EQ_B1_B_SHIFT 0 /* DSP2RX_EQ_B1_B - [15:0] */
-#define WM8996_DSP2RX_EQ_B1_B_WIDTH 16 /* DSP2RX_EQ_B1_B - [15:0] */
-
-/*
- * R1412 (0x584) - DSP2 RX EQ Band 1 PG
- */
-#define WM8996_DSP2RX_EQ_B1_PG_MASK 0xFFFF /* DSP2RX_EQ_B1_PG - [15:0] */
-#define WM8996_DSP2RX_EQ_B1_PG_SHIFT 0 /* DSP2RX_EQ_B1_PG - [15:0] */
-#define WM8996_DSP2RX_EQ_B1_PG_WIDTH 16 /* DSP2RX_EQ_B1_PG - [15:0] */
-
-/*
- * R1413 (0x585) - DSP2 RX EQ Band 2 A
- */
-#define WM8996_DSP2RX_EQ_B2_A_MASK 0xFFFF /* DSP2RX_EQ_B2_A - [15:0] */
-#define WM8996_DSP2RX_EQ_B2_A_SHIFT 0 /* DSP2RX_EQ_B2_A - [15:0] */
-#define WM8996_DSP2RX_EQ_B2_A_WIDTH 16 /* DSP2RX_EQ_B2_A - [15:0] */
-
-/*
- * R1414 (0x586) - DSP2 RX EQ Band 2 B
- */
-#define WM8996_DSP2RX_EQ_B2_B_MASK 0xFFFF /* DSP2RX_EQ_B2_B - [15:0] */
-#define WM8996_DSP2RX_EQ_B2_B_SHIFT 0 /* DSP2RX_EQ_B2_B - [15:0] */
-#define WM8996_DSP2RX_EQ_B2_B_WIDTH 16 /* DSP2RX_EQ_B2_B - [15:0] */
-
-/*
- * R1415 (0x587) - DSP2 RX EQ Band 2 C
- */
-#define WM8996_DSP2RX_EQ_B2_C_MASK 0xFFFF /* DSP2RX_EQ_B2_C - [15:0] */
-#define WM8996_DSP2RX_EQ_B2_C_SHIFT 0 /* DSP2RX_EQ_B2_C - [15:0] */
-#define WM8996_DSP2RX_EQ_B2_C_WIDTH 16 /* DSP2RX_EQ_B2_C - [15:0] */
-
-/*
- * R1416 (0x588) - DSP2 RX EQ Band 2 PG
- */
-#define WM8996_DSP2RX_EQ_B2_PG_MASK 0xFFFF /* DSP2RX_EQ_B2_PG - [15:0] */
-#define WM8996_DSP2RX_EQ_B2_PG_SHIFT 0 /* DSP2RX_EQ_B2_PG - [15:0] */
-#define WM8996_DSP2RX_EQ_B2_PG_WIDTH 16 /* DSP2RX_EQ_B2_PG - [15:0] */
-
-/*
- * R1417 (0x589) - DSP2 RX EQ Band 3 A
- */
-#define WM8996_DSP2RX_EQ_B3_A_MASK 0xFFFF /* DSP2RX_EQ_B3_A - [15:0] */
-#define WM8996_DSP2RX_EQ_B3_A_SHIFT 0 /* DSP2RX_EQ_B3_A - [15:0] */
-#define WM8996_DSP2RX_EQ_B3_A_WIDTH 16 /* DSP2RX_EQ_B3_A - [15:0] */
-
-/*
- * R1418 (0x58A) - DSP2 RX EQ Band 3 B
- */
-#define WM8996_DSP2RX_EQ_B3_B_MASK 0xFFFF /* DSP2RX_EQ_B3_B - [15:0] */
-#define WM8996_DSP2RX_EQ_B3_B_SHIFT 0 /* DSP2RX_EQ_B3_B - [15:0] */
-#define WM8996_DSP2RX_EQ_B3_B_WIDTH 16 /* DSP2RX_EQ_B3_B - [15:0] */
-
-/*
- * R1419 (0x58B) - DSP2 RX EQ Band 3 C
- */
-#define WM8996_DSP2RX_EQ_B3_C_MASK 0xFFFF /* DSP2RX_EQ_B3_C - [15:0] */
-#define WM8996_DSP2RX_EQ_B3_C_SHIFT 0 /* DSP2RX_EQ_B3_C - [15:0] */
-#define WM8996_DSP2RX_EQ_B3_C_WIDTH 16 /* DSP2RX_EQ_B3_C - [15:0] */
-
-/*
- * R1420 (0x58C) - DSP2 RX EQ Band 3 PG
- */
-#define WM8996_DSP2RX_EQ_B3_PG_MASK 0xFFFF /* DSP2RX_EQ_B3_PG - [15:0] */
-#define WM8996_DSP2RX_EQ_B3_PG_SHIFT 0 /* DSP2RX_EQ_B3_PG - [15:0] */
-#define WM8996_DSP2RX_EQ_B3_PG_WIDTH 16 /* DSP2RX_EQ_B3_PG - [15:0] */
-
-/*
- * R1421 (0x58D) - DSP2 RX EQ Band 4 A
- */
-#define WM8996_DSP2RX_EQ_B4_A_MASK 0xFFFF /* DSP2RX_EQ_B4_A - [15:0] */
-#define WM8996_DSP2RX_EQ_B4_A_SHIFT 0 /* DSP2RX_EQ_B4_A - [15:0] */
-#define WM8996_DSP2RX_EQ_B4_A_WIDTH 16 /* DSP2RX_EQ_B4_A - [15:0] */
-
-/*
- * R1422 (0x58E) - DSP2 RX EQ Band 4 B
- */
-#define WM8996_DSP2RX_EQ_B4_B_MASK 0xFFFF /* DSP2RX_EQ_B4_B - [15:0] */
-#define WM8996_DSP2RX_EQ_B4_B_SHIFT 0 /* DSP2RX_EQ_B4_B - [15:0] */
-#define WM8996_DSP2RX_EQ_B4_B_WIDTH 16 /* DSP2RX_EQ_B4_B - [15:0] */
-
-/*
- * R1423 (0x58F) - DSP2 RX EQ Band 4 C
- */
-#define WM8996_DSP2RX_EQ_B4_C_MASK 0xFFFF /* DSP2RX_EQ_B4_C - [15:0] */
-#define WM8996_DSP2RX_EQ_B4_C_SHIFT 0 /* DSP2RX_EQ_B4_C - [15:0] */
-#define WM8996_DSP2RX_EQ_B4_C_WIDTH 16 /* DSP2RX_EQ_B4_C - [15:0] */
-
-/*
- * R1424 (0x590) - DSP2 RX EQ Band 4 PG
- */
-#define WM8996_DSP2RX_EQ_B4_PG_MASK 0xFFFF /* DSP2RX_EQ_B4_PG - [15:0] */
-#define WM8996_DSP2RX_EQ_B4_PG_SHIFT 0 /* DSP2RX_EQ_B4_PG - [15:0] */
-#define WM8996_DSP2RX_EQ_B4_PG_WIDTH 16 /* DSP2RX_EQ_B4_PG - [15:0] */
-
-/*
- * R1425 (0x591) - DSP2 RX EQ Band 5 A
- */
-#define WM8996_DSP2RX_EQ_B5_A_MASK 0xFFFF /* DSP2RX_EQ_B5_A - [15:0] */
-#define WM8996_DSP2RX_EQ_B5_A_SHIFT 0 /* DSP2RX_EQ_B5_A - [15:0] */
-#define WM8996_DSP2RX_EQ_B5_A_WIDTH 16 /* DSP2RX_EQ_B5_A - [15:0] */
-
-/*
- * R1426 (0x592) - DSP2 RX EQ Band 5 B
- */
-#define WM8996_DSP2RX_EQ_B5_B_MASK 0xFFFF /* DSP2RX_EQ_B5_B - [15:0] */
-#define WM8996_DSP2RX_EQ_B5_B_SHIFT 0 /* DSP2RX_EQ_B5_B - [15:0] */
-#define WM8996_DSP2RX_EQ_B5_B_WIDTH 16 /* DSP2RX_EQ_B5_B - [15:0] */
-
-/*
- * R1427 (0x593) - DSP2 RX EQ Band 5 PG
- */
-#define WM8996_DSP2RX_EQ_B5_PG_MASK 0xFFFF /* DSP2RX_EQ_B5_PG - [15:0] */
-#define WM8996_DSP2RX_EQ_B5_PG_SHIFT 0 /* DSP2RX_EQ_B5_PG - [15:0] */
-#define WM8996_DSP2RX_EQ_B5_PG_WIDTH 16 /* DSP2RX_EQ_B5_PG - [15:0] */
-
-/*
- * R1536 (0x600) - DAC1 Mixer Volumes
- */
-#define WM8996_ADCR_DAC1_VOL_MASK 0x03E0 /* ADCR_DAC1_VOL - [9:5] */
-#define WM8996_ADCR_DAC1_VOL_SHIFT 5 /* ADCR_DAC1_VOL - [9:5] */
-#define WM8996_ADCR_DAC1_VOL_WIDTH 5 /* ADCR_DAC1_VOL - [9:5] */
-#define WM8996_ADCL_DAC1_VOL_MASK 0x001F /* ADCL_DAC1_VOL - [4:0] */
-#define WM8996_ADCL_DAC1_VOL_SHIFT 0 /* ADCL_DAC1_VOL - [4:0] */
-#define WM8996_ADCL_DAC1_VOL_WIDTH 5 /* ADCL_DAC1_VOL - [4:0] */
-
-/*
- * R1537 (0x601) - DAC1 Left Mixer Routing
- */
-#define WM8996_ADCR_TO_DAC1L 0x0020 /* ADCR_TO_DAC1L */
-#define WM8996_ADCR_TO_DAC1L_MASK 0x0020 /* ADCR_TO_DAC1L */
-#define WM8996_ADCR_TO_DAC1L_SHIFT 5 /* ADCR_TO_DAC1L */
-#define WM8996_ADCR_TO_DAC1L_WIDTH 1 /* ADCR_TO_DAC1L */
-#define WM8996_ADCL_TO_DAC1L 0x0010 /* ADCL_TO_DAC1L */
-#define WM8996_ADCL_TO_DAC1L_MASK 0x0010 /* ADCL_TO_DAC1L */
-#define WM8996_ADCL_TO_DAC1L_SHIFT 4 /* ADCL_TO_DAC1L */
-#define WM8996_ADCL_TO_DAC1L_WIDTH 1 /* ADCL_TO_DAC1L */
-#define WM8996_DSP2RXL_TO_DAC1L 0x0002 /* DSP2RXL_TO_DAC1L */
-#define WM8996_DSP2RXL_TO_DAC1L_MASK 0x0002 /* DSP2RXL_TO_DAC1L */
-#define WM8996_DSP2RXL_TO_DAC1L_SHIFT 1 /* DSP2RXL_TO_DAC1L */
-#define WM8996_DSP2RXL_TO_DAC1L_WIDTH 1 /* DSP2RXL_TO_DAC1L */
-#define WM8996_DSP1RXL_TO_DAC1L 0x0001 /* DSP1RXL_TO_DAC1L */
-#define WM8996_DSP1RXL_TO_DAC1L_MASK 0x0001 /* DSP1RXL_TO_DAC1L */
-#define WM8996_DSP1RXL_TO_DAC1L_SHIFT 0 /* DSP1RXL_TO_DAC1L */
-#define WM8996_DSP1RXL_TO_DAC1L_WIDTH 1 /* DSP1RXL_TO_DAC1L */
-
-/*
- * R1538 (0x602) - DAC1 Right Mixer Routing
- */
-#define WM8996_ADCR_TO_DAC1R 0x0020 /* ADCR_TO_DAC1R */
-#define WM8996_ADCR_TO_DAC1R_MASK 0x0020 /* ADCR_TO_DAC1R */
-#define WM8996_ADCR_TO_DAC1R_SHIFT 5 /* ADCR_TO_DAC1R */
-#define WM8996_ADCR_TO_DAC1R_WIDTH 1 /* ADCR_TO_DAC1R */
-#define WM8996_ADCL_TO_DAC1R 0x0010 /* ADCL_TO_DAC1R */
-#define WM8996_ADCL_TO_DAC1R_MASK 0x0010 /* ADCL_TO_DAC1R */
-#define WM8996_ADCL_TO_DAC1R_SHIFT 4 /* ADCL_TO_DAC1R */
-#define WM8996_ADCL_TO_DAC1R_WIDTH 1 /* ADCL_TO_DAC1R */
-#define WM8996_DSP2RXR_TO_DAC1R 0x0002 /* DSP2RXR_TO_DAC1R */
-#define WM8996_DSP2RXR_TO_DAC1R_MASK 0x0002 /* DSP2RXR_TO_DAC1R */
-#define WM8996_DSP2RXR_TO_DAC1R_SHIFT 1 /* DSP2RXR_TO_DAC1R */
-#define WM8996_DSP2RXR_TO_DAC1R_WIDTH 1 /* DSP2RXR_TO_DAC1R */
-#define WM8996_DSP1RXR_TO_DAC1R 0x0001 /* DSP1RXR_TO_DAC1R */
-#define WM8996_DSP1RXR_TO_DAC1R_MASK 0x0001 /* DSP1RXR_TO_DAC1R */
-#define WM8996_DSP1RXR_TO_DAC1R_SHIFT 0 /* DSP1RXR_TO_DAC1R */
-#define WM8996_DSP1RXR_TO_DAC1R_WIDTH 1 /* DSP1RXR_TO_DAC1R */
-
-/*
- * R1539 (0x603) - DAC2 Mixer Volumes
- */
-#define WM8996_ADCR_DAC2_VOL_MASK 0x03E0 /* ADCR_DAC2_VOL - [9:5] */
-#define WM8996_ADCR_DAC2_VOL_SHIFT 5 /* ADCR_DAC2_VOL - [9:5] */
-#define WM8996_ADCR_DAC2_VOL_WIDTH 5 /* ADCR_DAC2_VOL - [9:5] */
-#define WM8996_ADCL_DAC2_VOL_MASK 0x001F /* ADCL_DAC2_VOL - [4:0] */
-#define WM8996_ADCL_DAC2_VOL_SHIFT 0 /* ADCL_DAC2_VOL - [4:0] */
-#define WM8996_ADCL_DAC2_VOL_WIDTH 5 /* ADCL_DAC2_VOL - [4:0] */
-
-/*
- * R1540 (0x604) - DAC2 Left Mixer Routing
- */
-#define WM8996_ADCR_TO_DAC2L 0x0020 /* ADCR_TO_DAC2L */
-#define WM8996_ADCR_TO_DAC2L_MASK 0x0020 /* ADCR_TO_DAC2L */
-#define WM8996_ADCR_TO_DAC2L_SHIFT 5 /* ADCR_TO_DAC2L */
-#define WM8996_ADCR_TO_DAC2L_WIDTH 1 /* ADCR_TO_DAC2L */
-#define WM8996_ADCL_TO_DAC2L 0x0010 /* ADCL_TO_DAC2L */
-#define WM8996_ADCL_TO_DAC2L_MASK 0x0010 /* ADCL_TO_DAC2L */
-#define WM8996_ADCL_TO_DAC2L_SHIFT 4 /* ADCL_TO_DAC2L */
-#define WM8996_ADCL_TO_DAC2L_WIDTH 1 /* ADCL_TO_DAC2L */
-#define WM8996_DSP2RXL_TO_DAC2L 0x0002 /* DSP2RXL_TO_DAC2L */
-#define WM8996_DSP2RXL_TO_DAC2L_MASK 0x0002 /* DSP2RXL_TO_DAC2L */
-#define WM8996_DSP2RXL_TO_DAC2L_SHIFT 1 /* DSP2RXL_TO_DAC2L */
-#define WM8996_DSP2RXL_TO_DAC2L_WIDTH 1 /* DSP2RXL_TO_DAC2L */
-#define WM8996_DSP1RXL_TO_DAC2L 0x0001 /* DSP1RXL_TO_DAC2L */
-#define WM8996_DSP1RXL_TO_DAC2L_MASK 0x0001 /* DSP1RXL_TO_DAC2L */
-#define WM8996_DSP1RXL_TO_DAC2L_SHIFT 0 /* DSP1RXL_TO_DAC2L */
-#define WM8996_DSP1RXL_TO_DAC2L_WIDTH 1 /* DSP1RXL_TO_DAC2L */
-
-/*
- * R1541 (0x605) - DAC2 Right Mixer Routing
- */
-#define WM8996_ADCR_TO_DAC2R 0x0020 /* ADCR_TO_DAC2R */
-#define WM8996_ADCR_TO_DAC2R_MASK 0x0020 /* ADCR_TO_DAC2R */
-#define WM8996_ADCR_TO_DAC2R_SHIFT 5 /* ADCR_TO_DAC2R */
-#define WM8996_ADCR_TO_DAC2R_WIDTH 1 /* ADCR_TO_DAC2R */
-#define WM8996_ADCL_TO_DAC2R 0x0010 /* ADCL_TO_DAC2R */
-#define WM8996_ADCL_TO_DAC2R_MASK 0x0010 /* ADCL_TO_DAC2R */
-#define WM8996_ADCL_TO_DAC2R_SHIFT 4 /* ADCL_TO_DAC2R */
-#define WM8996_ADCL_TO_DAC2R_WIDTH 1 /* ADCL_TO_DAC2R */
-#define WM8996_DSP2RXR_TO_DAC2R 0x0002 /* DSP2RXR_TO_DAC2R */
-#define WM8996_DSP2RXR_TO_DAC2R_MASK 0x0002 /* DSP2RXR_TO_DAC2R */
-#define WM8996_DSP2RXR_TO_DAC2R_SHIFT 1 /* DSP2RXR_TO_DAC2R */
-#define WM8996_DSP2RXR_TO_DAC2R_WIDTH 1 /* DSP2RXR_TO_DAC2R */
-#define WM8996_DSP1RXR_TO_DAC2R 0x0001 /* DSP1RXR_TO_DAC2R */
-#define WM8996_DSP1RXR_TO_DAC2R_MASK 0x0001 /* DSP1RXR_TO_DAC2R */
-#define WM8996_DSP1RXR_TO_DAC2R_SHIFT 0 /* DSP1RXR_TO_DAC2R */
-#define WM8996_DSP1RXR_TO_DAC2R_WIDTH 1 /* DSP1RXR_TO_DAC2R */
-
-/*
- * R1542 (0x606) - DSP1 TX Left Mixer Routing
- */
-#define WM8996_ADC1L_TO_DSP1TXL 0x0002 /* ADC1L_TO_DSP1TXL */
-#define WM8996_ADC1L_TO_DSP1TXL_MASK 0x0002 /* ADC1L_TO_DSP1TXL */
-#define WM8996_ADC1L_TO_DSP1TXL_SHIFT 1 /* ADC1L_TO_DSP1TXL */
-#define WM8996_ADC1L_TO_DSP1TXL_WIDTH 1 /* ADC1L_TO_DSP1TXL */
-#define WM8996_DACL_TO_DSP1TXL 0x0001 /* DACL_TO_DSP1TXL */
-#define WM8996_DACL_TO_DSP1TXL_MASK 0x0001 /* DACL_TO_DSP1TXL */
-#define WM8996_DACL_TO_DSP1TXL_SHIFT 0 /* DACL_TO_DSP1TXL */
-#define WM8996_DACL_TO_DSP1TXL_WIDTH 1 /* DACL_TO_DSP1TXL */
-
-/*
- * R1543 (0x607) - DSP1 TX Right Mixer Routing
- */
-#define WM8996_ADC1R_TO_DSP1TXR 0x0002 /* ADC1R_TO_DSP1TXR */
-#define WM8996_ADC1R_TO_DSP1TXR_MASK 0x0002 /* ADC1R_TO_DSP1TXR */
-#define WM8996_ADC1R_TO_DSP1TXR_SHIFT 1 /* ADC1R_TO_DSP1TXR */
-#define WM8996_ADC1R_TO_DSP1TXR_WIDTH 1 /* ADC1R_TO_DSP1TXR */
-#define WM8996_DACR_TO_DSP1TXR 0x0001 /* DACR_TO_DSP1TXR */
-#define WM8996_DACR_TO_DSP1TXR_MASK 0x0001 /* DACR_TO_DSP1TXR */
-#define WM8996_DACR_TO_DSP1TXR_SHIFT 0 /* DACR_TO_DSP1TXR */
-#define WM8996_DACR_TO_DSP1TXR_WIDTH 1 /* DACR_TO_DSP1TXR */
-
-/*
- * R1544 (0x608) - DSP2 TX Left Mixer Routing
- */
-#define WM8996_ADC2L_TO_DSP2TXL 0x0002 /* ADC2L_TO_DSP2TXL */
-#define WM8996_ADC2L_TO_DSP2TXL_MASK 0x0002 /* ADC2L_TO_DSP2TXL */
-#define WM8996_ADC2L_TO_DSP2TXL_SHIFT 1 /* ADC2L_TO_DSP2TXL */
-#define WM8996_ADC2L_TO_DSP2TXL_WIDTH 1 /* ADC2L_TO_DSP2TXL */
-#define WM8996_DACL_TO_DSP2TXL 0x0001 /* DACL_TO_DSP2TXL */
-#define WM8996_DACL_TO_DSP2TXL_MASK 0x0001 /* DACL_TO_DSP2TXL */
-#define WM8996_DACL_TO_DSP2TXL_SHIFT 0 /* DACL_TO_DSP2TXL */
-#define WM8996_DACL_TO_DSP2TXL_WIDTH 1 /* DACL_TO_DSP2TXL */
-
-/*
- * R1545 (0x609) - DSP2 TX Right Mixer Routing
- */
-#define WM8996_ADC2R_TO_DSP2TXR 0x0002 /* ADC2R_TO_DSP2TXR */
-#define WM8996_ADC2R_TO_DSP2TXR_MASK 0x0002 /* ADC2R_TO_DSP2TXR */
-#define WM8996_ADC2R_TO_DSP2TXR_SHIFT 1 /* ADC2R_TO_DSP2TXR */
-#define WM8996_ADC2R_TO_DSP2TXR_WIDTH 1 /* ADC2R_TO_DSP2TXR */
-#define WM8996_DACR_TO_DSP2TXR 0x0001 /* DACR_TO_DSP2TXR */
-#define WM8996_DACR_TO_DSP2TXR_MASK 0x0001 /* DACR_TO_DSP2TXR */
-#define WM8996_DACR_TO_DSP2TXR_SHIFT 0 /* DACR_TO_DSP2TXR */
-#define WM8996_DACR_TO_DSP2TXR_WIDTH 1 /* DACR_TO_DSP2TXR */
-
-/*
- * R1546 (0x60A) - DSP TX Mixer Select
- */
-#define WM8996_DAC_TO_DSPTX_SRC 0x0001 /* DAC_TO_DSPTX_SRC */
-#define WM8996_DAC_TO_DSPTX_SRC_MASK 0x0001 /* DAC_TO_DSPTX_SRC */
-#define WM8996_DAC_TO_DSPTX_SRC_SHIFT 0 /* DAC_TO_DSPTX_SRC */
-#define WM8996_DAC_TO_DSPTX_SRC_WIDTH 1 /* DAC_TO_DSPTX_SRC */
-
-/*
- * R1552 (0x610) - DAC Softmute
- */
-#define WM8996_DAC_SOFTMUTEMODE 0x0002 /* DAC_SOFTMUTEMODE */
-#define WM8996_DAC_SOFTMUTEMODE_MASK 0x0002 /* DAC_SOFTMUTEMODE */
-#define WM8996_DAC_SOFTMUTEMODE_SHIFT 1 /* DAC_SOFTMUTEMODE */
-#define WM8996_DAC_SOFTMUTEMODE_WIDTH 1 /* DAC_SOFTMUTEMODE */
-#define WM8996_DAC_MUTERATE 0x0001 /* DAC_MUTERATE */
-#define WM8996_DAC_MUTERATE_MASK 0x0001 /* DAC_MUTERATE */
-#define WM8996_DAC_MUTERATE_SHIFT 0 /* DAC_MUTERATE */
-#define WM8996_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
-
-/*
- * R1568 (0x620) - Oversampling
- */
-#define WM8996_SPK_OSR128 0x0008 /* SPK_OSR128 */
-#define WM8996_SPK_OSR128_MASK 0x0008 /* SPK_OSR128 */
-#define WM8996_SPK_OSR128_SHIFT 3 /* SPK_OSR128 */
-#define WM8996_SPK_OSR128_WIDTH 1 /* SPK_OSR128 */
-#define WM8996_DMIC_OSR64 0x0004 /* DMIC_OSR64 */
-#define WM8996_DMIC_OSR64_MASK 0x0004 /* DMIC_OSR64 */
-#define WM8996_DMIC_OSR64_SHIFT 2 /* DMIC_OSR64 */
-#define WM8996_DMIC_OSR64_WIDTH 1 /* DMIC_OSR64 */
-#define WM8996_ADC_OSR128 0x0002 /* ADC_OSR128 */
-#define WM8996_ADC_OSR128_MASK 0x0002 /* ADC_OSR128 */
-#define WM8996_ADC_OSR128_SHIFT 1 /* ADC_OSR128 */
-#define WM8996_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
-#define WM8996_DAC_OSR128 0x0001 /* DAC_OSR128 */
-#define WM8996_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */
-#define WM8996_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */
-#define WM8996_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
-
-/*
- * R1569 (0x621) - Sidetone
- */
-#define WM8996_ST_LPF 0x1000 /* ST_LPF */
-#define WM8996_ST_LPF_MASK 0x1000 /* ST_LPF */
-#define WM8996_ST_LPF_SHIFT 12 /* ST_LPF */
-#define WM8996_ST_LPF_WIDTH 1 /* ST_LPF */
-#define WM8996_ST_HPF_CUT_MASK 0x0380 /* ST_HPF_CUT - [9:7] */
-#define WM8996_ST_HPF_CUT_SHIFT 7 /* ST_HPF_CUT - [9:7] */
-#define WM8996_ST_HPF_CUT_WIDTH 3 /* ST_HPF_CUT - [9:7] */
-#define WM8996_ST_HPF 0x0040 /* ST_HPF */
-#define WM8996_ST_HPF_MASK 0x0040 /* ST_HPF */
-#define WM8996_ST_HPF_SHIFT 6 /* ST_HPF */
-#define WM8996_ST_HPF_WIDTH 1 /* ST_HPF */
-#define WM8996_STR_SEL 0x0002 /* STR_SEL */
-#define WM8996_STR_SEL_MASK 0x0002 /* STR_SEL */
-#define WM8996_STR_SEL_SHIFT 1 /* STR_SEL */
-#define WM8996_STR_SEL_WIDTH 1 /* STR_SEL */
-#define WM8996_STL_SEL 0x0001 /* STL_SEL */
-#define WM8996_STL_SEL_MASK 0x0001 /* STL_SEL */
-#define WM8996_STL_SEL_SHIFT 0 /* STL_SEL */
-#define WM8996_STL_SEL_WIDTH 1 /* STL_SEL */
-
-/*
- * R1792 (0x700) - GPIO 1
- */
-#define WM8996_GP1_DIR 0x8000 /* GP1_DIR */
-#define WM8996_GP1_DIR_MASK 0x8000 /* GP1_DIR */
-#define WM8996_GP1_DIR_SHIFT 15 /* GP1_DIR */
-#define WM8996_GP1_DIR_WIDTH 1 /* GP1_DIR */
-#define WM8996_GP1_PU 0x4000 /* GP1_PU */
-#define WM8996_GP1_PU_MASK 0x4000 /* GP1_PU */
-#define WM8996_GP1_PU_SHIFT 14 /* GP1_PU */
-#define WM8996_GP1_PU_WIDTH 1 /* GP1_PU */
-#define WM8996_GP1_PD 0x2000 /* GP1_PD */
-#define WM8996_GP1_PD_MASK 0x2000 /* GP1_PD */
-#define WM8996_GP1_PD_SHIFT 13 /* GP1_PD */
-#define WM8996_GP1_PD_WIDTH 1 /* GP1_PD */
-#define WM8996_GP1_POL 0x0400 /* GP1_POL */
-#define WM8996_GP1_POL_MASK 0x0400 /* GP1_POL */
-#define WM8996_GP1_POL_SHIFT 10 /* GP1_POL */
-#define WM8996_GP1_POL_WIDTH 1 /* GP1_POL */
-#define WM8996_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */
-#define WM8996_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */
-#define WM8996_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */
-#define WM8996_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
-#define WM8996_GP1_DB 0x0100 /* GP1_DB */
-#define WM8996_GP1_DB_MASK 0x0100 /* GP1_DB */
-#define WM8996_GP1_DB_SHIFT 8 /* GP1_DB */
-#define WM8996_GP1_DB_WIDTH 1 /* GP1_DB */
-#define WM8996_GP1_LVL 0x0040 /* GP1_LVL */
-#define WM8996_GP1_LVL_MASK 0x0040 /* GP1_LVL */
-#define WM8996_GP1_LVL_SHIFT 6 /* GP1_LVL */
-#define WM8996_GP1_LVL_WIDTH 1 /* GP1_LVL */
-#define WM8996_GP1_FN_MASK 0x000F /* GP1_FN - [3:0] */
-#define WM8996_GP1_FN_SHIFT 0 /* GP1_FN - [3:0] */
-#define WM8996_GP1_FN_WIDTH 4 /* GP1_FN - [3:0] */
-
-/*
- * R1793 (0x701) - GPIO 2
- */
-#define WM8996_GP2_DIR 0x8000 /* GP2_DIR */
-#define WM8996_GP2_DIR_MASK 0x8000 /* GP2_DIR */
-#define WM8996_GP2_DIR_SHIFT 15 /* GP2_DIR */
-#define WM8996_GP2_DIR_WIDTH 1 /* GP2_DIR */
-#define WM8996_GP2_PU 0x4000 /* GP2_PU */
-#define WM8996_GP2_PU_MASK 0x4000 /* GP2_PU */
-#define WM8996_GP2_PU_SHIFT 14 /* GP2_PU */
-#define WM8996_GP2_PU_WIDTH 1 /* GP2_PU */
-#define WM8996_GP2_PD 0x2000 /* GP2_PD */
-#define WM8996_GP2_PD_MASK 0x2000 /* GP2_PD */
-#define WM8996_GP2_PD_SHIFT 13 /* GP2_PD */
-#define WM8996_GP2_PD_WIDTH 1 /* GP2_PD */
-#define WM8996_GP2_POL 0x0400 /* GP2_POL */
-#define WM8996_GP2_POL_MASK 0x0400 /* GP2_POL */
-#define WM8996_GP2_POL_SHIFT 10 /* GP2_POL */
-#define WM8996_GP2_POL_WIDTH 1 /* GP2_POL */
-#define WM8996_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */
-#define WM8996_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */
-#define WM8996_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */
-#define WM8996_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
-#define WM8996_GP2_DB 0x0100 /* GP2_DB */
-#define WM8996_GP2_DB_MASK 0x0100 /* GP2_DB */
-#define WM8996_GP2_DB_SHIFT 8 /* GP2_DB */
-#define WM8996_GP2_DB_WIDTH 1 /* GP2_DB */
-#define WM8996_GP2_LVL 0x0040 /* GP2_LVL */
-#define WM8996_GP2_LVL_MASK 0x0040 /* GP2_LVL */
-#define WM8996_GP2_LVL_SHIFT 6 /* GP2_LVL */
-#define WM8996_GP2_LVL_WIDTH 1 /* GP2_LVL */
-#define WM8996_GP2_FN_MASK 0x000F /* GP2_FN - [3:0] */
-#define WM8996_GP2_FN_SHIFT 0 /* GP2_FN - [3:0] */
-#define WM8996_GP2_FN_WIDTH 4 /* GP2_FN - [3:0] */
-
-/*
- * R1794 (0x702) - GPIO 3
- */
-#define WM8996_GP3_DIR 0x8000 /* GP3_DIR */
-#define WM8996_GP3_DIR_MASK 0x8000 /* GP3_DIR */
-#define WM8996_GP3_DIR_SHIFT 15 /* GP3_DIR */
-#define WM8996_GP3_DIR_WIDTH 1 /* GP3_DIR */
-#define WM8996_GP3_PU 0x4000 /* GP3_PU */
-#define WM8996_GP3_PU_MASK 0x4000 /* GP3_PU */
-#define WM8996_GP3_PU_SHIFT 14 /* GP3_PU */
-#define WM8996_GP3_PU_WIDTH 1 /* GP3_PU */
-#define WM8996_GP3_PD 0x2000 /* GP3_PD */
-#define WM8996_GP3_PD_MASK 0x2000 /* GP3_PD */
-#define WM8996_GP3_PD_SHIFT 13 /* GP3_PD */
-#define WM8996_GP3_PD_WIDTH 1 /* GP3_PD */
-#define WM8996_GP3_POL 0x0400 /* GP3_POL */
-#define WM8996_GP3_POL_MASK 0x0400 /* GP3_POL */
-#define WM8996_GP3_POL_SHIFT 10 /* GP3_POL */
-#define WM8996_GP3_POL_WIDTH 1 /* GP3_POL */
-#define WM8996_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */
-#define WM8996_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */
-#define WM8996_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */
-#define WM8996_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
-#define WM8996_GP3_DB 0x0100 /* GP3_DB */
-#define WM8996_GP3_DB_MASK 0x0100 /* GP3_DB */
-#define WM8996_GP3_DB_SHIFT 8 /* GP3_DB */
-#define WM8996_GP3_DB_WIDTH 1 /* GP3_DB */
-#define WM8996_GP3_LVL 0x0040 /* GP3_LVL */
-#define WM8996_GP3_LVL_MASK 0x0040 /* GP3_LVL */
-#define WM8996_GP3_LVL_SHIFT 6 /* GP3_LVL */
-#define WM8996_GP3_LVL_WIDTH 1 /* GP3_LVL */
-#define WM8996_GP3_FN_MASK 0x000F /* GP3_FN - [3:0] */
-#define WM8996_GP3_FN_SHIFT 0 /* GP3_FN - [3:0] */
-#define WM8996_GP3_FN_WIDTH 4 /* GP3_FN - [3:0] */
-
-/*
- * R1795 (0x703) - GPIO 4
- */
-#define WM8996_GP4_DIR 0x8000 /* GP4_DIR */
-#define WM8996_GP4_DIR_MASK 0x8000 /* GP4_DIR */
-#define WM8996_GP4_DIR_SHIFT 15 /* GP4_DIR */
-#define WM8996_GP4_DIR_WIDTH 1 /* GP4_DIR */
-#define WM8996_GP4_PU 0x4000 /* GP4_PU */
-#define WM8996_GP4_PU_MASK 0x4000 /* GP4_PU */
-#define WM8996_GP4_PU_SHIFT 14 /* GP4_PU */
-#define WM8996_GP4_PU_WIDTH 1 /* GP4_PU */
-#define WM8996_GP4_PD 0x2000 /* GP4_PD */
-#define WM8996_GP4_PD_MASK 0x2000 /* GP4_PD */
-#define WM8996_GP4_PD_SHIFT 13 /* GP4_PD */
-#define WM8996_GP4_PD_WIDTH 1 /* GP4_PD */
-#define WM8996_GP4_POL 0x0400 /* GP4_POL */
-#define WM8996_GP4_POL_MASK 0x0400 /* GP4_POL */
-#define WM8996_GP4_POL_SHIFT 10 /* GP4_POL */
-#define WM8996_GP4_POL_WIDTH 1 /* GP4_POL */
-#define WM8996_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */
-#define WM8996_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */
-#define WM8996_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */
-#define WM8996_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
-#define WM8996_GP4_DB 0x0100 /* GP4_DB */
-#define WM8996_GP4_DB_MASK 0x0100 /* GP4_DB */
-#define WM8996_GP4_DB_SHIFT 8 /* GP4_DB */
-#define WM8996_GP4_DB_WIDTH 1 /* GP4_DB */
-#define WM8996_GP4_LVL 0x0040 /* GP4_LVL */
-#define WM8996_GP4_LVL_MASK 0x0040 /* GP4_LVL */
-#define WM8996_GP4_LVL_SHIFT 6 /* GP4_LVL */
-#define WM8996_GP4_LVL_WIDTH 1 /* GP4_LVL */
-#define WM8996_GP4_FN_MASK 0x000F /* GP4_FN - [3:0] */
-#define WM8996_GP4_FN_SHIFT 0 /* GP4_FN - [3:0] */
-#define WM8996_GP4_FN_WIDTH 4 /* GP4_FN - [3:0] */
-
-/*
- * R1796 (0x704) - GPIO 5
- */
-#define WM8996_GP5_DIR 0x8000 /* GP5_DIR */
-#define WM8996_GP5_DIR_MASK 0x8000 /* GP5_DIR */
-#define WM8996_GP5_DIR_SHIFT 15 /* GP5_DIR */
-#define WM8996_GP5_DIR_WIDTH 1 /* GP5_DIR */
-#define WM8996_GP5_PU 0x4000 /* GP5_PU */
-#define WM8996_GP5_PU_MASK 0x4000 /* GP5_PU */
-#define WM8996_GP5_PU_SHIFT 14 /* GP5_PU */
-#define WM8996_GP5_PU_WIDTH 1 /* GP5_PU */
-#define WM8996_GP5_PD 0x2000 /* GP5_PD */
-#define WM8996_GP5_PD_MASK 0x2000 /* GP5_PD */
-#define WM8996_GP5_PD_SHIFT 13 /* GP5_PD */
-#define WM8996_GP5_PD_WIDTH 1 /* GP5_PD */
-#define WM8996_GP5_POL 0x0400 /* GP5_POL */
-#define WM8996_GP5_POL_MASK 0x0400 /* GP5_POL */
-#define WM8996_GP5_POL_SHIFT 10 /* GP5_POL */
-#define WM8996_GP5_POL_WIDTH 1 /* GP5_POL */
-#define WM8996_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */
-#define WM8996_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */
-#define WM8996_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */
-#define WM8996_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
-#define WM8996_GP5_DB 0x0100 /* GP5_DB */
-#define WM8996_GP5_DB_MASK 0x0100 /* GP5_DB */
-#define WM8996_GP5_DB_SHIFT 8 /* GP5_DB */
-#define WM8996_GP5_DB_WIDTH 1 /* GP5_DB */
-#define WM8996_GP5_LVL 0x0040 /* GP5_LVL */
-#define WM8996_GP5_LVL_MASK 0x0040 /* GP5_LVL */
-#define WM8996_GP5_LVL_SHIFT 6 /* GP5_LVL */
-#define WM8996_GP5_LVL_WIDTH 1 /* GP5_LVL */
-#define WM8996_GP5_FN_MASK 0x000F /* GP5_FN - [3:0] */
-#define WM8996_GP5_FN_SHIFT 0 /* GP5_FN - [3:0] */
-#define WM8996_GP5_FN_WIDTH 4 /* GP5_FN - [3:0] */
-
-/*
- * R1824 (0x720) - Pull Control (1)
- */
-#define WM8996_DMICDAT2_PD 0x1000 /* DMICDAT2_PD */
-#define WM8996_DMICDAT2_PD_MASK 0x1000 /* DMICDAT2_PD */
-#define WM8996_DMICDAT2_PD_SHIFT 12 /* DMICDAT2_PD */
-#define WM8996_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */
-#define WM8996_DMICDAT1_PD 0x0400 /* DMICDAT1_PD */
-#define WM8996_DMICDAT1_PD_MASK 0x0400 /* DMICDAT1_PD */
-#define WM8996_DMICDAT1_PD_SHIFT 10 /* DMICDAT1_PD */
-#define WM8996_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */
-#define WM8996_MCLK2_PU 0x0200 /* MCLK2_PU */
-#define WM8996_MCLK2_PU_MASK 0x0200 /* MCLK2_PU */
-#define WM8996_MCLK2_PU_SHIFT 9 /* MCLK2_PU */
-#define WM8996_MCLK2_PU_WIDTH 1 /* MCLK2_PU */
-#define WM8996_MCLK2_PD 0x0100 /* MCLK2_PD */
-#define WM8996_MCLK2_PD_MASK 0x0100 /* MCLK2_PD */
-#define WM8996_MCLK2_PD_SHIFT 8 /* MCLK2_PD */
-#define WM8996_MCLK2_PD_WIDTH 1 /* MCLK2_PD */
-#define WM8996_MCLK1_PU 0x0080 /* MCLK1_PU */
-#define WM8996_MCLK1_PU_MASK 0x0080 /* MCLK1_PU */
-#define WM8996_MCLK1_PU_SHIFT 7 /* MCLK1_PU */
-#define WM8996_MCLK1_PU_WIDTH 1 /* MCLK1_PU */
-#define WM8996_MCLK1_PD 0x0040 /* MCLK1_PD */
-#define WM8996_MCLK1_PD_MASK 0x0040 /* MCLK1_PD */
-#define WM8996_MCLK1_PD_SHIFT 6 /* MCLK1_PD */
-#define WM8996_MCLK1_PD_WIDTH 1 /* MCLK1_PD */
-#define WM8996_DACDAT1_PU 0x0020 /* DACDAT1_PU */
-#define WM8996_DACDAT1_PU_MASK 0x0020 /* DACDAT1_PU */
-#define WM8996_DACDAT1_PU_SHIFT 5 /* DACDAT1_PU */
-#define WM8996_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */
-#define WM8996_DACDAT1_PD 0x0010 /* DACDAT1_PD */
-#define WM8996_DACDAT1_PD_MASK 0x0010 /* DACDAT1_PD */
-#define WM8996_DACDAT1_PD_SHIFT 4 /* DACDAT1_PD */
-#define WM8996_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */
-#define WM8996_DACLRCLK1_PU 0x0008 /* DACLRCLK1_PU */
-#define WM8996_DACLRCLK1_PU_MASK 0x0008 /* DACLRCLK1_PU */
-#define WM8996_DACLRCLK1_PU_SHIFT 3 /* DACLRCLK1_PU */
-#define WM8996_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */
-#define WM8996_DACLRCLK1_PD 0x0004 /* DACLRCLK1_PD */
-#define WM8996_DACLRCLK1_PD_MASK 0x0004 /* DACLRCLK1_PD */
-#define WM8996_DACLRCLK1_PD_SHIFT 2 /* DACLRCLK1_PD */
-#define WM8996_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */
-#define WM8996_BCLK1_PU 0x0002 /* BCLK1_PU */
-#define WM8996_BCLK1_PU_MASK 0x0002 /* BCLK1_PU */
-#define WM8996_BCLK1_PU_SHIFT 1 /* BCLK1_PU */
-#define WM8996_BCLK1_PU_WIDTH 1 /* BCLK1_PU */
-#define WM8996_BCLK1_PD 0x0001 /* BCLK1_PD */
-#define WM8996_BCLK1_PD_MASK 0x0001 /* BCLK1_PD */
-#define WM8996_BCLK1_PD_SHIFT 0 /* BCLK1_PD */
-#define WM8996_BCLK1_PD_WIDTH 1 /* BCLK1_PD */
-
-/*
- * R1825 (0x721) - Pull Control (2)
- */
-#define WM8996_LDO1ENA_PD 0x0100 /* LDO1ENA_PD */
-#define WM8996_LDO1ENA_PD_MASK 0x0100 /* LDO1ENA_PD */
-#define WM8996_LDO1ENA_PD_SHIFT 8 /* LDO1ENA_PD */
-#define WM8996_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */
-#define WM8996_ADDR_PD 0x0040 /* ADDR_PD */
-#define WM8996_ADDR_PD_MASK 0x0040 /* ADDR_PD */
-#define WM8996_ADDR_PD_SHIFT 6 /* ADDR_PD */
-#define WM8996_ADDR_PD_WIDTH 1 /* ADDR_PD */
-#define WM8996_DACDAT2_PU 0x0020 /* DACDAT2_PU */
-#define WM8996_DACDAT2_PU_MASK 0x0020 /* DACDAT2_PU */
-#define WM8996_DACDAT2_PU_SHIFT 5 /* DACDAT2_PU */
-#define WM8996_DACDAT2_PU_WIDTH 1 /* DACDAT2_PU */
-#define WM8996_DACDAT2_PD 0x0010 /* DACDAT2_PD */
-#define WM8996_DACDAT2_PD_MASK 0x0010 /* DACDAT2_PD */
-#define WM8996_DACDAT2_PD_SHIFT 4 /* DACDAT2_PD */
-#define WM8996_DACDAT2_PD_WIDTH 1 /* DACDAT2_PD */
-#define WM8996_DACLRCLK2_PU 0x0008 /* DACLRCLK2_PU */
-#define WM8996_DACLRCLK2_PU_MASK 0x0008 /* DACLRCLK2_PU */
-#define WM8996_DACLRCLK2_PU_SHIFT 3 /* DACLRCLK2_PU */
-#define WM8996_DACLRCLK2_PU_WIDTH 1 /* DACLRCLK2_PU */
-#define WM8996_DACLRCLK2_PD 0x0004 /* DACLRCLK2_PD */
-#define WM8996_DACLRCLK2_PD_MASK 0x0004 /* DACLRCLK2_PD */
-#define WM8996_DACLRCLK2_PD_SHIFT 2 /* DACLRCLK2_PD */
-#define WM8996_DACLRCLK2_PD_WIDTH 1 /* DACLRCLK2_PD */
-#define WM8996_BCLK2_PU 0x0002 /* BCLK2_PU */
-#define WM8996_BCLK2_PU_MASK 0x0002 /* BCLK2_PU */
-#define WM8996_BCLK2_PU_SHIFT 1 /* BCLK2_PU */
-#define WM8996_BCLK2_PU_WIDTH 1 /* BCLK2_PU */
-#define WM8996_BCLK2_PD 0x0001 /* BCLK2_PD */
-#define WM8996_BCLK2_PD_MASK 0x0001 /* BCLK2_PD */
-#define WM8996_BCLK2_PD_SHIFT 0 /* BCLK2_PD */
-#define WM8996_BCLK2_PD_WIDTH 1 /* BCLK2_PD */
-
-/*
- * R1840 (0x730) - Interrupt Status 1
- */
-#define WM8996_GP5_EINT 0x0010 /* GP5_EINT */
-#define WM8996_GP5_EINT_MASK 0x0010 /* GP5_EINT */
-#define WM8996_GP5_EINT_SHIFT 4 /* GP5_EINT */
-#define WM8996_GP5_EINT_WIDTH 1 /* GP5_EINT */
-#define WM8996_GP4_EINT 0x0008 /* GP4_EINT */
-#define WM8996_GP4_EINT_MASK 0x0008 /* GP4_EINT */
-#define WM8996_GP4_EINT_SHIFT 3 /* GP4_EINT */
-#define WM8996_GP4_EINT_WIDTH 1 /* GP4_EINT */
-#define WM8996_GP3_EINT 0x0004 /* GP3_EINT */
-#define WM8996_GP3_EINT_MASK 0x0004 /* GP3_EINT */
-#define WM8996_GP3_EINT_SHIFT 2 /* GP3_EINT */
-#define WM8996_GP3_EINT_WIDTH 1 /* GP3_EINT */
-#define WM8996_GP2_EINT 0x0002 /* GP2_EINT */
-#define WM8996_GP2_EINT_MASK 0x0002 /* GP2_EINT */
-#define WM8996_GP2_EINT_SHIFT 1 /* GP2_EINT */
-#define WM8996_GP2_EINT_WIDTH 1 /* GP2_EINT */
-#define WM8996_GP1_EINT 0x0001 /* GP1_EINT */
-#define WM8996_GP1_EINT_MASK 0x0001 /* GP1_EINT */
-#define WM8996_GP1_EINT_SHIFT 0 /* GP1_EINT */
-#define WM8996_GP1_EINT_WIDTH 1 /* GP1_EINT */
-
-/*
- * R1841 (0x731) - Interrupt Status 2
- */
-#define WM8996_DCS_DONE_23_EINT 0x1000 /* DCS_DONE_23_EINT */
-#define WM8996_DCS_DONE_23_EINT_MASK 0x1000 /* DCS_DONE_23_EINT */
-#define WM8996_DCS_DONE_23_EINT_SHIFT 12 /* DCS_DONE_23_EINT */
-#define WM8996_DCS_DONE_23_EINT_WIDTH 1 /* DCS_DONE_23_EINT */
-#define WM8996_DCS_DONE_01_EINT 0x0800 /* DCS_DONE_01_EINT */
-#define WM8996_DCS_DONE_01_EINT_MASK 0x0800 /* DCS_DONE_01_EINT */
-#define WM8996_DCS_DONE_01_EINT_SHIFT 11 /* DCS_DONE_01_EINT */
-#define WM8996_DCS_DONE_01_EINT_WIDTH 1 /* DCS_DONE_01_EINT */
-#define WM8996_WSEQ_DONE_EINT 0x0400 /* WSEQ_DONE_EINT */
-#define WM8996_WSEQ_DONE_EINT_MASK 0x0400 /* WSEQ_DONE_EINT */
-#define WM8996_WSEQ_DONE_EINT_SHIFT 10 /* WSEQ_DONE_EINT */
-#define WM8996_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */
-#define WM8996_FIFOS_ERR_EINT 0x0200 /* FIFOS_ERR_EINT */
-#define WM8996_FIFOS_ERR_EINT_MASK 0x0200 /* FIFOS_ERR_EINT */
-#define WM8996_FIFOS_ERR_EINT_SHIFT 9 /* FIFOS_ERR_EINT */
-#define WM8996_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */
-#define WM8996_DSP2DRC_SIG_DET_EINT 0x0080 /* DSP2DRC_SIG_DET_EINT */
-#define WM8996_DSP2DRC_SIG_DET_EINT_MASK 0x0080 /* DSP2DRC_SIG_DET_EINT */
-#define WM8996_DSP2DRC_SIG_DET_EINT_SHIFT 7 /* DSP2DRC_SIG_DET_EINT */
-#define WM8996_DSP2DRC_SIG_DET_EINT_WIDTH 1 /* DSP2DRC_SIG_DET_EINT */
-#define WM8996_DSP1DRC_SIG_DET_EINT 0x0040 /* DSP1DRC_SIG_DET_EINT */
-#define WM8996_DSP1DRC_SIG_DET_EINT_MASK 0x0040 /* DSP1DRC_SIG_DET_EINT */
-#define WM8996_DSP1DRC_SIG_DET_EINT_SHIFT 6 /* DSP1DRC_SIG_DET_EINT */
-#define WM8996_DSP1DRC_SIG_DET_EINT_WIDTH 1 /* DSP1DRC_SIG_DET_EINT */
-#define WM8996_FLL_SW_CLK_DONE_EINT 0x0008 /* FLL_SW_CLK_DONE_EINT */
-#define WM8996_FLL_SW_CLK_DONE_EINT_MASK 0x0008 /* FLL_SW_CLK_DONE_EINT */
-#define WM8996_FLL_SW_CLK_DONE_EINT_SHIFT 3 /* FLL_SW_CLK_DONE_EINT */
-#define WM8996_FLL_SW_CLK_DONE_EINT_WIDTH 1 /* FLL_SW_CLK_DONE_EINT */
-#define WM8996_FLL_LOCK_EINT 0x0004 /* FLL_LOCK_EINT */
-#define WM8996_FLL_LOCK_EINT_MASK 0x0004 /* FLL_LOCK_EINT */
-#define WM8996_FLL_LOCK_EINT_SHIFT 2 /* FLL_LOCK_EINT */
-#define WM8996_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */
-#define WM8996_HP_DONE_EINT 0x0002 /* HP_DONE_EINT */
-#define WM8996_HP_DONE_EINT_MASK 0x0002 /* HP_DONE_EINT */
-#define WM8996_HP_DONE_EINT_SHIFT 1 /* HP_DONE_EINT */
-#define WM8996_HP_DONE_EINT_WIDTH 1 /* HP_DONE_EINT */
-#define WM8996_MICD_EINT 0x0001 /* MICD_EINT */
-#define WM8996_MICD_EINT_MASK 0x0001 /* MICD_EINT */
-#define WM8996_MICD_EINT_SHIFT 0 /* MICD_EINT */
-#define WM8996_MICD_EINT_WIDTH 1 /* MICD_EINT */
-
-/*
- * R1842 (0x732) - Interrupt Raw Status 2
- */
-#define WM8996_DCS_DONE_23_STS 0x1000 /* DCS_DONE_23_STS */
-#define WM8996_DCS_DONE_23_STS_MASK 0x1000 /* DCS_DONE_23_STS */
-#define WM8996_DCS_DONE_23_STS_SHIFT 12 /* DCS_DONE_23_STS */
-#define WM8996_DCS_DONE_23_STS_WIDTH 1 /* DCS_DONE_23_STS */
-#define WM8996_DCS_DONE_01_STS 0x0800 /* DCS_DONE_01_STS */
-#define WM8996_DCS_DONE_01_STS_MASK 0x0800 /* DCS_DONE_01_STS */
-#define WM8996_DCS_DONE_01_STS_SHIFT 11 /* DCS_DONE_01_STS */
-#define WM8996_DCS_DONE_01_STS_WIDTH 1 /* DCS_DONE_01_STS */
-#define WM8996_WSEQ_DONE_STS 0x0400 /* WSEQ_DONE_STS */
-#define WM8996_WSEQ_DONE_STS_MASK 0x0400 /* WSEQ_DONE_STS */
-#define WM8996_WSEQ_DONE_STS_SHIFT 10 /* WSEQ_DONE_STS */
-#define WM8996_WSEQ_DONE_STS_WIDTH 1 /* WSEQ_DONE_STS */
-#define WM8996_FIFOS_ERR_STS 0x0200 /* FIFOS_ERR_STS */
-#define WM8996_FIFOS_ERR_STS_MASK 0x0200 /* FIFOS_ERR_STS */
-#define WM8996_FIFOS_ERR_STS_SHIFT 9 /* FIFOS_ERR_STS */
-#define WM8996_FIFOS_ERR_STS_WIDTH 1 /* FIFOS_ERR_STS */
-#define WM8996_DSP2DRC_SIG_DET_STS 0x0080 /* DSP2DRC_SIG_DET_STS */
-#define WM8996_DSP2DRC_SIG_DET_STS_MASK 0x0080 /* DSP2DRC_SIG_DET_STS */
-#define WM8996_DSP2DRC_SIG_DET_STS_SHIFT 7 /* DSP2DRC_SIG_DET_STS */
-#define WM8996_DSP2DRC_SIG_DET_STS_WIDTH 1 /* DSP2DRC_SIG_DET_STS */
-#define WM8996_DSP1DRC_SIG_DET_STS 0x0040 /* DSP1DRC_SIG_DET_STS */
-#define WM8996_DSP1DRC_SIG_DET_STS_MASK 0x0040 /* DSP1DRC_SIG_DET_STS */
-#define WM8996_DSP1DRC_SIG_DET_STS_SHIFT 6 /* DSP1DRC_SIG_DET_STS */
-#define WM8996_DSP1DRC_SIG_DET_STS_WIDTH 1 /* DSP1DRC_SIG_DET_STS */
-#define WM8996_FLL_LOCK_STS 0x0004 /* FLL_LOCK_STS */
-#define WM8996_FLL_LOCK_STS_MASK 0x0004 /* FLL_LOCK_STS */
-#define WM8996_FLL_LOCK_STS_SHIFT 2 /* FLL_LOCK_STS */
-#define WM8996_FLL_LOCK_STS_WIDTH 1 /* FLL_LOCK_STS */
-
-/*
- * R1848 (0x738) - Interrupt Status 1 Mask
- */
-#define WM8996_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
-#define WM8996_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
-#define WM8996_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
-#define WM8996_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
-#define WM8996_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
-#define WM8996_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
-#define WM8996_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
-#define WM8996_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
-#define WM8996_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
-#define WM8996_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
-#define WM8996_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
-#define WM8996_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
-#define WM8996_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
-#define WM8996_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
-#define WM8996_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
-#define WM8996_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
-#define WM8996_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
-#define WM8996_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
-#define WM8996_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
-#define WM8996_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
-
-/*
- * R1849 (0x739) - Interrupt Status 2 Mask
- */
-#define WM8996_IM_DCS_DONE_23_EINT 0x1000 /* IM_DCS_DONE_23_EINT */
-#define WM8996_IM_DCS_DONE_23_EINT_MASK 0x1000 /* IM_DCS_DONE_23_EINT */
-#define WM8996_IM_DCS_DONE_23_EINT_SHIFT 12 /* IM_DCS_DONE_23_EINT */
-#define WM8996_IM_DCS_DONE_23_EINT_WIDTH 1 /* IM_DCS_DONE_23_EINT */
-#define WM8996_IM_DCS_DONE_01_EINT 0x0800 /* IM_DCS_DONE_01_EINT */
-#define WM8996_IM_DCS_DONE_01_EINT_MASK 0x0800 /* IM_DCS_DONE_01_EINT */
-#define WM8996_IM_DCS_DONE_01_EINT_SHIFT 11 /* IM_DCS_DONE_01_EINT */
-#define WM8996_IM_DCS_DONE_01_EINT_WIDTH 1 /* IM_DCS_DONE_01_EINT */
-#define WM8996_IM_WSEQ_DONE_EINT 0x0400 /* IM_WSEQ_DONE_EINT */
-#define WM8996_IM_WSEQ_DONE_EINT_MASK 0x0400 /* IM_WSEQ_DONE_EINT */
-#define WM8996_IM_WSEQ_DONE_EINT_SHIFT 10 /* IM_WSEQ_DONE_EINT */
-#define WM8996_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */
-#define WM8996_IM_FIFOS_ERR_EINT 0x0200 /* IM_FIFOS_ERR_EINT */
-#define WM8996_IM_FIFOS_ERR_EINT_MASK 0x0200 /* IM_FIFOS_ERR_EINT */
-#define WM8996_IM_FIFOS_ERR_EINT_SHIFT 9 /* IM_FIFOS_ERR_EINT */
-#define WM8996_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */
-#define WM8996_IM_DSP2DRC_SIG_DET_EINT 0x0080 /* IM_DSP2DRC_SIG_DET_EINT */
-#define WM8996_IM_DSP2DRC_SIG_DET_EINT_MASK 0x0080 /* IM_DSP2DRC_SIG_DET_EINT */
-#define WM8996_IM_DSP2DRC_SIG_DET_EINT_SHIFT 7 /* IM_DSP2DRC_SIG_DET_EINT */
-#define WM8996_IM_DSP2DRC_SIG_DET_EINT_WIDTH 1 /* IM_DSP2DRC_SIG_DET_EINT */
-#define WM8996_IM_DSP1DRC_SIG_DET_EINT 0x0040 /* IM_DSP1DRC_SIG_DET_EINT */
-#define WM8996_IM_DSP1DRC_SIG_DET_EINT_MASK 0x0040 /* IM_DSP1DRC_SIG_DET_EINT */
-#define WM8996_IM_DSP1DRC_SIG_DET_EINT_SHIFT 6 /* IM_DSP1DRC_SIG_DET_EINT */
-#define WM8996_IM_DSP1DRC_SIG_DET_EINT_WIDTH 1 /* IM_DSP1DRC_SIG_DET_EINT */
-#define WM8996_IM_FLL_SW_CLK_DONE_EINT 0x0008 /* IM_FLL_SW_CLK_DONE_EINT */
-#define WM8996_IM_FLL_SW_CLK_DONE_EINT_MASK 0x0008 /* IM_FLL_SW_CLK_DONE_EINT */
-#define WM8996_IM_FLL_SW_CLK_DONE_EINT_SHIFT 3 /* IM_FLL_SW_CLK_DONE_EINT */
-#define WM8996_IM_FLL_SW_CLK_DONE_EINT_WIDTH 1 /* IM_FLL_SW_CLK_DONE_EINT */
-#define WM8996_IM_FLL_LOCK_EINT 0x0004 /* IM_FLL_LOCK_EINT */
-#define WM8996_IM_FLL_LOCK_EINT_MASK 0x0004 /* IM_FLL_LOCK_EINT */
-#define WM8996_IM_FLL_LOCK_EINT_SHIFT 2 /* IM_FLL_LOCK_EINT */
-#define WM8996_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */
-#define WM8996_IM_HP_DONE_EINT 0x0002 /* IM_HP_DONE_EINT */
-#define WM8996_IM_HP_DONE_EINT_MASK 0x0002 /* IM_HP_DONE_EINT */
-#define WM8996_IM_HP_DONE_EINT_SHIFT 1 /* IM_HP_DONE_EINT */
-#define WM8996_IM_HP_DONE_EINT_WIDTH 1 /* IM_HP_DONE_EINT */
-#define WM8996_IM_MICD_EINT 0x0001 /* IM_MICD_EINT */
-#define WM8996_IM_MICD_EINT_MASK 0x0001 /* IM_MICD_EINT */
-#define WM8996_IM_MICD_EINT_SHIFT 0 /* IM_MICD_EINT */
-#define WM8996_IM_MICD_EINT_WIDTH 1 /* IM_MICD_EINT */
-
-/*
- * R1856 (0x740) - Interrupt Control
- */
-#define WM8996_IM_IRQ 0x0001 /* IM_IRQ */
-#define WM8996_IM_IRQ_MASK 0x0001 /* IM_IRQ */
-#define WM8996_IM_IRQ_SHIFT 0 /* IM_IRQ */
-#define WM8996_IM_IRQ_WIDTH 1 /* IM_IRQ */
-
-/*
- * R2048 (0x800) - Left PDM Speaker
- */
-#define WM8996_SPKL_ENA 0x0010 /* SPKL_ENA */
-#define WM8996_SPKL_ENA_MASK 0x0010 /* SPKL_ENA */
-#define WM8996_SPKL_ENA_SHIFT 4 /* SPKL_ENA */
-#define WM8996_SPKL_ENA_WIDTH 1 /* SPKL_ENA */
-#define WM8996_SPKL_MUTE 0x0008 /* SPKL_MUTE */
-#define WM8996_SPKL_MUTE_MASK 0x0008 /* SPKL_MUTE */
-#define WM8996_SPKL_MUTE_SHIFT 3 /* SPKL_MUTE */
-#define WM8996_SPKL_MUTE_WIDTH 1 /* SPKL_MUTE */
-#define WM8996_SPKL_MUTE_ZC 0x0004 /* SPKL_MUTE_ZC */
-#define WM8996_SPKL_MUTE_ZC_MASK 0x0004 /* SPKL_MUTE_ZC */
-#define WM8996_SPKL_MUTE_ZC_SHIFT 2 /* SPKL_MUTE_ZC */
-#define WM8996_SPKL_MUTE_ZC_WIDTH 1 /* SPKL_MUTE_ZC */
-#define WM8996_SPKL_SRC_MASK 0x0003 /* SPKL_SRC - [1:0] */
-#define WM8996_SPKL_SRC_SHIFT 0 /* SPKL_SRC - [1:0] */
-#define WM8996_SPKL_SRC_WIDTH 2 /* SPKL_SRC - [1:0] */
-
-/*
- * R2049 (0x801) - Right PDM Speaker
- */
-#define WM8996_SPKR_ENA 0x0010 /* SPKR_ENA */
-#define WM8996_SPKR_ENA_MASK 0x0010 /* SPKR_ENA */
-#define WM8996_SPKR_ENA_SHIFT 4 /* SPKR_ENA */
-#define WM8996_SPKR_ENA_WIDTH 1 /* SPKR_ENA */
-#define WM8996_SPKR_MUTE 0x0008 /* SPKR_MUTE */
-#define WM8996_SPKR_MUTE_MASK 0x0008 /* SPKR_MUTE */
-#define WM8996_SPKR_MUTE_SHIFT 3 /* SPKR_MUTE */
-#define WM8996_SPKR_MUTE_WIDTH 1 /* SPKR_MUTE */
-#define WM8996_SPKR_MUTE_ZC 0x0004 /* SPKR_MUTE_ZC */
-#define WM8996_SPKR_MUTE_ZC_MASK 0x0004 /* SPKR_MUTE_ZC */
-#define WM8996_SPKR_MUTE_ZC_SHIFT 2 /* SPKR_MUTE_ZC */
-#define WM8996_SPKR_MUTE_ZC_WIDTH 1 /* SPKR_MUTE_ZC */
-#define WM8996_SPKR_SRC_MASK 0x0003 /* SPKR_SRC - [1:0] */
-#define WM8996_SPKR_SRC_SHIFT 0 /* SPKR_SRC - [1:0] */
-#define WM8996_SPKR_SRC_WIDTH 2 /* SPKR_SRC - [1:0] */
-
-/*
- * R2050 (0x802) - PDM Speaker Mute Sequence
- */
-#define WM8996_SPK_MUTE_ENDIAN 0x0100 /* SPK_MUTE_ENDIAN */
-#define WM8996_SPK_MUTE_ENDIAN_MASK 0x0100 /* SPK_MUTE_ENDIAN */
-#define WM8996_SPK_MUTE_ENDIAN_SHIFT 8 /* SPK_MUTE_ENDIAN */
-#define WM8996_SPK_MUTE_ENDIAN_WIDTH 1 /* SPK_MUTE_ENDIAN */
-#define WM8996_SPK_MUTE_SEQ1_MASK 0x00FF /* SPK_MUTE_SEQ1 - [7:0] */
-#define WM8996_SPK_MUTE_SEQ1_SHIFT 0 /* SPK_MUTE_SEQ1 - [7:0] */
-#define WM8996_SPK_MUTE_SEQ1_WIDTH 8 /* SPK_MUTE_SEQ1 - [7:0] */
-
-/*
- * R2051 (0x803) - PDM Speaker Volume
- */
-#define WM8996_SPKR_VOL_MASK 0x00F0 /* SPKR_VOL - [7:4] */
-#define WM8996_SPKR_VOL_SHIFT 4 /* SPKR_VOL - [7:4] */
-#define WM8996_SPKR_VOL_WIDTH 4 /* SPKR_VOL - [7:4] */
-#define WM8996_SPKL_VOL_MASK 0x000F /* SPKL_VOL - [3:0] */
-#define WM8996_SPKL_VOL_SHIFT 0 /* SPKL_VOL - [3:0] */
-#define WM8996_SPKL_VOL_WIDTH 4 /* SPKL_VOL - [3:0] */
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm9081.c b/ANDROID_3.4.5/sound/soc/codecs/wm9081.c
deleted file mode 100644
index 076c126e..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm9081.c
+++ /dev/null
@@ -1,1425 +0,0 @@
-/*
- * wm9081.c -- WM9081 ALSA SoC Audio driver
- *
- * Author: Mark Brown
- *
- * Copyright 2009 Wolfson Microelectronics plc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/regmap.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include <sound/wm9081.h>
-#include "wm9081.h"
-
-static struct reg_default wm9081_reg[] = {
- { 2, 0x00B9 }, /* R2 - Analogue Lineout */
- { 3, 0x00B9 }, /* R3 - Analogue Speaker PGA */
- { 4, 0x0001 }, /* R4 - VMID Control */
- { 5, 0x0068 }, /* R5 - Bias Control 1 */
- { 7, 0x0000 }, /* R7 - Analogue Mixer */
- { 8, 0x0000 }, /* R8 - Anti Pop Control */
- { 9, 0x01DB }, /* R9 - Analogue Speaker 1 */
- { 10, 0x0018 }, /* R10 - Analogue Speaker 2 */
- { 11, 0x0180 }, /* R11 - Power Management */
- { 12, 0x0000 }, /* R12 - Clock Control 1 */
- { 13, 0x0038 }, /* R13 - Clock Control 2 */
- { 14, 0x4000 }, /* R14 - Clock Control 3 */
- { 16, 0x0000 }, /* R16 - FLL Control 1 */
- { 17, 0x0200 }, /* R17 - FLL Control 2 */
- { 18, 0x0000 }, /* R18 - FLL Control 3 */
- { 19, 0x0204 }, /* R19 - FLL Control 4 */
- { 20, 0x0000 }, /* R20 - FLL Control 5 */
- { 22, 0x0000 }, /* R22 - Audio Interface 1 */
- { 23, 0x0002 }, /* R23 - Audio Interface 2 */
- { 24, 0x0008 }, /* R24 - Audio Interface 3 */
- { 25, 0x0022 }, /* R25 - Audio Interface 4 */
- { 27, 0x0006 }, /* R27 - Interrupt Status Mask */
- { 28, 0x0000 }, /* R28 - Interrupt Polarity */
- { 29, 0x0000 }, /* R29 - Interrupt Control */
- { 30, 0x00C0 }, /* R30 - DAC Digital 1 */
- { 31, 0x0008 }, /* R31 - DAC Digital 2 */
- { 32, 0x09AF }, /* R32 - DRC 1 */
- { 33, 0x4201 }, /* R33 - DRC 2 */
- { 34, 0x0000 }, /* R34 - DRC 3 */
- { 35, 0x0000 }, /* R35 - DRC 4 */
- { 38, 0x0000 }, /* R38 - Write Sequencer 1 */
- { 39, 0x0000 }, /* R39 - Write Sequencer 2 */
- { 40, 0x0002 }, /* R40 - MW Slave 1 */
- { 42, 0x0000 }, /* R42 - EQ 1 */
- { 43, 0x0000 }, /* R43 - EQ 2 */
- { 44, 0x0FCA }, /* R44 - EQ 3 */
- { 45, 0x0400 }, /* R45 - EQ 4 */
- { 46, 0x00B8 }, /* R46 - EQ 5 */
- { 47, 0x1EB5 }, /* R47 - EQ 6 */
- { 48, 0xF145 }, /* R48 - EQ 7 */
- { 49, 0x0B75 }, /* R49 - EQ 8 */
- { 50, 0x01C5 }, /* R50 - EQ 9 */
- { 51, 0x169E }, /* R51 - EQ 10 */
- { 52, 0xF829 }, /* R52 - EQ 11 */
- { 53, 0x07AD }, /* R53 - EQ 12 */
- { 54, 0x1103 }, /* R54 - EQ 13 */
- { 55, 0x1C58 }, /* R55 - EQ 14 */
- { 56, 0xF373 }, /* R56 - EQ 15 */
- { 57, 0x0A54 }, /* R57 - EQ 16 */
- { 58, 0x0558 }, /* R58 - EQ 17 */
- { 59, 0x0564 }, /* R59 - EQ 18 */
- { 60, 0x0559 }, /* R60 - EQ 19 */
- { 61, 0x4000 }, /* R61 - EQ 20 */
-};
-
-static struct {
- int ratio;
- int clk_sys_rate;
-} clk_sys_rates[] = {
- { 64, 0 },
- { 128, 1 },
- { 192, 2 },
- { 256, 3 },
- { 384, 4 },
- { 512, 5 },
- { 768, 6 },
- { 1024, 7 },
- { 1408, 8 },
- { 1536, 9 },
-};
-
-static struct {
- int rate;
- int sample_rate;
-} sample_rates[] = {
- { 8000, 0 },
- { 11025, 1 },
- { 12000, 2 },
- { 16000, 3 },
- { 22050, 4 },
- { 24000, 5 },
- { 32000, 6 },
- { 44100, 7 },
- { 48000, 8 },
- { 88200, 9 },
- { 96000, 10 },
-};
-
-static struct {
- int div; /* *10 due to .5s */
- int bclk_div;
-} bclk_divs[] = {
- { 10, 0 },
- { 15, 1 },
- { 20, 2 },
- { 30, 3 },
- { 40, 4 },
- { 50, 5 },
- { 55, 6 },
- { 60, 7 },
- { 80, 8 },
- { 100, 9 },
- { 110, 10 },
- { 120, 11 },
- { 160, 12 },
- { 200, 13 },
- { 220, 14 },
- { 240, 15 },
- { 250, 16 },
- { 300, 17 },
- { 320, 18 },
- { 440, 19 },
- { 480, 20 },
-};
-
-struct wm9081_priv {
- struct regmap *regmap;
- int sysclk_source;
- int mclk_rate;
- int sysclk_rate;
- int fs;
- int bclk;
- int master;
- int fll_fref;
- int fll_fout;
- int tdm_width;
- struct wm9081_pdata pdata;
-};
-
-static bool wm9081_volatile_register(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM9081_SOFTWARE_RESET:
- case WM9081_INTERRUPT_STATUS:
- return true;
- default:
- return false;
- }
-}
-
-static bool wm9081_readable_register(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM9081_SOFTWARE_RESET:
- case WM9081_ANALOGUE_LINEOUT:
- case WM9081_ANALOGUE_SPEAKER_PGA:
- case WM9081_VMID_CONTROL:
- case WM9081_BIAS_CONTROL_1:
- case WM9081_ANALOGUE_MIXER:
- case WM9081_ANTI_POP_CONTROL:
- case WM9081_ANALOGUE_SPEAKER_1:
- case WM9081_ANALOGUE_SPEAKER_2:
- case WM9081_POWER_MANAGEMENT:
- case WM9081_CLOCK_CONTROL_1:
- case WM9081_CLOCK_CONTROL_2:
- case WM9081_CLOCK_CONTROL_3:
- case WM9081_FLL_CONTROL_1:
- case WM9081_FLL_CONTROL_2:
- case WM9081_FLL_CONTROL_3:
- case WM9081_FLL_CONTROL_4:
- case WM9081_FLL_CONTROL_5:
- case WM9081_AUDIO_INTERFACE_1:
- case WM9081_AUDIO_INTERFACE_2:
- case WM9081_AUDIO_INTERFACE_3:
- case WM9081_AUDIO_INTERFACE_4:
- case WM9081_INTERRUPT_STATUS:
- case WM9081_INTERRUPT_STATUS_MASK:
- case WM9081_INTERRUPT_POLARITY:
- case WM9081_INTERRUPT_CONTROL:
- case WM9081_DAC_DIGITAL_1:
- case WM9081_DAC_DIGITAL_2:
- case WM9081_DRC_1:
- case WM9081_DRC_2:
- case WM9081_DRC_3:
- case WM9081_DRC_4:
- case WM9081_WRITE_SEQUENCER_1:
- case WM9081_WRITE_SEQUENCER_2:
- case WM9081_MW_SLAVE_1:
- case WM9081_EQ_1:
- case WM9081_EQ_2:
- case WM9081_EQ_3:
- case WM9081_EQ_4:
- case WM9081_EQ_5:
- case WM9081_EQ_6:
- case WM9081_EQ_7:
- case WM9081_EQ_8:
- case WM9081_EQ_9:
- case WM9081_EQ_10:
- case WM9081_EQ_11:
- case WM9081_EQ_12:
- case WM9081_EQ_13:
- case WM9081_EQ_14:
- case WM9081_EQ_15:
- case WM9081_EQ_16:
- case WM9081_EQ_17:
- case WM9081_EQ_18:
- case WM9081_EQ_19:
- case WM9081_EQ_20:
- return true;
- default:
- return false;
- }
-}
-
-static int wm9081_reset(struct regmap *map)
-{
- return regmap_write(map, WM9081_SOFTWARE_RESET, 0x9081);
-}
-
-static const DECLARE_TLV_DB_SCALE(drc_in_tlv, -4500, 75, 0);
-static const DECLARE_TLV_DB_SCALE(drc_out_tlv, -2250, 75, 0);
-static const DECLARE_TLV_DB_SCALE(drc_min_tlv, -1800, 600, 0);
-static unsigned int drc_max_tlv[] = {
- TLV_DB_RANGE_HEAD(4),
- 0, 0, TLV_DB_SCALE_ITEM(1200, 0, 0),
- 1, 1, TLV_DB_SCALE_ITEM(1800, 0, 0),
- 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
- 3, 3, TLV_DB_SCALE_ITEM(3600, 0, 0),
-};
-static const DECLARE_TLV_DB_SCALE(drc_qr_tlv, 1200, 600, 0);
-static const DECLARE_TLV_DB_SCALE(drc_startup_tlv, -300, 50, 0);
-
-static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
-
-static const DECLARE_TLV_DB_SCALE(in_tlv, -600, 600, 0);
-static const DECLARE_TLV_DB_SCALE(dac_tlv, -7200, 75, 1);
-static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
-
-static const char *drc_high_text[] = {
- "1",
- "1/2",
- "1/4",
- "1/8",
- "1/16",
- "0",
-};
-
-static const struct soc_enum drc_high =
- SOC_ENUM_SINGLE(WM9081_DRC_3, 3, 6, drc_high_text);
-
-static const char *drc_low_text[] = {
- "1",
- "1/2",
- "1/4",
- "1/8",
- "0",
-};
-
-static const struct soc_enum drc_low =
- SOC_ENUM_SINGLE(WM9081_DRC_3, 0, 5, drc_low_text);
-
-static const char *drc_atk_text[] = {
- "181us",
- "181us",
- "363us",
- "726us",
- "1.45ms",
- "2.9ms",
- "5.8ms",
- "11.6ms",
- "23.2ms",
- "46.4ms",
- "92.8ms",
- "185.6ms",
-};
-
-static const struct soc_enum drc_atk =
- SOC_ENUM_SINGLE(WM9081_DRC_2, 12, 12, drc_atk_text);
-
-static const char *drc_dcy_text[] = {
- "186ms",
- "372ms",
- "743ms",
- "1.49s",
- "2.97s",
- "5.94s",
- "11.89s",
- "23.78s",
- "47.56s",
-};
-
-static const struct soc_enum drc_dcy =
- SOC_ENUM_SINGLE(WM9081_DRC_2, 8, 9, drc_dcy_text);
-
-static const char *drc_qr_dcy_text[] = {
- "0.725ms",
- "1.45ms",
- "5.8ms",
-};
-
-static const struct soc_enum drc_qr_dcy =
- SOC_ENUM_SINGLE(WM9081_DRC_2, 4, 3, drc_qr_dcy_text);
-
-static const char *dac_deemph_text[] = {
- "None",
- "32kHz",
- "44.1kHz",
- "48kHz",
-};
-
-static const struct soc_enum dac_deemph =
- SOC_ENUM_SINGLE(WM9081_DAC_DIGITAL_2, 1, 4, dac_deemph_text);
-
-static const char *speaker_mode_text[] = {
- "Class D",
- "Class AB",
-};
-
-static const struct soc_enum speaker_mode =
- SOC_ENUM_SINGLE(WM9081_ANALOGUE_SPEAKER_2, 6, 2, speaker_mode_text);
-
-static int speaker_mode_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int reg;
-
- reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_2);
- if (reg & WM9081_SPK_MODE)
- ucontrol->value.integer.value[0] = 1;
- else
- ucontrol->value.integer.value[0] = 0;
-
- return 0;
-}
-
-/*
- * Stop any attempts to change speaker mode while the speaker is enabled.
- *
- * We also have some special anti-pop controls dependent on speaker
- * mode which must be changed along with the mode.
- */
-static int speaker_mode_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int reg_pwr = snd_soc_read(codec, WM9081_POWER_MANAGEMENT);
- unsigned int reg2 = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_2);
-
- /* Are we changing anything? */
- if (ucontrol->value.integer.value[0] ==
- ((reg2 & WM9081_SPK_MODE) != 0))
- return 0;
-
- /* Don't try to change modes while enabled */
- if (reg_pwr & WM9081_SPK_ENA)
- return -EINVAL;
-
- if (ucontrol->value.integer.value[0]) {
- /* Class AB */
- reg2 &= ~(WM9081_SPK_INV_MUTE | WM9081_OUT_SPK_CTRL);
- reg2 |= WM9081_SPK_MODE;
- } else {
- /* Class D */
- reg2 |= WM9081_SPK_INV_MUTE | WM9081_OUT_SPK_CTRL;
- reg2 &= ~WM9081_SPK_MODE;
- }
-
- snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_2, reg2);
-
- return 0;
-}
-
-static const struct snd_kcontrol_new wm9081_snd_controls[] = {
-SOC_SINGLE_TLV("IN1 Volume", WM9081_ANALOGUE_MIXER, 1, 1, 1, in_tlv),
-SOC_SINGLE_TLV("IN2 Volume", WM9081_ANALOGUE_MIXER, 3, 1, 1, in_tlv),
-
-SOC_SINGLE_TLV("Playback Volume", WM9081_DAC_DIGITAL_1, 1, 96, 0, dac_tlv),
-
-SOC_SINGLE("LINEOUT Switch", WM9081_ANALOGUE_LINEOUT, 7, 1, 1),
-SOC_SINGLE("LINEOUT ZC Switch", WM9081_ANALOGUE_LINEOUT, 6, 1, 0),
-SOC_SINGLE_TLV("LINEOUT Volume", WM9081_ANALOGUE_LINEOUT, 0, 63, 0, out_tlv),
-
-SOC_SINGLE("DRC Switch", WM9081_DRC_1, 15, 1, 0),
-SOC_ENUM("DRC High Slope", drc_high),
-SOC_ENUM("DRC Low Slope", drc_low),
-SOC_SINGLE_TLV("DRC Input Volume", WM9081_DRC_4, 5, 60, 1, drc_in_tlv),
-SOC_SINGLE_TLV("DRC Output Volume", WM9081_DRC_4, 0, 30, 1, drc_out_tlv),
-SOC_SINGLE_TLV("DRC Minimum Volume", WM9081_DRC_2, 2, 3, 1, drc_min_tlv),
-SOC_SINGLE_TLV("DRC Maximum Volume", WM9081_DRC_2, 0, 3, 0, drc_max_tlv),
-SOC_ENUM("DRC Attack", drc_atk),
-SOC_ENUM("DRC Decay", drc_dcy),
-SOC_SINGLE("DRC Quick Release Switch", WM9081_DRC_1, 2, 1, 0),
-SOC_SINGLE_TLV("DRC Quick Release Volume", WM9081_DRC_2, 6, 3, 0, drc_qr_tlv),
-SOC_ENUM("DRC Quick Release Decay", drc_qr_dcy),
-SOC_SINGLE_TLV("DRC Startup Volume", WM9081_DRC_1, 6, 18, 0, drc_startup_tlv),
-
-SOC_SINGLE("EQ Switch", WM9081_EQ_1, 0, 1, 0),
-
-SOC_SINGLE("Speaker DC Volume", WM9081_ANALOGUE_SPEAKER_1, 3, 5, 0),
-SOC_SINGLE("Speaker AC Volume", WM9081_ANALOGUE_SPEAKER_1, 0, 5, 0),
-SOC_SINGLE("Speaker Switch", WM9081_ANALOGUE_SPEAKER_PGA, 7, 1, 1),
-SOC_SINGLE("Speaker ZC Switch", WM9081_ANALOGUE_SPEAKER_PGA, 6, 1, 0),
-SOC_SINGLE_TLV("Speaker Volume", WM9081_ANALOGUE_SPEAKER_PGA, 0, 63, 0,
- out_tlv),
-SOC_ENUM("DAC Deemphasis", dac_deemph),
-SOC_ENUM_EXT("Speaker Mode", speaker_mode, speaker_mode_get, speaker_mode_put),
-};
-
-static const struct snd_kcontrol_new wm9081_eq_controls[] = {
-SOC_SINGLE_TLV("EQ1 Volume", WM9081_EQ_1, 11, 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ2 Volume", WM9081_EQ_1, 6, 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ3 Volume", WM9081_EQ_1, 1, 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ4 Volume", WM9081_EQ_2, 11, 24, 0, eq_tlv),
-SOC_SINGLE_TLV("EQ5 Volume", WM9081_EQ_2, 6, 24, 0, eq_tlv),
-};
-
-static const struct snd_kcontrol_new mixer[] = {
-SOC_DAPM_SINGLE("IN1 Switch", WM9081_ANALOGUE_MIXER, 0, 1, 0),
-SOC_DAPM_SINGLE("IN2 Switch", WM9081_ANALOGUE_MIXER, 2, 1, 0),
-SOC_DAPM_SINGLE("Playback Switch", WM9081_ANALOGUE_MIXER, 4, 1, 0),
-};
-
-struct _fll_div {
- u16 fll_fratio;
- u16 fll_outdiv;
- u16 fll_clk_ref_div;
- u16 n;
- u16 k;
-};
-
-/* The size in bits of the FLL divide multiplied by 10
- * to allow rounding later */
-#define FIXED_FLL_SIZE ((1 << 16) * 10)
-
-static struct {
- unsigned int min;
- unsigned int max;
- u16 fll_fratio;
- int ratio;
-} fll_fratios[] = {
- { 0, 64000, 4, 16 },
- { 64000, 128000, 3, 8 },
- { 128000, 256000, 2, 4 },
- { 256000, 1000000, 1, 2 },
- { 1000000, 13500000, 0, 1 },
-};
-
-static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
- unsigned int Fout)
-{
- u64 Kpart;
- unsigned int K, Ndiv, Nmod, target;
- unsigned int div;
- int i;
-
- /* Fref must be <=13.5MHz */
- div = 1;
- while ((Fref / div) > 13500000) {
- div *= 2;
-
- if (div > 8) {
- pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
- Fref);
- return -EINVAL;
- }
- }
- fll_div->fll_clk_ref_div = div / 2;
-
- pr_debug("Fref=%u Fout=%u\n", Fref, Fout);
-
- /* Apply the division for our remaining calculations */
- Fref /= div;
-
- /* Fvco should be 90-100MHz; don't check the upper bound */
- div = 0;
- target = Fout * 2;
- while (target < 90000000) {
- div++;
- target *= 2;
- if (div > 7) {
- pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
- Fout);
- return -EINVAL;
- }
- }
- fll_div->fll_outdiv = div;
-
- pr_debug("Fvco=%dHz\n", target);
-
- /* Find an appropriate FLL_FRATIO and factor it out of the target */
- for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
- if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
- fll_div->fll_fratio = fll_fratios[i].fll_fratio;
- target /= fll_fratios[i].ratio;
- break;
- }
- }
- if (i == ARRAY_SIZE(fll_fratios)) {
- pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
- return -EINVAL;
- }
-
- /* Now, calculate N.K */
- Ndiv = target / Fref;
-
- fll_div->n = Ndiv;
- Nmod = target % Fref;
- pr_debug("Nmod=%d\n", Nmod);
-
- /* Calculate fractional part - scale up so we can round. */
- Kpart = FIXED_FLL_SIZE * (long long)Nmod;
-
- do_div(Kpart, Fref);
-
- K = Kpart & 0xFFFFFFFF;
-
- if ((K % 10) >= 5)
- K += 5;
-
- /* Move down to proper range now rounding is done */
- fll_div->k = K / 10;
-
- pr_debug("N=%x K=%x FLL_FRATIO=%x FLL_OUTDIV=%x FLL_CLK_REF_DIV=%x\n",
- fll_div->n, fll_div->k,
- fll_div->fll_fratio, fll_div->fll_outdiv,
- fll_div->fll_clk_ref_div);
-
- return 0;
-}
-
-static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id,
- unsigned int Fref, unsigned int Fout)
-{
- struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
- u16 reg1, reg4, reg5;
- struct _fll_div fll_div;
- int ret;
- int clk_sys_reg;
-
- /* Any change? */
- if (Fref == wm9081->fll_fref && Fout == wm9081->fll_fout)
- return 0;
-
- /* Disable the FLL */
- if (Fout == 0) {
- dev_dbg(codec->dev, "FLL disabled\n");
- wm9081->fll_fref = 0;
- wm9081->fll_fout = 0;
-
- return 0;
- }
-
- ret = fll_factors(&fll_div, Fref, Fout);
- if (ret != 0)
- return ret;
-
- reg5 = snd_soc_read(codec, WM9081_FLL_CONTROL_5);
- reg5 &= ~WM9081_FLL_CLK_SRC_MASK;
-
- switch (fll_id) {
- case WM9081_SYSCLK_FLL_MCLK:
- reg5 |= 0x1;
- break;
-
- default:
- dev_err(codec->dev, "Unknown FLL ID %d\n", fll_id);
- return -EINVAL;
- }
-
- /* Disable CLK_SYS while we reconfigure */
- clk_sys_reg = snd_soc_read(codec, WM9081_CLOCK_CONTROL_3);
- if (clk_sys_reg & WM9081_CLK_SYS_ENA)
- snd_soc_write(codec, WM9081_CLOCK_CONTROL_3,
- clk_sys_reg & ~WM9081_CLK_SYS_ENA);
-
- /* Any FLL configuration change requires that the FLL be
- * disabled first. */
- reg1 = snd_soc_read(codec, WM9081_FLL_CONTROL_1);
- reg1 &= ~WM9081_FLL_ENA;
- snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1);
-
- /* Apply the configuration */
- if (fll_div.k)
- reg1 |= WM9081_FLL_FRAC_MASK;
- else
- reg1 &= ~WM9081_FLL_FRAC_MASK;
- snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1);
-
- snd_soc_write(codec, WM9081_FLL_CONTROL_2,
- (fll_div.fll_outdiv << WM9081_FLL_OUTDIV_SHIFT) |
- (fll_div.fll_fratio << WM9081_FLL_FRATIO_SHIFT));
- snd_soc_write(codec, WM9081_FLL_CONTROL_3, fll_div.k);
-
- reg4 = snd_soc_read(codec, WM9081_FLL_CONTROL_4);
- reg4 &= ~WM9081_FLL_N_MASK;
- reg4 |= fll_div.n << WM9081_FLL_N_SHIFT;
- snd_soc_write(codec, WM9081_FLL_CONTROL_4, reg4);
-
- reg5 &= ~WM9081_FLL_CLK_REF_DIV_MASK;
- reg5 |= fll_div.fll_clk_ref_div << WM9081_FLL_CLK_REF_DIV_SHIFT;
- snd_soc_write(codec, WM9081_FLL_CONTROL_5, reg5);
-
- /* Set gain to the recommended value */
- snd_soc_update_bits(codec, WM9081_FLL_CONTROL_4,
- WM9081_FLL_GAIN_MASK, 0);
-
- /* Enable the FLL */
- snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1 | WM9081_FLL_ENA);
-
- /* Then bring CLK_SYS up again if it was disabled */
- if (clk_sys_reg & WM9081_CLK_SYS_ENA)
- snd_soc_write(codec, WM9081_CLOCK_CONTROL_3, clk_sys_reg);
-
- dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout);
-
- wm9081->fll_fref = Fref;
- wm9081->fll_fout = Fout;
-
- return 0;
-}
-
-static int configure_clock(struct snd_soc_codec *codec)
-{
- struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
- int new_sysclk, i, target;
- unsigned int reg;
- int ret = 0;
- int mclkdiv = 0;
- int fll = 0;
-
- switch (wm9081->sysclk_source) {
- case WM9081_SYSCLK_MCLK:
- if (wm9081->mclk_rate > 12225000) {
- mclkdiv = 1;
- wm9081->sysclk_rate = wm9081->mclk_rate / 2;
- } else {
- wm9081->sysclk_rate = wm9081->mclk_rate;
- }
- wm9081_set_fll(codec, WM9081_SYSCLK_FLL_MCLK, 0, 0);
- break;
-
- case WM9081_SYSCLK_FLL_MCLK:
- /* If we have a sample rate calculate a CLK_SYS that
- * gives us a suitable DAC configuration, plus BCLK.
- * Ideally we would check to see if we can clock
- * directly from MCLK and only use the FLL if this is
- * not the case, though care must be taken with free
- * running mode.
- */
- if (wm9081->master && wm9081->bclk) {
- /* Make sure we can generate CLK_SYS and BCLK
- * and that we've got 3MHz for optimal
- * performance. */
- for (i = 0; i < ARRAY_SIZE(clk_sys_rates); i++) {
- target = wm9081->fs * clk_sys_rates[i].ratio;
- new_sysclk = target;
- if (target >= wm9081->bclk &&
- target > 3000000)
- break;
- }
-
- if (i == ARRAY_SIZE(clk_sys_rates))
- return -EINVAL;
-
- } else if (wm9081->fs) {
- for (i = 0; i < ARRAY_SIZE(clk_sys_rates); i++) {
- new_sysclk = clk_sys_rates[i].ratio
- * wm9081->fs;
- if (new_sysclk > 3000000)
- break;
- }
-
- if (i == ARRAY_SIZE(clk_sys_rates))
- return -EINVAL;
-
- } else {
- new_sysclk = 12288000;
- }
-
- ret = wm9081_set_fll(codec, WM9081_SYSCLK_FLL_MCLK,
- wm9081->mclk_rate, new_sysclk);
- if (ret == 0) {
- wm9081->sysclk_rate = new_sysclk;
-
- /* Switch SYSCLK over to FLL */
- fll = 1;
- } else {
- wm9081->sysclk_rate = wm9081->mclk_rate;
- }
- break;
-
- default:
- return -EINVAL;
- }
-
- reg = snd_soc_read(codec, WM9081_CLOCK_CONTROL_1);
- if (mclkdiv)
- reg |= WM9081_MCLKDIV2;
- else
- reg &= ~WM9081_MCLKDIV2;
- snd_soc_write(codec, WM9081_CLOCK_CONTROL_1, reg);
-
- reg = snd_soc_read(codec, WM9081_CLOCK_CONTROL_3);
- if (fll)
- reg |= WM9081_CLK_SRC_SEL;
- else
- reg &= ~WM9081_CLK_SRC_SEL;
- snd_soc_write(codec, WM9081_CLOCK_CONTROL_3, reg);
-
- dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm9081->sysclk_rate);
-
- return ret;
-}
-
-static int clk_sys_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
-
- /* This should be done on init() for bypass paths */
- switch (wm9081->sysclk_source) {
- case WM9081_SYSCLK_MCLK:
- dev_dbg(codec->dev, "Using %dHz MCLK\n", wm9081->mclk_rate);
- break;
- case WM9081_SYSCLK_FLL_MCLK:
- dev_dbg(codec->dev, "Using %dHz MCLK with FLL\n",
- wm9081->mclk_rate);
- break;
- default:
- dev_err(codec->dev, "System clock not configured\n");
- return -EINVAL;
- }
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- configure_clock(codec);
- break;
-
- case SND_SOC_DAPM_POST_PMD:
- /* Disable the FLL if it's running */
- wm9081_set_fll(codec, 0, 0, 0);
- break;
- }
-
- return 0;
-}
-
-static const struct snd_soc_dapm_widget wm9081_dapm_widgets[] = {
-SND_SOC_DAPM_INPUT("IN1"),
-SND_SOC_DAPM_INPUT("IN2"),
-
-SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM9081_POWER_MANAGEMENT, 0, 0),
-
-SND_SOC_DAPM_MIXER_NAMED_CTL("Mixer", SND_SOC_NOPM, 0, 0,
- mixer, ARRAY_SIZE(mixer)),
-
-SND_SOC_DAPM_PGA("LINEOUT PGA", WM9081_POWER_MANAGEMENT, 4, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA("Speaker PGA", WM9081_POWER_MANAGEMENT, 2, 0, NULL, 0),
-SND_SOC_DAPM_OUT_DRV("Speaker", WM9081_POWER_MANAGEMENT, 1, 0, NULL, 0),
-
-SND_SOC_DAPM_OUTPUT("LINEOUT"),
-SND_SOC_DAPM_OUTPUT("SPKN"),
-SND_SOC_DAPM_OUTPUT("SPKP"),
-
-SND_SOC_DAPM_SUPPLY("CLK_SYS", WM9081_CLOCK_CONTROL_3, 0, 0, clk_sys_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-SND_SOC_DAPM_SUPPLY("CLK_DSP", WM9081_CLOCK_CONTROL_3, 1, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("TOCLK", WM9081_CLOCK_CONTROL_3, 2, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("TSENSE", WM9081_POWER_MANAGEMENT, 7, 0, NULL, 0),
-};
-
-
-static const struct snd_soc_dapm_route wm9081_audio_paths[] = {
- { "DAC", NULL, "CLK_SYS" },
- { "DAC", NULL, "CLK_DSP" },
-
- { "Mixer", "IN1 Switch", "IN1" },
- { "Mixer", "IN2 Switch", "IN2" },
- { "Mixer", "Playback Switch", "DAC" },
-
- { "LINEOUT PGA", NULL, "Mixer" },
- { "LINEOUT PGA", NULL, "TOCLK" },
- { "LINEOUT PGA", NULL, "CLK_SYS" },
-
- { "LINEOUT", NULL, "LINEOUT PGA" },
-
- { "Speaker PGA", NULL, "Mixer" },
- { "Speaker PGA", NULL, "TOCLK" },
- { "Speaker PGA", NULL, "CLK_SYS" },
-
- { "Speaker", NULL, "Speaker PGA" },
- { "Speaker", NULL, "TSENSE" },
-
- { "SPKN", NULL, "Speaker" },
- { "SPKP", NULL, "Speaker" },
-};
-
-static int wm9081_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- /* VMID=2*40k */
- snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
- WM9081_VMID_SEL_MASK, 0x2);
-
- /* Normal bias current */
- snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
- WM9081_STBY_BIAS_ENA, 0);
- break;
-
- case SND_SOC_BIAS_STANDBY:
- /* Initial cold start */
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- regcache_cache_only(wm9081->regmap, false);
- regcache_sync(wm9081->regmap);
-
- /* Disable LINEOUT discharge */
- snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL,
- WM9081_LINEOUT_DISCH, 0);
-
- /* Select startup bias source */
- snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
- WM9081_BIAS_SRC | WM9081_BIAS_ENA,
- WM9081_BIAS_SRC | WM9081_BIAS_ENA);
-
- /* VMID 2*4k; Soft VMID ramp enable */
- snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
- WM9081_VMID_RAMP |
- WM9081_VMID_SEL_MASK,
- WM9081_VMID_RAMP | 0x6);
-
- mdelay(100);
-
- /* Normal bias enable & soft start off */
- snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
- WM9081_VMID_RAMP, 0);
-
- /* Standard bias source */
- snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
- WM9081_BIAS_SRC, 0);
- }
-
- /* VMID 2*240k */
- snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
- WM9081_VMID_SEL_MASK, 0x04);
-
- /* Standby bias current on */
- snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
- WM9081_STBY_BIAS_ENA,
- WM9081_STBY_BIAS_ENA);
- break;
-
- case SND_SOC_BIAS_OFF:
- /* Startup bias source and disable bias */
- snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
- WM9081_BIAS_SRC | WM9081_BIAS_ENA,
- WM9081_BIAS_SRC);
-
- /* Disable VMID with soft ramping */
- snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
- WM9081_VMID_RAMP | WM9081_VMID_SEL_MASK,
- WM9081_VMID_RAMP);
-
- /* Actively discharge LINEOUT */
- snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL,
- WM9081_LINEOUT_DISCH,
- WM9081_LINEOUT_DISCH);
-
- regcache_cache_only(wm9081->regmap, true);
- break;
- }
-
- codec->dapm.bias_level = level;
-
- return 0;
-}
-
-static int wm9081_set_dai_fmt(struct snd_soc_dai *dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
- unsigned int aif2 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_2);
-
- aif2 &= ~(WM9081_AIF_BCLK_INV | WM9081_AIF_LRCLK_INV |
- WM9081_BCLK_DIR | WM9081_LRCLK_DIR | WM9081_AIF_FMT_MASK);
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- wm9081->master = 0;
- break;
- case SND_SOC_DAIFMT_CBS_CFM:
- aif2 |= WM9081_LRCLK_DIR;
- wm9081->master = 1;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- aif2 |= WM9081_BCLK_DIR;
- wm9081->master = 1;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- aif2 |= WM9081_LRCLK_DIR | WM9081_BCLK_DIR;
- wm9081->master = 1;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_B:
- aif2 |= WM9081_AIF_LRCLK_INV;
- case SND_SOC_DAIFMT_DSP_A:
- aif2 |= 0x3;
- break;
- case SND_SOC_DAIFMT_I2S:
- aif2 |= 0x2;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- aif2 |= 0x1;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- case SND_SOC_DAIFMT_DSP_B:
- /* frame inversion not valid for DSP modes */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_NF:
- aif2 |= WM9081_AIF_BCLK_INV;
- break;
- default:
- return -EINVAL;
- }
- break;
-
- case SND_SOC_DAIFMT_I2S:
- case SND_SOC_DAIFMT_RIGHT_J:
- case SND_SOC_DAIFMT_LEFT_J:
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- aif2 |= WM9081_AIF_BCLK_INV | WM9081_AIF_LRCLK_INV;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- aif2 |= WM9081_AIF_BCLK_INV;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- aif2 |= WM9081_AIF_LRCLK_INV;
- break;
- default:
- return -EINVAL;
- }
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM9081_AUDIO_INTERFACE_2, aif2);
-
- return 0;
-}
-
-static int wm9081_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
- int ret, i, best, best_val, cur_val;
- unsigned int clk_ctrl2, aif1, aif2, aif3, aif4;
-
- clk_ctrl2 = snd_soc_read(codec, WM9081_CLOCK_CONTROL_2);
- clk_ctrl2 &= ~(WM9081_CLK_SYS_RATE_MASK | WM9081_SAMPLE_RATE_MASK);
-
- aif1 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_1);
-
- aif2 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_2);
- aif2 &= ~WM9081_AIF_WL_MASK;
-
- aif3 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_3);
- aif3 &= ~WM9081_BCLK_DIV_MASK;
-
- aif4 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_4);
- aif4 &= ~WM9081_LRCLK_RATE_MASK;
-
- wm9081->fs = params_rate(params);
-
- if (wm9081->tdm_width) {
- /* If TDM is set up then that fixes our BCLK. */
- int slots = ((aif1 & WM9081_AIFDAC_TDM_MODE_MASK) >>
- WM9081_AIFDAC_TDM_MODE_SHIFT) + 1;
-
- wm9081->bclk = wm9081->fs * wm9081->tdm_width * slots;
- } else {
- /* Otherwise work out a BCLK from the sample size */
- wm9081->bclk = 2 * wm9081->fs;
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- wm9081->bclk *= 16;
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- wm9081->bclk *= 20;
- aif2 |= 0x4;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- wm9081->bclk *= 24;
- aif2 |= 0x8;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- wm9081->bclk *= 32;
- aif2 |= 0xc;
- break;
- default:
- return -EINVAL;
- }
- }
-
- dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm9081->bclk);
-
- ret = configure_clock(codec);
- if (ret != 0)
- return ret;
-
- /* Select nearest CLK_SYS_RATE */
- best = 0;
- best_val = abs((wm9081->sysclk_rate / clk_sys_rates[0].ratio)
- - wm9081->fs);
- for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
- cur_val = abs((wm9081->sysclk_rate /
- clk_sys_rates[i].ratio) - wm9081->fs);
- if (cur_val < best_val) {
- best = i;
- best_val = cur_val;
- }
- }
- dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n",
- clk_sys_rates[best].ratio);
- clk_ctrl2 |= (clk_sys_rates[best].clk_sys_rate
- << WM9081_CLK_SYS_RATE_SHIFT);
-
- /* SAMPLE_RATE */
- best = 0;
- best_val = abs(wm9081->fs - sample_rates[0].rate);
- for (i = 1; i < ARRAY_SIZE(sample_rates); i++) {
- /* Closest match */
- cur_val = abs(wm9081->fs - sample_rates[i].rate);
- if (cur_val < best_val) {
- best = i;
- best_val = cur_val;
- }
- }
- dev_dbg(codec->dev, "Selected SAMPLE_RATE of %dHz\n",
- sample_rates[best].rate);
- clk_ctrl2 |= (sample_rates[best].sample_rate
- << WM9081_SAMPLE_RATE_SHIFT);
-
- /* BCLK_DIV */
- best = 0;
- best_val = INT_MAX;
- for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
- cur_val = ((wm9081->sysclk_rate * 10) / bclk_divs[i].div)
- - wm9081->bclk;
- if (cur_val < 0) /* Table is sorted */
- break;
- if (cur_val < best_val) {
- best = i;
- best_val = cur_val;
- }
- }
- wm9081->bclk = (wm9081->sysclk_rate * 10) / bclk_divs[best].div;
- dev_dbg(codec->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n",
- bclk_divs[best].div, wm9081->bclk);
- aif3 |= bclk_divs[best].bclk_div;
-
- /* LRCLK is a simple fraction of BCLK */
- dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm9081->bclk / wm9081->fs);
- aif4 |= wm9081->bclk / wm9081->fs;
-
- /* Apply a ReTune Mobile configuration if it's in use */
- if (wm9081->pdata.num_retune_configs) {
- struct wm9081_pdata *pdata = &wm9081->pdata;
- struct wm9081_retune_mobile_setting *s;
- int eq1;
-
- best = 0;
- best_val = abs(pdata->retune_configs[0].rate - wm9081->fs);
- for (i = 0; i < pdata->num_retune_configs; i++) {
- cur_val = abs(pdata->retune_configs[i].rate -
- wm9081->fs);
- if (cur_val < best_val) {
- best_val = cur_val;
- best = i;
- }
- }
- s = &pdata->retune_configs[best];
-
- dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n",
- s->name, s->rate);
-
- /* If the EQ is enabled then disable it while we write out */
- eq1 = snd_soc_read(codec, WM9081_EQ_1) & WM9081_EQ_ENA;
- if (eq1 & WM9081_EQ_ENA)
- snd_soc_write(codec, WM9081_EQ_1, 0);
-
- /* Write out the other values */
- for (i = 1; i < ARRAY_SIZE(s->config); i++)
- snd_soc_write(codec, WM9081_EQ_1 + i, s->config[i]);
-
- eq1 |= (s->config[0] & ~WM9081_EQ_ENA);
- snd_soc_write(codec, WM9081_EQ_1, eq1);
- }
-
- snd_soc_write(codec, WM9081_CLOCK_CONTROL_2, clk_ctrl2);
- snd_soc_write(codec, WM9081_AUDIO_INTERFACE_2, aif2);
- snd_soc_write(codec, WM9081_AUDIO_INTERFACE_3, aif3);
- snd_soc_write(codec, WM9081_AUDIO_INTERFACE_4, aif4);
-
- return 0;
-}
-
-static int wm9081_digital_mute(struct snd_soc_dai *codec_dai, int mute)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- unsigned int reg;
-
- reg = snd_soc_read(codec, WM9081_DAC_DIGITAL_2);
-
- if (mute)
- reg |= WM9081_DAC_MUTE;
- else
- reg &= ~WM9081_DAC_MUTE;
-
- snd_soc_write(codec, WM9081_DAC_DIGITAL_2, reg);
-
- return 0;
-}
-
-static int wm9081_set_sysclk(struct snd_soc_codec *codec, int clk_id,
- int source, unsigned int freq, int dir)
-{
- struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
-
- switch (clk_id) {
- case WM9081_SYSCLK_MCLK:
- case WM9081_SYSCLK_FLL_MCLK:
- wm9081->sysclk_source = clk_id;
- wm9081->mclk_rate = freq;
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int wm9081_set_tdm_slot(struct snd_soc_dai *dai,
- unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
- unsigned int aif1 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_1);
-
- aif1 &= ~(WM9081_AIFDAC_TDM_SLOT_MASK | WM9081_AIFDAC_TDM_MODE_MASK);
-
- if (slots < 0 || slots > 4)
- return -EINVAL;
-
- wm9081->tdm_width = slot_width;
-
- if (slots == 0)
- slots = 1;
-
- aif1 |= (slots - 1) << WM9081_AIFDAC_TDM_MODE_SHIFT;
-
- switch (rx_mask) {
- case 1:
- break;
- case 2:
- aif1 |= 0x10;
- break;
- case 4:
- aif1 |= 0x20;
- break;
- case 8:
- aif1 |= 0x30;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, WM9081_AUDIO_INTERFACE_1, aif1);
-
- return 0;
-}
-
-#define WM9081_RATES SNDRV_PCM_RATE_8000_96000
-
-#define WM9081_FORMATS \
- (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops wm9081_dai_ops = {
- .hw_params = wm9081_hw_params,
- .set_fmt = wm9081_set_dai_fmt,
- .digital_mute = wm9081_digital_mute,
- .set_tdm_slot = wm9081_set_tdm_slot,
-};
-
-/* We report two channels because the CODEC processes a stereo signal, even
- * though it is only capable of handling a mono output.
- */
-static struct snd_soc_dai_driver wm9081_dai = {
- .name = "wm9081-hifi",
- .playback = {
- .stream_name = "HiFi Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM9081_RATES,
- .formats = WM9081_FORMATS,
- },
- .ops = &wm9081_dai_ops,
-};
-
-static int wm9081_probe(struct snd_soc_codec *codec)
-{
- struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- codec->control_data = wm9081->regmap;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- /* Enable zero cross by default */
- snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT,
- WM9081_LINEOUTZC, WM9081_LINEOUTZC);
- snd_soc_update_bits(codec, WM9081_ANALOGUE_SPEAKER_PGA,
- WM9081_SPKPGAZC, WM9081_SPKPGAZC);
-
- if (!wm9081->pdata.num_retune_configs) {
- dev_dbg(codec->dev,
- "No ReTune Mobile data, using normal EQ\n");
- snd_soc_add_codec_controls(codec, wm9081_eq_controls,
- ARRAY_SIZE(wm9081_eq_controls));
- }
-
- return ret;
-}
-
-static int wm9081_remove(struct snd_soc_codec *codec)
-{
- wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
- .probe = wm9081_probe,
- .remove = wm9081_remove,
-
- .set_sysclk = wm9081_set_sysclk,
- .set_bias_level = wm9081_set_bias_level,
-
- .idle_bias_off = true,
-
- .controls = wm9081_snd_controls,
- .num_controls = ARRAY_SIZE(wm9081_snd_controls),
- .dapm_widgets = wm9081_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm9081_dapm_widgets),
- .dapm_routes = wm9081_audio_paths,
- .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths),
-};
-
-static const struct regmap_config wm9081_regmap = {
- .reg_bits = 8,
- .val_bits = 16,
-
- .max_register = WM9081_MAX_REGISTER,
- .reg_defaults = wm9081_reg,
- .num_reg_defaults = ARRAY_SIZE(wm9081_reg),
- .volatile_reg = wm9081_volatile_register,
- .readable_reg = wm9081_readable_register,
- .cache_type = REGCACHE_RBTREE,
-};
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm9081_priv *wm9081;
- unsigned int reg;
- int ret;
-
- wm9081 = devm_kzalloc(&i2c->dev, sizeof(struct wm9081_priv),
- GFP_KERNEL);
- if (wm9081 == NULL)
- return -ENOMEM;
-
- i2c_set_clientdata(i2c, wm9081);
-
- wm9081->regmap = regmap_init_i2c(i2c, &wm9081_regmap);
- if (IS_ERR(wm9081->regmap)) {
- ret = PTR_ERR(wm9081->regmap);
- dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
- goto err;
- }
-
- ret = regmap_read(wm9081->regmap, WM9081_SOFTWARE_RESET, &reg);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret);
- goto err_regmap;
- }
- if (reg != 0x9081) {
- dev_err(&i2c->dev, "Device is not a WM9081: ID=0x%x\n", reg);
- ret = -EINVAL;
- goto err_regmap;
- }
-
- ret = wm9081_reset(wm9081->regmap);
- if (ret < 0) {
- dev_err(&i2c->dev, "Failed to issue reset\n");
- goto err_regmap;
- }
-
- if (dev_get_platdata(&i2c->dev))
- memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev),
- sizeof(wm9081->pdata));
-
- reg = 0;
- if (wm9081->pdata.irq_high)
- reg |= WM9081_IRQ_POL;
- if (!wm9081->pdata.irq_cmos)
- reg |= WM9081_IRQ_OP_CTRL;
- regmap_update_bits(wm9081->regmap, WM9081_INTERRUPT_CONTROL,
- WM9081_IRQ_POL | WM9081_IRQ_OP_CTRL, reg);
-
- regcache_cache_only(wm9081->regmap, true);
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm9081, &wm9081_dai, 1);
- if (ret < 0)
- goto err_regmap;
-
- return 0;
-
-err_regmap:
- regmap_exit(wm9081->regmap);
-err:
-
- return ret;
-}
-
-static __devexit int wm9081_i2c_remove(struct i2c_client *client)
-{
- struct wm9081_priv *wm9081 = i2c_get_clientdata(client);
-
- snd_soc_unregister_codec(&client->dev);
- regmap_exit(wm9081->regmap);
- return 0;
-}
-
-static const struct i2c_device_id wm9081_i2c_id[] = {
- { "wm9081", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm9081_i2c_id);
-
-static struct i2c_driver wm9081_i2c_driver = {
- .driver = {
- .name = "wm9081",
- .owner = THIS_MODULE,
- },
- .probe = wm9081_i2c_probe,
- .remove = __devexit_p(wm9081_i2c_remove),
- .id_table = wm9081_i2c_id,
-};
-#endif
-
-module_i2c_driver(wm9081_i2c_driver);
-
-MODULE_DESCRIPTION("ASoC WM9081 driver");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm9081.h b/ANDROID_3.4.5/sound/soc/codecs/wm9081.h
deleted file mode 100644
index 871cccb0..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm9081.h
+++ /dev/null
@@ -1,784 +0,0 @@
-#ifndef WM9081_H
-#define WM9081_H
-
-/*
- * wm9081.c -- WM9081 ALSA SoC Audio driver
- *
- * Author: Mark Brown
- *
- * Copyright 2009 Wolfson Microelectronics plc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <sound/soc.h>
-
-/*
- * SYSCLK sources
- */
-#define WM9081_SYSCLK_MCLK 1 /* Use MCLK without FLL */
-#define WM9081_SYSCLK_FLL_MCLK 2 /* Use MCLK, enabling FLL if required */
-
-/*
- * Register values.
- */
-#define WM9081_SOFTWARE_RESET 0x00
-#define WM9081_ANALOGUE_LINEOUT 0x02
-#define WM9081_ANALOGUE_SPEAKER_PGA 0x03
-#define WM9081_VMID_CONTROL 0x04
-#define WM9081_BIAS_CONTROL_1 0x05
-#define WM9081_ANALOGUE_MIXER 0x07
-#define WM9081_ANTI_POP_CONTROL 0x08
-#define WM9081_ANALOGUE_SPEAKER_1 0x09
-#define WM9081_ANALOGUE_SPEAKER_2 0x0A
-#define WM9081_POWER_MANAGEMENT 0x0B
-#define WM9081_CLOCK_CONTROL_1 0x0C
-#define WM9081_CLOCK_CONTROL_2 0x0D
-#define WM9081_CLOCK_CONTROL_3 0x0E
-#define WM9081_FLL_CONTROL_1 0x10
-#define WM9081_FLL_CONTROL_2 0x11
-#define WM9081_FLL_CONTROL_3 0x12
-#define WM9081_FLL_CONTROL_4 0x13
-#define WM9081_FLL_CONTROL_5 0x14
-#define WM9081_AUDIO_INTERFACE_1 0x16
-#define WM9081_AUDIO_INTERFACE_2 0x17
-#define WM9081_AUDIO_INTERFACE_3 0x18
-#define WM9081_AUDIO_INTERFACE_4 0x19
-#define WM9081_INTERRUPT_STATUS 0x1A
-#define WM9081_INTERRUPT_STATUS_MASK 0x1B
-#define WM9081_INTERRUPT_POLARITY 0x1C
-#define WM9081_INTERRUPT_CONTROL 0x1D
-#define WM9081_DAC_DIGITAL_1 0x1E
-#define WM9081_DAC_DIGITAL_2 0x1F
-#define WM9081_DRC_1 0x20
-#define WM9081_DRC_2 0x21
-#define WM9081_DRC_3 0x22
-#define WM9081_DRC_4 0x23
-#define WM9081_WRITE_SEQUENCER_1 0x26
-#define WM9081_WRITE_SEQUENCER_2 0x27
-#define WM9081_MW_SLAVE_1 0x28
-#define WM9081_EQ_1 0x2A
-#define WM9081_EQ_2 0x2B
-#define WM9081_EQ_3 0x2C
-#define WM9081_EQ_4 0x2D
-#define WM9081_EQ_5 0x2E
-#define WM9081_EQ_6 0x2F
-#define WM9081_EQ_7 0x30
-#define WM9081_EQ_8 0x31
-#define WM9081_EQ_9 0x32
-#define WM9081_EQ_10 0x33
-#define WM9081_EQ_11 0x34
-#define WM9081_EQ_12 0x35
-#define WM9081_EQ_13 0x36
-#define WM9081_EQ_14 0x37
-#define WM9081_EQ_15 0x38
-#define WM9081_EQ_16 0x39
-#define WM9081_EQ_17 0x3A
-#define WM9081_EQ_18 0x3B
-#define WM9081_EQ_19 0x3C
-#define WM9081_EQ_20 0x3D
-
-#define WM9081_REGISTER_COUNT 55
-#define WM9081_MAX_REGISTER 0x3D
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - Software Reset
- */
-#define WM9081_SW_RST_DEV_ID1_MASK 0xFFFF /* SW_RST_DEV_ID1 - [15:0] */
-#define WM9081_SW_RST_DEV_ID1_SHIFT 0 /* SW_RST_DEV_ID1 - [15:0] */
-#define WM9081_SW_RST_DEV_ID1_WIDTH 16 /* SW_RST_DEV_ID1 - [15:0] */
-
-/*
- * R2 (0x02) - Analogue Lineout
- */
-#define WM9081_LINEOUT_MUTE 0x0080 /* LINEOUT_MUTE */
-#define WM9081_LINEOUT_MUTE_MASK 0x0080 /* LINEOUT_MUTE */
-#define WM9081_LINEOUT_MUTE_SHIFT 7 /* LINEOUT_MUTE */
-#define WM9081_LINEOUT_MUTE_WIDTH 1 /* LINEOUT_MUTE */
-#define WM9081_LINEOUTZC 0x0040 /* LINEOUTZC */
-#define WM9081_LINEOUTZC_MASK 0x0040 /* LINEOUTZC */
-#define WM9081_LINEOUTZC_SHIFT 6 /* LINEOUTZC */
-#define WM9081_LINEOUTZC_WIDTH 1 /* LINEOUTZC */
-#define WM9081_LINEOUT_VOL_MASK 0x003F /* LINEOUT_VOL - [5:0] */
-#define WM9081_LINEOUT_VOL_SHIFT 0 /* LINEOUT_VOL - [5:0] */
-#define WM9081_LINEOUT_VOL_WIDTH 6 /* LINEOUT_VOL - [5:0] */
-
-/*
- * R3 (0x03) - Analogue Speaker PGA
- */
-#define WM9081_SPKPGA_MUTE 0x0080 /* SPKPGA_MUTE */
-#define WM9081_SPKPGA_MUTE_MASK 0x0080 /* SPKPGA_MUTE */
-#define WM9081_SPKPGA_MUTE_SHIFT 7 /* SPKPGA_MUTE */
-#define WM9081_SPKPGA_MUTE_WIDTH 1 /* SPKPGA_MUTE */
-#define WM9081_SPKPGAZC 0x0040 /* SPKPGAZC */
-#define WM9081_SPKPGAZC_MASK 0x0040 /* SPKPGAZC */
-#define WM9081_SPKPGAZC_SHIFT 6 /* SPKPGAZC */
-#define WM9081_SPKPGAZC_WIDTH 1 /* SPKPGAZC */
-#define WM9081_SPKPGA_VOL_MASK 0x003F /* SPKPGA_VOL - [5:0] */
-#define WM9081_SPKPGA_VOL_SHIFT 0 /* SPKPGA_VOL - [5:0] */
-#define WM9081_SPKPGA_VOL_WIDTH 6 /* SPKPGA_VOL - [5:0] */
-
-/*
- * R4 (0x04) - VMID Control
- */
-#define WM9081_VMID_BUF_ENA 0x0020 /* VMID_BUF_ENA */
-#define WM9081_VMID_BUF_ENA_MASK 0x0020 /* VMID_BUF_ENA */
-#define WM9081_VMID_BUF_ENA_SHIFT 5 /* VMID_BUF_ENA */
-#define WM9081_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
-#define WM9081_VMID_RAMP 0x0008 /* VMID_RAMP */
-#define WM9081_VMID_RAMP_MASK 0x0008 /* VMID_RAMP */
-#define WM9081_VMID_RAMP_SHIFT 3 /* VMID_RAMP */
-#define WM9081_VMID_RAMP_WIDTH 1 /* VMID_RAMP */
-#define WM9081_VMID_SEL_MASK 0x0006 /* VMID_SEL - [2:1] */
-#define WM9081_VMID_SEL_SHIFT 1 /* VMID_SEL - [2:1] */
-#define WM9081_VMID_SEL_WIDTH 2 /* VMID_SEL - [2:1] */
-#define WM9081_VMID_FAST_ST 0x0001 /* VMID_FAST_ST */
-#define WM9081_VMID_FAST_ST_MASK 0x0001 /* VMID_FAST_ST */
-#define WM9081_VMID_FAST_ST_SHIFT 0 /* VMID_FAST_ST */
-#define WM9081_VMID_FAST_ST_WIDTH 1 /* VMID_FAST_ST */
-
-/*
- * R5 (0x05) - Bias Control 1
- */
-#define WM9081_BIAS_SRC 0x0040 /* BIAS_SRC */
-#define WM9081_BIAS_SRC_MASK 0x0040 /* BIAS_SRC */
-#define WM9081_BIAS_SRC_SHIFT 6 /* BIAS_SRC */
-#define WM9081_BIAS_SRC_WIDTH 1 /* BIAS_SRC */
-#define WM9081_STBY_BIAS_LVL 0x0020 /* STBY_BIAS_LVL */
-#define WM9081_STBY_BIAS_LVL_MASK 0x0020 /* STBY_BIAS_LVL */
-#define WM9081_STBY_BIAS_LVL_SHIFT 5 /* STBY_BIAS_LVL */
-#define WM9081_STBY_BIAS_LVL_WIDTH 1 /* STBY_BIAS_LVL */
-#define WM9081_STBY_BIAS_ENA 0x0010 /* STBY_BIAS_ENA */
-#define WM9081_STBY_BIAS_ENA_MASK 0x0010 /* STBY_BIAS_ENA */
-#define WM9081_STBY_BIAS_ENA_SHIFT 4 /* STBY_BIAS_ENA */
-#define WM9081_STBY_BIAS_ENA_WIDTH 1 /* STBY_BIAS_ENA */
-#define WM9081_BIAS_LVL_MASK 0x000C /* BIAS_LVL - [3:2] */
-#define WM9081_BIAS_LVL_SHIFT 2 /* BIAS_LVL - [3:2] */
-#define WM9081_BIAS_LVL_WIDTH 2 /* BIAS_LVL - [3:2] */
-#define WM9081_BIAS_ENA 0x0002 /* BIAS_ENA */
-#define WM9081_BIAS_ENA_MASK 0x0002 /* BIAS_ENA */
-#define WM9081_BIAS_ENA_SHIFT 1 /* BIAS_ENA */
-#define WM9081_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
-#define WM9081_STARTUP_BIAS_ENA 0x0001 /* STARTUP_BIAS_ENA */
-#define WM9081_STARTUP_BIAS_ENA_MASK 0x0001 /* STARTUP_BIAS_ENA */
-#define WM9081_STARTUP_BIAS_ENA_SHIFT 0 /* STARTUP_BIAS_ENA */
-#define WM9081_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */
-
-/*
- * R7 (0x07) - Analogue Mixer
- */
-#define WM9081_DAC_SEL 0x0010 /* DAC_SEL */
-#define WM9081_DAC_SEL_MASK 0x0010 /* DAC_SEL */
-#define WM9081_DAC_SEL_SHIFT 4 /* DAC_SEL */
-#define WM9081_DAC_SEL_WIDTH 1 /* DAC_SEL */
-#define WM9081_IN2_VOL 0x0008 /* IN2_VOL */
-#define WM9081_IN2_VOL_MASK 0x0008 /* IN2_VOL */
-#define WM9081_IN2_VOL_SHIFT 3 /* IN2_VOL */
-#define WM9081_IN2_VOL_WIDTH 1 /* IN2_VOL */
-#define WM9081_IN2_ENA 0x0004 /* IN2_ENA */
-#define WM9081_IN2_ENA_MASK 0x0004 /* IN2_ENA */
-#define WM9081_IN2_ENA_SHIFT 2 /* IN2_ENA */
-#define WM9081_IN2_ENA_WIDTH 1 /* IN2_ENA */
-#define WM9081_IN1_VOL 0x0002 /* IN1_VOL */
-#define WM9081_IN1_VOL_MASK 0x0002 /* IN1_VOL */
-#define WM9081_IN1_VOL_SHIFT 1 /* IN1_VOL */
-#define WM9081_IN1_VOL_WIDTH 1 /* IN1_VOL */
-#define WM9081_IN1_ENA 0x0001 /* IN1_ENA */
-#define WM9081_IN1_ENA_MASK 0x0001 /* IN1_ENA */
-#define WM9081_IN1_ENA_SHIFT 0 /* IN1_ENA */
-#define WM9081_IN1_ENA_WIDTH 1 /* IN1_ENA */
-
-/*
- * R8 (0x08) - Anti Pop Control
- */
-#define WM9081_LINEOUT_DISCH 0x0004 /* LINEOUT_DISCH */
-#define WM9081_LINEOUT_DISCH_MASK 0x0004 /* LINEOUT_DISCH */
-#define WM9081_LINEOUT_DISCH_SHIFT 2 /* LINEOUT_DISCH */
-#define WM9081_LINEOUT_DISCH_WIDTH 1 /* LINEOUT_DISCH */
-#define WM9081_LINEOUT_VROI 0x0002 /* LINEOUT_VROI */
-#define WM9081_LINEOUT_VROI_MASK 0x0002 /* LINEOUT_VROI */
-#define WM9081_LINEOUT_VROI_SHIFT 1 /* LINEOUT_VROI */
-#define WM9081_LINEOUT_VROI_WIDTH 1 /* LINEOUT_VROI */
-#define WM9081_LINEOUT_CLAMP 0x0001 /* LINEOUT_CLAMP */
-#define WM9081_LINEOUT_CLAMP_MASK 0x0001 /* LINEOUT_CLAMP */
-#define WM9081_LINEOUT_CLAMP_SHIFT 0 /* LINEOUT_CLAMP */
-#define WM9081_LINEOUT_CLAMP_WIDTH 1 /* LINEOUT_CLAMP */
-
-/*
- * R9 (0x09) - Analogue Speaker 1
- */
-#define WM9081_SPK_DCGAIN_MASK 0x0038 /* SPK_DCGAIN - [5:3] */
-#define WM9081_SPK_DCGAIN_SHIFT 3 /* SPK_DCGAIN - [5:3] */
-#define WM9081_SPK_DCGAIN_WIDTH 3 /* SPK_DCGAIN - [5:3] */
-#define WM9081_SPK_ACGAIN_MASK 0x0007 /* SPK_ACGAIN - [2:0] */
-#define WM9081_SPK_ACGAIN_SHIFT 0 /* SPK_ACGAIN - [2:0] */
-#define WM9081_SPK_ACGAIN_WIDTH 3 /* SPK_ACGAIN - [2:0] */
-
-/*
- * R10 (0x0A) - Analogue Speaker 2
- */
-#define WM9081_SPK_MODE 0x0040 /* SPK_MODE */
-#define WM9081_SPK_MODE_MASK 0x0040 /* SPK_MODE */
-#define WM9081_SPK_MODE_SHIFT 6 /* SPK_MODE */
-#define WM9081_SPK_MODE_WIDTH 1 /* SPK_MODE */
-#define WM9081_SPK_INV_MUTE 0x0010 /* SPK_INV_MUTE */
-#define WM9081_SPK_INV_MUTE_MASK 0x0010 /* SPK_INV_MUTE */
-#define WM9081_SPK_INV_MUTE_SHIFT 4 /* SPK_INV_MUTE */
-#define WM9081_SPK_INV_MUTE_WIDTH 1 /* SPK_INV_MUTE */
-#define WM9081_OUT_SPK_CTRL 0x0008 /* OUT_SPK_CTRL */
-#define WM9081_OUT_SPK_CTRL_MASK 0x0008 /* OUT_SPK_CTRL */
-#define WM9081_OUT_SPK_CTRL_SHIFT 3 /* OUT_SPK_CTRL */
-#define WM9081_OUT_SPK_CTRL_WIDTH 1 /* OUT_SPK_CTRL */
-
-/*
- * R11 (0x0B) - Power Management
- */
-#define WM9081_TSHUT_ENA 0x0100 /* TSHUT_ENA */
-#define WM9081_TSHUT_ENA_MASK 0x0100 /* TSHUT_ENA */
-#define WM9081_TSHUT_ENA_SHIFT 8 /* TSHUT_ENA */
-#define WM9081_TSHUT_ENA_WIDTH 1 /* TSHUT_ENA */
-#define WM9081_TSENSE_ENA 0x0080 /* TSENSE_ENA */
-#define WM9081_TSENSE_ENA_MASK 0x0080 /* TSENSE_ENA */
-#define WM9081_TSENSE_ENA_SHIFT 7 /* TSENSE_ENA */
-#define WM9081_TSENSE_ENA_WIDTH 1 /* TSENSE_ENA */
-#define WM9081_TEMP_SHUT 0x0040 /* TEMP_SHUT */
-#define WM9081_TEMP_SHUT_MASK 0x0040 /* TEMP_SHUT */
-#define WM9081_TEMP_SHUT_SHIFT 6 /* TEMP_SHUT */
-#define WM9081_TEMP_SHUT_WIDTH 1 /* TEMP_SHUT */
-#define WM9081_LINEOUT_ENA 0x0010 /* LINEOUT_ENA */
-#define WM9081_LINEOUT_ENA_MASK 0x0010 /* LINEOUT_ENA */
-#define WM9081_LINEOUT_ENA_SHIFT 4 /* LINEOUT_ENA */
-#define WM9081_LINEOUT_ENA_WIDTH 1 /* LINEOUT_ENA */
-#define WM9081_SPKPGA_ENA 0x0004 /* SPKPGA_ENA */
-#define WM9081_SPKPGA_ENA_MASK 0x0004 /* SPKPGA_ENA */
-#define WM9081_SPKPGA_ENA_SHIFT 2 /* SPKPGA_ENA */
-#define WM9081_SPKPGA_ENA_WIDTH 1 /* SPKPGA_ENA */
-#define WM9081_SPK_ENA 0x0002 /* SPK_ENA */
-#define WM9081_SPK_ENA_MASK 0x0002 /* SPK_ENA */
-#define WM9081_SPK_ENA_SHIFT 1 /* SPK_ENA */
-#define WM9081_SPK_ENA_WIDTH 1 /* SPK_ENA */
-#define WM9081_DAC_ENA 0x0001 /* DAC_ENA */
-#define WM9081_DAC_ENA_MASK 0x0001 /* DAC_ENA */
-#define WM9081_DAC_ENA_SHIFT 0 /* DAC_ENA */
-#define WM9081_DAC_ENA_WIDTH 1 /* DAC_ENA */
-
-/*
- * R12 (0x0C) - Clock Control 1
- */
-#define WM9081_CLK_OP_DIV_MASK 0x1C00 /* CLK_OP_DIV - [12:10] */
-#define WM9081_CLK_OP_DIV_SHIFT 10 /* CLK_OP_DIV - [12:10] */
-#define WM9081_CLK_OP_DIV_WIDTH 3 /* CLK_OP_DIV - [12:10] */
-#define WM9081_CLK_TO_DIV_MASK 0x0300 /* CLK_TO_DIV - [9:8] */
-#define WM9081_CLK_TO_DIV_SHIFT 8 /* CLK_TO_DIV - [9:8] */
-#define WM9081_CLK_TO_DIV_WIDTH 2 /* CLK_TO_DIV - [9:8] */
-#define WM9081_MCLKDIV2 0x0080 /* MCLKDIV2 */
-#define WM9081_MCLKDIV2_MASK 0x0080 /* MCLKDIV2 */
-#define WM9081_MCLKDIV2_SHIFT 7 /* MCLKDIV2 */
-#define WM9081_MCLKDIV2_WIDTH 1 /* MCLKDIV2 */
-
-/*
- * R13 (0x0D) - Clock Control 2
- */
-#define WM9081_CLK_SYS_RATE_MASK 0x00F0 /* CLK_SYS_RATE - [7:4] */
-#define WM9081_CLK_SYS_RATE_SHIFT 4 /* CLK_SYS_RATE - [7:4] */
-#define WM9081_CLK_SYS_RATE_WIDTH 4 /* CLK_SYS_RATE - [7:4] */
-#define WM9081_SAMPLE_RATE_MASK 0x000F /* SAMPLE_RATE - [3:0] */
-#define WM9081_SAMPLE_RATE_SHIFT 0 /* SAMPLE_RATE - [3:0] */
-#define WM9081_SAMPLE_RATE_WIDTH 4 /* SAMPLE_RATE - [3:0] */
-
-/*
- * R14 (0x0E) - Clock Control 3
- */
-#define WM9081_CLK_SRC_SEL 0x2000 /* CLK_SRC_SEL */
-#define WM9081_CLK_SRC_SEL_MASK 0x2000 /* CLK_SRC_SEL */
-#define WM9081_CLK_SRC_SEL_SHIFT 13 /* CLK_SRC_SEL */
-#define WM9081_CLK_SRC_SEL_WIDTH 1 /* CLK_SRC_SEL */
-#define WM9081_CLK_OP_ENA 0x0020 /* CLK_OP_ENA */
-#define WM9081_CLK_OP_ENA_MASK 0x0020 /* CLK_OP_ENA */
-#define WM9081_CLK_OP_ENA_SHIFT 5 /* CLK_OP_ENA */
-#define WM9081_CLK_OP_ENA_WIDTH 1 /* CLK_OP_ENA */
-#define WM9081_CLK_TO_ENA 0x0004 /* CLK_TO_ENA */
-#define WM9081_CLK_TO_ENA_MASK 0x0004 /* CLK_TO_ENA */
-#define WM9081_CLK_TO_ENA_SHIFT 2 /* CLK_TO_ENA */
-#define WM9081_CLK_TO_ENA_WIDTH 1 /* CLK_TO_ENA */
-#define WM9081_CLK_DSP_ENA 0x0002 /* CLK_DSP_ENA */
-#define WM9081_CLK_DSP_ENA_MASK 0x0002 /* CLK_DSP_ENA */
-#define WM9081_CLK_DSP_ENA_SHIFT 1 /* CLK_DSP_ENA */
-#define WM9081_CLK_DSP_ENA_WIDTH 1 /* CLK_DSP_ENA */
-#define WM9081_CLK_SYS_ENA 0x0001 /* CLK_SYS_ENA */
-#define WM9081_CLK_SYS_ENA_MASK 0x0001 /* CLK_SYS_ENA */
-#define WM9081_CLK_SYS_ENA_SHIFT 0 /* CLK_SYS_ENA */
-#define WM9081_CLK_SYS_ENA_WIDTH 1 /* CLK_SYS_ENA */
-
-/*
- * R16 (0x10) - FLL Control 1
- */
-#define WM9081_FLL_HOLD 0x0008 /* FLL_HOLD */
-#define WM9081_FLL_HOLD_MASK 0x0008 /* FLL_HOLD */
-#define WM9081_FLL_HOLD_SHIFT 3 /* FLL_HOLD */
-#define WM9081_FLL_HOLD_WIDTH 1 /* FLL_HOLD */
-#define WM9081_FLL_FRAC 0x0004 /* FLL_FRAC */
-#define WM9081_FLL_FRAC_MASK 0x0004 /* FLL_FRAC */
-#define WM9081_FLL_FRAC_SHIFT 2 /* FLL_FRAC */
-#define WM9081_FLL_FRAC_WIDTH 1 /* FLL_FRAC */
-#define WM9081_FLL_ENA 0x0001 /* FLL_ENA */
-#define WM9081_FLL_ENA_MASK 0x0001 /* FLL_ENA */
-#define WM9081_FLL_ENA_SHIFT 0 /* FLL_ENA */
-#define WM9081_FLL_ENA_WIDTH 1 /* FLL_ENA */
-
-/*
- * R17 (0x11) - FLL Control 2
- */
-#define WM9081_FLL_OUTDIV_MASK 0x0700 /* FLL_OUTDIV - [10:8] */
-#define WM9081_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [10:8] */
-#define WM9081_FLL_OUTDIV_WIDTH 3 /* FLL_OUTDIV - [10:8] */
-#define WM9081_FLL_CTRL_RATE_MASK 0x0070 /* FLL_CTRL_RATE - [6:4] */
-#define WM9081_FLL_CTRL_RATE_SHIFT 4 /* FLL_CTRL_RATE - [6:4] */
-#define WM9081_FLL_CTRL_RATE_WIDTH 3 /* FLL_CTRL_RATE - [6:4] */
-#define WM9081_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
-#define WM9081_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
-#define WM9081_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
-
-/*
- * R18 (0x12) - FLL Control 3
- */
-#define WM9081_FLL_K_MASK 0xFFFF /* FLL_K - [15:0] */
-#define WM9081_FLL_K_SHIFT 0 /* FLL_K - [15:0] */
-#define WM9081_FLL_K_WIDTH 16 /* FLL_K - [15:0] */
-
-/*
- * R19 (0x13) - FLL Control 4
- */
-#define WM9081_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */
-#define WM9081_FLL_N_SHIFT 5 /* FLL_N - [14:5] */
-#define WM9081_FLL_N_WIDTH 10 /* FLL_N - [14:5] */
-#define WM9081_FLL_GAIN_MASK 0x000F /* FLL_GAIN - [3:0] */
-#define WM9081_FLL_GAIN_SHIFT 0 /* FLL_GAIN - [3:0] */
-#define WM9081_FLL_GAIN_WIDTH 4 /* FLL_GAIN - [3:0] */
-
-/*
- * R20 (0x14) - FLL Control 5
- */
-#define WM9081_FLL_CLK_REF_DIV_MASK 0x0018 /* FLL_CLK_REF_DIV - [4:3] */
-#define WM9081_FLL_CLK_REF_DIV_SHIFT 3 /* FLL_CLK_REF_DIV - [4:3] */
-#define WM9081_FLL_CLK_REF_DIV_WIDTH 2 /* FLL_CLK_REF_DIV - [4:3] */
-#define WM9081_FLL_CLK_SRC_MASK 0x0003 /* FLL_CLK_SRC - [1:0] */
-#define WM9081_FLL_CLK_SRC_SHIFT 0 /* FLL_CLK_SRC - [1:0] */
-#define WM9081_FLL_CLK_SRC_WIDTH 2 /* FLL_CLK_SRC - [1:0] */
-
-/*
- * R22 (0x16) - Audio Interface 1
- */
-#define WM9081_AIFDAC_CHAN 0x0040 /* AIFDAC_CHAN */
-#define WM9081_AIFDAC_CHAN_MASK 0x0040 /* AIFDAC_CHAN */
-#define WM9081_AIFDAC_CHAN_SHIFT 6 /* AIFDAC_CHAN */
-#define WM9081_AIFDAC_CHAN_WIDTH 1 /* AIFDAC_CHAN */
-#define WM9081_AIFDAC_TDM_SLOT_MASK 0x0030 /* AIFDAC_TDM_SLOT - [5:4] */
-#define WM9081_AIFDAC_TDM_SLOT_SHIFT 4 /* AIFDAC_TDM_SLOT - [5:4] */
-#define WM9081_AIFDAC_TDM_SLOT_WIDTH 2 /* AIFDAC_TDM_SLOT - [5:4] */
-#define WM9081_AIFDAC_TDM_MODE_MASK 0x000C /* AIFDAC_TDM_MODE - [3:2] */
-#define WM9081_AIFDAC_TDM_MODE_SHIFT 2 /* AIFDAC_TDM_MODE - [3:2] */
-#define WM9081_AIFDAC_TDM_MODE_WIDTH 2 /* AIFDAC_TDM_MODE - [3:2] */
-#define WM9081_DAC_COMP 0x0002 /* DAC_COMP */
-#define WM9081_DAC_COMP_MASK 0x0002 /* DAC_COMP */
-#define WM9081_DAC_COMP_SHIFT 1 /* DAC_COMP */
-#define WM9081_DAC_COMP_WIDTH 1 /* DAC_COMP */
-#define WM9081_DAC_COMPMODE 0x0001 /* DAC_COMPMODE */
-#define WM9081_DAC_COMPMODE_MASK 0x0001 /* DAC_COMPMODE */
-#define WM9081_DAC_COMPMODE_SHIFT 0 /* DAC_COMPMODE */
-#define WM9081_DAC_COMPMODE_WIDTH 1 /* DAC_COMPMODE */
-
-/*
- * R23 (0x17) - Audio Interface 2
- */
-#define WM9081_AIF_TRIS 0x0200 /* AIF_TRIS */
-#define WM9081_AIF_TRIS_MASK 0x0200 /* AIF_TRIS */
-#define WM9081_AIF_TRIS_SHIFT 9 /* AIF_TRIS */
-#define WM9081_AIF_TRIS_WIDTH 1 /* AIF_TRIS */
-#define WM9081_DAC_DAT_INV 0x0100 /* DAC_DAT_INV */
-#define WM9081_DAC_DAT_INV_MASK 0x0100 /* DAC_DAT_INV */
-#define WM9081_DAC_DAT_INV_SHIFT 8 /* DAC_DAT_INV */
-#define WM9081_DAC_DAT_INV_WIDTH 1 /* DAC_DAT_INV */
-#define WM9081_AIF_BCLK_INV 0x0080 /* AIF_BCLK_INV */
-#define WM9081_AIF_BCLK_INV_MASK 0x0080 /* AIF_BCLK_INV */
-#define WM9081_AIF_BCLK_INV_SHIFT 7 /* AIF_BCLK_INV */
-#define WM9081_AIF_BCLK_INV_WIDTH 1 /* AIF_BCLK_INV */
-#define WM9081_BCLK_DIR 0x0040 /* BCLK_DIR */
-#define WM9081_BCLK_DIR_MASK 0x0040 /* BCLK_DIR */
-#define WM9081_BCLK_DIR_SHIFT 6 /* BCLK_DIR */
-#define WM9081_BCLK_DIR_WIDTH 1 /* BCLK_DIR */
-#define WM9081_LRCLK_DIR 0x0020 /* LRCLK_DIR */
-#define WM9081_LRCLK_DIR_MASK 0x0020 /* LRCLK_DIR */
-#define WM9081_LRCLK_DIR_SHIFT 5 /* LRCLK_DIR */
-#define WM9081_LRCLK_DIR_WIDTH 1 /* LRCLK_DIR */
-#define WM9081_AIF_LRCLK_INV 0x0010 /* AIF_LRCLK_INV */
-#define WM9081_AIF_LRCLK_INV_MASK 0x0010 /* AIF_LRCLK_INV */
-#define WM9081_AIF_LRCLK_INV_SHIFT 4 /* AIF_LRCLK_INV */
-#define WM9081_AIF_LRCLK_INV_WIDTH 1 /* AIF_LRCLK_INV */
-#define WM9081_AIF_WL_MASK 0x000C /* AIF_WL - [3:2] */
-#define WM9081_AIF_WL_SHIFT 2 /* AIF_WL - [3:2] */
-#define WM9081_AIF_WL_WIDTH 2 /* AIF_WL - [3:2] */
-#define WM9081_AIF_FMT_MASK 0x0003 /* AIF_FMT - [1:0] */
-#define WM9081_AIF_FMT_SHIFT 0 /* AIF_FMT - [1:0] */
-#define WM9081_AIF_FMT_WIDTH 2 /* AIF_FMT - [1:0] */
-
-/*
- * R24 (0x18) - Audio Interface 3
- */
-#define WM9081_BCLK_DIV_MASK 0x001F /* BCLK_DIV - [4:0] */
-#define WM9081_BCLK_DIV_SHIFT 0 /* BCLK_DIV - [4:0] */
-#define WM9081_BCLK_DIV_WIDTH 5 /* BCLK_DIV - [4:0] */
-
-/*
- * R25 (0x19) - Audio Interface 4
- */
-#define WM9081_LRCLK_RATE_MASK 0x07FF /* LRCLK_RATE - [10:0] */
-#define WM9081_LRCLK_RATE_SHIFT 0 /* LRCLK_RATE - [10:0] */
-#define WM9081_LRCLK_RATE_WIDTH 11 /* LRCLK_RATE - [10:0] */
-
-/*
- * R26 (0x1A) - Interrupt Status
- */
-#define WM9081_WSEQ_BUSY_EINT 0x0004 /* WSEQ_BUSY_EINT */
-#define WM9081_WSEQ_BUSY_EINT_MASK 0x0004 /* WSEQ_BUSY_EINT */
-#define WM9081_WSEQ_BUSY_EINT_SHIFT 2 /* WSEQ_BUSY_EINT */
-#define WM9081_WSEQ_BUSY_EINT_WIDTH 1 /* WSEQ_BUSY_EINT */
-#define WM9081_TSHUT_EINT 0x0001 /* TSHUT_EINT */
-#define WM9081_TSHUT_EINT_MASK 0x0001 /* TSHUT_EINT */
-#define WM9081_TSHUT_EINT_SHIFT 0 /* TSHUT_EINT */
-#define WM9081_TSHUT_EINT_WIDTH 1 /* TSHUT_EINT */
-
-/*
- * R27 (0x1B) - Interrupt Status Mask
- */
-#define WM9081_IM_WSEQ_BUSY_EINT 0x0004 /* IM_WSEQ_BUSY_EINT */
-#define WM9081_IM_WSEQ_BUSY_EINT_MASK 0x0004 /* IM_WSEQ_BUSY_EINT */
-#define WM9081_IM_WSEQ_BUSY_EINT_SHIFT 2 /* IM_WSEQ_BUSY_EINT */
-#define WM9081_IM_WSEQ_BUSY_EINT_WIDTH 1 /* IM_WSEQ_BUSY_EINT */
-#define WM9081_IM_TSHUT_EINT 0x0001 /* IM_TSHUT_EINT */
-#define WM9081_IM_TSHUT_EINT_MASK 0x0001 /* IM_TSHUT_EINT */
-#define WM9081_IM_TSHUT_EINT_SHIFT 0 /* IM_TSHUT_EINT */
-#define WM9081_IM_TSHUT_EINT_WIDTH 1 /* IM_TSHUT_EINT */
-
-/*
- * R28 (0x1C) - Interrupt Polarity
- */
-#define WM9081_TSHUT_INV 0x0001 /* TSHUT_INV */
-#define WM9081_TSHUT_INV_MASK 0x0001 /* TSHUT_INV */
-#define WM9081_TSHUT_INV_SHIFT 0 /* TSHUT_INV */
-#define WM9081_TSHUT_INV_WIDTH 1 /* TSHUT_INV */
-
-/*
- * R29 (0x1D) - Interrupt Control
- */
-#define WM9081_IRQ_POL 0x8000 /* IRQ_POL */
-#define WM9081_IRQ_POL_MASK 0x8000 /* IRQ_POL */
-#define WM9081_IRQ_POL_SHIFT 15 /* IRQ_POL */
-#define WM9081_IRQ_POL_WIDTH 1 /* IRQ_POL */
-#define WM9081_IRQ_OP_CTRL 0x0001 /* IRQ_OP_CTRL */
-#define WM9081_IRQ_OP_CTRL_MASK 0x0001 /* IRQ_OP_CTRL */
-#define WM9081_IRQ_OP_CTRL_SHIFT 0 /* IRQ_OP_CTRL */
-#define WM9081_IRQ_OP_CTRL_WIDTH 1 /* IRQ_OP_CTRL */
-
-/*
- * R30 (0x1E) - DAC Digital 1
- */
-#define WM9081_DAC_VOL_MASK 0x00FF /* DAC_VOL - [7:0] */
-#define WM9081_DAC_VOL_SHIFT 0 /* DAC_VOL - [7:0] */
-#define WM9081_DAC_VOL_WIDTH 8 /* DAC_VOL - [7:0] */
-
-/*
- * R31 (0x1F) - DAC Digital 2
- */
-#define WM9081_DAC_MUTERATE 0x0400 /* DAC_MUTERATE */
-#define WM9081_DAC_MUTERATE_MASK 0x0400 /* DAC_MUTERATE */
-#define WM9081_DAC_MUTERATE_SHIFT 10 /* DAC_MUTERATE */
-#define WM9081_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
-#define WM9081_DAC_MUTEMODE 0x0200 /* DAC_MUTEMODE */
-#define WM9081_DAC_MUTEMODE_MASK 0x0200 /* DAC_MUTEMODE */
-#define WM9081_DAC_MUTEMODE_SHIFT 9 /* DAC_MUTEMODE */
-#define WM9081_DAC_MUTEMODE_WIDTH 1 /* DAC_MUTEMODE */
-#define WM9081_DAC_MUTE 0x0008 /* DAC_MUTE */
-#define WM9081_DAC_MUTE_MASK 0x0008 /* DAC_MUTE */
-#define WM9081_DAC_MUTE_SHIFT 3 /* DAC_MUTE */
-#define WM9081_DAC_MUTE_WIDTH 1 /* DAC_MUTE */
-#define WM9081_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */
-#define WM9081_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */
-#define WM9081_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */
-
-/*
- * R32 (0x20) - DRC 1
- */
-#define WM9081_DRC_ENA 0x8000 /* DRC_ENA */
-#define WM9081_DRC_ENA_MASK 0x8000 /* DRC_ENA */
-#define WM9081_DRC_ENA_SHIFT 15 /* DRC_ENA */
-#define WM9081_DRC_ENA_WIDTH 1 /* DRC_ENA */
-#define WM9081_DRC_STARTUP_GAIN_MASK 0x07C0 /* DRC_STARTUP_GAIN - [10:6] */
-#define WM9081_DRC_STARTUP_GAIN_SHIFT 6 /* DRC_STARTUP_GAIN - [10:6] */
-#define WM9081_DRC_STARTUP_GAIN_WIDTH 5 /* DRC_STARTUP_GAIN - [10:6] */
-#define WM9081_DRC_FF_DLY 0x0020 /* DRC_FF_DLY */
-#define WM9081_DRC_FF_DLY_MASK 0x0020 /* DRC_FF_DLY */
-#define WM9081_DRC_FF_DLY_SHIFT 5 /* DRC_FF_DLY */
-#define WM9081_DRC_FF_DLY_WIDTH 1 /* DRC_FF_DLY */
-#define WM9081_DRC_QR 0x0004 /* DRC_QR */
-#define WM9081_DRC_QR_MASK 0x0004 /* DRC_QR */
-#define WM9081_DRC_QR_SHIFT 2 /* DRC_QR */
-#define WM9081_DRC_QR_WIDTH 1 /* DRC_QR */
-#define WM9081_DRC_ANTICLIP 0x0002 /* DRC_ANTICLIP */
-#define WM9081_DRC_ANTICLIP_MASK 0x0002 /* DRC_ANTICLIP */
-#define WM9081_DRC_ANTICLIP_SHIFT 1 /* DRC_ANTICLIP */
-#define WM9081_DRC_ANTICLIP_WIDTH 1 /* DRC_ANTICLIP */
-
-/*
- * R33 (0x21) - DRC 2
- */
-#define WM9081_DRC_ATK_MASK 0xF000 /* DRC_ATK - [15:12] */
-#define WM9081_DRC_ATK_SHIFT 12 /* DRC_ATK - [15:12] */
-#define WM9081_DRC_ATK_WIDTH 4 /* DRC_ATK - [15:12] */
-#define WM9081_DRC_DCY_MASK 0x0F00 /* DRC_DCY - [11:8] */
-#define WM9081_DRC_DCY_SHIFT 8 /* DRC_DCY - [11:8] */
-#define WM9081_DRC_DCY_WIDTH 4 /* DRC_DCY - [11:8] */
-#define WM9081_DRC_QR_THR_MASK 0x00C0 /* DRC_QR_THR - [7:6] */
-#define WM9081_DRC_QR_THR_SHIFT 6 /* DRC_QR_THR - [7:6] */
-#define WM9081_DRC_QR_THR_WIDTH 2 /* DRC_QR_THR - [7:6] */
-#define WM9081_DRC_QR_DCY_MASK 0x0030 /* DRC_QR_DCY - [5:4] */
-#define WM9081_DRC_QR_DCY_SHIFT 4 /* DRC_QR_DCY - [5:4] */
-#define WM9081_DRC_QR_DCY_WIDTH 2 /* DRC_QR_DCY - [5:4] */
-#define WM9081_DRC_MINGAIN_MASK 0x000C /* DRC_MINGAIN - [3:2] */
-#define WM9081_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [3:2] */
-#define WM9081_DRC_MINGAIN_WIDTH 2 /* DRC_MINGAIN - [3:2] */
-#define WM9081_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */
-#define WM9081_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */
-#define WM9081_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */
-
-/*
- * R34 (0x22) - DRC 3
- */
-#define WM9081_DRC_HI_COMP_MASK 0x0038 /* DRC_HI_COMP - [5:3] */
-#define WM9081_DRC_HI_COMP_SHIFT 3 /* DRC_HI_COMP - [5:3] */
-#define WM9081_DRC_HI_COMP_WIDTH 3 /* DRC_HI_COMP - [5:3] */
-#define WM9081_DRC_LO_COMP_MASK 0x0007 /* DRC_LO_COMP - [2:0] */
-#define WM9081_DRC_LO_COMP_SHIFT 0 /* DRC_LO_COMP - [2:0] */
-#define WM9081_DRC_LO_COMP_WIDTH 3 /* DRC_LO_COMP - [2:0] */
-
-/*
- * R35 (0x23) - DRC 4
- */
-#define WM9081_DRC_KNEE_IP_MASK 0x07E0 /* DRC_KNEE_IP - [10:5] */
-#define WM9081_DRC_KNEE_IP_SHIFT 5 /* DRC_KNEE_IP - [10:5] */
-#define WM9081_DRC_KNEE_IP_WIDTH 6 /* DRC_KNEE_IP - [10:5] */
-#define WM9081_DRC_KNEE_OP_MASK 0x001F /* DRC_KNEE_OP - [4:0] */
-#define WM9081_DRC_KNEE_OP_SHIFT 0 /* DRC_KNEE_OP - [4:0] */
-#define WM9081_DRC_KNEE_OP_WIDTH 5 /* DRC_KNEE_OP - [4:0] */
-
-/*
- * R38 (0x26) - Write Sequencer 1
- */
-#define WM9081_WSEQ_ENA 0x8000 /* WSEQ_ENA */
-#define WM9081_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */
-#define WM9081_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */
-#define WM9081_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
-#define WM9081_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
-#define WM9081_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
-#define WM9081_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
-#define WM9081_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
-#define WM9081_WSEQ_START 0x0100 /* WSEQ_START */
-#define WM9081_WSEQ_START_MASK 0x0100 /* WSEQ_START */
-#define WM9081_WSEQ_START_SHIFT 8 /* WSEQ_START */
-#define WM9081_WSEQ_START_WIDTH 1 /* WSEQ_START */
-#define WM9081_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */
-#define WM9081_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */
-#define WM9081_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */
-
-/*
- * R39 (0x27) - Write Sequencer 2
- */
-#define WM9081_WSEQ_CURRENT_INDEX_MASK 0x07F0 /* WSEQ_CURRENT_INDEX - [10:4] */
-#define WM9081_WSEQ_CURRENT_INDEX_SHIFT 4 /* WSEQ_CURRENT_INDEX - [10:4] */
-#define WM9081_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [10:4] */
-#define WM9081_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
-#define WM9081_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
-#define WM9081_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
-#define WM9081_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
-
-/*
- * R40 (0x28) - MW Slave 1
- */
-#define WM9081_SPI_CFG 0x0020 /* SPI_CFG */
-#define WM9081_SPI_CFG_MASK 0x0020 /* SPI_CFG */
-#define WM9081_SPI_CFG_SHIFT 5 /* SPI_CFG */
-#define WM9081_SPI_CFG_WIDTH 1 /* SPI_CFG */
-#define WM9081_SPI_4WIRE 0x0010 /* SPI_4WIRE */
-#define WM9081_SPI_4WIRE_MASK 0x0010 /* SPI_4WIRE */
-#define WM9081_SPI_4WIRE_SHIFT 4 /* SPI_4WIRE */
-#define WM9081_SPI_4WIRE_WIDTH 1 /* SPI_4WIRE */
-#define WM9081_ARA_ENA 0x0008 /* ARA_ENA */
-#define WM9081_ARA_ENA_MASK 0x0008 /* ARA_ENA */
-#define WM9081_ARA_ENA_SHIFT 3 /* ARA_ENA */
-#define WM9081_ARA_ENA_WIDTH 1 /* ARA_ENA */
-#define WM9081_AUTO_INC 0x0002 /* AUTO_INC */
-#define WM9081_AUTO_INC_MASK 0x0002 /* AUTO_INC */
-#define WM9081_AUTO_INC_SHIFT 1 /* AUTO_INC */
-#define WM9081_AUTO_INC_WIDTH 1 /* AUTO_INC */
-
-/*
- * R42 (0x2A) - EQ 1
- */
-#define WM9081_EQ_B1_GAIN_MASK 0xF800 /* EQ_B1_GAIN - [15:11] */
-#define WM9081_EQ_B1_GAIN_SHIFT 11 /* EQ_B1_GAIN - [15:11] */
-#define WM9081_EQ_B1_GAIN_WIDTH 5 /* EQ_B1_GAIN - [15:11] */
-#define WM9081_EQ_B2_GAIN_MASK 0x07C0 /* EQ_B2_GAIN - [10:6] */
-#define WM9081_EQ_B2_GAIN_SHIFT 6 /* EQ_B2_GAIN - [10:6] */
-#define WM9081_EQ_B2_GAIN_WIDTH 5 /* EQ_B2_GAIN - [10:6] */
-#define WM9081_EQ_B4_GAIN_MASK 0x003E /* EQ_B4_GAIN - [5:1] */
-#define WM9081_EQ_B4_GAIN_SHIFT 1 /* EQ_B4_GAIN - [5:1] */
-#define WM9081_EQ_B4_GAIN_WIDTH 5 /* EQ_B4_GAIN - [5:1] */
-#define WM9081_EQ_ENA 0x0001 /* EQ_ENA */
-#define WM9081_EQ_ENA_MASK 0x0001 /* EQ_ENA */
-#define WM9081_EQ_ENA_SHIFT 0 /* EQ_ENA */
-#define WM9081_EQ_ENA_WIDTH 1 /* EQ_ENA */
-
-/*
- * R43 (0x2B) - EQ 2
- */
-#define WM9081_EQ_B3_GAIN_MASK 0xF800 /* EQ_B3_GAIN - [15:11] */
-#define WM9081_EQ_B3_GAIN_SHIFT 11 /* EQ_B3_GAIN - [15:11] */
-#define WM9081_EQ_B3_GAIN_WIDTH 5 /* EQ_B3_GAIN - [15:11] */
-#define WM9081_EQ_B5_GAIN_MASK 0x07C0 /* EQ_B5_GAIN - [10:6] */
-#define WM9081_EQ_B5_GAIN_SHIFT 6 /* EQ_B5_GAIN - [10:6] */
-#define WM9081_EQ_B5_GAIN_WIDTH 5 /* EQ_B5_GAIN - [10:6] */
-
-/*
- * R44 (0x2C) - EQ 3
- */
-#define WM9081_EQ_B1_A_MASK 0xFFFF /* EQ_B1_A - [15:0] */
-#define WM9081_EQ_B1_A_SHIFT 0 /* EQ_B1_A - [15:0] */
-#define WM9081_EQ_B1_A_WIDTH 16 /* EQ_B1_A - [15:0] */
-
-/*
- * R45 (0x2D) - EQ 4
- */
-#define WM9081_EQ_B1_B_MASK 0xFFFF /* EQ_B1_B - [15:0] */
-#define WM9081_EQ_B1_B_SHIFT 0 /* EQ_B1_B - [15:0] */
-#define WM9081_EQ_B1_B_WIDTH 16 /* EQ_B1_B - [15:0] */
-
-/*
- * R46 (0x2E) - EQ 5
- */
-#define WM9081_EQ_B1_PG_MASK 0xFFFF /* EQ_B1_PG - [15:0] */
-#define WM9081_EQ_B1_PG_SHIFT 0 /* EQ_B1_PG - [15:0] */
-#define WM9081_EQ_B1_PG_WIDTH 16 /* EQ_B1_PG - [15:0] */
-
-/*
- * R47 (0x2F) - EQ 6
- */
-#define WM9081_EQ_B2_A_MASK 0xFFFF /* EQ_B2_A - [15:0] */
-#define WM9081_EQ_B2_A_SHIFT 0 /* EQ_B2_A - [15:0] */
-#define WM9081_EQ_B2_A_WIDTH 16 /* EQ_B2_A - [15:0] */
-
-/*
- * R48 (0x30) - EQ 7
- */
-#define WM9081_EQ_B2_B_MASK 0xFFFF /* EQ_B2_B - [15:0] */
-#define WM9081_EQ_B2_B_SHIFT 0 /* EQ_B2_B - [15:0] */
-#define WM9081_EQ_B2_B_WIDTH 16 /* EQ_B2_B - [15:0] */
-
-/*
- * R49 (0x31) - EQ 8
- */
-#define WM9081_EQ_B2_C_MASK 0xFFFF /* EQ_B2_C - [15:0] */
-#define WM9081_EQ_B2_C_SHIFT 0 /* EQ_B2_C - [15:0] */
-#define WM9081_EQ_B2_C_WIDTH 16 /* EQ_B2_C - [15:0] */
-
-/*
- * R50 (0x32) - EQ 9
- */
-#define WM9081_EQ_B2_PG_MASK 0xFFFF /* EQ_B2_PG - [15:0] */
-#define WM9081_EQ_B2_PG_SHIFT 0 /* EQ_B2_PG - [15:0] */
-#define WM9081_EQ_B2_PG_WIDTH 16 /* EQ_B2_PG - [15:0] */
-
-/*
- * R51 (0x33) - EQ 10
- */
-#define WM9081_EQ_B4_A_MASK 0xFFFF /* EQ_B4_A - [15:0] */
-#define WM9081_EQ_B4_A_SHIFT 0 /* EQ_B4_A - [15:0] */
-#define WM9081_EQ_B4_A_WIDTH 16 /* EQ_B4_A - [15:0] */
-
-/*
- * R52 (0x34) - EQ 11
- */
-#define WM9081_EQ_B4_B_MASK 0xFFFF /* EQ_B4_B - [15:0] */
-#define WM9081_EQ_B4_B_SHIFT 0 /* EQ_B4_B - [15:0] */
-#define WM9081_EQ_B4_B_WIDTH 16 /* EQ_B4_B - [15:0] */
-
-/*
- * R53 (0x35) - EQ 12
- */
-#define WM9081_EQ_B4_C_MASK 0xFFFF /* EQ_B4_C - [15:0] */
-#define WM9081_EQ_B4_C_SHIFT 0 /* EQ_B4_C - [15:0] */
-#define WM9081_EQ_B4_C_WIDTH 16 /* EQ_B4_C - [15:0] */
-
-/*
- * R54 (0x36) - EQ 13
- */
-#define WM9081_EQ_B4_PG_MASK 0xFFFF /* EQ_B4_PG - [15:0] */
-#define WM9081_EQ_B4_PG_SHIFT 0 /* EQ_B4_PG - [15:0] */
-#define WM9081_EQ_B4_PG_WIDTH 16 /* EQ_B4_PG - [15:0] */
-
-/*
- * R55 (0x37) - EQ 14
- */
-#define WM9081_EQ_B3_A_MASK 0xFFFF /* EQ_B3_A - [15:0] */
-#define WM9081_EQ_B3_A_SHIFT 0 /* EQ_B3_A - [15:0] */
-#define WM9081_EQ_B3_A_WIDTH 16 /* EQ_B3_A - [15:0] */
-
-/*
- * R56 (0x38) - EQ 15
- */
-#define WM9081_EQ_B3_B_MASK 0xFFFF /* EQ_B3_B - [15:0] */
-#define WM9081_EQ_B3_B_SHIFT 0 /* EQ_B3_B - [15:0] */
-#define WM9081_EQ_B3_B_WIDTH 16 /* EQ_B3_B - [15:0] */
-
-/*
- * R57 (0x39) - EQ 16
- */
-#define WM9081_EQ_B3_C_MASK 0xFFFF /* EQ_B3_C - [15:0] */
-#define WM9081_EQ_B3_C_SHIFT 0 /* EQ_B3_C - [15:0] */
-#define WM9081_EQ_B3_C_WIDTH 16 /* EQ_B3_C - [15:0] */
-
-/*
- * R58 (0x3A) - EQ 17
- */
-#define WM9081_EQ_B3_PG_MASK 0xFFFF /* EQ_B3_PG - [15:0] */
-#define WM9081_EQ_B3_PG_SHIFT 0 /* EQ_B3_PG - [15:0] */
-#define WM9081_EQ_B3_PG_WIDTH 16 /* EQ_B3_PG - [15:0] */
-
-/*
- * R59 (0x3B) - EQ 18
- */
-#define WM9081_EQ_B5_A_MASK 0xFFFF /* EQ_B5_A - [15:0] */
-#define WM9081_EQ_B5_A_SHIFT 0 /* EQ_B5_A - [15:0] */
-#define WM9081_EQ_B5_A_WIDTH 16 /* EQ_B5_A - [15:0] */
-
-/*
- * R60 (0x3C) - EQ 19
- */
-#define WM9081_EQ_B5_B_MASK 0xFFFF /* EQ_B5_B - [15:0] */
-#define WM9081_EQ_B5_B_SHIFT 0 /* EQ_B5_B - [15:0] */
-#define WM9081_EQ_B5_B_WIDTH 16 /* EQ_B5_B - [15:0] */
-
-/*
- * R61 (0x3D) - EQ 20
- */
-#define WM9081_EQ_B5_PG_MASK 0xFFFF /* EQ_B5_PG - [15:0] */
-#define WM9081_EQ_B5_PG_SHIFT 0 /* EQ_B5_PG - [15:0] */
-#define WM9081_EQ_B5_PG_WIDTH 16 /* EQ_B5_PG - [15:0] */
-
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm9090.c b/ANDROID_3.4.5/sound/soc/codecs/wm9090.c
deleted file mode 100644
index 4b263b6e..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm9090.c
+++ /dev/null
@@ -1,712 +0,0 @@
-/*
- * ALSA SoC WM9090 driver
- *
- * Copyright 2009, 2010 Wolfson Microelectronics
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <linux/regmap.h>
-#include <linux/slab.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-#include <sound/tlv.h>
-#include <sound/wm9090.h>
-
-#include "wm9090.h"
-
-static const struct reg_default wm9090_reg_defaults[] = {
- { 1, 0x0006 }, /* R1 - Power Management (1) */
- { 2, 0x6000 }, /* R2 - Power Management (2) */
- { 3, 0x0000 }, /* R3 - Power Management (3) */
- { 6, 0x01C0 }, /* R6 - Clocking 1 */
- { 22, 0x0003 }, /* R22 - IN1 Line Control */
- { 23, 0x0003 }, /* R23 - IN2 Line Control */
- { 24, 0x0083 }, /* R24 - IN1 Line Input A Volume */
- { 25, 0x0083 }, /* R25 - IN1 Line Input B Volume */
- { 26, 0x0083 }, /* R26 - IN2 Line Input A Volume */
- { 27, 0x0083 }, /* R27 - IN2 Line Input B Volume */
- { 28, 0x002D }, /* R28 - Left Output Volume */
- { 29, 0x002D }, /* R29 - Right Output Volume */
- { 34, 0x0100 }, /* R34 - SPKMIXL Attenuation */
- { 35, 0x0010 }, /* R36 - SPKOUT Mixers */
- { 37, 0x0140 }, /* R37 - ClassD3 */
- { 38, 0x0039 }, /* R38 - Speaker Volume Left */
- { 45, 0x0000 }, /* R45 - Output Mixer1 */
- { 46, 0x0000 }, /* R46 - Output Mixer2 */
- { 47, 0x0100 }, /* R47 - Output Mixer3 */
- { 48, 0x0100 }, /* R48 - Output Mixer4 */
- { 54, 0x0000 }, /* R54 - Speaker Mixer */
- { 57, 0x000D }, /* R57 - AntiPOP2 */
- { 70, 0x0000 }, /* R70 - Write Sequencer 0 */
- { 71, 0x0000 }, /* R71 - Write Sequencer 1 */
- { 72, 0x0000 }, /* R72 - Write Sequencer 2 */
- { 73, 0x0000 }, /* R73 - Write Sequencer 3 */
- { 74, 0x0000 }, /* R74 - Write Sequencer 4 */
- { 75, 0x0000 }, /* R75 - Write Sequencer 5 */
- { 76, 0x1F25 }, /* R76 - Charge Pump 1 */
- { 85, 0x054A }, /* R85 - DC Servo 1 */
- { 87, 0x0000 }, /* R87 - DC Servo 3 */
- { 96, 0x0100 }, /* R96 - Analogue HP 0 */
- { 98, 0x8640 }, /* R98 - AGC Control 0 */
- { 99, 0xC000 }, /* R99 - AGC Control 1 */
- { 100, 0x0200 }, /* R100 - AGC Control 2 */
-};
-
-/* This struct is used to save the context */
-struct wm9090_priv {
- struct wm9090_platform_data pdata;
- struct regmap *regmap;
-};
-
-static bool wm9090_volatile(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM9090_SOFTWARE_RESET:
- case WM9090_DC_SERVO_0:
- case WM9090_DC_SERVO_READBACK_0:
- case WM9090_DC_SERVO_READBACK_1:
- case WM9090_DC_SERVO_READBACK_2:
- return true;
-
- default:
- return false;
- }
-}
-
-static bool wm9090_readable(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case WM9090_SOFTWARE_RESET:
- case WM9090_POWER_MANAGEMENT_1:
- case WM9090_POWER_MANAGEMENT_2:
- case WM9090_POWER_MANAGEMENT_3:
- case WM9090_CLOCKING_1:
- case WM9090_IN1_LINE_CONTROL:
- case WM9090_IN2_LINE_CONTROL:
- case WM9090_IN1_LINE_INPUT_A_VOLUME:
- case WM9090_IN1_LINE_INPUT_B_VOLUME:
- case WM9090_IN2_LINE_INPUT_A_VOLUME:
- case WM9090_IN2_LINE_INPUT_B_VOLUME:
- case WM9090_LEFT_OUTPUT_VOLUME:
- case WM9090_RIGHT_OUTPUT_VOLUME:
- case WM9090_SPKMIXL_ATTENUATION:
- case WM9090_SPKOUT_MIXERS:
- case WM9090_CLASSD3:
- case WM9090_SPEAKER_VOLUME_LEFT:
- case WM9090_OUTPUT_MIXER1:
- case WM9090_OUTPUT_MIXER2:
- case WM9090_OUTPUT_MIXER3:
- case WM9090_OUTPUT_MIXER4:
- case WM9090_SPEAKER_MIXER:
- case WM9090_ANTIPOP2:
- case WM9090_WRITE_SEQUENCER_0:
- case WM9090_WRITE_SEQUENCER_1:
- case WM9090_WRITE_SEQUENCER_2:
- case WM9090_WRITE_SEQUENCER_3:
- case WM9090_WRITE_SEQUENCER_4:
- case WM9090_WRITE_SEQUENCER_5:
- case WM9090_CHARGE_PUMP_1:
- case WM9090_DC_SERVO_0:
- case WM9090_DC_SERVO_1:
- case WM9090_DC_SERVO_3:
- case WM9090_DC_SERVO_READBACK_0:
- case WM9090_DC_SERVO_READBACK_1:
- case WM9090_DC_SERVO_READBACK_2:
- case WM9090_ANALOGUE_HP_0:
- case WM9090_AGC_CONTROL_0:
- case WM9090_AGC_CONTROL_1:
- case WM9090_AGC_CONTROL_2:
- return true;
-
- default:
- return false;
- }
-}
-
-static void wait_for_dc_servo(struct snd_soc_codec *codec)
-{
- unsigned int reg;
- int count = 0;
-
- dev_dbg(codec->dev, "Waiting for DC servo...\n");
- do {
- count++;
- msleep(1);
- reg = snd_soc_read(codec, WM9090_DC_SERVO_READBACK_0);
- dev_dbg(codec->dev, "DC servo status: %x\n", reg);
- } while ((reg & WM9090_DCS_CAL_COMPLETE_MASK)
- != WM9090_DCS_CAL_COMPLETE_MASK && count < 1000);
-
- if ((reg & WM9090_DCS_CAL_COMPLETE_MASK)
- != WM9090_DCS_CAL_COMPLETE_MASK)
- dev_err(codec->dev, "Timed out waiting for DC Servo\n");
-}
-
-static const unsigned int in_tlv[] = {
- TLV_DB_RANGE_HEAD(3),
- 0, 0, TLV_DB_SCALE_ITEM(-600, 0, 0),
- 1, 3, TLV_DB_SCALE_ITEM(-350, 350, 0),
- 4, 6, TLV_DB_SCALE_ITEM(600, 600, 0),
-};
-static const unsigned int mix_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 2, TLV_DB_SCALE_ITEM(-1200, 300, 0),
- 3, 3, TLV_DB_SCALE_ITEM(0, 0, 0),
-};
-static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
-static const unsigned int spkboost_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0),
- 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0),
-};
-
-static const struct snd_kcontrol_new wm9090_controls[] = {
-SOC_SINGLE_TLV("IN1A Volume", WM9090_IN1_LINE_INPUT_A_VOLUME, 0, 6, 0,
- in_tlv),
-SOC_SINGLE("IN1A Switch", WM9090_IN1_LINE_INPUT_A_VOLUME, 7, 1, 1),
-SOC_SINGLE("IN1A ZC Switch", WM9090_IN1_LINE_INPUT_A_VOLUME, 6, 1, 0),
-
-SOC_SINGLE_TLV("IN2A Volume", WM9090_IN2_LINE_INPUT_A_VOLUME, 0, 6, 0,
- in_tlv),
-SOC_SINGLE("IN2A Switch", WM9090_IN2_LINE_INPUT_A_VOLUME, 7, 1, 1),
-SOC_SINGLE("IN2A ZC Switch", WM9090_IN2_LINE_INPUT_A_VOLUME, 6, 1, 0),
-
-SOC_SINGLE("MIXOUTL Switch", WM9090_OUTPUT_MIXER3, 8, 1, 1),
-SOC_SINGLE_TLV("MIXOUTL IN1A Volume", WM9090_OUTPUT_MIXER3, 6, 3, 1,
- mix_tlv),
-SOC_SINGLE_TLV("MIXOUTL IN2A Volume", WM9090_OUTPUT_MIXER3, 2, 3, 1,
- mix_tlv),
-
-SOC_SINGLE("MIXOUTR Switch", WM9090_OUTPUT_MIXER4, 8, 1, 1),
-SOC_SINGLE_TLV("MIXOUTR IN1A Volume", WM9090_OUTPUT_MIXER4, 6, 3, 1,
- mix_tlv),
-SOC_SINGLE_TLV("MIXOUTR IN2A Volume", WM9090_OUTPUT_MIXER4, 2, 3, 1,
- mix_tlv),
-
-SOC_SINGLE("SPKMIX Switch", WM9090_SPKMIXL_ATTENUATION, 8, 1, 1),
-SOC_SINGLE_TLV("SPKMIX IN1A Volume", WM9090_SPKMIXL_ATTENUATION, 6, 3, 1,
- mix_tlv),
-SOC_SINGLE_TLV("SPKMIX IN2A Volume", WM9090_SPKMIXL_ATTENUATION, 2, 3, 1,
- mix_tlv),
-
-SOC_DOUBLE_R_TLV("Headphone Volume", WM9090_LEFT_OUTPUT_VOLUME,
- WM9090_RIGHT_OUTPUT_VOLUME, 0, 63, 0, out_tlv),
-SOC_DOUBLE_R("Headphone Switch", WM9090_LEFT_OUTPUT_VOLUME,
- WM9090_RIGHT_OUTPUT_VOLUME, 6, 1, 1),
-SOC_DOUBLE_R("Headphone ZC Switch", WM9090_LEFT_OUTPUT_VOLUME,
- WM9090_RIGHT_OUTPUT_VOLUME, 7, 1, 0),
-
-SOC_SINGLE_TLV("Speaker Volume", WM9090_SPEAKER_VOLUME_LEFT, 0, 63, 0,
- out_tlv),
-SOC_SINGLE("Speaker Switch", WM9090_SPEAKER_VOLUME_LEFT, 6, 1, 1),
-SOC_SINGLE("Speaker ZC Switch", WM9090_SPEAKER_VOLUME_LEFT, 7, 1, 0),
-SOC_SINGLE_TLV("Speaker Boost Volume", WM9090_CLASSD3, 3, 7, 0, spkboost_tlv),
-};
-
-static const struct snd_kcontrol_new wm9090_in1_se_controls[] = {
-SOC_SINGLE_TLV("IN1B Volume", WM9090_IN1_LINE_INPUT_B_VOLUME, 0, 6, 0,
- in_tlv),
-SOC_SINGLE("IN1B Switch", WM9090_IN1_LINE_INPUT_B_VOLUME, 7, 1, 1),
-SOC_SINGLE("IN1B ZC Switch", WM9090_IN1_LINE_INPUT_B_VOLUME, 6, 1, 0),
-
-SOC_SINGLE_TLV("SPKMIX IN1B Volume", WM9090_SPKMIXL_ATTENUATION, 4, 3, 1,
- mix_tlv),
-SOC_SINGLE_TLV("MIXOUTL IN1B Volume", WM9090_OUTPUT_MIXER3, 4, 3, 1,
- mix_tlv),
-SOC_SINGLE_TLV("MIXOUTR IN1B Volume", WM9090_OUTPUT_MIXER4, 4, 3, 1,
- mix_tlv),
-};
-
-static const struct snd_kcontrol_new wm9090_in2_se_controls[] = {
-SOC_SINGLE_TLV("IN2B Volume", WM9090_IN2_LINE_INPUT_B_VOLUME, 0, 6, 0,
- in_tlv),
-SOC_SINGLE("IN2B Switch", WM9090_IN2_LINE_INPUT_B_VOLUME, 7, 1, 1),
-SOC_SINGLE("IN2B ZC Switch", WM9090_IN2_LINE_INPUT_B_VOLUME, 6, 1, 0),
-
-SOC_SINGLE_TLV("SPKMIX IN2B Volume", WM9090_SPKMIXL_ATTENUATION, 0, 3, 1,
- mix_tlv),
-SOC_SINGLE_TLV("MIXOUTL IN2B Volume", WM9090_OUTPUT_MIXER3, 0, 3, 1,
- mix_tlv),
-SOC_SINGLE_TLV("MIXOUTR IN2B Volume", WM9090_OUTPUT_MIXER4, 0, 3, 1,
- mix_tlv),
-};
-
-static int hp_ev(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- unsigned int reg = snd_soc_read(codec, WM9090_ANALOGUE_HP_0);
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- snd_soc_update_bits(codec, WM9090_CHARGE_PUMP_1,
- WM9090_CP_ENA, WM9090_CP_ENA);
-
- msleep(5);
-
- snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_1,
- WM9090_HPOUT1L_ENA | WM9090_HPOUT1R_ENA,
- WM9090_HPOUT1L_ENA | WM9090_HPOUT1R_ENA);
-
- reg |= WM9090_HPOUT1L_DLY | WM9090_HPOUT1R_DLY;
- snd_soc_write(codec, WM9090_ANALOGUE_HP_0, reg);
-
- /* Start the DC servo. We don't currently use the
- * ability to save the state since we don't have full
- * control of the analogue paths and they can change
- * DC offsets; see the WM8904 driver for an example of
- * doing so.
- */
- snd_soc_write(codec, WM9090_DC_SERVO_0,
- WM9090_DCS_ENA_CHAN_0 |
- WM9090_DCS_ENA_CHAN_1 |
- WM9090_DCS_TRIG_STARTUP_1 |
- WM9090_DCS_TRIG_STARTUP_0);
- wait_for_dc_servo(codec);
-
- reg |= WM9090_HPOUT1R_OUTP | WM9090_HPOUT1R_RMV_SHORT |
- WM9090_HPOUT1L_OUTP | WM9090_HPOUT1L_RMV_SHORT;
- snd_soc_write(codec, WM9090_ANALOGUE_HP_0, reg);
- break;
-
- case SND_SOC_DAPM_PRE_PMD:
- reg &= ~(WM9090_HPOUT1L_RMV_SHORT |
- WM9090_HPOUT1L_DLY |
- WM9090_HPOUT1L_OUTP |
- WM9090_HPOUT1R_RMV_SHORT |
- WM9090_HPOUT1R_DLY |
- WM9090_HPOUT1R_OUTP);
-
- snd_soc_write(codec, WM9090_ANALOGUE_HP_0, reg);
-
- snd_soc_write(codec, WM9090_DC_SERVO_0, 0);
-
- snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_1,
- WM9090_HPOUT1L_ENA | WM9090_HPOUT1R_ENA,
- 0);
-
- snd_soc_update_bits(codec, WM9090_CHARGE_PUMP_1,
- WM9090_CP_ENA, 0);
- break;
- }
-
- return 0;
-}
-
-static const struct snd_kcontrol_new spkmix[] = {
-SOC_DAPM_SINGLE("IN1A Switch", WM9090_SPEAKER_MIXER, 6, 1, 0),
-SOC_DAPM_SINGLE("IN1B Switch", WM9090_SPEAKER_MIXER, 4, 1, 0),
-SOC_DAPM_SINGLE("IN2A Switch", WM9090_SPEAKER_MIXER, 2, 1, 0),
-SOC_DAPM_SINGLE("IN2B Switch", WM9090_SPEAKER_MIXER, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new spkout[] = {
-SOC_DAPM_SINGLE("Mixer Switch", WM9090_SPKOUT_MIXERS, 4, 1, 0),
-};
-
-static const struct snd_kcontrol_new mixoutl[] = {
-SOC_DAPM_SINGLE("IN1A Switch", WM9090_OUTPUT_MIXER1, 6, 1, 0),
-SOC_DAPM_SINGLE("IN1B Switch", WM9090_OUTPUT_MIXER1, 4, 1, 0),
-SOC_DAPM_SINGLE("IN2A Switch", WM9090_OUTPUT_MIXER1, 2, 1, 0),
-SOC_DAPM_SINGLE("IN2B Switch", WM9090_OUTPUT_MIXER1, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new mixoutr[] = {
-SOC_DAPM_SINGLE("IN1A Switch", WM9090_OUTPUT_MIXER2, 6, 1, 0),
-SOC_DAPM_SINGLE("IN1B Switch", WM9090_OUTPUT_MIXER2, 4, 1, 0),
-SOC_DAPM_SINGLE("IN2A Switch", WM9090_OUTPUT_MIXER2, 2, 1, 0),
-SOC_DAPM_SINGLE("IN2B Switch", WM9090_OUTPUT_MIXER2, 0, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget wm9090_dapm_widgets[] = {
-SND_SOC_DAPM_INPUT("IN1+"),
-SND_SOC_DAPM_INPUT("IN1-"),
-SND_SOC_DAPM_INPUT("IN2+"),
-SND_SOC_DAPM_INPUT("IN2-"),
-
-SND_SOC_DAPM_SUPPLY("OSC", WM9090_POWER_MANAGEMENT_1, 3, 0, NULL, 0),
-
-SND_SOC_DAPM_PGA("IN1A PGA", WM9090_POWER_MANAGEMENT_2, 7, 0, NULL, 0),
-SND_SOC_DAPM_PGA("IN1B PGA", WM9090_POWER_MANAGEMENT_2, 6, 0, NULL, 0),
-SND_SOC_DAPM_PGA("IN2A PGA", WM9090_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA("IN2B PGA", WM9090_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
-
-SND_SOC_DAPM_MIXER("SPKMIX", WM9090_POWER_MANAGEMENT_3, 3, 0,
- spkmix, ARRAY_SIZE(spkmix)),
-SND_SOC_DAPM_MIXER("MIXOUTL", WM9090_POWER_MANAGEMENT_3, 5, 0,
- mixoutl, ARRAY_SIZE(mixoutl)),
-SND_SOC_DAPM_MIXER("MIXOUTR", WM9090_POWER_MANAGEMENT_3, 4, 0,
- mixoutr, ARRAY_SIZE(mixoutr)),
-
-SND_SOC_DAPM_PGA_E("HP PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
- hp_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-
-SND_SOC_DAPM_PGA("SPKPGA", WM9090_POWER_MANAGEMENT_3, 8, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("SPKOUT", WM9090_POWER_MANAGEMENT_1, 12, 0,
- spkout, ARRAY_SIZE(spkout)),
-
-SND_SOC_DAPM_OUTPUT("HPR"),
-SND_SOC_DAPM_OUTPUT("HPL"),
-SND_SOC_DAPM_OUTPUT("Speaker"),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- { "IN1A PGA", NULL, "IN1+" },
- { "IN2A PGA", NULL, "IN2+" },
-
- { "SPKMIX", "IN1A Switch", "IN1A PGA" },
- { "SPKMIX", "IN2A Switch", "IN2A PGA" },
-
- { "MIXOUTL", "IN1A Switch", "IN1A PGA" },
- { "MIXOUTL", "IN2A Switch", "IN2A PGA" },
-
- { "MIXOUTR", "IN1A Switch", "IN1A PGA" },
- { "MIXOUTR", "IN2A Switch", "IN2A PGA" },
-
- { "HP PGA", NULL, "OSC" },
- { "HP PGA", NULL, "MIXOUTL" },
- { "HP PGA", NULL, "MIXOUTR" },
-
- { "HPL", NULL, "HP PGA" },
- { "HPR", NULL, "HP PGA" },
-
- { "SPKPGA", NULL, "OSC" },
- { "SPKPGA", NULL, "SPKMIX" },
-
- { "SPKOUT", "Mixer Switch", "SPKPGA" },
-
- { "Speaker", NULL, "SPKOUT" },
-};
-
-static const struct snd_soc_dapm_route audio_map_in1_se[] = {
- { "IN1B PGA", NULL, "IN1-" },
-
- { "SPKMIX", "IN1B Switch", "IN1B PGA" },
- { "MIXOUTL", "IN1B Switch", "IN1B PGA" },
- { "MIXOUTR", "IN1B Switch", "IN1B PGA" },
-};
-
-static const struct snd_soc_dapm_route audio_map_in1_diff[] = {
- { "IN1A PGA", NULL, "IN1-" },
-};
-
-static const struct snd_soc_dapm_route audio_map_in2_se[] = {
- { "IN2B PGA", NULL, "IN2-" },
-
- { "SPKMIX", "IN2B Switch", "IN2B PGA" },
- { "MIXOUTL", "IN2B Switch", "IN2B PGA" },
- { "MIXOUTR", "IN2B Switch", "IN2B PGA" },
-};
-
-static const struct snd_soc_dapm_route audio_map_in2_diff[] = {
- { "IN2A PGA", NULL, "IN2-" },
-};
-
-static int wm9090_add_controls(struct snd_soc_codec *codec)
-{
- struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int i;
-
- snd_soc_dapm_new_controls(dapm, wm9090_dapm_widgets,
- ARRAY_SIZE(wm9090_dapm_widgets));
-
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
- snd_soc_add_codec_controls(codec, wm9090_controls,
- ARRAY_SIZE(wm9090_controls));
-
- if (wm9090->pdata.lin1_diff) {
- snd_soc_dapm_add_routes(dapm, audio_map_in1_diff,
- ARRAY_SIZE(audio_map_in1_diff));
- } else {
- snd_soc_dapm_add_routes(dapm, audio_map_in1_se,
- ARRAY_SIZE(audio_map_in1_se));
- snd_soc_add_codec_controls(codec, wm9090_in1_se_controls,
- ARRAY_SIZE(wm9090_in1_se_controls));
- }
-
- if (wm9090->pdata.lin2_diff) {
- snd_soc_dapm_add_routes(dapm, audio_map_in2_diff,
- ARRAY_SIZE(audio_map_in2_diff));
- } else {
- snd_soc_dapm_add_routes(dapm, audio_map_in2_se,
- ARRAY_SIZE(audio_map_in2_se));
- snd_soc_add_codec_controls(codec, wm9090_in2_se_controls,
- ARRAY_SIZE(wm9090_in2_se_controls));
- }
-
- if (wm9090->pdata.agc_ena) {
- for (i = 0; i < ARRAY_SIZE(wm9090->pdata.agc); i++)
- snd_soc_write(codec, WM9090_AGC_CONTROL_0 + i,
- wm9090->pdata.agc[i]);
- snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_3,
- WM9090_AGC_ENA, WM9090_AGC_ENA);
- } else {
- snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_3,
- WM9090_AGC_ENA, 0);
- }
-
- return 0;
-
-}
-
-/*
- * The machine driver should call this from their set_bias_level; if there
- * isn't one then this can just be set as the set_bias_level function.
- */
-static int wm9090_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- snd_soc_update_bits(codec, WM9090_ANTIPOP2, WM9090_VMID_ENA,
- WM9090_VMID_ENA);
- snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_1,
- WM9090_BIAS_ENA |
- WM9090_VMID_RES_MASK,
- WM9090_BIAS_ENA |
- 1 << WM9090_VMID_RES_SHIFT);
- msleep(1); /* Probably an overestimate */
- break;
-
- case SND_SOC_BIAS_STANDBY:
- if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- /* Restore the register cache */
- regcache_sync(wm9090->regmap);
- }
-
- /* We keep VMID off during standby since the combination of
- * ground referenced outputs and class D speaker mean that
- * latency is not an issue.
- */
- snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_1,
- WM9090_BIAS_ENA | WM9090_VMID_RES_MASK, 0);
- snd_soc_update_bits(codec, WM9090_ANTIPOP2,
- WM9090_VMID_ENA, 0);
- break;
-
- case SND_SOC_BIAS_OFF:
- break;
- }
-
- codec->dapm.bias_level = level;
-
- return 0;
-}
-
-static int wm9090_probe(struct snd_soc_codec *codec)
-{
- struct wm9090_priv *wm9090 = dev_get_drvdata(codec->dev);
- int ret;
-
- codec->control_data = wm9090->regmap;
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- /* Configure some defaults; they will be written out when we
- * bring the bias up.
- */
- snd_soc_update_bits(codec, WM9090_IN1_LINE_INPUT_A_VOLUME,
- WM9090_IN1_VU | WM9090_IN1A_ZC,
- WM9090_IN1_VU | WM9090_IN1A_ZC);
- snd_soc_update_bits(codec, WM9090_IN1_LINE_INPUT_B_VOLUME,
- WM9090_IN1_VU | WM9090_IN1B_ZC,
- WM9090_IN1_VU | WM9090_IN1B_ZC);
- snd_soc_update_bits(codec, WM9090_IN2_LINE_INPUT_A_VOLUME,
- WM9090_IN2_VU | WM9090_IN2A_ZC,
- WM9090_IN2_VU | WM9090_IN2A_ZC);
- snd_soc_update_bits(codec, WM9090_IN2_LINE_INPUT_B_VOLUME,
- WM9090_IN2_VU | WM9090_IN2B_ZC,
- WM9090_IN2_VU | WM9090_IN2B_ZC);
- snd_soc_update_bits(codec, WM9090_SPEAKER_VOLUME_LEFT,
- WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC,
- WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC);
- snd_soc_update_bits(codec, WM9090_LEFT_OUTPUT_VOLUME,
- WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC,
- WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC);
- snd_soc_update_bits(codec, WM9090_RIGHT_OUTPUT_VOLUME,
- WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC,
- WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC);
-
- snd_soc_update_bits(codec, WM9090_CLOCKING_1,
- WM9090_TOCLK_ENA, WM9090_TOCLK_ENA);
-
- wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- wm9090_add_controls(codec);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int wm9090_suspend(struct snd_soc_codec *codec)
-{
- wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int wm9090_resume(struct snd_soc_codec *codec)
-{
- wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-#else
-#define wm9090_suspend NULL
-#define wm9090_resume NULL
-#endif
-
-static int wm9090_remove(struct snd_soc_codec *codec)
-{
- wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm9090 = {
- .probe = wm9090_probe,
- .remove = wm9090_remove,
- .suspend = wm9090_suspend,
- .resume = wm9090_resume,
- .set_bias_level = wm9090_set_bias_level,
-};
-
-static const struct regmap_config wm9090_regmap = {
- .reg_bits = 8,
- .val_bits = 16,
-
- .max_register = WM9090_MAX_REGISTER,
- .volatile_reg = wm9090_volatile,
- .readable_reg = wm9090_readable,
-
- .cache_type = REGCACHE_RBTREE,
- .reg_defaults = wm9090_reg_defaults,
- .num_reg_defaults = ARRAY_SIZE(wm9090_reg_defaults),
-};
-
-
-static int wm9090_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm9090_priv *wm9090;
- unsigned int reg;
- int ret;
-
- wm9090 = devm_kzalloc(&i2c->dev, sizeof(*wm9090), GFP_KERNEL);
- if (wm9090 == NULL) {
- dev_err(&i2c->dev, "Can not allocate memory\n");
- return -ENOMEM;
- }
-
- wm9090->regmap = regmap_init_i2c(i2c, &wm9090_regmap);
- if (IS_ERR(wm9090->regmap)) {
- ret = PTR_ERR(wm9090->regmap);
- dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
- return ret;
- }
-
- ret = regmap_read(wm9090->regmap, WM9090_SOFTWARE_RESET, &reg);
- if (ret < 0)
- goto err;
- if (reg != 0x9093) {
- dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", reg);
- ret = -ENODEV;
- goto err;
- }
-
- ret = regmap_write(wm9090->regmap, WM9090_SOFTWARE_RESET, 0);
- if (ret < 0)
- goto err;
-
- if (i2c->dev.platform_data)
- memcpy(&wm9090->pdata, i2c->dev.platform_data,
- sizeof(wm9090->pdata));
-
- i2c_set_clientdata(i2c, wm9090);
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_wm9090, NULL, 0);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
- goto err;
- }
-
- return 0;
-
-err:
- regmap_exit(wm9090->regmap);
- return ret;
-}
-
-static int __devexit wm9090_i2c_remove(struct i2c_client *i2c)
-{
- struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c);
-
- snd_soc_unregister_codec(&i2c->dev);
- regmap_exit(wm9090->regmap);
-
- return 0;
-}
-
-static const struct i2c_device_id wm9090_id[] = {
- { "wm9090", 0 },
- { "wm9093", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm9090_id);
-
-static struct i2c_driver wm9090_i2c_driver = {
- .driver = {
- .name = "wm9090",
- .owner = THIS_MODULE,
- },
- .probe = wm9090_i2c_probe,
- .remove = __devexit_p(wm9090_i2c_remove),
- .id_table = wm9090_id,
-};
-
-static int __init wm9090_init(void)
-{
- return i2c_add_driver(&wm9090_i2c_driver);
-}
-module_init(wm9090_init);
-
-static void __exit wm9090_exit(void)
-{
- i2c_del_driver(&wm9090_i2c_driver);
-}
-module_exit(wm9090_exit);
-
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_DESCRIPTION("WM9090 ASoC driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm9090.h b/ANDROID_3.4.5/sound/soc/codecs/wm9090.h
deleted file mode 100644
index 29b9d9fc..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm9090.h
+++ /dev/null
@@ -1,713 +0,0 @@
-/*
- * ALSA SoC WM9090 driver
- *
- * Copyright 2009 Wolfson Microelectronics
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#ifndef __WM9090_H
-#define __WM9090_H
-
-/*
- * Register values.
- */
-#define WM9090_SOFTWARE_RESET 0x00
-#define WM9090_POWER_MANAGEMENT_1 0x01
-#define WM9090_POWER_MANAGEMENT_2 0x02
-#define WM9090_POWER_MANAGEMENT_3 0x03
-#define WM9090_CLOCKING_1 0x06
-#define WM9090_IN1_LINE_CONTROL 0x16
-#define WM9090_IN2_LINE_CONTROL 0x17
-#define WM9090_IN1_LINE_INPUT_A_VOLUME 0x18
-#define WM9090_IN1_LINE_INPUT_B_VOLUME 0x19
-#define WM9090_IN2_LINE_INPUT_A_VOLUME 0x1A
-#define WM9090_IN2_LINE_INPUT_B_VOLUME 0x1B
-#define WM9090_LEFT_OUTPUT_VOLUME 0x1C
-#define WM9090_RIGHT_OUTPUT_VOLUME 0x1D
-#define WM9090_SPKMIXL_ATTENUATION 0x22
-#define WM9090_SPKOUT_MIXERS 0x24
-#define WM9090_CLASSD3 0x25
-#define WM9090_SPEAKER_VOLUME_LEFT 0x26
-#define WM9090_OUTPUT_MIXER1 0x2D
-#define WM9090_OUTPUT_MIXER2 0x2E
-#define WM9090_OUTPUT_MIXER3 0x2F
-#define WM9090_OUTPUT_MIXER4 0x30
-#define WM9090_SPEAKER_MIXER 0x36
-#define WM9090_ANTIPOP2 0x39
-#define WM9090_WRITE_SEQUENCER_0 0x46
-#define WM9090_WRITE_SEQUENCER_1 0x47
-#define WM9090_WRITE_SEQUENCER_2 0x48
-#define WM9090_WRITE_SEQUENCER_3 0x49
-#define WM9090_WRITE_SEQUENCER_4 0x4A
-#define WM9090_WRITE_SEQUENCER_5 0x4B
-#define WM9090_CHARGE_PUMP_1 0x4C
-#define WM9090_DC_SERVO_0 0x54
-#define WM9090_DC_SERVO_1 0x55
-#define WM9090_DC_SERVO_3 0x57
-#define WM9090_DC_SERVO_READBACK_0 0x58
-#define WM9090_DC_SERVO_READBACK_1 0x59
-#define WM9090_DC_SERVO_READBACK_2 0x5A
-#define WM9090_ANALOGUE_HP_0 0x60
-#define WM9090_AGC_CONTROL_0 0x62
-#define WM9090_AGC_CONTROL_1 0x63
-#define WM9090_AGC_CONTROL_2 0x64
-
-#define WM9090_REGISTER_COUNT 40
-#define WM9090_MAX_REGISTER 0x64
-
-/*
- * Field Definitions.
- */
-
-/*
- * R0 (0x00) - Software Reset
- */
-#define WM9090_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
-#define WM9090_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
-#define WM9090_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
-
-/*
- * R1 (0x01) - Power Management (1)
- */
-#define WM9090_SPKOUTL_ENA 0x1000 /* SPKOUTL_ENA */
-#define WM9090_SPKOUTL_ENA_MASK 0x1000 /* SPKOUTL_ENA */
-#define WM9090_SPKOUTL_ENA_SHIFT 12 /* SPKOUTL_ENA */
-#define WM9090_SPKOUTL_ENA_WIDTH 1 /* SPKOUTL_ENA */
-#define WM9090_HPOUT1L_ENA 0x0200 /* HPOUT1L_ENA */
-#define WM9090_HPOUT1L_ENA_MASK 0x0200 /* HPOUT1L_ENA */
-#define WM9090_HPOUT1L_ENA_SHIFT 9 /* HPOUT1L_ENA */
-#define WM9090_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */
-#define WM9090_HPOUT1R_ENA 0x0100 /* HPOUT1R_ENA */
-#define WM9090_HPOUT1R_ENA_MASK 0x0100 /* HPOUT1R_ENA */
-#define WM9090_HPOUT1R_ENA_SHIFT 8 /* HPOUT1R_ENA */
-#define WM9090_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */
-#define WM9090_OSC_ENA 0x0008 /* OSC_ENA */
-#define WM9090_OSC_ENA_MASK 0x0008 /* OSC_ENA */
-#define WM9090_OSC_ENA_SHIFT 3 /* OSC_ENA */
-#define WM9090_OSC_ENA_WIDTH 1 /* OSC_ENA */
-#define WM9090_VMID_RES_MASK 0x0006 /* VMID_RES - [2:1] */
-#define WM9090_VMID_RES_SHIFT 1 /* VMID_RES - [2:1] */
-#define WM9090_VMID_RES_WIDTH 2 /* VMID_RES - [2:1] */
-#define WM9090_BIAS_ENA 0x0001 /* BIAS_ENA */
-#define WM9090_BIAS_ENA_MASK 0x0001 /* BIAS_ENA */
-#define WM9090_BIAS_ENA_SHIFT 0 /* BIAS_ENA */
-#define WM9090_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
-
-/*
- * R2 (0x02) - Power Management (2)
- */
-#define WM9090_TSHUT 0x8000 /* TSHUT */
-#define WM9090_TSHUT_MASK 0x8000 /* TSHUT */
-#define WM9090_TSHUT_SHIFT 15 /* TSHUT */
-#define WM9090_TSHUT_WIDTH 1 /* TSHUT */
-#define WM9090_TSHUT_ENA 0x4000 /* TSHUT_ENA */
-#define WM9090_TSHUT_ENA_MASK 0x4000 /* TSHUT_ENA */
-#define WM9090_TSHUT_ENA_SHIFT 14 /* TSHUT_ENA */
-#define WM9090_TSHUT_ENA_WIDTH 1 /* TSHUT_ENA */
-#define WM9090_TSHUT_OPDIS 0x2000 /* TSHUT_OPDIS */
-#define WM9090_TSHUT_OPDIS_MASK 0x2000 /* TSHUT_OPDIS */
-#define WM9090_TSHUT_OPDIS_SHIFT 13 /* TSHUT_OPDIS */
-#define WM9090_TSHUT_OPDIS_WIDTH 1 /* TSHUT_OPDIS */
-#define WM9090_IN1A_ENA 0x0080 /* IN1A_ENA */
-#define WM9090_IN1A_ENA_MASK 0x0080 /* IN1A_ENA */
-#define WM9090_IN1A_ENA_SHIFT 7 /* IN1A_ENA */
-#define WM9090_IN1A_ENA_WIDTH 1 /* IN1A_ENA */
-#define WM9090_IN1B_ENA 0x0040 /* IN1B_ENA */
-#define WM9090_IN1B_ENA_MASK 0x0040 /* IN1B_ENA */
-#define WM9090_IN1B_ENA_SHIFT 6 /* IN1B_ENA */
-#define WM9090_IN1B_ENA_WIDTH 1 /* IN1B_ENA */
-#define WM9090_IN2A_ENA 0x0020 /* IN2A_ENA */
-#define WM9090_IN2A_ENA_MASK 0x0020 /* IN2A_ENA */
-#define WM9090_IN2A_ENA_SHIFT 5 /* IN2A_ENA */
-#define WM9090_IN2A_ENA_WIDTH 1 /* IN2A_ENA */
-#define WM9090_IN2B_ENA 0x0010 /* IN2B_ENA */
-#define WM9090_IN2B_ENA_MASK 0x0010 /* IN2B_ENA */
-#define WM9090_IN2B_ENA_SHIFT 4 /* IN2B_ENA */
-#define WM9090_IN2B_ENA_WIDTH 1 /* IN2B_ENA */
-
-/*
- * R3 (0x03) - Power Management (3)
- */
-#define WM9090_AGC_ENA 0x4000 /* AGC_ENA */
-#define WM9090_AGC_ENA_MASK 0x4000 /* AGC_ENA */
-#define WM9090_AGC_ENA_SHIFT 14 /* AGC_ENA */
-#define WM9090_AGC_ENA_WIDTH 1 /* AGC_ENA */
-#define WM9090_SPKLVOL_ENA 0x0100 /* SPKLVOL_ENA */
-#define WM9090_SPKLVOL_ENA_MASK 0x0100 /* SPKLVOL_ENA */
-#define WM9090_SPKLVOL_ENA_SHIFT 8 /* SPKLVOL_ENA */
-#define WM9090_SPKLVOL_ENA_WIDTH 1 /* SPKLVOL_ENA */
-#define WM9090_MIXOUTL_ENA 0x0020 /* MIXOUTL_ENA */
-#define WM9090_MIXOUTL_ENA_MASK 0x0020 /* MIXOUTL_ENA */
-#define WM9090_MIXOUTL_ENA_SHIFT 5 /* MIXOUTL_ENA */
-#define WM9090_MIXOUTL_ENA_WIDTH 1 /* MIXOUTL_ENA */
-#define WM9090_MIXOUTR_ENA 0x0010 /* MIXOUTR_ENA */
-#define WM9090_MIXOUTR_ENA_MASK 0x0010 /* MIXOUTR_ENA */
-#define WM9090_MIXOUTR_ENA_SHIFT 4 /* MIXOUTR_ENA */
-#define WM9090_MIXOUTR_ENA_WIDTH 1 /* MIXOUTR_ENA */
-#define WM9090_SPKMIX_ENA 0x0008 /* SPKMIX_ENA */
-#define WM9090_SPKMIX_ENA_MASK 0x0008 /* SPKMIX_ENA */
-#define WM9090_SPKMIX_ENA_SHIFT 3 /* SPKMIX_ENA */
-#define WM9090_SPKMIX_ENA_WIDTH 1 /* SPKMIX_ENA */
-
-/*
- * R6 (0x06) - Clocking 1
- */
-#define WM9090_TOCLK_RATE 0x8000 /* TOCLK_RATE */
-#define WM9090_TOCLK_RATE_MASK 0x8000 /* TOCLK_RATE */
-#define WM9090_TOCLK_RATE_SHIFT 15 /* TOCLK_RATE */
-#define WM9090_TOCLK_RATE_WIDTH 1 /* TOCLK_RATE */
-#define WM9090_TOCLK_ENA 0x4000 /* TOCLK_ENA */
-#define WM9090_TOCLK_ENA_MASK 0x4000 /* TOCLK_ENA */
-#define WM9090_TOCLK_ENA_SHIFT 14 /* TOCLK_ENA */
-#define WM9090_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
-
-/*
- * R22 (0x16) - IN1 Line Control
- */
-#define WM9090_IN1_DIFF 0x0002 /* IN1_DIFF */
-#define WM9090_IN1_DIFF_MASK 0x0002 /* IN1_DIFF */
-#define WM9090_IN1_DIFF_SHIFT 1 /* IN1_DIFF */
-#define WM9090_IN1_DIFF_WIDTH 1 /* IN1_DIFF */
-#define WM9090_IN1_CLAMP 0x0001 /* IN1_CLAMP */
-#define WM9090_IN1_CLAMP_MASK 0x0001 /* IN1_CLAMP */
-#define WM9090_IN1_CLAMP_SHIFT 0 /* IN1_CLAMP */
-#define WM9090_IN1_CLAMP_WIDTH 1 /* IN1_CLAMP */
-
-/*
- * R23 (0x17) - IN2 Line Control
- */
-#define WM9090_IN2_DIFF 0x0002 /* IN2_DIFF */
-#define WM9090_IN2_DIFF_MASK 0x0002 /* IN2_DIFF */
-#define WM9090_IN2_DIFF_SHIFT 1 /* IN2_DIFF */
-#define WM9090_IN2_DIFF_WIDTH 1 /* IN2_DIFF */
-#define WM9090_IN2_CLAMP 0x0001 /* IN2_CLAMP */
-#define WM9090_IN2_CLAMP_MASK 0x0001 /* IN2_CLAMP */
-#define WM9090_IN2_CLAMP_SHIFT 0 /* IN2_CLAMP */
-#define WM9090_IN2_CLAMP_WIDTH 1 /* IN2_CLAMP */
-
-/*
- * R24 (0x18) - IN1 Line Input A Volume
- */
-#define WM9090_IN1_VU 0x0100 /* IN1_VU */
-#define WM9090_IN1_VU_MASK 0x0100 /* IN1_VU */
-#define WM9090_IN1_VU_SHIFT 8 /* IN1_VU */
-#define WM9090_IN1_VU_WIDTH 1 /* IN1_VU */
-#define WM9090_IN1A_MUTE 0x0080 /* IN1A_MUTE */
-#define WM9090_IN1A_MUTE_MASK 0x0080 /* IN1A_MUTE */
-#define WM9090_IN1A_MUTE_SHIFT 7 /* IN1A_MUTE */
-#define WM9090_IN1A_MUTE_WIDTH 1 /* IN1A_MUTE */
-#define WM9090_IN1A_ZC 0x0040 /* IN1A_ZC */
-#define WM9090_IN1A_ZC_MASK 0x0040 /* IN1A_ZC */
-#define WM9090_IN1A_ZC_SHIFT 6 /* IN1A_ZC */
-#define WM9090_IN1A_ZC_WIDTH 1 /* IN1A_ZC */
-#define WM9090_IN1A_VOL_MASK 0x0007 /* IN1A_VOL - [2:0] */
-#define WM9090_IN1A_VOL_SHIFT 0 /* IN1A_VOL - [2:0] */
-#define WM9090_IN1A_VOL_WIDTH 3 /* IN1A_VOL - [2:0] */
-
-/*
- * R25 (0x19) - IN1 Line Input B Volume
- */
-#define WM9090_IN1_VU 0x0100 /* IN1_VU */
-#define WM9090_IN1_VU_MASK 0x0100 /* IN1_VU */
-#define WM9090_IN1_VU_SHIFT 8 /* IN1_VU */
-#define WM9090_IN1_VU_WIDTH 1 /* IN1_VU */
-#define WM9090_IN1B_MUTE 0x0080 /* IN1B_MUTE */
-#define WM9090_IN1B_MUTE_MASK 0x0080 /* IN1B_MUTE */
-#define WM9090_IN1B_MUTE_SHIFT 7 /* IN1B_MUTE */
-#define WM9090_IN1B_MUTE_WIDTH 1 /* IN1B_MUTE */
-#define WM9090_IN1B_ZC 0x0040 /* IN1B_ZC */
-#define WM9090_IN1B_ZC_MASK 0x0040 /* IN1B_ZC */
-#define WM9090_IN1B_ZC_SHIFT 6 /* IN1B_ZC */
-#define WM9090_IN1B_ZC_WIDTH 1 /* IN1B_ZC */
-#define WM9090_IN1B_VOL_MASK 0x0007 /* IN1B_VOL - [2:0] */
-#define WM9090_IN1B_VOL_SHIFT 0 /* IN1B_VOL - [2:0] */
-#define WM9090_IN1B_VOL_WIDTH 3 /* IN1B_VOL - [2:0] */
-
-/*
- * R26 (0x1A) - IN2 Line Input A Volume
- */
-#define WM9090_IN2_VU 0x0100 /* IN2_VU */
-#define WM9090_IN2_VU_MASK 0x0100 /* IN2_VU */
-#define WM9090_IN2_VU_SHIFT 8 /* IN2_VU */
-#define WM9090_IN2_VU_WIDTH 1 /* IN2_VU */
-#define WM9090_IN2A_MUTE 0x0080 /* IN2A_MUTE */
-#define WM9090_IN2A_MUTE_MASK 0x0080 /* IN2A_MUTE */
-#define WM9090_IN2A_MUTE_SHIFT 7 /* IN2A_MUTE */
-#define WM9090_IN2A_MUTE_WIDTH 1 /* IN2A_MUTE */
-#define WM9090_IN2A_ZC 0x0040 /* IN2A_ZC */
-#define WM9090_IN2A_ZC_MASK 0x0040 /* IN2A_ZC */
-#define WM9090_IN2A_ZC_SHIFT 6 /* IN2A_ZC */
-#define WM9090_IN2A_ZC_WIDTH 1 /* IN2A_ZC */
-#define WM9090_IN2A_VOL_MASK 0x0007 /* IN2A_VOL - [2:0] */
-#define WM9090_IN2A_VOL_SHIFT 0 /* IN2A_VOL - [2:0] */
-#define WM9090_IN2A_VOL_WIDTH 3 /* IN2A_VOL - [2:0] */
-
-/*
- * R27 (0x1B) - IN2 Line Input B Volume
- */
-#define WM9090_IN2_VU 0x0100 /* IN2_VU */
-#define WM9090_IN2_VU_MASK 0x0100 /* IN2_VU */
-#define WM9090_IN2_VU_SHIFT 8 /* IN2_VU */
-#define WM9090_IN2_VU_WIDTH 1 /* IN2_VU */
-#define WM9090_IN2B_MUTE 0x0080 /* IN2B_MUTE */
-#define WM9090_IN2B_MUTE_MASK 0x0080 /* IN2B_MUTE */
-#define WM9090_IN2B_MUTE_SHIFT 7 /* IN2B_MUTE */
-#define WM9090_IN2B_MUTE_WIDTH 1 /* IN2B_MUTE */
-#define WM9090_IN2B_ZC 0x0040 /* IN2B_ZC */
-#define WM9090_IN2B_ZC_MASK 0x0040 /* IN2B_ZC */
-#define WM9090_IN2B_ZC_SHIFT 6 /* IN2B_ZC */
-#define WM9090_IN2B_ZC_WIDTH 1 /* IN2B_ZC */
-#define WM9090_IN2B_VOL_MASK 0x0007 /* IN2B_VOL - [2:0] */
-#define WM9090_IN2B_VOL_SHIFT 0 /* IN2B_VOL - [2:0] */
-#define WM9090_IN2B_VOL_WIDTH 3 /* IN2B_VOL - [2:0] */
-
-/*
- * R28 (0x1C) - Left Output Volume
- */
-#define WM9090_HPOUT1_VU 0x0100 /* HPOUT1_VU */
-#define WM9090_HPOUT1_VU_MASK 0x0100 /* HPOUT1_VU */
-#define WM9090_HPOUT1_VU_SHIFT 8 /* HPOUT1_VU */
-#define WM9090_HPOUT1_VU_WIDTH 1 /* HPOUT1_VU */
-#define WM9090_HPOUT1L_ZC 0x0080 /* HPOUT1L_ZC */
-#define WM9090_HPOUT1L_ZC_MASK 0x0080 /* HPOUT1L_ZC */
-#define WM9090_HPOUT1L_ZC_SHIFT 7 /* HPOUT1L_ZC */
-#define WM9090_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */
-#define WM9090_HPOUT1L_MUTE 0x0040 /* HPOUT1L_MUTE */
-#define WM9090_HPOUT1L_MUTE_MASK 0x0040 /* HPOUT1L_MUTE */
-#define WM9090_HPOUT1L_MUTE_SHIFT 6 /* HPOUT1L_MUTE */
-#define WM9090_HPOUT1L_MUTE_WIDTH 1 /* HPOUT1L_MUTE */
-#define WM9090_HPOUT1L_VOL_MASK 0x003F /* HPOUT1L_VOL - [5:0] */
-#define WM9090_HPOUT1L_VOL_SHIFT 0 /* HPOUT1L_VOL - [5:0] */
-#define WM9090_HPOUT1L_VOL_WIDTH 6 /* HPOUT1L_VOL - [5:0] */
-
-/*
- * R29 (0x1D) - Right Output Volume
- */
-#define WM9090_HPOUT1_VU 0x0100 /* HPOUT1_VU */
-#define WM9090_HPOUT1_VU_MASK 0x0100 /* HPOUT1_VU */
-#define WM9090_HPOUT1_VU_SHIFT 8 /* HPOUT1_VU */
-#define WM9090_HPOUT1_VU_WIDTH 1 /* HPOUT1_VU */
-#define WM9090_HPOUT1R_ZC 0x0080 /* HPOUT1R_ZC */
-#define WM9090_HPOUT1R_ZC_MASK 0x0080 /* HPOUT1R_ZC */
-#define WM9090_HPOUT1R_ZC_SHIFT 7 /* HPOUT1R_ZC */
-#define WM9090_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */
-#define WM9090_HPOUT1R_MUTE 0x0040 /* HPOUT1R_MUTE */
-#define WM9090_HPOUT1R_MUTE_MASK 0x0040 /* HPOUT1R_MUTE */
-#define WM9090_HPOUT1R_MUTE_SHIFT 6 /* HPOUT1R_MUTE */
-#define WM9090_HPOUT1R_MUTE_WIDTH 1 /* HPOUT1R_MUTE */
-#define WM9090_HPOUT1R_VOL_MASK 0x003F /* HPOUT1R_VOL - [5:0] */
-#define WM9090_HPOUT1R_VOL_SHIFT 0 /* HPOUT1R_VOL - [5:0] */
-#define WM9090_HPOUT1R_VOL_WIDTH 6 /* HPOUT1R_VOL - [5:0] */
-
-/*
- * R34 (0x22) - SPKMIXL Attenuation
- */
-#define WM9090_SPKMIX_MUTE 0x0100 /* SPKMIX_MUTE */
-#define WM9090_SPKMIX_MUTE_MASK 0x0100 /* SPKMIX_MUTE */
-#define WM9090_SPKMIX_MUTE_SHIFT 8 /* SPKMIX_MUTE */
-#define WM9090_SPKMIX_MUTE_WIDTH 1 /* SPKMIX_MUTE */
-#define WM9090_IN1A_SPKMIX_VOL_MASK 0x00C0 /* IN1A_SPKMIX_VOL - [7:6] */
-#define WM9090_IN1A_SPKMIX_VOL_SHIFT 6 /* IN1A_SPKMIX_VOL - [7:6] */
-#define WM9090_IN1A_SPKMIX_VOL_WIDTH 2 /* IN1A_SPKMIX_VOL - [7:6] */
-#define WM9090_IN1B_SPKMIX_VOL_MASK 0x0030 /* IN1B_SPKMIX_VOL - [5:4] */
-#define WM9090_IN1B_SPKMIX_VOL_SHIFT 4 /* IN1B_SPKMIX_VOL - [5:4] */
-#define WM9090_IN1B_SPKMIX_VOL_WIDTH 2 /* IN1B_SPKMIX_VOL - [5:4] */
-#define WM9090_IN2A_SPKMIX_VOL_MASK 0x000C /* IN2A_SPKMIX_VOL - [3:2] */
-#define WM9090_IN2A_SPKMIX_VOL_SHIFT 2 /* IN2A_SPKMIX_VOL - [3:2] */
-#define WM9090_IN2A_SPKMIX_VOL_WIDTH 2 /* IN2A_SPKMIX_VOL - [3:2] */
-#define WM9090_IN2B_SPKMIX_VOL_MASK 0x0003 /* IN2B_SPKMIX_VOL - [1:0] */
-#define WM9090_IN2B_SPKMIX_VOL_SHIFT 0 /* IN2B_SPKMIX_VOL - [1:0] */
-#define WM9090_IN2B_SPKMIX_VOL_WIDTH 2 /* IN2B_SPKMIX_VOL - [1:0] */
-
-/*
- * R36 (0x24) - SPKOUT Mixers
- */
-#define WM9090_SPKMIXL_TO_SPKOUTL 0x0010 /* SPKMIXL_TO_SPKOUTL */
-#define WM9090_SPKMIXL_TO_SPKOUTL_MASK 0x0010 /* SPKMIXL_TO_SPKOUTL */
-#define WM9090_SPKMIXL_TO_SPKOUTL_SHIFT 4 /* SPKMIXL_TO_SPKOUTL */
-#define WM9090_SPKMIXL_TO_SPKOUTL_WIDTH 1 /* SPKMIXL_TO_SPKOUTL */
-
-/*
- * R37 (0x25) - ClassD3
- */
-#define WM9090_SPKOUTL_BOOST_MASK 0x0038 /* SPKOUTL_BOOST - [5:3] */
-#define WM9090_SPKOUTL_BOOST_SHIFT 3 /* SPKOUTL_BOOST - [5:3] */
-#define WM9090_SPKOUTL_BOOST_WIDTH 3 /* SPKOUTL_BOOST - [5:3] */
-
-/*
- * R38 (0x26) - Speaker Volume Left
- */
-#define WM9090_SPKOUT_VU 0x0100 /* SPKOUT_VU */
-#define WM9090_SPKOUT_VU_MASK 0x0100 /* SPKOUT_VU */
-#define WM9090_SPKOUT_VU_SHIFT 8 /* SPKOUT_VU */
-#define WM9090_SPKOUT_VU_WIDTH 1 /* SPKOUT_VU */
-#define WM9090_SPKOUTL_ZC 0x0080 /* SPKOUTL_ZC */
-#define WM9090_SPKOUTL_ZC_MASK 0x0080 /* SPKOUTL_ZC */
-#define WM9090_SPKOUTL_ZC_SHIFT 7 /* SPKOUTL_ZC */
-#define WM9090_SPKOUTL_ZC_WIDTH 1 /* SPKOUTL_ZC */
-#define WM9090_SPKOUTL_MUTE 0x0040 /* SPKOUTL_MUTE */
-#define WM9090_SPKOUTL_MUTE_MASK 0x0040 /* SPKOUTL_MUTE */
-#define WM9090_SPKOUTL_MUTE_SHIFT 6 /* SPKOUTL_MUTE */
-#define WM9090_SPKOUTL_MUTE_WIDTH 1 /* SPKOUTL_MUTE */
-#define WM9090_SPKOUTL_VOL_MASK 0x003F /* SPKOUTL_VOL - [5:0] */
-#define WM9090_SPKOUTL_VOL_SHIFT 0 /* SPKOUTL_VOL - [5:0] */
-#define WM9090_SPKOUTL_VOL_WIDTH 6 /* SPKOUTL_VOL - [5:0] */
-
-/*
- * R45 (0x2D) - Output Mixer1
- */
-#define WM9090_IN1A_TO_MIXOUTL 0x0040 /* IN1A_TO_MIXOUTL */
-#define WM9090_IN1A_TO_MIXOUTL_MASK 0x0040 /* IN1A_TO_MIXOUTL */
-#define WM9090_IN1A_TO_MIXOUTL_SHIFT 6 /* IN1A_TO_MIXOUTL */
-#define WM9090_IN1A_TO_MIXOUTL_WIDTH 1 /* IN1A_TO_MIXOUTL */
-#define WM9090_IN2A_TO_MIXOUTL 0x0004 /* IN2A_TO_MIXOUTL */
-#define WM9090_IN2A_TO_MIXOUTL_MASK 0x0004 /* IN2A_TO_MIXOUTL */
-#define WM9090_IN2A_TO_MIXOUTL_SHIFT 2 /* IN2A_TO_MIXOUTL */
-#define WM9090_IN2A_TO_MIXOUTL_WIDTH 1 /* IN2A_TO_MIXOUTL */
-
-/*
- * R46 (0x2E) - Output Mixer2
- */
-#define WM9090_IN1A_TO_MIXOUTR 0x0040 /* IN1A_TO_MIXOUTR */
-#define WM9090_IN1A_TO_MIXOUTR_MASK 0x0040 /* IN1A_TO_MIXOUTR */
-#define WM9090_IN1A_TO_MIXOUTR_SHIFT 6 /* IN1A_TO_MIXOUTR */
-#define WM9090_IN1A_TO_MIXOUTR_WIDTH 1 /* IN1A_TO_MIXOUTR */
-#define WM9090_IN1B_TO_MIXOUTR 0x0010 /* IN1B_TO_MIXOUTR */
-#define WM9090_IN1B_TO_MIXOUTR_MASK 0x0010 /* IN1B_TO_MIXOUTR */
-#define WM9090_IN1B_TO_MIXOUTR_SHIFT 4 /* IN1B_TO_MIXOUTR */
-#define WM9090_IN1B_TO_MIXOUTR_WIDTH 1 /* IN1B_TO_MIXOUTR */
-#define WM9090_IN2A_TO_MIXOUTR 0x0004 /* IN2A_TO_MIXOUTR */
-#define WM9090_IN2A_TO_MIXOUTR_MASK 0x0004 /* IN2A_TO_MIXOUTR */
-#define WM9090_IN2A_TO_MIXOUTR_SHIFT 2 /* IN2A_TO_MIXOUTR */
-#define WM9090_IN2A_TO_MIXOUTR_WIDTH 1 /* IN2A_TO_MIXOUTR */
-#define WM9090_IN2B_TO_MIXOUTR 0x0001 /* IN2B_TO_MIXOUTR */
-#define WM9090_IN2B_TO_MIXOUTR_MASK 0x0001 /* IN2B_TO_MIXOUTR */
-#define WM9090_IN2B_TO_MIXOUTR_SHIFT 0 /* IN2B_TO_MIXOUTR */
-#define WM9090_IN2B_TO_MIXOUTR_WIDTH 1 /* IN2B_TO_MIXOUTR */
-
-/*
- * R47 (0x2F) - Output Mixer3
- */
-#define WM9090_MIXOUTL_MUTE 0x0100 /* MIXOUTL_MUTE */
-#define WM9090_MIXOUTL_MUTE_MASK 0x0100 /* MIXOUTL_MUTE */
-#define WM9090_MIXOUTL_MUTE_SHIFT 8 /* MIXOUTL_MUTE */
-#define WM9090_MIXOUTL_MUTE_WIDTH 1 /* MIXOUTL_MUTE */
-#define WM9090_IN1A_MIXOUTL_VOL_MASK 0x00C0 /* IN1A_MIXOUTL_VOL - [7:6] */
-#define WM9090_IN1A_MIXOUTL_VOL_SHIFT 6 /* IN1A_MIXOUTL_VOL - [7:6] */
-#define WM9090_IN1A_MIXOUTL_VOL_WIDTH 2 /* IN1A_MIXOUTL_VOL - [7:6] */
-#define WM9090_IN2A_MIXOUTL_VOL_MASK 0x000C /* IN2A_MIXOUTL_VOL - [3:2] */
-#define WM9090_IN2A_MIXOUTL_VOL_SHIFT 2 /* IN2A_MIXOUTL_VOL - [3:2] */
-#define WM9090_IN2A_MIXOUTL_VOL_WIDTH 2 /* IN2A_MIXOUTL_VOL - [3:2] */
-
-/*
- * R48 (0x30) - Output Mixer4
- */
-#define WM9090_MIXOUTR_MUTE 0x0100 /* MIXOUTR_MUTE */
-#define WM9090_MIXOUTR_MUTE_MASK 0x0100 /* MIXOUTR_MUTE */
-#define WM9090_MIXOUTR_MUTE_SHIFT 8 /* MIXOUTR_MUTE */
-#define WM9090_MIXOUTR_MUTE_WIDTH 1 /* MIXOUTR_MUTE */
-#define WM9090_IN1A_MIXOUTR_VOL_MASK 0x00C0 /* IN1A_MIXOUTR_VOL - [7:6] */
-#define WM9090_IN1A_MIXOUTR_VOL_SHIFT 6 /* IN1A_MIXOUTR_VOL - [7:6] */
-#define WM9090_IN1A_MIXOUTR_VOL_WIDTH 2 /* IN1A_MIXOUTR_VOL - [7:6] */
-#define WM9090_IN1B_MIXOUTR_VOL_MASK 0x0030 /* IN1B_MIXOUTR_VOL - [5:4] */
-#define WM9090_IN1B_MIXOUTR_VOL_SHIFT 4 /* IN1B_MIXOUTR_VOL - [5:4] */
-#define WM9090_IN1B_MIXOUTR_VOL_WIDTH 2 /* IN1B_MIXOUTR_VOL - [5:4] */
-#define WM9090_IN2A_MIXOUTR_VOL_MASK 0x000C /* IN2A_MIXOUTR_VOL - [3:2] */
-#define WM9090_IN2A_MIXOUTR_VOL_SHIFT 2 /* IN2A_MIXOUTR_VOL - [3:2] */
-#define WM9090_IN2A_MIXOUTR_VOL_WIDTH 2 /* IN2A_MIXOUTR_VOL - [3:2] */
-#define WM9090_IN2B_MIXOUTR_VOL_MASK 0x0003 /* IN2B_MIXOUTR_VOL - [1:0] */
-#define WM9090_IN2B_MIXOUTR_VOL_SHIFT 0 /* IN2B_MIXOUTR_VOL - [1:0] */
-#define WM9090_IN2B_MIXOUTR_VOL_WIDTH 2 /* IN2B_MIXOUTR_VOL - [1:0] */
-
-/*
- * R54 (0x36) - Speaker Mixer
- */
-#define WM9090_IN1A_TO_SPKMIX 0x0040 /* IN1A_TO_SPKMIX */
-#define WM9090_IN1A_TO_SPKMIX_MASK 0x0040 /* IN1A_TO_SPKMIX */
-#define WM9090_IN1A_TO_SPKMIX_SHIFT 6 /* IN1A_TO_SPKMIX */
-#define WM9090_IN1A_TO_SPKMIX_WIDTH 1 /* IN1A_TO_SPKMIX */
-#define WM9090_IN1B_TO_SPKMIX 0x0010 /* IN1B_TO_SPKMIX */
-#define WM9090_IN1B_TO_SPKMIX_MASK 0x0010 /* IN1B_TO_SPKMIX */
-#define WM9090_IN1B_TO_SPKMIX_SHIFT 4 /* IN1B_TO_SPKMIX */
-#define WM9090_IN1B_TO_SPKMIX_WIDTH 1 /* IN1B_TO_SPKMIX */
-#define WM9090_IN2A_TO_SPKMIX 0x0004 /* IN2A_TO_SPKMIX */
-#define WM9090_IN2A_TO_SPKMIX_MASK 0x0004 /* IN2A_TO_SPKMIX */
-#define WM9090_IN2A_TO_SPKMIX_SHIFT 2 /* IN2A_TO_SPKMIX */
-#define WM9090_IN2A_TO_SPKMIX_WIDTH 1 /* IN2A_TO_SPKMIX */
-#define WM9090_IN2B_TO_SPKMIX 0x0001 /* IN2B_TO_SPKMIX */
-#define WM9090_IN2B_TO_SPKMIX_MASK 0x0001 /* IN2B_TO_SPKMIX */
-#define WM9090_IN2B_TO_SPKMIX_SHIFT 0 /* IN2B_TO_SPKMIX */
-#define WM9090_IN2B_TO_SPKMIX_WIDTH 1 /* IN2B_TO_SPKMIX */
-
-/*
- * R57 (0x39) - AntiPOP2
- */
-#define WM9090_VMID_BUF_ENA 0x0008 /* VMID_BUF_ENA */
-#define WM9090_VMID_BUF_ENA_MASK 0x0008 /* VMID_BUF_ENA */
-#define WM9090_VMID_BUF_ENA_SHIFT 3 /* VMID_BUF_ENA */
-#define WM9090_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
-#define WM9090_VMID_ENA 0x0001 /* VMID_ENA */
-#define WM9090_VMID_ENA_MASK 0x0001 /* VMID_ENA */
-#define WM9090_VMID_ENA_SHIFT 0 /* VMID_ENA */
-#define WM9090_VMID_ENA_WIDTH 1 /* VMID_ENA */
-
-/*
- * R70 (0x46) - Write Sequencer 0
- */
-#define WM9090_WSEQ_ENA 0x0100 /* WSEQ_ENA */
-#define WM9090_WSEQ_ENA_MASK 0x0100 /* WSEQ_ENA */
-#define WM9090_WSEQ_ENA_SHIFT 8 /* WSEQ_ENA */
-#define WM9090_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
-#define WM9090_WSEQ_WRITE_INDEX_MASK 0x000F /* WSEQ_WRITE_INDEX - [3:0] */
-#define WM9090_WSEQ_WRITE_INDEX_SHIFT 0 /* WSEQ_WRITE_INDEX - [3:0] */
-#define WM9090_WSEQ_WRITE_INDEX_WIDTH 4 /* WSEQ_WRITE_INDEX - [3:0] */
-
-/*
- * R71 (0x47) - Write Sequencer 1
- */
-#define WM9090_WSEQ_DATA_WIDTH_MASK 0x7000 /* WSEQ_DATA_WIDTH - [14:12] */
-#define WM9090_WSEQ_DATA_WIDTH_SHIFT 12 /* WSEQ_DATA_WIDTH - [14:12] */
-#define WM9090_WSEQ_DATA_WIDTH_WIDTH 3 /* WSEQ_DATA_WIDTH - [14:12] */
-#define WM9090_WSEQ_DATA_START_MASK 0x0F00 /* WSEQ_DATA_START - [11:8] */
-#define WM9090_WSEQ_DATA_START_SHIFT 8 /* WSEQ_DATA_START - [11:8] */
-#define WM9090_WSEQ_DATA_START_WIDTH 4 /* WSEQ_DATA_START - [11:8] */
-#define WM9090_WSEQ_ADDR_MASK 0x00FF /* WSEQ_ADDR - [7:0] */
-#define WM9090_WSEQ_ADDR_SHIFT 0 /* WSEQ_ADDR - [7:0] */
-#define WM9090_WSEQ_ADDR_WIDTH 8 /* WSEQ_ADDR - [7:0] */
-
-/*
- * R72 (0x48) - Write Sequencer 2
- */
-#define WM9090_WSEQ_EOS 0x4000 /* WSEQ_EOS */
-#define WM9090_WSEQ_EOS_MASK 0x4000 /* WSEQ_EOS */
-#define WM9090_WSEQ_EOS_SHIFT 14 /* WSEQ_EOS */
-#define WM9090_WSEQ_EOS_WIDTH 1 /* WSEQ_EOS */
-#define WM9090_WSEQ_DELAY_MASK 0x0F00 /* WSEQ_DELAY - [11:8] */
-#define WM9090_WSEQ_DELAY_SHIFT 8 /* WSEQ_DELAY - [11:8] */
-#define WM9090_WSEQ_DELAY_WIDTH 4 /* WSEQ_DELAY - [11:8] */
-#define WM9090_WSEQ_DATA_MASK 0x00FF /* WSEQ_DATA - [7:0] */
-#define WM9090_WSEQ_DATA_SHIFT 0 /* WSEQ_DATA - [7:0] */
-#define WM9090_WSEQ_DATA_WIDTH 8 /* WSEQ_DATA - [7:0] */
-
-/*
- * R73 (0x49) - Write Sequencer 3
- */
-#define WM9090_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
-#define WM9090_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
-#define WM9090_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
-#define WM9090_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
-#define WM9090_WSEQ_START 0x0100 /* WSEQ_START */
-#define WM9090_WSEQ_START_MASK 0x0100 /* WSEQ_START */
-#define WM9090_WSEQ_START_SHIFT 8 /* WSEQ_START */
-#define WM9090_WSEQ_START_WIDTH 1 /* WSEQ_START */
-#define WM9090_WSEQ_START_INDEX_MASK 0x003F /* WSEQ_START_INDEX - [5:0] */
-#define WM9090_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [5:0] */
-#define WM9090_WSEQ_START_INDEX_WIDTH 6 /* WSEQ_START_INDEX - [5:0] */
-
-/*
- * R74 (0x4A) - Write Sequencer 4
- */
-#define WM9090_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
-#define WM9090_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
-#define WM9090_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
-#define WM9090_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
-
-/*
- * R75 (0x4B) - Write Sequencer 5
- */
-#define WM9090_WSEQ_CURRENT_INDEX_MASK 0x003F /* WSEQ_CURRENT_INDEX - [5:0] */
-#define WM9090_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [5:0] */
-#define WM9090_WSEQ_CURRENT_INDEX_WIDTH 6 /* WSEQ_CURRENT_INDEX - [5:0] */
-
-/*
- * R76 (0x4C) - Charge Pump 1
- */
-#define WM9090_CP_ENA 0x8000 /* CP_ENA */
-#define WM9090_CP_ENA_MASK 0x8000 /* CP_ENA */
-#define WM9090_CP_ENA_SHIFT 15 /* CP_ENA */
-#define WM9090_CP_ENA_WIDTH 1 /* CP_ENA */
-
-/*
- * R84 (0x54) - DC Servo 0
- */
-#define WM9090_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
-#define WM9090_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
-#define WM9090_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
-#define WM9090_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
-#define WM9090_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
-#define WM9090_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
-#define WM9090_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
-#define WM9090_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
-#define WM9090_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
-#define WM9090_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
-#define WM9090_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
-#define WM9090_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
-#define WM9090_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
-#define WM9090_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
-#define WM9090_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
-#define WM9090_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
-#define WM9090_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
-#define WM9090_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
-#define WM9090_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
-#define WM9090_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
-#define WM9090_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
-#define WM9090_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
-#define WM9090_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
-#define WM9090_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
-#define WM9090_DCS_TRIG_DAC_WR_1 0x0008 /* DCS_TRIG_DAC_WR_1 */
-#define WM9090_DCS_TRIG_DAC_WR_1_MASK 0x0008 /* DCS_TRIG_DAC_WR_1 */
-#define WM9090_DCS_TRIG_DAC_WR_1_SHIFT 3 /* DCS_TRIG_DAC_WR_1 */
-#define WM9090_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
-#define WM9090_DCS_TRIG_DAC_WR_0 0x0004 /* DCS_TRIG_DAC_WR_0 */
-#define WM9090_DCS_TRIG_DAC_WR_0_MASK 0x0004 /* DCS_TRIG_DAC_WR_0 */
-#define WM9090_DCS_TRIG_DAC_WR_0_SHIFT 2 /* DCS_TRIG_DAC_WR_0 */
-#define WM9090_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
-#define WM9090_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
-#define WM9090_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
-#define WM9090_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
-#define WM9090_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
-#define WM9090_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
-#define WM9090_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
-#define WM9090_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
-#define WM9090_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
-
-/*
- * R85 (0x55) - DC Servo 1
- */
-#define WM9090_DCS_SERIES_NO_01_MASK 0x0FE0 /* DCS_SERIES_NO_01 - [11:5] */
-#define WM9090_DCS_SERIES_NO_01_SHIFT 5 /* DCS_SERIES_NO_01 - [11:5] */
-#define WM9090_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [11:5] */
-#define WM9090_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
-#define WM9090_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
-#define WM9090_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
-
-/*
- * R87 (0x57) - DC Servo 3
- */
-#define WM9090_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */
-#define WM9090_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
-#define WM9090_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
-#define WM9090_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
-#define WM9090_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
-#define WM9090_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
-
-/*
- * R88 (0x58) - DC Servo Readback 0
- */
-#define WM9090_DCS_CAL_COMPLETE_MASK 0x0300 /* DCS_CAL_COMPLETE - [9:8] */
-#define WM9090_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [9:8] */
-#define WM9090_DCS_CAL_COMPLETE_WIDTH 2 /* DCS_CAL_COMPLETE - [9:8] */
-#define WM9090_DCS_DAC_WR_COMPLETE_MASK 0x0030 /* DCS_DAC_WR_COMPLETE - [5:4] */
-#define WM9090_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [5:4] */
-#define WM9090_DCS_DAC_WR_COMPLETE_WIDTH 2 /* DCS_DAC_WR_COMPLETE - [5:4] */
-#define WM9090_DCS_STARTUP_COMPLETE_MASK 0x0003 /* DCS_STARTUP_COMPLETE - [1:0] */
-#define WM9090_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [1:0] */
-#define WM9090_DCS_STARTUP_COMPLETE_WIDTH 2 /* DCS_STARTUP_COMPLETE - [1:0] */
-
-/*
- * R89 (0x59) - DC Servo Readback 1
- */
-#define WM9090_DCS_DAC_WR_VAL_1_RD_MASK 0x00FF /* DCS_DAC_WR_VAL_1_RD - [7:0] */
-#define WM9090_DCS_DAC_WR_VAL_1_RD_SHIFT 0 /* DCS_DAC_WR_VAL_1_RD - [7:0] */
-#define WM9090_DCS_DAC_WR_VAL_1_RD_WIDTH 8 /* DCS_DAC_WR_VAL_1_RD - [7:0] */
-
-/*
- * R90 (0x5A) - DC Servo Readback 2
- */
-#define WM9090_DCS_DAC_WR_VAL_0_RD_MASK 0x00FF /* DCS_DAC_WR_VAL_0_RD - [7:0] */
-#define WM9090_DCS_DAC_WR_VAL_0_RD_SHIFT 0 /* DCS_DAC_WR_VAL_0_RD - [7:0] */
-#define WM9090_DCS_DAC_WR_VAL_0_RD_WIDTH 8 /* DCS_DAC_WR_VAL_0_RD - [7:0] */
-
-/*
- * R96 (0x60) - Analogue HP 0
- */
-#define WM9090_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
-#define WM9090_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
-#define WM9090_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
-#define WM9090_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */
-#define WM9090_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */
-#define WM9090_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */
-#define WM9090_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */
-#define WM9090_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */
-#define WM9090_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */
-#define WM9090_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */
-#define WM9090_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */
-#define WM9090_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */
-#define WM9090_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */
-#define WM9090_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */
-#define WM9090_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */
-#define WM9090_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */
-#define WM9090_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */
-#define WM9090_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */
-#define WM9090_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */
-#define WM9090_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */
-#define WM9090_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */
-#define WM9090_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */
-#define WM9090_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */
-#define WM9090_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
-
-/*
- * R98 (0x62) - AGC Control 0
- */
-#define WM9090_AGC_CLIP_ENA 0x8000 /* AGC_CLIP_ENA */
-#define WM9090_AGC_CLIP_ENA_MASK 0x8000 /* AGC_CLIP_ENA */
-#define WM9090_AGC_CLIP_ENA_SHIFT 15 /* AGC_CLIP_ENA */
-#define WM9090_AGC_CLIP_ENA_WIDTH 1 /* AGC_CLIP_ENA */
-#define WM9090_AGC_CLIP_THR_MASK 0x0F00 /* AGC_CLIP_THR - [11:8] */
-#define WM9090_AGC_CLIP_THR_SHIFT 8 /* AGC_CLIP_THR - [11:8] */
-#define WM9090_AGC_CLIP_THR_WIDTH 4 /* AGC_CLIP_THR - [11:8] */
-#define WM9090_AGC_CLIP_ATK_MASK 0x0070 /* AGC_CLIP_ATK - [6:4] */
-#define WM9090_AGC_CLIP_ATK_SHIFT 4 /* AGC_CLIP_ATK - [6:4] */
-#define WM9090_AGC_CLIP_ATK_WIDTH 3 /* AGC_CLIP_ATK - [6:4] */
-#define WM9090_AGC_CLIP_DCY_MASK 0x0007 /* AGC_CLIP_DCY - [2:0] */
-#define WM9090_AGC_CLIP_DCY_SHIFT 0 /* AGC_CLIP_DCY - [2:0] */
-#define WM9090_AGC_CLIP_DCY_WIDTH 3 /* AGC_CLIP_DCY - [2:0] */
-
-/*
- * R99 (0x63) - AGC Control 1
- */
-#define WM9090_AGC_PWR_ENA 0x8000 /* AGC_PWR_ENA */
-#define WM9090_AGC_PWR_ENA_MASK 0x8000 /* AGC_PWR_ENA */
-#define WM9090_AGC_PWR_ENA_SHIFT 15 /* AGC_PWR_ENA */
-#define WM9090_AGC_PWR_ENA_WIDTH 1 /* AGC_PWR_ENA */
-#define WM9090_AGC_PWR_AVG 0x1000 /* AGC_PWR_AVG */
-#define WM9090_AGC_PWR_AVG_MASK 0x1000 /* AGC_PWR_AVG */
-#define WM9090_AGC_PWR_AVG_SHIFT 12 /* AGC_PWR_AVG */
-#define WM9090_AGC_PWR_AVG_WIDTH 1 /* AGC_PWR_AVG */
-#define WM9090_AGC_PWR_THR_MASK 0x0F00 /* AGC_PWR_THR - [11:8] */
-#define WM9090_AGC_PWR_THR_SHIFT 8 /* AGC_PWR_THR - [11:8] */
-#define WM9090_AGC_PWR_THR_WIDTH 4 /* AGC_PWR_THR - [11:8] */
-#define WM9090_AGC_PWR_ATK_MASK 0x0070 /* AGC_PWR_ATK - [6:4] */
-#define WM9090_AGC_PWR_ATK_SHIFT 4 /* AGC_PWR_ATK - [6:4] */
-#define WM9090_AGC_PWR_ATK_WIDTH 3 /* AGC_PWR_ATK - [6:4] */
-#define WM9090_AGC_PWR_DCY_MASK 0x0007 /* AGC_PWR_DCY - [2:0] */
-#define WM9090_AGC_PWR_DCY_SHIFT 0 /* AGC_PWR_DCY - [2:0] */
-#define WM9090_AGC_PWR_DCY_WIDTH 3 /* AGC_PWR_DCY - [2:0] */
-
-/*
- * R100 (0x64) - AGC Control 2
- */
-#define WM9090_AGC_RAMP 0x0100 /* AGC_RAMP */
-#define WM9090_AGC_RAMP_MASK 0x0100 /* AGC_RAMP */
-#define WM9090_AGC_RAMP_SHIFT 8 /* AGC_RAMP */
-#define WM9090_AGC_RAMP_WIDTH 1 /* AGC_RAMP */
-#define WM9090_AGC_MINGAIN_MASK 0x003F /* AGC_MINGAIN - [5:0] */
-#define WM9090_AGC_MINGAIN_SHIFT 0 /* AGC_MINGAIN - [5:0] */
-#define WM9090_AGC_MINGAIN_WIDTH 6 /* AGC_MINGAIN - [5:0] */
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm9705.c b/ANDROID_3.4.5/sound/soc/codecs/wm9705.c
deleted file mode 100644
index cacc6a86..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm9705.c
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * wm9705.c -- ALSA Soc WM9705 codec support
- *
- * Copyright 2008 Ian Molton <spyro@f2s.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; Version 2 of the License only.
- *
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include "wm9705.h"
-
-/*
- * WM9705 register cache
- */
-static const u16 wm9705_reg[] = {
- 0x6150, 0x8000, 0x8000, 0x8000, /* 0x0 */
- 0x0000, 0x8000, 0x8008, 0x8008, /* 0x8 */
- 0x8808, 0x8808, 0x8808, 0x8808, /* 0x10 */
- 0x8808, 0x0000, 0x8000, 0x0000, /* 0x18 */
- 0x0000, 0x0000, 0x0000, 0x000f, /* 0x20 */
- 0x0605, 0x0000, 0xbb80, 0x0000, /* 0x28 */
- 0x0000, 0xbb80, 0x0000, 0x0000, /* 0x30 */
- 0x0000, 0x2000, 0x0000, 0x0000, /* 0x38 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 0x40 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 0x48 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 0x50 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 0x58 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 0x60 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 0x68 */
- 0x0000, 0x0808, 0x0000, 0x0006, /* 0x70 */
- 0x0000, 0x0000, 0x574d, 0x4c05, /* 0x78 */
-};
-
-static const struct snd_kcontrol_new wm9705_snd_ac97_controls[] = {
- SOC_DOUBLE("Master Playback Volume", AC97_MASTER, 8, 0, 31, 1),
- SOC_SINGLE("Master Playback Switch", AC97_MASTER, 15, 1, 1),
- SOC_DOUBLE("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1),
- SOC_SINGLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 1, 1),
- SOC_DOUBLE("PCM Playback Volume", AC97_PCM, 8, 0, 31, 1),
- SOC_SINGLE("PCM Playback Switch", AC97_PCM, 15, 1, 1),
- SOC_SINGLE("Mono Playback Volume", AC97_MASTER_MONO, 0, 31, 1),
- SOC_SINGLE("Mono Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
- SOC_SINGLE("PCBeep Playback Volume", AC97_PC_BEEP, 1, 15, 1),
- SOC_SINGLE("Phone Playback Volume", AC97_PHONE, 0, 31, 1),
- SOC_DOUBLE("Line Playback Volume", AC97_LINE, 8, 0, 31, 1),
- SOC_DOUBLE("CD Playback Volume", AC97_CD, 8, 0, 31, 1),
- SOC_SINGLE("Mic Playback Volume", AC97_MIC, 0, 31, 1),
- SOC_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 6, 1, 0),
- SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 15, 0),
- SOC_SINGLE("Capture Switch", AC97_REC_GAIN, 15, 1, 1),
-};
-
-static const char *wm9705_mic[] = {"Mic 1", "Mic 2"};
-static const char *wm9705_rec_sel[] = {"Mic", "CD", "NC", "NC",
- "Line", "Stereo Mix", "Mono Mix", "Phone"};
-
-static const struct soc_enum wm9705_enum_mic =
- SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 8, 2, wm9705_mic);
-static const struct soc_enum wm9705_enum_rec_l =
- SOC_ENUM_SINGLE(AC97_REC_SEL, 8, 8, wm9705_rec_sel);
-static const struct soc_enum wm9705_enum_rec_r =
- SOC_ENUM_SINGLE(AC97_REC_SEL, 0, 8, wm9705_rec_sel);
-
-/* Headphone Mixer */
-static const struct snd_kcontrol_new wm9705_hp_mixer_controls[] = {
- SOC_DAPM_SINGLE("PCBeep Playback Switch", AC97_PC_BEEP, 15, 1, 1),
- SOC_DAPM_SINGLE("CD Playback Switch", AC97_CD, 15, 1, 1),
- SOC_DAPM_SINGLE("Mic Playback Switch", AC97_MIC, 15, 1, 1),
- SOC_DAPM_SINGLE("Phone Playback Switch", AC97_PHONE, 15, 1, 1),
- SOC_DAPM_SINGLE("Line Playback Switch", AC97_LINE, 15, 1, 1),
-};
-
-/* Mic source */
-static const struct snd_kcontrol_new wm9705_mic_src_controls =
- SOC_DAPM_ENUM("Route", wm9705_enum_mic);
-
-/* Capture source */
-static const struct snd_kcontrol_new wm9705_capture_selectl_controls =
- SOC_DAPM_ENUM("Route", wm9705_enum_rec_l);
-static const struct snd_kcontrol_new wm9705_capture_selectr_controls =
- SOC_DAPM_ENUM("Route", wm9705_enum_rec_r);
-
-/* DAPM widgets */
-static const struct snd_soc_dapm_widget wm9705_dapm_widgets[] = {
- SND_SOC_DAPM_MUX("Mic Source", SND_SOC_NOPM, 0, 0,
- &wm9705_mic_src_controls),
- SND_SOC_DAPM_MUX("Left Capture Source", SND_SOC_NOPM, 0, 0,
- &wm9705_capture_selectl_controls),
- SND_SOC_DAPM_MUX("Right Capture Source", SND_SOC_NOPM, 0, 0,
- &wm9705_capture_selectr_controls),
- SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback",
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback",
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_MIXER_NAMED_CTL("HP Mixer", SND_SOC_NOPM, 0, 0,
- &wm9705_hp_mixer_controls[0],
- ARRAY_SIZE(wm9705_hp_mixer_controls)),
- SND_SOC_DAPM_MIXER("Mono Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture", SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture", SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_PGA("Headphone PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Speaker PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Line PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Line out PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Mono PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Phone PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Mic PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("PCBEEP PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("CD PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("ADC PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_OUTPUT("HPOUTL"),
- SND_SOC_DAPM_OUTPUT("HPOUTR"),
- SND_SOC_DAPM_OUTPUT("LOUT"),
- SND_SOC_DAPM_OUTPUT("ROUT"),
- SND_SOC_DAPM_OUTPUT("MONOOUT"),
- SND_SOC_DAPM_INPUT("PHONE"),
- SND_SOC_DAPM_INPUT("LINEINL"),
- SND_SOC_DAPM_INPUT("LINEINR"),
- SND_SOC_DAPM_INPUT("CDINL"),
- SND_SOC_DAPM_INPUT("CDINR"),
- SND_SOC_DAPM_INPUT("PCBEEP"),
- SND_SOC_DAPM_INPUT("MIC1"),
- SND_SOC_DAPM_INPUT("MIC2"),
-};
-
-/* Audio map
- * WM9705 has no switches to disable the route from the inputs to the HP mixer
- * so in order to prevent active inputs from forcing the audio outputs to be
- * constantly enabled, we use the mutes on those inputs to simulate such
- * controls.
- */
-static const struct snd_soc_dapm_route wm9705_audio_map[] = {
- /* HP mixer */
- {"HP Mixer", "PCBeep Playback Switch", "PCBEEP PGA"},
- {"HP Mixer", "CD Playback Switch", "CD PGA"},
- {"HP Mixer", "Mic Playback Switch", "Mic PGA"},
- {"HP Mixer", "Phone Playback Switch", "Phone PGA"},
- {"HP Mixer", "Line Playback Switch", "Line PGA"},
- {"HP Mixer", NULL, "Left DAC"},
- {"HP Mixer", NULL, "Right DAC"},
-
- /* mono mixer */
- {"Mono Mixer", NULL, "HP Mixer"},
-
- /* outputs */
- {"Headphone PGA", NULL, "HP Mixer"},
- {"HPOUTL", NULL, "Headphone PGA"},
- {"HPOUTR", NULL, "Headphone PGA"},
- {"Line out PGA", NULL, "HP Mixer"},
- {"LOUT", NULL, "Line out PGA"},
- {"ROUT", NULL, "Line out PGA"},
- {"Mono PGA", NULL, "Mono Mixer"},
- {"MONOOUT", NULL, "Mono PGA"},
-
- /* inputs */
- {"CD PGA", NULL, "CDINL"},
- {"CD PGA", NULL, "CDINR"},
- {"Line PGA", NULL, "LINEINL"},
- {"Line PGA", NULL, "LINEINR"},
- {"Phone PGA", NULL, "PHONE"},
- {"Mic Source", "Mic 1", "MIC1"},
- {"Mic Source", "Mic 2", "MIC2"},
- {"Mic PGA", NULL, "Mic Source"},
- {"PCBEEP PGA", NULL, "PCBEEP"},
-
- /* Left capture selector */
- {"Left Capture Source", "Mic", "Mic Source"},
- {"Left Capture Source", "CD", "CDINL"},
- {"Left Capture Source", "Line", "LINEINL"},
- {"Left Capture Source", "Stereo Mix", "HP Mixer"},
- {"Left Capture Source", "Mono Mix", "HP Mixer"},
- {"Left Capture Source", "Phone", "PHONE"},
-
- /* Right capture source */
- {"Right Capture Source", "Mic", "Mic Source"},
- {"Right Capture Source", "CD", "CDINR"},
- {"Right Capture Source", "Line", "LINEINR"},
- {"Right Capture Source", "Stereo Mix", "HP Mixer"},
- {"Right Capture Source", "Mono Mix", "HP Mixer"},
- {"Right Capture Source", "Phone", "PHONE"},
-
- {"ADC PGA", NULL, "Left Capture Source"},
- {"ADC PGA", NULL, "Right Capture Source"},
-
- /* ADC's */
- {"Left ADC", NULL, "ADC PGA"},
- {"Right ADC", NULL, "ADC PGA"},
-};
-
-/* We use a register cache to enhance read performance. */
-static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg)
-{
- u16 *cache = codec->reg_cache;
-
- switch (reg) {
- case AC97_RESET:
- case AC97_VENDOR_ID1:
- case AC97_VENDOR_ID2:
- return soc_ac97_ops.read(codec->ac97, reg);
- default:
- reg = reg >> 1;
-
- if (reg >= (ARRAY_SIZE(wm9705_reg)))
- return -EIO;
-
- return cache[reg];
- }
-}
-
-static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int val)
-{
- u16 *cache = codec->reg_cache;
-
- soc_ac97_ops.write(codec->ac97, reg, val);
- reg = reg >> 1;
- if (reg < (ARRAY_SIZE(wm9705_reg)))
- cache[reg] = val;
-
- return 0;
-}
-
-static int ac97_prepare(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- int reg;
- u16 vra;
-
- vra = ac97_read(codec, AC97_EXTENDED_STATUS);
- ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- reg = AC97_PCM_FRONT_DAC_RATE;
- else
- reg = AC97_PCM_LR_ADC_RATE;
-
- return ac97_write(codec, reg, runtime->rate);
-}
-
-#define WM9705_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | \
- SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000)
-
-static const struct snd_soc_dai_ops wm9705_dai_ops = {
- .prepare = ac97_prepare,
-};
-
-static struct snd_soc_dai_driver wm9705_dai[] = {
- {
- .name = "wm9705-hifi",
- .ac97_control = 1,
- .playback = {
- .stream_name = "HiFi Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM9705_AC97_RATES,
- .formats = SND_SOC_STD_AC97_FMTS,
- },
- .capture = {
- .stream_name = "HiFi Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM9705_AC97_RATES,
- .formats = SND_SOC_STD_AC97_FMTS,
- },
- .ops = &wm9705_dai_ops,
- },
- {
- .name = "wm9705-aux",
- .playback = {
- .stream_name = "Aux Playback",
- .channels_min = 1,
- .channels_max = 1,
- .rates = WM9705_AC97_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- }
-};
-
-static int wm9705_reset(struct snd_soc_codec *codec)
-{
- if (soc_ac97_ops.reset) {
- soc_ac97_ops.reset(codec->ac97);
- if (ac97_read(codec, 0) == wm9705_reg[0])
- return 0; /* Success */
- }
-
- return -EIO;
-}
-
-#ifdef CONFIG_PM
-static int wm9705_soc_suspend(struct snd_soc_codec *codec)
-{
- soc_ac97_ops.write(codec->ac97, AC97_POWERDOWN, 0xffff);
-
- return 0;
-}
-
-static int wm9705_soc_resume(struct snd_soc_codec *codec)
-{
- int i, ret;
- u16 *cache = codec->reg_cache;
-
- ret = wm9705_reset(codec);
- if (ret < 0) {
- printk(KERN_ERR "could not reset AC97 codec\n");
- return ret;
- }
-
- for (i = 2; i < ARRAY_SIZE(wm9705_reg) << 1; i += 2) {
- soc_ac97_ops.write(codec->ac97, i, cache[i>>1]);
- }
-
- return 0;
-}
-#else
-#define wm9705_soc_suspend NULL
-#define wm9705_soc_resume NULL
-#endif
-
-static int wm9705_soc_probe(struct snd_soc_codec *codec)
-{
- int ret = 0;
-
- printk(KERN_INFO "WM9705 SoC Audio Codec\n");
-
- ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
- if (ret < 0) {
- printk(KERN_ERR "wm9705: failed to register AC97 codec\n");
- return ret;
- }
-
- ret = wm9705_reset(codec);
- if (ret)
- goto reset_err;
-
- snd_soc_add_codec_controls(codec, wm9705_snd_ac97_controls,
- ARRAY_SIZE(wm9705_snd_ac97_controls));
-
- return 0;
-
-reset_err:
- snd_soc_free_ac97_codec(codec);
- return ret;
-}
-
-static int wm9705_soc_remove(struct snd_soc_codec *codec)
-{
- snd_soc_free_ac97_codec(codec);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm9705 = {
- .probe = wm9705_soc_probe,
- .remove = wm9705_soc_remove,
- .suspend = wm9705_soc_suspend,
- .resume = wm9705_soc_resume,
- .read = ac97_read,
- .write = ac97_write,
- .reg_cache_size = ARRAY_SIZE(wm9705_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_step = 2,
- .reg_cache_default = wm9705_reg,
- .dapm_widgets = wm9705_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm9705_dapm_widgets),
- .dapm_routes = wm9705_audio_map,
- .num_dapm_routes = ARRAY_SIZE(wm9705_audio_map),
-};
-
-static __devinit int wm9705_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev,
- &soc_codec_dev_wm9705, wm9705_dai, ARRAY_SIZE(wm9705_dai));
-}
-
-static int __devexit wm9705_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver wm9705_codec_driver = {
- .driver = {
- .name = "wm9705-codec",
- .owner = THIS_MODULE,
- },
-
- .probe = wm9705_probe,
- .remove = __devexit_p(wm9705_remove),
-};
-
-module_platform_driver(wm9705_codec_driver);
-
-MODULE_DESCRIPTION("ASoC WM9705 driver");
-MODULE_AUTHOR("Ian Molton");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm9705.h b/ANDROID_3.4.5/sound/soc/codecs/wm9705.h
deleted file mode 100644
index 23ea9ce4..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm9705.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * wm9705.h -- WM9705 Soc Audio driver
- */
-
-#ifndef _WM9705_H
-#define _WM9705_H
-
-#define WM9705_DAI_AC97_HIFI 0
-#define WM9705_DAI_AC97_AUX 1
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm9712.c b/ANDROID_3.4.5/sound/soc/codecs/wm9712.c
deleted file mode 100644
index b342ae50..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm9712.c
+++ /dev/null
@@ -1,700 +0,0 @@
-/*
- * wm9712.c -- ALSA Soc WM9712 codec support
- *
- * Copyright 2006 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood <lrg@slimlogic.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-#include <sound/tlv.h>
-#include "wm9712.h"
-
-static unsigned int ac97_read(struct snd_soc_codec *codec,
- unsigned int reg);
-static int ac97_write(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int val);
-
-/*
- * WM9712 register cache
- */
-static const u16 wm9712_reg[] = {
- 0x6174, 0x8000, 0x8000, 0x8000, /* 6 */
- 0x0f0f, 0xaaa0, 0xc008, 0x6808, /* e */
- 0xe808, 0xaaa0, 0xad00, 0x8000, /* 16 */
- 0xe808, 0x3000, 0x8000, 0x0000, /* 1e */
- 0x0000, 0x0000, 0x0000, 0x000f, /* 26 */
- 0x0405, 0x0410, 0xbb80, 0xbb80, /* 2e */
- 0x0000, 0xbb80, 0x0000, 0x0000, /* 36 */
- 0x0000, 0x2000, 0x0000, 0x0000, /* 3e */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 46 */
- 0x0000, 0x0000, 0xf83e, 0xffff, /* 4e */
- 0x0000, 0x0000, 0x0000, 0xf83e, /* 56 */
- 0x0008, 0x0000, 0x0000, 0x0000, /* 5e */
- 0xb032, 0x3e00, 0x0000, 0x0000, /* 66 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 6e */
- 0x0000, 0x0000, 0x0000, 0x0006, /* 76 */
- 0x0001, 0x0000, 0x574d, 0x4c12, /* 7e */
- 0x0000, 0x0000 /* virtual hp mixers */
-};
-
-/* virtual HP mixers regs */
-#define HPL_MIXER 0x80
-#define HPR_MIXER 0x82
-
-static const char *wm9712_alc_select[] = {"None", "Left", "Right", "Stereo"};
-static const char *wm9712_alc_mux[] = {"Stereo", "Left", "Right", "None"};
-static const char *wm9712_out3_src[] = {"Left", "VREF", "Left + Right",
- "Mono"};
-static const char *wm9712_spk_src[] = {"Speaker Mix", "Headphone Mix"};
-static const char *wm9712_rec_adc[] = {"Stereo", "Left", "Right", "Mute"};
-static const char *wm9712_base[] = {"Linear Control", "Adaptive Boost"};
-static const char *wm9712_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"};
-static const char *wm9712_mic[] = {"Mic 1", "Differential", "Mic 2",
- "Stereo"};
-static const char *wm9712_rec_sel[] = {"Mic", "NC", "NC", "Speaker Mixer",
- "Line", "Headphone Mixer", "Phone Mixer", "Phone"};
-static const char *wm9712_ng_type[] = {"Constant Gain", "Mute"};
-static const char *wm9712_diff_sel[] = {"Mic", "Line"};
-
-static const DECLARE_TLV_DB_SCALE(main_tlv, -3450, 150, 0);
-static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 2000, 0);
-
-static const struct soc_enum wm9712_enum[] = {
-SOC_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9712_alc_select),
-SOC_ENUM_SINGLE(AC97_VIDEO, 12, 4, wm9712_alc_mux),
-SOC_ENUM_SINGLE(AC97_AUX, 9, 4, wm9712_out3_src),
-SOC_ENUM_SINGLE(AC97_AUX, 8, 2, wm9712_spk_src),
-SOC_ENUM_SINGLE(AC97_REC_SEL, 12, 4, wm9712_rec_adc),
-SOC_ENUM_SINGLE(AC97_MASTER_TONE, 15, 2, wm9712_base),
-SOC_ENUM_DOUBLE(AC97_REC_GAIN, 14, 6, 2, wm9712_rec_gain),
-SOC_ENUM_SINGLE(AC97_MIC, 5, 4, wm9712_mic),
-SOC_ENUM_SINGLE(AC97_REC_SEL, 8, 8, wm9712_rec_sel),
-SOC_ENUM_SINGLE(AC97_REC_SEL, 0, 8, wm9712_rec_sel),
-SOC_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9712_ng_type),
-SOC_ENUM_SINGLE(0x5c, 8, 2, wm9712_diff_sel),
-};
-
-static const struct snd_kcontrol_new wm9712_snd_ac97_controls[] = {
-SOC_DOUBLE("Speaker Playback Volume", AC97_MASTER, 8, 0, 31, 1),
-SOC_SINGLE("Speaker Playback Switch", AC97_MASTER, 15, 1, 1),
-SOC_DOUBLE("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1),
-SOC_SINGLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 1, 1),
-SOC_DOUBLE("PCM Playback Volume", AC97_PCM, 8, 0, 31, 1),
-
-SOC_SINGLE("Speaker Playback ZC Switch", AC97_MASTER, 7, 1, 0),
-SOC_SINGLE("Speaker Playback Invert Switch", AC97_MASTER, 6, 1, 0),
-SOC_SINGLE("Headphone Playback ZC Switch", AC97_HEADPHONE, 7, 1, 0),
-SOC_SINGLE("Mono Playback ZC Switch", AC97_MASTER_MONO, 7, 1, 0),
-SOC_SINGLE("Mono Playback Volume", AC97_MASTER_MONO, 0, 31, 1),
-SOC_SINGLE("Mono Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
-
-SOC_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0),
-SOC_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0),
-SOC_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV, 4, 15, 0),
-SOC_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0),
-SOC_ENUM("ALC Function", wm9712_enum[0]),
-SOC_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0),
-SOC_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 1),
-SOC_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0),
-SOC_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0),
-SOC_ENUM("ALC NG Type", wm9712_enum[10]),
-SOC_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 1),
-
-SOC_SINGLE("Mic Headphone Volume", AC97_VIDEO, 12, 7, 1),
-SOC_SINGLE("ALC Headphone Volume", AC97_VIDEO, 7, 7, 1),
-
-SOC_SINGLE("Out3 Switch", AC97_AUX, 15, 1, 1),
-SOC_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 1),
-SOC_SINGLE("Out3 Volume", AC97_AUX, 0, 31, 1),
-
-SOC_SINGLE("PCBeep Bypass Headphone Volume", AC97_PC_BEEP, 12, 7, 1),
-SOC_SINGLE("PCBeep Bypass Speaker Volume", AC97_PC_BEEP, 8, 7, 1),
-SOC_SINGLE("PCBeep Bypass Phone Volume", AC97_PC_BEEP, 4, 7, 1),
-
-SOC_SINGLE("Aux Playback Headphone Volume", AC97_CD, 12, 7, 1),
-SOC_SINGLE("Aux Playback Speaker Volume", AC97_CD, 8, 7, 1),
-SOC_SINGLE("Aux Playback Phone Volume", AC97_CD, 4, 7, 1),
-
-SOC_SINGLE("Phone Volume", AC97_PHONE, 0, 15, 1),
-SOC_DOUBLE("Line Capture Volume", AC97_LINE, 8, 0, 31, 1),
-
-SOC_SINGLE("Capture 20dB Boost Switch", AC97_REC_SEL, 14, 1, 0),
-SOC_SINGLE("Capture to Phone 20dB Boost Switch", AC97_REC_SEL, 11, 1, 1),
-
-SOC_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1),
-SOC_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1),
-SOC_SINGLE("3D Playback Volume", AC97_3D_CONTROL, 0, 15, 0),
-
-SOC_ENUM("Bass Control", wm9712_enum[5]),
-SOC_SINGLE("Bass Cut-off Switch", AC97_MASTER_TONE, 12, 1, 1),
-SOC_SINGLE("Tone Cut-off Switch", AC97_MASTER_TONE, 4, 1, 1),
-SOC_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0),
-SOC_SINGLE("Bass Volume", AC97_MASTER_TONE, 8, 15, 1),
-SOC_SINGLE("Treble Volume", AC97_MASTER_TONE, 0, 15, 1),
-
-SOC_SINGLE("Capture ADC Switch", AC97_REC_GAIN, 15, 1, 1),
-SOC_ENUM("Capture Volume Steps", wm9712_enum[6]),
-SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1),
-SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0),
-
-SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv),
-SOC_SINGLE_TLV("Mic 2 Volume", AC97_MIC, 0, 31, 1, main_tlv),
-SOC_SINGLE_TLV("Mic Boost Volume", AC97_MIC, 7, 1, 0, boost_tlv),
-};
-
-/* We have to create a fake left and right HP mixers because
- * the codec only has a single control that is shared by both channels.
- * This makes it impossible to determine the audio path.
- */
-static int mixer_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- u16 l, r, beep, line, phone, mic, pcm, aux;
-
- l = ac97_read(w->codec, HPL_MIXER);
- r = ac97_read(w->codec, HPR_MIXER);
- beep = ac97_read(w->codec, AC97_PC_BEEP);
- mic = ac97_read(w->codec, AC97_VIDEO);
- phone = ac97_read(w->codec, AC97_PHONE);
- line = ac97_read(w->codec, AC97_LINE);
- pcm = ac97_read(w->codec, AC97_PCM);
- aux = ac97_read(w->codec, AC97_CD);
-
- if (l & 0x1 || r & 0x1)
- ac97_write(w->codec, AC97_VIDEO, mic & 0x7fff);
- else
- ac97_write(w->codec, AC97_VIDEO, mic | 0x8000);
-
- if (l & 0x2 || r & 0x2)
- ac97_write(w->codec, AC97_PCM, pcm & 0x7fff);
- else
- ac97_write(w->codec, AC97_PCM, pcm | 0x8000);
-
- if (l & 0x4 || r & 0x4)
- ac97_write(w->codec, AC97_LINE, line & 0x7fff);
- else
- ac97_write(w->codec, AC97_LINE, line | 0x8000);
-
- if (l & 0x8 || r & 0x8)
- ac97_write(w->codec, AC97_PHONE, phone & 0x7fff);
- else
- ac97_write(w->codec, AC97_PHONE, phone | 0x8000);
-
- if (l & 0x10 || r & 0x10)
- ac97_write(w->codec, AC97_CD, aux & 0x7fff);
- else
- ac97_write(w->codec, AC97_CD, aux | 0x8000);
-
- if (l & 0x20 || r & 0x20)
- ac97_write(w->codec, AC97_PC_BEEP, beep & 0x7fff);
- else
- ac97_write(w->codec, AC97_PC_BEEP, beep | 0x8000);
-
- return 0;
-}
-
-/* Left Headphone Mixers */
-static const struct snd_kcontrol_new wm9712_hpl_mixer_controls[] = {
- SOC_DAPM_SINGLE("PCBeep Bypass Switch", HPL_MIXER, 5, 1, 0),
- SOC_DAPM_SINGLE("Aux Playback Switch", HPL_MIXER, 4, 1, 0),
- SOC_DAPM_SINGLE("Phone Bypass Switch", HPL_MIXER, 3, 1, 0),
- SOC_DAPM_SINGLE("Line Bypass Switch", HPL_MIXER, 2, 1, 0),
- SOC_DAPM_SINGLE("PCM Playback Switch", HPL_MIXER, 1, 1, 0),
- SOC_DAPM_SINGLE("Mic Sidetone Switch", HPL_MIXER, 0, 1, 0),
-};
-
-/* Right Headphone Mixers */
-static const struct snd_kcontrol_new wm9712_hpr_mixer_controls[] = {
- SOC_DAPM_SINGLE("PCBeep Bypass Switch", HPR_MIXER, 5, 1, 0),
- SOC_DAPM_SINGLE("Aux Playback Switch", HPR_MIXER, 4, 1, 0),
- SOC_DAPM_SINGLE("Phone Bypass Switch", HPR_MIXER, 3, 1, 0),
- SOC_DAPM_SINGLE("Line Bypass Switch", HPR_MIXER, 2, 1, 0),
- SOC_DAPM_SINGLE("PCM Playback Switch", HPR_MIXER, 1, 1, 0),
- SOC_DAPM_SINGLE("Mic Sidetone Switch", HPR_MIXER, 0, 1, 0),
-};
-
-/* Speaker Mixer */
-static const struct snd_kcontrol_new wm9712_speaker_mixer_controls[] = {
- SOC_DAPM_SINGLE("PCBeep Bypass Switch", AC97_PC_BEEP, 11, 1, 1),
- SOC_DAPM_SINGLE("Aux Playback Switch", AC97_CD, 11, 1, 1),
- SOC_DAPM_SINGLE("Phone Bypass Switch", AC97_PHONE, 14, 1, 1),
- SOC_DAPM_SINGLE("Line Bypass Switch", AC97_LINE, 14, 1, 1),
- SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PCM, 14, 1, 1),
-};
-
-/* Phone Mixer */
-static const struct snd_kcontrol_new wm9712_phone_mixer_controls[] = {
- SOC_DAPM_SINGLE("PCBeep Bypass Switch", AC97_PC_BEEP, 7, 1, 1),
- SOC_DAPM_SINGLE("Aux Playback Switch", AC97_CD, 7, 1, 1),
- SOC_DAPM_SINGLE("Line Bypass Switch", AC97_LINE, 13, 1, 1),
- SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PCM, 13, 1, 1),
- SOC_DAPM_SINGLE("Mic 1 Sidetone Switch", AC97_MIC, 14, 1, 1),
- SOC_DAPM_SINGLE("Mic 2 Sidetone Switch", AC97_MIC, 13, 1, 1),
-};
-
-/* ALC headphone mux */
-static const struct snd_kcontrol_new wm9712_alc_mux_controls =
-SOC_DAPM_ENUM("Route", wm9712_enum[1]);
-
-/* out 3 mux */
-static const struct snd_kcontrol_new wm9712_out3_mux_controls =
-SOC_DAPM_ENUM("Route", wm9712_enum[2]);
-
-/* spk mux */
-static const struct snd_kcontrol_new wm9712_spk_mux_controls =
-SOC_DAPM_ENUM("Route", wm9712_enum[3]);
-
-/* Capture to Phone mux */
-static const struct snd_kcontrol_new wm9712_capture_phone_mux_controls =
-SOC_DAPM_ENUM("Route", wm9712_enum[4]);
-
-/* Capture left select */
-static const struct snd_kcontrol_new wm9712_capture_selectl_controls =
-SOC_DAPM_ENUM("Route", wm9712_enum[8]);
-
-/* Capture right select */
-static const struct snd_kcontrol_new wm9712_capture_selectr_controls =
-SOC_DAPM_ENUM("Route", wm9712_enum[9]);
-
-/* Mic select */
-static const struct snd_kcontrol_new wm9712_mic_src_controls =
-SOC_DAPM_ENUM("Route", wm9712_enum[7]);
-
-/* diff select */
-static const struct snd_kcontrol_new wm9712_diff_sel_controls =
-SOC_DAPM_ENUM("Route", wm9712_enum[11]);
-
-static const struct snd_soc_dapm_widget wm9712_dapm_widgets[] = {
-SND_SOC_DAPM_MUX("ALC Sidetone Mux", SND_SOC_NOPM, 0, 0,
- &wm9712_alc_mux_controls),
-SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 0,
- &wm9712_out3_mux_controls),
-SND_SOC_DAPM_MUX("Speaker Mux", SND_SOC_NOPM, 0, 0,
- &wm9712_spk_mux_controls),
-SND_SOC_DAPM_MUX("Capture Phone Mux", SND_SOC_NOPM, 0, 0,
- &wm9712_capture_phone_mux_controls),
-SND_SOC_DAPM_MUX("Left Capture Select", SND_SOC_NOPM, 0, 0,
- &wm9712_capture_selectl_controls),
-SND_SOC_DAPM_MUX("Right Capture Select", SND_SOC_NOPM, 0, 0,
- &wm9712_capture_selectr_controls),
-SND_SOC_DAPM_MUX("Mic Select Source", SND_SOC_NOPM, 0, 0,
- &wm9712_mic_src_controls),
-SND_SOC_DAPM_MUX("Differential Source", SND_SOC_NOPM, 0, 0,
- &wm9712_diff_sel_controls),
-SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_MIXER_E("Left HP Mixer", AC97_INT_PAGING, 9, 1,
- &wm9712_hpl_mixer_controls[0], ARRAY_SIZE(wm9712_hpl_mixer_controls),
- mixer_event, SND_SOC_DAPM_POST_REG),
-SND_SOC_DAPM_MIXER_E("Right HP Mixer", AC97_INT_PAGING, 8, 1,
- &wm9712_hpr_mixer_controls[0], ARRAY_SIZE(wm9712_hpr_mixer_controls),
- mixer_event, SND_SOC_DAPM_POST_REG),
-SND_SOC_DAPM_MIXER("Phone Mixer", AC97_INT_PAGING, 6, 1,
- &wm9712_phone_mixer_controls[0], ARRAY_SIZE(wm9712_phone_mixer_controls)),
-SND_SOC_DAPM_MIXER("Speaker Mixer", AC97_INT_PAGING, 7, 1,
- &wm9712_speaker_mixer_controls[0],
- ARRAY_SIZE(wm9712_speaker_mixer_controls)),
-SND_SOC_DAPM_MIXER("Mono Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", AC97_INT_PAGING, 14, 1),
-SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", AC97_INT_PAGING, 13, 1),
-SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture", AC97_INT_PAGING, 12, 1),
-SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture", AC97_INT_PAGING, 11, 1),
-SND_SOC_DAPM_PGA("Headphone PGA", AC97_INT_PAGING, 4, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Speaker PGA", AC97_INT_PAGING, 3, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Out 3 PGA", AC97_INT_PAGING, 5, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Line PGA", AC97_INT_PAGING, 2, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Phone PGA", AC97_INT_PAGING, 1, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Mic PGA", AC97_INT_PAGING, 0, 1, NULL, 0),
-SND_SOC_DAPM_MICBIAS("Mic Bias", AC97_INT_PAGING, 10, 1),
-SND_SOC_DAPM_OUTPUT("MONOOUT"),
-SND_SOC_DAPM_OUTPUT("HPOUTL"),
-SND_SOC_DAPM_OUTPUT("HPOUTR"),
-SND_SOC_DAPM_OUTPUT("LOUT2"),
-SND_SOC_DAPM_OUTPUT("ROUT2"),
-SND_SOC_DAPM_OUTPUT("OUT3"),
-SND_SOC_DAPM_INPUT("LINEINL"),
-SND_SOC_DAPM_INPUT("LINEINR"),
-SND_SOC_DAPM_INPUT("PHONE"),
-SND_SOC_DAPM_INPUT("PCBEEP"),
-SND_SOC_DAPM_INPUT("MIC1"),
-SND_SOC_DAPM_INPUT("MIC2"),
-};
-
-static const struct snd_soc_dapm_route wm9712_audio_map[] = {
- /* virtual mixer - mixes left & right channels for spk and mono */
- {"AC97 Mixer", NULL, "Left DAC"},
- {"AC97 Mixer", NULL, "Right DAC"},
-
- /* Left HP mixer */
- {"Left HP Mixer", "PCBeep Bypass Switch", "PCBEEP"},
- {"Left HP Mixer", "Aux Playback Switch", "Aux DAC"},
- {"Left HP Mixer", "Phone Bypass Switch", "Phone PGA"},
- {"Left HP Mixer", "Line Bypass Switch", "Line PGA"},
- {"Left HP Mixer", "PCM Playback Switch", "Left DAC"},
- {"Left HP Mixer", "Mic Sidetone Switch", "Mic PGA"},
- {"Left HP Mixer", NULL, "ALC Sidetone Mux"},
-
- /* Right HP mixer */
- {"Right HP Mixer", "PCBeep Bypass Switch", "PCBEEP"},
- {"Right HP Mixer", "Aux Playback Switch", "Aux DAC"},
- {"Right HP Mixer", "Phone Bypass Switch", "Phone PGA"},
- {"Right HP Mixer", "Line Bypass Switch", "Line PGA"},
- {"Right HP Mixer", "PCM Playback Switch", "Right DAC"},
- {"Right HP Mixer", "Mic Sidetone Switch", "Mic PGA"},
- {"Right HP Mixer", NULL, "ALC Sidetone Mux"},
-
- /* speaker mixer */
- {"Speaker Mixer", "PCBeep Bypass Switch", "PCBEEP"},
- {"Speaker Mixer", "Line Bypass Switch", "Line PGA"},
- {"Speaker Mixer", "PCM Playback Switch", "AC97 Mixer"},
- {"Speaker Mixer", "Phone Bypass Switch", "Phone PGA"},
- {"Speaker Mixer", "Aux Playback Switch", "Aux DAC"},
-
- /* Phone mixer */
- {"Phone Mixer", "PCBeep Bypass Switch", "PCBEEP"},
- {"Phone Mixer", "Line Bypass Switch", "Line PGA"},
- {"Phone Mixer", "Aux Playback Switch", "Aux DAC"},
- {"Phone Mixer", "PCM Playback Switch", "AC97 Mixer"},
- {"Phone Mixer", "Mic 1 Sidetone Switch", "Mic PGA"},
- {"Phone Mixer", "Mic 2 Sidetone Switch", "Mic PGA"},
-
- /* inputs */
- {"Line PGA", NULL, "LINEINL"},
- {"Line PGA", NULL, "LINEINR"},
- {"Phone PGA", NULL, "PHONE"},
- {"Mic PGA", NULL, "MIC1"},
- {"Mic PGA", NULL, "MIC2"},
-
- /* left capture selector */
- {"Left Capture Select", "Mic", "MIC1"},
- {"Left Capture Select", "Speaker Mixer", "Speaker Mixer"},
- {"Left Capture Select", "Line", "LINEINL"},
- {"Left Capture Select", "Headphone Mixer", "Left HP Mixer"},
- {"Left Capture Select", "Phone Mixer", "Phone Mixer"},
- {"Left Capture Select", "Phone", "PHONE"},
-
- /* right capture selector */
- {"Right Capture Select", "Mic", "MIC2"},
- {"Right Capture Select", "Speaker Mixer", "Speaker Mixer"},
- {"Right Capture Select", "Line", "LINEINR"},
- {"Right Capture Select", "Headphone Mixer", "Right HP Mixer"},
- {"Right Capture Select", "Phone Mixer", "Phone Mixer"},
- {"Right Capture Select", "Phone", "PHONE"},
-
- /* ALC Sidetone */
- {"ALC Sidetone Mux", "Stereo", "Left Capture Select"},
- {"ALC Sidetone Mux", "Stereo", "Right Capture Select"},
- {"ALC Sidetone Mux", "Left", "Left Capture Select"},
- {"ALC Sidetone Mux", "Right", "Right Capture Select"},
-
- /* ADC's */
- {"Left ADC", NULL, "Left Capture Select"},
- {"Right ADC", NULL, "Right Capture Select"},
-
- /* outputs */
- {"MONOOUT", NULL, "Phone Mixer"},
- {"HPOUTL", NULL, "Headphone PGA"},
- {"Headphone PGA", NULL, "Left HP Mixer"},
- {"HPOUTR", NULL, "Headphone PGA"},
- {"Headphone PGA", NULL, "Right HP Mixer"},
-
- /* mono mixer */
- {"Mono Mixer", NULL, "Left HP Mixer"},
- {"Mono Mixer", NULL, "Right HP Mixer"},
-
- /* Out3 Mux */
- {"Out3 Mux", "Left", "Left HP Mixer"},
- {"Out3 Mux", "Mono", "Phone Mixer"},
- {"Out3 Mux", "Left + Right", "Mono Mixer"},
- {"Out 3 PGA", NULL, "Out3 Mux"},
- {"OUT3", NULL, "Out 3 PGA"},
-
- /* speaker Mux */
- {"Speaker Mux", "Speaker Mix", "Speaker Mixer"},
- {"Speaker Mux", "Headphone Mix", "Mono Mixer"},
- {"Speaker PGA", NULL, "Speaker Mux"},
- {"LOUT2", NULL, "Speaker PGA"},
- {"ROUT2", NULL, "Speaker PGA"},
-};
-
-static unsigned int ac97_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- u16 *cache = codec->reg_cache;
-
- if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||
- reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 ||
- reg == AC97_REC_GAIN)
- return soc_ac97_ops.read(codec->ac97, reg);
- else {
- reg = reg >> 1;
-
- if (reg >= (ARRAY_SIZE(wm9712_reg)))
- return -EIO;
-
- return cache[reg];
- }
-}
-
-static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int val)
-{
- u16 *cache = codec->reg_cache;
-
- if (reg < 0x7c)
- soc_ac97_ops.write(codec->ac97, reg, val);
- reg = reg >> 1;
- if (reg < (ARRAY_SIZE(wm9712_reg)))
- cache[reg] = val;
-
- return 0;
-}
-
-static int ac97_prepare(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec =rtd->codec;
- int reg;
- u16 vra;
-
- vra = ac97_read(codec, AC97_EXTENDED_STATUS);
- ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- reg = AC97_PCM_FRONT_DAC_RATE;
- else
- reg = AC97_PCM_LR_ADC_RATE;
-
- return ac97_write(codec, reg, runtime->rate);
-}
-
-static int ac97_aux_prepare(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- u16 vra, xsle;
-
- vra = ac97_read(codec, AC97_EXTENDED_STATUS);
- ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1);
- xsle = ac97_read(codec, AC97_PCI_SID);
- ac97_write(codec, AC97_PCI_SID, xsle | 0x8000);
-
- if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
- return -ENODEV;
-
- return ac97_write(codec, AC97_PCM_SURR_DAC_RATE, runtime->rate);
-}
-
-#define WM9712_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\
- SNDRV_PCM_RATE_48000)
-
-static const struct snd_soc_dai_ops wm9712_dai_ops_hifi = {
- .prepare = ac97_prepare,
-};
-
-static const struct snd_soc_dai_ops wm9712_dai_ops_aux = {
- .prepare = ac97_aux_prepare,
-};
-
-static struct snd_soc_dai_driver wm9712_dai[] = {
-{
- .name = "wm9712-hifi",
- .ac97_control = 1,
- .playback = {
- .stream_name = "HiFi Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM9712_AC97_RATES,
- .formats = SND_SOC_STD_AC97_FMTS,},
- .capture = {
- .stream_name = "HiFi Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM9712_AC97_RATES,
- .formats = SND_SOC_STD_AC97_FMTS,},
- .ops = &wm9712_dai_ops_hifi,
-},
-{
- .name = "wm9712-aux",
- .playback = {
- .stream_name = "Aux Playback",
- .channels_min = 1,
- .channels_max = 1,
- .rates = WM9712_AC97_RATES,
- .formats = SND_SOC_STD_AC97_FMTS,},
- .ops = &wm9712_dai_ops_aux,
-}
-};
-
-static int wm9712_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- switch (level) {
- case SND_SOC_BIAS_ON:
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- ac97_write(codec, AC97_POWERDOWN, 0x0000);
- break;
- case SND_SOC_BIAS_OFF:
- /* disable everything including AC link */
- ac97_write(codec, AC97_EXTENDED_MSTATUS, 0xffff);
- ac97_write(codec, AC97_POWERDOWN, 0xffff);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-static int wm9712_reset(struct snd_soc_codec *codec, int try_warm)
-{
- if (try_warm && soc_ac97_ops.warm_reset) {
- soc_ac97_ops.warm_reset(codec->ac97);
- if (ac97_read(codec, 0) == wm9712_reg[0])
- return 1;
- }
-
- soc_ac97_ops.reset(codec->ac97);
- if (soc_ac97_ops.warm_reset)
- soc_ac97_ops.warm_reset(codec->ac97);
- if (ac97_read(codec, 0) != wm9712_reg[0])
- goto err;
- return 0;
-
-err:
- printk(KERN_ERR "WM9712 AC97 reset failed\n");
- return -EIO;
-}
-
-static int wm9712_soc_suspend(struct snd_soc_codec *codec)
-{
- wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm9712_soc_resume(struct snd_soc_codec *codec)
-{
- int i, ret;
- u16 *cache = codec->reg_cache;
-
- ret = wm9712_reset(codec, 1);
- if (ret < 0) {
- printk(KERN_ERR "could not reset AC97 codec\n");
- return ret;
- }
-
- wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- if (ret == 0) {
- /* Sync reg_cache with the hardware after cold reset */
- for (i = 2; i < ARRAY_SIZE(wm9712_reg) << 1; i += 2) {
- if (i == AC97_INT_PAGING || i == AC97_POWERDOWN ||
- (i > 0x58 && i != 0x5c))
- continue;
- soc_ac97_ops.write(codec->ac97, i, cache[i>>1]);
- }
- }
-
- return ret;
-}
-
-static int wm9712_soc_probe(struct snd_soc_codec *codec)
-{
- int ret = 0;
-
- ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
- if (ret < 0) {
- printk(KERN_ERR "wm9712: failed to register AC97 codec\n");
- return ret;
- }
-
- ret = wm9712_reset(codec, 0);
- if (ret < 0) {
- printk(KERN_ERR "Failed to reset WM9712: AC97 link error\n");
- goto reset_err;
- }
-
- /* set alc mux to none */
- ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000);
-
- wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- snd_soc_add_codec_controls(codec, wm9712_snd_ac97_controls,
- ARRAY_SIZE(wm9712_snd_ac97_controls));
-
- return 0;
-
-reset_err:
- snd_soc_free_ac97_codec(codec);
- return ret;
-}
-
-static int wm9712_soc_remove(struct snd_soc_codec *codec)
-{
- snd_soc_free_ac97_codec(codec);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm9712 = {
- .probe = wm9712_soc_probe,
- .remove = wm9712_soc_remove,
- .suspend = wm9712_soc_suspend,
- .resume = wm9712_soc_resume,
- .read = ac97_read,
- .write = ac97_write,
- .set_bias_level = wm9712_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm9712_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_step = 2,
- .reg_cache_default = wm9712_reg,
- .dapm_widgets = wm9712_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm9712_dapm_widgets),
- .dapm_routes = wm9712_audio_map,
- .num_dapm_routes = ARRAY_SIZE(wm9712_audio_map),
-};
-
-static __devinit int wm9712_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev,
- &soc_codec_dev_wm9712, wm9712_dai, ARRAY_SIZE(wm9712_dai));
-}
-
-static int __devexit wm9712_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver wm9712_codec_driver = {
- .driver = {
- .name = "wm9712-codec",
- .owner = THIS_MODULE,
- },
-
- .probe = wm9712_probe,
- .remove = __devexit_p(wm9712_remove),
-};
-
-module_platform_driver(wm9712_codec_driver);
-
-MODULE_DESCRIPTION("ASoC WM9711/WM9712 driver");
-MODULE_AUTHOR("Liam Girdwood");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm9712.h b/ANDROID_3.4.5/sound/soc/codecs/wm9712.h
deleted file mode 100644
index fb69c3aa..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm9712.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * wm9712.h -- WM9712 Soc Audio driver
- */
-
-#ifndef _WM9712_H
-#define _WM9712_H
-
-#define WM9712_DAI_AC97_HIFI 0
-#define WM9712_DAI_AC97_AUX 1
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm9713.c b/ANDROID_3.4.5/sound/soc/codecs/wm9713.c
deleted file mode 100644
index 2d22cc70..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm9713.c
+++ /dev/null
@@ -1,1283 +0,0 @@
-/*
- * wm9713.c -- ALSA Soc WM9713 codec support
- *
- * Copyright 2006 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood <lrg@slimlogic.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * Features:-
- *
- * o Support for AC97 Codec, Voice DAC and Aux DAC
- * o Support for DAPM
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-#include <sound/pcm_params.h>
-#include <sound/tlv.h>
-#include <sound/soc.h>
-
-#include "wm9713.h"
-
-struct wm9713_priv {
- u32 pll_in; /* PLL input frequency */
-};
-
-static unsigned int ac97_read(struct snd_soc_codec *codec,
- unsigned int reg);
-static int ac97_write(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int val);
-
-/*
- * WM9713 register cache
- * Reg 0x3c bit 15 is used by touch driver.
- */
-static const u16 wm9713_reg[] = {
- 0x6174, 0x8080, 0x8080, 0x8080,
- 0xc880, 0xe808, 0xe808, 0x0808,
- 0x00da, 0x8000, 0xd600, 0xaaa0,
- 0xaaa0, 0xaaa0, 0x0000, 0x0000,
- 0x0f0f, 0x0040, 0x0000, 0x7f00,
- 0x0405, 0x0410, 0xbb80, 0xbb80,
- 0x0000, 0xbb80, 0x0000, 0x4523,
- 0x0000, 0x2000, 0x7eff, 0xffff,
- 0x0000, 0x0000, 0x0080, 0x0000,
- 0x0000, 0x0000, 0xfffe, 0xffff,
- 0x0000, 0x0000, 0x0000, 0xfffe,
- 0x4000, 0x0000, 0x0000, 0x0000,
- 0xb032, 0x3e00, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0006,
- 0x0001, 0x0000, 0x574d, 0x4c13,
- 0x0000, 0x0000, 0x0000
-};
-
-/* virtual HP mixers regs */
-#define HPL_MIXER 0x80
-#define HPR_MIXER 0x82
-#define MICB_MUX 0x82
-
-static const char *wm9713_mic_mixer[] = {"Stereo", "Mic 1", "Mic 2", "Mute"};
-static const char *wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"};
-static const char *wm9713_rec_src[] =
- {"Mic 1", "Mic 2", "Line", "Mono In", "Headphone", "Speaker",
- "Mono Out", "Zh"};
-static const char *wm9713_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"};
-static const char *wm9713_alc_select[] = {"None", "Left", "Right", "Stereo"};
-static const char *wm9713_mono_pga[] = {"Vmid", "Zh", "Mono", "Inv",
- "Mono Vmid", "Inv Vmid"};
-static const char *wm9713_spk_pga[] =
- {"Vmid", "Zh", "Headphone", "Speaker", "Inv", "Headphone Vmid",
- "Speaker Vmid", "Inv Vmid"};
-static const char *wm9713_hp_pga[] = {"Vmid", "Zh", "Headphone",
- "Headphone Vmid"};
-static const char *wm9713_out3_pga[] = {"Vmid", "Zh", "Inv 1", "Inv 1 Vmid"};
-static const char *wm9713_out4_pga[] = {"Vmid", "Zh", "Inv 2", "Inv 2 Vmid"};
-static const char *wm9713_dac_inv[] =
- {"Off", "Mono", "Speaker", "Left Headphone", "Right Headphone",
- "Headphone Mono", "NC", "Vmid"};
-static const char *wm9713_bass[] = {"Linear Control", "Adaptive Boost"};
-static const char *wm9713_ng_type[] = {"Constant Gain", "Mute"};
-static const char *wm9713_mic_select[] = {"Mic 1", "Mic 2 A", "Mic 2 B"};
-static const char *wm9713_micb_select[] = {"MPB", "MPA"};
-
-static const struct soc_enum wm9713_enum[] = {
-SOC_ENUM_SINGLE(AC97_LINE, 3, 4, wm9713_mic_mixer), /* record mic mixer 0 */
-SOC_ENUM_SINGLE(AC97_VIDEO, 14, 4, wm9713_rec_mux), /* record mux hp 1 */
-SOC_ENUM_SINGLE(AC97_VIDEO, 9, 4, wm9713_rec_mux), /* record mux mono 2 */
-SOC_ENUM_SINGLE(AC97_VIDEO, 3, 8, wm9713_rec_src), /* record mux left 3 */
-SOC_ENUM_SINGLE(AC97_VIDEO, 0, 8, wm9713_rec_src), /* record mux right 4*/
-SOC_ENUM_DOUBLE(AC97_CD, 14, 6, 2, wm9713_rec_gain), /* record step size 5 */
-SOC_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9713_alc_select), /* alc source select 6*/
-SOC_ENUM_SINGLE(AC97_REC_GAIN, 14, 4, wm9713_mono_pga), /* mono input select 7 */
-SOC_ENUM_SINGLE(AC97_REC_GAIN, 11, 8, wm9713_spk_pga), /* speaker left input select 8 */
-SOC_ENUM_SINGLE(AC97_REC_GAIN, 8, 8, wm9713_spk_pga), /* speaker right input select 9 */
-SOC_ENUM_SINGLE(AC97_REC_GAIN, 6, 3, wm9713_hp_pga), /* headphone left input 10 */
-SOC_ENUM_SINGLE(AC97_REC_GAIN, 4, 3, wm9713_hp_pga), /* headphone right input 11 */
-SOC_ENUM_SINGLE(AC97_REC_GAIN, 2, 4, wm9713_out3_pga), /* out 3 source 12 */
-SOC_ENUM_SINGLE(AC97_REC_GAIN, 0, 4, wm9713_out4_pga), /* out 4 source 13 */
-SOC_ENUM_SINGLE(AC97_REC_GAIN_MIC, 13, 8, wm9713_dac_inv), /* dac invert 1 14 */
-SOC_ENUM_SINGLE(AC97_REC_GAIN_MIC, 10, 8, wm9713_dac_inv), /* dac invert 2 15 */
-SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, wm9713_bass), /* bass control 16 */
-SOC_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9713_ng_type), /* noise gate type 17 */
-SOC_ENUM_SINGLE(AC97_3D_CONTROL, 12, 3, wm9713_mic_select), /* mic selection 18 */
-SOC_ENUM_SINGLE(MICB_MUX, 0, 2, wm9713_micb_select), /* mic selection 19 */
-};
-
-static const DECLARE_TLV_DB_SCALE(out_tlv, -4650, 150, 0);
-static const DECLARE_TLV_DB_SCALE(main_tlv, -3450, 150, 0);
-static const DECLARE_TLV_DB_SCALE(misc_tlv, -1500, 300, 0);
-static unsigned int mic_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 2, TLV_DB_SCALE_ITEM(1200, 600, 0),
- 3, 3, TLV_DB_SCALE_ITEM(3000, 0, 0),
-};
-
-static const struct snd_kcontrol_new wm9713_snd_ac97_controls[] = {
-SOC_DOUBLE_TLV("Speaker Playback Volume", AC97_MASTER, 8, 0, 31, 1, out_tlv),
-SOC_DOUBLE("Speaker Playback Switch", AC97_MASTER, 15, 7, 1, 1),
-SOC_DOUBLE_TLV("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1,
- out_tlv),
-SOC_DOUBLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 7, 1, 1),
-SOC_DOUBLE_TLV("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1, main_tlv),
-SOC_DOUBLE_TLV("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1, main_tlv),
-SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv),
-SOC_SINGLE_TLV("Mic 2 Volume", AC97_MIC, 0, 31, 1, main_tlv),
-SOC_SINGLE_TLV("Mic 1 Preamp Volume", AC97_3D_CONTROL, 10, 3, 0, mic_tlv),
-SOC_SINGLE_TLV("Mic 2 Preamp Volume", AC97_3D_CONTROL, 12, 3, 0, mic_tlv),
-
-SOC_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0),
-SOC_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1),
-
-SOC_SINGLE("Capture Switch", AC97_CD, 15, 1, 1),
-SOC_ENUM("Capture Volume Steps", wm9713_enum[5]),
-SOC_DOUBLE("Capture Volume", AC97_CD, 8, 0, 31, 0),
-SOC_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0),
-
-SOC_SINGLE_TLV("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1, misc_tlv),
-SOC_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0),
-SOC_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0),
-
-SOC_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0),
-SOC_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0),
-SOC_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV, 4, 15, 0),
-SOC_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0),
-SOC_ENUM("ALC Function", wm9713_enum[6]),
-SOC_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0),
-SOC_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 0),
-SOC_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0),
-SOC_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0),
-SOC_ENUM("ALC NG Type", wm9713_enum[17]),
-SOC_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 0),
-
-SOC_DOUBLE("Speaker Playback ZC Switch", AC97_MASTER, 14, 6, 1, 0),
-SOC_DOUBLE("Headphone Playback ZC Switch", AC97_HEADPHONE, 14, 6, 1, 0),
-
-SOC_SINGLE("Out4 Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
-SOC_SINGLE("Out4 Playback ZC Switch", AC97_MASTER_MONO, 14, 1, 0),
-SOC_SINGLE_TLV("Out4 Playback Volume", AC97_MASTER_MONO, 8, 31, 1, out_tlv),
-
-SOC_SINGLE("Out3 Playback Switch", AC97_MASTER_MONO, 7, 1, 1),
-SOC_SINGLE("Out3 Playback ZC Switch", AC97_MASTER_MONO, 6, 1, 0),
-SOC_SINGLE_TLV("Out3 Playback Volume", AC97_MASTER_MONO, 0, 31, 1, out_tlv),
-
-SOC_SINGLE_TLV("Mono Capture Volume", AC97_MASTER_TONE, 8, 31, 1, main_tlv),
-SOC_SINGLE("Mono Playback Switch", AC97_MASTER_TONE, 7, 1, 1),
-SOC_SINGLE("Mono Playback ZC Switch", AC97_MASTER_TONE, 6, 1, 0),
-SOC_SINGLE_TLV("Mono Playback Volume", AC97_MASTER_TONE, 0, 31, 1, out_tlv),
-
-SOC_SINGLE_TLV("Headphone Mixer Beep Playback Volume", AC97_AUX, 12, 7, 1,
- misc_tlv),
-SOC_SINGLE_TLV("Speaker Mixer Beep Playback Volume", AC97_AUX, 8, 7, 1,
- misc_tlv),
-SOC_SINGLE_TLV("Mono Mixer Beep Playback Volume", AC97_AUX, 4, 7, 1, misc_tlv),
-
-SOC_SINGLE_TLV("Voice Playback Headphone Volume", AC97_PCM, 12, 7, 1,
- misc_tlv),
-SOC_SINGLE("Voice Playback Master Volume", AC97_PCM, 8, 7, 1),
-SOC_SINGLE("Voice Playback Mono Volume", AC97_PCM, 4, 7, 1),
-
-SOC_SINGLE_TLV("Headphone Mixer Aux Playback Volume", AC97_REC_SEL, 12, 7, 1,
- misc_tlv),
-
-SOC_SINGLE_TLV("Speaker Mixer Voice Playback Volume", AC97_PCM, 8, 7, 1,
- misc_tlv),
-SOC_SINGLE_TLV("Speaker Mixer Aux Playback Volume", AC97_REC_SEL, 8, 7, 1,
- misc_tlv),
-
-SOC_SINGLE_TLV("Mono Mixer Voice Playback Volume", AC97_PCM, 4, 7, 1,
- misc_tlv),
-SOC_SINGLE_TLV("Mono Mixer Aux Playback Volume", AC97_REC_SEL, 4, 7, 1,
- misc_tlv),
-
-SOC_SINGLE("Aux Playback Headphone Volume", AC97_REC_SEL, 12, 7, 1),
-SOC_SINGLE("Aux Playback Master Volume", AC97_REC_SEL, 8, 7, 1),
-
-SOC_ENUM("Bass Control", wm9713_enum[16]),
-SOC_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1),
-SOC_SINGLE("Tone Cut-off Switch", AC97_GENERAL_PURPOSE, 4, 1, 1),
-SOC_SINGLE("Playback Attenuate (-6dB) Switch", AC97_GENERAL_PURPOSE, 6, 1, 0),
-SOC_SINGLE("Bass Volume", AC97_GENERAL_PURPOSE, 8, 15, 1),
-SOC_SINGLE("Tone Volume", AC97_GENERAL_PURPOSE, 0, 15, 1),
-
-SOC_SINGLE("3D Upper Cut-off Switch", AC97_REC_GAIN_MIC, 5, 1, 0),
-SOC_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0),
-SOC_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1),
-};
-
-static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- u16 status, rate;
-
- BUG_ON(event != SND_SOC_DAPM_PRE_PMD);
-
- /* Gracefully shut down the voice interface. */
- status = ac97_read(codec, AC97_EXTENDED_MID) | 0x1000;
- rate = ac97_read(codec, AC97_HANDSET_RATE) & 0xF0FF;
- ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0200);
- schedule_timeout_interruptible(msecs_to_jiffies(1));
- ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0F00);
- ac97_write(codec, AC97_EXTENDED_MID, status);
-
- return 0;
-}
-
-
-/* We have to create a fake left and right HP mixers because
- * the codec only has a single control that is shared by both channels.
- * This makes it impossible to determine the audio path using the current
- * register map, thus we add a new (virtual) register to help determine the
- * audio route within the device.
- */
-static int mixer_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- u16 l, r, beep, tone, phone, rec, pcm, aux;
-
- l = ac97_read(w->codec, HPL_MIXER);
- r = ac97_read(w->codec, HPR_MIXER);
- beep = ac97_read(w->codec, AC97_PC_BEEP);
- tone = ac97_read(w->codec, AC97_MASTER_TONE);
- phone = ac97_read(w->codec, AC97_PHONE);
- rec = ac97_read(w->codec, AC97_REC_SEL);
- pcm = ac97_read(w->codec, AC97_PCM);
- aux = ac97_read(w->codec, AC97_AUX);
-
- if (event & SND_SOC_DAPM_PRE_REG)
- return 0;
- if ((l & 0x1) || (r & 0x1))
- ac97_write(w->codec, AC97_PC_BEEP, beep & 0x7fff);
- else
- ac97_write(w->codec, AC97_PC_BEEP, beep | 0x8000);
-
- if ((l & 0x2) || (r & 0x2))
- ac97_write(w->codec, AC97_MASTER_TONE, tone & 0x7fff);
- else
- ac97_write(w->codec, AC97_MASTER_TONE, tone | 0x8000);
-
- if ((l & 0x4) || (r & 0x4))
- ac97_write(w->codec, AC97_PHONE, phone & 0x7fff);
- else
- ac97_write(w->codec, AC97_PHONE, phone | 0x8000);
-
- if ((l & 0x8) || (r & 0x8))
- ac97_write(w->codec, AC97_REC_SEL, rec & 0x7fff);
- else
- ac97_write(w->codec, AC97_REC_SEL, rec | 0x8000);
-
- if ((l & 0x10) || (r & 0x10))
- ac97_write(w->codec, AC97_PCM, pcm & 0x7fff);
- else
- ac97_write(w->codec, AC97_PCM, pcm | 0x8000);
-
- if ((l & 0x20) || (r & 0x20))
- ac97_write(w->codec, AC97_AUX, aux & 0x7fff);
- else
- ac97_write(w->codec, AC97_AUX, aux | 0x8000);
-
- return 0;
-}
-
-/* Left Headphone Mixers */
-static const struct snd_kcontrol_new wm9713_hpl_mixer_controls[] = {
-SOC_DAPM_SINGLE("Beep Playback Switch", HPL_MIXER, 5, 1, 0),
-SOC_DAPM_SINGLE("Voice Playback Switch", HPL_MIXER, 4, 1, 0),
-SOC_DAPM_SINGLE("Aux Playback Switch", HPL_MIXER, 3, 1, 0),
-SOC_DAPM_SINGLE("PCM Playback Switch", HPL_MIXER, 2, 1, 0),
-SOC_DAPM_SINGLE("MonoIn Playback Switch", HPL_MIXER, 1, 1, 0),
-SOC_DAPM_SINGLE("Bypass Playback Switch", HPL_MIXER, 0, 1, 0),
-};
-
-/* Right Headphone Mixers */
-static const struct snd_kcontrol_new wm9713_hpr_mixer_controls[] = {
-SOC_DAPM_SINGLE("Beep Playback Switch", HPR_MIXER, 5, 1, 0),
-SOC_DAPM_SINGLE("Voice Playback Switch", HPR_MIXER, 4, 1, 0),
-SOC_DAPM_SINGLE("Aux Playback Switch", HPR_MIXER, 3, 1, 0),
-SOC_DAPM_SINGLE("PCM Playback Switch", HPR_MIXER, 2, 1, 0),
-SOC_DAPM_SINGLE("MonoIn Playback Switch", HPR_MIXER, 1, 1, 0),
-SOC_DAPM_SINGLE("Bypass Playback Switch", HPR_MIXER, 0, 1, 0),
-};
-
-/* headphone capture mux */
-static const struct snd_kcontrol_new wm9713_hp_rec_mux_controls =
-SOC_DAPM_ENUM("Route", wm9713_enum[1]);
-
-/* headphone mic mux */
-static const struct snd_kcontrol_new wm9713_hp_mic_mux_controls =
-SOC_DAPM_ENUM("Route", wm9713_enum[0]);
-
-/* Speaker Mixer */
-static const struct snd_kcontrol_new wm9713_speaker_mixer_controls[] = {
-SOC_DAPM_SINGLE("Beep Playback Switch", AC97_AUX, 11, 1, 1),
-SOC_DAPM_SINGLE("Voice Playback Switch", AC97_PCM, 11, 1, 1),
-SOC_DAPM_SINGLE("Aux Playback Switch", AC97_REC_SEL, 11, 1, 1),
-SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PHONE, 14, 1, 1),
-SOC_DAPM_SINGLE("MonoIn Playback Switch", AC97_MASTER_TONE, 14, 1, 1),
-SOC_DAPM_SINGLE("Bypass Playback Switch", AC97_PC_BEEP, 14, 1, 1),
-};
-
-/* Mono Mixer */
-static const struct snd_kcontrol_new wm9713_mono_mixer_controls[] = {
-SOC_DAPM_SINGLE("Beep Playback Switch", AC97_AUX, 7, 1, 1),
-SOC_DAPM_SINGLE("Voice Playback Switch", AC97_PCM, 7, 1, 1),
-SOC_DAPM_SINGLE("Aux Playback Switch", AC97_REC_SEL, 7, 1, 1),
-SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PHONE, 13, 1, 1),
-SOC_DAPM_SINGLE("MonoIn Playback Switch", AC97_MASTER_TONE, 13, 1, 1),
-SOC_DAPM_SINGLE("Bypass Playback Switch", AC97_PC_BEEP, 13, 1, 1),
-SOC_DAPM_SINGLE("Mic 1 Sidetone Switch", AC97_LINE, 7, 1, 1),
-SOC_DAPM_SINGLE("Mic 2 Sidetone Switch", AC97_LINE, 6, 1, 1),
-};
-
-/* mono mic mux */
-static const struct snd_kcontrol_new wm9713_mono_mic_mux_controls =
-SOC_DAPM_ENUM("Route", wm9713_enum[2]);
-
-/* mono output mux */
-static const struct snd_kcontrol_new wm9713_mono_mux_controls =
-SOC_DAPM_ENUM("Route", wm9713_enum[7]);
-
-/* speaker left output mux */
-static const struct snd_kcontrol_new wm9713_hp_spkl_mux_controls =
-SOC_DAPM_ENUM("Route", wm9713_enum[8]);
-
-/* speaker right output mux */
-static const struct snd_kcontrol_new wm9713_hp_spkr_mux_controls =
-SOC_DAPM_ENUM("Route", wm9713_enum[9]);
-
-/* headphone left output mux */
-static const struct snd_kcontrol_new wm9713_hpl_out_mux_controls =
-SOC_DAPM_ENUM("Route", wm9713_enum[10]);
-
-/* headphone right output mux */
-static const struct snd_kcontrol_new wm9713_hpr_out_mux_controls =
-SOC_DAPM_ENUM("Route", wm9713_enum[11]);
-
-/* Out3 mux */
-static const struct snd_kcontrol_new wm9713_out3_mux_controls =
-SOC_DAPM_ENUM("Route", wm9713_enum[12]);
-
-/* Out4 mux */
-static const struct snd_kcontrol_new wm9713_out4_mux_controls =
-SOC_DAPM_ENUM("Route", wm9713_enum[13]);
-
-/* DAC inv mux 1 */
-static const struct snd_kcontrol_new wm9713_dac_inv1_mux_controls =
-SOC_DAPM_ENUM("Route", wm9713_enum[14]);
-
-/* DAC inv mux 2 */
-static const struct snd_kcontrol_new wm9713_dac_inv2_mux_controls =
-SOC_DAPM_ENUM("Route", wm9713_enum[15]);
-
-/* Capture source left */
-static const struct snd_kcontrol_new wm9713_rec_srcl_mux_controls =
-SOC_DAPM_ENUM("Route", wm9713_enum[3]);
-
-/* Capture source right */
-static const struct snd_kcontrol_new wm9713_rec_srcr_mux_controls =
-SOC_DAPM_ENUM("Route", wm9713_enum[4]);
-
-/* mic source */
-static const struct snd_kcontrol_new wm9713_mic_sel_mux_controls =
-SOC_DAPM_ENUM("Route", wm9713_enum[18]);
-
-/* mic source B virtual control */
-static const struct snd_kcontrol_new wm9713_micb_sel_mux_controls =
-SOC_DAPM_ENUM("Route", wm9713_enum[19]);
-
-static const struct snd_soc_dapm_widget wm9713_dapm_widgets[] = {
-SND_SOC_DAPM_MUX("Capture Headphone Mux", SND_SOC_NOPM, 0, 0,
- &wm9713_hp_rec_mux_controls),
-SND_SOC_DAPM_MUX("Sidetone Mux", SND_SOC_NOPM, 0, 0,
- &wm9713_hp_mic_mux_controls),
-SND_SOC_DAPM_MUX("Capture Mono Mux", SND_SOC_NOPM, 0, 0,
- &wm9713_mono_mic_mux_controls),
-SND_SOC_DAPM_MUX("Mono Out Mux", SND_SOC_NOPM, 0, 0,
- &wm9713_mono_mux_controls),
-SND_SOC_DAPM_MUX("Left Speaker Out Mux", SND_SOC_NOPM, 0, 0,
- &wm9713_hp_spkl_mux_controls),
-SND_SOC_DAPM_MUX("Right Speaker Out Mux", SND_SOC_NOPM, 0, 0,
- &wm9713_hp_spkr_mux_controls),
-SND_SOC_DAPM_MUX("Left Headphone Out Mux", SND_SOC_NOPM, 0, 0,
- &wm9713_hpl_out_mux_controls),
-SND_SOC_DAPM_MUX("Right Headphone Out Mux", SND_SOC_NOPM, 0, 0,
- &wm9713_hpr_out_mux_controls),
-SND_SOC_DAPM_MUX("Out 3 Mux", SND_SOC_NOPM, 0, 0,
- &wm9713_out3_mux_controls),
-SND_SOC_DAPM_MUX("Out 4 Mux", SND_SOC_NOPM, 0, 0,
- &wm9713_out4_mux_controls),
-SND_SOC_DAPM_MUX("DAC Inv Mux 1", SND_SOC_NOPM, 0, 0,
- &wm9713_dac_inv1_mux_controls),
-SND_SOC_DAPM_MUX("DAC Inv Mux 2", SND_SOC_NOPM, 0, 0,
- &wm9713_dac_inv2_mux_controls),
-SND_SOC_DAPM_MUX("Left Capture Source", SND_SOC_NOPM, 0, 0,
- &wm9713_rec_srcl_mux_controls),
-SND_SOC_DAPM_MUX("Right Capture Source", SND_SOC_NOPM, 0, 0,
- &wm9713_rec_srcr_mux_controls),
-SND_SOC_DAPM_MUX("Mic A Source", SND_SOC_NOPM, 0, 0,
- &wm9713_mic_sel_mux_controls),
-SND_SOC_DAPM_MUX("Mic B Source", SND_SOC_NOPM, 0, 0,
- &wm9713_micb_sel_mux_controls),
-SND_SOC_DAPM_MIXER_E("Left HP Mixer", AC97_EXTENDED_MID, 3, 1,
- &wm9713_hpl_mixer_controls[0], ARRAY_SIZE(wm9713_hpl_mixer_controls),
- mixer_event, SND_SOC_DAPM_POST_REG),
-SND_SOC_DAPM_MIXER_E("Right HP Mixer", AC97_EXTENDED_MID, 2, 1,
- &wm9713_hpr_mixer_controls[0], ARRAY_SIZE(wm9713_hpr_mixer_controls),
- mixer_event, SND_SOC_DAPM_POST_REG),
-SND_SOC_DAPM_MIXER("Mono Mixer", AC97_EXTENDED_MID, 0, 1,
- &wm9713_mono_mixer_controls[0], ARRAY_SIZE(wm9713_mono_mixer_controls)),
-SND_SOC_DAPM_MIXER("Speaker Mixer", AC97_EXTENDED_MID, 1, 1,
- &wm9713_speaker_mixer_controls[0],
- ARRAY_SIZE(wm9713_speaker_mixer_controls)),
-SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", AC97_EXTENDED_MID, 7, 1),
-SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", AC97_EXTENDED_MID, 6, 1),
-SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("HP Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("Line Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("Capture Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_DAC_E("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1,
- wm9713_voice_shutdown, SND_SOC_DAPM_PRE_PMD),
-SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", AC97_EXTENDED_MID, 11, 1),
-SND_SOC_DAPM_PGA("Left ADC", AC97_EXTENDED_MID, 5, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Right ADC", AC97_EXTENDED_MID, 4, 1, NULL, 0),
-SND_SOC_DAPM_ADC("Left HiFi ADC", "Left HiFi Capture", SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_ADC("Right HiFi ADC", "Right HiFi Capture", SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_ADC("Left Voice ADC", "Left Voice Capture", SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_ADC("Right Voice ADC", "Right Voice Capture", SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_PGA("Left Headphone", AC97_EXTENDED_MSTATUS, 10, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Right Headphone", AC97_EXTENDED_MSTATUS, 9, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Left Speaker", AC97_EXTENDED_MSTATUS, 8, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Right Speaker", AC97_EXTENDED_MSTATUS, 7, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Out 3", AC97_EXTENDED_MSTATUS, 11, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Out 4", AC97_EXTENDED_MSTATUS, 12, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Mono Out", AC97_EXTENDED_MSTATUS, 13, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Left Line In", AC97_EXTENDED_MSTATUS, 6, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Right Line In", AC97_EXTENDED_MSTATUS, 5, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Mono In", AC97_EXTENDED_MSTATUS, 4, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Mic A PGA", AC97_EXTENDED_MSTATUS, 3, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Mic B PGA", AC97_EXTENDED_MSTATUS, 2, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Mic A Pre Amp", AC97_EXTENDED_MSTATUS, 1, 1, NULL, 0),
-SND_SOC_DAPM_PGA("Mic B Pre Amp", AC97_EXTENDED_MSTATUS, 0, 1, NULL, 0),
-SND_SOC_DAPM_MICBIAS("Mic Bias", AC97_EXTENDED_MSTATUS, 14, 1),
-SND_SOC_DAPM_OUTPUT("MONO"),
-SND_SOC_DAPM_OUTPUT("HPL"),
-SND_SOC_DAPM_OUTPUT("HPR"),
-SND_SOC_DAPM_OUTPUT("SPKL"),
-SND_SOC_DAPM_OUTPUT("SPKR"),
-SND_SOC_DAPM_OUTPUT("OUT3"),
-SND_SOC_DAPM_OUTPUT("OUT4"),
-SND_SOC_DAPM_INPUT("LINEL"),
-SND_SOC_DAPM_INPUT("LINER"),
-SND_SOC_DAPM_INPUT("MONOIN"),
-SND_SOC_DAPM_INPUT("PCBEEP"),
-SND_SOC_DAPM_INPUT("MIC1"),
-SND_SOC_DAPM_INPUT("MIC2A"),
-SND_SOC_DAPM_INPUT("MIC2B"),
-SND_SOC_DAPM_VMID("VMID"),
-};
-
-static const struct snd_soc_dapm_route wm9713_audio_map[] = {
- /* left HP mixer */
- {"Left HP Mixer", "Beep Playback Switch", "PCBEEP"},
- {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"},
- {"Left HP Mixer", "Aux Playback Switch", "Aux DAC"},
- {"Left HP Mixer", "Bypass Playback Switch", "Left Line In"},
- {"Left HP Mixer", "PCM Playback Switch", "Left DAC"},
- {"Left HP Mixer", "MonoIn Playback Switch", "Mono In"},
- {"Left HP Mixer", NULL, "Capture Headphone Mux"},
-
- /* right HP mixer */
- {"Right HP Mixer", "Beep Playback Switch", "PCBEEP"},
- {"Right HP Mixer", "Voice Playback Switch", "Voice DAC"},
- {"Right HP Mixer", "Aux Playback Switch", "Aux DAC"},
- {"Right HP Mixer", "Bypass Playback Switch", "Right Line In"},
- {"Right HP Mixer", "PCM Playback Switch", "Right DAC"},
- {"Right HP Mixer", "MonoIn Playback Switch", "Mono In"},
- {"Right HP Mixer", NULL, "Capture Headphone Mux"},
-
- /* virtual mixer - mixes left & right channels for spk and mono */
- {"AC97 Mixer", NULL, "Left DAC"},
- {"AC97 Mixer", NULL, "Right DAC"},
- {"Line Mixer", NULL, "Right Line In"},
- {"Line Mixer", NULL, "Left Line In"},
- {"HP Mixer", NULL, "Left HP Mixer"},
- {"HP Mixer", NULL, "Right HP Mixer"},
- {"Capture Mixer", NULL, "Left Capture Source"},
- {"Capture Mixer", NULL, "Right Capture Source"},
-
- /* speaker mixer */
- {"Speaker Mixer", "Beep Playback Switch", "PCBEEP"},
- {"Speaker Mixer", "Voice Playback Switch", "Voice DAC"},
- {"Speaker Mixer", "Aux Playback Switch", "Aux DAC"},
- {"Speaker Mixer", "Bypass Playback Switch", "Line Mixer"},
- {"Speaker Mixer", "PCM Playback Switch", "AC97 Mixer"},
- {"Speaker Mixer", "MonoIn Playback Switch", "Mono In"},
-
- /* mono mixer */
- {"Mono Mixer", "Beep Playback Switch", "PCBEEP"},
- {"Mono Mixer", "Voice Playback Switch", "Voice DAC"},
- {"Mono Mixer", "Aux Playback Switch", "Aux DAC"},
- {"Mono Mixer", "Bypass Playback Switch", "Line Mixer"},
- {"Mono Mixer", "PCM Playback Switch", "AC97 Mixer"},
- {"Mono Mixer", "Mic 1 Sidetone Switch", "Mic A PGA"},
- {"Mono Mixer", "Mic 2 Sidetone Switch", "Mic B PGA"},
- {"Mono Mixer", NULL, "Capture Mono Mux"},
-
- /* DAC inv mux 1 */
- {"DAC Inv Mux 1", "Mono", "Mono Mixer"},
- {"DAC Inv Mux 1", "Speaker", "Speaker Mixer"},
- {"DAC Inv Mux 1", "Left Headphone", "Left HP Mixer"},
- {"DAC Inv Mux 1", "Right Headphone", "Right HP Mixer"},
- {"DAC Inv Mux 1", "Headphone Mono", "HP Mixer"},
-
- /* DAC inv mux 2 */
- {"DAC Inv Mux 2", "Mono", "Mono Mixer"},
- {"DAC Inv Mux 2", "Speaker", "Speaker Mixer"},
- {"DAC Inv Mux 2", "Left Headphone", "Left HP Mixer"},
- {"DAC Inv Mux 2", "Right Headphone", "Right HP Mixer"},
- {"DAC Inv Mux 2", "Headphone Mono", "HP Mixer"},
-
- /* headphone left mux */
- {"Left Headphone Out Mux", "Headphone", "Left HP Mixer"},
-
- /* headphone right mux */
- {"Right Headphone Out Mux", "Headphone", "Right HP Mixer"},
-
- /* speaker left mux */
- {"Left Speaker Out Mux", "Headphone", "Left HP Mixer"},
- {"Left Speaker Out Mux", "Speaker", "Speaker Mixer"},
- {"Left Speaker Out Mux", "Inv", "DAC Inv Mux 1"},
-
- /* speaker right mux */
- {"Right Speaker Out Mux", "Headphone", "Right HP Mixer"},
- {"Right Speaker Out Mux", "Speaker", "Speaker Mixer"},
- {"Right Speaker Out Mux", "Inv", "DAC Inv Mux 2"},
-
- /* mono mux */
- {"Mono Out Mux", "Mono", "Mono Mixer"},
- {"Mono Out Mux", "Inv", "DAC Inv Mux 1"},
-
- /* out 3 mux */
- {"Out 3 Mux", "Inv 1", "DAC Inv Mux 1"},
-
- /* out 4 mux */
- {"Out 4 Mux", "Inv 2", "DAC Inv Mux 2"},
-
- /* output pga */
- {"HPL", NULL, "Left Headphone"},
- {"Left Headphone", NULL, "Left Headphone Out Mux"},
- {"HPR", NULL, "Right Headphone"},
- {"Right Headphone", NULL, "Right Headphone Out Mux"},
- {"OUT3", NULL, "Out 3"},
- {"Out 3", NULL, "Out 3 Mux"},
- {"OUT4", NULL, "Out 4"},
- {"Out 4", NULL, "Out 4 Mux"},
- {"SPKL", NULL, "Left Speaker"},
- {"Left Speaker", NULL, "Left Speaker Out Mux"},
- {"SPKR", NULL, "Right Speaker"},
- {"Right Speaker", NULL, "Right Speaker Out Mux"},
- {"MONO", NULL, "Mono Out"},
- {"Mono Out", NULL, "Mono Out Mux"},
-
- /* input pga */
- {"Left Line In", NULL, "LINEL"},
- {"Right Line In", NULL, "LINER"},
- {"Mono In", NULL, "MONOIN"},
- {"Mic A PGA", NULL, "Mic A Pre Amp"},
- {"Mic B PGA", NULL, "Mic B Pre Amp"},
-
- /* left capture select */
- {"Left Capture Source", "Mic 1", "Mic A Pre Amp"},
- {"Left Capture Source", "Mic 2", "Mic B Pre Amp"},
- {"Left Capture Source", "Line", "LINEL"},
- {"Left Capture Source", "Mono In", "MONOIN"},
- {"Left Capture Source", "Headphone", "Left HP Mixer"},
- {"Left Capture Source", "Speaker", "Speaker Mixer"},
- {"Left Capture Source", "Mono Out", "Mono Mixer"},
-
- /* right capture select */
- {"Right Capture Source", "Mic 1", "Mic A Pre Amp"},
- {"Right Capture Source", "Mic 2", "Mic B Pre Amp"},
- {"Right Capture Source", "Line", "LINER"},
- {"Right Capture Source", "Mono In", "MONOIN"},
- {"Right Capture Source", "Headphone", "Right HP Mixer"},
- {"Right Capture Source", "Speaker", "Speaker Mixer"},
- {"Right Capture Source", "Mono Out", "Mono Mixer"},
-
- /* left ADC */
- {"Left ADC", NULL, "Left Capture Source"},
- {"Left Voice ADC", NULL, "Left ADC"},
- {"Left HiFi ADC", NULL, "Left ADC"},
-
- /* right ADC */
- {"Right ADC", NULL, "Right Capture Source"},
- {"Right Voice ADC", NULL, "Right ADC"},
- {"Right HiFi ADC", NULL, "Right ADC"},
-
- /* mic */
- {"Mic A Pre Amp", NULL, "Mic A Source"},
- {"Mic A Source", "Mic 1", "MIC1"},
- {"Mic A Source", "Mic 2 A", "MIC2A"},
- {"Mic A Source", "Mic 2 B", "Mic B Source"},
- {"Mic B Pre Amp", "MPB", "Mic B Source"},
- {"Mic B Source", NULL, "MIC2B"},
-
- /* headphone capture */
- {"Capture Headphone Mux", "Stereo", "Capture Mixer"},
- {"Capture Headphone Mux", "Left", "Left Capture Source"},
- {"Capture Headphone Mux", "Right", "Right Capture Source"},
-
- /* mono capture */
- {"Capture Mono Mux", "Stereo", "Capture Mixer"},
- {"Capture Mono Mux", "Left", "Left Capture Source"},
- {"Capture Mono Mux", "Right", "Right Capture Source"},
-};
-
-static unsigned int ac97_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- u16 *cache = codec->reg_cache;
-
- if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||
- reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 ||
- reg == AC97_CD)
- return soc_ac97_ops.read(codec->ac97, reg);
- else {
- reg = reg >> 1;
-
- if (reg >= (ARRAY_SIZE(wm9713_reg)))
- return -EIO;
-
- return cache[reg];
- }
-}
-
-static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int val)
-{
- u16 *cache = codec->reg_cache;
- if (reg < 0x7c)
- soc_ac97_ops.write(codec->ac97, reg, val);
- reg = reg >> 1;
- if (reg < (ARRAY_SIZE(wm9713_reg)))
- cache[reg] = val;
-
- return 0;
-}
-
-/* PLL divisors */
-struct _pll_div {
- u32 divsel:1;
- u32 divctl:1;
- u32 lf:1;
- u32 n:4;
- u32 k:24;
-};
-
-/* The size in bits of the PLL divide multiplied by 10
- * to allow rounding later */
-#define FIXED_PLL_SIZE ((1 << 22) * 10)
-
-static void pll_factors(struct _pll_div *pll_div, unsigned int source)
-{
- u64 Kpart;
- unsigned int K, Ndiv, Nmod, target;
-
- /* The the PLL output is always 98.304MHz. */
- target = 98304000;
-
- /* If the input frequency is over 14.4MHz then scale it down. */
- if (source > 14400000) {
- source >>= 1;
- pll_div->divsel = 1;
-
- if (source > 14400000) {
- source >>= 1;
- pll_div->divctl = 1;
- } else
- pll_div->divctl = 0;
-
- } else {
- pll_div->divsel = 0;
- pll_div->divctl = 0;
- }
-
- /* Low frequency sources require an additional divide in the
- * loop.
- */
- if (source < 8192000) {
- pll_div->lf = 1;
- target >>= 2;
- } else
- pll_div->lf = 0;
-
- Ndiv = target / source;
- if ((Ndiv < 5) || (Ndiv > 12))
- printk(KERN_WARNING
- "WM9713 PLL N value %u out of recommended range!\n",
- Ndiv);
-
- pll_div->n = Ndiv;
- Nmod = target % source;
- Kpart = FIXED_PLL_SIZE * (long long)Nmod;
-
- do_div(Kpart, source);
-
- K = Kpart & 0xFFFFFFFF;
-
- /* Check if we need to round */
- if ((K % 10) >= 5)
- K += 5;
-
- /* Move down to proper range now rounding is done */
- K /= 10;
-
- pll_div->k = K;
-}
-
-/**
- * Please note that changing the PLL input frequency may require
- * resynchronisation with the AC97 controller.
- */
-static int wm9713_set_pll(struct snd_soc_codec *codec,
- int pll_id, unsigned int freq_in, unsigned int freq_out)
-{
- struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
- u16 reg, reg2;
- struct _pll_div pll_div;
-
- /* turn PLL off ? */
- if (freq_in == 0) {
- /* disable PLL power and select ext source */
- reg = ac97_read(codec, AC97_HANDSET_RATE);
- ac97_write(codec, AC97_HANDSET_RATE, reg | 0x0080);
- reg = ac97_read(codec, AC97_EXTENDED_MID);
- ac97_write(codec, AC97_EXTENDED_MID, reg | 0x0200);
- wm9713->pll_in = 0;
- return 0;
- }
-
- pll_factors(&pll_div, freq_in);
-
- if (pll_div.k == 0) {
- reg = (pll_div.n << 12) | (pll_div.lf << 11) |
- (pll_div.divsel << 9) | (pll_div.divctl << 8);
- ac97_write(codec, AC97_LINE1_LEVEL, reg);
- } else {
- /* write the fractional k to the reg 0x46 pages */
- reg2 = (pll_div.n << 12) | (pll_div.lf << 11) | (1 << 10) |
- (pll_div.divsel << 9) | (pll_div.divctl << 8);
-
- /* K [21:20] */
- reg = reg2 | (0x5 << 4) | (pll_div.k >> 20);
- ac97_write(codec, AC97_LINE1_LEVEL, reg);
-
- /* K [19:16] */
- reg = reg2 | (0x4 << 4) | ((pll_div.k >> 16) & 0xf);
- ac97_write(codec, AC97_LINE1_LEVEL, reg);
-
- /* K [15:12] */
- reg = reg2 | (0x3 << 4) | ((pll_div.k >> 12) & 0xf);
- ac97_write(codec, AC97_LINE1_LEVEL, reg);
-
- /* K [11:8] */
- reg = reg2 | (0x2 << 4) | ((pll_div.k >> 8) & 0xf);
- ac97_write(codec, AC97_LINE1_LEVEL, reg);
-
- /* K [7:4] */
- reg = reg2 | (0x1 << 4) | ((pll_div.k >> 4) & 0xf);
- ac97_write(codec, AC97_LINE1_LEVEL, reg);
-
- reg = reg2 | (0x0 << 4) | (pll_div.k & 0xf); /* K [3:0] */
- ac97_write(codec, AC97_LINE1_LEVEL, reg);
- }
-
- /* turn PLL on and select as source */
- reg = ac97_read(codec, AC97_EXTENDED_MID);
- ac97_write(codec, AC97_EXTENDED_MID, reg & 0xfdff);
- reg = ac97_read(codec, AC97_HANDSET_RATE);
- ac97_write(codec, AC97_HANDSET_RATE, reg & 0xff7f);
- wm9713->pll_in = freq_in;
-
- /* wait 10ms AC97 link frames for the link to stabilise */
- schedule_timeout_interruptible(msecs_to_jiffies(10));
- return 0;
-}
-
-static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
- int source, unsigned int freq_in, unsigned int freq_out)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- return wm9713_set_pll(codec, pll_id, freq_in, freq_out);
-}
-
-/*
- * Tristate the PCM DAI lines, tristate can be disabled by calling
- * wm9713_set_dai_fmt()
- */
-static int wm9713_set_dai_tristate(struct snd_soc_dai *codec_dai,
- int tristate)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 reg = ac97_read(codec, AC97_CENTER_LFE_MASTER) & 0x9fff;
-
- if (tristate)
- ac97_write(codec, AC97_CENTER_LFE_MASTER, reg);
-
- return 0;
-}
-
-/*
- * Configure WM9713 clock dividers.
- * Voice DAC needs 256 FS
- */
-static int wm9713_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
- int div_id, int div)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 reg;
-
- switch (div_id) {
- case WM9713_PCMCLK_DIV:
- reg = ac97_read(codec, AC97_HANDSET_RATE) & 0xf0ff;
- ac97_write(codec, AC97_HANDSET_RATE, reg | div);
- break;
- case WM9713_CLKA_MULT:
- reg = ac97_read(codec, AC97_HANDSET_RATE) & 0xfffd;
- ac97_write(codec, AC97_HANDSET_RATE, reg | div);
- break;
- case WM9713_CLKB_MULT:
- reg = ac97_read(codec, AC97_HANDSET_RATE) & 0xfffb;
- ac97_write(codec, AC97_HANDSET_RATE, reg | div);
- break;
- case WM9713_HIFI_DIV:
- reg = ac97_read(codec, AC97_HANDSET_RATE) & 0x8fff;
- ac97_write(codec, AC97_HANDSET_RATE, reg | div);
- break;
- case WM9713_PCMBCLK_DIV:
- reg = ac97_read(codec, AC97_CENTER_LFE_MASTER) & 0xf1ff;
- ac97_write(codec, AC97_CENTER_LFE_MASTER, reg | div);
- break;
- case WM9713_PCMCLK_PLL_DIV:
- reg = ac97_read(codec, AC97_LINE1_LEVEL) & 0xff80;
- ac97_write(codec, AC97_LINE1_LEVEL, reg | 0x60 | div);
- break;
- case WM9713_HIFI_PLL_DIV:
- reg = ac97_read(codec, AC97_LINE1_LEVEL) & 0xff80;
- ac97_write(codec, AC97_LINE1_LEVEL, reg | 0x70 | div);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int wm9713_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 gpio = ac97_read(codec, AC97_GPIO_CFG) & 0xffc5;
- u16 reg = 0x8000;
-
- /* clock masters */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- reg |= 0x4000;
- gpio |= 0x0010;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- reg |= 0x6000;
- gpio |= 0x0018;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- reg |= 0x2000;
- gpio |= 0x001a;
- break;
- case SND_SOC_DAIFMT_CBS_CFM:
- gpio |= 0x0012;
- break;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_IB_IF:
- reg |= 0x00c0;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- reg |= 0x0080;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- reg |= 0x0040;
- break;
- }
-
- /* DAI format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- reg |= 0x0002;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- reg |= 0x0001;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- reg |= 0x0003;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- reg |= 0x0043;
- break;
- }
-
- ac97_write(codec, AC97_GPIO_CFG, gpio);
- ac97_write(codec, AC97_CENTER_LFE_MASTER, reg);
- return 0;
-}
-
-static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 reg = ac97_read(codec, AC97_CENTER_LFE_MASTER) & 0xfff3;
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- reg |= 0x0004;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- reg |= 0x0008;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- reg |= 0x000c;
- break;
- }
-
- /* enable PCM interface in master mode */
- ac97_write(codec, AC97_CENTER_LFE_MASTER, reg);
- return 0;
-}
-
-static int ac97_hifi_prepare(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int reg;
- u16 vra;
-
- vra = ac97_read(codec, AC97_EXTENDED_STATUS);
- ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- reg = AC97_PCM_FRONT_DAC_RATE;
- else
- reg = AC97_PCM_LR_ADC_RATE;
-
- return ac97_write(codec, reg, runtime->rate);
-}
-
-static int ac97_aux_prepare(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_codec *codec = dai->codec;
- struct snd_pcm_runtime *runtime = substream->runtime;
- u16 vra, xsle;
-
- vra = ac97_read(codec, AC97_EXTENDED_STATUS);
- ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1);
- xsle = ac97_read(codec, AC97_PCI_SID);
- ac97_write(codec, AC97_PCI_SID, xsle | 0x8000);
-
- if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
- return -ENODEV;
-
- return ac97_write(codec, AC97_PCM_SURR_DAC_RATE, runtime->rate);
-}
-
-#define WM9713_RATES (SNDRV_PCM_RATE_8000 | \
- SNDRV_PCM_RATE_11025 | \
- SNDRV_PCM_RATE_22050 | \
- SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000)
-
-#define WM9713_PCM_RATES (SNDRV_PCM_RATE_8000 | \
- SNDRV_PCM_RATE_11025 | \
- SNDRV_PCM_RATE_16000 | \
- SNDRV_PCM_RATE_22050 | \
- SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000)
-
-#define WM9713_PCM_FORMATS \
- (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \
- SNDRV_PCM_FORMAT_S24_LE)
-
-static const struct snd_soc_dai_ops wm9713_dai_ops_hifi = {
- .prepare = ac97_hifi_prepare,
- .set_clkdiv = wm9713_set_dai_clkdiv,
- .set_pll = wm9713_set_dai_pll,
-};
-
-static const struct snd_soc_dai_ops wm9713_dai_ops_aux = {
- .prepare = ac97_aux_prepare,
- .set_clkdiv = wm9713_set_dai_clkdiv,
- .set_pll = wm9713_set_dai_pll,
-};
-
-static const struct snd_soc_dai_ops wm9713_dai_ops_voice = {
- .hw_params = wm9713_pcm_hw_params,
- .set_clkdiv = wm9713_set_dai_clkdiv,
- .set_pll = wm9713_set_dai_pll,
- .set_fmt = wm9713_set_dai_fmt,
- .set_tristate = wm9713_set_dai_tristate,
-};
-
-static struct snd_soc_dai_driver wm9713_dai[] = {
-{
- .name = "wm9713-hifi",
- .ac97_control = 1,
- .playback = {
- .stream_name = "HiFi Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM9713_RATES,
- .formats = SND_SOC_STD_AC97_FMTS,},
- .capture = {
- .stream_name = "HiFi Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM9713_RATES,
- .formats = SND_SOC_STD_AC97_FMTS,},
- .ops = &wm9713_dai_ops_hifi,
- },
- {
- .name = "wm9713-aux",
- .playback = {
- .stream_name = "Aux Playback",
- .channels_min = 1,
- .channels_max = 1,
- .rates = WM9713_RATES,
- .formats = SND_SOC_STD_AC97_FMTS,},
- .ops = &wm9713_dai_ops_aux,
- },
- {
- .name = "wm9713-voice",
- .playback = {
- .stream_name = "Voice Playback",
- .channels_min = 1,
- .channels_max = 1,
- .rates = WM9713_PCM_RATES,
- .formats = WM9713_PCM_FORMATS,},
- .capture = {
- .stream_name = "Voice Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM9713_PCM_RATES,
- .formats = WM9713_PCM_FORMATS,},
- .ops = &wm9713_dai_ops_voice,
- .symmetric_rates = 1,
- },
-};
-
-int wm9713_reset(struct snd_soc_codec *codec, int try_warm)
-{
- if (try_warm && soc_ac97_ops.warm_reset) {
- soc_ac97_ops.warm_reset(codec->ac97);
- if (ac97_read(codec, 0) == wm9713_reg[0])
- return 1;
- }
-
- soc_ac97_ops.reset(codec->ac97);
- if (soc_ac97_ops.warm_reset)
- soc_ac97_ops.warm_reset(codec->ac97);
- if (ac97_read(codec, 0) != wm9713_reg[0])
- return -EIO;
- return 0;
-}
-EXPORT_SYMBOL_GPL(wm9713_reset);
-
-static int wm9713_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- u16 reg;
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- /* enable thermal shutdown */
- reg = ac97_read(codec, AC97_EXTENDED_MID) & 0x1bff;
- ac97_write(codec, AC97_EXTENDED_MID, reg);
- break;
- case SND_SOC_BIAS_PREPARE:
- break;
- case SND_SOC_BIAS_STANDBY:
- /* enable master bias and vmid */
- reg = ac97_read(codec, AC97_EXTENDED_MID) & 0x3bff;
- ac97_write(codec, AC97_EXTENDED_MID, reg);
- ac97_write(codec, AC97_POWERDOWN, 0x0000);
- break;
- case SND_SOC_BIAS_OFF:
- /* disable everything including AC link */
- ac97_write(codec, AC97_EXTENDED_MID, 0xffff);
- ac97_write(codec, AC97_EXTENDED_MSTATUS, 0xffff);
- ac97_write(codec, AC97_POWERDOWN, 0xffff);
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-static int wm9713_soc_suspend(struct snd_soc_codec *codec)
-{
- u16 reg;
-
- /* Disable everything except touchpanel - that will be handled
- * by the touch driver and left disabled if touch is not in
- * use. */
- reg = ac97_read(codec, AC97_EXTENDED_MID);
- ac97_write(codec, AC97_EXTENDED_MID, reg | 0x7fff);
- ac97_write(codec, AC97_EXTENDED_MSTATUS, 0xffff);
- ac97_write(codec, AC97_POWERDOWN, 0x6f00);
- ac97_write(codec, AC97_POWERDOWN, 0xffff);
-
- return 0;
-}
-
-static int wm9713_soc_resume(struct snd_soc_codec *codec)
-{
- struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
- int i, ret;
- u16 *cache = codec->reg_cache;
-
- ret = wm9713_reset(codec, 1);
- if (ret < 0) {
- printk(KERN_ERR "could not reset AC97 codec\n");
- return ret;
- }
-
- wm9713_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* do we need to re-start the PLL ? */
- if (wm9713->pll_in)
- wm9713_set_pll(codec, 0, wm9713->pll_in, 0);
-
- /* only synchronise the codec if warm reset failed */
- if (ret == 0) {
- for (i = 2; i < ARRAY_SIZE(wm9713_reg) << 1; i += 2) {
- if (i == AC97_POWERDOWN || i == AC97_EXTENDED_MID ||
- i == AC97_EXTENDED_MSTATUS || i > 0x66)
- continue;
- soc_ac97_ops.write(codec->ac97, i, cache[i>>1]);
- }
- }
-
- return ret;
-}
-
-static int wm9713_soc_probe(struct snd_soc_codec *codec)
-{
- struct wm9713_priv *wm9713;
- int ret = 0, reg;
-
- wm9713 = kzalloc(sizeof(struct wm9713_priv), GFP_KERNEL);
- if (wm9713 == NULL)
- return -ENOMEM;
- snd_soc_codec_set_drvdata(codec, wm9713);
-
- ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
- if (ret < 0)
- goto codec_err;
-
- /* do a cold reset for the controller and then try
- * a warm reset followed by an optional cold reset for codec */
- wm9713_reset(codec, 0);
- ret = wm9713_reset(codec, 1);
- if (ret < 0) {
- printk(KERN_ERR "Failed to reset WM9713: AC97 link error\n");
- goto reset_err;
- }
-
- wm9713_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* unmute the adc - move to kcontrol */
- reg = ac97_read(codec, AC97_CD) & 0x7fff;
- ac97_write(codec, AC97_CD, reg);
-
- snd_soc_add_codec_controls(codec, wm9713_snd_ac97_controls,
- ARRAY_SIZE(wm9713_snd_ac97_controls));
-
- return 0;
-
-reset_err:
- snd_soc_free_ac97_codec(codec);
-codec_err:
- kfree(wm9713);
- return ret;
-}
-
-static int wm9713_soc_remove(struct snd_soc_codec *codec)
-{
- struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
- snd_soc_free_ac97_codec(codec);
- kfree(wm9713);
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_wm9713 = {
- .probe = wm9713_soc_probe,
- .remove = wm9713_soc_remove,
- .suspend = wm9713_soc_suspend,
- .resume = wm9713_soc_resume,
- .read = ac97_read,
- .write = ac97_write,
- .set_bias_level = wm9713_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm9713_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_step = 2,
- .reg_cache_default = wm9713_reg,
- .dapm_widgets = wm9713_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm9713_dapm_widgets),
- .dapm_routes = wm9713_audio_map,
- .num_dapm_routes = ARRAY_SIZE(wm9713_audio_map),
-};
-
-static __devinit int wm9713_probe(struct platform_device *pdev)
-{
- return snd_soc_register_codec(&pdev->dev,
- &soc_codec_dev_wm9713, wm9713_dai, ARRAY_SIZE(wm9713_dai));
-}
-
-static int __devexit wm9713_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver wm9713_codec_driver = {
- .driver = {
- .name = "wm9713-codec",
- .owner = THIS_MODULE,
- },
-
- .probe = wm9713_probe,
- .remove = __devexit_p(wm9713_remove),
-};
-
-module_platform_driver(wm9713_codec_driver);
-
-MODULE_DESCRIPTION("ASoC WM9713/WM9714 driver");
-MODULE_AUTHOR("Liam Girdwood");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm9713.h b/ANDROID_3.4.5/sound/soc/codecs/wm9713.h
deleted file mode 100644
index 793da863..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm9713.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * wm9713.h -- WM9713 Soc Audio driver
- */
-
-#ifndef _WM9713_H
-#define _WM9713_H
-
-/* clock inputs */
-#define WM9713_CLKA_PIN 0
-#define WM9713_CLKB_PIN 1
-
-/* clock divider ID's */
-#define WM9713_PCMCLK_DIV 0
-#define WM9713_CLKA_MULT 1
-#define WM9713_CLKB_MULT 2
-#define WM9713_HIFI_DIV 3
-#define WM9713_PCMBCLK_DIV 4
-#define WM9713_PCMCLK_PLL_DIV 5
-#define WM9713_HIFI_PLL_DIV 6
-
-/* Calculate the appropriate bit mask for the external PCM clock divider */
-#define WM9713_PCMDIV(x) ((x - 1) << 8)
-
-/* Calculate the appropriate bit mask for the external HiFi clock divider */
-#define WM9713_HIFIDIV(x) ((x - 1) << 12)
-
-/* MCLK clock mulitipliers */
-#define WM9713_CLKA_X1 (0 << 1)
-#define WM9713_CLKA_X2 (1 << 1)
-#define WM9713_CLKB_X1 (0 << 2)
-#define WM9713_CLKB_X2 (1 << 2)
-
-/* MCLK clock MUX */
-#define WM9713_CLK_MUX_A (0 << 0)
-#define WM9713_CLK_MUX_B (1 << 0)
-
-/* Voice DAI BCLK divider */
-#define WM9713_PCMBCLK_DIV_1 (0 << 9)
-#define WM9713_PCMBCLK_DIV_2 (1 << 9)
-#define WM9713_PCMBCLK_DIV_4 (2 << 9)
-#define WM9713_PCMBCLK_DIV_8 (3 << 9)
-#define WM9713_PCMBCLK_DIV_16 (4 << 9)
-
-#define WM9713_DAI_AC97_HIFI 0
-#define WM9713_DAI_AC97_AUX 1
-#define WM9713_DAI_PCM_VOICE 2
-
-int wm9713_reset(struct snd_soc_codec *codec, int try_warm);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm_hubs.c b/ANDROID_3.4.5/sound/soc/codecs/wm_hubs.c
deleted file mode 100644
index 6c028c47..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm_hubs.c
+++ /dev/null
@@ -1,1086 +0,0 @@
-/*
- * wm_hubs.c -- WM8993/4 common code
- *
- * Copyright 2009 Wolfson Microelectronics plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/mfd/wm8994/registers.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "wm8993.h"
-#include "wm_hubs.h"
-
-const DECLARE_TLV_DB_SCALE(wm_hubs_spkmix_tlv, -300, 300, 0);
-EXPORT_SYMBOL_GPL(wm_hubs_spkmix_tlv);
-
-static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1650, 150, 0);
-static const DECLARE_TLV_DB_SCALE(inmix_sw_tlv, 0, 3000, 0);
-static const DECLARE_TLV_DB_SCALE(inmix_tlv, -1500, 300, 1);
-static const DECLARE_TLV_DB_SCALE(earpiece_tlv, -600, 600, 0);
-static const DECLARE_TLV_DB_SCALE(outmix_tlv, -2100, 300, 0);
-static const DECLARE_TLV_DB_SCALE(spkmixout_tlv, -1800, 600, 1);
-static const DECLARE_TLV_DB_SCALE(outpga_tlv, -5700, 100, 0);
-static const unsigned int spkboost_tlv[] = {
- TLV_DB_RANGE_HEAD(2),
- 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0),
- 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0),
-};
-static const DECLARE_TLV_DB_SCALE(line_tlv, -600, 600, 0);
-
-static const char *speaker_ref_text[] = {
- "SPKVDD/2",
- "VMID",
-};
-
-static const struct soc_enum speaker_ref =
- SOC_ENUM_SINGLE(WM8993_SPEAKER_MIXER, 8, 2, speaker_ref_text);
-
-static const char *speaker_mode_text[] = {
- "Class D",
- "Class AB",
-};
-
-static const struct soc_enum speaker_mode =
- SOC_ENUM_SINGLE(WM8993_SPKMIXR_ATTENUATION, 8, 2, speaker_mode_text);
-
-static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
-{
- struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
- unsigned int reg;
- int count = 0;
- int timeout;
- unsigned int val;
-
- val = op | WM8993_DCS_ENA_CHAN_0 | WM8993_DCS_ENA_CHAN_1;
-
- /* Trigger the command */
- snd_soc_write(codec, WM8993_DC_SERVO_0, val);
-
- dev_dbg(codec->dev, "Waiting for DC servo...\n");
-
- if (hubs->dcs_done_irq)
- timeout = 4;
- else
- timeout = 400;
-
- do {
- count++;
-
- if (hubs->dcs_done_irq)
- wait_for_completion_timeout(&hubs->dcs_done,
- msecs_to_jiffies(250));
- else
- msleep(1);
-
- reg = snd_soc_read(codec, WM8993_DC_SERVO_0);
- dev_dbg(codec->dev, "DC servo: %x\n", reg);
- } while (reg & op && count < timeout);
-
- if (reg & op)
- dev_err(codec->dev, "Timed out waiting for DC Servo %x\n",
- op);
-}
-
-irqreturn_t wm_hubs_dcs_done(int irq, void *data)
-{
- struct wm_hubs_data *hubs = data;
-
- complete(&hubs->dcs_done);
-
- return IRQ_HANDLED;
-}
-EXPORT_SYMBOL_GPL(wm_hubs_dcs_done);
-
-/*
- * Startup calibration of the DC servo
- */
-static void calibrate_dc_servo(struct snd_soc_codec *codec)
-{
- struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
- s8 offset;
- u16 reg, reg_l, reg_r, dcs_cfg, dcs_reg;
-
- switch (hubs->dcs_readback_mode) {
- case 2:
- dcs_reg = WM8994_DC_SERVO_4E;
- break;
- default:
- dcs_reg = WM8993_DC_SERVO_3;
- break;
- }
-
- /* If we're using a digital only path and have a previously
- * callibrated DC servo offset stored then use that. */
- if (hubs->class_w && hubs->class_w_dcs) {
- dev_dbg(codec->dev, "Using cached DC servo offset %x\n",
- hubs->class_w_dcs);
- snd_soc_write(codec, dcs_reg, hubs->class_w_dcs);
- wait_for_dc_servo(codec,
- WM8993_DCS_TRIG_DAC_WR_0 |
- WM8993_DCS_TRIG_DAC_WR_1);
- return;
- }
-
- if (hubs->series_startup) {
- /* Set for 32 series updates */
- snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
- WM8993_DCS_SERIES_NO_01_MASK,
- 32 << WM8993_DCS_SERIES_NO_01_SHIFT);
- wait_for_dc_servo(codec,
- WM8993_DCS_TRIG_SERIES_0 |
- WM8993_DCS_TRIG_SERIES_1);
- } else {
- wait_for_dc_servo(codec,
- WM8993_DCS_TRIG_STARTUP_0 |
- WM8993_DCS_TRIG_STARTUP_1);
- }
-
- /* Different chips in the family support different readback
- * methods.
- */
- switch (hubs->dcs_readback_mode) {
- case 0:
- reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
- & WM8993_DCS_INTEG_CHAN_0_MASK;
- reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
- & WM8993_DCS_INTEG_CHAN_1_MASK;
- break;
- case 2:
- case 1:
- reg = snd_soc_read(codec, dcs_reg);
- reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
- >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
- reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
- break;
- default:
- WARN(1, "Unknown DCS readback method\n");
- return;
- }
-
- dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
-
- /* Apply correction to DC servo result */
- if (hubs->dcs_codes_l || hubs->dcs_codes_r) {
- dev_dbg(codec->dev,
- "Applying %d/%d code DC servo correction\n",
- hubs->dcs_codes_l, hubs->dcs_codes_r);
-
- /* HPOUT1R */
- offset = reg_r;
- offset += hubs->dcs_codes_r;
- dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
-
- /* HPOUT1L */
- offset = reg_l;
- offset += hubs->dcs_codes_l;
- dcs_cfg |= (u8)offset;
-
- dev_dbg(codec->dev, "DCS result: %x\n", dcs_cfg);
-
- /* Do it */
- snd_soc_write(codec, dcs_reg, dcs_cfg);
- wait_for_dc_servo(codec,
- WM8993_DCS_TRIG_DAC_WR_0 |
- WM8993_DCS_TRIG_DAC_WR_1);
- } else {
- dcs_cfg = reg_r << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
- dcs_cfg |= reg_l;
- }
-
- /* Save the callibrated offset if we're in class W mode and
- * therefore don't have any analogue signal mixed in. */
- if (hubs->class_w && !hubs->no_cache_class_w)
- hubs->class_w_dcs = dcs_cfg;
-}
-
-/*
- * Update the DC servo calibration on gain changes
- */
-static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- ret = snd_soc_put_volsw(kcontrol, ucontrol);
-
- /* Updating the analogue gains invalidates the DC servo cache */
- hubs->class_w_dcs = 0;
-
- /* If we're applying an offset correction then updating the
- * callibration would be likely to introduce further offsets. */
- if (hubs->dcs_codes_l || hubs->dcs_codes_r || hubs->no_series_update)
- return ret;
-
- /* Only need to do this if the outputs are active */
- if (snd_soc_read(codec, WM8993_POWER_MANAGEMENT_1)
- & (WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA))
- snd_soc_update_bits(codec,
- WM8993_DC_SERVO_0,
- WM8993_DCS_TRIG_SINGLE_0 |
- WM8993_DCS_TRIG_SINGLE_1,
- WM8993_DCS_TRIG_SINGLE_0 |
- WM8993_DCS_TRIG_SINGLE_1);
-
- return ret;
-}
-
-static const struct snd_kcontrol_new analogue_snd_controls[] = {
-SOC_SINGLE_TLV("IN1L Volume", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 0, 31, 0,
- inpga_tlv),
-SOC_SINGLE("IN1L Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 7, 1, 1),
-SOC_SINGLE("IN1L ZC Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 6, 1, 0),
-
-SOC_SINGLE_TLV("IN1R Volume", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 0, 31, 0,
- inpga_tlv),
-SOC_SINGLE("IN1R Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 7, 1, 1),
-SOC_SINGLE("IN1R ZC Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 6, 1, 0),
-
-
-SOC_SINGLE_TLV("IN2L Volume", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 0, 31, 0,
- inpga_tlv),
-SOC_SINGLE("IN2L Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 7, 1, 1),
-SOC_SINGLE("IN2L ZC Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 6, 1, 0),
-
-SOC_SINGLE_TLV("IN2R Volume", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 0, 31, 0,
- inpga_tlv),
-SOC_SINGLE("IN2R Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 7, 1, 1),
-SOC_SINGLE("IN2R ZC Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 6, 1, 0),
-
-SOC_SINGLE_TLV("MIXINL IN2L Volume", WM8993_INPUT_MIXER3, 7, 1, 0,
- inmix_sw_tlv),
-SOC_SINGLE_TLV("MIXINL IN1L Volume", WM8993_INPUT_MIXER3, 4, 1, 0,
- inmix_sw_tlv),
-SOC_SINGLE_TLV("MIXINL Output Record Volume", WM8993_INPUT_MIXER3, 0, 7, 0,
- inmix_tlv),
-SOC_SINGLE_TLV("MIXINL IN1LP Volume", WM8993_INPUT_MIXER5, 6, 7, 0, inmix_tlv),
-SOC_SINGLE_TLV("MIXINL Direct Voice Volume", WM8993_INPUT_MIXER5, 0, 6, 0,
- inmix_tlv),
-
-SOC_SINGLE_TLV("MIXINR IN2R Volume", WM8993_INPUT_MIXER4, 7, 1, 0,
- inmix_sw_tlv),
-SOC_SINGLE_TLV("MIXINR IN1R Volume", WM8993_INPUT_MIXER4, 4, 1, 0,
- inmix_sw_tlv),
-SOC_SINGLE_TLV("MIXINR Output Record Volume", WM8993_INPUT_MIXER4, 0, 7, 0,
- inmix_tlv),
-SOC_SINGLE_TLV("MIXINR IN1RP Volume", WM8993_INPUT_MIXER6, 6, 7, 0, inmix_tlv),
-SOC_SINGLE_TLV("MIXINR Direct Voice Volume", WM8993_INPUT_MIXER6, 0, 6, 0,
- inmix_tlv),
-
-SOC_SINGLE_TLV("Left Output Mixer IN2RN Volume", WM8993_OUTPUT_MIXER5, 6, 7, 1,
- outmix_tlv),
-SOC_SINGLE_TLV("Left Output Mixer IN2LN Volume", WM8993_OUTPUT_MIXER3, 6, 7, 1,
- outmix_tlv),
-SOC_SINGLE_TLV("Left Output Mixer IN2LP Volume", WM8993_OUTPUT_MIXER3, 9, 7, 1,
- outmix_tlv),
-SOC_SINGLE_TLV("Left Output Mixer IN1L Volume", WM8993_OUTPUT_MIXER3, 0, 7, 1,
- outmix_tlv),
-SOC_SINGLE_TLV("Left Output Mixer IN1R Volume", WM8993_OUTPUT_MIXER3, 3, 7, 1,
- outmix_tlv),
-SOC_SINGLE_TLV("Left Output Mixer Right Input Volume",
- WM8993_OUTPUT_MIXER5, 3, 7, 1, outmix_tlv),
-SOC_SINGLE_TLV("Left Output Mixer Left Input Volume",
- WM8993_OUTPUT_MIXER5, 0, 7, 1, outmix_tlv),
-SOC_SINGLE_TLV("Left Output Mixer DAC Volume", WM8993_OUTPUT_MIXER5, 9, 7, 1,
- outmix_tlv),
-
-SOC_SINGLE_TLV("Right Output Mixer IN2LN Volume",
- WM8993_OUTPUT_MIXER6, 6, 7, 1, outmix_tlv),
-SOC_SINGLE_TLV("Right Output Mixer IN2RN Volume",
- WM8993_OUTPUT_MIXER4, 6, 7, 1, outmix_tlv),
-SOC_SINGLE_TLV("Right Output Mixer IN1L Volume",
- WM8993_OUTPUT_MIXER4, 3, 7, 1, outmix_tlv),
-SOC_SINGLE_TLV("Right Output Mixer IN1R Volume",
- WM8993_OUTPUT_MIXER4, 0, 7, 1, outmix_tlv),
-SOC_SINGLE_TLV("Right Output Mixer IN2RP Volume",
- WM8993_OUTPUT_MIXER4, 9, 7, 1, outmix_tlv),
-SOC_SINGLE_TLV("Right Output Mixer Left Input Volume",
- WM8993_OUTPUT_MIXER6, 3, 7, 1, outmix_tlv),
-SOC_SINGLE_TLV("Right Output Mixer Right Input Volume",
- WM8993_OUTPUT_MIXER6, 6, 7, 1, outmix_tlv),
-SOC_SINGLE_TLV("Right Output Mixer DAC Volume",
- WM8993_OUTPUT_MIXER6, 9, 7, 1, outmix_tlv),
-
-SOC_DOUBLE_R_TLV("Output Volume", WM8993_LEFT_OPGA_VOLUME,
- WM8993_RIGHT_OPGA_VOLUME, 0, 63, 0, outpga_tlv),
-SOC_DOUBLE_R("Output Switch", WM8993_LEFT_OPGA_VOLUME,
- WM8993_RIGHT_OPGA_VOLUME, 6, 1, 0),
-SOC_DOUBLE_R("Output ZC Switch", WM8993_LEFT_OPGA_VOLUME,
- WM8993_RIGHT_OPGA_VOLUME, 7, 1, 0),
-
-SOC_SINGLE("Earpiece Switch", WM8993_HPOUT2_VOLUME, 5, 1, 1),
-SOC_SINGLE_TLV("Earpiece Volume", WM8993_HPOUT2_VOLUME, 4, 1, 1, earpiece_tlv),
-
-SOC_SINGLE_TLV("SPKL Input Volume", WM8993_SPKMIXL_ATTENUATION,
- 5, 1, 1, wm_hubs_spkmix_tlv),
-SOC_SINGLE_TLV("SPKL IN1LP Volume", WM8993_SPKMIXL_ATTENUATION,
- 4, 1, 1, wm_hubs_spkmix_tlv),
-SOC_SINGLE_TLV("SPKL Output Volume", WM8993_SPKMIXL_ATTENUATION,
- 3, 1, 1, wm_hubs_spkmix_tlv),
-
-SOC_SINGLE_TLV("SPKR Input Volume", WM8993_SPKMIXR_ATTENUATION,
- 5, 1, 1, wm_hubs_spkmix_tlv),
-SOC_SINGLE_TLV("SPKR IN1RP Volume", WM8993_SPKMIXR_ATTENUATION,
- 4, 1, 1, wm_hubs_spkmix_tlv),
-SOC_SINGLE_TLV("SPKR Output Volume", WM8993_SPKMIXR_ATTENUATION,
- 3, 1, 1, wm_hubs_spkmix_tlv),
-
-SOC_DOUBLE_R_TLV("Speaker Mixer Volume",
- WM8993_SPKMIXL_ATTENUATION, WM8993_SPKMIXR_ATTENUATION,
- 0, 3, 1, spkmixout_tlv),
-SOC_DOUBLE_R_TLV("Speaker Volume",
- WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT,
- 0, 63, 0, outpga_tlv),
-SOC_DOUBLE_R("Speaker Switch",
- WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT,
- 6, 1, 0),
-SOC_DOUBLE_R("Speaker ZC Switch",
- WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT,
- 7, 1, 0),
-SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 3, 0, 7, 0,
- spkboost_tlv),
-SOC_ENUM("Speaker Reference", speaker_ref),
-SOC_ENUM("Speaker Mode", speaker_mode),
-
-SOC_DOUBLE_R_EXT_TLV("Headphone Volume",
- WM8993_LEFT_OUTPUT_VOLUME, WM8993_RIGHT_OUTPUT_VOLUME,
- 0, 63, 0, snd_soc_get_volsw, wm8993_put_dc_servo,
- outpga_tlv),
-
-SOC_DOUBLE_R("Headphone Switch", WM8993_LEFT_OUTPUT_VOLUME,
- WM8993_RIGHT_OUTPUT_VOLUME, 6, 1, 0),
-SOC_DOUBLE_R("Headphone ZC Switch", WM8993_LEFT_OUTPUT_VOLUME,
- WM8993_RIGHT_OUTPUT_VOLUME, 7, 1, 0),
-
-SOC_SINGLE("LINEOUT1N Switch", WM8993_LINE_OUTPUTS_VOLUME, 6, 1, 1),
-SOC_SINGLE("LINEOUT1P Switch", WM8993_LINE_OUTPUTS_VOLUME, 5, 1, 1),
-SOC_SINGLE_TLV("LINEOUT1 Volume", WM8993_LINE_OUTPUTS_VOLUME, 4, 1, 1,
- line_tlv),
-
-SOC_SINGLE("LINEOUT2N Switch", WM8993_LINE_OUTPUTS_VOLUME, 2, 1, 1),
-SOC_SINGLE("LINEOUT2P Switch", WM8993_LINE_OUTPUTS_VOLUME, 1, 1, 1),
-SOC_SINGLE_TLV("LINEOUT2 Volume", WM8993_LINE_OUTPUTS_VOLUME, 0, 1, 1,
- line_tlv),
-};
-
-static int hp_supply_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- switch (hubs->hp_startup_mode) {
- case 0:
- break;
- case 1:
- /* Enable the headphone amp */
- snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
- WM8993_HPOUT1L_ENA |
- WM8993_HPOUT1R_ENA,
- WM8993_HPOUT1L_ENA |
- WM8993_HPOUT1R_ENA);
-
- /* Enable the second stage */
- snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
- WM8993_HPOUT1L_DLY |
- WM8993_HPOUT1R_DLY,
- WM8993_HPOUT1L_DLY |
- WM8993_HPOUT1R_DLY);
- break;
- default:
- dev_err(codec->dev, "Unknown HP startup mode %d\n",
- hubs->hp_startup_mode);
- break;
- }
-
- case SND_SOC_DAPM_PRE_PMD:
- snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1,
- WM8993_CP_ENA, 0);
- break;
- }
-
- return 0;
-}
-
-static int hp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- unsigned int reg = snd_soc_read(codec, WM8993_ANALOGUE_HP_0);
-
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1,
- WM8993_CP_ENA, WM8993_CP_ENA);
-
- msleep(5);
-
- snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
- WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA,
- WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA);
-
- reg |= WM8993_HPOUT1L_DLY | WM8993_HPOUT1R_DLY;
- snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
-
- snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
- WM8993_DCS_TIMER_PERIOD_01_MASK, 0);
-
- calibrate_dc_servo(codec);
-
- reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT |
- WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT;
- snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
- break;
-
- case SND_SOC_DAPM_PRE_PMD:
- snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
- WM8993_HPOUT1L_OUTP |
- WM8993_HPOUT1R_OUTP |
- WM8993_HPOUT1L_RMV_SHORT |
- WM8993_HPOUT1R_RMV_SHORT, 0);
-
- snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
- WM8993_HPOUT1L_DLY |
- WM8993_HPOUT1R_DLY, 0);
-
- snd_soc_write(codec, WM8993_DC_SERVO_0, 0);
-
- snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
- WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA,
- 0);
- break;
- }
-
- return 0;
-}
-
-static int earpiece_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *control, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- u16 reg = snd_soc_read(codec, WM8993_ANTIPOP1) & ~WM8993_HPOUT2_IN_ENA;
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- reg |= WM8993_HPOUT2_IN_ENA;
- snd_soc_write(codec, WM8993_ANTIPOP1, reg);
- udelay(50);
- break;
-
- case SND_SOC_DAPM_POST_PMD:
- snd_soc_write(codec, WM8993_ANTIPOP1, reg);
- break;
-
- default:
- BUG();
- break;
- }
-
- return 0;
-}
-
-static int lineout_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *control, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
- bool *flag;
-
- switch (w->shift) {
- case WM8993_LINEOUT1N_ENA_SHIFT:
- flag = &hubs->lineout1n_ena;
- break;
- case WM8993_LINEOUT1P_ENA_SHIFT:
- flag = &hubs->lineout1p_ena;
- break;
- case WM8993_LINEOUT2N_ENA_SHIFT:
- flag = &hubs->lineout2n_ena;
- break;
- case WM8993_LINEOUT2P_ENA_SHIFT:
- flag = &hubs->lineout2p_ena;
- break;
- default:
- WARN(1, "Unknown line output");
- return -EINVAL;
- }
-
- *flag = SND_SOC_DAPM_EVENT_ON(event);
-
- return 0;
-}
-
-static const struct snd_kcontrol_new in1l_pga[] = {
-SOC_DAPM_SINGLE("IN1LP Switch", WM8993_INPUT_MIXER2, 5, 1, 0),
-SOC_DAPM_SINGLE("IN1LN Switch", WM8993_INPUT_MIXER2, 4, 1, 0),
-};
-
-static const struct snd_kcontrol_new in1r_pga[] = {
-SOC_DAPM_SINGLE("IN1RP Switch", WM8993_INPUT_MIXER2, 1, 1, 0),
-SOC_DAPM_SINGLE("IN1RN Switch", WM8993_INPUT_MIXER2, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new in2l_pga[] = {
-SOC_DAPM_SINGLE("IN2LP Switch", WM8993_INPUT_MIXER2, 7, 1, 0),
-SOC_DAPM_SINGLE("IN2LN Switch", WM8993_INPUT_MIXER2, 6, 1, 0),
-};
-
-static const struct snd_kcontrol_new in2r_pga[] = {
-SOC_DAPM_SINGLE("IN2RP Switch", WM8993_INPUT_MIXER2, 3, 1, 0),
-SOC_DAPM_SINGLE("IN2RN Switch", WM8993_INPUT_MIXER2, 2, 1, 0),
-};
-
-static const struct snd_kcontrol_new mixinl[] = {
-SOC_DAPM_SINGLE("IN2L Switch", WM8993_INPUT_MIXER3, 8, 1, 0),
-SOC_DAPM_SINGLE("IN1L Switch", WM8993_INPUT_MIXER3, 5, 1, 0),
-};
-
-static const struct snd_kcontrol_new mixinr[] = {
-SOC_DAPM_SINGLE("IN2R Switch", WM8993_INPUT_MIXER4, 8, 1, 0),
-SOC_DAPM_SINGLE("IN1R Switch", WM8993_INPUT_MIXER4, 5, 1, 0),
-};
-
-static const struct snd_kcontrol_new left_output_mixer[] = {
-SOC_DAPM_SINGLE("Right Input Switch", WM8993_OUTPUT_MIXER1, 7, 1, 0),
-SOC_DAPM_SINGLE("Left Input Switch", WM8993_OUTPUT_MIXER1, 6, 1, 0),
-SOC_DAPM_SINGLE("IN2RN Switch", WM8993_OUTPUT_MIXER1, 5, 1, 0),
-SOC_DAPM_SINGLE("IN2LN Switch", WM8993_OUTPUT_MIXER1, 4, 1, 0),
-SOC_DAPM_SINGLE("IN2LP Switch", WM8993_OUTPUT_MIXER1, 1, 1, 0),
-SOC_DAPM_SINGLE("IN1R Switch", WM8993_OUTPUT_MIXER1, 3, 1, 0),
-SOC_DAPM_SINGLE("IN1L Switch", WM8993_OUTPUT_MIXER1, 2, 1, 0),
-SOC_DAPM_SINGLE("DAC Switch", WM8993_OUTPUT_MIXER1, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new right_output_mixer[] = {
-SOC_DAPM_SINGLE("Left Input Switch", WM8993_OUTPUT_MIXER2, 7, 1, 0),
-SOC_DAPM_SINGLE("Right Input Switch", WM8993_OUTPUT_MIXER2, 6, 1, 0),
-SOC_DAPM_SINGLE("IN2LN Switch", WM8993_OUTPUT_MIXER2, 5, 1, 0),
-SOC_DAPM_SINGLE("IN2RN Switch", WM8993_OUTPUT_MIXER2, 4, 1, 0),
-SOC_DAPM_SINGLE("IN1L Switch", WM8993_OUTPUT_MIXER2, 3, 1, 0),
-SOC_DAPM_SINGLE("IN1R Switch", WM8993_OUTPUT_MIXER2, 2, 1, 0),
-SOC_DAPM_SINGLE("IN2RP Switch", WM8993_OUTPUT_MIXER2, 1, 1, 0),
-SOC_DAPM_SINGLE("DAC Switch", WM8993_OUTPUT_MIXER2, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new earpiece_mixer[] = {
-SOC_DAPM_SINGLE("Direct Voice Switch", WM8993_HPOUT2_MIXER, 5, 1, 0),
-SOC_DAPM_SINGLE("Left Output Switch", WM8993_HPOUT2_MIXER, 4, 1, 0),
-SOC_DAPM_SINGLE("Right Output Switch", WM8993_HPOUT2_MIXER, 3, 1, 0),
-};
-
-static const struct snd_kcontrol_new left_speaker_boost[] = {
-SOC_DAPM_SINGLE("Direct Voice Switch", WM8993_SPKOUT_MIXERS, 5, 1, 0),
-SOC_DAPM_SINGLE("SPKL Switch", WM8993_SPKOUT_MIXERS, 4, 1, 0),
-SOC_DAPM_SINGLE("SPKR Switch", WM8993_SPKOUT_MIXERS, 3, 1, 0),
-};
-
-static const struct snd_kcontrol_new right_speaker_boost[] = {
-SOC_DAPM_SINGLE("Direct Voice Switch", WM8993_SPKOUT_MIXERS, 2, 1, 0),
-SOC_DAPM_SINGLE("SPKL Switch", WM8993_SPKOUT_MIXERS, 1, 1, 0),
-SOC_DAPM_SINGLE("SPKR Switch", WM8993_SPKOUT_MIXERS, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new line1_mix[] = {
-SOC_DAPM_SINGLE("IN1R Switch", WM8993_LINE_MIXER1, 2, 1, 0),
-SOC_DAPM_SINGLE("IN1L Switch", WM8993_LINE_MIXER1, 1, 1, 0),
-SOC_DAPM_SINGLE("Output Switch", WM8993_LINE_MIXER1, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new line1n_mix[] = {
-SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER1, 6, 1, 0),
-SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER1, 5, 1, 0),
-};
-
-static const struct snd_kcontrol_new line1p_mix[] = {
-SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER1, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new line2_mix[] = {
-SOC_DAPM_SINGLE("IN1L Switch", WM8993_LINE_MIXER2, 2, 1, 0),
-SOC_DAPM_SINGLE("IN1R Switch", WM8993_LINE_MIXER2, 1, 1, 0),
-SOC_DAPM_SINGLE("Output Switch", WM8993_LINE_MIXER2, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new line2n_mix[] = {
-SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER2, 5, 1, 0),
-SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER2, 6, 1, 0),
-};
-
-static const struct snd_kcontrol_new line2p_mix[] = {
-SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER2, 0, 1, 0),
-};
-
-static const struct snd_soc_dapm_widget analogue_dapm_widgets[] = {
-SND_SOC_DAPM_INPUT("IN1LN"),
-SND_SOC_DAPM_INPUT("IN1LP"),
-SND_SOC_DAPM_INPUT("IN2LN"),
-SND_SOC_DAPM_INPUT("IN2LP:VXRN"),
-SND_SOC_DAPM_INPUT("IN1RN"),
-SND_SOC_DAPM_INPUT("IN1RP"),
-SND_SOC_DAPM_INPUT("IN2RN"),
-SND_SOC_DAPM_INPUT("IN2RP:VXRP"),
-
-SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0, NULL, 0),
-
-SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0,
- in1l_pga, ARRAY_SIZE(in1l_pga)),
-SND_SOC_DAPM_MIXER("IN1R PGA", WM8993_POWER_MANAGEMENT_2, 4, 0,
- in1r_pga, ARRAY_SIZE(in1r_pga)),
-
-SND_SOC_DAPM_MIXER("IN2L PGA", WM8993_POWER_MANAGEMENT_2, 7, 0,
- in2l_pga, ARRAY_SIZE(in2l_pga)),
-SND_SOC_DAPM_MIXER("IN2R PGA", WM8993_POWER_MANAGEMENT_2, 5, 0,
- in2r_pga, ARRAY_SIZE(in2r_pga)),
-
-SND_SOC_DAPM_MIXER("MIXINL", WM8993_POWER_MANAGEMENT_2, 9, 0,
- mixinl, ARRAY_SIZE(mixinl)),
-SND_SOC_DAPM_MIXER("MIXINR", WM8993_POWER_MANAGEMENT_2, 8, 0,
- mixinr, ARRAY_SIZE(mixinr)),
-
-SND_SOC_DAPM_MIXER("Left Output Mixer", WM8993_POWER_MANAGEMENT_3, 5, 0,
- left_output_mixer, ARRAY_SIZE(left_output_mixer)),
-SND_SOC_DAPM_MIXER("Right Output Mixer", WM8993_POWER_MANAGEMENT_3, 4, 0,
- right_output_mixer, ARRAY_SIZE(right_output_mixer)),
-
-SND_SOC_DAPM_PGA("Left Output PGA", WM8993_POWER_MANAGEMENT_3, 7, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right Output PGA", WM8993_POWER_MANAGEMENT_3, 6, 0, NULL, 0),
-
-SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0, hp_supply_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
-SND_SOC_DAPM_OUT_DRV_E("Headphone PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
- hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-
-SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
- earpiece_mixer, ARRAY_SIZE(earpiece_mixer)),
-SND_SOC_DAPM_PGA_E("Earpiece Driver", WM8993_POWER_MANAGEMENT_1, 11, 0,
- NULL, 0, earpiece_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
-SND_SOC_DAPM_MIXER("SPKL Boost", SND_SOC_NOPM, 0, 0,
- left_speaker_boost, ARRAY_SIZE(left_speaker_boost)),
-SND_SOC_DAPM_MIXER("SPKR Boost", SND_SOC_NOPM, 0, 0,
- right_speaker_boost, ARRAY_SIZE(right_speaker_boost)),
-
-SND_SOC_DAPM_SUPPLY("TSHUT", WM8993_POWER_MANAGEMENT_2, 14, 0, NULL, 0),
-SND_SOC_DAPM_OUT_DRV("SPKL Driver", WM8993_POWER_MANAGEMENT_1, 12, 0,
- NULL, 0),
-SND_SOC_DAPM_OUT_DRV("SPKR Driver", WM8993_POWER_MANAGEMENT_1, 13, 0,
- NULL, 0),
-
-SND_SOC_DAPM_MIXER("LINEOUT1 Mixer", SND_SOC_NOPM, 0, 0,
- line1_mix, ARRAY_SIZE(line1_mix)),
-SND_SOC_DAPM_MIXER("LINEOUT2 Mixer", SND_SOC_NOPM, 0, 0,
- line2_mix, ARRAY_SIZE(line2_mix)),
-
-SND_SOC_DAPM_MIXER("LINEOUT1N Mixer", SND_SOC_NOPM, 0, 0,
- line1n_mix, ARRAY_SIZE(line1n_mix)),
-SND_SOC_DAPM_MIXER("LINEOUT1P Mixer", SND_SOC_NOPM, 0, 0,
- line1p_mix, ARRAY_SIZE(line1p_mix)),
-SND_SOC_DAPM_MIXER("LINEOUT2N Mixer", SND_SOC_NOPM, 0, 0,
- line2n_mix, ARRAY_SIZE(line2n_mix)),
-SND_SOC_DAPM_MIXER("LINEOUT2P Mixer", SND_SOC_NOPM, 0, 0,
- line2p_mix, ARRAY_SIZE(line2p_mix)),
-
-SND_SOC_DAPM_OUT_DRV_E("LINEOUT1N Driver", WM8993_POWER_MANAGEMENT_3, 13, 0,
- NULL, 0, lineout_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-SND_SOC_DAPM_OUT_DRV_E("LINEOUT1P Driver", WM8993_POWER_MANAGEMENT_3, 12, 0,
- NULL, 0, lineout_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-SND_SOC_DAPM_OUT_DRV_E("LINEOUT2N Driver", WM8993_POWER_MANAGEMENT_3, 11, 0,
- NULL, 0, lineout_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-SND_SOC_DAPM_OUT_DRV_E("LINEOUT2P Driver", WM8993_POWER_MANAGEMENT_3, 10, 0,
- NULL, 0, lineout_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-
-SND_SOC_DAPM_OUTPUT("SPKOUTLP"),
-SND_SOC_DAPM_OUTPUT("SPKOUTLN"),
-SND_SOC_DAPM_OUTPUT("SPKOUTRP"),
-SND_SOC_DAPM_OUTPUT("SPKOUTRN"),
-SND_SOC_DAPM_OUTPUT("HPOUT1L"),
-SND_SOC_DAPM_OUTPUT("HPOUT1R"),
-SND_SOC_DAPM_OUTPUT("HPOUT2P"),
-SND_SOC_DAPM_OUTPUT("HPOUT2N"),
-SND_SOC_DAPM_OUTPUT("LINEOUT1P"),
-SND_SOC_DAPM_OUTPUT("LINEOUT1N"),
-SND_SOC_DAPM_OUTPUT("LINEOUT2P"),
-SND_SOC_DAPM_OUTPUT("LINEOUT2N"),
-};
-
-static const struct snd_soc_dapm_route analogue_routes[] = {
- { "MICBIAS1", NULL, "CLK_SYS" },
- { "MICBIAS2", NULL, "CLK_SYS" },
-
- { "IN1L PGA", "IN1LP Switch", "IN1LP" },
- { "IN1L PGA", "IN1LN Switch", "IN1LN" },
-
- { "IN1L PGA", NULL, "VMID" },
- { "IN1R PGA", NULL, "VMID" },
- { "IN2L PGA", NULL, "VMID" },
- { "IN2R PGA", NULL, "VMID" },
-
- { "IN1R PGA", "IN1RP Switch", "IN1RP" },
- { "IN1R PGA", "IN1RN Switch", "IN1RN" },
-
- { "IN2L PGA", "IN2LP Switch", "IN2LP:VXRN" },
- { "IN2L PGA", "IN2LN Switch", "IN2LN" },
-
- { "IN2R PGA", "IN2RP Switch", "IN2RP:VXRP" },
- { "IN2R PGA", "IN2RN Switch", "IN2RN" },
-
- { "Direct Voice", NULL, "IN2LP:VXRN" },
- { "Direct Voice", NULL, "IN2RP:VXRP" },
-
- { "MIXINL", "IN1L Switch", "IN1L PGA" },
- { "MIXINL", "IN2L Switch", "IN2L PGA" },
- { "MIXINL", NULL, "Direct Voice" },
- { "MIXINL", NULL, "IN1LP" },
- { "MIXINL", NULL, "Left Output Mixer" },
- { "MIXINL", NULL, "VMID" },
-
- { "MIXINR", "IN1R Switch", "IN1R PGA" },
- { "MIXINR", "IN2R Switch", "IN2R PGA" },
- { "MIXINR", NULL, "Direct Voice" },
- { "MIXINR", NULL, "IN1RP" },
- { "MIXINR", NULL, "Right Output Mixer" },
- { "MIXINR", NULL, "VMID" },
-
- { "ADCL", NULL, "MIXINL" },
- { "ADCR", NULL, "MIXINR" },
-
- { "Left Output Mixer", "Left Input Switch", "MIXINL" },
- { "Left Output Mixer", "Right Input Switch", "MIXINR" },
- { "Left Output Mixer", "IN2RN Switch", "IN2RN" },
- { "Left Output Mixer", "IN2LN Switch", "IN2LN" },
- { "Left Output Mixer", "IN2LP Switch", "IN2LP:VXRN" },
- { "Left Output Mixer", "IN1L Switch", "IN1L PGA" },
- { "Left Output Mixer", "IN1R Switch", "IN1R PGA" },
-
- { "Right Output Mixer", "Left Input Switch", "MIXINL" },
- { "Right Output Mixer", "Right Input Switch", "MIXINR" },
- { "Right Output Mixer", "IN2LN Switch", "IN2LN" },
- { "Right Output Mixer", "IN2RN Switch", "IN2RN" },
- { "Right Output Mixer", "IN2RP Switch", "IN2RP:VXRP" },
- { "Right Output Mixer", "IN1L Switch", "IN1L PGA" },
- { "Right Output Mixer", "IN1R Switch", "IN1R PGA" },
-
- { "Left Output PGA", NULL, "Left Output Mixer" },
- { "Left Output PGA", NULL, "TOCLK" },
-
- { "Right Output PGA", NULL, "Right Output Mixer" },
- { "Right Output PGA", NULL, "TOCLK" },
-
- { "Earpiece Mixer", "Direct Voice Switch", "Direct Voice" },
- { "Earpiece Mixer", "Left Output Switch", "Left Output PGA" },
- { "Earpiece Mixer", "Right Output Switch", "Right Output PGA" },
-
- { "Earpiece Driver", NULL, "VMID" },
- { "Earpiece Driver", NULL, "Earpiece Mixer" },
- { "HPOUT2N", NULL, "Earpiece Driver" },
- { "HPOUT2P", NULL, "Earpiece Driver" },
-
- { "SPKL", "Input Switch", "MIXINL" },
- { "SPKL", "IN1LP Switch", "IN1LP" },
- { "SPKL", "Output Switch", "Left Output PGA" },
- { "SPKL", NULL, "TOCLK" },
-
- { "SPKR", "Input Switch", "MIXINR" },
- { "SPKR", "IN1RP Switch", "IN1RP" },
- { "SPKR", "Output Switch", "Right Output PGA" },
- { "SPKR", NULL, "TOCLK" },
-
- { "SPKL Boost", "Direct Voice Switch", "Direct Voice" },
- { "SPKL Boost", "SPKL Switch", "SPKL" },
- { "SPKL Boost", "SPKR Switch", "SPKR" },
-
- { "SPKR Boost", "Direct Voice Switch", "Direct Voice" },
- { "SPKR Boost", "SPKR Switch", "SPKR" },
- { "SPKR Boost", "SPKL Switch", "SPKL" },
-
- { "SPKL Driver", NULL, "VMID" },
- { "SPKL Driver", NULL, "SPKL Boost" },
- { "SPKL Driver", NULL, "CLK_SYS" },
- { "SPKL Driver", NULL, "TSHUT" },
-
- { "SPKR Driver", NULL, "VMID" },
- { "SPKR Driver", NULL, "SPKR Boost" },
- { "SPKR Driver", NULL, "CLK_SYS" },
- { "SPKR Driver", NULL, "TSHUT" },
-
- { "SPKOUTLP", NULL, "SPKL Driver" },
- { "SPKOUTLN", NULL, "SPKL Driver" },
- { "SPKOUTRP", NULL, "SPKR Driver" },
- { "SPKOUTRN", NULL, "SPKR Driver" },
-
- { "Left Headphone Mux", "Mixer", "Left Output PGA" },
- { "Right Headphone Mux", "Mixer", "Right Output PGA" },
-
- { "Headphone PGA", NULL, "Left Headphone Mux" },
- { "Headphone PGA", NULL, "Right Headphone Mux" },
- { "Headphone PGA", NULL, "VMID" },
- { "Headphone PGA", NULL, "CLK_SYS" },
- { "Headphone PGA", NULL, "Headphone Supply" },
-
- { "HPOUT1L", NULL, "Headphone PGA" },
- { "HPOUT1R", NULL, "Headphone PGA" },
-
- { "LINEOUT1N Driver", NULL, "VMID" },
- { "LINEOUT1P Driver", NULL, "VMID" },
- { "LINEOUT2N Driver", NULL, "VMID" },
- { "LINEOUT2P Driver", NULL, "VMID" },
-
- { "LINEOUT1N", NULL, "LINEOUT1N Driver" },
- { "LINEOUT1P", NULL, "LINEOUT1P Driver" },
- { "LINEOUT2N", NULL, "LINEOUT2N Driver" },
- { "LINEOUT2P", NULL, "LINEOUT2P Driver" },
-};
-
-static const struct snd_soc_dapm_route lineout1_diff_routes[] = {
- { "LINEOUT1 Mixer", "IN1L Switch", "IN1L PGA" },
- { "LINEOUT1 Mixer", "IN1R Switch", "IN1R PGA" },
- { "LINEOUT1 Mixer", "Output Switch", "Left Output PGA" },
-
- { "LINEOUT1N Driver", NULL, "LINEOUT1 Mixer" },
- { "LINEOUT1P Driver", NULL, "LINEOUT1 Mixer" },
-};
-
-static const struct snd_soc_dapm_route lineout1_se_routes[] = {
- { "LINEOUT1N Mixer", "Left Output Switch", "Left Output PGA" },
- { "LINEOUT1N Mixer", "Right Output Switch", "Right Output PGA" },
-
- { "LINEOUT1P Mixer", "Left Output Switch", "Left Output PGA" },
-
- { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" },
- { "LINEOUT1P Driver", NULL, "LINEOUT1P Mixer" },
-};
-
-static const struct snd_soc_dapm_route lineout2_diff_routes[] = {
- { "LINEOUT2 Mixer", "IN1L Switch", "IN1L PGA" },
- { "LINEOUT2 Mixer", "IN1R Switch", "IN1R PGA" },
- { "LINEOUT2 Mixer", "Output Switch", "Right Output PGA" },
-
- { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" },
- { "LINEOUT2P Driver", NULL, "LINEOUT2 Mixer" },
-};
-
-static const struct snd_soc_dapm_route lineout2_se_routes[] = {
- { "LINEOUT2N Mixer", "Left Output Switch", "Left Output PGA" },
- { "LINEOUT2N Mixer", "Right Output Switch", "Right Output PGA" },
-
- { "LINEOUT2P Mixer", "Right Output Switch", "Right Output PGA" },
-
- { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" },
- { "LINEOUT2P Driver", NULL, "LINEOUT2P Mixer" },
-};
-
-int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- /* Latch volume update bits & default ZC on */
- snd_soc_update_bits(codec, WM8993_LEFT_LINE_INPUT_1_2_VOLUME,
- WM8993_IN1_VU, WM8993_IN1_VU);
- snd_soc_update_bits(codec, WM8993_RIGHT_LINE_INPUT_1_2_VOLUME,
- WM8993_IN1_VU, WM8993_IN1_VU);
- snd_soc_update_bits(codec, WM8993_LEFT_LINE_INPUT_3_4_VOLUME,
- WM8993_IN2_VU, WM8993_IN2_VU);
- snd_soc_update_bits(codec, WM8993_RIGHT_LINE_INPUT_3_4_VOLUME,
- WM8993_IN2_VU, WM8993_IN2_VU);
-
- snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_LEFT,
- WM8993_SPKOUT_VU, WM8993_SPKOUT_VU);
- snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_RIGHT,
- WM8993_SPKOUT_VU, WM8993_SPKOUT_VU);
-
- snd_soc_update_bits(codec, WM8993_LEFT_OUTPUT_VOLUME,
- WM8993_HPOUT1_VU | WM8993_HPOUT1L_ZC,
- WM8993_HPOUT1_VU | WM8993_HPOUT1L_ZC);
- snd_soc_update_bits(codec, WM8993_RIGHT_OUTPUT_VOLUME,
- WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC,
- WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC);
-
- snd_soc_update_bits(codec, WM8993_LEFT_OPGA_VOLUME,
- WM8993_MIXOUTL_ZC | WM8993_MIXOUT_VU,
- WM8993_MIXOUTL_ZC | WM8993_MIXOUT_VU);
- snd_soc_update_bits(codec, WM8993_RIGHT_OPGA_VOLUME,
- WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU,
- WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU);
-
- snd_soc_add_codec_controls(codec, analogue_snd_controls,
- ARRAY_SIZE(analogue_snd_controls));
-
- snd_soc_dapm_new_controls(dapm, analogue_dapm_widgets,
- ARRAY_SIZE(analogue_dapm_widgets));
- return 0;
-}
-EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_controls);
-
-int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec,
- int lineout1_diff, int lineout2_diff)
-{
- struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- init_completion(&hubs->dcs_done);
-
- snd_soc_dapm_add_routes(dapm, analogue_routes,
- ARRAY_SIZE(analogue_routes));
-
- if (lineout1_diff)
- snd_soc_dapm_add_routes(dapm,
- lineout1_diff_routes,
- ARRAY_SIZE(lineout1_diff_routes));
- else
- snd_soc_dapm_add_routes(dapm,
- lineout1_se_routes,
- ARRAY_SIZE(lineout1_se_routes));
-
- if (lineout2_diff)
- snd_soc_dapm_add_routes(dapm,
- lineout2_diff_routes,
- ARRAY_SIZE(lineout2_diff_routes));
- else
- snd_soc_dapm_add_routes(dapm,
- lineout2_se_routes,
- ARRAY_SIZE(lineout2_se_routes));
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_routes);
-
-int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
- int lineout1_diff, int lineout2_diff,
- int lineout1fb, int lineout2fb,
- int jd_scthr, int jd_thr, int micbias1_lvl,
- int micbias2_lvl)
-{
- struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
-
- hubs->lineout1_se = !lineout1_diff;
- hubs->lineout2_se = !lineout2_diff;
-
- if (!lineout1_diff)
- snd_soc_update_bits(codec, WM8993_LINE_MIXER1,
- WM8993_LINEOUT1_MODE,
- WM8993_LINEOUT1_MODE);
- if (!lineout2_diff)
- snd_soc_update_bits(codec, WM8993_LINE_MIXER2,
- WM8993_LINEOUT2_MODE,
- WM8993_LINEOUT2_MODE);
-
- if (!lineout1_diff && !lineout2_diff)
- snd_soc_update_bits(codec, WM8993_ANTIPOP1,
- WM8993_LINEOUT_VMID_BUF_ENA,
- WM8993_LINEOUT_VMID_BUF_ENA);
-
- if (lineout1fb)
- snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
- WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB);
-
- if (lineout2fb)
- snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
- WM8993_LINEOUT2_FB, WM8993_LINEOUT2_FB);
-
- snd_soc_update_bits(codec, WM8993_MICBIAS,
- WM8993_JD_SCTHR_MASK | WM8993_JD_THR_MASK |
- WM8993_MICB1_LVL | WM8993_MICB2_LVL,
- jd_scthr << WM8993_JD_SCTHR_SHIFT |
- jd_thr << WM8993_JD_THR_SHIFT |
- micbias1_lvl |
- micbias2_lvl << WM8993_MICB2_LVL_SHIFT);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(wm_hubs_handle_analogue_pdata);
-
-void wm_hubs_vmid_ena(struct snd_soc_codec *codec)
-{
- struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
- int val = 0;
-
- if (hubs->lineout1_se)
- val |= WM8993_LINEOUT1N_ENA | WM8993_LINEOUT1P_ENA;
-
- if (hubs->lineout2_se)
- val |= WM8993_LINEOUT2N_ENA | WM8993_LINEOUT2P_ENA;
-
- /* Enable the line outputs while we power up */
- snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3, val, val);
-}
-EXPORT_SYMBOL_GPL(wm_hubs_vmid_ena);
-
-void wm_hubs_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
- int mask, val;
-
- switch (level) {
- case SND_SOC_BIAS_STANDBY:
- /* Clamp the inputs to VMID while we ramp to charge caps */
- snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG,
- WM8993_INPUTS_CLAMP, WM8993_INPUTS_CLAMP);
- break;
-
- case SND_SOC_BIAS_ON:
- /* Turn off any unneded single ended outputs */
- val = 0;
- mask = 0;
-
- if (hubs->lineout1_se)
- mask |= WM8993_LINEOUT1N_ENA | WM8993_LINEOUT1P_ENA;
-
- if (hubs->lineout2_se)
- mask |= WM8993_LINEOUT2N_ENA | WM8993_LINEOUT2P_ENA;
-
- if (hubs->lineout1_se && hubs->lineout1n_ena)
- val |= WM8993_LINEOUT1N_ENA;
-
- if (hubs->lineout1_se && hubs->lineout1p_ena)
- val |= WM8993_LINEOUT1P_ENA;
-
- if (hubs->lineout2_se && hubs->lineout2n_ena)
- val |= WM8993_LINEOUT2N_ENA;
-
- if (hubs->lineout2_se && hubs->lineout2p_ena)
- val |= WM8993_LINEOUT2P_ENA;
-
- snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3,
- mask, val);
-
- /* Remove the input clamps */
- snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG,
- WM8993_INPUTS_CLAMP, 0);
- break;
-
- default:
- break;
- }
-}
-EXPORT_SYMBOL_GPL(wm_hubs_set_bias_level);
-
-MODULE_DESCRIPTION("Shared support for Wolfson hubs products");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wm_hubs.h b/ANDROID_3.4.5/sound/soc/codecs/wm_hubs.h
deleted file mode 100644
index 5705276f..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wm_hubs.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * wm_hubs.h -- WM899x common code
- *
- * Copyright 2009 Wolfson Microelectronics plc
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _WM_HUBS_H
-#define _WM_HUBS_H
-
-#include <linux/completion.h>
-#include <linux/interrupt.h>
-
-struct snd_soc_codec;
-
-extern const unsigned int wm_hubs_spkmix_tlv[];
-
-/* This *must* be the first element of the codec->private_data struct */
-struct wm_hubs_data {
- int dcs_codes_l;
- int dcs_codes_r;
- int dcs_readback_mode;
- int hp_startup_mode;
- int series_startup;
- int no_series_update;
-
- bool no_cache_class_w;
- bool class_w;
- u16 class_w_dcs;
-
- bool lineout1_se;
- bool lineout1n_ena;
- bool lineout1p_ena;
-
- bool lineout2_se;
- bool lineout2n_ena;
- bool lineout2p_ena;
-
- bool dcs_done_irq;
- struct completion dcs_done;
-};
-
-extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
-extern int wm_hubs_add_analogue_routes(struct snd_soc_codec *, int, int);
-extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *,
- int lineout1_diff, int lineout2_diff,
- int lineout1fb, int lineout2fb,
- int jd_scthr, int jd_thr,
- int micbias1_lvl, int micbias2_lvl);
-
-extern irqreturn_t wm_hubs_dcs_done(int irq, void *data);
-extern void wm_hubs_vmid_ena(struct snd_soc_codec *codec);
-extern void wm_hubs_set_bias_level(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wmt_fm34.c b/ANDROID_3.4.5/sound/soc/codecs/wmt_fm34.c
deleted file mode 100755
index cee4dce9..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wmt_fm34.c
+++ /dev/null
@@ -1,830 +0,0 @@
-/*++
- * linux/sound/soc/codecs/wmt_fm34.c
- * WonderMedia echo cancellation driver
- *
- * Copyright c 2010 WonderMedia Technologies, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * WonderMedia Technologies, Inc.
- * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
---*/
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/version.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/kdev_t.h>
-#include <asm/page.h>
-#include <linux/cdev.h>
-#include <linux/device.h>
-
-#include <linux/gpio.h>
-#include <mach/wmt_iomux.h>
-
-#define FM34_DEVID 0x501a
-#define FM34_I2C_BUS_NR 4
-
-#define FM34_CTRL_NAME "wmt_echo"
-static int fm34_ctrl_major = 0;
-static struct cdev fm34_ctrl_dev;
-static struct class *fm34_ctrl_class;
-
-// FM34 control interface commands
-#define FM34_CMD_ECHO _IOWR('E', 0x01, int)
-#define FM34_CMD_BYPASS _IOWR('E', 0x02, int)
-#define FM34_CMD_INCALL_MAIN_MIC _IOWR('E', 0x04, int)
-#define FM34_CMD_INCALL_HEADSET_MIC _IOWR('E', 0x08, int)
-#define FM34_CMD_CAPTURE_MAIN_MIC _IOWR('E', 0x10, int)
-#define FM34_CMD_CAPTURE_HEADSET_MIC _IOWR('E', 0x20, int)
-
-enum FM34_MODE_TYPE {
- FM34_MODE_ECHO,
- FM34_MODE_BYPASS,
- FM34_MODE_MAX,
-};
-
-enum FM34_MIC_SOURCE {
- FM34_INCALL_MIC_MAIN,
- FM34_INCALL_MIC_HEADSET,
- FM34_CAPTURE_MIC_MAIN,
- FM34_CAPTURE_MIC_HEADSET,
- FM34_MIC_MAX,
-};
-
-extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
-
-struct fm34_ctrl_gpo {
- int enable;
- int gpio;
- int active;
-};
-
-static struct fm34_ctrl_gpo fm34_reset;
-static struct fm34_ctrl_gpo fm34_powerdown;
-static struct fm34_ctrl_gpo fm34_bypass;
-
-struct fm34 {
- int (*read_dev)(struct fm34 *fm34,
- const u8 wdata[], int wsize,
- u8 rdata[], int rsize);
- int (*write_dev)(struct fm34 *fm34, const u8 wdata[], int wsize);
- void *control_data;
- struct device *dev;
- struct delayed_work delaywork;
-};
-
-static struct fm34 *fm34_context;
-static enum FM34_MODE_TYPE fm_mode = FM34_MODE_MAX;
-static enum FM34_MIC_SOURCE fm_mic = FM34_MIC_MAX;
-
-static const u8 wmt_fm34_incall_main_mic[] = {
- 0xFC, 0xF3, 0x3B, 0x22, 0xC0, 0x00, 0x04,
- 0xFC, 0xF3, 0x3B, 0x22, 0xC1, 0x00, 0x04,
- 0xFC, 0xF3, 0x3B, 0x22, 0xC2, 0x00, 0x03,
- 0xFC, 0xF3, 0x3B, 0x22, 0xC3, 0x00, 0x03,
- 0xFC, 0xF3, 0x3B, 0x22, 0xC6, 0x00, 0x0C,
- 0xFC, 0xF3, 0x3B, 0x22, 0xC7, 0x00, 0x0C,
- 0xFC, 0xF3, 0x3B, 0x22, 0xC8, 0x00, 0x2C,
- 0xFC, 0xF3, 0x3B, 0x22, 0xD2, 0x12, 0x94,
- 0xFC, 0xF3, 0x3B, 0x22, 0xEE, 0x00, 0x00,
- 0xFC, 0xF3, 0x3B, 0x22, 0xF2, 0x00, 0x40,
- 0xFC, 0xF3, 0x3B, 0x22, 0xF6, 0x00, 0x03,
- 0xFC, 0xF3, 0x3B, 0x22, 0xF8, 0x80, 0x05,
- 0xFC, 0xF3, 0x3B, 0x22, 0xF9, 0x20, 0xFF,
- 0xFC, 0xF3, 0x3B, 0x22, 0xFA, 0x22, 0x8B,
- 0xFC, 0xF3, 0x3B, 0x23, 0x01, 0x00, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x02, 0x01, 0x01,
- 0xFC, 0xF3, 0x3B, 0x23, 0x03, 0x09, 0x01,
- 0xFC, 0xF3, 0x3B, 0x23, 0x04, 0x03, 0x1E,
- 0xFC, 0xF3, 0x3B, 0x23, 0x05, 0x00, 0x01,
- 0xFC, 0xF3, 0x3B, 0x23, 0x07, 0xF0, 0xF0,
- 0xFC, 0xF3, 0x3B, 0x23, 0x08, 0x08, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x0A, 0x1B, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x0C, 0x04, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x48, 0x08, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x49, 0x06, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x6E, 0x20, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x6F, 0x0A, 0x0A,
- 0xFC, 0xF3, 0x3B, 0x23, 0x70, 0x0F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x73, 0x22, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x74, 0x18, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x75, 0x12, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x77, 0x30, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x7B, 0x00, 0x08,
- 0xFC, 0xF3, 0x3B, 0x23, 0x86, 0x48, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x8C, 0x10, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x9C, 0x60, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x9D, 0x40, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x9E, 0x40, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xBD, 0x30, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xCE, 0x40, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xCF, 0x0A, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xD0, 0x08, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xD1, 0x02, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xD2, 0x05, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xED, 0x05, 0x40,
- 0xFC, 0xF3, 0x3B, 0x23, 0xEE, 0x08, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xD5, 0x30, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x80, 0x7F, 0xFF,
- 0xFC, 0xF3, 0x3B, 0x23, 0x81, 0x40, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x82, 0x04, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x83, 0x04, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x84, 0x00, 0x04,
- 0xFC, 0xF3, 0x3B, 0x23, 0x85, 0x00, 0x05,
- 0xFC, 0xF3, 0x3B, 0x23, 0x8E, 0x70, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x90, 0xA9, 0x87,
- 0xFC, 0xF3, 0x3B, 0x23, 0x91, 0x76, 0x54,
- 0xFC, 0xF3, 0x3B, 0x23, 0x93, 0x44, 0x55,
- 0xFC, 0xF3, 0x3B, 0x23, 0x94, 0x55, 0x66,
- 0xFC, 0xF3, 0x3B, 0x23, 0x95, 0x66, 0x77,
- 0xFC, 0xF3, 0x3B, 0x23, 0x96, 0x20, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x97, 0x30, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x98, 0x00, 0x20,
- 0xFC, 0xF3, 0x3B, 0x23, 0xA5, 0x00, 0x06,
- 0xFC, 0xF3, 0x3B, 0x23, 0xA8, 0x7F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xA9, 0x7F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xAA, 0x7F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xAB, 0x7F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xAC, 0x7F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xAD, 0x7F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xAE, 0x7F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xAF, 0x7F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xB0, 0x7F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xB1, 0x7F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x09, 0x08, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xB3, 0x00, 0x20,
- 0xFC, 0xF3, 0x3B, 0x23, 0xB4, 0x00, 0x18,
- 0xFC, 0xF3, 0x3B, 0x23, 0x10, 0x48, 0x90,
- 0xFC, 0xF3, 0x3B, 0x23, 0x2F, 0x01, 0x40,
- 0xFC, 0xF3, 0x3B, 0x23, 0x32, 0x00, 0x30,
- 0xFC, 0xF3, 0x3B, 0x23, 0x33, 0x00, 0x0C,
- 0xFC, 0xF3, 0x3B, 0x23, 0x37, 0x00, 0x02,
- 0xFC, 0xF3, 0x3B, 0x23, 0x39, 0x00, 0x01,
- 0xFC, 0xF3, 0x3B, 0x22, 0xFB, 0x00, 0x00
-};
-
-static const u8 wmt_fm34_incall_headset_mic[] = {
- 0xFC, 0xF3, 0x3B, 0x22, 0xC0, 0x00, 0x04,
- 0xFC, 0xF3, 0x3B, 0x22, 0xC1, 0x00, 0x04,
- 0xFC, 0xF3, 0x3B, 0x22, 0xC2, 0x00, 0x03,
- 0xFC, 0xF3, 0x3B, 0x22, 0xC3, 0x00, 0x03,
- 0xFC, 0xF3, 0x3B, 0x22, 0xC6, 0x00, 0x0C,
- 0xFC, 0xF3, 0x3B, 0x22, 0xC7, 0x00, 0x0C,
- 0xFC, 0xF3, 0x3B, 0x22, 0xC8, 0x00, 0x2C,
- 0xFC, 0xF3, 0x3B, 0x22, 0xD2, 0x12, 0x94,
- 0xFC, 0xF3, 0x3B, 0x22, 0xEE, 0x00, 0x00,
- 0xFC, 0xF3, 0x3B, 0x22, 0xF2, 0x00, 0x40,
- 0xFC, 0xF3, 0x3B, 0x22, 0xF6, 0x00, 0x03,
- 0xFC, 0xF3, 0x3B, 0x22, 0xF8, 0x80, 0x05,
- 0xFC, 0xF3, 0x3B, 0x22, 0xF9, 0x20, 0xFF,
- 0xFC, 0xF3, 0x3B, 0x22, 0xFA, 0x22, 0x8B,
- 0xFC, 0xF3, 0x3B, 0x23, 0x01, 0x00, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x02, 0x01, 0x01,
- 0xFC, 0xF3, 0x3B, 0x23, 0x03, 0x09, 0x01,
- 0xFC, 0xF3, 0x3B, 0x23, 0x04, 0x03, 0x1E,
- 0xFC, 0xF3, 0x3B, 0x23, 0x05, 0x00, 0x01,
- 0xFC, 0xF3, 0x3B, 0x23, 0x07, 0xF0, 0xF0,
- 0xFC, 0xF3, 0x3B, 0x23, 0x08, 0x08, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x0A, 0x1A, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x0C, 0x04, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x48, 0x08, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x49, 0x06, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x6E, 0x20, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x6F, 0x0A, 0x0A,
- 0xFC, 0xF3, 0x3B, 0x23, 0x70, 0x0F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x73, 0x22, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x74, 0x18, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x75, 0x12, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x77, 0x30, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x7B, 0x00, 0x08,
- 0xFC, 0xF3, 0x3B, 0x23, 0x86, 0x48, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x8C, 0x10, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x9C, 0x60, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x9D, 0x40, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x9E, 0x40, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xBD, 0x30, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xCE, 0x40, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xCF, 0x08, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xD0, 0x06, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xD1, 0x02, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xD2, 0x05, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xED, 0x05, 0x40,
- 0xFC, 0xF3, 0x3B, 0x23, 0xEE, 0x08, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xD5, 0x20, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x80, 0x7F, 0xFF,
- 0xFC, 0xF3, 0x3B, 0x23, 0x81, 0x40, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x82, 0x04, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x83, 0x04, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x84, 0x00, 0x04,
- 0xFC, 0xF3, 0x3B, 0x23, 0x85, 0x00, 0x05,
- 0xFC, 0xF3, 0x3B, 0x23, 0x8E, 0x70, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x90, 0xA9, 0x87,
- 0xFC, 0xF3, 0x3B, 0x23, 0x91, 0x76, 0x54,
- 0xFC, 0xF3, 0x3B, 0x23, 0x93, 0x44, 0x55,
- 0xFC, 0xF3, 0x3B, 0x23, 0x94, 0x55, 0x66,
- 0xFC, 0xF3, 0x3B, 0x23, 0x95, 0x66, 0x77,
- 0xFC, 0xF3, 0x3B, 0x23, 0x96, 0x20, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x97, 0x30, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x98, 0x00, 0x20,
- 0xFC, 0xF3, 0x3B, 0x23, 0xA5, 0x00, 0x06,
- 0xFC, 0xF3, 0x3B, 0x23, 0xA8, 0x7F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xA9, 0x7F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xAA, 0x7F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xAB, 0x7F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xAC, 0x7F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xAD, 0x7F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xAE, 0x7F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xAF, 0x7F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xB0, 0x7F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xB1, 0x7F, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x09, 0x08, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xB3, 0x00, 0x06,
- 0xFC, 0xF3, 0x3B, 0x23, 0xB4, 0x00, 0x01,
- 0xFC, 0xF3, 0x3B, 0x23, 0x10, 0x48, 0x90,
- 0xFC, 0xF3, 0x3B, 0x23, 0x2F, 0x01, 0x40,
- 0xFC, 0xF3, 0x3B, 0x23, 0x32, 0x00, 0x30,
- 0xFC, 0xF3, 0x3B, 0x23, 0x33, 0x00, 0x0C,
- 0xFC, 0xF3, 0x3B, 0x23, 0x37, 0x00, 0x02,
- 0xFC, 0xF3, 0x3B, 0x23, 0x39, 0x00, 0x01,
- 0xFC, 0xF3, 0x3B, 0x22, 0xFB, 0x00, 0x00
-};
-
-static const u8 wmt_fm34_capture_main_mic[] = {
- 0xFC, 0xF3, 0x3B, 0x22, 0x9F, 0x00, 0x01,
- 0xFC, 0xF3, 0x3B, 0x22, 0xC6, 0x00, 0x0C,
- 0xFC, 0xF3, 0x3B, 0x22, 0xC7, 0x00, 0x0C,
- 0xFC, 0xF3, 0x3B, 0x22, 0xC8, 0x00, 0x2C,
- 0xFC, 0xF3, 0x3B, 0x22, 0xEE, 0x00, 0x00,
- 0xFC, 0xF3, 0x3B, 0x22, 0xF2, 0x00, 0x40,
- 0xFC, 0xF3, 0x3B, 0x22, 0xF6, 0x00, 0x03,
- 0xFC, 0xF3, 0x3B, 0x22, 0xF7, 0x01, 0x00,
- 0xFC, 0xF3, 0x3B, 0x22, 0xF8, 0x80, 0x02,
- 0xFC, 0xF3, 0x3B, 0x22, 0xF9, 0x67, 0xFF,
- 0xFC, 0xF3, 0x3B, 0x22, 0xFA, 0x23, 0x8B,
- 0xFC, 0xF3, 0x3B, 0x23, 0x01, 0x00, 0x02,
- 0xFC, 0xF3, 0x3B, 0x23, 0x02, 0x00, 0x01,
- 0xFC, 0xF3, 0x3B, 0x23, 0x03, 0x29, 0x88,
- 0xFC, 0xF3, 0x3B, 0x23, 0x04, 0x20, 0x0E,
- 0xFC, 0xF3, 0x3B, 0x23, 0x05, 0x00, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x07, 0x00, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x08, 0x0C, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x0A, 0x1B, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x0C, 0x02, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x48, 0x08, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x6E, 0x7F, 0xFF,
- 0xFC, 0xF3, 0x3B, 0x23, 0x6F, 0x0B, 0x05,
- 0xFC, 0xF3, 0x3B, 0x23, 0x70, 0x0C, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x73, 0x18, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x74, 0x21, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x75, 0x18, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x7B, 0x00, 0x08,
- 0xFC, 0xF3, 0x3B, 0x23, 0x82, 0x05, 0x80,
- 0xFC, 0xF3, 0x3B, 0x23, 0x83, 0x03, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x84, 0x00, 0x03,
- 0xFC, 0xF3, 0x3B, 0x23, 0x86, 0x48, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x8C, 0x10, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x90, 0x44, 0x44,
- 0xFC, 0xF3, 0x3B, 0x23, 0x91, 0x44, 0x44,
- 0xFC, 0xF3, 0x3B, 0x23, 0x92, 0x44, 0x44,
- 0xFC, 0xF3, 0x3B, 0x23, 0x93, 0x44, 0x44,
- 0xFC, 0xF3, 0x3B, 0x23, 0xBD, 0x30, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xCE, 0x40, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xCF, 0x12, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xD0, 0x10, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xD1, 0x07, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xD2, 0x05, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xD5, 0x70, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xED, 0x0A, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xEE, 0x10, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x28, 0x7F, 0xFF,
- 0xFC, 0xF3, 0x3B, 0x22, 0xF1, 0xD0, 0x00,
- 0xFC, 0xF3, 0x3B, 0x22, 0xFB, 0x00, 0x00
-};
-
-static const u8 wmt_fm34_capture_headset_mic[] = {
- 0xFC, 0xF3, 0x3B, 0x22, 0x9F, 0x00, 0x01,
- 0xFC, 0xF3, 0x3B, 0x22, 0xC6, 0x00, 0x0C,
- 0xFC, 0xF3, 0x3B, 0x22, 0xC7, 0x00, 0x0C,
- 0xFC, 0xF3, 0x3B, 0x22, 0xC8, 0x00, 0x2C,
- 0xFC, 0xF3, 0x3B, 0x22, 0xEE, 0x00, 0x00,
- 0xFC, 0xF3, 0x3B, 0x22, 0xF2, 0x00, 0x40,
- 0xFC, 0xF3, 0x3B, 0x22, 0xF6, 0x00, 0x03,
- 0xFC, 0xF3, 0x3B, 0x22, 0xF7, 0x01, 0x00,
- 0xFC, 0xF3, 0x3B, 0x22, 0xF8, 0x80, 0x02,
- 0xFC, 0xF3, 0x3B, 0x22, 0xF9, 0x67, 0xFF,
- 0xFC, 0xF3, 0x3B, 0x22, 0xFA, 0x23, 0x8B,
- 0xFC, 0xF3, 0x3B, 0x23, 0x01, 0x00, 0x02,
- 0xFC, 0xF3, 0x3B, 0x23, 0x02, 0x00, 0x01,
- 0xFC, 0xF3, 0x3B, 0x23, 0x03, 0x29, 0x88,
- 0xFC, 0xF3, 0x3B, 0x23, 0x04, 0x20, 0x0E,
- 0xFC, 0xF3, 0x3B, 0x23, 0x05, 0x00, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x07, 0x00, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x08, 0x0C, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x0A, 0x1A, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x0C, 0x02, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x48, 0x08, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x6E, 0x7F, 0xFF,
- 0xFC, 0xF3, 0x3B, 0x23, 0x6F, 0x0B, 0x05,
- 0xFC, 0xF3, 0x3B, 0x23, 0x70, 0x0C, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x73, 0x18, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x74, 0x21, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x75, 0x18, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x7B, 0x00, 0x08,
- 0xFC, 0xF3, 0x3B, 0x23, 0x82, 0x05, 0x80,
- 0xFC, 0xF3, 0x3B, 0x23, 0x83, 0x03, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x84, 0x00, 0x03,
- 0xFC, 0xF3, 0x3B, 0x23, 0x86, 0x48, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x8C, 0x10, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x90, 0x44, 0x44,
- 0xFC, 0xF3, 0x3B, 0x23, 0x91, 0x44, 0x44,
- 0xFC, 0xF3, 0x3B, 0x23, 0x92, 0x44, 0x44,
- 0xFC, 0xF3, 0x3B, 0x23, 0x93, 0x44, 0x44,
- 0xFC, 0xF3, 0x3B, 0x23, 0xBD, 0x30, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xCE, 0x40, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xCF, 0x12, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xD0, 0x10, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xD1, 0x07, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xD2, 0x05, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xD5, 0x70, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xED, 0x0A, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0xEE, 0x10, 0x00,
- 0xFC, 0xF3, 0x3B, 0x23, 0x28, 0x7F, 0xFF,
- 0xFC, 0xF3, 0x3B, 0x22, 0xF1, 0xD0, 0x00,
- 0xFC, 0xF3, 0x3B, 0x22, 0xFB, 0x00, 0x00
-};
-
-static int fm34_check_functionality(struct fm34 *fm34)
-{
- u8 rdata1, rdata2;
- int devid = 0;
- const u8 wdata1[] = {
- 0xFC, 0xF3, 0x27, 0x37, 0xFF
- };
- const u8 wdata2[] = {
- 0xFC, 0xF3, 0x60, 0x25
- };
- const u8 wdata3[] = {
- 0xFC, 0xF3, 0x60, 0x26
- };
-
- if (fm34->write_dev(fm34, wdata1, sizeof(wdata1)))
- return 0;
-
- if (fm34->read_dev(fm34, wdata2, sizeof(wdata2), &rdata1, 1) ||
- fm34->read_dev(fm34, wdata3, sizeof(wdata3), &rdata2, 1))
- return 0;
-
- devid = (rdata2 << 8) | rdata1;
- printk("-->fm34_check_functionality: %x\n", devid);
- if (devid == FM34_DEVID)
- return 1;
-
- return 0;
-}
-
-static int fm34_i2c_write(struct fm34 *fm34, const u8 wdata[], int wsize)
-{
- int ret;
- struct i2c_client *i2c = fm34->control_data;
- struct i2c_msg xfer[1];
-
- /*
- * [MSG1]: fill the register address data
- * fill the data Tx buffer
- */
- xfer[0].addr = i2c->addr;
- xfer[0].flags = 0 ;
- xfer[0].flags &= ~(I2C_M_RD);
- xfer[0].buf = (__u8 *)wdata;
- xfer[0].len = wsize;
-
- /* i2c_transfer returns number of messages transferred */
- ret = i2c_transfer(i2c->adapter, xfer, ARRAY_SIZE(xfer));
- if (ret != ARRAY_SIZE(xfer)) {
- pr_err("fm34_i2c_write err[%d]\n", ret);
- if (ret < 0)
- return ret;
- else
- return -EIO;
- } else
- return 0;
-}
-
-static int fm34_i2c_read(struct fm34 *fm34,
- const u8 wdata[], int wsize,
- u8 rdata[], int rsize)
-{
- int ret;
- struct i2c_client *i2c = fm34->control_data;
- struct i2c_msg xfer[2];
-
- /* [MSG1] fill the register address data */
- xfer[0].addr = i2c->addr;
- xfer[0].flags = 2; /* Read the register val */
- xfer[0].buf = (__u8 *)wdata;
- xfer[0].len = wsize;
-
- /* [MSG2] fill the data rx buffer */
- xfer[1].addr = i2c->addr;
- xfer[1].flags = I2C_M_RD; /* Read the register val */
- xfer[1].len = rsize; /* only n bytes */
- xfer[1].buf = rdata;
-
- /* i2c_transfer returns number of messages transferred */
- ret = i2c_transfer(i2c->adapter, xfer, ARRAY_SIZE(xfer));
- if (ret != ARRAY_SIZE(xfer)) {
- pr_err("vt1603_i2c_read err[%d]\n", ret);
- if (ret < 0)
- return ret;
- else
- return -EIO;
- } else {
- return 0;
- }
-}
-
-static void fm34_timing_init(void)
-{
- // pwdn high to power up fm34 module
- if (fm34_powerdown.enable) {
- gpio_set_value_cansleep(fm34_powerdown.gpio, !!fm34_powerdown.active);
- msleep(100);
- }
-
- // reset fm34 module
- if (fm34_reset.enable) {
- gpio_set_value_cansleep(fm34_reset.gpio, !!fm34_reset.active);
- msleep(10);
- gpio_set_value_cansleep(fm34_reset.gpio, !fm34_reset.active);
- msleep(10);
- gpio_set_value_cansleep(fm34_reset.gpio, !!fm34_reset.active);
- msleep(100);
- }
-
- // disable fm34 bypass
- if (fm34_bypass.enable) {
- gpio_set_value_cansleep(fm34_bypass.gpio, !!fm34_bypass.active);
- }
-}
-
-static void fm34_do_work(struct work_struct *work)
-{
- struct fm34 *fm34 = container_of(work, struct fm34, delaywork.work);
-
- fm34_timing_init();
-
- if (fm34_check_functionality(fm34) == 0) {
- pr_err("fm34_check_functionality: wrong device id\n");
- }
-
- fm34->write_dev(fm34, wmt_fm34_incall_main_mic, sizeof(wmt_fm34_incall_main_mic));
- //fm_mode = FM34_MODE_ECHO;
- fm_mic = FM34_INCALL_MIC_MAIN;
-}
-
-static int __devinit fm34_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct fm34 *fm34;
- int ret;
-
- if (i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C) == 0) {
- pr_err("i2c_check_functionality: can't talk I2C?\n");
- return -EIO;
- }
-
- fm34 = kzalloc(sizeof(struct fm34), GFP_KERNEL);
- if (fm34 == NULL)
- return -ENOMEM;
-
- fm34->dev = &i2c->dev;
- fm34->control_data = i2c;
- fm34->read_dev = fm34_i2c_read;
- fm34->write_dev = fm34_i2c_write;
-
- i2c_set_clientdata(i2c, fm34);
- dev_set_drvdata(fm34->dev, fm34);
-
- INIT_DELAYED_WORK(&fm34->delaywork, fm34_do_work);
-
- if (fm34_powerdown.enable && gpio_is_valid(fm34_powerdown.gpio)) {
- ret = gpio_request(fm34_powerdown.gpio, "FM34-powerdown");
- if (ret < 0){
- dev_warn(fm34->dev, "cann't register fm34_powerdown.gpio-%d\n", fm34_powerdown.gpio);
- fm34_powerdown.enable = 0;
- }
- else
- gpio_direction_output(fm34_powerdown.gpio, 0);
- }
-
- if (fm34_reset.enable && gpio_is_valid(fm34_reset.gpio)) {
- ret = gpio_request(fm34_reset.gpio, "FM34-reset");
- if (ret < 0) {
- dev_warn(fm34->dev, "cann't register fm34_reset.gpio-%d\n", fm34_reset.gpio);
- fm34_reset.enable = 0;
- }
- else
- gpio_direction_output(fm34_reset.gpio, 0);
- }
-
- if (fm34_bypass.enable && gpio_is_valid(fm34_bypass.gpio)) {
- ret = gpio_request(fm34_bypass.gpio, "FM34-bypass");
- if (ret < 0) {
- dev_warn(fm34->dev, "cann't register fm34_bypass.gpio-%d\n", fm34_bypass.gpio);
- fm34_bypass.enable = 0;
- }
- else
- gpio_direction_output(fm34_bypass.gpio, 0);
- }
-
- fm34_timing_init();
-
- if (fm34_check_functionality(fm34) == 0) {
- pr_err("fm34_check_functionality: wrong device id\n");
- return -EIO;
- }
-
- fm34_context = fm34;
-
- /* write the firmware to device */
- fm34->write_dev(fm34, wmt_fm34_incall_main_mic, sizeof(wmt_fm34_incall_main_mic));
- fm_mode = FM34_MODE_ECHO; // default is echo mode
- fm_mic = FM34_INCALL_MIC_MAIN;
- return 0;
-}
-
-static int __devexit fm34_i2c_remove(struct i2c_client *i2c)
-{
- struct fm34 *fm34 = i2c_get_clientdata(i2c);
-
- if (fm34_powerdown.enable) {
- gpio_free(fm34_powerdown.gpio);
- }
- if (fm34_reset.enable) {
- gpio_free(fm34_reset.gpio);
- }
- if (fm34_bypass.enable) {
- gpio_free(fm34_bypass.gpio);
- }
-
- kfree(fm34);
- return 0;
-}
-
-static int fm34_suspend(struct i2c_client *i2c, pm_message_t mesg)
-{
- struct fm34 *fm34 = i2c_get_clientdata(i2c);
- cancel_delayed_work_sync(&fm34->delaywork);
- return 0;
-}
-static int fm34_resume(struct i2c_client *i2c)
-{
- struct fm34 *fm34 = i2c_get_clientdata(i2c);
- schedule_delayed_work(&fm34->delaywork, msecs_to_jiffies(2000));
- return 0;
-}
-
-static const struct i2c_device_id fm34_i2c_id[] = {
- { "wmt-fm34", 0 },
- { },
-};
-MODULE_DEVICE_TABLE(i2c, fm34_i2c_id);
-
-static struct i2c_driver fm34_i2c_driver = {
- .driver = {
- .name = "wmt-fm34",
- .owner = THIS_MODULE,
- },
- .probe = fm34_i2c_probe,
- .remove = __devexit_p(fm34_i2c_remove),
- .suspend = fm34_suspend,
- .resume = fm34_resume,
- .id_table = fm34_i2c_id,
-};
-
-static struct i2c_board_info fm34_i2c_board_info = {
- I2C_BOARD_INFO("wmt-fm34", 0xc0>>1),
-};
-
-static int fm34_ctrl_open (struct inode *inode, struct file *filp)
-{
- printk("%s %d\n", __func__, __LINE__);
- return 0;
-}
-
-static int fm34_ctrl_release(struct inode *inode, struct file *filp)
-{
- printk("%s %d\n", __func__, __LINE__);
- return 0;
-}
-
-static ssize_t fm34_ctrl_read(struct file *filp, char __user *buf, size_t size, loff_t *offp)
-{
- printk("%s %d\n", __func__, __LINE__);
- return size;
-}
-
-static long fm34_ctrl_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
- const u8 echo[] = { 0xFC, 0xF3, 0x3B, 0x23, 0x00, 0x00, 0x00 };
- const u8 bypass[] = { 0xFC, 0xF3, 0x3B, 0x23, 0x00, 0x00, 0x01 };
- //const u8 main_mic[] = { 0xFC, 0xF3, 0x3B, 0x23, 0x0a, 0x1a, 0x00 };
- //const u8 headset_mic[] = { 0xFC, 0xF3, 0x3B, 0x23, 0x0a, 0x1b, 0x00 };
-
- switch (cmd) {
- case FM34_CMD_ECHO:
- if (fm_mode != FM34_MODE_ECHO) {
- printk("FM34 cmd: echo\n");
- if (fm34_context->write_dev(fm34_context, echo, sizeof(echo)))
- return -EIO;
- fm_mode = FM34_MODE_ECHO;
- }
- break;
-
- case FM34_CMD_BYPASS:
- if (fm_mode != FM34_MODE_BYPASS) {
- printk("FM34 cmd: bypass\n");
- if (fm34_context->write_dev(fm34_context, bypass, sizeof(bypass)))
- return -EIO;
- fm_mode = FM34_MODE_BYPASS;
- }
- break;
-
- case FM34_CMD_INCALL_MAIN_MIC:
- if (fm_mic != FM34_INCALL_MIC_MAIN) {
- printk("FM34 cmd: incall main-mic\n");
- if (fm34_reset.enable) {
- gpio_set_value_cansleep(fm34_reset.gpio, !fm34_reset.active);
- msleep(20);
- gpio_set_value_cansleep(fm34_reset.gpio, !!fm34_reset.active);
- msleep(20);
- }
- if (fm34_context->write_dev(fm34_context, wmt_fm34_incall_main_mic, sizeof(wmt_fm34_incall_main_mic)))
- return -EIO;
- fm_mic = FM34_INCALL_MIC_MAIN;
- }
- break;
-
- case FM34_CMD_INCALL_HEADSET_MIC:
- if (fm_mic != FM34_INCALL_MIC_HEADSET) {
- printk("FM34 cmd: incall headset-mic\n");
- if (fm34_reset.enable) {
- gpio_set_value_cansleep(fm34_reset.gpio, !fm34_reset.active);
- msleep(20);
- gpio_set_value_cansleep(fm34_reset.gpio, !!fm34_reset.active);
- msleep(20);
- }
- if (fm34_context->write_dev(fm34_context, wmt_fm34_incall_headset_mic, sizeof(wmt_fm34_incall_headset_mic)))
- return -EIO;
- fm_mic = FM34_INCALL_MIC_HEADSET;
- }
- break;
-
- case FM34_CMD_CAPTURE_MAIN_MIC:
- if (fm_mic != FM34_CMD_CAPTURE_MAIN_MIC) {
- printk("FM34 cmd: capture main-mic\n");
- if (fm34_reset.enable) {
- gpio_set_value_cansleep(fm34_reset.gpio, !fm34_reset.active);
- msleep(20);
- gpio_set_value_cansleep(fm34_reset.gpio, !!fm34_reset.active);
- msleep(20);
- }
- if (fm34_context->write_dev(fm34_context, wmt_fm34_capture_main_mic, sizeof(wmt_fm34_capture_main_mic)))
- return -EIO;
- fm_mic = FM34_CMD_CAPTURE_MAIN_MIC;
- }
- break;
-
- case FM34_CMD_CAPTURE_HEADSET_MIC:
- if (fm_mic != FM34_CMD_CAPTURE_HEADSET_MIC) {
- printk("FM34 cmd: capture headset-mic\n");
- if (fm34_reset.enable) {
- gpio_set_value_cansleep(fm34_reset.gpio, !fm34_reset.active);
- msleep(20);
- gpio_set_value_cansleep(fm34_reset.gpio, !!fm34_reset.active);
- msleep(20);
- }
- if (fm34_context->write_dev(fm34_context, wmt_fm34_capture_headset_mic, sizeof(wmt_fm34_capture_headset_mic)))
- return -EIO;
- fm_mic = FM34_CMD_CAPTURE_HEADSET_MIC;
- }
- break;
-
- default:
- printk(KERN_ERR "FM34: Not support cmd[%d]\n", cmd);
- break;
- }
-
- return 0;
-}
-
-static struct file_operations fm34_ctrl_ops = {
- .owner = THIS_MODULE,
- .open = fm34_ctrl_open,
- .release = fm34_ctrl_release,
- .read = fm34_ctrl_read,
- .unlocked_ioctl = fm34_ctrl_ioctl,
-};
-
-static int fm34_ctrl_setup_cdev(struct cdev *dev, int minor, struct file_operations *fops)
-{
- int ret, devno = MKDEV(fm34_ctrl_major, minor);
- cdev_init(dev, fops);
- dev->owner = THIS_MODULE;
- dev->ops = fops;
- ret = cdev_add(dev, devno, 1);
- if (ret)
- printk(KERN_ERR "Error %d adding wmt_echo %d", ret, minor);
- return ret;
-}
-
-static int __init fm34_init(void)
-{
- int ret = -1;
- int len = 64;
- char buf[64];
- dev_t dev;
- struct i2c_adapter *adapter;
- struct i2c_client *client;
-
- ret = wmt_getsyspara("wmt.echo.cancellation", buf, &len);
- if (ret == 0) {
- sscanf(buf, "fm34:[%d:%d:%d]:[%d:%d:%d]:[%d:%d:%d]",
- &fm34_powerdown.enable, &fm34_powerdown.gpio, &fm34_powerdown.active,
- &fm34_reset.enable, &fm34_reset.gpio, &fm34_reset.active,
- &fm34_bypass.enable, &fm34_bypass.gpio, &fm34_bypass.active);
- }
- else {
- fm34_reset.enable = 0;
- fm34_powerdown.enable = 0;
- fm34_bypass.enable = 0;
- }
-
- ret = alloc_chrdev_region(&dev, 0, 1, FM34_CTRL_NAME);
- if (ret == 0)
- fm34_ctrl_major = MAJOR(dev);
- else
- printk(KERN_ERR "fm34: alloc_chrdev_region failed!\n");
-
- ret = fm34_ctrl_setup_cdev(&fm34_ctrl_dev, 0, &fm34_ctrl_ops);
- if (ret == 0) {
- fm34_ctrl_class = class_create(THIS_MODULE, FM34_CTRL_NAME);
- if (IS_ERR(fm34_ctrl_class)) {
- printk("fm34: class_create failed!\n");
- }
- else
- device_create(fm34_ctrl_class, NULL, MKDEV(fm34_ctrl_major, 0), NULL, FM34_CTRL_NAME);
- }
-
- adapter = i2c_get_adapter(FM34_I2C_BUS_NR);
- client = i2c_new_device(adapter, &fm34_i2c_board_info);
- i2c_put_adapter(adapter);
-
- ret = i2c_add_driver(&fm34_i2c_driver);
- if (ret != 0)
- pr_err("Failed to register FM34 I2C driver: %d\n", ret);
- return ret;
-}
-module_init(fm34_init);
-
-static void __exit fm34_exit(void)
-{
- cdev_del(&fm34_ctrl_dev);
- device_destroy(fm34_ctrl_class, MKDEV(fm34_ctrl_major, 0));
- class_destroy(fm34_ctrl_class);
- unregister_chrdev_region(MKDEV(fm34_ctrl_major, 0), 1);
-
- i2c_del_driver(&fm34_i2c_driver);
-}
-module_exit(fm34_exit);
-
-MODULE_DESCRIPTION("WMT [ALSA SoC/echocancellation] driver");
-MODULE_AUTHOR("WonderMedia Technologies, Inc.");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wmt_hwdac.c b/ANDROID_3.4.5/sound/soc/codecs/wmt_hwdac.c
deleted file mode 100755
index ae31bb5e..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wmt_hwdac.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*++
- * linux/sound/soc/codecs/wmt_hwdac.c
- * WonderMedia I2S audio driver for ALSA
- *
- * Copyright c 2010 WonderMedia Technologies, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * WonderMedia Technologies, Inc.
- * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
---*/
-
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-
-
-/*
- * Debug
- */
-#define AUDIO_NAME "HW_DAC"
-//#define WMT_HWDAC_DEBUG 1
-//#define WMT_HWDAC_DEBUG_DETAIL 1
-
-#ifdef WMT_HWDAC_DEBUG
-#define DPRINTK(format, arg...) \
- printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
-#else
-#define DPRINTK(format, arg...) do {} while (0)
-#endif
-
-#ifdef WMT_HWDAC_DEBUG_DETAIL
-#define DBG_DETAIL(format, arg...) \
- printk(KERN_INFO AUDIO_NAME ": [%s]" format "\n" , __FUNCTION__, ## arg)
-#else
-#define DBG_DETAIL(format, arg...) do {} while (0)
-#endif
-
-#define err(format, arg...) \
- printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg)
-#define info(format, arg...) \
- printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
-#define warn(format, arg...) \
- printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg)
-
-extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
-
-
-static int hwdac_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
-{
- DBG_DETAIL();
-
- return 0;
-}
-
-
-#define HWDAC_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | \
- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | \
- SNDRV_PCM_RATE_96000)
-
-#define HWDAC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_FLOAT)
-
-static struct snd_soc_dai_ops hwdac_dai_ops = {
- .hw_params = hwdac_pcm_hw_params,
-};
-
-struct snd_soc_dai_driver hwdac_dai = {
- .name = "HWDAC",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = HWDAC_RATES,
- .formats = HWDAC_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = HWDAC_RATES,
- .formats = HWDAC_FORMATS,
- },
- .ops = &hwdac_dai_ops,
-};
-
-static int hwdac_probe(struct snd_soc_codec *codec)
-{
- DBG_DETAIL();
-
- return 0;
-}
-
-/* remove everything here */
-static int hwdac_remove(struct snd_soc_codec *codec)
-{
- DBG_DETAIL();
-
- return 0;
-}
-
-struct snd_soc_codec_driver soc_codec_dev_hwdac = {
- .probe = hwdac_probe,
- .remove = hwdac_remove,
-};
-
-static int __devinit hwdac_platform_probe(struct platform_device *pdev)
-{
- int ret = 0;
-
- DBG_DETAIL();
-
- ret = snd_soc_register_codec(&pdev->dev,
- &soc_codec_dev_hwdac, &hwdac_dai, 1);
-
- if (ret)
- info("snd_soc_register_codec fail");
-
- return ret;
-}
-
-static int __devexit hwdac_platform_remove(struct platform_device *pdev)
-{
- DBG_DETAIL();
-
- snd_soc_unregister_codec(&pdev->dev);
-
- return 0;
-}
-
-static struct platform_driver wmt_hwdac_driver = {
- .driver = {
- .name = "wmt-i2s-hwdac",
- .owner = THIS_MODULE,
- },
-
- .probe = hwdac_platform_probe,
- .remove = __devexit_p(hwdac_platform_remove),
-};
-
-static int __init wmt_hwdac_platform_init(void)
-{
- char buf[80];
- int varlen = 80;
- char codec_name[5];
- int ret = 0;
-
- DBG_DETAIL();
-
- /*ret = wmt_getsyspara("wmt.audio.i2s", buf, &varlen);
-
- if (ret == 0) {
- sscanf(buf, "%5s", codec_name);
-
- if (strcmp(codec_name, "hwdac")) {
- info("hwdac string not found");
- return -EINVAL;
- }
- }*/
-
- return platform_driver_register(&wmt_hwdac_driver);
-}
-module_init(wmt_hwdac_platform_init);
-
-static void __exit wmt_hwdac_platform_exit(void)
-{
- DBG_DETAIL();
-
- platform_driver_unregister(&wmt_hwdac_driver);
-}
-module_exit(wmt_hwdac_platform_exit);
-
-MODULE_DESCRIPTION("WMT [ALSA SoC] driver");
-MODULE_AUTHOR("WonderMedia Technologies, Inc.");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wmt_vt1602.c b/ANDROID_3.4.5/sound/soc/codecs/wmt_vt1602.c
deleted file mode 100755
index fd625c95..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wmt_vt1602.c
+++ /dev/null
@@ -1,981 +0,0 @@
-/*++
- * linux/sound/soc/codecs/wmt_vt1602.c
- * WonderMedia I2S audio driver for ALSA
- *
- * Copyright c 2010 WonderMedia Technologies, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * WonderMedia Technologies, Inc.
- * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
---*/
-
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/i2c.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-
-#include "wmt_vt1602.h"
-
-#define VT1602_VERSION "0.20"
-#define I2C_DRIVERID_VT1602 90
-
-/*
- * Debug
- */
-#define AUDIO_NAME "VT1602"
-//#define WMT_VT1602_DEBUG 1
-//#define WMT_VT1602_DEBUG_DETAIL 1
-
-#ifdef WMT_VT1602_DEBUG
-#define DPRINTK(format, arg...) \
- printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
-#else
-#define DPRINTK(format, arg...) do {} while (0)
-#endif
-
-#ifdef WMT_VT1602_DEBUG_DETAIL
-#define DBG_DETAIL(format, arg...) \
- printk(KERN_INFO AUDIO_NAME ": [%s]" format "\n" , __FUNCTION__, ## arg)
-#else
-#define DBG_DETAIL(format, arg...) do {} while (0)
-#endif
-
-#define err(format, arg...) \
- printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg)
-#define info(format, arg...) \
- printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
-#define warn(format, arg...) \
- printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg)
-
-/* codec private data */
-struct vt1602_priv {
- unsigned int sysclk;
- enum snd_soc_control_type control_type;
- struct snd_pcm_substream *master_substream;
- struct snd_pcm_substream *slave_substream;
-};
-
-/*
- * vt1602 register cache
- * We can't read the VT1602 register space when we
- * are using 2 wire for device control, so we cache them instead.
- */
-static const u16 vt1602_reg[] = {
- 0x0050, 0x0050, 0x007f, 0x007f, /* 0 */
- 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */
- 0x0000, 0x0000, 0x00fc, 0x00fc, /* 8 */
- 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */
- 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */
- 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */
- 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */
- 0x0000, 0x0000, 0x0100, 0x0000, /* 32 */
- 0x0000, 0x0100, 0x0050, 0x0050, /* 36 */
- 0x0079, 0x0079, 0x0079, /* 40 */
-};
-
-extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
-
-#define vt1602_reset(c) snd_soc_write(c, VT1602_RESET, 0)
-
-/*
- * VT1602 Controls
- */
-static const char *vt1602_bass[] = {"Linear Control", "Adaptive Boost"};
-static const char *vt1602_bass_filter[] = { "130Hz @ 48kHz", "200Hz @ 48kHz" };
-static const char *vt1602_treble[] = {"8kHz", "4kHz"};
-static const char *vt1602_3d_lc[] = {"200Hz", "500Hz"};
-static const char *vt1602_3d_uc[] = {"2.2kHz", "1.5kHz"};
-static const char *vt1602_3d_func[] = {"Capture", "Playback"};
-static const char *vt1602_alc_func[] = {"Off", "Right", "Left", "Stereo"};
-static const char *vt1602_ng_type[] = {"Constant PGA Gain",
- "Mute ADC Output"};
-static const char *vt1602_line_mux[] = {"Line 1", "Line 2", "Line 3", "PGA",
- "Differential"};
-static const char *vt1602_pga_sel[] = {"Line 1", "Line 2", "Line 3",
- "Differential"};
-static const char *vt1602_out3[] = {"VREF", "ROUT1 + Vol", "MonoOut",
- "ROUT1"};
-static const char *vt1602_diff_sel[] = {"Line 1", "Line 2"};
-static const char *vt1602_adcpol[] = {"Normal", "L Invert", "R Invert",
- "L + R Invert"};
-static const char *vt1602_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
-static const char *vt1602_mono_mux[] = {"Stereo", "Mono (Left)",
- "Mono (Right)", "Digital Mono"};
-
-static const struct soc_enum vt1602_enum[] = {
-SOC_ENUM_SINGLE(VT1602_BASS, 7, 2, vt1602_bass),
-SOC_ENUM_SINGLE(VT1602_BASS, 6, 2, vt1602_bass_filter),
-SOC_ENUM_SINGLE(VT1602_TREBLE, 6, 2, vt1602_treble),
-SOC_ENUM_SINGLE(VT1602_3D, 5, 2, vt1602_3d_lc),
-SOC_ENUM_SINGLE(VT1602_3D, 6, 2, vt1602_3d_uc),
-SOC_ENUM_SINGLE(VT1602_3D, 7, 2, vt1602_3d_func),
-SOC_ENUM_SINGLE(VT1602_ALC1, 7, 4, vt1602_alc_func),
-SOC_ENUM_SINGLE(VT1602_NGATE, 1, 2, vt1602_ng_type),
-SOC_ENUM_SINGLE(VT1602_LOUTM1, 0, 5, vt1602_line_mux),
-SOC_ENUM_SINGLE(VT1602_ROUTM1, 0, 5, vt1602_line_mux),
-SOC_ENUM_SINGLE(VT1602_LADCIN, 6, 4, vt1602_pga_sel), /* 10 */
-SOC_ENUM_SINGLE(VT1602_RADCIN, 6, 4, vt1602_pga_sel),
-SOC_ENUM_SINGLE(VT1602_ADCTL2, 7, 4, vt1602_out3),
-SOC_ENUM_SINGLE(VT1602_ADCIN, 8, 2, vt1602_diff_sel),
-SOC_ENUM_SINGLE(VT1602_ADCDAC, 5, 4, vt1602_adcpol),
-SOC_ENUM_SINGLE(VT1602_ADCDAC, 1, 4, vt1602_deemph),
-SOC_ENUM_SINGLE(VT1602_ADCIN, 6, 4, vt1602_mono_mux), /* 16 */
-
-};
-
-static const struct snd_kcontrol_new vt1602_snd_controls[] = {
-
-SOC_DOUBLE_R("Capture Volume", VT1602_LINVOL, VT1602_RINVOL, 0, 63, 0),
-SOC_DOUBLE_R("Capture ZC Switch", VT1602_LINVOL, VT1602_RINVOL, 6, 1, 0),
-SOC_DOUBLE_R("Capture Switch", VT1602_LINVOL, VT1602_RINVOL, 7, 1, 1),
-
-SOC_DOUBLE_R("Headphone Playback ZC Switch", VT1602_LOUT1V,
- VT1602_ROUT1V, 7, 1, 0),
-SOC_DOUBLE_R("Speaker Playback ZC Switch", VT1602_LOUT2V,
- VT1602_ROUT2V, 7, 1, 0),
-
-SOC_ENUM("Playback De-emphasis", vt1602_enum[15]),
-
-SOC_ENUM("Capture Polarity", vt1602_enum[14]),
-SOC_SINGLE("Playback 6dB Attenuate", VT1602_ADCDAC, 7, 1, 0),
-SOC_SINGLE("Capture 6dB Attenuate", VT1602_ADCDAC, 8, 1, 0),
-
-SOC_DOUBLE_R("Master Volume", VT1602_LOUT1V, VT1602_ROUT1V, 0, 127, 0),
-//SOC_DOUBLE_R("PCM Volume", VT1602_LOUT1V, VT1602_ROUT1V, 0, 127, 0),
-
-/*
-SOC_ENUM("Bass Boost", vt1602_enum[0]),
-SOC_ENUM("Bass Filter", vt1602_enum[1]),
-SOC_SINGLE("Bass Volume", VT1602_BASS, 0, 15, 1),
-
-SOC_SINGLE("Treble Volume", VT1602_TREBLE, 0, 15, 0),
-SOC_ENUM("Treble Cut-off", vt1602_enum[2]),
-
-SOC_SINGLE("3D Switch", VT1602_3D, 0, 1, 0),
-SOC_SINGLE("3D Volume", VT1602_3D, 1, 15, 0),
-SOC_ENUM("3D Lower Cut-off", vt1602_enum[3]),
-SOC_ENUM("3D Upper Cut-off", vt1602_enum[4]),
-SOC_ENUM("3D Mode", vt1602_enum[5]),
-
-SOC_SINGLE("ALC Capture Target Volume", VT1602_ALC1, 0, 7, 0),
-SOC_SINGLE("ALC Capture Max Volume", VT1602_ALC1, 4, 7, 0),
-SOC_ENUM("ALC Capture Function", vt1602_enum[6]),
-SOC_SINGLE("ALC Capture ZC Switch", VT1602_ALC2, 7, 1, 0),
-SOC_SINGLE("ALC Capture Hold Time", VT1602_ALC2, 0, 15, 0),
-SOC_SINGLE("ALC Capture Decay Time", VT1602_ALC3, 4, 15, 0),
-SOC_SINGLE("ALC Capture Attack Time", VT1602_ALC3, 0, 15, 0),
-SOC_SINGLE("ALC Capture NG Threshold", VT1602_NGATE, 3, 31, 0),
-SOC_ENUM("ALC Capture NG Type", vt1602_enum[4]),
-SOC_SINGLE("ALC Capture NG Switch", VT1602_NGATE, 0, 1, 0),
-*/
-
-SOC_SINGLE("Left ADC Capture Volume", VT1602_LADC, 0, 255, 0),
-SOC_SINGLE("Right ADC Capture Volume", VT1602_RADC, 0, 255, 0),
-
-SOC_SINGLE("ZC Timeout Switch", VT1602_ADCTL1, 0, 1, 0),
-SOC_SINGLE("Playback Invert Switch", VT1602_ADCTL1, 1, 1, 0),
-
-SOC_SINGLE("Right Speaker Playback Invert Switch", VT1602_ADCTL2, 4, 1, 0),
-
-/* Unimplemented */
-/* ADCDAC Bit 0 - ADCHPD */
-/* ADCDAC Bit 4 - HPOR */
-/* ADCTL1 Bit 2,3 - DATSEL */
-/* ADCTL1 Bit 4,5 - DMONOMIX */
-/* ADCTL1 Bit 6,7 - VSEL */
-/* ADCTL2 Bit 2 - LRCM */
-/* ADCTL2 Bit 3 - TRI */
-/* ADCTL3 Bit 5 - HPFLREN */
-/* ADCTL3 Bit 6 - VROI */
-/* ADCTL3 Bit 7,8 - ADCLRM */
-/* ADCIN Bit 4 - LDCM */
-/* ADCIN Bit 5 - RDCM */
-
-SOC_DOUBLE_R("Mic Boost", VT1602_LADCIN, VT1602_RADCIN, 4, 3, 0),
-
-SOC_DOUBLE_R("Bypass Left Playback Volume", VT1602_LOUTM1,
- VT1602_LOUTM2, 4, 7, 1),
-SOC_DOUBLE_R("Bypass Right Playback Volume", VT1602_ROUTM1,
- VT1602_ROUTM2, 4, 7, 1),
-SOC_DOUBLE_R("Bypass Mono Playback Volume", VT1602_MOUTM1,
- VT1602_MOUTM2, 4, 7, 1),
-
-SOC_SINGLE("Mono Playback ZC Switch", VT1602_MOUTV, 7, 1, 0),
-
-SOC_DOUBLE_R("Headphone Playback Volume", VT1602_LOUT1V, VT1602_ROUT1V,
- 0, 127, 0),
-SOC_DOUBLE_R("Speaker Playback Volume", VT1602_LOUT2V, VT1602_ROUT2V,
- 0, 127, 0),
-
-SOC_SINGLE("Mono Playback Volume", VT1602_MOUTV, 0, 127, 0),
-
-};
-
-/*
- * DAPM Controls
- */
-
-/* Left Mixer */
-static const struct snd_kcontrol_new vt1602_left_mixer_controls[] = {
-SOC_DAPM_SINGLE("Playback Switch", VT1602_LOUTM1, 8, 1, 0),
-SOC_DAPM_SINGLE("Left Bypass Switch", VT1602_LOUTM1, 7, 1, 0),
-SOC_DAPM_SINGLE("Right Playback Switch", VT1602_LOUTM2, 8, 1, 0),
-SOC_DAPM_SINGLE("Right Bypass Switch", VT1602_LOUTM2, 7, 1, 0),
-};
-
-/* Right Mixer */
-static const struct snd_kcontrol_new vt1602_right_mixer_controls[] = {
-SOC_DAPM_SINGLE("Left Playback Switch", VT1602_ROUTM1, 8, 1, 0),
-SOC_DAPM_SINGLE("Left Bypass Switch", VT1602_ROUTM1, 7, 1, 0),
-SOC_DAPM_SINGLE("Playback Switch", VT1602_ROUTM2, 8, 1, 0),
-SOC_DAPM_SINGLE("Right Bypass Switch", VT1602_ROUTM2, 7, 1, 0),
-};
-
-/* Mono Mixer */
-static const struct snd_kcontrol_new vt1602_mono_mixer_controls[] = {
-SOC_DAPM_SINGLE("Left Playback Switch", VT1602_MOUTM1, 8, 1, 0),
-SOC_DAPM_SINGLE("Left Bypass Switch", VT1602_MOUTM1, 7, 1, 0),
-SOC_DAPM_SINGLE("Right Playback Switch", VT1602_MOUTM2, 8, 1, 0),
-SOC_DAPM_SINGLE("Right Bypass Switch", VT1602_MOUTM2, 7, 1, 0),
-};
-
-/* Left Line Mux */
-static const struct snd_kcontrol_new vt1602_left_line_controls =
-SOC_DAPM_ENUM("Route", vt1602_enum[8]);
-
-/* Right Line Mux */
-static const struct snd_kcontrol_new vt1602_right_line_controls =
-SOC_DAPM_ENUM("Route", vt1602_enum[9]);
-
-/* Left PGA Mux */
-static const struct snd_kcontrol_new vt1602_left_pga_controls =
-SOC_DAPM_ENUM("Route", vt1602_enum[10]);
-
-/* Right PGA Mux */
-static const struct snd_kcontrol_new vt1602_right_pga_controls =
-SOC_DAPM_ENUM("Route", vt1602_enum[11]);
-
-/* Out 3 Mux */
-static const struct snd_kcontrol_new vt1602_out3_controls =
-SOC_DAPM_ENUM("Route", vt1602_enum[12]);
-
-/* Differential Mux */
-static const struct snd_kcontrol_new vt1602_diffmux_controls =
-SOC_DAPM_ENUM("Route", vt1602_enum[13]);
-
-/* Mono ADC Mux */
-static const struct snd_kcontrol_new vt1602_monomux_controls =
-SOC_DAPM_ENUM("Route", vt1602_enum[16]);
-
-static const struct snd_soc_dapm_widget vt1602_dapm_widgets[] = {
- SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
- &vt1602_left_mixer_controls[0],
- ARRAY_SIZE(vt1602_left_mixer_controls)),
- SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
- &vt1602_right_mixer_controls[0],
- ARRAY_SIZE(vt1602_right_mixer_controls)),
- /*
- SND_SOC_DAPM_MIXER("Mono Mixer", VT1602_PWR2, 2, 0,
- &vt1602_mono_mixer_controls[0],
- ARRAY_SIZE(vt1602_mono_mixer_controls)),
-
- SND_SOC_DAPM_PGA("Right Out 2", VT1602_PWR2, 3, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Left Out 2", VT1602_PWR2, 4, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Right Out 1", VT1602_PWR2, 5, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Left Out 1", VT1602_PWR2, 6, 0, NULL, 0),
- SND_SOC_DAPM_DAC("Right DAC", "Right Playback", VT1602_PWR2, 7, 0),
- SND_SOC_DAPM_DAC("Left DAC", "Left Playback", VT1602_PWR2, 8, 0),
- */
- /*
- SND_SOC_DAPM_MICBIAS("Mic Bias", VT1602_PWR1, 1, 0),
- SND_SOC_DAPM_ADC("Right ADC", "Right Capture", VT1602_PWR1, 2, 0),
- SND_SOC_DAPM_ADC("Left ADC", "Left Capture", VT1602_PWR1, 3, 0),
-
- SND_SOC_DAPM_MUX("Left PGA Mux", VT1602_PWR1, 5, 0,
- &vt1602_left_pga_controls),
- SND_SOC_DAPM_MUX("Right PGA Mux", VT1602_PWR1, 4, 0,
- &vt1602_right_pga_controls),
- */
- SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0,
- &vt1602_left_line_controls),
- SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0,
- &vt1602_right_line_controls),
-
- SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 0, &vt1602_out3_controls),
- /*
- SND_SOC_DAPM_PGA("Out 3", VT1602_PWR2, 1, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Mono Out 1", VT1602_PWR2, 2, 0, NULL, 0),
- */
-
- SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0,
- &vt1602_diffmux_controls),
- SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0,
- &vt1602_monomux_controls),
- SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0,
- &vt1602_monomux_controls),
-
- SND_SOC_DAPM_OUTPUT("LOUT1"),
- SND_SOC_DAPM_OUTPUT("ROUT1"),
- SND_SOC_DAPM_OUTPUT("LOUT2"),
- SND_SOC_DAPM_OUTPUT("ROUT2"),
- SND_SOC_DAPM_OUTPUT("MONO1"),
- SND_SOC_DAPM_OUTPUT("OUT3"),
- SND_SOC_DAPM_OUTPUT("VREF"),
-
- SND_SOC_DAPM_INPUT("LINPUT1"),
- SND_SOC_DAPM_INPUT("LINPUT2"),
- SND_SOC_DAPM_INPUT("LINPUT3"),
- SND_SOC_DAPM_INPUT("RINPUT1"),
- SND_SOC_DAPM_INPUT("RINPUT2"),
- SND_SOC_DAPM_INPUT("RINPUT3"),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- /* left mixer */
- {"Left Mixer", "Playback Switch", "Left DAC"},
- {"Left Mixer", "Left Bypass Switch", "Left Line Mux"},
- {"Left Mixer", "Right Playback Switch", "Right DAC"},
- {"Left Mixer", "Right Bypass Switch", "Right Line Mux"},
-
- /* right mixer */
- {"Right Mixer", "Left Playback Switch", "Left DAC"},
- {"Right Mixer", "Left Bypass Switch", "Left Line Mux"},
- {"Right Mixer", "Playback Switch", "Right DAC"},
- {"Right Mixer", "Right Bypass Switch", "Right Line Mux"},
-
- /* left out 1 */
- {"Left Out 1", NULL, "Left Mixer"},
- {"LOUT1", NULL, "Left Out 1"},
-
- /* left out 2 */
- {"Left Out 2", NULL, "Left Mixer"},
- {"LOUT2", NULL, "Left Out 2"},
-
- /* right out 1 */
- {"Right Out 1", NULL, "Right Mixer"},
- {"ROUT1", NULL, "Right Out 1"},
-
- /* right out 2 */
- {"Right Out 2", NULL, "Right Mixer"},
- {"ROUT2", NULL, "Right Out 2"},
-
- /* mono mixer */
- {"Mono Mixer", "Left Playback Switch", "Left DAC"},
- {"Mono Mixer", "Left Bypass Switch", "Left Line Mux"},
- {"Mono Mixer", "Right Playback Switch", "Right DAC"},
- {"Mono Mixer", "Right Bypass Switch", "Right Line Mux"},
-
- /* mono out */
- {"Mono Out 1", NULL, "Mono Mixer"},
- {"MONO1", NULL, "Mono Out 1"},
-
- /* out 3 */
- {"Out3 Mux", "VREF", "VREF"},
- {"Out3 Mux", "ROUT1 + Vol", "ROUT1"},
- {"Out3 Mux", "ROUT1", "Right Mixer"},
- {"Out3 Mux", "MonoOut", "MONO1"},
- {"Out 3", NULL, "Out3 Mux"},
- {"OUT3", NULL, "Out 3"},
-
- /* Left Line Mux */
- {"Left Line Mux", "Line 1", "LINPUT1"},
- {"Left Line Mux", "Line 2", "LINPUT2"},
- {"Left Line Mux", "Line 3", "LINPUT3"},
- {"Left Line Mux", "PGA", "Left PGA Mux"},
- {"Left Line Mux", "Differential", "Differential Mux"},
-
- /* Right Line Mux */
- {"Right Line Mux", "Line 1", "RINPUT1"},
- {"Right Line Mux", "Line 2", "RINPUT2"},
- {"Right Line Mux", "Line 3", "RINPUT3"},
- {"Right Line Mux", "PGA", "Right PGA Mux"},
- {"Right Line Mux", "Differential", "Differential Mux"},
-
- /* Left PGA Mux */
- {"Left PGA Mux", "Line 1", "LINPUT1"},
- {"Left PGA Mux", "Line 2", "LINPUT2"},
- {"Left PGA Mux", "Line 3", "LINPUT3"},
- {"Left PGA Mux", "Differential", "Differential Mux"},
-
- /* Right PGA Mux */
- {"Right PGA Mux", "Line 1", "RINPUT1"},
- {"Right PGA Mux", "Line 2", "RINPUT2"},
- {"Right PGA Mux", "Line 3", "RINPUT3"},
- {"Right PGA Mux", "Differential", "Differential Mux"},
-
- /* Differential Mux */
- {"Differential Mux", "Line 1", "LINPUT1"},
- {"Differential Mux", "Line 1", "RINPUT1"},
- {"Differential Mux", "Line 2", "LINPUT2"},
- {"Differential Mux", "Line 2", "RINPUT2"},
-
- /* Left ADC Mux */
- {"Left ADC Mux", "Stereo", "Left PGA Mux"},
- {"Left ADC Mux", "Mono (Left)", "Left PGA Mux"},
- {"Left ADC Mux", "Digital Mono", "Left PGA Mux"},
-
- /* Right ADC Mux */
- {"Right ADC Mux", "Stereo", "Right PGA Mux"},
- {"Right ADC Mux", "Mono (Right)", "Right PGA Mux"},
- {"Right ADC Mux", "Digital Mono", "Right PGA Mux"},
-
- /* ADC */
- {"Left ADC", NULL, "Left ADC Mux"},
- {"Right ADC", NULL, "Right ADC Mux"},
-};
-
-struct _coeff_div {
- u32 mclk;
- u32 rate;
- u16 fs;
- u8 sr:5;
- u8 usb:1;
-};
-
-/* codec hifi mclk clock divider coefficients */
-static const struct _coeff_div coeff_div[] = {
- /* 8k */
- {12288000, 8000, 1536, 0x6, 0x0},
-
- /* 11.025k */
- {11289600, 11025, 1024, 0x18, 0x0},
-
- /* 16k */
- {12288000, 16000, 768, 0xa, 0x0},
-
- /* 22.05k */
- {11289600, 22050, 512, 0x1a, 0x0},
-
- /* 32k */
- {12288000, 32000, 384, 0xc, 0x0},
-
- /* 44.1k */
- {11289600, 44100, 256, 0x10, 0x0},
-
- /* 48k */
- {12288000, 48000, 256, 0x0, 0x0},
-
- /* 88.2k */
- {11289600, 88200, 128, 0x1e, 0x0},
-
- /* 96k */
- {12288000, 96000, 128, 0xe, 0x0},
-};
-
-static inline int get_coeff(int mclk, int rate)
-{
- int i;
-
- DBG_DETAIL("mclk=%d, rate=%d", mclk, rate);
-
- for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
- if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
- return i;
- }
-
- printk(KERN_ERR "vt1602: could not get coeff for mclk %d @ rate %d\n",
- mclk, rate);
- return -EINVAL;
-}
-
-static int vt1602_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
- u16 iface = snd_soc_read(codec, VT1602_IFACE) & 0x1f3;
- //int coeff = get_coeff(vt1602->sysclk, params_rate(params));
-
- DBG_DETAIL();
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= 0x0004;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface |= 0x0008;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- iface |= 0x000c;
- break;
- }
-
- /* set iface & srate */
- snd_soc_write(codec, VT1602_IFACE, iface);
-
- return 0;
-}
-
-static int vt1602_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
- u16 mute_reg = snd_soc_read(codec, VT1602_ADCDAC) & 0xfff7;
-
- DBG_DETAIL();
-
- if (mute)
- snd_soc_write(codec, VT1602_ADCDAC, mute_reg | 0x8);
- else
- snd_soc_write(codec, VT1602_ADCDAC, mute_reg);
- return 0;
-}
-
-static int vt1602_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct vt1602_priv *vt1602 = snd_soc_codec_get_drvdata(codec);
-
- DBG_DETAIL();
-
- switch (freq) {
- case 11289600:
- case 12000000:
- case 12288000:
- case 16934400:
- case 18432000:
- vt1602->sysclk = freq;
- return 0;
- }
- return -EINVAL;
-}
-
-static int vt1602_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 iface = 0;
-
- DBG_DETAIL();
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- iface = 0x0040;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- iface |= 0x0002;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= 0x0001;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= 0x0003;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- iface |= 0x0013;
- break;
- default:
- return -EINVAL;
- }
-
- /* clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- iface |= 0x0090;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= 0x0080;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- iface |= 0x0010;
- break;
- default:
- return -EINVAL;
- }
-
- snd_soc_write(codec, VT1602_IFACE, iface);
- return 0;
-}
-
-static int vt1602_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level )
-{
- DBG_DETAIL();
-
- switch (level) {
- case SND_SOC_BIAS_ON:
- /* set vmid to 50k and unmute dac */
- break;
- case SND_SOC_BIAS_PREPARE:
- /* set vmid to 5k for quick power up */
- break;
- case SND_SOC_BIAS_STANDBY:
- /* mute dac and set vmid to 500k, enable VREF */
- break;
- case SND_SOC_BIAS_OFF:
- break;
- }
- codec->dapm.bias_level = level;
- return 0;
-}
-
-static void vt1602_work(struct work_struct *work)
-{
- struct snd_soc_codec *codec =
- container_of(work, struct snd_soc_codec, dapm.delayed_work.work);
-
- DBG_DETAIL();
-
- vt1602_set_bias_level(codec, codec->dapm.bias_level);
-}
-
-#define VT1602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | \
- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | \
- SNDRV_PCM_RATE_96000)
-
-#define VT1602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_FLOAT)
-
-static const struct snd_soc_dai_ops vt1602_dai_ops = {
- .hw_params = vt1602_pcm_hw_params,
- .digital_mute = vt1602_mute,
- .set_sysclk = vt1602_set_dai_sysclk,
- .set_fmt = vt1602_set_dai_fmt,
-};
-
-struct snd_soc_dai_driver vt1602_dai = {
- .name = "VT1602",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = VT1602_RATES,
- .formats = VT1602_FORMATS,},
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = VT1602_RATES,
- .formats = VT1602_FORMATS,},
- .ops = &vt1602_dai_ops,
-};
-
-static int vt1602_suspend(struct snd_soc_codec *codec)
-{
- DBG_DETAIL();
-
- vt1602_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int vt1602_resume(struct snd_soc_codec *codec)
-{
- DBG_DETAIL();
-
- snd_soc_cache_sync(codec);
- vt1602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* charge vt1602 caps */
- if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
- vt1602_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
- codec->dapm.bias_level = SND_SOC_BIAS_ON;
- schedule_delayed_work(&codec->dapm.delayed_work,
- msecs_to_jiffies(1000));
- }
-
- return 0;
-}
-
-static int wmt_vt1602_init(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret, reg;
-
- DBG_DETAIL();
-
- /* charge output caps */
- vt1602_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
- codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
- schedule_delayed_work(&codec->dapm.delayed_work, msecs_to_jiffies(1000));
-
- /* set the update bits */
- reg = snd_soc_read(codec, VT1602_LDAC);
- snd_soc_write(codec, VT1602_LDAC, reg | 0x0100);
- reg = snd_soc_read(codec, VT1602_RDAC);
- snd_soc_write(codec, VT1602_RDAC, reg | 0x0100);
- reg = snd_soc_read(codec, VT1602_LOUT1V);
- snd_soc_write(codec, VT1602_LOUT1V, reg | 0x0100);
- reg = snd_soc_read(codec, VT1602_ROUT1V);
- snd_soc_write(codec, VT1602_ROUT1V, reg | 0x0100);
- reg = snd_soc_read(codec, VT1602_LOUT2V);
- snd_soc_write(codec, VT1602_LOUT2V, reg | 0x0100);
- reg = snd_soc_read(codec, VT1602_ROUT2V);
- snd_soc_write(codec, VT1602_ROUT2V, reg | 0x0100);
- reg = snd_soc_read(codec, VT1602_LINVOL);
- snd_soc_write(codec, VT1602_LINVOL, reg | 0x0100);
- reg = snd_soc_read(codec, VT1602_RINVOL);
- snd_soc_write(codec, VT1602_RINVOL, reg | 0x0100);
- reg = snd_soc_read(codec, VT1602_LOUTM1);
- snd_soc_write(codec, VT1602_LOUTM1, reg);
- reg = snd_soc_read(codec, VT1602_LOUTM2);
- snd_soc_write(codec, VT1602_LOUTM2, reg);
- reg = snd_soc_read(codec, VT1602_ROUTM1);
- snd_soc_write(codec, VT1602_ROUTM1, reg);
- reg = snd_soc_read(codec, VT1602_ROUTM2);
- snd_soc_write(codec, VT1602_ROUTM2, reg);
- snd_soc_write(codec, VT1602_PWR1, 0x1FE);
- snd_soc_write(codec, VT1602_PWR2, 0x1E0);
- snd_soc_write(codec, VT1602_LADCIN, 0x020);
- snd_soc_write(codec, VT1602_RADCIN, 0x020);
- snd_soc_write(codec, VT1602_ADCTL3, 0x040);
-
- ret = snd_soc_add_codec_controls(codec, vt1602_snd_controls,
- ARRAY_SIZE(vt1602_snd_controls));
- if (ret) {
- info("snd_soc_add_codec_controls fail");
- return ret;
- }
-
- ret = snd_soc_dapm_new_controls(dapm, vt1602_dapm_widgets,
- ARRAY_SIZE(vt1602_dapm_widgets));
- if (ret) {
- info("snd_soc_dapm_new_controls fail");
- return ret;
- }
-
- ret = snd_soc_dapm_add_routes(dapm, audio_map,
- ARRAY_SIZE(audio_map));
- if (ret) {
- info("snd_soc_dapm_add_routes fail");
- return 0;
- }
-
- return ret;
-}
-
-static int vt1602_probe(struct snd_soc_codec *codec)
-{
- struct vt1602_priv *vt1602 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- pr_info("VT1602 Audio Codec %s\n", VT1602_VERSION);
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, vt1602->control_type);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- return ret;
- }
-
- ret = vt1602_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
- return ret;
- }
-
- INIT_DELAYED_WORK(&codec->dapm.delayed_work, vt1602_work);
-
- ret = wmt_vt1602_init(codec);
- if (ret)
- info("vt1602_probe fail");
- return ret;
-}
-
-/*
- * This function forces any delayed work to be queued and run.
- */
-static int run_delayed_work(struct delayed_work *dwork)
-{
- int ret;
-
- DBG_DETAIL();
-
- /* cancel any work waiting to be queued. */
- ret = cancel_delayed_work(dwork);
-
- /* if there was any work waiting then we run it now and
- * wait for it's completion */
- if (ret) {
- schedule_delayed_work(dwork, 0);
- flush_scheduled_work();
- }
- return ret;
-}
-
-/* remove everything here */
-static int vt1602_remove(struct snd_soc_codec *codec)
-{
- DBG_DETAIL();
-
- vt1602_set_bias_level(codec, SND_SOC_BIAS_OFF);
- run_delayed_work(&codec->dapm.delayed_work);
-
- return 0;
-}
-
-static struct snd_soc_codec_driver soc_codec_dev_vt1602 = {
- .probe = vt1602_probe,
- .remove = vt1602_remove,
- .suspend = vt1602_suspend,
- .resume = vt1602_resume,
- .set_bias_level = vt1602_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(vt1602_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = vt1602_reg,
-
- /*.controls = vt1602_snd_controls,
- .num_controls = ARRAY_SIZE(vt1602_snd_controls),
- .dapm_widgets = vt1602_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(vt1602_dapm_widgets),
- .dapm_routes = audio_map,
- .num_dapm_routes = ARRAY_SIZE(audio_map),*/
-};
-
-#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
-static int __devinit vt1602_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct vt1602_priv *vt1602;
- int ret;
-
- DBG_DETAIL();
-
- vt1602 = devm_kzalloc(&i2c->dev, sizeof(struct vt1602_priv), GFP_KERNEL);
- if (vt1602 == NULL) {
- info("vt1602_i2c_probe kzalloc fail");
- return -ENOMEM;
- }
-
- i2c_set_clientdata(i2c, vt1602);
- vt1602->control_type = SND_SOC_I2C;
-
- ret = snd_soc_register_codec(&i2c->dev,
- &soc_codec_dev_vt1602, &vt1602_dai, 1);
-
- return ret;
-}
-
-static int __devexit vt1602_i2c_remove(struct i2c_client *client)
-{
- DBG_DETAIL();
-
- snd_soc_unregister_codec(&client->dev);
-
- return 0;
-}
-
-static const struct i2c_device_id vt1602_i2c_id[] = {
- { "vt1602", 1},
- { }
-};
-MODULE_DEVICE_TABLE(i2c, vt1602_i2c_id);
-
-/* corgi i2c codec control layer */
-static struct i2c_driver vt1602_i2c_driver = {
- .driver = {
- .name = "vt1602",
- .owner = THIS_MODULE,
- },
- .probe = vt1602_i2c_probe,
- .remove = __devexit_p(vt1602_i2c_remove),
- .id_table = vt1602_i2c_id,
-};
-#endif
-
-static struct i2c_board_info __initdata wmt_vt1602_board_info[] = {
- {
- I2C_BOARD_INFO("vt1602", 0x1a),
- },
-};
-
-static int __init vt1602_modinit(void)
-{
- char buf[80];
- int varlen = 80;
- int ret = 0;
- char codec_name[6];
- struct i2c_adapter *adapter = NULL;
-
- DBG_DETAIL();
-
- ret = wmt_getsyspara("wmt.audio.i2s", buf, &varlen);
-
- if (ret == 0) {
- sscanf(buf, "%6s", codec_name);
-
- if (strcmp(codec_name, "vt1602")) {
- info("vt1602 string not found");
- return -EINVAL;
- }
- }
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- /*i2c_register_board_info(1, wmt_vt1602_board_info,
- ARRAY_SIZE(wmt_vt1602_board_info));*/
-
- adapter = i2c_get_adapter(1);
- if (adapter == NULL) {
- err("can not get i2c adapter, client address error");
- return -ENODEV;
- }
-
- if (i2c_new_device(adapter, wmt_vt1602_board_info) == NULL) {
- err("allocate i2c client failed");
- return -ENOMEM;
- }
-
- i2c_put_adapter(adapter);
-
- ret = i2c_add_driver(&vt1602_i2c_driver);
- if (ret) {
- info("i2c_add_driver fail");
- }
-#endif
-
- return ret;
-}
-module_init(vt1602_modinit);
-
-static void __exit vt1602_exit(void)
-{
- DBG_DETAIL();
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_del_driver(&vt1602_i2c_driver);
-#endif
-}
-module_exit(vt1602_exit);
-
-MODULE_DESCRIPTION("WMT [ALSA SoC] driver");
-MODULE_AUTHOR("WonderMedia Technologies, Inc.");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/codecs/wmt_vt1602.h b/ANDROID_3.4.5/sound/soc/codecs/wmt_vt1602.h
deleted file mode 100755
index 718c822a..00000000
--- a/ANDROID_3.4.5/sound/soc/codecs/wmt_vt1602.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*++
- * linux/sound/soc/codecs/wmt_vt1602.h
- * WonderMedia I2S audio driver for ALSA
- *
- * Copyright c 2010 WonderMedia Technologies, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * WonderMedia Technologies, Inc.
- * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
---*/
-
-
-#ifndef _VT1602_H
-#define _VT1602_H
-
-/* VT1602 register space */
-
-#define VT1602_LINVOL 0x00
-#define VT1602_RINVOL 0x01
-#define VT1602_LOUT1V 0x02
-#define VT1602_ROUT1V 0x03
-#define VT1602_ADCDAC 0x05
-#define VT1602_IFACE 0x07
-#define VT1602_SRATE 0x08
-#define VT1602_LDAC 0x0a
-#define VT1602_RDAC 0x0b
-#define VT1602_BASS 0x0c
-#define VT1602_TREBLE 0x0d
-#define VT1602_RESET 0x0f
-#define VT1602_3D 0x10
-#define VT1602_ALC1 0x11
-#define VT1602_ALC2 0x12
-#define VT1602_ALC3 0x13
-#define VT1602_NGATE 0x14
-#define VT1602_LADC 0x15
-#define VT1602_RADC 0x16
-#define VT1602_ADCTL1 0x17
-#define VT1602_ADCTL2 0x18
-#define VT1602_PWR1 0x19
-#define VT1602_PWR2 0x1a
-#define VT1602_ADCTL3 0x1b
-#define VT1602_ADCIN 0x1f
-#define VT1602_LADCIN 0x20
-#define VT1602_RADCIN 0x21
-#define VT1602_LOUTM1 0x22
-#define VT1602_LOUTM2 0x23
-#define VT1602_ROUTM1 0x24
-#define VT1602_ROUTM2 0x25
-#define VT1602_MOUTM1 0x26
-#define VT1602_MOUTM2 0x27
-#define VT1602_LOUT2V 0x28
-#define VT1602_ROUT2V 0x29
-#define VT1602_MOUTV 0x2a
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/davinci/Kconfig b/ANDROID_3.4.5/sound/soc/davinci/Kconfig
deleted file mode 100644
index 9e11a14d..00000000
--- a/ANDROID_3.4.5/sound/soc/davinci/Kconfig
+++ /dev/null
@@ -1,85 +0,0 @@
-config SND_DAVINCI_SOC
- tristate "SoC Audio for the TI DAVINCI chip"
- depends on ARCH_DAVINCI
- help
- Say Y or M if you want to add support for codecs attached to
- the DAVINCI AC97 or I2S interface. You will also need
- to select the audio interfaces to support below.
-
-config SND_DAVINCI_SOC_I2S
- tristate
-
-config SND_DAVINCI_SOC_MCASP
- tristate
-
-config SND_DAVINCI_SOC_VCIF
- tristate
-
-config SND_DAVINCI_SOC_EVM
- tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM"
- depends on SND_DAVINCI_SOC
- depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM || MACH_DAVINCI_DM365_EVM
- select SND_DAVINCI_SOC_I2S
- select SND_SOC_TLV320AIC3X
- help
- Say Y if you want to add support for SoC audio on TI
- DaVinci DM6446, DM355 or DM365 EVM platforms.
-
-choice
- prompt "DM365 codec select"
- depends on SND_DAVINCI_SOC_EVM
- depends on MACH_DAVINCI_DM365_EVM
-
-config SND_DM365_AIC3X_CODEC
- bool "Audio Codec - AIC3101"
- help
- Say Y if you want to add support for AIC3101 audio codec
-
-config SND_DM365_VOICE_CODEC
- bool "Voice Codec - CQ93VC"
- select MFD_DAVINCI_VOICECODEC
- select SND_DAVINCI_SOC_VCIF
- select SND_SOC_CQ0093VC
- help
- Say Y if you want to add support for SoC On-chip voice codec
-endchoice
-
-config SND_DM6467_SOC_EVM
- tristate "SoC Audio support for DaVinci DM6467 EVM"
- depends on SND_DAVINCI_SOC && MACH_DAVINCI_DM6467_EVM
- select SND_DAVINCI_SOC_MCASP
- select SND_SOC_TLV320AIC3X
- select SND_SOC_SPDIF
-
- help
- Say Y if you want to add support for SoC audio on TI
-
-config SND_DAVINCI_SOC_SFFSDR
- tristate "SoC Audio support for SFFSDR"
- depends on SND_DAVINCI_SOC && MACH_SFFSDR
- select SND_DAVINCI_SOC_I2S
- select SND_SOC_PCM3008
- select SFFSDR_FPGA
- help
- Say Y if you want to add support for SoC audio on
- Lyrtech SFFSDR board.
-
-config SND_DA830_SOC_EVM
- tristate "SoC Audio support for DA830/OMAP-L137 EVM"
- depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA830_EVM
- select SND_DAVINCI_SOC_MCASP
- select SND_SOC_TLV320AIC3X
-
- help
- Say Y if you want to add support for SoC audio on TI
- DA830/OMAP-L137 EVM
-
-config SND_DA850_SOC_EVM
- tristate "SoC Audio support for DA850/OMAP-L138 EVM"
- depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM
- select SND_DAVINCI_SOC_MCASP
- select SND_SOC_TLV320AIC3X
- help
- Say Y if you want to add support for SoC audio on TI
- DA850/OMAP-L138 EVM
-
diff --git a/ANDROID_3.4.5/sound/soc/davinci/Makefile b/ANDROID_3.4.5/sound/soc/davinci/Makefile
deleted file mode 100644
index a93679d6..00000000
--- a/ANDROID_3.4.5/sound/soc/davinci/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-# DAVINCI Platform Support
-snd-soc-davinci-objs := davinci-pcm.o
-snd-soc-davinci-i2s-objs := davinci-i2s.o
-snd-soc-davinci-mcasp-objs:= davinci-mcasp.o
-snd-soc-davinci-vcif-objs:= davinci-vcif.o
-
-obj-$(CONFIG_SND_DAVINCI_SOC) += snd-soc-davinci.o
-obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o
-obj-$(CONFIG_SND_DAVINCI_SOC_MCASP) += snd-soc-davinci-mcasp.o
-obj-$(CONFIG_SND_DAVINCI_SOC_VCIF) += snd-soc-davinci-vcif.o
-
-# DAVINCI Machine Support
-snd-soc-evm-objs := davinci-evm.o
-snd-soc-sffsdr-objs := davinci-sffsdr.o
-
-obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o
-obj-$(CONFIG_SND_DM6467_SOC_EVM) += snd-soc-evm.o
-obj-$(CONFIG_SND_DA830_SOC_EVM) += snd-soc-evm.o
-obj-$(CONFIG_SND_DA850_SOC_EVM) += snd-soc-evm.o
-obj-$(CONFIG_SND_DAVINCI_SOC_SFFSDR) += snd-soc-sffsdr.o
diff --git a/ANDROID_3.4.5/sound/soc/davinci/davinci-evm.c b/ANDROID_3.4.5/sound/soc/davinci/davinci-evm.c
deleted file mode 100644
index 10a2d8c7..00000000
--- a/ANDROID_3.4.5/sound/soc/davinci/davinci-evm.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * ASoC driver for TI DAVINCI EVM platform
- *
- * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
- * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/dma.h>
-#include <asm/mach-types.h>
-
-#include <mach/asp.h>
-#include <mach/edma.h>
-#include <mach/mux.h>
-
-#include "davinci-pcm.h"
-#include "davinci-i2s.h"
-#include "davinci-mcasp.h"
-
-#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
- SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF)
-static int evm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
- unsigned sysclk;
-
- /* ASP1 on DM355 EVM is clocked by an external oscillator */
- if (machine_is_davinci_dm355_evm() || machine_is_davinci_dm6467_evm() ||
- machine_is_davinci_dm365_evm())
- sysclk = 27000000;
-
- /* ASP0 in DM6446 EVM is clocked by U55, as configured by
- * board-dm644x-evm.c using GPIOs from U18. There are six
- * options; here we "know" we use a 48 KHz sample rate.
- */
- else if (machine_is_davinci_evm())
- sysclk = 12288000;
-
- else if (machine_is_davinci_da830_evm() ||
- machine_is_davinci_da850_evm())
- sysclk = 24576000;
-
- else
- return -EINVAL;
-
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, AUDIO_FORMAT);
- if (ret < 0)
- return ret;
-
- /* set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT);
- if (ret < 0)
- return ret;
-
- /* set the codec system clock */
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_OUT);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int evm_spdif_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-
- /* set cpu DAI configuration */
- return snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT);
-}
-
-static struct snd_soc_ops evm_ops = {
- .hw_params = evm_hw_params,
-};
-
-static struct snd_soc_ops evm_spdif_ops = {
- .hw_params = evm_spdif_hw_params,
-};
-
-/* davinci-evm machine dapm widgets */
-static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_LINE("Line Out", NULL),
- SND_SOC_DAPM_MIC("Mic Jack", NULL),
- SND_SOC_DAPM_LINE("Line In", NULL),
-};
-
-/* davinci-evm machine audio_mapnections to the codec pins */
-static const struct snd_soc_dapm_route audio_map[] = {
- /* Headphone connected to HPLOUT, HPROUT */
- {"Headphone Jack", NULL, "HPLOUT"},
- {"Headphone Jack", NULL, "HPROUT"},
-
- /* Line Out connected to LLOUT, RLOUT */
- {"Line Out", NULL, "LLOUT"},
- {"Line Out", NULL, "RLOUT"},
-
- /* Mic connected to (MIC3L | MIC3R) */
- {"MIC3L", NULL, "Mic Bias 2V"},
- {"MIC3R", NULL, "Mic Bias 2V"},
- {"Mic Bias 2V", NULL, "Mic Jack"},
-
- /* Line In connected to (LINE1L | LINE2L), (LINE1R | LINE2R) */
- {"LINE1L", NULL, "Line In"},
- {"LINE2L", NULL, "Line In"},
- {"LINE1R", NULL, "Line In"},
- {"LINE2R", NULL, "Line In"},
-};
-
-/* Logic for a aic3x as connected on a davinci-evm */
-static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- /* Add davinci-evm specific widgets */
- snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
- ARRAY_SIZE(aic3x_dapm_widgets));
-
- /* Set up davinci-evm specific audio path audio_map */
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
- /* not connected */
- snd_soc_dapm_disable_pin(dapm, "MONO_LOUT");
- snd_soc_dapm_disable_pin(dapm, "HPLCOM");
- snd_soc_dapm_disable_pin(dapm, "HPRCOM");
-
- /* always connected */
- snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_enable_pin(dapm, "Line Out");
- snd_soc_dapm_enable_pin(dapm, "Mic Jack");
- snd_soc_dapm_enable_pin(dapm, "Line In");
-
- return 0;
-}
-
-/* davinci-evm digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link dm6446_evm_dai = {
- .name = "TLV320AIC3X",
- .stream_name = "AIC3X",
- .cpu_dai_name = "davinci-mcbsp",
- .codec_dai_name = "tlv320aic3x-hifi",
- .codec_name = "tlv320aic3x-codec.1-001b",
- .platform_name = "davinci-pcm-audio",
- .init = evm_aic3x_init,
- .ops = &evm_ops,
-};
-
-static struct snd_soc_dai_link dm355_evm_dai = {
- .name = "TLV320AIC3X",
- .stream_name = "AIC3X",
- .cpu_dai_name = "davinci-mcbsp.1",
- .codec_dai_name = "tlv320aic3x-hifi",
- .codec_name = "tlv320aic3x-codec.1-001b",
- .platform_name = "davinci-pcm-audio",
- .init = evm_aic3x_init,
- .ops = &evm_ops,
-};
-
-static struct snd_soc_dai_link dm365_evm_dai = {
-#ifdef CONFIG_SND_DM365_AIC3X_CODEC
- .name = "TLV320AIC3X",
- .stream_name = "AIC3X",
- .cpu_dai_name = "davinci-mcbsp",
- .codec_dai_name = "tlv320aic3x-hifi",
- .init = evm_aic3x_init,
- .codec_name = "tlv320aic3x-codec.1-0018",
- .ops = &evm_ops,
-#elif defined(CONFIG_SND_DM365_VOICE_CODEC)
- .name = "Voice Codec - CQ93VC",
- .stream_name = "CQ93",
- .cpu_dai_name = "davinci-vcif",
- .codec_dai_name = "cq93vc-hifi",
- .codec_name = "cq93vc-codec",
-#endif
- .platform_name = "davinci-pcm-audio",
-};
-
-static struct snd_soc_dai_link dm6467_evm_dai[] = {
- {
- .name = "TLV320AIC3X",
- .stream_name = "AIC3X",
- .cpu_dai_name= "davinci-mcasp.0",
- .codec_dai_name = "tlv320aic3x-hifi",
- .platform_name ="davinci-pcm-audio",
- .codec_name = "tlv320aic3x-codec.0-001a",
- .init = evm_aic3x_init,
- .ops = &evm_ops,
- },
- {
- .name = "McASP",
- .stream_name = "spdif",
- .cpu_dai_name= "davinci-mcasp.1",
- .codec_dai_name = "dit-hifi",
- .codec_name = "spdif_dit",
- .platform_name = "davinci-pcm-audio",
- .ops = &evm_spdif_ops,
- },
-};
-
-static struct snd_soc_dai_link da830_evm_dai = {
- .name = "TLV320AIC3X",
- .stream_name = "AIC3X",
- .cpu_dai_name = "davinci-mcasp.1",
- .codec_dai_name = "tlv320aic3x-hifi",
- .codec_name = "tlv320aic3x-codec.1-0018",
- .platform_name = "davinci-pcm-audio",
- .init = evm_aic3x_init,
- .ops = &evm_ops,
-};
-
-static struct snd_soc_dai_link da850_evm_dai = {
- .name = "TLV320AIC3X",
- .stream_name = "AIC3X",
- .cpu_dai_name= "davinci-mcasp.0",
- .codec_dai_name = "tlv320aic3x-hifi",
- .codec_name = "tlv320aic3x-codec.1-0018",
- .platform_name = "davinci-pcm-audio",
- .init = evm_aic3x_init,
- .ops = &evm_ops,
-};
-
-/* davinci dm6446 evm audio machine driver */
-static struct snd_soc_card dm6446_snd_soc_card_evm = {
- .name = "DaVinci DM6446 EVM",
- .owner = THIS_MODULE,
- .dai_link = &dm6446_evm_dai,
- .num_links = 1,
-};
-
-/* davinci dm355 evm audio machine driver */
-static struct snd_soc_card dm355_snd_soc_card_evm = {
- .name = "DaVinci DM355 EVM",
- .owner = THIS_MODULE,
- .dai_link = &dm355_evm_dai,
- .num_links = 1,
-};
-
-/* davinci dm365 evm audio machine driver */
-static struct snd_soc_card dm365_snd_soc_card_evm = {
- .name = "DaVinci DM365 EVM",
- .owner = THIS_MODULE,
- .dai_link = &dm365_evm_dai,
- .num_links = 1,
-};
-
-/* davinci dm6467 evm audio machine driver */
-static struct snd_soc_card dm6467_snd_soc_card_evm = {
- .name = "DaVinci DM6467 EVM",
- .owner = THIS_MODULE,
- .dai_link = dm6467_evm_dai,
- .num_links = ARRAY_SIZE(dm6467_evm_dai),
-};
-
-static struct snd_soc_card da830_snd_soc_card = {
- .name = "DA830/OMAP-L137 EVM",
- .owner = THIS_MODULE,
- .dai_link = &da830_evm_dai,
- .num_links = 1,
-};
-
-static struct snd_soc_card da850_snd_soc_card = {
- .name = "DA850/OMAP-L138 EVM",
- .owner = THIS_MODULE,
- .dai_link = &da850_evm_dai,
- .num_links = 1,
-};
-
-static struct platform_device *evm_snd_device;
-
-static int __init evm_init(void)
-{
- struct snd_soc_card *evm_snd_dev_data;
- int index;
- int ret;
-
- if (machine_is_davinci_evm()) {
- evm_snd_dev_data = &dm6446_snd_soc_card_evm;
- index = 0;
- } else if (machine_is_davinci_dm355_evm()) {
- evm_snd_dev_data = &dm355_snd_soc_card_evm;
- index = 1;
- } else if (machine_is_davinci_dm365_evm()) {
- evm_snd_dev_data = &dm365_snd_soc_card_evm;
- index = 0;
- } else if (machine_is_davinci_dm6467_evm()) {
- evm_snd_dev_data = &dm6467_snd_soc_card_evm;
- index = 0;
- } else if (machine_is_davinci_da830_evm()) {
- evm_snd_dev_data = &da830_snd_soc_card;
- index = 1;
- } else if (machine_is_davinci_da850_evm()) {
- evm_snd_dev_data = &da850_snd_soc_card;
- index = 0;
- } else
- return -EINVAL;
-
- evm_snd_device = platform_device_alloc("soc-audio", index);
- if (!evm_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(evm_snd_device, evm_snd_dev_data);
- ret = platform_device_add(evm_snd_device);
- if (ret)
- platform_device_put(evm_snd_device);
-
- return ret;
-}
-
-static void __exit evm_exit(void)
-{
- platform_device_unregister(evm_snd_device);
-}
-
-module_init(evm_init);
-module_exit(evm_exit);
-
-MODULE_AUTHOR("Vladimir Barinov");
-MODULE_DESCRIPTION("TI DAVINCI EVM ASoC driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/davinci/davinci-i2s.c b/ANDROID_3.4.5/sound/soc/davinci/davinci-i2s.c
deleted file mode 100644
index 0a74b958..00000000
--- a/ANDROID_3.4.5/sound/soc/davinci/davinci-i2s.c
+++ /dev/null
@@ -1,768 +0,0 @@
-/*
- * ALSA SoC I2S (McBSP) Audio Layer for TI DAVINCI processor
- *
- * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
- * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include <mach/asp.h>
-
-#include "davinci-pcm.h"
-#include "davinci-i2s.h"
-
-
-/*
- * NOTE: terminology here is confusing.
- *
- * - This driver supports the "Audio Serial Port" (ASP),
- * found on dm6446, dm355, and other DaVinci chips.
- *
- * - But it labels it a "Multi-channel Buffered Serial Port"
- * (McBSP) as on older chips like the dm642 ... which was
- * backward-compatible, possibly explaining that confusion.
- *
- * - OMAP chips have a controller called McBSP, which is
- * incompatible with the DaVinci flavor of McBSP.
- *
- * - Newer DaVinci chips have a controller called McASP,
- * incompatible with ASP and with either McBSP.
- *
- * In short: this uses ASP to implement I2S, not McBSP.
- * And it won't be the only DaVinci implemention of I2S.
- */
-#define DAVINCI_MCBSP_DRR_REG 0x00
-#define DAVINCI_MCBSP_DXR_REG 0x04
-#define DAVINCI_MCBSP_SPCR_REG 0x08
-#define DAVINCI_MCBSP_RCR_REG 0x0c
-#define DAVINCI_MCBSP_XCR_REG 0x10
-#define DAVINCI_MCBSP_SRGR_REG 0x14
-#define DAVINCI_MCBSP_PCR_REG 0x24
-
-#define DAVINCI_MCBSP_SPCR_RRST (1 << 0)
-#define DAVINCI_MCBSP_SPCR_RINTM(v) ((v) << 4)
-#define DAVINCI_MCBSP_SPCR_XRST (1 << 16)
-#define DAVINCI_MCBSP_SPCR_XINTM(v) ((v) << 20)
-#define DAVINCI_MCBSP_SPCR_GRST (1 << 22)
-#define DAVINCI_MCBSP_SPCR_FRST (1 << 23)
-#define DAVINCI_MCBSP_SPCR_FREE (1 << 25)
-
-#define DAVINCI_MCBSP_RCR_RWDLEN1(v) ((v) << 5)
-#define DAVINCI_MCBSP_RCR_RFRLEN1(v) ((v) << 8)
-#define DAVINCI_MCBSP_RCR_RDATDLY(v) ((v) << 16)
-#define DAVINCI_MCBSP_RCR_RFIG (1 << 18)
-#define DAVINCI_MCBSP_RCR_RWDLEN2(v) ((v) << 21)
-#define DAVINCI_MCBSP_RCR_RFRLEN2(v) ((v) << 24)
-#define DAVINCI_MCBSP_RCR_RPHASE BIT(31)
-
-#define DAVINCI_MCBSP_XCR_XWDLEN1(v) ((v) << 5)
-#define DAVINCI_MCBSP_XCR_XFRLEN1(v) ((v) << 8)
-#define DAVINCI_MCBSP_XCR_XDATDLY(v) ((v) << 16)
-#define DAVINCI_MCBSP_XCR_XFIG (1 << 18)
-#define DAVINCI_MCBSP_XCR_XWDLEN2(v) ((v) << 21)
-#define DAVINCI_MCBSP_XCR_XFRLEN2(v) ((v) << 24)
-#define DAVINCI_MCBSP_XCR_XPHASE BIT(31)
-
-#define DAVINCI_MCBSP_SRGR_FWID(v) ((v) << 8)
-#define DAVINCI_MCBSP_SRGR_FPER(v) ((v) << 16)
-#define DAVINCI_MCBSP_SRGR_FSGM (1 << 28)
-#define DAVINCI_MCBSP_SRGR_CLKSM BIT(29)
-
-#define DAVINCI_MCBSP_PCR_CLKRP (1 << 0)
-#define DAVINCI_MCBSP_PCR_CLKXP (1 << 1)
-#define DAVINCI_MCBSP_PCR_FSRP (1 << 2)
-#define DAVINCI_MCBSP_PCR_FSXP (1 << 3)
-#define DAVINCI_MCBSP_PCR_SCLKME (1 << 7)
-#define DAVINCI_MCBSP_PCR_CLKRM (1 << 8)
-#define DAVINCI_MCBSP_PCR_CLKXM (1 << 9)
-#define DAVINCI_MCBSP_PCR_FSRM (1 << 10)
-#define DAVINCI_MCBSP_PCR_FSXM (1 << 11)
-
-enum {
- DAVINCI_MCBSP_WORD_8 = 0,
- DAVINCI_MCBSP_WORD_12,
- DAVINCI_MCBSP_WORD_16,
- DAVINCI_MCBSP_WORD_20,
- DAVINCI_MCBSP_WORD_24,
- DAVINCI_MCBSP_WORD_32,
-};
-
-static const unsigned char data_type[SNDRV_PCM_FORMAT_S32_LE + 1] = {
- [SNDRV_PCM_FORMAT_S8] = 1,
- [SNDRV_PCM_FORMAT_S16_LE] = 2,
- [SNDRV_PCM_FORMAT_S32_LE] = 4,
-};
-
-static const unsigned char asp_word_length[SNDRV_PCM_FORMAT_S32_LE + 1] = {
- [SNDRV_PCM_FORMAT_S8] = DAVINCI_MCBSP_WORD_8,
- [SNDRV_PCM_FORMAT_S16_LE] = DAVINCI_MCBSP_WORD_16,
- [SNDRV_PCM_FORMAT_S32_LE] = DAVINCI_MCBSP_WORD_32,
-};
-
-static const unsigned char double_fmt[SNDRV_PCM_FORMAT_S32_LE + 1] = {
- [SNDRV_PCM_FORMAT_S8] = SNDRV_PCM_FORMAT_S16_LE,
- [SNDRV_PCM_FORMAT_S16_LE] = SNDRV_PCM_FORMAT_S32_LE,
-};
-
-struct davinci_mcbsp_dev {
- struct device *dev;
- struct davinci_pcm_dma_params dma_params[2];
- void __iomem *base;
-#define MOD_DSP_A 0
-#define MOD_DSP_B 1
- int mode;
- u32 pcr;
- struct clk *clk;
- /*
- * Combining both channels into 1 element will at least double the
- * amount of time between servicing the dma channel, increase
- * effiency, and reduce the chance of overrun/underrun. But,
- * it will result in the left & right channels being swapped.
- *
- * If relabeling the left and right channels is not possible,
- * you may want to let the codec know to swap them back.
- *
- * It may allow x10 the amount of time to service dma requests,
- * if the codec is master and is using an unnecessarily fast bit clock
- * (ie. tlvaic23b), independent of the sample rate. So, having an
- * entire frame at once means it can be serviced at the sample rate
- * instead of the bit clock rate.
- *
- * In the now unlikely case that an underrun still
- * occurs, both the left and right samples will be repeated
- * so that no pops are heard, and the left and right channels
- * won't end up being swapped because of the underrun.
- */
- unsigned enable_channel_combine:1;
-
- unsigned int fmt;
- int clk_div;
- int clk_input_pin;
- bool i2s_accurate_sck;
-};
-
-static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev,
- int reg, u32 val)
-{
- __raw_writel(val, dev->base + reg);
-}
-
-static inline u32 davinci_mcbsp_read_reg(struct davinci_mcbsp_dev *dev, int reg)
-{
- return __raw_readl(dev->base + reg);
-}
-
-static void toggle_clock(struct davinci_mcbsp_dev *dev, int playback)
-{
- u32 m = playback ? DAVINCI_MCBSP_PCR_CLKXP : DAVINCI_MCBSP_PCR_CLKRP;
- /* The clock needs to toggle to complete reset.
- * So, fake it by toggling the clk polarity.
- */
- davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, dev->pcr ^ m);
- davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, dev->pcr);
-}
-
-static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev,
- struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_platform *platform = rtd->platform;
- int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
- u32 spcr;
- u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST;
- spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
- if (spcr & mask) {
- /* start off disabled */
- davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG,
- spcr & ~mask);
- toggle_clock(dev, playback);
- }
- if (dev->pcr & (DAVINCI_MCBSP_PCR_FSXM | DAVINCI_MCBSP_PCR_FSRM |
- DAVINCI_MCBSP_PCR_CLKXM | DAVINCI_MCBSP_PCR_CLKRM)) {
- /* Start the sample generator */
- spcr |= DAVINCI_MCBSP_SPCR_GRST;
- davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
- }
-
- if (playback) {
- /* Stop the DMA to avoid data loss */
- /* while the transmitter is out of reset to handle XSYNCERR */
- if (platform->driver->ops->trigger) {
- int ret = platform->driver->ops->trigger(substream,
- SNDRV_PCM_TRIGGER_STOP);
- if (ret < 0)
- printk(KERN_DEBUG "Playback DMA stop failed\n");
- }
-
- /* Enable the transmitter */
- spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
- spcr |= DAVINCI_MCBSP_SPCR_XRST;
- davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
-
- /* wait for any unexpected frame sync error to occur */
- udelay(100);
-
- /* Disable the transmitter to clear any outstanding XSYNCERR */
- spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
- spcr &= ~DAVINCI_MCBSP_SPCR_XRST;
- davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
- toggle_clock(dev, playback);
-
- /* Restart the DMA */
- if (platform->driver->ops->trigger) {
- int ret = platform->driver->ops->trigger(substream,
- SNDRV_PCM_TRIGGER_START);
- if (ret < 0)
- printk(KERN_DEBUG "Playback DMA start failed\n");
- }
- }
-
- /* Enable transmitter or receiver */
- spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
- spcr |= mask;
-
- if (dev->pcr & (DAVINCI_MCBSP_PCR_FSXM | DAVINCI_MCBSP_PCR_FSRM)) {
- /* Start frame sync */
- spcr |= DAVINCI_MCBSP_SPCR_FRST;
- }
- davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
-}
-
-static void davinci_mcbsp_stop(struct davinci_mcbsp_dev *dev, int playback)
-{
- u32 spcr;
-
- /* Reset transmitter/receiver and sample rate/frame sync generators */
- spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
- spcr &= ~(DAVINCI_MCBSP_SPCR_GRST | DAVINCI_MCBSP_SPCR_FRST);
- spcr &= playback ? ~DAVINCI_MCBSP_SPCR_XRST : ~DAVINCI_MCBSP_SPCR_RRST;
- davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
- toggle_clock(dev, playback);
-}
-
-#define DEFAULT_BITPERSAMPLE 16
-
-static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
- unsigned int fmt)
-{
- struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
- unsigned int pcr;
- unsigned int srgr;
- bool inv_fs = false;
- /* Attention srgr is updated by hw_params! */
- srgr = DAVINCI_MCBSP_SRGR_FSGM |
- DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) |
- DAVINCI_MCBSP_SRGR_FWID(DEFAULT_BITPERSAMPLE - 1);
-
- dev->fmt = fmt;
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- /* cpu is master */
- pcr = DAVINCI_MCBSP_PCR_FSXM |
- DAVINCI_MCBSP_PCR_FSRM |
- DAVINCI_MCBSP_PCR_CLKXM |
- DAVINCI_MCBSP_PCR_CLKRM;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- pcr = DAVINCI_MCBSP_PCR_FSRM | DAVINCI_MCBSP_PCR_FSXM;
- /*
- * Selection of the clock input pin that is the
- * input for the Sample Rate Generator.
- * McBSP FSR and FSX are driven by the Sample Rate
- * Generator.
- */
- switch (dev->clk_input_pin) {
- case MCBSP_CLKS:
- pcr |= DAVINCI_MCBSP_PCR_CLKXM |
- DAVINCI_MCBSP_PCR_CLKRM;
- break;
- case MCBSP_CLKR:
- pcr |= DAVINCI_MCBSP_PCR_SCLKME;
- break;
- default:
- dev_err(dev->dev, "bad clk_input_pin\n");
- return -EINVAL;
- }
-
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- /* codec is master */
- pcr = 0;
- break;
- default:
- printk(KERN_ERR "%s:bad master\n", __func__);
- return -EINVAL;
- }
-
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- /* Davinci doesn't support TRUE I2S, but some codecs will have
- * the left and right channels contiguous. This allows
- * dsp_a mode to be used with an inverted normal frame clk.
- * If your codec is master and does not have contiguous
- * channels, then you will have sound on only one channel.
- * Try using a different mode, or codec as slave.
- *
- * The TLV320AIC33 is an example of a codec where this works.
- * It has a variable bit clock frequency allowing it to have
- * valid data on every bit clock.
- *
- * The TLV320AIC23 is an example of a codec where this does not
- * work. It has a fixed bit clock frequency with progressively
- * more empty bit clock slots between channels as the sample
- * rate is lowered.
- */
- inv_fs = true;
- case SND_SOC_DAIFMT_DSP_A:
- dev->mode = MOD_DSP_A;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- dev->mode = MOD_DSP_B;
- break;
- default:
- printk(KERN_ERR "%s:bad format\n", __func__);
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- /* CLKRP Receive clock polarity,
- * 1 - sampled on rising edge of CLKR
- * valid on rising edge
- * CLKXP Transmit clock polarity,
- * 1 - clocked on falling edge of CLKX
- * valid on rising edge
- * FSRP Receive frame sync pol, 0 - active high
- * FSXP Transmit frame sync pol, 0 - active high
- */
- pcr |= (DAVINCI_MCBSP_PCR_CLKXP | DAVINCI_MCBSP_PCR_CLKRP);
- break;
- case SND_SOC_DAIFMT_IB_IF:
- /* CLKRP Receive clock polarity,
- * 0 - sampled on falling edge of CLKR
- * valid on falling edge
- * CLKXP Transmit clock polarity,
- * 0 - clocked on rising edge of CLKX
- * valid on falling edge
- * FSRP Receive frame sync pol, 1 - active low
- * FSXP Transmit frame sync pol, 1 - active low
- */
- pcr |= (DAVINCI_MCBSP_PCR_FSXP | DAVINCI_MCBSP_PCR_FSRP);
- break;
- case SND_SOC_DAIFMT_NB_IF:
- /* CLKRP Receive clock polarity,
- * 1 - sampled on rising edge of CLKR
- * valid on rising edge
- * CLKXP Transmit clock polarity,
- * 1 - clocked on falling edge of CLKX
- * valid on rising edge
- * FSRP Receive frame sync pol, 1 - active low
- * FSXP Transmit frame sync pol, 1 - active low
- */
- pcr |= (DAVINCI_MCBSP_PCR_CLKXP | DAVINCI_MCBSP_PCR_CLKRP |
- DAVINCI_MCBSP_PCR_FSXP | DAVINCI_MCBSP_PCR_FSRP);
- break;
- case SND_SOC_DAIFMT_IB_NF:
- /* CLKRP Receive clock polarity,
- * 0 - sampled on falling edge of CLKR
- * valid on falling edge
- * CLKXP Transmit clock polarity,
- * 0 - clocked on rising edge of CLKX
- * valid on falling edge
- * FSRP Receive frame sync pol, 0 - active high
- * FSXP Transmit frame sync pol, 0 - active high
- */
- break;
- default:
- return -EINVAL;
- }
- if (inv_fs == true)
- pcr ^= (DAVINCI_MCBSP_PCR_FSXP | DAVINCI_MCBSP_PCR_FSRP);
- davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr);
- dev->pcr = pcr;
- davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr);
- return 0;
-}
-
-static int davinci_i2s_dai_set_clkdiv(struct snd_soc_dai *cpu_dai,
- int div_id, int div)
-{
- struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
-
- if (div_id != DAVINCI_MCBSP_CLKGDV)
- return -ENODEV;
-
- dev->clk_div = div;
- return 0;
-}
-
-static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
- struct davinci_pcm_dma_params *dma_params =
- &dev->dma_params[substream->stream];
- struct snd_interval *i = NULL;
- int mcbsp_word_length, master;
- unsigned int rcr, xcr, srgr, clk_div, freq, framesize;
- u32 spcr;
- snd_pcm_format_t fmt;
- unsigned element_cnt = 1;
-
- /* general line settings */
- spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- spcr |= DAVINCI_MCBSP_SPCR_RINTM(3) | DAVINCI_MCBSP_SPCR_FREE;
- davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
- } else {
- spcr |= DAVINCI_MCBSP_SPCR_XINTM(3) | DAVINCI_MCBSP_SPCR_FREE;
- davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
- }
-
- master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK;
- fmt = params_format(params);
- mcbsp_word_length = asp_word_length[fmt];
-
- switch (master) {
- case SND_SOC_DAIFMT_CBS_CFS:
- freq = clk_get_rate(dev->clk);
- srgr = DAVINCI_MCBSP_SRGR_FSGM |
- DAVINCI_MCBSP_SRGR_CLKSM;
- srgr |= DAVINCI_MCBSP_SRGR_FWID(mcbsp_word_length *
- 8 - 1);
- if (dev->i2s_accurate_sck) {
- clk_div = 256;
- do {
- framesize = (freq / (--clk_div)) /
- params->rate_num *
- params->rate_den;
- } while (((framesize < 33) || (framesize > 4095)) &&
- (clk_div));
- clk_div--;
- srgr |= DAVINCI_MCBSP_SRGR_FPER(framesize - 1);
- } else {
- /* symmetric waveforms */
- clk_div = freq / (mcbsp_word_length * 16) /
- params->rate_num * params->rate_den;
- srgr |= DAVINCI_MCBSP_SRGR_FPER(mcbsp_word_length *
- 16 - 1);
- }
- clk_div &= 0xFF;
- srgr |= clk_div;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- srgr = DAVINCI_MCBSP_SRGR_FSGM;
- clk_div = dev->clk_div - 1;
- srgr |= DAVINCI_MCBSP_SRGR_FWID(mcbsp_word_length * 8 - 1);
- srgr |= DAVINCI_MCBSP_SRGR_FPER(mcbsp_word_length * 16 - 1);
- clk_div &= 0xFF;
- srgr |= clk_div;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- /* Clock and frame sync given from external sources */
- i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS);
- srgr = DAVINCI_MCBSP_SRGR_FSGM;
- srgr |= DAVINCI_MCBSP_SRGR_FWID(snd_interval_value(i) - 1);
- pr_debug("%s - %d FWID set: re-read srgr = %X\n",
- __func__, __LINE__, snd_interval_value(i) - 1);
-
- i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_FRAME_BITS);
- srgr |= DAVINCI_MCBSP_SRGR_FPER(snd_interval_value(i) - 1);
- break;
- default:
- return -EINVAL;
- }
- davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr);
-
- rcr = DAVINCI_MCBSP_RCR_RFIG;
- xcr = DAVINCI_MCBSP_XCR_XFIG;
- if (dev->mode == MOD_DSP_B) {
- rcr |= DAVINCI_MCBSP_RCR_RDATDLY(0);
- xcr |= DAVINCI_MCBSP_XCR_XDATDLY(0);
- } else {
- rcr |= DAVINCI_MCBSP_RCR_RDATDLY(1);
- xcr |= DAVINCI_MCBSP_XCR_XDATDLY(1);
- }
- /* Determine xfer data type */
- fmt = params_format(params);
- if ((fmt > SNDRV_PCM_FORMAT_S32_LE) || !data_type[fmt]) {
- printk(KERN_WARNING "davinci-i2s: unsupported PCM format\n");
- return -EINVAL;
- }
-
- if (params_channels(params) == 2) {
- element_cnt = 2;
- if (double_fmt[fmt] && dev->enable_channel_combine) {
- element_cnt = 1;
- fmt = double_fmt[fmt];
- }
- switch (master) {
- case SND_SOC_DAIFMT_CBS_CFS:
- case SND_SOC_DAIFMT_CBS_CFM:
- rcr |= DAVINCI_MCBSP_RCR_RFRLEN2(0);
- xcr |= DAVINCI_MCBSP_XCR_XFRLEN2(0);
- rcr |= DAVINCI_MCBSP_RCR_RPHASE;
- xcr |= DAVINCI_MCBSP_XCR_XPHASE;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- case SND_SOC_DAIFMT_CBM_CFS:
- rcr |= DAVINCI_MCBSP_RCR_RFRLEN2(element_cnt - 1);
- xcr |= DAVINCI_MCBSP_XCR_XFRLEN2(element_cnt - 1);
- break;
- default:
- return -EINVAL;
- }
- }
- dma_params->acnt = dma_params->data_type = data_type[fmt];
- dma_params->fifo_level = 0;
- mcbsp_word_length = asp_word_length[fmt];
-
- switch (master) {
- case SND_SOC_DAIFMT_CBS_CFS:
- case SND_SOC_DAIFMT_CBS_CFM:
- rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(0);
- xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(0);
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- case SND_SOC_DAIFMT_CBM_CFS:
- rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(element_cnt - 1);
- xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(element_cnt - 1);
- break;
- default:
- return -EINVAL;
- }
-
- rcr |= DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) |
- DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length);
- xcr |= DAVINCI_MCBSP_XCR_XWDLEN1(mcbsp_word_length) |
- DAVINCI_MCBSP_XCR_XWDLEN2(mcbsp_word_length);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, xcr);
- else
- davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, rcr);
-
- pr_debug("%s - %d srgr=%X\n", __func__, __LINE__, srgr);
- pr_debug("%s - %d xcr=%X\n", __func__, __LINE__, xcr);
- pr_debug("%s - %d rcr=%X\n", __func__, __LINE__, rcr);
- return 0;
-}
-
-static int davinci_i2s_prepare(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
- int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
- davinci_mcbsp_stop(dev, playback);
- return 0;
-}
-
-static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
- int ret = 0;
- int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- davinci_mcbsp_start(dev, substream);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- davinci_mcbsp_stop(dev, playback);
- break;
- default:
- ret = -EINVAL;
- }
- return ret;
-}
-
-static int davinci_i2s_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
-
- snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
- return 0;
-}
-
-static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
- int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
- davinci_mcbsp_stop(dev, playback);
-}
-
-#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000
-
-static const struct snd_soc_dai_ops davinci_i2s_dai_ops = {
- .startup = davinci_i2s_startup,
- .shutdown = davinci_i2s_shutdown,
- .prepare = davinci_i2s_prepare,
- .trigger = davinci_i2s_trigger,
- .hw_params = davinci_i2s_hw_params,
- .set_fmt = davinci_i2s_set_dai_fmt,
- .set_clkdiv = davinci_i2s_dai_set_clkdiv,
-
-};
-
-static struct snd_soc_dai_driver davinci_i2s_dai = {
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = DAVINCI_I2S_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = DAVINCI_I2S_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .ops = &davinci_i2s_dai_ops,
-
-};
-
-static int davinci_i2s_probe(struct platform_device *pdev)
-{
- struct snd_platform_data *pdata = pdev->dev.platform_data;
- struct davinci_mcbsp_dev *dev;
- struct resource *mem, *ioarea, *res;
- enum dma_event_q asp_chan_q = EVENTQ_0;
- enum dma_event_q ram_chan_q = EVENTQ_1;
- int ret;
-
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem) {
- dev_err(&pdev->dev, "no mem resource?\n");
- return -ENODEV;
- }
-
- ioarea = devm_request_mem_region(&pdev->dev, mem->start,
- resource_size(mem),
- pdev->name);
- if (!ioarea) {
- dev_err(&pdev->dev, "McBSP region already claimed\n");
- return -EBUSY;
- }
-
- dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_mcbsp_dev),
- GFP_KERNEL);
- if (!dev)
- return -ENOMEM;
- if (pdata) {
- dev->enable_channel_combine = pdata->enable_channel_combine;
- dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].sram_size =
- pdata->sram_size_playback;
- dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].sram_size =
- pdata->sram_size_capture;
- dev->clk_input_pin = pdata->clk_input_pin;
- dev->i2s_accurate_sck = pdata->i2s_accurate_sck;
- asp_chan_q = pdata->asp_chan_q;
- ram_chan_q = pdata->ram_chan_q;
- }
-
- dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].asp_chan_q = asp_chan_q;
- dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].ram_chan_q = ram_chan_q;
- dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].asp_chan_q = asp_chan_q;
- dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].ram_chan_q = ram_chan_q;
-
- dev->clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(dev->clk))
- return -ENODEV;
- clk_enable(dev->clk);
-
- dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
- if (!dev->base) {
- dev_err(&pdev->dev, "ioremap failed\n");
- ret = -ENOMEM;
- goto err_release_clk;
- }
-
- dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr =
- (dma_addr_t)(mem->start + DAVINCI_MCBSP_DXR_REG);
-
- dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr =
- (dma_addr_t)(mem->start + DAVINCI_MCBSP_DRR_REG);
-
- /* first TX, then RX */
- res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!res) {
- dev_err(&pdev->dev, "no DMA resource\n");
- ret = -ENXIO;
- goto err_release_clk;
- }
- dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start;
-
- res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (!res) {
- dev_err(&pdev->dev, "no DMA resource\n");
- ret = -ENXIO;
- goto err_release_clk;
- }
- dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
- dev->dev = &pdev->dev;
-
- dev_set_drvdata(&pdev->dev, dev);
-
- ret = snd_soc_register_dai(&pdev->dev, &davinci_i2s_dai);
- if (ret != 0)
- goto err_release_clk;
-
- return 0;
-
-err_release_clk:
- clk_disable(dev->clk);
- clk_put(dev->clk);
- return ret;
-}
-
-static int davinci_i2s_remove(struct platform_device *pdev)
-{
- struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev);
-
- snd_soc_unregister_dai(&pdev->dev);
- clk_disable(dev->clk);
- clk_put(dev->clk);
- dev->clk = NULL;
-
- return 0;
-}
-
-static struct platform_driver davinci_mcbsp_driver = {
- .probe = davinci_i2s_probe,
- .remove = davinci_i2s_remove,
- .driver = {
- .name = "davinci-mcbsp",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(davinci_mcbsp_driver);
-
-MODULE_AUTHOR("Vladimir Barinov");
-MODULE_DESCRIPTION("TI DAVINCI I2S (McBSP) SoC Interface");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/davinci/davinci-i2s.h b/ANDROID_3.4.5/sound/soc/davinci/davinci-i2s.h
deleted file mode 100644
index 48dac3e2..00000000
--- a/ANDROID_3.4.5/sound/soc/davinci/davinci-i2s.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * ALSA SoC I2S (McBSP) Audio Layer for TI DAVINCI processor
- *
- * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
- * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _DAVINCI_I2S_H
-#define _DAVINCI_I2S_H
-
-/* McBSP dividers */
-enum davinci_mcbsp_div {
- DAVINCI_MCBSP_CLKGDV, /* Sample rate generator divider */
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/davinci/davinci-mcasp.c b/ANDROID_3.4.5/sound/soc/davinci/davinci-mcasp.c
deleted file mode 100644
index 95441bfc..00000000
--- a/ANDROID_3.4.5/sound/soc/davinci/davinci-mcasp.c
+++ /dev/null
@@ -1,983 +0,0 @@
-/*
- * ALSA SoC McASP Audio Layer for TI DAVINCI processor
- *
- * Multi-channel Audio Serial Port Driver
- *
- * Author: Nirmal Pandey <n-pandey@ti.com>,
- * Suresh Rajashekara <suresh.r@ti.com>
- * Steve Chen <schen@.mvista.com>
- *
- * Copyright: (C) 2009 MontaVista Software, Inc., <source@mvista.com>
- * Copyright: (C) 2009 Texas Instruments, India
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include "davinci-pcm.h"
-#include "davinci-mcasp.h"
-
-/*
- * McASP register definitions
- */
-#define DAVINCI_MCASP_PID_REG 0x00
-#define DAVINCI_MCASP_PWREMUMGT_REG 0x04
-
-#define DAVINCI_MCASP_PFUNC_REG 0x10
-#define DAVINCI_MCASP_PDIR_REG 0x14
-#define DAVINCI_MCASP_PDOUT_REG 0x18
-#define DAVINCI_MCASP_PDSET_REG 0x1c
-
-#define DAVINCI_MCASP_PDCLR_REG 0x20
-
-#define DAVINCI_MCASP_TLGC_REG 0x30
-#define DAVINCI_MCASP_TLMR_REG 0x34
-
-#define DAVINCI_MCASP_GBLCTL_REG 0x44
-#define DAVINCI_MCASP_AMUTE_REG 0x48
-#define DAVINCI_MCASP_LBCTL_REG 0x4c
-
-#define DAVINCI_MCASP_TXDITCTL_REG 0x50
-
-#define DAVINCI_MCASP_GBLCTLR_REG 0x60
-#define DAVINCI_MCASP_RXMASK_REG 0x64
-#define DAVINCI_MCASP_RXFMT_REG 0x68
-#define DAVINCI_MCASP_RXFMCTL_REG 0x6c
-
-#define DAVINCI_MCASP_ACLKRCTL_REG 0x70
-#define DAVINCI_MCASP_AHCLKRCTL_REG 0x74
-#define DAVINCI_MCASP_RXTDM_REG 0x78
-#define DAVINCI_MCASP_EVTCTLR_REG 0x7c
-
-#define DAVINCI_MCASP_RXSTAT_REG 0x80
-#define DAVINCI_MCASP_RXTDMSLOT_REG 0x84
-#define DAVINCI_MCASP_RXCLKCHK_REG 0x88
-#define DAVINCI_MCASP_REVTCTL_REG 0x8c
-
-#define DAVINCI_MCASP_GBLCTLX_REG 0xa0
-#define DAVINCI_MCASP_TXMASK_REG 0xa4
-#define DAVINCI_MCASP_TXFMT_REG 0xa8
-#define DAVINCI_MCASP_TXFMCTL_REG 0xac
-
-#define DAVINCI_MCASP_ACLKXCTL_REG 0xb0
-#define DAVINCI_MCASP_AHCLKXCTL_REG 0xb4
-#define DAVINCI_MCASP_TXTDM_REG 0xb8
-#define DAVINCI_MCASP_EVTCTLX_REG 0xbc
-
-#define DAVINCI_MCASP_TXSTAT_REG 0xc0
-#define DAVINCI_MCASP_TXTDMSLOT_REG 0xc4
-#define DAVINCI_MCASP_TXCLKCHK_REG 0xc8
-#define DAVINCI_MCASP_XEVTCTL_REG 0xcc
-
-/* Left(even TDM Slot) Channel Status Register File */
-#define DAVINCI_MCASP_DITCSRA_REG 0x100
-/* Right(odd TDM slot) Channel Status Register File */
-#define DAVINCI_MCASP_DITCSRB_REG 0x118
-/* Left(even TDM slot) User Data Register File */
-#define DAVINCI_MCASP_DITUDRA_REG 0x130
-/* Right(odd TDM Slot) User Data Register File */
-#define DAVINCI_MCASP_DITUDRB_REG 0x148
-
-/* Serializer n Control Register */
-#define DAVINCI_MCASP_XRSRCTL_BASE_REG 0x180
-#define DAVINCI_MCASP_XRSRCTL_REG(n) (DAVINCI_MCASP_XRSRCTL_BASE_REG + \
- (n << 2))
-
-/* Transmit Buffer for Serializer n */
-#define DAVINCI_MCASP_TXBUF_REG 0x200
-/* Receive Buffer for Serializer n */
-#define DAVINCI_MCASP_RXBUF_REG 0x280
-
-/* McASP FIFO Registers */
-#define DAVINCI_MCASP_WFIFOCTL (0x1010)
-#define DAVINCI_MCASP_WFIFOSTS (0x1014)
-#define DAVINCI_MCASP_RFIFOCTL (0x1018)
-#define DAVINCI_MCASP_RFIFOSTS (0x101C)
-
-/*
- * DAVINCI_MCASP_PWREMUMGT_REG - Power Down and Emulation Management
- * Register Bits
- */
-#define MCASP_FREE BIT(0)
-#define MCASP_SOFT BIT(1)
-
-/*
- * DAVINCI_MCASP_PFUNC_REG - Pin Function / GPIO Enable Register Bits
- */
-#define AXR(n) (1<<n)
-#define PFUNC_AMUTE BIT(25)
-#define ACLKX BIT(26)
-#define AHCLKX BIT(27)
-#define AFSX BIT(28)
-#define ACLKR BIT(29)
-#define AHCLKR BIT(30)
-#define AFSR BIT(31)
-
-/*
- * DAVINCI_MCASP_PDIR_REG - Pin Direction Register Bits
- */
-#define AXR(n) (1<<n)
-#define PDIR_AMUTE BIT(25)
-#define ACLKX BIT(26)
-#define AHCLKX BIT(27)
-#define AFSX BIT(28)
-#define ACLKR BIT(29)
-#define AHCLKR BIT(30)
-#define AFSR BIT(31)
-
-/*
- * DAVINCI_MCASP_TXDITCTL_REG - Transmit DIT Control Register Bits
- */
-#define DITEN BIT(0) /* Transmit DIT mode enable/disable */
-#define VA BIT(2)
-#define VB BIT(3)
-
-/*
- * DAVINCI_MCASP_TXFMT_REG - Transmit Bitstream Format Register Bits
- */
-#define TXROT(val) (val)
-#define TXSEL BIT(3)
-#define TXSSZ(val) (val<<4)
-#define TXPBIT(val) (val<<8)
-#define TXPAD(val) (val<<13)
-#define TXORD BIT(15)
-#define FSXDLY(val) (val<<16)
-
-/*
- * DAVINCI_MCASP_RXFMT_REG - Receive Bitstream Format Register Bits
- */
-#define RXROT(val) (val)
-#define RXSEL BIT(3)
-#define RXSSZ(val) (val<<4)
-#define RXPBIT(val) (val<<8)
-#define RXPAD(val) (val<<13)
-#define RXORD BIT(15)
-#define FSRDLY(val) (val<<16)
-
-/*
- * DAVINCI_MCASP_TXFMCTL_REG - Transmit Frame Control Register Bits
- */
-#define FSXPOL BIT(0)
-#define AFSXE BIT(1)
-#define FSXDUR BIT(4)
-#define FSXMOD(val) (val<<7)
-
-/*
- * DAVINCI_MCASP_RXFMCTL_REG - Receive Frame Control Register Bits
- */
-#define FSRPOL BIT(0)
-#define AFSRE BIT(1)
-#define FSRDUR BIT(4)
-#define FSRMOD(val) (val<<7)
-
-/*
- * DAVINCI_MCASP_ACLKXCTL_REG - Transmit Clock Control Register Bits
- */
-#define ACLKXDIV(val) (val)
-#define ACLKXE BIT(5)
-#define TX_ASYNC BIT(6)
-#define ACLKXPOL BIT(7)
-
-/*
- * DAVINCI_MCASP_ACLKRCTL_REG Receive Clock Control Register Bits
- */
-#define ACLKRDIV(val) (val)
-#define ACLKRE BIT(5)
-#define RX_ASYNC BIT(6)
-#define ACLKRPOL BIT(7)
-
-/*
- * DAVINCI_MCASP_AHCLKXCTL_REG - High Frequency Transmit Clock Control
- * Register Bits
- */
-#define AHCLKXDIV(val) (val)
-#define AHCLKXPOL BIT(14)
-#define AHCLKXE BIT(15)
-
-/*
- * DAVINCI_MCASP_AHCLKRCTL_REG - High Frequency Receive Clock Control
- * Register Bits
- */
-#define AHCLKRDIV(val) (val)
-#define AHCLKRPOL BIT(14)
-#define AHCLKRE BIT(15)
-
-/*
- * DAVINCI_MCASP_XRSRCTL_BASE_REG - Serializer Control Register Bits
- */
-#define MODE(val) (val)
-#define DISMOD (val)(val<<2)
-#define TXSTATE BIT(4)
-#define RXSTATE BIT(5)
-
-/*
- * DAVINCI_MCASP_LBCTL_REG - Loop Back Control Register Bits
- */
-#define LBEN BIT(0)
-#define LBORD BIT(1)
-#define LBGENMODE(val) (val<<2)
-
-/*
- * DAVINCI_MCASP_TXTDMSLOT_REG - Transmit TDM Slot Register configuration
- */
-#define TXTDMS(n) (1<<n)
-
-/*
- * DAVINCI_MCASP_RXTDMSLOT_REG - Receive TDM Slot Register configuration
- */
-#define RXTDMS(n) (1<<n)
-
-/*
- * DAVINCI_MCASP_GBLCTL_REG - Global Control Register Bits
- */
-#define RXCLKRST BIT(0) /* Receiver Clock Divider Reset */
-#define RXHCLKRST BIT(1) /* Receiver High Frequency Clock Divider */
-#define RXSERCLR BIT(2) /* Receiver Serializer Clear */
-#define RXSMRST BIT(3) /* Receiver State Machine Reset */
-#define RXFSRST BIT(4) /* Frame Sync Generator Reset */
-#define TXCLKRST BIT(8) /* Transmitter Clock Divider Reset */
-#define TXHCLKRST BIT(9) /* Transmitter High Frequency Clock Divider*/
-#define TXSERCLR BIT(10) /* Transmit Serializer Clear */
-#define TXSMRST BIT(11) /* Transmitter State Machine Reset */
-#define TXFSRST BIT(12) /* Frame Sync Generator Reset */
-
-/*
- * DAVINCI_MCASP_AMUTE_REG - Mute Control Register Bits
- */
-#define MUTENA(val) (val)
-#define MUTEINPOL BIT(2)
-#define MUTEINENA BIT(3)
-#define MUTEIN BIT(4)
-#define MUTER BIT(5)
-#define MUTEX BIT(6)
-#define MUTEFSR BIT(7)
-#define MUTEFSX BIT(8)
-#define MUTEBADCLKR BIT(9)
-#define MUTEBADCLKX BIT(10)
-#define MUTERXDMAERR BIT(11)
-#define MUTETXDMAERR BIT(12)
-
-/*
- * DAVINCI_MCASP_REVTCTL_REG - Receiver DMA Event Control Register bits
- */
-#define RXDATADMADIS BIT(0)
-
-/*
- * DAVINCI_MCASP_XEVTCTL_REG - Transmitter DMA Event Control Register bits
- */
-#define TXDATADMADIS BIT(0)
-
-/*
- * DAVINCI_MCASP_W[R]FIFOCTL - Write/Read FIFO Control Register bits
- */
-#define FIFO_ENABLE BIT(16)
-#define NUMEVT_MASK (0xFF << 8)
-#define NUMDMA_MASK (0xFF)
-
-#define DAVINCI_MCASP_NUM_SERIALIZER 16
-
-static inline void mcasp_set_bits(void __iomem *reg, u32 val)
-{
- __raw_writel(__raw_readl(reg) | val, reg);
-}
-
-static inline void mcasp_clr_bits(void __iomem *reg, u32 val)
-{
- __raw_writel((__raw_readl(reg) & ~(val)), reg);
-}
-
-static inline void mcasp_mod_bits(void __iomem *reg, u32 val, u32 mask)
-{
- __raw_writel((__raw_readl(reg) & ~mask) | val, reg);
-}
-
-static inline void mcasp_set_reg(void __iomem *reg, u32 val)
-{
- __raw_writel(val, reg);
-}
-
-static inline u32 mcasp_get_reg(void __iomem *reg)
-{
- return (unsigned int)__raw_readl(reg);
-}
-
-static inline void mcasp_set_ctl_reg(void __iomem *regs, u32 val)
-{
- int i = 0;
-
- mcasp_set_bits(regs, val);
-
- /* programming GBLCTL needs to read back from GBLCTL and verfiy */
- /* loop count is to avoid the lock-up */
- for (i = 0; i < 1000; i++) {
- if ((mcasp_get_reg(regs) & val) == val)
- break;
- }
-
- if (i == 1000 && ((mcasp_get_reg(regs) & val) != val))
- printk(KERN_ERR "GBLCTL write error\n");
-}
-
-static void mcasp_start_rx(struct davinci_audio_dev *dev)
-{
- mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST);
- mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXCLKRST);
- mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXSERCLR);
- mcasp_set_reg(dev->base + DAVINCI_MCASP_RXBUF_REG, 0);
-
- mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXSMRST);
- mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXFSRST);
- mcasp_set_reg(dev->base + DAVINCI_MCASP_RXBUF_REG, 0);
-
- mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXSMRST);
- mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXFSRST);
-}
-
-static void mcasp_start_tx(struct davinci_audio_dev *dev)
-{
- u8 offset = 0, i;
- u32 cnt;
-
- mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST);
- mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST);
- mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXSERCLR);
- mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0);
-
- mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXSMRST);
- mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXFSRST);
- mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0);
- for (i = 0; i < dev->num_serializer; i++) {
- if (dev->serial_dir[i] == TX_MODE) {
- offset = i;
- break;
- }
- }
-
- /* wait for TX ready */
- cnt = 0;
- while (!(mcasp_get_reg(dev->base + DAVINCI_MCASP_XRSRCTL_REG(offset)) &
- TXSTATE) && (cnt < 100000))
- cnt++;
-
- mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0);
-}
-
-static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream)
-{
- if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (dev->txnumevt) /* enable FIFO */
- mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
- FIFO_ENABLE);
- mcasp_start_tx(dev);
- } else {
- if (dev->rxnumevt) /* enable FIFO */
- mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
- FIFO_ENABLE);
- mcasp_start_rx(dev);
- }
-}
-
-static void mcasp_stop_rx(struct davinci_audio_dev *dev)
-{
- mcasp_set_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, 0);
- mcasp_set_reg(dev->base + DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF);
-}
-
-static void mcasp_stop_tx(struct davinci_audio_dev *dev)
-{
- mcasp_set_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, 0);
- mcasp_set_reg(dev->base + DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF);
-}
-
-static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream)
-{
- if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (dev->txnumevt) /* disable FIFO */
- mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
- FIFO_ENABLE);
- mcasp_stop_tx(dev);
- } else {
- if (dev->rxnumevt) /* disable FIFO */
- mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
- FIFO_ENABLE);
- mcasp_stop_rx(dev);
- }
-}
-
-static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
- unsigned int fmt)
-{
- struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
- void __iomem *base = dev->base;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- /* codec is clock and frame slave */
- mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
- mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
-
- mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
- mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
-
- mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG,
- ACLKX | AHCLKX | AFSX);
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- /* codec is clock master and frame slave */
- mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
- mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
-
- mcasp_clr_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
- mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
-
- mcasp_clr_bits(base + DAVINCI_MCASP_PDIR_REG,
- ACLKX | ACLKR);
- mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG,
- AFSX | AFSR);
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- /* codec is clock and frame master */
- mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
- mcasp_clr_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
-
- mcasp_clr_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
- mcasp_clr_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
-
- mcasp_clr_bits(base + DAVINCI_MCASP_PDIR_REG,
- ACLKX | AHCLKX | AFSX | ACLKR | AHCLKR | AFSR);
- break;
-
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_IB_NF:
- mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
- mcasp_clr_bits(base + DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
-
- mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
- mcasp_clr_bits(base + DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
- break;
-
- case SND_SOC_DAIFMT_NB_IF:
- mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
- mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
-
- mcasp_clr_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
- mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
- break;
-
- case SND_SOC_DAIFMT_IB_IF:
- mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
- mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
-
- mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
- mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
- break;
-
- case SND_SOC_DAIFMT_NB_NF:
- mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
- mcasp_clr_bits(base + DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
-
- mcasp_clr_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
- mcasp_clr_bits(base + DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int davinci_config_channel_size(struct davinci_audio_dev *dev,
- int channel_size)
-{
- u32 fmt = 0;
- u32 mask, rotate;
-
- switch (channel_size) {
- case DAVINCI_AUDIO_WORD_8:
- fmt = 0x03;
- rotate = 6;
- mask = 0x000000ff;
- break;
-
- case DAVINCI_AUDIO_WORD_12:
- fmt = 0x05;
- rotate = 5;
- mask = 0x00000fff;
- break;
-
- case DAVINCI_AUDIO_WORD_16:
- fmt = 0x07;
- rotate = 4;
- mask = 0x0000ffff;
- break;
-
- case DAVINCI_AUDIO_WORD_20:
- fmt = 0x09;
- rotate = 3;
- mask = 0x000fffff;
- break;
-
- case DAVINCI_AUDIO_WORD_24:
- fmt = 0x0B;
- rotate = 2;
- mask = 0x00ffffff;
- break;
-
- case DAVINCI_AUDIO_WORD_28:
- fmt = 0x0D;
- rotate = 1;
- mask = 0x0fffffff;
- break;
-
- case DAVINCI_AUDIO_WORD_32:
- fmt = 0x0F;
- rotate = 0;
- mask = 0xffffffff;
- break;
-
- default:
- return -EINVAL;
- }
-
- mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG,
- RXSSZ(fmt), RXSSZ(0x0F));
- mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
- TXSSZ(fmt), TXSSZ(0x0F));
- mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXROT(rotate),
- TXROT(7));
- mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXROT(rotate),
- RXROT(7));
- mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, mask);
- mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG, mask);
-
- return 0;
-}
-
-static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream)
-{
- int i;
- u8 tx_ser = 0;
- u8 rx_ser = 0;
-
- /* Default configuration */
- mcasp_set_bits(dev->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT);
-
- /* All PINS as McASP */
- mcasp_set_reg(dev->base + DAVINCI_MCASP_PFUNC_REG, 0x00000000);
-
- if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
- mcasp_set_reg(dev->base + DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF);
- mcasp_clr_bits(dev->base + DAVINCI_MCASP_XEVTCTL_REG,
- TXDATADMADIS);
- } else {
- mcasp_set_reg(dev->base + DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF);
- mcasp_clr_bits(dev->base + DAVINCI_MCASP_REVTCTL_REG,
- RXDATADMADIS);
- }
-
- for (i = 0; i < dev->num_serializer; i++) {
- mcasp_set_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i),
- dev->serial_dir[i]);
- if (dev->serial_dir[i] == TX_MODE) {
- mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG,
- AXR(i));
- tx_ser++;
- } else if (dev->serial_dir[i] == RX_MODE) {
- mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG,
- AXR(i));
- rx_ser++;
- }
- }
-
- if (dev->txnumevt && stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (dev->txnumevt * tx_ser > 64)
- dev->txnumevt = 1;
-
- mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, tx_ser,
- NUMDMA_MASK);
- mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
- ((dev->txnumevt * tx_ser) << 8), NUMEVT_MASK);
- }
-
- if (dev->rxnumevt && stream == SNDRV_PCM_STREAM_CAPTURE) {
- if (dev->rxnumevt * rx_ser > 64)
- dev->rxnumevt = 1;
-
- mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, rx_ser,
- NUMDMA_MASK);
- mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
- ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK);
- }
-}
-
-static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
-{
- int i, active_slots;
- u32 mask = 0;
-
- active_slots = (dev->tdm_slots > 31) ? 32 : dev->tdm_slots;
- for (i = 0; i < active_slots; i++)
- mask |= (1 << i);
-
- mcasp_clr_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC);
-
- if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
- /* bit stream is MSB first with no delay */
- /* DSP_B mode */
- mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG,
- AHCLKXE);
- mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, mask);
- mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXORD);
-
- if ((dev->tdm_slots >= 2) && (dev->tdm_slots <= 32))
- mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG,
- FSXMOD(dev->tdm_slots), FSXMOD(0x1FF));
- else
- printk(KERN_ERR "playback tdm slot %d not supported\n",
- dev->tdm_slots);
-
- mcasp_clr_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
- } else {
- /* bit stream is MSB first with no delay */
- /* DSP_B mode */
- mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXORD);
- mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG,
- AHCLKRE);
- mcasp_set_reg(dev->base + DAVINCI_MCASP_RXTDM_REG, mask);
-
- if ((dev->tdm_slots >= 2) && (dev->tdm_slots <= 32))
- mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG,
- FSRMOD(dev->tdm_slots), FSRMOD(0x1FF));
- else
- printk(KERN_ERR "capture tdm slot %d not supported\n",
- dev->tdm_slots);
-
- mcasp_clr_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
- }
-}
-
-/* S/PDIF */
-static void davinci_hw_dit_param(struct davinci_audio_dev *dev)
-{
- /* Set the PDIR for Serialiser as output */
- mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AFSX);
-
- /* TXMASK for 24 bits */
- mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, 0x00FFFFFF);
-
- /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0
- and LSB first */
- mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
- TXROT(6) | TXSSZ(15));
-
- /* Set TX frame synch : DIT Mode, 1 bit width, internal, rising edge */
- mcasp_set_reg(dev->base + DAVINCI_MCASP_TXFMCTL_REG,
- AFSXE | FSXMOD(0x180));
-
- /* Set the TX tdm : for all the slots */
- mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, 0xFFFFFFFF);
-
- /* Set the TX clock controls : div = 1 and internal */
- mcasp_set_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG,
- ACLKXE | TX_ASYNC);
-
- mcasp_clr_bits(dev->base + DAVINCI_MCASP_XEVTCTL_REG, TXDATADMADIS);
-
- /* Only 44100 and 48000 are valid, both have the same setting */
- mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXDIV(3));
-
- /* Enable the DIT */
- mcasp_set_bits(dev->base + DAVINCI_MCASP_TXDITCTL_REG, DITEN);
-}
-
-static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *cpu_dai)
-{
- struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
- struct davinci_pcm_dma_params *dma_params =
- &dev->dma_params[substream->stream];
- int word_length;
- u8 fifo_level;
-
- davinci_hw_common_param(dev, substream->stream);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- fifo_level = dev->txnumevt;
- else
- fifo_level = dev->rxnumevt;
-
- if (dev->op_mode == DAVINCI_MCASP_DIT_MODE)
- davinci_hw_dit_param(dev);
- else
- davinci_hw_param(dev, substream->stream);
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_U8:
- case SNDRV_PCM_FORMAT_S8:
- dma_params->data_type = 1;
- word_length = DAVINCI_AUDIO_WORD_8;
- break;
-
- case SNDRV_PCM_FORMAT_U16_LE:
- case SNDRV_PCM_FORMAT_S16_LE:
- dma_params->data_type = 2;
- word_length = DAVINCI_AUDIO_WORD_16;
- break;
-
- case SNDRV_PCM_FORMAT_U32_LE:
- case SNDRV_PCM_FORMAT_S32_LE:
- dma_params->data_type = 4;
- word_length = DAVINCI_AUDIO_WORD_32;
- break;
-
- default:
- printk(KERN_WARNING "davinci-mcasp: unsupported PCM format");
- return -EINVAL;
- }
-
- if (dev->version == MCASP_VERSION_2 && !fifo_level)
- dma_params->acnt = 4;
- else
- dma_params->acnt = dma_params->data_type;
-
- dma_params->fifo_level = fifo_level;
- davinci_config_channel_size(dev, word_length);
-
- return 0;
-}
-
-static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
- int cmd, struct snd_soc_dai *cpu_dai)
-{
- struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
- int ret = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (!dev->clk_active) {
- clk_enable(dev->clk);
- dev->clk_active = 1;
- }
- davinci_mcasp_start(dev, substream->stream);
- break;
-
- case SNDRV_PCM_TRIGGER_SUSPEND:
- davinci_mcasp_stop(dev, substream->stream);
- if (dev->clk_active) {
- clk_disable(dev->clk);
- dev->clk_active = 0;
- }
-
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- davinci_mcasp_stop(dev, substream->stream);
- break;
-
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai);
-
- snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
- return 0;
-}
-
-static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
- .startup = davinci_mcasp_startup,
- .trigger = davinci_mcasp_trigger,
- .hw_params = davinci_mcasp_hw_params,
- .set_fmt = davinci_mcasp_set_dai_fmt,
-
-};
-
-#define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \
- SNDRV_PCM_FMTBIT_U8 | \
- SNDRV_PCM_FMTBIT_S16_LE | \
- SNDRV_PCM_FMTBIT_U16_LE | \
- SNDRV_PCM_FMTBIT_S32_LE | \
- SNDRV_PCM_FMTBIT_U32_LE)
-
-static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
- {
- .name = "davinci-mcasp.0",
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = DAVINCI_MCASP_RATES,
- .formats = DAVINCI_MCASP_PCM_FMTS,
- },
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = DAVINCI_MCASP_RATES,
- .formats = DAVINCI_MCASP_PCM_FMTS,
- },
- .ops = &davinci_mcasp_dai_ops,
-
- },
- {
- "davinci-mcasp.1",
- .playback = {
- .channels_min = 1,
- .channels_max = 384,
- .rates = DAVINCI_MCASP_RATES,
- .formats = DAVINCI_MCASP_PCM_FMTS,
- },
- .ops = &davinci_mcasp_dai_ops,
- },
-
-};
-
-static int davinci_mcasp_probe(struct platform_device *pdev)
-{
- struct davinci_pcm_dma_params *dma_data;
- struct resource *mem, *ioarea, *res;
- struct snd_platform_data *pdata;
- struct davinci_audio_dev *dev;
- int ret;
-
- dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_audio_dev),
- GFP_KERNEL);
- if (!dev)
- return -ENOMEM;
-
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem) {
- dev_err(&pdev->dev, "no mem resource?\n");
- return -ENODEV;
- }
-
- ioarea = devm_request_mem_region(&pdev->dev, mem->start,
- resource_size(mem), pdev->name);
- if (!ioarea) {
- dev_err(&pdev->dev, "Audio region already claimed\n");
- return -EBUSY;
- }
-
- pdata = pdev->dev.platform_data;
- dev->clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(dev->clk))
- return -ENODEV;
-
- clk_enable(dev->clk);
- dev->clk_active = 1;
-
- dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
- if (!dev->base) {
- dev_err(&pdev->dev, "ioremap failed\n");
- ret = -ENOMEM;
- goto err_release_clk;
- }
-
- dev->op_mode = pdata->op_mode;
- dev->tdm_slots = pdata->tdm_slots;
- dev->num_serializer = pdata->num_serializer;
- dev->serial_dir = pdata->serial_dir;
- dev->codec_fmt = pdata->codec_fmt;
- dev->version = pdata->version;
- dev->txnumevt = pdata->txnumevt;
- dev->rxnumevt = pdata->rxnumevt;
-
- dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
- dma_data->asp_chan_q = pdata->asp_chan_q;
- dma_data->ram_chan_q = pdata->ram_chan_q;
- dma_data->sram_size = pdata->sram_size_playback;
- dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
- mem->start);
-
- /* first TX, then RX */
- res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!res) {
- dev_err(&pdev->dev, "no DMA resource\n");
- ret = -ENODEV;
- goto err_release_clk;
- }
-
- dma_data->channel = res->start;
-
- dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE];
- dma_data->asp_chan_q = pdata->asp_chan_q;
- dma_data->ram_chan_q = pdata->ram_chan_q;
- dma_data->sram_size = pdata->sram_size_capture;
- dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
- mem->start);
-
- res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (!res) {
- dev_err(&pdev->dev, "no DMA resource\n");
- ret = -ENODEV;
- goto err_release_clk;
- }
-
- dma_data->channel = res->start;
- dev_set_drvdata(&pdev->dev, dev);
- ret = snd_soc_register_dai(&pdev->dev, &davinci_mcasp_dai[pdata->op_mode]);
-
- if (ret != 0)
- goto err_release_clk;
- return 0;
-
-err_release_clk:
- clk_disable(dev->clk);
- clk_put(dev->clk);
- return ret;
-}
-
-static int davinci_mcasp_remove(struct platform_device *pdev)
-{
- struct davinci_audio_dev *dev = dev_get_drvdata(&pdev->dev);
-
- snd_soc_unregister_dai(&pdev->dev);
- clk_disable(dev->clk);
- clk_put(dev->clk);
- dev->clk = NULL;
-
- return 0;
-}
-
-static struct platform_driver davinci_mcasp_driver = {
- .probe = davinci_mcasp_probe,
- .remove = davinci_mcasp_remove,
- .driver = {
- .name = "davinci-mcasp",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(davinci_mcasp_driver);
-
-MODULE_AUTHOR("Steve Chen");
-MODULE_DESCRIPTION("TI DAVINCI McASP SoC Interface");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/soc/davinci/davinci-mcasp.h b/ANDROID_3.4.5/sound/soc/davinci/davinci-mcasp.h
deleted file mode 100644
index 4681acc6..00000000
--- a/ANDROID_3.4.5/sound/soc/davinci/davinci-mcasp.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * ALSA SoC McASP Audio Layer for TI DAVINCI processor
- *
- * MCASP related definitions
- *
- * Author: Nirmal Pandey <n-pandey@ti.com>,
- * Suresh Rajashekara <suresh.r@ti.com>
- * Steve Chen <schen@.mvista.com>
- *
- * Copyright: (C) 2009 MontaVista Software, Inc., <source@mvista.com>
- * Copyright: (C) 2009 Texas Instruments, India
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef DAVINCI_MCASP_H
-#define DAVINCI_MCASP_H
-
-#include <linux/io.h>
-#include <mach/asp.h>
-#include "davinci-pcm.h"
-
-#define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_96000
-#define DAVINCI_MCASP_I2S_DAI 0
-#define DAVINCI_MCASP_DIT_DAI 1
-
-enum {
- DAVINCI_AUDIO_WORD_8 = 0,
- DAVINCI_AUDIO_WORD_12,
- DAVINCI_AUDIO_WORD_16,
- DAVINCI_AUDIO_WORD_20,
- DAVINCI_AUDIO_WORD_24,
- DAVINCI_AUDIO_WORD_32,
- DAVINCI_AUDIO_WORD_28, /* This is only valid for McASP */
-};
-
-struct davinci_audio_dev {
- struct davinci_pcm_dma_params dma_params[2];
- void __iomem *base;
- int sample_rate;
- struct clk *clk;
- unsigned int codec_fmt;
- u8 clk_active;
-
- /* McASP specific data */
- int tdm_slots;
- u8 op_mode;
- u8 num_serializer;
- u8 *serial_dir;
- u8 version;
-
- /* McASP FIFO related */
- u8 txnumevt;
- u8 rxnumevt;
-};
-
-#endif /* DAVINCI_MCASP_H */
diff --git a/ANDROID_3.4.5/sound/soc/davinci/davinci-pcm.c b/ANDROID_3.4.5/sound/soc/davinci/davinci-pcm.c
deleted file mode 100644
index 97d77b29..00000000
--- a/ANDROID_3.4.5/sound/soc/davinci/davinci-pcm.c
+++ /dev/null
@@ -1,892 +0,0 @@
-/*
- * ALSA PCM interface for the TI DAVINCI processor
- *
- * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
- * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
- * added SRAM ping/pong (C) 2008 Troy Kisky <troy.kisky@boundarydevices.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/dma-mapping.h>
-#include <linux/kernel.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/dma.h>
-#include <mach/edma.h>
-#include <mach/sram.h>
-
-#include "davinci-pcm.h"
-
-#ifdef DEBUG
-static void print_buf_info(int slot, char *name)
-{
- struct edmacc_param p;
- if (slot < 0)
- return;
- edma_read_slot(slot, &p);
- printk(KERN_DEBUG "%s: 0x%x, opt=%x, src=%x, a_b_cnt=%x dst=%x\n",
- name, slot, p.opt, p.src, p.a_b_cnt, p.dst);
- printk(KERN_DEBUG " src_dst_bidx=%x link_bcntrld=%x src_dst_cidx=%x ccnt=%x\n",
- p.src_dst_bidx, p.link_bcntrld, p.src_dst_cidx, p.ccnt);
-}
-#else
-static void print_buf_info(int slot, char *name)
-{
-}
-#endif
-
-#define DAVINCI_PCM_FMTBITS (\
- SNDRV_PCM_FMTBIT_S8 |\
- SNDRV_PCM_FMTBIT_U8 |\
- SNDRV_PCM_FMTBIT_S16_LE |\
- SNDRV_PCM_FMTBIT_S16_BE |\
- SNDRV_PCM_FMTBIT_U16_LE |\
- SNDRV_PCM_FMTBIT_U16_BE |\
- SNDRV_PCM_FMTBIT_S24_LE |\
- SNDRV_PCM_FMTBIT_S24_BE |\
- SNDRV_PCM_FMTBIT_U24_LE |\
- SNDRV_PCM_FMTBIT_U24_BE |\
- SNDRV_PCM_FMTBIT_S32_LE |\
- SNDRV_PCM_FMTBIT_S32_BE |\
- SNDRV_PCM_FMTBIT_U32_LE |\
- SNDRV_PCM_FMTBIT_U32_BE)
-
-static struct snd_pcm_hardware pcm_hardware_playback = {
- .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME|
- SNDRV_PCM_INFO_BATCH),
- .formats = DAVINCI_PCM_FMTBITS,
- .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
- SNDRV_PCM_RATE_KNOT),
- .rate_min = 8000,
- .rate_max = 96000,
- .channels_min = 2,
- .channels_max = 384,
- .buffer_bytes_max = 128 * 1024,
- .period_bytes_min = 32,
- .period_bytes_max = 8 * 1024,
- .periods_min = 16,
- .periods_max = 255,
- .fifo_size = 0,
-};
-
-static struct snd_pcm_hardware pcm_hardware_capture = {
- .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_BATCH),
- .formats = DAVINCI_PCM_FMTBITS,
- .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
- SNDRV_PCM_RATE_KNOT),
- .rate_min = 8000,
- .rate_max = 96000,
- .channels_min = 2,
- .channels_max = 384,
- .buffer_bytes_max = 128 * 1024,
- .period_bytes_min = 32,
- .period_bytes_max = 8 * 1024,
- .periods_min = 16,
- .periods_max = 255,
- .fifo_size = 0,
-};
-
-/*
- * How ping/pong works....
- *
- * Playback:
- * ram_params - copys 2*ping_size from start of SDRAM to iram,
- * links to ram_link2
- * ram_link2 - copys rest of SDRAM to iram in ping_size units,
- * links to ram_link
- * ram_link - copys entire SDRAM to iram in ping_size uints,
- * links to self
- *
- * asp_params - same as asp_link[0]
- * asp_link[0] - copys from lower half of iram to asp port
- * links to asp_link[1], triggers iram copy event on completion
- * asp_link[1] - copys from upper half of iram to asp port
- * links to asp_link[0], triggers iram copy event on completion
- * triggers interrupt only needed to let upper SOC levels update position
- * in stream on completion
- *
- * When playback is started:
- * ram_params started
- * asp_params started
- *
- * Capture:
- * ram_params - same as ram_link,
- * links to ram_link
- * ram_link - same as playback
- * links to self
- *
- * asp_params - same as playback
- * asp_link[0] - same as playback
- * asp_link[1] - same as playback
- *
- * When capture is started:
- * asp_params started
- */
-struct davinci_runtime_data {
- spinlock_t lock;
- int period; /* current DMA period */
- int asp_channel; /* Master DMA channel */
- int asp_link[2]; /* asp parameter link channel, ping/pong */
- struct davinci_pcm_dma_params *params; /* DMA params */
- int ram_channel;
- int ram_link;
- int ram_link2;
- struct edmacc_param asp_params;
- struct edmacc_param ram_params;
-};
-
-static void davinci_pcm_period_elapsed(struct snd_pcm_substream *substream)
-{
- struct davinci_runtime_data *prtd = substream->runtime->private_data;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- prtd->period++;
- if (unlikely(prtd->period >= runtime->periods))
- prtd->period = 0;
-}
-
-static void davinci_pcm_period_reset(struct snd_pcm_substream *substream)
-{
- struct davinci_runtime_data *prtd = substream->runtime->private_data;
-
- prtd->period = 0;
-}
-/*
- * Not used with ping/pong
- */
-static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
-{
- struct davinci_runtime_data *prtd = substream->runtime->private_data;
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int period_size;
- unsigned int dma_offset;
- dma_addr_t dma_pos;
- dma_addr_t src, dst;
- unsigned short src_bidx, dst_bidx;
- unsigned short src_cidx, dst_cidx;
- unsigned int data_type;
- unsigned short acnt;
- unsigned int count;
- unsigned int fifo_level;
-
- period_size = snd_pcm_lib_period_bytes(substream);
- dma_offset = prtd->period * period_size;
- dma_pos = runtime->dma_addr + dma_offset;
- fifo_level = prtd->params->fifo_level;
-
- pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d "
- "dma_ptr = %x period_size=%x\n", prtd->asp_link[0], dma_pos,
- period_size);
-
- data_type = prtd->params->data_type;
- count = period_size / data_type;
- if (fifo_level)
- count /= fifo_level;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- src = dma_pos;
- dst = prtd->params->dma_addr;
- src_bidx = data_type;
- dst_bidx = 0;
- src_cidx = data_type * fifo_level;
- dst_cidx = 0;
- } else {
- src = prtd->params->dma_addr;
- dst = dma_pos;
- src_bidx = 0;
- dst_bidx = data_type;
- src_cidx = 0;
- dst_cidx = data_type * fifo_level;
- }
-
- acnt = prtd->params->acnt;
- edma_set_src(prtd->asp_link[0], src, INCR, W8BIT);
- edma_set_dest(prtd->asp_link[0], dst, INCR, W8BIT);
-
- edma_set_src_index(prtd->asp_link[0], src_bidx, src_cidx);
- edma_set_dest_index(prtd->asp_link[0], dst_bidx, dst_cidx);
-
- if (!fifo_level)
- edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0,
- ASYNC);
- else
- edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level,
- count, fifo_level,
- ABSYNC);
-}
-
-static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data)
-{
- struct snd_pcm_substream *substream = data;
- struct davinci_runtime_data *prtd = substream->runtime->private_data;
-
- print_buf_info(prtd->ram_channel, "i ram_channel");
- pr_debug("davinci_pcm: link=%d, status=0x%x\n", link, ch_status);
-
- if (unlikely(ch_status != DMA_COMPLETE))
- return;
-
- if (snd_pcm_running(substream)) {
- spin_lock(&prtd->lock);
- if (prtd->ram_channel < 0) {
- /* No ping/pong must fix up link dma data*/
- davinci_pcm_enqueue_dma(substream);
- }
- davinci_pcm_period_elapsed(substream);
- spin_unlock(&prtd->lock);
- snd_pcm_period_elapsed(substream);
- }
-}
-
-static int allocate_sram(struct snd_pcm_substream *substream, unsigned size,
- struct snd_pcm_hardware *ppcm)
-{
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- struct snd_dma_buffer *iram_dma = NULL;
- dma_addr_t iram_phys = 0;
- void *iram_virt = NULL;
-
- if (buf->private_data || !size)
- return 0;
-
- ppcm->period_bytes_max = size;
- iram_virt = sram_alloc(size, &iram_phys);
- if (!iram_virt)
- goto exit1;
- iram_dma = kzalloc(sizeof(*iram_dma), GFP_KERNEL);
- if (!iram_dma)
- goto exit2;
- iram_dma->area = iram_virt;
- iram_dma->addr = iram_phys;
- memset(iram_dma->area, 0, size);
- iram_dma->bytes = size;
- buf->private_data = iram_dma;
- return 0;
-exit2:
- if (iram_virt)
- sram_free(iram_virt, size);
-exit1:
- return -ENOMEM;
-}
-
-/*
- * Only used with ping/pong.
- * This is called after runtime->dma_addr, period_bytes and data_type are valid
- */
-static int ping_pong_dma_setup(struct snd_pcm_substream *substream)
-{
- unsigned short ram_src_cidx, ram_dst_cidx;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct davinci_runtime_data *prtd = runtime->private_data;
- struct snd_dma_buffer *iram_dma =
- (struct snd_dma_buffer *)substream->dma_buffer.private_data;
- struct davinci_pcm_dma_params *params = prtd->params;
- unsigned int data_type = params->data_type;
- unsigned int acnt = params->acnt;
- /* divide by 2 for ping/pong */
- unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1;
- unsigned int fifo_level = prtd->params->fifo_level;
- unsigned int count;
- if ((data_type == 0) || (data_type > 4)) {
- printk(KERN_ERR "%s: data_type=%i\n", __func__, data_type);
- return -EINVAL;
- }
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- dma_addr_t asp_src_pong = iram_dma->addr + ping_size;
- ram_src_cidx = ping_size;
- ram_dst_cidx = -ping_size;
- edma_set_src(prtd->asp_link[1], asp_src_pong, INCR, W8BIT);
-
- edma_set_src_index(prtd->asp_link[0], data_type,
- data_type * fifo_level);
- edma_set_src_index(prtd->asp_link[1], data_type,
- data_type * fifo_level);
-
- edma_set_src(prtd->ram_link, runtime->dma_addr, INCR, W32BIT);
- } else {
- dma_addr_t asp_dst_pong = iram_dma->addr + ping_size;
- ram_src_cidx = -ping_size;
- ram_dst_cidx = ping_size;
- edma_set_dest(prtd->asp_link[1], asp_dst_pong, INCR, W8BIT);
-
- edma_set_dest_index(prtd->asp_link[0], data_type,
- data_type * fifo_level);
- edma_set_dest_index(prtd->asp_link[1], data_type,
- data_type * fifo_level);
-
- edma_set_dest(prtd->ram_link, runtime->dma_addr, INCR, W32BIT);
- }
-
- if (!fifo_level) {
- count = ping_size / data_type;
- edma_set_transfer_params(prtd->asp_link[0], acnt, count,
- 1, 0, ASYNC);
- edma_set_transfer_params(prtd->asp_link[1], acnt, count,
- 1, 0, ASYNC);
- } else {
- count = ping_size / (data_type * fifo_level);
- edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level,
- count, fifo_level, ABSYNC);
- edma_set_transfer_params(prtd->asp_link[1], acnt, fifo_level,
- count, fifo_level, ABSYNC);
- }
-
- edma_set_src_index(prtd->ram_link, ping_size, ram_src_cidx);
- edma_set_dest_index(prtd->ram_link, ping_size, ram_dst_cidx);
- edma_set_transfer_params(prtd->ram_link, ping_size, 2,
- runtime->periods, 2, ASYNC);
-
- /* init master params */
- edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
- edma_read_slot(prtd->ram_link, &prtd->ram_params);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- struct edmacc_param p_ram;
- /* Copy entire iram buffer before playback started */
- prtd->ram_params.a_b_cnt = (1 << 16) | (ping_size << 1);
- /* 0 dst_bidx */
- prtd->ram_params.src_dst_bidx = (ping_size << 1);
- /* 0 dst_cidx */
- prtd->ram_params.src_dst_cidx = (ping_size << 1);
- prtd->ram_params.ccnt = 1;
-
- /* Skip 1st period */
- edma_read_slot(prtd->ram_link, &p_ram);
- p_ram.src += (ping_size << 1);
- p_ram.ccnt -= 1;
- edma_write_slot(prtd->ram_link2, &p_ram);
- /*
- * When 1st started, ram -> iram dma channel will fill the
- * entire iram. Then, whenever a ping/pong asp buffer finishes,
- * 1/2 iram will be filled.
- */
- prtd->ram_params.link_bcntrld =
- EDMA_CHAN_SLOT(prtd->ram_link2) << 5;
- }
- return 0;
-}
-
-/* 1 asp tx or rx channel using 2 parameter channels
- * 1 ram to/from iram channel using 1 parameter channel
- *
- * Playback
- * ram copy channel kicks off first,
- * 1st ram copy of entire iram buffer completion kicks off asp channel
- * asp tcc always kicks off ram copy of 1/2 iram buffer
- *
- * Record
- * asp channel starts, tcc kicks off ram copy
- */
-static int request_ping_pong(struct snd_pcm_substream *substream,
- struct davinci_runtime_data *prtd,
- struct snd_dma_buffer *iram_dma)
-{
- dma_addr_t asp_src_ping;
- dma_addr_t asp_dst_ping;
- int ret;
- struct davinci_pcm_dma_params *params = prtd->params;
-
- /* Request ram master channel */
- ret = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY,
- davinci_pcm_dma_irq, substream,
- prtd->params->ram_chan_q);
- if (ret < 0)
- goto exit1;
-
- /* Request ram link channel */
- ret = prtd->ram_link = edma_alloc_slot(
- EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
- if (ret < 0)
- goto exit2;
-
- ret = prtd->asp_link[1] = edma_alloc_slot(
- EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
- if (ret < 0)
- goto exit3;
-
- prtd->ram_link2 = -1;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- ret = prtd->ram_link2 = edma_alloc_slot(
- EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
- if (ret < 0)
- goto exit4;
- }
- /* circle ping-pong buffers */
- edma_link(prtd->asp_link[0], prtd->asp_link[1]);
- edma_link(prtd->asp_link[1], prtd->asp_link[0]);
- /* circle ram buffers */
- edma_link(prtd->ram_link, prtd->ram_link);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- asp_src_ping = iram_dma->addr;
- asp_dst_ping = params->dma_addr; /* fifo */
- } else {
- asp_src_ping = params->dma_addr; /* fifo */
- asp_dst_ping = iram_dma->addr;
- }
- /* ping */
- edma_set_src(prtd->asp_link[0], asp_src_ping, INCR, W16BIT);
- edma_set_dest(prtd->asp_link[0], asp_dst_ping, INCR, W16BIT);
- edma_set_src_index(prtd->asp_link[0], 0, 0);
- edma_set_dest_index(prtd->asp_link[0], 0, 0);
-
- edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
- prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN);
- prtd->asp_params.opt |= TCCHEN |
- EDMA_TCC(prtd->ram_channel & 0x3f);
- edma_write_slot(prtd->asp_link[0], &prtd->asp_params);
-
- /* pong */
- edma_set_src(prtd->asp_link[1], asp_src_ping, INCR, W16BIT);
- edma_set_dest(prtd->asp_link[1], asp_dst_ping, INCR, W16BIT);
- edma_set_src_index(prtd->asp_link[1], 0, 0);
- edma_set_dest_index(prtd->asp_link[1], 0, 0);
-
- edma_read_slot(prtd->asp_link[1], &prtd->asp_params);
- prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f));
- /* interrupt after every pong completion */
- prtd->asp_params.opt |= TCINTEN | TCCHEN |
- EDMA_TCC(prtd->ram_channel & 0x3f);
- edma_write_slot(prtd->asp_link[1], &prtd->asp_params);
-
- /* ram */
- edma_set_src(prtd->ram_link, iram_dma->addr, INCR, W32BIT);
- edma_set_dest(prtd->ram_link, iram_dma->addr, INCR, W32BIT);
- pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u,"
- "for asp:%u %u %u\n", __func__,
- prtd->ram_channel, prtd->ram_link, prtd->ram_link2,
- prtd->asp_channel, prtd->asp_link[0],
- prtd->asp_link[1]);
- return 0;
-exit4:
- edma_free_channel(prtd->asp_link[1]);
- prtd->asp_link[1] = -1;
-exit3:
- edma_free_channel(prtd->ram_link);
- prtd->ram_link = -1;
-exit2:
- edma_free_channel(prtd->ram_channel);
- prtd->ram_channel = -1;
-exit1:
- return ret;
-}
-
-static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
-{
- struct snd_dma_buffer *iram_dma;
- struct davinci_runtime_data *prtd = substream->runtime->private_data;
- struct davinci_pcm_dma_params *params = prtd->params;
- int ret;
-
- if (!params)
- return -ENODEV;
-
- /* Request asp master DMA channel */
- ret = prtd->asp_channel = edma_alloc_channel(params->channel,
- davinci_pcm_dma_irq, substream,
- prtd->params->asp_chan_q);
- if (ret < 0)
- goto exit1;
-
- /* Request asp link channels */
- ret = prtd->asp_link[0] = edma_alloc_slot(
- EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
- if (ret < 0)
- goto exit2;
-
- iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data;
- if (iram_dma) {
- if (request_ping_pong(substream, prtd, iram_dma) == 0)
- return 0;
- printk(KERN_WARNING "%s: dma channel allocation failed,"
- "not using sram\n", __func__);
- }
-
- /* Issue transfer completion IRQ when the channel completes a
- * transfer, then always reload from the same slot (by a kind
- * of loopback link). The completion IRQ handler will update
- * the reload slot with a new buffer.
- *
- * REVISIT save p_ram here after setting up everything except
- * the buffer and its length (ccnt) ... use it as a template
- * so davinci_pcm_enqueue_dma() takes less time in IRQ.
- */
- edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
- prtd->asp_params.opt |= TCINTEN |
- EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel));
- prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(prtd->asp_link[0]) << 5;
- edma_write_slot(prtd->asp_link[0], &prtd->asp_params);
- return 0;
-exit2:
- edma_free_channel(prtd->asp_channel);
- prtd->asp_channel = -1;
-exit1:
- return ret;
-}
-
-static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct davinci_runtime_data *prtd = substream->runtime->private_data;
- int ret = 0;
-
- spin_lock(&prtd->lock);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- edma_start(prtd->asp_channel);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
- prtd->ram_channel >= 0) {
- /* copy 1st iram buffer */
- edma_start(prtd->ram_channel);
- }
- break;
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- edma_resume(prtd->asp_channel);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- edma_pause(prtd->asp_channel);
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- spin_unlock(&prtd->lock);
-
- return ret;
-}
-
-static int davinci_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct davinci_runtime_data *prtd = substream->runtime->private_data;
-
- davinci_pcm_period_reset(substream);
- if (prtd->ram_channel >= 0) {
- int ret = ping_pong_dma_setup(substream);
- if (ret < 0)
- return ret;
-
- edma_write_slot(prtd->ram_channel, &prtd->ram_params);
- edma_write_slot(prtd->asp_channel, &prtd->asp_params);
-
- print_buf_info(prtd->ram_channel, "ram_channel");
- print_buf_info(prtd->ram_link, "ram_link");
- print_buf_info(prtd->ram_link2, "ram_link2");
- print_buf_info(prtd->asp_channel, "asp_channel");
- print_buf_info(prtd->asp_link[0], "asp_link[0]");
- print_buf_info(prtd->asp_link[1], "asp_link[1]");
-
- /*
- * There is a phase offset of 2 periods between the position
- * used by dma setup and the position reported in the pointer
- * function.
- *
- * The phase offset, when not using ping-pong buffers, is due to
- * the two consecutive calls to davinci_pcm_enqueue_dma() below.
- *
- * Whereas here, with ping-pong buffers, the phase is due to
- * there being an entire buffer transfer complete before the
- * first dma completion event triggers davinci_pcm_dma_irq().
- */
- davinci_pcm_period_elapsed(substream);
- davinci_pcm_period_elapsed(substream);
-
- return 0;
- }
- davinci_pcm_enqueue_dma(substream);
- davinci_pcm_period_elapsed(substream);
-
- /* Copy self-linked parameter RAM entry into master channel */
- edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
- edma_write_slot(prtd->asp_channel, &prtd->asp_params);
- davinci_pcm_enqueue_dma(substream);
- davinci_pcm_period_elapsed(substream);
-
- return 0;
-}
-
-static snd_pcm_uframes_t
-davinci_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct davinci_runtime_data *prtd = runtime->private_data;
- unsigned int offset;
- int asp_count;
- unsigned int period_size = snd_pcm_lib_period_bytes(substream);
-
- /*
- * There is a phase offset of 2 periods between the position used by dma
- * setup and the position reported in the pointer function. Either +2 in
- * the dma setup or -2 here in the pointer function (with wrapping,
- * both) accounts for this offset -- choose the latter since it makes
- * the first-time setup clearer.
- */
- spin_lock(&prtd->lock);
- asp_count = prtd->period - 2;
- spin_unlock(&prtd->lock);
-
- if (asp_count < 0)
- asp_count += runtime->periods;
- asp_count *= period_size;
-
- offset = bytes_to_frames(runtime, asp_count);
- if (offset >= runtime->buffer_size)
- offset = 0;
-
- return offset;
-}
-
-static int davinci_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct davinci_runtime_data *prtd;
- struct snd_pcm_hardware *ppcm;
- int ret = 0;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct davinci_pcm_dma_params *pa;
- struct davinci_pcm_dma_params *params;
-
- pa = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
- if (!pa)
- return -ENODEV;
- params = &pa[substream->stream];
-
- ppcm = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
- &pcm_hardware_playback : &pcm_hardware_capture;
- allocate_sram(substream, params->sram_size, ppcm);
- snd_soc_set_runtime_hwparams(substream, ppcm);
- /* ensure that buffer size is a multiple of period size */
- ret = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (ret < 0)
- return ret;
-
- prtd = kzalloc(sizeof(struct davinci_runtime_data), GFP_KERNEL);
- if (prtd == NULL)
- return -ENOMEM;
-
- spin_lock_init(&prtd->lock);
- prtd->params = params;
- prtd->asp_channel = -1;
- prtd->asp_link[0] = prtd->asp_link[1] = -1;
- prtd->ram_channel = -1;
- prtd->ram_link = -1;
- prtd->ram_link2 = -1;
-
- runtime->private_data = prtd;
-
- ret = davinci_pcm_dma_request(substream);
- if (ret) {
- printk(KERN_ERR "davinci_pcm: Failed to get dma channels\n");
- kfree(prtd);
- }
-
- return ret;
-}
-
-static int davinci_pcm_close(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct davinci_runtime_data *prtd = runtime->private_data;
-
- if (prtd->ram_channel >= 0)
- edma_stop(prtd->ram_channel);
- if (prtd->asp_channel >= 0)
- edma_stop(prtd->asp_channel);
- if (prtd->asp_link[0] >= 0)
- edma_unlink(prtd->asp_link[0]);
- if (prtd->asp_link[1] >= 0)
- edma_unlink(prtd->asp_link[1]);
- if (prtd->ram_link >= 0)
- edma_unlink(prtd->ram_link);
-
- if (prtd->asp_link[0] >= 0)
- edma_free_slot(prtd->asp_link[0]);
- if (prtd->asp_link[1] >= 0)
- edma_free_slot(prtd->asp_link[1]);
- if (prtd->asp_channel >= 0)
- edma_free_channel(prtd->asp_channel);
- if (prtd->ram_link >= 0)
- edma_free_slot(prtd->ram_link);
- if (prtd->ram_link2 >= 0)
- edma_free_slot(prtd->ram_link2);
- if (prtd->ram_channel >= 0)
- edma_free_channel(prtd->ram_channel);
-
- kfree(prtd);
-
- return 0;
-}
-
-static int davinci_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-}
-
-static int davinci_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int davinci_pcm_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- return dma_mmap_writecombine(substream->pcm->card->dev, vma,
- runtime->dma_area,
- runtime->dma_addr,
- runtime->dma_bytes);
-}
-
-static struct snd_pcm_ops davinci_pcm_ops = {
- .open = davinci_pcm_open,
- .close = davinci_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = davinci_pcm_hw_params,
- .hw_free = davinci_pcm_hw_free,
- .prepare = davinci_pcm_prepare,
- .trigger = davinci_pcm_trigger,
- .pointer = davinci_pcm_pointer,
- .mmap = davinci_pcm_mmap,
-};
-
-static int davinci_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream,
- size_t size)
-{
- struct snd_pcm_substream *substream = pcm->streams[stream].substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
-
- buf->dev.type = SNDRV_DMA_TYPE_DEV;
- buf->dev.dev = pcm->card->dev;
- buf->private_data = NULL;
- buf->area = dma_alloc_writecombine(pcm->card->dev, size,
- &buf->addr, GFP_KERNEL);
-
- pr_debug("davinci_pcm: preallocate_dma_buffer: area=%p, addr=%p, "
- "size=%d\n", (void *) buf->area, (void *) buf->addr, size);
-
- if (!buf->area)
- return -ENOMEM;
-
- buf->bytes = size;
- return 0;
-}
-
-static void davinci_pcm_free(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- struct snd_dma_buffer *buf;
- int stream;
-
- for (stream = 0; stream < 2; stream++) {
- struct snd_dma_buffer *iram_dma;
- substream = pcm->streams[stream].substream;
- if (!substream)
- continue;
-
- buf = &substream->dma_buffer;
- if (!buf->area)
- continue;
-
- dma_free_writecombine(pcm->card->dev, buf->bytes,
- buf->area, buf->addr);
- buf->area = NULL;
- iram_dma = buf->private_data;
- if (iram_dma) {
- sram_free(iram_dma->area, iram_dma->bytes);
- kfree(iram_dma);
- }
- }
-}
-
-static u64 davinci_pcm_dmamask = DMA_BIT_MASK(32);
-
-static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- int ret;
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &davinci_pcm_dmamask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = davinci_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_PLAYBACK,
- pcm_hardware_playback.buffer_bytes_max);
- if (ret)
- return ret;
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- ret = davinci_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_CAPTURE,
- pcm_hardware_capture.buffer_bytes_max);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_soc_platform_driver davinci_soc_platform = {
- .ops = &davinci_pcm_ops,
- .pcm_new = davinci_pcm_new,
- .pcm_free = davinci_pcm_free,
-};
-
-static int __devinit davinci_soc_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_platform(&pdev->dev, &davinci_soc_platform);
-}
-
-static int __devexit davinci_soc_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver davinci_pcm_driver = {
- .driver = {
- .name = "davinci-pcm-audio",
- .owner = THIS_MODULE,
- },
-
- .probe = davinci_soc_platform_probe,
- .remove = __devexit_p(davinci_soc_platform_remove),
-};
-
-module_platform_driver(davinci_pcm_driver);
-
-MODULE_AUTHOR("Vladimir Barinov");
-MODULE_DESCRIPTION("TI DAVINCI PCM DMA module");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/davinci/davinci-pcm.h b/ANDROID_3.4.5/sound/soc/davinci/davinci-pcm.h
deleted file mode 100644
index c0d6c9be..00000000
--- a/ANDROID_3.4.5/sound/soc/davinci/davinci-pcm.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * ALSA PCM interface for the TI DAVINCI processor
- *
- * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
- * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _DAVINCI_PCM_H
-#define _DAVINCI_PCM_H
-
-#include <mach/edma.h>
-#include <mach/asp.h>
-
-
-struct davinci_pcm_dma_params {
- int channel; /* sync dma channel ID */
- unsigned short acnt;
- dma_addr_t dma_addr; /* device physical address for DMA */
- unsigned sram_size;
- enum dma_event_q asp_chan_q; /* event queue number for ASP channel */
- enum dma_event_q ram_chan_q; /* event queue number for RAM channel */
- unsigned char data_type; /* xfer data type */
- unsigned char convert_mono_stereo;
- unsigned int fifo_level;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/davinci/davinci-sffsdr.c b/ANDROID_3.4.5/sound/soc/davinci/davinci-sffsdr.c
deleted file mode 100644
index f71175b2..00000000
--- a/ANDROID_3.4.5/sound/soc/davinci/davinci-sffsdr.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * ASoC driver for Lyrtech SFFSDR board.
- *
- * Author: Hugo Villeneuve
- * Copyright (C) 2008 Lyrtech inc
- *
- * Based on ASoC driver for TI DAVINCI EVM platform, original copyright follow:
- * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/dma.h>
-#include <asm/mach-types.h>
-#ifdef CONFIG_SFFSDR_FPGA
-#include <asm/plat-sffsdr/sffsdr-fpga.h>
-#endif
-
-#include <mach/edma.h>
-
-#include "../codecs/pcm3008.h"
-#include "davinci-pcm.h"
-#include "davinci-i2s.h"
-
-/*
- * CLKX and CLKR are the inputs for the Sample Rate Generator.
- * FSX and FSR are outputs, driven by the sample Rate Generator.
- */
-#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
- SND_SOC_DAIFMT_CBM_CFS | \
- SND_SOC_DAIFMT_IB_NF)
-
-static int sffsdr_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int fs;
- int ret = 0;
-
- /* Fsref can be 32000, 44100 or 48000. */
- fs = params_rate(params);
-
-#ifndef CONFIG_SFFSDR_FPGA
- /* Without the FPGA module, the Fs is fixed at 44100 Hz */
- if (fs != 44100) {
- pr_debug("warning: only 44.1 kHz is supported without SFFSDR FPGA module\n");
- return -EINVAL;
- }
-#endif
-
- /* set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT);
- if (ret < 0)
- return ret;
-
- pr_debug("sffsdr_hw_params: rate = %d Hz\n", fs);
-
-#ifndef CONFIG_SFFSDR_FPGA
- return 0;
-#else
- return sffsdr_fpga_set_codec_fs(fs);
-#endif
-}
-
-static struct snd_soc_ops sffsdr_ops = {
- .hw_params = sffsdr_hw_params,
-};
-
-/* davinci-sffsdr digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link sffsdr_dai = {
- .name = "PCM3008", /* Codec name */
- .stream_name = "PCM3008 HiFi",
- .cpu_dai_name = "davinci-mcbsp",
- .codec_dai_name = "pcm3008-hifi",
- .codec_name = "pcm3008-codec",
- .platform_name = "davinci-pcm-audio",
- .ops = &sffsdr_ops,
-};
-
-/* davinci-sffsdr audio machine driver */
-static struct snd_soc_card snd_soc_sffsdr = {
- .name = "DaVinci SFFSDR",
- .owner = THIS_MODULE,
- .dai_link = &sffsdr_dai,
- .num_links = 1,
-};
-
-/* sffsdr audio private data */
-static struct pcm3008_setup_data sffsdr_pcm3008_setup = {
- .dem0_pin = GPIO(45),
- .dem1_pin = GPIO(46),
- .pdad_pin = GPIO(47),
- .pdda_pin = GPIO(38),
-};
-
-struct platform_device pcm3008_codec = {
- .name = "pcm3008-codec",
- .id = 0,
- .dev = {
- .platform_data = &sffsdr_pcm3008_setup,
- },
-};
-
-static struct resource sffsdr_snd_resources[] = {
- {
- .start = DAVINCI_MCBSP_BASE,
- .end = DAVINCI_MCBSP_BASE + SZ_8K - 1,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct evm_snd_platform_data sffsdr_snd_data = {
- .tx_dma_ch = DAVINCI_DMA_MCBSP_TX,
- .rx_dma_ch = DAVINCI_DMA_MCBSP_RX,
-};
-
-static struct platform_device *sffsdr_snd_device;
-
-static int __init sffsdr_init(void)
-{
- int ret;
-
- if (!machine_is_sffsdr())
- return -EINVAL;
-
- platform_device_register(&pcm3008_codec);
-
- sffsdr_snd_device = platform_device_alloc("soc-audio", 0);
- if (!sffsdr_snd_device) {
- printk(KERN_ERR "platform device allocation failed\n");
- return -ENOMEM;
- }
-
- platform_set_drvdata(sffsdr_snd_device, &snd_soc_sffsdr);
- platform_device_add_data(sffsdr_snd_device, &sffsdr_snd_data,
- sizeof(sffsdr_snd_data));
-
- ret = platform_device_add_resources(sffsdr_snd_device,
- sffsdr_snd_resources,
- ARRAY_SIZE(sffsdr_snd_resources));
- if (ret) {
- printk(KERN_ERR "platform device add resources failed\n");
- goto error;
- }
-
- ret = platform_device_add(sffsdr_snd_device);
- if (ret)
- goto error;
-
- return ret;
-
-error:
- platform_device_put(sffsdr_snd_device);
- return ret;
-}
-
-static void __exit sffsdr_exit(void)
-{
- platform_device_unregister(sffsdr_snd_device);
- platform_device_unregister(&pcm3008_codec);
-}
-
-module_init(sffsdr_init);
-module_exit(sffsdr_exit);
-
-MODULE_AUTHOR("Hugo Villeneuve");
-MODULE_DESCRIPTION("Lyrtech SFFSDR ASoC driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/davinci/davinci-vcif.c b/ANDROID_3.4.5/sound/soc/davinci/davinci-vcif.c
deleted file mode 100644
index da030ff8..00000000
--- a/ANDROID_3.4.5/sound/soc/davinci/davinci-vcif.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * ALSA SoC Voice Codec Interface for TI DAVINCI processor
- *
- * Copyright (C) 2010 Texas Instruments.
- *
- * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/mfd/davinci_voicecodec.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include "davinci-pcm.h"
-#include "davinci-i2s.h"
-
-#define MOD_REG_BIT(val, mask, set) do { \
- if (set) { \
- val |= mask; \
- } else { \
- val &= ~mask; \
- } \
-} while (0)
-
-struct davinci_vcif_dev {
- struct davinci_vc *davinci_vc;
- struct davinci_pcm_dma_params dma_params[2];
-};
-
-static void davinci_vcif_start(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct davinci_vcif_dev *davinci_vcif_dev =
- snd_soc_dai_get_drvdata(rtd->cpu_dai);
- struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc;
- u32 w;
-
- /* Start the sample generator and enable transmitter/receiver */
- w = readl(davinci_vc->base + DAVINCI_VC_CTRL);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 0);
- else
- MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 0);
-
- writel(w, davinci_vc->base + DAVINCI_VC_CTRL);
-}
-
-static void davinci_vcif_stop(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct davinci_vcif_dev *davinci_vcif_dev =
- snd_soc_dai_get_drvdata(rtd->cpu_dai);
- struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc;
- u32 w;
-
- /* Reset transmitter/receiver and sample rate/frame sync generators */
- w = readl(davinci_vc->base + DAVINCI_VC_CTRL);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 1);
- else
- MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 1);
-
- writel(w, davinci_vc->base + DAVINCI_VC_CTRL);
-}
-
-static int davinci_vcif_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct davinci_vcif_dev *davinci_vcif_dev = snd_soc_dai_get_drvdata(dai);
- struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc;
- struct davinci_pcm_dma_params *dma_params =
- &davinci_vcif_dev->dma_params[substream->stream];
- u32 w;
-
- /* Restart the codec before setup */
- davinci_vcif_stop(substream);
- davinci_vcif_start(substream);
-
- /* General line settings */
- writel(DAVINCI_VC_CTRL_MASK, davinci_vc->base + DAVINCI_VC_CTRL);
-
- writel(DAVINCI_VC_INT_MASK, davinci_vc->base + DAVINCI_VC_INTCLR);
-
- writel(DAVINCI_VC_INT_MASK, davinci_vc->base + DAVINCI_VC_INTEN);
-
- w = readl(davinci_vc->base + DAVINCI_VC_CTRL);
-
- /* Determine xfer data type */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_U8:
- dma_params->data_type = 0;
-
- MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 |
- DAVINCI_VC_CTRL_RD_UNSIGNED |
- DAVINCI_VC_CTRL_WD_BITS_8 |
- DAVINCI_VC_CTRL_WD_UNSIGNED, 1);
- break;
- case SNDRV_PCM_FORMAT_S8:
- dma_params->data_type = 1;
-
- MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 |
- DAVINCI_VC_CTRL_WD_BITS_8, 1);
-
- MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_UNSIGNED |
- DAVINCI_VC_CTRL_WD_UNSIGNED, 0);
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- dma_params->data_type = 2;
-
- MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 |
- DAVINCI_VC_CTRL_RD_UNSIGNED |
- DAVINCI_VC_CTRL_WD_BITS_8 |
- DAVINCI_VC_CTRL_WD_UNSIGNED, 0);
- break;
- default:
- printk(KERN_WARNING "davinci-vcif: unsupported PCM format");
- return -EINVAL;
- }
-
- dma_params->acnt = dma_params->data_type;
-
- writel(w, davinci_vc->base + DAVINCI_VC_CTRL);
-
- return 0;
-}
-
-static int davinci_vcif_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- int ret = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- davinci_vcif_start(substream);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- davinci_vcif_stop(substream);
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int davinci_vcif_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct davinci_vcif_dev *dev = snd_soc_dai_get_drvdata(dai);
-
- snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
- return 0;
-}
-
-#define DAVINCI_VCIF_RATES SNDRV_PCM_RATE_8000_48000
-
-static const struct snd_soc_dai_ops davinci_vcif_dai_ops = {
- .startup = davinci_vcif_startup,
- .trigger = davinci_vcif_trigger,
- .hw_params = davinci_vcif_hw_params,
-};
-
-static struct snd_soc_dai_driver davinci_vcif_dai = {
- .playback = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = DAVINCI_VCIF_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .capture = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = DAVINCI_VCIF_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .ops = &davinci_vcif_dai_ops,
-
-};
-
-static int davinci_vcif_probe(struct platform_device *pdev)
-{
- struct davinci_vc *davinci_vc = pdev->dev.platform_data;
- struct davinci_vcif_dev *davinci_vcif_dev;
- int ret;
-
- davinci_vcif_dev = devm_kzalloc(&pdev->dev,
- sizeof(struct davinci_vcif_dev),
- GFP_KERNEL);
- if (!davinci_vcif_dev) {
- dev_dbg(&pdev->dev,
- "could not allocate memory for private data\n");
- return -ENOMEM;
- }
-
- /* DMA tx params */
- davinci_vcif_dev->davinci_vc = davinci_vc;
- davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel =
- davinci_vc->davinci_vcif.dma_tx_channel;
- davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr =
- davinci_vc->davinci_vcif.dma_tx_addr;
-
- /* DMA rx params */
- davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel =
- davinci_vc->davinci_vcif.dma_rx_channel;
- davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr =
- davinci_vc->davinci_vcif.dma_rx_addr;
-
- dev_set_drvdata(&pdev->dev, davinci_vcif_dev);
-
- ret = snd_soc_register_dai(&pdev->dev, &davinci_vcif_dai);
- if (ret != 0) {
- dev_err(&pdev->dev, "could not register dai\n");
- return ret;
- }
-
- return 0;
-}
-
-static int davinci_vcif_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_dai(&pdev->dev);
-
- return 0;
-}
-
-static struct platform_driver davinci_vcif_driver = {
- .probe = davinci_vcif_probe,
- .remove = davinci_vcif_remove,
- .driver = {
- .name = "davinci-vcif",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(davinci_vcif_driver);
-
-MODULE_AUTHOR("Miguel Aguilar");
-MODULE_DESCRIPTION("Texas Instruments DaVinci ASoC Voice Codec Interface");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/ep93xx/Kconfig b/ANDROID_3.4.5/sound/soc/ep93xx/Kconfig
deleted file mode 100644
index 88143db7..00000000
--- a/ANDROID_3.4.5/sound/soc/ep93xx/Kconfig
+++ /dev/null
@@ -1,42 +0,0 @@
-config SND_EP93XX_SOC
- tristate "SoC Audio support for the Cirrus Logic EP93xx series"
- depends on ARCH_EP93XX && SND_SOC
- select SND_SOC_DMAENGINE_PCM
- help
- Say Y or M if you want to add support for codecs attached to
- the EP93xx I2S or AC97 interfaces.
-
-config SND_EP93XX_SOC_I2S
- tristate
-
-config SND_EP93XX_SOC_AC97
- tristate
- select AC97_BUS
- select SND_SOC_AC97_BUS
-
-config SND_EP93XX_SOC_SNAPPERCL15
- tristate "SoC Audio support for Bluewater Systems Snapper CL15 module"
- depends on SND_EP93XX_SOC && MACH_SNAPPER_CL15
- select SND_EP93XX_SOC_I2S
- select SND_SOC_TLV320AIC23
- help
- Say Y or M here if you want to add support for I2S audio on the
- Bluewater Systems Snapper CL15 module.
-
-config SND_EP93XX_SOC_SIMONE
- tristate "SoC Audio support for Simplemachines Sim.One board"
- depends on SND_EP93XX_SOC && MACH_SIM_ONE
- select SND_EP93XX_SOC_AC97
- select SND_SOC_AC97_CODEC
- help
- Say Y or M here if you want to add support for AC97 audio on the
- Simplemachines Sim.One board.
-
-config SND_EP93XX_SOC_EDB93XX
- tristate "SoC Audio support for Cirrus Logic EDB93xx boards"
- depends on SND_EP93XX_SOC && (MACH_EDB9301 || MACH_EDB9302 || MACH_EDB9302A || MACH_EDB9307A || MACH_EDB9315A)
- select SND_EP93XX_SOC_I2S
- select SND_SOC_CS4271
- help
- Say Y or M here if you want to add support for I2S audio on the
- Cirrus Logic EDB93xx boards.
diff --git a/ANDROID_3.4.5/sound/soc/ep93xx/Makefile b/ANDROID_3.4.5/sound/soc/ep93xx/Makefile
deleted file mode 100644
index 5514146c..00000000
--- a/ANDROID_3.4.5/sound/soc/ep93xx/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-# EP93xx Platform Support
-snd-soc-ep93xx-objs := ep93xx-pcm.o
-snd-soc-ep93xx-i2s-objs := ep93xx-i2s.o
-snd-soc-ep93xx-ac97-objs := ep93xx-ac97.o
-
-obj-$(CONFIG_SND_EP93XX_SOC) += snd-soc-ep93xx.o
-obj-$(CONFIG_SND_EP93XX_SOC_I2S) += snd-soc-ep93xx-i2s.o
-obj-$(CONFIG_SND_EP93XX_SOC_AC97) += snd-soc-ep93xx-ac97.o
-
-# EP93XX Machine Support
-snd-soc-snappercl15-objs := snappercl15.o
-snd-soc-simone-objs := simone.o
-snd-soc-edb93xx-objs := edb93xx.o
-
-obj-$(CONFIG_SND_EP93XX_SOC_SNAPPERCL15) += snd-soc-snappercl15.o
-obj-$(CONFIG_SND_EP93XX_SOC_SIMONE) += snd-soc-simone.o
-obj-$(CONFIG_SND_EP93XX_SOC_EDB93XX) += snd-soc-edb93xx.o
diff --git a/ANDROID_3.4.5/sound/soc/ep93xx/edb93xx.c b/ANDROID_3.4.5/sound/soc/ep93xx/edb93xx.c
deleted file mode 100644
index e01cb02a..00000000
--- a/ANDROID_3.4.5/sound/soc/ep93xx/edb93xx.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * SoC audio for EDB93xx
- *
- * Copyright (c) 2010 Alexander Sverdlin <subaparts@yandex.ru>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * This driver support CS4271 codec being master or slave, working
- * in control port mode, connected either via SPI or I2C.
- * The data format accepted is I2S or left-justified.
- * DAPM support not implemented.
- */
-
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include "ep93xx-pcm.h"
-
-static int edb93xx_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int err;
- unsigned int mclk_rate;
- unsigned int rate = params_rate(params);
-
- /*
- * According to CS4271 datasheet we use MCLK/LRCK=256 for
- * rates below 50kHz and 128 for higher sample rates
- */
- if (rate < 50000)
- mclk_rate = rate * 64 * 4;
- else
- mclk_rate = rate * 64 * 2;
-
- err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk_rate,
- SND_SOC_CLOCK_IN);
- if (err)
- return err;
-
- return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_rate,
- SND_SOC_CLOCK_OUT);
-}
-
-static struct snd_soc_ops edb93xx_ops = {
- .hw_params = edb93xx_hw_params,
-};
-
-static struct snd_soc_dai_link edb93xx_dai = {
- .name = "CS4271",
- .stream_name = "CS4271 HiFi",
- .platform_name = "ep93xx-pcm-audio",
- .cpu_dai_name = "ep93xx-i2s",
- .codec_name = "spi0.0",
- .codec_dai_name = "cs4271-hifi",
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
- SND_SOC_DAIFMT_CBS_CFS,
- .ops = &edb93xx_ops,
-};
-
-static struct snd_soc_card snd_soc_edb93xx = {
- .name = "EDB93XX",
- .owner = THIS_MODULE,
- .dai_link = &edb93xx_dai,
- .num_links = 1,
-};
-
-static int __devinit edb93xx_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &snd_soc_edb93xx;
- int ret;
-
- ret = ep93xx_i2s_acquire();
- if (ret)
- return ret;
-
- card->dev = &pdev->dev;
-
- ret = snd_soc_register_card(card);
- if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
- ret);
- ep93xx_i2s_release();
- }
-
- return ret;
-}
-
-static int __devexit edb93xx_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- snd_soc_unregister_card(card);
- ep93xx_i2s_release();
-
- return 0;
-}
-
-static struct platform_driver edb93xx_driver = {
- .driver = {
- .name = "edb93xx-audio",
- .owner = THIS_MODULE,
- },
- .probe = edb93xx_probe,
- .remove = __devexit_p(edb93xx_remove),
-};
-
-module_platform_driver(edb93xx_driver);
-
-MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>");
-MODULE_DESCRIPTION("ALSA SoC EDB93xx");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:edb93xx-audio");
diff --git a/ANDROID_3.4.5/sound/soc/ep93xx/ep93xx-ac97.c b/ANDROID_3.4.5/sound/soc/ep93xx/ep93xx-ac97.c
deleted file mode 100644
index 0678637a..00000000
--- a/ANDROID_3.4.5/sound/soc/ep93xx/ep93xx-ac97.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * ASoC driver for Cirrus Logic EP93xx AC97 controller.
- *
- * Copyright (c) 2010 Mika Westerberg
- *
- * Based on s3c-ac97 ASoC driver by Jaswinder Singh.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <sound/core.h>
-#include <sound/ac97_codec.h>
-#include <sound/soc.h>
-
-#include <mach/dma.h>
-#include "ep93xx-pcm.h"
-
-/*
- * Per channel (1-4) registers.
- */
-#define AC97CH(n) (((n) - 1) * 0x20)
-
-#define AC97DR(n) (AC97CH(n) + 0x0000)
-
-#define AC97RXCR(n) (AC97CH(n) + 0x0004)
-#define AC97RXCR_REN BIT(0)
-#define AC97RXCR_RX3 BIT(3)
-#define AC97RXCR_RX4 BIT(4)
-#define AC97RXCR_CM BIT(15)
-
-#define AC97TXCR(n) (AC97CH(n) + 0x0008)
-#define AC97TXCR_TEN BIT(0)
-#define AC97TXCR_TX3 BIT(3)
-#define AC97TXCR_TX4 BIT(4)
-#define AC97TXCR_CM BIT(15)
-
-#define AC97SR(n) (AC97CH(n) + 0x000c)
-#define AC97SR_TXFE BIT(1)
-#define AC97SR_TXUE BIT(6)
-
-#define AC97RISR(n) (AC97CH(n) + 0x0010)
-#define AC97ISR(n) (AC97CH(n) + 0x0014)
-#define AC97IE(n) (AC97CH(n) + 0x0018)
-
-/*
- * Global AC97 controller registers.
- */
-#define AC97S1DATA 0x0080
-#define AC97S2DATA 0x0084
-#define AC97S12DATA 0x0088
-
-#define AC97RGIS 0x008c
-#define AC97GIS 0x0090
-#define AC97IM 0x0094
-/*
- * Common bits for RGIS, GIS and IM registers.
- */
-#define AC97_SLOT2RXVALID BIT(1)
-#define AC97_CODECREADY BIT(5)
-#define AC97_SLOT2TXCOMPLETE BIT(6)
-
-#define AC97EOI 0x0098
-#define AC97EOI_WINT BIT(0)
-#define AC97EOI_CODECREADY BIT(1)
-
-#define AC97GCR 0x009c
-#define AC97GCR_AC97IFE BIT(0)
-
-#define AC97RESET 0x00a0
-#define AC97RESET_TIMEDRESET BIT(0)
-
-#define AC97SYNC 0x00a4
-#define AC97SYNC_TIMEDSYNC BIT(0)
-
-#define AC97_TIMEOUT msecs_to_jiffies(5)
-
-/**
- * struct ep93xx_ac97_info - EP93xx AC97 controller info structure
- * @lock: mutex serializing access to the bus (slot 1 & 2 ops)
- * @dev: pointer to the platform device dev structure
- * @mem: physical memory resource for the registers
- * @regs: mapped AC97 controller registers
- * @irq: AC97 interrupt number
- * @done: bus ops wait here for an interrupt
- */
-struct ep93xx_ac97_info {
- struct mutex lock;
- struct device *dev;
- struct resource *mem;
- void __iomem *regs;
- int irq;
- struct completion done;
-};
-
-/* currently ALSA only supports a single AC97 device */
-static struct ep93xx_ac97_info *ep93xx_ac97_info;
-
-static struct ep93xx_pcm_dma_params ep93xx_ac97_pcm_out = {
- .name = "ac97-pcm-out",
- .dma_port = EP93XX_DMA_AAC1,
-};
-
-static struct ep93xx_pcm_dma_params ep93xx_ac97_pcm_in = {
- .name = "ac97-pcm-in",
- .dma_port = EP93XX_DMA_AAC1,
-};
-
-static inline unsigned ep93xx_ac97_read_reg(struct ep93xx_ac97_info *info,
- unsigned reg)
-{
- return __raw_readl(info->regs + reg);
-}
-
-static inline void ep93xx_ac97_write_reg(struct ep93xx_ac97_info *info,
- unsigned reg, unsigned val)
-{
- __raw_writel(val, info->regs + reg);
-}
-
-static unsigned short ep93xx_ac97_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- struct ep93xx_ac97_info *info = ep93xx_ac97_info;
- unsigned short val;
-
- mutex_lock(&info->lock);
-
- ep93xx_ac97_write_reg(info, AC97S1DATA, reg);
- ep93xx_ac97_write_reg(info, AC97IM, AC97_SLOT2RXVALID);
- if (!wait_for_completion_timeout(&info->done, AC97_TIMEOUT)) {
- dev_warn(info->dev, "timeout reading register %x\n", reg);
- mutex_unlock(&info->lock);
- return -ETIMEDOUT;
- }
- val = (unsigned short)ep93xx_ac97_read_reg(info, AC97S2DATA);
-
- mutex_unlock(&info->lock);
- return val;
-}
-
-static void ep93xx_ac97_write(struct snd_ac97 *ac97,
- unsigned short reg,
- unsigned short val)
-{
- struct ep93xx_ac97_info *info = ep93xx_ac97_info;
-
- mutex_lock(&info->lock);
-
- /*
- * Writes to the codec need to be done so that slot 2 is filled in
- * before slot 1.
- */
- ep93xx_ac97_write_reg(info, AC97S2DATA, val);
- ep93xx_ac97_write_reg(info, AC97S1DATA, reg);
-
- ep93xx_ac97_write_reg(info, AC97IM, AC97_SLOT2TXCOMPLETE);
- if (!wait_for_completion_timeout(&info->done, AC97_TIMEOUT))
- dev_warn(info->dev, "timeout writing register %x\n", reg);
-
- mutex_unlock(&info->lock);
-}
-
-static void ep93xx_ac97_warm_reset(struct snd_ac97 *ac97)
-{
- struct ep93xx_ac97_info *info = ep93xx_ac97_info;
-
- mutex_lock(&info->lock);
-
- /*
- * We are assuming that before this functions gets called, the codec
- * BIT_CLK is stopped by forcing the codec into powerdown mode. We can
- * control the SYNC signal directly via AC97SYNC register. Using
- * TIMEDSYNC the controller will keep the SYNC high > 1us.
- */
- ep93xx_ac97_write_reg(info, AC97SYNC, AC97SYNC_TIMEDSYNC);
- ep93xx_ac97_write_reg(info, AC97IM, AC97_CODECREADY);
- if (!wait_for_completion_timeout(&info->done, AC97_TIMEOUT))
- dev_warn(info->dev, "codec warm reset timeout\n");
-
- mutex_unlock(&info->lock);
-}
-
-static void ep93xx_ac97_cold_reset(struct snd_ac97 *ac97)
-{
- struct ep93xx_ac97_info *info = ep93xx_ac97_info;
-
- mutex_lock(&info->lock);
-
- /*
- * For doing cold reset, we disable the AC97 controller interface, clear
- * WINT and CODECREADY bits, and finally enable the interface again.
- */
- ep93xx_ac97_write_reg(info, AC97GCR, 0);
- ep93xx_ac97_write_reg(info, AC97EOI, AC97EOI_CODECREADY | AC97EOI_WINT);
- ep93xx_ac97_write_reg(info, AC97GCR, AC97GCR_AC97IFE);
-
- /*
- * Now, assert the reset and wait for the codec to become ready.
- */
- ep93xx_ac97_write_reg(info, AC97RESET, AC97RESET_TIMEDRESET);
- ep93xx_ac97_write_reg(info, AC97IM, AC97_CODECREADY);
- if (!wait_for_completion_timeout(&info->done, AC97_TIMEOUT))
- dev_warn(info->dev, "codec cold reset timeout\n");
-
- /*
- * Give the codec some time to come fully out from the reset. This way
- * we ensure that the subsequent reads/writes will work.
- */
- usleep_range(15000, 20000);
-
- mutex_unlock(&info->lock);
-}
-
-static irqreturn_t ep93xx_ac97_interrupt(int irq, void *dev_id)
-{
- struct ep93xx_ac97_info *info = dev_id;
- unsigned status, mask;
-
- /*
- * Just mask out the interrupt and wake up the waiting thread.
- * Interrupts are cleared via reading/writing to slot 1 & 2 registers by
- * the waiting thread.
- */
- status = ep93xx_ac97_read_reg(info, AC97GIS);
- mask = ep93xx_ac97_read_reg(info, AC97IM);
- mask &= ~status;
- ep93xx_ac97_write_reg(info, AC97IM, mask);
-
- complete(&info->done);
- return IRQ_HANDLED;
-}
-
-struct snd_ac97_bus_ops soc_ac97_ops = {
- .read = ep93xx_ac97_read,
- .write = ep93xx_ac97_write,
- .reset = ep93xx_ac97_cold_reset,
- .warm_reset = ep93xx_ac97_warm_reset,
-};
-EXPORT_SYMBOL_GPL(soc_ac97_ops);
-
-static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream,
- int cmd, struct snd_soc_dai *dai)
-{
- struct ep93xx_ac97_info *info = snd_soc_dai_get_drvdata(dai);
- unsigned v = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- /*
- * Enable compact mode, TX slots 3 & 4, and the TX FIFO
- * itself.
- */
- v |= AC97TXCR_CM;
- v |= AC97TXCR_TX3 | AC97TXCR_TX4;
- v |= AC97TXCR_TEN;
- ep93xx_ac97_write_reg(info, AC97TXCR(1), v);
- } else {
- /*
- * Enable compact mode, RX slots 3 & 4, and the RX FIFO
- * itself.
- */
- v |= AC97RXCR_CM;
- v |= AC97RXCR_RX3 | AC97RXCR_RX4;
- v |= AC97RXCR_REN;
- ep93xx_ac97_write_reg(info, AC97RXCR(1), v);
- }
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- /*
- * As per Cirrus EP93xx errata described below:
- *
- * http://www.cirrus.com/en/pubs/errata/ER667E2B.pdf
- *
- * we will wait for the TX FIFO to be empty before
- * clearing the TEN bit.
- */
- unsigned long timeout = jiffies + AC97_TIMEOUT;
-
- do {
- v = ep93xx_ac97_read_reg(info, AC97SR(1));
- if (time_after(jiffies, timeout)) {
- dev_warn(info->dev, "TX timeout\n");
- break;
- }
- } while (!(v & (AC97SR_TXFE | AC97SR_TXUE)));
-
- /* disable the TX FIFO */
- ep93xx_ac97_write_reg(info, AC97TXCR(1), 0);
- } else {
- /* disable the RX FIFO */
- ep93xx_ac97_write_reg(info, AC97RXCR(1), 0);
- }
- break;
-
- default:
- dev_warn(info->dev, "unknown command %d\n", cmd);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int ep93xx_ac97_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct ep93xx_pcm_dma_params *dma_data;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dma_data = &ep93xx_ac97_pcm_out;
- else
- dma_data = &ep93xx_ac97_pcm_in;
-
- snd_soc_dai_set_dma_data(dai, substream, dma_data);
- return 0;
-}
-
-static const struct snd_soc_dai_ops ep93xx_ac97_dai_ops = {
- .startup = ep93xx_ac97_startup,
- .trigger = ep93xx_ac97_trigger,
-};
-
-static struct snd_soc_dai_driver ep93xx_ac97_dai = {
- .name = "ep93xx-ac97",
- .id = 0,
- .ac97_control = 1,
- .playback = {
- .stream_name = "AC97 Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .capture = {
- .stream_name = "AC97 Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .ops = &ep93xx_ac97_dai_ops,
-};
-
-static int __devinit ep93xx_ac97_probe(struct platform_device *pdev)
-{
- struct ep93xx_ac97_info *info;
- int ret;
-
- info = kzalloc(sizeof(struct ep93xx_ac97_info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
-
- dev_set_drvdata(&pdev->dev, info);
-
- mutex_init(&info->lock);
- init_completion(&info->done);
- info->dev = &pdev->dev;
-
- info->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!info->mem) {
- ret = -ENXIO;
- goto fail_free_info;
- }
-
- info->irq = platform_get_irq(pdev, 0);
- if (!info->irq) {
- ret = -ENXIO;
- goto fail_free_info;
- }
-
- if (!request_mem_region(info->mem->start, resource_size(info->mem),
- pdev->name)) {
- ret = -EBUSY;
- goto fail_free_info;
- }
-
- info->regs = ioremap(info->mem->start, resource_size(info->mem));
- if (!info->regs) {
- ret = -ENOMEM;
- goto fail_release_mem;
- }
-
- ret = request_irq(info->irq, ep93xx_ac97_interrupt, IRQF_TRIGGER_HIGH,
- pdev->name, info);
- if (ret)
- goto fail_unmap_mem;
-
- ep93xx_ac97_info = info;
- platform_set_drvdata(pdev, info);
-
- ret = snd_soc_register_dai(&pdev->dev, &ep93xx_ac97_dai);
- if (ret)
- goto fail_free_irq;
-
- return 0;
-
-fail_free_irq:
- platform_set_drvdata(pdev, NULL);
- free_irq(info->irq, info);
-fail_unmap_mem:
- iounmap(info->regs);
-fail_release_mem:
- release_mem_region(info->mem->start, resource_size(info->mem));
-fail_free_info:
- kfree(info);
-
- return ret;
-}
-
-static int __devexit ep93xx_ac97_remove(struct platform_device *pdev)
-{
- struct ep93xx_ac97_info *info = platform_get_drvdata(pdev);
-
- snd_soc_unregister_dai(&pdev->dev);
-
- /* disable the AC97 controller */
- ep93xx_ac97_write_reg(info, AC97GCR, 0);
-
- free_irq(info->irq, info);
- iounmap(info->regs);
- release_mem_region(info->mem->start, resource_size(info->mem));
- platform_set_drvdata(pdev, NULL);
- kfree(info);
-
- return 0;
-}
-
-static struct platform_driver ep93xx_ac97_driver = {
- .probe = ep93xx_ac97_probe,
- .remove = __devexit_p(ep93xx_ac97_remove),
- .driver = {
- .name = "ep93xx-ac97",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(ep93xx_ac97_driver);
-
-MODULE_DESCRIPTION("EP93xx AC97 ASoC Driver");
-MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:ep93xx-ac97");
diff --git a/ANDROID_3.4.5/sound/soc/ep93xx/ep93xx-i2s.c b/ANDROID_3.4.5/sound/soc/ep93xx/ep93xx-i2s.c
deleted file mode 100644
index f7a62348..00000000
--- a/ANDROID_3.4.5/sound/soc/ep93xx/ep93xx-i2s.c
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- * linux/sound/soc/ep93xx-i2s.c
- * EP93xx I2S driver
- *
- * Copyright (C) 2010 Ryan Mallon
- *
- * Based on the original driver by:
- * Copyright (C) 2007 Chase Douglas <chasedouglas@gmail>
- * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include <mach/hardware.h>
-#include <mach/ep93xx-regs.h>
-#include <mach/dma.h>
-
-#include "ep93xx-pcm.h"
-
-#define EP93XX_I2S_TXCLKCFG 0x00
-#define EP93XX_I2S_RXCLKCFG 0x04
-#define EP93XX_I2S_GLCTRL 0x0C
-
-#define EP93XX_I2S_TXLINCTRLDATA 0x28
-#define EP93XX_I2S_TXCTRL 0x2C
-#define EP93XX_I2S_TXWRDLEN 0x30
-#define EP93XX_I2S_TX0EN 0x34
-
-#define EP93XX_I2S_RXLINCTRLDATA 0x58
-#define EP93XX_I2S_RXCTRL 0x5C
-#define EP93XX_I2S_RXWRDLEN 0x60
-#define EP93XX_I2S_RX0EN 0x64
-
-#define EP93XX_I2S_WRDLEN_16 (0 << 0)
-#define EP93XX_I2S_WRDLEN_24 (1 << 0)
-#define EP93XX_I2S_WRDLEN_32 (2 << 0)
-
-#define EP93XX_I2S_LINCTRLDATA_R_JUST (1 << 2) /* Right justify */
-
-#define EP93XX_I2S_CLKCFG_LRS (1 << 0) /* lrclk polarity */
-#define EP93XX_I2S_CLKCFG_CKP (1 << 1) /* Bit clock polarity */
-#define EP93XX_I2S_CLKCFG_REL (1 << 2) /* First bit transition */
-#define EP93XX_I2S_CLKCFG_MASTER (1 << 3) /* Master mode */
-#define EP93XX_I2S_CLKCFG_NBCG (1 << 4) /* Not bit clock gating */
-
-struct ep93xx_i2s_info {
- struct clk *mclk;
- struct clk *sclk;
- struct clk *lrclk;
- struct ep93xx_pcm_dma_params *dma_params;
- struct resource *mem;
- void __iomem *regs;
-};
-
-struct ep93xx_pcm_dma_params ep93xx_i2s_dma_params[] = {
- [SNDRV_PCM_STREAM_PLAYBACK] = {
- .name = "i2s-pcm-out",
- .dma_port = EP93XX_DMA_I2S1,
- },
- [SNDRV_PCM_STREAM_CAPTURE] = {
- .name = "i2s-pcm-in",
- .dma_port = EP93XX_DMA_I2S1,
- },
-};
-
-static inline void ep93xx_i2s_write_reg(struct ep93xx_i2s_info *info,
- unsigned reg, unsigned val)
-{
- __raw_writel(val, info->regs + reg);
-}
-
-static inline unsigned ep93xx_i2s_read_reg(struct ep93xx_i2s_info *info,
- unsigned reg)
-{
- return __raw_readl(info->regs + reg);
-}
-
-static void ep93xx_i2s_enable(struct ep93xx_i2s_info *info, int stream)
-{
- unsigned base_reg;
- int i;
-
- if ((ep93xx_i2s_read_reg(info, EP93XX_I2S_TX0EN) & 0x1) == 0 &&
- (ep93xx_i2s_read_reg(info, EP93XX_I2S_RX0EN) & 0x1) == 0) {
- /* Enable clocks */
- clk_enable(info->mclk);
- clk_enable(info->sclk);
- clk_enable(info->lrclk);
-
- /* Enable i2s */
- ep93xx_i2s_write_reg(info, EP93XX_I2S_GLCTRL, 1);
- }
-
- /* Enable fifos */
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
- base_reg = EP93XX_I2S_TX0EN;
- else
- base_reg = EP93XX_I2S_RX0EN;
- for (i = 0; i < 3; i++)
- ep93xx_i2s_write_reg(info, base_reg + (i * 4), 1);
-}
-
-static void ep93xx_i2s_disable(struct ep93xx_i2s_info *info, int stream)
-{
- unsigned base_reg;
- int i;
-
- /* Disable fifos */
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
- base_reg = EP93XX_I2S_TX0EN;
- else
- base_reg = EP93XX_I2S_RX0EN;
- for (i = 0; i < 3; i++)
- ep93xx_i2s_write_reg(info, base_reg + (i * 4), 0);
-
- if ((ep93xx_i2s_read_reg(info, EP93XX_I2S_TX0EN) & 0x1) == 0 &&
- (ep93xx_i2s_read_reg(info, EP93XX_I2S_RX0EN) & 0x1) == 0) {
- /* Disable i2s */
- ep93xx_i2s_write_reg(info, EP93XX_I2S_GLCTRL, 0);
-
- /* Disable clocks */
- clk_disable(info->lrclk);
- clk_disable(info->sclk);
- clk_disable(info->mclk);
- }
-}
-
-static int ep93xx_i2s_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-
- snd_soc_dai_set_dma_data(cpu_dai, substream,
- &info->dma_params[substream->stream]);
- return 0;
-}
-
-static void ep93xx_i2s_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
-
- ep93xx_i2s_disable(info, substream->stream);
-}
-
-static int ep93xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
- unsigned int fmt)
-{
- struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(cpu_dai);
- unsigned int clk_cfg, lin_ctrl;
-
- clk_cfg = ep93xx_i2s_read_reg(info, EP93XX_I2S_RXCLKCFG);
- lin_ctrl = ep93xx_i2s_read_reg(info, EP93XX_I2S_RXLINCTRLDATA);
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- clk_cfg |= EP93XX_I2S_CLKCFG_REL;
- lin_ctrl &= ~EP93XX_I2S_LINCTRLDATA_R_JUST;
- break;
-
- case SND_SOC_DAIFMT_LEFT_J:
- clk_cfg &= ~EP93XX_I2S_CLKCFG_REL;
- lin_ctrl &= ~EP93XX_I2S_LINCTRLDATA_R_JUST;
- break;
-
- case SND_SOC_DAIFMT_RIGHT_J:
- clk_cfg &= ~EP93XX_I2S_CLKCFG_REL;
- lin_ctrl |= EP93XX_I2S_LINCTRLDATA_R_JUST;
- break;
-
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- /* CPU is master */
- clk_cfg |= EP93XX_I2S_CLKCFG_MASTER;
- break;
-
- case SND_SOC_DAIFMT_CBM_CFM:
- /* Codec is master */
- clk_cfg &= ~EP93XX_I2S_CLKCFG_MASTER;
- break;
-
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- /* Negative bit clock, lrclk low on left word */
- clk_cfg &= ~(EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_REL);
- break;
-
- case SND_SOC_DAIFMT_NB_IF:
- /* Negative bit clock, lrclk low on right word */
- clk_cfg &= ~EP93XX_I2S_CLKCFG_CKP;
- clk_cfg |= EP93XX_I2S_CLKCFG_REL;
- break;
-
- case SND_SOC_DAIFMT_IB_NF:
- /* Positive bit clock, lrclk low on left word */
- clk_cfg |= EP93XX_I2S_CLKCFG_CKP;
- clk_cfg &= ~EP93XX_I2S_CLKCFG_REL;
- break;
-
- case SND_SOC_DAIFMT_IB_IF:
- /* Positive bit clock, lrclk low on right word */
- clk_cfg |= EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_REL;
- break;
- }
-
- /* Write new register values */
- ep93xx_i2s_write_reg(info, EP93XX_I2S_RXCLKCFG, clk_cfg);
- ep93xx_i2s_write_reg(info, EP93XX_I2S_TXCLKCFG, clk_cfg);
- ep93xx_i2s_write_reg(info, EP93XX_I2S_RXLINCTRLDATA, lin_ctrl);
- ep93xx_i2s_write_reg(info, EP93XX_I2S_TXLINCTRLDATA, lin_ctrl);
- return 0;
-}
-
-static int ep93xx_i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
- unsigned word_len, div, sdiv, lrdiv;
- int err;
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- word_len = EP93XX_I2S_WRDLEN_16;
- break;
-
- case SNDRV_PCM_FORMAT_S24_LE:
- word_len = EP93XX_I2S_WRDLEN_24;
- break;
-
- case SNDRV_PCM_FORMAT_S32_LE:
- word_len = EP93XX_I2S_WRDLEN_32;
- break;
-
- default:
- return -EINVAL;
- }
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- ep93xx_i2s_write_reg(info, EP93XX_I2S_TXWRDLEN, word_len);
- else
- ep93xx_i2s_write_reg(info, EP93XX_I2S_RXWRDLEN, word_len);
-
- /*
- * EP93xx I2S module can be setup so SCLK / LRCLK value can be
- * 32, 64, 128. MCLK / SCLK value can be 2 and 4.
- * We set LRCLK equal to `rate' and minimum SCLK / LRCLK
- * value is 64, because our sample size is 32 bit * 2 channels.
- * I2S standard permits us to transmit more bits than
- * the codec uses.
- */
- div = clk_get_rate(info->mclk) / params_rate(params);
- sdiv = 4;
- if (div > (256 + 512) / 2) {
- lrdiv = 128;
- } else {
- lrdiv = 64;
- if (div < (128 + 256) / 2)
- sdiv = 2;
- }
-
- err = clk_set_rate(info->sclk, clk_get_rate(info->mclk) / sdiv);
- if (err)
- return err;
-
- err = clk_set_rate(info->lrclk, clk_get_rate(info->sclk) / lrdiv);
- if (err)
- return err;
-
- ep93xx_i2s_enable(info, substream->stream);
- return 0;
-}
-
-static int ep93xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id,
- unsigned int freq, int dir)
-{
- struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(cpu_dai);
-
- if (dir == SND_SOC_CLOCK_IN || clk_id != 0)
- return -EINVAL;
-
- return clk_set_rate(info->mclk, freq);
-}
-
-#ifdef CONFIG_PM
-static int ep93xx_i2s_suspend(struct snd_soc_dai *dai)
-{
- struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
-
- if (!dai->active)
- return 0;
-
- ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_PLAYBACK);
- ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_CAPTURE);
-
- return 0;
-}
-
-static int ep93xx_i2s_resume(struct snd_soc_dai *dai)
-{
- struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
-
- if (!dai->active)
- return 0;
-
- ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_PLAYBACK);
- ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_CAPTURE);
-
- return 0;
-}
-#else
-#define ep93xx_i2s_suspend NULL
-#define ep93xx_i2s_resume NULL
-#endif
-
-static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {
- .startup = ep93xx_i2s_startup,
- .shutdown = ep93xx_i2s_shutdown,
- .hw_params = ep93xx_i2s_hw_params,
- .set_sysclk = ep93xx_i2s_set_sysclk,
- .set_fmt = ep93xx_i2s_set_dai_fmt,
-};
-
-#define EP93XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
-
-static struct snd_soc_dai_driver ep93xx_i2s_dai = {
- .symmetric_rates= 1,
- .suspend = ep93xx_i2s_suspend,
- .resume = ep93xx_i2s_resume,
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_192000,
- .formats = EP93XX_I2S_FORMATS,
- },
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_192000,
- .formats = EP93XX_I2S_FORMATS,
- },
- .ops = &ep93xx_i2s_dai_ops,
-};
-
-static int ep93xx_i2s_probe(struct platform_device *pdev)
-{
- struct ep93xx_i2s_info *info;
- struct resource *res;
- int err;
-
- info = kzalloc(sizeof(struct ep93xx_i2s_info), GFP_KERNEL);
- if (!info) {
- err = -ENOMEM;
- goto fail;
- }
-
- dev_set_drvdata(&pdev->dev, info);
- info->dma_params = ep93xx_i2s_dma_params;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- err = -ENODEV;
- goto fail_free_info;
- }
-
- info->mem = request_mem_region(res->start, resource_size(res),
- pdev->name);
- if (!info->mem) {
- err = -EBUSY;
- goto fail_free_info;
- }
-
- info->regs = ioremap(info->mem->start, resource_size(info->mem));
- if (!info->regs) {
- err = -ENXIO;
- goto fail_release_mem;
- }
-
- info->mclk = clk_get(&pdev->dev, "mclk");
- if (IS_ERR(info->mclk)) {
- err = PTR_ERR(info->mclk);
- goto fail_unmap_mem;
- }
-
- info->sclk = clk_get(&pdev->dev, "sclk");
- if (IS_ERR(info->sclk)) {
- err = PTR_ERR(info->sclk);
- goto fail_put_mclk;
- }
-
- info->lrclk = clk_get(&pdev->dev, "lrclk");
- if (IS_ERR(info->lrclk)) {
- err = PTR_ERR(info->lrclk);
- goto fail_put_sclk;
- }
-
- err = snd_soc_register_dai(&pdev->dev, &ep93xx_i2s_dai);
- if (err)
- goto fail_put_lrclk;
-
- return 0;
-
-fail_put_lrclk:
- clk_put(info->lrclk);
-fail_put_sclk:
- clk_put(info->sclk);
-fail_put_mclk:
- clk_put(info->mclk);
-fail_unmap_mem:
- iounmap(info->regs);
-fail_release_mem:
- release_mem_region(info->mem->start, resource_size(info->mem));
-fail_free_info:
- kfree(info);
-fail:
- return err;
-}
-
-static int __devexit ep93xx_i2s_remove(struct platform_device *pdev)
-{
- struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev);
-
- snd_soc_unregister_dai(&pdev->dev);
- clk_put(info->lrclk);
- clk_put(info->sclk);
- clk_put(info->mclk);
- iounmap(info->regs);
- release_mem_region(info->mem->start, resource_size(info->mem));
- kfree(info);
- return 0;
-}
-
-static struct platform_driver ep93xx_i2s_driver = {
- .probe = ep93xx_i2s_probe,
- .remove = __devexit_p(ep93xx_i2s_remove),
- .driver = {
- .name = "ep93xx-i2s",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(ep93xx_i2s_driver);
-
-MODULE_ALIAS("platform:ep93xx-i2s");
-MODULE_AUTHOR("Ryan Mallon");
-MODULE_DESCRIPTION("EP93XX I2S driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/ep93xx/ep93xx-pcm.c b/ANDROID_3.4.5/sound/soc/ep93xx/ep93xx-pcm.c
deleted file mode 100644
index 162dbb74..00000000
--- a/ANDROID_3.4.5/sound/soc/ep93xx/ep93xx-pcm.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * linux/sound/arm/ep93xx-pcm.c - EP93xx ALSA PCM interface
- *
- * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
- * Copyright (C) 2006 Applied Data Systems
- *
- * Rewritten for the SoC audio subsystem (Based on PXA2xx code):
- * Copyright (c) 2008 Ryan Mallon
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <linux/dmaengine.h>
-#include <linux/dma-mapping.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/dmaengine_pcm.h>
-
-#include <mach/dma.h>
-#include <mach/hardware.h>
-#include <mach/ep93xx-regs.h>
-
-#include "ep93xx-pcm.h"
-
-static const struct snd_pcm_hardware ep93xx_pcm_hardware = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER),
-
- .rates = SNDRV_PCM_RATE_8000_192000,
- .rate_min = SNDRV_PCM_RATE_8000,
- .rate_max = SNDRV_PCM_RATE_192000,
-
- .formats = (SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE),
-
- .buffer_bytes_max = 131072,
- .period_bytes_min = 32,
- .period_bytes_max = 32768,
- .periods_min = 1,
- .periods_max = 32,
- .fifo_size = 32,
-};
-
-static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param)
-{
- struct ep93xx_dma_data *data = filter_param;
-
- if (data->direction == ep93xx_dma_chan_direction(chan)) {
- chan->private = data;
- return true;
- }
-
- return false;
-}
-
-static int ep93xx_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct ep93xx_pcm_dma_params *dma_params;
- struct ep93xx_dma_data *dma_data;
- int ret;
-
- snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware);
-
- dma_data = kmalloc(sizeof(*dma_data), GFP_KERNEL);
- if (!dma_data)
- return -ENOMEM;
-
- dma_params = snd_soc_dai_get_dma_data(cpu_dai, substream);
- dma_data->port = dma_params->dma_port;
- dma_data->name = dma_params->name;
- dma_data->direction = snd_pcm_substream_to_dma_direction(substream);
-
- ret = snd_dmaengine_pcm_open(substream, ep93xx_pcm_dma_filter, dma_data);
- if (ret) {
- kfree(dma_data);
- return ret;
- }
-
- snd_dmaengine_pcm_set_data(substream, dma_data);
-
- return 0;
-}
-
-static int ep93xx_pcm_close(struct snd_pcm_substream *substream)
-{
- struct dma_data *dma_data = snd_dmaengine_pcm_get_data(substream);
-
- snd_dmaengine_pcm_close(substream);
- kfree(dma_data);
- return 0;
-}
-
-static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
-
- return 0;
-}
-
-static int ep93xx_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- snd_pcm_set_runtime_buffer(substream, NULL);
- return 0;
-}
-
-static int ep93xx_pcm_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- return dma_mmap_writecombine(substream->pcm->card->dev, vma,
- runtime->dma_area,
- runtime->dma_addr,
- runtime->dma_bytes);
-}
-
-static struct snd_pcm_ops ep93xx_pcm_ops = {
- .open = ep93xx_pcm_open,
- .close = ep93xx_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = ep93xx_pcm_hw_params,
- .hw_free = ep93xx_pcm_hw_free,
- .trigger = snd_dmaengine_pcm_trigger,
- .pointer = snd_dmaengine_pcm_pointer,
- .mmap = ep93xx_pcm_mmap,
-};
-
-static int ep93xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
- struct snd_pcm_substream *substream = pcm->streams[stream].substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = ep93xx_pcm_hardware.buffer_bytes_max;
-
- buf->dev.type = SNDRV_DMA_TYPE_DEV;
- buf->dev.dev = pcm->card->dev;
- buf->private_data = NULL;
- buf->area = dma_alloc_writecombine(pcm->card->dev, size,
- &buf->addr, GFP_KERNEL);
- buf->bytes = size;
-
- return (buf->area == NULL) ? -ENOMEM : 0;
-}
-
-static void ep93xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- struct snd_dma_buffer *buf;
- int stream;
-
- for (stream = 0; stream < 2; stream++) {
- substream = pcm->streams[stream].substream;
- if (!substream)
- continue;
-
- buf = &substream->dma_buffer;
- if (!buf->area)
- continue;
-
- dma_free_writecombine(pcm->card->dev, buf->bytes, buf->area,
- buf->addr);
- buf->area = NULL;
- }
-}
-
-static u64 ep93xx_pcm_dmamask = DMA_BIT_MASK(32);
-
-static int ep93xx_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- int ret = 0;
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &ep93xx_pcm_dmamask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = ep93xx_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_PLAYBACK);
- if (ret)
- return ret;
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- ret = ep93xx_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_CAPTURE);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_soc_platform_driver ep93xx_soc_platform = {
- .ops = &ep93xx_pcm_ops,
- .pcm_new = &ep93xx_pcm_new,
- .pcm_free = &ep93xx_pcm_free_dma_buffers,
-};
-
-static int __devinit ep93xx_soc_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_platform(&pdev->dev, &ep93xx_soc_platform);
-}
-
-static int __devexit ep93xx_soc_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver ep93xx_pcm_driver = {
- .driver = {
- .name = "ep93xx-pcm-audio",
- .owner = THIS_MODULE,
- },
-
- .probe = ep93xx_soc_platform_probe,
- .remove = __devexit_p(ep93xx_soc_platform_remove),
-};
-
-module_platform_driver(ep93xx_pcm_driver);
-
-MODULE_AUTHOR("Ryan Mallon");
-MODULE_DESCRIPTION("EP93xx ALSA PCM interface");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:ep93xx-pcm-audio");
diff --git a/ANDROID_3.4.5/sound/soc/ep93xx/ep93xx-pcm.h b/ANDROID_3.4.5/sound/soc/ep93xx/ep93xx-pcm.h
deleted file mode 100644
index 111e1121..00000000
--- a/ANDROID_3.4.5/sound/soc/ep93xx/ep93xx-pcm.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * sound/soc/ep93xx/ep93xx-pcm.h - EP93xx ALSA PCM interface
- *
- * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
- * Copyright (C) 2006 Applied Data Systems
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _EP93XX_SND_SOC_PCM_H
-#define _EP93XX_SND_SOC_PCM_H
-
-struct ep93xx_pcm_dma_params {
- char *name;
- int dma_port;
-};
-
-#endif /* _EP93XX_SND_SOC_PCM_H */
diff --git a/ANDROID_3.4.5/sound/soc/ep93xx/simone.c b/ANDROID_3.4.5/sound/soc/ep93xx/simone.c
deleted file mode 100644
index dd997094..00000000
--- a/ANDROID_3.4.5/sound/soc/ep93xx/simone.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * simone.c -- ASoC audio for Simplemachines Sim.One board
- *
- * Copyright (c) 2010 Mika Westerberg
- *
- * Based on snappercl15 machine driver by Ryan Mallon.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-
-#include "ep93xx-pcm.h"
-
-static struct snd_soc_dai_link simone_dai = {
- .name = "AC97",
- .stream_name = "AC97 HiFi",
- .cpu_dai_name = "ep93xx-ac97",
- .codec_dai_name = "ac97-hifi",
- .codec_name = "ac97-codec",
- .platform_name = "ep93xx-pcm-audio",
-};
-
-static struct snd_soc_card snd_soc_simone = {
- .name = "Sim.One",
- .owner = THIS_MODULE,
- .dai_link = &simone_dai,
- .num_links = 1,
-};
-
-static struct platform_device *simone_snd_ac97_device;
-
-static int __devinit simone_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &snd_soc_simone;
- int ret;
-
- simone_snd_ac97_device = platform_device_register_simple("ac97-codec",
- -1, NULL, 0);
- if (IS_ERR(simone_snd_ac97_device))
- return PTR_ERR(simone_snd_ac97_device);
-
- card->dev = &pdev->dev;
-
- ret = snd_soc_register_card(card);
- if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
- ret);
- platform_device_unregister(simone_snd_ac97_device);
- }
-
- return ret;
-}
-
-static int __devexit simone_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- snd_soc_unregister_card(card);
- platform_device_unregister(simone_snd_ac97_device);
-
- return 0;
-}
-
-static struct platform_driver simone_driver = {
- .driver = {
- .name = "simone-audio",
- .owner = THIS_MODULE,
- },
- .probe = simone_probe,
- .remove = __devexit_p(simone_remove),
-};
-
-module_platform_driver(simone_driver);
-
-MODULE_DESCRIPTION("ALSA SoC Simplemachines Sim.One");
-MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:simone-audio");
diff --git a/ANDROID_3.4.5/sound/soc/ep93xx/snappercl15.c b/ANDROID_3.4.5/sound/soc/ep93xx/snappercl15.c
deleted file mode 100644
index a193cea3..00000000
--- a/ANDROID_3.4.5/sound/soc/ep93xx/snappercl15.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * snappercl15.c -- SoC audio for Bluewater Systems Snapper CL15 module
- *
- * Copyright (C) 2008 Bluewater Systems Ltd
- * Author: Ryan Mallon
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-
-#include "../codecs/tlv320aic23.h"
-#include "ep93xx-pcm.h"
-
-#define CODEC_CLOCK 5644800
-
-static int snappercl15_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int err;
-
- err = snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK,
- SND_SOC_CLOCK_IN);
- if (err)
- return err;
-
- err = snd_soc_dai_set_sysclk(cpu_dai, 0, CODEC_CLOCK,
- SND_SOC_CLOCK_OUT);
- if (err)
- return err;
-
- return 0;
-}
-
-static struct snd_soc_ops snappercl15_ops = {
- .hw_params = snappercl15_hw_params,
-};
-
-static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_LINE("Line In", NULL),
- SND_SOC_DAPM_MIC("Mic Jack", NULL),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- {"Headphone Jack", NULL, "LHPOUT"},
- {"Headphone Jack", NULL, "RHPOUT"},
-
- {"LLINEIN", NULL, "Line In"},
- {"RLINEIN", NULL, "Line In"},
-
- {"MICIN", NULL, "Mic Jack"},
-};
-
-static int snappercl15_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
- ARRAY_SIZE(tlv320aic23_dapm_widgets));
-
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- return 0;
-}
-
-static struct snd_soc_dai_link snappercl15_dai = {
- .name = "tlv320aic23",
- .stream_name = "AIC23",
- .cpu_dai_name = "ep93xx-i2s",
- .codec_dai_name = "tlv320aic23-hifi",
- .codec_name = "tlv320aic23-codec.0-001a",
- .platform_name = "ep93xx-pcm-audio",
- .init = snappercl15_tlv320aic23_init,
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
- SND_SOC_DAIFMT_CBS_CFS,
- .ops = &snappercl15_ops,
-};
-
-static struct snd_soc_card snd_soc_snappercl15 = {
- .name = "Snapper CL15",
- .owner = THIS_MODULE,
- .dai_link = &snappercl15_dai,
- .num_links = 1,
-};
-
-static int __devinit snappercl15_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &snd_soc_snappercl15;
- int ret;
-
- ret = ep93xx_i2s_acquire();
- if (ret)
- return ret;
-
- card->dev = &pdev->dev;
-
- ret = snd_soc_register_card(card);
- if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
- ret);
- ep93xx_i2s_release();
- }
-
- return ret;
-}
-
-static int __devexit snappercl15_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- snd_soc_unregister_card(card);
- ep93xx_i2s_release();
-
- return 0;
-}
-
-static struct platform_driver snappercl15_driver = {
- .driver = {
- .name = "snappercl15-audio",
- .owner = THIS_MODULE,
- },
- .probe = snappercl15_probe,
- .remove = __devexit_p(snappercl15_remove),
-};
-
-module_platform_driver(snappercl15_driver);
-
-MODULE_AUTHOR("Ryan Mallon");
-MODULE_DESCRIPTION("ALSA SoC Snapper CL15");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:snappercl15-audio");
diff --git a/ANDROID_3.4.5/sound/soc/fsl/Kconfig b/ANDROID_3.4.5/sound/soc/fsl/Kconfig
deleted file mode 100644
index d754d34d..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/Kconfig
+++ /dev/null
@@ -1,67 +0,0 @@
-config SND_MPC52xx_DMA
- tristate
-
-# ASoC platform support for the Freescale PowerPC SOCs that have an SSI and
-# an Elo DMA controller, such as the MPC8610 and P1022. You will still need to
-# select a platform driver and a codec driver.
-config SND_SOC_POWERPC_SSI
- tristate
- depends on FSL_SOC
-
-config SND_SOC_MPC8610_HPCD
- tristate "ALSA SoC support for the Freescale MPC8610 HPCD board"
- # I2C is necessary for the CS4270 driver
- depends on MPC8610_HPCD && I2C
- select SND_SOC_POWERPC_SSI
- select SND_SOC_CS4270
- select SND_SOC_CS4270_VD33_ERRATA
- default y if MPC8610_HPCD
- help
- Say Y if you want to enable audio on the Freescale MPC8610 HPCD.
-
-config SND_SOC_P1022_DS
- tristate "ALSA SoC support for the Freescale P1022 DS board"
- # I2C is necessary for the WM8776 driver
- depends on P1022_DS && I2C
- select SND_SOC_POWERPC_SSI
- select SND_SOC_WM8776
- default y if P1022_DS
- help
- Say Y if you want to enable audio on the Freescale P1022 DS board.
- This will also include the Wolfson Microelectronics WM8776 codec
- driver.
-
-config SND_SOC_MPC5200_I2S
- tristate "Freescale MPC5200 PSC in I2S mode driver"
- depends on PPC_MPC52xx && PPC_BESTCOMM
- select SND_MPC52xx_DMA
- select PPC_BESTCOMM_GEN_BD
- help
- Say Y here to support the MPC5200 PSCs in I2S mode.
-
-config SND_SOC_MPC5200_AC97
- tristate "Freescale MPC5200 PSC in AC97 mode driver"
- depends on PPC_MPC52xx && PPC_BESTCOMM
- select SND_SOC_AC97_BUS
- select SND_MPC52xx_DMA
- select PPC_BESTCOMM_GEN_BD
- help
- Say Y here to support the MPC5200 PSCs in AC97 mode.
-
-config SND_MPC52xx_SOC_PCM030
- tristate "SoC AC97 Audio support for Phytec pcm030 and WM9712"
- depends on PPC_MPC5200_SIMPLE
- select SND_SOC_MPC5200_AC97
- select SND_SOC_WM9712
- help
- Say Y if you want to add support for sound on the Phytec pcm030
- baseboard.
-
-config SND_MPC52xx_SOC_EFIKA
- tristate "SoC AC97 Audio support for bbplan Efika and STAC9766"
- depends on PPC_EFIKA
- select SND_SOC_MPC5200_AC97
- select SND_SOC_STAC9766
- help
- Say Y if you want to add support for sound on the Efika.
-
diff --git a/ANDROID_3.4.5/sound/soc/fsl/Makefile b/ANDROID_3.4.5/sound/soc/fsl/Makefile
deleted file mode 100644
index b4a38c0a..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-# MPC8610 HPCD Machine Support
-snd-soc-mpc8610-hpcd-objs := mpc8610_hpcd.o
-obj-$(CONFIG_SND_SOC_MPC8610_HPCD) += snd-soc-mpc8610-hpcd.o
-
-# P1022 DS Machine Support
-snd-soc-p1022-ds-objs := p1022_ds.o
-obj-$(CONFIG_SND_SOC_P1022_DS) += snd-soc-p1022-ds.o
-
-# Freescale PowerPC SSI/DMA Platform Support
-snd-soc-fsl-ssi-objs := fsl_ssi.o
-snd-soc-fsl-dma-objs := fsl_dma.o
-obj-$(CONFIG_SND_SOC_POWERPC_SSI) += snd-soc-fsl-ssi.o snd-soc-fsl-dma.o
-
-# MPC5200 Platform Support
-obj-$(CONFIG_SND_MPC52xx_DMA) += mpc5200_dma.o
-obj-$(CONFIG_SND_SOC_MPC5200_I2S) += mpc5200_psc_i2s.o
-obj-$(CONFIG_SND_SOC_MPC5200_AC97) += mpc5200_psc_ac97.o
-
-# MPC5200 Machine Support
-obj-$(CONFIG_SND_MPC52xx_SOC_PCM030) += pcm030-audio-fabric.o
-obj-$(CONFIG_SND_MPC52xx_SOC_EFIKA) += efika-audio-fabric.o
-
diff --git a/ANDROID_3.4.5/sound/soc/fsl/efika-audio-fabric.c b/ANDROID_3.4.5/sound/soc/fsl/efika-audio-fabric.c
deleted file mode 100644
index b2acd329..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/efika-audio-fabric.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Efika driver for the PSC of the Freescale MPC52xx
- * configured as AC97 interface
- *
- * Copyright 2008 Jon Smirl, Digispeaker
- * Author: Jon Smirl <jonsmirl@gmail.com>
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/of_device.h>
-#include <linux/of_platform.h>
-#include <linux/dma-mapping.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include "mpc5200_dma.h"
-#include "mpc5200_psc_ac97.h"
-#include "../codecs/stac9766.h"
-
-#define DRV_NAME "efika-audio-fabric"
-
-static struct snd_soc_dai_link efika_fabric_dai[] = {
-{
- .name = "AC97",
- .stream_name = "AC97 Analog",
- .codec_dai_name = "stac9766-hifi-analog",
- .cpu_dai_name = "mpc5200-psc-ac97.0",
- .platform_name = "mpc5200-pcm-audio",
- .codec_name = "stac9766-codec",
-},
-{
- .name = "AC97",
- .stream_name = "AC97 IEC958",
- .codec_dai_name = "stac9766-hifi-IEC958",
- .cpu_dai_name = "mpc5200-psc-ac97.1",
- .platform_name = "mpc5200-pcm-audio",
- .codec_name = "stac9766-codec",
-},
-};
-
-static struct snd_soc_card card = {
- .name = "Efika",
- .owner = THIS_MODULE,
- .dai_link = efika_fabric_dai,
- .num_links = ARRAY_SIZE(efika_fabric_dai),
-};
-
-static __init int efika_fabric_init(void)
-{
- struct platform_device *pdev;
- int rc;
-
- if (!of_machine_is_compatible("bplan,efika"))
- return -ENODEV;
-
- pdev = platform_device_alloc("soc-audio", 1);
- if (!pdev) {
- pr_err("efika_fabric_init: platform_device_alloc() failed\n");
- return -ENODEV;
- }
-
- platform_set_drvdata(pdev, &card);
-
- rc = platform_device_add(pdev);
- if (rc) {
- pr_err("efika_fabric_init: platform_device_add() failed\n");
- platform_device_put(pdev);
- return -ENODEV;
- }
- return 0;
-}
-
-module_init(efika_fabric_init);
-
-
-MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
-MODULE_DESCRIPTION(DRV_NAME ": mpc5200 Efika fabric driver");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/soc/fsl/fsl_dma.c b/ANDROID_3.4.5/sound/soc/fsl/fsl_dma.c
deleted file mode 100644
index 96bb92dd..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/fsl_dma.c
+++ /dev/null
@@ -1,999 +0,0 @@
-/*
- * Freescale DMA ALSA SoC PCM driver
- *
- * Author: Timur Tabi <timur@freescale.com>
- *
- * Copyright 2007-2010 Freescale Semiconductor, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- *
- * This driver implements ASoC support for the Elo DMA controller, which is
- * the DMA controller on Freescale 83xx, 85xx, and 86xx SOCs. In ALSA terms,
- * the PCM driver is what handles the DMA buffer.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/gfp.h>
-#include <linux/of_platform.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/io.h>
-
-#include "fsl_dma.h"
-#include "fsl_ssi.h" /* For the offset of stx0 and srx0 */
-
-/*
- * The formats that the DMA controller supports, which is anything
- * that is 8, 16, or 32 bits.
- */
-#define FSLDMA_PCM_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
- SNDRV_PCM_FMTBIT_U8 | \
- SNDRV_PCM_FMTBIT_S16_LE | \
- SNDRV_PCM_FMTBIT_S16_BE | \
- SNDRV_PCM_FMTBIT_U16_LE | \
- SNDRV_PCM_FMTBIT_U16_BE | \
- SNDRV_PCM_FMTBIT_S24_LE | \
- SNDRV_PCM_FMTBIT_S24_BE | \
- SNDRV_PCM_FMTBIT_U24_LE | \
- SNDRV_PCM_FMTBIT_U24_BE | \
- SNDRV_PCM_FMTBIT_S32_LE | \
- SNDRV_PCM_FMTBIT_S32_BE | \
- SNDRV_PCM_FMTBIT_U32_LE | \
- SNDRV_PCM_FMTBIT_U32_BE)
-
-#define FSLDMA_PCM_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \
- SNDRV_PCM_RATE_CONTINUOUS)
-
-struct dma_object {
- struct snd_soc_platform_driver dai;
- dma_addr_t ssi_stx_phys;
- dma_addr_t ssi_srx_phys;
- unsigned int ssi_fifo_depth;
- struct ccsr_dma_channel __iomem *channel;
- unsigned int irq;
- bool assigned;
- char path[1];
-};
-
-/*
- * The number of DMA links to use. Two is the bare minimum, but if you
- * have really small links you might need more.
- */
-#define NUM_DMA_LINKS 2
-
-/** fsl_dma_private: p-substream DMA data
- *
- * Each substream has a 1-to-1 association with a DMA channel.
- *
- * The link[] array is first because it needs to be aligned on a 32-byte
- * boundary, so putting it first will ensure alignment without padding the
- * structure.
- *
- * @link[]: array of link descriptors
- * @dma_channel: pointer to the DMA channel's registers
- * @irq: IRQ for this DMA channel
- * @substream: pointer to the substream object, needed by the ISR
- * @ssi_sxx_phys: bus address of the STX or SRX register to use
- * @ld_buf_phys: physical address of the LD buffer
- * @current_link: index into link[] of the link currently being processed
- * @dma_buf_phys: physical address of the DMA buffer
- * @dma_buf_next: physical address of the next period to process
- * @dma_buf_end: physical address of the byte after the end of the DMA
- * @buffer period_size: the size of a single period
- * @num_periods: the number of periods in the DMA buffer
- */
-struct fsl_dma_private {
- struct fsl_dma_link_descriptor link[NUM_DMA_LINKS];
- struct ccsr_dma_channel __iomem *dma_channel;
- unsigned int irq;
- struct snd_pcm_substream *substream;
- dma_addr_t ssi_sxx_phys;
- unsigned int ssi_fifo_depth;
- dma_addr_t ld_buf_phys;
- unsigned int current_link;
- dma_addr_t dma_buf_phys;
- dma_addr_t dma_buf_next;
- dma_addr_t dma_buf_end;
- size_t period_size;
- unsigned int num_periods;
-};
-
-/**
- * fsl_dma_hardare: define characteristics of the PCM hardware.
- *
- * The PCM hardware is the Freescale DMA controller. This structure defines
- * the capabilities of that hardware.
- *
- * Since the sampling rate and data format are not controlled by the DMA
- * controller, we specify no limits for those values. The only exception is
- * period_bytes_min, which is set to a reasonably low value to prevent the
- * DMA controller from generating too many interrupts per second.
- *
- * Since each link descriptor has a 32-bit byte count field, we set
- * period_bytes_max to the largest 32-bit number. We also have no maximum
- * number of periods.
- *
- * Note that we specify SNDRV_PCM_INFO_JOINT_DUPLEX here, but only because a
- * limitation in the SSI driver requires the sample rates for playback and
- * capture to be the same.
- */
-static const struct snd_pcm_hardware fsl_dma_hardware = {
-
- .info = SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_JOINT_DUPLEX |
- SNDRV_PCM_INFO_PAUSE,
- .formats = FSLDMA_PCM_FORMATS,
- .rates = FSLDMA_PCM_RATES,
- .rate_min = 5512,
- .rate_max = 192000,
- .period_bytes_min = 512, /* A reasonable limit */
- .period_bytes_max = (u32) -1,
- .periods_min = NUM_DMA_LINKS,
- .periods_max = (unsigned int) -1,
- .buffer_bytes_max = 128 * 1024, /* A reasonable limit */
-};
-
-/**
- * fsl_dma_abort_stream: tell ALSA that the DMA transfer has aborted
- *
- * This function should be called by the ISR whenever the DMA controller
- * halts data transfer.
- */
-static void fsl_dma_abort_stream(struct snd_pcm_substream *substream)
-{
- unsigned long flags;
-
- snd_pcm_stream_lock_irqsave(substream, flags);
-
- if (snd_pcm_running(substream))
- snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
-
- snd_pcm_stream_unlock_irqrestore(substream, flags);
-}
-
-/**
- * fsl_dma_update_pointers - update LD pointers to point to the next period
- *
- * As each period is completed, this function changes the the link
- * descriptor pointers for that period to point to the next period.
- */
-static void fsl_dma_update_pointers(struct fsl_dma_private *dma_private)
-{
- struct fsl_dma_link_descriptor *link =
- &dma_private->link[dma_private->current_link];
-
- /* Update our link descriptors to point to the next period. On a 36-bit
- * system, we also need to update the ESAD bits. We also set (keep) the
- * snoop bits. See the comments in fsl_dma_hw_params() about snooping.
- */
- if (dma_private->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- link->source_addr = cpu_to_be32(dma_private->dma_buf_next);
-#ifdef CONFIG_PHYS_64BIT
- link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP |
- upper_32_bits(dma_private->dma_buf_next));
-#endif
- } else {
- link->dest_addr = cpu_to_be32(dma_private->dma_buf_next);
-#ifdef CONFIG_PHYS_64BIT
- link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP |
- upper_32_bits(dma_private->dma_buf_next));
-#endif
- }
-
- /* Update our variables for next time */
- dma_private->dma_buf_next += dma_private->period_size;
-
- if (dma_private->dma_buf_next >= dma_private->dma_buf_end)
- dma_private->dma_buf_next = dma_private->dma_buf_phys;
-
- if (++dma_private->current_link >= NUM_DMA_LINKS)
- dma_private->current_link = 0;
-}
-
-/**
- * fsl_dma_isr: interrupt handler for the DMA controller
- *
- * @irq: IRQ of the DMA channel
- * @dev_id: pointer to the dma_private structure for this DMA channel
- */
-static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
-{
- struct fsl_dma_private *dma_private = dev_id;
- struct snd_pcm_substream *substream = dma_private->substream;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct device *dev = rtd->platform->dev;
- struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
- irqreturn_t ret = IRQ_NONE;
- u32 sr, sr2 = 0;
-
- /* We got an interrupt, so read the status register to see what we
- were interrupted for.
- */
- sr = in_be32(&dma_channel->sr);
-
- if (sr & CCSR_DMA_SR_TE) {
- dev_err(dev, "dma transmit error\n");
- fsl_dma_abort_stream(substream);
- sr2 |= CCSR_DMA_SR_TE;
- ret = IRQ_HANDLED;
- }
-
- if (sr & CCSR_DMA_SR_CH)
- ret = IRQ_HANDLED;
-
- if (sr & CCSR_DMA_SR_PE) {
- dev_err(dev, "dma programming error\n");
- fsl_dma_abort_stream(substream);
- sr2 |= CCSR_DMA_SR_PE;
- ret = IRQ_HANDLED;
- }
-
- if (sr & CCSR_DMA_SR_EOLNI) {
- sr2 |= CCSR_DMA_SR_EOLNI;
- ret = IRQ_HANDLED;
- }
-
- if (sr & CCSR_DMA_SR_CB)
- ret = IRQ_HANDLED;
-
- if (sr & CCSR_DMA_SR_EOSI) {
- /* Tell ALSA we completed a period. */
- snd_pcm_period_elapsed(substream);
-
- /*
- * Update our link descriptors to point to the next period. We
- * only need to do this if the number of periods is not equal to
- * the number of links.
- */
- if (dma_private->num_periods != NUM_DMA_LINKS)
- fsl_dma_update_pointers(dma_private);
-
- sr2 |= CCSR_DMA_SR_EOSI;
- ret = IRQ_HANDLED;
- }
-
- if (sr & CCSR_DMA_SR_EOLSI) {
- sr2 |= CCSR_DMA_SR_EOLSI;
- ret = IRQ_HANDLED;
- }
-
- /* Clear the bits that we set */
- if (sr2)
- out_be32(&dma_channel->sr, sr2);
-
- return ret;
-}
-
-/**
- * fsl_dma_new: initialize this PCM driver.
- *
- * This function is called when the codec driver calls snd_soc_new_pcms(),
- * once for each .dai_link in the machine driver's snd_soc_card
- * structure.
- *
- * snd_dma_alloc_pages() is just a front-end to dma_alloc_coherent(), which
- * (currently) always allocates the DMA buffer in lowmem, even if GFP_HIGHMEM
- * is specified. Therefore, any DMA buffers we allocate will always be in low
- * memory, but we support for 36-bit physical addresses anyway.
- *
- * Regardless of where the memory is actually allocated, since the device can
- * technically DMA to any 36-bit address, we do need to set the DMA mask to 36.
- */
-static int fsl_dma_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- static u64 fsl_dma_dmamask = DMA_BIT_MASK(36);
- int ret;
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &fsl_dma_dmamask;
-
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = fsl_dma_dmamask;
-
- /* Some codecs have separate DAIs for playback and capture, so we
- * should allocate a DMA buffer only for the streams that are valid.
- */
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev,
- fsl_dma_hardware.buffer_bytes_max,
- &pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer);
- if (ret) {
- dev_err(card->dev, "can't alloc playback dma buffer\n");
- return ret;
- }
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev,
- fsl_dma_hardware.buffer_bytes_max,
- &pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->dma_buffer);
- if (ret) {
- dev_err(card->dev, "can't alloc capture dma buffer\n");
- snd_dma_free_pages(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer);
- return ret;
- }
- }
-
- return 0;
-}
-
-/**
- * fsl_dma_open: open a new substream.
- *
- * Each substream has its own DMA buffer.
- *
- * ALSA divides the DMA buffer into N periods. We create NUM_DMA_LINKS link
- * descriptors that ping-pong from one period to the next. For example, if
- * there are six periods and two link descriptors, this is how they look
- * before playback starts:
- *
- * The last link descriptor
- * ____________ points back to the first
- * | |
- * V |
- * ___ ___ |
- * | |->| |->|
- * |___| |___|
- * | |
- * | |
- * V V
- * _________________________________________
- * | | | | | | | The DMA buffer is
- * | | | | | | | divided into 6 parts
- * |______|______|______|______|______|______|
- *
- * and here's how they look after the first period is finished playing:
- *
- * ____________
- * | |
- * V |
- * ___ ___ |
- * | |->| |->|
- * |___| |___|
- * | |
- * |______________
- * | |
- * V V
- * _________________________________________
- * | | | | | | |
- * | | | | | | |
- * |______|______|______|______|______|______|
- *
- * The first link descriptor now points to the third period. The DMA
- * controller is currently playing the second period. When it finishes, it
- * will jump back to the first descriptor and play the third period.
- *
- * There are four reasons we do this:
- *
- * 1. The only way to get the DMA controller to automatically restart the
- * transfer when it gets to the end of the buffer is to use chaining
- * mode. Basic direct mode doesn't offer that feature.
- * 2. We need to receive an interrupt at the end of every period. The DMA
- * controller can generate an interrupt at the end of every link transfer
- * (aka segment). Making each period into a DMA segment will give us the
- * interrupts we need.
- * 3. By creating only two link descriptors, regardless of the number of
- * periods, we do not need to reallocate the link descriptors if the
- * number of periods changes.
- * 4. All of the audio data is still stored in a single, contiguous DMA
- * buffer, which is what ALSA expects. We're just dividing it into
- * contiguous parts, and creating a link descriptor for each one.
- */
-static int fsl_dma_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct device *dev = rtd->platform->dev;
- struct dma_object *dma =
- container_of(rtd->platform->driver, struct dma_object, dai);
- struct fsl_dma_private *dma_private;
- struct ccsr_dma_channel __iomem *dma_channel;
- dma_addr_t ld_buf_phys;
- u64 temp_link; /* Pointer to next link descriptor */
- u32 mr;
- unsigned int channel;
- int ret = 0;
- unsigned int i;
-
- /*
- * Reject any DMA buffer whose size is not a multiple of the period
- * size. We need to make sure that the DMA buffer can be evenly divided
- * into periods.
- */
- ret = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (ret < 0) {
- dev_err(dev, "invalid buffer size\n");
- return ret;
- }
-
- channel = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
-
- if (dma->assigned) {
- dev_err(dev, "dma channel already assigned\n");
- return -EBUSY;
- }
-
- dma_private = dma_alloc_coherent(dev, sizeof(struct fsl_dma_private),
- &ld_buf_phys, GFP_KERNEL);
- if (!dma_private) {
- dev_err(dev, "can't allocate dma private data\n");
- return -ENOMEM;
- }
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dma_private->ssi_sxx_phys = dma->ssi_stx_phys;
- else
- dma_private->ssi_sxx_phys = dma->ssi_srx_phys;
-
- dma_private->ssi_fifo_depth = dma->ssi_fifo_depth;
- dma_private->dma_channel = dma->channel;
- dma_private->irq = dma->irq;
- dma_private->substream = substream;
- dma_private->ld_buf_phys = ld_buf_phys;
- dma_private->dma_buf_phys = substream->dma_buffer.addr;
-
- ret = request_irq(dma_private->irq, fsl_dma_isr, 0, "fsldma-audio",
- dma_private);
- if (ret) {
- dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n",
- dma_private->irq, ret);
- dma_free_coherent(dev, sizeof(struct fsl_dma_private),
- dma_private, dma_private->ld_buf_phys);
- return ret;
- }
-
- dma->assigned = 1;
-
- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
- snd_soc_set_runtime_hwparams(substream, &fsl_dma_hardware);
- runtime->private_data = dma_private;
-
- /* Program the fixed DMA controller parameters */
-
- dma_channel = dma_private->dma_channel;
-
- temp_link = dma_private->ld_buf_phys +
- sizeof(struct fsl_dma_link_descriptor);
-
- for (i = 0; i < NUM_DMA_LINKS; i++) {
- dma_private->link[i].next = cpu_to_be64(temp_link);
-
- temp_link += sizeof(struct fsl_dma_link_descriptor);
- }
- /* The last link descriptor points to the first */
- dma_private->link[i - 1].next = cpu_to_be64(dma_private->ld_buf_phys);
-
- /* Tell the DMA controller where the first link descriptor is */
- out_be32(&dma_channel->clndar,
- CCSR_DMA_CLNDAR_ADDR(dma_private->ld_buf_phys));
- out_be32(&dma_channel->eclndar,
- CCSR_DMA_ECLNDAR_ADDR(dma_private->ld_buf_phys));
-
- /* The manual says the BCR must be clear before enabling EMP */
- out_be32(&dma_channel->bcr, 0);
-
- /*
- * Program the mode register for interrupts, external master control,
- * and source/destination hold. Also clear the Channel Abort bit.
- */
- mr = in_be32(&dma_channel->mr) &
- ~(CCSR_DMA_MR_CA | CCSR_DMA_MR_DAHE | CCSR_DMA_MR_SAHE);
-
- /*
- * We want External Master Start and External Master Pause enabled,
- * because the SSI is controlling the DMA controller. We want the DMA
- * controller to be set up in advance, and then we signal only the SSI
- * to start transferring.
- *
- * We want End-Of-Segment Interrupts enabled, because this will generate
- * an interrupt at the end of each segment (each link descriptor
- * represents one segment). Each DMA segment is the same thing as an
- * ALSA period, so this is how we get an interrupt at the end of every
- * period.
- *
- * We want Error Interrupt enabled, so that we can get an error if
- * the DMA controller is mis-programmed somehow.
- */
- mr |= CCSR_DMA_MR_EOSIE | CCSR_DMA_MR_EIE | CCSR_DMA_MR_EMP_EN |
- CCSR_DMA_MR_EMS_EN;
-
- /* For playback, we want the destination address to be held. For
- capture, set the source address to be held. */
- mr |= (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
- CCSR_DMA_MR_DAHE : CCSR_DMA_MR_SAHE;
-
- out_be32(&dma_channel->mr, mr);
-
- return 0;
-}
-
-/**
- * fsl_dma_hw_params: continue initializing the DMA links
- *
- * This function obtains hardware parameters about the opened stream and
- * programs the DMA controller accordingly.
- *
- * One drawback of big-endian is that when copying integers of different
- * sizes to a fixed-sized register, the address to which the integer must be
- * copied is dependent on the size of the integer.
- *
- * For example, if P is the address of a 32-bit register, and X is a 32-bit
- * integer, then X should be copied to address P. However, if X is a 16-bit
- * integer, then it should be copied to P+2. If X is an 8-bit register,
- * then it should be copied to P+3.
- *
- * So for playback of 8-bit samples, the DMA controller must transfer single
- * bytes from the DMA buffer to the last byte of the STX0 register, i.e.
- * offset by 3 bytes. For 16-bit samples, the offset is two bytes.
- *
- * For 24-bit samples, the offset is 1 byte. However, the DMA controller
- * does not support 3-byte copies (the DAHTS register supports only 1, 2, 4,
- * and 8 bytes at a time). So we do not support packed 24-bit samples.
- * 24-bit data must be padded to 32 bits.
- */
-static int fsl_dma_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct fsl_dma_private *dma_private = runtime->private_data;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct device *dev = rtd->platform->dev;
-
- /* Number of bits per sample */
- unsigned int sample_bits =
- snd_pcm_format_physical_width(params_format(hw_params));
-
- /* Number of bytes per frame */
- unsigned int sample_bytes = sample_bits / 8;
-
- /* Bus address of SSI STX register */
- dma_addr_t ssi_sxx_phys = dma_private->ssi_sxx_phys;
-
- /* Size of the DMA buffer, in bytes */
- size_t buffer_size = params_buffer_bytes(hw_params);
-
- /* Number of bytes per period */
- size_t period_size = params_period_bytes(hw_params);
-
- /* Pointer to next period */
- dma_addr_t temp_addr = substream->dma_buffer.addr;
-
- /* Pointer to DMA controller */
- struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
-
- u32 mr; /* DMA Mode Register */
-
- unsigned int i;
-
- /* Initialize our DMA tracking variables */
- dma_private->period_size = period_size;
- dma_private->num_periods = params_periods(hw_params);
- dma_private->dma_buf_end = dma_private->dma_buf_phys + buffer_size;
- dma_private->dma_buf_next = dma_private->dma_buf_phys +
- (NUM_DMA_LINKS * period_size);
-
- if (dma_private->dma_buf_next >= dma_private->dma_buf_end)
- /* This happens if the number of periods == NUM_DMA_LINKS */
- dma_private->dma_buf_next = dma_private->dma_buf_phys;
-
- mr = in_be32(&dma_channel->mr) & ~(CCSR_DMA_MR_BWC_MASK |
- CCSR_DMA_MR_SAHTS_MASK | CCSR_DMA_MR_DAHTS_MASK);
-
- /* Due to a quirk of the SSI's STX register, the target address
- * for the DMA operations depends on the sample size. So we calculate
- * that offset here. While we're at it, also tell the DMA controller
- * how much data to transfer per sample.
- */
- switch (sample_bits) {
- case 8:
- mr |= CCSR_DMA_MR_DAHTS_1 | CCSR_DMA_MR_SAHTS_1;
- ssi_sxx_phys += 3;
- break;
- case 16:
- mr |= CCSR_DMA_MR_DAHTS_2 | CCSR_DMA_MR_SAHTS_2;
- ssi_sxx_phys += 2;
- break;
- case 32:
- mr |= CCSR_DMA_MR_DAHTS_4 | CCSR_DMA_MR_SAHTS_4;
- break;
- default:
- /* We should never get here */
- dev_err(dev, "unsupported sample size %u\n", sample_bits);
- return -EINVAL;
- }
-
- /*
- * BWC determines how many bytes are sent/received before the DMA
- * controller checks the SSI to see if it needs to stop. BWC should
- * always be a multiple of the frame size, so that we always transmit
- * whole frames. Each frame occupies two slots in the FIFO. The
- * parameter for CCSR_DMA_MR_BWC() is rounded down the next power of two
- * (MR[BWC] can only represent even powers of two).
- *
- * To simplify the process, we set BWC to the largest value that is
- * less than or equal to the FIFO watermark. For playback, this ensures
- * that we transfer the maximum amount without overrunning the FIFO.
- * For capture, this ensures that we transfer the maximum amount without
- * underrunning the FIFO.
- *
- * f = SSI FIFO depth
- * w = SSI watermark value (which equals f - 2)
- * b = DMA bandwidth count (in bytes)
- * s = sample size (in bytes, which equals frame_size * 2)
- *
- * For playback, we never transmit more than the transmit FIFO
- * watermark, otherwise we might write more data than the FIFO can hold.
- * The watermark is equal to the FIFO depth minus two.
- *
- * For capture, two equations must hold:
- * w > f - (b / s)
- * w >= b / s
- *
- * So, b > 2 * s, but b must also be <= s * w. To simplify, we set
- * b = s * w, which is equal to
- * (dma_private->ssi_fifo_depth - 2) * sample_bytes.
- */
- mr |= CCSR_DMA_MR_BWC((dma_private->ssi_fifo_depth - 2) * sample_bytes);
-
- out_be32(&dma_channel->mr, mr);
-
- for (i = 0; i < NUM_DMA_LINKS; i++) {
- struct fsl_dma_link_descriptor *link = &dma_private->link[i];
-
- link->count = cpu_to_be32(period_size);
-
- /* The snoop bit tells the DMA controller whether it should tell
- * the ECM to snoop during a read or write to an address. For
- * audio, we use DMA to transfer data between memory and an I/O
- * device (the SSI's STX0 or SRX0 register). Snooping is only
- * needed if there is a cache, so we need to snoop memory
- * addresses only. For playback, that means we snoop the source
- * but not the destination. For capture, we snoop the
- * destination but not the source.
- *
- * Note that failing to snoop properly is unlikely to cause
- * cache incoherency if the period size is larger than the
- * size of L1 cache. This is because filling in one period will
- * flush out the data for the previous period. So if you
- * increased period_bytes_min to a large enough size, you might
- * get more performance by not snooping, and you'll still be
- * okay. You'll need to update fsl_dma_update_pointers() also.
- */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- link->source_addr = cpu_to_be32(temp_addr);
- link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP |
- upper_32_bits(temp_addr));
-
- link->dest_addr = cpu_to_be32(ssi_sxx_phys);
- link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP |
- upper_32_bits(ssi_sxx_phys));
- } else {
- link->source_addr = cpu_to_be32(ssi_sxx_phys);
- link->source_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP |
- upper_32_bits(ssi_sxx_phys));
-
- link->dest_addr = cpu_to_be32(temp_addr);
- link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP |
- upper_32_bits(temp_addr));
- }
-
- temp_addr += period_size;
- }
-
- return 0;
-}
-
-/**
- * fsl_dma_pointer: determine the current position of the DMA transfer
- *
- * This function is called by ALSA when ALSA wants to know where in the
- * stream buffer the hardware currently is.
- *
- * For playback, the SAR register contains the physical address of the most
- * recent DMA transfer. For capture, the value is in the DAR register.
- *
- * The base address of the buffer is stored in the source_addr field of the
- * first link descriptor.
- */
-static snd_pcm_uframes_t fsl_dma_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct fsl_dma_private *dma_private = runtime->private_data;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct device *dev = rtd->platform->dev;
- struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
- dma_addr_t position;
- snd_pcm_uframes_t frames;
-
- /* Obtain the current DMA pointer, but don't read the ESAD bits if we
- * only have 32-bit DMA addresses. This function is typically called
- * in interrupt context, so we need to optimize it.
- */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- position = in_be32(&dma_channel->sar);
-#ifdef CONFIG_PHYS_64BIT
- position |= (u64)(in_be32(&dma_channel->satr) &
- CCSR_DMA_ATR_ESAD_MASK) << 32;
-#endif
- } else {
- position = in_be32(&dma_channel->dar);
-#ifdef CONFIG_PHYS_64BIT
- position |= (u64)(in_be32(&dma_channel->datr) &
- CCSR_DMA_ATR_ESAD_MASK) << 32;
-#endif
- }
-
- /*
- * When capture is started, the SSI immediately starts to fill its FIFO.
- * This means that the DMA controller is not started until the FIFO is
- * full. However, ALSA calls this function before that happens, when
- * MR.DAR is still zero. In this case, just return zero to indicate
- * that nothing has been received yet.
- */
- if (!position)
- return 0;
-
- if ((position < dma_private->dma_buf_phys) ||
- (position > dma_private->dma_buf_end)) {
- dev_err(dev, "dma pointer is out of range, halting stream\n");
- return SNDRV_PCM_POS_XRUN;
- }
-
- frames = bytes_to_frames(runtime, position - dma_private->dma_buf_phys);
-
- /*
- * If the current address is just past the end of the buffer, wrap it
- * around.
- */
- if (frames == runtime->buffer_size)
- frames = 0;
-
- return frames;
-}
-
-/**
- * fsl_dma_hw_free: release resources allocated in fsl_dma_hw_params()
- *
- * Release the resources allocated in fsl_dma_hw_params() and de-program the
- * registers.
- *
- * This function can be called multiple times.
- */
-static int fsl_dma_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct fsl_dma_private *dma_private = runtime->private_data;
-
- if (dma_private) {
- struct ccsr_dma_channel __iomem *dma_channel;
-
- dma_channel = dma_private->dma_channel;
-
- /* Stop the DMA */
- out_be32(&dma_channel->mr, CCSR_DMA_MR_CA);
- out_be32(&dma_channel->mr, 0);
-
- /* Reset all the other registers */
- out_be32(&dma_channel->sr, -1);
- out_be32(&dma_channel->clndar, 0);
- out_be32(&dma_channel->eclndar, 0);
- out_be32(&dma_channel->satr, 0);
- out_be32(&dma_channel->sar, 0);
- out_be32(&dma_channel->datr, 0);
- out_be32(&dma_channel->dar, 0);
- out_be32(&dma_channel->bcr, 0);
- out_be32(&dma_channel->nlndar, 0);
- out_be32(&dma_channel->enlndar, 0);
- }
-
- return 0;
-}
-
-/**
- * fsl_dma_close: close the stream.
- */
-static int fsl_dma_close(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct fsl_dma_private *dma_private = runtime->private_data;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct device *dev = rtd->platform->dev;
- struct dma_object *dma =
- container_of(rtd->platform->driver, struct dma_object, dai);
-
- if (dma_private) {
- if (dma_private->irq)
- free_irq(dma_private->irq, dma_private);
-
- if (dma_private->ld_buf_phys) {
- dma_unmap_single(dev, dma_private->ld_buf_phys,
- sizeof(dma_private->link),
- DMA_TO_DEVICE);
- }
-
- /* Deallocate the fsl_dma_private structure */
- dma_free_coherent(dev, sizeof(struct fsl_dma_private),
- dma_private, dma_private->ld_buf_phys);
- substream->runtime->private_data = NULL;
- }
-
- dma->assigned = 0;
-
- return 0;
-}
-
-/*
- * Remove this PCM driver.
- */
-static void fsl_dma_free_dma_buffers(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(pcm->streams); i++) {
- substream = pcm->streams[i].substream;
- if (substream) {
- snd_dma_free_pages(&substream->dma_buffer);
- substream->dma_buffer.area = NULL;
- substream->dma_buffer.addr = 0;
- }
- }
-}
-
-/**
- * find_ssi_node -- returns the SSI node that points to his DMA channel node
- *
- * Although this DMA driver attempts to operate independently of the other
- * devices, it still needs to determine some information about the SSI device
- * that it's working with. Unfortunately, the device tree does not contain
- * a pointer from the DMA channel node to the SSI node -- the pointer goes the
- * other way. So we need to scan the device tree for SSI nodes until we find
- * the one that points to the given DMA channel node. It's ugly, but at least
- * it's contained in this one function.
- */
-static struct device_node *find_ssi_node(struct device_node *dma_channel_np)
-{
- struct device_node *ssi_np, *np;
-
- for_each_compatible_node(ssi_np, NULL, "fsl,mpc8610-ssi") {
- /* Check each DMA phandle to see if it points to us. We
- * assume that device_node pointers are a valid comparison.
- */
- np = of_parse_phandle(ssi_np, "fsl,playback-dma", 0);
- of_node_put(np);
- if (np == dma_channel_np)
- return ssi_np;
-
- np = of_parse_phandle(ssi_np, "fsl,capture-dma", 0);
- of_node_put(np);
- if (np == dma_channel_np)
- return ssi_np;
- }
-
- return NULL;
-}
-
-static struct snd_pcm_ops fsl_dma_ops = {
- .open = fsl_dma_open,
- .close = fsl_dma_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = fsl_dma_hw_params,
- .hw_free = fsl_dma_hw_free,
- .pointer = fsl_dma_pointer,
-};
-
-static int __devinit fsl_soc_dma_probe(struct platform_device *pdev)
- {
- struct dma_object *dma;
- struct device_node *np = pdev->dev.of_node;
- struct device_node *ssi_np;
- struct resource res;
- const uint32_t *iprop;
- int ret;
-
- /* Find the SSI node that points to us. */
- ssi_np = find_ssi_node(np);
- if (!ssi_np) {
- dev_err(&pdev->dev, "cannot find parent SSI node\n");
- return -ENODEV;
- }
-
- ret = of_address_to_resource(ssi_np, 0, &res);
- if (ret) {
- dev_err(&pdev->dev, "could not determine resources for %s\n",
- ssi_np->full_name);
- of_node_put(ssi_np);
- return ret;
- }
-
- dma = kzalloc(sizeof(*dma) + strlen(np->full_name), GFP_KERNEL);
- if (!dma) {
- dev_err(&pdev->dev, "could not allocate dma object\n");
- of_node_put(ssi_np);
- return -ENOMEM;
- }
-
- strcpy(dma->path, np->full_name);
- dma->dai.ops = &fsl_dma_ops;
- dma->dai.pcm_new = fsl_dma_new;
- dma->dai.pcm_free = fsl_dma_free_dma_buffers;
-
- /* Store the SSI-specific information that we need */
- dma->ssi_stx_phys = res.start + offsetof(struct ccsr_ssi, stx0);
- dma->ssi_srx_phys = res.start + offsetof(struct ccsr_ssi, srx0);
-
- iprop = of_get_property(ssi_np, "fsl,fifo-depth", NULL);
- if (iprop)
- dma->ssi_fifo_depth = be32_to_cpup(iprop);
- else
- /* Older 8610 DTs didn't have the fifo-depth property */
- dma->ssi_fifo_depth = 8;
-
- of_node_put(ssi_np);
-
- ret = snd_soc_register_platform(&pdev->dev, &dma->dai);
- if (ret) {
- dev_err(&pdev->dev, "could not register platform\n");
- kfree(dma);
- return ret;
- }
-
- dma->channel = of_iomap(np, 0);
- dma->irq = irq_of_parse_and_map(np, 0);
-
- dev_set_drvdata(&pdev->dev, dma);
-
- return 0;
-}
-
-static int __devexit fsl_soc_dma_remove(struct platform_device *pdev)
-{
- struct dma_object *dma = dev_get_drvdata(&pdev->dev);
-
- snd_soc_unregister_platform(&pdev->dev);
- iounmap(dma->channel);
- irq_dispose_mapping(dma->irq);
- kfree(dma);
-
- return 0;
-}
-
-static const struct of_device_id fsl_soc_dma_ids[] = {
- { .compatible = "fsl,ssi-dma-channel", },
- {}
-};
-MODULE_DEVICE_TABLE(of, fsl_soc_dma_ids);
-
-static struct platform_driver fsl_soc_dma_driver = {
- .driver = {
- .name = "fsl-pcm-audio",
- .owner = THIS_MODULE,
- .of_match_table = fsl_soc_dma_ids,
- },
- .probe = fsl_soc_dma_probe,
- .remove = __devexit_p(fsl_soc_dma_remove),
-};
-
-module_platform_driver(fsl_soc_dma_driver);
-
-MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
-MODULE_DESCRIPTION("Freescale Elo DMA ASoC PCM Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/sound/soc/fsl/fsl_dma.h b/ANDROID_3.4.5/sound/soc/fsl/fsl_dma.h
deleted file mode 100644
index 78fee97e..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/fsl_dma.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * mpc8610-pcm.h - ALSA PCM interface for the Freescale MPC8610 SoC
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _MPC8610_PCM_H
-#define _MPC8610_PCM_H
-
-struct ccsr_dma {
- u8 res0[0x100];
- struct ccsr_dma_channel {
- __be32 mr; /* Mode register */
- __be32 sr; /* Status register */
- __be32 eclndar; /* Current link descriptor extended addr reg */
- __be32 clndar; /* Current link descriptor address register */
- __be32 satr; /* Source attributes register */
- __be32 sar; /* Source address register */
- __be32 datr; /* Destination attributes register */
- __be32 dar; /* Destination address register */
- __be32 bcr; /* Byte count register */
- __be32 enlndar; /* Next link descriptor extended address reg */
- __be32 nlndar; /* Next link descriptor address register */
- u8 res1[4];
- __be32 eclsdar; /* Current list descriptor extended addr reg */
- __be32 clsdar; /* Current list descriptor address register */
- __be32 enlsdar; /* Next list descriptor extended address reg */
- __be32 nlsdar; /* Next list descriptor address register */
- __be32 ssr; /* Source stride register */
- __be32 dsr; /* Destination stride register */
- u8 res2[0x38];
- } channel[4];
- __be32 dgsr;
-};
-
-#define CCSR_DMA_MR_BWC_DISABLED 0x0F000000
-#define CCSR_DMA_MR_BWC_SHIFT 24
-#define CCSR_DMA_MR_BWC_MASK 0x0F000000
-#define CCSR_DMA_MR_BWC(x) \
- ((ilog2(x) << CCSR_DMA_MR_BWC_SHIFT) & CCSR_DMA_MR_BWC_MASK)
-#define CCSR_DMA_MR_EMP_EN 0x00200000
-#define CCSR_DMA_MR_EMS_EN 0x00040000
-#define CCSR_DMA_MR_DAHTS_MASK 0x00030000
-#define CCSR_DMA_MR_DAHTS_1 0x00000000
-#define CCSR_DMA_MR_DAHTS_2 0x00010000
-#define CCSR_DMA_MR_DAHTS_4 0x00020000
-#define CCSR_DMA_MR_DAHTS_8 0x00030000
-#define CCSR_DMA_MR_SAHTS_MASK 0x0000C000
-#define CCSR_DMA_MR_SAHTS_1 0x00000000
-#define CCSR_DMA_MR_SAHTS_2 0x00004000
-#define CCSR_DMA_MR_SAHTS_4 0x00008000
-#define CCSR_DMA_MR_SAHTS_8 0x0000C000
-#define CCSR_DMA_MR_DAHE 0x00002000
-#define CCSR_DMA_MR_SAHE 0x00001000
-#define CCSR_DMA_MR_SRW 0x00000400
-#define CCSR_DMA_MR_EOSIE 0x00000200
-#define CCSR_DMA_MR_EOLNIE 0x00000100
-#define CCSR_DMA_MR_EOLSIE 0x00000080
-#define CCSR_DMA_MR_EIE 0x00000040
-#define CCSR_DMA_MR_XFE 0x00000020
-#define CCSR_DMA_MR_CDSM_SWSM 0x00000010
-#define CCSR_DMA_MR_CA 0x00000008
-#define CCSR_DMA_MR_CTM 0x00000004
-#define CCSR_DMA_MR_CC 0x00000002
-#define CCSR_DMA_MR_CS 0x00000001
-
-#define CCSR_DMA_SR_TE 0x00000080
-#define CCSR_DMA_SR_CH 0x00000020
-#define CCSR_DMA_SR_PE 0x00000010
-#define CCSR_DMA_SR_EOLNI 0x00000008
-#define CCSR_DMA_SR_CB 0x00000004
-#define CCSR_DMA_SR_EOSI 0x00000002
-#define CCSR_DMA_SR_EOLSI 0x00000001
-
-/* ECLNDAR takes bits 32-36 of the CLNDAR register */
-static inline u32 CCSR_DMA_ECLNDAR_ADDR(u64 x)
-{
- return (x >> 32) & 0xf;
-}
-
-#define CCSR_DMA_CLNDAR_ADDR(x) ((x) & 0xFFFFFFFE)
-#define CCSR_DMA_CLNDAR_EOSIE 0x00000008
-
-/* SATR and DATR, combined */
-#define CCSR_DMA_ATR_PBATMU 0x20000000
-#define CCSR_DMA_ATR_TFLOWLVL_0 0x00000000
-#define CCSR_DMA_ATR_TFLOWLVL_1 0x06000000
-#define CCSR_DMA_ATR_TFLOWLVL_2 0x08000000
-#define CCSR_DMA_ATR_TFLOWLVL_3 0x0C000000
-#define CCSR_DMA_ATR_PCIORDER 0x02000000
-#define CCSR_DMA_ATR_SME 0x01000000
-#define CCSR_DMA_ATR_NOSNOOP 0x00040000
-#define CCSR_DMA_ATR_SNOOP 0x00050000
-#define CCSR_DMA_ATR_ESAD_MASK 0x0000000F
-
-/**
- * List Descriptor for extended chaining mode DMA operations.
- *
- * The CLSDAR register points to the first (in a linked-list) List
- * Descriptor. Each object must be aligned on a 32-byte boundary. Each
- * list descriptor points to a linked-list of link Descriptors.
- */
-struct fsl_dma_list_descriptor {
- __be64 next; /* Address of next list descriptor */
- __be64 first_link; /* Address of first link descriptor */
- __be32 source; /* Source stride */
- __be32 dest; /* Destination stride */
- u8 res[8]; /* Reserved */
-} __attribute__ ((aligned(32), packed));
-
-/**
- * Link Descriptor for basic and extended chaining mode DMA operations.
- *
- * A Link Descriptor points to a single DMA buffer. Each link descriptor
- * must be aligned on a 32-byte boundary.
- */
-struct fsl_dma_link_descriptor {
- __be32 source_attr; /* Programmed into SATR register */
- __be32 source_addr; /* Programmed into SAR register */
- __be32 dest_attr; /* Programmed into DATR register */
- __be32 dest_addr; /* Programmed into DAR register */
- __be64 next; /* Address of next link descriptor */
- __be32 count; /* Byte count */
- u8 res[4]; /* Reserved */
-} __attribute__ ((aligned(32), packed));
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/fsl/fsl_ssi.c b/ANDROID_3.4.5/sound/soc/fsl/fsl_ssi.c
deleted file mode 100644
index 2eb407fa..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/fsl_ssi.c
+++ /dev/null
@@ -1,800 +0,0 @@
-/*
- * Freescale SSI ALSA SoC Digital Audio Interface (DAI) driver
- *
- * Author: Timur Tabi <timur@freescale.com>
- *
- * Copyright 2007-2010 Freescale Semiconductor, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/of_platform.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include "fsl_ssi.h"
-
-/**
- * FSLSSI_I2S_RATES: sample rates supported by the I2S
- *
- * This driver currently only supports the SSI running in I2S slave mode,
- * which means the codec determines the sample rate. Therefore, we tell
- * ALSA that we support all rates and let the codec driver decide what rates
- * are really supported.
- */
-#define FSLSSI_I2S_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \
- SNDRV_PCM_RATE_CONTINUOUS)
-
-/**
- * FSLSSI_I2S_FORMATS: audio formats supported by the SSI
- *
- * This driver currently only supports the SSI running in I2S slave mode.
- *
- * The SSI has a limitation in that the samples must be in the same byte
- * order as the host CPU. This is because when multiple bytes are written
- * to the STX register, the bytes and bits must be written in the same
- * order. The STX is a shift register, so all the bits need to be aligned
- * (bit-endianness must match byte-endianness). Processors typically write
- * the bits within a byte in the same order that the bytes of a word are
- * written in. So if the host CPU is big-endian, then only big-endian
- * samples will be written to STX properly.
- */
-#ifdef __BIG_ENDIAN
-#define FSLSSI_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | \
- SNDRV_PCM_FMTBIT_S18_3BE | SNDRV_PCM_FMTBIT_S20_3BE | \
- SNDRV_PCM_FMTBIT_S24_3BE | SNDRV_PCM_FMTBIT_S24_BE)
-#else
-#define FSLSSI_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
- SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE | \
- SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE)
-#endif
-
-/* SIER bitflag of interrupts to enable */
-#define SIER_FLAGS (CCSR_SSI_SIER_TFRC_EN | CCSR_SSI_SIER_TDMAE | \
- CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TUE0_EN | \
- CCSR_SSI_SIER_TUE1_EN | CCSR_SSI_SIER_RFRC_EN | \
- CCSR_SSI_SIER_RDMAE | CCSR_SSI_SIER_RIE | \
- CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_ROE1_EN)
-
-/**
- * fsl_ssi_private: per-SSI private data
- *
- * @ssi: pointer to the SSI's registers
- * @ssi_phys: physical address of the SSI registers
- * @irq: IRQ of this SSI
- * @first_stream: pointer to the stream that was opened first
- * @second_stream: pointer to second stream
- * @playback: the number of playback streams opened
- * @capture: the number of capture streams opened
- * @cpu_dai: the CPU DAI for this device
- * @dev_attr: the sysfs device attribute structure
- * @stats: SSI statistics
- * @name: name for this device
- */
-struct fsl_ssi_private {
- struct ccsr_ssi __iomem *ssi;
- dma_addr_t ssi_phys;
- unsigned int irq;
- struct snd_pcm_substream *first_stream;
- struct snd_pcm_substream *second_stream;
- unsigned int fifo_depth;
- struct snd_soc_dai_driver cpu_dai_drv;
- struct device_attribute dev_attr;
- struct platform_device *pdev;
-
- struct {
- unsigned int rfrc;
- unsigned int tfrc;
- unsigned int cmdau;
- unsigned int cmddu;
- unsigned int rxt;
- unsigned int rdr1;
- unsigned int rdr0;
- unsigned int tde1;
- unsigned int tde0;
- unsigned int roe1;
- unsigned int roe0;
- unsigned int tue1;
- unsigned int tue0;
- unsigned int tfs;
- unsigned int rfs;
- unsigned int tls;
- unsigned int rls;
- unsigned int rff1;
- unsigned int rff0;
- unsigned int tfe1;
- unsigned int tfe0;
- } stats;
-
- char name[1];
-};
-
-/**
- * fsl_ssi_isr: SSI interrupt handler
- *
- * Although it's possible to use the interrupt handler to send and receive
- * data to/from the SSI, we use the DMA instead. Programming is more
- * complicated, but the performance is much better.
- *
- * This interrupt handler is used only to gather statistics.
- *
- * @irq: IRQ of the SSI device
- * @dev_id: pointer to the ssi_private structure for this SSI device
- */
-static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
-{
- struct fsl_ssi_private *ssi_private = dev_id;
- struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
- irqreturn_t ret = IRQ_NONE;
- __be32 sisr;
- __be32 sisr2 = 0;
-
- /* We got an interrupt, so read the status register to see what we
- were interrupted for. We mask it with the Interrupt Enable register
- so that we only check for events that we're interested in.
- */
- sisr = in_be32(&ssi->sisr) & SIER_FLAGS;
-
- if (sisr & CCSR_SSI_SISR_RFRC) {
- ssi_private->stats.rfrc++;
- sisr2 |= CCSR_SSI_SISR_RFRC;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_TFRC) {
- ssi_private->stats.tfrc++;
- sisr2 |= CCSR_SSI_SISR_TFRC;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_CMDAU) {
- ssi_private->stats.cmdau++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_CMDDU) {
- ssi_private->stats.cmddu++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_RXT) {
- ssi_private->stats.rxt++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_RDR1) {
- ssi_private->stats.rdr1++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_RDR0) {
- ssi_private->stats.rdr0++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_TDE1) {
- ssi_private->stats.tde1++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_TDE0) {
- ssi_private->stats.tde0++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_ROE1) {
- ssi_private->stats.roe1++;
- sisr2 |= CCSR_SSI_SISR_ROE1;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_ROE0) {
- ssi_private->stats.roe0++;
- sisr2 |= CCSR_SSI_SISR_ROE0;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_TUE1) {
- ssi_private->stats.tue1++;
- sisr2 |= CCSR_SSI_SISR_TUE1;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_TUE0) {
- ssi_private->stats.tue0++;
- sisr2 |= CCSR_SSI_SISR_TUE0;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_TFS) {
- ssi_private->stats.tfs++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_RFS) {
- ssi_private->stats.rfs++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_TLS) {
- ssi_private->stats.tls++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_RLS) {
- ssi_private->stats.rls++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_RFF1) {
- ssi_private->stats.rff1++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_RFF0) {
- ssi_private->stats.rff0++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_TFE1) {
- ssi_private->stats.tfe1++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_TFE0) {
- ssi_private->stats.tfe0++;
- ret = IRQ_HANDLED;
- }
-
- /* Clear the bits that we set */
- if (sisr2)
- out_be32(&ssi->sisr, sisr2);
-
- return ret;
-}
-
-/**
- * fsl_ssi_startup: create a new substream
- *
- * This is the first function called when a stream is opened.
- *
- * If this is the first stream open, then grab the IRQ and program most of
- * the SSI registers.
- */
-static int fsl_ssi_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct fsl_ssi_private *ssi_private =
- snd_soc_dai_get_drvdata(rtd->cpu_dai);
- int synchronous = ssi_private->cpu_dai_drv.symmetric_rates;
-
- /*
- * If this is the first stream opened, then request the IRQ
- * and initialize the SSI registers.
- */
- if (!ssi_private->first_stream) {
- struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
-
- ssi_private->first_stream = substream;
-
- /*
- * Section 16.5 of the MPC8610 reference manual says that the
- * SSI needs to be disabled before updating the registers we set
- * here.
- */
- clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
-
- /*
- * Program the SSI into I2S Slave Non-Network Synchronous mode.
- * Also enable the transmit and receive FIFO.
- *
- * FIXME: Little-endian samples require a different shift dir
- */
- clrsetbits_be32(&ssi->scr,
- CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
- CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE
- | (synchronous ? CCSR_SSI_SCR_SYN : 0));
-
- out_be32(&ssi->stcr,
- CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
- CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS |
- CCSR_SSI_STCR_TSCKP);
-
- out_be32(&ssi->srcr,
- CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
- CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
- CCSR_SSI_SRCR_RSCKP);
-
- /*
- * The DC and PM bits are only used if the SSI is the clock
- * master.
- */
-
- /* Enable the interrupts and DMA requests */
- out_be32(&ssi->sier, SIER_FLAGS);
-
- /*
- * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
- * don't use FIFO 1. We program the transmit water to signal a
- * DMA transfer if there are only two (or fewer) elements left
- * in the FIFO. Two elements equals one frame (left channel,
- * right channel). This value, however, depends on the depth of
- * the transmit buffer.
- *
- * We program the receive FIFO to notify us if at least two
- * elements (one frame) have been written to the FIFO. We could
- * make this value larger (and maybe we should), but this way
- * data will be written to memory as soon as it's available.
- */
- out_be32(&ssi->sfcsr,
- CCSR_SSI_SFCSR_TFWM0(ssi_private->fifo_depth - 2) |
- CCSR_SSI_SFCSR_RFWM0(ssi_private->fifo_depth - 2));
-
- /*
- * We keep the SSI disabled because if we enable it, then the
- * DMA controller will start. It's not supposed to start until
- * the SCR.TE (or SCR.RE) bit is set, but it does anyway. The
- * DMA controller will transfer one "BWC" of data (i.e. the
- * amount of data that the MR.BWC bits are set to). The reason
- * this is bad is because at this point, the PCM driver has not
- * finished initializing the DMA controller.
- */
- } else {
- if (synchronous) {
- struct snd_pcm_runtime *first_runtime =
- ssi_private->first_stream->runtime;
- /*
- * This is the second stream open, and we're in
- * synchronous mode, so we need to impose sample
- * sample size constraints. This is because STCCR is
- * used for playback and capture in synchronous mode,
- * so there's no way to specify different word
- * lengths.
- *
- * Note that this can cause a race condition if the
- * second stream is opened before the first stream is
- * fully initialized. We provide some protection by
- * checking to make sure the first stream is
- * initialized, but it's not perfect. ALSA sometimes
- * re-initializes the driver with a different sample
- * rate or size. If the second stream is opened
- * before the first stream has received its final
- * parameters, then the second stream may be
- * constrained to the wrong sample rate or size.
- */
- if (!first_runtime->sample_bits) {
- dev_err(substream->pcm->card->dev,
- "set sample size in %s stream first\n",
- substream->stream ==
- SNDRV_PCM_STREAM_PLAYBACK
- ? "capture" : "playback");
- return -EAGAIN;
- }
-
- snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
- first_runtime->sample_bits,
- first_runtime->sample_bits);
- }
-
- ssi_private->second_stream = substream;
- }
-
- return 0;
-}
-
-/**
- * fsl_ssi_hw_params - program the sample size
- *
- * Most of the SSI registers have been programmed in the startup function,
- * but the word length must be programmed here. Unfortunately, programming
- * the SxCCR.WL bits requires the SSI to be temporarily disabled. This can
- * cause a problem with supporting simultaneous playback and capture. If
- * the SSI is already playing a stream, then that stream may be temporarily
- * stopped when you start capture.
- *
- * Note: The SxCCR.DC and SxCCR.PM bits are only used if the SSI is the
- * clock master.
- */
-static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai)
-{
- struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
- struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
- unsigned int sample_size =
- snd_pcm_format_width(params_format(hw_params));
- u32 wl = CCSR_SSI_SxCCR_WL(sample_size);
- int enabled = in_be32(&ssi->scr) & CCSR_SSI_SCR_SSIEN;
-
- /*
- * If we're in synchronous mode, and the SSI is already enabled,
- * then STCCR is already set properly.
- */
- if (enabled && ssi_private->cpu_dai_drv.symmetric_rates)
- return 0;
-
- /*
- * FIXME: The documentation says that SxCCR[WL] should not be
- * modified while the SSI is enabled. The only time this can
- * happen is if we're trying to do simultaneous playback and
- * capture in asynchronous mode. Unfortunately, I have been enable
- * to get that to work at all on the P1022DS. Therefore, we don't
- * bother to disable/enable the SSI when setting SxCCR[WL], because
- * the SSI will stop anyway. Maybe one day, this will get fixed.
- */
-
- /* In synchronous mode, the SSI uses STCCR for capture */
- if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ||
- ssi_private->cpu_dai_drv.symmetric_rates)
- clrsetbits_be32(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl);
- else
- clrsetbits_be32(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl);
-
- return 0;
-}
-
-/**
- * fsl_ssi_trigger: start and stop the DMA transfer.
- *
- * This function is called by ALSA to start, stop, pause, and resume the DMA
- * transfer of data.
- *
- * The DMA channel is in external master start and pause mode, which
- * means the SSI completely controls the flow of data.
- */
-static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
- struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- setbits32(&ssi->scr,
- CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE);
- else
- setbits32(&ssi->scr,
- CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE);
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- clrbits32(&ssi->scr, CCSR_SSI_SCR_TE);
- else
- clrbits32(&ssi->scr, CCSR_SSI_SCR_RE);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/**
- * fsl_ssi_shutdown: shutdown the SSI
- *
- * Shutdown the SSI if there are no other substreams open.
- */
-static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
-
- if (ssi_private->first_stream == substream)
- ssi_private->first_stream = ssi_private->second_stream;
-
- ssi_private->second_stream = NULL;
-
- /*
- * If this is the last active substream, disable the SSI.
- */
- if (!ssi_private->first_stream) {
- struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
-
- clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
- }
-}
-
-static const struct snd_soc_dai_ops fsl_ssi_dai_ops = {
- .startup = fsl_ssi_startup,
- .hw_params = fsl_ssi_hw_params,
- .shutdown = fsl_ssi_shutdown,
- .trigger = fsl_ssi_trigger,
-};
-
-/* Template for the CPU dai driver structure */
-static struct snd_soc_dai_driver fsl_ssi_dai_template = {
- .playback = {
- /* The SSI does not support monaural audio. */
- .channels_min = 2,
- .channels_max = 2,
- .rates = FSLSSI_I2S_RATES,
- .formats = FSLSSI_I2S_FORMATS,
- },
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = FSLSSI_I2S_RATES,
- .formats = FSLSSI_I2S_FORMATS,
- },
- .ops = &fsl_ssi_dai_ops,
-};
-
-/* Show the statistics of a flag only if its interrupt is enabled. The
- * compiler will optimze this code to a no-op if the interrupt is not
- * enabled.
- */
-#define SIER_SHOW(flag, name) \
- do { \
- if (SIER_FLAGS & CCSR_SSI_SIER_##flag) \
- length += sprintf(buf + length, #name "=%u\n", \
- ssi_private->stats.name); \
- } while (0)
-
-
-/**
- * fsl_sysfs_ssi_show: display SSI statistics
- *
- * Display the statistics for the current SSI device. To avoid confusion,
- * we only show those counts that are enabled.
- */
-static ssize_t fsl_sysfs_ssi_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct fsl_ssi_private *ssi_private =
- container_of(attr, struct fsl_ssi_private, dev_attr);
- ssize_t length = 0;
-
- SIER_SHOW(RFRC_EN, rfrc);
- SIER_SHOW(TFRC_EN, tfrc);
- SIER_SHOW(CMDAU_EN, cmdau);
- SIER_SHOW(CMDDU_EN, cmddu);
- SIER_SHOW(RXT_EN, rxt);
- SIER_SHOW(RDR1_EN, rdr1);
- SIER_SHOW(RDR0_EN, rdr0);
- SIER_SHOW(TDE1_EN, tde1);
- SIER_SHOW(TDE0_EN, tde0);
- SIER_SHOW(ROE1_EN, roe1);
- SIER_SHOW(ROE0_EN, roe0);
- SIER_SHOW(TUE1_EN, tue1);
- SIER_SHOW(TUE0_EN, tue0);
- SIER_SHOW(TFS_EN, tfs);
- SIER_SHOW(RFS_EN, rfs);
- SIER_SHOW(TLS_EN, tls);
- SIER_SHOW(RLS_EN, rls);
- SIER_SHOW(RFF1_EN, rff1);
- SIER_SHOW(RFF0_EN, rff0);
- SIER_SHOW(TFE1_EN, tfe1);
- SIER_SHOW(TFE0_EN, tfe0);
-
- return length;
-}
-
-/**
- * Make every character in a string lower-case
- */
-static void make_lowercase(char *s)
-{
- char *p = s;
- char c;
-
- while ((c = *p)) {
- if ((c >= 'A') && (c <= 'Z'))
- *p = c + ('a' - 'A');
- p++;
- }
-}
-
-static int __devinit fsl_ssi_probe(struct platform_device *pdev)
-{
- struct fsl_ssi_private *ssi_private;
- int ret = 0;
- struct device_attribute *dev_attr = NULL;
- struct device_node *np = pdev->dev.of_node;
- const char *p, *sprop;
- const uint32_t *iprop;
- struct resource res;
- char name[64];
-
- /* SSIs that are not connected on the board should have a
- * status = "disabled"
- * property in their device tree nodes.
- */
- if (!of_device_is_available(np))
- return -ENODEV;
-
- /* Check for a codec-handle property. */
- if (!of_get_property(np, "codec-handle", NULL)) {
- dev_err(&pdev->dev, "missing codec-handle property\n");
- return -ENODEV;
- }
-
- /* We only support the SSI in "I2S Slave" mode */
- sprop = of_get_property(np, "fsl,mode", NULL);
- if (!sprop || strcmp(sprop, "i2s-slave")) {
- dev_notice(&pdev->dev, "mode %s is unsupported\n", sprop);
- return -ENODEV;
- }
-
- /* The DAI name is the last part of the full name of the node. */
- p = strrchr(np->full_name, '/') + 1;
- ssi_private = kzalloc(sizeof(struct fsl_ssi_private) + strlen(p),
- GFP_KERNEL);
- if (!ssi_private) {
- dev_err(&pdev->dev, "could not allocate DAI object\n");
- return -ENOMEM;
- }
-
- strcpy(ssi_private->name, p);
-
- /* Initialize this copy of the CPU DAI driver structure */
- memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template,
- sizeof(fsl_ssi_dai_template));
- ssi_private->cpu_dai_drv.name = ssi_private->name;
-
- /* Get the addresses and IRQ */
- ret = of_address_to_resource(np, 0, &res);
- if (ret) {
- dev_err(&pdev->dev, "could not determine device resources\n");
- goto error_kmalloc;
- }
- ssi_private->ssi = of_iomap(np, 0);
- if (!ssi_private->ssi) {
- dev_err(&pdev->dev, "could not map device resources\n");
- ret = -ENOMEM;
- goto error_kmalloc;
- }
- ssi_private->ssi_phys = res.start;
-
- ssi_private->irq = irq_of_parse_and_map(np, 0);
- if (ssi_private->irq == NO_IRQ) {
- dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
- ret = -ENXIO;
- goto error_iomap;
- }
-
- /* The 'name' should not have any slashes in it. */
- ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0, ssi_private->name,
- ssi_private);
- if (ret < 0) {
- dev_err(&pdev->dev, "could not claim irq %u\n", ssi_private->irq);
- goto error_irqmap;
- }
-
- /* Are the RX and the TX clocks locked? */
- if (!of_find_property(np, "fsl,ssi-asynchronous", NULL))
- ssi_private->cpu_dai_drv.symmetric_rates = 1;
-
- /* Determine the FIFO depth. */
- iprop = of_get_property(np, "fsl,fifo-depth", NULL);
- if (iprop)
- ssi_private->fifo_depth = be32_to_cpup(iprop);
- else
- /* Older 8610 DTs didn't have the fifo-depth property */
- ssi_private->fifo_depth = 8;
-
- /* Initialize the the device_attribute structure */
- dev_attr = &ssi_private->dev_attr;
- sysfs_attr_init(&dev_attr->attr);
- dev_attr->attr.name = "statistics";
- dev_attr->attr.mode = S_IRUGO;
- dev_attr->show = fsl_sysfs_ssi_show;
-
- ret = device_create_file(&pdev->dev, dev_attr);
- if (ret) {
- dev_err(&pdev->dev, "could not create sysfs %s file\n",
- ssi_private->dev_attr.attr.name);
- goto error_irq;
- }
-
- /* Register with ASoC */
- dev_set_drvdata(&pdev->dev, ssi_private);
-
- ret = snd_soc_register_dai(&pdev->dev, &ssi_private->cpu_dai_drv);
- if (ret) {
- dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
- goto error_dev;
- }
-
- /* Trigger the machine driver's probe function. The platform driver
- * name of the machine driver is taken from /compatible property of the
- * device tree. We also pass the address of the CPU DAI driver
- * structure.
- */
- sprop = of_get_property(of_find_node_by_path("/"), "compatible", NULL);
- /* Sometimes the compatible name has a "fsl," prefix, so we strip it. */
- p = strrchr(sprop, ',');
- if (p)
- sprop = p + 1;
- snprintf(name, sizeof(name), "snd-soc-%s", sprop);
- make_lowercase(name);
-
- ssi_private->pdev =
- platform_device_register_data(&pdev->dev, name, 0, NULL, 0);
- if (IS_ERR(ssi_private->pdev)) {
- ret = PTR_ERR(ssi_private->pdev);
- dev_err(&pdev->dev, "failed to register platform: %d\n", ret);
- goto error_dai;
- }
-
- return 0;
-
-error_dai:
- snd_soc_unregister_dai(&pdev->dev);
-
-error_dev:
- dev_set_drvdata(&pdev->dev, NULL);
- device_remove_file(&pdev->dev, dev_attr);
-
-error_irq:
- free_irq(ssi_private->irq, ssi_private);
-
-error_irqmap:
- irq_dispose_mapping(ssi_private->irq);
-
-error_iomap:
- iounmap(ssi_private->ssi);
-
-error_kmalloc:
- kfree(ssi_private);
-
- return ret;
-}
-
-static int fsl_ssi_remove(struct platform_device *pdev)
-{
- struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev);
-
- platform_device_unregister(ssi_private->pdev);
- snd_soc_unregister_dai(&pdev->dev);
- device_remove_file(&pdev->dev, &ssi_private->dev_attr);
-
- free_irq(ssi_private->irq, ssi_private);
- irq_dispose_mapping(ssi_private->irq);
-
- kfree(ssi_private);
- dev_set_drvdata(&pdev->dev, NULL);
-
- return 0;
-}
-
-static const struct of_device_id fsl_ssi_ids[] = {
- { .compatible = "fsl,mpc8610-ssi", },
- {}
-};
-MODULE_DEVICE_TABLE(of, fsl_ssi_ids);
-
-static struct platform_driver fsl_ssi_driver = {
- .driver = {
- .name = "fsl-ssi-dai",
- .owner = THIS_MODULE,
- .of_match_table = fsl_ssi_ids,
- },
- .probe = fsl_ssi_probe,
- .remove = fsl_ssi_remove,
-};
-
-module_platform_driver(fsl_ssi_driver);
-
-MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
-MODULE_DESCRIPTION("Freescale Synchronous Serial Interface (SSI) ASoC Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/sound/soc/fsl/fsl_ssi.h b/ANDROID_3.4.5/sound/soc/fsl/fsl_ssi.h
deleted file mode 100644
index 21730002..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/fsl_ssi.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * fsl_ssi.h - ALSA SSI interface for the Freescale MPC8610 SoC
- *
- * Author: Timur Tabi <timur@freescale.com>
- *
- * Copyright 2007-2008 Freescale Semiconductor, Inc. This file is licensed
- * under the terms of the GNU General Public License version 2. This
- * program is licensed "as is" without any warranty of any kind, whether
- * express or implied.
- */
-
-#ifndef _MPC8610_I2S_H
-#define _MPC8610_I2S_H
-
-/* SSI Register Map */
-struct ccsr_ssi {
- __be32 stx0; /* 0x.0000 - SSI Transmit Data Register 0 */
- __be32 stx1; /* 0x.0004 - SSI Transmit Data Register 1 */
- __be32 srx0; /* 0x.0008 - SSI Receive Data Register 0 */
- __be32 srx1; /* 0x.000C - SSI Receive Data Register 1 */
- __be32 scr; /* 0x.0010 - SSI Control Register */
- __be32 sisr; /* 0x.0014 - SSI Interrupt Status Register Mixed */
- __be32 sier; /* 0x.0018 - SSI Interrupt Enable Register */
- __be32 stcr; /* 0x.001C - SSI Transmit Configuration Register */
- __be32 srcr; /* 0x.0020 - SSI Receive Configuration Register */
- __be32 stccr; /* 0x.0024 - SSI Transmit Clock Control Register */
- __be32 srccr; /* 0x.0028 - SSI Receive Clock Control Register */
- __be32 sfcsr; /* 0x.002C - SSI FIFO Control/Status Register */
- __be32 str; /* 0x.0030 - SSI Test Register */
- __be32 sor; /* 0x.0034 - SSI Option Register */
- __be32 sacnt; /* 0x.0038 - SSI AC97 Control Register */
- __be32 sacadd; /* 0x.003C - SSI AC97 Command Address Register */
- __be32 sacdat; /* 0x.0040 - SSI AC97 Command Data Register */
- __be32 satag; /* 0x.0044 - SSI AC97 Tag Register */
- __be32 stmsk; /* 0x.0048 - SSI Transmit Time Slot Mask Register */
- __be32 srmsk; /* 0x.004C - SSI Receive Time Slot Mask Register */
- __be32 saccst; /* 0x.0050 - SSI AC97 Channel Status Register */
- __be32 saccen; /* 0x.0054 - SSI AC97 Channel Enable Register */
- __be32 saccdis; /* 0x.0058 - SSI AC97 Channel Disable Register */
-};
-
-#define CCSR_SSI_SCR_RFR_CLK_DIS 0x00000800
-#define CCSR_SSI_SCR_TFR_CLK_DIS 0x00000400
-#define CCSR_SSI_SCR_TCH_EN 0x00000100
-#define CCSR_SSI_SCR_SYS_CLK_EN 0x00000080
-#define CCSR_SSI_SCR_I2S_MODE_MASK 0x00000060
-#define CCSR_SSI_SCR_I2S_MODE_NORMAL 0x00000000
-#define CCSR_SSI_SCR_I2S_MODE_MASTER 0x00000020
-#define CCSR_SSI_SCR_I2S_MODE_SLAVE 0x00000040
-#define CCSR_SSI_SCR_SYN 0x00000010
-#define CCSR_SSI_SCR_NET 0x00000008
-#define CCSR_SSI_SCR_RE 0x00000004
-#define CCSR_SSI_SCR_TE 0x00000002
-#define CCSR_SSI_SCR_SSIEN 0x00000001
-
-#define CCSR_SSI_SISR_RFRC 0x01000000
-#define CCSR_SSI_SISR_TFRC 0x00800000
-#define CCSR_SSI_SISR_CMDAU 0x00040000
-#define CCSR_SSI_SISR_CMDDU 0x00020000
-#define CCSR_SSI_SISR_RXT 0x00010000
-#define CCSR_SSI_SISR_RDR1 0x00008000
-#define CCSR_SSI_SISR_RDR0 0x00004000
-#define CCSR_SSI_SISR_TDE1 0x00002000
-#define CCSR_SSI_SISR_TDE0 0x00001000
-#define CCSR_SSI_SISR_ROE1 0x00000800
-#define CCSR_SSI_SISR_ROE0 0x00000400
-#define CCSR_SSI_SISR_TUE1 0x00000200
-#define CCSR_SSI_SISR_TUE0 0x00000100
-#define CCSR_SSI_SISR_TFS 0x00000080
-#define CCSR_SSI_SISR_RFS 0x00000040
-#define CCSR_SSI_SISR_TLS 0x00000020
-#define CCSR_SSI_SISR_RLS 0x00000010
-#define CCSR_SSI_SISR_RFF1 0x00000008
-#define CCSR_SSI_SISR_RFF0 0x00000004
-#define CCSR_SSI_SISR_TFE1 0x00000002
-#define CCSR_SSI_SISR_TFE0 0x00000001
-
-#define CCSR_SSI_SIER_RFRC_EN 0x01000000
-#define CCSR_SSI_SIER_TFRC_EN 0x00800000
-#define CCSR_SSI_SIER_RDMAE 0x00400000
-#define CCSR_SSI_SIER_RIE 0x00200000
-#define CCSR_SSI_SIER_TDMAE 0x00100000
-#define CCSR_SSI_SIER_TIE 0x00080000
-#define CCSR_SSI_SIER_CMDAU_EN 0x00040000
-#define CCSR_SSI_SIER_CMDDU_EN 0x00020000
-#define CCSR_SSI_SIER_RXT_EN 0x00010000
-#define CCSR_SSI_SIER_RDR1_EN 0x00008000
-#define CCSR_SSI_SIER_RDR0_EN 0x00004000
-#define CCSR_SSI_SIER_TDE1_EN 0x00002000
-#define CCSR_SSI_SIER_TDE0_EN 0x00001000
-#define CCSR_SSI_SIER_ROE1_EN 0x00000800
-#define CCSR_SSI_SIER_ROE0_EN 0x00000400
-#define CCSR_SSI_SIER_TUE1_EN 0x00000200
-#define CCSR_SSI_SIER_TUE0_EN 0x00000100
-#define CCSR_SSI_SIER_TFS_EN 0x00000080
-#define CCSR_SSI_SIER_RFS_EN 0x00000040
-#define CCSR_SSI_SIER_TLS_EN 0x00000020
-#define CCSR_SSI_SIER_RLS_EN 0x00000010
-#define CCSR_SSI_SIER_RFF1_EN 0x00000008
-#define CCSR_SSI_SIER_RFF0_EN 0x00000004
-#define CCSR_SSI_SIER_TFE1_EN 0x00000002
-#define CCSR_SSI_SIER_TFE0_EN 0x00000001
-
-#define CCSR_SSI_STCR_TXBIT0 0x00000200
-#define CCSR_SSI_STCR_TFEN1 0x00000100
-#define CCSR_SSI_STCR_TFEN0 0x00000080
-#define CCSR_SSI_STCR_TFDIR 0x00000040
-#define CCSR_SSI_STCR_TXDIR 0x00000020
-#define CCSR_SSI_STCR_TSHFD 0x00000010
-#define CCSR_SSI_STCR_TSCKP 0x00000008
-#define CCSR_SSI_STCR_TFSI 0x00000004
-#define CCSR_SSI_STCR_TFSL 0x00000002
-#define CCSR_SSI_STCR_TEFS 0x00000001
-
-#define CCSR_SSI_SRCR_RXEXT 0x00000400
-#define CCSR_SSI_SRCR_RXBIT0 0x00000200
-#define CCSR_SSI_SRCR_RFEN1 0x00000100
-#define CCSR_SSI_SRCR_RFEN0 0x00000080
-#define CCSR_SSI_SRCR_RFDIR 0x00000040
-#define CCSR_SSI_SRCR_RXDIR 0x00000020
-#define CCSR_SSI_SRCR_RSHFD 0x00000010
-#define CCSR_SSI_SRCR_RSCKP 0x00000008
-#define CCSR_SSI_SRCR_RFSI 0x00000004
-#define CCSR_SSI_SRCR_RFSL 0x00000002
-#define CCSR_SSI_SRCR_REFS 0x00000001
-
-/* STCCR and SRCCR */
-#define CCSR_SSI_SxCCR_DIV2 0x00040000
-#define CCSR_SSI_SxCCR_PSR 0x00020000
-#define CCSR_SSI_SxCCR_WL_SHIFT 13
-#define CCSR_SSI_SxCCR_WL_MASK 0x0001E000
-#define CCSR_SSI_SxCCR_WL(x) \
- (((((x) / 2) - 1) << CCSR_SSI_SxCCR_WL_SHIFT) & CCSR_SSI_SxCCR_WL_MASK)
-#define CCSR_SSI_SxCCR_DC_SHIFT 8
-#define CCSR_SSI_SxCCR_DC_MASK 0x00001F00
-#define CCSR_SSI_SxCCR_DC(x) \
- ((((x) - 1) << CCSR_SSI_SxCCR_DC_SHIFT) & CCSR_SSI_SxCCR_DC_MASK)
-#define CCSR_SSI_SxCCR_PM_SHIFT 0
-#define CCSR_SSI_SxCCR_PM_MASK 0x000000FF
-#define CCSR_SSI_SxCCR_PM(x) \
- ((((x) - 1) << CCSR_SSI_SxCCR_PM_SHIFT) & CCSR_SSI_SxCCR_PM_MASK)
-
-/*
- * The xFCNT bits are read-only, and the xFWM bits are read/write. Use the
- * CCSR_SSI_SFCSR_xFCNTy() macros to read the FIFO counters, and use the
- * CCSR_SSI_SFCSR_xFWMy() macros to set the watermarks.
- */
-#define CCSR_SSI_SFCSR_RFCNT1_SHIFT 28
-#define CCSR_SSI_SFCSR_RFCNT1_MASK 0xF0000000
-#define CCSR_SSI_SFCSR_RFCNT1(x) \
- (((x) & CCSR_SSI_SFCSR_RFCNT1_MASK) >> CCSR_SSI_SFCSR_RFCNT1_SHIFT)
-#define CCSR_SSI_SFCSR_TFCNT1_SHIFT 24
-#define CCSR_SSI_SFCSR_TFCNT1_MASK 0x0F000000
-#define CCSR_SSI_SFCSR_TFCNT1(x) \
- (((x) & CCSR_SSI_SFCSR_TFCNT1_MASK) >> CCSR_SSI_SFCSR_TFCNT1_SHIFT)
-#define CCSR_SSI_SFCSR_RFWM1_SHIFT 20
-#define CCSR_SSI_SFCSR_RFWM1_MASK 0x00F00000
-#define CCSR_SSI_SFCSR_RFWM1(x) \
- (((x) << CCSR_SSI_SFCSR_RFWM1_SHIFT) & CCSR_SSI_SFCSR_RFWM1_MASK)
-#define CCSR_SSI_SFCSR_TFWM1_SHIFT 16
-#define CCSR_SSI_SFCSR_TFWM1_MASK 0x000F0000
-#define CCSR_SSI_SFCSR_TFWM1(x) \
- (((x) << CCSR_SSI_SFCSR_TFWM1_SHIFT) & CCSR_SSI_SFCSR_TFWM1_MASK)
-#define CCSR_SSI_SFCSR_RFCNT0_SHIFT 12
-#define CCSR_SSI_SFCSR_RFCNT0_MASK 0x0000F000
-#define CCSR_SSI_SFCSR_RFCNT0(x) \
- (((x) & CCSR_SSI_SFCSR_RFCNT0_MASK) >> CCSR_SSI_SFCSR_RFCNT0_SHIFT)
-#define CCSR_SSI_SFCSR_TFCNT0_SHIFT 8
-#define CCSR_SSI_SFCSR_TFCNT0_MASK 0x00000F00
-#define CCSR_SSI_SFCSR_TFCNT0(x) \
- (((x) & CCSR_SSI_SFCSR_TFCNT0_MASK) >> CCSR_SSI_SFCSR_TFCNT0_SHIFT)
-#define CCSR_SSI_SFCSR_RFWM0_SHIFT 4
-#define CCSR_SSI_SFCSR_RFWM0_MASK 0x000000F0
-#define CCSR_SSI_SFCSR_RFWM0(x) \
- (((x) << CCSR_SSI_SFCSR_RFWM0_SHIFT) & CCSR_SSI_SFCSR_RFWM0_MASK)
-#define CCSR_SSI_SFCSR_TFWM0_SHIFT 0
-#define CCSR_SSI_SFCSR_TFWM0_MASK 0x0000000F
-#define CCSR_SSI_SFCSR_TFWM0(x) \
- (((x) << CCSR_SSI_SFCSR_TFWM0_SHIFT) & CCSR_SSI_SFCSR_TFWM0_MASK)
-
-#define CCSR_SSI_STR_TEST 0x00008000
-#define CCSR_SSI_STR_RCK2TCK 0x00004000
-#define CCSR_SSI_STR_RFS2TFS 0x00002000
-#define CCSR_SSI_STR_RXSTATE(x) (((x) >> 8) & 0x1F)
-#define CCSR_SSI_STR_TXD2RXD 0x00000080
-#define CCSR_SSI_STR_TCK2RCK 0x00000040
-#define CCSR_SSI_STR_TFS2RFS 0x00000020
-#define CCSR_SSI_STR_TXSTATE(x) ((x) & 0x1F)
-
-#define CCSR_SSI_SOR_CLKOFF 0x00000040
-#define CCSR_SSI_SOR_RX_CLR 0x00000020
-#define CCSR_SSI_SOR_TX_CLR 0x00000010
-#define CCSR_SSI_SOR_INIT 0x00000008
-#define CCSR_SSI_SOR_WAIT_SHIFT 1
-#define CCSR_SSI_SOR_WAIT_MASK 0x00000006
-#define CCSR_SSI_SOR_WAIT(x) (((x) & 3) << CCSR_SSI_SOR_WAIT_SHIFT)
-#define CCSR_SSI_SOR_SYNRST 0x00000001
-
-#endif
-
diff --git a/ANDROID_3.4.5/sound/soc/fsl/mpc5200_dma.c b/ANDROID_3.4.5/sound/soc/fsl/mpc5200_dma.c
deleted file mode 100644
index 9a3f7c5a..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/mpc5200_dma.c
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- * Freescale MPC5200 PSC DMA
- * ALSA SoC Platform driver
- *
- * Copyright (C) 2008 Secret Lab Technologies Ltd.
- * Copyright (C) 2009 Jon Smirl, Digispeaker
- */
-
-#include <linux/module.h>
-#include <linux/of_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-#include <linux/of_platform.h>
-
-#include <sound/soc.h>
-
-#include <sysdev/bestcomm/bestcomm.h>
-#include <sysdev/bestcomm/gen_bd.h>
-#include <asm/mpc52xx_psc.h>
-
-#include "mpc5200_dma.h"
-
-/*
- * Interrupt handlers
- */
-static irqreturn_t psc_dma_status_irq(int irq, void *_psc_dma)
-{
- struct psc_dma *psc_dma = _psc_dma;
- struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
- u16 isr;
-
- isr = in_be16(&regs->mpc52xx_psc_isr);
-
- /* Playback underrun error */
- if (psc_dma->playback.active && (isr & MPC52xx_PSC_IMR_TXEMP))
- psc_dma->stats.underrun_count++;
-
- /* Capture overrun error */
- if (psc_dma->capture.active && (isr & MPC52xx_PSC_IMR_ORERR))
- psc_dma->stats.overrun_count++;
-
- out_8(&regs->command, MPC52xx_PSC_RST_ERR_STAT);
-
- return IRQ_HANDLED;
-}
-
-/**
- * psc_dma_bcom_enqueue_next_buffer - Enqueue another audio buffer
- * @s: pointer to stream private data structure
- *
- * Enqueues another audio period buffer into the bestcomm queue.
- *
- * Note: The routine must only be called when there is space available in
- * the queue. Otherwise the enqueue will fail and the audio ring buffer
- * will get out of sync
- */
-static void psc_dma_bcom_enqueue_next_buffer(struct psc_dma_stream *s)
-{
- struct bcom_bd *bd;
-
- /* Prepare and enqueue the next buffer descriptor */
- bd = bcom_prepare_next_buffer(s->bcom_task);
- bd->status = s->period_bytes;
- bd->data[0] = s->runtime->dma_addr + (s->period_next * s->period_bytes);
- bcom_submit_next_buffer(s->bcom_task, NULL);
-
- /* Update for next period */
- s->period_next = (s->period_next + 1) % s->runtime->periods;
-}
-
-/* Bestcomm DMA irq handler */
-static irqreturn_t psc_dma_bcom_irq(int irq, void *_psc_dma_stream)
-{
- struct psc_dma_stream *s = _psc_dma_stream;
-
- spin_lock(&s->psc_dma->lock);
- /* For each finished period, dequeue the completed period buffer
- * and enqueue a new one in it's place. */
- while (bcom_buffer_done(s->bcom_task)) {
- bcom_retrieve_buffer(s->bcom_task, NULL, NULL);
-
- s->period_current = (s->period_current+1) % s->runtime->periods;
- s->period_count++;
-
- psc_dma_bcom_enqueue_next_buffer(s);
- }
- spin_unlock(&s->psc_dma->lock);
-
- /* If the stream is active, then also inform the PCM middle layer
- * of the period finished event. */
- if (s->active)
- snd_pcm_period_elapsed(s->stream);
-
- return IRQ_HANDLED;
-}
-
-static int psc_dma_hw_free(struct snd_pcm_substream *substream)
-{
- snd_pcm_set_runtime_buffer(substream, NULL);
- return 0;
-}
-
-/**
- * psc_dma_trigger: start and stop the DMA transfer.
- *
- * This function is called by ALSA to start, stop, pause, and resume the DMA
- * transfer of data.
- */
-static int psc_dma_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma);
- struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
- u16 imr;
- unsigned long flags;
- int i;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- dev_dbg(psc_dma->dev, "START: stream=%i fbits=%u ps=%u #p=%u\n",
- substream->pstr->stream, runtime->frame_bits,
- (int)runtime->period_size, runtime->periods);
- s->period_bytes = frames_to_bytes(runtime,
- runtime->period_size);
- s->period_next = 0;
- s->period_current = 0;
- s->active = 1;
- s->period_count = 0;
- s->runtime = runtime;
-
- /* Fill up the bestcomm bd queue and enable DMA.
- * This will begin filling the PSC's fifo.
- */
- spin_lock_irqsave(&psc_dma->lock, flags);
-
- if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
- bcom_gen_bd_rx_reset(s->bcom_task);
- else
- bcom_gen_bd_tx_reset(s->bcom_task);
-
- for (i = 0; i < runtime->periods; i++)
- if (!bcom_queue_full(s->bcom_task))
- psc_dma_bcom_enqueue_next_buffer(s);
-
- bcom_enable(s->bcom_task);
- spin_unlock_irqrestore(&psc_dma->lock, flags);
-
- out_8(&regs->command, MPC52xx_PSC_RST_ERR_STAT);
-
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- dev_dbg(psc_dma->dev, "STOP: stream=%i periods_count=%i\n",
- substream->pstr->stream, s->period_count);
- s->active = 0;
-
- spin_lock_irqsave(&psc_dma->lock, flags);
- bcom_disable(s->bcom_task);
- if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
- bcom_gen_bd_rx_reset(s->bcom_task);
- else
- bcom_gen_bd_tx_reset(s->bcom_task);
- spin_unlock_irqrestore(&psc_dma->lock, flags);
-
- break;
-
- default:
- dev_dbg(psc_dma->dev, "unhandled trigger: stream=%i cmd=%i\n",
- substream->pstr->stream, cmd);
- return -EINVAL;
- }
-
- /* Update interrupt enable settings */
- imr = 0;
- if (psc_dma->playback.active)
- imr |= MPC52xx_PSC_IMR_TXEMP;
- if (psc_dma->capture.active)
- imr |= MPC52xx_PSC_IMR_ORERR;
- out_be16(&regs->isr_imr.imr, psc_dma->imr | imr);
-
- return 0;
-}
-
-
-/* ---------------------------------------------------------------------
- * The PSC DMA 'ASoC platform' driver
- *
- * Can be referenced by an 'ASoC machine' driver
- * This driver only deals with the audio bus; it doesn't have any
- * interaction with the attached codec
- */
-
-static const struct snd_pcm_hardware psc_dma_hardware = {
- .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_BATCH,
- .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .period_bytes_max = 1024 * 1024,
- .period_bytes_min = 32,
- .periods_min = 2,
- .periods_max = 256,
- .buffer_bytes_max = 2 * 1024 * 1024,
- .fifo_size = 512,
-};
-
-static int psc_dma_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
- struct psc_dma_stream *s;
- int rc;
-
- dev_dbg(psc_dma->dev, "psc_dma_open(substream=%p)\n", substream);
-
- if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
- s = &psc_dma->capture;
- else
- s = &psc_dma->playback;
-
- snd_soc_set_runtime_hwparams(substream, &psc_dma_hardware);
-
- rc = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (rc < 0) {
- dev_err(substream->pcm->card->dev, "invalid buffer size\n");
- return rc;
- }
-
- s->stream = substream;
- return 0;
-}
-
-static int psc_dma_close(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
- struct psc_dma_stream *s;
-
- dev_dbg(psc_dma->dev, "psc_dma_close(substream=%p)\n", substream);
-
- if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
- s = &psc_dma->capture;
- else
- s = &psc_dma->playback;
-
- if (!psc_dma->playback.active &&
- !psc_dma->capture.active) {
-
- /* Disable all interrupts and reset the PSC */
- out_be16(&psc_dma->psc_regs->isr_imr.imr, psc_dma->imr);
- out_8(&psc_dma->psc_regs->command, 4 << 4); /* reset error */
- }
- s->stream = NULL;
- return 0;
-}
-
-static snd_pcm_uframes_t
-psc_dma_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
- struct psc_dma_stream *s;
- dma_addr_t count;
-
- if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
- s = &psc_dma->capture;
- else
- s = &psc_dma->playback;
-
- count = s->period_current * s->period_bytes;
-
- return bytes_to_frames(substream->runtime, count);
-}
-
-static int
-psc_dma_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
-
- return 0;
-}
-
-static struct snd_pcm_ops psc_dma_ops = {
- .open = psc_dma_open,
- .close = psc_dma_close,
- .hw_free = psc_dma_hw_free,
- .ioctl = snd_pcm_lib_ioctl,
- .pointer = psc_dma_pointer,
- .trigger = psc_dma_trigger,
- .hw_params = psc_dma_hw_params,
-};
-
-static u64 psc_dma_dmamask = DMA_BIT_MASK(32);
-static int psc_dma_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_soc_dai *dai = rtd->cpu_dai;
- struct snd_pcm *pcm = rtd->pcm;
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
- size_t size = psc_dma_hardware.buffer_bytes_max;
- int rc = 0;
-
- dev_dbg(rtd->platform->dev, "psc_dma_new(card=%p, dai=%p, pcm=%p)\n",
- card, dai, pcm);
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &psc_dma_dmamask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev,
- size, &pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer);
- if (rc)
- goto playback_alloc_err;
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev,
- size, &pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->dma_buffer);
- if (rc)
- goto capture_alloc_err;
- }
-
- if (rtd->codec->ac97)
- rtd->codec->ac97->private_data = psc_dma;
-
- return 0;
-
- capture_alloc_err:
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream)
- snd_dma_free_pages(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer);
-
- playback_alloc_err:
- dev_err(card->dev, "Cannot allocate buffer(s)\n");
-
- return -ENOMEM;
-}
-
-static void psc_dma_free(struct snd_pcm *pcm)
-{
- struct snd_soc_pcm_runtime *rtd = pcm->private_data;
- struct snd_pcm_substream *substream;
- int stream;
-
- dev_dbg(rtd->platform->dev, "psc_dma_free(pcm=%p)\n", pcm);
-
- for (stream = 0; stream < 2; stream++) {
- substream = pcm->streams[stream].substream;
- if (substream) {
- snd_dma_free_pages(&substream->dma_buffer);
- substream->dma_buffer.area = NULL;
- substream->dma_buffer.addr = 0;
- }
- }
-}
-
-static struct snd_soc_platform_driver mpc5200_audio_dma_platform = {
- .ops = &psc_dma_ops,
- .pcm_new = &psc_dma_new,
- .pcm_free = &psc_dma_free,
-};
-
-static int mpc5200_hpcd_probe(struct platform_device *op)
-{
- phys_addr_t fifo;
- struct psc_dma *psc_dma;
- struct resource res;
- int size, irq, rc;
- const __be32 *prop;
- void __iomem *regs;
- int ret;
-
- /* Fetch the registers and IRQ of the PSC */
- irq = irq_of_parse_and_map(op->dev.of_node, 0);
- if (of_address_to_resource(op->dev.of_node, 0, &res)) {
- dev_err(&op->dev, "Missing reg property\n");
- return -ENODEV;
- }
- regs = ioremap(res.start, resource_size(&res));
- if (!regs) {
- dev_err(&op->dev, "Could not map registers\n");
- return -ENODEV;
- }
-
- /* Allocate and initialize the driver private data */
- psc_dma = kzalloc(sizeof *psc_dma, GFP_KERNEL);
- if (!psc_dma) {
- ret = -ENOMEM;
- goto out_unmap;
- }
-
- /* Get the PSC ID */
- prop = of_get_property(op->dev.of_node, "cell-index", &size);
- if (!prop || size < sizeof *prop) {
- ret = -ENODEV;
- goto out_free;
- }
-
- spin_lock_init(&psc_dma->lock);
- mutex_init(&psc_dma->mutex);
- psc_dma->id = be32_to_cpu(*prop);
- psc_dma->irq = irq;
- psc_dma->psc_regs = regs;
- psc_dma->fifo_regs = regs + sizeof *psc_dma->psc_regs;
- psc_dma->dev = &op->dev;
- psc_dma->playback.psc_dma = psc_dma;
- psc_dma->capture.psc_dma = psc_dma;
- snprintf(psc_dma->name, sizeof psc_dma->name, "PSC%u", psc_dma->id);
-
- /* Find the address of the fifo data registers and setup the
- * DMA tasks */
- fifo = res.start + offsetof(struct mpc52xx_psc, buffer.buffer_32);
- psc_dma->capture.bcom_task =
- bcom_psc_gen_bd_rx_init(psc_dma->id, 10, fifo, 512);
- psc_dma->playback.bcom_task =
- bcom_psc_gen_bd_tx_init(psc_dma->id, 10, fifo);
- if (!psc_dma->capture.bcom_task ||
- !psc_dma->playback.bcom_task) {
- dev_err(&op->dev, "Could not allocate bestcomm tasks\n");
- ret = -ENODEV;
- goto out_free;
- }
-
- /* Disable all interrupts and reset the PSC */
- out_be16(&psc_dma->psc_regs->isr_imr.imr, psc_dma->imr);
- /* reset receiver */
- out_8(&psc_dma->psc_regs->command, MPC52xx_PSC_RST_RX);
- /* reset transmitter */
- out_8(&psc_dma->psc_regs->command, MPC52xx_PSC_RST_TX);
- /* reset error */
- out_8(&psc_dma->psc_regs->command, MPC52xx_PSC_RST_ERR_STAT);
- /* reset mode */
- out_8(&psc_dma->psc_regs->command, MPC52xx_PSC_SEL_MODE_REG_1);
-
- /* Set up mode register;
- * First write: RxRdy (FIFO Alarm) generates rx FIFO irq
- * Second write: register Normal mode for non loopback
- */
- out_8(&psc_dma->psc_regs->mode, 0);
- out_8(&psc_dma->psc_regs->mode, 0);
-
- /* Set the TX and RX fifo alarm thresholds */
- out_be16(&psc_dma->fifo_regs->rfalarm, 0x100);
- out_8(&psc_dma->fifo_regs->rfcntl, 0x4);
- out_be16(&psc_dma->fifo_regs->tfalarm, 0x100);
- out_8(&psc_dma->fifo_regs->tfcntl, 0x7);
-
- /* Lookup the IRQ numbers */
- psc_dma->playback.irq =
- bcom_get_task_irq(psc_dma->playback.bcom_task);
- psc_dma->capture.irq =
- bcom_get_task_irq(psc_dma->capture.bcom_task);
-
- rc = request_irq(psc_dma->irq, &psc_dma_status_irq, IRQF_SHARED,
- "psc-dma-status", psc_dma);
- rc |= request_irq(psc_dma->capture.irq, &psc_dma_bcom_irq, IRQF_SHARED,
- "psc-dma-capture", &psc_dma->capture);
- rc |= request_irq(psc_dma->playback.irq, &psc_dma_bcom_irq, IRQF_SHARED,
- "psc-dma-playback", &psc_dma->playback);
- if (rc) {
- ret = -ENODEV;
- goto out_irq;
- }
-
- /* Save what we've done so it can be found again later */
- dev_set_drvdata(&op->dev, psc_dma);
-
- /* Tell the ASoC OF helpers about it */
- return snd_soc_register_platform(&op->dev, &mpc5200_audio_dma_platform);
-out_irq:
- free_irq(psc_dma->irq, psc_dma);
- free_irq(psc_dma->capture.irq, &psc_dma->capture);
- free_irq(psc_dma->playback.irq, &psc_dma->playback);
-out_free:
- kfree(psc_dma);
-out_unmap:
- iounmap(regs);
- return ret;
-}
-
-static int mpc5200_hpcd_remove(struct platform_device *op)
-{
- struct psc_dma *psc_dma = dev_get_drvdata(&op->dev);
-
- dev_dbg(&op->dev, "mpc5200_audio_dma_destroy()\n");
-
- snd_soc_unregister_platform(&op->dev);
-
- bcom_gen_bd_rx_release(psc_dma->capture.bcom_task);
- bcom_gen_bd_tx_release(psc_dma->playback.bcom_task);
-
- /* Release irqs */
- free_irq(psc_dma->irq, psc_dma);
- free_irq(psc_dma->capture.irq, &psc_dma->capture);
- free_irq(psc_dma->playback.irq, &psc_dma->playback);
-
- iounmap(psc_dma->psc_regs);
- kfree(psc_dma);
- dev_set_drvdata(&op->dev, NULL);
-
- return 0;
-}
-
-static struct of_device_id mpc5200_hpcd_match[] = {
- { .compatible = "fsl,mpc5200-pcm", },
- {}
-};
-MODULE_DEVICE_TABLE(of, mpc5200_hpcd_match);
-
-static struct platform_driver mpc5200_hpcd_of_driver = {
- .probe = mpc5200_hpcd_probe,
- .remove = mpc5200_hpcd_remove,
- .driver = {
- .owner = THIS_MODULE,
- .name = "mpc5200-pcm-audio",
- .of_match_table = mpc5200_hpcd_match,
- }
-};
-
-module_platform_driver(mpc5200_hpcd_of_driver);
-
-MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
-MODULE_DESCRIPTION("Freescale MPC5200 PSC in DMA mode ASoC Driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/fsl/mpc5200_dma.h b/ANDROID_3.4.5/sound/soc/fsl/mpc5200_dma.h
deleted file mode 100644
index a3c0cd53..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/mpc5200_dma.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Freescale MPC5200 Audio DMA driver
- */
-
-#ifndef __SOUND_SOC_FSL_MPC5200_DMA_H__
-#define __SOUND_SOC_FSL_MPC5200_DMA_H__
-
-#define PSC_STREAM_NAME_LEN 32
-
-/**
- * psc_ac97_stream - Data specific to a single stream (playback or capture)
- * @active: flag indicating if the stream is active
- * @psc_dma: pointer back to parent psc_dma data structure
- * @bcom_task: bestcomm task structure
- * @irq: irq number for bestcomm task
- * @period_end: physical address of end of DMA region
- * @period_next_pt: physical address of next DMA buffer to enqueue
- * @period_bytes: size of DMA period in bytes
- * @ac97_slot_bits: Enable bits for turning on the correct AC97 slot
- */
-struct psc_dma_stream {
- struct snd_pcm_runtime *runtime;
- int active;
- struct psc_dma *psc_dma;
- struct bcom_task *bcom_task;
- int irq;
- struct snd_pcm_substream *stream;
- int period_next;
- int period_current;
- int period_bytes;
- int period_count;
-
- /* AC97 state */
- u32 ac97_slot_bits;
-};
-
-/**
- * psc_dma - Private driver data
- * @name: short name for this device ("PSC0", "PSC1", etc)
- * @psc_regs: pointer to the PSC's registers
- * @fifo_regs: pointer to the PSC's FIFO registers
- * @irq: IRQ of this PSC
- * @dev: struct device pointer
- * @dai: the CPU DAI for this device
- * @sicr: Base value used in serial interface control register; mode is ORed
- * with this value.
- * @playback: Playback stream context data
- * @capture: Capture stream context data
- */
-struct psc_dma {
- char name[32];
- struct mpc52xx_psc __iomem *psc_regs;
- struct mpc52xx_psc_fifo __iomem *fifo_regs;
- unsigned int irq;
- struct device *dev;
- spinlock_t lock;
- struct mutex mutex;
- u32 sicr;
- uint sysclk;
- int imr;
- int id;
- unsigned int slots;
-
- /* per-stream data */
- struct psc_dma_stream playback;
- struct psc_dma_stream capture;
-
- /* Statistics */
- struct {
- unsigned long overrun_count;
- unsigned long underrun_count;
- } stats;
-};
-
-/* Utility for retrieving psc_dma_stream structure from a substream */
-static inline struct psc_dma_stream *
-to_psc_dma_stream(struct snd_pcm_substream *substream, struct psc_dma *psc_dma)
-{
- if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
- return &psc_dma->capture;
- return &psc_dma->playback;
-}
-
-#endif /* __SOUND_SOC_FSL_MPC5200_DMA_H__ */
diff --git a/ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_ac97.c b/ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_ac97.c
deleted file mode 100644
index ffa00a2e..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_ac97.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * linux/sound/mpc5200-ac97.c -- AC97 support for the Freescale MPC52xx chip.
- *
- * Copyright (C) 2009 Jon Smirl, Digispeaker
- * Author: Jon Smirl <jonsmirl@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/of_device.h>
-#include <linux/of_platform.h>
-#include <linux/delay.h>
-
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/time.h>
-#include <asm/delay.h>
-#include <asm/mpc52xx.h>
-#include <asm/mpc52xx_psc.h>
-
-#include "mpc5200_dma.h"
-#include "mpc5200_psc_ac97.h"
-
-#define DRV_NAME "mpc5200-psc-ac97"
-
-/* ALSA only supports a single AC97 device so static is recommend here */
-static struct psc_dma *psc_dma;
-
-static unsigned short psc_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
-{
- int status;
- unsigned int val;
-
- mutex_lock(&psc_dma->mutex);
-
- /* Wait for command send status zero = ready */
- status = spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) &
- MPC52xx_PSC_SR_CMDSEND), 100, 0);
- if (status == 0) {
- pr_err("timeout on ac97 bus (rdy)\n");
- mutex_unlock(&psc_dma->mutex);
- return -ENODEV;
- }
-
- /* Force clear the data valid bit */
- in_be32(&psc_dma->psc_regs->ac97_data);
-
- /* Send the read */
- out_be32(&psc_dma->psc_regs->ac97_cmd, (1<<31) | ((reg & 0x7f) << 24));
-
- /* Wait for the answer */
- status = spin_event_timeout((in_be16(&psc_dma->psc_regs->sr_csr.status) &
- MPC52xx_PSC_SR_DATA_VAL), 100, 0);
- if (status == 0) {
- pr_err("timeout on ac97 read (val) %x\n",
- in_be16(&psc_dma->psc_regs->sr_csr.status));
- mutex_unlock(&psc_dma->mutex);
- return -ENODEV;
- }
- /* Get the data */
- val = in_be32(&psc_dma->psc_regs->ac97_data);
- if (((val >> 24) & 0x7f) != reg) {
- pr_err("reg echo error on ac97 read\n");
- mutex_unlock(&psc_dma->mutex);
- return -ENODEV;
- }
- val = (val >> 8) & 0xffff;
-
- mutex_unlock(&psc_dma->mutex);
- return (unsigned short) val;
-}
-
-static void psc_ac97_write(struct snd_ac97 *ac97,
- unsigned short reg, unsigned short val)
-{
- int status;
-
- mutex_lock(&psc_dma->mutex);
-
- /* Wait for command status zero = ready */
- status = spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) &
- MPC52xx_PSC_SR_CMDSEND), 100, 0);
- if (status == 0) {
- pr_err("timeout on ac97 bus (write)\n");
- goto out;
- }
- /* Write data */
- out_be32(&psc_dma->psc_regs->ac97_cmd,
- ((reg & 0x7f) << 24) | (val << 8));
-
- out:
- mutex_unlock(&psc_dma->mutex);
-}
-
-static void psc_ac97_warm_reset(struct snd_ac97 *ac97)
-{
- struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
-
- mutex_lock(&psc_dma->mutex);
-
- out_be32(&regs->sicr, psc_dma->sicr | MPC52xx_PSC_SICR_AWR);
- udelay(3);
- out_be32(&regs->sicr, psc_dma->sicr);
-
- mutex_unlock(&psc_dma->mutex);
-}
-
-static void psc_ac97_cold_reset(struct snd_ac97 *ac97)
-{
- struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
-
- mutex_lock(&psc_dma->mutex);
- dev_dbg(psc_dma->dev, "cold reset\n");
-
- mpc5200_psc_ac97_gpio_reset(psc_dma->id);
-
- /* Notify the PSC that a reset has occurred */
- out_be32(&regs->sicr, psc_dma->sicr | MPC52xx_PSC_SICR_ACRB);
-
- /* Re-enable RX and TX */
- out_8(&regs->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
-
- mutex_unlock(&psc_dma->mutex);
-
- msleep(1);
- psc_ac97_warm_reset(ac97);
-}
-
-struct snd_ac97_bus_ops soc_ac97_ops = {
- .read = psc_ac97_read,
- .write = psc_ac97_write,
- .reset = psc_ac97_cold_reset,
- .warm_reset = psc_ac97_warm_reset,
-};
-EXPORT_SYMBOL_GPL(soc_ac97_ops);
-
-static int psc_ac97_hw_analog_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *cpu_dai)
-{
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(cpu_dai);
- struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma);
-
- dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i"
- " periods=%i buffer_size=%i buffer_bytes=%i channels=%i"
- " rate=%i format=%i\n",
- __func__, substream, params_period_size(params),
- params_period_bytes(params), params_periods(params),
- params_buffer_size(params), params_buffer_bytes(params),
- params_channels(params), params_rate(params),
- params_format(params));
-
- /* Determine the set of enable bits to turn on */
- s->ac97_slot_bits = (params_channels(params) == 1) ? 0x100 : 0x300;
- if (substream->pstr->stream != SNDRV_PCM_STREAM_CAPTURE)
- s->ac97_slot_bits <<= 16;
- return 0;
-}
-
-static int psc_ac97_hw_digital_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *cpu_dai)
-{
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(cpu_dai);
-
- dev_dbg(psc_dma->dev, "%s(substream=%p)\n", __func__, substream);
-
- if (params_channels(params) == 1)
- out_be32(&psc_dma->psc_regs->ac97_slots, 0x01000000);
- else
- out_be32(&psc_dma->psc_regs->ac97_slots, 0x03000000);
-
- return 0;
-}
-
-static int psc_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(dai);
- struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- dev_dbg(psc_dma->dev, "AC97 START: stream=%i\n",
- substream->pstr->stream);
-
- /* Set the slot enable bits */
- psc_dma->slots |= s->ac97_slot_bits;
- out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots);
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- dev_dbg(psc_dma->dev, "AC97 STOP: stream=%i\n",
- substream->pstr->stream);
-
- /* Clear the slot enable bits */
- psc_dma->slots &= ~(s->ac97_slot_bits);
- out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots);
- break;
- }
- return 0;
-}
-
-static int psc_ac97_probe(struct snd_soc_dai *cpu_dai)
-{
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(cpu_dai);
- struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
-
- /* Go */
- out_8(&regs->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
- return 0;
-}
-
-/* ---------------------------------------------------------------------
- * ALSA SoC Bindings
- *
- * - Digital Audio Interface (DAI) template
- * - create/destroy dai hooks
- */
-
-/**
- * psc_ac97_dai_template: template CPU Digital Audio Interface
- */
-static const struct snd_soc_dai_ops psc_ac97_analog_ops = {
- .hw_params = psc_ac97_hw_analog_params,
- .trigger = psc_ac97_trigger,
-};
-
-static const struct snd_soc_dai_ops psc_ac97_digital_ops = {
- .hw_params = psc_ac97_hw_digital_params,
-};
-
-static struct snd_soc_dai_driver psc_ac97_dai[] = {
-{
- .ac97_control = 1,
- .probe = psc_ac97_probe,
- .playback = {
- .channels_min = 1,
- .channels_max = 6,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S32_BE,
- },
- .capture = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S32_BE,
- },
- .ops = &psc_ac97_analog_ops,
-},
-{
- .ac97_control = 1,
- .playback = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_32000 | \
- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE,
- },
- .ops = &psc_ac97_digital_ops,
-} };
-
-
-
-/* ---------------------------------------------------------------------
- * OF platform bus binding code:
- * - Probe/remove operations
- * - OF device match table
- */
-static int __devinit psc_ac97_of_probe(struct platform_device *op)
-{
- int rc;
- struct snd_ac97 ac97;
- struct mpc52xx_psc __iomem *regs;
-
- rc = snd_soc_register_dais(&op->dev, psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai));
- if (rc != 0) {
- dev_err(&op->dev, "Failed to register DAI\n");
- return rc;
- }
-
- psc_dma = dev_get_drvdata(&op->dev);
- regs = psc_dma->psc_regs;
- ac97.private_data = psc_dma;
-
- psc_dma->imr = 0;
- out_be16(&psc_dma->psc_regs->isr_imr.imr, psc_dma->imr);
-
- /* Configure the serial interface mode to AC97 */
- psc_dma->sicr = MPC52xx_PSC_SICR_SIM_AC97 | MPC52xx_PSC_SICR_ENAC97;
- out_be32(&regs->sicr, psc_dma->sicr);
-
- /* No slots active */
- out_be32(&regs->ac97_slots, 0x00000000);
-
- return 0;
-}
-
-static int __devexit psc_ac97_of_remove(struct platform_device *op)
-{
- snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_ac97_dai));
- return 0;
-}
-
-/* Match table for of_platform binding */
-static struct of_device_id psc_ac97_match[] __devinitdata = {
- { .compatible = "fsl,mpc5200-psc-ac97", },
- { .compatible = "fsl,mpc5200b-psc-ac97", },
- {}
-};
-MODULE_DEVICE_TABLE(of, psc_ac97_match);
-
-static struct platform_driver psc_ac97_driver = {
- .probe = psc_ac97_of_probe,
- .remove = __devexit_p(psc_ac97_of_remove),
- .driver = {
- .name = "mpc5200-psc-ac97",
- .owner = THIS_MODULE,
- .of_match_table = psc_ac97_match,
- },
-};
-
-module_platform_driver(psc_ac97_driver);
-
-MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
-MODULE_DESCRIPTION("mpc5200 AC97 module");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_ac97.h b/ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_ac97.h
deleted file mode 100644
index e881e784..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_ac97.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Freescale MPC5200 PSC in AC97 mode
- * ALSA SoC Digital Audio Interface (DAI) driver
- *
- */
-
-#ifndef __SOUND_SOC_FSL_MPC52xx_PSC_AC97_H__
-#define __SOUND_SOC_FSL_MPC52xx_PSC_AC97_H__
-
-#define MPC5200_AC97_NORMAL 0
-#define MPC5200_AC97_SPDIF 1
-
-#endif /* __SOUND_SOC_FSL_MPC52xx_PSC_AC97_H__ */
diff --git a/ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_i2s.c b/ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_i2s.c
deleted file mode 100644
index 7b530327..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_i2s.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Freescale MPC5200 PSC in I2S mode
- * ALSA SoC Digital Audio Interface (DAI) driver
- *
- * Copyright (C) 2008 Secret Lab Technologies Ltd.
- * Copyright (C) 2009 Jon Smirl, Digispeaker
- */
-
-#include <linux/module.h>
-#include <linux/of_device.h>
-#include <linux/of_platform.h>
-
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/mpc52xx_psc.h>
-
-#include "mpc5200_dma.h"
-
-/**
- * PSC_I2S_RATES: sample rates supported by the I2S
- *
- * This driver currently only supports the PSC running in I2S slave mode,
- * which means the codec determines the sample rate. Therefore, we tell
- * ALSA that we support all rates and let the codec driver decide what rates
- * are really supported.
- */
-#define PSC_I2S_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \
- SNDRV_PCM_RATE_CONTINUOUS)
-
-/**
- * PSC_I2S_FORMATS: audio formats supported by the PSC I2S mode
- */
-#define PSC_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | \
- SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE)
-
-static int psc_i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
- u32 mode;
-
- dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i"
- " periods=%i buffer_size=%i buffer_bytes=%i\n",
- __func__, substream, params_period_size(params),
- params_period_bytes(params), params_periods(params),
- params_buffer_size(params), params_buffer_bytes(params));
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S8:
- mode = MPC52xx_PSC_SICR_SIM_CODEC_8;
- break;
- case SNDRV_PCM_FORMAT_S16_BE:
- mode = MPC52xx_PSC_SICR_SIM_CODEC_16;
- break;
- case SNDRV_PCM_FORMAT_S24_BE:
- mode = MPC52xx_PSC_SICR_SIM_CODEC_24;
- break;
- case SNDRV_PCM_FORMAT_S32_BE:
- mode = MPC52xx_PSC_SICR_SIM_CODEC_32;
- break;
- default:
- dev_dbg(psc_dma->dev, "invalid format\n");
- return -EINVAL;
- }
- out_be32(&psc_dma->psc_regs->sicr, psc_dma->sicr | mode);
-
- return 0;
-}
-
-/**
- * psc_i2s_set_sysclk: set the clock frequency and direction
- *
- * This function is called by the machine driver to tell us what the clock
- * frequency and direction are.
- *
- * Currently, we only support operating as a clock slave (SND_SOC_CLOCK_IN),
- * and we don't care about the frequency. Return an error if the direction
- * is not SND_SOC_CLOCK_IN.
- *
- * @clk_id: reserved, should be zero
- * @freq: the frequency of the given clock ID, currently ignored
- * @dir: SND_SOC_CLOCK_IN (clock slave) or SND_SOC_CLOCK_OUT (clock master)
- */
-static int psc_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(cpu_dai);
- dev_dbg(psc_dma->dev, "psc_i2s_set_sysclk(cpu_dai=%p, dir=%i)\n",
- cpu_dai, dir);
- return (dir == SND_SOC_CLOCK_IN) ? 0 : -EINVAL;
-}
-
-/**
- * psc_i2s_set_fmt: set the serial format.
- *
- * This function is called by the machine driver to tell us what serial
- * format to use.
- *
- * This driver only supports I2S mode. Return an error if the format is
- * not SND_SOC_DAIFMT_I2S.
- *
- * @format: one of SND_SOC_DAIFMT_xxx
- */
-static int psc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format)
-{
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(cpu_dai);
- dev_dbg(psc_dma->dev, "psc_i2s_set_fmt(cpu_dai=%p, format=%i)\n",
- cpu_dai, format);
- return (format == SND_SOC_DAIFMT_I2S) ? 0 : -EINVAL;
-}
-
-/* ---------------------------------------------------------------------
- * ALSA SoC Bindings
- *
- * - Digital Audio Interface (DAI) template
- * - create/destroy dai hooks
- */
-
-/**
- * psc_i2s_dai_template: template CPU Digital Audio Interface
- */
-static const struct snd_soc_dai_ops psc_i2s_dai_ops = {
- .hw_params = psc_i2s_hw_params,
- .set_sysclk = psc_i2s_set_sysclk,
- .set_fmt = psc_i2s_set_fmt,
-};
-
-static struct snd_soc_dai_driver psc_i2s_dai[] = {{
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = PSC_I2S_RATES,
- .formats = PSC_I2S_FORMATS,
- },
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = PSC_I2S_RATES,
- .formats = PSC_I2S_FORMATS,
- },
- .ops = &psc_i2s_dai_ops,
-} };
-
-/* ---------------------------------------------------------------------
- * OF platform bus binding code:
- * - Probe/remove operations
- * - OF device match table
- */
-static int __devinit psc_i2s_of_probe(struct platform_device *op)
-{
- int rc;
- struct psc_dma *psc_dma;
- struct mpc52xx_psc __iomem *regs;
-
- rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai));
- if (rc != 0) {
- pr_err("Failed to register DAI\n");
- return rc;
- }
-
- psc_dma = dev_get_drvdata(&op->dev);
- regs = psc_dma->psc_regs;
-
- /* Configure the serial interface mode; defaulting to CODEC8 mode */
- psc_dma->sicr = MPC52xx_PSC_SICR_DTS1 | MPC52xx_PSC_SICR_I2S |
- MPC52xx_PSC_SICR_CLKPOL;
- out_be32(&psc_dma->psc_regs->sicr,
- psc_dma->sicr | MPC52xx_PSC_SICR_SIM_CODEC_8);
-
- /* Check for the codec handle. If it is not present then we
- * are done */
- if (!of_get_property(op->dev.of_node, "codec-handle", NULL))
- return 0;
-
- /* Due to errata in the dma mode; need to line up enabling
- * the transmitter with a transition on the frame sync
- * line */
-
- /* first make sure it is low */
- while ((in_8(&regs->ipcr_acr.ipcr) & 0x80) != 0)
- ;
- /* then wait for the transition to high */
- while ((in_8(&regs->ipcr_acr.ipcr) & 0x80) == 0)
- ;
- /* Finally, enable the PSC.
- * Receiver must always be enabled; even when we only want
- * transmit. (see 15.3.2.3 of MPC5200B User's Guide) */
-
- /* Go */
- out_8(&psc_dma->psc_regs->command,
- MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
-
- return 0;
-
-}
-
-static int __devexit psc_i2s_of_remove(struct platform_device *op)
-{
- snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_i2s_dai));
- return 0;
-}
-
-/* Match table for of_platform binding */
-static struct of_device_id psc_i2s_match[] __devinitdata = {
- { .compatible = "fsl,mpc5200-psc-i2s", },
- { .compatible = "fsl,mpc5200b-psc-i2s", },
- {}
-};
-MODULE_DEVICE_TABLE(of, psc_i2s_match);
-
-static struct platform_driver psc_i2s_driver = {
- .probe = psc_i2s_of_probe,
- .remove = __devexit_p(psc_i2s_of_remove),
- .driver = {
- .name = "mpc5200-psc-i2s",
- .owner = THIS_MODULE,
- .of_match_table = psc_i2s_match,
- },
-};
-
-module_platform_driver(psc_i2s_driver);
-
-MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
-MODULE_DESCRIPTION("Freescale MPC5200 PSC in I2S mode ASoC Driver");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/soc/fsl/mpc8610_hpcd.c b/ANDROID_3.4.5/sound/soc/fsl/mpc8610_hpcd.c
deleted file mode 100644
index 3fea5a15..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/mpc8610_hpcd.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/**
- * Freescale MPC8610HPCD ALSA SoC Machine driver
- *
- * Author: Timur Tabi <timur@freescale.com>
- *
- * Copyright 2007-2010 Freescale Semiconductor, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/of_device.h>
-#include <linux/slab.h>
-#include <linux/of_i2c.h>
-#include <sound/soc.h>
-#include <asm/fsl_guts.h>
-
-#include "fsl_dma.h"
-#include "fsl_ssi.h"
-
-/* There's only one global utilities register */
-static phys_addr_t guts_phys;
-
-#define DAI_NAME_SIZE 32
-
-/**
- * mpc8610_hpcd_data: machine-specific ASoC device data
- *
- * This structure contains data for a single sound platform device on an
- * MPC8610 HPCD. Some of the data is taken from the device tree.
- */
-struct mpc8610_hpcd_data {
- struct snd_soc_dai_link dai[2];
- struct snd_soc_card card;
- unsigned int dai_format;
- unsigned int codec_clk_direction;
- unsigned int cpu_clk_direction;
- unsigned int clk_frequency;
- unsigned int ssi_id; /* 0 = SSI1, 1 = SSI2, etc */
- unsigned int dma_id[2]; /* 0 = DMA1, 1 = DMA2, etc */
- unsigned int dma_channel_id[2]; /* 0 = ch 0, 1 = ch 1, etc*/
- char codec_dai_name[DAI_NAME_SIZE];
- char codec_name[DAI_NAME_SIZE];
- char platform_name[2][DAI_NAME_SIZE]; /* One for each DMA channel */
-};
-
-/**
- * mpc8610_hpcd_machine_probe: initialize the board
- *
- * This function is used to initialize the board-specific hardware.
- *
- * Here we program the DMACR and PMUXCR registers.
- */
-static int mpc8610_hpcd_machine_probe(struct snd_soc_card *card)
-{
- struct mpc8610_hpcd_data *machine_data =
- container_of(card, struct mpc8610_hpcd_data, card);
- struct ccsr_guts __iomem *guts;
-
- guts = ioremap(guts_phys, sizeof(struct ccsr_guts));
- if (!guts) {
- dev_err(card->dev, "could not map global utilities\n");
- return -ENOMEM;
- }
-
- /* Program the signal routing between the SSI and the DMA */
- guts_set_dmacr(guts, machine_data->dma_id[0],
- machine_data->dma_channel_id[0],
- CCSR_GUTS_DMACR_DEV_SSI);
- guts_set_dmacr(guts, machine_data->dma_id[1],
- machine_data->dma_channel_id[1],
- CCSR_GUTS_DMACR_DEV_SSI);
-
- guts_set_pmuxcr_dma(guts, machine_data->dma_id[0],
- machine_data->dma_channel_id[0], 0);
- guts_set_pmuxcr_dma(guts, machine_data->dma_id[1],
- machine_data->dma_channel_id[1], 0);
-
- switch (machine_data->ssi_id) {
- case 0:
- clrsetbits_be32(&guts->pmuxcr,
- CCSR_GUTS_PMUXCR_SSI1_MASK, CCSR_GUTS_PMUXCR_SSI1_SSI);
- break;
- case 1:
- clrsetbits_be32(&guts->pmuxcr,
- CCSR_GUTS_PMUXCR_SSI2_MASK, CCSR_GUTS_PMUXCR_SSI2_SSI);
- break;
- }
-
- iounmap(guts);
-
- return 0;
-}
-
-/**
- * mpc8610_hpcd_startup: program the board with various hardware parameters
- *
- * This function takes board-specific information, like clock frequencies
- * and serial data formats, and passes that information to the codec and
- * transport drivers.
- */
-static int mpc8610_hpcd_startup(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct mpc8610_hpcd_data *machine_data =
- container_of(rtd->card, struct mpc8610_hpcd_data, card);
- struct device *dev = rtd->card->dev;
- int ret = 0;
-
- /* Tell the codec driver what the serial protocol is. */
- ret = snd_soc_dai_set_fmt(rtd->codec_dai, machine_data->dai_format);
- if (ret < 0) {
- dev_err(dev, "could not set codec driver audio format\n");
- return ret;
- }
-
- /*
- * Tell the codec driver what the MCLK frequency is, and whether it's
- * a slave or master.
- */
- ret = snd_soc_dai_set_sysclk(rtd->codec_dai, 0,
- machine_data->clk_frequency,
- machine_data->codec_clk_direction);
- if (ret < 0) {
- dev_err(dev, "could not set codec driver clock params\n");
- return ret;
- }
-
- return 0;
-}
-
-/**
- * mpc8610_hpcd_machine_remove: Remove the sound device
- *
- * This function is called to remove the sound device for one SSI. We
- * de-program the DMACR and PMUXCR register.
- */
-static int mpc8610_hpcd_machine_remove(struct snd_soc_card *card)
-{
- struct mpc8610_hpcd_data *machine_data =
- container_of(card, struct mpc8610_hpcd_data, card);
- struct ccsr_guts __iomem *guts;
-
- guts = ioremap(guts_phys, sizeof(struct ccsr_guts));
- if (!guts) {
- dev_err(card->dev, "could not map global utilities\n");
- return -ENOMEM;
- }
-
- /* Restore the signal routing */
-
- guts_set_dmacr(guts, machine_data->dma_id[0],
- machine_data->dma_channel_id[0], 0);
- guts_set_dmacr(guts, machine_data->dma_id[1],
- machine_data->dma_channel_id[1], 0);
-
- switch (machine_data->ssi_id) {
- case 0:
- clrsetbits_be32(&guts->pmuxcr,
- CCSR_GUTS_PMUXCR_SSI1_MASK, CCSR_GUTS_PMUXCR_SSI1_LA);
- break;
- case 1:
- clrsetbits_be32(&guts->pmuxcr,
- CCSR_GUTS_PMUXCR_SSI2_MASK, CCSR_GUTS_PMUXCR_SSI2_LA);
- break;
- }
-
- iounmap(guts);
-
- return 0;
-}
-
-/**
- * mpc8610_hpcd_ops: ASoC machine driver operations
- */
-static struct snd_soc_ops mpc8610_hpcd_ops = {
- .startup = mpc8610_hpcd_startup,
-};
-
-/**
- * get_node_by_phandle_name - get a node by its phandle name
- *
- * This function takes a node, the name of a property in that node, and a
- * compatible string. Assuming the property is a phandle to another node,
- * it returns that node, (optionally) if that node is compatible.
- *
- * If the property is not a phandle, or the node it points to is not compatible
- * with the specific string, then NULL is returned.
- */
-static struct device_node *get_node_by_phandle_name(struct device_node *np,
- const char *name,
- const char *compatible)
-{
- const phandle *ph;
- int len;
-
- ph = of_get_property(np, name, &len);
- if (!ph || (len != sizeof(phandle)))
- return NULL;
-
- np = of_find_node_by_phandle(*ph);
- if (!np)
- return NULL;
-
- if (compatible && !of_device_is_compatible(np, compatible)) {
- of_node_put(np);
- return NULL;
- }
-
- return np;
-}
-
-/**
- * get_parent_cell_index -- return the cell-index of the parent of a node
- *
- * Return the value of the cell-index property of the parent of the given
- * node. This is used for DMA channel nodes that need to know the DMA ID
- * of the controller they are on.
- */
-static int get_parent_cell_index(struct device_node *np)
-{
- struct device_node *parent = of_get_parent(np);
- const u32 *iprop;
-
- if (!parent)
- return -1;
-
- iprop = of_get_property(parent, "cell-index", NULL);
- of_node_put(parent);
-
- if (!iprop)
- return -1;
-
- return be32_to_cpup(iprop);
-}
-
-/**
- * codec_node_dev_name - determine the dev_name for a codec node
- *
- * This function determines the dev_name for an I2C node. This is the name
- * that would be returned by dev_name() if this device_node were part of a
- * 'struct device' It's ugly and hackish, but it works.
- *
- * The dev_name for such devices include the bus number and I2C address. For
- * example, "cs4270.0-004f".
- */
-static int codec_node_dev_name(struct device_node *np, char *buf, size_t len)
-{
- const u32 *iprop;
- int addr;
- char temp[DAI_NAME_SIZE];
- struct i2c_client *i2c;
-
- of_modalias_node(np, temp, DAI_NAME_SIZE);
-
- iprop = of_get_property(np, "reg", NULL);
- if (!iprop)
- return -EINVAL;
-
- addr = be32_to_cpup(iprop);
-
- /* We need the adapter number */
- i2c = of_find_i2c_device_by_node(np);
- if (!i2c)
- return -ENODEV;
-
- snprintf(buf, len, "%s.%u-%04x", temp, i2c->adapter->nr, addr);
-
- return 0;
-}
-
-static int get_dma_channel(struct device_node *ssi_np,
- const char *name,
- struct snd_soc_dai_link *dai,
- unsigned int *dma_channel_id,
- unsigned int *dma_id)
-{
- struct resource res;
- struct device_node *dma_channel_np;
- const u32 *iprop;
- int ret;
-
- dma_channel_np = get_node_by_phandle_name(ssi_np, name,
- "fsl,ssi-dma-channel");
- if (!dma_channel_np)
- return -EINVAL;
-
- /* Determine the dev_name for the device_node. This code mimics the
- * behavior of of_device_make_bus_id(). We need this because ASoC uses
- * the dev_name() of the device to match the platform (DMA) device with
- * the CPU (SSI) device. It's all ugly and hackish, but it works (for
- * now).
- *
- * dai->platform name should already point to an allocated buffer.
- */
- ret = of_address_to_resource(dma_channel_np, 0, &res);
- if (ret)
- return ret;
- snprintf((char *)dai->platform_name, DAI_NAME_SIZE, "%llx.%s",
- (unsigned long long) res.start, dma_channel_np->name);
-
- iprop = of_get_property(dma_channel_np, "cell-index", NULL);
- if (!iprop) {
- of_node_put(dma_channel_np);
- return -EINVAL;
- }
-
- *dma_channel_id = be32_to_cpup(iprop);
- *dma_id = get_parent_cell_index(dma_channel_np);
- of_node_put(dma_channel_np);
-
- return 0;
-}
-
-/**
- * mpc8610_hpcd_probe: platform probe function for the machine driver
- *
- * Although this is a machine driver, the SSI node is the "master" node with
- * respect to audio hardware connections. Therefore, we create a new ASoC
- * device for each new SSI node that has a codec attached.
- */
-static int mpc8610_hpcd_probe(struct platform_device *pdev)
-{
- struct device *dev = pdev->dev.parent;
- /* ssi_pdev is the platform device for the SSI node that probed us */
- struct platform_device *ssi_pdev =
- container_of(dev, struct platform_device, dev);
- struct device_node *np = ssi_pdev->dev.of_node;
- struct device_node *codec_np = NULL;
- struct platform_device *sound_device = NULL;
- struct mpc8610_hpcd_data *machine_data;
- int ret = -ENODEV;
- const char *sprop;
- const u32 *iprop;
-
- /* Find the codec node for this SSI. */
- codec_np = of_parse_phandle(np, "codec-handle", 0);
- if (!codec_np) {
- dev_err(dev, "invalid codec node\n");
- return -EINVAL;
- }
-
- machine_data = kzalloc(sizeof(struct mpc8610_hpcd_data), GFP_KERNEL);
- if (!machine_data) {
- ret = -ENOMEM;
- goto error_alloc;
- }
-
- machine_data->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev);
- machine_data->dai[0].ops = &mpc8610_hpcd_ops;
-
- /* Determine the codec name, it will be used as the codec DAI name */
- ret = codec_node_dev_name(codec_np, machine_data->codec_name,
- DAI_NAME_SIZE);
- if (ret) {
- dev_err(&pdev->dev, "invalid codec node %s\n",
- codec_np->full_name);
- ret = -EINVAL;
- goto error;
- }
- machine_data->dai[0].codec_name = machine_data->codec_name;
-
- /* The DAI name from the codec (snd_soc_dai_driver.name) */
- machine_data->dai[0].codec_dai_name = "cs4270-hifi";
-
- /* We register two DAIs per SSI, one for playback and the other for
- * capture. Currently, we only support codecs that have one DAI for
- * both playback and capture.
- */
- memcpy(&machine_data->dai[1], &machine_data->dai[0],
- sizeof(struct snd_soc_dai_link));
-
- /* Get the device ID */
- iprop = of_get_property(np, "cell-index", NULL);
- if (!iprop) {
- dev_err(&pdev->dev, "cell-index property not found\n");
- ret = -EINVAL;
- goto error;
- }
- machine_data->ssi_id = be32_to_cpup(iprop);
-
- /* Get the serial format and clock direction. */
- sprop = of_get_property(np, "fsl,mode", NULL);
- if (!sprop) {
- dev_err(&pdev->dev, "fsl,mode property not found\n");
- ret = -EINVAL;
- goto error;
- }
-
- if (strcasecmp(sprop, "i2s-slave") == 0) {
- machine_data->dai_format =
- SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM;
- machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT;
- machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN;
-
- /* In i2s-slave mode, the codec has its own clock source, so we
- * need to get the frequency from the device tree and pass it to
- * the codec driver.
- */
- iprop = of_get_property(codec_np, "clock-frequency", NULL);
- if (!iprop || !*iprop) {
- dev_err(&pdev->dev, "codec bus-frequency "
- "property is missing or invalid\n");
- ret = -EINVAL;
- goto error;
- }
- machine_data->clk_frequency = be32_to_cpup(iprop);
- } else if (strcasecmp(sprop, "i2s-master") == 0) {
- machine_data->dai_format =
- SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS;
- machine_data->codec_clk_direction = SND_SOC_CLOCK_IN;
- machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT;
- } else if (strcasecmp(sprop, "lj-slave") == 0) {
- machine_data->dai_format =
- SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM;
- machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT;
- machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN;
- } else if (strcasecmp(sprop, "lj-master") == 0) {
- machine_data->dai_format =
- SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBS_CFS;
- machine_data->codec_clk_direction = SND_SOC_CLOCK_IN;
- machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT;
- } else if (strcasecmp(sprop, "rj-slave") == 0) {
- machine_data->dai_format =
- SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBM_CFM;
- machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT;
- machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN;
- } else if (strcasecmp(sprop, "rj-master") == 0) {
- machine_data->dai_format =
- SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBS_CFS;
- machine_data->codec_clk_direction = SND_SOC_CLOCK_IN;
- machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT;
- } else if (strcasecmp(sprop, "ac97-slave") == 0) {
- machine_data->dai_format =
- SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBM_CFM;
- machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT;
- machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN;
- } else if (strcasecmp(sprop, "ac97-master") == 0) {
- machine_data->dai_format =
- SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBS_CFS;
- machine_data->codec_clk_direction = SND_SOC_CLOCK_IN;
- machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT;
- } else {
- dev_err(&pdev->dev,
- "unrecognized fsl,mode property '%s'\n", sprop);
- ret = -EINVAL;
- goto error;
- }
-
- if (!machine_data->clk_frequency) {
- dev_err(&pdev->dev, "unknown clock frequency\n");
- ret = -EINVAL;
- goto error;
- }
-
- /* Find the playback DMA channel to use. */
- machine_data->dai[0].platform_name = machine_data->platform_name[0];
- ret = get_dma_channel(np, "fsl,playback-dma", &machine_data->dai[0],
- &machine_data->dma_channel_id[0],
- &machine_data->dma_id[0]);
- if (ret) {
- dev_err(&pdev->dev, "missing/invalid playback DMA phandle\n");
- goto error;
- }
-
- /* Find the capture DMA channel to use. */
- machine_data->dai[1].platform_name = machine_data->platform_name[1];
- ret = get_dma_channel(np, "fsl,capture-dma", &machine_data->dai[1],
- &machine_data->dma_channel_id[1],
- &machine_data->dma_id[1]);
- if (ret) {
- dev_err(&pdev->dev, "missing/invalid capture DMA phandle\n");
- goto error;
- }
-
- /* Initialize our DAI data structure. */
- machine_data->dai[0].stream_name = "playback";
- machine_data->dai[1].stream_name = "capture";
- machine_data->dai[0].name = machine_data->dai[0].stream_name;
- machine_data->dai[1].name = machine_data->dai[1].stream_name;
-
- machine_data->card.probe = mpc8610_hpcd_machine_probe;
- machine_data->card.remove = mpc8610_hpcd_machine_remove;
- machine_data->card.name = pdev->name; /* The platform driver name */
- machine_data->card.num_links = 2;
- machine_data->card.dai_link = machine_data->dai;
-
- /* Allocate a new audio platform device structure */
- sound_device = platform_device_alloc("soc-audio", -1);
- if (!sound_device) {
- dev_err(&pdev->dev, "platform device alloc failed\n");
- ret = -ENOMEM;
- goto error;
- }
-
- /* Associate the card data with the sound device */
- platform_set_drvdata(sound_device, &machine_data->card);
-
- /* Register with ASoC */
- ret = platform_device_add(sound_device);
- if (ret) {
- dev_err(&pdev->dev, "platform device add failed\n");
- goto error_sound;
- }
- dev_set_drvdata(&pdev->dev, sound_device);
-
- of_node_put(codec_np);
-
- return 0;
-
-error_sound:
- platform_device_put(sound_device);
-error:
- kfree(machine_data);
-error_alloc:
- of_node_put(codec_np);
- return ret;
-}
-
-/**
- * mpc8610_hpcd_remove: remove the platform device
- *
- * This function is called when the platform device is removed.
- */
-static int __devexit mpc8610_hpcd_remove(struct platform_device *pdev)
-{
- struct platform_device *sound_device = dev_get_drvdata(&pdev->dev);
- struct snd_soc_card *card = platform_get_drvdata(sound_device);
- struct mpc8610_hpcd_data *machine_data =
- container_of(card, struct mpc8610_hpcd_data, card);
-
- platform_device_unregister(sound_device);
-
- kfree(machine_data);
- sound_device->dev.platform_data = NULL;
-
- dev_set_drvdata(&pdev->dev, NULL);
-
- return 0;
-}
-
-static struct platform_driver mpc8610_hpcd_driver = {
- .probe = mpc8610_hpcd_probe,
- .remove = __devexit_p(mpc8610_hpcd_remove),
- .driver = {
- /* The name must match 'compatible' property in the device tree,
- * in lowercase letters.
- */
- .name = "snd-soc-mpc8610hpcd",
- .owner = THIS_MODULE,
- },
-};
-
-/**
- * mpc8610_hpcd_init: machine driver initialization.
- *
- * This function is called when this module is loaded.
- */
-static int __init mpc8610_hpcd_init(void)
-{
- struct device_node *guts_np;
- struct resource res;
-
- pr_info("Freescale MPC8610 HPCD ALSA SoC machine driver\n");
-
- /* Get the physical address of the global utilities registers */
- guts_np = of_find_compatible_node(NULL, NULL, "fsl,mpc8610-guts");
- if (of_address_to_resource(guts_np, 0, &res)) {
- pr_err("mpc8610-hpcd: missing/invalid global utilities node\n");
- return -EINVAL;
- }
- guts_phys = res.start;
-
- return platform_driver_register(&mpc8610_hpcd_driver);
-}
-
-/**
- * mpc8610_hpcd_exit: machine driver exit
- *
- * This function is called when this driver is unloaded.
- */
-static void __exit mpc8610_hpcd_exit(void)
-{
- platform_driver_unregister(&mpc8610_hpcd_driver);
-}
-
-module_init(mpc8610_hpcd_init);
-module_exit(mpc8610_hpcd_exit);
-
-MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
-MODULE_DESCRIPTION("Freescale MPC8610 HPCD ALSA SoC machine driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/sound/soc/fsl/p1022_ds.c b/ANDROID_3.4.5/sound/soc/fsl/p1022_ds.c
deleted file mode 100644
index 982a1c94..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/p1022_ds.c
+++ /dev/null
@@ -1,601 +0,0 @@
-/**
- * Freescale P1022DS ALSA SoC Machine driver
- *
- * Author: Timur Tabi <timur@freescale.com>
- *
- * Copyright 2010 Freescale Semiconductor, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/of_device.h>
-#include <linux/slab.h>
-#include <linux/of_i2c.h>
-#include <sound/soc.h>
-#include <asm/fsl_guts.h>
-
-#include "fsl_dma.h"
-#include "fsl_ssi.h"
-
-/* P1022-specific PMUXCR and DMUXCR bit definitions */
-
-#define CCSR_GUTS_PMUXCR_UART0_I2C1_MASK 0x0001c000
-#define CCSR_GUTS_PMUXCR_UART0_I2C1_UART0_SSI 0x00010000
-#define CCSR_GUTS_PMUXCR_UART0_I2C1_SSI 0x00018000
-
-#define CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK 0x00000c00
-#define CCSR_GUTS_PMUXCR_SSI_DMA_TDM_SSI 0x00000000
-
-#define CCSR_GUTS_DMUXCR_PAD 1 /* DMA controller/channel set to pad */
-#define CCSR_GUTS_DMUXCR_SSI 2 /* DMA controller/channel set to SSI */
-
-/*
- * Set the DMACR register in the GUTS
- *
- * The DMACR register determines the source of initiated transfers for each
- * channel on each DMA controller. Rather than have a bunch of repetitive
- * macros for the bit patterns, we just have a function that calculates
- * them.
- *
- * guts: Pointer to GUTS structure
- * co: The DMA controller (0 or 1)
- * ch: The channel on the DMA controller (0, 1, 2, or 3)
- * device: The device to set as the target (CCSR_GUTS_DMUXCR_xxx)
- */
-static inline void guts_set_dmuxcr(struct ccsr_guts __iomem *guts,
- unsigned int co, unsigned int ch, unsigned int device)
-{
- unsigned int shift = 16 + (8 * (1 - co) + 2 * (3 - ch));
-
- clrsetbits_be32(&guts->dmuxcr, 3 << shift, device << shift);
-}
-
-/* There's only one global utilities register */
-static phys_addr_t guts_phys;
-
-#define DAI_NAME_SIZE 32
-
-/**
- * machine_data: machine-specific ASoC device data
- *
- * This structure contains data for a single sound platform device on an
- * P1022 DS. Some of the data is taken from the device tree.
- */
-struct machine_data {
- struct snd_soc_dai_link dai[2];
- struct snd_soc_card card;
- unsigned int dai_format;
- unsigned int codec_clk_direction;
- unsigned int cpu_clk_direction;
- unsigned int clk_frequency;
- unsigned int ssi_id; /* 0 = SSI1, 1 = SSI2, etc */
- unsigned int dma_id[2]; /* 0 = DMA1, 1 = DMA2, etc */
- unsigned int dma_channel_id[2]; /* 0 = ch 0, 1 = ch 1, etc*/
- char codec_name[DAI_NAME_SIZE];
- char platform_name[2][DAI_NAME_SIZE]; /* One for each DMA channel */
-};
-
-/**
- * p1022_ds_machine_probe: initialize the board
- *
- * This function is used to initialize the board-specific hardware.
- *
- * Here we program the DMACR and PMUXCR registers.
- */
-static int p1022_ds_machine_probe(struct snd_soc_card *card)
-{
- struct machine_data *mdata =
- container_of(card, struct machine_data, card);
- struct ccsr_guts __iomem *guts;
-
- guts = ioremap(guts_phys, sizeof(struct ccsr_guts));
- if (!guts) {
- dev_err(card->dev, "could not map global utilities\n");
- return -ENOMEM;
- }
-
- /* Enable SSI Tx signal */
- clrsetbits_be32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_UART0_I2C1_MASK,
- CCSR_GUTS_PMUXCR_UART0_I2C1_UART0_SSI);
-
- /* Enable SSI Rx signal */
- clrsetbits_be32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK,
- CCSR_GUTS_PMUXCR_SSI_DMA_TDM_SSI);
-
- /* Enable DMA Channel for SSI */
- guts_set_dmuxcr(guts, mdata->dma_id[0], mdata->dma_channel_id[0],
- CCSR_GUTS_DMUXCR_SSI);
-
- guts_set_dmuxcr(guts, mdata->dma_id[1], mdata->dma_channel_id[1],
- CCSR_GUTS_DMUXCR_SSI);
-
- iounmap(guts);
-
- return 0;
-}
-
-/**
- * p1022_ds_startup: program the board with various hardware parameters
- *
- * This function takes board-specific information, like clock frequencies
- * and serial data formats, and passes that information to the codec and
- * transport drivers.
- */
-static int p1022_ds_startup(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct machine_data *mdata =
- container_of(rtd->card, struct machine_data, card);
- struct device *dev = rtd->card->dev;
- int ret = 0;
-
- /* Tell the codec driver what the serial protocol is. */
- ret = snd_soc_dai_set_fmt(rtd->codec_dai, mdata->dai_format);
- if (ret < 0) {
- dev_err(dev, "could not set codec driver audio format\n");
- return ret;
- }
-
- /*
- * Tell the codec driver what the MCLK frequency is, and whether it's
- * a slave or master.
- */
- ret = snd_soc_dai_set_sysclk(rtd->codec_dai, 0, mdata->clk_frequency,
- mdata->codec_clk_direction);
- if (ret < 0) {
- dev_err(dev, "could not set codec driver clock params\n");
- return ret;
- }
-
- return 0;
-}
-
-/**
- * p1022_ds_machine_remove: Remove the sound device
- *
- * This function is called to remove the sound device for one SSI. We
- * de-program the DMACR and PMUXCR register.
- */
-static int p1022_ds_machine_remove(struct snd_soc_card *card)
-{
- struct machine_data *mdata =
- container_of(card, struct machine_data, card);
- struct ccsr_guts __iomem *guts;
-
- guts = ioremap(guts_phys, sizeof(struct ccsr_guts));
- if (!guts) {
- dev_err(card->dev, "could not map global utilities\n");
- return -ENOMEM;
- }
-
- /* Restore the signal routing */
- clrbits32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_UART0_I2C1_MASK);
- clrbits32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK);
- guts_set_dmuxcr(guts, mdata->dma_id[0], mdata->dma_channel_id[0], 0);
- guts_set_dmuxcr(guts, mdata->dma_id[1], mdata->dma_channel_id[1], 0);
-
- iounmap(guts);
-
- return 0;
-}
-
-/**
- * p1022_ds_ops: ASoC machine driver operations
- */
-static struct snd_soc_ops p1022_ds_ops = {
- .startup = p1022_ds_startup,
-};
-
-/**
- * get_node_by_phandle_name - get a node by its phandle name
- *
- * This function takes a node, the name of a property in that node, and a
- * compatible string. Assuming the property is a phandle to another node,
- * it returns that node, (optionally) if that node is compatible.
- *
- * If the property is not a phandle, or the node it points to is not compatible
- * with the specific string, then NULL is returned.
- */
-static struct device_node *get_node_by_phandle_name(struct device_node *np,
- const char *name, const char *compatible)
-{
- np = of_parse_phandle(np, name, 0);
- if (!np)
- return NULL;
-
- if (!of_device_is_compatible(np, compatible)) {
- of_node_put(np);
- return NULL;
- }
-
- return np;
-}
-
-/**
- * get_parent_cell_index -- return the cell-index of the parent of a node
- *
- * Return the value of the cell-index property of the parent of the given
- * node. This is used for DMA channel nodes that need to know the DMA ID
- * of the controller they are on.
- */
-static int get_parent_cell_index(struct device_node *np)
-{
- struct device_node *parent = of_get_parent(np);
- const u32 *iprop;
- int ret = -1;
-
- if (!parent)
- return -1;
-
- iprop = of_get_property(parent, "cell-index", NULL);
- if (iprop)
- ret = be32_to_cpup(iprop);
-
- of_node_put(parent);
-
- return ret;
-}
-
-/**
- * codec_node_dev_name - determine the dev_name for a codec node
- *
- * This function determines the dev_name for an I2C node. This is the name
- * that would be returned by dev_name() if this device_node were part of a
- * 'struct device' It's ugly and hackish, but it works.
- *
- * The dev_name for such devices include the bus number and I2C address. For
- * example, "cs4270-codec.0-004f".
- */
-static int codec_node_dev_name(struct device_node *np, char *buf, size_t len)
-{
- const u32 *iprop;
- int addr;
- char temp[DAI_NAME_SIZE];
- struct i2c_client *i2c;
-
- of_modalias_node(np, temp, DAI_NAME_SIZE);
-
- iprop = of_get_property(np, "reg", NULL);
- if (!iprop)
- return -EINVAL;
-
- addr = be32_to_cpup(iprop);
-
- /* We need the adapter number */
- i2c = of_find_i2c_device_by_node(np);
- if (!i2c)
- return -ENODEV;
-
- snprintf(buf, len, "%s.%u-%04x", temp, i2c->adapter->nr, addr);
-
- return 0;
-}
-
-static int get_dma_channel(struct device_node *ssi_np,
- const char *name,
- struct snd_soc_dai_link *dai,
- unsigned int *dma_channel_id,
- unsigned int *dma_id)
-{
- struct resource res;
- struct device_node *dma_channel_np;
- const u32 *iprop;
- int ret;
-
- dma_channel_np = get_node_by_phandle_name(ssi_np, name,
- "fsl,ssi-dma-channel");
- if (!dma_channel_np)
- return -EINVAL;
-
- /* Determine the dev_name for the device_node. This code mimics the
- * behavior of of_device_make_bus_id(). We need this because ASoC uses
- * the dev_name() of the device to match the platform (DMA) device with
- * the CPU (SSI) device. It's all ugly and hackish, but it works (for
- * now).
- *
- * dai->platform name should already point to an allocated buffer.
- */
- ret = of_address_to_resource(dma_channel_np, 0, &res);
- if (ret) {
- of_node_put(dma_channel_np);
- return ret;
- }
- snprintf((char *)dai->platform_name, DAI_NAME_SIZE, "%llx.%s",
- (unsigned long long) res.start, dma_channel_np->name);
-
- iprop = of_get_property(dma_channel_np, "cell-index", NULL);
- if (!iprop) {
- of_node_put(dma_channel_np);
- return -EINVAL;
- }
-
- *dma_channel_id = be32_to_cpup(iprop);
- *dma_id = get_parent_cell_index(dma_channel_np);
- of_node_put(dma_channel_np);
-
- return 0;
-}
-
-/**
- * p1022_ds_probe: platform probe function for the machine driver
- *
- * Although this is a machine driver, the SSI node is the "master" node with
- * respect to audio hardware connections. Therefore, we create a new ASoC
- * device for each new SSI node that has a codec attached.
- */
-static int p1022_ds_probe(struct platform_device *pdev)
-{
- struct device *dev = pdev->dev.parent;
- /* ssi_pdev is the platform device for the SSI node that probed us */
- struct platform_device *ssi_pdev =
- container_of(dev, struct platform_device, dev);
- struct device_node *np = ssi_pdev->dev.of_node;
- struct device_node *codec_np = NULL;
- struct platform_device *sound_device = NULL;
- struct machine_data *mdata;
- int ret = -ENODEV;
- const char *sprop;
- const u32 *iprop;
-
- /* Find the codec node for this SSI. */
- codec_np = of_parse_phandle(np, "codec-handle", 0);
- if (!codec_np) {
- dev_err(dev, "could not find codec node\n");
- return -EINVAL;
- }
-
- mdata = kzalloc(sizeof(struct machine_data), GFP_KERNEL);
- if (!mdata) {
- ret = -ENOMEM;
- goto error_put;
- }
-
- mdata->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev);
- mdata->dai[0].ops = &p1022_ds_ops;
-
- /* Determine the codec name, it will be used as the codec DAI name */
- ret = codec_node_dev_name(codec_np, mdata->codec_name, DAI_NAME_SIZE);
- if (ret) {
- dev_err(&pdev->dev, "invalid codec node %s\n",
- codec_np->full_name);
- ret = -EINVAL;
- goto error;
- }
- mdata->dai[0].codec_name = mdata->codec_name;
-
- /* We register two DAIs per SSI, one for playback and the other for
- * capture. We support codecs that have separate DAIs for both playback
- * and capture.
- */
- memcpy(&mdata->dai[1], &mdata->dai[0], sizeof(struct snd_soc_dai_link));
-
- /* The DAI names from the codec (snd_soc_dai_driver.name) */
- mdata->dai[0].codec_dai_name = "wm8776-hifi-playback";
- mdata->dai[1].codec_dai_name = "wm8776-hifi-capture";
-
- /* Get the device ID */
- iprop = of_get_property(np, "cell-index", NULL);
- if (!iprop) {
- dev_err(&pdev->dev, "cell-index property not found\n");
- ret = -EINVAL;
- goto error;
- }
- mdata->ssi_id = be32_to_cpup(iprop);
-
- /* Get the serial format and clock direction. */
- sprop = of_get_property(np, "fsl,mode", NULL);
- if (!sprop) {
- dev_err(&pdev->dev, "fsl,mode property not found\n");
- ret = -EINVAL;
- goto error;
- }
-
- if (strcasecmp(sprop, "i2s-slave") == 0) {
- mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM;
- mdata->codec_clk_direction = SND_SOC_CLOCK_OUT;
- mdata->cpu_clk_direction = SND_SOC_CLOCK_IN;
-
- /* In i2s-slave mode, the codec has its own clock source, so we
- * need to get the frequency from the device tree and pass it to
- * the codec driver.
- */
- iprop = of_get_property(codec_np, "clock-frequency", NULL);
- if (!iprop || !*iprop) {
- dev_err(&pdev->dev, "codec bus-frequency "
- "property is missing or invalid\n");
- ret = -EINVAL;
- goto error;
- }
- mdata->clk_frequency = be32_to_cpup(iprop);
- } else if (strcasecmp(sprop, "i2s-master") == 0) {
- mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS;
- mdata->codec_clk_direction = SND_SOC_CLOCK_IN;
- mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT;
- } else if (strcasecmp(sprop, "lj-slave") == 0) {
- mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM;
- mdata->codec_clk_direction = SND_SOC_CLOCK_OUT;
- mdata->cpu_clk_direction = SND_SOC_CLOCK_IN;
- } else if (strcasecmp(sprop, "lj-master") == 0) {
- mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBS_CFS;
- mdata->codec_clk_direction = SND_SOC_CLOCK_IN;
- mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT;
- } else if (strcasecmp(sprop, "rj-slave") == 0) {
- mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBM_CFM;
- mdata->codec_clk_direction = SND_SOC_CLOCK_OUT;
- mdata->cpu_clk_direction = SND_SOC_CLOCK_IN;
- } else if (strcasecmp(sprop, "rj-master") == 0) {
- mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBS_CFS;
- mdata->codec_clk_direction = SND_SOC_CLOCK_IN;
- mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT;
- } else if (strcasecmp(sprop, "ac97-slave") == 0) {
- mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBM_CFM;
- mdata->codec_clk_direction = SND_SOC_CLOCK_OUT;
- mdata->cpu_clk_direction = SND_SOC_CLOCK_IN;
- } else if (strcasecmp(sprop, "ac97-master") == 0) {
- mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBS_CFS;
- mdata->codec_clk_direction = SND_SOC_CLOCK_IN;
- mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT;
- } else {
- dev_err(&pdev->dev,
- "unrecognized fsl,mode property '%s'\n", sprop);
- ret = -EINVAL;
- goto error;
- }
-
- if (!mdata->clk_frequency) {
- dev_err(&pdev->dev, "unknown clock frequency\n");
- ret = -EINVAL;
- goto error;
- }
-
- /* Find the playback DMA channel to use. */
- mdata->dai[0].platform_name = mdata->platform_name[0];
- ret = get_dma_channel(np, "fsl,playback-dma", &mdata->dai[0],
- &mdata->dma_channel_id[0],
- &mdata->dma_id[0]);
- if (ret) {
- dev_err(&pdev->dev, "missing/invalid playback DMA phandle\n");
- goto error;
- }
-
- /* Find the capture DMA channel to use. */
- mdata->dai[1].platform_name = mdata->platform_name[1];
- ret = get_dma_channel(np, "fsl,capture-dma", &mdata->dai[1],
- &mdata->dma_channel_id[1],
- &mdata->dma_id[1]);
- if (ret) {
- dev_err(&pdev->dev, "missing/invalid capture DMA phandle\n");
- goto error;
- }
-
- /* Initialize our DAI data structure. */
- mdata->dai[0].stream_name = "playback";
- mdata->dai[1].stream_name = "capture";
- mdata->dai[0].name = mdata->dai[0].stream_name;
- mdata->dai[1].name = mdata->dai[1].stream_name;
-
- mdata->card.probe = p1022_ds_machine_probe;
- mdata->card.remove = p1022_ds_machine_remove;
- mdata->card.name = pdev->name; /* The platform driver name */
- mdata->card.num_links = 2;
- mdata->card.dai_link = mdata->dai;
-
- /* Allocate a new audio platform device structure */
- sound_device = platform_device_alloc("soc-audio", -1);
- if (!sound_device) {
- dev_err(&pdev->dev, "platform device alloc failed\n");
- ret = -ENOMEM;
- goto error;
- }
-
- /* Associate the card data with the sound device */
- platform_set_drvdata(sound_device, &mdata->card);
-
- /* Register with ASoC */
- ret = platform_device_add(sound_device);
- if (ret) {
- dev_err(&pdev->dev, "platform device add failed\n");
- goto error;
- }
- dev_set_drvdata(&pdev->dev, sound_device);
-
- of_node_put(codec_np);
-
- return 0;
-
-error:
- if (sound_device)
- platform_device_put(sound_device);
-
- kfree(mdata);
-error_put:
- of_node_put(codec_np);
- return ret;
-}
-
-/**
- * p1022_ds_remove: remove the platform device
- *
- * This function is called when the platform device is removed.
- */
-static int __devexit p1022_ds_remove(struct platform_device *pdev)
-{
- struct platform_device *sound_device = dev_get_drvdata(&pdev->dev);
- struct snd_soc_card *card = platform_get_drvdata(sound_device);
- struct machine_data *mdata =
- container_of(card, struct machine_data, card);
-
- platform_device_unregister(sound_device);
-
- kfree(mdata);
- sound_device->dev.platform_data = NULL;
-
- dev_set_drvdata(&pdev->dev, NULL);
-
- return 0;
-}
-
-static struct platform_driver p1022_ds_driver = {
- .probe = p1022_ds_probe,
- .remove = __devexit_p(p1022_ds_remove),
- .driver = {
- /*
- * The name must match 'compatible' property in the device tree,
- * in lowercase letters.
- */
- .name = "snd-soc-p1022ds",
- .owner = THIS_MODULE,
- },
-};
-
-/**
- * p1022_ds_init: machine driver initialization.
- *
- * This function is called when this module is loaded.
- */
-static int __init p1022_ds_init(void)
-{
- struct device_node *guts_np;
- struct resource res;
-
- /* Get the physical address of the global utilities registers */
- guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts");
- if (of_address_to_resource(guts_np, 0, &res)) {
- pr_err("snd-soc-p1022ds: missing/invalid global utils node\n");
- of_node_put(guts_np);
- return -EINVAL;
- }
- guts_phys = res.start;
- of_node_put(guts_np);
-
- return platform_driver_register(&p1022_ds_driver);
-}
-
-/**
- * p1022_ds_exit: machine driver exit
- *
- * This function is called when this driver is unloaded.
- */
-static void __exit p1022_ds_exit(void)
-{
- platform_driver_unregister(&p1022_ds_driver);
-}
-
-module_init(p1022_ds_init);
-module_exit(p1022_ds_exit);
-
-MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
-MODULE_DESCRIPTION("Freescale P1022 DS ALSA SoC machine driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/sound/soc/fsl/pcm030-audio-fabric.c b/ANDROID_3.4.5/sound/soc/fsl/pcm030-audio-fabric.c
deleted file mode 100644
index b3af55dc..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/pcm030-audio-fabric.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Phytec pcm030 driver for the PSC of the Freescale MPC52xx
- * configured as AC97 interface
- *
- * Copyright 2008 Jon Smirl, Digispeaker
- * Author: Jon Smirl <jonsmirl@gmail.com>
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/of_device.h>
-#include <linux/of_platform.h>
-#include <linux/dma-mapping.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include "mpc5200_dma.h"
-#include "mpc5200_psc_ac97.h"
-#include "../codecs/wm9712.h"
-
-#define DRV_NAME "pcm030-audio-fabric"
-
-static struct snd_soc_dai_link pcm030_fabric_dai[] = {
-{
- .name = "AC97",
- .stream_name = "AC97 Analog",
- .codec_dai_name = "wm9712-hifi",
- .cpu_dai_name = "mpc5200-psc-ac97.0",
- .platform_name = "mpc5200-pcm-audio",
- .codec_name = "wm9712-codec",
-},
-{
- .name = "AC97",
- .stream_name = "AC97 IEC958",
- .codec_dai_name = "wm9712-aux",
- .cpu_dai_name = "mpc5200-psc-ac97.1",
- .platform_name = "mpc5200-pcm-audio",
- .codec_name = "wm9712-codec",
-},
-};
-
-static struct snd_soc_card card = {
- .name = "pcm030",
- .owner = THIS_MODULE,
- .dai_link = pcm030_fabric_dai,
- .num_links = ARRAY_SIZE(pcm030_fabric_dai),
-};
-
-static __init int pcm030_fabric_init(void)
-{
- struct platform_device *pdev;
- int rc;
-
- if (!of_machine_is_compatible("phytec,pcm030"))
- return -ENODEV;
-
- pdev = platform_device_alloc("soc-audio", 1);
- if (!pdev) {
- pr_err("pcm030_fabric_init: platform_device_alloc() failed\n");
- return -ENODEV;
- }
-
- platform_set_drvdata(pdev, &card);
-
- rc = platform_device_add(pdev);
- if (rc) {
- pr_err("pcm030_fabric_init: platform_device_add() failed\n");
- platform_device_put(pdev);
- return -ENODEV;
- }
- return 0;
-}
-
-module_init(pcm030_fabric_init);
-
-
-MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
-MODULE_DESCRIPTION(DRV_NAME ": mpc5200 pcm030 fabric driver");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/soc/imx/Kconfig b/ANDROID_3.4.5/sound/soc/imx/Kconfig
deleted file mode 100644
index 810acaa0..00000000
--- a/ANDROID_3.4.5/sound/soc/imx/Kconfig
+++ /dev/null
@@ -1,79 +0,0 @@
-menuconfig SND_IMX_SOC
- tristate "SoC Audio for Freescale i.MX CPUs"
- depends on ARCH_MXC
- help
- Say Y or M if you want to add support for codecs attached to
- the i.MX SSI interface.
-
-
-if SND_IMX_SOC
-
-config SND_SOC_IMX_SSI
- tristate
-
-config SND_SOC_IMX_PCM
- tristate
-
-config SND_MXC_SOC_FIQ
- tristate
- select FIQ
- select SND_SOC_IMX_PCM
-
-config SND_MXC_SOC_MX2
- select SND_SOC_DMAENGINE_PCM
- tristate
- select SND_SOC_IMX_PCM
-
-config SND_SOC_IMX_AUDMUX
- tristate
-
-config SND_MXC_SOC_WM1133_EV1
- tristate "Audio on the the i.MX31ADS with WM1133-EV1 fitted"
- depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL
- select SND_SOC_WM8350
- select SND_MXC_SOC_FIQ
- select SND_SOC_IMX_AUDMUX
- select SND_SOC_IMX_SSI
- help
- Enable support for audio on the i.MX31ADS with the WM1133-EV1
- PMIC board with WM8835x fitted.
-
-config SND_SOC_MX27VIS_AIC32X4
- tristate "SoC audio support for Visstrim M10 boards"
- depends on MACH_IMX27_VISSTRIM_M10 && I2C
- select SND_SOC_TLV320AIC32X4
- select SND_MXC_SOC_MX2
- select SND_SOC_IMX_AUDMUX
- select SND_SOC_IMX_SSI
- help
- Say Y if you want to add support for SoC audio on Visstrim SM10
- board with TLV320AIC32X4 codec.
-
-config SND_SOC_PHYCORE_AC97
- tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards"
- depends on MACH_PCM043 || MACH_PCA100
- select SND_SOC_AC97_BUS
- select SND_SOC_WM9712
- select SND_MXC_SOC_FIQ
- select SND_SOC_IMX_AUDMUX
- select SND_SOC_IMX_SSI
- help
- Say Y if you want to add support for SoC audio on Phytec phyCORE
- and phyCARD boards in AC97 mode
-
-config SND_SOC_EUKREA_TLV320
- tristate "Eukrea TLV320"
- depends on MACH_EUKREA_MBIMX27_BASEBOARD \
- || MACH_EUKREA_MBIMXSD25_BASEBOARD \
- || MACH_EUKREA_MBIMXSD35_BASEBOARD \
- || MACH_EUKREA_MBIMXSD51_BASEBOARD
- depends on I2C
- select SND_SOC_TLV320AIC23
- select SND_MXC_SOC_FIQ
- select SND_SOC_IMX_AUDMUX
- select SND_SOC_IMX_SSI
- help
- Enable I2S based access to the TLV320AIC23B codec attached
- to the SSI interface
-
-endif # SND_IMX_SOC
diff --git a/ANDROID_3.4.5/sound/soc/imx/Makefile b/ANDROID_3.4.5/sound/soc/imx/Makefile
deleted file mode 100644
index f5db3e92..00000000
--- a/ANDROID_3.4.5/sound/soc/imx/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-# i.MX Platform Support
-snd-soc-imx-ssi-objs := imx-ssi.o
-snd-soc-imx-audmux-objs := imx-audmux.o
-
-obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o
-obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o
-
-obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o
-snd-soc-imx-pcm-y := imx-pcm.o
-snd-soc-imx-pcm-$(CONFIG_SND_MXC_SOC_FIQ) += imx-pcm-fiq.o
-snd-soc-imx-pcm-$(CONFIG_SND_MXC_SOC_MX2) += imx-pcm-dma-mx2.o
-
-# i.MX Machine Support
-snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
-snd-soc-phycore-ac97-objs := phycore-ac97.o
-snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
-snd-soc-wm1133-ev1-objs := wm1133-ev1.o
-
-obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
-obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
-obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
-obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
diff --git a/ANDROID_3.4.5/sound/soc/imx/eukrea-tlv320.c b/ANDROID_3.4.5/sound/soc/imx/eukrea-tlv320.c
deleted file mode 100644
index 7d4475cf..00000000
--- a/ANDROID_3.4.5/sound/soc/imx/eukrea-tlv320.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * eukrea-tlv320.c -- SoC audio for eukrea_cpuimxXX in I2S mode
- *
- * Copyright 2010 Eric Bénard, Eukréa Electromatique <eric@eukrea.com>
- *
- * based on sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
- * which is Copyright 2009 Simtec Electronics
- * and on sound/soc/imx/phycore-ac97.c which is
- * Copyright 2009 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <asm/mach-types.h>
-
-#include "../codecs/tlv320aic23.h"
-#include "imx-ssi.h"
-#include "imx-audmux.h"
-
-#define CODEC_CLOCK 12000000
-
-static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret;
-
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM);
- if (ret) {
- pr_err("%s: failed set cpu dai format\n", __func__);
- return ret;
- }
-
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM);
- if (ret) {
- pr_err("%s: failed set codec dai format\n", __func__);
- return ret;
- }
-
- ret = snd_soc_dai_set_sysclk(codec_dai, 0,
- CODEC_CLOCK, SND_SOC_CLOCK_OUT);
- if (ret) {
- pr_err("%s: failed setting codec sysclk\n", __func__);
- return ret;
- }
- snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffc, 0xffffffc, 2, 0);
-
- ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0,
- SND_SOC_CLOCK_IN);
- if (ret) {
- pr_err("can't set CPU system clock IMX_SSP_SYS_CLK\n");
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_soc_ops eukrea_tlv320_snd_ops = {
- .hw_params = eukrea_tlv320_hw_params,
-};
-
-static struct snd_soc_dai_link eukrea_tlv320_dai = {
- .name = "tlv320aic23",
- .stream_name = "TLV320AIC23",
- .codec_dai_name = "tlv320aic23-hifi",
- .platform_name = "imx-fiq-pcm-audio.0",
- .codec_name = "tlv320aic23-codec.0-001a",
- .cpu_dai_name = "imx-ssi.0",
- .ops = &eukrea_tlv320_snd_ops,
-};
-
-static struct snd_soc_card eukrea_tlv320 = {
- .name = "cpuimx-audio",
- .owner = THIS_MODULE,
- .dai_link = &eukrea_tlv320_dai,
- .num_links = 1,
-};
-
-static struct platform_device *eukrea_tlv320_snd_device;
-
-static int __init eukrea_tlv320_init(void)
-{
- int ret;
- int int_port = 0, ext_port;
-
- if (machine_is_eukrea_cpuimx27()) {
- imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
- IMX_AUDMUX_V1_PCR_SYN |
- IMX_AUDMUX_V1_PCR_TFSDIR |
- IMX_AUDMUX_V1_PCR_TCLKDIR |
- IMX_AUDMUX_V1_PCR_RFSDIR |
- IMX_AUDMUX_V1_PCR_RCLKDIR |
- IMX_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
- IMX_AUDMUX_V1_PCR_RFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
- IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4)
- );
- imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR3_SSI_PINS_4,
- IMX_AUDMUX_V1_PCR_SYN |
- IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
- );
- } else if (machine_is_eukrea_cpuimx25sd() ||
- machine_is_eukrea_cpuimx35sd() ||
- machine_is_eukrea_cpuimx51sd()) {
- ext_port = machine_is_eukrea_cpuimx25sd() ? 4 : 3;
- imx_audmux_v2_configure_port(int_port,
- IMX_AUDMUX_V2_PTCR_SYN |
- IMX_AUDMUX_V2_PTCR_TFSDIR |
- IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) |
- IMX_AUDMUX_V2_PTCR_TCLKDIR |
- IMX_AUDMUX_V2_PTCR_TCSEL(ext_port),
- IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port)
- );
- imx_audmux_v2_configure_port(ext_port,
- IMX_AUDMUX_V2_PTCR_SYN,
- IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)
- );
- } else {
- /* return happy. We might run on a totally different machine */
- return 0;
- }
-
- eukrea_tlv320_snd_device = platform_device_alloc("soc-audio", -1);
- if (!eukrea_tlv320_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(eukrea_tlv320_snd_device, &eukrea_tlv320);
- ret = platform_device_add(eukrea_tlv320_snd_device);
-
- if (ret) {
- printk(KERN_ERR "ASoC: Platform device allocation failed\n");
- platform_device_put(eukrea_tlv320_snd_device);
- }
-
- return ret;
-}
-
-static void __exit eukrea_tlv320_exit(void)
-{
- platform_device_unregister(eukrea_tlv320_snd_device);
-}
-
-module_init(eukrea_tlv320_init);
-module_exit(eukrea_tlv320_exit);
-
-MODULE_AUTHOR("Eric Bénard <eric@eukrea.com>");
-MODULE_DESCRIPTION("CPUIMX ALSA SoC driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/imx/imx-audmux.c b/ANDROID_3.4.5/sound/soc/imx/imx-audmux.c
deleted file mode 100644
index f2370035..00000000
--- a/ANDROID_3.4.5/sound/soc/imx/imx-audmux.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright 2012 Freescale Semiconductor, Inc.
- * Copyright 2012 Linaro Ltd.
- * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
- *
- * Initial development of this code was funded by
- * Phytec Messtechnik GmbH, http://www.phytec.de
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/clk.h>
-#include <linux/debugfs.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include "imx-audmux.h"
-
-#define DRIVER_NAME "imx-audmux"
-
-static struct clk *audmux_clk;
-static void __iomem *audmux_base;
-
-#define IMX_AUDMUX_V2_PTCR(x) ((x) * 8)
-#define IMX_AUDMUX_V2_PDCR(x) ((x) * 8 + 4)
-
-#ifdef CONFIG_DEBUG_FS
-static struct dentry *audmux_debugfs_root;
-
-/* There is an annoying discontinuity in the SSI numbering with regard
- * to the Linux number of the devices */
-static const char *audmux_port_string(int port)
-{
- switch (port) {
- case MX31_AUDMUX_PORT1_SSI0:
- return "imx-ssi.0";
- case MX31_AUDMUX_PORT2_SSI1:
- return "imx-ssi.1";
- case MX31_AUDMUX_PORT3_SSI_PINS_3:
- return "SSI3";
- case MX31_AUDMUX_PORT4_SSI_PINS_4:
- return "SSI4";
- case MX31_AUDMUX_PORT5_SSI_PINS_5:
- return "SSI5";
- case MX31_AUDMUX_PORT6_SSI_PINS_6:
- return "SSI6";
- default:
- return "UNKNOWN";
- }
-}
-
-static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- ssize_t ret;
- char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
- int port = (int)file->private_data;
- u32 pdcr, ptcr;
-
- if (!buf)
- return -ENOMEM;
-
- if (!audmux_base)
- return -ENOSYS;
-
- if (audmux_clk)
- clk_prepare_enable(audmux_clk);
-
- ptcr = readl(audmux_base + IMX_AUDMUX_V2_PTCR(port));
- pdcr = readl(audmux_base + IMX_AUDMUX_V2_PDCR(port));
-
- if (audmux_clk)
- clk_disable_unprepare(audmux_clk);
-
- ret = snprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
- pdcr, ptcr);
-
- if (ptcr & IMX_AUDMUX_V2_PTCR_TFSDIR)
- ret += snprintf(buf + ret, PAGE_SIZE - ret,
- "TxFS output from %s, ",
- audmux_port_string((ptcr >> 27) & 0x7));
- else
- ret += snprintf(buf + ret, PAGE_SIZE - ret,
- "TxFS input, ");
-
- if (ptcr & IMX_AUDMUX_V2_PTCR_TCLKDIR)
- ret += snprintf(buf + ret, PAGE_SIZE - ret,
- "TxClk output from %s",
- audmux_port_string((ptcr >> 22) & 0x7));
- else
- ret += snprintf(buf + ret, PAGE_SIZE - ret,
- "TxClk input");
-
- ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
-
- if (ptcr & IMX_AUDMUX_V2_PTCR_SYN) {
- ret += snprintf(buf + ret, PAGE_SIZE - ret,
- "Port is symmetric");
- } else {
- if (ptcr & IMX_AUDMUX_V2_PTCR_RFSDIR)
- ret += snprintf(buf + ret, PAGE_SIZE - ret,
- "RxFS output from %s, ",
- audmux_port_string((ptcr >> 17) & 0x7));
- else
- ret += snprintf(buf + ret, PAGE_SIZE - ret,
- "RxFS input, ");
-
- if (ptcr & IMX_AUDMUX_V2_PTCR_RCLKDIR)
- ret += snprintf(buf + ret, PAGE_SIZE - ret,
- "RxClk output from %s",
- audmux_port_string((ptcr >> 12) & 0x7));
- else
- ret += snprintf(buf + ret, PAGE_SIZE - ret,
- "RxClk input");
- }
-
- ret += snprintf(buf + ret, PAGE_SIZE - ret,
- "\nData received from %s\n",
- audmux_port_string((pdcr >> 13) & 0x7));
-
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
-
- kfree(buf);
-
- return ret;
-}
-
-static const struct file_operations audmux_debugfs_fops = {
- .open = simple_open,
- .read = audmux_read_file,
- .llseek = default_llseek,
-};
-
-static void __init audmux_debugfs_init(void)
-{
- int i;
- char buf[20];
-
- audmux_debugfs_root = debugfs_create_dir("audmux", NULL);
- if (!audmux_debugfs_root) {
- pr_warning("Failed to create AUDMUX debugfs root\n");
- return;
- }
-
- for (i = 0; i < MX31_AUDMUX_PORT6_SSI_PINS_6 + 1; i++) {
- snprintf(buf, sizeof(buf), "ssi%d", i);
- if (!debugfs_create_file(buf, 0444, audmux_debugfs_root,
- (void *)i, &audmux_debugfs_fops))
- pr_warning("Failed to create AUDMUX port %d debugfs file\n",
- i);
- }
-}
-
-static void __devexit audmux_debugfs_remove(void)
-{
- debugfs_remove_recursive(audmux_debugfs_root);
-}
-#else
-static inline void audmux_debugfs_init(void)
-{
-}
-
-static inline void audmux_debugfs_remove(void)
-{
-}
-#endif
-
-enum imx_audmux_type {
- IMX21_AUDMUX,
- IMX31_AUDMUX,
-} audmux_type;
-
-static struct platform_device_id imx_audmux_ids[] = {
- {
- .name = "imx21-audmux",
- .driver_data = IMX21_AUDMUX,
- }, {
- .name = "imx31-audmux",
- .driver_data = IMX31_AUDMUX,
- }, {
- /* sentinel */
- }
-};
-MODULE_DEVICE_TABLE(platform, imx_audmux_ids);
-
-static const struct of_device_id imx_audmux_dt_ids[] = {
- { .compatible = "fsl,imx21-audmux", .data = &imx_audmux_ids[0], },
- { .compatible = "fsl,imx31-audmux", .data = &imx_audmux_ids[1], },
- { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, imx_audmux_dt_ids);
-
-static const uint8_t port_mapping[] = {
- 0x0, 0x4, 0x8, 0x10, 0x14, 0x1c,
-};
-
-int imx_audmux_v1_configure_port(unsigned int port, unsigned int pcr)
-{
- if (audmux_type != IMX21_AUDMUX)
- return -EINVAL;
-
- if (!audmux_base)
- return -ENOSYS;
-
- if (port >= ARRAY_SIZE(port_mapping))
- return -EINVAL;
-
- writel(pcr, audmux_base + port_mapping[port]);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(imx_audmux_v1_configure_port);
-
-int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
- unsigned int pdcr)
-{
- if (audmux_type != IMX31_AUDMUX)
- return -EINVAL;
-
- if (!audmux_base)
- return -ENOSYS;
-
- if (audmux_clk)
- clk_prepare_enable(audmux_clk);
-
- writel(ptcr, audmux_base + IMX_AUDMUX_V2_PTCR(port));
- writel(pdcr, audmux_base + IMX_AUDMUX_V2_PDCR(port));
-
- if (audmux_clk)
- clk_disable_unprepare(audmux_clk);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port);
-
-static int __devinit imx_audmux_probe(struct platform_device *pdev)
-{
- struct resource *res;
- const struct of_device_id *of_id =
- of_match_device(imx_audmux_dt_ids, &pdev->dev);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- audmux_base = devm_request_and_ioremap(&pdev->dev, res);
- if (!audmux_base)
- return -EADDRNOTAVAIL;
-
- audmux_clk = clk_get(&pdev->dev, "audmux");
- if (IS_ERR(audmux_clk)) {
- dev_dbg(&pdev->dev, "cannot get clock: %ld\n",
- PTR_ERR(audmux_clk));
- audmux_clk = NULL;
- }
-
- if (of_id)
- pdev->id_entry = of_id->data;
- audmux_type = pdev->id_entry->driver_data;
- if (audmux_type == IMX31_AUDMUX)
- audmux_debugfs_init();
-
- return 0;
-}
-
-static int __devexit imx_audmux_remove(struct platform_device *pdev)
-{
- if (audmux_type == IMX31_AUDMUX)
- audmux_debugfs_remove();
- clk_put(audmux_clk);
-
- return 0;
-}
-
-static struct platform_driver imx_audmux_driver = {
- .probe = imx_audmux_probe,
- .remove = __devexit_p(imx_audmux_remove),
- .id_table = imx_audmux_ids,
- .driver = {
- .name = DRIVER_NAME,
- .owner = THIS_MODULE,
- .of_match_table = imx_audmux_dt_ids,
- }
-};
-
-static int __init imx_audmux_init(void)
-{
- return platform_driver_register(&imx_audmux_driver);
-}
-subsys_initcall(imx_audmux_init);
-
-static void __exit imx_audmux_exit(void)
-{
- platform_driver_unregister(&imx_audmux_driver);
-}
-module_exit(imx_audmux_exit);
-
-MODULE_DESCRIPTION("Freescale i.MX AUDMUX driver");
-MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/ANDROID_3.4.5/sound/soc/imx/imx-audmux.h b/ANDROID_3.4.5/sound/soc/imx/imx-audmux.h
deleted file mode 100644
index 04ebbab8..00000000
--- a/ANDROID_3.4.5/sound/soc/imx/imx-audmux.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef __IMX_AUDMUX_H
-#define __IMX_AUDMUX_H
-
-#define MX27_AUDMUX_HPCR1_SSI0 0
-#define MX27_AUDMUX_HPCR2_SSI1 1
-#define MX27_AUDMUX_HPCR3_SSI_PINS_4 2
-#define MX27_AUDMUX_PPCR1_SSI_PINS_1 3
-#define MX27_AUDMUX_PPCR2_SSI_PINS_2 4
-#define MX27_AUDMUX_PPCR3_SSI_PINS_3 5
-
-#define MX31_AUDMUX_PORT1_SSI0 0
-#define MX31_AUDMUX_PORT2_SSI1 1
-#define MX31_AUDMUX_PORT3_SSI_PINS_3 2
-#define MX31_AUDMUX_PORT4_SSI_PINS_4 3
-#define MX31_AUDMUX_PORT5_SSI_PINS_5 4
-#define MX31_AUDMUX_PORT6_SSI_PINS_6 5
-
-#define MX51_AUDMUX_PORT1_SSI0 0
-#define MX51_AUDMUX_PORT2_SSI1 1
-#define MX51_AUDMUX_PORT3 2
-#define MX51_AUDMUX_PORT4 3
-#define MX51_AUDMUX_PORT5 4
-#define MX51_AUDMUX_PORT6 5
-#define MX51_AUDMUX_PORT7 6
-
-/* Register definitions for the i.MX21/27 Digital Audio Multiplexer */
-#define IMX_AUDMUX_V1_PCR_INMMASK(x) ((x) & 0xff)
-#define IMX_AUDMUX_V1_PCR_INMEN (1 << 8)
-#define IMX_AUDMUX_V1_PCR_TXRXEN (1 << 10)
-#define IMX_AUDMUX_V1_PCR_SYN (1 << 12)
-#define IMX_AUDMUX_V1_PCR_RXDSEL(x) (((x) & 0x7) << 13)
-#define IMX_AUDMUX_V1_PCR_RFCSEL(x) (((x) & 0xf) << 20)
-#define IMX_AUDMUX_V1_PCR_RCLKDIR (1 << 24)
-#define IMX_AUDMUX_V1_PCR_RFSDIR (1 << 25)
-#define IMX_AUDMUX_V1_PCR_TFCSEL(x) (((x) & 0xf) << 26)
-#define IMX_AUDMUX_V1_PCR_TCLKDIR (1 << 30)
-#define IMX_AUDMUX_V1_PCR_TFSDIR (1 << 31)
-
-/* Register definitions for the i.MX25/31/35/51 Digital Audio Multiplexer */
-#define IMX_AUDMUX_V2_PTCR_TFSDIR (1 << 31)
-#define IMX_AUDMUX_V2_PTCR_TFSEL(x) (((x) & 0xf) << 27)
-#define IMX_AUDMUX_V2_PTCR_TCLKDIR (1 << 26)
-#define IMX_AUDMUX_V2_PTCR_TCSEL(x) (((x) & 0xf) << 22)
-#define IMX_AUDMUX_V2_PTCR_RFSDIR (1 << 21)
-#define IMX_AUDMUX_V2_PTCR_RFSEL(x) (((x) & 0xf) << 17)
-#define IMX_AUDMUX_V2_PTCR_RCLKDIR (1 << 16)
-#define IMX_AUDMUX_V2_PTCR_RCSEL(x) (((x) & 0xf) << 12)
-#define IMX_AUDMUX_V2_PTCR_SYN (1 << 11)
-
-#define IMX_AUDMUX_V2_PDCR_RXDSEL(x) (((x) & 0x7) << 13)
-#define IMX_AUDMUX_V2_PDCR_TXRXEN (1 << 12)
-#define IMX_AUDMUX_V2_PDCR_MODE(x) (((x) & 0x3) << 8)
-#define IMX_AUDMUX_V2_PDCR_INMMASK(x) ((x) & 0xff)
-
-int imx_audmux_v1_configure_port(unsigned int port, unsigned int pcr);
-
-int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
- unsigned int pdcr);
-
-#endif /* __IMX_AUDMUX_H */
diff --git a/ANDROID_3.4.5/sound/soc/imx/imx-pcm-dma-mx2.c b/ANDROID_3.4.5/sound/soc/imx/imx-pcm-dma-mx2.c
deleted file mode 100644
index 6b818de2..00000000
--- a/ANDROID_3.4.5/sound/soc/imx/imx-pcm-dma-mx2.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * imx-pcm-dma-mx2.c -- ALSA Soc Audio Layer
- *
- * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
- *
- * This code is based on code copyrighted by Freescale,
- * Liam Girdwood, Javier Martin and probably others.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/dmaengine.h>
-#include <linux/types.h>
-
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/dmaengine_pcm.h>
-
-#include <mach/dma.h>
-
-#include "imx-pcm.h"
-
-static bool filter(struct dma_chan *chan, void *param)
-{
- if (!imx_dma_is_general_purpose(chan))
- return false;
-
- chan->private = param;
-
- return true;
-}
-
-static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
- struct imx_pcm_dma_params *dma_params;
- struct dma_slave_config slave_config;
- int ret;
-
- dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
- ret = snd_hwparams_to_dma_slave_config(substream, params, &slave_config);
- if (ret)
- return ret;
-
- slave_config.device_fc = false;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- slave_config.dst_addr = dma_params->dma_addr;
- slave_config.dst_maxburst = dma_params->burstsize;
- } else {
- slave_config.src_addr = dma_params->dma_addr;
- slave_config.src_maxburst = dma_params->burstsize;
- }
-
- ret = dmaengine_slave_config(chan, &slave_config);
- if (ret)
- return ret;
-
- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
-
- return 0;
-}
-
-static struct snd_pcm_hardware snd_imx_hardware = {
- .info = SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rate_min = 8000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
- .period_bytes_min = 128,
- .period_bytes_max = 65535, /* Limited by SDMA engine */
- .periods_min = 2,
- .periods_max = 255,
- .fifo_size = 0,
-};
-
-static int snd_imx_open(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct imx_pcm_dma_params *dma_params;
- struct imx_dma_data *dma_data;
- int ret;
-
- snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
-
- dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
- dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL);
- dma_data->peripheral_type = IMX_DMATYPE_SSI;
- dma_data->priority = DMA_PRIO_HIGH;
- dma_data->dma_request = dma_params->dma;
-
- ret = snd_dmaengine_pcm_open(substream, filter, dma_data);
- if (ret) {
- kfree(dma_data);
- return 0;
- }
-
- snd_dmaengine_pcm_set_data(substream, dma_data);
-
- return 0;
-}
-
-static int snd_imx_close(struct snd_pcm_substream *substream)
-{
- struct imx_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream);
-
- snd_dmaengine_pcm_close(substream);
- kfree(dma_data);
-
- return 0;
-}
-
-static struct snd_pcm_ops imx_pcm_ops = {
- .open = snd_imx_open,
- .close = snd_imx_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_imx_pcm_hw_params,
- .trigger = snd_dmaengine_pcm_trigger,
- .pointer = snd_dmaengine_pcm_pointer,
- .mmap = snd_imx_pcm_mmap,
-};
-
-static struct snd_soc_platform_driver imx_soc_platform_mx2 = {
- .ops = &imx_pcm_ops,
- .pcm_new = imx_pcm_new,
- .pcm_free = imx_pcm_free,
-};
-
-static int __devinit imx_soc_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2);
-}
-
-static int __devexit imx_soc_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver imx_pcm_driver = {
- .driver = {
- .name = "imx-pcm-audio",
- .owner = THIS_MODULE,
- },
- .probe = imx_soc_platform_probe,
- .remove = __devexit_p(imx_soc_platform_remove),
-};
-
-module_platform_driver(imx_pcm_driver);
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:imx-pcm-audio");
diff --git a/ANDROID_3.4.5/sound/soc/imx/imx-pcm-fiq.c b/ANDROID_3.4.5/sound/soc/imx/imx-pcm-fiq.c
deleted file mode 100644
index 456b7d72..00000000
--- a/ANDROID_3.4.5/sound/soc/imx/imx-pcm-fiq.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * imx-pcm-fiq.c -- ALSA Soc Audio Layer
- *
- * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
- *
- * This code is based on code copyrighted by Freescale,
- * Liam Girdwood, Javier Martin and probably others.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/fiq.h>
-
-#include <mach/ssi.h>
-
-#include "imx-ssi.h"
-
-struct imx_pcm_runtime_data {
- int period;
- int periods;
- unsigned long offset;
- unsigned long last_offset;
- unsigned long size;
- struct hrtimer hrt;
- int poll_time_ns;
- struct snd_pcm_substream *substream;
- atomic_t running;
-};
-
-static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
-{
- struct imx_pcm_runtime_data *iprtd =
- container_of(hrt, struct imx_pcm_runtime_data, hrt);
- struct snd_pcm_substream *substream = iprtd->substream;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct pt_regs regs;
- unsigned long delta;
-
- if (!atomic_read(&iprtd->running))
- return HRTIMER_NORESTART;
-
- get_fiq_regs(&regs);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- iprtd->offset = regs.ARM_r8 & 0xffff;
- else
- iprtd->offset = regs.ARM_r9 & 0xffff;
-
- /* How much data have we transferred since the last period report? */
- if (iprtd->offset >= iprtd->last_offset)
- delta = iprtd->offset - iprtd->last_offset;
- else
- delta = runtime->buffer_size + iprtd->offset
- - iprtd->last_offset;
-
- /* If we've transferred at least a period then report it and
- * reset our poll time */
- if (delta >= iprtd->period) {
- snd_pcm_period_elapsed(substream);
- iprtd->last_offset = iprtd->offset;
- }
-
- hrtimer_forward_now(hrt, ns_to_ktime(iprtd->poll_time_ns));
-
- return HRTIMER_RESTART;
-}
-
-static struct fiq_handler fh = {
- .name = DRV_NAME,
-};
-
-static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct imx_pcm_runtime_data *iprtd = runtime->private_data;
-
- iprtd->size = params_buffer_bytes(params);
- iprtd->periods = params_periods(params);
- iprtd->period = params_period_bytes(params) ;
- iprtd->offset = 0;
- iprtd->last_offset = 0;
- iprtd->poll_time_ns = 1000000000 / params_rate(params) *
- params_period_size(params);
- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
-
- return 0;
-}
-
-static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct imx_pcm_runtime_data *iprtd = runtime->private_data;
- struct pt_regs regs;
-
- get_fiq_regs(&regs);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- regs.ARM_r8 = (iprtd->period * iprtd->periods - 1) << 16;
- else
- regs.ARM_r9 = (iprtd->period * iprtd->periods - 1) << 16;
-
- set_fiq_regs(&regs);
-
- return 0;
-}
-
-static int fiq_enable;
-static int imx_pcm_fiq;
-
-static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct imx_pcm_runtime_data *iprtd = runtime->private_data;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- atomic_set(&iprtd->running, 1);
- hrtimer_start(&iprtd->hrt, ns_to_ktime(iprtd->poll_time_ns),
- HRTIMER_MODE_REL);
- if (++fiq_enable == 1)
- enable_fiq(imx_pcm_fiq);
-
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- atomic_set(&iprtd->running, 0);
-
- if (--fiq_enable == 0)
- disable_fiq(imx_pcm_fiq);
-
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct imx_pcm_runtime_data *iprtd = runtime->private_data;
-
- return bytes_to_frames(substream->runtime, iprtd->offset);
-}
-
-static struct snd_pcm_hardware snd_imx_hardware = {
- .info = SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rate_min = 8000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
- .period_bytes_min = 128,
- .period_bytes_max = 16 * 1024,
- .periods_min = 4,
- .periods_max = 255,
- .fifo_size = 0,
-};
-
-static int snd_imx_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct imx_pcm_runtime_data *iprtd;
- int ret;
-
- iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
- if (iprtd == NULL)
- return -ENOMEM;
- runtime->private_data = iprtd;
-
- iprtd->substream = substream;
-
- atomic_set(&iprtd->running, 0);
- hrtimer_init(&iprtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- iprtd->hrt.function = snd_hrtimer_callback;
-
- ret = snd_pcm_hw_constraint_integer(substream->runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (ret < 0) {
- kfree(iprtd);
- return ret;
- }
-
- snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
- return 0;
-}
-
-static int snd_imx_close(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct imx_pcm_runtime_data *iprtd = runtime->private_data;
-
- hrtimer_cancel(&iprtd->hrt);
-
- kfree(iprtd);
-
- return 0;
-}
-
-static struct snd_pcm_ops imx_pcm_ops = {
- .open = snd_imx_open,
- .close = snd_imx_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_imx_pcm_hw_params,
- .prepare = snd_imx_pcm_prepare,
- .trigger = snd_imx_pcm_trigger,
- .pointer = snd_imx_pcm_pointer,
- .mmap = snd_imx_pcm_mmap,
-};
-
-static int ssi_irq = 0;
-
-static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_pcm *pcm = rtd->pcm;
- struct snd_pcm_substream *substream;
- int ret;
-
- ret = imx_pcm_new(rtd);
- if (ret)
- return ret;
-
- substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
- if (substream) {
- struct snd_dma_buffer *buf = &substream->dma_buffer;
-
- imx_ssi_fiq_tx_buffer = (unsigned long)buf->area;
- }
-
- substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
- if (substream) {
- struct snd_dma_buffer *buf = &substream->dma_buffer;
-
- imx_ssi_fiq_rx_buffer = (unsigned long)buf->area;
- }
-
- set_fiq_handler(&imx_ssi_fiq_start,
- &imx_ssi_fiq_end - &imx_ssi_fiq_start);
-
- return 0;
-}
-
-static void imx_pcm_fiq_free(struct snd_pcm *pcm)
-{
- mxc_set_irq_fiq(ssi_irq, 0);
- release_fiq(&fh);
- imx_pcm_free(pcm);
-}
-
-static struct snd_soc_platform_driver imx_soc_platform_fiq = {
- .ops = &imx_pcm_ops,
- .pcm_new = imx_pcm_fiq_new,
- .pcm_free = imx_pcm_fiq_free,
-};
-
-static int __devinit imx_soc_platform_probe(struct platform_device *pdev)
-{
- struct imx_ssi *ssi = platform_get_drvdata(pdev);
- int ret;
-
- ret = claim_fiq(&fh);
- if (ret) {
- dev_err(&pdev->dev, "failed to claim fiq: %d", ret);
- return ret;
- }
-
- mxc_set_irq_fiq(ssi->irq, 1);
- ssi_irq = ssi->irq;
-
- imx_pcm_fiq = ssi->irq;
-
- imx_ssi_fiq_base = (unsigned long)ssi->base;
-
- ssi->dma_params_tx.burstsize = 4;
- ssi->dma_params_rx.burstsize = 6;
-
- ret = snd_soc_register_platform(&pdev->dev, &imx_soc_platform_fiq);
- if (ret)
- goto failed_register;
-
- return 0;
-
-failed_register:
- mxc_set_irq_fiq(ssi_irq, 0);
- release_fiq(&fh);
-
- return ret;
-}
-
-static int __devexit imx_soc_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver imx_pcm_driver = {
- .driver = {
- .name = "imx-fiq-pcm-audio",
- .owner = THIS_MODULE,
- },
-
- .probe = imx_soc_platform_probe,
- .remove = __devexit_p(imx_soc_platform_remove),
-};
-
-module_platform_driver(imx_pcm_driver);
-
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/imx/imx-pcm.c b/ANDROID_3.4.5/sound/soc/imx/imx-pcm.c
deleted file mode 100644
index 93dc360b..00000000
--- a/ANDROID_3.4.5/sound/soc/imx/imx-pcm.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
- *
- * This code is based on code copyrighted by Freescale,
- * Liam Girdwood, Javier Martin and probably others.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/module.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include "imx-pcm.h"
-
-int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int ret;
-
- ret = dma_mmap_writecombine(substream->pcm->card->dev, vma,
- runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
-
- pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret,
- runtime->dma_area,
- runtime->dma_addr,
- runtime->dma_bytes);
- return ret;
-}
-EXPORT_SYMBOL_GPL(snd_imx_pcm_mmap);
-
-static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
- struct snd_pcm_substream *substream = pcm->streams[stream].substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = IMX_SSI_DMABUF_SIZE;
-
- buf->dev.type = SNDRV_DMA_TYPE_DEV;
- buf->dev.dev = pcm->card->dev;
- buf->private_data = NULL;
- buf->area = dma_alloc_writecombine(pcm->card->dev, size,
- &buf->addr, GFP_KERNEL);
- if (!buf->area)
- return -ENOMEM;
- buf->bytes = size;
-
- return 0;
-}
-
-static u64 imx_pcm_dmamask = DMA_BIT_MASK(32);
-
-int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- int ret = 0;
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &imx_pcm_dmamask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = imx_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_PLAYBACK);
- if (ret)
- goto out;
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- ret = imx_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_CAPTURE);
- if (ret)
- goto out;
- }
-
-out:
- return ret;
-}
-EXPORT_SYMBOL_GPL(imx_pcm_new);
-
-void imx_pcm_free(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- struct snd_dma_buffer *buf;
- int stream;
-
- for (stream = 0; stream < 2; stream++) {
- substream = pcm->streams[stream].substream;
- if (!substream)
- continue;
-
- buf = &substream->dma_buffer;
- if (!buf->area)
- continue;
-
- dma_free_writecombine(pcm->card->dev, buf->bytes,
- buf->area, buf->addr);
- buf->area = NULL;
- }
-}
-EXPORT_SYMBOL_GPL(imx_pcm_free);
diff --git a/ANDROID_3.4.5/sound/soc/imx/imx-pcm.h b/ANDROID_3.4.5/sound/soc/imx/imx-pcm.h
deleted file mode 100644
index b5f5c3ac..00000000
--- a/ANDROID_3.4.5/sound/soc/imx/imx-pcm.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
- *
- * This code is based on code copyrighted by Freescale,
- * Liam Girdwood, Javier Martin and probably others.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#ifndef _IMX_PCM_H
-#define _IMX_PCM_H
-
-/*
- * Do not change this as the FIQ handler depends on this size
- */
-#define IMX_SSI_DMABUF_SIZE (64 * 1024)
-
-struct imx_pcm_dma_params {
- int dma;
- unsigned long dma_addr;
- int burstsize;
-};
-
-int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *vma);
-int imx_pcm_new(struct snd_soc_pcm_runtime *rtd);
-void imx_pcm_free(struct snd_pcm *pcm);
-
-#endif /* _IMX_PCM_H */
diff --git a/ANDROID_3.4.5/sound/soc/imx/imx-ssi.c b/ANDROID_3.4.5/sound/soc/imx/imx-ssi.c
deleted file mode 100644
index 4f81ed45..00000000
--- a/ANDROID_3.4.5/sound/soc/imx/imx-ssi.c
+++ /dev/null
@@ -1,690 +0,0 @@
-/*
- * imx-ssi.c -- ALSA Soc Audio Layer
- *
- * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
- *
- * This code is based on code copyrighted by Freescale,
- * Liam Girdwood, Javier Martin and probably others.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- *
- * The i.MX SSI core has some nasty limitations in AC97 mode. While most
- * sane processor vendors have a FIFO per AC97 slot, the i.MX has only
- * one FIFO which combines all valid receive slots. We cannot even select
- * which slots we want to receive. The WM9712 with which this driver
- * was developed with always sends GPIO status data in slot 12 which
- * we receive in our (PCM-) data stream. The only chance we have is to
- * manually skip this data in the FIQ handler. With sampling rates different
- * from 48000Hz not every frame has valid receive data, so the ratio
- * between pcm data and GPIO status data changes. Our FIQ handler is not
- * able to handle this, hence this driver only works with 48000Hz sampling
- * rate.
- * Reading and writing AC97 registers is another challenge. The core
- * provides us status bits when the read register is updated with *another*
- * value. When we read the same register two times (and the register still
- * contains the same value) these status bits are not set. We work
- * around this by not polling these bits but only wait a fixed delay.
- *
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <mach/ssi.h>
-#include <mach/hardware.h>
-
-#include "imx-ssi.h"
-
-#define SSI_SACNT_DEFAULT (SSI_SACNT_AC97EN | SSI_SACNT_FV)
-
-/*
- * SSI Network Mode or TDM slots configuration.
- * Should only be called when port is inactive (i.e. SSIEN = 0).
- */
-static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
- unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
-{
- struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
- u32 sccr;
-
- sccr = readl(ssi->base + SSI_STCCR);
- sccr &= ~SSI_STCCR_DC_MASK;
- sccr |= SSI_STCCR_DC(slots - 1);
- writel(sccr, ssi->base + SSI_STCCR);
-
- sccr = readl(ssi->base + SSI_SRCCR);
- sccr &= ~SSI_STCCR_DC_MASK;
- sccr |= SSI_STCCR_DC(slots - 1);
- writel(sccr, ssi->base + SSI_SRCCR);
-
- writel(tx_mask, ssi->base + SSI_STMSK);
- writel(rx_mask, ssi->base + SSI_SRMSK);
-
- return 0;
-}
-
-/*
- * SSI DAI format configuration.
- * Should only be called when port is inactive (i.e. SSIEN = 0).
- */
-static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
-{
- struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
- u32 strcr = 0, scr;
-
- scr = readl(ssi->base + SSI_SCR) & ~(SSI_SCR_SYN | SSI_SCR_NET);
-
- /* DAI mode */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- /* data on rising edge of bclk, frame low 1clk before data */
- strcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0;
- scr |= SSI_SCR_NET;
- if (ssi->flags & IMX_SSI_USE_I2S_SLAVE) {
- scr &= ~SSI_I2S_MODE_MASK;
- scr |= SSI_SCR_I2S_MODE_SLAVE;
- }
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- /* data on rising edge of bclk, frame high with data */
- strcr |= SSI_STCR_TXBIT0;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- /* data on rising edge of bclk, frame high with data */
- strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- /* data on rising edge of bclk, frame high 1clk before data */
- strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0 | SSI_STCR_TEFS;
- break;
- }
-
- /* DAI clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_IB_IF:
- strcr |= SSI_STCR_TFSI;
- strcr &= ~SSI_STCR_TSCKP;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- strcr &= ~(SSI_STCR_TSCKP | SSI_STCR_TFSI);
- break;
- case SND_SOC_DAIFMT_NB_IF:
- strcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP;
- break;
- case SND_SOC_DAIFMT_NB_NF:
- strcr &= ~SSI_STCR_TFSI;
- strcr |= SSI_STCR_TSCKP;
- break;
- }
-
- /* DAI clock master masks */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- break;
- default:
- /* Master mode not implemented, needs handling of clocks. */
- return -EINVAL;
- }
-
- strcr |= SSI_STCR_TFEN0;
-
- if (ssi->flags & IMX_SSI_NET)
- scr |= SSI_SCR_NET;
- if (ssi->flags & IMX_SSI_SYN)
- scr |= SSI_SCR_SYN;
-
- writel(strcr, ssi->base + SSI_STCR);
- writel(strcr, ssi->base + SSI_SRCR);
- writel(scr, ssi->base + SSI_SCR);
-
- return 0;
-}
-
-/*
- * SSI system clock configuration.
- * Should only be called when port is inactive (i.e. SSIEN = 0).
- */
-static int imx_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
- u32 scr;
-
- scr = readl(ssi->base + SSI_SCR);
-
- switch (clk_id) {
- case IMX_SSP_SYS_CLK:
- if (dir == SND_SOC_CLOCK_OUT)
- scr |= SSI_SCR_SYS_CLK_EN;
- else
- scr &= ~SSI_SCR_SYS_CLK_EN;
- break;
- default:
- return -EINVAL;
- }
-
- writel(scr, ssi->base + SSI_SCR);
-
- return 0;
-}
-
-/*
- * SSI Clock dividers
- * Should only be called when port is inactive (i.e. SSIEN = 0).
- */
-static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
- int div_id, int div)
-{
- struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
- u32 stccr, srccr;
-
- stccr = readl(ssi->base + SSI_STCCR);
- srccr = readl(ssi->base + SSI_SRCCR);
-
- switch (div_id) {
- case IMX_SSI_TX_DIV_2:
- stccr &= ~SSI_STCCR_DIV2;
- stccr |= div;
- break;
- case IMX_SSI_TX_DIV_PSR:
- stccr &= ~SSI_STCCR_PSR;
- stccr |= div;
- break;
- case IMX_SSI_TX_DIV_PM:
- stccr &= ~0xff;
- stccr |= SSI_STCCR_PM(div);
- break;
- case IMX_SSI_RX_DIV_2:
- stccr &= ~SSI_STCCR_DIV2;
- stccr |= div;
- break;
- case IMX_SSI_RX_DIV_PSR:
- stccr &= ~SSI_STCCR_PSR;
- stccr |= div;
- break;
- case IMX_SSI_RX_DIV_PM:
- stccr &= ~0xff;
- stccr |= SSI_STCCR_PM(div);
- break;
- default:
- return -EINVAL;
- }
-
- writel(stccr, ssi->base + SSI_STCCR);
- writel(srccr, ssi->base + SSI_SRCCR);
-
- return 0;
-}
-
-static int imx_ssi_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *cpu_dai)
-{
- struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
- struct imx_pcm_dma_params *dma_data;
-
- /* Tx/Rx config */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dma_data = &ssi->dma_params_tx;
- else
- dma_data = &ssi->dma_params_rx;
-
- snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
-
- return 0;
-}
-
-/*
- * Should only be called when port is inactive (i.e. SSIEN = 0),
- * although can be called multiple times by upper layers.
- */
-static int imx_ssi_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *cpu_dai)
-{
- struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
- u32 reg, sccr;
-
- /* Tx/Rx config */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- reg = SSI_STCCR;
- else
- reg = SSI_SRCCR;
-
- if (ssi->flags & IMX_SSI_SYN)
- reg = SSI_STCCR;
-
- sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK;
-
- /* DAI data (word) size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- sccr |= SSI_SRCCR_WL(16);
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- sccr |= SSI_SRCCR_WL(20);
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- sccr |= SSI_SRCCR_WL(24);
- break;
- }
-
- writel(sccr, ssi->base + reg);
-
- return 0;
-}
-
-static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- struct imx_ssi *ssi = snd_soc_dai_get_drvdata(dai);
- unsigned int sier_bits, sier;
- unsigned int scr;
-
- scr = readl(ssi->base + SSI_SCR);
- sier = readl(ssi->base + SSI_SIER);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (ssi->flags & IMX_SSI_DMA)
- sier_bits = SSI_SIER_TDMAE;
- else
- sier_bits = SSI_SIER_TIE | SSI_SIER_TFE0_EN;
- } else {
- if (ssi->flags & IMX_SSI_DMA)
- sier_bits = SSI_SIER_RDMAE;
- else
- sier_bits = SSI_SIER_RIE | SSI_SIER_RFF0_EN;
- }
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- scr |= SSI_SCR_TE;
- else
- scr |= SSI_SCR_RE;
- sier |= sier_bits;
-
- if (++ssi->enabled == 1)
- scr |= SSI_SCR_SSIEN;
-
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- scr &= ~SSI_SCR_TE;
- else
- scr &= ~SSI_SCR_RE;
- sier &= ~sier_bits;
-
- if (--ssi->enabled == 0)
- scr &= ~SSI_SCR_SSIEN;
-
- break;
- default:
- return -EINVAL;
- }
-
- if (!(ssi->flags & IMX_SSI_USE_AC97))
- /* rx/tx are always enabled to access ac97 registers */
- writel(scr, ssi->base + SSI_SCR);
-
- writel(sier, ssi->base + SSI_SIER);
-
- return 0;
-}
-
-static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
- .startup = imx_ssi_startup,
- .hw_params = imx_ssi_hw_params,
- .set_fmt = imx_ssi_set_dai_fmt,
- .set_clkdiv = imx_ssi_set_dai_clkdiv,
- .set_sysclk = imx_ssi_set_dai_sysclk,
- .set_tdm_slot = imx_ssi_set_dai_tdm_slot,
- .trigger = imx_ssi_trigger,
-};
-
-static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
-{
- struct imx_ssi *ssi = dev_get_drvdata(dai->dev);
- uint32_t val;
-
- snd_soc_dai_set_drvdata(dai, ssi);
-
- val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) |
- SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
- writel(val, ssi->base + SSI_SFCSR);
-
- return 0;
-}
-
-static struct snd_soc_dai_driver imx_ssi_dai = {
- .probe = imx_ssi_dai_probe,
- .playback = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .capture = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .ops = &imx_ssi_pcm_dai_ops,
-};
-
-static struct snd_soc_dai_driver imx_ac97_dai = {
- .probe = imx_ssi_dai_probe,
- .ac97_control = 1,
- .playback = {
- .stream_name = "AC97 Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .capture = {
- .stream_name = "AC97 Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .ops = &imx_ssi_pcm_dai_ops,
-};
-
-static void setup_channel_to_ac97(struct imx_ssi *imx_ssi)
-{
- void __iomem *base = imx_ssi->base;
-
- writel(0x0, base + SSI_SCR);
- writel(0x0, base + SSI_STCR);
- writel(0x0, base + SSI_SRCR);
-
- writel(SSI_SCR_SYN | SSI_SCR_NET, base + SSI_SCR);
-
- writel(SSI_SFCSR_RFWM0(8) |
- SSI_SFCSR_TFWM0(8) |
- SSI_SFCSR_RFWM1(8) |
- SSI_SFCSR_TFWM1(8), base + SSI_SFCSR);
-
- writel(SSI_STCCR_WL(16) | SSI_STCCR_DC(12), base + SSI_STCCR);
- writel(SSI_STCCR_WL(16) | SSI_STCCR_DC(12), base + SSI_SRCCR);
-
- writel(SSI_SCR_SYN | SSI_SCR_NET | SSI_SCR_SSIEN, base + SSI_SCR);
- writel(SSI_SOR_WAIT(3), base + SSI_SOR);
-
- writel(SSI_SCR_SYN | SSI_SCR_NET | SSI_SCR_SSIEN |
- SSI_SCR_TE | SSI_SCR_RE,
- base + SSI_SCR);
-
- writel(SSI_SACNT_DEFAULT, base + SSI_SACNT);
- writel(0xff, base + SSI_SACCDIS);
- writel(0x300, base + SSI_SACCEN);
-}
-
-static struct imx_ssi *ac97_ssi;
-
-static void imx_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short val)
-{
- struct imx_ssi *imx_ssi = ac97_ssi;
- void __iomem *base = imx_ssi->base;
- unsigned int lreg;
- unsigned int lval;
-
- if (reg > 0x7f)
- return;
-
- pr_debug("%s: 0x%02x 0x%04x\n", __func__, reg, val);
-
- lreg = reg << 12;
- writel(lreg, base + SSI_SACADD);
-
- lval = val << 4;
- writel(lval , base + SSI_SACDAT);
-
- writel(SSI_SACNT_DEFAULT | SSI_SACNT_WR, base + SSI_SACNT);
- udelay(100);
-}
-
-static unsigned short imx_ssi_ac97_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- struct imx_ssi *imx_ssi = ac97_ssi;
- void __iomem *base = imx_ssi->base;
-
- unsigned short val = -1;
- unsigned int lreg;
-
- lreg = (reg & 0x7f) << 12 ;
- writel(lreg, base + SSI_SACADD);
- writel(SSI_SACNT_DEFAULT | SSI_SACNT_RD, base + SSI_SACNT);
-
- udelay(100);
-
- val = (readl(base + SSI_SACDAT) >> 4) & 0xffff;
-
- pr_debug("%s: 0x%02x 0x%04x\n", __func__, reg, val);
-
- return val;
-}
-
-static void imx_ssi_ac97_reset(struct snd_ac97 *ac97)
-{
- struct imx_ssi *imx_ssi = ac97_ssi;
-
- if (imx_ssi->ac97_reset)
- imx_ssi->ac97_reset(ac97);
-}
-
-static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97)
-{
- struct imx_ssi *imx_ssi = ac97_ssi;
-
- if (imx_ssi->ac97_warm_reset)
- imx_ssi->ac97_warm_reset(ac97);
-}
-
-struct snd_ac97_bus_ops soc_ac97_ops = {
- .read = imx_ssi_ac97_read,
- .write = imx_ssi_ac97_write,
- .reset = imx_ssi_ac97_reset,
- .warm_reset = imx_ssi_ac97_warm_reset
-};
-EXPORT_SYMBOL_GPL(soc_ac97_ops);
-
-static int imx_ssi_probe(struct platform_device *pdev)
-{
- struct resource *res;
- struct imx_ssi *ssi;
- struct imx_ssi_platform_data *pdata = pdev->dev.platform_data;
- int ret = 0;
- struct snd_soc_dai_driver *dai;
-
- ssi = kzalloc(sizeof(*ssi), GFP_KERNEL);
- if (!ssi)
- return -ENOMEM;
- dev_set_drvdata(&pdev->dev, ssi);
-
- if (pdata) {
- ssi->ac97_reset = pdata->ac97_reset;
- ssi->ac97_warm_reset = pdata->ac97_warm_reset;
- ssi->flags = pdata->flags;
- }
-
- ssi->irq = platform_get_irq(pdev, 0);
-
- ssi->clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(ssi->clk)) {
- ret = PTR_ERR(ssi->clk);
- dev_err(&pdev->dev, "Cannot get the clock: %d\n",
- ret);
- goto failed_clk;
- }
- clk_enable(ssi->clk);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- ret = -ENODEV;
- goto failed_get_resource;
- }
-
- if (!request_mem_region(res->start, resource_size(res), DRV_NAME)) {
- dev_err(&pdev->dev, "request_mem_region failed\n");
- ret = -EBUSY;
- goto failed_get_resource;
- }
-
- ssi->base = ioremap(res->start, resource_size(res));
- if (!ssi->base) {
- dev_err(&pdev->dev, "ioremap failed\n");
- ret = -ENODEV;
- goto failed_ioremap;
- }
-
- if (ssi->flags & IMX_SSI_USE_AC97) {
- if (ac97_ssi) {
- ret = -EBUSY;
- goto failed_ac97;
- }
- ac97_ssi = ssi;
- setup_channel_to_ac97(ssi);
- dai = &imx_ac97_dai;
- } else
- dai = &imx_ssi_dai;
-
- writel(0x0, ssi->base + SSI_SIER);
-
- ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0;
- ssi->dma_params_tx.dma_addr = res->start + SSI_STX0;
-
- ssi->dma_params_tx.burstsize = 6;
- ssi->dma_params_rx.burstsize = 4;
-
- res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0");
- if (res)
- ssi->dma_params_tx.dma = res->start;
-
- res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx0");
- if (res)
- ssi->dma_params_rx.dma = res->start;
-
- platform_set_drvdata(pdev, ssi);
-
- ret = snd_soc_register_dai(&pdev->dev, dai);
- if (ret) {
- dev_err(&pdev->dev, "register DAI failed\n");
- goto failed_register;
- }
-
- ssi->soc_platform_pdev_fiq = platform_device_alloc("imx-fiq-pcm-audio", pdev->id);
- if (!ssi->soc_platform_pdev_fiq) {
- ret = -ENOMEM;
- goto failed_pdev_fiq_alloc;
- }
-
- platform_set_drvdata(ssi->soc_platform_pdev_fiq, ssi);
- ret = platform_device_add(ssi->soc_platform_pdev_fiq);
- if (ret) {
- dev_err(&pdev->dev, "failed to add platform device\n");
- goto failed_pdev_fiq_add;
- }
-
- ssi->soc_platform_pdev = platform_device_alloc("imx-pcm-audio", pdev->id);
- if (!ssi->soc_platform_pdev) {
- ret = -ENOMEM;
- goto failed_pdev_alloc;
- }
-
- platform_set_drvdata(ssi->soc_platform_pdev, ssi);
- ret = platform_device_add(ssi->soc_platform_pdev);
- if (ret) {
- dev_err(&pdev->dev, "failed to add platform device\n");
- goto failed_pdev_add;
- }
-
- return 0;
-
-failed_pdev_add:
- platform_device_put(ssi->soc_platform_pdev);
-failed_pdev_alloc:
- platform_device_del(ssi->soc_platform_pdev_fiq);
-failed_pdev_fiq_add:
- platform_device_put(ssi->soc_platform_pdev_fiq);
-failed_pdev_fiq_alloc:
- snd_soc_unregister_dai(&pdev->dev);
-failed_register:
-failed_ac97:
- iounmap(ssi->base);
-failed_ioremap:
- release_mem_region(res->start, resource_size(res));
-failed_get_resource:
- clk_disable(ssi->clk);
- clk_put(ssi->clk);
-failed_clk:
- kfree(ssi);
-
- return ret;
-}
-
-static int __devexit imx_ssi_remove(struct platform_device *pdev)
-{
- struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- struct imx_ssi *ssi = platform_get_drvdata(pdev);
-
- platform_device_unregister(ssi->soc_platform_pdev);
- platform_device_unregister(ssi->soc_platform_pdev_fiq);
-
- snd_soc_unregister_dai(&pdev->dev);
-
- if (ssi->flags & IMX_SSI_USE_AC97)
- ac97_ssi = NULL;
-
- iounmap(ssi->base);
- release_mem_region(res->start, resource_size(res));
- clk_disable(ssi->clk);
- clk_put(ssi->clk);
- kfree(ssi);
-
- return 0;
-}
-
-static struct platform_driver imx_ssi_driver = {
- .probe = imx_ssi_probe,
- .remove = __devexit_p(imx_ssi_remove),
-
- .driver = {
- .name = "imx-ssi",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(imx_ssi_driver);
-
-/* Module information */
-MODULE_AUTHOR("Sascha Hauer, <s.hauer@pengutronix.de>");
-MODULE_DESCRIPTION("i.MX I2S/ac97 SoC Interface");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:imx-ssi");
diff --git a/ANDROID_3.4.5/sound/soc/imx/imx-ssi.h b/ANDROID_3.4.5/sound/soc/imx/imx-ssi.h
deleted file mode 100644
index 5744e86c..00000000
--- a/ANDROID_3.4.5/sound/soc/imx/imx-ssi.h
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _IMX_SSI_H
-#define _IMX_SSI_H
-
-#define SSI_STX0 0x00
-#define SSI_STX1 0x04
-#define SSI_SRX0 0x08
-#define SSI_SRX1 0x0c
-
-#define SSI_SCR 0x10
-#define SSI_SCR_CLK_IST (1 << 9)
-#define SSI_SCR_CLK_IST_SHIFT 9
-#define SSI_SCR_TCH_EN (1 << 8)
-#define SSI_SCR_SYS_CLK_EN (1 << 7)
-#define SSI_SCR_I2S_MODE_NORM (0 << 5)
-#define SSI_SCR_I2S_MODE_MSTR (1 << 5)
-#define SSI_SCR_I2S_MODE_SLAVE (2 << 5)
-#define SSI_I2S_MODE_MASK (3 << 5)
-#define SSI_SCR_SYN (1 << 4)
-#define SSI_SCR_NET (1 << 3)
-#define SSI_SCR_RE (1 << 2)
-#define SSI_SCR_TE (1 << 1)
-#define SSI_SCR_SSIEN (1 << 0)
-
-#define SSI_SISR 0x14
-#define SSI_SISR_MASK ((1 << 19) - 1)
-#define SSI_SISR_CMDAU (1 << 18)
-#define SSI_SISR_CMDDU (1 << 17)
-#define SSI_SISR_RXT (1 << 16)
-#define SSI_SISR_RDR1 (1 << 15)
-#define SSI_SISR_RDR0 (1 << 14)
-#define SSI_SISR_TDE1 (1 << 13)
-#define SSI_SISR_TDE0 (1 << 12)
-#define SSI_SISR_ROE1 (1 << 11)
-#define SSI_SISR_ROE0 (1 << 10)
-#define SSI_SISR_TUE1 (1 << 9)
-#define SSI_SISR_TUE0 (1 << 8)
-#define SSI_SISR_TFS (1 << 7)
-#define SSI_SISR_RFS (1 << 6)
-#define SSI_SISR_TLS (1 << 5)
-#define SSI_SISR_RLS (1 << 4)
-#define SSI_SISR_RFF1 (1 << 3)
-#define SSI_SISR_RFF0 (1 << 2)
-#define SSI_SISR_TFE1 (1 << 1)
-#define SSI_SISR_TFE0 (1 << 0)
-
-#define SSI_SIER 0x18
-#define SSI_SIER_RDMAE (1 << 22)
-#define SSI_SIER_RIE (1 << 21)
-#define SSI_SIER_TDMAE (1 << 20)
-#define SSI_SIER_TIE (1 << 19)
-#define SSI_SIER_CMDAU_EN (1 << 18)
-#define SSI_SIER_CMDDU_EN (1 << 17)
-#define SSI_SIER_RXT_EN (1 << 16)
-#define SSI_SIER_RDR1_EN (1 << 15)
-#define SSI_SIER_RDR0_EN (1 << 14)
-#define SSI_SIER_TDE1_EN (1 << 13)
-#define SSI_SIER_TDE0_EN (1 << 12)
-#define SSI_SIER_ROE1_EN (1 << 11)
-#define SSI_SIER_ROE0_EN (1 << 10)
-#define SSI_SIER_TUE1_EN (1 << 9)
-#define SSI_SIER_TUE0_EN (1 << 8)
-#define SSI_SIER_TFS_EN (1 << 7)
-#define SSI_SIER_RFS_EN (1 << 6)
-#define SSI_SIER_TLS_EN (1 << 5)
-#define SSI_SIER_RLS_EN (1 << 4)
-#define SSI_SIER_RFF1_EN (1 << 3)
-#define SSI_SIER_RFF0_EN (1 << 2)
-#define SSI_SIER_TFE1_EN (1 << 1)
-#define SSI_SIER_TFE0_EN (1 << 0)
-
-#define SSI_STCR 0x1c
-#define SSI_STCR_TXBIT0 (1 << 9)
-#define SSI_STCR_TFEN1 (1 << 8)
-#define SSI_STCR_TFEN0 (1 << 7)
-#define SSI_FIFO_ENABLE_0_SHIFT 7
-#define SSI_STCR_TFDIR (1 << 6)
-#define SSI_STCR_TXDIR (1 << 5)
-#define SSI_STCR_TSHFD (1 << 4)
-#define SSI_STCR_TSCKP (1 << 3)
-#define SSI_STCR_TFSI (1 << 2)
-#define SSI_STCR_TFSL (1 << 1)
-#define SSI_STCR_TEFS (1 << 0)
-
-#define SSI_SRCR 0x20
-#define SSI_SRCR_RXBIT0 (1 << 9)
-#define SSI_SRCR_RFEN1 (1 << 8)
-#define SSI_SRCR_RFEN0 (1 << 7)
-#define SSI_FIFO_ENABLE_0_SHIFT 7
-#define SSI_SRCR_RFDIR (1 << 6)
-#define SSI_SRCR_RXDIR (1 << 5)
-#define SSI_SRCR_RSHFD (1 << 4)
-#define SSI_SRCR_RSCKP (1 << 3)
-#define SSI_SRCR_RFSI (1 << 2)
-#define SSI_SRCR_RFSL (1 << 1)
-#define SSI_SRCR_REFS (1 << 0)
-
-#define SSI_SRCCR 0x28
-#define SSI_SRCCR_DIV2 (1 << 18)
-#define SSI_SRCCR_PSR (1 << 17)
-#define SSI_SRCCR_WL(x) ((((x) - 2) >> 1) << 13)
-#define SSI_SRCCR_DC(x) (((x) & 0x1f) << 8)
-#define SSI_SRCCR_PM(x) (((x) & 0xff) << 0)
-#define SSI_SRCCR_WL_MASK (0xf << 13)
-#define SSI_SRCCR_DC_MASK (0x1f << 8)
-#define SSI_SRCCR_PM_MASK (0xff << 0)
-
-#define SSI_STCCR 0x24
-#define SSI_STCCR_DIV2 (1 << 18)
-#define SSI_STCCR_PSR (1 << 17)
-#define SSI_STCCR_WL(x) ((((x) - 2) >> 1) << 13)
-#define SSI_STCCR_DC(x) (((x) & 0x1f) << 8)
-#define SSI_STCCR_PM(x) (((x) & 0xff) << 0)
-#define SSI_STCCR_WL_MASK (0xf << 13)
-#define SSI_STCCR_DC_MASK (0x1f << 8)
-#define SSI_STCCR_PM_MASK (0xff << 0)
-
-#define SSI_SFCSR 0x2c
-#define SSI_SFCSR_RFCNT1(x) (((x) & 0xf) << 28)
-#define SSI_RX_FIFO_1_COUNT_SHIFT 28
-#define SSI_SFCSR_TFCNT1(x) (((x) & 0xf) << 24)
-#define SSI_TX_FIFO_1_COUNT_SHIFT 24
-#define SSI_SFCSR_RFWM1(x) (((x) & 0xf) << 20)
-#define SSI_SFCSR_TFWM1(x) (((x) & 0xf) << 16)
-#define SSI_SFCSR_RFCNT0(x) (((x) & 0xf) << 12)
-#define SSI_RX_FIFO_0_COUNT_SHIFT 12
-#define SSI_SFCSR_TFCNT0(x) (((x) & 0xf) << 8)
-#define SSI_TX_FIFO_0_COUNT_SHIFT 8
-#define SSI_SFCSR_RFWM0(x) (((x) & 0xf) << 4)
-#define SSI_SFCSR_TFWM0(x) (((x) & 0xf) << 0)
-#define SSI_SFCSR_RFWM0_MASK (0xf << 4)
-#define SSI_SFCSR_TFWM0_MASK (0xf << 0)
-
-#define SSI_STR 0x30
-#define SSI_STR_TEST (1 << 15)
-#define SSI_STR_RCK2TCK (1 << 14)
-#define SSI_STR_RFS2TFS (1 << 13)
-#define SSI_STR_RXSTATE(x) (((x) & 0xf) << 8)
-#define SSI_STR_TXD2RXD (1 << 7)
-#define SSI_STR_TCK2RCK (1 << 6)
-#define SSI_STR_TFS2RFS (1 << 5)
-#define SSI_STR_TXSTATE(x) (((x) & 0xf) << 0)
-
-#define SSI_SOR 0x34
-#define SSI_SOR_CLKOFF (1 << 6)
-#define SSI_SOR_RX_CLR (1 << 5)
-#define SSI_SOR_TX_CLR (1 << 4)
-#define SSI_SOR_INIT (1 << 3)
-#define SSI_SOR_WAIT(x) (((x) & 0x3) << 1)
-#define SSI_SOR_WAIT_MASK (0x3 << 1)
-#define SSI_SOR_SYNRST (1 << 0)
-
-#define SSI_SACNT 0x38
-#define SSI_SACNT_FRDIV(x) (((x) & 0x3f) << 5)
-#define SSI_SACNT_WR (1 << 4)
-#define SSI_SACNT_RD (1 << 3)
-#define SSI_SACNT_TIF (1 << 2)
-#define SSI_SACNT_FV (1 << 1)
-#define SSI_SACNT_AC97EN (1 << 0)
-
-#define SSI_SACADD 0x3c
-#define SSI_SACDAT 0x40
-#define SSI_SATAG 0x44
-#define SSI_STMSK 0x48
-#define SSI_SRMSK 0x4c
-#define SSI_SACCST 0x50
-#define SSI_SACCEN 0x54
-#define SSI_SACCDIS 0x58
-
-/* SSI clock sources */
-#define IMX_SSP_SYS_CLK 0
-
-/* SSI audio dividers */
-#define IMX_SSI_TX_DIV_2 0
-#define IMX_SSI_TX_DIV_PSR 1
-#define IMX_SSI_TX_DIV_PM 2
-#define IMX_SSI_RX_DIV_2 3
-#define IMX_SSI_RX_DIV_PSR 4
-#define IMX_SSI_RX_DIV_PM 5
-
-#define DRV_NAME "imx-ssi"
-
-#include <linux/dmaengine.h>
-#include <mach/dma.h>
-#include "imx-pcm.h"
-
-struct imx_ssi {
- struct platform_device *ac97_dev;
-
- struct snd_soc_dai *imx_ac97;
- struct clk *clk;
- void __iomem *base;
- int irq;
- int fiq_enable;
- unsigned int offset;
-
- unsigned int flags;
-
- void (*ac97_reset) (struct snd_ac97 *ac97);
- void (*ac97_warm_reset)(struct snd_ac97 *ac97);
-
- struct imx_pcm_dma_params dma_params_rx;
- struct imx_pcm_dma_params dma_params_tx;
-
- int enabled;
-
- struct platform_device *soc_platform_pdev;
- struct platform_device *soc_platform_pdev_fiq;
-};
-
-#endif /* _IMX_SSI_H */
diff --git a/ANDROID_3.4.5/sound/soc/imx/mx27vis-aic32x4.c b/ANDROID_3.4.5/sound/soc/imx/mx27vis-aic32x4.c
deleted file mode 100644
index f6d04ad4..00000000
--- a/ANDROID_3.4.5/sound/soc/imx/mx27vis-aic32x4.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * mx27vis-aic32x4.c
- *
- * Copyright 2011 Vista Silicon S.L.
- *
- * Author: Javier Martin <javier.martin@vista-silicon.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <linux/gpio.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/tlv.h>
-#include <asm/mach-types.h>
-#include <mach/iomux-mx27.h>
-
-#include "../codecs/tlv320aic32x4.h"
-#include "imx-ssi.h"
-#include "imx-audmux.h"
-
-#define MX27VIS_AMP_GAIN 0
-#define MX27VIS_AMP_MUTE 1
-
-#define MX27VIS_PIN_G0 (GPIO_PORTF + 9)
-#define MX27VIS_PIN_G1 (GPIO_PORTF + 8)
-#define MX27VIS_PIN_SDL (GPIO_PORTE + 5)
-#define MX27VIS_PIN_SDR (GPIO_PORTF + 7)
-
-static int mx27vis_amp_gain;
-static int mx27vis_amp_mute;
-
-static const int mx27vis_amp_pins[] = {
- MX27VIS_PIN_G0 | GPIO_GPIO | GPIO_OUT,
- MX27VIS_PIN_G1 | GPIO_GPIO | GPIO_OUT,
- MX27VIS_PIN_SDL | GPIO_GPIO | GPIO_OUT,
- MX27VIS_PIN_SDR | GPIO_GPIO | GPIO_OUT,
-};
-
-static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret;
- u32 dai_format;
-
- dai_format = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM;
-
- /* set codec DAI configuration */
- snd_soc_dai_set_fmt(codec_dai, dai_format);
-
- /* set cpu DAI configuration */
- snd_soc_dai_set_fmt(cpu_dai, dai_format);
-
- ret = snd_soc_dai_set_sysclk(codec_dai, 0,
- 25000000, SND_SOC_CLOCK_OUT);
- if (ret) {
- pr_err("%s: failed setting codec sysclk\n", __func__);
- return ret;
- }
-
- ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0,
- SND_SOC_CLOCK_IN);
- if (ret) {
- pr_err("can't set CPU system clock IMX_SSP_SYS_CLK\n");
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_soc_ops mx27vis_aic32x4_snd_ops = {
- .hw_params = mx27vis_aic32x4_hw_params,
-};
-
-static int mx27vis_amp_set(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- int value = ucontrol->value.integer.value[0];
- unsigned int reg = mc->reg;
- int max = mc->max;
-
- if (value > max)
- return -EINVAL;
-
- switch (reg) {
- case MX27VIS_AMP_GAIN:
- gpio_set_value(MX27VIS_PIN_G0, value & 1);
- gpio_set_value(MX27VIS_PIN_G1, value >> 1);
- mx27vis_amp_gain = value;
- break;
- case MX27VIS_AMP_MUTE:
- gpio_set_value(MX27VIS_PIN_SDL, value & 1);
- gpio_set_value(MX27VIS_PIN_SDR, value >> 1);
- mx27vis_amp_mute = value;
- break;
- }
- return 0;
-}
-
-static int mx27vis_amp_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- unsigned int reg = mc->reg;
-
- switch (reg) {
- case MX27VIS_AMP_GAIN:
- ucontrol->value.integer.value[0] = mx27vis_amp_gain;
- break;
- case MX27VIS_AMP_MUTE:
- ucontrol->value.integer.value[0] = mx27vis_amp_mute;
- break;
- }
- return 0;
-}
-
-/* From 6dB to 24dB in steps of 6dB */
-static const DECLARE_TLV_DB_SCALE(mx27vis_amp_tlv, 600, 600, 0);
-
-static const struct snd_kcontrol_new mx27vis_aic32x4_controls[] = {
- SOC_DAPM_PIN_SWITCH("External Mic"),
- SOC_SINGLE_EXT_TLV("LO Ext Boost", MX27VIS_AMP_GAIN, 0, 3, 0,
- mx27vis_amp_get, mx27vis_amp_set, mx27vis_amp_tlv),
- SOC_DOUBLE_EXT("LO Ext Mute Switch", MX27VIS_AMP_MUTE, 0, 1, 1, 0,
- mx27vis_amp_get, mx27vis_amp_set),
-};
-
-static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = {
- SND_SOC_DAPM_MIC("External Mic", NULL),
-};
-
-static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = {
- {"Mic Bias", NULL, "External Mic"},
- {"IN1_R", NULL, "Mic Bias"},
- {"IN2_R", NULL, "Mic Bias"},
- {"IN3_R", NULL, "Mic Bias"},
- {"IN1_L", NULL, "Mic Bias"},
- {"IN2_L", NULL, "Mic Bias"},
- {"IN3_L", NULL, "Mic Bias"},
-};
-
-static struct snd_soc_dai_link mx27vis_aic32x4_dai = {
- .name = "tlv320aic32x4",
- .stream_name = "TLV320AIC32X4",
- .codec_dai_name = "tlv320aic32x4-hifi",
- .platform_name = "imx-pcm-audio.0",
- .codec_name = "tlv320aic32x4.0-0018",
- .cpu_dai_name = "imx-ssi.0",
- .ops = &mx27vis_aic32x4_snd_ops,
-};
-
-static struct snd_soc_card mx27vis_aic32x4 = {
- .name = "visstrim_m10-audio",
- .owner = THIS_MODULE,
- .dai_link = &mx27vis_aic32x4_dai,
- .num_links = 1,
- .controls = mx27vis_aic32x4_controls,
- .num_controls = ARRAY_SIZE(mx27vis_aic32x4_controls),
- .dapm_widgets = aic32x4_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(aic32x4_dapm_widgets),
- .dapm_routes = aic32x4_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes),
-};
-
-static int __devinit mx27vis_aic32x4_probe(struct platform_device *pdev)
-{
- int ret;
-
- mx27vis_aic32x4.dev = &pdev->dev;
- ret = snd_soc_register_card(&mx27vis_aic32x4);
- if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
- ret);
- return ret;
- }
-
- /* Connect SSI0 as clock slave to SSI1 external pins */
- imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
- IMX_AUDMUX_V1_PCR_SYN |
- IMX_AUDMUX_V1_PCR_TFSDIR |
- IMX_AUDMUX_V1_PCR_TCLKDIR |
- IMX_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1) |
- IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1)
- );
- imx_audmux_v1_configure_port(MX27_AUDMUX_PPCR1_SSI_PINS_1,
- IMX_AUDMUX_V1_PCR_SYN |
- IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
- );
-
- ret = mxc_gpio_setup_multiple_pins(mx27vis_amp_pins,
- ARRAY_SIZE(mx27vis_amp_pins), "MX27VIS_AMP");
- if (ret)
- printk(KERN_ERR "ASoC: unable to setup gpios\n");
-
- return ret;
-}
-
-static int __devexit mx27vis_aic32x4_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_card(&mx27vis_aic32x4);
-
- return 0;
-}
-
-static struct platform_driver mx27vis_aic32x4_audio_driver = {
- .driver = {
- .name = "mx27vis",
- .owner = THIS_MODULE,
- },
- .probe = mx27vis_aic32x4_probe,
- .remove = __devexit_p(mx27vis_aic32x4_remove),
-};
-
-module_platform_driver(mx27vis_aic32x4_audio_driver);
-
-MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
-MODULE_DESCRIPTION("ALSA SoC AIC32X4 mx27 visstrim");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:mx27vis");
diff --git a/ANDROID_3.4.5/sound/soc/imx/phycore-ac97.c b/ANDROID_3.4.5/sound/soc/imx/phycore-ac97.c
deleted file mode 100644
index f8da6dd1..00000000
--- a/ANDROID_3.4.5/sound/soc/imx/phycore-ac97.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * phycore-ac97.c -- SoC audio for imx_phycore in AC97 mode
- *
- * Copyright 2009 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <asm/mach-types.h>
-
-#include "imx-audmux.h"
-
-static struct snd_soc_card imx_phycore;
-
-static struct snd_soc_ops imx_phycore_hifi_ops = {
-};
-
-static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
- {
- .name = "HiFi",
- .stream_name = "HiFi",
- .codec_dai_name = "wm9712-hifi",
- .codec_name = "wm9712-codec",
- .cpu_dai_name = "imx-ssi.0",
- .platform_name = "imx-fiq-pcm-audio.0",
- .ops = &imx_phycore_hifi_ops,
- },
-};
-
-static struct snd_soc_card imx_phycore = {
- .name = "PhyCORE-ac97-audio",
- .owner = THIS_MODULE,
- .dai_link = imx_phycore_dai_ac97,
- .num_links = ARRAY_SIZE(imx_phycore_dai_ac97),
-};
-
-static struct platform_device *imx_phycore_snd_ac97_device;
-static struct platform_device *imx_phycore_snd_device;
-
-static int __init imx_phycore_init(void)
-{
- int ret;
-
- if (machine_is_pca100()) {
- imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
- IMX_AUDMUX_V1_PCR_SYN | /* 4wire mode */
- IMX_AUDMUX_V1_PCR_TFCSEL(3) |
- IMX_AUDMUX_V1_PCR_TCLKDIR | /* clock is output */
- IMX_AUDMUX_V1_PCR_RXDSEL(3));
- imx_audmux_v1_configure_port(3,
- IMX_AUDMUX_V1_PCR_SYN | /* 4wire mode */
- IMX_AUDMUX_V1_PCR_TFCSEL(0) |
- IMX_AUDMUX_V1_PCR_TFSDIR |
- IMX_AUDMUX_V1_PCR_RXDSEL(0));
- } else if (machine_is_pcm043()) {
- imx_audmux_v2_configure_port(3,
- IMX_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
- IMX_AUDMUX_V2_PTCR_TFSEL(0) |
- IMX_AUDMUX_V2_PTCR_TFSDIR,
- IMX_AUDMUX_V2_PDCR_RXDSEL(0));
- imx_audmux_v2_configure_port(0,
- IMX_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
- IMX_AUDMUX_V2_PTCR_TCSEL(3) |
- IMX_AUDMUX_V2_PTCR_TCLKDIR, /* clock is output */
- IMX_AUDMUX_V2_PDCR_RXDSEL(3));
- } else {
- /* return happy. We might run on a totally different machine */
- return 0;
- }
-
- imx_phycore_snd_ac97_device = platform_device_alloc("soc-audio", -1);
- if (!imx_phycore_snd_ac97_device)
- return -ENOMEM;
-
- platform_set_drvdata(imx_phycore_snd_ac97_device, &imx_phycore);
- ret = platform_device_add(imx_phycore_snd_ac97_device);
- if (ret)
- goto fail1;
-
- imx_phycore_snd_device = platform_device_alloc("wm9712-codec", -1);
- if (!imx_phycore_snd_device) {
- ret = -ENOMEM;
- goto fail2;
- }
- ret = platform_device_add(imx_phycore_snd_device);
-
- if (ret) {
- printk(KERN_ERR "ASoC: Platform device allocation failed\n");
- goto fail3;
- }
-
- return 0;
-
-fail3:
- platform_device_put(imx_phycore_snd_device);
-fail2:
- platform_device_del(imx_phycore_snd_ac97_device);
-fail1:
- platform_device_put(imx_phycore_snd_ac97_device);
- return ret;
-}
-
-static void __exit imx_phycore_exit(void)
-{
- platform_device_unregister(imx_phycore_snd_device);
- platform_device_unregister(imx_phycore_snd_ac97_device);
-}
-
-late_initcall(imx_phycore_init);
-module_exit(imx_phycore_exit);
-
-MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
-MODULE_DESCRIPTION("PhyCORE ALSA SoC driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/imx/wm1133-ev1.c b/ANDROID_3.4.5/sound/soc/imx/wm1133-ev1.c
deleted file mode 100644
index fe54a690..00000000
--- a/ANDROID_3.4.5/sound/soc/imx/wm1133-ev1.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * wm1133-ev1.c - Audio for WM1133-EV1 on i.MX31ADS
- *
- * Copyright (c) 2010 Wolfson Microelectronics plc
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * Based on an earlier driver for the same hardware by Liam Girdwood.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/jack.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include "imx-ssi.h"
-#include "../codecs/wm8350.h"
-#include "imx-audmux.h"
-
-/* There is a silicon mic on the board optionally connected via a solder pad
- * SP1. Define this to enable it.
- */
-#undef USE_SIMIC
-
-struct _wm8350_audio {
- unsigned int channels;
- snd_pcm_format_t format;
- unsigned int rate;
- unsigned int sysclk;
- unsigned int bclkdiv;
- unsigned int clkdiv;
- unsigned int lr_rate;
-};
-
-/* in order of power consumption per rate (lowest first) */
-static const struct _wm8350_audio wm8350_audio[] = {
- /* 16bit mono modes */
- {1, SNDRV_PCM_FORMAT_S16_LE, 8000, 12288000 >> 1,
- WM8350_BCLK_DIV_48, WM8350_DACDIV_3, 16,},
-
- /* 16 bit stereo modes */
- {2, SNDRV_PCM_FORMAT_S16_LE, 8000, 12288000,
- WM8350_BCLK_DIV_48, WM8350_DACDIV_6, 32,},
- {2, SNDRV_PCM_FORMAT_S16_LE, 16000, 12288000,
- WM8350_BCLK_DIV_24, WM8350_DACDIV_3, 32,},
- {2, SNDRV_PCM_FORMAT_S16_LE, 32000, 12288000,
- WM8350_BCLK_DIV_12, WM8350_DACDIV_1_5, 32,},
- {2, SNDRV_PCM_FORMAT_S16_LE, 48000, 12288000,
- WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
- {2, SNDRV_PCM_FORMAT_S16_LE, 96000, 24576000,
- WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
- {2, SNDRV_PCM_FORMAT_S16_LE, 11025, 11289600,
- WM8350_BCLK_DIV_32, WM8350_DACDIV_4, 32,},
- {2, SNDRV_PCM_FORMAT_S16_LE, 22050, 11289600,
- WM8350_BCLK_DIV_16, WM8350_DACDIV_2, 32,},
- {2, SNDRV_PCM_FORMAT_S16_LE, 44100, 11289600,
- WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
- {2, SNDRV_PCM_FORMAT_S16_LE, 88200, 22579200,
- WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
-
- /* 24bit stereo modes */
- {2, SNDRV_PCM_FORMAT_S24_LE, 48000, 12288000,
- WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
- {2, SNDRV_PCM_FORMAT_S24_LE, 96000, 24576000,
- WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
- {2, SNDRV_PCM_FORMAT_S24_LE, 44100, 11289600,
- WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
- {2, SNDRV_PCM_FORMAT_S24_LE, 88200, 22579200,
- WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
-};
-
-static int wm1133_ev1_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int i, found = 0;
- snd_pcm_format_t format = params_format(params);
- unsigned int rate = params_rate(params);
- unsigned int channels = params_channels(params);
- u32 dai_format;
-
- /* find the correct audio parameters */
- for (i = 0; i < ARRAY_SIZE(wm8350_audio); i++) {
- if (rate == wm8350_audio[i].rate &&
- format == wm8350_audio[i].format &&
- channels == wm8350_audio[i].channels) {
- found = 1;
- break;
- }
- }
- if (!found)
- return -EINVAL;
-
- /* codec FLL input is 14.75 MHz from MCLK */
- snd_soc_dai_set_pll(codec_dai, 0, 0, 14750000, wm8350_audio[i].sysclk);
-
- dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM;
-
- /* set codec DAI configuration */
- snd_soc_dai_set_fmt(codec_dai, dai_format);
-
- /* set cpu DAI configuration */
- snd_soc_dai_set_fmt(cpu_dai, dai_format);
-
- /* TODO: The SSI driver should figure this out for us */
- switch (channels) {
- case 2:
- snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffc, 0xffffffc, 2, 0);
- break;
- case 1:
- snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffe, 0xffffffe, 1, 0);
- break;
- default:
- return -EINVAL;
- }
-
- /* set MCLK as the codec system clock for DAC and ADC */
- snd_soc_dai_set_sysclk(codec_dai, WM8350_MCLK_SEL_PLL_MCLK,
- wm8350_audio[i].sysclk, SND_SOC_CLOCK_IN);
-
- /* set codec BCLK division for sample rate */
- snd_soc_dai_set_clkdiv(codec_dai, WM8350_BCLK_CLKDIV,
- wm8350_audio[i].bclkdiv);
-
- /* DAI is synchronous and clocked with DAC LRCLK & ADC LRC */
- snd_soc_dai_set_clkdiv(codec_dai,
- WM8350_DACLR_CLKDIV, wm8350_audio[i].lr_rate);
- snd_soc_dai_set_clkdiv(codec_dai,
- WM8350_ADCLR_CLKDIV, wm8350_audio[i].lr_rate);
-
- /* now configure DAC and ADC clocks */
- snd_soc_dai_set_clkdiv(codec_dai,
- WM8350_DAC_CLKDIV, wm8350_audio[i].clkdiv);
-
- snd_soc_dai_set_clkdiv(codec_dai,
- WM8350_ADC_CLKDIV, wm8350_audio[i].clkdiv);
-
- return 0;
-}
-
-static struct snd_soc_ops wm1133_ev1_ops = {
- .hw_params = wm1133_ev1_hw_params,
-};
-
-static const struct snd_soc_dapm_widget wm1133_ev1_widgets[] = {
-#ifdef USE_SIMIC
- SND_SOC_DAPM_MIC("SiMIC", NULL),
-#endif
- SND_SOC_DAPM_MIC("Mic1 Jack", NULL),
- SND_SOC_DAPM_MIC("Mic2 Jack", NULL),
- SND_SOC_DAPM_LINE("Line In Jack", NULL),
- SND_SOC_DAPM_LINE("Line Out Jack", NULL),
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
-};
-
-/* imx32ads soc_card audio map */
-static const struct snd_soc_dapm_route wm1133_ev1_map[] = {
-
-#ifdef USE_SIMIC
- /* SiMIC --> IN1LN (with automatic bias) via SP1 */
- { "IN1LN", NULL, "Mic Bias" },
- { "Mic Bias", NULL, "SiMIC" },
-#endif
-
- /* Mic 1 Jack --> IN1LN and IN1LP (with automatic bias) */
- { "IN1LN", NULL, "Mic Bias" },
- { "IN1LP", NULL, "Mic1 Jack" },
- { "Mic Bias", NULL, "Mic1 Jack" },
-
- /* Mic 2 Jack --> IN1RN and IN1RP (with automatic bias) */
- { "IN1RN", NULL, "Mic Bias" },
- { "IN1RP", NULL, "Mic2 Jack" },
- { "Mic Bias", NULL, "Mic2 Jack" },
-
- /* Line in Jack --> AUX (L+R) */
- { "IN3R", NULL, "Line In Jack" },
- { "IN3L", NULL, "Line In Jack" },
-
- /* Out1 --> Headphone Jack */
- { "Headphone Jack", NULL, "OUT1R" },
- { "Headphone Jack", NULL, "OUT1L" },
-
- /* Out1 --> Line Out Jack */
- { "Line Out Jack", NULL, "OUT2R" },
- { "Line Out Jack", NULL, "OUT2L" },
-};
-
-static struct snd_soc_jack hp_jack;
-
-static struct snd_soc_jack_pin hp_jack_pins[] = {
- { .pin = "Headphone Jack", .mask = SND_JACK_HEADPHONE },
-};
-
-static struct snd_soc_jack mic_jack;
-
-static struct snd_soc_jack_pin mic_jack_pins[] = {
- { .pin = "Mic1 Jack", .mask = SND_JACK_MICROPHONE },
- { .pin = "Mic2 Jack", .mask = SND_JACK_MICROPHONE },
-};
-
-static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_new_controls(dapm, wm1133_ev1_widgets,
- ARRAY_SIZE(wm1133_ev1_widgets));
-
- snd_soc_dapm_add_routes(dapm, wm1133_ev1_map,
- ARRAY_SIZE(wm1133_ev1_map));
-
- /* Headphone jack detection */
- snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, &hp_jack);
- snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins),
- hp_jack_pins);
- wm8350_hp_jack_detect(codec, WM8350_JDR, &hp_jack, SND_JACK_HEADPHONE);
-
- /* Microphone jack detection */
- snd_soc_jack_new(codec, "Microphone",
- SND_JACK_MICROPHONE | SND_JACK_BTN_0, &mic_jack);
- snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins),
- mic_jack_pins);
- wm8350_mic_jack_detect(codec, &mic_jack, SND_JACK_MICROPHONE,
- SND_JACK_BTN_0);
-
- snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
-
- return 0;
-}
-
-
-static struct snd_soc_dai_link wm1133_ev1_dai = {
- .name = "WM1133-EV1",
- .stream_name = "Audio",
- .cpu_dai_name = "imx-ssi.0",
- .codec_dai_name = "wm8350-hifi",
- .platform_name = "imx-fiq-pcm-audio.0",
- .codec_name = "wm8350-codec.0-0x1a",
- .init = wm1133_ev1_init,
- .ops = &wm1133_ev1_ops,
- .symmetric_rates = 1,
-};
-
-static struct snd_soc_card wm1133_ev1 = {
- .name = "WM1133-EV1",
- .owner = THIS_MODULE,
- .dai_link = &wm1133_ev1_dai,
- .num_links = 1,
-};
-
-static struct platform_device *wm1133_ev1_snd_device;
-
-static int __init wm1133_ev1_audio_init(void)
-{
- int ret;
- unsigned int ptcr, pdcr;
-
- /* SSI0 mastered by port 5 */
- ptcr = IMX_AUDMUX_V2_PTCR_SYN |
- IMX_AUDMUX_V2_PTCR_TFSDIR |
- IMX_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT5_SSI_PINS_5) |
- IMX_AUDMUX_V2_PTCR_TCLKDIR |
- IMX_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT5_SSI_PINS_5);
- pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT5_SSI_PINS_5);
- imx_audmux_v2_configure_port(MX31_AUDMUX_PORT1_SSI0, ptcr, pdcr);
-
- ptcr = IMX_AUDMUX_V2_PTCR_SYN;
- pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0);
- imx_audmux_v2_configure_port(MX31_AUDMUX_PORT5_SSI_PINS_5, ptcr, pdcr);
-
- wm1133_ev1_snd_device = platform_device_alloc("soc-audio", -1);
- if (!wm1133_ev1_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(wm1133_ev1_snd_device, &wm1133_ev1);
- ret = platform_device_add(wm1133_ev1_snd_device);
-
- if (ret)
- platform_device_put(wm1133_ev1_snd_device);
-
- return ret;
-}
-module_init(wm1133_ev1_audio_init);
-
-static void __exit wm1133_ev1_audio_exit(void)
-{
- platform_device_unregister(wm1133_ev1_snd_device);
-}
-module_exit(wm1133_ev1_audio_exit);
-
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_DESCRIPTION("Audio for WM1133-EV1 on i.MX31ADS");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/jz4740/Kconfig b/ANDROID_3.4.5/sound/soc/jz4740/Kconfig
deleted file mode 100644
index 5351cba6..00000000
--- a/ANDROID_3.4.5/sound/soc/jz4740/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-config SND_JZ4740_SOC
- tristate "SoC Audio for Ingenic JZ4740 SoC"
- depends on MACH_JZ4740 && SND_SOC
- help
- Say Y or M if you want to add support for codecs attached to
- the JZ4740 I2S interface. You will also need to select the audio
- interfaces to support below.
-
-config SND_JZ4740_SOC_I2S
- depends on SND_JZ4740_SOC
- tristate "SoC Audio (I2S protocol) for Ingenic JZ4740 SoC"
- help
- Say Y if you want to use I2S protocol and I2S codec on Ingenic JZ4740
- based boards.
-
-config SND_JZ4740_SOC_QI_LB60
- tristate "SoC Audio support for Qi LB60"
- depends on SND_JZ4740_SOC && JZ4740_QI_LB60
- select SND_JZ4740_SOC_I2S
- select SND_SOC_JZ4740_CODEC
- help
- Say Y if you want to add support for ASoC audio on the Qi LB60 board
- a.k.a Qi Ben NanoNote.
diff --git a/ANDROID_3.4.5/sound/soc/jz4740/Makefile b/ANDROID_3.4.5/sound/soc/jz4740/Makefile
deleted file mode 100644
index be873c1b..00000000
--- a/ANDROID_3.4.5/sound/soc/jz4740/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# Jz4740 Platform Support
-#
-snd-soc-jz4740-objs := jz4740-pcm.o
-snd-soc-jz4740-i2s-objs := jz4740-i2s.o
-
-obj-$(CONFIG_SND_JZ4740_SOC) += snd-soc-jz4740.o
-obj-$(CONFIG_SND_JZ4740_SOC_I2S) += snd-soc-jz4740-i2s.o
-
-# Jz4740 Machine Support
-snd-soc-qi-lb60-objs := qi_lb60.o
-
-obj-$(CONFIG_SND_JZ4740_SOC_QI_LB60) += snd-soc-qi-lb60.o
diff --git a/ANDROID_3.4.5/sound/soc/jz4740/jz4740-i2s.c b/ANDROID_3.4.5/sound/soc/jz4740/jz4740-i2s.c
deleted file mode 100644
index a5af7c42..00000000
--- a/ANDROID_3.4.5/sound/soc/jz4740/jz4740-i2s.c
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-
-#include <linux/dma-mapping.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-
-#include "jz4740-i2s.h"
-#include "jz4740-pcm.h"
-
-#define JZ_REG_AIC_CONF 0x00
-#define JZ_REG_AIC_CTRL 0x04
-#define JZ_REG_AIC_I2S_FMT 0x10
-#define JZ_REG_AIC_FIFO_STATUS 0x14
-#define JZ_REG_AIC_I2S_STATUS 0x1c
-#define JZ_REG_AIC_CLK_DIV 0x30
-#define JZ_REG_AIC_FIFO 0x34
-
-#define JZ_AIC_CONF_FIFO_RX_THRESHOLD_MASK (0xf << 12)
-#define JZ_AIC_CONF_FIFO_TX_THRESHOLD_MASK (0xf << 8)
-#define JZ_AIC_CONF_OVERFLOW_PLAY_LAST BIT(6)
-#define JZ_AIC_CONF_INTERNAL_CODEC BIT(5)
-#define JZ_AIC_CONF_I2S BIT(4)
-#define JZ_AIC_CONF_RESET BIT(3)
-#define JZ_AIC_CONF_BIT_CLK_MASTER BIT(2)
-#define JZ_AIC_CONF_SYNC_CLK_MASTER BIT(1)
-#define JZ_AIC_CONF_ENABLE BIT(0)
-
-#define JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 12
-#define JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 8
-
-#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK (0x7 << 19)
-#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK (0x7 << 16)
-#define JZ_AIC_CTRL_ENABLE_RX_DMA BIT(15)
-#define JZ_AIC_CTRL_ENABLE_TX_DMA BIT(14)
-#define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11)
-#define JZ_AIC_CTRL_SWITCH_ENDIANNESS BIT(10)
-#define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED BIT(9)
-#define JZ_AIC_CTRL_FLUSH BIT(8)
-#define JZ_AIC_CTRL_ENABLE_ROR_INT BIT(6)
-#define JZ_AIC_CTRL_ENABLE_TUR_INT BIT(5)
-#define JZ_AIC_CTRL_ENABLE_RFS_INT BIT(4)
-#define JZ_AIC_CTRL_ENABLE_TFS_INT BIT(3)
-#define JZ_AIC_CTRL_ENABLE_LOOPBACK BIT(2)
-#define JZ_AIC_CTRL_ENABLE_PLAYBACK BIT(1)
-#define JZ_AIC_CTRL_ENABLE_CAPTURE BIT(0)
-
-#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_OFFSET 19
-#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET 16
-
-#define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK BIT(12)
-#define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK BIT(4)
-#define JZ_AIC_I2S_FMT_MSB BIT(0)
-
-#define JZ_AIC_I2S_STATUS_BUSY BIT(2)
-
-#define JZ_AIC_CLK_DIV_MASK 0xf
-
-struct jz4740_i2s {
- struct resource *mem;
- void __iomem *base;
- dma_addr_t phys_base;
-
- struct clk *clk_aic;
- struct clk *clk_i2s;
-
- struct jz4740_pcm_config pcm_config_playback;
- struct jz4740_pcm_config pcm_config_capture;
-};
-
-static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s,
- unsigned int reg)
-{
- return readl(i2s->base + reg);
-}
-
-static inline void jz4740_i2s_write(const struct jz4740_i2s *i2s,
- unsigned int reg, uint32_t value)
-{
- writel(value, i2s->base + reg);
-}
-
-static int jz4740_i2s_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
- uint32_t conf, ctrl;
-
- if (dai->active)
- return 0;
-
- ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
- ctrl |= JZ_AIC_CTRL_FLUSH;
- jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
-
- clk_enable(i2s->clk_i2s);
-
- conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
- conf |= JZ_AIC_CONF_ENABLE;
- jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
-
- return 0;
-}
-
-static void jz4740_i2s_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
- uint32_t conf;
-
- if (dai->active)
- return;
-
- conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
- conf &= ~JZ_AIC_CONF_ENABLE;
- jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
-
- clk_disable(i2s->clk_i2s);
-}
-
-static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-
- uint32_t ctrl;
- uint32_t mask;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- mask = JZ_AIC_CTRL_ENABLE_PLAYBACK | JZ_AIC_CTRL_ENABLE_TX_DMA;
- else
- mask = JZ_AIC_CTRL_ENABLE_CAPTURE | JZ_AIC_CTRL_ENABLE_RX_DMA;
-
- ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- ctrl |= mask;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- ctrl &= ~mask;
- break;
- default:
- return -EINVAL;
- }
-
- jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
-
- return 0;
-}
-
-static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-
- uint32_t format = 0;
- uint32_t conf;
-
- conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
-
- conf &= ~(JZ_AIC_CONF_BIT_CLK_MASTER | JZ_AIC_CONF_SYNC_CLK_MASTER);
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- conf |= JZ_AIC_CONF_BIT_CLK_MASTER | JZ_AIC_CONF_SYNC_CLK_MASTER;
- format |= JZ_AIC_I2S_FMT_ENABLE_SYS_CLK;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- conf |= JZ_AIC_CONF_SYNC_CLK_MASTER;
- break;
- case SND_SOC_DAIFMT_CBS_CFM:
- conf |= JZ_AIC_CONF_BIT_CLK_MASTER;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_MSB:
- format |= JZ_AIC_I2S_FMT_MSB;
- break;
- case SND_SOC_DAIFMT_I2S:
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- default:
- return -EINVAL;
- }
-
- jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
- jz4740_i2s_write(i2s, JZ_REG_AIC_I2S_FMT, format);
-
- return 0;
-}
-
-static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
-{
- struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
- enum jz4740_dma_width dma_width;
- struct jz4740_pcm_config *pcm_config;
- unsigned int sample_size;
- uint32_t ctrl;
-
- ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S8:
- sample_size = 0;
- dma_width = JZ4740_DMA_WIDTH_8BIT;
- break;
- case SNDRV_PCM_FORMAT_S16:
- sample_size = 1;
- dma_width = JZ4740_DMA_WIDTH_16BIT;
- break;
- default:
- return -EINVAL;
- }
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- ctrl &= ~JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK;
- ctrl |= sample_size << JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_OFFSET;
- if (params_channels(params) == 1)
- ctrl |= JZ_AIC_CTRL_MONO_TO_STEREO;
- else
- ctrl &= ~JZ_AIC_CTRL_MONO_TO_STEREO;
-
- pcm_config = &i2s->pcm_config_playback;
- pcm_config->dma_config.dst_width = dma_width;
-
- } else {
- ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK;
- ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET;
-
- pcm_config = &i2s->pcm_config_capture;
- pcm_config->dma_config.src_width = dma_width;
- }
-
- jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
-
- snd_soc_dai_set_dma_data(dai, substream, pcm_config);
-
- return 0;
-}
-
-static int jz4740_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
- unsigned int freq, int dir)
-{
- struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
- struct clk *parent;
- int ret = 0;
-
- switch (clk_id) {
- case JZ4740_I2S_CLKSRC_EXT:
- parent = clk_get(NULL, "ext");
- clk_set_parent(i2s->clk_i2s, parent);
- break;
- case JZ4740_I2S_CLKSRC_PLL:
- parent = clk_get(NULL, "pll half");
- clk_set_parent(i2s->clk_i2s, parent);
- ret = clk_set_rate(i2s->clk_i2s, freq);
- break;
- default:
- return -EINVAL;
- }
- clk_put(parent);
-
- return ret;
-}
-
-static int jz4740_i2s_suspend(struct snd_soc_dai *dai)
-{
- struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
- uint32_t conf;
-
- if (dai->active) {
- conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
- conf &= ~JZ_AIC_CONF_ENABLE;
- jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
-
- clk_disable(i2s->clk_i2s);
- }
-
- clk_disable(i2s->clk_aic);
-
- return 0;
-}
-
-static int jz4740_i2s_resume(struct snd_soc_dai *dai)
-{
- struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
- uint32_t conf;
-
- clk_enable(i2s->clk_aic);
-
- if (dai->active) {
- clk_enable(i2s->clk_i2s);
-
- conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
- conf |= JZ_AIC_CONF_ENABLE;
- jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
- }
-
- return 0;
-}
-
-static void jz4740_i2c_init_pcm_config(struct jz4740_i2s *i2s)
-{
- struct jz4740_dma_config *dma_config;
-
- /* Playback */
- dma_config = &i2s->pcm_config_playback.dma_config;
- dma_config->src_width = JZ4740_DMA_WIDTH_32BIT,
- dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE;
- dma_config->request_type = JZ4740_DMA_TYPE_AIC_TRANSMIT;
- dma_config->flags = JZ4740_DMA_SRC_AUTOINC;
- dma_config->mode = JZ4740_DMA_MODE_SINGLE;
- i2s->pcm_config_playback.fifo_addr = i2s->phys_base + JZ_REG_AIC_FIFO;
-
- /* Capture */
- dma_config = &i2s->pcm_config_capture.dma_config;
- dma_config->dst_width = JZ4740_DMA_WIDTH_32BIT,
- dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE;
- dma_config->request_type = JZ4740_DMA_TYPE_AIC_RECEIVE;
- dma_config->flags = JZ4740_DMA_DST_AUTOINC;
- dma_config->mode = JZ4740_DMA_MODE_SINGLE;
- i2s->pcm_config_capture.fifo_addr = i2s->phys_base + JZ_REG_AIC_FIFO;
-}
-
-static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
-{
- struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
- uint32_t conf;
-
- clk_enable(i2s->clk_aic);
-
- jz4740_i2c_init_pcm_config(i2s);
-
- conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
- (8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
- JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
- JZ_AIC_CONF_I2S |
- JZ_AIC_CONF_INTERNAL_CODEC;
-
- jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
- jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
-
- return 0;
-}
-
-static int jz4740_i2s_dai_remove(struct snd_soc_dai *dai)
-{
- struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-
- clk_disable(i2s->clk_aic);
- return 0;
-}
-
-static const struct snd_soc_dai_ops jz4740_i2s_dai_ops = {
- .startup = jz4740_i2s_startup,
- .shutdown = jz4740_i2s_shutdown,
- .trigger = jz4740_i2s_trigger,
- .hw_params = jz4740_i2s_hw_params,
- .set_fmt = jz4740_i2s_set_fmt,
- .set_sysclk = jz4740_i2s_set_sysclk,
-};
-
-#define JZ4740_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \
- SNDRV_PCM_FMTBIT_S16_LE)
-
-static struct snd_soc_dai_driver jz4740_i2s_dai = {
- .probe = jz4740_i2s_dai_probe,
- .remove = jz4740_i2s_dai_remove,
- .playback = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = JZ4740_I2S_FMTS,
- },
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = JZ4740_I2S_FMTS,
- },
- .symmetric_rates = 1,
- .ops = &jz4740_i2s_dai_ops,
- .suspend = jz4740_i2s_suspend,
- .resume = jz4740_i2s_resume,
-};
-
-static int __devinit jz4740_i2s_dev_probe(struct platform_device *pdev)
-{
- struct jz4740_i2s *i2s;
- int ret;
-
- i2s = kzalloc(sizeof(*i2s), GFP_KERNEL);
-
- if (!i2s)
- return -ENOMEM;
-
- i2s->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!i2s->mem) {
- ret = -ENOENT;
- goto err_free;
- }
-
- i2s->mem = request_mem_region(i2s->mem->start, resource_size(i2s->mem),
- pdev->name);
- if (!i2s->mem) {
- ret = -EBUSY;
- goto err_free;
- }
-
- i2s->base = ioremap_nocache(i2s->mem->start, resource_size(i2s->mem));
- if (!i2s->base) {
- ret = -EBUSY;
- goto err_release_mem_region;
- }
-
- i2s->phys_base = i2s->mem->start;
-
- i2s->clk_aic = clk_get(&pdev->dev, "aic");
- if (IS_ERR(i2s->clk_aic)) {
- ret = PTR_ERR(i2s->clk_aic);
- goto err_iounmap;
- }
-
- i2s->clk_i2s = clk_get(&pdev->dev, "i2s");
- if (IS_ERR(i2s->clk_i2s)) {
- ret = PTR_ERR(i2s->clk_i2s);
- goto err_clk_put_aic;
- }
-
- platform_set_drvdata(pdev, i2s);
- ret = snd_soc_register_dai(&pdev->dev, &jz4740_i2s_dai);
-
- if (ret) {
- dev_err(&pdev->dev, "Failed to register DAI\n");
- goto err_clk_put_i2s;
- }
-
- return 0;
-
-err_clk_put_i2s:
- clk_put(i2s->clk_i2s);
-err_clk_put_aic:
- clk_put(i2s->clk_aic);
-err_iounmap:
- iounmap(i2s->base);
-err_release_mem_region:
- release_mem_region(i2s->mem->start, resource_size(i2s->mem));
-err_free:
- kfree(i2s);
-
- return ret;
-}
-
-static int __devexit jz4740_i2s_dev_remove(struct platform_device *pdev)
-{
- struct jz4740_i2s *i2s = platform_get_drvdata(pdev);
-
- snd_soc_unregister_dai(&pdev->dev);
-
- clk_put(i2s->clk_i2s);
- clk_put(i2s->clk_aic);
-
- iounmap(i2s->base);
- release_mem_region(i2s->mem->start, resource_size(i2s->mem));
-
- platform_set_drvdata(pdev, NULL);
- kfree(i2s);
-
- return 0;
-}
-
-static struct platform_driver jz4740_i2s_driver = {
- .probe = jz4740_i2s_dev_probe,
- .remove = __devexit_p(jz4740_i2s_dev_remove),
- .driver = {
- .name = "jz4740-i2s",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(jz4740_i2s_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen, <lars@metafoo.de>");
-MODULE_DESCRIPTION("Ingenic JZ4740 SoC I2S driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:jz4740-i2s");
diff --git a/ANDROID_3.4.5/sound/soc/jz4740/jz4740-i2s.h b/ANDROID_3.4.5/sound/soc/jz4740/jz4740-i2s.h
deleted file mode 100644
index 5e49339d..00000000
--- a/ANDROID_3.4.5/sound/soc/jz4740/jz4740-i2s.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _JZ4740_I2S_H
-#define _JZ4740_I2S_H
-
-/* I2S clock source */
-#define JZ4740_I2S_CLKSRC_EXT 0
-#define JZ4740_I2S_CLKSRC_PLL 1
-
-#define JZ4740_I2S_BIT_CLK 0
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/jz4740/jz4740-pcm.c b/ANDROID_3.4.5/sound/soc/jz4740/jz4740-pcm.c
deleted file mode 100644
index 9b8cf256..00000000
--- a/ANDROID_3.4.5/sound/soc/jz4740/jz4740-pcm.c
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <linux/dma-mapping.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/mach-jz4740/dma.h>
-#include "jz4740-pcm.h"
-
-struct jz4740_runtime_data {
- unsigned long dma_period;
- dma_addr_t dma_start;
- dma_addr_t dma_pos;
- dma_addr_t dma_end;
-
- struct jz4740_dma_chan *dma;
-
- dma_addr_t fifo_addr;
-};
-
-/* identify hardware playback capabilities */
-static const struct snd_pcm_hardware jz4740_pcm_hardware = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8,
-
- .rates = SNDRV_PCM_RATE_8000_48000,
- .channels_min = 1,
- .channels_max = 2,
- .period_bytes_min = 16,
- .period_bytes_max = 2 * PAGE_SIZE,
- .periods_min = 2,
- .periods_max = 128,
- .buffer_bytes_max = 128 * 2 * PAGE_SIZE,
- .fifo_size = 32,
-};
-
-static void jz4740_pcm_start_transfer(struct jz4740_runtime_data *prtd,
- struct snd_pcm_substream *substream)
-{
- unsigned long count;
-
- if (prtd->dma_pos == prtd->dma_end)
- prtd->dma_pos = prtd->dma_start;
-
- if (prtd->dma_pos + prtd->dma_period > prtd->dma_end)
- count = prtd->dma_end - prtd->dma_pos;
- else
- count = prtd->dma_period;
-
- jz4740_dma_disable(prtd->dma);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- jz4740_dma_set_src_addr(prtd->dma, prtd->dma_pos);
- jz4740_dma_set_dst_addr(prtd->dma, prtd->fifo_addr);
- } else {
- jz4740_dma_set_src_addr(prtd->dma, prtd->fifo_addr);
- jz4740_dma_set_dst_addr(prtd->dma, prtd->dma_pos);
- }
-
- jz4740_dma_set_transfer_count(prtd->dma, count);
-
- prtd->dma_pos += count;
-
- jz4740_dma_enable(prtd->dma);
-}
-
-static void jz4740_pcm_dma_transfer_done(struct jz4740_dma_chan *dma, int err,
- void *dev_id)
-{
- struct snd_pcm_substream *substream = dev_id;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct jz4740_runtime_data *prtd = runtime->private_data;
-
- snd_pcm_period_elapsed(substream);
-
- jz4740_pcm_start_transfer(prtd, substream);
-}
-
-static int jz4740_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct jz4740_runtime_data *prtd = runtime->private_data;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct jz4740_pcm_config *config;
-
- config = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
- if (!config)
- return 0;
-
- if (!prtd->dma) {
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- prtd->dma = jz4740_dma_request(substream, "PCM Capture");
- else
- prtd->dma = jz4740_dma_request(substream, "PCM Playback");
- }
-
- if (!prtd->dma)
- return -EBUSY;
-
- jz4740_dma_configure(prtd->dma, &config->dma_config);
- prtd->fifo_addr = config->fifo_addr;
-
- jz4740_dma_set_complete_cb(prtd->dma, jz4740_pcm_dma_transfer_done);
-
- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
- runtime->dma_bytes = params_buffer_bytes(params);
-
- prtd->dma_period = params_period_bytes(params);
- prtd->dma_start = runtime->dma_addr;
- prtd->dma_pos = prtd->dma_start;
- prtd->dma_end = prtd->dma_start + runtime->dma_bytes;
-
- return 0;
-}
-
-static int jz4740_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct jz4740_runtime_data *prtd = substream->runtime->private_data;
-
- snd_pcm_set_runtime_buffer(substream, NULL);
- if (prtd->dma) {
- jz4740_dma_free(prtd->dma);
- prtd->dma = NULL;
- }
-
- return 0;
-}
-
-static int jz4740_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct jz4740_runtime_data *prtd = substream->runtime->private_data;
-
- if (!prtd->dma)
- return -EBUSY;
-
- prtd->dma_pos = prtd->dma_start;
-
- return 0;
-}
-
-static int jz4740_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct jz4740_runtime_data *prtd = runtime->private_data;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- jz4740_pcm_start_transfer(prtd, substream);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- jz4740_dma_disable(prtd->dma);
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-static snd_pcm_uframes_t jz4740_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct jz4740_runtime_data *prtd = runtime->private_data;
- unsigned long byte_offset;
- snd_pcm_uframes_t offset;
- struct jz4740_dma_chan *dma = prtd->dma;
-
- /* prtd->dma_pos points to the end of the current transfer. So by
- * subtracting prdt->dma_start we get the offset to the end of the
- * current period in bytes. By subtracting the residue of the transfer
- * we get the current offset in bytes. */
- byte_offset = prtd->dma_pos - prtd->dma_start;
- byte_offset -= jz4740_dma_get_residue(dma);
-
- offset = bytes_to_frames(runtime, byte_offset);
- if (offset >= runtime->buffer_size)
- offset = 0;
-
- return offset;
-}
-
-static int jz4740_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct jz4740_runtime_data *prtd;
-
- prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
- if (prtd == NULL)
- return -ENOMEM;
-
- snd_soc_set_runtime_hwparams(substream, &jz4740_pcm_hardware);
-
- runtime->private_data = prtd;
-
- return 0;
-}
-
-static int jz4740_pcm_close(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct jz4740_runtime_data *prtd = runtime->private_data;
-
- kfree(prtd);
-
- return 0;
-}
-
-static int jz4740_pcm_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- return remap_pfn_range(vma, vma->vm_start,
- substream->dma_buffer.addr >> PAGE_SHIFT,
- vma->vm_end - vma->vm_start, vma->vm_page_prot);
-}
-
-static struct snd_pcm_ops jz4740_pcm_ops = {
- .open = jz4740_pcm_open,
- .close = jz4740_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = jz4740_pcm_hw_params,
- .hw_free = jz4740_pcm_hw_free,
- .prepare = jz4740_pcm_prepare,
- .trigger = jz4740_pcm_trigger,
- .pointer = jz4740_pcm_pointer,
- .mmap = jz4740_pcm_mmap,
-};
-
-static int jz4740_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
- struct snd_pcm_substream *substream = pcm->streams[stream].substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = jz4740_pcm_hardware.buffer_bytes_max;
-
- buf->dev.type = SNDRV_DMA_TYPE_DEV;
- buf->dev.dev = pcm->card->dev;
- buf->private_data = NULL;
-
- buf->area = dma_alloc_noncoherent(pcm->card->dev, size,
- &buf->addr, GFP_KERNEL);
- if (!buf->area)
- return -ENOMEM;
-
- buf->bytes = size;
-
- return 0;
-}
-
-static void jz4740_pcm_free(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- struct snd_dma_buffer *buf;
- int stream;
-
- for (stream = 0; stream < SNDRV_PCM_STREAM_LAST; ++stream) {
- substream = pcm->streams[stream].substream;
- if (!substream)
- continue;
-
- buf = &substream->dma_buffer;
- if (!buf->area)
- continue;
-
- dma_free_noncoherent(pcm->card->dev, buf->bytes, buf->area,
- buf->addr);
- buf->area = NULL;
- }
-}
-
-static u64 jz4740_pcm_dmamask = DMA_BIT_MASK(32);
-
-static int jz4740_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- int ret = 0;
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &jz4740_pcm_dmamask;
-
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = jz4740_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_PLAYBACK);
- if (ret)
- goto err;
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- ret = jz4740_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_CAPTURE);
- if (ret)
- goto err;
- }
-
-err:
- return ret;
-}
-
-static struct snd_soc_platform_driver jz4740_soc_platform = {
- .ops = &jz4740_pcm_ops,
- .pcm_new = jz4740_pcm_new,
- .pcm_free = jz4740_pcm_free,
-};
-
-static int __devinit jz4740_pcm_probe(struct platform_device *pdev)
-{
- return snd_soc_register_platform(&pdev->dev, &jz4740_soc_platform);
-}
-
-static int __devexit jz4740_pcm_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver jz4740_pcm_driver = {
- .probe = jz4740_pcm_probe,
- .remove = __devexit_p(jz4740_pcm_remove),
- .driver = {
- .name = "jz4740-pcm-audio",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(jz4740_pcm_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("Ingenic SoC JZ4740 PCM driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/jz4740/jz4740-pcm.h b/ANDROID_3.4.5/sound/soc/jz4740/jz4740-pcm.h
deleted file mode 100644
index 1220cbb4..00000000
--- a/ANDROID_3.4.5/sound/soc/jz4740/jz4740-pcm.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _JZ4740_PCM_H
-#define _JZ4740_PCM_H
-
-#include <linux/dma-mapping.h>
-#include <asm/mach-jz4740/dma.h>
-
-
-struct jz4740_pcm_config {
- struct jz4740_dma_config dma_config;
- phys_addr_t fifo_addr;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/jz4740/qi_lb60.c b/ANDROID_3.4.5/sound/soc/jz4740/qi_lb60.c
deleted file mode 100644
index e8aaff18..00000000
--- a/ANDROID_3.4.5/sound/soc/jz4740/qi_lb60.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <linux/gpio.h>
-
-#define QI_LB60_SND_GPIO JZ_GPIO_PORTB(29)
-#define QI_LB60_AMP_GPIO JZ_GPIO_PORTD(4)
-
-static int qi_lb60_spk_event(struct snd_soc_dapm_widget *widget,
- struct snd_kcontrol *ctrl, int event)
-{
- int on = !SND_SOC_DAPM_EVENT_OFF(event);
-
- gpio_set_value(QI_LB60_SND_GPIO, on);
- gpio_set_value(QI_LB60_AMP_GPIO, on);
-
- return 0;
-}
-
-static const struct snd_soc_dapm_widget qi_lb60_widgets[] = {
- SND_SOC_DAPM_SPK("Speaker", qi_lb60_spk_event),
- SND_SOC_DAPM_MIC("Mic", NULL),
-};
-
-static const struct snd_soc_dapm_route qi_lb60_routes[] = {
- {"Mic", NULL, "MIC"},
- {"Speaker", NULL, "LOUT"},
- {"Speaker", NULL, "ROUT"},
-};
-
-#define QI_LB60_DAIFMT (SND_SOC_DAIFMT_I2S | \
- SND_SOC_DAIFMT_NB_NF | \
- SND_SOC_DAIFMT_CBM_CFM)
-
-static int qi_lb60_codec_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret;
-
- snd_soc_dapm_nc_pin(dapm, "LIN");
- snd_soc_dapm_nc_pin(dapm, "RIN");
-
- ret = snd_soc_dai_set_fmt(cpu_dai, QI_LB60_DAIFMT);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cpu dai format: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_soc_dai_link qi_lb60_dai = {
- .name = "jz4740",
- .stream_name = "jz4740",
- .cpu_dai_name = "jz4740-i2s",
- .platform_name = "jz4740-pcm-audio",
- .codec_dai_name = "jz4740-hifi",
- .codec_name = "jz4740-codec",
- .init = qi_lb60_codec_init,
-};
-
-static struct snd_soc_card qi_lb60 = {
- .name = "QI LB60",
- .owner = THIS_MODULE,
- .dai_link = &qi_lb60_dai,
- .num_links = 1,
-
- .dapm_widgets = qi_lb60_widgets,
- .num_dapm_widgets = ARRAY_SIZE(qi_lb60_widgets),
- .dapm_routes = qi_lb60_routes,
- .num_dapm_routes = ARRAY_SIZE(qi_lb60_routes),
-};
-
-static const struct gpio qi_lb60_gpios[] = {
- { QI_LB60_SND_GPIO, GPIOF_OUT_INIT_LOW, "SND" },
- { QI_LB60_AMP_GPIO, GPIOF_OUT_INIT_LOW, "AMP" },
-};
-
-static int __devinit qi_lb60_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &qi_lb60;
- int ret;
-
- ret = gpio_request_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
- if (ret)
- return ret;
-
- card->dev = &pdev->dev;
-
- ret = snd_soc_register_card(card);
- if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
- ret);
- gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
- }
- return ret;
-}
-
-static int __devexit qi_lb60_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- snd_soc_unregister_card(card);
- gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
- return 0;
-}
-
-static struct platform_driver qi_lb60_driver = {
- .driver = {
- .name = "qi-lb60-audio",
- .owner = THIS_MODULE,
- },
- .probe = qi_lb60_probe,
- .remove = __devexit_p(qi_lb60_remove),
-};
-
-module_platform_driver(qi_lb60_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("ALSA SoC QI LB60 Audio support");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:qi-lb60-audio");
diff --git a/ANDROID_3.4.5/sound/soc/kirkwood/Kconfig b/ANDROID_3.4.5/sound/soc/kirkwood/Kconfig
deleted file mode 100644
index c62d7152..00000000
--- a/ANDROID_3.4.5/sound/soc/kirkwood/Kconfig
+++ /dev/null
@@ -1,30 +0,0 @@
-config SND_KIRKWOOD_SOC
- tristate "SoC Audio for the Marvell Kirkwood chip"
- depends on ARCH_KIRKWOOD
- help
- Say Y or M if you want to add support for codecs attached to
- the Kirkwood I2S interface. You will also need to select the
- audio interfaces to support below.
-
-config SND_KIRKWOOD_SOC_I2S
- tristate
-
-config SND_KIRKWOOD_SOC_OPENRD
- tristate "SoC Audio support for Kirkwood Openrd Client"
- depends on SND_KIRKWOOD_SOC && (MACH_OPENRD_CLIENT || MACH_OPENRD_ULTIMATE)
- depends on I2C
- select SND_KIRKWOOD_SOC_I2S
- select SND_SOC_CS42L51
- help
- Say Y if you want to add support for SoC audio on
- Openrd Client.
-
-config SND_KIRKWOOD_SOC_T5325
- tristate "SoC Audio support for HP t5325"
- depends on SND_KIRKWOOD_SOC && MACH_T5325 && I2C
- select SND_KIRKWOOD_SOC_I2S
- select SND_SOC_ALC5623
- help
- Say Y if you want to add support for SoC audio on
- the HP t5325 thin client.
-
diff --git a/ANDROID_3.4.5/sound/soc/kirkwood/Makefile b/ANDROID_3.4.5/sound/soc/kirkwood/Makefile
deleted file mode 100644
index 3e62ae9e..00000000
--- a/ANDROID_3.4.5/sound/soc/kirkwood/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-snd-soc-kirkwood-objs := kirkwood-dma.o
-snd-soc-kirkwood-i2s-objs := kirkwood-i2s.o
-
-obj-$(CONFIG_SND_KIRKWOOD_SOC) += snd-soc-kirkwood.o
-obj-$(CONFIG_SND_KIRKWOOD_SOC_I2S) += snd-soc-kirkwood-i2s.o
-
-snd-soc-openrd-objs := kirkwood-openrd.o
-snd-soc-t5325-objs := kirkwood-t5325.o
-
-obj-$(CONFIG_SND_KIRKWOOD_SOC_OPENRD) += snd-soc-openrd.o
-obj-$(CONFIG_SND_KIRKWOOD_SOC_T5325) += snd-soc-t5325.o
diff --git a/ANDROID_3.4.5/sound/soc/kirkwood/kirkwood-dma.c b/ANDROID_3.4.5/sound/soc/kirkwood/kirkwood-dma.c
deleted file mode 100644
index b9f16598..00000000
--- a/ANDROID_3.4.5/sound/soc/kirkwood/kirkwood-dma.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * kirkwood-dma.c
- *
- * (c) 2010 Arnaud Patard <apatard@mandriva.com>
- * (c) 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/dma-mapping.h>
-#include <linux/mbus.h>
-#include <sound/soc.h>
-#include "kirkwood.h"
-
-#define KIRKWOOD_RATES \
- (SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
-#define KIRKWOOD_FORMATS \
- (SNDRV_PCM_FMTBIT_S16_LE | \
- SNDRV_PCM_FMTBIT_S24_LE | \
- SNDRV_PCM_FMTBIT_S32_LE)
-
-struct kirkwood_dma_priv {
- struct snd_pcm_substream *play_stream;
- struct snd_pcm_substream *rec_stream;
- struct kirkwood_dma_data *data;
-};
-
-static struct snd_pcm_hardware kirkwood_dma_snd_hw = {
- .info = (SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_PAUSE),
- .formats = KIRKWOOD_FORMATS,
- .rates = KIRKWOOD_RATES,
- .rate_min = 44100,
- .rate_max = 96000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES * KIRKWOOD_SND_MAX_PERIODS,
- .period_bytes_min = KIRKWOOD_SND_MIN_PERIOD_BYTES,
- .period_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES,
- .periods_min = KIRKWOOD_SND_MIN_PERIODS,
- .periods_max = KIRKWOOD_SND_MAX_PERIODS,
- .fifo_size = 0,
-};
-
-static u64 kirkwood_dma_dmamask = DMA_BIT_MASK(32);
-
-static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id)
-{
- struct kirkwood_dma_priv *prdata = dev_id;
- struct kirkwood_dma_data *priv = prdata->data;
- unsigned long mask, status, cause;
-
- mask = readl(priv->io + KIRKWOOD_INT_MASK);
- status = readl(priv->io + KIRKWOOD_INT_CAUSE) & mask;
-
- cause = readl(priv->io + KIRKWOOD_ERR_CAUSE);
- if (unlikely(cause)) {
- printk(KERN_WARNING "%s: got err interrupt 0x%lx\n",
- __func__, cause);
- writel(cause, priv->io + KIRKWOOD_ERR_CAUSE);
- return IRQ_HANDLED;
- }
-
- /* we've enabled only bytes interrupts ... */
- if (status & ~(KIRKWOOD_INT_CAUSE_PLAY_BYTES | \
- KIRKWOOD_INT_CAUSE_REC_BYTES)) {
- printk(KERN_WARNING "%s: unexpected interrupt %lx\n",
- __func__, status);
- return IRQ_NONE;
- }
-
- /* ack int */
- writel(status, priv->io + KIRKWOOD_INT_CAUSE);
-
- if (status & KIRKWOOD_INT_CAUSE_PLAY_BYTES)
- snd_pcm_period_elapsed(prdata->play_stream);
-
- if (status & KIRKWOOD_INT_CAUSE_REC_BYTES)
- snd_pcm_period_elapsed(prdata->rec_stream);
-
- return IRQ_HANDLED;
-}
-
-static void
-kirkwood_dma_conf_mbus_windows(void __iomem *base, int win,
- unsigned long dma,
- const struct mbus_dram_target_info *dram)
-{
- int i;
-
- /* First disable and clear windows */
- writel(0, base + KIRKWOOD_AUDIO_WIN_CTRL_REG(win));
- writel(0, base + KIRKWOOD_AUDIO_WIN_BASE_REG(win));
-
- /* try to find matching cs for current dma address */
- for (i = 0; i < dram->num_cs; i++) {
- const struct mbus_dram_window *cs = dram->cs + i;
- if ((cs->base & 0xffff0000) < (dma & 0xffff0000)) {
- writel(cs->base & 0xffff0000,
- base + KIRKWOOD_AUDIO_WIN_BASE_REG(win));
- writel(((cs->size - 1) & 0xffff0000) |
- (cs->mbus_attr << 8) |
- (dram->mbus_dram_target_id << 4) | 1,
- base + KIRKWOOD_AUDIO_WIN_CTRL_REG(win));
- }
- }
-}
-
-static int kirkwood_dma_open(struct snd_pcm_substream *substream)
-{
- int err;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct snd_soc_platform *platform = soc_runtime->platform;
- struct snd_soc_dai *cpu_dai = soc_runtime->cpu_dai;
- struct kirkwood_dma_data *priv;
- struct kirkwood_dma_priv *prdata = snd_soc_platform_get_drvdata(platform);
- const struct mbus_dram_target_info *dram;
- unsigned long addr;
-
- priv = snd_soc_dai_get_dma_data(cpu_dai, substream);
- snd_soc_set_runtime_hwparams(substream, &kirkwood_dma_snd_hw);
-
- /* Ensure that all constraints linked to dma burst are fulfilled */
- err = snd_pcm_hw_constraint_minmax(runtime,
- SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
- priv->burst * 2,
- KIRKWOOD_AUDIO_BUF_MAX-1);
- if (err < 0)
- return err;
-
- err = snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
- priv->burst);
- if (err < 0)
- return err;
-
- err = snd_pcm_hw_constraint_step(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- priv->burst);
- if (err < 0)
- return err;
-
- if (prdata == NULL) {
- prdata = kzalloc(sizeof(struct kirkwood_dma_priv), GFP_KERNEL);
- if (prdata == NULL)
- return -ENOMEM;
-
- prdata->data = priv;
-
- err = request_irq(priv->irq, kirkwood_dma_irq, IRQF_SHARED,
- "kirkwood-i2s", prdata);
- if (err) {
- kfree(prdata);
- return -EBUSY;
- }
-
- snd_soc_platform_set_drvdata(platform, prdata);
-
- /*
- * Enable Error interrupts. We're only ack'ing them but
- * it's useful for diagnostics
- */
- writel((unsigned long)-1, priv->io + KIRKWOOD_ERR_MASK);
- }
-
- dram = mv_mbus_dram_info();
- addr = virt_to_phys(substream->dma_buffer.area);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- prdata->play_stream = substream;
- kirkwood_dma_conf_mbus_windows(priv->io,
- KIRKWOOD_PLAYBACK_WIN, addr, dram);
- } else {
- prdata->rec_stream = substream;
- kirkwood_dma_conf_mbus_windows(priv->io,
- KIRKWOOD_RECORD_WIN, addr, dram);
- }
-
- return 0;
-}
-
-static int kirkwood_dma_close(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct snd_soc_dai *cpu_dai = soc_runtime->cpu_dai;
- struct snd_soc_platform *platform = soc_runtime->platform;
- struct kirkwood_dma_priv *prdata = snd_soc_platform_get_drvdata(platform);
- struct kirkwood_dma_data *priv;
-
- priv = snd_soc_dai_get_dma_data(cpu_dai, substream);
-
- if (!prdata || !priv)
- return 0;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- prdata->play_stream = NULL;
- else
- prdata->rec_stream = NULL;
-
- if (!prdata->play_stream && !prdata->rec_stream) {
- writel(0, priv->io + KIRKWOOD_ERR_MASK);
- free_irq(priv->irq, prdata);
- kfree(prdata);
- snd_soc_platform_set_drvdata(platform, NULL);
- }
-
- return 0;
-}
-
-static int kirkwood_dma_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
- runtime->dma_bytes = params_buffer_bytes(params);
-
- return 0;
-}
-
-static int kirkwood_dma_hw_free(struct snd_pcm_substream *substream)
-{
- snd_pcm_set_runtime_buffer(substream, NULL);
- return 0;
-}
-
-static int kirkwood_dma_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct snd_soc_dai *cpu_dai = soc_runtime->cpu_dai;
- struct kirkwood_dma_data *priv;
- unsigned long size, count;
-
- priv = snd_soc_dai_get_dma_data(cpu_dai, substream);
-
- /* compute buffer size in term of "words" as requested in specs */
- size = frames_to_bytes(runtime, runtime->buffer_size);
- size = (size>>2)-1;
- count = snd_pcm_lib_period_bytes(substream);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- writel(count, priv->io + KIRKWOOD_PLAY_BYTE_INT_COUNT);
- writel(runtime->dma_addr, priv->io + KIRKWOOD_PLAY_BUF_ADDR);
- writel(size, priv->io + KIRKWOOD_PLAY_BUF_SIZE);
- } else {
- writel(count, priv->io + KIRKWOOD_REC_BYTE_INT_COUNT);
- writel(runtime->dma_addr, priv->io + KIRKWOOD_REC_BUF_ADDR);
- writel(size, priv->io + KIRKWOOD_REC_BUF_SIZE);
- }
-
-
- return 0;
-}
-
-static snd_pcm_uframes_t kirkwood_dma_pointer(struct snd_pcm_substream
- *substream)
-{
- struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct snd_soc_dai *cpu_dai = soc_runtime->cpu_dai;
- struct kirkwood_dma_data *priv;
- snd_pcm_uframes_t count;
-
- priv = snd_soc_dai_get_dma_data(cpu_dai, substream);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- count = bytes_to_frames(substream->runtime,
- readl(priv->io + KIRKWOOD_PLAY_BYTE_COUNT));
- else
- count = bytes_to_frames(substream->runtime,
- readl(priv->io + KIRKWOOD_REC_BYTE_COUNT));
-
- return count;
-}
-
-struct snd_pcm_ops kirkwood_dma_ops = {
- .open = kirkwood_dma_open,
- .close = kirkwood_dma_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = kirkwood_dma_hw_params,
- .hw_free = kirkwood_dma_hw_free,
- .prepare = kirkwood_dma_prepare,
- .pointer = kirkwood_dma_pointer,
-};
-
-static int kirkwood_dma_preallocate_dma_buffer(struct snd_pcm *pcm,
- int stream)
-{
- struct snd_pcm_substream *substream = pcm->streams[stream].substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = kirkwood_dma_snd_hw.buffer_bytes_max;
-
- buf->dev.type = SNDRV_DMA_TYPE_DEV;
- buf->dev.dev = pcm->card->dev;
- buf->area = dma_alloc_coherent(pcm->card->dev, size,
- &buf->addr, GFP_KERNEL);
- if (!buf->area)
- return -ENOMEM;
- buf->bytes = size;
- buf->private_data = NULL;
-
- return 0;
-}
-
-static int kirkwood_dma_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- int ret;
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &kirkwood_dma_dmamask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = kirkwood_dma_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_PLAYBACK);
- if (ret)
- return ret;
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- ret = kirkwood_dma_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_CAPTURE);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-static void kirkwood_dma_free_dma_buffers(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- struct snd_dma_buffer *buf;
- int stream;
-
- for (stream = 0; stream < 2; stream++) {
- substream = pcm->streams[stream].substream;
- if (!substream)
- continue;
- buf = &substream->dma_buffer;
- if (!buf->area)
- continue;
-
- dma_free_coherent(pcm->card->dev, buf->bytes,
- buf->area, buf->addr);
- buf->area = NULL;
- }
-}
-
-static struct snd_soc_platform_driver kirkwood_soc_platform = {
- .ops = &kirkwood_dma_ops,
- .pcm_new = kirkwood_dma_new,
- .pcm_free = kirkwood_dma_free_dma_buffers,
-};
-
-static int __devinit kirkwood_soc_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_platform(&pdev->dev, &kirkwood_soc_platform);
-}
-
-static int __devexit kirkwood_soc_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver kirkwood_pcm_driver = {
- .driver = {
- .name = "kirkwood-pcm-audio",
- .owner = THIS_MODULE,
- },
-
- .probe = kirkwood_soc_platform_probe,
- .remove = __devexit_p(kirkwood_soc_platform_remove),
-};
-
-module_platform_driver(kirkwood_pcm_driver);
-
-MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
-MODULE_DESCRIPTION("Marvell Kirkwood Audio DMA module");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:kirkwood-pcm-audio");
diff --git a/ANDROID_3.4.5/sound/soc/kirkwood/kirkwood-i2s.c b/ANDROID_3.4.5/sound/soc/kirkwood/kirkwood-i2s.c
deleted file mode 100644
index 3cb9aa42..00000000
--- a/ANDROID_3.4.5/sound/soc/kirkwood/kirkwood-i2s.c
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * kirkwood-i2s.c
- *
- * (c) 2010 Arnaud Patard <apatard@mandriva.com>
- * (c) 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/mbus.h>
-#include <linux/delay.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <plat/audio.h>
-#include "kirkwood.h"
-
-#define DRV_NAME "kirkwood-i2s"
-
-#define KIRKWOOD_I2S_RATES \
- (SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
-#define KIRKWOOD_I2S_FORMATS \
- (SNDRV_PCM_FMTBIT_S16_LE | \
- SNDRV_PCM_FMTBIT_S24_LE | \
- SNDRV_PCM_FMTBIT_S32_LE)
-
-static int kirkwood_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
- unsigned int fmt)
-{
- struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(cpu_dai);
- unsigned long mask;
- unsigned long value;
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_RIGHT_J:
- mask = KIRKWOOD_I2S_CTL_RJ;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- mask = KIRKWOOD_I2S_CTL_LJ;
- break;
- case SND_SOC_DAIFMT_I2S:
- mask = KIRKWOOD_I2S_CTL_I2S;
- break;
- default:
- return -EINVAL;
- }
-
- /*
- * Set same format for playback and record
- * This avoids some troubles.
- */
- value = readl(priv->io+KIRKWOOD_I2S_PLAYCTL);
- value &= ~KIRKWOOD_I2S_CTL_JUST_MASK;
- value |= mask;
- writel(value, priv->io+KIRKWOOD_I2S_PLAYCTL);
-
- value = readl(priv->io+KIRKWOOD_I2S_RECCTL);
- value &= ~KIRKWOOD_I2S_CTL_JUST_MASK;
- value |= mask;
- writel(value, priv->io+KIRKWOOD_I2S_RECCTL);
-
- return 0;
-}
-
-static inline void kirkwood_set_dco(void __iomem *io, unsigned long rate)
-{
- unsigned long value;
-
- value = KIRKWOOD_DCO_CTL_OFFSET_0;
- switch (rate) {
- default:
- case 44100:
- value |= KIRKWOOD_DCO_CTL_FREQ_11;
- break;
- case 48000:
- value |= KIRKWOOD_DCO_CTL_FREQ_12;
- break;
- case 96000:
- value |= KIRKWOOD_DCO_CTL_FREQ_24;
- break;
- }
- writel(value, io + KIRKWOOD_DCO_CTL);
-
- /* wait for dco locked */
- do {
- cpu_relax();
- value = readl(io + KIRKWOOD_DCO_SPCR_STATUS);
- value &= KIRKWOOD_DCO_SPCR_STATUS;
- } while (value == 0);
-}
-
-static int kirkwood_i2s_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
-
- snd_soc_dai_set_dma_data(dai, substream, priv);
- return 0;
-}
-
-static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
- unsigned int i2s_reg, reg;
- unsigned long i2s_value, value;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- i2s_reg = KIRKWOOD_I2S_PLAYCTL;
- reg = KIRKWOOD_PLAYCTL;
- } else {
- i2s_reg = KIRKWOOD_I2S_RECCTL;
- reg = KIRKWOOD_RECCTL;
- }
-
- /* set dco conf */
- kirkwood_set_dco(priv->io, params_rate(params));
-
- i2s_value = readl(priv->io+i2s_reg);
- i2s_value &= ~KIRKWOOD_I2S_CTL_SIZE_MASK;
-
- value = readl(priv->io+reg);
- value &= ~KIRKWOOD_PLAYCTL_SIZE_MASK;
-
- /*
- * Size settings in play/rec i2s control regs and play/rec control
- * regs must be the same.
- */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- i2s_value |= KIRKWOOD_I2S_CTL_SIZE_16;
- value |= KIRKWOOD_PLAYCTL_SIZE_16_C;
- break;
- /*
- * doesn't work... S20_3LE != kirkwood 20bit format ?
- *
- case SNDRV_PCM_FORMAT_S20_3LE:
- i2s_value |= KIRKWOOD_I2S_CTL_SIZE_20;
- value |= KIRKWOOD_PLAYCTL_SIZE_20;
- break;
- */
- case SNDRV_PCM_FORMAT_S24_LE:
- i2s_value |= KIRKWOOD_I2S_CTL_SIZE_24;
- value |= KIRKWOOD_PLAYCTL_SIZE_24;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- i2s_value |= KIRKWOOD_I2S_CTL_SIZE_32;
- value |= KIRKWOOD_PLAYCTL_SIZE_32;
- break;
- default:
- return -EINVAL;
- }
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- value &= ~KIRKWOOD_PLAYCTL_MONO_MASK;
- if (params_channels(params) == 1)
- value |= KIRKWOOD_PLAYCTL_MONO_BOTH;
- else
- value |= KIRKWOOD_PLAYCTL_MONO_OFF;
- }
-
- writel(i2s_value, priv->io+i2s_reg);
- writel(value, priv->io+reg);
-
- return 0;
-}
-
-static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
- int cmd, struct snd_soc_dai *dai)
-{
- struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
- unsigned long value;
-
- /*
- * specs says KIRKWOOD_PLAYCTL must be read 2 times before
- * changing it. So read 1 time here and 1 later.
- */
- value = readl(priv->io + KIRKWOOD_PLAYCTL);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- /* stop audio, enable interrupts */
- value = readl(priv->io + KIRKWOOD_PLAYCTL);
- value |= KIRKWOOD_PLAYCTL_PAUSE;
- writel(value, priv->io + KIRKWOOD_PLAYCTL);
-
- value = readl(priv->io + KIRKWOOD_INT_MASK);
- value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES;
- writel(value, priv->io + KIRKWOOD_INT_MASK);
-
- /* configure audio & enable i2s playback */
- value = readl(priv->io + KIRKWOOD_PLAYCTL);
- value &= ~KIRKWOOD_PLAYCTL_BURST_MASK;
- value &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE
- | KIRKWOOD_PLAYCTL_SPDIF_EN);
-
- if (priv->burst == 32)
- value |= KIRKWOOD_PLAYCTL_BURST_32;
- else
- value |= KIRKWOOD_PLAYCTL_BURST_128;
- value |= KIRKWOOD_PLAYCTL_I2S_EN;
- writel(value, priv->io + KIRKWOOD_PLAYCTL);
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- /* stop audio, disable interrupts */
- value = readl(priv->io + KIRKWOOD_PLAYCTL);
- value |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE;
- writel(value, priv->io + KIRKWOOD_PLAYCTL);
-
- value = readl(priv->io + KIRKWOOD_INT_MASK);
- value &= ~KIRKWOOD_INT_CAUSE_PLAY_BYTES;
- writel(value, priv->io + KIRKWOOD_INT_MASK);
-
- /* disable all playbacks */
- value = readl(priv->io + KIRKWOOD_PLAYCTL);
- value &= ~(KIRKWOOD_PLAYCTL_I2S_EN | KIRKWOOD_PLAYCTL_SPDIF_EN);
- writel(value, priv->io + KIRKWOOD_PLAYCTL);
- break;
-
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- value = readl(priv->io + KIRKWOOD_PLAYCTL);
- value |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE;
- writel(value, priv->io + KIRKWOOD_PLAYCTL);
- break;
-
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- value = readl(priv->io + KIRKWOOD_PLAYCTL);
- value &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE);
- writel(value, priv->io + KIRKWOOD_PLAYCTL);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream,
- int cmd, struct snd_soc_dai *dai)
-{
- struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
- unsigned long value;
-
- value = readl(priv->io + KIRKWOOD_RECCTL);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- /* stop audio, enable interrupts */
- value = readl(priv->io + KIRKWOOD_RECCTL);
- value |= KIRKWOOD_RECCTL_PAUSE;
- writel(value, priv->io + KIRKWOOD_RECCTL);
-
- value = readl(priv->io + KIRKWOOD_INT_MASK);
- value |= KIRKWOOD_INT_CAUSE_REC_BYTES;
- writel(value, priv->io + KIRKWOOD_INT_MASK);
-
- /* configure audio & enable i2s record */
- value = readl(priv->io + KIRKWOOD_RECCTL);
- value &= ~KIRKWOOD_RECCTL_BURST_MASK;
- value &= ~KIRKWOOD_RECCTL_MONO;
- value &= ~(KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE
- | KIRKWOOD_RECCTL_SPDIF_EN);
-
- if (priv->burst == 32)
- value |= KIRKWOOD_RECCTL_BURST_32;
- else
- value |= KIRKWOOD_RECCTL_BURST_128;
- value |= KIRKWOOD_RECCTL_I2S_EN;
-
- writel(value, priv->io + KIRKWOOD_RECCTL);
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- /* stop audio, disable interrupts */
- value = readl(priv->io + KIRKWOOD_RECCTL);
- value |= KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE;
- writel(value, priv->io + KIRKWOOD_RECCTL);
-
- value = readl(priv->io + KIRKWOOD_INT_MASK);
- value &= ~KIRKWOOD_INT_CAUSE_REC_BYTES;
- writel(value, priv->io + KIRKWOOD_INT_MASK);
-
- /* disable all records */
- value = readl(priv->io + KIRKWOOD_RECCTL);
- value &= ~(KIRKWOOD_RECCTL_I2S_EN | KIRKWOOD_RECCTL_SPDIF_EN);
- writel(value, priv->io + KIRKWOOD_RECCTL);
- break;
-
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- value = readl(priv->io + KIRKWOOD_RECCTL);
- value |= KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE;
- writel(value, priv->io + KIRKWOOD_RECCTL);
- break;
-
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- value = readl(priv->io + KIRKWOOD_RECCTL);
- value &= ~(KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE);
- writel(value, priv->io + KIRKWOOD_RECCTL);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int kirkwood_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- return kirkwood_i2s_play_trigger(substream, cmd, dai);
- else
- return kirkwood_i2s_rec_trigger(substream, cmd, dai);
-
- return 0;
-}
-
-static int kirkwood_i2s_probe(struct snd_soc_dai *dai)
-{
- struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
- unsigned long value;
- unsigned int reg_data;
-
- /* put system in a "safe" state : */
- /* disable audio interrupts */
- writel(0xffffffff, priv->io + KIRKWOOD_INT_CAUSE);
- writel(0, priv->io + KIRKWOOD_INT_MASK);
-
- reg_data = readl(priv->io + 0x1200);
- reg_data &= (~(0x333FF8));
- reg_data |= 0x111D18;
- writel(reg_data, priv->io + 0x1200);
-
- msleep(500);
-
- reg_data = readl(priv->io + 0x1200);
- reg_data &= (~(0x333FF8));
- reg_data |= 0x111D18;
- writel(reg_data, priv->io + 0x1200);
-
- /* disable playback/record */
- value = readl(priv->io + KIRKWOOD_PLAYCTL);
- value &= ~(KIRKWOOD_PLAYCTL_I2S_EN|KIRKWOOD_PLAYCTL_SPDIF_EN);
- writel(value, priv->io + KIRKWOOD_PLAYCTL);
-
- value = readl(priv->io + KIRKWOOD_RECCTL);
- value &= ~(KIRKWOOD_RECCTL_I2S_EN | KIRKWOOD_RECCTL_SPDIF_EN);
- writel(value, priv->io + KIRKWOOD_RECCTL);
-
- return 0;
-
-}
-
-static int kirkwood_i2s_remove(struct snd_soc_dai *dai)
-{
- return 0;
-}
-
-static const struct snd_soc_dai_ops kirkwood_i2s_dai_ops = {
- .startup = kirkwood_i2s_startup,
- .trigger = kirkwood_i2s_trigger,
- .hw_params = kirkwood_i2s_hw_params,
- .set_fmt = kirkwood_i2s_set_fmt,
-};
-
-
-static struct snd_soc_dai_driver kirkwood_i2s_dai = {
- .probe = kirkwood_i2s_probe,
- .remove = kirkwood_i2s_remove,
- .playback = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = KIRKWOOD_I2S_RATES,
- .formats = KIRKWOOD_I2S_FORMATS,},
- .capture = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = KIRKWOOD_I2S_RATES,
- .formats = KIRKWOOD_I2S_FORMATS,},
- .ops = &kirkwood_i2s_dai_ops,
-};
-
-static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev)
-{
- struct resource *mem;
- struct kirkwood_asoc_platform_data *data =
- pdev->dev.platform_data;
- struct kirkwood_dma_data *priv;
- int err;
-
- priv = kzalloc(sizeof(struct kirkwood_dma_data), GFP_KERNEL);
- if (!priv) {
- dev_err(&pdev->dev, "allocation failed\n");
- err = -ENOMEM;
- goto error;
- }
- dev_set_drvdata(&pdev->dev, priv);
-
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem) {
- dev_err(&pdev->dev, "platform_get_resource failed\n");
- err = -ENXIO;
- goto err_alloc;
- }
-
- priv->mem = request_mem_region(mem->start, SZ_16K, DRV_NAME);
- if (!priv->mem) {
- dev_err(&pdev->dev, "request_mem_region failed\n");
- err = -EBUSY;
- goto err_alloc;
- }
-
- priv->io = ioremap(priv->mem->start, SZ_16K);
- if (!priv->io) {
- dev_err(&pdev->dev, "ioremap failed\n");
- err = -ENOMEM;
- goto err_iomem;
- }
-
- priv->irq = platform_get_irq(pdev, 0);
- if (priv->irq <= 0) {
- dev_err(&pdev->dev, "platform_get_irq failed\n");
- err = -ENXIO;
- goto err_ioremap;
- }
-
- if (!data) {
- dev_err(&pdev->dev, "no platform data ?!\n");
- err = -EINVAL;
- goto err_ioremap;
- }
-
- priv->burst = data->burst;
-
- return snd_soc_register_dai(&pdev->dev, &kirkwood_i2s_dai);
-
-err_ioremap:
- iounmap(priv->io);
-err_iomem:
- release_mem_region(priv->mem->start, SZ_16K);
-err_alloc:
- kfree(priv);
-error:
- return err;
-}
-
-static __devexit int kirkwood_i2s_dev_remove(struct platform_device *pdev)
-{
- struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev);
-
- snd_soc_unregister_dai(&pdev->dev);
- iounmap(priv->io);
- release_mem_region(priv->mem->start, SZ_16K);
- kfree(priv);
-
- return 0;
-}
-
-static struct platform_driver kirkwood_i2s_driver = {
- .probe = kirkwood_i2s_dev_probe,
- .remove = __devexit_p(kirkwood_i2s_dev_remove),
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(kirkwood_i2s_driver);
-
-/* Module information */
-MODULE_AUTHOR("Arnaud Patard, <arnaud.patard@rtp-net.org>");
-MODULE_DESCRIPTION("Kirkwood I2S SoC Interface");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:kirkwood-i2s");
diff --git a/ANDROID_3.4.5/sound/soc/kirkwood/kirkwood-openrd.c b/ANDROID_3.4.5/sound/soc/kirkwood/kirkwood-openrd.c
deleted file mode 100644
index 80bd59c3..00000000
--- a/ANDROID_3.4.5/sound/soc/kirkwood/kirkwood-openrd.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * kirkwood-openrd.c
- *
- * (c) 2010 Arnaud Patard <apatard@mandriva.com>
- * (c) 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <sound/soc.h>
-#include <mach/kirkwood.h>
-#include <plat/audio.h>
-#include <asm/mach-types.h>
-#include "../codecs/cs42l51.h"
-
-static int openrd_client_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- unsigned int freq;
-
- switch (params_rate(params)) {
- default:
- case 44100:
- freq = 11289600;
- break;
- case 48000:
- freq = 12288000;
- break;
- case 96000:
- freq = 24576000;
- break;
- }
-
- return snd_soc_dai_set_sysclk(codec_dai, 0, freq, SND_SOC_CLOCK_IN);
-
-}
-
-static struct snd_soc_ops openrd_client_ops = {
- .hw_params = openrd_client_hw_params,
-};
-
-
-static struct snd_soc_dai_link openrd_client_dai[] = {
-{
- .name = "CS42L51",
- .stream_name = "CS42L51 HiFi",
- .cpu_dai_name = "kirkwood-i2s",
- .platform_name = "kirkwood-pcm-audio",
- .codec_dai_name = "cs42l51-hifi",
- .codec_name = "cs42l51-codec.0-004a",
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS,
- .ops = &openrd_client_ops,
-},
-};
-
-
-static struct snd_soc_card openrd_client = {
- .name = "OpenRD Client",
- .owner = THIS_MODULE,
- .dai_link = openrd_client_dai,
- .num_links = ARRAY_SIZE(openrd_client_dai),
-};
-
-static int __devinit openrd_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &openrd_client;
- int ret;
-
- card->dev = &pdev->dev;
-
- ret = snd_soc_register_card(card);
- if (ret)
- dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
- ret);
- return ret;
-}
-
-static int __devexit openrd_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- snd_soc_unregister_card(card);
- return 0;
-}
-
-static struct platform_driver openrd_driver = {
- .driver = {
- .name = "openrd-client-audio",
- .owner = THIS_MODULE,
- },
- .probe = openrd_probe,
- .remove = __devexit_p(openrd_remove),
-};
-
-module_platform_driver(openrd_driver);
-
-/* Module information */
-MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
-MODULE_DESCRIPTION("ALSA SoC OpenRD Client");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:openrd-client-audio");
diff --git a/ANDROID_3.4.5/sound/soc/kirkwood/kirkwood-t5325.c b/ANDROID_3.4.5/sound/soc/kirkwood/kirkwood-t5325.c
deleted file mode 100644
index f8983635..00000000
--- a/ANDROID_3.4.5/sound/soc/kirkwood/kirkwood-t5325.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * kirkwood-t5325.c
- *
- * (c) 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <sound/soc.h>
-#include <mach/kirkwood.h>
-#include <plat/audio.h>
-#include <asm/mach-types.h>
-#include "../codecs/alc5623.h"
-
-static int t5325_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- unsigned int freq;
-
- freq = params_rate(params) * 256;
-
- return snd_soc_dai_set_sysclk(codec_dai, 0, freq, SND_SOC_CLOCK_IN);
-
-}
-
-static struct snd_soc_ops t5325_ops = {
- .hw_params = t5325_hw_params,
-};
-
-static const struct snd_soc_dapm_widget t5325_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_SPK("Speaker", NULL),
- SND_SOC_DAPM_MIC("Mic Jack", NULL),
-};
-
-static const struct snd_soc_dapm_route t5325_route[] = {
- { "Headphone Jack", NULL, "HPL" },
- { "Headphone Jack", NULL, "HPR" },
-
- {"Speaker", NULL, "SPKOUT"},
- {"Speaker", NULL, "SPKOUTN"},
-
- { "MIC1", NULL, "Mic Jack" },
- { "MIC2", NULL, "Mic Jack" },
-};
-
-static int t5325_dai_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_enable_pin(dapm, "Mic Jack");
- snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_enable_pin(dapm, "Speaker");
-
- return 0;
-}
-
-static struct snd_soc_dai_link t5325_dai[] = {
-{
- .name = "ALC5621",
- .stream_name = "ALC5621 HiFi",
- .cpu_dai_name = "kirkwood-i2s",
- .platform_name = "kirkwood-pcm-audio",
- .codec_dai_name = "alc5621-hifi",
- .codec_name = "alc562x-codec.0-001a",
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS,
- .ops = &t5325_ops,
- .init = t5325_dai_init,
-},
-};
-
-static struct snd_soc_card t5325 = {
- .name = "t5325",
- .owner = THIS_MODULE,
- .dai_link = t5325_dai,
- .num_links = ARRAY_SIZE(t5325_dai),
-
- .dapm_widgets = t5325_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(t5325_dapm_widgets),
- .dapm_routes = t5325_route,
- .num_dapm_routes = ARRAY_SIZE(t5325_route),
-};
-
-static int __devinit t5325_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &t5325;
- int ret;
-
- card->dev = &pdev->dev;
-
- ret = snd_soc_register_card(card);
- if (ret)
- dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
- ret);
- return ret;
-}
-
-static int __devexit t5325_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- snd_soc_unregister_card(card);
- return 0;
-}
-
-static struct platform_driver t5325_driver = {
- .driver = {
- .name = "t5325-audio",
- .owner = THIS_MODULE,
- },
- .probe = t5325_probe,
- .remove = __devexit_p(t5325_remove),
-};
-
-module_platform_driver(t5325_driver);
-
-MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
-MODULE_DESCRIPTION("ALSA SoC t5325 audio client");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:t5325-audio");
diff --git a/ANDROID_3.4.5/sound/soc/kirkwood/kirkwood.h b/ANDROID_3.4.5/sound/soc/kirkwood/kirkwood.h
deleted file mode 100644
index 9047436b..00000000
--- a/ANDROID_3.4.5/sound/soc/kirkwood/kirkwood.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * kirkwood.h
- *
- * (c) 2010 Arnaud Patard <apatard@mandriva.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#ifndef _KIRKWOOD_AUDIO_H
-#define _KIRKWOOD_AUDIO_H
-
-#define KIRKWOOD_RECORD_WIN 0
-#define KIRKWOOD_PLAYBACK_WIN 1
-#define KIRKWOOD_MAX_AUDIO_WIN 2
-
-#define KIRKWOOD_AUDIO_WIN_BASE_REG(win) (0xA00 + ((win)<<3))
-#define KIRKWOOD_AUDIO_WIN_CTRL_REG(win) (0xA04 + ((win)<<3))
-
-
-#define KIRKWOOD_RECCTL 0x1000
-#define KIRKWOOD_RECCTL_SPDIF_EN (1<<11)
-#define KIRKWOOD_RECCTL_I2S_EN (1<<10)
-#define KIRKWOOD_RECCTL_PAUSE (1<<9)
-#define KIRKWOOD_RECCTL_MUTE (1<<8)
-#define KIRKWOOD_RECCTL_BURST_MASK (3<<5)
-#define KIRKWOOD_RECCTL_BURST_128 (2<<5)
-#define KIRKWOOD_RECCTL_BURST_32 (1<<5)
-#define KIRKWOOD_RECCTL_MONO (1<<4)
-#define KIRKWOOD_RECCTL_MONO_CHAN_RIGHT (1<<3)
-#define KIRKWOOD_RECCTL_MONO_CHAN_LEFT (0<<3)
-#define KIRKWOOD_RECCTL_SIZE_MASK (7<<0)
-#define KIRKWOOD_RECCTL_SIZE_16 (7<<0)
-#define KIRKWOOD_RECCTL_SIZE_16_C (3<<0)
-#define KIRKWOOD_RECCTL_SIZE_20 (2<<0)
-#define KIRKWOOD_RECCTL_SIZE_24 (1<<0)
-#define KIRKWOOD_RECCTL_SIZE_32 (0<<0)
-
-#define KIRKWOOD_REC_BUF_ADDR 0x1004
-#define KIRKWOOD_REC_BUF_SIZE 0x1008
-#define KIRKWOOD_REC_BYTE_COUNT 0x100C
-
-#define KIRKWOOD_PLAYCTL 0x1100
-#define KIRKWOOD_PLAYCTL_PLAY_BUSY (1<<16)
-#define KIRKWOOD_PLAYCTL_BURST_MASK (3<<11)
-#define KIRKWOOD_PLAYCTL_BURST_128 (2<<11)
-#define KIRKWOOD_PLAYCTL_BURST_32 (1<<11)
-#define KIRKWOOD_PLAYCTL_PAUSE (1<<9)
-#define KIRKWOOD_PLAYCTL_SPDIF_MUTE (1<<8)
-#define KIRKWOOD_PLAYCTL_MONO_MASK (3<<5)
-#define KIRKWOOD_PLAYCTL_MONO_BOTH (3<<5)
-#define KIRKWOOD_PLAYCTL_MONO_OFF (0<<5)
-#define KIRKWOOD_PLAYCTL_I2S_MUTE (1<<7)
-#define KIRKWOOD_PLAYCTL_SPDIF_EN (1<<4)
-#define KIRKWOOD_PLAYCTL_I2S_EN (1<<3)
-#define KIRKWOOD_PLAYCTL_SIZE_MASK (7<<0)
-#define KIRKWOOD_PLAYCTL_SIZE_16 (7<<0)
-#define KIRKWOOD_PLAYCTL_SIZE_16_C (3<<0)
-#define KIRKWOOD_PLAYCTL_SIZE_20 (2<<0)
-#define KIRKWOOD_PLAYCTL_SIZE_24 (1<<0)
-#define KIRKWOOD_PLAYCTL_SIZE_32 (0<<0)
-
-#define KIRKWOOD_PLAY_BUF_ADDR 0x1104
-#define KIRKWOOD_PLAY_BUF_SIZE 0x1108
-#define KIRKWOOD_PLAY_BYTE_COUNT 0x110C
-
-#define KIRKWOOD_DCO_CTL 0x1204
-#define KIRKWOOD_DCO_CTL_OFFSET_MASK (0xFFF<<2)
-#define KIRKWOOD_DCO_CTL_OFFSET_0 (0x800<<2)
-#define KIRKWOOD_DCO_CTL_FREQ_MASK (3<<0)
-#define KIRKWOOD_DCO_CTL_FREQ_11 (0<<0)
-#define KIRKWOOD_DCO_CTL_FREQ_12 (1<<0)
-#define KIRKWOOD_DCO_CTL_FREQ_24 (2<<0)
-
-#define KIRKWOOD_DCO_SPCR_STATUS 0x120c
-#define KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK (1<<16)
-
-#define KIRKWOOD_ERR_CAUSE 0x1300
-#define KIRKWOOD_ERR_MASK 0x1304
-
-#define KIRKWOOD_INT_CAUSE 0x1308
-#define KIRKWOOD_INT_MASK 0x130C
-#define KIRKWOOD_INT_CAUSE_PLAY_BYTES (1<<14)
-#define KIRKWOOD_INT_CAUSE_REC_BYTES (1<<13)
-#define KIRKWOOD_INT_CAUSE_DMA_PLAY_END (1<<7)
-#define KIRKWOOD_INT_CAUSE_DMA_PLAY_3Q (1<<6)
-#define KIRKWOOD_INT_CAUSE_DMA_PLAY_HALF (1<<5)
-#define KIRKWOOD_INT_CAUSE_DMA_PLAY_1Q (1<<4)
-#define KIRKWOOD_INT_CAUSE_DMA_REC_END (1<<3)
-#define KIRKWOOD_INT_CAUSE_DMA_REC_3Q (1<<2)
-#define KIRKWOOD_INT_CAUSE_DMA_REC_HALF (1<<1)
-#define KIRKWOOD_INT_CAUSE_DMA_REC_1Q (1<<0)
-
-#define KIRKWOOD_REC_BYTE_INT_COUNT 0x1310
-#define KIRKWOOD_PLAY_BYTE_INT_COUNT 0x1314
-#define KIRKWOOD_BYTE_INT_COUNT_MASK 0xffffff
-
-#define KIRKWOOD_I2S_PLAYCTL 0x2508
-#define KIRKWOOD_I2S_RECCTL 0x2408
-#define KIRKWOOD_I2S_CTL_JUST_MASK (0xf<<26)
-#define KIRKWOOD_I2S_CTL_LJ (0<<26)
-#define KIRKWOOD_I2S_CTL_I2S (5<<26)
-#define KIRKWOOD_I2S_CTL_RJ (8<<26)
-#define KIRKWOOD_I2S_CTL_SIZE_MASK (3<<30)
-#define KIRKWOOD_I2S_CTL_SIZE_16 (3<<30)
-#define KIRKWOOD_I2S_CTL_SIZE_20 (2<<30)
-#define KIRKWOOD_I2S_CTL_SIZE_24 (1<<30)
-#define KIRKWOOD_I2S_CTL_SIZE_32 (0<<30)
-
-#define KIRKWOOD_AUDIO_BUF_MAX (16*1024*1024)
-
-/* Theses values come from the marvell alsa driver */
-/* need to find where they come from */
-#define KIRKWOOD_SND_MIN_PERIODS 8
-#define KIRKWOOD_SND_MAX_PERIODS 16
-#define KIRKWOOD_SND_MIN_PERIOD_BYTES 0x4000
-#define KIRKWOOD_SND_MAX_PERIOD_BYTES 0x4000
-
-struct kirkwood_dma_data {
- struct resource *mem;
- void __iomem *io;
- int irq;
- int burst;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/mid-x86/Kconfig b/ANDROID_3.4.5/sound/soc/mid-x86/Kconfig
deleted file mode 100644
index 61c10bf5..00000000
--- a/ANDROID_3.4.5/sound/soc/mid-x86/Kconfig
+++ /dev/null
@@ -1,13 +0,0 @@
-config SND_MFLD_MACHINE
- tristate "SOC Machine Audio driver for Intel Medfield MID platform"
- depends on INTEL_SCU_IPC
- select SND_SOC_SN95031
- select SND_SST_PLATFORM
- help
- This adds support for ASoC machine driver for Intel(R) MID Medfield platform
- used as alsa device in audio substem in Intel(R) MID devices
- Say Y if you have such a device
- If unsure select "N".
-
-config SND_SST_PLATFORM
- tristate
diff --git a/ANDROID_3.4.5/sound/soc/mid-x86/Makefile b/ANDROID_3.4.5/sound/soc/mid-x86/Makefile
deleted file mode 100644
index 63988333..00000000
--- a/ANDROID_3.4.5/sound/soc/mid-x86/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-snd-soc-sst-platform-objs := sst_platform.o
-snd-soc-mfld-machine-objs := mfld_machine.o
-
-obj-$(CONFIG_SND_SST_PLATFORM) += snd-soc-sst-platform.o
-obj-$(CONFIG_SND_MFLD_MACHINE) += snd-soc-mfld-machine.o
diff --git a/ANDROID_3.4.5/sound/soc/mid-x86/mfld_machine.c b/ANDROID_3.4.5/sound/soc/mid-x86/mfld_machine.c
deleted file mode 100644
index 2937e54d..00000000
--- a/ANDROID_3.4.5/sound/soc/mid-x86/mfld_machine.c
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * mfld_machine.c - ASoc Machine driver for Intel Medfield MID platform
- *
- * Copyright (C) 2010 Intel Corp
- * Author: Vinod Koul <vinod.koul@intel.com>
- * Author: Harsha Priya <priya.harsha@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/jack.h>
-#include "../codecs/sn95031.h"
-
-#define MID_MONO 1
-#define MID_STEREO 2
-#define MID_MAX_CAP 5
-#define MFLD_JACK_INSERT 0x04
-
-enum soc_mic_bias_zones {
- MFLD_MV_START = 0,
- /* mic bias volutage range for Headphones*/
- MFLD_MV_HP = 400,
- /* mic bias volutage range for American Headset*/
- MFLD_MV_AM_HS = 650,
- /* mic bias volutage range for Headset*/
- MFLD_MV_HS = 2000,
- MFLD_MV_UNDEFINED,
-};
-
-static unsigned int hs_switch;
-static unsigned int lo_dac;
-
-struct mfld_mc_private {
- void __iomem *int_base;
- u8 interrupt_status;
-};
-
-struct snd_soc_jack mfld_jack;
-
-/*Headset jack detection DAPM pins */
-static struct snd_soc_jack_pin mfld_jack_pins[] = {
- {
- .pin = "Headphones",
- .mask = SND_JACK_HEADPHONE,
- },
- {
- .pin = "AMIC1",
- .mask = SND_JACK_MICROPHONE,
- },
-};
-
-/* jack detection voltage zones */
-static struct snd_soc_jack_zone mfld_zones[] = {
- {MFLD_MV_START, MFLD_MV_AM_HS, SND_JACK_HEADPHONE},
- {MFLD_MV_AM_HS, MFLD_MV_HS, SND_JACK_HEADSET},
-};
-
-/* sound card controls */
-static const char *headset_switch_text[] = {"Earpiece", "Headset"};
-
-static const char *lo_text[] = {"Vibra", "Headset", "IHF", "None"};
-
-static const struct soc_enum headset_enum =
- SOC_ENUM_SINGLE_EXT(2, headset_switch_text);
-
-static const struct soc_enum lo_enum =
- SOC_ENUM_SINGLE_EXT(4, lo_text);
-
-static int headset_get_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = hs_switch;
- return 0;
-}
-
-static int headset_set_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-
- if (ucontrol->value.integer.value[0] == hs_switch)
- return 0;
-
- if (ucontrol->value.integer.value[0]) {
- pr_debug("hs_set HS path\n");
- snd_soc_dapm_enable_pin(&codec->dapm, "Headphones");
- snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT");
- } else {
- pr_debug("hs_set EP path\n");
- snd_soc_dapm_disable_pin(&codec->dapm, "Headphones");
- snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT");
- }
- snd_soc_dapm_sync(&codec->dapm);
- hs_switch = ucontrol->value.integer.value[0];
-
- return 0;
-}
-
-static void lo_enable_out_pins(struct snd_soc_codec *codec)
-{
- snd_soc_dapm_enable_pin(&codec->dapm, "IHFOUTL");
- snd_soc_dapm_enable_pin(&codec->dapm, "IHFOUTR");
- snd_soc_dapm_enable_pin(&codec->dapm, "LINEOUTL");
- snd_soc_dapm_enable_pin(&codec->dapm, "LINEOUTR");
- snd_soc_dapm_enable_pin(&codec->dapm, "VIB1OUT");
- snd_soc_dapm_enable_pin(&codec->dapm, "VIB2OUT");
- if (hs_switch) {
- snd_soc_dapm_enable_pin(&codec->dapm, "Headphones");
- snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT");
- } else {
- snd_soc_dapm_disable_pin(&codec->dapm, "Headphones");
- snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT");
- }
-}
-
-static int lo_get_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = lo_dac;
- return 0;
-}
-
-static int lo_set_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-
- if (ucontrol->value.integer.value[0] == lo_dac)
- return 0;
-
- /* we dont want to work with last state of lineout so just enable all
- * pins and then disable pins not required
- */
- lo_enable_out_pins(codec);
- switch (ucontrol->value.integer.value[0]) {
- case 0:
- pr_debug("set vibra path\n");
- snd_soc_dapm_disable_pin(&codec->dapm, "VIB1OUT");
- snd_soc_dapm_disable_pin(&codec->dapm, "VIB2OUT");
- snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0);
- break;
-
- case 1:
- pr_debug("set hs path\n");
- snd_soc_dapm_disable_pin(&codec->dapm, "Headphones");
- snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT");
- snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x22);
- break;
-
- case 2:
- pr_debug("set spkr path\n");
- snd_soc_dapm_disable_pin(&codec->dapm, "IHFOUTL");
- snd_soc_dapm_disable_pin(&codec->dapm, "IHFOUTR");
- snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x44);
- break;
-
- case 3:
- pr_debug("set null path\n");
- snd_soc_dapm_disable_pin(&codec->dapm, "LINEOUTL");
- snd_soc_dapm_disable_pin(&codec->dapm, "LINEOUTR");
- snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x66);
- break;
- }
- snd_soc_dapm_sync(&codec->dapm);
- lo_dac = ucontrol->value.integer.value[0];
- return 0;
-}
-
-static const struct snd_kcontrol_new mfld_snd_controls[] = {
- SOC_ENUM_EXT("Playback Switch", headset_enum,
- headset_get_switch, headset_set_switch),
- SOC_ENUM_EXT("Lineout Mux", lo_enum,
- lo_get_switch, lo_set_switch),
-};
-
-static const struct snd_soc_dapm_widget mfld_widgets[] = {
- SND_SOC_DAPM_HP("Headphones", NULL),
- SND_SOC_DAPM_MIC("Mic", NULL),
-};
-
-static const struct snd_soc_dapm_route mfld_map[] = {
- {"Headphones", NULL, "HPOUTR"},
- {"Headphones", NULL, "HPOUTL"},
- {"Mic", NULL, "AMIC1"},
-};
-
-static void mfld_jack_check(unsigned int intr_status)
-{
- struct mfld_jack_data jack_data;
-
- jack_data.mfld_jack = &mfld_jack;
- jack_data.intr_id = intr_status;
-
- sn95031_jack_detection(&jack_data);
- /* TODO: add american headset detection post gpiolib support */
-}
-
-static int mfld_init(struct snd_soc_pcm_runtime *runtime)
-{
- struct snd_soc_codec *codec = runtime->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret_val;
-
- /* Add jack sense widgets */
- snd_soc_dapm_new_controls(dapm, mfld_widgets, ARRAY_SIZE(mfld_widgets));
-
- /* Set up the map */
- snd_soc_dapm_add_routes(dapm, mfld_map, ARRAY_SIZE(mfld_map));
-
- /* always connected */
- snd_soc_dapm_enable_pin(dapm, "Headphones");
- snd_soc_dapm_enable_pin(dapm, "Mic");
-
- ret_val = snd_soc_add_codec_controls(codec, mfld_snd_controls,
- ARRAY_SIZE(mfld_snd_controls));
- if (ret_val) {
- pr_err("soc_add_controls failed %d", ret_val);
- return ret_val;
- }
- /* default is earpiece pin, userspace sets it explcitly */
- snd_soc_dapm_disable_pin(dapm, "Headphones");
- /* default is lineout NC, userspace sets it explcitly */
- snd_soc_dapm_disable_pin(dapm, "LINEOUTL");
- snd_soc_dapm_disable_pin(dapm, "LINEOUTR");
- lo_dac = 3;
- hs_switch = 0;
- /* we dont use linein in this so set to NC */
- snd_soc_dapm_disable_pin(dapm, "LINEINL");
- snd_soc_dapm_disable_pin(dapm, "LINEINR");
-
- /* Headset and button jack detection */
- ret_val = snd_soc_jack_new(codec, "Intel(R) MID Audio Jack",
- SND_JACK_HEADSET | SND_JACK_BTN_0 |
- SND_JACK_BTN_1, &mfld_jack);
- if (ret_val) {
- pr_err("jack creation failed\n");
- return ret_val;
- }
-
- ret_val = snd_soc_jack_add_pins(&mfld_jack,
- ARRAY_SIZE(mfld_jack_pins), mfld_jack_pins);
- if (ret_val) {
- pr_err("adding jack pins failed\n");
- return ret_val;
- }
- ret_val = snd_soc_jack_add_zones(&mfld_jack,
- ARRAY_SIZE(mfld_zones), mfld_zones);
- if (ret_val) {
- pr_err("adding jack zones failed\n");
- return ret_val;
- }
-
- /* we want to check if anything is inserted at boot,
- * so send a fake event to codec and it will read adc
- * to find if anything is there or not */
- mfld_jack_check(MFLD_JACK_INSERT);
- return ret_val;
-}
-
-static struct snd_soc_dai_link mfld_msic_dailink[] = {
- {
- .name = "Medfield Headset",
- .stream_name = "Headset",
- .cpu_dai_name = "Headset-cpu-dai",
- .codec_dai_name = "SN95031 Headset",
- .codec_name = "sn95031",
- .platform_name = "sst-platform",
- .init = mfld_init,
- },
- {
- .name = "Medfield Speaker",
- .stream_name = "Speaker",
- .cpu_dai_name = "Speaker-cpu-dai",
- .codec_dai_name = "SN95031 Speaker",
- .codec_name = "sn95031",
- .platform_name = "sst-platform",
- .init = NULL,
- },
- {
- .name = "Medfield Vibra",
- .stream_name = "Vibra1",
- .cpu_dai_name = "Vibra1-cpu-dai",
- .codec_dai_name = "SN95031 Vibra1",
- .codec_name = "sn95031",
- .platform_name = "sst-platform",
- .init = NULL,
- },
- {
- .name = "Medfield Haptics",
- .stream_name = "Vibra2",
- .cpu_dai_name = "Vibra2-cpu-dai",
- .codec_dai_name = "SN95031 Vibra2",
- .codec_name = "sn95031",
- .platform_name = "sst-platform",
- .init = NULL,
- },
-};
-
-/* SoC card */
-static struct snd_soc_card snd_soc_card_mfld = {
- .name = "medfield_audio",
- .owner = THIS_MODULE,
- .dai_link = mfld_msic_dailink,
- .num_links = ARRAY_SIZE(mfld_msic_dailink),
-};
-
-static irqreturn_t snd_mfld_jack_intr_handler(int irq, void *dev)
-{
- struct mfld_mc_private *mc_private = (struct mfld_mc_private *) dev;
-
- memcpy_fromio(&mc_private->interrupt_status,
- ((void *)(mc_private->int_base)),
- sizeof(u8));
- return IRQ_WAKE_THREAD;
-}
-
-static irqreturn_t snd_mfld_jack_detection(int irq, void *data)
-{
- struct mfld_mc_private *mc_drv_ctx = (struct mfld_mc_private *) data;
-
- if (mfld_jack.codec == NULL)
- return IRQ_HANDLED;
- mfld_jack_check(mc_drv_ctx->interrupt_status);
-
- return IRQ_HANDLED;
-}
-
-static int __devinit snd_mfld_mc_probe(struct platform_device *pdev)
-{
- int ret_val = 0, irq;
- struct mfld_mc_private *mc_drv_ctx;
- struct resource *irq_mem;
-
- pr_debug("snd_mfld_mc_probe called\n");
-
- /* retrive the irq number */
- irq = platform_get_irq(pdev, 0);
-
- /* audio interrupt base of SRAM location where
- * interrupts are stored by System FW */
- mc_drv_ctx = kzalloc(sizeof(*mc_drv_ctx), GFP_ATOMIC);
- if (!mc_drv_ctx) {
- pr_err("allocation failed\n");
- return -ENOMEM;
- }
-
- irq_mem = platform_get_resource_byname(
- pdev, IORESOURCE_MEM, "IRQ_BASE");
- if (!irq_mem) {
- pr_err("no mem resource given\n");
- ret_val = -ENODEV;
- goto unalloc;
- }
- mc_drv_ctx->int_base = ioremap_nocache(irq_mem->start,
- resource_size(irq_mem));
- if (!mc_drv_ctx->int_base) {
- pr_err("Mapping of cache failed\n");
- ret_val = -ENOMEM;
- goto unalloc;
- }
- /* register for interrupt */
- ret_val = request_threaded_irq(irq, snd_mfld_jack_intr_handler,
- snd_mfld_jack_detection,
- IRQF_SHARED, pdev->dev.driver->name, mc_drv_ctx);
- if (ret_val) {
- pr_err("cannot register IRQ\n");
- goto unalloc;
- }
- /* register the soc card */
- snd_soc_card_mfld.dev = &pdev->dev;
- ret_val = snd_soc_register_card(&snd_soc_card_mfld);
- if (ret_val) {
- pr_debug("snd_soc_register_card failed %d\n", ret_val);
- goto freeirq;
- }
- platform_set_drvdata(pdev, mc_drv_ctx);
- pr_debug("successfully exited probe\n");
- return ret_val;
-
-freeirq:
- free_irq(irq, mc_drv_ctx);
-unalloc:
- kfree(mc_drv_ctx);
- return ret_val;
-}
-
-static int __devexit snd_mfld_mc_remove(struct platform_device *pdev)
-{
- struct mfld_mc_private *mc_drv_ctx = platform_get_drvdata(pdev);
-
- pr_debug("snd_mfld_mc_remove called\n");
- free_irq(platform_get_irq(pdev, 0), mc_drv_ctx);
- snd_soc_unregister_card(&snd_soc_card_mfld);
- kfree(mc_drv_ctx);
- platform_set_drvdata(pdev, NULL);
- return 0;
-}
-
-static struct platform_driver snd_mfld_mc_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "msic_audio",
- },
- .probe = snd_mfld_mc_probe,
- .remove = __devexit_p(snd_mfld_mc_remove),
-};
-
-module_platform_driver(snd_mfld_mc_driver);
-
-MODULE_DESCRIPTION("ASoC Intel(R) MID Machine driver");
-MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
-MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:msic-audio");
diff --git a/ANDROID_3.4.5/sound/soc/mid-x86/sst_platform.c b/ANDROID_3.4.5/sound/soc/mid-x86/sst_platform.c
deleted file mode 100644
index d34563b1..00000000
--- a/ANDROID_3.4.5/sound/soc/mid-x86/sst_platform.c
+++ /dev/null
@@ -1,517 +0,0 @@
-/*
- * sst_platform.c - Intel MID Platform driver
- *
- * Copyright (C) 2010 Intel Corp
- * Author: Vinod Koul <vinod.koul@intel.com>
- * Author: Harsha Priya <priya.harsha@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *
- */
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include "sst_platform.h"
-
-static struct sst_device *sst;
-static DEFINE_MUTEX(sst_lock);
-
-int sst_register_dsp(struct sst_device *dev)
-{
- BUG_ON(!dev);
- if (!try_module_get(dev->dev->driver->owner))
- return -ENODEV;
- mutex_lock(&sst_lock);
- if (sst) {
- pr_err("we already have a device %s\n", sst->name);
- module_put(dev->dev->driver->owner);
- mutex_unlock(&sst_lock);
- return -EEXIST;
- }
- pr_debug("registering device %s\n", dev->name);
- sst = dev;
- mutex_unlock(&sst_lock);
- return 0;
-}
-EXPORT_SYMBOL_GPL(sst_register_dsp);
-
-int sst_unregister_dsp(struct sst_device *dev)
-{
- BUG_ON(!dev);
- if (dev != sst)
- return -EINVAL;
-
- mutex_lock(&sst_lock);
-
- if (!sst) {
- mutex_unlock(&sst_lock);
- return -EIO;
- }
-
- module_put(sst->dev->driver->owner);
- pr_debug("unreg %s\n", sst->name);
- sst = NULL;
- mutex_unlock(&sst_lock);
- return 0;
-}
-EXPORT_SYMBOL_GPL(sst_unregister_dsp);
-
-static struct snd_pcm_hardware sst_platform_pcm_hw = {
- .info = (SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_DOUBLE |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_MMAP|
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_SYNC_START),
- .formats = (SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_U16 |
- SNDRV_PCM_FMTBIT_S24 | SNDRV_PCM_FMTBIT_U24 |
- SNDRV_PCM_FMTBIT_S32 | SNDRV_PCM_FMTBIT_U32),
- .rates = (SNDRV_PCM_RATE_8000|
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000),
- .rate_min = SST_MIN_RATE,
- .rate_max = SST_MAX_RATE,
- .channels_min = SST_MIN_CHANNEL,
- .channels_max = SST_MAX_CHANNEL,
- .buffer_bytes_max = SST_MAX_BUFFER,
- .period_bytes_min = SST_MIN_PERIOD_BYTES,
- .period_bytes_max = SST_MAX_PERIOD_BYTES,
- .periods_min = SST_MIN_PERIODS,
- .periods_max = SST_MAX_PERIODS,
- .fifo_size = SST_FIFO_SIZE,
-};
-
-/* MFLD - MSIC */
-static struct snd_soc_dai_driver sst_platform_dai[] = {
-{
- .name = "Headset-cpu-dai",
- .id = 0,
- .playback = {
- .channels_min = SST_STEREO,
- .channels_max = SST_STEREO,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S24_LE,
- },
- .capture = {
- .channels_min = 1,
- .channels_max = 5,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S24_LE,
- },
-},
-{
- .name = "Speaker-cpu-dai",
- .id = 1,
- .playback = {
- .channels_min = SST_MONO,
- .channels_max = SST_STEREO,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S24_LE,
- },
-},
-{
- .name = "Vibra1-cpu-dai",
- .id = 2,
- .playback = {
- .channels_min = SST_MONO,
- .channels_max = SST_MONO,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S24_LE,
- },
-},
-{
- .name = "Vibra2-cpu-dai",
- .id = 3,
- .playback = {
- .channels_min = SST_MONO,
- .channels_max = SST_STEREO,
- .rates = SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S24_LE,
- },
-},
-};
-
-/* helper functions */
-static inline void sst_set_stream_status(struct sst_runtime_stream *stream,
- int state)
-{
- unsigned long flags;
- spin_lock_irqsave(&stream->status_lock, flags);
- stream->stream_status = state;
- spin_unlock_irqrestore(&stream->status_lock, flags);
-}
-
-static inline int sst_get_stream_status(struct sst_runtime_stream *stream)
-{
- int state;
- unsigned long flags;
-
- spin_lock_irqsave(&stream->status_lock, flags);
- state = stream->stream_status;
- spin_unlock_irqrestore(&stream->status_lock, flags);
- return state;
-}
-
-static void sst_fill_pcm_params(struct snd_pcm_substream *substream,
- struct sst_pcm_params *param)
-{
-
- param->codec = SST_CODEC_TYPE_PCM;
- param->num_chan = (u8) substream->runtime->channels;
- param->pcm_wd_sz = substream->runtime->sample_bits;
- param->reserved = 0;
- param->sfreq = substream->runtime->rate;
- param->ring_buffer_size = snd_pcm_lib_buffer_bytes(substream);
- param->period_count = substream->runtime->period_size;
- param->ring_buffer_addr = virt_to_phys(substream->dma_buffer.area);
- pr_debug("period_cnt = %d\n", param->period_count);
- pr_debug("sfreq= %d, wd_sz = %d\n", param->sfreq, param->pcm_wd_sz);
-}
-
-static int sst_platform_alloc_stream(struct snd_pcm_substream *substream)
-{
- struct sst_runtime_stream *stream =
- substream->runtime->private_data;
- struct sst_pcm_params param = {0};
- struct sst_stream_params str_params = {0};
- int ret_val;
-
- /* set codec params and inform SST driver the same */
- sst_fill_pcm_params(substream, &param);
- substream->runtime->dma_area = substream->dma_buffer.area;
- str_params.sparams = param;
- str_params.codec = param.codec;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- str_params.ops = STREAM_OPS_PLAYBACK;
- str_params.device_type = substream->pcm->device + 1;
- pr_debug("Playbck stream,Device %d\n",
- substream->pcm->device);
- } else {
- str_params.ops = STREAM_OPS_CAPTURE;
- str_params.device_type = SND_SST_DEVICE_CAPTURE;
- pr_debug("Capture stream,Device %d\n",
- substream->pcm->device);
- }
- ret_val = stream->ops->open(&str_params);
- pr_debug("SST_SND_PLAY/CAPTURE ret_val = %x\n", ret_val);
- if (ret_val < 0)
- return ret_val;
-
- stream->stream_info.str_id = ret_val;
- pr_debug("str id : %d\n", stream->stream_info.str_id);
- return ret_val;
-}
-
-static void sst_period_elapsed(void *mad_substream)
-{
- struct snd_pcm_substream *substream = mad_substream;
- struct sst_runtime_stream *stream;
- int status;
-
- if (!substream || !substream->runtime)
- return;
- stream = substream->runtime->private_data;
- if (!stream)
- return;
- status = sst_get_stream_status(stream);
- if (status != SST_PLATFORM_RUNNING)
- return;
- snd_pcm_period_elapsed(substream);
-}
-
-static int sst_platform_init_stream(struct snd_pcm_substream *substream)
-{
- struct sst_runtime_stream *stream =
- substream->runtime->private_data;
- int ret_val;
-
- pr_debug("setting buffer ptr param\n");
- sst_set_stream_status(stream, SST_PLATFORM_INIT);
- stream->stream_info.period_elapsed = sst_period_elapsed;
- stream->stream_info.mad_substream = substream;
- stream->stream_info.buffer_ptr = 0;
- stream->stream_info.sfreq = substream->runtime->rate;
- ret_val = stream->ops->device_control(
- SST_SND_STREAM_INIT, &stream->stream_info);
- if (ret_val)
- pr_err("control_set ret error %d\n", ret_val);
- return ret_val;
-
-}
-/* end -- helper functions */
-
-static int sst_platform_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct sst_runtime_stream *stream;
- int ret_val;
-
- pr_debug("sst_platform_open called\n");
-
- snd_soc_set_runtime_hwparams(substream, &sst_platform_pcm_hw);
- ret_val = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (ret_val < 0)
- return ret_val;
-
- stream = kzalloc(sizeof(*stream), GFP_KERNEL);
- if (!stream)
- return -ENOMEM;
- spin_lock_init(&stream->status_lock);
-
- /* get the sst ops */
- mutex_lock(&sst_lock);
- if (!sst) {
- pr_err("no device available to run\n");
- mutex_unlock(&sst_lock);
- kfree(stream);
- return -ENODEV;
- }
- if (!try_module_get(sst->dev->driver->owner)) {
- mutex_unlock(&sst_lock);
- kfree(stream);
- return -ENODEV;
- }
- stream->ops = sst->ops;
- mutex_unlock(&sst_lock);
-
- stream->stream_info.str_id = 0;
- sst_set_stream_status(stream, SST_PLATFORM_INIT);
- stream->stream_info.mad_substream = substream;
- /* allocate memory for SST API set */
- runtime->private_data = stream;
-
- return 0;
-}
-
-static int sst_platform_close(struct snd_pcm_substream *substream)
-{
- struct sst_runtime_stream *stream;
- int ret_val = 0, str_id;
-
- pr_debug("sst_platform_close called\n");
- stream = substream->runtime->private_data;
- str_id = stream->stream_info.str_id;
- if (str_id)
- ret_val = stream->ops->close(str_id);
- module_put(sst->dev->driver->owner);
- kfree(stream);
- return ret_val;
-}
-
-static int sst_platform_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct sst_runtime_stream *stream;
- int ret_val = 0, str_id;
-
- pr_debug("sst_platform_pcm_prepare called\n");
- stream = substream->runtime->private_data;
- str_id = stream->stream_info.str_id;
- if (stream->stream_info.str_id) {
- ret_val = stream->ops->device_control(
- SST_SND_DROP, &str_id);
- return ret_val;
- }
-
- ret_val = sst_platform_alloc_stream(substream);
- if (ret_val < 0)
- return ret_val;
- snprintf(substream->pcm->id, sizeof(substream->pcm->id),
- "%d", stream->stream_info.str_id);
-
- ret_val = sst_platform_init_stream(substream);
- if (ret_val)
- return ret_val;
- substream->runtime->hw.info = SNDRV_PCM_INFO_BLOCK_TRANSFER;
- return ret_val;
-}
-
-static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- int ret_val = 0, str_id;
- struct sst_runtime_stream *stream;
- int str_cmd, status;
-
- pr_debug("sst_platform_pcm_trigger called\n");
- stream = substream->runtime->private_data;
- str_id = stream->stream_info.str_id;
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- pr_debug("sst: Trigger Start\n");
- str_cmd = SST_SND_START;
- status = SST_PLATFORM_RUNNING;
- stream->stream_info.mad_substream = substream;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- pr_debug("sst: in stop\n");
- str_cmd = SST_SND_DROP;
- status = SST_PLATFORM_DROPPED;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- pr_debug("sst: in pause\n");
- str_cmd = SST_SND_PAUSE;
- status = SST_PLATFORM_PAUSED;
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- pr_debug("sst: in pause release\n");
- str_cmd = SST_SND_RESUME;
- status = SST_PLATFORM_RUNNING;
- break;
- default:
- return -EINVAL;
- }
- ret_val = stream->ops->device_control(str_cmd, &str_id);
- if (!ret_val)
- sst_set_stream_status(stream, status);
-
- return ret_val;
-}
-
-
-static snd_pcm_uframes_t sst_platform_pcm_pointer
- (struct snd_pcm_substream *substream)
-{
- struct sst_runtime_stream *stream;
- int ret_val, status;
- struct pcm_stream_info *str_info;
-
- stream = substream->runtime->private_data;
- status = sst_get_stream_status(stream);
- if (status == SST_PLATFORM_INIT)
- return 0;
- str_info = &stream->stream_info;
- ret_val = stream->ops->device_control(
- SST_SND_BUFFER_POINTER, str_info);
- if (ret_val) {
- pr_err("sst: error code = %d\n", ret_val);
- return ret_val;
- }
- return stream->stream_info.buffer_ptr;
-}
-
-static int sst_platform_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
- memset(substream->runtime->dma_area, 0, params_buffer_bytes(params));
-
- return 0;
-}
-
-static int sst_platform_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static struct snd_pcm_ops sst_platform_ops = {
- .open = sst_platform_open,
- .close = sst_platform_close,
- .ioctl = snd_pcm_lib_ioctl,
- .prepare = sst_platform_pcm_prepare,
- .trigger = sst_platform_pcm_trigger,
- .pointer = sst_platform_pcm_pointer,
- .hw_params = sst_platform_pcm_hw_params,
- .hw_free = sst_platform_pcm_hw_free,
-};
-
-static void sst_pcm_free(struct snd_pcm *pcm)
-{
- pr_debug("sst_pcm_free called\n");
- snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_pcm *pcm = rtd->pcm;
- int retval = 0;
-
- pr_debug("sst_pcm_new called\n");
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream ||
- pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- retval = snd_pcm_lib_preallocate_pages_for_all(pcm,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- SST_MIN_BUFFER, SST_MAX_BUFFER);
- if (retval) {
- pr_err("dma buffer allocationf fail\n");
- return retval;
- }
- }
- return retval;
-}
-static struct snd_soc_platform_driver sst_soc_platform_drv = {
- .ops = &sst_platform_ops,
- .pcm_new = sst_pcm_new,
- .pcm_free = sst_pcm_free,
-};
-
-static int sst_platform_probe(struct platform_device *pdev)
-{
- int ret;
-
- pr_debug("sst_platform_probe called\n");
- sst = NULL;
- ret = snd_soc_register_platform(&pdev->dev, &sst_soc_platform_drv);
- if (ret) {
- pr_err("registering soc platform failed\n");
- return ret;
- }
-
- ret = snd_soc_register_dais(&pdev->dev,
- sst_platform_dai, ARRAY_SIZE(sst_platform_dai));
- if (ret) {
- pr_err("registering cpu dais failed\n");
- snd_soc_unregister_platform(&pdev->dev);
- }
- return ret;
-}
-
-static int sst_platform_remove(struct platform_device *pdev)
-{
-
- snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sst_platform_dai));
- snd_soc_unregister_platform(&pdev->dev);
- pr_debug("sst_platform_remove success\n");
- return 0;
-}
-
-static struct platform_driver sst_platform_driver = {
- .driver = {
- .name = "sst-platform",
- .owner = THIS_MODULE,
- },
- .probe = sst_platform_probe,
- .remove = sst_platform_remove,
-};
-
-module_platform_driver(sst_platform_driver);
-
-MODULE_DESCRIPTION("ASoC Intel(R) MID Platform driver");
-MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
-MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:sst-platform");
diff --git a/ANDROID_3.4.5/sound/soc/mid-x86/sst_platform.h b/ANDROID_3.4.5/sound/soc/mid-x86/sst_platform.h
deleted file mode 100644
index f04f4f72..00000000
--- a/ANDROID_3.4.5/sound/soc/mid-x86/sst_platform.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * sst_platform.h - Intel MID Platform driver header file
- *
- * Copyright (C) 2010 Intel Corp
- * Author: Vinod Koul <vinod.koul@intel.com>
- * Author: Harsha Priya <priya.harsha@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *
- */
-
-#ifndef __SST_PLATFORMDRV_H__
-#define __SST_PLATFORMDRV_H__
-
-#define SST_MONO 1
-#define SST_STEREO 2
-#define SST_MAX_CAP 5
-
-#define SST_MIN_RATE 8000
-#define SST_MAX_RATE 48000
-#define SST_MIN_CHANNEL 1
-#define SST_MAX_CHANNEL 5
-#define SST_MAX_BUFFER (800*1024)
-#define SST_MIN_BUFFER (800*1024)
-#define SST_MIN_PERIOD_BYTES 32
-#define SST_MAX_PERIOD_BYTES SST_MAX_BUFFER
-#define SST_MIN_PERIODS 2
-#define SST_MAX_PERIODS (1024*2)
-#define SST_FIFO_SIZE 0
-#define SST_CODEC_TYPE_PCM 1
-
-struct pcm_stream_info {
- int str_id;
- void *mad_substream;
- void (*period_elapsed) (void *mad_substream);
- unsigned long long buffer_ptr;
- int sfreq;
-};
-
-enum sst_drv_status {
- SST_PLATFORM_INIT = 1,
- SST_PLATFORM_STARTED,
- SST_PLATFORM_RUNNING,
- SST_PLATFORM_PAUSED,
- SST_PLATFORM_DROPPED,
-};
-
-enum sst_controls {
- SST_SND_ALLOC = 0x00,
- SST_SND_PAUSE = 0x01,
- SST_SND_RESUME = 0x02,
- SST_SND_DROP = 0x03,
- SST_SND_FREE = 0x04,
- SST_SND_BUFFER_POINTER = 0x05,
- SST_SND_STREAM_INIT = 0x06,
- SST_SND_START = 0x07,
- SST_MAX_CONTROLS = 0x07,
-};
-
-enum sst_stream_ops {
- STREAM_OPS_PLAYBACK = 0,
- STREAM_OPS_CAPTURE,
-};
-
-enum sst_audio_device_type {
- SND_SST_DEVICE_HEADSET = 1,
- SND_SST_DEVICE_IHF,
- SND_SST_DEVICE_VIBRA,
- SND_SST_DEVICE_HAPTIC,
- SND_SST_DEVICE_CAPTURE,
-};
-
-/* PCM Parameters */
-struct sst_pcm_params {
- u16 codec; /* codec type */
- u8 num_chan; /* 1=Mono, 2=Stereo */
- u8 pcm_wd_sz; /* 16/24 - bit*/
- u32 reserved; /* Bitrate in bits per second */
- u32 sfreq; /* Sampling rate in Hz */
- u32 ring_buffer_size;
- u32 period_count; /* period elapsed in samples*/
- u32 ring_buffer_addr;
-};
-
-struct sst_stream_params {
- u32 result;
- u32 stream_id;
- u8 codec;
- u8 ops;
- u8 stream_type;
- u8 device_type;
- struct sst_pcm_params sparams;
-};
-
-struct sst_ops {
- int (*open) (struct sst_stream_params *str_param);
- int (*device_control) (int cmd, void *arg);
- int (*close) (unsigned int str_id);
-};
-
-struct sst_runtime_stream {
- int stream_status;
- struct pcm_stream_info stream_info;
- struct sst_ops *ops;
- spinlock_t status_lock;
-};
-
-struct sst_device {
- char *name;
- struct device *dev;
- struct sst_ops *ops;
-};
-
-int sst_register_dsp(struct sst_device *sst);
-int sst_unregister_dsp(struct sst_device *sst);
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/mxs/Kconfig b/ANDROID_3.4.5/sound/soc/mxs/Kconfig
deleted file mode 100644
index 99a997f1..00000000
--- a/ANDROID_3.4.5/sound/soc/mxs/Kconfig
+++ /dev/null
@@ -1,20 +0,0 @@
-menuconfig SND_MXS_SOC
- tristate "SoC Audio for Freescale MXS CPUs"
- depends on ARCH_MXS
- select SND_SOC_DMAENGINE_PCM
- help
- Say Y or M if you want to add support for codecs attached to
- the MXS SAIF interface.
-
-
-if SND_MXS_SOC
-
-config SND_SOC_MXS_SGTL5000
- tristate "SoC Audio support for i.MX boards with sgtl5000"
- depends on I2C
- select SND_SOC_SGTL5000
- help
- Say Y if you want to add support for SoC audio on an MXS board with
- a sgtl5000 codec.
-
-endif # SND_MXS_SOC
diff --git a/ANDROID_3.4.5/sound/soc/mxs/Makefile b/ANDROID_3.4.5/sound/soc/mxs/Makefile
deleted file mode 100644
index 565b5b51..00000000
--- a/ANDROID_3.4.5/sound/soc/mxs/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# MXS Platform Support
-snd-soc-mxs-objs := mxs-saif.o
-snd-soc-mxs-pcm-objs := mxs-pcm.o
-
-obj-$(CONFIG_SND_MXS_SOC) += snd-soc-mxs.o snd-soc-mxs-pcm.o
-
-# i.MX Machine Support
-snd-soc-mxs-sgtl5000-objs := mxs-sgtl5000.o
-
-obj-$(CONFIG_SND_SOC_MXS_SGTL5000) += snd-soc-mxs-sgtl5000.o
diff --git a/ANDROID_3.4.5/sound/soc/mxs/mxs-pcm.c b/ANDROID_3.4.5/sound/soc/mxs/mxs-pcm.c
deleted file mode 100644
index e373fbbc..00000000
--- a/ANDROID_3.4.5/sound/soc/mxs/mxs-pcm.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * Based on sound/soc/imx/imx-pcm-dma-mx2.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/dmaengine.h>
-#include <linux/fsl/mxs-dma.h>
-
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/dmaengine_pcm.h>
-
-#include "mxs-pcm.h"
-
-struct mxs_pcm_dma_data {
- struct mxs_dma_data dma_data;
- struct mxs_pcm_dma_params *dma_params;
-};
-
-static struct snd_pcm_hardware snd_mxs_hardware = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_INTERLEAVED,
- .formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S20_3LE |
- SNDRV_PCM_FMTBIT_S24_LE,
- .channels_min = 2,
- .channels_max = 2,
- .period_bytes_min = 32,
- .period_bytes_max = 8192,
- .periods_min = 1,
- .periods_max = 52,
- .buffer_bytes_max = 64 * 1024,
- .fifo_size = 32,
-
-};
-
-static bool filter(struct dma_chan *chan, void *param)
-{
- struct mxs_pcm_dma_data *pcm_dma_data = param;
- struct mxs_pcm_dma_params *dma_params = pcm_dma_data->dma_params;
-
- if (!mxs_dma_is_apbx(chan))
- return false;
-
- if (chan->chan_id != dma_params->chan_num)
- return false;
-
- chan->private = &pcm_dma_data->dma_data;
-
- return true;
-}
-
-static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
-
- return 0;
-}
-
-static int snd_mxs_open(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct mxs_pcm_dma_data *pcm_dma_data;
- int ret;
-
- pcm_dma_data = kzalloc(sizeof(*pcm_dma_data), GFP_KERNEL);
- if (pcm_dma_data == NULL)
- return -ENOMEM;
-
- pcm_dma_data->dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
- pcm_dma_data->dma_data.chan_irq = pcm_dma_data->dma_params->chan_irq;
-
- ret = snd_dmaengine_pcm_open(substream, filter, pcm_dma_data);
- if (ret) {
- kfree(pcm_dma_data);
- return ret;
- }
-
- snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware);
-
- snd_dmaengine_pcm_set_data(substream, pcm_dma_data);
-
- return 0;
-}
-
-static int snd_mxs_close(struct snd_pcm_substream *substream)
-{
- struct mxs_pcm_dma_data *pcm_dma_data = snd_dmaengine_pcm_get_data(substream);
-
- snd_dmaengine_pcm_close(substream);
- kfree(pcm_dma_data);
-
- return 0;
-}
-
-static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- return dma_mmap_writecombine(substream->pcm->card->dev, vma,
- runtime->dma_area,
- runtime->dma_addr,
- runtime->dma_bytes);
-}
-
-static struct snd_pcm_ops mxs_pcm_ops = {
- .open = snd_mxs_open,
- .close = snd_mxs_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_mxs_pcm_hw_params,
- .trigger = snd_dmaengine_pcm_trigger,
- .pointer = snd_dmaengine_pcm_pointer,
- .mmap = snd_mxs_pcm_mmap,
-};
-
-static int mxs_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
- struct snd_pcm_substream *substream = pcm->streams[stream].substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = snd_mxs_hardware.buffer_bytes_max;
-
- buf->dev.type = SNDRV_DMA_TYPE_DEV;
- buf->dev.dev = pcm->card->dev;
- buf->private_data = NULL;
- buf->area = dma_alloc_writecombine(pcm->card->dev, size,
- &buf->addr, GFP_KERNEL);
- if (!buf->area)
- return -ENOMEM;
- buf->bytes = size;
-
- return 0;
-}
-
-static u64 mxs_pcm_dmamask = DMA_BIT_MASK(32);
-static int mxs_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- int ret = 0;
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &mxs_pcm_dmamask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = mxs_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_PLAYBACK);
- if (ret)
- goto out;
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- ret = mxs_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_CAPTURE);
- if (ret)
- goto out;
- }
-
-out:
- return ret;
-}
-
-static void mxs_pcm_free(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- struct snd_dma_buffer *buf;
- int stream;
-
- for (stream = 0; stream < 2; stream++) {
- substream = pcm->streams[stream].substream;
- if (!substream)
- continue;
-
- buf = &substream->dma_buffer;
- if (!buf->area)
- continue;
-
- dma_free_writecombine(pcm->card->dev, buf->bytes,
- buf->area, buf->addr);
- buf->area = NULL;
- }
-}
-
-static struct snd_soc_platform_driver mxs_soc_platform = {
- .ops = &mxs_pcm_ops,
- .pcm_new = mxs_pcm_new,
- .pcm_free = mxs_pcm_free,
-};
-
-static int __devinit mxs_soc_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_platform(&pdev->dev, &mxs_soc_platform);
-}
-
-static int __devexit mxs_soc_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
-
- return 0;
-}
-
-static struct platform_driver mxs_pcm_driver = {
- .driver = {
- .name = "mxs-pcm-audio",
- .owner = THIS_MODULE,
- },
- .probe = mxs_soc_platform_probe,
- .remove = __devexit_p(mxs_soc_platform_remove),
-};
-
-module_platform_driver(mxs_pcm_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:mxs-pcm-audio");
diff --git a/ANDROID_3.4.5/sound/soc/mxs/mxs-pcm.h b/ANDROID_3.4.5/sound/soc/mxs/mxs-pcm.h
deleted file mode 100644
index 5f01a912..00000000
--- a/ANDROID_3.4.5/sound/soc/mxs/mxs-pcm.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef _MXS_PCM_H
-#define _MXS_PCM_H
-
-struct mxs_pcm_dma_params {
- int chan_irq;
- int chan_num;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/mxs/mxs-saif.c b/ANDROID_3.4.5/sound/soc/mxs/mxs-saif.c
deleted file mode 100644
index 53f4fd8f..00000000
--- a/ANDROID_3.4.5/sound/soc/mxs/mxs-saif.c
+++ /dev/null
@@ -1,762 +0,0 @@
-/*
- * Copyright 2011 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/dma-mapping.h>
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/time.h>
-#include <linux/fsl/mxs-dma.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/saif.h>
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/mxs.h>
-
-#include "mxs-saif.h"
-
-static struct mxs_saif *mxs_saif[2];
-
-/*
- * SAIF is a little different with other normal SOC DAIs on clock using.
- *
- * For MXS, two SAIF modules are instantiated on-chip.
- * Each SAIF has a set of clock pins and can be operating in master
- * mode simultaneously if they are connected to different off-chip codecs.
- * Also, one of the two SAIFs can master or drive the clock pins while the
- * other SAIF, in slave mode, receives clocking from the master SAIF.
- * This also means that both SAIFs must operate at the same sample rate.
- *
- * We abstract this as each saif has a master, the master could be
- * himself or other saifs. In the generic saif driver, saif does not need
- * to know the different clkmux. Saif only needs to know who is his master
- * and operating his master to generate the proper clock rate for him.
- * The master id is provided in mach-specific layer according to different
- * clkmux setting.
- */
-
-static int mxs_saif_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
-
- switch (clk_id) {
- case MXS_SAIF_MCLK:
- saif->mclk = freq;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-/*
- * Since SAIF may work on EXTMASTER mode, IOW, it's working BITCLK&LRCLK
- * is provided by other SAIF, we provide a interface here to get its master
- * from its master_id.
- * Note that the master could be himself.
- */
-static inline struct mxs_saif *mxs_saif_get_master(struct mxs_saif * saif)
-{
- return mxs_saif[saif->master_id];
-}
-
-/*
- * Set SAIF clock and MCLK
- */
-static int mxs_saif_set_clk(struct mxs_saif *saif,
- unsigned int mclk,
- unsigned int rate)
-{
- u32 scr;
- int ret;
- struct mxs_saif *master_saif;
-
- dev_dbg(saif->dev, "mclk %d rate %d\n", mclk, rate);
-
- /* Set master saif to generate proper clock */
- master_saif = mxs_saif_get_master(saif);
- if (!master_saif)
- return -EINVAL;
-
- dev_dbg(saif->dev, "master saif%d\n", master_saif->id);
-
- /* Checking if can playback and capture simutaneously */
- if (master_saif->ongoing && rate != master_saif->cur_rate) {
- dev_err(saif->dev,
- "can not change clock, master saif%d(rate %d) is ongoing\n",
- master_saif->id, master_saif->cur_rate);
- return -EINVAL;
- }
-
- scr = __raw_readl(master_saif->base + SAIF_CTRL);
- scr &= ~BM_SAIF_CTRL_BITCLK_MULT_RATE;
- scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
-
- /*
- * Set SAIF clock
- *
- * The SAIF clock should be either 384*fs or 512*fs.
- * If MCLK is used, the SAIF clk ratio need to match mclk ratio.
- * For 32x mclk, set saif clk as 512*fs.
- * For 48x mclk, set saif clk as 384*fs.
- *
- * If MCLK is not used, we just set saif clk to 512*fs.
- */
- clk_prepare_enable(master_saif->clk);
-
- if (master_saif->mclk_in_use) {
- if (mclk % 32 == 0) {
- scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
- ret = clk_set_rate(master_saif->clk, 512 * rate);
- } else if (mclk % 48 == 0) {
- scr |= BM_SAIF_CTRL_BITCLK_BASE_RATE;
- ret = clk_set_rate(master_saif->clk, 384 * rate);
- } else {
- /* SAIF MCLK should be either 32x or 48x */
- clk_disable_unprepare(master_saif->clk);
- return -EINVAL;
- }
- } else {
- ret = clk_set_rate(master_saif->clk, 512 * rate);
- scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
- }
-
- clk_disable_unprepare(master_saif->clk);
-
- if (ret)
- return ret;
-
- master_saif->cur_rate = rate;
-
- if (!master_saif->mclk_in_use) {
- __raw_writel(scr, master_saif->base + SAIF_CTRL);
- return 0;
- }
-
- /*
- * Program the over-sample rate for MCLK output
- *
- * The available MCLK range is 32x, 48x... 512x. The rate
- * could be from 8kHz to 192kH.
- */
- switch (mclk / rate) {
- case 32:
- scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(4);
- break;
- case 64:
- scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(3);
- break;
- case 128:
- scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(2);
- break;
- case 256:
- scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(1);
- break;
- case 512:
- scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(0);
- break;
- case 48:
- scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(3);
- break;
- case 96:
- scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(2);
- break;
- case 192:
- scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(1);
- break;
- case 384:
- scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(0);
- break;
- default:
- return -EINVAL;
- }
-
- __raw_writel(scr, master_saif->base + SAIF_CTRL);
-
- return 0;
-}
-
-/*
- * Put and disable MCLK.
- */
-int mxs_saif_put_mclk(unsigned int saif_id)
-{
- struct mxs_saif *saif = mxs_saif[saif_id];
- u32 stat;
-
- if (!saif)
- return -EINVAL;
-
- stat = __raw_readl(saif->base + SAIF_STAT);
- if (stat & BM_SAIF_STAT_BUSY) {
- dev_err(saif->dev, "error: busy\n");
- return -EBUSY;
- }
-
- clk_disable_unprepare(saif->clk);
-
- /* disable MCLK output */
- __raw_writel(BM_SAIF_CTRL_CLKGATE,
- saif->base + SAIF_CTRL + MXS_SET_ADDR);
- __raw_writel(BM_SAIF_CTRL_RUN,
- saif->base + SAIF_CTRL + MXS_CLR_ADDR);
-
- saif->mclk_in_use = 0;
- return 0;
-}
-
-/*
- * Get MCLK and set clock rate, then enable it
- *
- * This interface is used for codecs who are using MCLK provided
- * by saif.
- */
-int mxs_saif_get_mclk(unsigned int saif_id, unsigned int mclk,
- unsigned int rate)
-{
- struct mxs_saif *saif = mxs_saif[saif_id];
- u32 stat;
- int ret;
- struct mxs_saif *master_saif;
-
- if (!saif)
- return -EINVAL;
-
- /* Clear Reset */
- __raw_writel(BM_SAIF_CTRL_SFTRST,
- saif->base + SAIF_CTRL + MXS_CLR_ADDR);
-
- /* FIXME: need clear clk gate for register r/w */
- __raw_writel(BM_SAIF_CTRL_CLKGATE,
- saif->base + SAIF_CTRL + MXS_CLR_ADDR);
-
- master_saif = mxs_saif_get_master(saif);
- if (saif != master_saif) {
- dev_err(saif->dev, "can not get mclk from a non-master saif\n");
- return -EINVAL;
- }
-
- stat = __raw_readl(saif->base + SAIF_STAT);
- if (stat & BM_SAIF_STAT_BUSY) {
- dev_err(saif->dev, "error: busy\n");
- return -EBUSY;
- }
-
- saif->mclk_in_use = 1;
- ret = mxs_saif_set_clk(saif, mclk, rate);
- if (ret)
- return ret;
-
- ret = clk_prepare_enable(saif->clk);
- if (ret)
- return ret;
-
- /* enable MCLK output */
- __raw_writel(BM_SAIF_CTRL_RUN,
- saif->base + SAIF_CTRL + MXS_SET_ADDR);
-
- return 0;
-}
-
-/*
- * SAIF DAI format configuration.
- * Should only be called when port is inactive.
- */
-static int mxs_saif_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
-{
- u32 scr, stat;
- u32 scr0;
- struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
-
- stat = __raw_readl(saif->base + SAIF_STAT);
- if (stat & BM_SAIF_STAT_BUSY) {
- dev_err(cpu_dai->dev, "error: busy\n");
- return -EBUSY;
- }
-
- scr0 = __raw_readl(saif->base + SAIF_CTRL);
- scr0 = scr0 & ~BM_SAIF_CTRL_BITCLK_EDGE & ~BM_SAIF_CTRL_LRCLK_POLARITY \
- & ~BM_SAIF_CTRL_JUSTIFY & ~BM_SAIF_CTRL_DELAY;
- scr = 0;
-
- /* DAI mode */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- /* data frame low 1clk before data */
- scr |= BM_SAIF_CTRL_DELAY;
- scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- /* data frame high with data */
- scr &= ~BM_SAIF_CTRL_DELAY;
- scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
- scr &= ~BM_SAIF_CTRL_JUSTIFY;
- break;
- default:
- return -EINVAL;
- }
-
- /* DAI clock inversion */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_IB_IF:
- scr |= BM_SAIF_CTRL_BITCLK_EDGE;
- scr |= BM_SAIF_CTRL_LRCLK_POLARITY;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- scr |= BM_SAIF_CTRL_BITCLK_EDGE;
- scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- scr &= ~BM_SAIF_CTRL_BITCLK_EDGE;
- scr |= BM_SAIF_CTRL_LRCLK_POLARITY;
- break;
- case SND_SOC_DAIFMT_NB_NF:
- scr &= ~BM_SAIF_CTRL_BITCLK_EDGE;
- scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
- break;
- }
-
- /*
- * Note: We simply just support master mode since SAIF TX can only
- * work as master.
- * Here the master is relative to codec side.
- * Saif internally could be slave when working on EXTMASTER mode.
- * We just hide this to machine driver.
- */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- if (saif->id == saif->master_id)
- scr &= ~BM_SAIF_CTRL_SLAVE_MODE;
- else
- scr |= BM_SAIF_CTRL_SLAVE_MODE;
-
- __raw_writel(scr | scr0, saif->base + SAIF_CTRL);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int mxs_saif_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *cpu_dai)
-{
- struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
- snd_soc_dai_set_dma_data(cpu_dai, substream, &saif->dma_param);
-
- /* clear error status to 0 for each re-open */
- saif->fifo_underrun = 0;
- saif->fifo_overrun = 0;
-
- /* Clear Reset for normal operations */
- __raw_writel(BM_SAIF_CTRL_SFTRST,
- saif->base + SAIF_CTRL + MXS_CLR_ADDR);
-
- /* clear clock gate */
- __raw_writel(BM_SAIF_CTRL_CLKGATE,
- saif->base + SAIF_CTRL + MXS_CLR_ADDR);
-
- return 0;
-}
-
-/*
- * Should only be called when port is inactive.
- * although can be called multiple times by upper layers.
- */
-static int mxs_saif_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *cpu_dai)
-{
- struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
- u32 scr, stat;
- int ret;
-
- /* mclk should already be set */
- if (!saif->mclk && saif->mclk_in_use) {
- dev_err(cpu_dai->dev, "set mclk first\n");
- return -EINVAL;
- }
-
- stat = __raw_readl(saif->base + SAIF_STAT);
- if (stat & BM_SAIF_STAT_BUSY) {
- dev_err(cpu_dai->dev, "error: busy\n");
- return -EBUSY;
- }
-
- /*
- * Set saif clk based on sample rate.
- * If mclk is used, we also set mclk, if not, saif->mclk is
- * default 0, means not used.
- */
- ret = mxs_saif_set_clk(saif, saif->mclk, params_rate(params));
- if (ret) {
- dev_err(cpu_dai->dev, "unable to get proper clk\n");
- return ret;
- }
-
- scr = __raw_readl(saif->base + SAIF_CTRL);
-
- scr &= ~BM_SAIF_CTRL_WORD_LENGTH;
- scr &= ~BM_SAIF_CTRL_BITCLK_48XFS_ENABLE;
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- scr |= BF_SAIF_CTRL_WORD_LENGTH(0);
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- scr |= BF_SAIF_CTRL_WORD_LENGTH(4);
- scr |= BM_SAIF_CTRL_BITCLK_48XFS_ENABLE;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- scr |= BF_SAIF_CTRL_WORD_LENGTH(8);
- scr |= BM_SAIF_CTRL_BITCLK_48XFS_ENABLE;
- break;
- default:
- return -EINVAL;
- }
-
- /* Tx/Rx config */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- /* enable TX mode */
- scr &= ~BM_SAIF_CTRL_READ_MODE;
- } else {
- /* enable RX mode */
- scr |= BM_SAIF_CTRL_READ_MODE;
- }
-
- __raw_writel(scr, saif->base + SAIF_CTRL);
- return 0;
-}
-
-static int mxs_saif_prepare(struct snd_pcm_substream *substream,
- struct snd_soc_dai *cpu_dai)
-{
- struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
-
- /* enable FIFO error irqs */
- __raw_writel(BM_SAIF_CTRL_FIFO_ERROR_IRQ_EN,
- saif->base + SAIF_CTRL + MXS_SET_ADDR);
-
- return 0;
-}
-
-static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *cpu_dai)
-{
- struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
- struct mxs_saif *master_saif;
- u32 delay;
-
- master_saif = mxs_saif_get_master(saif);
- if (!master_saif)
- return -EINVAL;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- dev_dbg(cpu_dai->dev, "start\n");
-
- clk_enable(master_saif->clk);
- if (!master_saif->mclk_in_use)
- __raw_writel(BM_SAIF_CTRL_RUN,
- master_saif->base + SAIF_CTRL + MXS_SET_ADDR);
-
- /*
- * If the saif's master is not himself, we also need to enable
- * itself clk for its internal basic logic to work.
- */
- if (saif != master_saif) {
- clk_enable(saif->clk);
- __raw_writel(BM_SAIF_CTRL_RUN,
- saif->base + SAIF_CTRL + MXS_SET_ADDR);
- }
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- /*
- * write a data to saif data register to trigger
- * the transfer
- */
- __raw_writel(0, saif->base + SAIF_DATA);
- } else {
- /*
- * read a data from saif data register to trigger
- * the receive
- */
- __raw_readl(saif->base + SAIF_DATA);
- }
-
- master_saif->ongoing = 1;
-
- dev_dbg(saif->dev, "CTRL 0x%x STAT 0x%x\n",
- __raw_readl(saif->base + SAIF_CTRL),
- __raw_readl(saif->base + SAIF_STAT));
-
- dev_dbg(master_saif->dev, "CTRL 0x%x STAT 0x%x\n",
- __raw_readl(master_saif->base + SAIF_CTRL),
- __raw_readl(master_saif->base + SAIF_STAT));
- break;
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- dev_dbg(cpu_dai->dev, "stop\n");
-
- /* wait a while for the current sample to complete */
- delay = USEC_PER_SEC / master_saif->cur_rate;
-
- if (!master_saif->mclk_in_use) {
- __raw_writel(BM_SAIF_CTRL_RUN,
- master_saif->base + SAIF_CTRL + MXS_CLR_ADDR);
- udelay(delay);
- }
- clk_disable(master_saif->clk);
-
- if (saif != master_saif) {
- __raw_writel(BM_SAIF_CTRL_RUN,
- saif->base + SAIF_CTRL + MXS_CLR_ADDR);
- udelay(delay);
- clk_disable(saif->clk);
- }
-
- master_saif->ongoing = 0;
-
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-#define MXS_SAIF_RATES SNDRV_PCM_RATE_8000_192000
-#define MXS_SAIF_FORMATS \
- (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static const struct snd_soc_dai_ops mxs_saif_dai_ops = {
- .startup = mxs_saif_startup,
- .trigger = mxs_saif_trigger,
- .prepare = mxs_saif_prepare,
- .hw_params = mxs_saif_hw_params,
- .set_sysclk = mxs_saif_set_dai_sysclk,
- .set_fmt = mxs_saif_set_dai_fmt,
-};
-
-static int mxs_saif_dai_probe(struct snd_soc_dai *dai)
-{
- struct mxs_saif *saif = dev_get_drvdata(dai->dev);
-
- snd_soc_dai_set_drvdata(dai, saif);
-
- return 0;
-}
-
-static struct snd_soc_dai_driver mxs_saif_dai = {
- .name = "mxs-saif",
- .probe = mxs_saif_dai_probe,
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = MXS_SAIF_RATES,
- .formats = MXS_SAIF_FORMATS,
- },
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = MXS_SAIF_RATES,
- .formats = MXS_SAIF_FORMATS,
- },
- .ops = &mxs_saif_dai_ops,
-};
-
-static irqreturn_t mxs_saif_irq(int irq, void *dev_id)
-{
- struct mxs_saif *saif = dev_id;
- unsigned int stat;
-
- stat = __raw_readl(saif->base + SAIF_STAT);
- if (!(stat & (BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ |
- BM_SAIF_STAT_FIFO_OVERFLOW_IRQ)))
- return IRQ_NONE;
-
- if (stat & BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ) {
- dev_dbg(saif->dev, "underrun!!! %d\n", ++saif->fifo_underrun);
- __raw_writel(BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ,
- saif->base + SAIF_STAT + MXS_CLR_ADDR);
- }
-
- if (stat & BM_SAIF_STAT_FIFO_OVERFLOW_IRQ) {
- dev_dbg(saif->dev, "overrun!!! %d\n", ++saif->fifo_overrun);
- __raw_writel(BM_SAIF_STAT_FIFO_OVERFLOW_IRQ,
- saif->base + SAIF_STAT + MXS_CLR_ADDR);
- }
-
- dev_dbg(saif->dev, "SAIF_CTRL %x SAIF_STAT %x\n",
- __raw_readl(saif->base + SAIF_CTRL),
- __raw_readl(saif->base + SAIF_STAT));
-
- return IRQ_HANDLED;
-}
-
-static int mxs_saif_probe(struct platform_device *pdev)
-{
- struct resource *iores, *dmares;
- struct mxs_saif *saif;
- struct mxs_saif_platform_data *pdata;
- int ret = 0;
-
- if (pdev->id >= ARRAY_SIZE(mxs_saif))
- return -EINVAL;
-
- saif = devm_kzalloc(&pdev->dev, sizeof(*saif), GFP_KERNEL);
- if (!saif)
- return -ENOMEM;
-
- mxs_saif[pdev->id] = saif;
- saif->id = pdev->id;
-
- pdata = pdev->dev.platform_data;
- if (pdata && !pdata->master_mode) {
- saif->master_id = pdata->master_id;
- if (saif->master_id < 0 ||
- saif->master_id >= ARRAY_SIZE(mxs_saif) ||
- saif->master_id == saif->id) {
- dev_err(&pdev->dev, "get wrong master id\n");
- return -EINVAL;
- }
- } else {
- saif->master_id = saif->id;
- }
-
- saif->clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(saif->clk)) {
- ret = PTR_ERR(saif->clk);
- dev_err(&pdev->dev, "Cannot get the clock: %d\n",
- ret);
- return ret;
- }
-
- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
- saif->base = devm_request_and_ioremap(&pdev->dev, iores);
- if (!saif->base) {
- dev_err(&pdev->dev, "ioremap failed\n");
- ret = -ENODEV;
- goto failed_get_resource;
- }
-
- dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!dmares) {
- ret = -ENODEV;
- dev_err(&pdev->dev, "failed to get dma resource: %d\n",
- ret);
- goto failed_get_resource;
- }
- saif->dma_param.chan_num = dmares->start;
-
- saif->irq = platform_get_irq(pdev, 0);
- if (saif->irq < 0) {
- ret = saif->irq;
- dev_err(&pdev->dev, "failed to get irq resource: %d\n",
- ret);
- goto failed_get_resource;
- }
-
- saif->dev = &pdev->dev;
- ret = devm_request_irq(&pdev->dev, saif->irq, mxs_saif_irq, 0,
- "mxs-saif", saif);
- if (ret) {
- dev_err(&pdev->dev, "failed to request irq\n");
- goto failed_get_resource;
- }
-
- saif->dma_param.chan_irq = platform_get_irq(pdev, 1);
- if (saif->dma_param.chan_irq < 0) {
- ret = saif->dma_param.chan_irq;
- dev_err(&pdev->dev, "failed to get dma irq resource: %d\n",
- ret);
- goto failed_get_resource;
- }
-
- platform_set_drvdata(pdev, saif);
-
- ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai);
- if (ret) {
- dev_err(&pdev->dev, "register DAI failed\n");
- goto failed_get_resource;
- }
-
- saif->soc_platform_pdev = platform_device_alloc(
- "mxs-pcm-audio", pdev->id);
- if (!saif->soc_platform_pdev) {
- ret = -ENOMEM;
- goto failed_pdev_alloc;
- }
-
- platform_set_drvdata(saif->soc_platform_pdev, saif);
- ret = platform_device_add(saif->soc_platform_pdev);
- if (ret) {
- dev_err(&pdev->dev, "failed to add soc platform device\n");
- goto failed_pdev_add;
- }
-
- return 0;
-
-failed_pdev_add:
- platform_device_put(saif->soc_platform_pdev);
-failed_pdev_alloc:
- snd_soc_unregister_dai(&pdev->dev);
-failed_get_resource:
- clk_put(saif->clk);
-
- return ret;
-}
-
-static int __devexit mxs_saif_remove(struct platform_device *pdev)
-{
- struct mxs_saif *saif = platform_get_drvdata(pdev);
-
- platform_device_unregister(saif->soc_platform_pdev);
- snd_soc_unregister_dai(&pdev->dev);
- clk_put(saif->clk);
-
- return 0;
-}
-
-static struct platform_driver mxs_saif_driver = {
- .probe = mxs_saif_probe,
- .remove = __devexit_p(mxs_saif_remove),
-
- .driver = {
- .name = "mxs-saif",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(mxs_saif_driver);
-
-MODULE_AUTHOR("Freescale Semiconductor, Inc.");
-MODULE_DESCRIPTION("MXS ASoC SAIF driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/mxs/mxs-saif.h b/ANDROID_3.4.5/sound/soc/mxs/mxs-saif.h
deleted file mode 100644
index 12c91e4e..00000000
--- a/ANDROID_3.4.5/sound/soc/mxs/mxs-saif.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-
-#ifndef _MXS_SAIF_H
-#define _MXS_SAIF_H
-
-#define SAIF_CTRL 0x0
-#define SAIF_STAT 0x10
-#define SAIF_DATA 0x20
-#define SAIF_VERSION 0X30
-
-/* SAIF_CTRL */
-#define BM_SAIF_CTRL_SFTRST 0x80000000
-#define BM_SAIF_CTRL_CLKGATE 0x40000000
-#define BP_SAIF_CTRL_BITCLK_MULT_RATE 27
-#define BM_SAIF_CTRL_BITCLK_MULT_RATE 0x38000000
-#define BF_SAIF_CTRL_BITCLK_MULT_RATE(v) \
- (((v) << 27) & BM_SAIF_CTRL_BITCLK_MULT_RATE)
-#define BM_SAIF_CTRL_BITCLK_BASE_RATE 0x04000000
-#define BM_SAIF_CTRL_FIFO_ERROR_IRQ_EN 0x02000000
-#define BM_SAIF_CTRL_FIFO_SERVICE_IRQ_EN 0x01000000
-#define BP_SAIF_CTRL_RSRVD2 21
-#define BM_SAIF_CTRL_RSRVD2 0x00E00000
-
-#define BP_SAIF_CTRL_DMAWAIT_COUNT 16
-#define BM_SAIF_CTRL_DMAWAIT_COUNT 0x001F0000
-#define BF_SAIF_CTRL_DMAWAIT_COUNT(v) \
- (((v) << 16) & BM_SAIF_CTRL_DMAWAIT_COUNT)
-#define BP_SAIF_CTRL_CHANNEL_NUM_SELECT 14
-#define BM_SAIF_CTRL_CHANNEL_NUM_SELECT 0x0000C000
-#define BF_SAIF_CTRL_CHANNEL_NUM_SELECT(v) \
- (((v) << 14) & BM_SAIF_CTRL_CHANNEL_NUM_SELECT)
-#define BM_SAIF_CTRL_LRCLK_PULSE 0x00002000
-#define BM_SAIF_CTRL_BIT_ORDER 0x00001000
-#define BM_SAIF_CTRL_DELAY 0x00000800
-#define BM_SAIF_CTRL_JUSTIFY 0x00000400
-#define BM_SAIF_CTRL_LRCLK_POLARITY 0x00000200
-#define BM_SAIF_CTRL_BITCLK_EDGE 0x00000100
-#define BP_SAIF_CTRL_WORD_LENGTH 4
-#define BM_SAIF_CTRL_WORD_LENGTH 0x000000F0
-#define BF_SAIF_CTRL_WORD_LENGTH(v) \
- (((v) << 4) & BM_SAIF_CTRL_WORD_LENGTH)
-#define BM_SAIF_CTRL_BITCLK_48XFS_ENABLE 0x00000008
-#define BM_SAIF_CTRL_SLAVE_MODE 0x00000004
-#define BM_SAIF_CTRL_READ_MODE 0x00000002
-#define BM_SAIF_CTRL_RUN 0x00000001
-
-/* SAIF_STAT */
-#define BM_SAIF_STAT_PRESENT 0x80000000
-#define BP_SAIF_STAT_RSRVD2 17
-#define BM_SAIF_STAT_RSRVD2 0x7FFE0000
-#define BF_SAIF_STAT_RSRVD2(v) \
- (((v) << 17) & BM_SAIF_STAT_RSRVD2)
-#define BM_SAIF_STAT_DMA_PREQ 0x00010000
-#define BP_SAIF_STAT_RSRVD1 7
-#define BM_SAIF_STAT_RSRVD1 0x0000FF80
-#define BF_SAIF_STAT_RSRVD1(v) \
- (((v) << 7) & BM_SAIF_STAT_RSRVD1)
-
-#define BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ 0x00000040
-#define BM_SAIF_STAT_FIFO_OVERFLOW_IRQ 0x00000020
-#define BM_SAIF_STAT_FIFO_SERVICE_IRQ 0x00000010
-#define BP_SAIF_STAT_RSRVD0 1
-#define BM_SAIF_STAT_RSRVD0 0x0000000E
-#define BF_SAIF_STAT_RSRVD0(v) \
- (((v) << 1) & BM_SAIF_STAT_RSRVD0)
-#define BM_SAIF_STAT_BUSY 0x00000001
-
-/* SAFI_DATA */
-#define BP_SAIF_DATA_PCM_RIGHT 16
-#define BM_SAIF_DATA_PCM_RIGHT 0xFFFF0000
-#define BF_SAIF_DATA_PCM_RIGHT(v) \
- (((v) << 16) & BM_SAIF_DATA_PCM_RIGHT)
-#define BP_SAIF_DATA_PCM_LEFT 0
-#define BM_SAIF_DATA_PCM_LEFT 0x0000FFFF
-#define BF_SAIF_DATA_PCM_LEFT(v) \
- (((v) << 0) & BM_SAIF_DATA_PCM_LEFT)
-
-/* SAIF_VERSION */
-#define BP_SAIF_VERSION_MAJOR 24
-#define BM_SAIF_VERSION_MAJOR 0xFF000000
-#define BF_SAIF_VERSION_MAJOR(v) \
- (((v) << 24) & BM_SAIF_VERSION_MAJOR)
-#define BP_SAIF_VERSION_MINOR 16
-#define BM_SAIF_VERSION_MINOR 0x00FF0000
-#define BF_SAIF_VERSION_MINOR(v) \
- (((v) << 16) & BM_SAIF_VERSION_MINOR)
-#define BP_SAIF_VERSION_STEP 0
-#define BM_SAIF_VERSION_STEP 0x0000FFFF
-#define BF_SAIF_VERSION_STEP(v) \
- (((v) << 0) & BM_SAIF_VERSION_STEP)
-
-#define MXS_SAIF_MCLK 0
-
-#include "mxs-pcm.h"
-
-struct mxs_saif {
- struct device *dev;
- struct clk *clk;
- unsigned int mclk;
- unsigned int mclk_in_use;
- void __iomem *base;
- int irq;
- struct mxs_pcm_dma_params dma_param;
- unsigned int id;
- unsigned int master_id;
- unsigned int cur_rate;
- unsigned int ongoing;
-
- struct platform_device *soc_platform_pdev;
- u32 fifo_underrun;
- u32 fifo_overrun;
-};
-
-extern int mxs_saif_put_mclk(unsigned int saif_id);
-extern int mxs_saif_get_mclk(unsigned int saif_id, unsigned int mclk,
- unsigned int rate);
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/mxs/mxs-sgtl5000.c b/ANDROID_3.4.5/sound/soc/mxs/mxs-sgtl5000.c
deleted file mode 100644
index 60f052b7..00000000
--- a/ANDROID_3.4.5/sound/soc/mxs/mxs-sgtl5000.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright 2011 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/jack.h>
-#include <sound/soc-dapm.h>
-#include <asm/mach-types.h>
-
-#include "../codecs/sgtl5000.h"
-#include "mxs-saif.h"
-
-static int mxs_sgtl5000_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- unsigned int rate = params_rate(params);
- u32 dai_format, mclk;
- int ret;
-
- /* sgtl5000 does not support 512*rate when in 96000 fs */
- switch (rate) {
- case 96000:
- mclk = 256 * rate;
- break;
- default:
- mclk = 512 * rate;
- break;
- }
-
- /* Sgtl5000 sysclk should be >= 8MHz and <= 27M */
- if (mclk < 8000000 || mclk > 27000000)
- return -EINVAL;
-
- /* Set SGTL5000's SYSCLK (provided by SAIF MCLK) */
- ret = snd_soc_dai_set_sysclk(codec_dai, SGTL5000_SYSCLK, mclk, 0);
- if (ret)
- return ret;
-
- /* The SAIF MCLK should be the same as SGTL5000_SYSCLK */
- ret = snd_soc_dai_set_sysclk(cpu_dai, MXS_SAIF_MCLK, mclk, 0);
- if (ret)
- return ret;
-
- /* set codec to slave mode */
- dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS;
-
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
- if (ret)
- return ret;
-
- /* set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, dai_format);
- if (ret)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops mxs_sgtl5000_hifi_ops = {
- .hw_params = mxs_sgtl5000_hw_params,
-};
-
-static struct snd_soc_dai_link mxs_sgtl5000_dai[] = {
- {
- .name = "HiFi Tx",
- .stream_name = "HiFi Playback",
- .codec_dai_name = "sgtl5000",
- .codec_name = "sgtl5000.0-000a",
- .cpu_dai_name = "mxs-saif.0",
- .platform_name = "mxs-pcm-audio.0",
- .ops = &mxs_sgtl5000_hifi_ops,
- }, {
- .name = "HiFi Rx",
- .stream_name = "HiFi Capture",
- .codec_dai_name = "sgtl5000",
- .codec_name = "sgtl5000.0-000a",
- .cpu_dai_name = "mxs-saif.1",
- .platform_name = "mxs-pcm-audio.1",
- .ops = &mxs_sgtl5000_hifi_ops,
- },
-};
-
-static struct snd_soc_card mxs_sgtl5000 = {
- .name = "mxs_sgtl5000",
- .owner = THIS_MODULE,
- .dai_link = mxs_sgtl5000_dai,
- .num_links = ARRAY_SIZE(mxs_sgtl5000_dai),
-};
-
-static int __devinit mxs_sgtl5000_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &mxs_sgtl5000;
- int ret;
-
- /*
- * Set an init clock(11.28Mhz) for sgtl5000 initialization(i2c r/w).
- * The Sgtl5000 sysclk is derived from saif0 mclk and it's range
- * should be >= 8MHz and <= 27M.
- */
- ret = mxs_saif_get_mclk(0, 44100 * 256, 44100);
- if (ret)
- return ret;
-
- card->dev = &pdev->dev;
- platform_set_drvdata(pdev, card);
-
- ret = snd_soc_register_card(card);
- if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
- ret);
- return ret;
- }
-
- return 0;
-}
-
-static int __devexit mxs_sgtl5000_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- mxs_saif_put_mclk(0);
-
- snd_soc_unregister_card(card);
-
- return 0;
-}
-
-static struct platform_driver mxs_sgtl5000_audio_driver = {
- .driver = {
- .name = "mxs-sgtl5000",
- .owner = THIS_MODULE,
- },
- .probe = mxs_sgtl5000_probe,
- .remove = __devexit_p(mxs_sgtl5000_remove),
-};
-
-module_platform_driver(mxs_sgtl5000_audio_driver);
-
-MODULE_AUTHOR("Freescale Semiconductor, Inc.");
-MODULE_DESCRIPTION("MXS ALSA SoC Machine driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:mxs-sgtl5000");
diff --git a/ANDROID_3.4.5/sound/soc/nuc900/Kconfig b/ANDROID_3.4.5/sound/soc/nuc900/Kconfig
deleted file mode 100644
index a0ed1c61..00000000
--- a/ANDROID_3.4.5/sound/soc/nuc900/Kconfig
+++ /dev/null
@@ -1,27 +0,0 @@
-##
-## NUC900 series AC97 API
-##
-config SND_SOC_NUC900
- tristate "SoC Audio for NUC900 series"
- depends on ARCH_W90X900
- help
- This option enables support for AC97 mode on the NUC900 SoC.
-
-config SND_SOC_NUC900_AC97
- tristate
- select AC97_BUS
- select SND_AC97_CODEC
- select SND_SOC_AC97_BUS
-
-
-##
-## Boards
-##
-config SND_SOC_NUC900EVB
- tristate "NUC900 AC97 support for demo board"
- depends on SND_SOC_NUC900
- select SND_SOC_NUC900_AC97
- select SND_SOC_AC97_CODEC
- help
- Select this option to enable audio (AC97) on the
- NUC900 demoboard.
diff --git a/ANDROID_3.4.5/sound/soc/nuc900/Makefile b/ANDROID_3.4.5/sound/soc/nuc900/Makefile
deleted file mode 100644
index 7e46c715..00000000
--- a/ANDROID_3.4.5/sound/soc/nuc900/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# NUC900 series audio
-snd-soc-nuc900-pcm-objs := nuc900-pcm.o
-snd-soc-nuc900-ac97-objs := nuc900-ac97.o
-
-obj-$(CONFIG_SND_SOC_NUC900) += snd-soc-nuc900-pcm.o
-obj-$(CONFIG_SND_SOC_NUC900_AC97) += snd-soc-nuc900-ac97.o
-
-# Boards
-snd-soc-nuc900-audio-objs := nuc900-audio.o
-
-obj-$(CONFIG_SND_SOC_NUC900EVB) += snd-soc-nuc900-audio.o
diff --git a/ANDROID_3.4.5/sound/soc/nuc900/nuc900-ac97.c b/ANDROID_3.4.5/sound/soc/nuc900/nuc900-ac97.c
deleted file mode 100644
index 946020a6..00000000
--- a/ANDROID_3.4.5/sound/soc/nuc900/nuc900-ac97.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * Copyright (c) 2009-2010 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation;version 2 of the License.
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/suspend.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-#include <linux/clk.h>
-
-#include <mach/mfp.h>
-
-#include "nuc900-audio.h"
-
-static DEFINE_MUTEX(ac97_mutex);
-struct nuc900_audio *nuc900_ac97_data;
-
-static int nuc900_checkready(void)
-{
- struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
-
- if (!(AUDIO_READ(nuc900_audio->mmio + ACTL_ACIS0) & CODEC_READY))
- return -EPERM;
-
- return 0;
-}
-
-/* AC97 controller reads codec register */
-static unsigned short nuc900_ac97_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
- unsigned long timeout = 0x10000, val;
-
- mutex_lock(&ac97_mutex);
-
- val = nuc900_checkready();
- if (val) {
- dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
- goto out;
- }
-
- /* set the R_WB bit and write register index */
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS1, R_WB | reg);
-
- /* set the valid frame bit and valid slots */
- val = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0);
- val |= (VALID_FRAME | SLOT1_VALID);
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, val);
-
- udelay(100);
-
- /* polling the AC_R_FINISH */
- while (!(AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON) & AC_R_FINISH)
- && timeout--)
- mdelay(1);
-
- if (!timeout) {
- dev_err(nuc900_audio->dev, "AC97 read register time out !\n");
- val = -EPERM;
- goto out;
- }
-
- val = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0) ;
- val &= ~SLOT1_VALID;
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, val);
-
- if (AUDIO_READ(nuc900_audio->mmio + ACTL_ACIS1) >> 2 != reg) {
- dev_err(nuc900_audio->dev,
- "R_INDEX of REG_ACTL_ACIS1 not match!\n");
- }
-
- udelay(100);
- val = (AUDIO_READ(nuc900_audio->mmio + ACTL_ACIS2) & 0xFFFF);
-
-out:
- mutex_unlock(&ac97_mutex);
- return val;
-}
-
-/* AC97 controller writes to codec register */
-static void nuc900_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short val)
-{
- struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
- unsigned long tmp, timeout = 0x10000;
-
- mutex_lock(&ac97_mutex);
-
- tmp = nuc900_checkready();
- if (tmp)
- dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
-
- /* clear the R_WB bit and write register index */
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS1, reg);
-
- /* write register value */
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS2, val);
-
- /* set the valid frame bit and valid slots */
- tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0);
- tmp |= SLOT1_VALID | SLOT2_VALID | VALID_FRAME;
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, tmp);
-
- udelay(100);
-
- /* polling the AC_W_FINISH */
- while ((AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON) & AC_W_FINISH)
- && timeout--)
- mdelay(1);
-
- if (!timeout)
- dev_err(nuc900_audio->dev, "AC97 write register time out !\n");
-
- tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0);
- tmp &= ~(SLOT1_VALID | SLOT2_VALID);
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, tmp);
-
- mutex_unlock(&ac97_mutex);
-
-}
-
-static void nuc900_ac97_warm_reset(struct snd_ac97 *ac97)
-{
- struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
- unsigned long val;
-
- mutex_lock(&ac97_mutex);
-
- /* warm reset AC 97 */
- val = AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON);
- val |= AC_W_RES;
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACCON, val);
-
- udelay(100);
-
- val = nuc900_checkready();
- if (val)
- dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
-
- mutex_unlock(&ac97_mutex);
-}
-
-static void nuc900_ac97_cold_reset(struct snd_ac97 *ac97)
-{
- struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
- unsigned long val;
-
- mutex_lock(&ac97_mutex);
-
- /* reset Audio Controller */
- val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
- val |= ACTL_RESET_BIT;
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
-
- val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
- val &= (~ACTL_RESET_BIT);
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
-
- /* reset AC-link interface */
-
- val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
- val |= AC_RESET;
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
-
- val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
- val &= ~AC_RESET;
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
-
- /* cold reset AC 97 */
- val = AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON);
- val |= AC_C_RES;
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACCON, val);
-
- val = AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON);
- val &= (~AC_C_RES);
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACCON, val);
-
- udelay(100);
-
- mutex_unlock(&ac97_mutex);
-
-}
-
-/* AC97 controller operations */
-struct snd_ac97_bus_ops soc_ac97_ops = {
- .read = nuc900_ac97_read,
- .write = nuc900_ac97_write,
- .reset = nuc900_ac97_cold_reset,
- .warm_reset = nuc900_ac97_warm_reset,
-}
-EXPORT_SYMBOL_GPL(soc_ac97_ops);
-
-static int nuc900_ac97_trigger(struct snd_pcm_substream *substream,
- int cmd, struct snd_soc_dai *dai)
-{
- struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
- int ret;
- unsigned long val, tmp;
-
- ret = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0);
- tmp |= (SLOT3_VALID | SLOT4_VALID | VALID_FRAME);
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, tmp);
-
- tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_PSR);
- tmp |= (P_DMA_END_IRQ | P_DMA_MIDDLE_IRQ);
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_PSR, tmp);
- val |= AC_PLAY;
- } else {
- tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_RSR);
- tmp |= (R_DMA_END_IRQ | R_DMA_MIDDLE_IRQ);
-
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_RSR, tmp);
- val |= AC_RECORD;
- }
-
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
-
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0);
- tmp &= ~(SLOT3_VALID | SLOT4_VALID);
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, tmp);
-
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_PSR, RESET_PRSR);
- val &= ~AC_PLAY;
- } else {
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_RSR, RESET_PRSR);
- val &= ~AC_RECORD;
- }
-
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
-
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int nuc900_ac97_probe(struct snd_soc_dai *dai)
-{
- struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
- unsigned long val;
-
- mutex_lock(&ac97_mutex);
-
- /* enable unit clock */
- clk_enable(nuc900_audio->clk);
-
- /* enable audio controller and AC-link interface */
- val = AUDIO_READ(nuc900_audio->mmio + ACTL_CON);
- val |= (IIS_AC_PIN_SEL | ACLINK_EN);
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_CON, val);
-
- mutex_unlock(&ac97_mutex);
-
- return 0;
-}
-
-static int nuc900_ac97_remove(struct snd_soc_dai *dai)
-{
- struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
-
- clk_disable(nuc900_audio->clk);
- return 0;
-}
-
-static const struct snd_soc_dai_ops nuc900_ac97_dai_ops = {
- .trigger = nuc900_ac97_trigger,
-};
-
-static struct snd_soc_dai_driver nuc900_ac97_dai = {
- .probe = nuc900_ac97_probe,
- .remove = nuc900_ac97_remove,
- .ac97_control = 1,
- .playback = {
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .channels_min = 1,
- .channels_max = 2,
- },
- .capture = {
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .channels_min = 1,
- .channels_max = 2,
- },
- .ops = &nuc900_ac97_dai_ops,
-};
-
-static int __devinit nuc900_ac97_drvprobe(struct platform_device *pdev)
-{
- struct nuc900_audio *nuc900_audio;
- int ret;
-
- if (nuc900_ac97_data)
- return -EBUSY;
-
- nuc900_audio = kzalloc(sizeof(struct nuc900_audio), GFP_KERNEL);
- if (!nuc900_audio)
- return -ENOMEM;
-
- spin_lock_init(&nuc900_audio->lock);
-
- nuc900_audio->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!nuc900_audio->res) {
- ret = -ENODEV;
- goto out0;
- }
-
- if (!request_mem_region(nuc900_audio->res->start,
- resource_size(nuc900_audio->res), pdev->name)) {
- ret = -EBUSY;
- goto out0;
- }
-
- nuc900_audio->mmio = ioremap(nuc900_audio->res->start,
- resource_size(nuc900_audio->res));
- if (!nuc900_audio->mmio) {
- ret = -ENOMEM;
- goto out1;
- }
-
- nuc900_audio->clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(nuc900_audio->clk)) {
- ret = PTR_ERR(nuc900_audio->clk);
- goto out2;
- }
-
- nuc900_audio->irq_num = platform_get_irq(pdev, 0);
- if (!nuc900_audio->irq_num) {
- ret = -EBUSY;
- goto out3;
- }
-
- nuc900_ac97_data = nuc900_audio;
-
- ret = snd_soc_register_dai(&pdev->dev, &nuc900_ac97_dai);
- if (ret)
- goto out3;
-
- /* enbale ac97 multifunction pin */
- mfp_set_groupg(nuc900_audio->dev, NULL);
-
- return 0;
-
-out3:
- clk_put(nuc900_audio->clk);
-out2:
- iounmap(nuc900_audio->mmio);
-out1:
- release_mem_region(nuc900_audio->res->start,
- resource_size(nuc900_audio->res));
-out0:
- kfree(nuc900_audio);
- return ret;
-}
-
-static int __devexit nuc900_ac97_drvremove(struct platform_device *pdev)
-{
- snd_soc_unregister_dai(&pdev->dev);
-
- clk_put(nuc900_ac97_data->clk);
- iounmap(nuc900_ac97_data->mmio);
- release_mem_region(nuc900_ac97_data->res->start,
- resource_size(nuc900_ac97_data->res));
-
- kfree(nuc900_ac97_data);
- nuc900_ac97_data = NULL;
-
- return 0;
-}
-
-static struct platform_driver nuc900_ac97_driver = {
- .driver = {
- .name = "nuc900-ac97",
- .owner = THIS_MODULE,
- },
- .probe = nuc900_ac97_drvprobe,
- .remove = __devexit_p(nuc900_ac97_drvremove),
-};
-
-module_platform_driver(nuc900_ac97_driver);
-
-MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
-MODULE_DESCRIPTION("NUC900 AC97 SoC driver!");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:nuc900-ac97");
diff --git a/ANDROID_3.4.5/sound/soc/nuc900/nuc900-audio.c b/ANDROID_3.4.5/sound/soc/nuc900/nuc900-audio.c
deleted file mode 100644
index 2f6e6fd6..00000000
--- a/ANDROID_3.4.5/sound/soc/nuc900/nuc900-audio.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2010 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation;version 2 of the License.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include "nuc900-audio.h"
-
-static struct snd_soc_dai_link nuc900evb_ac97_dai = {
- .name = "AC97",
- .stream_name = "AC97 HiFi",
- .cpu_dai_name = "nuc900-ac97",
- .codec_dai_name = "ac97-hifi",
- .codec_name = "ac97-codec",
- .platform_name = "nuc900-pcm-audio",
-};
-
-static struct snd_soc_card nuc900evb_audio_machine = {
- .name = "NUC900EVB_AC97",
- .owner = THIS_MODULE,
- .dai_link = &nuc900evb_ac97_dai,
- .num_links = 1,
-};
-
-static struct platform_device *nuc900evb_asoc_dev;
-
-static int __init nuc900evb_audio_init(void)
-{
- int ret;
-
- ret = -ENOMEM;
- nuc900evb_asoc_dev = platform_device_alloc("soc-audio", -1);
- if (!nuc900evb_asoc_dev)
- goto out;
-
- /* nuc900 board audio device */
- platform_set_drvdata(nuc900evb_asoc_dev, &nuc900evb_audio_machine);
-
- ret = platform_device_add(nuc900evb_asoc_dev);
-
- if (ret) {
- platform_device_put(nuc900evb_asoc_dev);
- nuc900evb_asoc_dev = NULL;
- }
-
-out:
- return ret;
-}
-
-static void __exit nuc900evb_audio_exit(void)
-{
- platform_device_unregister(nuc900evb_asoc_dev);
-}
-
-module_init(nuc900evb_audio_init);
-module_exit(nuc900evb_audio_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("NUC900 Series ASoC audio support");
-MODULE_AUTHOR("Wan ZongShun");
diff --git a/ANDROID_3.4.5/sound/soc/nuc900/nuc900-audio.h b/ANDROID_3.4.5/sound/soc/nuc900/nuc900-audio.h
deleted file mode 100644
index 59f7e8ed..00000000
--- a/ANDROID_3.4.5/sound/soc/nuc900/nuc900-audio.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2010 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation;version 2 of the License.
- *
- */
-
-#ifndef _NUC900_AUDIO_H
-#define _NUC900_AUDIO_H
-
-#include <linux/io.h>
-
-/* Audio Control Registers */
-#define ACTL_CON 0x00
-#define ACTL_RESET 0x04
-#define ACTL_RDSTB 0x08
-#define ACTL_RDST_LENGTH 0x0C
-#define ACTL_RDSTC 0x10
-#define ACTL_RSR 0x14
-#define ACTL_PDSTB 0x18
-#define ACTL_PDST_LENGTH 0x1C
-#define ACTL_PDSTC 0x20
-#define ACTL_PSR 0x24
-#define ACTL_IISCON 0x28
-#define ACTL_ACCON 0x2C
-#define ACTL_ACOS0 0x30
-#define ACTL_ACOS1 0x34
-#define ACTL_ACOS2 0x38
-#define ACTL_ACIS0 0x3C
-#define ACTL_ACIS1 0x40
-#define ACTL_ACIS2 0x44
-#define ACTL_COUNTER 0x48
-
-/* bit definition of REG_ACTL_CON register */
-#define R_DMA_IRQ 0x1000
-#define T_DMA_IRQ 0x0800
-#define IIS_AC_PIN_SEL 0x0100
-#define FIFO_TH 0x0080
-#define ADC_EN 0x0010
-#define M80_EN 0x0008
-#define ACLINK_EN 0x0004
-#define IIS_EN 0x0002
-
-/* bit definition of REG_ACTL_RESET register */
-#define W5691_PLAY 0x20000
-#define ACTL_RESET_BIT 0x10000
-#define RECORD_RIGHT_CHNNEL 0x08000
-#define RECORD_LEFT_CHNNEL 0x04000
-#define PLAY_RIGHT_CHNNEL 0x02000
-#define PLAY_LEFT_CHNNEL 0x01000
-#define DAC_PLAY 0x00800
-#define ADC_RECORD 0x00400
-#define M80_PLAY 0x00200
-#define AC_RECORD 0x00100
-#define AC_PLAY 0x00080
-#define IIS_RECORD 0x00040
-#define IIS_PLAY 0x00020
-#define DAC_RESET 0x00010
-#define ADC_RESET 0x00008
-#define M80_RESET 0x00004
-#define AC_RESET 0x00002
-#define IIS_RESET 0x00001
-
-/* bit definition of REG_ACTL_ACCON register */
-#define AC_BCLK_PU_EN 0x20
-#define AC_R_FINISH 0x10
-#define AC_W_FINISH 0x08
-#define AC_W_RES 0x04
-#define AC_C_RES 0x02
-
-/* bit definition of ACTL_RSR register */
-#define R_FIFO_EMPTY 0x04
-#define R_DMA_END_IRQ 0x02
-#define R_DMA_MIDDLE_IRQ 0x01
-
-/* bit definition of ACTL_PSR register */
-#define P_FIFO_EMPTY 0x04
-#define P_DMA_END_IRQ 0x02
-#define P_DMA_MIDDLE_IRQ 0x01
-
-/* bit definition of ACTL_ACOS0 register */
-#define SLOT1_VALID 0x01
-#define SLOT2_VALID 0x02
-#define SLOT3_VALID 0x04
-#define SLOT4_VALID 0x08
-#define VALID_FRAME 0x10
-
-/* bit definition of ACTL_ACOS1 register */
-#define R_WB 0x80
-
-#define CODEC_READY 0x10
-#define RESET_PRSR 0x00
-#define AUDIO_WRITE(addr, val) __raw_writel(val, addr)
-#define AUDIO_READ(addr) __raw_readl(addr)
-
-struct nuc900_audio {
- void __iomem *mmio;
- spinlock_t lock;
- dma_addr_t dma_addr[2];
- unsigned long buffersize[2];
- unsigned long irq_num;
- struct snd_pcm_substream *substream;
- struct resource *res;
- struct clk *clk;
- struct device *dev;
-
-};
-
-extern struct nuc900_audio *nuc900_ac97_data;
-
-#endif /*end _NUC900_AUDIO_H */
diff --git a/ANDROID_3.4.5/sound/soc/nuc900/nuc900-pcm.c b/ANDROID_3.4.5/sound/soc/nuc900/nuc900-pcm.c
deleted file mode 100644
index 37585b47..00000000
--- a/ANDROID_3.4.5/sound/soc/nuc900/nuc900-pcm.c
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Copyright (c) 2010 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation;version 2 of the License.
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/dma-mapping.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <mach/hardware.h>
-
-#include "nuc900-audio.h"
-
-static const struct snd_pcm_hardware nuc900_pcm_hardware = {
- .info = SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 4*1024,
- .period_bytes_min = 1*1024,
- .period_bytes_max = 4*1024,
- .periods_min = 1,
- .periods_max = 1024,
-};
-
-static int nuc900_dma_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct nuc900_audio *nuc900_audio = runtime->private_data;
- unsigned long flags;
- int ret = 0;
-
- ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
- if (ret < 0)
- return ret;
-
- spin_lock_irqsave(&nuc900_audio->lock, flags);
-
- nuc900_audio->substream = substream;
- nuc900_audio->dma_addr[substream->stream] = runtime->dma_addr;
- nuc900_audio->buffersize[substream->stream] =
- params_buffer_bytes(params);
-
- spin_unlock_irqrestore(&nuc900_audio->lock, flags);
-
- return ret;
-}
-
-static void nuc900_update_dma_register(struct snd_pcm_substream *substream,
- dma_addr_t dma_addr, size_t count)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct nuc900_audio *nuc900_audio = runtime->private_data;
- void __iomem *mmio_addr, *mmio_len;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- mmio_addr = nuc900_audio->mmio + ACTL_PDSTB;
- mmio_len = nuc900_audio->mmio + ACTL_PDST_LENGTH;
- } else {
- mmio_addr = nuc900_audio->mmio + ACTL_RDSTB;
- mmio_len = nuc900_audio->mmio + ACTL_RDST_LENGTH;
- }
-
- AUDIO_WRITE(mmio_addr, dma_addr);
- AUDIO_WRITE(mmio_len, count);
-}
-
-static void nuc900_dma_start(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct nuc900_audio *nuc900_audio = runtime->private_data;
- unsigned long val;
-
- val = AUDIO_READ(nuc900_audio->mmio + ACTL_CON);
- val |= (T_DMA_IRQ | R_DMA_IRQ);
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_CON, val);
-}
-
-static void nuc900_dma_stop(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct nuc900_audio *nuc900_audio = runtime->private_data;
- unsigned long val;
-
- val = AUDIO_READ(nuc900_audio->mmio + ACTL_CON);
- val &= ~(T_DMA_IRQ | R_DMA_IRQ);
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_CON, val);
-}
-
-static irqreturn_t nuc900_dma_interrupt(int irq, void *dev_id)
-{
- struct snd_pcm_substream *substream = dev_id;
- struct nuc900_audio *nuc900_audio = substream->runtime->private_data;
- unsigned long val;
-
- spin_lock(&nuc900_audio->lock);
-
- val = AUDIO_READ(nuc900_audio->mmio + ACTL_CON);
-
- if (val & R_DMA_IRQ) {
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_CON, val | R_DMA_IRQ);
-
- val = AUDIO_READ(nuc900_audio->mmio + ACTL_RSR);
-
- if (val & R_DMA_MIDDLE_IRQ) {
- val |= R_DMA_MIDDLE_IRQ;
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_RSR, val);
- }
-
- if (val & R_DMA_END_IRQ) {
- val |= R_DMA_END_IRQ;
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_RSR, val);
- }
- } else if (val & T_DMA_IRQ) {
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_CON, val | T_DMA_IRQ);
-
- val = AUDIO_READ(nuc900_audio->mmio + ACTL_PSR);
-
- if (val & P_DMA_MIDDLE_IRQ) {
- val |= P_DMA_MIDDLE_IRQ;
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_PSR, val);
- }
-
- if (val & P_DMA_END_IRQ) {
- val |= P_DMA_END_IRQ;
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_PSR, val);
- }
- } else {
- dev_err(nuc900_audio->dev, "Wrong DMA interrupt status!\n");
- spin_unlock(&nuc900_audio->lock);
- return IRQ_HANDLED;
- }
-
- spin_unlock(&nuc900_audio->lock);
-
- snd_pcm_period_elapsed(substream);
-
- return IRQ_HANDLED;
-}
-
-static int nuc900_dma_hw_free(struct snd_pcm_substream *substream)
-{
- snd_pcm_lib_free_pages(substream);
- return 0;
-}
-
-static int nuc900_dma_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct nuc900_audio *nuc900_audio = runtime->private_data;
- unsigned long flags, val;
- int ret = 0;
-
- spin_lock_irqsave(&nuc900_audio->lock, flags);
-
- nuc900_update_dma_register(substream,
- nuc900_audio->dma_addr[substream->stream],
- nuc900_audio->buffersize[substream->stream]);
-
- val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
-
- switch (runtime->channels) {
- case 1:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- val &= ~(PLAY_LEFT_CHNNEL | PLAY_RIGHT_CHNNEL);
- val |= PLAY_RIGHT_CHNNEL;
- } else {
- val &= ~(RECORD_LEFT_CHNNEL | RECORD_RIGHT_CHNNEL);
- val |= RECORD_RIGHT_CHNNEL;
- }
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
- break;
- case 2:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- val |= (PLAY_LEFT_CHNNEL | PLAY_RIGHT_CHNNEL);
- else
- val |= (RECORD_LEFT_CHNNEL | RECORD_RIGHT_CHNNEL);
- AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
- break;
- default:
- ret = -EINVAL;
- }
- spin_unlock_irqrestore(&nuc900_audio->lock, flags);
- return ret;
-}
-
-static int nuc900_dma_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- int ret = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- nuc900_dma_start(substream);
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- nuc900_dma_stop(substream);
- break;
-
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-static int nuc900_dma_getposition(struct snd_pcm_substream *substream,
- dma_addr_t *src, dma_addr_t *dst)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct nuc900_audio *nuc900_audio = runtime->private_data;
-
- if (src != NULL)
- *src = AUDIO_READ(nuc900_audio->mmio + ACTL_PDSTC);
-
- if (dst != NULL)
- *dst = AUDIO_READ(nuc900_audio->mmio + ACTL_RDSTC);
-
- return 0;
-}
-
-static snd_pcm_uframes_t nuc900_dma_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- dma_addr_t src, dst;
- unsigned long res;
-
- nuc900_dma_getposition(substream, &src, &dst);
-
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- res = dst - runtime->dma_addr;
- else
- res = src - runtime->dma_addr;
-
- return bytes_to_frames(substream->runtime, res);
-}
-
-static int nuc900_dma_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct nuc900_audio *nuc900_audio;
-
- snd_soc_set_runtime_hwparams(substream, &nuc900_pcm_hardware);
-
- nuc900_audio = nuc900_ac97_data;
-
- if (request_irq(nuc900_audio->irq_num, nuc900_dma_interrupt,
- 0, "nuc900-dma", substream))
- return -EBUSY;
-
- runtime->private_data = nuc900_audio;
-
- return 0;
-}
-
-static int nuc900_dma_close(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct nuc900_audio *nuc900_audio = runtime->private_data;
-
- free_irq(nuc900_audio->irq_num, substream);
-
- return 0;
-}
-
-static int nuc900_dma_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- return dma_mmap_writecombine(substream->pcm->card->dev, vma,
- runtime->dma_area,
- runtime->dma_addr,
- runtime->dma_bytes);
-}
-
-static struct snd_pcm_ops nuc900_dma_ops = {
- .open = nuc900_dma_open,
- .close = nuc900_dma_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = nuc900_dma_hw_params,
- .hw_free = nuc900_dma_hw_free,
- .prepare = nuc900_dma_prepare,
- .trigger = nuc900_dma_trigger,
- .pointer = nuc900_dma_pointer,
- .mmap = nuc900_dma_mmap,
-};
-
-static void nuc900_dma_free_dma_buffers(struct snd_pcm *pcm)
-{
- snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static u64 nuc900_pcm_dmamask = DMA_BIT_MASK(32);
-static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &nuc900_pcm_dmamask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- card->dev, 4 * 1024, (4 * 1024) - 1);
-
- return 0;
-}
-
-static struct snd_soc_platform_driver nuc900_soc_platform = {
- .ops = &nuc900_dma_ops,
- .pcm_new = nuc900_dma_new,
- .pcm_free = nuc900_dma_free_dma_buffers,
-};
-
-static int __devinit nuc900_soc_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_platform(&pdev->dev, &nuc900_soc_platform);
-}
-
-static int __devexit nuc900_soc_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver nuc900_pcm_driver = {
- .driver = {
- .name = "nuc900-pcm-audio",
- .owner = THIS_MODULE,
- },
-
- .probe = nuc900_soc_platform_probe,
- .remove = __devexit_p(nuc900_soc_platform_remove),
-};
-
-module_platform_driver(nuc900_pcm_driver);
-
-MODULE_AUTHOR("Wan ZongShun, <mcuos.com@gmail.com>");
-MODULE_DESCRIPTION("nuc900 Audio DMA module");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/omap/Kconfig b/ANDROID_3.4.5/sound/soc/omap/Kconfig
deleted file mode 100644
index deafbfaa..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/Kconfig
+++ /dev/null
@@ -1,152 +0,0 @@
-config SND_OMAP_SOC
- tristate "SoC Audio for the Texas Instruments OMAP chips"
- depends on ARCH_OMAP
-
-config SND_OMAP_SOC_DMIC
- tristate
-
-config SND_OMAP_SOC_MCBSP
- tristate
-
-config SND_OMAP_SOC_MCPDM
- tristate
-
-config SND_OMAP_SOC_HDMI
- tristate
-
-config SND_OMAP_SOC_N810
- tristate "SoC Audio support for Nokia N810"
- depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C
- depends on OMAP_MUX
- select SND_OMAP_SOC_MCBSP
- select SND_SOC_TLV320AIC3X
- help
- Say Y if you want to add support for SoC audio on Nokia N810.
-
-config SND_OMAP_SOC_RX51
- tristate "SoC Audio support for Nokia RX-51"
- depends on SND_OMAP_SOC && MACH_NOKIA_RX51
- select SND_OMAP_SOC_MCBSP
- select SND_SOC_TLV320AIC3X
- select SND_SOC_TPA6130A2
- help
- Say Y if you want to add support for SoC audio on Nokia RX-51
- hardware. This is also known as Nokia N900 product.
-
-config SND_OMAP_SOC_AMS_DELTA
- tristate "SoC Audio support for Amstrad E3 (Delta) videophone"
- depends on SND_OMAP_SOC && MACH_AMS_DELTA
- select SND_OMAP_SOC_MCBSP
- select SND_SOC_CX20442
- help
- Say Y if you want to add support for SoC audio device connected to
- a handset and a speakerphone found on Amstrad E3 (Delta) videophone.
-
- Note that in order to get those devices fully supported, you have to
- build the kernel with standard serial port driver included and
- configured for at least 4 ports. Then, from userspace, you must load
- a line discipline #19 on the modem (ttyS3) serial line. The simplest
- way to achieve this is to install util-linux-ng and use the included
- ldattach utility. This can be started automatically from udev,
- a simple rule like this one should do the trick (it does for me):
- ACTION=="add", KERNEL=="controlC0", \
- RUN+="/usr/sbin/ldattach 19 /dev/ttyS3"
-
-config SND_OMAP_SOC_OSK5912
- tristate "SoC Audio support for omap osk5912"
- depends on SND_OMAP_SOC && MACH_OMAP_OSK && I2C
- select SND_OMAP_SOC_MCBSP
- select SND_SOC_TLV320AIC23
- help
- Say Y if you want to add support for SoC audio on osk5912.
-
-config SND_OMAP_SOC_OVERO
- tristate "SoC Audio support for Gumstix Overo and CompuLab CM-T35"
- depends on TWL4030_CORE && SND_OMAP_SOC && (MACH_OVERO || MACH_CM_T35)
- select SND_OMAP_SOC_MCBSP
- select SND_SOC_TWL4030
- help
- Say Y if you want to add support for SoC audio on the
- Gumstix Overo or CompuLab CM-T35
-
-config SND_OMAP_SOC_OMAP3EVM
- tristate "SoC Audio support for OMAP3EVM board"
- depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3EVM
- select SND_OMAP_SOC_MCBSP
- select SND_SOC_TWL4030
- help
- Say Y if you want to add support for SoC audio on the omap3evm board.
-
-config SND_OMAP_SOC_AM3517EVM
- tristate "SoC Audio support for OMAP3517 / AM3517 EVM"
- depends on SND_OMAP_SOC && MACH_OMAP3517EVM && I2C
- select SND_OMAP_SOC_MCBSP
- select SND_SOC_TLV320AIC23
- help
- Say Y if you want to add support for SoC audio on the OMAP3517 / AM3517
- EVM.
-
-config SND_OMAP_SOC_SDP3430
- tristate "SoC Audio support for Texas Instruments SDP3430"
- depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_3430SDP
- select SND_OMAP_SOC_MCBSP
- select SND_SOC_TWL4030
- help
- Say Y if you want to add support for SoC audio on Texas Instruments
- SDP3430.
-
-config SND_OMAP_SOC_OMAP_ABE_TWL6040
- tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec"
- depends on TWL6040_CORE && SND_OMAP_SOC && ARCH_OMAP4
- select SND_OMAP_SOC_DMIC
- select SND_OMAP_SOC_MCPDM
- select SND_SOC_TWL6040
- select SND_SOC_DMIC
- help
- Say Y if you want to add support for SoC audio on OMAP boards using
- ABE and twl6040 codec. This driver currently supports:
- - SDP4430/Blaze boards
- - PandaBoard (4430)
- - PandaBoardES (4460)
-
-config SND_OMAP_SOC_OMAP4_HDMI
- tristate "SoC Audio support for Texas Instruments OMAP4 HDMI"
- depends on SND_OMAP_SOC && OMAP4_DSS_HDMI && OMAP2_DSS && ARCH_OMAP4
- select SND_OMAP_SOC_HDMI
- help
- Say Y if you want to add support for SoC HDMI audio on Texas Instruments
- OMAP4 chips
-
-config SND_OMAP_SOC_OMAP3_PANDORA
- tristate "SoC Audio support for OMAP3 Pandora"
- depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_PANDORA
- select SND_OMAP_SOC_MCBSP
- select SND_SOC_TWL4030
- help
- Say Y if you want to add support for SoC audio on the OMAP3 Pandora.
-
-config SND_OMAP_SOC_OMAP3_BEAGLE
- tristate "SoC Audio support for OMAP3 Beagle and Devkit8000"
- depends on TWL4030_CORE && SND_OMAP_SOC
- depends on (MACH_OMAP3_BEAGLE || MACH_DEVKIT8000)
- select SND_OMAP_SOC_MCBSP
- select SND_SOC_TWL4030
- help
- Say Y if you want to add support for SoC audio on the Beagleboard or
- the clone Devkit8000.
-
-config SND_OMAP_SOC_ZOOM2
- tristate "SoC Audio support for Zoom2"
- depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_ZOOM2
- select SND_OMAP_SOC_MCBSP
- select SND_SOC_TWL4030
- help
- Say Y if you want to add support for Soc audio on Zoom2 board.
-
-config SND_OMAP_SOC_IGEP0020
- tristate "SoC Audio support for IGEP v2"
- depends on TWL4030_CORE && SND_OMAP_SOC && MACH_IGEP0020
- select SND_OMAP_SOC_MCBSP
- select SND_SOC_TWL4030
- help
- Say Y if you want to add support for Soc audio on IGEP v2 board.
diff --git a/ANDROID_3.4.5/sound/soc/omap/Makefile b/ANDROID_3.4.5/sound/soc/omap/Makefile
deleted file mode 100644
index 1d656bce..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/Makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-# OMAP Platform Support
-snd-soc-omap-objs := omap-pcm.o
-snd-soc-omap-dmic-objs := omap-dmic.o
-snd-soc-omap-mcbsp-objs := omap-mcbsp.o mcbsp.o
-snd-soc-omap-mcpdm-objs := omap-mcpdm.o
-snd-soc-omap-hdmi-objs := omap-hdmi.o
-
-obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o
-obj-$(CONFIG_SND_OMAP_SOC_DMIC) += snd-soc-omap-dmic.o
-obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o
-obj-$(CONFIG_SND_OMAP_SOC_MCPDM) += snd-soc-omap-mcpdm.o
-obj-$(CONFIG_SND_OMAP_SOC_HDMI) += snd-soc-omap-hdmi.o
-
-# OMAP Machine Support
-snd-soc-n810-objs := n810.o
-snd-soc-rx51-objs := rx51.o
-snd-soc-ams-delta-objs := ams-delta.o
-snd-soc-osk5912-objs := osk5912.o
-snd-soc-overo-objs := overo.o
-snd-soc-omap3evm-objs := omap3evm.o
-snd-soc-am3517evm-objs := am3517evm.o
-snd-soc-sdp3430-objs := sdp3430.o
-snd-soc-omap-abe-twl6040-objs := omap-abe-twl6040.o
-snd-soc-omap3pandora-objs := omap3pandora.o
-snd-soc-omap3beagle-objs := omap3beagle.o
-snd-soc-zoom2-objs := zoom2.o
-snd-soc-igep0020-objs := igep0020.o
-snd-soc-omap4-hdmi-objs := omap4-hdmi-card.o
-
-obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
-obj-$(CONFIG_SND_OMAP_SOC_RX51) += snd-soc-rx51.o
-obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o
-obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
-obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
-obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o
-obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o
-obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o
-obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
-obj-$(CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o
-obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
-obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o
-obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o
-obj-$(CONFIG_SND_OMAP_SOC_IGEP0020) += snd-soc-igep0020.o
-obj-$(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) += snd-soc-omap4-hdmi.o
diff --git a/ANDROID_3.4.5/sound/soc/omap/am3517evm.c b/ANDROID_3.4.5/sound/soc/omap/am3517evm.c
deleted file mode 100644
index 009533ab..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/am3517evm.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * am3517evm.c -- ALSA SoC support for OMAP3517 / AM3517 EVM
- *
- * Author: Anuj Aggarwal <anuj.aggarwal@ti.com>
- *
- * Based on sound/soc/omap/beagle.c by Steve Sakoman
- *
- * Copyright (C) 2009 Texas Instruments Incorporated
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
- * whether express or implied; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- */
-
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-#include <plat/mcbsp.h>
-
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-
-#include "../codecs/tlv320aic23.h"
-
-#define CODEC_CLOCK 12000000
-
-static int am3517evm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret;
-
- /* Set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, 0,
- CODEC_CLOCK, SND_SOC_CLOCK_IN);
- if (ret < 0) {
- printk(KERN_ERR "can't set codec system clock\n");
- return ret;
- }
-
- ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_CLKR_SRC_CLKX, 0,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_CLKR_SRC_CLKX\n");
- return ret;
- }
-
- snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_FSR_SRC_FSX, 0,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_FSR_SRC_FSX\n");
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_soc_ops am3517evm_ops = {
- .hw_params = am3517evm_hw_params,
-};
-
-/* am3517evm machine dapm widgets */
-static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Line Out", NULL),
- SND_SOC_DAPM_LINE("Line In", NULL),
- SND_SOC_DAPM_MIC("Mic In", NULL),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- /* Line Out connected to LLOUT, RLOUT */
- {"Line Out", NULL, "LOUT"},
- {"Line Out", NULL, "ROUT"},
-
- {"LLINEIN", NULL, "Line In"},
- {"RLINEIN", NULL, "Line In"},
-
- {"MICIN", NULL, "Mic In"},
-};
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link am3517evm_dai = {
- .name = "TLV320AIC23",
- .stream_name = "AIC23",
- .cpu_dai_name = "omap-mcbsp.1",
- .codec_dai_name = "tlv320aic23-hifi",
- .platform_name = "omap-pcm-audio",
- .codec_name = "tlv320aic23-codec.2-001a",
- .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM,
- .ops = &am3517evm_ops,
-};
-
-/* Audio machine driver */
-static struct snd_soc_card snd_soc_am3517evm = {
- .name = "am3517evm",
- .owner = THIS_MODULE,
- .dai_link = &am3517evm_dai,
- .num_links = 1,
-
- .dapm_widgets = tlv320aic23_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
- .dapm_routes = audio_map,
- .num_dapm_routes = ARRAY_SIZE(audio_map),
-};
-
-static struct platform_device *am3517evm_snd_device;
-
-static int __init am3517evm_soc_init(void)
-{
- int ret;
-
- if (!machine_is_omap3517evm())
- return -ENODEV;
- pr_info("OMAP3517 / AM3517 EVM SoC init\n");
-
- am3517evm_snd_device = platform_device_alloc("soc-audio", -1);
- if (!am3517evm_snd_device) {
- printk(KERN_ERR "Platform device allocation failed\n");
- return -ENOMEM;
- }
-
- platform_set_drvdata(am3517evm_snd_device, &snd_soc_am3517evm);
-
- ret = platform_device_add(am3517evm_snd_device);
- if (ret)
- goto err1;
-
- return 0;
-
-err1:
- printk(KERN_ERR "Unable to add platform device\n");
- platform_device_put(am3517evm_snd_device);
-
- return ret;
-}
-
-static void __exit am3517evm_soc_exit(void)
-{
- platform_device_unregister(am3517evm_snd_device);
-}
-
-module_init(am3517evm_soc_init);
-module_exit(am3517evm_soc_exit);
-
-MODULE_AUTHOR("Anuj Aggarwal <anuj.aggarwal@ti.com>");
-MODULE_DESCRIPTION("ALSA SoC OMAP3517 / AM3517 EVM");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/sound/soc/omap/ams-delta.c b/ANDROID_3.4.5/sound/soc/omap/ams-delta.c
deleted file mode 100644
index 7d4fa8ed..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/ams-delta.c
+++ /dev/null
@@ -1,630 +0,0 @@
-/*
- * ams-delta.c -- SoC audio for Amstrad E3 (Delta) videophone
- *
- * Copyright (C) 2009 Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
- *
- * Initially based on sound/soc/omap/osk5912.x
- * Copyright (C) 2008 Mistral Solutions
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/gpio.h>
-#include <linux/spinlock.h>
-#include <linux/tty.h>
-#include <linux/module.h>
-
-#include <sound/soc.h>
-#include <sound/jack.h>
-
-#include <asm/mach-types.h>
-
-#include <plat/board-ams-delta.h>
-#include <plat/mcbsp.h>
-
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-#include "../codecs/cx20442.h"
-
-
-/* Board specific DAPM widgets */
-static const struct snd_soc_dapm_widget ams_delta_dapm_widgets[] = {
- /* Handset */
- SND_SOC_DAPM_MIC("Mouthpiece", NULL),
- SND_SOC_DAPM_HP("Earpiece", NULL),
- /* Handsfree/Speakerphone */
- SND_SOC_DAPM_MIC("Microphone", NULL),
- SND_SOC_DAPM_SPK("Speaker", NULL),
-};
-
-/* How they are connected to codec pins */
-static const struct snd_soc_dapm_route ams_delta_audio_map[] = {
- {"TELIN", NULL, "Mouthpiece"},
- {"Earpiece", NULL, "TELOUT"},
-
- {"MIC", NULL, "Microphone"},
- {"Speaker", NULL, "SPKOUT"},
-};
-
-/*
- * Controls, functional after the modem line discipline is activated.
- */
-
-/* Virtual switch: audio input/output constellations */
-static const char *ams_delta_audio_mode[] =
- {"Mixed", "Handset", "Handsfree", "Speakerphone"};
-
-/* Selection <-> pin translation */
-#define AMS_DELTA_MOUTHPIECE 0
-#define AMS_DELTA_EARPIECE 1
-#define AMS_DELTA_MICROPHONE 2
-#define AMS_DELTA_SPEAKER 3
-#define AMS_DELTA_AGC 4
-
-#define AMS_DELTA_MIXED ((1 << AMS_DELTA_EARPIECE) | \
- (1 << AMS_DELTA_MICROPHONE))
-#define AMS_DELTA_HANDSET ((1 << AMS_DELTA_MOUTHPIECE) | \
- (1 << AMS_DELTA_EARPIECE))
-#define AMS_DELTA_HANDSFREE ((1 << AMS_DELTA_MICROPHONE) | \
- (1 << AMS_DELTA_SPEAKER))
-#define AMS_DELTA_SPEAKERPHONE (AMS_DELTA_HANDSFREE | (1 << AMS_DELTA_AGC))
-
-static const unsigned short ams_delta_audio_mode_pins[] = {
- AMS_DELTA_MIXED,
- AMS_DELTA_HANDSET,
- AMS_DELTA_HANDSFREE,
- AMS_DELTA_SPEAKERPHONE,
-};
-
-static unsigned short ams_delta_audio_agc;
-
-static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- struct soc_enum *control = (struct soc_enum *)kcontrol->private_value;
- unsigned short pins;
- int pin, changed = 0;
-
- /* Refuse any mode changes if we are not able to control the codec. */
- if (!codec->hw_write)
- return -EUNATCH;
-
- if (ucontrol->value.enumerated.item[0] >= control->max)
- return -EINVAL;
-
- mutex_lock(&codec->mutex);
-
- /* Translate selection to bitmap */
- pins = ams_delta_audio_mode_pins[ucontrol->value.enumerated.item[0]];
-
- /* Setup pins after corresponding bits if changed */
- pin = !!(pins & (1 << AMS_DELTA_MOUTHPIECE));
- if (pin != snd_soc_dapm_get_pin_status(dapm, "Mouthpiece")) {
- changed = 1;
- if (pin)
- snd_soc_dapm_enable_pin(dapm, "Mouthpiece");
- else
- snd_soc_dapm_disable_pin(dapm, "Mouthpiece");
- }
- pin = !!(pins & (1 << AMS_DELTA_EARPIECE));
- if (pin != snd_soc_dapm_get_pin_status(dapm, "Earpiece")) {
- changed = 1;
- if (pin)
- snd_soc_dapm_enable_pin(dapm, "Earpiece");
- else
- snd_soc_dapm_disable_pin(dapm, "Earpiece");
- }
- pin = !!(pins & (1 << AMS_DELTA_MICROPHONE));
- if (pin != snd_soc_dapm_get_pin_status(dapm, "Microphone")) {
- changed = 1;
- if (pin)
- snd_soc_dapm_enable_pin(dapm, "Microphone");
- else
- snd_soc_dapm_disable_pin(dapm, "Microphone");
- }
- pin = !!(pins & (1 << AMS_DELTA_SPEAKER));
- if (pin != snd_soc_dapm_get_pin_status(dapm, "Speaker")) {
- changed = 1;
- if (pin)
- snd_soc_dapm_enable_pin(dapm, "Speaker");
- else
- snd_soc_dapm_disable_pin(dapm, "Speaker");
- }
- pin = !!(pins & (1 << AMS_DELTA_AGC));
- if (pin != ams_delta_audio_agc) {
- ams_delta_audio_agc = pin;
- changed = 1;
- if (pin)
- snd_soc_dapm_enable_pin(dapm, "AGCIN");
- else
- snd_soc_dapm_disable_pin(dapm, "AGCIN");
- }
- if (changed)
- snd_soc_dapm_sync(dapm);
-
- mutex_unlock(&codec->mutex);
-
- return changed;
-}
-
-static int ams_delta_get_audio_mode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- unsigned short pins, mode;
-
- pins = ((snd_soc_dapm_get_pin_status(dapm, "Mouthpiece") <<
- AMS_DELTA_MOUTHPIECE) |
- (snd_soc_dapm_get_pin_status(dapm, "Earpiece") <<
- AMS_DELTA_EARPIECE));
- if (pins)
- pins |= (snd_soc_dapm_get_pin_status(dapm, "Microphone") <<
- AMS_DELTA_MICROPHONE);
- else
- pins = ((snd_soc_dapm_get_pin_status(dapm, "Microphone") <<
- AMS_DELTA_MICROPHONE) |
- (snd_soc_dapm_get_pin_status(dapm, "Speaker") <<
- AMS_DELTA_SPEAKER) |
- (ams_delta_audio_agc << AMS_DELTA_AGC));
-
- for (mode = 0; mode < ARRAY_SIZE(ams_delta_audio_mode); mode++)
- if (pins == ams_delta_audio_mode_pins[mode])
- break;
-
- if (mode >= ARRAY_SIZE(ams_delta_audio_mode))
- return -EINVAL;
-
- ucontrol->value.enumerated.item[0] = mode;
-
- return 0;
-}
-
-static const struct soc_enum ams_delta_audio_enum[] = {
- SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ams_delta_audio_mode),
- ams_delta_audio_mode),
-};
-
-static const struct snd_kcontrol_new ams_delta_audio_controls[] = {
- SOC_ENUM_EXT("Audio Mode", ams_delta_audio_enum[0],
- ams_delta_get_audio_mode, ams_delta_set_audio_mode),
-};
-
-/* Hook switch */
-static struct snd_soc_jack ams_delta_hook_switch;
-static struct snd_soc_jack_gpio ams_delta_hook_switch_gpios[] = {
- {
- .gpio = 4,
- .name = "hook_switch",
- .report = SND_JACK_HEADSET,
- .invert = 1,
- .debounce_time = 150,
- }
-};
-
-/* After we are able to control the codec over the modem,
- * the hook switch can be used for dynamic DAPM reconfiguration. */
-static struct snd_soc_jack_pin ams_delta_hook_switch_pins[] = {
- /* Handset */
- {
- .pin = "Mouthpiece",
- .mask = SND_JACK_MICROPHONE,
- },
- {
- .pin = "Earpiece",
- .mask = SND_JACK_HEADPHONE,
- },
- /* Handsfree */
- {
- .pin = "Microphone",
- .mask = SND_JACK_MICROPHONE,
- .invert = 1,
- },
- {
- .pin = "Speaker",
- .mask = SND_JACK_HEADPHONE,
- .invert = 1,
- },
-};
-
-
-/*
- * Modem line discipline, required for making above controls functional.
- * Activated from userspace with ldattach, possibly invoked from udev rule.
- */
-
-/* To actually apply any modem controlled configuration changes to the codec,
- * we must connect codec DAI pins to the modem for a moment. Be careful not
- * to interfere with our digital mute function that shares the same hardware. */
-static struct timer_list cx81801_timer;
-static bool cx81801_cmd_pending;
-static bool ams_delta_muted;
-static DEFINE_SPINLOCK(ams_delta_lock);
-
-static void cx81801_timeout(unsigned long data)
-{
- int muted;
-
- spin_lock(&ams_delta_lock);
- cx81801_cmd_pending = 0;
- muted = ams_delta_muted;
- spin_unlock(&ams_delta_lock);
-
- /* Reconnect the codec DAI back from the modem to the CPU DAI
- * only if digital mute still off */
- if (!muted)
- ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, 0);
-}
-
-/*
- * Used for passing a codec structure pointer
- * from the board initialization code to the tty line discipline.
- */
-static struct snd_soc_codec *cx20442_codec;
-
-/* Line discipline .open() */
-static int cx81801_open(struct tty_struct *tty)
-{
- int ret;
-
- if (!cx20442_codec)
- return -ENODEV;
-
- /*
- * Pass the codec structure pointer for use by other ldisc callbacks,
- * both the card and the codec specific parts.
- */
- tty->disc_data = cx20442_codec;
-
- ret = v253_ops.open(tty);
-
- if (ret < 0)
- tty->disc_data = NULL;
-
- return ret;
-}
-
-/* Line discipline .close() */
-static void cx81801_close(struct tty_struct *tty)
-{
- struct snd_soc_codec *codec = tty->disc_data;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- del_timer_sync(&cx81801_timer);
-
- /* Prevent the hook switch from further changing the DAPM pins */
- INIT_LIST_HEAD(&ams_delta_hook_switch.pins);
-
- if (!codec)
- return;
-
- v253_ops.close(tty);
-
- /* Revert back to default audio input/output constellation */
- snd_soc_dapm_disable_pin(dapm, "Mouthpiece");
- snd_soc_dapm_enable_pin(dapm, "Earpiece");
- snd_soc_dapm_enable_pin(dapm, "Microphone");
- snd_soc_dapm_disable_pin(dapm, "Speaker");
- snd_soc_dapm_disable_pin(dapm, "AGCIN");
- snd_soc_dapm_sync(dapm);
-}
-
-/* Line discipline .hangup() */
-static int cx81801_hangup(struct tty_struct *tty)
-{
- cx81801_close(tty);
- return 0;
-}
-
-/* Line discipline .receive_buf() */
-static void cx81801_receive(struct tty_struct *tty,
- const unsigned char *cp, char *fp, int count)
-{
- struct snd_soc_codec *codec = tty->disc_data;
- const unsigned char *c;
- int apply, ret;
-
- if (!codec)
- return;
-
- if (!codec->hw_write) {
- /* First modem response, complete setup procedure */
-
- /* Initialize timer used for config pulse generation */
- setup_timer(&cx81801_timer, cx81801_timeout, 0);
-
- v253_ops.receive_buf(tty, cp, fp, count);
-
- /* Link hook switch to DAPM pins */
- ret = snd_soc_jack_add_pins(&ams_delta_hook_switch,
- ARRAY_SIZE(ams_delta_hook_switch_pins),
- ams_delta_hook_switch_pins);
- if (ret)
- dev_warn(codec->dev,
- "Failed to link hook switch to DAPM pins, "
- "will continue with hook switch unlinked.\n");
-
- return;
- }
-
- v253_ops.receive_buf(tty, cp, fp, count);
-
- for (c = &cp[count - 1]; c >= cp; c--) {
- if (*c != '\r')
- continue;
- /* Complete modem response received, apply config to codec */
-
- spin_lock_bh(&ams_delta_lock);
- mod_timer(&cx81801_timer, jiffies + msecs_to_jiffies(150));
- apply = !ams_delta_muted && !cx81801_cmd_pending;
- cx81801_cmd_pending = 1;
- spin_unlock_bh(&ams_delta_lock);
-
- /* Apply config pulse by connecting the codec to the modem
- * if not already done */
- if (apply)
- ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC,
- AMS_DELTA_LATCH2_MODEM_CODEC);
- break;
- }
-}
-
-/* Line discipline .write_wakeup() */
-static void cx81801_wakeup(struct tty_struct *tty)
-{
- v253_ops.write_wakeup(tty);
-}
-
-static struct tty_ldisc_ops cx81801_ops = {
- .magic = TTY_LDISC_MAGIC,
- .name = "cx81801",
- .owner = THIS_MODULE,
- .open = cx81801_open,
- .close = cx81801_close,
- .hangup = cx81801_hangup,
- .receive_buf = cx81801_receive,
- .write_wakeup = cx81801_wakeup,
-};
-
-
-/*
- * Even if not very useful, the sound card can still work without any of the
- * above functonality activated. You can still control its audio input/output
- * constellation and speakerphone gain from userspace by issuing AT commands
- * over the modem port.
- */
-
-static int ams_delta_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
-
- /* Set cpu DAI configuration */
- return snd_soc_dai_set_fmt(rtd->cpu_dai,
- SND_SOC_DAIFMT_DSP_A |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM);
-}
-
-static struct snd_soc_ops ams_delta_ops = {
- .hw_params = ams_delta_hw_params,
-};
-
-
-/* Digital mute implemented using modem/CPU multiplexer.
- * Shares hardware with codec config pulse generation */
-static bool ams_delta_muted = 1;
-
-static int ams_delta_digital_mute(struct snd_soc_dai *dai, int mute)
-{
- int apply;
-
- if (ams_delta_muted == mute)
- return 0;
-
- spin_lock_bh(&ams_delta_lock);
- ams_delta_muted = mute;
- apply = !cx81801_cmd_pending;
- spin_unlock_bh(&ams_delta_lock);
-
- if (apply)
- ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC,
- mute ? AMS_DELTA_LATCH2_MODEM_CODEC : 0);
- return 0;
-}
-
-/* Our codec DAI probably doesn't have its own .ops structure */
-static const struct snd_soc_dai_ops ams_delta_dai_ops = {
- .digital_mute = ams_delta_digital_mute,
-};
-
-/* Will be used if the codec ever has its own digital_mute function */
-static int ams_delta_startup(struct snd_pcm_substream *substream)
-{
- return ams_delta_digital_mute(NULL, 0);
-}
-
-static void ams_delta_shutdown(struct snd_pcm_substream *substream)
-{
- ams_delta_digital_mute(NULL, 1);
-}
-
-
-/*
- * Card initialization
- */
-
-static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_card *card = rtd->card;
- int ret;
- /* Codec is ready, now add/activate board specific controls */
-
- /* Store a pointer to the codec structure for tty ldisc use */
- cx20442_codec = codec;
-
- /* Set up digital mute if not provided by the codec */
- if (!codec_dai->driver->ops) {
- codec_dai->driver->ops = &ams_delta_dai_ops;
- } else {
- ams_delta_ops.startup = ams_delta_startup;
- ams_delta_ops.shutdown = ams_delta_shutdown;
- }
-
- /* Add hook switch - can be used to control the codec from userspace
- * even if line discipline fails */
- ret = snd_soc_jack_new(rtd->codec, "hook_switch",
- SND_JACK_HEADSET, &ams_delta_hook_switch);
- if (ret)
- dev_warn(card->dev,
- "Failed to allocate resources for hook switch, "
- "will continue without one.\n");
- else {
- ret = snd_soc_jack_add_gpios(&ams_delta_hook_switch,
- ARRAY_SIZE(ams_delta_hook_switch_gpios),
- ams_delta_hook_switch_gpios);
- if (ret)
- dev_warn(card->dev,
- "Failed to set up hook switch GPIO line, "
- "will continue with hook switch inactive.\n");
- }
-
- /* Register optional line discipline for over the modem control */
- ret = tty_register_ldisc(N_V253, &cx81801_ops);
- if (ret) {
- dev_warn(card->dev,
- "Failed to register line discipline, "
- "will continue without any controls.\n");
- return 0;
- }
-
- /* Add board specific DAPM widgets and routes */
- ret = snd_soc_dapm_new_controls(dapm, ams_delta_dapm_widgets,
- ARRAY_SIZE(ams_delta_dapm_widgets));
- if (ret) {
- dev_warn(card->dev,
- "Failed to register DAPM controls, "
- "will continue without any.\n");
- return 0;
- }
-
- ret = snd_soc_dapm_add_routes(dapm, ams_delta_audio_map,
- ARRAY_SIZE(ams_delta_audio_map));
- if (ret) {
- dev_warn(card->dev,
- "Failed to set up DAPM routes, "
- "will continue with codec default map.\n");
- return 0;
- }
-
- /* Set up initial pin constellation */
- snd_soc_dapm_disable_pin(dapm, "Mouthpiece");
- snd_soc_dapm_enable_pin(dapm, "Earpiece");
- snd_soc_dapm_enable_pin(dapm, "Microphone");
- snd_soc_dapm_disable_pin(dapm, "Speaker");
- snd_soc_dapm_disable_pin(dapm, "AGCIN");
- snd_soc_dapm_disable_pin(dapm, "AGCOUT");
-
- /* Add virtual switch */
- ret = snd_soc_add_codec_controls(codec, ams_delta_audio_controls,
- ARRAY_SIZE(ams_delta_audio_controls));
- if (ret)
- dev_warn(card->dev,
- "Failed to register audio mode control, "
- "will continue without it.\n");
-
- return 0;
-}
-
-/* DAI glue - connects codec <--> CPU */
-static struct snd_soc_dai_link ams_delta_dai_link = {
- .name = "CX20442",
- .stream_name = "CX20442",
- .cpu_dai_name = "omap-mcbsp.1",
- .codec_dai_name = "cx20442-voice",
- .init = ams_delta_cx20442_init,
- .platform_name = "omap-pcm-audio",
- .codec_name = "cx20442-codec",
- .ops = &ams_delta_ops,
-};
-
-/* Audio card driver */
-static struct snd_soc_card ams_delta_audio_card = {
- .name = "AMS_DELTA",
- .owner = THIS_MODULE,
- .dai_link = &ams_delta_dai_link,
- .num_links = 1,
-};
-
-/* Module init/exit */
-static struct platform_device *ams_delta_audio_platform_device;
-static struct platform_device *cx20442_platform_device;
-
-static int __init ams_delta_module_init(void)
-{
- int ret;
-
- if (!(machine_is_ams_delta()))
- return -ENODEV;
-
- ams_delta_audio_platform_device =
- platform_device_alloc("soc-audio", -1);
- if (!ams_delta_audio_platform_device)
- return -ENOMEM;
-
- platform_set_drvdata(ams_delta_audio_platform_device,
- &ams_delta_audio_card);
-
- ret = platform_device_add(ams_delta_audio_platform_device);
- if (ret)
- goto err;
-
- /*
- * Codec platform device could be registered from elsewhere (board?),
- * but I do it here as it makes sense only if used with the card.
- */
- cx20442_platform_device =
- platform_device_register_simple("cx20442-codec", -1, NULL, 0);
- return 0;
-err:
- platform_device_put(ams_delta_audio_platform_device);
- return ret;
-}
-late_initcall(ams_delta_module_init);
-
-static void __exit ams_delta_module_exit(void)
-{
- if (tty_unregister_ldisc(N_V253) != 0)
- dev_warn(&ams_delta_audio_platform_device->dev,
- "failed to unregister V253 line discipline\n");
-
- snd_soc_jack_free_gpios(&ams_delta_hook_switch,
- ARRAY_SIZE(ams_delta_hook_switch_gpios),
- ams_delta_hook_switch_gpios);
-
- platform_device_unregister(cx20442_platform_device);
- platform_device_unregister(ams_delta_audio_platform_device);
-}
-module_exit(ams_delta_module_exit);
-
-MODULE_AUTHOR("Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>");
-MODULE_DESCRIPTION("ALSA SoC driver for Amstrad E3 (Delta) videophone");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/omap/igep0020.c b/ANDROID_3.4.5/sound/soc/omap/igep0020.c
deleted file mode 100644
index e8357819..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/igep0020.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * igep0020.c -- SoC audio for IGEP v2
- *
- * Based on sound/soc/omap/overo.c by Steve Sakoman
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-#include <plat/mcbsp.h>
-
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-
-static int igep2_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int ret;
-
- /* Set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- printk(KERN_ERR "can't set codec system clock\n");
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_soc_ops igep2_ops = {
- .hw_params = igep2_hw_params,
-};
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link igep2_dai = {
- .name = "TWL4030",
- .stream_name = "TWL4030",
- .cpu_dai_name = "omap-mcbsp.2",
- .codec_dai_name = "twl4030-hifi",
- .platform_name = "omap-pcm-audio",
- .codec_name = "twl4030-codec",
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM,
- .ops = &igep2_ops,
-};
-
-/* Audio machine driver */
-static struct snd_soc_card snd_soc_card_igep2 = {
- .name = "igep2",
- .owner = THIS_MODULE,
- .dai_link = &igep2_dai,
- .num_links = 1,
-};
-
-static struct platform_device *igep2_snd_device;
-
-static int __init igep2_soc_init(void)
-{
- int ret;
-
- if (!machine_is_igep0020())
- return -ENODEV;
- printk(KERN_INFO "IGEP v2 SoC init\n");
-
- igep2_snd_device = platform_device_alloc("soc-audio", -1);
- if (!igep2_snd_device) {
- printk(KERN_ERR "Platform device allocation failed\n");
- return -ENOMEM;
- }
-
- platform_set_drvdata(igep2_snd_device, &snd_soc_card_igep2);
-
- ret = platform_device_add(igep2_snd_device);
- if (ret)
- goto err1;
-
- return 0;
-
-err1:
- printk(KERN_ERR "Unable to add platform device\n");
- platform_device_put(igep2_snd_device);
-
- return ret;
-}
-module_init(igep2_soc_init);
-
-static void __exit igep2_soc_exit(void)
-{
- platform_device_unregister(igep2_snd_device);
-}
-module_exit(igep2_soc_exit);
-
-MODULE_AUTHOR("Enric Balletbo i Serra <eballetbo@iseebcn.com>");
-MODULE_DESCRIPTION("ALSA SoC IGEP v2");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/omap/mcbsp.c b/ANDROID_3.4.5/sound/soc/omap/mcbsp.c
deleted file mode 100644
index e5f44440..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/mcbsp.c
+++ /dev/null
@@ -1,1040 +0,0 @@
-/*
- * sound/soc/omap/mcbsp.c
- *
- * Copyright (C) 2004 Nokia Corporation
- * Author: Samuel Ortiz <samuel.ortiz@nokia.com>
- *
- * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
- * Peter Ujfalusi <peter.ujfalusi@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Multichannel mode not supported.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-
-#include <plat/mcbsp.h>
-
-#include "mcbsp.h"
-
-static void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
-{
- void __iomem *addr = mcbsp->io_base + reg * mcbsp->pdata->reg_step;
-
- if (mcbsp->pdata->reg_size == 2) {
- ((u16 *)mcbsp->reg_cache)[reg] = (u16)val;
- __raw_writew((u16)val, addr);
- } else {
- ((u32 *)mcbsp->reg_cache)[reg] = val;
- __raw_writel(val, addr);
- }
-}
-
-static int omap_mcbsp_read(struct omap_mcbsp *mcbsp, u16 reg, bool from_cache)
-{
- void __iomem *addr = mcbsp->io_base + reg * mcbsp->pdata->reg_step;
-
- if (mcbsp->pdata->reg_size == 2) {
- return !from_cache ? __raw_readw(addr) :
- ((u16 *)mcbsp->reg_cache)[reg];
- } else {
- return !from_cache ? __raw_readl(addr) :
- ((u32 *)mcbsp->reg_cache)[reg];
- }
-}
-
-static void omap_mcbsp_st_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
-{
- __raw_writel(val, mcbsp->st_data->io_base_st + reg);
-}
-
-static int omap_mcbsp_st_read(struct omap_mcbsp *mcbsp, u16 reg)
-{
- return __raw_readl(mcbsp->st_data->io_base_st + reg);
-}
-
-#define MCBSP_READ(mcbsp, reg) \
- omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 0)
-#define MCBSP_WRITE(mcbsp, reg, val) \
- omap_mcbsp_write(mcbsp, OMAP_MCBSP_REG_##reg, val)
-#define MCBSP_READ_CACHE(mcbsp, reg) \
- omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 1)
-
-#define MCBSP_ST_READ(mcbsp, reg) \
- omap_mcbsp_st_read(mcbsp, OMAP_ST_REG_##reg)
-#define MCBSP_ST_WRITE(mcbsp, reg, val) \
- omap_mcbsp_st_write(mcbsp, OMAP_ST_REG_##reg, val)
-
-static void omap_mcbsp_dump_reg(struct omap_mcbsp *mcbsp)
-{
- dev_dbg(mcbsp->dev, "**** McBSP%d regs ****\n", mcbsp->id);
- dev_dbg(mcbsp->dev, "DRR2: 0x%04x\n",
- MCBSP_READ(mcbsp, DRR2));
- dev_dbg(mcbsp->dev, "DRR1: 0x%04x\n",
- MCBSP_READ(mcbsp, DRR1));
- dev_dbg(mcbsp->dev, "DXR2: 0x%04x\n",
- MCBSP_READ(mcbsp, DXR2));
- dev_dbg(mcbsp->dev, "DXR1: 0x%04x\n",
- MCBSP_READ(mcbsp, DXR1));
- dev_dbg(mcbsp->dev, "SPCR2: 0x%04x\n",
- MCBSP_READ(mcbsp, SPCR2));
- dev_dbg(mcbsp->dev, "SPCR1: 0x%04x\n",
- MCBSP_READ(mcbsp, SPCR1));
- dev_dbg(mcbsp->dev, "RCR2: 0x%04x\n",
- MCBSP_READ(mcbsp, RCR2));
- dev_dbg(mcbsp->dev, "RCR1: 0x%04x\n",
- MCBSP_READ(mcbsp, RCR1));
- dev_dbg(mcbsp->dev, "XCR2: 0x%04x\n",
- MCBSP_READ(mcbsp, XCR2));
- dev_dbg(mcbsp->dev, "XCR1: 0x%04x\n",
- MCBSP_READ(mcbsp, XCR1));
- dev_dbg(mcbsp->dev, "SRGR2: 0x%04x\n",
- MCBSP_READ(mcbsp, SRGR2));
- dev_dbg(mcbsp->dev, "SRGR1: 0x%04x\n",
- MCBSP_READ(mcbsp, SRGR1));
- dev_dbg(mcbsp->dev, "PCR0: 0x%04x\n",
- MCBSP_READ(mcbsp, PCR0));
- dev_dbg(mcbsp->dev, "***********************\n");
-}
-
-static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
-{
- struct omap_mcbsp *mcbsp_tx = dev_id;
- u16 irqst_spcr2;
-
- irqst_spcr2 = MCBSP_READ(mcbsp_tx, SPCR2);
- dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n", irqst_spcr2);
-
- if (irqst_spcr2 & XSYNC_ERR) {
- dev_err(mcbsp_tx->dev, "TX Frame Sync Error! : 0x%x\n",
- irqst_spcr2);
- /* Writing zero to XSYNC_ERR clears the IRQ */
- MCBSP_WRITE(mcbsp_tx, SPCR2, MCBSP_READ_CACHE(mcbsp_tx, SPCR2));
- }
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
-{
- struct omap_mcbsp *mcbsp_rx = dev_id;
- u16 irqst_spcr1;
-
- irqst_spcr1 = MCBSP_READ(mcbsp_rx, SPCR1);
- dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n", irqst_spcr1);
-
- if (irqst_spcr1 & RSYNC_ERR) {
- dev_err(mcbsp_rx->dev, "RX Frame Sync Error! : 0x%x\n",
- irqst_spcr1);
- /* Writing zero to RSYNC_ERR clears the IRQ */
- MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1));
- }
-
- return IRQ_HANDLED;
-}
-
-/*
- * omap_mcbsp_config simply write a config to the
- * appropriate McBSP.
- * You either call this function or set the McBSP registers
- * by yourself before calling omap_mcbsp_start().
- */
-void omap_mcbsp_config(struct omap_mcbsp *mcbsp,
- const struct omap_mcbsp_reg_cfg *config)
-{
- dev_dbg(mcbsp->dev, "Configuring McBSP%d phys_base: 0x%08lx\n",
- mcbsp->id, mcbsp->phys_base);
-
- /* We write the given config */
- MCBSP_WRITE(mcbsp, SPCR2, config->spcr2);
- MCBSP_WRITE(mcbsp, SPCR1, config->spcr1);
- MCBSP_WRITE(mcbsp, RCR2, config->rcr2);
- MCBSP_WRITE(mcbsp, RCR1, config->rcr1);
- MCBSP_WRITE(mcbsp, XCR2, config->xcr2);
- MCBSP_WRITE(mcbsp, XCR1, config->xcr1);
- MCBSP_WRITE(mcbsp, SRGR2, config->srgr2);
- MCBSP_WRITE(mcbsp, SRGR1, config->srgr1);
- MCBSP_WRITE(mcbsp, MCR2, config->mcr2);
- MCBSP_WRITE(mcbsp, MCR1, config->mcr1);
- MCBSP_WRITE(mcbsp, PCR0, config->pcr0);
- if (mcbsp->pdata->has_ccr) {
- MCBSP_WRITE(mcbsp, XCCR, config->xccr);
- MCBSP_WRITE(mcbsp, RCCR, config->rccr);
- }
- /* Enable wakeup behavior */
- if (mcbsp->pdata->has_wakeup)
- MCBSP_WRITE(mcbsp, WAKEUPEN, XRDYEN | RRDYEN);
-}
-
-/**
- * omap_mcbsp_dma_reg_params - returns the address of mcbsp data register
- * @id - mcbsp id
- * @stream - indicates the direction of data flow (rx or tx)
- *
- * Returns the address of mcbsp data transmit register or data receive register
- * to be used by DMA for transferring/receiving data based on the value of
- * @stream for the requested mcbsp given by @id
- */
-static int omap_mcbsp_dma_reg_params(struct omap_mcbsp *mcbsp,
- unsigned int stream)
-{
- int data_reg;
-
- if (mcbsp->pdata->reg_size == 2) {
- if (stream)
- data_reg = OMAP_MCBSP_REG_DRR1;
- else
- data_reg = OMAP_MCBSP_REG_DXR1;
- } else {
- if (stream)
- data_reg = OMAP_MCBSP_REG_DRR;
- else
- data_reg = OMAP_MCBSP_REG_DXR;
- }
-
- return mcbsp->phys_dma_base + data_reg * mcbsp->pdata->reg_step;
-}
-
-static void omap_st_on(struct omap_mcbsp *mcbsp)
-{
- unsigned int w;
-
- if (mcbsp->pdata->enable_st_clock)
- mcbsp->pdata->enable_st_clock(mcbsp->id, 1);
-
- /* Enable McBSP Sidetone */
- w = MCBSP_READ(mcbsp, SSELCR);
- MCBSP_WRITE(mcbsp, SSELCR, w | SIDETONEEN);
-
- /* Enable Sidetone from Sidetone Core */
- w = MCBSP_ST_READ(mcbsp, SSELCR);
- MCBSP_ST_WRITE(mcbsp, SSELCR, w | ST_SIDETONEEN);
-}
-
-static void omap_st_off(struct omap_mcbsp *mcbsp)
-{
- unsigned int w;
-
- w = MCBSP_ST_READ(mcbsp, SSELCR);
- MCBSP_ST_WRITE(mcbsp, SSELCR, w & ~(ST_SIDETONEEN));
-
- w = MCBSP_READ(mcbsp, SSELCR);
- MCBSP_WRITE(mcbsp, SSELCR, w & ~(SIDETONEEN));
-
- if (mcbsp->pdata->enable_st_clock)
- mcbsp->pdata->enable_st_clock(mcbsp->id, 0);
-}
-
-static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir)
-{
- u16 val, i;
-
- val = MCBSP_ST_READ(mcbsp, SSELCR);
-
- if (val & ST_COEFFWREN)
- MCBSP_ST_WRITE(mcbsp, SSELCR, val & ~(ST_COEFFWREN));
-
- MCBSP_ST_WRITE(mcbsp, SSELCR, val | ST_COEFFWREN);
-
- for (i = 0; i < 128; i++)
- MCBSP_ST_WRITE(mcbsp, SFIRCR, fir[i]);
-
- i = 0;
-
- val = MCBSP_ST_READ(mcbsp, SSELCR);
- while (!(val & ST_COEFFWRDONE) && (++i < 1000))
- val = MCBSP_ST_READ(mcbsp, SSELCR);
-
- MCBSP_ST_WRITE(mcbsp, SSELCR, val & ~(ST_COEFFWREN));
-
- if (i == 1000)
- dev_err(mcbsp->dev, "McBSP FIR load error!\n");
-}
-
-static void omap_st_chgain(struct omap_mcbsp *mcbsp)
-{
- u16 w;
- struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
-
- w = MCBSP_ST_READ(mcbsp, SSELCR);
-
- MCBSP_ST_WRITE(mcbsp, SGAINCR, ST_CH0GAIN(st_data->ch0gain) | \
- ST_CH1GAIN(st_data->ch1gain));
-}
-
-int omap_st_set_chgain(struct omap_mcbsp *mcbsp, int channel, s16 chgain)
-{
- struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
- int ret = 0;
-
- if (!st_data)
- return -ENOENT;
-
- spin_lock_irq(&mcbsp->lock);
- if (channel == 0)
- st_data->ch0gain = chgain;
- else if (channel == 1)
- st_data->ch1gain = chgain;
- else
- ret = -EINVAL;
-
- if (st_data->enabled)
- omap_st_chgain(mcbsp);
- spin_unlock_irq(&mcbsp->lock);
-
- return ret;
-}
-
-int omap_st_get_chgain(struct omap_mcbsp *mcbsp, int channel, s16 *chgain)
-{
- struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
- int ret = 0;
-
- if (!st_data)
- return -ENOENT;
-
- spin_lock_irq(&mcbsp->lock);
- if (channel == 0)
- *chgain = st_data->ch0gain;
- else if (channel == 1)
- *chgain = st_data->ch1gain;
- else
- ret = -EINVAL;
- spin_unlock_irq(&mcbsp->lock);
-
- return ret;
-}
-
-static int omap_st_start(struct omap_mcbsp *mcbsp)
-{
- struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
-
- if (st_data->enabled && !st_data->running) {
- omap_st_fir_write(mcbsp, st_data->taps);
- omap_st_chgain(mcbsp);
-
- if (!mcbsp->free) {
- omap_st_on(mcbsp);
- st_data->running = 1;
- }
- }
-
- return 0;
-}
-
-int omap_st_enable(struct omap_mcbsp *mcbsp)
-{
- struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
-
- if (!st_data)
- return -ENODEV;
-
- spin_lock_irq(&mcbsp->lock);
- st_data->enabled = 1;
- omap_st_start(mcbsp);
- spin_unlock_irq(&mcbsp->lock);
-
- return 0;
-}
-
-static int omap_st_stop(struct omap_mcbsp *mcbsp)
-{
- struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
-
- if (st_data->running) {
- if (!mcbsp->free) {
- omap_st_off(mcbsp);
- st_data->running = 0;
- }
- }
-
- return 0;
-}
-
-int omap_st_disable(struct omap_mcbsp *mcbsp)
-{
- struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
- int ret = 0;
-
- if (!st_data)
- return -ENODEV;
-
- spin_lock_irq(&mcbsp->lock);
- omap_st_stop(mcbsp);
- st_data->enabled = 0;
- spin_unlock_irq(&mcbsp->lock);
-
- return ret;
-}
-
-int omap_st_is_enabled(struct omap_mcbsp *mcbsp)
-{
- struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
-
- if (!st_data)
- return -ENODEV;
-
- return st_data->enabled;
-}
-
-/*
- * omap_mcbsp_set_rx_threshold configures the transmit threshold in words.
- * The threshold parameter is 1 based, and it is converted (threshold - 1)
- * for the THRSH2 register.
- */
-void omap_mcbsp_set_tx_threshold(struct omap_mcbsp *mcbsp, u16 threshold)
-{
- if (mcbsp->pdata->buffer_size == 0)
- return;
-
- if (threshold && threshold <= mcbsp->max_tx_thres)
- MCBSP_WRITE(mcbsp, THRSH2, threshold - 1);
-}
-
-/*
- * omap_mcbsp_set_rx_threshold configures the receive threshold in words.
- * The threshold parameter is 1 based, and it is converted (threshold - 1)
- * for the THRSH1 register.
- */
-void omap_mcbsp_set_rx_threshold(struct omap_mcbsp *mcbsp, u16 threshold)
-{
- if (mcbsp->pdata->buffer_size == 0)
- return;
-
- if (threshold && threshold <= mcbsp->max_rx_thres)
- MCBSP_WRITE(mcbsp, THRSH1, threshold - 1);
-}
-
-/*
- * omap_mcbsp_get_tx_delay returns the number of used slots in the McBSP FIFO
- */
-u16 omap_mcbsp_get_tx_delay(struct omap_mcbsp *mcbsp)
-{
- u16 buffstat;
-
- if (mcbsp->pdata->buffer_size == 0)
- return 0;
-
- /* Returns the number of free locations in the buffer */
- buffstat = MCBSP_READ(mcbsp, XBUFFSTAT);
-
- /* Number of slots are different in McBSP ports */
- return mcbsp->pdata->buffer_size - buffstat;
-}
-
-/*
- * omap_mcbsp_get_rx_delay returns the number of free slots in the McBSP FIFO
- * to reach the threshold value (when the DMA will be triggered to read it)
- */
-u16 omap_mcbsp_get_rx_delay(struct omap_mcbsp *mcbsp)
-{
- u16 buffstat, threshold;
-
- if (mcbsp->pdata->buffer_size == 0)
- return 0;
-
- /* Returns the number of used locations in the buffer */
- buffstat = MCBSP_READ(mcbsp, RBUFFSTAT);
- /* RX threshold */
- threshold = MCBSP_READ(mcbsp, THRSH1);
-
- /* Return the number of location till we reach the threshold limit */
- if (threshold <= buffstat)
- return 0;
- else
- return threshold - buffstat;
-}
-
-int omap_mcbsp_request(struct omap_mcbsp *mcbsp)
-{
- void *reg_cache;
- int err;
-
- reg_cache = kzalloc(mcbsp->reg_cache_size, GFP_KERNEL);
- if (!reg_cache) {
- return -ENOMEM;
- }
-
- spin_lock(&mcbsp->lock);
- if (!mcbsp->free) {
- dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
- mcbsp->id);
- err = -EBUSY;
- goto err_kfree;
- }
-
- mcbsp->free = false;
- mcbsp->reg_cache = reg_cache;
- spin_unlock(&mcbsp->lock);
-
- if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
- mcbsp->pdata->ops->request(mcbsp->id - 1);
-
- /*
- * Make sure that transmitter, receiver and sample-rate generator are
- * not running before activating IRQs.
- */
- MCBSP_WRITE(mcbsp, SPCR1, 0);
- MCBSP_WRITE(mcbsp, SPCR2, 0);
-
- err = request_irq(mcbsp->tx_irq, omap_mcbsp_tx_irq_handler,
- 0, "McBSP", (void *)mcbsp);
- if (err != 0) {
- dev_err(mcbsp->dev, "Unable to request TX IRQ %d "
- "for McBSP%d\n", mcbsp->tx_irq,
- mcbsp->id);
- goto err_clk_disable;
- }
-
- if (mcbsp->rx_irq) {
- err = request_irq(mcbsp->rx_irq,
- omap_mcbsp_rx_irq_handler,
- 0, "McBSP", (void *)mcbsp);
- if (err != 0) {
- dev_err(mcbsp->dev, "Unable to request RX IRQ %d "
- "for McBSP%d\n", mcbsp->rx_irq,
- mcbsp->id);
- goto err_free_irq;
- }
- }
-
- return 0;
-err_free_irq:
- free_irq(mcbsp->tx_irq, (void *)mcbsp);
-err_clk_disable:
- if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
- mcbsp->pdata->ops->free(mcbsp->id - 1);
-
- /* Disable wakeup behavior */
- if (mcbsp->pdata->has_wakeup)
- MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
-
- spin_lock(&mcbsp->lock);
- mcbsp->free = true;
- mcbsp->reg_cache = NULL;
-err_kfree:
- spin_unlock(&mcbsp->lock);
- kfree(reg_cache);
-
- return err;
-}
-
-void omap_mcbsp_free(struct omap_mcbsp *mcbsp)
-{
- void *reg_cache;
-
- if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
- mcbsp->pdata->ops->free(mcbsp->id - 1);
-
- /* Disable wakeup behavior */
- if (mcbsp->pdata->has_wakeup)
- MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
-
- if (mcbsp->rx_irq)
- free_irq(mcbsp->rx_irq, (void *)mcbsp);
- free_irq(mcbsp->tx_irq, (void *)mcbsp);
-
- reg_cache = mcbsp->reg_cache;
-
- /*
- * Select CLKS source from internal source unconditionally before
- * marking the McBSP port as free.
- * If the external clock source via MCBSP_CLKS pin has been selected the
- * system will refuse to enter idle if the CLKS pin source is not reset
- * back to internal source.
- */
- if (!cpu_class_is_omap1())
- omap2_mcbsp_set_clks_src(mcbsp, MCBSP_CLKS_PRCM_SRC);
-
- spin_lock(&mcbsp->lock);
- if (mcbsp->free)
- dev_err(mcbsp->dev, "McBSP%d was not reserved\n", mcbsp->id);
- else
- mcbsp->free = true;
- mcbsp->reg_cache = NULL;
- spin_unlock(&mcbsp->lock);
-
- if (reg_cache)
- kfree(reg_cache);
-}
-
-/*
- * Here we start the McBSP, by enabling transmitter, receiver or both.
- * If no transmitter or receiver is active prior calling, then sample-rate
- * generator and frame sync are started.
- */
-void omap_mcbsp_start(struct omap_mcbsp *mcbsp, int tx, int rx)
-{
- int enable_srg = 0;
- u16 w;
-
- if (mcbsp->st_data)
- omap_st_start(mcbsp);
-
- /* Only enable SRG, if McBSP is master */
- w = MCBSP_READ_CACHE(mcbsp, PCR0);
- if (w & (FSXM | FSRM | CLKXM | CLKRM))
- enable_srg = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
- MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
-
- if (enable_srg) {
- /* Start the sample generator */
- w = MCBSP_READ_CACHE(mcbsp, SPCR2);
- MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 6));
- }
-
- /* Enable transmitter and receiver */
- tx &= 1;
- w = MCBSP_READ_CACHE(mcbsp, SPCR2);
- MCBSP_WRITE(mcbsp, SPCR2, w | tx);
-
- rx &= 1;
- w = MCBSP_READ_CACHE(mcbsp, SPCR1);
- MCBSP_WRITE(mcbsp, SPCR1, w | rx);
-
- /*
- * Worst case: CLKSRG*2 = 8000khz: (1/8000) * 2 * 2 usec
- * REVISIT: 100us may give enough time for two CLKSRG, however
- * due to some unknown PM related, clock gating etc. reason it
- * is now at 500us.
- */
- udelay(500);
-
- if (enable_srg) {
- /* Start frame sync */
- w = MCBSP_READ_CACHE(mcbsp, SPCR2);
- MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 7));
- }
-
- if (mcbsp->pdata->has_ccr) {
- /* Release the transmitter and receiver */
- w = MCBSP_READ_CACHE(mcbsp, XCCR);
- w &= ~(tx ? XDISABLE : 0);
- MCBSP_WRITE(mcbsp, XCCR, w);
- w = MCBSP_READ_CACHE(mcbsp, RCCR);
- w &= ~(rx ? RDISABLE : 0);
- MCBSP_WRITE(mcbsp, RCCR, w);
- }
-
- /* Dump McBSP Regs */
- omap_mcbsp_dump_reg(mcbsp);
-}
-
-void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx)
-{
- int idle;
- u16 w;
-
- /* Reset transmitter */
- tx &= 1;
- if (mcbsp->pdata->has_ccr) {
- w = MCBSP_READ_CACHE(mcbsp, XCCR);
- w |= (tx ? XDISABLE : 0);
- MCBSP_WRITE(mcbsp, XCCR, w);
- }
- w = MCBSP_READ_CACHE(mcbsp, SPCR2);
- MCBSP_WRITE(mcbsp, SPCR2, w & ~tx);
-
- /* Reset receiver */
- rx &= 1;
- if (mcbsp->pdata->has_ccr) {
- w = MCBSP_READ_CACHE(mcbsp, RCCR);
- w |= (rx ? RDISABLE : 0);
- MCBSP_WRITE(mcbsp, RCCR, w);
- }
- w = MCBSP_READ_CACHE(mcbsp, SPCR1);
- MCBSP_WRITE(mcbsp, SPCR1, w & ~rx);
-
- idle = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
- MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
-
- if (idle) {
- /* Reset the sample rate generator */
- w = MCBSP_READ_CACHE(mcbsp, SPCR2);
- MCBSP_WRITE(mcbsp, SPCR2, w & ~(1 << 6));
- }
-
- if (mcbsp->st_data)
- omap_st_stop(mcbsp);
-}
-
-int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id)
-{
- const char *src;
-
- if (fck_src_id == MCBSP_CLKS_PAD_SRC)
- src = "clks_ext";
- else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
- src = "clks_fclk";
- else
- return -EINVAL;
-
- if (mcbsp->pdata->set_clk_src)
- return mcbsp->pdata->set_clk_src(mcbsp->dev, mcbsp->fclk, src);
- else
- return -EINVAL;
-}
-
-int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux)
-{
- const char *signal, *src;
-
- if (mcbsp->pdata->mux_signal)
- return -EINVAL;
-
- switch (mux) {
- case CLKR_SRC_CLKR:
- signal = "clkr";
- src = "clkr";
- break;
- case CLKR_SRC_CLKX:
- signal = "clkr";
- src = "clkx";
- break;
- case FSR_SRC_FSR:
- signal = "fsr";
- src = "fsr";
- break;
- case FSR_SRC_FSX:
- signal = "fsr";
- src = "fsx";
- break;
- default:
- return -EINVAL;
- }
-
- return mcbsp->pdata->mux_signal(mcbsp->dev, signal, src);
-}
-
-#define max_thres(m) (mcbsp->pdata->buffer_size)
-#define valid_threshold(m, val) ((val) <= max_thres(m))
-#define THRESHOLD_PROP_BUILDER(prop) \
-static ssize_t prop##_show(struct device *dev, \
- struct device_attribute *attr, char *buf) \
-{ \
- struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \
- \
- return sprintf(buf, "%u\n", mcbsp->prop); \
-} \
- \
-static ssize_t prop##_store(struct device *dev, \
- struct device_attribute *attr, \
- const char *buf, size_t size) \
-{ \
- struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \
- unsigned long val; \
- int status; \
- \
- status = strict_strtoul(buf, 0, &val); \
- if (status) \
- return status; \
- \
- if (!valid_threshold(mcbsp, val)) \
- return -EDOM; \
- \
- mcbsp->prop = val; \
- return size; \
-} \
- \
-static DEVICE_ATTR(prop, 0644, prop##_show, prop##_store);
-
-THRESHOLD_PROP_BUILDER(max_tx_thres);
-THRESHOLD_PROP_BUILDER(max_rx_thres);
-
-static const char *dma_op_modes[] = {
- "element", "threshold", "frame",
-};
-
-static ssize_t dma_op_mode_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
- int dma_op_mode, i = 0;
- ssize_t len = 0;
- const char * const *s;
-
- dma_op_mode = mcbsp->dma_op_mode;
-
- for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++) {
- if (dma_op_mode == i)
- len += sprintf(buf + len, "[%s] ", *s);
- else
- len += sprintf(buf + len, "%s ", *s);
- }
- len += sprintf(buf + len, "\n");
-
- return len;
-}
-
-static ssize_t dma_op_mode_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t size)
-{
- struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
- const char * const *s;
- int i = 0;
-
- for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++)
- if (sysfs_streq(buf, *s))
- break;
-
- if (i == ARRAY_SIZE(dma_op_modes))
- return -EINVAL;
-
- spin_lock_irq(&mcbsp->lock);
- if (!mcbsp->free) {
- size = -EBUSY;
- goto unlock;
- }
- mcbsp->dma_op_mode = i;
-
-unlock:
- spin_unlock_irq(&mcbsp->lock);
-
- return size;
-}
-
-static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store);
-
-static const struct attribute *additional_attrs[] = {
- &dev_attr_max_tx_thres.attr,
- &dev_attr_max_rx_thres.attr,
- &dev_attr_dma_op_mode.attr,
- NULL,
-};
-
-static const struct attribute_group additional_attr_group = {
- .attrs = (struct attribute **)additional_attrs,
-};
-
-static ssize_t st_taps_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
- struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
- ssize_t status = 0;
- int i;
-
- spin_lock_irq(&mcbsp->lock);
- for (i = 0; i < st_data->nr_taps; i++)
- status += sprintf(&buf[status], (i ? ", %d" : "%d"),
- st_data->taps[i]);
- if (i)
- status += sprintf(&buf[status], "\n");
- spin_unlock_irq(&mcbsp->lock);
-
- return status;
-}
-
-static ssize_t st_taps_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t size)
-{
- struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
- struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
- int val, tmp, status, i = 0;
-
- spin_lock_irq(&mcbsp->lock);
- memset(st_data->taps, 0, sizeof(st_data->taps));
- st_data->nr_taps = 0;
-
- do {
- status = sscanf(buf, "%d%n", &val, &tmp);
- if (status < 0 || status == 0) {
- size = -EINVAL;
- goto out;
- }
- if (val < -32768 || val > 32767) {
- size = -EINVAL;
- goto out;
- }
- st_data->taps[i++] = val;
- buf += tmp;
- if (*buf != ',')
- break;
- buf++;
- } while (1);
-
- st_data->nr_taps = i;
-
-out:
- spin_unlock_irq(&mcbsp->lock);
-
- return size;
-}
-
-static DEVICE_ATTR(st_taps, 0644, st_taps_show, st_taps_store);
-
-static const struct attribute *sidetone_attrs[] = {
- &dev_attr_st_taps.attr,
- NULL,
-};
-
-static const struct attribute_group sidetone_attr_group = {
- .attrs = (struct attribute **)sidetone_attrs,
-};
-
-static int __devinit omap_st_add(struct omap_mcbsp *mcbsp,
- struct resource *res)
-{
- struct omap_mcbsp_st_data *st_data;
- int err;
-
- st_data = devm_kzalloc(mcbsp->dev, sizeof(*mcbsp->st_data), GFP_KERNEL);
- if (!st_data)
- return -ENOMEM;
-
- st_data->io_base_st = devm_ioremap(mcbsp->dev, res->start,
- resource_size(res));
- if (!st_data->io_base_st)
- return -ENOMEM;
-
- err = sysfs_create_group(&mcbsp->dev->kobj, &sidetone_attr_group);
- if (err)
- return err;
-
- mcbsp->st_data = st_data;
- return 0;
-}
-
-/*
- * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
- * 730 has only 2 McBSP, and both of them are MPU peripherals.
- */
-int __devinit omap_mcbsp_init(struct platform_device *pdev)
-{
- struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
- struct resource *res;
- int ret = 0;
-
- spin_lock_init(&mcbsp->lock);
- mcbsp->free = true;
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
- if (!res) {
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(mcbsp->dev, "invalid memory resource\n");
- return -ENOMEM;
- }
- }
- if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
- dev_name(&pdev->dev))) {
- dev_err(mcbsp->dev, "memory region already claimed\n");
- return -ENODEV;
- }
-
- mcbsp->phys_base = res->start;
- mcbsp->reg_cache_size = resource_size(res);
- mcbsp->io_base = devm_ioremap(&pdev->dev, res->start,
- resource_size(res));
- if (!mcbsp->io_base)
- return -ENOMEM;
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma");
- if (!res)
- mcbsp->phys_dma_base = mcbsp->phys_base;
- else
- mcbsp->phys_dma_base = res->start;
-
- mcbsp->tx_irq = platform_get_irq_byname(pdev, "tx");
- mcbsp->rx_irq = platform_get_irq_byname(pdev, "rx");
-
- /* From OMAP4 there will be a single irq line */
- if (mcbsp->tx_irq == -ENXIO) {
- mcbsp->tx_irq = platform_get_irq(pdev, 0);
- mcbsp->rx_irq = 0;
- }
-
- res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
- if (!res) {
- dev_err(&pdev->dev, "invalid rx DMA channel\n");
- return -ENODEV;
- }
- /* RX DMA request number, and port address configuration */
- mcbsp->dma_data[1].name = "Audio Capture";
- mcbsp->dma_data[1].dma_req = res->start;
- mcbsp->dma_data[1].port_addr = omap_mcbsp_dma_reg_params(mcbsp, 1);
-
- res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
- if (!res) {
- dev_err(&pdev->dev, "invalid tx DMA channel\n");
- return -ENODEV;
- }
- /* TX DMA request number, and port address configuration */
- mcbsp->dma_data[0].name = "Audio Playback";
- mcbsp->dma_data[0].dma_req = res->start;
- mcbsp->dma_data[0].port_addr = omap_mcbsp_dma_reg_params(mcbsp, 0);
-
- mcbsp->fclk = clk_get(&pdev->dev, "fck");
- if (IS_ERR(mcbsp->fclk)) {
- ret = PTR_ERR(mcbsp->fclk);
- dev_err(mcbsp->dev, "unable to get fck: %d\n", ret);
- return ret;
- }
-
- mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
- if (mcbsp->pdata->buffer_size) {
- /*
- * Initially configure the maximum thresholds to a safe value.
- * The McBSP FIFO usage with these values should not go under
- * 16 locations.
- * If the whole FIFO without safety buffer is used, than there
- * is a possibility that the DMA will be not able to push the
- * new data on time, causing channel shifts in runtime.
- */
- mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10;
- mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10;
-
- ret = sysfs_create_group(&mcbsp->dev->kobj,
- &additional_attr_group);
- if (ret) {
- dev_err(mcbsp->dev,
- "Unable to create additional controls\n");
- goto err_thres;
- }
- } else {
- mcbsp->max_tx_thres = -EINVAL;
- mcbsp->max_rx_thres = -EINVAL;
- }
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sidetone");
- if (res) {
- ret = omap_st_add(mcbsp, res);
- if (ret) {
- dev_err(mcbsp->dev,
- "Unable to create sidetone controls\n");
- goto err_st;
- }
- }
-
- return 0;
-
-err_st:
- if (mcbsp->pdata->buffer_size)
- sysfs_remove_group(&mcbsp->dev->kobj, &additional_attr_group);
-err_thres:
- clk_put(mcbsp->fclk);
- return ret;
-}
-
-void __devexit omap_mcbsp_sysfs_remove(struct omap_mcbsp *mcbsp)
-{
- if (mcbsp->pdata->buffer_size)
- sysfs_remove_group(&mcbsp->dev->kobj, &additional_attr_group);
-
- if (mcbsp->st_data)
- sysfs_remove_group(&mcbsp->dev->kobj, &sidetone_attr_group);
-}
diff --git a/ANDROID_3.4.5/sound/soc/omap/mcbsp.h b/ANDROID_3.4.5/sound/soc/omap/mcbsp.h
deleted file mode 100644
index a944fcc9..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/mcbsp.h
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * sound/soc/omap/mcbsp.h
- *
- * OMAP Multi-Channel Buffered Serial Port
- *
- * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
- * Peter Ujfalusi <peter.ujfalusi@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __ASOC_MCBSP_H
-#define __ASOC_MCBSP_H
-
-#include "omap-pcm.h"
-
-/* McBSP register numbers. Register address offset = num * reg_step */
-enum {
- /* Common registers */
- OMAP_MCBSP_REG_SPCR2 = 4,
- OMAP_MCBSP_REG_SPCR1,
- OMAP_MCBSP_REG_RCR2,
- OMAP_MCBSP_REG_RCR1,
- OMAP_MCBSP_REG_XCR2,
- OMAP_MCBSP_REG_XCR1,
- OMAP_MCBSP_REG_SRGR2,
- OMAP_MCBSP_REG_SRGR1,
- OMAP_MCBSP_REG_MCR2,
- OMAP_MCBSP_REG_MCR1,
- OMAP_MCBSP_REG_RCERA,
- OMAP_MCBSP_REG_RCERB,
- OMAP_MCBSP_REG_XCERA,
- OMAP_MCBSP_REG_XCERB,
- OMAP_MCBSP_REG_PCR0,
- OMAP_MCBSP_REG_RCERC,
- OMAP_MCBSP_REG_RCERD,
- OMAP_MCBSP_REG_XCERC,
- OMAP_MCBSP_REG_XCERD,
- OMAP_MCBSP_REG_RCERE,
- OMAP_MCBSP_REG_RCERF,
- OMAP_MCBSP_REG_XCERE,
- OMAP_MCBSP_REG_XCERF,
- OMAP_MCBSP_REG_RCERG,
- OMAP_MCBSP_REG_RCERH,
- OMAP_MCBSP_REG_XCERG,
- OMAP_MCBSP_REG_XCERH,
-
- /* OMAP1-OMAP2420 registers */
- OMAP_MCBSP_REG_DRR2 = 0,
- OMAP_MCBSP_REG_DRR1,
- OMAP_MCBSP_REG_DXR2,
- OMAP_MCBSP_REG_DXR1,
-
- /* OMAP2430 and onwards */
- OMAP_MCBSP_REG_DRR = 0,
- OMAP_MCBSP_REG_DXR = 2,
- OMAP_MCBSP_REG_SYSCON = 35,
- OMAP_MCBSP_REG_THRSH2,
- OMAP_MCBSP_REG_THRSH1,
- OMAP_MCBSP_REG_IRQST = 40,
- OMAP_MCBSP_REG_IRQEN,
- OMAP_MCBSP_REG_WAKEUPEN,
- OMAP_MCBSP_REG_XCCR,
- OMAP_MCBSP_REG_RCCR,
- OMAP_MCBSP_REG_XBUFFSTAT,
- OMAP_MCBSP_REG_RBUFFSTAT,
- OMAP_MCBSP_REG_SSELCR,
-};
-
-/* OMAP3 sidetone control registers */
-#define OMAP_ST_REG_REV 0x00
-#define OMAP_ST_REG_SYSCONFIG 0x10
-#define OMAP_ST_REG_IRQSTATUS 0x18
-#define OMAP_ST_REG_IRQENABLE 0x1C
-#define OMAP_ST_REG_SGAINCR 0x24
-#define OMAP_ST_REG_SFIRCR 0x28
-#define OMAP_ST_REG_SSELCR 0x2C
-
-/************************** McBSP SPCR1 bit definitions ***********************/
-#define RRST BIT(0)
-#define RRDY BIT(1)
-#define RFULL BIT(2)
-#define RSYNC_ERR BIT(3)
-#define RINTM(value) (((value) & 0x3) << 4) /* bits 4:5 */
-#define ABIS BIT(6)
-#define DXENA BIT(7)
-#define CLKSTP(value) (((value) & 0x3) << 11) /* bits 11:12 */
-#define RJUST(value) (((value) & 0x3) << 13) /* bits 13:14 */
-#define ALB BIT(15)
-#define DLB BIT(15)
-
-/************************** McBSP SPCR2 bit definitions ***********************/
-#define XRST BIT(0)
-#define XRDY BIT(1)
-#define XEMPTY BIT(2)
-#define XSYNC_ERR BIT(3)
-#define XINTM(value) (((value) & 0x3) << 4) /* bits 4:5 */
-#define GRST BIT(6)
-#define FRST BIT(7)
-#define SOFT BIT(8)
-#define FREE BIT(9)
-
-/************************** McBSP PCR bit definitions *************************/
-#define CLKRP BIT(0)
-#define CLKXP BIT(1)
-#define FSRP BIT(2)
-#define FSXP BIT(3)
-#define DR_STAT BIT(4)
-#define DX_STAT BIT(5)
-#define CLKS_STAT BIT(6)
-#define SCLKME BIT(7)
-#define CLKRM BIT(8)
-#define CLKXM BIT(9)
-#define FSRM BIT(10)
-#define FSXM BIT(11)
-#define RIOEN BIT(12)
-#define XIOEN BIT(13)
-#define IDLE_EN BIT(14)
-
-/************************** McBSP RCR1 bit definitions ************************/
-#define RWDLEN1(value) (((value) & 0x7) << 5) /* Bits 5:7 */
-#define RFRLEN1(value) (((value) & 0x7f) << 8) /* Bits 8:14 */
-
-/************************** McBSP XCR1 bit definitions ************************/
-#define XWDLEN1(value) (((value) & 0x7) << 5) /* Bits 5:7 */
-#define XFRLEN1(value) (((value) & 0x7f) << 8) /* Bits 8:14 */
-
-/*************************** McBSP RCR2 bit definitions ***********************/
-#define RDATDLY(value) ((value) & 0x3) /* Bits 0:1 */
-#define RFIG BIT(2)
-#define RCOMPAND(value) (((value) & 0x3) << 3) /* Bits 3:4 */
-#define RWDLEN2(value) (((value) & 0x7) << 5) /* Bits 5:7 */
-#define RFRLEN2(value) (((value) & 0x7f) << 8) /* Bits 8:14 */
-#define RPHASE BIT(15)
-
-/*************************** McBSP XCR2 bit definitions ***********************/
-#define XDATDLY(value) ((value) & 0x3) /* Bits 0:1 */
-#define XFIG BIT(2)
-#define XCOMPAND(value) (((value) & 0x3) << 3) /* Bits 3:4 */
-#define XWDLEN2(value) (((value) & 0x7) << 5) /* Bits 5:7 */
-#define XFRLEN2(value) (((value) & 0x7f) << 8) /* Bits 8:14 */
-#define XPHASE BIT(15)
-
-/************************* McBSP SRGR1 bit definitions ************************/
-#define CLKGDV(value) ((value) & 0x7f) /* Bits 0:7 */
-#define FWID(value) (((value) & 0xff) << 8) /* Bits 8:15 */
-
-/************************* McBSP SRGR2 bit definitions ************************/
-#define FPER(value) ((value) & 0x0fff) /* Bits 0:11 */
-#define FSGM BIT(12)
-#define CLKSM BIT(13)
-#define CLKSP BIT(14)
-#define GSYNC BIT(15)
-
-/************************* McBSP MCR1 bit definitions *************************/
-#define RMCM BIT(0)
-#define RCBLK(value) (((value) & 0x7) << 2) /* Bits 2:4 */
-#define RPABLK(value) (((value) & 0x3) << 5) /* Bits 5:6 */
-#define RPBBLK(value) (((value) & 0x3) << 7) /* Bits 7:8 */
-
-/************************* McBSP MCR2 bit definitions *************************/
-#define XMCM(value) ((value) & 0x3) /* Bits 0:1 */
-#define XCBLK(value) (((value) & 0x7) << 2) /* Bits 2:4 */
-#define XPABLK(value) (((value) & 0x3) << 5) /* Bits 5:6 */
-#define XPBBLK(value) (((value) & 0x3) << 7) /* Bits 7:8 */
-
-/*********************** McBSP XCCR bit definitions *************************/
-#define XDISABLE BIT(0)
-#define XDMAEN BIT(3)
-#define DILB BIT(5)
-#define XFULL_CYCLE BIT(11)
-#define DXENDLY(value) (((value) & 0x3) << 12) /* Bits 12:13 */
-#define PPCONNECT BIT(14)
-#define EXTCLKGATE BIT(15)
-
-/********************** McBSP RCCR bit definitions *************************/
-#define RDISABLE BIT(0)
-#define RDMAEN BIT(3)
-#define RFULL_CYCLE BIT(11)
-
-/********************** McBSP SYSCONFIG bit definitions ********************/
-#define SOFTRST BIT(1)
-#define ENAWAKEUP BIT(2)
-#define SIDLEMODE(value) (((value) & 0x3) << 3)
-#define CLOCKACTIVITY(value) (((value) & 0x3) << 8)
-
-/********************** McBSP SSELCR bit definitions ***********************/
-#define SIDETONEEN BIT(10)
-
-/********************** McBSP Sidetone SYSCONFIG bit definitions ***********/
-#define ST_AUTOIDLE BIT(0)
-
-/********************** McBSP Sidetone SGAINCR bit definitions *************/
-#define ST_CH0GAIN(value) ((value) & 0xffff) /* Bits 0:15 */
-#define ST_CH1GAIN(value) (((value) & 0xffff) << 16) /* Bits 16:31 */
-
-/********************** McBSP Sidetone SFIRCR bit definitions **************/
-#define ST_FIRCOEFF(value) ((value) & 0xffff) /* Bits 0:15 */
-
-/********************** McBSP Sidetone SSELCR bit definitions **************/
-#define ST_SIDETONEEN BIT(0)
-#define ST_COEFFWREN BIT(1)
-#define ST_COEFFWRDONE BIT(2)
-
-/********************** McBSP DMA operating modes **************************/
-#define MCBSP_DMA_MODE_ELEMENT 0
-#define MCBSP_DMA_MODE_THRESHOLD 1
-#define MCBSP_DMA_MODE_FRAME 2
-
-/********************** McBSP WAKEUPEN bit definitions *********************/
-#define RSYNCERREN BIT(0)
-#define RFSREN BIT(1)
-#define REOFEN BIT(2)
-#define RRDYEN BIT(3)
-#define XSYNCERREN BIT(7)
-#define XFSXEN BIT(8)
-#define XEOFEN BIT(9)
-#define XRDYEN BIT(10)
-#define XEMPTYEOFEN BIT(14)
-
-/* Clock signal muxing options */
-#define CLKR_SRC_CLKR 0 /* CLKR signal is from the CLKR pin */
-#define CLKR_SRC_CLKX 1 /* CLKR signal is from the CLKX pin */
-#define FSR_SRC_FSR 2 /* FSR signal is from the FSR pin */
-#define FSR_SRC_FSX 3 /* FSR signal is from the FSX pin */
-
-/* McBSP functional clock sources */
-#define MCBSP_CLKS_PRCM_SRC 0
-#define MCBSP_CLKS_PAD_SRC 1
-
-/* we don't do multichannel for now */
-struct omap_mcbsp_reg_cfg {
- u16 spcr2;
- u16 spcr1;
- u16 rcr2;
- u16 rcr1;
- u16 xcr2;
- u16 xcr1;
- u16 srgr2;
- u16 srgr1;
- u16 mcr2;
- u16 mcr1;
- u16 pcr0;
- u16 rcerc;
- u16 rcerd;
- u16 xcerc;
- u16 xcerd;
- u16 rcere;
- u16 rcerf;
- u16 xcere;
- u16 xcerf;
- u16 rcerg;
- u16 rcerh;
- u16 xcerg;
- u16 xcerh;
- u16 xccr;
- u16 rccr;
-};
-
-struct omap_mcbsp_st_data {
- void __iomem *io_base_st;
- bool running;
- bool enabled;
- s16 taps[128]; /* Sidetone filter coefficients */
- int nr_taps; /* Number of filter coefficients in use */
- s16 ch0gain;
- s16 ch1gain;
-};
-
-struct omap_mcbsp {
- struct device *dev;
- struct clk *fclk;
- spinlock_t lock;
- unsigned long phys_base;
- unsigned long phys_dma_base;
- void __iomem *io_base;
- u8 id;
- /*
- * Flags indicating is the bus already activated and configured by
- * another substream
- */
- int active;
- int configured;
- u8 free;
-
- int rx_irq;
- int tx_irq;
-
- /* Protect the field .free, while checking if the mcbsp is in use */
- struct omap_mcbsp_platform_data *pdata;
- struct omap_mcbsp_st_data *st_data;
- struct omap_mcbsp_reg_cfg cfg_regs;
- struct omap_pcm_dma_data dma_data[2];
- int dma_op_mode;
- u16 max_tx_thres;
- u16 max_rx_thres;
- void *reg_cache;
- int reg_cache_size;
-
- unsigned int fmt;
- unsigned int in_freq;
- int clk_div;
- int wlen;
-};
-
-void omap_mcbsp_config(struct omap_mcbsp *mcbsp,
- const struct omap_mcbsp_reg_cfg *config);
-void omap_mcbsp_set_tx_threshold(struct omap_mcbsp *mcbsp, u16 threshold);
-void omap_mcbsp_set_rx_threshold(struct omap_mcbsp *mcbsp, u16 threshold);
-u16 omap_mcbsp_get_tx_delay(struct omap_mcbsp *mcbsp);
-u16 omap_mcbsp_get_rx_delay(struct omap_mcbsp *mcbsp);
-int omap_mcbsp_get_dma_op_mode(struct omap_mcbsp *mcbsp);
-int omap_mcbsp_request(struct omap_mcbsp *mcbsp);
-void omap_mcbsp_free(struct omap_mcbsp *mcbsp);
-void omap_mcbsp_start(struct omap_mcbsp *mcbsp, int tx, int rx);
-void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx);
-
-/* McBSP functional clock source changing function */
-int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id);
-
-/* McBSP signal muxing API */
-int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux);
-
-/* Sidetone specific API */
-int omap_st_set_chgain(struct omap_mcbsp *mcbsp, int channel, s16 chgain);
-int omap_st_get_chgain(struct omap_mcbsp *mcbsp, int channel, s16 *chgain);
-int omap_st_enable(struct omap_mcbsp *mcbsp);
-int omap_st_disable(struct omap_mcbsp *mcbsp);
-int omap_st_is_enabled(struct omap_mcbsp *mcbsp);
-
-int __devinit omap_mcbsp_init(struct platform_device *pdev);
-void __devexit omap_mcbsp_sysfs_remove(struct omap_mcbsp *mcbsp);
-
-#endif /* __ASOC_MCBSP_H */
diff --git a/ANDROID_3.4.5/sound/soc/omap/n810.c b/ANDROID_3.4.5/sound/soc/omap/n810.c
deleted file mode 100644
index abac4b69..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/n810.c
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * n810.c -- SoC audio for Nokia N810
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/clk.h>
-#include <linux/i2c.h>
-#include <linux/platform_device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <linux/gpio.h>
-#include <linux/module.h>
-#include <plat/mcbsp.h>
-
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-
-#define N810_HEADSET_AMP_GPIO 10
-#define N810_SPEAKER_AMP_GPIO 101
-
-enum {
- N810_JACK_DISABLED,
- N810_JACK_HP,
- N810_JACK_HS,
- N810_JACK_MIC,
-};
-
-static struct clk *sys_clkout2;
-static struct clk *sys_clkout2_src;
-static struct clk *func96m_clk;
-
-static int n810_spk_func;
-static int n810_jack_func;
-static int n810_dmic_func;
-
-static void n810_ext_control(struct snd_soc_dapm_context *dapm)
-{
- int hp = 0, line1l = 0;
-
- switch (n810_jack_func) {
- case N810_JACK_HS:
- line1l = 1;
- case N810_JACK_HP:
- hp = 1;
- break;
- case N810_JACK_MIC:
- line1l = 1;
- break;
- }
-
- if (n810_spk_func)
- snd_soc_dapm_enable_pin(dapm, "Ext Spk");
- else
- snd_soc_dapm_disable_pin(dapm, "Ext Spk");
-
- if (hp)
- snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
- else
- snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
- if (line1l)
- snd_soc_dapm_enable_pin(dapm, "LINE1L");
- else
- snd_soc_dapm_disable_pin(dapm, "LINE1L");
-
- if (n810_dmic_func)
- snd_soc_dapm_enable_pin(dapm, "DMic");
- else
- snd_soc_dapm_disable_pin(dapm, "DMic");
-
- snd_soc_dapm_sync(dapm);
-}
-
-static int n810_startup(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
-
- snd_pcm_hw_constraint_minmax(runtime,
- SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
-
- n810_ext_control(&codec->dapm);
- return clk_enable(sys_clkout2);
-}
-
-static void n810_shutdown(struct snd_pcm_substream *substream)
-{
- clk_disable(sys_clkout2);
-}
-
-static int n810_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int err;
-
- /* Set the codec system clock for DAC and ADC */
- err = snd_soc_dai_set_sysclk(codec_dai, 0, 12000000,
- SND_SOC_CLOCK_IN);
-
- return err;
-}
-
-static struct snd_soc_ops n810_ops = {
- .startup = n810_startup,
- .hw_params = n810_hw_params,
- .shutdown = n810_shutdown,
-};
-
-static int n810_get_spk(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = n810_spk_func;
-
- return 0;
-}
-
-static int n810_set_spk(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
-
- if (n810_spk_func == ucontrol->value.integer.value[0])
- return 0;
-
- n810_spk_func = ucontrol->value.integer.value[0];
- n810_ext_control(&card->dapm);
-
- return 1;
-}
-
-static int n810_get_jack(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = n810_jack_func;
-
- return 0;
-}
-
-static int n810_set_jack(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
-
- if (n810_jack_func == ucontrol->value.integer.value[0])
- return 0;
-
- n810_jack_func = ucontrol->value.integer.value[0];
- n810_ext_control(&card->dapm);
-
- return 1;
-}
-
-static int n810_get_input(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = n810_dmic_func;
-
- return 0;
-}
-
-static int n810_set_input(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
-
- if (n810_dmic_func == ucontrol->value.integer.value[0])
- return 0;
-
- n810_dmic_func = ucontrol->value.integer.value[0];
- n810_ext_control(&card->dapm);
-
- return 1;
-}
-
-static int n810_spk_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- if (SND_SOC_DAPM_EVENT_ON(event))
- gpio_set_value(N810_SPEAKER_AMP_GPIO, 1);
- else
- gpio_set_value(N810_SPEAKER_AMP_GPIO, 0);
-
- return 0;
-}
-
-static int n810_jack_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- if (SND_SOC_DAPM_EVENT_ON(event))
- gpio_set_value(N810_HEADSET_AMP_GPIO, 1);
- else
- gpio_set_value(N810_HEADSET_AMP_GPIO, 0);
-
- return 0;
-}
-
-static const struct snd_soc_dapm_widget aic33_dapm_widgets[] = {
- SND_SOC_DAPM_SPK("Ext Spk", n810_spk_event),
- SND_SOC_DAPM_HP("Headphone Jack", n810_jack_event),
- SND_SOC_DAPM_MIC("DMic", NULL),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- {"Headphone Jack", NULL, "HPLOUT"},
- {"Headphone Jack", NULL, "HPROUT"},
-
- {"Ext Spk", NULL, "LLOUT"},
- {"Ext Spk", NULL, "RLOUT"},
-
- {"DMic Rate 64", NULL, "Mic Bias 2V"},
- {"Mic Bias 2V", NULL, "DMic"},
-};
-
-static const char *spk_function[] = {"Off", "On"};
-static const char *jack_function[] = {"Off", "Headphone", "Headset", "Mic"};
-static const char *input_function[] = {"ADC", "Digital Mic"};
-static const struct soc_enum n810_enum[] = {
- SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function),
- SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(jack_function), jack_function),
- SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(input_function), input_function),
-};
-
-static const struct snd_kcontrol_new aic33_n810_controls[] = {
- SOC_ENUM_EXT("Speaker Function", n810_enum[0],
- n810_get_spk, n810_set_spk),
- SOC_ENUM_EXT("Jack Function", n810_enum[1],
- n810_get_jack, n810_set_jack),
- SOC_ENUM_EXT("Input Select", n810_enum[2],
- n810_get_input, n810_set_input),
-};
-
-static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- /* Not connected */
- snd_soc_dapm_nc_pin(dapm, "MONO_LOUT");
- snd_soc_dapm_nc_pin(dapm, "HPLCOM");
- snd_soc_dapm_nc_pin(dapm, "HPRCOM");
- snd_soc_dapm_nc_pin(dapm, "MIC3L");
- snd_soc_dapm_nc_pin(dapm, "MIC3R");
- snd_soc_dapm_nc_pin(dapm, "LINE1R");
- snd_soc_dapm_nc_pin(dapm, "LINE2L");
- snd_soc_dapm_nc_pin(dapm, "LINE2R");
-
- return 0;
-}
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link n810_dai = {
- .name = "TLV320AIC33",
- .stream_name = "AIC33",
- .cpu_dai_name = "omap-mcbsp.2",
- .platform_name = "omap-pcm-audio",
- .codec_name = "tlv320aic3x-codec.2-0018",
- .codec_dai_name = "tlv320aic3x-hifi",
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM,
- .init = n810_aic33_init,
- .ops = &n810_ops,
-};
-
-/* Audio machine driver */
-static struct snd_soc_card snd_soc_n810 = {
- .name = "N810",
- .owner = THIS_MODULE,
- .dai_link = &n810_dai,
- .num_links = 1,
-
- .controls = aic33_n810_controls,
- .num_controls = ARRAY_SIZE(aic33_n810_controls),
- .dapm_widgets = aic33_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(aic33_dapm_widgets),
- .dapm_routes = audio_map,
- .num_dapm_routes = ARRAY_SIZE(audio_map),
-};
-
-static struct platform_device *n810_snd_device;
-
-static int __init n810_soc_init(void)
-{
- int err;
- struct device *dev;
-
- if (!(machine_is_nokia_n810() || machine_is_nokia_n810_wimax()))
- return -ENODEV;
-
- n810_snd_device = platform_device_alloc("soc-audio", -1);
- if (!n810_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(n810_snd_device, &snd_soc_n810);
- err = platform_device_add(n810_snd_device);
- if (err)
- goto err1;
-
- dev = &n810_snd_device->dev;
-
- sys_clkout2_src = clk_get(dev, "sys_clkout2_src");
- if (IS_ERR(sys_clkout2_src)) {
- dev_err(dev, "Could not get sys_clkout2_src clock\n");
- err = PTR_ERR(sys_clkout2_src);
- goto err2;
- }
- sys_clkout2 = clk_get(dev, "sys_clkout2");
- if (IS_ERR(sys_clkout2)) {
- dev_err(dev, "Could not get sys_clkout2\n");
- err = PTR_ERR(sys_clkout2);
- goto err3;
- }
- /*
- * Configure 12 MHz output on SYS_CLKOUT2. Therefore we must use
- * 96 MHz as its parent in order to get 12 MHz
- */
- func96m_clk = clk_get(dev, "func_96m_ck");
- if (IS_ERR(func96m_clk)) {
- dev_err(dev, "Could not get func 96M clock\n");
- err = PTR_ERR(func96m_clk);
- goto err4;
- }
- clk_set_parent(sys_clkout2_src, func96m_clk);
- clk_set_rate(sys_clkout2, 12000000);
-
- BUG_ON((gpio_request(N810_HEADSET_AMP_GPIO, "hs_amp") < 0) ||
- (gpio_request(N810_SPEAKER_AMP_GPIO, "spk_amp") < 0));
-
- gpio_direction_output(N810_HEADSET_AMP_GPIO, 0);
- gpio_direction_output(N810_SPEAKER_AMP_GPIO, 0);
-
- return 0;
-err4:
- clk_put(sys_clkout2);
-err3:
- clk_put(sys_clkout2_src);
-err2:
- platform_device_del(n810_snd_device);
-err1:
- platform_device_put(n810_snd_device);
-
- return err;
-}
-
-static void __exit n810_soc_exit(void)
-{
- gpio_free(N810_SPEAKER_AMP_GPIO);
- gpio_free(N810_HEADSET_AMP_GPIO);
- clk_put(sys_clkout2_src);
- clk_put(sys_clkout2);
- clk_put(func96m_clk);
-
- platform_device_unregister(n810_snd_device);
-}
-
-module_init(n810_soc_init);
-module_exit(n810_soc_exit);
-
-MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>");
-MODULE_DESCRIPTION("ALSA SoC Nokia N810");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/omap/omap-abe-twl6040.c b/ANDROID_3.4.5/sound/soc/omap/omap-abe-twl6040.c
deleted file mode 100644
index 93bb8eee..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/omap-abe-twl6040.c
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * omap-abe-twl6040.c -- SoC audio for TI OMAP based boards with ABE and
- * twl6040 codec
- *
- * Author: Misael Lopez Cruz <misael.lopez@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/mfd/twl6040.h>
-#include <linux/platform_data/omap-abe-twl6040.h>
-#include <linux/module.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/jack.h>
-
-#include <asm/mach-types.h>
-#include <plat/hardware.h>
-#include <plat/mux.h>
-
-#include "omap-dmic.h"
-#include "omap-mcpdm.h"
-#include "omap-pcm.h"
-#include "../codecs/twl6040.h"
-
-static int omap_abe_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_card *card = codec->card;
- struct omap_abe_twl6040_data *pdata = dev_get_platdata(card->dev);
- int clk_id, freq;
- int ret;
-
- clk_id = twl6040_get_clk_id(rtd->codec);
- if (clk_id == TWL6040_SYSCLK_SEL_HPPLL)
- freq = pdata->mclk_freq;
- else if (clk_id == TWL6040_SYSCLK_SEL_LPPLL)
- freq = 32768;
- else
- return -EINVAL;
-
- /* set the codec mclk */
- ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, freq,
- SND_SOC_CLOCK_IN);
- if (ret) {
- printk(KERN_ERR "can't set codec system clock\n");
- return ret;
- }
- return ret;
-}
-
-static struct snd_soc_ops omap_abe_ops = {
- .hw_params = omap_abe_hw_params,
-};
-
-static int omap_abe_dmic_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
-
- ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_SYSCLK_PAD_CLKS,
- 19200000, SND_SOC_CLOCK_IN);
- if (ret < 0) {
- printk(KERN_ERR "can't set DMIC cpu system clock\n");
- return ret;
- }
- ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_ABE_DMIC_CLK, 2400000,
- SND_SOC_CLOCK_OUT);
- if (ret < 0) {
- printk(KERN_ERR "can't set DMIC output clock\n");
- return ret;
- }
- return 0;
-}
-
-static struct snd_soc_ops omap_abe_dmic_ops = {
- .hw_params = omap_abe_dmic_hw_params,
-};
-
-/* Headset jack */
-static struct snd_soc_jack hs_jack;
-
-/*Headset jack detection DAPM pins */
-static struct snd_soc_jack_pin hs_jack_pins[] = {
- {
- .pin = "Headset Mic",
- .mask = SND_JACK_MICROPHONE,
- },
- {
- .pin = "Headset Stereophone",
- .mask = SND_JACK_HEADPHONE,
- },
-};
-
-/* SDP4430 machine DAPM */
-static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
- /* Outputs */
- SND_SOC_DAPM_HP("Headset Stereophone", NULL),
- SND_SOC_DAPM_SPK("Earphone Spk", NULL),
- SND_SOC_DAPM_SPK("Ext Spk", NULL),
- SND_SOC_DAPM_LINE("Line Out", NULL),
- SND_SOC_DAPM_SPK("Vibrator", NULL),
-
- /* Inputs */
- SND_SOC_DAPM_MIC("Headset Mic", NULL),
- SND_SOC_DAPM_MIC("Main Handset Mic", NULL),
- SND_SOC_DAPM_MIC("Sub Handset Mic", NULL),
- SND_SOC_DAPM_LINE("Line In", NULL),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- /* Routings for outputs */
- {"Headset Stereophone", NULL, "HSOL"},
- {"Headset Stereophone", NULL, "HSOR"},
-
- {"Earphone Spk", NULL, "EP"},
-
- {"Ext Spk", NULL, "HFL"},
- {"Ext Spk", NULL, "HFR"},
-
- {"Line Out", NULL, "AUXL"},
- {"Line Out", NULL, "AUXR"},
-
- {"Vibrator", NULL, "VIBRAL"},
- {"Vibrator", NULL, "VIBRAR"},
-
- /* Routings for inputs */
- {"HSMIC", NULL, "Headset Mic"},
- {"Headset Mic", NULL, "Headset Mic Bias"},
-
- {"MAINMIC", NULL, "Main Handset Mic"},
- {"Main Handset Mic", NULL, "Main Mic Bias"},
-
- {"SUBMIC", NULL, "Sub Handset Mic"},
- {"Sub Handset Mic", NULL, "Main Mic Bias"},
-
- {"AFML", NULL, "Line In"},
- {"AFMR", NULL, "Line In"},
-};
-
-static inline void twl6040_disconnect_pin(struct snd_soc_dapm_context *dapm,
- int connected, char *pin)
-{
- if (!connected)
- snd_soc_dapm_disable_pin(dapm, pin);
-}
-
-static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_card *card = codec->card;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- struct omap_abe_twl6040_data *pdata = dev_get_platdata(card->dev);
- int hs_trim;
- int ret = 0;
-
- /* Disable not connected paths if not used */
- twl6040_disconnect_pin(dapm, pdata->has_hs, "Headset Stereophone");
- twl6040_disconnect_pin(dapm, pdata->has_hf, "Ext Spk");
- twl6040_disconnect_pin(dapm, pdata->has_ep, "Earphone Spk");
- twl6040_disconnect_pin(dapm, pdata->has_aux, "Line Out");
- twl6040_disconnect_pin(dapm, pdata->has_vibra, "Vinrator");
- twl6040_disconnect_pin(dapm, pdata->has_hsmic, "Headset Mic");
- twl6040_disconnect_pin(dapm, pdata->has_mainmic, "Main Handset Mic");
- twl6040_disconnect_pin(dapm, pdata->has_submic, "Sub Handset Mic");
- twl6040_disconnect_pin(dapm, pdata->has_afm, "Line In");
-
- /*
- * Configure McPDM offset cancellation based on the HSOTRIM value from
- * twl6040.
- */
- hs_trim = twl6040_get_trim_value(codec, TWL6040_TRIM_HSOTRIM);
- omap_mcpdm_configure_dn_offsets(rtd, TWL6040_HSF_TRIM_LEFT(hs_trim),
- TWL6040_HSF_TRIM_RIGHT(hs_trim));
-
- /* Headset jack detection only if it is supported */
- if (pdata->jack_detection) {
- ret = snd_soc_jack_new(codec, "Headset Jack",
- SND_JACK_HEADSET, &hs_jack);
- if (ret)
- return ret;
-
- ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
- hs_jack_pins);
- twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET);
- }
-
- return ret;
-}
-
-static const struct snd_soc_dapm_widget dmic_dapm_widgets[] = {
- SND_SOC_DAPM_MIC("Digital Mic", NULL),
-};
-
-static const struct snd_soc_dapm_route dmic_audio_map[] = {
- {"DMic", NULL, "Digital Mic"},
- {"Digital Mic", NULL, "Digital Mic1 Bias"},
-};
-
-static int omap_abe_dmic_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret;
-
- ret = snd_soc_dapm_new_controls(dapm, dmic_dapm_widgets,
- ARRAY_SIZE(dmic_dapm_widgets));
- if (ret)
- return ret;
-
- return snd_soc_dapm_add_routes(dapm, dmic_audio_map,
- ARRAY_SIZE(dmic_audio_map));
-}
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link twl6040_dmic_dai[] = {
- {
- .name = "TWL6040",
- .stream_name = "TWL6040",
- .cpu_dai_name = "omap-mcpdm",
- .codec_dai_name = "twl6040-legacy",
- .platform_name = "omap-pcm-audio",
- .codec_name = "twl6040-codec",
- .init = omap_abe_twl6040_init,
- .ops = &omap_abe_ops,
- },
- {
- .name = "DMIC",
- .stream_name = "DMIC Capture",
- .cpu_dai_name = "omap-dmic",
- .codec_dai_name = "dmic-hifi",
- .platform_name = "omap-pcm-audio",
- .codec_name = "dmic-codec",
- .init = omap_abe_dmic_init,
- .ops = &omap_abe_dmic_ops,
- },
-};
-
-static struct snd_soc_dai_link twl6040_only_dai[] = {
- {
- .name = "TWL6040",
- .stream_name = "TWL6040",
- .cpu_dai_name = "omap-mcpdm",
- .codec_dai_name = "twl6040-legacy",
- .platform_name = "omap-pcm-audio",
- .codec_name = "twl6040-codec",
- .init = omap_abe_twl6040_init,
- .ops = &omap_abe_ops,
- },
-};
-
-/* Audio machine driver */
-static struct snd_soc_card omap_abe_card = {
- .owner = THIS_MODULE,
-
- .dapm_widgets = twl6040_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets),
- .dapm_routes = audio_map,
- .num_dapm_routes = ARRAY_SIZE(audio_map),
-};
-
-static __devinit int omap_abe_probe(struct platform_device *pdev)
-{
- struct omap_abe_twl6040_data *pdata = dev_get_platdata(&pdev->dev);
- struct snd_soc_card *card = &omap_abe_card;
- int ret;
-
- card->dev = &pdev->dev;
-
- if (!pdata) {
- dev_err(&pdev->dev, "Missing pdata\n");
- return -ENODEV;
- }
-
- if (pdata->card_name) {
- card->name = pdata->card_name;
- } else {
- dev_err(&pdev->dev, "Card name is not provided\n");
- return -ENODEV;
- }
-
- if (!pdata->mclk_freq) {
- dev_err(&pdev->dev, "MCLK frequency missing\n");
- return -ENODEV;
- }
-
- if (pdata->has_dmic) {
- card->dai_link = twl6040_dmic_dai;
- card->num_links = ARRAY_SIZE(twl6040_dmic_dai);
- } else {
- card->dai_link = twl6040_only_dai;
- card->num_links = ARRAY_SIZE(twl6040_only_dai);
- }
-
- ret = snd_soc_register_card(card);
- if (ret)
- dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
- ret);
-
- return ret;
-}
-
-static int __devexit omap_abe_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- snd_soc_unregister_card(card);
-
- return 0;
-}
-
-static struct platform_driver omap_abe_driver = {
- .driver = {
- .name = "omap-abe-twl6040",
- .owner = THIS_MODULE,
- .pm = &snd_soc_pm_ops,
- },
- .probe = omap_abe_probe,
- .remove = __devexit_p(omap_abe_remove),
-};
-
-module_platform_driver(omap_abe_driver);
-
-MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
-MODULE_DESCRIPTION("ALSA SoC for OMAP boards with ABE and twl6040 codec");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:omap-abe-twl6040");
diff --git a/ANDROID_3.4.5/sound/soc/omap/omap-dmic.c b/ANDROID_3.4.5/sound/soc/omap/omap-dmic.c
deleted file mode 100644
index 4dcb5a7e..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/omap-dmic.c
+++ /dev/null
@@ -1,545 +0,0 @@
-/*
- * omap-dmic.c -- OMAP ASoC DMIC DAI driver
- *
- * Copyright (C) 2010 - 2011 Texas Instruments
- *
- * Author: David Lambert <dlambert@ti.com>
- * Misael Lopez Cruz <misael.lopez@ti.com>
- * Liam Girdwood <lrg@ti.com>
- * Peter Ujfalusi <peter.ujfalusi@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/pm_runtime.h>
-#include <plat/dma.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include "omap-pcm.h"
-#include "omap-dmic.h"
-
-struct omap_dmic {
- struct device *dev;
- void __iomem *io_base;
- struct clk *fclk;
- int fclk_freq;
- int out_freq;
- int clk_div;
- int sysclk;
- int threshold;
- u32 ch_enabled;
- bool active;
- struct mutex mutex;
-};
-
-/*
- * Stream DMA parameters
- */
-static struct omap_pcm_dma_data omap_dmic_dai_dma_params = {
- .name = "DMIC capture",
- .data_type = OMAP_DMA_DATA_TYPE_S32,
- .sync_mode = OMAP_DMA_SYNC_PACKET,
-};
-
-static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val)
-{
- __raw_writel(val, dmic->io_base + reg);
-}
-
-static inline int omap_dmic_read(struct omap_dmic *dmic, u16 reg)
-{
- return __raw_readl(dmic->io_base + reg);
-}
-
-static inline void omap_dmic_start(struct omap_dmic *dmic)
-{
- u32 ctrl = omap_dmic_read(dmic, OMAP_DMIC_CTRL_REG);
-
- /* Configure DMA controller */
- omap_dmic_write(dmic, OMAP_DMIC_DMAENABLE_SET_REG,
- OMAP_DMIC_DMA_ENABLE);
-
- omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG, ctrl | dmic->ch_enabled);
-}
-
-static inline void omap_dmic_stop(struct omap_dmic *dmic)
-{
- u32 ctrl = omap_dmic_read(dmic, OMAP_DMIC_CTRL_REG);
- omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG,
- ctrl & ~OMAP_DMIC_UP_ENABLE_MASK);
-
- /* Disable DMA request generation */
- omap_dmic_write(dmic, OMAP_DMIC_DMAENABLE_CLR_REG,
- OMAP_DMIC_DMA_ENABLE);
-
-}
-
-static inline int dmic_is_enabled(struct omap_dmic *dmic)
-{
- return omap_dmic_read(dmic, OMAP_DMIC_CTRL_REG) &
- OMAP_DMIC_UP_ENABLE_MASK;
-}
-
-static int omap_dmic_dai_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
- int ret = 0;
-
- mutex_lock(&dmic->mutex);
-
- if (!dai->active)
- dmic->active = 1;
- else
- ret = -EBUSY;
-
- mutex_unlock(&dmic->mutex);
-
- return ret;
-}
-
-static void omap_dmic_dai_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
-
- mutex_lock(&dmic->mutex);
-
- if (!dai->active)
- dmic->active = 0;
-
- mutex_unlock(&dmic->mutex);
-}
-
-static int omap_dmic_select_divider(struct omap_dmic *dmic, int sample_rate)
-{
- int divider = -EINVAL;
-
- /*
- * 192KHz rate is only supported with 19.2MHz/3.84MHz clock
- * configuration.
- */
- if (sample_rate == 192000) {
- if (dmic->fclk_freq == 19200000 && dmic->out_freq == 3840000)
- divider = 0x6; /* Divider: 5 (192KHz sampling rate) */
- else
- dev_err(dmic->dev,
- "invalid clock configuration for 192KHz\n");
-
- return divider;
- }
-
- switch (dmic->out_freq) {
- case 1536000:
- if (dmic->fclk_freq != 24576000)
- goto div_err;
- divider = 0x4; /* Divider: 16 */
- break;
- case 2400000:
- switch (dmic->fclk_freq) {
- case 12000000:
- divider = 0x5; /* Divider: 5 */
- break;
- case 19200000:
- divider = 0x0; /* Divider: 8 */
- break;
- case 24000000:
- divider = 0x2; /* Divider: 10 */
- break;
- default:
- goto div_err;
- }
- break;
- case 3072000:
- if (dmic->fclk_freq != 24576000)
- goto div_err;
- divider = 0x3; /* Divider: 8 */
- break;
- case 3840000:
- if (dmic->fclk_freq != 19200000)
- goto div_err;
- divider = 0x1; /* Divider: 5 (96KHz sampling rate) */
- break;
- default:
- dev_err(dmic->dev, "invalid out frequency: %dHz\n",
- dmic->out_freq);
- break;
- }
-
- return divider;
-
-div_err:
- dev_err(dmic->dev, "invalid out frequency %dHz for %dHz input\n",
- dmic->out_freq, dmic->fclk_freq);
- return -EINVAL;
-}
-
-static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
- int channels;
-
- dmic->clk_div = omap_dmic_select_divider(dmic, params_rate(params));
- if (dmic->clk_div < 0) {
- dev_err(dmic->dev, "no valid divider for %dHz from %dHz\n",
- dmic->out_freq, dmic->fclk_freq);
- return -EINVAL;
- }
-
- dmic->ch_enabled = 0;
- channels = params_channels(params);
- switch (channels) {
- case 6:
- dmic->ch_enabled |= OMAP_DMIC_UP3_ENABLE;
- case 4:
- dmic->ch_enabled |= OMAP_DMIC_UP2_ENABLE;
- case 2:
- dmic->ch_enabled |= OMAP_DMIC_UP1_ENABLE;
- break;
- default:
- dev_err(dmic->dev, "invalid number of legacy channels\n");
- return -EINVAL;
- }
-
- /* packet size is threshold * channels */
- omap_dmic_dai_dma_params.packet_size = dmic->threshold * channels;
- snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params);
-
- return 0;
-}
-
-static int omap_dmic_dai_prepare(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
- u32 ctrl;
-
- /* Configure uplink threshold */
- omap_dmic_write(dmic, OMAP_DMIC_FIFO_CTRL_REG, dmic->threshold);
-
- ctrl = omap_dmic_read(dmic, OMAP_DMIC_CTRL_REG);
-
- /* Set dmic out format */
- ctrl &= ~(OMAP_DMIC_FORMAT | OMAP_DMIC_POLAR_MASK);
- ctrl |= (OMAP_DMICOUTFORMAT_LJUST | OMAP_DMIC_POLAR1 |
- OMAP_DMIC_POLAR2 | OMAP_DMIC_POLAR3);
-
- /* Configure dmic clock divider */
- ctrl &= ~OMAP_DMIC_CLK_DIV_MASK;
- ctrl |= OMAP_DMIC_CLK_DIV(dmic->clk_div);
-
- omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG, ctrl);
-
- omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG,
- ctrl | OMAP_DMICOUTFORMAT_LJUST | OMAP_DMIC_POLAR1 |
- OMAP_DMIC_POLAR2 | OMAP_DMIC_POLAR3);
-
- return 0;
-}
-
-static int omap_dmic_dai_trigger(struct snd_pcm_substream *substream,
- int cmd, struct snd_soc_dai *dai)
-{
- struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- omap_dmic_start(dmic);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- omap_dmic_stop(dmic);
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-static int omap_dmic_select_fclk(struct omap_dmic *dmic, int clk_id,
- unsigned int freq)
-{
- struct clk *parent_clk;
- char *parent_clk_name;
- int ret = 0;
-
- switch (freq) {
- case 12000000:
- case 19200000:
- case 24000000:
- case 24576000:
- break;
- default:
- dev_err(dmic->dev, "invalid input frequency: %dHz\n", freq);
- dmic->fclk_freq = 0;
- return -EINVAL;
- }
-
- if (dmic->sysclk == clk_id) {
- dmic->fclk_freq = freq;
- return 0;
- }
-
- /* re-parent not allowed if a stream is ongoing */
- if (dmic->active && dmic_is_enabled(dmic)) {
- dev_err(dmic->dev, "can't re-parent when DMIC active\n");
- return -EBUSY;
- }
-
- switch (clk_id) {
- case OMAP_DMIC_SYSCLK_PAD_CLKS:
- parent_clk_name = "pad_clks_ck";
- break;
- case OMAP_DMIC_SYSCLK_SLIMBLUS_CLKS:
- parent_clk_name = "slimbus_clk";
- break;
- case OMAP_DMIC_SYSCLK_SYNC_MUX_CLKS:
- parent_clk_name = "dmic_sync_mux_ck";
- break;
- default:
- dev_err(dmic->dev, "fclk clk_id (%d) not supported\n", clk_id);
- return -EINVAL;
- }
-
- parent_clk = clk_get(dmic->dev, parent_clk_name);
- if (IS_ERR(parent_clk)) {
- dev_err(dmic->dev, "can't get %s\n", parent_clk_name);
- return -ENODEV;
- }
-
- mutex_lock(&dmic->mutex);
- if (dmic->active) {
- /* disable clock while reparenting */
- pm_runtime_put_sync(dmic->dev);
- ret = clk_set_parent(dmic->fclk, parent_clk);
- pm_runtime_get_sync(dmic->dev);
- } else {
- ret = clk_set_parent(dmic->fclk, parent_clk);
- }
- mutex_unlock(&dmic->mutex);
-
- if (ret < 0) {
- dev_err(dmic->dev, "re-parent failed\n");
- goto err_busy;
- }
-
- dmic->sysclk = clk_id;
- dmic->fclk_freq = freq;
-
-err_busy:
- clk_put(parent_clk);
-
- return ret;
-}
-
-static int omap_dmic_select_outclk(struct omap_dmic *dmic, int clk_id,
- unsigned int freq)
-{
- int ret = 0;
-
- if (clk_id != OMAP_DMIC_ABE_DMIC_CLK) {
- dev_err(dmic->dev, "output clk_id (%d) not supported\n",
- clk_id);
- return -EINVAL;
- }
-
- switch (freq) {
- case 1536000:
- case 2400000:
- case 3072000:
- case 3840000:
- dmic->out_freq = freq;
- break;
- default:
- dev_err(dmic->dev, "invalid out frequency: %dHz\n", freq);
- dmic->out_freq = 0;
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int omap_dmic_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
- unsigned int freq, int dir)
-{
- struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
-
- if (dir == SND_SOC_CLOCK_IN)
- return omap_dmic_select_fclk(dmic, clk_id, freq);
- else if (dir == SND_SOC_CLOCK_OUT)
- return omap_dmic_select_outclk(dmic, clk_id, freq);
-
- dev_err(dmic->dev, "invalid clock direction (%d)\n", dir);
- return -EINVAL;
-}
-
-static const struct snd_soc_dai_ops omap_dmic_dai_ops = {
- .startup = omap_dmic_dai_startup,
- .shutdown = omap_dmic_dai_shutdown,
- .hw_params = omap_dmic_dai_hw_params,
- .prepare = omap_dmic_dai_prepare,
- .trigger = omap_dmic_dai_trigger,
- .set_sysclk = omap_dmic_set_dai_sysclk,
-};
-
-static int omap_dmic_probe(struct snd_soc_dai *dai)
-{
- struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
-
- pm_runtime_enable(dmic->dev);
-
- /* Disable lines while request is ongoing */
- pm_runtime_get_sync(dmic->dev);
- omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG, 0x00);
- pm_runtime_put_sync(dmic->dev);
-
- /* Configure DMIC threshold value */
- dmic->threshold = OMAP_DMIC_THRES_MAX - 3;
- return 0;
-}
-
-static int omap_dmic_remove(struct snd_soc_dai *dai)
-{
- struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
-
- pm_runtime_disable(dmic->dev);
-
- return 0;
-}
-
-static struct snd_soc_dai_driver omap_dmic_dai = {
- .name = "omap-dmic",
- .probe = omap_dmic_probe,
- .remove = omap_dmic_remove,
- .capture = {
- .channels_min = 2,
- .channels_max = 6,
- .rates = SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .sig_bits = 24,
- },
- .ops = &omap_dmic_dai_ops,
-};
-
-static __devinit int asoc_dmic_probe(struct platform_device *pdev)
-{
- struct omap_dmic *dmic;
- struct resource *res;
- int ret;
-
- dmic = devm_kzalloc(&pdev->dev, sizeof(struct omap_dmic), GFP_KERNEL);
- if (!dmic)
- return -ENOMEM;
-
- platform_set_drvdata(pdev, dmic);
- dmic->dev = &pdev->dev;
- dmic->sysclk = OMAP_DMIC_SYSCLK_SYNC_MUX_CLKS;
-
- mutex_init(&dmic->mutex);
-
- dmic->fclk = clk_get(dmic->dev, "dmic_fck");
- if (IS_ERR(dmic->fclk)) {
- dev_err(dmic->dev, "cant get dmic_fck\n");
- return -ENODEV;
- }
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma");
- if (!res) {
- dev_err(dmic->dev, "invalid dma memory resource\n");
- ret = -ENODEV;
- goto err_put_clk;
- }
- omap_dmic_dai_dma_params.port_addr = res->start + OMAP_DMIC_DATA_REG;
-
- res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!res) {
- dev_err(dmic->dev, "invalid dma resource\n");
- ret = -ENODEV;
- goto err_put_clk;
- }
- omap_dmic_dai_dma_params.dma_req = res->start;
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
- if (!res) {
- dev_err(dmic->dev, "invalid memory resource\n");
- ret = -ENODEV;
- goto err_put_clk;
- }
-
- if (!devm_request_mem_region(&pdev->dev, res->start,
- resource_size(res), pdev->name)) {
- dev_err(dmic->dev, "memory region already claimed\n");
- ret = -ENODEV;
- goto err_put_clk;
- }
-
- dmic->io_base = devm_ioremap(&pdev->dev, res->start,
- resource_size(res));
- if (!dmic->io_base) {
- ret = -ENOMEM;
- goto err_put_clk;
- }
-
- ret = snd_soc_register_dai(&pdev->dev, &omap_dmic_dai);
- if (ret)
- goto err_put_clk;
-
- return 0;
-
-err_put_clk:
- clk_put(dmic->fclk);
- return ret;
-}
-
-static int __devexit asoc_dmic_remove(struct platform_device *pdev)
-{
- struct omap_dmic *dmic = platform_get_drvdata(pdev);
-
- snd_soc_unregister_dai(&pdev->dev);
- clk_put(dmic->fclk);
-
- return 0;
-}
-
-static struct platform_driver asoc_dmic_driver = {
- .driver = {
- .name = "omap-dmic",
- .owner = THIS_MODULE,
- },
- .probe = asoc_dmic_probe,
- .remove = __devexit_p(asoc_dmic_remove),
-};
-
-module_platform_driver(asoc_dmic_driver);
-
-MODULE_ALIAS("platform:omap-dmic");
-MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
-MODULE_DESCRIPTION("OMAP DMIC ASoC Interface");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/omap/omap-dmic.h b/ANDROID_3.4.5/sound/soc/omap/omap-dmic.h
deleted file mode 100644
index 231e728b..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/omap-dmic.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * omap-dmic.h -- OMAP Digital Microphone Controller
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _OMAP_DMIC_H
-#define _OMAP_DMIC_H
-
-#define OMAP_DMIC_REVISION_REG 0x00
-#define OMAP_DMIC_SYSCONFIG_REG 0x10
-#define OMAP_DMIC_IRQSTATUS_RAW_REG 0x24
-#define OMAP_DMIC_IRQSTATUS_REG 0x28
-#define OMAP_DMIC_IRQENABLE_SET_REG 0x2C
-#define OMAP_DMIC_IRQENABLE_CLR_REG 0x30
-#define OMAP_DMIC_IRQWAKE_EN_REG 0x34
-#define OMAP_DMIC_DMAENABLE_SET_REG 0x38
-#define OMAP_DMIC_DMAENABLE_CLR_REG 0x3C
-#define OMAP_DMIC_DMAWAKEEN_REG 0x40
-#define OMAP_DMIC_CTRL_REG 0x44
-#define OMAP_DMIC_DATA_REG 0x48
-#define OMAP_DMIC_FIFO_CTRL_REG 0x4C
-#define OMAP_DMIC_FIFO_DMIC1R_DATA_REG 0x50
-#define OMAP_DMIC_FIFO_DMIC1L_DATA_REG 0x54
-#define OMAP_DMIC_FIFO_DMIC2R_DATA_REG 0x58
-#define OMAP_DMIC_FIFO_DMIC2L_DATA_REG 0x5C
-#define OMAP_DMIC_FIFO_DMIC3R_DATA_REG 0x60
-#define OMAP_DMIC_FIFO_DMIC3L_DATA_REG 0x64
-
-/* IRQSTATUS_RAW, IRQSTATUS, IRQENABLE_SET, IRQENABLE_CLR bit fields */
-#define OMAP_DMIC_IRQ (1 << 0)
-#define OMAP_DMIC_IRQ_FULL (1 << 1)
-#define OMAP_DMIC_IRQ_ALMST_EMPTY (1 << 2)
-#define OMAP_DMIC_IRQ_EMPTY (1 << 3)
-#define OMAP_DMIC_IRQ_MASK 0x07
-
-/* DMIC_DMAENABLE bit fields */
-#define OMAP_DMIC_DMA_ENABLE 0x1
-
-/* DMIC_CTRL bit fields */
-#define OMAP_DMIC_UP1_ENABLE (1 << 0)
-#define OMAP_DMIC_UP2_ENABLE (1 << 1)
-#define OMAP_DMIC_UP3_ENABLE (1 << 2)
-#define OMAP_DMIC_UP_ENABLE_MASK 0x7
-#define OMAP_DMIC_FORMAT (1 << 3)
-#define OMAP_DMIC_POLAR1 (1 << 4)
-#define OMAP_DMIC_POLAR2 (1 << 5)
-#define OMAP_DMIC_POLAR3 (1 << 6)
-#define OMAP_DMIC_POLAR_MASK (0x7 << 4)
-#define OMAP_DMIC_CLK_DIV(x) (((x) & 0x7) << 7)
-#define OMAP_DMIC_CLK_DIV_MASK (0x7 << 7)
-#define OMAP_DMIC_RESET (1 << 10)
-
-#define OMAP_DMICOUTFORMAT_LJUST (0 << 3)
-#define OMAP_DMICOUTFORMAT_RJUST (1 << 3)
-
-/* DMIC_FIFO_CTRL bit fields */
-#define OMAP_DMIC_THRES_MAX 0xF
-
-enum omap_dmic_clk {
- OMAP_DMIC_SYSCLK_PAD_CLKS, /* PAD_CLKS */
- OMAP_DMIC_SYSCLK_SLIMBLUS_CLKS, /* SLIMBUS_CLK */
- OMAP_DMIC_SYSCLK_SYNC_MUX_CLKS, /* DMIC_SYNC_MUX_CLK */
- OMAP_DMIC_ABE_DMIC_CLK, /* abe_dmic_clk */
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/omap/omap-hdmi.c b/ANDROID_3.4.5/sound/soc/omap/omap-hdmi.c
deleted file mode 100644
index 38e0defa..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/omap-hdmi.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * omap-hdmi.c
- *
- * OMAP ALSA SoC DAI driver for HDMI audio on OMAP4 processors.
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
- * Authors: Jorge Candelaria <jorge.candelaria@ti.com>
- * Ricardo Neri <ricardo.neri@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include <plat/dma.h>
-#include "omap-pcm.h"
-#include "omap-hdmi.h"
-
-#define DRV_NAME "hdmi-audio-dai"
-
-static struct omap_pcm_dma_data omap_hdmi_dai_dma_params = {
- .name = "HDMI playback",
- .sync_mode = OMAP_DMA_SYNC_PACKET,
-};
-
-static int omap_hdmi_dai_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- int err;
- /*
- * Make sure that the period bytes are multiple of the DMA packet size.
- * Largest packet size we use is 32 32-bit words = 128 bytes
- */
- err = snd_pcm_hw_constraint_step(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 128);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static int omap_hdmi_dai_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- int err = 0;
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- omap_hdmi_dai_dma_params.packet_size = 16;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- omap_hdmi_dai_dma_params.packet_size = 32;
- break;
- default:
- err = -EINVAL;
- }
-
- omap_hdmi_dai_dma_params.data_type = OMAP_DMA_DATA_TYPE_S32;
-
- snd_soc_dai_set_dma_data(dai, substream,
- &omap_hdmi_dai_dma_params);
-
- return err;
-}
-
-static const struct snd_soc_dai_ops omap_hdmi_dai_ops = {
- .startup = omap_hdmi_dai_startup,
- .hw_params = omap_hdmi_dai_hw_params,
-};
-
-static struct snd_soc_dai_driver omap_hdmi_dai = {
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = OMAP_HDMI_RATES,
- .formats = OMAP_HDMI_FORMATS,
- },
- .ops = &omap_hdmi_dai_ops,
-};
-
-static __devinit int omap_hdmi_probe(struct platform_device *pdev)
-{
- int ret;
- struct resource *hdmi_rsrc;
-
- hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!hdmi_rsrc) {
- dev_err(&pdev->dev, "Cannot obtain IORESOURCE_MEM HDMI\n");
- return -EINVAL;
- }
-
- omap_hdmi_dai_dma_params.port_addr = hdmi_rsrc->start
- + OMAP_HDMI_AUDIO_DMA_PORT;
-
- hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!hdmi_rsrc) {
- dev_err(&pdev->dev, "Cannot obtain IORESOURCE_DMA HDMI\n");
- return -EINVAL;
- }
-
- omap_hdmi_dai_dma_params.dma_req = hdmi_rsrc->start;
-
- ret = snd_soc_register_dai(&pdev->dev, &omap_hdmi_dai);
- return ret;
-}
-
-static int __devexit omap_hdmi_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_dai(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver hdmi_dai_driver = {
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- },
- .probe = omap_hdmi_probe,
- .remove = __devexit_p(omap_hdmi_remove),
-};
-
-module_platform_driver(hdmi_dai_driver);
-
-MODULE_AUTHOR("Jorge Candelaria <jorge.candelaria@ti.com>");
-MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>");
-MODULE_DESCRIPTION("OMAP HDMI SoC Interface");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/ANDROID_3.4.5/sound/soc/omap/omap-hdmi.h b/ANDROID_3.4.5/sound/soc/omap/omap-hdmi.h
deleted file mode 100644
index 34c298d5..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/omap-hdmi.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * omap-hdmi.h
- *
- * Definitions for OMAP ALSA SoC DAI driver for HDMI audio on OMAP4 processors.
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
- * Authors: Jorge Candelaria <jorge.candelaria@ti.com>
- * Ricardo Neri <ricardo.neri@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __OMAP_HDMI_H__
-#define __OMAP_HDMI_H__
-
-#define OMAP_HDMI_AUDIO_DMA_PORT 0x8c
-
-#define OMAP_HDMI_RATES (SNDRV_PCM_RATE_32000 | \
- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
-
-#define OMAP_HDMI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
- SNDRV_PCM_FMTBIT_S24_LE)
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/omap/omap-mcbsp.c b/ANDROID_3.4.5/sound/soc/omap/omap-mcbsp.c
deleted file mode 100644
index 6912ac7c..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/omap-mcbsp.c
+++ /dev/null
@@ -1,817 +0,0 @@
-/*
- * omap-mcbsp.c -- OMAP ALSA SoC DAI driver using McBSP port
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
- * Peter Ujfalusi <peter.ujfalusi@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/pm_runtime.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include <plat/dma.h>
-#include <plat/mcbsp.h>
-#include "mcbsp.h"
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-
-#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000)
-
-#define OMAP_MCBSP_SOC_SINGLE_S16_EXT(xname, xmin, xmax, \
- xhandler_get, xhandler_put) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = omap_mcbsp_st_info_volsw, \
- .get = xhandler_get, .put = xhandler_put, \
- .private_value = (unsigned long) &(struct soc_mixer_control) \
- {.min = xmin, .max = xmax} }
-
-enum {
- OMAP_MCBSP_WORD_8 = 0,
- OMAP_MCBSP_WORD_12,
- OMAP_MCBSP_WORD_16,
- OMAP_MCBSP_WORD_20,
- OMAP_MCBSP_WORD_24,
- OMAP_MCBSP_WORD_32,
-};
-
-/*
- * Stream DMA parameters. DMA request line and port address are set runtime
- * since they are different between OMAP1 and later OMAPs
- */
-static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
- struct omap_pcm_dma_data *dma_data;
- int words;
-
- dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
- /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
- if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD)
- /*
- * Configure McBSP threshold based on either:
- * packet_size, when the sDMA is in packet mode, or
- * based on the period size.
- */
- if (dma_data->packet_size)
- words = dma_data->packet_size;
- else
- words = snd_pcm_lib_period_bytes(substream) /
- (mcbsp->wlen / 8);
- else
- words = 1;
-
- /* Configure McBSP internal buffer usage */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- omap_mcbsp_set_tx_threshold(mcbsp, words);
- else
- omap_mcbsp_set_rx_threshold(mcbsp, words);
-}
-
-static int omap_mcbsp_hwrule_min_buffersize(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_interval *buffer_size = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE);
- struct snd_interval *channels = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_CHANNELS);
- struct omap_mcbsp *mcbsp = rule->private;
- struct snd_interval frames;
- int size;
-
- snd_interval_any(&frames);
- size = mcbsp->pdata->buffer_size;
-
- frames.min = size / channels->min;
- frames.integer = 1;
- return snd_interval_refine(buffer_size, &frames);
-}
-
-static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *cpu_dai)
-{
- struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
- int err = 0;
-
- if (!cpu_dai->active)
- err = omap_mcbsp_request(mcbsp);
-
- /*
- * OMAP3 McBSP FIFO is word structured.
- * McBSP2 has 1024 + 256 = 1280 word long buffer,
- * McBSP1,3,4,5 has 128 word long buffer
- * This means that the size of the FIFO depends on the sample format.
- * For example on McBSP3:
- * 16bit samples: size is 128 * 2 = 256 bytes
- * 32bit samples: size is 128 * 4 = 512 bytes
- * It is simpler to place constraint for buffer and period based on
- * channels.
- * McBSP3 as example again (16 or 32 bit samples):
- * 1 channel (mono): size is 128 frames (128 words)
- * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words)
- * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words)
- */
- if (mcbsp->pdata->buffer_size) {
- /*
- * Rule for the buffer size. We should not allow
- * smaller buffer than the FIFO size to avoid underruns
- */
- snd_pcm_hw_rule_add(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
- omap_mcbsp_hwrule_min_buffersize,
- mcbsp,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
-
- /* Make sure, that the period size is always even */
- snd_pcm_hw_constraint_step(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2);
- }
-
- return err;
-}
-
-static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *cpu_dai)
-{
- struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
-
- if (!cpu_dai->active) {
- omap_mcbsp_free(mcbsp);
- mcbsp->configured = 0;
- }
-}
-
-static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *cpu_dai)
-{
- struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
- int err = 0, play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- mcbsp->active++;
- omap_mcbsp_start(mcbsp, play, !play);
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- omap_mcbsp_stop(mcbsp, play, !play);
- mcbsp->active--;
- break;
- default:
- err = -EINVAL;
- }
-
- return err;
-}
-
-static snd_pcm_sframes_t omap_mcbsp_dai_delay(
- struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
- u16 fifo_use;
- snd_pcm_sframes_t delay;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- fifo_use = omap_mcbsp_get_tx_delay(mcbsp);
- else
- fifo_use = omap_mcbsp_get_rx_delay(mcbsp);
-
- /*
- * Divide the used locations with the channel count to get the
- * FIFO usage in samples (don't care about partial samples in the
- * buffer).
- */
- delay = fifo_use / substream->runtime->channels;
-
- return delay;
-}
-
-static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *cpu_dai)
-{
- struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
- struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs;
- struct omap_pcm_dma_data *dma_data;
- int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT;
- int pkt_size = 0;
- unsigned int format, div, framesize, master;
-
- dma_data = &mcbsp->dma_data[substream->stream];
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- dma_data->data_type = OMAP_DMA_DATA_TYPE_S16;
- wlen = 16;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- dma_data->data_type = OMAP_DMA_DATA_TYPE_S32;
- wlen = 32;
- break;
- default:
- return -EINVAL;
- }
- if (mcbsp->pdata->buffer_size) {
- dma_data->set_threshold = omap_mcbsp_set_threshold;
- /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
- if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
- int period_words, max_thrsh;
-
- period_words = params_period_bytes(params) / (wlen / 8);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- max_thrsh = mcbsp->max_tx_thres;
- else
- max_thrsh = mcbsp->max_rx_thres;
- /*
- * If the period contains less or equal number of words,
- * we are using the original threshold mode setup:
- * McBSP threshold = sDMA frame size = period_size
- * Otherwise we switch to sDMA packet mode:
- * McBSP threshold = sDMA packet size
- * sDMA frame size = period size
- */
- if (period_words > max_thrsh) {
- int divider = 0;
-
- /*
- * Look for the biggest threshold value, which
- * divides the period size evenly.
- */
- divider = period_words / max_thrsh;
- if (period_words % max_thrsh)
- divider++;
- while (period_words % divider &&
- divider < period_words)
- divider++;
- if (divider == period_words)
- return -EINVAL;
-
- pkt_size = period_words / divider;
- sync_mode = OMAP_DMA_SYNC_PACKET;
- } else {
- sync_mode = OMAP_DMA_SYNC_FRAME;
- }
- }
- }
-
- dma_data->sync_mode = sync_mode;
- dma_data->packet_size = pkt_size;
-
- snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
-
- if (mcbsp->configured) {
- /* McBSP already configured by another stream */
- return 0;
- }
-
- regs->rcr2 &= ~(RPHASE | RFRLEN2(0x7f) | RWDLEN2(7));
- regs->xcr2 &= ~(RPHASE | XFRLEN2(0x7f) | XWDLEN2(7));
- regs->rcr1 &= ~(RFRLEN1(0x7f) | RWDLEN1(7));
- regs->xcr1 &= ~(XFRLEN1(0x7f) | XWDLEN1(7));
- format = mcbsp->fmt & SND_SOC_DAIFMT_FORMAT_MASK;
- wpf = channels = params_channels(params);
- if (channels == 2 && (format == SND_SOC_DAIFMT_I2S ||
- format == SND_SOC_DAIFMT_LEFT_J)) {
- /* Use dual-phase frames */
- regs->rcr2 |= RPHASE;
- regs->xcr2 |= XPHASE;
- /* Set 1 word per (McBSP) frame for phase1 and phase2 */
- wpf--;
- regs->rcr2 |= RFRLEN2(wpf - 1);
- regs->xcr2 |= XFRLEN2(wpf - 1);
- }
-
- regs->rcr1 |= RFRLEN1(wpf - 1);
- regs->xcr1 |= XFRLEN1(wpf - 1);
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- /* Set word lengths */
- regs->rcr2 |= RWDLEN2(OMAP_MCBSP_WORD_16);
- regs->rcr1 |= RWDLEN1(OMAP_MCBSP_WORD_16);
- regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_16);
- regs->xcr1 |= XWDLEN1(OMAP_MCBSP_WORD_16);
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- /* Set word lengths */
- regs->rcr2 |= RWDLEN2(OMAP_MCBSP_WORD_32);
- regs->rcr1 |= RWDLEN1(OMAP_MCBSP_WORD_32);
- regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_32);
- regs->xcr1 |= XWDLEN1(OMAP_MCBSP_WORD_32);
- break;
- default:
- /* Unsupported PCM format */
- return -EINVAL;
- }
-
- /* In McBSP master modes, FRAME (i.e. sample rate) is generated
- * by _counting_ BCLKs. Calculate frame size in BCLKs */
- master = mcbsp->fmt & SND_SOC_DAIFMT_MASTER_MASK;
- if (master == SND_SOC_DAIFMT_CBS_CFS) {
- div = mcbsp->clk_div ? mcbsp->clk_div : 1;
- framesize = (mcbsp->in_freq / div) / params_rate(params);
-
- if (framesize < wlen * channels) {
- printk(KERN_ERR "%s: not enough bandwidth for desired rate and "
- "channels\n", __func__);
- return -EINVAL;
- }
- } else
- framesize = wlen * channels;
-
- /* Set FS period and length in terms of bit clock periods */
- regs->srgr2 &= ~FPER(0xfff);
- regs->srgr1 &= ~FWID(0xff);
- switch (format) {
- case SND_SOC_DAIFMT_I2S:
- case SND_SOC_DAIFMT_LEFT_J:
- regs->srgr2 |= FPER(framesize - 1);
- regs->srgr1 |= FWID((framesize >> 1) - 1);
- break;
- case SND_SOC_DAIFMT_DSP_A:
- case SND_SOC_DAIFMT_DSP_B:
- regs->srgr2 |= FPER(framesize - 1);
- regs->srgr1 |= FWID(0);
- break;
- }
-
- omap_mcbsp_config(mcbsp, &mcbsp->cfg_regs);
- mcbsp->wlen = wlen;
- mcbsp->configured = 1;
-
- return 0;
-}
-
-/*
- * This must be called before _set_clkdiv and _set_sysclk since McBSP register
- * cache is initialized here
- */
-static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
- unsigned int fmt)
-{
- struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
- struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs;
- bool inv_fs = false;
-
- if (mcbsp->configured)
- return 0;
-
- mcbsp->fmt = fmt;
- memset(regs, 0, sizeof(*regs));
- /* Generic McBSP register settings */
- regs->spcr2 |= XINTM(3) | FREE;
- regs->spcr1 |= RINTM(3);
- /* RFIG and XFIG are not defined in 34xx */
- if (!cpu_is_omap34xx() && !cpu_is_omap44xx()) {
- regs->rcr2 |= RFIG;
- regs->xcr2 |= XFIG;
- }
- if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
- regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE;
- regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- /* 1-bit data delay */
- regs->rcr2 |= RDATDLY(1);
- regs->xcr2 |= XDATDLY(1);
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- /* 0-bit data delay */
- regs->rcr2 |= RDATDLY(0);
- regs->xcr2 |= XDATDLY(0);
- regs->spcr1 |= RJUST(2);
- /* Invert FS polarity configuration */
- inv_fs = true;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- /* 1-bit data delay */
- regs->rcr2 |= RDATDLY(1);
- regs->xcr2 |= XDATDLY(1);
- /* Invert FS polarity configuration */
- inv_fs = true;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- /* 0-bit data delay */
- regs->rcr2 |= RDATDLY(0);
- regs->xcr2 |= XDATDLY(0);
- /* Invert FS polarity configuration */
- inv_fs = true;
- break;
- default:
- /* Unsupported data format */
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- /* McBSP master. Set FS and bit clocks as outputs */
- regs->pcr0 |= FSXM | FSRM |
- CLKXM | CLKRM;
- /* Sample rate generator drives the FS */
- regs->srgr2 |= FSGM;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- /* McBSP slave */
- break;
- default:
- /* Unsupported master/slave configuration */
- return -EINVAL;
- }
-
- /* Set bit clock (CLKX/CLKR) and FS polarities */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- /*
- * Normal BCLK + FS.
- * FS active low. TX data driven on falling edge of bit clock
- * and RX data sampled on rising edge of bit clock.
- */
- regs->pcr0 |= FSXP | FSRP |
- CLKXP | CLKRP;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- regs->pcr0 |= CLKXP | CLKRP;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- regs->pcr0 |= FSXP | FSRP;
- break;
- case SND_SOC_DAIFMT_IB_IF:
- break;
- default:
- return -EINVAL;
- }
- if (inv_fs == true)
- regs->pcr0 ^= FSXP | FSRP;
-
- return 0;
-}
-
-static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_dai *cpu_dai,
- int div_id, int div)
-{
- struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
- struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs;
-
- if (div_id != OMAP_MCBSP_CLKGDV)
- return -ENODEV;
-
- mcbsp->clk_div = div;
- regs->srgr1 &= ~CLKGDV(0xff);
- regs->srgr1 |= CLKGDV(div - 1);
-
- return 0;
-}
-
-static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
- int clk_id, unsigned int freq,
- int dir)
-{
- struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
- struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs;
- int err = 0;
-
- if (mcbsp->active) {
- if (freq == mcbsp->in_freq)
- return 0;
- else
- return -EBUSY;
- }
-
- if (clk_id == OMAP_MCBSP_SYSCLK_CLK ||
- clk_id == OMAP_MCBSP_SYSCLK_CLKS_FCLK ||
- clk_id == OMAP_MCBSP_SYSCLK_CLKS_EXT ||
- clk_id == OMAP_MCBSP_SYSCLK_CLKX_EXT ||
- clk_id == OMAP_MCBSP_SYSCLK_CLKR_EXT) {
- mcbsp->in_freq = freq;
- regs->srgr2 &= ~CLKSM;
- regs->pcr0 &= ~SCLKME;
- } else if (cpu_class_is_omap1()) {
- /*
- * McBSP CLKR/FSR signal muxing functions are only available on
- * OMAP2 or newer versions
- */
- return -EINVAL;
- }
-
- switch (clk_id) {
- case OMAP_MCBSP_SYSCLK_CLK:
- regs->srgr2 |= CLKSM;
- break;
- case OMAP_MCBSP_SYSCLK_CLKS_FCLK:
- if (cpu_class_is_omap1()) {
- err = -EINVAL;
- break;
- }
- err = omap2_mcbsp_set_clks_src(mcbsp,
- MCBSP_CLKS_PRCM_SRC);
- break;
- case OMAP_MCBSP_SYSCLK_CLKS_EXT:
- if (cpu_class_is_omap1()) {
- err = 0;
- break;
- }
- err = omap2_mcbsp_set_clks_src(mcbsp,
- MCBSP_CLKS_PAD_SRC);
- break;
-
- case OMAP_MCBSP_SYSCLK_CLKX_EXT:
- regs->srgr2 |= CLKSM;
- case OMAP_MCBSP_SYSCLK_CLKR_EXT:
- regs->pcr0 |= SCLKME;
- break;
-
-
- case OMAP_MCBSP_CLKR_SRC_CLKR:
- err = omap_mcbsp_6pin_src_mux(mcbsp, CLKR_SRC_CLKR);
- break;
- case OMAP_MCBSP_CLKR_SRC_CLKX:
- err = omap_mcbsp_6pin_src_mux(mcbsp, CLKR_SRC_CLKX);
- break;
- case OMAP_MCBSP_FSR_SRC_FSR:
- err = omap_mcbsp_6pin_src_mux(mcbsp, FSR_SRC_FSR);
- break;
- case OMAP_MCBSP_FSR_SRC_FSX:
- err = omap_mcbsp_6pin_src_mux(mcbsp, FSR_SRC_FSX);
- break;
- default:
- err = -ENODEV;
- }
-
- return err;
-}
-
-static const struct snd_soc_dai_ops mcbsp_dai_ops = {
- .startup = omap_mcbsp_dai_startup,
- .shutdown = omap_mcbsp_dai_shutdown,
- .trigger = omap_mcbsp_dai_trigger,
- .delay = omap_mcbsp_dai_delay,
- .hw_params = omap_mcbsp_dai_hw_params,
- .set_fmt = omap_mcbsp_dai_set_dai_fmt,
- .set_clkdiv = omap_mcbsp_dai_set_clkdiv,
- .set_sysclk = omap_mcbsp_dai_set_dai_sysclk,
-};
-
-static int omap_mcbsp_probe(struct snd_soc_dai *dai)
-{
- struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(dai);
-
- pm_runtime_enable(mcbsp->dev);
-
- return 0;
-}
-
-static int omap_mcbsp_remove(struct snd_soc_dai *dai)
-{
- struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(dai);
-
- pm_runtime_disable(mcbsp->dev);
-
- return 0;
-}
-
-static struct snd_soc_dai_driver omap_mcbsp_dai = {
- .probe = omap_mcbsp_probe,
- .remove = omap_mcbsp_remove,
- .playback = {
- .channels_min = 1,
- .channels_max = 16,
- .rates = OMAP_MCBSP_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
- },
- .capture = {
- .channels_min = 1,
- .channels_max = 16,
- .rates = OMAP_MCBSP_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
- },
- .ops = &mcbsp_dai_ops,
-};
-
-static int omap_mcbsp_st_info_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- int max = mc->max;
- int min = mc->min;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = min;
- uinfo->value.integer.max = max;
- return 0;
-}
-
-#define OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(channel) \
-static int \
-omap_mcbsp_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \
- struct snd_ctl_elem_value *uc) \
-{ \
- struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \
- struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); \
- struct soc_mixer_control *mc = \
- (struct soc_mixer_control *)kc->private_value; \
- int max = mc->max; \
- int min = mc->min; \
- int val = uc->value.integer.value[0]; \
- \
- if (val < min || val > max) \
- return -EINVAL; \
- \
- /* OMAP McBSP implementation uses index values 0..4 */ \
- return omap_st_set_chgain(mcbsp, channel, val); \
-}
-
-#define OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(channel) \
-static int \
-omap_mcbsp_get_st_ch##channel##_volume(struct snd_kcontrol *kc, \
- struct snd_ctl_elem_value *uc) \
-{ \
- struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \
- struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); \
- s16 chgain; \
- \
- if (omap_st_get_chgain(mcbsp, channel, &chgain)) \
- return -EAGAIN; \
- \
- uc->value.integer.value[0] = chgain; \
- return 0; \
-}
-
-OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(0)
-OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(1)
-OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(0)
-OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(1)
-
-static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
- struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
- u8 value = ucontrol->value.integer.value[0];
-
- if (value == omap_st_is_enabled(mcbsp))
- return 0;
-
- if (value)
- omap_st_enable(mcbsp);
- else
- omap_st_disable(mcbsp);
-
- return 1;
-}
-
-static int omap_mcbsp_st_get_mode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
- struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
-
- ucontrol->value.integer.value[0] = omap_st_is_enabled(mcbsp);
- return 0;
-}
-
-static const struct snd_kcontrol_new omap_mcbsp2_st_controls[] = {
- SOC_SINGLE_EXT("McBSP2 Sidetone Switch", 1, 0, 1, 0,
- omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode),
- OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 0 Volume",
- -32768, 32767,
- omap_mcbsp_get_st_ch0_volume,
- omap_mcbsp_set_st_ch0_volume),
- OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 1 Volume",
- -32768, 32767,
- omap_mcbsp_get_st_ch1_volume,
- omap_mcbsp_set_st_ch1_volume),
-};
-
-static const struct snd_kcontrol_new omap_mcbsp3_st_controls[] = {
- SOC_SINGLE_EXT("McBSP3 Sidetone Switch", 2, 0, 1, 0,
- omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode),
- OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 0 Volume",
- -32768, 32767,
- omap_mcbsp_get_st_ch0_volume,
- omap_mcbsp_set_st_ch0_volume),
- OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 1 Volume",
- -32768, 32767,
- omap_mcbsp_get_st_ch1_volume,
- omap_mcbsp_set_st_ch1_volume),
-};
-
-int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
-
- if (!mcbsp->st_data)
- return -ENODEV;
-
- switch (cpu_dai->id) {
- case 2: /* McBSP 2 */
- return snd_soc_add_dai_controls(cpu_dai,
- omap_mcbsp2_st_controls,
- ARRAY_SIZE(omap_mcbsp2_st_controls));
- case 3: /* McBSP 3 */
- return snd_soc_add_dai_controls(cpu_dai,
- omap_mcbsp3_st_controls,
- ARRAY_SIZE(omap_mcbsp3_st_controls));
- default:
- break;
- }
-
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls);
-
-static __devinit int asoc_mcbsp_probe(struct platform_device *pdev)
-{
- struct omap_mcbsp_platform_data *pdata = dev_get_platdata(&pdev->dev);
- struct omap_mcbsp *mcbsp;
- int ret;
-
- if (!pdata) {
- dev_err(&pdev->dev, "missing platform data.\n");
- return -EINVAL;
- }
- mcbsp = devm_kzalloc(&pdev->dev, sizeof(struct omap_mcbsp), GFP_KERNEL);
- if (!mcbsp)
- return -ENOMEM;
-
- mcbsp->id = pdev->id;
- mcbsp->pdata = pdata;
- mcbsp->dev = &pdev->dev;
- platform_set_drvdata(pdev, mcbsp);
-
- ret = omap_mcbsp_init(pdev);
- if (!ret)
- return snd_soc_register_dai(&pdev->dev, &omap_mcbsp_dai);
-
- return ret;
-}
-
-static int __devexit asoc_mcbsp_remove(struct platform_device *pdev)
-{
- struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
-
- snd_soc_unregister_dai(&pdev->dev);
-
- if (mcbsp->pdata->ops && mcbsp->pdata->ops->free)
- mcbsp->pdata->ops->free(mcbsp->id);
-
- omap_mcbsp_sysfs_remove(mcbsp);
-
- clk_put(mcbsp->fclk);
-
- platform_set_drvdata(pdev, NULL);
-
- return 0;
-}
-
-static struct platform_driver asoc_mcbsp_driver = {
- .driver = {
- .name = "omap-mcbsp",
- .owner = THIS_MODULE,
- },
-
- .probe = asoc_mcbsp_probe,
- .remove = __devexit_p(asoc_mcbsp_remove),
-};
-
-module_platform_driver(asoc_mcbsp_driver);
-
-MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>");
-MODULE_DESCRIPTION("OMAP I2S SoC Interface");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/omap/omap-mcbsp.h b/ANDROID_3.4.5/sound/soc/omap/omap-mcbsp.h
deleted file mode 100644
index f877b16f..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/omap-mcbsp.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * omap-mcbsp.h
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
- * Peter Ujfalusi <peter.ujfalusi@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __OMAP_I2S_H__
-#define __OMAP_I2S_H__
-
-/* Source clocks for McBSP sample rate generator */
-enum omap_mcbsp_clksrg_clk {
- OMAP_MCBSP_SYSCLK_CLKS_FCLK, /* Internal FCLK */
- OMAP_MCBSP_SYSCLK_CLKS_EXT, /* External CLKS pin */
- OMAP_MCBSP_SYSCLK_CLK, /* Internal ICLK */
- OMAP_MCBSP_SYSCLK_CLKX_EXT, /* External CLKX pin */
- OMAP_MCBSP_SYSCLK_CLKR_EXT, /* External CLKR pin */
- OMAP_MCBSP_CLKR_SRC_CLKR, /* CLKR from CLKR pin */
- OMAP_MCBSP_CLKR_SRC_CLKX, /* CLKR from CLKX pin */
- OMAP_MCBSP_FSR_SRC_FSR, /* FSR from FSR pin */
- OMAP_MCBSP_FSR_SRC_FSX, /* FSR from FSX pin */
-};
-
-/* McBSP dividers */
-enum omap_mcbsp_div {
- OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */
-};
-
-#if defined(CONFIG_SOC_OMAP2420)
-#define NUM_LINKS 2
-#endif
-#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
-#undef NUM_LINKS
-#define NUM_LINKS 3
-#endif
-#if defined(CONFIG_ARCH_OMAP4)
-#undef NUM_LINKS
-#define NUM_LINKS 4
-#endif
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_OMAP2430)
-#undef NUM_LINKS
-#define NUM_LINKS 5
-#endif
-
-int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/omap/omap-mcpdm.c b/ANDROID_3.4.5/sound/soc/omap/omap-mcpdm.c
deleted file mode 100644
index 39705561..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/omap-mcpdm.c
+++ /dev/null
@@ -1,524 +0,0 @@
-/*
- * omap-mcpdm.c -- OMAP ALSA SoC DAI driver using McPDM port
- *
- * Copyright (C) 2009 - 2011 Texas Instruments
- *
- * Author: Misael Lopez Cruz <misael.lopez@ti.com>
- * Contact: Jorge Eduardo Candelaria <x0107209@ti.com>
- * Margarita Olaya <magi.olaya@ti.com>
- * Peter Ujfalusi <peter.ujfalusi@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/slab.h>
-#include <linux/pm_runtime.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <plat/dma.h>
-#include <plat/omap_hwmod.h>
-#include "omap-mcpdm.h"
-#include "omap-pcm.h"
-
-struct omap_mcpdm {
- struct device *dev;
- unsigned long phys_base;
- void __iomem *io_base;
- int irq;
-
- struct mutex mutex;
-
- /* channel data */
- u32 dn_channels;
- u32 up_channels;
-
- /* McPDM FIFO thresholds */
- u32 dn_threshold;
- u32 up_threshold;
-
- /* McPDM dn offsets for rx1, and 2 channels */
- u32 dn_rx_offset;
-};
-
-/*
- * Stream DMA parameters
- */
-static struct omap_pcm_dma_data omap_mcpdm_dai_dma_params[] = {
- {
- .name = "Audio playback",
- .dma_req = OMAP44XX_DMA_MCPDM_DL,
- .data_type = OMAP_DMA_DATA_TYPE_S32,
- .sync_mode = OMAP_DMA_SYNC_PACKET,
- .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_REG_DN_DATA,
- },
- {
- .name = "Audio capture",
- .dma_req = OMAP44XX_DMA_MCPDM_UP,
- .data_type = OMAP_DMA_DATA_TYPE_S32,
- .sync_mode = OMAP_DMA_SYNC_PACKET,
- .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_REG_UP_DATA,
- },
-};
-
-static inline void omap_mcpdm_write(struct omap_mcpdm *mcpdm, u16 reg, u32 val)
-{
- __raw_writel(val, mcpdm->io_base + reg);
-}
-
-static inline int omap_mcpdm_read(struct omap_mcpdm *mcpdm, u16 reg)
-{
- return __raw_readl(mcpdm->io_base + reg);
-}
-
-#ifdef DEBUG
-static void omap_mcpdm_reg_dump(struct omap_mcpdm *mcpdm)
-{
- dev_dbg(mcpdm->dev, "***********************\n");
- dev_dbg(mcpdm->dev, "IRQSTATUS_RAW: 0x%04x\n",
- omap_mcpdm_read(mcpdm, MCPDM_REG_IRQSTATUS_RAW));
- dev_dbg(mcpdm->dev, "IRQSTATUS: 0x%04x\n",
- omap_mcpdm_read(mcpdm, MCPDM_REG_IRQSTATUS));
- dev_dbg(mcpdm->dev, "IRQENABLE_SET: 0x%04x\n",
- omap_mcpdm_read(mcpdm, MCPDM_REG_IRQENABLE_SET));
- dev_dbg(mcpdm->dev, "IRQENABLE_CLR: 0x%04x\n",
- omap_mcpdm_read(mcpdm, MCPDM_REG_IRQENABLE_CLR));
- dev_dbg(mcpdm->dev, "IRQWAKE_EN: 0x%04x\n",
- omap_mcpdm_read(mcpdm, MCPDM_REG_IRQWAKE_EN));
- dev_dbg(mcpdm->dev, "DMAENABLE_SET: 0x%04x\n",
- omap_mcpdm_read(mcpdm, MCPDM_REG_DMAENABLE_SET));
- dev_dbg(mcpdm->dev, "DMAENABLE_CLR: 0x%04x\n",
- omap_mcpdm_read(mcpdm, MCPDM_REG_DMAENABLE_CLR));
- dev_dbg(mcpdm->dev, "DMAWAKEEN: 0x%04x\n",
- omap_mcpdm_read(mcpdm, MCPDM_REG_DMAWAKEEN));
- dev_dbg(mcpdm->dev, "CTRL: 0x%04x\n",
- omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL));
- dev_dbg(mcpdm->dev, "DN_DATA: 0x%04x\n",
- omap_mcpdm_read(mcpdm, MCPDM_REG_DN_DATA));
- dev_dbg(mcpdm->dev, "UP_DATA: 0x%04x\n",
- omap_mcpdm_read(mcpdm, MCPDM_REG_UP_DATA));
- dev_dbg(mcpdm->dev, "FIFO_CTRL_DN: 0x%04x\n",
- omap_mcpdm_read(mcpdm, MCPDM_REG_FIFO_CTRL_DN));
- dev_dbg(mcpdm->dev, "FIFO_CTRL_UP: 0x%04x\n",
- omap_mcpdm_read(mcpdm, MCPDM_REG_FIFO_CTRL_UP));
- dev_dbg(mcpdm->dev, "***********************\n");
-}
-#else
-static void omap_mcpdm_reg_dump(struct omap_mcpdm *mcpdm) {}
-#endif
-
-/*
- * Enables the transfer through the PDM interface to/from the Phoenix
- * codec by enabling the corresponding UP or DN channels.
- */
-static void omap_mcpdm_start(struct omap_mcpdm *mcpdm)
-{
- u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
-
- ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
- omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
-
- ctrl |= mcpdm->dn_channels | mcpdm->up_channels;
- omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
-
- ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
- omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
-}
-
-/*
- * Disables the transfer through the PDM interface to/from the Phoenix
- * codec by disabling the corresponding UP or DN channels.
- */
-static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm)
-{
- u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
-
- ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
- omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
-
- ctrl &= ~(mcpdm->dn_channels | mcpdm->up_channels);
- omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
-
- ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
- omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
-
-}
-
-/*
- * Is the physical McPDM interface active.
- */
-static inline int omap_mcpdm_active(struct omap_mcpdm *mcpdm)
-{
- return omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL) &
- (MCPDM_PDM_DN_MASK | MCPDM_PDM_UP_MASK);
-}
-
-/*
- * Configures McPDM uplink, and downlink for audio.
- * This function should be called before omap_mcpdm_start.
- */
-static void omap_mcpdm_open_streams(struct omap_mcpdm *mcpdm)
-{
- omap_mcpdm_write(mcpdm, MCPDM_REG_IRQENABLE_SET,
- MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL |
- MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL);
-
- /* Enable DN RX1/2 offset cancellation feature, if configured */
- if (mcpdm->dn_rx_offset) {
- u32 dn_offset = mcpdm->dn_rx_offset;
-
- omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset);
- dn_offset |= (MCPDM_DN_OFST_RX1_EN | MCPDM_DN_OFST_RX2_EN);
- omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset);
- }
-
- omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN, mcpdm->dn_threshold);
- omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP, mcpdm->up_threshold);
-
- omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_SET,
- MCPDM_DMA_DN_ENABLE | MCPDM_DMA_UP_ENABLE);
-}
-
-/*
- * Cleans McPDM uplink, and downlink configuration.
- * This function should be called when the stream is closed.
- */
-static void omap_mcpdm_close_streams(struct omap_mcpdm *mcpdm)
-{
- /* Disable irq request generation for downlink */
- omap_mcpdm_write(mcpdm, MCPDM_REG_IRQENABLE_CLR,
- MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL);
-
- /* Disable DMA request generation for downlink */
- omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_CLR, MCPDM_DMA_DN_ENABLE);
-
- /* Disable irq request generation for uplink */
- omap_mcpdm_write(mcpdm, MCPDM_REG_IRQENABLE_CLR,
- MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL);
-
- /* Disable DMA request generation for uplink */
- omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_CLR, MCPDM_DMA_UP_ENABLE);
-
- /* Disable RX1/2 offset cancellation */
- if (mcpdm->dn_rx_offset)
- omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, 0);
-}
-
-static irqreturn_t omap_mcpdm_irq_handler(int irq, void *dev_id)
-{
- struct omap_mcpdm *mcpdm = dev_id;
- int irq_status;
-
- irq_status = omap_mcpdm_read(mcpdm, MCPDM_REG_IRQSTATUS);
-
- /* Acknowledge irq event */
- omap_mcpdm_write(mcpdm, MCPDM_REG_IRQSTATUS, irq_status);
-
- if (irq_status & MCPDM_DN_IRQ_FULL)
- dev_dbg(mcpdm->dev, "DN (playback) FIFO Full\n");
-
- if (irq_status & MCPDM_DN_IRQ_EMPTY)
- dev_dbg(mcpdm->dev, "DN (playback) FIFO Empty\n");
-
- if (irq_status & MCPDM_DN_IRQ)
- dev_dbg(mcpdm->dev, "DN (playback) write request\n");
-
- if (irq_status & MCPDM_UP_IRQ_FULL)
- dev_dbg(mcpdm->dev, "UP (capture) FIFO Full\n");
-
- if (irq_status & MCPDM_UP_IRQ_EMPTY)
- dev_dbg(mcpdm->dev, "UP (capture) FIFO Empty\n");
-
- if (irq_status & MCPDM_UP_IRQ)
- dev_dbg(mcpdm->dev, "UP (capture) write request\n");
-
- return IRQ_HANDLED;
-}
-
-static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
-
- mutex_lock(&mcpdm->mutex);
-
- if (!dai->active) {
- /* Enable watch dog for ES above ES 1.0 to avoid saturation */
- if (omap_rev() != OMAP4430_REV_ES1_0) {
- u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
-
- omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL,
- ctrl | MCPDM_WD_EN);
- }
- omap_mcpdm_open_streams(mcpdm);
- }
-
- mutex_unlock(&mcpdm->mutex);
-
- return 0;
-}
-
-static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
-
- mutex_lock(&mcpdm->mutex);
-
- if (!dai->active) {
- if (omap_mcpdm_active(mcpdm)) {
- omap_mcpdm_stop(mcpdm);
- omap_mcpdm_close_streams(mcpdm);
- }
- }
-
- mutex_unlock(&mcpdm->mutex);
-}
-
-static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
- int stream = substream->stream;
- struct omap_pcm_dma_data *dma_data;
- int channels;
- int link_mask = 0;
-
- channels = params_channels(params);
- switch (channels) {
- case 5:
- if (stream == SNDRV_PCM_STREAM_CAPTURE)
- /* up to 3 channels for capture */
- return -EINVAL;
- link_mask |= 1 << 4;
- case 4:
- if (stream == SNDRV_PCM_STREAM_CAPTURE)
- /* up to 3 channels for capture */
- return -EINVAL;
- link_mask |= 1 << 3;
- case 3:
- link_mask |= 1 << 2;
- case 2:
- link_mask |= 1 << 1;
- case 1:
- link_mask |= 1 << 0;
- break;
- default:
- /* unsupported number of channels */
- return -EINVAL;
- }
-
- dma_data = &omap_mcpdm_dai_dma_params[stream];
-
- /* Configure McPDM channels, and DMA packet size */
- if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
- mcpdm->dn_channels = link_mask << 3;
- dma_data->packet_size =
- (MCPDM_DN_THRES_MAX - mcpdm->dn_threshold) * channels;
- } else {
- mcpdm->up_channels = link_mask << 0;
- dma_data->packet_size = mcpdm->up_threshold * channels;
- }
-
- snd_soc_dai_set_dma_data(dai, substream, dma_data);
-
- return 0;
-}
-
-static int omap_mcpdm_prepare(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
-
- if (!omap_mcpdm_active(mcpdm)) {
- omap_mcpdm_start(mcpdm);
- omap_mcpdm_reg_dump(mcpdm);
- }
-
- return 0;
-}
-
-static const struct snd_soc_dai_ops omap_mcpdm_dai_ops = {
- .startup = omap_mcpdm_dai_startup,
- .shutdown = omap_mcpdm_dai_shutdown,
- .hw_params = omap_mcpdm_dai_hw_params,
- .prepare = omap_mcpdm_prepare,
-};
-
-static int omap_mcpdm_probe(struct snd_soc_dai *dai)
-{
- struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
- int ret;
-
- pm_runtime_enable(mcpdm->dev);
-
- /* Disable lines while request is ongoing */
- pm_runtime_get_sync(mcpdm->dev);
- omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00);
-
- ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler,
- 0, "McPDM", (void *)mcpdm);
-
- pm_runtime_put_sync(mcpdm->dev);
-
- if (ret) {
- dev_err(mcpdm->dev, "Request for IRQ failed\n");
- pm_runtime_disable(mcpdm->dev);
- }
-
- /* Configure McPDM threshold values */
- mcpdm->dn_threshold = 2;
- mcpdm->up_threshold = MCPDM_UP_THRES_MAX - 3;
- return ret;
-}
-
-static int omap_mcpdm_remove(struct snd_soc_dai *dai)
-{
- struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
-
- free_irq(mcpdm->irq, (void *)mcpdm);
- pm_runtime_disable(mcpdm->dev);
-
- return 0;
-}
-
-#define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
-#define OMAP_MCPDM_FORMATS SNDRV_PCM_FMTBIT_S32_LE
-
-static struct snd_soc_dai_driver omap_mcpdm_dai = {
- .probe = omap_mcpdm_probe,
- .remove = omap_mcpdm_remove,
- .probe_order = SND_SOC_COMP_ORDER_LATE,
- .remove_order = SND_SOC_COMP_ORDER_EARLY,
- .playback = {
- .channels_min = 1,
- .channels_max = 5,
- .rates = OMAP_MCPDM_RATES,
- .formats = OMAP_MCPDM_FORMATS,
- .sig_bits = 24,
- },
- .capture = {
- .channels_min = 1,
- .channels_max = 3,
- .rates = OMAP_MCPDM_RATES,
- .formats = OMAP_MCPDM_FORMATS,
- .sig_bits = 24,
- },
- .ops = &omap_mcpdm_dai_ops,
-};
-
-void omap_mcpdm_configure_dn_offsets(struct snd_soc_pcm_runtime *rtd,
- u8 rx1, u8 rx2)
-{
- struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(rtd->cpu_dai);
-
- mcpdm->dn_rx_offset = MCPDM_DNOFST_RX1(rx1) | MCPDM_DNOFST_RX2(rx2);
-}
-EXPORT_SYMBOL_GPL(omap_mcpdm_configure_dn_offsets);
-
-static __devinit int asoc_mcpdm_probe(struct platform_device *pdev)
-{
- struct omap_mcpdm *mcpdm;
- struct resource *res;
- int ret = 0;
-
- mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL);
- if (!mcpdm)
- return -ENOMEM;
-
- platform_set_drvdata(pdev, mcpdm);
-
- mutex_init(&mcpdm->mutex);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "no resource\n");
- goto err_res;
- }
-
- if (!request_mem_region(res->start, resource_size(res), "McPDM")) {
- ret = -EBUSY;
- goto err_res;
- }
-
- mcpdm->io_base = ioremap(res->start, resource_size(res));
- if (!mcpdm->io_base) {
- ret = -ENOMEM;
- goto err_iomap;
- }
-
- mcpdm->irq = platform_get_irq(pdev, 0);
- if (mcpdm->irq < 0) {
- ret = mcpdm->irq;
- goto err_irq;
- }
-
- mcpdm->dev = &pdev->dev;
-
- ret = snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai);
- if (!ret)
- return 0;
-
-err_irq:
- iounmap(mcpdm->io_base);
-err_iomap:
- release_mem_region(res->start, resource_size(res));
-err_res:
- kfree(mcpdm);
- return ret;
-}
-
-static int __devexit asoc_mcpdm_remove(struct platform_device *pdev)
-{
- struct omap_mcpdm *mcpdm = platform_get_drvdata(pdev);
- struct resource *res;
-
- snd_soc_unregister_dai(&pdev->dev);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- iounmap(mcpdm->io_base);
- release_mem_region(res->start, resource_size(res));
-
- kfree(mcpdm);
- return 0;
-}
-
-static struct platform_driver asoc_mcpdm_driver = {
- .driver = {
- .name = "omap-mcpdm",
- .owner = THIS_MODULE,
- },
-
- .probe = asoc_mcpdm_probe,
- .remove = __devexit_p(asoc_mcpdm_remove),
-};
-
-module_platform_driver(asoc_mcpdm_driver);
-
-MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
-MODULE_DESCRIPTION("OMAP PDM SoC Interface");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/omap/omap-mcpdm.h b/ANDROID_3.4.5/sound/soc/omap/omap-mcpdm.h
deleted file mode 100644
index de8cf265..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/omap-mcpdm.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * omap-mcpdm.h
- *
- * Copyright (C) 2009 - 2011 Texas Instruments
- *
- * Contact: Misael Lopez Cruz <misael.lopez@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __OMAP_MCPDM_H__
-#define __OMAP_MCPDM_H__
-
-#define MCPDM_REG_REVISION 0x00
-#define MCPDM_REG_SYSCONFIG 0x10
-#define MCPDM_REG_IRQSTATUS_RAW 0x24
-#define MCPDM_REG_IRQSTATUS 0x28
-#define MCPDM_REG_IRQENABLE_SET 0x2C
-#define MCPDM_REG_IRQENABLE_CLR 0x30
-#define MCPDM_REG_IRQWAKE_EN 0x34
-#define MCPDM_REG_DMAENABLE_SET 0x38
-#define MCPDM_REG_DMAENABLE_CLR 0x3C
-#define MCPDM_REG_DMAWAKEEN 0x40
-#define MCPDM_REG_CTRL 0x44
-#define MCPDM_REG_DN_DATA 0x48
-#define MCPDM_REG_UP_DATA 0x4C
-#define MCPDM_REG_FIFO_CTRL_DN 0x50
-#define MCPDM_REG_FIFO_CTRL_UP 0x54
-#define MCPDM_REG_DN_OFFSET 0x58
-
-/*
- * MCPDM_IRQ bit fields
- * IRQSTATUS_RAW, IRQSTATUS, IRQENABLE_SET, IRQENABLE_CLR
- */
-
-#define MCPDM_DN_IRQ (1 << 0)
-#define MCPDM_DN_IRQ_EMPTY (1 << 1)
-#define MCPDM_DN_IRQ_ALMST_EMPTY (1 << 2)
-#define MCPDM_DN_IRQ_FULL (1 << 3)
-
-#define MCPDM_UP_IRQ (1 << 8)
-#define MCPDM_UP_IRQ_EMPTY (1 << 9)
-#define MCPDM_UP_IRQ_ALMST_FULL (1 << 10)
-#define MCPDM_UP_IRQ_FULL (1 << 11)
-
-#define MCPDM_DOWNLINK_IRQ_MASK 0x00F
-#define MCPDM_UPLINK_IRQ_MASK 0xF00
-
-/*
- * MCPDM_DMAENABLE bit fields
- */
-
-#define MCPDM_DMA_DN_ENABLE (1 << 0)
-#define MCPDM_DMA_UP_ENABLE (1 << 1)
-
-/*
- * MCPDM_CTRL bit fields
- */
-
-#define MCPDM_PDM_UPLINK_EN(x) (1 << (x - 1)) /* ch1 is at bit 0 */
-#define MCPDM_PDM_DOWNLINK_EN(x) (1 << (x + 2)) /* ch1 is at bit 3 */
-#define MCPDM_PDMOUTFORMAT (1 << 8)
-#define MCPDM_CMD_INT (1 << 9)
-#define MCPDM_STATUS_INT (1 << 10)
-#define MCPDM_SW_UP_RST (1 << 11)
-#define MCPDM_SW_DN_RST (1 << 12)
-#define MCPDM_WD_EN (1 << 14)
-#define MCPDM_PDM_UP_MASK 0x7
-#define MCPDM_PDM_DN_MASK (0x1f << 3)
-
-
-#define MCPDM_PDMOUTFORMAT_LJUST (0 << 8)
-#define MCPDM_PDMOUTFORMAT_RJUST (1 << 8)
-
-/*
- * MCPDM_FIFO_CTRL bit fields
- */
-
-#define MCPDM_UP_THRES_MAX 0xF
-#define MCPDM_DN_THRES_MAX 0xF
-
-/*
- * MCPDM_DN_OFFSET bit fields
- */
-
-#define MCPDM_DN_OFST_RX1_EN (1 << 0)
-#define MCPDM_DNOFST_RX1(x) ((x & 0x1f) << 1)
-#define MCPDM_DN_OFST_RX2_EN (1 << 8)
-#define MCPDM_DNOFST_RX2(x) ((x & 0x1f) << 9)
-
-void omap_mcpdm_configure_dn_offsets(struct snd_soc_pcm_runtime *rtd,
- u8 rx1, u8 rx2);
-
-#endif /* End of __OMAP_MCPDM_H__ */
diff --git a/ANDROID_3.4.5/sound/soc/omap/omap-pcm.c b/ANDROID_3.4.5/sound/soc/omap/omap-pcm.c
deleted file mode 100644
index 5a649da9..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/omap-pcm.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * omap-pcm.c -- ALSA PCM interface for the OMAP SoC
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
- * Peter Ujfalusi <peter.ujfalusi@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <plat/dma.h>
-#include "omap-pcm.h"
-
-static const struct snd_pcm_hardware omap_pcm_hardware = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
- .formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- .period_bytes_min = 32,
- .period_bytes_max = 64 * 1024,
- .periods_min = 2,
- .periods_max = 255,
- .buffer_bytes_max = 128 * 1024,
-};
-
-struct omap_runtime_data {
- spinlock_t lock;
- struct omap_pcm_dma_data *dma_data;
- int dma_ch;
- int period_index;
-};
-
-static void omap_pcm_dma_irq(int ch, u16 stat, void *data)
-{
- struct snd_pcm_substream *substream = data;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct omap_runtime_data *prtd = runtime->private_data;
- unsigned long flags;
-
- if ((cpu_is_omap1510())) {
- /*
- * OMAP1510 doesn't fully support DMA progress counter
- * and there is no software emulation implemented yet,
- * so have to maintain our own progress counters
- * that can be used by omap_pcm_pointer() instead.
- */
- spin_lock_irqsave(&prtd->lock, flags);
- if ((stat == OMAP_DMA_LAST_IRQ) &&
- (prtd->period_index == runtime->periods - 1)) {
- /* we are in sync, do nothing */
- spin_unlock_irqrestore(&prtd->lock, flags);
- return;
- }
- if (prtd->period_index >= 0) {
- if (stat & OMAP_DMA_BLOCK_IRQ) {
- /* end of buffer reached, loop back */
- prtd->period_index = 0;
- } else if (stat & OMAP_DMA_LAST_IRQ) {
- /* update the counter for the last period */
- prtd->period_index = runtime->periods - 1;
- } else if (++prtd->period_index >= runtime->periods) {
- /* end of buffer missed? loop back */
- prtd->period_index = 0;
- }
- }
- spin_unlock_irqrestore(&prtd->lock, flags);
- }
-
- snd_pcm_period_elapsed(substream);
-}
-
-/* this may get called several times by oss emulation */
-static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct omap_runtime_data *prtd = runtime->private_data;
- struct omap_pcm_dma_data *dma_data;
-
- int err = 0;
-
- dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
- /* return if this is a bufferless transfer e.g.
- * codec <--> BT codec or GSM modem -- lg FIXME */
- if (!dma_data)
- return 0;
-
- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
- runtime->dma_bytes = params_buffer_bytes(params);
-
- if (prtd->dma_data)
- return 0;
- prtd->dma_data = dma_data;
- err = omap_request_dma(dma_data->dma_req, dma_data->name,
- omap_pcm_dma_irq, substream, &prtd->dma_ch);
- if (!err) {
- /*
- * Link channel with itself so DMA doesn't need any
- * reprogramming while looping the buffer
- */
- omap_dma_link_lch(prtd->dma_ch, prtd->dma_ch);
- }
-
- return err;
-}
-
-static int omap_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct omap_runtime_data *prtd = runtime->private_data;
-
- if (prtd->dma_data == NULL)
- return 0;
-
- omap_dma_unlink_lch(prtd->dma_ch, prtd->dma_ch);
- omap_free_dma(prtd->dma_ch);
- prtd->dma_data = NULL;
-
- snd_pcm_set_runtime_buffer(substream, NULL);
-
- return 0;
-}
-
-static int omap_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct omap_runtime_data *prtd = runtime->private_data;
- struct omap_pcm_dma_data *dma_data = prtd->dma_data;
- struct omap_dma_channel_params dma_params;
- int bytes;
-
- /* return if this is a bufferless transfer e.g.
- * codec <--> BT codec or GSM modem -- lg FIXME */
- if (!prtd->dma_data)
- return 0;
-
- memset(&dma_params, 0, sizeof(dma_params));
- dma_params.data_type = dma_data->data_type;
- dma_params.trigger = dma_data->dma_req;
- dma_params.sync_mode = dma_data->sync_mode;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- dma_params.src_amode = OMAP_DMA_AMODE_POST_INC;
- dma_params.dst_amode = OMAP_DMA_AMODE_CONSTANT;
- dma_params.src_or_dst_synch = OMAP_DMA_DST_SYNC;
- dma_params.src_start = runtime->dma_addr;
- dma_params.dst_start = dma_data->port_addr;
- dma_params.dst_port = OMAP_DMA_PORT_MPUI;
- dma_params.dst_fi = dma_data->packet_size;
- } else {
- dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT;
- dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC;
- dma_params.src_or_dst_synch = OMAP_DMA_SRC_SYNC;
- dma_params.src_start = dma_data->port_addr;
- dma_params.dst_start = runtime->dma_addr;
- dma_params.src_port = OMAP_DMA_PORT_MPUI;
- dma_params.src_fi = dma_data->packet_size;
- }
- /*
- * Set DMA transfer frame size equal to ALSA period size and frame
- * count as no. of ALSA periods. Then with DMA frame interrupt enabled,
- * we can transfer the whole ALSA buffer with single DMA transfer but
- * still can get an interrupt at each period bounary
- */
- bytes = snd_pcm_lib_period_bytes(substream);
- dma_params.elem_count = bytes >> dma_data->data_type;
- dma_params.frame_count = runtime->periods;
- omap_set_dma_params(prtd->dma_ch, &dma_params);
-
- if ((cpu_is_omap1510()))
- omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ |
- OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ);
- else if (!substream->runtime->no_period_wakeup)
- omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ);
- else {
- /*
- * No period wakeup:
- * we need to disable BLOCK_IRQ, which is enabled by the omap
- * dma core at request dma time.
- */
- omap_disable_dma_irq(prtd->dma_ch, OMAP_DMA_BLOCK_IRQ);
- }
-
- if (!(cpu_class_is_omap1())) {
- omap_set_dma_src_burst_mode(prtd->dma_ch,
- OMAP_DMA_DATA_BURST_16);
- omap_set_dma_dest_burst_mode(prtd->dma_ch,
- OMAP_DMA_DATA_BURST_16);
- }
-
- return 0;
-}
-
-static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct omap_runtime_data *prtd = runtime->private_data;
- struct omap_pcm_dma_data *dma_data = prtd->dma_data;
- unsigned long flags;
- int ret = 0;
-
- spin_lock_irqsave(&prtd->lock, flags);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- prtd->period_index = 0;
- /* Configure McBSP internal buffer usage */
- if (dma_data->set_threshold)
- dma_data->set_threshold(substream);
-
- omap_start_dma(prtd->dma_ch);
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- prtd->period_index = -1;
- omap_stop_dma(prtd->dma_ch);
- break;
- default:
- ret = -EINVAL;
- }
- spin_unlock_irqrestore(&prtd->lock, flags);
-
- return ret;
-}
-
-static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct omap_runtime_data *prtd = runtime->private_data;
- dma_addr_t ptr;
- snd_pcm_uframes_t offset;
-
- if (cpu_is_omap1510()) {
- offset = prtd->period_index * runtime->period_size;
- } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- ptr = omap_get_dma_dst_pos(prtd->dma_ch);
- offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
- } else {
- ptr = omap_get_dma_src_pos(prtd->dma_ch);
- offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
- }
-
- if (offset >= runtime->buffer_size)
- offset = 0;
-
- return offset;
-}
-
-static int omap_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct omap_runtime_data *prtd;
- int ret;
-
- snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware);
-
- /* Ensure that buffer size is a multiple of period size */
- ret = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (ret < 0)
- goto out;
-
- prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
- if (prtd == NULL) {
- ret = -ENOMEM;
- goto out;
- }
- spin_lock_init(&prtd->lock);
- runtime->private_data = prtd;
-
-out:
- return ret;
-}
-
-static int omap_pcm_close(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- kfree(runtime->private_data);
- return 0;
-}
-
-static int omap_pcm_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- return dma_mmap_writecombine(substream->pcm->card->dev, vma,
- runtime->dma_area,
- runtime->dma_addr,
- runtime->dma_bytes);
-}
-
-static struct snd_pcm_ops omap_pcm_ops = {
- .open = omap_pcm_open,
- .close = omap_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = omap_pcm_hw_params,
- .hw_free = omap_pcm_hw_free,
- .prepare = omap_pcm_prepare,
- .trigger = omap_pcm_trigger,
- .pointer = omap_pcm_pointer,
- .mmap = omap_pcm_mmap,
-};
-
-static u64 omap_pcm_dmamask = DMA_BIT_MASK(64);
-
-static int omap_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
- int stream)
-{
- struct snd_pcm_substream *substream = pcm->streams[stream].substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = omap_pcm_hardware.buffer_bytes_max;
-
- buf->dev.type = SNDRV_DMA_TYPE_DEV;
- buf->dev.dev = pcm->card->dev;
- buf->private_data = NULL;
- buf->area = dma_alloc_writecombine(pcm->card->dev, size,
- &buf->addr, GFP_KERNEL);
- if (!buf->area)
- return -ENOMEM;
-
- buf->bytes = size;
- return 0;
-}
-
-static void omap_pcm_free_dma_buffers(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- struct snd_dma_buffer *buf;
- int stream;
-
- for (stream = 0; stream < 2; stream++) {
- substream = pcm->streams[stream].substream;
- if (!substream)
- continue;
-
- buf = &substream->dma_buffer;
- if (!buf->area)
- continue;
-
- dma_free_writecombine(pcm->card->dev, buf->bytes,
- buf->area, buf->addr);
- buf->area = NULL;
- }
-}
-
-static int omap_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- int ret = 0;
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &omap_pcm_dmamask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(64);
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = omap_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_PLAYBACK);
- if (ret)
- goto out;
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- ret = omap_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_CAPTURE);
- if (ret)
- goto out;
- }
-
-out:
- /* free preallocated buffers in case of error */
- if (ret)
- omap_pcm_free_dma_buffers(pcm);
-
- return ret;
-}
-
-static struct snd_soc_platform_driver omap_soc_platform = {
- .ops = &omap_pcm_ops,
- .pcm_new = omap_pcm_new,
- .pcm_free = omap_pcm_free_dma_buffers,
-};
-
-static __devinit int omap_pcm_probe(struct platform_device *pdev)
-{
- return snd_soc_register_platform(&pdev->dev,
- &omap_soc_platform);
-}
-
-static int __devexit omap_pcm_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver omap_pcm_driver = {
- .driver = {
- .name = "omap-pcm-audio",
- .owner = THIS_MODULE,
- },
-
- .probe = omap_pcm_probe,
- .remove = __devexit_p(omap_pcm_remove),
-};
-
-module_platform_driver(omap_pcm_driver);
-
-MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>");
-MODULE_DESCRIPTION("OMAP PCM DMA module");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/omap/omap-pcm.h b/ANDROID_3.4.5/sound/soc/omap/omap-pcm.h
deleted file mode 100644
index b92248cb..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/omap-pcm.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * omap-pcm.h
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
- * Peter Ujfalusi <peter.ujfalusi@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __OMAP_PCM_H__
-#define __OMAP_PCM_H__
-
-struct snd_pcm_substream;
-
-struct omap_pcm_dma_data {
- char *name; /* stream identifier */
- int dma_req; /* DMA request line */
- unsigned long port_addr; /* transmit/receive register */
- void (*set_threshold)(struct snd_pcm_substream *substream);
- int data_type; /* data type 8,16,32 */
- int sync_mode; /* DMA sync mode */
- int packet_size; /* packet size only in PACKET mode */
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/omap/omap3beagle.c b/ANDROID_3.4.5/sound/soc/omap/omap3beagle.c
deleted file mode 100644
index 2830dfd0..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/omap3beagle.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * omap3beagle.c -- SoC audio for OMAP3 Beagle
- *
- * Author: Steve Sakoman <steve@sakoman.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-#include <plat/mcbsp.h>
-
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-
-static int omap3beagle_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- unsigned int fmt;
- int ret;
-
- switch (params_channels(params)) {
- case 2: /* Stereo I2S mode */
- fmt = SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM;
- break;
- case 4: /* Four channel TDM mode */
- fmt = SND_SOC_DAIFMT_DSP_A |
- SND_SOC_DAIFMT_IB_NF |
- SND_SOC_DAIFMT_CBM_CFM;
- break;
- default:
- return -EINVAL;
- }
-
- /* Set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, fmt);
- if (ret < 0) {
- printk(KERN_ERR "can't set codec DAI configuration\n");
- return ret;
- }
-
- /* Set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
- if (ret < 0) {
- printk(KERN_ERR "can't set cpu DAI configuration\n");
- return ret;
- }
-
- /* Set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- printk(KERN_ERR "can't set codec system clock\n");
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_soc_ops omap3beagle_ops = {
- .hw_params = omap3beagle_hw_params,
-};
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link omap3beagle_dai = {
- .name = "TWL4030",
- .stream_name = "TWL4030",
- .cpu_dai_name = "omap-mcbsp.2",
- .platform_name = "omap-pcm-audio",
- .codec_dai_name = "twl4030-hifi",
- .codec_name = "twl4030-codec",
- .ops = &omap3beagle_ops,
-};
-
-/* Audio machine driver */
-static struct snd_soc_card snd_soc_omap3beagle = {
- .name = "omap3beagle",
- .owner = THIS_MODULE,
- .dai_link = &omap3beagle_dai,
- .num_links = 1,
-};
-
-static struct platform_device *omap3beagle_snd_device;
-
-static int __init omap3beagle_soc_init(void)
-{
- int ret;
-
- if (!(machine_is_omap3_beagle() || machine_is_devkit8000()))
- return -ENODEV;
- pr_info("OMAP3 Beagle/Devkit8000 SoC init\n");
-
- omap3beagle_snd_device = platform_device_alloc("soc-audio", -1);
- if (!omap3beagle_snd_device) {
- printk(KERN_ERR "Platform device allocation failed\n");
- return -ENOMEM;
- }
-
- platform_set_drvdata(omap3beagle_snd_device, &snd_soc_omap3beagle);
-
- ret = platform_device_add(omap3beagle_snd_device);
- if (ret)
- goto err1;
-
- return 0;
-
-err1:
- printk(KERN_ERR "Unable to add platform device\n");
- platform_device_put(omap3beagle_snd_device);
-
- return ret;
-}
-
-static void __exit omap3beagle_soc_exit(void)
-{
- platform_device_unregister(omap3beagle_snd_device);
-}
-
-module_init(omap3beagle_soc_init);
-module_exit(omap3beagle_soc_exit);
-
-MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>");
-MODULE_DESCRIPTION("ALSA SoC OMAP3 Beagle");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/omap/omap3evm.c b/ANDROID_3.4.5/sound/soc/omap/omap3evm.c
deleted file mode 100644
index 3d468c91..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/omap3evm.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * omap3evm.c -- ALSA SoC support for OMAP3 EVM
- *
- * Author: Anuj Aggarwal <anuj.aggarwal@ti.com>
- *
- * Based on sound/soc/omap/beagle.c by Steve Sakoman
- *
- * Copyright (C) 2008 Texas Instruments, Incorporated
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
- * whether express or implied; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- */
-
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-#include <plat/mcbsp.h>
-
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-
-static int omap3evm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int ret;
-
- /* Set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- printk(KERN_ERR "Can't set codec system clock\n");
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_soc_ops omap3evm_ops = {
- .hw_params = omap3evm_hw_params,
-};
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link omap3evm_dai = {
- .name = "TWL4030",
- .stream_name = "TWL4030",
- .cpu_dai_name = "omap-mcbsp.2",
- .codec_dai_name = "twl4030-hifi",
- .platform_name = "omap-pcm-audio",
- .codec_name = "twl4030-codec",
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM,
- .ops = &omap3evm_ops,
-};
-
-/* Audio machine driver */
-static struct snd_soc_card snd_soc_omap3evm = {
- .name = "omap3evm",
- .owner = THIS_MODULE,
- .dai_link = &omap3evm_dai,
- .num_links = 1,
-};
-
-static struct platform_device *omap3evm_snd_device;
-
-static int __init omap3evm_soc_init(void)
-{
- int ret;
-
- if (!machine_is_omap3evm())
- return -ENODEV;
- pr_info("OMAP3 EVM SoC init\n");
-
- omap3evm_snd_device = platform_device_alloc("soc-audio", -1);
- if (!omap3evm_snd_device) {
- printk(KERN_ERR "Platform device allocation failed\n");
- return -ENOMEM;
- }
-
- platform_set_drvdata(omap3evm_snd_device, &snd_soc_omap3evm);
- ret = platform_device_add(omap3evm_snd_device);
- if (ret)
- goto err1;
-
- return 0;
-
-err1:
- printk(KERN_ERR "Unable to add platform device\n");
- platform_device_put(omap3evm_snd_device);
-
- return ret;
-}
-
-static void __exit omap3evm_soc_exit(void)
-{
- platform_device_unregister(omap3evm_snd_device);
-}
-
-module_init(omap3evm_soc_init);
-module_exit(omap3evm_soc_exit);
-
-MODULE_AUTHOR("Anuj Aggarwal <anuj.aggarwal@ti.com>");
-MODULE_DESCRIPTION("ALSA SoC OMAP3 EVM");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/sound/soc/omap/omap3pandora.c b/ANDROID_3.4.5/sound/soc/omap/omap3pandora.c
deleted file mode 100644
index 4c3a0978..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/omap3pandora.c
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * omap3pandora.c -- SoC audio for Pandora Handheld Console
- *
- * Author: Gražvydas Ignotas <notasas@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/regulator/consumer.h>
-#include <linux/module.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <plat/mcbsp.h>
-
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-
-#define OMAP3_PANDORA_DAC_POWER_GPIO 118
-#define OMAP3_PANDORA_AMP_POWER_GPIO 14
-
-#define PREFIX "ASoC omap3pandora: "
-
-static struct regulator *omap3pandora_dac_reg;
-
-static int omap3pandora_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret;
-
- /* Set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- pr_err(PREFIX "can't set codec system clock\n");
- return ret;
- }
-
- /* Set McBSP clock to external */
- ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_EXT,
- 256 * params_rate(params),
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- pr_err(PREFIX "can't set cpu system clock\n");
- return ret;
- }
-
- ret = snd_soc_dai_set_clkdiv(cpu_dai, OMAP_MCBSP_CLKGDV, 8);
- if (ret < 0) {
- pr_err(PREFIX "can't set SRG clock divider\n");
- return ret;
- }
-
- return 0;
-}
-
-static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- /*
- * The PCM1773 DAC datasheet requires 1ms delay between switching
- * VCC power on/off and /PD pin high/low
- */
- if (SND_SOC_DAPM_EVENT_ON(event)) {
- regulator_enable(omap3pandora_dac_reg);
- mdelay(1);
- gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1);
- } else {
- gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 0);
- mdelay(1);
- regulator_disable(omap3pandora_dac_reg);
- }
-
- return 0;
-}
-
-static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- if (SND_SOC_DAPM_EVENT_ON(event))
- gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 1);
- else
- gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 0);
-
- return 0;
-}
-
-/*
- * Audio paths on Pandora board:
- *
- * |O| ---> PCM DAC +-> AMP -> Headphone Jack
- * |M| A +--------> Line Out
- * |A| <~~clk~~+
- * |P| <--- TWL4030 <--------- Line In and MICs
- */
-static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = {
- SND_SOC_DAPM_DAC_E("PCM DAC", "HiFi Playback", SND_SOC_NOPM,
- 0, 0, omap3pandora_dac_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
- SND_SOC_DAPM_PGA_E("Headphone Amplifier", SND_SOC_NOPM,
- 0, 0, NULL, 0, omap3pandora_hp_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_LINE("Line Out", NULL),
-};
-
-static const struct snd_soc_dapm_widget omap3pandora_in_dapm_widgets[] = {
- SND_SOC_DAPM_MIC("Mic (internal)", NULL),
- SND_SOC_DAPM_MIC("Mic (external)", NULL),
- SND_SOC_DAPM_LINE("Line In", NULL),
-};
-
-static const struct snd_soc_dapm_route omap3pandora_out_map[] = {
- {"PCM DAC", NULL, "APLL Enable"},
- {"Headphone Amplifier", NULL, "PCM DAC"},
- {"Line Out", NULL, "PCM DAC"},
- {"Headphone Jack", NULL, "Headphone Amplifier"},
-};
-
-static const struct snd_soc_dapm_route omap3pandora_in_map[] = {
- {"AUXL", NULL, "Line In"},
- {"AUXR", NULL, "Line In"},
-
- {"MAINMIC", NULL, "Mic Bias 1"},
- {"Mic Bias 1", NULL, "Mic (internal)"},
-
- {"SUBMIC", NULL, "Mic Bias 2"},
- {"Mic Bias 2", NULL, "Mic (external)"},
-};
-
-static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret;
-
- /* All TWL4030 output pins are floating */
- snd_soc_dapm_nc_pin(dapm, "EARPIECE");
- snd_soc_dapm_nc_pin(dapm, "PREDRIVEL");
- snd_soc_dapm_nc_pin(dapm, "PREDRIVER");
- snd_soc_dapm_nc_pin(dapm, "HSOL");
- snd_soc_dapm_nc_pin(dapm, "HSOR");
- snd_soc_dapm_nc_pin(dapm, "CARKITL");
- snd_soc_dapm_nc_pin(dapm, "CARKITR");
- snd_soc_dapm_nc_pin(dapm, "HFL");
- snd_soc_dapm_nc_pin(dapm, "HFR");
- snd_soc_dapm_nc_pin(dapm, "VIBRA");
-
- ret = snd_soc_dapm_new_controls(dapm, omap3pandora_out_dapm_widgets,
- ARRAY_SIZE(omap3pandora_out_dapm_widgets));
- if (ret < 0)
- return ret;
-
- return snd_soc_dapm_add_routes(dapm, omap3pandora_out_map,
- ARRAY_SIZE(omap3pandora_out_map));
-}
-
-static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret;
-
- /* Not comnnected */
- snd_soc_dapm_nc_pin(dapm, "HSMIC");
- snd_soc_dapm_nc_pin(dapm, "CARKITMIC");
- snd_soc_dapm_nc_pin(dapm, "DIGIMIC0");
- snd_soc_dapm_nc_pin(dapm, "DIGIMIC1");
-
- ret = snd_soc_dapm_new_controls(dapm, omap3pandora_in_dapm_widgets,
- ARRAY_SIZE(omap3pandora_in_dapm_widgets));
- if (ret < 0)
- return ret;
-
- return snd_soc_dapm_add_routes(dapm, omap3pandora_in_map,
- ARRAY_SIZE(omap3pandora_in_map));
-}
-
-static struct snd_soc_ops omap3pandora_ops = {
- .hw_params = omap3pandora_hw_params,
-};
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link omap3pandora_dai[] = {
- {
- .name = "PCM1773",
- .stream_name = "HiFi Out",
- .cpu_dai_name = "omap-mcbsp.2",
- .codec_dai_name = "twl4030-hifi",
- .platform_name = "omap-pcm-audio",
- .codec_name = "twl4030-codec",
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS,
- .ops = &omap3pandora_ops,
- .init = omap3pandora_out_init,
- }, {
- .name = "TWL4030",
- .stream_name = "Line/Mic In",
- .cpu_dai_name = "omap-mcbsp.4",
- .codec_dai_name = "twl4030-hifi",
- .platform_name = "omap-pcm-audio",
- .codec_name = "twl4030-codec",
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS,
- .ops = &omap3pandora_ops,
- .init = omap3pandora_in_init,
- }
-};
-
-/* SoC card */
-static struct snd_soc_card snd_soc_card_omap3pandora = {
- .name = "omap3pandora",
- .owner = THIS_MODULE,
- .dai_link = omap3pandora_dai,
- .num_links = ARRAY_SIZE(omap3pandora_dai),
-};
-
-static struct platform_device *omap3pandora_snd_device;
-
-static int __init omap3pandora_soc_init(void)
-{
- int ret;
-
- if (!machine_is_omap3_pandora())
- return -ENODEV;
-
- pr_info("OMAP3 Pandora SoC init\n");
-
- ret = gpio_request(OMAP3_PANDORA_DAC_POWER_GPIO, "dac_power");
- if (ret) {
- pr_err(PREFIX "Failed to get DAC power GPIO\n");
- return ret;
- }
-
- ret = gpio_direction_output(OMAP3_PANDORA_DAC_POWER_GPIO, 0);
- if (ret) {
- pr_err(PREFIX "Failed to set DAC power GPIO direction\n");
- goto fail0;
- }
-
- ret = gpio_request(OMAP3_PANDORA_AMP_POWER_GPIO, "amp_power");
- if (ret) {
- pr_err(PREFIX "Failed to get amp power GPIO\n");
- goto fail0;
- }
-
- ret = gpio_direction_output(OMAP3_PANDORA_AMP_POWER_GPIO, 0);
- if (ret) {
- pr_err(PREFIX "Failed to set amp power GPIO direction\n");
- goto fail1;
- }
-
- omap3pandora_snd_device = platform_device_alloc("soc-audio", -1);
- if (omap3pandora_snd_device == NULL) {
- pr_err(PREFIX "Platform device allocation failed\n");
- ret = -ENOMEM;
- goto fail1;
- }
-
- platform_set_drvdata(omap3pandora_snd_device, &snd_soc_card_omap3pandora);
-
- ret = platform_device_add(omap3pandora_snd_device);
- if (ret) {
- pr_err(PREFIX "Unable to add platform device\n");
- goto fail2;
- }
-
- omap3pandora_dac_reg = regulator_get(&omap3pandora_snd_device->dev, "vcc");
- if (IS_ERR(omap3pandora_dac_reg)) {
- pr_err(PREFIX "Failed to get DAC regulator from %s: %ld\n",
- dev_name(&omap3pandora_snd_device->dev),
- PTR_ERR(omap3pandora_dac_reg));
- ret = PTR_ERR(omap3pandora_dac_reg);
- goto fail3;
- }
-
- return 0;
-
-fail3:
- platform_device_del(omap3pandora_snd_device);
-fail2:
- platform_device_put(omap3pandora_snd_device);
-fail1:
- gpio_free(OMAP3_PANDORA_AMP_POWER_GPIO);
-fail0:
- gpio_free(OMAP3_PANDORA_DAC_POWER_GPIO);
- return ret;
-}
-module_init(omap3pandora_soc_init);
-
-static void __exit omap3pandora_soc_exit(void)
-{
- regulator_put(omap3pandora_dac_reg);
- platform_device_unregister(omap3pandora_snd_device);
- gpio_free(OMAP3_PANDORA_AMP_POWER_GPIO);
- gpio_free(OMAP3_PANDORA_DAC_POWER_GPIO);
-}
-module_exit(omap3pandora_soc_exit);
-
-MODULE_AUTHOR("Grazvydas Ignotas <notasas@gmail.com>");
-MODULE_DESCRIPTION("ALSA SoC OMAP3 Pandora");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/omap/omap4-hdmi-card.c b/ANDROID_3.4.5/sound/soc/omap/omap4-hdmi-card.c
deleted file mode 100644
index 28d689b2..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/omap4-hdmi-card.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * omap4-hdmi-card.c
- *
- * OMAP ALSA SoC machine driver for TI OMAP4 HDMI
- * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
- * Author: Ricardo Neri <ricardo.neri@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/module.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <asm/mach-types.h>
-#include <video/omapdss.h>
-
-#define DRV_NAME "omap4-hdmi-audio"
-
-static int omap4_hdmi_dai_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- int i;
- struct omap_overlay_manager *mgr = NULL;
- struct device *dev = substream->pcm->card->dev;
-
- /* Find DSS HDMI device */
- for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) {
- mgr = omap_dss_get_overlay_manager(i);
- if (mgr && mgr->device
- && mgr->device->type == OMAP_DISPLAY_TYPE_HDMI)
- break;
- }
-
- if (i == omap_dss_get_num_overlay_managers()) {
- dev_err(dev, "HDMI display device not found!\n");
- return -ENODEV;
- }
-
- /* Make sure HDMI is power-on to avoid L3 interconnect errors */
- if (mgr->device->state != OMAP_DSS_DISPLAY_ACTIVE) {
- dev_err(dev, "HDMI display is not active!\n");
- return -EIO;
- }
-
- return 0;
-}
-
-static struct snd_soc_ops omap4_hdmi_dai_ops = {
- .hw_params = omap4_hdmi_dai_hw_params,
-};
-
-static struct snd_soc_dai_link omap4_hdmi_dai = {
- .name = "HDMI",
- .stream_name = "HDMI",
- .cpu_dai_name = "hdmi-audio-dai",
- .platform_name = "omap-pcm-audio",
- .codec_name = "omapdss_hdmi",
- .codec_dai_name = "hdmi-audio-codec",
- .ops = &omap4_hdmi_dai_ops,
-};
-
-static struct snd_soc_card snd_soc_omap4_hdmi = {
- .name = "OMAP4HDMI",
- .owner = THIS_MODULE,
- .dai_link = &omap4_hdmi_dai,
- .num_links = 1,
-};
-
-static __devinit int omap4_hdmi_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &snd_soc_omap4_hdmi;
- int ret;
-
- card->dev = &pdev->dev;
-
- ret = snd_soc_register_card(card);
- if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
- card->dev = NULL;
- return ret;
- }
- return 0;
-}
-
-static int __devexit omap4_hdmi_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- snd_soc_unregister_card(card);
- card->dev = NULL;
- return 0;
-}
-
-static struct platform_driver omap4_hdmi_driver = {
- .driver = {
- .name = "omap4-hdmi-audio",
- .owner = THIS_MODULE,
- },
- .probe = omap4_hdmi_probe,
- .remove = __devexit_p(omap4_hdmi_remove),
-};
-
-module_platform_driver(omap4_hdmi_driver);
-
-MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>");
-MODULE_DESCRIPTION("OMAP4 HDMI machine ASoC driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/ANDROID_3.4.5/sound/soc/omap/osk5912.c b/ANDROID_3.4.5/sound/soc/omap/osk5912.c
deleted file mode 100644
index b1a9d64c..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/osk5912.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * osk5912.c -- SoC audio for OSK 5912
- *
- * Copyright (C) 2008 Mistral Solutions
- *
- * Contact: Arun KS <arunks@mistralsolutions.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <linux/gpio.h>
-#include <linux/module.h>
-#include <plat/mcbsp.h>
-
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-#include "../codecs/tlv320aic23.h"
-
-#define CODEC_CLOCK 12000000
-
-static struct clk *tlv320aic23_mclk;
-
-static int osk_startup(struct snd_pcm_substream *substream)
-{
- return clk_enable(tlv320aic23_mclk);
-}
-
-static void osk_shutdown(struct snd_pcm_substream *substream)
-{
- clk_disable(tlv320aic23_mclk);
-}
-
-static int osk_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int err;
-
- /* Set the codec system clock for DAC and ADC */
- err =
- snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN);
-
- if (err < 0) {
- printk(KERN_ERR "can't set codec system clock\n");
- return err;
- }
-
- return err;
-}
-
-static struct snd_soc_ops osk_ops = {
- .startup = osk_startup,
- .hw_params = osk_hw_params,
- .shutdown = osk_shutdown,
-};
-
-static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_LINE("Line In", NULL),
- SND_SOC_DAPM_MIC("Mic Jack", NULL),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- {"Headphone Jack", NULL, "LHPOUT"},
- {"Headphone Jack", NULL, "RHPOUT"},
-
- {"LLINEIN", NULL, "Line In"},
- {"RLINEIN", NULL, "Line In"},
-
- {"MICIN", NULL, "Mic Jack"},
-};
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link osk_dai = {
- .name = "TLV320AIC23",
- .stream_name = "AIC23",
- .cpu_dai_name = "omap-mcbsp.1",
- .codec_dai_name = "tlv320aic23-hifi",
- .platform_name = "omap-pcm-audio",
- .codec_name = "tlv320aic23-codec",
- .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM,
- .ops = &osk_ops,
-};
-
-/* Audio machine driver */
-static struct snd_soc_card snd_soc_card_osk = {
- .name = "OSK5912",
- .owner = THIS_MODULE,
- .dai_link = &osk_dai,
- .num_links = 1,
-
- .dapm_widgets = tlv320aic23_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
- .dapm_routes = audio_map,
- .num_dapm_routes = ARRAY_SIZE(audio_map),
-};
-
-static struct platform_device *osk_snd_device;
-
-static int __init osk_soc_init(void)
-{
- int err;
- u32 curRate;
- struct device *dev;
-
- if (!(machine_is_omap_osk()))
- return -ENODEV;
-
- osk_snd_device = platform_device_alloc("soc-audio", -1);
- if (!osk_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(osk_snd_device, &snd_soc_card_osk);
- err = platform_device_add(osk_snd_device);
- if (err)
- goto err1;
-
- dev = &osk_snd_device->dev;
-
- tlv320aic23_mclk = clk_get(dev, "mclk");
- if (IS_ERR(tlv320aic23_mclk)) {
- printk(KERN_ERR "Could not get mclk clock\n");
- err = PTR_ERR(tlv320aic23_mclk);
- goto err2;
- }
-
- /*
- * Configure 12 MHz output on MCLK.
- */
- curRate = (uint) clk_get_rate(tlv320aic23_mclk);
- if (curRate != CODEC_CLOCK) {
- if (clk_set_rate(tlv320aic23_mclk, CODEC_CLOCK)) {
- printk(KERN_ERR "Cannot set MCLK for AIC23 CODEC\n");
- err = -ECANCELED;
- goto err3;
- }
- }
-
- printk(KERN_INFO "MCLK = %d [%d]\n",
- (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK);
-
- return 0;
-
-err3:
- clk_put(tlv320aic23_mclk);
-err2:
- platform_device_del(osk_snd_device);
-err1:
- platform_device_put(osk_snd_device);
-
- return err;
-
-}
-
-static void __exit osk_soc_exit(void)
-{
- clk_put(tlv320aic23_mclk);
- platform_device_unregister(osk_snd_device);
-}
-
-module_init(osk_soc_init);
-module_exit(osk_soc_exit);
-
-MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
-MODULE_DESCRIPTION("ALSA SoC OSK 5912");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/omap/overo.c b/ANDROID_3.4.5/sound/soc/omap/overo.c
deleted file mode 100644
index 6ac3e0c3..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/overo.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * overo.c -- SoC audio for Gumstix Overo
- *
- * Author: Steve Sakoman <steve@sakoman.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-#include <plat/mcbsp.h>
-
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-
-static int overo_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int ret;
-
- /* Set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- printk(KERN_ERR "can't set codec system clock\n");
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_soc_ops overo_ops = {
- .hw_params = overo_hw_params,
-};
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link overo_dai = {
- .name = "TWL4030",
- .stream_name = "TWL4030",
- .cpu_dai_name = "omap-mcbsp.2",
- .codec_dai_name = "twl4030-hifi",
- .platform_name = "omap-pcm-audio",
- .codec_name = "twl4030-codec",
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM,
- .ops = &overo_ops,
-};
-
-/* Audio machine driver */
-static struct snd_soc_card snd_soc_card_overo = {
- .name = "overo",
- .owner = THIS_MODULE,
- .dai_link = &overo_dai,
- .num_links = 1,
-};
-
-static struct platform_device *overo_snd_device;
-
-static int __init overo_soc_init(void)
-{
- int ret;
-
- if (!(machine_is_overo() || machine_is_cm_t35())) {
- pr_debug("Incomatible machine!\n");
- return -ENODEV;
- }
- printk(KERN_INFO "overo SoC init\n");
-
- overo_snd_device = platform_device_alloc("soc-audio", -1);
- if (!overo_snd_device) {
- printk(KERN_ERR "Platform device allocation failed\n");
- return -ENOMEM;
- }
-
- platform_set_drvdata(overo_snd_device, &snd_soc_card_overo);
-
- ret = platform_device_add(overo_snd_device);
- if (ret)
- goto err1;
-
- return 0;
-
-err1:
- printk(KERN_ERR "Unable to add platform device\n");
- platform_device_put(overo_snd_device);
-
- return ret;
-}
-module_init(overo_soc_init);
-
-static void __exit overo_soc_exit(void)
-{
- platform_device_unregister(overo_snd_device);
-}
-module_exit(overo_soc_exit);
-
-MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>");
-MODULE_DESCRIPTION("ALSA SoC overo");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/omap/rx51.c b/ANDROID_3.4.5/sound/soc/omap/rx51.c
deleted file mode 100644
index 2712dd23..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/rx51.c
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * rx51.c -- SoC audio for Nokia RX-51
- *
- * Copyright (C) 2008 - 2009 Nokia Corporation
- *
- * Contact: Peter Ujfalusi <peter.ujfalusi@ti.com>
- * Eduardo Valentin <eduardo.valentin@nokia.com>
- * Jarkko Nikula <jarkko.nikula@bitmer.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/jack.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <plat/mcbsp.h>
-#include "../codecs/tpa6130a2.h"
-
-#include <asm/mach-types.h>
-
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-
-#define RX51_TVOUT_SEL_GPIO 40
-#define RX51_JACK_DETECT_GPIO 177
-#define RX51_ECI_SW_GPIO 182
-/*
- * REVISIT: TWL4030 GPIO base in RX-51. Now statically defined to 192. This
- * gpio is reserved in arch/arm/mach-omap2/board-rx51-peripherals.c
- */
-#define RX51_SPEAKER_AMP_TWL_GPIO (192 + 7)
-
-enum {
- RX51_JACK_DISABLED,
- RX51_JACK_TVOUT, /* tv-out with stereo output */
- RX51_JACK_HP, /* headphone: stereo output, no mic */
- RX51_JACK_HS, /* headset: stereo output with mic */
-};
-
-static int rx51_spk_func;
-static int rx51_dmic_func;
-static int rx51_jack_func;
-
-static void rx51_ext_control(struct snd_soc_dapm_context *dapm)
-{
- int hp = 0, hs = 0, tvout = 0;
-
- switch (rx51_jack_func) {
- case RX51_JACK_TVOUT:
- tvout = 1;
- hp = 1;
- break;
- case RX51_JACK_HS:
- hs = 1;
- case RX51_JACK_HP:
- hp = 1;
- break;
- }
-
- if (rx51_spk_func)
- snd_soc_dapm_enable_pin(dapm, "Ext Spk");
- else
- snd_soc_dapm_disable_pin(dapm, "Ext Spk");
- if (rx51_dmic_func)
- snd_soc_dapm_enable_pin(dapm, "DMic");
- else
- snd_soc_dapm_disable_pin(dapm, "DMic");
- if (hp)
- snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
- else
- snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
- if (hs)
- snd_soc_dapm_enable_pin(dapm, "HS Mic");
- else
- snd_soc_dapm_disable_pin(dapm, "HS Mic");
-
- gpio_set_value(RX51_TVOUT_SEL_GPIO, tvout);
-
- snd_soc_dapm_sync(dapm);
-}
-
-static int rx51_startup(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_card *card = rtd->card;
-
- snd_pcm_hw_constraint_minmax(runtime,
- SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
- rx51_ext_control(&card->dapm);
-
- return 0;
-}
-
-static int rx51_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
-
- /* Set the codec system clock for DAC and ADC */
- return snd_soc_dai_set_sysclk(codec_dai, 0, 19200000,
- SND_SOC_CLOCK_IN);
-}
-
-static struct snd_soc_ops rx51_ops = {
- .startup = rx51_startup,
- .hw_params = rx51_hw_params,
-};
-
-static int rx51_get_spk(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = rx51_spk_func;
-
- return 0;
-}
-
-static int rx51_set_spk(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
-
- if (rx51_spk_func == ucontrol->value.integer.value[0])
- return 0;
-
- rx51_spk_func = ucontrol->value.integer.value[0];
- rx51_ext_control(&card->dapm);
-
- return 1;
-}
-
-static int rx51_spk_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- if (SND_SOC_DAPM_EVENT_ON(event))
- gpio_set_value_cansleep(RX51_SPEAKER_AMP_TWL_GPIO, 1);
- else
- gpio_set_value_cansleep(RX51_SPEAKER_AMP_TWL_GPIO, 0);
-
- return 0;
-}
-
-static int rx51_hp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- struct snd_soc_codec *codec = w->dapm->codec;
-
- if (SND_SOC_DAPM_EVENT_ON(event))
- tpa6130a2_stereo_enable(codec, 1);
- else
- tpa6130a2_stereo_enable(codec, 0);
-
- return 0;
-}
-
-static int rx51_get_input(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = rx51_dmic_func;
-
- return 0;
-}
-
-static int rx51_set_input(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
-
- if (rx51_dmic_func == ucontrol->value.integer.value[0])
- return 0;
-
- rx51_dmic_func = ucontrol->value.integer.value[0];
- rx51_ext_control(&card->dapm);
-
- return 1;
-}
-
-static int rx51_get_jack(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = rx51_jack_func;
-
- return 0;
-}
-
-static int rx51_set_jack(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
-
- if (rx51_jack_func == ucontrol->value.integer.value[0])
- return 0;
-
- rx51_jack_func = ucontrol->value.integer.value[0];
- rx51_ext_control(&card->dapm);
-
- return 1;
-}
-
-static struct snd_soc_jack rx51_av_jack;
-
-static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = {
- {
- .gpio = RX51_JACK_DETECT_GPIO,
- .name = "avdet-gpio",
- .report = SND_JACK_HEADSET,
- .invert = 1,
- .debounce_time = 200,
- },
-};
-
-static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = {
- SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event),
- SND_SOC_DAPM_MIC("DMic", NULL),
- SND_SOC_DAPM_HP("Headphone Jack", rx51_hp_event),
- SND_SOC_DAPM_MIC("HS Mic", NULL),
- SND_SOC_DAPM_LINE("FM Transmitter", NULL),
-};
-
-static const struct snd_soc_dapm_widget aic34_dapm_widgetsb[] = {
- SND_SOC_DAPM_SPK("Earphone", NULL),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- {"Ext Spk", NULL, "HPLOUT"},
- {"Ext Spk", NULL, "HPROUT"},
- {"Headphone Jack", NULL, "LLOUT"},
- {"Headphone Jack", NULL, "RLOUT"},
- {"FM Transmitter", NULL, "LLOUT"},
- {"FM Transmitter", NULL, "RLOUT"},
-
- {"DMic Rate 64", NULL, "Mic Bias 2V"},
- {"Mic Bias 2V", NULL, "DMic"},
-};
-
-static const struct snd_soc_dapm_route audio_mapb[] = {
- {"b LINE2R", NULL, "MONO_LOUT"},
- {"Earphone", NULL, "b HPLOUT"},
-
- {"LINE1L", NULL, "b Mic Bias 2.5V"},
- {"b Mic Bias 2.5V", NULL, "HS Mic"}
-};
-
-static const char *spk_function[] = {"Off", "On"};
-static const char *input_function[] = {"ADC", "Digital Mic"};
-static const char *jack_function[] = {"Off", "TV-OUT", "Headphone", "Headset"};
-
-static const struct soc_enum rx51_enum[] = {
- SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function),
- SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(input_function), input_function),
- SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(jack_function), jack_function),
-};
-
-static const struct snd_kcontrol_new aic34_rx51_controls[] = {
- SOC_ENUM_EXT("Speaker Function", rx51_enum[0],
- rx51_get_spk, rx51_set_spk),
- SOC_ENUM_EXT("Input Select", rx51_enum[1],
- rx51_get_input, rx51_set_input),
- SOC_ENUM_EXT("Jack Function", rx51_enum[2],
- rx51_get_jack, rx51_set_jack),
- SOC_DAPM_PIN_SWITCH("FM Transmitter"),
-};
-
-static const struct snd_kcontrol_new aic34_rx51_controlsb[] = {
- SOC_DAPM_PIN_SWITCH("Earphone"),
-};
-
-static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int err;
-
- /* Set up NC codec pins */
- snd_soc_dapm_nc_pin(dapm, "MIC3L");
- snd_soc_dapm_nc_pin(dapm, "MIC3R");
- snd_soc_dapm_nc_pin(dapm, "LINE1R");
-
- /* Add RX-51 specific controls */
- err = snd_soc_add_card_controls(rtd->card, aic34_rx51_controls,
- ARRAY_SIZE(aic34_rx51_controls));
- if (err < 0)
- return err;
-
- /* Add RX-51 specific widgets */
- snd_soc_dapm_new_controls(dapm, aic34_dapm_widgets,
- ARRAY_SIZE(aic34_dapm_widgets));
-
- /* Set up RX-51 specific audio path audio_map */
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
- err = tpa6130a2_add_controls(codec);
- if (err < 0)
- return err;
- snd_soc_limit_volume(codec, "TPA6130A2 Headphone Playback Volume", 42);
-
- err = omap_mcbsp_st_add_controls(rtd);
- if (err < 0)
- return err;
-
- /* AV jack detection */
- err = snd_soc_jack_new(codec, "AV Jack",
- SND_JACK_HEADSET | SND_JACK_VIDEOOUT,
- &rx51_av_jack);
- if (err)
- return err;
- err = snd_soc_jack_add_gpios(&rx51_av_jack,
- ARRAY_SIZE(rx51_av_jack_gpios),
- rx51_av_jack_gpios);
-
- return err;
-}
-
-static int rx51_aic34b_init(struct snd_soc_dapm_context *dapm)
-{
- int err;
-
- err = snd_soc_add_card_controls(dapm->card, aic34_rx51_controlsb,
- ARRAY_SIZE(aic34_rx51_controlsb));
- if (err < 0)
- return err;
-
- err = snd_soc_dapm_new_controls(dapm, aic34_dapm_widgetsb,
- ARRAY_SIZE(aic34_dapm_widgetsb));
- if (err < 0)
- return 0;
-
- return snd_soc_dapm_add_routes(dapm, audio_mapb,
- ARRAY_SIZE(audio_mapb));
-}
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link rx51_dai[] = {
- {
- .name = "TLV320AIC34",
- .stream_name = "AIC34",
- .cpu_dai_name = "omap-mcbsp.2",
- .codec_dai_name = "tlv320aic3x-hifi",
- .platform_name = "omap-pcm-audio",
- .codec_name = "tlv320aic3x-codec.2-0018",
- .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF |
- SND_SOC_DAIFMT_CBM_CFM,
- .init = rx51_aic34_init,
- .ops = &rx51_ops,
- },
-};
-
-static struct snd_soc_aux_dev rx51_aux_dev[] = {
- {
- .name = "TLV320AIC34b",
- .codec_name = "tlv320aic3x-codec.2-0019",
- .init = rx51_aic34b_init,
- },
-};
-
-static struct snd_soc_codec_conf rx51_codec_conf[] = {
- {
- .dev_name = "tlv320aic3x-codec.2-0019",
- .name_prefix = "b",
- },
-};
-
-/* Audio card */
-static struct snd_soc_card rx51_sound_card = {
- .name = "RX-51",
- .owner = THIS_MODULE,
- .dai_link = rx51_dai,
- .num_links = ARRAY_SIZE(rx51_dai),
- .aux_dev = rx51_aux_dev,
- .num_aux_devs = ARRAY_SIZE(rx51_aux_dev),
- .codec_conf = rx51_codec_conf,
- .num_configs = ARRAY_SIZE(rx51_codec_conf),
-};
-
-static struct platform_device *rx51_snd_device;
-
-static int __init rx51_soc_init(void)
-{
- int err;
-
- if (!machine_is_nokia_rx51())
- return -ENODEV;
-
- err = gpio_request_one(RX51_TVOUT_SEL_GPIO,
- GPIOF_DIR_OUT | GPIOF_INIT_LOW, "tvout_sel");
- if (err)
- goto err_gpio_tvout_sel;
- err = gpio_request_one(RX51_ECI_SW_GPIO,
- GPIOF_DIR_OUT | GPIOF_INIT_HIGH, "eci_sw");
- if (err)
- goto err_gpio_eci_sw;
-
- rx51_snd_device = platform_device_alloc("soc-audio", -1);
- if (!rx51_snd_device) {
- err = -ENOMEM;
- goto err1;
- }
-
- platform_set_drvdata(rx51_snd_device, &rx51_sound_card);
-
- err = platform_device_add(rx51_snd_device);
- if (err)
- goto err2;
-
- return 0;
-err2:
- platform_device_put(rx51_snd_device);
-err1:
- gpio_free(RX51_ECI_SW_GPIO);
-err_gpio_eci_sw:
- gpio_free(RX51_TVOUT_SEL_GPIO);
-err_gpio_tvout_sel:
-
- return err;
-}
-
-static void __exit rx51_soc_exit(void)
-{
- snd_soc_jack_free_gpios(&rx51_av_jack, ARRAY_SIZE(rx51_av_jack_gpios),
- rx51_av_jack_gpios);
-
- platform_device_unregister(rx51_snd_device);
- gpio_free(RX51_ECI_SW_GPIO);
- gpio_free(RX51_TVOUT_SEL_GPIO);
-}
-
-module_init(rx51_soc_init);
-module_exit(rx51_soc_exit);
-
-MODULE_AUTHOR("Nokia Corporation");
-MODULE_DESCRIPTION("ALSA SoC Nokia RX-51");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/omap/sdp3430.c b/ANDROID_3.4.5/sound/soc/omap/sdp3430.c
deleted file mode 100644
index 0e283226..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/sdp3430.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * sdp3430.c -- SoC audio for TI OMAP3430 SDP
- *
- * Author: Misael Lopez Cruz <x0052729@ti.com>
- *
- * Based on:
- * Author: Steve Sakoman <steve@sakoman.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/i2c/twl.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/jack.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-#include <plat/mcbsp.h>
-
-/* Register descriptions for twl4030 codec part */
-#include <linux/mfd/twl4030-audio.h>
-#include <linux/module.h>
-
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-
-/* TWL4030 PMBR1 Register */
-#define TWL4030_INTBR_PMBR1 0x0D
-/* TWL4030 PMBR1 Register GPIO6 mux bit */
-#define TWL4030_GPIO6_PWM0_MUTE(value) (value << 2)
-
-static struct snd_soc_card snd_soc_sdp3430;
-
-static int sdp3430_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int ret;
-
- /* Set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- printk(KERN_ERR "can't set codec system clock\n");
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_soc_ops sdp3430_ops = {
- .hw_params = sdp3430_hw_params,
-};
-
-/* Headset jack */
-static struct snd_soc_jack hs_jack;
-
-/* Headset jack detection DAPM pins */
-static struct snd_soc_jack_pin hs_jack_pins[] = {
- {
- .pin = "Headset Mic",
- .mask = SND_JACK_MICROPHONE,
- },
- {
- .pin = "Headset Stereophone",
- .mask = SND_JACK_HEADPHONE,
- },
-};
-
-/* Headset jack detection gpios */
-static struct snd_soc_jack_gpio hs_jack_gpios[] = {
- {
- .gpio = (OMAP_MAX_GPIO_LINES + 2),
- .name = "hsdet-gpio",
- .report = SND_JACK_HEADSET,
- .debounce_time = 200,
- },
-};
-
-/* SDP3430 machine DAPM */
-static const struct snd_soc_dapm_widget sdp3430_twl4030_dapm_widgets[] = {
- SND_SOC_DAPM_MIC("Ext Mic", NULL),
- SND_SOC_DAPM_SPK("Ext Spk", NULL),
- SND_SOC_DAPM_MIC("Headset Mic", NULL),
- SND_SOC_DAPM_HP("Headset Stereophone", NULL),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- /* External Mics: MAINMIC, SUBMIC with bias*/
- {"MAINMIC", NULL, "Mic Bias 1"},
- {"SUBMIC", NULL, "Mic Bias 2"},
- {"Mic Bias 1", NULL, "Ext Mic"},
- {"Mic Bias 2", NULL, "Ext Mic"},
-
- /* External Speakers: HFL, HFR */
- {"Ext Spk", NULL, "HFL"},
- {"Ext Spk", NULL, "HFR"},
-
- /* Headset Mic: HSMIC with bias */
- {"HSMIC", NULL, "Headset Mic Bias"},
- {"Headset Mic Bias", NULL, "Headset Mic"},
-
- /* Headset Stereophone (Headphone): HSOL, HSOR */
- {"Headset Stereophone", NULL, "HSOL"},
- {"Headset Stereophone", NULL, "HSOR"},
-};
-
-static int sdp3430_twl4030_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret;
-
- /* SDP3430 connected pins */
- snd_soc_dapm_enable_pin(dapm, "Ext Mic");
- snd_soc_dapm_enable_pin(dapm, "Ext Spk");
- snd_soc_dapm_disable_pin(dapm, "Headset Mic");
- snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
-
- /* TWL4030 not connected pins */
- snd_soc_dapm_nc_pin(dapm, "AUXL");
- snd_soc_dapm_nc_pin(dapm, "AUXR");
- snd_soc_dapm_nc_pin(dapm, "CARKITMIC");
- snd_soc_dapm_nc_pin(dapm, "DIGIMIC0");
- snd_soc_dapm_nc_pin(dapm, "DIGIMIC1");
-
- snd_soc_dapm_nc_pin(dapm, "OUTL");
- snd_soc_dapm_nc_pin(dapm, "OUTR");
- snd_soc_dapm_nc_pin(dapm, "EARPIECE");
- snd_soc_dapm_nc_pin(dapm, "PREDRIVEL");
- snd_soc_dapm_nc_pin(dapm, "PREDRIVER");
- snd_soc_dapm_nc_pin(dapm, "CARKITL");
- snd_soc_dapm_nc_pin(dapm, "CARKITR");
-
- /* Headset jack detection */
- ret = snd_soc_jack_new(codec, "Headset Jack",
- SND_JACK_HEADSET, &hs_jack);
- if (ret)
- return ret;
-
- ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
- hs_jack_pins);
- if (ret)
- return ret;
-
- ret = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios),
- hs_jack_gpios);
-
- return ret;
-}
-
-static int sdp3430_twl4030_voice_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- unsigned short reg;
-
- /* Enable voice interface */
- reg = codec->driver->read(codec, TWL4030_REG_VOICE_IF);
- reg |= TWL4030_VIF_DIN_EN | TWL4030_VIF_DOUT_EN | TWL4030_VIF_EN;
- codec->driver->write(codec, TWL4030_REG_VOICE_IF, reg);
-
- return 0;
-}
-
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link sdp3430_dai[] = {
- {
- .name = "TWL4030 I2S",
- .stream_name = "TWL4030 Audio",
- .cpu_dai_name = "omap-mcbsp.2",
- .codec_dai_name = "twl4030-hifi",
- .platform_name = "omap-pcm-audio",
- .codec_name = "twl4030-codec",
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM,
- .init = sdp3430_twl4030_init,
- .ops = &sdp3430_ops,
- },
- {
- .name = "TWL4030 PCM",
- .stream_name = "TWL4030 Voice",
- .cpu_dai_name = "omap-mcbsp.3",
- .codec_dai_name = "twl4030-voice",
- .platform_name = "omap-pcm-audio",
- .codec_name = "twl4030-codec",
- .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF |
- SND_SOC_DAIFMT_CBM_CFM,
- .init = sdp3430_twl4030_voice_init,
- .ops = &sdp3430_ops,
- },
-};
-
-/* Audio machine driver */
-static struct snd_soc_card snd_soc_sdp3430 = {
- .name = "SDP3430",
- .owner = THIS_MODULE,
- .dai_link = sdp3430_dai,
- .num_links = ARRAY_SIZE(sdp3430_dai),
-
- .dapm_widgets = sdp3430_twl4030_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(sdp3430_twl4030_dapm_widgets),
- .dapm_routes = audio_map,
- .num_dapm_routes = ARRAY_SIZE(audio_map),
-};
-
-static struct platform_device *sdp3430_snd_device;
-
-static int __init sdp3430_soc_init(void)
-{
- int ret;
- u8 pin_mux;
-
- if (!machine_is_omap_3430sdp())
- return -ENODEV;
- printk(KERN_INFO "SDP3430 SoC init\n");
-
- sdp3430_snd_device = platform_device_alloc("soc-audio", -1);
- if (!sdp3430_snd_device) {
- printk(KERN_ERR "Platform device allocation failed\n");
- return -ENOMEM;
- }
-
- platform_set_drvdata(sdp3430_snd_device, &snd_soc_sdp3430);
-
- /* Set TWL4030 GPIO6 as EXTMUTE signal */
- twl_i2c_read_u8(TWL4030_MODULE_INTBR, &pin_mux,
- TWL4030_INTBR_PMBR1);
- pin_mux &= ~TWL4030_GPIO6_PWM0_MUTE(0x03);
- pin_mux |= TWL4030_GPIO6_PWM0_MUTE(0x02);
- twl_i2c_write_u8(TWL4030_MODULE_INTBR, pin_mux,
- TWL4030_INTBR_PMBR1);
-
- ret = platform_device_add(sdp3430_snd_device);
- if (ret)
- goto err1;
-
- return 0;
-
-err1:
- printk(KERN_ERR "Unable to add platform device\n");
- platform_device_put(sdp3430_snd_device);
-
- return ret;
-}
-module_init(sdp3430_soc_init);
-
-static void __exit sdp3430_soc_exit(void)
-{
- snd_soc_jack_free_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios),
- hs_jack_gpios);
-
- platform_device_unregister(sdp3430_snd_device);
-}
-module_exit(sdp3430_soc_exit);
-
-MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>");
-MODULE_DESCRIPTION("ALSA SoC SDP3430");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/soc/omap/zoom2.c b/ANDROID_3.4.5/sound/soc/omap/zoom2.c
deleted file mode 100644
index 920e0d9e..00000000
--- a/ANDROID_3.4.5/sound/soc/omap/zoom2.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * zoom2.c -- SoC audio for Zoom2
- *
- * Author: Misael Lopez Cruz <x0052729@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-#include <mach/board-zoom.h>
-#include <plat/mcbsp.h>
-
-/* Register descriptions for twl4030 codec part */
-#include <linux/mfd/twl4030-audio.h>
-#include <linux/module.h>
-
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-
-#define ZOOM2_HEADSET_MUX_GPIO (OMAP_MAX_GPIO_LINES + 15)
-
-static int zoom2_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int ret;
-
- /* Set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- printk(KERN_ERR "can't set codec system clock\n");
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_soc_ops zoom2_ops = {
- .hw_params = zoom2_hw_params,
-};
-
-/* Zoom2 machine DAPM */
-static const struct snd_soc_dapm_widget zoom2_twl4030_dapm_widgets[] = {
- SND_SOC_DAPM_MIC("Ext Mic", NULL),
- SND_SOC_DAPM_SPK("Ext Spk", NULL),
- SND_SOC_DAPM_MIC("Headset Mic", NULL),
- SND_SOC_DAPM_HP("Headset Stereophone", NULL),
- SND_SOC_DAPM_LINE("Aux In", NULL),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- /* External Mics: MAINMIC, SUBMIC with bias*/
- {"MAINMIC", NULL, "Mic Bias 1"},
- {"SUBMIC", NULL, "Mic Bias 2"},
- {"Mic Bias 1", NULL, "Ext Mic"},
- {"Mic Bias 2", NULL, "Ext Mic"},
-
- /* External Speakers: HFL, HFR */
- {"Ext Spk", NULL, "HFL"},
- {"Ext Spk", NULL, "HFR"},
-
- /* Headset Stereophone: HSOL, HSOR */
- {"Headset Stereophone", NULL, "HSOL"},
- {"Headset Stereophone", NULL, "HSOR"},
-
- /* Headset Mic: HSMIC with bias */
- {"HSMIC", NULL, "Headset Mic Bias"},
- {"Headset Mic Bias", NULL, "Headset Mic"},
-
- /* Aux In: AUXL, AUXR */
- {"Aux In", NULL, "AUXL"},
- {"Aux In", NULL, "AUXR"},
-};
-
-static int zoom2_twl4030_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- /* TWL4030 not connected pins */
- snd_soc_dapm_nc_pin(dapm, "CARKITMIC");
- snd_soc_dapm_nc_pin(dapm, "DIGIMIC0");
- snd_soc_dapm_nc_pin(dapm, "DIGIMIC1");
- snd_soc_dapm_nc_pin(dapm, "EARPIECE");
- snd_soc_dapm_nc_pin(dapm, "PREDRIVEL");
- snd_soc_dapm_nc_pin(dapm, "PREDRIVER");
- snd_soc_dapm_nc_pin(dapm, "CARKITL");
- snd_soc_dapm_nc_pin(dapm, "CARKITR");
-
- return 0;
-}
-
-static int zoom2_twl4030_voice_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- unsigned short reg;
-
- /* Enable voice interface */
- reg = codec->driver->read(codec, TWL4030_REG_VOICE_IF);
- reg |= TWL4030_VIF_DIN_EN | TWL4030_VIF_DOUT_EN | TWL4030_VIF_EN;
- codec->driver->write(codec, TWL4030_REG_VOICE_IF, reg);
-
- return 0;
-}
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link zoom2_dai[] = {
- {
- .name = "TWL4030 I2S",
- .stream_name = "TWL4030 Audio",
- .cpu_dai_name = "omap-mcbsp.2",
- .codec_dai_name = "twl4030-hifi",
- .platform_name = "omap-pcm-audio",
- .codec_name = "twl4030-codec",
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM,
- .init = zoom2_twl4030_init,
- .ops = &zoom2_ops,
- },
- {
- .name = "TWL4030 PCM",
- .stream_name = "TWL4030 Voice",
- .cpu_dai_name = "omap-mcbsp.3",
- .codec_dai_name = "twl4030-voice",
- .platform_name = "omap-pcm-audio",
- .codec_name = "twl4030-codec",
- .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF |
- SND_SOC_DAIFMT_CBM_CFM,
- .init = zoom2_twl4030_voice_init,
- .ops = &zoom2_ops,
- },
-};
-
-/* Audio machine driver */
-static struct snd_soc_card snd_soc_zoom2 = {
- .name = "Zoom2",
- .owner = THIS_MODULE,
- .dai_link = zoom2_dai,
- .num_links = ARRAY_SIZE(zoom2_dai),
-
- .dapm_widgets = zoom2_twl4030_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(zoom2_twl4030_dapm_widgets),
- .dapm_routes = audio_map,
- .num_dapm_routes = ARRAY_SIZE(audio_map),
-};
-
-static struct platform_device *zoom2_snd_device;
-
-static int __init zoom2_soc_init(void)
-{
- int ret;
-
- if (!machine_is_omap_zoom2())
- return -ENODEV;
- printk(KERN_INFO "Zoom2 SoC init\n");
-
- zoom2_snd_device = platform_device_alloc("soc-audio", -1);
- if (!zoom2_snd_device) {
- printk(KERN_ERR "Platform device allocation failed\n");
- return -ENOMEM;
- }
-
- platform_set_drvdata(zoom2_snd_device, &snd_soc_zoom2);
- ret = platform_device_add(zoom2_snd_device);
- if (ret)
- goto err1;
-
- BUG_ON(gpio_request(ZOOM2_HEADSET_MUX_GPIO, "hs_mux") < 0);
- gpio_direction_output(ZOOM2_HEADSET_MUX_GPIO, 0);
-
- BUG_ON(gpio_request(ZOOM2_HEADSET_EXTMUTE_GPIO, "ext_mute") < 0);
- gpio_direction_output(ZOOM2_HEADSET_EXTMUTE_GPIO, 0);
-
- return 0;
-
-err1:
- printk(KERN_ERR "Unable to add platform device\n");
- platform_device_put(zoom2_snd_device);
-
- return ret;
-}
-module_init(zoom2_soc_init);
-
-static void __exit zoom2_soc_exit(void)
-{
- gpio_free(ZOOM2_HEADSET_MUX_GPIO);
- gpio_free(ZOOM2_HEADSET_EXTMUTE_GPIO);
-
- platform_device_unregister(zoom2_snd_device);
-}
-module_exit(zoom2_soc_exit);
-
-MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>");
-MODULE_DESCRIPTION("ALSA SoC Zoom2");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/soc/pxa/Kconfig b/ANDROID_3.4.5/sound/soc/pxa/Kconfig
deleted file mode 100644
index a0f7d3cf..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/Kconfig
+++ /dev/null
@@ -1,196 +0,0 @@
-config SND_PXA2XX_SOC
- tristate "SoC Audio for the Intel PXA2xx chip"
- depends on ARCH_PXA
- select SND_ARM
- select SND_PXA2XX_LIB
- help
- Say Y or M if you want to add support for codecs attached to
- the PXA2xx AC97, I2S or SSP interface. You will also need
- to select the audio interfaces to support below.
-
-config SND_PXA2XX_AC97
- tristate
- select SND_AC97_CODEC
-
-config SND_PXA2XX_SOC_AC97
- tristate
- select AC97_BUS
- select SND_ARM
- select SND_PXA2XX_LIB_AC97
- select SND_SOC_AC97_BUS
-
-config SND_PXA2XX_SOC_I2S
- tristate
-
-config SND_PXA_SOC_SSP
- tristate
- select PXA_SSP
-
-config SND_PXA2XX_SOC_CORGI
- tristate "SoC Audio support for Sharp Zaurus SL-C7x0"
- depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx
- select SND_PXA2XX_SOC_I2S
- select SND_SOC_WM8731
- help
- Say Y if you want to add support for SoC audio on Sharp
- Zaurus SL-C7x0 models (Corgi, Shepherd, Husky).
-
-config SND_PXA2XX_SOC_SPITZ
- tristate "SoC Audio support for Sharp Zaurus SL-Cxx00"
- depends on SND_PXA2XX_SOC && PXA_SHARP_Cxx00
- select SND_PXA2XX_SOC_I2S
- select SND_SOC_WM8750
- help
- Say Y if you want to add support for SoC audio on Sharp
- Zaurus SL-Cxx00 models (Spitz, Borzoi and Akita).
-
-config SND_PXA2XX_SOC_Z2
- tristate "SoC Audio support for Zipit Z2"
- depends on SND_PXA2XX_SOC && MACH_ZIPIT2
- select SND_PXA2XX_SOC_I2S
- select SND_SOC_WM8750
- help
- Say Y if you want to add support for SoC audio on Zipit Z2.
-
-config SND_PXA2XX_SOC_POODLE
- tristate "SoC Audio support for Poodle"
- depends on SND_PXA2XX_SOC && MACH_POODLE
- select SND_PXA2XX_SOC_I2S
- select SND_SOC_WM8731
- help
- Say Y if you want to add support for SoC audio on Sharp
- Zaurus SL-5600 model (Poodle).
-
-config SND_PXA2XX_SOC_TOSA
- tristate "SoC AC97 Audio support for Tosa"
- depends on SND_PXA2XX_SOC && MACH_TOSA
- depends on MFD_TC6393XB
- select SND_PXA2XX_SOC_AC97
- select SND_SOC_WM9712
- help
- Say Y if you want to add support for SoC audio on Sharp
- Zaurus SL-C6000x models (Tosa).
-
-config SND_PXA2XX_SOC_E740
- tristate "SoC AC97 Audio support for e740"
- depends on SND_PXA2XX_SOC && MACH_E740
- select SND_SOC_WM9705
- select SND_PXA2XX_SOC_AC97
- help
- Say Y if you want to add support for SoC audio on the
- toshiba e740 PDA
-
-config SND_PXA2XX_SOC_E750
- tristate "SoC AC97 Audio support for e750"
- depends on SND_PXA2XX_SOC && MACH_E750
- select SND_SOC_WM9705
- select SND_PXA2XX_SOC_AC97
- help
- Say Y if you want to add support for SoC audio on the
- toshiba e750 PDA
-
-config SND_PXA2XX_SOC_E800
- tristate "SoC AC97 Audio support for e800"
- depends on SND_PXA2XX_SOC && MACH_E800
- select SND_SOC_WM9712
- select SND_PXA2XX_SOC_AC97
- help
- Say Y if you want to add support for SoC audio on the
- Toshiba e800 PDA
-
-config SND_PXA2XX_SOC_EM_X270
- tristate "SoC Audio support for CompuLab EM-x270, eXeda and CM-X300"
- depends on SND_PXA2XX_SOC && (MACH_EM_X270 || MACH_EXEDA || \
- MACH_CM_X300)
- select SND_PXA2XX_SOC_AC97
- select SND_SOC_WM9712
- help
- Say Y if you want to add support for SoC audio on
- CompuLab EM-x270, eXeda and CM-X300 machines.
-
-config SND_PXA2XX_SOC_PALM27X
- bool "SoC Audio support for Palm T|X, T5, E2 and LifeDrive"
- depends on SND_PXA2XX_SOC && (MACH_PALMLD || MACH_PALMTX || \
- MACH_PALMT5 || MACH_PALMTE2)
- select SND_PXA2XX_SOC_AC97
- select SND_SOC_WM9712
- help
- Say Y if you want to add support for SoC audio on
- Palm T|X, T5, E2 or LifeDrive handheld computer.
-
-config SND_SOC_SAARB
- tristate "SoC Audio support for Marvell Saarb"
- depends on SND_PXA2XX_SOC && MACH_SAARB
- select MFD_88PM860X
- select SND_PXA_SOC_SSP
- select SND_SOC_88PM860X
- help
- Say Y if you want to add support for SoC audio on the
- Marvell Saarb reference platform.
-
-config SND_SOC_TAVOREVB3
- tristate "SoC Audio support for Marvell Tavor EVB3"
- depends on SND_PXA2XX_SOC && MACH_TAVOREVB3
- select MFD_88PM860X
- select SND_PXA_SOC_SSP
- select SND_SOC_88PM860X
- help
- Say Y if you want to add support for SoC audio on the
- Marvell Saarb reference platform.
-
-config SND_SOC_ZYLONITE
- tristate "SoC Audio support for Marvell Zylonite"
- depends on SND_PXA2XX_SOC && MACH_ZYLONITE
- select SND_PXA2XX_SOC_AC97
- select SND_PXA_SOC_SSP
- select SND_SOC_WM9713
- help
- Say Y if you want to add support for SoC audio on the
- Marvell Zylonite reference platform.
-
-config SND_SOC_RAUMFELD
- tristate "SoC Audio support Raumfeld audio adapter"
- depends on SND_PXA2XX_SOC && (MACH_RAUMFELD_SPEAKER || MACH_RAUMFELD_CONNECTOR)
- depends on I2C && SPI_MASTER
- select SND_PXA_SOC_SSP
- select SND_SOC_CS4270
- select SND_SOC_AK4104
- help
- Say Y if you want to add support for SoC audio on Raumfeld devices
-
-config SND_PXA2XX_SOC_HX4700
- tristate "SoC Audio support for HP iPAQ hx4700"
- depends on SND_PXA2XX_SOC && MACH_H4700 && I2C
- select SND_PXA2XX_SOC_I2S
- select SND_SOC_AK4641
- help
- Say Y if you want to add support for SoC audio on the
- HP iPAQ hx4700.
-
-config SND_PXA2XX_SOC_MAGICIAN
- tristate "SoC Audio support for HTC Magician"
- depends on SND_PXA2XX_SOC && MACH_MAGICIAN
- select SND_PXA2XX_SOC_I2S
- select SND_PXA_SOC_SSP
- select SND_SOC_UDA1380
- help
- Say Y if you want to add support for SoC audio on the
- HTC Magician.
-
-config SND_PXA2XX_SOC_MIOA701
- tristate "SoC Audio support for MIO A701"
- depends on SND_PXA2XX_SOC && MACH_MIOA701
- select SND_PXA2XX_SOC_AC97
- select SND_SOC_WM9713
- help
- Say Y if you want to add support for SoC audio on the
- MIO A701.
-
-config SND_PXA2XX_SOC_IMOTE2
- tristate "SoC Audio support for IMote 2"
- depends on SND_PXA2XX_SOC && MACH_INTELMOTE2 && I2C
- select SND_PXA2XX_SOC_I2S
- select SND_SOC_WM8940
- help
- Say Y if you want to add support for SoC audio on the
- IMote 2.
diff --git a/ANDROID_3.4.5/sound/soc/pxa/Makefile b/ANDROID_3.4.5/sound/soc/pxa/Makefile
deleted file mode 100644
index af357623..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/Makefile
+++ /dev/null
@@ -1,49 +0,0 @@
-# PXA Platform Support
-snd-soc-pxa2xx-objs := pxa2xx-pcm.o
-snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o
-snd-soc-pxa2xx-i2s-objs := pxa2xx-i2s.o
-snd-soc-pxa-ssp-objs := pxa-ssp.o
-
-obj-$(CONFIG_SND_PXA2XX_SOC) += snd-soc-pxa2xx.o
-obj-$(CONFIG_SND_PXA2XX_SOC_AC97) += snd-soc-pxa2xx-ac97.o
-obj-$(CONFIG_SND_PXA2XX_SOC_I2S) += snd-soc-pxa2xx-i2s.o
-obj-$(CONFIG_SND_PXA_SOC_SSP) += snd-soc-pxa-ssp.o
-
-# PXA Machine Support
-snd-soc-corgi-objs := corgi.o
-snd-soc-poodle-objs := poodle.o
-snd-soc-tosa-objs := tosa.o
-snd-soc-e740-objs := e740_wm9705.o
-snd-soc-e750-objs := e750_wm9705.o
-snd-soc-e800-objs := e800_wm9712.o
-snd-soc-spitz-objs := spitz.o
-snd-soc-em-x270-objs := em-x270.o
-snd-soc-palm27x-objs := palm27x.o
-snd-soc-saarb-objs := saarb.o
-snd-soc-tavorevb3-objs := tavorevb3.o
-snd-soc-zylonite-objs := zylonite.o
-snd-soc-hx4700-objs := hx4700.o
-snd-soc-magician-objs := magician.o
-snd-soc-mioa701-objs := mioa701_wm9713.o
-snd-soc-z2-objs := z2.o
-snd-soc-imote2-objs := imote2.o
-snd-soc-raumfeld-objs := raumfeld.o
-
-obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o
-obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o
-obj-$(CONFIG_SND_PXA2XX_SOC_TOSA) += snd-soc-tosa.o
-obj-$(CONFIG_SND_PXA2XX_SOC_E740) += snd-soc-e740.o
-obj-$(CONFIG_SND_PXA2XX_SOC_E750) += snd-soc-e750.o
-obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o
-obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o
-obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o
-obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o
-obj-$(CONFIG_SND_PXA2XX_SOC_HX4700) += snd-soc-hx4700.o
-obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o
-obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o
-obj-$(CONFIG_SND_PXA2XX_SOC_Z2) += snd-soc-z2.o
-obj-$(CONFIG_SND_SOC_SAARB) += snd-soc-saarb.o
-obj-$(CONFIG_SND_SOC_TAVOREVB3) += snd-soc-tavorevb3.o
-obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
-obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o
-obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o
diff --git a/ANDROID_3.4.5/sound/soc/pxa/corgi.c b/ANDROID_3.4.5/sound/soc/pxa/corgi.c
deleted file mode 100644
index 863367ad..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/corgi.c
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * corgi.c -- SoC audio for Corgi
- *
- * Copyright 2005 Wolfson Microelectronics PLC.
- * Copyright 2005 Openedhand Ltd.
- *
- * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
- * Richard Purdie <richard@openedhand.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/timer.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/corgi.h>
-#include <mach/audio.h>
-
-#include "../codecs/wm8731.h"
-#include "pxa2xx-i2s.h"
-
-#define CORGI_HP 0
-#define CORGI_MIC 1
-#define CORGI_LINE 2
-#define CORGI_HEADSET 3
-#define CORGI_HP_OFF 4
-#define CORGI_SPK_ON 0
-#define CORGI_SPK_OFF 1
-
- /* audio clock in Hz - rounded from 12.235MHz */
-#define CORGI_AUDIO_CLOCK 12288000
-
-static int corgi_jack_func;
-static int corgi_spk_func;
-
-static void corgi_ext_control(struct snd_soc_dapm_context *dapm)
-{
- /* set up jack connection */
- switch (corgi_jack_func) {
- case CORGI_HP:
- /* set = unmute headphone */
- gpio_set_value(CORGI_GPIO_MUTE_L, 1);
- gpio_set_value(CORGI_GPIO_MUTE_R, 1);
- snd_soc_dapm_disable_pin(dapm, "Mic Jack");
- snd_soc_dapm_disable_pin(dapm, "Line Jack");
- snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_disable_pin(dapm, "Headset Jack");
- break;
- case CORGI_MIC:
- /* reset = mute headphone */
- gpio_set_value(CORGI_GPIO_MUTE_L, 0);
- gpio_set_value(CORGI_GPIO_MUTE_R, 0);
- snd_soc_dapm_enable_pin(dapm, "Mic Jack");
- snd_soc_dapm_disable_pin(dapm, "Line Jack");
- snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_disable_pin(dapm, "Headset Jack");
- break;
- case CORGI_LINE:
- gpio_set_value(CORGI_GPIO_MUTE_L, 0);
- gpio_set_value(CORGI_GPIO_MUTE_R, 0);
- snd_soc_dapm_disable_pin(dapm, "Mic Jack");
- snd_soc_dapm_enable_pin(dapm, "Line Jack");
- snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_disable_pin(dapm, "Headset Jack");
- break;
- case CORGI_HEADSET:
- gpio_set_value(CORGI_GPIO_MUTE_L, 0);
- gpio_set_value(CORGI_GPIO_MUTE_R, 1);
- snd_soc_dapm_enable_pin(dapm, "Mic Jack");
- snd_soc_dapm_disable_pin(dapm, "Line Jack");
- snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_enable_pin(dapm, "Headset Jack");
- break;
- }
-
- if (corgi_spk_func == CORGI_SPK_ON)
- snd_soc_dapm_enable_pin(dapm, "Ext Spk");
- else
- snd_soc_dapm_disable_pin(dapm, "Ext Spk");
-
- /* signal a DAPM event */
- snd_soc_dapm_sync(dapm);
-}
-
-static int corgi_startup(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
-
- mutex_lock(&codec->mutex);
-
- /* check the jack status at stream startup */
- corgi_ext_control(&codec->dapm);
-
- mutex_unlock(&codec->mutex);
-
- return 0;
-}
-
-/* we need to unmute the HP at shutdown as the mute burns power on corgi */
-static void corgi_shutdown(struct snd_pcm_substream *substream)
-{
- /* set = unmute headphone */
- gpio_set_value(CORGI_GPIO_MUTE_L, 1);
- gpio_set_value(CORGI_GPIO_MUTE_R, 1);
-}
-
-static int corgi_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- unsigned int clk = 0;
- int ret = 0;
-
- switch (params_rate(params)) {
- case 8000:
- case 16000:
- case 48000:
- case 96000:
- clk = 12288000;
- break;
- case 11025:
- case 22050:
- case 44100:
- clk = 11289600;
- break;
- }
-
- /* set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL, clk,
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- /* set the I2S system clock as input (unused) */
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops corgi_ops = {
- .startup = corgi_startup,
- .hw_params = corgi_hw_params,
- .shutdown = corgi_shutdown,
-};
-
-static int corgi_get_jack(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = corgi_jack_func;
- return 0;
-}
-
-static int corgi_set_jack(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
-
- if (corgi_jack_func == ucontrol->value.integer.value[0])
- return 0;
-
- corgi_jack_func = ucontrol->value.integer.value[0];
- corgi_ext_control(&card->dapm);
- return 1;
-}
-
-static int corgi_get_spk(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = corgi_spk_func;
- return 0;
-}
-
-static int corgi_set_spk(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
-
- if (corgi_spk_func == ucontrol->value.integer.value[0])
- return 0;
-
- corgi_spk_func = ucontrol->value.integer.value[0];
- corgi_ext_control(&card->dapm);
- return 1;
-}
-
-static int corgi_amp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- gpio_set_value(CORGI_GPIO_APM_ON, SND_SOC_DAPM_EVENT_ON(event));
- return 0;
-}
-
-static int corgi_mic_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- gpio_set_value(CORGI_GPIO_MIC_BIAS, SND_SOC_DAPM_EVENT_ON(event));
- return 0;
-}
-
-/* corgi machine dapm widgets */
-static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = {
-SND_SOC_DAPM_HP("Headphone Jack", NULL),
-SND_SOC_DAPM_MIC("Mic Jack", corgi_mic_event),
-SND_SOC_DAPM_SPK("Ext Spk", corgi_amp_event),
-SND_SOC_DAPM_LINE("Line Jack", NULL),
-SND_SOC_DAPM_HP("Headset Jack", NULL),
-};
-
-/* Corgi machine audio map (connections to the codec pins) */
-static const struct snd_soc_dapm_route corgi_audio_map[] = {
-
- /* headset Jack - in = micin, out = LHPOUT*/
- {"Headset Jack", NULL, "LHPOUT"},
-
- /* headphone connected to LHPOUT1, RHPOUT1 */
- {"Headphone Jack", NULL, "LHPOUT"},
- {"Headphone Jack", NULL, "RHPOUT"},
-
- /* speaker connected to LOUT, ROUT */
- {"Ext Spk", NULL, "ROUT"},
- {"Ext Spk", NULL, "LOUT"},
-
- /* mic is connected to MICIN (via right channel of headphone jack) */
- {"MICIN", NULL, "Mic Jack"},
-
- /* Same as the above but no mic bias for line signals */
- {"MICIN", NULL, "Line Jack"},
-};
-
-static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset",
- "Off"};
-static const char *spk_function[] = {"On", "Off"};
-static const struct soc_enum corgi_enum[] = {
- SOC_ENUM_SINGLE_EXT(5, jack_function),
- SOC_ENUM_SINGLE_EXT(2, spk_function),
-};
-
-static const struct snd_kcontrol_new wm8731_corgi_controls[] = {
- SOC_ENUM_EXT("Jack Function", corgi_enum[0], corgi_get_jack,
- corgi_set_jack),
- SOC_ENUM_EXT("Speaker Function", corgi_enum[1], corgi_get_spk,
- corgi_set_spk),
-};
-
-/*
- * Logic for a wm8731 as connected on a Sharp SL-C7x0 Device
- */
-static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_nc_pin(dapm, "LLINEIN");
- snd_soc_dapm_nc_pin(dapm, "RLINEIN");
-
- return 0;
-}
-
-/* corgi digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link corgi_dai = {
- .name = "WM8731",
- .stream_name = "WM8731",
- .cpu_dai_name = "pxa2xx-i2s",
- .codec_dai_name = "wm8731-hifi",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "wm8731.0-001b",
- .init = corgi_wm8731_init,
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS,
- .ops = &corgi_ops,
-};
-
-/* corgi audio machine driver */
-static struct snd_soc_card corgi = {
- .name = "Corgi",
- .owner = THIS_MODULE,
- .dai_link = &corgi_dai,
- .num_links = 1,
-
- .controls = wm8731_corgi_controls,
- .num_controls = ARRAY_SIZE(wm8731_corgi_controls),
- .dapm_widgets = wm8731_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets),
- .dapm_routes = corgi_audio_map,
- .num_dapm_routes = ARRAY_SIZE(corgi_audio_map),
-};
-
-static int __devinit corgi_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &corgi;
- int ret;
-
- card->dev = &pdev->dev;
-
- ret = snd_soc_register_card(card);
- if (ret)
- dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
- ret);
- return ret;
-}
-
-static int __devexit corgi_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- snd_soc_unregister_card(card);
- return 0;
-}
-
-static struct platform_driver corgi_driver = {
- .driver = {
- .name = "corgi-audio",
- .owner = THIS_MODULE,
- },
- .probe = corgi_probe,
- .remove = __devexit_p(corgi_remove),
-};
-
-module_platform_driver(corgi_driver);
-
-/* Module information */
-MODULE_AUTHOR("Richard Purdie");
-MODULE_DESCRIPTION("ALSA SoC Corgi");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:corgi-audio");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/e740_wm9705.c b/ANDROID_3.4.5/sound/soc/pxa/e740_wm9705.c
deleted file mode 100644
index 7b1bc239..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/e740_wm9705.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * e740-wm9705.c -- SoC audio for e740
- *
- * Copyright 2007 (c) Ian Molton <spyro@f2s.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; version 2 ONLY.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/gpio.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <mach/audio.h>
-#include <mach/eseries-gpio.h>
-
-#include <asm/mach-types.h>
-
-#include "../codecs/wm9705.h"
-#include "pxa2xx-ac97.h"
-
-
-#define E740_AUDIO_OUT 1
-#define E740_AUDIO_IN 2
-
-static int e740_audio_power;
-
-static void e740_sync_audio_power(int status)
-{
- gpio_set_value(GPIO_E740_WM9705_nAVDD2, !status);
- gpio_set_value(GPIO_E740_AMP_ON, (status & E740_AUDIO_OUT) ? 1 : 0);
- gpio_set_value(GPIO_E740_MIC_ON, (status & E740_AUDIO_IN) ? 1 : 0);
-}
-
-static int e740_mic_amp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- if (event & SND_SOC_DAPM_PRE_PMU)
- e740_audio_power |= E740_AUDIO_IN;
- else if (event & SND_SOC_DAPM_POST_PMD)
- e740_audio_power &= ~E740_AUDIO_IN;
-
- e740_sync_audio_power(e740_audio_power);
-
- return 0;
-}
-
-static int e740_output_amp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- if (event & SND_SOC_DAPM_PRE_PMU)
- e740_audio_power |= E740_AUDIO_OUT;
- else if (event & SND_SOC_DAPM_POST_PMD)
- e740_audio_power &= ~E740_AUDIO_OUT;
-
- e740_sync_audio_power(e740_audio_power);
-
- return 0;
-}
-
-static const struct snd_soc_dapm_widget e740_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_SPK("Speaker", NULL),
- SND_SOC_DAPM_MIC("Mic (Internal)", NULL),
- SND_SOC_DAPM_PGA_E("Output Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
- e740_output_amp_event, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_PGA_E("Mic Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
- e740_mic_amp_event, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMD),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- {"Output Amp", NULL, "LOUT"},
- {"Output Amp", NULL, "ROUT"},
- {"Output Amp", NULL, "MONOOUT"},
-
- {"Speaker", NULL, "Output Amp"},
- {"Headphone Jack", NULL, "Output Amp"},
-
- {"MIC1", NULL, "Mic Amp"},
- {"Mic Amp", NULL, "Mic (Internal)"},
-};
-
-static int e740_ac97_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_nc_pin(dapm, "HPOUTL");
- snd_soc_dapm_nc_pin(dapm, "HPOUTR");
- snd_soc_dapm_nc_pin(dapm, "PHONE");
- snd_soc_dapm_nc_pin(dapm, "LINEINL");
- snd_soc_dapm_nc_pin(dapm, "LINEINR");
- snd_soc_dapm_nc_pin(dapm, "CDINL");
- snd_soc_dapm_nc_pin(dapm, "CDINR");
- snd_soc_dapm_nc_pin(dapm, "PCBEEP");
- snd_soc_dapm_nc_pin(dapm, "MIC2");
-
- snd_soc_dapm_new_controls(dapm, e740_dapm_widgets,
- ARRAY_SIZE(e740_dapm_widgets));
-
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
- return 0;
-}
-
-static struct snd_soc_dai_link e740_dai[] = {
- {
- .name = "AC97",
- .stream_name = "AC97 HiFi",
- .cpu_dai_name = "pxa2xx-ac97",
- .codec_dai_name = "wm9705-hifi",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "wm9705-codec",
- .init = e740_ac97_init,
- },
- {
- .name = "AC97 Aux",
- .stream_name = "AC97 Aux",
- .cpu_dai_name = "pxa2xx-ac97-aux",
- .codec_dai_name = "wm9705-aux",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "wm9705-codec",
- },
-};
-
-static struct snd_soc_card e740 = {
- .name = "Toshiba e740",
- .owner = THIS_MODULE,
- .dai_link = e740_dai,
- .num_links = ARRAY_SIZE(e740_dai),
-};
-
-static struct gpio e740_audio_gpios[] = {
- { GPIO_E740_MIC_ON, GPIOF_OUT_INIT_LOW, "Mic amp" },
- { GPIO_E740_AMP_ON, GPIOF_OUT_INIT_LOW, "Output amp" },
- { GPIO_E740_WM9705_nAVDD2, GPIOF_OUT_INIT_HIGH, "Audio power" },
-};
-
-static int __devinit e740_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &e740;
- int ret;
-
- ret = gpio_request_array(e740_audio_gpios,
- ARRAY_SIZE(e740_audio_gpios));
- if (ret)
- return ret;
-
- card->dev = &pdev->dev;
-
- ret = snd_soc_register_card(card);
- if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
- ret);
- gpio_free_array(e740_audio_gpios, ARRAY_SIZE(e740_audio_gpios));
- }
- return ret;
-}
-
-static int __devexit e740_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- gpio_free_array(e740_audio_gpios, ARRAY_SIZE(e740_audio_gpios));
- snd_soc_unregister_card(card);
- return 0;
-}
-
-static struct platform_driver e740_driver = {
- .driver = {
- .name = "e740-audio",
- .owner = THIS_MODULE,
- },
- .probe = e740_probe,
- .remove = __devexit_p(e740_remove),
-};
-
-module_platform_driver(e740_driver);
-
-/* Module information */
-MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
-MODULE_DESCRIPTION("ALSA SoC driver for e740");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:e740-audio");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/e750_wm9705.c b/ANDROID_3.4.5/sound/soc/pxa/e750_wm9705.c
deleted file mode 100644
index 47b89d71..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/e750_wm9705.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * e750-wm9705.c -- SoC audio for e750
- *
- * Copyright 2007 (c) Ian Molton <spyro@f2s.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; version 2 ONLY.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/gpio.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <mach/audio.h>
-#include <mach/eseries-gpio.h>
-
-#include <asm/mach-types.h>
-
-#include "../codecs/wm9705.h"
-#include "pxa2xx-ac97.h"
-
-static int e750_spk_amp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- if (event & SND_SOC_DAPM_PRE_PMU)
- gpio_set_value(GPIO_E750_SPK_AMP_OFF, 0);
- else if (event & SND_SOC_DAPM_POST_PMD)
- gpio_set_value(GPIO_E750_SPK_AMP_OFF, 1);
-
- return 0;
-}
-
-static int e750_hp_amp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- if (event & SND_SOC_DAPM_PRE_PMU)
- gpio_set_value(GPIO_E750_HP_AMP_OFF, 0);
- else if (event & SND_SOC_DAPM_POST_PMD)
- gpio_set_value(GPIO_E750_HP_AMP_OFF, 1);
-
- return 0;
-}
-
-static const struct snd_soc_dapm_widget e750_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_SPK("Speaker", NULL),
- SND_SOC_DAPM_MIC("Mic (Internal)", NULL),
- SND_SOC_DAPM_PGA_E("Headphone Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
- e750_hp_amp_event, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_PGA_E("Speaker Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
- e750_spk_amp_event, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMD),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- {"Headphone Amp", NULL, "HPOUTL"},
- {"Headphone Amp", NULL, "HPOUTR"},
- {"Headphone Jack", NULL, "Headphone Amp"},
-
- {"Speaker Amp", NULL, "MONOOUT"},
- {"Speaker", NULL, "Speaker Amp"},
-
- {"MIC1", NULL, "Mic (Internal)"},
-};
-
-static int e750_ac97_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_nc_pin(dapm, "LOUT");
- snd_soc_dapm_nc_pin(dapm, "ROUT");
- snd_soc_dapm_nc_pin(dapm, "PHONE");
- snd_soc_dapm_nc_pin(dapm, "LINEINL");
- snd_soc_dapm_nc_pin(dapm, "LINEINR");
- snd_soc_dapm_nc_pin(dapm, "CDINL");
- snd_soc_dapm_nc_pin(dapm, "CDINR");
- snd_soc_dapm_nc_pin(dapm, "PCBEEP");
- snd_soc_dapm_nc_pin(dapm, "MIC2");
-
- snd_soc_dapm_new_controls(dapm, e750_dapm_widgets,
- ARRAY_SIZE(e750_dapm_widgets));
-
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
- return 0;
-}
-
-static struct snd_soc_dai_link e750_dai[] = {
- {
- .name = "AC97",
- .stream_name = "AC97 HiFi",
- .cpu_dai_name = "pxa2xx-ac97",
- .codec_dai_name = "wm9705-hifi",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "wm9705-codec",
- .init = e750_ac97_init,
- /* use ops to check startup state */
- },
- {
- .name = "AC97 Aux",
- .stream_name = "AC97 Aux",
- .cpu_dai_name = "pxa2xx-ac97-aux",
- .codec_dai_name ="wm9705-aux",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "wm9705-codec",
- },
-};
-
-static struct snd_soc_card e750 = {
- .name = "Toshiba e750",
- .owner = THIS_MODULE,
- .dai_link = e750_dai,
- .num_links = ARRAY_SIZE(e750_dai),
-};
-
-static struct gpio e750_audio_gpios[] = {
- { GPIO_E750_HP_AMP_OFF, GPIOF_OUT_INIT_HIGH, "Headphone amp" },
- { GPIO_E750_SPK_AMP_OFF, GPIOF_OUT_INIT_HIGH, "Speaker amp" },
-};
-
-static int __devinit e750_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &e750;
- int ret;
-
- ret = gpio_request_array(e750_audio_gpios,
- ARRAY_SIZE(e750_audio_gpios));
- if (ret)
- return ret;
-
- card->dev = &pdev->dev;
-
- ret = snd_soc_register_card(card);
- if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
- ret);
- gpio_free_array(e750_audio_gpios, ARRAY_SIZE(e750_audio_gpios));
- }
- return ret;
-}
-
-static int __devexit e750_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- gpio_free_array(e750_audio_gpios, ARRAY_SIZE(e750_audio_gpios));
- snd_soc_unregister_card(card);
- return 0;
-}
-
-static struct platform_driver e750_driver = {
- .driver = {
- .name = "e750-audio",
- .owner = THIS_MODULE,
- },
- .probe = e750_probe,
- .remove = __devexit_p(e750_remove),
-};
-
-module_platform_driver(e750_driver);
-
-/* Module information */
-MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
-MODULE_DESCRIPTION("ALSA SoC driver for e750");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:e750-audio");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/e800_wm9712.c b/ANDROID_3.4.5/sound/soc/pxa/e800_wm9712.c
deleted file mode 100644
index ea9707ec..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/e800_wm9712.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * e800-wm9712.c -- SoC audio for e800
- *
- * Copyright 2007 (c) Ian Molton <spyro@f2s.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; version 2 ONLY.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/gpio.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/audio.h>
-#include <mach/eseries-gpio.h>
-
-#include "../codecs/wm9712.h"
-#include "pxa2xx-ac97.h"
-
-static int e800_spk_amp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- if (event & SND_SOC_DAPM_PRE_PMU)
- gpio_set_value(GPIO_E800_SPK_AMP_ON, 1);
- else if (event & SND_SOC_DAPM_POST_PMD)
- gpio_set_value(GPIO_E800_SPK_AMP_ON, 0);
-
- return 0;
-}
-
-static int e800_hp_amp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- if (event & SND_SOC_DAPM_PRE_PMU)
- gpio_set_value(GPIO_E800_HP_AMP_OFF, 0);
- else if (event & SND_SOC_DAPM_POST_PMD)
- gpio_set_value(GPIO_E800_HP_AMP_OFF, 1);
-
- return 0;
-}
-
-static const struct snd_soc_dapm_widget e800_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_MIC("Mic (Internal1)", NULL),
- SND_SOC_DAPM_MIC("Mic (Internal2)", NULL),
- SND_SOC_DAPM_SPK("Speaker", NULL),
- SND_SOC_DAPM_PGA_E("Headphone Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
- e800_hp_amp_event, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_PGA_E("Speaker Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
- e800_spk_amp_event, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMD),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- {"Headphone Jack", NULL, "HPOUTL"},
- {"Headphone Jack", NULL, "HPOUTR"},
- {"Headphone Jack", NULL, "Headphone Amp"},
-
- {"Speaker Amp", NULL, "MONOOUT"},
- {"Speaker", NULL, "Speaker Amp"},
-
- {"MIC1", NULL, "Mic (Internal1)"},
- {"MIC2", NULL, "Mic (Internal2)"},
-};
-
-static int e800_ac97_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_new_controls(dapm, e800_dapm_widgets,
- ARRAY_SIZE(e800_dapm_widgets));
-
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
- return 0;
-}
-
-static struct snd_soc_dai_link e800_dai[] = {
- {
- .name = "AC97",
- .stream_name = "AC97 HiFi",
- .cpu_dai_name = "pxa2xx-ac97",
- .codec_dai_name = "wm9712-hifi",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "wm9712-codec",
- .init = e800_ac97_init,
- },
- {
- .name = "AC97 Aux",
- .stream_name = "AC97 Aux",
- .cpu_dai_name = "pxa2xx-ac97-aux",
- .codec_dai_name ="wm9712-aux",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "wm9712-codec",
- },
-};
-
-static struct snd_soc_card e800 = {
- .name = "Toshiba e800",
- .owner = THIS_MODULE,
- .dai_link = e800_dai,
- .num_links = ARRAY_SIZE(e800_dai),
-};
-
-static struct gpio e800_audio_gpios[] = {
- { GPIO_E800_SPK_AMP_ON, GPIOF_OUT_INIT_HIGH, "Headphone amp" },
- { GPIO_E800_HP_AMP_OFF, GPIOF_OUT_INIT_HIGH, "Speaker amp" },
-};
-
-static int __devinit e800_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &e800;
- int ret;
-
- ret = gpio_request_array(e800_audio_gpios,
- ARRAY_SIZE(e800_audio_gpios));
- if (ret)
- return ret;
-
- card->dev = &pdev->dev;
-
- ret = snd_soc_register_card(card);
- if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
- ret);
- gpio_free_array(e800_audio_gpios, ARRAY_SIZE(e800_audio_gpios));
- }
- return ret;
-}
-
-static int __devexit e800_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- gpio_free_array(e800_audio_gpios, ARRAY_SIZE(e800_audio_gpios));
- snd_soc_unregister_card(card);
- return 0;
-}
-
-static struct platform_driver e800_driver = {
- .driver = {
- .name = "e800-audio",
- .owner = THIS_MODULE,
- },
- .probe = e800_probe,
- .remove = __devexit_p(e800_remove),
-};
-
-module_platform_driver(e800_driver);
-
-/* Module information */
-MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
-MODULE_DESCRIPTION("ALSA SoC driver for e800");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:e800-audio");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/em-x270.c b/ANDROID_3.4.5/sound/soc/pxa/em-x270.c
deleted file mode 100644
index 64743a05..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/em-x270.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * SoC audio driver for EM-X270, eXeda and CM-X300
- *
- * Copyright 2007, 2009 CompuLab, Ltd.
- *
- * Author: Mike Rapoport <mike@compulab.co.il>
- *
- * Copied from tosa.c:
- * Copyright 2005 Wolfson Microelectronics PLC.
- * Copyright 2005 Openedhand Ltd.
- *
- * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
- * Richard Purdie <richard@openedhand.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/audio.h>
-
-#include "../codecs/wm9712.h"
-#include "pxa2xx-ac97.h"
-
-static struct snd_soc_dai_link em_x270_dai[] = {
- {
- .name = "AC97",
- .stream_name = "AC97 HiFi",
- .cpu_dai_name = "pxa2xx-ac97",
- .codec_dai_name = "wm9712-hifi",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "wm9712-codec",
- },
- {
- .name = "AC97 Aux",
- .stream_name = "AC97 Aux",
- .cpu_dai_name = "pxa2xx-ac97-aux",
- .codec_dai_name ="wm9712-aux",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "wm9712-codec",
- },
-};
-
-static struct snd_soc_card em_x270 = {
- .name = "EM-X270",
- .owner = THIS_MODULE,
- .dai_link = em_x270_dai,
- .num_links = ARRAY_SIZE(em_x270_dai),
-};
-
-static struct platform_device *em_x270_snd_device;
-
-static int __init em_x270_init(void)
-{
- int ret;
-
- if (!(machine_is_em_x270() || machine_is_exeda()
- || machine_is_cm_x300()))
- return -ENODEV;
-
- em_x270_snd_device = platform_device_alloc("soc-audio", -1);
- if (!em_x270_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(em_x270_snd_device, &em_x270);
- ret = platform_device_add(em_x270_snd_device);
-
- if (ret)
- platform_device_put(em_x270_snd_device);
-
- return ret;
-}
-
-static void __exit em_x270_exit(void)
-{
- platform_device_unregister(em_x270_snd_device);
-}
-
-module_init(em_x270_init);
-module_exit(em_x270_exit);
-
-/* Module information */
-MODULE_AUTHOR("Mike Rapoport");
-MODULE_DESCRIPTION("ALSA SoC EM-X270, eXeda and CM-X300");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/hx4700.c b/ANDROID_3.4.5/sound/soc/pxa/hx4700.c
deleted file mode 100644
index 2a342c92..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/hx4700.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * SoC audio for HP iPAQ hx4700
- *
- * Copyright (c) 2009 Philipp Zabel
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-
-#include <sound/core.h>
-#include <sound/jack.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <mach/hx4700.h>
-#include <asm/mach-types.h>
-#include "pxa2xx-i2s.h"
-
-#include "../codecs/ak4641.h"
-
-static struct snd_soc_jack hs_jack;
-
-/* Headphones jack detection DAPM pin */
-static struct snd_soc_jack_pin hs_jack_pin[] = {
- {
- .pin = "Headphone Jack",
- .mask = SND_JACK_HEADPHONE,
- },
- {
- .pin = "Speaker",
- /* disable speaker when hp jack is inserted */
- .mask = SND_JACK_HEADPHONE,
- .invert = 1,
- },
-};
-
-/* Headphones jack detection GPIO */
-static struct snd_soc_jack_gpio hs_jack_gpio = {
- .gpio = GPIO75_HX4700_EARPHONE_nDET,
- .invert = true,
- .name = "hp-gpio",
- .report = SND_JACK_HEADPHONE,
- .debounce_time = 200,
-};
-
-/*
- * iPAQ hx4700 uses I2S for capture and playback.
- */
-static int hx4700_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
-
- /* set the I2S system clock as output */
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
- SND_SOC_CLOCK_OUT);
- if (ret < 0)
- return ret;
-
- /* inform codec driver about clock freq *
- * (PXA I2S always uses divider 256) */
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, 256 * params_rate(params),
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops hx4700_ops = {
- .hw_params = hx4700_hw_params,
-};
-
-static int hx4700_spk_power(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- gpio_set_value(GPIO107_HX4700_SPK_nSD, !!SND_SOC_DAPM_EVENT_ON(event));
- return 0;
-}
-
-static int hx4700_hp_power(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- gpio_set_value(GPIO92_HX4700_HP_DRIVER, !!SND_SOC_DAPM_EVENT_ON(event));
- return 0;
-}
-
-/* hx4700 machine dapm widgets */
-static const struct snd_soc_dapm_widget hx4700_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Jack", hx4700_hp_power),
- SND_SOC_DAPM_SPK("Speaker", hx4700_spk_power),
- SND_SOC_DAPM_MIC("Built-in Microphone", NULL),
-};
-
-/* hx4700 machine audio_map */
-static const struct snd_soc_dapm_route hx4700_audio_map[] = {
-
- /* Headphone connected to LOUT, ROUT */
- {"Headphone Jack", NULL, "LOUT"},
- {"Headphone Jack", NULL, "ROUT"},
-
- /* Speaker connected to MOUT2 */
- {"Speaker", NULL, "MOUT2"},
-
- /* Microphone connected to MICIN */
- {"MICIN", NULL, "Built-in Microphone"},
- {"AIN", NULL, "MICOUT"},
-};
-
-/*
- * Logic for a ak4641 as connected on a HP iPAQ hx4700
- */
-static int hx4700_ak4641_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int err;
-
- /* NC codec pins */
- /* FIXME: is anything connected here? */
- snd_soc_dapm_nc_pin(dapm, "MOUT1");
- snd_soc_dapm_nc_pin(dapm, "MICEXT");
- snd_soc_dapm_nc_pin(dapm, "AUX");
-
- /* Jack detection API stuff */
- err = snd_soc_jack_new(codec, "Headphone Jack",
- SND_JACK_HEADPHONE, &hs_jack);
- if (err)
- return err;
-
- err = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pin),
- hs_jack_pin);
- if (err)
- return err;
-
- err = snd_soc_jack_add_gpios(&hs_jack, 1, &hs_jack_gpio);
-
- return err;
-}
-
-/* hx4700 digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link hx4700_dai = {
- .name = "ak4641",
- .stream_name = "AK4641",
- .cpu_dai_name = "pxa2xx-i2s",
- .codec_dai_name = "ak4641-hifi",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "ak4641.0-0012",
- .init = hx4700_ak4641_init,
- .dai_fmt = SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS,
- .ops = &hx4700_ops,
-};
-
-/* hx4700 audio machine driver */
-static struct snd_soc_card snd_soc_card_hx4700 = {
- .name = "iPAQ hx4700",
- .owner = THIS_MODULE,
- .dai_link = &hx4700_dai,
- .num_links = 1,
- .dapm_widgets = hx4700_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(hx4700_dapm_widgets),
- .dapm_routes = hx4700_audio_map,
- .num_dapm_routes = ARRAY_SIZE(hx4700_audio_map),
-};
-
-static struct gpio hx4700_audio_gpios[] = {
- { GPIO107_HX4700_SPK_nSD, GPIOF_OUT_INIT_HIGH, "SPK_POWER" },
- { GPIO92_HX4700_HP_DRIVER, GPIOF_OUT_INIT_LOW, "EP_POWER" },
-};
-
-static int __devinit hx4700_audio_probe(struct platform_device *pdev)
-{
- int ret;
-
- if (!machine_is_h4700())
- return -ENODEV;
-
- ret = gpio_request_array(hx4700_audio_gpios,
- ARRAY_SIZE(hx4700_audio_gpios));
- if (ret)
- return ret;
-
- snd_soc_card_hx4700.dev = &pdev->dev;
- ret = snd_soc_register_card(&snd_soc_card_hx4700);
- if (ret)
- gpio_free_array(hx4700_audio_gpios,
- ARRAY_SIZE(hx4700_audio_gpios));
-
- return ret;
-}
-
-static int __devexit hx4700_audio_remove(struct platform_device *pdev)
-{
- snd_soc_jack_free_gpios(&hs_jack, 1, &hs_jack_gpio);
- snd_soc_unregister_card(&snd_soc_card_hx4700);
-
- gpio_set_value(GPIO92_HX4700_HP_DRIVER, 0);
- gpio_set_value(GPIO107_HX4700_SPK_nSD, 0);
-
- gpio_free_array(hx4700_audio_gpios, ARRAY_SIZE(hx4700_audio_gpios));
- return 0;
-}
-
-static struct platform_driver hx4700_audio_driver = {
- .driver = {
- .name = "hx4700-audio",
- .owner = THIS_MODULE,
- .pm = &snd_soc_pm_ops,
- },
- .probe = hx4700_audio_probe,
- .remove = __devexit_p(hx4700_audio_remove),
-};
-
-module_platform_driver(hx4700_audio_driver);
-
-MODULE_AUTHOR("Philipp Zabel");
-MODULE_DESCRIPTION("ALSA SoC iPAQ hx4700");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:hx4700-audio");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/imote2.c b/ANDROID_3.4.5/sound/soc/pxa/imote2.c
deleted file mode 100644
index b93dafd3..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/imote2.c
+++ /dev/null
@@ -1,104 +0,0 @@
-
-#include <linux/module.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-
-#include "../codecs/wm8940.h"
-#include "pxa2xx-i2s.h"
-
-static int imote2_asoc_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- unsigned int clk = 0;
- int ret;
-
- switch (params_rate(params)) {
- case 8000:
- case 16000:
- case 48000:
- case 96000:
- clk = 12288000;
- break;
- case 11025:
- case 22050:
- case 44100:
- clk = 11289600;
- break;
- }
-
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- /* set the I2S system clock as input (unused) */
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, clk,
- SND_SOC_CLOCK_OUT);
-
- return ret;
-}
-
-static struct snd_soc_ops imote2_asoc_ops = {
- .hw_params = imote2_asoc_hw_params,
-};
-
-static struct snd_soc_dai_link imote2_dai = {
- .name = "WM8940",
- .stream_name = "WM8940",
- .cpu_dai_name = "pxa2xx-i2s",
- .codec_dai_name = "wm8940-hifi",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "wm8940-codec.0-0034",
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS,
- .ops = &imote2_asoc_ops,
-};
-
-static struct snd_soc_card imote2 = {
- .name = "Imote2",
- .owner = THIS_MODULE,
- .dai_link = &imote2_dai,
- .num_links = 1,
-};
-
-static int __devinit imote2_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &imote2;
- int ret;
-
- card->dev = &pdev->dev;
-
- ret = snd_soc_register_card(card);
- if (ret)
- dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
- ret);
- return ret;
-}
-
-static int __devexit imote2_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- snd_soc_unregister_card(card);
- return 0;
-}
-
-static struct platform_driver imote2_driver = {
- .driver = {
- .name = "imote2-audio",
- .owner = THIS_MODULE,
- },
- .probe = imote2_probe,
- .remove = __devexit_p(imote2_remove),
-};
-
-module_platform_driver(imote2_driver);
-
-MODULE_AUTHOR("Jonathan Cameron");
-MODULE_DESCRIPTION("ALSA SoC Imote 2");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:imote2-audio");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/magician.c b/ANDROID_3.4.5/sound/soc/pxa/magician.c
deleted file mode 100644
index aace19e0..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/magician.c
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * SoC audio for HTC Magician
- *
- * Copyright (c) 2006 Philipp Zabel <philipp.zabel@gmail.com>
- *
- * based on spitz.c,
- * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
- * Richard Purdie <richard@openedhand.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/uda1380.h>
-
-#include <mach/magician.h>
-#include <asm/mach-types.h>
-#include "../codecs/uda1380.h"
-#include "pxa2xx-i2s.h"
-#include "pxa-ssp.h"
-
-#define MAGICIAN_MIC 0
-#define MAGICIAN_MIC_EXT 1
-
-static int magician_hp_switch;
-static int magician_spk_switch = 1;
-static int magician_in_sel = MAGICIAN_MIC;
-
-static void magician_ext_control(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- if (magician_spk_switch)
- snd_soc_dapm_enable_pin(dapm, "Speaker");
- else
- snd_soc_dapm_disable_pin(dapm, "Speaker");
- if (magician_hp_switch)
- snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
- else
- snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
-
- switch (magician_in_sel) {
- case MAGICIAN_MIC:
- snd_soc_dapm_disable_pin(dapm, "Headset Mic");
- snd_soc_dapm_enable_pin(dapm, "Call Mic");
- break;
- case MAGICIAN_MIC_EXT:
- snd_soc_dapm_disable_pin(dapm, "Call Mic");
- snd_soc_dapm_enable_pin(dapm, "Headset Mic");
- break;
- }
-
- snd_soc_dapm_sync(dapm);
-}
-
-static int magician_startup(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
-
- mutex_lock(&codec->mutex);
-
- /* check the jack status at stream startup */
- magician_ext_control(codec);
-
- mutex_unlock(&codec->mutex);
-
- return 0;
-}
-
-/*
- * Magician uses SSP port for playback.
- */
-static int magician_playback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- unsigned int acps, acds, width;
- unsigned int div4 = PXA_SSP_CLK_SCDB_4;
- int ret = 0;
-
- width = snd_pcm_format_physical_width(params_format(params));
-
- /*
- * rate = SSPSCLK / (2 * width(16 or 32))
- * SSPSCLK = (ACPS / ACDS) / SSPSCLKDIV(div4 or div1)
- */
- switch (params_rate(params)) {
- case 8000:
- /* off by a factor of 2: bug in the PXA27x audio clock? */
- acps = 32842000;
- switch (width) {
- case 16:
- /* 513156 Hz ~= _2_ * 8000 Hz * 32 (+0.23%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_16;
- break;
- default: /* 32 */
- /* 1026312 Hz ~= _2_ * 8000 Hz * 64 (+0.23%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_8;
- }
- break;
- case 11025:
- acps = 5622000;
- switch (width) {
- case 16:
- /* 351375 Hz ~= 11025 Hz * 32 (-0.41%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_4;
- break;
- default: /* 32 */
- /* 702750 Hz ~= 11025 Hz * 64 (-0.41%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_2;
- }
- break;
- case 22050:
- acps = 5622000;
- switch (width) {
- case 16:
- /* 702750 Hz ~= 22050 Hz * 32 (-0.41%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_2;
- break;
- default: /* 32 */
- /* 1405500 Hz ~= 22050 Hz * 64 (-0.41%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_1;
- }
- break;
- case 44100:
- acps = 5622000;
- switch (width) {
- case 16:
- /* 1405500 Hz ~= 44100 Hz * 32 (-0.41%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_2;
- break;
- default: /* 32 */
- /* 2811000 Hz ~= 44100 Hz * 64 (-0.41%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_1;
- }
- break;
- case 48000:
- acps = 12235000;
- switch (width) {
- case 16:
- /* 1529375 Hz ~= 48000 Hz * 32 (-0.44%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_2;
- break;
- default: /* 32 */
- /* 3058750 Hz ~= 48000 Hz * 64 (-0.44%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_1;
- }
- break;
- case 96000:
- default:
- acps = 12235000;
- switch (width) {
- case 16:
- /* 3058750 Hz ~= 96000 Hz * 32 (-0.44%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_1;
- break;
- default: /* 32 */
- /* 6117500 Hz ~= 96000 Hz * 64 (-0.44%) */
- acds = PXA_SSP_CLK_AUDIO_DIV_2;
- div4 = PXA_SSP_CLK_SCDB_1;
- break;
- }
- break;
- }
-
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_MSB |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
- SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_tdm_slot(cpu_dai, 1, 0, 1, width);
- if (ret < 0)
- return ret;
-
- /* set audio clock as clock source */
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0,
- SND_SOC_CLOCK_OUT);
- if (ret < 0)
- return ret;
-
- /* set the SSP audio system clock ACDS divider */
- ret = snd_soc_dai_set_clkdiv(cpu_dai,
- PXA_SSP_AUDIO_DIV_ACDS, acds);
- if (ret < 0)
- return ret;
-
- /* set the SSP audio system clock SCDB divider4 */
- ret = snd_soc_dai_set_clkdiv(cpu_dai,
- PXA_SSP_AUDIO_DIV_SCDB, div4);
- if (ret < 0)
- return ret;
-
- /* set SSP audio pll clock */
- ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, acps);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-/*
- * Magician uses I2S for capture.
- */
-static int magician_capture_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
-
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai,
- SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai,
- SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* set the I2S system clock as output */
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
- SND_SOC_CLOCK_OUT);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops magician_capture_ops = {
- .startup = magician_startup,
- .hw_params = magician_capture_hw_params,
-};
-
-static struct snd_soc_ops magician_playback_ops = {
- .startup = magician_startup,
- .hw_params = magician_playback_hw_params,
-};
-
-static int magician_get_hp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = magician_hp_switch;
- return 0;
-}
-
-static int magician_set_hp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-
- if (magician_hp_switch == ucontrol->value.integer.value[0])
- return 0;
-
- magician_hp_switch = ucontrol->value.integer.value[0];
- magician_ext_control(codec);
- return 1;
-}
-
-static int magician_get_spk(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = magician_spk_switch;
- return 0;
-}
-
-static int magician_set_spk(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-
- if (magician_spk_switch == ucontrol->value.integer.value[0])
- return 0;
-
- magician_spk_switch = ucontrol->value.integer.value[0];
- magician_ext_control(codec);
- return 1;
-}
-
-static int magician_get_input(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = magician_in_sel;
- return 0;
-}
-
-static int magician_set_input(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- if (magician_in_sel == ucontrol->value.integer.value[0])
- return 0;
-
- magician_in_sel = ucontrol->value.integer.value[0];
-
- switch (magician_in_sel) {
- case MAGICIAN_MIC:
- gpio_set_value(EGPIO_MAGICIAN_IN_SEL1, 1);
- break;
- case MAGICIAN_MIC_EXT:
- gpio_set_value(EGPIO_MAGICIAN_IN_SEL1, 0);
- }
-
- return 1;
-}
-
-static int magician_spk_power(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- gpio_set_value(EGPIO_MAGICIAN_SPK_POWER, SND_SOC_DAPM_EVENT_ON(event));
- return 0;
-}
-
-static int magician_hp_power(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- gpio_set_value(EGPIO_MAGICIAN_EP_POWER, SND_SOC_DAPM_EVENT_ON(event));
- return 0;
-}
-
-static int magician_mic_bias(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- gpio_set_value(EGPIO_MAGICIAN_MIC_POWER, SND_SOC_DAPM_EVENT_ON(event));
- return 0;
-}
-
-/* magician machine dapm widgets */
-static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Jack", magician_hp_power),
- SND_SOC_DAPM_SPK("Speaker", magician_spk_power),
- SND_SOC_DAPM_MIC("Call Mic", magician_mic_bias),
- SND_SOC_DAPM_MIC("Headset Mic", magician_mic_bias),
-};
-
-/* magician machine audio_map */
-static const struct snd_soc_dapm_route audio_map[] = {
-
- /* Headphone connected to VOUTL, VOUTR */
- {"Headphone Jack", NULL, "VOUTL"},
- {"Headphone Jack", NULL, "VOUTR"},
-
- /* Speaker connected to VOUTL, VOUTR */
- {"Speaker", NULL, "VOUTL"},
- {"Speaker", NULL, "VOUTR"},
-
- /* Mics are connected to VINM */
- {"VINM", NULL, "Headset Mic"},
- {"VINM", NULL, "Call Mic"},
-};
-
-static const char *input_select[] = {"Call Mic", "Headset Mic"};
-static const struct soc_enum magician_in_sel_enum =
- SOC_ENUM_SINGLE_EXT(2, input_select);
-
-static const struct snd_kcontrol_new uda1380_magician_controls[] = {
- SOC_SINGLE_BOOL_EXT("Headphone Switch",
- (unsigned long)&magician_hp_switch,
- magician_get_hp, magician_set_hp),
- SOC_SINGLE_BOOL_EXT("Speaker Switch",
- (unsigned long)&magician_spk_switch,
- magician_get_spk, magician_set_spk),
- SOC_ENUM_EXT("Input Select", magician_in_sel_enum,
- magician_get_input, magician_set_input),
-};
-
-/*
- * Logic for a uda1380 as connected on a HTC Magician
- */
-static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int err;
-
- /* NC codec pins */
- snd_soc_dapm_nc_pin(dapm, "VOUTLHP");
- snd_soc_dapm_nc_pin(dapm, "VOUTRHP");
-
- /* FIXME: is anything connected here? */
- snd_soc_dapm_nc_pin(dapm, "VINL");
- snd_soc_dapm_nc_pin(dapm, "VINR");
-
- /* Add magician specific controls */
- err = snd_soc_add_codec_controls(codec, uda1380_magician_controls,
- ARRAY_SIZE(uda1380_magician_controls));
- if (err < 0)
- return err;
-
- /* Add magician specific widgets */
- snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
- ARRAY_SIZE(uda1380_dapm_widgets));
-
- /* Set up magician specific audio path interconnects */
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
- return 0;
-}
-
-/* magician digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link magician_dai[] = {
-{
- .name = "uda1380",
- .stream_name = "UDA1380 Playback",
- .cpu_dai_name = "pxa-ssp-dai.0",
- .codec_dai_name = "uda1380-hifi-playback",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "uda1380-codec.0-0018",
- .init = magician_uda1380_init,
- .ops = &magician_playback_ops,
-},
-{
- .name = "uda1380",
- .stream_name = "UDA1380 Capture",
- .cpu_dai_name = "pxa2xx-i2s",
- .codec_dai_name = "uda1380-hifi-capture",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "uda1380-codec.0-0018",
- .ops = &magician_capture_ops,
-}
-};
-
-/* magician audio machine driver */
-static struct snd_soc_card snd_soc_card_magician = {
- .name = "Magician",
- .owner = THIS_MODULE,
- .dai_link = magician_dai,
- .num_links = ARRAY_SIZE(magician_dai),
-
-};
-
-static struct platform_device *magician_snd_device;
-
-/*
- * FIXME: move into magician board file once merged into the pxa tree
- */
-static struct uda1380_platform_data uda1380_info = {
- .gpio_power = EGPIO_MAGICIAN_CODEC_POWER,
- .gpio_reset = EGPIO_MAGICIAN_CODEC_RESET,
- .dac_clk = UDA1380_DAC_CLK_WSPLL,
-};
-
-static struct i2c_board_info i2c_board_info[] = {
- {
- I2C_BOARD_INFO("uda1380", 0x18),
- .platform_data = &uda1380_info,
- },
-};
-
-static int __init magician_init(void)
-{
- int ret;
- struct i2c_adapter *adapter;
- struct i2c_client *client;
-
- if (!machine_is_magician())
- return -ENODEV;
-
- adapter = i2c_get_adapter(0);
- if (!adapter)
- return -ENODEV;
- client = i2c_new_device(adapter, i2c_board_info);
- i2c_put_adapter(adapter);
- if (!client)
- return -ENODEV;
-
- ret = gpio_request(EGPIO_MAGICIAN_SPK_POWER, "SPK_POWER");
- if (ret)
- goto err_request_spk;
- ret = gpio_request(EGPIO_MAGICIAN_EP_POWER, "EP_POWER");
- if (ret)
- goto err_request_ep;
- ret = gpio_request(EGPIO_MAGICIAN_MIC_POWER, "MIC_POWER");
- if (ret)
- goto err_request_mic;
- ret = gpio_request(EGPIO_MAGICIAN_IN_SEL0, "IN_SEL0");
- if (ret)
- goto err_request_in_sel0;
- ret = gpio_request(EGPIO_MAGICIAN_IN_SEL1, "IN_SEL1");
- if (ret)
- goto err_request_in_sel1;
-
- gpio_set_value(EGPIO_MAGICIAN_IN_SEL0, 0);
-
- magician_snd_device = platform_device_alloc("soc-audio", -1);
- if (!magician_snd_device) {
- ret = -ENOMEM;
- goto err_pdev;
- }
-
- platform_set_drvdata(magician_snd_device, &snd_soc_card_magician);
- ret = platform_device_add(magician_snd_device);
- if (ret) {
- platform_device_put(magician_snd_device);
- goto err_pdev;
- }
-
- return 0;
-
-err_pdev:
- gpio_free(EGPIO_MAGICIAN_IN_SEL1);
-err_request_in_sel1:
- gpio_free(EGPIO_MAGICIAN_IN_SEL0);
-err_request_in_sel0:
- gpio_free(EGPIO_MAGICIAN_MIC_POWER);
-err_request_mic:
- gpio_free(EGPIO_MAGICIAN_EP_POWER);
-err_request_ep:
- gpio_free(EGPIO_MAGICIAN_SPK_POWER);
-err_request_spk:
- return ret;
-}
-
-static void __exit magician_exit(void)
-{
- platform_device_unregister(magician_snd_device);
-
- gpio_set_value(EGPIO_MAGICIAN_SPK_POWER, 0);
- gpio_set_value(EGPIO_MAGICIAN_EP_POWER, 0);
- gpio_set_value(EGPIO_MAGICIAN_MIC_POWER, 0);
-
- gpio_free(EGPIO_MAGICIAN_IN_SEL1);
- gpio_free(EGPIO_MAGICIAN_IN_SEL0);
- gpio_free(EGPIO_MAGICIAN_MIC_POWER);
- gpio_free(EGPIO_MAGICIAN_EP_POWER);
- gpio_free(EGPIO_MAGICIAN_SPK_POWER);
-}
-
-module_init(magician_init);
-module_exit(magician_exit);
-
-MODULE_AUTHOR("Philipp Zabel");
-MODULE_DESCRIPTION("ALSA SoC Magician");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/mioa701_wm9713.c b/ANDROID_3.4.5/sound/soc/pxa/mioa701_wm9713.c
deleted file mode 100644
index 9c585af5..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/mioa701_wm9713.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Handles the Mitac mioa701 SoC system
- *
- * Copyright (C) 2008 Robert Jarzmik
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation in version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * This is a little schema of the sound interconnections :
- *
- * Sagem X200 Wolfson WM9713
- * +--------+ +-------------------+ Rear Speaker
- * | | | | /-+
- * | +--->----->---+MONOIN SPKL+--->----+-+ |
- * | GSM | | | | | |
- * | +--->----->---+PCBEEP SPKR+--->----+-+ |
- * | CHIP | | | \-+
- * | +---<-----<---+MONO |
- * | | | | Front Speaker
- * +--------+ | | /-+
- * | HPL+--->----+-+ |
- * | | | | |
- * | OUT3+--->----+-+ |
- * | | \-+
- * | |
- * | | Front Micro
- * | | +
- * | MIC1+-----<--+o+
- * | | +
- * +-------------------+ ---
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach-types.h>
-#include <mach/audio.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-#include <sound/ac97_codec.h>
-
-#include "pxa2xx-ac97.h"
-#include "../codecs/wm9713.h"
-
-#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
-
-#define AC97_GPIO_PULL 0x58
-
-/* Use GPIO8 for rear speaker amplifier */
-static int rear_amp_power(struct snd_soc_codec *codec, int power)
-{
- unsigned short reg;
-
- if (power) {
- reg = snd_soc_read(codec, AC97_GPIO_CFG);
- snd_soc_write(codec, AC97_GPIO_CFG, reg | 0x0100);
- reg = snd_soc_read(codec, AC97_GPIO_PULL);
- snd_soc_write(codec, AC97_GPIO_PULL, reg | (1<<15));
- } else {
- reg = snd_soc_read(codec, AC97_GPIO_CFG);
- snd_soc_write(codec, AC97_GPIO_CFG, reg & ~0x0100);
- reg = snd_soc_read(codec, AC97_GPIO_PULL);
- snd_soc_write(codec, AC97_GPIO_PULL, reg & ~(1<<15));
- }
-
- return 0;
-}
-
-static int rear_amp_event(struct snd_soc_dapm_widget *widget,
- struct snd_kcontrol *kctl, int event)
-{
- struct snd_soc_codec *codec = widget->codec;
-
- return rear_amp_power(codec, SND_SOC_DAPM_EVENT_ON(event));
-}
-
-/* mioa701 machine dapm widgets */
-static const struct snd_soc_dapm_widget mioa701_dapm_widgets[] = {
- SND_SOC_DAPM_SPK("Front Speaker", NULL),
- SND_SOC_DAPM_SPK("Rear Speaker", rear_amp_event),
- SND_SOC_DAPM_MIC("Headset", NULL),
- SND_SOC_DAPM_LINE("GSM Line Out", NULL),
- SND_SOC_DAPM_LINE("GSM Line In", NULL),
- SND_SOC_DAPM_MIC("Headset Mic", NULL),
- SND_SOC_DAPM_MIC("Front Mic", NULL),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- /* Call Mic */
- {"Mic Bias", NULL, "Front Mic"},
- {"MIC1", NULL, "Mic Bias"},
-
- /* Headset Mic */
- {"LINEL", NULL, "Headset Mic"},
- {"LINER", NULL, "Headset Mic"},
-
- /* GSM Module */
- {"MONOIN", NULL, "GSM Line Out"},
- {"PCBEEP", NULL, "GSM Line Out"},
- {"GSM Line In", NULL, "MONO"},
-
- /* headphone connected to HPL, HPR */
- {"Headset", NULL, "HPL"},
- {"Headset", NULL, "HPR"},
-
- /* front speaker connected to HPL, OUT3 */
- {"Front Speaker", NULL, "HPL"},
- {"Front Speaker", NULL, "OUT3"},
-
- /* rear speaker connected to SPKL, SPKR */
- {"Rear Speaker", NULL, "SPKL"},
- {"Rear Speaker", NULL, "SPKR"},
-};
-
-static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- unsigned short reg;
-
- /* Add mioa701 specific widgets */
- snd_soc_dapm_new_controls(dapm, ARRAY_AND_SIZE(mioa701_dapm_widgets));
-
- /* Set up mioa701 specific audio path audio_mapnects */
- snd_soc_dapm_add_routes(dapm, ARRAY_AND_SIZE(audio_map));
-
- /* Prepare GPIO8 for rear speaker amplifier */
- reg = codec->driver->read(codec, AC97_GPIO_CFG);
- codec->driver->write(codec, AC97_GPIO_CFG, reg | 0x0100);
-
- /* Prepare MIC input */
- reg = codec->driver->read(codec, AC97_3D_CONTROL);
- codec->driver->write(codec, AC97_3D_CONTROL, reg | 0xc000);
-
- snd_soc_dapm_enable_pin(dapm, "Front Speaker");
- snd_soc_dapm_enable_pin(dapm, "Rear Speaker");
- snd_soc_dapm_enable_pin(dapm, "Front Mic");
- snd_soc_dapm_enable_pin(dapm, "GSM Line In");
- snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
-
- return 0;
-}
-
-static struct snd_soc_ops mioa701_ops;
-
-static struct snd_soc_dai_link mioa701_dai[] = {
- {
- .name = "AC97",
- .stream_name = "AC97 HiFi",
- .cpu_dai_name = "pxa2xx-ac97",
- .codec_dai_name = "wm9713-hifi",
- .codec_name = "wm9713-codec",
- .init = mioa701_wm9713_init,
- .platform_name = "pxa-pcm-audio",
- .ops = &mioa701_ops,
- },
- {
- .name = "AC97 Aux",
- .stream_name = "AC97 Aux",
- .cpu_dai_name = "pxa2xx-ac97-aux",
- .codec_dai_name ="wm9713-aux",
- .codec_name = "wm9713-codec",
- .platform_name = "pxa-pcm-audio",
- .ops = &mioa701_ops,
- },
-};
-
-static struct snd_soc_card mioa701 = {
- .name = "MioA701",
- .owner = THIS_MODULE,
- .dai_link = mioa701_dai,
- .num_links = ARRAY_SIZE(mioa701_dai),
-};
-
-static struct platform_device *mioa701_snd_device;
-
-static int mioa701_wm9713_probe(struct platform_device *pdev)
-{
- int ret;
-
- if (!machine_is_mioa701())
- return -ENODEV;
-
- dev_warn(&pdev->dev, "Be warned that incorrect mixers/muxes setup will"
- "lead to overheating and possible destruction of your device."
- "Do not use without a good knowledge of mio's board design!\n");
-
- mioa701_snd_device = platform_device_alloc("soc-audio", -1);
- if (!mioa701_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(mioa701_snd_device, &mioa701);
-
- ret = platform_device_add(mioa701_snd_device);
- if (!ret)
- return 0;
-
- platform_device_put(mioa701_snd_device);
- return ret;
-}
-
-static int __devexit mioa701_wm9713_remove(struct platform_device *pdev)
-{
- platform_device_unregister(mioa701_snd_device);
- return 0;
-}
-
-static struct platform_driver mioa701_wm9713_driver = {
- .probe = mioa701_wm9713_probe,
- .remove = __devexit_p(mioa701_wm9713_remove),
- .driver = {
- .name = "mioa701-wm9713",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(mioa701_wm9713_driver);
-
-/* Module information */
-MODULE_AUTHOR("Robert Jarzmik (rjarzmik@free.fr)");
-MODULE_DESCRIPTION("ALSA SoC WM9713 MIO A701");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/palm27x.c b/ANDROID_3.4.5/sound/soc/pxa/palm27x.c
deleted file mode 100644
index db24bc68..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/palm27x.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * linux/sound/soc/pxa/palm27x.c
- *
- * SoC Audio driver for Palm T|X, T5 and LifeDrive
- *
- * based on tosa.c
- *
- * Copyright (C) 2008 Marek Vasut <marek.vasut@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/gpio.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/jack.h>
-
-#include <asm/mach-types.h>
-#include <mach/audio.h>
-#include <mach/palmasoc.h>
-
-#include "../codecs/wm9712.h"
-#include "pxa2xx-ac97.h"
-
-static struct snd_soc_jack hs_jack;
-
-/* Headphones jack detection DAPM pins */
-static struct snd_soc_jack_pin hs_jack_pins[] = {
- {
- .pin = "Headphone Jack",
- .mask = SND_JACK_HEADPHONE,
- },
-};
-
-/* Headphones jack detection gpios */
-static struct snd_soc_jack_gpio hs_jack_gpios[] = {
- [0] = {
- /* gpio is set on per-platform basis */
- .name = "hp-gpio",
- .report = SND_JACK_HEADPHONE,
- .debounce_time = 200,
- },
-};
-
-/* Palm27x machine dapm widgets */
-static const struct snd_soc_dapm_widget palm27x_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_SPK("Ext. Speaker", NULL),
- SND_SOC_DAPM_MIC("Ext. Microphone", NULL),
-};
-
-/* PalmTX audio map */
-static const struct snd_soc_dapm_route audio_map[] = {
- /* headphone connected to HPOUTL, HPOUTR */
- {"Headphone Jack", NULL, "HPOUTL"},
- {"Headphone Jack", NULL, "HPOUTR"},
-
- /* ext speaker connected to ROUT2, LOUT2 */
- {"Ext. Speaker", NULL, "LOUT2"},
- {"Ext. Speaker", NULL, "ROUT2"},
-
- /* mic connected to MIC1 */
- {"Ext. Microphone", NULL, "MIC1"},
-};
-
-static struct snd_soc_card palm27x_asoc;
-
-static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int err;
-
- /* add palm27x specific widgets */
- err = snd_soc_dapm_new_controls(dapm, palm27x_dapm_widgets,
- ARRAY_SIZE(palm27x_dapm_widgets));
- if (err)
- return err;
-
- /* set up palm27x specific audio path audio_map */
- err = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
- if (err)
- return err;
-
- /* connected pins */
- if (machine_is_palmld())
- snd_soc_dapm_enable_pin(dapm, "MIC1");
- snd_soc_dapm_enable_pin(dapm, "HPOUTL");
- snd_soc_dapm_enable_pin(dapm, "HPOUTR");
- snd_soc_dapm_enable_pin(dapm, "LOUT2");
- snd_soc_dapm_enable_pin(dapm, "ROUT2");
-
- /* not connected pins */
- snd_soc_dapm_nc_pin(dapm, "OUT3");
- snd_soc_dapm_nc_pin(dapm, "MONOOUT");
- snd_soc_dapm_nc_pin(dapm, "LINEINL");
- snd_soc_dapm_nc_pin(dapm, "LINEINR");
- snd_soc_dapm_nc_pin(dapm, "PCBEEP");
- snd_soc_dapm_nc_pin(dapm, "PHONE");
- snd_soc_dapm_nc_pin(dapm, "MIC2");
-
- /* Jack detection API stuff */
- err = snd_soc_jack_new(codec, "Headphone Jack",
- SND_JACK_HEADPHONE, &hs_jack);
- if (err)
- return err;
-
- err = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
- hs_jack_pins);
- if (err)
- return err;
-
- err = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios),
- hs_jack_gpios);
-
- return err;
-}
-
-static struct snd_soc_dai_link palm27x_dai[] = {
-{
- .name = "AC97 HiFi",
- .stream_name = "AC97 HiFi",
- .cpu_dai_name = "pxa2xx-ac97",
- .codec_dai_name = "wm9712-hifi",
- .codec_name = "wm9712-codec",
- .platform_name = "pxa-pcm-audio",
- .init = palm27x_ac97_init,
-},
-{
- .name = "AC97 Aux",
- .stream_name = "AC97 Aux",
- .cpu_dai_name = "pxa2xx-ac97-aux",
- .codec_dai_name = "wm9712-aux",
- .codec_name = "wm9712-codec",
- .platform_name = "pxa-pcm-audio",
-},
-};
-
-static struct snd_soc_card palm27x_asoc = {
- .name = "Palm/PXA27x",
- .owner = THIS_MODULE,
- .dai_link = palm27x_dai,
- .num_links = ARRAY_SIZE(palm27x_dai),
-};
-
-static struct platform_device *palm27x_snd_device;
-
-static int palm27x_asoc_probe(struct platform_device *pdev)
-{
- int ret;
-
- if (!(machine_is_palmtx() || machine_is_palmt5() ||
- machine_is_palmld() || machine_is_palmte2()))
- return -ENODEV;
-
- if (!pdev->dev.platform_data) {
- dev_err(&pdev->dev, "please supply platform_data\n");
- return -ENODEV;
- }
-
- hs_jack_gpios[0].gpio = ((struct palm27x_asoc_info *)
- (pdev->dev.platform_data))->jack_gpio;
-
- palm27x_snd_device = platform_device_alloc("soc-audio", -1);
- if (!palm27x_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(palm27x_snd_device, &palm27x_asoc);
- ret = platform_device_add(palm27x_snd_device);
-
- if (ret != 0)
- goto put_device;
-
- return 0;
-
-put_device:
- platform_device_put(palm27x_snd_device);
-
- return ret;
-}
-
-static int __devexit palm27x_asoc_remove(struct platform_device *pdev)
-{
- platform_device_unregister(palm27x_snd_device);
- return 0;
-}
-
-static struct platform_driver palm27x_wm9712_driver = {
- .probe = palm27x_asoc_probe,
- .remove = __devexit_p(palm27x_asoc_remove),
- .driver = {
- .name = "palm27x-asoc",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(palm27x_wm9712_driver);
-
-/* Module information */
-MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
-MODULE_DESCRIPTION("ALSA SoC Palm T|X, T5 and LifeDrive");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/poodle.c b/ANDROID_3.4.5/sound/soc/pxa/poodle.c
deleted file mode 100644
index d2cc8173..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/poodle.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * poodle.c -- SoC audio for Poodle
- *
- * Copyright 2005 Wolfson Microelectronics PLC.
- * Copyright 2005 Openedhand Ltd.
- *
- * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
- * Richard Purdie <richard@openedhand.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/timer.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <asm/hardware/locomo.h>
-#include <mach/poodle.h>
-#include <mach/audio.h>
-
-#include "../codecs/wm8731.h"
-#include "pxa2xx-i2s.h"
-
-#define POODLE_HP 1
-#define POODLE_HP_OFF 0
-#define POODLE_SPK_ON 1
-#define POODLE_SPK_OFF 0
-
- /* audio clock in Hz - rounded from 12.235MHz */
-#define POODLE_AUDIO_CLOCK 12288000
-
-static int poodle_jack_func;
-static int poodle_spk_func;
-
-static void poodle_ext_control(struct snd_soc_dapm_context *dapm)
-{
- /* set up jack connection */
- if (poodle_jack_func == POODLE_HP) {
- /* set = unmute headphone */
- locomo_gpio_write(&poodle_locomo_device.dev,
- POODLE_LOCOMO_GPIO_MUTE_L, 1);
- locomo_gpio_write(&poodle_locomo_device.dev,
- POODLE_LOCOMO_GPIO_MUTE_R, 1);
- snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
- } else {
- locomo_gpio_write(&poodle_locomo_device.dev,
- POODLE_LOCOMO_GPIO_MUTE_L, 0);
- locomo_gpio_write(&poodle_locomo_device.dev,
- POODLE_LOCOMO_GPIO_MUTE_R, 0);
- snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
- }
-
- /* set the enpoints to their new connetion states */
- if (poodle_spk_func == POODLE_SPK_ON)
- snd_soc_dapm_enable_pin(dapm, "Ext Spk");
- else
- snd_soc_dapm_disable_pin(dapm, "Ext Spk");
-
- /* signal a DAPM event */
- snd_soc_dapm_sync(dapm);
-}
-
-static int poodle_startup(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
-
- mutex_lock(&codec->mutex);
-
- /* check the jack status at stream startup */
- poodle_ext_control(&codec->dapm);
-
- mutex_unlock(&codec->mutex);
-
- return 0;
-}
-
-/* we need to unmute the HP at shutdown as the mute burns power on poodle */
-static void poodle_shutdown(struct snd_pcm_substream *substream)
-{
- /* set = unmute headphone */
- locomo_gpio_write(&poodle_locomo_device.dev,
- POODLE_LOCOMO_GPIO_MUTE_L, 1);
- locomo_gpio_write(&poodle_locomo_device.dev,
- POODLE_LOCOMO_GPIO_MUTE_R, 1);
-}
-
-static int poodle_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- unsigned int clk = 0;
- int ret = 0;
-
- switch (params_rate(params)) {
- case 8000:
- case 16000:
- case 48000:
- case 96000:
- clk = 12288000;
- break;
- case 11025:
- case 22050:
- case 44100:
- clk = 11289600;
- break;
- }
-
- /* set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL, clk,
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- /* set the I2S system clock as input (unused) */
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops poodle_ops = {
- .startup = poodle_startup,
- .hw_params = poodle_hw_params,
- .shutdown = poodle_shutdown,
-};
-
-static int poodle_get_jack(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = poodle_jack_func;
- return 0;
-}
-
-static int poodle_set_jack(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
-
- if (poodle_jack_func == ucontrol->value.integer.value[0])
- return 0;
-
- poodle_jack_func = ucontrol->value.integer.value[0];
- poodle_ext_control(&card->dapm);
- return 1;
-}
-
-static int poodle_get_spk(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = poodle_spk_func;
- return 0;
-}
-
-static int poodle_set_spk(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
-
- if (poodle_spk_func == ucontrol->value.integer.value[0])
- return 0;
-
- poodle_spk_func = ucontrol->value.integer.value[0];
- poodle_ext_control(&card->dapm);
- return 1;
-}
-
-static int poodle_amp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- if (SND_SOC_DAPM_EVENT_ON(event))
- locomo_gpio_write(&poodle_locomo_device.dev,
- POODLE_LOCOMO_GPIO_AMP_ON, 0);
- else
- locomo_gpio_write(&poodle_locomo_device.dev,
- POODLE_LOCOMO_GPIO_AMP_ON, 1);
-
- return 0;
-}
-
-/* poodle machine dapm widgets */
-static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = {
-SND_SOC_DAPM_HP("Headphone Jack", NULL),
-SND_SOC_DAPM_SPK("Ext Spk", poodle_amp_event),
-};
-
-/* Corgi machine connections to the codec pins */
-static const struct snd_soc_dapm_route poodle_audio_map[] = {
-
- /* headphone connected to LHPOUT1, RHPOUT1 */
- {"Headphone Jack", NULL, "LHPOUT"},
- {"Headphone Jack", NULL, "RHPOUT"},
-
- /* speaker connected to LOUT, ROUT */
- {"Ext Spk", NULL, "ROUT"},
- {"Ext Spk", NULL, "LOUT"},
-};
-
-static const char *jack_function[] = {"Off", "Headphone"};
-static const char *spk_function[] = {"Off", "On"};
-static const struct soc_enum poodle_enum[] = {
- SOC_ENUM_SINGLE_EXT(2, jack_function),
- SOC_ENUM_SINGLE_EXT(2, spk_function),
-};
-
-static const struct snd_kcontrol_new wm8731_poodle_controls[] = {
- SOC_ENUM_EXT("Jack Function", poodle_enum[0], poodle_get_jack,
- poodle_set_jack),
- SOC_ENUM_EXT("Speaker Function", poodle_enum[1], poodle_get_spk,
- poodle_set_spk),
-};
-
-/*
- * Logic for a wm8731 as connected on a Sharp SL-C7x0 Device
- */
-static int poodle_wm8731_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_nc_pin(dapm, "LLINEIN");
- snd_soc_dapm_nc_pin(dapm, "RLINEIN");
- snd_soc_dapm_enable_pin(dapm, "MICIN");
-
- return 0;
-}
-
-/* poodle digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link poodle_dai = {
- .name = "WM8731",
- .stream_name = "WM8731",
- .cpu_dai_name = "pxa2xx-i2s",
- .codec_dai_name = "wm8731-hifi",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "wm8731.0-001b",
- .init = poodle_wm8731_init,
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS,
- .ops = &poodle_ops,
-};
-
-/* poodle audio machine driver */
-static struct snd_soc_card poodle = {
- .name = "Poodle",
- .dai_link = &poodle_dai,
- .num_links = 1,
- .owner = THIS_MODULE,
-
- .controls = wm8731_poodle_controls,
- .num_controls = ARRAY_SIZE(wm8731_poodle_controls),
- .dapm_widgets = wm8731_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets),
- .dapm_routes = poodle_audio_map,
- .num_dapm_routes = ARRAY_SIZE(poodle_audio_map),
-};
-
-static int __devinit poodle_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &poodle;
- int ret;
-
- locomo_gpio_set_dir(&poodle_locomo_device.dev,
- POODLE_LOCOMO_GPIO_AMP_ON, 0);
- /* should we mute HP at startup - burning power ?*/
- locomo_gpio_set_dir(&poodle_locomo_device.dev,
- POODLE_LOCOMO_GPIO_MUTE_L, 0);
- locomo_gpio_set_dir(&poodle_locomo_device.dev,
- POODLE_LOCOMO_GPIO_MUTE_R, 0);
-
- card->dev = &pdev->dev;
-
- ret = snd_soc_register_card(card);
- if (ret)
- dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
- ret);
- return ret;
-}
-
-static int __devexit poodle_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- snd_soc_unregister_card(card);
- return 0;
-}
-
-static struct platform_driver poodle_driver = {
- .driver = {
- .name = "poodle-audio",
- .owner = THIS_MODULE,
- },
- .probe = poodle_probe,
- .remove = __devexit_p(poodle_remove),
-};
-
-module_platform_driver(poodle_driver);
-
-/* Module information */
-MODULE_AUTHOR("Richard Purdie");
-MODULE_DESCRIPTION("ALSA SoC Poodle");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:poodle-audio");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/pxa-ssp.c b/ANDROID_3.4.5/sound/soc/pxa/pxa-ssp.c
deleted file mode 100644
index fd04ce13..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/pxa-ssp.c
+++ /dev/null
@@ -1,845 +0,0 @@
-/*
- * pxa-ssp.c -- ALSA Soc Audio Layer
- *
- * Copyright 2005,2008 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood
- * Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * TODO:
- * o Test network mode for > 16bit sample size
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/pxa2xx_ssp.h>
-
-#include <asm/irq.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/initval.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/pxa2xx-lib.h>
-
-#include <mach/hardware.h>
-#include <mach/dma.h>
-#include <mach/audio.h>
-
-#include "../../arm/pxa2xx-pcm.h"
-#include "pxa-ssp.h"
-
-/*
- * SSP audio private data
- */
-struct ssp_priv {
- struct ssp_device *ssp;
- unsigned int sysclk;
- int dai_fmt;
-#ifdef CONFIG_PM
- uint32_t cr0;
- uint32_t cr1;
- uint32_t to;
- uint32_t psp;
-#endif
-};
-
-static void dump_registers(struct ssp_device *ssp)
-{
- dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n",
- pxa_ssp_read_reg(ssp, SSCR0), pxa_ssp_read_reg(ssp, SSCR1),
- pxa_ssp_read_reg(ssp, SSTO));
-
- dev_dbg(&ssp->pdev->dev, "SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x\n",
- pxa_ssp_read_reg(ssp, SSPSP), pxa_ssp_read_reg(ssp, SSSR),
- pxa_ssp_read_reg(ssp, SSACD));
-}
-
-static void pxa_ssp_enable(struct ssp_device *ssp)
-{
- uint32_t sscr0;
-
- sscr0 = __raw_readl(ssp->mmio_base + SSCR0) | SSCR0_SSE;
- __raw_writel(sscr0, ssp->mmio_base + SSCR0);
-}
-
-static void pxa_ssp_disable(struct ssp_device *ssp)
-{
- uint32_t sscr0;
-
- sscr0 = __raw_readl(ssp->mmio_base + SSCR0) & ~SSCR0_SSE;
- __raw_writel(sscr0, ssp->mmio_base + SSCR0);
-}
-
-struct pxa2xx_pcm_dma_data {
- struct pxa2xx_pcm_dma_params params;
- char name[20];
-};
-
-static struct pxa2xx_pcm_dma_params *
-pxa_ssp_get_dma_params(struct ssp_device *ssp, int width4, int out)
-{
- struct pxa2xx_pcm_dma_data *dma;
-
- dma = kzalloc(sizeof(struct pxa2xx_pcm_dma_data), GFP_KERNEL);
- if (dma == NULL)
- return NULL;
-
- snprintf(dma->name, 20, "SSP%d PCM %s %s", ssp->port_id,
- width4 ? "32-bit" : "16-bit", out ? "out" : "in");
-
- dma->params.name = dma->name;
- dma->params.drcmr = &DRCMR(out ? ssp->drcmr_tx : ssp->drcmr_rx);
- dma->params.dcmd = (out ? (DCMD_INCSRCADDR | DCMD_FLOWTRG) :
- (DCMD_INCTRGADDR | DCMD_FLOWSRC)) |
- (width4 ? DCMD_WIDTH4 : DCMD_WIDTH2) | DCMD_BURST16;
- dma->params.dev_addr = ssp->phys_base + SSDR;
-
- return &dma->params;
-}
-
-static int pxa_ssp_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *cpu_dai)
-{
- struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
- struct ssp_device *ssp = priv->ssp;
- int ret = 0;
-
- if (!cpu_dai->active) {
- clk_enable(ssp->clk);
- pxa_ssp_disable(ssp);
- }
-
- kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
- snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
-
- return ret;
-}
-
-static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *cpu_dai)
-{
- struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
- struct ssp_device *ssp = priv->ssp;
-
- if (!cpu_dai->active) {
- pxa_ssp_disable(ssp);
- clk_disable(ssp->clk);
- }
-
- kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
- snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
-}
-
-#ifdef CONFIG_PM
-
-static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
-{
- struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
- struct ssp_device *ssp = priv->ssp;
-
- if (!cpu_dai->active)
- clk_enable(ssp->clk);
-
- priv->cr0 = __raw_readl(ssp->mmio_base + SSCR0);
- priv->cr1 = __raw_readl(ssp->mmio_base + SSCR1);
- priv->to = __raw_readl(ssp->mmio_base + SSTO);
- priv->psp = __raw_readl(ssp->mmio_base + SSPSP);
-
- pxa_ssp_disable(ssp);
- clk_disable(ssp->clk);
- return 0;
-}
-
-static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
-{
- struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
- struct ssp_device *ssp = priv->ssp;
- uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE;
-
- clk_enable(ssp->clk);
-
- __raw_writel(sssr, ssp->mmio_base + SSSR);
- __raw_writel(priv->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0);
- __raw_writel(priv->cr1, ssp->mmio_base + SSCR1);
- __raw_writel(priv->to, ssp->mmio_base + SSTO);
- __raw_writel(priv->psp, ssp->mmio_base + SSPSP);
-
- if (cpu_dai->active)
- pxa_ssp_enable(ssp);
- else
- clk_disable(ssp->clk);
-
- return 0;
-}
-
-#else
-#define pxa_ssp_suspend NULL
-#define pxa_ssp_resume NULL
-#endif
-
-/**
- * ssp_set_clkdiv - set SSP clock divider
- * @div: serial clock rate divider
- */
-static void pxa_ssp_set_scr(struct ssp_device *ssp, u32 div)
-{
- u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
-
- if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) {
- sscr0 &= ~0x0000ff00;
- sscr0 |= ((div - 2)/2) << 8; /* 2..512 */
- } else {
- sscr0 &= ~0x000fff00;
- sscr0 |= (div - 1) << 8; /* 1..4096 */
- }
- pxa_ssp_write_reg(ssp, SSCR0, sscr0);
-}
-
-/**
- * pxa_ssp_get_clkdiv - get SSP clock divider
- */
-static u32 pxa_ssp_get_scr(struct ssp_device *ssp)
-{
- u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
- u32 div;
-
- if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP)
- div = ((sscr0 >> 8) & 0xff) * 2 + 2;
- else
- div = ((sscr0 >> 8) & 0xfff) + 1;
- return div;
-}
-
-/*
- * Set the SSP ports SYSCLK.
- */
-static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
- struct ssp_device *ssp = priv->ssp;
- int val;
-
- u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
- ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
-
- dev_dbg(&ssp->pdev->dev,
- "pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %u\n",
- cpu_dai->id, clk_id, freq);
-
- switch (clk_id) {
- case PXA_SSP_CLK_NET_PLL:
- sscr0 |= SSCR0_MOD;
- break;
- case PXA_SSP_CLK_PLL:
- /* Internal PLL is fixed */
- if (cpu_is_pxa25x())
- priv->sysclk = 1843200;
- else
- priv->sysclk = 13000000;
- break;
- case PXA_SSP_CLK_EXT:
- priv->sysclk = freq;
- sscr0 |= SSCR0_ECS;
- break;
- case PXA_SSP_CLK_NET:
- priv->sysclk = freq;
- sscr0 |= SSCR0_NCS | SSCR0_MOD;
- break;
- case PXA_SSP_CLK_AUDIO:
- priv->sysclk = 0;
- pxa_ssp_set_scr(ssp, 1);
- sscr0 |= SSCR0_ACS;
- break;
- default:
- return -ENODEV;
- }
-
- /* The SSP clock must be disabled when changing SSP clock mode
- * on PXA2xx. On PXA3xx it must be enabled when doing so. */
- if (!cpu_is_pxa3xx())
- clk_disable(ssp->clk);
- val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0;
- pxa_ssp_write_reg(ssp, SSCR0, val);
- if (!cpu_is_pxa3xx())
- clk_enable(ssp->clk);
-
- return 0;
-}
-
-/*
- * Set the SSP clock dividers.
- */
-static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
- int div_id, int div)
-{
- struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
- struct ssp_device *ssp = priv->ssp;
- int val;
-
- switch (div_id) {
- case PXA_SSP_AUDIO_DIV_ACDS:
- val = (pxa_ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div);
- pxa_ssp_write_reg(ssp, SSACD, val);
- break;
- case PXA_SSP_AUDIO_DIV_SCDB:
- val = pxa_ssp_read_reg(ssp, SSACD);
- val &= ~SSACD_SCDB;
-#if defined(CONFIG_PXA3xx)
- if (cpu_is_pxa3xx())
- val &= ~SSACD_SCDX8;
-#endif
- switch (div) {
- case PXA_SSP_CLK_SCDB_1:
- val |= SSACD_SCDB;
- break;
- case PXA_SSP_CLK_SCDB_4:
- break;
-#if defined(CONFIG_PXA3xx)
- case PXA_SSP_CLK_SCDB_8:
- if (cpu_is_pxa3xx())
- val |= SSACD_SCDX8;
- else
- return -EINVAL;
- break;
-#endif
- default:
- return -EINVAL;
- }
- pxa_ssp_write_reg(ssp, SSACD, val);
- break;
- case PXA_SSP_DIV_SCR:
- pxa_ssp_set_scr(ssp, div);
- break;
- default:
- return -ENODEV;
- }
-
- return 0;
-}
-
-/*
- * Configure the PLL frequency pxa27x and (afaik - pxa320 only)
- */
-static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
- int source, unsigned int freq_in, unsigned int freq_out)
-{
- struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
- struct ssp_device *ssp = priv->ssp;
- u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70;
-
-#if defined(CONFIG_PXA3xx)
- if (cpu_is_pxa3xx())
- pxa_ssp_write_reg(ssp, SSACDD, 0);
-#endif
-
- switch (freq_out) {
- case 5622000:
- break;
- case 11345000:
- ssacd |= (0x1 << 4);
- break;
- case 12235000:
- ssacd |= (0x2 << 4);
- break;
- case 14857000:
- ssacd |= (0x3 << 4);
- break;
- case 32842000:
- ssacd |= (0x4 << 4);
- break;
- case 48000000:
- ssacd |= (0x5 << 4);
- break;
- case 0:
- /* Disable */
- break;
-
- default:
-#ifdef CONFIG_PXA3xx
- /* PXA3xx has a clock ditherer which can be used to generate
- * a wider range of frequencies - calculate a value for it.
- */
- if (cpu_is_pxa3xx()) {
- u32 val;
- u64 tmp = 19968;
- tmp *= 1000000;
- do_div(tmp, freq_out);
- val = tmp;
-
- val = (val << 16) | 64;
- pxa_ssp_write_reg(ssp, SSACDD, val);
-
- ssacd |= (0x6 << 4);
-
- dev_dbg(&ssp->pdev->dev,
- "Using SSACDD %x to supply %uHz\n",
- val, freq_out);
- break;
- }
-#endif
-
- return -EINVAL;
- }
-
- pxa_ssp_write_reg(ssp, SSACD, ssacd);
-
- return 0;
-}
-
-/*
- * Set the active slots in TDM/Network mode
- */
-static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
- unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
-{
- struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
- struct ssp_device *ssp = priv->ssp;
- u32 sscr0;
-
- sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
- sscr0 &= ~(SSCR0_MOD | SSCR0_SlotsPerFrm(8) | SSCR0_EDSS | SSCR0_DSS);
-
- /* set slot width */
- if (slot_width > 16)
- sscr0 |= SSCR0_EDSS | SSCR0_DataSize(slot_width - 16);
- else
- sscr0 |= SSCR0_DataSize(slot_width);
-
- if (slots > 1) {
- /* enable network mode */
- sscr0 |= SSCR0_MOD;
-
- /* set number of active slots */
- sscr0 |= SSCR0_SlotsPerFrm(slots);
-
- /* set active slot mask */
- pxa_ssp_write_reg(ssp, SSTSA, tx_mask);
- pxa_ssp_write_reg(ssp, SSRSA, rx_mask);
- }
- pxa_ssp_write_reg(ssp, SSCR0, sscr0);
-
- return 0;
-}
-
-/*
- * Tristate the SSP DAI lines
- */
-static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
- int tristate)
-{
- struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
- struct ssp_device *ssp = priv->ssp;
- u32 sscr1;
-
- sscr1 = pxa_ssp_read_reg(ssp, SSCR1);
- if (tristate)
- sscr1 &= ~SSCR1_TTE;
- else
- sscr1 |= SSCR1_TTE;
- pxa_ssp_write_reg(ssp, SSCR1, sscr1);
-
- return 0;
-}
-
-/*
- * Set up the SSP DAI format.
- * The SSP Port must be inactive before calling this function as the
- * physical interface format is changed.
- */
-static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
- unsigned int fmt)
-{
- struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
- struct ssp_device *ssp = priv->ssp;
- u32 sscr0, sscr1, sspsp, scfr;
-
- /* check if we need to change anything at all */
- if (priv->dai_fmt == fmt)
- return 0;
-
- /* we can only change the settings if the port is not in use */
- if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) {
- dev_err(&ssp->pdev->dev,
- "can't change hardware dai format: stream is in use");
- return -EINVAL;
- }
-
- /* reset port settings */
- sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
- ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
- sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7);
- sspsp = 0;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- sscr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR | SSCR1_SCFR;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- sscr1 |= SSCR1_SCLKDIR | SSCR1_SCFR;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- sspsp |= SSPSP_SFRMP;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- sspsp |= SSPSP_SCMODE(2);
- break;
- case SND_SOC_DAIFMT_IB_NF:
- sspsp |= SSPSP_SCMODE(2) | SSPSP_SFRMP;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- sscr0 |= SSCR0_PSP;
- sscr1 |= SSCR1_RWOT | SSCR1_TRAIL;
- /* See hw_params() */
- break;
-
- case SND_SOC_DAIFMT_DSP_A:
- sspsp |= SSPSP_FSRT;
- case SND_SOC_DAIFMT_DSP_B:
- sscr0 |= SSCR0_MOD | SSCR0_PSP;
- sscr1 |= SSCR1_TRAIL | SSCR1_RWOT;
- break;
-
- default:
- return -EINVAL;
- }
-
- pxa_ssp_write_reg(ssp, SSCR0, sscr0);
- pxa_ssp_write_reg(ssp, SSCR1, sscr1);
- pxa_ssp_write_reg(ssp, SSPSP, sspsp);
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- case SND_SOC_DAIFMT_CBM_CFS:
- scfr = pxa_ssp_read_reg(ssp, SSCR1) | SSCR1_SCFR;
- pxa_ssp_write_reg(ssp, SSCR1, scfr);
-
- while (pxa_ssp_read_reg(ssp, SSSR) & SSSR_BSY)
- cpu_relax();
- break;
- }
-
- dump_registers(ssp);
-
- /* Since we are configuring the timings for the format by hand
- * we have to defer some things until hw_params() where we
- * know parameters like the sample size.
- */
- priv->dai_fmt = fmt;
-
- return 0;
-}
-
-/*
- * Set the SSP audio DMA parameters and sample size.
- * Can be called multiple times by oss emulation.
- */
-static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *cpu_dai)
-{
- struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
- struct ssp_device *ssp = priv->ssp;
- int chn = params_channels(params);
- u32 sscr0;
- u32 sspsp;
- int width = snd_pcm_format_physical_width(params_format(params));
- int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf;
- struct pxa2xx_pcm_dma_params *dma_data;
-
- dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream);
-
- /* generate correct DMA params */
- kfree(dma_data);
-
- /* Network mode with one active slot (ttsa == 1) can be used
- * to force 16-bit frame width on the wire (for S16_LE), even
- * with two channels. Use 16-bit DMA transfers for this case.
- */
- dma_data = pxa_ssp_get_dma_params(ssp,
- ((chn == 2) && (ttsa != 1)) || (width == 32),
- substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
-
- snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
-
- /* we can only change the settings if the port is not in use */
- if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
- return 0;
-
- /* clear selected SSP bits */
- sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
-
- /* bit size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
-#ifdef CONFIG_PXA3xx
- if (cpu_is_pxa3xx())
- sscr0 |= SSCR0_FPCKE;
-#endif
- sscr0 |= SSCR0_DataSize(16);
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(8));
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16));
- break;
- }
- pxa_ssp_write_reg(ssp, SSCR0, sscr0);
-
- switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- sspsp = pxa_ssp_read_reg(ssp, SSPSP);
-
- if ((pxa_ssp_get_scr(ssp) == 4) && (width == 16)) {
- /* This is a special case where the bitclk is 64fs
- * and we're not dealing with 2*32 bits of audio
- * samples.
- *
- * The SSP values used for that are all found out by
- * trying and failing a lot; some of the registers
- * needed for that mode are only available on PXA3xx.
- */
-
-#ifdef CONFIG_PXA3xx
- if (!cpu_is_pxa3xx())
- return -EINVAL;
-
- sspsp |= SSPSP_SFRMWDTH(width * 2);
- sspsp |= SSPSP_SFRMDLY(width * 4);
- sspsp |= SSPSP_EDMYSTOP(3);
- sspsp |= SSPSP_DMYSTOP(3);
- sspsp |= SSPSP_DMYSTRT(1);
-#else
- return -EINVAL;
-#endif
- } else {
- /* The frame width is the width the LRCLK is
- * asserted for; the delay is expressed in
- * half cycle units. We need the extra cycle
- * because the data starts clocking out one BCLK
- * after LRCLK changes polarity.
- */
- sspsp |= SSPSP_SFRMWDTH(width + 1);
- sspsp |= SSPSP_SFRMDLY((width + 1) * 2);
- sspsp |= SSPSP_DMYSTRT(1);
- }
-
- pxa_ssp_write_reg(ssp, SSPSP, sspsp);
- break;
- default:
- break;
- }
-
- /* When we use a network mode, we always require TDM slots
- * - complain loudly and fail if they've not been set up yet.
- */
- if ((sscr0 & SSCR0_MOD) && !ttsa) {
- dev_err(&ssp->pdev->dev, "No TDM timeslot configured\n");
- return -EINVAL;
- }
-
- dump_registers(ssp);
-
- return 0;
-}
-
-static void pxa_ssp_set_running_bit(struct snd_pcm_substream *substream,
- struct ssp_device *ssp, int value)
-{
- uint32_t sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
- uint32_t sscr1 = pxa_ssp_read_reg(ssp, SSCR1);
- uint32_t sspsp = pxa_ssp_read_reg(ssp, SSPSP);
- uint32_t sssr = pxa_ssp_read_reg(ssp, SSSR);
-
- if (value && (sscr0 & SSCR0_SSE))
- pxa_ssp_write_reg(ssp, SSCR0, sscr0 & ~SSCR0_SSE);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (value)
- sscr1 |= SSCR1_TSRE;
- else
- sscr1 &= ~SSCR1_TSRE;
- } else {
- if (value)
- sscr1 |= SSCR1_RSRE;
- else
- sscr1 &= ~SSCR1_RSRE;
- }
-
- pxa_ssp_write_reg(ssp, SSCR1, sscr1);
-
- if (value) {
- pxa_ssp_write_reg(ssp, SSSR, sssr);
- pxa_ssp_write_reg(ssp, SSPSP, sspsp);
- pxa_ssp_write_reg(ssp, SSCR0, sscr0 | SSCR0_SSE);
- }
-}
-
-static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *cpu_dai)
-{
- int ret = 0;
- struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
- struct ssp_device *ssp = priv->ssp;
- int val;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_RESUME:
- pxa_ssp_enable(ssp);
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- pxa_ssp_set_running_bit(substream, ssp, 1);
- val = pxa_ssp_read_reg(ssp, SSSR);
- pxa_ssp_write_reg(ssp, SSSR, val);
- break;
- case SNDRV_PCM_TRIGGER_START:
- pxa_ssp_set_running_bit(substream, ssp, 1);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- pxa_ssp_set_running_bit(substream, ssp, 0);
- break;
- case SNDRV_PCM_TRIGGER_SUSPEND:
- pxa_ssp_disable(ssp);
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- pxa_ssp_set_running_bit(substream, ssp, 0);
- break;
-
- default:
- ret = -EINVAL;
- }
-
- dump_registers(ssp);
-
- return ret;
-}
-
-static int pxa_ssp_probe(struct snd_soc_dai *dai)
-{
- struct ssp_priv *priv;
- int ret;
-
- priv = kzalloc(sizeof(struct ssp_priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->ssp = pxa_ssp_request(dai->id + 1, "SoC audio");
- if (priv->ssp == NULL) {
- ret = -ENODEV;
- goto err_priv;
- }
-
- priv->dai_fmt = (unsigned int) -1;
- snd_soc_dai_set_drvdata(dai, priv);
-
- return 0;
-
-err_priv:
- kfree(priv);
- return ret;
-}
-
-static int pxa_ssp_remove(struct snd_soc_dai *dai)
-{
- struct ssp_priv *priv = snd_soc_dai_get_drvdata(dai);
-
- pxa_ssp_free(priv->ssp);
- kfree(priv);
- return 0;
-}
-
-#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \
- SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
-
-#define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
- SNDRV_PCM_FMTBIT_S24_LE | \
- SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops pxa_ssp_dai_ops = {
- .startup = pxa_ssp_startup,
- .shutdown = pxa_ssp_shutdown,
- .trigger = pxa_ssp_trigger,
- .hw_params = pxa_ssp_hw_params,
- .set_sysclk = pxa_ssp_set_dai_sysclk,
- .set_clkdiv = pxa_ssp_set_dai_clkdiv,
- .set_pll = pxa_ssp_set_dai_pll,
- .set_fmt = pxa_ssp_set_dai_fmt,
- .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
- .set_tristate = pxa_ssp_set_dai_tristate,
-};
-
-static struct snd_soc_dai_driver pxa_ssp_dai = {
- .probe = pxa_ssp_probe,
- .remove = pxa_ssp_remove,
- .suspend = pxa_ssp_suspend,
- .resume = pxa_ssp_resume,
- .playback = {
- .channels_min = 1,
- .channels_max = 8,
- .rates = PXA_SSP_RATES,
- .formats = PXA_SSP_FORMATS,
- },
- .capture = {
- .channels_min = 1,
- .channels_max = 8,
- .rates = PXA_SSP_RATES,
- .formats = PXA_SSP_FORMATS,
- },
- .ops = &pxa_ssp_dai_ops,
-};
-
-static __devinit int asoc_ssp_probe(struct platform_device *pdev)
-{
- return snd_soc_register_dai(&pdev->dev, &pxa_ssp_dai);
-}
-
-static int __devexit asoc_ssp_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_dai(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver asoc_ssp_driver = {
- .driver = {
- .name = "pxa-ssp-dai",
- .owner = THIS_MODULE,
- },
-
- .probe = asoc_ssp_probe,
- .remove = __devexit_p(asoc_ssp_remove),
-};
-
-module_platform_driver(asoc_ssp_driver);
-
-/* Module information */
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_DESCRIPTION("PXA SSP/PCM SoC Interface");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/pxa-ssp.h b/ANDROID_3.4.5/sound/soc/pxa/pxa-ssp.h
deleted file mode 100644
index bc79da22..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/pxa-ssp.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * ASoC PXA SSP port support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _PXA_SSP_H
-#define _PXA_SSP_H
-
-/* pxa DAI SSP IDs */
-#define PXA_DAI_SSP1 0
-#define PXA_DAI_SSP2 1
-#define PXA_DAI_SSP3 2
-#define PXA_DAI_SSP4 3
-
-/* SSP clock sources */
-#define PXA_SSP_CLK_PLL 0
-#define PXA_SSP_CLK_EXT 1
-#define PXA_SSP_CLK_NET 2
-#define PXA_SSP_CLK_AUDIO 3
-#define PXA_SSP_CLK_NET_PLL 4
-
-/* SSP audio dividers */
-#define PXA_SSP_AUDIO_DIV_ACDS 0
-#define PXA_SSP_AUDIO_DIV_SCDB 1
-#define PXA_SSP_DIV_SCR 2
-
-/* SSP ACDS audio dividers values */
-#define PXA_SSP_CLK_AUDIO_DIV_1 0
-#define PXA_SSP_CLK_AUDIO_DIV_2 1
-#define PXA_SSP_CLK_AUDIO_DIV_4 2
-#define PXA_SSP_CLK_AUDIO_DIV_8 3
-#define PXA_SSP_CLK_AUDIO_DIV_16 4
-#define PXA_SSP_CLK_AUDIO_DIV_32 5
-
-/* SSP divider bypass */
-#define PXA_SSP_CLK_SCDB_4 0
-#define PXA_SSP_CLK_SCDB_1 1
-#define PXA_SSP_CLK_SCDB_8 2
-
-#define PXA_SSP_PLL_OUT 0
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/pxa/pxa2xx-ac97.c b/ANDROID_3.4.5/sound/soc/pxa/pxa2xx-ac97.c
deleted file mode 100644
index 06ea2744..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/pxa2xx-ac97.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * linux/sound/pxa2xx-ac97.c -- AC97 support for the Intel PXA2xx chip.
- *
- * Author: Nicolas Pitre
- * Created: Dec 02, 2004
- * Copyright: MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-
-#include <sound/core.h>
-#include <sound/ac97_codec.h>
-#include <sound/soc.h>
-#include <sound/pxa2xx-lib.h>
-
-#include <mach/hardware.h>
-#include <mach/regs-ac97.h>
-#include <mach/dma.h>
-#include <mach/audio.h>
-
-#include "pxa2xx-ac97.h"
-
-static void pxa2xx_ac97_warm_reset(struct snd_ac97 *ac97)
-{
- pxa2xx_ac97_try_warm_reset(ac97);
-
- pxa2xx_ac97_finish_reset(ac97);
-}
-
-static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97)
-{
- pxa2xx_ac97_try_cold_reset(ac97);
-
- pxa2xx_ac97_finish_reset(ac97);
-}
-
-struct snd_ac97_bus_ops soc_ac97_ops = {
- .read = pxa2xx_ac97_read,
- .write = pxa2xx_ac97_write,
- .warm_reset = pxa2xx_ac97_warm_reset,
- .reset = pxa2xx_ac97_cold_reset,
-};
-
-static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = {
- .name = "AC97 PCM Stereo out",
- .dev_addr = __PREG(PCDR),
- .drcmr = &DRCMR(12),
- .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
- DCMD_BURST32 | DCMD_WIDTH4,
-};
-
-static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = {
- .name = "AC97 PCM Stereo in",
- .dev_addr = __PREG(PCDR),
- .drcmr = &DRCMR(11),
- .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
- DCMD_BURST32 | DCMD_WIDTH4,
-};
-
-static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = {
- .name = "AC97 Aux PCM (Slot 5) Mono out",
- .dev_addr = __PREG(MODR),
- .drcmr = &DRCMR(10),
- .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
- DCMD_BURST16 | DCMD_WIDTH2,
-};
-
-static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = {
- .name = "AC97 Aux PCM (Slot 5) Mono in",
- .dev_addr = __PREG(MODR),
- .drcmr = &DRCMR(9),
- .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
- DCMD_BURST16 | DCMD_WIDTH2,
-};
-
-static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = {
- .name = "AC97 Mic PCM (Slot 6) Mono in",
- .dev_addr = __PREG(MCDR),
- .drcmr = &DRCMR(8),
- .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
- DCMD_BURST16 | DCMD_WIDTH2,
-};
-
-#ifdef CONFIG_PM
-static int pxa2xx_ac97_suspend(struct snd_soc_dai *dai)
-{
- return pxa2xx_ac97_hw_suspend();
-}
-
-static int pxa2xx_ac97_resume(struct snd_soc_dai *dai)
-{
- return pxa2xx_ac97_hw_resume();
-}
-
-#else
-#define pxa2xx_ac97_suspend NULL
-#define pxa2xx_ac97_resume NULL
-#endif
-
-static int __devinit pxa2xx_ac97_probe(struct snd_soc_dai *dai)
-{
- return pxa2xx_ac97_hw_probe(to_platform_device(dai->dev));
-}
-
-static int pxa2xx_ac97_remove(struct snd_soc_dai *dai)
-{
- pxa2xx_ac97_hw_remove(to_platform_device(dai->dev));
- return 0;
-}
-
-static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *cpu_dai)
-{
- struct pxa2xx_pcm_dma_params *dma_data;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dma_data = &pxa2xx_ac97_pcm_stereo_out;
- else
- dma_data = &pxa2xx_ac97_pcm_stereo_in;
-
- snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
-
- return 0;
-}
-
-static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *cpu_dai)
-{
- struct pxa2xx_pcm_dma_params *dma_data;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dma_data = &pxa2xx_ac97_pcm_aux_mono_out;
- else
- dma_data = &pxa2xx_ac97_pcm_aux_mono_in;
-
- snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
-
- return 0;
-}
-
-static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *cpu_dai)
-{
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- return -ENODEV;
- else
- snd_soc_dai_set_dma_data(cpu_dai, substream,
- &pxa2xx_ac97_pcm_mic_mono_in);
-
- return 0;
-}
-
-#define PXA2XX_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000)
-
-static const struct snd_soc_dai_ops pxa_ac97_hifi_dai_ops = {
- .hw_params = pxa2xx_ac97_hw_params,
-};
-
-static const struct snd_soc_dai_ops pxa_ac97_aux_dai_ops = {
- .hw_params = pxa2xx_ac97_hw_aux_params,
-};
-
-static const struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = {
- .hw_params = pxa2xx_ac97_hw_mic_params,
-};
-
-/*
- * There is only 1 physical AC97 interface for pxa2xx, but it
- * has extra fifo's that can be used for aux DACs and ADCs.
- */
-static struct snd_soc_dai_driver pxa_ac97_dai_driver[] = {
-{
- .name = "pxa2xx-ac97",
- .ac97_control = 1,
- .probe = pxa2xx_ac97_probe,
- .remove = pxa2xx_ac97_remove,
- .suspend = pxa2xx_ac97_suspend,
- .resume = pxa2xx_ac97_resume,
- .playback = {
- .stream_name = "AC97 Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = PXA2XX_AC97_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .capture = {
- .stream_name = "AC97 Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = PXA2XX_AC97_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .ops = &pxa_ac97_hifi_dai_ops,
-},
-{
- .name = "pxa2xx-ac97-aux",
- .ac97_control = 1,
- .playback = {
- .stream_name = "AC97 Aux Playback",
- .channels_min = 1,
- .channels_max = 1,
- .rates = PXA2XX_AC97_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .capture = {
- .stream_name = "AC97 Aux Capture",
- .channels_min = 1,
- .channels_max = 1,
- .rates = PXA2XX_AC97_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .ops = &pxa_ac97_aux_dai_ops,
-},
-{
- .name = "pxa2xx-ac97-mic",
- .ac97_control = 1,
- .capture = {
- .stream_name = "AC97 Mic Capture",
- .channels_min = 1,
- .channels_max = 1,
- .rates = PXA2XX_AC97_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .ops = &pxa_ac97_mic_dai_ops,
-},
-};
-
-EXPORT_SYMBOL_GPL(soc_ac97_ops);
-
-static __devinit int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
-{
- if (pdev->id != -1) {
- dev_err(&pdev->dev, "PXA2xx has only one AC97 port.\n");
- return -ENXIO;
- }
-
- /* Punt most of the init to the SoC probe; we may need the machine
- * driver to do interesting things with the clocking to get us up
- * and running.
- */
- return snd_soc_register_dais(&pdev->dev, pxa_ac97_dai_driver,
- ARRAY_SIZE(pxa_ac97_dai_driver));
-}
-
-static int __devexit pxa2xx_ac97_dev_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(pxa_ac97_dai_driver));
- return 0;
-}
-
-static struct platform_driver pxa2xx_ac97_driver = {
- .probe = pxa2xx_ac97_dev_probe,
- .remove = __devexit_p(pxa2xx_ac97_dev_remove),
- .driver = {
- .name = "pxa2xx-ac97",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(pxa2xx_ac97_driver);
-
-MODULE_AUTHOR("Nicolas Pitre");
-MODULE_DESCRIPTION("AC97 driver for the Intel PXA2xx chip");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/pxa2xx-ac97.h b/ANDROID_3.4.5/sound/soc/pxa/pxa2xx-ac97.h
deleted file mode 100644
index eda891e6..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/pxa2xx-ac97.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * linux/sound/soc/pxa/pxa2xx-ac97.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _PXA2XX_AC97_H
-#define _PXA2XX_AC97_H
-
-/* pxa2xx DAI ID's */
-#define PXA2XX_DAI_AC97_HIFI 0
-#define PXA2XX_DAI_AC97_AUX 1
-#define PXA2XX_DAI_AC97_MIC 2
-
-/* platform data */
-extern struct snd_ac97_bus_ops pxa2xx_ac97_ops;
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/pxa/pxa2xx-i2s.c b/ANDROID_3.4.5/sound/soc/pxa/pxa2xx-i2s.c
deleted file mode 100644
index d0858379..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/pxa2xx-i2s.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * pxa2xx-i2s.c -- ALSA Soc Audio Layer
- *
- * Copyright 2005 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood
- * lrg@slimlogic.co.uk
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-#include <sound/pxa2xx-lib.h>
-
-#include <mach/hardware.h>
-#include <mach/dma.h>
-#include <mach/audio.h>
-
-#include "pxa2xx-i2s.h"
-
-/*
- * I2S Controller Register and Bit Definitions
- */
-#define SACR0 __REG(0x40400000) /* Global Control Register */
-#define SACR1 __REG(0x40400004) /* Serial Audio I 2 S/MSB-Justified Control Register */
-#define SASR0 __REG(0x4040000C) /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */
-#define SAIMR __REG(0x40400014) /* Serial Audio Interrupt Mask Register */
-#define SAICR __REG(0x40400018) /* Serial Audio Interrupt Clear Register */
-#define SADIV __REG(0x40400060) /* Audio Clock Divider Register. */
-#define SADR __REG(0x40400080) /* Serial Audio Data Register (TX and RX FIFO access Register). */
-
-#define SACR0_RFTH(x) ((x) << 12) /* Rx FIFO Interrupt or DMA Trigger Threshold */
-#define SACR0_TFTH(x) ((x) << 8) /* Tx FIFO Interrupt or DMA Trigger Threshold */
-#define SACR0_STRF (1 << 5) /* FIFO Select for EFWR Special Function */
-#define SACR0_EFWR (1 << 4) /* Enable EFWR Function */
-#define SACR0_RST (1 << 3) /* FIFO, i2s Register Reset */
-#define SACR0_BCKD (1 << 2) /* Bit Clock Direction */
-#define SACR0_ENB (1 << 0) /* Enable I2S Link */
-#define SACR1_ENLBF (1 << 5) /* Enable Loopback */
-#define SACR1_DRPL (1 << 4) /* Disable Replaying Function */
-#define SACR1_DREC (1 << 3) /* Disable Recording Function */
-#define SACR1_AMSL (1 << 0) /* Specify Alternate Mode */
-
-#define SASR0_I2SOFF (1 << 7) /* Controller Status */
-#define SASR0_ROR (1 << 6) /* Rx FIFO Overrun */
-#define SASR0_TUR (1 << 5) /* Tx FIFO Underrun */
-#define SASR0_RFS (1 << 4) /* Rx FIFO Service Request */
-#define SASR0_TFS (1 << 3) /* Tx FIFO Service Request */
-#define SASR0_BSY (1 << 2) /* I2S Busy */
-#define SASR0_RNE (1 << 1) /* Rx FIFO Not Empty */
-#define SASR0_TNF (1 << 0) /* Tx FIFO Not Empty */
-
-#define SAICR_ROR (1 << 6) /* Clear Rx FIFO Overrun Interrupt */
-#define SAICR_TUR (1 << 5) /* Clear Tx FIFO Underrun Interrupt */
-
-#define SAIMR_ROR (1 << 6) /* Enable Rx FIFO Overrun Condition Interrupt */
-#define SAIMR_TUR (1 << 5) /* Enable Tx FIFO Underrun Condition Interrupt */
-#define SAIMR_RFS (1 << 4) /* Enable Rx FIFO Service Interrupt */
-#define SAIMR_TFS (1 << 3) /* Enable Tx FIFO Service Interrupt */
-
-struct pxa_i2s_port {
- u32 sadiv;
- u32 sacr0;
- u32 sacr1;
- u32 saimr;
- int master;
- u32 fmt;
-};
-static struct pxa_i2s_port pxa_i2s;
-static struct clk *clk_i2s;
-static int clk_ena = 0;
-
-static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = {
- .name = "I2S PCM Stereo out",
- .dev_addr = __PREG(SADR),
- .drcmr = &DRCMR(3),
- .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
- DCMD_BURST32 | DCMD_WIDTH4,
-};
-
-static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_in = {
- .name = "I2S PCM Stereo in",
- .dev_addr = __PREG(SADR),
- .drcmr = &DRCMR(2),
- .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
- DCMD_BURST32 | DCMD_WIDTH4,
-};
-
-static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-
- if (IS_ERR(clk_i2s))
- return PTR_ERR(clk_i2s);
-
- if (!cpu_dai->active)
- SACR0 = 0;
-
- return 0;
-}
-
-/* wait for I2S controller to be ready */
-static int pxa_i2s_wait(void)
-{
- int i;
-
- /* flush the Rx FIFO */
- for(i = 0; i < 16; i++)
- SADR;
- return 0;
-}
-
-static int pxa2xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
- unsigned int fmt)
-{
- /* interface format */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- pxa_i2s.fmt = 0;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- pxa_i2s.fmt = SACR1_AMSL;
- break;
- }
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- pxa_i2s.master = 1;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- pxa_i2s.master = 0;
- break;
- default:
- break;
- }
- return 0;
-}
-
-static int pxa2xx_i2s_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
- int clk_id, unsigned int freq, int dir)
-{
- if (clk_id != PXA2XX_I2S_SYSCLK)
- return -ENODEV;
-
- return 0;
-}
-
-static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct pxa2xx_pcm_dma_params *dma_data;
-
- BUG_ON(IS_ERR(clk_i2s));
- clk_enable(clk_i2s);
- clk_ena = 1;
- pxa_i2s_wait();
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dma_data = &pxa2xx_i2s_pcm_stereo_out;
- else
- dma_data = &pxa2xx_i2s_pcm_stereo_in;
-
- snd_soc_dai_set_dma_data(dai, substream, dma_data);
-
- /* is port used by another stream */
- if (!(SACR0 & SACR0_ENB)) {
- SACR0 = 0;
- if (pxa_i2s.master)
- SACR0 |= SACR0_BCKD;
-
- SACR0 |= SACR0_RFTH(14) | SACR0_TFTH(1);
- SACR1 |= pxa_i2s.fmt;
- }
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- SAIMR |= SAIMR_TFS;
- else
- SAIMR |= SAIMR_RFS;
-
- switch (params_rate(params)) {
- case 8000:
- SADIV = 0x48;
- break;
- case 11025:
- SADIV = 0x34;
- break;
- case 16000:
- SADIV = 0x24;
- break;
- case 22050:
- SADIV = 0x1a;
- break;
- case 44100:
- SADIV = 0xd;
- break;
- case 48000:
- SADIV = 0xc;
- break;
- case 96000: /* not in manual and possibly slightly inaccurate */
- SADIV = 0x6;
- break;
- }
-
- return 0;
-}
-
-static int pxa2xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- int ret = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- SACR1 &= ~SACR1_DRPL;
- else
- SACR1 &= ~SACR1_DREC;
- SACR0 |= SACR0_ENB;
- break;
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- SACR1 |= SACR1_DRPL;
- SAIMR &= ~SAIMR_TFS;
- } else {
- SACR1 |= SACR1_DREC;
- SAIMR &= ~SAIMR_RFS;
- }
-
- if ((SACR1 & (SACR1_DREC | SACR1_DRPL)) == (SACR1_DREC | SACR1_DRPL)) {
- SACR0 &= ~SACR0_ENB;
- pxa_i2s_wait();
- if (clk_ena) {
- clk_disable(clk_i2s);
- clk_ena = 0;
- }
- }
-}
-
-#ifdef CONFIG_PM
-static int pxa2xx_i2s_suspend(struct snd_soc_dai *dai)
-{
- /* store registers */
- pxa_i2s.sacr0 = SACR0;
- pxa_i2s.sacr1 = SACR1;
- pxa_i2s.saimr = SAIMR;
- pxa_i2s.sadiv = SADIV;
-
- /* deactivate link */
- SACR0 &= ~SACR0_ENB;
- pxa_i2s_wait();
- return 0;
-}
-
-static int pxa2xx_i2s_resume(struct snd_soc_dai *dai)
-{
- pxa_i2s_wait();
-
- SACR0 = pxa_i2s.sacr0 & ~SACR0_ENB;
- SACR1 = pxa_i2s.sacr1;
- SAIMR = pxa_i2s.saimr;
- SADIV = pxa_i2s.sadiv;
-
- SACR0 = pxa_i2s.sacr0;
-
- return 0;
-}
-
-#else
-#define pxa2xx_i2s_suspend NULL
-#define pxa2xx_i2s_resume NULL
-#endif
-
-static int pxa2xx_i2s_probe(struct snd_soc_dai *dai)
-{
- clk_i2s = clk_get(dai->dev, "I2SCLK");
- if (IS_ERR(clk_i2s))
- return PTR_ERR(clk_i2s);
-
- /*
- * PXA Developer's Manual:
- * If SACR0[ENB] is toggled in the middle of a normal operation,
- * the SACR0[RST] bit must also be set and cleared to reset all
- * I2S controller registers.
- */
- SACR0 = SACR0_RST;
- SACR0 = 0;
- /* Make sure RPL and REC are disabled */
- SACR1 = SACR1_DRPL | SACR1_DREC;
- /* Along with FIFO servicing */
- SAIMR &= ~(SAIMR_RFS | SAIMR_TFS);
-
- return 0;
-}
-
-static int pxa2xx_i2s_remove(struct snd_soc_dai *dai)
-{
- clk_put(clk_i2s);
- clk_i2s = ERR_PTR(-ENOENT);
- return 0;
-}
-
-#define PXA2XX_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
- SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
-
-static const struct snd_soc_dai_ops pxa_i2s_dai_ops = {
- .startup = pxa2xx_i2s_startup,
- .shutdown = pxa2xx_i2s_shutdown,
- .trigger = pxa2xx_i2s_trigger,
- .hw_params = pxa2xx_i2s_hw_params,
- .set_fmt = pxa2xx_i2s_set_dai_fmt,
- .set_sysclk = pxa2xx_i2s_set_dai_sysclk,
-};
-
-static struct snd_soc_dai_driver pxa_i2s_dai = {
- .probe = pxa2xx_i2s_probe,
- .remove = pxa2xx_i2s_remove,
- .suspend = pxa2xx_i2s_suspend,
- .resume = pxa2xx_i2s_resume,
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = PXA2XX_I2S_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = PXA2XX_I2S_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .ops = &pxa_i2s_dai_ops,
- .symmetric_rates = 1,
-};
-
-static int pxa2xx_i2s_drv_probe(struct platform_device *pdev)
-{
- return snd_soc_register_dai(&pdev->dev, &pxa_i2s_dai);
-}
-
-static int __devexit pxa2xx_i2s_drv_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_dai(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver pxa2xx_i2s_driver = {
- .probe = pxa2xx_i2s_drv_probe,
- .remove = __devexit_p(pxa2xx_i2s_drv_remove),
-
- .driver = {
- .name = "pxa2xx-i2s",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init pxa2xx_i2s_init(void)
-{
- clk_i2s = ERR_PTR(-ENOENT);
- return platform_driver_register(&pxa2xx_i2s_driver);
-}
-
-static void __exit pxa2xx_i2s_exit(void)
-{
- platform_driver_unregister(&pxa2xx_i2s_driver);
-}
-
-module_init(pxa2xx_i2s_init);
-module_exit(pxa2xx_i2s_exit);
-
-/* Module information */
-MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
-MODULE_DESCRIPTION("pxa2xx I2S SoC Interface");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:pxa2xx-i2s");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/pxa2xx-i2s.h b/ANDROID_3.4.5/sound/soc/pxa/pxa2xx-i2s.h
deleted file mode 100644
index 070f3c60..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/pxa2xx-i2s.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * linux/sound/soc/pxa/pxa2xx-i2s.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _PXA2XX_I2S_H
-#define _PXA2XX_I2S_H
-
-/* pxa2xx DAI ID's */
-#define PXA2XX_DAI_I2S 0
-
-/* I2S clock */
-#define PXA2XX_I2S_SYSCLK 0
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/pxa/pxa2xx-pcm.c b/ANDROID_3.4.5/sound/soc/pxa/pxa2xx-pcm.c
deleted file mode 100644
index fdd6bede..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/pxa2xx-pcm.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * linux/sound/arm/pxa2xx-pcm.c -- ALSA PCM interface for the Intel PXA2xx chip
- *
- * Author: Nicolas Pitre
- * Created: Nov 30, 2004
- * Copyright: (C) 2004 MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/module.h>
-
-#include <sound/core.h>
-#include <sound/soc.h>
-#include <sound/pxa2xx-lib.h>
-
-#include "../../arm/pxa2xx-pcm.h"
-
-static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct pxa2xx_runtime_data *prtd = runtime->private_data;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct pxa2xx_pcm_dma_params *dma;
- int ret;
-
- dma = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
- /* return if this is a bufferless transfer e.g.
- * codec <--> BT codec or GSM modem -- lg FIXME */
- if (!dma)
- return 0;
-
- /* this may get called several times by oss emulation
- * with different params */
- if (prtd->params == NULL) {
- prtd->params = dma;
- ret = pxa_request_dma(prtd->params->name, DMA_PRIO_LOW,
- pxa2xx_pcm_dma_irq, substream);
- if (ret < 0)
- return ret;
- prtd->dma_ch = ret;
- } else if (prtd->params != dma) {
- pxa_free_dma(prtd->dma_ch);
- prtd->params = dma;
- ret = pxa_request_dma(prtd->params->name, DMA_PRIO_LOW,
- pxa2xx_pcm_dma_irq, substream);
- if (ret < 0)
- return ret;
- prtd->dma_ch = ret;
- }
-
- return __pxa2xx_pcm_hw_params(substream, params);
-}
-
-static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
-
- __pxa2xx_pcm_hw_free(substream);
-
- if (prtd->dma_ch >= 0) {
- pxa_free_dma(prtd->dma_ch);
- prtd->dma_ch = -1;
- prtd->params = NULL;
- }
-
- return 0;
-}
-
-static struct snd_pcm_ops pxa2xx_pcm_ops = {
- .open = __pxa2xx_pcm_open,
- .close = __pxa2xx_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = pxa2xx_pcm_hw_params,
- .hw_free = pxa2xx_pcm_hw_free,
- .prepare = __pxa2xx_pcm_prepare,
- .trigger = pxa2xx_pcm_trigger,
- .pointer = pxa2xx_pcm_pointer,
- .mmap = pxa2xx_pcm_mmap,
-};
-
-static u64 pxa2xx_pcm_dmamask = DMA_BIT_MASK(32);
-
-static int pxa2xx_soc_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- int ret = 0;
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &pxa2xx_pcm_dmamask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = pxa2xx_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_PLAYBACK);
- if (ret)
- goto out;
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- ret = pxa2xx_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_CAPTURE);
- if (ret)
- goto out;
- }
- out:
- return ret;
-}
-
-static struct snd_soc_platform_driver pxa2xx_soc_platform = {
- .ops = &pxa2xx_pcm_ops,
- .pcm_new = pxa2xx_soc_pcm_new,
- .pcm_free = pxa2xx_pcm_free_dma_buffers,
-};
-
-static int __devinit pxa2xx_soc_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_platform(&pdev->dev, &pxa2xx_soc_platform);
-}
-
-static int __devexit pxa2xx_soc_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver pxa_pcm_driver = {
- .driver = {
- .name = "pxa-pcm-audio",
- .owner = THIS_MODULE,
- },
-
- .probe = pxa2xx_soc_platform_probe,
- .remove = __devexit_p(pxa2xx_soc_platform_remove),
-};
-
-module_platform_driver(pxa_pcm_driver);
-
-MODULE_AUTHOR("Nicolas Pitre");
-MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/raumfeld.c b/ANDROID_3.4.5/sound/soc/pxa/raumfeld.c
deleted file mode 100644
index 08370659..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/raumfeld.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * raumfeld_audio.c -- SoC audio for Raumfeld audio devices
- *
- * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
- *
- * based on code from:
- *
- * Wolfson Microelectronics PLC.
- * Openedhand Ltd.
- * Liam Girdwood <lrg@slimlogic.co.uk>
- * Richard Purdie <richard@openedhand.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-
-#include "pxa-ssp.h"
-
-#define GPIO_SPDIF_RESET (38)
-#define GPIO_MCLK_RESET (111)
-#define GPIO_CODEC_RESET (120)
-
-static struct i2c_client *max9486_client;
-static struct i2c_board_info max9486_hwmon_info = {
- I2C_BOARD_INFO("max9485", 0x63),
-};
-
-#define MAX9485_MCLK_FREQ_112896 0x22
-#define MAX9485_MCLK_FREQ_122880 0x23
-#define MAX9485_MCLK_FREQ_225792 0x32
-#define MAX9485_MCLK_FREQ_245760 0x33
-
-static void set_max9485_clk(char clk)
-{
- i2c_master_send(max9486_client, &clk, 1);
-}
-
-static void raumfeld_enable_audio(bool en)
-{
- if (en) {
- gpio_set_value(GPIO_MCLK_RESET, 1);
-
- /* wait some time to let the clocks become stable */
- msleep(100);
-
- gpio_set_value(GPIO_SPDIF_RESET, 1);
- gpio_set_value(GPIO_CODEC_RESET, 1);
- } else {
- gpio_set_value(GPIO_MCLK_RESET, 0);
- gpio_set_value(GPIO_SPDIF_RESET, 0);
- gpio_set_value(GPIO_CODEC_RESET, 0);
- }
-}
-
-/* CS4270 */
-static int raumfeld_cs4270_startup(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
-
- /* set freq to 0 to enable all possible codec sample rates */
- return snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
-}
-
-static void raumfeld_cs4270_shutdown(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
-
- /* set freq to 0 to enable all possible codec sample rates */
- snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
-}
-
-static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- unsigned int fmt, clk = 0;
- int ret = 0;
-
- switch (params_rate(params)) {
- case 44100:
- set_max9485_clk(MAX9485_MCLK_FREQ_112896);
- clk = 11289600;
- break;
- case 48000:
- set_max9485_clk(MAX9485_MCLK_FREQ_122880);
- clk = 12288000;
- break;
- case 88200:
- set_max9485_clk(MAX9485_MCLK_FREQ_225792);
- clk = 22579200;
- break;
- case 96000:
- set_max9485_clk(MAX9485_MCLK_FREQ_245760);
- clk = 24576000;
- break;
- default:
- return -EINVAL;
- }
-
- fmt = SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS;
-
- /* setup the CODEC DAI */
- ret = snd_soc_dai_set_fmt(codec_dai, fmt);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, 0);
- if (ret < 0)
- return ret;
-
- /* setup the CPU DAI */
- ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, clk);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops raumfeld_cs4270_ops = {
- .startup = raumfeld_cs4270_startup,
- .shutdown = raumfeld_cs4270_shutdown,
- .hw_params = raumfeld_cs4270_hw_params,
-};
-
-static int raumfeld_analog_suspend(struct snd_soc_card *card)
-{
- raumfeld_enable_audio(false);
- return 0;
-}
-
-static int raumfeld_analog_resume(struct snd_soc_card *card)
-{
- raumfeld_enable_audio(true);
- return 0;
-}
-
-/* AK4104 */
-
-static int raumfeld_ak4104_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int fmt, ret = 0, clk = 0;
-
- switch (params_rate(params)) {
- case 44100:
- set_max9485_clk(MAX9485_MCLK_FREQ_112896);
- clk = 11289600;
- break;
- case 48000:
- set_max9485_clk(MAX9485_MCLK_FREQ_122880);
- clk = 12288000;
- break;
- case 88200:
- set_max9485_clk(MAX9485_MCLK_FREQ_225792);
- clk = 22579200;
- break;
- case 96000:
- set_max9485_clk(MAX9485_MCLK_FREQ_245760);
- clk = 24576000;
- break;
- default:
- return -EINVAL;
- }
-
- fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF;
-
- /* setup the CODEC DAI */
- ret = snd_soc_dai_set_fmt(codec_dai, fmt | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* setup the CPU DAI */
- ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, clk);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_fmt(cpu_dai, fmt | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops raumfeld_ak4104_ops = {
- .hw_params = raumfeld_ak4104_hw_params,
-};
-
-#define DAI_LINK_CS4270 \
-{ \
- .name = "CS4270", \
- .stream_name = "CS4270", \
- .cpu_dai_name = "pxa-ssp-dai.0", \
- .platform_name = "pxa-pcm-audio", \
- .codec_dai_name = "cs4270-hifi", \
- .codec_name = "cs4270.0-0048", \
- .ops = &raumfeld_cs4270_ops, \
-}
-
-#define DAI_LINK_AK4104 \
-{ \
- .name = "ak4104", \
- .stream_name = "Playback", \
- .cpu_dai_name = "pxa-ssp-dai.1", \
- .codec_dai_name = "ak4104-hifi", \
- .platform_name = "pxa-pcm-audio", \
- .ops = &raumfeld_ak4104_ops, \
- .codec_name = "spi0.0", \
-}
-
-static struct snd_soc_dai_link snd_soc_raumfeld_connector_dai[] =
-{
- DAI_LINK_CS4270,
- DAI_LINK_AK4104,
-};
-
-static struct snd_soc_dai_link snd_soc_raumfeld_speaker_dai[] =
-{
- DAI_LINK_CS4270,
-};
-
-static struct snd_soc_card snd_soc_raumfeld_connector = {
- .name = "Raumfeld Connector",
- .owner = THIS_MODULE,
- .dai_link = snd_soc_raumfeld_connector_dai,
- .num_links = ARRAY_SIZE(snd_soc_raumfeld_connector_dai),
- .suspend_post = raumfeld_analog_suspend,
- .resume_pre = raumfeld_analog_resume,
-};
-
-static struct snd_soc_card snd_soc_raumfeld_speaker = {
- .name = "Raumfeld Speaker",
- .owner = THIS_MODULE,
- .dai_link = snd_soc_raumfeld_speaker_dai,
- .num_links = ARRAY_SIZE(snd_soc_raumfeld_speaker_dai),
- .suspend_post = raumfeld_analog_suspend,
- .resume_pre = raumfeld_analog_resume,
-};
-
-static struct platform_device *raumfeld_audio_device;
-
-static int __init raumfeld_audio_init(void)
-{
- int ret;
-
- if (!machine_is_raumfeld_speaker() &&
- !machine_is_raumfeld_connector())
- return 0;
-
- max9486_client = i2c_new_device(i2c_get_adapter(0),
- &max9486_hwmon_info);
-
- if (!max9486_client)
- return -ENOMEM;
-
- set_max9485_clk(MAX9485_MCLK_FREQ_122880);
-
- /* Register analog device */
- raumfeld_audio_device = platform_device_alloc("soc-audio", 0);
- if (!raumfeld_audio_device)
- return -ENOMEM;
-
- if (machine_is_raumfeld_speaker())
- platform_set_drvdata(raumfeld_audio_device,
- &snd_soc_raumfeld_speaker);
-
- if (machine_is_raumfeld_connector())
- platform_set_drvdata(raumfeld_audio_device,
- &snd_soc_raumfeld_connector);
-
- ret = platform_device_add(raumfeld_audio_device);
- if (ret < 0) {
- platform_device_put(raumfeld_audio_device);
- return ret;
- }
-
- raumfeld_enable_audio(true);
- return 0;
-}
-
-static void __exit raumfeld_audio_exit(void)
-{
- raumfeld_enable_audio(false);
-
- platform_device_unregister(raumfeld_audio_device);
-
- i2c_unregister_device(max9486_client);
-
- gpio_free(GPIO_MCLK_RESET);
- gpio_free(GPIO_CODEC_RESET);
- gpio_free(GPIO_SPDIF_RESET);
-}
-
-module_init(raumfeld_audio_init);
-module_exit(raumfeld_audio_exit);
-
-/* Module information */
-MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
-MODULE_DESCRIPTION("Raumfeld audio SoC");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/saarb.c b/ANDROID_3.4.5/sound/soc/pxa/saarb.c
deleted file mode 100644
index c34146b7..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/saarb.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * saarb.c -- SoC audio for saarb
- *
- * Copyright (C) 2010 Marvell International Ltd.
- * Haojian Zhuang <haojian.zhuang@marvell.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/clk.h>
-#include <linux/i2c.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/jack.h>
-
-#include <asm/mach-types.h>
-
-#include "../codecs/88pm860x-codec.h"
-#include "pxa-ssp.h"
-
-static int saarb_pm860x_init(struct snd_soc_pcm_runtime *rtd);
-
-static struct platform_device *saarb_snd_device;
-
-static struct snd_soc_jack hs_jack, mic_jack;
-
-static struct snd_soc_jack_pin hs_jack_pins[] = {
- { .pin = "Headset Stereophone", .mask = SND_JACK_HEADPHONE, },
-};
-
-static struct snd_soc_jack_pin mic_jack_pins[] = {
- { .pin = "Headset Mic 2", .mask = SND_JACK_MICROPHONE, },
-};
-
-/* saarb machine dapm widgets */
-static const struct snd_soc_dapm_widget saarb_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Stereophone", NULL),
- SND_SOC_DAPM_LINE("Lineout Out 1", NULL),
- SND_SOC_DAPM_LINE("Lineout Out 2", NULL),
- SND_SOC_DAPM_SPK("Ext Speaker", NULL),
- SND_SOC_DAPM_MIC("Ext Mic 1", NULL),
- SND_SOC_DAPM_MIC("Headset Mic", NULL),
- SND_SOC_DAPM_MIC("Ext Mic 3", NULL),
-};
-
-/* saarb machine audio map */
-static const struct snd_soc_dapm_route saarb_audio_map[] = {
- {"Headset Stereophone", NULL, "HS1"},
- {"Headset Stereophone", NULL, "HS2"},
-
- {"Ext Speaker", NULL, "LSP"},
- {"Ext Speaker", NULL, "LSN"},
-
- {"Lineout Out 1", NULL, "LINEOUT1"},
- {"Lineout Out 2", NULL, "LINEOUT2"},
-
- {"MIC1P", NULL, "Mic1 Bias"},
- {"MIC1N", NULL, "Mic1 Bias"},
- {"Mic1 Bias", NULL, "Ext Mic 1"},
-
- {"MIC2P", NULL, "Mic1 Bias"},
- {"MIC2N", NULL, "Mic1 Bias"},
- {"Mic1 Bias", NULL, "Headset Mic 2"},
-
- {"MIC3P", NULL, "Mic3 Bias"},
- {"MIC3N", NULL, "Mic3 Bias"},
- {"Mic3 Bias", NULL, "Ext Mic 3"},
-};
-
-static int saarb_i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int width = snd_pcm_format_physical_width(params_format(params));
- int ret;
-
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_NET_PLL, 0,
- PM860X_CLK_DIR_OUT);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, 0, PM860X_CLK_DIR_OUT);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_tdm_slot(cpu_dai, 3, 3, 2, width);
-
- return ret;
-}
-
-static struct snd_soc_ops saarb_i2s_ops = {
- .hw_params = saarb_i2s_hw_params,
-};
-
-static struct snd_soc_dai_link saarb_dai[] = {
- {
- .name = "88PM860x I2S",
- .stream_name = "I2S Audio",
- .cpu_dai_name = "pxa-ssp-dai.1",
- .codec_dai_name = "88pm860x-i2s",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "88pm860x-codec",
- .init = saarb_pm860x_init,
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM,
- .ops = &saarb_i2s_ops,
- },
-};
-
-static struct snd_soc_card snd_soc_card_saarb = {
- .name = "Saarb",
- .owner = THIS_MODULE,
- .dai_link = saarb_dai,
- .num_links = ARRAY_SIZE(saarb_dai),
-
- .dapm_widgets = saarb_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(saarb_dapm_widgets),
- .dapm_routes = saarb_audio_map,
- .num_dapm_routes = ARRAY_SIZE(saarb_audio_map),
-};
-
-static int saarb_pm860x_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- /* connected pins */
- snd_soc_dapm_enable_pin(dapm, "Ext Speaker");
- snd_soc_dapm_enable_pin(dapm, "Ext Mic 1");
- snd_soc_dapm_enable_pin(dapm, "Ext Mic 3");
- snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
- snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
-
- /* Headset jack detection */
- snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE
- | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2,
- &hs_jack);
- snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
- hs_jack_pins);
- snd_soc_jack_new(codec, "Microphone Jack", SND_JACK_MICROPHONE,
- &mic_jack);
- snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins),
- mic_jack_pins);
-
- /* headphone, microphone detection & headset short detection */
- pm860x_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADPHONE,
- SND_JACK_BTN_0, SND_JACK_BTN_1, SND_JACK_BTN_2);
- pm860x_mic_jack_detect(codec, &hs_jack, SND_JACK_MICROPHONE);
- return 0;
-}
-
-static int __init saarb_init(void)
-{
- int ret;
-
- if (!machine_is_saarb())
- return -ENODEV;
- saarb_snd_device = platform_device_alloc("soc-audio", -1);
- if (!saarb_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(saarb_snd_device, &snd_soc_card_saarb);
-
- ret = platform_device_add(saarb_snd_device);
- if (ret)
- platform_device_put(saarb_snd_device);
-
- return ret;
-}
-
-static void __exit saarb_exit(void)
-{
- platform_device_unregister(saarb_snd_device);
-}
-
-module_init(saarb_init);
-module_exit(saarb_exit);
-
-MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
-MODULE_DESCRIPTION("ALSA SoC 88PM860x Saarb");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/spitz.c b/ANDROID_3.4.5/sound/soc/pxa/spitz.c
deleted file mode 100644
index fc052d82..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/spitz.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * spitz.c -- SoC audio for Sharp SL-Cxx00 models Spitz, Borzoi and Akita
- *
- * Copyright 2005 Wolfson Microelectronics PLC.
- * Copyright 2005 Openedhand Ltd.
- *
- * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
- * Richard Purdie <richard@openedhand.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/spitz.h>
-#include "../codecs/wm8750.h"
-#include "pxa2xx-i2s.h"
-
-#define SPITZ_HP 0
-#define SPITZ_MIC 1
-#define SPITZ_LINE 2
-#define SPITZ_HEADSET 3
-#define SPITZ_HP_OFF 4
-#define SPITZ_SPK_ON 0
-#define SPITZ_SPK_OFF 1
-
- /* audio clock in Hz - rounded from 12.235MHz */
-#define SPITZ_AUDIO_CLOCK 12288000
-
-static int spitz_jack_func;
-static int spitz_spk_func;
-static int spitz_mic_gpio;
-
-static void spitz_ext_control(struct snd_soc_dapm_context *dapm)
-{
- if (spitz_spk_func == SPITZ_SPK_ON)
- snd_soc_dapm_enable_pin(dapm, "Ext Spk");
- else
- snd_soc_dapm_disable_pin(dapm, "Ext Spk");
-
- /* set up jack connection */
- switch (spitz_jack_func) {
- case SPITZ_HP:
- /* enable and unmute hp jack, disable mic bias */
- snd_soc_dapm_disable_pin(dapm, "Headset Jack");
- snd_soc_dapm_disable_pin(dapm, "Mic Jack");
- snd_soc_dapm_disable_pin(dapm, "Line Jack");
- snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
- gpio_set_value(SPITZ_GPIO_MUTE_L, 1);
- gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
- break;
- case SPITZ_MIC:
- /* enable mic jack and bias, mute hp */
- snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_disable_pin(dapm, "Headset Jack");
- snd_soc_dapm_disable_pin(dapm, "Line Jack");
- snd_soc_dapm_enable_pin(dapm, "Mic Jack");
- gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
- gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
- break;
- case SPITZ_LINE:
- /* enable line jack, disable mic bias and mute hp */
- snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_disable_pin(dapm, "Headset Jack");
- snd_soc_dapm_disable_pin(dapm, "Mic Jack");
- snd_soc_dapm_enable_pin(dapm, "Line Jack");
- gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
- gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
- break;
- case SPITZ_HEADSET:
- /* enable and unmute headset jack enable mic bias, mute L hp */
- snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_enable_pin(dapm, "Mic Jack");
- snd_soc_dapm_disable_pin(dapm, "Line Jack");
- snd_soc_dapm_enable_pin(dapm, "Headset Jack");
- gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
- gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
- break;
- case SPITZ_HP_OFF:
-
- /* jack removed, everything off */
- snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_disable_pin(dapm, "Headset Jack");
- snd_soc_dapm_disable_pin(dapm, "Mic Jack");
- snd_soc_dapm_disable_pin(dapm, "Line Jack");
- gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
- gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
- break;
- }
- snd_soc_dapm_sync(dapm);
-}
-
-static int spitz_startup(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
-
- mutex_lock(&codec->mutex);
-
- /* check the jack status at stream startup */
- spitz_ext_control(&codec->dapm);
-
- mutex_unlock(&codec->mutex);
-
- return 0;
-}
-
-static int spitz_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- unsigned int clk = 0;
- int ret = 0;
-
- switch (params_rate(params)) {
- case 8000:
- case 16000:
- case 48000:
- case 96000:
- clk = 12288000;
- break;
- case 11025:
- case 22050:
- case 44100:
- clk = 11289600;
- break;
- }
-
- /* set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk,
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- /* set the I2S system clock as input (unused) */
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops spitz_ops = {
- .startup = spitz_startup,
- .hw_params = spitz_hw_params,
-};
-
-static int spitz_get_jack(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = spitz_jack_func;
- return 0;
-}
-
-static int spitz_set_jack(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
-
- if (spitz_jack_func == ucontrol->value.integer.value[0])
- return 0;
-
- spitz_jack_func = ucontrol->value.integer.value[0];
- spitz_ext_control(&card->dapm);
- return 1;
-}
-
-static int spitz_get_spk(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = spitz_spk_func;
- return 0;
-}
-
-static int spitz_set_spk(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
-
- if (spitz_spk_func == ucontrol->value.integer.value[0])
- return 0;
-
- spitz_spk_func = ucontrol->value.integer.value[0];
- spitz_ext_control(&card->dapm);
- return 1;
-}
-
-static int spitz_mic_bias(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- gpio_set_value_cansleep(spitz_mic_gpio, SND_SOC_DAPM_EVENT_ON(event));
- return 0;
-}
-
-/* spitz machine dapm widgets */
-static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_MIC("Mic Jack", spitz_mic_bias),
- SND_SOC_DAPM_SPK("Ext Spk", NULL),
- SND_SOC_DAPM_LINE("Line Jack", NULL),
-
- /* headset is a mic and mono headphone */
- SND_SOC_DAPM_HP("Headset Jack", NULL),
-};
-
-/* Spitz machine audio_map */
-static const struct snd_soc_dapm_route spitz_audio_map[] = {
-
- /* headphone connected to LOUT1, ROUT1 */
- {"Headphone Jack", NULL, "LOUT1"},
- {"Headphone Jack", NULL, "ROUT1"},
-
- /* headset connected to ROUT1 and LINPUT1 with bias (def below) */
- {"Headset Jack", NULL, "ROUT1"},
-
- /* ext speaker connected to LOUT2, ROUT2 */
- {"Ext Spk", NULL , "ROUT2"},
- {"Ext Spk", NULL , "LOUT2"},
-
- /* mic is connected to input 1 - with bias */
- {"LINPUT1", NULL, "Mic Bias"},
- {"Mic Bias", NULL, "Mic Jack"},
-
- /* line is connected to input 1 - no bias */
- {"LINPUT1", NULL, "Line Jack"},
-};
-
-static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset",
- "Off"};
-static const char *spk_function[] = {"On", "Off"};
-static const struct soc_enum spitz_enum[] = {
- SOC_ENUM_SINGLE_EXT(5, jack_function),
- SOC_ENUM_SINGLE_EXT(2, spk_function),
-};
-
-static const struct snd_kcontrol_new wm8750_spitz_controls[] = {
- SOC_ENUM_EXT("Jack Function", spitz_enum[0], spitz_get_jack,
- spitz_set_jack),
- SOC_ENUM_EXT("Speaker Function", spitz_enum[1], spitz_get_spk,
- spitz_set_spk),
-};
-
-/*
- * Logic for a wm8750 as connected on a Sharp SL-Cxx00 Device
- */
-static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- /* NC codec pins */
- snd_soc_dapm_nc_pin(dapm, "RINPUT1");
- snd_soc_dapm_nc_pin(dapm, "LINPUT2");
- snd_soc_dapm_nc_pin(dapm, "RINPUT2");
- snd_soc_dapm_nc_pin(dapm, "LINPUT3");
- snd_soc_dapm_nc_pin(dapm, "RINPUT3");
- snd_soc_dapm_nc_pin(dapm, "OUT3");
- snd_soc_dapm_nc_pin(dapm, "MONO1");
-
- return 0;
-}
-
-/* spitz digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link spitz_dai = {
- .name = "wm8750",
- .stream_name = "WM8750",
- .cpu_dai_name = "pxa2xx-i2s",
- .codec_dai_name = "wm8750-hifi",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "wm8750.0-001b",
- .init = spitz_wm8750_init,
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS,
- .ops = &spitz_ops,
-};
-
-/* spitz audio machine driver */
-static struct snd_soc_card snd_soc_spitz = {
- .name = "Spitz",
- .owner = THIS_MODULE,
- .dai_link = &spitz_dai,
- .num_links = 1,
-
- .controls = wm8750_spitz_controls,
- .num_controls = ARRAY_SIZE(wm8750_spitz_controls),
- .dapm_widgets = wm8750_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets),
- .dapm_routes = spitz_audio_map,
- .num_dapm_routes = ARRAY_SIZE(spitz_audio_map),
-};
-
-static struct platform_device *spitz_snd_device;
-
-static int __init spitz_init(void)
-{
- int ret;
-
- if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita()))
- return -ENODEV;
-
- if (machine_is_borzoi() || machine_is_spitz())
- spitz_mic_gpio = SPITZ_GPIO_MIC_BIAS;
- else
- spitz_mic_gpio = AKITA_GPIO_MIC_BIAS;
-
- ret = gpio_request(spitz_mic_gpio, "MIC GPIO");
- if (ret)
- goto err1;
-
- ret = gpio_direction_output(spitz_mic_gpio, 0);
- if (ret)
- goto err2;
-
- spitz_snd_device = platform_device_alloc("soc-audio", -1);
- if (!spitz_snd_device) {
- ret = -ENOMEM;
- goto err2;
- }
-
- platform_set_drvdata(spitz_snd_device, &snd_soc_spitz);
-
- ret = platform_device_add(spitz_snd_device);
- if (ret)
- goto err3;
-
- return 0;
-
-err3:
- platform_device_put(spitz_snd_device);
-err2:
- gpio_free(spitz_mic_gpio);
-err1:
- return ret;
-}
-
-static void __exit spitz_exit(void)
-{
- platform_device_unregister(spitz_snd_device);
- gpio_free(spitz_mic_gpio);
-}
-
-module_init(spitz_init);
-module_exit(spitz_exit);
-
-MODULE_AUTHOR("Richard Purdie");
-MODULE_DESCRIPTION("ALSA SoC Spitz");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/tavorevb3.c b/ANDROID_3.4.5/sound/soc/pxa/tavorevb3.c
deleted file mode 100644
index 8b5ab8f7..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/tavorevb3.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * tavorevb3.c -- SoC audio for Tavor EVB3
- *
- * Copyright (C) 2010 Marvell International Ltd.
- * Haojian Zhuang <haojian.zhuang@marvell.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/clk.h>
-#include <linux/i2c.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/jack.h>
-
-#include <asm/mach-types.h>
-
-#include "../codecs/88pm860x-codec.h"
-#include "pxa-ssp.h"
-
-static int evb3_pm860x_init(struct snd_soc_pcm_runtime *rtd);
-
-static struct platform_device *evb3_snd_device;
-
-static struct snd_soc_jack hs_jack, mic_jack;
-
-static struct snd_soc_jack_pin hs_jack_pins[] = {
- { .pin = "Headset Stereophone", .mask = SND_JACK_HEADPHONE, },
-};
-
-static struct snd_soc_jack_pin mic_jack_pins[] = {
- { .pin = "Headset Mic 2", .mask = SND_JACK_MICROPHONE, },
-};
-
-/* tavorevb3 machine dapm widgets */
-static const struct snd_soc_dapm_widget evb3_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headset Stereophone", NULL),
- SND_SOC_DAPM_LINE("Lineout Out 1", NULL),
- SND_SOC_DAPM_LINE("Lineout Out 2", NULL),
- SND_SOC_DAPM_SPK("Ext Speaker", NULL),
- SND_SOC_DAPM_MIC("Ext Mic 1", NULL),
- SND_SOC_DAPM_MIC("Headset Mic 2", NULL),
- SND_SOC_DAPM_MIC("Ext Mic 3", NULL),
-};
-
-/* tavorevb3 machine audio map */
-static const struct snd_soc_dapm_route evb3_audio_map[] = {
- {"Headset Stereophone", NULL, "HS1"},
- {"Headset Stereophone", NULL, "HS2"},
-
- {"Ext Speaker", NULL, "LSP"},
- {"Ext Speaker", NULL, "LSN"},
-
- {"Lineout Out 1", NULL, "LINEOUT1"},
- {"Lineout Out 2", NULL, "LINEOUT2"},
-
- {"MIC1P", NULL, "Mic1 Bias"},
- {"MIC1N", NULL, "Mic1 Bias"},
- {"Mic1 Bias", NULL, "Ext Mic 1"},
-
- {"MIC2P", NULL, "Mic1 Bias"},
- {"MIC2N", NULL, "Mic1 Bias"},
- {"Mic1 Bias", NULL, "Headset Mic 2"},
-
- {"MIC3P", NULL, "Mic3 Bias"},
- {"MIC3N", NULL, "Mic3 Bias"},
- {"Mic3 Bias", NULL, "Ext Mic 3"},
-};
-
-static int evb3_i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int width = snd_pcm_format_physical_width(params_format(params));
- int ret;
-
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_NET_PLL, 0,
- PM860X_CLK_DIR_OUT);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, 0, PM860X_CLK_DIR_OUT);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_tdm_slot(cpu_dai, 3, 3, 2, width);
- return ret;
-}
-
-static struct snd_soc_ops evb3_i2s_ops = {
- .hw_params = evb3_i2s_hw_params,
-};
-
-static struct snd_soc_dai_link evb3_dai[] = {
- {
- .name = "88PM860x I2S",
- .stream_name = "I2S Audio",
- .cpu_dai_name = "pxa-ssp-dai.1",
- .codec_dai_name = "88pm860x-i2s",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "88pm860x-codec",
- .init = evb3_pm860x_init,
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM,
- .ops = &evb3_i2s_ops,
- },
-};
-
-static struct snd_soc_card snd_soc_card_evb3 = {
- .name = "Tavor EVB3",
- .owner = THIS_MODULE,
- .dai_link = evb3_dai,
- .num_links = ARRAY_SIZE(evb3_dai),
-
- .dapm_widgets = evb3_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(evb3_dapm_widgets),
- .dapm_routes = evb3_audio_map,
- .num_dapm_routes = ARRAY_SIZE(evb3_audio_map),
-};
-
-static int evb3_pm860x_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- /* connected pins */
- snd_soc_dapm_enable_pin(dapm, "Ext Speaker");
- snd_soc_dapm_enable_pin(dapm, "Ext Mic 1");
- snd_soc_dapm_enable_pin(dapm, "Ext Mic 3");
- snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
- snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
-
- /* Headset jack detection */
- snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE
- | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2,
- &hs_jack);
- snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
- hs_jack_pins);
- snd_soc_jack_new(codec, "Microphone Jack", SND_JACK_MICROPHONE,
- &mic_jack);
- snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins),
- mic_jack_pins);
-
- /* headphone, microphone detection & headset short detection */
- pm860x_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADPHONE,
- SND_JACK_BTN_0, SND_JACK_BTN_1, SND_JACK_BTN_2);
- pm860x_mic_jack_detect(codec, &hs_jack, SND_JACK_MICROPHONE);
- return 0;
-}
-
-static int __init tavorevb3_init(void)
-{
- int ret;
-
- if (!machine_is_tavorevb3())
- return -ENODEV;
- evb3_snd_device = platform_device_alloc("soc-audio", -1);
- if (!evb3_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(evb3_snd_device, &snd_soc_card_evb3);
-
- ret = platform_device_add(evb3_snd_device);
- if (ret)
- platform_device_put(evb3_snd_device);
-
- return ret;
-}
-
-static void __exit tavorevb3_exit(void)
-{
- platform_device_unregister(evb3_snd_device);
-}
-
-module_init(tavorevb3_init);
-module_exit(tavorevb3_exit);
-
-MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
-MODULE_DESCRIPTION("ALSA SoC 88PM860x Tavor EVB3");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/tosa.c b/ANDROID_3.4.5/sound/soc/pxa/tosa.c
deleted file mode 100644
index 2aec63f3..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/tosa.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * tosa.c -- SoC audio for Tosa
- *
- * Copyright 2005 Wolfson Microelectronics PLC.
- * Copyright 2005 Openedhand Ltd.
- *
- * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
- * Richard Purdie <richard@openedhand.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * GPIO's
- * 1 - Jack Insertion
- * 5 - Hookswitch (headset answer/hang up switch)
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/gpio.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/tosa.h>
-#include <mach/audio.h>
-
-#include "../codecs/wm9712.h"
-#include "pxa2xx-ac97.h"
-
-#define TOSA_HP 0
-#define TOSA_MIC_INT 1
-#define TOSA_HEADSET 2
-#define TOSA_HP_OFF 3
-#define TOSA_SPK_ON 0
-#define TOSA_SPK_OFF 1
-
-static int tosa_jack_func;
-static int tosa_spk_func;
-
-static void tosa_ext_control(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- /* set up jack connection */
- switch (tosa_jack_func) {
- case TOSA_HP:
- snd_soc_dapm_disable_pin(dapm, "Mic (Internal)");
- snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_disable_pin(dapm, "Headset Jack");
- break;
- case TOSA_MIC_INT:
- snd_soc_dapm_enable_pin(dapm, "Mic (Internal)");
- snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_disable_pin(dapm, "Headset Jack");
- break;
- case TOSA_HEADSET:
- snd_soc_dapm_disable_pin(dapm, "Mic (Internal)");
- snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_enable_pin(dapm, "Headset Jack");
- break;
- }
-
- if (tosa_spk_func == TOSA_SPK_ON)
- snd_soc_dapm_enable_pin(dapm, "Speaker");
- else
- snd_soc_dapm_disable_pin(dapm, "Speaker");
-
- snd_soc_dapm_sync(dapm);
-}
-
-static int tosa_startup(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
-
- mutex_lock(&codec->mutex);
-
- /* check the jack status at stream startup */
- tosa_ext_control(codec);
-
- mutex_unlock(&codec->mutex);
-
- return 0;
-}
-
-static struct snd_soc_ops tosa_ops = {
- .startup = tosa_startup,
-};
-
-static int tosa_get_jack(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = tosa_jack_func;
- return 0;
-}
-
-static int tosa_set_jack(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-
- if (tosa_jack_func == ucontrol->value.integer.value[0])
- return 0;
-
- tosa_jack_func = ucontrol->value.integer.value[0];
- tosa_ext_control(codec);
- return 1;
-}
-
-static int tosa_get_spk(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = tosa_spk_func;
- return 0;
-}
-
-static int tosa_set_spk(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-
- if (tosa_spk_func == ucontrol->value.integer.value[0])
- return 0;
-
- tosa_spk_func = ucontrol->value.integer.value[0];
- tosa_ext_control(codec);
- return 1;
-}
-
-/* tosa dapm event handlers */
-static int tosa_hp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- gpio_set_value(TOSA_GPIO_L_MUTE, SND_SOC_DAPM_EVENT_ON(event) ? 1 :0);
- return 0;
-}
-
-/* tosa machine dapm widgets */
-static const struct snd_soc_dapm_widget tosa_dapm_widgets[] = {
-SND_SOC_DAPM_HP("Headphone Jack", tosa_hp_event),
-SND_SOC_DAPM_HP("Headset Jack", NULL),
-SND_SOC_DAPM_MIC("Mic (Internal)", NULL),
-SND_SOC_DAPM_SPK("Speaker", NULL),
-};
-
-/* tosa audio map */
-static const struct snd_soc_dapm_route audio_map[] = {
-
- /* headphone connected to HPOUTL, HPOUTR */
- {"Headphone Jack", NULL, "HPOUTL"},
- {"Headphone Jack", NULL, "HPOUTR"},
-
- /* ext speaker connected to LOUT2, ROUT2 */
- {"Speaker", NULL, "LOUT2"},
- {"Speaker", NULL, "ROUT2"},
-
- /* internal mic is connected to mic1, mic2 differential - with bias */
- {"MIC1", NULL, "Mic Bias"},
- {"MIC2", NULL, "Mic Bias"},
- {"Mic Bias", NULL, "Mic (Internal)"},
-
- /* headset is connected to HPOUTR, and LINEINR with bias */
- {"Headset Jack", NULL, "HPOUTR"},
- {"LINEINR", NULL, "Mic Bias"},
- {"Mic Bias", NULL, "Headset Jack"},
-};
-
-static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset",
- "Off"};
-static const char *spk_function[] = {"On", "Off"};
-static const struct soc_enum tosa_enum[] = {
- SOC_ENUM_SINGLE_EXT(5, jack_function),
- SOC_ENUM_SINGLE_EXT(2, spk_function),
-};
-
-static const struct snd_kcontrol_new tosa_controls[] = {
- SOC_ENUM_EXT("Jack Function", tosa_enum[0], tosa_get_jack,
- tosa_set_jack),
- SOC_ENUM_EXT("Speaker Function", tosa_enum[1], tosa_get_spk,
- tosa_set_spk),
-};
-
-static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int err;
-
- snd_soc_dapm_nc_pin(dapm, "OUT3");
- snd_soc_dapm_nc_pin(dapm, "MONOOUT");
-
- /* add tosa specific controls */
- err = snd_soc_add_codec_controls(codec, tosa_controls,
- ARRAY_SIZE(tosa_controls));
- if (err < 0)
- return err;
-
- /* add tosa specific widgets */
- snd_soc_dapm_new_controls(dapm, tosa_dapm_widgets,
- ARRAY_SIZE(tosa_dapm_widgets));
-
- /* set up tosa specific audio path audio_map */
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
- return 0;
-}
-
-static struct snd_soc_dai_link tosa_dai[] = {
-{
- .name = "AC97",
- .stream_name = "AC97 HiFi",
- .cpu_dai_name = "pxa2xx-ac97",
- .codec_dai_name = "wm9712-hifi",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "wm9712-codec",
- .init = tosa_ac97_init,
- .ops = &tosa_ops,
-},
-{
- .name = "AC97 Aux",
- .stream_name = "AC97 Aux",
- .cpu_dai_name = "pxa2xx-ac97-aux",
- .codec_dai_name = "wm9712-aux",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "wm9712-codec",
- .ops = &tosa_ops,
-},
-};
-
-static struct snd_soc_card tosa = {
- .name = "Tosa",
- .owner = THIS_MODULE,
- .dai_link = tosa_dai,
- .num_links = ARRAY_SIZE(tosa_dai),
-};
-
-static int __devinit tosa_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &tosa;
- int ret;
-
- ret = gpio_request_one(TOSA_GPIO_L_MUTE, GPIOF_OUT_INIT_LOW,
- "Headphone Jack");
- if (ret)
- return ret;
-
- card->dev = &pdev->dev;
-
- ret = snd_soc_register_card(card);
- if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
- ret);
- gpio_free(TOSA_GPIO_L_MUTE);
- }
- return ret;
-}
-
-static int __devexit tosa_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- gpio_free(TOSA_GPIO_L_MUTE);
- snd_soc_unregister_card(card);
- return 0;
-}
-
-static struct platform_driver tosa_driver = {
- .driver = {
- .name = "tosa-audio",
- .owner = THIS_MODULE,
- },
- .probe = tosa_probe,
- .remove = __devexit_p(tosa_remove),
-};
-
-module_platform_driver(tosa_driver);
-
-/* Module information */
-MODULE_AUTHOR("Richard Purdie");
-MODULE_DESCRIPTION("ALSA SoC Tosa");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:tosa-audio");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/z2.c b/ANDROID_3.4.5/sound/soc/pxa/z2.c
deleted file mode 100644
index 76ccb172..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/z2.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * linux/sound/soc/pxa/z2.c
- *
- * SoC Audio driver for Aeronix Zipit Z2
- *
- * Copyright (C) 2009 Ken McGuire <kenm@desertweyr.com>
- * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/jack.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/audio.h>
-#include <mach/z2.h>
-
-#include "../codecs/wm8750.h"
-#include "pxa2xx-i2s.h"
-
-static struct snd_soc_card snd_soc_z2;
-
-static int z2_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- unsigned int clk = 0;
- int ret = 0;
-
- switch (params_rate(params)) {
- case 8000:
- case 16000:
- case 48000:
- case 96000:
- clk = 12288000;
- break;
- case 11025:
- case 22050:
- case 44100:
- clk = 11289600;
- break;
- }
-
- /* set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk,
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- /* set the I2S system clock as input (unused) */
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_jack hs_jack;
-
-/* Headset jack detection DAPM pins */
-static struct snd_soc_jack_pin hs_jack_pins[] = {
- {
- .pin = "Mic Jack",
- .mask = SND_JACK_MICROPHONE,
- },
- {
- .pin = "Headphone Jack",
- .mask = SND_JACK_HEADPHONE,
- },
- {
- .pin = "Ext Spk",
- .mask = SND_JACK_HEADPHONE,
- .invert = 1
- },
-};
-
-/* Headset jack detection gpios */
-static struct snd_soc_jack_gpio hs_jack_gpios[] = {
- {
- .gpio = GPIO37_ZIPITZ2_HEADSET_DETECT,
- .name = "hsdet-gpio",
- .report = SND_JACK_HEADSET,
- .debounce_time = 200,
- .invert = 1,
- },
-};
-
-/* z2 machine dapm widgets */
-static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_MIC("Mic Jack", NULL),
- SND_SOC_DAPM_SPK("Ext Spk", NULL),
-
- /* headset is a mic and mono headphone */
- SND_SOC_DAPM_HP("Headset Jack", NULL),
-};
-
-/* Z2 machine audio_map */
-static const struct snd_soc_dapm_route z2_audio_map[] = {
-
- /* headphone connected to LOUT1, ROUT1 */
- {"Headphone Jack", NULL, "LOUT1"},
- {"Headphone Jack", NULL, "ROUT1"},
-
- /* ext speaker connected to LOUT2, ROUT2 */
- {"Ext Spk", NULL , "ROUT2"},
- {"Ext Spk", NULL , "LOUT2"},
-
- /* mic is connected to R input 2 - with bias */
- {"RINPUT2", NULL, "Mic Bias"},
- {"Mic Bias", NULL, "Mic Jack"},
-};
-
-/*
- * Logic for a wm8750 as connected on a Z2 Device
- */
-static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret;
-
- /* NC codec pins */
- snd_soc_dapm_disable_pin(dapm, "LINPUT3");
- snd_soc_dapm_disable_pin(dapm, "RINPUT3");
- snd_soc_dapm_disable_pin(dapm, "OUT3");
- snd_soc_dapm_disable_pin(dapm, "MONO1");
-
- /* Jack detection API stuff */
- ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
- &hs_jack);
- if (ret)
- goto err;
-
- ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
- hs_jack_pins);
- if (ret)
- goto err;
-
- ret = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios),
- hs_jack_gpios);
- if (ret)
- goto err;
-
- return 0;
-
-err:
- return ret;
-}
-
-static struct snd_soc_ops z2_ops = {
- .hw_params = z2_hw_params,
-};
-
-/* z2 digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link z2_dai = {
- .name = "wm8750",
- .stream_name = "WM8750",
- .cpu_dai_name = "pxa2xx-i2s",
- .codec_dai_name = "wm8750-hifi",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "wm8750.0-001b",
- .init = z2_wm8750_init,
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS,
- .ops = &z2_ops,
-};
-
-/* z2 audio machine driver */
-static struct snd_soc_card snd_soc_z2 = {
- .name = "Z2",
- .owner = THIS_MODULE,
- .dai_link = &z2_dai,
- .num_links = 1,
-
- .dapm_widgets = wm8750_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets),
- .dapm_routes = z2_audio_map,
- .num_dapm_routes = ARRAY_SIZE(z2_audio_map),
-};
-
-static struct platform_device *z2_snd_device;
-
-static int __init z2_init(void)
-{
- int ret;
-
- if (!machine_is_zipit2())
- return -ENODEV;
-
- z2_snd_device = platform_device_alloc("soc-audio", -1);
- if (!z2_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(z2_snd_device, &snd_soc_z2);
- ret = platform_device_add(z2_snd_device);
-
- if (ret)
- platform_device_put(z2_snd_device);
-
- return ret;
-}
-
-static void __exit z2_exit(void)
-{
- platform_device_unregister(z2_snd_device);
-}
-
-module_init(z2_init);
-module_exit(z2_exit);
-
-MODULE_AUTHOR("Ken McGuire <kenm@desertweyr.com>, "
- "Marek Vasut <marek.vasut@gmail.com>");
-MODULE_DESCRIPTION("ALSA SoC ZipitZ2");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/pxa/zylonite.c b/ANDROID_3.4.5/sound/soc/pxa/zylonite.c
deleted file mode 100644
index ceb65669..00000000
--- a/ANDROID_3.4.5/sound/soc/pxa/zylonite.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * zylonite.c -- SoC audio for Zylonite
- *
- * Copyright 2008 Wolfson Microelectronics PLC.
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/clk.h>
-#include <linux/i2c.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include "../codecs/wm9713.h"
-#include "pxa2xx-ac97.h"
-#include "pxa-ssp.h"
-
-/*
- * There is a physical switch SW15 on the board which changes the MCLK
- * for the WM9713 between the standard AC97 master clock and the
- * output of the CLK_POUT signal from the PXA.
- */
-static int clk_pout;
-module_param(clk_pout, int, 0);
-MODULE_PARM_DESC(clk_pout, "Use CLK_POUT as WM9713 MCLK (SW15 on board).");
-
-static struct clk *pout;
-
-static struct snd_soc_card zylonite;
-
-static const struct snd_soc_dapm_widget zylonite_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone", NULL),
- SND_SOC_DAPM_MIC("Headset Microphone", NULL),
- SND_SOC_DAPM_MIC("Handset Microphone", NULL),
- SND_SOC_DAPM_SPK("Multiactor", NULL),
- SND_SOC_DAPM_SPK("Headset Earpiece", NULL),
-};
-
-/* Currently supported audio map */
-static const struct snd_soc_dapm_route audio_map[] = {
-
- /* Headphone output connected to HPL/HPR */
- { "Headphone", NULL, "HPL" },
- { "Headphone", NULL, "HPR" },
-
- /* On-board earpiece */
- { "Headset Earpiece", NULL, "OUT3" },
-
- /* Headphone mic */
- { "MIC2A", NULL, "Mic Bias" },
- { "Mic Bias", NULL, "Headset Microphone" },
-
- /* On-board mic */
- { "MIC1", NULL, "Mic Bias" },
- { "Mic Bias", NULL, "Handset Microphone" },
-
- /* Multiactor differentially connected over SPKL/SPKR */
- { "Multiactor", NULL, "SPKL" },
- { "Multiactor", NULL, "SPKR" },
-};
-
-static int zylonite_wm9713_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- if (clk_pout)
- snd_soc_dai_set_pll(rtd->codec_dai, 0, 0,
- clk_get_rate(pout), 0);
-
- snd_soc_dapm_new_controls(dapm, zylonite_dapm_widgets,
- ARRAY_SIZE(zylonite_dapm_widgets));
-
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
- /* Static setup for now */
- snd_soc_dapm_enable_pin(dapm, "Headphone");
- snd_soc_dapm_enable_pin(dapm, "Headset Earpiece");
-
- return 0;
-}
-
-static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- unsigned int pll_out = 0;
- unsigned int wm9713_div = 0;
- int ret = 0;
- int rate = params_rate(params);
- int width = snd_pcm_format_physical_width(params_format(params));
-
- /* Only support ratios that we can generate neatly from the AC97
- * based master clock - in particular, this excludes 44.1kHz.
- * In most applications the voice DAC will be used for telephony
- * data so multiples of 8kHz will be the common case.
- */
- switch (rate) {
- case 8000:
- wm9713_div = 12;
- break;
- case 16000:
- wm9713_div = 6;
- break;
- case 48000:
- wm9713_div = 2;
- break;
- default:
- /* Don't support OSS emulation */
- return -EINVAL;
- }
-
- /* Add 1 to the width for the leading clock cycle */
- pll_out = rate * (width + 1) * 8;
-
- ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, pll_out);
- if (ret < 0)
- return ret;
-
- if (clk_pout)
- ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_PLL_DIV,
- WM9713_PCMDIV(wm9713_div));
- else
- ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_DIV,
- WM9713_PCMDIV(wm9713_div));
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops zylonite_voice_ops = {
- .hw_params = zylonite_voice_hw_params,
-};
-
-static struct snd_soc_dai_link zylonite_dai[] = {
-{
- .name = "AC97",
- .stream_name = "AC97 HiFi",
- .codec_name = "wm9713-codec",
- .platform_name = "pxa-pcm-audio",
- .cpu_dai_name = "pxa2xx-ac97",
- .codec_dai_name = "wm9713-hifi",
- .init = zylonite_wm9713_init,
-},
-{
- .name = "AC97 Aux",
- .stream_name = "AC97 Aux",
- .codec_name = "wm9713-codec",
- .platform_name = "pxa-pcm-audio",
- .cpu_dai_name = "pxa2xx-ac97-aux",
- .codec_dai_name = "wm9713-aux",
-},
-{
- .name = "WM9713 Voice",
- .stream_name = "WM9713 Voice",
- .codec_name = "wm9713-codec",
- .platform_name = "pxa-pcm-audio",
- .cpu_dai_name = "pxa-ssp-dai.2",
- .codec_dai_name = "wm9713-voice",
- .ops = &zylonite_voice_ops,
-},
-};
-
-static int zylonite_probe(struct snd_soc_card *card)
-{
- int ret;
-
- if (clk_pout) {
- pout = clk_get(NULL, "CLK_POUT");
- if (IS_ERR(pout)) {
- dev_err(card->dev, "Unable to obtain CLK_POUT: %ld\n",
- PTR_ERR(pout));
- return PTR_ERR(pout);
- }
-
- ret = clk_enable(pout);
- if (ret != 0) {
- dev_err(card->dev, "Unable to enable CLK_POUT: %d\n",
- ret);
- clk_put(pout);
- return ret;
- }
-
- dev_dbg(card->dev, "MCLK enabled at %luHz\n",
- clk_get_rate(pout));
- }
-
- return 0;
-}
-
-static int zylonite_remove(struct snd_soc_card *card)
-{
- if (clk_pout) {
- clk_disable(pout);
- clk_put(pout);
- }
-
- return 0;
-}
-
-static int zylonite_suspend_post(struct snd_soc_card *card)
-{
- if (clk_pout)
- clk_disable(pout);
-
- return 0;
-}
-
-static int zylonite_resume_pre(struct snd_soc_card *card)
-{
- int ret = 0;
-
- if (clk_pout) {
- ret = clk_enable(pout);
- if (ret != 0)
- dev_err(card->dev, "Unable to enable CLK_POUT: %d\n",
- ret);
- }
-
- return ret;
-}
-
-static struct snd_soc_card zylonite = {
- .name = "Zylonite",
- .owner = THIS_MODULE,
- .probe = &zylonite_probe,
- .remove = &zylonite_remove,
- .suspend_post = &zylonite_suspend_post,
- .resume_pre = &zylonite_resume_pre,
- .dai_link = zylonite_dai,
- .num_links = ARRAY_SIZE(zylonite_dai),
- .owner = THIS_MODULE,
-};
-
-static struct platform_device *zylonite_snd_ac97_device;
-
-static int __init zylonite_init(void)
-{
- int ret;
-
- zylonite_snd_ac97_device = platform_device_alloc("soc-audio", -1);
- if (!zylonite_snd_ac97_device)
- return -ENOMEM;
-
- platform_set_drvdata(zylonite_snd_ac97_device, &zylonite);
-
- ret = platform_device_add(zylonite_snd_ac97_device);
- if (ret != 0)
- platform_device_put(zylonite_snd_ac97_device);
-
- return ret;
-}
-
-static void __exit zylonite_exit(void)
-{
- platform_device_unregister(zylonite_snd_ac97_device);
-}
-
-module_init(zylonite_init);
-module_exit(zylonite_exit);
-
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_DESCRIPTION("ALSA SoC WM9713 Zylonite");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/s6000/Kconfig b/ANDROID_3.4.5/sound/soc/s6000/Kconfig
deleted file mode 100644
index c74eb3d4..00000000
--- a/ANDROID_3.4.5/sound/soc/s6000/Kconfig
+++ /dev/null
@@ -1,19 +0,0 @@
-config SND_S6000_SOC
- tristate "SoC Audio for the Stretch s6000 family"
- depends on XTENSA_VARIANT_S6000
- help
- Say Y or M if you want to add support for codecs attached to
- s6000 family chips. You will also need to select the platform
- to support below.
-
-config SND_S6000_SOC_I2S
- tristate
-
-config SND_S6000_SOC_S6IPCAM
- tristate "SoC Audio support for Stretch 6105 IP Camera"
- depends on SND_S6000_SOC && XTENSA_PLATFORM_S6105
- select SND_S6000_SOC_I2S
- select SND_SOC_TLV320AIC3X
- help
- Say Y if you want to add support for SoC audio on the
- Stretch s6105 IP Camera Reference Design.
diff --git a/ANDROID_3.4.5/sound/soc/s6000/Makefile b/ANDROID_3.4.5/sound/soc/s6000/Makefile
deleted file mode 100644
index 7a613612..00000000
--- a/ANDROID_3.4.5/sound/soc/s6000/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# s6000 Platform Support
-snd-soc-s6000-objs := s6000-pcm.o
-snd-soc-s6000-i2s-objs := s6000-i2s.o
-
-obj-$(CONFIG_SND_S6000_SOC) += snd-soc-s6000.o
-obj-$(CONFIG_SND_S6000_SOC_I2S) += snd-soc-s6000-i2s.o
-
-# s6105 Machine Support
-snd-soc-s6ipcam-objs := s6105-ipcam.o
-
-obj-$(CONFIG_SND_S6000_SOC_S6IPCAM) += snd-soc-s6ipcam.o
diff --git a/ANDROID_3.4.5/sound/soc/s6000/s6000-i2s.c b/ANDROID_3.4.5/sound/soc/s6000/s6000-i2s.c
deleted file mode 100644
index aaabdbae..00000000
--- a/ANDROID_3.4.5/sound/soc/s6000/s6000-i2s.c
+++ /dev/null
@@ -1,611 +0,0 @@
-/*
- * ALSA SoC I2S Audio Layer for the Stretch S6000 family
- *
- * Author: Daniel Gloeckner, <dg@emlix.com>
- * Copyright: (C) 2009 emlix GmbH <info@emlix.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include "s6000-i2s.h"
-#include "s6000-pcm.h"
-
-struct s6000_i2s_dev {
- dma_addr_t sifbase;
- u8 __iomem *scbbase;
- unsigned int wide;
- unsigned int channel_in;
- unsigned int channel_out;
- unsigned int lines_in;
- unsigned int lines_out;
- struct s6000_pcm_dma_params dma_params;
-};
-
-#define S6_I2S_INTERRUPT_STATUS 0x00
-#define S6_I2S_INT_OVERRUN 1
-#define S6_I2S_INT_UNDERRUN 2
-#define S6_I2S_INT_ALIGNMENT 4
-#define S6_I2S_INTERRUPT_ENABLE 0x04
-#define S6_I2S_INTERRUPT_RAW 0x08
-#define S6_I2S_INTERRUPT_CLEAR 0x0C
-#define S6_I2S_INTERRUPT_SET 0x10
-#define S6_I2S_MODE 0x20
-#define S6_I2S_DUAL 0
-#define S6_I2S_WIDE 1
-#define S6_I2S_TX_DEFAULT 0x24
-#define S6_I2S_DATA_CFG(c) (0x40 + 0x10 * (c))
-#define S6_I2S_IN 0
-#define S6_I2S_OUT 1
-#define S6_I2S_UNUSED 2
-#define S6_I2S_INTERFACE_CFG(c) (0x44 + 0x10 * (c))
-#define S6_I2S_DIV_MASK 0x001fff
-#define S6_I2S_16BIT 0x000000
-#define S6_I2S_20BIT 0x002000
-#define S6_I2S_24BIT 0x004000
-#define S6_I2S_32BIT 0x006000
-#define S6_I2S_BITS_MASK 0x006000
-#define S6_I2S_MEM_16BIT 0x000000
-#define S6_I2S_MEM_32BIT 0x008000
-#define S6_I2S_MEM_MASK 0x008000
-#define S6_I2S_CHANNELS_SHIFT 16
-#define S6_I2S_CHANNELS_MASK 0x030000
-#define S6_I2S_SCK_IN 0x000000
-#define S6_I2S_SCK_OUT 0x040000
-#define S6_I2S_SCK_DIR 0x040000
-#define S6_I2S_WS_IN 0x000000
-#define S6_I2S_WS_OUT 0x080000
-#define S6_I2S_WS_DIR 0x080000
-#define S6_I2S_LEFT_FIRST 0x000000
-#define S6_I2S_RIGHT_FIRST 0x100000
-#define S6_I2S_FIRST 0x100000
-#define S6_I2S_CUR_SCK 0x200000
-#define S6_I2S_CUR_WS 0x400000
-#define S6_I2S_ENABLE(c) (0x48 + 0x10 * (c))
-#define S6_I2S_DISABLE_IF 0x02
-#define S6_I2S_ENABLE_IF 0x03
-#define S6_I2S_IS_BUSY 0x04
-#define S6_I2S_DMA_ACTIVE 0x08
-#define S6_I2S_IS_ENABLED 0x10
-
-#define S6_I2S_NUM_LINES 4
-
-#define S6_I2S_SIF_PORT0 0x0000000
-#define S6_I2S_SIF_PORT1 0x0000080 /* docs say 0x0000010 */
-
-static inline void s6_i2s_write_reg(struct s6000_i2s_dev *dev, int reg, u32 val)
-{
- writel(val, dev->scbbase + reg);
-}
-
-static inline u32 s6_i2s_read_reg(struct s6000_i2s_dev *dev, int reg)
-{
- return readl(dev->scbbase + reg);
-}
-
-static inline void s6_i2s_mod_reg(struct s6000_i2s_dev *dev, int reg,
- u32 mask, u32 val)
-{
- val ^= s6_i2s_read_reg(dev, reg) & ~mask;
- s6_i2s_write_reg(dev, reg, val);
-}
-
-static void s6000_i2s_start_channel(struct s6000_i2s_dev *dev, int channel)
-{
- int i, j, cur, prev;
-
- /*
- * Wait for WCLK to toggle 5 times before enabling the channel
- * s6000 Family Datasheet 3.6.4:
- * "At least two cycles of WS must occur between commands
- * to disable or enable the interface"
- */
- j = 0;
- prev = ~S6_I2S_CUR_WS;
- for (i = 1000000; --i && j < 6; ) {
- cur = s6_i2s_read_reg(dev, S6_I2S_INTERFACE_CFG(channel))
- & S6_I2S_CUR_WS;
- if (prev != cur) {
- prev = cur;
- j++;
- }
- }
- if (j < 6)
- printk(KERN_WARNING "s6000-i2s: timeout waiting for WCLK\n");
-
- s6_i2s_write_reg(dev, S6_I2S_ENABLE(channel), S6_I2S_ENABLE_IF);
-}
-
-static void s6000_i2s_stop_channel(struct s6000_i2s_dev *dev, int channel)
-{
- s6_i2s_write_reg(dev, S6_I2S_ENABLE(channel), S6_I2S_DISABLE_IF);
-}
-
-static void s6000_i2s_start(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(rtd->cpu_dai);
- int channel;
-
- channel = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
- dev->channel_out : dev->channel_in;
-
- s6000_i2s_start_channel(dev, channel);
-}
-
-static void s6000_i2s_stop(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(rtd->cpu_dai);
- int channel;
-
- channel = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
- dev->channel_out : dev->channel_in;
-
- s6000_i2s_stop_channel(dev, channel);
-}
-
-static int s6000_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
- int after)
-{
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) ^ !after)
- s6000_i2s_start(substream);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (!after)
- s6000_i2s_stop(substream);
- }
- return 0;
-}
-
-static unsigned int s6000_i2s_int_sources(struct s6000_i2s_dev *dev)
-{
- unsigned int pending;
- pending = s6_i2s_read_reg(dev, S6_I2S_INTERRUPT_RAW);
- pending &= S6_I2S_INT_ALIGNMENT |
- S6_I2S_INT_UNDERRUN |
- S6_I2S_INT_OVERRUN;
- s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_CLEAR, pending);
-
- return pending;
-}
-
-static unsigned int s6000_i2s_check_xrun(struct snd_soc_dai *cpu_dai)
-{
- struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
- unsigned int errors;
- unsigned int ret;
-
- errors = s6000_i2s_int_sources(dev);
- if (likely(!errors))
- return 0;
-
- ret = 0;
- if (errors & S6_I2S_INT_ALIGNMENT)
- printk(KERN_ERR "s6000-i2s: WCLK misaligned\n");
- if (errors & S6_I2S_INT_UNDERRUN)
- ret |= 1 << SNDRV_PCM_STREAM_PLAYBACK;
- if (errors & S6_I2S_INT_OVERRUN)
- ret |= 1 << SNDRV_PCM_STREAM_CAPTURE;
- return ret;
-}
-
-static void s6000_i2s_wait_disabled(struct s6000_i2s_dev *dev)
-{
- int channel;
- int n = 50;
- for (channel = 0; channel < 2; channel++) {
- while (--n >= 0) {
- int v = s6_i2s_read_reg(dev, S6_I2S_ENABLE(channel));
- if ((v & S6_I2S_IS_ENABLED)
- || !(v & (S6_I2S_DMA_ACTIVE | S6_I2S_IS_BUSY)))
- break;
- udelay(20);
- }
- }
- if (n < 0)
- printk(KERN_WARNING "s6000-i2s: timeout disabling interfaces");
-}
-
-static int s6000_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
- unsigned int fmt)
-{
- struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
- u32 w;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- w = S6_I2S_SCK_IN | S6_I2S_WS_IN;
- break;
- case SND_SOC_DAIFMT_CBS_CFM:
- w = S6_I2S_SCK_OUT | S6_I2S_WS_IN;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- w = S6_I2S_SCK_IN | S6_I2S_WS_OUT;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- w = S6_I2S_SCK_OUT | S6_I2S_WS_OUT;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- w |= S6_I2S_LEFT_FIRST;
- break;
- case SND_SOC_DAIFMT_NB_IF:
- w |= S6_I2S_RIGHT_FIRST;
- break;
- default:
- return -EINVAL;
- }
-
- s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(0),
- S6_I2S_FIRST | S6_I2S_WS_DIR | S6_I2S_SCK_DIR, w);
- s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(1),
- S6_I2S_FIRST | S6_I2S_WS_DIR | S6_I2S_SCK_DIR, w);
-
- return 0;
-}
-
-static int s6000_i2s_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div)
-{
- struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
-
- if (!div || (div & 1) || div > (S6_I2S_DIV_MASK + 1) * 2)
- return -EINVAL;
-
- s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(div_id),
- S6_I2S_DIV_MASK, div / 2 - 1);
- return 0;
-}
-
-static int s6000_i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
- int interf;
- u32 w = 0;
-
- if (dev->wide)
- interf = 0;
- else {
- w |= (((params_channels(params) - 2) / 2)
- << S6_I2S_CHANNELS_SHIFT) & S6_I2S_CHANNELS_MASK;
- interf = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- ? dev->channel_out : dev->channel_in;
- }
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- w |= S6_I2S_16BIT | S6_I2S_MEM_16BIT;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- w |= S6_I2S_32BIT | S6_I2S_MEM_32BIT;
- break;
- default:
- printk(KERN_WARNING "s6000-i2s: unsupported PCM format %x\n",
- params_format(params));
- return -EINVAL;
- }
-
- if (s6_i2s_read_reg(dev, S6_I2S_INTERFACE_CFG(interf))
- & S6_I2S_IS_ENABLED) {
- printk(KERN_ERR "s6000-i2s: interface already enabled\n");
- return -EBUSY;
- }
-
- s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(interf),
- S6_I2S_CHANNELS_MASK|S6_I2S_MEM_MASK|S6_I2S_BITS_MASK,
- w);
-
- return 0;
-}
-
-static int s6000_i2s_dai_probe(struct snd_soc_dai *dai)
-{
- struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
- struct s6000_snd_platform_data *pdata = dai->dev->platform_data;
-
- if (!pdata)
- return -EINVAL;
-
- dai->capture_dma_data = &dev->dma_params;
- dai->playback_dma_data = &dev->dma_params;
-
- dev->wide = pdata->wide;
- dev->channel_in = pdata->channel_in;
- dev->channel_out = pdata->channel_out;
- dev->lines_in = pdata->lines_in;
- dev->lines_out = pdata->lines_out;
-
- s6_i2s_write_reg(dev, S6_I2S_MODE,
- dev->wide ? S6_I2S_WIDE : S6_I2S_DUAL);
-
- if (dev->wide) {
- int i;
-
- if (dev->lines_in + dev->lines_out > S6_I2S_NUM_LINES)
- return -EINVAL;
-
- dev->channel_in = 0;
- dev->channel_out = 1;
- dai->driver->capture.channels_min = 2 * dev->lines_in;
- dai->driver->capture.channels_max = dai->driver->capture.channels_min;
- dai->driver->playback.channels_min = 2 * dev->lines_out;
- dai->driver->playback.channels_max = dai->driver->playback.channels_min;
-
- for (i = 0; i < dev->lines_out; i++)
- s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(i), S6_I2S_OUT);
-
- for (; i < S6_I2S_NUM_LINES - dev->lines_in; i++)
- s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(i),
- S6_I2S_UNUSED);
-
- for (; i < S6_I2S_NUM_LINES; i++)
- s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(i), S6_I2S_IN);
- } else {
- unsigned int cfg[2] = {S6_I2S_UNUSED, S6_I2S_UNUSED};
-
- if (dev->lines_in > 1 || dev->lines_out > 1)
- return -EINVAL;
-
- dai->driver->capture.channels_min = 2 * dev->lines_in;
- dai->driver->capture.channels_max = 8 * dev->lines_in;
- dai->driver->playback.channels_min = 2 * dev->lines_out;
- dai->driver->playback.channels_max = 8 * dev->lines_out;
-
- if (dev->lines_in)
- cfg[dev->channel_in] = S6_I2S_IN;
- if (dev->lines_out)
- cfg[dev->channel_out] = S6_I2S_OUT;
-
- s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(0), cfg[0]);
- s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(1), cfg[1]);
- }
-
- if (dev->lines_out) {
- if (dev->lines_in) {
- if (!dev->dma_params.dma_out)
- return -ENODEV;
- } else {
- dev->dma_params.dma_out = dev->dma_params.dma_in;
- dev->dma_params.dma_in = 0;
- }
- }
- dev->dma_params.sif_in = dev->sifbase + (dev->channel_in ?
- S6_I2S_SIF_PORT1 : S6_I2S_SIF_PORT0);
- dev->dma_params.sif_out = dev->sifbase + (dev->channel_out ?
- S6_I2S_SIF_PORT1 : S6_I2S_SIF_PORT0);
- dev->dma_params.same_rate = pdata->same_rate | pdata->wide;
- return 0;
-}
-
-#define S6000_I2S_RATES (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_5512 | \
- SNDRV_PCM_RATE_8000_192000)
-#define S6000_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops s6000_i2s_dai_ops = {
- .set_fmt = s6000_i2s_set_dai_fmt,
- .set_clkdiv = s6000_i2s_set_clkdiv,
- .hw_params = s6000_i2s_hw_params,
-};
-
-static struct snd_soc_dai_driver s6000_i2s_dai = {
- .probe = s6000_i2s_dai_probe,
- .playback = {
- .channels_min = 2,
- .channels_max = 8,
- .formats = S6000_I2S_FORMATS,
- .rates = S6000_I2S_RATES,
- .rate_min = 0,
- .rate_max = 1562500,
- },
- .capture = {
- .channels_min = 2,
- .channels_max = 8,
- .formats = S6000_I2S_FORMATS,
- .rates = S6000_I2S_RATES,
- .rate_min = 0,
- .rate_max = 1562500,
- },
- .ops = &s6000_i2s_dai_ops,
-};
-
-static int __devinit s6000_i2s_probe(struct platform_device *pdev)
-{
- struct s6000_i2s_dev *dev;
- struct resource *scbmem, *sifmem, *region, *dma1, *dma2;
- u8 __iomem *mmio;
- int ret;
-
- scbmem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!scbmem) {
- dev_err(&pdev->dev, "no mem resource?\n");
- ret = -ENODEV;
- goto err_release_none;
- }
-
- region = request_mem_region(scbmem->start, resource_size(scbmem),
- pdev->name);
- if (!region) {
- dev_err(&pdev->dev, "I2S SCB region already claimed\n");
- ret = -EBUSY;
- goto err_release_none;
- }
-
- mmio = ioremap(scbmem->start, resource_size(scbmem));
- if (!mmio) {
- dev_err(&pdev->dev, "can't ioremap SCB region\n");
- ret = -ENOMEM;
- goto err_release_scb;
- }
-
- sifmem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (!sifmem) {
- dev_err(&pdev->dev, "no second mem resource?\n");
- ret = -ENODEV;
- goto err_release_map;
- }
-
- region = request_mem_region(sifmem->start, resource_size(sifmem),
- pdev->name);
- if (!region) {
- dev_err(&pdev->dev, "I2S SIF region already claimed\n");
- ret = -EBUSY;
- goto err_release_map;
- }
-
- dma1 = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!dma1) {
- dev_err(&pdev->dev, "no dma resource?\n");
- ret = -ENODEV;
- goto err_release_sif;
- }
-
- region = request_mem_region(dma1->start, resource_size(dma1),
- pdev->name);
- if (!region) {
- dev_err(&pdev->dev, "I2S DMA region already claimed\n");
- ret = -EBUSY;
- goto err_release_sif;
- }
-
- dma2 = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (dma2) {
- region = request_mem_region(dma2->start, resource_size(dma2),
- pdev->name);
- if (!region) {
- dev_err(&pdev->dev,
- "I2S DMA region already claimed\n");
- ret = -EBUSY;
- goto err_release_dma1;
- }
- }
-
- dev = kzalloc(sizeof(struct s6000_i2s_dev), GFP_KERNEL);
- if (!dev) {
- ret = -ENOMEM;
- goto err_release_dma2;
- }
- dev_set_drvdata(&pdev->dev, dev);
-
- dev->sifbase = sifmem->start;
- dev->scbbase = mmio;
-
- s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE, 0);
- s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_CLEAR,
- S6_I2S_INT_ALIGNMENT |
- S6_I2S_INT_UNDERRUN |
- S6_I2S_INT_OVERRUN);
-
- s6000_i2s_stop_channel(dev, 0);
- s6000_i2s_stop_channel(dev, 1);
- s6000_i2s_wait_disabled(dev);
-
- dev->dma_params.check_xrun = s6000_i2s_check_xrun;
- dev->dma_params.trigger = s6000_i2s_trigger;
- dev->dma_params.dma_in = dma1->start;
- dev->dma_params.dma_out = dma2 ? dma2->start : 0;
- dev->dma_params.irq = platform_get_irq(pdev, 0);
- if (dev->dma_params.irq < 0) {
- dev_err(&pdev->dev, "no irq resource?\n");
- ret = -ENODEV;
- goto err_release_dev;
- }
-
- s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE,
- S6_I2S_INT_ALIGNMENT |
- S6_I2S_INT_UNDERRUN |
- S6_I2S_INT_OVERRUN);
-
- ret = snd_soc_register_dai(&pdev->dev, &s6000_i2s_dai);
- if (ret)
- goto err_release_dev;
-
- return 0;
-
-err_release_dev:
- kfree(dev);
-err_release_dma2:
- if (dma2)
- release_mem_region(dma2->start, resource_size(dma2));
-err_release_dma1:
- release_mem_region(dma1->start, resource_size(dma1));
-err_release_sif:
- release_mem_region(sifmem->start, resource_size(sifmem));
-err_release_map:
- iounmap(mmio);
-err_release_scb:
- release_mem_region(scbmem->start, resource_size(scbmem));
-err_release_none:
- return ret;
-}
-
-static void __devexit s6000_i2s_remove(struct platform_device *pdev)
-{
- struct s6000_i2s_dev *dev = dev_get_drvdata(&pdev->dev);
- struct resource *region;
- void __iomem *mmio = dev->scbbase;
-
- snd_soc_unregister_dai(&pdev->dev);
-
- s6000_i2s_stop_channel(dev, 0);
- s6000_i2s_stop_channel(dev, 1);
-
- s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE, 0);
- kfree(dev);
-
- region = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- release_mem_region(region->start, resource_size(region));
-
- region = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (region)
- release_mem_region(region->start, resource_size(region));
-
- region = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(region->start, resource_size(region));
-
- iounmap(mmio);
- region = platform_get_resource(pdev, IORESOURCE_IO, 0);
- release_mem_region(region->start, resource_size(region));
-}
-
-static struct platform_driver s6000_i2s_driver = {
- .probe = s6000_i2s_probe,
- .remove = __devexit_p(s6000_i2s_remove),
- .driver = {
- .name = "s6000-i2s",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(s6000_i2s_driver);
-
-MODULE_AUTHOR("Daniel Gloeckner");
-MODULE_DESCRIPTION("Stretch s6000 family I2S SoC Interface");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/s6000/s6000-i2s.h b/ANDROID_3.4.5/sound/soc/s6000/s6000-i2s.h
deleted file mode 100644
index 86aa1921..00000000
--- a/ANDROID_3.4.5/sound/soc/s6000/s6000-i2s.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * ALSA SoC I2S Audio Layer for the Stretch s6000 family
- *
- * Author: Daniel Gloeckner, <dg@emlix.com>
- * Copyright: (C) 2009 emlix GmbH <info@emlix.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _S6000_I2S_H
-#define _S6000_I2S_H
-
-struct s6000_snd_platform_data {
- int lines_in;
- int lines_out;
- int channel_in;
- int channel_out;
- int wide;
- int same_rate;
-};
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/s6000/s6000-pcm.c b/ANDROID_3.4.5/sound/soc/s6000/s6000-pcm.c
deleted file mode 100644
index 716da861..00000000
--- a/ANDROID_3.4.5/sound/soc/s6000/s6000-pcm.c
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
- * ALSA PCM interface for the Stetch s6000 family
- *
- * Author: Daniel Gloeckner, <dg@emlix.com>
- * Copyright: (C) 2009 emlix GmbH <info@emlix.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/dma-mapping.h>
-#include <linux/interrupt.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/dma.h>
-#include <variant/dmac.h>
-
-#include "s6000-pcm.h"
-
-#define S6_PCM_PREALLOCATE_SIZE (96 * 1024)
-#define S6_PCM_PREALLOCATE_MAX (2048 * 1024)
-
-static struct snd_pcm_hardware s6000_pcm_hardware = {
- .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_JOINT_DUPLEX),
- .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE),
- .rates = (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_5512 | \
- SNDRV_PCM_RATE_8000_192000),
- .rate_min = 0,
- .rate_max = 1562500,
- .channels_min = 2,
- .channels_max = 8,
- .buffer_bytes_max = 0x7ffffff0,
- .period_bytes_min = 16,
- .period_bytes_max = 0xfffff0,
- .periods_min = 2,
- .periods_max = 1024, /* no limit */
- .fifo_size = 0,
-};
-
-struct s6000_runtime_data {
- spinlock_t lock;
- int period; /* current DMA period */
-};
-
-static void s6000_pcm_enqueue_dma(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct s6000_runtime_data *prtd = runtime->private_data;
- struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par;
- int channel;
- unsigned int period_size;
- unsigned int dma_offset;
- dma_addr_t dma_pos;
- dma_addr_t src, dst;
-
- par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
-
- period_size = snd_pcm_lib_period_bytes(substream);
- dma_offset = prtd->period * period_size;
- dma_pos = runtime->dma_addr + dma_offset;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- src = dma_pos;
- dst = par->sif_out;
- channel = par->dma_out;
- } else {
- src = par->sif_in;
- dst = dma_pos;
- channel = par->dma_in;
- }
-
- if (!s6dmac_channel_enabled(DMA_MASK_DMAC(channel),
- DMA_INDEX_CHNL(channel)))
- return;
-
- if (s6dmac_fifo_full(DMA_MASK_DMAC(channel), DMA_INDEX_CHNL(channel))) {
- printk(KERN_ERR "s6000-pcm: fifo full\n");
- return;
- }
-
- BUG_ON(period_size & 15);
- s6dmac_put_fifo(DMA_MASK_DMAC(channel), DMA_INDEX_CHNL(channel),
- src, dst, period_size);
-
- prtd->period++;
- if (unlikely(prtd->period >= runtime->periods))
- prtd->period = 0;
-}
-
-static irqreturn_t s6000_pcm_irq(int irq, void *data)
-{
- struct snd_pcm *pcm = data;
- struct snd_soc_pcm_runtime *runtime = pcm->private_data;
- struct s6000_runtime_data *prtd;
- unsigned int has_xrun;
- int i, ret = IRQ_NONE;
-
- for (i = 0; i < 2; ++i) {
- struct snd_pcm_substream *substream = pcm->streams[i].substream;
- struct s6000_pcm_dma_params *params =
- snd_soc_dai_get_dma_data(runtime->cpu_dai, substream);
- u32 channel;
- unsigned int pending;
-
- if (substream == SNDRV_PCM_STREAM_PLAYBACK)
- channel = params->dma_out;
- else
- channel = params->dma_in;
-
- has_xrun = params->check_xrun(runtime->cpu_dai);
-
- if (!channel)
- continue;
-
- if (unlikely(has_xrun & (1 << i)) &&
- substream->runtime &&
- snd_pcm_running(substream)) {
- dev_dbg(pcm->dev, "xrun\n");
- snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
- ret = IRQ_HANDLED;
- }
-
- pending = s6dmac_int_sources(DMA_MASK_DMAC(channel),
- DMA_INDEX_CHNL(channel));
-
- if (pending & 1) {
- ret = IRQ_HANDLED;
- if (likely(substream->runtime &&
- snd_pcm_running(substream))) {
- snd_pcm_period_elapsed(substream);
- dev_dbg(pcm->dev, "period elapsed %x %x\n",
- s6dmac_cur_src(DMA_MASK_DMAC(channel),
- DMA_INDEX_CHNL(channel)),
- s6dmac_cur_dst(DMA_MASK_DMAC(channel),
- DMA_INDEX_CHNL(channel)));
- prtd = substream->runtime->private_data;
- spin_lock(&prtd->lock);
- s6000_pcm_enqueue_dma(substream);
- spin_unlock(&prtd->lock);
- }
- }
-
- if (unlikely(pending & ~7)) {
- if (pending & (1 << 3))
- printk(KERN_WARNING
- "s6000-pcm: DMA %x Underflow\n",
- channel);
- if (pending & (1 << 4))
- printk(KERN_WARNING
- "s6000-pcm: DMA %x Overflow\n",
- channel);
- if (pending & 0x1e0)
- printk(KERN_WARNING
- "s6000-pcm: DMA %x Master Error "
- "(mask %x)\n",
- channel, pending >> 5);
-
- }
- }
-
- return ret;
-}
-
-static int s6000_pcm_start(struct snd_pcm_substream *substream)
-{
- struct s6000_runtime_data *prtd = substream->runtime->private_data;
- struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par;
- unsigned long flags;
- int srcinc;
- u32 dma;
-
- par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
-
- spin_lock_irqsave(&prtd->lock, flags);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- srcinc = 1;
- dma = par->dma_out;
- } else {
- srcinc = 0;
- dma = par->dma_in;
- }
- s6dmac_enable_chan(DMA_MASK_DMAC(dma), DMA_INDEX_CHNL(dma),
- 1 /* priority 1 (0 is max) */,
- 0 /* peripheral requests w/o xfer length mode */,
- srcinc /* source address increment */,
- srcinc^1 /* destination address increment */,
- 0 /* chunksize 0 (skip impossible on this dma) */,
- 0 /* source skip after chunk (impossible) */,
- 0 /* destination skip after chunk (impossible) */,
- 4 /* 16 byte burst size */,
- -1 /* don't conserve bandwidth */,
- 0 /* low watermark irq descriptor threshold */,
- 0 /* disable hardware timestamps */,
- 1 /* enable channel */);
-
- s6000_pcm_enqueue_dma(substream);
- s6000_pcm_enqueue_dma(substream);
-
- spin_unlock_irqrestore(&prtd->lock, flags);
-
- return 0;
-}
-
-static int s6000_pcm_stop(struct snd_pcm_substream *substream)
-{
- struct s6000_runtime_data *prtd = substream->runtime->private_data;
- struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par;
- unsigned long flags;
- u32 channel;
-
- par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- channel = par->dma_out;
- else
- channel = par->dma_in;
-
- s6dmac_set_terminal_count(DMA_MASK_DMAC(channel),
- DMA_INDEX_CHNL(channel), 0);
-
- spin_lock_irqsave(&prtd->lock, flags);
-
- s6dmac_disable_chan(DMA_MASK_DMAC(channel), DMA_INDEX_CHNL(channel));
-
- spin_unlock_irqrestore(&prtd->lock, flags);
-
- return 0;
-}
-
-static int s6000_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par;
- int ret;
-
- par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
-
- ret = par->trigger(substream, cmd, 0);
- if (ret < 0)
- return ret;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- ret = s6000_pcm_start(substream);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- ret = s6000_pcm_stop(substream);
- break;
- default:
- ret = -EINVAL;
- }
- if (ret < 0)
- return ret;
-
- return par->trigger(substream, cmd, 1);
-}
-
-static int s6000_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct s6000_runtime_data *prtd = substream->runtime->private_data;
-
- prtd->period = 0;
-
- return 0;
-}
-
-static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct s6000_runtime_data *prtd = runtime->private_data;
- unsigned long flags;
- unsigned int offset;
- dma_addr_t count;
-
- par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
-
- spin_lock_irqsave(&prtd->lock, flags);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- count = s6dmac_cur_src(DMA_MASK_DMAC(par->dma_out),
- DMA_INDEX_CHNL(par->dma_out));
- else
- count = s6dmac_cur_dst(DMA_MASK_DMAC(par->dma_in),
- DMA_INDEX_CHNL(par->dma_in));
-
- count -= runtime->dma_addr;
-
- spin_unlock_irqrestore(&prtd->lock, flags);
-
- offset = bytes_to_frames(runtime, count);
- if (unlikely(offset >= runtime->buffer_size))
- offset = 0;
-
- return offset;
-}
-
-static int s6000_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct s6000_runtime_data *prtd;
- int ret;
-
- par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
- snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware);
-
- ret = snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 16);
- if (ret < 0)
- return ret;
- ret = snd_pcm_hw_constraint_step(runtime, 0,
- SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 16);
- if (ret < 0)
- return ret;
- ret = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (ret < 0)
- return ret;
-
- if (par->same_rate) {
- int rate;
- spin_lock(&par->lock); /* needed? */
- rate = par->rate;
- spin_unlock(&par->lock);
- if (rate != -1) {
- ret = snd_pcm_hw_constraint_minmax(runtime,
- SNDRV_PCM_HW_PARAM_RATE,
- rate, rate);
- if (ret < 0)
- return ret;
- }
- }
-
- prtd = kzalloc(sizeof(struct s6000_runtime_data), GFP_KERNEL);
- if (prtd == NULL)
- return -ENOMEM;
-
- spin_lock_init(&prtd->lock);
-
- runtime->private_data = prtd;
-
- return 0;
-}
-
-static int s6000_pcm_close(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct s6000_runtime_data *prtd = runtime->private_data;
-
- kfree(prtd);
-
- return 0;
-}
-
-static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par;
- int ret;
- ret = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- if (ret < 0) {
- printk(KERN_WARNING "s6000-pcm: allocation of memory failed\n");
- return ret;
- }
-
- par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
-
- if (par->same_rate) {
- spin_lock(&par->lock);
- if (par->rate == -1 ||
- !(par->in_use & ~(1 << substream->stream))) {
- par->rate = params_rate(hw_params);
- par->in_use |= 1 << substream->stream;
- } else if (params_rate(hw_params) != par->rate) {
- snd_pcm_lib_free_pages(substream);
- par->in_use &= ~(1 << substream->stream);
- ret = -EBUSY;
- }
- spin_unlock(&par->lock);
- }
- return ret;
-}
-
-static int s6000_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par =
- snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
-
- spin_lock(&par->lock);
- par->in_use &= ~(1 << substream->stream);
- if (!par->in_use)
- par->rate = -1;
- spin_unlock(&par->lock);
-
- return snd_pcm_lib_free_pages(substream);
-}
-
-static struct snd_pcm_ops s6000_pcm_ops = {
- .open = s6000_pcm_open,
- .close = s6000_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = s6000_pcm_hw_params,
- .hw_free = s6000_pcm_hw_free,
- .trigger = s6000_pcm_trigger,
- .prepare = s6000_pcm_prepare,
- .pointer = s6000_pcm_pointer,
-};
-
-static void s6000_pcm_free(struct snd_pcm *pcm)
-{
- struct snd_soc_pcm_runtime *runtime = pcm->private_data;
- struct s6000_pcm_dma_params *params =
- snd_soc_dai_get_dma_data(runtime->cpu_dai,
- pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream);
-
- free_irq(params->irq, pcm);
- snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static u64 s6000_pcm_dmamask = DMA_BIT_MASK(32);
-
-static int s6000_pcm_new(struct snd_soc_pcm_runtime *runtime)
-{
- struct snd_card *card = runtime->card->snd_card;
- struct snd_pcm *pcm = runtime->pcm;
- struct s6000_pcm_dma_params *params;
- int res;
-
- params = snd_soc_dai_get_dma_data(runtime->cpu_dai,
- pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream);
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &s6000_pcm_dmamask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- if (params->dma_in) {
- s6dmac_disable_chan(DMA_MASK_DMAC(params->dma_in),
- DMA_INDEX_CHNL(params->dma_in));
- s6dmac_int_sources(DMA_MASK_DMAC(params->dma_in),
- DMA_INDEX_CHNL(params->dma_in));
- }
-
- if (params->dma_out) {
- s6dmac_disable_chan(DMA_MASK_DMAC(params->dma_out),
- DMA_INDEX_CHNL(params->dma_out));
- s6dmac_int_sources(DMA_MASK_DMAC(params->dma_out),
- DMA_INDEX_CHNL(params->dma_out));
- }
-
- res = request_irq(params->irq, s6000_pcm_irq, IRQF_SHARED,
- "s6000-audio", pcm);
- if (res) {
- printk(KERN_ERR "s6000-pcm couldn't get IRQ\n");
- return res;
- }
-
- res = snd_pcm_lib_preallocate_pages_for_all(pcm,
- SNDRV_DMA_TYPE_DEV,
- card->dev,
- S6_PCM_PREALLOCATE_SIZE,
- S6_PCM_PREALLOCATE_MAX);
- if (res)
- printk(KERN_WARNING "s6000-pcm: preallocation failed\n");
-
- spin_lock_init(&params->lock);
- params->in_use = 0;
- params->rate = -1;
- return 0;
-}
-
-static struct snd_soc_platform_driver s6000_soc_platform = {
- .ops = &s6000_pcm_ops,
- .pcm_new = s6000_pcm_new,
- .pcm_free = s6000_pcm_free,
-};
-
-static int __devinit s6000_soc_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_platform(&pdev->dev, &s6000_soc_platform);
-}
-
-static int __devexit s6000_soc_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver s6000_pcm_driver = {
- .driver = {
- .name = "s6000-pcm-audio",
- .owner = THIS_MODULE,
- },
-
- .probe = s6000_soc_platform_probe,
- .remove = __devexit_p(s6000_soc_platform_remove),
-};
-
-module_platform_driver(s6000_pcm_driver);
-
-MODULE_AUTHOR("Daniel Gloeckner");
-MODULE_DESCRIPTION("Stretch s6000 family PCM DMA module");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/s6000/s6000-pcm.h b/ANDROID_3.4.5/sound/soc/s6000/s6000-pcm.h
deleted file mode 100644
index 09d9b883..00000000
--- a/ANDROID_3.4.5/sound/soc/s6000/s6000-pcm.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * ALSA PCM interface for the Stretch s6000 family
- *
- * Author: Daniel Gloeckner, <dg@emlix.com>
- * Copyright: (C) 2009 emlix GmbH <info@emlix.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _S6000_PCM_H
-#define _S6000_PCM_H
-
-struct snd_soc_dai;
-struct snd_pcm_substream;
-
-struct s6000_pcm_dma_params {
- unsigned int (*check_xrun)(struct snd_soc_dai *cpu_dai);
- int (*trigger)(struct snd_pcm_substream *substream, int cmd, int after);
- dma_addr_t sif_in;
- dma_addr_t sif_out;
- u32 dma_in;
- u32 dma_out;
- int irq;
- int same_rate;
-
- spinlock_t lock;
- int in_use;
- int rate;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/s6000/s6105-ipcam.c b/ANDROID_3.4.5/sound/soc/s6000/s6105-ipcam.c
deleted file mode 100644
index 58cfb1eb..00000000
--- a/ANDROID_3.4.5/sound/soc/s6000/s6105-ipcam.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * ASoC driver for Stretch s6105 IP camera platform
- *
- * Author: Daniel Gloeckner, <dg@emlix.com>
- * Copyright: (C) 2009 emlix GmbH <info@emlix.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <variant/dmac.h>
-
-#include "s6000-pcm.h"
-#include "s6000-i2s.h"
-
-#define S6105_CAM_CODEC_CLOCK 12288000
-
-static int s6105_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
-
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- /* set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBM_CFM |
- SND_SOC_DAIFMT_NB_NF);
- if (ret < 0)
- return ret;
-
- /* set the codec system clock */
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, S6105_CAM_CODEC_CLOCK,
- SND_SOC_CLOCK_OUT);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops s6105_ops = {
- .hw_params = s6105_hw_params,
-};
-
-/* s6105 machine dapm widgets */
-static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
- SND_SOC_DAPM_LINE("Audio Out Differential", NULL),
- SND_SOC_DAPM_LINE("Audio Out Stereo", NULL),
- SND_SOC_DAPM_LINE("Audio In", NULL),
-};
-
-/* s6105 machine audio_mapnections to the codec pins */
-static const struct snd_soc_dapm_route audio_map[] = {
- /* Audio Out connected to HPLOUT, HPLCOM, HPROUT */
- {"Audio Out Differential", NULL, "HPLOUT"},
- {"Audio Out Differential", NULL, "HPLCOM"},
- {"Audio Out Stereo", NULL, "HPLOUT"},
- {"Audio Out Stereo", NULL, "HPROUT"},
-
- /* Audio In connected to LINE1L, LINE1R */
- {"LINE1L", NULL, "Audio In"},
- {"LINE1R", NULL, "Audio In"},
-};
-
-static int output_type_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item) {
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name, "HPLOUT/HPROUT");
- } else {
- strcpy(uinfo->value.enumerated.name, "HPLOUT/HPLCOM");
- }
- return 0;
-}
-
-static int output_type_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.enumerated.item[0] = kcontrol->private_value;
- return 0;
-}
-
-static int output_type_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = kcontrol->private_data;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- unsigned int val = (ucontrol->value.enumerated.item[0] != 0);
- char *differential = "Audio Out Differential";
- char *stereo = "Audio Out Stereo";
-
- if (kcontrol->private_value == val)
- return 0;
- kcontrol->private_value = val;
- snd_soc_dapm_disable_pin(dapm, val ? differential : stereo);
- snd_soc_dapm_sync(dapm);
- snd_soc_dapm_enable_pin(dapm, val ? stereo : differential);
- snd_soc_dapm_sync(dapm);
-
- return 1;
-}
-
-static const struct snd_kcontrol_new audio_out_mux = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Output Mux",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = output_type_info,
- .get = output_type_get,
- .put = output_type_put,
- .private_value = 1 /* default to stereo */
-};
-
-/* Logic for a aic3x as connected on the s6105 ip camera ref design */
-static int s6105_aic3x_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- /* Add s6105 specific widgets */
- snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
- ARRAY_SIZE(aic3x_dapm_widgets));
-
- /* Set up s6105 specific audio path audio_map */
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
- /* not present */
- snd_soc_dapm_nc_pin(dapm, "MONO_LOUT");
- snd_soc_dapm_nc_pin(dapm, "LINE2L");
- snd_soc_dapm_nc_pin(dapm, "LINE2R");
-
- /* not connected */
- snd_soc_dapm_nc_pin(dapm, "MIC3L"); /* LINE2L on this chip */
- snd_soc_dapm_nc_pin(dapm, "MIC3R"); /* LINE2R on this chip */
- snd_soc_dapm_nc_pin(dapm, "LLOUT");
- snd_soc_dapm_nc_pin(dapm, "RLOUT");
- snd_soc_dapm_nc_pin(dapm, "HPRCOM");
-
- /* always connected */
- snd_soc_dapm_enable_pin(dapm, "Audio In");
-
- /* must correspond to audio_out_mux.private_value initializer */
- snd_soc_dapm_disable_pin(dapm, "Audio Out Differential");
- snd_soc_dapm_sync(dapm);
- snd_soc_dapm_enable_pin(dapm, "Audio Out Stereo");
-
- snd_soc_dapm_sync(dapm);
-
- snd_ctl_add(codec->card->snd_card, snd_ctl_new1(&audio_out_mux, codec));
-
- return 0;
-}
-
-/* s6105 digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link s6105_dai = {
- .name = "TLV320AIC31",
- .stream_name = "AIC31",
- .cpu_dai_name = "s6000-i2s",
- .codec_dai_name = "tlv320aic3x-hifi",
- .platform_name = "s6000-pcm-audio",
- .codec_name = "tlv320aic3x-codec.0-001a",
- .init = s6105_aic3x_init,
- .ops = &s6105_ops,
-};
-
-/* s6105 audio machine driver */
-static struct snd_soc_card snd_soc_card_s6105 = {
- .name = "Stretch IP Camera",
- .owner = THIS_MODULE,
- .dai_link = &s6105_dai,
- .num_links = 1,
-};
-
-static struct s6000_snd_platform_data __initdata s6105_snd_data = {
- .wide = 0,
- .channel_in = 0,
- .channel_out = 1,
- .lines_in = 1,
- .lines_out = 1,
- .same_rate = 1,
-};
-
-static struct platform_device *s6105_snd_device;
-
-/* temporary i2c device creation until this can be moved into the machine
- * support file.
-*/
-static struct i2c_board_info i2c_device[] = {
- { I2C_BOARD_INFO("tlv320aic33", 0x18), }
-};
-
-static int __init s6105_init(void)
-{
- int ret;
-
- i2c_register_board_info(0, i2c_device, ARRAY_SIZE(i2c_device));
-
- s6105_snd_device = platform_device_alloc("soc-audio", -1);
- if (!s6105_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(s6105_snd_device, &snd_soc_card_s6105);
- platform_device_add_data(s6105_snd_device, &s6105_snd_data,
- sizeof(s6105_snd_data));
-
- ret = platform_device_add(s6105_snd_device);
- if (ret)
- platform_device_put(s6105_snd_device);
-
- return ret;
-}
-
-static void __exit s6105_exit(void)
-{
- platform_device_unregister(s6105_snd_device);
-}
-
-module_init(s6105_init);
-module_exit(s6105_exit);
-
-MODULE_AUTHOR("Daniel Gloeckner");
-MODULE_DESCRIPTION("Stretch s6105 IP camera ASoC driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/Kconfig b/ANDROID_3.4.5/sound/soc/samsung/Kconfig
deleted file mode 100644
index fe3995ce..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/Kconfig
+++ /dev/null
@@ -1,214 +0,0 @@
-config SND_SOC_SAMSUNG
- tristate "ASoC support for Samsung"
- depends on ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 || ARCH_EXYNOS4
- select S3C64XX_DMA if ARCH_S3C64XX
- select S3C2410_DMA if ARCH_S3C24XX
- help
- Say Y or M if you want to add support for codecs attached to
- the Samsung SoCs' Audio interfaces. You will also need to
- select the audio interfaces to support below.
-
-config SND_S3C24XX_I2S
- tristate
- select S3C2410_DMA
-
-config SND_S3C_I2SV2_SOC
- tristate
-
-config SND_S3C2412_SOC_I2S
- tristate
- select SND_S3C_I2SV2_SOC
- select S3C2410_DMA
-
-config SND_SAMSUNG_PCM
- tristate
-
-config SND_SAMSUNG_AC97
- tristate
- select SND_SOC_AC97_BUS
-
-config SND_SAMSUNG_SPDIF
- tristate
- select SND_SOC_SPDIF
-
-config SND_SAMSUNG_I2S
- tristate
-
-config SND_SOC_SAMSUNG_NEO1973_WM8753
- tristate "Audio support for Openmoko Neo1973 Smartphones (GTA01/GTA02)"
- depends on SND_SOC_SAMSUNG && (MACH_NEO1973_GTA01 || MACH_NEO1973_GTA02)
- select SND_S3C24XX_I2S
- select SND_SOC_WM8753
- select SND_SOC_LM4857 if MACH_NEO1973_GTA01
- select SND_SOC_DFBMCS320
- help
- Say Y here to enable audio support for the Openmoko Neo1973
- Smartphones.
-
-config SND_SOC_SAMSUNG_JIVE_WM8750
- tristate "SoC I2S Audio support for Jive"
- depends on SND_SOC_SAMSUNG && MACH_JIVE
- select SND_SOC_WM8750
- select SND_S3C2412_SOC_I2S
- help
- Sat Y if you want to add support for SoC audio on the Jive.
-
-config SND_SOC_SAMSUNG_SMDK_WM8580
- tristate "SoC I2S Audio support for WM8580 on SMDK"
- depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDK6440 || MACH_SMDK6450 || MACH_SMDKV210 || MACH_SMDKC110)
- select SND_SOC_WM8580
- select SND_SAMSUNG_I2S
- help
- Say Y if you want to add support for SoC audio on the SMDKs.
-
-config SND_SOC_SAMSUNG_SMDK_WM8994
- tristate "SoC I2S Audio support for WM8994 on SMDK"
- depends on SND_SOC_SAMSUNG && (MACH_SMDKV310 || MACH_SMDKC210 || MACH_SMDK4212)
- depends on I2C=y && GENERIC_HARDIRQS
- select MFD_WM8994
- select SND_SOC_WM8994
- select SND_SAMSUNG_I2S
- help
- Say Y if you want to add support for SoC audio on the SMDKs.
-
-config SND_SOC_SAMSUNG_SMDK2443_WM9710
- tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
- depends on SND_SOC_SAMSUNG && MACH_SMDK2443
- select S3C2410_DMA
- select AC97_BUS
- select SND_SOC_AC97_CODEC
- select SND_SAMSUNG_AC97
- help
- Say Y if you want to add support for SoC audio on smdk2443
- with the WM9710.
-
-config SND_SOC_SAMSUNG_LN2440SBC_ALC650
- tristate "SoC AC97 Audio support for LN2440SBC - ALC650"
- depends on SND_SOC_SAMSUNG && ARCH_S3C24XX
- select S3C2410_DMA
- select AC97_BUS
- select SND_SOC_AC97_CODEC
- select SND_SAMSUNG_AC97
- help
- Say Y if you want to add support for SoC audio on ln2440sbc
- with the ALC650.
-
-config SND_SOC_SAMSUNG_S3C24XX_UDA134X
- tristate "SoC I2S Audio support UDA134X wired to a S3C24XX"
- depends on SND_SOC_SAMSUNG && ARCH_S3C24XX
- select SND_S3C24XX_I2S
- select SND_SOC_L3
- select SND_SOC_UDA134X
-
-config SND_SOC_SAMSUNG_SIMTEC
- tristate
- help
- Internal node for common S3C24XX/Simtec suppor
-
-config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23
- tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards"
- depends on SND_SOC_SAMSUNG && ARCH_S3C24XX
- select SND_S3C24XX_I2S
- select SND_SOC_TLV320AIC23
- select SND_SOC_SAMSUNG_SIMTEC
-
-config SND_SOC_SAMSUNG_SIMTEC_HERMES
- tristate "SoC I2S Audio support for Simtec Hermes board"
- depends on SND_SOC_SAMSUNG && ARCH_S3C24XX
- select SND_S3C24XX_I2S
- select SND_SOC_TLV320AIC3X
- select SND_SOC_SAMSUNG_SIMTEC
-
-config SND_SOC_SAMSUNG_H1940_UDA1380
- tristate "Audio support for the HP iPAQ H1940"
- depends on SND_SOC_SAMSUNG && ARCH_H1940
- select SND_S3C24XX_I2S
- select SND_SOC_UDA1380
- help
- This driver provides audio support for HP iPAQ h1940 PDA.
-
-config SND_SOC_SAMSUNG_RX1950_UDA1380
- tristate "Audio support for the HP iPAQ RX1950"
- depends on SND_SOC_SAMSUNG && MACH_RX1950
- select SND_S3C24XX_I2S
- select SND_SOC_UDA1380
- help
- This driver provides audio support for HP iPAQ RX1950 PDA.
-
-config SND_SOC_SAMSUNG_SMDK_WM9713
- tristate "SoC AC97 Audio support for SMDK with WM9713"
- depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110 || MACH_SMDKV310 || MACH_SMDKC210)
- select SND_SOC_WM9713
- select SND_SAMSUNG_AC97
- help
- Sat Y if you want to add support for SoC audio on the SMDK.
-
-config SND_SOC_SMARTQ
- tristate "SoC I2S Audio support for SmartQ board"
- depends on SND_SOC_SAMSUNG && MACH_SMARTQ
- select SND_SAMSUNG_I2S
- select SND_SOC_WM8750
-
-config SND_SOC_GONI_AQUILA_WM8994
- tristate "SoC I2S Audio support for AQUILA/GONI - WM8994"
- depends on SND_SOC_SAMSUNG && (MACH_GONI || MACH_AQUILA)
- depends on I2C=y && GENERIC_HARDIRQS
- select SND_SAMSUNG_I2S
- select MFD_WM8994
- select SND_SOC_WM8994
- help
- Say Y if you want to add support for SoC audio on goni or aquila
- with the WM8994.
-
-config SND_SOC_SAMSUNG_SMDK_SPDIF
- tristate "SoC S/PDIF Audio support for SMDK"
- depends on SND_SOC_SAMSUNG && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210 || MACH_SMDKV310 || MACH_SMDK4212)
- select SND_SAMSUNG_SPDIF
- help
- Say Y if you want to add support for SoC S/PDIF audio on the SMDK.
-
-config SND_SOC_SMDK_WM8580_PCM
- tristate "SoC PCM Audio support for WM8580 on SMDK"
- depends on SND_SOC_SAMSUNG && (MACH_SMDK6450 || MACH_SMDKV210 || MACH_SMDKC110)
- select SND_SOC_WM8580
- select SND_SAMSUNG_PCM
- help
- Say Y if you want to add support for SoC audio on the SMDK.
-
-config SND_SOC_SMDK_WM8994_PCM
- tristate "SoC PCM Audio support for WM8994 on SMDK"
- depends on SND_SOC_SAMSUNG && (MACH_SMDKC210 || MACH_SMDKV310 || MACH_SMDK4212)
- depends on I2C=y && GENERIC_HARDIRQS
- select MFD_WM8994
- select SND_SOC_WM8994
- select SND_SAMSUNG_PCM
- help
- Say Y if you want to add support for SoC audio on the SMDK
-
-config SND_SOC_SPEYSIDE
- tristate "Audio support for Wolfson Speyside"
- depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
- select SND_SAMSUNG_I2S
- select SND_SOC_WM8996
- select SND_SOC_WM9081
- select SND_SOC_WM1250_EV1
-
-config SND_SOC_TOBERMORY
- tristate "Audio support for Wolfson Tobermory"
- depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
- select SND_SAMSUNG_I2S
- select SND_SOC_WM8962
-
-config SND_SOC_LOWLAND
- tristate "Audio support for Wolfson Lowland"
- depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
- select SND_SAMSUNG_I2S
- select SND_SOC_WM5100
- select SND_SOC_WM9081
-
-config SND_SOC_LITTLEMILL
- tristate "Audio support for Wolfson Littlemill"
- depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
- select SND_SAMSUNG_I2S
- select MFD_WM8994
- select SND_SOC_WM8994
diff --git a/ANDROID_3.4.5/sound/soc/samsung/Makefile b/ANDROID_3.4.5/sound/soc/samsung/Makefile
deleted file mode 100644
index 9d03beb4..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/Makefile
+++ /dev/null
@@ -1,67 +0,0 @@
-# S3c24XX Platform Support
-snd-soc-s3c24xx-objs := dma.o
-snd-soc-idma-objs := idma.o
-snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
-snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o
-snd-soc-ac97-objs := ac97.o
-snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o
-snd-soc-samsung-spdif-objs := spdif.o
-snd-soc-pcm-objs := pcm.o
-snd-soc-i2s-objs := i2s.o
-
-obj-$(CONFIG_SND_SOC_SAMSUNG) += snd-soc-s3c24xx.o
-obj-$(CONFIG_SND_S3C24XX_I2S) += snd-soc-s3c24xx-i2s.o
-obj-$(CONFIG_SND_SAMSUNG_AC97) += snd-soc-ac97.o
-obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
-obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o
-obj-$(CONFIG_SND_SAMSUNG_SPDIF) += snd-soc-samsung-spdif.o
-obj-$(CONFIG_SND_SAMSUNG_PCM) += snd-soc-pcm.o
-obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-i2s.o
-obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-idma.o
-
-# S3C24XX Machine Support
-snd-soc-jive-wm8750-objs := jive_wm8750.o
-snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
-snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
-snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
-snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
-snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o
-snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o
-snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o
-snd-soc-h1940-uda1380-objs := h1940_uda1380.o
-snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o
-snd-soc-smdk-wm8580-objs := smdk_wm8580.o
-snd-soc-smdk-wm8994-objs := smdk_wm8994.o
-snd-soc-smdk-wm9713-objs := smdk_wm9713.o
-snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o
-snd-soc-goni-wm8994-objs := goni_wm8994.o
-snd-soc-smdk-spdif-objs := smdk_spdif.o
-snd-soc-smdk-wm8580pcm-objs := smdk_wm8580pcm.o
-snd-soc-smdk-wm8994pcm-objs := smdk_wm8994pcm.o
-snd-soc-speyside-objs := speyside.o
-snd-soc-tobermory-objs := tobermory.o
-snd-soc-lowland-objs := lowland.o
-snd-soc-littlemill-objs := littlemill.o
-
-obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o
-obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
-obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
-obj-$(CONFIG_SND_SOC_SAMSUNG_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o
-obj-$(CONFIG_SND_SOC_SAMSUNG_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
-obj-$(CONFIG_SND_SOC_SAMSUNG_SIMTEC) += snd-soc-s3c24xx-simtec.o
-obj-$(CONFIG_SND_SOC_SAMSUNG_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o
-obj-$(CONFIG_SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o
-obj-$(CONFIG_SND_SOC_SAMSUNG_H1940_UDA1380) += snd-soc-h1940-uda1380.o
-obj-$(CONFIG_SND_SOC_SAMSUNG_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o
-obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM8580) += snd-soc-smdk-wm8580.o
-obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM8994) += snd-soc-smdk-wm8994.o
-obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o
-obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o
-obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o
-obj-$(CONFIG_SND_SOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o
-obj-$(CONFIG_SND_SOC_SMDK_WM8580_PCM) += snd-soc-smdk-wm8580pcm.o
-obj-$(CONFIG_SND_SOC_SMDK_WM8994_PCM) += snd-soc-smdk-wm8994pcm.o
-obj-$(CONFIG_SND_SOC_SPEYSIDE) += snd-soc-speyside.o
-obj-$(CONFIG_SND_SOC_TOBERMORY) += snd-soc-tobermory.o
-obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o
-obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o
diff --git a/ANDROID_3.4.5/sound/soc/samsung/ac97.c b/ANDROID_3.4.5/sound/soc/samsung/ac97.c
deleted file mode 100644
index 3d04c1fa..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/ac97.c
+++ /dev/null
@@ -1,517 +0,0 @@
-/* sound/soc/samsung/ac97.c
- *
- * ALSA SoC Audio Layer - S3C AC97 Controller driver
- * Evolved from s3c2443-ac97.c
- *
- * Copyright (c) 2010 Samsung Electronics Co. Ltd
- * Author: Jaswinder Singh <jassisinghbrar@gmail.com>
- * Credits: Graeme Gregory, Sean Choi
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/module.h>
-
-#include <sound/soc.h>
-
-#include <mach/dma.h>
-#include <plat/regs-ac97.h>
-#include <plat/audio.h>
-
-#include "dma.h"
-
-#define AC_CMD_ADDR(x) (x << 16)
-#define AC_CMD_DATA(x) (x & 0xffff)
-
-#define S3C_AC97_DAI_PCM 0
-#define S3C_AC97_DAI_MIC 1
-
-struct s3c_ac97_info {
- struct clk *ac97_clk;
- void __iomem *regs;
- struct mutex lock;
- struct completion done;
-};
-static struct s3c_ac97_info s3c_ac97;
-
-static struct s3c2410_dma_client s3c_dma_client_out = {
- .name = "AC97 PCMOut"
-};
-
-static struct s3c2410_dma_client s3c_dma_client_in = {
- .name = "AC97 PCMIn"
-};
-
-static struct s3c2410_dma_client s3c_dma_client_micin = {
- .name = "AC97 MicIn"
-};
-
-static struct s3c_dma_params s3c_ac97_pcm_out = {
- .client = &s3c_dma_client_out,
- .dma_size = 4,
-};
-
-static struct s3c_dma_params s3c_ac97_pcm_in = {
- .client = &s3c_dma_client_in,
- .dma_size = 4,
-};
-
-static struct s3c_dma_params s3c_ac97_mic_in = {
- .client = &s3c_dma_client_micin,
- .dma_size = 4,
-};
-
-static void s3c_ac97_activate(struct snd_ac97 *ac97)
-{
- u32 ac_glbctrl, stat;
-
- stat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT) & 0x7;
- if (stat == S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE)
- return; /* Return if already active */
-
- INIT_COMPLETION(s3c_ac97.done);
-
- ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
- ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON;
- writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
- msleep(1);
-
- ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE;
- writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
- msleep(1);
-
- ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
- ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
- writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
-
- if (!wait_for_completion_timeout(&s3c_ac97.done, HZ))
- pr_err("AC97: Unable to activate!");
-}
-
-static unsigned short s3c_ac97_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- u32 ac_glbctrl, ac_codec_cmd;
- u32 stat, addr, data;
-
- mutex_lock(&s3c_ac97.lock);
-
- s3c_ac97_activate(ac97);
-
- INIT_COMPLETION(s3c_ac97.done);
-
- ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD);
- ac_codec_cmd = S3C_AC97_CODEC_CMD_READ | AC_CMD_ADDR(reg);
- writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD);
-
- udelay(50);
-
- ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
- ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
- writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
-
- if (!wait_for_completion_timeout(&s3c_ac97.done, HZ))
- pr_err("AC97: Unable to read!");
-
- stat = readl(s3c_ac97.regs + S3C_AC97_STAT);
- addr = (stat >> 16) & 0x7f;
- data = (stat & 0xffff);
-
- if (addr != reg)
- pr_err("ac97: req addr = %02x, rep addr = %02x\n",
- reg, addr);
-
- mutex_unlock(&s3c_ac97.lock);
-
- return (unsigned short)data;
-}
-
-static void s3c_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short val)
-{
- u32 ac_glbctrl, ac_codec_cmd;
-
- mutex_lock(&s3c_ac97.lock);
-
- s3c_ac97_activate(ac97);
-
- INIT_COMPLETION(s3c_ac97.done);
-
- ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD);
- ac_codec_cmd = AC_CMD_ADDR(reg) | AC_CMD_DATA(val);
- writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD);
-
- udelay(50);
-
- ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
- ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
- writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
-
- if (!wait_for_completion_timeout(&s3c_ac97.done, HZ))
- pr_err("AC97: Unable to write!");
-
- ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD);
- ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ;
- writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD);
-
- mutex_unlock(&s3c_ac97.lock);
-}
-
-static void s3c_ac97_cold_reset(struct snd_ac97 *ac97)
-{
- pr_debug("AC97: Cold reset\n");
- writel(S3C_AC97_GLBCTRL_COLDRESET,
- s3c_ac97.regs + S3C_AC97_GLBCTRL);
- msleep(1);
-
- writel(0, s3c_ac97.regs + S3C_AC97_GLBCTRL);
- msleep(1);
-}
-
-static void s3c_ac97_warm_reset(struct snd_ac97 *ac97)
-{
- u32 stat;
-
- stat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT) & 0x7;
- if (stat == S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE)
- return; /* Return if already active */
-
- pr_debug("AC97: Warm reset\n");
-
- writel(S3C_AC97_GLBCTRL_WARMRESET, s3c_ac97.regs + S3C_AC97_GLBCTRL);
- msleep(1);
-
- writel(0, s3c_ac97.regs + S3C_AC97_GLBCTRL);
- msleep(1);
-
- s3c_ac97_activate(ac97);
-}
-
-static irqreturn_t s3c_ac97_irq(int irq, void *dev_id)
-{
- u32 ac_glbctrl, ac_glbstat;
-
- ac_glbstat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT);
-
- if (ac_glbstat & S3C_AC97_GLBSTAT_CODECREADY) {
-
- ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
- ac_glbctrl &= ~S3C_AC97_GLBCTRL_CODECREADYIE;
- writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
-
- complete(&s3c_ac97.done);
- }
-
- ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
- ac_glbctrl |= (1<<30); /* Clear interrupt */
- writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
-
- return IRQ_HANDLED;
-}
-
-struct snd_ac97_bus_ops soc_ac97_ops = {
- .read = s3c_ac97_read,
- .write = s3c_ac97_write,
- .warm_reset = s3c_ac97_warm_reset,
- .reset = s3c_ac97_cold_reset,
-};
-EXPORT_SYMBOL_GPL(soc_ac97_ops);
-
-static int s3c_ac97_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct s3c_dma_params *dma_data;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dma_data = &s3c_ac97_pcm_out;
- else
- dma_data = &s3c_ac97_pcm_in;
-
- snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
-
- return 0;
-}
-
-static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- u32 ac_glbctrl;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct s3c_dma_params *dma_data =
- snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
- ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK;
- else
- ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA;
- else
- ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA;
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- break;
- }
-
- writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
-
- if (!dma_data->ops)
- dma_data->ops = samsung_dma_get_ops();
-
- dma_data->ops->started(dma_data->channel);
-
- return 0;
-}
-
-static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- return -ENODEV;
- else
- snd_soc_dai_set_dma_data(cpu_dai, substream, &s3c_ac97_mic_in);
-
- return 0;
-}
-
-static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
- int cmd, struct snd_soc_dai *dai)
-{
- u32 ac_glbctrl;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct s3c_dma_params *dma_data =
- snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
- ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
- ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- ac_glbctrl |= S3C_AC97_GLBCTRL_MICINTM_DMA;
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- break;
- }
-
- writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
-
- if (!dma_data->ops)
- dma_data->ops = samsung_dma_get_ops();
-
- dma_data->ops->started(dma_data->channel);
-
- return 0;
-}
-
-static const struct snd_soc_dai_ops s3c_ac97_dai_ops = {
- .hw_params = s3c_ac97_hw_params,
- .trigger = s3c_ac97_trigger,
-};
-
-static const struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = {
- .hw_params = s3c_ac97_hw_mic_params,
- .trigger = s3c_ac97_mic_trigger,
-};
-
-static struct snd_soc_dai_driver s3c_ac97_dai[] = {
- [S3C_AC97_DAI_PCM] = {
- .name = "samsung-ac97",
- .ac97_control = 1,
- .playback = {
- .stream_name = "AC97 Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .capture = {
- .stream_name = "AC97 Capture",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .ops = &s3c_ac97_dai_ops,
- },
- [S3C_AC97_DAI_MIC] = {
- .name = "samsung-ac97-mic",
- .ac97_control = 1,
- .capture = {
- .stream_name = "AC97 Mic Capture",
- .channels_min = 1,
- .channels_max = 1,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .ops = &s3c_ac97_mic_dai_ops,
- },
-};
-
-static __devinit int s3c_ac97_probe(struct platform_device *pdev)
-{
- struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res;
- struct s3c_audio_pdata *ac97_pdata;
- int ret;
-
- ac97_pdata = pdev->dev.platform_data;
- if (!ac97_pdata || !ac97_pdata->cfg_gpio) {
- dev_err(&pdev->dev, "cfg_gpio callback not provided!\n");
- return -EINVAL;
- }
-
- /* Check for availability of necessary resource */
- dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!dmatx_res) {
- dev_err(&pdev->dev, "Unable to get AC97-TX dma resource\n");
- return -ENXIO;
- }
-
- dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (!dmarx_res) {
- dev_err(&pdev->dev, "Unable to get AC97-RX dma resource\n");
- return -ENXIO;
- }
-
- dmamic_res = platform_get_resource(pdev, IORESOURCE_DMA, 2);
- if (!dmamic_res) {
- dev_err(&pdev->dev, "Unable to get AC97-MIC dma resource\n");
- return -ENXIO;
- }
-
- mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem_res) {
- dev_err(&pdev->dev, "Unable to get register resource\n");
- return -ENXIO;
- }
-
- irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!irq_res) {
- dev_err(&pdev->dev, "AC97 IRQ not provided!\n");
- return -ENXIO;
- }
-
- if (!request_mem_region(mem_res->start,
- resource_size(mem_res), "ac97")) {
- dev_err(&pdev->dev, "Unable to request register region\n");
- return -EBUSY;
- }
-
- s3c_ac97_pcm_out.channel = dmatx_res->start;
- s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
- s3c_ac97_pcm_in.channel = dmarx_res->start;
- s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
- s3c_ac97_mic_in.channel = dmamic_res->start;
- s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA;
-
- init_completion(&s3c_ac97.done);
- mutex_init(&s3c_ac97.lock);
-
- s3c_ac97.regs = ioremap(mem_res->start, resource_size(mem_res));
- if (s3c_ac97.regs == NULL) {
- dev_err(&pdev->dev, "Unable to ioremap register region\n");
- ret = -ENXIO;
- goto err1;
- }
-
- s3c_ac97.ac97_clk = clk_get(&pdev->dev, "ac97");
- if (IS_ERR(s3c_ac97.ac97_clk)) {
- dev_err(&pdev->dev, "ac97 failed to get ac97_clock\n");
- ret = -ENODEV;
- goto err2;
- }
- clk_enable(s3c_ac97.ac97_clk);
-
- if (ac97_pdata->cfg_gpio(pdev)) {
- dev_err(&pdev->dev, "Unable to configure gpio\n");
- ret = -EINVAL;
- goto err3;
- }
-
- ret = request_irq(irq_res->start, s3c_ac97_irq,
- 0, "AC97", NULL);
- if (ret < 0) {
- dev_err(&pdev->dev, "ac97: interrupt request failed.\n");
- goto err4;
- }
-
- ret = snd_soc_register_dais(&pdev->dev, s3c_ac97_dai,
- ARRAY_SIZE(s3c_ac97_dai));
- if (ret)
- goto err5;
-
- return 0;
-
-err5:
- free_irq(irq_res->start, NULL);
-err4:
-err3:
- clk_disable(s3c_ac97.ac97_clk);
- clk_put(s3c_ac97.ac97_clk);
-err2:
- iounmap(s3c_ac97.regs);
-err1:
- release_mem_region(mem_res->start, resource_size(mem_res));
-
- return ret;
-}
-
-static __devexit int s3c_ac97_remove(struct platform_device *pdev)
-{
- struct resource *mem_res, *irq_res;
-
- snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai));
-
- irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (irq_res)
- free_irq(irq_res->start, NULL);
-
- clk_disable(s3c_ac97.ac97_clk);
- clk_put(s3c_ac97.ac97_clk);
-
- iounmap(s3c_ac97.regs);
-
- mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (mem_res)
- release_mem_region(mem_res->start, resource_size(mem_res));
-
- return 0;
-}
-
-static struct platform_driver s3c_ac97_driver = {
- .probe = s3c_ac97_probe,
- .remove = __devexit_p(s3c_ac97_remove),
- .driver = {
- .name = "samsung-ac97",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(s3c_ac97_driver);
-
-MODULE_AUTHOR("Jaswinder Singh, <jassisinghbrar@gmail.com>");
-MODULE_DESCRIPTION("AC97 driver for the Samsung SoC");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:samsung-ac97");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/dma.c b/ANDROID_3.4.5/sound/soc/samsung/dma.c
deleted file mode 100644
index ddc6cde1..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/dma.c
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * dma.c -- ALSA Soc Audio Layer
- *
- * (c) 2006 Wolfson Microelectronics PLC.
- * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
- *
- * Copyright 2004-2005 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/slab.h>
-#include <linux/dma-mapping.h>
-#include <linux/module.h>
-
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <asm/dma.h>
-#include <mach/hardware.h>
-#include <mach/dma.h>
-
-#include "dma.h"
-
-#define ST_RUNNING (1<<0)
-#define ST_OPENED (1<<1)
-
-static const struct snd_pcm_hardware dma_hardware = {
- .info = SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME,
- .formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_U16_LE |
- SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S8,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 128*1024,
- .period_bytes_min = PAGE_SIZE,
- .period_bytes_max = PAGE_SIZE*2,
- .periods_min = 2,
- .periods_max = 128,
- .fifo_size = 32,
-};
-
-struct runtime_data {
- spinlock_t lock;
- int state;
- unsigned int dma_loaded;
- unsigned int dma_period;
- dma_addr_t dma_start;
- dma_addr_t dma_pos;
- dma_addr_t dma_end;
- struct s3c_dma_params *params;
-};
-
-static void audio_buffdone(void *data);
-
-/* dma_enqueue
- *
- * place a dma buffer onto the queue for the dma system
- * to handle.
- */
-static void dma_enqueue(struct snd_pcm_substream *substream)
-{
- struct runtime_data *prtd = substream->runtime->private_data;
- dma_addr_t pos = prtd->dma_pos;
- unsigned int limit;
- struct samsung_dma_prep_info dma_info;
-
- pr_debug("Entered %s\n", __func__);
-
- limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period;
-
- pr_debug("%s: loaded %d, limit %d\n",
- __func__, prtd->dma_loaded, limit);
-
- dma_info.cap = (samsung_dma_has_circular() ? DMA_CYCLIC : DMA_SLAVE);
- dma_info.direction =
- (substream->stream == SNDRV_PCM_STREAM_PLAYBACK
- ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM);
- dma_info.fp = audio_buffdone;
- dma_info.fp_param = substream;
- dma_info.period = prtd->dma_period;
- dma_info.len = prtd->dma_period*limit;
-
- while (prtd->dma_loaded < limit) {
- pr_debug("dma_loaded: %d\n", prtd->dma_loaded);
-
- if ((pos + dma_info.period) > prtd->dma_end) {
- dma_info.period = prtd->dma_end - pos;
- pr_debug("%s: corrected dma len %ld\n",
- __func__, dma_info.period);
- }
-
- dma_info.buf = pos;
- prtd->params->ops->prepare(prtd->params->ch, &dma_info);
-
- prtd->dma_loaded++;
- pos += prtd->dma_period;
- if (pos >= prtd->dma_end)
- pos = prtd->dma_start;
- }
-
- prtd->dma_pos = pos;
-}
-
-static void audio_buffdone(void *data)
-{
- struct snd_pcm_substream *substream = data;
- struct runtime_data *prtd = substream->runtime->private_data;
-
- pr_debug("Entered %s\n", __func__);
-
- if (prtd->state & ST_RUNNING) {
- prtd->dma_pos += prtd->dma_period;
- if (prtd->dma_pos >= prtd->dma_end)
- prtd->dma_pos = prtd->dma_start;
-
- if (substream)
- snd_pcm_period_elapsed(substream);
-
- spin_lock(&prtd->lock);
- if (!samsung_dma_has_circular()) {
- prtd->dma_loaded--;
- dma_enqueue(substream);
- }
- spin_unlock(&prtd->lock);
- }
-}
-
-static int dma_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct runtime_data *prtd = runtime->private_data;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- unsigned long totbytes = params_buffer_bytes(params);
- struct s3c_dma_params *dma =
- snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
- struct samsung_dma_info dma_info;
-
- pr_debug("Entered %s\n", __func__);
-
- /* return if this is a bufferless transfer e.g.
- * codec <--> BT codec or GSM modem -- lg FIXME */
- if (!dma)
- return 0;
-
- /* this may get called several times by oss emulation
- * with different params -HW */
- if (prtd->params == NULL) {
- /* prepare DMA */
- prtd->params = dma;
-
- pr_debug("params %p, client %p, channel %d\n", prtd->params,
- prtd->params->client, prtd->params->channel);
-
- prtd->params->ops = samsung_dma_get_ops();
-
- dma_info.cap = (samsung_dma_has_circular() ?
- DMA_CYCLIC : DMA_SLAVE);
- dma_info.client = prtd->params->client;
- dma_info.direction =
- (substream->stream == SNDRV_PCM_STREAM_PLAYBACK
- ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM);
- dma_info.width = prtd->params->dma_size;
- dma_info.fifo = prtd->params->dma_addr;
- prtd->params->ch = prtd->params->ops->request(
- prtd->params->channel, &dma_info);
- }
-
- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
-
- runtime->dma_bytes = totbytes;
-
- spin_lock_irq(&prtd->lock);
- prtd->dma_loaded = 0;
- prtd->dma_period = params_period_bytes(params);
- prtd->dma_start = runtime->dma_addr;
- prtd->dma_pos = prtd->dma_start;
- prtd->dma_end = prtd->dma_start + totbytes;
- spin_unlock_irq(&prtd->lock);
-
- return 0;
-}
-
-static int dma_hw_free(struct snd_pcm_substream *substream)
-{
- struct runtime_data *prtd = substream->runtime->private_data;
-
- pr_debug("Entered %s\n", __func__);
-
- snd_pcm_set_runtime_buffer(substream, NULL);
-
- if (prtd->params) {
- prtd->params->ops->flush(prtd->params->ch);
- prtd->params->ops->release(prtd->params->ch,
- prtd->params->client);
- prtd->params = NULL;
- }
-
- return 0;
-}
-
-static int dma_prepare(struct snd_pcm_substream *substream)
-{
- struct runtime_data *prtd = substream->runtime->private_data;
- int ret = 0;
-
- pr_debug("Entered %s\n", __func__);
-
- /* return if this is a bufferless transfer e.g.
- * codec <--> BT codec or GSM modem -- lg FIXME */
- if (!prtd->params)
- return 0;
-
- /* flush the DMA channel */
- prtd->params->ops->flush(prtd->params->ch);
-
- prtd->dma_loaded = 0;
- prtd->dma_pos = prtd->dma_start;
-
- /* enqueue dma buffers */
- dma_enqueue(substream);
-
- return ret;
-}
-
-static int dma_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct runtime_data *prtd = substream->runtime->private_data;
- int ret = 0;
-
- pr_debug("Entered %s\n", __func__);
-
- spin_lock(&prtd->lock);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- prtd->state |= ST_RUNNING;
- prtd->params->ops->trigger(prtd->params->ch);
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- prtd->state &= ~ST_RUNNING;
- prtd->params->ops->stop(prtd->params->ch);
- break;
-
- default:
- ret = -EINVAL;
- break;
- }
-
- spin_unlock(&prtd->lock);
-
- return ret;
-}
-
-static snd_pcm_uframes_t
-dma_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct runtime_data *prtd = runtime->private_data;
- unsigned long res;
-
- pr_debug("Entered %s\n", __func__);
-
- res = prtd->dma_pos - prtd->dma_start;
-
- pr_debug("Pointer offset: %lu\n", res);
-
- /* we seem to be getting the odd error from the pcm library due
- * to out-of-bounds pointers. this is maybe due to the dma engine
- * not having loaded the new values for the channel before being
- * called... (todo - fix )
- */
-
- if (res >= snd_pcm_lib_buffer_bytes(substream)) {
- if (res == snd_pcm_lib_buffer_bytes(substream))
- res = 0;
- }
-
- return bytes_to_frames(substream->runtime, res);
-}
-
-static int dma_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct runtime_data *prtd;
-
- pr_debug("Entered %s\n", __func__);
-
- snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
- snd_soc_set_runtime_hwparams(substream, &dma_hardware);
-
- prtd = kzalloc(sizeof(struct runtime_data), GFP_KERNEL);
- if (prtd == NULL)
- return -ENOMEM;
-
- spin_lock_init(&prtd->lock);
-
- runtime->private_data = prtd;
- return 0;
-}
-
-static int dma_close(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct runtime_data *prtd = runtime->private_data;
-
- pr_debug("Entered %s\n", __func__);
-
- if (!prtd)
- pr_debug("dma_close called with prtd == NULL\n");
-
- kfree(prtd);
-
- return 0;
-}
-
-static int dma_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- pr_debug("Entered %s\n", __func__);
-
- return dma_mmap_writecombine(substream->pcm->card->dev, vma,
- runtime->dma_area,
- runtime->dma_addr,
- runtime->dma_bytes);
-}
-
-static struct snd_pcm_ops dma_ops = {
- .open = dma_open,
- .close = dma_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = dma_hw_params,
- .hw_free = dma_hw_free,
- .prepare = dma_prepare,
- .trigger = dma_trigger,
- .pointer = dma_pointer,
- .mmap = dma_mmap,
-};
-
-static int preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
- struct snd_pcm_substream *substream = pcm->streams[stream].substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = dma_hardware.buffer_bytes_max;
-
- pr_debug("Entered %s\n", __func__);
-
- buf->dev.type = SNDRV_DMA_TYPE_DEV;
- buf->dev.dev = pcm->card->dev;
- buf->private_data = NULL;
- buf->area = dma_alloc_writecombine(pcm->card->dev, size,
- &buf->addr, GFP_KERNEL);
- if (!buf->area)
- return -ENOMEM;
- buf->bytes = size;
- return 0;
-}
-
-static void dma_free_dma_buffers(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- struct snd_dma_buffer *buf;
- int stream;
-
- pr_debug("Entered %s\n", __func__);
-
- for (stream = 0; stream < 2; stream++) {
- substream = pcm->streams[stream].substream;
- if (!substream)
- continue;
-
- buf = &substream->dma_buffer;
- if (!buf->area)
- continue;
-
- dma_free_writecombine(pcm->card->dev, buf->bytes,
- buf->area, buf->addr);
- buf->area = NULL;
- }
-}
-
-static u64 dma_mask = DMA_BIT_MASK(32);
-
-static int dma_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- int ret = 0;
-
- pr_debug("Entered %s\n", __func__);
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &dma_mask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_PLAYBACK);
- if (ret)
- goto out;
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- ret = preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_CAPTURE);
- if (ret)
- goto out;
- }
-out:
- return ret;
-}
-
-static struct snd_soc_platform_driver samsung_asoc_platform = {
- .ops = &dma_ops,
- .pcm_new = dma_new,
- .pcm_free = dma_free_dma_buffers,
-};
-
-static int __devinit samsung_asoc_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_platform(&pdev->dev, &samsung_asoc_platform);
-}
-
-static int __devexit samsung_asoc_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver asoc_dma_driver = {
- .driver = {
- .name = "samsung-audio",
- .owner = THIS_MODULE,
- },
-
- .probe = samsung_asoc_platform_probe,
- .remove = __devexit_p(samsung_asoc_platform_remove),
-};
-
-module_platform_driver(asoc_dma_driver);
-
-MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
-MODULE_DESCRIPTION("Samsung ASoC DMA Driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:samsung-audio");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/dma.h b/ANDROID_3.4.5/sound/soc/samsung/dma.h
deleted file mode 100644
index 7d1ead77..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/dma.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * dma.h --
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * ALSA PCM interface for the Samsung SoC
- */
-
-#ifndef _S3C_AUDIO_H
-#define _S3C_AUDIO_H
-
-struct s3c_dma_params {
- struct s3c2410_dma_client *client; /* stream identifier */
- int channel; /* Channel ID */
- dma_addr_t dma_addr;
- int dma_size; /* Size of the DMA transfer */
- unsigned ch;
- struct samsung_dma_ops *ops;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/samsung/goni_wm8994.c b/ANDROID_3.4.5/sound/soc/samsung/goni_wm8994.c
deleted file mode 100644
index c23c2ae9..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/goni_wm8994.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * goni_wm8994.c
- *
- * Copyright (C) 2010 Samsung Electronics Co.Ltd
- * Author: Chanwoo Choi <cw00.choi@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <sound/soc.h>
-#include <sound/jack.h>
-
-#include <asm/mach-types.h>
-#include <mach/gpio.h>
-
-#include "../codecs/wm8994.h"
-
-#define MACHINE_NAME 0
-#define CPU_VOICE_DAI 1
-
-static const char *aquila_str[] = {
- [MACHINE_NAME] = "aquila",
- [CPU_VOICE_DAI] = "aquila-voice-dai",
-};
-
-static struct snd_soc_card goni;
-static struct platform_device *goni_snd_device;
-
-/* 3.5 pie jack */
-static struct snd_soc_jack jack;
-
-/* 3.5 pie jack detection DAPM pins */
-static struct snd_soc_jack_pin jack_pins[] = {
- {
- .pin = "Headset Mic",
- .mask = SND_JACK_MICROPHONE,
- }, {
- .pin = "Headset Stereophone",
- .mask = SND_JACK_HEADPHONE | SND_JACK_MECHANICAL |
- SND_JACK_AVOUT,
- },
-};
-
-/* 3.5 pie jack detection gpios */
-static struct snd_soc_jack_gpio jack_gpios[] = {
- {
- .gpio = S5PV210_GPH0(6),
- .name = "DET_3.5",
- .report = SND_JACK_HEADSET | SND_JACK_MECHANICAL |
- SND_JACK_AVOUT,
- .debounce_time = 200,
- },
-};
-
-static const struct snd_soc_dapm_widget goni_dapm_widgets[] = {
- SND_SOC_DAPM_SPK("Ext Left Spk", NULL),
- SND_SOC_DAPM_SPK("Ext Right Spk", NULL),
- SND_SOC_DAPM_SPK("Ext Rcv", NULL),
- SND_SOC_DAPM_HP("Headset Stereophone", NULL),
- SND_SOC_DAPM_MIC("Headset Mic", NULL),
- SND_SOC_DAPM_MIC("Main Mic", NULL),
- SND_SOC_DAPM_MIC("2nd Mic", NULL),
- SND_SOC_DAPM_LINE("Radio In", NULL),
-};
-
-static const struct snd_soc_dapm_route goni_dapm_routes[] = {
- {"Ext Left Spk", NULL, "SPKOUTLP"},
- {"Ext Left Spk", NULL, "SPKOUTLN"},
-
- {"Ext Right Spk", NULL, "SPKOUTRP"},
- {"Ext Right Spk", NULL, "SPKOUTRN"},
-
- {"Ext Rcv", NULL, "HPOUT2N"},
- {"Ext Rcv", NULL, "HPOUT2P"},
-
- {"Headset Stereophone", NULL, "HPOUT1L"},
- {"Headset Stereophone", NULL, "HPOUT1R"},
-
- {"IN1RN", NULL, "Headset Mic"},
- {"IN1RP", NULL, "Headset Mic"},
-
- {"IN1RN", NULL, "2nd Mic"},
- {"IN1RP", NULL, "2nd Mic"},
-
- {"IN1LN", NULL, "Main Mic"},
- {"IN1LP", NULL, "Main Mic"},
-
- {"IN2LN", NULL, "Radio In"},
- {"IN2RN", NULL, "Radio In"},
-};
-
-static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret;
-
- /* set endpoints to not connected */
- snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN");
- snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP");
- snd_soc_dapm_nc_pin(dapm, "LINEOUT1N");
- snd_soc_dapm_nc_pin(dapm, "LINEOUT1P");
- snd_soc_dapm_nc_pin(dapm, "LINEOUT2N");
- snd_soc_dapm_nc_pin(dapm, "LINEOUT2P");
-
- if (machine_is_aquila()) {
- snd_soc_dapm_nc_pin(dapm, "SPKOUTRN");
- snd_soc_dapm_nc_pin(dapm, "SPKOUTRP");
- }
-
- /* Headset jack detection */
- ret = snd_soc_jack_new(codec, "Headset Jack",
- SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT,
- &jack);
- if (ret)
- return ret;
-
- ret = snd_soc_jack_add_pins(&jack, ARRAY_SIZE(jack_pins), jack_pins);
- if (ret)
- return ret;
-
- ret = snd_soc_jack_add_gpios(&jack, ARRAY_SIZE(jack_gpios), jack_gpios);
- if (ret)
- return ret;
-
- return 0;
-}
-
-static int goni_hifi_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- unsigned int pll_out = 24000000;
- int ret = 0;
-
- /* set the cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- /* set the codec FLL */
- ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, 0, pll_out,
- params_rate(params) * 256);
- if (ret < 0)
- return ret;
-
- /* set the codec system clock */
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1,
- params_rate(params) * 256, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops goni_hifi_ops = {
- .hw_params = goni_hifi_hw_params,
-};
-
-static int goni_voice_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- unsigned int pll_out = 24000000;
- int ret = 0;
-
- if (params_rate(params) != 8000)
- return -EINVAL;
-
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J |
- SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- /* set the codec FLL */
- ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, 0, pll_out,
- params_rate(params) * 256);
- if (ret < 0)
- return ret;
-
- /* set the codec system clock */
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2,
- params_rate(params) * 256, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_dai_driver voice_dai = {
- .name = "goni-voice-dai",
- .id = 0,
- .playback = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .capture = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
-};
-
-static struct snd_soc_ops goni_voice_ops = {
- .hw_params = goni_voice_hw_params,
-};
-
-static struct snd_soc_dai_link goni_dai[] = {
-{
- .name = "WM8994",
- .stream_name = "WM8994 HiFi",
- .cpu_dai_name = "samsung-i2s.0",
- .codec_dai_name = "wm8994-aif1",
- .platform_name = "samsung-audio",
- .codec_name = "wm8994-codec.0-001a",
- .init = goni_wm8994_init,
- .ops = &goni_hifi_ops,
-}, {
- .name = "WM8994 Voice",
- .stream_name = "Voice",
- .cpu_dai_name = "goni-voice-dai",
- .codec_dai_name = "wm8994-aif2",
- .codec_name = "wm8994-codec.0-001a",
- .ops = &goni_voice_ops,
-},
-};
-
-static struct snd_soc_card goni = {
- .name = "goni",
- .owner = THIS_MODULE,
- .dai_link = goni_dai,
- .num_links = ARRAY_SIZE(goni_dai),
-
- .dapm_widgets = goni_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(goni_dapm_widgets),
- .dapm_routes = goni_dapm_routes,
- .num_dapm_routes = ARRAY_SIZE(goni_dapm_routes),
-};
-
-static int __init goni_init(void)
-{
- int ret;
-
- if (machine_is_aquila()) {
- voice_dai.name = aquila_str[CPU_VOICE_DAI];
- goni_dai[1].cpu_dai_name = aquila_str[CPU_VOICE_DAI];
- goni.name = aquila_str[MACHINE_NAME];
- } else if (!machine_is_goni())
- return -ENODEV;
-
- goni_snd_device = platform_device_alloc("soc-audio", -1);
- if (!goni_snd_device)
- return -ENOMEM;
-
- /* register voice DAI here */
- ret = snd_soc_register_dai(&goni_snd_device->dev, &voice_dai);
- if (ret) {
- platform_device_put(goni_snd_device);
- return ret;
- }
-
- platform_set_drvdata(goni_snd_device, &goni);
- ret = platform_device_add(goni_snd_device);
-
- if (ret) {
- snd_soc_unregister_dai(&goni_snd_device->dev);
- platform_device_put(goni_snd_device);
- }
-
- return ret;
-}
-
-static void __exit goni_exit(void)
-{
- snd_soc_unregister_dai(&goni_snd_device->dev);
- platform_device_unregister(goni_snd_device);
-}
-
-module_init(goni_init);
-module_exit(goni_exit);
-
-/* Module information */
-MODULE_DESCRIPTION("ALSA SoC WM8994 GONI(S5PV210)");
-MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/h1940_uda1380.c b/ANDROID_3.4.5/sound/soc/samsung/h1940_uda1380.c
deleted file mode 100644
index 6e325771..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/h1940_uda1380.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * h1940-uda1380.c -- ALSA Soc Audio Layer
- *
- * Copyright (c) 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
- * Copyright (c) 2010 Vasily Khoruzhick <anarsoul@gmail.com>
- *
- * Based on version from Arnaud Patard <arnaud.patard@rtp-net.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/types.h>
-#include <linux/gpio.h>
-#include <linux/module.h>
-
-#include <sound/soc.h>
-#include <sound/jack.h>
-
-#include <plat/regs-iis.h>
-#include <mach/h1940-latch.h>
-#include <asm/mach-types.h>
-
-#include "s3c24xx-i2s.h"
-
-static unsigned int rates[] = {
- 11025,
- 22050,
- 44100,
-};
-
-static struct snd_pcm_hw_constraint_list hw_rates = {
- .count = ARRAY_SIZE(rates),
- .list = rates,
- .mask = 0,
-};
-
-static struct snd_soc_jack hp_jack;
-
-static struct snd_soc_jack_pin hp_jack_pins[] = {
- {
- .pin = "Headphone Jack",
- .mask = SND_JACK_HEADPHONE,
- },
- {
- .pin = "Speaker",
- .mask = SND_JACK_HEADPHONE,
- .invert = 1,
- },
-};
-
-static struct snd_soc_jack_gpio hp_jack_gpios[] = {
- {
- .gpio = S3C2410_GPG(4),
- .name = "hp-gpio",
- .report = SND_JACK_HEADPHONE,
- .invert = 1,
- .debounce_time = 200,
- },
-};
-
-static int h1940_startup(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- runtime->hw.rate_min = hw_rates.list[0];
- runtime->hw.rate_max = hw_rates.list[hw_rates.count - 1];
- runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
-
- return snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- &hw_rates);
-}
-
-static int h1940_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int div;
- int ret;
- unsigned int rate = params_rate(params);
-
- switch (rate) {
- case 11025:
- case 22050:
- case 44100:
- div = s3c24xx_i2s_get_clockrate() / (384 * rate);
- if (s3c24xx_i2s_get_clockrate() % (384 * rate) > (192 * rate))
- div++;
- break;
- default:
- dev_err(&rtd->dev, "%s: rate %d is not supported\n",
- __func__, rate);
- return -EINVAL;
- }
-
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* select clock source */
- ret = snd_soc_dai_set_sysclk(cpu_dai, S3C24XX_CLKSRC_PCLK, rate,
- SND_SOC_CLOCK_OUT);
- if (ret < 0)
- return ret;
-
- /* set MCLK division for sample rate */
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
- S3C2410_IISMOD_384FS);
- if (ret < 0)
- return ret;
-
- /* set BCLK division for sample rate */
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK,
- S3C2410_IISMOD_32FS);
- if (ret < 0)
- return ret;
-
- /* set prescaler division for sample rate */
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
- S3C24XX_PRESCALE(div, div));
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops h1940_ops = {
- .startup = h1940_startup,
- .hw_params = h1940_hw_params,
-};
-
-static int h1940_spk_power(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- if (SND_SOC_DAPM_EVENT_ON(event))
- gpio_set_value(H1940_LATCH_AUDIO_POWER, 1);
- else
- gpio_set_value(H1940_LATCH_AUDIO_POWER, 0);
-
- return 0;
-}
-
-/* h1940 machine dapm widgets */
-static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_MIC("Mic Jack", NULL),
- SND_SOC_DAPM_SPK("Speaker", h1940_spk_power),
-};
-
-/* h1940 machine audio_map */
-static const struct snd_soc_dapm_route audio_map[] = {
- /* headphone connected to VOUTLHP, VOUTRHP */
- {"Headphone Jack", NULL, "VOUTLHP"},
- {"Headphone Jack", NULL, "VOUTRHP"},
-
- /* ext speaker connected to VOUTL, VOUTR */
- {"Speaker", NULL, "VOUTL"},
- {"Speaker", NULL, "VOUTR"},
-
- /* mic is connected to VINM */
- {"VINM", NULL, "Mic Jack"},
-};
-
-static struct platform_device *s3c24xx_snd_device;
-
-static int h1940_uda1380_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int err;
-
- snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_enable_pin(dapm, "Speaker");
- snd_soc_dapm_enable_pin(dapm, "Mic Jack");
-
- snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
- &hp_jack);
-
- snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins),
- hp_jack_pins);
-
- snd_soc_jack_add_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios),
- hp_jack_gpios);
-
- return 0;
-}
-
-/* s3c24xx digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link h1940_uda1380_dai[] = {
- {
- .name = "uda1380",
- .stream_name = "UDA1380 Duplex",
- .cpu_dai_name = "s3c24xx-iis",
- .codec_dai_name = "uda1380-hifi",
- .init = h1940_uda1380_init,
- .platform_name = "samsung-audio",
- .codec_name = "uda1380-codec.0-001a",
- .ops = &h1940_ops,
- },
-};
-
-static struct snd_soc_card h1940_asoc = {
- .name = "h1940",
- .owner = THIS_MODULE,
- .dai_link = h1940_uda1380_dai,
- .num_links = ARRAY_SIZE(h1940_uda1380_dai),
-
- .dapm_widgets = uda1380_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets),
- .dapm_routes = audio_map,
- .num_dapm_routes = ARRAY_SIZE(audio_map),
-};
-
-static int __init h1940_init(void)
-{
- int ret;
-
- if (!machine_is_h1940())
- return -ENODEV;
-
- /* configure some gpios */
- ret = gpio_request(H1940_LATCH_AUDIO_POWER, "speaker-power");
- if (ret)
- goto err_out;
-
- ret = gpio_direction_output(H1940_LATCH_AUDIO_POWER, 0);
- if (ret)
- goto err_gpio;
-
- s3c24xx_snd_device = platform_device_alloc("soc-audio", -1);
- if (!s3c24xx_snd_device) {
- ret = -ENOMEM;
- goto err_gpio;
- }
-
- platform_set_drvdata(s3c24xx_snd_device, &h1940_asoc);
- ret = platform_device_add(s3c24xx_snd_device);
-
- if (ret)
- goto err_plat;
-
- return 0;
-
-err_plat:
- platform_device_put(s3c24xx_snd_device);
-err_gpio:
- gpio_free(H1940_LATCH_AUDIO_POWER);
-
-err_out:
- return ret;
-}
-
-static void __exit h1940_exit(void)
-{
- platform_device_unregister(s3c24xx_snd_device);
- snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios),
- hp_jack_gpios);
- gpio_free(H1940_LATCH_AUDIO_POWER);
-}
-
-module_init(h1940_init);
-module_exit(h1940_exit);
-
-/* Module information */
-MODULE_AUTHOR("Arnaud Patard, Vasily Khoruzhick");
-MODULE_DESCRIPTION("ALSA SoC H1940");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/i2s-regs.h b/ANDROID_3.4.5/sound/soc/samsung/i2s-regs.h
deleted file mode 100644
index c0e6d9a1..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/i2s-regs.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * linux/sound/soc/samsung/i2s-regs.h
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Samsung I2S driver's register header
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#ifndef __SND_SOC_SAMSUNG_I2S_REGS_H
-#define __SND_SOC_SAMSUNG_I2S_REGS_H
-
-#define I2SCON 0x0
-#define I2SMOD 0x4
-#define I2SFIC 0x8
-#define I2SPSR 0xc
-#define I2STXD 0x10
-#define I2SRXD 0x14
-#define I2SFICS 0x18
-#define I2STXDS 0x1c
-#define I2SAHB 0x20
-#define I2SSTR0 0x24
-#define I2SSIZE 0x28
-#define I2STRNCNT 0x2c
-#define I2SLVL0ADDR 0x30
-#define I2SLVL1ADDR 0x34
-#define I2SLVL2ADDR 0x38
-#define I2SLVL3ADDR 0x3c
-
-#define CON_RSTCLR (1 << 31)
-#define CON_FRXOFSTATUS (1 << 26)
-#define CON_FRXORINTEN (1 << 25)
-#define CON_FTXSURSTAT (1 << 24)
-#define CON_FTXSURINTEN (1 << 23)
-#define CON_TXSDMA_PAUSE (1 << 20)
-#define CON_TXSDMA_ACTIVE (1 << 18)
-
-#define CON_FTXURSTATUS (1 << 17)
-#define CON_FTXURINTEN (1 << 16)
-#define CON_TXFIFO2_EMPTY (1 << 15)
-#define CON_TXFIFO1_EMPTY (1 << 14)
-#define CON_TXFIFO2_FULL (1 << 13)
-#define CON_TXFIFO1_FULL (1 << 12)
-
-#define CON_LRINDEX (1 << 11)
-#define CON_TXFIFO_EMPTY (1 << 10)
-#define CON_RXFIFO_EMPTY (1 << 9)
-#define CON_TXFIFO_FULL (1 << 8)
-#define CON_RXFIFO_FULL (1 << 7)
-#define CON_TXDMA_PAUSE (1 << 6)
-#define CON_RXDMA_PAUSE (1 << 5)
-#define CON_TXCH_PAUSE (1 << 4)
-#define CON_RXCH_PAUSE (1 << 3)
-#define CON_TXDMA_ACTIVE (1 << 2)
-#define CON_RXDMA_ACTIVE (1 << 1)
-#define CON_ACTIVE (1 << 0)
-
-#define MOD_OPCLK_CDCLK_OUT (0 << 30)
-#define MOD_OPCLK_CDCLK_IN (1 << 30)
-#define MOD_OPCLK_BCLK_OUT (2 << 30)
-#define MOD_OPCLK_PCLK (3 << 30)
-#define MOD_OPCLK_MASK (3 << 30)
-#define MOD_TXS_IDMA (1 << 28) /* Sec_TXFIFO use I-DMA */
-
-#define MOD_BLCS_SHIFT 26
-#define MOD_BLCS_16BIT (0 << MOD_BLCS_SHIFT)
-#define MOD_BLCS_8BIT (1 << MOD_BLCS_SHIFT)
-#define MOD_BLCS_24BIT (2 << MOD_BLCS_SHIFT)
-#define MOD_BLCS_MASK (3 << MOD_BLCS_SHIFT)
-#define MOD_BLCP_SHIFT 24
-#define MOD_BLCP_16BIT (0 << MOD_BLCP_SHIFT)
-#define MOD_BLCP_8BIT (1 << MOD_BLCP_SHIFT)
-#define MOD_BLCP_24BIT (2 << MOD_BLCP_SHIFT)
-#define MOD_BLCP_MASK (3 << MOD_BLCP_SHIFT)
-
-#define MOD_C2DD_HHALF (1 << 21) /* Discard Higher-half */
-#define MOD_C2DD_LHALF (1 << 20) /* Discard Lower-half */
-#define MOD_C1DD_HHALF (1 << 19)
-#define MOD_C1DD_LHALF (1 << 18)
-#define MOD_DC2_EN (1 << 17)
-#define MOD_DC1_EN (1 << 16)
-#define MOD_BLC_16BIT (0 << 13)
-#define MOD_BLC_8BIT (1 << 13)
-#define MOD_BLC_24BIT (2 << 13)
-#define MOD_BLC_MASK (3 << 13)
-
-#define MOD_IMS_SYSMUX (1 << 10)
-#define MOD_SLAVE (1 << 11)
-#define MOD_TXONLY (0 << 8)
-#define MOD_RXONLY (1 << 8)
-#define MOD_TXRX (2 << 8)
-#define MOD_MASK (3 << 8)
-#define MOD_LR_LLOW (0 << 7)
-#define MOD_LR_RLOW (1 << 7)
-#define MOD_SDF_IIS (0 << 5)
-#define MOD_SDF_MSB (1 << 5)
-#define MOD_SDF_LSB (2 << 5)
-#define MOD_SDF_MASK (3 << 5)
-#define MOD_RCLK_256FS (0 << 3)
-#define MOD_RCLK_512FS (1 << 3)
-#define MOD_RCLK_384FS (2 << 3)
-#define MOD_RCLK_768FS (3 << 3)
-#define MOD_RCLK_MASK (3 << 3)
-#define MOD_BCLK_32FS (0 << 1)
-#define MOD_BCLK_48FS (1 << 1)
-#define MOD_BCLK_16FS (2 << 1)
-#define MOD_BCLK_24FS (3 << 1)
-#define MOD_BCLK_MASK (3 << 1)
-#define MOD_8BIT (1 << 0)
-
-#define MOD_CDCLKCON (1 << 12)
-
-#define PSR_PSREN (1 << 15)
-
-#define FIC_TX2COUNT(x) (((x) >> 24) & 0xf)
-#define FIC_TX1COUNT(x) (((x) >> 16) & 0xf)
-
-#define FIC_TXFLUSH (1 << 15)
-#define FIC_RXFLUSH (1 << 7)
-
-#define FIC_TXCOUNT(x) (((x) >> 8) & 0xf)
-#define FIC_RXCOUNT(x) (((x) >> 0) & 0xf)
-#define FICS_TXCOUNT(x) (((x) >> 8) & 0x7f)
-
-#define AHB_INTENLVL0 (1 << 24)
-#define AHB_LVL0INT (1 << 20)
-#define AHB_CLRLVL0INT (1 << 16)
-#define AHB_DMARLD (1 << 5)
-#define AHB_INTMASK (1 << 3)
-#define AHB_DMAEN (1 << 0)
-#define AHB_LVLINTMASK (0xf << 20)
-
-#define I2SSIZE_TRNMSK (0xffff)
-#define I2SSIZE_SHIFT (16)
-
-#endif /* __SND_SOC_SAMSUNG_I2S_REGS_H */
-
-
diff --git a/ANDROID_3.4.5/sound/soc/samsung/i2s.c b/ANDROID_3.4.5/sound/soc/samsung/i2s.c
deleted file mode 100644
index 6ac7b828..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/i2s.c
+++ /dev/null
@@ -1,1158 +0,0 @@
-/* sound/soc/samsung/i2s.c
- *
- * ALSA SoC Audio Layer - Samsung I2S Controller driver
- *
- * Copyright (c) 2010 Samsung Electronics Co. Ltd.
- * Jaswinder Singh <jassisinghbrar@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/pm_runtime.h>
-
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <plat/audio.h>
-
-#include "dma.h"
-#include "idma.h"
-#include "i2s.h"
-#include "i2s-regs.h"
-
-#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
-
-struct i2s_dai {
- /* Platform device for this DAI */
- struct platform_device *pdev;
- /* IOREMAP'd SFRs */
- void __iomem *addr;
- /* Physical base address of SFRs */
- u32 base;
- /* Rate of RCLK source clock */
- unsigned long rclk_srcrate;
- /* Frame Clock */
- unsigned frmclk;
- /*
- * Specifically requested RCLK,BCLK by MACHINE Driver.
- * 0 indicates CPU driver is free to choose any value.
- */
- unsigned rfs, bfs;
- /* I2S Controller's core clock */
- struct clk *clk;
- /* Clock for generating I2S signals */
- struct clk *op_clk;
- /* Array of clock names for op_clk */
- const char **src_clk;
- /* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */
- struct i2s_dai *pri_dai;
- /* Pointer to the Secondary_Fifo if it has one, NULL otherwise */
- struct i2s_dai *sec_dai;
-#define DAI_OPENED (1 << 0) /* Dai is opened */
-#define DAI_MANAGER (1 << 1) /* Dai is the manager */
- unsigned mode;
- /* Driver for this DAI */
- struct snd_soc_dai_driver i2s_dai_drv;
- /* DMA parameters */
- struct s3c_dma_params dma_playback;
- struct s3c_dma_params dma_capture;
- struct s3c_dma_params idma_playback;
- u32 quirks;
- u32 suspend_i2smod;
- u32 suspend_i2scon;
- u32 suspend_i2spsr;
-};
-
-/* Lock for cross i/f checks */
-static DEFINE_SPINLOCK(lock);
-
-/* If this is the 'overlay' stereo DAI */
-static inline bool is_secondary(struct i2s_dai *i2s)
-{
- return i2s->pri_dai ? true : false;
-}
-
-/* If operating in SoC-Slave mode */
-static inline bool is_slave(struct i2s_dai *i2s)
-{
- return (readl(i2s->addr + I2SMOD) & MOD_SLAVE) ? true : false;
-}
-
-/* If this interface of the controller is transmitting data */
-static inline bool tx_active(struct i2s_dai *i2s)
-{
- u32 active;
-
- if (!i2s)
- return false;
-
- active = readl(i2s->addr + I2SCON);
-
- if (is_secondary(i2s))
- active &= CON_TXSDMA_ACTIVE;
- else
- active &= CON_TXDMA_ACTIVE;
-
- return active ? true : false;
-}
-
-/* If the other interface of the controller is transmitting data */
-static inline bool other_tx_active(struct i2s_dai *i2s)
-{
- struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
-
- return tx_active(other);
-}
-
-/* If any interface of the controller is transmitting data */
-static inline bool any_tx_active(struct i2s_dai *i2s)
-{
- return tx_active(i2s) || other_tx_active(i2s);
-}
-
-/* If this interface of the controller is receiving data */
-static inline bool rx_active(struct i2s_dai *i2s)
-{
- u32 active;
-
- if (!i2s)
- return false;
-
- active = readl(i2s->addr + I2SCON) & CON_RXDMA_ACTIVE;
-
- return active ? true : false;
-}
-
-/* If the other interface of the controller is receiving data */
-static inline bool other_rx_active(struct i2s_dai *i2s)
-{
- struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
-
- return rx_active(other);
-}
-
-/* If any interface of the controller is receiving data */
-static inline bool any_rx_active(struct i2s_dai *i2s)
-{
- return rx_active(i2s) || other_rx_active(i2s);
-}
-
-/* If the other DAI is transmitting or receiving data */
-static inline bool other_active(struct i2s_dai *i2s)
-{
- return other_rx_active(i2s) || other_tx_active(i2s);
-}
-
-/* If this DAI is transmitting or receiving data */
-static inline bool this_active(struct i2s_dai *i2s)
-{
- return tx_active(i2s) || rx_active(i2s);
-}
-
-/* If the controller is active anyway */
-static inline bool any_active(struct i2s_dai *i2s)
-{
- return this_active(i2s) || other_active(i2s);
-}
-
-static inline struct i2s_dai *to_info(struct snd_soc_dai *dai)
-{
- return snd_soc_dai_get_drvdata(dai);
-}
-
-static inline bool is_opened(struct i2s_dai *i2s)
-{
- if (i2s && (i2s->mode & DAI_OPENED))
- return true;
- else
- return false;
-}
-
-static inline bool is_manager(struct i2s_dai *i2s)
-{
- if (is_opened(i2s) && (i2s->mode & DAI_MANAGER))
- return true;
- else
- return false;
-}
-
-/* Read RCLK of I2S (in multiples of LRCLK) */
-static inline unsigned get_rfs(struct i2s_dai *i2s)
-{
- u32 rfs = (readl(i2s->addr + I2SMOD) >> 3) & 0x3;
-
- switch (rfs) {
- case 3: return 768;
- case 2: return 384;
- case 1: return 512;
- default: return 256;
- }
-}
-
-/* Write RCLK of I2S (in multiples of LRCLK) */
-static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs)
-{
- u32 mod = readl(i2s->addr + I2SMOD);
-
- mod &= ~MOD_RCLK_MASK;
-
- switch (rfs) {
- case 768:
- mod |= MOD_RCLK_768FS;
- break;
- case 512:
- mod |= MOD_RCLK_512FS;
- break;
- case 384:
- mod |= MOD_RCLK_384FS;
- break;
- default:
- mod |= MOD_RCLK_256FS;
- break;
- }
-
- writel(mod, i2s->addr + I2SMOD);
-}
-
-/* Read Bit-Clock of I2S (in multiples of LRCLK) */
-static inline unsigned get_bfs(struct i2s_dai *i2s)
-{
- u32 bfs = (readl(i2s->addr + I2SMOD) >> 1) & 0x3;
-
- switch (bfs) {
- case 3: return 24;
- case 2: return 16;
- case 1: return 48;
- default: return 32;
- }
-}
-
-/* Write Bit-Clock of I2S (in multiples of LRCLK) */
-static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs)
-{
- u32 mod = readl(i2s->addr + I2SMOD);
-
- mod &= ~MOD_BCLK_MASK;
-
- switch (bfs) {
- case 48:
- mod |= MOD_BCLK_48FS;
- break;
- case 32:
- mod |= MOD_BCLK_32FS;
- break;
- case 24:
- mod |= MOD_BCLK_24FS;
- break;
- case 16:
- mod |= MOD_BCLK_16FS;
- break;
- default:
- dev_err(&i2s->pdev->dev, "Wrong BCLK Divider!\n");
- return;
- }
-
- writel(mod, i2s->addr + I2SMOD);
-}
-
-/* Sample-Size */
-static inline int get_blc(struct i2s_dai *i2s)
-{
- int blc = readl(i2s->addr + I2SMOD);
-
- blc = (blc >> 13) & 0x3;
-
- switch (blc) {
- case 2: return 24;
- case 1: return 8;
- default: return 16;
- }
-}
-
-/* TX Channel Control */
-static void i2s_txctrl(struct i2s_dai *i2s, int on)
-{
- void __iomem *addr = i2s->addr;
- u32 con = readl(addr + I2SCON);
- u32 mod = readl(addr + I2SMOD) & ~MOD_MASK;
-
- if (on) {
- con |= CON_ACTIVE;
- con &= ~CON_TXCH_PAUSE;
-
- if (is_secondary(i2s)) {
- con |= CON_TXSDMA_ACTIVE;
- con &= ~CON_TXSDMA_PAUSE;
- } else {
- con |= CON_TXDMA_ACTIVE;
- con &= ~CON_TXDMA_PAUSE;
- }
-
- if (any_rx_active(i2s))
- mod |= MOD_TXRX;
- else
- mod |= MOD_TXONLY;
- } else {
- if (is_secondary(i2s)) {
- con |= CON_TXSDMA_PAUSE;
- con &= ~CON_TXSDMA_ACTIVE;
- } else {
- con |= CON_TXDMA_PAUSE;
- con &= ~CON_TXDMA_ACTIVE;
- }
-
- if (other_tx_active(i2s)) {
- writel(con, addr + I2SCON);
- return;
- }
-
- con |= CON_TXCH_PAUSE;
-
- if (any_rx_active(i2s))
- mod |= MOD_RXONLY;
- else
- con &= ~CON_ACTIVE;
- }
-
- writel(mod, addr + I2SMOD);
- writel(con, addr + I2SCON);
-}
-
-/* RX Channel Control */
-static void i2s_rxctrl(struct i2s_dai *i2s, int on)
-{
- void __iomem *addr = i2s->addr;
- u32 con = readl(addr + I2SCON);
- u32 mod = readl(addr + I2SMOD) & ~MOD_MASK;
-
- if (on) {
- con |= CON_RXDMA_ACTIVE | CON_ACTIVE;
- con &= ~(CON_RXDMA_PAUSE | CON_RXCH_PAUSE);
-
- if (any_tx_active(i2s))
- mod |= MOD_TXRX;
- else
- mod |= MOD_RXONLY;
- } else {
- con |= CON_RXDMA_PAUSE | CON_RXCH_PAUSE;
- con &= ~CON_RXDMA_ACTIVE;
-
- if (any_tx_active(i2s))
- mod |= MOD_TXONLY;
- else
- con &= ~CON_ACTIVE;
- }
-
- writel(mod, addr + I2SMOD);
- writel(con, addr + I2SCON);
-}
-
-/* Flush FIFO of an interface */
-static inline void i2s_fifo(struct i2s_dai *i2s, u32 flush)
-{
- void __iomem *fic;
- u32 val;
-
- if (!i2s)
- return;
-
- if (is_secondary(i2s))
- fic = i2s->addr + I2SFICS;
- else
- fic = i2s->addr + I2SFIC;
-
- /* Flush the FIFO */
- writel(readl(fic) | flush, fic);
-
- /* Be patient */
- val = msecs_to_loops(1) / 1000; /* 1 usec */
- while (--val)
- cpu_relax();
-
- writel(readl(fic) & ~flush, fic);
-}
-
-static int i2s_set_sysclk(struct snd_soc_dai *dai,
- int clk_id, unsigned int rfs, int dir)
-{
- struct i2s_dai *i2s = to_info(dai);
- struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
- u32 mod = readl(i2s->addr + I2SMOD);
-
- switch (clk_id) {
- case SAMSUNG_I2S_CDCLK:
- /* Shouldn't matter in GATING(CLOCK_IN) mode */
- if (dir == SND_SOC_CLOCK_IN)
- rfs = 0;
-
- if ((rfs && other->rfs && (other->rfs != rfs)) ||
- (any_active(i2s) &&
- (((dir == SND_SOC_CLOCK_IN)
- && !(mod & MOD_CDCLKCON)) ||
- ((dir == SND_SOC_CLOCK_OUT)
- && (mod & MOD_CDCLKCON))))) {
- dev_err(&i2s->pdev->dev,
- "%s:%d Other DAI busy\n", __func__, __LINE__);
- return -EAGAIN;
- }
-
- if (dir == SND_SOC_CLOCK_IN)
- mod |= MOD_CDCLKCON;
- else
- mod &= ~MOD_CDCLKCON;
-
- i2s->rfs = rfs;
- break;
-
- case SAMSUNG_I2S_RCLKSRC_0: /* clock corrsponding to IISMOD[10] := 0 */
- case SAMSUNG_I2S_RCLKSRC_1: /* clock corrsponding to IISMOD[10] := 1 */
- if ((i2s->quirks & QUIRK_NO_MUXPSR)
- || (clk_id == SAMSUNG_I2S_RCLKSRC_0))
- clk_id = 0;
- else
- clk_id = 1;
-
- if (!any_active(i2s)) {
- if (i2s->op_clk) {
- if ((clk_id && !(mod & MOD_IMS_SYSMUX)) ||
- (!clk_id && (mod & MOD_IMS_SYSMUX))) {
- clk_disable(i2s->op_clk);
- clk_put(i2s->op_clk);
- } else {
- i2s->rclk_srcrate =
- clk_get_rate(i2s->op_clk);
- return 0;
- }
- }
-
- i2s->op_clk = clk_get(&i2s->pdev->dev,
- i2s->src_clk[clk_id]);
- clk_enable(i2s->op_clk);
- i2s->rclk_srcrate = clk_get_rate(i2s->op_clk);
-
- /* Over-ride the other's */
- if (other) {
- other->op_clk = i2s->op_clk;
- other->rclk_srcrate = i2s->rclk_srcrate;
- }
- } else if ((!clk_id && (mod & MOD_IMS_SYSMUX))
- || (clk_id && !(mod & MOD_IMS_SYSMUX))) {
- dev_err(&i2s->pdev->dev,
- "%s:%d Other DAI busy\n", __func__, __LINE__);
- return -EAGAIN;
- } else {
- /* Call can't be on the active DAI */
- i2s->op_clk = other->op_clk;
- i2s->rclk_srcrate = other->rclk_srcrate;
- return 0;
- }
-
- if (clk_id == 0)
- mod &= ~MOD_IMS_SYSMUX;
- else
- mod |= MOD_IMS_SYSMUX;
- break;
-
- default:
- dev_err(&i2s->pdev->dev, "We don't serve that!\n");
- return -EINVAL;
- }
-
- writel(mod, i2s->addr + I2SMOD);
-
- return 0;
-}
-
-static int i2s_set_fmt(struct snd_soc_dai *dai,
- unsigned int fmt)
-{
- struct i2s_dai *i2s = to_info(dai);
- u32 mod = readl(i2s->addr + I2SMOD);
- u32 tmp = 0;
-
- /* Format is priority */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_RIGHT_J:
- tmp |= MOD_LR_RLOW;
- tmp |= MOD_SDF_MSB;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- tmp |= MOD_LR_RLOW;
- tmp |= MOD_SDF_LSB;
- break;
- case SND_SOC_DAIFMT_I2S:
- tmp |= MOD_SDF_IIS;
- break;
- default:
- dev_err(&i2s->pdev->dev, "Format not supported\n");
- return -EINVAL;
- }
-
- /*
- * INV flag is relative to the FORMAT flag - if set it simply
- * flips the polarity specified by the Standard
- */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_NB_IF:
- if (tmp & MOD_LR_RLOW)
- tmp &= ~MOD_LR_RLOW;
- else
- tmp |= MOD_LR_RLOW;
- break;
- default:
- dev_err(&i2s->pdev->dev, "Polarity not supported\n");
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- tmp |= MOD_SLAVE;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- /* Set default source clock in Master mode */
- if (i2s->rclk_srcrate == 0)
- i2s_set_sysclk(dai, SAMSUNG_I2S_RCLKSRC_0,
- 0, SND_SOC_CLOCK_IN);
- break;
- default:
- dev_err(&i2s->pdev->dev, "master/slave format not supported\n");
- return -EINVAL;
- }
-
- if (any_active(i2s) &&
- ((mod & (MOD_SDF_MASK | MOD_LR_RLOW
- | MOD_SLAVE)) != tmp)) {
- dev_err(&i2s->pdev->dev,
- "%s:%d Other DAI busy\n", __func__, __LINE__);
- return -EAGAIN;
- }
-
- mod &= ~(MOD_SDF_MASK | MOD_LR_RLOW | MOD_SLAVE);
- mod |= tmp;
- writel(mod, i2s->addr + I2SMOD);
-
- return 0;
-}
-
-static int i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
-{
- struct i2s_dai *i2s = to_info(dai);
- u32 mod = readl(i2s->addr + I2SMOD);
-
- if (!is_secondary(i2s))
- mod &= ~(MOD_DC2_EN | MOD_DC1_EN);
-
- switch (params_channels(params)) {
- case 6:
- mod |= MOD_DC2_EN;
- case 4:
- mod |= MOD_DC1_EN;
- break;
- case 2:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- i2s->dma_playback.dma_size = 4;
- else
- i2s->dma_capture.dma_size = 4;
- break;
- case 1:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- i2s->dma_playback.dma_size = 2;
- else
- i2s->dma_capture.dma_size = 2;
-
- break;
- default:
- dev_err(&i2s->pdev->dev, "%d channels not supported\n",
- params_channels(params));
- return -EINVAL;
- }
-
- if (is_secondary(i2s))
- mod &= ~MOD_BLCS_MASK;
- else
- mod &= ~MOD_BLCP_MASK;
-
- if (is_manager(i2s))
- mod &= ~MOD_BLC_MASK;
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S8:
- if (is_secondary(i2s))
- mod |= MOD_BLCS_8BIT;
- else
- mod |= MOD_BLCP_8BIT;
- if (is_manager(i2s))
- mod |= MOD_BLC_8BIT;
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- if (is_secondary(i2s))
- mod |= MOD_BLCS_16BIT;
- else
- mod |= MOD_BLCP_16BIT;
- if (is_manager(i2s))
- mod |= MOD_BLC_16BIT;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- if (is_secondary(i2s))
- mod |= MOD_BLCS_24BIT;
- else
- mod |= MOD_BLCP_24BIT;
- if (is_manager(i2s))
- mod |= MOD_BLC_24BIT;
- break;
- default:
- dev_err(&i2s->pdev->dev, "Format(%d) not supported\n",
- params_format(params));
- return -EINVAL;
- }
- writel(mod, i2s->addr + I2SMOD);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- snd_soc_dai_set_dma_data(dai, substream,
- (void *)&i2s->dma_playback);
- else
- snd_soc_dai_set_dma_data(dai, substream,
- (void *)&i2s->dma_capture);
-
- i2s->frmclk = params_rate(params);
-
- return 0;
-}
-
-/* We set constraints on the substream acc to the version of I2S */
-static int i2s_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct i2s_dai *i2s = to_info(dai);
- struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
- unsigned long flags;
-
- spin_lock_irqsave(&lock, flags);
-
- i2s->mode |= DAI_OPENED;
-
- if (is_manager(other))
- i2s->mode &= ~DAI_MANAGER;
- else
- i2s->mode |= DAI_MANAGER;
-
- /* Enforce set_sysclk in Master mode */
- i2s->rclk_srcrate = 0;
-
- spin_unlock_irqrestore(&lock, flags);
-
- return 0;
-}
-
-static void i2s_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct i2s_dai *i2s = to_info(dai);
- struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
- unsigned long flags;
-
- spin_lock_irqsave(&lock, flags);
-
- i2s->mode &= ~DAI_OPENED;
- i2s->mode &= ~DAI_MANAGER;
-
- if (is_opened(other))
- other->mode |= DAI_MANAGER;
-
- /* Reset any constraint on RFS and BFS */
- i2s->rfs = 0;
- i2s->bfs = 0;
-
- spin_unlock_irqrestore(&lock, flags);
-
- /* Gate CDCLK by default */
- if (!is_opened(other))
- i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK,
- 0, SND_SOC_CLOCK_IN);
-}
-
-static int config_setup(struct i2s_dai *i2s)
-{
- struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
- unsigned rfs, bfs, blc;
- u32 psr;
-
- blc = get_blc(i2s);
-
- bfs = i2s->bfs;
-
- if (!bfs && other)
- bfs = other->bfs;
-
- /* Select least possible multiple(2) if no constraint set */
- if (!bfs)
- bfs = blc * 2;
-
- rfs = i2s->rfs;
-
- if (!rfs && other)
- rfs = other->rfs;
-
- if ((rfs == 256 || rfs == 512) && (blc == 24)) {
- dev_err(&i2s->pdev->dev,
- "%d-RFS not supported for 24-blc\n", rfs);
- return -EINVAL;
- }
-
- if (!rfs) {
- if (bfs == 16 || bfs == 32)
- rfs = 256;
- else
- rfs = 384;
- }
-
- /* If already setup and running */
- if (any_active(i2s) && (get_rfs(i2s) != rfs || get_bfs(i2s) != bfs)) {
- dev_err(&i2s->pdev->dev,
- "%s:%d Other DAI busy\n", __func__, __LINE__);
- return -EAGAIN;
- }
-
- /* Don't bother RFS, BFS & PSR in Slave mode */
- if (is_slave(i2s))
- return 0;
-
- set_bfs(i2s, bfs);
- set_rfs(i2s, rfs);
-
- if (!(i2s->quirks & QUIRK_NO_MUXPSR)) {
- psr = i2s->rclk_srcrate / i2s->frmclk / rfs;
- writel(((psr - 1) << 8) | PSR_PSREN, i2s->addr + I2SPSR);
- dev_dbg(&i2s->pdev->dev,
- "RCLK_SRC=%luHz PSR=%u, RCLK=%dfs, BCLK=%dfs\n",
- i2s->rclk_srcrate, psr, rfs, bfs);
- }
-
- return 0;
-}
-
-static int i2s_trigger(struct snd_pcm_substream *substream,
- int cmd, struct snd_soc_dai *dai)
-{
- int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct i2s_dai *i2s = to_info(rtd->cpu_dai);
- unsigned long flags;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- local_irq_save(flags);
-
- if (config_setup(i2s)) {
- local_irq_restore(flags);
- return -EINVAL;
- }
-
- if (capture)
- i2s_rxctrl(i2s, 1);
- else
- i2s_txctrl(i2s, 1);
-
- local_irq_restore(flags);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- local_irq_save(flags);
-
- if (capture) {
- i2s_rxctrl(i2s, 0);
- i2s_fifo(i2s, FIC_RXFLUSH);
- } else {
- i2s_txctrl(i2s, 0);
- i2s_fifo(i2s, FIC_TXFLUSH);
- }
-
- local_irq_restore(flags);
- break;
- }
-
- return 0;
-}
-
-static int i2s_set_clkdiv(struct snd_soc_dai *dai,
- int div_id, int div)
-{
- struct i2s_dai *i2s = to_info(dai);
- struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
-
- switch (div_id) {
- case SAMSUNG_I2S_DIV_BCLK:
- if ((any_active(i2s) && div && (get_bfs(i2s) != div))
- || (other && other->bfs && (other->bfs != div))) {
- dev_err(&i2s->pdev->dev,
- "%s:%d Other DAI busy\n", __func__, __LINE__);
- return -EAGAIN;
- }
- i2s->bfs = div;
- break;
- default:
- dev_err(&i2s->pdev->dev,
- "Invalid clock divider(%d)\n", div_id);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static snd_pcm_sframes_t
-i2s_delay(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
-{
- struct i2s_dai *i2s = to_info(dai);
- u32 reg = readl(i2s->addr + I2SFIC);
- snd_pcm_sframes_t delay;
-
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- delay = FIC_RXCOUNT(reg);
- else if (is_secondary(i2s))
- delay = FICS_TXCOUNT(readl(i2s->addr + I2SFICS));
- else
- delay = FIC_TXCOUNT(reg);
-
- return delay;
-}
-
-#ifdef CONFIG_PM
-static int i2s_suspend(struct snd_soc_dai *dai)
-{
- struct i2s_dai *i2s = to_info(dai);
-
- if (dai->active) {
- i2s->suspend_i2smod = readl(i2s->addr + I2SMOD);
- i2s->suspend_i2scon = readl(i2s->addr + I2SCON);
- i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR);
- }
-
- return 0;
-}
-
-static int i2s_resume(struct snd_soc_dai *dai)
-{
- struct i2s_dai *i2s = to_info(dai);
-
- if (dai->active) {
- writel(i2s->suspend_i2scon, i2s->addr + I2SCON);
- writel(i2s->suspend_i2smod, i2s->addr + I2SMOD);
- writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR);
- }
-
- return 0;
-}
-#else
-#define i2s_suspend NULL
-#define i2s_resume NULL
-#endif
-
-static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
-{
- struct i2s_dai *i2s = to_info(dai);
- struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
-
- if (other && other->clk) /* If this is probe on secondary */
- goto probe_exit;
-
- i2s->addr = ioremap(i2s->base, 0x100);
- if (i2s->addr == NULL) {
- dev_err(&i2s->pdev->dev, "cannot ioremap registers\n");
- return -ENXIO;
- }
-
- i2s->clk = clk_get(&i2s->pdev->dev, "iis");
- if (IS_ERR(i2s->clk)) {
- dev_err(&i2s->pdev->dev, "failed to get i2s_clock\n");
- iounmap(i2s->addr);
- return -ENOENT;
- }
- clk_enable(i2s->clk);
-
- if (other) {
- other->addr = i2s->addr;
- other->clk = i2s->clk;
- }
-
- if (i2s->quirks & QUIRK_NEED_RSTCLR)
- writel(CON_RSTCLR, i2s->addr + I2SCON);
-
- if (i2s->quirks & QUIRK_SEC_DAI)
- idma_reg_addr_init(i2s->addr,
- i2s->sec_dai->idma_playback.dma_addr);
-
-probe_exit:
- /* Reset any constraint on RFS and BFS */
- i2s->rfs = 0;
- i2s->bfs = 0;
- i2s_txctrl(i2s, 0);
- i2s_rxctrl(i2s, 0);
- i2s_fifo(i2s, FIC_TXFLUSH);
- i2s_fifo(other, FIC_TXFLUSH);
- i2s_fifo(i2s, FIC_RXFLUSH);
-
- /* Gate CDCLK by default */
- if (!is_opened(other))
- i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK,
- 0, SND_SOC_CLOCK_IN);
-
- return 0;
-}
-
-static int samsung_i2s_dai_remove(struct snd_soc_dai *dai)
-{
- struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai);
- struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
-
- if (!other || !other->clk) {
-
- if (i2s->quirks & QUIRK_NEED_RSTCLR)
- writel(0, i2s->addr + I2SCON);
-
- clk_disable(i2s->clk);
- clk_put(i2s->clk);
-
- iounmap(i2s->addr);
- }
-
- i2s->clk = NULL;
-
- return 0;
-}
-
-static const struct snd_soc_dai_ops samsung_i2s_dai_ops = {
- .trigger = i2s_trigger,
- .hw_params = i2s_hw_params,
- .set_fmt = i2s_set_fmt,
- .set_clkdiv = i2s_set_clkdiv,
- .set_sysclk = i2s_set_sysclk,
- .startup = i2s_startup,
- .shutdown = i2s_shutdown,
- .delay = i2s_delay,
-};
-
-#define SAMSUNG_I2S_RATES SNDRV_PCM_RATE_8000_96000
-
-#define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \
- SNDRV_PCM_FMTBIT_S16_LE | \
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static __devinit
-struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
-{
- struct i2s_dai *i2s;
-
- i2s = devm_kzalloc(&pdev->dev, sizeof(struct i2s_dai), GFP_KERNEL);
- if (i2s == NULL)
- return NULL;
-
- i2s->pdev = pdev;
- i2s->pri_dai = NULL;
- i2s->sec_dai = NULL;
- i2s->i2s_dai_drv.symmetric_rates = 1;
- i2s->i2s_dai_drv.probe = samsung_i2s_dai_probe;
- i2s->i2s_dai_drv.remove = samsung_i2s_dai_remove;
- i2s->i2s_dai_drv.ops = &samsung_i2s_dai_ops;
- i2s->i2s_dai_drv.suspend = i2s_suspend;
- i2s->i2s_dai_drv.resume = i2s_resume;
- i2s->i2s_dai_drv.playback.channels_min = 2;
- i2s->i2s_dai_drv.playback.channels_max = 2;
- i2s->i2s_dai_drv.playback.rates = SAMSUNG_I2S_RATES;
- i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS;
-
- if (!sec) {
- i2s->i2s_dai_drv.capture.channels_min = 1;
- i2s->i2s_dai_drv.capture.channels_max = 2;
- i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES;
- i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS;
- } else { /* Create a new platform_device for Secondary */
- i2s->pdev = platform_device_register_resndata(NULL,
- pdev->name, pdev->id + SAMSUNG_I2S_SECOFF,
- NULL, 0, NULL, 0);
- if (IS_ERR(i2s->pdev))
- return NULL;
- }
-
- /* Pre-assign snd_soc_dai_set_drvdata */
- dev_set_drvdata(&i2s->pdev->dev, i2s);
-
- return i2s;
-}
-
-static __devinit int samsung_i2s_probe(struct platform_device *pdev)
-{
- u32 dma_pl_chan, dma_cp_chan, dma_pl_sec_chan;
- struct i2s_dai *pri_dai, *sec_dai = NULL;
- struct s3c_audio_pdata *i2s_pdata;
- struct samsung_i2s *i2s_cfg;
- struct resource *res;
- u32 regs_base, quirks;
- int ret = 0;
-
- /* Call during Seconday interface registration */
- if (pdev->id >= SAMSUNG_I2S_SECOFF) {
- sec_dai = dev_get_drvdata(&pdev->dev);
- snd_soc_register_dai(&sec_dai->pdev->dev,
- &sec_dai->i2s_dai_drv);
- return 0;
- }
-
- i2s_pdata = pdev->dev.platform_data;
- if (i2s_pdata == NULL) {
- dev_err(&pdev->dev, "Can't work without s3c_audio_pdata\n");
- return -EINVAL;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!res) {
- dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n");
- return -ENXIO;
- }
- dma_pl_chan = res->start;
-
- res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (!res) {
- dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n");
- return -ENXIO;
- }
- dma_cp_chan = res->start;
-
- res = platform_get_resource(pdev, IORESOURCE_DMA, 2);
- if (res)
- dma_pl_sec_chan = res->start;
- else
- dma_pl_sec_chan = 0;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "Unable to get I2S SFR address\n");
- return -ENXIO;
- }
-
- if (!request_mem_region(res->start, resource_size(res),
- "samsung-i2s")) {
- dev_err(&pdev->dev, "Unable to request SFR region\n");
- return -EBUSY;
- }
- regs_base = res->start;
-
- i2s_cfg = &i2s_pdata->type.i2s;
- quirks = i2s_cfg->quirks;
-
- pri_dai = i2s_alloc_dai(pdev, false);
- if (!pri_dai) {
- dev_err(&pdev->dev, "Unable to alloc I2S_pri\n");
- ret = -ENOMEM;
- goto err;
- }
-
- pri_dai->dma_playback.dma_addr = regs_base + I2STXD;
- pri_dai->dma_capture.dma_addr = regs_base + I2SRXD;
- pri_dai->dma_playback.client =
- (struct s3c2410_dma_client *)&pri_dai->dma_playback;
- pri_dai->dma_capture.client =
- (struct s3c2410_dma_client *)&pri_dai->dma_capture;
- pri_dai->dma_playback.channel = dma_pl_chan;
- pri_dai->dma_capture.channel = dma_cp_chan;
- pri_dai->src_clk = i2s_cfg->src_clk;
- pri_dai->dma_playback.dma_size = 4;
- pri_dai->dma_capture.dma_size = 4;
- pri_dai->base = regs_base;
- pri_dai->quirks = quirks;
-
- if (quirks & QUIRK_PRI_6CHAN)
- pri_dai->i2s_dai_drv.playback.channels_max = 6;
-
- if (quirks & QUIRK_SEC_DAI) {
- sec_dai = i2s_alloc_dai(pdev, true);
- if (!sec_dai) {
- dev_err(&pdev->dev, "Unable to alloc I2S_sec\n");
- ret = -ENOMEM;
- goto err;
- }
- sec_dai->dma_playback.dma_addr = regs_base + I2STXDS;
- sec_dai->dma_playback.client =
- (struct s3c2410_dma_client *)&sec_dai->dma_playback;
- /* Use iDMA always if SysDMA not provided */
- sec_dai->dma_playback.channel = dma_pl_sec_chan ? : -1;
- sec_dai->src_clk = i2s_cfg->src_clk;
- sec_dai->dma_playback.dma_size = 4;
- sec_dai->base = regs_base;
- sec_dai->quirks = quirks;
- sec_dai->idma_playback.dma_addr = i2s_cfg->idma_addr;
- sec_dai->pri_dai = pri_dai;
- pri_dai->sec_dai = sec_dai;
- }
-
- if (i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
- dev_err(&pdev->dev, "Unable to configure gpio\n");
- ret = -EINVAL;
- goto err;
- }
-
- snd_soc_register_dai(&pri_dai->pdev->dev, &pri_dai->i2s_dai_drv);
-
- pm_runtime_enable(&pdev->dev);
-
- return 0;
-err:
- release_mem_region(regs_base, resource_size(res));
-
- return ret;
-}
-
-static __devexit int samsung_i2s_remove(struct platform_device *pdev)
-{
- struct i2s_dai *i2s, *other;
- struct resource *res;
-
- i2s = dev_get_drvdata(&pdev->dev);
- other = i2s->pri_dai ? : i2s->sec_dai;
-
- if (other) {
- other->pri_dai = NULL;
- other->sec_dai = NULL;
- } else {
- pm_runtime_disable(&pdev->dev);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res)
- release_mem_region(res->start, resource_size(res));
- }
-
- i2s->pri_dai = NULL;
- i2s->sec_dai = NULL;
-
- snd_soc_unregister_dai(&pdev->dev);
-
- return 0;
-}
-
-static struct platform_driver samsung_i2s_driver = {
- .probe = samsung_i2s_probe,
- .remove = __devexit_p(samsung_i2s_remove),
- .driver = {
- .name = "samsung-i2s",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(samsung_i2s_driver);
-
-/* Module information */
-MODULE_AUTHOR("Jaswinder Singh, <jassisinghbrar@gmail.com>");
-MODULE_DESCRIPTION("Samsung I2S Interface");
-MODULE_ALIAS("platform:samsung-i2s");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/i2s.h b/ANDROID_3.4.5/sound/soc/samsung/i2s.h
deleted file mode 100644
index d420a7ca..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/i2s.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* sound/soc/samsung/i2s.h
- *
- * ALSA SoC Audio Layer - Samsung I2S Controller driver
- *
- * Copyright (c) 2010 Samsung Electronics Co. Ltd.
- * Jaswinder Singh <jassisinghbrar@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __SND_SOC_SAMSUNG_I2S_H
-#define __SND_SOC_SAMSUNG_I2S_H
-
-/*
- * Maximum number of I2S blocks that any SoC can have.
- * The secondary interface of a CPU dai(if there exists any),
- * is indexed at [cpu-dai's ID + SAMSUNG_I2S_SECOFF]
- */
-#define SAMSUNG_I2S_SECOFF 4
-
-#define SAMSUNG_I2S_DIV_BCLK 1
-
-#define SAMSUNG_I2S_RCLKSRC_0 0
-#define SAMSUNG_I2S_RCLKSRC_1 1
-#define SAMSUNG_I2S_CDCLK 2
-
-#endif /* __SND_SOC_SAMSUNG_I2S_H */
diff --git a/ANDROID_3.4.5/sound/soc/samsung/idma.c b/ANDROID_3.4.5/sound/soc/samsung/idma.c
deleted file mode 100644
index c227c316..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/idma.c
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * sound/soc/samsung/idma.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * I2S0's Internal DMA driver
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include "i2s.h"
-#include "idma.h"
-#include "dma.h"
-#include "i2s-regs.h"
-
-#define ST_RUNNING (1<<0)
-#define ST_OPENED (1<<1)
-
-static const struct snd_pcm_hardware idma_hardware = {
- .info = SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME,
- .formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_U16_LE |
- SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_U24_LE |
- SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S8,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = MAX_IDMA_BUFFER,
- .period_bytes_min = 128,
- .period_bytes_max = MAX_IDMA_PERIOD,
- .periods_min = 1,
- .periods_max = 2,
-};
-
-struct idma_ctrl {
- spinlock_t lock;
- int state;
- dma_addr_t start;
- dma_addr_t pos;
- dma_addr_t end;
- dma_addr_t period;
- dma_addr_t periodsz;
- void *token;
- void (*cb)(void *dt, int bytes_xfer);
-};
-
-static struct idma_info {
- spinlock_t lock;
- void __iomem *regs;
- dma_addr_t lp_tx_addr;
-} idma;
-
-static void idma_getpos(dma_addr_t *src)
-{
- *src = idma.lp_tx_addr +
- (readl(idma.regs + I2STRNCNT) & 0xffffff) * 4;
-}
-
-static int idma_enqueue(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct idma_ctrl *prtd = substream->runtime->private_data;
- u32 val;
-
- spin_lock(&prtd->lock);
- prtd->token = (void *) substream;
- spin_unlock(&prtd->lock);
-
- /* Internal DMA Level0 Interrupt Address */
- val = idma.lp_tx_addr + prtd->periodsz;
- writel(val, idma.regs + I2SLVL0ADDR);
-
- /* Start address0 of I2S internal DMA operation. */
- val = idma.lp_tx_addr;
- writel(val, idma.regs + I2SSTR0);
-
- /*
- * Transfer block size for I2S internal DMA.
- * Should decide transfer size before start dma operation
- */
- val = readl(idma.regs + I2SSIZE);
- val &= ~(I2SSIZE_TRNMSK << I2SSIZE_SHIFT);
- val |= (((runtime->dma_bytes >> 2) &
- I2SSIZE_TRNMSK) << I2SSIZE_SHIFT);
- writel(val, idma.regs + I2SSIZE);
-
- val = readl(idma.regs + I2SAHB);
- val |= AHB_INTENLVL0;
- writel(val, idma.regs + I2SAHB);
-
- return 0;
-}
-
-static void idma_setcallbk(struct snd_pcm_substream *substream,
- void (*cb)(void *, int))
-{
- struct idma_ctrl *prtd = substream->runtime->private_data;
-
- spin_lock(&prtd->lock);
- prtd->cb = cb;
- spin_unlock(&prtd->lock);
-}
-
-static void idma_control(int op)
-{
- u32 val = readl(idma.regs + I2SAHB);
-
- spin_lock(&idma.lock);
-
- switch (op) {
- case LPAM_DMA_START:
- val |= (AHB_INTENLVL0 | AHB_DMAEN);
- break;
- case LPAM_DMA_STOP:
- val &= ~(AHB_INTENLVL0 | AHB_DMAEN);
- break;
- default:
- spin_unlock(&idma.lock);
- return;
- }
-
- writel(val, idma.regs + I2SAHB);
- spin_unlock(&idma.lock);
-}
-
-static void idma_done(void *id, int bytes_xfer)
-{
- struct snd_pcm_substream *substream = id;
- struct idma_ctrl *prtd = substream->runtime->private_data;
-
- if (prtd && (prtd->state & ST_RUNNING))
- snd_pcm_period_elapsed(substream);
-}
-
-static int idma_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct idma_ctrl *prtd = substream->runtime->private_data;
- u32 mod = readl(idma.regs + I2SMOD);
- u32 ahb = readl(idma.regs + I2SAHB);
-
- ahb |= (AHB_DMARLD | AHB_INTMASK);
- mod |= MOD_TXS_IDMA;
- writel(ahb, idma.regs + I2SAHB);
- writel(mod, idma.regs + I2SMOD);
-
- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
- runtime->dma_bytes = params_buffer_bytes(params);
-
- prtd->start = prtd->pos = runtime->dma_addr;
- prtd->period = params_periods(params);
- prtd->periodsz = params_period_bytes(params);
- prtd->end = runtime->dma_addr + runtime->dma_bytes;
-
- idma_setcallbk(substream, idma_done);
-
- return 0;
-}
-
-static int idma_hw_free(struct snd_pcm_substream *substream)
-{
- snd_pcm_set_runtime_buffer(substream, NULL);
-
- return 0;
-}
-
-static int idma_prepare(struct snd_pcm_substream *substream)
-{
- struct idma_ctrl *prtd = substream->runtime->private_data;
-
- prtd->pos = prtd->start;
-
- /* flush the DMA channel */
- idma_control(LPAM_DMA_STOP);
- idma_enqueue(substream);
-
- return 0;
-}
-
-static int idma_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct idma_ctrl *prtd = substream->runtime->private_data;
- int ret = 0;
-
- spin_lock(&prtd->lock);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- prtd->state |= ST_RUNNING;
- idma_control(LPAM_DMA_START);
- break;
-
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- prtd->state &= ~ST_RUNNING;
- idma_control(LPAM_DMA_STOP);
- break;
-
- default:
- ret = -EINVAL;
- break;
- }
-
- spin_unlock(&prtd->lock);
-
- return ret;
-}
-
-static snd_pcm_uframes_t
- idma_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct idma_ctrl *prtd = runtime->private_data;
- dma_addr_t src;
- unsigned long res;
-
- spin_lock(&prtd->lock);
-
- idma_getpos(&src);
- res = src - prtd->start;
-
- spin_unlock(&prtd->lock);
-
- return bytes_to_frames(substream->runtime, res);
-}
-
-static int idma_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long size, offset;
- int ret;
-
- /* From snd_pcm_lib_mmap_iomem */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- vma->vm_flags |= VM_IO;
- size = vma->vm_end - vma->vm_start;
- offset = vma->vm_pgoff << PAGE_SHIFT;
- ret = io_remap_pfn_range(vma, vma->vm_start,
- (runtime->dma_addr + offset) >> PAGE_SHIFT,
- size, vma->vm_page_prot);
-
- return ret;
-}
-
-static irqreturn_t iis_irq(int irqno, void *dev_id)
-{
- struct idma_ctrl *prtd = (struct idma_ctrl *)dev_id;
- u32 iiscon, iisahb, val, addr;
-
- iisahb = readl(idma.regs + I2SAHB);
- iiscon = readl(idma.regs + I2SCON);
-
- val = (iisahb & AHB_LVL0INT) ? AHB_CLRLVL0INT : 0;
-
- if (val) {
- iisahb |= val;
- writel(iisahb, idma.regs + I2SAHB);
-
- addr = readl(idma.regs + I2SLVL0ADDR) - idma.lp_tx_addr;
- addr += prtd->periodsz;
- addr %= (prtd->end - prtd->start);
- addr += idma.lp_tx_addr;
-
- writel(addr, idma.regs + I2SLVL0ADDR);
-
- if (prtd->cb)
- prtd->cb(prtd->token, prtd->period);
- }
-
- return IRQ_HANDLED;
-}
-
-static int idma_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct idma_ctrl *prtd;
- int ret;
-
- snd_soc_set_runtime_hwparams(substream, &idma_hardware);
-
- prtd = kzalloc(sizeof(struct idma_ctrl), GFP_KERNEL);
- if (prtd == NULL)
- return -ENOMEM;
-
- ret = request_irq(IRQ_I2S0, iis_irq, 0, "i2s", prtd);
- if (ret < 0) {
- pr_err("fail to claim i2s irq , ret = %d\n", ret);
- kfree(prtd);
- return ret;
- }
-
- spin_lock_init(&prtd->lock);
-
- runtime->private_data = prtd;
-
- return 0;
-}
-
-static int idma_close(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct idma_ctrl *prtd = runtime->private_data;
-
- free_irq(IRQ_I2S0, prtd);
-
- if (!prtd)
- pr_err("idma_close called with prtd == NULL\n");
-
- kfree(prtd);
-
- return 0;
-}
-
-static struct snd_pcm_ops idma_ops = {
- .open = idma_open,
- .close = idma_close,
- .ioctl = snd_pcm_lib_ioctl,
- .trigger = idma_trigger,
- .pointer = idma_pointer,
- .mmap = idma_mmap,
- .hw_params = idma_hw_params,
- .hw_free = idma_hw_free,
- .prepare = idma_prepare,
-};
-
-static void idma_free(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- struct snd_dma_buffer *buf;
-
- substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
- if (!substream)
- return;
-
- buf = &substream->dma_buffer;
- if (!buf->area)
- return;
-
- iounmap(buf->area);
-
- buf->area = NULL;
- buf->addr = 0;
-}
-
-static int preallocate_idma_buffer(struct snd_pcm *pcm, int stream)
-{
- struct snd_pcm_substream *substream = pcm->streams[stream].substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
-
- buf->dev.dev = pcm->card->dev;
- buf->private_data = NULL;
-
- /* Assign PCM buffer pointers */
- buf->dev.type = SNDRV_DMA_TYPE_CONTINUOUS;
- buf->addr = idma.lp_tx_addr;
- buf->bytes = idma_hardware.buffer_bytes_max;
- buf->area = (unsigned char *)ioremap(buf->addr, buf->bytes);
-
- return 0;
-}
-
-static u64 idma_mask = DMA_BIT_MASK(32);
-
-static int idma_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- int ret = 0;
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &idma_mask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = preallocate_idma_buffer(pcm,
- SNDRV_PCM_STREAM_PLAYBACK);
- }
-
- return ret;
-}
-
-void idma_reg_addr_init(void __iomem *regs, dma_addr_t addr)
-{
- spin_lock_init(&idma.lock);
- idma.regs = regs;
- idma.lp_tx_addr = addr;
-}
-
-static struct snd_soc_platform_driver asoc_idma_platform = {
- .ops = &idma_ops,
- .pcm_new = idma_new,
- .pcm_free = idma_free,
-};
-
-static int __devinit asoc_idma_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_platform(&pdev->dev, &asoc_idma_platform);
-}
-
-static int __devexit asoc_idma_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver asoc_idma_driver = {
- .driver = {
- .name = "samsung-idma",
- .owner = THIS_MODULE,
- },
-
- .probe = asoc_idma_platform_probe,
- .remove = __devexit_p(asoc_idma_platform_remove),
-};
-
-module_platform_driver(asoc_idma_driver);
-
-MODULE_AUTHOR("Jaswinder Singh, <jassisinghbrar@gmail.com>");
-MODULE_DESCRIPTION("Samsung ASoC IDMA Driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/idma.h b/ANDROID_3.4.5/sound/soc/samsung/idma.h
deleted file mode 100644
index 86449469..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/idma.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * sound/soc/samsung/idma.h
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#ifndef __SND_SOC_SAMSUNG_IDMA_H_
-#define __SND_SOC_SAMSUNG_IDMA_H_
-
-extern void idma_reg_addr_init(void __iomem *regs, dma_addr_t addr);
-
-/* dma_state */
-#define LPAM_DMA_STOP 0
-#define LPAM_DMA_START 1
-
-#define MAX_IDMA_PERIOD (128 * 1024)
-#define MAX_IDMA_BUFFER (160 * 1024)
-
-#endif /* __SND_SOC_SAMSUNG_IDMA_H_ */
diff --git a/ANDROID_3.4.5/sound/soc/samsung/jive_wm8750.c b/ANDROID_3.4.5/sound/soc/samsung/jive_wm8750.c
deleted file mode 100644
index 1578663a..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/jive_wm8750.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/* sound/soc/samsung/jive_wm8750.c
- *
- * Copyright 2007,2008 Simtec Electronics
- *
- * Based on sound/soc/pxa/spitz.c
- * Copyright 2005 Wolfson Microelectronics PLC.
- * Copyright 2005 Openedhand Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/module.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-
-#include "s3c2412-i2s.h"
-#include "../codecs/wm8750.h"
-
-static const struct snd_soc_dapm_route audio_map[] = {
- { "Headphone Jack", NULL, "LOUT1" },
- { "Headphone Jack", NULL, "ROUT1" },
- { "Internal Speaker", NULL, "LOUT2" },
- { "Internal Speaker", NULL, "ROUT2" },
- { "LINPUT1", NULL, "Line Input" },
- { "RINPUT1", NULL, "Line Input" },
-};
-
-static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_SPK("Internal Speaker", NULL),
- SND_SOC_DAPM_LINE("Line In", NULL),
-};
-
-static int jive_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct s3c_i2sv2_rate_calc div;
- unsigned int clk = 0;
- int ret = 0;
-
- switch (params_rate(params)) {
- case 8000:
- case 16000:
- case 48000:
- case 96000:
- clk = 12288000;
- break;
- case 11025:
- case 22050:
- case 44100:
- clk = 11289600;
- break;
- }
-
- s3c_i2sv2_iis_calc_rate(&div, NULL, params_rate(params),
- s3c_i2sv2_get_clock(cpu_dai));
-
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk,
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C2412_DIV_RCLK, div.fs_div);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C2412_DIV_PRESCALER,
- div.clk_div - 1);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops jive_ops = {
- .hw_params = jive_hw_params,
-};
-
-static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- /* These endpoints are not being used. */
- snd_soc_dapm_nc_pin(dapm, "LINPUT2");
- snd_soc_dapm_nc_pin(dapm, "RINPUT2");
- snd_soc_dapm_nc_pin(dapm, "LINPUT3");
- snd_soc_dapm_nc_pin(dapm, "RINPUT3");
- snd_soc_dapm_nc_pin(dapm, "OUT3");
- snd_soc_dapm_nc_pin(dapm, "MONO");
-
- return 0;
-}
-
-static struct snd_soc_dai_link jive_dai = {
- .name = "wm8750",
- .stream_name = "WM8750",
- .cpu_dai_name = "s3c2412-i2s",
- .codec_dai_name = "wm8750-hifi",
- .platform_name = "samsung-audio",
- .codec_name = "wm8750.0-001a",
- .init = jive_wm8750_init,
- .ops = &jive_ops,
-};
-
-/* jive audio machine driver */
-static struct snd_soc_card snd_soc_machine_jive = {
- .name = "Jive",
- .owner = THIS_MODULE,
- .dai_link = &jive_dai,
- .num_links = 1,
-
- .dapm_widgets = wm8750_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets),
- .dapm_routes = audio_map,
- .num_dapm_routes = ARRAY_SIZE(audio_map),
-};
-
-static struct platform_device *jive_snd_device;
-
-static int __init jive_init(void)
-{
- int ret;
-
- if (!machine_is_jive())
- return 0;
-
- printk("JIVE WM8750 Audio support\n");
-
- jive_snd_device = platform_device_alloc("soc-audio", -1);
- if (!jive_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(jive_snd_device, &snd_soc_machine_jive);
- ret = platform_device_add(jive_snd_device);
-
- if (ret)
- platform_device_put(jive_snd_device);
-
- return ret;
-}
-
-static void __exit jive_exit(void)
-{
- platform_device_unregister(jive_snd_device);
-}
-
-module_init(jive_init);
-module_exit(jive_exit);
-
-MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
-MODULE_DESCRIPTION("ALSA SoC Jive Audio support");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/littlemill.c b/ANDROID_3.4.5/sound/soc/samsung/littlemill.c
deleted file mode 100644
index e7416851..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/littlemill.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Littlemill audio support
- *
- * Copyright 2011 Wolfson Microelectronics
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/jack.h>
-#include <linux/gpio.h>
-#include <linux/module.h>
-
-#include "../codecs/wm8994.h"
-
-static int sample_rate = 44100;
-
-static int littlemill_set_bias_level(struct snd_soc_card *card,
- struct snd_soc_dapm_context *dapm,
- enum snd_soc_bias_level level)
-{
- struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
- int ret;
-
- if (dapm->dev != codec_dai->dev)
- return 0;
-
- switch (level) {
- case SND_SOC_BIAS_PREPARE:
- /*
- * If we've not already clocked things via hw_params()
- * then do so now, otherwise these are noops.
- */
- if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
- ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1,
- WM8994_FLL_SRC_MCLK2, 32768,
- sample_rate * 512);
- if (ret < 0) {
- pr_err("Failed to start FLL: %d\n", ret);
- return ret;
- }
-
- ret = snd_soc_dai_set_sysclk(codec_dai,
- WM8994_SYSCLK_FLL1,
- sample_rate * 512,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- pr_err("Failed to set SYSCLK: %d\n", ret);
- return ret;
- }
- }
- break;
-
- default:
- break;
- }
-
- return 0;
-}
-
-static int littlemill_set_bias_level_post(struct snd_soc_card *card,
- struct snd_soc_dapm_context *dapm,
- enum snd_soc_bias_level level)
-{
- struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
- int ret;
-
- if (dapm->dev != codec_dai->dev)
- return 0;
-
- switch (level) {
- case SND_SOC_BIAS_STANDBY:
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK2,
- 32768, SND_SOC_CLOCK_IN);
- if (ret < 0) {
- pr_err("Failed to switch away from FLL: %d\n", ret);
- return ret;
- }
-
- ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1,
- 0, 0, 0);
- if (ret < 0) {
- pr_err("Failed to stop FLL: %d\n", ret);
- return ret;
- }
- break;
-
- default:
- break;
- }
-
- dapm->bias_level = level;
-
- return 0;
-}
-
-static int littlemill_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int ret;
-
- sample_rate = params_rate(params);
-
- ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1,
- WM8994_FLL_SRC_MCLK2, 32768,
- sample_rate * 512);
- if (ret < 0) {
- pr_err("Failed to start FLL: %d\n", ret);
- return ret;
- }
-
- ret = snd_soc_dai_set_sysclk(codec_dai,
- WM8994_SYSCLK_FLL1,
- sample_rate * 512,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- pr_err("Failed to set SYSCLK: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_soc_ops littlemill_ops = {
- .hw_params = littlemill_hw_params,
-};
-
-static struct snd_soc_dai_link littlemill_dai[] = {
- {
- .name = "CPU",
- .stream_name = "CPU",
- .cpu_dai_name = "samsung-i2s.0",
- .codec_dai_name = "wm8994-aif1",
- .platform_name = "samsung-audio",
- .codec_name = "wm8994-codec",
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
- | SND_SOC_DAIFMT_CBM_CFM,
- .ops = &littlemill_ops,
- },
-};
-
-static struct snd_soc_dapm_widget widgets[] = {
- SND_SOC_DAPM_HP("Headphone", NULL),
-
- SND_SOC_DAPM_MIC("AMIC", NULL),
- SND_SOC_DAPM_MIC("DMIC", NULL),
-};
-
-static struct snd_soc_dapm_route audio_paths[] = {
- { "Headphone", NULL, "HPOUT1L" },
- { "Headphone", NULL, "HPOUT1R" },
-
- { "AMIC", NULL, "MICBIAS1" }, /* Default for AMICBIAS jumper */
- { "IN1LN", NULL, "AMIC" },
-
- { "DMIC", NULL, "MICBIAS2" }, /* Default for DMICBIAS jumper */
- { "DMIC1DAT", NULL, "DMIC" },
- { "DMIC2DAT", NULL, "DMIC" },
-};
-
-static struct snd_soc_jack littlemill_headset;
-
-static int littlemill_late_probe(struct snd_soc_card *card)
-{
- struct snd_soc_codec *codec = card->rtd[0].codec;
- struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
- int ret;
-
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK2,
- 32768, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_jack_new(codec, "Headset",
- SND_JACK_HEADSET | SND_JACK_MECHANICAL |
- SND_JACK_BTN_0 | SND_JACK_BTN_1 |
- SND_JACK_BTN_2 | SND_JACK_BTN_3 |
- SND_JACK_BTN_4 | SND_JACK_BTN_5,
- &littlemill_headset);
- if (ret)
- return ret;
-
- /* This will check device compatibility itself */
- wm8958_mic_detect(codec, &littlemill_headset, NULL, NULL);
-
- /* As will this */
- wm8994_mic_detect(codec, &littlemill_headset, 1);
-
- return 0;
-}
-
-static struct snd_soc_card littlemill = {
- .name = "Littlemill",
- .owner = THIS_MODULE,
- .dai_link = littlemill_dai,
- .num_links = ARRAY_SIZE(littlemill_dai),
-
- .set_bias_level = littlemill_set_bias_level,
- .set_bias_level_post = littlemill_set_bias_level_post,
-
- .dapm_widgets = widgets,
- .num_dapm_widgets = ARRAY_SIZE(widgets),
- .dapm_routes = audio_paths,
- .num_dapm_routes = ARRAY_SIZE(audio_paths),
-
- .late_probe = littlemill_late_probe,
-};
-
-static __devinit int littlemill_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &littlemill;
- int ret;
-
- card->dev = &pdev->dev;
-
- ret = snd_soc_register_card(card);
- if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
- ret);
- return ret;
- }
-
- return 0;
-}
-
-static int __devexit littlemill_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- snd_soc_unregister_card(card);
-
- return 0;
-}
-
-static struct platform_driver littlemill_driver = {
- .driver = {
- .name = "littlemill",
- .owner = THIS_MODULE,
- .pm = &snd_soc_pm_ops,
- },
- .probe = littlemill_probe,
- .remove = __devexit_p(littlemill_remove),
-};
-
-module_platform_driver(littlemill_driver);
-
-MODULE_DESCRIPTION("Littlemill audio support");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:littlemill");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/ln2440sbc_alc650.c b/ANDROID_3.4.5/sound/soc/samsung/ln2440sbc_alc650.c
deleted file mode 100644
index 69c4a593..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/ln2440sbc_alc650.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * SoC audio for ln2440sbc
- *
- * Copyright 2007 KonekTel, a.s.
- * Author: Ivan Kuten
- * ivan.kuten@promwad.com
- *
- * Heavily based on smdk2443_wm9710.c
- * Copyright 2007 Wolfson Microelectronics PLC.
- * Author: Graeme Gregory
- * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/module.h>
-#include <sound/soc.h>
-
-static struct snd_soc_card ln2440sbc;
-
-static struct snd_soc_dai_link ln2440sbc_dai[] = {
-{
- .name = "AC97",
- .stream_name = "AC97 HiFi",
- .cpu_dai_name = "samsung-ac97",
- .codec_dai_name = "ac97-hifi",
- .codec_name = "ac97-codec",
- .platform_name = "samsung-audio",
-},
-};
-
-static struct snd_soc_card ln2440sbc = {
- .name = "LN2440SBC",
- .owner = THIS_MODULE,
- .dai_link = ln2440sbc_dai,
- .num_links = ARRAY_SIZE(ln2440sbc_dai),
-};
-
-static struct platform_device *ln2440sbc_snd_ac97_device;
-
-static int __init ln2440sbc_init(void)
-{
- int ret;
-
- ln2440sbc_snd_ac97_device = platform_device_alloc("soc-audio", -1);
- if (!ln2440sbc_snd_ac97_device)
- return -ENOMEM;
-
- platform_set_drvdata(ln2440sbc_snd_ac97_device, &ln2440sbc);
- ret = platform_device_add(ln2440sbc_snd_ac97_device);
-
- if (ret)
- platform_device_put(ln2440sbc_snd_ac97_device);
-
- return ret;
-}
-
-static void __exit ln2440sbc_exit(void)
-{
- platform_device_unregister(ln2440sbc_snd_ac97_device);
-}
-
-module_init(ln2440sbc_init);
-module_exit(ln2440sbc_exit);
-
-/* Module information */
-MODULE_AUTHOR("Ivan Kuten");
-MODULE_DESCRIPTION("ALSA SoC ALC650 LN2440SBC");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/lowland.c b/ANDROID_3.4.5/sound/soc/samsung/lowland.c
deleted file mode 100644
index 4adff934..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/lowland.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Lowland audio support
- *
- * Copyright 2011 Wolfson Microelectronics
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/jack.h>
-#include <linux/gpio.h>
-#include <linux/module.h>
-
-#include "../codecs/wm5100.h"
-#include "../codecs/wm9081.h"
-
-#define MCLK1_RATE (44100 * 512)
-#define CLKOUT_RATE (44100 * 256)
-
-static int lowland_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int ret;
-
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
- | SND_SOC_DAIFMT_NB_NF
- | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
- | SND_SOC_DAIFMT_NB_NF
- | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops lowland_ops = {
- .hw_params = lowland_hw_params,
-};
-
-static struct snd_soc_jack lowland_headset;
-
-/* Headset jack detection DAPM pins */
-static struct snd_soc_jack_pin lowland_headset_pins[] = {
- {
- .pin = "Headphone",
- .mask = SND_JACK_HEADPHONE | SND_JACK_LINEOUT,
- },
- {
- .pin = "Headset Mic",
- .mask = SND_JACK_MICROPHONE,
- },
-};
-
-static int lowland_wm5100_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- int ret;
-
- ret = snd_soc_codec_set_sysclk(codec, WM5100_CLK_SYSCLK,
- WM5100_CLKSRC_MCLK1, MCLK1_RATE,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- pr_err("Failed to set SYSCLK clock source: %d\n", ret);
- return ret;
- }
-
- /* Clock OPCLK, used by the other audio components. */
- ret = snd_soc_codec_set_sysclk(codec, WM5100_CLK_OPCLK, 0,
- CLKOUT_RATE, 0);
- if (ret < 0) {
- pr_err("Failed to set OPCLK rate: %d\n", ret);
- return ret;
- }
-
- ret = snd_soc_jack_new(codec, "Headset",
- SND_JACK_LINEOUT | SND_JACK_HEADSET |
- SND_JACK_BTN_0,
- &lowland_headset);
- if (ret)
- return ret;
-
- ret = snd_soc_jack_add_pins(&lowland_headset,
- ARRAY_SIZE(lowland_headset_pins),
- lowland_headset_pins);
- if (ret)
- return ret;
-
- wm5100_detect(codec, &lowland_headset);
-
- return 0;
-}
-
-static struct snd_soc_dai_link lowland_dai[] = {
- {
- .name = "CPU",
- .stream_name = "CPU",
- .cpu_dai_name = "samsung-i2s.0",
- .codec_dai_name = "wm5100-aif1",
- .platform_name = "samsung-audio",
- .codec_name = "wm5100.1-001a",
- .ops = &lowland_ops,
- .init = lowland_wm5100_init,
- },
- {
- .name = "Baseband",
- .stream_name = "Baseband",
- .cpu_dai_name = "wm5100-aif2",
- .codec_dai_name = "wm1250-ev1",
- .codec_name = "wm1250-ev1.1-0027",
- .ops = &lowland_ops,
- .ignore_suspend = 1,
- },
-};
-
-static int lowland_wm9081_init(struct snd_soc_dapm_context *dapm)
-{
- snd_soc_dapm_nc_pin(dapm, "LINEOUT");
-
- /* At any time the WM9081 is active it will have this clock */
- return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, 0,
- CLKOUT_RATE, 0);
-}
-
-static struct snd_soc_aux_dev lowland_aux_dev[] = {
- {
- .name = "wm9081",
- .codec_name = "wm9081.1-006c",
- .init = lowland_wm9081_init,
- },
-};
-
-static struct snd_soc_codec_conf lowland_codec_conf[] = {
- {
- .dev_name = "wm9081.1-006c",
- .name_prefix = "Sub",
- },
-};
-
-static const struct snd_kcontrol_new controls[] = {
- SOC_DAPM_PIN_SWITCH("Main Speaker"),
- SOC_DAPM_PIN_SWITCH("Main DMIC"),
- SOC_DAPM_PIN_SWITCH("Main AMIC"),
- SOC_DAPM_PIN_SWITCH("WM1250 Input"),
- SOC_DAPM_PIN_SWITCH("WM1250 Output"),
- SOC_DAPM_PIN_SWITCH("Headphone"),
-};
-
-static struct snd_soc_dapm_widget widgets[] = {
- SND_SOC_DAPM_HP("Headphone", NULL),
- SND_SOC_DAPM_MIC("Headset Mic", NULL),
-
- SND_SOC_DAPM_SPK("Main Speaker", NULL),
-
- SND_SOC_DAPM_MIC("Main AMIC", NULL),
- SND_SOC_DAPM_MIC("Main DMIC", NULL),
-};
-
-static struct snd_soc_dapm_route audio_paths[] = {
- { "Sub IN1", NULL, "HPOUT2L" },
- { "Sub IN2", NULL, "HPOUT2R" },
-
- { "Main Speaker", NULL, "Sub SPKN" },
- { "Main Speaker", NULL, "Sub SPKP" },
- { "Main Speaker", NULL, "SPKDAT1" },
-};
-
-static struct snd_soc_card lowland = {
- .name = "Lowland",
- .owner = THIS_MODULE,
- .dai_link = lowland_dai,
- .num_links = ARRAY_SIZE(lowland_dai),
- .aux_dev = lowland_aux_dev,
- .num_aux_devs = ARRAY_SIZE(lowland_aux_dev),
- .codec_conf = lowland_codec_conf,
- .num_configs = ARRAY_SIZE(lowland_codec_conf),
-
- .controls = controls,
- .num_controls = ARRAY_SIZE(controls),
- .dapm_widgets = widgets,
- .num_dapm_widgets = ARRAY_SIZE(widgets),
- .dapm_routes = audio_paths,
- .num_dapm_routes = ARRAY_SIZE(audio_paths),
-};
-
-static __devinit int lowland_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &lowland;
- int ret;
-
- card->dev = &pdev->dev;
-
- ret = snd_soc_register_card(card);
- if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
- ret);
- return ret;
- }
-
- return 0;
-}
-
-static int __devexit lowland_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- snd_soc_unregister_card(card);
-
- return 0;
-}
-
-static struct platform_driver lowland_driver = {
- .driver = {
- .name = "lowland",
- .owner = THIS_MODULE,
- .pm = &snd_soc_pm_ops,
- },
- .probe = lowland_probe,
- .remove = __devexit_p(lowland_remove),
-};
-
-module_platform_driver(lowland_driver);
-
-MODULE_DESCRIPTION("Lowland audio support");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:lowland");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/neo1973_wm8753.c b/ANDROID_3.4.5/sound/soc/samsung/neo1973_wm8753.c
deleted file mode 100644
index 321d5113..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/neo1973_wm8753.c
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- * neo1973_wm8753.c -- SoC audio for Openmoko Neo1973 and Freerunner devices
- *
- * Copyright 2007 Openmoko Inc
- * Author: Graeme Gregory <graeme@openmoko.org>
- * Copyright 2007 Wolfson Microelectronics PLC.
- * Author: Graeme Gregory
- * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
- * Copyright 2009 Wolfson Microelectronics
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <plat/regs-iis.h>
-#include <mach/gta02.h>
-
-#include "../codecs/wm8753.h"
-#include "s3c24xx-i2s.h"
-
-static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- unsigned int pll_out = 0, bclk = 0;
- int ret = 0;
- unsigned long iis_clkrate;
-
- iis_clkrate = s3c24xx_i2s_get_clockrate();
-
- switch (params_rate(params)) {
- case 8000:
- case 16000:
- pll_out = 12288000;
- break;
- case 48000:
- bclk = WM8753_BCLK_DIV_4;
- pll_out = 12288000;
- break;
- case 96000:
- bclk = WM8753_BCLK_DIV_2;
- pll_out = 12288000;
- break;
- case 11025:
- bclk = WM8753_BCLK_DIV_16;
- pll_out = 11289600;
- break;
- case 22050:
- bclk = WM8753_BCLK_DIV_8;
- pll_out = 11289600;
- break;
- case 44100:
- bclk = WM8753_BCLK_DIV_4;
- pll_out = 11289600;
- break;
- case 88200:
- bclk = WM8753_BCLK_DIV_2;
- pll_out = 11289600;
- break;
- }
-
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai,
- SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- /* set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai,
- SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- /* set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out,
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- /* set MCLK division for sample rate */
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
- S3C2410_IISMOD_32FS);
- if (ret < 0)
- return ret;
-
- /* set codec BCLK division for sample rate */
- ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_BCLKDIV, bclk);
- if (ret < 0)
- return ret;
-
- /* set prescaler division for sample rate */
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
- S3C24XX_PRESCALE(4, 4));
- if (ret < 0)
- return ret;
-
- /* codec PLL input is PCLK/4 */
- ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0,
- iis_clkrate / 4, pll_out);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
-
- /* disable the PLL */
- return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0);
-}
-
-/*
- * Neo1973 WM8753 HiFi DAI opserations.
- */
-static struct snd_soc_ops neo1973_hifi_ops = {
- .hw_params = neo1973_hifi_hw_params,
- .hw_free = neo1973_hifi_hw_free,
-};
-
-static int neo1973_voice_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- unsigned int pcmdiv = 0;
- int ret = 0;
- unsigned long iis_clkrate;
-
- iis_clkrate = s3c24xx_i2s_get_clockrate();
-
- if (params_rate(params) != 8000)
- return -EINVAL;
- if (params_channels(params) != 1)
- return -EINVAL;
-
- pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */
-
- /* todo: gg check mode (DSP_B) against CSR datasheet */
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK, 12288000,
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- /* set codec PCM division for sample rate */
- ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_PCMDIV, pcmdiv);
- if (ret < 0)
- return ret;
-
- /* configure and enable PLL for 12.288MHz output */
- ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0,
- iis_clkrate / 4, 12288000);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int neo1973_voice_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
-
- /* disable the PLL */
- return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0);
-}
-
-static struct snd_soc_ops neo1973_voice_ops = {
- .hw_params = neo1973_voice_hw_params,
- .hw_free = neo1973_voice_hw_free,
-};
-
-/* Shared routes and controls */
-
-static const struct snd_soc_dapm_widget neo1973_wm8753_dapm_widgets[] = {
- SND_SOC_DAPM_LINE("GSM Line Out", NULL),
- SND_SOC_DAPM_LINE("GSM Line In", NULL),
- SND_SOC_DAPM_MIC("Headset Mic", NULL),
- SND_SOC_DAPM_MIC("Handset Mic", NULL),
-};
-
-static const struct snd_soc_dapm_route neo1973_wm8753_routes[] = {
- /* Connections to the GSM Module */
- {"GSM Line Out", NULL, "MONO1"},
- {"GSM Line Out", NULL, "MONO2"},
- {"RXP", NULL, "GSM Line In"},
- {"RXN", NULL, "GSM Line In"},
-
- /* Connections to Headset */
- {"MIC1", NULL, "Mic Bias"},
- {"Mic Bias", NULL, "Headset Mic"},
-
- /* Call Mic */
- {"MIC2", NULL, "Mic Bias"},
- {"MIC2N", NULL, "Mic Bias"},
- {"Mic Bias", NULL, "Handset Mic"},
-
- /* Connect the ALC pins */
- {"ACIN", NULL, "ACOP"},
-};
-
-static const struct snd_kcontrol_new neo1973_wm8753_controls[] = {
- SOC_DAPM_PIN_SWITCH("GSM Line Out"),
- SOC_DAPM_PIN_SWITCH("GSM Line In"),
- SOC_DAPM_PIN_SWITCH("Headset Mic"),
- SOC_DAPM_PIN_SWITCH("Handset Mic"),
-};
-
-/* GTA02 specific routes and controls */
-
-static int gta02_speaker_enabled;
-
-static int lm4853_set_spk(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- gta02_speaker_enabled = ucontrol->value.integer.value[0];
-
- gpio_set_value(GTA02_GPIO_HP_IN, !gta02_speaker_enabled);
-
- return 0;
-}
-
-static int lm4853_get_spk(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = gta02_speaker_enabled;
- return 0;
-}
-
-static int lm4853_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- gpio_set_value(GTA02_GPIO_AMP_SHUT, SND_SOC_DAPM_EVENT_OFF(event));
-
- return 0;
-}
-
-static const struct snd_soc_dapm_route neo1973_gta02_routes[] = {
- /* Connections to the amp */
- {"Stereo Out", NULL, "LOUT1"},
- {"Stereo Out", NULL, "ROUT1"},
-
- /* Call Speaker */
- {"Handset Spk", NULL, "LOUT2"},
- {"Handset Spk", NULL, "ROUT2"},
-};
-
-static const struct snd_kcontrol_new neo1973_gta02_wm8753_controls[] = {
- SOC_DAPM_PIN_SWITCH("Handset Spk"),
- SOC_DAPM_PIN_SWITCH("Stereo Out"),
-
- SOC_SINGLE_BOOL_EXT("Amp Spk Switch", 0,
- lm4853_get_spk,
- lm4853_set_spk),
-};
-
-static const struct snd_soc_dapm_widget neo1973_gta02_wm8753_dapm_widgets[] = {
- SND_SOC_DAPM_SPK("Handset Spk", NULL),
- SND_SOC_DAPM_SPK("Stereo Out", lm4853_event),
-};
-
-static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret;
-
- ret = snd_soc_dapm_new_controls(dapm, neo1973_gta02_wm8753_dapm_widgets,
- ARRAY_SIZE(neo1973_gta02_wm8753_dapm_widgets));
- if (ret)
- return ret;
-
- ret = snd_soc_dapm_add_routes(dapm, neo1973_gta02_routes,
- ARRAY_SIZE(neo1973_gta02_routes));
- if (ret)
- return ret;
-
- ret = snd_soc_add_card_controls(codec->card, neo1973_gta02_wm8753_controls,
- ARRAY_SIZE(neo1973_gta02_wm8753_controls));
- if (ret)
- return ret;
-
- snd_soc_dapm_disable_pin(dapm, "Stereo Out");
- snd_soc_dapm_disable_pin(dapm, "Handset Spk");
- snd_soc_dapm_ignore_suspend(dapm, "Stereo Out");
- snd_soc_dapm_ignore_suspend(dapm, "Handset Spk");
-
- return 0;
-}
-
-static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int ret;
-
- /* set up NC codec pins */
- snd_soc_dapm_nc_pin(dapm, "OUT3");
- snd_soc_dapm_nc_pin(dapm, "OUT4");
- snd_soc_dapm_nc_pin(dapm, "LINE1");
- snd_soc_dapm_nc_pin(dapm, "LINE2");
-
- /* Add neo1973 specific widgets */
- ret = snd_soc_dapm_new_controls(dapm, neo1973_wm8753_dapm_widgets,
- ARRAY_SIZE(neo1973_wm8753_dapm_widgets));
- if (ret)
- return ret;
-
- /* add neo1973 specific controls */
- ret = snd_soc_add_card_controls(rtd->card, neo1973_wm8753_controls,
- ARRAY_SIZE(neo1973_wm8753_controls));
- if (ret)
- return ret;
-
- /* set up neo1973 specific audio routes */
- ret = snd_soc_dapm_add_routes(dapm, neo1973_wm8753_routes,
- ARRAY_SIZE(neo1973_wm8753_routes));
- if (ret)
- return ret;
-
- /* set endpoints to default off mode */
- snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
- snd_soc_dapm_disable_pin(dapm, "GSM Line In");
- snd_soc_dapm_disable_pin(dapm, "Headset Mic");
- snd_soc_dapm_disable_pin(dapm, "Handset Mic");
-
- /* allow audio paths from the GSM modem to run during suspend */
- snd_soc_dapm_ignore_suspend(dapm, "GSM Line Out");
- snd_soc_dapm_ignore_suspend(dapm, "GSM Line In");
- snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
- snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
-
- if (machine_is_neo1973_gta02()) {
- ret = neo1973_gta02_wm8753_init(codec);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_soc_dai_link neo1973_dai[] = {
-{ /* Hifi Playback - for similatious use with voice below */
- .name = "WM8753",
- .stream_name = "WM8753 HiFi",
- .platform_name = "samsung-audio",
- .cpu_dai_name = "s3c24xx-iis",
- .codec_dai_name = "wm8753-hifi",
- .codec_name = "wm8753.0-001a",
- .init = neo1973_wm8753_init,
- .ops = &neo1973_hifi_ops,
-},
-{ /* Voice via BT */
- .name = "Bluetooth",
- .stream_name = "Voice",
- .cpu_dai_name = "dfbmcs320-pcm",
- .codec_dai_name = "wm8753-voice",
- .codec_name = "wm8753.0-001a",
- .ops = &neo1973_voice_ops,
-},
-};
-
-static struct snd_soc_aux_dev neo1973_aux_devs[] = {
- {
- .name = "dfbmcs320",
- .codec_name = "dfbmcs320.0",
- },
-};
-
-static struct snd_soc_codec_conf neo1973_codec_conf[] = {
- {
- .dev_name = "lm4857.0-007c",
- .name_prefix = "Amp",
- },
-};
-
-static const struct gpio neo1973_gta02_gpios[] = {
- { GTA02_GPIO_HP_IN, GPIOF_OUT_INIT_HIGH, "GTA02_HP_IN" },
- { GTA02_GPIO_AMP_SHUT, GPIOF_OUT_INIT_HIGH, "GTA02_AMP_SHUT" },
-};
-
-static struct snd_soc_card neo1973 = {
- .name = "neo1973",
- .owner = THIS_MODULE,
- .dai_link = neo1973_dai,
- .num_links = ARRAY_SIZE(neo1973_dai),
- .aux_dev = neo1973_aux_devs,
- .num_aux_devs = ARRAY_SIZE(neo1973_aux_devs),
- .codec_conf = neo1973_codec_conf,
- .num_configs = ARRAY_SIZE(neo1973_codec_conf),
-};
-
-static struct platform_device *neo1973_snd_device;
-
-static int __init neo1973_init(void)
-{
- int ret;
-
- if (!machine_is_neo1973_gta02())
- return -ENODEV;
-
- if (machine_is_neo1973_gta02()) {
- neo1973.name = "neo1973gta02";
- neo1973.num_aux_devs = 1;
-
- ret = gpio_request_array(neo1973_gta02_gpios,
- ARRAY_SIZE(neo1973_gta02_gpios));
- if (ret)
- return ret;
- }
-
- neo1973_snd_device = platform_device_alloc("soc-audio", -1);
- if (!neo1973_snd_device) {
- ret = -ENOMEM;
- goto err_gpio_free;
- }
-
- platform_set_drvdata(neo1973_snd_device, &neo1973);
- ret = platform_device_add(neo1973_snd_device);
-
- if (ret)
- goto err_put_device;
-
- return 0;
-
-err_put_device:
- platform_device_put(neo1973_snd_device);
-err_gpio_free:
- if (machine_is_neo1973_gta02()) {
- gpio_free_array(neo1973_gta02_gpios,
- ARRAY_SIZE(neo1973_gta02_gpios));
- }
- return ret;
-}
-module_init(neo1973_init);
-
-static void __exit neo1973_exit(void)
-{
- platform_device_unregister(neo1973_snd_device);
-
- if (machine_is_neo1973_gta02()) {
- gpio_free_array(neo1973_gta02_gpios,
- ARRAY_SIZE(neo1973_gta02_gpios));
- }
-}
-module_exit(neo1973_exit);
-
-/* Module information */
-MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org, www.openmoko.org");
-MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973 and Frerunner");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/pcm.c b/ANDROID_3.4.5/sound/soc/samsung/pcm.c
deleted file mode 100644
index b7b2a1f9..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/pcm.c
+++ /dev/null
@@ -1,645 +0,0 @@
-/* sound/soc/samsung/pcm.c
- *
- * ALSA SoC Audio Layer - S3C PCM-Controller driver
- *
- * Copyright (c) 2009 Samsung Electronics Co. Ltd
- * Author: Jaswinder Singh <jassisinghbrar@gmail.com>
- * based upon I2S drivers by Ben Dooks.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/pm_runtime.h>
-
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <plat/audio.h>
-#include <plat/dma.h>
-
-#include "dma.h"
-#include "pcm.h"
-
-/*Register Offsets */
-#define S3C_PCM_CTL 0x00
-#define S3C_PCM_CLKCTL 0x04
-#define S3C_PCM_TXFIFO 0x08
-#define S3C_PCM_RXFIFO 0x0C
-#define S3C_PCM_IRQCTL 0x10
-#define S3C_PCM_IRQSTAT 0x14
-#define S3C_PCM_FIFOSTAT 0x18
-#define S3C_PCM_CLRINT 0x20
-
-/* PCM_CTL Bit-Fields */
-#define S3C_PCM_CTL_TXDIPSTICK_MASK 0x3f
-#define S3C_PCM_CTL_TXDIPSTICK_SHIFT 13
-#define S3C_PCM_CTL_RXDIPSTICK_MASK 0x3f
-#define S3C_PCM_CTL_RXDIPSTICK_SHIFT 7
-#define S3C_PCM_CTL_TXDMA_EN (0x1 << 6)
-#define S3C_PCM_CTL_RXDMA_EN (0x1 << 5)
-#define S3C_PCM_CTL_TXMSB_AFTER_FSYNC (0x1 << 4)
-#define S3C_PCM_CTL_RXMSB_AFTER_FSYNC (0x1 << 3)
-#define S3C_PCM_CTL_TXFIFO_EN (0x1 << 2)
-#define S3C_PCM_CTL_RXFIFO_EN (0x1 << 1)
-#define S3C_PCM_CTL_ENABLE (0x1 << 0)
-
-/* PCM_CLKCTL Bit-Fields */
-#define S3C_PCM_CLKCTL_SERCLK_EN (0x1 << 19)
-#define S3C_PCM_CLKCTL_SERCLKSEL_PCLK (0x1 << 18)
-#define S3C_PCM_CLKCTL_SCLKDIV_MASK 0x1ff
-#define S3C_PCM_CLKCTL_SYNCDIV_MASK 0x1ff
-#define S3C_PCM_CLKCTL_SCLKDIV_SHIFT 9
-#define S3C_PCM_CLKCTL_SYNCDIV_SHIFT 0
-
-/* PCM_TXFIFO Bit-Fields */
-#define S3C_PCM_TXFIFO_DVALID (0x1 << 16)
-#define S3C_PCM_TXFIFO_DATA_MSK (0xffff << 0)
-
-/* PCM_RXFIFO Bit-Fields */
-#define S3C_PCM_RXFIFO_DVALID (0x1 << 16)
-#define S3C_PCM_RXFIFO_DATA_MSK (0xffff << 0)
-
-/* PCM_IRQCTL Bit-Fields */
-#define S3C_PCM_IRQCTL_IRQEN (0x1 << 14)
-#define S3C_PCM_IRQCTL_WRDEN (0x1 << 12)
-#define S3C_PCM_IRQCTL_TXEMPTYEN (0x1 << 11)
-#define S3C_PCM_IRQCTL_TXALMSTEMPTYEN (0x1 << 10)
-#define S3C_PCM_IRQCTL_TXFULLEN (0x1 << 9)
-#define S3C_PCM_IRQCTL_TXALMSTFULLEN (0x1 << 8)
-#define S3C_PCM_IRQCTL_TXSTARVEN (0x1 << 7)
-#define S3C_PCM_IRQCTL_TXERROVRFLEN (0x1 << 6)
-#define S3C_PCM_IRQCTL_RXEMPTEN (0x1 << 5)
-#define S3C_PCM_IRQCTL_RXALMSTEMPTEN (0x1 << 4)
-#define S3C_PCM_IRQCTL_RXFULLEN (0x1 << 3)
-#define S3C_PCM_IRQCTL_RXALMSTFULLEN (0x1 << 2)
-#define S3C_PCM_IRQCTL_RXSTARVEN (0x1 << 1)
-#define S3C_PCM_IRQCTL_RXERROVRFLEN (0x1 << 0)
-
-/* PCM_IRQSTAT Bit-Fields */
-#define S3C_PCM_IRQSTAT_IRQPND (0x1 << 13)
-#define S3C_PCM_IRQSTAT_WRD_XFER (0x1 << 12)
-#define S3C_PCM_IRQSTAT_TXEMPTY (0x1 << 11)
-#define S3C_PCM_IRQSTAT_TXALMSTEMPTY (0x1 << 10)
-#define S3C_PCM_IRQSTAT_TXFULL (0x1 << 9)
-#define S3C_PCM_IRQSTAT_TXALMSTFULL (0x1 << 8)
-#define S3C_PCM_IRQSTAT_TXSTARV (0x1 << 7)
-#define S3C_PCM_IRQSTAT_TXERROVRFL (0x1 << 6)
-#define S3C_PCM_IRQSTAT_RXEMPT (0x1 << 5)
-#define S3C_PCM_IRQSTAT_RXALMSTEMPT (0x1 << 4)
-#define S3C_PCM_IRQSTAT_RXFULL (0x1 << 3)
-#define S3C_PCM_IRQSTAT_RXALMSTFULL (0x1 << 2)
-#define S3C_PCM_IRQSTAT_RXSTARV (0x1 << 1)
-#define S3C_PCM_IRQSTAT_RXERROVRFL (0x1 << 0)
-
-/* PCM_FIFOSTAT Bit-Fields */
-#define S3C_PCM_FIFOSTAT_TXCNT_MSK (0x3f << 14)
-#define S3C_PCM_FIFOSTAT_TXFIFOEMPTY (0x1 << 13)
-#define S3C_PCM_FIFOSTAT_TXFIFOALMSTEMPTY (0x1 << 12)
-#define S3C_PCM_FIFOSTAT_TXFIFOFULL (0x1 << 11)
-#define S3C_PCM_FIFOSTAT_TXFIFOALMSTFULL (0x1 << 10)
-#define S3C_PCM_FIFOSTAT_RXCNT_MSK (0x3f << 4)
-#define S3C_PCM_FIFOSTAT_RXFIFOEMPTY (0x1 << 3)
-#define S3C_PCM_FIFOSTAT_RXFIFOALMSTEMPTY (0x1 << 2)
-#define S3C_PCM_FIFOSTAT_RXFIFOFULL (0x1 << 1)
-#define S3C_PCM_FIFOSTAT_RXFIFOALMSTFULL (0x1 << 0)
-
-/**
- * struct s3c_pcm_info - S3C PCM Controller information
- * @dev: The parent device passed to use from the probe.
- * @regs: The pointer to the device register block.
- * @dma_playback: DMA information for playback channel.
- * @dma_capture: DMA information for capture channel.
- */
-struct s3c_pcm_info {
- spinlock_t lock;
- struct device *dev;
- void __iomem *regs;
-
- unsigned int sclk_per_fs;
-
- /* Whether to keep PCMSCLK enabled even when idle(no active xfer) */
- unsigned int idleclk;
-
- struct clk *pclk;
- struct clk *cclk;
-
- struct s3c_dma_params *dma_playback;
- struct s3c_dma_params *dma_capture;
-};
-
-static struct s3c2410_dma_client s3c_pcm_dma_client_out = {
- .name = "PCM Stereo out"
-};
-
-static struct s3c2410_dma_client s3c_pcm_dma_client_in = {
- .name = "PCM Stereo in"
-};
-
-static struct s3c_dma_params s3c_pcm_stereo_out[] = {
- [0] = {
- .client = &s3c_pcm_dma_client_out,
- .dma_size = 4,
- },
- [1] = {
- .client = &s3c_pcm_dma_client_out,
- .dma_size = 4,
- },
-};
-
-static struct s3c_dma_params s3c_pcm_stereo_in[] = {
- [0] = {
- .client = &s3c_pcm_dma_client_in,
- .dma_size = 4,
- },
- [1] = {
- .client = &s3c_pcm_dma_client_in,
- .dma_size = 4,
- },
-};
-
-static struct s3c_pcm_info s3c_pcm[2];
-
-static void s3c_pcm_snd_txctrl(struct s3c_pcm_info *pcm, int on)
-{
- void __iomem *regs = pcm->regs;
- u32 ctl, clkctl;
-
- clkctl = readl(regs + S3C_PCM_CLKCTL);
- ctl = readl(regs + S3C_PCM_CTL);
- ctl &= ~(S3C_PCM_CTL_TXDIPSTICK_MASK
- << S3C_PCM_CTL_TXDIPSTICK_SHIFT);
-
- if (on) {
- ctl |= S3C_PCM_CTL_TXDMA_EN;
- ctl |= S3C_PCM_CTL_TXFIFO_EN;
- ctl |= S3C_PCM_CTL_ENABLE;
- ctl |= (0x4<<S3C_PCM_CTL_TXDIPSTICK_SHIFT);
- clkctl |= S3C_PCM_CLKCTL_SERCLK_EN;
- } else {
- ctl &= ~S3C_PCM_CTL_TXDMA_EN;
- ctl &= ~S3C_PCM_CTL_TXFIFO_EN;
-
- if (!(ctl & S3C_PCM_CTL_RXFIFO_EN)) {
- ctl &= ~S3C_PCM_CTL_ENABLE;
- if (!pcm->idleclk)
- clkctl |= S3C_PCM_CLKCTL_SERCLK_EN;
- }
- }
-
- writel(clkctl, regs + S3C_PCM_CLKCTL);
- writel(ctl, regs + S3C_PCM_CTL);
-}
-
-static void s3c_pcm_snd_rxctrl(struct s3c_pcm_info *pcm, int on)
-{
- void __iomem *regs = pcm->regs;
- u32 ctl, clkctl;
-
- ctl = readl(regs + S3C_PCM_CTL);
- clkctl = readl(regs + S3C_PCM_CLKCTL);
- ctl &= ~(S3C_PCM_CTL_RXDIPSTICK_MASK
- << S3C_PCM_CTL_RXDIPSTICK_SHIFT);
-
- if (on) {
- ctl |= S3C_PCM_CTL_RXDMA_EN;
- ctl |= S3C_PCM_CTL_RXFIFO_EN;
- ctl |= S3C_PCM_CTL_ENABLE;
- ctl |= (0x20<<S3C_PCM_CTL_RXDIPSTICK_SHIFT);
- clkctl |= S3C_PCM_CLKCTL_SERCLK_EN;
- } else {
- ctl &= ~S3C_PCM_CTL_RXDMA_EN;
- ctl &= ~S3C_PCM_CTL_RXFIFO_EN;
-
- if (!(ctl & S3C_PCM_CTL_TXFIFO_EN)) {
- ctl &= ~S3C_PCM_CTL_ENABLE;
- if (!pcm->idleclk)
- clkctl |= S3C_PCM_CLKCTL_SERCLK_EN;
- }
- }
-
- writel(clkctl, regs + S3C_PCM_CLKCTL);
- writel(ctl, regs + S3C_PCM_CTL);
-}
-
-static int s3c_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai);
- unsigned long flags;
-
- dev_dbg(pcm->dev, "Entered %s\n", __func__);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- spin_lock_irqsave(&pcm->lock, flags);
-
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- s3c_pcm_snd_rxctrl(pcm, 1);
- else
- s3c_pcm_snd_txctrl(pcm, 1);
-
- spin_unlock_irqrestore(&pcm->lock, flags);
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- spin_lock_irqsave(&pcm->lock, flags);
-
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- s3c_pcm_snd_rxctrl(pcm, 0);
- else
- s3c_pcm_snd_txctrl(pcm, 0);
-
- spin_unlock_irqrestore(&pcm->lock, flags);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *socdai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai);
- struct s3c_dma_params *dma_data;
- void __iomem *regs = pcm->regs;
- struct clk *clk;
- int sclk_div, sync_div;
- unsigned long flags;
- u32 clkctl;
-
- dev_dbg(pcm->dev, "Entered %s\n", __func__);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dma_data = pcm->dma_playback;
- else
- dma_data = pcm->dma_capture;
-
- snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data);
-
- /* Strictly check for sample size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- default:
- return -EINVAL;
- }
-
- spin_lock_irqsave(&pcm->lock, flags);
-
- /* Get hold of the PCMSOURCE_CLK */
- clkctl = readl(regs + S3C_PCM_CLKCTL);
- if (clkctl & S3C_PCM_CLKCTL_SERCLKSEL_PCLK)
- clk = pcm->pclk;
- else
- clk = pcm->cclk;
-
- /* Set the SCLK divider */
- sclk_div = clk_get_rate(clk) / pcm->sclk_per_fs /
- params_rate(params) / 2 - 1;
-
- clkctl &= ~(S3C_PCM_CLKCTL_SCLKDIV_MASK
- << S3C_PCM_CLKCTL_SCLKDIV_SHIFT);
- clkctl |= ((sclk_div & S3C_PCM_CLKCTL_SCLKDIV_MASK)
- << S3C_PCM_CLKCTL_SCLKDIV_SHIFT);
-
- /* Set the SYNC divider */
- sync_div = pcm->sclk_per_fs - 1;
-
- clkctl &= ~(S3C_PCM_CLKCTL_SYNCDIV_MASK
- << S3C_PCM_CLKCTL_SYNCDIV_SHIFT);
- clkctl |= ((sync_div & S3C_PCM_CLKCTL_SYNCDIV_MASK)
- << S3C_PCM_CLKCTL_SYNCDIV_SHIFT);
-
- writel(clkctl, regs + S3C_PCM_CLKCTL);
-
- spin_unlock_irqrestore(&pcm->lock, flags);
-
- dev_dbg(pcm->dev, "PCMSOURCE_CLK-%lu SCLK=%ufs SCLK_DIV=%d SYNC_DIV=%d\n",
- clk_get_rate(clk), pcm->sclk_per_fs,
- sclk_div, sync_div);
-
- return 0;
-}
-
-static int s3c_pcm_set_fmt(struct snd_soc_dai *cpu_dai,
- unsigned int fmt)
-{
- struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai);
- void __iomem *regs = pcm->regs;
- unsigned long flags;
- int ret = 0;
- u32 ctl;
-
- dev_dbg(pcm->dev, "Entered %s\n", __func__);
-
- spin_lock_irqsave(&pcm->lock, flags);
-
- ctl = readl(regs + S3C_PCM_CTL);
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_IB_NF:
- /* Nothing to do, IB_NF by default */
- break;
- default:
- dev_err(pcm->dev, "Unsupported clock inversion!\n");
- ret = -EINVAL;
- goto exit;
- }
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- /* Nothing to do, Master by default */
- break;
- default:
- dev_err(pcm->dev, "Unsupported master/slave format!\n");
- ret = -EINVAL;
- goto exit;
- }
-
- switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) {
- case SND_SOC_DAIFMT_CONT:
- pcm->idleclk = 1;
- break;
- case SND_SOC_DAIFMT_GATED:
- pcm->idleclk = 0;
- break;
- default:
- dev_err(pcm->dev, "Invalid Clock gating request!\n");
- ret = -EINVAL;
- goto exit;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- ctl |= S3C_PCM_CTL_TXMSB_AFTER_FSYNC;
- ctl |= S3C_PCM_CTL_RXMSB_AFTER_FSYNC;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- ctl &= ~S3C_PCM_CTL_TXMSB_AFTER_FSYNC;
- ctl &= ~S3C_PCM_CTL_RXMSB_AFTER_FSYNC;
- break;
- default:
- dev_err(pcm->dev, "Unsupported data format!\n");
- ret = -EINVAL;
- goto exit;
- }
-
- writel(ctl, regs + S3C_PCM_CTL);
-
-exit:
- spin_unlock_irqrestore(&pcm->lock, flags);
-
- return ret;
-}
-
-static int s3c_pcm_set_clkdiv(struct snd_soc_dai *cpu_dai,
- int div_id, int div)
-{
- struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai);
-
- switch (div_id) {
- case S3C_PCM_SCLK_PER_FS:
- pcm->sclk_per_fs = div;
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int s3c_pcm_set_sysclk(struct snd_soc_dai *cpu_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai);
- void __iomem *regs = pcm->regs;
- u32 clkctl = readl(regs + S3C_PCM_CLKCTL);
-
- switch (clk_id) {
- case S3C_PCM_CLKSRC_PCLK:
- clkctl |= S3C_PCM_CLKCTL_SERCLKSEL_PCLK;
- break;
-
- case S3C_PCM_CLKSRC_MUX:
- clkctl &= ~S3C_PCM_CLKCTL_SERCLKSEL_PCLK;
-
- if (clk_get_rate(pcm->cclk) != freq)
- clk_set_rate(pcm->cclk, freq);
-
- break;
-
- default:
- return -EINVAL;
- }
-
- writel(clkctl, regs + S3C_PCM_CLKCTL);
-
- return 0;
-}
-
-static const struct snd_soc_dai_ops s3c_pcm_dai_ops = {
- .set_sysclk = s3c_pcm_set_sysclk,
- .set_clkdiv = s3c_pcm_set_clkdiv,
- .trigger = s3c_pcm_trigger,
- .hw_params = s3c_pcm_hw_params,
- .set_fmt = s3c_pcm_set_fmt,
-};
-
-#define S3C_PCM_RATES SNDRV_PCM_RATE_8000_96000
-
-#define S3C_PCM_DAI_DECLARE \
- .symmetric_rates = 1, \
- .ops = &s3c_pcm_dai_ops, \
- .playback = { \
- .channels_min = 2, \
- .channels_max = 2, \
- .rates = S3C_PCM_RATES, \
- .formats = SNDRV_PCM_FMTBIT_S16_LE, \
- }, \
- .capture = { \
- .channels_min = 2, \
- .channels_max = 2, \
- .rates = S3C_PCM_RATES, \
- .formats = SNDRV_PCM_FMTBIT_S16_LE, \
- }
-
-static struct snd_soc_dai_driver s3c_pcm_dai[] = {
- [0] = {
- .name = "samsung-pcm.0",
- S3C_PCM_DAI_DECLARE,
- },
- [1] = {
- .name = "samsung-pcm.1",
- S3C_PCM_DAI_DECLARE,
- },
-};
-
-static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev)
-{
- struct s3c_pcm_info *pcm;
- struct resource *mem_res, *dmatx_res, *dmarx_res;
- struct s3c_audio_pdata *pcm_pdata;
- int ret;
-
- /* Check for valid device index */
- if ((pdev->id < 0) || pdev->id >= ARRAY_SIZE(s3c_pcm)) {
- dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
- return -EINVAL;
- }
-
- pcm_pdata = pdev->dev.platform_data;
-
- /* Check for availability of necessary resource */
- dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!dmatx_res) {
- dev_err(&pdev->dev, "Unable to get PCM-TX dma resource\n");
- return -ENXIO;
- }
-
- dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (!dmarx_res) {
- dev_err(&pdev->dev, "Unable to get PCM-RX dma resource\n");
- return -ENXIO;
- }
-
- mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem_res) {
- dev_err(&pdev->dev, "Unable to get register resource\n");
- return -ENXIO;
- }
-
- if (pcm_pdata && pcm_pdata->cfg_gpio && pcm_pdata->cfg_gpio(pdev)) {
- dev_err(&pdev->dev, "Unable to configure gpio\n");
- return -EINVAL;
- }
-
- pcm = &s3c_pcm[pdev->id];
- pcm->dev = &pdev->dev;
-
- spin_lock_init(&pcm->lock);
-
- /* Default is 128fs */
- pcm->sclk_per_fs = 128;
-
- pcm->cclk = clk_get(&pdev->dev, "audio-bus");
- if (IS_ERR(pcm->cclk)) {
- dev_err(&pdev->dev, "failed to get audio-bus\n");
- ret = PTR_ERR(pcm->cclk);
- goto err1;
- }
- clk_enable(pcm->cclk);
-
- /* record our pcm structure for later use in the callbacks */
- dev_set_drvdata(&pdev->dev, pcm);
-
- if (!request_mem_region(mem_res->start,
- resource_size(mem_res), "samsung-pcm")) {
- dev_err(&pdev->dev, "Unable to request register region\n");
- ret = -EBUSY;
- goto err2;
- }
-
- pcm->regs = ioremap(mem_res->start, 0x100);
- if (pcm->regs == NULL) {
- dev_err(&pdev->dev, "cannot ioremap registers\n");
- ret = -ENXIO;
- goto err3;
- }
-
- pcm->pclk = clk_get(&pdev->dev, "pcm");
- if (IS_ERR(pcm->pclk)) {
- dev_err(&pdev->dev, "failed to get pcm_clock\n");
- ret = -ENOENT;
- goto err4;
- }
- clk_enable(pcm->pclk);
-
- s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start
- + S3C_PCM_RXFIFO;
- s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start
- + S3C_PCM_TXFIFO;
-
- s3c_pcm_stereo_in[pdev->id].channel = dmarx_res->start;
- s3c_pcm_stereo_out[pdev->id].channel = dmatx_res->start;
-
- pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id];
- pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id];
-
- pm_runtime_enable(&pdev->dev);
-
- ret = snd_soc_register_dai(&pdev->dev, &s3c_pcm_dai[pdev->id]);
- if (ret != 0) {
- dev_err(&pdev->dev, "failed to get register DAI: %d\n", ret);
- goto err5;
- }
-
- return 0;
-
-err5:
- clk_disable(pcm->pclk);
- clk_put(pcm->pclk);
-err4:
- iounmap(pcm->regs);
-err3:
- release_mem_region(mem_res->start, resource_size(mem_res));
-err2:
- clk_disable(pcm->cclk);
- clk_put(pcm->cclk);
-err1:
- return ret;
-}
-
-static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev)
-{
- struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id];
- struct resource *mem_res;
-
- snd_soc_unregister_dai(&pdev->dev);
-
- pm_runtime_disable(&pdev->dev);
-
- iounmap(pcm->regs);
-
- mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(mem_res->start, resource_size(mem_res));
-
- clk_disable(pcm->cclk);
- clk_disable(pcm->pclk);
- clk_put(pcm->pclk);
- clk_put(pcm->cclk);
-
- return 0;
-}
-
-static struct platform_driver s3c_pcm_driver = {
- .probe = s3c_pcm_dev_probe,
- .remove = __devexit_p(s3c_pcm_dev_remove),
- .driver = {
- .name = "samsung-pcm",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(s3c_pcm_driver);
-
-/* Module information */
-MODULE_AUTHOR("Jaswinder Singh, <jassisinghbrar@gmail.com>");
-MODULE_DESCRIPTION("S3C PCM Controller Driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:samsung-pcm");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/pcm.h b/ANDROID_3.4.5/sound/soc/samsung/pcm.h
deleted file mode 100644
index 726baf81..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/pcm.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* sound/soc/samsung/pcm.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#ifndef __S3C_PCM_H
-#define __S3C_PCM_H __FILE__
-
-#define S3C_PCM_CLKSRC_PCLK 0
-#define S3C_PCM_CLKSRC_MUX 1
-
-#define S3C_PCM_SCLK_PER_FS 0
-
-#endif /* __S3C_PCM_H */
diff --git a/ANDROID_3.4.5/sound/soc/samsung/regs-i2s-v2.h b/ANDROID_3.4.5/sound/soc/samsung/regs-i2s-v2.h
deleted file mode 100644
index 5e5e5680..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/regs-i2s-v2.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* linux/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h
- *
- * Copyright 2007 Simtec Electronics <linux@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2412 IIS register definition
-*/
-
-#ifndef __ASM_ARCH_REGS_S3C2412_IIS_H
-#define __ASM_ARCH_REGS_S3C2412_IIS_H
-
-#define S3C2412_IISCON (0x00)
-#define S3C2412_IISMOD (0x04)
-#define S3C2412_IISFIC (0x08)
-#define S3C2412_IISPSR (0x0C)
-#define S3C2412_IISTXD (0x10)
-#define S3C2412_IISRXD (0x14)
-
-#define S5PC1XX_IISFICS 0x18
-#define S5PC1XX_IISTXDS 0x1C
-
-#define S5PC1XX_IISCON_SW_RST (1 << 31)
-#define S5PC1XX_IISCON_FRXOFSTATUS (1 << 26)
-#define S5PC1XX_IISCON_FRXORINTEN (1 << 25)
-#define S5PC1XX_IISCON_FTXSURSTAT (1 << 24)
-#define S5PC1XX_IISCON_FTXSURINTEN (1 << 23)
-#define S5PC1XX_IISCON_TXSDMAPAUSE (1 << 20)
-#define S5PC1XX_IISCON_TXSDMACTIVE (1 << 18)
-
-#define S3C64XX_IISCON_FTXURSTATUS (1 << 17)
-#define S3C64XX_IISCON_FTXURINTEN (1 << 16)
-#define S3C64XX_IISCON_TXFIFO2_EMPTY (1 << 15)
-#define S3C64XX_IISCON_TXFIFO1_EMPTY (1 << 14)
-#define S3C64XX_IISCON_TXFIFO2_FULL (1 << 13)
-#define S3C64XX_IISCON_TXFIFO1_FULL (1 << 12)
-
-#define S3C2412_IISCON_LRINDEX (1 << 11)
-#define S3C2412_IISCON_TXFIFO_EMPTY (1 << 10)
-#define S3C2412_IISCON_RXFIFO_EMPTY (1 << 9)
-#define S3C2412_IISCON_TXFIFO_FULL (1 << 8)
-#define S3C2412_IISCON_RXFIFO_FULL (1 << 7)
-#define S3C2412_IISCON_TXDMA_PAUSE (1 << 6)
-#define S3C2412_IISCON_RXDMA_PAUSE (1 << 5)
-#define S3C2412_IISCON_TXCH_PAUSE (1 << 4)
-#define S3C2412_IISCON_RXCH_PAUSE (1 << 3)
-#define S3C2412_IISCON_TXDMA_ACTIVE (1 << 2)
-#define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1)
-#define S3C2412_IISCON_IIS_ACTIVE (1 << 0)
-
-#define S5PC1XX_IISMOD_OPCLK_CDCLK_OUT (0 << 30)
-#define S5PC1XX_IISMOD_OPCLK_CDCLK_IN (1 << 30)
-#define S5PC1XX_IISMOD_OPCLK_BCLK_OUT (2 << 30)
-#define S5PC1XX_IISMOD_OPCLK_PCLK (3 << 30)
-#define S5PC1XX_IISMOD_OPCLK_MASK (3 << 30)
-#define S5PC1XX_IISMOD_TXS_IDMA (1 << 28) /* Sec_TXFIFO use I-DMA */
-#define S5PC1XX_IISMOD_BLCS_MASK 0x3
-#define S5PC1XX_IISMOD_BLCS_SHIFT 26
-#define S5PC1XX_IISMOD_BLCP_MASK 0x3
-#define S5PC1XX_IISMOD_BLCP_SHIFT 24
-
-#define S3C64XX_IISMOD_C2DD_HHALF (1 << 21) /* Discard Higher-half */
-#define S3C64XX_IISMOD_C2DD_LHALF (1 << 20) /* Discard Lower-half */
-#define S3C64XX_IISMOD_C1DD_HHALF (1 << 19)
-#define S3C64XX_IISMOD_C1DD_LHALF (1 << 18)
-#define S3C64XX_IISMOD_DC2_EN (1 << 17)
-#define S3C64XX_IISMOD_DC1_EN (1 << 16)
-#define S3C64XX_IISMOD_BLC_16BIT (0 << 13)
-#define S3C64XX_IISMOD_BLC_8BIT (1 << 13)
-#define S3C64XX_IISMOD_BLC_24BIT (2 << 13)
-#define S3C64XX_IISMOD_BLC_MASK (3 << 13)
-
-#define S3C2412_IISMOD_IMS_SYSMUX (1 << 10)
-#define S3C2412_IISMOD_SLAVE (1 << 11)
-#define S3C2412_IISMOD_MODE_TXONLY (0 << 8)
-#define S3C2412_IISMOD_MODE_RXONLY (1 << 8)
-#define S3C2412_IISMOD_MODE_TXRX (2 << 8)
-#define S3C2412_IISMOD_MODE_MASK (3 << 8)
-#define S3C2412_IISMOD_LR_LLOW (0 << 7)
-#define S3C2412_IISMOD_LR_RLOW (1 << 7)
-#define S3C2412_IISMOD_SDF_IIS (0 << 5)
-#define S3C2412_IISMOD_SDF_MSB (1 << 5)
-#define S3C2412_IISMOD_SDF_LSB (2 << 5)
-#define S3C2412_IISMOD_SDF_MASK (3 << 5)
-#define S3C2412_IISMOD_RCLK_256FS (0 << 3)
-#define S3C2412_IISMOD_RCLK_512FS (1 << 3)
-#define S3C2412_IISMOD_RCLK_384FS (2 << 3)
-#define S3C2412_IISMOD_RCLK_768FS (3 << 3)
-#define S3C2412_IISMOD_RCLK_MASK (3 << 3)
-#define S3C2412_IISMOD_BCLK_32FS (0 << 1)
-#define S3C2412_IISMOD_BCLK_48FS (1 << 1)
-#define S3C2412_IISMOD_BCLK_16FS (2 << 1)
-#define S3C2412_IISMOD_BCLK_24FS (3 << 1)
-#define S3C2412_IISMOD_BCLK_MASK (3 << 1)
-#define S3C2412_IISMOD_8BIT (1 << 0)
-
-#define S3C64XX_IISMOD_CDCLKCON (1 << 12)
-
-#define S3C2412_IISPSR_PSREN (1 << 15)
-
-#define S3C64XX_IISFIC_TX2COUNT(x) (((x) >> 24) & 0xf)
-#define S3C64XX_IISFIC_TX1COUNT(x) (((x) >> 16) & 0xf)
-
-#define S3C2412_IISFIC_TXFLUSH (1 << 15)
-#define S3C2412_IISFIC_RXFLUSH (1 << 7)
-#define S3C2412_IISFIC_TXCOUNT(x) (((x) >> 8) & 0xf)
-#define S3C2412_IISFIC_RXCOUNT(x) (((x) >> 0) & 0xf)
-
-#define S5PC1XX_IISFICS_TXFLUSH (1 << 15)
-#define S5PC1XX_IISFICS_TXCOUNT(x) (((x) >> 8) & 0x7f)
-
-#endif /* __ASM_ARCH_REGS_S3C2412_IIS_H */
diff --git a/ANDROID_3.4.5/sound/soc/samsung/rx1950_uda1380.c b/ANDROID_3.4.5/sound/soc/samsung/rx1950_uda1380.c
deleted file mode 100644
index 21e12361..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/rx1950_uda1380.c
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * rx1950.c -- ALSA Soc Audio Layer
- *
- * Copyright (c) 2010 Vasily Khoruzhick <anarsoul@gmail.com>
- *
- * Based on smdk2440.c and magician.c
- *
- * Authors: Graeme Gregory graeme.gregory@wolfsonmicro.com
- * Philipp Zabel <philipp.zabel@gmail.com>
- * Denis Grigoriev <dgreenday@gmail.com>
- * Vasily Khoruzhick <anarsoul@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/types.h>
-#include <linux/gpio.h>
-#include <linux/module.h>
-
-#include <sound/soc.h>
-#include <sound/jack.h>
-
-#include <plat/regs-iis.h>
-#include <asm/mach-types.h>
-
-#include "s3c24xx-i2s.h"
-
-static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd);
-static int rx1950_startup(struct snd_pcm_substream *substream);
-static int rx1950_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params);
-static int rx1950_spk_power(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event);
-
-static unsigned int rates[] = {
- 16000,
- 44100,
- 48000,
-};
-
-static struct snd_pcm_hw_constraint_list hw_rates = {
- .count = ARRAY_SIZE(rates),
- .list = rates,
- .mask = 0,
-};
-
-static struct snd_soc_jack hp_jack;
-
-static struct snd_soc_jack_pin hp_jack_pins[] = {
- {
- .pin = "Headphone Jack",
- .mask = SND_JACK_HEADPHONE,
- },
- {
- .pin = "Speaker",
- .mask = SND_JACK_HEADPHONE,
- .invert = 1,
- },
-};
-
-static struct snd_soc_jack_gpio hp_jack_gpios[] = {
- [0] = {
- .gpio = S3C2410_GPG(12),
- .name = "hp-gpio",
- .report = SND_JACK_HEADPHONE,
- .invert = 1,
- .debounce_time = 200,
- },
-};
-
-static struct snd_soc_ops rx1950_ops = {
- .startup = rx1950_startup,
- .hw_params = rx1950_hw_params,
-};
-
-/* s3c24xx digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link rx1950_uda1380_dai[] = {
- {
- .name = "uda1380",
- .stream_name = "UDA1380 Duplex",
- .cpu_dai_name = "s3c24xx-iis",
- .codec_dai_name = "uda1380-hifi",
- .init = rx1950_uda1380_init,
- .platform_name = "samsung-audio",
- .codec_name = "uda1380-codec.0-001a",
- .ops = &rx1950_ops,
- },
-};
-
-/* rx1950 machine dapm widgets */
-static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_MIC("Mic Jack", NULL),
- SND_SOC_DAPM_SPK("Speaker", rx1950_spk_power),
-};
-
-/* rx1950 machine audio_map */
-static const struct snd_soc_dapm_route audio_map[] = {
- /* headphone connected to VOUTLHP, VOUTRHP */
- {"Headphone Jack", NULL, "VOUTLHP"},
- {"Headphone Jack", NULL, "VOUTRHP"},
-
- /* ext speaker connected to VOUTL, VOUTR */
- {"Speaker", NULL, "VOUTL"},
- {"Speaker", NULL, "VOUTR"},
-
- /* mic is connected to VINM */
- {"VINM", NULL, "Mic Jack"},
-};
-
-static struct snd_soc_card rx1950_asoc = {
- .name = "rx1950",
- .owner = THIS_MODULE,
- .dai_link = rx1950_uda1380_dai,
- .num_links = ARRAY_SIZE(rx1950_uda1380_dai),
-
- .dapm_widgets = uda1380_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets),
- .dapm_routes = audio_map,
- .num_dapm_routes = ARRAY_SIZE(audio_map),
-};
-
-static struct platform_device *s3c24xx_snd_device;
-
-static int rx1950_startup(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- runtime->hw.rate_min = hw_rates.list[0];
- runtime->hw.rate_max = hw_rates.list[hw_rates.count - 1];
- runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
-
- return snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- &hw_rates);
-}
-
-static int rx1950_spk_power(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- if (SND_SOC_DAPM_EVENT_ON(event))
- gpio_set_value(S3C2410_GPA(1), 1);
- else
- gpio_set_value(S3C2410_GPA(1), 0);
-
- return 0;
-}
-
-static int rx1950_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int div;
- int ret;
- unsigned int rate = params_rate(params);
- int clk_source, fs_mode;
-
- switch (rate) {
- case 16000:
- case 48000:
- clk_source = S3C24XX_CLKSRC_PCLK;
- fs_mode = S3C2410_IISMOD_256FS;
- div = s3c24xx_i2s_get_clockrate() / (256 * rate);
- if (s3c24xx_i2s_get_clockrate() % (256 * rate) > (128 * rate))
- div++;
- break;
- case 44100:
- case 88200:
- clk_source = S3C24XX_CLKSRC_MPLL;
- fs_mode = S3C2410_IISMOD_384FS;
- div = 1;
- break;
- default:
- printk(KERN_ERR "%s: rate %d is not supported\n",
- __func__, rate);
- return -EINVAL;
- }
-
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* select clock source */
- ret = snd_soc_dai_set_sysclk(cpu_dai, clk_source, rate,
- SND_SOC_CLOCK_OUT);
- if (ret < 0)
- return ret;
-
- /* set MCLK division for sample rate */
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
- fs_mode);
- if (ret < 0)
- return ret;
-
- /* set BCLK division for sample rate */
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK,
- S3C2410_IISMOD_32FS);
- if (ret < 0)
- return ret;
-
- /* set prescaler division for sample rate */
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
- S3C24XX_PRESCALE(div, div));
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int err;
-
- snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_enable_pin(dapm, "Speaker");
- snd_soc_dapm_enable_pin(dapm, "Mic Jack");
-
- snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
- &hp_jack);
-
- snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins),
- hp_jack_pins);
-
- snd_soc_jack_add_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios),
- hp_jack_gpios);
-
- return 0;
-}
-
-static int __init rx1950_init(void)
-{
- int ret;
-
- if (!machine_is_rx1950())
- return -ENODEV;
-
- /* configure some gpios */
- ret = gpio_request(S3C2410_GPA(1), "speaker-power");
- if (ret)
- goto err_gpio;
-
- ret = gpio_direction_output(S3C2410_GPA(1), 0);
- if (ret)
- goto err_gpio_conf;
-
- s3c24xx_snd_device = platform_device_alloc("soc-audio", -1);
- if (!s3c24xx_snd_device) {
- ret = -ENOMEM;
- goto err_plat_alloc;
- }
-
- platform_set_drvdata(s3c24xx_snd_device, &rx1950_asoc);
- ret = platform_device_add(s3c24xx_snd_device);
-
- if (ret) {
- platform_device_put(s3c24xx_snd_device);
- goto err_plat_add;
- }
-
- return 0;
-
-err_plat_add:
-err_plat_alloc:
-err_gpio_conf:
- gpio_free(S3C2410_GPA(1));
-
-err_gpio:
- return ret;
-}
-
-static void __exit rx1950_exit(void)
-{
- platform_device_unregister(s3c24xx_snd_device);
- snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios),
- hp_jack_gpios);
- gpio_free(S3C2410_GPA(1));
-}
-
-module_init(rx1950_init);
-module_exit(rx1950_exit);
-
-/* Module information */
-MODULE_AUTHOR("Vasily Khoruzhick");
-MODULE_DESCRIPTION("ALSA SoC RX1950");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/s3c-i2s-v2.c b/ANDROID_3.4.5/sound/soc/samsung/s3c-i2s-v2.c
deleted file mode 100644
index 7a73380b..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/s3c-i2s-v2.c
+++ /dev/null
@@ -1,757 +0,0 @@
-/* sound/soc/samsung/s3c-i2c-v2.c
- *
- * ALSA Soc Audio Layer - I2S core for newer Samsung SoCs.
- *
- * Copyright (c) 2006 Wolfson Microelectronics PLC.
- * Graeme Gregory graeme.gregory@wolfsonmicro.com
- * linux@wolfsonmicro.com
- *
- * Copyright (c) 2008, 2007, 2004-2005 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <mach/dma.h>
-
-#include "regs-i2s-v2.h"
-#include "s3c-i2s-v2.h"
-#include "dma.h"
-
-#undef S3C_IIS_V2_SUPPORTED
-
-#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) \
- || defined(CONFIG_CPU_S5PV210)
-#define S3C_IIS_V2_SUPPORTED
-#endif
-
-#ifdef CONFIG_PLAT_S3C64XX
-#define S3C_IIS_V2_SUPPORTED
-#endif
-
-#ifndef S3C_IIS_V2_SUPPORTED
-#error Unsupported CPU model
-#endif
-
-#define S3C2412_I2S_DEBUG_CON 0
-
-static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
-{
- return snd_soc_dai_get_drvdata(cpu_dai);
-}
-
-#define bit_set(v, b) (((v) & (b)) ? 1 : 0)
-
-#if S3C2412_I2S_DEBUG_CON
-static void dbg_showcon(const char *fn, u32 con)
-{
- printk(KERN_DEBUG "%s: LRI=%d, TXFEMPT=%d, RXFEMPT=%d, TXFFULL=%d, RXFFULL=%d\n", fn,
- bit_set(con, S3C2412_IISCON_LRINDEX),
- bit_set(con, S3C2412_IISCON_TXFIFO_EMPTY),
- bit_set(con, S3C2412_IISCON_RXFIFO_EMPTY),
- bit_set(con, S3C2412_IISCON_TXFIFO_FULL),
- bit_set(con, S3C2412_IISCON_RXFIFO_FULL));
-
- printk(KERN_DEBUG "%s: PAUSE: TXDMA=%d, RXDMA=%d, TXCH=%d, RXCH=%d\n",
- fn,
- bit_set(con, S3C2412_IISCON_TXDMA_PAUSE),
- bit_set(con, S3C2412_IISCON_RXDMA_PAUSE),
- bit_set(con, S3C2412_IISCON_TXCH_PAUSE),
- bit_set(con, S3C2412_IISCON_RXCH_PAUSE));
- printk(KERN_DEBUG "%s: ACTIVE: TXDMA=%d, RXDMA=%d, IIS=%d\n", fn,
- bit_set(con, S3C2412_IISCON_TXDMA_ACTIVE),
- bit_set(con, S3C2412_IISCON_RXDMA_ACTIVE),
- bit_set(con, S3C2412_IISCON_IIS_ACTIVE));
-}
-#else
-static inline void dbg_showcon(const char *fn, u32 con)
-{
-}
-#endif
-
-
-/* Turn on or off the transmission path. */
-static void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on)
-{
- void __iomem *regs = i2s->regs;
- u32 fic, con, mod;
-
- pr_debug("%s(%d)\n", __func__, on);
-
- fic = readl(regs + S3C2412_IISFIC);
- con = readl(regs + S3C2412_IISCON);
- mod = readl(regs + S3C2412_IISMOD);
-
- pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
-
- if (on) {
- con |= S3C2412_IISCON_TXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE;
- con &= ~S3C2412_IISCON_TXDMA_PAUSE;
- con &= ~S3C2412_IISCON_TXCH_PAUSE;
-
- switch (mod & S3C2412_IISMOD_MODE_MASK) {
- case S3C2412_IISMOD_MODE_TXONLY:
- case S3C2412_IISMOD_MODE_TXRX:
- /* do nothing, we are in the right mode */
- break;
-
- case S3C2412_IISMOD_MODE_RXONLY:
- mod &= ~S3C2412_IISMOD_MODE_MASK;
- mod |= S3C2412_IISMOD_MODE_TXRX;
- break;
-
- default:
- dev_err(i2s->dev, "TXEN: Invalid MODE %x in IISMOD\n",
- mod & S3C2412_IISMOD_MODE_MASK);
- break;
- }
-
- writel(con, regs + S3C2412_IISCON);
- writel(mod, regs + S3C2412_IISMOD);
- } else {
- /* Note, we do not have any indication that the FIFO problems
- * tha the S3C2410/2440 had apply here, so we should be able
- * to disable the DMA and TX without resetting the FIFOS.
- */
-
- con |= S3C2412_IISCON_TXDMA_PAUSE;
- con |= S3C2412_IISCON_TXCH_PAUSE;
- con &= ~S3C2412_IISCON_TXDMA_ACTIVE;
-
- switch (mod & S3C2412_IISMOD_MODE_MASK) {
- case S3C2412_IISMOD_MODE_TXRX:
- mod &= ~S3C2412_IISMOD_MODE_MASK;
- mod |= S3C2412_IISMOD_MODE_RXONLY;
- break;
-
- case S3C2412_IISMOD_MODE_TXONLY:
- mod &= ~S3C2412_IISMOD_MODE_MASK;
- con &= ~S3C2412_IISCON_IIS_ACTIVE;
- break;
-
- default:
- dev_err(i2s->dev, "TXDIS: Invalid MODE %x in IISMOD\n",
- mod & S3C2412_IISMOD_MODE_MASK);
- break;
- }
-
- writel(mod, regs + S3C2412_IISMOD);
- writel(con, regs + S3C2412_IISCON);
- }
-
- fic = readl(regs + S3C2412_IISFIC);
- dbg_showcon(__func__, con);
- pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
-}
-
-static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
-{
- void __iomem *regs = i2s->regs;
- u32 fic, con, mod;
-
- pr_debug("%s(%d)\n", __func__, on);
-
- fic = readl(regs + S3C2412_IISFIC);
- con = readl(regs + S3C2412_IISCON);
- mod = readl(regs + S3C2412_IISMOD);
-
- pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
-
- if (on) {
- con |= S3C2412_IISCON_RXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE;
- con &= ~S3C2412_IISCON_RXDMA_PAUSE;
- con &= ~S3C2412_IISCON_RXCH_PAUSE;
-
- switch (mod & S3C2412_IISMOD_MODE_MASK) {
- case S3C2412_IISMOD_MODE_TXRX:
- case S3C2412_IISMOD_MODE_RXONLY:
- /* do nothing, we are in the right mode */
- break;
-
- case S3C2412_IISMOD_MODE_TXONLY:
- mod &= ~S3C2412_IISMOD_MODE_MASK;
- mod |= S3C2412_IISMOD_MODE_TXRX;
- break;
-
- default:
- dev_err(i2s->dev, "RXEN: Invalid MODE %x in IISMOD\n",
- mod & S3C2412_IISMOD_MODE_MASK);
- }
-
- writel(mod, regs + S3C2412_IISMOD);
- writel(con, regs + S3C2412_IISCON);
- } else {
- /* See txctrl notes on FIFOs. */
-
- con &= ~S3C2412_IISCON_RXDMA_ACTIVE;
- con |= S3C2412_IISCON_RXDMA_PAUSE;
- con |= S3C2412_IISCON_RXCH_PAUSE;
-
- switch (mod & S3C2412_IISMOD_MODE_MASK) {
- case S3C2412_IISMOD_MODE_RXONLY:
- con &= ~S3C2412_IISCON_IIS_ACTIVE;
- mod &= ~S3C2412_IISMOD_MODE_MASK;
- break;
-
- case S3C2412_IISMOD_MODE_TXRX:
- mod &= ~S3C2412_IISMOD_MODE_MASK;
- mod |= S3C2412_IISMOD_MODE_TXONLY;
- break;
-
- default:
- dev_err(i2s->dev, "RXDIS: Invalid MODE %x in IISMOD\n",
- mod & S3C2412_IISMOD_MODE_MASK);
- }
-
- writel(con, regs + S3C2412_IISCON);
- writel(mod, regs + S3C2412_IISMOD);
- }
-
- fic = readl(regs + S3C2412_IISFIC);
- pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
-}
-
-#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
-
-/*
- * Wait for the LR signal to allow synchronisation to the L/R clock
- * from the codec. May only be needed for slave mode.
- */
-static int s3c2412_snd_lrsync(struct s3c_i2sv2_info *i2s)
-{
- u32 iiscon;
- unsigned long loops = msecs_to_loops(5);
-
- pr_debug("Entered %s\n", __func__);
-
- while (--loops) {
- iiscon = readl(i2s->regs + S3C2412_IISCON);
- if (iiscon & S3C2412_IISCON_LRINDEX)
- break;
-
- cpu_relax();
- }
-
- if (!loops) {
- printk(KERN_ERR "%s: timeout\n", __func__);
- return -ETIMEDOUT;
- }
-
- return 0;
-}
-
-/*
- * Set S3C2412 I2S DAI format
- */
-static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
- unsigned int fmt)
-{
- struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
- u32 iismod;
-
- pr_debug("Entered %s\n", __func__);
-
- iismod = readl(i2s->regs + S3C2412_IISMOD);
- pr_debug("hw_params r: IISMOD: %x \n", iismod);
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- i2s->master = 0;
- iismod |= S3C2412_IISMOD_SLAVE;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- i2s->master = 1;
- iismod &= ~S3C2412_IISMOD_SLAVE;
- break;
- default:
- pr_err("unknwon master/slave format\n");
- return -EINVAL;
- }
-
- iismod &= ~S3C2412_IISMOD_SDF_MASK;
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_RIGHT_J:
- iismod |= S3C2412_IISMOD_LR_RLOW;
- iismod |= S3C2412_IISMOD_SDF_MSB;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iismod |= S3C2412_IISMOD_LR_RLOW;
- iismod |= S3C2412_IISMOD_SDF_LSB;
- break;
- case SND_SOC_DAIFMT_I2S:
- iismod &= ~S3C2412_IISMOD_LR_RLOW;
- iismod |= S3C2412_IISMOD_SDF_IIS;
- break;
- default:
- pr_err("Unknown data format\n");
- return -EINVAL;
- }
-
- writel(iismod, i2s->regs + S3C2412_IISMOD);
- pr_debug("hw_params w: IISMOD: %x \n", iismod);
- return 0;
-}
-
-static int s3c_i2sv2_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct s3c_i2sv2_info *i2s = to_info(dai);
- struct s3c_dma_params *dma_data;
- u32 iismod;
-
- pr_debug("Entered %s\n", __func__);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dma_data = i2s->dma_playback;
- else
- dma_data = i2s->dma_capture;
-
- snd_soc_dai_set_dma_data(dai, substream, dma_data);
-
- /* Working copies of register */
- iismod = readl(i2s->regs + S3C2412_IISMOD);
- pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);
-
- iismod &= ~S3C64XX_IISMOD_BLC_MASK;
- /* Sample size */
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S8:
- iismod |= S3C64XX_IISMOD_BLC_8BIT;
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- iismod |= S3C64XX_IISMOD_BLC_24BIT;
- break;
- }
-
- writel(iismod, i2s->regs + S3C2412_IISMOD);
- pr_debug("%s: w: IISMOD: %x\n", __func__, iismod);
-
- return 0;
-}
-
-static int s3c_i2sv2_set_sysclk(struct snd_soc_dai *cpu_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
- u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
-
- pr_debug("Entered %s\n", __func__);
- pr_debug("%s r: IISMOD: %x\n", __func__, iismod);
-
- switch (clk_id) {
- case S3C_I2SV2_CLKSRC_PCLK:
- iismod &= ~S3C2412_IISMOD_IMS_SYSMUX;
- break;
-
- case S3C_I2SV2_CLKSRC_AUDIOBUS:
- iismod |= S3C2412_IISMOD_IMS_SYSMUX;
- break;
-
- case S3C_I2SV2_CLKSRC_CDCLK:
- /* Error if controller doesn't have the CDCLKCON bit */
- if (!(i2s->feature & S3C_FEATURE_CDCLKCON))
- return -EINVAL;
-
- switch (dir) {
- case SND_SOC_CLOCK_IN:
- iismod |= S3C64XX_IISMOD_CDCLKCON;
- break;
- case SND_SOC_CLOCK_OUT:
- iismod &= ~S3C64XX_IISMOD_CDCLKCON;
- break;
- default:
- return -EINVAL;
- }
- break;
-
- default:
- return -EINVAL;
- }
-
- writel(iismod, i2s->regs + S3C2412_IISMOD);
- pr_debug("%s w: IISMOD: %x\n", __func__, iismod);
-
- return 0;
-}
-
-static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct s3c_i2sv2_info *i2s = to_info(rtd->cpu_dai);
- int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
- unsigned long irqs;
- int ret = 0;
- struct s3c_dma_params *dma_data =
- snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
- pr_debug("Entered %s\n", __func__);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- /* On start, ensure that the FIFOs are cleared and reset. */
-
- writel(capture ? S3C2412_IISFIC_RXFLUSH : S3C2412_IISFIC_TXFLUSH,
- i2s->regs + S3C2412_IISFIC);
-
- /* clear again, just in case */
- writel(0x0, i2s->regs + S3C2412_IISFIC);
-
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (!i2s->master) {
- ret = s3c2412_snd_lrsync(i2s);
- if (ret)
- goto exit_err;
- }
-
- local_irq_save(irqs);
-
- if (capture)
- s3c2412_snd_rxctrl(i2s, 1);
- else
- s3c2412_snd_txctrl(i2s, 1);
-
- local_irq_restore(irqs);
-
- /*
- * Load the next buffer to DMA to meet the reqirement
- * of the auto reload mechanism of S3C24XX.
- * This call won't bother S3C64XX.
- */
- s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
-
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- local_irq_save(irqs);
-
- if (capture)
- s3c2412_snd_rxctrl(i2s, 0);
- else
- s3c2412_snd_txctrl(i2s, 0);
-
- local_irq_restore(irqs);
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
-exit_err:
- return ret;
-}
-
-/*
- * Set S3C2412 Clock dividers
- */
-static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
- int div_id, int div)
-{
- struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
- u32 reg;
-
- pr_debug("%s(%p, %d, %d)\n", __func__, cpu_dai, div_id, div);
-
- switch (div_id) {
- case S3C_I2SV2_DIV_BCLK:
- switch (div) {
- case 16:
- div = S3C2412_IISMOD_BCLK_16FS;
- break;
-
- case 32:
- div = S3C2412_IISMOD_BCLK_32FS;
- break;
-
- case 24:
- div = S3C2412_IISMOD_BCLK_24FS;
- break;
-
- case 48:
- div = S3C2412_IISMOD_BCLK_48FS;
- break;
-
- default:
- return -EINVAL;
- }
-
- reg = readl(i2s->regs + S3C2412_IISMOD);
- reg &= ~S3C2412_IISMOD_BCLK_MASK;
- writel(reg | div, i2s->regs + S3C2412_IISMOD);
-
- pr_debug("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD));
- break;
-
- case S3C_I2SV2_DIV_RCLK:
- switch (div) {
- case 256:
- div = S3C2412_IISMOD_RCLK_256FS;
- break;
-
- case 384:
- div = S3C2412_IISMOD_RCLK_384FS;
- break;
-
- case 512:
- div = S3C2412_IISMOD_RCLK_512FS;
- break;
-
- case 768:
- div = S3C2412_IISMOD_RCLK_768FS;
- break;
-
- default:
- return -EINVAL;
- }
-
- reg = readl(i2s->regs + S3C2412_IISMOD);
- reg &= ~S3C2412_IISMOD_RCLK_MASK;
- writel(reg | div, i2s->regs + S3C2412_IISMOD);
- pr_debug("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD));
- break;
-
- case S3C_I2SV2_DIV_PRESCALER:
- if (div >= 0) {
- writel((div << 8) | S3C2412_IISPSR_PSREN,
- i2s->regs + S3C2412_IISPSR);
- } else {
- writel(0x0, i2s->regs + S3C2412_IISPSR);
- }
- pr_debug("%s: PSR=%08x\n", __func__, readl(i2s->regs + S3C2412_IISPSR));
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static snd_pcm_sframes_t s3c2412_i2s_delay(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct s3c_i2sv2_info *i2s = to_info(dai);
- u32 reg = readl(i2s->regs + S3C2412_IISFIC);
- snd_pcm_sframes_t delay;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- delay = S3C2412_IISFIC_TXCOUNT(reg);
- else
- delay = S3C2412_IISFIC_RXCOUNT(reg);
-
- return delay;
-}
-
-struct clk *s3c_i2sv2_get_clock(struct snd_soc_dai *cpu_dai)
-{
- struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
- u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
-
- if (iismod & S3C2412_IISMOD_IMS_SYSMUX)
- return i2s->iis_cclk;
- else
- return i2s->iis_pclk;
-}
-EXPORT_SYMBOL_GPL(s3c_i2sv2_get_clock);
-
-/* default table of all avaialable root fs divisors */
-static unsigned int iis_fs_tab[] = { 256, 512, 384, 768 };
-
-int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info,
- unsigned int *fstab,
- unsigned int rate, struct clk *clk)
-{
- unsigned long clkrate = clk_get_rate(clk);
- unsigned int div;
- unsigned int fsclk;
- unsigned int actual;
- unsigned int fs;
- unsigned int fsdiv;
- signed int deviation = 0;
- unsigned int best_fs = 0;
- unsigned int best_div = 0;
- unsigned int best_rate = 0;
- unsigned int best_deviation = INT_MAX;
-
- pr_debug("Input clock rate %ldHz\n", clkrate);
-
- if (fstab == NULL)
- fstab = iis_fs_tab;
-
- for (fs = 0; fs < ARRAY_SIZE(iis_fs_tab); fs++) {
- fsdiv = iis_fs_tab[fs];
-
- fsclk = clkrate / fsdiv;
- div = fsclk / rate;
-
- if ((fsclk % rate) > (rate / 2))
- div++;
-
- if (div <= 1)
- continue;
-
- actual = clkrate / (fsdiv * div);
- deviation = actual - rate;
-
- printk(KERN_DEBUG "%ufs: div %u => result %u, deviation %d\n",
- fsdiv, div, actual, deviation);
-
- deviation = abs(deviation);
-
- if (deviation < best_deviation) {
- best_fs = fsdiv;
- best_div = div;
- best_rate = actual;
- best_deviation = deviation;
- }
-
- if (deviation == 0)
- break;
- }
-
- printk(KERN_DEBUG "best: fs=%u, div=%u, rate=%u\n",
- best_fs, best_div, best_rate);
-
- info->fs_div = best_fs;
- info->clk_div = best_div;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(s3c_i2sv2_iis_calc_rate);
-
-int s3c_i2sv2_probe(struct snd_soc_dai *dai,
- struct s3c_i2sv2_info *i2s,
- unsigned long base)
-{
- struct device *dev = dai->dev;
- unsigned int iismod;
-
- i2s->dev = dev;
-
- /* record our i2s structure for later use in the callbacks */
- snd_soc_dai_set_drvdata(dai, i2s);
-
- i2s->regs = ioremap(base, 0x100);
- if (i2s->regs == NULL) {
- dev_err(dev, "cannot ioremap registers\n");
- return -ENXIO;
- }
-
- i2s->iis_pclk = clk_get(dev, "iis");
- if (IS_ERR(i2s->iis_pclk)) {
- dev_err(dev, "failed to get iis_clock\n");
- iounmap(i2s->regs);
- return -ENOENT;
- }
-
- clk_enable(i2s->iis_pclk);
-
- /* Mark ourselves as in TXRX mode so we can run through our cleanup
- * process without warnings. */
- iismod = readl(i2s->regs + S3C2412_IISMOD);
- iismod |= S3C2412_IISMOD_MODE_TXRX;
- writel(iismod, i2s->regs + S3C2412_IISMOD);
- s3c2412_snd_txctrl(i2s, 0);
- s3c2412_snd_rxctrl(i2s, 0);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(s3c_i2sv2_probe);
-
-#ifdef CONFIG_PM
-static int s3c2412_i2s_suspend(struct snd_soc_dai *dai)
-{
- struct s3c_i2sv2_info *i2s = to_info(dai);
- u32 iismod;
-
- if (dai->active) {
- i2s->suspend_iismod = readl(i2s->regs + S3C2412_IISMOD);
- i2s->suspend_iiscon = readl(i2s->regs + S3C2412_IISCON);
- i2s->suspend_iispsr = readl(i2s->regs + S3C2412_IISPSR);
-
- /* some basic suspend checks */
-
- iismod = readl(i2s->regs + S3C2412_IISMOD);
-
- if (iismod & S3C2412_IISCON_RXDMA_ACTIVE)
- pr_warning("%s: RXDMA active?\n", __func__);
-
- if (iismod & S3C2412_IISCON_TXDMA_ACTIVE)
- pr_warning("%s: TXDMA active?\n", __func__);
-
- if (iismod & S3C2412_IISCON_IIS_ACTIVE)
- pr_warning("%s: IIS active\n", __func__);
- }
-
- return 0;
-}
-
-static int s3c2412_i2s_resume(struct snd_soc_dai *dai)
-{
- struct s3c_i2sv2_info *i2s = to_info(dai);
-
- pr_info("dai_active %d, IISMOD %08x, IISCON %08x\n",
- dai->active, i2s->suspend_iismod, i2s->suspend_iiscon);
-
- if (dai->active) {
- writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON);
- writel(i2s->suspend_iismod, i2s->regs + S3C2412_IISMOD);
- writel(i2s->suspend_iispsr, i2s->regs + S3C2412_IISPSR);
-
- writel(S3C2412_IISFIC_RXFLUSH | S3C2412_IISFIC_TXFLUSH,
- i2s->regs + S3C2412_IISFIC);
-
- ndelay(250);
- writel(0x0, i2s->regs + S3C2412_IISFIC);
- }
-
- return 0;
-}
-#else
-#define s3c2412_i2s_suspend NULL
-#define s3c2412_i2s_resume NULL
-#endif
-
-int s3c_i2sv2_register_dai(struct device *dev, int id,
- struct snd_soc_dai_driver *drv)
-{
- struct snd_soc_dai_ops *ops = drv->ops;
-
- ops->trigger = s3c2412_i2s_trigger;
- if (!ops->hw_params)
- ops->hw_params = s3c_i2sv2_hw_params;
- ops->set_fmt = s3c2412_i2s_set_fmt;
- ops->set_clkdiv = s3c2412_i2s_set_clkdiv;
- ops->set_sysclk = s3c_i2sv2_set_sysclk;
-
- /* Allow overriding by (for example) IISv4 */
- if (!ops->delay)
- ops->delay = s3c2412_i2s_delay;
-
- drv->suspend = s3c2412_i2s_suspend;
- drv->resume = s3c2412_i2s_resume;
-
- return snd_soc_register_dai(dev, drv);
-}
-EXPORT_SYMBOL_GPL(s3c_i2sv2_register_dai);
-
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/s3c-i2s-v2.h b/ANDROID_3.4.5/sound/soc/samsung/s3c-i2s-v2.h
deleted file mode 100644
index f8297d9b..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/s3c-i2s-v2.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* sound/soc/samsung/s3c-i2s-v2.h
- *
- * ALSA Soc Audio Layer - S3C_I2SV2 I2S driver
- *
- * Copyright (c) 2007 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
-*/
-
-/* This code is the core support for the I2S block found in a number of
- * Samsung SoC devices which is unofficially named I2S-V2. Currently the
- * S3C2412 and the S3C64XX series use this block to provide 1 or 2 I2S
- * channels via configurable GPIO.
- */
-
-#ifndef __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H
-#define __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H __FILE__
-
-#define S3C_I2SV2_DIV_BCLK (1)
-#define S3C_I2SV2_DIV_RCLK (2)
-#define S3C_I2SV2_DIV_PRESCALER (3)
-
-#define S3C_I2SV2_CLKSRC_PCLK 0
-#define S3C_I2SV2_CLKSRC_AUDIOBUS 1
-#define S3C_I2SV2_CLKSRC_CDCLK 2
-
-/* Set this flag for I2S controllers that have the bit IISMOD[12]
- * bridge/break RCLK signal and external Xi2sCDCLK pin.
- */
-#define S3C_FEATURE_CDCLKCON (1 << 0)
-
-/**
- * struct s3c_i2sv2_info - S3C I2S-V2 information
- * @dev: The parent device passed to use from the probe.
- * @regs: The pointer to the device registe block.
- * @feature: Set of bit-flags indicating features of the controller.
- * @master: True if the I2S core is the I2S bit clock master.
- * @dma_playback: DMA information for playback channel.
- * @dma_capture: DMA information for capture channel.
- * @suspend_iismod: PM save for the IISMOD register.
- * @suspend_iiscon: PM save for the IISCON register.
- * @suspend_iispsr: PM save for the IISPSR register.
- *
- * This is the private codec state for the hardware associated with an
- * I2S channel such as the register mappings and clock sources.
- */
-struct s3c_i2sv2_info {
- struct device *dev;
- void __iomem *regs;
-
- u32 feature;
-
- struct clk *iis_pclk;
- struct clk *iis_cclk;
-
- unsigned char master;
-
- struct s3c_dma_params *dma_playback;
- struct s3c_dma_params *dma_capture;
-
- u32 suspend_iismod;
- u32 suspend_iiscon;
- u32 suspend_iispsr;
-
- unsigned long base;
-};
-
-extern struct clk *s3c_i2sv2_get_clock(struct snd_soc_dai *cpu_dai);
-
-struct s3c_i2sv2_rate_calc {
- unsigned int clk_div; /* for prescaler */
- unsigned int fs_div; /* for root frame clock */
-};
-
-extern int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info,
- unsigned int *fstab,
- unsigned int rate, struct clk *clk);
-
-/**
- * s3c_i2sv2_probe - probe for i2s device helper
- * @dai: The ASoC DAI structure supplied to the original probe.
- * @i2s: Our local i2s structure to fill in.
- * @base: The base address for the registers.
- */
-extern int s3c_i2sv2_probe(struct snd_soc_dai *dai,
- struct s3c_i2sv2_info *i2s,
- unsigned long base);
-
-/**
- * s3c_i2sv2_register_dai - register dai with soc core
- * @dev: DAI device
- * @id: DAI ID
- * @drv: The driver structure to register
- *
- * Fill in any missing fields and then register the given dai with the
- * soc core.
- */
-extern int s3c_i2sv2_register_dai(struct device *dev, int id,
- struct snd_soc_dai_driver *drv);
-
-#endif /* __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H */
diff --git a/ANDROID_3.4.5/sound/soc/samsung/s3c2412-i2s.c b/ANDROID_3.4.5/sound/soc/samsung/s3c2412-i2s.c
deleted file mode 100644
index 79fbeea9..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/s3c2412-i2s.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/* sound/soc/samsung/s3c2412-i2s.c
- *
- * ALSA Soc Audio Layer - S3C2412 I2S driver
- *
- * Copyright (c) 2006 Wolfson Microelectronics PLC.
- * Graeme Gregory graeme.gregory@wolfsonmicro.com
- * linux@wolfsonmicro.com
- *
- * Copyright (c) 2007, 2004-2005 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/module.h>
-
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <mach/regs-gpio.h>
-#include <mach/dma.h>
-
-#include "dma.h"
-#include "regs-i2s-v2.h"
-#include "s3c2412-i2s.h"
-
-static struct s3c2410_dma_client s3c2412_dma_client_out = {
- .name = "I2S PCM Stereo out"
-};
-
-static struct s3c2410_dma_client s3c2412_dma_client_in = {
- .name = "I2S PCM Stereo in"
-};
-
-static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = {
- .client = &s3c2412_dma_client_out,
- .channel = DMACH_I2S_OUT,
- .dma_addr = S3C2410_PA_IIS + S3C2412_IISTXD,
- .dma_size = 4,
-};
-
-static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = {
- .client = &s3c2412_dma_client_in,
- .channel = DMACH_I2S_IN,
- .dma_addr = S3C2410_PA_IIS + S3C2412_IISRXD,
- .dma_size = 4,
-};
-
-static struct s3c_i2sv2_info s3c2412_i2s;
-
-static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
-{
- int ret;
-
- pr_debug("Entered %s\n", __func__);
-
- ret = s3c_i2sv2_probe(dai, &s3c2412_i2s, S3C2410_PA_IIS);
- if (ret)
- return ret;
-
- s3c2412_i2s.dma_capture = &s3c2412_i2s_pcm_stereo_in;
- s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out;
-
- s3c2412_i2s.iis_cclk = clk_get(dai->dev, "i2sclk");
- if (IS_ERR(s3c2412_i2s.iis_cclk)) {
- pr_err("failed to get i2sclk clock\n");
- iounmap(s3c2412_i2s.regs);
- return PTR_ERR(s3c2412_i2s.iis_cclk);
- }
-
- /* Set MPLL as the source for IIS CLK */
-
- clk_set_parent(s3c2412_i2s.iis_cclk, clk_get(NULL, "mpll"));
- clk_enable(s3c2412_i2s.iis_cclk);
-
- s3c2412_i2s.iis_cclk = s3c2412_i2s.iis_pclk;
-
- /* Configure the I2S pins in correct mode */
- s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK);
- s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2410_GPE1_I2SSCLK);
- s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2410_GPE2_CDCLK);
- s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI);
- s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO);
-
- return 0;
-}
-
-static int s3c2412_i2s_remove(struct snd_soc_dai *dai)
-{
- clk_disable(s3c2412_i2s.iis_cclk);
- clk_put(s3c2412_i2s.iis_cclk);
- iounmap(s3c2412_i2s.regs);
-
- return 0;
-}
-
-static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *cpu_dai)
-{
- struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai);
- struct s3c_dma_params *dma_data;
- u32 iismod;
-
- pr_debug("Entered %s\n", __func__);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dma_data = i2s->dma_playback;
- else
- dma_data = i2s->dma_capture;
-
- snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
-
- iismod = readl(i2s->regs + S3C2412_IISMOD);
- pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S8:
- iismod |= S3C2412_IISMOD_8BIT;
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- iismod &= ~S3C2412_IISMOD_8BIT;
- break;
- }
-
- writel(iismod, i2s->regs + S3C2412_IISMOD);
- pr_debug("%s: w: IISMOD: %x\n", __func__, iismod);
-
- return 0;
-}
-
-#define S3C2412_I2S_RATES \
- (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
- SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
-
-static const struct snd_soc_dai_ops s3c2412_i2s_dai_ops = {
- .hw_params = s3c2412_i2s_hw_params,
-};
-
-static struct snd_soc_dai_driver s3c2412_i2s_dai = {
- .probe = s3c2412_i2s_probe,
- .remove = s3c2412_i2s_remove,
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = S3C2412_I2S_RATES,
- .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,
- },
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = S3C2412_I2S_RATES,
- .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,
- },
- .ops = &s3c2412_i2s_dai_ops,
-};
-
-static __devinit int s3c2412_iis_dev_probe(struct platform_device *pdev)
-{
- return s3c_i2sv2_register_dai(&pdev->dev, -1, &s3c2412_i2s_dai);
-}
-
-static __devexit int s3c2412_iis_dev_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_dai(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver s3c2412_iis_driver = {
- .probe = s3c2412_iis_dev_probe,
- .remove = __devexit_p(s3c2412_iis_dev_remove),
- .driver = {
- .name = "s3c2412-iis",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(s3c2412_iis_driver);
-
-/* Module information */
-MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
-MODULE_DESCRIPTION("S3C2412 I2S SoC Interface");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:s3c2412-iis");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/s3c2412-i2s.h b/ANDROID_3.4.5/sound/soc/samsung/s3c2412-i2s.h
deleted file mode 100644
index 02ad5794..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/s3c2412-i2s.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* sound/soc/samsung/s3c2412-i2s.c
- *
- * ALSA Soc Audio Layer - S3C2412 I2S driver
- *
- * Copyright (c) 2007 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
-*/
-
-#ifndef __SND_SOC_S3C24XX_S3C2412_I2S_H
-#define __SND_SOC_S3C24XX_S3C2412_I2S_H __FILE__
-
-#include "s3c-i2s-v2.h"
-
-#define S3C2412_DIV_BCLK S3C_I2SV2_DIV_BCLK
-#define S3C2412_DIV_RCLK S3C_I2SV2_DIV_RCLK
-#define S3C2412_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER
-
-#define S3C2412_CLKSRC_PCLK S3C_I2SV2_CLKSRC_PCLK
-#define S3C2412_CLKSRC_I2SCLK S3C_I2SV2_CLKSRC_AUDIOBUS
-
-#endif /* __SND_SOC_S3C24XX_S3C2412_I2S_H */
diff --git a/ANDROID_3.4.5/sound/soc/samsung/s3c24xx-i2s.c b/ANDROID_3.4.5/sound/soc/samsung/s3c24xx-i2s.c
deleted file mode 100644
index c4aa4d41..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/s3c24xx-i2s.c
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * s3c24xx-i2s.c -- ALSA Soc Audio Layer
- *
- * (c) 2006 Wolfson Microelectronics PLC.
- * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
- *
- * Copyright 2004-2005 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/module.h>
-
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <mach/regs-gpio.h>
-#include <mach/dma.h>
-#include <plat/regs-iis.h>
-
-#include "dma.h"
-#include "s3c24xx-i2s.h"
-
-static struct s3c2410_dma_client s3c24xx_dma_client_out = {
- .name = "I2S PCM Stereo out"
-};
-
-static struct s3c2410_dma_client s3c24xx_dma_client_in = {
- .name = "I2S PCM Stereo in"
-};
-
-static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = {
- .client = &s3c24xx_dma_client_out,
- .channel = DMACH_I2S_OUT,
- .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO,
- .dma_size = 2,
-};
-
-static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = {
- .client = &s3c24xx_dma_client_in,
- .channel = DMACH_I2S_IN,
- .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO,
- .dma_size = 2,
-};
-
-struct s3c24xx_i2s_info {
- void __iomem *regs;
- struct clk *iis_clk;
- u32 iiscon;
- u32 iismod;
- u32 iisfcon;
- u32 iispsr;
-};
-static struct s3c24xx_i2s_info s3c24xx_i2s;
-
-static void s3c24xx_snd_txctrl(int on)
-{
- u32 iisfcon;
- u32 iiscon;
- u32 iismod;
-
- pr_debug("Entered %s\n", __func__);
-
- iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON);
- iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON);
- iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
-
- pr_debug("r: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon);
-
- if (on) {
- iisfcon |= S3C2410_IISFCON_TXDMA | S3C2410_IISFCON_TXENABLE;
- iiscon |= S3C2410_IISCON_TXDMAEN | S3C2410_IISCON_IISEN;
- iiscon &= ~S3C2410_IISCON_TXIDLE;
- iismod |= S3C2410_IISMOD_TXMODE;
-
- writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
- writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON);
- writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON);
- } else {
- /* note, we have to disable the FIFOs otherwise bad things
- * seem to happen when the DMA stops. According to the
- * Samsung supplied kernel, this should allow the DMA
- * engine and FIFOs to reset. If this isn't allowed, the
- * DMA engine will simply freeze randomly.
- */
-
- iisfcon &= ~S3C2410_IISFCON_TXENABLE;
- iisfcon &= ~S3C2410_IISFCON_TXDMA;
- iiscon |= S3C2410_IISCON_TXIDLE;
- iiscon &= ~S3C2410_IISCON_TXDMAEN;
- iismod &= ~S3C2410_IISMOD_TXMODE;
-
- writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON);
- writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON);
- writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
- }
-
- pr_debug("w: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon);
-}
-
-static void s3c24xx_snd_rxctrl(int on)
-{
- u32 iisfcon;
- u32 iiscon;
- u32 iismod;
-
- pr_debug("Entered %s\n", __func__);
-
- iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON);
- iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON);
- iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
-
- pr_debug("r: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon);
-
- if (on) {
- iisfcon |= S3C2410_IISFCON_RXDMA | S3C2410_IISFCON_RXENABLE;
- iiscon |= S3C2410_IISCON_RXDMAEN | S3C2410_IISCON_IISEN;
- iiscon &= ~S3C2410_IISCON_RXIDLE;
- iismod |= S3C2410_IISMOD_RXMODE;
-
- writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
- writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON);
- writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON);
- } else {
- /* note, we have to disable the FIFOs otherwise bad things
- * seem to happen when the DMA stops. According to the
- * Samsung supplied kernel, this should allow the DMA
- * engine and FIFOs to reset. If this isn't allowed, the
- * DMA engine will simply freeze randomly.
- */
-
- iisfcon &= ~S3C2410_IISFCON_RXENABLE;
- iisfcon &= ~S3C2410_IISFCON_RXDMA;
- iiscon |= S3C2410_IISCON_RXIDLE;
- iiscon &= ~S3C2410_IISCON_RXDMAEN;
- iismod &= ~S3C2410_IISMOD_RXMODE;
-
- writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON);
- writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON);
- writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
- }
-
- pr_debug("w: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon);
-}
-
-/*
- * Wait for the LR signal to allow synchronisation to the L/R clock
- * from the codec. May only be needed for slave mode.
- */
-static int s3c24xx_snd_lrsync(void)
-{
- u32 iiscon;
- int timeout = 50; /* 5ms */
-
- pr_debug("Entered %s\n", __func__);
-
- while (1) {
- iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON);
- if (iiscon & S3C2410_IISCON_LRINDEX)
- break;
-
- if (!timeout--)
- return -ETIMEDOUT;
- udelay(100);
- }
-
- return 0;
-}
-
-/*
- * Check whether CPU is the master or slave
- */
-static inline int s3c24xx_snd_is_clkmaster(void)
-{
- pr_debug("Entered %s\n", __func__);
-
- return (readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & S3C2410_IISMOD_SLAVE) ? 0:1;
-}
-
-/*
- * Set S3C24xx I2S DAI format
- */
-static int s3c24xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
- unsigned int fmt)
-{
- u32 iismod;
-
- pr_debug("Entered %s\n", __func__);
-
- iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
- pr_debug("hw_params r: IISMOD: %x \n", iismod);
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- iismod |= S3C2410_IISMOD_SLAVE;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- iismod &= ~S3C2410_IISMOD_SLAVE;
- break;
- default:
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_LEFT_J:
- iismod |= S3C2410_IISMOD_MSB;
- break;
- case SND_SOC_DAIFMT_I2S:
- iismod &= ~S3C2410_IISMOD_MSB;
- break;
- default:
- return -EINVAL;
- }
-
- writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
- pr_debug("hw_params w: IISMOD: %x \n", iismod);
- return 0;
-}
-
-static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct s3c_dma_params *dma_data;
- u32 iismod;
-
- pr_debug("Entered %s\n", __func__);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dma_data = &s3c24xx_i2s_pcm_stereo_out;
- else
- dma_data = &s3c24xx_i2s_pcm_stereo_in;
-
- snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data);
-
- /* Working copies of register */
- iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
- pr_debug("hw_params r: IISMOD: %x\n", iismod);
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S8:
- iismod &= ~S3C2410_IISMOD_16BIT;
- dma_data->dma_size = 1;
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- iismod |= S3C2410_IISMOD_16BIT;
- dma_data->dma_size = 2;
- break;
- default:
- return -EINVAL;
- }
-
- writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
- pr_debug("hw_params w: IISMOD: %x\n", iismod);
- return 0;
-}
-
-static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- int ret = 0;
- struct s3c_dma_params *dma_data =
- snd_soc_dai_get_dma_data(dai, substream);
-
- pr_debug("Entered %s\n", __func__);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (!s3c24xx_snd_is_clkmaster()) {
- ret = s3c24xx_snd_lrsync();
- if (ret)
- goto exit_err;
- }
-
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- s3c24xx_snd_rxctrl(1);
- else
- s3c24xx_snd_txctrl(1);
-
- s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- s3c24xx_snd_rxctrl(0);
- else
- s3c24xx_snd_txctrl(0);
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
-exit_err:
- return ret;
-}
-
-/*
- * Set S3C24xx Clock source
- */
-static int s3c24xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
- int clk_id, unsigned int freq, int dir)
-{
- u32 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
-
- pr_debug("Entered %s\n", __func__);
-
- iismod &= ~S3C2440_IISMOD_MPLL;
-
- switch (clk_id) {
- case S3C24XX_CLKSRC_PCLK:
- break;
- case S3C24XX_CLKSRC_MPLL:
- iismod |= S3C2440_IISMOD_MPLL;
- break;
- default:
- return -EINVAL;
- }
-
- writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
- return 0;
-}
-
-/*
- * Set S3C24xx Clock dividers
- */
-static int s3c24xx_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
- int div_id, int div)
-{
- u32 reg;
-
- pr_debug("Entered %s\n", __func__);
-
- switch (div_id) {
- case S3C24XX_DIV_BCLK:
- reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~S3C2410_IISMOD_FS_MASK;
- writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD);
- break;
- case S3C24XX_DIV_MCLK:
- reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~(S3C2410_IISMOD_384FS);
- writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD);
- break;
- case S3C24XX_DIV_PRESCALER:
- writel(div, s3c24xx_i2s.regs + S3C2410_IISPSR);
- reg = readl(s3c24xx_i2s.regs + S3C2410_IISCON);
- writel(reg | S3C2410_IISCON_PSCEN, s3c24xx_i2s.regs + S3C2410_IISCON);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * To avoid duplicating clock code, allow machine driver to
- * get the clockrate from here.
- */
-u32 s3c24xx_i2s_get_clockrate(void)
-{
- return clk_get_rate(s3c24xx_i2s.iis_clk);
-}
-EXPORT_SYMBOL_GPL(s3c24xx_i2s_get_clockrate);
-
-static int s3c24xx_i2s_probe(struct snd_soc_dai *dai)
-{
- pr_debug("Entered %s\n", __func__);
-
- s3c24xx_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100);
- if (s3c24xx_i2s.regs == NULL)
- return -ENXIO;
-
- s3c24xx_i2s.iis_clk = clk_get(dai->dev, "iis");
- if (IS_ERR(s3c24xx_i2s.iis_clk)) {
- pr_err("failed to get iis_clock\n");
- iounmap(s3c24xx_i2s.regs);
- return PTR_ERR(s3c24xx_i2s.iis_clk);
- }
- clk_enable(s3c24xx_i2s.iis_clk);
-
- /* Configure the I2S pins in correct mode */
- s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK);
- s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2410_GPE1_I2SSCLK);
- s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2410_GPE2_CDCLK);
- s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI);
- s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO);
-
- writel(S3C2410_IISCON_IISEN, s3c24xx_i2s.regs + S3C2410_IISCON);
-
- s3c24xx_snd_txctrl(0);
- s3c24xx_snd_rxctrl(0);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int s3c24xx_i2s_suspend(struct snd_soc_dai *cpu_dai)
-{
- pr_debug("Entered %s\n", __func__);
-
- s3c24xx_i2s.iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON);
- s3c24xx_i2s.iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
- s3c24xx_i2s.iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON);
- s3c24xx_i2s.iispsr = readl(s3c24xx_i2s.regs + S3C2410_IISPSR);
-
- clk_disable(s3c24xx_i2s.iis_clk);
-
- return 0;
-}
-
-static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai)
-{
- pr_debug("Entered %s\n", __func__);
- clk_enable(s3c24xx_i2s.iis_clk);
-
- writel(s3c24xx_i2s.iiscon, s3c24xx_i2s.regs + S3C2410_IISCON);
- writel(s3c24xx_i2s.iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
- writel(s3c24xx_i2s.iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON);
- writel(s3c24xx_i2s.iispsr, s3c24xx_i2s.regs + S3C2410_IISPSR);
-
- return 0;
-}
-#else
-#define s3c24xx_i2s_suspend NULL
-#define s3c24xx_i2s_resume NULL
-#endif
-
-
-#define S3C24XX_I2S_RATES \
- (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
- SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
-
-static const struct snd_soc_dai_ops s3c24xx_i2s_dai_ops = {
- .trigger = s3c24xx_i2s_trigger,
- .hw_params = s3c24xx_i2s_hw_params,
- .set_fmt = s3c24xx_i2s_set_fmt,
- .set_clkdiv = s3c24xx_i2s_set_clkdiv,
- .set_sysclk = s3c24xx_i2s_set_sysclk,
-};
-
-static struct snd_soc_dai_driver s3c24xx_i2s_dai = {
- .probe = s3c24xx_i2s_probe,
- .suspend = s3c24xx_i2s_suspend,
- .resume = s3c24xx_i2s_resume,
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = S3C24XX_I2S_RATES,
- .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,},
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = S3C24XX_I2S_RATES,
- .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,},
- .ops = &s3c24xx_i2s_dai_ops,
-};
-
-static __devinit int s3c24xx_iis_dev_probe(struct platform_device *pdev)
-{
- return snd_soc_register_dai(&pdev->dev, &s3c24xx_i2s_dai);
-}
-
-static __devexit int s3c24xx_iis_dev_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_dai(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver s3c24xx_iis_driver = {
- .probe = s3c24xx_iis_dev_probe,
- .remove = __devexit_p(s3c24xx_iis_dev_remove),
- .driver = {
- .name = "s3c24xx-iis",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(s3c24xx_iis_driver);
-
-/* Module information */
-MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
-MODULE_DESCRIPTION("s3c24xx I2S SoC Interface");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:s3c24xx-iis");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/s3c24xx-i2s.h b/ANDROID_3.4.5/sound/soc/samsung/s3c24xx-i2s.h
deleted file mode 100644
index f9ca04ed..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/s3c24xx-i2s.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * s3c24xx-i2s.c -- ALSA Soc Audio Layer
- *
- * Copyright 2005 Wolfson Microelectronics PLC.
- * Author: Graeme Gregory
- * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * Revision history
- * 10th Nov 2006 Initial version.
- */
-
-#ifndef S3C24XXI2S_H_
-#define S3C24XXI2S_H_
-
-/* clock sources */
-#define S3C24XX_CLKSRC_PCLK 0
-#define S3C24XX_CLKSRC_MPLL 1
-
-/* Clock dividers */
-#define S3C24XX_DIV_MCLK 0
-#define S3C24XX_DIV_BCLK 1
-#define S3C24XX_DIV_PRESCALER 2
-
-/* prescaler */
-#define S3C24XX_PRESCALE(a,b) \
- (((a - 1) << S3C2410_IISPSR_INTSHIFT) | ((b - 1) << S3C2410_IISPSR_EXTSHFIT))
-
-u32 s3c24xx_i2s_get_clockrate(void);
-
-#endif /*S3C24XXI2S_H_*/
diff --git a/ANDROID_3.4.5/sound/soc/samsung/s3c24xx_simtec.c b/ANDROID_3.4.5/sound/soc/samsung/s3c24xx_simtec.c
deleted file mode 100644
index 656d5afe..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/s3c24xx_simtec.c
+++ /dev/null
@@ -1,388 +0,0 @@
-/* sound/soc/samsung/s3c24xx_simtec.c
- *
- * Copyright 2009 Simtec Electronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/gpio.h>
-#include <linux/clk.h>
-#include <linux/module.h>
-
-#include <sound/soc.h>
-
-#include <plat/audio-simtec.h>
-
-#include "s3c24xx-i2s.h"
-#include "s3c24xx_simtec.h"
-
-static struct s3c24xx_audio_simtec_pdata *pdata;
-static struct clk *xtal_clk;
-
-static int spk_gain;
-static int spk_unmute;
-
-/**
- * speaker_gain_get - read the speaker gain setting.
- * @kcontrol: The control for the speaker gain.
- * @ucontrol: The value that needs to be updated.
- *
- * Read the value for the AMP gain control.
- */
-static int speaker_gain_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = spk_gain;
- return 0;
-}
-
-/**
- * speaker_gain_set - set the value of the speaker amp gain
- * @value: The value to write.
- */
-static void speaker_gain_set(int value)
-{
- gpio_set_value_cansleep(pdata->amp_gain[0], value & 1);
- gpio_set_value_cansleep(pdata->amp_gain[1], value >> 1);
-}
-
-/**
- * speaker_gain_put - set the speaker gain setting.
- * @kcontrol: The control for the speaker gain.
- * @ucontrol: The value that needs to be set.
- *
- * Set the value of the speaker gain from the specified
- * @ucontrol setting.
- *
- * Note, if the speaker amp is muted, then we do not set a gain value
- * as at-least one of the ICs that is fitted will try and power up even
- * if the main control is set to off.
- */
-static int speaker_gain_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- int value = ucontrol->value.integer.value[0];
-
- spk_gain = value;
-
- if (!spk_unmute)
- speaker_gain_set(value);
-
- return 0;
-}
-
-static const struct snd_kcontrol_new amp_gain_controls[] = {
- SOC_SINGLE_EXT("Speaker Gain", 0, 0, 3, 0,
- speaker_gain_get, speaker_gain_put),
-};
-
-/**
- * spk_unmute_state - set the unmute state of the speaker
- * @to: zero to unmute, non-zero to ununmute.
- */
-static void spk_unmute_state(int to)
-{
- pr_debug("%s: to=%d\n", __func__, to);
-
- spk_unmute = to;
- gpio_set_value(pdata->amp_gpio, to);
-
- /* if we're umuting, also re-set the gain */
- if (to && pdata->amp_gain[0] > 0)
- speaker_gain_set(spk_gain);
-}
-
-/**
- * speaker_unmute_get - read the speaker unmute setting.
- * @kcontrol: The control for the speaker gain.
- * @ucontrol: The value that needs to be updated.
- *
- * Read the value for the AMP gain control.
- */
-static int speaker_unmute_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = spk_unmute;
- return 0;
-}
-
-/**
- * speaker_unmute_put - set the speaker unmute setting.
- * @kcontrol: The control for the speaker gain.
- * @ucontrol: The value that needs to be set.
- *
- * Set the value of the speaker gain from the specified
- * @ucontrol setting.
- */
-static int speaker_unmute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- spk_unmute_state(ucontrol->value.integer.value[0]);
- return 0;
-}
-
-/* This is added as a manual control as the speaker amps create clicks
- * when their power state is changed, which are far more noticeable than
- * anything produced by the CODEC itself.
- */
-static const struct snd_kcontrol_new amp_unmute_controls[] = {
- SOC_SINGLE_EXT("Speaker Switch", 0, 0, 1, 0,
- speaker_unmute_get, speaker_unmute_put),
-};
-
-void simtec_audio_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_card *card = rtd->card;
-
- if (pdata->amp_gpio > 0) {
- pr_debug("%s: adding amp routes\n", __func__);
-
- snd_soc_add_card_controls(card, amp_unmute_controls,
- ARRAY_SIZE(amp_unmute_controls));
- }
-
- if (pdata->amp_gain[0] > 0) {
- pr_debug("%s: adding amp controls\n", __func__);
- snd_soc_add_card_controls(card, amp_gain_controls,
- ARRAY_SIZE(amp_gain_controls));
- }
-}
-EXPORT_SYMBOL_GPL(simtec_audio_init);
-
-#define CODEC_CLOCK 12000000
-
-/**
- * simtec_hw_params - update hardware parameters
- * @substream: The audio substream instance.
- * @params: The parameters requested.
- *
- * Update the codec data routing and configuration settings
- * from the supplied data.
- */
-static int simtec_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret;
-
- /* Set the CODEC as the bus clock master, I2S */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM);
- if (ret) {
- pr_err("%s: failed set cpu dai format\n", __func__);
- return ret;
- }
-
- /* Set the CODEC as the bus clock master */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM);
- if (ret) {
- pr_err("%s: failed set codec dai format\n", __func__);
- return ret;
- }
-
- ret = snd_soc_dai_set_sysclk(codec_dai, 0,
- CODEC_CLOCK, SND_SOC_CLOCK_IN);
- if (ret) {
- pr_err( "%s: failed setting codec sysclk\n", __func__);
- return ret;
- }
-
- if (pdata->use_mpllin) {
- ret = snd_soc_dai_set_sysclk(cpu_dai, S3C24XX_CLKSRC_MPLL,
- 0, SND_SOC_CLOCK_OUT);
-
- if (ret) {
- pr_err("%s: failed to set MPLLin as clksrc\n",
- __func__);
- return ret;
- }
- }
-
- if (pdata->output_cdclk) {
- int cdclk_scale;
-
- cdclk_scale = clk_get_rate(xtal_clk) / CODEC_CLOCK;
- cdclk_scale--;
-
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
- cdclk_scale);
- }
-
- return 0;
-}
-
-static int simtec_call_startup(struct s3c24xx_audio_simtec_pdata *pd)
-{
- /* call any board supplied startup code, this currently only
- * covers the bast/vr1000 which have a CPLD in the way of the
- * LRCLK */
- if (pd->startup)
- pd->startup();
-
- return 0;
-}
-
-static struct snd_soc_ops simtec_snd_ops = {
- .hw_params = simtec_hw_params,
-};
-
-/**
- * attach_gpio_amp - get and configure the necessary gpios
- * @dev: The device we're probing.
- * @pd: The platform data supplied by the board.
- *
- * If there is a GPIO based amplifier attached to the board, claim
- * the necessary GPIO lines for it, and set default values.
- */
-static int attach_gpio_amp(struct device *dev,
- struct s3c24xx_audio_simtec_pdata *pd)
-{
- int ret;
-
- /* attach gpio amp gain (if any) */
- if (pdata->amp_gain[0] > 0) {
- ret = gpio_request(pd->amp_gain[0], "gpio-amp-gain0");
- if (ret) {
- dev_err(dev, "cannot get amp gpio gain0\n");
- return ret;
- }
-
- ret = gpio_request(pd->amp_gain[1], "gpio-amp-gain1");
- if (ret) {
- dev_err(dev, "cannot get amp gpio gain1\n");
- gpio_free(pdata->amp_gain[0]);
- return ret;
- }
-
- gpio_direction_output(pd->amp_gain[0], 0);
- gpio_direction_output(pd->amp_gain[1], 0);
- }
-
- /* note, currently we assume GPA0 isn't valid amp */
- if (pdata->amp_gpio > 0) {
- ret = gpio_request(pd->amp_gpio, "gpio-amp");
- if (ret) {
- dev_err(dev, "cannot get amp gpio %d (%d)\n",
- pd->amp_gpio, ret);
- goto err_amp;
- }
-
- /* set the amp off at startup */
- spk_unmute_state(0);
- }
-
- return 0;
-
-err_amp:
- if (pd->amp_gain[0] > 0) {
- gpio_free(pd->amp_gain[0]);
- gpio_free(pd->amp_gain[1]);
- }
-
- return ret;
-}
-
-static void detach_gpio_amp(struct s3c24xx_audio_simtec_pdata *pd)
-{
- if (pd->amp_gain[0] > 0) {
- gpio_free(pd->amp_gain[0]);
- gpio_free(pd->amp_gain[1]);
- }
-
- if (pd->amp_gpio > 0)
- gpio_free(pd->amp_gpio);
-}
-
-#ifdef CONFIG_PM
-static int simtec_audio_resume(struct device *dev)
-{
- simtec_call_startup(pdata);
- return 0;
-}
-
-const struct dev_pm_ops simtec_audio_pmops = {
- .resume = simtec_audio_resume,
-};
-EXPORT_SYMBOL_GPL(simtec_audio_pmops);
-#endif
-
-int __devinit simtec_audio_core_probe(struct platform_device *pdev,
- struct snd_soc_card *card)
-{
- struct platform_device *snd_dev;
- int ret;
-
- card->dai_link->ops = &simtec_snd_ops;
-
- pdata = pdev->dev.platform_data;
- if (!pdata) {
- dev_err(&pdev->dev, "no platform data supplied\n");
- return -EINVAL;
- }
-
- simtec_call_startup(pdata);
-
- xtal_clk = clk_get(&pdev->dev, "xtal");
- if (IS_ERR(xtal_clk)) {
- dev_err(&pdev->dev, "could not get clkout0\n");
- return -EINVAL;
- }
-
- dev_info(&pdev->dev, "xtal rate is %ld\n", clk_get_rate(xtal_clk));
-
- ret = attach_gpio_amp(&pdev->dev, pdata);
- if (ret)
- goto err_clk;
-
- snd_dev = platform_device_alloc("soc-audio", -1);
- if (!snd_dev) {
- dev_err(&pdev->dev, "failed to alloc soc-audio devicec\n");
- ret = -ENOMEM;
- goto err_gpio;
- }
-
- platform_set_drvdata(snd_dev, card);
-
- ret = platform_device_add(snd_dev);
- if (ret) {
- dev_err(&pdev->dev, "failed to add soc-audio dev\n");
- goto err_pdev;
- }
-
- platform_set_drvdata(pdev, snd_dev);
- return 0;
-
-err_pdev:
- platform_device_put(snd_dev);
-
-err_gpio:
- detach_gpio_amp(pdata);
-
-err_clk:
- clk_put(xtal_clk);
- return ret;
-}
-EXPORT_SYMBOL_GPL(simtec_audio_core_probe);
-
-int __devexit simtec_audio_remove(struct platform_device *pdev)
-{
- struct platform_device *snd_dev = platform_get_drvdata(pdev);
-
- platform_device_unregister(snd_dev);
-
- detach_gpio_amp(pdata);
- clk_put(xtal_clk);
- return 0;
-}
-EXPORT_SYMBOL_GPL(simtec_audio_remove);
-
-MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
-MODULE_DESCRIPTION("ALSA SoC Simtec Audio common support");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/s3c24xx_simtec.h b/ANDROID_3.4.5/sound/soc/samsung/s3c24xx_simtec.h
deleted file mode 100644
index 8270748a..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/s3c24xx_simtec.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* sound/soc/samsung/s3c24xx_simtec.h
- *
- * Copyright 2009 Simtec Electronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-extern void simtec_audio_init(struct snd_soc_pcm_runtime *rtd);
-
-extern int simtec_audio_core_probe(struct platform_device *pdev,
- struct snd_soc_card *card);
-
-extern int simtec_audio_remove(struct platform_device *pdev);
-
-#ifdef CONFIG_PM
-extern const struct dev_pm_ops simtec_audio_pmops;
-#define simtec_audio_pm &simtec_audio_pmops
-#else
-#define simtec_audio_pm NULL
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/samsung/s3c24xx_simtec_hermes.c b/ANDROID_3.4.5/sound/soc/samsung/s3c24xx_simtec_hermes.c
deleted file mode 100644
index 7ace6a87..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/s3c24xx_simtec_hermes.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/* sound/soc/samsung/s3c24xx_simtec_hermes.c
- *
- * Copyright 2009 Simtec Electronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/module.h>
-#include <sound/soc.h>
-
-#include "s3c24xx_simtec.h"
-
-static const struct snd_soc_dapm_widget dapm_widgets[] = {
- SND_SOC_DAPM_LINE("GSM Out", NULL),
- SND_SOC_DAPM_LINE("GSM In", NULL),
- SND_SOC_DAPM_LINE("Line In", NULL),
- SND_SOC_DAPM_LINE("Line Out", NULL),
- SND_SOC_DAPM_LINE("ZV", NULL),
- SND_SOC_DAPM_MIC("Mic Jack", NULL),
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
-};
-
-static const struct snd_soc_dapm_route base_map[] = {
- /* Headphone connected to HP{L,R}OUT and HP{L,R}COM */
-
- { "Headphone Jack", NULL, "HPLOUT" },
- { "Headphone Jack", NULL, "HPLCOM" },
- { "Headphone Jack", NULL, "HPROUT" },
- { "Headphone Jack", NULL, "HPRCOM" },
-
- /* ZV connected to Line1 */
-
- { "LINE1L", NULL, "ZV" },
- { "LINE1R", NULL, "ZV" },
-
- /* Line In connected to Line2 */
-
- { "LINE2L", NULL, "Line In" },
- { "LINE2R", NULL, "Line In" },
-
- /* Microphone connected to MIC3R and MIC_BIAS */
-
- { "MIC3L", NULL, "Mic Jack" },
-
- /* GSM connected to MONO_LOUT and MIC3L (in) */
-
- { "GSM Out", NULL, "MONO_LOUT" },
- { "MIC3L", NULL, "GSM In" },
-
- /* Speaker is connected to LINEOUT{LN,LP,RN,RP}, however we are
- * not using the DAPM to power it up and down as there it makes
- * a click when powering up. */
-};
-
-/**
- * simtec_hermes_init - initialise and add controls
- * @codec; The codec instance to attach to.
- *
- * Attach our controls and configure the necessary codec
- * mappings for our sound card instance.
-*/
-static int simtec_hermes_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_enable_pin(dapm, "Line In");
- snd_soc_dapm_enable_pin(dapm, "Line Out");
- snd_soc_dapm_enable_pin(dapm, "Mic Jack");
-
- simtec_audio_init(rtd);
-
- return 0;
-}
-
-static struct snd_soc_dai_link simtec_dai_aic33 = {
- .name = "tlv320aic33",
- .stream_name = "TLV320AIC33",
- .codec_name = "tlv320aic3x-codec.0-001a",
- .cpu_dai_name = "s3c24xx-iis",
- .codec_dai_name = "tlv320aic3x-hifi",
- .platform_name = "samsung-audio",
- .init = simtec_hermes_init,
-};
-
-/* simtec audio machine driver */
-static struct snd_soc_card snd_soc_machine_simtec_aic33 = {
- .name = "Simtec-Hermes",
- .owner = THIS_MODULE,
- .dai_link = &simtec_dai_aic33,
- .num_links = 1,
-
- .dapm_widgets = dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(dapm_widgets),
- .dapm_routes = base_map,
- .num_dapm_routes = ARRAY_SIZE(base_map),
-};
-
-static int __devinit simtec_audio_hermes_probe(struct platform_device *pd)
-{
- dev_info(&pd->dev, "probing....\n");
- return simtec_audio_core_probe(pd, &snd_soc_machine_simtec_aic33);
-}
-
-static struct platform_driver simtec_audio_hermes_platdrv = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "s3c24xx-simtec-hermes-snd",
- .pm = simtec_audio_pm,
- },
- .probe = simtec_audio_hermes_probe,
- .remove = __devexit_p(simtec_audio_remove),
-};
-
-module_platform_driver(simtec_audio_hermes_platdrv);
-
-MODULE_ALIAS("platform:s3c24xx-simtec-hermes-snd");
-MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
-MODULE_DESCRIPTION("ALSA SoC Simtec Audio support");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c b/ANDROID_3.4.5/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
deleted file mode 100644
index c42d5f00..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
- *
- * Copyright 2009 Simtec Electronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/module.h>
-#include <sound/soc.h>
-
-#include "s3c24xx_simtec.h"
-
-/* supported machines:
- *
- * Machine Connections AMP
- * ------- ----------- ---
- * BAST MIC, HPOUT, LOUT, LIN TPA2001D1 (HPOUTL,R) (gain hardwired)
- * VR1000 HPOUT, LIN None
- * VR2000 LIN, LOUT, MIC, HP LM4871 (HPOUTL,R)
- * DePicture LIN, LOUT, MIC, HP LM4871 (HPOUTL,R)
- * Anubis LIN, LOUT, MIC, HP TPA2001D1 (HPOUTL,R)
- */
-
-static const struct snd_soc_dapm_widget dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_LINE("Line In", NULL),
- SND_SOC_DAPM_LINE("Line Out", NULL),
- SND_SOC_DAPM_MIC("Mic Jack", NULL),
-};
-
-static const struct snd_soc_dapm_route base_map[] = {
- { "Headphone Jack", NULL, "LHPOUT"},
- { "Headphone Jack", NULL, "RHPOUT"},
-
- { "Line Out", NULL, "LOUT" },
- { "Line Out", NULL, "ROUT" },
-
- { "LLINEIN", NULL, "Line In"},
- { "RLINEIN", NULL, "Line In"},
-
- { "MICIN", NULL, "Mic Jack"},
-};
-
-/**
- * simtec_tlv320aic23_init - initialise and add controls
- * @codec; The codec instance to attach to.
- *
- * Attach our controls and configure the necessary codec
- * mappings for our sound card instance.
-*/
-static int simtec_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_enable_pin(dapm, "Line In");
- snd_soc_dapm_enable_pin(dapm, "Line Out");
- snd_soc_dapm_enable_pin(dapm, "Mic Jack");
-
- simtec_audio_init(rtd);
-
- return 0;
-}
-
-static struct snd_soc_dai_link simtec_dai_aic23 = {
- .name = "tlv320aic23",
- .stream_name = "TLV320AIC23",
- .codec_name = "tlv320aic3x-codec.0-001a",
- .cpu_dai_name = "s3c24xx-iis",
- .codec_dai_name = "tlv320aic3x-hifi",
- .platform_name = "samsung-audio",
- .init = simtec_tlv320aic23_init,
-};
-
-/* simtec audio machine driver */
-static struct snd_soc_card snd_soc_machine_simtec_aic23 = {
- .name = "Simtec",
- .owner = THIS_MODULE,
- .dai_link = &simtec_dai_aic23,
- .num_links = 1,
-
- .dapm_widgets = dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(dapm_widgets),
- .dapm_routes = base_map,
- .num_dapm_routes = ARRAY_SIZE(base_map),
-};
-
-static int __devinit simtec_audio_tlv320aic23_probe(struct platform_device *pd)
-{
- return simtec_audio_core_probe(pd, &snd_soc_machine_simtec_aic23);
-}
-
-static struct platform_driver simtec_audio_tlv320aic23_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "s3c24xx-simtec-tlv320aic23",
- .pm = simtec_audio_pm,
- },
- .probe = simtec_audio_tlv320aic23_probe,
- .remove = __devexit_p(simtec_audio_remove),
-};
-
-module_platform_driver(simtec_audio_tlv320aic23_driver);
-
-MODULE_ALIAS("platform:s3c24xx-simtec-tlv320aic23");
-MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
-MODULE_DESCRIPTION("ALSA SoC Simtec Audio support");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/s3c24xx_uda134x.c b/ANDROID_3.4.5/sound/soc/samsung/s3c24xx_uda134x.c
deleted file mode 100644
index d731042e..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/s3c24xx_uda134x.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * Modifications by Christian Pellegrin <chripell@evolware.org>
- *
- * s3c24xx_uda134x.c -- S3C24XX_UDA134X ALSA SoC Audio board driver
- *
- * Copyright 2007 Dension Audio Systems Ltd.
- * Author: Zoltan Devai
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/clk.h>
-#include <linux/gpio.h>
-#include <linux/module.h>
-
-#include <sound/soc.h>
-#include <sound/s3c24xx_uda134x.h>
-
-#include <plat/regs-iis.h>
-
-#include "s3c24xx-i2s.h"
-
-/* #define ENFORCE_RATES 1 */
-/*
- Unfortunately the S3C24XX in master mode has a limited capacity of
- generating the clock for the codec. If you define this only rates
- that are really available will be enforced. But be careful, most
- user level application just want the usual sampling frequencies (8,
- 11.025, 22.050, 44.1 kHz) and anyway resampling is a costly
- operation for embedded systems. So if you aren't very lucky or your
- hardware engineer wasn't very forward-looking it's better to leave
- this undefined. If you do so an approximate value for the requested
- sampling rate in the range -/+ 5% will be chosen. If this in not
- possible an error will be returned.
-*/
-
-static struct clk *xtal;
-static struct clk *pclk;
-/* this is need because we don't have a place where to keep the
- * pointers to the clocks in each substream. We get the clocks only
- * when we are actually using them so we don't block stuff like
- * frequency change or oscillator power-off */
-static int clk_users;
-static DEFINE_MUTEX(clk_lock);
-
-static unsigned int rates[33 * 2];
-#ifdef ENFORCE_RATES
-static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
- .count = ARRAY_SIZE(rates),
- .list = rates,
- .mask = 0,
-};
-#endif
-
-static struct platform_device *s3c24xx_uda134x_snd_device;
-
-static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
-{
- int ret = 0;
-#ifdef ENFORCE_RATES
- struct snd_pcm_runtime *runtime = substream->runtime;
-#endif
-
- mutex_lock(&clk_lock);
- pr_debug("%s %d\n", __func__, clk_users);
- if (clk_users == 0) {
- xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal");
- if (IS_ERR(xtal)) {
- printk(KERN_ERR "%s cannot get xtal\n", __func__);
- ret = PTR_ERR(xtal);
- } else {
- pclk = clk_get(&s3c24xx_uda134x_snd_device->dev,
- "pclk");
- if (IS_ERR(pclk)) {
- printk(KERN_ERR "%s cannot get pclk\n",
- __func__);
- clk_put(xtal);
- ret = PTR_ERR(pclk);
- }
- }
- if (!ret) {
- int i, j;
-
- for (i = 0; i < 2; i++) {
- int fs = i ? 256 : 384;
-
- rates[i*33] = clk_get_rate(xtal) / fs;
- for (j = 1; j < 33; j++)
- rates[i*33 + j] = clk_get_rate(pclk) /
- (j * fs);
- }
- }
- }
- clk_users += 1;
- mutex_unlock(&clk_lock);
- if (!ret) {
-#ifdef ENFORCE_RATES
- ret = snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- &hw_constraints_rates);
- if (ret < 0)
- printk(KERN_ERR "%s cannot set constraints\n",
- __func__);
-#endif
- }
- return ret;
-}
-
-static void s3c24xx_uda134x_shutdown(struct snd_pcm_substream *substream)
-{
- mutex_lock(&clk_lock);
- pr_debug("%s %d\n", __func__, clk_users);
- clk_users -= 1;
- if (clk_users == 0) {
- clk_put(xtal);
- xtal = NULL;
- clk_put(pclk);
- pclk = NULL;
- }
- mutex_unlock(&clk_lock);
-}
-
-static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- unsigned int clk = 0;
- int ret = 0;
- int clk_source, fs_mode;
- unsigned long rate = params_rate(params);
- long err, cerr;
- unsigned int div;
- int i, bi;
-
- err = 999999;
- bi = 0;
- for (i = 0; i < 2*33; i++) {
- cerr = rates[i] - rate;
- if (cerr < 0)
- cerr = -cerr;
- if (cerr < err) {
- err = cerr;
- bi = i;
- }
- }
- if (bi / 33 == 1)
- fs_mode = S3C2410_IISMOD_256FS;
- else
- fs_mode = S3C2410_IISMOD_384FS;
- if (bi % 33 == 0) {
- clk_source = S3C24XX_CLKSRC_MPLL;
- div = 1;
- } else {
- clk_source = S3C24XX_CLKSRC_PCLK;
- div = bi % 33;
- }
- pr_debug("%s desired rate %lu, %d\n", __func__, rate, bi);
-
- clk = (fs_mode == S3C2410_IISMOD_384FS ? 384 : 256) * rate;
- pr_debug("%s will use: %s %s %d sysclk %d err %ld\n", __func__,
- fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS",
- clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK",
- div, clk, err);
-
- if ((err * 100 / rate) > 5) {
- printk(KERN_ERR "S3C24XX_UDA134X: effective frequency "
- "too different from desired (%ld%%)\n",
- err * 100 / rate);
- return -EINVAL;
- }
-
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_sysclk(cpu_dai, clk_source , clk,
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, fs_mode);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK,
- S3C2410_IISMOD_32FS);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
- S3C24XX_PRESCALE(div, div));
- if (ret < 0)
- return ret;
-
- /* set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
- SND_SOC_CLOCK_OUT);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops s3c24xx_uda134x_ops = {
- .startup = s3c24xx_uda134x_startup,
- .shutdown = s3c24xx_uda134x_shutdown,
- .hw_params = s3c24xx_uda134x_hw_params,
-};
-
-static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = {
- .name = "UDA134X",
- .stream_name = "UDA134X",
- .codec_name = "uda134x-codec",
- .codec_dai_name = "uda134x-hifi",
- .cpu_dai_name = "s3c24xx-iis",
- .ops = &s3c24xx_uda134x_ops,
- .platform_name = "samsung-audio",
-};
-
-static struct snd_soc_card snd_soc_s3c24xx_uda134x = {
- .name = "S3C24XX_UDA134X",
- .owner = THIS_MODULE,
- .dai_link = &s3c24xx_uda134x_dai_link,
- .num_links = 1,
-};
-
-static struct s3c24xx_uda134x_platform_data *s3c24xx_uda134x_l3_pins;
-
-static void setdat(int v)
-{
- gpio_set_value(s3c24xx_uda134x_l3_pins->l3_data, v > 0);
-}
-
-static void setclk(int v)
-{
- gpio_set_value(s3c24xx_uda134x_l3_pins->l3_clk, v > 0);
-}
-
-static void setmode(int v)
-{
- gpio_set_value(s3c24xx_uda134x_l3_pins->l3_mode, v > 0);
-}
-
-/* FIXME - This must be codec platform data but in which board file ?? */
-static struct uda134x_platform_data s3c24xx_uda134x = {
- .l3 = {
- .setdat = setdat,
- .setclk = setclk,
- .setmode = setmode,
- .data_hold = 1,
- .data_setup = 1,
- .clock_high = 1,
- .mode_hold = 1,
- .mode = 1,
- .mode_setup = 1,
- },
-};
-
-static int s3c24xx_uda134x_setup_pin(int pin, char *fun)
-{
- if (gpio_request(pin, "s3c24xx_uda134x") < 0) {
- printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
- "l3 %s pin already in use", fun);
- return -EBUSY;
- }
- gpio_direction_output(pin, 0);
- return 0;
-}
-
-static int s3c24xx_uda134x_probe(struct platform_device *pdev)
-{
- int ret;
-
- printk(KERN_INFO "S3C24XX_UDA134X SoC Audio driver\n");
-
- s3c24xx_uda134x_l3_pins = pdev->dev.platform_data;
- if (s3c24xx_uda134x_l3_pins == NULL) {
- printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
- "unable to find platform data\n");
- return -ENODEV;
- }
- s3c24xx_uda134x.power = s3c24xx_uda134x_l3_pins->power;
- s3c24xx_uda134x.model = s3c24xx_uda134x_l3_pins->model;
-
- if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_data,
- "data") < 0)
- return -EBUSY;
- if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_clk,
- "clk") < 0) {
- gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
- return -EBUSY;
- }
- if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_mode,
- "mode") < 0) {
- gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
- gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);
- return -EBUSY;
- }
-
- s3c24xx_uda134x_snd_device = platform_device_alloc("soc-audio", -1);
- if (!s3c24xx_uda134x_snd_device) {
- printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
- "Unable to register\n");
- return -ENOMEM;
- }
-
- platform_set_drvdata(s3c24xx_uda134x_snd_device,
- &snd_soc_s3c24xx_uda134x);
- platform_device_add_data(s3c24xx_uda134x_snd_device, &s3c24xx_uda134x, sizeof(s3c24xx_uda134x));
- ret = platform_device_add(s3c24xx_uda134x_snd_device);
- if (ret) {
- printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: Unable to add\n");
- platform_device_put(s3c24xx_uda134x_snd_device);
- }
-
- return ret;
-}
-
-static int s3c24xx_uda134x_remove(struct platform_device *pdev)
-{
- platform_device_unregister(s3c24xx_uda134x_snd_device);
- gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
- gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);
- gpio_free(s3c24xx_uda134x_l3_pins->l3_mode);
- return 0;
-}
-
-static struct platform_driver s3c24xx_uda134x_driver = {
- .probe = s3c24xx_uda134x_probe,
- .remove = s3c24xx_uda134x_remove,
- .driver = {
- .name = "s3c24xx_uda134x",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(s3c24xx_uda134x_driver);
-
-MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
-MODULE_DESCRIPTION("S3C24XX_UDA134X ALSA SoC audio driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/smartq_wm8987.c b/ANDROID_3.4.5/sound/soc/samsung/smartq_wm8987.c
deleted file mode 100644
index f2dcb424..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/smartq_wm8987.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/* sound/soc/samsung/smartq_wm8987.c
- *
- * Copyright 2010 Maurus Cuelenaere <mcuelenaere@gmail.com>
- *
- * Based on smdk6410_wm8987.c
- * Copyright 2007 Wolfson Microelectronics PLC. - linux@wolfsonmicro.com
- * Graeme Gregory - graeme.gregory@wolfsonmicro.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/gpio.h>
-#include <linux/module.h>
-
-#include <sound/soc.h>
-#include <sound/jack.h>
-
-#include <asm/mach-types.h>
-
-#include "i2s.h"
-#include "../codecs/wm8750.h"
-
-/*
- * WM8987 is register compatible with WM8750, so using that as base driver.
- */
-
-static struct snd_soc_card snd_soc_smartq;
-
-static int smartq_hifi_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- unsigned int clk = 0;
- int ret;
-
- switch (params_rate(params)) {
- case 8000:
- case 16000:
- case 32000:
- case 48000:
- case 96000:
- clk = 12288000;
- break;
- case 11025:
- case 22050:
- case 44100:
- case 88200:
- clk = 11289600;
- break;
- }
-
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* Use PCLK for I2S signal generation */
- ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0,
- 0, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- /* Gate the RCLK output on PAD */
- ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK,
- 0, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- /* set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk,
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-/*
- * SmartQ WM8987 HiFi DAI operations.
- */
-static struct snd_soc_ops smartq_hifi_ops = {
- .hw_params = smartq_hifi_hw_params,
-};
-
-static struct snd_soc_jack smartq_jack;
-
-static struct snd_soc_jack_pin smartq_jack_pins[] = {
- /* Disable speaker when headphone is plugged in */
- {
- .pin = "Internal Speaker",
- .mask = SND_JACK_HEADPHONE,
- },
-};
-
-static struct snd_soc_jack_gpio smartq_jack_gpios[] = {
- {
- .gpio = S3C64XX_GPL(12),
- .name = "headphone detect",
- .report = SND_JACK_HEADPHONE,
- .debounce_time = 200,
- },
-};
-
-static const struct snd_kcontrol_new wm8987_smartq_controls[] = {
- SOC_DAPM_PIN_SWITCH("Internal Speaker"),
- SOC_DAPM_PIN_SWITCH("Headphone Jack"),
- SOC_DAPM_PIN_SWITCH("Internal Mic"),
-};
-
-static int smartq_speaker_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k,
- int event)
-{
- gpio_set_value(S3C64XX_GPK(12), SND_SOC_DAPM_EVENT_OFF(event));
-
- return 0;
-}
-
-static const struct snd_soc_dapm_widget wm8987_dapm_widgets[] = {
- SND_SOC_DAPM_SPK("Internal Speaker", smartq_speaker_event),
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_MIC("Internal Mic", NULL),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- {"Headphone Jack", NULL, "LOUT2"},
- {"Headphone Jack", NULL, "ROUT2"},
-
- {"Internal Speaker", NULL, "LOUT2"},
- {"Internal Speaker", NULL, "ROUT2"},
-
- {"Mic Bias", NULL, "Internal Mic"},
- {"LINPUT2", NULL, "Mic Bias"},
-};
-
-static int smartq_wm8987_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- int err = 0;
-
- /* set endpoints to not connected */
- snd_soc_dapm_nc_pin(dapm, "LINPUT1");
- snd_soc_dapm_nc_pin(dapm, "RINPUT1");
- snd_soc_dapm_nc_pin(dapm, "OUT3");
- snd_soc_dapm_nc_pin(dapm, "ROUT1");
-
- /* set endpoints to default off mode */
- snd_soc_dapm_enable_pin(dapm, "Internal Speaker");
- snd_soc_dapm_enable_pin(dapm, "Internal Mic");
- snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
-
- /* Headphone jack detection */
- err = snd_soc_jack_new(codec, "Headphone Jack",
- SND_JACK_HEADPHONE, &smartq_jack);
- if (err)
- return err;
-
- err = snd_soc_jack_add_pins(&smartq_jack, ARRAY_SIZE(smartq_jack_pins),
- smartq_jack_pins);
- if (err)
- return err;
-
- err = snd_soc_jack_add_gpios(&smartq_jack,
- ARRAY_SIZE(smartq_jack_gpios),
- smartq_jack_gpios);
-
- return err;
-}
-
-static struct snd_soc_dai_link smartq_dai[] = {
- {
- .name = "wm8987",
- .stream_name = "SmartQ Hi-Fi",
- .cpu_dai_name = "samsung-i2s.0",
- .codec_dai_name = "wm8750-hifi",
- .platform_name = "samsung-audio",
- .codec_name = "wm8750.0-0x1a",
- .init = smartq_wm8987_init,
- .ops = &smartq_hifi_ops,
- },
-};
-
-static struct snd_soc_card snd_soc_smartq = {
- .name = "SmartQ",
- .owner = THIS_MODULE,
- .dai_link = smartq_dai,
- .num_links = ARRAY_SIZE(smartq_dai),
-
- .dapm_widgets = wm8987_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(wm8987_dapm_widgets),
- .dapm_routes = audio_map,
- .num_dapm_routes = ARRAY_SIZE(audio_map),
- .controls = wm8987_smartq_controls,
- .num_controls = ARRAY_SIZE(wm8987_smartq_controls),
-};
-
-static struct platform_device *smartq_snd_device;
-
-static int __init smartq_init(void)
-{
- int ret;
-
- if (!machine_is_smartq7() && !machine_is_smartq5()) {
- pr_info("Only SmartQ is supported by this ASoC driver\n");
- return -ENODEV;
- }
-
- smartq_snd_device = platform_device_alloc("soc-audio", -1);
- if (!smartq_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(smartq_snd_device, &snd_soc_smartq);
-
- ret = platform_device_add(smartq_snd_device);
- if (ret) {
- platform_device_put(smartq_snd_device);
- return ret;
- }
-
- /* Initialise GPIOs used by amplifiers */
- ret = gpio_request(S3C64XX_GPK(12), "amplifiers shutdown");
- if (ret) {
- dev_err(&smartq_snd_device->dev, "Failed to register GPK12\n");
- goto err_unregister_device;
- }
-
- /* Disable amplifiers */
- ret = gpio_direction_output(S3C64XX_GPK(12), 1);
- if (ret) {
- dev_err(&smartq_snd_device->dev, "Failed to configure GPK12\n");
- goto err_free_gpio_amp_shut;
- }
-
- return 0;
-
-err_free_gpio_amp_shut:
- gpio_free(S3C64XX_GPK(12));
-err_unregister_device:
- platform_device_unregister(smartq_snd_device);
-
- return ret;
-}
-
-static void __exit smartq_exit(void)
-{
- gpio_free(S3C64XX_GPK(12));
- snd_soc_jack_free_gpios(&smartq_jack, ARRAY_SIZE(smartq_jack_gpios),
- smartq_jack_gpios);
-
- platform_device_unregister(smartq_snd_device);
-}
-
-module_init(smartq_init);
-module_exit(smartq_exit);
-
-/* Module information */
-MODULE_AUTHOR("Maurus Cuelenaere <mcuelenaere@gmail.com>");
-MODULE_DESCRIPTION("ALSA SoC SmartQ WM8987");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/smdk2443_wm9710.c b/ANDROID_3.4.5/sound/soc/samsung/smdk2443_wm9710.c
deleted file mode 100644
index 720ba29b..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/smdk2443_wm9710.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * smdk2443_wm9710.c -- SoC audio for smdk2443
- *
- * Copyright 2007 Wolfson Microelectronics PLC.
- * Author: Graeme Gregory
- * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <sound/soc.h>
-
-static struct snd_soc_card smdk2443;
-
-static struct snd_soc_dai_link smdk2443_dai[] = {
-{
- .name = "AC97",
- .stream_name = "AC97 HiFi",
- .cpu_dai_name = "samsung-ac97",
- .codec_dai_name = "ac97-hifi",
- .codec_name = "ac97-codec",
- .platform_name = "samsung-audio",
-},
-};
-
-static struct snd_soc_card smdk2443 = {
- .name = "SMDK2443",
- .owner = THIS_MODULE,
- .dai_link = smdk2443_dai,
- .num_links = ARRAY_SIZE(smdk2443_dai),
-};
-
-static struct platform_device *smdk2443_snd_ac97_device;
-
-static int __init smdk2443_init(void)
-{
- int ret;
-
- smdk2443_snd_ac97_device = platform_device_alloc("soc-audio", -1);
- if (!smdk2443_snd_ac97_device)
- return -ENOMEM;
-
- platform_set_drvdata(smdk2443_snd_ac97_device, &smdk2443);
- ret = platform_device_add(smdk2443_snd_ac97_device);
-
- if (ret)
- platform_device_put(smdk2443_snd_ac97_device);
-
- return ret;
-}
-
-static void __exit smdk2443_exit(void)
-{
- platform_device_unregister(smdk2443_snd_ac97_device);
-}
-
-module_init(smdk2443_init);
-module_exit(smdk2443_exit);
-
-/* Module information */
-MODULE_AUTHOR("Graeme Gregory, graeme.gregory@wolfsonmicro.com, www.wolfsonmicro.com");
-MODULE_DESCRIPTION("ALSA SoC WM9710 SMDK2443");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/smdk_spdif.c b/ANDROID_3.4.5/sound/soc/samsung/smdk_spdif.c
deleted file mode 100644
index beaa9c15..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/smdk_spdif.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * smdk_spdif.c -- S/PDIF audio for SMDK
- *
- * Copyright 2010 Samsung Electronics Co. Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- */
-
-#include <linux/clk.h>
-#include <linux/module.h>
-
-#include <sound/soc.h>
-
-#include "spdif.h"
-
-/* Audio clock settings are belonged to board specific part. Every
- * board can set audio source clock setting which is matched with H/W
- * like this function-'set_audio_clock_heirachy'.
- */
-static int set_audio_clock_heirachy(struct platform_device *pdev)
-{
- struct clk *fout_epll, *mout_epll, *sclk_audio0, *sclk_spdif;
- int ret = 0;
-
- fout_epll = clk_get(NULL, "fout_epll");
- if (IS_ERR(fout_epll)) {
- printk(KERN_WARNING "%s: Cannot find fout_epll.\n",
- __func__);
- return -EINVAL;
- }
-
- mout_epll = clk_get(NULL, "mout_epll");
- if (IS_ERR(mout_epll)) {
- printk(KERN_WARNING "%s: Cannot find mout_epll.\n",
- __func__);
- ret = -EINVAL;
- goto out1;
- }
-
- sclk_audio0 = clk_get(&pdev->dev, "sclk_audio");
- if (IS_ERR(sclk_audio0)) {
- printk(KERN_WARNING "%s: Cannot find sclk_audio.\n",
- __func__);
- ret = -EINVAL;
- goto out2;
- }
-
- sclk_spdif = clk_get(NULL, "sclk_spdif");
- if (IS_ERR(sclk_spdif)) {
- printk(KERN_WARNING "%s: Cannot find sclk_spdif.\n",
- __func__);
- ret = -EINVAL;
- goto out3;
- }
-
- /* Set audio clock hierarchy for S/PDIF */
- clk_set_parent(mout_epll, fout_epll);
- clk_set_parent(sclk_audio0, mout_epll);
- clk_set_parent(sclk_spdif, sclk_audio0);
-
- clk_put(sclk_spdif);
-out3:
- clk_put(sclk_audio0);
-out2:
- clk_put(mout_epll);
-out1:
- clk_put(fout_epll);
-
- return ret;
-}
-
-/* We should haved to set clock directly on this part because of clock
- * scheme of Samsudng SoCs did not support to set rates from abstrct
- * clock of it's hierarchy.
- */
-static int set_audio_clock_rate(unsigned long epll_rate,
- unsigned long audio_rate)
-{
- struct clk *fout_epll, *sclk_spdif;
-
- fout_epll = clk_get(NULL, "fout_epll");
- if (IS_ERR(fout_epll)) {
- printk(KERN_ERR "%s: failed to get fout_epll\n", __func__);
- return -ENOENT;
- }
-
- clk_set_rate(fout_epll, epll_rate);
- clk_put(fout_epll);
-
- sclk_spdif = clk_get(NULL, "sclk_spdif");
- if (IS_ERR(sclk_spdif)) {
- printk(KERN_ERR "%s: failed to get sclk_spdif\n", __func__);
- return -ENOENT;
- }
-
- clk_set_rate(sclk_spdif, audio_rate);
- clk_put(sclk_spdif);
-
- return 0;
-}
-
-static int smdk_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- unsigned long pll_out, rclk_rate;
- int ret, ratio;
-
- switch (params_rate(params)) {
- case 44100:
- pll_out = 45158400;
- break;
- case 32000:
- case 48000:
- case 96000:
- pll_out = 49152000;
- break;
- default:
- return -EINVAL;
- }
-
- /* Setting ratio to 512fs helps to use S/PDIF with HDMI without
- * modify S/PDIF ASoC machine driver.
- */
- ratio = 512;
- rclk_rate = params_rate(params) * ratio;
-
- /* Set audio source clock rates */
- ret = set_audio_clock_rate(pll_out, rclk_rate);
- if (ret < 0)
- return ret;
-
- /* Set S/PDIF uses internal source clock */
- ret = snd_soc_dai_set_sysclk(cpu_dai, SND_SOC_SPDIF_INT_MCLK,
- rclk_rate, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- return ret;
-}
-
-static struct snd_soc_ops smdk_spdif_ops = {
- .hw_params = smdk_hw_params,
-};
-
-static struct snd_soc_dai_link smdk_dai = {
- .name = "S/PDIF",
- .stream_name = "S/PDIF PCM Playback",
- .platform_name = "samsung-audio",
- .cpu_dai_name = "samsung-spdif",
- .codec_dai_name = "dit-hifi",
- .codec_name = "spdif-dit",
- .ops = &smdk_spdif_ops,
-};
-
-static struct snd_soc_card smdk = {
- .name = "SMDK-S/PDIF",
- .owner = THIS_MODULE,
- .dai_link = &smdk_dai,
- .num_links = 1,
-};
-
-static struct platform_device *smdk_snd_spdif_dit_device;
-static struct platform_device *smdk_snd_spdif_device;
-
-static int __init smdk_init(void)
-{
- int ret;
-
- smdk_snd_spdif_dit_device = platform_device_alloc("spdif-dit", -1);
- if (!smdk_snd_spdif_dit_device)
- return -ENOMEM;
-
- ret = platform_device_add(smdk_snd_spdif_dit_device);
- if (ret)
- goto err1;
-
- smdk_snd_spdif_device = platform_device_alloc("soc-audio", -1);
- if (!smdk_snd_spdif_device) {
- ret = -ENOMEM;
- goto err2;
- }
-
- platform_set_drvdata(smdk_snd_spdif_device, &smdk);
-
- ret = platform_device_add(smdk_snd_spdif_device);
- if (ret)
- goto err3;
-
- /* Set audio clock hierarchy manually */
- ret = set_audio_clock_heirachy(smdk_snd_spdif_device);
- if (ret)
- goto err4;
-
- return 0;
-err4:
- platform_device_del(smdk_snd_spdif_device);
-err3:
- platform_device_put(smdk_snd_spdif_device);
-err2:
- platform_device_del(smdk_snd_spdif_dit_device);
-err1:
- platform_device_put(smdk_snd_spdif_dit_device);
- return ret;
-}
-
-static void __exit smdk_exit(void)
-{
- platform_device_unregister(smdk_snd_spdif_device);
- platform_device_unregister(smdk_snd_spdif_dit_device);
-}
-
-module_init(smdk_init);
-module_exit(smdk_exit);
-
-MODULE_AUTHOR("Seungwhan Youn, <sw.youn@samsung.com>");
-MODULE_DESCRIPTION("ALSA SoC SMDK+S/PDIF");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/smdk_wm8580.c b/ANDROID_3.4.5/sound/soc/samsung/smdk_wm8580.c
deleted file mode 100644
index ade2809c..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/smdk_wm8580.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * smdk_wm8580.c
- *
- * Copyright (c) 2009 Samsung Electronics Co. Ltd
- * Author: Jaswinder Singh <jassisinghbrar@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/module.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <asm/mach-types.h>
-
-#include "../codecs/wm8580.h"
-#include "i2s.h"
-
-/*
- * Default CFG switch settings to use this driver:
- *
- * SMDK6410: Set CFG1 1-3 Off, CFG2 1-4 On
- */
-
-/* SMDK has a 12MHZ crystal attached to WM8580 */
-#define SMDK_WM8580_FREQ 12000000
-
-static int smdk_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- unsigned int pll_out;
- int bfs, rfs, ret;
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_U8:
- case SNDRV_PCM_FORMAT_S8:
- bfs = 16;
- break;
- case SNDRV_PCM_FORMAT_U16_LE:
- case SNDRV_PCM_FORMAT_S16_LE:
- bfs = 32;
- break;
- default:
- return -EINVAL;
- }
-
- /* The Fvco for WM8580 PLLs must fall within [90,100]MHz.
- * This criterion can't be met if we request PLL output
- * as {8000x256, 64000x256, 11025x256}Hz.
- * As a wayout, we rather change rfs to a minimum value that
- * results in (params_rate(params) * rfs), and itself, acceptable
- * to both - the CODEC and the CPU.
- */
- switch (params_rate(params)) {
- case 16000:
- case 22050:
- case 32000:
- case 44100:
- case 48000:
- case 88200:
- case 96000:
- rfs = 256;
- break;
- case 64000:
- rfs = 384;
- break;
- case 8000:
- case 11025:
- rfs = 512;
- break;
- default:
- return -EINVAL;
- }
- pll_out = params_rate(params) * rfs;
-
- /* Set the Codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
- | SND_SOC_DAIFMT_NB_NF
- | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- /* Set the AP DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
- | SND_SOC_DAIFMT_NB_NF
- | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- /* Set WM8580 to drive MCLK from its PLLA */
- ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK,
- WM8580_CLKSRC_PLLA);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0,
- SMDK_WM8580_FREQ, pll_out);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_PLLA,
- pll_out, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-/*
- * SMDK WM8580 DAI operations.
- */
-static struct snd_soc_ops smdk_ops = {
- .hw_params = smdk_hw_params,
-};
-
-/* SMDK Playback widgets */
-static const struct snd_soc_dapm_widget smdk_wm8580_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Front", NULL),
- SND_SOC_DAPM_HP("Center+Sub", NULL),
- SND_SOC_DAPM_HP("Rear", NULL),
-
- SND_SOC_DAPM_MIC("MicIn", NULL),
- SND_SOC_DAPM_LINE("LineIn", NULL),
-};
-
-/* SMDK-PAIFTX connections */
-static const struct snd_soc_dapm_route smdk_wm8580_audio_map[] = {
- /* MicIn feeds AINL */
- {"AINL", NULL, "MicIn"},
-
- /* LineIn feeds AINL/R */
- {"AINL", NULL, "LineIn"},
- {"AINR", NULL, "LineIn"},
-
- /* Front Left/Right are fed VOUT1L/R */
- {"Front", NULL, "VOUT1L"},
- {"Front", NULL, "VOUT1R"},
-
- /* Center/Sub are fed VOUT2L/R */
- {"Center+Sub", NULL, "VOUT2L"},
- {"Center+Sub", NULL, "VOUT2R"},
-
- /* Rear Left/Right are fed VOUT3L/R */
- {"Rear", NULL, "VOUT3L"},
- {"Rear", NULL, "VOUT3R"},
-};
-
-static int smdk_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- /* Enabling the microphone requires the fitting of a 0R
- * resistor to connect the line from the microphone jack.
- */
- snd_soc_dapm_disable_pin(dapm, "MicIn");
-
- return 0;
-}
-
-enum {
- PRI_PLAYBACK = 0,
- PRI_CAPTURE,
- SEC_PLAYBACK,
-};
-
-static struct snd_soc_dai_link smdk_dai[] = {
- [PRI_PLAYBACK] = { /* Primary Playback i/f */
- .name = "WM8580 PAIF RX",
- .stream_name = "Playback",
- .cpu_dai_name = "samsung-i2s.0",
- .codec_dai_name = "wm8580-hifi-playback",
- .platform_name = "samsung-audio",
- .codec_name = "wm8580.0-001b",
- .ops = &smdk_ops,
- },
- [PRI_CAPTURE] = { /* Primary Capture i/f */
- .name = "WM8580 PAIF TX",
- .stream_name = "Capture",
- .cpu_dai_name = "samsung-i2s.0",
- .codec_dai_name = "wm8580-hifi-capture",
- .platform_name = "samsung-audio",
- .codec_name = "wm8580.0-001b",
- .init = smdk_wm8580_init_paiftx,
- .ops = &smdk_ops,
- },
- [SEC_PLAYBACK] = { /* Sec_Fifo Playback i/f */
- .name = "Sec_FIFO TX",
- .stream_name = "Playback",
- .cpu_dai_name = "samsung-i2s.x",
- .codec_dai_name = "wm8580-hifi-playback",
- .platform_name = "samsung-audio",
- .codec_name = "wm8580.0-001b",
- .ops = &smdk_ops,
- },
-};
-
-static struct snd_soc_card smdk = {
- .name = "SMDK-I2S",
- .owner = THIS_MODULE,
- .dai_link = smdk_dai,
- .num_links = 2,
-
- .dapm_widgets = smdk_wm8580_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(smdk_wm8580_dapm_widgets),
- .dapm_routes = smdk_wm8580_audio_map,
- .num_dapm_routes = ARRAY_SIZE(smdk_wm8580_audio_map),
-};
-
-static struct platform_device *smdk_snd_device;
-
-static int __init smdk_audio_init(void)
-{
- int ret;
- char *str;
-
- if (machine_is_smdkc100()
- || machine_is_smdkv210() || machine_is_smdkc110()) {
- smdk.num_links = 3;
- /* Secondary is at offset SAMSUNG_I2S_SECOFF from Primary */
- str = (char *)smdk_dai[SEC_PLAYBACK].cpu_dai_name;
- str[strlen(str) - 1] = '0' + SAMSUNG_I2S_SECOFF;
- } else if (machine_is_smdk6410()) {
- str = (char *)smdk_dai[PRI_PLAYBACK].cpu_dai_name;
- str[strlen(str) - 1] = '2';
- str = (char *)smdk_dai[PRI_CAPTURE].cpu_dai_name;
- str[strlen(str) - 1] = '2';
- }
-
- smdk_snd_device = platform_device_alloc("soc-audio", -1);
- if (!smdk_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(smdk_snd_device, &smdk);
- ret = platform_device_add(smdk_snd_device);
-
- if (ret)
- platform_device_put(smdk_snd_device);
-
- return ret;
-}
-module_init(smdk_audio_init);
-
-static void __exit smdk_audio_exit(void)
-{
- platform_device_unregister(smdk_snd_device);
-}
-module_exit(smdk_audio_exit);
-
-MODULE_AUTHOR("Jaswinder Singh, jassisinghbrar@gmail.com");
-MODULE_DESCRIPTION("ALSA SoC SMDK WM8580");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/smdk_wm8580pcm.c b/ANDROID_3.4.5/sound/soc/samsung/smdk_wm8580pcm.c
deleted file mode 100644
index fab5322e..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/smdk_wm8580pcm.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * sound/soc/samsung/smdk_wm8580pcm.c
- *
- * Copyright (c) 2011 Samsung Electronics Co. Ltd
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-#include <linux/module.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-#include <sound/pcm.h>
-
-#include <asm/mach-types.h>
-
-#include "../codecs/wm8580.h"
-#include "dma.h"
-#include "pcm.h"
-
-/*
- * Board Settings:
- * o '1' means 'ON'
- * o '0' means 'OFF'
- * o 'X' means 'Don't care'
- *
- * SMDK6410, SMDK6440, SMDK6450 Base B/D: CFG1-0000, CFG2-1111
- * SMDKC110, SMDKV210: CFGB11-100100, CFGB12-0000
- */
-
-#define SMDK_WM8580_EXT_OSC 12000000
-#define SMDK_WM8580_EXT_MCLK 4096000
-#define SMDK_WM8580_EXT_VOICE 2048000
-
-static unsigned long mclk_freq;
-static unsigned long xtal_freq;
-
-/*
- * If MCLK clock directly gets from XTAL, we don't have to use PLL
- * to make MCLK, but if XTAL clock source connects with other codec
- * pin (like XTI), we should have to set codec's PLL to make MCLK.
- * Because Samsung SoC does not support pcmcdclk output like I2S.
- */
-
-static int smdk_wm8580_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int rfs, ret;
-
- switch (params_rate(params)) {
- case 8000:
- break;
- default:
- printk(KERN_ERR "%s:%d Sampling Rate %u not supported!\n",
- __func__, __LINE__, params_rate(params));
- return -EINVAL;
- }
-
- rfs = mclk_freq / params_rate(params) / 2;
-
- /* Set the codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B
- | SND_SOC_DAIFMT_IB_NF
- | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* Set the cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B
- | SND_SOC_DAIFMT_IB_NF
- | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- if (mclk_freq == xtal_freq) {
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_MCLK,
- mclk_freq, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK,
- WM8580_CLKSRC_MCLK);
- if (ret < 0)
- return ret;
- } else {
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_PLLA,
- mclk_freq, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK,
- WM8580_CLKSRC_PLLA);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0,
- xtal_freq, mclk_freq);
- if (ret < 0)
- return ret;
- }
-
- /* Set PCM source clock on CPU */
- ret = snd_soc_dai_set_sysclk(cpu_dai, S3C_PCM_CLKSRC_MUX,
- mclk_freq, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- /* Set SCLK_DIV for making bclk */
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_PCM_SCLK_PER_FS, rfs);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops smdk_wm8580_pcm_ops = {
- .hw_params = smdk_wm8580_pcm_hw_params,
-};
-
-static struct snd_soc_dai_link smdk_dai[] = {
- {
- .name = "WM8580 PAIF PCM RX",
- .stream_name = "Playback",
- .cpu_dai_name = "samsung-pcm.0",
- .codec_dai_name = "wm8580-hifi-playback",
- .platform_name = "samsung-audio",
- .codec_name = "wm8580.0-001b",
- .ops = &smdk_wm8580_pcm_ops,
- }, {
- .name = "WM8580 PAIF PCM TX",
- .stream_name = "Capture",
- .cpu_dai_name = "samsung-pcm.0",
- .codec_dai_name = "wm8580-hifi-capture",
- .platform_name = "samsung-audio",
- .codec_name = "wm8580.0-001b",
- .ops = &smdk_wm8580_pcm_ops,
- },
-};
-
-static struct snd_soc_card smdk_pcm = {
- .name = "SMDK-PCM",
- .owner = THIS_MODULE,
- .dai_link = smdk_dai,
- .num_links = 2,
-};
-
-/*
- * After SMDKC110 Base Board's Rev is '0.1', 12MHz External OSC(X1)
- * is absent (or not connected), so we connect EXT_VOICE_CLK(OSC4),
- * 2.0484Mhz, directly with MCLK both Codec and SoC.
- */
-static int __devinit snd_smdk_probe(struct platform_device *pdev)
-{
- int ret = 0;
-
- xtal_freq = SMDK_WM8580_EXT_OSC;
- mclk_freq = SMDK_WM8580_EXT_MCLK;
-
- if (machine_is_smdkc110() || machine_is_smdkv210())
- xtal_freq = mclk_freq = SMDK_WM8580_EXT_VOICE;
-
- smdk_pcm.dev = &pdev->dev;
- ret = snd_soc_register_card(&smdk_pcm);
- if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-static int __devexit snd_smdk_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_card(&smdk_pcm);
- platform_set_drvdata(pdev, NULL);
- return 0;
-}
-
-static struct platform_driver snd_smdk_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "samsung-smdk-pcm",
- },
- .probe = snd_smdk_probe,
- .remove = __devexit_p(snd_smdk_remove),
-};
-
-module_platform_driver(snd_smdk_driver);
-
-MODULE_AUTHOR("Sangbeom Kim, <sbkim73@samsung.com>");
-MODULE_DESCRIPTION("ALSA SoC SMDK WM8580 for PCM");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/smdk_wm8994.c b/ANDROID_3.4.5/sound/soc/samsung/smdk_wm8994.c
deleted file mode 100644
index 8eb309f2..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/smdk_wm8994.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * smdk_wm8994.c
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include "../codecs/wm8994.h"
-#include <sound/pcm_params.h>
-#include <linux/module.h>
-
- /*
- * Default CFG switch settings to use this driver:
- * SMDKV310: CFG5-1000, CFG7-111111
- */
-
- /*
- * Configure audio route as :-
- * $ amixer sset 'DAC1' on,on
- * $ amixer sset 'Right Headphone Mux' 'DAC'
- * $ amixer sset 'Left Headphone Mux' 'DAC'
- * $ amixer sset 'DAC1R Mixer AIF1.1' on
- * $ amixer sset 'DAC1L Mixer AIF1.1' on
- * $ amixer sset 'IN2L' on
- * $ amixer sset 'IN2L PGA IN2LN' on
- * $ amixer sset 'MIXINL IN2L' on
- * $ amixer sset 'AIF1ADC1L Mixer ADC/DMIC' on
- * $ amixer sset 'IN2R' on
- * $ amixer sset 'IN2R PGA IN2RN' on
- * $ amixer sset 'MIXINR IN2R' on
- * $ amixer sset 'AIF1ADC1R Mixer ADC/DMIC' on
- */
-
-/* SMDK has a 16.934MHZ crystal attached to WM8994 */
-#define SMDK_WM8994_FREQ 16934000
-
-static int smdk_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- unsigned int pll_out;
- int ret;
-
- /* AIF1CLK should be >=3MHz for optimal performance */
- if (params_format(params) == SNDRV_PCM_FORMAT_S24_LE)
- pll_out = params_rate(params) * 384;
- else if (params_rate(params) == 8000 || params_rate(params) == 11025)
- pll_out = params_rate(params) * 512;
- else
- pll_out = params_rate(params) * 256;
-
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
- | SND_SOC_DAIFMT_NB_NF
- | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
- | SND_SOC_DAIFMT_NB_NF
- | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1,
- SMDK_WM8994_FREQ, pll_out);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1,
- pll_out, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-/*
- * SMDK WM8994 DAI operations.
- */
-static struct snd_soc_ops smdk_ops = {
- .hw_params = smdk_hw_params,
-};
-
-static int smdk_wm8994_init_paiftx(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- /* HeadPhone */
- snd_soc_dapm_enable_pin(dapm, "HPOUT1R");
- snd_soc_dapm_enable_pin(dapm, "HPOUT1L");
-
- /* MicIn */
- snd_soc_dapm_enable_pin(dapm, "IN1LN");
- snd_soc_dapm_enable_pin(dapm, "IN1RN");
-
- /* LineIn */
- snd_soc_dapm_enable_pin(dapm, "IN2LN");
- snd_soc_dapm_enable_pin(dapm, "IN2RN");
-
- /* Other pins NC */
- snd_soc_dapm_nc_pin(dapm, "HPOUT2P");
- snd_soc_dapm_nc_pin(dapm, "HPOUT2N");
- snd_soc_dapm_nc_pin(dapm, "SPKOUTLN");
- snd_soc_dapm_nc_pin(dapm, "SPKOUTLP");
- snd_soc_dapm_nc_pin(dapm, "SPKOUTRP");
- snd_soc_dapm_nc_pin(dapm, "SPKOUTRN");
- snd_soc_dapm_nc_pin(dapm, "LINEOUT1N");
- snd_soc_dapm_nc_pin(dapm, "LINEOUT1P");
- snd_soc_dapm_nc_pin(dapm, "LINEOUT2N");
- snd_soc_dapm_nc_pin(dapm, "LINEOUT2P");
- snd_soc_dapm_nc_pin(dapm, "IN1LP");
- snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN");
- snd_soc_dapm_nc_pin(dapm, "IN1RP");
- snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP");
-
- return 0;
-}
-
-static struct snd_soc_dai_link smdk_dai[] = {
- { /* Primary DAI i/f */
- .name = "WM8994 AIF1",
- .stream_name = "Pri_Dai",
- .cpu_dai_name = "samsung-i2s.0",
- .codec_dai_name = "wm8994-aif1",
- .platform_name = "samsung-audio",
- .codec_name = "wm8994-codec",
- .init = smdk_wm8994_init_paiftx,
- .ops = &smdk_ops,
- }, { /* Sec_Fifo Playback i/f */
- .name = "Sec_FIFO TX",
- .stream_name = "Sec_Dai",
- .cpu_dai_name = "samsung-i2s.4",
- .codec_dai_name = "wm8994-aif1",
- .platform_name = "samsung-audio",
- .codec_name = "wm8994-codec",
- .ops = &smdk_ops,
- },
-};
-
-static struct snd_soc_card smdk = {
- .name = "SMDK-I2S",
- .owner = THIS_MODULE,
- .dai_link = smdk_dai,
- .num_links = ARRAY_SIZE(smdk_dai),
-};
-
-static struct platform_device *smdk_snd_device;
-
-static int __init smdk_audio_init(void)
-{
- int ret;
-
- smdk_snd_device = platform_device_alloc("soc-audio", -1);
- if (!smdk_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(smdk_snd_device, &smdk);
-
- ret = platform_device_add(smdk_snd_device);
- if (ret)
- platform_device_put(smdk_snd_device);
-
- return ret;
-}
-module_init(smdk_audio_init);
-
-static void __exit smdk_audio_exit(void)
-{
- platform_device_unregister(smdk_snd_device);
-}
-module_exit(smdk_audio_exit);
-
-MODULE_DESCRIPTION("ALSA SoC SMDK WM8994");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/smdk_wm8994pcm.c b/ANDROID_3.4.5/sound/soc/samsung/smdk_wm8994pcm.c
deleted file mode 100644
index 77ecba93..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/smdk_wm8994pcm.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * sound/soc/samsung/smdk_wm8994pcm.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-#include <linux/module.h>
-#include <sound/soc.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-
-#include "../codecs/wm8994.h"
-#include "dma.h"
-#include "pcm.h"
-
-/*
- * Board Settings:
- * o '1' means 'ON'
- * o '0' means 'OFF'
- * o 'X' means 'Don't care'
- *
- * SMDKC210, SMDKV310: CFG3- 1001, CFG5-1000, CFG7-111111
- */
-
-/*
- * Configure audio route as :-
- * $ amixer sset 'DAC1' on,on
- * $ amixer sset 'Right Headphone Mux' 'DAC'
- * $ amixer sset 'Left Headphone Mux' 'DAC'
- * $ amixer sset 'DAC1R Mixer AIF1.1' on
- * $ amixer sset 'DAC1L Mixer AIF1.1' on
- * $ amixer sset 'IN2L' on
- * $ amixer sset 'IN2L PGA IN2LN' on
- * $ amixer sset 'MIXINL IN2L' on
- * $ amixer sset 'AIF1ADC1L Mixer ADC/DMIC' on
- * $ amixer sset 'IN2R' on
- * $ amixer sset 'IN2R PGA IN2RN' on
- * $ amixer sset 'MIXINR IN2R' on
- * $ amixer sset 'AIF1ADC1R Mixer ADC/DMIC' on
- */
-
-/* SMDK has a 16.9344MHZ crystal attached to WM8994 */
-#define SMDK_WM8994_FREQ 16934400
-
-static int smdk_wm8994_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- unsigned long mclk_freq;
- int rfs, ret;
-
- switch(params_rate(params)) {
- case 8000:
- rfs = 512;
- break;
- default:
- dev_err(cpu_dai->dev, "%s:%d Sampling Rate %u not supported!\n",
- __func__, __LINE__, params_rate(params));
- return -EINVAL;
- }
-
- mclk_freq = params_rate(params) * rfs;
-
- /* Set the codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B
- | SND_SOC_DAIFMT_IB_NF
- | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- /* Set the cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B
- | SND_SOC_DAIFMT_IB_NF
- | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1,
- mclk_freq, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1,
- SMDK_WM8994_FREQ, mclk_freq);
- if (ret < 0)
- return ret;
-
- /* Set PCM source clock on CPU */
- ret = snd_soc_dai_set_sysclk(cpu_dai, S3C_PCM_CLKSRC_MUX,
- mclk_freq, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- /* Set SCLK_DIV for making bclk */
- ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_PCM_SCLK_PER_FS, rfs);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops smdk_wm8994_pcm_ops = {
- .hw_params = smdk_wm8994_pcm_hw_params,
-};
-
-static struct snd_soc_dai_link smdk_dai[] = {
- {
- .name = "WM8994 PAIF PCM",
- .stream_name = "Primary PCM",
- .cpu_dai_name = "samsung-pcm.0",
- .codec_dai_name = "wm8994-aif1",
- .platform_name = "samsung-audio",
- .codec_name = "wm8994-codec",
- .ops = &smdk_wm8994_pcm_ops,
- },
-};
-
-static struct snd_soc_card smdk_pcm = {
- .name = "SMDK-PCM",
- .owner = THIS_MODULE,
- .dai_link = smdk_dai,
- .num_links = 1,
-};
-
-static int __devinit snd_smdk_probe(struct platform_device *pdev)
-{
- int ret = 0;
-
- smdk_pcm.dev = &pdev->dev;
- ret = snd_soc_register_card(&smdk_pcm);
- if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-static int __devexit snd_smdk_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_card(&smdk_pcm);
- platform_set_drvdata(pdev, NULL);
- return 0;
-}
-
-static struct platform_driver snd_smdk_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "samsung-smdk-pcm",
- },
- .probe = snd_smdk_probe,
- .remove = __devexit_p(snd_smdk_remove),
-};
-
-module_platform_driver(snd_smdk_driver);
-
-MODULE_AUTHOR("Sangbeom Kim, <sbkim73@samsung.com>");
-MODULE_DESCRIPTION("ALSA SoC SMDK WM8994 for PCM");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/smdk_wm9713.c b/ANDROID_3.4.5/sound/soc/samsung/smdk_wm9713.c
deleted file mode 100644
index 55b2ca7f..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/smdk_wm9713.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * smdk_wm9713.c -- SoC audio for SMDK
- *
- * Copyright 2010 Samsung Electronics Co. Ltd.
- * Author: Jaswinder Singh Brar <jassisinghbrar@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <sound/soc.h>
-
-static struct snd_soc_card smdk;
-
-/*
- * Default CFG switch settings to use this driver:
- *
- * SMDK6410: Set CFG1 1-3 On, CFG2 1-4 Off
- * SMDKC100: Set CFG6 1-3 On, CFG7 1 On
- * SMDKC110: Set CFGB10 1-2 Off, CFGB12 1-3 On
- * SMDKV210: Set CFGB10 1-2 Off, CFGB12 1-3 On
- * SMDKV310: Set CFG2 1-2 Off, CFG4 All On, CFG7 All Off, CFG8 1-On
- */
-
-/*
- Playback (HeadPhone):-
- $ amixer sset 'Headphone' unmute
- $ amixer sset 'Right Headphone Out Mux' 'Headphone'
- $ amixer sset 'Left Headphone Out Mux' 'Headphone'
- $ amixer sset 'Right HP Mixer PCM' unmute
- $ amixer sset 'Left HP Mixer PCM' unmute
-
- Capture (LineIn):-
- $ amixer sset 'Right Capture Source' 'Line'
- $ amixer sset 'Left Capture Source' 'Line'
-*/
-
-static struct snd_soc_dai_link smdk_dai = {
- .name = "AC97",
- .stream_name = "AC97 PCM",
- .platform_name = "samsung-audio",
- .cpu_dai_name = "samsung-ac97",
- .codec_dai_name = "wm9713-hifi",
- .codec_name = "wm9713-codec",
-};
-
-static struct snd_soc_card smdk = {
- .name = "SMDK WM9713",
- .owner = THIS_MODULE,
- .dai_link = &smdk_dai,
- .num_links = 1,
-};
-
-static struct platform_device *smdk_snd_wm9713_device;
-static struct platform_device *smdk_snd_ac97_device;
-
-static int __init smdk_init(void)
-{
- int ret;
-
- smdk_snd_wm9713_device = platform_device_alloc("wm9713-codec", -1);
- if (!smdk_snd_wm9713_device)
- return -ENOMEM;
-
- ret = platform_device_add(smdk_snd_wm9713_device);
- if (ret)
- goto err1;
-
- smdk_snd_ac97_device = platform_device_alloc("soc-audio", -1);
- if (!smdk_snd_ac97_device) {
- ret = -ENOMEM;
- goto err2;
- }
-
- platform_set_drvdata(smdk_snd_ac97_device, &smdk);
-
- ret = platform_device_add(smdk_snd_ac97_device);
- if (ret)
- goto err3;
-
- return 0;
-
-err3:
- platform_device_put(smdk_snd_ac97_device);
-err2:
- platform_device_del(smdk_snd_wm9713_device);
-err1:
- platform_device_put(smdk_snd_wm9713_device);
- return ret;
-}
-
-static void __exit smdk_exit(void)
-{
- platform_device_unregister(smdk_snd_ac97_device);
- platform_device_unregister(smdk_snd_wm9713_device);
-}
-
-module_init(smdk_init);
-module_exit(smdk_exit);
-
-/* Module information */
-MODULE_AUTHOR("Jaswinder Singh Brar, jassisinghbrar@gmail.com");
-MODULE_DESCRIPTION("ALSA SoC SMDK+WM9713");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/spdif.c b/ANDROID_3.4.5/sound/soc/samsung/spdif.c
deleted file mode 100644
index a5a56a12..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/spdif.c
+++ /dev/null
@@ -1,491 +0,0 @@
-/* sound/soc/samsung/spdif.c
- *
- * ALSA SoC Audio Layer - Samsung S/PDIF Controller driver
- *
- * Copyright (c) 2010 Samsung Electronics Co. Ltd
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/module.h>
-
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <plat/audio.h>
-#include <mach/dma.h>
-
-#include "dma.h"
-#include "spdif.h"
-
-/* Registers */
-#define CLKCON 0x00
-#define CON 0x04
-#define BSTAS 0x08
-#define CSTAS 0x0C
-#define DATA_OUTBUF 0x10
-#define DCNT 0x14
-#define BSTAS_S 0x18
-#define DCNT_S 0x1C
-
-#define CLKCTL_MASK 0x7
-#define CLKCTL_MCLK_EXT (0x1 << 2)
-#define CLKCTL_PWR_ON (0x1 << 0)
-
-#define CON_MASK 0x3ffffff
-#define CON_FIFO_TH_SHIFT 19
-#define CON_FIFO_TH_MASK (0x7 << 19)
-#define CON_USERDATA_23RDBIT (0x1 << 12)
-
-#define CON_SW_RESET (0x1 << 5)
-
-#define CON_MCLKDIV_MASK (0x3 << 3)
-#define CON_MCLKDIV_256FS (0x0 << 3)
-#define CON_MCLKDIV_384FS (0x1 << 3)
-#define CON_MCLKDIV_512FS (0x2 << 3)
-
-#define CON_PCM_MASK (0x3 << 1)
-#define CON_PCM_16BIT (0x0 << 1)
-#define CON_PCM_20BIT (0x1 << 1)
-#define CON_PCM_24BIT (0x2 << 1)
-
-#define CON_PCM_DATA (0x1 << 0)
-
-#define CSTAS_MASK 0x3fffffff
-#define CSTAS_SAMP_FREQ_MASK (0xF << 24)
-#define CSTAS_SAMP_FREQ_44 (0x0 << 24)
-#define CSTAS_SAMP_FREQ_48 (0x2 << 24)
-#define CSTAS_SAMP_FREQ_32 (0x3 << 24)
-#define CSTAS_SAMP_FREQ_96 (0xA << 24)
-
-#define CSTAS_CATEGORY_MASK (0xFF << 8)
-#define CSTAS_CATEGORY_CODE_CDP (0x01 << 8)
-
-#define CSTAS_NO_COPYRIGHT (0x1 << 2)
-
-/**
- * struct samsung_spdif_info - Samsung S/PDIF Controller information
- * @lock: Spin lock for S/PDIF.
- * @dev: The parent device passed to use from the probe.
- * @regs: The pointer to the device register block.
- * @clk_rate: Current clock rate for calcurate ratio.
- * @pclk: The peri-clock pointer for spdif master operation.
- * @sclk: The source clock pointer for making sync signals.
- * @save_clkcon: Backup clkcon reg. in suspend.
- * @save_con: Backup con reg. in suspend.
- * @save_cstas: Backup cstas reg. in suspend.
- * @dma_playback: DMA information for playback channel.
- */
-struct samsung_spdif_info {
- spinlock_t lock;
- struct device *dev;
- void __iomem *regs;
- unsigned long clk_rate;
- struct clk *pclk;
- struct clk *sclk;
- u32 saved_clkcon;
- u32 saved_con;
- u32 saved_cstas;
- struct s3c_dma_params *dma_playback;
-};
-
-static struct s3c2410_dma_client spdif_dma_client_out = {
- .name = "S/PDIF Stereo out",
-};
-
-static struct s3c_dma_params spdif_stereo_out;
-static struct samsung_spdif_info spdif_info;
-
-static inline struct samsung_spdif_info *to_info(struct snd_soc_dai *cpu_dai)
-{
- return snd_soc_dai_get_drvdata(cpu_dai);
-}
-
-static void spdif_snd_txctrl(struct samsung_spdif_info *spdif, int on)
-{
- void __iomem *regs = spdif->regs;
- u32 clkcon;
-
- dev_dbg(spdif->dev, "Entered %s\n", __func__);
-
- clkcon = readl(regs + CLKCON) & CLKCTL_MASK;
- if (on)
- writel(clkcon | CLKCTL_PWR_ON, regs + CLKCON);
- else
- writel(clkcon & ~CLKCTL_PWR_ON, regs + CLKCON);
-}
-
-static int spdif_set_sysclk(struct snd_soc_dai *cpu_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct samsung_spdif_info *spdif = to_info(cpu_dai);
- u32 clkcon;
-
- dev_dbg(spdif->dev, "Entered %s\n", __func__);
-
- clkcon = readl(spdif->regs + CLKCON);
-
- if (clk_id == SND_SOC_SPDIF_INT_MCLK)
- clkcon &= ~CLKCTL_MCLK_EXT;
- else
- clkcon |= CLKCTL_MCLK_EXT;
-
- writel(clkcon, spdif->regs + CLKCON);
-
- spdif->clk_rate = freq;
-
- return 0;
-}
-
-static int spdif_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai);
- unsigned long flags;
-
- dev_dbg(spdif->dev, "Entered %s\n", __func__);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- spin_lock_irqsave(&spdif->lock, flags);
- spdif_snd_txctrl(spdif, 1);
- spin_unlock_irqrestore(&spdif->lock, flags);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- spin_lock_irqsave(&spdif->lock, flags);
- spdif_snd_txctrl(spdif, 0);
- spin_unlock_irqrestore(&spdif->lock, flags);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int spdif_sysclk_ratios[] = {
- 512, 384, 256,
-};
-
-static int spdif_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *socdai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai);
- void __iomem *regs = spdif->regs;
- struct s3c_dma_params *dma_data;
- u32 con, clkcon, cstas;
- unsigned long flags;
- int i, ratio;
-
- dev_dbg(spdif->dev, "Entered %s\n", __func__);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dma_data = spdif->dma_playback;
- else {
- dev_err(spdif->dev, "Capture is not supported\n");
- return -EINVAL;
- }
-
- snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data);
-
- spin_lock_irqsave(&spdif->lock, flags);
-
- con = readl(regs + CON) & CON_MASK;
- cstas = readl(regs + CSTAS) & CSTAS_MASK;
- clkcon = readl(regs + CLKCON) & CLKCTL_MASK;
-
- con &= ~CON_FIFO_TH_MASK;
- con |= (0x7 << CON_FIFO_TH_SHIFT);
- con |= CON_USERDATA_23RDBIT;
- con |= CON_PCM_DATA;
-
- con &= ~CON_PCM_MASK;
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- con |= CON_PCM_16BIT;
- break;
- default:
- dev_err(spdif->dev, "Unsupported data size.\n");
- goto err;
- }
-
- ratio = spdif->clk_rate / params_rate(params);
- for (i = 0; i < ARRAY_SIZE(spdif_sysclk_ratios); i++)
- if (ratio == spdif_sysclk_ratios[i])
- break;
- if (i == ARRAY_SIZE(spdif_sysclk_ratios)) {
- dev_err(spdif->dev, "Invalid clock ratio %ld/%d\n",
- spdif->clk_rate, params_rate(params));
- goto err;
- }
-
- con &= ~CON_MCLKDIV_MASK;
- switch (ratio) {
- case 256:
- con |= CON_MCLKDIV_256FS;
- break;
- case 384:
- con |= CON_MCLKDIV_384FS;
- break;
- case 512:
- con |= CON_MCLKDIV_512FS;
- break;
- }
-
- cstas &= ~CSTAS_SAMP_FREQ_MASK;
- switch (params_rate(params)) {
- case 44100:
- cstas |= CSTAS_SAMP_FREQ_44;
- break;
- case 48000:
- cstas |= CSTAS_SAMP_FREQ_48;
- break;
- case 32000:
- cstas |= CSTAS_SAMP_FREQ_32;
- break;
- case 96000:
- cstas |= CSTAS_SAMP_FREQ_96;
- break;
- default:
- dev_err(spdif->dev, "Invalid sampling rate %d\n",
- params_rate(params));
- goto err;
- }
-
- cstas &= ~CSTAS_CATEGORY_MASK;
- cstas |= CSTAS_CATEGORY_CODE_CDP;
- cstas |= CSTAS_NO_COPYRIGHT;
-
- writel(con, regs + CON);
- writel(cstas, regs + CSTAS);
- writel(clkcon, regs + CLKCON);
-
- spin_unlock_irqrestore(&spdif->lock, flags);
-
- return 0;
-err:
- spin_unlock_irqrestore(&spdif->lock, flags);
- return -EINVAL;
-}
-
-static void spdif_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai);
- void __iomem *regs = spdif->regs;
- u32 con, clkcon;
-
- dev_dbg(spdif->dev, "Entered %s\n", __func__);
-
- con = readl(regs + CON) & CON_MASK;
- clkcon = readl(regs + CLKCON) & CLKCTL_MASK;
-
- writel(con | CON_SW_RESET, regs + CON);
- cpu_relax();
-
- writel(clkcon & ~CLKCTL_PWR_ON, regs + CLKCON);
-}
-
-#ifdef CONFIG_PM
-static int spdif_suspend(struct snd_soc_dai *cpu_dai)
-{
- struct samsung_spdif_info *spdif = to_info(cpu_dai);
- u32 con = spdif->saved_con;
-
- dev_dbg(spdif->dev, "Entered %s\n", __func__);
-
- spdif->saved_clkcon = readl(spdif->regs + CLKCON) & CLKCTL_MASK;
- spdif->saved_con = readl(spdif->regs + CON) & CON_MASK;
- spdif->saved_cstas = readl(spdif->regs + CSTAS) & CSTAS_MASK;
-
- writel(con | CON_SW_RESET, spdif->regs + CON);
- cpu_relax();
-
- return 0;
-}
-
-static int spdif_resume(struct snd_soc_dai *cpu_dai)
-{
- struct samsung_spdif_info *spdif = to_info(cpu_dai);
-
- dev_dbg(spdif->dev, "Entered %s\n", __func__);
-
- writel(spdif->saved_clkcon, spdif->regs + CLKCON);
- writel(spdif->saved_con, spdif->regs + CON);
- writel(spdif->saved_cstas, spdif->regs + CSTAS);
-
- return 0;
-}
-#else
-#define spdif_suspend NULL
-#define spdif_resume NULL
-#endif
-
-static const struct snd_soc_dai_ops spdif_dai_ops = {
- .set_sysclk = spdif_set_sysclk,
- .trigger = spdif_trigger,
- .hw_params = spdif_hw_params,
- .shutdown = spdif_shutdown,
-};
-
-static struct snd_soc_dai_driver samsung_spdif_dai = {
- .name = "samsung-spdif",
- .playback = {
- .stream_name = "S/PDIF Playback",
- .channels_min = 2,
- .channels_max = 2,
- .rates = (SNDRV_PCM_RATE_32000 |
- SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_96000),
- .formats = SNDRV_PCM_FMTBIT_S16_LE, },
- .ops = &spdif_dai_ops,
- .suspend = spdif_suspend,
- .resume = spdif_resume,
-};
-
-static __devinit int spdif_probe(struct platform_device *pdev)
-{
- struct s3c_audio_pdata *spdif_pdata;
- struct resource *mem_res, *dma_res;
- struct samsung_spdif_info *spdif;
- int ret;
-
- spdif_pdata = pdev->dev.platform_data;
-
- dev_dbg(&pdev->dev, "Entered %s\n", __func__);
-
- dma_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!dma_res) {
- dev_err(&pdev->dev, "Unable to get dma resource.\n");
- return -ENXIO;
- }
-
- mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem_res) {
- dev_err(&pdev->dev, "Unable to get register resource.\n");
- return -ENXIO;
- }
-
- if (spdif_pdata && spdif_pdata->cfg_gpio
- && spdif_pdata->cfg_gpio(pdev)) {
- dev_err(&pdev->dev, "Unable to configure GPIO pins\n");
- return -EINVAL;
- }
-
- spdif = &spdif_info;
- spdif->dev = &pdev->dev;
-
- spin_lock_init(&spdif->lock);
-
- spdif->pclk = clk_get(&pdev->dev, "spdif");
- if (IS_ERR(spdif->pclk)) {
- dev_err(&pdev->dev, "failed to get peri-clock\n");
- ret = -ENOENT;
- goto err0;
- }
- clk_enable(spdif->pclk);
-
- spdif->sclk = clk_get(&pdev->dev, "sclk_spdif");
- if (IS_ERR(spdif->sclk)) {
- dev_err(&pdev->dev, "failed to get internal source clock\n");
- ret = -ENOENT;
- goto err1;
- }
- clk_enable(spdif->sclk);
-
- /* Request S/PDIF Register's memory region */
- if (!request_mem_region(mem_res->start,
- resource_size(mem_res), "samsung-spdif")) {
- dev_err(&pdev->dev, "Unable to request register region\n");
- ret = -EBUSY;
- goto err2;
- }
-
- spdif->regs = ioremap(mem_res->start, 0x100);
- if (spdif->regs == NULL) {
- dev_err(&pdev->dev, "Cannot ioremap registers\n");
- ret = -ENXIO;
- goto err3;
- }
-
- dev_set_drvdata(&pdev->dev, spdif);
-
- ret = snd_soc_register_dai(&pdev->dev, &samsung_spdif_dai);
- if (ret != 0) {
- dev_err(&pdev->dev, "fail to register dai\n");
- goto err4;
- }
-
- spdif_stereo_out.dma_size = 2;
- spdif_stereo_out.client = &spdif_dma_client_out;
- spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF;
- spdif_stereo_out.channel = dma_res->start;
-
- spdif->dma_playback = &spdif_stereo_out;
-
- return 0;
-
-err4:
- iounmap(spdif->regs);
-err3:
- release_mem_region(mem_res->start, resource_size(mem_res));
-err2:
- clk_disable(spdif->sclk);
- clk_put(spdif->sclk);
-err1:
- clk_disable(spdif->pclk);
- clk_put(spdif->pclk);
-err0:
- return ret;
-}
-
-static __devexit int spdif_remove(struct platform_device *pdev)
-{
- struct samsung_spdif_info *spdif = &spdif_info;
- struct resource *mem_res;
-
- snd_soc_unregister_dai(&pdev->dev);
-
- iounmap(spdif->regs);
-
- mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (mem_res)
- release_mem_region(mem_res->start, resource_size(mem_res));
-
- clk_disable(spdif->sclk);
- clk_put(spdif->sclk);
- clk_disable(spdif->pclk);
- clk_put(spdif->pclk);
-
- return 0;
-}
-
-static struct platform_driver samsung_spdif_driver = {
- .probe = spdif_probe,
- .remove = __devexit_p(spdif_remove),
- .driver = {
- .name = "samsung-spdif",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(samsung_spdif_driver);
-
-MODULE_AUTHOR("Seungwhan Youn, <sw.youn@samsung.com>");
-MODULE_DESCRIPTION("Samsung S/PDIF Controller Driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:samsung-spdif");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/spdif.h b/ANDROID_3.4.5/sound/soc/samsung/spdif.h
deleted file mode 100644
index 4f72cb44..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/spdif.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* sound/soc/samsung/spdif.h
- *
- * ALSA SoC Audio Layer - Samsung S/PDIF Controller driver
- *
- * Copyright (c) 2010 Samsung Electronics Co. Ltd
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __SND_SOC_SAMSUNG_SPDIF_H
-#define __SND_SOC_SAMSUNG_SPDIF_H __FILE__
-
-#define SND_SOC_SPDIF_INT_MCLK 0
-#define SND_SOC_SPDIF_EXT_MCLK 1
-
-#endif /* __SND_SOC_SAMSUNG_SPDIF_H */
diff --git a/ANDROID_3.4.5/sound/soc/samsung/speyside.c b/ANDROID_3.4.5/sound/soc/samsung/speyside.c
deleted file mode 100644
index f9ab7707..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/speyside.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Speyside audio support
- *
- * Copyright 2011 Wolfson Microelectronics
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/jack.h>
-#include <linux/gpio.h>
-#include <linux/module.h>
-
-#include "../codecs/wm8996.h"
-#include "../codecs/wm9081.h"
-
-#define WM8996_HPSEL_GPIO 214
-#define MCLK_AUDIO_RATE (512 * 48000)
-
-static int speyside_set_bias_level(struct snd_soc_card *card,
- struct snd_soc_dapm_context *dapm,
- enum snd_soc_bias_level level)
-{
- struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
- int ret;
-
- if (dapm->dev != codec_dai->dev)
- return 0;
-
- switch (level) {
- case SND_SOC_BIAS_STANDBY:
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8996_SYSCLK_MCLK2,
- 32768, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_pll(codec_dai, WM8996_FLL_MCLK2,
- 0, 0, 0);
- if (ret < 0) {
- pr_err("Failed to stop FLL\n");
- return ret;
- }
- break;
-
- default:
- break;
- }
-
- return 0;
-}
-
-static int speyside_set_bias_level_post(struct snd_soc_card *card,
- struct snd_soc_dapm_context *dapm,
- enum snd_soc_bias_level level)
-{
- struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
- int ret;
-
- if (dapm->dev != codec_dai->dev)
- return 0;
-
- switch (level) {
- case SND_SOC_BIAS_PREPARE:
- if (card->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
- ret = snd_soc_dai_set_pll(codec_dai, 0,
- WM8996_FLL_MCLK2,
- 32768, MCLK_AUDIO_RATE);
- if (ret < 0) {
- pr_err("Failed to start FLL\n");
- return ret;
- }
-
- ret = snd_soc_dai_set_sysclk(codec_dai,
- WM8996_SYSCLK_FLL,
- MCLK_AUDIO_RATE,
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
- }
- break;
-
- default:
- break;
- }
-
- card->dapm.bias_level = level;
-
- return 0;
-}
-
-static int speyside_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int ret;
-
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
- | SND_SOC_DAIFMT_NB_NF
- | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
- | SND_SOC_DAIFMT_NB_NF
- | SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct snd_soc_ops speyside_ops = {
- .hw_params = speyside_hw_params,
-};
-
-static struct snd_soc_jack speyside_headset;
-
-/* Headset jack detection DAPM pins */
-static struct snd_soc_jack_pin speyside_headset_pins[] = {
- {
- .pin = "Headset Mic",
- .mask = SND_JACK_MICROPHONE,
- },
-};
-
-/* Default the headphone selection to active high */
-static int speyside_jack_polarity;
-
-static int speyside_get_micbias(struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink)
-{
- if (speyside_jack_polarity && (strcmp(source->name, "MICB1") == 0))
- return 1;
- if (!speyside_jack_polarity && (strcmp(source->name, "MICB2") == 0))
- return 1;
-
- return 0;
-}
-
-static void speyside_set_polarity(struct snd_soc_codec *codec,
- int polarity)
-{
- speyside_jack_polarity = !polarity;
- gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity);
-
- /* Re-run DAPM to make sure we're using the correct mic bias */
- snd_soc_dapm_sync(&codec->dapm);
-}
-
-static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_dai *dai = rtd->codec_dai;
- struct snd_soc_codec *codec = rtd->codec;
- int ret;
-
- ret = snd_soc_dai_set_sysclk(dai, WM8996_SYSCLK_MCLK2, 32768, 0);
- if (ret < 0)
- return ret;
-
- ret = gpio_request(WM8996_HPSEL_GPIO, "HP_SEL");
- if (ret != 0)
- pr_err("Failed to request HP_SEL GPIO: %d\n", ret);
- gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity);
-
- ret = snd_soc_jack_new(codec, "Headset",
- SND_JACK_LINEOUT | SND_JACK_HEADSET |
- SND_JACK_BTN_0,
- &speyside_headset);
- if (ret)
- return ret;
-
- ret = snd_soc_jack_add_pins(&speyside_headset,
- ARRAY_SIZE(speyside_headset_pins),
- speyside_headset_pins);
- if (ret)
- return ret;
-
- wm8996_detect(codec, &speyside_headset, speyside_set_polarity);
-
- return 0;
-}
-
-static int speyside_late_probe(struct snd_soc_card *card)
-{
- snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
- snd_soc_dapm_ignore_suspend(&card->dapm, "Headset Mic");
- snd_soc_dapm_ignore_suspend(&card->dapm, "Main AMIC");
- snd_soc_dapm_ignore_suspend(&card->dapm, "Main DMIC");
- snd_soc_dapm_ignore_suspend(&card->dapm, "Main Speaker");
- snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Output");
- snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Input");
-
- return 0;
-}
-
-static struct snd_soc_dai_link speyside_dai[] = {
- {
- .name = "CPU",
- .stream_name = "CPU",
- .cpu_dai_name = "samsung-i2s.0",
- .codec_dai_name = "wm8996-aif1",
- .platform_name = "samsung-audio",
- .codec_name = "wm8996.1-001a",
- .init = speyside_wm8996_init,
- .ops = &speyside_ops,
- },
- {
- .name = "Baseband",
- .stream_name = "Baseband",
- .cpu_dai_name = "wm8996-aif2",
- .codec_dai_name = "wm1250-ev1",
- .codec_name = "wm1250-ev1.1-0027",
- .ops = &speyside_ops,
- .ignore_suspend = 1,
- },
-};
-
-static int speyside_wm9081_init(struct snd_soc_dapm_context *dapm)
-{
- /* At any time the WM9081 is active it will have this clock */
- return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, 0,
- MCLK_AUDIO_RATE, 0);
-}
-
-static struct snd_soc_aux_dev speyside_aux_dev[] = {
- {
- .name = "wm9081",
- .codec_name = "wm9081.1-006c",
- .init = speyside_wm9081_init,
- },
-};
-
-static struct snd_soc_codec_conf speyside_codec_conf[] = {
- {
- .dev_name = "wm9081.1-006c",
- .name_prefix = "Sub",
- },
-};
-
-static const struct snd_kcontrol_new controls[] = {
- SOC_DAPM_PIN_SWITCH("Main Speaker"),
- SOC_DAPM_PIN_SWITCH("Main DMIC"),
- SOC_DAPM_PIN_SWITCH("Main AMIC"),
- SOC_DAPM_PIN_SWITCH("WM1250 Input"),
- SOC_DAPM_PIN_SWITCH("WM1250 Output"),
- SOC_DAPM_PIN_SWITCH("Headphone"),
-};
-
-static struct snd_soc_dapm_widget widgets[] = {
- SND_SOC_DAPM_HP("Headphone", NULL),
- SND_SOC_DAPM_MIC("Headset Mic", NULL),
-
- SND_SOC_DAPM_SPK("Main Speaker", NULL),
-
- SND_SOC_DAPM_MIC("Main AMIC", NULL),
- SND_SOC_DAPM_MIC("Main DMIC", NULL),
-};
-
-static struct snd_soc_dapm_route audio_paths[] = {
- { "IN1RN", NULL, "MICB1" },
- { "IN1RP", NULL, "MICB1" },
- { "IN1RN", NULL, "MICB2" },
- { "IN1RP", NULL, "MICB2" },
- { "MICB1", NULL, "Headset Mic", speyside_get_micbias },
- { "MICB2", NULL, "Headset Mic", speyside_get_micbias },
-
- { "IN1LP", NULL, "MICB2" },
- { "IN1RN", NULL, "MICB1" },
- { "MICB2", NULL, "Main AMIC" },
-
- { "DMIC1DAT", NULL, "MICB1" },
- { "DMIC2DAT", NULL, "MICB1" },
- { "MICB1", NULL, "Main DMIC" },
-
- { "Headphone", NULL, "HPOUT1L" },
- { "Headphone", NULL, "HPOUT1R" },
-
- { "Sub IN1", NULL, "HPOUT2L" },
- { "Sub IN2", NULL, "HPOUT2R" },
-
- { "Main Speaker", NULL, "Sub SPKN" },
- { "Main Speaker", NULL, "Sub SPKP" },
- { "Main Speaker", NULL, "SPKDAT" },
-};
-
-static struct snd_soc_card speyside = {
- .name = "Speyside",
- .owner = THIS_MODULE,
- .dai_link = speyside_dai,
- .num_links = ARRAY_SIZE(speyside_dai),
- .aux_dev = speyside_aux_dev,
- .num_aux_devs = ARRAY_SIZE(speyside_aux_dev),
- .codec_conf = speyside_codec_conf,
- .num_configs = ARRAY_SIZE(speyside_codec_conf),
-
- .set_bias_level = speyside_set_bias_level,
- .set_bias_level_post = speyside_set_bias_level_post,
-
- .controls = controls,
- .num_controls = ARRAY_SIZE(controls),
- .dapm_widgets = widgets,
- .num_dapm_widgets = ARRAY_SIZE(widgets),
- .dapm_routes = audio_paths,
- .num_dapm_routes = ARRAY_SIZE(audio_paths),
- .fully_routed = true,
-
- .late_probe = speyside_late_probe,
-};
-
-static __devinit int speyside_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &speyside;
- int ret;
-
- card->dev = &pdev->dev;
-
- ret = snd_soc_register_card(card);
- if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
- ret);
- return ret;
- }
-
- return 0;
-}
-
-static int __devexit speyside_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- snd_soc_unregister_card(card);
-
- return 0;
-}
-
-static struct platform_driver speyside_driver = {
- .driver = {
- .name = "speyside",
- .owner = THIS_MODULE,
- .pm = &snd_soc_pm_ops,
- },
- .probe = speyside_probe,
- .remove = __devexit_p(speyside_remove),
-};
-
-module_platform_driver(speyside_driver);
-
-MODULE_DESCRIPTION("Speyside audio support");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:speyside");
diff --git a/ANDROID_3.4.5/sound/soc/samsung/tobermory.c b/ANDROID_3.4.5/sound/soc/samsung/tobermory.c
deleted file mode 100644
index 9199649b..00000000
--- a/ANDROID_3.4.5/sound/soc/samsung/tobermory.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Tobermory audio support
- *
- * Copyright 2011 Wolfson Microelectronics
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/jack.h>
-#include <linux/gpio.h>
-#include <linux/module.h>
-
-#include "../codecs/wm8962.h"
-
-static int sample_rate = 44100;
-
-static int tobermory_set_bias_level(struct snd_soc_card *card,
- struct snd_soc_dapm_context *dapm,
- enum snd_soc_bias_level level)
-{
- struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
- int ret;
-
- if (dapm->dev != codec_dai->dev)
- return 0;
-
- switch (level) {
- case SND_SOC_BIAS_PREPARE:
- if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
- ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL,
- WM8962_FLL_MCLK, 32768,
- sample_rate * 512);
- if (ret < 0)
- pr_err("Failed to start FLL: %d\n", ret);
-
- ret = snd_soc_dai_set_sysclk(codec_dai,
- WM8962_SYSCLK_FLL,
- sample_rate * 512,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- pr_err("Failed to set SYSCLK: %d\n", ret);
- return ret;
- }
- }
- break;
-
- default:
- break;
- }
-
- return 0;
-}
-
-static int tobermory_set_bias_level_post(struct snd_soc_card *card,
- struct snd_soc_dapm_context *dapm,
- enum snd_soc_bias_level level)
-{
- struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
- int ret;
-
- if (dapm->dev != codec_dai->dev)
- return 0;
-
- switch (level) {
- case SND_SOC_BIAS_STANDBY:
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK,
- 32768, SND_SOC_CLOCK_IN);
- if (ret < 0) {
- pr_err("Failed to switch away from FLL: %d\n", ret);
- return ret;
- }
-
- ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL,
- 0, 0, 0);
- if (ret < 0) {
- pr_err("Failed to stop FLL: %d\n", ret);
- return ret;
- }
- break;
-
- default:
- break;
- }
-
- dapm->bias_level = level;
-
- return 0;
-}
-
-static int tobermory_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- sample_rate = params_rate(params);
-
- return 0;
-}
-
-static struct snd_soc_ops tobermory_ops = {
- .hw_params = tobermory_hw_params,
-};
-
-static struct snd_soc_dai_link tobermory_dai[] = {
- {
- .name = "CPU",
- .stream_name = "CPU",
- .cpu_dai_name = "samsung-i2s.0",
- .codec_dai_name = "wm8962",
- .platform_name = "samsung-audio",
- .codec_name = "wm8962.1-001a",
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
- | SND_SOC_DAIFMT_CBM_CFM,
- .ops = &tobermory_ops,
- },
-};
-
-static const struct snd_kcontrol_new controls[] = {
- SOC_DAPM_PIN_SWITCH("Main Speaker"),
- SOC_DAPM_PIN_SWITCH("DMIC"),
-};
-
-static struct snd_soc_dapm_widget widgets[] = {
- SND_SOC_DAPM_HP("Headphone", NULL),
- SND_SOC_DAPM_MIC("Headset Mic", NULL),
-
- SND_SOC_DAPM_MIC("DMIC", NULL),
- SND_SOC_DAPM_MIC("AMIC", NULL),
-
- SND_SOC_DAPM_SPK("Main Speaker", NULL),
-};
-
-static struct snd_soc_dapm_route audio_paths[] = {
- { "Headphone", NULL, "HPOUTL" },
- { "Headphone", NULL, "HPOUTR" },
-
- { "Main Speaker", NULL, "SPKOUTL" },
- { "Main Speaker", NULL, "SPKOUTR" },
-
- { "Headset Mic", NULL, "MICBIAS" },
- { "IN4L", NULL, "Headset Mic" },
- { "IN4R", NULL, "Headset Mic" },
-
- { "AMIC", NULL, "MICBIAS" },
- { "IN1L", NULL, "AMIC" },
- { "IN1R", NULL, "AMIC" },
-
- { "DMIC", NULL, "MICBIAS" },
- { "DMICDAT", NULL, "DMIC" },
-};
-
-static struct snd_soc_jack tobermory_headset;
-
-/* Headset jack detection DAPM pins */
-static struct snd_soc_jack_pin tobermory_headset_pins[] = {
- {
- .pin = "Headset Mic",
- .mask = SND_JACK_MICROPHONE,
- },
- {
- .pin = "Headphone",
- .mask = SND_JACK_MICROPHONE,
- },
-};
-
-static int tobermory_late_probe(struct snd_soc_card *card)
-{
- struct snd_soc_codec *codec = card->rtd[0].codec;
- struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
- int ret;
-
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK,
- 32768, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_jack_new(codec, "Headset",
- SND_JACK_HEADSET | SND_JACK_BTN_0,
- &tobermory_headset);
- if (ret)
- return ret;
-
- ret = snd_soc_jack_add_pins(&tobermory_headset,
- ARRAY_SIZE(tobermory_headset_pins),
- tobermory_headset_pins);
- if (ret)
- return ret;
-
- wm8962_mic_detect(codec, &tobermory_headset);
-
- return 0;
-}
-
-static struct snd_soc_card tobermory = {
- .name = "Tobermory",
- .owner = THIS_MODULE,
- .dai_link = tobermory_dai,
- .num_links = ARRAY_SIZE(tobermory_dai),
-
- .set_bias_level = tobermory_set_bias_level,
- .set_bias_level_post = tobermory_set_bias_level_post,
-
- .controls = controls,
- .num_controls = ARRAY_SIZE(controls),
- .dapm_widgets = widgets,
- .num_dapm_widgets = ARRAY_SIZE(widgets),
- .dapm_routes = audio_paths,
- .num_dapm_routes = ARRAY_SIZE(audio_paths),
- .fully_routed = true,
-
- .late_probe = tobermory_late_probe,
-};
-
-static __devinit int tobermory_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &tobermory;
- int ret;
-
- card->dev = &pdev->dev;
-
- ret = snd_soc_register_card(card);
- if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
- ret);
- return ret;
- }
-
- return 0;
-}
-
-static int __devexit tobermory_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- snd_soc_unregister_card(card);
-
- return 0;
-}
-
-static struct platform_driver tobermory_driver = {
- .driver = {
- .name = "tobermory",
- .owner = THIS_MODULE,
- .pm = &snd_soc_pm_ops,
- },
- .probe = tobermory_probe,
- .remove = __devexit_p(tobermory_remove),
-};
-
-module_platform_driver(tobermory_driver);
-
-MODULE_DESCRIPTION("Tobermory audio support");
-MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:tobermory");
diff --git a/ANDROID_3.4.5/sound/soc/sh/Kconfig b/ANDROID_3.4.5/sound/soc/sh/Kconfig
deleted file mode 100644
index d8e06a60..00000000
--- a/ANDROID_3.4.5/sound/soc/sh/Kconfig
+++ /dev/null
@@ -1,80 +0,0 @@
-menu "SoC Audio support for SuperH"
- depends on SUPERH || ARCH_SHMOBILE
-
-config SND_SOC_PCM_SH7760
- tristate "SoC Audio support for Renesas SH7760"
- depends on CPU_SUBTYPE_SH7760 && SH_DMABRG
- help
- Enable this option for SH7760 AC97/I2S audio support.
-
-
-##
-## Audio unit modules
-##
-
-config SND_SOC_SH4_HAC
- tristate
- select AC97_BUS
- select SND_SOC_AC97_BUS
-
-config SND_SOC_SH4_SSI
- tristate
-
-config SND_SOC_SH4_FSI
- tristate "SH4 FSI support"
- help
- This option enables FSI sound support
-
-config SND_SOC_SH4_SIU
- tristate
- depends on (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
- select DMA_ENGINE
- select DMADEVICES
- select SH_DMAE
- select FW_LOADER
-
-##
-## Boards
-##
-
-config SND_SH7760_AC97
- tristate "SH7760 AC97 sound support"
- depends on CPU_SUBTYPE_SH7760 && SND_SOC_PCM_SH7760
- select SND_SOC_SH4_HAC
- select SND_SOC_AC97_CODEC
- help
- This option enables generic sound support for the first
- AC97 unit of the SH7760.
-
-config SND_FSI_AK4642
- tristate "FSI-AK4642 sound support"
- depends on SND_SOC_SH4_FSI && I2C
- select SND_SOC_AK4642
- help
- This option enables generic sound support for the
- FSI - AK4642 unit
-
-config SND_FSI_DA7210
- tristate "FSI-DA7210 sound support"
- depends on SND_SOC_SH4_FSI && I2C
- select SND_SOC_DA7210
- help
- This option enables generic sound support for the
- FSI - DA7210 unit
-
-config SND_FSI_HDMI
- tristate "FSI-HDMI sound support"
- depends on SND_SOC_SH4_FSI && FB_SH_MOBILE_HDMI
- help
- This option enables generic sound support for the
- FSI - HDMI unit
-
-config SND_SIU_MIGOR
- tristate "SIU sound support on Migo-R"
- depends on SH_MIGOR
- select SND_SOC_SH4_SIU
- select SND_SOC_WM8978
- help
- This option enables sound support for the SH7722 Migo-R board
-
-endmenu
diff --git a/ANDROID_3.4.5/sound/soc/sh/Makefile b/ANDROID_3.4.5/sound/soc/sh/Makefile
deleted file mode 100644
index 94476d4c..00000000
--- a/ANDROID_3.4.5/sound/soc/sh/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-## DMA engines
-snd-soc-dma-sh7760-objs := dma-sh7760.o
-obj-$(CONFIG_SND_SOC_PCM_SH7760) += snd-soc-dma-sh7760.o
-
-## audio units found on some SH-4
-snd-soc-hac-objs := hac.o
-snd-soc-ssi-objs := ssi.o
-snd-soc-fsi-objs := fsi.o
-snd-soc-siu-objs := siu_pcm.o siu_dai.o
-obj-$(CONFIG_SND_SOC_SH4_HAC) += snd-soc-hac.o
-obj-$(CONFIG_SND_SOC_SH4_SSI) += snd-soc-ssi.o
-obj-$(CONFIG_SND_SOC_SH4_FSI) += snd-soc-fsi.o
-obj-$(CONFIG_SND_SOC_SH4_SIU) += snd-soc-siu.o
-
-## boards
-snd-soc-sh7760-ac97-objs := sh7760-ac97.o
-snd-soc-fsi-ak4642-objs := fsi-ak4642.o
-snd-soc-fsi-da7210-objs := fsi-da7210.o
-snd-soc-fsi-hdmi-objs := fsi-hdmi.o
-snd-soc-migor-objs := migor.o
-
-obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o
-obj-$(CONFIG_SND_FSI_AK4642) += snd-soc-fsi-ak4642.o
-obj-$(CONFIG_SND_FSI_DA7210) += snd-soc-fsi-da7210.o
-obj-$(CONFIG_SND_FSI_HDMI) += snd-soc-fsi-hdmi.o
-obj-$(CONFIG_SND_SIU_MIGOR) += snd-soc-migor.o
diff --git a/ANDROID_3.4.5/sound/soc/sh/dma-sh7760.c b/ANDROID_3.4.5/sound/soc/sh/dma-sh7760.c
deleted file mode 100644
index 7da20186..00000000
--- a/ANDROID_3.4.5/sound/soc/sh/dma-sh7760.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * SH7760 ("camelot") DMABRG audio DMA unit support
- *
- * Copyright (C) 2007 Manuel Lauss <mano@roarinelk.homelinux.net>
- * licensed under the terms outlined in the file COPYING at the root
- * of the linux kernel sources.
- *
- * The SH7760 DMABRG provides 4 dma channels (2x rec, 2x play), which
- * trigger an interrupt when one half of the programmed transfer size
- * has been xmitted.
- *
- * FIXME: little-endian only for now
- */
-
-#include <linux/module.h>
-#include <linux/gfp.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <asm/dmabrg.h>
-
-
-/* registers and bits */
-#define BRGATXSAR 0x00
-#define BRGARXDAR 0x04
-#define BRGATXTCR 0x08
-#define BRGARXTCR 0x0C
-#define BRGACR 0x10
-#define BRGATXTCNT 0x14
-#define BRGARXTCNT 0x18
-
-#define ACR_RAR (1 << 18)
-#define ACR_RDS (1 << 17)
-#define ACR_RDE (1 << 16)
-#define ACR_TAR (1 << 2)
-#define ACR_TDS (1 << 1)
-#define ACR_TDE (1 << 0)
-
-/* receiver/transmitter data alignment */
-#define ACR_RAM_NONE (0 << 24)
-#define ACR_RAM_4BYTE (1 << 24)
-#define ACR_RAM_2WORD (2 << 24)
-#define ACR_TAM_NONE (0 << 8)
-#define ACR_TAM_4BYTE (1 << 8)
-#define ACR_TAM_2WORD (2 << 8)
-
-
-struct camelot_pcm {
- unsigned long mmio; /* DMABRG audio channel control reg MMIO */
- unsigned int txid; /* ID of first DMABRG IRQ for this unit */
-
- struct snd_pcm_substream *tx_ss;
- unsigned long tx_period_size;
- unsigned int tx_period;
-
- struct snd_pcm_substream *rx_ss;
- unsigned long rx_period_size;
- unsigned int rx_period;
-
-} cam_pcm_data[2] = {
- {
- .mmio = 0xFE3C0040,
- .txid = DMABRGIRQ_A0TXF,
- },
- {
- .mmio = 0xFE3C0060,
- .txid = DMABRGIRQ_A1TXF,
- },
-};
-
-#define BRGREG(x) (*(unsigned long *)(cam->mmio + (x)))
-
-/*
- * set a minimum of 16kb per period, to avoid interrupt-"storm" and
- * resulting skipping. In general, the bigger the minimum size, the
- * better for overall system performance. (The SH7760 is a puny CPU
- * with a slow SDRAM interface and poor internal bus bandwidth,
- * *especially* when the LCDC is active). The minimum for the DMAC
- * is 8 bytes; 16kbytes are enough to get skip-free playback of a
- * 44kHz/16bit/stereo MP3 on a lightly loaded system, and maintain
- * reasonable responsiveness in MPlayer.
- */
-#define DMABRG_PERIOD_MIN 16 * 1024
-#define DMABRG_PERIOD_MAX 0x03fffffc
-#define DMABRG_PREALLOC_BUFFER 32 * 1024
-#define DMABRG_PREALLOC_BUFFER_MAX 32 * 1024
-
-/* support everything the SSI supports */
-#define DMABRG_RATES \
- SNDRV_PCM_RATE_8000_192000
-
-#define DMABRG_FMTS \
- (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \
- SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \
- SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \
- SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE)
-
-static struct snd_pcm_hardware camelot_pcm_hardware = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BATCH),
- .formats = DMABRG_FMTS,
- .rates = DMABRG_RATES,
- .rate_min = 8000,
- .rate_max = 192000,
- .channels_min = 2,
- .channels_max = 8, /* max of the SSI */
- .buffer_bytes_max = DMABRG_PERIOD_MAX,
- .period_bytes_min = DMABRG_PERIOD_MIN,
- .period_bytes_max = DMABRG_PERIOD_MAX / 2,
- .periods_min = 2,
- .periods_max = 2,
- .fifo_size = 128,
-};
-
-static void camelot_txdma(void *data)
-{
- struct camelot_pcm *cam = data;
- cam->tx_period ^= 1;
- snd_pcm_period_elapsed(cam->tx_ss);
-}
-
-static void camelot_rxdma(void *data)
-{
- struct camelot_pcm *cam = data;
- cam->rx_period ^= 1;
- snd_pcm_period_elapsed(cam->rx_ss);
-}
-
-static int camelot_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id];
- int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1;
- int ret, dmairq;
-
- snd_soc_set_runtime_hwparams(substream, &camelot_pcm_hardware);
-
- /* DMABRG buffer half/full events */
- dmairq = (recv) ? cam->txid + 2 : cam->txid;
- if (recv) {
- cam->rx_ss = substream;
- ret = dmabrg_request_irq(dmairq, camelot_rxdma, cam);
- if (unlikely(ret)) {
- pr_debug("audio unit %d irqs already taken!\n",
- rtd->cpu_dai->id);
- return -EBUSY;
- }
- (void)dmabrg_request_irq(dmairq + 1,camelot_rxdma, cam);
- } else {
- cam->tx_ss = substream;
- ret = dmabrg_request_irq(dmairq, camelot_txdma, cam);
- if (unlikely(ret)) {
- pr_debug("audio unit %d irqs already taken!\n",
- rtd->cpu_dai->id);
- return -EBUSY;
- }
- (void)dmabrg_request_irq(dmairq + 1, camelot_txdma, cam);
- }
- return 0;
-}
-
-static int camelot_pcm_close(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id];
- int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1;
- int dmairq;
-
- dmairq = (recv) ? cam->txid + 2 : cam->txid;
-
- if (recv)
- cam->rx_ss = NULL;
- else
- cam->tx_ss = NULL;
-
- dmabrg_free_irq(dmairq + 1);
- dmabrg_free_irq(dmairq);
-
- return 0;
-}
-
-static int camelot_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id];
- int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1;
- int ret;
-
- ret = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- if (ret < 0)
- return ret;
-
- if (recv) {
- cam->rx_period_size = params_period_bytes(hw_params);
- cam->rx_period = 0;
- } else {
- cam->tx_period_size = params_period_bytes(hw_params);
- cam->tx_period = 0;
- }
- return 0;
-}
-
-static int camelot_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int camelot_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id];
-
- pr_debug("PCM data: addr 0x%08ulx len %d\n",
- (u32)runtime->dma_addr, runtime->dma_bytes);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- BRGREG(BRGATXSAR) = (unsigned long)runtime->dma_area;
- BRGREG(BRGATXTCR) = runtime->dma_bytes;
- } else {
- BRGREG(BRGARXDAR) = (unsigned long)runtime->dma_area;
- BRGREG(BRGARXTCR) = runtime->dma_bytes;
- }
-
- return 0;
-}
-
-static inline void dmabrg_play_dma_start(struct camelot_pcm *cam)
-{
- unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS);
- /* start DMABRG engine: XFER start, auto-addr-reload */
- BRGREG(BRGACR) = acr | ACR_TDE | ACR_TAR | ACR_TAM_2WORD;
-}
-
-static inline void dmabrg_play_dma_stop(struct camelot_pcm *cam)
-{
- unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS);
- /* forcibly terminate data transmission */
- BRGREG(BRGACR) = acr | ACR_TDS;
-}
-
-static inline void dmabrg_rec_dma_start(struct camelot_pcm *cam)
-{
- unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS);
- /* start DMABRG engine: recv start, auto-reload */
- BRGREG(BRGACR) = acr | ACR_RDE | ACR_RAR | ACR_RAM_2WORD;
-}
-
-static inline void dmabrg_rec_dma_stop(struct camelot_pcm *cam)
-{
- unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS);
- /* forcibly terminate data receiver */
- BRGREG(BRGACR) = acr | ACR_RDS;
-}
-
-static int camelot_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id];
- int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- if (recv)
- dmabrg_rec_dma_start(cam);
- else
- dmabrg_play_dma_start(cam);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- if (recv)
- dmabrg_rec_dma_stop(cam);
- else
- dmabrg_play_dma_stop(cam);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static snd_pcm_uframes_t camelot_pos(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id];
- int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1;
- unsigned long pos;
-
- /* cannot use the DMABRG pointer register: under load, by the
- * time ALSA comes around to read the register, it is already
- * far ahead (or worse, already done with the fragment) of the
- * position at the time the IRQ was triggered, which results in
- * fast-playback sound in my test application (ScummVM)
- */
- if (recv)
- pos = cam->rx_period ? cam->rx_period_size : 0;
- else
- pos = cam->tx_period ? cam->tx_period_size : 0;
-
- return bytes_to_frames(runtime, pos);
-}
-
-static struct snd_pcm_ops camelot_pcm_ops = {
- .open = camelot_pcm_open,
- .close = camelot_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = camelot_hw_params,
- .hw_free = camelot_hw_free,
- .prepare = camelot_prepare,
- .trigger = camelot_trigger,
- .pointer = camelot_pos,
-};
-
-static void camelot_pcm_free(struct snd_pcm *pcm)
-{
- snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int camelot_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_pcm *pcm = rtd->pcm;
-
- /* dont use SNDRV_DMA_TYPE_DEV, since it will oops the SH kernel
- * in MMAP mode (i.e. aplay -M)
- */
- snd_pcm_lib_preallocate_pages_for_all(pcm,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- DMABRG_PREALLOC_BUFFER, DMABRG_PREALLOC_BUFFER_MAX);
-
- return 0;
-}
-
-static struct snd_soc_platform sh7760_soc_platform = {
- .pcm_ops = &camelot_pcm_ops,
- .pcm_new = camelot_pcm_new,
- .pcm_free = camelot_pcm_free,
-};
-
-static int __devinit sh7760_soc_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_platform(&pdev->dev, &sh7760_soc_platform);
-}
-
-static int __devexit sh7760_soc_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver sh7760_pcm_driver = {
- .driver = {
- .name = "sh7760-pcm-audio",
- .owner = THIS_MODULE,
- },
-
- .probe = sh7760_soc_platform_probe,
- .remove = __devexit_p(sh7760_soc_platform_remove),
-};
-
-module_platform_driver(sh7760_pcm_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("SH7760 Audio DMA (DMABRG) driver");
-MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/ANDROID_3.4.5/sound/soc/sh/fsi-ak4642.c b/ANDROID_3.4.5/sound/soc/sh/fsi-ak4642.c
deleted file mode 100644
index 97f540aa..00000000
--- a/ANDROID_3.4.5/sound/soc/sh/fsi-ak4642.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * FSI-AK464x sound support for ms7724se
- *
- * Copyright (C) 2009 Renesas Solutions Corp.
- * Kuninori Morimoto <morimoto.kuninori@renesas.com>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/sh_fsi.h>
-
-struct fsi_ak4642_data {
- const char *name;
- const char *card;
- const char *cpu_dai;
- const char *codec;
- const char *platform;
- int id;
-};
-
-static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_dai *codec = rtd->codec_dai;
- struct snd_soc_dai *cpu = rtd->cpu_dai;
- int ret;
-
- ret = snd_soc_dai_set_fmt(codec, SND_SOC_DAIFMT_LEFT_J |
- SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_sysclk(codec, 0, 11289600, 0);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_LEFT_J |
- SND_SOC_DAIFMT_CBS_CFS);
-
- return ret;
-}
-
-static struct snd_soc_dai_link fsi_dai_link = {
- .codec_dai_name = "ak4642-hifi",
- .init = fsi_ak4642_dai_init,
-};
-
-static struct snd_soc_card fsi_soc_card = {
- .owner = THIS_MODULE,
- .dai_link = &fsi_dai_link,
- .num_links = 1,
-};
-
-static struct platform_device *fsi_snd_device;
-
-static int fsi_ak4642_probe(struct platform_device *pdev)
-{
- int ret = -ENOMEM;
- struct fsi_ak4642_info *pinfo = pdev->dev.platform_data;
-
- if (!pinfo) {
- dev_err(&pdev->dev, "no info for fsi ak4642\n");
- goto out;
- }
-
- fsi_snd_device = platform_device_alloc("soc-audio", pinfo->id);
- if (!fsi_snd_device)
- goto out;
-
- fsi_dai_link.name = pinfo->name;
- fsi_dai_link.stream_name = pinfo->name;
- fsi_dai_link.cpu_dai_name = pinfo->cpu_dai;
- fsi_dai_link.platform_name = pinfo->platform;
- fsi_dai_link.codec_name = pinfo->codec;
- fsi_soc_card.name = pinfo->card;
-
- platform_set_drvdata(fsi_snd_device, &fsi_soc_card);
- ret = platform_device_add(fsi_snd_device);
-
- if (ret)
- platform_device_put(fsi_snd_device);
-
-out:
- return ret;
-}
-
-static int fsi_ak4642_remove(struct platform_device *pdev)
-{
- platform_device_unregister(fsi_snd_device);
- return 0;
-}
-
-static struct platform_driver fsi_ak4642 = {
- .driver = {
- .name = "fsi-ak4642-audio",
- },
- .probe = fsi_ak4642_probe,
- .remove = fsi_ak4642_remove,
-};
-
-module_platform_driver(fsi_ak4642);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Generic SH4 FSI-AK4642 sound card");
-MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
diff --git a/ANDROID_3.4.5/sound/soc/sh/fsi-da7210.c b/ANDROID_3.4.5/sound/soc/sh/fsi-da7210.c
deleted file mode 100644
index 1dd3354c..00000000
--- a/ANDROID_3.4.5/sound/soc/sh/fsi-da7210.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * fsi-da7210.c
- *
- * Copyright (C) 2009 Renesas Solutions Corp.
- * Kuninori Morimoto <morimoto.kuninori@renesas.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/sh_fsi.h>
-
-static int fsi_da7210_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_dai *codec = rtd->codec_dai;
- struct snd_soc_dai *cpu = rtd->cpu_dai;
- int ret;
-
- ret = snd_soc_dai_set_fmt(codec,
- SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_CBM_CFM);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_CBS_CFS);
-
- return ret;
-}
-
-static struct snd_soc_dai_link fsi_da7210_dai = {
- .name = "DA7210",
- .stream_name = "DA7210",
- .cpu_dai_name = "fsib-dai", /* FSI B */
- .codec_dai_name = "da7210-hifi",
- .platform_name = "sh_fsi.0",
- .codec_name = "da7210-codec.0-001a",
- .init = fsi_da7210_init,
-};
-
-static struct snd_soc_card fsi_soc_card = {
- .name = "FSI-DA7210",
- .owner = THIS_MODULE,
- .dai_link = &fsi_da7210_dai,
- .num_links = 1,
-};
-
-static struct platform_device *fsi_da7210_snd_device;
-
-static int __init fsi_da7210_sound_init(void)
-{
- int ret;
-
- fsi_da7210_snd_device = platform_device_alloc("soc-audio", FSI_PORT_B);
- if (!fsi_da7210_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(fsi_da7210_snd_device, &fsi_soc_card);
- ret = platform_device_add(fsi_da7210_snd_device);
- if (ret)
- platform_device_put(fsi_da7210_snd_device);
-
- return ret;
-}
-
-static void __exit fsi_da7210_sound_exit(void)
-{
- platform_device_unregister(fsi_da7210_snd_device);
-}
-
-module_init(fsi_da7210_sound_init);
-module_exit(fsi_da7210_sound_exit);
-
-/* Module information */
-MODULE_DESCRIPTION("ALSA SoC FSI DA2710");
-MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/sh/fsi-hdmi.c b/ANDROID_3.4.5/sound/soc/sh/fsi-hdmi.c
deleted file mode 100644
index 6e419083..00000000
--- a/ANDROID_3.4.5/sound/soc/sh/fsi-hdmi.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * FSI - HDMI sound support
- *
- * Copyright (C) 2010 Renesas Solutions Corp.
- * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/sh_fsi.h>
-
-struct fsi_hdmi_data {
- const char *cpu_dai;
- const char *card;
- int id;
-};
-
-static int fsi_hdmi_dai_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_dai *cpu = rtd->cpu_dai;
- int ret;
-
- ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_CBM_CFM);
-
- return ret;
-}
-
-static struct snd_soc_dai_link fsi_dai_link = {
- .name = "HDMI",
- .stream_name = "HDMI",
- .codec_dai_name = "sh_mobile_hdmi-hifi",
- .platform_name = "sh_fsi2",
- .codec_name = "sh-mobile-hdmi",
- .init = fsi_hdmi_dai_init,
-};
-
-static struct snd_soc_card fsi_soc_card = {
- .owner = THIS_MODULE,
- .dai_link = &fsi_dai_link,
- .num_links = 1,
-};
-
-static struct platform_device *fsi_snd_device;
-
-static int fsi_hdmi_probe(struct platform_device *pdev)
-{
- int ret = -ENOMEM;
- const struct platform_device_id *id_entry;
- struct fsi_hdmi_data *pdata;
-
- id_entry = pdev->id_entry;
- if (!id_entry) {
- dev_err(&pdev->dev, "unknown fsi hdmi\n");
- return -ENODEV;
- }
-
- pdata = (struct fsi_hdmi_data *)id_entry->driver_data;
-
- fsi_snd_device = platform_device_alloc("soc-audio", pdata->id);
- if (!fsi_snd_device)
- goto out;
-
- fsi_dai_link.cpu_dai_name = pdata->cpu_dai;
- fsi_soc_card.name = pdata->card;
-
- platform_set_drvdata(fsi_snd_device, &fsi_soc_card);
- ret = platform_device_add(fsi_snd_device);
-
- if (ret)
- platform_device_put(fsi_snd_device);
-
-out:
- return ret;
-}
-
-static int fsi_hdmi_remove(struct platform_device *pdev)
-{
- platform_device_unregister(fsi_snd_device);
- return 0;
-}
-
-static struct fsi_hdmi_data fsi2_a_hdmi = {
- .cpu_dai = "fsia-dai",
- .card = "FSI2A-HDMI",
- .id = FSI_PORT_A,
-};
-
-static struct fsi_hdmi_data fsi2_b_hdmi = {
- .cpu_dai = "fsib-dai",
- .card = "FSI2B-HDMI",
- .id = FSI_PORT_B,
-};
-
-static struct platform_device_id fsi_id_table[] = {
- /* FSI 2 */
- { "sh_fsi2_a_hdmi", (kernel_ulong_t)&fsi2_a_hdmi },
- { "sh_fsi2_b_hdmi", (kernel_ulong_t)&fsi2_b_hdmi },
- {},
-};
-
-static struct platform_driver fsi_hdmi = {
- .driver = {
- .name = "fsi-hdmi-audio",
- },
- .probe = fsi_hdmi_probe,
- .remove = fsi_hdmi_remove,
- .id_table = fsi_id_table,
-};
-
-module_platform_driver(fsi_hdmi);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Generic SH4 FSI-HDMI sound card");
-MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/ANDROID_3.4.5/sound/soc/sh/fsi.c b/ANDROID_3.4.5/sound/soc/sh/fsi.c
deleted file mode 100644
index 74ed2dff..00000000
--- a/ANDROID_3.4.5/sound/soc/sh/fsi.c
+++ /dev/null
@@ -1,1771 +0,0 @@
-/*
- * Fifo-attached Serial Interface (FSI) support for SH7724
- *
- * Copyright (C) 2009 Renesas Solutions Corp.
- * Kuninori Morimoto <morimoto.kuninori@renesas.com>
- *
- * Based on ssi.c
- * Copyright (c) 2007 Manuel Lauss <mano@roarinelk.homelinux.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <linux/pm_runtime.h>
-#include <linux/io.h>
-#include <linux/scatterlist.h>
-#include <linux/sh_dma.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/soc.h>
-#include <sound/sh_fsi.h>
-
-/* PortA/PortB register */
-#define REG_DO_FMT 0x0000
-#define REG_DOFF_CTL 0x0004
-#define REG_DOFF_ST 0x0008
-#define REG_DI_FMT 0x000C
-#define REG_DIFF_CTL 0x0010
-#define REG_DIFF_ST 0x0014
-#define REG_CKG1 0x0018
-#define REG_CKG2 0x001C
-#define REG_DIDT 0x0020
-#define REG_DODT 0x0024
-#define REG_MUTE_ST 0x0028
-#define REG_OUT_DMAC 0x002C
-#define REG_OUT_SEL 0x0030
-#define REG_IN_DMAC 0x0038
-
-/* master register */
-#define MST_CLK_RST 0x0210
-#define MST_SOFT_RST 0x0214
-#define MST_FIFO_SZ 0x0218
-
-/* core register (depend on FSI version) */
-#define A_MST_CTLR 0x0180
-#define B_MST_CTLR 0x01A0
-#define CPU_INT_ST 0x01F4
-#define CPU_IEMSK 0x01F8
-#define CPU_IMSK 0x01FC
-#define INT_ST 0x0200
-#define IEMSK 0x0204
-#define IMSK 0x0208
-
-/* DO_FMT */
-/* DI_FMT */
-#define CR_BWS_MASK (0x3 << 20) /* FSI2 */
-#define CR_BWS_24 (0x0 << 20) /* FSI2 */
-#define CR_BWS_16 (0x1 << 20) /* FSI2 */
-#define CR_BWS_20 (0x2 << 20) /* FSI2 */
-
-#define CR_DTMD_PCM (0x0 << 8) /* FSI2 */
-#define CR_DTMD_SPDIF_PCM (0x1 << 8) /* FSI2 */
-#define CR_DTMD_SPDIF_STREAM (0x2 << 8) /* FSI2 */
-
-#define CR_MONO (0x0 << 4)
-#define CR_MONO_D (0x1 << 4)
-#define CR_PCM (0x2 << 4)
-#define CR_I2S (0x3 << 4)
-#define CR_TDM (0x4 << 4)
-#define CR_TDM_D (0x5 << 4)
-
-/* OUT_DMAC */
-/* IN_DMAC */
-#define VDMD_MASK (0x3 << 4)
-#define VDMD_FRONT (0x0 << 4) /* Package in front */
-#define VDMD_BACK (0x1 << 4) /* Package in back */
-#define VDMD_STREAM (0x2 << 4) /* Stream mode(16bit * 2) */
-
-#define DMA_ON (0x1 << 0)
-
-/* DOFF_CTL */
-/* DIFF_CTL */
-#define IRQ_HALF 0x00100000
-#define FIFO_CLR 0x00000001
-
-/* DOFF_ST */
-#define ERR_OVER 0x00000010
-#define ERR_UNDER 0x00000001
-#define ST_ERR (ERR_OVER | ERR_UNDER)
-
-/* CKG1 */
-#define ACKMD_MASK 0x00007000
-#define BPFMD_MASK 0x00000700
-#define DIMD (1 << 4)
-#define DOMD (1 << 0)
-
-/* A/B MST_CTLR */
-#define BP (1 << 4) /* Fix the signal of Biphase output */
-#define SE (1 << 0) /* Fix the master clock */
-
-/* CLK_RST */
-#define CRB (1 << 4)
-#define CRA (1 << 0)
-
-/* IO SHIFT / MACRO */
-#define BI_SHIFT 12
-#define BO_SHIFT 8
-#define AI_SHIFT 4
-#define AO_SHIFT 0
-#define AB_IO(param, shift) (param << shift)
-
-/* SOFT_RST */
-#define PBSR (1 << 12) /* Port B Software Reset */
-#define PASR (1 << 8) /* Port A Software Reset */
-#define IR (1 << 4) /* Interrupt Reset */
-#define FSISR (1 << 0) /* Software Reset */
-
-/* OUT_SEL (FSI2) */
-#define DMMD (1 << 4) /* SPDIF output timing 0: Biphase only */
- /* 1: Biphase and serial */
-
-/* FIFO_SZ */
-#define FIFO_SZ_MASK 0x7
-
-#define FSI_RATES SNDRV_PCM_RATE_8000_96000
-
-#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
-
-typedef int (*set_rate_func)(struct device *dev, int rate, int enable);
-
-/*
- * FSI driver use below type name for variable
- *
- * xxx_num : number of data
- * xxx_pos : position of data
- * xxx_capa : capacity of data
- */
-
-/*
- * period/frame/sample image
- *
- * ex) PCM (2ch)
- *
- * period pos period pos
- * [n] [n + 1]
- * |<-------------------- period--------------------->|
- * ==|============================================ ... =|==
- * | |
- * ||<----- frame ----->|<------ frame ----->| ... |
- * |+--------------------+--------------------+- ... |
- * ||[ sample ][ sample ]|[ sample ][ sample ]| ... |
- * |+--------------------+--------------------+- ... |
- * ==|============================================ ... =|==
- */
-
-/*
- * FSI FIFO image
- *
- * | |
- * | |
- * | [ sample ] |
- * | [ sample ] |
- * | [ sample ] |
- * | [ sample ] |
- * --> go to codecs
- */
-
-/*
- * struct
- */
-
-struct fsi_stream_handler;
-struct fsi_stream {
-
- /*
- * these are initialized by fsi_stream_init()
- */
- struct snd_pcm_substream *substream;
- int fifo_sample_capa; /* sample capacity of FSI FIFO */
- int buff_sample_capa; /* sample capacity of ALSA buffer */
- int buff_sample_pos; /* sample position of ALSA buffer */
- int period_samples; /* sample number / 1 period */
- int period_pos; /* current period position */
- int sample_width; /* sample width */
- int uerr_num;
- int oerr_num;
-
- /*
- * thse are initialized by fsi_handler_init()
- */
- struct fsi_stream_handler *handler;
- struct fsi_priv *priv;
-
- /*
- * these are for DMAEngine
- */
- struct dma_chan *chan;
- struct sh_dmae_slave slave; /* see fsi_handler_init() */
- struct tasklet_struct tasklet;
- dma_addr_t dma;
-};
-
-struct fsi_priv {
- void __iomem *base;
- struct fsi_master *master;
- struct sh_fsi_port_info *info;
-
- struct fsi_stream playback;
- struct fsi_stream capture;
-
- u32 do_fmt;
- u32 di_fmt;
-
- int chan_num:16;
- int clk_master:1;
- int spdif:1;
-
- long rate;
-};
-
-struct fsi_stream_handler {
- int (*init)(struct fsi_priv *fsi, struct fsi_stream *io);
- int (*quit)(struct fsi_priv *fsi, struct fsi_stream *io);
- int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io);
- int (*transfer)(struct fsi_priv *fsi, struct fsi_stream *io);
- int (*remove)(struct fsi_priv *fsi, struct fsi_stream *io);
- void (*start_stop)(struct fsi_priv *fsi, struct fsi_stream *io,
- int enable);
-};
-#define fsi_stream_handler_call(io, func, args...) \
- (!(io) ? -ENODEV : \
- !((io)->handler->func) ? 0 : \
- (io)->handler->func(args))
-
-struct fsi_core {
- int ver;
-
- u32 int_st;
- u32 iemsk;
- u32 imsk;
- u32 a_mclk;
- u32 b_mclk;
-};
-
-struct fsi_master {
- void __iomem *base;
- int irq;
- struct fsi_priv fsia;
- struct fsi_priv fsib;
- struct fsi_core *core;
- spinlock_t lock;
-};
-
-static int fsi_stream_is_play(struct fsi_priv *fsi, struct fsi_stream *io);
-
-/*
- * basic read write function
- */
-
-static void __fsi_reg_write(u32 __iomem *reg, u32 data)
-{
- /* valid data area is 24bit */
- data &= 0x00ffffff;
-
- __raw_writel(data, reg);
-}
-
-static u32 __fsi_reg_read(u32 __iomem *reg)
-{
- return __raw_readl(reg);
-}
-
-static void __fsi_reg_mask_set(u32 __iomem *reg, u32 mask, u32 data)
-{
- u32 val = __fsi_reg_read(reg);
-
- val &= ~mask;
- val |= data & mask;
-
- __fsi_reg_write(reg, val);
-}
-
-#define fsi_reg_write(p, r, d)\
- __fsi_reg_write((p->base + REG_##r), d)
-
-#define fsi_reg_read(p, r)\
- __fsi_reg_read((p->base + REG_##r))
-
-#define fsi_reg_mask_set(p, r, m, d)\
- __fsi_reg_mask_set((p->base + REG_##r), m, d)
-
-#define fsi_master_read(p, r) _fsi_master_read(p, MST_##r)
-#define fsi_core_read(p, r) _fsi_master_read(p, p->core->r)
-static u32 _fsi_master_read(struct fsi_master *master, u32 reg)
-{
- u32 ret;
- unsigned long flags;
-
- spin_lock_irqsave(&master->lock, flags);
- ret = __fsi_reg_read(master->base + reg);
- spin_unlock_irqrestore(&master->lock, flags);
-
- return ret;
-}
-
-#define fsi_master_mask_set(p, r, m, d) _fsi_master_mask_set(p, MST_##r, m, d)
-#define fsi_core_mask_set(p, r, m, d) _fsi_master_mask_set(p, p->core->r, m, d)
-static void _fsi_master_mask_set(struct fsi_master *master,
- u32 reg, u32 mask, u32 data)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&master->lock, flags);
- __fsi_reg_mask_set(master->base + reg, mask, data);
- spin_unlock_irqrestore(&master->lock, flags);
-}
-
-/*
- * basic function
- */
-
-static struct fsi_master *fsi_get_master(struct fsi_priv *fsi)
-{
- return fsi->master;
-}
-
-static int fsi_is_clk_master(struct fsi_priv *fsi)
-{
- return fsi->clk_master;
-}
-
-static int fsi_is_port_a(struct fsi_priv *fsi)
-{
- return fsi->master->base == fsi->base;
-}
-
-static int fsi_is_spdif(struct fsi_priv *fsi)
-{
- return fsi->spdif;
-}
-
-static int fsi_is_play(struct snd_pcm_substream *substream)
-{
- return substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
-}
-
-static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
-
- return rtd->cpu_dai;
-}
-
-static struct fsi_priv *fsi_get_priv_frm_dai(struct snd_soc_dai *dai)
-{
- struct fsi_master *master = snd_soc_dai_get_drvdata(dai);
-
- if (dai->id == 0)
- return &master->fsia;
- else
- return &master->fsib;
-}
-
-static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
-{
- return fsi_get_priv_frm_dai(fsi_get_dai(substream));
-}
-
-static set_rate_func fsi_get_info_set_rate(struct fsi_priv *fsi)
-{
- if (!fsi->info)
- return NULL;
-
- return fsi->info->set_rate;
-}
-
-static u32 fsi_get_info_flags(struct fsi_priv *fsi)
-{
- if (!fsi->info)
- return 0;
-
- return fsi->info->flags;
-}
-
-static u32 fsi_get_port_shift(struct fsi_priv *fsi, struct fsi_stream *io)
-{
- int is_play = fsi_stream_is_play(fsi, io);
- int is_porta = fsi_is_port_a(fsi);
- u32 shift;
-
- if (is_porta)
- shift = is_play ? AO_SHIFT : AI_SHIFT;
- else
- shift = is_play ? BO_SHIFT : BI_SHIFT;
-
- return shift;
-}
-
-static int fsi_frame2sample(struct fsi_priv *fsi, int frames)
-{
- return frames * fsi->chan_num;
-}
-
-static int fsi_sample2frame(struct fsi_priv *fsi, int samples)
-{
- return samples / fsi->chan_num;
-}
-
-static int fsi_get_current_fifo_samples(struct fsi_priv *fsi,
- struct fsi_stream *io)
-{
- int is_play = fsi_stream_is_play(fsi, io);
- u32 status;
- int frames;
-
- status = is_play ?
- fsi_reg_read(fsi, DOFF_ST) :
- fsi_reg_read(fsi, DIFF_ST);
-
- frames = 0x1ff & (status >> 8);
-
- return fsi_frame2sample(fsi, frames);
-}
-
-static void fsi_count_fifo_err(struct fsi_priv *fsi)
-{
- u32 ostatus = fsi_reg_read(fsi, DOFF_ST);
- u32 istatus = fsi_reg_read(fsi, DIFF_ST);
-
- if (ostatus & ERR_OVER)
- fsi->playback.oerr_num++;
-
- if (ostatus & ERR_UNDER)
- fsi->playback.uerr_num++;
-
- if (istatus & ERR_OVER)
- fsi->capture.oerr_num++;
-
- if (istatus & ERR_UNDER)
- fsi->capture.uerr_num++;
-
- fsi_reg_write(fsi, DOFF_ST, 0);
- fsi_reg_write(fsi, DIFF_ST, 0);
-}
-
-/*
- * fsi_stream_xx() function
- */
-static inline int fsi_stream_is_play(struct fsi_priv *fsi,
- struct fsi_stream *io)
-{
- return &fsi->playback == io;
-}
-
-static inline struct fsi_stream *fsi_stream_get(struct fsi_priv *fsi,
- struct snd_pcm_substream *substream)
-{
- return fsi_is_play(substream) ? &fsi->playback : &fsi->capture;
-}
-
-static int fsi_stream_is_working(struct fsi_priv *fsi,
- struct fsi_stream *io)
-{
- struct fsi_master *master = fsi_get_master(fsi);
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&master->lock, flags);
- ret = !!(io->substream && io->substream->runtime);
- spin_unlock_irqrestore(&master->lock, flags);
-
- return ret;
-}
-
-static struct fsi_priv *fsi_stream_to_priv(struct fsi_stream *io)
-{
- return io->priv;
-}
-
-static void fsi_stream_init(struct fsi_priv *fsi,
- struct fsi_stream *io,
- struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct fsi_master *master = fsi_get_master(fsi);
- unsigned long flags;
-
- spin_lock_irqsave(&master->lock, flags);
- io->substream = substream;
- io->buff_sample_capa = fsi_frame2sample(fsi, runtime->buffer_size);
- io->buff_sample_pos = 0;
- io->period_samples = fsi_frame2sample(fsi, runtime->period_size);
- io->period_pos = 0;
- io->sample_width = samples_to_bytes(runtime, 1);
- io->oerr_num = -1; /* ignore 1st err */
- io->uerr_num = -1; /* ignore 1st err */
- fsi_stream_handler_call(io, init, fsi, io);
- spin_unlock_irqrestore(&master->lock, flags);
-}
-
-static void fsi_stream_quit(struct fsi_priv *fsi, struct fsi_stream *io)
-{
- struct snd_soc_dai *dai = fsi_get_dai(io->substream);
- struct fsi_master *master = fsi_get_master(fsi);
- unsigned long flags;
-
- spin_lock_irqsave(&master->lock, flags);
-
- if (io->oerr_num > 0)
- dev_err(dai->dev, "over_run = %d\n", io->oerr_num);
-
- if (io->uerr_num > 0)
- dev_err(dai->dev, "under_run = %d\n", io->uerr_num);
-
- fsi_stream_handler_call(io, quit, fsi, io);
- io->substream = NULL;
- io->buff_sample_capa = 0;
- io->buff_sample_pos = 0;
- io->period_samples = 0;
- io->period_pos = 0;
- io->sample_width = 0;
- io->oerr_num = 0;
- io->uerr_num = 0;
- spin_unlock_irqrestore(&master->lock, flags);
-}
-
-static int fsi_stream_transfer(struct fsi_stream *io)
-{
- struct fsi_priv *fsi = fsi_stream_to_priv(io);
- if (!fsi)
- return -EIO;
-
- return fsi_stream_handler_call(io, transfer, fsi, io);
-}
-
-#define fsi_stream_start(fsi, io)\
- fsi_stream_handler_call(io, start_stop, fsi, io, 1)
-
-#define fsi_stream_stop(fsi, io)\
- fsi_stream_handler_call(io, start_stop, fsi, io, 0)
-
-static int fsi_stream_probe(struct fsi_priv *fsi)
-{
- struct fsi_stream *io;
- int ret1, ret2;
-
- io = &fsi->playback;
- ret1 = fsi_stream_handler_call(io, probe, fsi, io);
-
- io = &fsi->capture;
- ret2 = fsi_stream_handler_call(io, probe, fsi, io);
-
- if (ret1 < 0)
- return ret1;
- if (ret2 < 0)
- return ret2;
-
- return 0;
-}
-
-static int fsi_stream_remove(struct fsi_priv *fsi)
-{
- struct fsi_stream *io;
- int ret1, ret2;
-
- io = &fsi->playback;
- ret1 = fsi_stream_handler_call(io, remove, fsi, io);
-
- io = &fsi->capture;
- ret2 = fsi_stream_handler_call(io, remove, fsi, io);
-
- if (ret1 < 0)
- return ret1;
- if (ret2 < 0)
- return ret2;
-
- return 0;
-}
-
-/*
- * irq function
- */
-
-static void fsi_irq_enable(struct fsi_priv *fsi, struct fsi_stream *io)
-{
- u32 data = AB_IO(1, fsi_get_port_shift(fsi, io));
- struct fsi_master *master = fsi_get_master(fsi);
-
- fsi_core_mask_set(master, imsk, data, data);
- fsi_core_mask_set(master, iemsk, data, data);
-}
-
-static void fsi_irq_disable(struct fsi_priv *fsi, struct fsi_stream *io)
-{
- u32 data = AB_IO(1, fsi_get_port_shift(fsi, io));
- struct fsi_master *master = fsi_get_master(fsi);
-
- fsi_core_mask_set(master, imsk, data, 0);
- fsi_core_mask_set(master, iemsk, data, 0);
-}
-
-static u32 fsi_irq_get_status(struct fsi_master *master)
-{
- return fsi_core_read(master, int_st);
-}
-
-static void fsi_irq_clear_status(struct fsi_priv *fsi)
-{
- u32 data = 0;
- struct fsi_master *master = fsi_get_master(fsi);
-
- data |= AB_IO(1, fsi_get_port_shift(fsi, &fsi->playback));
- data |= AB_IO(1, fsi_get_port_shift(fsi, &fsi->capture));
-
- /* clear interrupt factor */
- fsi_core_mask_set(master, int_st, data, 0);
-}
-
-/*
- * SPDIF master clock function
- *
- * These functions are used later FSI2
- */
-static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable)
-{
- struct fsi_master *master = fsi_get_master(fsi);
- u32 mask, val;
-
- if (master->core->ver < 2) {
- pr_err("fsi: register access err (%s)\n", __func__);
- return;
- }
-
- mask = BP | SE;
- val = enable ? mask : 0;
-
- fsi_is_port_a(fsi) ?
- fsi_core_mask_set(master, a_mclk, mask, val) :
- fsi_core_mask_set(master, b_mclk, mask, val);
-}
-
-/*
- * clock function
- */
-static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
- long rate, int enable)
-{
- struct fsi_master *master = fsi_get_master(fsi);
- set_rate_func set_rate = fsi_get_info_set_rate(fsi);
- int fsi_ver = master->core->ver;
- int ret;
-
- if (!set_rate)
- return 0;
-
- ret = set_rate(dev, rate, enable);
- if (ret < 0) /* error */
- return ret;
-
- if (!enable)
- return 0;
-
- if (ret > 0) {
- u32 data = 0;
-
- switch (ret & SH_FSI_ACKMD_MASK) {
- default:
- /* FALL THROUGH */
- case SH_FSI_ACKMD_512:
- data |= (0x0 << 12);
- break;
- case SH_FSI_ACKMD_256:
- data |= (0x1 << 12);
- break;
- case SH_FSI_ACKMD_128:
- data |= (0x2 << 12);
- break;
- case SH_FSI_ACKMD_64:
- data |= (0x3 << 12);
- break;
- case SH_FSI_ACKMD_32:
- if (fsi_ver < 2)
- dev_err(dev, "unsupported ACKMD\n");
- else
- data |= (0x4 << 12);
- break;
- }
-
- switch (ret & SH_FSI_BPFMD_MASK) {
- default:
- /* FALL THROUGH */
- case SH_FSI_BPFMD_32:
- data |= (0x0 << 8);
- break;
- case SH_FSI_BPFMD_64:
- data |= (0x1 << 8);
- break;
- case SH_FSI_BPFMD_128:
- data |= (0x2 << 8);
- break;
- case SH_FSI_BPFMD_256:
- data |= (0x3 << 8);
- break;
- case SH_FSI_BPFMD_512:
- data |= (0x4 << 8);
- break;
- case SH_FSI_BPFMD_16:
- if (fsi_ver < 2)
- dev_err(dev, "unsupported ACKMD\n");
- else
- data |= (0x7 << 8);
- break;
- }
-
- fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data);
- udelay(10);
- ret = 0;
- }
-
- return ret;
-}
-
-/*
- * pio data transfer handler
- */
-static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples)
-{
- u16 *buf = (u16 *)_buf;
- int i;
-
- for (i = 0; i < samples; i++)
- fsi_reg_write(fsi, DODT, ((u32)*(buf + i) << 8));
-}
-
-static void fsi_pio_pop16(struct fsi_priv *fsi, u8 *_buf, int samples)
-{
- u16 *buf = (u16 *)_buf;
- int i;
-
- for (i = 0; i < samples; i++)
- *(buf + i) = (u16)(fsi_reg_read(fsi, DIDT) >> 8);
-}
-
-static void fsi_pio_push32(struct fsi_priv *fsi, u8 *_buf, int samples)
-{
- u32 *buf = (u32 *)_buf;
- int i;
-
- for (i = 0; i < samples; i++)
- fsi_reg_write(fsi, DODT, *(buf + i));
-}
-
-static void fsi_pio_pop32(struct fsi_priv *fsi, u8 *_buf, int samples)
-{
- u32 *buf = (u32 *)_buf;
- int i;
-
- for (i = 0; i < samples; i++)
- *(buf + i) = fsi_reg_read(fsi, DIDT);
-}
-
-static u8 *fsi_pio_get_area(struct fsi_priv *fsi, struct fsi_stream *io)
-{
- struct snd_pcm_runtime *runtime = io->substream->runtime;
-
- return runtime->dma_area +
- samples_to_bytes(runtime, io->buff_sample_pos);
-}
-
-static int fsi_pio_transfer(struct fsi_priv *fsi, struct fsi_stream *io,
- void (*run16)(struct fsi_priv *fsi, u8 *buf, int samples),
- void (*run32)(struct fsi_priv *fsi, u8 *buf, int samples),
- int samples)
-{
- struct snd_pcm_runtime *runtime;
- struct snd_pcm_substream *substream;
- u8 *buf;
- int over_period;
-
- if (!fsi_stream_is_working(fsi, io))
- return -EINVAL;
-
- over_period = 0;
- substream = io->substream;
- runtime = substream->runtime;
-
- /* FSI FIFO has limit.
- * So, this driver can not send periods data at a time
- */
- if (io->buff_sample_pos >=
- io->period_samples * (io->period_pos + 1)) {
-
- over_period = 1;
- io->period_pos = (io->period_pos + 1) % runtime->periods;
-
- if (0 == io->period_pos)
- io->buff_sample_pos = 0;
- }
-
- buf = fsi_pio_get_area(fsi, io);
-
- switch (io->sample_width) {
- case 2:
- run16(fsi, buf, samples);
- break;
- case 4:
- run32(fsi, buf, samples);
- break;
- default:
- return -EINVAL;
- }
-
- /* update buff_sample_pos */
- io->buff_sample_pos += samples;
-
- if (over_period)
- snd_pcm_period_elapsed(substream);
-
- return 0;
-}
-
-static int fsi_pio_pop(struct fsi_priv *fsi, struct fsi_stream *io)
-{
- int sample_residues; /* samples in FSI fifo */
- int sample_space; /* ALSA free samples space */
- int samples;
-
- sample_residues = fsi_get_current_fifo_samples(fsi, io);
- sample_space = io->buff_sample_capa - io->buff_sample_pos;
-
- samples = min(sample_residues, sample_space);
-
- return fsi_pio_transfer(fsi, io,
- fsi_pio_pop16,
- fsi_pio_pop32,
- samples);
-}
-
-static int fsi_pio_push(struct fsi_priv *fsi, struct fsi_stream *io)
-{
- int sample_residues; /* ALSA residue samples */
- int sample_space; /* FSI fifo free samples space */
- int samples;
-
- sample_residues = io->buff_sample_capa - io->buff_sample_pos;
- sample_space = io->fifo_sample_capa -
- fsi_get_current_fifo_samples(fsi, io);
-
- samples = min(sample_residues, sample_space);
-
- return fsi_pio_transfer(fsi, io,
- fsi_pio_push16,
- fsi_pio_push32,
- samples);
-}
-
-static void fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
- int enable)
-{
- struct fsi_master *master = fsi_get_master(fsi);
- u32 clk = fsi_is_port_a(fsi) ? CRA : CRB;
-
- if (enable)
- fsi_irq_enable(fsi, io);
- else
- fsi_irq_disable(fsi, io);
-
- if (fsi_is_clk_master(fsi))
- fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
-}
-
-static struct fsi_stream_handler fsi_pio_push_handler = {
- .transfer = fsi_pio_push,
- .start_stop = fsi_pio_start_stop,
-};
-
-static struct fsi_stream_handler fsi_pio_pop_handler = {
- .transfer = fsi_pio_pop,
- .start_stop = fsi_pio_start_stop,
-};
-
-static irqreturn_t fsi_interrupt(int irq, void *data)
-{
- struct fsi_master *master = data;
- u32 int_st = fsi_irq_get_status(master);
-
- /* clear irq status */
- fsi_master_mask_set(master, SOFT_RST, IR, 0);
- fsi_master_mask_set(master, SOFT_RST, IR, IR);
-
- if (int_st & AB_IO(1, AO_SHIFT))
- fsi_stream_transfer(&master->fsia.playback);
- if (int_st & AB_IO(1, BO_SHIFT))
- fsi_stream_transfer(&master->fsib.playback);
- if (int_st & AB_IO(1, AI_SHIFT))
- fsi_stream_transfer(&master->fsia.capture);
- if (int_st & AB_IO(1, BI_SHIFT))
- fsi_stream_transfer(&master->fsib.capture);
-
- fsi_count_fifo_err(&master->fsia);
- fsi_count_fifo_err(&master->fsib);
-
- fsi_irq_clear_status(&master->fsia);
- fsi_irq_clear_status(&master->fsib);
-
- return IRQ_HANDLED;
-}
-
-/*
- * dma data transfer handler
- */
-static int fsi_dma_init(struct fsi_priv *fsi, struct fsi_stream *io)
-{
- struct snd_pcm_runtime *runtime = io->substream->runtime;
- struct snd_soc_dai *dai = fsi_get_dai(io->substream);
- enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
- DMA_TO_DEVICE : DMA_FROM_DEVICE;
-
- io->dma = dma_map_single(dai->dev, runtime->dma_area,
- snd_pcm_lib_buffer_bytes(io->substream), dir);
- return 0;
-}
-
-static int fsi_dma_quit(struct fsi_priv *fsi, struct fsi_stream *io)
-{
- struct snd_soc_dai *dai = fsi_get_dai(io->substream);
- enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
- DMA_TO_DEVICE : DMA_FROM_DEVICE;
-
- dma_unmap_single(dai->dev, io->dma,
- snd_pcm_lib_buffer_bytes(io->substream), dir);
- return 0;
-}
-
-static void fsi_dma_complete(void *data)
-{
- struct fsi_stream *io = (struct fsi_stream *)data;
- struct fsi_priv *fsi = fsi_stream_to_priv(io);
- struct snd_pcm_runtime *runtime = io->substream->runtime;
- struct snd_soc_dai *dai = fsi_get_dai(io->substream);
- enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
- DMA_TO_DEVICE : DMA_FROM_DEVICE;
-
- dma_sync_single_for_cpu(dai->dev, io->dma,
- samples_to_bytes(runtime, io->period_samples), dir);
-
- io->buff_sample_pos += io->period_samples;
- io->period_pos++;
-
- if (io->period_pos >= runtime->periods) {
- io->period_pos = 0;
- io->buff_sample_pos = 0;
- }
-
- fsi_count_fifo_err(fsi);
- fsi_stream_transfer(io);
-
- snd_pcm_period_elapsed(io->substream);
-}
-
-static dma_addr_t fsi_dma_get_area(struct fsi_stream *io)
-{
- struct snd_pcm_runtime *runtime = io->substream->runtime;
-
- return io->dma + samples_to_bytes(runtime, io->buff_sample_pos);
-}
-
-static void fsi_dma_do_tasklet(unsigned long data)
-{
- struct fsi_stream *io = (struct fsi_stream *)data;
- struct fsi_priv *fsi = fsi_stream_to_priv(io);
- struct dma_chan *chan;
- struct snd_soc_dai *dai;
- struct dma_async_tx_descriptor *desc;
- struct scatterlist sg;
- struct snd_pcm_runtime *runtime;
- enum dma_data_direction dir;
- dma_cookie_t cookie;
- int is_play = fsi_stream_is_play(fsi, io);
- int len;
- dma_addr_t buf;
-
- if (!fsi_stream_is_working(fsi, io))
- return;
-
- dai = fsi_get_dai(io->substream);
- chan = io->chan;
- runtime = io->substream->runtime;
- dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
- len = samples_to_bytes(runtime, io->period_samples);
- buf = fsi_dma_get_area(io);
-
- dma_sync_single_for_device(dai->dev, io->dma, len, dir);
-
- sg_init_table(&sg, 1);
- sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf)),
- len , offset_in_page(buf));
- sg_dma_address(&sg) = buf;
- sg_dma_len(&sg) = len;
-
- desc = dmaengine_prep_slave_sg(chan, &sg, 1, dir,
- DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
- if (!desc) {
- dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n");
- return;
- }
-
- desc->callback = fsi_dma_complete;
- desc->callback_param = io;
-
- cookie = desc->tx_submit(desc);
- if (cookie < 0) {
- dev_err(dai->dev, "tx_submit() fail\n");
- return;
- }
-
- dma_async_issue_pending(chan);
-
- /*
- * FIXME
- *
- * In DMAEngine case, codec and FSI cannot be started simultaneously
- * since FSI is using tasklet.
- * Therefore, in capture case, probably FSI FIFO will have got
- * overflow error in this point.
- * in that case, DMA cannot start transfer until error was cleared.
- */
- if (!is_play) {
- if (ERR_OVER & fsi_reg_read(fsi, DIFF_ST)) {
- fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR);
- fsi_reg_write(fsi, DIFF_ST, 0);
- }
- }
-}
-
-static bool fsi_dma_filter(struct dma_chan *chan, void *param)
-{
- struct sh_dmae_slave *slave = param;
-
- chan->private = slave;
-
- return true;
-}
-
-static int fsi_dma_transfer(struct fsi_priv *fsi, struct fsi_stream *io)
-{
- tasklet_schedule(&io->tasklet);
-
- return 0;
-}
-
-static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
- int start)
-{
- u32 bws;
- u32 dma;
-
- switch (io->sample_width * start) {
- case 2:
- bws = CR_BWS_16;
- dma = VDMD_STREAM | DMA_ON;
- break;
- case 4:
- bws = CR_BWS_24;
- dma = VDMD_BACK | DMA_ON;
- break;
- default:
- bws = 0;
- dma = 0;
- }
-
- fsi_reg_mask_set(fsi, DO_FMT, CR_BWS_MASK, bws);
- fsi_reg_write(fsi, OUT_DMAC, dma);
-}
-
-static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io)
-{
- dma_cap_mask_t mask;
-
- dma_cap_zero(mask);
- dma_cap_set(DMA_SLAVE, mask);
-
- io->chan = dma_request_channel(mask, fsi_dma_filter, &io->slave);
- if (!io->chan)
- return -EIO;
-
- tasklet_init(&io->tasklet, fsi_dma_do_tasklet, (unsigned long)io);
-
- return 0;
-}
-
-static int fsi_dma_remove(struct fsi_priv *fsi, struct fsi_stream *io)
-{
- tasklet_kill(&io->tasklet);
-
- fsi_stream_stop(fsi, io);
-
- if (io->chan)
- dma_release_channel(io->chan);
-
- io->chan = NULL;
- return 0;
-}
-
-static struct fsi_stream_handler fsi_dma_push_handler = {
- .init = fsi_dma_init,
- .quit = fsi_dma_quit,
- .probe = fsi_dma_probe,
- .transfer = fsi_dma_transfer,
- .remove = fsi_dma_remove,
- .start_stop = fsi_dma_push_start_stop,
-};
-
-/*
- * dai ops
- */
-static void fsi_fifo_init(struct fsi_priv *fsi,
- struct fsi_stream *io,
- struct device *dev)
-{
- struct fsi_master *master = fsi_get_master(fsi);
- int is_play = fsi_stream_is_play(fsi, io);
- u32 shift, i;
- int frame_capa;
-
- /* get on-chip RAM capacity */
- shift = fsi_master_read(master, FIFO_SZ);
- shift >>= fsi_get_port_shift(fsi, io);
- shift &= FIFO_SZ_MASK;
- frame_capa = 256 << shift;
- dev_dbg(dev, "fifo = %d words\n", frame_capa);
-
- /*
- * The maximum number of sample data varies depending
- * on the number of channels selected for the format.
- *
- * FIFOs are used in 4-channel units in 3-channel mode
- * and in 8-channel units in 5- to 7-channel mode
- * meaning that more FIFOs than the required size of DPRAM
- * are used.
- *
- * ex) if 256 words of DP-RAM is connected
- * 1 channel: 256 (256 x 1 = 256)
- * 2 channels: 128 (128 x 2 = 256)
- * 3 channels: 64 ( 64 x 3 = 192)
- * 4 channels: 64 ( 64 x 4 = 256)
- * 5 channels: 32 ( 32 x 5 = 160)
- * 6 channels: 32 ( 32 x 6 = 192)
- * 7 channels: 32 ( 32 x 7 = 224)
- * 8 channels: 32 ( 32 x 8 = 256)
- */
- for (i = 1; i < fsi->chan_num; i <<= 1)
- frame_capa >>= 1;
- dev_dbg(dev, "%d channel %d store\n",
- fsi->chan_num, frame_capa);
-
- io->fifo_sample_capa = fsi_frame2sample(fsi, frame_capa);
-
- /*
- * set interrupt generation factor
- * clear FIFO
- */
- if (is_play) {
- fsi_reg_write(fsi, DOFF_CTL, IRQ_HALF);
- fsi_reg_mask_set(fsi, DOFF_CTL, FIFO_CLR, FIFO_CLR);
- } else {
- fsi_reg_write(fsi, DIFF_CTL, IRQ_HALF);
- fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR);
- }
-}
-
-static int fsi_hw_startup(struct fsi_priv *fsi,
- struct fsi_stream *io,
- struct device *dev)
-{
- struct fsi_master *master = fsi_get_master(fsi);
- int fsi_ver = master->core->ver;
- u32 flags = fsi_get_info_flags(fsi);
- u32 data = 0;
-
- /* clock setting */
- if (fsi_is_clk_master(fsi))
- data = DIMD | DOMD;
-
- fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data);
-
- /* clock inversion (CKG2) */
- data = 0;
- if (SH_FSI_LRM_INV & flags)
- data |= 1 << 12;
- if (SH_FSI_BRM_INV & flags)
- data |= 1 << 8;
- if (SH_FSI_LRS_INV & flags)
- data |= 1 << 4;
- if (SH_FSI_BRS_INV & flags)
- data |= 1 << 0;
-
- fsi_reg_write(fsi, CKG2, data);
-
- /* set format */
- fsi_reg_write(fsi, DO_FMT, fsi->do_fmt);
- fsi_reg_write(fsi, DI_FMT, fsi->di_fmt);
-
- /* spdif ? */
- if (fsi_is_spdif(fsi)) {
- fsi_spdif_clk_ctrl(fsi, 1);
- fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
- }
-
- /*
- * FIXME
- *
- * FSI driver assumed that data package is in-back.
- * FSI2 chip can select it.
- */
- if (fsi_ver >= 2) {
- fsi_reg_write(fsi, OUT_DMAC, (1 << 4));
- fsi_reg_write(fsi, IN_DMAC, (1 << 4));
- }
-
- /* irq clear */
- fsi_irq_disable(fsi, io);
- fsi_irq_clear_status(fsi);
-
- /* fifo init */
- fsi_fifo_init(fsi, io, dev);
-
- return 0;
-}
-
-static void fsi_hw_shutdown(struct fsi_priv *fsi,
- struct device *dev)
-{
- if (fsi_is_clk_master(fsi))
- fsi_set_master_clk(dev, fsi, fsi->rate, 0);
-}
-
-static int fsi_dai_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct fsi_priv *fsi = fsi_get_priv(substream);
-
- return fsi_hw_startup(fsi, fsi_stream_get(fsi, substream), dai->dev);
-}
-
-static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct fsi_priv *fsi = fsi_get_priv(substream);
-
- fsi_hw_shutdown(fsi, dai->dev);
- fsi->rate = 0;
-}
-
-static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- struct fsi_priv *fsi = fsi_get_priv(substream);
- struct fsi_stream *io = fsi_stream_get(fsi, substream);
- int ret = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- fsi_stream_init(fsi, io, substream);
- ret = fsi_stream_transfer(io);
- if (0 == ret)
- fsi_stream_start(fsi, io);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- fsi_stream_stop(fsi, io);
- fsi_stream_quit(fsi, io);
- break;
- }
-
- return ret;
-}
-
-static int fsi_set_fmt_dai(struct fsi_priv *fsi, unsigned int fmt)
-{
- u32 data = 0;
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- data = CR_I2S;
- fsi->chan_num = 2;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- data = CR_PCM;
- fsi->chan_num = 2;
- break;
- default:
- return -EINVAL;
- }
-
- fsi->do_fmt = data;
- fsi->di_fmt = data;
-
- return 0;
-}
-
-static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
-{
- struct fsi_master *master = fsi_get_master(fsi);
- u32 data = 0;
-
- if (master->core->ver < 2)
- return -EINVAL;
-
- data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
- fsi->chan_num = 2;
- fsi->spdif = 1;
-
- fsi->do_fmt = data;
- fsi->di_fmt = data;
-
- return 0;
-}
-
-static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai);
- set_rate_func set_rate = fsi_get_info_set_rate(fsi);
- u32 flags = fsi_get_info_flags(fsi);
- int ret;
-
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- fsi->clk_master = 1;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- default:
- return -EINVAL;
- }
-
- if (fsi_is_clk_master(fsi) && !set_rate) {
- dev_err(dai->dev, "platform doesn't have set_rate\n");
- return -EINVAL;
- }
-
- /* set format */
- switch (flags & SH_FSI_FMT_MASK) {
- case SH_FSI_FMT_DAI:
- ret = fsi_set_fmt_dai(fsi, fmt & SND_SOC_DAIFMT_FORMAT_MASK);
- break;
- case SH_FSI_FMT_SPDIF:
- ret = fsi_set_fmt_spdif(fsi);
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct fsi_priv *fsi = fsi_get_priv(substream);
- long rate = params_rate(params);
- int ret;
-
- if (!fsi_is_clk_master(fsi))
- return 0;
-
- ret = fsi_set_master_clk(dai->dev, fsi, rate, 1);
- if (ret < 0)
- return ret;
-
- fsi->rate = rate;
-
- return ret;
-}
-
-static const struct snd_soc_dai_ops fsi_dai_ops = {
- .startup = fsi_dai_startup,
- .shutdown = fsi_dai_shutdown,
- .trigger = fsi_dai_trigger,
- .set_fmt = fsi_dai_set_fmt,
- .hw_params = fsi_dai_hw_params,
-};
-
-/*
- * pcm ops
- */
-
-static struct snd_pcm_hardware fsi_pcm_hardware = {
- .info = SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE,
- .formats = FSI_FMTS,
- .rates = FSI_RATES,
- .rate_min = 8000,
- .rate_max = 192000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 64 * 1024,
- .period_bytes_min = 32,
- .period_bytes_max = 8192,
- .periods_min = 1,
- .periods_max = 32,
- .fifo_size = 256,
-};
-
-static int fsi_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int ret = 0;
-
- snd_soc_set_runtime_hwparams(substream, &fsi_pcm_hardware);
-
- ret = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
-
- return ret;
-}
-
-static int fsi_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-}
-
-static int fsi_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
-{
- struct fsi_priv *fsi = fsi_get_priv(substream);
- struct fsi_stream *io = fsi_stream_get(fsi, substream);
-
- return fsi_sample2frame(fsi, io->buff_sample_pos);
-}
-
-static struct snd_pcm_ops fsi_pcm_ops = {
- .open = fsi_pcm_open,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = fsi_hw_params,
- .hw_free = fsi_hw_free,
- .pointer = fsi_pointer,
-};
-
-/*
- * snd_soc_platform
- */
-
-#define PREALLOC_BUFFER (32 * 1024)
-#define PREALLOC_BUFFER_MAX (32 * 1024)
-
-static void fsi_pcm_free(struct snd_pcm *pcm)
-{
- snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int fsi_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_pcm *pcm = rtd->pcm;
-
- /*
- * dont use SNDRV_DMA_TYPE_DEV, since it will oops the SH kernel
- * in MMAP mode (i.e. aplay -M)
- */
- return snd_pcm_lib_preallocate_pages_for_all(
- pcm,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- PREALLOC_BUFFER, PREALLOC_BUFFER_MAX);
-}
-
-/*
- * alsa struct
- */
-
-static struct snd_soc_dai_driver fsi_soc_dai[] = {
- {
- .name = "fsia-dai",
- .playback = {
- .rates = FSI_RATES,
- .formats = FSI_FMTS,
- .channels_min = 1,
- .channels_max = 8,
- },
- .capture = {
- .rates = FSI_RATES,
- .formats = FSI_FMTS,
- .channels_min = 1,
- .channels_max = 8,
- },
- .ops = &fsi_dai_ops,
- },
- {
- .name = "fsib-dai",
- .playback = {
- .rates = FSI_RATES,
- .formats = FSI_FMTS,
- .channels_min = 1,
- .channels_max = 8,
- },
- .capture = {
- .rates = FSI_RATES,
- .formats = FSI_FMTS,
- .channels_min = 1,
- .channels_max = 8,
- },
- .ops = &fsi_dai_ops,
- },
-};
-
-static struct snd_soc_platform_driver fsi_soc_platform = {
- .ops = &fsi_pcm_ops,
- .pcm_new = fsi_pcm_new,
- .pcm_free = fsi_pcm_free,
-};
-
-/*
- * platform function
- */
-static void fsi_handler_init(struct fsi_priv *fsi)
-{
- fsi->playback.handler = &fsi_pio_push_handler; /* default PIO */
- fsi->playback.priv = fsi;
- fsi->capture.handler = &fsi_pio_pop_handler; /* default PIO */
- fsi->capture.priv = fsi;
-
- if (fsi->info->tx_id) {
- fsi->playback.slave.slave_id = fsi->info->tx_id;
- fsi->playback.handler = &fsi_dma_push_handler;
- }
-}
-
-static int fsi_probe(struct platform_device *pdev)
-{
- struct fsi_master *master;
- const struct platform_device_id *id_entry;
- struct sh_fsi_platform_info *info = pdev->dev.platform_data;
- struct resource *res;
- unsigned int irq;
- int ret;
-
- id_entry = pdev->id_entry;
- if (!id_entry) {
- dev_err(&pdev->dev, "unknown fsi device\n");
- return -ENODEV;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- irq = platform_get_irq(pdev, 0);
- if (!res || (int)irq <= 0) {
- dev_err(&pdev->dev, "Not enough FSI platform resources.\n");
- ret = -ENODEV;
- goto exit;
- }
-
- master = kzalloc(sizeof(*master), GFP_KERNEL);
- if (!master) {
- dev_err(&pdev->dev, "Could not allocate master\n");
- ret = -ENOMEM;
- goto exit;
- }
-
- master->base = ioremap_nocache(res->start, resource_size(res));
- if (!master->base) {
- ret = -ENXIO;
- dev_err(&pdev->dev, "Unable to ioremap FSI registers.\n");
- goto exit_kfree;
- }
-
- /* master setting */
- master->irq = irq;
- master->core = (struct fsi_core *)id_entry->driver_data;
- spin_lock_init(&master->lock);
-
- /* FSI A setting */
- master->fsia.base = master->base;
- master->fsia.master = master;
- master->fsia.info = &info->port_a;
- fsi_handler_init(&master->fsia);
- ret = fsi_stream_probe(&master->fsia);
- if (ret < 0) {
- dev_err(&pdev->dev, "FSIA stream probe failed\n");
- goto exit_iounmap;
- }
-
- /* FSI B setting */
- master->fsib.base = master->base + 0x40;
- master->fsib.master = master;
- master->fsib.info = &info->port_b;
- fsi_handler_init(&master->fsib);
- ret = fsi_stream_probe(&master->fsib);
- if (ret < 0) {
- dev_err(&pdev->dev, "FSIB stream probe failed\n");
- goto exit_fsia;
- }
-
- pm_runtime_enable(&pdev->dev);
- dev_set_drvdata(&pdev->dev, master);
-
- ret = request_irq(irq, &fsi_interrupt, 0,
- id_entry->name, master);
- if (ret) {
- dev_err(&pdev->dev, "irq request err\n");
- goto exit_fsib;
- }
-
- ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform);
- if (ret < 0) {
- dev_err(&pdev->dev, "cannot snd soc register\n");
- goto exit_free_irq;
- }
-
- ret = snd_soc_register_dais(&pdev->dev, fsi_soc_dai,
- ARRAY_SIZE(fsi_soc_dai));
- if (ret < 0) {
- dev_err(&pdev->dev, "cannot snd dai register\n");
- goto exit_snd_soc;
- }
-
- return ret;
-
-exit_snd_soc:
- snd_soc_unregister_platform(&pdev->dev);
-exit_free_irq:
- free_irq(irq, master);
-exit_fsib:
- fsi_stream_remove(&master->fsib);
-exit_fsia:
- fsi_stream_remove(&master->fsia);
-exit_iounmap:
- iounmap(master->base);
- pm_runtime_disable(&pdev->dev);
-exit_kfree:
- kfree(master);
- master = NULL;
-exit:
- return ret;
-}
-
-static int fsi_remove(struct platform_device *pdev)
-{
- struct fsi_master *master;
-
- master = dev_get_drvdata(&pdev->dev);
-
- free_irq(master->irq, master);
- pm_runtime_disable(&pdev->dev);
-
- snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai));
- snd_soc_unregister_platform(&pdev->dev);
-
- fsi_stream_remove(&master->fsia);
- fsi_stream_remove(&master->fsib);
-
- iounmap(master->base);
- kfree(master);
-
- return 0;
-}
-
-static void __fsi_suspend(struct fsi_priv *fsi,
- struct fsi_stream *io,
- struct device *dev)
-{
- if (!fsi_stream_is_working(fsi, io))
- return;
-
- fsi_stream_stop(fsi, io);
- fsi_hw_shutdown(fsi, dev);
-}
-
-static void __fsi_resume(struct fsi_priv *fsi,
- struct fsi_stream *io,
- struct device *dev)
-{
- if (!fsi_stream_is_working(fsi, io))
- return;
-
- fsi_hw_startup(fsi, io, dev);
-
- if (fsi_is_clk_master(fsi) && fsi->rate)
- fsi_set_master_clk(dev, fsi, fsi->rate, 1);
-
- fsi_stream_start(fsi, io);
-}
-
-static int fsi_suspend(struct device *dev)
-{
- struct fsi_master *master = dev_get_drvdata(dev);
- struct fsi_priv *fsia = &master->fsia;
- struct fsi_priv *fsib = &master->fsib;
-
- __fsi_suspend(fsia, &fsia->playback, dev);
- __fsi_suspend(fsia, &fsia->capture, dev);
-
- __fsi_suspend(fsib, &fsib->playback, dev);
- __fsi_suspend(fsib, &fsib->capture, dev);
-
- return 0;
-}
-
-static int fsi_resume(struct device *dev)
-{
- struct fsi_master *master = dev_get_drvdata(dev);
- struct fsi_priv *fsia = &master->fsia;
- struct fsi_priv *fsib = &master->fsib;
-
- __fsi_resume(fsia, &fsia->playback, dev);
- __fsi_resume(fsia, &fsia->capture, dev);
-
- __fsi_resume(fsib, &fsib->playback, dev);
- __fsi_resume(fsib, &fsib->capture, dev);
-
- return 0;
-}
-
-static struct dev_pm_ops fsi_pm_ops = {
- .suspend = fsi_suspend,
- .resume = fsi_resume,
-};
-
-static struct fsi_core fsi1_core = {
- .ver = 1,
-
- /* Interrupt */
- .int_st = INT_ST,
- .iemsk = IEMSK,
- .imsk = IMSK,
-};
-
-static struct fsi_core fsi2_core = {
- .ver = 2,
-
- /* Interrupt */
- .int_st = CPU_INT_ST,
- .iemsk = CPU_IEMSK,
- .imsk = CPU_IMSK,
- .a_mclk = A_MST_CTLR,
- .b_mclk = B_MST_CTLR,
-};
-
-static struct platform_device_id fsi_id_table[] = {
- { "sh_fsi", (kernel_ulong_t)&fsi1_core },
- { "sh_fsi2", (kernel_ulong_t)&fsi2_core },
- {},
-};
-MODULE_DEVICE_TABLE(platform, fsi_id_table);
-
-static struct platform_driver fsi_driver = {
- .driver = {
- .name = "fsi-pcm-audio",
- .pm = &fsi_pm_ops,
- },
- .probe = fsi_probe,
- .remove = fsi_remove,
- .id_table = fsi_id_table,
-};
-
-module_platform_driver(fsi_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("SuperH onchip FSI audio driver");
-MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
-MODULE_ALIAS("platform:fsi-pcm-audio");
diff --git a/ANDROID_3.4.5/sound/soc/sh/hac.c b/ANDROID_3.4.5/sound/soc/sh/hac.c
deleted file mode 100644
index 3474d7be..00000000
--- a/ANDROID_3.4.5/sound/soc/sh/hac.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Hitachi Audio Controller (AC97) support for SH7760/SH7780
- *
- * Copyright (c) 2007 Manuel Lauss <mano@roarinelk.homelinux.net>
- * licensed under the terms outlined in the file COPYING at the root
- * of the linux kernel sources.
- *
- * dont forget to set IPSEL/OMSEL register bits (in your board code) to
- * enable HAC output pins!
- */
-
-/* BIG FAT FIXME: although the SH7760 has 2 independent AC97 units, only
- * the FIRST can be used since ASoC does not pass any information to the
- * ac97_read/write() functions regarding WHICH unit to use. You'll have
- * to edit the code a bit to use the other AC97 unit. --mlau
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-/* regs and bits */
-#define HACCR 0x08
-#define HACCSAR 0x20
-#define HACCSDR 0x24
-#define HACPCML 0x28
-#define HACPCMR 0x2C
-#define HACTIER 0x50
-#define HACTSR 0x54
-#define HACRIER 0x58
-#define HACRSR 0x5C
-#define HACACR 0x60
-
-#define CR_CR (1 << 15) /* "codec-ready" indicator */
-#define CR_CDRT (1 << 11) /* cold reset */
-#define CR_WMRT (1 << 10) /* warm reset */
-#define CR_B9 (1 << 9) /* the mysterious "bit 9" */
-#define CR_ST (1 << 5) /* AC97 link start bit */
-
-#define CSAR_RD (1 << 19) /* AC97 data read bit */
-#define CSAR_WR (0)
-
-#define TSR_CMDAMT (1 << 31)
-#define TSR_CMDDMT (1 << 30)
-
-#define RSR_STARY (1 << 22)
-#define RSR_STDRY (1 << 21)
-
-#define ACR_DMARX16 (1 << 30)
-#define ACR_DMATX16 (1 << 29)
-#define ACR_TX12ATOM (1 << 26)
-#define ACR_DMARX20 ((1 << 24) | (1 << 22))
-#define ACR_DMATX20 ((1 << 23) | (1 << 21))
-
-#define CSDR_SHIFT 4
-#define CSDR_MASK (0xffff << CSDR_SHIFT)
-#define CSAR_SHIFT 12
-#define CSAR_MASK (0x7f << CSAR_SHIFT)
-
-#define AC97_WRITE_RETRY 1
-#define AC97_READ_RETRY 5
-
-/* manual-suggested AC97 codec access timeouts (us) */
-#define TMO_E1 500 /* 21 < E1 < 1000 */
-#define TMO_E2 13 /* 13 < E2 */
-#define TMO_E3 21 /* 21 < E3 */
-#define TMO_E4 500 /* 21 < E4 < 1000 */
-
-struct hac_priv {
- unsigned long mmio; /* HAC base address */
-} hac_cpu_data[] = {
-#if defined(CONFIG_CPU_SUBTYPE_SH7760)
- {
- .mmio = 0xFE240000,
- },
- {
- .mmio = 0xFE250000,
- },
-#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
- {
- .mmio = 0xFFE40000,
- },
-#else
-#error "Unsupported SuperH SoC"
-#endif
-};
-
-#define HACREG(reg) (*(unsigned long *)(hac->mmio + (reg)))
-
-/*
- * AC97 read/write flow as outlined in the SH7760 manual (pages 903-906)
- */
-static int hac_get_codec_data(struct hac_priv *hac, unsigned short r,
- unsigned short *v)
-{
- unsigned int to1, to2, i;
- unsigned short adr;
-
- for (i = AC97_READ_RETRY; i; i--) {
- *v = 0;
- /* wait for HAC to receive something from the codec */
- for (to1 = TMO_E4;
- to1 && !(HACREG(HACRSR) & RSR_STARY);
- --to1)
- udelay(1);
- for (to2 = TMO_E4;
- to2 && !(HACREG(HACRSR) & RSR_STDRY);
- --to2)
- udelay(1);
-
- if (!to1 && !to2)
- return 0; /* codec comm is down */
-
- adr = ((HACREG(HACCSAR) & CSAR_MASK) >> CSAR_SHIFT);
- *v = ((HACREG(HACCSDR) & CSDR_MASK) >> CSDR_SHIFT);
-
- HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY);
-
- if (r == adr)
- break;
-
- /* manual says: wait at least 21 usec before retrying */
- udelay(21);
- }
- HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY);
- return i;
-}
-
-static unsigned short hac_read_codec_aux(struct hac_priv *hac,
- unsigned short reg)
-{
- unsigned short val;
- unsigned int i, to;
-
- for (i = AC97_READ_RETRY; i; i--) {
- /* send_read_request */
- local_irq_disable();
- HACREG(HACTSR) &= ~(TSR_CMDAMT);
- HACREG(HACCSAR) = (reg << CSAR_SHIFT) | CSAR_RD;
- local_irq_enable();
-
- for (to = TMO_E3;
- to && !(HACREG(HACTSR) & TSR_CMDAMT);
- --to)
- udelay(1);
-
- HACREG(HACTSR) &= ~TSR_CMDAMT;
- val = 0;
- if (hac_get_codec_data(hac, reg, &val) != 0)
- break;
- }
-
- return i ? val : ~0;
-}
-
-static void hac_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short val)
-{
- int unit_id = 0 /* ac97->private_data */;
- struct hac_priv *hac = &hac_cpu_data[unit_id];
- unsigned int i, to;
- /* write_codec_aux */
- for (i = AC97_WRITE_RETRY; i; i--) {
- /* send_write_request */
- local_irq_disable();
- HACREG(HACTSR) &= ~(TSR_CMDDMT | TSR_CMDAMT);
- HACREG(HACCSDR) = (val << CSDR_SHIFT);
- HACREG(HACCSAR) = (reg << CSAR_SHIFT) & (~CSAR_RD);
- local_irq_enable();
-
- /* poll-wait for CMDAMT and CMDDMT */
- for (to = TMO_E1;
- to && !(HACREG(HACTSR) & (TSR_CMDAMT|TSR_CMDDMT));
- --to)
- udelay(1);
-
- HACREG(HACTSR) &= ~(TSR_CMDAMT | TSR_CMDDMT);
- if (to)
- break;
- /* timeout, try again */
- }
-}
-
-static unsigned short hac_ac97_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- int unit_id = 0 /* ac97->private_data */;
- struct hac_priv *hac = &hac_cpu_data[unit_id];
- return hac_read_codec_aux(hac, reg);
-}
-
-static void hac_ac97_warmrst(struct snd_ac97 *ac97)
-{
- int unit_id = 0 /* ac97->private_data */;
- struct hac_priv *hac = &hac_cpu_data[unit_id];
- unsigned int tmo;
-
- HACREG(HACCR) = CR_WMRT | CR_ST | CR_B9;
- msleep(10);
- HACREG(HACCR) = CR_ST | CR_B9;
- for (tmo = 1000; (tmo > 0) && !(HACREG(HACCR) & CR_CR); tmo--)
- udelay(1);
-
- if (!tmo)
- printk(KERN_INFO "hac: reset: AC97 link down!\n");
- /* settings this bit lets us have a conversation with codec */
- HACREG(HACACR) |= ACR_TX12ATOM;
-}
-
-static void hac_ac97_coldrst(struct snd_ac97 *ac97)
-{
- int unit_id = 0 /* ac97->private_data */;
- struct hac_priv *hac;
- hac = &hac_cpu_data[unit_id];
-
- HACREG(HACCR) = 0;
- HACREG(HACCR) = CR_CDRT | CR_ST | CR_B9;
- msleep(10);
- hac_ac97_warmrst(ac97);
-}
-
-struct snd_ac97_bus_ops soc_ac97_ops = {
- .read = hac_ac97_read,
- .write = hac_ac97_write,
- .reset = hac_ac97_coldrst,
- .warm_reset = hac_ac97_warmrst,
-};
-EXPORT_SYMBOL_GPL(soc_ac97_ops);
-
-static int hac_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct hac_priv *hac = &hac_cpu_data[dai->id];
- int d = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
-
- switch (params->msbits) {
- case 16:
- HACREG(HACACR) |= d ? ACR_DMARX16 : ACR_DMATX16;
- HACREG(HACACR) &= d ? ~ACR_DMARX20 : ~ACR_DMATX20;
- break;
- case 20:
- HACREG(HACACR) &= d ? ~ACR_DMARX16 : ~ACR_DMATX16;
- HACREG(HACACR) |= d ? ACR_DMARX20 : ACR_DMATX20;
- break;
- default:
- pr_debug("hac: invalid depth %d bit\n", params->msbits);
- return -EINVAL;
- break;
- }
-
- return 0;
-}
-
-#define AC97_RATES \
- SNDRV_PCM_RATE_8000_192000
-
-#define AC97_FMTS \
- SNDRV_PCM_FMTBIT_S16_LE
-
-static const struct snd_soc_dai_ops hac_dai_ops = {
- .hw_params = hac_hw_params,
-};
-
-static struct snd_soc_dai_driver sh4_hac_dai[] = {
-{
- .name = "hac-dai.0",
- .ac97_control = 1,
- .playback = {
- .rates = AC97_RATES,
- .formats = AC97_FMTS,
- .channels_min = 2,
- .channels_max = 2,
- },
- .capture = {
- .rates = AC97_RATES,
- .formats = AC97_FMTS,
- .channels_min = 2,
- .channels_max = 2,
- },
- .ops = &hac_dai_ops,
-},
-#ifdef CONFIG_CPU_SUBTYPE_SH7760
-{
- .name = "hac-dai.1",
- .id = 1,
- .playback = {
- .rates = AC97_RATES,
- .formats = AC97_FMTS,
- .channels_min = 2,
- .channels_max = 2,
- },
- .capture = {
- .rates = AC97_RATES,
- .formats = AC97_FMTS,
- .channels_min = 2,
- .channels_max = 2,
- },
- .ops = &hac_dai_ops,
-
-},
-#endif
-};
-
-static int __devinit hac_soc_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_dais(&pdev->dev, sh4_hac_dai,
- ARRAY_SIZE(sh4_hac_dai));
-}
-
-static int __devexit hac_soc_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sh4_hac_dai));
- return 0;
-}
-
-static struct platform_driver hac_pcm_driver = {
- .driver = {
- .name = "hac-pcm-audio",
- .owner = THIS_MODULE,
- },
-
- .probe = hac_soc_platform_probe,
- .remove = __devexit_p(hac_soc_platform_remove),
-};
-
-module_platform_driver(hac_pcm_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver");
-MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/ANDROID_3.4.5/sound/soc/sh/migor.c b/ANDROID_3.4.5/sound/soc/sh/migor.c
deleted file mode 100644
index 8526e1ed..00000000
--- a/ANDROID_3.4.5/sound/soc/sh/migor.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * ALSA SoC driver for Migo-R
- *
- * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/clkdev.h>
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/module.h>
-
-#include <asm/clock.h>
-
-#include <cpu/sh7722.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include "../codecs/wm8978.h"
-#include "siu.h"
-
-/* Default 8000Hz sampling frequency */
-static unsigned long codec_freq = 8000 * 512;
-
-static unsigned int use_count;
-
-/* External clock, sourced from the codec at the SIUMCKB pin */
-static unsigned long siumckb_recalc(struct clk *clk)
-{
- return codec_freq;
-}
-
-static struct sh_clk_ops siumckb_clk_ops = {
- .recalc = siumckb_recalc,
-};
-
-static struct clk siumckb_clk = {
- .ops = &siumckb_clk_ops,
- .rate = 0, /* initialised at run-time */
-};
-
-static struct clk_lookup *siumckb_lookup;
-
-static int migor_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int ret;
- unsigned int rate = params_rate(params);
-
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8978_PLL, 13000000,
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_clkdiv(codec_dai, WM8978_OPCLKRATE, rate * 512);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_NB_IF |
- SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_dai_set_fmt(rtd->cpu_dai, SND_SOC_DAIFMT_NB_IF |
- SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
-
- codec_freq = rate * 512;
- /*
- * This propagates the parent frequency change to children and
- * recalculates the frequency table
- */
- clk_set_rate(&siumckb_clk, codec_freq);
- dev_dbg(codec_dai->dev, "%s: configure %luHz\n", __func__, codec_freq);
-
- ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, SIU_CLKB_EXT,
- codec_freq / 2, SND_SOC_CLOCK_IN);
-
- if (!ret)
- use_count++;
-
- return ret;
-}
-
-static int migor_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
-
- if (use_count) {
- use_count--;
-
- if (!use_count)
- snd_soc_dai_set_sysclk(codec_dai, WM8978_PLL, 0,
- SND_SOC_CLOCK_IN);
- } else {
- dev_dbg(codec_dai->dev, "Unbalanced hw_free!\n");
- }
-
- return 0;
-}
-
-static struct snd_soc_ops migor_dai_ops = {
- .hw_params = migor_hw_params,
- .hw_free = migor_hw_free,
-};
-
-static const struct snd_soc_dapm_widget migor_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone", NULL),
- SND_SOC_DAPM_MIC("Onboard Microphone", NULL),
- SND_SOC_DAPM_MIC("External Microphone", NULL),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- /* Headphone output connected to LHP/RHP, enable OUT4 for VMID */
- { "Headphone", NULL, "OUT4 VMID" },
- { "OUT4 VMID", NULL, "LHP" },
- { "OUT4 VMID", NULL, "RHP" },
-
- /* On-board microphone */
- { "RMICN", NULL, "Mic Bias" },
- { "RMICP", NULL, "Mic Bias" },
- { "Mic Bias", NULL, "Onboard Microphone" },
-
- /* External microphone */
- { "LMICN", NULL, "Mic Bias" },
- { "LMICP", NULL, "Mic Bias" },
- { "Mic Bias", NULL, "External Microphone" },
-};
-
-static int migor_dai_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_new_controls(dapm, migor_dapm_widgets,
- ARRAY_SIZE(migor_dapm_widgets));
-
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
- return 0;
-}
-
-/* migor digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link migor_dai = {
- .name = "wm8978",
- .stream_name = "WM8978",
- .cpu_dai_name = "siu-i2s-dai",
- .codec_dai_name = "wm8978-hifi",
- .platform_name = "siu-pcm-audio",
- .codec_name = "wm8978.0-001a",
- .ops = &migor_dai_ops,
- .init = migor_dai_init,
-};
-
-/* migor audio machine driver */
-static struct snd_soc_card snd_soc_migor = {
- .name = "Migo-R",
- .owner = THIS_MODULE,
- .dai_link = &migor_dai,
- .num_links = 1,
-};
-
-static struct platform_device *migor_snd_device;
-
-static int __init migor_init(void)
-{
- int ret;
-
- ret = clk_register(&siumckb_clk);
- if (ret < 0)
- return ret;
-
- siumckb_lookup = clkdev_alloc(&siumckb_clk, "siumckb_clk", NULL);
- if (!siumckb_lookup) {
- ret = -ENOMEM;
- goto eclkdevalloc;
- }
- clkdev_add(siumckb_lookup);
-
- /* Port number used on this machine: port B */
- migor_snd_device = platform_device_alloc("soc-audio", 1);
- if (!migor_snd_device) {
- ret = -ENOMEM;
- goto epdevalloc;
- }
-
- platform_set_drvdata(migor_snd_device, &snd_soc_migor);
-
- ret = platform_device_add(migor_snd_device);
- if (ret)
- goto epdevadd;
-
- return 0;
-
-epdevadd:
- platform_device_put(migor_snd_device);
-epdevalloc:
- clkdev_drop(siumckb_lookup);
-eclkdevalloc:
- clk_unregister(&siumckb_clk);
- return ret;
-}
-
-static void __exit migor_exit(void)
-{
- clkdev_drop(siumckb_lookup);
- clk_unregister(&siumckb_clk);
- platform_device_unregister(migor_snd_device);
-}
-
-module_init(migor_init);
-module_exit(migor_exit);
-
-MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
-MODULE_DESCRIPTION("ALSA SoC Migor");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/sound/soc/sh/sh7760-ac97.c b/ANDROID_3.4.5/sound/soc/sh/sh7760-ac97.c
deleted file mode 100644
index 4a3568a9..00000000
--- a/ANDROID_3.4.5/sound/soc/sh/sh7760-ac97.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Generic AC97 sound support for SH7760
- *
- * (c) 2007 Manuel Lauss
- *
- * Licensed under the GPLv2.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/platform_device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <asm/io.h>
-
-#define IPSEL 0xFE400034
-
-static struct snd_soc_dai_link sh7760_ac97_dai = {
- .name = "AC97",
- .stream_name = "AC97 HiFi",
- .cpu_dai_name = "hac-dai.0", /* HAC0 */
- .codec_dai_name = "ac97-hifi",
- .platform_name = "sh7760-pcm-audio",
- .codec_name = "ac97-codec",
- .ops = NULL,
-};
-
-static struct snd_soc_card sh7760_ac97_soc_machine = {
- .name = "SH7760 AC97",
- .owner = THIS_MODULE,
- .dai_link = &sh7760_ac97_dai,
- .num_links = 1,
-};
-
-static struct platform_device *sh7760_ac97_snd_device;
-
-static int __init sh7760_ac97_init(void)
-{
- int ret;
- unsigned short ipsel;
-
- /* enable both AC97 controllers in pinmux reg */
- ipsel = __raw_readw(IPSEL);
- __raw_writew(ipsel | (3 << 10), IPSEL);
-
- ret = -ENOMEM;
- sh7760_ac97_snd_device = platform_device_alloc("soc-audio", -1);
- if (!sh7760_ac97_snd_device)
- goto out;
-
- platform_set_drvdata(sh7760_ac97_snd_device,
- &sh7760_ac97_soc_machine);
- ret = platform_device_add(sh7760_ac97_snd_device);
-
- if (ret)
- platform_device_put(sh7760_ac97_snd_device);
-
-out:
- return ret;
-}
-
-static void __exit sh7760_ac97_exit(void)
-{
- platform_device_unregister(sh7760_ac97_snd_device);
-}
-
-module_init(sh7760_ac97_init);
-module_exit(sh7760_ac97_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Generic SH7760 AC97 sound machine");
-MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/ANDROID_3.4.5/sound/soc/sh/siu.h b/ANDROID_3.4.5/sound/soc/sh/siu.h
deleted file mode 100644
index 83c3430a..00000000
--- a/ANDROID_3.4.5/sound/soc/sh/siu.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * siu.h - ALSA SoC driver for Renesas SH7343, SH7722 SIU peripheral.
- *
- * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- * Copyright (C) 2006 Carlos Munoz <carlos@kenati.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef SIU_H
-#define SIU_H
-
-/* Common kernel and user-space firmware-building defines and types */
-
-#define YRAM0_SIZE (0x0040 / 4) /* 16 */
-#define YRAM1_SIZE (0x0080 / 4) /* 32 */
-#define YRAM2_SIZE (0x0040 / 4) /* 16 */
-#define YRAM3_SIZE (0x0080 / 4) /* 32 */
-#define YRAM4_SIZE (0x0080 / 4) /* 32 */
-#define YRAM_DEF_SIZE (YRAM0_SIZE + YRAM1_SIZE + YRAM2_SIZE + \
- YRAM3_SIZE + YRAM4_SIZE)
-#define YRAM_FIR_SIZE (0x0400 / 4) /* 256 */
-#define YRAM_IIR_SIZE (0x0200 / 4) /* 128 */
-
-#define XRAM0_SIZE (0x0400 / 4) /* 256 */
-#define XRAM1_SIZE (0x0200 / 4) /* 128 */
-#define XRAM2_SIZE (0x0200 / 4) /* 128 */
-
-/* PRAM program array size */
-#define PRAM0_SIZE (0x0100 / 4) /* 64 */
-#define PRAM1_SIZE ((0x2000 - 0x0100) / 4) /* 1984 */
-
-#include <linux/types.h>
-
-struct siu_spb_param {
- __u32 ab1a; /* input FIFO address */
- __u32 ab0a; /* output FIFO address */
- __u32 dir; /* 0=the ather except CPUOUTPUT, 1=CPUINPUT */
- __u32 event; /* SPB program starting conditions */
- __u32 stfifo; /* STFIFO register setting value */
- __u32 trdat; /* TRDAT register setting value */
-};
-
-struct siu_firmware {
- __u32 yram_fir_coeff[YRAM_FIR_SIZE];
- __u32 pram0[PRAM0_SIZE];
- __u32 pram1[PRAM1_SIZE];
- __u32 yram0[YRAM0_SIZE];
- __u32 yram1[YRAM1_SIZE];
- __u32 yram2[YRAM2_SIZE];
- __u32 yram3[YRAM3_SIZE];
- __u32 yram4[YRAM4_SIZE];
- __u32 spbpar_num;
- struct siu_spb_param spbpar[32];
-};
-
-#ifdef __KERNEL__
-
-#include <linux/dmaengine.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/sh_dma.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#define SIU_PERIOD_BYTES_MAX 8192 /* DMA transfer/period size */
-#define SIU_PERIOD_BYTES_MIN 256 /* DMA transfer/period size */
-#define SIU_PERIODS_MAX 64 /* Max periods in buffer */
-#define SIU_PERIODS_MIN 4 /* Min periods in buffer */
-#define SIU_BUFFER_BYTES_MAX (SIU_PERIOD_BYTES_MAX * SIU_PERIODS_MAX)
-
-/* SIU ports: only one can be used at a time */
-enum {
- SIU_PORT_A,
- SIU_PORT_B,
- SIU_PORT_NUM,
-};
-
-/* SIU clock configuration */
-enum {
- SIU_CLKA_PLL,
- SIU_CLKA_EXT,
- SIU_CLKB_PLL,
- SIU_CLKB_EXT
-};
-
-struct device;
-struct siu_info {
- struct device *dev;
- int port_id;
- u32 __iomem *pram;
- u32 __iomem *xram;
- u32 __iomem *yram;
- u32 __iomem *reg;
- struct siu_firmware fw;
-};
-
-struct siu_stream {
- struct tasklet_struct tasklet;
- struct snd_pcm_substream *substream;
- snd_pcm_format_t format;
- size_t buf_bytes;
- size_t period_bytes;
- int cur_period; /* Period currently in dma */
- u32 volume;
- snd_pcm_sframes_t xfer_cnt; /* Number of frames */
- u8 rw_flg; /* transfer status */
- /* DMA status */
- struct dma_chan *chan; /* DMA channel */
- struct dma_async_tx_descriptor *tx_desc;
- dma_cookie_t cookie;
- struct sh_dmae_slave param;
-};
-
-struct siu_port {
- unsigned long play_cap; /* Used to track full duplex */
- struct snd_pcm *pcm;
- struct siu_stream playback;
- struct siu_stream capture;
- u32 stfifo; /* STFIFO value from firmware */
- u32 trdat; /* TRDAT value from firmware */
-};
-
-extern struct siu_port *siu_ports[SIU_PORT_NUM];
-
-static inline struct siu_port *siu_port_info(struct snd_pcm_substream *substream)
-{
- struct platform_device *pdev =
- to_platform_device(substream->pcm->card->dev);
- return siu_ports[pdev->id];
-}
-
-/* Register access */
-static inline void siu_write32(u32 __iomem *addr, u32 val)
-{
- __raw_writel(val, addr);
-}
-
-static inline u32 siu_read32(u32 __iomem *addr)
-{
- return __raw_readl(addr);
-}
-
-/* SIU registers */
-#define SIU_IFCTL (0x000 / sizeof(u32))
-#define SIU_SRCTL (0x004 / sizeof(u32))
-#define SIU_SFORM (0x008 / sizeof(u32))
-#define SIU_CKCTL (0x00c / sizeof(u32))
-#define SIU_TRDAT (0x010 / sizeof(u32))
-#define SIU_STFIFO (0x014 / sizeof(u32))
-#define SIU_DPAK (0x01c / sizeof(u32))
-#define SIU_CKREV (0x020 / sizeof(u32))
-#define SIU_EVNTC (0x028 / sizeof(u32))
-#define SIU_SBCTL (0x040 / sizeof(u32))
-#define SIU_SBPSET (0x044 / sizeof(u32))
-#define SIU_SBFSTS (0x068 / sizeof(u32))
-#define SIU_SBDVCA (0x06c / sizeof(u32))
-#define SIU_SBDVCB (0x070 / sizeof(u32))
-#define SIU_SBACTIV (0x074 / sizeof(u32))
-#define SIU_DMAIA (0x090 / sizeof(u32))
-#define SIU_DMAIB (0x094 / sizeof(u32))
-#define SIU_DMAOA (0x098 / sizeof(u32))
-#define SIU_DMAOB (0x09c / sizeof(u32))
-#define SIU_DMAML (0x0a0 / sizeof(u32))
-#define SIU_SPSTS (0x0cc / sizeof(u32))
-#define SIU_SPCTL (0x0d0 / sizeof(u32))
-#define SIU_BRGASEL (0x100 / sizeof(u32))
-#define SIU_BRRA (0x104 / sizeof(u32))
-#define SIU_BRGBSEL (0x108 / sizeof(u32))
-#define SIU_BRRB (0x10c / sizeof(u32))
-
-extern struct snd_soc_platform_driver siu_platform;
-extern struct siu_info *siu_i2s_data;
-
-int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card);
-void siu_free_port(struct siu_port *port_info);
-
-#endif
-
-#endif /* SIU_H */
diff --git a/ANDROID_3.4.5/sound/soc/sh/siu_dai.c b/ANDROID_3.4.5/sound/soc/sh/siu_dai.c
deleted file mode 100644
index 52d4c17b..00000000
--- a/ANDROID_3.4.5/sound/soc/sh/siu_dai.c
+++ /dev/null
@@ -1,853 +0,0 @@
-/*
- * siu_dai.c - ALSA SoC driver for Renesas SH7343, SH7722 SIU peripheral.
- *
- * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- * Copyright (C) 2006 Carlos Munoz <carlos@kenati.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/delay.h>
-#include <linux/firmware.h>
-#include <linux/pm_runtime.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-#include <asm/clock.h>
-#include <asm/siu.h>
-
-#include <sound/control.h>
-#include <sound/soc.h>
-
-#include "siu.h"
-
-/* Board specifics */
-#if defined(CONFIG_CPU_SUBTYPE_SH7722)
-# define SIU_MAX_VOLUME 0x1000
-#else
-# define SIU_MAX_VOLUME 0x7fff
-#endif
-
-#define PRAM_SIZE 0x2000
-#define XRAM_SIZE 0x800
-#define YRAM_SIZE 0x800
-
-#define XRAM_OFFSET 0x4000
-#define YRAM_OFFSET 0x6000
-#define REG_OFFSET 0xc000
-
-#define PLAYBACK_ENABLED 1
-#define CAPTURE_ENABLED 2
-
-#define VOLUME_CAPTURE 0
-#define VOLUME_PLAYBACK 1
-#define DFLT_VOLUME_LEVEL 0x08000800
-
-/*
- * SPDIF is only available on port A and on some SIU implementations it is only
- * available for input. Due to the lack of hardware to test it, SPDIF is left
- * disabled in this driver version
- */
-struct format_flag {
- u32 i2s;
- u32 pcm;
- u32 spdif;
- u32 mask;
-};
-
-struct port_flag {
- struct format_flag playback;
- struct format_flag capture;
-};
-
-struct siu_info *siu_i2s_data;
-
-static struct port_flag siu_flags[SIU_PORT_NUM] = {
- [SIU_PORT_A] = {
- .playback = {
- .i2s = 0x50000000,
- .pcm = 0x40000000,
- .spdif = 0x80000000, /* not on all SIU versions */
- .mask = 0xd0000000,
- },
- .capture = {
- .i2s = 0x05000000,
- .pcm = 0x04000000,
- .spdif = 0x08000000,
- .mask = 0x0d000000,
- },
- },
- [SIU_PORT_B] = {
- .playback = {
- .i2s = 0x00500000,
- .pcm = 0x00400000,
- .spdif = 0, /* impossible - turn off */
- .mask = 0x00500000,
- },
- .capture = {
- .i2s = 0x00050000,
- .pcm = 0x00040000,
- .spdif = 0, /* impossible - turn off */
- .mask = 0x00050000,
- },
- },
-};
-
-static void siu_dai_start(struct siu_port *port_info)
-{
- struct siu_info *info = siu_i2s_data;
- u32 __iomem *base = info->reg;
-
- dev_dbg(port_info->pcm->card->dev, "%s\n", __func__);
-
- /* Issue software reset to siu */
- siu_write32(base + SIU_SRCTL, 0);
-
- /* Wait for the reset to take effect */
- udelay(1);
-
- port_info->stfifo = 0;
- port_info->trdat = 0;
-
- /* portA, portB, SIU operate */
- siu_write32(base + SIU_SRCTL, 0x301);
-
- /* portA=256fs, portB=256fs */
- siu_write32(base + SIU_CKCTL, 0x40400000);
-
- /* portA's BRG does not divide SIUCKA */
- siu_write32(base + SIU_BRGASEL, 0);
- siu_write32(base + SIU_BRRA, 0);
-
- /* portB's BRG divides SIUCKB by half */
- siu_write32(base + SIU_BRGBSEL, 1);
- siu_write32(base + SIU_BRRB, 0);
-
- siu_write32(base + SIU_IFCTL, 0x44440000);
-
- /* portA: 32 bit/fs, master; portB: 32 bit/fs, master */
- siu_write32(base + SIU_SFORM, 0x0c0c0000);
-
- /*
- * Volume levels: looks like the DSP firmware implements volume controls
- * differently from what's described in the datasheet
- */
- siu_write32(base + SIU_SBDVCA, port_info->playback.volume);
- siu_write32(base + SIU_SBDVCB, port_info->capture.volume);
-}
-
-static void siu_dai_stop(struct siu_port *port_info)
-{
- struct siu_info *info = siu_i2s_data;
- u32 __iomem *base = info->reg;
-
- /* SIU software reset */
- siu_write32(base + SIU_SRCTL, 0);
-}
-
-static void siu_dai_spbAselect(struct siu_port *port_info)
-{
- struct siu_info *info = siu_i2s_data;
- struct siu_firmware *fw = &info->fw;
- u32 *ydef = fw->yram0;
- u32 idx;
-
- /* path A use */
- if (!info->port_id)
- idx = 1; /* portA */
- else
- idx = 2; /* portB */
-
- ydef[0] = (fw->spbpar[idx].ab1a << 16) |
- (fw->spbpar[idx].ab0a << 8) |
- (fw->spbpar[idx].dir << 7) | 3;
- ydef[1] = fw->yram0[1]; /* 0x03000300 */
- ydef[2] = (16 / 2) << 24;
- ydef[3] = fw->yram0[3]; /* 0 */
- ydef[4] = fw->yram0[4]; /* 0 */
- ydef[7] = fw->spbpar[idx].event;
- port_info->stfifo |= fw->spbpar[idx].stfifo;
- port_info->trdat |= fw->spbpar[idx].trdat;
-}
-
-static void siu_dai_spbBselect(struct siu_port *port_info)
-{
- struct siu_info *info = siu_i2s_data;
- struct siu_firmware *fw = &info->fw;
- u32 *ydef = fw->yram0;
- u32 idx;
-
- /* path B use */
- if (!info->port_id)
- idx = 7; /* portA */
- else
- idx = 8; /* portB */
-
- ydef[5] = (fw->spbpar[idx].ab1a << 16) |
- (fw->spbpar[idx].ab0a << 8) | 1;
- ydef[6] = fw->spbpar[idx].event;
- port_info->stfifo |= fw->spbpar[idx].stfifo;
- port_info->trdat |= fw->spbpar[idx].trdat;
-}
-
-static void siu_dai_open(struct siu_stream *siu_stream)
-{
- struct siu_info *info = siu_i2s_data;
- u32 __iomem *base = info->reg;
- u32 srctl, ifctl;
-
- srctl = siu_read32(base + SIU_SRCTL);
- ifctl = siu_read32(base + SIU_IFCTL);
-
- switch (info->port_id) {
- case SIU_PORT_A:
- /* portA operates */
- srctl |= 0x200;
- ifctl &= ~0xc2;
- break;
- case SIU_PORT_B:
- /* portB operates */
- srctl |= 0x100;
- ifctl &= ~0x31;
- break;
- }
-
- siu_write32(base + SIU_SRCTL, srctl);
- /* Unmute and configure portA */
- siu_write32(base + SIU_IFCTL, ifctl);
-}
-
-/*
- * At the moment only fixed Left-upper, Left-lower, Right-upper, Right-lower
- * packing is supported
- */
-static void siu_dai_pcmdatapack(struct siu_stream *siu_stream)
-{
- struct siu_info *info = siu_i2s_data;
- u32 __iomem *base = info->reg;
- u32 dpak;
-
- dpak = siu_read32(base + SIU_DPAK);
-
- switch (info->port_id) {
- case SIU_PORT_A:
- dpak &= ~0xc0000000;
- break;
- case SIU_PORT_B:
- dpak &= ~0x00c00000;
- break;
- }
-
- siu_write32(base + SIU_DPAK, dpak);
-}
-
-static int siu_dai_spbstart(struct siu_port *port_info)
-{
- struct siu_info *info = siu_i2s_data;
- u32 __iomem *base = info->reg;
- struct siu_firmware *fw = &info->fw;
- u32 *ydef = fw->yram0;
- int cnt;
- u32 __iomem *add;
- u32 *ptr;
-
- /* Load SPB Program in PRAM */
- ptr = fw->pram0;
- add = info->pram;
- for (cnt = 0; cnt < PRAM0_SIZE; cnt++, add++, ptr++)
- siu_write32(add, *ptr);
-
- ptr = fw->pram1;
- add = info->pram + (0x0100 / sizeof(u32));
- for (cnt = 0; cnt < PRAM1_SIZE; cnt++, add++, ptr++)
- siu_write32(add, *ptr);
-
- /* XRAM initialization */
- add = info->xram;
- for (cnt = 0; cnt < XRAM0_SIZE + XRAM1_SIZE + XRAM2_SIZE; cnt++, add++)
- siu_write32(add, 0);
-
- /* YRAM variable area initialization */
- add = info->yram;
- for (cnt = 0; cnt < YRAM_DEF_SIZE; cnt++, add++)
- siu_write32(add, ydef[cnt]);
-
- /* YRAM FIR coefficient area initialization */
- add = info->yram + (0x0200 / sizeof(u32));
- for (cnt = 0; cnt < YRAM_FIR_SIZE; cnt++, add++)
- siu_write32(add, fw->yram_fir_coeff[cnt]);
-
- /* YRAM IIR coefficient area initialization */
- add = info->yram + (0x0600 / sizeof(u32));
- for (cnt = 0; cnt < YRAM_IIR_SIZE; cnt++, add++)
- siu_write32(add, 0);
-
- siu_write32(base + SIU_TRDAT, port_info->trdat);
- port_info->trdat = 0x0;
-
-
- /* SPB start condition: software */
- siu_write32(base + SIU_SBACTIV, 0);
- /* Start SPB */
- siu_write32(base + SIU_SBCTL, 0xc0000000);
- /* Wait for program to halt */
- cnt = 0x10000;
- while (--cnt && siu_read32(base + SIU_SBCTL) != 0x80000000)
- cpu_relax();
-
- if (!cnt)
- return -EBUSY;
-
- /* SPB program start address setting */
- siu_write32(base + SIU_SBPSET, 0x00400000);
- /* SPB hardware start(FIFOCTL source) */
- siu_write32(base + SIU_SBACTIV, 0xc0000000);
-
- return 0;
-}
-
-static void siu_dai_spbstop(struct siu_port *port_info)
-{
- struct siu_info *info = siu_i2s_data;
- u32 __iomem *base = info->reg;
-
- siu_write32(base + SIU_SBACTIV, 0);
- /* SPB stop */
- siu_write32(base + SIU_SBCTL, 0);
-
- port_info->stfifo = 0;
-}
-
-/* API functions */
-
-/* Playback and capture hardware properties are identical */
-static struct snd_pcm_hardware siu_dai_pcm_hw = {
- .info = SNDRV_PCM_INFO_INTERLEAVED,
- .formats = SNDRV_PCM_FMTBIT_S16,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = SIU_BUFFER_BYTES_MAX,
- .period_bytes_min = SIU_PERIOD_BYTES_MIN,
- .period_bytes_max = SIU_PERIOD_BYTES_MAX,
- .periods_min = SIU_PERIODS_MIN,
- .periods_max = SIU_PERIODS_MAX,
-};
-
-static int siu_dai_info_volume(struct snd_kcontrol *kctrl,
- struct snd_ctl_elem_info *uinfo)
-{
- struct siu_port *port_info = snd_kcontrol_chip(kctrl);
-
- dev_dbg(port_info->pcm->card->dev, "%s\n", __func__);
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = SIU_MAX_VOLUME;
-
- return 0;
-}
-
-static int siu_dai_get_volume(struct snd_kcontrol *kctrl,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct siu_port *port_info = snd_kcontrol_chip(kctrl);
- struct device *dev = port_info->pcm->card->dev;
- u32 vol;
-
- dev_dbg(dev, "%s\n", __func__);
-
- switch (kctrl->private_value) {
- case VOLUME_PLAYBACK:
- /* Playback is always on port 0 */
- vol = port_info->playback.volume;
- ucontrol->value.integer.value[0] = vol & 0xffff;
- ucontrol->value.integer.value[1] = vol >> 16 & 0xffff;
- break;
- case VOLUME_CAPTURE:
- /* Capture is always on port 1 */
- vol = port_info->capture.volume;
- ucontrol->value.integer.value[0] = vol & 0xffff;
- ucontrol->value.integer.value[1] = vol >> 16 & 0xffff;
- break;
- default:
- dev_err(dev, "%s() invalid private_value=%ld\n",
- __func__, kctrl->private_value);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int siu_dai_put_volume(struct snd_kcontrol *kctrl,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct siu_port *port_info = snd_kcontrol_chip(kctrl);
- struct device *dev = port_info->pcm->card->dev;
- struct siu_info *info = siu_i2s_data;
- u32 __iomem *base = info->reg;
- u32 new_vol;
- u32 cur_vol;
-
- dev_dbg(dev, "%s\n", __func__);
-
- if (ucontrol->value.integer.value[0] < 0 ||
- ucontrol->value.integer.value[0] > SIU_MAX_VOLUME ||
- ucontrol->value.integer.value[1] < 0 ||
- ucontrol->value.integer.value[1] > SIU_MAX_VOLUME)
- return -EINVAL;
-
- new_vol = ucontrol->value.integer.value[0] |
- ucontrol->value.integer.value[1] << 16;
-
- /* See comment above - DSP firmware implementation */
- switch (kctrl->private_value) {
- case VOLUME_PLAYBACK:
- /* Playback is always on port 0 */
- cur_vol = port_info->playback.volume;
- siu_write32(base + SIU_SBDVCA, new_vol);
- port_info->playback.volume = new_vol;
- break;
- case VOLUME_CAPTURE:
- /* Capture is always on port 1 */
- cur_vol = port_info->capture.volume;
- siu_write32(base + SIU_SBDVCB, new_vol);
- port_info->capture.volume = new_vol;
- break;
- default:
- dev_err(dev, "%s() invalid private_value=%ld\n",
- __func__, kctrl->private_value);
- return -EINVAL;
- }
-
- if (cur_vol != new_vol)
- return 1;
-
- return 0;
-}
-
-static struct snd_kcontrol_new playback_controls = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Playback Volume",
- .index = 0,
- .info = siu_dai_info_volume,
- .get = siu_dai_get_volume,
- .put = siu_dai_put_volume,
- .private_value = VOLUME_PLAYBACK,
-};
-
-static struct snd_kcontrol_new capture_controls = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Capture Volume",
- .index = 0,
- .info = siu_dai_info_volume,
- .get = siu_dai_get_volume,
- .put = siu_dai_put_volume,
- .private_value = VOLUME_CAPTURE,
-};
-
-int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card)
-{
- struct device *dev = card->dev;
- struct snd_kcontrol *kctrl;
- int ret;
-
- *port_info = kzalloc(sizeof(**port_info), GFP_KERNEL);
- if (!*port_info)
- return -ENOMEM;
-
- dev_dbg(dev, "%s: port #%d@%p\n", __func__, port, *port_info);
-
- (*port_info)->playback.volume = DFLT_VOLUME_LEVEL;
- (*port_info)->capture.volume = DFLT_VOLUME_LEVEL;
-
- /*
- * Add mixer support. The SPB is used to change the volume. Both
- * ports use the same SPB. Therefore, we only register one
- * control instance since it will be used by both channels.
- * In error case we continue without controls.
- */
- kctrl = snd_ctl_new1(&playback_controls, *port_info);
- ret = snd_ctl_add(card, kctrl);
- if (ret < 0)
- dev_err(dev,
- "failed to add playback controls %p port=%d err=%d\n",
- kctrl, port, ret);
-
- kctrl = snd_ctl_new1(&capture_controls, *port_info);
- ret = snd_ctl_add(card, kctrl);
- if (ret < 0)
- dev_err(dev,
- "failed to add capture controls %p port=%d err=%d\n",
- kctrl, port, ret);
-
- return 0;
-}
-
-void siu_free_port(struct siu_port *port_info)
-{
- kfree(port_info);
-}
-
-static int siu_dai_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct siu_info *info = snd_soc_dai_get_drvdata(dai);
- struct snd_pcm_runtime *rt = substream->runtime;
- struct siu_port *port_info = siu_port_info(substream);
- int ret;
-
- dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__,
- info->port_id, port_info);
-
- snd_soc_set_runtime_hwparams(substream, &siu_dai_pcm_hw);
-
- ret = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
- if (unlikely(ret < 0))
- return ret;
-
- siu_dai_start(port_info);
-
- return 0;
-}
-
-static void siu_dai_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct siu_info *info = snd_soc_dai_get_drvdata(dai);
- struct siu_port *port_info = siu_port_info(substream);
-
- dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__,
- info->port_id, port_info);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- port_info->play_cap &= ~PLAYBACK_ENABLED;
- else
- port_info->play_cap &= ~CAPTURE_ENABLED;
-
- /* Stop the siu if the other stream is not using it */
- if (!port_info->play_cap) {
- /* during stmread or stmwrite ? */
- BUG_ON(port_info->playback.rw_flg || port_info->capture.rw_flg);
- siu_dai_spbstop(port_info);
- siu_dai_stop(port_info);
- }
-}
-
-/* PCM part of siu_dai_playback_prepare() / siu_dai_capture_prepare() */
-static int siu_dai_prepare(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct siu_info *info = snd_soc_dai_get_drvdata(dai);
- struct snd_pcm_runtime *rt = substream->runtime;
- struct siu_port *port_info = siu_port_info(substream);
- struct siu_stream *siu_stream;
- int self, ret;
-
- dev_dbg(substream->pcm->card->dev,
- "%s: port %d, active streams %lx, %d channels\n",
- __func__, info->port_id, port_info->play_cap, rt->channels);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- self = PLAYBACK_ENABLED;
- siu_stream = &port_info->playback;
- } else {
- self = CAPTURE_ENABLED;
- siu_stream = &port_info->capture;
- }
-
- /* Set up the siu if not already done */
- if (!port_info->play_cap) {
- siu_stream->rw_flg = 0; /* stream-data transfer flag */
-
- siu_dai_spbAselect(port_info);
- siu_dai_spbBselect(port_info);
-
- siu_dai_open(siu_stream);
-
- siu_dai_pcmdatapack(siu_stream);
-
- ret = siu_dai_spbstart(port_info);
- if (ret < 0)
- goto fail;
- } else {
- ret = 0;
- }
-
- port_info->play_cap |= self;
-
-fail:
- return ret;
-}
-
-/*
- * SIU can set bus format to I2S / PCM / SPDIF independently for playback and
- * capture, however, the current API sets the bus format globally for a DAI.
- */
-static int siu_dai_set_fmt(struct snd_soc_dai *dai,
- unsigned int fmt)
-{
- struct siu_info *info = snd_soc_dai_get_drvdata(dai);
- u32 __iomem *base = info->reg;
- u32 ifctl;
-
- dev_dbg(dai->dev, "%s: fmt 0x%x on port %d\n",
- __func__, fmt, info->port_id);
-
- if (info->port_id < 0)
- return -ENODEV;
-
- /* Here select between I2S / PCM / SPDIF */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- ifctl = siu_flags[info->port_id].playback.i2s |
- siu_flags[info->port_id].capture.i2s;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- ifctl = siu_flags[info->port_id].playback.pcm |
- siu_flags[info->port_id].capture.pcm;
- break;
- /* SPDIF disabled - see comment at the top */
- default:
- return -EINVAL;
- }
-
- ifctl |= ~(siu_flags[info->port_id].playback.mask |
- siu_flags[info->port_id].capture.mask) &
- siu_read32(base + SIU_IFCTL);
- siu_write32(base + SIU_IFCTL, ifctl);
-
- return 0;
-}
-
-static int siu_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
- unsigned int freq, int dir)
-{
- struct clk *siu_clk, *parent_clk;
- char *siu_name, *parent_name;
- int ret;
-
- if (dir != SND_SOC_CLOCK_IN)
- return -EINVAL;
-
- dev_dbg(dai->dev, "%s: using clock %d\n", __func__, clk_id);
-
- switch (clk_id) {
- case SIU_CLKA_PLL:
- siu_name = "siua_clk";
- parent_name = "pll_clk";
- break;
- case SIU_CLKA_EXT:
- siu_name = "siua_clk";
- parent_name = "siumcka_clk";
- break;
- case SIU_CLKB_PLL:
- siu_name = "siub_clk";
- parent_name = "pll_clk";
- break;
- case SIU_CLKB_EXT:
- siu_name = "siub_clk";
- parent_name = "siumckb_clk";
- break;
- default:
- return -EINVAL;
- }
-
- siu_clk = clk_get(dai->dev, siu_name);
- if (IS_ERR(siu_clk)) {
- dev_err(dai->dev, "%s: cannot get a SIU clock: %ld\n", __func__,
- PTR_ERR(siu_clk));
- return PTR_ERR(siu_clk);
- }
-
- parent_clk = clk_get(dai->dev, parent_name);
- if (IS_ERR(parent_clk)) {
- ret = PTR_ERR(parent_clk);
- dev_err(dai->dev, "cannot get a SIU clock parent: %d\n", ret);
- goto epclkget;
- }
-
- ret = clk_set_parent(siu_clk, parent_clk);
- if (ret < 0) {
- dev_err(dai->dev, "cannot reparent the SIU clock: %d\n", ret);
- goto eclksetp;
- }
-
- ret = clk_set_rate(siu_clk, freq);
- if (ret < 0)
- dev_err(dai->dev, "cannot set SIU clock rate: %d\n", ret);
-
- /* TODO: when clkdev gets reference counting we'll move these to siu_dai_shutdown() */
-eclksetp:
- clk_put(parent_clk);
-epclkget:
- clk_put(siu_clk);
-
- return ret;
-}
-
-static const struct snd_soc_dai_ops siu_dai_ops = {
- .startup = siu_dai_startup,
- .shutdown = siu_dai_shutdown,
- .prepare = siu_dai_prepare,
- .set_sysclk = siu_dai_set_sysclk,
- .set_fmt = siu_dai_set_fmt,
-};
-
-static struct snd_soc_dai_driver siu_i2s_dai = {
- .name = "siu-i2s-dai",
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .formats = SNDRV_PCM_FMTBIT_S16,
- .rates = SNDRV_PCM_RATE_8000_48000,
- },
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .formats = SNDRV_PCM_FMTBIT_S16,
- .rates = SNDRV_PCM_RATE_8000_48000,
- },
- .ops = &siu_dai_ops,
-};
-
-static int __devinit siu_probe(struct platform_device *pdev)
-{
- const struct firmware *fw_entry;
- struct resource *res, *region;
- struct siu_info *info;
- int ret;
-
- info = kmalloc(sizeof(*info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
- siu_i2s_data = info;
- info->dev = &pdev->dev;
-
- ret = request_firmware(&fw_entry, "siu_spb.bin", &pdev->dev);
- if (ret)
- goto ereqfw;
-
- /*
- * Loaded firmware is "const" - read only, but we have to modify it in
- * snd_siu_sh7343_spbAselect() and snd_siu_sh7343_spbBselect()
- */
- memcpy(&info->fw, fw_entry->data, fw_entry->size);
-
- release_firmware(fw_entry);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- ret = -ENODEV;
- goto egetres;
- }
-
- region = request_mem_region(res->start, resource_size(res),
- pdev->name);
- if (!region) {
- dev_err(&pdev->dev, "SIU region already claimed\n");
- ret = -EBUSY;
- goto ereqmemreg;
- }
-
- ret = -ENOMEM;
- info->pram = ioremap(res->start, PRAM_SIZE);
- if (!info->pram)
- goto emappram;
- info->xram = ioremap(res->start + XRAM_OFFSET, XRAM_SIZE);
- if (!info->xram)
- goto emapxram;
- info->yram = ioremap(res->start + YRAM_OFFSET, YRAM_SIZE);
- if (!info->yram)
- goto emapyram;
- info->reg = ioremap(res->start + REG_OFFSET, resource_size(res) -
- REG_OFFSET);
- if (!info->reg)
- goto emapreg;
-
- dev_set_drvdata(&pdev->dev, info);
-
- /* register using ARRAY version so we can keep dai name */
- ret = snd_soc_register_dais(&pdev->dev, &siu_i2s_dai, 1);
- if (ret < 0)
- goto edaiinit;
-
- ret = snd_soc_register_platform(&pdev->dev, &siu_platform);
- if (ret < 0)
- goto esocregp;
-
- pm_runtime_enable(&pdev->dev);
-
- return ret;
-
-esocregp:
- snd_soc_unregister_dai(&pdev->dev);
-edaiinit:
- iounmap(info->reg);
-emapreg:
- iounmap(info->yram);
-emapyram:
- iounmap(info->xram);
-emapxram:
- iounmap(info->pram);
-emappram:
- release_mem_region(res->start, resource_size(res));
-ereqmemreg:
-egetres:
-ereqfw:
- kfree(info);
-
- return ret;
-}
-
-static int __devexit siu_remove(struct platform_device *pdev)
-{
- struct siu_info *info = dev_get_drvdata(&pdev->dev);
- struct resource *res;
-
- pm_runtime_disable(&pdev->dev);
-
- snd_soc_unregister_platform(&pdev->dev);
- snd_soc_unregister_dai(&pdev->dev);
-
- iounmap(info->reg);
- iounmap(info->yram);
- iounmap(info->xram);
- iounmap(info->pram);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res)
- release_mem_region(res->start, resource_size(res));
- kfree(info);
-
- return 0;
-}
-
-static struct platform_driver siu_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "siu-pcm-audio",
- },
- .probe = siu_probe,
- .remove = __devexit_p(siu_remove),
-};
-
-module_platform_driver(siu_driver);
-
-MODULE_AUTHOR("Carlos Munoz <carlos@kenati.com>");
-MODULE_DESCRIPTION("ALSA SoC SH7722 SIU driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/sh/siu_pcm.c b/ANDROID_3.4.5/sound/soc/sh/siu_pcm.c
deleted file mode 100644
index 5cfcc655..00000000
--- a/ANDROID_3.4.5/sound/soc/sh/siu_pcm.c
+++ /dev/null
@@ -1,617 +0,0 @@
-/*
- * siu_pcm.c - ALSA driver for Renesas SH7343, SH7722 SIU peripheral.
- *
- * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- * Copyright (C) 2006 Carlos Munoz <carlos@kenati.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <linux/dmaengine.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/siu.h>
-
-#include "siu.h"
-
-#define GET_MAX_PERIODS(buf_bytes, period_bytes) \
- ((buf_bytes) / (period_bytes))
-#define PERIOD_OFFSET(buf_addr, period_num, period_bytes) \
- ((buf_addr) + ((period_num) * (period_bytes)))
-
-#define RWF_STM_RD 0x01 /* Read in progress */
-#define RWF_STM_WT 0x02 /* Write in progress */
-
-struct siu_port *siu_ports[SIU_PORT_NUM];
-
-/* transfersize is number of u32 dma transfers per period */
-static int siu_pcm_stmwrite_stop(struct siu_port *port_info)
-{
- struct siu_info *info = siu_i2s_data;
- u32 __iomem *base = info->reg;
- struct siu_stream *siu_stream = &port_info->playback;
- u32 stfifo;
-
- if (!siu_stream->rw_flg)
- return -EPERM;
-
- /* output FIFO disable */
- stfifo = siu_read32(base + SIU_STFIFO);
- siu_write32(base + SIU_STFIFO, stfifo & ~0x0c180c18);
- pr_debug("%s: STFIFO %x -> %x\n", __func__,
- stfifo, stfifo & ~0x0c180c18);
-
- /* during stmwrite clear */
- siu_stream->rw_flg = 0;
-
- return 0;
-}
-
-static int siu_pcm_stmwrite_start(struct siu_port *port_info)
-{
- struct siu_stream *siu_stream = &port_info->playback;
-
- if (siu_stream->rw_flg)
- return -EPERM;
-
- /* Current period in buffer */
- port_info->playback.cur_period = 0;
-
- /* during stmwrite flag set */
- siu_stream->rw_flg = RWF_STM_WT;
-
- /* DMA transfer start */
- tasklet_schedule(&siu_stream->tasklet);
-
- return 0;
-}
-
-static void siu_dma_tx_complete(void *arg)
-{
- struct siu_stream *siu_stream = arg;
-
- if (!siu_stream->rw_flg)
- return;
-
- /* Update completed period count */
- if (++siu_stream->cur_period >=
- GET_MAX_PERIODS(siu_stream->buf_bytes,
- siu_stream->period_bytes))
- siu_stream->cur_period = 0;
-
- pr_debug("%s: done period #%d (%u/%u bytes), cookie %d\n",
- __func__, siu_stream->cur_period,
- siu_stream->cur_period * siu_stream->period_bytes,
- siu_stream->buf_bytes, siu_stream->cookie);
-
- tasklet_schedule(&siu_stream->tasklet);
-
- /* Notify alsa: a period is done */
- snd_pcm_period_elapsed(siu_stream->substream);
-}
-
-static int siu_pcm_wr_set(struct siu_port *port_info,
- dma_addr_t buff, u32 size)
-{
- struct siu_info *info = siu_i2s_data;
- u32 __iomem *base = info->reg;
- struct siu_stream *siu_stream = &port_info->playback;
- struct snd_pcm_substream *substream = siu_stream->substream;
- struct device *dev = substream->pcm->card->dev;
- struct dma_async_tx_descriptor *desc;
- dma_cookie_t cookie;
- struct scatterlist sg;
- u32 stfifo;
-
- sg_init_table(&sg, 1);
- sg_set_page(&sg, pfn_to_page(PFN_DOWN(buff)),
- size, offset_in_page(buff));
- sg_dma_len(&sg) = size;
- sg_dma_address(&sg) = buff;
-
- desc = dmaengine_prep_slave_sg(siu_stream->chan,
- &sg, 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
- if (!desc) {
- dev_err(dev, "Failed to allocate a dma descriptor\n");
- return -ENOMEM;
- }
-
- desc->callback = siu_dma_tx_complete;
- desc->callback_param = siu_stream;
- cookie = desc->tx_submit(desc);
- if (cookie < 0) {
- dev_err(dev, "Failed to submit a dma transfer\n");
- return cookie;
- }
-
- siu_stream->tx_desc = desc;
- siu_stream->cookie = cookie;
-
- dma_async_issue_pending(siu_stream->chan);
-
- /* only output FIFO enable */
- stfifo = siu_read32(base + SIU_STFIFO);
- siu_write32(base + SIU_STFIFO, stfifo | (port_info->stfifo & 0x0c180c18));
- dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__,
- stfifo, stfifo | (port_info->stfifo & 0x0c180c18));
-
- return 0;
-}
-
-static int siu_pcm_rd_set(struct siu_port *port_info,
- dma_addr_t buff, size_t size)
-{
- struct siu_info *info = siu_i2s_data;
- u32 __iomem *base = info->reg;
- struct siu_stream *siu_stream = &port_info->capture;
- struct snd_pcm_substream *substream = siu_stream->substream;
- struct device *dev = substream->pcm->card->dev;
- struct dma_async_tx_descriptor *desc;
- dma_cookie_t cookie;
- struct scatterlist sg;
- u32 stfifo;
-
- dev_dbg(dev, "%s: %u@%llx\n", __func__, size, (unsigned long long)buff);
-
- sg_init_table(&sg, 1);
- sg_set_page(&sg, pfn_to_page(PFN_DOWN(buff)),
- size, offset_in_page(buff));
- sg_dma_len(&sg) = size;
- sg_dma_address(&sg) = buff;
-
- desc = dmaengine_prep_slave_sg(siu_stream->chan,
- &sg, 1, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
- if (!desc) {
- dev_err(dev, "Failed to allocate dma descriptor\n");
- return -ENOMEM;
- }
-
- desc->callback = siu_dma_tx_complete;
- desc->callback_param = siu_stream;
- cookie = desc->tx_submit(desc);
- if (cookie < 0) {
- dev_err(dev, "Failed to submit dma descriptor\n");
- return cookie;
- }
-
- siu_stream->tx_desc = desc;
- siu_stream->cookie = cookie;
-
- dma_async_issue_pending(siu_stream->chan);
-
- /* only input FIFO enable */
- stfifo = siu_read32(base + SIU_STFIFO);
- siu_write32(base + SIU_STFIFO, siu_read32(base + SIU_STFIFO) |
- (port_info->stfifo & 0x13071307));
- dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__,
- stfifo, stfifo | (port_info->stfifo & 0x13071307));
-
- return 0;
-}
-
-static void siu_io_tasklet(unsigned long data)
-{
- struct siu_stream *siu_stream = (struct siu_stream *)data;
- struct snd_pcm_substream *substream = siu_stream->substream;
- struct device *dev = substream->pcm->card->dev;
- struct snd_pcm_runtime *rt = substream->runtime;
- struct siu_port *port_info = siu_port_info(substream);
-
- dev_dbg(dev, "%s: flags %x\n", __func__, siu_stream->rw_flg);
-
- if (!siu_stream->rw_flg) {
- dev_dbg(dev, "%s: stream inactive\n", __func__);
- return;
- }
-
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- dma_addr_t buff;
- size_t count;
- u8 *virt;
-
- buff = (dma_addr_t)PERIOD_OFFSET(rt->dma_addr,
- siu_stream->cur_period,
- siu_stream->period_bytes);
- virt = PERIOD_OFFSET(rt->dma_area,
- siu_stream->cur_period,
- siu_stream->period_bytes);
- count = siu_stream->period_bytes;
-
- /* DMA transfer start */
- siu_pcm_rd_set(port_info, buff, count);
- } else {
- siu_pcm_wr_set(port_info,
- (dma_addr_t)PERIOD_OFFSET(rt->dma_addr,
- siu_stream->cur_period,
- siu_stream->period_bytes),
- siu_stream->period_bytes);
- }
-}
-
-/* Capture */
-static int siu_pcm_stmread_start(struct siu_port *port_info)
-{
- struct siu_stream *siu_stream = &port_info->capture;
-
- if (siu_stream->xfer_cnt > 0x1000000)
- return -EINVAL;
- if (siu_stream->rw_flg)
- return -EPERM;
-
- /* Current period in buffer */
- siu_stream->cur_period = 0;
-
- /* during stmread flag set */
- siu_stream->rw_flg = RWF_STM_RD;
-
- tasklet_schedule(&siu_stream->tasklet);
-
- return 0;
-}
-
-static int siu_pcm_stmread_stop(struct siu_port *port_info)
-{
- struct siu_info *info = siu_i2s_data;
- u32 __iomem *base = info->reg;
- struct siu_stream *siu_stream = &port_info->capture;
- struct device *dev = siu_stream->substream->pcm->card->dev;
- u32 stfifo;
-
- if (!siu_stream->rw_flg)
- return -EPERM;
-
- /* input FIFO disable */
- stfifo = siu_read32(base + SIU_STFIFO);
- siu_write32(base + SIU_STFIFO, stfifo & ~0x13071307);
- dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__,
- stfifo, stfifo & ~0x13071307);
-
- /* during stmread flag clear */
- siu_stream->rw_flg = 0;
-
- return 0;
-}
-
-static int siu_pcm_hw_params(struct snd_pcm_substream *ss,
- struct snd_pcm_hw_params *hw_params)
-{
- struct siu_info *info = siu_i2s_data;
- struct device *dev = ss->pcm->card->dev;
- int ret;
-
- dev_dbg(dev, "%s: port=%d\n", __func__, info->port_id);
-
- ret = snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw_params));
- if (ret < 0)
- dev_err(dev, "snd_pcm_lib_malloc_pages() failed\n");
-
- return ret;
-}
-
-static int siu_pcm_hw_free(struct snd_pcm_substream *ss)
-{
- struct siu_info *info = siu_i2s_data;
- struct siu_port *port_info = siu_port_info(ss);
- struct device *dev = ss->pcm->card->dev;
- struct siu_stream *siu_stream;
-
- if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
- siu_stream = &port_info->playback;
- else
- siu_stream = &port_info->capture;
-
- dev_dbg(dev, "%s: port=%d\n", __func__, info->port_id);
-
- return snd_pcm_lib_free_pages(ss);
-}
-
-static bool filter(struct dma_chan *chan, void *slave)
-{
- struct sh_dmae_slave *param = slave;
-
- pr_debug("%s: slave ID %d\n", __func__, param->slave_id);
-
- if (unlikely(param->dma_dev != chan->device->dev))
- return false;
-
- chan->private = param;
- return true;
-}
-
-static int siu_pcm_open(struct snd_pcm_substream *ss)
-{
- /* Playback / Capture */
- struct snd_soc_pcm_runtime *rtd = ss->private_data;
- struct siu_platform *pdata = rtd->platform->dev->platform_data;
- struct siu_info *info = siu_i2s_data;
- struct siu_port *port_info = siu_port_info(ss);
- struct siu_stream *siu_stream;
- u32 port = info->port_id;
- struct device *dev = ss->pcm->card->dev;
- dma_cap_mask_t mask;
- struct sh_dmae_slave *param;
-
- dma_cap_zero(mask);
- dma_cap_set(DMA_SLAVE, mask);
-
- dev_dbg(dev, "%s, port=%d@%p\n", __func__, port, port_info);
-
- if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- siu_stream = &port_info->playback;
- param = &siu_stream->param;
- param->slave_id = port ? pdata->dma_slave_tx_b :
- pdata->dma_slave_tx_a;
- } else {
- siu_stream = &port_info->capture;
- param = &siu_stream->param;
- param->slave_id = port ? pdata->dma_slave_rx_b :
- pdata->dma_slave_rx_a;
- }
-
- param->dma_dev = pdata->dma_dev;
- /* Get DMA channel */
- siu_stream->chan = dma_request_channel(mask, filter, param);
- if (!siu_stream->chan) {
- dev_err(dev, "DMA channel allocation failed!\n");
- return -EBUSY;
- }
-
- siu_stream->substream = ss;
-
- return 0;
-}
-
-static int siu_pcm_close(struct snd_pcm_substream *ss)
-{
- struct siu_info *info = siu_i2s_data;
- struct device *dev = ss->pcm->card->dev;
- struct siu_port *port_info = siu_port_info(ss);
- struct siu_stream *siu_stream;
-
- dev_dbg(dev, "%s: port=%d\n", __func__, info->port_id);
-
- if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
- siu_stream = &port_info->playback;
- else
- siu_stream = &port_info->capture;
-
- dma_release_channel(siu_stream->chan);
- siu_stream->chan = NULL;
-
- siu_stream->substream = NULL;
-
- return 0;
-}
-
-static int siu_pcm_prepare(struct snd_pcm_substream *ss)
-{
- struct siu_info *info = siu_i2s_data;
- struct siu_port *port_info = siu_port_info(ss);
- struct device *dev = ss->pcm->card->dev;
- struct snd_pcm_runtime *rt = ss->runtime;
- struct siu_stream *siu_stream;
- snd_pcm_sframes_t xfer_cnt;
-
- if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
- siu_stream = &port_info->playback;
- else
- siu_stream = &port_info->capture;
-
- rt = siu_stream->substream->runtime;
-
- siu_stream->buf_bytes = snd_pcm_lib_buffer_bytes(ss);
- siu_stream->period_bytes = snd_pcm_lib_period_bytes(ss);
-
- dev_dbg(dev, "%s: port=%d, %d channels, period=%u bytes\n", __func__,
- info->port_id, rt->channels, siu_stream->period_bytes);
-
- /* We only support buffers that are multiples of the period */
- if (siu_stream->buf_bytes % siu_stream->period_bytes) {
- dev_err(dev, "%s() - buffer=%d not multiple of period=%d\n",
- __func__, siu_stream->buf_bytes,
- siu_stream->period_bytes);
- return -EINVAL;
- }
-
- xfer_cnt = bytes_to_frames(rt, siu_stream->period_bytes);
- if (!xfer_cnt || xfer_cnt > 0x1000000)
- return -EINVAL;
-
- siu_stream->format = rt->format;
- siu_stream->xfer_cnt = xfer_cnt;
-
- dev_dbg(dev, "port=%d buf=%lx buf_bytes=%d period_bytes=%d "
- "format=%d channels=%d xfer_cnt=%d\n", info->port_id,
- (unsigned long)rt->dma_addr, siu_stream->buf_bytes,
- siu_stream->period_bytes,
- siu_stream->format, rt->channels, (int)xfer_cnt);
-
- return 0;
-}
-
-static int siu_pcm_trigger(struct snd_pcm_substream *ss, int cmd)
-{
- struct siu_info *info = siu_i2s_data;
- struct device *dev = ss->pcm->card->dev;
- struct siu_port *port_info = siu_port_info(ss);
- int ret;
-
- dev_dbg(dev, "%s: port=%d@%p, cmd=%d\n", __func__,
- info->port_id, port_info, cmd);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
- ret = siu_pcm_stmwrite_start(port_info);
- else
- ret = siu_pcm_stmread_start(port_info);
-
- if (ret < 0)
- dev_warn(dev, "%s: start failed on port=%d\n",
- __func__, info->port_id);
-
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
- siu_pcm_stmwrite_stop(port_info);
- else
- siu_pcm_stmread_stop(port_info);
- ret = 0;
-
- break;
- default:
- dev_err(dev, "%s() unsupported cmd=%d\n", __func__, cmd);
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-/*
- * So far only resolution of one period is supported, subject to extending the
- * dmangine API
- */
-static snd_pcm_uframes_t siu_pcm_pointer_dma(struct snd_pcm_substream *ss)
-{
- struct device *dev = ss->pcm->card->dev;
- struct siu_info *info = siu_i2s_data;
- u32 __iomem *base = info->reg;
- struct siu_port *port_info = siu_port_info(ss);
- struct snd_pcm_runtime *rt = ss->runtime;
- size_t ptr;
- struct siu_stream *siu_stream;
-
- if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
- siu_stream = &port_info->playback;
- else
- siu_stream = &port_info->capture;
-
- /*
- * ptr is the offset into the buffer where the dma is currently at. We
- * check if the dma buffer has just wrapped.
- */
- ptr = PERIOD_OFFSET(rt->dma_addr,
- siu_stream->cur_period,
- siu_stream->period_bytes) - rt->dma_addr;
-
- dev_dbg(dev,
- "%s: port=%d, events %x, FSTS %x, xferred %u/%u, cookie %d\n",
- __func__, info->port_id, siu_read32(base + SIU_EVNTC),
- siu_read32(base + SIU_SBFSTS), ptr, siu_stream->buf_bytes,
- siu_stream->cookie);
-
- if (ptr >= siu_stream->buf_bytes)
- ptr = 0;
-
- return bytes_to_frames(ss->runtime, ptr);
-}
-
-static int siu_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
- /* card->dev == socdev->dev, see snd_soc_new_pcms() */
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- struct siu_info *info = siu_i2s_data;
- struct platform_device *pdev = to_platform_device(card->dev);
- int ret;
- int i;
-
- /* pdev->id selects between SIUA and SIUB */
- if (pdev->id < 0 || pdev->id >= SIU_PORT_NUM)
- return -EINVAL;
-
- info->port_id = pdev->id;
-
- /*
- * While the siu has 2 ports, only one port can be on at a time (only 1
- * SPB). So far all the boards using the siu had only one of the ports
- * wired to a codec. To simplify things, we only register one port with
- * alsa. In case both ports are needed, it should be changed here
- */
- for (i = pdev->id; i < pdev->id + 1; i++) {
- struct siu_port **port_info = &siu_ports[i];
-
- ret = siu_init_port(i, port_info, card);
- if (ret < 0)
- return ret;
-
- ret = snd_pcm_lib_preallocate_pages_for_all(pcm,
- SNDRV_DMA_TYPE_DEV, NULL,
- SIU_BUFFER_BYTES_MAX, SIU_BUFFER_BYTES_MAX);
- if (ret < 0) {
- dev_err(card->dev,
- "snd_pcm_lib_preallocate_pages_for_all() err=%d",
- ret);
- goto fail;
- }
-
- (*port_info)->pcm = pcm;
-
- /* IO tasklets */
- tasklet_init(&(*port_info)->playback.tasklet, siu_io_tasklet,
- (unsigned long)&(*port_info)->playback);
- tasklet_init(&(*port_info)->capture.tasklet, siu_io_tasklet,
- (unsigned long)&(*port_info)->capture);
- }
-
- dev_info(card->dev, "SuperH SIU driver initialized.\n");
- return 0;
-
-fail:
- siu_free_port(siu_ports[pdev->id]);
- dev_err(card->dev, "SIU: failed to initialize.\n");
- return ret;
-}
-
-static void siu_pcm_free(struct snd_pcm *pcm)
-{
- struct platform_device *pdev = to_platform_device(pcm->card->dev);
- struct siu_port *port_info = siu_ports[pdev->id];
-
- tasklet_kill(&port_info->capture.tasklet);
- tasklet_kill(&port_info->playback.tasklet);
-
- siu_free_port(port_info);
- snd_pcm_lib_preallocate_free_for_all(pcm);
-
- dev_dbg(pcm->card->dev, "%s\n", __func__);
-}
-
-static struct snd_pcm_ops siu_pcm_ops = {
- .open = siu_pcm_open,
- .close = siu_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = siu_pcm_hw_params,
- .hw_free = siu_pcm_hw_free,
- .prepare = siu_pcm_prepare,
- .trigger = siu_pcm_trigger,
- .pointer = siu_pcm_pointer_dma,
-};
-
-struct snd_soc_platform_driver siu_platform = {
- .ops = &siu_pcm_ops,
- .pcm_new = siu_pcm_new,
- .pcm_free = siu_pcm_free,
-};
-EXPORT_SYMBOL_GPL(siu_platform);
diff --git a/ANDROID_3.4.5/sound/soc/sh/ssi.c b/ANDROID_3.4.5/sound/soc/sh/ssi.c
deleted file mode 100644
index ff82b56a..00000000
--- a/ANDROID_3.4.5/sound/soc/sh/ssi.c
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Serial Sound Interface (I2S) support for SH7760/SH7780
- *
- * Copyright (c) 2007 Manuel Lauss <mano@roarinelk.homelinux.net>
- *
- * licensed under the terms outlined in the file COPYING at the root
- * of the linux kernel sources.
- *
- * dont forget to set IPSEL/OMSEL register bits (in your board code) to
- * enable SSI output pins!
- */
-
-/*
- * LIMITATIONS:
- * The SSI unit has only one physical data line, so full duplex is
- * impossible. This can be remedied on the SH7760 by using the
- * other SSI unit for recording; however the SH7780 has only 1 SSI
- * unit, and its pins are shared with the AC97 unit, among others.
- *
- * FEATURES:
- * The SSI features "compressed mode": in this mode it continuously
- * streams PCM data over the I2S lines and uses LRCK as a handshake
- * signal. Can be used to send compressed data (AC3/DTS) to a DSP.
- * The number of bits sent over the wire in a frame can be adjusted
- * and can be independent from the actual sample bit depth. This is
- * useful to support TDM mode codecs like the AD1939 which have a
- * fixed TDM slot size, regardless of sample resolution.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-#include <asm/io.h>
-
-#define SSICR 0x00
-#define SSISR 0x04
-
-#define CR_DMAEN (1 << 28)
-#define CR_CHNL_SHIFT 22
-#define CR_CHNL_MASK (3 << CR_CHNL_SHIFT)
-#define CR_DWL_SHIFT 19
-#define CR_DWL_MASK (7 << CR_DWL_SHIFT)
-#define CR_SWL_SHIFT 16
-#define CR_SWL_MASK (7 << CR_SWL_SHIFT)
-#define CR_SCK_MASTER (1 << 15) /* bitclock master bit */
-#define CR_SWS_MASTER (1 << 14) /* wordselect master bit */
-#define CR_SCKP (1 << 13) /* I2Sclock polarity */
-#define CR_SWSP (1 << 12) /* LRCK polarity */
-#define CR_SPDP (1 << 11)
-#define CR_SDTA (1 << 10) /* i2s alignment (msb/lsb) */
-#define CR_PDTA (1 << 9) /* fifo data alignment */
-#define CR_DEL (1 << 8) /* delay data by 1 i2sclk */
-#define CR_BREN (1 << 7) /* clock gating in burst mode */
-#define CR_CKDIV_SHIFT 4
-#define CR_CKDIV_MASK (7 << CR_CKDIV_SHIFT) /* bitclock divider */
-#define CR_MUTE (1 << 3) /* SSI mute */
-#define CR_CPEN (1 << 2) /* compressed mode */
-#define CR_TRMD (1 << 1) /* transmit/receive select */
-#define CR_EN (1 << 0) /* enable SSI */
-
-#define SSIREG(reg) (*(unsigned long *)(ssi->mmio + (reg)))
-
-struct ssi_priv {
- unsigned long mmio;
- unsigned long sysclk;
- int inuse;
-} ssi_cpu_data[] = {
-#if defined(CONFIG_CPU_SUBTYPE_SH7760)
- {
- .mmio = 0xFE680000,
- },
- {
- .mmio = 0xFE690000,
- },
-#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
- {
- .mmio = 0xFFE70000,
- },
-#else
-#error "Unsupported SuperH SoC"
-#endif
-};
-
-/*
- * track usage of the SSI; it is simplex-only so prevent attempts of
- * concurrent playback + capture. FIXME: any locking required?
- */
-static int ssi_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct ssi_priv *ssi = &ssi_cpu_data[dai->id];
- if (ssi->inuse) {
- pr_debug("ssi: already in use!\n");
- return -EBUSY;
- } else
- ssi->inuse = 1;
- return 0;
-}
-
-static void ssi_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct ssi_priv *ssi = &ssi_cpu_data[dai->id];
-
- ssi->inuse = 0;
-}
-
-static int ssi_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- struct ssi_priv *ssi = &ssi_cpu_data[dai->id];
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- SSIREG(SSICR) |= CR_DMAEN | CR_EN;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- SSIREG(SSICR) &= ~(CR_DMAEN | CR_EN);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int ssi_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct ssi_priv *ssi = &ssi_cpu_data[dai->id];
- unsigned long ssicr = SSIREG(SSICR);
- unsigned int bits, channels, swl, recv, i;
-
- channels = params_channels(params);
- bits = params->msbits;
- recv = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 0 : 1;
-
- pr_debug("ssi_hw_params() enter\nssicr was %08lx\n", ssicr);
- pr_debug("bits: %u channels: %u\n", bits, channels);
-
- ssicr &= ~(CR_TRMD | CR_CHNL_MASK | CR_DWL_MASK | CR_PDTA |
- CR_SWL_MASK);
-
- /* direction (send/receive) */
- if (!recv)
- ssicr |= CR_TRMD; /* transmit */
-
- /* channels */
- if ((channels < 2) || (channels > 8) || (channels & 1)) {
- pr_debug("ssi: invalid number of channels\n");
- return -EINVAL;
- }
- ssicr |= ((channels >> 1) - 1) << CR_CHNL_SHIFT;
-
- /* DATA WORD LENGTH (DWL): databits in audio sample */
- i = 0;
- switch (bits) {
- case 32: ++i;
- case 24: ++i;
- case 22: ++i;
- case 20: ++i;
- case 18: ++i;
- case 16: ++i;
- ssicr |= i << CR_DWL_SHIFT;
- case 8: break;
- default:
- pr_debug("ssi: invalid sample width\n");
- return -EINVAL;
- }
-
- /*
- * SYSTEM WORD LENGTH: size in bits of half a frame over the I2S
- * wires. This is usually bits_per_sample x channels/2; i.e. in
- * Stereo mode the SWL equals DWL. SWL can be bigger than the
- * product of (channels_per_slot x samplebits), e.g. for codecs
- * like the AD1939 which only accept 32bit wide TDM slots. For
- * "standard" I2S operation we set SWL = chans / 2 * DWL here.
- * Waiting for ASoC to get TDM support ;-)
- */
- if ((bits > 16) && (bits <= 24)) {
- bits = 24; /* these are padded by the SSI */
- /*ssicr |= CR_PDTA;*/ /* cpu/data endianness ? */
- }
- i = 0;
- swl = (bits * channels) / 2;
- switch (swl) {
- case 256: ++i;
- case 128: ++i;
- case 64: ++i;
- case 48: ++i;
- case 32: ++i;
- case 16: ++i;
- ssicr |= i << CR_SWL_SHIFT;
- case 8: break;
- default:
- pr_debug("ssi: invalid system word length computed\n");
- return -EINVAL;
- }
-
- SSIREG(SSICR) = ssicr;
-
- pr_debug("ssi_hw_params() leave\nssicr is now %08lx\n", ssicr);
- return 0;
-}
-
-static int ssi_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id,
- unsigned int freq, int dir)
-{
- struct ssi_priv *ssi = &ssi_cpu_data[cpu_dai->id];
-
- ssi->sysclk = freq;
-
- return 0;
-}
-
-/*
- * This divider is used to generate the SSI_SCK (I2S bitclock) from the
- * clock at the HAC_BIT_CLK ("oversampling clock") pin.
- */
-static int ssi_set_clkdiv(struct snd_soc_dai *dai, int did, int div)
-{
- struct ssi_priv *ssi = &ssi_cpu_data[dai->id];
- unsigned long ssicr;
- int i;
-
- i = 0;
- ssicr = SSIREG(SSICR) & ~CR_CKDIV_MASK;
- switch (div) {
- case 16: ++i;
- case 8: ++i;
- case 4: ++i;
- case 2: ++i;
- SSIREG(SSICR) = ssicr | (i << CR_CKDIV_SHIFT);
- case 1: break;
- default:
- pr_debug("ssi: invalid sck divider %d\n", div);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int ssi_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- struct ssi_priv *ssi = &ssi_cpu_data[dai->id];
- unsigned long ssicr = SSIREG(SSICR);
-
- pr_debug("ssi_set_fmt()\nssicr was 0x%08lx\n", ssicr);
-
- ssicr &= ~(CR_DEL | CR_PDTA | CR_BREN | CR_SWSP | CR_SCKP |
- CR_SWS_MASTER | CR_SCK_MASTER);
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- ssicr |= CR_DEL | CR_PDTA;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- ssicr |= CR_DEL;
- break;
- default:
- pr_debug("ssi: unsupported format\n");
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) {
- case SND_SOC_DAIFMT_CONT:
- break;
- case SND_SOC_DAIFMT_GATED:
- ssicr |= CR_BREN;
- break;
- }
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- ssicr |= CR_SCKP; /* sample data at low clkedge */
- break;
- case SND_SOC_DAIFMT_NB_IF:
- ssicr |= CR_SCKP | CR_SWSP;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- ssicr |= CR_SWSP; /* word select starts low */
- break;
- default:
- pr_debug("ssi: invalid inversion\n");
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- break;
- case SND_SOC_DAIFMT_CBS_CFM:
- ssicr |= CR_SCK_MASTER;
- break;
- case SND_SOC_DAIFMT_CBM_CFS:
- ssicr |= CR_SWS_MASTER;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- ssicr |= CR_SWS_MASTER | CR_SCK_MASTER;
- break;
- default:
- pr_debug("ssi: invalid master/slave configuration\n");
- return -EINVAL;
- }
-
- SSIREG(SSICR) = ssicr;
- pr_debug("ssi_set_fmt() leave\nssicr is now 0x%08lx\n", ssicr);
-
- return 0;
-}
-
-/* the SSI depends on an external clocksource (at HAC_BIT_CLK) even in
- * Master mode, so really this is board specific; the SSI can do any
- * rate with the right bitclk and divider settings.
- */
-#define SSI_RATES \
- SNDRV_PCM_RATE_8000_192000
-
-/* the SSI can do 8-32 bit samples, with 8 possible channels */
-#define SSI_FMTS \
- (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \
- SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \
- SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \
- SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE)
-
-static const struct snd_soc_dai_ops ssi_dai_ops = {
- .startup = ssi_startup,
- .shutdown = ssi_shutdown,
- .trigger = ssi_trigger,
- .hw_params = ssi_hw_params,
- .set_sysclk = ssi_set_sysclk,
- .set_clkdiv = ssi_set_clkdiv,
- .set_fmt = ssi_set_fmt,
-};
-
-static struct snd_soc_dai_driver sh4_ssi_dai[] = {
-{
- .name = "ssi-dai.0",
- .playback = {
- .rates = SSI_RATES,
- .formats = SSI_FMTS,
- .channels_min = 2,
- .channels_max = 8,
- },
- .capture = {
- .rates = SSI_RATES,
- .formats = SSI_FMTS,
- .channels_min = 2,
- .channels_max = 8,
- },
- .ops = &ssi_dai_ops,
-},
-#ifdef CONFIG_CPU_SUBTYPE_SH7760
-{
- .name = "ssi-dai.1",
- .playback = {
- .rates = SSI_RATES,
- .formats = SSI_FMTS,
- .channels_min = 2,
- .channels_max = 8,
- },
- .capture = {
- .rates = SSI_RATES,
- .formats = SSI_FMTS,
- .channels_min = 2,
- .channels_max = 8,
- },
- .ops = &ssi_dai_ops,
-},
-#endif
-};
-
-static int __devinit sh4_soc_dai_probe(struct platform_device *pdev)
-{
- return snd_soc_register_dais(&pdev->dev, sh4_ssi_dai,
- ARRAY_SIZE(sh4_ssi_dai));
-}
-
-static int __devexit sh4_soc_dai_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sh4_ssi_dai));
- return 0;
-}
-
-static struct platform_driver sh4_ssi_driver = {
- .driver = {
- .name = "sh4-ssi-dai",
- .owner = THIS_MODULE,
- },
-
- .probe = sh4_soc_dai_probe,
- .remove = __devexit_p(sh4_soc_dai_remove),
-};
-
-module_platform_driver(sh4_ssi_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver");
-MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/ANDROID_3.4.5/sound/soc/soc-cache.c b/ANDROID_3.4.5/sound/soc/soc-cache.c
deleted file mode 100644
index 9d56f021..00000000
--- a/ANDROID_3.4.5/sound/soc/soc-cache.c
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * soc-cache.c -- ASoC register cache helpers
- *
- * Copyright 2009 Wolfson Microelectronics PLC.
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/i2c.h>
-#include <linux/spi/spi.h>
-#include <sound/soc.h>
-#include <linux/bitmap.h>
-#include <linux/rbtree.h>
-#include <linux/export.h>
-
-#include <trace/events/asoc.h>
-
-static bool snd_soc_set_cache_val(void *base, unsigned int idx,
- unsigned int val, unsigned int word_size)
-{
- switch (word_size) {
- case 1: {
- u8 *cache = base;
- if (cache[idx] == val)
- return true;
- cache[idx] = val;
- break;
- }
- case 2: {
- u16 *cache = base;
- if (cache[idx] == val)
- return true;
- cache[idx] = val;
- break;
- }
- default:
- BUG();
- }
- return false;
-}
-
-static unsigned int snd_soc_get_cache_val(const void *base, unsigned int idx,
- unsigned int word_size)
-{
- if (!base)
- return -1;
-
- switch (word_size) {
- case 1: {
- const u8 *cache = base;
- return cache[idx];
- }
- case 2: {
- const u16 *cache = base;
- return cache[idx];
- }
- default:
- BUG();
- }
- /* unreachable */
- return -1;
-}
-
-static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
-{
- int i;
- int ret;
- const struct snd_soc_codec_driver *codec_drv;
- unsigned int val;
-
- codec_drv = codec->driver;
- for (i = 0; i < codec_drv->reg_cache_size; ++i) {
- ret = snd_soc_cache_read(codec, i, &val);
- if (ret)
- return ret;
- if (codec->reg_def_copy)
- if (snd_soc_get_cache_val(codec->reg_def_copy,
- i, codec_drv->reg_word_size) == val)
- continue;
-
- WARN_ON(!snd_soc_codec_writable_register(codec, i));
-
- ret = snd_soc_write(codec, i, val);
- if (ret)
- return ret;
- dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
- i, val);
- }
- return 0;
-}
-
-static int snd_soc_flat_cache_write(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int value)
-{
- snd_soc_set_cache_val(codec->reg_cache, reg, value,
- codec->driver->reg_word_size);
- return 0;
-}
-
-static int snd_soc_flat_cache_read(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int *value)
-{
- *value = snd_soc_get_cache_val(codec->reg_cache, reg,
- codec->driver->reg_word_size);
- return 0;
-}
-
-static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec)
-{
- if (!codec->reg_cache)
- return 0;
- kfree(codec->reg_cache);
- codec->reg_cache = NULL;
- return 0;
-}
-
-static int snd_soc_flat_cache_init(struct snd_soc_codec *codec)
-{
- if (codec->reg_def_copy)
- codec->reg_cache = kmemdup(codec->reg_def_copy,
- codec->reg_size, GFP_KERNEL);
- else
- codec->reg_cache = kzalloc(codec->reg_size, GFP_KERNEL);
- if (!codec->reg_cache)
- return -ENOMEM;
-
- return 0;
-}
-
-/* an array of all supported compression types */
-static const struct snd_soc_cache_ops cache_types[] = {
- /* Flat *must* be the first entry for fallback */
- {
- .id = SND_SOC_FLAT_COMPRESSION,
- .name = "flat",
- .init = snd_soc_flat_cache_init,
- .exit = snd_soc_flat_cache_exit,
- .read = snd_soc_flat_cache_read,
- .write = snd_soc_flat_cache_write,
- .sync = snd_soc_flat_cache_sync
- },
-};
-
-int snd_soc_cache_init(struct snd_soc_codec *codec)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(cache_types); ++i)
- if (cache_types[i].id == codec->compress_type)
- break;
-
- /* Fall back to flat compression */
- if (i == ARRAY_SIZE(cache_types)) {
- dev_warn(codec->dev, "Could not match compress type: %d\n",
- codec->compress_type);
- i = 0;
- }
-
- mutex_init(&codec->cache_rw_mutex);
- codec->cache_ops = &cache_types[i];
-
- if (codec->cache_ops->init) {
- if (codec->cache_ops->name)
- dev_dbg(codec->dev, "Initializing %s cache for %s codec\n",
- codec->cache_ops->name, codec->name);
- return codec->cache_ops->init(codec);
- }
- return -ENOSYS;
-}
-
-/*
- * NOTE: keep in mind that this function might be called
- * multiple times.
- */
-int snd_soc_cache_exit(struct snd_soc_codec *codec)
-{
- if (codec->cache_ops && codec->cache_ops->exit) {
- if (codec->cache_ops->name)
- dev_dbg(codec->dev, "Destroying %s cache for %s codec\n",
- codec->cache_ops->name, codec->name);
- return codec->cache_ops->exit(codec);
- }
- return -ENOSYS;
-}
-
-/**
- * snd_soc_cache_read: Fetch the value of a given register from the cache.
- *
- * @codec: CODEC to configure.
- * @reg: The register index.
- * @value: The value to be returned.
- */
-int snd_soc_cache_read(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int *value)
-{
- int ret;
-
- mutex_lock(&codec->cache_rw_mutex);
-
- if (value && codec->cache_ops && codec->cache_ops->read) {
- ret = codec->cache_ops->read(codec, reg, value);
- mutex_unlock(&codec->cache_rw_mutex);
- return ret;
- }
-
- mutex_unlock(&codec->cache_rw_mutex);
- return -ENOSYS;
-}
-EXPORT_SYMBOL_GPL(snd_soc_cache_read);
-
-/**
- * snd_soc_cache_write: Set the value of a given register in the cache.
- *
- * @codec: CODEC to configure.
- * @reg: The register index.
- * @value: The new register value.
- */
-int snd_soc_cache_write(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int value)
-{
- int ret;
-
- mutex_lock(&codec->cache_rw_mutex);
-
- if (codec->cache_ops && codec->cache_ops->write) {
- ret = codec->cache_ops->write(codec, reg, value);
- mutex_unlock(&codec->cache_rw_mutex);
- return ret;
- }
-
- mutex_unlock(&codec->cache_rw_mutex);
- return -ENOSYS;
-}
-EXPORT_SYMBOL_GPL(snd_soc_cache_write);
-
-/**
- * snd_soc_cache_sync: Sync the register cache with the hardware.
- *
- * @codec: CODEC to configure.
- *
- * Any registers that should not be synced should be marked as
- * volatile. In general drivers can choose not to use the provided
- * syncing functionality if they so require.
- */
-int snd_soc_cache_sync(struct snd_soc_codec *codec)
-{
- int ret;
- const char *name;
-
- if (!codec->cache_sync) {
- return 0;
- }
-
- if (!codec->cache_ops || !codec->cache_ops->sync)
- return -ENOSYS;
-
- if (codec->cache_ops->name)
- name = codec->cache_ops->name;
- else
- name = "unknown";
-
- if (codec->cache_ops->name)
- dev_dbg(codec->dev, "Syncing %s cache for %s codec\n",
- codec->cache_ops->name, codec->name);
- trace_snd_soc_cache_sync(codec, name, "start");
- ret = codec->cache_ops->sync(codec);
- if (!ret)
- codec->cache_sync = 0;
- trace_snd_soc_cache_sync(codec, name, "end");
- return ret;
-}
-EXPORT_SYMBOL_GPL(snd_soc_cache_sync);
-
-static int snd_soc_get_reg_access_index(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- const struct snd_soc_codec_driver *codec_drv;
- unsigned int min, max, index;
-
- codec_drv = codec->driver;
- min = 0;
- max = codec_drv->reg_access_size - 1;
- do {
- index = (min + max) / 2;
- if (codec_drv->reg_access_default[index].reg == reg)
- return index;
- if (codec_drv->reg_access_default[index].reg < reg)
- min = index + 1;
- else
- max = index;
- } while (min <= max);
- return -1;
-}
-
-int snd_soc_default_volatile_register(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- int index;
-
- if (reg >= codec->driver->reg_cache_size)
- return 1;
- index = snd_soc_get_reg_access_index(codec, reg);
- if (index < 0)
- return 0;
- return codec->driver->reg_access_default[index].vol;
-}
-EXPORT_SYMBOL_GPL(snd_soc_default_volatile_register);
-
-int snd_soc_default_readable_register(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- int index;
-
- if (reg >= codec->driver->reg_cache_size)
- return 1;
- index = snd_soc_get_reg_access_index(codec, reg);
- if (index < 0)
- return 0;
- return codec->driver->reg_access_default[index].read;
-}
-EXPORT_SYMBOL_GPL(snd_soc_default_readable_register);
-
-int snd_soc_default_writable_register(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- int index;
-
- if (reg >= codec->driver->reg_cache_size)
- return 1;
- index = snd_soc_get_reg_access_index(codec, reg);
- if (index < 0)
- return 0;
- return codec->driver->reg_access_default[index].write;
-}
-EXPORT_SYMBOL_GPL(snd_soc_default_writable_register);
diff --git a/ANDROID_3.4.5/sound/soc/soc-core.c b/ANDROID_3.4.5/sound/soc/soc-core.c
deleted file mode 100644
index 7e286549..00000000
--- a/ANDROID_3.4.5/sound/soc/soc-core.c
+++ /dev/null
@@ -1,3955 +0,0 @@
-/*
- * soc-core.c -- ALSA SoC Audio Layer
- *
- * Copyright 2005 Wolfson Microelectronics PLC.
- * Copyright 2005 Openedhand Ltd.
- * Copyright (C) 2010 Slimlogic Ltd.
- * Copyright (C) 2010 Texas Instruments Inc.
- *
- * Author: Liam Girdwood <lrg@slimlogic.co.uk>
- * with code, comments and ideas from :-
- * Richard Purdie <richard@openedhand.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * TODO:
- * o Add hw rules to enforce rates, etc.
- * o More testing with other codecs/machines.
- * o Add more codecs and platforms to ensure good API coverage.
- * o Support TDM on PCM and I2S
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/bitops.h>
-#include <linux/debugfs.h>
-#include <linux/platform_device.h>
-#include <linux/ctype.h>
-#include <linux/slab.h>
-#include <linux/of.h>
-#include <sound/ac97_codec.h>
-#include <sound/core.h>
-#include <sound/jack.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-
-#define CREATE_TRACE_POINTS
-#include <trace/events/asoc.h>
-
-#define NAME_SIZE 32
-
-static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq);
-
-#ifdef CONFIG_DEBUG_FS
-struct dentry *snd_soc_debugfs_root;
-EXPORT_SYMBOL_GPL(snd_soc_debugfs_root);
-#endif
-
-static DEFINE_MUTEX(client_mutex);
-static LIST_HEAD(card_list);
-static LIST_HEAD(dai_list);
-static LIST_HEAD(platform_list);
-static LIST_HEAD(codec_list);
-
-/*
- * This is a timeout to do a DAPM powerdown after a stream is closed().
- * It can be used to eliminate pops between different playback streams, e.g.
- * between two audio tracks.
- */
-static int pmdown_time = 5000;
-module_param(pmdown_time, int, 0);
-MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");
-
-/* returns the minimum number of bytes needed to represent
- * a particular given value */
-static int min_bytes_needed(unsigned long val)
-{
- int c = 0;
- int i;
-
- for (i = (sizeof val * 8) - 1; i >= 0; --i, ++c)
- if (val & (1UL << i))
- break;
- c = (sizeof val * 8) - c;
- if (!c || (c % 8))
- c = (c + 8) / 8;
- else
- c /= 8;
- return c;
-}
-
-/* fill buf which is 'len' bytes with a formatted
- * string of the form 'reg: value\n' */
-static int format_register_str(struct snd_soc_codec *codec,
- unsigned int reg, char *buf, size_t len)
-{
- int wordsize = min_bytes_needed(codec->driver->reg_cache_size) * 2;
- int regsize = codec->driver->reg_word_size * 2;
- int ret;
- char tmpbuf[len + 1];
- char regbuf[regsize + 1];
-
- /* since tmpbuf is allocated on the stack, warn the callers if they
- * try to abuse this function */
- WARN_ON(len > 63);
-
- /* +2 for ': ' and + 1 for '\n' */
- if (wordsize + regsize + 2 + 1 != len)
- return -EINVAL;
-
- ret = snd_soc_read(codec, reg);
- if (ret < 0) {
- memset(regbuf, 'X', regsize);
- regbuf[regsize] = '\0';
- } else {
- snprintf(regbuf, regsize + 1, "%.*x", regsize, ret);
- }
-
- /* prepare the buffer */
- snprintf(tmpbuf, len + 1, "%.*x: %s\n", wordsize, reg, regbuf);
- /* copy it back to the caller without the '\0' */
- memcpy(buf, tmpbuf, len);
-
- return 0;
-}
-
-/* codec register dump */
-static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf,
- size_t count, loff_t pos)
-{
- int i, step = 1;
- int wordsize, regsize;
- int len;
- size_t total = 0;
- loff_t p = 0;
-
- wordsize = min_bytes_needed(codec->driver->reg_cache_size) * 2;
- regsize = codec->driver->reg_word_size * 2;
-
- len = wordsize + regsize + 2 + 1;
-
- if (!codec->driver->reg_cache_size)
- return 0;
-
- if (codec->driver->reg_cache_step)
- step = codec->driver->reg_cache_step;
-
- for (i = 0; i < codec->driver->reg_cache_size; i += step) {
- if (!snd_soc_codec_readable_register(codec, i))
- continue;
- if (codec->driver->display_register) {
- count += codec->driver->display_register(codec, buf + count,
- PAGE_SIZE - count, i);
- } else {
- /* only support larger than PAGE_SIZE bytes debugfs
- * entries for the default case */
- if (p >= pos) {
- if (total + len >= count - 1)
- break;
- format_register_str(codec, i, buf + total, len);
- total += len;
- }
- p += len;
- }
- }
-
- total = min(total, count - 1);
-
- return total;
-}
-
-static ssize_t codec_reg_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
-
- return soc_codec_reg_show(rtd->codec, buf, PAGE_SIZE, 0);
-}
-
-static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
-
-static ssize_t pmdown_time_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
-
- return sprintf(buf, "%ld\n", rtd->pmdown_time);
-}
-
-static ssize_t pmdown_time_set(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
- int ret;
-
- ret = strict_strtol(buf, 10, &rtd->pmdown_time);
- if (ret)
- return ret;
-
- return count;
-}
-
-static DEVICE_ATTR(pmdown_time, 0644, pmdown_time_show, pmdown_time_set);
-
-#ifdef CONFIG_DEBUG_FS
-static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- ssize_t ret;
- struct snd_soc_codec *codec = file->private_data;
- char *buf;
-
- if (*ppos < 0 || !count)
- return -EINVAL;
-
- buf = kmalloc(count, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- ret = soc_codec_reg_show(codec, buf, count, *ppos);
- if (ret >= 0) {
- if (copy_to_user(user_buf, buf, ret)) {
- kfree(buf);
- return -EFAULT;
- }
- *ppos += ret;
- }
-
- kfree(buf);
- return ret;
-}
-
-static ssize_t codec_reg_write_file(struct file *file,
- const char __user *user_buf, size_t count, loff_t *ppos)
-{
- char buf[32];
- size_t buf_size;
- char *start = buf;
- unsigned long reg, value;
- struct snd_soc_codec *codec = file->private_data;
-
- buf_size = min(count, (sizeof(buf)-1));
- if (copy_from_user(buf, user_buf, buf_size))
- return -EFAULT;
- buf[buf_size] = 0;
-
- while (*start == ' ')
- start++;
- reg = simple_strtoul(start, &start, 16);
- while (*start == ' ')
- start++;
- if (strict_strtoul(start, 16, &value))
- return -EINVAL;
-
- /* Userspace has been fiddling around behind the kernel's back */
- add_taint(TAINT_USER);
-
- snd_soc_write(codec, reg, value);
- return buf_size;
-}
-
-static const struct file_operations codec_reg_fops = {
- .open = simple_open,
- .read = codec_reg_read_file,
- .write = codec_reg_write_file,
- .llseek = default_llseek,
-};
-
-static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
-{
- struct dentry *debugfs_card_root = codec->card->debugfs_card_root;
-
- codec->debugfs_codec_root = debugfs_create_dir(codec->name,
- debugfs_card_root);
- if (!codec->debugfs_codec_root) {
- dev_warn(codec->dev, "Failed to create codec debugfs directory\n");
- return;
- }
-
- debugfs_create_bool("cache_sync", 0444, codec->debugfs_codec_root,
- &codec->cache_sync);
- debugfs_create_bool("cache_only", 0444, codec->debugfs_codec_root,
- &codec->cache_only);
-
- codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
- codec->debugfs_codec_root,
- codec, &codec_reg_fops);
- if (!codec->debugfs_reg)
- dev_warn(codec->dev, "Failed to create codec register debugfs file\n");
-
- snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root);
-}
-
-static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
-{
- debugfs_remove_recursive(codec->debugfs_codec_root);
-}
-
-static void soc_init_platform_debugfs(struct snd_soc_platform *platform)
-{
- struct dentry *debugfs_card_root = platform->card->debugfs_card_root;
-
- platform->debugfs_platform_root = debugfs_create_dir(platform->name,
- debugfs_card_root);
- if (!platform->debugfs_platform_root) {
- dev_warn(platform->dev,
- "Failed to create platform debugfs directory\n");
- return;
- }
-
- snd_soc_dapm_debugfs_init(&platform->dapm,
- platform->debugfs_platform_root);
-}
-
-static void soc_cleanup_platform_debugfs(struct snd_soc_platform *platform)
-{
- debugfs_remove_recursive(platform->debugfs_platform_root);
-}
-
-static ssize_t codec_list_read_file(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
- ssize_t len, ret = 0;
- struct snd_soc_codec *codec;
-
- if (!buf)
- return -ENOMEM;
-
- list_for_each_entry(codec, &codec_list, list) {
- len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n",
- codec->name);
- if (len >= 0)
- ret += len;
- if (ret > PAGE_SIZE) {
- ret = PAGE_SIZE;
- break;
- }
- }
-
- if (ret >= 0)
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
-
- kfree(buf);
-
- return ret;
-}
-
-static const struct file_operations codec_list_fops = {
- .read = codec_list_read_file,
- .llseek = default_llseek,/* read accesses f_pos */
-};
-
-static ssize_t dai_list_read_file(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
- ssize_t len, ret = 0;
- struct snd_soc_dai *dai;
-
- if (!buf)
- return -ENOMEM;
-
- list_for_each_entry(dai, &dai_list, list) {
- len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", dai->name);
- if (len >= 0)
- ret += len;
- if (ret > PAGE_SIZE) {
- ret = PAGE_SIZE;
- break;
- }
- }
-
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
-
- kfree(buf);
-
- return ret;
-}
-
-static const struct file_operations dai_list_fops = {
- .read = dai_list_read_file,
- .llseek = default_llseek,/* read accesses f_pos */
-};
-
-static ssize_t platform_list_read_file(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
- ssize_t len, ret = 0;
- struct snd_soc_platform *platform;
-
- if (!buf)
- return -ENOMEM;
-
- list_for_each_entry(platform, &platform_list, list) {
- len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n",
- platform->name);
- if (len >= 0)
- ret += len;
- if (ret > PAGE_SIZE) {
- ret = PAGE_SIZE;
- break;
- }
- }
-
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
-
- kfree(buf);
-
- return ret;
-}
-
-static const struct file_operations platform_list_fops = {
- .read = platform_list_read_file,
- .llseek = default_llseek,/* read accesses f_pos */
-};
-
-static void soc_init_card_debugfs(struct snd_soc_card *card)
-{
- card->debugfs_card_root = debugfs_create_dir(card->name,
- snd_soc_debugfs_root);
- if (!card->debugfs_card_root) {
- dev_warn(card->dev,
- "ASoC: Failed to create card debugfs directory\n");
- return;
- }
-
- card->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0644,
- card->debugfs_card_root,
- &card->pop_time);
- if (!card->debugfs_pop_time)
- dev_warn(card->dev,
- "Failed to create pop time debugfs file\n");
-}
-
-static void soc_cleanup_card_debugfs(struct snd_soc_card *card)
-{
- debugfs_remove_recursive(card->debugfs_card_root);
-}
-
-#else
-
-static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
-{
-}
-
-static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
-{
-}
-
-static inline void soc_init_platform_debugfs(struct snd_soc_platform *platform)
-{
-}
-
-static inline void soc_cleanup_platform_debugfs(struct snd_soc_platform *platform)
-{
-}
-
-static inline void soc_init_card_debugfs(struct snd_soc_card *card)
-{
-}
-
-static inline void soc_cleanup_card_debugfs(struct snd_soc_card *card)
-{
-}
-#endif
-
-#ifdef CONFIG_SND_SOC_AC97_BUS
-/* unregister ac97 codec */
-static int soc_ac97_dev_unregister(struct snd_soc_codec *codec)
-{
- if (codec->ac97->dev.bus)
- device_unregister(&codec->ac97->dev);
- return 0;
-}
-
-/* stop no dev release warning */
-static void soc_ac97_device_release(struct device *dev){}
-
-/* register ac97 codec to bus */
-static int soc_ac97_dev_register(struct snd_soc_codec *codec)
-{
- int err;
-
- codec->ac97->dev.bus = &ac97_bus_type;
- codec->ac97->dev.parent = codec->card->dev;
- codec->ac97->dev.release = soc_ac97_device_release;
-
- dev_set_name(&codec->ac97->dev, "%d-%d:%s",
- codec->card->snd_card->number, 0, codec->name);
- err = device_register(&codec->ac97->dev);
- if (err < 0) {
- snd_printk(KERN_ERR "Can't register ac97 bus\n");
- codec->ac97->dev.bus = NULL;
- return err;
- }
- return 0;
-}
-#endif
-
-#ifdef CONFIG_PM_SLEEP
-/* powers down audio subsystem for suspend */
-int snd_soc_suspend(struct device *dev)
-{
- struct snd_soc_card *card = dev_get_drvdata(dev);
- struct snd_soc_codec *codec;
- int i;
-
- /* If the initialization of this soc device failed, there is no codec
- * associated with it. Just bail out in this case.
- */
- if (list_empty(&card->codec_dev_list))
- return 0;
-
- /* Due to the resume being scheduled into a workqueue we could
- * suspend before that's finished - wait for it to complete.
- */
- snd_power_lock(card->snd_card);
- snd_power_wait(card->snd_card, SNDRV_CTL_POWER_D0);
- snd_power_unlock(card->snd_card);
-
- /* we're going to block userspace touching us until resume completes */
- snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot);
-
- /* mute any active DACs */
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_dai *dai = card->rtd[i].codec_dai;
- struct snd_soc_dai_driver *drv = dai->driver;
-
- if (card->rtd[i].dai_link->ignore_suspend)
- continue;
-
- if (drv->ops->digital_mute && dai->playback_active)
- drv->ops->digital_mute(dai, 1);
- }
-
- /* suspend all pcms */
- for (i = 0; i < card->num_rtd; i++) {
- if (card->rtd[i].dai_link->ignore_suspend)
- continue;
-
- snd_pcm_suspend_all(card->rtd[i].pcm);
- }
-
- if (card->suspend_pre)
- card->suspend_pre(card);
-
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
- struct snd_soc_platform *platform = card->rtd[i].platform;
-
- if (card->rtd[i].dai_link->ignore_suspend)
- continue;
-
- if (cpu_dai->driver->suspend && !cpu_dai->driver->ac97_control)
- cpu_dai->driver->suspend(cpu_dai);
- if (platform->driver->suspend && !platform->suspended) {
- platform->driver->suspend(cpu_dai);
- platform->suspended = 1;
- }
- }
-
- /* close any waiting streams and save state */
- for (i = 0; i < card->num_rtd; i++) {
- flush_delayed_work_sync(&card->rtd[i].delayed_work);
- card->rtd[i].codec->dapm.suspend_bias_level = card->rtd[i].codec->dapm.bias_level;
- }
-
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_dai *codec_dai = card->rtd[i].codec_dai;
-
- if (card->rtd[i].dai_link->ignore_suspend)
- continue;
-
- snd_soc_dapm_stream_event(&card->rtd[i],
- SNDRV_PCM_STREAM_PLAYBACK,
- codec_dai,
- SND_SOC_DAPM_STREAM_SUSPEND);
-
- snd_soc_dapm_stream_event(&card->rtd[i],
- SNDRV_PCM_STREAM_CAPTURE,
- codec_dai,
- SND_SOC_DAPM_STREAM_SUSPEND);
- }
-
- /* suspend all CODECs */
- list_for_each_entry(codec, &card->codec_dev_list, card_list) {
- /* If there are paths active then the CODEC will be held with
- * bias _ON and should not be suspended. */
- if (!codec->suspended && codec->driver->suspend) {
- switch (codec->dapm.bias_level) {
- case SND_SOC_BIAS_STANDBY:
- /*
- * If the CODEC is capable of idle
- * bias off then being in STANDBY
- * means it's doing something,
- * otherwise fall through.
- */
- if (codec->dapm.idle_bias_off) {
- dev_dbg(codec->dev,
- "idle_bias_off CODEC on over suspend\n");
- break;
- }
- case SND_SOC_BIAS_OFF:
- codec->driver->suspend(codec);
- codec->suspended = 1;
- codec->cache_sync = 1;
- break;
- default:
- dev_dbg(codec->dev, "CODEC is on over suspend\n");
- break;
- }
- }
- }
-
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
-
- if (card->rtd[i].dai_link->ignore_suspend)
- continue;
-
- if (cpu_dai->driver->suspend && cpu_dai->driver->ac97_control)
- cpu_dai->driver->suspend(cpu_dai);
- }
-
- if (card->suspend_post)
- card->suspend_post(card);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_suspend);
-
-/* deferred resume work, so resume can complete before we finished
- * setting our codec back up, which can be very slow on I2C
- */
-static void soc_resume_deferred(struct work_struct *work)
-{
- struct snd_soc_card *card =
- container_of(work, struct snd_soc_card, deferred_resume_work);
- struct snd_soc_codec *codec;
- int i;
-
- int dbg_resume = 0;
- /* our power state is still SNDRV_CTL_POWER_D3hot from suspend time,
- * so userspace apps are blocked from touching us
- */
-
- dev_dbg(card->dev, "starting resume work\n");
-
- /* Bring us up into D2 so that DAPM starts enabling things */
- snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D2);
-
- if (card->resume_pre)
- card->resume_pre(card);
-
- /* resume AC97 DAIs */
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
-
- if (card->rtd[i].dai_link->ignore_suspend)
- continue;
-
- if (cpu_dai->driver->resume && cpu_dai->driver->ac97_control)
- cpu_dai->driver->resume(cpu_dai);
- }
-
- list_for_each_entry(codec, &card->codec_dev_list, card_list) {
- /* If the CODEC was idle over suspend then it will have been
- * left with bias OFF or STANDBY and suspended so we must now
- * resume. Otherwise the suspend was suppressed.
- */
- if (codec->driver->resume && codec->suspended) {
- switch (codec->dapm.bias_level) {
- case SND_SOC_BIAS_STANDBY:
- case SND_SOC_BIAS_OFF:
- codec->driver->resume(codec);
- codec->suspended = 0;
- dbg_resume = 1;
- break;
- default:
-
- dev_dbg(codec->dev, "CODEC was on over suspend\n");
- break;
- }
- }
- #if 1
- if (!dbg_resume && codec->driver->resume) //add for temp std 2014-3-24
- {
- dbg_resume = 1;
- codec->driver->resume(codec);
- codec->suspended = 0;
-
- }
- #endif
- }
-
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_dai *codec_dai = card->rtd[i].codec_dai;
-
- if (card->rtd[i].dai_link->ignore_suspend)
- continue;
-
- snd_soc_dapm_stream_event(&card->rtd[i],
- SNDRV_PCM_STREAM_PLAYBACK, codec_dai,
- SND_SOC_DAPM_STREAM_RESUME);
-
- snd_soc_dapm_stream_event(&card->rtd[i],
- SNDRV_PCM_STREAM_CAPTURE, codec_dai,
- SND_SOC_DAPM_STREAM_RESUME);
- }
-
- /* unmute any active DACs */
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_dai *dai = card->rtd[i].codec_dai;
- struct snd_soc_dai_driver *drv = dai->driver;
-
- if (card->rtd[i].dai_link->ignore_suspend)
- continue;
-
- if (drv->ops->digital_mute && dai->playback_active)
- drv->ops->digital_mute(dai, 0);
- }
-
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
- struct snd_soc_platform *platform = card->rtd[i].platform;
-
- if (card->rtd[i].dai_link->ignore_suspend)
- continue;
-
- if (cpu_dai->driver->resume && !cpu_dai->driver->ac97_control)
- cpu_dai->driver->resume(cpu_dai);
- if (platform->driver->resume && platform->suspended) {
- platform->driver->resume(cpu_dai);
- platform->suspended = 0;
- }
- }
-
- if (card->resume_post)
- card->resume_post(card);
-
- dev_dbg(card->dev, "resume work completed\n");
-
- /* userspace can access us now we are back as we were before */
- snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0);
-}
-
-/* powers up audio subsystem after a suspend */
-int snd_soc_resume(struct device *dev)
-{
- struct snd_soc_card *card = dev_get_drvdata(dev);
- int i, ac97_control = 0;
-
- /* If the initialization of this soc device failed, there is no codec
- * associated with it. Just bail out in this case.
- */
- if (list_empty(&card->codec_dev_list))
- return 0;
-
- /* AC97 devices might have other drivers hanging off them so
- * need to resume immediately. Other drivers don't have that
- * problem and may take a substantial amount of time to resume
- * due to I/O costs and anti-pop so handle them out of line.
- */
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
- ac97_control |= cpu_dai->driver->ac97_control;
- }
- if (ac97_control) {
- dev_dbg(dev, "Resuming AC97 immediately\n");
- soc_resume_deferred(&card->deferred_resume_work);
- } else {
- dev_dbg(dev, "Scheduling resume work\n");
- if (!schedule_work(&card->deferred_resume_work))
- dev_err(dev, "resume work item may be lost\n");
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_resume);
-#else
-#define snd_soc_suspend NULL
-#define snd_soc_resume NULL
-#endif
-
-static const struct snd_soc_dai_ops null_dai_ops = {
-};
-
-static int soc_bind_dai_link(struct snd_soc_card *card, int num)
-{
- struct snd_soc_dai_link *dai_link = &card->dai_link[num];
- struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
- struct snd_soc_codec *codec;
- struct snd_soc_platform *platform;
- struct snd_soc_dai *codec_dai, *cpu_dai;
- const char *platform_name;
-
- if (rtd->complete)
- return 1;
- dev_dbg(card->dev, "binding %s at idx %d\n", dai_link->name, num);
-
- /* do we already have the CPU DAI for this link ? */
- if (rtd->cpu_dai) {
- goto find_codec;
- }
- /* no, then find CPU DAI from registered DAIs*/
- list_for_each_entry(cpu_dai, &dai_list, list) {
- if (dai_link->cpu_dai_of_node) {
- if (cpu_dai->dev->of_node != dai_link->cpu_dai_of_node)
- continue;
- } else {
- if (strcmp(cpu_dai->name, dai_link->cpu_dai_name))
- continue;
- }
-
- rtd->cpu_dai = cpu_dai;
- goto find_codec;
- }
- dev_dbg(card->dev, "CPU DAI %s not registered\n",
- dai_link->cpu_dai_name);
-
-find_codec:
- /* do we already have the CODEC for this link ? */
- if (rtd->codec) {
- goto find_platform;
- }
-
- /* no, then find CODEC from registered CODECs*/
- list_for_each_entry(codec, &codec_list, list) {
- if (dai_link->codec_of_node) {
- if (codec->dev->of_node != dai_link->codec_of_node)
- continue;
- } else {
- if (strcmp(codec->name, dai_link->codec_name))
- continue;
- }
-
- rtd->codec = codec;
-
- /*
- * CODEC found, so find CODEC DAI from registered DAIs from
- * this CODEC
- */
- list_for_each_entry(codec_dai, &dai_list, list) {
- if (codec->dev == codec_dai->dev &&
- !strcmp(codec_dai->name,
- dai_link->codec_dai_name)) {
-
- rtd->codec_dai = codec_dai;
- goto find_platform;
- }
- }
- dev_dbg(card->dev, "CODEC DAI %s not registered\n",
- dai_link->codec_dai_name);
-
- goto find_platform;
- }
- dev_dbg(card->dev, "CODEC %s not registered\n",
- dai_link->codec_name);
-
-find_platform:
- /* do we need a platform? */
- if (rtd->platform)
- goto out;
-
- /* if there's no platform we match on the empty platform */
- platform_name = dai_link->platform_name;
- if (!platform_name && !dai_link->platform_of_node)
- platform_name = "snd-soc-dummy";
-
- /* no, then find one from the set of registered platforms */
- list_for_each_entry(platform, &platform_list, list) {
- if (dai_link->platform_of_node) {
- if (platform->dev->of_node !=
- dai_link->platform_of_node)
- continue;
- } else {
- if (strcmp(platform->name, platform_name))
- continue;
- }
-
- rtd->platform = platform;
- goto out;
- }
-
- dev_dbg(card->dev, "platform %s not registered\n",
- dai_link->platform_name);
- return 0;
-
-out:
- /* mark rtd as complete if we found all 4 of our client devices */
- if (rtd->codec && rtd->codec_dai && rtd->platform && rtd->cpu_dai) {
- rtd->complete = 1;
- card->num_rtd++;
- }
- return 1;
-}
-
-static void soc_remove_codec(struct snd_soc_codec *codec)
-{
- int err;
-
- if (codec->driver->remove) {
- err = codec->driver->remove(codec);
- if (err < 0)
- dev_err(codec->dev,
- "asoc: failed to remove %s: %d\n",
- codec->name, err);
- }
-
- /* Make sure all DAPM widgets are freed */
- snd_soc_dapm_free(&codec->dapm);
-
- soc_cleanup_codec_debugfs(codec);
- codec->probed = 0;
- list_del(&codec->card_list);
- module_put(codec->dev->driver->owner);
-}
-
-static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order)
-{
- struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_platform *platform = rtd->platform;
- struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai;
- int err;
-
- /* unregister the rtd device */
- if (rtd->dev_registered) {
- device_remove_file(rtd->dev, &dev_attr_pmdown_time);
- device_remove_file(rtd->dev, &dev_attr_codec_reg);
- device_unregister(rtd->dev);
- rtd->dev_registered = 0;
- }
-
- /* remove the CODEC DAI */
- if (codec_dai && codec_dai->probed &&
- codec_dai->driver->remove_order == order) {
- if (codec_dai->driver->remove) {
- err = codec_dai->driver->remove(codec_dai);
- if (err < 0)
- pr_err("asoc: failed to remove %s: %d\n",
- codec_dai->name, err);
- }
- codec_dai->probed = 0;
- list_del(&codec_dai->card_list);
- }
-
- /* remove the platform */
- if (platform && platform->probed &&
- platform->driver->remove_order == order) {
- if (platform->driver->remove) {
- err = platform->driver->remove(platform);
- if (err < 0)
- pr_err("asoc: failed to remove %s: %d\n",
- platform->name, err);
- }
-
- /* Make sure all DAPM widgets are freed */
- snd_soc_dapm_free(&platform->dapm);
-
- soc_cleanup_platform_debugfs(platform);
- platform->probed = 0;
- list_del(&platform->card_list);
- module_put(platform->dev->driver->owner);
- }
-
- /* remove the CODEC */
- if (codec && codec->probed &&
- codec->driver->remove_order == order)
- soc_remove_codec(codec);
-
- /* remove the cpu_dai */
- if (cpu_dai && cpu_dai->probed &&
- cpu_dai->driver->remove_order == order) {
- if (cpu_dai->driver->remove) {
- err = cpu_dai->driver->remove(cpu_dai);
- if (err < 0)
- pr_err("asoc: failed to remove %s: %d\n",
- cpu_dai->name, err);
- }
- cpu_dai->probed = 0;
- list_del(&cpu_dai->card_list);
- module_put(cpu_dai->dev->driver->owner);
- }
-}
-
-static void soc_remove_dai_links(struct snd_soc_card *card)
-{
- int dai, order;
-
- for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
- order++) {
- for (dai = 0; dai < card->num_rtd; dai++)
- soc_remove_dai_link(card, dai, order);
- }
- card->num_rtd = 0;
-}
-
-static void soc_set_name_prefix(struct snd_soc_card *card,
- struct snd_soc_codec *codec)
-{
- int i;
-
- if (card->codec_conf == NULL)
- return;
-
- for (i = 0; i < card->num_configs; i++) {
- struct snd_soc_codec_conf *map = &card->codec_conf[i];
- if (map->dev_name && !strcmp(codec->name, map->dev_name)) {
- codec->name_prefix = map->name_prefix;
- break;
- }
- }
-}
-
-static int soc_probe_codec(struct snd_soc_card *card,
- struct snd_soc_codec *codec)
-{
- int ret = 0;
- const struct snd_soc_codec_driver *driver = codec->driver;
- struct snd_soc_dai *dai;
-
- codec->card = card;
- codec->dapm.card = card;
- soc_set_name_prefix(card, codec);
-
- if (!try_module_get(codec->dev->driver->owner))
- return -ENODEV;
-
- soc_init_codec_debugfs(codec);
-
- if (driver->dapm_widgets)
- snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets,
- driver->num_dapm_widgets);
-
- /* Create DAPM widgets for each DAI stream */
- list_for_each_entry(dai, &dai_list, list) {
- if (dai->dev != codec->dev)
- continue;
-
- snd_soc_dapm_new_dai_widgets(&codec->dapm, dai);
- }
-
- codec->dapm.idle_bias_off = driver->idle_bias_off;
-
- if (driver->probe) {
- ret = driver->probe(codec);
- if (ret < 0) {
- dev_err(codec->dev,
- "asoc: failed to probe CODEC %s: %d\n",
- codec->name, ret);
- goto err_probe;
- }
- }
-
- if (driver->controls)
- snd_soc_add_codec_controls(codec, driver->controls,
- driver->num_controls);
- if (driver->dapm_routes)
- snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes,
- driver->num_dapm_routes);
-
- /* mark codec as probed and add to card codec list */
- codec->probed = 1;
- list_add(&codec->card_list, &card->codec_dev_list);
- list_add(&codec->dapm.list, &card->dapm_list);
-
- return 0;
-
-err_probe:
- soc_cleanup_codec_debugfs(codec);
- module_put(codec->dev->driver->owner);
-
- return ret;
-}
-
-static int soc_probe_platform(struct snd_soc_card *card,
- struct snd_soc_platform *platform)
-{
- int ret = 0;
- const struct snd_soc_platform_driver *driver = platform->driver;
-
- platform->card = card;
- platform->dapm.card = card;
-
- if (!try_module_get(platform->dev->driver->owner))
- return -ENODEV;
-
- soc_init_platform_debugfs(platform);
-
- if (driver->dapm_widgets)
- snd_soc_dapm_new_controls(&platform->dapm,
- driver->dapm_widgets, driver->num_dapm_widgets);
-
- platform->dapm.idle_bias_off = 1;
-
- if (driver->probe) {
- ret = driver->probe(platform);
- if (ret < 0) {
- dev_err(platform->dev,
- "asoc: failed to probe platform %s: %d\n",
- platform->name, ret);
- goto err_probe;
- }
- }
-
- if (driver->controls)
- snd_soc_add_platform_controls(platform, driver->controls,
- driver->num_controls);
- if (driver->dapm_routes)
- snd_soc_dapm_add_routes(&platform->dapm, driver->dapm_routes,
- driver->num_dapm_routes);
-
- /* mark platform as probed and add to card platform list */
- platform->probed = 1;
- list_add(&platform->card_list, &card->platform_dev_list);
- list_add(&platform->dapm.list, &card->dapm_list);
-
- return 0;
-
-err_probe:
- soc_cleanup_platform_debugfs(platform);
- module_put(platform->dev->driver->owner);
-
- return ret;
-}
-
-static void rtd_release(struct device *dev)
-{
- kfree(dev);
-}
-
-static int soc_post_component_init(struct snd_soc_card *card,
- struct snd_soc_codec *codec,
- int num, int dailess)
-{
- struct snd_soc_dai_link *dai_link = NULL;
- struct snd_soc_aux_dev *aux_dev = NULL;
- struct snd_soc_pcm_runtime *rtd;
- const char *temp, *name;
- int ret = 0;
-
- if (!dailess) {
- dai_link = &card->dai_link[num];
- rtd = &card->rtd[num];
- name = dai_link->name;
- } else {
- aux_dev = &card->aux_dev[num];
- rtd = &card->rtd_aux[num];
- name = aux_dev->name;
- }
- rtd->card = card;
-
- /* Make sure all DAPM widgets are instantiated */
- snd_soc_dapm_new_widgets(&codec->dapm);
-
- /* machine controls, routes and widgets are not prefixed */
- temp = codec->name_prefix;
- codec->name_prefix = NULL;
-
- /* do machine specific initialization */
- if (!dailess && dai_link->init)
- ret = dai_link->init(rtd);
- else if (dailess && aux_dev->init)
- ret = aux_dev->init(&codec->dapm);
- if (ret < 0) {
- dev_err(card->dev, "asoc: failed to init %s: %d\n", name, ret);
- return ret;
- }
- codec->name_prefix = temp;
-
- /* register the rtd device */
- rtd->codec = codec;
-
- rtd->dev = kzalloc(sizeof(struct device), GFP_KERNEL);
- if (!rtd->dev)
- return -ENOMEM;
- device_initialize(rtd->dev);
- rtd->dev->parent = card->dev;
- rtd->dev->release = rtd_release;
- rtd->dev->init_name = name;
- dev_set_drvdata(rtd->dev, rtd);
- mutex_init(&rtd->pcm_mutex);
- ret = device_add(rtd->dev);
- if (ret < 0) {
- dev_err(card->dev,
- "asoc: failed to register runtime device: %d\n", ret);
- return ret;
- }
- rtd->dev_registered = 1;
-
- /* add DAPM sysfs entries for this codec */
- ret = snd_soc_dapm_sys_add(rtd->dev);
- if (ret < 0)
- dev_err(codec->dev,
- "asoc: failed to add codec dapm sysfs entries: %d\n",
- ret);
-
- /* add codec sysfs entries */
- ret = device_create_file(rtd->dev, &dev_attr_codec_reg);
- if (ret < 0)
- dev_err(codec->dev,
- "asoc: failed to add codec sysfs files: %d\n", ret);
-
- return 0;
-}
-
-static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
-{
- struct snd_soc_dai_link *dai_link = &card->dai_link[num];
- struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_platform *platform = rtd->platform;
- struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai;
- int ret;
-
- dev_dbg(card->dev, "probe %s dai link %d late %d\n",
- card->name, num, order);
-
- /* config components */
- codec_dai->codec = codec;
- cpu_dai->platform = platform;
- codec_dai->card = card;
- cpu_dai->card = card;
-
- /* set default power off timeout */
- rtd->pmdown_time = pmdown_time;
-
- /* probe the cpu_dai */
- if (!cpu_dai->probed &&
- cpu_dai->driver->probe_order == order) {
- if (!try_module_get(cpu_dai->dev->driver->owner))
- return -ENODEV;
-
- if (cpu_dai->driver->probe) {
- ret = cpu_dai->driver->probe(cpu_dai);
- if (ret < 0) {
- pr_err("asoc: failed to probe CPU DAI %s: %d\n",
- cpu_dai->name, ret);
- module_put(cpu_dai->dev->driver->owner);
- return ret;
- }
- }
- cpu_dai->probed = 1;
- /* mark cpu_dai as probed and add to card dai list */
- list_add(&cpu_dai->card_list, &card->dai_dev_list);
- }
-
- /* probe the CODEC */
- if (!codec->probed &&
- codec->driver->probe_order == order) {
- ret = soc_probe_codec(card, codec);
- if (ret < 0)
- return ret;
- }
-
- /* probe the platform */
- if (!platform->probed &&
- platform->driver->probe_order == order) {
- ret = soc_probe_platform(card, platform);
- if (ret < 0)
- return ret;
- }
-
- /* probe the CODEC DAI */
- if (!codec_dai->probed && codec_dai->driver->probe_order == order) {
- if (codec_dai->driver->probe) {
- ret = codec_dai->driver->probe(codec_dai);
- if (ret < 0) {
- pr_err("asoc: failed to probe CODEC DAI %s: %d\n",
- codec_dai->name, ret);
- return ret;
- }
- }
-
- /* mark codec_dai as probed and add to card dai list */
- codec_dai->probed = 1;
- list_add(&codec_dai->card_list, &card->dai_dev_list);
- }
-
- /* complete DAI probe during last probe */
- if (order != SND_SOC_COMP_ORDER_LAST)
- return 0;
-
- ret = soc_post_component_init(card, codec, num, 0);
- if (ret)
- return ret;
-
- ret = device_create_file(rtd->dev, &dev_attr_pmdown_time);
- if (ret < 0)
- pr_warn("asoc: failed to add pmdown_time sysfs:%d\n", ret);
-
- /* create the pcm */
- ret = soc_new_pcm(rtd, num);
- if (ret < 0) {
- pr_err("asoc: can't create pcm %s :%d\n",
- dai_link->stream_name, ret);
- return ret;
- }
-
- /* add platform data for AC97 devices */
- if (rtd->codec_dai->driver->ac97_control)
- snd_ac97_dev_add_pdata(codec->ac97, rtd->cpu_dai->ac97_pdata);
-
- return 0;
-}
-
-#ifdef CONFIG_SND_SOC_AC97_BUS
-static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd)
-{
- int ret;
-
- /* Only instantiate AC97 if not already done by the adaptor
- * for the generic AC97 subsystem.
- */
- if (rtd->codec_dai->driver->ac97_control && !rtd->codec->ac97_registered) {
- /*
- * It is possible that the AC97 device is already registered to
- * the device subsystem. This happens when the device is created
- * via snd_ac97_mixer(). Currently only SoC codec that does so
- * is the generic AC97 glue but others migh emerge.
- *
- * In those cases we don't try to register the device again.
- */
- if (!rtd->codec->ac97_created)
- return 0;
-
- ret = soc_ac97_dev_register(rtd->codec);
- if (ret < 0) {
- pr_err("asoc: AC97 device register failed:%d\n", ret);
- return ret;
- }
-
- rtd->codec->ac97_registered = 1;
- }
- return 0;
-}
-
-static void soc_unregister_ac97_dai_link(struct snd_soc_codec *codec)
-{
- if (codec->ac97_registered) {
- soc_ac97_dev_unregister(codec);
- codec->ac97_registered = 0;
- }
-}
-#endif
-
-static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
-{
- struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
- struct snd_soc_codec *codec;
- int ret = -ENODEV;
-
- /* find CODEC from registered CODECs*/
- list_for_each_entry(codec, &codec_list, list) {
- if (!strcmp(codec->name, aux_dev->codec_name)) {
- if (codec->probed) {
- dev_err(codec->dev,
- "asoc: codec already probed");
- ret = -EBUSY;
- goto out;
- }
- goto found;
- }
- }
- /* codec not found */
- dev_err(card->dev, "asoc: codec %s not found", aux_dev->codec_name);
- goto out;
-
-found:
- ret = soc_probe_codec(card, codec);
- if (ret < 0)
- return ret;
-
- ret = soc_post_component_init(card, codec, num, 1);
-
-out:
- return ret;
-}
-
-static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
-{
- struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
- struct snd_soc_codec *codec = rtd->codec;
-
- /* unregister the rtd device */
- if (rtd->dev_registered) {
- device_remove_file(rtd->dev, &dev_attr_codec_reg);
- device_del(rtd->dev);
- rtd->dev_registered = 0;
- }
-
- if (codec && codec->probed)
- soc_remove_codec(codec);
-}
-
-static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,
- enum snd_soc_compress_type compress_type)
-{
- int ret;
-
- if (codec->cache_init)
- return 0;
-
- /* override the compress_type if necessary */
- if (compress_type && codec->compress_type != compress_type)
- codec->compress_type = compress_type;
- ret = snd_soc_cache_init(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache compression type: %d\n",
- ret);
- return ret;
- }
- codec->cache_init = 1;
- return 0;
-}
-
-static void snd_soc_instantiate_card(struct snd_soc_card *card)
-{
- struct snd_soc_codec *codec;
- struct snd_soc_codec_conf *codec_conf;
- enum snd_soc_compress_type compress_type;
- struct snd_soc_dai_link *dai_link;
- int ret, i, order;
-
- mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT);
-
- if (card->instantiated) {
- mutex_unlock(&card->mutex);
- return;
- }
-
- /* bind DAIs */
- for (i = 0; i < card->num_links; i++)
- soc_bind_dai_link(card, i);
-
- /* bind completed ? */
- if (card->num_rtd != card->num_links) {
- mutex_unlock(&card->mutex);
- return;
- }
-
- /* initialize the register cache for each available codec */
- list_for_each_entry(codec, &codec_list, list) {
- if (codec->cache_init)
- continue;
- /* by default we don't override the compress_type */
- compress_type = 0;
- /* check to see if we need to override the compress_type */
- for (i = 0; i < card->num_configs; ++i) {
- codec_conf = &card->codec_conf[i];
- if (!strcmp(codec->name, codec_conf->dev_name)) {
- compress_type = codec_conf->compress_type;
- if (compress_type && compress_type
- != codec->compress_type)
- break;
- }
- }
- ret = snd_soc_init_codec_cache(codec, compress_type);
- if (ret < 0) {
- mutex_unlock(&card->mutex);
- return;
- }
- }
-
- /* card bind complete so register a sound card */
- ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
- card->owner, 0, &card->snd_card);
- if (ret < 0) {
- pr_err("asoc: can't create sound card for card %s: %d\n",
- card->name, ret);
- mutex_unlock(&card->mutex);
- return;
- }
- card->snd_card->dev = card->dev;
-
- card->dapm.bias_level = SND_SOC_BIAS_OFF;
- card->dapm.dev = card->dev;
- card->dapm.card = card;
- list_add(&card->dapm.list, &card->dapm_list);
-
-#ifdef CONFIG_DEBUG_FS
- snd_soc_dapm_debugfs_init(&card->dapm, card->debugfs_card_root);
-#endif
-
-#ifdef CONFIG_PM_SLEEP
- /* deferred resume work */
- INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
-#endif
-
- if (card->dapm_widgets)
- snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets,
- card->num_dapm_widgets);
-
- /* initialise the sound card only once */
- if (card->probe) {
- ret = card->probe(card);
- if (ret < 0)
- goto card_probe_error;
- }
-
- /* early DAI link probe */
- for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
- order++) {
- for (i = 0; i < card->num_links; i++) {
- ret = soc_probe_dai_link(card, i, order);
- if (ret < 0) {
- pr_err("asoc: failed to instantiate card %s: %d\n",
- card->name, ret);
- goto probe_dai_err;
- }
- }
- }
-
- for (i = 0; i < card->num_aux_devs; i++) {
- ret = soc_probe_aux_dev(card, i);
- if (ret < 0) {
- pr_err("asoc: failed to add auxiliary devices %s: %d\n",
- card->name, ret);
- goto probe_aux_dev_err;
- }
- }
-
- snd_soc_dapm_link_dai_widgets(card);
-
- if (card->controls)
- snd_soc_add_card_controls(card, card->controls, card->num_controls);
-
- if (card->dapm_routes)
- snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,
- card->num_dapm_routes);
-
- snd_soc_dapm_new_widgets(&card->dapm);
-
- for (i = 0; i < card->num_links; i++) {
- dai_link = &card->dai_link[i];
-
- if (dai_link->dai_fmt) {
- ret = snd_soc_dai_set_fmt(card->rtd[i].codec_dai,
- dai_link->dai_fmt);
- if (ret != 0 && ret != -ENOTSUPP)
- dev_warn(card->rtd[i].codec_dai->dev,
- "Failed to set DAI format: %d\n",
- ret);
-
- ret = snd_soc_dai_set_fmt(card->rtd[i].cpu_dai,
- dai_link->dai_fmt);
- if (ret != 0 && ret != -ENOTSUPP)
- dev_warn(card->rtd[i].cpu_dai->dev,
- "Failed to set DAI format: %d\n",
- ret);
- }
- }
-
- snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
- "%s", card->name);
- snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
- "%s", card->long_name ? card->long_name : card->name);
- snprintf(card->snd_card->driver, sizeof(card->snd_card->driver),
- "%s", card->driver_name ? card->driver_name : card->name);
- for (i = 0; i < ARRAY_SIZE(card->snd_card->driver); i++) {
- switch (card->snd_card->driver[i]) {
- case '_':
- case '-':
- case '\0':
- break;
- default:
- if (!isalnum(card->snd_card->driver[i]))
- card->snd_card->driver[i] = '_';
- break;
- }
- }
-
- if (card->late_probe) {
- ret = card->late_probe(card);
- if (ret < 0) {
- dev_err(card->dev, "%s late_probe() failed: %d\n",
- card->name, ret);
- goto probe_aux_dev_err;
- }
- }
-
- snd_soc_dapm_new_widgets(&card->dapm);
-
- if (card->fully_routed)
- list_for_each_entry(codec, &card->codec_dev_list, card_list)
- snd_soc_dapm_auto_nc_codec_pins(codec);
-
- ret = snd_card_register(card->snd_card);
- if (ret < 0) {
- pr_err("asoc: failed to register soundcard for %s: %d\n",
- card->name, ret);
- goto probe_aux_dev_err;
- }
-
-#ifdef CONFIG_SND_SOC_AC97_BUS
- /* register any AC97 codecs */
- for (i = 0; i < card->num_rtd; i++) {
- ret = soc_register_ac97_dai_link(&card->rtd[i]);
- if (ret < 0) {
- pr_err("asoc: failed to register AC97 %s: %d\n",
- card->name, ret);
- while (--i >= 0)
- soc_unregister_ac97_dai_link(card->rtd[i].codec);
- goto probe_aux_dev_err;
- }
- }
-#endif
-
- card->instantiated = 1;
- snd_soc_dapm_sync(&card->dapm);
- mutex_unlock(&card->mutex);
- return;
-
-probe_aux_dev_err:
- for (i = 0; i < card->num_aux_devs; i++)
- soc_remove_aux_dev(card, i);
-
-probe_dai_err:
- soc_remove_dai_links(card);
-
-card_probe_error:
- if (card->remove)
- card->remove(card);
-
- snd_card_free(card->snd_card);
-
- mutex_unlock(&card->mutex);
-}
-
-/*
- * Attempt to initialise any uninitialised cards. Must be called with
- * client_mutex.
- */
-static void snd_soc_instantiate_cards(void)
-{
- struct snd_soc_card *card;
- list_for_each_entry(card, &card_list, list)
- snd_soc_instantiate_card(card);
-}
-
-/* probes a new socdev */
-static int soc_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
- int ret = 0;
-
- /*
- * no card, so machine driver should be registering card
- * we should not be here in that case so ret error
- */
- if (!card)
- return -EINVAL;
-
- dev_warn(&pdev->dev,
- "ASoC machine %s should use snd_soc_register_card()\n",
- card->name);
-
- /* Bodge while we unpick instantiation */
- card->dev = &pdev->dev;
-
- ret = snd_soc_register_card(card);
- if (ret != 0) {
- dev_err(&pdev->dev, "Failed to register card\n");
- return ret;
- }
-
- return 0;
-}
-
-static int soc_cleanup_card_resources(struct snd_soc_card *card)
-{
- int i;
-
- /* make sure any delayed work runs */
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
- flush_delayed_work_sync(&rtd->delayed_work);
- }
-
- /* remove auxiliary devices */
- for (i = 0; i < card->num_aux_devs; i++)
- soc_remove_aux_dev(card, i);
-
- /* remove and free each DAI */
- soc_remove_dai_links(card);
-
- soc_cleanup_card_debugfs(card);
-
- /* remove the card */
- if (card->remove)
- card->remove(card);
-
- snd_soc_dapm_free(&card->dapm);
-
- snd_card_free(card->snd_card);
- return 0;
-
-}
-
-/* removes a socdev */
-static int soc_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
- snd_soc_unregister_card(card);
- return 0;
-}
-
-int snd_soc_poweroff(struct device *dev)
-{
- struct snd_soc_card *card = dev_get_drvdata(dev);
- int i;
-
- if (!card->instantiated)
- return 0;
-
- /* Flush out pmdown_time work - we actually do want to run it
- * now, we're shutting down so no imminent restart. */
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
- flush_delayed_work_sync(&rtd->delayed_work);
- }
-
- snd_soc_dapm_shutdown(card);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_poweroff);
-
-const struct dev_pm_ops snd_soc_pm_ops = {
- .suspend = snd_soc_suspend, //PMSG_SUSPEND
- .resume = snd_soc_resume, //
- .freeze = snd_soc_suspend, //PMSG_FREEZE
- .thaw = snd_soc_resume, //
- .poweroff = snd_soc_poweroff, //PMSG_HIBERNATE
- .restore = snd_soc_resume, //
-};
-EXPORT_SYMBOL_GPL(snd_soc_pm_ops);
-
-/*****add for std 2014-3-24*************/
-
-/* powers down audio subsystem for suspend */
-static int soc_suspend(struct platform_device *dev, pm_message_t state)
-{
- struct snd_soc_card *card = platform_get_drvdata(dev);
- struct snd_soc_codec *codec;
- int i;
- printk("<<<<<<<<%s, pm state: 0x%x\n", __func__, state.event);
-
- /* If the initialization of this soc device failed, there is no codec
- * associated with it. Just bail out in this case.
- */
- if (list_empty(&card->codec_dev_list))
- return 0;
-
-#if 0
- mutex_lock(&std_pm_mutex);
- if (std_dev_suspend)
- {
- mutex_unlock(&std_pm_mutex);
- return 0;
- }
- std_pdev_suspend = 1;
- mutex_unlock(&std_pm_mutex);
-
- if (std_pdev_suspend)
- return 0;
-
- std_pdev_suspend = 1;
-#endif
- /* Due to the resume being scheduled into a workqueue we could
- * suspend before that's finished - wait for it to complete.
- */
-
- if (state.event==PM_EVENT_SUSPEND/*0x2*/ || state.event==PM_EVENT_FREEZE/*0x1*/){ //move from device_driver pm
- snd_power_lock(card->snd_card);
- snd_power_wait(card->snd_card, SNDRV_CTL_POWER_D0);
- snd_power_unlock(card->snd_card);
-
- /* we're going to block userspace touching us until resume completes */
- snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot);
-
- /* mute any active DACs */
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_dai *dai = card->rtd[i].codec_dai;
- struct snd_soc_dai_driver *drv = dai->driver;
-
- if (card->rtd[i].dai_link->ignore_suspend)
- continue;
-
- if (drv->ops->digital_mute && dai->playback_active)
- drv->ops->digital_mute(dai, 1);
- }
-
- /* suspend all pcms */
- for (i = 0; i < card->num_rtd; i++) {
- if (card->rtd[i].dai_link->ignore_suspend)
- continue;
-
- snd_pcm_suspend_all(card->rtd[i].pcm);
- }
-
- if (card->suspend_pre)
- card->suspend_pre(card);
-
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
- struct snd_soc_platform *platform = card->rtd[i].platform;
-
- if (card->rtd[i].dai_link->ignore_suspend)
- continue;
-
- if (cpu_dai->driver->suspend && !cpu_dai->driver->ac97_control)
- cpu_dai->driver->suspend(cpu_dai);
- if (platform->driver->suspend && !platform->suspended) {
- platform->driver->suspend(cpu_dai);
- platform->suspended = 1;
- }
- }
-
- /* close any waiting streams and save state */
- for (i = 0; i < card->num_rtd; i++) {
- flush_delayed_work_sync(&card->rtd[i].delayed_work);
- card->rtd[i].codec->dapm.suspend_bias_level = card->rtd[i].codec->dapm.bias_level;
- }
-
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_dai *codec_dai = card->rtd[i].codec_dai;
-
- if (card->rtd[i].dai_link->ignore_suspend)
- continue;
-
- snd_soc_dapm_stream_event(&card->rtd[i],
- SNDRV_PCM_STREAM_PLAYBACK,
- codec_dai,
- SND_SOC_DAPM_STREAM_SUSPEND);
-
- snd_soc_dapm_stream_event(&card->rtd[i],
- SNDRV_PCM_STREAM_CAPTURE,
- codec_dai,
- SND_SOC_DAPM_STREAM_SUSPEND);
- }
-
- /* suspend all CODECs */
- list_for_each_entry(codec, &card->codec_dev_list, card_list) {
- /* If there are paths active then the CODEC will be held with
- * bias _ON and should not be suspended. */
- if (!codec->suspended && codec->driver->suspend) {
- switch (codec->dapm.bias_level) {
- case SND_SOC_BIAS_STANDBY:
- /*
- * If the CODEC is capable of idle
- * bias off then being in STANDBY
- * means it's doing something,
- * otherwise fall through.
- */
- if (codec->dapm.idle_bias_off) {
- dev_dbg(codec->dev,
- "idle_bias_off CODEC on over suspend\n");
- break;
- }
- case SND_SOC_BIAS_OFF:
- codec->driver->suspend(codec);
- codec->suspended = 1;
- codec->cache_sync = 1;
- break;
- default:
- dev_dbg(codec->dev, "CODEC is on over suspend\n");
- break;
- }
- }
- }
-
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
-
- if (card->rtd[i].dai_link->ignore_suspend)
- continue;
-
- if (cpu_dai->driver->suspend && cpu_dai->driver->ac97_control)
- cpu_dai->driver->suspend(cpu_dai);
- }
-
- if (card->suspend_post)
- card->suspend_post(card);
-
- return 0;
- }
-
- if (state.event == PM_EVENT_HIBERNATE) { // 0x4
-
- /* Flush out pmdown_time work - we actually do want to run it
- * now, we're shutting down so no imminent restart. */
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
- flush_delayed_work_sync(&rtd->delayed_work);
- }
-
- snd_soc_dapm_shutdown(card);
-
- return 0;
-
- }
-
- return 0;
-}
-
-/* powers up audio subsystem after a suspend */
-int soc_resume(struct platform_device *dev)
-{
- struct snd_soc_card *card = platform_get_drvdata(dev);
- int i, ac97_control = 0;
-
- printk("<<<<<%s\n", __func__);
-
-#if 0
- if (std_pdev_suspend)
- std_pdev_suspend = 0;
- else
- return 0;
-#endif
- /* If the initialization of this soc device failed, there is no codec
- * associated with it. Just bail out in this case.
- */
- if (list_empty(&card->codec_dev_list))
- return 0;
-#if 0
- mutex_lock(&std_pm_mutex);
- if (std_dev_suspend)
- {
- mutex_unlock(&std_pm_mutex);
- return 0;
- }
- std_pdev_suspend = 0;
- mutex_unlock(&std_pm_mutex);
-#endif
-
- /* AC97 devices might have other drivers hanging off them so
- * need to resume immediately. Other drivers don't have that
- * problem and may take a substantial amount of time to resume
- * due to I/O costs and anti-pop so handle them out of line.
- */
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
- ac97_control |= cpu_dai->driver->ac97_control;
- }
- if (ac97_control) {
- dev_dbg(dev, "Resuming AC97 immediately\n");
- soc_resume_deferred(&card->deferred_resume_work);
- } else {
- dev_dbg(dev, "Scheduling resume work\n");
- if (!schedule_work(&card->deferred_resume_work))
- dev_err(dev, "resume work item may be lost\n");
- }
-
- return 0;
-}
-
-/*********************************************/
-
-/* ASoC platform driver */
-static struct platform_driver soc_driver = {
- .driver = {
- .name = "soc-audio",
- .owner = THIS_MODULE,
- //.pm = &snd_soc_pm_ops,
- },
- .probe = soc_probe,
- .remove = soc_remove,
- .suspend = soc_suspend,
- .resume = soc_resume,
-};
-
-/**
- * snd_soc_codec_volatile_register: Report if a register is volatile.
- *
- * @codec: CODEC to query.
- * @reg: Register to query.
- *
- * Boolean function indiciating if a CODEC register is volatile.
- */
-int snd_soc_codec_volatile_register(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- if (codec->volatile_register)
- return codec->volatile_register(codec, reg);
- else
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register);
-
-/**
- * snd_soc_codec_readable_register: Report if a register is readable.
- *
- * @codec: CODEC to query.
- * @reg: Register to query.
- *
- * Boolean function indicating if a CODEC register is readable.
- */
-int snd_soc_codec_readable_register(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- if (codec->readable_register)
- return codec->readable_register(codec, reg);
- else
- return 1;
-}
-EXPORT_SYMBOL_GPL(snd_soc_codec_readable_register);
-
-/**
- * snd_soc_codec_writable_register: Report if a register is writable.
- *
- * @codec: CODEC to query.
- * @reg: Register to query.
- *
- * Boolean function indicating if a CODEC register is writable.
- */
-int snd_soc_codec_writable_register(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- if (codec->writable_register)
- return codec->writable_register(codec, reg);
- else
- return 1;
-}
-EXPORT_SYMBOL_GPL(snd_soc_codec_writable_register);
-
-int snd_soc_platform_read(struct snd_soc_platform *platform,
- unsigned int reg)
-{
- unsigned int ret;
-
- if (!platform->driver->read) {
- dev_err(platform->dev, "platform has no read back\n");
- return -1;
- }
-
- ret = platform->driver->read(platform, reg);
- dev_dbg(platform->dev, "read %x => %x\n", reg, ret);
- trace_snd_soc_preg_read(platform, reg, ret);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(snd_soc_platform_read);
-
-int snd_soc_platform_write(struct snd_soc_platform *platform,
- unsigned int reg, unsigned int val)
-{
- if (!platform->driver->write) {
- dev_err(platform->dev, "platform has no write back\n");
- return -1;
- }
-
- dev_dbg(platform->dev, "write %x = %x\n", reg, val);
- trace_snd_soc_preg_write(platform, reg, val);
- return platform->driver->write(platform, reg, val);
-}
-EXPORT_SYMBOL_GPL(snd_soc_platform_write);
-
-/**
- * snd_soc_new_ac97_codec - initailise AC97 device
- * @codec: audio codec
- * @ops: AC97 bus operations
- * @num: AC97 codec number
- *
- * Initialises AC97 codec resources for use by ad-hoc devices only.
- */
-int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
- struct snd_ac97_bus_ops *ops, int num)
-{
- mutex_lock(&codec->mutex);
-
- codec->ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL);
- if (codec->ac97 == NULL) {
- mutex_unlock(&codec->mutex);
- return -ENOMEM;
- }
-
- codec->ac97->bus = kzalloc(sizeof(struct snd_ac97_bus), GFP_KERNEL);
- if (codec->ac97->bus == NULL) {
- kfree(codec->ac97);
- codec->ac97 = NULL;
- mutex_unlock(&codec->mutex);
- return -ENOMEM;
- }
-
- codec->ac97->bus->ops = ops;
- codec->ac97->num = num;
-
- /*
- * Mark the AC97 device to be created by us. This way we ensure that the
- * device will be registered with the device subsystem later on.
- */
- codec->ac97_created = 1;
-
- mutex_unlock(&codec->mutex);
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
-
-/**
- * snd_soc_free_ac97_codec - free AC97 codec device
- * @codec: audio codec
- *
- * Frees AC97 codec device resources.
- */
-void snd_soc_free_ac97_codec(struct snd_soc_codec *codec)
-{
- mutex_lock(&codec->mutex);
-#ifdef CONFIG_SND_SOC_AC97_BUS
- soc_unregister_ac97_dai_link(codec);
-#endif
- kfree(codec->ac97->bus);
- kfree(codec->ac97);
- codec->ac97 = NULL;
- codec->ac97_created = 0;
- mutex_unlock(&codec->mutex);
-}
-EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec);
-
-unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg)
-{
- unsigned int ret;
-
- ret = codec->read(codec, reg);
- dev_dbg(codec->dev, "read %x => %x\n", reg, ret);
- trace_snd_soc_reg_read(codec, reg, ret);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(snd_soc_read);
-
-unsigned int snd_soc_write(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int val)
-{
- dev_dbg(codec->dev, "write %x = %x\n", reg, val);
- trace_snd_soc_reg_write(codec, reg, val);
- return codec->write(codec, reg, val);
-}
-EXPORT_SYMBOL_GPL(snd_soc_write);
-
-unsigned int snd_soc_bulk_write_raw(struct snd_soc_codec *codec,
- unsigned int reg, const void *data, size_t len)
-{
- return codec->bulk_write_raw(codec, reg, data, len);
-}
-EXPORT_SYMBOL_GPL(snd_soc_bulk_write_raw);
-
-/**
- * snd_soc_update_bits - update codec register bits
- * @codec: audio codec
- * @reg: codec register
- * @mask: register mask
- * @value: new value
- *
- * Writes new register value.
- *
- * Returns 1 for change, 0 for no change, or negative error code.
- */
-int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
- unsigned int mask, unsigned int value)
-{
- bool change;
- unsigned int old, new;
- int ret;
-
- if (codec->using_regmap) {
- ret = regmap_update_bits_check(codec->control_data, reg,
- mask, value, &change);
- } else {
- ret = snd_soc_read(codec, reg);
- if (ret < 0)
- return ret;
-
- old = ret;
- new = (old & ~mask) | (value & mask);
- change = old != new;
- if (change)
- ret = snd_soc_write(codec, reg, new);
- }
-
- if (ret < 0)
- return ret;
-
- return change;
-}
-EXPORT_SYMBOL_GPL(snd_soc_update_bits);
-
-/**
- * snd_soc_update_bits_locked - update codec register bits
- * @codec: audio codec
- * @reg: codec register
- * @mask: register mask
- * @value: new value
- *
- * Writes new register value, and takes the codec mutex.
- *
- * Returns 1 for change else 0.
- */
-int snd_soc_update_bits_locked(struct snd_soc_codec *codec,
- unsigned short reg, unsigned int mask,
- unsigned int value)
-{
- int change;
-
- mutex_lock(&codec->mutex);
- change = snd_soc_update_bits(codec, reg, mask, value);
- mutex_unlock(&codec->mutex);
-
- return change;
-}
-EXPORT_SYMBOL_GPL(snd_soc_update_bits_locked);
-
-/**
- * snd_soc_test_bits - test register for change
- * @codec: audio codec
- * @reg: codec register
- * @mask: register mask
- * @value: new value
- *
- * Tests a register with a new value and checks if the new value is
- * different from the old value.
- *
- * Returns 1 for change else 0.
- */
-int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
- unsigned int mask, unsigned int value)
-{
- int change;
- unsigned int old, new;
-
- old = snd_soc_read(codec, reg);
- new = (old & ~mask) | value;
- change = old != new;
-
- return change;
-}
-EXPORT_SYMBOL_GPL(snd_soc_test_bits);
-
-/**
- * snd_soc_set_runtime_hwparams - set the runtime hardware parameters
- * @substream: the pcm substream
- * @hw: the hardware parameters
- *
- * Sets the substream runtime hardware parameters.
- */
-int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
- const struct snd_pcm_hardware *hw)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- runtime->hw.info = hw->info;
- runtime->hw.formats = hw->formats;
- runtime->hw.period_bytes_min = hw->period_bytes_min;
- runtime->hw.period_bytes_max = hw->period_bytes_max;
- runtime->hw.periods_min = hw->periods_min;
- runtime->hw.periods_max = hw->periods_max;
- runtime->hw.buffer_bytes_max = hw->buffer_bytes_max;
- runtime->hw.fifo_size = hw->fifo_size;
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);
-
-/**
- * snd_soc_cnew - create new control
- * @_template: control template
- * @data: control private data
- * @long_name: control long name
- * @prefix: control name prefix
- *
- * Create a new mixer control from a template control.
- *
- * Returns 0 for success, else error.
- */
-struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
- void *data, const char *long_name,
- const char *prefix)
-{
- struct snd_kcontrol_new template;
- struct snd_kcontrol *kcontrol;
- char *name = NULL;
- int name_len;
-
- memcpy(&template, _template, sizeof(template));
- template.index = 0;
-
- if (!long_name)
- long_name = template.name;
-
- if (prefix) {
- name_len = strlen(long_name) + strlen(prefix) + 2;
- name = kmalloc(name_len, GFP_KERNEL);
- if (!name)
- return NULL;
-
- snprintf(name, name_len, "%s %s", prefix, long_name);
-
- template.name = name;
- } else {
- template.name = long_name;
- }
-
- kcontrol = snd_ctl_new1(&template, data);
-
- kfree(name);
-
- return kcontrol;
-}
-EXPORT_SYMBOL_GPL(snd_soc_cnew);
-
-static int snd_soc_add_controls(struct snd_card *card, struct device *dev,
- const struct snd_kcontrol_new *controls, int num_controls,
- const char *prefix, void *data)
-{
- int err, i;
-
- for (i = 0; i < num_controls; i++) {
- const struct snd_kcontrol_new *control = &controls[i];
- err = snd_ctl_add(card, snd_soc_cnew(control, data,
- control->name, prefix));
- if (err < 0) {
- dev_err(dev, "Failed to add %s: %d\n", control->name, err);
- return err;
- }
- }
-
- return 0;
-}
-
-/**
- * snd_soc_add_codec_controls - add an array of controls to a codec.
- * Convenience function to add a list of controls. Many codecs were
- * duplicating this code.
- *
- * @codec: codec to add controls to
- * @controls: array of controls to add
- * @num_controls: number of elements in the array
- *
- * Return 0 for success, else error.
- */
-int snd_soc_add_codec_controls(struct snd_soc_codec *codec,
- const struct snd_kcontrol_new *controls, int num_controls)
-{
- struct snd_card *card = codec->card->snd_card;
-
- return snd_soc_add_controls(card, codec->dev, controls, num_controls,
- codec->name_prefix, codec);
-}
-EXPORT_SYMBOL_GPL(snd_soc_add_codec_controls);
-
-/**
- * snd_soc_add_platform_controls - add an array of controls to a platform.
- * Convenience function to add a list of controls.
- *
- * @platform: platform to add controls to
- * @controls: array of controls to add
- * @num_controls: number of elements in the array
- *
- * Return 0 for success, else error.
- */
-int snd_soc_add_platform_controls(struct snd_soc_platform *platform,
- const struct snd_kcontrol_new *controls, int num_controls)
-{
- struct snd_card *card = platform->card->snd_card;
-
- return snd_soc_add_controls(card, platform->dev, controls, num_controls,
- NULL, platform);
-}
-EXPORT_SYMBOL_GPL(snd_soc_add_platform_controls);
-
-/**
- * snd_soc_add_card_controls - add an array of controls to a SoC card.
- * Convenience function to add a list of controls.
- *
- * @soc_card: SoC card to add controls to
- * @controls: array of controls to add
- * @num_controls: number of elements in the array
- *
- * Return 0 for success, else error.
- */
-int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
- const struct snd_kcontrol_new *controls, int num_controls)
-{
- struct snd_card *card = soc_card->snd_card;
-
- return snd_soc_add_controls(card, soc_card->dev, controls, num_controls,
- NULL, soc_card);
-}
-EXPORT_SYMBOL_GPL(snd_soc_add_card_controls);
-
-/**
- * snd_soc_add_dai_controls - add an array of controls to a DAI.
- * Convienience function to add a list of controls.
- *
- * @dai: DAI to add controls to
- * @controls: array of controls to add
- * @num_controls: number of elements in the array
- *
- * Return 0 for success, else error.
- */
-int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
- const struct snd_kcontrol_new *controls, int num_controls)
-{
- struct snd_card *card = dai->card->snd_card;
-
- return snd_soc_add_controls(card, dai->dev, controls, num_controls,
- NULL, dai);
-}
-EXPORT_SYMBOL_GPL(snd_soc_add_dai_controls);
-
-/**
- * snd_soc_info_enum_double - enumerated double mixer info callback
- * @kcontrol: mixer control
- * @uinfo: control element information
- *
- * Callback to provide information about a double enumerated
- * mixer control.
- *
- * Returns 0 for success.
- */
-int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = e->shift_l == e->shift_r ? 1 : 2;
- uinfo->value.enumerated.items = e->max;
-
- if (uinfo->value.enumerated.item > e->max - 1)
- uinfo->value.enumerated.item = e->max - 1;
- strcpy(uinfo->value.enumerated.name,
- e->texts[uinfo->value.enumerated.item]);
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_info_enum_double);
-
-/**
- * snd_soc_get_enum_double - enumerated double mixer get callback
- * @kcontrol: mixer control
- * @ucontrol: control element information
- *
- * Callback to get the value of a double enumerated mixer.
- *
- * Returns 0 for success.
- */
-int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int val, bitmask;
-
- for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
- ;
- val = snd_soc_read(codec, e->reg);
- ucontrol->value.enumerated.item[0]
- = (val >> e->shift_l) & (bitmask - 1);
- if (e->shift_l != e->shift_r)
- ucontrol->value.enumerated.item[1] =
- (val >> e->shift_r) & (bitmask - 1);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_get_enum_double);
-
-/**
- * snd_soc_put_enum_double - enumerated double mixer put callback
- * @kcontrol: mixer control
- * @ucontrol: control element information
- *
- * Callback to set the value of a double enumerated mixer.
- *
- * Returns 0 for success.
- */
-int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int val;
- unsigned int mask, bitmask;
-
- for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
- ;
- if (ucontrol->value.enumerated.item[0] > e->max - 1)
- return -EINVAL;
- val = ucontrol->value.enumerated.item[0] << e->shift_l;
- mask = (bitmask - 1) << e->shift_l;
- if (e->shift_l != e->shift_r) {
- if (ucontrol->value.enumerated.item[1] > e->max - 1)
- return -EINVAL;
- val |= ucontrol->value.enumerated.item[1] << e->shift_r;
- mask |= (bitmask - 1) << e->shift_r;
- }
-
- return snd_soc_update_bits_locked(codec, e->reg, mask, val);
-}
-EXPORT_SYMBOL_GPL(snd_soc_put_enum_double);
-
-/**
- * snd_soc_get_value_enum_double - semi enumerated double mixer get callback
- * @kcontrol: mixer control
- * @ucontrol: control element information
- *
- * Callback to get the value of a double semi enumerated mixer.
- *
- * Semi enumerated mixer: the enumerated items are referred as values. Can be
- * used for handling bitfield coded enumeration for example.
- *
- * Returns 0 for success.
- */
-int snd_soc_get_value_enum_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int reg_val, val, mux;
-
- reg_val = snd_soc_read(codec, e->reg);
- val = (reg_val >> e->shift_l) & e->mask;
- for (mux = 0; mux < e->max; mux++) {
- if (val == e->values[mux])
- break;
- }
- ucontrol->value.enumerated.item[0] = mux;
- if (e->shift_l != e->shift_r) {
- val = (reg_val >> e->shift_r) & e->mask;
- for (mux = 0; mux < e->max; mux++) {
- if (val == e->values[mux])
- break;
- }
- ucontrol->value.enumerated.item[1] = mux;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_get_value_enum_double);
-
-/**
- * snd_soc_put_value_enum_double - semi enumerated double mixer put callback
- * @kcontrol: mixer control
- * @ucontrol: control element information
- *
- * Callback to set the value of a double semi enumerated mixer.
- *
- * Semi enumerated mixer: the enumerated items are referred as values. Can be
- * used for handling bitfield coded enumeration for example.
- *
- * Returns 0 for success.
- */
-int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int val;
- unsigned int mask;
-
- if (ucontrol->value.enumerated.item[0] > e->max - 1)
- return -EINVAL;
- val = e->values[ucontrol->value.enumerated.item[0]] << e->shift_l;
- mask = e->mask << e->shift_l;
- if (e->shift_l != e->shift_r) {
- if (ucontrol->value.enumerated.item[1] > e->max - 1)
- return -EINVAL;
- val |= e->values[ucontrol->value.enumerated.item[1]] << e->shift_r;
- mask |= e->mask << e->shift_r;
- }
-
- return snd_soc_update_bits_locked(codec, e->reg, mask, val);
-}
-EXPORT_SYMBOL_GPL(snd_soc_put_value_enum_double);
-
-/**
- * snd_soc_info_enum_ext - external enumerated single mixer info callback
- * @kcontrol: mixer control
- * @uinfo: control element information
- *
- * Callback to provide information about an external enumerated
- * single mixer.
- *
- * Returns 0 for success.
- */
-int snd_soc_info_enum_ext(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = e->max;
-
- if (uinfo->value.enumerated.item > e->max - 1)
- uinfo->value.enumerated.item = e->max - 1;
- strcpy(uinfo->value.enumerated.name,
- e->texts[uinfo->value.enumerated.item]);
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_info_enum_ext);
-
-/**
- * snd_soc_info_volsw_ext - external single mixer info callback
- * @kcontrol: mixer control
- * @uinfo: control element information
- *
- * Callback to provide information about a single external mixer control.
- *
- * Returns 0 for success.
- */
-int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int max = kcontrol->private_value;
-
- if (max == 1 && !strstr(kcontrol->id.name, " Volume"))
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- else
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = max;
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_info_volsw_ext);
-
-/**
- * snd_soc_info_volsw - single mixer info callback
- * @kcontrol: mixer control
- * @uinfo: control element information
- *
- * Callback to provide information about a single mixer control, or a double
- * mixer control that spans 2 registers.
- *
- * Returns 0 for success.
- */
-int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- int platform_max;
-
- if (!mc->platform_max)
- mc->platform_max = mc->max;
- platform_max = mc->platform_max;
-
- if (platform_max == 1 && !strstr(kcontrol->id.name, " Volume"))
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- else
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-
- uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = platform_max;
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_info_volsw);
-
-/**
- * snd_soc_get_volsw - single mixer get callback
- * @kcontrol: mixer control
- * @ucontrol: control element information
- *
- * Callback to get the value of a single mixer control, or a double mixer
- * control that spans 2 registers.
- *
- * Returns 0 for success.
- */
-int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int reg = mc->reg;
- unsigned int reg2 = mc->rreg;
- unsigned int shift = mc->shift;
- unsigned int rshift = mc->rshift;
- int max = mc->max;
- unsigned int mask = (1 << fls(max)) - 1;
- unsigned int invert = mc->invert;
-
- ucontrol->value.integer.value[0] =
- (snd_soc_read(codec, reg) >> shift) & mask;
- if (invert)
- ucontrol->value.integer.value[0] =
- max - ucontrol->value.integer.value[0];
-
- if (snd_soc_volsw_is_stereo(mc)) {
- if (reg == reg2)
- ucontrol->value.integer.value[1] =
- (snd_soc_read(codec, reg) >> rshift) & mask;
- else
- ucontrol->value.integer.value[1] =
- (snd_soc_read(codec, reg2) >> shift) & mask;
- if (invert)
- ucontrol->value.integer.value[1] =
- max - ucontrol->value.integer.value[1];
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_get_volsw);
-
-/**
- * snd_soc_put_volsw - single mixer put callback
- * @kcontrol: mixer control
- * @ucontrol: control element information
- *
- * Callback to set the value of a single mixer control, or a double mixer
- * control that spans 2 registers.
- *
- * Returns 0 for success.
- */
-int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int reg = mc->reg;
- unsigned int reg2 = mc->rreg;
- unsigned int shift = mc->shift;
- unsigned int rshift = mc->rshift;
- int max = mc->max;
- unsigned int mask = (1 << fls(max)) - 1;
- unsigned int invert = mc->invert;
- int err;
- bool type_2r = 0;
- unsigned int val2 = 0;
- unsigned int val, val_mask;
-
- val = (ucontrol->value.integer.value[0] & mask);
- if (invert)
- val = max - val;
- val_mask = mask << shift;
- val = val << shift;
- if (snd_soc_volsw_is_stereo(mc)) {
- val2 = (ucontrol->value.integer.value[1] & mask);
- if (invert)
- val2 = max - val2;
- if (reg == reg2) {
- val_mask |= mask << rshift;
- val |= val2 << rshift;
- } else {
- val2 = val2 << shift;
- type_2r = 1;
- }
- }
- err = snd_soc_update_bits_locked(codec, reg, val_mask, val);
- if (err < 0)
- return err;
-
- if (type_2r)
- err = snd_soc_update_bits_locked(codec, reg2, val_mask, val2);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(snd_soc_put_volsw);
-
-/**
- * snd_soc_info_volsw_s8 - signed mixer info callback
- * @kcontrol: mixer control
- * @uinfo: control element information
- *
- * Callback to provide information about a signed mixer control.
- *
- * Returns 0 for success.
- */
-int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- int platform_max;
- int min = mc->min;
-
- if (!mc->platform_max)
- mc->platform_max = mc->max;
- platform_max = mc->platform_max;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = platform_max - min;
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_info_volsw_s8);
-
-/**
- * snd_soc_get_volsw_s8 - signed mixer get callback
- * @kcontrol: mixer control
- * @ucontrol: control element information
- *
- * Callback to get the value of a signed mixer control.
- *
- * Returns 0 for success.
- */
-int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int reg = mc->reg;
- int min = mc->min;
- int val = snd_soc_read(codec, reg);
-
- ucontrol->value.integer.value[0] =
- ((signed char)(val & 0xff))-min;
- ucontrol->value.integer.value[1] =
- ((signed char)((val >> 8) & 0xff))-min;
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_get_volsw_s8);
-
-/**
- * snd_soc_put_volsw_sgn - signed mixer put callback
- * @kcontrol: mixer control
- * @ucontrol: control element information
- *
- * Callback to set the value of a signed mixer control.
- *
- * Returns 0 for success.
- */
-int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int reg = mc->reg;
- int min = mc->min;
- unsigned int val;
-
- val = (ucontrol->value.integer.value[0]+min) & 0xff;
- val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8;
-
- return snd_soc_update_bits_locked(codec, reg, 0xffff, val);
-}
-EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
-
-/**
- * snd_soc_limit_volume - Set new limit to an existing volume control.
- *
- * @codec: where to look for the control
- * @name: Name of the control
- * @max: new maximum limit
- *
- * Return 0 for success, else error.
- */
-int snd_soc_limit_volume(struct snd_soc_codec *codec,
- const char *name, int max)
-{
- struct snd_card *card = codec->card->snd_card;
- struct snd_kcontrol *kctl;
- struct soc_mixer_control *mc;
- int found = 0;
- int ret = -EINVAL;
-
- /* Sanity check for name and max */
- if (unlikely(!name || max <= 0))
- return -EINVAL;
-
- list_for_each_entry(kctl, &card->controls, list) {
- if (!strncmp(kctl->id.name, name, sizeof(kctl->id.name))) {
- found = 1;
- break;
- }
- }
- if (found) {
- mc = (struct soc_mixer_control *)kctl->private_value;
- if (max <= mc->max) {
- mc->platform_max = max;
- ret = 0;
- }
- }
- return ret;
-}
-EXPORT_SYMBOL_GPL(snd_soc_limit_volume);
-
-/**
- * snd_soc_info_volsw_2r_sx - double with tlv and variable data size
- * mixer info callback
- * @kcontrol: mixer control
- * @uinfo: control element information
- *
- * Returns 0 for success.
- */
-int snd_soc_info_volsw_2r_sx(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- int max = mc->max;
- int min = mc->min;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = max-min;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r_sx);
-
-/**
- * snd_soc_get_volsw_2r_sx - double with tlv and variable data size
- * mixer get callback
- * @kcontrol: mixer control
- * @uinfo: control element information
- *
- * Returns 0 for success.
- */
-int snd_soc_get_volsw_2r_sx(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int mask = (1<<mc->shift)-1;
- int min = mc->min;
- int val = snd_soc_read(codec, mc->reg) & mask;
- int valr = snd_soc_read(codec, mc->rreg) & mask;
-
- ucontrol->value.integer.value[0] = ((val & 0xff)-min) & mask;
- ucontrol->value.integer.value[1] = ((valr & 0xff)-min) & mask;
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_get_volsw_2r_sx);
-
-/**
- * snd_soc_put_volsw_2r_sx - double with tlv and variable data size
- * mixer put callback
- * @kcontrol: mixer control
- * @uinfo: control element information
- *
- * Returns 0 for success.
- */
-int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int mask = (1<<mc->shift)-1;
- int min = mc->min;
- int ret;
- unsigned int val, valr, oval, ovalr;
-
- val = ((ucontrol->value.integer.value[0]+min) & 0xff);
- val &= mask;
- valr = ((ucontrol->value.integer.value[1]+min) & 0xff);
- valr &= mask;
-
- oval = snd_soc_read(codec, mc->reg) & mask;
- ovalr = snd_soc_read(codec, mc->rreg) & mask;
-
- ret = 0;
- if (oval != val) {
- ret = snd_soc_write(codec, mc->reg, val);
- if (ret < 0)
- return ret;
- }
- if (ovalr != valr) {
- ret = snd_soc_write(codec, mc->rreg, valr);
- if (ret < 0)
- return ret;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r_sx);
-
-int snd_soc_bytes_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct soc_bytes *params = (void *)kcontrol->private_value;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
- uinfo->count = params->num_regs * codec->val_bytes;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_bytes_info);
-
-int snd_soc_bytes_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_bytes *params = (void *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- int ret;
-
- if (codec->using_regmap)
- ret = regmap_raw_read(codec->control_data, params->base,
- ucontrol->value.bytes.data,
- params->num_regs * codec->val_bytes);
- else
- ret = -EINVAL;
-
- /* Hide any masked bytes to ensure consistent data reporting */
- if (ret == 0 && params->mask) {
- switch (codec->val_bytes) {
- case 1:
- ucontrol->value.bytes.data[0] &= ~params->mask;
- break;
- case 2:
- ((u16 *)(&ucontrol->value.bytes.data))[0]
- &= ~params->mask;
- break;
- case 4:
- ((u32 *)(&ucontrol->value.bytes.data))[0]
- &= ~params->mask;
- break;
- default:
- return -EINVAL;
- }
- }
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(snd_soc_bytes_get);
-
-int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct soc_bytes *params = (void *)kcontrol->private_value;
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- int ret, len;
- unsigned int val;
- void *data;
-
- if (!codec->using_regmap)
- return -EINVAL;
-
- data = ucontrol->value.bytes.data;
- len = params->num_regs * codec->val_bytes;
-
- /*
- * If we've got a mask then we need to preserve the register
- * bits. We shouldn't modify the incoming data so take a
- * copy.
- */
- if (params->mask) {
- ret = regmap_read(codec->control_data, params->base, &val);
- if (ret != 0)
- return ret;
-
- val &= params->mask;
-
- data = kmemdup(data, len, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- switch (codec->val_bytes) {
- case 1:
- ((u8 *)data)[0] &= ~params->mask;
- ((u8 *)data)[0] |= val;
- break;
- case 2:
- ((u16 *)data)[0] &= cpu_to_be16(~params->mask);
- ((u16 *)data)[0] |= cpu_to_be16(val);
- break;
- case 4:
- ((u32 *)data)[0] &= cpu_to_be32(~params->mask);
- ((u32 *)data)[0] |= cpu_to_be32(val);
- break;
- default:
- return -EINVAL;
- }
- }
-
- ret = regmap_raw_write(codec->control_data, params->base,
- data, len);
-
- if (params->mask)
- kfree(data);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(snd_soc_bytes_put);
-
-/**
- * snd_soc_dai_set_sysclk - configure DAI system or master clock.
- * @dai: DAI
- * @clk_id: DAI specific clock ID
- * @freq: new clock frequency in Hz
- * @dir: new clock direction - input/output.
- *
- * Configures the DAI master (MCLK) or system (SYSCLK) clocking.
- */
-int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
- unsigned int freq, int dir)
-{
- if (dai->driver && dai->driver->ops->set_sysclk)
- return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir);
- else if (dai->codec && dai->codec->driver->set_sysclk)
- return dai->codec->driver->set_sysclk(dai->codec, clk_id, 0,
- freq, dir);
- else
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
-
-/**
- * snd_soc_codec_set_sysclk - configure CODEC system or master clock.
- * @codec: CODEC
- * @clk_id: DAI specific clock ID
- * @source: Source for the clock
- * @freq: new clock frequency in Hz
- * @dir: new clock direction - input/output.
- *
- * Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
- */
-int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
- int source, unsigned int freq, int dir)
-{
- if (codec->driver->set_sysclk)
- return codec->driver->set_sysclk(codec, clk_id, source,
- freq, dir);
- else
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(snd_soc_codec_set_sysclk);
-
-/**
- * snd_soc_dai_set_clkdiv - configure DAI clock dividers.
- * @dai: DAI
- * @div_id: DAI specific clock divider ID
- * @div: new clock divisor.
- *
- * Configures the clock dividers. This is used to derive the best DAI bit and
- * frame clocks from the system or master clock. It's best to set the DAI bit
- * and frame clocks as low as possible to save system power.
- */
-int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
- int div_id, int div)
-{
- if (dai->driver && dai->driver->ops->set_clkdiv)
- return dai->driver->ops->set_clkdiv(dai, div_id, div);
- else
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
-
-/**
- * snd_soc_dai_set_pll - configure DAI PLL.
- * @dai: DAI
- * @pll_id: DAI specific PLL ID
- * @source: DAI specific source for the PLL
- * @freq_in: PLL input clock frequency in Hz
- * @freq_out: requested PLL output clock frequency in Hz
- *
- * Configures and enables PLL to generate output clock based on input clock.
- */
-int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
- unsigned int freq_in, unsigned int freq_out)
-{
- if (dai->driver && dai->driver->ops->set_pll)
- return dai->driver->ops->set_pll(dai, pll_id, source,
- freq_in, freq_out);
- else if (dai->codec && dai->codec->driver->set_pll)
- return dai->codec->driver->set_pll(dai->codec, pll_id, source,
- freq_in, freq_out);
- else
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
-
-/*
- * snd_soc_codec_set_pll - configure codec PLL.
- * @codec: CODEC
- * @pll_id: DAI specific PLL ID
- * @source: DAI specific source for the PLL
- * @freq_in: PLL input clock frequency in Hz
- * @freq_out: requested PLL output clock frequency in Hz
- *
- * Configures and enables PLL to generate output clock based on input clock.
- */
-int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
- unsigned int freq_in, unsigned int freq_out)
-{
- if (codec->driver->set_pll)
- return codec->driver->set_pll(codec, pll_id, source,
- freq_in, freq_out);
- else
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(snd_soc_codec_set_pll);
-
-/**
- * snd_soc_dai_set_fmt - configure DAI hardware audio format.
- * @dai: DAI
- * @fmt: SND_SOC_DAIFMT_ format value.
- *
- * Configures the DAI hardware format and clocking.
- */
-int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- if (dai->driver == NULL)
- return -EINVAL;
- if (dai->driver->ops->set_fmt == NULL)
- return -ENOTSUPP;
- return dai->driver->ops->set_fmt(dai, fmt);
-}
-EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
-
-/**
- * snd_soc_dai_set_tdm_slot - configure DAI TDM.
- * @dai: DAI
- * @tx_mask: bitmask representing active TX slots.
- * @rx_mask: bitmask representing active RX slots.
- * @slots: Number of slots in use.
- * @slot_width: Width in bits for each slot.
- *
- * Configures a DAI for TDM operation. Both mask and slots are codec and DAI
- * specific.
- */
-int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
- unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
-{
- if (dai->driver && dai->driver->ops->set_tdm_slot)
- return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask,
- slots, slot_width);
- else
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
-
-/**
- * snd_soc_dai_set_channel_map - configure DAI audio channel map
- * @dai: DAI
- * @tx_num: how many TX channels
- * @tx_slot: pointer to an array which imply the TX slot number channel
- * 0~num-1 uses
- * @rx_num: how many RX channels
- * @rx_slot: pointer to an array which imply the RX slot number channel
- * 0~num-1 uses
- *
- * configure the relationship between channel number and TDM slot number.
- */
-int snd_soc_dai_set_channel_map(struct snd_soc_dai *dai,
- unsigned int tx_num, unsigned int *tx_slot,
- unsigned int rx_num, unsigned int *rx_slot)
-{
- if (dai->driver && dai->driver->ops->set_channel_map)
- return dai->driver->ops->set_channel_map(dai, tx_num, tx_slot,
- rx_num, rx_slot);
- else
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dai_set_channel_map);
-
-/**
- * snd_soc_dai_set_tristate - configure DAI system or master clock.
- * @dai: DAI
- * @tristate: tristate enable
- *
- * Tristates the DAI so that others can use it.
- */
-int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate)
-{
- if (dai->driver && dai->driver->ops->set_tristate)
- return dai->driver->ops->set_tristate(dai, tristate);
- else
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate);
-
-/**
- * snd_soc_dai_digital_mute - configure DAI system or master clock.
- * @dai: DAI
- * @mute: mute enable
- *
- * Mutes the DAI DAC.
- */
-int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute)
-{
- if (dai->driver && dai->driver->ops->digital_mute)
- return dai->driver->ops->digital_mute(dai, mute);
- else
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
-
-/**
- * snd_soc_register_card - Register a card with the ASoC core
- *
- * @card: Card to register
- *
- */
-int snd_soc_register_card(struct snd_soc_card *card)
-{
- int i;
-
- if (!card->name || !card->dev)
- return -EINVAL;
-
- for (i = 0; i < card->num_links; i++) {
- struct snd_soc_dai_link *link = &card->dai_link[i];
-
- /*
- * Codec must be specified by 1 of name or OF node,
- * not both or neither.
- */
- if (!!link->codec_name == !!link->codec_of_node) {
- dev_err(card->dev,
- "Neither/both codec name/of_node are set for %s\n",
- link->name);
- return -EINVAL;
- }
-
- /*
- * Platform may be specified by either name or OF node, but
- * can be left unspecified, and a dummy platform will be used.
- */
- if (link->platform_name && link->platform_of_node) {
- dev_err(card->dev,
- "Both platform name/of_node are set for %s\n", link->name);
- return -EINVAL;
- }
-
- /*
- * CPU DAI must be specified by 1 of name or OF node,
- * not both or neither.
- */
- if (!!link->cpu_dai_name == !!link->cpu_dai_of_node) {
- dev_err(card->dev,
- "Neither/both cpu_dai name/of_node are set for %s\n",
- link->name);
- return -EINVAL;
- }
- }
-
- dev_set_drvdata(card->dev, card);
-
- snd_soc_initialize_card_lists(card);
-
- soc_init_card_debugfs(card);
-
- card->rtd = devm_kzalloc(card->dev,
- sizeof(struct snd_soc_pcm_runtime) *
- (card->num_links + card->num_aux_devs),
- GFP_KERNEL);
- if (card->rtd == NULL)
- return -ENOMEM;
- card->num_rtd = 0;
- card->rtd_aux = &card->rtd[card->num_links];
-
- for (i = 0; i < card->num_links; i++)
- card->rtd[i].dai_link = &card->dai_link[i];
-
- INIT_LIST_HEAD(&card->list);
- INIT_LIST_HEAD(&card->dapm_dirty);
- card->instantiated = 0;
- mutex_init(&card->mutex);
- mutex_init(&card->dapm_mutex);
-
- mutex_lock(&client_mutex);
- list_add(&card->list, &card_list);
- snd_soc_instantiate_cards();
- mutex_unlock(&client_mutex);
-
- dev_dbg(card->dev, "Registered card '%s'\n", card->name);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_register_card);
-
-/**
- * snd_soc_unregister_card - Unregister a card with the ASoC core
- *
- * @card: Card to unregister
- *
- */
-int snd_soc_unregister_card(struct snd_soc_card *card)
-{
- if (card->instantiated)
- soc_cleanup_card_resources(card);
- mutex_lock(&client_mutex);
- list_del(&card->list);
- mutex_unlock(&client_mutex);
- dev_dbg(card->dev, "Unregistered card '%s'\n", card->name);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_unregister_card);
-
-/*
- * Simplify DAI link configuration by removing ".-1" from device names
- * and sanitizing names.
- */
-static char *fmt_single_name(struct device *dev, int *id)
-{
- char *found, name[NAME_SIZE];
- int id1, id2;
-
- if (dev_name(dev) == NULL)
- return NULL;
-
- strlcpy(name, dev_name(dev), NAME_SIZE);
-
- /* are we a "%s.%d" name (platform and SPI components) */
- found = strstr(name, dev->driver->name);
- if (found) {
- /* get ID */
- if (sscanf(&found[strlen(dev->driver->name)], ".%d", id) == 1) {
-
- /* discard ID from name if ID == -1 */
- if (*id == -1)
- found[strlen(dev->driver->name)] = '\0';
- }
-
- } else {
- /* I2C component devices are named "bus-addr" */
- if (sscanf(name, "%x-%x", &id1, &id2) == 2) {
- char tmp[NAME_SIZE];
-
- /* create unique ID number from I2C addr and bus */
- *id = ((id1 & 0xffff) << 16) + id2;
-
- /* sanitize component name for DAI link creation */
- snprintf(tmp, NAME_SIZE, "%s.%s", dev->driver->name, name);
- strlcpy(name, tmp, NAME_SIZE);
- } else
- *id = 0;
- }
-
- return kstrdup(name, GFP_KERNEL);
-}
-
-/*
- * Simplify DAI link naming for single devices with multiple DAIs by removing
- * any ".-1" and using the DAI name (instead of device name).
- */
-static inline char *fmt_multiple_name(struct device *dev,
- struct snd_soc_dai_driver *dai_drv)
-{
- if (dai_drv->name == NULL) {
- pr_err("asoc: error - multiple DAI %s registered with no name\n",
- dev_name(dev));
- return NULL;
- }
-
- return kstrdup(dai_drv->name, GFP_KERNEL);
-}
-
-/**
- * snd_soc_register_dai - Register a DAI with the ASoC core
- *
- * @dai: DAI to register
- */
-int snd_soc_register_dai(struct device *dev,
- struct snd_soc_dai_driver *dai_drv)
-{
- struct snd_soc_dai *dai;
-
- dev_dbg(dev, "dai register %s\n", dev_name(dev));
-
- dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL);
- if (dai == NULL)
- return -ENOMEM;
-
- /* create DAI component name */
- dai->name = fmt_single_name(dev, &dai->id);
- if (dai->name == NULL) {
- kfree(dai);
- return -ENOMEM;
- }
-
- dai->dev = dev;
- dai->driver = dai_drv;
- if (!dai->driver->ops)
- dai->driver->ops = &null_dai_ops;
-
- mutex_lock(&client_mutex);
- list_add(&dai->list, &dai_list);
- snd_soc_instantiate_cards();
- mutex_unlock(&client_mutex);
-
- pr_debug("Registered DAI '%s'\n", dai->name);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_register_dai);
-
-/**
- * snd_soc_unregister_dai - Unregister a DAI from the ASoC core
- *
- * @dai: DAI to unregister
- */
-void snd_soc_unregister_dai(struct device *dev)
-{
- struct snd_soc_dai *dai;
-
- list_for_each_entry(dai, &dai_list, list) {
- if (dev == dai->dev)
- goto found;
- }
- return;
-
-found:
- mutex_lock(&client_mutex);
- list_del(&dai->list);
- mutex_unlock(&client_mutex);
-
- pr_debug("Unregistered DAI '%s'\n", dai->name);
- kfree(dai->name);
- kfree(dai);
-}
-EXPORT_SYMBOL_GPL(snd_soc_unregister_dai);
-
-/**
- * snd_soc_register_dais - Register multiple DAIs with the ASoC core
- *
- * @dai: Array of DAIs to register
- * @count: Number of DAIs
- */
-int snd_soc_register_dais(struct device *dev,
- struct snd_soc_dai_driver *dai_drv, size_t count)
-{
- struct snd_soc_dai *dai;
- int i, ret = 0;
-
- dev_dbg(dev, "dai register %s #%Zu\n", dev_name(dev), count);
-
- for (i = 0; i < count; i++) {
-
- dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL);
- if (dai == NULL) {
- ret = -ENOMEM;
- goto err;
- }
-
- /* create DAI component name */
- dai->name = fmt_multiple_name(dev, &dai_drv[i]);
- if (dai->name == NULL) {
- kfree(dai);
- ret = -EINVAL;
- goto err;
- }
-
- dai->dev = dev;
- dai->driver = &dai_drv[i];
- if (dai->driver->id)
- dai->id = dai->driver->id;
- else
- dai->id = i;
- if (!dai->driver->ops)
- dai->driver->ops = &null_dai_ops;
-
- mutex_lock(&client_mutex);
- list_add(&dai->list, &dai_list);
- mutex_unlock(&client_mutex);
-
- pr_debug("Registered DAI '%s'\n", dai->name);
- }
-
- mutex_lock(&client_mutex);
- snd_soc_instantiate_cards();
- mutex_unlock(&client_mutex);
- return 0;
-
-err:
- for (i--; i >= 0; i--)
- snd_soc_unregister_dai(dev);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(snd_soc_register_dais);
-
-/**
- * snd_soc_unregister_dais - Unregister multiple DAIs from the ASoC core
- *
- * @dai: Array of DAIs to unregister
- * @count: Number of DAIs
- */
-void snd_soc_unregister_dais(struct device *dev, size_t count)
-{
- int i;
-
- for (i = 0; i < count; i++)
- snd_soc_unregister_dai(dev);
-}
-EXPORT_SYMBOL_GPL(snd_soc_unregister_dais);
-
-/**
- * snd_soc_register_platform - Register a platform with the ASoC core
- *
- * @platform: platform to register
- */
-int snd_soc_register_platform(struct device *dev,
- struct snd_soc_platform_driver *platform_drv)
-{
- struct snd_soc_platform *platform;
-
- dev_dbg(dev, "platform register %s\n", dev_name(dev));
-
- platform = kzalloc(sizeof(struct snd_soc_platform), GFP_KERNEL);
- if (platform == NULL)
- return -ENOMEM;
-
- /* create platform component name */
- platform->name = fmt_single_name(dev, &platform->id);
- if (platform->name == NULL) {
- kfree(platform);
- return -ENOMEM;
- }
-
- platform->dev = dev;
- platform->driver = platform_drv;
- platform->dapm.dev = dev;
- platform->dapm.platform = platform;
- platform->dapm.stream_event = platform_drv->stream_event;
- mutex_init(&platform->mutex);
-
- mutex_lock(&client_mutex);
- list_add(&platform->list, &platform_list);
- snd_soc_instantiate_cards();
- mutex_unlock(&client_mutex);
-
- pr_debug("Registered platform '%s'\n", platform->name);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_register_platform);
-
-/**
- * snd_soc_unregister_platform - Unregister a platform from the ASoC core
- *
- * @platform: platform to unregister
- */
-void snd_soc_unregister_platform(struct device *dev)
-{
- struct snd_soc_platform *platform;
-
- list_for_each_entry(platform, &platform_list, list) {
- if (dev == platform->dev)
- goto found;
- }
- return;
-
-found:
- mutex_lock(&client_mutex);
- list_del(&platform->list);
- mutex_unlock(&client_mutex);
-
- pr_debug("Unregistered platform '%s'\n", platform->name);
- kfree(platform->name);
- kfree(platform);
-}
-EXPORT_SYMBOL_GPL(snd_soc_unregister_platform);
-
-static u64 codec_format_map[] = {
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE,
- SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE,
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE,
- SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_U24_BE,
- SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE,
- SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE,
- SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3BE,
- SNDRV_PCM_FMTBIT_U24_3LE | SNDRV_PCM_FMTBIT_U24_3BE,
- SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE,
- SNDRV_PCM_FMTBIT_U20_3LE | SNDRV_PCM_FMTBIT_U20_3BE,
- SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE,
- SNDRV_PCM_FMTBIT_U18_3LE | SNDRV_PCM_FMTBIT_U18_3BE,
- SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE,
- SNDRV_PCM_FMTBIT_FLOAT64_LE | SNDRV_PCM_FMTBIT_FLOAT64_BE,
- SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE
- | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE,
-};
-
-/* Fix up the DAI formats for endianness: codecs don't actually see
- * the endianness of the data but we're using the CPU format
- * definitions which do need to include endianness so we ensure that
- * codec DAIs always have both big and little endian variants set.
- */
-static void fixup_codec_formats(struct snd_soc_pcm_stream *stream)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(codec_format_map); i++)
- if (stream->formats & codec_format_map[i])
- stream->formats |= codec_format_map[i];
-}
-
-/**
- * snd_soc_register_codec - Register a codec with the ASoC core
- *
- * @codec: codec to register
- */
-int snd_soc_register_codec(struct device *dev,
- const struct snd_soc_codec_driver *codec_drv,
- struct snd_soc_dai_driver *dai_drv,
- int num_dai)
-{
- size_t reg_size;
- struct snd_soc_codec *codec;
- int ret, i;
-
- dev_dbg(dev, "codec register %s\n", dev_name(dev));
-
- codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (codec == NULL)
- return -ENOMEM;
-
- /* create CODEC component name */
- codec->name = fmt_single_name(dev, &codec->id);
- if (codec->name == NULL) {
- kfree(codec);
- return -ENOMEM;
- }
-
- if (codec_drv->compress_type)
- codec->compress_type = codec_drv->compress_type;
- else
- codec->compress_type = SND_SOC_FLAT_COMPRESSION;
-
- codec->write = codec_drv->write;
- codec->read = codec_drv->read;
- codec->volatile_register = codec_drv->volatile_register;
- codec->readable_register = codec_drv->readable_register;
- codec->writable_register = codec_drv->writable_register;
- codec->ignore_pmdown_time = codec_drv->ignore_pmdown_time;
- codec->dapm.bias_level = SND_SOC_BIAS_OFF;
- codec->dapm.dev = dev;
- codec->dapm.codec = codec;
- codec->dapm.seq_notifier = codec_drv->seq_notifier;
- codec->dapm.stream_event = codec_drv->stream_event;
- codec->dev = dev;
- codec->driver = codec_drv;
- codec->num_dai = num_dai;
- mutex_init(&codec->mutex);
-
- /* allocate CODEC register cache */
- if (codec_drv->reg_cache_size && codec_drv->reg_word_size) {
- reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
- codec->reg_size = reg_size;
- /* it is necessary to make a copy of the default register cache
- * because in the case of using a compression type that requires
- * the default register cache to be marked as __devinitconst the
- * kernel might have freed the array by the time we initialize
- * the cache.
- */
- if (codec_drv->reg_cache_default) {
- codec->reg_def_copy = kmemdup(codec_drv->reg_cache_default,
- reg_size, GFP_KERNEL);
- if (!codec->reg_def_copy) {
- ret = -ENOMEM;
- goto fail;
- }
- }
- }
-
- if (codec_drv->reg_access_size && codec_drv->reg_access_default) {
- if (!codec->volatile_register)
- codec->volatile_register = snd_soc_default_volatile_register;
- if (!codec->readable_register)
- codec->readable_register = snd_soc_default_readable_register;
- if (!codec->writable_register)
- codec->writable_register = snd_soc_default_writable_register;
- }
-
- for (i = 0; i < num_dai; i++) {
- fixup_codec_formats(&dai_drv[i].playback);
- fixup_codec_formats(&dai_drv[i].capture);
- }
-
- /* register any DAIs */
- if (num_dai) {
- ret = snd_soc_register_dais(dev, dai_drv, num_dai);
- if (ret < 0)
- goto fail;
- }
-
- mutex_lock(&client_mutex);
- list_add(&codec->list, &codec_list);
- snd_soc_instantiate_cards();
- mutex_unlock(&client_mutex);
-
- pr_debug("Registered codec '%s'\n", codec->name);
- return 0;
-
-fail:
- kfree(codec->reg_def_copy);
- codec->reg_def_copy = NULL;
- kfree(codec->name);
- kfree(codec);
- return ret;
-}
-EXPORT_SYMBOL_GPL(snd_soc_register_codec);
-
-/**
- * snd_soc_unregister_codec - Unregister a codec from the ASoC core
- *
- * @codec: codec to unregister
- */
-void snd_soc_unregister_codec(struct device *dev)
-{
- struct snd_soc_codec *codec;
- int i;
-
- list_for_each_entry(codec, &codec_list, list) {
- if (dev == codec->dev)
- goto found;
- }
- return;
-
-found:
- if (codec->num_dai)
- for (i = 0; i < codec->num_dai; i++)
- snd_soc_unregister_dai(dev);
-
- mutex_lock(&client_mutex);
- list_del(&codec->list);
- mutex_unlock(&client_mutex);
-
- pr_debug("Unregistered codec '%s'\n", codec->name);
-
- snd_soc_cache_exit(codec);
- kfree(codec->reg_def_copy);
- kfree(codec->name);
- kfree(codec);
-}
-EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
-
-/* Retrieve a card's name from device tree */
-int snd_soc_of_parse_card_name(struct snd_soc_card *card,
- const char *propname)
-{
- struct device_node *np = card->dev->of_node;
- int ret;
-
- ret = of_property_read_string_index(np, propname, 0, &card->name);
- /*
- * EINVAL means the property does not exist. This is fine providing
- * card->name was previously set, which is checked later in
- * snd_soc_register_card.
- */
- if (ret < 0 && ret != -EINVAL) {
- dev_err(card->dev,
- "Property '%s' could not be read: %d\n",
- propname, ret);
- return ret;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_of_parse_card_name);
-
-int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
- const char *propname)
-{
- struct device_node *np = card->dev->of_node;
- int num_routes;
- struct snd_soc_dapm_route *routes;
- int i, ret;
-
- num_routes = of_property_count_strings(np, propname);
- if (num_routes < 0 || num_routes & 1) {
- dev_err(card->dev,
- "Property '%s' does not exist or its length is not even\n",
- propname);
- return -EINVAL;
- }
- num_routes /= 2;
- if (!num_routes) {
- dev_err(card->dev,
- "Property '%s's length is zero\n",
- propname);
- return -EINVAL;
- }
-
- routes = devm_kzalloc(card->dev, num_routes * sizeof(*routes),
- GFP_KERNEL);
- if (!routes) {
- dev_err(card->dev,
- "Could not allocate DAPM route table\n");
- return -EINVAL;
- }
-
- for (i = 0; i < num_routes; i++) {
- ret = of_property_read_string_index(np, propname,
- 2 * i, &routes[i].sink);
- if (ret) {
- dev_err(card->dev,
- "Property '%s' index %d could not be read: %d\n",
- propname, 2 * i, ret);
- return -EINVAL;
- }
- ret = of_property_read_string_index(np, propname,
- (2 * i) + 1, &routes[i].source);
- if (ret) {
- dev_err(card->dev,
- "Property '%s' index %d could not be read: %d\n",
- propname, (2 * i) + 1, ret);
- return -EINVAL;
- }
- }
-
- card->num_dapm_routes = num_routes;
- card->dapm_routes = routes;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing);
-
-static int __init snd_soc_init(void)
-{
-#ifdef CONFIG_DEBUG_FS
- snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL);
- if (IS_ERR(snd_soc_debugfs_root) || !snd_soc_debugfs_root) {
- pr_warn("ASoC: Failed to create debugfs directory\n");
- snd_soc_debugfs_root = NULL;
- }
-
- if (!debugfs_create_file("codecs", 0444, snd_soc_debugfs_root, NULL,
- &codec_list_fops))
- pr_warn("ASoC: Failed to create CODEC list debugfs file\n");
-
- if (!debugfs_create_file("dais", 0444, snd_soc_debugfs_root, NULL,
- &dai_list_fops))
- pr_warn("ASoC: Failed to create DAI list debugfs file\n");
-
- if (!debugfs_create_file("platforms", 0444, snd_soc_debugfs_root, NULL,
- &platform_list_fops))
- pr_warn("ASoC: Failed to create platform list debugfs file\n");
-#endif
-
- snd_soc_util_init();
-
- return platform_driver_register(&soc_driver);
-}
-module_init(snd_soc_init);
-
-static void __exit snd_soc_exit(void)
-{
- snd_soc_util_exit();
-
-#ifdef CONFIG_DEBUG_FS
- debugfs_remove_recursive(snd_soc_debugfs_root);
-#endif
- platform_driver_unregister(&soc_driver);
-}
-module_exit(snd_soc_exit);
-
-/* Module information */
-MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
-MODULE_DESCRIPTION("ALSA SoC Core");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:soc-audio");
diff --git a/ANDROID_3.4.5/sound/soc/soc-dapm.c b/ANDROID_3.4.5/sound/soc/soc-dapm.c
deleted file mode 100644
index 6201fc54..00000000
--- a/ANDROID_3.4.5/sound/soc/soc-dapm.c
+++ /dev/null
@@ -1,3288 +0,0 @@
-/*
- * soc-dapm.c -- ALSA SoC Dynamic Audio Power Management
- *
- * Copyright 2005 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood <lrg@slimlogic.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * Features:
- * o Changes power status of internal codec blocks depending on the
- * dynamic configuration of codec internal audio paths and active
- * DACs/ADCs.
- * o Platform power domain - can support external components i.e. amps and
- * mic/headphone insertion events.
- * o Automatic Mic Bias support
- * o Jack insertion power event initiation - e.g. hp insertion will enable
- * sinks, dacs, etc
- * o Delayed power down of audio subsystem to reduce pops between a quick
- * device reopen.
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/async.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/bitops.h>
-#include <linux/platform_device.h>
-#include <linux/jiffies.h>
-#include <linux/debugfs.h>
-#include <linux/pm_runtime.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-
-#include <trace/events/asoc.h>
-
-#define DAPM_UPDATE_STAT(widget, val) widget->dapm->card->dapm_stats.val++;
-
-/* dapm power sequences - make this per codec in the future */
-static int dapm_up_seq[] = {
- [snd_soc_dapm_pre] = 0,
- [snd_soc_dapm_supply] = 1,
- [snd_soc_dapm_regulator_supply] = 1,
- [snd_soc_dapm_micbias] = 2,
- [snd_soc_dapm_dai] = 3,
- [snd_soc_dapm_aif_in] = 3,
- [snd_soc_dapm_aif_out] = 3,
- [snd_soc_dapm_mic] = 4,
- [snd_soc_dapm_mux] = 5,
- [snd_soc_dapm_virt_mux] = 5,
- [snd_soc_dapm_value_mux] = 5,
- [snd_soc_dapm_dac] = 6,
- [snd_soc_dapm_mixer] = 7,
- [snd_soc_dapm_mixer_named_ctl] = 7,
- [snd_soc_dapm_pga] = 8,
- [snd_soc_dapm_adc] = 9,
- [snd_soc_dapm_out_drv] = 10,
- [snd_soc_dapm_hp] = 10,
- [snd_soc_dapm_spk] = 10,
- [snd_soc_dapm_line] = 10,
- [snd_soc_dapm_post] = 11,
-};
-
-static int dapm_down_seq[] = {
- [snd_soc_dapm_pre] = 0,
- [snd_soc_dapm_adc] = 1,
- [snd_soc_dapm_hp] = 2,
- [snd_soc_dapm_spk] = 2,
- [snd_soc_dapm_line] = 2,
- [snd_soc_dapm_out_drv] = 2,
- [snd_soc_dapm_pga] = 4,
- [snd_soc_dapm_mixer_named_ctl] = 5,
- [snd_soc_dapm_mixer] = 5,
- [snd_soc_dapm_dac] = 6,
- [snd_soc_dapm_mic] = 7,
- [snd_soc_dapm_micbias] = 8,
- [snd_soc_dapm_mux] = 9,
- [snd_soc_dapm_virt_mux] = 9,
- [snd_soc_dapm_value_mux] = 9,
- [snd_soc_dapm_aif_in] = 10,
- [snd_soc_dapm_aif_out] = 10,
- [snd_soc_dapm_dai] = 10,
- [snd_soc_dapm_regulator_supply] = 11,
- [snd_soc_dapm_supply] = 11,
- [snd_soc_dapm_post] = 12,
-};
-
-static void pop_wait(u32 pop_time)
-{
- if (pop_time)
- schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time));
-}
-
-static void pop_dbg(struct device *dev, u32 pop_time, const char *fmt, ...)
-{
- va_list args;
- char *buf;
-
- if (!pop_time)
- return;
-
- buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
- if (buf == NULL)
- return;
-
- va_start(args, fmt);
- vsnprintf(buf, PAGE_SIZE, fmt, args);
- dev_info(dev, "%s", buf);
- va_end(args);
-
- kfree(buf);
-}
-
-static bool dapm_dirty_widget(struct snd_soc_dapm_widget *w)
-{
- return !list_empty(&w->dirty);
-}
-
-void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason)
-{
- if (!dapm_dirty_widget(w)) {
- dev_vdbg(w->dapm->dev, "Marking %s dirty due to %s\n",
- w->name, reason);
- list_add_tail(&w->dirty, &w->dapm->card->dapm_dirty);
- }
-}
-EXPORT_SYMBOL_GPL(dapm_mark_dirty);
-
-/* create a new dapm widget */
-static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
- const struct snd_soc_dapm_widget *_widget)
-{
- return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL);
-}
-
-/* get snd_card from DAPM context */
-static inline struct snd_card *dapm_get_snd_card(
- struct snd_soc_dapm_context *dapm)
-{
- if (dapm->codec)
- return dapm->codec->card->snd_card;
- else if (dapm->platform)
- return dapm->platform->card->snd_card;
- else
- BUG();
-
- /* unreachable */
- return NULL;
-}
-
-/* get soc_card from DAPM context */
-static inline struct snd_soc_card *dapm_get_soc_card(
- struct snd_soc_dapm_context *dapm)
-{
- if (dapm->codec)
- return dapm->codec->card;
- else if (dapm->platform)
- return dapm->platform->card;
- else
- BUG();
-
- /* unreachable */
- return NULL;
-}
-
-static void dapm_reset(struct snd_soc_card *card)
-{
- struct snd_soc_dapm_widget *w;
-
- memset(&card->dapm_stats, 0, sizeof(card->dapm_stats));
-
- list_for_each_entry(w, &card->widgets, list) {
- w->power_checked = false;
- w->inputs = -1;
- w->outputs = -1;
- }
-}
-
-static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg)
-{
- if (w->codec)
- return snd_soc_read(w->codec, reg);
- else if (w->platform)
- return snd_soc_platform_read(w->platform, reg);
-
- dev_err(w->dapm->dev, "no valid widget read method\n");
- return -1;
-}
-
-static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg, int val)
-{
- if (w->codec)
- return snd_soc_write(w->codec, reg, val);
- else if (w->platform)
- return snd_soc_platform_write(w->platform, reg, val);
-
- dev_err(w->dapm->dev, "no valid widget write method\n");
- return -1;
-}
-
-static int soc_widget_update_bits(struct snd_soc_dapm_widget *w,
- unsigned short reg, unsigned int mask, unsigned int value)
-{
- bool change;
- unsigned int old, new;
- int ret;
-
- if (w->codec && w->codec->using_regmap) {
- ret = regmap_update_bits_check(w->codec->control_data,
- reg, mask, value, &change);
- if (ret != 0)
- return ret;
- } else {
- ret = soc_widget_read(w, reg);
- if (ret < 0)
- return ret;
-
- old = ret;
- new = (old & ~mask) | (value & mask);
- change = old != new;
- if (change) {
- ret = soc_widget_write(w, reg, new);
- if (ret < 0)
- return ret;
- }
- }
-
- return change;
-}
-
-/**
- * snd_soc_dapm_set_bias_level - set the bias level for the system
- * @dapm: DAPM context
- * @level: level to configure
- *
- * Configure the bias (power) levels for the SoC audio device.
- *
- * Returns 0 for success else error.
- */
-static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm,
- enum snd_soc_bias_level level)
-{
- struct snd_soc_card *card = dapm->card;
- int ret = 0;
-
- trace_snd_soc_bias_level_start(card, level);
-
- if (card && card->set_bias_level)
- ret = card->set_bias_level(card, dapm, level);
- if (ret != 0)
- goto out;
-
- if (dapm->codec) {
- if (dapm->codec->driver->set_bias_level)
- ret = dapm->codec->driver->set_bias_level(dapm->codec,
- level);
- else
- dapm->bias_level = level;
- }
- if (ret != 0)
- goto out;
-
- if (card && card->set_bias_level_post)
- ret = card->set_bias_level_post(card, dapm, level);
-out:
- trace_snd_soc_bias_level_done(card, level);
-
- return ret;
-}
-
-/* set up initial codec paths */
-static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
- struct snd_soc_dapm_path *p, int i)
-{
- switch (w->id) {
- case snd_soc_dapm_switch:
- case snd_soc_dapm_mixer:
- case snd_soc_dapm_mixer_named_ctl: {
- int val;
- struct soc_mixer_control *mc = (struct soc_mixer_control *)
- w->kcontrol_news[i].private_value;
- unsigned int reg = mc->reg;
- unsigned int shift = mc->shift;
- int max = mc->max;
- unsigned int mask = (1 << fls(max)) - 1;
- unsigned int invert = mc->invert;
-
- val = soc_widget_read(w, reg);
- val = (val >> shift) & mask;
-
- if ((invert && !val) || (!invert && val))
- p->connect = 1;
- else
- p->connect = 0;
- }
- break;
- case snd_soc_dapm_mux: {
- struct soc_enum *e = (struct soc_enum *)
- w->kcontrol_news[i].private_value;
- int val, item, bitmask;
-
- for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
- ;
- val = soc_widget_read(w, e->reg);
- item = (val >> e->shift_l) & (bitmask - 1);
-
- p->connect = 0;
- for (i = 0; i < e->max; i++) {
- if (!(strcmp(p->name, e->texts[i])) && item == i)
- p->connect = 1;
- }
- }
- break;
- case snd_soc_dapm_virt_mux: {
- struct soc_enum *e = (struct soc_enum *)
- w->kcontrol_news[i].private_value;
-
- p->connect = 0;
- /* since a virtual mux has no backing registers to
- * decide which path to connect, it will try to match
- * with the first enumeration. This is to ensure
- * that the default mux choice (the first) will be
- * correctly powered up during initialization.
- */
- if (!strcmp(p->name, e->texts[0]))
- p->connect = 1;
- }
- break;
- case snd_soc_dapm_value_mux: {
- struct soc_enum *e = (struct soc_enum *)
- w->kcontrol_news[i].private_value;
- int val, item;
-
- val = soc_widget_read(w, e->reg);
- val = (val >> e->shift_l) & e->mask;
- for (item = 0; item < e->max; item++) {
- if (val == e->values[item])
- break;
- }
-
- p->connect = 0;
- for (i = 0; i < e->max; i++) {
- if (!(strcmp(p->name, e->texts[i])) && item == i)
- p->connect = 1;
- }
- }
- break;
- /* does not affect routing - always connected */
- case snd_soc_dapm_pga:
- case snd_soc_dapm_out_drv:
- case snd_soc_dapm_output:
- case snd_soc_dapm_adc:
- case snd_soc_dapm_input:
- case snd_soc_dapm_siggen:
- case snd_soc_dapm_dac:
- case snd_soc_dapm_micbias:
- case snd_soc_dapm_vmid:
- case snd_soc_dapm_supply:
- case snd_soc_dapm_regulator_supply:
- case snd_soc_dapm_aif_in:
- case snd_soc_dapm_aif_out:
- case snd_soc_dapm_dai:
- case snd_soc_dapm_hp:
- case snd_soc_dapm_mic:
- case snd_soc_dapm_spk:
- case snd_soc_dapm_line:
- p->connect = 1;
- break;
- /* does affect routing - dynamically connected */
- case snd_soc_dapm_pre:
- case snd_soc_dapm_post:
- p->connect = 0;
- break;
- }
-}
-
-/* connect mux widget to its interconnecting audio paths */
-static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
- struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
- struct snd_soc_dapm_path *path, const char *control_name,
- const struct snd_kcontrol_new *kcontrol)
-{
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- int i;
-
- for (i = 0; i < e->max; i++) {
- if (!(strcmp(control_name, e->texts[i]))) {
- list_add(&path->list, &dapm->card->paths);
- list_add(&path->list_sink, &dest->sources);
- list_add(&path->list_source, &src->sinks);
- path->name = (char*)e->texts[i];
- dapm_set_path_status(dest, path, 0);
- return 0;
- }
- }
-
- return -ENODEV;
-}
-
-/* connect mixer widget to its interconnecting audio paths */
-static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm,
- struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
- struct snd_soc_dapm_path *path, const char *control_name)
-{
- int i;
-
- /* search for mixer kcontrol */
- for (i = 0; i < dest->num_kcontrols; i++) {
- if (!strcmp(control_name, dest->kcontrol_news[i].name)) {
- list_add(&path->list, &dapm->card->paths);
- list_add(&path->list_sink, &dest->sources);
- list_add(&path->list_source, &src->sinks);
- path->name = dest->kcontrol_news[i].name;
- dapm_set_path_status(dest, path, i);
- return 0;
- }
- }
- return -ENODEV;
-}
-
-static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm,
- struct snd_soc_dapm_widget *kcontrolw,
- const struct snd_kcontrol_new *kcontrol_new,
- struct snd_kcontrol **kcontrol)
-{
- struct snd_soc_dapm_widget *w;
- int i;
-
- *kcontrol = NULL;
-
- list_for_each_entry(w, &dapm->card->widgets, list) {
- if (w == kcontrolw || w->dapm != kcontrolw->dapm)
- continue;
- for (i = 0; i < w->num_kcontrols; i++) {
- if (&w->kcontrol_news[i] == kcontrol_new) {
- if (w->kcontrols)
- *kcontrol = w->kcontrols[i];
- return 1;
- }
- }
- }
-
- return 0;
-}
-
-/* create new dapm mixer control */
-static int dapm_new_mixer(struct snd_soc_dapm_widget *w)
-{
- struct snd_soc_dapm_context *dapm = w->dapm;
- int i, ret = 0;
- size_t name_len, prefix_len;
- struct snd_soc_dapm_path *path;
- struct snd_card *card = dapm->card->snd_card;
- const char *prefix;
- struct snd_soc_dapm_widget_list *wlist;
- size_t wlistsize;
-
- if (dapm->codec)
- prefix = dapm->codec->name_prefix;
- else
- prefix = NULL;
-
- if (prefix)
- prefix_len = strlen(prefix) + 1;
- else
- prefix_len = 0;
-
- /* add kcontrol */
- for (i = 0; i < w->num_kcontrols; i++) {
-
- /* match name */
- list_for_each_entry(path, &w->sources, list_sink) {
-
- /* mixer/mux paths name must match control name */
- if (path->name != (char *)w->kcontrol_news[i].name)
- continue;
-
- if (w->kcontrols[i]) {
- path->kcontrol = w->kcontrols[i];
- continue;
- }
-
- wlistsize = sizeof(struct snd_soc_dapm_widget_list) +
- sizeof(struct snd_soc_dapm_widget *),
- wlist = kzalloc(wlistsize, GFP_KERNEL);
- if (wlist == NULL) {
- dev_err(dapm->dev,
- "asoc: can't allocate widget list for %s\n",
- w->name);
- return -ENOMEM;
- }
- wlist->num_widgets = 1;
- wlist->widgets[0] = w;
-
- /* add dapm control with long name.
- * for dapm_mixer this is the concatenation of the
- * mixer and kcontrol name.
- * for dapm_mixer_named_ctl this is simply the
- * kcontrol name.
- */
- name_len = strlen(w->kcontrol_news[i].name) + 1;
- if (w->id != snd_soc_dapm_mixer_named_ctl)
- name_len += 1 + strlen(w->name);
-
- path->long_name = kmalloc(name_len, GFP_KERNEL);
-
- if (path->long_name == NULL) {
- kfree(wlist);
- return -ENOMEM;
- }
-
- switch (w->id) {
- default:
- /* The control will get a prefix from
- * the control creation process but
- * we're also using the same prefix
- * for widgets so cut the prefix off
- * the front of the widget name.
- */
- snprintf((char *)path->long_name, name_len,
- "%s %s", w->name + prefix_len,
- w->kcontrol_news[i].name);
- break;
- case snd_soc_dapm_mixer_named_ctl:
- snprintf((char *)path->long_name, name_len,
- "%s", w->kcontrol_news[i].name);
- break;
- }
-
- ((char *)path->long_name)[name_len - 1] = '\0';
-
- path->kcontrol = snd_soc_cnew(&w->kcontrol_news[i],
- wlist, path->long_name,
- prefix);
- ret = snd_ctl_add(card, path->kcontrol);
- if (ret < 0) {
- dev_err(dapm->dev,
- "asoc: failed to add dapm kcontrol %s: %d\n",
- path->long_name, ret);
- kfree(wlist);
- kfree(path->long_name);
- path->long_name = NULL;
- return ret;
- }
- w->kcontrols[i] = path->kcontrol;
- }
- }
- return ret;
-}
-
-/* create new dapm mux control */
-static int dapm_new_mux(struct snd_soc_dapm_widget *w)
-{
- struct snd_soc_dapm_context *dapm = w->dapm;
- struct snd_soc_dapm_path *path = NULL;
- struct snd_kcontrol *kcontrol;
- struct snd_card *card = dapm->card->snd_card;
- const char *prefix;
- size_t prefix_len;
- int ret;
- struct snd_soc_dapm_widget_list *wlist;
- int shared, wlistentries;
- size_t wlistsize;
- const char *name;
-
- if (w->num_kcontrols != 1) {
- dev_err(dapm->dev,
- "asoc: mux %s has incorrect number of controls\n",
- w->name);
- return -EINVAL;
- }
-
- shared = dapm_is_shared_kcontrol(dapm, w, &w->kcontrol_news[0],
- &kcontrol);
- if (kcontrol) {
- wlist = kcontrol->private_data;
- wlistentries = wlist->num_widgets + 1;
- } else {
- wlist = NULL;
- wlistentries = 1;
- }
- wlistsize = sizeof(struct snd_soc_dapm_widget_list) +
- wlistentries * sizeof(struct snd_soc_dapm_widget *),
- wlist = krealloc(wlist, wlistsize, GFP_KERNEL);
- if (wlist == NULL) {
- dev_err(dapm->dev,
- "asoc: can't allocate widget list for %s\n", w->name);
- return -ENOMEM;
- }
- wlist->num_widgets = wlistentries;
- wlist->widgets[wlistentries - 1] = w;
-
- if (!kcontrol) {
- if (dapm->codec)
- prefix = dapm->codec->name_prefix;
- else
- prefix = NULL;
-
- if (shared) {
- name = w->kcontrol_news[0].name;
- prefix_len = 0;
- } else {
- name = w->name;
- if (prefix)
- prefix_len = strlen(prefix) + 1;
- else
- prefix_len = 0;
- }
-
- /*
- * The control will get a prefix from the control creation
- * process but we're also using the same prefix for widgets so
- * cut the prefix off the front of the widget name.
- */
- kcontrol = snd_soc_cnew(&w->kcontrol_news[0], wlist,
- name + prefix_len, prefix);
- ret = snd_ctl_add(card, kcontrol);
- if (ret < 0) {
- dev_err(dapm->dev, "failed to add kcontrol %s: %d\n",
- w->name, ret);
- kfree(wlist);
- return ret;
- }
- }
-
- kcontrol->private_data = wlist;
-
- w->kcontrols[0] = kcontrol;
-
- list_for_each_entry(path, &w->sources, list_sink)
- path->kcontrol = kcontrol;
-
- return 0;
-}
-
-/* create new dapm volume control */
-static int dapm_new_pga(struct snd_soc_dapm_widget *w)
-{
- if (w->num_kcontrols)
- dev_err(w->dapm->dev,
- "asoc: PGA controls not supported: '%s'\n", w->name);
-
- return 0;
-}
-
-/* reset 'walked' bit for each dapm path */
-static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm)
-{
- struct snd_soc_dapm_path *p;
-
- list_for_each_entry(p, &dapm->card->paths, list)
- p->walked = 0;
-}
-
-/* We implement power down on suspend by checking the power state of
- * the ALSA card - when we are suspending the ALSA state for the card
- * is set to D3.
- */
-static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget)
-{
- int level = snd_power_get_state(widget->dapm->card->snd_card);
-
- switch (level) {
- case SNDRV_CTL_POWER_D3hot:
- case SNDRV_CTL_POWER_D3cold:
- if (widget->ignore_suspend)
- dev_dbg(widget->dapm->dev, "%s ignoring suspend\n",
- widget->name);
- return widget->ignore_suspend;
- default:
- return 1;
- }
-}
-
-/*
- * Recursively check for a completed path to an active or physically connected
- * output widget. Returns number of complete paths.
- */
-static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
-{
- struct snd_soc_dapm_path *path;
- int con = 0;
-
- if (widget->outputs >= 0)
- return widget->outputs;
-
- DAPM_UPDATE_STAT(widget, path_checks);
-
- switch (widget->id) {
- case snd_soc_dapm_supply:
- case snd_soc_dapm_regulator_supply:
- return 0;
- default:
- break;
- }
-
- switch (widget->id) {
- case snd_soc_dapm_adc:
- case snd_soc_dapm_aif_out:
- case snd_soc_dapm_dai:
- if (widget->active) {
- widget->outputs = snd_soc_dapm_suspend_check(widget);
- return widget->outputs;
- }
- default:
- break;
- }
-
- if (widget->connected) {
- /* connected pin ? */
- if (widget->id == snd_soc_dapm_output && !widget->ext) {
- widget->outputs = snd_soc_dapm_suspend_check(widget);
- return widget->outputs;
- }
-
- /* connected jack or spk ? */
- if (widget->id == snd_soc_dapm_hp ||
- widget->id == snd_soc_dapm_spk ||
- (widget->id == snd_soc_dapm_line &&
- !list_empty(&widget->sources))) {
- widget->outputs = snd_soc_dapm_suspend_check(widget);
- return widget->outputs;
- }
- }
-
- list_for_each_entry(path, &widget->sinks, list_source) {
- DAPM_UPDATE_STAT(widget, neighbour_checks);
-
- if (path->weak)
- continue;
-
- if (path->walked)
- continue;
-
- if (path->sink && path->connect) {
- path->walked = 1;
- con += is_connected_output_ep(path->sink);
- }
- }
-
- widget->outputs = con;
-
- return con;
-}
-
-/*
- * Recursively check for a completed path to an active or physically connected
- * input widget. Returns number of complete paths.
- */
-static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
-{
- struct snd_soc_dapm_path *path;
- int con = 0;
-
- if (widget->inputs >= 0)
- return widget->inputs;
-
- DAPM_UPDATE_STAT(widget, path_checks);
-
- switch (widget->id) {
- case snd_soc_dapm_supply:
- case snd_soc_dapm_regulator_supply:
- return 0;
- default:
- break;
- }
-
- /* active stream ? */
- switch (widget->id) {
- case snd_soc_dapm_dac:
- case snd_soc_dapm_aif_in:
- case snd_soc_dapm_dai:
- if (widget->active) {
- widget->inputs = snd_soc_dapm_suspend_check(widget);
- return widget->inputs;
- }
- default:
- break;
- }
-
- if (widget->connected) {
- /* connected pin ? */
- if (widget->id == snd_soc_dapm_input && !widget->ext) {
- widget->inputs = snd_soc_dapm_suspend_check(widget);
- return widget->inputs;
- }
-
- /* connected VMID/Bias for lower pops */
- if (widget->id == snd_soc_dapm_vmid) {
- widget->inputs = snd_soc_dapm_suspend_check(widget);
- return widget->inputs;
- }
-
- /* connected jack ? */
- if (widget->id == snd_soc_dapm_mic ||
- (widget->id == snd_soc_dapm_line &&
- !list_empty(&widget->sinks))) {
- widget->inputs = snd_soc_dapm_suspend_check(widget);
- return widget->inputs;
- }
-
- /* signal generator */
- if (widget->id == snd_soc_dapm_siggen) {
- widget->inputs = snd_soc_dapm_suspend_check(widget);
- return widget->inputs;
- }
- }
-
- list_for_each_entry(path, &widget->sources, list_sink) {
- DAPM_UPDATE_STAT(widget, neighbour_checks);
-
- if (path->weak)
- continue;
-
- if (path->walked)
- continue;
-
- if (path->source && path->connect) {
- path->walked = 1;
- con += is_connected_input_ep(path->source);
- }
- }
-
- widget->inputs = con;
-
- return con;
-}
-
-/*
- * Handler for generic register modifier widget.
- */
-int dapm_reg_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- unsigned int val;
-
- if (SND_SOC_DAPM_EVENT_ON(event))
- val = w->on_val;
- else
- val = w->off_val;
-
- soc_widget_update_bits(w, -(w->reg + 1),
- w->mask << w->shift, val << w->shift);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(dapm_reg_event);
-
-/*
- * Handler for regulator supply widget.
- */
-int dapm_regulator_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- if (SND_SOC_DAPM_EVENT_ON(event))
- return regulator_enable(w->priv);
- else
- return regulator_disable_deferred(w->priv, w->shift);
-}
-EXPORT_SYMBOL_GPL(dapm_regulator_event);
-
-static int dapm_widget_power_check(struct snd_soc_dapm_widget *w)
-{
- if (w->power_checked)
- return w->new_power;
-
- if (w->force)
- w->new_power = 1;
- else
- w->new_power = w->power_check(w);
-
- w->power_checked = true;
-
- return w->new_power;
-}
-
-/* Generic check to see if a widget should be powered.
- */
-static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
-{
- int in, out;
-
- DAPM_UPDATE_STAT(w, power_checks);
-
- in = is_connected_input_ep(w);
- dapm_clear_walk(w->dapm);
- out = is_connected_output_ep(w);
- dapm_clear_walk(w->dapm);
- return out != 0 && in != 0;
-}
-
-static int dapm_dai_check_power(struct snd_soc_dapm_widget *w)
-{
- DAPM_UPDATE_STAT(w, power_checks);
-
- return w->active;
-}
-
-/* Check to see if an ADC has power */
-static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
-{
- int in;
-
- DAPM_UPDATE_STAT(w, power_checks);
-
- if (w->active) {
- in = is_connected_input_ep(w);
- dapm_clear_walk(w->dapm);
- return in != 0;
- } else {
- return dapm_generic_check_power(w);
- }
-}
-
-/* Check to see if a DAC has power */
-static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
-{
- int out;
-
- DAPM_UPDATE_STAT(w, power_checks);
-
- if (w->active) {
- out = is_connected_output_ep(w);
- dapm_clear_walk(w->dapm);
- return out != 0;
- } else {
- return dapm_generic_check_power(w);
- }
-}
-
-/* Check to see if a power supply is needed */
-static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
-{
- struct snd_soc_dapm_path *path;
-
- DAPM_UPDATE_STAT(w, power_checks);
-
- /* Check if one of our outputs is connected */
- list_for_each_entry(path, &w->sinks, list_source) {
- DAPM_UPDATE_STAT(w, neighbour_checks);
-
- if (path->weak)
- continue;
-
- if (path->connected &&
- !path->connected(path->source, path->sink))
- continue;
-
- if (!path->sink)
- continue;
-
- if (dapm_widget_power_check(path->sink))
- return 1;
- }
-
- dapm_clear_walk(w->dapm);
-
- return 0;
-}
-
-static int dapm_always_on_check_power(struct snd_soc_dapm_widget *w)
-{
- return 1;
-}
-
-static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
- struct snd_soc_dapm_widget *b,
- bool power_up)
-{
- int *sort;
-
- if (power_up)
- sort = dapm_up_seq;
- else
- sort = dapm_down_seq;
-
- if (sort[a->id] != sort[b->id])
- return sort[a->id] - sort[b->id];
- if (a->subseq != b->subseq) {
- if (power_up)
- return a->subseq - b->subseq;
- else
- return b->subseq - a->subseq;
- }
- if (a->reg != b->reg)
- return a->reg - b->reg;
- if (a->dapm != b->dapm)
- return (unsigned long)a->dapm - (unsigned long)b->dapm;
-
- return 0;
-}
-
-/* Insert a widget in order into a DAPM power sequence. */
-static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget,
- struct list_head *list,
- bool power_up)
-{
- struct snd_soc_dapm_widget *w;
-
- list_for_each_entry(w, list, power_list)
- if (dapm_seq_compare(new_widget, w, power_up) < 0) {
- list_add_tail(&new_widget->power_list, &w->power_list);
- return;
- }
-
- list_add_tail(&new_widget->power_list, list);
-}
-
-static void dapm_seq_check_event(struct snd_soc_dapm_context *dapm,
- struct snd_soc_dapm_widget *w, int event)
-{
- struct snd_soc_card *card = dapm->card;
- const char *ev_name;
- int power, ret;
-
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- ev_name = "PRE_PMU";
- power = 1;
- break;
- case SND_SOC_DAPM_POST_PMU:
- ev_name = "POST_PMU";
- power = 1;
- break;
- case SND_SOC_DAPM_PRE_PMD:
- ev_name = "PRE_PMD";
- power = 0;
- break;
- case SND_SOC_DAPM_POST_PMD:
- ev_name = "POST_PMD";
- power = 0;
- break;
- default:
- BUG();
- return;
- }
-
- if (w->power != power)
- return;
-
- if (w->event && (w->event_flags & event)) {
- pop_dbg(dapm->dev, card->pop_time, "pop test : %s %s\n",
- w->name, ev_name);
- trace_snd_soc_dapm_widget_event_start(w, event);
- ret = w->event(w, NULL, event);
- trace_snd_soc_dapm_widget_event_done(w, event);
- if (ret < 0)
- pr_err("%s: %s event failed: %d\n",
- ev_name, w->name, ret);
- }
-}
-
-/* Apply the coalesced changes from a DAPM sequence */
-static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm,
- struct list_head *pending)
-{
- struct snd_soc_card *card = dapm->card;
- struct snd_soc_dapm_widget *w;
- int reg, power;
- unsigned int value = 0;
- unsigned int mask = 0;
- unsigned int cur_mask;
-
- reg = list_first_entry(pending, struct snd_soc_dapm_widget,
- power_list)->reg;
-
- list_for_each_entry(w, pending, power_list) {
- cur_mask = 1 << w->shift;
- BUG_ON(reg != w->reg);
-
- if (w->invert)
- power = !w->power;
- else
- power = w->power;
-
- mask |= cur_mask;
- if (power)
- value |= cur_mask;
-
- pop_dbg(dapm->dev, card->pop_time,
- "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n",
- w->name, reg, value, mask);
-
- /* Check for events */
- dapm_seq_check_event(dapm, w, SND_SOC_DAPM_PRE_PMU);
- dapm_seq_check_event(dapm, w, SND_SOC_DAPM_PRE_PMD);
- }
-
- if (reg >= 0) {
- /* Any widget will do, they should all be updating the
- * same register.
- */
- w = list_first_entry(pending, struct snd_soc_dapm_widget,
- power_list);
-
- pop_dbg(dapm->dev, card->pop_time,
- "pop test : Applying 0x%x/0x%x to %x in %dms\n",
- value, mask, reg, card->pop_time);
- pop_wait(card->pop_time);
- soc_widget_update_bits(w, reg, mask, value);
- }
-
- list_for_each_entry(w, pending, power_list) {
- dapm_seq_check_event(dapm, w, SND_SOC_DAPM_POST_PMU);
- dapm_seq_check_event(dapm, w, SND_SOC_DAPM_POST_PMD);
- }
-}
-
-/* Apply a DAPM power sequence.
- *
- * We walk over a pre-sorted list of widgets to apply power to. In
- * order to minimise the number of writes to the device required
- * multiple widgets will be updated in a single write where possible.
- * Currently anything that requires more than a single write is not
- * handled.
- */
-static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
- struct list_head *list, int event, bool power_up)
-{
- struct snd_soc_dapm_widget *w, *n;
- LIST_HEAD(pending);
- int cur_sort = -1;
- int cur_subseq = -1;
- int cur_reg = SND_SOC_NOPM;
- struct snd_soc_dapm_context *cur_dapm = NULL;
- int ret, i;
- int *sort;
-
- if (power_up)
- sort = dapm_up_seq;
- else
- sort = dapm_down_seq;
-
- list_for_each_entry_safe(w, n, list, power_list) {
- ret = 0;
-
- /* Do we need to apply any queued changes? */
- if (sort[w->id] != cur_sort || w->reg != cur_reg ||
- w->dapm != cur_dapm || w->subseq != cur_subseq) {
- if (!list_empty(&pending))
- dapm_seq_run_coalesced(cur_dapm, &pending);
-
- if (cur_dapm && cur_dapm->seq_notifier) {
- for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++)
- if (sort[i] == cur_sort)
- cur_dapm->seq_notifier(cur_dapm,
- i,
- cur_subseq);
- }
-
- INIT_LIST_HEAD(&pending);
- cur_sort = -1;
- cur_subseq = INT_MIN;
- cur_reg = SND_SOC_NOPM;
- cur_dapm = NULL;
- }
-
- switch (w->id) {
- case snd_soc_dapm_pre:
- if (!w->event)
- list_for_each_entry_safe_continue(w, n, list,
- power_list);
-
- if (event == SND_SOC_DAPM_STREAM_START)
- ret = w->event(w,
- NULL, SND_SOC_DAPM_PRE_PMU);
- else if (event == SND_SOC_DAPM_STREAM_STOP)
- ret = w->event(w,
- NULL, SND_SOC_DAPM_PRE_PMD);
- break;
-
- case snd_soc_dapm_post:
- if (!w->event)
- list_for_each_entry_safe_continue(w, n, list,
- power_list);
-
- if (event == SND_SOC_DAPM_STREAM_START)
- ret = w->event(w,
- NULL, SND_SOC_DAPM_POST_PMU);
- else if (event == SND_SOC_DAPM_STREAM_STOP)
- ret = w->event(w,
- NULL, SND_SOC_DAPM_POST_PMD);
- break;
-
- default:
- /* Queue it up for application */
- cur_sort = sort[w->id];
- cur_subseq = w->subseq;
- cur_reg = w->reg;
- cur_dapm = w->dapm;
- list_move(&w->power_list, &pending);
- break;
- }
-
- if (ret < 0)
- dev_err(w->dapm->dev,
- "Failed to apply widget power: %d\n", ret);
- }
-
- if (!list_empty(&pending))
- dapm_seq_run_coalesced(cur_dapm, &pending);
-
- if (cur_dapm && cur_dapm->seq_notifier) {
- for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++)
- if (sort[i] == cur_sort)
- cur_dapm->seq_notifier(cur_dapm,
- i, cur_subseq);
- }
-}
-
-static void dapm_widget_update(struct snd_soc_dapm_context *dapm)
-{
- struct snd_soc_dapm_update *update = dapm->update;
- struct snd_soc_dapm_widget *w;
- int ret;
-
- if (!update)
- return;
-
- w = update->widget;
-
- if (w->event &&
- (w->event_flags & SND_SOC_DAPM_PRE_REG)) {
- ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG);
- if (ret != 0)
- pr_err("%s DAPM pre-event failed: %d\n",
- w->name, ret);
- }
-
- ret = snd_soc_update_bits(w->codec, update->reg, update->mask,
- update->val);
- if (ret < 0)
- pr_err("%s DAPM update failed: %d\n", w->name, ret);
-
- if (w->event &&
- (w->event_flags & SND_SOC_DAPM_POST_REG)) {
- ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG);
- if (ret != 0)
- pr_err("%s DAPM post-event failed: %d\n",
- w->name, ret);
- }
-}
-
-/* Async callback run prior to DAPM sequences - brings to _PREPARE if
- * they're changing state.
- */
-static void dapm_pre_sequence_async(void *data, async_cookie_t cookie)
-{
- struct snd_soc_dapm_context *d = data;
- int ret;
-
- /* If we're off and we're not supposed to be go into STANDBY */
- if (d->bias_level == SND_SOC_BIAS_OFF &&
- d->target_bias_level != SND_SOC_BIAS_OFF) {
- if (d->dev)
- pm_runtime_get_sync(d->dev);
-
- ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
- if (ret != 0)
- dev_err(d->dev,
- "Failed to turn on bias: %d\n", ret);
- }
-
- /* Prepare for a STADDBY->ON or ON->STANDBY transition */
- if (d->bias_level != d->target_bias_level) {
- ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_PREPARE);
- if (ret != 0)
- dev_err(d->dev,
- "Failed to prepare bias: %d\n", ret);
- }
-}
-
-/* Async callback run prior to DAPM sequences - brings to their final
- * state.
- */
-static void dapm_post_sequence_async(void *data, async_cookie_t cookie)
-{
- struct snd_soc_dapm_context *d = data;
- int ret;
-
- /* If we just powered the last thing off drop to standby bias */
- if (d->bias_level == SND_SOC_BIAS_PREPARE &&
- (d->target_bias_level == SND_SOC_BIAS_STANDBY ||
- d->target_bias_level == SND_SOC_BIAS_OFF)) {
- ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
- if (ret != 0)
- dev_err(d->dev, "Failed to apply standby bias: %d\n",
- ret);
- }
-
- /* If we're in standby and can support bias off then do that */
- if (d->bias_level == SND_SOC_BIAS_STANDBY &&
- d->target_bias_level == SND_SOC_BIAS_OFF) {
- ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_OFF);
- if (ret != 0)
- dev_err(d->dev, "Failed to turn off bias: %d\n", ret);
-
- if (d->dev)
- pm_runtime_put(d->dev);
- }
-
- /* If we just powered up then move to active bias */
- if (d->bias_level == SND_SOC_BIAS_PREPARE &&
- d->target_bias_level == SND_SOC_BIAS_ON) {
- ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_ON);
- if (ret != 0)
- dev_err(d->dev, "Failed to apply active bias: %d\n",
- ret);
- }
-}
-
-static void dapm_widget_set_peer_power(struct snd_soc_dapm_widget *peer,
- bool power, bool connect)
-{
- /* If a connection is being made or broken then that update
- * will have marked the peer dirty, otherwise the widgets are
- * not connected and this update has no impact. */
- if (!connect)
- return;
-
- /* If the peer is already in the state we're moving to then we
- * won't have an impact on it. */
- if (power != peer->power)
- dapm_mark_dirty(peer, "peer state change");
-}
-
-static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power,
- struct list_head *up_list,
- struct list_head *down_list)
-{
- struct snd_soc_dapm_path *path;
-
- if (w->power == power)
- return;
-
- trace_snd_soc_dapm_widget_power(w, power);
-
- /* If we changed our power state perhaps our neigbours changed
- * also.
- */
- list_for_each_entry(path, &w->sources, list_sink) {
- if (path->source) {
- dapm_widget_set_peer_power(path->source, power,
- path->connect);
- }
- }
- switch (w->id) {
- case snd_soc_dapm_supply:
- case snd_soc_dapm_regulator_supply:
- /* Supplies can't affect their outputs, only their inputs */
- break;
- default:
- list_for_each_entry(path, &w->sinks, list_source) {
- if (path->sink) {
- dapm_widget_set_peer_power(path->sink, power,
- path->connect);
- }
- }
- break;
- }
-
- if (power)
- dapm_seq_insert(w, up_list, true);
- else
- dapm_seq_insert(w, down_list, false);
-
- w->power = power;
-}
-
-static void dapm_power_one_widget(struct snd_soc_dapm_widget *w,
- struct list_head *up_list,
- struct list_head *down_list)
-{
- int power;
-
- switch (w->id) {
- case snd_soc_dapm_pre:
- dapm_seq_insert(w, down_list, false);
- break;
- case snd_soc_dapm_post:
- dapm_seq_insert(w, up_list, true);
- break;
-
- default:
- power = dapm_widget_power_check(w);
-
- dapm_widget_set_power(w, power, up_list, down_list);
- break;
- }
-}
-
-/*
- * Scan each dapm widget for complete audio path.
- * A complete path is a route that has valid endpoints i.e.:-
- *
- * o DAC to output pin.
- * o Input Pin to ADC.
- * o Input pin to Output pin (bypass, sidetone)
- * o DAC to ADC (loopback).
- */
-static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
-{
- struct snd_soc_card *card = dapm->card;
- struct snd_soc_dapm_widget *w;
- struct snd_soc_dapm_context *d;
- LIST_HEAD(up_list);
- LIST_HEAD(down_list);
- LIST_HEAD(async_domain);
- enum snd_soc_bias_level bias;
-
- trace_snd_soc_dapm_start(card);
-
- list_for_each_entry(d, &card->dapm_list, list) {
- if (d->n_widgets || d->codec == NULL) {
- if (d->idle_bias_off)
- d->target_bias_level = SND_SOC_BIAS_OFF;
- else
- d->target_bias_level = SND_SOC_BIAS_STANDBY;
- }
- }
-
- dapm_reset(card);
-
- /* Check which widgets we need to power and store them in
- * lists indicating if they should be powered up or down. We
- * only check widgets that have been flagged as dirty but note
- * that new widgets may be added to the dirty list while we
- * iterate.
- */
- list_for_each_entry(w, &card->dapm_dirty, dirty) {
- dapm_power_one_widget(w, &up_list, &down_list);
- }
-
- list_for_each_entry(w, &card->widgets, list) {
- switch (w->id) {
- case snd_soc_dapm_pre:
- case snd_soc_dapm_post:
- /* These widgets always need to be powered */
- break;
- default:
- list_del_init(&w->dirty);
- break;
- }
-
- if (w->power) {
- d = w->dapm;
-
- /* Supplies and micbiases only bring the
- * context up to STANDBY as unless something
- * else is active and passing audio they
- * generally don't require full power. Signal
- * generators are virtual pins and have no
- * power impact themselves.
- */
- switch (w->id) {
- case snd_soc_dapm_siggen:
- break;
- case snd_soc_dapm_supply:
- case snd_soc_dapm_regulator_supply:
- case snd_soc_dapm_micbias:
- if (d->target_bias_level < SND_SOC_BIAS_STANDBY)
- d->target_bias_level = SND_SOC_BIAS_STANDBY;
- break;
- default:
- d->target_bias_level = SND_SOC_BIAS_ON;
- break;
- }
- }
-
- }
-
- /* If there are no DAPM widgets then try to figure out power from the
- * event type.
- */
- if (!dapm->n_widgets) {
- switch (event) {
- case SND_SOC_DAPM_STREAM_START:
- case SND_SOC_DAPM_STREAM_RESUME:
- dapm->target_bias_level = SND_SOC_BIAS_ON;
- break;
- case SND_SOC_DAPM_STREAM_STOP:
- if (dapm->codec && dapm->codec->active)
- dapm->target_bias_level = SND_SOC_BIAS_ON;
- else
- dapm->target_bias_level = SND_SOC_BIAS_STANDBY;
- break;
- case SND_SOC_DAPM_STREAM_SUSPEND:
- dapm->target_bias_level = SND_SOC_BIAS_STANDBY;
- break;
- case SND_SOC_DAPM_STREAM_NOP:
- dapm->target_bias_level = dapm->bias_level;
- break;
- default:
- break;
- }
- }
-
- /* Force all contexts in the card to the same bias state if
- * they're not ground referenced.
- */
- bias = SND_SOC_BIAS_OFF;
- list_for_each_entry(d, &card->dapm_list, list)
- if (d->target_bias_level > bias)
- bias = d->target_bias_level;
- list_for_each_entry(d, &card->dapm_list, list)
- if (!d->idle_bias_off)
- d->target_bias_level = bias;
-
- trace_snd_soc_dapm_walk_done(card);
-
- /* Run all the bias changes in parallel */
- list_for_each_entry(d, &dapm->card->dapm_list, list)
- async_schedule_domain(dapm_pre_sequence_async, d,
- &async_domain);
- async_synchronize_full_domain(&async_domain);
-
- /* Power down widgets first; try to avoid amplifying pops. */
- dapm_seq_run(dapm, &down_list, event, false);
-
- dapm_widget_update(dapm);
-
- /* Now power up. */
- dapm_seq_run(dapm, &up_list, event, true);
-
- /* Run all the bias changes in parallel */
- list_for_each_entry(d, &dapm->card->dapm_list, list)
- async_schedule_domain(dapm_post_sequence_async, d,
- &async_domain);
- async_synchronize_full_domain(&async_domain);
-
- /* do we need to notify any clients that DAPM event is complete */
- list_for_each_entry(d, &card->dapm_list, list) {
- if (d->stream_event)
- d->stream_event(d, event);
- }
-
- pop_dbg(dapm->dev, card->pop_time,
- "DAPM sequencing finished, waiting %dms\n", card->pop_time);
- pop_wait(card->pop_time);
-
- trace_snd_soc_dapm_done(card);
-
- return 0;
-}
-
-#ifdef CONFIG_DEBUG_FS
-static ssize_t dapm_widget_power_read_file(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct snd_soc_dapm_widget *w = file->private_data;
- char *buf;
- int in, out;
- ssize_t ret;
- struct snd_soc_dapm_path *p = NULL;
-
- buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- in = is_connected_input_ep(w);
- dapm_clear_walk(w->dapm);
- out = is_connected_output_ep(w);
- dapm_clear_walk(w->dapm);
-
- ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d",
- w->name, w->power ? "On" : "Off",
- w->force ? " (forced)" : "", in, out);
-
- if (w->reg >= 0)
- ret += snprintf(buf + ret, PAGE_SIZE - ret,
- " - R%d(0x%x) bit %d",
- w->reg, w->reg, w->shift);
-
- ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
-
- if (w->sname)
- ret += snprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n",
- w->sname,
- w->active ? "active" : "inactive");
-
- list_for_each_entry(p, &w->sources, list_sink) {
- if (p->connected && !p->connected(w, p->sink))
- continue;
-
- if (p->connect)
- ret += snprintf(buf + ret, PAGE_SIZE - ret,
- " in \"%s\" \"%s\"\n",
- p->name ? p->name : "static",
- p->source->name);
- }
- list_for_each_entry(p, &w->sinks, list_source) {
- if (p->connected && !p->connected(w, p->sink))
- continue;
-
- if (p->connect)
- ret += snprintf(buf + ret, PAGE_SIZE - ret,
- " out \"%s\" \"%s\"\n",
- p->name ? p->name : "static",
- p->sink->name);
- }
-
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
-
- kfree(buf);
- return ret;
-}
-
-static const struct file_operations dapm_widget_power_fops = {
- .open = simple_open,
- .read = dapm_widget_power_read_file,
- .llseek = default_llseek,
-};
-
-static ssize_t dapm_bias_read_file(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct snd_soc_dapm_context *dapm = file->private_data;
- char *level;
-
- switch (dapm->bias_level) {
- case SND_SOC_BIAS_ON:
- level = "On\n";
- break;
- case SND_SOC_BIAS_PREPARE:
- level = "Prepare\n";
- break;
- case SND_SOC_BIAS_STANDBY:
- level = "Standby\n";
- break;
- case SND_SOC_BIAS_OFF:
- level = "Off\n";
- break;
- default:
- BUG();
- level = "Unknown\n";
- break;
- }
-
- return simple_read_from_buffer(user_buf, count, ppos, level,
- strlen(level));
-}
-
-static const struct file_operations dapm_bias_fops = {
- .open = simple_open,
- .read = dapm_bias_read_file,
- .llseek = default_llseek,
-};
-
-void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
- struct dentry *parent)
-{
- struct dentry *d;
-
- dapm->debugfs_dapm = debugfs_create_dir("dapm", parent);
-
- if (!dapm->debugfs_dapm) {
- dev_warn(dapm->dev,
- "Failed to create DAPM debugfs directory\n");
- return;
- }
-
- d = debugfs_create_file("bias_level", 0444,
- dapm->debugfs_dapm, dapm,
- &dapm_bias_fops);
- if (!d)
- dev_warn(dapm->dev,
- "ASoC: Failed to create bias level debugfs file\n");
-}
-
-static void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w)
-{
- struct snd_soc_dapm_context *dapm = w->dapm;
- struct dentry *d;
-
- if (!dapm->debugfs_dapm || !w->name)
- return;
-
- d = debugfs_create_file(w->name, 0444,
- dapm->debugfs_dapm, w,
- &dapm_widget_power_fops);
- if (!d)
- dev_warn(w->dapm->dev,
- "ASoC: Failed to create %s debugfs file\n",
- w->name);
-}
-
-static void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
-{
- debugfs_remove_recursive(dapm->debugfs_dapm);
-}
-
-#else
-void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
- struct dentry *parent)
-{
-}
-
-static inline void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w)
-{
-}
-
-static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
-{
-}
-
-#endif
-
-/* test and update the power status of a mux widget */
-int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
- struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e)
-{
- struct snd_soc_dapm_path *path;
- int found = 0;
-
- if (widget->id != snd_soc_dapm_mux &&
- widget->id != snd_soc_dapm_virt_mux &&
- widget->id != snd_soc_dapm_value_mux)
- return -ENODEV;
-
- /* find dapm widget path assoc with kcontrol */
- list_for_each_entry(path, &widget->dapm->card->paths, list) {
- if (path->kcontrol != kcontrol)
- continue;
-
- if (!path->name || !e->texts[mux])
- continue;
-
- found = 1;
- /* we now need to match the string in the enum to the path */
- if (!(strcmp(path->name, e->texts[mux]))) {
- path->connect = 1; /* new connection */
- dapm_mark_dirty(path->source, "mux connection");
- } else {
- if (path->connect)
- dapm_mark_dirty(path->source,
- "mux disconnection");
- path->connect = 0; /* old connection must be powered down */
- }
- }
-
- if (found) {
- dapm_mark_dirty(widget, "mux change");
- dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP);
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_mux_update_power);
-
-/* test and update the power status of a mixer or switch widget */
-int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
- struct snd_kcontrol *kcontrol, int connect)
-{
- struct snd_soc_dapm_path *path;
- int found = 0;
-
- if (widget->id != snd_soc_dapm_mixer &&
- widget->id != snd_soc_dapm_mixer_named_ctl &&
- widget->id != snd_soc_dapm_switch)
- return -ENODEV;
-
- /* find dapm widget path assoc with kcontrol */
- list_for_each_entry(path, &widget->dapm->card->paths, list) {
- if (path->kcontrol != kcontrol)
- continue;
-
- /* found, now check type */
- found = 1;
- path->connect = connect;
- dapm_mark_dirty(path->source, "mixer connection");
- }
-
- if (found) {
- dapm_mark_dirty(widget, "mixer update");
- dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP);
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_mixer_update_power);
-
-/* show dapm widget status in sys fs */
-static ssize_t dapm_widget_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
- struct snd_soc_codec *codec =rtd->codec;
- struct snd_soc_dapm_widget *w;
- int count = 0;
- char *state = "not set";
-
- list_for_each_entry(w, &codec->card->widgets, list) {
- if (w->dapm != &codec->dapm)
- continue;
-
- /* only display widgets that burnm power */
- switch (w->id) {
- case snd_soc_dapm_hp:
- case snd_soc_dapm_mic:
- case snd_soc_dapm_spk:
- case snd_soc_dapm_line:
- case snd_soc_dapm_micbias:
- case snd_soc_dapm_dac:
- case snd_soc_dapm_adc:
- case snd_soc_dapm_pga:
- case snd_soc_dapm_out_drv:
- case snd_soc_dapm_mixer:
- case snd_soc_dapm_mixer_named_ctl:
- case snd_soc_dapm_supply:
- case snd_soc_dapm_regulator_supply:
- if (w->name)
- count += sprintf(buf + count, "%s: %s\n",
- w->name, w->power ? "On":"Off");
- break;
- default:
- break;
- }
- }
-
- switch (codec->dapm.bias_level) {
- case SND_SOC_BIAS_ON:
- state = "On";
- break;
- case SND_SOC_BIAS_PREPARE:
- state = "Prepare";
- break;
- case SND_SOC_BIAS_STANDBY:
- state = "Standby";
- break;
- case SND_SOC_BIAS_OFF:
- state = "Off";
- break;
- }
- count += sprintf(buf + count, "PM State: %s\n", state);
-
- return count;
-}
-
-static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL);
-
-int snd_soc_dapm_sys_add(struct device *dev)
-{
- return device_create_file(dev, &dev_attr_dapm_widget);
-}
-
-static void snd_soc_dapm_sys_remove(struct device *dev)
-{
- device_remove_file(dev, &dev_attr_dapm_widget);
-}
-
-/* free all dapm widgets and resources */
-static void dapm_free_widgets(struct snd_soc_dapm_context *dapm)
-{
- struct snd_soc_dapm_widget *w, *next_w;
- struct snd_soc_dapm_path *p, *next_p;
-
- list_for_each_entry_safe(w, next_w, &dapm->card->widgets, list) {
- if (w->dapm != dapm)
- continue;
- list_del(&w->list);
- /*
- * remove source and sink paths associated to this widget.
- * While removing the path, remove reference to it from both
- * source and sink widgets so that path is removed only once.
- */
- list_for_each_entry_safe(p, next_p, &w->sources, list_sink) {
- list_del(&p->list_sink);
- list_del(&p->list_source);
- list_del(&p->list);
- kfree(p->long_name);
- kfree(p);
- }
- list_for_each_entry_safe(p, next_p, &w->sinks, list_source) {
- list_del(&p->list_sink);
- list_del(&p->list_source);
- list_del(&p->list);
- kfree(p->long_name);
- kfree(p);
- }
- kfree(w->kcontrols);
- kfree(w->name);
- kfree(w);
- }
-}
-
-static struct snd_soc_dapm_widget *dapm_find_widget(
- struct snd_soc_dapm_context *dapm, const char *pin,
- bool search_other_contexts)
-{
- struct snd_soc_dapm_widget *w;
- struct snd_soc_dapm_widget *fallback = NULL;
-
- list_for_each_entry(w, &dapm->card->widgets, list) {
- if (!strcmp(w->name, pin)) {
- if (w->dapm == dapm)
- return w;
- else
- fallback = w;
- }
- }
-
- if (search_other_contexts)
- return fallback;
-
- return NULL;
-}
-
-static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
- const char *pin, int status)
-{
- struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
-
- if (!w) {
- dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
- return -EINVAL;
- }
-
- if (w->connected != status)
- dapm_mark_dirty(w, "pin configuration");
-
- w->connected = status;
- if (status == 0)
- w->force = 0;
-
- return 0;
-}
-
-/**
- * snd_soc_dapm_sync - scan and power dapm paths
- * @dapm: DAPM context
- *
- * Walks all dapm audio paths and powers widgets according to their
- * stream or path usage.
- *
- * Returns 0 for success.
- */
-int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm)
-{
- int ret;
-
- /*
- * Suppress early reports (eg, jacks syncing their state) to avoid
- * silly DAPM runs during card startup.
- */
- if (!dapm->card || !dapm->card->instantiated)
- return 0;
-
- mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_PCM);
- ret = dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
- mutex_unlock(&dapm->card->dapm_mutex);
- return ret;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
-
-static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
- const struct snd_soc_dapm_route *route)
-{
- struct snd_soc_dapm_path *path;
- struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w;
- struct snd_soc_dapm_widget *wtsource = NULL, *wtsink = NULL;
- const char *sink;
- const char *control = route->control;
- const char *source;
- char prefixed_sink[80];
- char prefixed_source[80];
- int ret = 0;
-
- if (dapm->codec && dapm->codec->name_prefix) {
- snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
- dapm->codec->name_prefix, route->sink);
- sink = prefixed_sink;
- snprintf(prefixed_source, sizeof(prefixed_source), "%s %s",
- dapm->codec->name_prefix, route->source);
- source = prefixed_source;
- } else {
- sink = route->sink;
- source = route->source;
- }
-
- /*
- * find src and dest widgets over all widgets but favor a widget from
- * current DAPM context
- */
- list_for_each_entry(w, &dapm->card->widgets, list) {
- if (!wsink && !(strcmp(w->name, sink))) {
- wtsink = w;
- if (w->dapm == dapm)
- wsink = w;
- continue;
- }
- if (!wsource && !(strcmp(w->name, source))) {
- wtsource = w;
- if (w->dapm == dapm)
- wsource = w;
- }
- }
- /* use widget from another DAPM context if not found from this */
- if (!wsink)
- wsink = wtsink;
- if (!wsource)
- wsource = wtsource;
-
- if (wsource == NULL || wsink == NULL)
- return -ENODEV;
-
- path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL);
- if (!path)
- return -ENOMEM;
-
- path->source = wsource;
- path->sink = wsink;
- path->connected = route->connected;
- INIT_LIST_HEAD(&path->list);
- INIT_LIST_HEAD(&path->list_source);
- INIT_LIST_HEAD(&path->list_sink);
-
- /* check for external widgets */
- if (wsink->id == snd_soc_dapm_input) {
- if (wsource->id == snd_soc_dapm_micbias ||
- wsource->id == snd_soc_dapm_mic ||
- wsource->id == snd_soc_dapm_line ||
- wsource->id == snd_soc_dapm_output)
- wsink->ext = 1;
- }
- if (wsource->id == snd_soc_dapm_output) {
- if (wsink->id == snd_soc_dapm_spk ||
- wsink->id == snd_soc_dapm_hp ||
- wsink->id == snd_soc_dapm_line ||
- wsink->id == snd_soc_dapm_input)
- wsource->ext = 1;
- }
-
- /* connect static paths */
- if (control == NULL) {
- list_add(&path->list, &dapm->card->paths);
- list_add(&path->list_sink, &wsink->sources);
- list_add(&path->list_source, &wsource->sinks);
- path->connect = 1;
- return 0;
- }
-
- /* connect dynamic paths */
- switch (wsink->id) {
- case snd_soc_dapm_adc:
- case snd_soc_dapm_dac:
- case snd_soc_dapm_pga:
- case snd_soc_dapm_out_drv:
- case snd_soc_dapm_input:
- case snd_soc_dapm_output:
- case snd_soc_dapm_siggen:
- case snd_soc_dapm_micbias:
- case snd_soc_dapm_vmid:
- case snd_soc_dapm_pre:
- case snd_soc_dapm_post:
- case snd_soc_dapm_supply:
- case snd_soc_dapm_regulator_supply:
- case snd_soc_dapm_aif_in:
- case snd_soc_dapm_aif_out:
- case snd_soc_dapm_dai:
- list_add(&path->list, &dapm->card->paths);
- list_add(&path->list_sink, &wsink->sources);
- list_add(&path->list_source, &wsource->sinks);
- path->connect = 1;
- return 0;
- case snd_soc_dapm_mux:
- case snd_soc_dapm_virt_mux:
- case snd_soc_dapm_value_mux:
- ret = dapm_connect_mux(dapm, wsource, wsink, path, control,
- &wsink->kcontrol_news[0]);
- if (ret != 0)
- goto err;
- break;
- case snd_soc_dapm_switch:
- case snd_soc_dapm_mixer:
- case snd_soc_dapm_mixer_named_ctl:
- ret = dapm_connect_mixer(dapm, wsource, wsink, path, control);
- if (ret != 0)
- goto err;
- break;
- case snd_soc_dapm_hp:
- case snd_soc_dapm_mic:
- case snd_soc_dapm_line:
- case snd_soc_dapm_spk:
- list_add(&path->list, &dapm->card->paths);
- list_add(&path->list_sink, &wsink->sources);
- list_add(&path->list_source, &wsource->sinks);
- path->connect = 0;
- return 0;
- }
- return 0;
-
-err:
- dev_warn(dapm->dev, "asoc: no dapm match for %s --> %s --> %s\n",
- source, control, sink);
- kfree(path);
- return ret;
-}
-
-/**
- * snd_soc_dapm_add_routes - Add routes between DAPM widgets
- * @dapm: DAPM context
- * @route: audio routes
- * @num: number of routes
- *
- * Connects 2 dapm widgets together via a named audio path. The sink is
- * the widget receiving the audio signal, whilst the source is the sender
- * of the audio signal.
- *
- * Returns 0 for success else error. On error all resources can be freed
- * with a call to snd_soc_card_free().
- */
-int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
- const struct snd_soc_dapm_route *route, int num)
-{
- int i, ret = 0;
-
- mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
- for (i = 0; i < num; i++) {
- ret = snd_soc_dapm_add_route(dapm, route);
- if (ret < 0) {
- dev_err(dapm->dev, "Failed to add route %s->%s\n",
- route->source, route->sink);
- break;
- }
- route++;
- }
- mutex_unlock(&dapm->card->dapm_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes);
-
-static int snd_soc_dapm_weak_route(struct snd_soc_dapm_context *dapm,
- const struct snd_soc_dapm_route *route)
-{
- struct snd_soc_dapm_widget *source = dapm_find_widget(dapm,
- route->source,
- true);
- struct snd_soc_dapm_widget *sink = dapm_find_widget(dapm,
- route->sink,
- true);
- struct snd_soc_dapm_path *path;
- int count = 0;
-
- if (!source) {
- dev_err(dapm->dev, "Unable to find source %s for weak route\n",
- route->source);
- return -ENODEV;
- }
-
- if (!sink) {
- dev_err(dapm->dev, "Unable to find sink %s for weak route\n",
- route->sink);
- return -ENODEV;
- }
-
- if (route->control || route->connected)
- dev_warn(dapm->dev, "Ignoring control for weak route %s->%s\n",
- route->source, route->sink);
-
- list_for_each_entry(path, &source->sinks, list_source) {
- if (path->sink == sink) {
- path->weak = 1;
- count++;
- }
- }
-
- if (count == 0)
- dev_err(dapm->dev, "No path found for weak route %s->%s\n",
- route->source, route->sink);
- if (count > 1)
- dev_warn(dapm->dev, "%d paths found for weak route %s->%s\n",
- count, route->source, route->sink);
-
- return 0;
-}
-
-/**
- * snd_soc_dapm_weak_routes - Mark routes between DAPM widgets as weak
- * @dapm: DAPM context
- * @route: audio routes
- * @num: number of routes
- *
- * Mark existing routes matching those specified in the passed array
- * as being weak, meaning that they are ignored for the purpose of
- * power decisions. The main intended use case is for sidetone paths
- * which couple audio between other independent paths if they are both
- * active in order to make the combination work better at the user
- * level but which aren't intended to be "used".
- *
- * Note that CODEC drivers should not use this as sidetone type paths
- * can frequently also be used as bypass paths.
- */
-int snd_soc_dapm_weak_routes(struct snd_soc_dapm_context *dapm,
- const struct snd_soc_dapm_route *route, int num)
-{
- int i, err;
- int ret = 0;
-
- mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
- for (i = 0; i < num; i++) {
- err = snd_soc_dapm_weak_route(dapm, route);
- if (err)
- ret = err;
- route++;
- }
- mutex_unlock(&dapm->card->dapm_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_weak_routes);
-
-/**
- * snd_soc_dapm_new_widgets - add new dapm widgets
- * @dapm: DAPM context
- *
- * Checks the codec for any new dapm widgets and creates them if found.
- *
- * Returns 0 for success.
- */
-int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
-{
- struct snd_soc_dapm_widget *w;
- unsigned int val;
-
- mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
-
- list_for_each_entry(w, &dapm->card->widgets, list)
- {
- if (w->new)
- continue;
-
- if (w->num_kcontrols) {
- w->kcontrols = kzalloc(w->num_kcontrols *
- sizeof(struct snd_kcontrol *),
- GFP_KERNEL);
- if (!w->kcontrols) {
- mutex_unlock(&dapm->card->dapm_mutex);
- return -ENOMEM;
- }
- }
-
- switch(w->id) {
- case snd_soc_dapm_switch:
- case snd_soc_dapm_mixer:
- case snd_soc_dapm_mixer_named_ctl:
- dapm_new_mixer(w);
- break;
- case snd_soc_dapm_mux:
- case snd_soc_dapm_virt_mux:
- case snd_soc_dapm_value_mux:
- dapm_new_mux(w);
- break;
- case snd_soc_dapm_pga:
- case snd_soc_dapm_out_drv:
- dapm_new_pga(w);
- break;
- default:
- break;
- }
-
- /* Read the initial power state from the device */
- if (w->reg >= 0) {
- val = soc_widget_read(w, w->reg);
- val &= 1 << w->shift;
- if (w->invert)
- val = !val;
-
- if (val)
- w->power = 1;
- }
-
- w->new = 1;
-
- dapm_mark_dirty(w, "new widget");
- dapm_debugfs_add_widget(w);
- }
-
- dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
- mutex_unlock(&dapm->card->dapm_mutex);
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
-
-/**
- * snd_soc_dapm_get_volsw - dapm mixer get callback
- * @kcontrol: mixer control
- * @ucontrol: control element information
- *
- * Callback to get the value of a dapm mixer control.
- *
- * Returns 0 for success.
- */
-int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
- struct snd_soc_dapm_widget *widget = wlist->widgets[0];
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- unsigned int reg = mc->reg;
- unsigned int shift = mc->shift;
- unsigned int rshift = mc->rshift;
- int max = mc->max;
- unsigned int invert = mc->invert;
- unsigned int mask = (1 << fls(max)) - 1;
-
- ucontrol->value.integer.value[0] =
- (snd_soc_read(widget->codec, reg) >> shift) & mask;
- if (shift != rshift)
- ucontrol->value.integer.value[1] =
- (snd_soc_read(widget->codec, reg) >> rshift) & mask;
- if (invert) {
- ucontrol->value.integer.value[0] =
- max - ucontrol->value.integer.value[0];
- if (shift != rshift)
- ucontrol->value.integer.value[1] =
- max - ucontrol->value.integer.value[1];
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw);
-
-/**
- * snd_soc_dapm_put_volsw - dapm mixer set callback
- * @kcontrol: mixer control
- * @ucontrol: control element information
- *
- * Callback to set the value of a dapm mixer control.
- *
- * Returns 0 for success.
- */
-int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
- struct snd_soc_dapm_widget *widget = wlist->widgets[0];
- struct snd_soc_codec *codec = widget->codec;
- struct snd_soc_card *card = codec->card;
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
- unsigned int reg = mc->reg;
- unsigned int shift = mc->shift;
- int max = mc->max;
- unsigned int mask = (1 << fls(max)) - 1;
- unsigned int invert = mc->invert;
- unsigned int val;
- int connect, change;
- struct snd_soc_dapm_update update;
- int wi;
-
- val = (ucontrol->value.integer.value[0] & mask);
-
- if (invert)
- val = max - val;
- mask = mask << shift;
- val = val << shift;
-
- if (val)
- /* new connection */
- connect = invert ? 0 : 1;
- else
- /* old connection must be powered down */
- connect = invert ? 1 : 0;
-
- mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_PCM);
-
- change = snd_soc_test_bits(widget->codec, reg, mask, val);
- if (change) {
- for (wi = 0; wi < wlist->num_widgets; wi++) {
- widget = wlist->widgets[wi];
-
- widget->value = val;
-
- update.kcontrol = kcontrol;
- update.widget = widget;
- update.reg = reg;
- update.mask = mask;
- update.val = val;
- widget->dapm->update = &update;
-
- snd_soc_dapm_mixer_update_power(widget, kcontrol, connect);
-
- widget->dapm->update = NULL;
- }
- }
-
- mutex_unlock(&card->dapm_mutex);
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw);
-
-/**
- * snd_soc_dapm_get_enum_double - dapm enumerated double mixer get callback
- * @kcontrol: mixer control
- * @ucontrol: control element information
- *
- * Callback to get the value of a dapm enumerated double mixer control.
- *
- * Returns 0 for success.
- */
-int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
- struct snd_soc_dapm_widget *widget = wlist->widgets[0];
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int val, bitmask;
-
- for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
- ;
- val = snd_soc_read(widget->codec, e->reg);
- ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1);
- if (e->shift_l != e->shift_r)
- ucontrol->value.enumerated.item[1] =
- (val >> e->shift_r) & (bitmask - 1);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double);
-
-/**
- * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback
- * @kcontrol: mixer control
- * @ucontrol: control element information
- *
- * Callback to set the value of a dapm enumerated double mixer control.
- *
- * Returns 0 for success.
- */
-int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
- struct snd_soc_dapm_widget *widget = wlist->widgets[0];
- struct snd_soc_codec *codec = widget->codec;
- struct snd_soc_card *card = codec->card;
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int val, mux, change;
- unsigned int mask, bitmask;
- struct snd_soc_dapm_update update;
- int wi;
-
- for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
- ;
- if (ucontrol->value.enumerated.item[0] > e->max - 1)
- return -EINVAL;
- mux = ucontrol->value.enumerated.item[0];
- val = mux << e->shift_l;
- mask = (bitmask - 1) << e->shift_l;
- if (e->shift_l != e->shift_r) {
- if (ucontrol->value.enumerated.item[1] > e->max - 1)
- return -EINVAL;
- val |= ucontrol->value.enumerated.item[1] << e->shift_r;
- mask |= (bitmask - 1) << e->shift_r;
- }
-
- mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_PCM);
-
- change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
- if (change) {
- for (wi = 0; wi < wlist->num_widgets; wi++) {
- widget = wlist->widgets[wi];
-
- widget->value = val;
-
- update.kcontrol = kcontrol;
- update.widget = widget;
- update.reg = e->reg;
- update.mask = mask;
- update.val = val;
- widget->dapm->update = &update;
-
- snd_soc_dapm_mux_update_power(widget, kcontrol, mux, e);
-
- widget->dapm->update = NULL;
- }
- }
-
- mutex_unlock(&card->dapm_mutex);
- return change;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
-
-/**
- * snd_soc_dapm_get_enum_virt - Get virtual DAPM mux
- * @kcontrol: mixer control
- * @ucontrol: control element information
- *
- * Returns 0 for success.
- */
-int snd_soc_dapm_get_enum_virt(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
- struct snd_soc_dapm_widget *widget = wlist->widgets[0];
-
- ucontrol->value.enumerated.item[0] = widget->value;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_virt);
-
-/**
- * snd_soc_dapm_put_enum_virt - Set virtual DAPM mux
- * @kcontrol: mixer control
- * @ucontrol: control element information
- *
- * Returns 0 for success.
- */
-int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
- struct snd_soc_dapm_widget *widget = wlist->widgets[0];
- struct snd_soc_codec *codec = widget->codec;
- struct snd_soc_card *card = codec->card;
- struct soc_enum *e =
- (struct soc_enum *)kcontrol->private_value;
- int change;
- int ret = 0;
- int wi;
-
- if (ucontrol->value.enumerated.item[0] >= e->max)
- return -EINVAL;
-
- mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_PCM);
-
- change = widget->value != ucontrol->value.enumerated.item[0];
- if (change) {
- for (wi = 0; wi < wlist->num_widgets; wi++) {
- widget = wlist->widgets[wi];
-
- widget->value = ucontrol->value.enumerated.item[0];
-
- snd_soc_dapm_mux_update_power(widget, kcontrol, widget->value, e);
- }
- }
-
- mutex_unlock(&card->dapm_mutex);
- return ret;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt);
-
-/**
- * snd_soc_dapm_get_value_enum_double - dapm semi enumerated double mixer get
- * callback
- * @kcontrol: mixer control
- * @ucontrol: control element information
- *
- * Callback to get the value of a dapm semi enumerated double mixer control.
- *
- * Semi enumerated mixer: the enumerated items are referred as values. Can be
- * used for handling bitfield coded enumeration for example.
- *
- * Returns 0 for success.
- */
-int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
- struct snd_soc_dapm_widget *widget = wlist->widgets[0];
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int reg_val, val, mux;
-
- reg_val = snd_soc_read(widget->codec, e->reg);
- val = (reg_val >> e->shift_l) & e->mask;
- for (mux = 0; mux < e->max; mux++) {
- if (val == e->values[mux])
- break;
- }
- ucontrol->value.enumerated.item[0] = mux;
- if (e->shift_l != e->shift_r) {
- val = (reg_val >> e->shift_r) & e->mask;
- for (mux = 0; mux < e->max; mux++) {
- if (val == e->values[mux])
- break;
- }
- ucontrol->value.enumerated.item[1] = mux;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_get_value_enum_double);
-
-/**
- * snd_soc_dapm_put_value_enum_double - dapm semi enumerated double mixer set
- * callback
- * @kcontrol: mixer control
- * @ucontrol: control element information
- *
- * Callback to set the value of a dapm semi enumerated double mixer control.
- *
- * Semi enumerated mixer: the enumerated items are referred as values. Can be
- * used for handling bitfield coded enumeration for example.
- *
- * Returns 0 for success.
- */
-int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
- struct snd_soc_dapm_widget *widget = wlist->widgets[0];
- struct snd_soc_codec *codec = widget->codec;
- struct snd_soc_card *card = codec->card;
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int val, mux, change;
- unsigned int mask;
- struct snd_soc_dapm_update update;
- int wi;
-
- if (ucontrol->value.enumerated.item[0] > e->max - 1)
- return -EINVAL;
- mux = ucontrol->value.enumerated.item[0];
- val = e->values[ucontrol->value.enumerated.item[0]] << e->shift_l;
- mask = e->mask << e->shift_l;
- if (e->shift_l != e->shift_r) {
- if (ucontrol->value.enumerated.item[1] > e->max - 1)
- return -EINVAL;
- val |= e->values[ucontrol->value.enumerated.item[1]] << e->shift_r;
- mask |= e->mask << e->shift_r;
- }
-
- mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_PCM);
-
- change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
- if (change) {
- for (wi = 0; wi < wlist->num_widgets; wi++) {
- widget = wlist->widgets[wi];
-
- widget->value = val;
-
- update.kcontrol = kcontrol;
- update.widget = widget;
- update.reg = e->reg;
- update.mask = mask;
- update.val = val;
- widget->dapm->update = &update;
-
- snd_soc_dapm_mux_update_power(widget, kcontrol, mux, e);
-
- widget->dapm->update = NULL;
- }
- }
-
- mutex_unlock(&card->dapm_mutex);
- return change;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double);
-
-/**
- * snd_soc_dapm_info_pin_switch - Info for a pin switch
- *
- * @kcontrol: mixer control
- * @uinfo: control element information
- *
- * Callback to provide information about a pin switch control.
- */
-int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_info_pin_switch);
-
-/**
- * snd_soc_dapm_get_pin_switch - Get information for a pin switch
- *
- * @kcontrol: mixer control
- * @ucontrol: Value
- */
-int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
- const char *pin = (const char *)kcontrol->private_value;
-
- mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_PCM);
-
- ucontrol->value.integer.value[0] =
- snd_soc_dapm_get_pin_status(&card->dapm, pin);
-
- mutex_unlock(&card->dapm_mutex);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_switch);
-
-/**
- * snd_soc_dapm_put_pin_switch - Set information for a pin switch
- *
- * @kcontrol: mixer control
- * @ucontrol: Value
- */
-int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
- const char *pin = (const char *)kcontrol->private_value;
-
- mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_PCM);
-
- if (ucontrol->value.integer.value[0])
- snd_soc_dapm_enable_pin(&card->dapm, pin);
- else
- snd_soc_dapm_disable_pin(&card->dapm, pin);
-
- mutex_unlock(&card->dapm_mutex);
-
- snd_soc_dapm_sync(&card->dapm);
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch);
-
-static struct snd_soc_dapm_widget *
-snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
- const struct snd_soc_dapm_widget *widget)
-{
- struct snd_soc_dapm_widget *w;
- size_t name_len;
- int ret;
-
- if ((w = dapm_cnew_widget(widget)) == NULL)
- return NULL;
-
- switch (w->id) {
- case snd_soc_dapm_regulator_supply:
- w->priv = devm_regulator_get(dapm->dev, w->name);
- if (IS_ERR(w->priv)) {
- ret = PTR_ERR(w->priv);
- dev_err(dapm->dev, "Failed to request %s: %d\n",
- w->name, ret);
- return NULL;
- }
- break;
- default:
- break;
- }
-
- name_len = strlen(widget->name) + 1;
- if (dapm->codec && dapm->codec->name_prefix)
- name_len += 1 + strlen(dapm->codec->name_prefix);
- w->name = kmalloc(name_len, GFP_KERNEL);
- if (w->name == NULL) {
- kfree(w);
- return NULL;
- }
- if (dapm->codec && dapm->codec->name_prefix)
- snprintf((char *)w->name, name_len, "%s %s",
- dapm->codec->name_prefix, widget->name);
- else
- snprintf((char *)w->name, name_len, "%s", widget->name);
-
- switch (w->id) {
- case snd_soc_dapm_switch:
- case snd_soc_dapm_mixer:
- case snd_soc_dapm_mixer_named_ctl:
- w->power_check = dapm_generic_check_power;
- break;
- case snd_soc_dapm_mux:
- case snd_soc_dapm_virt_mux:
- case snd_soc_dapm_value_mux:
- w->power_check = dapm_generic_check_power;
- break;
- case snd_soc_dapm_adc:
- case snd_soc_dapm_aif_out:
- w->power_check = dapm_adc_check_power;
- break;
- case snd_soc_dapm_dac:
- case snd_soc_dapm_aif_in:
- w->power_check = dapm_dac_check_power;
- break;
- case snd_soc_dapm_pga:
- case snd_soc_dapm_out_drv:
- case snd_soc_dapm_input:
- case snd_soc_dapm_output:
- case snd_soc_dapm_micbias:
- case snd_soc_dapm_spk:
- case snd_soc_dapm_hp:
- case snd_soc_dapm_mic:
- case snd_soc_dapm_line:
- w->power_check = dapm_generic_check_power;
- break;
- case snd_soc_dapm_supply:
- case snd_soc_dapm_regulator_supply:
- w->power_check = dapm_supply_check_power;
- break;
- case snd_soc_dapm_dai:
- w->power_check = dapm_dai_check_power;
- break;
- default:
- w->power_check = dapm_always_on_check_power;
- break;
- }
-
- dapm->n_widgets++;
- w->dapm = dapm;
- w->codec = dapm->codec;
- w->platform = dapm->platform;
- INIT_LIST_HEAD(&w->sources);
- INIT_LIST_HEAD(&w->sinks);
- INIT_LIST_HEAD(&w->list);
- INIT_LIST_HEAD(&w->dirty);
- list_add(&w->list, &dapm->card->widgets);
-
- /* machine layer set ups unconnected pins and insertions */
- w->connected = 1;
- return w;
-}
-
-/**
- * snd_soc_dapm_new_controls - create new dapm controls
- * @dapm: DAPM context
- * @widget: widget array
- * @num: number of widgets
- *
- * Creates new DAPM controls based upon the templates.
- *
- * Returns 0 for success else error.
- */
-int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
- const struct snd_soc_dapm_widget *widget,
- int num)
-{
- struct snd_soc_dapm_widget *w;
- int i;
- int ret = 0;
-
- mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
- for (i = 0; i < num; i++) {
- w = snd_soc_dapm_new_control(dapm, widget);
- if (!w) {
- dev_err(dapm->dev,
- "ASoC: Failed to create DAPM control %s\n",
- widget->name);
- ret = -ENOMEM;
- break;
- }
- widget++;
- }
- mutex_unlock(&dapm->card->dapm_mutex);
- return ret;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
-
-int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_dapm_widget template;
- struct snd_soc_dapm_widget *w;
-
- WARN_ON(dapm->dev != dai->dev);
-
- memset(&template, 0, sizeof(template));
- template.reg = SND_SOC_NOPM;
-
- if (dai->driver->playback.stream_name) {
- template.id = snd_soc_dapm_dai;
- template.name = dai->driver->playback.stream_name;
- template.sname = dai->driver->playback.stream_name;
-
- dev_dbg(dai->dev, "adding %s widget\n",
- template.name);
-
- w = snd_soc_dapm_new_control(dapm, &template);
- if (!w) {
- dev_err(dapm->dev, "Failed to create %s widget\n",
- dai->driver->playback.stream_name);
- }
-
- w->priv = dai;
- dai->playback_widget = w;
- }
-
- if (dai->driver->capture.stream_name) {
- template.id = snd_soc_dapm_dai;
- template.name = dai->driver->capture.stream_name;
- template.sname = dai->driver->capture.stream_name;
-
- dev_dbg(dai->dev, "adding %s widget\n",
- template.name);
-
- w = snd_soc_dapm_new_control(dapm, &template);
- if (!w) {
- dev_err(dapm->dev, "Failed to create %s widget\n",
- dai->driver->capture.stream_name);
- }
-
- w->priv = dai;
- dai->capture_widget = w;
- }
-
- return 0;
-}
-
-int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
-{
- struct snd_soc_dapm_widget *dai_w, *w;
- struct snd_soc_dai *dai;
- struct snd_soc_dapm_route r;
-
- memset(&r, 0, sizeof(r));
-
- /* For each DAI widget... */
- list_for_each_entry(dai_w, &card->widgets, list) {
- if (dai_w->id != snd_soc_dapm_dai)
- continue;
-
- dai = dai_w->priv;
-
- /* ...find all widgets with the same stream and link them */
- list_for_each_entry(w, &card->widgets, list) {
- if (w->dapm != dai_w->dapm)
- continue;
-
- if (w->id == snd_soc_dapm_dai)
- continue;
-
- if (!w->sname)
- continue;
-
- if (dai->driver->playback.stream_name &&
- strstr(w->sname,
- dai->driver->playback.stream_name)) {
- r.source = dai->playback_widget->name;
- r.sink = w->name;
- dev_dbg(dai->dev, "%s -> %s\n",
- r.source, r.sink);
-
- snd_soc_dapm_add_route(w->dapm, &r);
- }
-
- if (dai->driver->capture.stream_name &&
- strstr(w->sname,
- dai->driver->capture.stream_name)) {
- r.source = w->name;
- r.sink = dai->capture_widget->name;
- dev_dbg(dai->dev, "%s -> %s\n",
- r.source, r.sink);
-
- snd_soc_dapm_add_route(w->dapm, &r);
- }
- }
- }
-
- return 0;
-}
-
-static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
- int stream, struct snd_soc_dai *dai,
- int event)
-{
- struct snd_soc_dapm_widget *w;
-
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
- w = dai->playback_widget;
- else
- w = dai->capture_widget;
-
- if (!w)
- return;
-
- dapm_mark_dirty(w, "stream event");
-
- switch (event) {
- case SND_SOC_DAPM_STREAM_START:
- w->active = 1;
- break;
- case SND_SOC_DAPM_STREAM_STOP:
- w->active = 0;
- break;
- case SND_SOC_DAPM_STREAM_SUSPEND:
- case SND_SOC_DAPM_STREAM_RESUME:
- case SND_SOC_DAPM_STREAM_PAUSE_PUSH:
- case SND_SOC_DAPM_STREAM_PAUSE_RELEASE:
- break;
- }
-
- dapm_power_widgets(dapm, event);
-}
-
-/**
- * snd_soc_dapm_stream_event - send a stream event to the dapm core
- * @rtd: PCM runtime data
- * @stream: stream name
- * @event: stream event
- *
- * Sends a stream event to the dapm core. The core then makes any
- * necessary widget power changes.
- *
- * Returns 0 for success else error.
- */
-int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
- struct snd_soc_dai *dai, int event)
-{
- struct snd_soc_card *card = rtd->card;
-
- mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_PCM);
- soc_dapm_stream_event(&card->dapm, stream, dai, event);
- mutex_unlock(&card->dapm_mutex);
- return 0;
-}
-
-/**
- * snd_soc_dapm_enable_pin - enable pin.
- * @dapm: DAPM context
- * @pin: pin name
- *
- * Enables input/output pin and its parents or children widgets iff there is
- * a valid audio route and active audio stream.
- * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
- * do any widget power switching.
- */
-int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin)
-{
- return snd_soc_dapm_set_pin(dapm, pin, 1);
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
-
-/**
- * snd_soc_dapm_force_enable_pin - force a pin to be enabled
- * @dapm: DAPM context
- * @pin: pin name
- *
- * Enables input/output pin regardless of any other state. This is
- * intended for use with microphone bias supplies used in microphone
- * jack detection.
- *
- * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
- * do any widget power switching.
- */
-int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
- const char *pin)
-{
- struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
-
- if (!w) {
- dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
- return -EINVAL;
- }
-
- dev_dbg(w->dapm->dev, "dapm: force enable pin %s\n", pin);
- w->connected = 1;
- w->force = 1;
- dapm_mark_dirty(w, "force enable");
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin);
-
-/**
- * snd_soc_dapm_disable_pin - disable pin.
- * @dapm: DAPM context
- * @pin: pin name
- *
- * Disables input/output pin and its parents or children widgets.
- * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
- * do any widget power switching.
- */
-int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm,
- const char *pin)
-{
- return snd_soc_dapm_set_pin(dapm, pin, 0);
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
-
-/**
- * snd_soc_dapm_nc_pin - permanently disable pin.
- * @dapm: DAPM context
- * @pin: pin name
- *
- * Marks the specified pin as being not connected, disabling it along
- * any parent or child widgets. At present this is identical to
- * snd_soc_dapm_disable_pin() but in future it will be extended to do
- * additional things such as disabling controls which only affect
- * paths through the pin.
- *
- * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
- * do any widget power switching.
- */
-int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin)
-{
- return snd_soc_dapm_set_pin(dapm, pin, 0);
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin);
-
-/**
- * snd_soc_dapm_get_pin_status - get audio pin status
- * @dapm: DAPM context
- * @pin: audio signal pin endpoint (or start point)
- *
- * Get audio pin status - connected or disconnected.
- *
- * Returns 1 for connected otherwise 0.
- */
-int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm,
- const char *pin)
-{
- struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
-
- if (w)
- return w->connected;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status);
-
-/**
- * snd_soc_dapm_ignore_suspend - ignore suspend status for DAPM endpoint
- * @dapm: DAPM context
- * @pin: audio signal pin endpoint (or start point)
- *
- * Mark the given endpoint or pin as ignoring suspend. When the
- * system is disabled a path between two endpoints flagged as ignoring
- * suspend will not be disabled. The path must already be enabled via
- * normal means at suspend time, it will not be turned on if it was not
- * already enabled.
- */
-int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
- const char *pin)
-{
- struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, false);
-
- if (!w) {
- dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
- return -EINVAL;
- }
-
- w->ignore_suspend = 1;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
-
-static bool snd_soc_dapm_widget_in_card_paths(struct snd_soc_card *card,
- struct snd_soc_dapm_widget *w)
-{
- struct snd_soc_dapm_path *p;
-
- list_for_each_entry(p, &card->paths, list) {
- if ((p->source == w) || (p->sink == w)) {
- dev_dbg(card->dev,
- "... Path %s(id:%d dapm:%p) - %s(id:%d dapm:%p)\n",
- p->source->name, p->source->id, p->source->dapm,
- p->sink->name, p->sink->id, p->sink->dapm);
-
- /* Connected to something other than the codec */
- if (p->source->dapm != p->sink->dapm)
- return true;
- /*
- * Loopback connection from codec external pin to
- * codec external pin
- */
- if (p->sink->id == snd_soc_dapm_input) {
- switch (p->source->id) {
- case snd_soc_dapm_output:
- case snd_soc_dapm_micbias:
- return true;
- default:
- break;
- }
- }
- }
- }
-
- return false;
-}
-
-/**
- * snd_soc_dapm_auto_nc_codec_pins - call snd_soc_dapm_nc_pin for unused pins
- * @codec: The codec whose pins should be processed
- *
- * Automatically call snd_soc_dapm_nc_pin() for any external pins in the codec
- * which are unused. Pins are used if they are connected externally to the
- * codec, whether that be to some other device, or a loop-back connection to
- * the codec itself.
- */
-void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec)
-{
- struct snd_soc_card *card = codec->card;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- struct snd_soc_dapm_widget *w;
-
- dev_dbg(codec->dev, "Auto NC: DAPMs: card:%p codec:%p\n",
- &card->dapm, &codec->dapm);
-
- list_for_each_entry(w, &card->widgets, list) {
- if (w->dapm != dapm)
- continue;
- switch (w->id) {
- case snd_soc_dapm_input:
- case snd_soc_dapm_output:
- case snd_soc_dapm_micbias:
- dev_dbg(codec->dev, "Auto NC: Checking widget %s\n",
- w->name);
- if (!snd_soc_dapm_widget_in_card_paths(card, w)) {
- dev_dbg(codec->dev,
- "... Not in map; disabling\n");
- snd_soc_dapm_nc_pin(dapm, w->name);
- }
- break;
- default:
- break;
- }
- }
-}
-
-/**
- * snd_soc_dapm_free - free dapm resources
- * @dapm: DAPM context
- *
- * Free all dapm widgets and resources.
- */
-void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm)
-{
- snd_soc_dapm_sys_remove(dapm->dev);
- dapm_debugfs_cleanup(dapm);
- dapm_free_widgets(dapm);
- list_del(&dapm->list);
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
-
-static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
-{
- struct snd_soc_dapm_widget *w;
- LIST_HEAD(down_list);
- int powerdown = 0;
-
- list_for_each_entry(w, &dapm->card->widgets, list) {
- if (w->dapm != dapm)
- continue;
- if (w->power) {
- dapm_seq_insert(w, &down_list, false);
- w->power = 0;
- powerdown = 1;
- }
- }
-
- /* If there were no widgets to power down we're already in
- * standby.
- */
- if (powerdown) {
- if (dapm->bias_level == SND_SOC_BIAS_ON)
- snd_soc_dapm_set_bias_level(dapm,
- SND_SOC_BIAS_PREPARE);
- dapm_seq_run(dapm, &down_list, 0, false);
- if (dapm->bias_level == SND_SOC_BIAS_PREPARE)
- snd_soc_dapm_set_bias_level(dapm,
- SND_SOC_BIAS_STANDBY);
- }
-}
-
-/*
- * snd_soc_dapm_shutdown - callback for system shutdown
- */
-void snd_soc_dapm_shutdown(struct snd_soc_card *card)
-{
- struct snd_soc_codec *codec;
-
- list_for_each_entry(codec, &card->codec_dev_list, card_list) {
- soc_dapm_shutdown_codec(&codec->dapm);
- if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY)
- snd_soc_dapm_set_bias_level(&codec->dapm,
- SND_SOC_BIAS_OFF);
- }
-}
-
-/* Module information */
-MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
-MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/soc-dmaengine-pcm.c b/ANDROID_3.4.5/sound/soc/soc-dmaengine-pcm.c
deleted file mode 100644
index 47569523..00000000
--- a/ANDROID_3.4.5/sound/soc/soc-dmaengine-pcm.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2012, Analog Devices Inc.
- * Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- * Based on:
- * imx-pcm-dma-mx2.c, Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
- * mxs-pcm.c, Copyright (C) 2011 Freescale Semiconductor, Inc.
- * ep93xx-pcm.c, Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
- * Copyright (C) 2006 Applied Data Systems
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/dmaengine.h>
-#include <linux/slab.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <sound/dmaengine_pcm.h>
-
-struct dmaengine_pcm_runtime_data {
- struct dma_chan *dma_chan;
-
- unsigned int pos;
-
- void *data;
-};
-
-static inline struct dmaengine_pcm_runtime_data *substream_to_prtd(
- const struct snd_pcm_substream *substream)
-{
- return substream->runtime->private_data;
-}
-
-/**
- * snd_dmaengine_pcm_set_data - Set dmaengine substream private data
- * @substream: PCM substream
- * @data: Data to set
- */
-void snd_dmaengine_pcm_set_data(struct snd_pcm_substream *substream, void *data)
-{
- struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
-
- prtd->data = data;
-}
-EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_data);
-
-/**
- * snd_dmaengine_pcm_get_data - Get dmaeinge substream private data
- * @substream: PCM substream
- *
- * Returns the data previously set with snd_dmaengine_pcm_set_data
- */
-void *snd_dmaengine_pcm_get_data(struct snd_pcm_substream *substream)
-{
- struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
-
- return prtd->data;
-}
-EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_get_data);
-
-struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream)
-{
- struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
-
- return prtd->dma_chan;
-}
-EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_get_chan);
-
-/**
- * snd_hwparams_to_dma_slave_config - Convert hw_params to dma_slave_config
- * @substream: PCM substream
- * @params: hw_params
- * @slave_config: DMA slave config
- *
- * This function can be used to initialize a dma_slave_config from a substream
- * and hw_params in a dmaengine based PCM driver implementation.
- */
-int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
- const struct snd_pcm_hw_params *params,
- struct dma_slave_config *slave_config)
-{
- enum dma_slave_buswidth buswidth;
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S8:
- buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
- break;
- case SNDRV_PCM_FORMAT_S18_3LE:
- case SNDRV_PCM_FORMAT_S20_3LE:
- case SNDRV_PCM_FORMAT_S24_LE:
- case SNDRV_PCM_FORMAT_S32_LE:
- buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
- break;
- default:
- return -EINVAL;
- }
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- slave_config->direction = DMA_MEM_TO_DEV;
- slave_config->dst_addr_width = buswidth;
- } else {
- slave_config->direction = DMA_DEV_TO_MEM;
- slave_config->src_addr_width = buswidth;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config);
-
-static void dmaengine_pcm_dma_complete(void *arg)
-{
- struct snd_pcm_substream *substream = arg;
- struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
-
- prtd->pos += snd_pcm_lib_period_bytes(substream);
- if (prtd->pos >= snd_pcm_lib_buffer_bytes(substream))
- prtd->pos = 0;
-
- snd_pcm_period_elapsed(substream);
-}
-
-static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
-{
- struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
- struct dma_chan *chan = prtd->dma_chan;
- struct dma_async_tx_descriptor *desc;
- enum dma_transfer_direction direction;
-
- direction = snd_pcm_substream_to_dma_direction(substream);
-
- prtd->pos = 0;
- desc = dmaengine_prep_dma_cyclic(chan,
- substream->runtime->dma_addr,
- snd_pcm_lib_buffer_bytes(substream),
- snd_pcm_lib_period_bytes(substream), direction);
-
- if (!desc)
- return -ENOMEM;
-
- desc->callback = dmaengine_pcm_dma_complete;
- desc->callback_param = substream;
- dmaengine_submit(desc);
-
- return 0;
-}
-
-/**
- * snd_dmaengine_pcm_trigger - dmaengine based PCM trigger implementation
- * @substream: PCM substream
- * @cmd: Trigger command
- *
- * Returns 0 on success, a negative error code otherwise.
- *
- * This function can be used as the PCM trigger callback for dmaengine based PCM
- * driver implementations.
- */
-int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
- int ret;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- ret = dmaengine_pcm_prepare_and_submit(substream);
- if (ret)
- return ret;
- dma_async_issue_pending(prtd->dma_chan);
- break;
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- dmaengine_resume(prtd->dma_chan);
- break;
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- dmaengine_pause(prtd->dma_chan);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- dmaengine_terminate_all(prtd->dma_chan);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_trigger);
-
-/**
- * snd_dmaengine_pcm_pointer - dmaengine based PCM pointer implementation
- * @substream: PCM substream
- *
- * This function can be used as the PCM pointer callback for dmaengine based PCM
- * driver implementations.
- */
-snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
- return bytes_to_frames(substream->runtime, prtd->pos);
-}
-EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer);
-
-static int dmaengine_pcm_request_channel(struct dmaengine_pcm_runtime_data *prtd,
- dma_filter_fn filter_fn, void *filter_data)
-{
- dma_cap_mask_t mask;
-
- dma_cap_zero(mask);
- dma_cap_set(DMA_SLAVE, mask);
- dma_cap_set(DMA_CYCLIC, mask);
- prtd->dma_chan = dma_request_channel(mask, filter_fn, filter_data);
-
- if (!prtd->dma_chan)
- return -ENXIO;
-
- return 0;
-}
-
-/**
- * snd_dmaengine_pcm_open - Open a dmaengine based PCM substream
- * @substream: PCM substream
- * @filter_fn: Filter function used to request the DMA channel
- * @filter_data: Data passed to the DMA filter function
- *
- * Returns 0 on success, a negative error code otherwise.
- *
- * This function will request a DMA channel using the passed filter function and
- * data. The function should usually be called from the pcm open callback.
- *
- * Note that this function will use private_data field of the substream's
- * runtime. So it is not availabe to your pcm driver implementation. If you need
- * to keep additional data attached to a substream use
- * snd_dmaeinge_pcm_{set,get}_data.
- */
-int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
- dma_filter_fn filter_fn, void *filter_data)
-{
- struct dmaengine_pcm_runtime_data *prtd;
- int ret;
-
- ret = snd_pcm_hw_constraint_integer(substream->runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (ret < 0)
- return ret;
-
- prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
- if (!prtd)
- return -ENOMEM;
-
- ret = dmaengine_pcm_request_channel(prtd, filter_fn, filter_data);
- if (ret < 0) {
- kfree(prtd);
- return ret;
- }
-
- substream->runtime->private_data = prtd;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open);
-
-/**
- * snd_dmaengine_pcm_close - Close a dmaengine based PCM substream
- * @substream: PCM substream
- */
-int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream)
-{
- struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
-
- dma_release_channel(prtd->dma_chan);
- kfree(prtd);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close);
diff --git a/ANDROID_3.4.5/sound/soc/soc-io.c b/ANDROID_3.4.5/sound/soc/soc-io.c
deleted file mode 100644
index 4d8dc6a2..00000000
--- a/ANDROID_3.4.5/sound/soc/soc-io.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * soc-io.c -- ASoC register I/O helpers
- *
- * Copyright 2009-2011 Wolfson Microelectronics PLC.
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/i2c.h>
-#include <linux/spi/spi.h>
-#include <linux/regmap.h>
-#include <linux/export.h>
-#include <sound/soc.h>
-
-#include <trace/events/asoc.h>
-
-#ifdef CONFIG_REGMAP
-static int hw_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- int ret;
-
- if (!snd_soc_codec_volatile_register(codec, reg) &&
- reg < codec->driver->reg_cache_size &&
- !codec->cache_bypass) {
- ret = snd_soc_cache_write(codec, reg, value);
- if (ret < 0)
- return -1;
- }
-
- if (codec->cache_only) {
- codec->cache_sync = 1;
- return 0;
- }
-
- return regmap_write(codec->control_data, reg, value);
-}
-
-static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
-{
- int ret;
- unsigned int val;
-
- if (reg >= codec->driver->reg_cache_size ||
- snd_soc_codec_volatile_register(codec, reg) ||
- codec->cache_bypass) {
- if (codec->cache_only)
- return -1;
-
- ret = regmap_read(codec->control_data, reg, &val);
- if (ret == 0)
- return val;
- else
- return -1;
- }
-
- ret = snd_soc_cache_read(codec, reg, &val);
- if (ret < 0)
- return -1;
- return val;
-}
-
-/* Primitive bulk write support for soc-cache. The data pointed to by
- * `data' needs to already be in the form the hardware expects. Any
- * data written through this function will not go through the cache as
- * it only handles writing to volatile or out of bounds registers.
- *
- * This is currently only supported for devices using the regmap API
- * wrappers.
- */
-static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec,
- unsigned int reg,
- const void *data, size_t len)
-{
- /* To ensure that we don't get out of sync with the cache, check
- * whether the base register is volatile or if we've directly asked
- * to bypass the cache. Out of bounds registers are considered
- * volatile.
- */
- if (!codec->cache_bypass
- && !snd_soc_codec_volatile_register(codec, reg)
- && reg < codec->driver->reg_cache_size)
- return -EINVAL;
-
- return regmap_raw_write(codec->control_data, reg, data, len);
-}
-
-/**
- * snd_soc_codec_set_cache_io: Set up standard I/O functions.
- *
- * @codec: CODEC to configure.
- * @addr_bits: Number of bits of register address data.
- * @data_bits: Number of bits of data per register.
- * @control: Control bus used.
- *
- * Register formats are frequently shared between many I2C and SPI
- * devices. In order to promote code reuse the ASoC core provides
- * some standard implementations of CODEC read and write operations
- * which can be set up using this function.
- *
- * The caller is responsible for allocating and initialising the
- * actual cache.
- *
- * Note that at present this code cannot be used by CODECs with
- * volatile registers.
- */
-int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
- int addr_bits, int data_bits,
- enum snd_soc_control_type control)
-{
- struct regmap_config config;
- int ret;
-
- memset(&config, 0, sizeof(config));
- codec->write = hw_write;
- codec->read = hw_read;
- codec->bulk_write_raw = snd_soc_hw_bulk_write_raw;
-
- config.reg_bits = addr_bits;
- config.val_bits = data_bits;
-
- switch (control) {
-#if defined(CONFIG_REGMAP_I2C) || defined(CONFIG_REGMAP_I2C_MODULE)
- case SND_SOC_I2C:
- codec->control_data = regmap_init_i2c(to_i2c_client(codec->dev),
- &config);
- break;
-#endif
-
-#if defined(CONFIG_REGMAP_SPI) || defined(CONFIG_REGMAP_SPI_MODULE)
- case SND_SOC_SPI:
- codec->control_data = regmap_init_spi(to_spi_device(codec->dev),
- &config);
- break;
-#endif
-
- case SND_SOC_REGMAP:
- /* Device has made its own regmap arrangements */
- codec->using_regmap = true;
-
- ret = regmap_get_val_bytes(codec->control_data);
- /* Errors are legitimate for non-integer byte multiples */
- if (ret > 0)
- codec->val_bytes = ret;
- break;
-
- default:
- return -EINVAL;
- }
-
- if (IS_ERR(codec->control_data))
- return PTR_ERR(codec->control_data);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
-#else
-int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
- int addr_bits, int data_bits,
- enum snd_soc_control_type control)
-{
- return -ENOTSUPP;
-}
-EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/soc-jack.c b/ANDROID_3.4.5/sound/soc/soc-jack.c
deleted file mode 100644
index ee4353f8..00000000
--- a/ANDROID_3.4.5/sound/soc/soc-jack.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * soc-jack.c -- ALSA SoC jack handling
- *
- * Copyright 2008 Wolfson Microelectronics PLC.
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <sound/jack.h>
-#include <sound/soc.h>
-#include <linux/gpio.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/delay.h>
-#include <linux/export.h>
-#include <trace/events/asoc.h>
-
-/**
- * snd_soc_jack_new - Create a new jack
- * @card: ASoC card
- * @id: an identifying string for this jack
- * @type: a bitmask of enum snd_jack_type values that can be detected by
- * this jack
- * @jack: structure to use for the jack
- *
- * Creates a new jack object.
- *
- * Returns zero if successful, or a negative error code on failure.
- * On success jack will be initialised.
- */
-int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type,
- struct snd_soc_jack *jack)
-{
- jack->codec = codec;
- INIT_LIST_HEAD(&jack->pins);
- INIT_LIST_HEAD(&jack->jack_zones);
- BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier);
-
- return snd_jack_new(codec->card->snd_card, id, type, &jack->jack);
-}
-EXPORT_SYMBOL_GPL(snd_soc_jack_new);
-
-/**
- * snd_soc_jack_report - Report the current status for a jack
- *
- * @jack: the jack
- * @status: a bitmask of enum snd_jack_type values that are currently detected.
- * @mask: a bitmask of enum snd_jack_type values that being reported.
- *
- * If configured using snd_soc_jack_add_pins() then the associated
- * DAPM pins will be enabled or disabled as appropriate and DAPM
- * synchronised.
- *
- * Note: This function uses mutexes and should be called from a
- * context which can sleep (such as a workqueue).
- */
-void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
-{
- struct snd_soc_codec *codec;
- struct snd_soc_dapm_context *dapm;
- struct snd_soc_jack_pin *pin;
- int enable;
- int oldstatus;
-
- trace_snd_soc_jack_report(jack, mask, status);
-
- if (!jack)
- return;
-
- codec = jack->codec;
- dapm = &codec->dapm;
-
- mutex_lock(&codec->mutex);
-
- oldstatus = jack->status;
-
- jack->status &= ~mask;
- jack->status |= status & mask;
-
- /* The DAPM sync is expensive enough to be worth skipping.
- * However, empty mask means pin synchronization is desired. */
- if (mask && (jack->status == oldstatus))
- goto out;
-
- trace_snd_soc_jack_notify(jack, status);
-
- list_for_each_entry(pin, &jack->pins, list) {
- enable = pin->mask & jack->status;
-
- if (pin->invert)
- enable = !enable;
-
- if (enable)
- snd_soc_dapm_enable_pin(dapm, pin->pin);
- else
- snd_soc_dapm_disable_pin(dapm, pin->pin);
- }
-
- /* Report before the DAPM sync to help users updating micbias status */
- blocking_notifier_call_chain(&jack->notifier, status, jack);
-
- snd_soc_dapm_sync(dapm);
-
- snd_jack_report(jack->jack, jack->status);
-
-out:
- mutex_unlock(&codec->mutex);
-}
-EXPORT_SYMBOL_GPL(snd_soc_jack_report);
-
-/**
- * snd_soc_jack_add_zones - Associate voltage zones with jack
- *
- * @jack: ASoC jack
- * @count: Number of zones
- * @zone: Array of zones
- *
- * After this function has been called the zones specified in the
- * array will be associated with the jack.
- */
-int snd_soc_jack_add_zones(struct snd_soc_jack *jack, int count,
- struct snd_soc_jack_zone *zones)
-{
- int i;
-
- for (i = 0; i < count; i++) {
- INIT_LIST_HEAD(&zones[i].list);
- list_add(&(zones[i].list), &jack->jack_zones);
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_jack_add_zones);
-
-/**
- * snd_soc_jack_get_type - Based on the mic bias value, this function returns
- * the type of jack from the zones delcared in the jack type
- *
- * @micbias_voltage: mic bias voltage at adc channel when jack is plugged in
- *
- * Based on the mic bias value passed, this function helps identify
- * the type of jack from the already delcared jack zones
- */
-int snd_soc_jack_get_type(struct snd_soc_jack *jack, int micbias_voltage)
-{
- struct snd_soc_jack_zone *zone;
-
- list_for_each_entry(zone, &jack->jack_zones, list) {
- if (micbias_voltage >= zone->min_mv &&
- micbias_voltage < zone->max_mv)
- return zone->jack_type;
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_jack_get_type);
-
-/**
- * snd_soc_jack_add_pins - Associate DAPM pins with an ASoC jack
- *
- * @jack: ASoC jack
- * @count: Number of pins
- * @pins: Array of pins
- *
- * After this function has been called the DAPM pins specified in the
- * pins array will have their status updated to reflect the current
- * state of the jack whenever the jack status is updated.
- */
-int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
- struct snd_soc_jack_pin *pins)
-{
- int i;
-
- for (i = 0; i < count; i++) {
- if (!pins[i].pin) {
- printk(KERN_ERR "No name for pin %d\n", i);
- return -EINVAL;
- }
- if (!pins[i].mask) {
- printk(KERN_ERR "No mask for pin %d (%s)\n", i,
- pins[i].pin);
- return -EINVAL;
- }
-
- INIT_LIST_HEAD(&pins[i].list);
- list_add(&(pins[i].list), &jack->pins);
- }
-
- snd_soc_dapm_new_widgets(&jack->codec->card->dapm);
-
- /* Update to reflect the last reported status; canned jack
- * implementations are likely to set their state before the
- * card has an opportunity to associate pins.
- */
- snd_soc_jack_report(jack, 0, 0);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_jack_add_pins);
-
-/**
- * snd_soc_jack_notifier_register - Register a notifier for jack status
- *
- * @jack: ASoC jack
- * @nb: Notifier block to register
- *
- * Register for notification of the current status of the jack. Note
- * that it is not possible to report additional jack events in the
- * callback from the notifier, this is intended to support
- * applications such as enabling electrical detection only when a
- * mechanical detection event has occurred.
- */
-void snd_soc_jack_notifier_register(struct snd_soc_jack *jack,
- struct notifier_block *nb)
-{
- blocking_notifier_chain_register(&jack->notifier, nb);
-}
-EXPORT_SYMBOL_GPL(snd_soc_jack_notifier_register);
-
-/**
- * snd_soc_jack_notifier_unregister - Unregister a notifier for jack status
- *
- * @jack: ASoC jack
- * @nb: Notifier block to unregister
- *
- * Stop notifying for status changes.
- */
-void snd_soc_jack_notifier_unregister(struct snd_soc_jack *jack,
- struct notifier_block *nb)
-{
- blocking_notifier_chain_unregister(&jack->notifier, nb);
-}
-EXPORT_SYMBOL_GPL(snd_soc_jack_notifier_unregister);
-
-#ifdef CONFIG_GPIOLIB
-/* gpio detect */
-static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
-{
- struct snd_soc_jack *jack = gpio->jack;
- int enable;
- int report;
-
- enable = gpio_get_value_cansleep(gpio->gpio);
- if (gpio->invert)
- enable = !enable;
-
- if (enable)
- report = gpio->report;
- else
- report = 0;
-
- if (gpio->jack_status_check)
- report = gpio->jack_status_check();
-
- snd_soc_jack_report(jack, report, gpio->report);
-}
-
-/* irq handler for gpio pin */
-static irqreturn_t gpio_handler(int irq, void *data)
-{
- struct snd_soc_jack_gpio *gpio = data;
- struct device *dev = gpio->jack->codec->card->dev;
-
- trace_snd_soc_jack_irq(gpio->name);
-
- if (device_may_wakeup(dev))
- pm_wakeup_event(dev, gpio->debounce_time + 50);
-
- schedule_delayed_work(&gpio->work,
- msecs_to_jiffies(gpio->debounce_time));
-
- return IRQ_HANDLED;
-}
-
-/* gpio work */
-static void gpio_work(struct work_struct *work)
-{
- struct snd_soc_jack_gpio *gpio;
-
- gpio = container_of(work, struct snd_soc_jack_gpio, work.work);
- snd_soc_jack_gpio_detect(gpio);
-}
-
-/**
- * snd_soc_jack_add_gpios - Associate GPIO pins with an ASoC jack
- *
- * @jack: ASoC jack
- * @count: number of pins
- * @gpios: array of gpio pins
- *
- * This function will request gpio, set data direction and request irq
- * for each gpio in the array.
- */
-int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
- struct snd_soc_jack_gpio *gpios)
-{
- int i, ret;
-
- for (i = 0; i < count; i++) {
- if (!gpio_is_valid(gpios[i].gpio)) {
- printk(KERN_ERR "Invalid gpio %d\n",
- gpios[i].gpio);
- ret = -EINVAL;
- goto undo;
- }
- if (!gpios[i].name) {
- printk(KERN_ERR "No name for gpio %d\n",
- gpios[i].gpio);
- ret = -EINVAL;
- goto undo;
- }
-
- ret = gpio_request(gpios[i].gpio, gpios[i].name);
- if (ret)
- goto undo;
-
- ret = gpio_direction_input(gpios[i].gpio);
- if (ret)
- goto err;
-
- INIT_DELAYED_WORK(&gpios[i].work, gpio_work);
- gpios[i].jack = jack;
-
- ret = request_any_context_irq(gpio_to_irq(gpios[i].gpio),
- gpio_handler,
- IRQF_TRIGGER_RISING |
- IRQF_TRIGGER_FALLING,
- gpios[i].name,
- &gpios[i]);
- if (ret < 0)
- goto err;
-
- if (gpios[i].wake) {
- ret = irq_set_irq_wake(gpio_to_irq(gpios[i].gpio), 1);
- if (ret != 0)
- printk(KERN_ERR
- "Failed to mark GPIO %d as wake source: %d\n",
- gpios[i].gpio, ret);
- }
-
- /* Expose GPIO value over sysfs for diagnostic purposes */
- gpio_export(gpios[i].gpio, false);
-
- /* Update initial jack status */
- snd_soc_jack_gpio_detect(&gpios[i]);
- }
-
- return 0;
-
-err:
- gpio_free(gpios[i].gpio);
-undo:
- snd_soc_jack_free_gpios(jack, i, gpios);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(snd_soc_jack_add_gpios);
-
-/**
- * snd_soc_jack_free_gpios - Release GPIO pins' resources of an ASoC jack
- *
- * @jack: ASoC jack
- * @count: number of pins
- * @gpios: array of gpio pins
- *
- * Release gpio and irq resources for gpio pins associated with an ASoC jack.
- */
-void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
- struct snd_soc_jack_gpio *gpios)
-{
- int i;
-
- for (i = 0; i < count; i++) {
- gpio_unexport(gpios[i].gpio);
- free_irq(gpio_to_irq(gpios[i].gpio), &gpios[i]);
- cancel_delayed_work_sync(&gpios[i].work);
- gpio_free(gpios[i].gpio);
- gpios[i].jack = NULL;
- }
-}
-EXPORT_SYMBOL_GPL(snd_soc_jack_free_gpios);
-#endif /* CONFIG_GPIOLIB */
diff --git a/ANDROID_3.4.5/sound/soc/soc-pcm.c b/ANDROID_3.4.5/sound/soc/soc-pcm.c
deleted file mode 100644
index 0ad8dcac..00000000
--- a/ANDROID_3.4.5/sound/soc/soc-pcm.c
+++ /dev/null
@@ -1,707 +0,0 @@
-/*
- * soc-pcm.c -- ALSA SoC PCM
- *
- * Copyright 2005 Wolfson Microelectronics PLC.
- * Copyright 2005 Openedhand Ltd.
- * Copyright (C) 2010 Slimlogic Ltd.
- * Copyright (C) 2010 Texas Instruments Inc.
- *
- * Authors: Liam Girdwood <lrg@ti.com>
- * Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm_runtime.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
-
-static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream,
- struct snd_soc_dai *soc_dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- int ret;
-
- if (!soc_dai->driver->symmetric_rates &&
- !rtd->dai_link->symmetric_rates)
- return 0;
-
- /* This can happen if multiple streams are starting simultaneously -
- * the second can need to get its constraints before the first has
- * picked a rate. Complain and allow the application to carry on.
- */
- if (!soc_dai->rate) {
- dev_warn(soc_dai->dev,
- "Not enforcing symmetric_rates due to race\n");
- return 0;
- }
-
- dev_dbg(soc_dai->dev, "Symmetry forces %dHz rate\n", soc_dai->rate);
-
- ret = snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_RATE,
- soc_dai->rate, soc_dai->rate);
- if (ret < 0) {
- dev_err(soc_dai->dev,
- "Unable to apply rate symmetry constraint: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-/*
- * List of sample sizes that might go over the bus for parameter
- * application. There ought to be a wildcard sample size for things
- * like the DAC/ADC resolution to use but there isn't right now.
- */
-static int sample_sizes[] = {
- 24, 32,
-};
-
-static void soc_pcm_apply_msb(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- int ret, i, bits;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- bits = dai->driver->playback.sig_bits;
- else
- bits = dai->driver->capture.sig_bits;
-
- if (!bits)
- return;
-
- for (i = 0; i < ARRAY_SIZE(sample_sizes); i++) {
- if (bits >= sample_sizes[i])
- continue;
-
- ret = snd_pcm_hw_constraint_msbits(substream->runtime, 0,
- sample_sizes[i], bits);
- if (ret != 0)
- dev_warn(dai->dev,
- "Failed to set MSB %d/%d: %d\n",
- bits, sample_sizes[i], ret);
- }
-}
-
-/*
- * Called by ALSA when a PCM substream is opened, the runtime->hw record is
- * then initialized and any private data can be allocated. This also calls
- * startup for the cpu DAI, platform, machine and codec DAI.
- */
-static int soc_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_platform *platform = rtd->platform;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver;
- struct snd_soc_dai_driver *codec_dai_drv = codec_dai->driver;
- int ret = 0;
-
- pm_runtime_get_sync(cpu_dai->dev);
- pm_runtime_get_sync(codec_dai->dev);
- pm_runtime_get_sync(platform->dev);
-
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
-
- /* startup the audio subsystem */
- if (cpu_dai->driver->ops->startup) {
- ret = cpu_dai->driver->ops->startup(substream, cpu_dai);
- if (ret < 0) {
- dev_err(cpu_dai->dev, "can't open interface %s: %d\n",
- cpu_dai->name, ret);
- goto out;
- }
- }
-
- if (platform->driver->ops && platform->driver->ops->open) {
- ret = platform->driver->ops->open(substream);
- if (ret < 0) {
- dev_err(platform->dev, "can't open platform %s: %d\n",
- platform->name, ret);
- goto platform_err;
- }
- }
-
- if (codec_dai->driver->ops->startup) {
- ret = codec_dai->driver->ops->startup(substream, codec_dai);
- if (ret < 0) {
- dev_err(codec_dai->dev, "can't open codec %s: %d\n",
- codec_dai->name, ret);
- goto codec_dai_err;
- }
- }
-
- if (rtd->dai_link->ops && rtd->dai_link->ops->startup) {
- ret = rtd->dai_link->ops->startup(substream);
- if (ret < 0) {
- pr_err("asoc: %s startup failed: %d\n",
- rtd->dai_link->name, ret);
- goto machine_err;
- }
- }
-
- /* Check that the codec and cpu DAIs are compatible */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- runtime->hw.rate_min =
- max(codec_dai_drv->playback.rate_min,
- cpu_dai_drv->playback.rate_min);
- runtime->hw.rate_max =
- min(codec_dai_drv->playback.rate_max,
- cpu_dai_drv->playback.rate_max);
- runtime->hw.channels_min =
- max(codec_dai_drv->playback.channels_min,
- cpu_dai_drv->playback.channels_min);
- runtime->hw.channels_max =
- min(codec_dai_drv->playback.channels_max,
- cpu_dai_drv->playback.channels_max);
- runtime->hw.formats =
- codec_dai_drv->playback.formats & cpu_dai_drv->playback.formats;
- runtime->hw.rates =
- codec_dai_drv->playback.rates & cpu_dai_drv->playback.rates;
- if (codec_dai_drv->playback.rates
- & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
- runtime->hw.rates |= cpu_dai_drv->playback.rates;
- if (cpu_dai_drv->playback.rates
- & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
- runtime->hw.rates |= codec_dai_drv->playback.rates;
- } else {
- runtime->hw.rate_min =
- max(codec_dai_drv->capture.rate_min,
- cpu_dai_drv->capture.rate_min);
- runtime->hw.rate_max =
- min(codec_dai_drv->capture.rate_max,
- cpu_dai_drv->capture.rate_max);
- runtime->hw.channels_min =
- max(codec_dai_drv->capture.channels_min,
- cpu_dai_drv->capture.channels_min);
- runtime->hw.channels_max =
- min(codec_dai_drv->capture.channels_max,
- cpu_dai_drv->capture.channels_max);
- runtime->hw.formats =
- codec_dai_drv->capture.formats & cpu_dai_drv->capture.formats;
- runtime->hw.rates =
- codec_dai_drv->capture.rates & cpu_dai_drv->capture.rates;
- if (codec_dai_drv->capture.rates
- & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
- runtime->hw.rates |= cpu_dai_drv->capture.rates;
- if (cpu_dai_drv->capture.rates
- & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
- runtime->hw.rates |= codec_dai_drv->capture.rates;
- }
-
- ret = -EINVAL;
- snd_pcm_limit_hw_rates(runtime);
- if (!runtime->hw.rates) {
- printk(KERN_ERR "asoc: %s <-> %s No matching rates\n",
- codec_dai->name, cpu_dai->name);
- goto config_err;
- }
- if (!runtime->hw.formats) {
- printk(KERN_ERR "asoc: %s <-> %s No matching formats\n",
- codec_dai->name, cpu_dai->name);
- goto config_err;
- }
- if (!runtime->hw.channels_min || !runtime->hw.channels_max ||
- runtime->hw.channels_min > runtime->hw.channels_max) {
- printk(KERN_ERR "asoc: %s <-> %s No matching channels\n",
- codec_dai->name, cpu_dai->name);
- goto config_err;
- }
-
- soc_pcm_apply_msb(substream, codec_dai);
- soc_pcm_apply_msb(substream, cpu_dai);
-
- /* Symmetry only applies if we've already got an active stream. */
- if (cpu_dai->active) {
- ret = soc_pcm_apply_symmetry(substream, cpu_dai);
- if (ret != 0)
- goto config_err;
- }
-
- if (codec_dai->active) {
- ret = soc_pcm_apply_symmetry(substream, codec_dai);
- if (ret != 0)
- goto config_err;
- }
-
- pr_debug("asoc: %s <-> %s info:\n",
- codec_dai->name, cpu_dai->name);
- pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates);
- pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min,
- runtime->hw.channels_max);
- pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min,
- runtime->hw.rate_max);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- cpu_dai->playback_active++;
- codec_dai->playback_active++;
- } else {
- cpu_dai->capture_active++;
- codec_dai->capture_active++;
- }
- cpu_dai->active++;
- codec_dai->active++;
- rtd->codec->active++;
- mutex_unlock(&rtd->pcm_mutex);
- return 0;
-
-config_err:
- if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown)
- rtd->dai_link->ops->shutdown(substream);
-
-machine_err:
- if (codec_dai->driver->ops->shutdown)
- codec_dai->driver->ops->shutdown(substream, codec_dai);
-
-codec_dai_err:
- if (platform->driver->ops && platform->driver->ops->close)
- platform->driver->ops->close(substream);
-
-platform_err:
- if (cpu_dai->driver->ops->shutdown)
- cpu_dai->driver->ops->shutdown(substream, cpu_dai);
-out:
- mutex_unlock(&rtd->pcm_mutex);
-
- pm_runtime_put(platform->dev);
- pm_runtime_put(codec_dai->dev);
- pm_runtime_put(cpu_dai->dev);
-
- return ret;
-}
-
-/*
- * Power down the audio subsystem pmdown_time msecs after close is called.
- * This is to ensure there are no pops or clicks in between any music tracks
- * due to DAPM power cycling.
- */
-static void close_delayed_work(struct work_struct *work)
-{
- struct snd_soc_pcm_runtime *rtd =
- container_of(work, struct snd_soc_pcm_runtime, delayed_work.work);
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
-
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
-
- pr_debug("pop wq checking: %s status: %s waiting: %s\n",
- codec_dai->driver->playback.stream_name,
- codec_dai->playback_active ? "active" : "inactive",
- codec_dai->pop_wait ? "yes" : "no");
-
- /* are we waiting on this codec DAI stream */
- if (codec_dai->pop_wait == 1) {
- codec_dai->pop_wait = 0;
- snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
- codec_dai, SND_SOC_DAPM_STREAM_STOP);
- }
-
- mutex_unlock(&rtd->pcm_mutex);
-}
-
-/*
- * Called by ALSA when a PCM substream is closed. Private data can be
- * freed here. The cpu DAI, codec DAI, machine and platform are also
- * shutdown.
- */
-static int soc_pcm_close(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_platform *platform = rtd->platform;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_codec *codec = rtd->codec;
-
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- cpu_dai->playback_active--;
- codec_dai->playback_active--;
- } else {
- cpu_dai->capture_active--;
- codec_dai->capture_active--;
- }
-
- cpu_dai->active--;
- codec_dai->active--;
- codec->active--;
-
- /* clear the corresponding DAIs rate when inactive */
- if (!cpu_dai->active)
- cpu_dai->rate = 0;
-
- if (!codec_dai->active)
- codec_dai->rate = 0;
-
- /* Muting the DAC suppresses artifacts caused during digital
- * shutdown, for example from stopping clocks.
- */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- snd_soc_dai_digital_mute(codec_dai, 1);
-
- if (cpu_dai->driver->ops->shutdown)
- cpu_dai->driver->ops->shutdown(substream, cpu_dai);
-
- if (codec_dai->driver->ops->shutdown)
- codec_dai->driver->ops->shutdown(substream, codec_dai);
-
- if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown)
- rtd->dai_link->ops->shutdown(substream);
-
- if (platform->driver->ops && platform->driver->ops->close)
- platform->driver->ops->close(substream);
- cpu_dai->runtime = NULL;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (!rtd->pmdown_time || codec->ignore_pmdown_time ||
- rtd->dai_link->ignore_pmdown_time) {
- /* powered down playback stream now */
- snd_soc_dapm_stream_event(rtd,
- SNDRV_PCM_STREAM_PLAYBACK,
- codec_dai,
- SND_SOC_DAPM_STREAM_STOP);
- } else {
- /* start delayed pop wq here for playback streams */
- codec_dai->pop_wait = 1;
- schedule_delayed_work(&rtd->delayed_work,
- msecs_to_jiffies(rtd->pmdown_time));
- }
- } else {
- /* capture streams can be powered down now */
- snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
- codec_dai, SND_SOC_DAPM_STREAM_STOP);
- }
-
- mutex_unlock(&rtd->pcm_mutex);
-
- pm_runtime_put(platform->dev);
- pm_runtime_put(codec_dai->dev);
- pm_runtime_put(cpu_dai->dev);
-
- return 0;
-}
-
-/*
- * Called by ALSA when the PCM substream is prepared, can set format, sample
- * rate, etc. This function is non atomic and can be called multiple times,
- * it can refer to the runtime info.
- */
-static int soc_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_platform *platform = rtd->platform;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int ret = 0;
-
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
-
- if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) {
- ret = rtd->dai_link->ops->prepare(substream);
- if (ret < 0) {
- pr_err("asoc: machine prepare error: %d\n", ret);
- goto out;
- }
- }
-
- if (platform->driver->ops && platform->driver->ops->prepare) {
- ret = platform->driver->ops->prepare(substream);
- if (ret < 0) {
- dev_err(platform->dev, "platform prepare error: %d\n",
- ret);
- goto out;
- }
- }
-
- if (codec_dai->driver->ops->prepare) {
- ret = codec_dai->driver->ops->prepare(substream, codec_dai);
- if (ret < 0) {
- dev_err(codec_dai->dev, "DAI prepare error: %d\n",
- ret);
- goto out;
- }
- }
-
- if (cpu_dai->driver->ops->prepare) {
- ret = cpu_dai->driver->ops->prepare(substream, cpu_dai);
- if (ret < 0) {
- dev_err(cpu_dai->dev, "DAI prepare error: %d\n",
- ret);
- goto out;
- }
- }
-
- /* cancel any delayed stream shutdown that is pending */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
- codec_dai->pop_wait) {
- codec_dai->pop_wait = 0;
- cancel_delayed_work(&rtd->delayed_work);
- }
-
- snd_soc_dapm_stream_event(rtd, substream->stream, codec_dai,
- SND_SOC_DAPM_STREAM_START);
-
- snd_soc_dai_digital_mute(codec_dai, 0);
-
-out:
- mutex_unlock(&rtd->pcm_mutex);
- return ret;
-}
-
-/*
- * Called by ALSA when the hardware params are set by application. This
- * function can also be called multiple times and can allocate buffers
- * (using snd_pcm_lib_* ). It's non-atomic.
- */
-static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_platform *platform = rtd->platform;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int ret = 0;
-
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
-
- if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) {
- ret = rtd->dai_link->ops->hw_params(substream, params);
- if (ret < 0) {
- pr_err("asoc: machine hw_params failed: %d\n", ret);
- goto out;
- }
- }
-
- if (codec_dai->driver->ops->hw_params) {
- ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai);
- if (ret < 0) {
- dev_err(codec_dai->dev, "can't set %s hw params: %d\n",
- codec_dai->name, ret);
- goto codec_err;
- }
- }
-
- if (cpu_dai->driver->ops->hw_params) {
- ret = cpu_dai->driver->ops->hw_params(substream, params, cpu_dai);
- if (ret < 0) {
- dev_err(cpu_dai->dev, "%s hw params failed: %d\n",
- cpu_dai->name, ret);
- goto interface_err;
- }
- }
-
- if (platform->driver->ops && platform->driver->ops->hw_params) {
- ret = platform->driver->ops->hw_params(substream, params);
- if (ret < 0) {
- dev_err(platform->dev, "%s hw params failed: %d\n",
- platform->name, ret);
- goto platform_err;
- }
- }
-
- /* store the rate for each DAIs */
- cpu_dai->rate = params_rate(params);
- codec_dai->rate = params_rate(params);
-
-out:
- mutex_unlock(&rtd->pcm_mutex);
- return ret;
-
-platform_err:
- if (cpu_dai->driver->ops->hw_free)
- cpu_dai->driver->ops->hw_free(substream, cpu_dai);
-
-interface_err:
- if (codec_dai->driver->ops->hw_free)
- codec_dai->driver->ops->hw_free(substream, codec_dai);
-
-codec_err:
- if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
- rtd->dai_link->ops->hw_free(substream);
-
- mutex_unlock(&rtd->pcm_mutex);
- return ret;
-}
-
-/*
- * Frees resources allocated by hw_params, can be called multiple times
- */
-static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_platform *platform = rtd->platform;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_codec *codec = rtd->codec;
-
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
-
- /* apply codec digital mute */
- if (!codec->active)
- snd_soc_dai_digital_mute(codec_dai, 1);
-
- /* free any machine hw params */
- if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
- rtd->dai_link->ops->hw_free(substream);
-
- /* free any DMA resources */
- if (platform->driver->ops && platform->driver->ops->hw_free)
- platform->driver->ops->hw_free(substream);
-
- /* now free hw params for the DAIs */
- if (codec_dai->driver->ops->hw_free)
- codec_dai->driver->ops->hw_free(substream, codec_dai);
-
- if (cpu_dai->driver->ops->hw_free)
- cpu_dai->driver->ops->hw_free(substream, cpu_dai);
-
- mutex_unlock(&rtd->pcm_mutex);
- return 0;
-}
-
-static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_platform *platform = rtd->platform;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int ret;
-
- if (codec_dai->driver->ops->trigger) {
- ret = codec_dai->driver->ops->trigger(substream, cmd, codec_dai);
- if (ret < 0)
- return ret;
- }
-
- if (platform->driver->ops && platform->driver->ops->trigger) {
- ret = platform->driver->ops->trigger(substream, cmd);
- if (ret < 0)
- return ret;
- }
-
- if (cpu_dai->driver->ops->trigger) {
- ret = cpu_dai->driver->ops->trigger(substream, cmd, cpu_dai);
- if (ret < 0)
- return ret;
- }
- return 0;
-}
-
-/*
- * soc level wrapper for pointer callback
- * If cpu_dai, codec_dai, platform driver has the delay callback, than
- * the runtime->delay will be updated accordingly.
- */
-static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_platform *platform = rtd->platform;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_uframes_t offset = 0;
- snd_pcm_sframes_t delay = 0;
-
- if (platform->driver->ops && platform->driver->ops->pointer)
- offset = platform->driver->ops->pointer(substream);
-
- if (cpu_dai->driver->ops->delay)
- delay += cpu_dai->driver->ops->delay(substream, cpu_dai);
-
- if (codec_dai->driver->ops->delay)
- delay += codec_dai->driver->ops->delay(substream, codec_dai);
-
- if (platform->driver->delay)
- delay += platform->driver->delay(substream, codec_dai);
-
- runtime->delay = delay;
-
- return offset;
-}
-
-/* create a new pcm */
-int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_platform *platform = rtd->platform;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_pcm_ops *soc_pcm_ops = &rtd->ops;
- struct snd_pcm *pcm;
- char new_name[64];
- int ret = 0, playback = 0, capture = 0;
-
- soc_pcm_ops->open = soc_pcm_open;
- soc_pcm_ops->close = soc_pcm_close;
- soc_pcm_ops->hw_params = soc_pcm_hw_params;
- soc_pcm_ops->hw_free = soc_pcm_hw_free;
- soc_pcm_ops->prepare = soc_pcm_prepare;
- soc_pcm_ops->trigger = soc_pcm_trigger;
- soc_pcm_ops->pointer = soc_pcm_pointer;
-
- /* check client and interface hw capabilities */
- snprintf(new_name, sizeof(new_name), "%s %s-%d",
- rtd->dai_link->stream_name, codec_dai->name, num);
-
- if (codec_dai->driver->playback.channels_min)
- playback = 1;
- if (codec_dai->driver->capture.channels_min)
- capture = 1;
-
- dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num,new_name);
- ret = snd_pcm_new(rtd->card->snd_card, new_name,
- num, playback, capture, &pcm);
- if (ret < 0) {
- printk(KERN_ERR "asoc: can't create pcm for codec %s\n", codec->name);
- return ret;
- }
-
- /* DAPM dai link stream work */
- INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
-
- rtd->pcm = pcm;
- pcm->private_data = rtd;
- if (platform->driver->ops) {
- soc_pcm_ops->mmap = platform->driver->ops->mmap;
- soc_pcm_ops->pointer = platform->driver->ops->pointer;
- soc_pcm_ops->ioctl = platform->driver->ops->ioctl;
- soc_pcm_ops->copy = platform->driver->ops->copy;
- soc_pcm_ops->silence = platform->driver->ops->silence;
- soc_pcm_ops->ack = platform->driver->ops->ack;
- soc_pcm_ops->page = platform->driver->ops->page;
- }
-
- if (playback)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, soc_pcm_ops);
-
- if (capture)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, soc_pcm_ops);
-
- if (platform->driver->pcm_new) {
- ret = platform->driver->pcm_new(rtd);
- if (ret < 0) {
- pr_err("asoc: platform pcm constructor failed\n");
- return ret;
- }
- }
-
- pcm->private_free = platform->driver->pcm_free;
- printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name,
- cpu_dai->name);
- return ret;
-}
diff --git a/ANDROID_3.4.5/sound/soc/soc-utils.c b/ANDROID_3.4.5/sound/soc/soc-utils.c
deleted file mode 100644
index 60053709..00000000
--- a/ANDROID_3.4.5/sound/soc/soc-utils.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * soc-util.c -- ALSA SoC Audio Layer utility functions
- *
- * Copyright 2009 Wolfson Microelectronics PLC.
- *
- * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
- * Liam Girdwood <lrg@slimlogic.co.uk>
- *
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/platform_device.h>
-#include <linux/export.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots)
-{
- return sample_size * channels * tdm_slots;
-}
-EXPORT_SYMBOL_GPL(snd_soc_calc_frame_size);
-
-int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params)
-{
- int sample_size;
-
- sample_size = snd_pcm_format_width(params_format(params));
- if (sample_size < 0)
- return sample_size;
-
- return snd_soc_calc_frame_size(sample_size, params_channels(params),
- 1);
-}
-EXPORT_SYMBOL_GPL(snd_soc_params_to_frame_size);
-
-int snd_soc_calc_bclk(int fs, int sample_size, int channels, int tdm_slots)
-{
- return fs * snd_soc_calc_frame_size(sample_size, channels, tdm_slots);
-}
-EXPORT_SYMBOL_GPL(snd_soc_calc_bclk);
-
-int snd_soc_params_to_bclk(struct snd_pcm_hw_params *params)
-{
- int ret;
-
- ret = snd_soc_params_to_frame_size(params);
-
- if (ret > 0)
- return ret * params_rate(params);
- else
- return ret;
-}
-EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk);
-
-static const struct snd_pcm_hardware dummy_dma_hardware = {
- .formats = 0xffffffff,
- .channels_min = 1,
- .channels_max = UINT_MAX,
-
- /* Random values to keep userspace happy when checking constraints */
- .info = SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER,
- .buffer_bytes_max = 128*1024,
- .period_bytes_min = PAGE_SIZE,
- .period_bytes_max = PAGE_SIZE*2,
- .periods_min = 2,
- .periods_max = 128,
-};
-
-static int dummy_dma_open(struct snd_pcm_substream *substream)
-{
- snd_soc_set_runtime_hwparams(substream, &dummy_dma_hardware);
-
- return 0;
-}
-
-static struct snd_pcm_ops dummy_dma_ops = {
- .open = dummy_dma_open,
- .ioctl = snd_pcm_lib_ioctl,
-};
-
-static struct snd_soc_platform_driver dummy_platform = {
- .ops = &dummy_dma_ops,
-};
-
-static struct snd_soc_codec_driver dummy_codec;
-static struct snd_soc_dai_driver dummy_dai = {
- .name = "snd-soc-dummy-dai",
-};
-
-static __devinit int snd_soc_dummy_probe(struct platform_device *pdev)
-{
- int ret;
-
- ret = snd_soc_register_codec(&pdev->dev, &dummy_codec, &dummy_dai, 1);
- if (ret < 0)
- return ret;
-
- ret = snd_soc_register_platform(&pdev->dev, &dummy_platform);
- if (ret < 0) {
- snd_soc_unregister_codec(&pdev->dev);
- return ret;
- }
-
- return ret;
-}
-
-static __devexit int snd_soc_dummy_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
- snd_soc_unregister_codec(&pdev->dev);
-
- return 0;
-}
-
-static struct platform_driver soc_dummy_driver = {
- .driver = {
- .name = "snd-soc-dummy",
- .owner = THIS_MODULE,
- },
- .probe = snd_soc_dummy_probe,
- .remove = __devexit_p(snd_soc_dummy_remove),
-};
-
-static struct platform_device *soc_dummy_dev;
-
-int __init snd_soc_util_init(void)
-{
- int ret;
-
- soc_dummy_dev = platform_device_alloc("snd-soc-dummy", -1);
- if (!soc_dummy_dev)
- return -ENOMEM;
-
- ret = platform_device_add(soc_dummy_dev);
- if (ret != 0) {
- platform_device_put(soc_dummy_dev);
- return ret;
- }
-
- ret = platform_driver_register(&soc_dummy_driver);
- if (ret != 0)
- platform_device_unregister(soc_dummy_dev);
-
- return ret;
-}
-
-void __exit snd_soc_util_exit(void)
-{
- platform_device_unregister(soc_dummy_dev);
- platform_driver_unregister(&soc_dummy_driver);
-}
diff --git a/ANDROID_3.4.5/sound/soc/tegra/Kconfig b/ANDROID_3.4.5/sound/soc/tegra/Kconfig
deleted file mode 100644
index ce1b773c..00000000
--- a/ANDROID_3.4.5/sound/soc/tegra/Kconfig
+++ /dev/null
@@ -1,58 +0,0 @@
-config SND_SOC_TEGRA
- tristate "SoC Audio for the Tegra System-on-Chip"
- depends on ARCH_TEGRA && TEGRA_SYSTEM_DMA
- help
- Say Y or M here if you want support for SoC audio on Tegra.
-
-config SND_SOC_TEGRA_I2S
- tristate
- depends on SND_SOC_TEGRA
- help
- Say Y or M if you want to add support for codecs attached to the
- Tegra I2S interface. You will also need to select the individual
- machine drivers to support below.
-
-config SND_SOC_TEGRA_SPDIF
- tristate
- depends on SND_SOC_TEGRA
- default m
- help
- Say Y or M if you want to add support for the SPDIF interface.
- You will also need to select the individual machine drivers to support
- below.
-
-config MACH_HAS_SND_SOC_TEGRA_WM8903
- bool
- help
- Machines that use the SND_SOC_TEGRA_WM8903 driver should select
- this config option, in order to allow the user to enable
- SND_SOC_TEGRA_WM8903.
-
-config SND_SOC_TEGRA_WM8903
- tristate "SoC Audio support for Tegra boards using a WM8903 codec"
- depends on SND_SOC_TEGRA && I2C
- depends on MACH_HAS_SND_SOC_TEGRA_WM8903
- select SND_SOC_TEGRA_I2S
- select SND_SOC_WM8903
- help
- Say Y or M here if you want to add support for SoC audio on Tegra
- boards using the WM8093 codec. Currently, the supported boards are
- Harmony, Ventana, Seaboard, Kaen, and Aebl.
-
-config SND_SOC_TEGRA_TRIMSLICE
- tristate "SoC Audio support for TrimSlice board"
- depends on SND_SOC_TEGRA && MACH_TRIMSLICE && I2C
- select SND_SOC_TEGRA_I2S
- select SND_SOC_TLV320AIC23
- help
- Say Y or M here if you want to add support for SoC audio on the
- TrimSlice platform.
-
-config SND_SOC_TEGRA_ALC5632
- tristate "SoC Audio support for Tegra boards using an ALC5632 codec"
- depends on SND_SOC_TEGRA && I2C
- select SND_SOC_TEGRA_I2S
- select SND_SOC_ALC5632
- help
- Say Y or M here if you want to add support for SoC audio on the
- Toshiba AC100 netbook.
diff --git a/ANDROID_3.4.5/sound/soc/tegra/Makefile b/ANDROID_3.4.5/sound/soc/tegra/Makefile
deleted file mode 100644
index 8e584b8f..00000000
--- a/ANDROID_3.4.5/sound/soc/tegra/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-# Tegra platform Support
-snd-soc-tegra-das-objs := tegra_das.o
-snd-soc-tegra-pcm-objs := tegra_pcm.o
-snd-soc-tegra-i2s-objs := tegra_i2s.o
-snd-soc-tegra-spdif-objs := tegra_spdif.o
-snd-soc-tegra-utils-objs += tegra_asoc_utils.o
-
-obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-utils.o
-obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-das.o
-obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o
-obj-$(CONFIG_SND_SOC_TEGRA_I2S) += snd-soc-tegra-i2s.o
-obj-$(CONFIG_SND_SOC_TEGRA_SPDIF) += snd-soc-tegra-spdif.o
-
-# Tegra machine Support
-snd-soc-tegra-wm8903-objs := tegra_wm8903.o
-snd-soc-tegra-trimslice-objs := trimslice.o
-snd-soc-tegra-alc5632-objs := tegra_alc5632.o
-
-obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o
-obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o
-obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o
diff --git a/ANDROID_3.4.5/sound/soc/tegra/tegra_alc5632.c b/ANDROID_3.4.5/sound/soc/tegra/tegra_alc5632.c
deleted file mode 100644
index e45ccd85..00000000
--- a/ANDROID_3.4.5/sound/soc/tegra/tegra_alc5632.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
-* tegra_alc5632.c -- Toshiba AC100(PAZ00) machine ASoC driver
-*
-* Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
-*
-* Authors: Leon Romanovsky <leon@leon.nu>
-* Andrey Danin <danindrey@mail.ru>
-* Marc Dietrich <marvin24@gmx.de>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License version 2 as
-* published by the Free Software Foundation.
-*/
-
-#include <asm/mach-types.h>
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/gpio.h>
-#include <linux/of_gpio.h>
-
-#include <sound/core.h>
-#include <sound/jack.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include "../codecs/alc5632.h"
-
-#include "tegra_das.h"
-#include "tegra_i2s.h"
-#include "tegra_pcm.h"
-#include "tegra_asoc_utils.h"
-
-#define DRV_NAME "tegra-alc5632"
-
-#define GPIO_HP_DET BIT(0)
-
-struct tegra_alc5632 {
- struct tegra_asoc_utils_data util_data;
- struct platform_device *pcm_dev;
- int gpio_requested;
- int gpio_hp_det;
-};
-
-static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_card *card = codec->card;
- struct tegra_alc5632 *alc5632 = snd_soc_card_get_drvdata(card);
- int srate, mclk;
- int err;
-
- srate = params_rate(params);
- mclk = 512 * srate;
-
- err = tegra_asoc_utils_set_rate(&alc5632->util_data, srate, mclk);
- if (err < 0) {
- dev_err(card->dev, "Can't configure clocks\n");
- return err;
- }
-
- err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
- SND_SOC_CLOCK_IN);
- if (err < 0) {
- dev_err(card->dev, "codec_dai clock not set\n");
- return err;
- }
-
- return 0;
-}
-
-static struct snd_soc_ops tegra_alc5632_asoc_ops = {
- .hw_params = tegra_alc5632_asoc_hw_params,
-};
-
-static struct snd_soc_jack tegra_alc5632_hs_jack;
-
-static struct snd_soc_jack_pin tegra_alc5632_hs_jack_pins[] = {
- {
- .pin = "Headset Mic",
- .mask = SND_JACK_MICROPHONE,
- },
- {
- .pin = "Headset Stereophone",
- .mask = SND_JACK_HEADPHONE,
- },
-};
-
-static struct snd_soc_jack_gpio tegra_alc5632_hp_jack_gpio = {
- .name = "Headset detection",
- .report = SND_JACK_HEADSET,
- .debounce_time = 150,
- .invert = 1,
-};
-
-static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = {
- SND_SOC_DAPM_SPK("Int Spk", NULL),
- SND_SOC_DAPM_HP("Headset Stereophone", NULL),
- SND_SOC_DAPM_MIC("Headset Mic", NULL),
- SND_SOC_DAPM_MIC("Digital Mic", NULL),
-};
-
-static const struct snd_kcontrol_new tegra_alc5632_controls[] = {
- SOC_DAPM_PIN_SWITCH("Int Spk"),
-};
-
-static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- struct device_node *np = codec->card->dev->of_node;
- struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(codec->card);
-
- snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
- &tegra_alc5632_hs_jack);
- snd_soc_jack_add_pins(&tegra_alc5632_hs_jack,
- ARRAY_SIZE(tegra_alc5632_hs_jack_pins),
- tegra_alc5632_hs_jack_pins);
-
- machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0);
-
- if (gpio_is_valid(machine->gpio_hp_det)) {
- tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det;
- snd_soc_jack_add_gpios(&tegra_alc5632_hs_jack,
- 1,
- &tegra_alc5632_hp_jack_gpio);
- machine->gpio_requested |= GPIO_HP_DET;
- }
-
- snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
-
- return 0;
-}
-
-static struct snd_soc_dai_link tegra_alc5632_dai = {
- .name = "ALC5632",
- .stream_name = "ALC5632 PCM",
- .platform_name = "tegra-pcm-audio",
- .codec_dai_name = "alc5632-hifi",
- .init = tegra_alc5632_asoc_init,
- .ops = &tegra_alc5632_asoc_ops,
- .dai_fmt = SND_SOC_DAIFMT_I2S
- | SND_SOC_DAIFMT_NB_NF
- | SND_SOC_DAIFMT_CBS_CFS,
-};
-
-static struct snd_soc_card snd_soc_tegra_alc5632 = {
- .name = "tegra-alc5632",
- .owner = THIS_MODULE,
- .dai_link = &tegra_alc5632_dai,
- .num_links = 1,
- .controls = tegra_alc5632_controls,
- .num_controls = ARRAY_SIZE(tegra_alc5632_controls),
- .dapm_widgets = tegra_alc5632_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(tegra_alc5632_dapm_widgets),
- .fully_routed = true,
-};
-
-static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &snd_soc_tegra_alc5632;
- struct tegra_alc5632 *alc5632;
- int ret;
-
- alc5632 = devm_kzalloc(&pdev->dev,
- sizeof(struct tegra_alc5632), GFP_KERNEL);
- if (!alc5632) {
- dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n");
- ret = -ENOMEM;
- goto err;
- }
-
- card->dev = &pdev->dev;
- platform_set_drvdata(pdev, card);
- snd_soc_card_set_drvdata(card, alc5632);
-
- alc5632->pcm_dev = ERR_PTR(-EINVAL);
-
- if (!(pdev->dev.of_node)) {
- dev_err(&pdev->dev, "Must be instantiated using device tree\n");
- ret = -EINVAL;
- goto err;
- }
-
- ret = snd_soc_of_parse_card_name(card, "nvidia,model");
- if (ret)
- goto err;
-
- ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing");
- if (ret)
- goto err;
-
- tegra_alc5632_dai.codec_of_node = of_parse_phandle(
- pdev->dev.of_node, "nvidia,audio-codec", 0);
-
- if (!tegra_alc5632_dai.codec_of_node) {
- dev_err(&pdev->dev,
- "Property 'nvidia,audio-codec' missing or invalid\n");
- ret = -EINVAL;
- goto err;
- }
-
- tegra_alc5632_dai.cpu_dai_of_node = of_parse_phandle(
- pdev->dev.of_node, "nvidia,i2s-controller", 0);
- if (!tegra_alc5632_dai.cpu_dai_of_node) {
- dev_err(&pdev->dev,
- "Property 'nvidia,i2s-controller' missing or invalid\n");
- ret = -EINVAL;
- goto err;
- }
-
- alc5632->pcm_dev = platform_device_register_simple(
- "tegra-pcm-audio", -1, NULL, 0);
- if (IS_ERR(alc5632->pcm_dev)) {
- dev_err(&pdev->dev,
- "Can't instantiate tegra-pcm-audio\n");
- ret = PTR_ERR(alc5632->pcm_dev);
- goto err;
- }
-
- ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev);
- if (ret)
- goto err_unregister;
-
- ret = snd_soc_register_card(card);
- if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
- ret);
- goto err_fini_utils;
- }
-
- return 0;
-
-err_fini_utils:
- tegra_asoc_utils_fini(&alc5632->util_data);
-err_unregister:
- if (!IS_ERR(alc5632->pcm_dev))
- platform_device_unregister(alc5632->pcm_dev);
-err:
- return ret;
-}
-
-static int __devexit tegra_alc5632_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
- struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(card);
-
- if (machine->gpio_requested & GPIO_HP_DET)
- snd_soc_jack_free_gpios(&tegra_alc5632_hs_jack,
- 1,
- &tegra_alc5632_hp_jack_gpio);
- machine->gpio_requested = 0;
-
- snd_soc_unregister_card(card);
-
- tegra_asoc_utils_fini(&machine->util_data);
- if (!IS_ERR(machine->pcm_dev))
- platform_device_unregister(machine->pcm_dev);
-
- return 0;
-}
-
-static const struct of_device_id tegra_alc5632_of_match[] __devinitconst = {
- { .compatible = "nvidia,tegra-audio-alc5632", },
- {},
-};
-
-static struct platform_driver tegra_alc5632_driver = {
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- .pm = &snd_soc_pm_ops,
- .of_match_table = tegra_alc5632_of_match,
- },
- .probe = tegra_alc5632_probe,
- .remove = __devexit_p(tegra_alc5632_remove),
-};
-module_platform_driver(tegra_alc5632_driver);
-
-MODULE_AUTHOR("Leon Romanovsky <leon@leon.nu>");
-MODULE_DESCRIPTION("Tegra+ALC5632 machine ASoC driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" DRV_NAME);
-MODULE_DEVICE_TABLE(of, tegra_alc5632_of_match);
diff --git a/ANDROID_3.4.5/sound/soc/tegra/tegra_asoc_utils.c b/ANDROID_3.4.5/sound/soc/tegra/tegra_asoc_utils.c
deleted file mode 100644
index f8428e41..00000000
--- a/ANDROID_3.4.5/sound/soc/tegra/tegra_asoc_utils.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * tegra_asoc_utils.c - Harmony machine ASoC driver
- *
- * Author: Stephen Warren <swarren@nvidia.com>
- * Copyright (C) 2010 - NVIDIA, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/clk.h>
-#include <linux/device.h>
-#include <linux/err.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include "tegra_asoc_utils.h"
-
-int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
- int mclk)
-{
- int new_baseclock;
- bool clk_change;
- int err;
-
- switch (srate) {
- case 11025:
- case 22050:
- case 44100:
- case 88200:
- new_baseclock = 56448000;
- break;
- case 8000:
- case 16000:
- case 32000:
- case 48000:
- case 64000:
- case 96000:
- new_baseclock = 73728000;
- break;
- default:
- return -EINVAL;
- }
-
- clk_change = ((new_baseclock != data->set_baseclock) ||
- (mclk != data->set_mclk));
- if (!clk_change)
- return 0;
-
- data->set_baseclock = 0;
- data->set_mclk = 0;
-
- clk_disable(data->clk_cdev1);
- clk_disable(data->clk_pll_a_out0);
- clk_disable(data->clk_pll_a);
-
- err = clk_set_rate(data->clk_pll_a, new_baseclock);
- if (err) {
- dev_err(data->dev, "Can't set pll_a rate: %d\n", err);
- return err;
- }
-
- err = clk_set_rate(data->clk_pll_a_out0, mclk);
- if (err) {
- dev_err(data->dev, "Can't set pll_a_out0 rate: %d\n", err);
- return err;
- }
-
- /* Don't set cdev1 rate; its locked to pll_a_out0 */
-
- err = clk_enable(data->clk_pll_a);
- if (err) {
- dev_err(data->dev, "Can't enable pll_a: %d\n", err);
- return err;
- }
-
- err = clk_enable(data->clk_pll_a_out0);
- if (err) {
- dev_err(data->dev, "Can't enable pll_a_out0: %d\n", err);
- return err;
- }
-
- err = clk_enable(data->clk_cdev1);
- if (err) {
- dev_err(data->dev, "Can't enable cdev1: %d\n", err);
- return err;
- }
-
- data->set_baseclock = new_baseclock;
- data->set_mclk = mclk;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(tegra_asoc_utils_set_rate);
-
-int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
- struct device *dev)
-{
- int ret;
-
- data->dev = dev;
-
- data->clk_pll_a = clk_get_sys(NULL, "pll_a");
- if (IS_ERR(data->clk_pll_a)) {
- dev_err(data->dev, "Can't retrieve clk pll_a\n");
- ret = PTR_ERR(data->clk_pll_a);
- goto err;
- }
-
- data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0");
- if (IS_ERR(data->clk_pll_a_out0)) {
- dev_err(data->dev, "Can't retrieve clk pll_a_out0\n");
- ret = PTR_ERR(data->clk_pll_a_out0);
- goto err_put_pll_a;
- }
-
- data->clk_cdev1 = clk_get_sys(NULL, "cdev1");
- if (IS_ERR(data->clk_cdev1)) {
- dev_err(data->dev, "Can't retrieve clk cdev1\n");
- ret = PTR_ERR(data->clk_cdev1);
- goto err_put_pll_a_out0;
- }
-
- return 0;
-
-err_put_pll_a_out0:
- clk_put(data->clk_pll_a_out0);
-err_put_pll_a:
- clk_put(data->clk_pll_a);
-err:
- return ret;
-}
-EXPORT_SYMBOL_GPL(tegra_asoc_utils_init);
-
-void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data)
-{
- clk_put(data->clk_cdev1);
- clk_put(data->clk_pll_a_out0);
- clk_put(data->clk_pll_a);
-}
-EXPORT_SYMBOL_GPL(tegra_asoc_utils_fini);
-
-MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
-MODULE_DESCRIPTION("Tegra ASoC utility code");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/tegra/tegra_asoc_utils.h b/ANDROID_3.4.5/sound/soc/tegra/tegra_asoc_utils.h
deleted file mode 100644
index 4818195d..00000000
--- a/ANDROID_3.4.5/sound/soc/tegra/tegra_asoc_utils.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * tegra_asoc_utils.h - Definitions for Tegra DAS driver
- *
- * Author: Stephen Warren <swarren@nvidia.com>
- * Copyright (C) 2010 - NVIDIA, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __TEGRA_ASOC_UTILS_H__
-#define __TEGRA_ASOC_UTILS_H_
-
-struct clk;
-struct device;
-
-struct tegra_asoc_utils_data {
- struct device *dev;
- struct clk *clk_pll_a;
- struct clk *clk_pll_a_out0;
- struct clk *clk_cdev1;
- int set_baseclock;
- int set_mclk;
-};
-
-int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
- int mclk);
-int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
- struct device *dev);
-void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data);
-
-#endif
-
diff --git a/ANDROID_3.4.5/sound/soc/tegra/tegra_das.c b/ANDROID_3.4.5/sound/soc/tegra/tegra_das.c
deleted file mode 100644
index 3b3c1ba4..00000000
--- a/ANDROID_3.4.5/sound/soc/tegra/tegra_das.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * tegra_das.c - Tegra DAS driver
- *
- * Author: Stephen Warren <swarren@nvidia.com>
- * Copyright (C) 2010 - NVIDIA, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/module.h>
-#include <linux/debugfs.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/seq_file.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <mach/iomap.h>
-#include <sound/soc.h>
-#include "tegra_das.h"
-
-#define DRV_NAME "tegra-das"
-
-static struct tegra_das *das;
-
-static inline void tegra_das_write(u32 reg, u32 val)
-{
- __raw_writel(val, das->regs + reg);
-}
-
-static inline u32 tegra_das_read(u32 reg)
-{
- return __raw_readl(das->regs + reg);
-}
-
-int tegra_das_connect_dap_to_dac(int dap, int dac)
-{
- u32 addr;
- u32 reg;
-
- if (!das)
- return -ENODEV;
-
- addr = TEGRA_DAS_DAP_CTRL_SEL +
- (dap * TEGRA_DAS_DAP_CTRL_SEL_STRIDE);
- reg = dac << TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P;
-
- tegra_das_write(addr, reg);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(tegra_das_connect_dap_to_dac);
-
-int tegra_das_connect_dap_to_dap(int dap, int otherdap, int master,
- int sdata1rx, int sdata2rx)
-{
- u32 addr;
- u32 reg;
-
- if (!das)
- return -ENODEV;
-
- addr = TEGRA_DAS_DAP_CTRL_SEL +
- (dap * TEGRA_DAS_DAP_CTRL_SEL_STRIDE);
- reg = otherdap << TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P |
- !!sdata2rx << TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_P |
- !!sdata1rx << TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_P |
- !!master << TEGRA_DAS_DAP_CTRL_SEL_DAP_MS_SEL_P;
-
- tegra_das_write(addr, reg);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(tegra_das_connect_dap_to_dap);
-
-int tegra_das_connect_dac_to_dap(int dac, int dap)
-{
- u32 addr;
- u32 reg;
-
- if (!das)
- return -ENODEV;
-
- addr = TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL +
- (dac * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE);
- reg = dap << TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_P |
- dap << TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_P |
- dap << TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P;
-
- tegra_das_write(addr, reg);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(tegra_das_connect_dac_to_dap);
-
-#ifdef CONFIG_DEBUG_FS
-static int tegra_das_show(struct seq_file *s, void *unused)
-{
- int i;
- u32 addr;
- u32 reg;
-
- for (i = 0; i < TEGRA_DAS_DAP_CTRL_SEL_COUNT; i++) {
- addr = TEGRA_DAS_DAP_CTRL_SEL +
- (i * TEGRA_DAS_DAP_CTRL_SEL_STRIDE);
- reg = tegra_das_read(addr);
- seq_printf(s, "TEGRA_DAS_DAP_CTRL_SEL[%d] = %08x\n", i, reg);
- }
-
- for (i = 0; i < TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_COUNT; i++) {
- addr = TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL +
- (i * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE);
- reg = tegra_das_read(addr);
- seq_printf(s, "TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL[%d] = %08x\n",
- i, reg);
- }
-
- return 0;
-}
-
-static int tegra_das_debug_open(struct inode *inode, struct file *file)
-{
- return single_open(file, tegra_das_show, inode->i_private);
-}
-
-static const struct file_operations tegra_das_debug_fops = {
- .open = tegra_das_debug_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static void tegra_das_debug_add(struct tegra_das *das)
-{
- das->debug = debugfs_create_file(DRV_NAME, S_IRUGO,
- snd_soc_debugfs_root, das,
- &tegra_das_debug_fops);
-}
-
-static void tegra_das_debug_remove(struct tegra_das *das)
-{
- if (das->debug)
- debugfs_remove(das->debug);
-}
-#else
-static inline void tegra_das_debug_add(struct tegra_das *das)
-{
-}
-
-static inline void tegra_das_debug_remove(struct tegra_das *das)
-{
-}
-#endif
-
-static int __devinit tegra_das_probe(struct platform_device *pdev)
-{
- struct resource *res, *region;
- int ret = 0;
-
- if (das)
- return -ENODEV;
-
- das = devm_kzalloc(&pdev->dev, sizeof(struct tegra_das), GFP_KERNEL);
- if (!das) {
- dev_err(&pdev->dev, "Can't allocate tegra_das\n");
- ret = -ENOMEM;
- goto err;
- }
- das->dev = &pdev->dev;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "No memory resource\n");
- ret = -ENODEV;
- goto err;
- }
-
- region = devm_request_mem_region(&pdev->dev, res->start,
- resource_size(res), pdev->name);
- if (!region) {
- dev_err(&pdev->dev, "Memory region already claimed\n");
- ret = -EBUSY;
- goto err;
- }
-
- das->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
- if (!das->regs) {
- dev_err(&pdev->dev, "ioremap failed\n");
- ret = -ENOMEM;
- goto err;
- }
-
- ret = tegra_das_connect_dap_to_dac(TEGRA_DAS_DAP_ID_1,
- TEGRA_DAS_DAP_SEL_DAC1);
- if (ret) {
- dev_err(&pdev->dev, "Can't set up DAS DAP connection\n");
- goto err;
- }
- ret = tegra_das_connect_dac_to_dap(TEGRA_DAS_DAC_ID_1,
- TEGRA_DAS_DAC_SEL_DAP1);
- if (ret) {
- dev_err(&pdev->dev, "Can't set up DAS DAC connection\n");
- goto err;
- }
-
- tegra_das_debug_add(das);
-
- platform_set_drvdata(pdev, das);
-
- return 0;
-
-err:
- das = NULL;
- return ret;
-}
-
-static int __devexit tegra_das_remove(struct platform_device *pdev)
-{
- if (!das)
- return -ENODEV;
-
- tegra_das_debug_remove(das);
-
- das = NULL;
-
- return 0;
-}
-
-static const struct of_device_id tegra_das_of_match[] __devinitconst = {
- { .compatible = "nvidia,tegra20-das", },
- {},
-};
-
-static struct platform_driver tegra_das_driver = {
- .probe = tegra_das_probe,
- .remove = __devexit_p(tegra_das_remove),
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- .of_match_table = tegra_das_of_match,
- },
-};
-module_platform_driver(tegra_das_driver);
-
-MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
-MODULE_DESCRIPTION("Tegra DAS driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" DRV_NAME);
-MODULE_DEVICE_TABLE(of, tegra_das_of_match);
diff --git a/ANDROID_3.4.5/sound/soc/tegra/tegra_das.h b/ANDROID_3.4.5/sound/soc/tegra/tegra_das.h
deleted file mode 100644
index 2c96c7b3..00000000
--- a/ANDROID_3.4.5/sound/soc/tegra/tegra_das.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * tegra_das.h - Definitions for Tegra DAS driver
- *
- * Author: Stephen Warren <swarren@nvidia.com>
- * Copyright (C) 2010 - NVIDIA, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __TEGRA_DAS_H__
-#define __TEGRA_DAS_H__
-
-/* Register TEGRA_DAS_DAP_CTRL_SEL */
-#define TEGRA_DAS_DAP_CTRL_SEL 0x00
-#define TEGRA_DAS_DAP_CTRL_SEL_COUNT 5
-#define TEGRA_DAS_DAP_CTRL_SEL_STRIDE 4
-#define TEGRA_DAS_DAP_CTRL_SEL_DAP_MS_SEL_P 31
-#define TEGRA_DAS_DAP_CTRL_SEL_DAP_MS_SEL_S 1
-#define TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_P 30
-#define TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_S 1
-#define TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_P 29
-#define TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_S 1
-#define TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P 0
-#define TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_S 5
-
-/* Values for field TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL */
-#define TEGRA_DAS_DAP_SEL_DAC1 0
-#define TEGRA_DAS_DAP_SEL_DAC2 1
-#define TEGRA_DAS_DAP_SEL_DAC3 2
-#define TEGRA_DAS_DAP_SEL_DAP1 16
-#define TEGRA_DAS_DAP_SEL_DAP2 17
-#define TEGRA_DAS_DAP_SEL_DAP3 18
-#define TEGRA_DAS_DAP_SEL_DAP4 19
-#define TEGRA_DAS_DAP_SEL_DAP5 20
-
-/* Register TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL */
-#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL 0x40
-#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_COUNT 3
-#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE 4
-#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P 28
-#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_S 4
-#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_P 24
-#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_S 4
-#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_P 0
-#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_S 4
-
-/*
- * Values for:
- * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL
- * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL
- * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL
- */
-#define TEGRA_DAS_DAC_SEL_DAP1 0
-#define TEGRA_DAS_DAC_SEL_DAP2 1
-#define TEGRA_DAS_DAC_SEL_DAP3 2
-#define TEGRA_DAS_DAC_SEL_DAP4 3
-#define TEGRA_DAS_DAC_SEL_DAP5 4
-
-/*
- * Names/IDs of the DACs/DAPs.
- */
-
-#define TEGRA_DAS_DAP_ID_1 0
-#define TEGRA_DAS_DAP_ID_2 1
-#define TEGRA_DAS_DAP_ID_3 2
-#define TEGRA_DAS_DAP_ID_4 3
-#define TEGRA_DAS_DAP_ID_5 4
-
-#define TEGRA_DAS_DAC_ID_1 0
-#define TEGRA_DAS_DAC_ID_2 1
-#define TEGRA_DAS_DAC_ID_3 2
-
-struct tegra_das {
- struct device *dev;
- void __iomem *regs;
- struct dentry *debug;
-};
-
-/*
- * Terminology:
- * DAS: Digital audio switch (HW module controlled by this driver)
- * DAP: Digital audio port (port/pins on Tegra device)
- * DAC: Digital audio controller (e.g. I2S or AC97 controller elsewhere)
- *
- * The Tegra DAS is a mux/cross-bar which can connect each DAP to a specific
- * DAC, or another DAP. When DAPs are connected, one must be the master and
- * one the slave. Each DAC allows selection of a specific DAP for input, to
- * cater for the case where N DAPs are connected to 1 DAC for broadcast
- * output.
- *
- * This driver is dumb; no attempt is made to ensure that a valid routing
- * configuration is programmed.
- */
-
-/*
- * Connect a DAP to to a DAC
- * dap_id: DAP to connect: TEGRA_DAS_DAP_ID_*
- * dac_sel: DAC to connect to: TEGRA_DAS_DAP_SEL_DAC*
- */
-extern int tegra_das_connect_dap_to_dac(int dap_id, int dac_sel);
-
-/*
- * Connect a DAP to to another DAP
- * dap_id: DAP to connect: TEGRA_DAS_DAP_ID_*
- * other_dap_sel: DAP to connect to: TEGRA_DAS_DAP_SEL_DAP*
- * master: Is this DAP the master (1) or slave (0)
- * sdata1rx: Is this DAP's SDATA1 pin RX (1) or TX (0)
- * sdata2rx: Is this DAP's SDATA2 pin RX (1) or TX (0)
- */
-extern int tegra_das_connect_dap_to_dap(int dap_id, int other_dap_sel,
- int master, int sdata1rx,
- int sdata2rx);
-
-/*
- * Connect a DAC's input to a DAP
- * (DAC outputs are selected by the DAP)
- * dac_id: DAC ID to connect: TEGRA_DAS_DAC_ID_*
- * dap_sel: DAP to receive input from: TEGRA_DAS_DAC_SEL_DAP*
- */
-extern int tegra_das_connect_dac_to_dap(int dac_id, int dap_sel);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/tegra/tegra_i2s.c b/ANDROID_3.4.5/sound/soc/tegra/tegra_i2s.c
deleted file mode 100644
index e5334991..00000000
--- a/ANDROID_3.4.5/sound/soc/tegra/tegra_i2s.c
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * tegra_i2s.c - Tegra I2S driver
- *
- * Author: Stephen Warren <swarren@nvidia.com>
- * Copyright (C) 2010 - NVIDIA, Inc.
- *
- * Based on code copyright/by:
- *
- * Copyright (c) 2009-2010, NVIDIA Corporation.
- * Scott Peterson <speterson@nvidia.com>
- *
- * Copyright (C) 2010 Google, Inc.
- * Iliyan Malchev <malchev@google.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/clk.h>
-#include <linux/module.h>
-#include <linux/debugfs.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/seq_file.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <mach/iomap.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include "tegra_i2s.h"
-
-#define DRV_NAME "tegra-i2s"
-
-static inline void tegra_i2s_write(struct tegra_i2s *i2s, u32 reg, u32 val)
-{
- __raw_writel(val, i2s->regs + reg);
-}
-
-static inline u32 tegra_i2s_read(struct tegra_i2s *i2s, u32 reg)
-{
- return __raw_readl(i2s->regs + reg);
-}
-
-#ifdef CONFIG_DEBUG_FS
-static int tegra_i2s_show(struct seq_file *s, void *unused)
-{
-#define REG(r) { r, #r }
- static const struct {
- int offset;
- const char *name;
- } regs[] = {
- REG(TEGRA_I2S_CTRL),
- REG(TEGRA_I2S_STATUS),
- REG(TEGRA_I2S_TIMING),
- REG(TEGRA_I2S_FIFO_SCR),
- REG(TEGRA_I2S_PCM_CTRL),
- REG(TEGRA_I2S_NW_CTRL),
- REG(TEGRA_I2S_TDM_CTRL),
- REG(TEGRA_I2S_TDM_TX_RX_CTRL),
- };
-#undef REG
-
- struct tegra_i2s *i2s = s->private;
- int i;
-
- clk_enable(i2s->clk_i2s);
-
- for (i = 0; i < ARRAY_SIZE(regs); i++) {
- u32 val = tegra_i2s_read(i2s, regs[i].offset);
- seq_printf(s, "%s = %08x\n", regs[i].name, val);
- }
-
- clk_disable(i2s->clk_i2s);
-
- return 0;
-}
-
-static int tegra_i2s_debug_open(struct inode *inode, struct file *file)
-{
- return single_open(file, tegra_i2s_show, inode->i_private);
-}
-
-static const struct file_operations tegra_i2s_debug_fops = {
- .open = tegra_i2s_debug_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static void tegra_i2s_debug_add(struct tegra_i2s *i2s)
-{
- i2s->debug = debugfs_create_file(i2s->dai.name, S_IRUGO,
- snd_soc_debugfs_root, i2s,
- &tegra_i2s_debug_fops);
-}
-
-static void tegra_i2s_debug_remove(struct tegra_i2s *i2s)
-{
- if (i2s->debug)
- debugfs_remove(i2s->debug);
-}
-#else
-static inline void tegra_i2s_debug_add(struct tegra_i2s *i2s)
-{
-}
-
-static inline void tegra_i2s_debug_remove(struct tegra_i2s *i2s)
-{
-}
-#endif
-
-static int tegra_i2s_set_fmt(struct snd_soc_dai *dai,
- unsigned int fmt)
-{
- struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- default:
- return -EINVAL;
- }
-
- i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_MASTER_ENABLE;
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- i2s->reg_ctrl |= TEGRA_I2S_CTRL_MASTER_ENABLE;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- break;
- default:
- return -EINVAL;
- }
-
- i2s->reg_ctrl &= ~(TEGRA_I2S_CTRL_BIT_FORMAT_MASK |
- TEGRA_I2S_CTRL_LRCK_MASK);
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_DSP;
- i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_DSP;
- i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_R_LOW;
- break;
- case SND_SOC_DAIFMT_I2S:
- i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_I2S;
- i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_RJM;
- i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_LJM;
- i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int tegra_i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct device *dev = substream->pcm->card->dev;
- struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai);
- u32 reg;
- int ret, sample_size, srate, i2sclock, bitcnt;
-
- i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_BIT_SIZE_MASK;
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_16;
- sample_size = 16;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_24;
- sample_size = 24;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_32;
- sample_size = 32;
- break;
- default:
- return -EINVAL;
- }
-
- srate = params_rate(params);
-
- /* Final "* 2" required by Tegra hardware */
- i2sclock = srate * params_channels(params) * sample_size * 2;
-
- ret = clk_set_rate(i2s->clk_i2s, i2sclock);
- if (ret) {
- dev_err(dev, "Can't set I2S clock rate: %d\n", ret);
- return ret;
- }
-
- bitcnt = (i2sclock / (2 * srate)) - 1;
- if (bitcnt < 0 || bitcnt > TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US)
- return -EINVAL;
- reg = bitcnt << TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT;
-
- if (i2sclock % (2 * srate))
- reg |= TEGRA_I2S_TIMING_NON_SYM_ENABLE;
-
- if (!i2s->clk_refs)
- clk_enable(i2s->clk_i2s);
-
- tegra_i2s_write(i2s, TEGRA_I2S_TIMING, reg);
-
- tegra_i2s_write(i2s, TEGRA_I2S_FIFO_SCR,
- TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS |
- TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS);
-
- if (!i2s->clk_refs)
- clk_disable(i2s->clk_i2s);
-
- return 0;
-}
-
-static void tegra_i2s_start_playback(struct tegra_i2s *i2s)
-{
- i2s->reg_ctrl |= TEGRA_I2S_CTRL_FIFO1_ENABLE;
- tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl);
-}
-
-static void tegra_i2s_stop_playback(struct tegra_i2s *i2s)
-{
- i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_FIFO1_ENABLE;
- tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl);
-}
-
-static void tegra_i2s_start_capture(struct tegra_i2s *i2s)
-{
- i2s->reg_ctrl |= TEGRA_I2S_CTRL_FIFO2_ENABLE;
- tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl);
-}
-
-static void tegra_i2s_stop_capture(struct tegra_i2s *i2s)
-{
- i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_FIFO2_ENABLE;
- tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl);
-}
-
-static int tegra_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
- if (!i2s->clk_refs)
- clk_enable(i2s->clk_i2s);
- i2s->clk_refs++;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- tegra_i2s_start_playback(i2s);
- else
- tegra_i2s_start_capture(i2s);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- tegra_i2s_stop_playback(i2s);
- else
- tegra_i2s_stop_capture(i2s);
- i2s->clk_refs--;
- if (!i2s->clk_refs)
- clk_disable(i2s->clk_i2s);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int tegra_i2s_probe(struct snd_soc_dai *dai)
-{
- struct tegra_i2s * i2s = snd_soc_dai_get_drvdata(dai);
-
- dai->capture_dma_data = &i2s->capture_dma_data;
- dai->playback_dma_data = &i2s->playback_dma_data;
-
- return 0;
-}
-
-static const struct snd_soc_dai_ops tegra_i2s_dai_ops = {
- .set_fmt = tegra_i2s_set_fmt,
- .hw_params = tegra_i2s_hw_params,
- .trigger = tegra_i2s_trigger,
-};
-
-static const struct snd_soc_dai_driver tegra_i2s_dai_template = {
- .probe = tegra_i2s_probe,
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_96000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .ops = &tegra_i2s_dai_ops,
- .symmetric_rates = 1,
-};
-
-static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev)
-{
- struct tegra_i2s * i2s;
- struct resource *mem, *memregion, *dmareq;
- u32 of_dma[2];
- u32 dma_ch;
- int ret;
-
- i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra_i2s), GFP_KERNEL);
- if (!i2s) {
- dev_err(&pdev->dev, "Can't allocate tegra_i2s\n");
- ret = -ENOMEM;
- goto err;
- }
- dev_set_drvdata(&pdev->dev, i2s);
-
- i2s->dai = tegra_i2s_dai_template;
- i2s->dai.name = dev_name(&pdev->dev);
-
- i2s->clk_i2s = clk_get(&pdev->dev, NULL);
- if (IS_ERR(i2s->clk_i2s)) {
- dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
- ret = PTR_ERR(i2s->clk_i2s);
- goto err;
- }
-
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem) {
- dev_err(&pdev->dev, "No memory resource\n");
- ret = -ENODEV;
- goto err_clk_put;
- }
-
- dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!dmareq) {
- if (of_property_read_u32_array(pdev->dev.of_node,
- "nvidia,dma-request-selector",
- of_dma, 2) < 0) {
- dev_err(&pdev->dev, "No DMA resource\n");
- ret = -ENODEV;
- goto err_clk_put;
- }
- dma_ch = of_dma[1];
- } else {
- dma_ch = dmareq->start;
- }
-
- memregion = devm_request_mem_region(&pdev->dev, mem->start,
- resource_size(mem), DRV_NAME);
- if (!memregion) {
- dev_err(&pdev->dev, "Memory region already claimed\n");
- ret = -EBUSY;
- goto err_clk_put;
- }
-
- i2s->regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
- if (!i2s->regs) {
- dev_err(&pdev->dev, "ioremap failed\n");
- ret = -ENOMEM;
- goto err_clk_put;
- }
-
- i2s->capture_dma_data.addr = mem->start + TEGRA_I2S_FIFO2;
- i2s->capture_dma_data.wrap = 4;
- i2s->capture_dma_data.width = 32;
- i2s->capture_dma_data.req_sel = dma_ch;
-
- i2s->playback_dma_data.addr = mem->start + TEGRA_I2S_FIFO1;
- i2s->playback_dma_data.wrap = 4;
- i2s->playback_dma_data.width = 32;
- i2s->playback_dma_data.req_sel = dma_ch;
-
- i2s->reg_ctrl = TEGRA_I2S_CTRL_FIFO_FORMAT_PACKED;
-
- ret = snd_soc_register_dai(&pdev->dev, &i2s->dai);
- if (ret) {
- dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
- ret = -ENOMEM;
- goto err_clk_put;
- }
-
- tegra_i2s_debug_add(i2s);
-
- return 0;
-
-err_clk_put:
- clk_put(i2s->clk_i2s);
-err:
- return ret;
-}
-
-static int __devexit tegra_i2s_platform_remove(struct platform_device *pdev)
-{
- struct tegra_i2s *i2s = dev_get_drvdata(&pdev->dev);
-
- snd_soc_unregister_dai(&pdev->dev);
-
- tegra_i2s_debug_remove(i2s);
-
- clk_put(i2s->clk_i2s);
-
- return 0;
-}
-
-static const struct of_device_id tegra_i2s_of_match[] __devinitconst = {
- { .compatible = "nvidia,tegra20-i2s", },
- {},
-};
-
-static struct platform_driver tegra_i2s_driver = {
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- .of_match_table = tegra_i2s_of_match,
- },
- .probe = tegra_i2s_platform_probe,
- .remove = __devexit_p(tegra_i2s_platform_remove),
-};
-module_platform_driver(tegra_i2s_driver);
-
-MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
-MODULE_DESCRIPTION("Tegra I2S ASoC driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" DRV_NAME);
-MODULE_DEVICE_TABLE(of, tegra_i2s_of_match);
diff --git a/ANDROID_3.4.5/sound/soc/tegra/tegra_i2s.h b/ANDROID_3.4.5/sound/soc/tegra/tegra_i2s.h
deleted file mode 100644
index 15ce1e2e..00000000
--- a/ANDROID_3.4.5/sound/soc/tegra/tegra_i2s.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * tegra_i2s.h - Definitions for Tegra I2S driver
- *
- * Author: Stephen Warren <swarren@nvidia.com>
- * Copyright (C) 2010 - NVIDIA, Inc.
- *
- * Based on code copyright/by:
- *
- * Copyright (c) 2009-2010, NVIDIA Corporation.
- * Scott Peterson <speterson@nvidia.com>
- *
- * Copyright (C) 2010 Google, Inc.
- * Iliyan Malchev <malchev@google.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __TEGRA_I2S_H__
-#define __TEGRA_I2S_H__
-
-#include "tegra_pcm.h"
-
-/* Register offsets from TEGRA_I2S1_BASE and TEGRA_I2S2_BASE */
-
-#define TEGRA_I2S_CTRL 0x00
-#define TEGRA_I2S_STATUS 0x04
-#define TEGRA_I2S_TIMING 0x08
-#define TEGRA_I2S_FIFO_SCR 0x0c
-#define TEGRA_I2S_PCM_CTRL 0x10
-#define TEGRA_I2S_NW_CTRL 0x14
-#define TEGRA_I2S_TDM_CTRL 0x20
-#define TEGRA_I2S_TDM_TX_RX_CTRL 0x24
-#define TEGRA_I2S_FIFO1 0x40
-#define TEGRA_I2S_FIFO2 0x80
-
-/* Fields in TEGRA_I2S_CTRL */
-
-#define TEGRA_I2S_CTRL_FIFO2_TX_ENABLE (1 << 30)
-#define TEGRA_I2S_CTRL_FIFO1_ENABLE (1 << 29)
-#define TEGRA_I2S_CTRL_FIFO2_ENABLE (1 << 28)
-#define TEGRA_I2S_CTRL_FIFO1_RX_ENABLE (1 << 27)
-#define TEGRA_I2S_CTRL_FIFO_LPBK_ENABLE (1 << 26)
-#define TEGRA_I2S_CTRL_MASTER_ENABLE (1 << 25)
-
-#define TEGRA_I2S_LRCK_LEFT_LOW 0
-#define TEGRA_I2S_LRCK_RIGHT_LOW 1
-
-#define TEGRA_I2S_CTRL_LRCK_SHIFT 24
-#define TEGRA_I2S_CTRL_LRCK_MASK (1 << TEGRA_I2S_CTRL_LRCK_SHIFT)
-#define TEGRA_I2S_CTRL_LRCK_L_LOW (TEGRA_I2S_LRCK_LEFT_LOW << TEGRA_I2S_CTRL_LRCK_SHIFT)
-#define TEGRA_I2S_CTRL_LRCK_R_LOW (TEGRA_I2S_LRCK_RIGHT_LOW << TEGRA_I2S_CTRL_LRCK_SHIFT)
-
-#define TEGRA_I2S_BIT_FORMAT_I2S 0
-#define TEGRA_I2S_BIT_FORMAT_RJM 1
-#define TEGRA_I2S_BIT_FORMAT_LJM 2
-#define TEGRA_I2S_BIT_FORMAT_DSP 3
-
-#define TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT 10
-#define TEGRA_I2S_CTRL_BIT_FORMAT_MASK (3 << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
-#define TEGRA_I2S_CTRL_BIT_FORMAT_I2S (TEGRA_I2S_BIT_FORMAT_I2S << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
-#define TEGRA_I2S_CTRL_BIT_FORMAT_RJM (TEGRA_I2S_BIT_FORMAT_RJM << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
-#define TEGRA_I2S_CTRL_BIT_FORMAT_LJM (TEGRA_I2S_BIT_FORMAT_LJM << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
-#define TEGRA_I2S_CTRL_BIT_FORMAT_DSP (TEGRA_I2S_BIT_FORMAT_DSP << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
-
-#define TEGRA_I2S_BIT_SIZE_16 0
-#define TEGRA_I2S_BIT_SIZE_20 1
-#define TEGRA_I2S_BIT_SIZE_24 2
-#define TEGRA_I2S_BIT_SIZE_32 3
-
-#define TEGRA_I2S_CTRL_BIT_SIZE_SHIFT 8
-#define TEGRA_I2S_CTRL_BIT_SIZE_MASK (3 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
-#define TEGRA_I2S_CTRL_BIT_SIZE_16 (TEGRA_I2S_BIT_SIZE_16 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
-#define TEGRA_I2S_CTRL_BIT_SIZE_20 (TEGRA_I2S_BIT_SIZE_20 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
-#define TEGRA_I2S_CTRL_BIT_SIZE_24 (TEGRA_I2S_BIT_SIZE_24 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
-#define TEGRA_I2S_CTRL_BIT_SIZE_32 (TEGRA_I2S_BIT_SIZE_32 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
-
-#define TEGRA_I2S_FIFO_16_LSB 0
-#define TEGRA_I2S_FIFO_20_LSB 1
-#define TEGRA_I2S_FIFO_24_LSB 2
-#define TEGRA_I2S_FIFO_32 3
-#define TEGRA_I2S_FIFO_PACKED 7
-
-#define TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT 4
-#define TEGRA_I2S_CTRL_FIFO_FORMAT_MASK (7 << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
-#define TEGRA_I2S_CTRL_FIFO_FORMAT_16_LSB (TEGRA_I2S_FIFO_16_LSB << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
-#define TEGRA_I2S_CTRL_FIFO_FORMAT_20_LSB (TEGRA_I2S_FIFO_20_LSB << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
-#define TEGRA_I2S_CTRL_FIFO_FORMAT_24_LSB (TEGRA_I2S_FIFO_24_LSB << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
-#define TEGRA_I2S_CTRL_FIFO_FORMAT_32 (TEGRA_I2S_FIFO_32 << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
-#define TEGRA_I2S_CTRL_FIFO_FORMAT_PACKED (TEGRA_I2S_FIFO_PACKED << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
-
-#define TEGRA_I2S_CTRL_IE_FIFO1_ERR (1 << 3)
-#define TEGRA_I2S_CTRL_IE_FIFO2_ERR (1 << 2)
-#define TEGRA_I2S_CTRL_QE_FIFO1 (1 << 1)
-#define TEGRA_I2S_CTRL_QE_FIFO2 (1 << 0)
-
-/* Fields in TEGRA_I2S_STATUS */
-
-#define TEGRA_I2S_STATUS_FIFO1_RDY (1 << 31)
-#define TEGRA_I2S_STATUS_FIFO2_RDY (1 << 30)
-#define TEGRA_I2S_STATUS_FIFO1_BSY (1 << 29)
-#define TEGRA_I2S_STATUS_FIFO2_BSY (1 << 28)
-#define TEGRA_I2S_STATUS_FIFO1_ERR (1 << 3)
-#define TEGRA_I2S_STATUS_FIFO2_ERR (1 << 2)
-#define TEGRA_I2S_STATUS_QS_FIFO1 (1 << 1)
-#define TEGRA_I2S_STATUS_QS_FIFO2 (1 << 0)
-
-/* Fields in TEGRA_I2S_TIMING */
-
-#define TEGRA_I2S_TIMING_NON_SYM_ENABLE (1 << 12)
-#define TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT 0
-#define TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US 0x7fff
-#define TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK (TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US << TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT)
-
-/* Fields in TEGRA_I2S_FIFO_SCR */
-
-#define TEGRA_I2S_FIFO_SCR_FIFO2_FULL_EMPTY_COUNT_SHIFT 24
-#define TEGRA_I2S_FIFO_SCR_FIFO1_FULL_EMPTY_COUNT_SHIFT 16
-#define TEGRA_I2S_FIFO_SCR_FIFO_FULL_EMPTY_COUNT_MASK 0x3f
-
-#define TEGRA_I2S_FIFO_SCR_FIFO2_CLR (1 << 12)
-#define TEGRA_I2S_FIFO_SCR_FIFO1_CLR (1 << 8)
-
-#define TEGRA_I2S_FIFO_ATN_LVL_ONE_SLOT 0
-#define TEGRA_I2S_FIFO_ATN_LVL_FOUR_SLOTS 1
-#define TEGRA_I2S_FIFO_ATN_LVL_EIGHT_SLOTS 2
-#define TEGRA_I2S_FIFO_ATN_LVL_TWELVE_SLOTS 3
-
-#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT 4
-#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_MASK (3 << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
-#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_ONE_SLOT (TEGRA_I2S_FIFO_ATN_LVL_ONE_SLOT << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
-#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_FOUR_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
-#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_EIGHT_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_EIGHT_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
-#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_TWELVE_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
-
-#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT 0
-#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_MASK (3 << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
-#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_ONE_SLOT (TEGRA_I2S_FIFO_ATN_LVL_ONE_SLOT << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
-#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_FOUR_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
-#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_EIGHT_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_EIGHT_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
-#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_TWELVE_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
-
-struct tegra_i2s {
- struct snd_soc_dai_driver dai;
- struct clk *clk_i2s;
- int clk_refs;
- struct tegra_pcm_dma_params capture_dma_data;
- struct tegra_pcm_dma_params playback_dma_data;
- void __iomem *regs;
- struct dentry *debug;
- u32 reg_ctrl;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/tegra/tegra_pcm.c b/ANDROID_3.4.5/sound/soc/tegra/tegra_pcm.c
deleted file mode 100644
index 8b445713..00000000
--- a/ANDROID_3.4.5/sound/soc/tegra/tegra_pcm.c
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * tegra_pcm.c - Tegra PCM driver
- *
- * Author: Stephen Warren <swarren@nvidia.com>
- * Copyright (C) 2010 - NVIDIA, Inc.
- *
- * Based on code copyright/by:
- *
- * Copyright (c) 2009-2010, NVIDIA Corporation.
- * Scott Peterson <speterson@nvidia.com>
- * Vijay Mali <vmali@nvidia.com>
- *
- * Copyright (C) 2010 Google, Inc.
- * Iliyan Malchev <malchev@google.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include "tegra_pcm.h"
-
-#define DRV_NAME "tegra-pcm-audio"
-
-static const struct snd_pcm_hardware tegra_pcm_hardware = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_INTERLEAVED,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .channels_min = 2,
- .channels_max = 2,
- .period_bytes_min = 1024,
- .period_bytes_max = PAGE_SIZE,
- .periods_min = 2,
- .periods_max = 8,
- .buffer_bytes_max = PAGE_SIZE * 8,
- .fifo_size = 4,
-};
-
-static void tegra_pcm_queue_dma(struct tegra_runtime_data *prtd)
-{
- struct snd_pcm_substream *substream = prtd->substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- struct tegra_dma_req *dma_req;
- unsigned long addr;
-
- dma_req = &prtd->dma_req[prtd->dma_req_idx];
- prtd->dma_req_idx = 1 - prtd->dma_req_idx;
-
- addr = buf->addr + prtd->dma_pos;
- prtd->dma_pos += dma_req->size;
- if (prtd->dma_pos >= prtd->dma_pos_end)
- prtd->dma_pos = 0;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dma_req->source_addr = addr;
- else
- dma_req->dest_addr = addr;
-
- tegra_dma_enqueue_req(prtd->dma_chan, dma_req);
-}
-
-static void dma_complete_callback(struct tegra_dma_req *req)
-{
- struct tegra_runtime_data *prtd = (struct tegra_runtime_data *)req->dev;
- struct snd_pcm_substream *substream = prtd->substream;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- spin_lock(&prtd->lock);
-
- if (!prtd->running) {
- spin_unlock(&prtd->lock);
- return;
- }
-
- if (++prtd->period_index >= runtime->periods)
- prtd->period_index = 0;
-
- tegra_pcm_queue_dma(prtd);
-
- spin_unlock(&prtd->lock);
-
- snd_pcm_period_elapsed(substream);
-}
-
-static void setup_dma_tx_request(struct tegra_dma_req *req,
- struct tegra_pcm_dma_params * dmap)
-{
- req->complete = dma_complete_callback;
- req->to_memory = false;
- req->dest_addr = dmap->addr;
- req->dest_wrap = dmap->wrap;
- req->source_bus_width = 32;
- req->source_wrap = 0;
- req->dest_bus_width = dmap->width;
- req->req_sel = dmap->req_sel;
-}
-
-static void setup_dma_rx_request(struct tegra_dma_req *req,
- struct tegra_pcm_dma_params * dmap)
-{
- req->complete = dma_complete_callback;
- req->to_memory = true;
- req->source_addr = dmap->addr;
- req->dest_wrap = 0;
- req->source_bus_width = dmap->width;
- req->source_wrap = dmap->wrap;
- req->dest_bus_width = 32;
- req->req_sel = dmap->req_sel;
-}
-
-static int tegra_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct tegra_runtime_data *prtd;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct tegra_pcm_dma_params * dmap;
- int ret = 0;
-
- prtd = kzalloc(sizeof(struct tegra_runtime_data), GFP_KERNEL);
- if (prtd == NULL)
- return -ENOMEM;
-
- runtime->private_data = prtd;
- prtd->substream = substream;
-
- spin_lock_init(&prtd->lock);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
- setup_dma_tx_request(&prtd->dma_req[0], dmap);
- setup_dma_tx_request(&prtd->dma_req[1], dmap);
- } else {
- dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
- setup_dma_rx_request(&prtd->dma_req[0], dmap);
- setup_dma_rx_request(&prtd->dma_req[1], dmap);
- }
-
- prtd->dma_req[0].dev = prtd;
- prtd->dma_req[1].dev = prtd;
-
- prtd->dma_chan = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT);
- if (prtd->dma_chan == NULL) {
- ret = -ENOMEM;
- goto err;
- }
-
- /* Set HW params now that initialization is complete */
- snd_soc_set_runtime_hwparams(substream, &tegra_pcm_hardware);
-
- /* Ensure that buffer size is a multiple of period size */
- ret = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (ret < 0)
- goto err;
-
- return 0;
-
-err:
- if (prtd->dma_chan) {
- tegra_dma_free_channel(prtd->dma_chan);
- }
-
- kfree(prtd);
-
- return ret;
-}
-
-static int tegra_pcm_close(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct tegra_runtime_data *prtd = runtime->private_data;
-
- tegra_dma_free_channel(prtd->dma_chan);
-
- kfree(prtd);
-
- return 0;
-}
-
-static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct tegra_runtime_data *prtd = runtime->private_data;
-
- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
-
- prtd->dma_req[0].size = params_period_bytes(params);
- prtd->dma_req[1].size = prtd->dma_req[0].size;
-
- return 0;
-}
-
-static int tegra_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- snd_pcm_set_runtime_buffer(substream, NULL);
-
- return 0;
-}
-
-static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct tegra_runtime_data *prtd = runtime->private_data;
- unsigned long flags;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- prtd->dma_pos = 0;
- prtd->dma_pos_end = frames_to_bytes(runtime, runtime->periods * runtime->period_size);
- prtd->period_index = 0;
- prtd->dma_req_idx = 0;
- /* Fall-through */
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- spin_lock_irqsave(&prtd->lock, flags);
- prtd->running = 1;
- spin_unlock_irqrestore(&prtd->lock, flags);
- tegra_pcm_queue_dma(prtd);
- tegra_pcm_queue_dma(prtd);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- spin_lock_irqsave(&prtd->lock, flags);
- prtd->running = 0;
- spin_unlock_irqrestore(&prtd->lock, flags);
- tegra_dma_dequeue_req(prtd->dma_chan, &prtd->dma_req[0]);
- tegra_dma_dequeue_req(prtd->dma_chan, &prtd->dma_req[1]);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static snd_pcm_uframes_t tegra_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct tegra_runtime_data *prtd = runtime->private_data;
-
- return prtd->period_index * runtime->period_size;
-}
-
-
-static int tegra_pcm_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- return dma_mmap_writecombine(substream->pcm->card->dev, vma,
- runtime->dma_area,
- runtime->dma_addr,
- runtime->dma_bytes);
-}
-
-static struct snd_pcm_ops tegra_pcm_ops = {
- .open = tegra_pcm_open,
- .close = tegra_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = tegra_pcm_hw_params,
- .hw_free = tegra_pcm_hw_free,
- .trigger = tegra_pcm_trigger,
- .pointer = tegra_pcm_pointer,
- .mmap = tegra_pcm_mmap,
-};
-
-static int tegra_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
- struct snd_pcm_substream *substream = pcm->streams[stream].substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = tegra_pcm_hardware.buffer_bytes_max;
-
- buf->area = dma_alloc_writecombine(pcm->card->dev, size,
- &buf->addr, GFP_KERNEL);
- if (!buf->area)
- return -ENOMEM;
-
- buf->dev.type = SNDRV_DMA_TYPE_DEV;
- buf->dev.dev = pcm->card->dev;
- buf->private_data = NULL;
- buf->bytes = size;
-
- return 0;
-}
-
-static void tegra_pcm_deallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
- struct snd_pcm_substream *substream;
- struct snd_dma_buffer *buf;
-
- substream = pcm->streams[stream].substream;
- if (!substream)
- return;
-
- buf = &substream->dma_buffer;
- if (!buf->area)
- return;
-
- dma_free_writecombine(pcm->card->dev, buf->bytes,
- buf->area, buf->addr);
- buf->area = NULL;
-}
-
-static u64 tegra_dma_mask = DMA_BIT_MASK(32);
-
-static int tegra_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- int ret = 0;
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &tegra_dma_mask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = tegra_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_PLAYBACK);
- if (ret)
- goto err;
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- ret = tegra_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_CAPTURE);
- if (ret)
- goto err_free_play;
- }
-
- return 0;
-
-err_free_play:
- tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK);
-err:
- return ret;
-}
-
-static void tegra_pcm_free(struct snd_pcm *pcm)
-{
- tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE);
- tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK);
-}
-
-static struct snd_soc_platform_driver tegra_pcm_platform = {
- .ops = &tegra_pcm_ops,
- .pcm_new = tegra_pcm_new,
- .pcm_free = tegra_pcm_free,
-};
-
-static int __devinit tegra_pcm_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_platform(&pdev->dev, &tegra_pcm_platform);
-}
-
-static int __devexit tegra_pcm_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver tegra_pcm_driver = {
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- },
- .probe = tegra_pcm_platform_probe,
- .remove = __devexit_p(tegra_pcm_platform_remove),
-};
-module_platform_driver(tegra_pcm_driver);
-
-MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
-MODULE_DESCRIPTION("Tegra PCM ASoC driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/ANDROID_3.4.5/sound/soc/tegra/tegra_pcm.h b/ANDROID_3.4.5/sound/soc/tegra/tegra_pcm.h
deleted file mode 100644
index dbb90339..00000000
--- a/ANDROID_3.4.5/sound/soc/tegra/tegra_pcm.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * tegra_pcm.h - Definitions for Tegra PCM driver
- *
- * Author: Stephen Warren <swarren@nvidia.com>
- * Copyright (C) 2010 - NVIDIA, Inc.
- *
- * Based on code copyright/by:
- *
- * Copyright (c) 2009-2010, NVIDIA Corporation.
- * Scott Peterson <speterson@nvidia.com>
- *
- * Copyright (C) 2010 Google, Inc.
- * Iliyan Malchev <malchev@google.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __TEGRA_PCM_H__
-#define __TEGRA_PCM_H__
-
-#include <mach/dma.h>
-
-struct tegra_pcm_dma_params {
- unsigned long addr;
- unsigned long wrap;
- unsigned long width;
- unsigned long req_sel;
-};
-
-struct tegra_runtime_data {
- struct snd_pcm_substream *substream;
- spinlock_t lock;
- int running;
- int dma_pos;
- int dma_pos_end;
- int period_index;
- int dma_req_idx;
- struct tegra_dma_req dma_req[2];
- struct tegra_dma_channel *dma_chan;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/tegra/tegra_spdif.c b/ANDROID_3.4.5/sound/soc/tegra/tegra_spdif.c
deleted file mode 100644
index 9ff2c601..00000000
--- a/ANDROID_3.4.5/sound/soc/tegra/tegra_spdif.c
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * tegra_spdif.c - Tegra SPDIF driver
- *
- * Author: Stephen Warren <swarren@nvidia.com>
- * Copyright (C) 2011 - NVIDIA, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/clk.h>
-#include <linux/module.h>
-#include <linux/debugfs.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/seq_file.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <mach/iomap.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include "tegra_spdif.h"
-
-#define DRV_NAME "tegra-spdif"
-
-static inline void tegra_spdif_write(struct tegra_spdif *spdif, u32 reg,
- u32 val)
-{
- __raw_writel(val, spdif->regs + reg);
-}
-
-static inline u32 tegra_spdif_read(struct tegra_spdif *spdif, u32 reg)
-{
- return __raw_readl(spdif->regs + reg);
-}
-
-#ifdef CONFIG_DEBUG_FS
-static int tegra_spdif_show(struct seq_file *s, void *unused)
-{
-#define REG(r) { r, #r }
- static const struct {
- int offset;
- const char *name;
- } regs[] = {
- REG(TEGRA_SPDIF_CTRL),
- REG(TEGRA_SPDIF_STATUS),
- REG(TEGRA_SPDIF_STROBE_CTRL),
- REG(TEGRA_SPDIF_DATA_FIFO_CSR),
- REG(TEGRA_SPDIF_CH_STA_RX_A),
- REG(TEGRA_SPDIF_CH_STA_RX_B),
- REG(TEGRA_SPDIF_CH_STA_RX_C),
- REG(TEGRA_SPDIF_CH_STA_RX_D),
- REG(TEGRA_SPDIF_CH_STA_RX_E),
- REG(TEGRA_SPDIF_CH_STA_RX_F),
- REG(TEGRA_SPDIF_CH_STA_TX_A),
- REG(TEGRA_SPDIF_CH_STA_TX_B),
- REG(TEGRA_SPDIF_CH_STA_TX_C),
- REG(TEGRA_SPDIF_CH_STA_TX_D),
- REG(TEGRA_SPDIF_CH_STA_TX_E),
- REG(TEGRA_SPDIF_CH_STA_TX_F),
- };
-#undef REG
-
- struct tegra_spdif *spdif = s->private;
- int i;
-
- clk_enable(spdif->clk_spdif_out);
-
- for (i = 0; i < ARRAY_SIZE(regs); i++) {
- u32 val = tegra_spdif_read(spdif, regs[i].offset);
- seq_printf(s, "%s = %08x\n", regs[i].name, val);
- }
-
- clk_disable(spdif->clk_spdif_out);
-
- return 0;
-}
-
-static int tegra_spdif_debug_open(struct inode *inode, struct file *file)
-{
- return single_open(file, tegra_spdif_show, inode->i_private);
-}
-
-static const struct file_operations tegra_spdif_debug_fops = {
- .open = tegra_spdif_debug_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static void tegra_spdif_debug_add(struct tegra_spdif *spdif)
-{
- spdif->debug = debugfs_create_file(DRV_NAME, S_IRUGO,
- snd_soc_debugfs_root, spdif,
- &tegra_spdif_debug_fops);
-}
-
-static void tegra_spdif_debug_remove(struct tegra_spdif *spdif)
-{
- if (spdif->debug)
- debugfs_remove(spdif->debug);
-}
-#else
-static inline void tegra_spdif_debug_add(struct tegra_spdif *spdif)
-{
-}
-
-static inline void tegra_spdif_debug_remove(struct tegra_spdif *spdif)
-{
-}
-#endif
-
-static int tegra_spdif_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct device *dev = substream->pcm->card->dev;
- struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai);
- int ret, spdifclock;
-
- spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_PACK;
- spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_BIT_MODE_MASK;
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- spdif->reg_ctrl |= TEGRA_SPDIF_CTRL_PACK;
- spdif->reg_ctrl |= TEGRA_SPDIF_CTRL_BIT_MODE_16BIT;
- break;
- default:
- return -EINVAL;
- }
-
- switch (params_rate(params)) {
- case 32000:
- spdifclock = 4096000;
- break;
- case 44100:
- spdifclock = 5644800;
- break;
- case 48000:
- spdifclock = 6144000;
- break;
- case 88200:
- spdifclock = 11289600;
- break;
- case 96000:
- spdifclock = 12288000;
- break;
- case 176400:
- spdifclock = 22579200;
- break;
- case 192000:
- spdifclock = 24576000;
- break;
- default:
- return -EINVAL;
- }
-
- ret = clk_set_rate(spdif->clk_spdif_out, spdifclock);
- if (ret) {
- dev_err(dev, "Can't set SPDIF clock rate: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-static void tegra_spdif_start_playback(struct tegra_spdif *spdif)
-{
- spdif->reg_ctrl |= TEGRA_SPDIF_CTRL_TX_EN;
- tegra_spdif_write(spdif, TEGRA_SPDIF_CTRL, spdif->reg_ctrl);
-}
-
-static void tegra_spdif_stop_playback(struct tegra_spdif *spdif)
-{
- spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_TX_EN;
- tegra_spdif_write(spdif, TEGRA_SPDIF_CTRL, spdif->reg_ctrl);
-}
-
-static int tegra_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
- if (!spdif->clk_refs)
- clk_enable(spdif->clk_spdif_out);
- spdif->clk_refs++;
- tegra_spdif_start_playback(spdif);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- tegra_spdif_stop_playback(spdif);
- spdif->clk_refs--;
- if (!spdif->clk_refs)
- clk_disable(spdif->clk_spdif_out);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int tegra_spdif_probe(struct snd_soc_dai *dai)
-{
- struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai);
-
- dai->capture_dma_data = NULL;
- dai->playback_dma_data = &spdif->playback_dma_data;
-
- return 0;
-}
-
-static const struct snd_soc_dai_ops tegra_spdif_dai_ops = {
- .hw_params = tegra_spdif_hw_params,
- .trigger = tegra_spdif_trigger,
-};
-
-static struct snd_soc_dai_driver tegra_spdif_dai = {
- .name = DRV_NAME,
- .probe = tegra_spdif_probe,
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .ops = &tegra_spdif_dai_ops,
-};
-
-static __devinit int tegra_spdif_platform_probe(struct platform_device *pdev)
-{
- struct tegra_spdif *spdif;
- struct resource *mem, *memregion, *dmareq;
- int ret;
-
- spdif = kzalloc(sizeof(struct tegra_spdif), GFP_KERNEL);
- if (!spdif) {
- dev_err(&pdev->dev, "Can't allocate tegra_spdif\n");
- ret = -ENOMEM;
- goto exit;
- }
- dev_set_drvdata(&pdev->dev, spdif);
-
- spdif->clk_spdif_out = clk_get(&pdev->dev, "spdif_out");
- if (IS_ERR(spdif->clk_spdif_out)) {
- pr_err("Can't retrieve spdif clock\n");
- ret = PTR_ERR(spdif->clk_spdif_out);
- goto err_free;
- }
-
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem) {
- dev_err(&pdev->dev, "No memory resource\n");
- ret = -ENODEV;
- goto err_clk_put;
- }
-
- dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!dmareq) {
- dev_err(&pdev->dev, "No DMA resource\n");
- ret = -ENODEV;
- goto err_clk_put;
- }
-
- memregion = request_mem_region(mem->start, resource_size(mem),
- DRV_NAME);
- if (!memregion) {
- dev_err(&pdev->dev, "Memory region already claimed\n");
- ret = -EBUSY;
- goto err_clk_put;
- }
-
- spdif->regs = ioremap(mem->start, resource_size(mem));
- if (!spdif->regs) {
- dev_err(&pdev->dev, "ioremap failed\n");
- ret = -ENOMEM;
- goto err_release;
- }
-
- spdif->playback_dma_data.addr = mem->start + TEGRA_SPDIF_DATA_OUT;
- spdif->playback_dma_data.wrap = 4;
- spdif->playback_dma_data.width = 32;
- spdif->playback_dma_data.req_sel = dmareq->start;
-
- ret = snd_soc_register_dai(&pdev->dev, &tegra_spdif_dai);
- if (ret) {
- dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
- ret = -ENOMEM;
- goto err_unmap;
- }
-
- tegra_spdif_debug_add(spdif);
-
- return 0;
-
-err_unmap:
- iounmap(spdif->regs);
-err_release:
- release_mem_region(mem->start, resource_size(mem));
-err_clk_put:
- clk_put(spdif->clk_spdif_out);
-err_free:
- kfree(spdif);
-exit:
- return ret;
-}
-
-static int __devexit tegra_spdif_platform_remove(struct platform_device *pdev)
-{
- struct tegra_spdif *spdif = dev_get_drvdata(&pdev->dev);
- struct resource *res;
-
- snd_soc_unregister_dai(&pdev->dev);
-
- tegra_spdif_debug_remove(spdif);
-
- iounmap(spdif->regs);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, resource_size(res));
-
- clk_put(spdif->clk_spdif_out);
-
- kfree(spdif);
-
- return 0;
-}
-
-static struct platform_driver tegra_spdif_driver = {
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- },
- .probe = tegra_spdif_platform_probe,
- .remove = __devexit_p(tegra_spdif_platform_remove),
-};
-
-module_platform_driver(tegra_spdif_driver);
-
-MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
-MODULE_DESCRIPTION("Tegra SPDIF ASoC driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/ANDROID_3.4.5/sound/soc/tegra/tegra_spdif.h b/ANDROID_3.4.5/sound/soc/tegra/tegra_spdif.h
deleted file mode 100644
index 2e03db43..00000000
--- a/ANDROID_3.4.5/sound/soc/tegra/tegra_spdif.h
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * tegra_spdif.h - Definitions for Tegra SPDIF driver
- *
- * Author: Stephen Warren <swarren@nvidia.com>
- * Copyright (C) 2011 - NVIDIA, Inc.
- *
- * Based on code copyright/by:
- * Copyright (c) 2008-2009, NVIDIA Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __TEGRA_SPDIF_H__
-#define __TEGRA_SPDIF_H__
-
-#include "tegra_pcm.h"
-
-/* Offsets from TEGRA_SPDIF_BASE */
-
-#define TEGRA_SPDIF_CTRL 0x0
-#define TEGRA_SPDIF_STATUS 0x4
-#define TEGRA_SPDIF_STROBE_CTRL 0x8
-#define TEGRA_SPDIF_DATA_FIFO_CSR 0x0C
-#define TEGRA_SPDIF_DATA_OUT 0x40
-#define TEGRA_SPDIF_DATA_IN 0x80
-#define TEGRA_SPDIF_CH_STA_RX_A 0x100
-#define TEGRA_SPDIF_CH_STA_RX_B 0x104
-#define TEGRA_SPDIF_CH_STA_RX_C 0x108
-#define TEGRA_SPDIF_CH_STA_RX_D 0x10C
-#define TEGRA_SPDIF_CH_STA_RX_E 0x110
-#define TEGRA_SPDIF_CH_STA_RX_F 0x114
-#define TEGRA_SPDIF_CH_STA_TX_A 0x140
-#define TEGRA_SPDIF_CH_STA_TX_B 0x144
-#define TEGRA_SPDIF_CH_STA_TX_C 0x148
-#define TEGRA_SPDIF_CH_STA_TX_D 0x14C
-#define TEGRA_SPDIF_CH_STA_TX_E 0x150
-#define TEGRA_SPDIF_CH_STA_TX_F 0x154
-#define TEGRA_SPDIF_USR_STA_RX_A 0x180
-#define TEGRA_SPDIF_USR_DAT_TX_A 0x1C0
-
-/* Fields in TEGRA_SPDIF_CTRL */
-
-/* Start capturing from 0=right, 1=left channel */
-#define TEGRA_SPDIF_CTRL_CAP_LC (1 << 30)
-
-/* SPDIF receiver(RX) enable */
-#define TEGRA_SPDIF_CTRL_RX_EN (1 << 29)
-
-/* SPDIF Transmitter(TX) enable */
-#define TEGRA_SPDIF_CTRL_TX_EN (1 << 28)
-
-/* Transmit Channel status */
-#define TEGRA_SPDIF_CTRL_TC_EN (1 << 27)
-
-/* Transmit user Data */
-#define TEGRA_SPDIF_CTRL_TU_EN (1 << 26)
-
-/* Interrupt on transmit error */
-#define TEGRA_SPDIF_CTRL_IE_TXE (1 << 25)
-
-/* Interrupt on receive error */
-#define TEGRA_SPDIF_CTRL_IE_RXE (1 << 24)
-
-/* Interrupt on invalid preamble */
-#define TEGRA_SPDIF_CTRL_IE_P (1 << 23)
-
-/* Interrupt on "B" preamble */
-#define TEGRA_SPDIF_CTRL_IE_B (1 << 22)
-
-/* Interrupt when block of channel status received */
-#define TEGRA_SPDIF_CTRL_IE_C (1 << 21)
-
-/* Interrupt when a valid information unit (IU) is received */
-#define TEGRA_SPDIF_CTRL_IE_U (1 << 20)
-
-/* Interrupt when RX user FIFO attention level is reached */
-#define TEGRA_SPDIF_CTRL_QE_RU (1 << 19)
-
-/* Interrupt when TX user FIFO attention level is reached */
-#define TEGRA_SPDIF_CTRL_QE_TU (1 << 18)
-
-/* Interrupt when RX data FIFO attention level is reached */
-#define TEGRA_SPDIF_CTRL_QE_RX (1 << 17)
-
-/* Interrupt when TX data FIFO attention level is reached */
-#define TEGRA_SPDIF_CTRL_QE_TX (1 << 16)
-
-/* Loopback test mode enable */
-#define TEGRA_SPDIF_CTRL_LBK_EN (1 << 15)
-
-/*
- * Pack data mode:
- * 0 = Single data (16 bit needs to be padded to match the
- * interface data bit size).
- * 1 = Packeted left/right channel data into a single word.
- */
-#define TEGRA_SPDIF_CTRL_PACK (1 << 14)
-
-/*
- * 00 = 16bit data
- * 01 = 20bit data
- * 10 = 24bit data
- * 11 = raw data
- */
-#define TEGRA_SPDIF_BIT_MODE_16BIT 0
-#define TEGRA_SPDIF_BIT_MODE_20BIT 1
-#define TEGRA_SPDIF_BIT_MODE_24BIT 2
-#define TEGRA_SPDIF_BIT_MODE_RAW 3
-
-#define TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT 12
-#define TEGRA_SPDIF_CTRL_BIT_MODE_MASK (3 << TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT)
-#define TEGRA_SPDIF_CTRL_BIT_MODE_16BIT (TEGRA_SPDIF_BIT_MODE_16BIT << TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT)
-#define TEGRA_SPDIF_CTRL_BIT_MODE_20BIT (TEGRA_SPDIF_BIT_MODE_20BIT << TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT)
-#define TEGRA_SPDIF_CTRL_BIT_MODE_24BIT (TEGRA_SPDIF_BIT_MODE_24BIT << TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT)
-#define TEGRA_SPDIF_CTRL_BIT_MODE_RAW (TEGRA_SPDIF_BIT_MODE_RAW << TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT)
-
-/* Fields in TEGRA_SPDIF_STATUS */
-
-/*
- * Note: IS_P, IS_B, IS_C, and IS_U are sticky bits. Software must
- * write a 1 to the corresponding bit location to clear the status.
- */
-
-/*
- * Receiver(RX) shifter is busy receiving data.
- * This bit is asserted when the receiver first locked onto the
- * preamble of the data stream after RX_EN is asserted. This bit is
- * deasserted when either,
- * (a) the end of a frame is reached after RX_EN is deeasserted, or
- * (b) the SPDIF data stream becomes inactive.
- */
-#define TEGRA_SPDIF_STATUS_RX_BSY (1 << 29)
-
-/*
- * Transmitter(TX) shifter is busy transmitting data.
- * This bit is asserted when TX_EN is asserted.
- * This bit is deasserted when the end of a frame is reached after
- * TX_EN is deasserted.
- */
-#define TEGRA_SPDIF_STATUS_TX_BSY (1 << 28)
-
-/*
- * TX is busy shifting out channel status.
- * This bit is asserted when both TX_EN and TC_EN are asserted and
- * data from CH_STA_TX_A register is loaded into the internal shifter.
- * This bit is deasserted when either,
- * (a) the end of a frame is reached after TX_EN is deasserted, or
- * (b) CH_STA_TX_F register is loaded into the internal shifter.
- */
-#define TEGRA_SPDIF_STATUS_TC_BSY (1 << 27)
-
-/*
- * TX User data FIFO busy.
- * This bit is asserted when TX_EN and TXU_EN are asserted and
- * there's data in the TX user FIFO. This bit is deassert when either,
- * (a) the end of a frame is reached after TX_EN is deasserted, or
- * (b) there's no data left in the TX user FIFO.
- */
-#define TEGRA_SPDIF_STATUS_TU_BSY (1 << 26)
-
-/* TX FIFO Underrun error status */
-#define TEGRA_SPDIF_STATUS_TX_ERR (1 << 25)
-
-/* RX FIFO Overrun error status */
-#define TEGRA_SPDIF_STATUS_RX_ERR (1 << 24)
-
-/* Preamble status: 0=Preamble OK, 1=bad/missing preamble */
-#define TEGRA_SPDIF_STATUS_IS_P (1 << 23)
-
-/* B-preamble detection status: 0=not detected, 1=B-preamble detected */
-#define TEGRA_SPDIF_STATUS_IS_B (1 << 22)
-
-/*
- * RX channel block data receive status:
- * 0=entire block not recieved yet.
- * 1=received entire block of channel status,
- */
-#define TEGRA_SPDIF_STATUS_IS_C (1 << 21)
-
-/* RX User Data Valid flag: 1=valid IU detected, 0 = no IU detected. */
-#define TEGRA_SPDIF_STATUS_IS_U (1 << 20)
-
-/*
- * RX User FIFO Status:
- * 1=attention level reached, 0=attention level not reached.
- */
-#define TEGRA_SPDIF_STATUS_QS_RU (1 << 19)
-
-/*
- * TX User FIFO Status:
- * 1=attention level reached, 0=attention level not reached.
- */
-#define TEGRA_SPDIF_STATUS_QS_TU (1 << 18)
-
-/*
- * RX Data FIFO Status:
- * 1=attention level reached, 0=attention level not reached.
- */
-#define TEGRA_SPDIF_STATUS_QS_RX (1 << 17)
-
-/*
- * TX Data FIFO Status:
- * 1=attention level reached, 0=attention level not reached.
- */
-#define TEGRA_SPDIF_STATUS_QS_TX (1 << 16)
-
-/* Fields in TEGRA_SPDIF_STROBE_CTRL */
-
-/*
- * Indicates the approximate number of detected SPDIFIN clocks within a
- * bi-phase period.
- */
-#define TEGRA_SPDIF_STROBE_CTRL_PERIOD_SHIFT 16
-#define TEGRA_SPDIF_STROBE_CTRL_PERIOD_MASK (0xff << TEGRA_SPDIF_STROBE_CTRL_PERIOD_SHIFT)
-
-/* Data strobe mode: 0=Auto-locked 1=Manual locked */
-#define TEGRA_SPDIF_STROBE_CTRL_STROBE (1 << 15)
-
-/*
- * Manual data strobe time within the bi-phase clock period (in terms of
- * the number of over-sampling clocks).
- */
-#define TEGRA_SPDIF_STROBE_CTRL_DATA_STROBES_SHIFT 8
-#define TEGRA_SPDIF_STROBE_CTRL_DATA_STROBES_MASK (0x1f << TEGRA_SPDIF_STROBE_CTRL_DATA_STROBES_SHIFT)
-
-/*
- * Manual SPDIFIN bi-phase clock period (in terms of the number of
- * over-sampling clocks).
- */
-#define TEGRA_SPDIF_STROBE_CTRL_CLOCK_PERIOD_SHIFT 0
-#define TEGRA_SPDIF_STROBE_CTRL_CLOCK_PERIOD_MASK (0x3f << TEGRA_SPDIF_STROBE_CTRL_CLOCK_PERIOD_SHIFT)
-
-/* Fields in SPDIF_DATA_FIFO_CSR */
-
-/* Clear Receiver User FIFO (RX USR.FIFO) */
-#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_CLR (1 << 31)
-
-#define TEGRA_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT 0
-#define TEGRA_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS 1
-#define TEGRA_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS 2
-#define TEGRA_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS 3
-
-/* RU FIFO attention level */
-#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT 29
-#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_MASK \
- (0x3 << TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
-#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU1_WORD_FULL \
- (TEGRA_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT << TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
-#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU2_WORD_FULL \
- (TEGRA_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
-#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU3_WORD_FULL \
- (TEGRA_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
-#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU4_WORD_FULL \
- (TEGRA_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
-
-/* Number of RX USR.FIFO levels with valid data. */
-#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_SHIFT 24
-#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_MASK (0x1f << TEGRA_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_SHIFT)
-
-/* Clear Transmitter User FIFO (TX USR.FIFO) */
-#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_CLR (1 << 23)
-
-/* TU FIFO attention level */
-#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT 21
-#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_MASK \
- (0x3 << TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
-#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU1_WORD_FULL \
- (TEGRA_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT << TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
-#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU2_WORD_FULL \
- (TEGRA_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
-#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU3_WORD_FULL \
- (TEGRA_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
-#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU4_WORD_FULL \
- (TEGRA_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
-
-/* Number of TX USR.FIFO levels that could be filled. */
-#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_EMPTY_COUNT_SHIFT 16
-#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_EMPTY_COUNT_MASK (0x1f << SPDIF_DATA_FIFO_CSR_TU_EMPTY_COUNT_SHIFT)
-
-/* Clear Receiver Data FIFO (RX DATA.FIFO) */
-#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_CLR (1 << 15)
-
-#define TEGRA_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT 0
-#define TEGRA_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS 1
-#define TEGRA_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS 2
-#define TEGRA_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS 3
-
-/* RU FIFO attention level */
-#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT 13
-#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_MASK \
- (0x3 << TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
-#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU1_WORD_FULL \
- (TEGRA_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT << TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
-#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU4_WORD_FULL \
- (TEGRA_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
-#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU8_WORD_FULL \
- (TEGRA_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
-#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU12_WORD_FULL \
- (TEGRA_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
-
-/* Number of RX DATA.FIFO levels with valid data. */
-#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_SHIFT 8
-#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_MASK (0x1f << TEGRA_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_SHIFT)
-
-/* Clear Transmitter Data FIFO (TX DATA.FIFO) */
-#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_CLR (1 << 7)
-
-/* TU FIFO attention level */
-#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT 5
-#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_MASK \
- (0x3 << TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
-#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU1_WORD_FULL \
- (TEGRA_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT << TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
-#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU4_WORD_FULL \
- (TEGRA_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
-#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU8_WORD_FULL \
- (TEGRA_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
-#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU12_WORD_FULL \
- (TEGRA_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
-
-/* Number of TX DATA.FIFO levels that could be filled. */
-#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_SHIFT 0
-#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_MASK (0x1f << SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_SHIFT)
-
-/* Fields in TEGRA_SPDIF_DATA_OUT */
-
-/*
- * This register has 5 different formats:
- * 16-bit (BIT_MODE=00, PACK=0)
- * 20-bit (BIT_MODE=01, PACK=0)
- * 24-bit (BIT_MODE=10, PACK=0)
- * raw (BIT_MODE=11, PACK=0)
- * 16-bit packed (BIT_MODE=00, PACK=1)
- */
-
-#define TEGRA_SPDIF_DATA_OUT_DATA_16_SHIFT 0
-#define TEGRA_SPDIF_DATA_OUT_DATA_16_MASK (0xffff << TEGRA_SPDIF_DATA_OUT_DATA_16_SHIFT)
-
-#define TEGRA_SPDIF_DATA_OUT_DATA_20_SHIFT 0
-#define TEGRA_SPDIF_DATA_OUT_DATA_20_MASK (0xfffff << TEGRA_SPDIF_DATA_OUT_DATA_20_SHIFT)
-
-#define TEGRA_SPDIF_DATA_OUT_DATA_24_SHIFT 0
-#define TEGRA_SPDIF_DATA_OUT_DATA_24_MASK (0xffffff << TEGRA_SPDIF_DATA_OUT_DATA_24_SHIFT)
-
-#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_P (1 << 31)
-#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_C (1 << 30)
-#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_U (1 << 29)
-#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_V (1 << 28)
-
-#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_DATA_SHIFT 8
-#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_DATA_MASK (0xfffff << TEGRA_SPDIF_DATA_OUT_DATA_RAW_DATA_SHIFT)
-
-#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_AUX_SHIFT 4
-#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_AUX_MASK (0xf << TEGRA_SPDIF_DATA_OUT_DATA_RAW_AUX_SHIFT)
-
-#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_SHIFT 0
-#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_MASK (0xf << TEGRA_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_SHIFT)
-
-#define TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_SHIFT 16
-#define TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_MASK (0xffff << TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_SHIFT)
-
-#define TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_SHIFT 0
-#define TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_MASK (0xffff << TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_SHIFT)
-
-/* Fields in TEGRA_SPDIF_DATA_IN */
-
-/*
- * This register has 5 different formats:
- * 16-bit (BIT_MODE=00, PACK=0)
- * 20-bit (BIT_MODE=01, PACK=0)
- * 24-bit (BIT_MODE=10, PACK=0)
- * raw (BIT_MODE=11, PACK=0)
- * 16-bit packed (BIT_MODE=00, PACK=1)
- *
- * Bits 31:24 are common to all modes except 16-bit packed
- */
-
-#define TEGRA_SPDIF_DATA_IN_DATA_P (1 << 31)
-#define TEGRA_SPDIF_DATA_IN_DATA_C (1 << 30)
-#define TEGRA_SPDIF_DATA_IN_DATA_U (1 << 29)
-#define TEGRA_SPDIF_DATA_IN_DATA_V (1 << 28)
-
-#define TEGRA_SPDIF_DATA_IN_DATA_PREAMBLE_SHIFT 24
-#define TEGRA_SPDIF_DATA_IN_DATA_PREAMBLE_MASK (0xf << TEGRA_SPDIF_DATA_IN_DATA_PREAMBLE_SHIFT)
-
-#define TEGRA_SPDIF_DATA_IN_DATA_16_SHIFT 0
-#define TEGRA_SPDIF_DATA_IN_DATA_16_MASK (0xffff << TEGRA_SPDIF_DATA_IN_DATA_16_SHIFT)
-
-#define TEGRA_SPDIF_DATA_IN_DATA_20_SHIFT 0
-#define TEGRA_SPDIF_DATA_IN_DATA_20_MASK (0xfffff << TEGRA_SPDIF_DATA_IN_DATA_20_SHIFT)
-
-#define TEGRA_SPDIF_DATA_IN_DATA_24_SHIFT 0
-#define TEGRA_SPDIF_DATA_IN_DATA_24_MASK (0xffffff << TEGRA_SPDIF_DATA_IN_DATA_24_SHIFT)
-
-#define TEGRA_SPDIF_DATA_IN_DATA_RAW_DATA_SHIFT 8
-#define TEGRA_SPDIF_DATA_IN_DATA_RAW_DATA_MASK (0xfffff << TEGRA_SPDIF_DATA_IN_DATA_RAW_DATA_SHIFT)
-
-#define TEGRA_SPDIF_DATA_IN_DATA_RAW_AUX_SHIFT 4
-#define TEGRA_SPDIF_DATA_IN_DATA_RAW_AUX_MASK (0xf << TEGRA_SPDIF_DATA_IN_DATA_RAW_AUX_SHIFT)
-
-#define TEGRA_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_SHIFT 0
-#define TEGRA_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_MASK (0xf << TEGRA_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_SHIFT)
-
-#define TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_SHIFT 16
-#define TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_MASK (0xffff << TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_SHIFT)
-
-#define TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_SHIFT 0
-#define TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_MASK (0xffff << TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_SHIFT)
-
-/* Fields in TEGRA_SPDIF_CH_STA_RX_A */
-/* Fields in TEGRA_SPDIF_CH_STA_RX_B */
-/* Fields in TEGRA_SPDIF_CH_STA_RX_C */
-/* Fields in TEGRA_SPDIF_CH_STA_RX_D */
-/* Fields in TEGRA_SPDIF_CH_STA_RX_E */
-/* Fields in TEGRA_SPDIF_CH_STA_RX_F */
-
-/*
- * The 6-word receive channel data page buffer holds a block (192 frames) of
- * channel status information. The order of receive is from LSB to MSB
- * bit, and from CH_STA_RX_A to CH_STA_RX_F then back to CH_STA_RX_A.
- */
-
-/* Fields in TEGRA_SPDIF_CH_STA_TX_A */
-/* Fields in TEGRA_SPDIF_CH_STA_TX_B */
-/* Fields in TEGRA_SPDIF_CH_STA_TX_C */
-/* Fields in TEGRA_SPDIF_CH_STA_TX_D */
-/* Fields in TEGRA_SPDIF_CH_STA_TX_E */
-/* Fields in TEGRA_SPDIF_CH_STA_TX_F */
-
-/*
- * The 6-word transmit channel data page buffer holds a block (192 frames) of
- * channel status information. The order of transmission is from LSB to MSB
- * bit, and from CH_STA_TX_A to CH_STA_TX_F then back to CH_STA_TX_A.
- */
-
-/* Fields in TEGRA_SPDIF_USR_STA_RX_A */
-
-/*
- * This 4-word deep FIFO receives user FIFO field information. The order of
- * receive is from LSB to MSB bit.
- */
-
-/* Fields in TEGRA_SPDIF_USR_DAT_TX_A */
-
-/*
- * This 4-word deep FIFO transmits user FIFO field information. The order of
- * transmission is from LSB to MSB bit.
- */
-
-struct tegra_spdif {
- struct clk *clk_spdif_out;
- int clk_refs;
- struct tegra_pcm_dma_params capture_dma_data;
- struct tegra_pcm_dma_params playback_dma_data;
- void __iomem *regs;
- struct dentry *debug;
- u32 reg_ctrl;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/tegra/tegra_wm8903.c b/ANDROID_3.4.5/sound/soc/tegra/tegra_wm8903.c
deleted file mode 100644
index 566655e2..00000000
--- a/ANDROID_3.4.5/sound/soc/tegra/tegra_wm8903.c
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * tegra_wm8903.c - Tegra machine ASoC driver for boards using WM8903 codec.
- *
- * Author: Stephen Warren <swarren@nvidia.com>
- * Copyright (C) 2010-2011 - NVIDIA, Inc.
- *
- * Based on code copyright/by:
- *
- * (c) 2009, 2010 Nvidia Graphics Pvt. Ltd.
- *
- * Copyright 2007 Wolfson Microelectronics PLC.
- * Author: Graeme Gregory
- * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <asm/mach-types.h>
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/gpio.h>
-#include <linux/of_gpio.h>
-
-#include <mach/tegra_wm8903_pdata.h>
-
-#include <sound/core.h>
-#include <sound/jack.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include "../codecs/wm8903.h"
-
-#include "tegra_das.h"
-#include "tegra_i2s.h"
-#include "tegra_pcm.h"
-#include "tegra_asoc_utils.h"
-
-#define DRV_NAME "tegra-snd-wm8903"
-
-#define GPIO_SPKR_EN BIT(0)
-#define GPIO_HP_MUTE BIT(1)
-#define GPIO_INT_MIC_EN BIT(2)
-#define GPIO_EXT_MIC_EN BIT(3)
-#define GPIO_HP_DET BIT(4)
-
-struct tegra_wm8903 {
- struct tegra_wm8903_platform_data pdata;
- struct platform_device *pcm_dev;
- struct tegra_asoc_utils_data util_data;
- int gpio_requested;
-};
-
-static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_card *card = codec->card;
- struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
- int srate, mclk;
- int err;
-
- srate = params_rate(params);
- switch (srate) {
- case 64000:
- case 88200:
- case 96000:
- mclk = 128 * srate;
- break;
- default:
- mclk = 256 * srate;
- break;
- }
- /* FIXME: Codec only requires >= 3MHz if OSR==0 */
- while (mclk < 6000000)
- mclk *= 2;
-
- err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
- if (err < 0) {
- dev_err(card->dev, "Can't configure clocks\n");
- return err;
- }
-
- err = snd_soc_dai_set_fmt(codec_dai,
- SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS);
- if (err < 0) {
- dev_err(card->dev, "codec_dai fmt not set\n");
- return err;
- }
-
- err = snd_soc_dai_set_fmt(cpu_dai,
- SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS);
- if (err < 0) {
- dev_err(card->dev, "cpu_dai fmt not set\n");
- return err;
- }
-
- err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
- SND_SOC_CLOCK_IN);
- if (err < 0) {
- dev_err(card->dev, "codec_dai clock not set\n");
- return err;
- }
-
- return 0;
-}
-
-static struct snd_soc_ops tegra_wm8903_ops = {
- .hw_params = tegra_wm8903_hw_params,
-};
-
-static struct snd_soc_jack tegra_wm8903_hp_jack;
-
-static struct snd_soc_jack_pin tegra_wm8903_hp_jack_pins[] = {
- {
- .pin = "Headphone Jack",
- .mask = SND_JACK_HEADPHONE,
- },
-};
-
-static struct snd_soc_jack_gpio tegra_wm8903_hp_jack_gpio = {
- .name = "headphone detect",
- .report = SND_JACK_HEADPHONE,
- .debounce_time = 150,
- .invert = 1,
-};
-
-static struct snd_soc_jack tegra_wm8903_mic_jack;
-
-static struct snd_soc_jack_pin tegra_wm8903_mic_jack_pins[] = {
- {
- .pin = "Mic Jack",
- .mask = SND_JACK_MICROPHONE,
- },
-};
-
-static int tegra_wm8903_event_int_spk(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- struct snd_soc_dapm_context *dapm = w->dapm;
- struct snd_soc_card *card = dapm->card;
- struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
- struct tegra_wm8903_platform_data *pdata = &machine->pdata;
-
- if (!(machine->gpio_requested & GPIO_SPKR_EN))
- return 0;
-
- gpio_set_value_cansleep(pdata->gpio_spkr_en,
- SND_SOC_DAPM_EVENT_ON(event));
-
- return 0;
-}
-
-static int tegra_wm8903_event_hp(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- struct snd_soc_dapm_context *dapm = w->dapm;
- struct snd_soc_card *card = dapm->card;
- struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
- struct tegra_wm8903_platform_data *pdata = &machine->pdata;
-
- if (!(machine->gpio_requested & GPIO_HP_MUTE))
- return 0;
-
- gpio_set_value_cansleep(pdata->gpio_hp_mute,
- !SND_SOC_DAPM_EVENT_ON(event));
-
- return 0;
-}
-
-static const struct snd_soc_dapm_widget tegra_wm8903_dapm_widgets[] = {
- SND_SOC_DAPM_SPK("Int Spk", tegra_wm8903_event_int_spk),
- SND_SOC_DAPM_HP("Headphone Jack", tegra_wm8903_event_hp),
- SND_SOC_DAPM_MIC("Mic Jack", NULL),
-};
-
-static const struct snd_soc_dapm_route harmony_audio_map[] = {
- {"Headphone Jack", NULL, "HPOUTR"},
- {"Headphone Jack", NULL, "HPOUTL"},
- {"Int Spk", NULL, "ROP"},
- {"Int Spk", NULL, "RON"},
- {"Int Spk", NULL, "LOP"},
- {"Int Spk", NULL, "LON"},
- {"Mic Jack", NULL, "MICBIAS"},
- {"IN1L", NULL, "Mic Jack"},
-};
-
-static const struct snd_soc_dapm_route seaboard_audio_map[] = {
- {"Headphone Jack", NULL, "HPOUTR"},
- {"Headphone Jack", NULL, "HPOUTL"},
- {"Int Spk", NULL, "ROP"},
- {"Int Spk", NULL, "RON"},
- {"Int Spk", NULL, "LOP"},
- {"Int Spk", NULL, "LON"},
- {"Mic Jack", NULL, "MICBIAS"},
- {"IN1R", NULL, "Mic Jack"},
-};
-
-static const struct snd_soc_dapm_route kaen_audio_map[] = {
- {"Headphone Jack", NULL, "HPOUTR"},
- {"Headphone Jack", NULL, "HPOUTL"},
- {"Int Spk", NULL, "ROP"},
- {"Int Spk", NULL, "RON"},
- {"Int Spk", NULL, "LOP"},
- {"Int Spk", NULL, "LON"},
- {"Mic Jack", NULL, "MICBIAS"},
- {"IN2R", NULL, "Mic Jack"},
-};
-
-static const struct snd_soc_dapm_route aebl_audio_map[] = {
- {"Headphone Jack", NULL, "HPOUTR"},
- {"Headphone Jack", NULL, "HPOUTL"},
- {"Int Spk", NULL, "LINEOUTR"},
- {"Int Spk", NULL, "LINEOUTL"},
- {"Mic Jack", NULL, "MICBIAS"},
- {"IN1R", NULL, "Mic Jack"},
-};
-
-static const struct snd_kcontrol_new tegra_wm8903_controls[] = {
- SOC_DAPM_PIN_SWITCH("Int Spk"),
-};
-
-static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- struct snd_soc_card *card = codec->card;
- struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
- struct tegra_wm8903_platform_data *pdata = &machine->pdata;
- struct device_node *np = card->dev->of_node;
- int ret;
-
- if (card->dev->platform_data) {
- memcpy(pdata, card->dev->platform_data, sizeof(*pdata));
- } else if (np) {
- /*
- * This part must be in init() rather than probe() in order to
- * guarantee that the WM8903 has been probed, and hence its
- * GPIO controller registered, which is a pre-condition for
- * of_get_named_gpio() to be able to map the phandles in the
- * properties to the controller node. Given this, all
- * pdata handling is in init() for consistency.
- */
- pdata->gpio_spkr_en = of_get_named_gpio(np,
- "nvidia,spkr-en-gpios", 0);
- pdata->gpio_hp_mute = of_get_named_gpio(np,
- "nvidia,hp-mute-gpios", 0);
- pdata->gpio_hp_det = of_get_named_gpio(np,
- "nvidia,hp-det-gpios", 0);
- pdata->gpio_int_mic_en = of_get_named_gpio(np,
- "nvidia,int-mic-en-gpios", 0);
- pdata->gpio_ext_mic_en = of_get_named_gpio(np,
- "nvidia,ext-mic-en-gpios", 0);
- } else {
- dev_err(card->dev, "No platform data supplied\n");
- return -EINVAL;
- }
-
- if (gpio_is_valid(pdata->gpio_spkr_en)) {
- ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
- if (ret) {
- dev_err(card->dev, "cannot get spkr_en gpio\n");
- return ret;
- }
- machine->gpio_requested |= GPIO_SPKR_EN;
-
- gpio_direction_output(pdata->gpio_spkr_en, 0);
- }
-
- if (gpio_is_valid(pdata->gpio_hp_mute)) {
- ret = gpio_request(pdata->gpio_hp_mute, "hp_mute");
- if (ret) {
- dev_err(card->dev, "cannot get hp_mute gpio\n");
- return ret;
- }
- machine->gpio_requested |= GPIO_HP_MUTE;
-
- gpio_direction_output(pdata->gpio_hp_mute, 1);
- }
-
- if (gpio_is_valid(pdata->gpio_int_mic_en)) {
- ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
- if (ret) {
- dev_err(card->dev, "cannot get int_mic_en gpio\n");
- return ret;
- }
- machine->gpio_requested |= GPIO_INT_MIC_EN;
-
- /* Disable int mic; enable signal is active-high */
- gpio_direction_output(pdata->gpio_int_mic_en, 0);
- }
-
- if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
- ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
- if (ret) {
- dev_err(card->dev, "cannot get ext_mic_en gpio\n");
- return ret;
- }
- machine->gpio_requested |= GPIO_EXT_MIC_EN;
-
- /* Enable ext mic; enable signal is active-low */
- gpio_direction_output(pdata->gpio_ext_mic_en, 0);
- }
-
- if (gpio_is_valid(pdata->gpio_hp_det)) {
- tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det;
- snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
- &tegra_wm8903_hp_jack);
- snd_soc_jack_add_pins(&tegra_wm8903_hp_jack,
- ARRAY_SIZE(tegra_wm8903_hp_jack_pins),
- tegra_wm8903_hp_jack_pins);
- snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack,
- 1,
- &tegra_wm8903_hp_jack_gpio);
- machine->gpio_requested |= GPIO_HP_DET;
- }
-
- snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE,
- &tegra_wm8903_mic_jack);
- snd_soc_jack_add_pins(&tegra_wm8903_mic_jack,
- ARRAY_SIZE(tegra_wm8903_mic_jack_pins),
- tegra_wm8903_mic_jack_pins);
- wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE,
- 0);
-
- snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");
-
- return 0;
-}
-
-static struct snd_soc_dai_link tegra_wm8903_dai = {
- .name = "WM8903",
- .stream_name = "WM8903 PCM",
- .codec_name = "wm8903.0-001a",
- .platform_name = "tegra-pcm-audio",
- .cpu_dai_name = "tegra-i2s.0",
- .codec_dai_name = "wm8903-hifi",
- .init = tegra_wm8903_init,
- .ops = &tegra_wm8903_ops,
-};
-
-static struct snd_soc_card snd_soc_tegra_wm8903 = {
- .name = "tegra-wm8903",
- .owner = THIS_MODULE,
- .dai_link = &tegra_wm8903_dai,
- .num_links = 1,
-
- .controls = tegra_wm8903_controls,
- .num_controls = ARRAY_SIZE(tegra_wm8903_controls),
- .dapm_widgets = tegra_wm8903_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(tegra_wm8903_dapm_widgets),
- .fully_routed = true,
-};
-
-static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &snd_soc_tegra_wm8903;
- struct tegra_wm8903 *machine;
- int ret;
-
- if (!pdev->dev.platform_data && !pdev->dev.of_node) {
- dev_err(&pdev->dev, "No platform data supplied\n");
- return -EINVAL;
- }
-
- machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8903),
- GFP_KERNEL);
- if (!machine) {
- dev_err(&pdev->dev, "Can't allocate tegra_wm8903 struct\n");
- ret = -ENOMEM;
- goto err;
- }
- machine->pcm_dev = ERR_PTR(-EINVAL);
-
- card->dev = &pdev->dev;
- platform_set_drvdata(pdev, card);
- snd_soc_card_set_drvdata(card, machine);
-
- if (pdev->dev.of_node) {
- ret = snd_soc_of_parse_card_name(card, "nvidia,model");
- if (ret)
- goto err;
-
- ret = snd_soc_of_parse_audio_routing(card,
- "nvidia,audio-routing");
- if (ret)
- goto err;
-
- tegra_wm8903_dai.codec_name = NULL;
- tegra_wm8903_dai.codec_of_node = of_parse_phandle(
- pdev->dev.of_node, "nvidia,audio-codec", 0);
- if (!tegra_wm8903_dai.codec_of_node) {
- dev_err(&pdev->dev,
- "Property 'nvidia,audio-codec' missing or invalid\n");
- ret = -EINVAL;
- goto err;
- }
-
- tegra_wm8903_dai.cpu_dai_name = NULL;
- tegra_wm8903_dai.cpu_dai_of_node = of_parse_phandle(
- pdev->dev.of_node, "nvidia,i2s-controller", 0);
- if (!tegra_wm8903_dai.cpu_dai_of_node) {
- dev_err(&pdev->dev,
- "Property 'nvidia,i2s-controller' missing or invalid\n");
- ret = -EINVAL;
- goto err;
- }
-
- machine->pcm_dev = platform_device_register_simple(
- "tegra-pcm-audio", -1, NULL, 0);
- if (IS_ERR(machine->pcm_dev)) {
- dev_err(&pdev->dev,
- "Can't instantiate tegra-pcm-audio\n");
- ret = PTR_ERR(machine->pcm_dev);
- goto err;
- }
- } else {
- if (machine_is_harmony()) {
- card->dapm_routes = harmony_audio_map;
- card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map);
- } else if (machine_is_seaboard()) {
- card->dapm_routes = seaboard_audio_map;
- card->num_dapm_routes = ARRAY_SIZE(seaboard_audio_map);
- } else if (machine_is_kaen()) {
- card->dapm_routes = kaen_audio_map;
- card->num_dapm_routes = ARRAY_SIZE(kaen_audio_map);
- } else {
- card->dapm_routes = aebl_audio_map;
- card->num_dapm_routes = ARRAY_SIZE(aebl_audio_map);
- }
- }
-
- ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
- if (ret)
- goto err_unregister;
-
- ret = snd_soc_register_card(card);
- if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
- ret);
- goto err_fini_utils;
- }
-
- return 0;
-
-err_fini_utils:
- tegra_asoc_utils_fini(&machine->util_data);
-err_unregister:
- if (!IS_ERR(machine->pcm_dev))
- platform_device_unregister(machine->pcm_dev);
-err:
- return ret;
-}
-
-static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
- struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
- struct tegra_wm8903_platform_data *pdata = &machine->pdata;
-
- if (machine->gpio_requested & GPIO_HP_DET)
- snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack,
- 1,
- &tegra_wm8903_hp_jack_gpio);
- if (machine->gpio_requested & GPIO_EXT_MIC_EN)
- gpio_free(pdata->gpio_ext_mic_en);
- if (machine->gpio_requested & GPIO_INT_MIC_EN)
- gpio_free(pdata->gpio_int_mic_en);
- if (machine->gpio_requested & GPIO_HP_MUTE)
- gpio_free(pdata->gpio_hp_mute);
- if (machine->gpio_requested & GPIO_SPKR_EN)
- gpio_free(pdata->gpio_spkr_en);
- machine->gpio_requested = 0;
-
- snd_soc_unregister_card(card);
-
- tegra_asoc_utils_fini(&machine->util_data);
- if (!IS_ERR(machine->pcm_dev))
- platform_device_unregister(machine->pcm_dev);
-
- return 0;
-}
-
-static const struct of_device_id tegra_wm8903_of_match[] __devinitconst = {
- { .compatible = "nvidia,tegra-audio-wm8903", },
- {},
-};
-
-static struct platform_driver tegra_wm8903_driver = {
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- .pm = &snd_soc_pm_ops,
- .of_match_table = tegra_wm8903_of_match,
- },
- .probe = tegra_wm8903_driver_probe,
- .remove = __devexit_p(tegra_wm8903_driver_remove),
-};
-module_platform_driver(tegra_wm8903_driver);
-
-MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
-MODULE_DESCRIPTION("Tegra+WM8903 machine ASoC driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" DRV_NAME);
-MODULE_DEVICE_TABLE(of, tegra_wm8903_of_match);
diff --git a/ANDROID_3.4.5/sound/soc/tegra/trimslice.c b/ANDROID_3.4.5/sound/soc/tegra/trimslice.c
deleted file mode 100644
index 2bdfc550..00000000
--- a/ANDROID_3.4.5/sound/soc/tegra/trimslice.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * trimslice.c - TrimSlice machine ASoC driver
- *
- * Copyright (C) 2011 - CompuLab, Ltd.
- * Author: Mike Rapoport <mike@compulab.co.il>
- *
- * Based on code copyright/by:
- * Author: Stephen Warren <swarren@nvidia.com>
- * Copyright (C) 2010-2011 - NVIDIA, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <asm/mach-types.h>
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <sound/core.h>
-#include <sound/jack.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include "../codecs/tlv320aic23.h"
-
-#include "tegra_das.h"
-#include "tegra_i2s.h"
-#include "tegra_pcm.h"
-#include "tegra_asoc_utils.h"
-
-#define DRV_NAME "tegra-snd-trimslice"
-
-struct tegra_trimslice {
- struct tegra_asoc_utils_data util_data;
-};
-
-static int trimslice_asoc_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_card *card = codec->card;
- struct tegra_trimslice *trimslice = snd_soc_card_get_drvdata(card);
- int srate, mclk;
- int err;
-
- srate = params_rate(params);
- mclk = 128 * srate;
-
- err = tegra_asoc_utils_set_rate(&trimslice->util_data, srate, mclk);
- if (err < 0) {
- dev_err(card->dev, "Can't configure clocks\n");
- return err;
- }
-
- err = snd_soc_dai_set_fmt(codec_dai,
- SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS);
- if (err < 0) {
- dev_err(card->dev, "codec_dai fmt not set\n");
- return err;
- }
-
- err = snd_soc_dai_set_fmt(cpu_dai,
- SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS);
- if (err < 0) {
- dev_err(card->dev, "cpu_dai fmt not set\n");
- return err;
- }
-
- err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
- SND_SOC_CLOCK_IN);
- if (err < 0) {
- dev_err(card->dev, "codec_dai clock not set\n");
- return err;
- }
-
- return 0;
-}
-
-static struct snd_soc_ops trimslice_asoc_ops = {
- .hw_params = trimslice_asoc_hw_params,
-};
-
-static const struct snd_soc_dapm_widget trimslice_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Line Out", NULL),
- SND_SOC_DAPM_LINE("Line In", NULL),
-};
-
-static const struct snd_soc_dapm_route trimslice_audio_map[] = {
- {"Line Out", NULL, "LOUT"},
- {"Line Out", NULL, "ROUT"},
-
- {"LLINEIN", NULL, "Line In"},
- {"RLINEIN", NULL, "Line In"},
-};
-
-static struct snd_soc_dai_link trimslice_tlv320aic23_dai = {
- .name = "TLV320AIC23",
- .stream_name = "AIC23",
- .codec_name = "tlv320aic23-codec.2-001a",
- .platform_name = "tegra-pcm-audio",
- .cpu_dai_name = "tegra-i2s.0",
- .codec_dai_name = "tlv320aic23-hifi",
- .ops = &trimslice_asoc_ops,
-};
-
-static struct snd_soc_card snd_soc_trimslice = {
- .name = "tegra-trimslice",
- .owner = THIS_MODULE,
- .dai_link = &trimslice_tlv320aic23_dai,
- .num_links = 1,
-
- .dapm_widgets = trimslice_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(trimslice_dapm_widgets),
- .dapm_routes = trimslice_audio_map,
- .num_dapm_routes = ARRAY_SIZE(trimslice_audio_map),
- .fully_routed = true,
-};
-
-static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev)
-{
- struct snd_soc_card *card = &snd_soc_trimslice;
- struct tegra_trimslice *trimslice;
- int ret;
-
- trimslice = devm_kzalloc(&pdev->dev, sizeof(struct tegra_trimslice),
- GFP_KERNEL);
- if (!trimslice) {
- dev_err(&pdev->dev, "Can't allocate tegra_trimslice\n");
- ret = -ENOMEM;
- goto err;
- }
-
- ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev);
- if (ret)
- goto err;
-
- card->dev = &pdev->dev;
- platform_set_drvdata(pdev, card);
- snd_soc_card_set_drvdata(card, trimslice);
-
- ret = snd_soc_register_card(card);
- if (ret) {
- dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
- ret);
- goto err_fini_utils;
- }
-
- return 0;
-
-err_fini_utils:
- tegra_asoc_utils_fini(&trimslice->util_data);
-err:
- return ret;
-}
-
-static int __devexit tegra_snd_trimslice_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
- struct tegra_trimslice *trimslice = snd_soc_card_get_drvdata(card);
-
- snd_soc_unregister_card(card);
-
- tegra_asoc_utils_fini(&trimslice->util_data);
-
- return 0;
-}
-
-static struct platform_driver tegra_snd_trimslice_driver = {
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- },
- .probe = tegra_snd_trimslice_probe,
- .remove = __devexit_p(tegra_snd_trimslice_remove),
-};
-module_platform_driver(tegra_snd_trimslice_driver);
-
-MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
-MODULE_DESCRIPTION("Trimslice machine ASoC driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/ANDROID_3.4.5/sound/soc/txx9/Kconfig b/ANDROID_3.4.5/sound/soc/txx9/Kconfig
deleted file mode 100644
index ebc9327e..00000000
--- a/ANDROID_3.4.5/sound/soc/txx9/Kconfig
+++ /dev/null
@@ -1,29 +0,0 @@
-##
-## TXx9 ACLC
-##
-config SND_SOC_TXX9ACLC
- tristate "SoC Audio for TXx9"
- depends on HAS_TXX9_ACLC && TXX9_DMAC
- help
- This option enables support for the AC Link Controllers in TXx9 SoC.
-
-config HAS_TXX9_ACLC
- bool
-
-config SND_SOC_TXX9ACLC_AC97
- tristate
- select AC97_BUS
- select SND_AC97_CODEC
- select SND_SOC_AC97_BUS
-
-
-##
-## Boards
-##
-config SND_SOC_TXX9ACLC_GENERIC
- tristate "Generic TXx9 ACLC sound machine"
- depends on SND_SOC_TXX9ACLC
- select SND_SOC_TXX9ACLC_AC97
- select SND_SOC_AC97_CODEC
- help
- This is a generic AC97 sound machine for use in TXx9 based systems.
diff --git a/ANDROID_3.4.5/sound/soc/txx9/Makefile b/ANDROID_3.4.5/sound/soc/txx9/Makefile
deleted file mode 100644
index 551f16c0..00000000
--- a/ANDROID_3.4.5/sound/soc/txx9/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# Platform
-snd-soc-txx9aclc-objs := txx9aclc.o
-snd-soc-txx9aclc-ac97-objs := txx9aclc-ac97.o
-
-obj-$(CONFIG_SND_SOC_TXX9ACLC) += snd-soc-txx9aclc.o
-obj-$(CONFIG_SND_SOC_TXX9ACLC_AC97) += snd-soc-txx9aclc-ac97.o
-
-# Machine
-snd-soc-txx9aclc-generic-objs := txx9aclc-generic.o
-
-obj-$(CONFIG_SND_SOC_TXX9ACLC_GENERIC) += snd-soc-txx9aclc-generic.o
diff --git a/ANDROID_3.4.5/sound/soc/txx9/txx9aclc-ac97.c b/ANDROID_3.4.5/sound/soc/txx9/txx9aclc-ac97.c
deleted file mode 100644
index 28db4ca9..00000000
--- a/ANDROID_3.4.5/sound/soc/txx9/txx9aclc-ac97.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * TXx9 ACLC AC97 driver
- *
- * Copyright (C) 2009 Atsushi Nemoto
- *
- * Based on RBTX49xx patch from CELF patch archive.
- * (C) Copyright TOSHIBA CORPORATION 2004-2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/gfp.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include "txx9aclc.h"
-
-#define AC97_DIR \
- (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE)
-
-#define AC97_RATES \
- SNDRV_PCM_RATE_8000_48000
-
-#ifdef __BIG_ENDIAN
-#define AC97_FMTS SNDRV_PCM_FMTBIT_S16_BE
-#else
-#define AC97_FMTS SNDRV_PCM_FMTBIT_S16_LE
-#endif
-
-static DECLARE_WAIT_QUEUE_HEAD(ac97_waitq);
-
-/* REVISIT: How to find txx9aclc_drvdata from snd_ac97? */
-static struct txx9aclc_plat_drvdata *txx9aclc_drvdata;
-
-static int txx9aclc_regready(struct txx9aclc_plat_drvdata *drvdata)
-{
- return __raw_readl(drvdata->base + ACINTSTS) & ACINT_REGACCRDY;
-}
-
-/* AC97 controller reads codec register */
-static unsigned short txx9aclc_ac97_read(struct snd_ac97 *ac97,
- unsigned short reg)
-{
- struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata;
- void __iomem *base = drvdata->base;
- u32 dat;
-
- if (!(__raw_readl(base + ACINTSTS) & ACINT_CODECRDY(ac97->num)))
- return 0xffff;
- reg |= ac97->num << 7;
- dat = (reg << ACREGACC_REG_SHIFT) | ACREGACC_READ;
- __raw_writel(dat, base + ACREGACC);
- __raw_writel(ACINT_REGACCRDY, base + ACINTEN);
- if (!wait_event_timeout(ac97_waitq, txx9aclc_regready(txx9aclc_drvdata), HZ)) {
- __raw_writel(ACINT_REGACCRDY, base + ACINTDIS);
- printk(KERN_ERR "ac97 read timeout (reg %#x)\n", reg);
- dat = 0xffff;
- goto done;
- }
- dat = __raw_readl(base + ACREGACC);
- if (((dat >> ACREGACC_REG_SHIFT) & 0xff) != reg) {
- printk(KERN_ERR "reg mismatch %x with %x\n",
- dat, reg);
- dat = 0xffff;
- goto done;
- }
- dat = (dat >> ACREGACC_DAT_SHIFT) & 0xffff;
-done:
- __raw_writel(ACINT_REGACCRDY, base + ACINTDIS);
- return dat;
-}
-
-/* AC97 controller writes to codec register */
-static void txx9aclc_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
- unsigned short val)
-{
- struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata;
- void __iomem *base = drvdata->base;
-
- __raw_writel(((reg | (ac97->num << 7)) << ACREGACC_REG_SHIFT) |
- (val << ACREGACC_DAT_SHIFT),
- base + ACREGACC);
- __raw_writel(ACINT_REGACCRDY, base + ACINTEN);
- if (!wait_event_timeout(ac97_waitq, txx9aclc_regready(txx9aclc_drvdata), HZ)) {
- printk(KERN_ERR
- "ac97 write timeout (reg %#x)\n", reg);
- }
- __raw_writel(ACINT_REGACCRDY, base + ACINTDIS);
-}
-
-static void txx9aclc_ac97_cold_reset(struct snd_ac97 *ac97)
-{
- struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata;
- void __iomem *base = drvdata->base;
- u32 ready = ACINT_CODECRDY(ac97->num) | ACINT_REGACCRDY;
-
- __raw_writel(ACCTL_ENLINK, base + ACCTLDIS);
- mmiowb();
- udelay(1);
- __raw_writel(ACCTL_ENLINK, base + ACCTLEN);
- /* wait for primary codec ready status */
- __raw_writel(ready, base + ACINTEN);
- if (!wait_event_timeout(ac97_waitq,
- (__raw_readl(base + ACINTSTS) & ready) == ready,
- HZ)) {
- dev_err(&ac97->dev, "primary codec is not ready "
- "(status %#x)\n",
- __raw_readl(base + ACINTSTS));
- }
- __raw_writel(ACINT_REGACCRDY, base + ACINTSTS);
- __raw_writel(ready, base + ACINTDIS);
-}
-
-/* AC97 controller operations */
-struct snd_ac97_bus_ops soc_ac97_ops = {
- .read = txx9aclc_ac97_read,
- .write = txx9aclc_ac97_write,
- .reset = txx9aclc_ac97_cold_reset,
-};
-EXPORT_SYMBOL_GPL(soc_ac97_ops);
-
-static irqreturn_t txx9aclc_ac97_irq(int irq, void *dev_id)
-{
- struct txx9aclc_plat_drvdata *drvdata = dev_id;
- void __iomem *base = drvdata->base;
-
- __raw_writel(__raw_readl(base + ACINTMSTS), base + ACINTDIS);
- wake_up(&ac97_waitq);
- return IRQ_HANDLED;
-}
-
-static int txx9aclc_ac97_probe(struct snd_soc_dai *dai)
-{
- txx9aclc_drvdata = snd_soc_dai_get_drvdata(dai);
- return 0;
-}
-
-static int txx9aclc_ac97_remove(struct snd_soc_dai *dai)
-{
- struct txx9aclc_plat_drvdata *drvdata = snd_soc_dai_get_drvdata(dai);
-
- /* disable AC-link */
- __raw_writel(ACCTL_ENLINK, drvdata->base + ACCTLDIS);
- txx9aclc_drvdata = NULL;
- return 0;
-}
-
-static struct snd_soc_dai_driver txx9aclc_ac97_dai = {
- .ac97_control = 1,
- .probe = txx9aclc_ac97_probe,
- .remove = txx9aclc_ac97_remove,
- .playback = {
- .rates = AC97_RATES,
- .formats = AC97_FMTS,
- .channels_min = 2,
- .channels_max = 2,
- },
- .capture = {
- .rates = AC97_RATES,
- .formats = AC97_FMTS,
- .channels_min = 2,
- .channels_max = 2,
- },
-};
-
-static int __devinit txx9aclc_ac97_dev_probe(struct platform_device *pdev)
-{
- struct txx9aclc_plat_drvdata *drvdata;
- struct resource *r;
- int err;
- int irq;
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return irq;
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!r)
- return -EBUSY;
-
- if (!devm_request_mem_region(&pdev->dev, r->start, resource_size(r),
- dev_name(&pdev->dev)))
- return -EBUSY;
-
- drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
- if (!drvdata)
- return -ENOMEM;
- platform_set_drvdata(pdev, drvdata);
- drvdata->physbase = r->start;
- if (sizeof(drvdata->physbase) > sizeof(r->start) &&
- r->start >= TXX9_DIRECTMAP_BASE &&
- r->start < TXX9_DIRECTMAP_BASE + 0x400000)
- drvdata->physbase |= 0xf00000000ull;
- drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
- if (!drvdata->base)
- return -EBUSY;
- err = devm_request_irq(&pdev->dev, irq, txx9aclc_ac97_irq,
- 0, dev_name(&pdev->dev), drvdata);
- if (err < 0)
- return err;
-
- return snd_soc_register_dai(&pdev->dev, &txx9aclc_ac97_dai);
-}
-
-static int __devexit txx9aclc_ac97_dev_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_dai(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver txx9aclc_ac97_driver = {
- .probe = txx9aclc_ac97_dev_probe,
- .remove = __devexit_p(txx9aclc_ac97_dev_remove),
- .driver = {
- .name = "txx9aclc-ac97",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(txx9aclc_ac97_driver);
-
-MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
-MODULE_DESCRIPTION("TXx9 ACLC AC97 driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:txx9aclc-ac97");
diff --git a/ANDROID_3.4.5/sound/soc/txx9/txx9aclc-generic.c b/ANDROID_3.4.5/sound/soc/txx9/txx9aclc-generic.c
deleted file mode 100644
index b056a143..00000000
--- a/ANDROID_3.4.5/sound/soc/txx9/txx9aclc-generic.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Generic TXx9 ACLC machine driver
- *
- * Copyright (C) 2009 Atsushi Nemoto
- *
- * Based on RBTX49xx patch from CELF patch archive.
- * (C) Copyright TOSHIBA CORPORATION 2004-2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This is a very generic AC97 sound machine driver for boards which
- * have (AC97) audio at ACLC (e.g. RBTX49XX boards).
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include "txx9aclc.h"
-
-static struct snd_soc_dai_link txx9aclc_generic_dai = {
- .name = "AC97",
- .stream_name = "AC97 HiFi",
- .cpu_dai_name = "txx9aclc-ac97",
- .codec_dai_name = "ac97-hifi",
- .platform_name = "txx9aclc-pcm-audio",
- .codec_name = "ac97-codec",
-};
-
-static struct snd_soc_card txx9aclc_generic_card = {
- .name = "Generic TXx9 ACLC Audio",
- .owner = THIS_MODULE,
- .dai_link = &txx9aclc_generic_dai,
- .num_links = 1,
-};
-
-static struct platform_device *soc_pdev;
-
-static int __init txx9aclc_generic_probe(struct platform_device *pdev)
-{
- int ret;
-
- soc_pdev = platform_device_alloc("soc-audio", -1);
- if (!soc_pdev)
- return -ENOMEM;
- platform_set_drvdata(soc_pdev, &txx9aclc_generic_card);
- ret = platform_device_add(soc_pdev);
- if (ret) {
- platform_device_put(soc_pdev);
- return ret;
- }
-
- return 0;
-}
-
-static int __exit txx9aclc_generic_remove(struct platform_device *pdev)
-{
- platform_device_unregister(soc_pdev);
- return 0;
-}
-
-static struct platform_driver txx9aclc_generic_driver = {
- .remove = __exit_p(txx9aclc_generic_remove),
- .driver = {
- .name = "txx9aclc-generic",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init txx9aclc_generic_init(void)
-{
- return platform_driver_probe(&txx9aclc_generic_driver,
- txx9aclc_generic_probe);
-}
-
-static void __exit txx9aclc_generic_exit(void)
-{
- platform_driver_unregister(&txx9aclc_generic_driver);
-}
-
-module_init(txx9aclc_generic_init);
-module_exit(txx9aclc_generic_exit);
-
-MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
-MODULE_DESCRIPTION("Generic TXx9 ACLC ALSA SoC audio driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:txx9aclc-generic");
diff --git a/ANDROID_3.4.5/sound/soc/txx9/txx9aclc.c b/ANDROID_3.4.5/sound/soc/txx9/txx9aclc.c
deleted file mode 100644
index b609d2c6..00000000
--- a/ANDROID_3.4.5/sound/soc/txx9/txx9aclc.c
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * Generic TXx9 ACLC platform driver
- *
- * Copyright (C) 2009 Atsushi Nemoto
- *
- * Based on RBTX49xx patch from CELF patch archive.
- * (C) Copyright TOSHIBA CORPORATION 2004-2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/scatterlist.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include "txx9aclc.h"
-
-static struct txx9aclc_soc_device {
- struct txx9aclc_dmadata dmadata[2];
-} txx9aclc_soc_device;
-
-/* REVISIT: How to find txx9aclc_drvdata from snd_ac97? */
-static struct txx9aclc_plat_drvdata *txx9aclc_drvdata;
-
-static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev,
- struct txx9aclc_dmadata *dmadata);
-
-static const struct snd_pcm_hardware txx9aclc_pcm_hardware = {
- /*
- * REVISIT: SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID
- * needs more works for noncoherent MIPS.
- */
- .info = SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BATCH |
- SNDRV_PCM_INFO_PAUSE,
-#ifdef __BIG_ENDIAN
- .formats = SNDRV_PCM_FMTBIT_S16_BE,
-#else
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
-#endif
- .period_bytes_min = 1024,
- .period_bytes_max = 8 * 1024,
- .periods_min = 2,
- .periods_max = 4096,
- .buffer_bytes_max = 32 * 1024,
-};
-
-static int txx9aclc_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct txx9aclc_dmadata *dmadata = runtime->private_data;
- int ret;
-
- ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
- if (ret < 0)
- return ret;
-
- dev_dbg(rtd->platform->dev,
- "runtime->dma_area = %#lx dma_addr = %#lx dma_bytes = %zd "
- "runtime->min_align %ld\n",
- (unsigned long)runtime->dma_area,
- (unsigned long)runtime->dma_addr, runtime->dma_bytes,
- runtime->min_align);
- dev_dbg(rtd->platform->dev,
- "periods %d period_bytes %d stream %d\n",
- params_periods(params), params_period_bytes(params),
- substream->stream);
-
- dmadata->substream = substream;
- dmadata->pos = 0;
- return 0;
-}
-
-static int txx9aclc_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int txx9aclc_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct txx9aclc_dmadata *dmadata = runtime->private_data;
-
- dmadata->dma_addr = runtime->dma_addr;
- dmadata->buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
- dmadata->period_bytes = snd_pcm_lib_period_bytes(substream);
-
- if (dmadata->buffer_bytes == dmadata->period_bytes) {
- dmadata->frag_bytes = dmadata->period_bytes >> 1;
- dmadata->frags = 2;
- } else {
- dmadata->frag_bytes = dmadata->period_bytes;
- dmadata->frags = dmadata->buffer_bytes / dmadata->period_bytes;
- }
- dmadata->frag_count = 0;
- dmadata->pos = 0;
- return 0;
-}
-
-static void txx9aclc_dma_complete(void *arg)
-{
- struct txx9aclc_dmadata *dmadata = arg;
- unsigned long flags;
-
- /* dma completion handler cannot submit new operations */
- spin_lock_irqsave(&dmadata->dma_lock, flags);
- if (dmadata->frag_count >= 0) {
- dmadata->dmacount--;
- BUG_ON(dmadata->dmacount < 0);
- tasklet_schedule(&dmadata->tasklet);
- }
- spin_unlock_irqrestore(&dmadata->dma_lock, flags);
-}
-
-static struct dma_async_tx_descriptor *
-txx9aclc_dma_submit(struct txx9aclc_dmadata *dmadata, dma_addr_t buf_dma_addr)
-{
- struct dma_chan *chan = dmadata->dma_chan;
- struct dma_async_tx_descriptor *desc;
- struct scatterlist sg;
-
- sg_init_table(&sg, 1);
- sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf_dma_addr)),
- dmadata->frag_bytes, buf_dma_addr & (PAGE_SIZE - 1));
- sg_dma_address(&sg) = buf_dma_addr;
- desc = dmaengine_prep_slave_sg(chan, &sg, 1,
- dmadata->substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
- DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
- DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
- if (!desc) {
- dev_err(&chan->dev->device, "cannot prepare slave dma\n");
- return NULL;
- }
- desc->callback = txx9aclc_dma_complete;
- desc->callback_param = dmadata;
- desc->tx_submit(desc);
- return desc;
-}
-
-#define NR_DMA_CHAIN 2
-
-static void txx9aclc_dma_tasklet(unsigned long data)
-{
- struct txx9aclc_dmadata *dmadata = (struct txx9aclc_dmadata *)data;
- struct dma_chan *chan = dmadata->dma_chan;
- struct dma_async_tx_descriptor *desc;
- struct snd_pcm_substream *substream = dmadata->substream;
- u32 ctlbit = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
- ACCTL_AUDODMA : ACCTL_AUDIDMA;
- int i;
- unsigned long flags;
-
- spin_lock_irqsave(&dmadata->dma_lock, flags);
- if (dmadata->frag_count < 0) {
- struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata;
- void __iomem *base = drvdata->base;
-
- spin_unlock_irqrestore(&dmadata->dma_lock, flags);
- chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
- /* first time */
- for (i = 0; i < NR_DMA_CHAIN; i++) {
- desc = txx9aclc_dma_submit(dmadata,
- dmadata->dma_addr + i * dmadata->frag_bytes);
- if (!desc)
- return;
- }
- dmadata->dmacount = NR_DMA_CHAIN;
- chan->device->device_issue_pending(chan);
- spin_lock_irqsave(&dmadata->dma_lock, flags);
- __raw_writel(ctlbit, base + ACCTLEN);
- dmadata->frag_count = NR_DMA_CHAIN % dmadata->frags;
- spin_unlock_irqrestore(&dmadata->dma_lock, flags);
- return;
- }
- BUG_ON(dmadata->dmacount >= NR_DMA_CHAIN);
- while (dmadata->dmacount < NR_DMA_CHAIN) {
- dmadata->dmacount++;
- spin_unlock_irqrestore(&dmadata->dma_lock, flags);
- desc = txx9aclc_dma_submit(dmadata,
- dmadata->dma_addr +
- dmadata->frag_count * dmadata->frag_bytes);
- if (!desc)
- return;
- chan->device->device_issue_pending(chan);
-
- spin_lock_irqsave(&dmadata->dma_lock, flags);
- dmadata->frag_count++;
- dmadata->frag_count %= dmadata->frags;
- dmadata->pos += dmadata->frag_bytes;
- dmadata->pos %= dmadata->buffer_bytes;
- if ((dmadata->frag_count * dmadata->frag_bytes) %
- dmadata->period_bytes == 0)
- snd_pcm_period_elapsed(substream);
- }
- spin_unlock_irqrestore(&dmadata->dma_lock, flags);
-}
-
-static int txx9aclc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct txx9aclc_dmadata *dmadata = substream->runtime->private_data;
- struct txx9aclc_plat_drvdata *drvdata =txx9aclc_drvdata;
- void __iomem *base = drvdata->base;
- unsigned long flags;
- int ret = 0;
- u32 ctlbit = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
- ACCTL_AUDODMA : ACCTL_AUDIDMA;
-
- spin_lock_irqsave(&dmadata->dma_lock, flags);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- dmadata->frag_count = -1;
- tasklet_schedule(&dmadata->tasklet);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- __raw_writel(ctlbit, base + ACCTLDIS);
- break;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
- __raw_writel(ctlbit, base + ACCTLEN);
- break;
- default:
- ret = -EINVAL;
- }
- spin_unlock_irqrestore(&dmadata->dma_lock, flags);
- return ret;
-}
-
-static snd_pcm_uframes_t
-txx9aclc_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct txx9aclc_dmadata *dmadata = substream->runtime->private_data;
-
- return bytes_to_frames(substream->runtime, dmadata->pos);
-}
-
-static int txx9aclc_pcm_open(struct snd_pcm_substream *substream)
-{
- struct txx9aclc_soc_device *dev = &txx9aclc_soc_device;
- struct txx9aclc_dmadata *dmadata = &dev->dmadata[substream->stream];
- int ret;
-
- ret = snd_soc_set_runtime_hwparams(substream, &txx9aclc_pcm_hardware);
- if (ret)
- return ret;
- /* ensure that buffer size is a multiple of period size */
- ret = snd_pcm_hw_constraint_integer(substream->runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (ret < 0)
- return ret;
- substream->runtime->private_data = dmadata;
- return 0;
-}
-
-static int txx9aclc_pcm_close(struct snd_pcm_substream *substream)
-{
- struct txx9aclc_dmadata *dmadata = substream->runtime->private_data;
- struct dma_chan *chan = dmadata->dma_chan;
-
- dmadata->frag_count = -1;
- chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
- return 0;
-}
-
-static struct snd_pcm_ops txx9aclc_pcm_ops = {
- .open = txx9aclc_pcm_open,
- .close = txx9aclc_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = txx9aclc_pcm_hw_params,
- .hw_free = txx9aclc_pcm_hw_free,
- .prepare = txx9aclc_pcm_prepare,
- .trigger = txx9aclc_pcm_trigger,
- .pointer = txx9aclc_pcm_pointer,
-};
-
-static void txx9aclc_pcm_free_dma_buffers(struct snd_pcm *pcm)
-{
- snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int txx9aclc_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_soc_dai *dai = rtd->cpu_dai;
- struct snd_pcm *pcm = rtd->pcm;
- struct platform_device *pdev = to_platform_device(dai->platform->dev);
- struct txx9aclc_soc_device *dev;
- struct resource *r;
- int i;
- int ret;
-
- /* at this point onwards the AC97 component has probed and this will be valid */
- dev = snd_soc_dai_get_drvdata(dai);
-
- dev->dmadata[0].stream = SNDRV_PCM_STREAM_PLAYBACK;
- dev->dmadata[1].stream = SNDRV_PCM_STREAM_CAPTURE;
- for (i = 0; i < 2; i++) {
- r = platform_get_resource(pdev, IORESOURCE_DMA, i);
- if (!r) {
- ret = -EBUSY;
- goto exit;
- }
- dev->dmadata[i].dma_res = r;
- ret = txx9aclc_dma_init(dev, &dev->dmadata[i]);
- if (ret)
- goto exit;
- }
- return snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- card->dev, 64 * 1024, 4 * 1024 * 1024);
-
-exit:
- for (i = 0; i < 2; i++) {
- if (dev->dmadata[i].dma_chan)
- dma_release_channel(dev->dmadata[i].dma_chan);
- dev->dmadata[i].dma_chan = NULL;
- }
- return ret;
-}
-
-static bool filter(struct dma_chan *chan, void *param)
-{
- struct txx9aclc_dmadata *dmadata = param;
- char *devname;
- bool found = false;
-
- devname = kasprintf(GFP_KERNEL, "%s.%d", dmadata->dma_res->name,
- (int)dmadata->dma_res->start);
- if (strcmp(dev_name(chan->device->dev), devname) == 0) {
- chan->private = &dmadata->dma_slave;
- found = true;
- }
- kfree(devname);
- return found;
-}
-
-static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev,
- struct txx9aclc_dmadata *dmadata)
-{
- struct txx9aclc_plat_drvdata *drvdata =txx9aclc_drvdata;
- struct txx9dmac_slave *ds = &dmadata->dma_slave;
- dma_cap_mask_t mask;
-
- spin_lock_init(&dmadata->dma_lock);
-
- ds->reg_width = sizeof(u32);
- if (dmadata->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- ds->tx_reg = drvdata->physbase + ACAUDODAT;
- ds->rx_reg = 0;
- } else {
- ds->tx_reg = 0;
- ds->rx_reg = drvdata->physbase + ACAUDIDAT;
- }
-
- /* Try to grab a DMA channel */
- dma_cap_zero(mask);
- dma_cap_set(DMA_SLAVE, mask);
- dmadata->dma_chan = dma_request_channel(mask, filter, dmadata);
- if (!dmadata->dma_chan) {
- printk(KERN_ERR
- "DMA channel for %s is not available\n",
- dmadata->stream == SNDRV_PCM_STREAM_PLAYBACK ?
- "playback" : "capture");
- return -EBUSY;
- }
- tasklet_init(&dmadata->tasklet, txx9aclc_dma_tasklet,
- (unsigned long)dmadata);
- return 0;
-}
-
-static int txx9aclc_pcm_probe(struct snd_soc_platform *platform)
-{
- snd_soc_platform_set_drvdata(platform, &txx9aclc_soc_device);
- return 0;
-}
-
-static int txx9aclc_pcm_remove(struct snd_soc_platform *platform)
-{
- struct txx9aclc_soc_device *dev = snd_soc_platform_get_drvdata(platform);
- struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata;
- void __iomem *base = drvdata->base;
- int i;
-
- /* disable all FIFO DMAs */
- __raw_writel(ACCTL_AUDODMA | ACCTL_AUDIDMA, base + ACCTLDIS);
- /* dummy R/W to clear pending DMAREQ if any */
- __raw_writel(__raw_readl(base + ACAUDIDAT), base + ACAUDODAT);
-
- for (i = 0; i < 2; i++) {
- struct txx9aclc_dmadata *dmadata = &dev->dmadata[i];
- struct dma_chan *chan = dmadata->dma_chan;
- if (chan) {
- dmadata->frag_count = -1;
- chan->device->device_control(chan,
- DMA_TERMINATE_ALL, 0);
- dma_release_channel(chan);
- }
- dev->dmadata[i].dma_chan = NULL;
- }
- return 0;
-}
-
-static struct snd_soc_platform_driver txx9aclc_soc_platform = {
- .probe = txx9aclc_pcm_probe,
- .remove = txx9aclc_pcm_remove,
- .ops = &txx9aclc_pcm_ops,
- .pcm_new = txx9aclc_pcm_new,
- .pcm_free = txx9aclc_pcm_free_dma_buffers,
-};
-
-static int __devinit txx9aclc_soc_platform_probe(struct platform_device *pdev)
-{
- return snd_soc_register_platform(&pdev->dev, &txx9aclc_soc_platform);
-}
-
-static int __devexit txx9aclc_soc_platform_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver txx9aclc_pcm_driver = {
- .driver = {
- .name = "txx9aclc-pcm-audio",
- .owner = THIS_MODULE,
- },
-
- .probe = txx9aclc_soc_platform_probe,
- .remove = __devexit_p(txx9aclc_soc_platform_remove),
-};
-
-module_platform_driver(txx9aclc_pcm_driver);
-
-MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
-MODULE_DESCRIPTION("TXx9 ACLC Audio DMA driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/txx9/txx9aclc.h b/ANDROID_3.4.5/sound/soc/txx9/txx9aclc.h
deleted file mode 100644
index 9c2de84f..00000000
--- a/ANDROID_3.4.5/sound/soc/txx9/txx9aclc.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * TXx9 SoC AC Link Controller
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __TXX9ACLC_H
-#define __TXX9ACLC_H
-
-#include <linux/interrupt.h>
-#include <asm/txx9/dmac.h>
-
-#define ACCTLEN 0x00 /* control enable */
-#define ACCTLDIS 0x04 /* control disable */
-#define ACCTL_ENLINK 0x00000001 /* enable/disable AC-link */
-#define ACCTL_AUDODMA 0x00000100 /* AUDODMA enable/disable */
-#define ACCTL_AUDIDMA 0x00001000 /* AUDIDMA enable/disable */
-#define ACCTL_AUDOEHLT 0x00010000 /* AUDO error halt
- enable/disable */
-#define ACCTL_AUDIEHLT 0x00100000 /* AUDI error halt
- enable/disable */
-#define ACREGACC 0x08 /* codec register access */
-#define ACREGACC_DAT_SHIFT 0 /* data field */
-#define ACREGACC_REG_SHIFT 16 /* address field */
-#define ACREGACC_CODECID_SHIFT 24 /* CODEC ID field */
-#define ACREGACC_READ 0x80000000 /* CODEC read */
-#define ACREGACC_WRITE 0x00000000 /* CODEC write */
-#define ACINTSTS 0x10 /* interrupt status */
-#define ACINTMSTS 0x14 /* interrupt masked status */
-#define ACINTEN 0x18 /* interrupt enable */
-#define ACINTDIS 0x1c /* interrupt disable */
-#define ACINT_CODECRDY(n) (0x00000001 << (n)) /* CODECn ready */
-#define ACINT_REGACCRDY 0x00000010 /* ACREGACC ready */
-#define ACINT_AUDOERR 0x00000100 /* AUDO underrun error */
-#define ACINT_AUDIERR 0x00001000 /* AUDI overrun error */
-#define ACDMASTS 0x80 /* DMA request status */
-#define ACDMA_AUDO 0x00000001 /* AUDODMA pending */
-#define ACDMA_AUDI 0x00000010 /* AUDIDMA pending */
-#define ACAUDODAT 0xa0 /* audio out data */
-#define ACAUDIDAT 0xb0 /* audio in data */
-#define ACREVID 0xfc /* revision ID */
-
-struct txx9aclc_dmadata {
- struct resource *dma_res;
- struct txx9dmac_slave dma_slave;
- struct dma_chan *dma_chan;
- struct tasklet_struct tasklet;
- spinlock_t dma_lock;
- int stream; /* SNDRV_PCM_STREAM_PLAYBACK or SNDRV_PCM_STREAM_CAPTURE */
- struct snd_pcm_substream *substream;
- unsigned long pos;
- dma_addr_t dma_addr;
- unsigned long buffer_bytes;
- unsigned long period_bytes;
- unsigned long frag_bytes;
- int frags;
- int frag_count;
- int dmacount;
-};
-
-struct txx9aclc_plat_drvdata {
- void __iomem *base;
- u64 physbase;
-};
-
-static inline struct txx9aclc_plat_drvdata *txx9aclc_get_plat_drvdata(
- struct snd_soc_dai *dai)
-{
- return dev_get_drvdata(dai->dev);
-}
-
-#endif /* __TXX9ACLC_H */
diff --git a/ANDROID_3.4.5/sound/soc/wmt/Kconfig b/ANDROID_3.4.5/sound/soc/wmt/Kconfig
deleted file mode 100755
index 344ec73d..00000000
--- a/ANDROID_3.4.5/sound/soc/wmt/Kconfig
+++ /dev/null
@@ -1,65 +0,0 @@
-config SND_WMT_SOC
- bool "SoC Audio for the WMT chip"
- depends on ARCH_WMT && SND && SND_SOC
- help
- Say Y or M if you want to add support for codecs attached to
- the WMT AC97, I2S interface. You will also need
- to select the audio interfaces to support below.
-
-#
-# WMT ALSA I2S driver
-#
-config SND_WMT_SOC_I2S
- bool "SoC I2S Audio support for WMT"
- depends on SND_WMT_SOC
- ---help---
- Say Y or M if you want to add support for codecs attached to
- the WMT I2S interface.
-
-config SND_WMT_SOC_PDM
- bool "SoC PDM Audio Interface support for WMT"
- depends on SND_WMT_SOC
- ---help---
- Say Y or M if you want to add support for codecs attached to
- the WMT PDM interface.
-
-config I2S_HW_DAC
- bool "HW_DAC"
- depends on SND_WMT_SOC_I2S
- select SND_SOC_HWDAC
- ---help---
- Say Y here if you want to use HW DAC.
-
-config I2S_CODEC_VT1602
- bool "VT1602"
- depends on SND_WMT_SOC_I2S
- select SND_SOC_VT1602
- ---help---
- Say Y here if you want to use VT1602 as the I2S Codec.
-
-config I2S_CODEC_WM8900
- bool "WM8900"
- depends on SND_WMT_SOC_I2S
- select SND_SOC_WM8900
- ---help---
- Say Y here if you want to use WM8900 as the I2S Codec.
-
-config I2S_CODEC_WM8994
- bool "WM8994"
- depends on SND_WMT_SOC_I2S
- select SND_SOC_WM8994
- ---help---
- Say Y here if you want to use WM8994 as the I2S Codec.
-
-config I2S_CODEC_VT1603
- bool "VT1603"
- depends on SND_WMT_SOC_I2S
- select SND_SOC_VT1603
- ---help---
- Say Y here if you want to use VT1603 as the I2S Codec.
-
-config ECHO_CANCELLATION_FM34
- tristate "FM34"
- select SND_SOC_WMT_FM34
- ---help---
- Say Y here if you want to use fm34 to echo cancallation.
diff --git a/ANDROID_3.4.5/sound/soc/wmt/Makefile b/ANDROID_3.4.5/sound/soc/wmt/Makefile
deleted file mode 100755
index bf4a07ef..00000000
--- a/ANDROID_3.4.5/sound/soc/wmt/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-## Makefile for ALSA WMT
-#
-#
-# WMT SOC Support
-snd-soc-wmt-i2s-objs := wmt-i2s.o wmt_swmixer.o
-snd-soc-wmt-objs := wmt-soc.o wmt-pcm.o wmt_wm8994.o wmt_hwdep.o
-
-snd-soc-wmt-pdm-objs := wmt-pcm-controller.o wmt-pcm-dma.o
-obj-$(CONFIG_SND_WMT_SOC_I2S) += snd-soc-wmt-i2s.o
-obj-$(CONFIG_SND_WMT_SOC) += snd-soc-wmt.o
-obj-$(CONFIG_SND_WMT_SOC_PDM) += snd-soc-wmt-pdm.o
diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt-i2s.c b/ANDROID_3.4.5/sound/soc/wmt/wmt-i2s.c
deleted file mode 100755
index 643d25e2..00000000
--- a/ANDROID_3.4.5/sound/soc/wmt/wmt-i2s.c
+++ /dev/null
@@ -1,1105 +0,0 @@
-/*++
- * linux/sound/soc/wmt/wmt-i2s.c
- * WonderMedia I2S audio driver for ALSA
- *
- * Copyright c 2010 WonderMedia Technologies, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * WonderMedia Technologies, Inc.
- * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
---*/
-
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <asm/irq.h>
-#include <linux/delay.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include <linux/gpio.h>
-#include <mach/wmt_iomux.h>
-#include <linux/suspend.h>
-
-#include <mach/hardware.h>
-#include <asm/dma.h>
-#include "wmt-soc.h"
-#include "wmt-pcm.h"
-
-#define NULL_DMA ((dmach_t)(-1))
-#define AUD_SPDIF_ENABLE 1
-
-static int wmt_i2s_output = 0; //hdmi enable or not 2013-9-3 //maybe can remove it 2013-10-24
-static int wmt_codec_wm8994 = 0; //env set 2013-9-3
-
-static int gpio_pa = -1;
-static int gpio_active = 0;
-extern int wmt_gpio_setpull(unsigned int gpio, enum wmt_gpio_pulltype pull);
-/*
- * Debug
- */
-#define AUDIO_NAME "WMT_I2S"
-//#define WMT_I2S_DEBUG 1
-//#define WMT_I2S_DEBUG_DETAIL 1
-
-#ifdef WMT_I2S_DEBUG
-#define DPRINTK(format, arg...) \
- printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
-#else
-#define DPRINTK(format, arg...) do {} while (0)
-#endif
-
-#ifdef WMT_I2S_DEBUG_DETAIL
-#define DBG_DETAIL(format, arg...) \
- printk(KERN_INFO AUDIO_NAME ": [%s]" format "\n" , __FUNCTION__, ## arg)
-#else
-#define DBG_DETAIL(format, arg...) do {} while (0)
-#endif
-
-#define err(format, arg...) \
- printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg)
-#define info(format, arg...) \
- printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
-#define warn(format, arg...) \
- printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg)
-
-struct wmt_i2s_asoc_data {
- int stream_id;
- unsigned int bus_id;
- struct i2s_s i2s;
- /*
- * Flags indicating is the bus already activated and configured by
- * another substream
- */
- unsigned char HDMI_and_DAC0; //new env set to determine
- unsigned char HDMI_aud_enable; //same with global wmt_i2s_output
-
- int active;
- int configured;
- unsigned char CH_SEL_NUM;
- unsigned char HDMI_SPDIF_STATE;
- /*struct timer_list delay_timer;*/
- struct audio_stream_a s[2];
-};
-static struct timer_list pa_timer;
-
-static int audio_interface_mode = 0;//add 2014-6-24 i2s left right
-
-static int wmt_pdm_module_enable = 0;
-extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
-
-#define to_i2s_data(priv) container_of((priv), struct wmt_i2s_asoc_data, bus_id)
-#define SNDRV_PCM_STREAM_ALL 2
-
-static void i2s_init(int mode);
-static void i2s_exit(void);
-
-#ifdef CONFIG_FB_WMT
-extern int vpp_set_audio(int format, int sample_rate, int channel);
-#endif
-
-
-static struct wmt_i2s_asoc_data i2s_data[NUM_LINKS] = {
- {
- .bus_id = 0, //?? 2 SNDRV_PCM_STREAM_ALL
- .i2s = {
- /* interrupt counters */
- {0, 0, 0, 0, 0, 0, 0, 0},
- /* irq number*/
- 0,
- /* reference counter */
- 0,
- /* channels */
- 0,
- /* format */
- 0,
- /* fragment size */
- 0,
- /* sample rate */
- 0,
- i2s_init,
- i2s_exit,
- },
- .s = {
- {
- .id = "WMT I2S out",
- .stream_id = SNDRV_PCM_STREAM_PLAYBACK,
- .dmach = NULL_DMA,
- .dma_dev = AHB1_AUD_DMA_REQ_1,
- /*.dma_cfg = dma_device_cfg_table[I2S_TX_DMA_REQ],*/
- },
- {
- .id = "WMT I2S in",
- .stream_id = SNDRV_PCM_STREAM_CAPTURE,
- .dmach = NULL_DMA,
- .dma_dev = AHB1_AUD_DMA_REQ_0,
- /*.dma_cfg = dma_device_cfg_table[I2S_RX_DMA_REQ],*/
- },
- },
- .HDMI_aud_enable = 0,
- .HDMI_and_DAC0 = 0,
- .CH_SEL_NUM = 2,
- .HDMI_SPDIF_STATE = 6,//hdmi spdif play at sametime
- },
-};
-
-
-/* for HDMI Audio status */
-int hd_audio_flag = 0;
-
-
-
-#ifdef CONFIG_WMT_I2S_INT
-/* wmt_i2s_interrupt()
- *
- * It's only interrupt counter now, might be useful to
- * debug or benchmark.
- */
-static irqreturn_t
-wmt_i2s_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- DBG_DETAIL();
-
- return IRQ_HANDLED;
-}
-#endif
-
-#if 0
-static void delay_timer_handler(unsigned long data)
-{
- DBG_DETAIL();
-}
-#endif
-
-static void pa_timer_handler(unsigned long data)
-{
- printk("%s\n", __func__);
- if (gpio_pa >= 0)
- {
-
- gpio_direction_output(gpio_pa, gpio_active);
- }
-}
-
-void wmt_i2s_ch_config(void)
-{
- /* CH_SEL_NUM = 0, mesns output L to SPDIF&DAC's L and R
- 1, mesns output R to SPDIF&DAC's L and R
- 2, means normal stereo output to SPDIF&DAC */
- switch (i2s_data->CH_SEL_NUM) {
- case 0:
- ASMPFCHCFG0_VAL = 0x10100000;
- ASMPF2HDACHCFG_VAL = 0x76543200;
- break;
- case 1:
- ASMPFCHCFG0_VAL = 0x10101111;
- ASMPF2HDACHCFG_VAL = 0x76543211;
- break;
- case 2:
- ASMPFCHCFG0_VAL = 0x10101010;
- ASMPF2HDACHCFG_VAL = 0x76543210;
- break;
- }
-
- if (i2s_data->i2s.channels == 0x01) {
- ASMPFCHCFG0_VAL = 0x10100000;
- ASMPF2HDACHCFG_VAL = 0x76543200;
- }
-
- if (i2s_data->HDMI_aud_enable) {
- /* disable DAC#0, if HDMI Audio is enabled */
- ASMPFCHCFG0_VAL &= 0xFFFF00FF;
- ASMPFCHCFG0_VAL |= 0x00009800;
- }
-
- /* HDMI_SPDIF_STATE = 3, means disable HDMI&SPDIF
- 4, means enable HDMI only
- 5, means enable SPDIF only
- 6, means enable HDMI&SPDIF as normal */
- switch (i2s_data->HDMI_SPDIF_STATE) {
- case 3:
- ASMPFCHCFG0_VAL &= 0xFFFFFF00;
- ASMPFCHCFG0_VAL |= 0x00000098;
- ASMPF2HDACHCFG_VAL &= 0xFFFFFF00;
- ASMPF2HDACHCFG_VAL |= 0x00000076;
- break;
- case 4:
- ASMPFCHCFG0_VAL &= 0xFFFFFF00;
- ASMPFCHCFG0_VAL |= 0x00000098;
- break;
- case 5:
- ASMPF2HDACHCFG_VAL &= 0xFFFFFF00;
- ASMPF2HDACHCFG_VAL |= 0x00000076;
- break;
- }
-}
-
-
-void wmt_i2s_dac0_ctrl(int HDMI_audio_enable)
-{
- /* check if output to HDMI audio and DAC0 at same time */
- if (i2s_data->HDMI_and_DAC0)
- return;
-
- if (HDMI_audio_enable) {
- i2s_data->HDMI_aud_enable = 1;
- info("HDMI Audio is enabled, disable dac0 of I2S");
- }
- else {
- i2s_data->HDMI_aud_enable = 0;
- info("HDMI Audio is disabled, enable dac0 of I2S");
- }
-
- wmt_i2s_ch_config();
-
- info("CHCFG0=0x%x, HDACHCFG=0x%x", ASMPFCHCFG0_VAL, ASMPF2HDACHCFG_VAL);
-}
-EXPORT_SYMBOL(wmt_i2s_dac0_ctrl);
-void wmt_i2s_ch_sel(int ch_sel_num)
-{
- if (ch_sel_num < 3)
- i2s_data->CH_SEL_NUM = ch_sel_num;
- else
- i2s_data->HDMI_SPDIF_STATE = ch_sel_num;
-
- wmt_i2s_ch_config();
-
-
- info("SEL: CHCFG0=0x%x, HDACHCFG=0x%x", ASMPFCHCFG0_VAL, ASMPF2HDACHCFG_VAL);
-}
-EXPORT_SYMBOL(wmt_i2s_ch_sel);
-
-static void i2s_disable(void)
-{
- DBG_DETAIL();
-
- DACCFG_VAL &= ~DACITF_ENABLE;
- ASMPFCFG_VAL &=~ASMPF_ENABLE;
- HDACKGEN_VAL &= ~HDACKGEN_ENABLE;
-
-#ifdef AUD_SPDIF_ENABLE
- DGOCFG_VAL &= ~DGOITF_ENABLE;
-#endif
-
- AADCF0CFG_VAL &= ~(AADCITF_ENABLE | AADCF_ENABLE);
-}
-
-static void i2s_enable(void)
-{
- DBG_DETAIL();
-
- AADCF0CFG_VAL |= (AADCITF_ENABLE | AADCF_ENABLE);
- ASMPFCFG_VAL |= (ASMPF_ENABLE);
-
-#ifdef AUD_SPDIF_ENABLE
- DGOCFG_VAL |= DGOITF_ENABLE;
-#endif
-
- DACCFG_VAL |= DACITF_ENABLE;
-
- if (hd_audio_flag)
- HDACKGEN_VAL |= HDACKGEN_ENABLE;
-}
-
-static void aud_audprf_setting(unsigned char smp_rate_index)
-{
- unsigned long cfg_tbl[] = {0x00002001, 0x00002001, 0x00002001,
- 0x00002001, 0x00002001, 0x00002001, 0x00002001, 0x00002001,
- 0x00002001, 0x00002001, 0x00002001, 0x00002001,
- 0x00000001, 0x00000001, 0x00000001
- };
- unsigned int dgo_tbl[] = {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00};
- unsigned int sysclk_tbl[] = {4096, 5632, 6144, 8192, 11264, 12288, 16384,
- 22579, 24576, 32768, 45056, 49152, 16384, 22528, 24576};
-#ifdef AUD_SPDIF_ENABLE
- unsigned int dgocs_tbl[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x02, 0x00, 0x08, 0x0A, 0x00, 0x0C, 0x0E};
-#endif
- //unsigned int clock = 0;
- unsigned long aud_reg_val;
-
- DBG_DETAIL();
-
- ADCCFG_VAL = cfg_tbl[smp_rate_index];
-
- aud_reg_val = dgo_tbl[smp_rate_index];
- DGOCFG_VAL = aud_reg_val;
- HDACKGEN_VAL = aud_reg_val;
-
-#ifdef AUD_SPDIF_ENABLE
- /* set ADGO channel status */
- aud_reg_val = dgocs_tbl[smp_rate_index] << 24;
- DGOCS0A_VAL = aud_reg_val;
- DGOCS1A_VAL = aud_reg_val;
- //info("%s : DGOCS01A_VAL=0x%x", __func__, (unsigned int)aud_reg_val);
-#endif
-
- DACCFG_VAL = cfg_tbl[smp_rate_index];
-
- auto_pll_divisor(DEV_I2S, CLK_ENABLE , 0, 0);
- auto_pll_divisor(DEV_I2S, SET_PLLDIV, 1, sysclk_tbl[smp_rate_index]);
- /*clock = auto_pll_divisor(DEV_I2S, GET_FREQ , 0, 0);
- info("%s : clock=%d", __func__, clock);*/
-}
-
-static unsigned char aud_smp_rate_convert(unsigned int smp_rate)
-{
- unsigned char i = 0;
- unsigned int smp_rate_tbl[] = {8000, 11025, 12000, 16000, 22050, 24000, 32000,
- 44100, 48000, 64000, 88200, 96000, 128000, 176000, 192000};
-
- DBG_DETAIL();
-
- /* boundary checking */
- if (smp_rate < 8000) {
- i = 0x00;
- }
- else if (smp_rate > 192000) {
- i = 0x0E;
- }
- else {
- for (i = 0; i < 0x1F; i++) {
- if (smp_rate == smp_rate_tbl[i]) {
- break;
- }
- else if (smp_rate < smp_rate_tbl[i + 1]) {
- if (smp_rate < (smp_rate_tbl[i] + ((smp_rate_tbl[i + 1] - smp_rate_tbl[i]) / 2))) {
- break;
- }
- else {
- i++;
- break;
- }
- }
- }
- }
-
- return i;
-
-}
-
-static void i2s_sample_rate(unsigned int rate)
-{
- unsigned char rate_index;
-
- DBG_DETAIL("rate=%d", rate);
-
- if (rate == i2s_data->i2s.rate)
- return;
-
- i2s_data->i2s.rate = rate;
-
- rate_index = aud_smp_rate_convert(rate);
-
- aud_audprf_setting(rate_index);
-
-#ifdef CONFIG_FB_WMT
- /* pass information of audio to HDMI Audio */
- hd_audio_flag = vpp_set_audio(16, rate, 2);
-#endif
-}
-
-static int i2sdacdat_gpio = -1;//means don't touch GP10 bit0-3 i2sDacDat0-3
-
-void wmt_set_i2s_share_pin(void)
-{
- int pwren_num,active_level,gpio_int_num;
- char buf[256];
- int varlen = 256;
- static int gpio26_mux = -1;
- unsigned int gpval = 0x0;
-
- if(gpio26_mux == -1){
- if(wmt_getsyspara("wmt.bt.mtk6622",buf,&varlen) == 0)
- {
- sscanf(buf,"%d:%d:%d",&pwren_num,&active_level,&gpio_int_num);
- printk("use customized value:p%d,a%d,i%d\n",pwren_num,active_level,gpio_int_num);
- if(pwren_num == 62){
- gpio26_mux = 0x01;
- }else{
- gpio26_mux = 0x00;
- }
-
- }else{
- gpio26_mux = 0x00;
- }
- }
- printk("%s gpio26_mux:%d\n",__func__,gpio26_mux);
- if(!gpio26_mux){
- /* disable GPIO and enable Pull Down mode */
- gpval &= ~0xff;
- //GPIO_CTRL_GP10_I2S_BYTE_VAL &= ~0xFF; // 0xFF bit1
- }else{
- gpval &= ~0xF7;
- //GPIO_CTRL_GP10_I2S_BYTE_VAL &= ~0xF7;
- }
-
- // configure I2SDACDAT1/2/3 as GPIO function but mmax-wm8994 that configured as I2SADCLRC/I2SADCBLCK
- if (!wmt_codec_wm8994)
- {
- gpval |= (BIT1 | BIT2 | BIT3);
- //GPIO_CTRL_GP10_I2S_BYTE_VAL |= (BIT1 | BIT2 | BIT3);
-
- }
-
- //add for mainly i2sdacdat1 work as gpio to control led 2014-8-15 so here just keep it specific func
- //tp driver will use it as gpio
- switch (i2sdacdat_gpio)
- {
- case 1:
- gpval |= BIT1;
- //GPIO_CTRL_GP10_I2S_BYTE_VAL |= BIT1; // i2sdacdat1 work as gpio
- break;
- case 2:
- gpval |= BIT2;
- //GPIO_CTRL_GP10_I2S_BYTE_VAL |= BIT2;
- break;
- case 3:
- gpval |= BIT3;
- //GPIO_CTRL_GP10_I2S_BYTE_VAL |= BIT3;
- break;
-
- }
- GPIO_CTRL_GP10_I2S_BYTE_VAL = gpval;
-
- GPIO_CTRL_GP11_I2S_BYTE_VAL &= ~(BIT0 | BIT1 | BIT2);
-
- if(!gpio26_mux){
- PULL_EN_GP10_I2S_BYTE_VAL |= 0xFF;
- }else{
- PULL_EN_GP10_I2S_BYTE_VAL |= 0xF7;
- }
- PULL_EN_GP11_I2S_BYTE_VAL |= (BIT0 | BIT1 | BIT2);
-
- if(!gpio26_mux){
- /* set to 2ch input, 2ch output */
- PIN_SHARING_SEL_4BYTE_VAL &= ~(BIT15 | BIT17 | BIT19 | BIT20);
- PIN_SHARING_SEL_4BYTE_VAL |= (BIT1 | BIT16 | BIT18);
- }else{
- PIN_SHARING_SEL_4BYTE_VAL &= ~(BIT15 | BIT17 | BIT20);
- PIN_SHARING_SEL_4BYTE_VAL |= (BIT1 | BIT16);
- }
-}
-EXPORT_SYMBOL(wmt_set_i2s_share_pin);
-
-static void i2s_init(int mode)
-{
-#ifdef DEBUG
- int ret;
-#endif
- int temp ;
- //unsigned int clock = 0;
-
- DPRINTK("i2s_ref = %d ", i2s_data->i2s.ref);
-
- if (++i2s_data->i2s.ref > 1)
- return;
-
- DBG_DETAIL();
-
- if (!mode) {
- /* set to 24.576MHz */
- auto_pll_divisor(DEV_I2S, CLK_ENABLE , 0, 0);
- auto_pll_divisor(DEV_I2S, SET_PLLDIV, 1, 24576);
- /*clock = auto_pll_divisor(DEV_I2S, GET_FREQ , 0, 0);
- info("%s : clock=%d \n" , __func__, clock);*/
-
- /* Enable BIT4:ARFP clock, BIT3:ARF clock */
- PMCEU_VAL |= (BIT4 | BIT3);
-
- /* Enable BIT2:AUD clock */
- PMCE3_VAL |= BIT2;
-
- wmt_set_i2s_share_pin();
- }
-
- /* connect DZDRQ8 to ADC0 FIFO, DZDRQ9 to DAC FIFO and DZDRQA to ADC1 FIFO */
- DZDRQ8_CFG_VAL = 0x0;
- DZDRQ9_CFG_VAL = 0x1;
- DZDRQA_CFG_VAL = 0x2;
-
- DACCFG_VAL = 0x0;
- ADCCFG_VAL = 0x0;
-
- /* little endian, signed format, enable sample FIFO, 16bit sample, 2 channel */
- ASMPFCFG_VAL = 0x52;
-
- /* assign ch0 to DAC#0_L, DAC#1_L, DAC#2_L, SPDIF_L,
- ch1 to DAC#0_R, DAC#1_R, DAC#2_R, SPDIF_R */
- ASMPFCHCFG0_VAL = 0x10101010;
-
- /* assign ch0 to DAC#3_L, ch1 to DAC#3_R */
- ASMPFCHCFG1_VAL = 0x10;
-
- /* select ADCDAT0, 16 bits mode, enable AADCFIFO and AADCITF */
- AADCF0CFG_VAL = (AADCITF_ENABLE | AADCF16_ENABLE | AADCF_ENABLE);
-
- /* the sequence must be ARF_ADCCFG first then ARF_DGOCFG, finally ARF_DACCFG while slave mode,
- otherwise will generate noise when record function is active */
-
- /* ADC slave mode, 48K sample rate, I2S mode */
- ADCCFG_VAL = 0x2001;
-
- i2s_data->i2s.rate = 48000;
- i2s_data->i2s.channels = 2;
- i2s_data->i2s.format = SNDRV_PCM_FORMAT_S16_LE;
-
-#ifdef AUD_SPDIF_ENABLE
- /* B1: 0 -> PCM, 1 -> Bitstream
- B24 ~ B27: sample rate */
- /* set ADGO channel status for 48K sample rate */
- DGOCS0A_VAL = 0x02 << 24;
- DGOCS1A_VAL = 0x02 << 24;
-
- /* enable ADGOITF and ADGOCKGEN for 48K sample rate */
- DGOCFG_VAL = 0x82;
-#endif
-
- /* enable ADACITF and ADACCKGEN for 44.1K sample rate, I2S mode */
- DACCFG_VAL = 0x402001;
- if (audio_interface_mode == 1)
- {
- printk("<<<<<%s left justified!\n", __func__);
- //left justified bit20: 0->i2s, 1->l/r clock polarity
- DACCFG_VAL |= 0x1 << 20;
- //bit7:0 padding added to dac serial data output
- //0 = LJ
- //1 = I2S
- //others = RJ (depends on Bit 11:8)
-
- DACCFG_VAL &= ~(0x1<<0);
-
- }
-
- /* enable HD Audio clock for 48K sample rate or not*/
- HDACKGEN_VAL = 0x12;
-
-#ifdef CONFIG_FB_WMT
- /* pass information of audio to HDMI Audio */
- hd_audio_flag = vpp_set_audio(16, i2s_data->i2s.rate, i2s_data->i2s.channels);
- ASMPF2HDACHCFG_VAL = 0x76543210;
-#endif
-
- if (!hd_audio_flag)
- HDACKGEN_VAL = 0;
-
- /* audio peri reset */
- temp = AUDPRFRST_VAL;
-
-#ifdef AUD_SPDIF_ENABLE
- temp |= (ASMPF_RESET | DACITF_RESET | ADCITF_RESET | DGOITF_RESET);
-#else
- temp |= (ASMPF_RESET | DACITF_RESET | ADCITF_RESET);
-#endif
-
- AUDPRFRST_VAL = temp;
-
- /*
- request irq
- */
-#ifdef CONFIG_WMT_I2S_INT
- ret = request_irq(i2s_data->i2s.irq,
- wmt_i2s_interrupt,
- SA_INTERRUPT,
- "wmt_alsa_vt1602",
- NULL);
- if (ret)
- printk("%s : unable to request IRQ \n" , __func__);
-#endif
-}
-
-static void i2s_exit(void)
-{
- DBG_DETAIL();
-
- if (--i2s_data->i2s.ref)
- return;
-
- DPRINTK("Do i2s_exit ");
-
-#ifdef CONFIG_WMT_I2S_INT
- free_irq(i2s_data->i2s.irq, NULL);
-#endif
-
- /* Reset counter.*/
- memset(&i2s_data->i2s.ints, 0, sizeof(struct i2s_ints_s));
- return;
-}
-
-static int wmt_i2s_dai_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int stream_id = substream->pstr->stream;
- struct audio_stream_a *s = &i2s_data->s[0];
-
- DBG_DETAIL();
-
- s[stream_id].stream = substream;
-
- runtime->private_data = s;
-
- return 0;
-}
-
-static void wmt_i2s_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
-{
- DBG_DETAIL();
-}
-
-static int wmt_i2s_dai_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- int err = 0;
- int stream_id = substream->pstr->stream;
-
- DBG_DETAIL();
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
- ASMPFCFG_VAL |= ASMPF_ENABLE;
- }
- else if (stream_id == SNDRV_PCM_STREAM_CAPTURE) {
- AADCF0CFG_VAL |= AADCF_ENABLE;
- }
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
- ASMPFCFG_VAL &= ~ASMPF_ENABLE;
- }
- else if (stream_id == SNDRV_PCM_STREAM_CAPTURE) {
- AADCF0CFG_VAL &= ~AADCF_ENABLE;
- }
-
- /*
- mod_timer(&i2s_data->delay_timer, jiffies + HZ / 100);
- */
- break;
- default:
- err = -EINVAL;
- }
-
- return err;
-}
-
-static int wmt_i2s_dai_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
-{
- DBG_DETAIL();
- return 0;
-}
-
-static int wmt_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int channel, byte;
- int stream_id = substream->pstr->stream;
-
-#ifdef CONFIG_SND_OSSEMUL
- //info("oss.rate=%d, oss.channels=%d", runtime->oss.rate, runtime->oss.channels);
-#else
- DBG_DETAIL();
-#endif
-
- byte = (runtime->sample_bits)/8;
- channel = runtime->channels;
-
- DPRINTK("snd_wmt_alsa_prepare byte = %d, channels = %d", byte, runtime->channels);
-
-
- if ((runtime->rate != i2s_data->i2s.rate) || (runtime->format != i2s_data->i2s.format) ||
- (runtime->channels != i2s_data->i2s.channels) || (stream_id != i2s_data->stream_id)) {
- info("*** stream_id=%d, rate=%d, format=0x%x channels=%d ***",
- stream_id, runtime->rate, runtime->format, runtime->channels);
- i2s_data->i2s.format = runtime->format;
- i2s_data->i2s.channels = runtime->channels;
- i2s_data->stream_id = stream_id;
- }
- else {
- return 0;
- }
-
- i2s_disable();
-
- /* format setting */
- if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
- /* little or big endian check */
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_S16_BE:
- case SNDRV_PCM_FORMAT_U16_BE:
- case SNDRV_PCM_FORMAT_S24_BE:
- case SNDRV_PCM_FORMAT_U24_BE:
- case SNDRV_PCM_FORMAT_S32_BE:
- case SNDRV_PCM_FORMAT_U32_BE:
- ASMPFCFG_VAL |= ASMPF_EXCH_ENDIAN;
- break;
- default:
- ASMPFCFG_VAL &= ~ASMPF_EXCH_ENDIAN;
- break;
- }
-
- /* unsigned or signed check */
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_U8:
- case SNDRV_PCM_FORMAT_U16_LE:
- case SNDRV_PCM_FORMAT_U16_BE:
- case SNDRV_PCM_FORMAT_U24_LE:
- case SNDRV_PCM_FORMAT_U24_BE:
- case SNDRV_PCM_FORMAT_U32_LE:
- case SNDRV_PCM_FORMAT_U32_BE:
- ASMPFCFG_VAL |= ASMPF_EXCH_FMT;
- break;
- default:
- ASMPFCFG_VAL &= ~ASMPF_EXCH_FMT;
- break;
- }
-
- /* sample quantization check */
- ASMPFCFG_VAL &= ~(BIT4 | BIT5);
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_S8:
- case SNDRV_PCM_FORMAT_U8:
- ASMPFCFG_VAL |= ASMPF_8BIT_SMP;
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- case SNDRV_PCM_FORMAT_S16_BE:
- case SNDRV_PCM_FORMAT_U16_LE:
- case SNDRV_PCM_FORMAT_U16_BE:
- ASMPFCFG_VAL |= ASMPF_16BIT_SMP;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- case SNDRV_PCM_FORMAT_S32_BE:
- case SNDRV_PCM_FORMAT_U32_LE:
- case SNDRV_PCM_FORMAT_U32_BE:
- ASMPFCFG_VAL |= ASMPF_32BIT_SMP;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- case SNDRV_PCM_FORMAT_S24_BE:
- case SNDRV_PCM_FORMAT_U24_LE:
- case SNDRV_PCM_FORMAT_U24_BE:
- info("*** Not Supported: fmt=24Bit ***");
- default:
- break;
- }
-
- /* channel number check */
- ASMPFCFG_VAL &= ~(BIT0 | BIT1 | BIT2 | BIT3);
- ASMPFCFG_VAL |= runtime->channels;
-
- wmt_i2s_ch_config();
- info("Prepare: CHCFG0=0x%x, HDACHCFG=0x%x", ASMPFCHCFG0_VAL, ASMPF2HDACHCFG_VAL);
- }
-
- /* sample rate setting */
-#ifdef CONFIG_SND_OSSEMUL
- if (runtime->oss.rate) {
- i2s_sample_rate(runtime->oss.rate);
- }
- else {
- i2s_sample_rate(runtime->rate);
- }
-#else
- i2s_sample_rate(runtime->rate);
-#endif
-
- i2s_enable();
-
- /*
- printk("avail_max=%d, rate=%d, channels=%d, period_size=%d, periods=%d, buffer_size=%d, tick_time=%d, \
- min_align=%d, byte_align=%d, frame_bits=%d, sample_bits=%d, sleep_min=%d, xfer_align=%d, boundary=%d\n",
- runtime->avail_max, runtime->rate, runtime->channels, runtime->period_size, runtime->periods,
- runtime->buffer_size, runtime->tick_time, runtime->min_align, runtime->byte_align,
- runtime->frame_bits, runtime->sample_bits,
- runtime->sleep_min, runtime->xfer_align, runtime->boundary);
- */
- return 0;
-}
-
-/*
- * This must be called before _set_clkdiv and _set_sysclk since McBSP register
- * cache is initialized here
- */
-static int wmt_i2s_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
- unsigned int fmt)
-{
- DBG_DETAIL();
- return 0; //add rambo 2013-3-13
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
- break;
- default:
- /* Unsupported data format */
- return -EINVAL;
- }
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- break;
- default:
- return -EINVAL;
- }
-
- /* Set bit clock (CLKX/CLKR) and FS polarities */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- /*
- * Normal BCLK + FS.
- * FS active low. TX data driven on falling edge of bit clock
- * and RX data sampled on rising edge of bit clock.
- */
- break;
- case SND_SOC_DAIFMT_NB_IF:
- break;
- case SND_SOC_DAIFMT_IB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int wmt_i2s_suspend(struct snd_soc_dai *cpu_dai)
-{
- printk("%s!\n", __func__);
-
- DBG_DETAIL();
-
- i2s_data->i2s.ref = 0;
-#if 1
- if (gpio_pa >= 0)
- {
- gpio_direction_output(gpio_pa, !gpio_active);
- }
-#endif
- return 0;
-}
-
-static int wmt_i2s_resume(struct snd_soc_dai *cpu_dai)
-{
- printk("%s!\n", __func__);
-
- DBG_DETAIL();
-
- i2s_init(1);
-
- wmt_i2s_ch_config();
-#if 1
- if (gpio_pa >= 0)
- {
- gpio_direction_output(gpio_pa, gpio_active);
- mdelay(50);
- }
-#endif
- info("Resume: CHCFG0=0x%x, HDACHCFG=0x%x", ASMPFCHCFG0_VAL, ASMPF2HDACHCFG_VAL);
- return 0;
-}
-#else
-#define wmt_i2s_suspend NULL
-#define wmt_i2s_resume NULL
-#endif
-
-static struct snd_soc_dai_ops wmt_i2s_dai_ops = {
- .startup = wmt_i2s_dai_startup,
- .prepare = wmt_i2s_prepare,
- .shutdown = wmt_i2s_dai_shutdown,
- .trigger = wmt_i2s_dai_trigger,
- .hw_params = wmt_i2s_dai_hw_params,
- .set_fmt = wmt_i2s_dai_set_dai_fmt,
-};
-
-struct snd_soc_dai_driver wmt_i2s_dai = {
- .suspend = wmt_i2s_suspend,
- .resume = wmt_i2s_resume,
- .playback = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_FLOAT,
- },
- .capture = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .ops = &wmt_i2s_dai_ops,
-};
-
-static int wmt_i2s_probe(struct platform_device *pdev)
-{
- int ret;
- char buf[64];
- int varlen = 64;
-
- DBG_DETAIL();
-
- ret = wmt_getsyspara("wmt.audio.pcm", buf, &varlen);
- if (ret == 0) {
- sscanf(buf, "%d", &wmt_pdm_module_enable);
- }
-
- ret = wmt_getsyspara("wmt.audio.i2s", buf, &varlen);
- if (ret == 0) {
- if (!strncmp(buf, "wm8994", strlen("wm8994")))
- wmt_codec_wm8994 = 1;
- }
- memset(buf, 0, sizeof(buf));
- ret = wmt_getsyspara("wmt.audio.codechdmi", buf, &varlen);
- if (ret == 0) {
- sscanf(buf, "%d", &i2s_data[0].HDMI_and_DAC0);
- printk("<<<%s codec and hdmi:%d\n", __FUNCTION__, i2s_data[0].HDMI_and_DAC0);
- }
-
- memset(buf, 0, sizeof(buf));
- //0:i2sdacdat0(usually use i2s function!!) 1:i2sdacdat1 2:i2sdacdat2 3:i2sdacdat3
- ret = wmt_getsyspara("wmt.audio.dacdat.gpio", buf, &varlen);
- if (ret == 0) {
- sscanf(buf, "%d", &i2sdacdat_gpio);
- printk("<<<%s i2sdacdat_gpio:%d\n", __FUNCTION__, i2sdacdat_gpio);
- }
-
-
- memset(buf, 0, sizeof(buf));
- ret = wmt_getsyspara("wmt.audio.interface.mode", buf, &varlen);
- if (ret == 0) { // 0:i2s 1:left justified 2:right justified
- sscanf(buf, "%d", &audio_interface_mode);
- printk("<<<%s audio_interface_mode:%d\n", __FUNCTION__, audio_interface_mode);
- }
-
- memset(buf, 0, sizeof(buf));
- ret = wmt_getsyspara("wmt.audio.pa", buf, &varlen);
- if (ret == 0) { // gpio nr:active---> 1:0
- sscanf(buf, "%d:%d", &gpio_pa, &gpio_active);
-
- }
- printk("%s audio pa:%d:%d\n", __FUNCTION__, gpio_pa, gpio_active);
- if (gpio_pa >= 0)
- {
- ret = gpio_request(gpio_pa, "audio pa");
- if (ret)
- {
- printk("%s gpio %d request error!\n", __func__, gpio_pa);
- return ret;
- }
- #if 0
- if (gpio_active)
- wmt_gpio_setpull(gpio_pa, WMT_GPIO_PULL_DOWN);
- else
- wmt_gpio_setpull(gpio_pa, WMT_GPIO_PULL_UP);
- msleep(10);
- gpio_direction_output(gpio_pa, !gpio_active); //???pop???
- printk("%s shutdown pa!\n", __func__);
- msleep(100);
- #endif
-
-
- init_timer(&pa_timer);
- pa_timer.function = pa_timer_handler;
- }
- i2s_data->s[0].dma_cfg = dma_device_cfg_table[AHB1_AUD_DMA_REQ_1];
- i2s_data->s[1].dma_cfg = dma_device_cfg_table[AHB1_AUD_DMA_REQ_0];
- /*init i2s controller*/
- i2s_data->i2s.init(0);
-
- spin_lock_init(&i2s_data->s[0].dma_lock);
- spin_lock_init(&i2s_data->s[1].dma_lock);
- /*init_timer(&i2s_data->delay_timer);
- i2s_data->delay_timer.function = delay_timer_handler;*/
-
- /* register with the ASoC layers */
- ret = snd_soc_register_dai(&pdev->dev, &wmt_i2s_dai);
- if (ret) {
- pr_err("Failed to register DAI: %d\n", ret);
- return ret;
- }
-
- if (gpio_pa >= 0)
- {
- mod_timer(&pa_timer, jiffies+msecs_to_jiffies(10000));
- }
- return 0;
-}
-
-static int __devexit wmt_i2s_remove(struct platform_device *pdev)
-{
- DBG_DETAIL();
-
- snd_soc_unregister_dai(&pdev->dev);
-
- return 0;
-}
-
-static void wmt_i2s_plat_shutdown(struct platform_device *pdev)
-{
- printk("%s!\n", __func__);
- if (gpio_pa >= 0)
- {
- gpio_direction_output(gpio_pa, !gpio_active);
- }
-}
-
-static struct platform_driver wmt_i2s_driver = {
- .probe = wmt_i2s_probe,
- .remove = __devexit_p(wmt_i2s_remove),
- //.suspend = wmt_i2s_plat_suspend,
- //.resume = wmt_i2s_plat_resume,
- .shutdown = wmt_i2s_plat_shutdown,
- .driver = {
- .name = "wmt-i2s",
- .owner = THIS_MODULE,
- },
-};
-
-
-static int __init wmt_i2s_init(void)
-{
- DBG_DETAIL();
-
- return platform_driver_register(&wmt_i2s_driver);
-}
-
-static void __exit wmt_i2s_exit(void)
-{
- DBG_DETAIL();
-
- platform_driver_unregister(&wmt_i2s_driver);
-}
-
-module_init(wmt_i2s_init);
-module_exit(wmt_i2s_exit);
-
-MODULE_AUTHOR("WonderMedia Technologies, Inc.");
-MODULE_DESCRIPTION("WMT [ALSA SoC] driver");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-controller.c b/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-controller.c
deleted file mode 100755
index dccb82c6..00000000
--- a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-controller.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/*++
- * linux/sound/soc/wmt/wmt-pdm-if.c
- * WonderMedia I2S audio driver for ALSA
- *
- * Copyright c 2010 WonderMedia Technologies, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * WonderMedia Technologies, Inc.
- * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
---*/
-
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <asm/irq.h>
-#include <linux/delay.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include <mach/hardware.h>
-#include <asm/dma.h>
-#include "wmt-soc.h"
-#include "wmt-pcm-controller.h"
-
-#define PCM_IS_MASTER_MODE
-#define NULL_DMA ((dmach_t)(-1))
-
-static int wmt_pcm_module_enable = 0;
-extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
-
-static struct audio_stream_a wmt_pcm_controller_data[] = {
- {
- .id = "WMT PCM out",
- .stream_id = SNDRV_PCM_STREAM_PLAYBACK,
- .dmach = NULL_DMA,
- .dma_dev = PCM_TX_DMA_REQ,
- /*.dma_cfg = dma_device_cfg_table[I2S_TX_DMA_REQ],*/
- },
- {
- .id = "WMT PCM in",
- .stream_id = SNDRV_PCM_STREAM_CAPTURE,
- .dmach = NULL_DMA,
- .dma_dev = PCM_RX_DMA_REQ,
- /*.dma_cfg = dma_device_cfg_table[I2S_RX_DMA_REQ],*/
- },
-};
-
-struct wmt_pcm_controller
-{
- int irq_no;
- int pcm_clk_src;
- int pcm_enable;
-};
-
-static struct wmt_pcm_controller wmt_pcm_controller;
-
-static irqreturn_t
-wmt_pcm_controller_irq_handler(int irq, void *dev_id)
-{
- if (PCMSR_VAL & PCMSR_TXUND) {
- printk("-->PCMSR_TXUND\n");
- }
- else if (PCMSR_VAL & PCMSR_RXOVR) {
- printk("-->PCMSR_RXOVR\n");
- }
-
- PCMSR_VAL = 0x7F; //write clear all intr
- return IRQ_HANDLED;
-}
-
-static void wmt_pcm_controller_enable(void)
-{
- PCMCR_VAL |= (PCMCR_PCM_ENABLE | PCMCR_DMA_EN);
-}
-
-static void wmt_pcm_controller_disable(void)
-{
- PCMCR_VAL &= ~(PCMCR_PCM_ENABLE | PCMCR_DMA_EN);
-}
-
-static int wmt_pcm_controller_init(void)
-{
- wmt_pcm_controller.irq_no = IRQ_PCM;
-
- // Before control pcm-module, enable pcm clock first
- CLOCKEN(27);
-
- // set pcm_clk_source = 62464khz
- //auto_pll_divisor(DEV_PCM0, CLK_ENABLE, 0, 0);
- //auto_pll_divisor(DEV_PCM0, SET_PLLDIV, 1, 83333);
-
- wmt_pcm_controller.pcm_clk_src = auto_pll_divisor(DEV_PCM0, GET_FREQ, 0, 0);
- wmt_pcm_controller.pcm_clk_src /= 1000;
- wmt_pcm_controller.pcm_enable = 0;
- printk("wmt_pcm_controller_init: pcm_clk_src=%d \n\r", wmt_pcm_controller.pcm_clk_src);
-
- // Note: you should config PIN_SHARING_SEL_4BYTE_VAL if using pcm function!!! Loon mark at 2013/4/10
- if (wmt_pcm_module_enable) {
- printk("begin to configure pcm pin\n");
- /* disable GPIO and Pull Down mode */
- /* Bit1:I2SDACDAT1=PCMSYNC, Bit2:I2SDACDAT2=PCMCLK, Bit3:I2SDACDAT3=PCMIN, Bit4:I2SADCMCLK=PCMOUT */
- GPIO_CTRL_GP10_I2S_BYTE_VAL &= ~(BIT1 | BIT2 | BIT3 | BIT4);
- GPIO_CTRL_GP11_I2S_BYTE_VAL &= ~(BIT1);
- /*disable pull enable*/
- PULL_EN_GP10_I2S_BYTE_VAL &= ~(BIT1 | BIT2 | BIT3 | BIT4);
- PULL_EN_GP11_I2S_BYTE_VAL &= ~(BIT1);
-
- /* set to pcm mode */
- // select PCMMCLK[bit0], PCMSYNC[bit17:16], PCMCLK[19:18], PCMIN[20], PCMOUT[22:21]
- //GPIO_PIN_SHARING_SEL_4BYTE_VAL &= ~(BIT21);
- GPIO_PIN_SHARING_SEL_4BYTE_VAL |= (BIT15 | BIT16 | BIT17 | BIT18 | BIT19 |BIT20);
- }
-
- // set pcm control register
- PCMCR_VAL |= (PCMCR_TXFF_RST | PCMCR_RXFF_RST);
- //PCMCR_VAL |= 0x00880000; // TX/RX Fifo Threshold A
- PCMCR_VAL &= ~(PCMCR_BCLK_SEL);
- PCMCR_VAL &= ~PCMCR_SLAVE; // master mode
- PCMCR_VAL |= PCMCR_SYNC_MODE;//short frame sync
-
- // set pcm format register
- PCMDFCR_VAL = 0;
- PCMDFCR_VAL |= (PCMDFCR_WR_AL | PCMDFCR_TX_AL | PCMDFCR_RX_AL | PCMDFCR_RD_AL);
- PCMDFCR_VAL |= (PCMDFCR_TX_SZ_14 | PCMDFCR_RX_SZ_14);
- //PCMDFCR_VAL |= (PCMDFCR_TX_SZ_08 | PCMDFCR_RX_SZ_08);
-
- //
- // request irq
- //
- /*if (request_irq(wmt_pcm_controller.irq_no, &wmt_pcm_controller_irq_handler, IRQF_DISABLED, "wmt_pcm_controller", NULL)){
- printk(KERN_ERR "PCM_IRQ Request Failed!\n");
- }
- PCMCR_VAL |= (PCMCR_IRQ_EN | PCMCR_TXUND_EN | PCMCR_RXOVR_EN);
- */
- printk("fun:%s,line:%d\n",__func__,__LINE__);
- return 0 ;
-}
-
-
-static int wmt_pcm_controller_dai_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int stream_id = substream->pstr->stream;
- struct audio_stream_a *s = &wmt_pcm_controller_data[0];
- //dump_stack();
- s[stream_id].stream = substream;
- runtime->private_data = s;
-
- return 0;
-}
-
-static void wmt_pcm_controller_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
-{
- //dump_stack();
-}
-
-static int wmt_pcm_controller_dai_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- int err = 0;
- int stream_id = substream->pstr->stream;
- //dump_stack();
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
- PCMCR_VAL |= PCMCR_TXFF_RST; // reset txfifo
- PCMDFCR_VAL |= PCMDFCR_TXFM_EN;
- }
- else if (stream_id == SNDRV_PCM_STREAM_CAPTURE) {
- PCMCR_VAL |= PCMCR_RXFF_RST; // reset rxfifo
- PCMDFCR_VAL |= PCMDFCR_RXFM_EN;
- }
- //wmt_pcm_controller_enable();
- wmt_pcm_controller.pcm_enable++;
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
- PCMDFCR_VAL &= ~PCMDFCR_TXFM_EN;
- }
- else if (stream_id == SNDRV_PCM_STREAM_CAPTURE) {
- PCMDFCR_VAL &= ~PCMDFCR_RXFM_EN;
- }
- //wmt_pcm_controller_disable();
- wmt_pcm_controller.pcm_enable--;
- break;
- default:
- err = -EINVAL;
- break;
- }
-
- if (wmt_pcm_controller.pcm_enable)
- wmt_pcm_controller_enable();
- else
- wmt_pcm_controller_disable();
-
- return err;
-}
-
-static int wmt_pcm_controller_dai_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
-{
- //dump_stack();
- return 0;
-}
-
-static int wmt_pcm_controller_dai_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int channel, byte;
- int stream_id = substream->pstr->stream;
-
- byte = (runtime->sample_bits)/8;
- channel = runtime->channels;
-
- printk(KERN_INFO "wmt_pcm_controller_dai_prepare byte = %d, channels = %d\n", byte, runtime->channels);
-
- /* format setting */
- if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
- /* little or big endian check */
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- default:
- break;
- }
-
- /* channel number check */
- switch (runtime->channels) {
- case 1:
- break;
- case 2:
- break;
- default:
- break;
- }
- }
- else if (stream_id == SNDRV_PCM_STREAM_CAPTURE) {
- /* little or big endian check */
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- default:
- break;
- }
-
- /* channel number check */
- switch (runtime->channels) {
- case 1:
- break;
- case 2:
- break;
- default:
- break;
- }
- }
-
- switch (runtime->rate) {
- case 16000:
- PCMDIVR_VAL &= ~PCMCLK_DIV_MASK;
- PCMDIVR_VAL |= (wmt_pcm_controller.pcm_clk_src / PCMCLK_256K);
- break;
- case 8000:
- PCMDIVR_VAL &= ~PCMCLK_DIV_MASK;
- PCMDIVR_VAL |= (wmt_pcm_controller.pcm_clk_src / PCMCLK_128K);
- break;
- default :
- printk(KERN_ERR "not supported fs: %d \n\r", runtime->rate);
- break;
- }
-
- return 0;
-}
-
-/*
- * This must be called before _set_clkdiv and _set_sysclk since McBSP register
- * cache is initialized here
- */
-static int wmt_pcm_controller_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
- unsigned int fmt)
-{
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int wmt_pcm_controller_suspend(struct snd_soc_dai *cpu_dai)
-{
- return 0;
-}
-
-static int wmt_pcm_controller_resume(struct snd_soc_dai *cpu_dai)
-{
- int ret = wmt_pcm_controller_init();
- if (ret) {
- pr_err("Failed to init pcm module: %d\n", ret);
- return ret;
- }
- return 0;
-}
-#else
-#define wmt_pcm_controller_suspend NULL
-#define wmt_pcm_controller_resume NULL
-#endif
-
-static struct snd_soc_dai_ops wmt_pcm_controller_dai_ops = {
- .startup = wmt_pcm_controller_dai_startup,
- .prepare = wmt_pcm_controller_dai_prepare,
- .shutdown = wmt_pcm_controller_dai_shutdown,
- .trigger = wmt_pcm_controller_dai_trigger,
- .hw_params = wmt_pcm_controller_dai_hw_params,
- .set_fmt = wmt_pcm_controller_dai_set_dai_fmt,
-};
-
-struct snd_soc_dai_driver wmt_pcm_controller_dai = {
- .suspend = wmt_pcm_controller_suspend,
- .resume = wmt_pcm_controller_resume,
- .playback = {
- .channels_min = 1,
- .channels_max = 1,
- .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .capture = {
- .channels_min = 1,
- .channels_max = 1,
- .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .ops = &wmt_pcm_controller_dai_ops,
-};
-
-static int wmt_pcm_controller_probe(struct platform_device *pdev)
-{
- int ret = 0;
- char buf[64];
- int varlen = 64;
-
- ret = wmt_getsyspara("wmt.audio.pcm", buf, &varlen);
- if (ret == 0) {
- sscanf(buf, "%d", &wmt_pcm_module_enable);
- }
-
- ret = wmt_pcm_controller_init();
- if (ret) {
- pr_err("Failed to init pcm module: %d\n", ret);
- return ret;
- }
-
- /* register with the ASoC layers */
- ret = snd_soc_register_dai(&pdev->dev, &wmt_pcm_controller_dai);
- if (ret) {
- pr_err("Failed to register DAI: %d\n", ret);
- return ret;
- }
-
- wmt_pcm_controller_data[0].dma_cfg = dma_device_cfg_table[PCM_TX_DMA_REQ];
- wmt_pcm_controller_data[1].dma_cfg = dma_device_cfg_table[PCM_RX_DMA_REQ];
-
- spin_lock_init(&wmt_pcm_controller_data[0].dma_lock);
- spin_lock_init(&wmt_pcm_controller_data[1].dma_lock);
-
- return 0;
-}
-
-static int __devexit wmt_pcm_controller_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_dai(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver wmt_pcm_controller_driver = {
- .probe = wmt_pcm_controller_probe,
- .remove = __devexit_p(wmt_pcm_controller_remove),
- .driver = {
- .name = "wmt-pcm-controller",
- .owner = THIS_MODULE,
- },
-};
-
-
-static int __init wmt_pcm_controller_module_init(void)
-{
- return platform_driver_register(&wmt_pcm_controller_driver);
-}
-
-static void __exit wmt_pcm_controller_module_exit(void)
-{
- platform_driver_unregister(&wmt_pcm_controller_driver);
-}
-
-module_init(wmt_pcm_controller_module_init);
-module_exit(wmt_pcm_controller_module_exit);
-
-MODULE_AUTHOR("WonderMedia Technologies, Inc.");
-MODULE_DESCRIPTION("WMT [ALSA SoC] driver");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-controller.h b/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-controller.h
deleted file mode 100755
index 58e94f23..00000000
--- a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-controller.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*++
-linux/include/asm-arm/arch-wmt/wmt_pcm.h
-
-Copyright (c) 2008 WonderMedia Technologies, Inc.
-
-This program is free software: you can redistribute it and/or modify it under the
-terms of the GNU General Public License as published by the Free Software Foundation,
-either version 2 of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-PARTICULAR PURPOSE. See the GNU General Public License for more details.
-You should have received a copy of the GNU General Public License along with
-this program. If not, see <http://www.gnu.org/licenses/>.
-
-WonderMedia Technologies, Inc.
-10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
---*/
-
-/* Be sure that virtual mapping is defined right */
-
-#ifndef __WMT_PCM_CONTROLLER_H
-#define __WMT_PCM_CONTROLLER_H
-
-/*
- * Address
- */
-#define PCM_CR_ADDR (0x0000+PCM_BASE_ADDR)
-#define PCM_SR_ADDR (0x0004+PCM_BASE_ADDR)
-/* Reserved 0x0008 ~ 0x000F */
-#define PCM_DFCR_ADDR (0x0008+PCM_BASE_ADDR)
-#define PCM_DIVR_ADDR (0x000C+PCM_BASE_ADDR)
-/* Reserved 0x0020 ~ 0x007F */
-#define PCM_TFIFO_ADDR (0x0010+PCM_BASE_ADDR)
-#define PCM_TFIFO_1_ADDR (0x0014+PCM_BASE_ADDR)
-
-#define PCM_RFIFO_ADDR (0x0030+PCM_BASE_ADDR)
-#define PCM_RFIFO_1_ADDR (0x0034+PCM_BASE_ADDR)
-/* Reserved 0x0100 ~ 0xFFFF */
-
-/*
- * Value
- */
-#define PCMCR_VAL (REG32_VAL(PCM_CR_ADDR))
-#define PCMSR_VAL (REG32_VAL(PCM_SR_ADDR))
-#define PCMDFCR_VAL (REG32_VAL(PCM_DFCR_ADDR))
-#define PCMDIVR_VAL (REG32_VAL(PCM_DIVR_ADDR))
-#define GPIO_PIN_SHARING_SEL_4BYTE_VAL (REG32_VAL(SHARE_PIN_SELEC))
-
-#define PCMCLK_DIV_MASK 0x7FF
-#define PLL_B_DIVF_MASK 0xFF0000
-#define PLL_B_DIVR_MASK 0x1F00
-#define PLL_B_DIVQ_MASK 0x07
-#define OSC_25M 25000
-#define PCMCLK_128K 128
-#define PCMCLK_256K 256
-
-
-//=============================================================================
-//
-// PCMCR PCM Control Register
-//
-//=============================================================================
-#define PCMCR_PCM_ENABLE (BIT0) /* PCM Interface Enable */
-#define PCMCR_SLAVE (BIT1) /* Master/Slave Mode */
-
-#define PCMCR_BCLK_SEL (BIT3) /* PCM_CLK Select */
-#define PCMCR_SYNC_MODE (BIT4) /* Frame Sync Mode: 0-long, 1-Short */
-#define PCMCR_DMA_EN (BIT5) /* DMA Enable */
-#define PCMCR_SYNC_OFF (BIT6) /* Sync Disable */
-#define PCMCR_MUTE (BIT7) /* Mute Enable */
-#define PCMCR_IRQ_EN (BIT8) /* Interrupt Enable */
-#define PCMCR_DMA_IRQ_SEL (BIT9) /* Threshold DMA/IRQ Select */
-#define PCMCR_RXFE_EN (BIT10) /* RX FIFO Empty Interrupt Enable */
-#define PCMCR_RXFF_EN (BIT11) /* RX FIFO Full Interrupt Enable */
-#define PCMCR_RXOVR_EN (BIT12) /* RX FIFO Overrun Interrupt Enable */
-#define PCMCR_TXFE_EN (BIT13) /* TX FIFO Empty Interrupt Enable */
-#define PCMCR_TXUND_EN (BIT14) /* TX FIFO Underrun Interrupt Enable */
-
-#define PCMCR_TXFF_RST (BIT24) /* TX FIFO Reset */
-#define PCMCR_RXFF_RST (BIT25) /* RX FIFO Reset */
-
-
-//=============================================================================
-//
-// PCMSR PCM Status Register
-//
-//=============================================================================
-#define PCMSR_RXFE (BIT0) /* RX FIFO Empty Status */
-#define PCMSR_RXFF (BIT1) /* RX FIFO Full Status */
-#define PCMSR_RXOVR (BIT2) /* RX FIFO Overrun Status */
-#define PCMSR_TXFE (BIT3) /* TX FIFO Empty Status */
-#define PCMSR_TXUND (BIT4) /* TX FIFO Underrun Status */
-#define PCMSR_TXFAE (BIT5) /* TX FIFO Almost Empty Status */
-#define PCMSR_RXFAF (BIT6) /* RX FIFO Almost Full Status */
-
-
-//=============================================================================
-//
-// PCMDFCR PCM Data Format Control Register
-//
-//=============================================================================
-#define PCMDFCR_TXFM_EN (BIT0) /* TX Data Format Enable */
-#define PCMDFCR_TX_SZ_13 0x00 /* TX Input Data Size 13 bits wide */
-#define PCMDFCR_TX_SZ_14 0x02 /* TX Input Data Size 14 bits wide */
-#define PCMDFCR_TX_SZ_08 0x04 /* TX Input Data Size 8 bits wide */
-#define PCMDFCR_WR_AL (BIT3) /* TX Write Data Alignment Setup */
-#define PCMDFCR_TX_AL (BIT4) /* PCM_OUT Alignment Control */
-#define PCMDFCR_TX_PAD (BIT5) /* PCM_OUT Padding Control */
-#define PCMDFCR_TX_MSB (BIT6) /* PCM_OUT First Bit Select */
-
-#define PCMDFCR_RXFM_EN (BIT8) /* RX Data Format Enable */
-#define PCMDFCR_RX_SZ_13 0x0000 /* RCM_IN Data Size 13 bits wide */
-#define PCMDFCR_RX_SZ_14 0x0200 /* RCM_IN Data Size 14 bits wide */
-#define PCMDFCR_RX_SZ_08 0x0400 /* RCM_IN Data Size 8 bits wide */
-#define PCMDFCR_RX_AL (BIT11) /* RCM_IN Data Alignment Setup */
-#define PCMDFCR_RD_AL (BIT12) /* PX FIFO Alignment Control */
-#define PCMDFCR_RX_PAD (BIT13) /* PX FIFO Padding Control */
-#define PCMDFCR_RX_MSB (BIT14) /* RX FIFO First Bit Select */
-
-
-#endif /* __WMT_PCM_CONTROLLER_H */
diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-dma.c b/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-dma.c
deleted file mode 100755
index 27a66bea..00000000
--- a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-dma.c
+++ /dev/null
@@ -1,597 +0,0 @@
-/*++
- * linux/sound/soc/wmt/wmt-pcm.c
- * WonderMedia audio driver for ALSA
- *
- * Copyright c 2010 WonderMedia Technologies, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * WonderMedia Technologies, Inc.
- * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
---*/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-
-#include <linux/dma-mapping.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <linux/delay.h>
-
-#include <asm/dma.h>
-#include "wmt-pcm-dma.h"
-#include "wmt-soc.h"
-
-#define NULL_DMA ((dmach_t)(-1))
-
-/*
- * Debug
- */
-#define AUDIO_NAME "WMT_PCM_DMA"
-//#define WMT_PCM_DEBUG 1
-//#define WMT_PCM_DEBUG_DETAIL 1
-
-#ifdef WMT_PCM_DEBUG
-#define DPRINTK(format, arg...) \
- printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
-#else
-#define DPRINTK(format, arg...) do {} while (0)
-#endif
-
-#ifdef WMT_PCM_DEBUG_DETAIL
-#define DBG_DETAIL(format, arg...) \
- printk(KERN_INFO AUDIO_NAME ": [%s]" format "\n" , __FUNCTION__, ## arg)
-#else
-#define DBG_DETAIL(format, arg...) do {} while (0)
-#endif
-
-#define err(format, arg...) \
- printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg)
-#define info(format, arg...) \
- printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
-#define warn(format, arg...) \
- printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg)
-
-static const struct snd_pcm_hardware wmt_pcm_dma_hardware = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rate_min = 8000,
- .rate_max = 16000,
- .period_bytes_min = 32,
- .period_bytes_max = 4 * 1024,
- .periods_min = 1,
- .periods_max = 32,
- .buffer_bytes_max = 16 * 1024,
-};
-
-static int audio_dma_free(struct audio_stream_a *s);
-
-/*
- * Main dma routine, requests dma according where you are in main alsa buffer
- */
-static void audio_process_dma(struct audio_stream_a *s)
-{
- struct snd_pcm_substream *substream = s->stream;
- struct snd_pcm_runtime *runtime;
- unsigned int dma_size;
- unsigned int offset;
- dma_addr_t dma_base;
- int ret = 0;
-
- DPRINTK("s: %d, dmach: %d. active: %d", (int)s, s->dmach, s->active);
-
- if (s->active) {
- substream = s->stream;
- runtime = substream->runtime;
- dma_size = frames_to_bytes(runtime, runtime->period_size);
-
- if (dma_size > MAX_DMA_SIZE)
- dma_size = CUT_DMA_SIZE;
- offset = dma_size * s->period;
-
- dma_base = __virt_to_phys((dma_addr_t)runtime->dma_area);
-
- if ((runtime->channels == 2 || runtime->channels == 1) &&
- (runtime->format == SNDRV_PCM_FORMAT_S16_LE)) {
- ret = wmt_start_dma(s->dmach, runtime->dma_addr + offset, 0, dma_size);
- }
-
- if (ret) {
- printk(KERN_ERR "audio_process_dma: cannot queue DMA buffer (%i) \n", ret);
- return;
- }
-
- s->period++;
- s->period %= runtime->periods;
- s->periods++;
- s->offset = offset;
- }
-}
-
-/*
- * This is called when dma IRQ occurs at the end of each transmited block
- */
-static void audio_dma_callback(void *data)
-{
- struct audio_stream_a *s = data;
-
- //DBG_DETAIL();
-
- /*
- * If we are getting a callback for an active stream then we inform
- * the PCM middle layer we've finished a period
- */
- if (s->active)
- snd_pcm_period_elapsed(s->stream);
-
- spin_lock(&s->dma_lock);
- if (s->periods > 0)
- s->periods--;
-
- audio_process_dma(s);
- spin_unlock(&s->dma_lock);
-}
-
-static int audio_dma_request(struct audio_stream_a *s, void (*callback) (void *))
-{
- int err;
- err = 0;
-
- DBG_DETAIL();
-
- //DPRINTK("s pointer: %d, dmach: %d, id: %s, dma_dev: %d", (int)s, s->dmach, s->id, s->dma_dev);
- err = wmt_request_dma(&s->dmach, s->id, s->dma_dev, callback, s);
- if (err < 0)
- printk(KERN_ERR "Unable to grab audio dma 0x%x\n", s->dmach);
-
- return err;
-}
-
-static void audio_setup_dma(struct audio_stream_a *s, int stream_id)
-{
- struct snd_pcm_runtime *runtime = s->stream->runtime;
-
- if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
- /* From memory to device */
- switch (runtime->channels * runtime->format) {
- case 1:
- s->dma_cfg.DefaultCCR = PCM_TX_DMA_8BITS_CFG; /* setup 1 bytes*/
- break ;
- case 2:
- s->dma_cfg.DefaultCCR = PCM_TX_DMA_16BITS_CFG; /* setup 2 bytes*/
- break ;
- case 4:
- s->dma_cfg.DefaultCCR = PCM_TX_DMA_32BITS_CFG; /* setup 4 byte*/
- break ;
- }
- }
- else {
- /* From device to memory */
- switch (runtime->channels * runtime->format) {
- case 1:
- s->dma_cfg.DefaultCCR = PCM_RX_DMA_8BITS_CFG ; /* setup 1 bytes*/
- break ;
- case 2:
- s->dma_cfg.DefaultCCR = PCM_RX_DMA_16BITS_CFG ; /* setup 2 bytes*/
- break ;
- case 4:
- s->dma_cfg.DefaultCCR = PCM_RX_DMA_32BITS_CFG ; /* setup 4 byte*/
- break ;
- }
- }
-
- s->dma_cfg.ChunkSize = 1;
-
- wmt_setup_dma(s->dmach, s->dma_cfg) ;
-}
-
-static int audio_dma_free(struct audio_stream_a *s)
-{
- int err = 0;
- DBG_DETAIL();
- wmt_free_dma(s->dmach);
- s->dmach = NULL_DMA;
- return err;
-}
-
-/*
- * this stops the dma and clears the dma ptrs
- */
-static void audio_stop_dma(struct audio_stream_a *s)
-{
- //dump_stack();
- unsigned long flags;
- DBG_DETAIL();
- local_irq_save(flags);
- s->active = 0;
- s->period = 0;
- s->periods = 0;
- s->offset = 0;
- wmt_stop_dma(s->dmach);
- wmt_clear_dma(s->dmach);
- local_irq_restore(flags);
-}
-
-/* this may get called several times by oss emulation */
-static int wmt_pcm_dma_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- //dump_stack();
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err = 0;
- DBG_DETAIL();
- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
- runtime->dma_bytes = params_buffer_bytes(params);
- return err;
-}
-
-static int wmt_pcm_dma_hw_free(struct snd_pcm_substream *substream)
-{
- DBG_DETAIL();
- snd_pcm_set_runtime_buffer(substream, NULL);
- return 0;
-}
-
-static int wmt_pcm_dma_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int stream_id = substream->pstr->stream;
- struct audio_stream_a *prtd = runtime->private_data;
- struct audio_stream_a *s = &prtd[stream_id];
- //dump_stack();
- DBG_DETAIL();
-
- s->period = 0;
- s->periods = 0;
- s->offset = 0;
- audio_setup_dma(s, stream_id);
-
- return 0;
-}
-
-static int wmt_pcm_dma_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int stream_id = substream->pstr->stream;
- struct audio_stream_a *prtd = runtime->private_data;
- struct audio_stream_a *s = &prtd[stream_id];
- int ret = 0;
-
- DPRINTK("Enter, cmd=%d", cmd);
- //dump_stack();
- spin_lock(&s->dma_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- s->active = 1;
- audio_process_dma(s);
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- s->active = 0;
- audio_stop_dma(s);
- break;
- default:
- ret = -EINVAL;
- }
- spin_unlock(&s->dma_lock);
-
- return ret;
-}
-
-static snd_pcm_uframes_t wmt_pcm_dma_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct audio_stream_a *prtd = runtime->private_data;
- int stream_id = substream->pstr->stream;
- struct audio_stream_a *s = &prtd[stream_id];
- dma_addr_t ptr;
- snd_pcm_uframes_t offset = 0;
- //dump_stack();
- ptr = wmt_get_dma_pos(s->dmach);
-
- if ((runtime->channels == 1 || runtime->channels == 2) && (runtime->format == SNDRV_PCM_FORMAT_S16_LE)) {
- offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
- }
-
- if (offset >= runtime->buffer_size)
- offset = 0;
-
- spin_lock(&s->dma_lock);
-
- if (s->periods > 0 && s->periods < 2) {
- if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
- if (snd_pcm_playback_hw_avail(runtime) >= 2 * runtime->period_size)
- audio_process_dma(s);
- }
- else {
- if (snd_pcm_capture_hw_avail(runtime) >= 2* runtime->period_size)
- audio_process_dma(s);
- }
-
- }
- spin_unlock(&s->dma_lock);
-
- return offset;
-}
-
-static int wmt_pcm_dma_open(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct audio_stream_a *s = runtime->private_data;
- int ret;
-
- DBG_DETAIL();
-
- if (!cpu_dai->active) {
- audio_dma_request(&s[0], audio_dma_callback);
- audio_dma_request(&s[1], audio_dma_callback);
- }
- //dump_stack();
- snd_soc_set_runtime_hwparams(substream, &wmt_pcm_dma_hardware);
-
- /* Ensure that buffer size is a multiple of period size */
- ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
- if (ret < 0)
- goto out;
-
-out:
- return ret;
-}
-
-static int wmt_pcm_dma_close(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct audio_stream_a *s = runtime->private_data;
-
- DBG_DETAIL();
- //dump_stack();
- if (!cpu_dai->active) {
- audio_dma_free(&s[0]);
- audio_dma_free(&s[1]);
- }
-
- return 0;
-}
-
-static int wmt_pcm_dma_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- DBG_DETAIL();
- //dump_stack();
- return dma_mmap_writecombine(substream->pcm->card->dev, vma,
- runtime->dma_area,
- runtime->dma_addr,
- runtime->dma_bytes);
-}
-
-static struct snd_pcm_ops wmt_pcm_dma_ops = {
- .open = wmt_pcm_dma_open,
- .close = wmt_pcm_dma_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = wmt_pcm_dma_hw_params,
- .hw_free = wmt_pcm_dma_hw_free,
- .prepare = wmt_pcm_dma_prepare,
- .trigger = wmt_pcm_dma_trigger,
- .pointer = wmt_pcm_dma_pointer,
- .mmap = wmt_pcm_dma_mmap,
-};
-
-static u64 wmt_pcm_dma_dmamask = DMA_BIT_MASK(32);
-
-static int wmt_pcm_dma_preallocate_dma_buffer(struct snd_pcm *pcm,
- int stream)
-{
- struct snd_pcm_substream *substream = pcm->streams[stream].substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = wmt_pcm_dma_hardware.buffer_bytes_max;
-
- DBG_DETAIL();
-
- buf->dev.type = SNDRV_DMA_TYPE_DEV;
- buf->dev.dev = pcm->card->dev;
- buf->private_data = NULL;
- buf->area = dma_alloc_writecombine(pcm->card->dev, size,
- &buf->addr, GFP_KERNEL);
-
- DPRINTK("buf_area = %x, buf_addr = %x", (unsigned int)buf->area, buf->addr);
- if (!buf->area)
- return -ENOMEM;
-
- buf->bytes = size;
-
- return 0;
-}
-
-static void wmt_pcm_dma_free_dma_buffers(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- struct snd_dma_buffer *buf;
- int stream;
-
- DBG_DETAIL();
-
- for (stream = 0; stream < 2; stream++) {
- substream = pcm->streams[stream].substream;
- if (!substream)
- continue;
-
- buf = &substream->dma_buffer;
- if (!buf->area)
- continue;
-
- dma_free_writecombine(pcm->card->dev, buf->bytes, buf->area, buf->addr);
-
- buf->area = NULL;
- }
-}
-
-static int wmt_pcm_dma_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- int ret = 0;
-
- DBG_DETAIL();
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &wmt_pcm_dma_dmamask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = wmt_pcm_dma_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_PLAYBACK);
- if (ret)
- goto out;
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- ret = wmt_pcm_dma_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_CAPTURE);
- if (ret)
- goto out;
- }
-
-out:
- /* free preallocated buffers in case of error */
- if (ret)
- wmt_pcm_dma_free_dma_buffers(pcm);
-
- return ret;
-}
-
-#ifdef CONFIG_PM
-static int wmt_pcm_dma_suspend(struct snd_soc_dai *dai)
-{
- struct snd_pcm_runtime *runtime = dai->runtime;
- struct audio_stream_a *prtd;
- struct audio_stream_a *s;
-
- DBG_DETAIL();
-
- if (!runtime)
- return 0;
-
- prtd = runtime->private_data;
- s = &prtd[SNDRV_PCM_STREAM_PLAYBACK];
-
- if (s->active) {
- udelay(5);
- wmt_stop_dma(s->dmach);
- /*
- wmt_clear_dma(s->dmach);
- audio_stop_dma(s);
- */
- }
-
- s = &prtd[SNDRV_PCM_STREAM_CAPTURE];
-
- if (s->active) {
- udelay(5);
- wmt_stop_dma(s->dmach);
- /*
- wmt_clear_dma(s->dmach);
- audio_stop_dma(s);
- */
- }
-
- return 0;
-}
-
-static int wmt_pcm_dma_resume(struct snd_soc_dai *dai)
-{
- struct snd_pcm_runtime *runtime = dai->runtime;
- struct audio_stream_a *prtd;
- struct audio_stream_a *s;
-
- DBG_DETAIL();
-
- if (!runtime)
- return 0;
-
- prtd = runtime->private_data;
- s = &prtd[SNDRV_PCM_STREAM_PLAYBACK];
- audio_setup_dma(s, SNDRV_PCM_STREAM_PLAYBACK);
-
- if (s->active) {
- wmt_resume_dma(s->dmach) ;
- }
-
- s = &prtd[SNDRV_PCM_STREAM_CAPTURE];
- audio_setup_dma(s, SNDRV_PCM_STREAM_CAPTURE);
-
- if (s->active) {
- wmt_resume_dma(s->dmach) ;
- }
-
- return 0;
-}
-#else
-#define wmt_pcm_dma_suspend NULL
-#define wmt_pcm_dma_resume NULL
-#endif
-
-static struct snd_soc_platform_driver wmt_soc_platform = {
- .ops = &wmt_pcm_dma_ops,
- .pcm_new = wmt_pcm_dma_new,
- .pcm_free = wmt_pcm_dma_free_dma_buffers,
- .suspend = wmt_pcm_dma_suspend,
- .resume = wmt_pcm_dma_resume,
-};
-
-static int __devinit wmt_pcm_dma_platform_probe(struct platform_device *pdev)
-{
- DBG_DETAIL();
- return snd_soc_register_platform(&pdev->dev, &wmt_soc_platform);
-}
-
-static int __devexit wmt_pcm_dma_platform_remove(struct platform_device *pdev)
-{
- DBG_DETAIL();
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver wmt_pcm_dma_driver = {
- .driver = {
- .name = "wmt-pcm-dma",
- .owner = THIS_MODULE,
- },
-
- .probe = wmt_pcm_dma_platform_probe,
- .remove = __devexit_p(wmt_pcm_dma_platform_remove),
-};
-
-module_platform_driver(wmt_pcm_dma_driver);
-
-MODULE_AUTHOR("WonderMedia Technologies, Inc.");
-MODULE_DESCRIPTION("WMT [ALSA SoC/pcm dma] driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-dma.h b/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-dma.h
deleted file mode 100755
index 88f246b2..00000000
--- a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-dma.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*++
- * linux/sound/soc/wmt/wmt-pcm.h
- * WonderMedia audio driver for ALSA
- *
- * Copyright c 2010 WonderMedia Technologies, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * WonderMedia Technologies, Inc.
- * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
---*/
-
-
-#ifndef __WMT_PCM_DMA_H__
-#define __WMT_PCM_DMA_H__
-
-struct wmt_pcm_dma_data {
- char *name; /* stream identifier */
- int dma_req; /* DMA request line */
- unsigned long port_addr; /* transmit/receive register */
- struct dma_device_cfg_s *dma_cfg;
-};
-
-#endif /* __WMT_PDM_PCM_H__ */
diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm.c b/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm.c
deleted file mode 100755
index 848ea5a1..00000000
--- a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm.c
+++ /dev/null
@@ -1,767 +0,0 @@
-/*++
- * linux/sound/soc/wmt/wmt-pcm.c
- * WonderMedia audio driver for ALSA
- *
- * Copyright c 2010 WonderMedia Technologies, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * WonderMedia Technologies, Inc.
- * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
---*/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-
-#include <linux/dma-mapping.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <linux/delay.h>
-
-#include <asm/dma.h>
-#include "wmt-pcm.h"
-#include "wmt-soc.h"
-
-#define NULL_DMA ((dmach_t)(-1))
-
-#define AUDIO_NAME "WMT_PCM"
-//#define WMT_PCM_DEBUG 1
-//#define WMT_PCM_DEBUG_DETAIL 1
-
-#ifdef WMT_PCM_DEBUG
-#define DPRINTK(format, arg...) \
- printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
-#else
-#define DPRINTK(format, arg...) do {} while (0)
-#endif
-
-#ifdef WMT_PCM_DEBUG_DETAIL
-#define DBG_DETAIL(format, arg...) \
- printk(KERN_INFO AUDIO_NAME ": [%s]" format "\n" , __FUNCTION__, ## arg)
-#else
-#define DBG_DETAIL(format, arg...) do {} while (0)
-#endif
-
-#define err(format, arg...) \
- printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg)
-#define info(format, arg...) \
- printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
-#define warn(format, arg...) \
- printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg)
-
-static const struct snd_pcm_hardware wmt_pcm_hardware = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rate_min = 8000,
- .rate_max = 96000,
- .period_bytes_min = 4*1024,//32,
- .period_bytes_max = 8*1024,//4 * 1024,
- .periods_min = 1,//2,
- .periods_max = 16,//128,
- .buffer_bytes_max = 64 * 1024,
- .fifo_size = 32,//
-};
-
-struct wmt_runtime_data {
- spinlock_t lock;
- struct wmt_pcm_dma_data *dma_data;
- int dma_ch;
- int period_index;
-};
-
-struct snd_wfd_buffer {
- struct device *dev;
- unsigned char *area; /* virtual pointer */
- dma_addr_t addr; /* physical address */
- size_t bytes; /* buffer size in bytes */
- size_t valuable_sz; /* valuable size in wfd buffer */
- unsigned char *wr_ptr;
- unsigned char *rd_ptr;
- int enable;
-};
-static struct snd_wfd_buffer wfd_audbuf;
-
-static int audio_dma_free(struct audio_stream_a *s);
-
-dmach_t pcm_out_dmach = 0xFF;
-struct dma_device_cfg_s *pcm_out_dma_cfg = NULL;
-
-void wmt_pcm_wfd_start(void)
-{
- /* allocate buffer for WFD support */
- wfd_audbuf.area = dma_alloc_writecombine(wfd_audbuf.dev, wfd_audbuf.bytes,
- &wfd_audbuf.addr, GFP_KERNEL);
-
- if (!wfd_audbuf.area) {
- err("WFD_Aud allocate buffer fail");
- }
- else {
- info("*WFD_Aud enable");
- wfd_audbuf.enable = 1;
- }
-
- memset(wfd_audbuf.area, 0x0, wfd_audbuf.bytes);
- //info("&wfd_audbuf.addr=0x%x wfd_audbuf.addr=0x%x", &wfd_audbuf.addr, (unsigned int)wfd_audbuf.addr);
-}
-EXPORT_SYMBOL(wmt_pcm_wfd_start);
-
-unsigned int wmt_pcm_wfd_get_buf(void)
-{
- wfd_audbuf.valuable_sz = 0;
- wfd_audbuf.wr_ptr = wfd_audbuf.rd_ptr = wfd_audbuf.area;
- return (unsigned int)&wfd_audbuf.addr;
-}
-EXPORT_SYMBOL(wmt_pcm_wfd_get_buf);
-
-void wmt_pcm_wfd_stop(void)
-{
- wfd_audbuf.wr_ptr = wfd_audbuf.area;
- wfd_audbuf.enable = 0;
-
- dma_free_writecombine(wfd_audbuf.dev, wfd_audbuf.bytes,
- wfd_audbuf.area, wfd_audbuf.addr);
- info("*WFD_Aud disable");
- return;
-}
-EXPORT_SYMBOL(wmt_pcm_wfd_stop);
-
-int wmt_pcm_wfd_get_strm(WFDStrmInfo_t *info)
-{
- if ((info->req_sz > wfd_audbuf.bytes) || (!wfd_audbuf.valuable_sz)) {
- //info("WFD read size=%d, Too Large!", info->req_sz);
- info->avail_sz = 0;
- return (int)info;
- }
- else if (wfd_audbuf.valuable_sz > info->req_sz) {
- info->avail_sz = info->req_sz;
- wfd_audbuf.valuable_sz -= info->req_sz;
- }
- else {
- info->avail_sz = wfd_audbuf.valuable_sz;
- wfd_audbuf.valuable_sz = 0;
- }
-
- info->buf_offset = wfd_audbuf.rd_ptr - wfd_audbuf.area;
- wfd_audbuf.rd_ptr += info->avail_sz;
-
- if (wfd_audbuf.rd_ptr >= wfd_audbuf.area + wfd_audbuf.bytes)
- wfd_audbuf.rd_ptr = wfd_audbuf.rd_ptr - wfd_audbuf.bytes;
-
- return (int)info;
-}
-EXPORT_SYMBOL(wmt_pcm_wfd_get_strm);
-
-void wmt_pcm_wfd_update(char *src_buf, unsigned int chunksize)
-{
- //info("wmt_pcm_wfd_update, 0x%x", src_buf[1024]);
- memcpy(wfd_audbuf.wr_ptr, src_buf, chunksize);
- wfd_audbuf.wr_ptr += chunksize;
-
- if (wfd_audbuf.wr_ptr == wfd_audbuf.area + wfd_audbuf.bytes)
- wfd_audbuf.wr_ptr = wfd_audbuf.area;
-
- wfd_audbuf.valuable_sz += chunksize;
- if (wfd_audbuf.valuable_sz >= wfd_audbuf.bytes) {
- wfd_audbuf.valuable_sz = wfd_audbuf.bytes;
- wfd_audbuf.rd_ptr = wfd_audbuf.wr_ptr;
- }
-}
-
-/*
- * Main dma routine, requests dma according where you are in main alsa buffer
- */
-static void audio_process_dma(struct audio_stream_a *s)
-{
- struct snd_pcm_substream *substream = s->stream;
- struct snd_pcm_runtime *runtime;
- unsigned int dma_size;
- unsigned int offset;
- dma_addr_t dma_base;
- int ret = 0;
-
- //DBG_DETAIL();
- DPRINTK("s: %d, dmach: %d. active: %d", (int)s, s->dmach, s->active);
-
- if (s->active) {
- substream = s->stream;
- runtime = substream->runtime;
- dma_size = frames_to_bytes(runtime, runtime->period_size);
- /*DPRINTK("frame_bits=%d, period_size=%d, dma_size 1=%d",
- runtime->frame_bits, (int)runtime->period_size, dma_size);*/
- if (dma_size > MAX_DMA_SIZE)
- dma_size = CUT_DMA_SIZE;
- offset = dma_size * s->period;
-
- /*DPRINTK("offset: 0x%x, ->dma_area: 0x%x, ->dma_addr: 0x%x, final addr: 0x%x",
- offset, (unsigned int)runtime->dma_area, runtime->dma_addr, runtime->dma_addr+offset);*/
-
- dma_base = __virt_to_phys((dma_addr_t)runtime->dma_area);
-
- //DPRINTK("dma address: 0x%x", dma_base+offset);
- /*DPRINTK("hw_ptr_interrupt: 0x%x, state: %d, hwptr: %u, applptr: %u, avail_min: %u",
- (unsigned int)runtime->hw_ptr_interrupt, runtime->status->state, (unsigned int)runtime->status->hw_ptr,
- (unsigned int)runtime->control->appl_ptr, (unsigned int)runtime->control->avail_min);*/
- //DPRINTK("dmach: %u, dma_addr: %x, dma_size: %u", s->dmach, dma_base+offset, dma_size);
-
- if ((runtime->channels == 2 || runtime->channels == 1) &&
- (runtime->format == SNDRV_PCM_FORMAT_S16_LE)) {
- ret = wmt_start_dma(s->dmach, runtime->dma_addr + offset, 0, dma_size);
- }
-
- if (ret) {
- printk(KERN_ERR "audio_process_dma: cannot queue DMA buffer (%i) \n", ret);
- return;
- }
-
- s->period++;
- s->period %= runtime->periods;
- s->periods++;
- s->offset = offset;
- }
-}
-
-/*
- * This is called when dma IRQ occurs at the end of each transmited block
- */
-static void audio_dma_callback(void *data)
-{
- struct audio_stream_a *s = data;
- struct snd_pcm_substream *substream;
- struct snd_pcm_runtime *runtime;
- unsigned int dma_size;
- unsigned int offset;
- int stream_id;
-
- //DBG_DETAIL();
-
- substream = s->stream;
- runtime = substream->runtime;
- dma_size = frames_to_bytes(runtime, runtime->period_size);
- stream_id = substream->pstr->stream;
-
- if (s->period > 0)
- offset = dma_size * (s->period - 1);
- else
- offset = dma_size * (s->periods - 1);
-
- if ((stream_id == SNDRV_PCM_STREAM_PLAYBACK) && (wfd_audbuf.enable)) {
- wmt_pcm_wfd_update(runtime->dma_area + offset, dma_size);
- }
-
- /*
- * If we are getting a callback for an active stream then we inform
- * the PCM middle layer we've finished a period
- */
- if (s->active)
- snd_pcm_period_elapsed(s->stream);
-
- spin_lock(&s->dma_lock);
- if (s->periods > 0)
- s->periods--;
-
- audio_process_dma(s);
- spin_unlock(&s->dma_lock);
-}
-
-static int audio_dma_request(struct audio_stream_a *s, void (*callback) (void *))
-{
- int err;
- err = 0;
-
- DBG_DETAIL();
-
- //DPRINTK("s pointer: %d, dmach: %d, id: %s, dma_dev: %d", (int)s, s->dmach, s->id, s->dma_dev);
- err = wmt_request_dma(&s->dmach, s->id, s->dma_dev, callback, s);
- if (err < 0)
- printk(KERN_ERR "Unable to grab audio dma 0x%x\n", s->dmach);
-
- if (!strcmp(s->id, "WMT I2S out")) {
- pcm_out_dmach = s->dmach;
- }
- return err;
-}
-
-static void audio_setup_dma(struct audio_stream_a *s, int stream_id)
-{
- struct snd_pcm_runtime *runtime = s->stream->runtime;
-
- if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
- /* From memory to device */
- switch (runtime->channels * runtime->format) {
- #if 0 //comment 2014-1-3 tinyplay mono pattern abnormal
- case 1:
- s->dma_cfg.DefaultCCR = I2S_TX_DMA_8BITS_CFG; /* setup 1 bytes*/
- break ;
- case 2:
- s->dma_cfg.DefaultCCR = I2S_TX_DMA_16BITS_CFG; /* setup 2 bytes*/
- break ;
- case 4:
- #endif
- default :
- s->dma_cfg.DefaultCCR = I2S_TX_DMA_32BITS_CFG; /* setup 4 byte*/
- break ;
- }
- }
- else {
- /* From device to memory */
- switch (runtime->channels * runtime->format) {
- case 1:
- s->dma_cfg.DefaultCCR = I2S_RX_DMA_8BITS_CFG ; /* setup 1 bytes*/
- break ;
- case 2:
- s->dma_cfg.DefaultCCR = I2S_RX_DMA_16BITS_CFG ; /* setup 2 bytes*/
- break ;
- case 4:
- s->dma_cfg.DefaultCCR = I2S_RX_DMA_32BITS_CFG ; /* setup 4 byte*/
- break ;
- }
- }
-
- s->dma_cfg.ChunkSize = 1;
- if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
- pcm_out_dma_cfg = &s->dma_cfg;
- }
-
- //DPRINTK("s pointer: %d. audio dma %d cfg.DefaultCCR 0x%x ", (int)s, s->dmach, (unsigned int)s->dma_cfg.DefaultCCR);
- //DPRINTK("cfg.ChunkSize 0x%x ", s->dma_cfg.ChunkSize);
- wmt_setup_dma(s->dmach, s->dma_cfg) ;
-}
-
-static int audio_dma_free(struct audio_stream_a *s)
-{
- int err = 0;
- DBG_DETAIL();
- wmt_free_dma(s->dmach);
- s->dmach = NULL_DMA;
- pcm_out_dma_cfg = NULL;
- return err;
-}
-
-/*
- * this stops the dma and clears the dma ptrs
- */
-static void audio_stop_dma(struct audio_stream_a *s)
-{
- unsigned long flags;
- DBG_DETAIL();
- local_irq_save(flags);
- s->active = 0;
- s->period = 0;
- s->periods = 0;
- s->offset = 0;
- s->last_offset = 0;
- wmt_stop_dma(s->dmach);
- wmt_clear_dma(s->dmach);
- local_irq_restore(flags);
-}
-
-/* this may get called several times by oss emulation */
-static int wmt_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err = 0;
- DBG_DETAIL();
- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
- runtime->dma_bytes = params_buffer_bytes(params);
- return err;
-}
-
-static int wmt_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- DBG_DETAIL();
- snd_pcm_set_runtime_buffer(substream, NULL);
- return 0;
-}
-
-static int wmt_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int stream_id = substream->pstr->stream;
- struct audio_stream_a *prtd = runtime->private_data;
- struct audio_stream_a *s = &prtd[stream_id];
-
- DBG_DETAIL();
-
- s->period = 0;
- s->periods = 0;
- s->offset = 0;
- s->last_offset = 0;
- audio_setup_dma(s, stream_id);
-
- return 0;
-}
-
-static int wmt_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int stream_id = substream->pstr->stream;
- struct audio_stream_a *prtd = runtime->private_data;
- struct audio_stream_a *s = &prtd[stream_id];
- int ret = 0;
-
- DPRINTK("wmt_pcm_trigger Enter, cmd=%d", cmd);
-
- spin_lock(&s->dma_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- s->active = 1;
- audio_process_dma(s);
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- s->active = 0;
- audio_stop_dma(s);
- break;
- default:
- ret = -EINVAL;
- }
- spin_unlock(&s->dma_lock);
-
- return ret;
-}
-
-static snd_pcm_uframes_t wmt_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct audio_stream_a *prtd = runtime->private_data;
- int stream_id = substream->pstr->stream;
- struct audio_stream_a *s = &prtd[stream_id];
- dma_addr_t ptr;
- snd_pcm_uframes_t offset = 0;
-
- ptr = wmt_get_dma_pos(s->dmach);
-
- if ((runtime->channels == 1 || runtime->channels == 2) && (runtime->format == SNDRV_PCM_FORMAT_S16_LE)) {
- offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
- }
-
- if ((offset < s->last_offset) && ((s->last_offset - offset) < runtime->period_size) &&
- (s->last_offset != runtime->buffer_size)) {
- snd_pcm_uframes_t old_offset = offset;
- if (s->last_offset < runtime->period_size)
- offset = runtime->period_size;
- else {
- offset = runtime->period_size *
- ((s->last_offset / runtime->period_size) + 1);
- }
- printk("last_offset %d, old offset %d, new offset %d\n", (int)s->last_offset, (int)old_offset, (int)offset);
- }
- s->last_offset = offset;
-
- if (offset >= runtime->buffer_size)
- offset = 0;
-
- spin_lock(&s->dma_lock);
-
- if (s->periods > 0 && s->periods < 3) {
- if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
- if (snd_pcm_playback_hw_avail(runtime) >= 3 * runtime->period_size)
- audio_process_dma(s);
- }
- else {
- if (snd_pcm_capture_hw_avail(runtime) >= 3* runtime->period_size)
- audio_process_dma(s);
- }
-
- }
- spin_unlock(&s->dma_lock);
-
- //DPRINTK("offset = %x", (unsigned int)offset);
- return offset;
-}
-
-static int wmt_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct audio_stream_a *s = runtime->private_data;
- int ret;
-
- DBG_DETAIL();
-
- if (!cpu_dai->active) {
- audio_dma_request(&s[0], audio_dma_callback);
- audio_dma_request(&s[1], audio_dma_callback);
- }
-
- snd_soc_set_runtime_hwparams(substream, &wmt_pcm_hardware);
-
- /* Ensure that buffer size is a multiple of period size */
- ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
- if (ret < 0)
- goto out;
-
-out:
- return ret;
-}
-
-static int wmt_pcm_close(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct audio_stream_a *s = runtime->private_data;
-
- DBG_DETAIL();
-
- if (!cpu_dai->active) {
- audio_dma_free(&s[0]);
- audio_dma_free(&s[1]);
- }
-
- return 0;
-}
-
-static int wmt_pcm_mmap(struct snd_pcm_substream *substream,
- struct vm_area_struct *vma)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- DBG_DETAIL();
-
- return dma_mmap_writecombine(substream->pcm->card->dev, vma,
- runtime->dma_area,
- runtime->dma_addr,
- runtime->dma_bytes);
-}
-
-static struct snd_pcm_ops wmt_pcm_ops = {
- .open = wmt_pcm_open,
- .close = wmt_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = wmt_pcm_hw_params,
- .hw_free = wmt_pcm_hw_free,
- .prepare = wmt_pcm_prepare,
- .trigger = wmt_pcm_trigger,
- .pointer = wmt_pcm_pointer,
- .mmap = wmt_pcm_mmap,
-};
-
-static u64 wmt_pcm_dmamask = DMA_BIT_MASK(32);
-
-static int wmt_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
- int stream)
-{
- struct snd_pcm_substream *substream = pcm->streams[stream].substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = wmt_pcm_hardware.buffer_bytes_max;
-
- DBG_DETAIL();
-
- buf->dev.type = SNDRV_DMA_TYPE_DEV;
- buf->dev.dev = pcm->card->dev;
- buf->private_data = NULL;
- buf->area = dma_alloc_writecombine(pcm->card->dev, size,
- &buf->addr, GFP_KERNEL);
-
- if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
- info("stream = %d, buf_addr = %x", stream, buf->addr);
-
- wfd_audbuf.bytes = size;
- wfd_audbuf.dev = pcm->card->dev;
- wfd_audbuf.enable = 0;
- }
-
- if (!buf->area)
- return -ENOMEM;
-
- buf->bytes = size;
-
- return 0;
-}
-
-static void wmt_pcm_free_dma_buffers(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- struct snd_dma_buffer *buf;
- int stream;
-
- DBG_DETAIL();
-
- for (stream = 0; stream < 2; stream++) {
- substream = pcm->streams[stream].substream;
- if (!substream)
- continue;
-
- buf = &substream->dma_buffer;
- if (!buf->area)
- continue;
-
- dma_free_writecombine(pcm->card->dev, buf->bytes, buf->area, buf->addr);
-
- buf->area = NULL;
- }
-}
-
-int wmt_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- int ret = 0;
-
- DBG_DETAIL();
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &wmt_pcm_dmamask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = wmt_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_PLAYBACK);
- if (ret)
- goto out;
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- ret = wmt_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_CAPTURE);
- if (ret)
- goto out;
- }
-
-out:
- /* free preallocated buffers in case of error */
- if (ret)
- wmt_pcm_free_dma_buffers(pcm);
-
- return ret;
-}
-
-#ifdef CONFIG_PM
-static int wmt_pcm_suspend(struct snd_soc_dai *dai)
-{
- struct snd_pcm_runtime *runtime = dai->runtime;
- struct audio_stream_a *prtd;
- struct audio_stream_a *s;
-
- DBG_DETAIL();
-
- if (!runtime)
- return 0;
-
- prtd = runtime->private_data;
- s = &prtd[SNDRV_PCM_STREAM_PLAYBACK];
-
- if (s->active) {
- udelay(5);
- wmt_stop_dma(s->dmach);
- /*
- wmt_clear_dma(s->dmach);
- audio_stop_dma(s);
- */
- }
-
- s = &prtd[SNDRV_PCM_STREAM_CAPTURE];
-
- if (s->active) {
- udelay(5);
- wmt_stop_dma(s->dmach);
- /*
- wmt_clear_dma(s->dmach);
- audio_stop_dma(s);
- */
- }
-
- return 0;
-}
-
-static int wmt_pcm_resume(struct snd_soc_dai *dai)
-{
- struct snd_pcm_runtime *runtime = dai->runtime;
- struct audio_stream_a *prtd;
- struct audio_stream_a *s;
-
- DBG_DETAIL();
-
- if (!runtime) {
- if ((pcm_out_dmach != 0xFF) && (pcm_out_dma_cfg != NULL)) {
- wmt_setup_dma(pcm_out_dmach, *pcm_out_dma_cfg);
- }
- return 0;
- }
-
- prtd = runtime->private_data;
- s = &prtd[SNDRV_PCM_STREAM_PLAYBACK];
- audio_setup_dma(s, SNDRV_PCM_STREAM_PLAYBACK);
-
- if (s->active) {
- wmt_resume_dma(s->dmach) ;
- }
-
- s = &prtd[SNDRV_PCM_STREAM_CAPTURE];
- audio_setup_dma(s, SNDRV_PCM_STREAM_CAPTURE);
-
- if (s->active) {
- wmt_resume_dma(s->dmach) ;
- }
-
- return 0;
-}
-#else
-#define wmt_pcm_suspend NULL
-#define wmt_pcm_resume NULL
-#endif
-
-static struct snd_soc_platform_driver wmt_soc_platform = {
- .ops = &wmt_pcm_ops,
- .pcm_new = wmt_pcm_new,
- .pcm_free = wmt_pcm_free_dma_buffers,
- .suspend = wmt_pcm_suspend,
- .resume = wmt_pcm_resume,
-};
-
-static int __devinit wmt_pcm_platform_probe(struct platform_device *pdev)
-{
- DBG_DETAIL();
-
- return snd_soc_register_platform(&pdev->dev, &wmt_soc_platform);
-}
-
-static int __devexit wmt_pcm_platform_remove(struct platform_device *pdev)
-{
- DBG_DETAIL();
-
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver wmt_pcm_driver = {
- .driver = {
- .name = "wmt-audio-pcm",
- .owner = THIS_MODULE,
- },
-
- .probe = wmt_pcm_platform_probe,
- .remove = __devexit_p(wmt_pcm_platform_remove),
-};
-
-module_platform_driver(wmt_pcm_driver);
-
-MODULE_AUTHOR("WonderMedia Technologies, Inc.");
-MODULE_DESCRIPTION("WMT [ALSA SoC/pcm] driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm.h b/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm.h
deleted file mode 100755
index 90ad7747..00000000
--- a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*++
- * linux/sound/soc/wmt/wmt-pcm.h
- * WonderMedia audio driver for ALSA
- *
- * Copyright c 2010 WonderMedia Technologies, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * WonderMedia Technologies, Inc.
- * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
---*/
-
-
-#ifndef __WMT_PCM_H__
-#define __WMT_PCM_H__
-
-struct wmt_pcm_dma_data {
- char *name; /* stream identifier */
- int dma_req; /* DMA request line */
- unsigned long port_addr; /* transmit/receive register */
- struct dma_device_cfg_s *dma_cfg;
-};
-
-typedef struct WFDStrmInfo {
- unsigned int req_sz;
- unsigned int avail_sz;
- unsigned int buf_offset;
-} WFDStrmInfo_t;
-
-extern void wmt_pcm_wfd_start(void);
-extern unsigned int wmt_pcm_wfd_get_buf(void);
-extern void wmt_pcm_wfd_stop(void);
-extern int wmt_pcm_wfd_get_strm(WFDStrmInfo_t *info);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt-soc.c b/ANDROID_3.4.5/sound/soc/wmt/wmt-soc.c
deleted file mode 100755
index f62e993d..00000000
--- a/ANDROID_3.4.5/sound/soc/wmt/wmt-soc.c
+++ /dev/null
@@ -1,321 +0,0 @@
-/*++
- * linux/sound/soc/wmt/wmt-soc.c
- * WonderMedia audio driver for ALSA
- *
- * Copyright c 2010 WonderMedia Technologies, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * WonderMedia Technologies, Inc.
- * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
---*/
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/hwdep.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-
-#include "wmt-soc.h"
-#include "wmt-pcm.h"
-#include "wmt_hwdep.h"
-#include "../codecs/wmt_vt1602.h"
-#include "../codecs/vt1603.h"
-
-extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
-extern void wmt_set_i2s_share_pin();
-char wmt_codec_name[80];
-char wmt_dai_name[80];
-char wmt_rate[10];
-
-#define AUDIO_NAME "WMT_SOC"
-//#define WMT_SOC_DEBUG 1
-//#define WMT_SOC_DEBUG_DETAIL 1
-
-#ifdef WMT_SOC_DEBUG
-#define DPRINTK(format, arg...) \
- printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
-#else
-#define DPRINTK(format, arg...) do {} while (0)
-#endif
-
-#ifdef WMT_SOC_DEBUG_DETAIL
-#define DBG_DETAIL(format, arg...) \
- printk(KERN_INFO AUDIO_NAME ": [%s]" format "\n" , __FUNCTION__, ## arg)
-#else
-#define DBG_DETAIL(format, arg...) do {} while (0)
-#endif
-
-#define err(format, arg...) \
- printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg)
-#define info(format, arg...) \
- printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
-#define warn(format, arg...) \
- printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg)
-
-#define WMT_I2S_RATES SNDRV_PCM_RATE_8000_96000
-
-static struct snd_soc_card snd_soc_machine_wmt;
-
-static int wmt_soc_primary_startup(struct snd_pcm_substream *substream)
-{
- DBG_DETAIL();
- return 0;
-}
-
-static void wmt_soc_primary_shutdown(struct snd_pcm_substream *substream)
-{
- DBG_DETAIL();
-}
-
-static int wmt_soc_primary_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
-
- DBG_DETAIL();
-
- if (strcmp(wmt_codec_name, "hwdac")) {
- /* Set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_CBS_CFS |
- SND_SOC_DAIFMT_I2S |SND_SOC_DAIFMT_NB_NF);
- if (ret < 0)
- return ret;
- }
-
-
- /* Set cpu DAI configuration for I2S */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
- |SND_SOC_DAIFMT_MASTER_MASK | SND_SOC_DAIFMT_NB_NF);
- if (ret < 0)
- return ret;
-
- if ((!strcmp(wmt_codec_name, "vt1602")) || (!strcmp(wmt_codec_name, "vt1603"))) {
- /* Set the codec system clock for DAC and ADC */
- if (!(params_rate(params) % 11025)) {
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, 11289600,
- SND_SOC_CLOCK_IN);
- }
- else {
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, 12288000,
- SND_SOC_CLOCK_IN);
- }
- }
-
- return ret;
-}
-
-static int wmt_soc_second_startup(struct snd_pcm_substream *substream)
-{
- //dump_stack();
- DBG_DETAIL();
- return 0;
-}
-
-static void wmt_soc_second_shutdown(struct snd_pcm_substream *substream)
-{
- //dump_stack();
- DBG_DETAIL();
-}
-
-static int wmt_soc_second_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- //dump_stack();
- DBG_DETAIL();
- return 0;
-}
-
-static int wmt_soc_dai_init(struct snd_soc_pcm_runtime *rtd)
-{
- DBG_DETAIL();
- wmt_soc_hwdep_new(rtd->codec);
- return 0;
-}
-
-static int wmt_suspend_pre(struct snd_soc_card *card)
-{
- snd_soc_dapm_disable_pin(&card->rtd->codec->dapm, "Left HP");
- snd_soc_dapm_disable_pin(&card->rtd->codec->dapm, "Right HP");
- snd_soc_dapm_disable_pin(&card->rtd->codec->dapm, "Left SPK");
- snd_soc_dapm_disable_pin(&card->rtd->codec->dapm, "Right SPK");
-}
-
-static int wmt_suspend_post(struct snd_soc_card *card)
-{
- DBG_DETAIL();
-
- /* Disable BIT15:I2S clock, BIT4:ARFP clock, BIT3:ARF clock */
- PMCEU_VAL &= ~(BIT15 | BIT4 | BIT3);
-
- snd_soc_dapm_enable_pin(&card->rtd->codec->dapm, "Left HP");
- snd_soc_dapm_enable_pin(&card->rtd->codec->dapm, "Right HP");
- snd_soc_dapm_enable_pin(&card->rtd->codec->dapm, "Left SPK");
- snd_soc_dapm_enable_pin(&card->rtd->codec->dapm, "Right SPK");
-
- return 0;
-}
-
-static int wmt_resume_pre(struct snd_soc_card *card)
-{
- /* Enable MCLK before VT1602 codec enable, otherwise the codec will be disabled. */
-
- /* set to 24.576MHz */
- auto_pll_divisor(DEV_I2S, CLK_ENABLE , 0, 0);
- auto_pll_divisor(DEV_I2S, SET_PLLDIV, 1, 24576);
- /* Enable BIT4:ARFP clock, BIT3:ARF clock */
- PMCEU_VAL |= (BIT4 | BIT3);
- /* Enable BIT2:AUD clock */
- PMCE3_VAL |= BIT2;
-
- wmt_set_i2s_share_pin();
- return 0;
-}
-
-static struct snd_soc_ops wmt_soc_primary_ops = {
- .startup = wmt_soc_primary_startup,
- .hw_params = wmt_soc_primary_hw_params,
- .shutdown = wmt_soc_primary_shutdown,
-};
-
-static struct snd_soc_ops wmt_soc_second_ops = {
- .startup = wmt_soc_second_startup,
- .hw_params = wmt_soc_second_hw_params,
- .shutdown = wmt_soc_second_shutdown,
-};
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link wmt_dai[] = {
- {
- .name = "HiFi",
- .stream_name = "HiFi",
- .platform_name = "wmt-audio-pcm.0",
- .init = wmt_soc_dai_init,
- .ops = &wmt_soc_primary_ops,
- },
- {
- .name = "Voice",
- .stream_name = "Voice",
- .platform_name = "wmt-pcm-dma.0",
- .cpu_dai_name = "wmt-pcm-controller.0",
- .codec_dai_name = "HWDAC",
- .codec_name = "wmt-i2s-hwdac.0",
- .ops = &wmt_soc_second_ops,
- },
-};
-
-/* Audio machine driver */
-static struct snd_soc_card snd_soc_machine_wmt = {
- .name = "WMT_VT1609",
- .dai_link = wmt_dai,
- .num_links = ARRAY_SIZE(wmt_dai),
- .suspend_pre = wmt_suspend_pre,
- .suspend_post = wmt_suspend_post,
- .resume_pre = wmt_resume_pre,
-};
-
-static struct platform_device *wmt_snd_device;
-
-static int __init wmt_soc_init(void)
-{
- int ret, i;
- char buf[64];
- int len = ARRAY_SIZE(buf);
-
- if (wmt_getsyspara("wmt.audio.i2s", buf, &len) != 0) {
- strcpy(wmt_dai_name, "null");
- strcpy(wmt_codec_name, "null");
- }
- else {
- strcpy(wmt_dai_name, "i2s");
- }
-
- if (strcmp(wmt_dai_name, "null")) {
- for (i = 0; i < 80; ++i) {
- if (buf[i] == ':')
- break;
- else
- wmt_codec_name[i] = buf[i];
- }
- }
- else {
- return -EINVAL;
- }
-
- // is wm8994, return and load wmt_wm8994 module
- if (strcmp(wmt_codec_name, "wm8994") == 0)
- return -ENODEV;
-
- info("dai_name=%s, codec_name=%s", wmt_dai_name, wmt_codec_name);
-
-
- wmt_i2s_dai.playback.rates = (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000);
- wmt_i2s_dai.capture.rates = (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000);
- wmt_dai[0].cpu_dai_name = "wmt-i2s.0";
-
- if (!strcmp(wmt_codec_name, "vt1602")) {
- wmt_dai[0].codec_dai_name = "VT1602";
- wmt_dai[0].codec_name = "vt1602.1-001a";
- }
- else if (!strcmp(wmt_codec_name, "hwdac")) {
- wmt_dai[0].codec_dai_name = "HWDAC";
- wmt_dai[0].codec_name = "wmt-i2s-hwdac.0";
- }
- else if (!strcmp(wmt_codec_name, "vt1603")) {
- wmt_dai[0].codec_dai_name = "VT1603";
- wmt_dai[0].codec_name = "vt1603-codec";
- }
-
- /* Doing register process after plug-in */
- wmt_snd_device = platform_device_alloc("soc-audio", -1);
- if (!wmt_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(wmt_snd_device, &snd_soc_machine_wmt);
-
- ret = platform_device_add(wmt_snd_device);
- if (ret)
- goto err1;
-
- return 0;
-
-err1:
- platform_device_put(wmt_snd_device);
- return ret;
-
-}
-
-static void __exit wmt_soc_exit(void)
-{
- DBG_DETAIL();
-
- platform_device_unregister(wmt_snd_device);
-}
-
-module_init(wmt_soc_init);
-module_exit(wmt_soc_exit);
-
-MODULE_AUTHOR("WonderMedia Technologies, Inc.");
-MODULE_DESCRIPTION("WMT [ALSA SoC/Machine] driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt-soc.h b/ANDROID_3.4.5/sound/soc/wmt/wmt-soc.h
deleted file mode 100755
index f49a2764..00000000
--- a/ANDROID_3.4.5/sound/soc/wmt/wmt-soc.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*++
- * linux/sound/soc/wmt/wmt-soc.h
- * WonderMedia audio driver for ALSA
- *
- * Copyright c 2010 WonderMedia Technologies, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * WonderMedia Technologies, Inc.
- * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
---*/
-
-
-#ifndef __WMT_ASOC_H__
-#define __WMT_ASOC_H__
-#include <mach/dma.h>
-
-struct audio_stream_a {
- char *id; /* identification string */
- int stream_id; /* numeric identification */
- dmach_t dmach; /* DMA channel number */
- struct dma_device_cfg_s dma_cfg; /* DMA device config */
- int dma_dev; /* dma number of that device */
- int dma_q_head; /* DMA Channel Q Head */
- int dma_q_tail; /* DMA Channel Q Tail */
- char dma_q_count; /* DMA Channel Q Count */
- int active:1; /* we are using this stream for transfer now */
- int period; /* current transfer period */
- int periods; /* current count of periods registerd in the DMA engine */
- spinlock_t dma_lock; /* for locking in DMA operations */
- struct snd_pcm_substream *stream; /* the pcm stream */
- unsigned linked:1; /* dma channels linked */
- int offset; /* store start position of the last period in the alsa buffer */
- snd_pcm_uframes_t last_offset;
-};
-
-#define NUM_LINKS 1
-
-extern struct snd_soc_dai_driver wmt_i2s_dai;
-
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.c b/ANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.c
deleted file mode 100755
index 8a6d374e..00000000
--- a/ANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*++
- * linux/sound/soc/wmt/wmt_hwdep.c
- * WonderMedia I2S audio driver for ALSA
- *
- * Copyright c 2010 WonderMedia Technologies, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * WonderMedia Technologies, Inc.
- * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
---*/
-
-#include <sound/soc.h>
-#include <sound/jack.h>
-
-#include <asm/mach-types.h>
-#include <mach/gpio.h>
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc-dapm.h>
-#include <sound/hwdep.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-
-#include "wmt_hwdep.h"
-#include "wmt-pcm.h"
-
-int WFD_flag = 0;
-static int gmode = 2;
-static char gstring[3] = "LR";
-
-static char gSpdHdm[6] = "BOTH";
-static int gSpHd = 6;
-
-extern void wmt_i2s_dac0_ctrl(int HDMI_audio_enable);
-
-static int wmt_hwdep_open(struct snd_hwdep *hw, struct file *file)
-{
- if ((file->f_flags & O_RDWR) && (WFD_flag)) {
- return -EBUSY;
- }
- else if (file->f_flags & O_SYNC) {
- WFD_flag = 1;
- }
- return 0;
-}
-
-static int wmt_hwdep_release(struct snd_hwdep *hw, struct file *file)
-{
- WFD_flag = 0;
- return 0;
-}
-
-static int wmt_hwdep_mmap(struct snd_hwdep *hw, struct file *file, struct vm_area_struct *vma)
-{
- vma->vm_flags |= VM_IO | VM_RESERVED;
- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
- if (remap_pfn_range(vma, vma->vm_start, (vma->vm_pgoff),
- vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
- printk("*E* remap page range failed: vm_pgoff=0x%x ", (unsigned int)vma->vm_pgoff);
- return -EAGAIN;
- }
- return 0;
-}
-
-static int wmt_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg)
-{
- int *value;
- WFDStrmInfo_t *info;
- struct wmt_soc_vt1603_info vt1603_info;
- int ret = 0;
-
- switch (cmd) {
- case WMT_SOC_IOCTL_HDMI:
- value = (int __user *)arg;
-
- if (*value > 1) {
- printk("Not supported status for HDMI Audio %d", *value);
- return 0;
- }
- wmt_i2s_dac0_ctrl(*value);
- return 0;
-
- case WMT_SOC_IOCTL_WFD_START:
- wmt_pcm_wfd_start();
- return copy_to_user( (void *)arg, (const void __user *) wmt_pcm_wfd_get_buf(), sizeof(unsigned int));
-
- case WMT_SOC_IOCTL_GET_STRM:
- info = (WFDStrmInfo_t *)wmt_pcm_wfd_get_strm((WFDStrmInfo_t *)arg);
- return __put_user((int)info, (unsigned int __user *) arg);
-
- case WMT_SOC_IOCTL_WFD_STOP:
- wmt_pcm_wfd_stop();
- return 0;
-
- case WMT_SOC_IOCTL_VT1603_RD:
- ret = copy_from_user(&vt1603_info, (void __user *)arg, sizeof(vt1603_info));
-
- if (ret == 0) {
- vt1603_info.reg_value = vt1603_hwdep_ioctl(0, vt1603_info.reg_offset, vt1603_info.reg_value);
- printk("<<<%s read reg 0x%x val 0x%x\n", __FUNCTION__, vt1603_info.reg_offset, vt1603_info.reg_value);
- ret = copy_to_user((void __user *)arg, &vt1603_info, sizeof(vt1603_info));
- }
- return ret;
- case WMT_SOC_IOCTL_VT1603_WR:
- ret = copy_from_user(&vt1603_info, (void __user *)arg, sizeof(vt1603_info));
- printk("<<<%s write reg 0x%x val 0x%x\n", __FUNCTION__, vt1603_info.reg_offset, vt1603_info.reg_value);
- if (ret == 0)
- vt1603_hwdep_ioctl(1, vt1603_info.reg_offset, vt1603_info.reg_value);
- return ret;
-
- case WMT_SOC_IOCTL_CH_SEL:
- value = (int __user *)arg;
-
- if (*value > 2) {
- printk("Not supported for CH select %d", *value);
- return 0;
- }
- wmt_i2s_ch_sel(*value);
- return 0;
-
- default:
- break;
- }
-
- printk("Not supported ioctl for WMT-HWDEP");
- return -ENOIOCTLCMD;
-}
-
-static long wmt_hwdep_write(struct snd_hwdep *hw, const char __user *buf,
- long count, loff_t *offset)
-{
- char string[3];
- //int mode;
- memset(string, 0, sizeof(string));
- copy_from_user(&string, buf, sizeof(string));
- printk("<<<%s %s\n", __FUNCTION__, string);
- if (!memcmp(string, "LL", 2)) {
- gmode = 0;
- }
- else if (!memcmp(string, "RR", 2)) {
- gmode = 1;
- }
- else if (!memcmp(string, "LR", 2)) {
- gmode = 2;
- }
- else {
- printk("Not supported for CH select");
- return count;
- }
-
- memset(gstring, 0, sizeof(gstring));
- strncpy(gstring, string, sizeof(string));
- wmt_i2s_ch_sel(gmode);
- return count;
-}
-
-static long wmt_hwdep_read(struct snd_hwdep *hw, char __user *buf,
- long count, loff_t *offset)
-{
- int len = 0;
- printk("%s string %s --> mode %d\n", __FUNCTION__, gstring, gmode);
- len = copy_to_user(buf, gstring, sizeof(gstring));
-
- return sizeof(gstring);
-}
-
-static long wmt_hwdep_write_1(struct snd_hwdep *hw, const char __user *buf,
- long count, loff_t *offset)
-{
- char string[5];
- //int mode;
-
- copy_from_user(&string, buf, sizeof(string));
- printk("<<<%s %s\n", __FUNCTION__, string);
- if (!memcmp(string, "NONE", 4)) {
- gSpHd = 3;
- }
- else if (!memcmp(string, "HDMI", 4)) {
- gSpHd = 4;
- }
- else if (!memcmp(string, "SPDIF", 5)) {
- gSpHd = 5;
- }
- else if (!memcmp(string, "BOTH", 4)) {
- gSpHd = 6;
- }
- else {
- printk("Not supported for SPDIF/HDMI switch");
- return count;
- }
-
- memset(gSpdHdm, 0, sizeof(gSpdHdm));
- strncpy(gSpdHdm, string, sizeof(string));
-
- wmt_i2s_ch_sel(gSpHd);
- return count;
-}
-
-
-static long wmt_hwdep_read_1(struct snd_hwdep *hw, char __user *buf,
- long count, loff_t *offset)
-{
- int len = 0;
- printk("%s string %s --> mode %d\n", __FUNCTION__, gSpdHdm, gSpHd);
- len = copy_to_user(buf, gSpdHdm, sizeof(gSpdHdm));
-
- return sizeof(gstring);
-}
-
-void wmt_soc_hwdep_new(struct snd_soc_codec *codec)
-{
- struct snd_hwdep *hwdep;
- struct snd_hwdep *hwdep_1;
- if (snd_hwdep_new(codec->card->snd_card, "WMT-HWDEP", 0, &hwdep) < 0) {
- printk("create WMT-HWDEP_0 fail");
- return;
- }
-
- sprintf(hwdep->name, "WMT-HWDEP %d", 0);
-
- hwdep->iface = SNDRV_HWDEP_IFACE_WMT;
- hwdep->ops.open = wmt_hwdep_open;
- hwdep->ops.ioctl = wmt_hwdep_ioctl;
- hwdep->ops.release = wmt_hwdep_release;
- hwdep->ops.mmap = wmt_hwdep_mmap;
- hwdep->ops.write = wmt_hwdep_write;
- hwdep->ops.read = wmt_hwdep_read;
-
- if (snd_hwdep_new(codec->card->snd_card, "WMT-HWDEP", 1, &hwdep_1) < 0) {
- printk("create WMT-HWDEP_1 fail");
- return;
- }
-
- sprintf(hwdep_1->name, "WMT-HWDEP %d", 1);
- printk("create %s success", hwdep_1->name);
-
- hwdep_1->iface = SNDRV_HWDEP_IFACE_WMT;
- hwdep_1->ops.write = wmt_hwdep_write_1;
- hwdep_1->ops.read = wmt_hwdep_read_1;
-}
-
diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.h b/ANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.h
deleted file mode 100755
index c95d5e9e..00000000
--- a/ANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*++
- * linux/sound/soc/wmt/wmt_hwdep.h
- * WonderMedia I2S audio driver for ALSA
- *
- * Copyright c 2010 WonderMedia Technologies, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * WonderMedia Technologies, Inc.
- * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
---*/
-
-/*
- * ioctls for Hardware Dependant Interface
- */
-#ifndef __WMT_HWDEP_H__
-#define __WMT_HWDEP_H__
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/hwdep.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-
-struct wmt_soc_vt1603_info {
- u16 reg_offset;
- u16 reg_value;
-};//add 2013-9-2 for vt1603 eq apk
-
-#define WMT_SOC_IOCTL_HDMI _IOWR('H', 0x10, int)
-#define WMT_SOC_IOCTL_WFD_START _IOWR('H', 0x20, int)
-#define WMT_SOC_IOCTL_GET_STRM _IOWR('H', 0x30, int)
-#define WMT_SOC_IOCTL_WFD_STOP _IOWR('H', 0x40, int)
-#define WMT_SOC_IOCTL_VT1603_RD _IOWR('H', 0x50, int)
-#define WMT_SOC_IOCTL_VT1603_WR _IOWR('H', 0x60, int)
-#define WMT_SOC_IOCTL_CH_SEL _IOWR('H', 0x70, int)
-void wmt_soc_hwdep_new(struct snd_soc_codec *codec);
-
-extern int vt1603_hwdep_ioctl(u8 rw_flag, u16 offset, u16 value);
-extern void wmt_i2s_ch_sel(int ch_sel_num);
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt_swmixer.c b/ANDROID_3.4.5/sound/soc/wmt/wmt_swmixer.c
deleted file mode 100755
index 4d92a81f..00000000
--- a/ANDROID_3.4.5/sound/soc/wmt/wmt_swmixer.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*++
- * linux/sound/soc/wmt/wmt_swmixer.c
- * WonderMedia I2S audio driver for ALSA
- *
- * Copyright c 2010 WonderMedia Technologies, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * WonderMedia Technologies, Inc.
- * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
---*/
-
-
-#include "wmt_swmixer.h"
-#include <sound/asound.h>
-
-
-
-void wmt_sw_u2s(int fmt, char *buffer, unsigned int chunksize)
-{
- unsigned int index;
- if (fmt == SNDRV_PCM_FORMAT_U8) {
- for (index = 0; index < chunksize; ++index)
- *(buffer + index) ^= 0x80;
- }
-
-}
-
-
-void wmt_pcm_fmt_trans(int fmt, int channel, char *src_buf, char *dst_buf, unsigned int chunksize)
-{
- unsigned int index = 0;
- float_data_t f_data;
- unsigned short data;
-
- /* always convert to 2ch, s16le (4 bytes) */
- if ((fmt == SNDRV_PCM_FORMAT_S16_LE) && (channel == 1)) {
- /* transfer from 1ch s16le(2 bytes) to 2ch s16le(4 bytes) */
- for (index = 0; index < (chunksize / 2); ++index) {
- *((unsigned int *)dst_buf + index) = (*((unsigned short *)src_buf + index) << 16 |
- *((unsigned short *)src_buf + index));
- }
- }
- else if ((fmt == SNDRV_PCM_FORMAT_U8) && (channel == 1)) {
- /* transfer from 1ch U8(1 bytes) to 2ch s16le(4 bytes) */
- for (index = 0; index < chunksize; ++index) {
- /* padding zero to byte 0 & byte 2 */
- *((unsigned int *)dst_buf + index) = (*((unsigned char *)src_buf + index) << 24 |
- *((unsigned char *)src_buf + index) << 8);
- }
- }
- else if ((fmt == SNDRV_PCM_FORMAT_U8) && (channel == 2)) {
- /* transfer from 2ch U8(2 bytes) to 2ch s16le(4 bytes) */
- for (index = 0; index < chunksize; ++index) {
- /* padding zero to byte 0 */
- *((unsigned short *)dst_buf + index) = *((unsigned char *)src_buf + index) << 8;
- }
- }
- else if ((fmt == SNDRV_PCM_FORMAT_FLOAT) && (channel == 2)) {
- /* transfer from 2ch float(8 bytes) to 2ch s16le(4 bytes) */
- for (index = 0; index < (chunksize / 4); ++index) {
- f_data = *((float_data_t *)src_buf + index);
-
- if (!f_data.sign) {
- data = (f_data.frac + 0x800000) >> (8 - (f_data.exp - 127));
- }
- else {
- data = ~((f_data.frac + 0x800000) >> (8 - (f_data.exp - 127))) + 1;
- }
-
- *((unsigned short *)dst_buf + index) = data;
- }
- }
- else if ((fmt == SNDRV_PCM_FORMAT_FLOAT) && (channel == 1)) {
- /* transfer from 1ch float(4 bytes) to 2ch s16le(4 bytes) */
- for (index = 0; index < (chunksize / 4); ++index) {
- f_data = *((float_data_t *)src_buf + index);
-
- if (!f_data.sign) {
- data = (unsigned short)((f_data.frac + 0x800000) >> (8 - (f_data.exp - 127)));
- }
- else {
- data = (unsigned short)(~((f_data.frac + 0x800000) >> (8 - (f_data.exp - 127))) + 1);
- }
-
- *((unsigned int *)dst_buf + index) = (data << 16) | data;
- }
- }
-}
-
diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt_swmixer.h b/ANDROID_3.4.5/sound/soc/wmt/wmt_swmixer.h
deleted file mode 100755
index 3163e5af..00000000
--- a/ANDROID_3.4.5/sound/soc/wmt/wmt_swmixer.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*++
- * linux/sound/soc/wmt/wmt_swmixer.h
- * WonderMedia I2S audio driver for ALSA
- *
- * Copyright c 2010 WonderMedia Technologies, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * WonderMedia Technologies, Inc.
- * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
---*/
-
-
-typedef struct float_data {
- unsigned long frac : 23;
- unsigned long exp : 8;
- unsigned long sign : 1;
-} float_data_t;
-
-void wmt_sw_u2s(int fmt, char *buffer, unsigned int chunksize);
-void wmt_pcm_fmt_trans(int fmt, int channel, char *src_buf, char *dst_buf, unsigned int chunksize);
-
diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt_wm8994.c b/ANDROID_3.4.5/sound/soc/wmt/wmt_wm8994.c
deleted file mode 100755
index 8d4cebf9..00000000
--- a/ANDROID_3.4.5/sound/soc/wmt/wmt_wm8994.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * wmt_wm8994.c
- *
- * Copyright (C) 2010 Samsung Electronics Co.Ltd
- * Author: Chanwoo Choi <cw00.choi@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <sound/soc.h>
-#include <sound/jack.h>
-
-#include <asm/mach-types.h>
-#include <mach/gpio.h>
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc-dapm.h>
-#include <sound/hwdep.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-
-#include "wmt-soc.h"
-#include "wmt-pcm.h"
-#include "wmt_hwdep.h"
-#include "../codecs/wm8994.h"
-#include <linux/mfd/wm8994/registers.h>
-#include <linux/mfd/wm8994/core.h>
-
-#include <linux/i2c.h>
-
-static struct snd_soc_card wmt;
-static struct platform_device *wmt_snd_device;
-static int wmt_incall = 0;
-
-extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
-extern void wmt_set_i2s_share_pin(void);
-
-static const struct snd_pcm_hardware wmt_voice_hardware = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rate_min = 8000,
- .rate_max = 8000,
- .period_bytes_min = 16,
- .period_bytes_max = 4 * 1024,
- .periods_min = 2,
- .periods_max = 16,
- .buffer_bytes_max = 16 * 1024,
-};
-
-static int wmt_snd_suspend_post(struct snd_soc_card *card)
-{
- /* Disable BIT15:I2S clock, BIT4:ARFP clock, BIT3:ARF clock */
- PMCEU_VAL &= ~(BIT15 | BIT4 | BIT3);
- return 0;
-}
-
-static int wmt_snd_resume_pre(struct snd_soc_card *card)
-{
- /* Enable MCLK before VT1602 codec enable, otherwise the codec will be disabled. */
-
- /* set to 24.576MHz */
- auto_pll_divisor(DEV_I2S, CLK_ENABLE , 0, 0);
- auto_pll_divisor(DEV_I2S, SET_PLLDIV, 1, 24576);
- /* Enable BIT4:ARFP clock, BIT3:ARF clock */
- PMCEU_VAL |= (BIT4 | BIT3);
- /* Enable BIT2:AUD clock */
- PMCE3_VAL |= BIT2;
-
- wmt_set_i2s_share_pin();
-
- return 0;
-}
-
-static int wmt_wm8994_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int ret = 0;
- unsigned int pll_in = 48000;
- unsigned int pll_out = 12000000;
-
- /* Set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_LRCLK,
- pll_in, pll_out);
- if (ret < 0)
- return ret;
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, pll_out,
- SND_SOC_CLOCK_IN);
-
- wmt_soc_hwdep_new(rtd->codec);
-
- return 0;
-}
-
-static int wmt_hifi_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
- unsigned int pll_in = 48000;
- unsigned int pll_out = 12000000;
-
- /* Set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF);
- if (ret< 0) {
- printk("<<ret:%d snd_soc_dai_set_fmt(codec) hifi\n", ret);
- return ret;
- }
-
- /* Set cpu DAI configuration for I2S */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S);
- if (ret < 0) {
- printk("<<ret:%d snd_soc_dai_set_fmt(cpu) hifi\n", ret);
- return ret;
- }
-
- /* Set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_LRCLK,
- pll_in, pll_out);
- if (ret < 0) {
- printk("<<ret:%d snd_soc_dai_set_pll hifi\n", ret);
- return ret;
- }
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, pll_out,
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- printk("<<ret:%d snd_soc_dai_set_sysclk hifi\n", ret);
-
- if (!wmt_incall)
- snd_soc_update_bits(codec_dai->codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, 0);
-
- return 0;
-}
-
-static int wmt_voice_startup(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- int ret;
-
- ret = snd_soc_set_runtime_hwparams(substream, &wmt_voice_hardware);
-
- /* Ensure that buffer size is a multiple of period size */
- ret = snd_pcm_hw_constraint_integer(runtime,SNDRV_PCM_HW_PARAM_PERIODS);
- return ret;
-}
-
-static int wmt_voice_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int ret = 0;
- unsigned int pll_in = 2048000;
- unsigned int pll_out = 12288000;
-
- if (params_rate(params) != 8000)
- return -EINVAL;
-
- /* Set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A |
- SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0) {
- printk("<<ret:%d snd_soc_dai_set_fmt voice\n", ret);
- return ret;
- }
-
- /* Set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, WM8994_FLL_SRC_BCLK,
- pll_in, pll_out);
- if (ret < 0) {
- printk("<<ret:%d snd_soc_dai_set_pll voice\n", ret);
- return ret;
- }
- ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2, pll_out,
- SND_SOC_CLOCK_IN);
- if (ret < 0)
- printk("<<ret:%d snd_soc_dai_set_sysclk voice\n", ret);
-
- wmt_incall = 1;
- return ret;
-}
-
-static int wmt_voice_hw_free(struct snd_pcm_substream *substream)
-{
- wmt_incall = 0;
- return 0;
-}
-
-static struct snd_soc_ops wmt_hifi_ops = {
- .hw_params = wmt_hifi_hw_params,
-};
-
-static struct snd_soc_ops wmt_voice_ops = {
- .startup = wmt_voice_startup,
- .hw_params = wmt_voice_hw_params,
- .hw_free = wmt_voice_hw_free,
-};
-
-static struct snd_soc_dai_driver voice_dai[] = {
- {
- .name = "wmt-voice-dai",
- .playback = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- .capture = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
- },
-};
-
-static struct snd_soc_dai_link wmt_dai[] = {
- {
- .name = "WM8994",
- .stream_name = "WM8994 HiFi",
- .cpu_dai_name = "wmt-i2s.0",
- .codec_dai_name = "wm8994-aif1",
- .platform_name = "wmt-audio-pcm.0",
- .codec_name = "wm8994-codec",
- .init = wmt_wm8994_init,
- .ops = &wmt_hifi_ops,
- },
- {
- .name = "WM8994 Voice",
- .stream_name = "Voice",
- .cpu_dai_name = "wmt-voice-dai",
- .codec_dai_name = "wm8994-aif2",
- .codec_name = "wm8994-codec",
- .ops = &wmt_voice_ops,
- },
-};
-
-static struct snd_soc_card wmt = {
- .name = "WMT_WM8994",
- .dai_link = wmt_dai,
- .num_links = ARRAY_SIZE(wmt_dai),
- .suspend_post = wmt_snd_suspend_post,
- .resume_pre = wmt_snd_resume_pre,
-};
-
-static int __init wmt_init(void)
-{
- int ret;
- char buf[128];
- int len = ARRAY_SIZE(buf);
-
- if (wmt_getsyspara("wmt.audio.i2s", buf, &len) != 0)
- return -EINVAL;
-
- if (strncmp(buf, "wm8994", strlen("wm8994")))
- return -ENODEV;
-
- wmt_snd_device = platform_device_alloc("soc-audio", -1);
- if (!wmt_snd_device)
- return -ENOMEM;
-
- /* register voice DAI here */
- ret = snd_soc_register_dais(&wmt_snd_device->dev, voice_dai, ARRAY_SIZE(voice_dai));
- if (ret) {
- platform_device_put(wmt_snd_device);
- return ret;
- }
-
- platform_set_drvdata(wmt_snd_device, &wmt);
- ret = platform_device_add(wmt_snd_device);
-
- if (ret) {
- snd_soc_unregister_dai(&wmt_snd_device->dev);
- platform_device_put(wmt_snd_device);
- }
-
- return ret;
-}
-
-static void __exit wmt_exit(void)
-{
- snd_soc_unregister_dai(&wmt_snd_device->dev);
- platform_device_unregister(wmt_snd_device);
-}
-
-module_init(wmt_init);
-module_exit(wmt_exit);
-
-MODULE_DESCRIPTION("ALSA SoC WM8994 WMT(wm8950)");
-MODULE_AUTHOR("Loonzhong <Loonzhong@wondermedia.com.cn>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/sound_core.c b/ANDROID_3.4.5/sound/sound_core.c
deleted file mode 100644
index c6e81fb9..00000000
--- a/ANDROID_3.4.5/sound/sound_core.c
+++ /dev/null
@@ -1,670 +0,0 @@
-/*
- * Sound core. This file is composed of two parts. sound_class
- * which is common to both OSS and ALSA and OSS sound core which
- * is used OSS or emulation of it.
- */
-
-/*
- * First, the common part.
- */
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/err.h>
-#include <linux/kdev_t.h>
-#include <linux/major.h>
-#include <sound/core.h>
-
-#ifdef CONFIG_SOUND_OSS_CORE
-static int __init init_oss_soundcore(void);
-static void cleanup_oss_soundcore(void);
-#else
-static inline int init_oss_soundcore(void) { return 0; }
-static inline void cleanup_oss_soundcore(void) { }
-#endif
-
-struct class *sound_class;
-EXPORT_SYMBOL(sound_class);
-
-MODULE_DESCRIPTION("Core sound module");
-MODULE_AUTHOR("Alan Cox");
-MODULE_LICENSE("GPL");
-
-static char *sound_devnode(struct device *dev, umode_t *mode)
-{
- if (MAJOR(dev->devt) == SOUND_MAJOR)
- return NULL;
- return kasprintf(GFP_KERNEL, "snd/%s", dev_name(dev));
-}
-
-static int __init init_soundcore(void)
-{
- int rc;
-
- rc = init_oss_soundcore();
- if (rc)
- return rc;
-
- sound_class = class_create(THIS_MODULE, "sound");
- if (IS_ERR(sound_class)) {
- cleanup_oss_soundcore();
- return PTR_ERR(sound_class);
- }
-
- sound_class->devnode = sound_devnode;
-
- return 0;
-}
-
-static void __exit cleanup_soundcore(void)
-{
- cleanup_oss_soundcore();
- class_destroy(sound_class);
-}
-
-subsys_initcall(init_soundcore);
-module_exit(cleanup_soundcore);
-
-
-#ifdef CONFIG_SOUND_OSS_CORE
-/*
- * OSS sound core handling. Breaks out sound functions to submodules
- *
- * Author: Alan Cox <alan@lxorguk.ukuu.org.uk>
- *
- * Fixes:
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * --------------------
- *
- * Top level handler for the sound subsystem. Various devices can
- * plug into this. The fact they don't all go via OSS doesn't mean
- * they don't have to implement the OSS API. There is a lot of logic
- * to keeping much of the OSS weight out of the code in a compatibility
- * module, but it's up to the driver to rember to load it...
- *
- * The code provides a set of functions for registration of devices
- * by type. This is done rather than providing a single call so that
- * we can hide any future changes in the internals (eg when we go to
- * 32bit dev_t) from the modules and their interface.
- *
- * Secondly we need to allocate the dsp, dsp16 and audio devices as
- * one. Thus we misuse the chains a bit to simplify this.
- *
- * Thirdly to make it more fun and for 2.3.x and above we do all
- * of this using fine grained locking.
- *
- * FIXME: we have to resolve modules and fine grained load/unload
- * locking at some point in 2.3.x.
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sound.h>
-#include <linux/kmod.h>
-
-#define SOUND_STEP 16
-
-struct sound_unit
-{
- int unit_minor;
- const struct file_operations *unit_fops;
- struct sound_unit *next;
- char name[32];
-};
-
-#ifdef CONFIG_SOUND_MSNDCLAS
-extern int msnd_classic_init(void);
-#endif
-#ifdef CONFIG_SOUND_MSNDPIN
-extern int msnd_pinnacle_init(void);
-#endif
-
-/*
- * By default, OSS sound_core claims full legacy minor range (0-255)
- * of SOUND_MAJOR to trap open attempts to any sound minor and
- * requests modules using custom sound-slot/service-* module aliases.
- * The only benefit of doing this is allowing use of custom module
- * aliases instead of the standard char-major-* ones. This behavior
- * prevents alternative OSS implementation and is scheduled to be
- * removed.
- *
- * CONFIG_SOUND_OSS_CORE_PRECLAIM and soundcore.preclaim_oss kernel
- * parameter are added to allow distros and developers to try and
- * switch to alternative implementations without needing to rebuild
- * the kernel in the meantime. If preclaim_oss is non-zero, the
- * kernel will behave the same as before. All SOUND_MAJOR minors are
- * preclaimed and the custom module aliases along with standard chrdev
- * ones are emitted if a missing device is opened. If preclaim_oss is
- * zero, sound_core only grabs what's actually in use and for missing
- * devices only the standard chrdev aliases are requested.
- *
- * All these clutters are scheduled to be removed along with
- * sound-slot/service-* module aliases. Please take a look at
- * feature-removal-schedule.txt for details.
- */
-#ifdef CONFIG_SOUND_OSS_CORE_PRECLAIM
-static int preclaim_oss = 1;
-#else
-static int preclaim_oss = 0;
-#endif
-
-module_param(preclaim_oss, int, 0444);
-
-static int soundcore_open(struct inode *, struct file *);
-
-static const struct file_operations soundcore_fops =
-{
- /* We must have an owner or the module locking fails */
- .owner = THIS_MODULE,
- .open = soundcore_open,
- .llseek = noop_llseek,
-};
-
-/*
- * Low level list operator. Scan the ordered list, find a hole and
- * join into it. Called with the lock asserted
- */
-
-static int __sound_insert_unit(struct sound_unit * s, struct sound_unit **list, const struct file_operations *fops, int index, int low, int top)
-{
- int n=low;
-
- if (index < 0) { /* first free */
-
- while (*list && (*list)->unit_minor<n)
- list=&((*list)->next);
-
- while(n<top)
- {
- /* Found a hole ? */
- if(*list==NULL || (*list)->unit_minor>n)
- break;
- list=&((*list)->next);
- n+=SOUND_STEP;
- }
-
- if(n>=top)
- return -ENOENT;
- } else {
- n = low+(index*16);
- while (*list) {
- if ((*list)->unit_minor==n)
- return -EBUSY;
- if ((*list)->unit_minor>n)
- break;
- list=&((*list)->next);
- }
- }
-
- /*
- * Fill it in
- */
-
- s->unit_minor=n;
- s->unit_fops=fops;
-
- /*
- * Link it
- */
-
- s->next=*list;
- *list=s;
-
-
- return n;
-}
-
-/*
- * Remove a node from the chain. Called with the lock asserted
- */
-
-static struct sound_unit *__sound_remove_unit(struct sound_unit **list, int unit)
-{
- while(*list)
- {
- struct sound_unit *p=*list;
- if(p->unit_minor==unit)
- {
- *list=p->next;
- return p;
- }
- list=&(p->next);
- }
- printk(KERN_ERR "Sound device %d went missing!\n", unit);
- return NULL;
-}
-
-/*
- * This lock guards the sound loader list.
- */
-
-static DEFINE_SPINLOCK(sound_loader_lock);
-
-/*
- * Allocate the controlling structure and add it to the sound driver
- * list. Acquires locks as needed
- */
-
-static int sound_insert_unit(struct sound_unit **list, const struct file_operations *fops, int index, int low, int top, const char *name, umode_t mode, struct device *dev)
-{
- struct sound_unit *s = kmalloc(sizeof(*s), GFP_KERNEL);
- int r;
-
- if (!s)
- return -ENOMEM;
-
- spin_lock(&sound_loader_lock);
-retry:
- r = __sound_insert_unit(s, list, fops, index, low, top);
- spin_unlock(&sound_loader_lock);
-
- if (r < 0)
- goto fail;
- else if (r < SOUND_STEP)
- sprintf(s->name, "sound/%s", name);
- else
- sprintf(s->name, "sound/%s%d", name, r / SOUND_STEP);
-
- if (!preclaim_oss) {
- /*
- * Something else might have grabbed the minor. If
- * first free slot is requested, rescan with @low set
- * to the next unit; otherwise, -EBUSY.
- */
- r = __register_chrdev(SOUND_MAJOR, s->unit_minor, 1, s->name,
- &soundcore_fops);
- if (r < 0) {
- spin_lock(&sound_loader_lock);
- __sound_remove_unit(list, s->unit_minor);
- if (index < 0) {
- low = s->unit_minor + SOUND_STEP;
- goto retry;
- }
- spin_unlock(&sound_loader_lock);
- return -EBUSY;
- }
- }
-
- device_create(sound_class, dev, MKDEV(SOUND_MAJOR, s->unit_minor),
- NULL, s->name+6);
- return s->unit_minor;
-
-fail:
- kfree(s);
- return r;
-}
-
-/*
- * Remove a unit. Acquires locks as needed. The drivers MUST have
- * completed the removal before their file operations become
- * invalid.
- */
-
-static void sound_remove_unit(struct sound_unit **list, int unit)
-{
- struct sound_unit *p;
-
- spin_lock(&sound_loader_lock);
- p = __sound_remove_unit(list, unit);
- spin_unlock(&sound_loader_lock);
- if (p) {
- if (!preclaim_oss)
- __unregister_chrdev(SOUND_MAJOR, p->unit_minor, 1,
- p->name);
- device_destroy(sound_class, MKDEV(SOUND_MAJOR, p->unit_minor));
- kfree(p);
- }
-}
-
-/*
- * Allocations
- *
- * 0 *16 Mixers
- * 1 *8 Sequencers
- * 2 *16 Midi
- * 3 *16 DSP
- * 4 *16 SunDSP
- * 5 *16 DSP16
- * 6 -- sndstat (obsolete)
- * 7 *16 unused
- * 8 -- alternate sequencer (see above)
- * 9 *16 raw synthesizer access
- * 10 *16 unused
- * 11 *16 unused
- * 12 *16 unused
- * 13 *16 unused
- * 14 *16 unused
- * 15 *16 unused
- */
-
-static struct sound_unit *chains[SOUND_STEP];
-
-/**
- * register_sound_special_device - register a special sound node
- * @fops: File operations for the driver
- * @unit: Unit number to allocate
- * @dev: device pointer
- *
- * Allocate a special sound device by minor number from the sound
- * subsystem. The allocated number is returned on success. On failure
- * a negative error code is returned.
- */
-
-int register_sound_special_device(const struct file_operations *fops, int unit,
- struct device *dev)
-{
- const int chain = unit % SOUND_STEP;
- int max_unit = 128 + chain;
- const char *name;
- char _name[16];
-
- switch (chain) {
- case 0:
- name = "mixer";
- break;
- case 1:
- name = "sequencer";
- if (unit >= SOUND_STEP)
- goto __unknown;
- max_unit = unit + 1;
- break;
- case 2:
- name = "midi";
- break;
- case 3:
- name = "dsp";
- break;
- case 4:
- name = "audio";
- break;
- case 5:
- name = "dspW";
- break;
- case 8:
- name = "sequencer2";
- if (unit >= SOUND_STEP)
- goto __unknown;
- max_unit = unit + 1;
- break;
- case 9:
- name = "dmmidi";
- break;
- case 10:
- name = "dmfm";
- break;
- case 12:
- name = "adsp";
- break;
- case 13:
- name = "amidi";
- break;
- case 14:
- name = "admmidi";
- break;
- default:
- {
- __unknown:
- sprintf(_name, "unknown%d", chain);
- if (unit >= SOUND_STEP)
- strcat(_name, "-");
- name = _name;
- }
- break;
- }
- return sound_insert_unit(&chains[chain], fops, -1, unit, max_unit,
- name, S_IRUSR | S_IWUSR, dev);
-}
-
-EXPORT_SYMBOL(register_sound_special_device);
-
-int register_sound_special(const struct file_operations *fops, int unit)
-{
- return register_sound_special_device(fops, unit, NULL);
-}
-
-EXPORT_SYMBOL(register_sound_special);
-
-/**
- * register_sound_mixer - register a mixer device
- * @fops: File operations for the driver
- * @dev: Unit number to allocate
- *
- * Allocate a mixer device. Unit is the number of the mixer requested.
- * Pass -1 to request the next free mixer unit. On success the allocated
- * number is returned, on failure a negative error code is returned.
- */
-
-int register_sound_mixer(const struct file_operations *fops, int dev)
-{
- return sound_insert_unit(&chains[0], fops, dev, 0, 128,
- "mixer", S_IRUSR | S_IWUSR, NULL);
-}
-
-EXPORT_SYMBOL(register_sound_mixer);
-
-/**
- * register_sound_midi - register a midi device
- * @fops: File operations for the driver
- * @dev: Unit number to allocate
- *
- * Allocate a midi device. Unit is the number of the midi device requested.
- * Pass -1 to request the next free midi unit. On success the allocated
- * number is returned, on failure a negative error code is returned.
- */
-
-int register_sound_midi(const struct file_operations *fops, int dev)
-{
- return sound_insert_unit(&chains[2], fops, dev, 2, 130,
- "midi", S_IRUSR | S_IWUSR, NULL);
-}
-
-EXPORT_SYMBOL(register_sound_midi);
-
-/*
- * DSP's are registered as a triple. Register only one and cheat
- * in open - see below.
- */
-
-/**
- * register_sound_dsp - register a DSP device
- * @fops: File operations for the driver
- * @dev: Unit number to allocate
- *
- * Allocate a DSP device. Unit is the number of the DSP requested.
- * Pass -1 to request the next free DSP unit. On success the allocated
- * number is returned, on failure a negative error code is returned.
- *
- * This function allocates both the audio and dsp device entries together
- * and will always allocate them as a matching pair - eg dsp3/audio3
- */
-
-int register_sound_dsp(const struct file_operations *fops, int dev)
-{
- return sound_insert_unit(&chains[3], fops, dev, 3, 131,
- "dsp", S_IWUSR | S_IRUSR, NULL);
-}
-
-EXPORT_SYMBOL(register_sound_dsp);
-
-/**
- * unregister_sound_special - unregister a special sound device
- * @unit: unit number to allocate
- *
- * Release a sound device that was allocated with
- * register_sound_special(). The unit passed is the return value from
- * the register function.
- */
-
-
-void unregister_sound_special(int unit)
-{
- sound_remove_unit(&chains[unit % SOUND_STEP], unit);
-}
-
-EXPORT_SYMBOL(unregister_sound_special);
-
-/**
- * unregister_sound_mixer - unregister a mixer
- * @unit: unit number to allocate
- *
- * Release a sound device that was allocated with register_sound_mixer().
- * The unit passed is the return value from the register function.
- */
-
-void unregister_sound_mixer(int unit)
-{
- sound_remove_unit(&chains[0], unit);
-}
-
-EXPORT_SYMBOL(unregister_sound_mixer);
-
-/**
- * unregister_sound_midi - unregister a midi device
- * @unit: unit number to allocate
- *
- * Release a sound device that was allocated with register_sound_midi().
- * The unit passed is the return value from the register function.
- */
-
-void unregister_sound_midi(int unit)
-{
- sound_remove_unit(&chains[2], unit);
-}
-
-EXPORT_SYMBOL(unregister_sound_midi);
-
-/**
- * unregister_sound_dsp - unregister a DSP device
- * @unit: unit number to allocate
- *
- * Release a sound device that was allocated with register_sound_dsp().
- * The unit passed is the return value from the register function.
- *
- * Both of the allocated units are released together automatically.
- */
-
-void unregister_sound_dsp(int unit)
-{
- sound_remove_unit(&chains[3], unit);
-}
-
-
-EXPORT_SYMBOL(unregister_sound_dsp);
-
-static struct sound_unit *__look_for_unit(int chain, int unit)
-{
- struct sound_unit *s;
-
- s=chains[chain];
- while(s && s->unit_minor <= unit)
- {
- if(s->unit_minor==unit)
- return s;
- s=s->next;
- }
- return NULL;
-}
-
-static int soundcore_open(struct inode *inode, struct file *file)
-{
- int chain;
- int unit = iminor(inode);
- struct sound_unit *s;
- const struct file_operations *new_fops = NULL;
-
- chain=unit&0x0F;
- if(chain==4 || chain==5) /* dsp/audio/dsp16 */
- {
- unit&=0xF0;
- unit|=3;
- chain=3;
- }
-
- spin_lock(&sound_loader_lock);
- s = __look_for_unit(chain, unit);
- if (s)
- new_fops = fops_get(s->unit_fops);
- if (preclaim_oss && !new_fops) {
- spin_unlock(&sound_loader_lock);
-
- /*
- * Please, don't change this order or code.
- * For ALSA slot means soundcard and OSS emulation code
- * comes as add-on modules which aren't depend on
- * ALSA toplevel modules for soundcards, thus we need
- * load them at first. [Jaroslav Kysela <perex@jcu.cz>]
- */
- request_module("sound-slot-%i", unit>>4);
- request_module("sound-service-%i-%i", unit>>4, chain);
-
- /*
- * sound-slot/service-* module aliases are scheduled
- * for removal in favor of the standard char-major-*
- * module aliases. For the time being, generate both
- * the legacy and standard module aliases to ease
- * transition.
- */
- if (request_module("char-major-%d-%d", SOUND_MAJOR, unit) > 0)
- request_module("char-major-%d", SOUND_MAJOR);
-
- spin_lock(&sound_loader_lock);
- s = __look_for_unit(chain, unit);
- if (s)
- new_fops = fops_get(s->unit_fops);
- }
- if (new_fops) {
- /*
- * We rely upon the fact that we can't be unloaded while the
- * subdriver is there, so if ->open() is successful we can
- * safely drop the reference counter and if it is not we can
- * revert to old ->f_op. Ugly, indeed, but that's the cost of
- * switching ->f_op in the first place.
- */
- int err = 0;
- const struct file_operations *old_fops = file->f_op;
- file->f_op = new_fops;
- spin_unlock(&sound_loader_lock);
-
- if (file->f_op->open)
- err = file->f_op->open(inode,file);
-
- if (err) {
- fops_put(file->f_op);
- file->f_op = fops_get(old_fops);
- }
-
- fops_put(old_fops);
- return err;
- }
- spin_unlock(&sound_loader_lock);
- return -ENODEV;
-}
-
-MODULE_ALIAS_CHARDEV_MAJOR(SOUND_MAJOR);
-
-static void cleanup_oss_soundcore(void)
-{
- /* We have nothing to really do here - we know the lists must be
- empty */
- unregister_chrdev(SOUND_MAJOR, "sound");
-}
-
-static int __init init_oss_soundcore(void)
-{
- if (preclaim_oss &&
- register_chrdev(SOUND_MAJOR, "sound", &soundcore_fops) == -1) {
- printk(KERN_ERR "soundcore: sound device already in use.\n");
- return -EBUSY;
- }
-
- return 0;
-}
-
-#endif /* CONFIG_SOUND_OSS_CORE */
diff --git a/ANDROID_3.4.5/sound/sound_firmware.c b/ANDROID_3.4.5/sound/sound_firmware.c
deleted file mode 100644
index 7e962495..00000000
--- a/ANDROID_3.4.5/sound/sound_firmware.c
+++ /dev/null
@@ -1,78 +0,0 @@
-#include <linux/vmalloc.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <asm/uaccess.h>
-#include "oss/sound_firmware.h"
-
-static int do_mod_firmware_load(const char *fn, char **fp)
-{
- struct file* filp;
- long l;
- char *dp;
- loff_t pos;
-
- filp = filp_open(fn, 0, 0);
- if (IS_ERR(filp))
- {
- printk(KERN_INFO "Unable to load '%s'.\n", fn);
- return 0;
- }
- l = i_size_read(filp->f_path.dentry->d_inode);
- if (l <= 0 || l > 131072)
- {
- printk(KERN_INFO "Invalid firmware '%s'\n", fn);
- filp_close(filp, current->files);
- return 0;
- }
- dp = vmalloc(l);
- if (dp == NULL)
- {
- printk(KERN_INFO "Out of memory loading '%s'.\n", fn);
- filp_close(filp, current->files);
- return 0;
- }
- pos = 0;
- if (vfs_read(filp, dp, l, &pos) != l)
- {
- printk(KERN_INFO "Failed to read '%s'.\n", fn);
- vfree(dp);
- filp_close(filp, current->files);
- return 0;
- }
- filp_close(filp, current->files);
- *fp = dp;
- return (int) l;
-}
-
-/**
- * mod_firmware_load - load sound driver firmware
- * @fn: filename
- * @fp: return for the buffer.
- *
- * Load the firmware for a sound module (up to 128K) into a buffer.
- * The buffer is returned in *fp. It is allocated with vmalloc so is
- * virtually linear and not DMAable. The caller should free it with
- * vfree when finished.
- *
- * The length of the buffer is returned on a successful load, the
- * value zero on a failure.
- *
- * Caution: This API is not recommended. Firmware should be loaded via
- * request_firmware.
- */
-
-int mod_firmware_load(const char *fn, char **fp)
-{
- int r;
- mm_segment_t fs = get_fs();
-
- set_fs(get_ds());
- r = do_mod_firmware_load(fn, fp);
- set_fs(fs);
- return r;
-}
-EXPORT_SYMBOL(mod_firmware_load);
-
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/sparc/Kconfig b/ANDROID_3.4.5/sound/sparc/Kconfig
deleted file mode 100644
index d75deba5..00000000
--- a/ANDROID_3.4.5/sound/sparc/Kconfig
+++ /dev/null
@@ -1,41 +0,0 @@
-# ALSA Sparc drivers
-
-menuconfig SND_SPARC
- bool "Sparc sound devices"
- depends on SPARC
- default y
- help
- Support for sound devices specific to Sun SPARC architectures.
-
-if SND_SPARC
-
-config SND_SUN_AMD7930
- tristate "Sun AMD7930"
- depends on SBUS
- select SND_PCM
- help
- Say Y here to include support for AMD7930 sound device on Sun.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-sun-amd7930.
-
-config SND_SUN_CS4231
- tristate "Sun CS4231"
- select SND_PCM
- help
- Say Y here to include support for CS4231 sound device on Sun.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-sun-cs4231.
-
-config SND_SUN_DBRI
- tristate "Sun DBRI"
- depends on SBUS
- select SND_PCM
- help
- Say Y here to include support for DBRI sound device on Sun.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-sun-dbri.
-
-endif # SND_SPARC
diff --git a/ANDROID_3.4.5/sound/sparc/Makefile b/ANDROID_3.4.5/sound/sparc/Makefile
deleted file mode 100644
index 3cd89c67..00000000
--- a/ANDROID_3.4.5/sound/sparc/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2002 by David S. Miller <davem@redhat.com>
-#
-
-snd-sun-amd7930-objs := amd7930.o
-snd-sun-cs4231-objs := cs4231.o
-snd-sun-dbri-objs := dbri.o
-
-obj-$(CONFIG_SND_SUN_AMD7930) += snd-sun-amd7930.o
-obj-$(CONFIG_SND_SUN_CS4231) += snd-sun-cs4231.o
-obj-$(CONFIG_SND_SUN_DBRI) += snd-sun-dbri.o
diff --git a/ANDROID_3.4.5/sound/sparc/amd7930.c b/ANDROID_3.4.5/sound/sparc/amd7930.c
deleted file mode 100644
index b63b3a86..00000000
--- a/ANDROID_3.4.5/sound/sparc/amd7930.c
+++ /dev/null
@@ -1,1099 +0,0 @@
-/*
- * Driver for AMD7930 sound chips found on Sparcs.
- * Copyright (C) 2002, 2008 David S. Miller <davem@davemloft.net>
- *
- * Based entirely upon drivers/sbus/audio/amd7930.c which is:
- * Copyright (C) 1996,1997 Thomas K. Dyas (tdyas@eden.rutgers.edu)
- *
- * --- Notes from Thomas's original driver ---
- * This is the lowlevel driver for the AMD7930 audio chip found on all
- * sun4c machines and some sun4m machines.
- *
- * The amd7930 is actually an ISDN chip which has a very simple
- * integrated audio encoder/decoder. When Sun decided on what chip to
- * use for audio, they had the brilliant idea of using the amd7930 and
- * only connecting the audio encoder/decoder pins.
- *
- * Thanks to the AMD engineer who was able to get us the AMD79C30
- * databook which has all the programming information and gain tables.
- *
- * Advanced Micro Devices' Am79C30A is an ISDN/audio chip used in the
- * SparcStation 1+. The chip provides microphone and speaker interfaces
- * which provide mono-channel audio at 8K samples per second via either
- * 8-bit A-law or 8-bit mu-law encoding. Also, the chip features an
- * ISDN BRI Line Interface Unit (LIU), I.430 S/T physical interface,
- * which performs basic D channel LAPD processing and provides raw
- * B channel data. The digital audio channel, the two ISDN B channels,
- * and two 64 Kbps channels to the microprocessor are all interconnected
- * via a multiplexer.
- * --- End of notes from Thoamas's original driver ---
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/moduleparam.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/initval.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/prom.h>
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Sun AMD7930 soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Sun AMD7930 soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Sun AMD7930 soundcard.");
-MODULE_AUTHOR("Thomas K. Dyas and David S. Miller");
-MODULE_DESCRIPTION("Sun AMD7930");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Sun,AMD7930}}");
-
-/* Device register layout. */
-
-/* Register interface presented to the CPU by the amd7930. */
-#define AMD7930_CR 0x00UL /* Command Register (W) */
-#define AMD7930_IR AMD7930_CR /* Interrupt Register (R) */
-#define AMD7930_DR 0x01UL /* Data Register (R/W) */
-#define AMD7930_DSR1 0x02UL /* D-channel Status Register 1 (R) */
-#define AMD7930_DER 0x03UL /* D-channel Error Register (R) */
-#define AMD7930_DCTB 0x04UL /* D-channel Transmit Buffer (W) */
-#define AMD7930_DCRB AMD7930_DCTB /* D-channel Receive Buffer (R) */
-#define AMD7930_BBTB 0x05UL /* Bb-channel Transmit Buffer (W) */
-#define AMD7930_BBRB AMD7930_BBTB /* Bb-channel Receive Buffer (R) */
-#define AMD7930_BCTB 0x06UL /* Bc-channel Transmit Buffer (W) */
-#define AMD7930_BCRB AMD7930_BCTB /* Bc-channel Receive Buffer (R) */
-#define AMD7930_DSR2 0x07UL /* D-channel Status Register 2 (R) */
-
-/* Indirect registers in the Main Audio Processor. */
-struct amd7930_map {
- __u16 x[8];
- __u16 r[8];
- __u16 gx;
- __u16 gr;
- __u16 ger;
- __u16 stgr;
- __u16 ftgr;
- __u16 atgr;
- __u8 mmr1;
- __u8 mmr2;
-};
-
-/* After an amd7930 interrupt, reading the Interrupt Register (ir)
- * clears the interrupt and returns a bitmask indicating which
- * interrupt source(s) require service.
- */
-
-#define AMR_IR_DTTHRSH 0x01 /* D-channel xmit threshold */
-#define AMR_IR_DRTHRSH 0x02 /* D-channel recv threshold */
-#define AMR_IR_DSRI 0x04 /* D-channel packet status */
-#define AMR_IR_DERI 0x08 /* D-channel error */
-#define AMR_IR_BBUF 0x10 /* B-channel data xfer */
-#define AMR_IR_LSRI 0x20 /* LIU status */
-#define AMR_IR_DSR2I 0x40 /* D-channel buffer status */
-#define AMR_IR_MLTFRMI 0x80 /* multiframe or PP */
-
-/* The amd7930 has "indirect registers" which are accessed by writing
- * the register number into the Command Register and then reading or
- * writing values from the Data Register as appropriate. We define the
- * AMR_* macros to be the indirect register numbers and AM_* macros to
- * be bits in whatever register is referred to.
- */
-
-/* Initialization */
-#define AMR_INIT 0x21
-#define AM_INIT_ACTIVE 0x01
-#define AM_INIT_DATAONLY 0x02
-#define AM_INIT_POWERDOWN 0x03
-#define AM_INIT_DISABLE_INTS 0x04
-#define AMR_INIT2 0x20
-#define AM_INIT2_ENABLE_POWERDOWN 0x20
-#define AM_INIT2_ENABLE_MULTIFRAME 0x10
-
-/* Line Interface Unit */
-#define AMR_LIU_LSR 0xA1
-#define AM_LIU_LSR_STATE 0x07
-#define AM_LIU_LSR_F3 0x08
-#define AM_LIU_LSR_F7 0x10
-#define AM_LIU_LSR_F8 0x20
-#define AM_LIU_LSR_HSW 0x40
-#define AM_LIU_LSR_HSW_CHG 0x80
-#define AMR_LIU_LPR 0xA2
-#define AMR_LIU_LMR1 0xA3
-#define AM_LIU_LMR1_B1_ENABL 0x01
-#define AM_LIU_LMR1_B2_ENABL 0x02
-#define AM_LIU_LMR1_F_DISABL 0x04
-#define AM_LIU_LMR1_FA_DISABL 0x08
-#define AM_LIU_LMR1_REQ_ACTIV 0x10
-#define AM_LIU_LMR1_F8_F3 0x20
-#define AM_LIU_LMR1_LIU_ENABL 0x40
-#define AMR_LIU_LMR2 0xA4
-#define AM_LIU_LMR2_DECHO 0x01
-#define AM_LIU_LMR2_DLOOP 0x02
-#define AM_LIU_LMR2_DBACKOFF 0x04
-#define AM_LIU_LMR2_EN_F3_INT 0x08
-#define AM_LIU_LMR2_EN_F8_INT 0x10
-#define AM_LIU_LMR2_EN_HSW_INT 0x20
-#define AM_LIU_LMR2_EN_F7_INT 0x40
-#define AMR_LIU_2_4 0xA5
-#define AMR_LIU_MF 0xA6
-#define AMR_LIU_MFSB 0xA7
-#define AMR_LIU_MFQB 0xA8
-
-/* Multiplexor */
-#define AMR_MUX_MCR1 0x41
-#define AMR_MUX_MCR2 0x42
-#define AMR_MUX_MCR3 0x43
-#define AM_MUX_CHANNEL_B1 0x01
-#define AM_MUX_CHANNEL_B2 0x02
-#define AM_MUX_CHANNEL_Ba 0x03
-#define AM_MUX_CHANNEL_Bb 0x04
-#define AM_MUX_CHANNEL_Bc 0x05
-#define AM_MUX_CHANNEL_Bd 0x06
-#define AM_MUX_CHANNEL_Be 0x07
-#define AM_MUX_CHANNEL_Bf 0x08
-#define AMR_MUX_MCR4 0x44
-#define AM_MUX_MCR4_ENABLE_INTS 0x08
-#define AM_MUX_MCR4_REVERSE_Bb 0x10
-#define AM_MUX_MCR4_REVERSE_Bc 0x20
-#define AMR_MUX_1_4 0x45
-
-/* Main Audio Processor */
-#define AMR_MAP_X 0x61
-#define AMR_MAP_R 0x62
-#define AMR_MAP_GX 0x63
-#define AMR_MAP_GR 0x64
-#define AMR_MAP_GER 0x65
-#define AMR_MAP_STGR 0x66
-#define AMR_MAP_FTGR_1_2 0x67
-#define AMR_MAP_ATGR_1_2 0x68
-#define AMR_MAP_MMR1 0x69
-#define AM_MAP_MMR1_ALAW 0x01
-#define AM_MAP_MMR1_GX 0x02
-#define AM_MAP_MMR1_GR 0x04
-#define AM_MAP_MMR1_GER 0x08
-#define AM_MAP_MMR1_X 0x10
-#define AM_MAP_MMR1_R 0x20
-#define AM_MAP_MMR1_STG 0x40
-#define AM_MAP_MMR1_LOOPBACK 0x80
-#define AMR_MAP_MMR2 0x6A
-#define AM_MAP_MMR2_AINB 0x01
-#define AM_MAP_MMR2_LS 0x02
-#define AM_MAP_MMR2_ENABLE_DTMF 0x04
-#define AM_MAP_MMR2_ENABLE_TONEGEN 0x08
-#define AM_MAP_MMR2_ENABLE_TONERING 0x10
-#define AM_MAP_MMR2_DISABLE_HIGHPASS 0x20
-#define AM_MAP_MMR2_DISABLE_AUTOZERO 0x40
-#define AMR_MAP_1_10 0x6B
-#define AMR_MAP_MMR3 0x6C
-#define AMR_MAP_STRA 0x6D
-#define AMR_MAP_STRF 0x6E
-#define AMR_MAP_PEAKX 0x70
-#define AMR_MAP_PEAKR 0x71
-#define AMR_MAP_15_16 0x72
-
-/* Data Link Controller */
-#define AMR_DLC_FRAR_1_2_3 0x81
-#define AMR_DLC_SRAR_1_2_3 0x82
-#define AMR_DLC_TAR 0x83
-#define AMR_DLC_DRLR 0x84
-#define AMR_DLC_DTCR 0x85
-#define AMR_DLC_DMR1 0x86
-#define AMR_DLC_DMR1_DTTHRSH_INT 0x01
-#define AMR_DLC_DMR1_DRTHRSH_INT 0x02
-#define AMR_DLC_DMR1_TAR_ENABL 0x04
-#define AMR_DLC_DMR1_EORP_INT 0x08
-#define AMR_DLC_DMR1_EN_ADDR1 0x10
-#define AMR_DLC_DMR1_EN_ADDR2 0x20
-#define AMR_DLC_DMR1_EN_ADDR3 0x40
-#define AMR_DLC_DMR1_EN_ADDR4 0x80
-#define AMR_DLC_DMR1_EN_ADDRS 0xf0
-#define AMR_DLC_DMR2 0x87
-#define AMR_DLC_DMR2_RABRT_INT 0x01
-#define AMR_DLC_DMR2_RESID_INT 0x02
-#define AMR_DLC_DMR2_COLL_INT 0x04
-#define AMR_DLC_DMR2_FCS_INT 0x08
-#define AMR_DLC_DMR2_OVFL_INT 0x10
-#define AMR_DLC_DMR2_UNFL_INT 0x20
-#define AMR_DLC_DMR2_OVRN_INT 0x40
-#define AMR_DLC_DMR2_UNRN_INT 0x80
-#define AMR_DLC_1_7 0x88
-#define AMR_DLC_DRCR 0x89
-#define AMR_DLC_RNGR1 0x8A
-#define AMR_DLC_RNGR2 0x8B
-#define AMR_DLC_FRAR4 0x8C
-#define AMR_DLC_SRAR4 0x8D
-#define AMR_DLC_DMR3 0x8E
-#define AMR_DLC_DMR3_VA_INT 0x01
-#define AMR_DLC_DMR3_EOTP_INT 0x02
-#define AMR_DLC_DMR3_LBRP_INT 0x04
-#define AMR_DLC_DMR3_RBA_INT 0x08
-#define AMR_DLC_DMR3_LBT_INT 0x10
-#define AMR_DLC_DMR3_TBE_INT 0x20
-#define AMR_DLC_DMR3_RPLOST_INT 0x40
-#define AMR_DLC_DMR3_KEEP_FCS 0x80
-#define AMR_DLC_DMR4 0x8F
-#define AMR_DLC_DMR4_RCV_1 0x00
-#define AMR_DLC_DMR4_RCV_2 0x01
-#define AMR_DLC_DMR4_RCV_4 0x02
-#define AMR_DLC_DMR4_RCV_8 0x03
-#define AMR_DLC_DMR4_RCV_16 0x01
-#define AMR_DLC_DMR4_RCV_24 0x02
-#define AMR_DLC_DMR4_RCV_30 0x03
-#define AMR_DLC_DMR4_XMT_1 0x00
-#define AMR_DLC_DMR4_XMT_2 0x04
-#define AMR_DLC_DMR4_XMT_4 0x08
-#define AMR_DLC_DMR4_XMT_8 0x0c
-#define AMR_DLC_DMR4_XMT_10 0x08
-#define AMR_DLC_DMR4_XMT_14 0x0c
-#define AMR_DLC_DMR4_IDLE_MARK 0x00
-#define AMR_DLC_DMR4_IDLE_FLAG 0x10
-#define AMR_DLC_DMR4_ADDR_BOTH 0x00
-#define AMR_DLC_DMR4_ADDR_1ST 0x20
-#define AMR_DLC_DMR4_ADDR_2ND 0xa0
-#define AMR_DLC_DMR4_CR_ENABLE 0x40
-#define AMR_DLC_12_15 0x90
-#define AMR_DLC_ASR 0x91
-#define AMR_DLC_EFCR 0x92
-#define AMR_DLC_EFCR_EXTEND_FIFO 0x01
-#define AMR_DLC_EFCR_SEC_PKT_INT 0x02
-
-#define AMR_DSR1_VADDR 0x01
-#define AMR_DSR1_EORP 0x02
-#define AMR_DSR1_PKT_IP 0x04
-#define AMR_DSR1_DECHO_ON 0x08
-#define AMR_DSR1_DLOOP_ON 0x10
-#define AMR_DSR1_DBACK_OFF 0x20
-#define AMR_DSR1_EOTP 0x40
-#define AMR_DSR1_CXMT_ABRT 0x80
-
-#define AMR_DSR2_LBRP 0x01
-#define AMR_DSR2_RBA 0x02
-#define AMR_DSR2_RPLOST 0x04
-#define AMR_DSR2_LAST_BYTE 0x08
-#define AMR_DSR2_TBE 0x10
-#define AMR_DSR2_MARK_IDLE 0x20
-#define AMR_DSR2_FLAG_IDLE 0x40
-#define AMR_DSR2_SECOND_PKT 0x80
-
-#define AMR_DER_RABRT 0x01
-#define AMR_DER_RFRAME 0x02
-#define AMR_DER_COLLISION 0x04
-#define AMR_DER_FCS 0x08
-#define AMR_DER_OVFL 0x10
-#define AMR_DER_UNFL 0x20
-#define AMR_DER_OVRN 0x40
-#define AMR_DER_UNRN 0x80
-
-/* Peripheral Port */
-#define AMR_PP_PPCR1 0xC0
-#define AMR_PP_PPSR 0xC1
-#define AMR_PP_PPIER 0xC2
-#define AMR_PP_MTDR 0xC3
-#define AMR_PP_MRDR 0xC3
-#define AMR_PP_CITDR0 0xC4
-#define AMR_PP_CIRDR0 0xC4
-#define AMR_PP_CITDR1 0xC5
-#define AMR_PP_CIRDR1 0xC5
-#define AMR_PP_PPCR2 0xC8
-#define AMR_PP_PPCR3 0xC9
-
-struct snd_amd7930 {
- spinlock_t lock;
- void __iomem *regs;
- u32 flags;
-#define AMD7930_FLAG_PLAYBACK 0x00000001
-#define AMD7930_FLAG_CAPTURE 0x00000002
-
- struct amd7930_map map;
-
- struct snd_card *card;
- struct snd_pcm *pcm;
- struct snd_pcm_substream *playback_substream;
- struct snd_pcm_substream *capture_substream;
-
- /* Playback/Capture buffer state. */
- unsigned char *p_orig, *p_cur;
- int p_left;
- unsigned char *c_orig, *c_cur;
- int c_left;
-
- int rgain;
- int pgain;
- int mgain;
-
- struct platform_device *op;
- unsigned int irq;
- struct snd_amd7930 *next;
-};
-
-static struct snd_amd7930 *amd7930_list;
-
-/* Idle the AMD7930 chip. The amd->lock is not held. */
-static __inline__ void amd7930_idle(struct snd_amd7930 *amd)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&amd->lock, flags);
- sbus_writeb(AMR_INIT, amd->regs + AMD7930_CR);
- sbus_writeb(0, amd->regs + AMD7930_DR);
- spin_unlock_irqrestore(&amd->lock, flags);
-}
-
-/* Enable chip interrupts. The amd->lock is not held. */
-static __inline__ void amd7930_enable_ints(struct snd_amd7930 *amd)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&amd->lock, flags);
- sbus_writeb(AMR_INIT, amd->regs + AMD7930_CR);
- sbus_writeb(AM_INIT_ACTIVE, amd->regs + AMD7930_DR);
- spin_unlock_irqrestore(&amd->lock, flags);
-}
-
-/* Disable chip interrupts. The amd->lock is not held. */
-static __inline__ void amd7930_disable_ints(struct snd_amd7930 *amd)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&amd->lock, flags);
- sbus_writeb(AMR_INIT, amd->regs + AMD7930_CR);
- sbus_writeb(AM_INIT_ACTIVE | AM_INIT_DISABLE_INTS, amd->regs + AMD7930_DR);
- spin_unlock_irqrestore(&amd->lock, flags);
-}
-
-/* Commit amd7930_map settings to the hardware.
- * The amd->lock is held and local interrupts are disabled.
- */
-static void __amd7930_write_map(struct snd_amd7930 *amd)
-{
- struct amd7930_map *map = &amd->map;
-
- sbus_writeb(AMR_MAP_GX, amd->regs + AMD7930_CR);
- sbus_writeb(((map->gx >> 0) & 0xff), amd->regs + AMD7930_DR);
- sbus_writeb(((map->gx >> 8) & 0xff), amd->regs + AMD7930_DR);
-
- sbus_writeb(AMR_MAP_GR, amd->regs + AMD7930_CR);
- sbus_writeb(((map->gr >> 0) & 0xff), amd->regs + AMD7930_DR);
- sbus_writeb(((map->gr >> 8) & 0xff), amd->regs + AMD7930_DR);
-
- sbus_writeb(AMR_MAP_STGR, amd->regs + AMD7930_CR);
- sbus_writeb(((map->stgr >> 0) & 0xff), amd->regs + AMD7930_DR);
- sbus_writeb(((map->stgr >> 8) & 0xff), amd->regs + AMD7930_DR);
-
- sbus_writeb(AMR_MAP_GER, amd->regs + AMD7930_CR);
- sbus_writeb(((map->ger >> 0) & 0xff), amd->regs + AMD7930_DR);
- sbus_writeb(((map->ger >> 8) & 0xff), amd->regs + AMD7930_DR);
-
- sbus_writeb(AMR_MAP_MMR1, amd->regs + AMD7930_CR);
- sbus_writeb(map->mmr1, amd->regs + AMD7930_DR);
-
- sbus_writeb(AMR_MAP_MMR2, amd->regs + AMD7930_CR);
- sbus_writeb(map->mmr2, amd->regs + AMD7930_DR);
-}
-
-/* gx, gr & stg gains. this table must contain 256 elements with
- * the 0th being "infinity" (the magic value 9008). The remaining
- * elements match sun's gain curve (but with higher resolution):
- * -18 to 0dB in .16dB steps then 0 to 12dB in .08dB steps.
- */
-static __const__ __u16 gx_coeff[256] = {
- 0x9008, 0x8b7c, 0x8b51, 0x8b45, 0x8b42, 0x8b3b, 0x8b36, 0x8b33,
- 0x8b32, 0x8b2a, 0x8b2b, 0x8b2c, 0x8b25, 0x8b23, 0x8b22, 0x8b22,
- 0x9122, 0x8b1a, 0x8aa3, 0x8aa3, 0x8b1c, 0x8aa6, 0x912d, 0x912b,
- 0x8aab, 0x8b12, 0x8aaa, 0x8ab2, 0x9132, 0x8ab4, 0x913c, 0x8abb,
- 0x9142, 0x9144, 0x9151, 0x8ad5, 0x8aeb, 0x8a79, 0x8a5a, 0x8a4a,
- 0x8b03, 0x91c2, 0x91bb, 0x8a3f, 0x8a33, 0x91b2, 0x9212, 0x9213,
- 0x8a2c, 0x921d, 0x8a23, 0x921a, 0x9222, 0x9223, 0x922d, 0x9231,
- 0x9234, 0x9242, 0x925b, 0x92dd, 0x92c1, 0x92b3, 0x92ab, 0x92a4,
- 0x92a2, 0x932b, 0x9341, 0x93d3, 0x93b2, 0x93a2, 0x943c, 0x94b2,
- 0x953a, 0x9653, 0x9782, 0x9e21, 0x9d23, 0x9cd2, 0x9c23, 0x9baa,
- 0x9bde, 0x9b33, 0x9b22, 0x9b1d, 0x9ab2, 0xa142, 0xa1e5, 0x9a3b,
- 0xa213, 0xa1a2, 0xa231, 0xa2eb, 0xa313, 0xa334, 0xa421, 0xa54b,
- 0xada4, 0xac23, 0xab3b, 0xaaab, 0xaa5c, 0xb1a3, 0xb2ca, 0xb3bd,
- 0xbe24, 0xbb2b, 0xba33, 0xc32b, 0xcb5a, 0xd2a2, 0xe31d, 0x0808,
- 0x72ba, 0x62c2, 0x5c32, 0x52db, 0x513e, 0x4cce, 0x43b2, 0x4243,
- 0x41b4, 0x3b12, 0x3bc3, 0x3df2, 0x34bd, 0x3334, 0x32c2, 0x3224,
- 0x31aa, 0x2a7b, 0x2aaa, 0x2b23, 0x2bba, 0x2c42, 0x2e23, 0x25bb,
- 0x242b, 0x240f, 0x231a, 0x22bb, 0x2241, 0x2223, 0x221f, 0x1a33,
- 0x1a4a, 0x1acd, 0x2132, 0x1b1b, 0x1b2c, 0x1b62, 0x1c12, 0x1c32,
- 0x1d1b, 0x1e71, 0x16b1, 0x1522, 0x1434, 0x1412, 0x1352, 0x1323,
- 0x1315, 0x12bc, 0x127a, 0x1235, 0x1226, 0x11a2, 0x1216, 0x0a2a,
- 0x11bc, 0x11d1, 0x1163, 0x0ac2, 0x0ab2, 0x0aab, 0x0b1b, 0x0b23,
- 0x0b33, 0x0c0f, 0x0bb3, 0x0c1b, 0x0c3e, 0x0cb1, 0x0d4c, 0x0ec1,
- 0x079a, 0x0614, 0x0521, 0x047c, 0x0422, 0x03b1, 0x03e3, 0x0333,
- 0x0322, 0x031c, 0x02aa, 0x02ba, 0x02f2, 0x0242, 0x0232, 0x0227,
- 0x0222, 0x021b, 0x01ad, 0x0212, 0x01b2, 0x01bb, 0x01cb, 0x01f6,
- 0x0152, 0x013a, 0x0133, 0x0131, 0x012c, 0x0123, 0x0122, 0x00a2,
- 0x011b, 0x011e, 0x0114, 0x00b1, 0x00aa, 0x00b3, 0x00bd, 0x00ba,
- 0x00c5, 0x00d3, 0x00f3, 0x0062, 0x0051, 0x0042, 0x003b, 0x0033,
- 0x0032, 0x002a, 0x002c, 0x0025, 0x0023, 0x0022, 0x001a, 0x0021,
- 0x001b, 0x001b, 0x001d, 0x0015, 0x0013, 0x0013, 0x0012, 0x0012,
- 0x000a, 0x000a, 0x0011, 0x0011, 0x000b, 0x000b, 0x000c, 0x000e,
-};
-
-static __const__ __u16 ger_coeff[] = {
- 0x431f, /* 5. dB */
- 0x331f, /* 5.5 dB */
- 0x40dd, /* 6. dB */
- 0x11dd, /* 6.5 dB */
- 0x440f, /* 7. dB */
- 0x411f, /* 7.5 dB */
- 0x311f, /* 8. dB */
- 0x5520, /* 8.5 dB */
- 0x10dd, /* 9. dB */
- 0x4211, /* 9.5 dB */
- 0x410f, /* 10. dB */
- 0x111f, /* 10.5 dB */
- 0x600b, /* 11. dB */
- 0x00dd, /* 11.5 dB */
- 0x4210, /* 12. dB */
- 0x110f, /* 13. dB */
- 0x7200, /* 14. dB */
- 0x2110, /* 15. dB */
- 0x2200, /* 15.9 dB */
- 0x000b, /* 16.9 dB */
- 0x000f /* 18. dB */
-};
-
-/* Update amd7930_map settings and program them into the hardware.
- * The amd->lock is held and local interrupts are disabled.
- */
-static void __amd7930_update_map(struct snd_amd7930 *amd)
-{
- struct amd7930_map *map = &amd->map;
- int level;
-
- map->gx = gx_coeff[amd->rgain];
- map->stgr = gx_coeff[amd->mgain];
- level = (amd->pgain * (256 + ARRAY_SIZE(ger_coeff))) >> 8;
- if (level >= 256) {
- map->ger = ger_coeff[level - 256];
- map->gr = gx_coeff[255];
- } else {
- map->ger = ger_coeff[0];
- map->gr = gx_coeff[level];
- }
- __amd7930_write_map(amd);
-}
-
-static irqreturn_t snd_amd7930_interrupt(int irq, void *dev_id)
-{
- struct snd_amd7930 *amd = dev_id;
- unsigned int elapsed;
- u8 ir;
-
- spin_lock(&amd->lock);
-
- elapsed = 0;
-
- ir = sbus_readb(amd->regs + AMD7930_IR);
- if (ir & AMR_IR_BBUF) {
- u8 byte;
-
- if (amd->flags & AMD7930_FLAG_PLAYBACK) {
- if (amd->p_left > 0) {
- byte = *(amd->p_cur++);
- amd->p_left--;
- sbus_writeb(byte, amd->regs + AMD7930_BBTB);
- if (amd->p_left == 0)
- elapsed |= AMD7930_FLAG_PLAYBACK;
- } else
- sbus_writeb(0, amd->regs + AMD7930_BBTB);
- } else if (amd->flags & AMD7930_FLAG_CAPTURE) {
- byte = sbus_readb(amd->regs + AMD7930_BBRB);
- if (amd->c_left > 0) {
- *(amd->c_cur++) = byte;
- amd->c_left--;
- if (amd->c_left == 0)
- elapsed |= AMD7930_FLAG_CAPTURE;
- }
- }
- }
- spin_unlock(&amd->lock);
-
- if (elapsed & AMD7930_FLAG_PLAYBACK)
- snd_pcm_period_elapsed(amd->playback_substream);
- else
- snd_pcm_period_elapsed(amd->capture_substream);
-
- return IRQ_HANDLED;
-}
-
-static int snd_amd7930_trigger(struct snd_amd7930 *amd, unsigned int flag, int cmd)
-{
- unsigned long flags;
- int result = 0;
-
- spin_lock_irqsave(&amd->lock, flags);
- if (cmd == SNDRV_PCM_TRIGGER_START) {
- if (!(amd->flags & flag)) {
- amd->flags |= flag;
-
- /* Enable B channel interrupts. */
- sbus_writeb(AMR_MUX_MCR4, amd->regs + AMD7930_CR);
- sbus_writeb(AM_MUX_MCR4_ENABLE_INTS, amd->regs + AMD7930_DR);
- }
- } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
- if (amd->flags & flag) {
- amd->flags &= ~flag;
-
- /* Disable B channel interrupts. */
- sbus_writeb(AMR_MUX_MCR4, amd->regs + AMD7930_CR);
- sbus_writeb(0, amd->regs + AMD7930_DR);
- }
- } else {
- result = -EINVAL;
- }
- spin_unlock_irqrestore(&amd->lock, flags);
-
- return result;
-}
-
-static int snd_amd7930_playback_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
- return snd_amd7930_trigger(amd, AMD7930_FLAG_PLAYBACK, cmd);
-}
-
-static int snd_amd7930_capture_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
- return snd_amd7930_trigger(amd, AMD7930_FLAG_CAPTURE, cmd);
-}
-
-static int snd_amd7930_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int size = snd_pcm_lib_buffer_bytes(substream);
- unsigned long flags;
- u8 new_mmr1;
-
- spin_lock_irqsave(&amd->lock, flags);
-
- amd->flags |= AMD7930_FLAG_PLAYBACK;
-
- /* Setup the pseudo-dma transfer pointers. */
- amd->p_orig = amd->p_cur = runtime->dma_area;
- amd->p_left = size;
-
- /* Put the chip into the correct encoding format. */
- new_mmr1 = amd->map.mmr1;
- if (runtime->format == SNDRV_PCM_FORMAT_A_LAW)
- new_mmr1 |= AM_MAP_MMR1_ALAW;
- else
- new_mmr1 &= ~AM_MAP_MMR1_ALAW;
- if (new_mmr1 != amd->map.mmr1) {
- amd->map.mmr1 = new_mmr1;
- __amd7930_update_map(amd);
- }
-
- spin_unlock_irqrestore(&amd->lock, flags);
-
- return 0;
-}
-
-static int snd_amd7930_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned int size = snd_pcm_lib_buffer_bytes(substream);
- unsigned long flags;
- u8 new_mmr1;
-
- spin_lock_irqsave(&amd->lock, flags);
-
- amd->flags |= AMD7930_FLAG_CAPTURE;
-
- /* Setup the pseudo-dma transfer pointers. */
- amd->c_orig = amd->c_cur = runtime->dma_area;
- amd->c_left = size;
-
- /* Put the chip into the correct encoding format. */
- new_mmr1 = amd->map.mmr1;
- if (runtime->format == SNDRV_PCM_FORMAT_A_LAW)
- new_mmr1 |= AM_MAP_MMR1_ALAW;
- else
- new_mmr1 &= ~AM_MAP_MMR1_ALAW;
- if (new_mmr1 != amd->map.mmr1) {
- amd->map.mmr1 = new_mmr1;
- __amd7930_update_map(amd);
- }
-
- spin_unlock_irqrestore(&amd->lock, flags);
-
- return 0;
-}
-
-static snd_pcm_uframes_t snd_amd7930_playback_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
- size_t ptr;
-
- if (!(amd->flags & AMD7930_FLAG_PLAYBACK))
- return 0;
- ptr = amd->p_cur - amd->p_orig;
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-static snd_pcm_uframes_t snd_amd7930_capture_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
- size_t ptr;
-
- if (!(amd->flags & AMD7930_FLAG_CAPTURE))
- return 0;
-
- ptr = amd->c_cur - amd->c_orig;
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-/* Playback and capture have identical properties. */
-static struct snd_pcm_hardware snd_amd7930_pcm_hw =
-{
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_HALF_DUPLEX),
- .formats = SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW,
- .rates = SNDRV_PCM_RATE_8000,
- .rate_min = 8000,
- .rate_max = 8000,
- .channels_min = 1,
- .channels_max = 1,
- .buffer_bytes_max = (64*1024),
- .period_bytes_min = 1,
- .period_bytes_max = (64*1024),
- .periods_min = 1,
- .periods_max = 1024,
-};
-
-static int snd_amd7930_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- amd->playback_substream = substream;
- runtime->hw = snd_amd7930_pcm_hw;
- return 0;
-}
-
-static int snd_amd7930_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- amd->capture_substream = substream;
- runtime->hw = snd_amd7930_pcm_hw;
- return 0;
-}
-
-static int snd_amd7930_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
-
- amd->playback_substream = NULL;
- return 0;
-}
-
-static int snd_amd7930_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
-
- amd->capture_substream = NULL;
- return 0;
-}
-
-static int snd_amd7930_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static int snd_amd7930_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static struct snd_pcm_ops snd_amd7930_playback_ops = {
- .open = snd_amd7930_playback_open,
- .close = snd_amd7930_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_amd7930_hw_params,
- .hw_free = snd_amd7930_hw_free,
- .prepare = snd_amd7930_playback_prepare,
- .trigger = snd_amd7930_playback_trigger,
- .pointer = snd_amd7930_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_amd7930_capture_ops = {
- .open = snd_amd7930_capture_open,
- .close = snd_amd7930_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_amd7930_hw_params,
- .hw_free = snd_amd7930_hw_free,
- .prepare = snd_amd7930_capture_prepare,
- .trigger = snd_amd7930_capture_trigger,
- .pointer = snd_amd7930_capture_pointer,
-};
-
-static int __devinit snd_amd7930_pcm(struct snd_amd7930 *amd)
-{
- struct snd_pcm *pcm;
- int err;
-
- if ((err = snd_pcm_new(amd->card,
- /* ID */ "sun_amd7930",
- /* device */ 0,
- /* playback count */ 1,
- /* capture count */ 1, &pcm)) < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_amd7930_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_amd7930_capture_ops);
-
- pcm->private_data = amd;
- pcm->info_flags = 0;
- strcpy(pcm->name, amd->card->shortname);
- amd->pcm = pcm;
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- 64*1024, 64*1024);
-
- return 0;
-}
-
-#define VOLUME_MONITOR 0
-#define VOLUME_CAPTURE 1
-#define VOLUME_PLAYBACK 2
-
-static int snd_amd7930_info_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 255;
-
- return 0;
-}
-
-static int snd_amd7930_get_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_amd7930 *amd = snd_kcontrol_chip(kctl);
- int type = kctl->private_value;
- int *swval;
-
- switch (type) {
- case VOLUME_MONITOR:
- swval = &amd->mgain;
- break;
- case VOLUME_CAPTURE:
- swval = &amd->rgain;
- break;
- case VOLUME_PLAYBACK:
- default:
- swval = &amd->pgain;
- break;
- };
-
- ucontrol->value.integer.value[0] = *swval;
-
- return 0;
-}
-
-static int snd_amd7930_put_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_amd7930 *amd = snd_kcontrol_chip(kctl);
- unsigned long flags;
- int type = kctl->private_value;
- int *swval, change;
-
- switch (type) {
- case VOLUME_MONITOR:
- swval = &amd->mgain;
- break;
- case VOLUME_CAPTURE:
- swval = &amd->rgain;
- break;
- case VOLUME_PLAYBACK:
- default:
- swval = &amd->pgain;
- break;
- };
-
- spin_lock_irqsave(&amd->lock, flags);
-
- if (*swval != ucontrol->value.integer.value[0]) {
- *swval = ucontrol->value.integer.value[0] & 0xff;
- __amd7930_update_map(amd);
- change = 1;
- } else
- change = 0;
-
- spin_unlock_irqrestore(&amd->lock, flags);
-
- return change;
-}
-
-static struct snd_kcontrol_new amd7930_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Monitor Volume",
- .index = 0,
- .info = snd_amd7930_info_volume,
- .get = snd_amd7930_get_volume,
- .put = snd_amd7930_put_volume,
- .private_value = VOLUME_MONITOR,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Volume",
- .index = 0,
- .info = snd_amd7930_info_volume,
- .get = snd_amd7930_get_volume,
- .put = snd_amd7930_put_volume,
- .private_value = VOLUME_CAPTURE,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Playback Volume",
- .index = 0,
- .info = snd_amd7930_info_volume,
- .get = snd_amd7930_get_volume,
- .put = snd_amd7930_put_volume,
- .private_value = VOLUME_PLAYBACK,
- },
-};
-
-static int __devinit snd_amd7930_mixer(struct snd_amd7930 *amd)
-{
- struct snd_card *card;
- int idx, err;
-
- if (snd_BUG_ON(!amd || !amd->card))
- return -EINVAL;
-
- card = amd->card;
- strcpy(card->mixername, card->shortname);
-
- for (idx = 0; idx < ARRAY_SIZE(amd7930_controls); idx++) {
- if ((err = snd_ctl_add(card,
- snd_ctl_new1(&amd7930_controls[idx], amd))) < 0)
- return err;
- }
-
- return 0;
-}
-
-static int snd_amd7930_free(struct snd_amd7930 *amd)
-{
- struct platform_device *op = amd->op;
-
- amd7930_idle(amd);
-
- if (amd->irq)
- free_irq(amd->irq, amd);
-
- if (amd->regs)
- of_iounmap(&op->resource[0], amd->regs,
- resource_size(&op->resource[0]));
-
- kfree(amd);
-
- return 0;
-}
-
-static int snd_amd7930_dev_free(struct snd_device *device)
-{
- struct snd_amd7930 *amd = device->device_data;
-
- return snd_amd7930_free(amd);
-}
-
-static struct snd_device_ops snd_amd7930_dev_ops = {
- .dev_free = snd_amd7930_dev_free,
-};
-
-static int __devinit snd_amd7930_create(struct snd_card *card,
- struct platform_device *op,
- int irq, int dev,
- struct snd_amd7930 **ramd)
-{
- struct snd_amd7930 *amd;
- unsigned long flags;
- int err;
-
- *ramd = NULL;
- amd = kzalloc(sizeof(*amd), GFP_KERNEL);
- if (amd == NULL)
- return -ENOMEM;
-
- spin_lock_init(&amd->lock);
- amd->card = card;
- amd->op = op;
-
- amd->regs = of_ioremap(&op->resource[0], 0,
- resource_size(&op->resource[0]), "amd7930");
- if (!amd->regs) {
- snd_printk(KERN_ERR
- "amd7930-%d: Unable to map chip registers.\n", dev);
- return -EIO;
- }
-
- amd7930_idle(amd);
-
- if (request_irq(irq, snd_amd7930_interrupt,
- IRQF_SHARED, "amd7930", amd)) {
- snd_printk(KERN_ERR "amd7930-%d: Unable to grab IRQ %d\n",
- dev, irq);
- snd_amd7930_free(amd);
- return -EBUSY;
- }
- amd->irq = irq;
-
- amd7930_enable_ints(amd);
-
- spin_lock_irqsave(&amd->lock, flags);
-
- amd->rgain = 128;
- amd->pgain = 200;
- amd->mgain = 0;
-
- memset(&amd->map, 0, sizeof(amd->map));
- amd->map.mmr1 = (AM_MAP_MMR1_GX | AM_MAP_MMR1_GER |
- AM_MAP_MMR1_GR | AM_MAP_MMR1_STG);
- amd->map.mmr2 = (AM_MAP_MMR2_LS | AM_MAP_MMR2_AINB);
-
- __amd7930_update_map(amd);
-
- /* Always MUX audio (Ba) to channel Bb. */
- sbus_writeb(AMR_MUX_MCR1, amd->regs + AMD7930_CR);
- sbus_writeb(AM_MUX_CHANNEL_Ba | (AM_MUX_CHANNEL_Bb << 4),
- amd->regs + AMD7930_DR);
-
- spin_unlock_irqrestore(&amd->lock, flags);
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
- amd, &snd_amd7930_dev_ops)) < 0) {
- snd_amd7930_free(amd);
- return err;
- }
-
- *ramd = amd;
- return 0;
-}
-
-static int __devinit amd7930_sbus_probe(struct platform_device *op)
-{
- struct resource *rp = &op->resource[0];
- static int dev_num;
- struct snd_card *card;
- struct snd_amd7930 *amd;
- int err, irq;
-
- irq = op->archdata.irqs[0];
-
- if (dev_num >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev_num]) {
- dev_num++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev_num], id[dev_num], THIS_MODULE, 0,
- &card);
- if (err < 0)
- return err;
-
- strcpy(card->driver, "AMD7930");
- strcpy(card->shortname, "Sun AMD7930");
- sprintf(card->longname, "%s at 0x%02lx:0x%08Lx, irq %d",
- card->shortname,
- rp->flags & 0xffL,
- (unsigned long long)rp->start,
- irq);
-
- if ((err = snd_amd7930_create(card, op,
- irq, dev_num, &amd)) < 0)
- goto out_err;
-
- if ((err = snd_amd7930_pcm(amd)) < 0)
- goto out_err;
-
- if ((err = snd_amd7930_mixer(amd)) < 0)
- goto out_err;
-
- if ((err = snd_card_register(card)) < 0)
- goto out_err;
-
- amd->next = amd7930_list;
- amd7930_list = amd;
-
- dev_num++;
-
- return 0;
-
-out_err:
- snd_card_free(card);
- return err;
-}
-
-static const struct of_device_id amd7930_match[] = {
- {
- .name = "audio",
- },
- {},
-};
-
-static struct platform_driver amd7930_sbus_driver = {
- .driver = {
- .name = "audio",
- .owner = THIS_MODULE,
- .of_match_table = amd7930_match,
- },
- .probe = amd7930_sbus_probe,
-};
-
-static int __init amd7930_init(void)
-{
- return platform_driver_register(&amd7930_sbus_driver);
-}
-
-static void __exit amd7930_exit(void)
-{
- struct snd_amd7930 *p = amd7930_list;
-
- while (p != NULL) {
- struct snd_amd7930 *next = p->next;
-
- snd_card_free(p->card);
-
- p = next;
- }
-
- amd7930_list = NULL;
-
- platform_driver_unregister(&amd7930_sbus_driver);
-}
-
-module_init(amd7930_init);
-module_exit(amd7930_exit);
diff --git a/ANDROID_3.4.5/sound/sparc/cs4231.c b/ANDROID_3.4.5/sound/sparc/cs4231.c
deleted file mode 100644
index f2eabd3f..00000000
--- a/ANDROID_3.4.5/sound/sparc/cs4231.c
+++ /dev/null
@@ -1,2121 +0,0 @@
-/*
- * Driver for CS4231 sound chips found on Sparcs.
- * Copyright (C) 2002, 2008 David S. Miller <davem@davemloft.net>
- *
- * Based entirely upon drivers/sbus/audio/cs4231.c which is:
- * Copyright (C) 1996, 1997, 1998 Derrick J Brashear (shadow@andrew.cmu.edu)
- * and also sound/isa/cs423x/cs4231_lib.c which is:
- * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/moduleparam.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/timer.h>
-#include <sound/initval.h>
-#include <sound/pcm_params.h>
-
-#ifdef CONFIG_SBUS
-#define SBUS_SUPPORT
-#endif
-
-#if defined(CONFIG_PCI) && defined(CONFIG_SPARC64)
-#define EBUS_SUPPORT
-#include <linux/pci.h>
-#include <asm/ebus_dma.h>
-#endif
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-/* Enable this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Sun CS4231 soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Sun CS4231 soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Sun CS4231 soundcard.");
-MODULE_AUTHOR("Jaroslav Kysela, Derrick J. Brashear and David S. Miller");
-MODULE_DESCRIPTION("Sun CS4231");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Sun,CS4231}}");
-
-#ifdef SBUS_SUPPORT
-struct sbus_dma_info {
- spinlock_t lock; /* DMA access lock */
- int dir;
- void __iomem *regs;
-};
-#endif
-
-struct snd_cs4231;
-struct cs4231_dma_control {
- void (*prepare)(struct cs4231_dma_control *dma_cont,
- int dir);
- void (*enable)(struct cs4231_dma_control *dma_cont, int on);
- int (*request)(struct cs4231_dma_control *dma_cont,
- dma_addr_t bus_addr, size_t len);
- unsigned int (*address)(struct cs4231_dma_control *dma_cont);
-#ifdef EBUS_SUPPORT
- struct ebus_dma_info ebus_info;
-#endif
-#ifdef SBUS_SUPPORT
- struct sbus_dma_info sbus_info;
-#endif
-};
-
-struct snd_cs4231 {
- spinlock_t lock; /* registers access lock */
- void __iomem *port;
-
- struct cs4231_dma_control p_dma;
- struct cs4231_dma_control c_dma;
-
- u32 flags;
-#define CS4231_FLAG_EBUS 0x00000001
-#define CS4231_FLAG_PLAYBACK 0x00000002
-#define CS4231_FLAG_CAPTURE 0x00000004
-
- struct snd_card *card;
- struct snd_pcm *pcm;
- struct snd_pcm_substream *playback_substream;
- unsigned int p_periods_sent;
- struct snd_pcm_substream *capture_substream;
- unsigned int c_periods_sent;
- struct snd_timer *timer;
-
- unsigned short mode;
-#define CS4231_MODE_NONE 0x0000
-#define CS4231_MODE_PLAY 0x0001
-#define CS4231_MODE_RECORD 0x0002
-#define CS4231_MODE_TIMER 0x0004
-#define CS4231_MODE_OPEN (CS4231_MODE_PLAY | CS4231_MODE_RECORD | \
- CS4231_MODE_TIMER)
-
- unsigned char image[32]; /* registers image */
- int mce_bit;
- int calibrate_mute;
- struct mutex mce_mutex; /* mutex for mce register */
- struct mutex open_mutex; /* mutex for ALSA open/close */
-
- struct platform_device *op;
- unsigned int irq[2];
- unsigned int regs_size;
- struct snd_cs4231 *next;
-};
-
-/* Eventually we can use sound/isa/cs423x/cs4231_lib.c directly, but for
- * now.... -DaveM
- */
-
-/* IO ports */
-#include <sound/cs4231-regs.h>
-
-/* XXX offsets are different than PC ISA chips... */
-#define CS4231U(chip, x) ((chip)->port + ((c_d_c_CS4231##x) << 2))
-
-/* SBUS DMA register defines. */
-
-#define APCCSR 0x10UL /* APC DMA CSR */
-#define APCCVA 0x20UL /* APC Capture DMA Address */
-#define APCCC 0x24UL /* APC Capture Count */
-#define APCCNVA 0x28UL /* APC Capture DMA Next Address */
-#define APCCNC 0x2cUL /* APC Capture Next Count */
-#define APCPVA 0x30UL /* APC Play DMA Address */
-#define APCPC 0x34UL /* APC Play Count */
-#define APCPNVA 0x38UL /* APC Play DMA Next Address */
-#define APCPNC 0x3cUL /* APC Play Next Count */
-
-/* Defines for SBUS DMA-routines */
-
-#define APCVA 0x0UL /* APC DMA Address */
-#define APCC 0x4UL /* APC Count */
-#define APCNVA 0x8UL /* APC DMA Next Address */
-#define APCNC 0xcUL /* APC Next Count */
-#define APC_PLAY 0x30UL /* Play registers start at 0x30 */
-#define APC_RECORD 0x20UL /* Record registers start at 0x20 */
-
-/* APCCSR bits */
-
-#define APC_INT_PENDING 0x800000 /* Interrupt Pending */
-#define APC_PLAY_INT 0x400000 /* Playback interrupt */
-#define APC_CAPT_INT 0x200000 /* Capture interrupt */
-#define APC_GENL_INT 0x100000 /* General interrupt */
-#define APC_XINT_ENA 0x80000 /* General ext int. enable */
-#define APC_XINT_PLAY 0x40000 /* Playback ext intr */
-#define APC_XINT_CAPT 0x20000 /* Capture ext intr */
-#define APC_XINT_GENL 0x10000 /* Error ext intr */
-#define APC_XINT_EMPT 0x8000 /* Pipe empty interrupt (0 write to pva) */
-#define APC_XINT_PEMP 0x4000 /* Play pipe empty (pva and pnva not set) */
-#define APC_XINT_PNVA 0x2000 /* Playback NVA dirty */
-#define APC_XINT_PENA 0x1000 /* play pipe empty Int enable */
-#define APC_XINT_COVF 0x800 /* Cap data dropped on floor */
-#define APC_XINT_CNVA 0x400 /* Capture NVA dirty */
-#define APC_XINT_CEMP 0x200 /* Capture pipe empty (cva and cnva not set) */
-#define APC_XINT_CENA 0x100 /* Cap. pipe empty int enable */
-#define APC_PPAUSE 0x80 /* Pause the play DMA */
-#define APC_CPAUSE 0x40 /* Pause the capture DMA */
-#define APC_CDC_RESET 0x20 /* CODEC RESET */
-#define APC_PDMA_READY 0x08 /* Play DMA Go */
-#define APC_CDMA_READY 0x04 /* Capture DMA Go */
-#define APC_CHIP_RESET 0x01 /* Reset the chip */
-
-/* EBUS DMA register offsets */
-
-#define EBDMA_CSR 0x00UL /* Control/Status */
-#define EBDMA_ADDR 0x04UL /* DMA Address */
-#define EBDMA_COUNT 0x08UL /* DMA Count */
-
-/*
- * Some variables
- */
-
-static unsigned char freq_bits[14] = {
- /* 5510 */ 0x00 | CS4231_XTAL2,
- /* 6620 */ 0x0E | CS4231_XTAL2,
- /* 8000 */ 0x00 | CS4231_XTAL1,
- /* 9600 */ 0x0E | CS4231_XTAL1,
- /* 11025 */ 0x02 | CS4231_XTAL2,
- /* 16000 */ 0x02 | CS4231_XTAL1,
- /* 18900 */ 0x04 | CS4231_XTAL2,
- /* 22050 */ 0x06 | CS4231_XTAL2,
- /* 27042 */ 0x04 | CS4231_XTAL1,
- /* 32000 */ 0x06 | CS4231_XTAL1,
- /* 33075 */ 0x0C | CS4231_XTAL2,
- /* 37800 */ 0x08 | CS4231_XTAL2,
- /* 44100 */ 0x0A | CS4231_XTAL2,
- /* 48000 */ 0x0C | CS4231_XTAL1
-};
-
-static unsigned int rates[14] = {
- 5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050,
- 27042, 32000, 33075, 37800, 44100, 48000
-};
-
-static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
- .count = ARRAY_SIZE(rates),
- .list = rates,
-};
-
-static int snd_cs4231_xrate(struct snd_pcm_runtime *runtime)
-{
- return snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- &hw_constraints_rates);
-}
-
-static unsigned char snd_cs4231_original_image[32] =
-{
- 0x00, /* 00/00 - lic */
- 0x00, /* 01/01 - ric */
- 0x9f, /* 02/02 - la1ic */
- 0x9f, /* 03/03 - ra1ic */
- 0x9f, /* 04/04 - la2ic */
- 0x9f, /* 05/05 - ra2ic */
- 0xbf, /* 06/06 - loc */
- 0xbf, /* 07/07 - roc */
- 0x20, /* 08/08 - pdfr */
- CS4231_AUTOCALIB, /* 09/09 - ic */
- 0x00, /* 0a/10 - pc */
- 0x00, /* 0b/11 - ti */
- CS4231_MODE2, /* 0c/12 - mi */
- 0x00, /* 0d/13 - lbc */
- 0x00, /* 0e/14 - pbru */
- 0x00, /* 0f/15 - pbrl */
- 0x80, /* 10/16 - afei */
- 0x01, /* 11/17 - afeii */
- 0x9f, /* 12/18 - llic */
- 0x9f, /* 13/19 - rlic */
- 0x00, /* 14/20 - tlb */
- 0x00, /* 15/21 - thb */
- 0x00, /* 16/22 - la3mic/reserved */
- 0x00, /* 17/23 - ra3mic/reserved */
- 0x00, /* 18/24 - afs */
- 0x00, /* 19/25 - lamoc/version */
- 0x00, /* 1a/26 - mioc */
- 0x00, /* 1b/27 - ramoc/reserved */
- 0x20, /* 1c/28 - cdfr */
- 0x00, /* 1d/29 - res4 */
- 0x00, /* 1e/30 - cbru */
- 0x00, /* 1f/31 - cbrl */
-};
-
-static u8 __cs4231_readb(struct snd_cs4231 *cp, void __iomem *reg_addr)
-{
- if (cp->flags & CS4231_FLAG_EBUS)
- return readb(reg_addr);
- else
- return sbus_readb(reg_addr);
-}
-
-static void __cs4231_writeb(struct snd_cs4231 *cp, u8 val,
- void __iomem *reg_addr)
-{
- if (cp->flags & CS4231_FLAG_EBUS)
- return writeb(val, reg_addr);
- else
- return sbus_writeb(val, reg_addr);
-}
-
-/*
- * Basic I/O functions
- */
-
-static void snd_cs4231_ready(struct snd_cs4231 *chip)
-{
- int timeout;
-
- for (timeout = 250; timeout > 0; timeout--) {
- int val = __cs4231_readb(chip, CS4231U(chip, REGSEL));
- if ((val & CS4231_INIT) == 0)
- break;
- udelay(100);
- }
-}
-
-static void snd_cs4231_dout(struct snd_cs4231 *chip, unsigned char reg,
- unsigned char value)
-{
- snd_cs4231_ready(chip);
-#ifdef CONFIG_SND_DEBUG
- if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT)
- snd_printdd("out: auto calibration time out - reg = 0x%x, "
- "value = 0x%x\n",
- reg, value);
-#endif
- __cs4231_writeb(chip, chip->mce_bit | reg, CS4231U(chip, REGSEL));
- wmb();
- __cs4231_writeb(chip, value, CS4231U(chip, REG));
- mb();
-}
-
-static inline void snd_cs4231_outm(struct snd_cs4231 *chip, unsigned char reg,
- unsigned char mask, unsigned char value)
-{
- unsigned char tmp = (chip->image[reg] & mask) | value;
-
- chip->image[reg] = tmp;
- if (!chip->calibrate_mute)
- snd_cs4231_dout(chip, reg, tmp);
-}
-
-static void snd_cs4231_out(struct snd_cs4231 *chip, unsigned char reg,
- unsigned char value)
-{
- snd_cs4231_dout(chip, reg, value);
- chip->image[reg] = value;
- mb();
-}
-
-static unsigned char snd_cs4231_in(struct snd_cs4231 *chip, unsigned char reg)
-{
- snd_cs4231_ready(chip);
-#ifdef CONFIG_SND_DEBUG
- if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT)
- snd_printdd("in: auto calibration time out - reg = 0x%x\n",
- reg);
-#endif
- __cs4231_writeb(chip, chip->mce_bit | reg, CS4231U(chip, REGSEL));
- mb();
- return __cs4231_readb(chip, CS4231U(chip, REG));
-}
-
-/*
- * CS4231 detection / MCE routines
- */
-
-static void snd_cs4231_busy_wait(struct snd_cs4231 *chip)
-{
- int timeout;
-
- /* looks like this sequence is proper for CS4231A chip (GUS MAX) */
- for (timeout = 5; timeout > 0; timeout--)
- __cs4231_readb(chip, CS4231U(chip, REGSEL));
-
- /* end of cleanup sequence */
- for (timeout = 500; timeout > 0; timeout--) {
- int val = __cs4231_readb(chip, CS4231U(chip, REGSEL));
- if ((val & CS4231_INIT) == 0)
- break;
- msleep(1);
- }
-}
-
-static void snd_cs4231_mce_up(struct snd_cs4231 *chip)
-{
- unsigned long flags;
- int timeout;
-
- spin_lock_irqsave(&chip->lock, flags);
- snd_cs4231_ready(chip);
-#ifdef CONFIG_SND_DEBUG
- if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT)
- snd_printdd("mce_up - auto calibration time out (0)\n");
-#endif
- chip->mce_bit |= CS4231_MCE;
- timeout = __cs4231_readb(chip, CS4231U(chip, REGSEL));
- if (timeout == 0x80)
- snd_printdd("mce_up [%p]: serious init problem - "
- "codec still busy\n",
- chip->port);
- if (!(timeout & CS4231_MCE))
- __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f),
- CS4231U(chip, REGSEL));
- spin_unlock_irqrestore(&chip->lock, flags);
-}
-
-static void snd_cs4231_mce_down(struct snd_cs4231 *chip)
-{
- unsigned long flags, timeout;
- int reg;
-
- snd_cs4231_busy_wait(chip);
- spin_lock_irqsave(&chip->lock, flags);
-#ifdef CONFIG_SND_DEBUG
- if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT)
- snd_printdd("mce_down [%p] - auto calibration time out (0)\n",
- CS4231U(chip, REGSEL));
-#endif
- chip->mce_bit &= ~CS4231_MCE;
- reg = __cs4231_readb(chip, CS4231U(chip, REGSEL));
- __cs4231_writeb(chip, chip->mce_bit | (reg & 0x1f),
- CS4231U(chip, REGSEL));
- if (reg == 0x80)
- snd_printdd("mce_down [%p]: serious init problem "
- "- codec still busy\n", chip->port);
- if ((reg & CS4231_MCE) == 0) {
- spin_unlock_irqrestore(&chip->lock, flags);
- return;
- }
-
- /*
- * Wait for auto-calibration (AC) process to finish, i.e. ACI to go low.
- */
- timeout = jiffies + msecs_to_jiffies(250);
- do {
- spin_unlock_irqrestore(&chip->lock, flags);
- msleep(1);
- spin_lock_irqsave(&chip->lock, flags);
- reg = snd_cs4231_in(chip, CS4231_TEST_INIT);
- reg &= CS4231_CALIB_IN_PROGRESS;
- } while (reg && time_before(jiffies, timeout));
- spin_unlock_irqrestore(&chip->lock, flags);
-
- if (reg)
- snd_printk(KERN_ERR
- "mce_down - auto calibration time out (2)\n");
-}
-
-static void snd_cs4231_advance_dma(struct cs4231_dma_control *dma_cont,
- struct snd_pcm_substream *substream,
- unsigned int *periods_sent)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- while (1) {
- unsigned int period_size = snd_pcm_lib_period_bytes(substream);
- unsigned int offset = period_size * (*periods_sent);
-
- BUG_ON(period_size >= (1 << 24));
-
- if (dma_cont->request(dma_cont,
- runtime->dma_addr + offset, period_size))
- return;
- (*periods_sent) = ((*periods_sent) + 1) % runtime->periods;
- }
-}
-
-static void cs4231_dma_trigger(struct snd_pcm_substream *substream,
- unsigned int what, int on)
-{
- struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
- struct cs4231_dma_control *dma_cont;
-
- if (what & CS4231_PLAYBACK_ENABLE) {
- dma_cont = &chip->p_dma;
- if (on) {
- dma_cont->prepare(dma_cont, 0);
- dma_cont->enable(dma_cont, 1);
- snd_cs4231_advance_dma(dma_cont,
- chip->playback_substream,
- &chip->p_periods_sent);
- } else {
- dma_cont->enable(dma_cont, 0);
- }
- }
- if (what & CS4231_RECORD_ENABLE) {
- dma_cont = &chip->c_dma;
- if (on) {
- dma_cont->prepare(dma_cont, 1);
- dma_cont->enable(dma_cont, 1);
- snd_cs4231_advance_dma(dma_cont,
- chip->capture_substream,
- &chip->c_periods_sent);
- } else {
- dma_cont->enable(dma_cont, 0);
- }
- }
-}
-
-static int snd_cs4231_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
- int result = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_STOP:
- {
- unsigned int what = 0;
- struct snd_pcm_substream *s;
- unsigned long flags;
-
- snd_pcm_group_for_each_entry(s, substream) {
- if (s == chip->playback_substream) {
- what |= CS4231_PLAYBACK_ENABLE;
- snd_pcm_trigger_done(s, substream);
- } else if (s == chip->capture_substream) {
- what |= CS4231_RECORD_ENABLE;
- snd_pcm_trigger_done(s, substream);
- }
- }
-
- spin_lock_irqsave(&chip->lock, flags);
- if (cmd == SNDRV_PCM_TRIGGER_START) {
- cs4231_dma_trigger(substream, what, 1);
- chip->image[CS4231_IFACE_CTRL] |= what;
- } else {
- cs4231_dma_trigger(substream, what, 0);
- chip->image[CS4231_IFACE_CTRL] &= ~what;
- }
- snd_cs4231_out(chip, CS4231_IFACE_CTRL,
- chip->image[CS4231_IFACE_CTRL]);
- spin_unlock_irqrestore(&chip->lock, flags);
- break;
- }
- default:
- result = -EINVAL;
- break;
- }
-
- return result;
-}
-
-/*
- * CODEC I/O
- */
-
-static unsigned char snd_cs4231_get_rate(unsigned int rate)
-{
- int i;
-
- for (i = 0; i < 14; i++)
- if (rate == rates[i])
- return freq_bits[i];
-
- return freq_bits[13];
-}
-
-static unsigned char snd_cs4231_get_format(struct snd_cs4231 *chip, int format,
- int channels)
-{
- unsigned char rformat;
-
- rformat = CS4231_LINEAR_8;
- switch (format) {
- case SNDRV_PCM_FORMAT_MU_LAW:
- rformat = CS4231_ULAW_8;
- break;
- case SNDRV_PCM_FORMAT_A_LAW:
- rformat = CS4231_ALAW_8;
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- rformat = CS4231_LINEAR_16;
- break;
- case SNDRV_PCM_FORMAT_S16_BE:
- rformat = CS4231_LINEAR_16_BIG;
- break;
- case SNDRV_PCM_FORMAT_IMA_ADPCM:
- rformat = CS4231_ADPCM_16;
- break;
- }
- if (channels > 1)
- rformat |= CS4231_STEREO;
- return rformat;
-}
-
-static void snd_cs4231_calibrate_mute(struct snd_cs4231 *chip, int mute)
-{
- unsigned long flags;
-
- mute = mute ? 1 : 0;
- spin_lock_irqsave(&chip->lock, flags);
- if (chip->calibrate_mute == mute) {
- spin_unlock_irqrestore(&chip->lock, flags);
- return;
- }
- if (!mute) {
- snd_cs4231_dout(chip, CS4231_LEFT_INPUT,
- chip->image[CS4231_LEFT_INPUT]);
- snd_cs4231_dout(chip, CS4231_RIGHT_INPUT,
- chip->image[CS4231_RIGHT_INPUT]);
- snd_cs4231_dout(chip, CS4231_LOOPBACK,
- chip->image[CS4231_LOOPBACK]);
- }
- snd_cs4231_dout(chip, CS4231_AUX1_LEFT_INPUT,
- mute ? 0x80 : chip->image[CS4231_AUX1_LEFT_INPUT]);
- snd_cs4231_dout(chip, CS4231_AUX1_RIGHT_INPUT,
- mute ? 0x80 : chip->image[CS4231_AUX1_RIGHT_INPUT]);
- snd_cs4231_dout(chip, CS4231_AUX2_LEFT_INPUT,
- mute ? 0x80 : chip->image[CS4231_AUX2_LEFT_INPUT]);
- snd_cs4231_dout(chip, CS4231_AUX2_RIGHT_INPUT,
- mute ? 0x80 : chip->image[CS4231_AUX2_RIGHT_INPUT]);
- snd_cs4231_dout(chip, CS4231_LEFT_OUTPUT,
- mute ? 0x80 : chip->image[CS4231_LEFT_OUTPUT]);
- snd_cs4231_dout(chip, CS4231_RIGHT_OUTPUT,
- mute ? 0x80 : chip->image[CS4231_RIGHT_OUTPUT]);
- snd_cs4231_dout(chip, CS4231_LEFT_LINE_IN,
- mute ? 0x80 : chip->image[CS4231_LEFT_LINE_IN]);
- snd_cs4231_dout(chip, CS4231_RIGHT_LINE_IN,
- mute ? 0x80 : chip->image[CS4231_RIGHT_LINE_IN]);
- snd_cs4231_dout(chip, CS4231_MONO_CTRL,
- mute ? 0xc0 : chip->image[CS4231_MONO_CTRL]);
- chip->calibrate_mute = mute;
- spin_unlock_irqrestore(&chip->lock, flags);
-}
-
-static void snd_cs4231_playback_format(struct snd_cs4231 *chip,
- struct snd_pcm_hw_params *params,
- unsigned char pdfr)
-{
- unsigned long flags;
-
- mutex_lock(&chip->mce_mutex);
- snd_cs4231_calibrate_mute(chip, 1);
-
- snd_cs4231_mce_up(chip);
-
- spin_lock_irqsave(&chip->lock, flags);
- snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT,
- (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) ?
- (pdfr & 0xf0) | (chip->image[CS4231_REC_FORMAT] & 0x0f) :
- pdfr);
- spin_unlock_irqrestore(&chip->lock, flags);
-
- snd_cs4231_mce_down(chip);
-
- snd_cs4231_calibrate_mute(chip, 0);
- mutex_unlock(&chip->mce_mutex);
-}
-
-static void snd_cs4231_capture_format(struct snd_cs4231 *chip,
- struct snd_pcm_hw_params *params,
- unsigned char cdfr)
-{
- unsigned long flags;
-
- mutex_lock(&chip->mce_mutex);
- snd_cs4231_calibrate_mute(chip, 1);
-
- snd_cs4231_mce_up(chip);
-
- spin_lock_irqsave(&chip->lock, flags);
- if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) {
- snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT,
- ((chip->image[CS4231_PLAYBK_FORMAT]) & 0xf0) |
- (cdfr & 0x0f));
- spin_unlock_irqrestore(&chip->lock, flags);
- snd_cs4231_mce_down(chip);
- snd_cs4231_mce_up(chip);
- spin_lock_irqsave(&chip->lock, flags);
- }
- snd_cs4231_out(chip, CS4231_REC_FORMAT, cdfr);
- spin_unlock_irqrestore(&chip->lock, flags);
-
- snd_cs4231_mce_down(chip);
-
- snd_cs4231_calibrate_mute(chip, 0);
- mutex_unlock(&chip->mce_mutex);
-}
-
-/*
- * Timer interface
- */
-
-static unsigned long snd_cs4231_timer_resolution(struct snd_timer *timer)
-{
- struct snd_cs4231 *chip = snd_timer_chip(timer);
-
- return chip->image[CS4231_PLAYBK_FORMAT] & 1 ? 9969 : 9920;
-}
-
-static int snd_cs4231_timer_start(struct snd_timer *timer)
-{
- unsigned long flags;
- unsigned int ticks;
- struct snd_cs4231 *chip = snd_timer_chip(timer);
-
- spin_lock_irqsave(&chip->lock, flags);
- ticks = timer->sticks;
- if ((chip->image[CS4231_ALT_FEATURE_1] & CS4231_TIMER_ENABLE) == 0 ||
- (unsigned char)(ticks >> 8) != chip->image[CS4231_TIMER_HIGH] ||
- (unsigned char)ticks != chip->image[CS4231_TIMER_LOW]) {
- snd_cs4231_out(chip, CS4231_TIMER_HIGH,
- chip->image[CS4231_TIMER_HIGH] =
- (unsigned char) (ticks >> 8));
- snd_cs4231_out(chip, CS4231_TIMER_LOW,
- chip->image[CS4231_TIMER_LOW] =
- (unsigned char) ticks);
- snd_cs4231_out(chip, CS4231_ALT_FEATURE_1,
- chip->image[CS4231_ALT_FEATURE_1] |
- CS4231_TIMER_ENABLE);
- }
- spin_unlock_irqrestore(&chip->lock, flags);
-
- return 0;
-}
-
-static int snd_cs4231_timer_stop(struct snd_timer *timer)
-{
- unsigned long flags;
- struct snd_cs4231 *chip = snd_timer_chip(timer);
-
- spin_lock_irqsave(&chip->lock, flags);
- chip->image[CS4231_ALT_FEATURE_1] &= ~CS4231_TIMER_ENABLE;
- snd_cs4231_out(chip, CS4231_ALT_FEATURE_1,
- chip->image[CS4231_ALT_FEATURE_1]);
- spin_unlock_irqrestore(&chip->lock, flags);
-
- return 0;
-}
-
-static void __devinit snd_cs4231_init(struct snd_cs4231 *chip)
-{
- unsigned long flags;
-
- snd_cs4231_mce_down(chip);
-
-#ifdef SNDRV_DEBUG_MCE
- snd_printdd("init: (1)\n");
-#endif
- snd_cs4231_mce_up(chip);
- spin_lock_irqsave(&chip->lock, flags);
- chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE |
- CS4231_PLAYBACK_PIO |
- CS4231_RECORD_ENABLE |
- CS4231_RECORD_PIO |
- CS4231_CALIB_MODE);
- chip->image[CS4231_IFACE_CTRL] |= CS4231_AUTOCALIB;
- snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
- spin_unlock_irqrestore(&chip->lock, flags);
- snd_cs4231_mce_down(chip);
-
-#ifdef SNDRV_DEBUG_MCE
- snd_printdd("init: (2)\n");
-#endif
-
- snd_cs4231_mce_up(chip);
- spin_lock_irqsave(&chip->lock, flags);
- snd_cs4231_out(chip, CS4231_ALT_FEATURE_1,
- chip->image[CS4231_ALT_FEATURE_1]);
- spin_unlock_irqrestore(&chip->lock, flags);
- snd_cs4231_mce_down(chip);
-
-#ifdef SNDRV_DEBUG_MCE
- snd_printdd("init: (3) - afei = 0x%x\n",
- chip->image[CS4231_ALT_FEATURE_1]);
-#endif
-
- spin_lock_irqsave(&chip->lock, flags);
- snd_cs4231_out(chip, CS4231_ALT_FEATURE_2,
- chip->image[CS4231_ALT_FEATURE_2]);
- spin_unlock_irqrestore(&chip->lock, flags);
-
- snd_cs4231_mce_up(chip);
- spin_lock_irqsave(&chip->lock, flags);
- snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT,
- chip->image[CS4231_PLAYBK_FORMAT]);
- spin_unlock_irqrestore(&chip->lock, flags);
- snd_cs4231_mce_down(chip);
-
-#ifdef SNDRV_DEBUG_MCE
- snd_printdd("init: (4)\n");
-#endif
-
- snd_cs4231_mce_up(chip);
- spin_lock_irqsave(&chip->lock, flags);
- snd_cs4231_out(chip, CS4231_REC_FORMAT, chip->image[CS4231_REC_FORMAT]);
- spin_unlock_irqrestore(&chip->lock, flags);
- snd_cs4231_mce_down(chip);
-
-#ifdef SNDRV_DEBUG_MCE
- snd_printdd("init: (5)\n");
-#endif
-}
-
-static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode)
-{
- unsigned long flags;
-
- mutex_lock(&chip->open_mutex);
- if ((chip->mode & mode)) {
- mutex_unlock(&chip->open_mutex);
- return -EAGAIN;
- }
- if (chip->mode & CS4231_MODE_OPEN) {
- chip->mode |= mode;
- mutex_unlock(&chip->open_mutex);
- return 0;
- }
- /* ok. now enable and ack CODEC IRQ */
- spin_lock_irqsave(&chip->lock, flags);
- snd_cs4231_out(chip, CS4231_IRQ_STATUS, CS4231_PLAYBACK_IRQ |
- CS4231_RECORD_IRQ |
- CS4231_TIMER_IRQ);
- snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
- __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */
- __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */
-
- snd_cs4231_out(chip, CS4231_IRQ_STATUS, CS4231_PLAYBACK_IRQ |
- CS4231_RECORD_IRQ |
- CS4231_TIMER_IRQ);
- snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
-
- spin_unlock_irqrestore(&chip->lock, flags);
-
- chip->mode = mode;
- mutex_unlock(&chip->open_mutex);
- return 0;
-}
-
-static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode)
-{
- unsigned long flags;
-
- mutex_lock(&chip->open_mutex);
- chip->mode &= ~mode;
- if (chip->mode & CS4231_MODE_OPEN) {
- mutex_unlock(&chip->open_mutex);
- return;
- }
- snd_cs4231_calibrate_mute(chip, 1);
-
- /* disable IRQ */
- spin_lock_irqsave(&chip->lock, flags);
- snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
- __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */
- __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */
-
- /* now disable record & playback */
-
- if (chip->image[CS4231_IFACE_CTRL] &
- (CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO |
- CS4231_RECORD_ENABLE | CS4231_RECORD_PIO)) {
- spin_unlock_irqrestore(&chip->lock, flags);
- snd_cs4231_mce_up(chip);
- spin_lock_irqsave(&chip->lock, flags);
- chip->image[CS4231_IFACE_CTRL] &=
- ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO |
- CS4231_RECORD_ENABLE | CS4231_RECORD_PIO);
- snd_cs4231_out(chip, CS4231_IFACE_CTRL,
- chip->image[CS4231_IFACE_CTRL]);
- spin_unlock_irqrestore(&chip->lock, flags);
- snd_cs4231_mce_down(chip);
- spin_lock_irqsave(&chip->lock, flags);
- }
-
- /* clear IRQ again */
- snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
- __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */
- __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */
- spin_unlock_irqrestore(&chip->lock, flags);
-
- snd_cs4231_calibrate_mute(chip, 0);
-
- chip->mode = 0;
- mutex_unlock(&chip->open_mutex);
-}
-
-/*
- * timer open/close
- */
-
-static int snd_cs4231_timer_open(struct snd_timer *timer)
-{
- struct snd_cs4231 *chip = snd_timer_chip(timer);
- snd_cs4231_open(chip, CS4231_MODE_TIMER);
- return 0;
-}
-
-static int snd_cs4231_timer_close(struct snd_timer *timer)
-{
- struct snd_cs4231 *chip = snd_timer_chip(timer);
- snd_cs4231_close(chip, CS4231_MODE_TIMER);
- return 0;
-}
-
-static struct snd_timer_hardware snd_cs4231_timer_table = {
- .flags = SNDRV_TIMER_HW_AUTO,
- .resolution = 9945,
- .ticks = 65535,
- .open = snd_cs4231_timer_open,
- .close = snd_cs4231_timer_close,
- .c_resolution = snd_cs4231_timer_resolution,
- .start = snd_cs4231_timer_start,
- .stop = snd_cs4231_timer_stop,
-};
-
-/*
- * ok.. exported functions..
- */
-
-static int snd_cs4231_playback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
- unsigned char new_pdfr;
- int err;
-
- err = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
- new_pdfr = snd_cs4231_get_format(chip, params_format(hw_params),
- params_channels(hw_params)) |
- snd_cs4231_get_rate(params_rate(hw_params));
- snd_cs4231_playback_format(chip, hw_params, new_pdfr);
-
- return 0;
-}
-
-static int snd_cs4231_playback_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long flags;
-
- spin_lock_irqsave(&chip->lock, flags);
-
- chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE |
- CS4231_PLAYBACK_PIO);
-
- BUG_ON(runtime->period_size > 0xffff + 1);
-
- chip->p_periods_sent = 0;
- spin_unlock_irqrestore(&chip->lock, flags);
-
- return 0;
-}
-
-static int snd_cs4231_capture_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
- unsigned char new_cdfr;
- int err;
-
- err = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
- if (err < 0)
- return err;
- new_cdfr = snd_cs4231_get_format(chip, params_format(hw_params),
- params_channels(hw_params)) |
- snd_cs4231_get_rate(params_rate(hw_params));
- snd_cs4231_capture_format(chip, hw_params, new_cdfr);
-
- return 0;
-}
-
-static int snd_cs4231_capture_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
- unsigned long flags;
-
- spin_lock_irqsave(&chip->lock, flags);
- chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE |
- CS4231_RECORD_PIO);
-
-
- chip->c_periods_sent = 0;
- spin_unlock_irqrestore(&chip->lock, flags);
-
- return 0;
-}
-
-static void snd_cs4231_overrange(struct snd_cs4231 *chip)
-{
- unsigned long flags;
- unsigned char res;
-
- spin_lock_irqsave(&chip->lock, flags);
- res = snd_cs4231_in(chip, CS4231_TEST_INIT);
- spin_unlock_irqrestore(&chip->lock, flags);
-
- /* detect overrange only above 0dB; may be user selectable? */
- if (res & (0x08 | 0x02))
- chip->capture_substream->runtime->overrange++;
-}
-
-static void snd_cs4231_play_callback(struct snd_cs4231 *chip)
-{
- if (chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE) {
- snd_pcm_period_elapsed(chip->playback_substream);
- snd_cs4231_advance_dma(&chip->p_dma, chip->playback_substream,
- &chip->p_periods_sent);
- }
-}
-
-static void snd_cs4231_capture_callback(struct snd_cs4231 *chip)
-{
- if (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) {
- snd_pcm_period_elapsed(chip->capture_substream);
- snd_cs4231_advance_dma(&chip->c_dma, chip->capture_substream,
- &chip->c_periods_sent);
- }
-}
-
-static snd_pcm_uframes_t snd_cs4231_playback_pointer(
- struct snd_pcm_substream *substream)
-{
- struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
- struct cs4231_dma_control *dma_cont = &chip->p_dma;
- size_t ptr;
-
- if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE))
- return 0;
- ptr = dma_cont->address(dma_cont);
- if (ptr != 0)
- ptr -= substream->runtime->dma_addr;
-
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-static snd_pcm_uframes_t snd_cs4231_capture_pointer(
- struct snd_pcm_substream *substream)
-{
- struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
- struct cs4231_dma_control *dma_cont = &chip->c_dma;
- size_t ptr;
-
- if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE))
- return 0;
- ptr = dma_cont->address(dma_cont);
- if (ptr != 0)
- ptr -= substream->runtime->dma_addr;
-
- return bytes_to_frames(substream->runtime, ptr);
-}
-
-static int __devinit snd_cs4231_probe(struct snd_cs4231 *chip)
-{
- unsigned long flags;
- int i;
- int id = 0;
- int vers = 0;
- unsigned char *ptr;
-
- for (i = 0; i < 50; i++) {
- mb();
- if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT)
- msleep(2);
- else {
- spin_lock_irqsave(&chip->lock, flags);
- snd_cs4231_out(chip, CS4231_MISC_INFO, CS4231_MODE2);
- id = snd_cs4231_in(chip, CS4231_MISC_INFO) & 0x0f;
- vers = snd_cs4231_in(chip, CS4231_VERSION);
- spin_unlock_irqrestore(&chip->lock, flags);
- if (id == 0x0a)
- break; /* this is valid value */
- }
- }
- snd_printdd("cs4231: port = %p, id = 0x%x\n", chip->port, id);
- if (id != 0x0a)
- return -ENODEV; /* no valid device found */
-
- spin_lock_irqsave(&chip->lock, flags);
-
- /* clear any pendings IRQ */
- __cs4231_readb(chip, CS4231U(chip, STATUS));
- __cs4231_writeb(chip, 0, CS4231U(chip, STATUS));
- mb();
-
- spin_unlock_irqrestore(&chip->lock, flags);
-
- chip->image[CS4231_MISC_INFO] = CS4231_MODE2;
- chip->image[CS4231_IFACE_CTRL] =
- chip->image[CS4231_IFACE_CTRL] & ~CS4231_SINGLE_DMA;
- chip->image[CS4231_ALT_FEATURE_1] = 0x80;
- chip->image[CS4231_ALT_FEATURE_2] = 0x01;
- if (vers & 0x20)
- chip->image[CS4231_ALT_FEATURE_2] |= 0x02;
-
- ptr = (unsigned char *) &chip->image;
-
- snd_cs4231_mce_down(chip);
-
- spin_lock_irqsave(&chip->lock, flags);
-
- for (i = 0; i < 32; i++) /* ok.. fill all CS4231 registers */
- snd_cs4231_out(chip, i, *ptr++);
-
- spin_unlock_irqrestore(&chip->lock, flags);
-
- snd_cs4231_mce_up(chip);
-
- snd_cs4231_mce_down(chip);
-
- mdelay(2);
-
- return 0; /* all things are ok.. */
-}
-
-static struct snd_pcm_hardware snd_cs4231_playback = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_SYNC_START,
- .formats = SNDRV_PCM_FMTBIT_MU_LAW |
- SNDRV_PCM_FMTBIT_A_LAW |
- SNDRV_PCM_FMTBIT_IMA_ADPCM |
- SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S16_BE,
- .rates = SNDRV_PCM_RATE_KNOT |
- SNDRV_PCM_RATE_8000_48000,
- .rate_min = 5510,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 32 * 1024,
- .period_bytes_min = 64,
- .period_bytes_max = 32 * 1024,
- .periods_min = 1,
- .periods_max = 1024,
-};
-
-static struct snd_pcm_hardware snd_cs4231_capture = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_SYNC_START,
- .formats = SNDRV_PCM_FMTBIT_MU_LAW |
- SNDRV_PCM_FMTBIT_A_LAW |
- SNDRV_PCM_FMTBIT_IMA_ADPCM |
- SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S16_BE,
- .rates = SNDRV_PCM_RATE_KNOT |
- SNDRV_PCM_RATE_8000_48000,
- .rate_min = 5510,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 32 * 1024,
- .period_bytes_min = 64,
- .period_bytes_max = 32 * 1024,
- .periods_min = 1,
- .periods_max = 1024,
-};
-
-static int snd_cs4231_playback_open(struct snd_pcm_substream *substream)
-{
- struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- runtime->hw = snd_cs4231_playback;
-
- err = snd_cs4231_open(chip, CS4231_MODE_PLAY);
- if (err < 0) {
- snd_free_pages(runtime->dma_area, runtime->dma_bytes);
- return err;
- }
- chip->playback_substream = substream;
- chip->p_periods_sent = 0;
- snd_pcm_set_sync(substream);
- snd_cs4231_xrate(runtime);
-
- return 0;
-}
-
-static int snd_cs4231_capture_open(struct snd_pcm_substream *substream)
-{
- struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- runtime->hw = snd_cs4231_capture;
-
- err = snd_cs4231_open(chip, CS4231_MODE_RECORD);
- if (err < 0) {
- snd_free_pages(runtime->dma_area, runtime->dma_bytes);
- return err;
- }
- chip->capture_substream = substream;
- chip->c_periods_sent = 0;
- snd_pcm_set_sync(substream);
- snd_cs4231_xrate(runtime);
-
- return 0;
-}
-
-static int snd_cs4231_playback_close(struct snd_pcm_substream *substream)
-{
- struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
-
- snd_cs4231_close(chip, CS4231_MODE_PLAY);
- chip->playback_substream = NULL;
-
- return 0;
-}
-
-static int snd_cs4231_capture_close(struct snd_pcm_substream *substream)
-{
- struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
-
- snd_cs4231_close(chip, CS4231_MODE_RECORD);
- chip->capture_substream = NULL;
-
- return 0;
-}
-
-/* XXX We can do some power-management, in particular on EBUS using
- * XXX the audio AUXIO register...
- */
-
-static struct snd_pcm_ops snd_cs4231_playback_ops = {
- .open = snd_cs4231_playback_open,
- .close = snd_cs4231_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cs4231_playback_hw_params,
- .hw_free = snd_pcm_lib_free_pages,
- .prepare = snd_cs4231_playback_prepare,
- .trigger = snd_cs4231_trigger,
- .pointer = snd_cs4231_playback_pointer,
-};
-
-static struct snd_pcm_ops snd_cs4231_capture_ops = {
- .open = snd_cs4231_capture_open,
- .close = snd_cs4231_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cs4231_capture_hw_params,
- .hw_free = snd_pcm_lib_free_pages,
- .prepare = snd_cs4231_capture_prepare,
- .trigger = snd_cs4231_trigger,
- .pointer = snd_cs4231_capture_pointer,
-};
-
-static int __devinit snd_cs4231_pcm(struct snd_card *card)
-{
- struct snd_cs4231 *chip = card->private_data;
- struct snd_pcm *pcm;
- int err;
-
- err = snd_pcm_new(card, "CS4231", 0, 1, 1, &pcm);
- if (err < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_cs4231_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_cs4231_capture_ops);
-
- /* global setup */
- pcm->private_data = chip;
- pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
- strcpy(pcm->name, "CS4231");
-
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- &chip->op->dev,
- 64 * 1024, 128 * 1024);
-
- chip->pcm = pcm;
-
- return 0;
-}
-
-static int __devinit snd_cs4231_timer(struct snd_card *card)
-{
- struct snd_cs4231 *chip = card->private_data;
- struct snd_timer *timer;
- struct snd_timer_id tid;
- int err;
-
- /* Timer initialization */
- tid.dev_class = SNDRV_TIMER_CLASS_CARD;
- tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
- tid.card = card->number;
- tid.device = 0;
- tid.subdevice = 0;
- err = snd_timer_new(card, "CS4231", &tid, &timer);
- if (err < 0)
- return err;
- strcpy(timer->name, "CS4231");
- timer->private_data = chip;
- timer->hw = snd_cs4231_timer_table;
- chip->timer = timer;
-
- return 0;
-}
-
-/*
- * MIXER part
- */
-
-static int snd_cs4231_info_mux(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- static char *texts[4] = {
- "Line", "CD", "Mic", "Mix"
- };
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 2;
- uinfo->value.enumerated.items = 4;
- if (uinfo->value.enumerated.item > 3)
- uinfo->value.enumerated.item = 3;
- strcpy(uinfo->value.enumerated.name,
- texts[uinfo->value.enumerated.item]);
-
- return 0;
-}
-
-static int snd_cs4231_get_mux(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
-
- spin_lock_irqsave(&chip->lock, flags);
- ucontrol->value.enumerated.item[0] =
- (chip->image[CS4231_LEFT_INPUT] & CS4231_MIXS_ALL) >> 6;
- ucontrol->value.enumerated.item[1] =
- (chip->image[CS4231_RIGHT_INPUT] & CS4231_MIXS_ALL) >> 6;
- spin_unlock_irqrestore(&chip->lock, flags);
-
- return 0;
-}
-
-static int snd_cs4231_put_mux(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- unsigned short left, right;
- int change;
-
- if (ucontrol->value.enumerated.item[0] > 3 ||
- ucontrol->value.enumerated.item[1] > 3)
- return -EINVAL;
- left = ucontrol->value.enumerated.item[0] << 6;
- right = ucontrol->value.enumerated.item[1] << 6;
-
- spin_lock_irqsave(&chip->lock, flags);
-
- left = (chip->image[CS4231_LEFT_INPUT] & ~CS4231_MIXS_ALL) | left;
- right = (chip->image[CS4231_RIGHT_INPUT] & ~CS4231_MIXS_ALL) | right;
- change = left != chip->image[CS4231_LEFT_INPUT] ||
- right != chip->image[CS4231_RIGHT_INPUT];
- snd_cs4231_out(chip, CS4231_LEFT_INPUT, left);
- snd_cs4231_out(chip, CS4231_RIGHT_INPUT, right);
-
- spin_unlock_irqrestore(&chip->lock, flags);
-
- return change;
-}
-
-static int snd_cs4231_info_single(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 16) & 0xff;
-
- uinfo->type = (mask == 1) ?
- SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
-
- return 0;
-}
-
-static int snd_cs4231_get_single(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
-
- spin_lock_irqsave(&chip->lock, flags);
-
- ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask;
-
- spin_unlock_irqrestore(&chip->lock, flags);
-
- if (invert)
- ucontrol->value.integer.value[0] =
- (mask - ucontrol->value.integer.value[0]);
-
- return 0;
-}
-
-static int snd_cs4231_put_single(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
- int change;
- unsigned short val;
-
- val = (ucontrol->value.integer.value[0] & mask);
- if (invert)
- val = mask - val;
- val <<= shift;
-
- spin_lock_irqsave(&chip->lock, flags);
-
- val = (chip->image[reg] & ~(mask << shift)) | val;
- change = val != chip->image[reg];
- snd_cs4231_out(chip, reg, val);
-
- spin_unlock_irqrestore(&chip->lock, flags);
-
- return change;
-}
-
-static int snd_cs4231_info_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 24) & 0xff;
-
- uinfo->type = mask == 1 ?
- SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
-
- return 0;
-}
-
-static int snd_cs4231_get_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int shift_left = (kcontrol->private_value >> 16) & 0x07;
- int shift_right = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
-
- spin_lock_irqsave(&chip->lock, flags);
-
- ucontrol->value.integer.value[0] =
- (chip->image[left_reg] >> shift_left) & mask;
- ucontrol->value.integer.value[1] =
- (chip->image[right_reg] >> shift_right) & mask;
-
- spin_unlock_irqrestore(&chip->lock, flags);
-
- if (invert) {
- ucontrol->value.integer.value[0] =
- (mask - ucontrol->value.integer.value[0]);
- ucontrol->value.integer.value[1] =
- (mask - ucontrol->value.integer.value[1]);
- }
-
- return 0;
-}
-
-static int snd_cs4231_put_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int shift_left = (kcontrol->private_value >> 16) & 0x07;
- int shift_right = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
- int change;
- unsigned short val1, val2;
-
- val1 = ucontrol->value.integer.value[0] & mask;
- val2 = ucontrol->value.integer.value[1] & mask;
- if (invert) {
- val1 = mask - val1;
- val2 = mask - val2;
- }
- val1 <<= shift_left;
- val2 <<= shift_right;
-
- spin_lock_irqsave(&chip->lock, flags);
-
- val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
- val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2;
- change = val1 != chip->image[left_reg];
- change |= val2 != chip->image[right_reg];
- snd_cs4231_out(chip, left_reg, val1);
- snd_cs4231_out(chip, right_reg, val2);
-
- spin_unlock_irqrestore(&chip->lock, flags);
-
- return change;
-}
-
-#define CS4231_SINGLE(xname, xindex, reg, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), .index = (xindex), \
- .info = snd_cs4231_info_single, \
- .get = snd_cs4231_get_single, .put = snd_cs4231_put_single, \
- .private_value = (reg) | ((shift) << 8) | ((mask) << 16) | ((invert) << 24) }
-
-#define CS4231_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, \
- shift_right, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), .index = (xindex), \
- .info = snd_cs4231_info_double, \
- .get = snd_cs4231_get_double, .put = snd_cs4231_put_double, \
- .private_value = (left_reg) | ((right_reg) << 8) | ((shift_left) << 16) | \
- ((shift_right) << 19) | ((mask) << 24) | ((invert) << 22) }
-
-static struct snd_kcontrol_new snd_cs4231_controls[] __devinitdata = {
-CS4231_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT,
- CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
-CS4231_DOUBLE("PCM Playback Volume", 0, CS4231_LEFT_OUTPUT,
- CS4231_RIGHT_OUTPUT, 0, 0, 63, 1),
-CS4231_DOUBLE("Line Playback Switch", 0, CS4231_LEFT_LINE_IN,
- CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
-CS4231_DOUBLE("Line Playback Volume", 0, CS4231_LEFT_LINE_IN,
- CS4231_RIGHT_LINE_IN, 0, 0, 31, 1),
-CS4231_DOUBLE("Aux Playback Switch", 0, CS4231_AUX1_LEFT_INPUT,
- CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
-CS4231_DOUBLE("Aux Playback Volume", 0, CS4231_AUX1_LEFT_INPUT,
- CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1),
-CS4231_DOUBLE("Aux Playback Switch", 1, CS4231_AUX2_LEFT_INPUT,
- CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
-CS4231_DOUBLE("Aux Playback Volume", 1, CS4231_AUX2_LEFT_INPUT,
- CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1),
-CS4231_SINGLE("Mono Playback Switch", 0, CS4231_MONO_CTRL, 7, 1, 1),
-CS4231_SINGLE("Mono Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1),
-CS4231_SINGLE("Mono Output Playback Switch", 0, CS4231_MONO_CTRL, 6, 1, 1),
-CS4231_SINGLE("Mono Output Playback Bypass", 0, CS4231_MONO_CTRL, 5, 1, 0),
-CS4231_DOUBLE("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0,
- 15, 0),
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = snd_cs4231_info_mux,
- .get = snd_cs4231_get_mux,
- .put = snd_cs4231_put_mux,
-},
-CS4231_DOUBLE("Mic Boost", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5,
- 1, 0),
-CS4231_SINGLE("Loopback Capture Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
-CS4231_SINGLE("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1),
-/* SPARC specific uses of XCTL{0,1} general purpose outputs. */
-CS4231_SINGLE("Line Out Switch", 0, CS4231_PIN_CTRL, 6, 1, 1),
-CS4231_SINGLE("Headphone Out Switch", 0, CS4231_PIN_CTRL, 7, 1, 1)
-};
-
-static int __devinit snd_cs4231_mixer(struct snd_card *card)
-{
- struct snd_cs4231 *chip = card->private_data;
- int err, idx;
-
- if (snd_BUG_ON(!chip || !chip->pcm))
- return -EINVAL;
-
- strcpy(card->mixername, chip->pcm->name);
-
- for (idx = 0; idx < ARRAY_SIZE(snd_cs4231_controls); idx++) {
- err = snd_ctl_add(card,
- snd_ctl_new1(&snd_cs4231_controls[idx], chip));
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-static int dev;
-
-static int __devinit cs4231_attach_begin(struct snd_card **rcard)
-{
- struct snd_card *card;
- struct snd_cs4231 *chip;
- int err;
-
- *rcard = NULL;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
-
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_cs4231), &card);
- if (err < 0)
- return err;
-
- strcpy(card->driver, "CS4231");
- strcpy(card->shortname, "Sun CS4231");
-
- chip = card->private_data;
- chip->card = card;
-
- *rcard = card;
- return 0;
-}
-
-static int __devinit cs4231_attach_finish(struct snd_card *card)
-{
- struct snd_cs4231 *chip = card->private_data;
- int err;
-
- err = snd_cs4231_pcm(card);
- if (err < 0)
- goto out_err;
-
- err = snd_cs4231_mixer(card);
- if (err < 0)
- goto out_err;
-
- err = snd_cs4231_timer(card);
- if (err < 0)
- goto out_err;
-
- err = snd_card_register(card);
- if (err < 0)
- goto out_err;
-
- dev_set_drvdata(&chip->op->dev, chip);
-
- dev++;
- return 0;
-
-out_err:
- snd_card_free(card);
- return err;
-}
-
-#ifdef SBUS_SUPPORT
-
-static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id)
-{
- unsigned long flags;
- unsigned char status;
- u32 csr;
- struct snd_cs4231 *chip = dev_id;
-
- /*This is IRQ is not raised by the cs4231*/
- if (!(__cs4231_readb(chip, CS4231U(chip, STATUS)) & CS4231_GLOBALIRQ))
- return IRQ_NONE;
-
- /* ACK the APC interrupt. */
- csr = sbus_readl(chip->port + APCCSR);
-
- sbus_writel(csr, chip->port + APCCSR);
-
- if ((csr & APC_PDMA_READY) &&
- (csr & APC_PLAY_INT) &&
- (csr & APC_XINT_PNVA) &&
- !(csr & APC_XINT_EMPT))
- snd_cs4231_play_callback(chip);
-
- if ((csr & APC_CDMA_READY) &&
- (csr & APC_CAPT_INT) &&
- (csr & APC_XINT_CNVA) &&
- !(csr & APC_XINT_EMPT))
- snd_cs4231_capture_callback(chip);
-
- status = snd_cs4231_in(chip, CS4231_IRQ_STATUS);
-
- if (status & CS4231_TIMER_IRQ) {
- if (chip->timer)
- snd_timer_interrupt(chip->timer, chip->timer->sticks);
- }
-
- if ((status & CS4231_RECORD_IRQ) && (csr & APC_CDMA_READY))
- snd_cs4231_overrange(chip);
-
- /* ACK the CS4231 interrupt. */
- spin_lock_irqsave(&chip->lock, flags);
- snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0);
- spin_unlock_irqrestore(&chip->lock, flags);
-
- return IRQ_HANDLED;
-}
-
-/*
- * SBUS DMA routines
- */
-
-static int sbus_dma_request(struct cs4231_dma_control *dma_cont,
- dma_addr_t bus_addr, size_t len)
-{
- unsigned long flags;
- u32 test, csr;
- int err;
- struct sbus_dma_info *base = &dma_cont->sbus_info;
-
- if (len >= (1 << 24))
- return -EINVAL;
- spin_lock_irqsave(&base->lock, flags);
- csr = sbus_readl(base->regs + APCCSR);
- err = -EINVAL;
- test = APC_CDMA_READY;
- if (base->dir == APC_PLAY)
- test = APC_PDMA_READY;
- if (!(csr & test))
- goto out;
- err = -EBUSY;
- test = APC_XINT_CNVA;
- if (base->dir == APC_PLAY)
- test = APC_XINT_PNVA;
- if (!(csr & test))
- goto out;
- err = 0;
- sbus_writel(bus_addr, base->regs + base->dir + APCNVA);
- sbus_writel(len, base->regs + base->dir + APCNC);
-out:
- spin_unlock_irqrestore(&base->lock, flags);
- return err;
-}
-
-static void sbus_dma_prepare(struct cs4231_dma_control *dma_cont, int d)
-{
- unsigned long flags;
- u32 csr, test;
- struct sbus_dma_info *base = &dma_cont->sbus_info;
-
- spin_lock_irqsave(&base->lock, flags);
- csr = sbus_readl(base->regs + APCCSR);
- test = APC_GENL_INT | APC_PLAY_INT | APC_XINT_ENA |
- APC_XINT_PLAY | APC_XINT_PEMP | APC_XINT_GENL |
- APC_XINT_PENA;
- if (base->dir == APC_RECORD)
- test = APC_GENL_INT | APC_CAPT_INT | APC_XINT_ENA |
- APC_XINT_CAPT | APC_XINT_CEMP | APC_XINT_GENL;
- csr |= test;
- sbus_writel(csr, base->regs + APCCSR);
- spin_unlock_irqrestore(&base->lock, flags);
-}
-
-static void sbus_dma_enable(struct cs4231_dma_control *dma_cont, int on)
-{
- unsigned long flags;
- u32 csr, shift;
- struct sbus_dma_info *base = &dma_cont->sbus_info;
-
- spin_lock_irqsave(&base->lock, flags);
- if (!on) {
- sbus_writel(0, base->regs + base->dir + APCNC);
- sbus_writel(0, base->regs + base->dir + APCNVA);
- if (base->dir == APC_PLAY) {
- sbus_writel(0, base->regs + base->dir + APCC);
- sbus_writel(0, base->regs + base->dir + APCVA);
- }
-
- udelay(1200);
- }
- csr = sbus_readl(base->regs + APCCSR);
- shift = 0;
- if (base->dir == APC_PLAY)
- shift = 1;
- if (on)
- csr &= ~(APC_CPAUSE << shift);
- else
- csr |= (APC_CPAUSE << shift);
- sbus_writel(csr, base->regs + APCCSR);
- if (on)
- csr |= (APC_CDMA_READY << shift);
- else
- csr &= ~(APC_CDMA_READY << shift);
- sbus_writel(csr, base->regs + APCCSR);
-
- spin_unlock_irqrestore(&base->lock, flags);
-}
-
-static unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont)
-{
- struct sbus_dma_info *base = &dma_cont->sbus_info;
-
- return sbus_readl(base->regs + base->dir + APCVA);
-}
-
-/*
- * Init and exit routines
- */
-
-static int snd_cs4231_sbus_free(struct snd_cs4231 *chip)
-{
- struct platform_device *op = chip->op;
-
- if (chip->irq[0])
- free_irq(chip->irq[0], chip);
-
- if (chip->port)
- of_iounmap(&op->resource[0], chip->port, chip->regs_size);
-
- return 0;
-}
-
-static int snd_cs4231_sbus_dev_free(struct snd_device *device)
-{
- struct snd_cs4231 *cp = device->device_data;
-
- return snd_cs4231_sbus_free(cp);
-}
-
-static struct snd_device_ops snd_cs4231_sbus_dev_ops = {
- .dev_free = snd_cs4231_sbus_dev_free,
-};
-
-static int __devinit snd_cs4231_sbus_create(struct snd_card *card,
- struct platform_device *op,
- int dev)
-{
- struct snd_cs4231 *chip = card->private_data;
- int err;
-
- spin_lock_init(&chip->lock);
- spin_lock_init(&chip->c_dma.sbus_info.lock);
- spin_lock_init(&chip->p_dma.sbus_info.lock);
- mutex_init(&chip->mce_mutex);
- mutex_init(&chip->open_mutex);
- chip->op = op;
- chip->regs_size = resource_size(&op->resource[0]);
- memcpy(&chip->image, &snd_cs4231_original_image,
- sizeof(snd_cs4231_original_image));
-
- chip->port = of_ioremap(&op->resource[0], 0,
- chip->regs_size, "cs4231");
- if (!chip->port) {
- snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev);
- return -EIO;
- }
-
- chip->c_dma.sbus_info.regs = chip->port;
- chip->p_dma.sbus_info.regs = chip->port;
- chip->c_dma.sbus_info.dir = APC_RECORD;
- chip->p_dma.sbus_info.dir = APC_PLAY;
-
- chip->p_dma.prepare = sbus_dma_prepare;
- chip->p_dma.enable = sbus_dma_enable;
- chip->p_dma.request = sbus_dma_request;
- chip->p_dma.address = sbus_dma_addr;
-
- chip->c_dma.prepare = sbus_dma_prepare;
- chip->c_dma.enable = sbus_dma_enable;
- chip->c_dma.request = sbus_dma_request;
- chip->c_dma.address = sbus_dma_addr;
-
- if (request_irq(op->archdata.irqs[0], snd_cs4231_sbus_interrupt,
- IRQF_SHARED, "cs4231", chip)) {
- snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %d\n",
- dev, op->archdata.irqs[0]);
- snd_cs4231_sbus_free(chip);
- return -EBUSY;
- }
- chip->irq[0] = op->archdata.irqs[0];
-
- if (snd_cs4231_probe(chip) < 0) {
- snd_cs4231_sbus_free(chip);
- return -ENODEV;
- }
- snd_cs4231_init(chip);
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
- chip, &snd_cs4231_sbus_dev_ops)) < 0) {
- snd_cs4231_sbus_free(chip);
- return err;
- }
-
- return 0;
-}
-
-static int __devinit cs4231_sbus_probe(struct platform_device *op)
-{
- struct resource *rp = &op->resource[0];
- struct snd_card *card;
- int err;
-
- err = cs4231_attach_begin(&card);
- if (err)
- return err;
-
- sprintf(card->longname, "%s at 0x%02lx:0x%016Lx, irq %d",
- card->shortname,
- rp->flags & 0xffL,
- (unsigned long long)rp->start,
- op->archdata.irqs[0]);
-
- err = snd_cs4231_sbus_create(card, op, dev);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- return cs4231_attach_finish(card);
-}
-#endif
-
-#ifdef EBUS_SUPPORT
-
-static void snd_cs4231_ebus_play_callback(struct ebus_dma_info *p, int event,
- void *cookie)
-{
- struct snd_cs4231 *chip = cookie;
-
- snd_cs4231_play_callback(chip);
-}
-
-static void snd_cs4231_ebus_capture_callback(struct ebus_dma_info *p,
- int event, void *cookie)
-{
- struct snd_cs4231 *chip = cookie;
-
- snd_cs4231_capture_callback(chip);
-}
-
-/*
- * EBUS DMA wrappers
- */
-
-static int _ebus_dma_request(struct cs4231_dma_control *dma_cont,
- dma_addr_t bus_addr, size_t len)
-{
- return ebus_dma_request(&dma_cont->ebus_info, bus_addr, len);
-}
-
-static void _ebus_dma_enable(struct cs4231_dma_control *dma_cont, int on)
-{
- ebus_dma_enable(&dma_cont->ebus_info, on);
-}
-
-static void _ebus_dma_prepare(struct cs4231_dma_control *dma_cont, int dir)
-{
- ebus_dma_prepare(&dma_cont->ebus_info, dir);
-}
-
-static unsigned int _ebus_dma_addr(struct cs4231_dma_control *dma_cont)
-{
- return ebus_dma_addr(&dma_cont->ebus_info);
-}
-
-/*
- * Init and exit routines
- */
-
-static int snd_cs4231_ebus_free(struct snd_cs4231 *chip)
-{
- struct platform_device *op = chip->op;
-
- if (chip->c_dma.ebus_info.regs) {
- ebus_dma_unregister(&chip->c_dma.ebus_info);
- of_iounmap(&op->resource[2], chip->c_dma.ebus_info.regs, 0x10);
- }
- if (chip->p_dma.ebus_info.regs) {
- ebus_dma_unregister(&chip->p_dma.ebus_info);
- of_iounmap(&op->resource[1], chip->p_dma.ebus_info.regs, 0x10);
- }
-
- if (chip->port)
- of_iounmap(&op->resource[0], chip->port, 0x10);
-
- return 0;
-}
-
-static int snd_cs4231_ebus_dev_free(struct snd_device *device)
-{
- struct snd_cs4231 *cp = device->device_data;
-
- return snd_cs4231_ebus_free(cp);
-}
-
-static struct snd_device_ops snd_cs4231_ebus_dev_ops = {
- .dev_free = snd_cs4231_ebus_dev_free,
-};
-
-static int __devinit snd_cs4231_ebus_create(struct snd_card *card,
- struct platform_device *op,
- int dev)
-{
- struct snd_cs4231 *chip = card->private_data;
- int err;
-
- spin_lock_init(&chip->lock);
- spin_lock_init(&chip->c_dma.ebus_info.lock);
- spin_lock_init(&chip->p_dma.ebus_info.lock);
- mutex_init(&chip->mce_mutex);
- mutex_init(&chip->open_mutex);
- chip->flags |= CS4231_FLAG_EBUS;
- chip->op = op;
- memcpy(&chip->image, &snd_cs4231_original_image,
- sizeof(snd_cs4231_original_image));
- strcpy(chip->c_dma.ebus_info.name, "cs4231(capture)");
- chip->c_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER;
- chip->c_dma.ebus_info.callback = snd_cs4231_ebus_capture_callback;
- chip->c_dma.ebus_info.client_cookie = chip;
- chip->c_dma.ebus_info.irq = op->archdata.irqs[0];
- strcpy(chip->p_dma.ebus_info.name, "cs4231(play)");
- chip->p_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER;
- chip->p_dma.ebus_info.callback = snd_cs4231_ebus_play_callback;
- chip->p_dma.ebus_info.client_cookie = chip;
- chip->p_dma.ebus_info.irq = op->archdata.irqs[1];
-
- chip->p_dma.prepare = _ebus_dma_prepare;
- chip->p_dma.enable = _ebus_dma_enable;
- chip->p_dma.request = _ebus_dma_request;
- chip->p_dma.address = _ebus_dma_addr;
-
- chip->c_dma.prepare = _ebus_dma_prepare;
- chip->c_dma.enable = _ebus_dma_enable;
- chip->c_dma.request = _ebus_dma_request;
- chip->c_dma.address = _ebus_dma_addr;
-
- chip->port = of_ioremap(&op->resource[0], 0, 0x10, "cs4231");
- chip->p_dma.ebus_info.regs =
- of_ioremap(&op->resource[1], 0, 0x10, "cs4231_pdma");
- chip->c_dma.ebus_info.regs =
- of_ioremap(&op->resource[2], 0, 0x10, "cs4231_cdma");
- if (!chip->port || !chip->p_dma.ebus_info.regs ||
- !chip->c_dma.ebus_info.regs) {
- snd_cs4231_ebus_free(chip);
- snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev);
- return -EIO;
- }
-
- if (ebus_dma_register(&chip->c_dma.ebus_info)) {
- snd_cs4231_ebus_free(chip);
- snd_printdd("cs4231-%d: Unable to register EBUS capture DMA\n",
- dev);
- return -EBUSY;
- }
- if (ebus_dma_irq_enable(&chip->c_dma.ebus_info, 1)) {
- snd_cs4231_ebus_free(chip);
- snd_printdd("cs4231-%d: Unable to enable EBUS capture IRQ\n",
- dev);
- return -EBUSY;
- }
-
- if (ebus_dma_register(&chip->p_dma.ebus_info)) {
- snd_cs4231_ebus_free(chip);
- snd_printdd("cs4231-%d: Unable to register EBUS play DMA\n",
- dev);
- return -EBUSY;
- }
- if (ebus_dma_irq_enable(&chip->p_dma.ebus_info, 1)) {
- snd_cs4231_ebus_free(chip);
- snd_printdd("cs4231-%d: Unable to enable EBUS play IRQ\n", dev);
- return -EBUSY;
- }
-
- if (snd_cs4231_probe(chip) < 0) {
- snd_cs4231_ebus_free(chip);
- return -ENODEV;
- }
- snd_cs4231_init(chip);
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
- chip, &snd_cs4231_ebus_dev_ops)) < 0) {
- snd_cs4231_ebus_free(chip);
- return err;
- }
-
- return 0;
-}
-
-static int __devinit cs4231_ebus_probe(struct platform_device *op)
-{
- struct snd_card *card;
- int err;
-
- err = cs4231_attach_begin(&card);
- if (err)
- return err;
-
- sprintf(card->longname, "%s at 0x%llx, irq %d",
- card->shortname,
- op->resource[0].start,
- op->archdata.irqs[0]);
-
- err = snd_cs4231_ebus_create(card, op, dev);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- return cs4231_attach_finish(card);
-}
-#endif
-
-static int __devinit cs4231_probe(struct platform_device *op)
-{
-#ifdef EBUS_SUPPORT
- if (!strcmp(op->dev.of_node->parent->name, "ebus"))
- return cs4231_ebus_probe(op);
-#endif
-#ifdef SBUS_SUPPORT
- if (!strcmp(op->dev.of_node->parent->name, "sbus") ||
- !strcmp(op->dev.of_node->parent->name, "sbi"))
- return cs4231_sbus_probe(op);
-#endif
- return -ENODEV;
-}
-
-static int __devexit cs4231_remove(struct platform_device *op)
-{
- struct snd_cs4231 *chip = dev_get_drvdata(&op->dev);
-
- snd_card_free(chip->card);
-
- return 0;
-}
-
-static const struct of_device_id cs4231_match[] = {
- {
- .name = "SUNW,CS4231",
- },
- {
- .name = "audio",
- .compatible = "SUNW,CS4231",
- },
- {},
-};
-
-MODULE_DEVICE_TABLE(of, cs4231_match);
-
-static struct platform_driver cs4231_driver = {
- .driver = {
- .name = "audio",
- .owner = THIS_MODULE,
- .of_match_table = cs4231_match,
- },
- .probe = cs4231_probe,
- .remove = __devexit_p(cs4231_remove),
-};
-
-module_platform_driver(cs4231_driver);
diff --git a/ANDROID_3.4.5/sound/sparc/dbri.c b/ANDROID_3.4.5/sound/sparc/dbri.c
deleted file mode 100644
index a6b0deb7..00000000
--- a/ANDROID_3.4.5/sound/sparc/dbri.c
+++ /dev/null
@@ -1,2700 +0,0 @@
-/*
- * Driver for DBRI sound chip found on Sparcs.
- * Copyright (C) 2004, 2005 Martin Habets (mhabets@users.sourceforge.net)
- *
- * Converted to ring buffered version by Krzysztof Helt (krzysztof.h1@wp.pl)
- *
- * Based entirely upon drivers/sbus/audio/dbri.c which is:
- * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de)
- * Copyright (C) 1998, 1999 Brent Baccala (baccala@freesoft.org)
- *
- * This is the low level driver for the DBRI & MMCODEC duo used for ISDN & AUDIO
- * on Sun SPARCStation 10, 20, LX and Voyager models.
- *
- * - DBRI: AT&T T5900FX Dual Basic Rates ISDN Interface. It is a 32 channel
- * data time multiplexer with ISDN support (aka T7259)
- * Interfaces: SBus,ISDN NT & TE, CHI, 4 bits parallel.
- * CHI: (spelled ki) Concentration Highway Interface (AT&T or Intel bus ?).
- * Documentation:
- * - "STP 4000SBus Dual Basic Rate ISDN (DBRI) Transceiver" from
- * Sparc Technology Business (courtesy of Sun Support)
- * - Data sheet of the T7903, a newer but very similar ISA bus equivalent
- * available from the Lucent (formerly AT&T microelectronics) home
- * page.
- * - http://www.freesoft.org/Linux/DBRI/
- * - MMCODEC: Crystal Semiconductor CS4215 16 bit Multimedia Audio Codec
- * Interfaces: CHI, Audio In & Out, 2 bits parallel
- * Documentation: from the Crystal Semiconductor home page.
- *
- * The DBRI is a 32 pipe machine, each pipe can transfer some bits between
- * memory and a serial device (long pipes, no. 0-15) or between two serial
- * devices (short pipes, no. 16-31), or simply send a fixed data to a serial
- * device (short pipes).
- * A timeslot defines the bit-offset and no. of bits read from a serial device.
- * The timeslots are linked to 6 circular lists, one for each direction for
- * each serial device (NT,TE,CHI). A timeslot is associated to 1 or 2 pipes
- * (the second one is a monitor/tee pipe, valid only for serial input).
- *
- * The mmcodec is connected via the CHI bus and needs the data & some
- * parameters (volume, output selection) time multiplexed in 8 byte
- * chunks. It also has a control mode, which serves for audio format setting.
- *
- * Looking at the CS4215 data sheet it is easy to set up 2 or 4 codecs on
- * the same CHI bus, so I thought perhaps it is possible to use the on-board
- * & the speakerbox codec simultaneously, giving 2 (not very independent :-)
- * audio devices. But the SUN HW group decided against it, at least on my
- * LX the speakerbox connector has at least 1 pin missing and 1 wrongly
- * connected.
- *
- * I've tried to stick to the following function naming conventions:
- * snd_* ALSA stuff
- * cs4215_* CS4215 codec specific stuff
- * dbri_* DBRI high-level stuff
- * other DBRI low-level stuff
- */
-
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/dma-mapping.h>
-#include <linux/gfp.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/info.h>
-#include <sound/control.h>
-#include <sound/initval.h>
-
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/atomic.h>
-#include <linux/module.h>
-
-MODULE_AUTHOR("Rudolf Koenig, Brent Baccala and Martin Habets");
-MODULE_DESCRIPTION("Sun DBRI");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Sun,DBRI}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-/* Enable this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Sun DBRI soundcard.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Sun DBRI soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Sun DBRI soundcard.");
-
-#undef DBRI_DEBUG
-
-#define D_INT (1<<0)
-#define D_GEN (1<<1)
-#define D_CMD (1<<2)
-#define D_MM (1<<3)
-#define D_USR (1<<4)
-#define D_DESC (1<<5)
-
-static int dbri_debug;
-module_param(dbri_debug, int, 0644);
-MODULE_PARM_DESC(dbri_debug, "Debug value for Sun DBRI soundcard.");
-
-#ifdef DBRI_DEBUG
-static char *cmds[] = {
- "WAIT", "PAUSE", "JUMP", "IIQ", "REX", "SDP", "CDP", "DTS",
- "SSP", "CHI", "NT", "TE", "CDEC", "TEST", "CDM", "RESRV"
-};
-
-#define dprintk(a, x...) if (dbri_debug & a) printk(KERN_DEBUG x)
-
-#else
-#define dprintk(a, x...) do { } while (0)
-
-#endif /* DBRI_DEBUG */
-
-#define DBRI_CMD(cmd, intr, value) ((cmd << 28) | \
- (intr << 27) | \
- value)
-
-/***************************************************************************
- CS4215 specific definitions and structures
-****************************************************************************/
-
-struct cs4215 {
- __u8 data[4]; /* Data mode: Time slots 5-8 */
- __u8 ctrl[4]; /* Ctrl mode: Time slots 1-4 */
- __u8 onboard;
- __u8 offset; /* Bit offset from frame sync to time slot 1 */
- volatile __u32 status;
- volatile __u32 version;
- __u8 precision; /* In bits, either 8 or 16 */
- __u8 channels; /* 1 or 2 */
-};
-
-/*
- * Control mode first
- */
-
-/* Time Slot 1, Status register */
-#define CS4215_CLB (1<<2) /* Control Latch Bit */
-#define CS4215_OLB (1<<3) /* 1: line: 2.0V, speaker 4V */
- /* 0: line: 2.8V, speaker 8V */
-#define CS4215_MLB (1<<4) /* 1: Microphone: 20dB gain disabled */
-#define CS4215_RSRVD_1 (1<<5)
-
-/* Time Slot 2, Data Format Register */
-#define CS4215_DFR_LINEAR16 0
-#define CS4215_DFR_ULAW 1
-#define CS4215_DFR_ALAW 2
-#define CS4215_DFR_LINEAR8 3
-#define CS4215_DFR_STEREO (1<<2)
-static struct {
- unsigned short freq;
- unsigned char xtal;
- unsigned char csval;
-} CS4215_FREQ[] = {
- { 8000, (1 << 4), (0 << 3) },
- { 16000, (1 << 4), (1 << 3) },
- { 27429, (1 << 4), (2 << 3) }, /* Actually 24428.57 */
- { 32000, (1 << 4), (3 << 3) },
- /* { NA, (1 << 4), (4 << 3) }, */
- /* { NA, (1 << 4), (5 << 3) }, */
- { 48000, (1 << 4), (6 << 3) },
- { 9600, (1 << 4), (7 << 3) },
- { 5512, (2 << 4), (0 << 3) }, /* Actually 5512.5 */
- { 11025, (2 << 4), (1 << 3) },
- { 18900, (2 << 4), (2 << 3) },
- { 22050, (2 << 4), (3 << 3) },
- { 37800, (2 << 4), (4 << 3) },
- { 44100, (2 << 4), (5 << 3) },
- { 33075, (2 << 4), (6 << 3) },
- { 6615, (2 << 4), (7 << 3) },
- { 0, 0, 0}
-};
-
-#define CS4215_HPF (1<<7) /* High Pass Filter, 1: Enabled */
-
-#define CS4215_12_MASK 0xfcbf /* Mask off reserved bits in slot 1 & 2 */
-
-/* Time Slot 3, Serial Port Control register */
-#define CS4215_XEN (1<<0) /* 0: Enable serial output */
-#define CS4215_XCLK (1<<1) /* 1: Master mode: Generate SCLK */
-#define CS4215_BSEL_64 (0<<2) /* Bitrate: 64 bits per frame */
-#define CS4215_BSEL_128 (1<<2)
-#define CS4215_BSEL_256 (2<<2)
-#define CS4215_MCK_MAST (0<<4) /* Master clock */
-#define CS4215_MCK_XTL1 (1<<4) /* 24.576 MHz clock source */
-#define CS4215_MCK_XTL2 (2<<4) /* 16.9344 MHz clock source */
-#define CS4215_MCK_CLK1 (3<<4) /* Clockin, 256 x Fs */
-#define CS4215_MCK_CLK2 (4<<4) /* Clockin, see DFR */
-
-/* Time Slot 4, Test Register */
-#define CS4215_DAD (1<<0) /* 0:Digital-Dig loop, 1:Dig-Analog-Dig loop */
-#define CS4215_ENL (1<<1) /* Enable Loopback Testing */
-
-/* Time Slot 5, Parallel Port Register */
-/* Read only here and the same as the in data mode */
-
-/* Time Slot 6, Reserved */
-
-/* Time Slot 7, Version Register */
-#define CS4215_VERSION_MASK 0xf /* Known versions 0/C, 1/D, 2/E */
-
-/* Time Slot 8, Reserved */
-
-/*
- * Data mode
- */
-/* Time Slot 1-2: Left Channel Data, 2-3: Right Channel Data */
-
-/* Time Slot 5, Output Setting */
-#define CS4215_LO(v) v /* Left Output Attenuation 0x3f: -94.5 dB */
-#define CS4215_LE (1<<6) /* Line Out Enable */
-#define CS4215_HE (1<<7) /* Headphone Enable */
-
-/* Time Slot 6, Output Setting */
-#define CS4215_RO(v) v /* Right Output Attenuation 0x3f: -94.5 dB */
-#define CS4215_SE (1<<6) /* Speaker Enable */
-#define CS4215_ADI (1<<7) /* A/D Data Invalid: Busy in calibration */
-
-/* Time Slot 7, Input Setting */
-#define CS4215_LG(v) v /* Left Gain Setting 0xf: 22.5 dB */
-#define CS4215_IS (1<<4) /* Input Select: 1=Microphone, 0=Line */
-#define CS4215_OVR (1<<5) /* 1: Over range condition occurred */
-#define CS4215_PIO0 (1<<6) /* Parallel I/O 0 */
-#define CS4215_PIO1 (1<<7)
-
-/* Time Slot 8, Input Setting */
-#define CS4215_RG(v) v /* Right Gain Setting 0xf: 22.5 dB */
-#define CS4215_MA(v) (v<<4) /* Monitor Path Attenuation 0xf: mute */
-
-/***************************************************************************
- DBRI specific definitions and structures
-****************************************************************************/
-
-/* DBRI main registers */
-#define REG0 0x00 /* Status and Control */
-#define REG1 0x04 /* Mode and Interrupt */
-#define REG2 0x08 /* Parallel IO */
-#define REG3 0x0c /* Test */
-#define REG8 0x20 /* Command Queue Pointer */
-#define REG9 0x24 /* Interrupt Queue Pointer */
-
-#define DBRI_NO_CMDS 64
-#define DBRI_INT_BLK 64
-#define DBRI_NO_DESCS 64
-#define DBRI_NO_PIPES 32
-#define DBRI_MAX_PIPE (DBRI_NO_PIPES - 1)
-
-#define DBRI_REC 0
-#define DBRI_PLAY 1
-#define DBRI_NO_STREAMS 2
-
-/* One transmit/receive descriptor */
-/* When ba != 0 descriptor is used */
-struct dbri_mem {
- volatile __u32 word1;
- __u32 ba; /* Transmit/Receive Buffer Address */
- __u32 nda; /* Next Descriptor Address */
- volatile __u32 word4;
-};
-
-/* This structure is in a DMA region where it can accessed by both
- * the CPU and the DBRI
- */
-struct dbri_dma {
- s32 cmd[DBRI_NO_CMDS]; /* Place for commands */
- volatile s32 intr[DBRI_INT_BLK]; /* Interrupt field */
- struct dbri_mem desc[DBRI_NO_DESCS]; /* Xmit/receive descriptors */
-};
-
-#define dbri_dma_off(member, elem) \
- ((u32)(unsigned long) \
- (&(((struct dbri_dma *)0)->member[elem])))
-
-enum in_or_out { PIPEinput, PIPEoutput };
-
-struct dbri_pipe {
- u32 sdp; /* SDP command word */
- int nextpipe; /* Next pipe in linked list */
- int length; /* Length of timeslot (bits) */
- int first_desc; /* Index of first descriptor */
- int desc; /* Index of active descriptor */
- volatile __u32 *recv_fixed_ptr; /* Ptr to receive fixed data */
-};
-
-/* Per stream (playback or record) information */
-struct dbri_streaminfo {
- struct snd_pcm_substream *substream;
- u32 dvma_buffer; /* Device view of ALSA DMA buffer */
- int size; /* Size of DMA buffer */
- size_t offset; /* offset in user buffer */
- int pipe; /* Data pipe used */
- int left_gain; /* mixer elements */
- int right_gain;
-};
-
-/* This structure holds the information for both chips (DBRI & CS4215) */
-struct snd_dbri {
- int regs_size, irq; /* Needed for unload */
- struct platform_device *op; /* OF device info */
- spinlock_t lock;
-
- struct dbri_dma *dma; /* Pointer to our DMA block */
- u32 dma_dvma; /* DBRI visible DMA address */
-
- void __iomem *regs; /* dbri HW regs */
- int dbri_irqp; /* intr queue pointer */
-
- struct dbri_pipe pipes[DBRI_NO_PIPES]; /* DBRI's 32 data pipes */
- int next_desc[DBRI_NO_DESCS]; /* Index of next desc, or -1 */
- spinlock_t cmdlock; /* Protects cmd queue accesses */
- s32 *cmdptr; /* Pointer to the last queued cmd */
-
- int chi_bpf;
-
- struct cs4215 mm; /* mmcodec special info */
- /* per stream (playback/record) info */
- struct dbri_streaminfo stream_info[DBRI_NO_STREAMS];
-};
-
-#define DBRI_MAX_VOLUME 63 /* Output volume */
-#define DBRI_MAX_GAIN 15 /* Input gain */
-
-/* DBRI Reg0 - Status Control Register - defines. (Page 17) */
-#define D_P (1<<15) /* Program command & queue pointer valid */
-#define D_G (1<<14) /* Allow 4-Word SBus Burst */
-#define D_S (1<<13) /* Allow 16-Word SBus Burst */
-#define D_E (1<<12) /* Allow 8-Word SBus Burst */
-#define D_X (1<<7) /* Sanity Timer Disable */
-#define D_T (1<<6) /* Permit activation of the TE interface */
-#define D_N (1<<5) /* Permit activation of the NT interface */
-#define D_C (1<<4) /* Permit activation of the CHI interface */
-#define D_F (1<<3) /* Force Sanity Timer Time-Out */
-#define D_D (1<<2) /* Disable Master Mode */
-#define D_H (1<<1) /* Halt for Analysis */
-#define D_R (1<<0) /* Soft Reset */
-
-/* DBRI Reg1 - Mode and Interrupt Register - defines. (Page 18) */
-#define D_LITTLE_END (1<<8) /* Byte Order */
-#define D_BIG_END (0<<8) /* Byte Order */
-#define D_MRR (1<<4) /* Multiple Error Ack on SBus (read only) */
-#define D_MLE (1<<3) /* Multiple Late Error on SBus (read only) */
-#define D_LBG (1<<2) /* Lost Bus Grant on SBus (read only) */
-#define D_MBE (1<<1) /* Burst Error on SBus (read only) */
-#define D_IR (1<<0) /* Interrupt Indicator (read only) */
-
-/* DBRI Reg2 - Parallel IO Register - defines. (Page 18) */
-#define D_ENPIO3 (1<<7) /* Enable Pin 3 */
-#define D_ENPIO2 (1<<6) /* Enable Pin 2 */
-#define D_ENPIO1 (1<<5) /* Enable Pin 1 */
-#define D_ENPIO0 (1<<4) /* Enable Pin 0 */
-#define D_ENPIO (0xf0) /* Enable all the pins */
-#define D_PIO3 (1<<3) /* Pin 3: 1: Data mode, 0: Ctrl mode */
-#define D_PIO2 (1<<2) /* Pin 2: 1: Onboard PDN */
-#define D_PIO1 (1<<1) /* Pin 1: 0: Reset */
-#define D_PIO0 (1<<0) /* Pin 0: 1: Speakerbox PDN */
-
-/* DBRI Commands (Page 20) */
-#define D_WAIT 0x0 /* Stop execution */
-#define D_PAUSE 0x1 /* Flush long pipes */
-#define D_JUMP 0x2 /* New command queue */
-#define D_IIQ 0x3 /* Initialize Interrupt Queue */
-#define D_REX 0x4 /* Report command execution via interrupt */
-#define D_SDP 0x5 /* Setup Data Pipe */
-#define D_CDP 0x6 /* Continue Data Pipe (reread NULL Pointer) */
-#define D_DTS 0x7 /* Define Time Slot */
-#define D_SSP 0x8 /* Set short Data Pipe */
-#define D_CHI 0x9 /* Set CHI Global Mode */
-#define D_NT 0xa /* NT Command */
-#define D_TE 0xb /* TE Command */
-#define D_CDEC 0xc /* Codec setup */
-#define D_TEST 0xd /* No comment */
-#define D_CDM 0xe /* CHI Data mode command */
-
-/* Special bits for some commands */
-#define D_PIPE(v) ((v)<<0) /* Pipe No.: 0-15 long, 16-21 short */
-
-/* Setup Data Pipe */
-/* IRM */
-#define D_SDP_2SAME (1<<18) /* Report 2nd time in a row value received */
-#define D_SDP_CHANGE (2<<18) /* Report any changes */
-#define D_SDP_EVERY (3<<18) /* Report any changes */
-#define D_SDP_EOL (1<<17) /* EOL interrupt enable */
-#define D_SDP_IDLE (1<<16) /* HDLC idle interrupt enable */
-
-/* Pipe data MODE */
-#define D_SDP_MEM (0<<13) /* To/from memory */
-#define D_SDP_HDLC (2<<13)
-#define D_SDP_HDLC_D (3<<13) /* D Channel (prio control) */
-#define D_SDP_SER (4<<13) /* Serial to serial */
-#define D_SDP_FIXED (6<<13) /* Short only */
-#define D_SDP_MODE(v) ((v)&(7<<13))
-
-#define D_SDP_TO_SER (1<<12) /* Direction */
-#define D_SDP_FROM_SER (0<<12) /* Direction */
-#define D_SDP_MSB (1<<11) /* Bit order within Byte */
-#define D_SDP_LSB (0<<11) /* Bit order within Byte */
-#define D_SDP_P (1<<10) /* Pointer Valid */
-#define D_SDP_A (1<<8) /* Abort */
-#define D_SDP_C (1<<7) /* Clear */
-
-/* Define Time Slot */
-#define D_DTS_VI (1<<17) /* Valid Input Time-Slot Descriptor */
-#define D_DTS_VO (1<<16) /* Valid Output Time-Slot Descriptor */
-#define D_DTS_INS (1<<15) /* Insert Time Slot */
-#define D_DTS_DEL (0<<15) /* Delete Time Slot */
-#define D_DTS_PRVIN(v) ((v)<<10) /* Previous In Pipe */
-#define D_DTS_PRVOUT(v) ((v)<<5) /* Previous Out Pipe */
-
-/* Time Slot defines */
-#define D_TS_LEN(v) ((v)<<24) /* Number of bits in this time slot */
-#define D_TS_CYCLE(v) ((v)<<14) /* Bit Count at start of TS */
-#define D_TS_DI (1<<13) /* Data Invert */
-#define D_TS_1CHANNEL (0<<10) /* Single Channel / Normal mode */
-#define D_TS_MONITOR (2<<10) /* Monitor pipe */
-#define D_TS_NONCONTIG (3<<10) /* Non contiguous mode */
-#define D_TS_ANCHOR (7<<10) /* Starting short pipes */
-#define D_TS_MON(v) ((v)<<5) /* Monitor Pipe */
-#define D_TS_NEXT(v) ((v)<<0) /* Pipe no.: 0-15 long, 16-21 short */
-
-/* Concentration Highway Interface Modes */
-#define D_CHI_CHICM(v) ((v)<<16) /* Clock mode */
-#define D_CHI_IR (1<<15) /* Immediate Interrupt Report */
-#define D_CHI_EN (1<<14) /* CHIL Interrupt enabled */
-#define D_CHI_OD (1<<13) /* Open Drain Enable */
-#define D_CHI_FE (1<<12) /* Sample CHIFS on Rising Frame Edge */
-#define D_CHI_FD (1<<11) /* Frame Drive */
-#define D_CHI_BPF(v) ((v)<<0) /* Bits per Frame */
-
-/* NT: These are here for completeness */
-#define D_NT_FBIT (1<<17) /* Frame Bit */
-#define D_NT_NBF (1<<16) /* Number of bad frames to loose framing */
-#define D_NT_IRM_IMM (1<<15) /* Interrupt Report & Mask: Immediate */
-#define D_NT_IRM_EN (1<<14) /* Interrupt Report & Mask: Enable */
-#define D_NT_ISNT (1<<13) /* Configure interface as NT */
-#define D_NT_FT (1<<12) /* Fixed Timing */
-#define D_NT_EZ (1<<11) /* Echo Channel is Zeros */
-#define D_NT_IFA (1<<10) /* Inhibit Final Activation */
-#define D_NT_ACT (1<<9) /* Activate Interface */
-#define D_NT_MFE (1<<8) /* Multiframe Enable */
-#define D_NT_RLB(v) ((v)<<5) /* Remote Loopback */
-#define D_NT_LLB(v) ((v)<<2) /* Local Loopback */
-#define D_NT_FACT (1<<1) /* Force Activation */
-#define D_NT_ABV (1<<0) /* Activate Bipolar Violation */
-
-/* Codec Setup */
-#define D_CDEC_CK(v) ((v)<<24) /* Clock Select */
-#define D_CDEC_FED(v) ((v)<<12) /* FSCOD Falling Edge Delay */
-#define D_CDEC_RED(v) ((v)<<0) /* FSCOD Rising Edge Delay */
-
-/* Test */
-#define D_TEST_RAM(v) ((v)<<16) /* RAM Pointer */
-#define D_TEST_SIZE(v) ((v)<<11) /* */
-#define D_TEST_ROMONOFF 0x5 /* Toggle ROM opcode monitor on/off */
-#define D_TEST_PROC 0x6 /* Microprocessor test */
-#define D_TEST_SER 0x7 /* Serial-Controller test */
-#define D_TEST_RAMREAD 0x8 /* Copy from Ram to system memory */
-#define D_TEST_RAMWRITE 0x9 /* Copy into Ram from system memory */
-#define D_TEST_RAMBIST 0xa /* RAM Built-In Self Test */
-#define D_TEST_MCBIST 0xb /* Microcontroller Built-In Self Test */
-#define D_TEST_DUMP 0xe /* ROM Dump */
-
-/* CHI Data Mode */
-#define D_CDM_THI (1 << 8) /* Transmit Data on CHIDR Pin */
-#define D_CDM_RHI (1 << 7) /* Receive Data on CHIDX Pin */
-#define D_CDM_RCE (1 << 6) /* Receive on Rising Edge of CHICK */
-#define D_CDM_XCE (1 << 2) /* Transmit Data on Rising Edge of CHICK */
-#define D_CDM_XEN (1 << 1) /* Transmit Highway Enable */
-#define D_CDM_REN (1 << 0) /* Receive Highway Enable */
-
-/* The Interrupts */
-#define D_INTR_BRDY 1 /* Buffer Ready for processing */
-#define D_INTR_MINT 2 /* Marked Interrupt in RD/TD */
-#define D_INTR_IBEG 3 /* Flag to idle transition detected (HDLC) */
-#define D_INTR_IEND 4 /* Idle to flag transition detected (HDLC) */
-#define D_INTR_EOL 5 /* End of List */
-#define D_INTR_CMDI 6 /* Command has bean read */
-#define D_INTR_XCMP 8 /* Transmission of frame complete */
-#define D_INTR_SBRI 9 /* BRI status change info */
-#define D_INTR_FXDT 10 /* Fixed data change */
-#define D_INTR_CHIL 11 /* CHI lost frame sync (channel 36 only) */
-#define D_INTR_COLL 11 /* Unrecoverable D-Channel collision */
-#define D_INTR_DBYT 12 /* Dropped by frame slip */
-#define D_INTR_RBYT 13 /* Repeated by frame slip */
-#define D_INTR_LINT 14 /* Lost Interrupt */
-#define D_INTR_UNDR 15 /* DMA underrun */
-
-#define D_INTR_TE 32
-#define D_INTR_NT 34
-#define D_INTR_CHI 36
-#define D_INTR_CMD 38
-
-#define D_INTR_GETCHAN(v) (((v) >> 24) & 0x3f)
-#define D_INTR_GETCODE(v) (((v) >> 20) & 0xf)
-#define D_INTR_GETCMD(v) (((v) >> 16) & 0xf)
-#define D_INTR_GETVAL(v) ((v) & 0xffff)
-#define D_INTR_GETRVAL(v) ((v) & 0xfffff)
-
-#define D_P_0 0 /* TE receive anchor */
-#define D_P_1 1 /* TE transmit anchor */
-#define D_P_2 2 /* NT transmit anchor */
-#define D_P_3 3 /* NT receive anchor */
-#define D_P_4 4 /* CHI send data */
-#define D_P_5 5 /* CHI receive data */
-#define D_P_6 6 /* */
-#define D_P_7 7 /* */
-#define D_P_8 8 /* */
-#define D_P_9 9 /* */
-#define D_P_10 10 /* */
-#define D_P_11 11 /* */
-#define D_P_12 12 /* */
-#define D_P_13 13 /* */
-#define D_P_14 14 /* */
-#define D_P_15 15 /* */
-#define D_P_16 16 /* CHI anchor pipe */
-#define D_P_17 17 /* CHI send */
-#define D_P_18 18 /* CHI receive */
-#define D_P_19 19 /* CHI receive */
-#define D_P_20 20 /* CHI receive */
-#define D_P_21 21 /* */
-#define D_P_22 22 /* */
-#define D_P_23 23 /* */
-#define D_P_24 24 /* */
-#define D_P_25 25 /* */
-#define D_P_26 26 /* */
-#define D_P_27 27 /* */
-#define D_P_28 28 /* */
-#define D_P_29 29 /* */
-#define D_P_30 30 /* */
-#define D_P_31 31 /* */
-
-/* Transmit descriptor defines */
-#define DBRI_TD_F (1 << 31) /* End of Frame */
-#define DBRI_TD_D (1 << 30) /* Do not append CRC */
-#define DBRI_TD_CNT(v) ((v) << 16) /* Number of valid bytes in the buffer */
-#define DBRI_TD_B (1 << 15) /* Final interrupt */
-#define DBRI_TD_M (1 << 14) /* Marker interrupt */
-#define DBRI_TD_I (1 << 13) /* Transmit Idle Characters */
-#define DBRI_TD_FCNT(v) (v) /* Flag Count */
-#define DBRI_TD_UNR (1 << 3) /* Underrun: transmitter is out of data */
-#define DBRI_TD_ABT (1 << 2) /* Abort: frame aborted */
-#define DBRI_TD_TBC (1 << 0) /* Transmit buffer Complete */
-#define DBRI_TD_STATUS(v) ((v) & 0xff) /* Transmit status */
- /* Maximum buffer size per TD: almost 8KB */
-#define DBRI_TD_MAXCNT ((1 << 13) - 4)
-
-/* Receive descriptor defines */
-#define DBRI_RD_F (1 << 31) /* End of Frame */
-#define DBRI_RD_C (1 << 30) /* Completed buffer */
-#define DBRI_RD_B (1 << 15) /* Final interrupt */
-#define DBRI_RD_M (1 << 14) /* Marker interrupt */
-#define DBRI_RD_BCNT(v) (v) /* Buffer size */
-#define DBRI_RD_CRC (1 << 7) /* 0: CRC is correct */
-#define DBRI_RD_BBC (1 << 6) /* 1: Bad Byte received */
-#define DBRI_RD_ABT (1 << 5) /* Abort: frame aborted */
-#define DBRI_RD_OVRN (1 << 3) /* Overrun: data lost */
-#define DBRI_RD_STATUS(v) ((v) & 0xff) /* Receive status */
-#define DBRI_RD_CNT(v) (((v) >> 16) & 0x1fff) /* Valid bytes in the buffer */
-
-/* stream_info[] access */
-/* Translate the ALSA direction into the array index */
-#define DBRI_STREAMNO(substream) \
- (substream->stream == \
- SNDRV_PCM_STREAM_PLAYBACK ? DBRI_PLAY: DBRI_REC)
-
-/* Return a pointer to dbri_streaminfo */
-#define DBRI_STREAM(dbri, substream) \
- &dbri->stream_info[DBRI_STREAMNO(substream)]
-
-/*
- * Short data pipes transmit LSB first. The CS4215 receives MSB first. Grrr.
- * So we have to reverse the bits. Note: not all bit lengths are supported
- */
-static __u32 reverse_bytes(__u32 b, int len)
-{
- switch (len) {
- case 32:
- b = ((b & 0xffff0000) >> 16) | ((b & 0x0000ffff) << 16);
- case 16:
- b = ((b & 0xff00ff00) >> 8) | ((b & 0x00ff00ff) << 8);
- case 8:
- b = ((b & 0xf0f0f0f0) >> 4) | ((b & 0x0f0f0f0f) << 4);
- case 4:
- b = ((b & 0xcccccccc) >> 2) | ((b & 0x33333333) << 2);
- case 2:
- b = ((b & 0xaaaaaaaa) >> 1) | ((b & 0x55555555) << 1);
- case 1:
- case 0:
- break;
- default:
- printk(KERN_ERR "DBRI reverse_bytes: unsupported length\n");
- };
-
- return b;
-}
-
-/*
-****************************************************************************
-************** DBRI initialization and command synchronization *************
-****************************************************************************
-
-Commands are sent to the DBRI by building a list of them in memory,
-then writing the address of the first list item to DBRI register 8.
-The list is terminated with a WAIT command, which generates a
-CPU interrupt to signal completion.
-
-Since the DBRI can run in parallel with the CPU, several means of
-synchronization present themselves. The method implemented here uses
-the dbri_cmdwait() to wait for execution of batch of sent commands.
-
-A circular command buffer is used here. A new command is being added
-while another can be executed. The scheme works by adding two WAIT commands
-after each sent batch of commands. When the next batch is prepared it is
-added after the WAIT commands then the WAITs are replaced with single JUMP
-command to the new batch. The the DBRI is forced to reread the last WAIT
-command (replaced by the JUMP by then). If the DBRI is still executing
-previous commands the request to reread the WAIT command is ignored.
-
-Every time a routine wants to write commands to the DBRI, it must
-first call dbri_cmdlock() and get pointer to a free space in
-dbri->dma->cmd buffer. After this, the commands can be written to
-the buffer, and dbri_cmdsend() is called with the final pointer value
-to send them to the DBRI.
-
-*/
-
-#define MAXLOOPS 20
-/*
- * Wait for the current command string to execute
- */
-static void dbri_cmdwait(struct snd_dbri *dbri)
-{
- int maxloops = MAXLOOPS;
- unsigned long flags;
-
- /* Delay if previous commands are still being processed */
- spin_lock_irqsave(&dbri->lock, flags);
- while ((--maxloops) > 0 && (sbus_readl(dbri->regs + REG0) & D_P)) {
- spin_unlock_irqrestore(&dbri->lock, flags);
- msleep_interruptible(1);
- spin_lock_irqsave(&dbri->lock, flags);
- }
- spin_unlock_irqrestore(&dbri->lock, flags);
-
- if (maxloops == 0)
- printk(KERN_ERR "DBRI: Chip never completed command buffer\n");
- else
- dprintk(D_CMD, "Chip completed command buffer (%d)\n",
- MAXLOOPS - maxloops - 1);
-}
-/*
- * Lock the command queue and return pointer to space for len cmd words
- * It locks the cmdlock spinlock.
- */
-static s32 *dbri_cmdlock(struct snd_dbri *dbri, int len)
-{
- /* Space for 2 WAIT cmds (replaced later by 1 JUMP cmd) */
- len += 2;
- spin_lock(&dbri->cmdlock);
- if (dbri->cmdptr - dbri->dma->cmd + len < DBRI_NO_CMDS - 2)
- return dbri->cmdptr + 2;
- else if (len < sbus_readl(dbri->regs + REG8) - dbri->dma_dvma)
- return dbri->dma->cmd;
- else
- printk(KERN_ERR "DBRI: no space for commands.");
-
- return NULL;
-}
-
-/*
- * Send prepared cmd string. It works by writing a JUMP cmd into
- * the last WAIT cmd and force DBRI to reread the cmd.
- * The JUMP cmd points to the new cmd string.
- * It also releases the cmdlock spinlock.
- *
- * Lock must be held before calling this.
- */
-static void dbri_cmdsend(struct snd_dbri *dbri, s32 *cmd, int len)
-{
- s32 tmp, addr;
- static int wait_id = 0;
-
- wait_id++;
- wait_id &= 0xffff; /* restrict it to a 16 bit counter. */
- *(cmd) = DBRI_CMD(D_WAIT, 1, wait_id);
- *(cmd+1) = DBRI_CMD(D_WAIT, 1, wait_id);
-
- /* Replace the last command with JUMP */
- addr = dbri->dma_dvma + (cmd - len - dbri->dma->cmd) * sizeof(s32);
- *(dbri->cmdptr+1) = addr;
- *(dbri->cmdptr) = DBRI_CMD(D_JUMP, 0, 0);
-
-#ifdef DBRI_DEBUG
- if (cmd > dbri->cmdptr) {
- s32 *ptr;
-
- for (ptr = dbri->cmdptr; ptr < cmd+2; ptr++)
- dprintk(D_CMD, "cmd: %lx:%08x\n",
- (unsigned long)ptr, *ptr);
- } else {
- s32 *ptr = dbri->cmdptr;
-
- dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
- ptr++;
- dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
- for (ptr = dbri->dma->cmd; ptr < cmd+2; ptr++)
- dprintk(D_CMD, "cmd: %lx:%08x\n",
- (unsigned long)ptr, *ptr);
- }
-#endif
-
- /* Reread the last command */
- tmp = sbus_readl(dbri->regs + REG0);
- tmp |= D_P;
- sbus_writel(tmp, dbri->regs + REG0);
-
- dbri->cmdptr = cmd;
- spin_unlock(&dbri->cmdlock);
-}
-
-/* Lock must be held when calling this */
-static void dbri_reset(struct snd_dbri *dbri)
-{
- int i;
- u32 tmp;
-
- dprintk(D_GEN, "reset 0:%x 2:%x 8:%x 9:%x\n",
- sbus_readl(dbri->regs + REG0),
- sbus_readl(dbri->regs + REG2),
- sbus_readl(dbri->regs + REG8), sbus_readl(dbri->regs + REG9));
-
- sbus_writel(D_R, dbri->regs + REG0); /* Soft Reset */
- for (i = 0; (sbus_readl(dbri->regs + REG0) & D_R) && i < 64; i++)
- udelay(10);
-
- /* A brute approach - DBRI falls back to working burst size by itself
- * On SS20 D_S does not work, so do not try so high. */
- tmp = sbus_readl(dbri->regs + REG0);
- tmp |= D_G | D_E;
- tmp &= ~D_S;
- sbus_writel(tmp, dbri->regs + REG0);
-}
-
-/* Lock must not be held before calling this */
-static void __devinit dbri_initialize(struct snd_dbri *dbri)
-{
- s32 *cmd;
- u32 dma_addr;
- unsigned long flags;
- int n;
-
- spin_lock_irqsave(&dbri->lock, flags);
-
- dbri_reset(dbri);
-
- /* Initialize pipes */
- for (n = 0; n < DBRI_NO_PIPES; n++)
- dbri->pipes[n].desc = dbri->pipes[n].first_desc = -1;
-
- spin_lock_init(&dbri->cmdlock);
- /*
- * Initialize the interrupt ring buffer.
- */
- dma_addr = dbri->dma_dvma + dbri_dma_off(intr, 0);
- dbri->dma->intr[0] = dma_addr;
- dbri->dbri_irqp = 1;
- /*
- * Set up the interrupt queue
- */
- spin_lock(&dbri->cmdlock);
- cmd = dbri->cmdptr = dbri->dma->cmd;
- *(cmd++) = DBRI_CMD(D_IIQ, 0, 0);
- *(cmd++) = dma_addr;
- *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
- dbri->cmdptr = cmd;
- *(cmd++) = DBRI_CMD(D_WAIT, 1, 0);
- *(cmd++) = DBRI_CMD(D_WAIT, 1, 0);
- dma_addr = dbri->dma_dvma + dbri_dma_off(cmd, 0);
- sbus_writel(dma_addr, dbri->regs + REG8);
- spin_unlock(&dbri->cmdlock);
-
- spin_unlock_irqrestore(&dbri->lock, flags);
- dbri_cmdwait(dbri);
-}
-
-/*
-****************************************************************************
-************************** DBRI data pipe management ***********************
-****************************************************************************
-
-While DBRI control functions use the command and interrupt buffers, the
-main data path takes the form of data pipes, which can be short (command
-and interrupt driven), or long (attached to DMA buffers). These functions
-provide a rudimentary means of setting up and managing the DBRI's pipes,
-but the calling functions have to make sure they respect the pipes' linked
-list ordering, among other things. The transmit and receive functions
-here interface closely with the transmit and receive interrupt code.
-
-*/
-static inline int pipe_active(struct snd_dbri *dbri, int pipe)
-{
- return ((pipe >= 0) && (dbri->pipes[pipe].desc != -1));
-}
-
-/* reset_pipe(dbri, pipe)
- *
- * Called on an in-use pipe to clear anything being transmitted or received
- * Lock must be held before calling this.
- */
-static void reset_pipe(struct snd_dbri *dbri, int pipe)
-{
- int sdp;
- int desc;
- s32 *cmd;
-
- if (pipe < 0 || pipe > DBRI_MAX_PIPE) {
- printk(KERN_ERR "DBRI: reset_pipe called with "
- "illegal pipe number\n");
- return;
- }
-
- sdp = dbri->pipes[pipe].sdp;
- if (sdp == 0) {
- printk(KERN_ERR "DBRI: reset_pipe called "
- "on uninitialized pipe\n");
- return;
- }
-
- cmd = dbri_cmdlock(dbri, 3);
- *(cmd++) = DBRI_CMD(D_SDP, 0, sdp | D_SDP_C | D_SDP_P);
- *(cmd++) = 0;
- *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
- dbri_cmdsend(dbri, cmd, 3);
-
- desc = dbri->pipes[pipe].first_desc;
- if (desc >= 0)
- do {
- dbri->dma->desc[desc].ba = 0;
- dbri->dma->desc[desc].nda = 0;
- desc = dbri->next_desc[desc];
- } while (desc != -1 && desc != dbri->pipes[pipe].first_desc);
-
- dbri->pipes[pipe].desc = -1;
- dbri->pipes[pipe].first_desc = -1;
-}
-
-/*
- * Lock must be held before calling this.
- */
-static void setup_pipe(struct snd_dbri *dbri, int pipe, int sdp)
-{
- if (pipe < 0 || pipe > DBRI_MAX_PIPE) {
- printk(KERN_ERR "DBRI: setup_pipe called "
- "with illegal pipe number\n");
- return;
- }
-
- if ((sdp & 0xf800) != sdp) {
- printk(KERN_ERR "DBRI: setup_pipe called "
- "with strange SDP value\n");
- /* sdp &= 0xf800; */
- }
-
- /* If this is a fixed receive pipe, arrange for an interrupt
- * every time its data changes
- */
- if (D_SDP_MODE(sdp) == D_SDP_FIXED && !(sdp & D_SDP_TO_SER))
- sdp |= D_SDP_CHANGE;
-
- sdp |= D_PIPE(pipe);
- dbri->pipes[pipe].sdp = sdp;
- dbri->pipes[pipe].desc = -1;
- dbri->pipes[pipe].first_desc = -1;
-
- reset_pipe(dbri, pipe);
-}
-
-/*
- * Lock must be held before calling this.
- */
-static void link_time_slot(struct snd_dbri *dbri, int pipe,
- int prevpipe, int nextpipe,
- int length, int cycle)
-{
- s32 *cmd;
- int val;
-
- if (pipe < 0 || pipe > DBRI_MAX_PIPE
- || prevpipe < 0 || prevpipe > DBRI_MAX_PIPE
- || nextpipe < 0 || nextpipe > DBRI_MAX_PIPE) {
- printk(KERN_ERR
- "DBRI: link_time_slot called with illegal pipe number\n");
- return;
- }
-
- if (dbri->pipes[pipe].sdp == 0
- || dbri->pipes[prevpipe].sdp == 0
- || dbri->pipes[nextpipe].sdp == 0) {
- printk(KERN_ERR "DBRI: link_time_slot called "
- "on uninitialized pipe\n");
- return;
- }
-
- dbri->pipes[prevpipe].nextpipe = pipe;
- dbri->pipes[pipe].nextpipe = nextpipe;
- dbri->pipes[pipe].length = length;
-
- cmd = dbri_cmdlock(dbri, 4);
-
- if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) {
- /* Deal with CHI special case:
- * "If transmission on edges 0 or 1 is desired, then cycle n
- * (where n = # of bit times per frame...) must be used."
- * - DBRI data sheet, page 11
- */
- if (prevpipe == 16 && cycle == 0)
- cycle = dbri->chi_bpf;
-
- val = D_DTS_VO | D_DTS_INS | D_DTS_PRVOUT(prevpipe) | pipe;
- *(cmd++) = DBRI_CMD(D_DTS, 0, val);
- *(cmd++) = 0;
- *(cmd++) =
- D_TS_LEN(length) | D_TS_CYCLE(cycle) | D_TS_NEXT(nextpipe);
- } else {
- val = D_DTS_VI | D_DTS_INS | D_DTS_PRVIN(prevpipe) | pipe;
- *(cmd++) = DBRI_CMD(D_DTS, 0, val);
- *(cmd++) =
- D_TS_LEN(length) | D_TS_CYCLE(cycle) | D_TS_NEXT(nextpipe);
- *(cmd++) = 0;
- }
- *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
-
- dbri_cmdsend(dbri, cmd, 4);
-}
-
-#if 0
-/*
- * Lock must be held before calling this.
- */
-static void unlink_time_slot(struct snd_dbri *dbri, int pipe,
- enum in_or_out direction, int prevpipe,
- int nextpipe)
-{
- s32 *cmd;
- int val;
-
- if (pipe < 0 || pipe > DBRI_MAX_PIPE
- || prevpipe < 0 || prevpipe > DBRI_MAX_PIPE
- || nextpipe < 0 || nextpipe > DBRI_MAX_PIPE) {
- printk(KERN_ERR
- "DBRI: unlink_time_slot called with illegal pipe number\n");
- return;
- }
-
- cmd = dbri_cmdlock(dbri, 4);
-
- if (direction == PIPEinput) {
- val = D_DTS_VI | D_DTS_DEL | D_DTS_PRVIN(prevpipe) | pipe;
- *(cmd++) = DBRI_CMD(D_DTS, 0, val);
- *(cmd++) = D_TS_NEXT(nextpipe);
- *(cmd++) = 0;
- } else {
- val = D_DTS_VO | D_DTS_DEL | D_DTS_PRVOUT(prevpipe) | pipe;
- *(cmd++) = DBRI_CMD(D_DTS, 0, val);
- *(cmd++) = 0;
- *(cmd++) = D_TS_NEXT(nextpipe);
- }
- *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
-
- dbri_cmdsend(dbri, cmd, 4);
-}
-#endif
-
-/* xmit_fixed() / recv_fixed()
- *
- * Transmit/receive data on a "fixed" pipe - i.e, one whose contents are not
- * expected to change much, and which we don't need to buffer.
- * The DBRI only interrupts us when the data changes (receive pipes),
- * or only changes the data when this function is called (transmit pipes).
- * Only short pipes (numbers 16-31) can be used in fixed data mode.
- *
- * These function operate on a 32-bit field, no matter how large
- * the actual time slot is. The interrupt handler takes care of bit
- * ordering and alignment. An 8-bit time slot will always end up
- * in the low-order 8 bits, filled either MSB-first or LSB-first,
- * depending on the settings passed to setup_pipe().
- *
- * Lock must not be held before calling it.
- */
-static void xmit_fixed(struct snd_dbri *dbri, int pipe, unsigned int data)
-{
- s32 *cmd;
- unsigned long flags;
-
- if (pipe < 16 || pipe > DBRI_MAX_PIPE) {
- printk(KERN_ERR "DBRI: xmit_fixed: Illegal pipe number\n");
- return;
- }
-
- if (D_SDP_MODE(dbri->pipes[pipe].sdp) == 0) {
- printk(KERN_ERR "DBRI: xmit_fixed: "
- "Uninitialized pipe %d\n", pipe);
- return;
- }
-
- if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) {
- printk(KERN_ERR "DBRI: xmit_fixed: Non-fixed pipe %d\n", pipe);
- return;
- }
-
- if (!(dbri->pipes[pipe].sdp & D_SDP_TO_SER)) {
- printk(KERN_ERR "DBRI: xmit_fixed: Called on receive pipe %d\n",
- pipe);
- return;
- }
-
- /* DBRI short pipes always transmit LSB first */
-
- if (dbri->pipes[pipe].sdp & D_SDP_MSB)
- data = reverse_bytes(data, dbri->pipes[pipe].length);
-
- cmd = dbri_cmdlock(dbri, 3);
-
- *(cmd++) = DBRI_CMD(D_SSP, 0, pipe);
- *(cmd++) = data;
- *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
-
- spin_lock_irqsave(&dbri->lock, flags);
- dbri_cmdsend(dbri, cmd, 3);
- spin_unlock_irqrestore(&dbri->lock, flags);
- dbri_cmdwait(dbri);
-
-}
-
-static void recv_fixed(struct snd_dbri *dbri, int pipe, volatile __u32 *ptr)
-{
- if (pipe < 16 || pipe > DBRI_MAX_PIPE) {
- printk(KERN_ERR "DBRI: recv_fixed called with "
- "illegal pipe number\n");
- return;
- }
-
- if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) {
- printk(KERN_ERR "DBRI: recv_fixed called on "
- "non-fixed pipe %d\n", pipe);
- return;
- }
-
- if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) {
- printk(KERN_ERR "DBRI: recv_fixed called on "
- "transmit pipe %d\n", pipe);
- return;
- }
-
- dbri->pipes[pipe].recv_fixed_ptr = ptr;
-}
-
-/* setup_descs()
- *
- * Setup transmit/receive data on a "long" pipe - i.e, one associated
- * with a DMA buffer.
- *
- * Only pipe numbers 0-15 can be used in this mode.
- *
- * This function takes a stream number pointing to a data buffer,
- * and work by building chains of descriptors which identify the
- * data buffers. Buffers too large for a single descriptor will
- * be spread across multiple descriptors.
- *
- * All descriptors create a ring buffer.
- *
- * Lock must be held before calling this.
- */
-static int setup_descs(struct snd_dbri *dbri, int streamno, unsigned int period)
-{
- struct dbri_streaminfo *info = &dbri->stream_info[streamno];
- __u32 dvma_buffer;
- int desc;
- int len;
- int first_desc = -1;
- int last_desc = -1;
-
- if (info->pipe < 0 || info->pipe > 15) {
- printk(KERN_ERR "DBRI: setup_descs: Illegal pipe number\n");
- return -2;
- }
-
- if (dbri->pipes[info->pipe].sdp == 0) {
- printk(KERN_ERR "DBRI: setup_descs: Uninitialized pipe %d\n",
- info->pipe);
- return -2;
- }
-
- dvma_buffer = info->dvma_buffer;
- len = info->size;
-
- if (streamno == DBRI_PLAY) {
- if (!(dbri->pipes[info->pipe].sdp & D_SDP_TO_SER)) {
- printk(KERN_ERR "DBRI: setup_descs: "
- "Called on receive pipe %d\n", info->pipe);
- return -2;
- }
- } else {
- if (dbri->pipes[info->pipe].sdp & D_SDP_TO_SER) {
- printk(KERN_ERR
- "DBRI: setup_descs: Called on transmit pipe %d\n",
- info->pipe);
- return -2;
- }
- /* Should be able to queue multiple buffers
- * to receive on a pipe
- */
- if (pipe_active(dbri, info->pipe)) {
- printk(KERN_ERR "DBRI: recv_on_pipe: "
- "Called on active pipe %d\n", info->pipe);
- return -2;
- }
-
- /* Make sure buffer size is multiple of four */
- len &= ~3;
- }
-
- /* Free descriptors if pipe has any */
- desc = dbri->pipes[info->pipe].first_desc;
- if (desc >= 0)
- do {
- dbri->dma->desc[desc].ba = 0;
- dbri->dma->desc[desc].nda = 0;
- desc = dbri->next_desc[desc];
- } while (desc != -1 &&
- desc != dbri->pipes[info->pipe].first_desc);
-
- dbri->pipes[info->pipe].desc = -1;
- dbri->pipes[info->pipe].first_desc = -1;
-
- desc = 0;
- while (len > 0) {
- int mylen;
-
- for (; desc < DBRI_NO_DESCS; desc++) {
- if (!dbri->dma->desc[desc].ba)
- break;
- }
-
- if (desc == DBRI_NO_DESCS) {
- printk(KERN_ERR "DBRI: setup_descs: No descriptors\n");
- return -1;
- }
-
- if (len > DBRI_TD_MAXCNT)
- mylen = DBRI_TD_MAXCNT; /* 8KB - 4 */
- else
- mylen = len;
-
- if (mylen > period)
- mylen = period;
-
- dbri->next_desc[desc] = -1;
- dbri->dma->desc[desc].ba = dvma_buffer;
- dbri->dma->desc[desc].nda = 0;
-
- if (streamno == DBRI_PLAY) {
- dbri->dma->desc[desc].word1 = DBRI_TD_CNT(mylen);
- dbri->dma->desc[desc].word4 = 0;
- dbri->dma->desc[desc].word1 |= DBRI_TD_F | DBRI_TD_B;
- } else {
- dbri->dma->desc[desc].word1 = 0;
- dbri->dma->desc[desc].word4 =
- DBRI_RD_B | DBRI_RD_BCNT(mylen);
- }
-
- if (first_desc == -1)
- first_desc = desc;
- else {
- dbri->next_desc[last_desc] = desc;
- dbri->dma->desc[last_desc].nda =
- dbri->dma_dvma + dbri_dma_off(desc, desc);
- }
-
- last_desc = desc;
- dvma_buffer += mylen;
- len -= mylen;
- }
-
- if (first_desc == -1 || last_desc == -1) {
- printk(KERN_ERR "DBRI: setup_descs: "
- " Not enough descriptors available\n");
- return -1;
- }
-
- dbri->dma->desc[last_desc].nda =
- dbri->dma_dvma + dbri_dma_off(desc, first_desc);
- dbri->next_desc[last_desc] = first_desc;
- dbri->pipes[info->pipe].first_desc = first_desc;
- dbri->pipes[info->pipe].desc = first_desc;
-
-#ifdef DBRI_DEBUG
- for (desc = first_desc; desc != -1;) {
- dprintk(D_DESC, "DESC %d: %08x %08x %08x %08x\n",
- desc,
- dbri->dma->desc[desc].word1,
- dbri->dma->desc[desc].ba,
- dbri->dma->desc[desc].nda, dbri->dma->desc[desc].word4);
- desc = dbri->next_desc[desc];
- if (desc == first_desc)
- break;
- }
-#endif
- return 0;
-}
-
-/*
-****************************************************************************
-************************** DBRI - CHI interface ****************************
-****************************************************************************
-
-The CHI is a four-wire (clock, frame sync, data in, data out) time-division
-multiplexed serial interface which the DBRI can operate in either master
-(give clock/frame sync) or slave (take clock/frame sync) mode.
-
-*/
-
-enum master_or_slave { CHImaster, CHIslave };
-
-/*
- * Lock must not be held before calling it.
- */
-static void reset_chi(struct snd_dbri *dbri,
- enum master_or_slave master_or_slave,
- int bits_per_frame)
-{
- s32 *cmd;
- int val;
-
- /* Set CHI Anchor: Pipe 16 */
-
- cmd = dbri_cmdlock(dbri, 4);
- val = D_DTS_VO | D_DTS_VI | D_DTS_INS
- | D_DTS_PRVIN(16) | D_PIPE(16) | D_DTS_PRVOUT(16);
- *(cmd++) = DBRI_CMD(D_DTS, 0, val);
- *(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16);
- *(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16);
- *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
- dbri_cmdsend(dbri, cmd, 4);
-
- dbri->pipes[16].sdp = 1;
- dbri->pipes[16].nextpipe = 16;
-
- cmd = dbri_cmdlock(dbri, 4);
-
- if (master_or_slave == CHIslave) {
- /* Setup DBRI for CHI Slave - receive clock, frame sync (FS)
- *
- * CHICM = 0 (slave mode, 8 kHz frame rate)
- * IR = give immediate CHI status interrupt
- * EN = give CHI status interrupt upon change
- */
- *(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(0));
- } else {
- /* Setup DBRI for CHI Master - generate clock, FS
- *
- * BPF = bits per 8 kHz frame
- * 12.288 MHz / CHICM_divisor = clock rate
- * FD = 1 - drive CHIFS on rising edge of CHICK
- */
- int clockrate = bits_per_frame * 8;
- int divisor = 12288 / clockrate;
-
- if (divisor > 255 || divisor * clockrate != 12288)
- printk(KERN_ERR "DBRI: illegal bits_per_frame "
- "in setup_chi\n");
-
- *(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(divisor) | D_CHI_FD
- | D_CHI_BPF(bits_per_frame));
- }
-
- dbri->chi_bpf = bits_per_frame;
-
- /* CHI Data Mode
- *
- * RCE = 0 - receive on falling edge of CHICK
- * XCE = 1 - transmit on rising edge of CHICK
- * XEN = 1 - enable transmitter
- * REN = 1 - enable receiver
- */
-
- *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
- *(cmd++) = DBRI_CMD(D_CDM, 0, D_CDM_XCE | D_CDM_XEN | D_CDM_REN);
- *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
-
- dbri_cmdsend(dbri, cmd, 4);
-}
-
-/*
-****************************************************************************
-*********************** CS4215 audio codec management **********************
-****************************************************************************
-
-In the standard SPARC audio configuration, the CS4215 codec is attached
-to the DBRI via the CHI interface and few of the DBRI's PIO pins.
-
- * Lock must not be held before calling it.
-
-*/
-static __devinit void cs4215_setup_pipes(struct snd_dbri *dbri)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&dbri->lock, flags);
- /*
- * Data mode:
- * Pipe 4: Send timeslots 1-4 (audio data)
- * Pipe 20: Send timeslots 5-8 (part of ctrl data)
- * Pipe 6: Receive timeslots 1-4 (audio data)
- * Pipe 21: Receive timeslots 6-7. We can only receive 20 bits via
- * interrupt, and the rest of the data (slot 5 and 8) is
- * not relevant for us (only for doublechecking).
- *
- * Control mode:
- * Pipe 17: Send timeslots 1-4 (slots 5-8 are read only)
- * Pipe 18: Receive timeslot 1 (clb).
- * Pipe 19: Receive timeslot 7 (version).
- */
-
- setup_pipe(dbri, 4, D_SDP_MEM | D_SDP_TO_SER | D_SDP_MSB);
- setup_pipe(dbri, 20, D_SDP_FIXED | D_SDP_TO_SER | D_SDP_MSB);
- setup_pipe(dbri, 6, D_SDP_MEM | D_SDP_FROM_SER | D_SDP_MSB);
- setup_pipe(dbri, 21, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB);
-
- setup_pipe(dbri, 17, D_SDP_FIXED | D_SDP_TO_SER | D_SDP_MSB);
- setup_pipe(dbri, 18, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB);
- setup_pipe(dbri, 19, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB);
- spin_unlock_irqrestore(&dbri->lock, flags);
-
- dbri_cmdwait(dbri);
-}
-
-static __devinit int cs4215_init_data(struct cs4215 *mm)
-{
- /*
- * No action, memory resetting only.
- *
- * Data Time Slot 5-8
- * Speaker,Line and Headphone enable. Gain set to the half.
- * Input is mike.
- */
- mm->data[0] = CS4215_LO(0x20) | CS4215_HE | CS4215_LE;
- mm->data[1] = CS4215_RO(0x20) | CS4215_SE;
- mm->data[2] = CS4215_LG(0x8) | CS4215_IS | CS4215_PIO0 | CS4215_PIO1;
- mm->data[3] = CS4215_RG(0x8) | CS4215_MA(0xf);
-
- /*
- * Control Time Slot 1-4
- * 0: Default I/O voltage scale
- * 1: 8 bit ulaw, 8kHz, mono, high pass filter disabled
- * 2: Serial enable, CHI master, 128 bits per frame, clock 1
- * 3: Tests disabled
- */
- mm->ctrl[0] = CS4215_RSRVD_1 | CS4215_MLB;
- mm->ctrl[1] = CS4215_DFR_ULAW | CS4215_FREQ[0].csval;
- mm->ctrl[2] = CS4215_XCLK | CS4215_BSEL_128 | CS4215_FREQ[0].xtal;
- mm->ctrl[3] = 0;
-
- mm->status = 0;
- mm->version = 0xff;
- mm->precision = 8; /* For ULAW */
- mm->channels = 1;
-
- return 0;
-}
-
-static void cs4215_setdata(struct snd_dbri *dbri, int muted)
-{
- if (muted) {
- dbri->mm.data[0] |= 63;
- dbri->mm.data[1] |= 63;
- dbri->mm.data[2] &= ~15;
- dbri->mm.data[3] &= ~15;
- } else {
- /* Start by setting the playback attenuation. */
- struct dbri_streaminfo *info = &dbri->stream_info[DBRI_PLAY];
- int left_gain = info->left_gain & 0x3f;
- int right_gain = info->right_gain & 0x3f;
-
- dbri->mm.data[0] &= ~0x3f; /* Reset the volume bits */
- dbri->mm.data[1] &= ~0x3f;
- dbri->mm.data[0] |= (DBRI_MAX_VOLUME - left_gain);
- dbri->mm.data[1] |= (DBRI_MAX_VOLUME - right_gain);
-
- /* Now set the recording gain. */
- info = &dbri->stream_info[DBRI_REC];
- left_gain = info->left_gain & 0xf;
- right_gain = info->right_gain & 0xf;
- dbri->mm.data[2] |= CS4215_LG(left_gain);
- dbri->mm.data[3] |= CS4215_RG(right_gain);
- }
-
- xmit_fixed(dbri, 20, *(int *)dbri->mm.data);
-}
-
-/*
- * Set the CS4215 to data mode.
- */
-static void cs4215_open(struct snd_dbri *dbri)
-{
- int data_width;
- u32 tmp;
- unsigned long flags;
-
- dprintk(D_MM, "cs4215_open: %d channels, %d bits\n",
- dbri->mm.channels, dbri->mm.precision);
-
- /* Temporarily mute outputs, and wait 1/8000 sec (125 us)
- * to make sure this takes. This avoids clicking noises.
- */
-
- cs4215_setdata(dbri, 1);
- udelay(125);
-
- /*
- * Data mode:
- * Pipe 4: Send timeslots 1-4 (audio data)
- * Pipe 20: Send timeslots 5-8 (part of ctrl data)
- * Pipe 6: Receive timeslots 1-4 (audio data)
- * Pipe 21: Receive timeslots 6-7. We can only receive 20 bits via
- * interrupt, and the rest of the data (slot 5 and 8) is
- * not relevant for us (only for doublechecking).
- *
- * Just like in control mode, the time slots are all offset by eight
- * bits. The CS4215, it seems, observes TSIN (the delayed signal)
- * even if it's the CHI master. Don't ask me...
- */
- spin_lock_irqsave(&dbri->lock, flags);
- tmp = sbus_readl(dbri->regs + REG0);
- tmp &= ~(D_C); /* Disable CHI */
- sbus_writel(tmp, dbri->regs + REG0);
-
- /* Switch CS4215 to data mode - set PIO3 to 1 */
- sbus_writel(D_ENPIO | D_PIO1 | D_PIO3 |
- (dbri->mm.onboard ? D_PIO0 : D_PIO2), dbri->regs + REG2);
-
- reset_chi(dbri, CHIslave, 128);
-
- /* Note: this next doesn't work for 8-bit stereo, because the two
- * channels would be on timeslots 1 and 3, with 2 and 4 idle.
- * (See CS4215 datasheet Fig 15)
- *
- * DBRI non-contiguous mode would be required to make this work.
- */
- data_width = dbri->mm.channels * dbri->mm.precision;
-
- link_time_slot(dbri, 4, 16, 16, data_width, dbri->mm.offset);
- link_time_slot(dbri, 20, 4, 16, 32, dbri->mm.offset + 32);
- link_time_slot(dbri, 6, 16, 16, data_width, dbri->mm.offset);
- link_time_slot(dbri, 21, 6, 16, 16, dbri->mm.offset + 40);
-
- /* FIXME: enable CHI after _setdata? */
- tmp = sbus_readl(dbri->regs + REG0);
- tmp |= D_C; /* Enable CHI */
- sbus_writel(tmp, dbri->regs + REG0);
- spin_unlock_irqrestore(&dbri->lock, flags);
-
- cs4215_setdata(dbri, 0);
-}
-
-/*
- * Send the control information (i.e. audio format)
- */
-static int cs4215_setctrl(struct snd_dbri *dbri)
-{
- int i, val;
- u32 tmp;
- unsigned long flags;
-
- /* FIXME - let the CPU do something useful during these delays */
-
- /* Temporarily mute outputs, and wait 1/8000 sec (125 us)
- * to make sure this takes. This avoids clicking noises.
- */
- cs4215_setdata(dbri, 1);
- udelay(125);
-
- /*
- * Enable Control mode: Set DBRI's PIO3 (4215's D/~C) to 0, then wait
- * 12 cycles <= 12/(5512.5*64) sec = 34.01 usec
- */
- val = D_ENPIO | D_PIO1 | (dbri->mm.onboard ? D_PIO0 : D_PIO2);
- sbus_writel(val, dbri->regs + REG2);
- dprintk(D_MM, "cs4215_setctrl: reg2=0x%x\n", val);
- udelay(34);
-
- /* In Control mode, the CS4215 is a slave device, so the DBRI must
- * operate as CHI master, supplying clocking and frame synchronization.
- *
- * In Data mode, however, the CS4215 must be CHI master to insure
- * that its data stream is synchronous with its codec.
- *
- * The upshot of all this? We start by putting the DBRI into master
- * mode, program the CS4215 in Control mode, then switch the CS4215
- * into Data mode and put the DBRI into slave mode. Various timing
- * requirements must be observed along the way.
- *
- * Oh, and one more thing, on a SPARCStation 20 (and maybe
- * others?), the addressing of the CS4215's time slots is
- * offset by eight bits, so we add eight to all the "cycle"
- * values in the Define Time Slot (DTS) commands. This is
- * done in hardware by a TI 248 that delays the DBRI->4215
- * frame sync signal by eight clock cycles. Anybody know why?
- */
- spin_lock_irqsave(&dbri->lock, flags);
- tmp = sbus_readl(dbri->regs + REG0);
- tmp &= ~D_C; /* Disable CHI */
- sbus_writel(tmp, dbri->regs + REG0);
-
- reset_chi(dbri, CHImaster, 128);
-
- /*
- * Control mode:
- * Pipe 17: Send timeslots 1-4 (slots 5-8 are read only)
- * Pipe 18: Receive timeslot 1 (clb).
- * Pipe 19: Receive timeslot 7 (version).
- */
-
- link_time_slot(dbri, 17, 16, 16, 32, dbri->mm.offset);
- link_time_slot(dbri, 18, 16, 16, 8, dbri->mm.offset);
- link_time_slot(dbri, 19, 18, 16, 8, dbri->mm.offset + 48);
- spin_unlock_irqrestore(&dbri->lock, flags);
-
- /* Wait for the chip to echo back CLB (Control Latch Bit) as zero */
- dbri->mm.ctrl[0] &= ~CS4215_CLB;
- xmit_fixed(dbri, 17, *(int *)dbri->mm.ctrl);
-
- spin_lock_irqsave(&dbri->lock, flags);
- tmp = sbus_readl(dbri->regs + REG0);
- tmp |= D_C; /* Enable CHI */
- sbus_writel(tmp, dbri->regs + REG0);
- spin_unlock_irqrestore(&dbri->lock, flags);
-
- for (i = 10; ((dbri->mm.status & 0xe4) != 0x20); --i)
- msleep_interruptible(1);
-
- if (i == 0) {
- dprintk(D_MM, "CS4215 didn't respond to CLB (0x%02x)\n",
- dbri->mm.status);
- return -1;
- }
-
- /* Disable changes to our copy of the version number, as we are about
- * to leave control mode.
- */
- recv_fixed(dbri, 19, NULL);
-
- /* Terminate CS4215 control mode - data sheet says
- * "Set CLB=1 and send two more frames of valid control info"
- */
- dbri->mm.ctrl[0] |= CS4215_CLB;
- xmit_fixed(dbri, 17, *(int *)dbri->mm.ctrl);
-
- /* Two frames of control info @ 8kHz frame rate = 250 us delay */
- udelay(250);
-
- cs4215_setdata(dbri, 0);
-
- return 0;
-}
-
-/*
- * Setup the codec with the sampling rate, audio format and number of
- * channels.
- * As part of the process we resend the settings for the data
- * timeslots as well.
- */
-static int cs4215_prepare(struct snd_dbri *dbri, unsigned int rate,
- snd_pcm_format_t format, unsigned int channels)
-{
- int freq_idx;
- int ret = 0;
-
- /* Lookup index for this rate */
- for (freq_idx = 0; CS4215_FREQ[freq_idx].freq != 0; freq_idx++) {
- if (CS4215_FREQ[freq_idx].freq == rate)
- break;
- }
- if (CS4215_FREQ[freq_idx].freq != rate) {
- printk(KERN_WARNING "DBRI: Unsupported rate %d Hz\n", rate);
- return -1;
- }
-
- switch (format) {
- case SNDRV_PCM_FORMAT_MU_LAW:
- dbri->mm.ctrl[1] = CS4215_DFR_ULAW;
- dbri->mm.precision = 8;
- break;
- case SNDRV_PCM_FORMAT_A_LAW:
- dbri->mm.ctrl[1] = CS4215_DFR_ALAW;
- dbri->mm.precision = 8;
- break;
- case SNDRV_PCM_FORMAT_U8:
- dbri->mm.ctrl[1] = CS4215_DFR_LINEAR8;
- dbri->mm.precision = 8;
- break;
- case SNDRV_PCM_FORMAT_S16_BE:
- dbri->mm.ctrl[1] = CS4215_DFR_LINEAR16;
- dbri->mm.precision = 16;
- break;
- default:
- printk(KERN_WARNING "DBRI: Unsupported format %d\n", format);
- return -1;
- }
-
- /* Add rate parameters */
- dbri->mm.ctrl[1] |= CS4215_FREQ[freq_idx].csval;
- dbri->mm.ctrl[2] = CS4215_XCLK |
- CS4215_BSEL_128 | CS4215_FREQ[freq_idx].xtal;
-
- dbri->mm.channels = channels;
- if (channels == 2)
- dbri->mm.ctrl[1] |= CS4215_DFR_STEREO;
-
- ret = cs4215_setctrl(dbri);
- if (ret == 0)
- cs4215_open(dbri); /* set codec to data mode */
-
- return ret;
-}
-
-/*
- *
- */
-static __devinit int cs4215_init(struct snd_dbri *dbri)
-{
- u32 reg2 = sbus_readl(dbri->regs + REG2);
- dprintk(D_MM, "cs4215_init: reg2=0x%x\n", reg2);
-
- /* Look for the cs4215 chips */
- if (reg2 & D_PIO2) {
- dprintk(D_MM, "Onboard CS4215 detected\n");
- dbri->mm.onboard = 1;
- }
- if (reg2 & D_PIO0) {
- dprintk(D_MM, "Speakerbox detected\n");
- dbri->mm.onboard = 0;
-
- if (reg2 & D_PIO2) {
- printk(KERN_INFO "DBRI: Using speakerbox / "
- "ignoring onboard mmcodec.\n");
- sbus_writel(D_ENPIO2, dbri->regs + REG2);
- }
- }
-
- if (!(reg2 & (D_PIO0 | D_PIO2))) {
- printk(KERN_ERR "DBRI: no mmcodec found.\n");
- return -EIO;
- }
-
- cs4215_setup_pipes(dbri);
- cs4215_init_data(&dbri->mm);
-
- /* Enable capture of the status & version timeslots. */
- recv_fixed(dbri, 18, &dbri->mm.status);
- recv_fixed(dbri, 19, &dbri->mm.version);
-
- dbri->mm.offset = dbri->mm.onboard ? 0 : 8;
- if (cs4215_setctrl(dbri) == -1 || dbri->mm.version == 0xff) {
- dprintk(D_MM, "CS4215 failed probe at offset %d\n",
- dbri->mm.offset);
- return -EIO;
- }
- dprintk(D_MM, "Found CS4215 at offset %d\n", dbri->mm.offset);
-
- return 0;
-}
-
-/*
-****************************************************************************
-*************************** DBRI interrupt handler *************************
-****************************************************************************
-
-The DBRI communicates with the CPU mainly via a circular interrupt
-buffer. When an interrupt is signaled, the CPU walks through the
-buffer and calls dbri_process_one_interrupt() for each interrupt word.
-Complicated interrupts are handled by dedicated functions (which
-appear first in this file). Any pending interrupts can be serviced by
-calling dbri_process_interrupt_buffer(), which works even if the CPU's
-interrupts are disabled.
-
-*/
-
-/* xmit_descs()
- *
- * Starts transmitting the current TD's for recording/playing.
- * For playback, ALSA has filled the DMA memory with new data (we hope).
- */
-static void xmit_descs(struct snd_dbri *dbri)
-{
- struct dbri_streaminfo *info;
- s32 *cmd;
- unsigned long flags;
- int first_td;
-
- if (dbri == NULL)
- return; /* Disabled */
-
- info = &dbri->stream_info[DBRI_REC];
- spin_lock_irqsave(&dbri->lock, flags);
-
- if (info->pipe >= 0) {
- first_td = dbri->pipes[info->pipe].first_desc;
-
- dprintk(D_DESC, "xmit_descs rec @ TD %d\n", first_td);
-
- /* Stream could be closed by the time we run. */
- if (first_td >= 0) {
- cmd = dbri_cmdlock(dbri, 2);
- *(cmd++) = DBRI_CMD(D_SDP, 0,
- dbri->pipes[info->pipe].sdp
- | D_SDP_P | D_SDP_EVERY | D_SDP_C);
- *(cmd++) = dbri->dma_dvma +
- dbri_dma_off(desc, first_td);
- dbri_cmdsend(dbri, cmd, 2);
-
- /* Reset our admin of the pipe. */
- dbri->pipes[info->pipe].desc = first_td;
- }
- }
-
- info = &dbri->stream_info[DBRI_PLAY];
-
- if (info->pipe >= 0) {
- first_td = dbri->pipes[info->pipe].first_desc;
-
- dprintk(D_DESC, "xmit_descs play @ TD %d\n", first_td);
-
- /* Stream could be closed by the time we run. */
- if (first_td >= 0) {
- cmd = dbri_cmdlock(dbri, 2);
- *(cmd++) = DBRI_CMD(D_SDP, 0,
- dbri->pipes[info->pipe].sdp
- | D_SDP_P | D_SDP_EVERY | D_SDP_C);
- *(cmd++) = dbri->dma_dvma +
- dbri_dma_off(desc, first_td);
- dbri_cmdsend(dbri, cmd, 2);
-
- /* Reset our admin of the pipe. */
- dbri->pipes[info->pipe].desc = first_td;
- }
- }
-
- spin_unlock_irqrestore(&dbri->lock, flags);
-}
-
-/* transmission_complete_intr()
- *
- * Called by main interrupt handler when DBRI signals transmission complete
- * on a pipe (interrupt triggered by the B bit in a transmit descriptor).
- *
- * Walks through the pipe's list of transmit buffer descriptors and marks
- * them as available. Stops when the first descriptor is found without
- * TBC (Transmit Buffer Complete) set, or we've run through them all.
- *
- * The DMA buffers are not released. They form a ring buffer and
- * they are filled by ALSA while others are transmitted by DMA.
- *
- */
-
-static void transmission_complete_intr(struct snd_dbri *dbri, int pipe)
-{
- struct dbri_streaminfo *info = &dbri->stream_info[DBRI_PLAY];
- int td = dbri->pipes[pipe].desc;
- int status;
-
- while (td >= 0) {
- if (td >= DBRI_NO_DESCS) {
- printk(KERN_ERR "DBRI: invalid td on pipe %d\n", pipe);
- return;
- }
-
- status = DBRI_TD_STATUS(dbri->dma->desc[td].word4);
- if (!(status & DBRI_TD_TBC))
- break;
-
- dprintk(D_INT, "TD %d, status 0x%02x\n", td, status);
-
- dbri->dma->desc[td].word4 = 0; /* Reset it for next time. */
- info->offset += DBRI_RD_CNT(dbri->dma->desc[td].word1);
-
- td = dbri->next_desc[td];
- dbri->pipes[pipe].desc = td;
- }
-
- /* Notify ALSA */
- spin_unlock(&dbri->lock);
- snd_pcm_period_elapsed(info->substream);
- spin_lock(&dbri->lock);
-}
-
-static void reception_complete_intr(struct snd_dbri *dbri, int pipe)
-{
- struct dbri_streaminfo *info;
- int rd = dbri->pipes[pipe].desc;
- s32 status;
-
- if (rd < 0 || rd >= DBRI_NO_DESCS) {
- printk(KERN_ERR "DBRI: invalid rd on pipe %d\n", pipe);
- return;
- }
-
- dbri->pipes[pipe].desc = dbri->next_desc[rd];
- status = dbri->dma->desc[rd].word1;
- dbri->dma->desc[rd].word1 = 0; /* Reset it for next time. */
-
- info = &dbri->stream_info[DBRI_REC];
- info->offset += DBRI_RD_CNT(status);
-
- /* FIXME: Check status */
-
- dprintk(D_INT, "Recv RD %d, status 0x%02x, len %d\n",
- rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status));
-
- /* Notify ALSA */
- spin_unlock(&dbri->lock);
- snd_pcm_period_elapsed(info->substream);
- spin_lock(&dbri->lock);
-}
-
-static void dbri_process_one_interrupt(struct snd_dbri *dbri, int x)
-{
- int val = D_INTR_GETVAL(x);
- int channel = D_INTR_GETCHAN(x);
- int command = D_INTR_GETCMD(x);
- int code = D_INTR_GETCODE(x);
-#ifdef DBRI_DEBUG
- int rval = D_INTR_GETRVAL(x);
-#endif
-
- if (channel == D_INTR_CMD) {
- dprintk(D_CMD, "INTR: Command: %-5s Value:%d\n",
- cmds[command], val);
- } else {
- dprintk(D_INT, "INTR: Chan:%d Code:%d Val:%#x\n",
- channel, code, rval);
- }
-
- switch (code) {
- case D_INTR_CMDI:
- if (command != D_WAIT)
- printk(KERN_ERR "DBRI: Command read interrupt\n");
- break;
- case D_INTR_BRDY:
- reception_complete_intr(dbri, channel);
- break;
- case D_INTR_XCMP:
- case D_INTR_MINT:
- transmission_complete_intr(dbri, channel);
- break;
- case D_INTR_UNDR:
- /* UNDR - Transmission underrun
- * resend SDP command with clear pipe bit (C) set
- */
- {
- /* FIXME: do something useful in case of underrun */
- printk(KERN_ERR "DBRI: Underrun error\n");
-#if 0
- s32 *cmd;
- int pipe = channel;
- int td = dbri->pipes[pipe].desc;
-
- dbri->dma->desc[td].word4 = 0;
- cmd = dbri_cmdlock(dbri, NoGetLock);
- *(cmd++) = DBRI_CMD(D_SDP, 0,
- dbri->pipes[pipe].sdp
- | D_SDP_P | D_SDP_C | D_SDP_2SAME);
- *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, td);
- dbri_cmdsend(dbri, cmd);
-#endif
- }
- break;
- case D_INTR_FXDT:
- /* FXDT - Fixed data change */
- if (dbri->pipes[channel].sdp & D_SDP_MSB)
- val = reverse_bytes(val, dbri->pipes[channel].length);
-
- if (dbri->pipes[channel].recv_fixed_ptr)
- *(dbri->pipes[channel].recv_fixed_ptr) = val;
- break;
- default:
- if (channel != D_INTR_CMD)
- printk(KERN_WARNING
- "DBRI: Ignored Interrupt: %d (0x%x)\n", code, x);
- }
-}
-
-/* dbri_process_interrupt_buffer advances through the DBRI's interrupt
- * buffer until it finds a zero word (indicating nothing more to do
- * right now). Non-zero words require processing and are handed off
- * to dbri_process_one_interrupt AFTER advancing the pointer.
- */
-static void dbri_process_interrupt_buffer(struct snd_dbri *dbri)
-{
- s32 x;
-
- while ((x = dbri->dma->intr[dbri->dbri_irqp]) != 0) {
- dbri->dma->intr[dbri->dbri_irqp] = 0;
- dbri->dbri_irqp++;
- if (dbri->dbri_irqp == DBRI_INT_BLK)
- dbri->dbri_irqp = 1;
-
- dbri_process_one_interrupt(dbri, x);
- }
-}
-
-static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id)
-{
- struct snd_dbri *dbri = dev_id;
- static int errcnt = 0;
- int x;
-
- if (dbri == NULL)
- return IRQ_NONE;
- spin_lock(&dbri->lock);
-
- /*
- * Read it, so the interrupt goes away.
- */
- x = sbus_readl(dbri->regs + REG1);
-
- if (x & (D_MRR | D_MLE | D_LBG | D_MBE)) {
- u32 tmp;
-
- if (x & D_MRR)
- printk(KERN_ERR
- "DBRI: Multiple Error Ack on SBus reg1=0x%x\n",
- x);
- if (x & D_MLE)
- printk(KERN_ERR
- "DBRI: Multiple Late Error on SBus reg1=0x%x\n",
- x);
- if (x & D_LBG)
- printk(KERN_ERR
- "DBRI: Lost Bus Grant on SBus reg1=0x%x\n", x);
- if (x & D_MBE)
- printk(KERN_ERR
- "DBRI: Burst Error on SBus reg1=0x%x\n", x);
-
- /* Some of these SBus errors cause the chip's SBus circuitry
- * to be disabled, so just re-enable and try to keep going.
- *
- * The only one I've seen is MRR, which will be triggered
- * if you let a transmit pipe underrun, then try to CDP it.
- *
- * If these things persist, we reset the chip.
- */
- if ((++errcnt) % 10 == 0) {
- dprintk(D_INT, "Interrupt errors exceeded.\n");
- dbri_reset(dbri);
- } else {
- tmp = sbus_readl(dbri->regs + REG0);
- tmp &= ~(D_D);
- sbus_writel(tmp, dbri->regs + REG0);
- }
- }
-
- dbri_process_interrupt_buffer(dbri);
-
- spin_unlock(&dbri->lock);
-
- return IRQ_HANDLED;
-}
-
-/****************************************************************************
- PCM Interface
-****************************************************************************/
-static struct snd_pcm_hardware snd_dbri_pcm_hw = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BATCH,
- .formats = SNDRV_PCM_FMTBIT_MU_LAW |
- SNDRV_PCM_FMTBIT_A_LAW |
- SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_BE,
- .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_5512,
- .rate_min = 5512,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 64 * 1024,
- .period_bytes_min = 1,
- .period_bytes_max = DBRI_TD_MAXCNT,
- .periods_min = 1,
- .periods_max = 1024,
-};
-
-static int snd_hw_rule_format(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_interval *c = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
- struct snd_mask fmt;
-
- snd_mask_any(&fmt);
- if (c->min > 1) {
- fmt.bits[0] &= SNDRV_PCM_FMTBIT_S16_BE;
- return snd_mask_refine(f, &fmt);
- }
- return 0;
-}
-
-static int snd_hw_rule_channels(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_interval *c = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
- struct snd_interval ch;
-
- snd_interval_any(&ch);
- if (!(f->bits[0] & SNDRV_PCM_FMTBIT_S16_BE)) {
- ch.min = 1;
- ch.max = 1;
- ch.integer = 1;
- return snd_interval_refine(c, &ch);
- }
- return 0;
-}
-
-static int snd_dbri_open(struct snd_pcm_substream *substream)
-{
- struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
- unsigned long flags;
-
- dprintk(D_USR, "open audio output.\n");
- runtime->hw = snd_dbri_pcm_hw;
-
- spin_lock_irqsave(&dbri->lock, flags);
- info->substream = substream;
- info->offset = 0;
- info->dvma_buffer = 0;
- info->pipe = -1;
- spin_unlock_irqrestore(&dbri->lock, flags);
-
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- snd_hw_rule_format, NULL, SNDRV_PCM_HW_PARAM_FORMAT,
- -1);
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
- snd_hw_rule_channels, NULL,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- -1);
-
- cs4215_open(dbri);
-
- return 0;
-}
-
-static int snd_dbri_close(struct snd_pcm_substream *substream)
-{
- struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
- struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
-
- dprintk(D_USR, "close audio output.\n");
- info->substream = NULL;
- info->offset = 0;
-
- return 0;
-}
-
-static int snd_dbri_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
- struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
- int direction;
- int ret;
-
- /* set sampling rate, audio format and number of channels */
- ret = cs4215_prepare(dbri, params_rate(hw_params),
- params_format(hw_params),
- params_channels(hw_params));
- if (ret != 0)
- return ret;
-
- if ((ret = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params))) < 0) {
- printk(KERN_ERR "malloc_pages failed with %d\n", ret);
- return ret;
- }
-
- /* hw_params can get called multiple times. Only map the DMA once.
- */
- if (info->dvma_buffer == 0) {
- if (DBRI_STREAMNO(substream) == DBRI_PLAY)
- direction = DMA_TO_DEVICE;
- else
- direction = DMA_FROM_DEVICE;
-
- info->dvma_buffer =
- dma_map_single(&dbri->op->dev,
- runtime->dma_area,
- params_buffer_bytes(hw_params),
- direction);
- }
-
- direction = params_buffer_bytes(hw_params);
- dprintk(D_USR, "hw_params: %d bytes, dvma=%x\n",
- direction, info->dvma_buffer);
- return 0;
-}
-
-static int snd_dbri_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
- struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
- int direction;
-
- dprintk(D_USR, "hw_free.\n");
-
- /* hw_free can get called multiple times. Only unmap the DMA once.
- */
- if (info->dvma_buffer) {
- if (DBRI_STREAMNO(substream) == DBRI_PLAY)
- direction = DMA_TO_DEVICE;
- else
- direction = DMA_FROM_DEVICE;
-
- dma_unmap_single(&dbri->op->dev, info->dvma_buffer,
- substream->runtime->buffer_size, direction);
- info->dvma_buffer = 0;
- }
- if (info->pipe != -1) {
- reset_pipe(dbri, info->pipe);
- info->pipe = -1;
- }
-
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_dbri_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
- struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
- int ret;
-
- info->size = snd_pcm_lib_buffer_bytes(substream);
- if (DBRI_STREAMNO(substream) == DBRI_PLAY)
- info->pipe = 4; /* Send pipe */
- else
- info->pipe = 6; /* Receive pipe */
-
- spin_lock_irq(&dbri->lock);
- info->offset = 0;
-
- /* Setup the all the transmit/receive descriptors to cover the
- * whole DMA buffer.
- */
- ret = setup_descs(dbri, DBRI_STREAMNO(substream),
- snd_pcm_lib_period_bytes(substream));
-
- spin_unlock_irq(&dbri->lock);
-
- dprintk(D_USR, "prepare audio output. %d bytes\n", info->size);
- return ret;
-}
-
-static int snd_dbri_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
- struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
- int ret = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- dprintk(D_USR, "start audio, period is %d bytes\n",
- (int)snd_pcm_lib_period_bytes(substream));
- /* Re-submit the TDs. */
- xmit_descs(dbri);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- dprintk(D_USR, "stop audio.\n");
- reset_pipe(dbri, info->pipe);
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static snd_pcm_uframes_t snd_dbri_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
- struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
- snd_pcm_uframes_t ret;
-
- ret = bytes_to_frames(substream->runtime, info->offset)
- % substream->runtime->buffer_size;
- dprintk(D_USR, "I/O pointer: %ld frames of %ld.\n",
- ret, substream->runtime->buffer_size);
- return ret;
-}
-
-static struct snd_pcm_ops snd_dbri_ops = {
- .open = snd_dbri_open,
- .close = snd_dbri_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_dbri_hw_params,
- .hw_free = snd_dbri_hw_free,
- .prepare = snd_dbri_prepare,
- .trigger = snd_dbri_trigger,
- .pointer = snd_dbri_pointer,
-};
-
-static int __devinit snd_dbri_pcm(struct snd_card *card)
-{
- struct snd_pcm *pcm;
- int err;
-
- if ((err = snd_pcm_new(card,
- /* ID */ "sun_dbri",
- /* device */ 0,
- /* playback count */ 1,
- /* capture count */ 1, &pcm)) < 0)
- return err;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dbri_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_dbri_ops);
-
- pcm->private_data = card->private_data;
- pcm->info_flags = 0;
- strcpy(pcm->name, card->shortname);
-
- if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- 64 * 1024, 64 * 1024)) < 0)
- return err;
-
- return 0;
-}
-
-/*****************************************************************************
- Mixer interface
-*****************************************************************************/
-
-static int snd_cs4215_info_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- if (kcontrol->private_value == DBRI_PLAY)
- uinfo->value.integer.max = DBRI_MAX_VOLUME;
- else
- uinfo->value.integer.max = DBRI_MAX_GAIN;
- return 0;
-}
-
-static int snd_cs4215_get_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol);
- struct dbri_streaminfo *info;
-
- if (snd_BUG_ON(!dbri))
- return -EINVAL;
- info = &dbri->stream_info[kcontrol->private_value];
-
- ucontrol->value.integer.value[0] = info->left_gain;
- ucontrol->value.integer.value[1] = info->right_gain;
- return 0;
-}
-
-static int snd_cs4215_put_volume(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol);
- struct dbri_streaminfo *info =
- &dbri->stream_info[kcontrol->private_value];
- unsigned int vol[2];
- int changed = 0;
-
- vol[0] = ucontrol->value.integer.value[0];
- vol[1] = ucontrol->value.integer.value[1];
- if (kcontrol->private_value == DBRI_PLAY) {
- if (vol[0] > DBRI_MAX_VOLUME || vol[1] > DBRI_MAX_VOLUME)
- return -EINVAL;
- } else {
- if (vol[0] > DBRI_MAX_GAIN || vol[1] > DBRI_MAX_GAIN)
- return -EINVAL;
- }
-
- if (info->left_gain != vol[0]) {
- info->left_gain = vol[0];
- changed = 1;
- }
- if (info->right_gain != vol[1]) {
- info->right_gain = vol[1];
- changed = 1;
- }
- if (changed) {
- /* First mute outputs, and wait 1/8000 sec (125 us)
- * to make sure this takes. This avoids clicking noises.
- */
- cs4215_setdata(dbri, 1);
- udelay(125);
- cs4215_setdata(dbri, 0);
- }
- return changed;
-}
-
-static int snd_cs4215_info_single(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 16) & 0xff;
-
- uinfo->type = (mask == 1) ?
- SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
- return 0;
-}
-
-static int snd_cs4215_get_single(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol);
- int elem = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 1;
-
- if (snd_BUG_ON(!dbri))
- return -EINVAL;
-
- if (elem < 4)
- ucontrol->value.integer.value[0] =
- (dbri->mm.data[elem] >> shift) & mask;
- else
- ucontrol->value.integer.value[0] =
- (dbri->mm.ctrl[elem - 4] >> shift) & mask;
-
- if (invert == 1)
- ucontrol->value.integer.value[0] =
- mask - ucontrol->value.integer.value[0];
- return 0;
-}
-
-static int snd_cs4215_put_single(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol);
- int elem = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 1;
- int changed = 0;
- unsigned short val;
-
- if (snd_BUG_ON(!dbri))
- return -EINVAL;
-
- val = (ucontrol->value.integer.value[0] & mask);
- if (invert == 1)
- val = mask - val;
- val <<= shift;
-
- if (elem < 4) {
- dbri->mm.data[elem] = (dbri->mm.data[elem] &
- ~(mask << shift)) | val;
- changed = (val != dbri->mm.data[elem]);
- } else {
- dbri->mm.ctrl[elem - 4] = (dbri->mm.ctrl[elem - 4] &
- ~(mask << shift)) | val;
- changed = (val != dbri->mm.ctrl[elem - 4]);
- }
-
- dprintk(D_GEN, "put_single: mask=0x%x, changed=%d, "
- "mixer-value=%ld, mm-value=0x%x\n",
- mask, changed, ucontrol->value.integer.value[0],
- dbri->mm.data[elem & 3]);
-
- if (changed) {
- /* First mute outputs, and wait 1/8000 sec (125 us)
- * to make sure this takes. This avoids clicking noises.
- */
- cs4215_setdata(dbri, 1);
- udelay(125);
- cs4215_setdata(dbri, 0);
- }
- return changed;
-}
-
-/* Entries 0-3 map to the 4 data timeslots, entries 4-7 map to the 4 control
- timeslots. Shift is the bit offset in the timeslot, mask defines the
- number of bits. invert is a boolean for use with attenuation.
- */
-#define CS4215_SINGLE(xname, entry, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
- .info = snd_cs4215_info_single, \
- .get = snd_cs4215_get_single, .put = snd_cs4215_put_single, \
- .private_value = (entry) | ((shift) << 8) | ((mask) << 16) | \
- ((invert) << 24) },
-
-static struct snd_kcontrol_new dbri_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Playback Volume",
- .info = snd_cs4215_info_volume,
- .get = snd_cs4215_get_volume,
- .put = snd_cs4215_put_volume,
- .private_value = DBRI_PLAY,
- },
- CS4215_SINGLE("Headphone switch", 0, 7, 1, 0)
- CS4215_SINGLE("Line out switch", 0, 6, 1, 0)
- CS4215_SINGLE("Speaker switch", 1, 6, 1, 0)
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Volume",
- .info = snd_cs4215_info_volume,
- .get = snd_cs4215_get_volume,
- .put = snd_cs4215_put_volume,
- .private_value = DBRI_REC,
- },
- /* FIXME: mic/line switch */
- CS4215_SINGLE("Line in switch", 2, 4, 1, 0)
- CS4215_SINGLE("High Pass Filter switch", 5, 7, 1, 0)
- CS4215_SINGLE("Monitor Volume", 3, 4, 0xf, 1)
- CS4215_SINGLE("Mic boost", 4, 4, 1, 1)
-};
-
-static int __devinit snd_dbri_mixer(struct snd_card *card)
-{
- int idx, err;
- struct snd_dbri *dbri;
-
- if (snd_BUG_ON(!card || !card->private_data))
- return -EINVAL;
- dbri = card->private_data;
-
- strcpy(card->mixername, card->shortname);
-
- for (idx = 0; idx < ARRAY_SIZE(dbri_controls); idx++) {
- err = snd_ctl_add(card,
- snd_ctl_new1(&dbri_controls[idx], dbri));
- if (err < 0)
- return err;
- }
-
- for (idx = DBRI_REC; idx < DBRI_NO_STREAMS; idx++) {
- dbri->stream_info[idx].left_gain = 0;
- dbri->stream_info[idx].right_gain = 0;
- }
-
- return 0;
-}
-
-/****************************************************************************
- /proc interface
-****************************************************************************/
-static void dbri_regs_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_dbri *dbri = entry->private_data;
-
- snd_iprintf(buffer, "REG0: 0x%x\n", sbus_readl(dbri->regs + REG0));
- snd_iprintf(buffer, "REG2: 0x%x\n", sbus_readl(dbri->regs + REG2));
- snd_iprintf(buffer, "REG8: 0x%x\n", sbus_readl(dbri->regs + REG8));
- snd_iprintf(buffer, "REG9: 0x%x\n", sbus_readl(dbri->regs + REG9));
-}
-
-#ifdef DBRI_DEBUG
-static void dbri_debug_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_dbri *dbri = entry->private_data;
- int pipe;
- snd_iprintf(buffer, "debug=%d\n", dbri_debug);
-
- for (pipe = 0; pipe < 32; pipe++) {
- if (pipe_active(dbri, pipe)) {
- struct dbri_pipe *pptr = &dbri->pipes[pipe];
- snd_iprintf(buffer,
- "Pipe %d: %s SDP=0x%x desc=%d, "
- "len=%d next %d\n",
- pipe,
- (pptr->sdp & D_SDP_TO_SER) ? "output" :
- "input",
- pptr->sdp, pptr->desc,
- pptr->length, pptr->nextpipe);
- }
- }
-}
-#endif
-
-static void __devinit snd_dbri_proc(struct snd_card *card)
-{
- struct snd_dbri *dbri = card->private_data;
- struct snd_info_entry *entry;
-
- if (!snd_card_proc_new(card, "regs", &entry))
- snd_info_set_text_ops(entry, dbri, dbri_regs_read);
-
-#ifdef DBRI_DEBUG
- if (!snd_card_proc_new(card, "debug", &entry)) {
- snd_info_set_text_ops(entry, dbri, dbri_debug_read);
- entry->mode = S_IFREG | S_IRUGO; /* Readable only. */
- }
-#endif
-}
-
-/*
-****************************************************************************
-**************************** Initialization ********************************
-****************************************************************************
-*/
-static void snd_dbri_free(struct snd_dbri *dbri);
-
-static int __devinit snd_dbri_create(struct snd_card *card,
- struct platform_device *op,
- int irq, int dev)
-{
- struct snd_dbri *dbri = card->private_data;
- int err;
-
- spin_lock_init(&dbri->lock);
- dbri->op = op;
- dbri->irq = irq;
-
- dbri->dma = dma_alloc_coherent(&op->dev,
- sizeof(struct dbri_dma),
- &dbri->dma_dvma, GFP_ATOMIC);
- if (!dbri->dma)
- return -ENOMEM;
- memset((void *)dbri->dma, 0, sizeof(struct dbri_dma));
-
- dprintk(D_GEN, "DMA Cmd Block 0x%p (0x%08x)\n",
- dbri->dma, dbri->dma_dvma);
-
- /* Map the registers into memory. */
- dbri->regs_size = resource_size(&op->resource[0]);
- dbri->regs = of_ioremap(&op->resource[0], 0,
- dbri->regs_size, "DBRI Registers");
- if (!dbri->regs) {
- printk(KERN_ERR "DBRI: could not allocate registers\n");
- dma_free_coherent(&op->dev, sizeof(struct dbri_dma),
- (void *)dbri->dma, dbri->dma_dvma);
- return -EIO;
- }
-
- err = request_irq(dbri->irq, snd_dbri_interrupt, IRQF_SHARED,
- "DBRI audio", dbri);
- if (err) {
- printk(KERN_ERR "DBRI: Can't get irq %d\n", dbri->irq);
- of_iounmap(&op->resource[0], dbri->regs, dbri->regs_size);
- dma_free_coherent(&op->dev, sizeof(struct dbri_dma),
- (void *)dbri->dma, dbri->dma_dvma);
- return err;
- }
-
- /* Do low level initialization of the DBRI and CS4215 chips */
- dbri_initialize(dbri);
- err = cs4215_init(dbri);
- if (err) {
- snd_dbri_free(dbri);
- return err;
- }
-
- return 0;
-}
-
-static void snd_dbri_free(struct snd_dbri *dbri)
-{
- dprintk(D_GEN, "snd_dbri_free\n");
- dbri_reset(dbri);
-
- if (dbri->irq)
- free_irq(dbri->irq, dbri);
-
- if (dbri->regs)
- of_iounmap(&dbri->op->resource[0], dbri->regs, dbri->regs_size);
-
- if (dbri->dma)
- dma_free_coherent(&dbri->op->dev,
- sizeof(struct dbri_dma),
- (void *)dbri->dma, dbri->dma_dvma);
-}
-
-static int __devinit dbri_probe(struct platform_device *op)
-{
- struct snd_dbri *dbri;
- struct resource *rp;
- struct snd_card *card;
- static int dev = 0;
- int irq;
- int err;
-
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- irq = op->archdata.irqs[0];
- if (irq <= 0) {
- printk(KERN_ERR "DBRI-%d: No IRQ.\n", dev);
- return -ENODEV;
- }
-
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_dbri), &card);
- if (err < 0)
- return err;
-
- strcpy(card->driver, "DBRI");
- strcpy(card->shortname, "Sun DBRI");
- rp = &op->resource[0];
- sprintf(card->longname, "%s at 0x%02lx:0x%016Lx, irq %d",
- card->shortname,
- rp->flags & 0xffL, (unsigned long long)rp->start, irq);
-
- err = snd_dbri_create(card, op, irq, dev);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- dbri = card->private_data;
- err = snd_dbri_pcm(card);
- if (err < 0)
- goto _err;
-
- err = snd_dbri_mixer(card);
- if (err < 0)
- goto _err;
-
- /* /proc file handling */
- snd_dbri_proc(card);
- dev_set_drvdata(&op->dev, card);
-
- err = snd_card_register(card);
- if (err < 0)
- goto _err;
-
- printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n",
- dev, dbri->regs,
- dbri->irq, op->dev.of_node->name[9], dbri->mm.version);
- dev++;
-
- return 0;
-
-_err:
- snd_dbri_free(dbri);
- snd_card_free(card);
- return err;
-}
-
-static int __devexit dbri_remove(struct platform_device *op)
-{
- struct snd_card *card = dev_get_drvdata(&op->dev);
-
- snd_dbri_free(card->private_data);
- snd_card_free(card);
-
- dev_set_drvdata(&op->dev, NULL);
-
- return 0;
-}
-
-static const struct of_device_id dbri_match[] = {
- {
- .name = "SUNW,DBRIe",
- },
- {
- .name = "SUNW,DBRIf",
- },
- {},
-};
-
-MODULE_DEVICE_TABLE(of, dbri_match);
-
-static struct platform_driver dbri_sbus_driver = {
- .driver = {
- .name = "dbri",
- .owner = THIS_MODULE,
- .of_match_table = dbri_match,
- },
- .probe = dbri_probe,
- .remove = __devexit_p(dbri_remove),
-};
-
-module_platform_driver(dbri_sbus_driver);
diff --git a/ANDROID_3.4.5/sound/spi/Kconfig b/ANDROID_3.4.5/sound/spi/Kconfig
deleted file mode 100644
index e6485be2..00000000
--- a/ANDROID_3.4.5/sound/spi/Kconfig
+++ /dev/null
@@ -1,38 +0,0 @@
-#SPI drivers
-
-menuconfig SND_SPI
- bool "SPI sound devices"
- depends on SPI
- default y
- help
- Support for sound devices connected via the SPI bus.
-
-if SND_SPI
-
-config SND_AT73C213
- tristate "Atmel AT73C213 DAC driver"
- depends on ATMEL_SSC
- select SND_PCM
- help
- Say Y here if you want to use the Atmel AT73C213 external DAC. This
- DAC can be found on Atmel development boards.
-
- This driver requires the Atmel SSC driver for sound sink, a
- peripheral found on most AT91 and AVR32 microprocessors.
-
- To compile this driver as a module, choose M here: the module will be
- called snd-at73c213.
-
-config SND_AT73C213_TARGET_BITRATE
- int "Target bitrate for AT73C213"
- depends on SND_AT73C213
- default "48000"
- range 8000 50000
- help
- Sets the target bitrate for the bitrate calculator in the driver.
- Limited by hardware to be between 8000 Hz and 50000 Hz.
-
- Set to 48000 Hz by default.
-
-endif # SND_SPI
-
diff --git a/ANDROID_3.4.5/sound/spi/Makefile b/ANDROID_3.4.5/sound/spi/Makefile
deleted file mode 100644
index 026fb73f..00000000
--- a/ANDROID_3.4.5/sound/spi/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-# Makefile for SPI drivers
-
-snd-at73c213-objs := at73c213.o
-
-obj-$(CONFIG_SND_AT73C213) += snd-at73c213.o
diff --git a/ANDROID_3.4.5/sound/spi/at73c213.c b/ANDROID_3.4.5/sound/spi/at73c213.c
deleted file mode 100644
index c6500d00..00000000
--- a/ANDROID_3.4.5/sound/spi/at73c213.c
+++ /dev/null
@@ -1,1119 +0,0 @@
-/*
- * Driver for AT73C213 16-bit stereo DAC connected to Atmel SSC
- *
- * Copyright (C) 2006-2007 Atmel Norway
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- */
-
-/*#define DEBUG*/
-
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <sound/initval.h>
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include <linux/atmel-ssc.h>
-
-#include <linux/spi/spi.h>
-#include <linux/spi/at73c213.h>
-
-#include "at73c213.h"
-
-#define BITRATE_MIN 8000 /* Hardware limit? */
-#define BITRATE_TARGET CONFIG_SND_AT73C213_TARGET_BITRATE
-#define BITRATE_MAX 50000 /* Hardware limit. */
-
-/* Initial (hardware reset) AT73C213 register values. */
-static u8 snd_at73c213_original_image[18] =
-{
- 0x00, /* 00 - CTRL */
- 0x05, /* 01 - LLIG */
- 0x05, /* 02 - RLIG */
- 0x08, /* 03 - LPMG */
- 0x08, /* 04 - RPMG */
- 0x00, /* 05 - LLOG */
- 0x00, /* 06 - RLOG */
- 0x22, /* 07 - OLC */
- 0x09, /* 08 - MC */
- 0x00, /* 09 - CSFC */
- 0x00, /* 0A - MISC */
- 0x00, /* 0B - */
- 0x00, /* 0C - PRECH */
- 0x05, /* 0D - AUXG */
- 0x00, /* 0E - */
- 0x00, /* 0F - */
- 0x00, /* 10 - RST */
- 0x00, /* 11 - PA_CTRL */
-};
-
-struct snd_at73c213 {
- struct snd_card *card;
- struct snd_pcm *pcm;
- struct snd_pcm_substream *substream;
- struct at73c213_board_info *board;
- int irq;
- int period;
- unsigned long bitrate;
- struct ssc_device *ssc;
- struct spi_device *spi;
- u8 spi_wbuffer[2];
- u8 spi_rbuffer[2];
- /* Image of the SPI registers in AT73C213. */
- u8 reg_image[18];
- /* Protect SSC registers against concurrent access. */
- spinlock_t lock;
- /* Protect mixer registers against concurrent access. */
- struct mutex mixer_lock;
-};
-
-#define get_chip(card) ((struct snd_at73c213 *)card->private_data)
-
-static int
-snd_at73c213_write_reg(struct snd_at73c213 *chip, u8 reg, u8 val)
-{
- struct spi_message msg;
- struct spi_transfer msg_xfer = {
- .len = 2,
- .cs_change = 0,
- };
- int retval;
-
- spi_message_init(&msg);
-
- chip->spi_wbuffer[0] = reg;
- chip->spi_wbuffer[1] = val;
-
- msg_xfer.tx_buf = chip->spi_wbuffer;
- msg_xfer.rx_buf = chip->spi_rbuffer;
- spi_message_add_tail(&msg_xfer, &msg);
-
- retval = spi_sync(chip->spi, &msg);
-
- if (!retval)
- chip->reg_image[reg] = val;
-
- return retval;
-}
-
-static struct snd_pcm_hardware snd_at73c213_playback_hw = {
- .info = SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER,
- .formats = SNDRV_PCM_FMTBIT_S16_BE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 8000, /* Replaced by chip->bitrate later. */
- .rate_max = 50000, /* Replaced by chip->bitrate later. */
- .channels_min = 1,
- .channels_max = 2,
- .buffer_bytes_max = 64 * 1024 - 1,
- .period_bytes_min = 512,
- .period_bytes_max = 64 * 1024 - 1,
- .periods_min = 4,
- .periods_max = 1024,
-};
-
-/*
- * Calculate and set bitrate and divisions.
- */
-static int snd_at73c213_set_bitrate(struct snd_at73c213 *chip)
-{
- unsigned long ssc_rate = clk_get_rate(chip->ssc->clk);
- unsigned long dac_rate_new, ssc_div;
- int status;
- unsigned long ssc_div_max, ssc_div_min;
- int max_tries;
-
- /*
- * We connect two clocks here, picking divisors so the I2S clocks
- * out data at the same rate the DAC clocks it in ... and as close
- * as practical to the desired target rate.
- *
- * The DAC master clock (MCLK) is programmable, and is either 256
- * or (not here) 384 times the I2S output clock (BCLK).
- */
-
- /* SSC clock / (bitrate * stereo * 16-bit). */
- ssc_div = ssc_rate / (BITRATE_TARGET * 2 * 16);
- ssc_div_min = ssc_rate / (BITRATE_MAX * 2 * 16);
- ssc_div_max = ssc_rate / (BITRATE_MIN * 2 * 16);
- max_tries = (ssc_div_max - ssc_div_min) / 2;
-
- if (max_tries < 1)
- max_tries = 1;
-
- /* ssc_div must be even. */
- ssc_div = (ssc_div + 1) & ~1UL;
-
- if ((ssc_rate / (ssc_div * 2 * 16)) < BITRATE_MIN) {
- ssc_div -= 2;
- if ((ssc_rate / (ssc_div * 2 * 16)) > BITRATE_MAX)
- return -ENXIO;
- }
-
- /* Search for a possible bitrate. */
- do {
- /* SSC clock / (ssc divider * 16-bit * stereo). */
- if ((ssc_rate / (ssc_div * 2 * 16)) < BITRATE_MIN)
- return -ENXIO;
-
- /* 256 / (2 * 16) = 8 */
- dac_rate_new = 8 * (ssc_rate / ssc_div);
-
- status = clk_round_rate(chip->board->dac_clk, dac_rate_new);
- if (status < 0)
- return status;
-
- /* Ignore difference smaller than 256 Hz. */
- if ((status/256) == (dac_rate_new/256))
- goto set_rate;
-
- ssc_div += 2;
- } while (--max_tries);
-
- /* Not able to find a valid bitrate. */
- return -ENXIO;
-
-set_rate:
- status = clk_set_rate(chip->board->dac_clk, status);
- if (status < 0)
- return status;
-
- /* Set divider in SSC device. */
- ssc_writel(chip->ssc->regs, CMR, ssc_div/2);
-
- /* SSC clock / (ssc divider * 16-bit * stereo). */
- chip->bitrate = ssc_rate / (ssc_div * 16 * 2);
-
- dev_info(&chip->spi->dev,
- "at73c213: supported bitrate is %lu (%lu divider)\n",
- chip->bitrate, ssc_div);
-
- return 0;
-}
-
-static int snd_at73c213_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int err;
-
- /* ensure buffer_size is a multiple of period_size */
- err = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0)
- return err;
- snd_at73c213_playback_hw.rate_min = chip->bitrate;
- snd_at73c213_playback_hw.rate_max = chip->bitrate;
- runtime->hw = snd_at73c213_playback_hw;
- chip->substream = substream;
-
- return 0;
-}
-
-static int snd_at73c213_pcm_close(struct snd_pcm_substream *substream)
-{
- struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
- chip->substream = NULL;
- return 0;
-}
-
-static int snd_at73c213_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
- int channels = params_channels(hw_params);
- int val;
-
- val = ssc_readl(chip->ssc->regs, TFMR);
- val = SSC_BFINS(TFMR_DATNB, channels - 1, val);
- ssc_writel(chip->ssc->regs, TFMR, val);
-
- return snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params));
-}
-
-static int snd_at73c213_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
-static int snd_at73c213_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- int block_size;
-
- block_size = frames_to_bytes(runtime, runtime->period_size);
-
- chip->period = 0;
-
- ssc_writel(chip->ssc->regs, PDC_TPR,
- (long)runtime->dma_addr);
- ssc_writel(chip->ssc->regs, PDC_TCR,
- runtime->period_size * runtime->channels);
- ssc_writel(chip->ssc->regs, PDC_TNPR,
- (long)runtime->dma_addr + block_size);
- ssc_writel(chip->ssc->regs, PDC_TNCR,
- runtime->period_size * runtime->channels);
-
- return 0;
-}
-
-static int snd_at73c213_pcm_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
- int retval = 0;
-
- spin_lock(&chip->lock);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- ssc_writel(chip->ssc->regs, IER, SSC_BIT(IER_ENDTX));
- ssc_writel(chip->ssc->regs, PDC_PTCR, SSC_BIT(PDC_PTCR_TXTEN));
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- ssc_writel(chip->ssc->regs, PDC_PTCR, SSC_BIT(PDC_PTCR_TXTDIS));
- ssc_writel(chip->ssc->regs, IDR, SSC_BIT(IDR_ENDTX));
- break;
- default:
- dev_dbg(&chip->spi->dev, "spurious command %x\n", cmd);
- retval = -EINVAL;
- break;
- }
-
- spin_unlock(&chip->lock);
-
- return retval;
-}
-
-static snd_pcm_uframes_t
-snd_at73c213_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_uframes_t pos;
- unsigned long bytes;
-
- bytes = ssc_readl(chip->ssc->regs, PDC_TPR)
- - (unsigned long)runtime->dma_addr;
-
- pos = bytes_to_frames(runtime, bytes);
- if (pos >= runtime->buffer_size)
- pos -= runtime->buffer_size;
-
- return pos;
-}
-
-static struct snd_pcm_ops at73c213_playback_ops = {
- .open = snd_at73c213_pcm_open,
- .close = snd_at73c213_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_at73c213_pcm_hw_params,
- .hw_free = snd_at73c213_pcm_hw_free,
- .prepare = snd_at73c213_pcm_prepare,
- .trigger = snd_at73c213_pcm_trigger,
- .pointer = snd_at73c213_pcm_pointer,
-};
-
-static int __devinit snd_at73c213_pcm_new(struct snd_at73c213 *chip, int device)
-{
- struct snd_pcm *pcm;
- int retval;
-
- retval = snd_pcm_new(chip->card, chip->card->shortname,
- device, 1, 0, &pcm);
- if (retval < 0)
- goto out;
-
- pcm->private_data = chip;
- pcm->info_flags = SNDRV_PCM_INFO_BLOCK_TRANSFER;
- strcpy(pcm->name, "at73c213");
- chip->pcm = pcm;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &at73c213_playback_ops);
-
- retval = snd_pcm_lib_preallocate_pages_for_all(chip->pcm,
- SNDRV_DMA_TYPE_DEV, &chip->ssc->pdev->dev,
- 64 * 1024, 64 * 1024);
-out:
- return retval;
-}
-
-static irqreturn_t snd_at73c213_interrupt(int irq, void *dev_id)
-{
- struct snd_at73c213 *chip = dev_id;
- struct snd_pcm_runtime *runtime = chip->substream->runtime;
- u32 status;
- int offset;
- int block_size;
- int next_period;
- int retval = IRQ_NONE;
-
- spin_lock(&chip->lock);
-
- block_size = frames_to_bytes(runtime, runtime->period_size);
- status = ssc_readl(chip->ssc->regs, IMR);
-
- if (status & SSC_BIT(IMR_ENDTX)) {
- chip->period++;
- if (chip->period == runtime->periods)
- chip->period = 0;
- next_period = chip->period + 1;
- if (next_period == runtime->periods)
- next_period = 0;
-
- offset = block_size * next_period;
-
- ssc_writel(chip->ssc->regs, PDC_TNPR,
- (long)runtime->dma_addr + offset);
- ssc_writel(chip->ssc->regs, PDC_TNCR,
- runtime->period_size * runtime->channels);
- retval = IRQ_HANDLED;
- }
-
- ssc_readl(chip->ssc->regs, IMR);
- spin_unlock(&chip->lock);
-
- if (status & SSC_BIT(IMR_ENDTX))
- snd_pcm_period_elapsed(chip->substream);
-
- return retval;
-}
-
-/*
- * Mixer functions.
- */
-static int snd_at73c213_mono_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
-
- mutex_lock(&chip->mixer_lock);
-
- ucontrol->value.integer.value[0] =
- (chip->reg_image[reg] >> shift) & mask;
-
- if (invert)
- ucontrol->value.integer.value[0] =
- mask - ucontrol->value.integer.value[0];
-
- mutex_unlock(&chip->mixer_lock);
-
- return 0;
-}
-
-static int snd_at73c213_mono_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
- int change, retval;
- unsigned short val;
-
- val = (ucontrol->value.integer.value[0] & mask);
- if (invert)
- val = mask - val;
- val <<= shift;
-
- mutex_lock(&chip->mixer_lock);
-
- val = (chip->reg_image[reg] & ~(mask << shift)) | val;
- change = val != chip->reg_image[reg];
- retval = snd_at73c213_write_reg(chip, reg, val);
-
- mutex_unlock(&chip->mixer_lock);
-
- if (retval)
- return retval;
-
- return change;
-}
-
-static int snd_at73c213_stereo_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int mask = (kcontrol->private_value >> 24) & 0xff;
-
- if (mask == 1)
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- else
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = mask;
-
- return 0;
-}
-
-static int snd_at73c213_stereo_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int shift_left = (kcontrol->private_value >> 16) & 0x07;
- int shift_right = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
-
- mutex_lock(&chip->mixer_lock);
-
- ucontrol->value.integer.value[0] =
- (chip->reg_image[left_reg] >> shift_left) & mask;
- ucontrol->value.integer.value[1] =
- (chip->reg_image[right_reg] >> shift_right) & mask;
-
- if (invert) {
- ucontrol->value.integer.value[0] =
- mask - ucontrol->value.integer.value[0];
- ucontrol->value.integer.value[1] =
- mask - ucontrol->value.integer.value[1];
- }
-
- mutex_unlock(&chip->mixer_lock);
-
- return 0;
-}
-
-static int snd_at73c213_stereo_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
- int left_reg = kcontrol->private_value & 0xff;
- int right_reg = (kcontrol->private_value >> 8) & 0xff;
- int shift_left = (kcontrol->private_value >> 16) & 0x07;
- int shift_right = (kcontrol->private_value >> 19) & 0x07;
- int mask = (kcontrol->private_value >> 24) & 0xff;
- int invert = (kcontrol->private_value >> 22) & 1;
- int change, retval;
- unsigned short val1, val2;
-
- val1 = ucontrol->value.integer.value[0] & mask;
- val2 = ucontrol->value.integer.value[1] & mask;
- if (invert) {
- val1 = mask - val1;
- val2 = mask - val2;
- }
- val1 <<= shift_left;
- val2 <<= shift_right;
-
- mutex_lock(&chip->mixer_lock);
-
- val1 = (chip->reg_image[left_reg] & ~(mask << shift_left)) | val1;
- val2 = (chip->reg_image[right_reg] & ~(mask << shift_right)) | val2;
- change = val1 != chip->reg_image[left_reg]
- || val2 != chip->reg_image[right_reg];
- retval = snd_at73c213_write_reg(chip, left_reg, val1);
- if (retval) {
- mutex_unlock(&chip->mixer_lock);
- goto out;
- }
- retval = snd_at73c213_write_reg(chip, right_reg, val2);
- if (retval) {
- mutex_unlock(&chip->mixer_lock);
- goto out;
- }
-
- mutex_unlock(&chip->mixer_lock);
-
- return change;
-
-out:
- return retval;
-}
-
-#define snd_at73c213_mono_switch_info snd_ctl_boolean_mono_info
-
-static int snd_at73c213_mono_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
-
- mutex_lock(&chip->mixer_lock);
-
- ucontrol->value.integer.value[0] =
- (chip->reg_image[reg] >> shift) & 0x01;
-
- if (invert)
- ucontrol->value.integer.value[0] =
- 0x01 - ucontrol->value.integer.value[0];
-
- mutex_unlock(&chip->mixer_lock);
-
- return 0;
-}
-
-static int snd_at73c213_mono_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
- int mask = (kcontrol->private_value >> 16) & 0xff;
- int invert = (kcontrol->private_value >> 24) & 0xff;
- int change, retval;
- unsigned short val;
-
- if (ucontrol->value.integer.value[0])
- val = mask;
- else
- val = 0;
-
- if (invert)
- val = mask - val;
- val <<= shift;
-
- mutex_lock(&chip->mixer_lock);
-
- val |= (chip->reg_image[reg] & ~(mask << shift));
- change = val != chip->reg_image[reg];
-
- retval = snd_at73c213_write_reg(chip, reg, val);
-
- mutex_unlock(&chip->mixer_lock);
-
- if (retval)
- return retval;
-
- return change;
-}
-
-static int snd_at73c213_pa_volume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = ((kcontrol->private_value >> 16) & 0xff) - 1;
-
- return 0;
-}
-
-static int snd_at73c213_line_capture_volume_info(
- struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- /* When inverted will give values 0x10001 => 0. */
- uinfo->value.integer.min = 14;
- uinfo->value.integer.max = 31;
-
- return 0;
-}
-
-static int snd_at73c213_aux_capture_volume_info(
- struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- /* When inverted will give values 0x10001 => 0. */
- uinfo->value.integer.min = 14;
- uinfo->value.integer.max = 31;
-
- return 0;
-}
-
-#define AT73C213_MONO_SWITCH(xname, xindex, reg, shift, mask, invert) \
-{ \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_at73c213_mono_switch_info, \
- .get = snd_at73c213_mono_switch_get, \
- .put = snd_at73c213_mono_switch_put, \
- .private_value = (reg | (shift << 8) | (mask << 16) | (invert << 24)) \
-}
-
-#define AT73C213_STEREO(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
-{ \
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- .name = xname, \
- .index = xindex, \
- .info = snd_at73c213_stereo_info, \
- .get = snd_at73c213_stereo_get, \
- .put = snd_at73c213_stereo_put, \
- .private_value = (left_reg | (right_reg << 8) \
- | (shift_left << 16) | (shift_right << 19) \
- | (mask << 24) | (invert << 22)) \
-}
-
-static struct snd_kcontrol_new snd_at73c213_controls[] __devinitdata = {
-AT73C213_STEREO("Master Playback Volume", 0, DAC_LMPG, DAC_RMPG, 0, 0, 0x1f, 1),
-AT73C213_STEREO("Master Playback Switch", 0, DAC_LMPG, DAC_RMPG, 5, 5, 1, 1),
-AT73C213_STEREO("PCM Playback Volume", 0, DAC_LLOG, DAC_RLOG, 0, 0, 0x1f, 1),
-AT73C213_STEREO("PCM Playback Switch", 0, DAC_LLOG, DAC_RLOG, 5, 5, 1, 1),
-AT73C213_MONO_SWITCH("Mono PA Playback Switch", 0, DAC_CTRL, DAC_CTRL_ONPADRV,
- 0x01, 0),
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PA Playback Volume",
- .index = 0,
- .info = snd_at73c213_pa_volume_info,
- .get = snd_at73c213_mono_get,
- .put = snd_at73c213_mono_put,
- .private_value = PA_CTRL | (PA_CTRL_APAGAIN << 8) | \
- (0x0f << 16) | (1 << 24),
-},
-AT73C213_MONO_SWITCH("PA High Gain Playback Switch", 0, PA_CTRL, PA_CTRL_APALP,
- 0x01, 1),
-AT73C213_MONO_SWITCH("PA Playback Switch", 0, PA_CTRL, PA_CTRL_APAON, 0x01, 0),
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Aux Capture Volume",
- .index = 0,
- .info = snd_at73c213_aux_capture_volume_info,
- .get = snd_at73c213_mono_get,
- .put = snd_at73c213_mono_put,
- .private_value = DAC_AUXG | (0 << 8) | (0x1f << 16) | (1 << 24),
-},
-AT73C213_MONO_SWITCH("Aux Capture Switch", 0, DAC_CTRL, DAC_CTRL_ONAUXIN,
- 0x01, 0),
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Line Capture Volume",
- .index = 0,
- .info = snd_at73c213_line_capture_volume_info,
- .get = snd_at73c213_stereo_get,
- .put = snd_at73c213_stereo_put,
- .private_value = DAC_LLIG | (DAC_RLIG << 8) | (0 << 16) | (0 << 19)
- | (0x1f << 24) | (1 << 22),
-},
-AT73C213_MONO_SWITCH("Line Capture Switch", 0, DAC_CTRL, 0, 0x03, 0),
-};
-
-static int __devinit snd_at73c213_mixer(struct snd_at73c213 *chip)
-{
- struct snd_card *card;
- int errval, idx;
-
- if (chip == NULL || chip->pcm == NULL)
- return -EINVAL;
-
- card = chip->card;
-
- strcpy(card->mixername, chip->pcm->name);
-
- for (idx = 0; idx < ARRAY_SIZE(snd_at73c213_controls); idx++) {
- errval = snd_ctl_add(card,
- snd_ctl_new1(&snd_at73c213_controls[idx],
- chip));
- if (errval < 0)
- goto cleanup;
- }
-
- return 0;
-
-cleanup:
- for (idx = 1; idx < ARRAY_SIZE(snd_at73c213_controls) + 1; idx++) {
- struct snd_kcontrol *kctl;
- kctl = snd_ctl_find_numid(card, idx);
- if (kctl)
- snd_ctl_remove(card, kctl);
- }
- return errval;
-}
-
-/*
- * Device functions
- */
-static int __devinit snd_at73c213_ssc_init(struct snd_at73c213 *chip)
-{
- /*
- * Continuous clock output.
- * Starts on falling TF.
- * Delay 1 cycle (1 bit).
- * Periode is 16 bit (16 - 1).
- */
- ssc_writel(chip->ssc->regs, TCMR,
- SSC_BF(TCMR_CKO, 1)
- | SSC_BF(TCMR_START, 4)
- | SSC_BF(TCMR_STTDLY, 1)
- | SSC_BF(TCMR_PERIOD, 16 - 1));
- /*
- * Data length is 16 bit (16 - 1).
- * Transmit MSB first.
- * Transmit 2 words each transfer.
- * Frame sync length is 16 bit (16 - 1).
- * Frame starts on negative pulse.
- */
- ssc_writel(chip->ssc->regs, TFMR,
- SSC_BF(TFMR_DATLEN, 16 - 1)
- | SSC_BIT(TFMR_MSBF)
- | SSC_BF(TFMR_DATNB, 1)
- | SSC_BF(TFMR_FSLEN, 16 - 1)
- | SSC_BF(TFMR_FSOS, 1));
-
- return 0;
-}
-
-static int __devinit snd_at73c213_chip_init(struct snd_at73c213 *chip)
-{
- int retval;
- unsigned char dac_ctrl = 0;
-
- retval = snd_at73c213_set_bitrate(chip);
- if (retval)
- goto out;
-
- /* Enable DAC master clock. */
- clk_enable(chip->board->dac_clk);
-
- /* Initialize at73c213 on SPI bus. */
- retval = snd_at73c213_write_reg(chip, DAC_RST, 0x04);
- if (retval)
- goto out_clk;
- msleep(1);
- retval = snd_at73c213_write_reg(chip, DAC_RST, 0x03);
- if (retval)
- goto out_clk;
-
- /* Precharge everything. */
- retval = snd_at73c213_write_reg(chip, DAC_PRECH, 0xff);
- if (retval)
- goto out_clk;
- retval = snd_at73c213_write_reg(chip, PA_CTRL, (1<<PA_CTRL_APAPRECH));
- if (retval)
- goto out_clk;
- retval = snd_at73c213_write_reg(chip, DAC_CTRL,
- (1<<DAC_CTRL_ONLNOL) | (1<<DAC_CTRL_ONLNOR));
- if (retval)
- goto out_clk;
-
- msleep(50);
-
- /* Stop precharging PA. */
- retval = snd_at73c213_write_reg(chip, PA_CTRL,
- (1<<PA_CTRL_APALP) | 0x0f);
- if (retval)
- goto out_clk;
-
- msleep(450);
-
- /* Stop precharging DAC, turn on master power. */
- retval = snd_at73c213_write_reg(chip, DAC_PRECH, (1<<DAC_PRECH_ONMSTR));
- if (retval)
- goto out_clk;
-
- msleep(1);
-
- /* Turn on DAC. */
- dac_ctrl = (1<<DAC_CTRL_ONDACL) | (1<<DAC_CTRL_ONDACR)
- | (1<<DAC_CTRL_ONLNOL) | (1<<DAC_CTRL_ONLNOR);
-
- retval = snd_at73c213_write_reg(chip, DAC_CTRL, dac_ctrl);
- if (retval)
- goto out_clk;
-
- /* Mute sound. */
- retval = snd_at73c213_write_reg(chip, DAC_LMPG, 0x3f);
- if (retval)
- goto out_clk;
- retval = snd_at73c213_write_reg(chip, DAC_RMPG, 0x3f);
- if (retval)
- goto out_clk;
- retval = snd_at73c213_write_reg(chip, DAC_LLOG, 0x3f);
- if (retval)
- goto out_clk;
- retval = snd_at73c213_write_reg(chip, DAC_RLOG, 0x3f);
- if (retval)
- goto out_clk;
- retval = snd_at73c213_write_reg(chip, DAC_LLIG, 0x11);
- if (retval)
- goto out_clk;
- retval = snd_at73c213_write_reg(chip, DAC_RLIG, 0x11);
- if (retval)
- goto out_clk;
- retval = snd_at73c213_write_reg(chip, DAC_AUXG, 0x11);
- if (retval)
- goto out_clk;
-
- /* Enable I2S device, i.e. clock output. */
- ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXEN));
-
- goto out;
-
-out_clk:
- clk_disable(chip->board->dac_clk);
-out:
- return retval;
-}
-
-static int snd_at73c213_dev_free(struct snd_device *device)
-{
- struct snd_at73c213 *chip = device->device_data;
-
- ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS));
- if (chip->irq >= 0) {
- free_irq(chip->irq, chip);
- chip->irq = -1;
- }
-
- return 0;
-}
-
-static int __devinit snd_at73c213_dev_init(struct snd_card *card,
- struct spi_device *spi)
-{
- static struct snd_device_ops ops = {
- .dev_free = snd_at73c213_dev_free,
- };
- struct snd_at73c213 *chip = get_chip(card);
- int irq, retval;
-
- irq = chip->ssc->irq;
- if (irq < 0)
- return irq;
-
- spin_lock_init(&chip->lock);
- mutex_init(&chip->mixer_lock);
- chip->card = card;
- chip->irq = -1;
-
- retval = request_irq(irq, snd_at73c213_interrupt, 0, "at73c213", chip);
- if (retval) {
- dev_dbg(&chip->spi->dev, "unable to request irq %d\n", irq);
- goto out;
- }
- chip->irq = irq;
-
- memcpy(&chip->reg_image, &snd_at73c213_original_image,
- sizeof(snd_at73c213_original_image));
-
- retval = snd_at73c213_ssc_init(chip);
- if (retval)
- goto out_irq;
-
- retval = snd_at73c213_chip_init(chip);
- if (retval)
- goto out_irq;
-
- retval = snd_at73c213_pcm_new(chip, 0);
- if (retval)
- goto out_irq;
-
- retval = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
- if (retval)
- goto out_irq;
-
- retval = snd_at73c213_mixer(chip);
- if (retval)
- goto out_snd_dev;
-
- snd_card_set_dev(card, &spi->dev);
-
- goto out;
-
-out_snd_dev:
- snd_device_free(card, chip);
-out_irq:
- free_irq(chip->irq, chip);
- chip->irq = -1;
-out:
- return retval;
-}
-
-static int __devinit snd_at73c213_probe(struct spi_device *spi)
-{
- struct snd_card *card;
- struct snd_at73c213 *chip;
- struct at73c213_board_info *board;
- int retval;
- char id[16];
-
- board = spi->dev.platform_data;
- if (!board) {
- dev_dbg(&spi->dev, "no platform_data\n");
- return -ENXIO;
- }
-
- if (!board->dac_clk) {
- dev_dbg(&spi->dev, "no DAC clk\n");
- return -ENXIO;
- }
-
- if (IS_ERR(board->dac_clk)) {
- dev_dbg(&spi->dev, "no DAC clk\n");
- return PTR_ERR(board->dac_clk);
- }
-
- /* Allocate "card" using some unused identifiers. */
- snprintf(id, sizeof id, "at73c213_%d", board->ssc_id);
- retval = snd_card_create(-1, id, THIS_MODULE,
- sizeof(struct snd_at73c213), &card);
- if (retval < 0)
- goto out;
-
- chip = card->private_data;
- chip->spi = spi;
- chip->board = board;
-
- chip->ssc = ssc_request(board->ssc_id);
- if (IS_ERR(chip->ssc)) {
- dev_dbg(&spi->dev, "could not get ssc%d device\n",
- board->ssc_id);
- retval = PTR_ERR(chip->ssc);
- goto out_card;
- }
-
- retval = snd_at73c213_dev_init(card, spi);
- if (retval)
- goto out_ssc;
-
- strcpy(card->driver, "at73c213");
- strcpy(card->shortname, board->shortname);
- sprintf(card->longname, "%s on irq %d", card->shortname, chip->irq);
-
- retval = snd_card_register(card);
- if (retval)
- goto out_ssc;
-
- dev_set_drvdata(&spi->dev, card);
-
- goto out;
-
-out_ssc:
- ssc_free(chip->ssc);
-out_card:
- snd_card_free(card);
-out:
- return retval;
-}
-
-static int __devexit snd_at73c213_remove(struct spi_device *spi)
-{
- struct snd_card *card = dev_get_drvdata(&spi->dev);
- struct snd_at73c213 *chip = card->private_data;
- int retval;
-
- /* Stop playback. */
- ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS));
-
- /* Mute sound. */
- retval = snd_at73c213_write_reg(chip, DAC_LMPG, 0x3f);
- if (retval)
- goto out;
- retval = snd_at73c213_write_reg(chip, DAC_RMPG, 0x3f);
- if (retval)
- goto out;
- retval = snd_at73c213_write_reg(chip, DAC_LLOG, 0x3f);
- if (retval)
- goto out;
- retval = snd_at73c213_write_reg(chip, DAC_RLOG, 0x3f);
- if (retval)
- goto out;
- retval = snd_at73c213_write_reg(chip, DAC_LLIG, 0x11);
- if (retval)
- goto out;
- retval = snd_at73c213_write_reg(chip, DAC_RLIG, 0x11);
- if (retval)
- goto out;
- retval = snd_at73c213_write_reg(chip, DAC_AUXG, 0x11);
- if (retval)
- goto out;
-
- /* Turn off PA. */
- retval = snd_at73c213_write_reg(chip, PA_CTRL,
- chip->reg_image[PA_CTRL] | 0x0f);
- if (retval)
- goto out;
- msleep(10);
- retval = snd_at73c213_write_reg(chip, PA_CTRL,
- (1 << PA_CTRL_APALP) | 0x0f);
- if (retval)
- goto out;
-
- /* Turn off external DAC. */
- retval = snd_at73c213_write_reg(chip, DAC_CTRL, 0x0c);
- if (retval)
- goto out;
- msleep(2);
- retval = snd_at73c213_write_reg(chip, DAC_CTRL, 0x00);
- if (retval)
- goto out;
-
- /* Turn off master power. */
- retval = snd_at73c213_write_reg(chip, DAC_PRECH, 0x00);
- if (retval)
- goto out;
-
-out:
- /* Stop DAC master clock. */
- clk_disable(chip->board->dac_clk);
-
- ssc_free(chip->ssc);
- snd_card_free(card);
- dev_set_drvdata(&spi->dev, NULL);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int snd_at73c213_suspend(struct spi_device *spi, pm_message_t msg)
-{
- struct snd_card *card = dev_get_drvdata(&spi->dev);
- struct snd_at73c213 *chip = card->private_data;
-
- ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS));
- clk_disable(chip->board->dac_clk);
-
- return 0;
-}
-
-static int snd_at73c213_resume(struct spi_device *spi)
-{
- struct snd_card *card = dev_get_drvdata(&spi->dev);
- struct snd_at73c213 *chip = card->private_data;
-
- clk_enable(chip->board->dac_clk);
- ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXEN));
-
- return 0;
-}
-#else
-#define snd_at73c213_suspend NULL
-#define snd_at73c213_resume NULL
-#endif
-
-static struct spi_driver at73c213_driver = {
- .driver = {
- .name = "at73c213",
- },
- .probe = snd_at73c213_probe,
- .suspend = snd_at73c213_suspend,
- .resume = snd_at73c213_resume,
- .remove = __devexit_p(snd_at73c213_remove),
-};
-
-module_spi_driver(at73c213_driver);
-
-MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
-MODULE_DESCRIPTION("Sound driver for AT73C213 with Atmel SSC");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/spi/at73c213.h b/ANDROID_3.4.5/sound/spi/at73c213.h
deleted file mode 100644
index fd8b372d..00000000
--- a/ANDROID_3.4.5/sound/spi/at73c213.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Driver for the AT73C213 16-bit stereo DAC on Atmel ATSTK1000
- *
- * Copyright (C) 2006 - 2007 Atmel Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * The full GNU General Public License is included in this
- * distribution in the file called COPYING.
- */
-
-#ifndef _SND_AT73C213_H
-#define _SND_AT73C213_H
-
-/* DAC control register */
-#define DAC_CTRL 0x00
-#define DAC_CTRL_ONPADRV 7
-#define DAC_CTRL_ONAUXIN 6
-#define DAC_CTRL_ONDACR 5
-#define DAC_CTRL_ONDACL 4
-#define DAC_CTRL_ONLNOR 3
-#define DAC_CTRL_ONLNOL 2
-#define DAC_CTRL_ONLNIR 1
-#define DAC_CTRL_ONLNIL 0
-
-/* DAC left line in gain register */
-#define DAC_LLIG 0x01
-#define DAC_LLIG_LLIG 0
-
-/* DAC right line in gain register */
-#define DAC_RLIG 0x02
-#define DAC_RLIG_RLIG 0
-
-/* DAC Left Master Playback Gain Register */
-#define DAC_LMPG 0x03
-#define DAC_LMPG_LMPG 0
-
-/* DAC Right Master Playback Gain Register */
-#define DAC_RMPG 0x04
-#define DAC_RMPG_RMPG 0
-
-/* DAC Left Line Out Gain Register */
-#define DAC_LLOG 0x05
-#define DAC_LLOG_LLOG 0
-
-/* DAC Right Line Out Gain Register */
-#define DAC_RLOG 0x06
-#define DAC_RLOG_RLOG 0
-
-/* DAC Output Level Control Register */
-#define DAC_OLC 0x07
-#define DAC_OLC_RSHORT 7
-#define DAC_OLC_ROLC 4
-#define DAC_OLC_LSHORT 3
-#define DAC_OLC_LOLC 0
-
-/* DAC Mixer Control Register */
-#define DAC_MC 0x08
-#define DAC_MC_INVR 5
-#define DAC_MC_INVL 4
-#define DAC_MC_RMSMIN2 3
-#define DAC_MC_RMSMIN1 2
-#define DAC_MC_LMSMIN2 1
-#define DAC_MC_LMSMIN1 0
-
-/* DAC Clock and Sampling Frequency Control Register */
-#define DAC_CSFC 0x09
-#define DAC_CSFC_OVRSEL 4
-
-/* DAC Miscellaneous Register */
-#define DAC_MISC 0x0A
-#define DAC_MISC_VCMCAPSEL 7
-#define DAC_MISC_DINTSEL 4
-#define DAC_MISC_DITHEN 3
-#define DAC_MISC_DEEMPEN 2
-#define DAC_MISC_NBITS 0
-
-/* DAC Precharge Control Register */
-#define DAC_PRECH 0x0C
-#define DAC_PRECH_PRCHGPDRV 7
-#define DAC_PRECH_PRCHGAUX1 6
-#define DAC_PRECH_PRCHGLNOR 5
-#define DAC_PRECH_PRCHGLNOL 4
-#define DAC_PRECH_PRCHGLNIR 3
-#define DAC_PRECH_PRCHGLNIL 2
-#define DAC_PRECH_PRCHG 1
-#define DAC_PRECH_ONMSTR 0
-
-/* DAC Auxiliary Input Gain Control Register */
-#define DAC_AUXG 0x0D
-#define DAC_AUXG_AUXG 0
-
-/* DAC Reset Register */
-#define DAC_RST 0x10
-#define DAC_RST_RESMASK 2
-#define DAC_RST_RESFILZ 1
-#define DAC_RST_RSTZ 0
-
-/* Power Amplifier Control Register */
-#define PA_CTRL 0x11
-#define PA_CTRL_APAON 6
-#define PA_CTRL_APAPRECH 5
-#define PA_CTRL_APALP 4
-#define PA_CTRL_APAGAIN 0
-
-#endif /* _SND_AT73C213_H */
diff --git a/ANDROID_3.4.5/sound/synth/Makefile b/ANDROID_3.4.5/sound/synth/Makefile
deleted file mode 100644
index 11eb06ac..00000000
--- a/ANDROID_3.4.5/sound/synth/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-util-mem-objs := util_mem.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_EMU10K1) += snd-util-mem.o
-obj-$(CONFIG_SND_TRIDENT) += snd-util-mem.o
-obj-$(CONFIG_SND_SBAWE_SEQ) += snd-util-mem.o
-obj-$(CONFIG_SND_SEQUENCER) += emux/
diff --git a/ANDROID_3.4.5/sound/synth/emux/Makefile b/ANDROID_3.4.5/sound/synth/emux/Makefile
deleted file mode 100644
index 328594e6..00000000
--- a/ANDROID_3.4.5/sound/synth/emux/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
-#
-
-snd-emux-synth-objs := emux.o emux_synth.o emux_seq.o emux_nrpn.o \
- emux_effect.o emux_proc.o emux_hwdep.o soundfont.o \
- $(if $(CONFIG_SND_SEQUENCER_OSS),emux_oss.o)
-
-# Toplevel Module Dependencies
-obj-$(CONFIG_SND_SBAWE_SEQ) += snd-emux-synth.o
-obj-$(CONFIG_SND_EMU10K1_SEQ) += snd-emux-synth.o
diff --git a/ANDROID_3.4.5/sound/synth/emux/emux.c b/ANDROID_3.4.5/sound/synth/emux/emux.c
deleted file mode 100644
index 93522072..00000000
--- a/ANDROID_3.4.5/sound/synth/emux/emux.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
- *
- * Routines for control of EMU WaveTable chip
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/wait.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <sound/core.h>
-#include <sound/emux_synth.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include "emux_voice.h"
-
-MODULE_AUTHOR("Takashi Iwai");
-MODULE_DESCRIPTION("Routines for control of EMU WaveTable chip");
-MODULE_LICENSE("GPL");
-
-/*
- * create a new hardware dependent device for Emu8000/Emu10k1
- */
-int snd_emux_new(struct snd_emux **remu)
-{
- struct snd_emux *emu;
-
- *remu = NULL;
- emu = kzalloc(sizeof(*emu), GFP_KERNEL);
- if (emu == NULL)
- return -ENOMEM;
-
- spin_lock_init(&emu->voice_lock);
- mutex_init(&emu->register_mutex);
-
- emu->client = -1;
-#ifdef CONFIG_SND_SEQUENCER_OSS
- emu->oss_synth = NULL;
-#endif
- emu->max_voices = 0;
- emu->use_time = 0;
-
- init_timer(&emu->tlist);
- emu->tlist.function = snd_emux_timer_callback;
- emu->tlist.data = (unsigned long)emu;
- emu->timer_active = 0;
-
- *remu = emu;
- return 0;
-}
-
-EXPORT_SYMBOL(snd_emux_new);
-
-/*
- */
-static int sf_sample_new(void *private_data, struct snd_sf_sample *sp,
- struct snd_util_memhdr *hdr,
- const void __user *buf, long count)
-{
- struct snd_emux *emu = private_data;
- return emu->ops.sample_new(emu, sp, hdr, buf, count);
-
-}
-
-static int sf_sample_free(void *private_data, struct snd_sf_sample *sp,
- struct snd_util_memhdr *hdr)
-{
- struct snd_emux *emu = private_data;
- return emu->ops.sample_free(emu, sp, hdr);
-
-}
-
-static void sf_sample_reset(void *private_data)
-{
- struct snd_emux *emu = private_data;
- emu->ops.sample_reset(emu);
-}
-
-int snd_emux_register(struct snd_emux *emu, struct snd_card *card, int index, char *name)
-{
- int err;
- struct snd_sf_callback sf_cb;
-
- if (snd_BUG_ON(!emu->hw || emu->max_voices <= 0))
- return -EINVAL;
- if (snd_BUG_ON(!card || !name))
- return -EINVAL;
-
- emu->card = card;
- emu->name = kstrdup(name, GFP_KERNEL);
- emu->voices = kcalloc(emu->max_voices, sizeof(struct snd_emux_voice),
- GFP_KERNEL);
- if (emu->voices == NULL)
- return -ENOMEM;
-
- /* create soundfont list */
- memset(&sf_cb, 0, sizeof(sf_cb));
- sf_cb.private_data = emu;
- if (emu->ops.sample_new)
- sf_cb.sample_new = sf_sample_new;
- if (emu->ops.sample_free)
- sf_cb.sample_free = sf_sample_free;
- if (emu->ops.sample_reset)
- sf_cb.sample_reset = sf_sample_reset;
- emu->sflist = snd_sf_new(&sf_cb, emu->memhdr);
- if (emu->sflist == NULL)
- return -ENOMEM;
-
- if ((err = snd_emux_init_hwdep(emu)) < 0)
- return err;
-
- snd_emux_init_voices(emu);
-
- snd_emux_init_seq(emu, card, index);
-#ifdef CONFIG_SND_SEQUENCER_OSS
- snd_emux_init_seq_oss(emu);
-#endif
- snd_emux_init_virmidi(emu, card);
-
-#ifdef CONFIG_PROC_FS
- snd_emux_proc_init(emu, card, index);
-#endif
- return 0;
-}
-
-EXPORT_SYMBOL(snd_emux_register);
-
-/*
- */
-int snd_emux_free(struct snd_emux *emu)
-{
- unsigned long flags;
-
- if (! emu)
- return -EINVAL;
-
- spin_lock_irqsave(&emu->voice_lock, flags);
- if (emu->timer_active)
- del_timer(&emu->tlist);
- spin_unlock_irqrestore(&emu->voice_lock, flags);
-
-#ifdef CONFIG_PROC_FS
- snd_emux_proc_free(emu);
-#endif
- snd_emux_delete_virmidi(emu);
-#ifdef CONFIG_SND_SEQUENCER_OSS
- snd_emux_detach_seq_oss(emu);
-#endif
- snd_emux_detach_seq(emu);
-
- snd_emux_delete_hwdep(emu);
-
- if (emu->sflist)
- snd_sf_free(emu->sflist);
-
- kfree(emu->voices);
- kfree(emu->name);
- kfree(emu);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_emux_free);
-
-
-/*
- * INIT part
- */
-
-static int __init alsa_emux_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_emux_exit(void)
-{
-}
-
-module_init(alsa_emux_init)
-module_exit(alsa_emux_exit)
diff --git a/ANDROID_3.4.5/sound/synth/emux/emux_effect.c b/ANDROID_3.4.5/sound/synth/emux/emux_effect.c
deleted file mode 100644
index a447218b..00000000
--- a/ANDROID_3.4.5/sound/synth/emux/emux_effect.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Midi synth routines for the Emu8k/Emu10k1
- *
- * Copyright (C) 1999 Steve Ratcliffe
- * Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de>
- *
- * Contains code based on awe_wave.c by Takashi Iwai
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "emux_voice.h"
-#include <linux/slab.h>
-
-#ifdef SNDRV_EMUX_USE_RAW_EFFECT
-/*
- * effects table
- */
-
-#define xoffsetof(type,tag) ((long)(&((type)NULL)->tag) - (long)(NULL))
-
-#define parm_offset(tag) xoffsetof(struct soundfont_voice_parm *, tag)
-
-#define PARM_IS_BYTE (1 << 0)
-#define PARM_IS_WORD (1 << 1)
-#define PARM_IS_ALIGNED (3 << 2)
-#define PARM_IS_ALIGN_HI (1 << 2)
-#define PARM_IS_ALIGN_LO (2 << 2)
-#define PARM_IS_SIGNED (1 << 4)
-
-#define PARM_WORD (PARM_IS_WORD)
-#define PARM_BYTE_LO (PARM_IS_BYTE|PARM_IS_ALIGN_LO)
-#define PARM_BYTE_HI (PARM_IS_BYTE|PARM_IS_ALIGN_HI)
-#define PARM_BYTE (PARM_IS_BYTE)
-#define PARM_SIGN_LO (PARM_IS_BYTE|PARM_IS_ALIGN_LO|PARM_IS_SIGNED)
-#define PARM_SIGN_HI (PARM_IS_BYTE|PARM_IS_ALIGN_HI|PARM_IS_SIGNED)
-
-static struct emux_parm_defs {
- int type; /* byte or word */
- int low, high; /* value range */
- long offset; /* offset in parameter record (-1 = not written) */
- int update; /* flgas for real-time update */
-} parm_defs[EMUX_NUM_EFFECTS] = {
- {PARM_WORD, 0, 0x8000, parm_offset(moddelay), 0}, /* env1 delay */
- {PARM_BYTE_LO, 1, 0x80, parm_offset(modatkhld), 0}, /* env1 attack */
- {PARM_BYTE_HI, 0, 0x7e, parm_offset(modatkhld), 0}, /* env1 hold */
- {PARM_BYTE_LO, 1, 0x7f, parm_offset(moddcysus), 0}, /* env1 decay */
- {PARM_BYTE_LO, 1, 0x7f, parm_offset(modrelease), 0}, /* env1 release */
- {PARM_BYTE_HI, 0, 0x7f, parm_offset(moddcysus), 0}, /* env1 sustain */
- {PARM_BYTE_HI, 0, 0xff, parm_offset(pefe), 0}, /* env1 pitch */
- {PARM_BYTE_LO, 0, 0xff, parm_offset(pefe), 0}, /* env1 fc */
-
- {PARM_WORD, 0, 0x8000, parm_offset(voldelay), 0}, /* env2 delay */
- {PARM_BYTE_LO, 1, 0x80, parm_offset(volatkhld), 0}, /* env2 attack */
- {PARM_BYTE_HI, 0, 0x7e, parm_offset(volatkhld), 0}, /* env2 hold */
- {PARM_BYTE_LO, 1, 0x7f, parm_offset(voldcysus), 0}, /* env2 decay */
- {PARM_BYTE_LO, 1, 0x7f, parm_offset(volrelease), 0}, /* env2 release */
- {PARM_BYTE_HI, 0, 0x7f, parm_offset(voldcysus), 0}, /* env2 sustain */
-
- {PARM_WORD, 0, 0x8000, parm_offset(lfo1delay), 0}, /* lfo1 delay */
- {PARM_BYTE_LO, 0, 0xff, parm_offset(tremfrq), SNDRV_EMUX_UPDATE_TREMFREQ}, /* lfo1 freq */
- {PARM_SIGN_HI, -128, 127, parm_offset(tremfrq), SNDRV_EMUX_UPDATE_TREMFREQ}, /* lfo1 vol */
- {PARM_SIGN_HI, -128, 127, parm_offset(fmmod), SNDRV_EMUX_UPDATE_FMMOD}, /* lfo1 pitch */
- {PARM_BYTE_LO, 0, 0xff, parm_offset(fmmod), SNDRV_EMUX_UPDATE_FMMOD}, /* lfo1 cutoff */
-
- {PARM_WORD, 0, 0x8000, parm_offset(lfo2delay), 0}, /* lfo2 delay */
- {PARM_BYTE_LO, 0, 0xff, parm_offset(fm2frq2), SNDRV_EMUX_UPDATE_FM2FRQ2}, /* lfo2 freq */
- {PARM_SIGN_HI, -128, 127, parm_offset(fm2frq2), SNDRV_EMUX_UPDATE_FM2FRQ2}, /* lfo2 pitch */
-
- {PARM_WORD, 0, 0xffff, -1, SNDRV_EMUX_UPDATE_PITCH}, /* initial pitch */
- {PARM_BYTE, 0, 0xff, parm_offset(chorus), 0}, /* chorus */
- {PARM_BYTE, 0, 0xff, parm_offset(reverb), 0}, /* reverb */
- {PARM_BYTE, 0, 0xff, parm_offset(cutoff), SNDRV_EMUX_UPDATE_VOLUME}, /* cutoff */
- {PARM_BYTE, 0, 15, parm_offset(filterQ), SNDRV_EMUX_UPDATE_Q}, /* resonance */
-
- {PARM_WORD, 0, 0xffff, -1, 0}, /* sample start */
- {PARM_WORD, 0, 0xffff, -1, 0}, /* loop start */
- {PARM_WORD, 0, 0xffff, -1, 0}, /* loop end */
- {PARM_WORD, 0, 0xffff, -1, 0}, /* coarse sample start */
- {PARM_WORD, 0, 0xffff, -1, 0}, /* coarse loop start */
- {PARM_WORD, 0, 0xffff, -1, 0}, /* coarse loop end */
- {PARM_BYTE, 0, 0xff, -1, SNDRV_EMUX_UPDATE_VOLUME}, /* initial attenuation */
-};
-
-/* set byte effect value */
-static void
-effect_set_byte(unsigned char *valp, struct snd_midi_channel *chan, int type)
-{
- short effect;
- struct snd_emux_effect_table *fx = chan->private;
-
- effect = fx->val[type];
- if (fx->flag[type] == EMUX_FX_FLAG_ADD) {
- if (parm_defs[type].type & PARM_IS_SIGNED)
- effect += *(char*)valp;
- else
- effect += *valp;
- }
- if (effect < parm_defs[type].low)
- effect = parm_defs[type].low;
- else if (effect > parm_defs[type].high)
- effect = parm_defs[type].high;
- *valp = (unsigned char)effect;
-}
-
-/* set word effect value */
-static void
-effect_set_word(unsigned short *valp, struct snd_midi_channel *chan, int type)
-{
- int effect;
- struct snd_emux_effect_table *fx = chan->private;
-
- effect = *(unsigned short*)&fx->val[type];
- if (fx->flag[type] == EMUX_FX_FLAG_ADD)
- effect += *valp;
- if (effect < parm_defs[type].low)
- effect = parm_defs[type].low;
- else if (effect > parm_defs[type].high)
- effect = parm_defs[type].high;
- *valp = (unsigned short)effect;
-}
-
-/* address offset */
-static int
-effect_get_offset(struct snd_midi_channel *chan, int lo, int hi, int mode)
-{
- int addr = 0;
- struct snd_emux_effect_table *fx = chan->private;
-
- if (fx->flag[hi])
- addr = (short)fx->val[hi];
- addr = addr << 15;
- if (fx->flag[lo])
- addr += (short)fx->val[lo];
- if (!(mode & SNDRV_SFNT_SAMPLE_8BITS))
- addr /= 2;
- return addr;
-}
-
-#ifdef CONFIG_SND_SEQUENCER_OSS
-/* change effects - for OSS sequencer compatibility */
-void
-snd_emux_send_effect_oss(struct snd_emux_port *port,
- struct snd_midi_channel *chan, int type, int val)
-{
- int mode;
-
- if (type & 0x40)
- mode = EMUX_FX_FLAG_OFF;
- else if (type & 0x80)
- mode = EMUX_FX_FLAG_ADD;
- else
- mode = EMUX_FX_FLAG_SET;
- type &= 0x3f;
-
- snd_emux_send_effect(port, chan, type, val, mode);
-}
-#endif
-
-/* Modify the effect value.
- * if update is necessary, call emu8000_control
- */
-void
-snd_emux_send_effect(struct snd_emux_port *port, struct snd_midi_channel *chan,
- int type, int val, int mode)
-{
- int i;
- int offset;
- unsigned char *srcp, *origp;
- struct snd_emux *emu;
- struct snd_emux_effect_table *fx;
- unsigned long flags;
-
- emu = port->emu;
- fx = chan->private;
- if (emu == NULL || fx == NULL)
- return;
- if (type < 0 || type >= EMUX_NUM_EFFECTS)
- return;
-
- fx->val[type] = val;
- fx->flag[type] = mode;
-
- /* do we need to modify the register in realtime ? */
- if (! parm_defs[type].update || (offset = parm_defs[type].offset) < 0)
- return;
-
-#ifdef SNDRV_LITTLE_ENDIAN
- if (parm_defs[type].type & PARM_IS_ALIGN_HI)
- offset++;
-#else
- if (parm_defs[type].type & PARM_IS_ALIGN_LO)
- offset++;
-#endif
- /* modify the register values */
- spin_lock_irqsave(&emu->voice_lock, flags);
- for (i = 0; i < emu->max_voices; i++) {
- struct snd_emux_voice *vp = &emu->voices[i];
- if (!STATE_IS_PLAYING(vp->state) || vp->chan != chan)
- continue;
- srcp = (unsigned char*)&vp->reg.parm + offset;
- origp = (unsigned char*)&vp->zone->v.parm + offset;
- if (parm_defs[i].type & PARM_IS_BYTE) {
- *srcp = *origp;
- effect_set_byte(srcp, chan, type);
- } else {
- *(unsigned short*)srcp = *(unsigned short*)origp;
- effect_set_word((unsigned short*)srcp, chan, type);
- }
- }
- spin_unlock_irqrestore(&emu->voice_lock, flags);
-
- /* activate them */
- snd_emux_update_channel(port, chan, parm_defs[type].update);
-}
-
-
-/* copy wavetable registers to voice table */
-void
-snd_emux_setup_effect(struct snd_emux_voice *vp)
-{
- struct snd_midi_channel *chan = vp->chan;
- struct snd_emux_effect_table *fx;
- unsigned char *srcp;
- int i;
-
- if (! (fx = chan->private))
- return;
-
- /* modify the register values via effect table */
- for (i = 0; i < EMUX_FX_END; i++) {
- int offset;
- if (! fx->flag[i] || (offset = parm_defs[i].offset) < 0)
- continue;
-#ifdef SNDRV_LITTLE_ENDIAN
- if (parm_defs[i].type & PARM_IS_ALIGN_HI)
- offset++;
-#else
- if (parm_defs[i].type & PARM_IS_ALIGN_LO)
- offset++;
-#endif
- srcp = (unsigned char*)&vp->reg.parm + offset;
- if (parm_defs[i].type & PARM_IS_BYTE)
- effect_set_byte(srcp, chan, i);
- else
- effect_set_word((unsigned short*)srcp, chan, i);
- }
-
- /* correct sample and loop points */
- vp->reg.start += effect_get_offset(chan, EMUX_FX_SAMPLE_START,
- EMUX_FX_COARSE_SAMPLE_START,
- vp->reg.sample_mode);
-
- vp->reg.loopstart += effect_get_offset(chan, EMUX_FX_LOOP_START,
- EMUX_FX_COARSE_LOOP_START,
- vp->reg.sample_mode);
-
- vp->reg.loopend += effect_get_offset(chan, EMUX_FX_LOOP_END,
- EMUX_FX_COARSE_LOOP_END,
- vp->reg.sample_mode);
-}
-
-/*
- * effect table
- */
-void
-snd_emux_create_effect(struct snd_emux_port *p)
-{
- int i;
- p->effect = kcalloc(p->chset.max_channels,
- sizeof(struct snd_emux_effect_table), GFP_KERNEL);
- if (p->effect) {
- for (i = 0; i < p->chset.max_channels; i++)
- p->chset.channels[i].private = p->effect + i;
- } else {
- for (i = 0; i < p->chset.max_channels; i++)
- p->chset.channels[i].private = NULL;
- }
-}
-
-void
-snd_emux_delete_effect(struct snd_emux_port *p)
-{
- kfree(p->effect);
- p->effect = NULL;
-}
-
-void
-snd_emux_clear_effect(struct snd_emux_port *p)
-{
- if (p->effect) {
- memset(p->effect, 0, sizeof(struct snd_emux_effect_table) *
- p->chset.max_channels);
- }
-}
-
-#endif /* SNDRV_EMUX_USE_RAW_EFFECT */
diff --git a/ANDROID_3.4.5/sound/synth/emux/emux_hwdep.c b/ANDROID_3.4.5/sound/synth/emux/emux_hwdep.c
deleted file mode 100644
index 5ae1eae9..00000000
--- a/ANDROID_3.4.5/sound/synth/emux/emux_hwdep.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Interface for hwdep device
- *
- * Copyright (C) 2004 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <sound/core.h>
-#include <sound/hwdep.h>
-#include <asm/uaccess.h>
-#include "emux_voice.h"
-
-
-#define TMP_CLIENT_ID 0x1001
-
-/*
- * load patch
- */
-static int
-snd_emux_hwdep_load_patch(struct snd_emux *emu, void __user *arg)
-{
- int err;
- struct soundfont_patch_info patch;
-
- if (copy_from_user(&patch, arg, sizeof(patch)))
- return -EFAULT;
-
- if (patch.type >= SNDRV_SFNT_LOAD_INFO &&
- patch.type <= SNDRV_SFNT_PROBE_DATA) {
- err = snd_soundfont_load(emu->sflist, arg, patch.len + sizeof(patch), TMP_CLIENT_ID);
- if (err < 0)
- return err;
- } else {
- if (emu->ops.load_fx)
- return emu->ops.load_fx(emu, patch.type, patch.optarg, arg, patch.len + sizeof(patch));
- else
- return -EINVAL;
- }
- return 0;
-}
-
-/*
- * set misc mode
- */
-static int
-snd_emux_hwdep_misc_mode(struct snd_emux *emu, void __user *arg)
-{
- struct snd_emux_misc_mode info;
- int i;
-
- if (copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
- if (info.mode < 0 || info.mode >= EMUX_MD_END)
- return -EINVAL;
-
- if (info.port < 0) {
- for (i = 0; i < emu->num_ports; i++)
- emu->portptrs[i]->ctrls[info.mode] = info.value;
- } else {
- if (info.port < emu->num_ports)
- emu->portptrs[info.port]->ctrls[info.mode] = info.value;
- }
- return 0;
-}
-
-
-/*
- * ioctl
- */
-static int
-snd_emux_hwdep_ioctl(struct snd_hwdep * hw, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct snd_emux *emu = hw->private_data;
-
- switch (cmd) {
- case SNDRV_EMUX_IOCTL_VERSION:
- return put_user(SNDRV_EMUX_VERSION, (unsigned int __user *)arg);
- case SNDRV_EMUX_IOCTL_LOAD_PATCH:
- return snd_emux_hwdep_load_patch(emu, (void __user *)arg);
- case SNDRV_EMUX_IOCTL_RESET_SAMPLES:
- snd_soundfont_remove_samples(emu->sflist);
- break;
- case SNDRV_EMUX_IOCTL_REMOVE_LAST_SAMPLES:
- snd_soundfont_remove_unlocked(emu->sflist);
- break;
- case SNDRV_EMUX_IOCTL_MEM_AVAIL:
- if (emu->memhdr) {
- int size = snd_util_mem_avail(emu->memhdr);
- return put_user(size, (unsigned int __user *)arg);
- }
- break;
- case SNDRV_EMUX_IOCTL_MISC_MODE:
- return snd_emux_hwdep_misc_mode(emu, (void __user *)arg);
- }
-
- return 0;
-}
-
-
-/*
- * register hwdep device
- */
-
-int
-snd_emux_init_hwdep(struct snd_emux *emu)
-{
- struct snd_hwdep *hw;
- int err;
-
- if ((err = snd_hwdep_new(emu->card, SNDRV_EMUX_HWDEP_NAME, emu->hwdep_idx, &hw)) < 0)
- return err;
- emu->hwdep = hw;
- strcpy(hw->name, SNDRV_EMUX_HWDEP_NAME);
- hw->iface = SNDRV_HWDEP_IFACE_EMUX_WAVETABLE;
- hw->ops.ioctl = snd_emux_hwdep_ioctl;
- /* The ioctl parameter types are compatible between 32- and
- * 64-bit architectures, so use the same function. */
- hw->ops.ioctl_compat = snd_emux_hwdep_ioctl;
- hw->exclusive = 1;
- hw->private_data = emu;
- if ((err = snd_card_register(emu->card)) < 0)
- return err;
-
- return 0;
-}
-
-
-/*
- * unregister
- */
-void
-snd_emux_delete_hwdep(struct snd_emux *emu)
-{
- if (emu->hwdep) {
- snd_device_free(emu->card, emu->hwdep);
- emu->hwdep = NULL;
- }
-}
diff --git a/ANDROID_3.4.5/sound/synth/emux/emux_nrpn.c b/ANDROID_3.4.5/sound/synth/emux/emux_nrpn.c
deleted file mode 100644
index 00fc005e..00000000
--- a/ANDROID_3.4.5/sound/synth/emux/emux_nrpn.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * NRPN / SYSEX callbacks for Emu8k/Emu10k1
- *
- * Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "emux_voice.h"
-#include <sound/asoundef.h>
-
-/*
- * conversion from NRPN/control parameters to Emu8000 raw parameters
- */
-
-/* NRPN / CC -> Emu8000 parameter converter */
-struct nrpn_conv_table {
- int control;
- int effect;
- int (*convert)(int val);
-};
-
-/* effect sensitivity */
-
-#define FX_CUTOFF 0
-#define FX_RESONANCE 1
-#define FX_ATTACK 2
-#define FX_RELEASE 3
-#define FX_VIBRATE 4
-#define FX_VIBDEPTH 5
-#define FX_VIBDELAY 6
-#define FX_NUMS 7
-
-/*
- * convert NRPN/control values
- */
-
-static int send_converted_effect(struct nrpn_conv_table *table, int num_tables,
- struct snd_emux_port *port,
- struct snd_midi_channel *chan,
- int type, int val, int mode)
-{
- int i, cval;
- for (i = 0; i < num_tables; i++) {
- if (table[i].control == type) {
- cval = table[i].convert(val);
- snd_emux_send_effect(port, chan, table[i].effect,
- cval, mode);
- return 1;
- }
- }
- return 0;
-}
-
-#define DEF_FX_CUTOFF 170
-#define DEF_FX_RESONANCE 6
-#define DEF_FX_ATTACK 50
-#define DEF_FX_RELEASE 50
-#define DEF_FX_VIBRATE 30
-#define DEF_FX_VIBDEPTH 4
-#define DEF_FX_VIBDELAY 1500
-
-/* effect sensitivities for GS NRPN:
- * adjusted for chaos 8MB soundfonts
- */
-static int gs_sense[] =
-{
- DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
- DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
-};
-
-/* effect sensitivies for XG controls:
- * adjusted for chaos 8MB soundfonts
- */
-static int xg_sense[] =
-{
- DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
- DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
-};
-
-
-/*
- * AWE32 NRPN effects
- */
-
-static int fx_delay(int val);
-static int fx_attack(int val);
-static int fx_hold(int val);
-static int fx_decay(int val);
-static int fx_the_value(int val);
-static int fx_twice_value(int val);
-static int fx_conv_pitch(int val);
-static int fx_conv_Q(int val);
-
-/* function for each NRPN */ /* [range] units */
-#define fx_env1_delay fx_delay /* [0,5900] 4msec */
-#define fx_env1_attack fx_attack /* [0,5940] 1msec */
-#define fx_env1_hold fx_hold /* [0,8191] 1msec */
-#define fx_env1_decay fx_decay /* [0,5940] 4msec */
-#define fx_env1_release fx_decay /* [0,5940] 4msec */
-#define fx_env1_sustain fx_the_value /* [0,127] 0.75dB */
-#define fx_env1_pitch fx_the_value /* [-127,127] 9.375cents */
-#define fx_env1_cutoff fx_the_value /* [-127,127] 56.25cents */
-
-#define fx_env2_delay fx_delay /* [0,5900] 4msec */
-#define fx_env2_attack fx_attack /* [0,5940] 1msec */
-#define fx_env2_hold fx_hold /* [0,8191] 1msec */
-#define fx_env2_decay fx_decay /* [0,5940] 4msec */
-#define fx_env2_release fx_decay /* [0,5940] 4msec */
-#define fx_env2_sustain fx_the_value /* [0,127] 0.75dB */
-
-#define fx_lfo1_delay fx_delay /* [0,5900] 4msec */
-#define fx_lfo1_freq fx_twice_value /* [0,127] 84mHz */
-#define fx_lfo1_volume fx_twice_value /* [0,127] 0.1875dB */
-#define fx_lfo1_pitch fx_the_value /* [-127,127] 9.375cents */
-#define fx_lfo1_cutoff fx_twice_value /* [-64,63] 56.25cents */
-
-#define fx_lfo2_delay fx_delay /* [0,5900] 4msec */
-#define fx_lfo2_freq fx_twice_value /* [0,127] 84mHz */
-#define fx_lfo2_pitch fx_the_value /* [-127,127] 9.375cents */
-
-#define fx_init_pitch fx_conv_pitch /* [-8192,8192] cents */
-#define fx_chorus fx_the_value /* [0,255] -- */
-#define fx_reverb fx_the_value /* [0,255] -- */
-#define fx_cutoff fx_twice_value /* [0,127] 62Hz */
-#define fx_filterQ fx_conv_Q /* [0,127] -- */
-
-static int fx_delay(int val)
-{
- return (unsigned short)snd_sf_calc_parm_delay(val);
-}
-
-static int fx_attack(int val)
-{
- return (unsigned short)snd_sf_calc_parm_attack(val);
-}
-
-static int fx_hold(int val)
-{
- return (unsigned short)snd_sf_calc_parm_hold(val);
-}
-
-static int fx_decay(int val)
-{
- return (unsigned short)snd_sf_calc_parm_decay(val);
-}
-
-static int fx_the_value(int val)
-{
- return (unsigned short)(val & 0xff);
-}
-
-static int fx_twice_value(int val)
-{
- return (unsigned short)((val * 2) & 0xff);
-}
-
-static int fx_conv_pitch(int val)
-{
- return (short)(val * 4096 / 1200);
-}
-
-static int fx_conv_Q(int val)
-{
- return (unsigned short)((val / 8) & 0xff);
-}
-
-
-static struct nrpn_conv_table awe_effects[] =
-{
- { 0, EMUX_FX_LFO1_DELAY, fx_lfo1_delay},
- { 1, EMUX_FX_LFO1_FREQ, fx_lfo1_freq},
- { 2, EMUX_FX_LFO2_DELAY, fx_lfo2_delay},
- { 3, EMUX_FX_LFO2_FREQ, fx_lfo2_freq},
-
- { 4, EMUX_FX_ENV1_DELAY, fx_env1_delay},
- { 5, EMUX_FX_ENV1_ATTACK,fx_env1_attack},
- { 6, EMUX_FX_ENV1_HOLD, fx_env1_hold},
- { 7, EMUX_FX_ENV1_DECAY, fx_env1_decay},
- { 8, EMUX_FX_ENV1_SUSTAIN, fx_env1_sustain},
- { 9, EMUX_FX_ENV1_RELEASE, fx_env1_release},
-
- {10, EMUX_FX_ENV2_DELAY, fx_env2_delay},
- {11, EMUX_FX_ENV2_ATTACK, fx_env2_attack},
- {12, EMUX_FX_ENV2_HOLD, fx_env2_hold},
- {13, EMUX_FX_ENV2_DECAY, fx_env2_decay},
- {14, EMUX_FX_ENV2_SUSTAIN, fx_env2_sustain},
- {15, EMUX_FX_ENV2_RELEASE, fx_env2_release},
-
- {16, EMUX_FX_INIT_PITCH, fx_init_pitch},
- {17, EMUX_FX_LFO1_PITCH, fx_lfo1_pitch},
- {18, EMUX_FX_LFO2_PITCH, fx_lfo2_pitch},
- {19, EMUX_FX_ENV1_PITCH, fx_env1_pitch},
- {20, EMUX_FX_LFO1_VOLUME, fx_lfo1_volume},
- {21, EMUX_FX_CUTOFF, fx_cutoff},
- {22, EMUX_FX_FILTERQ, fx_filterQ},
- {23, EMUX_FX_LFO1_CUTOFF, fx_lfo1_cutoff},
- {24, EMUX_FX_ENV1_CUTOFF, fx_env1_cutoff},
- {25, EMUX_FX_CHORUS, fx_chorus},
- {26, EMUX_FX_REVERB, fx_reverb},
-};
-
-
-/*
- * GS(SC88) NRPN effects; still experimental
- */
-
-/* cutoff: quarter semitone step, max=255 */
-static int gs_cutoff(int val)
-{
- return (val - 64) * gs_sense[FX_CUTOFF] / 50;
-}
-
-/* resonance: 0 to 15(max) */
-static int gs_filterQ(int val)
-{
- return (val - 64) * gs_sense[FX_RESONANCE] / 50;
-}
-
-/* attack: */
-static int gs_attack(int val)
-{
- return -(val - 64) * gs_sense[FX_ATTACK] / 50;
-}
-
-/* decay: */
-static int gs_decay(int val)
-{
- return -(val - 64) * gs_sense[FX_RELEASE] / 50;
-}
-
-/* release: */
-static int gs_release(int val)
-{
- return -(val - 64) * gs_sense[FX_RELEASE] / 50;
-}
-
-/* vibrato freq: 0.042Hz step, max=255 */
-static int gs_vib_rate(int val)
-{
- return (val - 64) * gs_sense[FX_VIBRATE] / 50;
-}
-
-/* vibrato depth: max=127, 1 octave */
-static int gs_vib_depth(int val)
-{
- return (val - 64) * gs_sense[FX_VIBDEPTH] / 50;
-}
-
-/* vibrato delay: -0.725msec step */
-static int gs_vib_delay(int val)
-{
- return -(val - 64) * gs_sense[FX_VIBDELAY] / 50;
-}
-
-static struct nrpn_conv_table gs_effects[] =
-{
- {32, EMUX_FX_CUTOFF, gs_cutoff},
- {33, EMUX_FX_FILTERQ, gs_filterQ},
- {99, EMUX_FX_ENV2_ATTACK, gs_attack},
- {100, EMUX_FX_ENV2_DECAY, gs_decay},
- {102, EMUX_FX_ENV2_RELEASE, gs_release},
- {8, EMUX_FX_LFO1_FREQ, gs_vib_rate},
- {9, EMUX_FX_LFO1_VOLUME, gs_vib_depth},
- {10, EMUX_FX_LFO1_DELAY, gs_vib_delay},
-};
-
-
-/*
- * NRPN events
- */
-void
-snd_emux_nrpn(void *p, struct snd_midi_channel *chan,
- struct snd_midi_channel_set *chset)
-{
- struct snd_emux_port *port;
-
- port = p;
- if (snd_BUG_ON(!port || !chan))
- return;
-
- if (chan->control[MIDI_CTL_NONREG_PARM_NUM_MSB] == 127 &&
- chan->control[MIDI_CTL_NONREG_PARM_NUM_LSB] <= 26) {
- int val;
- /* Win/DOS AWE32 specific NRPNs */
- /* both MSB/LSB necessary */
- val = (chan->control[MIDI_CTL_MSB_DATA_ENTRY] << 7) |
- chan->control[MIDI_CTL_LSB_DATA_ENTRY];
- val -= 8192;
- send_converted_effect
- (awe_effects, ARRAY_SIZE(awe_effects),
- port, chan, chan->control[MIDI_CTL_NONREG_PARM_NUM_LSB],
- val, EMUX_FX_FLAG_SET);
- return;
- }
-
- if (port->chset.midi_mode == SNDRV_MIDI_MODE_GS &&
- chan->control[MIDI_CTL_NONREG_PARM_NUM_MSB] == 1) {
- int val;
- /* GS specific NRPNs */
- /* only MSB is valid */
- val = chan->control[MIDI_CTL_MSB_DATA_ENTRY];
- send_converted_effect
- (gs_effects, ARRAY_SIZE(gs_effects),
- port, chan, chan->control[MIDI_CTL_NONREG_PARM_NUM_LSB],
- val, EMUX_FX_FLAG_ADD);
- return;
- }
-}
-
-
-/*
- * XG control effects; still experimental
- */
-
-/* cutoff: quarter semitone step, max=255 */
-static int xg_cutoff(int val)
-{
- return (val - 64) * xg_sense[FX_CUTOFF] / 64;
-}
-
-/* resonance: 0(open) to 15(most nasal) */
-static int xg_filterQ(int val)
-{
- return (val - 64) * xg_sense[FX_RESONANCE] / 64;
-}
-
-/* attack: */
-static int xg_attack(int val)
-{
- return -(val - 64) * xg_sense[FX_ATTACK] / 64;
-}
-
-/* release: */
-static int xg_release(int val)
-{
- return -(val - 64) * xg_sense[FX_RELEASE] / 64;
-}
-
-static struct nrpn_conv_table xg_effects[] =
-{
- {71, EMUX_FX_CUTOFF, xg_cutoff},
- {74, EMUX_FX_FILTERQ, xg_filterQ},
- {72, EMUX_FX_ENV2_RELEASE, xg_release},
- {73, EMUX_FX_ENV2_ATTACK, xg_attack},
-};
-
-int
-snd_emux_xg_control(struct snd_emux_port *port, struct snd_midi_channel *chan,
- int param)
-{
- return send_converted_effect(xg_effects, ARRAY_SIZE(xg_effects),
- port, chan, param,
- chan->control[param],
- EMUX_FX_FLAG_ADD);
-}
-
-/*
- * receive sysex
- */
-void
-snd_emux_sysex(void *p, unsigned char *buf, int len, int parsed,
- struct snd_midi_channel_set *chset)
-{
- struct snd_emux_port *port;
- struct snd_emux *emu;
-
- port = p;
- if (snd_BUG_ON(!port || !chset))
- return;
- emu = port->emu;
-
- switch (parsed) {
- case SNDRV_MIDI_SYSEX_GS_MASTER_VOLUME:
- snd_emux_update_port(port, SNDRV_EMUX_UPDATE_VOLUME);
- break;
- default:
- if (emu->ops.sysex)
- emu->ops.sysex(emu, buf, len, parsed, chset);
- break;
- }
-}
-
diff --git a/ANDROID_3.4.5/sound/synth/emux/emux_oss.c b/ANDROID_3.4.5/sound/synth/emux/emux_oss.c
deleted file mode 100644
index 319754cf..00000000
--- a/ANDROID_3.4.5/sound/synth/emux/emux_oss.c
+++ /dev/null
@@ -1,517 +0,0 @@
-/*
- * Interface for OSS sequencer emulation
- *
- * Copyright (C) 1999 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Changes
- * 19990227 Steve Ratcliffe Made separate file and merged in latest
- * midi emulation.
- */
-
-
-#ifdef CONFIG_SND_SEQUENCER_OSS
-
-#include <linux/export.h>
-#include <asm/uaccess.h>
-#include <sound/core.h>
-#include "emux_voice.h"
-#include <sound/asoundef.h>
-
-static int snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure);
-static int snd_emux_close_seq_oss(struct snd_seq_oss_arg *arg);
-static int snd_emux_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd,
- unsigned long ioarg);
-static int snd_emux_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format,
- const char __user *buf, int offs, int count);
-static int snd_emux_reset_seq_oss(struct snd_seq_oss_arg *arg);
-static int snd_emux_event_oss_input(struct snd_seq_event *ev, int direct,
- void *private, int atomic, int hop);
-static void reset_port_mode(struct snd_emux_port *port, int midi_mode);
-static void emuspec_control(struct snd_emux *emu, struct snd_emux_port *port,
- int cmd, unsigned char *event, int atomic, int hop);
-static void gusspec_control(struct snd_emux *emu, struct snd_emux_port *port,
- int cmd, unsigned char *event, int atomic, int hop);
-static void fake_event(struct snd_emux *emu, struct snd_emux_port *port,
- int ch, int param, int val, int atomic, int hop);
-
-/* operators */
-static struct snd_seq_oss_callback oss_callback = {
- .owner = THIS_MODULE,
- .open = snd_emux_open_seq_oss,
- .close = snd_emux_close_seq_oss,
- .ioctl = snd_emux_ioctl_seq_oss,
- .load_patch = snd_emux_load_patch_seq_oss,
- .reset = snd_emux_reset_seq_oss,
-};
-
-
-/*
- * register OSS synth
- */
-
-void
-snd_emux_init_seq_oss(struct snd_emux *emu)
-{
- struct snd_seq_oss_reg *arg;
- struct snd_seq_device *dev;
-
- if (snd_seq_device_new(emu->card, 0, SNDRV_SEQ_DEV_ID_OSS,
- sizeof(struct snd_seq_oss_reg), &dev) < 0)
- return;
-
- emu->oss_synth = dev;
- strcpy(dev->name, emu->name);
- arg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
- arg->type = SYNTH_TYPE_SAMPLE;
- arg->subtype = SAMPLE_TYPE_AWE32;
- arg->nvoices = emu->max_voices;
- arg->oper = oss_callback;
- arg->private_data = emu;
-
- /* register to OSS synth table */
- snd_device_register(emu->card, dev);
-}
-
-
-/*
- * unregister
- */
-void
-snd_emux_detach_seq_oss(struct snd_emux *emu)
-{
- if (emu->oss_synth) {
- snd_device_free(emu->card, emu->oss_synth);
- emu->oss_synth = NULL;
- }
-}
-
-
-/* use port number as a unique soundfont client number */
-#define SF_CLIENT_NO(p) ((p) + 0x1000)
-
-/*
- * open port for OSS sequencer
- */
-static int
-snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure)
-{
- struct snd_emux *emu;
- struct snd_emux_port *p;
- struct snd_seq_port_callback callback;
- char tmpname[64];
-
- emu = closure;
- if (snd_BUG_ON(!arg || !emu))
- return -ENXIO;
-
- mutex_lock(&emu->register_mutex);
-
- if (!snd_emux_inc_count(emu)) {
- mutex_unlock(&emu->register_mutex);
- return -EFAULT;
- }
-
- memset(&callback, 0, sizeof(callback));
- callback.owner = THIS_MODULE;
- callback.event_input = snd_emux_event_oss_input;
-
- sprintf(tmpname, "%s OSS Port", emu->name);
- p = snd_emux_create_port(emu, tmpname, 32,
- 1, &callback);
- if (p == NULL) {
- snd_printk(KERN_ERR "can't create port\n");
- snd_emux_dec_count(emu);
- mutex_unlock(&emu->register_mutex);
- return -ENOMEM;
- }
-
- /* fill the argument data */
- arg->private_data = p;
- arg->addr.client = p->chset.client;
- arg->addr.port = p->chset.port;
- p->oss_arg = arg;
-
- reset_port_mode(p, arg->seq_mode);
-
- snd_emux_reset_port(p);
-
- mutex_unlock(&emu->register_mutex);
- return 0;
-}
-
-
-#define DEFAULT_DRUM_FLAGS ((1<<9) | (1<<25))
-
-/*
- * reset port mode
- */
-static void
-reset_port_mode(struct snd_emux_port *port, int midi_mode)
-{
- if (midi_mode) {
- port->port_mode = SNDRV_EMUX_PORT_MODE_OSS_MIDI;
- port->drum_flags = DEFAULT_DRUM_FLAGS;
- port->volume_atten = 0;
- port->oss_arg->event_passing = SNDRV_SEQ_OSS_PROCESS_KEYPRESS;
- } else {
- port->port_mode = SNDRV_EMUX_PORT_MODE_OSS_SYNTH;
- port->drum_flags = 0;
- port->volume_atten = 32;
- port->oss_arg->event_passing = SNDRV_SEQ_OSS_PROCESS_EVENTS;
- }
-}
-
-
-/*
- * close port
- */
-static int
-snd_emux_close_seq_oss(struct snd_seq_oss_arg *arg)
-{
- struct snd_emux *emu;
- struct snd_emux_port *p;
-
- if (snd_BUG_ON(!arg))
- return -ENXIO;
- p = arg->private_data;
- if (snd_BUG_ON(!p))
- return -ENXIO;
-
- emu = p->emu;
- if (snd_BUG_ON(!emu))
- return -ENXIO;
-
- mutex_lock(&emu->register_mutex);
- snd_emux_sounds_off_all(p);
- snd_soundfont_close_check(emu->sflist, SF_CLIENT_NO(p->chset.port));
- snd_seq_event_port_detach(p->chset.client, p->chset.port);
- snd_emux_dec_count(emu);
-
- mutex_unlock(&emu->register_mutex);
- return 0;
-}
-
-
-/*
- * load patch
- */
-static int
-snd_emux_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format,
- const char __user *buf, int offs, int count)
-{
- struct snd_emux *emu;
- struct snd_emux_port *p;
- int rc;
-
- if (snd_BUG_ON(!arg))
- return -ENXIO;
- p = arg->private_data;
- if (snd_BUG_ON(!p))
- return -ENXIO;
-
- emu = p->emu;
- if (snd_BUG_ON(!emu))
- return -ENXIO;
-
- if (format == GUS_PATCH)
- rc = snd_soundfont_load_guspatch(emu->sflist, buf, count,
- SF_CLIENT_NO(p->chset.port));
- else if (format == SNDRV_OSS_SOUNDFONT_PATCH) {
- struct soundfont_patch_info patch;
- if (count < (int)sizeof(patch))
- rc = -EINVAL;
- if (copy_from_user(&patch, buf, sizeof(patch)))
- rc = -EFAULT;
- if (patch.type >= SNDRV_SFNT_LOAD_INFO &&
- patch.type <= SNDRV_SFNT_PROBE_DATA)
- rc = snd_soundfont_load(emu->sflist, buf, count, SF_CLIENT_NO(p->chset.port));
- else {
- if (emu->ops.load_fx)
- rc = emu->ops.load_fx(emu, patch.type, patch.optarg, buf, count);
- else
- rc = -EINVAL;
- }
- } else
- rc = 0;
- return rc;
-}
-
-
-/*
- * ioctl
- */
-static int
-snd_emux_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd, unsigned long ioarg)
-{
- struct snd_emux_port *p;
- struct snd_emux *emu;
-
- if (snd_BUG_ON(!arg))
- return -ENXIO;
- p = arg->private_data;
- if (snd_BUG_ON(!p))
- return -ENXIO;
-
- emu = p->emu;
- if (snd_BUG_ON(!emu))
- return -ENXIO;
-
- switch (cmd) {
- case SNDCTL_SEQ_RESETSAMPLES:
- snd_soundfont_remove_samples(emu->sflist);
- return 0;
-
- case SNDCTL_SYNTH_MEMAVL:
- if (emu->memhdr)
- return snd_util_mem_avail(emu->memhdr);
- return 0;
- }
-
- return 0;
-}
-
-
-/*
- * reset device
- */
-static int
-snd_emux_reset_seq_oss(struct snd_seq_oss_arg *arg)
-{
- struct snd_emux_port *p;
-
- if (snd_BUG_ON(!arg))
- return -ENXIO;
- p = arg->private_data;
- if (snd_BUG_ON(!p))
- return -ENXIO;
- snd_emux_reset_port(p);
- return 0;
-}
-
-
-/*
- * receive raw events: only SEQ_PRIVATE is accepted.
- */
-static int
-snd_emux_event_oss_input(struct snd_seq_event *ev, int direct, void *private_data,
- int atomic, int hop)
-{
- struct snd_emux *emu;
- struct snd_emux_port *p;
- unsigned char cmd, *data;
-
- p = private_data;
- if (snd_BUG_ON(!p))
- return -EINVAL;
- emu = p->emu;
- if (snd_BUG_ON(!emu))
- return -EINVAL;
- if (ev->type != SNDRV_SEQ_EVENT_OSS)
- return snd_emux_event_input(ev, direct, private_data, atomic, hop);
-
- data = ev->data.raw8.d;
- /* only SEQ_PRIVATE is accepted */
- if (data[0] != 0xfe)
- return 0;
- cmd = data[2] & _EMUX_OSS_MODE_VALUE_MASK;
- if (data[2] & _EMUX_OSS_MODE_FLAG)
- emuspec_control(emu, p, cmd, data, atomic, hop);
- else
- gusspec_control(emu, p, cmd, data, atomic, hop);
- return 0;
-}
-
-
-/*
- * OSS/AWE driver specific h/w controls
- */
-static void
-emuspec_control(struct snd_emux *emu, struct snd_emux_port *port, int cmd,
- unsigned char *event, int atomic, int hop)
-{
- int voice;
- unsigned short p1;
- short p2;
- int i;
- struct snd_midi_channel *chan;
-
- voice = event[3];
- if (voice < 0 || voice >= port->chset.max_channels)
- chan = NULL;
- else
- chan = &port->chset.channels[voice];
-
- p1 = *(unsigned short *) &event[4];
- p2 = *(short *) &event[6];
-
- switch (cmd) {
-#if 0 /* don't do this atomically */
- case _EMUX_OSS_REMOVE_LAST_SAMPLES:
- snd_soundfont_remove_unlocked(emu->sflist);
- break;
-#endif
- case _EMUX_OSS_SEND_EFFECT:
- if (chan)
- snd_emux_send_effect_oss(port, chan, p1, p2);
- break;
-
- case _EMUX_OSS_TERMINATE_ALL:
- snd_emux_terminate_all(emu);
- break;
-
- case _EMUX_OSS_TERMINATE_CHANNEL:
- /*snd_emux_mute_channel(emu, chan);*/
- break;
- case _EMUX_OSS_RESET_CHANNEL:
- /*snd_emux_channel_init(chset, chan);*/
- break;
-
- case _EMUX_OSS_RELEASE_ALL:
- fake_event(emu, port, voice, MIDI_CTL_ALL_NOTES_OFF, 0, atomic, hop);
- break;
- case _EMUX_OSS_NOTEOFF_ALL:
- fake_event(emu, port, voice, MIDI_CTL_ALL_SOUNDS_OFF, 0, atomic, hop);
- break;
-
- case _EMUX_OSS_INITIAL_VOLUME:
- if (p2) {
- port->volume_atten = (short)p1;
- snd_emux_update_port(port, SNDRV_EMUX_UPDATE_VOLUME);
- }
- break;
-
- case _EMUX_OSS_CHN_PRESSURE:
- if (chan) {
- chan->midi_pressure = p1;
- snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_FMMOD|SNDRV_EMUX_UPDATE_FM2FRQ2);
- }
- break;
-
- case _EMUX_OSS_CHANNEL_MODE:
- reset_port_mode(port, p1);
- snd_emux_reset_port(port);
- break;
-
- case _EMUX_OSS_DRUM_CHANNELS:
- port->drum_flags = *(unsigned int*)&event[4];
- for (i = 0; i < port->chset.max_channels; i++) {
- chan = &port->chset.channels[i];
- chan->drum_channel = ((port->drum_flags >> i) & 1) ? 1 : 0;
- }
- break;
-
- case _EMUX_OSS_MISC_MODE:
- if (p1 < EMUX_MD_END)
- port->ctrls[p1] = p2;
- break;
- case _EMUX_OSS_DEBUG_MODE:
- break;
-
- default:
- if (emu->ops.oss_ioctl)
- emu->ops.oss_ioctl(emu, cmd, p1, p2);
- break;
- }
-}
-
-/*
- * GUS specific h/w controls
- */
-
-#include <linux/ultrasound.h>
-
-static void
-gusspec_control(struct snd_emux *emu, struct snd_emux_port *port, int cmd,
- unsigned char *event, int atomic, int hop)
-{
- int voice;
- unsigned short p1;
- short p2;
- int plong;
- struct snd_midi_channel *chan;
-
- if (port->port_mode != SNDRV_EMUX_PORT_MODE_OSS_SYNTH)
- return;
- if (cmd == _GUS_NUMVOICES)
- return;
- voice = event[3];
- if (voice < 0 || voice >= port->chset.max_channels)
- return;
-
- chan = &port->chset.channels[voice];
-
- p1 = *(unsigned short *) &event[4];
- p2 = *(short *) &event[6];
- plong = *(int*) &event[4];
-
- switch (cmd) {
- case _GUS_VOICESAMPLE:
- chan->midi_program = p1;
- return;
-
- case _GUS_VOICEBALA:
- /* 0 to 15 --> 0 to 127 */
- chan->control[MIDI_CTL_MSB_PAN] = (int)p1 << 3;
- snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PAN);
- return;
-
- case _GUS_VOICEVOL:
- case _GUS_VOICEVOL2:
- /* not supported yet */
- return;
-
- case _GUS_RAMPRANGE:
- case _GUS_RAMPRATE:
- case _GUS_RAMPMODE:
- case _GUS_RAMPON:
- case _GUS_RAMPOFF:
- /* volume ramping not supported */
- return;
-
- case _GUS_VOLUME_SCALE:
- return;
-
- case _GUS_VOICE_POS:
-#ifdef SNDRV_EMUX_USE_RAW_EFFECT
- snd_emux_send_effect(port, chan, EMUX_FX_SAMPLE_START,
- (short)(plong & 0x7fff),
- EMUX_FX_FLAG_SET);
- snd_emux_send_effect(port, chan, EMUX_FX_COARSE_SAMPLE_START,
- (plong >> 15) & 0xffff,
- EMUX_FX_FLAG_SET);
-#endif
- return;
- }
-}
-
-
-/*
- * send an event to midi emulation
- */
-static void
-fake_event(struct snd_emux *emu, struct snd_emux_port *port, int ch, int param, int val, int atomic, int hop)
-{
- struct snd_seq_event ev;
- memset(&ev, 0, sizeof(ev));
- ev.type = SNDRV_SEQ_EVENT_CONTROLLER;
- ev.data.control.channel = ch;
- ev.data.control.param = param;
- ev.data.control.value = val;
- snd_emux_event_input(&ev, 0, port, atomic, hop);
-}
-
-#endif /* CONFIG_SND_SEQUENCER_OSS */
diff --git a/ANDROID_3.4.5/sound/synth/emux/emux_proc.c b/ANDROID_3.4.5/sound/synth/emux/emux_proc.c
deleted file mode 100644
index 58a32a10..00000000
--- a/ANDROID_3.4.5/sound/synth/emux/emux_proc.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
- *
- * Proc interface for Emu8k/Emu10k1 WaveTable synth
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/wait.h>
-#include <sound/core.h>
-#include <sound/emux_synth.h>
-#include <sound/info.h>
-#include "emux_voice.h"
-
-#ifdef CONFIG_PROC_FS
-
-static void
-snd_emux_proc_info_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buf)
-{
- struct snd_emux *emu;
- int i;
-
- emu = entry->private_data;
- mutex_lock(&emu->register_mutex);
- if (emu->name)
- snd_iprintf(buf, "Device: %s\n", emu->name);
- snd_iprintf(buf, "Ports: %d\n", emu->num_ports);
- snd_iprintf(buf, "Addresses:");
- for (i = 0; i < emu->num_ports; i++)
- snd_iprintf(buf, " %d:%d", emu->client, emu->ports[i]);
- snd_iprintf(buf, "\n");
- snd_iprintf(buf, "Use Counter: %d\n", emu->used);
- snd_iprintf(buf, "Max Voices: %d\n", emu->max_voices);
- snd_iprintf(buf, "Allocated Voices: %d\n", emu->num_voices);
- if (emu->memhdr) {
- snd_iprintf(buf, "Memory Size: %d\n", emu->memhdr->size);
- snd_iprintf(buf, "Memory Available: %d\n", snd_util_mem_avail(emu->memhdr));
- snd_iprintf(buf, "Allocated Blocks: %d\n", emu->memhdr->nblocks);
- } else {
- snd_iprintf(buf, "Memory Size: 0\n");
- }
- if (emu->sflist) {
- mutex_lock(&emu->sflist->presets_mutex);
- snd_iprintf(buf, "SoundFonts: %d\n", emu->sflist->fonts_size);
- snd_iprintf(buf, "Instruments: %d\n", emu->sflist->zone_counter);
- snd_iprintf(buf, "Samples: %d\n", emu->sflist->sample_counter);
- snd_iprintf(buf, "Locked Instruments: %d\n", emu->sflist->zone_locked);
- snd_iprintf(buf, "Locked Samples: %d\n", emu->sflist->sample_locked);
- mutex_unlock(&emu->sflist->presets_mutex);
- }
-#if 0 /* debug */
- if (emu->voices[0].state != SNDRV_EMUX_ST_OFF && emu->voices[0].ch >= 0) {
- struct snd_emux_voice *vp = &emu->voices[0];
- snd_iprintf(buf, "voice 0: on\n");
- snd_iprintf(buf, "mod delay=%x, atkhld=%x, dcysus=%x, rel=%x\n",
- vp->reg.parm.moddelay,
- vp->reg.parm.modatkhld,
- vp->reg.parm.moddcysus,
- vp->reg.parm.modrelease);
- snd_iprintf(buf, "vol delay=%x, atkhld=%x, dcysus=%x, rel=%x\n",
- vp->reg.parm.voldelay,
- vp->reg.parm.volatkhld,
- vp->reg.parm.voldcysus,
- vp->reg.parm.volrelease);
- snd_iprintf(buf, "lfo1 delay=%x, lfo2 delay=%x, pefe=%x\n",
- vp->reg.parm.lfo1delay,
- vp->reg.parm.lfo2delay,
- vp->reg.parm.pefe);
- snd_iprintf(buf, "fmmod=%x, tremfrq=%x, fm2frq2=%x\n",
- vp->reg.parm.fmmod,
- vp->reg.parm.tremfrq,
- vp->reg.parm.fm2frq2);
- snd_iprintf(buf, "cutoff=%x, filterQ=%x, chorus=%x, reverb=%x\n",
- vp->reg.parm.cutoff,
- vp->reg.parm.filterQ,
- vp->reg.parm.chorus,
- vp->reg.parm.reverb);
- snd_iprintf(buf, "avol=%x, acutoff=%x, apitch=%x\n",
- vp->avol, vp->acutoff, vp->apitch);
- snd_iprintf(buf, "apan=%x, aaux=%x, ptarget=%x, vtarget=%x, ftarget=%x\n",
- vp->apan, vp->aaux,
- vp->ptarget,
- vp->vtarget,
- vp->ftarget);
- snd_iprintf(buf, "start=%x, end=%x, loopstart=%x, loopend=%x\n",
- vp->reg.start, vp->reg.end, vp->reg.loopstart, vp->reg.loopend);
- snd_iprintf(buf, "sample_mode=%x, rate=%x\n", vp->reg.sample_mode, vp->reg.rate_offset);
- }
-#endif
- mutex_unlock(&emu->register_mutex);
-}
-
-
-void snd_emux_proc_init(struct snd_emux *emu, struct snd_card *card, int device)
-{
- struct snd_info_entry *entry;
- char name[64];
-
- sprintf(name, "wavetableD%d", device);
- entry = snd_info_create_card_entry(card, name, card->proc_root);
- if (entry == NULL)
- return;
-
- entry->content = SNDRV_INFO_CONTENT_TEXT;
- entry->private_data = emu;
- entry->c.text.read = snd_emux_proc_info_read;
- if (snd_info_register(entry) < 0)
- snd_info_free_entry(entry);
- else
- emu->proc = entry;
-}
-
-void snd_emux_proc_free(struct snd_emux *emu)
-{
- snd_info_free_entry(emu->proc);
- emu->proc = NULL;
-}
-
-#endif /* CONFIG_PROC_FS */
diff --git a/ANDROID_3.4.5/sound/synth/emux/emux_seq.c b/ANDROID_3.4.5/sound/synth/emux/emux_seq.c
deleted file mode 100644
index 7778b8e1..00000000
--- a/ANDROID_3.4.5/sound/synth/emux/emux_seq.c
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * Midi Sequencer interface routines.
- *
- * Copyright (C) 1999 Steve Ratcliffe
- * Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "emux_voice.h"
-#include <linux/slab.h>
-#include <linux/module.h>
-
-/* Prototypes for static functions */
-static void free_port(void *private);
-static void snd_emux_init_port(struct snd_emux_port *p);
-static int snd_emux_use(void *private_data, struct snd_seq_port_subscribe *info);
-static int snd_emux_unuse(void *private_data, struct snd_seq_port_subscribe *info);
-
-/*
- * MIDI emulation operators
- */
-static struct snd_midi_op emux_ops = {
- snd_emux_note_on,
- snd_emux_note_off,
- snd_emux_key_press,
- snd_emux_terminate_note,
- snd_emux_control,
- snd_emux_nrpn,
- snd_emux_sysex,
-};
-
-
-/*
- * number of MIDI channels
- */
-#define MIDI_CHANNELS 16
-
-/*
- * type flags for MIDI sequencer port
- */
-#define DEFAULT_MIDI_TYPE (SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |\
- SNDRV_SEQ_PORT_TYPE_MIDI_GM |\
- SNDRV_SEQ_PORT_TYPE_MIDI_GS |\
- SNDRV_SEQ_PORT_TYPE_MIDI_XG |\
- SNDRV_SEQ_PORT_TYPE_HARDWARE |\
- SNDRV_SEQ_PORT_TYPE_SYNTHESIZER)
-
-/*
- * Initialise the EMUX Synth by creating a client and registering
- * a series of ports.
- * Each of the ports will contain the 16 midi channels. Applications
- * can connect to these ports to play midi data.
- */
-int
-snd_emux_init_seq(struct snd_emux *emu, struct snd_card *card, int index)
-{
- int i;
- struct snd_seq_port_callback pinfo;
- char tmpname[64];
-
- emu->client = snd_seq_create_kernel_client(card, index,
- "%s WaveTable", emu->name);
- if (emu->client < 0) {
- snd_printk(KERN_ERR "can't create client\n");
- return -ENODEV;
- }
-
- if (emu->num_ports < 0) {
- snd_printk(KERN_WARNING "seqports must be greater than zero\n");
- emu->num_ports = 1;
- } else if (emu->num_ports >= SNDRV_EMUX_MAX_PORTS) {
- snd_printk(KERN_WARNING "too many ports."
- "limited max. ports %d\n", SNDRV_EMUX_MAX_PORTS);
- emu->num_ports = SNDRV_EMUX_MAX_PORTS;
- }
-
- memset(&pinfo, 0, sizeof(pinfo));
- pinfo.owner = THIS_MODULE;
- pinfo.use = snd_emux_use;
- pinfo.unuse = snd_emux_unuse;
- pinfo.event_input = snd_emux_event_input;
-
- for (i = 0; i < emu->num_ports; i++) {
- struct snd_emux_port *p;
-
- sprintf(tmpname, "%s Port %d", emu->name, i);
- p = snd_emux_create_port(emu, tmpname, MIDI_CHANNELS,
- 0, &pinfo);
- if (p == NULL) {
- snd_printk(KERN_ERR "can't create port\n");
- return -ENOMEM;
- }
-
- p->port_mode = SNDRV_EMUX_PORT_MODE_MIDI;
- snd_emux_init_port(p);
- emu->ports[i] = p->chset.port;
- emu->portptrs[i] = p;
- }
-
- return 0;
-}
-
-
-/*
- * Detach from the ports that were set up for this synthesizer and
- * destroy the kernel client.
- */
-void
-snd_emux_detach_seq(struct snd_emux *emu)
-{
- if (emu->voices)
- snd_emux_terminate_all(emu);
-
- mutex_lock(&emu->register_mutex);
- if (emu->client >= 0) {
- snd_seq_delete_kernel_client(emu->client);
- emu->client = -1;
- }
- mutex_unlock(&emu->register_mutex);
-}
-
-
-/*
- * create a sequencer port and channel_set
- */
-
-struct snd_emux_port *
-snd_emux_create_port(struct snd_emux *emu, char *name,
- int max_channels, int oss_port,
- struct snd_seq_port_callback *callback)
-{
- struct snd_emux_port *p;
- int i, type, cap;
-
- /* Allocate structures for this channel */
- if ((p = kzalloc(sizeof(*p), GFP_KERNEL)) == NULL) {
- snd_printk(KERN_ERR "no memory\n");
- return NULL;
- }
- p->chset.channels = kcalloc(max_channels, sizeof(struct snd_midi_channel), GFP_KERNEL);
- if (p->chset.channels == NULL) {
- snd_printk(KERN_ERR "no memory\n");
- kfree(p);
- return NULL;
- }
- for (i = 0; i < max_channels; i++)
- p->chset.channels[i].number = i;
- p->chset.private_data = p;
- p->chset.max_channels = max_channels;
- p->emu = emu;
- p->chset.client = emu->client;
-#ifdef SNDRV_EMUX_USE_RAW_EFFECT
- snd_emux_create_effect(p);
-#endif
- callback->private_free = free_port;
- callback->private_data = p;
-
- cap = SNDRV_SEQ_PORT_CAP_WRITE;
- if (oss_port) {
- type = SNDRV_SEQ_PORT_TYPE_SPECIFIC;
- } else {
- type = DEFAULT_MIDI_TYPE;
- cap |= SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
- }
-
- p->chset.port = snd_seq_event_port_attach(emu->client, callback,
- cap, type, max_channels,
- emu->max_voices, name);
-
- return p;
-}
-
-
-/*
- * release memory block for port
- */
-static void
-free_port(void *private_data)
-{
- struct snd_emux_port *p;
-
- p = private_data;
- if (p) {
-#ifdef SNDRV_EMUX_USE_RAW_EFFECT
- snd_emux_delete_effect(p);
-#endif
- kfree(p->chset.channels);
- kfree(p);
- }
-}
-
-
-#define DEFAULT_DRUM_FLAGS (1<<9)
-
-/*
- * initialize the port specific parameters
- */
-static void
-snd_emux_init_port(struct snd_emux_port *p)
-{
- p->drum_flags = DEFAULT_DRUM_FLAGS;
- p->volume_atten = 0;
-
- snd_emux_reset_port(p);
-}
-
-
-/*
- * reset port
- */
-void
-snd_emux_reset_port(struct snd_emux_port *port)
-{
- int i;
-
- /* stop all sounds */
- snd_emux_sounds_off_all(port);
-
- snd_midi_channel_set_clear(&port->chset);
-
-#ifdef SNDRV_EMUX_USE_RAW_EFFECT
- snd_emux_clear_effect(port);
-#endif
-
- /* set port specific control parameters */
- port->ctrls[EMUX_MD_DEF_BANK] = 0;
- port->ctrls[EMUX_MD_DEF_DRUM] = 0;
- port->ctrls[EMUX_MD_REALTIME_PAN] = 1;
-
- for (i = 0; i < port->chset.max_channels; i++) {
- struct snd_midi_channel *chan = port->chset.channels + i;
- chan->drum_channel = ((port->drum_flags >> i) & 1) ? 1 : 0;
- }
-}
-
-
-/*
- * input sequencer event
- */
-int
-snd_emux_event_input(struct snd_seq_event *ev, int direct, void *private_data,
- int atomic, int hop)
-{
- struct snd_emux_port *port;
-
- port = private_data;
- if (snd_BUG_ON(!port || !ev))
- return -EINVAL;
-
- snd_midi_process_event(&emux_ops, ev, &port->chset);
-
- return 0;
-}
-
-
-/*
- * increment usage count
- */
-int
-snd_emux_inc_count(struct snd_emux *emu)
-{
- emu->used++;
- if (!try_module_get(emu->ops.owner))
- goto __error;
- if (!try_module_get(emu->card->module)) {
- module_put(emu->ops.owner);
- __error:
- emu->used--;
- return 0;
- }
- return 1;
-}
-
-
-/*
- * decrease usage count
- */
-void
-snd_emux_dec_count(struct snd_emux *emu)
-{
- module_put(emu->card->module);
- emu->used--;
- if (emu->used <= 0)
- snd_emux_terminate_all(emu);
- module_put(emu->ops.owner);
-}
-
-
-/*
- * Routine that is called upon a first use of a particular port
- */
-static int
-snd_emux_use(void *private_data, struct snd_seq_port_subscribe *info)
-{
- struct snd_emux_port *p;
- struct snd_emux *emu;
-
- p = private_data;
- if (snd_BUG_ON(!p))
- return -EINVAL;
- emu = p->emu;
- if (snd_BUG_ON(!emu))
- return -EINVAL;
-
- mutex_lock(&emu->register_mutex);
- snd_emux_init_port(p);
- snd_emux_inc_count(emu);
- mutex_unlock(&emu->register_mutex);
- return 0;
-}
-
-/*
- * Routine that is called upon the last unuse() of a particular port.
- */
-static int
-snd_emux_unuse(void *private_data, struct snd_seq_port_subscribe *info)
-{
- struct snd_emux_port *p;
- struct snd_emux *emu;
-
- p = private_data;
- if (snd_BUG_ON(!p))
- return -EINVAL;
- emu = p->emu;
- if (snd_BUG_ON(!emu))
- return -EINVAL;
-
- mutex_lock(&emu->register_mutex);
- snd_emux_sounds_off_all(p);
- snd_emux_dec_count(emu);
- mutex_unlock(&emu->register_mutex);
- return 0;
-}
-
-
-/*
- * attach virtual rawmidi devices
- */
-int snd_emux_init_virmidi(struct snd_emux *emu, struct snd_card *card)
-{
- int i;
-
- emu->vmidi = NULL;
- if (emu->midi_ports <= 0)
- return 0;
-
- emu->vmidi = kcalloc(emu->midi_ports, sizeof(struct snd_rawmidi *), GFP_KERNEL);
- if (emu->vmidi == NULL)
- return -ENOMEM;
-
- for (i = 0; i < emu->midi_ports; i++) {
- struct snd_rawmidi *rmidi;
- struct snd_virmidi_dev *rdev;
- if (snd_virmidi_new(card, emu->midi_devidx + i, &rmidi) < 0)
- goto __error;
- rdev = rmidi->private_data;
- sprintf(rmidi->name, "%s Synth MIDI", emu->name);
- rdev->seq_mode = SNDRV_VIRMIDI_SEQ_ATTACH;
- rdev->client = emu->client;
- rdev->port = emu->ports[i];
- if (snd_device_register(card, rmidi) < 0) {
- snd_device_free(card, rmidi);
- goto __error;
- }
- emu->vmidi[i] = rmidi;
- /* snd_printk(KERN_DEBUG "virmidi %d ok\n", i); */
- }
- return 0;
-
-__error:
- /* snd_printk(KERN_DEBUG "error init..\n"); */
- snd_emux_delete_virmidi(emu);
- return -ENOMEM;
-}
-
-int snd_emux_delete_virmidi(struct snd_emux *emu)
-{
- int i;
-
- if (emu->vmidi == NULL)
- return 0;
-
- for (i = 0; i < emu->midi_ports; i++) {
- if (emu->vmidi[i])
- snd_device_free(emu->card, emu->vmidi[i]);
- }
- kfree(emu->vmidi);
- emu->vmidi = NULL;
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/synth/emux/emux_synth.c b/ANDROID_3.4.5/sound/synth/emux/emux_synth.c
deleted file mode 100644
index 9a38de45..00000000
--- a/ANDROID_3.4.5/sound/synth/emux/emux_synth.c
+++ /dev/null
@@ -1,984 +0,0 @@
-/*
- * Midi synth routines for the Emu8k/Emu10k1
- *
- * Copyright (C) 1999 Steve Ratcliffe
- * Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de>
- *
- * Contains code based on awe_wave.c by Takashi Iwai
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/export.h>
-#include "emux_voice.h"
-#include <sound/asoundef.h>
-
-/*
- * Prototypes
- */
-
-/*
- * Ensure a value is between two points
- * macro evaluates its args more than once, so changed to upper-case.
- */
-#define LIMITVALUE(x, a, b) do { if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b); } while (0)
-#define LIMITMAX(x, a) do {if ((x) > (a)) (x) = (a); } while (0)
-
-static int get_zone(struct snd_emux *emu, struct snd_emux_port *port,
- int *notep, int vel, struct snd_midi_channel *chan,
- struct snd_sf_zone **table);
-static int get_bank(struct snd_emux_port *port, struct snd_midi_channel *chan);
-static void terminate_note1(struct snd_emux *emu, int note,
- struct snd_midi_channel *chan, int free);
-static void exclusive_note_off(struct snd_emux *emu, struct snd_emux_port *port,
- int exclass);
-static void terminate_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int free);
-static void update_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int update);
-static void setup_voice(struct snd_emux_voice *vp);
-static int calc_pan(struct snd_emux_voice *vp);
-static int calc_volume(struct snd_emux_voice *vp);
-static int calc_pitch(struct snd_emux_voice *vp);
-
-
-/*
- * Start a note.
- */
-void
-snd_emux_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
-{
- struct snd_emux *emu;
- int i, key, nvoices;
- struct snd_emux_voice *vp;
- struct snd_sf_zone *table[SNDRV_EMUX_MAX_MULTI_VOICES];
- unsigned long flags;
- struct snd_emux_port *port;
-
- port = p;
- if (snd_BUG_ON(!port || !chan))
- return;
-
- emu = port->emu;
- if (snd_BUG_ON(!emu || !emu->ops.get_voice || !emu->ops.trigger))
- return;
-
- key = note; /* remember the original note */
- nvoices = get_zone(emu, port, &note, vel, chan, table);
- if (! nvoices)
- return;
-
- /* exclusive note off */
- for (i = 0; i < nvoices; i++) {
- struct snd_sf_zone *zp = table[i];
- if (zp && zp->v.exclusiveClass)
- exclusive_note_off(emu, port, zp->v.exclusiveClass);
- }
-
-#if 0 // seems not necessary
- /* Turn off the same note on the same channel. */
- terminate_note1(emu, key, chan, 0);
-#endif
-
- spin_lock_irqsave(&emu->voice_lock, flags);
- for (i = 0; i < nvoices; i++) {
-
- /* set up each voice parameter */
- /* at this stage, we don't trigger the voice yet. */
-
- if (table[i] == NULL)
- continue;
-
- vp = emu->ops.get_voice(emu, port);
- if (vp == NULL || vp->ch < 0)
- continue;
- if (STATE_IS_PLAYING(vp->state))
- emu->ops.terminate(vp);
-
- vp->time = emu->use_time++;
- vp->chan = chan;
- vp->port = port;
- vp->key = key;
- vp->note = note;
- vp->velocity = vel;
- vp->zone = table[i];
- if (vp->zone->sample)
- vp->block = vp->zone->sample->block;
- else
- vp->block = NULL;
-
- setup_voice(vp);
-
- vp->state = SNDRV_EMUX_ST_STANDBY;
- if (emu->ops.prepare) {
- vp->state = SNDRV_EMUX_ST_OFF;
- if (emu->ops.prepare(vp) >= 0)
- vp->state = SNDRV_EMUX_ST_STANDBY;
- }
- }
-
- /* start envelope now */
- for (i = 0; i < emu->max_voices; i++) {
- vp = &emu->voices[i];
- if (vp->state == SNDRV_EMUX_ST_STANDBY &&
- vp->chan == chan) {
- emu->ops.trigger(vp);
- vp->state = SNDRV_EMUX_ST_ON;
- vp->ontime = jiffies; /* remember the trigger timing */
- }
- }
- spin_unlock_irqrestore(&emu->voice_lock, flags);
-
-#ifdef SNDRV_EMUX_USE_RAW_EFFECT
- if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) {
- /* clear voice position for the next note on this channel */
- struct snd_emux_effect_table *fx = chan->private;
- if (fx) {
- fx->flag[EMUX_FX_SAMPLE_START] = 0;
- fx->flag[EMUX_FX_COARSE_SAMPLE_START] = 0;
- }
- }
-#endif
-}
-
-/*
- * Release a note in response to a midi note off.
- */
-void
-snd_emux_note_off(void *p, int note, int vel, struct snd_midi_channel *chan)
-{
- int ch;
- struct snd_emux *emu;
- struct snd_emux_voice *vp;
- unsigned long flags;
- struct snd_emux_port *port;
-
- port = p;
- if (snd_BUG_ON(!port || !chan))
- return;
-
- emu = port->emu;
- if (snd_BUG_ON(!emu || !emu->ops.release))
- return;
-
- spin_lock_irqsave(&emu->voice_lock, flags);
- for (ch = 0; ch < emu->max_voices; ch++) {
- vp = &emu->voices[ch];
- if (STATE_IS_PLAYING(vp->state) &&
- vp->chan == chan && vp->key == note) {
- vp->state = SNDRV_EMUX_ST_RELEASED;
- if (vp->ontime == jiffies) {
- /* if note-off is sent too shortly after
- * note-on, emuX engine cannot produce the sound
- * correctly. so we'll release this note
- * a bit later via timer callback.
- */
- vp->state = SNDRV_EMUX_ST_PENDING;
- if (! emu->timer_active) {
- emu->tlist.expires = jiffies + 1;
- add_timer(&emu->tlist);
- emu->timer_active = 1;
- }
- } else
- /* ok now release the note */
- emu->ops.release(vp);
- }
- }
- spin_unlock_irqrestore(&emu->voice_lock, flags);
-}
-
-/*
- * timer callback
- *
- * release the pending note-offs
- */
-void snd_emux_timer_callback(unsigned long data)
-{
- struct snd_emux *emu = (struct snd_emux *) data;
- struct snd_emux_voice *vp;
- unsigned long flags;
- int ch, do_again = 0;
-
- spin_lock_irqsave(&emu->voice_lock, flags);
- for (ch = 0; ch < emu->max_voices; ch++) {
- vp = &emu->voices[ch];
- if (vp->state == SNDRV_EMUX_ST_PENDING) {
- if (vp->ontime == jiffies)
- do_again++; /* release this at the next interrupt */
- else {
- emu->ops.release(vp);
- vp->state = SNDRV_EMUX_ST_RELEASED;
- }
- }
- }
- if (do_again) {
- emu->tlist.expires = jiffies + 1;
- add_timer(&emu->tlist);
- emu->timer_active = 1;
- } else
- emu->timer_active = 0;
- spin_unlock_irqrestore(&emu->voice_lock, flags);
-}
-
-/*
- * key pressure change
- */
-void
-snd_emux_key_press(void *p, int note, int vel, struct snd_midi_channel *chan)
-{
- int ch;
- struct snd_emux *emu;
- struct snd_emux_voice *vp;
- unsigned long flags;
- struct snd_emux_port *port;
-
- port = p;
- if (snd_BUG_ON(!port || !chan))
- return;
-
- emu = port->emu;
- if (snd_BUG_ON(!emu || !emu->ops.update))
- return;
-
- spin_lock_irqsave(&emu->voice_lock, flags);
- for (ch = 0; ch < emu->max_voices; ch++) {
- vp = &emu->voices[ch];
- if (vp->state == SNDRV_EMUX_ST_ON &&
- vp->chan == chan && vp->key == note) {
- vp->velocity = vel;
- update_voice(emu, vp, SNDRV_EMUX_UPDATE_VOLUME);
- }
- }
- spin_unlock_irqrestore(&emu->voice_lock, flags);
-}
-
-
-/*
- * Modulate the voices which belong to the channel
- */
-void
-snd_emux_update_channel(struct snd_emux_port *port, struct snd_midi_channel *chan, int update)
-{
- struct snd_emux *emu;
- struct snd_emux_voice *vp;
- int i;
- unsigned long flags;
-
- if (! update)
- return;
-
- emu = port->emu;
- if (snd_BUG_ON(!emu || !emu->ops.update))
- return;
-
- spin_lock_irqsave(&emu->voice_lock, flags);
- for (i = 0; i < emu->max_voices; i++) {
- vp = &emu->voices[i];
- if (vp->chan == chan)
- update_voice(emu, vp, update);
- }
- spin_unlock_irqrestore(&emu->voice_lock, flags);
-}
-
-/*
- * Modulate all the voices which belong to the port.
- */
-void
-snd_emux_update_port(struct snd_emux_port *port, int update)
-{
- struct snd_emux *emu;
- struct snd_emux_voice *vp;
- int i;
- unsigned long flags;
-
- if (! update)
- return;
-
- emu = port->emu;
- if (snd_BUG_ON(!emu || !emu->ops.update))
- return;
-
- spin_lock_irqsave(&emu->voice_lock, flags);
- for (i = 0; i < emu->max_voices; i++) {
- vp = &emu->voices[i];
- if (vp->port == port)
- update_voice(emu, vp, update);
- }
- spin_unlock_irqrestore(&emu->voice_lock, flags);
-}
-
-
-/*
- * Deal with a controller type event. This includes all types of
- * control events, not just the midi controllers
- */
-void
-snd_emux_control(void *p, int type, struct snd_midi_channel *chan)
-{
- struct snd_emux_port *port;
-
- port = p;
- if (snd_BUG_ON(!port || !chan))
- return;
-
- switch (type) {
- case MIDI_CTL_MSB_MAIN_VOLUME:
- case MIDI_CTL_MSB_EXPRESSION:
- snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_VOLUME);
- break;
-
- case MIDI_CTL_MSB_PAN:
- snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PAN);
- break;
-
- case MIDI_CTL_SOFT_PEDAL:
-#ifdef SNDRV_EMUX_USE_RAW_EFFECT
- /* FIXME: this is an emulation */
- if (chan->control[type] >= 64)
- snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, -160,
- EMUX_FX_FLAG_ADD);
- else
- snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, 0,
- EMUX_FX_FLAG_OFF);
-#endif
- break;
-
- case MIDI_CTL_PITCHBEND:
- snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PITCH);
- break;
-
- case MIDI_CTL_MSB_MODWHEEL:
- case MIDI_CTL_CHAN_PRESSURE:
- snd_emux_update_channel(port, chan,
- SNDRV_EMUX_UPDATE_FMMOD |
- SNDRV_EMUX_UPDATE_FM2FRQ2);
- break;
-
- }
-
- if (port->chset.midi_mode == SNDRV_MIDI_MODE_XG) {
- snd_emux_xg_control(port, chan, type);
- }
-}
-
-
-/*
- * terminate note - if free flag is true, free the terminated voice
- */
-static void
-terminate_note1(struct snd_emux *emu, int note, struct snd_midi_channel *chan, int free)
-{
- int i;
- struct snd_emux_voice *vp;
- unsigned long flags;
-
- spin_lock_irqsave(&emu->voice_lock, flags);
- for (i = 0; i < emu->max_voices; i++) {
- vp = &emu->voices[i];
- if (STATE_IS_PLAYING(vp->state) && vp->chan == chan &&
- vp->key == note)
- terminate_voice(emu, vp, free);
- }
- spin_unlock_irqrestore(&emu->voice_lock, flags);
-}
-
-
-/*
- * terminate note - exported for midi emulation
- */
-void
-snd_emux_terminate_note(void *p, int note, struct snd_midi_channel *chan)
-{
- struct snd_emux *emu;
- struct snd_emux_port *port;
-
- port = p;
- if (snd_BUG_ON(!port || !chan))
- return;
-
- emu = port->emu;
- if (snd_BUG_ON(!emu || !emu->ops.terminate))
- return;
-
- terminate_note1(emu, note, chan, 1);
-}
-
-
-/*
- * Terminate all the notes
- */
-void
-snd_emux_terminate_all(struct snd_emux *emu)
-{
- int i;
- struct snd_emux_voice *vp;
- unsigned long flags;
-
- spin_lock_irqsave(&emu->voice_lock, flags);
- for (i = 0; i < emu->max_voices; i++) {
- vp = &emu->voices[i];
- if (STATE_IS_PLAYING(vp->state))
- terminate_voice(emu, vp, 0);
- if (vp->state == SNDRV_EMUX_ST_OFF) {
- if (emu->ops.free_voice)
- emu->ops.free_voice(vp);
- if (emu->ops.reset)
- emu->ops.reset(emu, i);
- }
- vp->time = 0;
- }
- /* initialize allocation time */
- emu->use_time = 0;
- spin_unlock_irqrestore(&emu->voice_lock, flags);
-}
-
-EXPORT_SYMBOL(snd_emux_terminate_all);
-
-/*
- * Terminate all voices associated with the given port
- */
-void
-snd_emux_sounds_off_all(struct snd_emux_port *port)
-{
- int i;
- struct snd_emux *emu;
- struct snd_emux_voice *vp;
- unsigned long flags;
-
- if (snd_BUG_ON(!port))
- return;
- emu = port->emu;
- if (snd_BUG_ON(!emu || !emu->ops.terminate))
- return;
-
- spin_lock_irqsave(&emu->voice_lock, flags);
- for (i = 0; i < emu->max_voices; i++) {
- vp = &emu->voices[i];
- if (STATE_IS_PLAYING(vp->state) &&
- vp->port == port)
- terminate_voice(emu, vp, 0);
- if (vp->state == SNDRV_EMUX_ST_OFF) {
- if (emu->ops.free_voice)
- emu->ops.free_voice(vp);
- if (emu->ops.reset)
- emu->ops.reset(emu, i);
- }
- }
- spin_unlock_irqrestore(&emu->voice_lock, flags);
-}
-
-
-/*
- * Terminate all voices that have the same exclusive class. This
- * is mainly for drums.
- */
-static void
-exclusive_note_off(struct snd_emux *emu, struct snd_emux_port *port, int exclass)
-{
- struct snd_emux_voice *vp;
- int i;
- unsigned long flags;
-
- spin_lock_irqsave(&emu->voice_lock, flags);
- for (i = 0; i < emu->max_voices; i++) {
- vp = &emu->voices[i];
- if (STATE_IS_PLAYING(vp->state) && vp->port == port &&
- vp->reg.exclusiveClass == exclass) {
- terminate_voice(emu, vp, 0);
- }
- }
- spin_unlock_irqrestore(&emu->voice_lock, flags);
-}
-
-/*
- * terminate a voice
- * if free flag is true, call free_voice after termination
- */
-static void
-terminate_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int free)
-{
- emu->ops.terminate(vp);
- vp->time = emu->use_time++;
- vp->chan = NULL;
- vp->port = NULL;
- vp->zone = NULL;
- vp->block = NULL;
- vp->state = SNDRV_EMUX_ST_OFF;
- if (free && emu->ops.free_voice)
- emu->ops.free_voice(vp);
-}
-
-
-/*
- * Modulate the voice
- */
-static void
-update_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int update)
-{
- if (!STATE_IS_PLAYING(vp->state))
- return;
-
- if (vp->chan == NULL || vp->port == NULL)
- return;
- if (update & SNDRV_EMUX_UPDATE_VOLUME)
- calc_volume(vp);
- if (update & SNDRV_EMUX_UPDATE_PITCH)
- calc_pitch(vp);
- if (update & SNDRV_EMUX_UPDATE_PAN) {
- if (! calc_pan(vp) && (update == SNDRV_EMUX_UPDATE_PAN))
- return;
- }
- emu->ops.update(vp, update);
-}
-
-
-#if 0 // not used
-/* table for volume target calculation */
-static unsigned short voltarget[16] = {
- 0xEAC0, 0xE0C8, 0xD740, 0xCE20, 0xC560, 0xBD08, 0xB500, 0xAD58,
- 0xA5F8, 0x9EF0, 0x9830, 0x91C0, 0x8B90, 0x85A8, 0x8000, 0x7A90
-};
-#endif
-
-#define LO_BYTE(v) ((v) & 0xff)
-#define HI_BYTE(v) (((v) >> 8) & 0xff)
-
-/*
- * Sets up the voice structure by calculating some values that
- * will be needed later.
- */
-static void
-setup_voice(struct snd_emux_voice *vp)
-{
- struct soundfont_voice_parm *parm;
- int pitch;
-
- /* copy the original register values */
- vp->reg = vp->zone->v;
-
-#ifdef SNDRV_EMUX_USE_RAW_EFFECT
- snd_emux_setup_effect(vp);
-#endif
-
- /* reset status */
- vp->apan = -1;
- vp->avol = -1;
- vp->apitch = -1;
-
- calc_volume(vp);
- calc_pitch(vp);
- calc_pan(vp);
-
- parm = &vp->reg.parm;
-
- /* compute filter target and correct modulation parameters */
- if (LO_BYTE(parm->modatkhld) >= 0x80 && parm->moddelay >= 0x8000) {
- parm->moddelay = 0xbfff;
- pitch = (HI_BYTE(parm->pefe) << 4) + vp->apitch;
- if (pitch > 0xffff)
- pitch = 0xffff;
- /* calculate filter target */
- vp->ftarget = parm->cutoff + LO_BYTE(parm->pefe);
- LIMITVALUE(vp->ftarget, 0, 255);
- vp->ftarget <<= 8;
- } else {
- vp->ftarget = parm->cutoff;
- vp->ftarget <<= 8;
- pitch = vp->apitch;
- }
-
- /* compute pitch target */
- if (pitch != 0xffff) {
- vp->ptarget = 1 << (pitch >> 12);
- if (pitch & 0x800) vp->ptarget += (vp->ptarget*0x102e)/0x2710;
- if (pitch & 0x400) vp->ptarget += (vp->ptarget*0x764)/0x2710;
- if (pitch & 0x200) vp->ptarget += (vp->ptarget*0x389)/0x2710;
- vp->ptarget += (vp->ptarget >> 1);
- if (vp->ptarget > 0xffff) vp->ptarget = 0xffff;
- } else
- vp->ptarget = 0xffff;
-
- if (LO_BYTE(parm->modatkhld) >= 0x80) {
- parm->modatkhld &= ~0xff;
- parm->modatkhld |= 0x7f;
- }
-
- /* compute volume target and correct volume parameters */
- vp->vtarget = 0;
-#if 0 /* FIXME: this leads to some clicks.. */
- if (LO_BYTE(parm->volatkhld) >= 0x80 && parm->voldelay >= 0x8000) {
- parm->voldelay = 0xbfff;
- vp->vtarget = voltarget[vp->avol % 0x10] >> (vp->avol >> 4);
- }
-#endif
-
- if (LO_BYTE(parm->volatkhld) >= 0x80) {
- parm->volatkhld &= ~0xff;
- parm->volatkhld |= 0x7f;
- }
-}
-
-/*
- * calculate pitch parameter
- */
-static unsigned char pan_volumes[256] = {
-0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x14,0x17,0x1a,0x1d,0x20,0x22,0x25,0x28,0x2a,
-0x2d,0x30,0x32,0x35,0x37,0x3a,0x3c,0x3f,0x41,0x44,0x46,0x49,0x4b,0x4d,0x50,0x52,
-0x54,0x57,0x59,0x5b,0x5d,0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6f,0x71,0x73,0x75,
-0x77,0x79,0x7b,0x7c,0x7e,0x80,0x82,0x84,0x86,0x88,0x89,0x8b,0x8d,0x8f,0x90,0x92,
-0x94,0x96,0x97,0x99,0x9a,0x9c,0x9e,0x9f,0xa1,0xa2,0xa4,0xa5,0xa7,0xa8,0xaa,0xab,
-0xad,0xae,0xaf,0xb1,0xb2,0xb3,0xb5,0xb6,0xb7,0xb9,0xba,0xbb,0xbc,0xbe,0xbf,0xc0,
-0xc1,0xc2,0xc3,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,
-0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdc,0xdd,0xde,0xdf,
-0xdf,0xe0,0xe1,0xe2,0xe2,0xe3,0xe4,0xe4,0xe5,0xe6,0xe6,0xe7,0xe8,0xe8,0xe9,0xe9,
-0xea,0xeb,0xeb,0xec,0xec,0xed,0xed,0xee,0xee,0xef,0xef,0xf0,0xf0,0xf1,0xf1,0xf1,
-0xf2,0xf2,0xf3,0xf3,0xf3,0xf4,0xf4,0xf5,0xf5,0xf5,0xf6,0xf6,0xf6,0xf7,0xf7,0xf7,
-0xf7,0xf8,0xf8,0xf8,0xf9,0xf9,0xf9,0xf9,0xf9,0xfa,0xfa,0xfa,0xfa,0xfb,0xfb,0xfb,
-0xfb,0xfb,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,
-0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-};
-
-static int
-calc_pan(struct snd_emux_voice *vp)
-{
- struct snd_midi_channel *chan = vp->chan;
- int pan;
-
- /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
- if (vp->reg.fixpan > 0) /* 0-127 */
- pan = 255 - (int)vp->reg.fixpan * 2;
- else {
- pan = chan->control[MIDI_CTL_MSB_PAN] - 64;
- if (vp->reg.pan >= 0) /* 0-127 */
- pan += vp->reg.pan - 64;
- pan = 127 - (int)pan * 2;
- }
- LIMITVALUE(pan, 0, 255);
-
- if (vp->emu->linear_panning) {
- /* assuming linear volume */
- if (pan != vp->apan) {
- vp->apan = pan;
- if (pan == 0)
- vp->aaux = 0xff;
- else
- vp->aaux = (-pan) & 0xff;
- return 1;
- } else
- return 0;
- } else {
- /* using volume table */
- if (vp->apan != (int)pan_volumes[pan]) {
- vp->apan = pan_volumes[pan];
- vp->aaux = pan_volumes[255 - pan];
- return 1;
- }
- return 0;
- }
-}
-
-
-/*
- * calculate volume attenuation
- *
- * Voice volume is controlled by volume attenuation parameter.
- * So volume becomes maximum when avol is 0 (no attenuation), and
- * minimum when 255 (-96dB or silence).
- */
-
-/* tables for volume->attenuation calculation */
-static unsigned char voltab1[128] = {
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22,
- 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a,
- 0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14,
- 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10,
- 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d,
- 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static unsigned char voltab2[128] = {
- 0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a,
- 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21,
- 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a,
- 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15,
- 0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10,
- 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d,
- 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static unsigned char expressiontab[128] = {
- 0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42,
- 0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30,
- 0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25,
- 0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e,
- 0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18,
- 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13,
- 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f,
- 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c,
- 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09,
- 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
- 0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
- 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/*
- * Magic to calculate the volume (actually attenuation) from all the
- * voice and channels parameters.
- */
-static int
-calc_volume(struct snd_emux_voice *vp)
-{
- int vol;
- int main_vol, expression_vol, master_vol;
- struct snd_midi_channel *chan = vp->chan;
- struct snd_emux_port *port = vp->port;
-
- expression_vol = chan->control[MIDI_CTL_MSB_EXPRESSION];
- LIMITMAX(vp->velocity, 127);
- LIMITVALUE(expression_vol, 0, 127);
- if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) {
- /* 0 - 127 */
- main_vol = chan->control[MIDI_CTL_MSB_MAIN_VOLUME];
- vol = (vp->velocity * main_vol * expression_vol) / (127*127);
- vol = vol * vp->reg.amplitude / 127;
-
- LIMITVALUE(vol, 0, 127);
-
- /* calc to attenuation */
- vol = snd_sf_vol_table[vol];
-
- } else {
- main_vol = chan->control[MIDI_CTL_MSB_MAIN_VOLUME] * vp->reg.amplitude / 127;
- LIMITVALUE(main_vol, 0, 127);
-
- vol = voltab1[main_vol] + voltab2[vp->velocity];
- vol = (vol * 8) / 3;
- vol += vp->reg.attenuation;
- vol += ((0x100 - vol) * expressiontab[expression_vol])/128;
- }
-
- master_vol = port->chset.gs_master_volume;
- LIMITVALUE(master_vol, 0, 127);
- vol += snd_sf_vol_table[master_vol];
- vol += port->volume_atten;
-
-#ifdef SNDRV_EMUX_USE_RAW_EFFECT
- if (chan->private) {
- struct snd_emux_effect_table *fx = chan->private;
- vol += fx->val[EMUX_FX_ATTEN];
- }
-#endif
-
- LIMITVALUE(vol, 0, 255);
- if (vp->avol == vol)
- return 0; /* value unchanged */
-
- vp->avol = vol;
- if (!SF_IS_DRUM_BANK(get_bank(port, chan))
- && LO_BYTE(vp->reg.parm.volatkhld) < 0x7d) {
- int atten;
- if (vp->velocity < 70)
- atten = 70;
- else
- atten = vp->velocity;
- vp->acutoff = (atten * vp->reg.parm.cutoff + 0xa0) >> 7;
- } else {
- vp->acutoff = vp->reg.parm.cutoff;
- }
-
- return 1; /* value changed */
-}
-
-/*
- * calculate pitch offset
- *
- * 0xE000 is no pitch offset at 44100Hz sample.
- * Every 4096 is one octave.
- */
-
-static int
-calc_pitch(struct snd_emux_voice *vp)
-{
- struct snd_midi_channel *chan = vp->chan;
- int offset;
-
- /* calculate offset */
- if (vp->reg.fixkey >= 0) {
- offset = (vp->reg.fixkey - vp->reg.root) * 4096 / 12;
- } else {
- offset = (vp->note - vp->reg.root) * 4096 / 12;
- }
- offset = (offset * vp->reg.scaleTuning) / 100;
- offset += vp->reg.tune * 4096 / 1200;
- if (chan->midi_pitchbend != 0) {
- /* (128 * 8192: 1 semitone) ==> (4096: 12 semitones) */
- offset += chan->midi_pitchbend * chan->gm_rpn_pitch_bend_range / 3072;
- }
-
- /* tuning via RPN:
- * coarse = -8192 to 8192 (100 cent per 128)
- * fine = -8192 to 8192 (max=100cent)
- */
- /* 4096 = 1200 cents in emu8000 parameter */
- offset += chan->gm_rpn_coarse_tuning * 4096 / (12 * 128);
- offset += chan->gm_rpn_fine_tuning / 24;
-
-#ifdef SNDRV_EMUX_USE_RAW_EFFECT
- /* add initial pitch correction */
- if (chan->private) {
- struct snd_emux_effect_table *fx = chan->private;
- if (fx->flag[EMUX_FX_INIT_PITCH])
- offset += fx->val[EMUX_FX_INIT_PITCH];
- }
-#endif
-
- /* 0xe000: root pitch */
- offset += 0xe000 + vp->reg.rate_offset;
- offset += vp->emu->pitch_shift;
- LIMITVALUE(offset, 0, 0xffff);
- if (offset == vp->apitch)
- return 0; /* unchanged */
- vp->apitch = offset;
- return 1; /* value changed */
-}
-
-/*
- * Get the bank number assigned to the channel
- */
-static int
-get_bank(struct snd_emux_port *port, struct snd_midi_channel *chan)
-{
- int val;
-
- switch (port->chset.midi_mode) {
- case SNDRV_MIDI_MODE_XG:
- val = chan->control[MIDI_CTL_MSB_BANK];
- if (val == 127)
- return 128; /* return drum bank */
- return chan->control[MIDI_CTL_LSB_BANK];
-
- case SNDRV_MIDI_MODE_GS:
- if (chan->drum_channel)
- return 128;
- /* ignore LSB (bank map) */
- return chan->control[MIDI_CTL_MSB_BANK];
-
- default:
- if (chan->drum_channel)
- return 128;
- return chan->control[MIDI_CTL_MSB_BANK];
- }
-}
-
-
-/* Look for the zones matching with the given note and velocity.
- * The resultant zones are stored on table.
- */
-static int
-get_zone(struct snd_emux *emu, struct snd_emux_port *port,
- int *notep, int vel, struct snd_midi_channel *chan,
- struct snd_sf_zone **table)
-{
- int preset, bank, def_preset, def_bank;
-
- bank = get_bank(port, chan);
- preset = chan->midi_program;
-
- if (SF_IS_DRUM_BANK(bank)) {
- def_preset = port->ctrls[EMUX_MD_DEF_DRUM];
- def_bank = bank;
- } else {
- def_preset = preset;
- def_bank = port->ctrls[EMUX_MD_DEF_BANK];
- }
-
- return snd_soundfont_search_zone(emu->sflist, notep, vel, preset, bank,
- def_preset, def_bank,
- table, SNDRV_EMUX_MAX_MULTI_VOICES);
-}
-
-/*
- */
-void
-snd_emux_init_voices(struct snd_emux *emu)
-{
- struct snd_emux_voice *vp;
- int i;
- unsigned long flags;
-
- spin_lock_irqsave(&emu->voice_lock, flags);
- for (i = 0; i < emu->max_voices; i++) {
- vp = &emu->voices[i];
- vp->ch = -1; /* not used */
- vp->state = SNDRV_EMUX_ST_OFF;
- vp->chan = NULL;
- vp->port = NULL;
- vp->time = 0;
- vp->emu = emu;
- vp->hw = emu->hw;
- }
- spin_unlock_irqrestore(&emu->voice_lock, flags);
-}
-
-/*
- */
-void snd_emux_lock_voice(struct snd_emux *emu, int voice)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&emu->voice_lock, flags);
- if (emu->voices[voice].state == SNDRV_EMUX_ST_OFF)
- emu->voices[voice].state = SNDRV_EMUX_ST_LOCKED;
- else
- snd_printk(KERN_WARNING
- "invalid voice for lock %d (state = %x)\n",
- voice, emu->voices[voice].state);
- spin_unlock_irqrestore(&emu->voice_lock, flags);
-}
-
-EXPORT_SYMBOL(snd_emux_lock_voice);
-
-/*
- */
-void snd_emux_unlock_voice(struct snd_emux *emu, int voice)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&emu->voice_lock, flags);
- if (emu->voices[voice].state == SNDRV_EMUX_ST_LOCKED)
- emu->voices[voice].state = SNDRV_EMUX_ST_OFF;
- else
- snd_printk(KERN_WARNING
- "invalid voice for unlock %d (state = %x)\n",
- voice, emu->voices[voice].state);
- spin_unlock_irqrestore(&emu->voice_lock, flags);
-}
-
-EXPORT_SYMBOL(snd_emux_unlock_voice);
diff --git a/ANDROID_3.4.5/sound/synth/emux/emux_voice.h b/ANDROID_3.4.5/sound/synth/emux/emux_voice.h
deleted file mode 100644
index 09711f84..00000000
--- a/ANDROID_3.4.5/sound/synth/emux/emux_voice.h
+++ /dev/null
@@ -1,96 +0,0 @@
-#ifndef __EMUX_VOICE_H
-#define __EMUX_VOICE_H
-
-/*
- * A structure to keep track of each hardware voice
- *
- * Copyright (C) 1999 Steve Ratcliffe
- * Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/wait.h>
-#include <linux/sched.h>
-#include <sound/core.h>
-#include <sound/emux_synth.h>
-
-/* Prototypes for emux_seq.c */
-int snd_emux_init_seq(struct snd_emux *emu, struct snd_card *card, int index);
-void snd_emux_detach_seq(struct snd_emux *emu);
-struct snd_emux_port *snd_emux_create_port(struct snd_emux *emu, char *name,
- int max_channels, int type,
- struct snd_seq_port_callback *callback);
-void snd_emux_reset_port(struct snd_emux_port *port);
-int snd_emux_event_input(struct snd_seq_event *ev, int direct, void *private,
- int atomic, int hop);
-int snd_emux_inc_count(struct snd_emux *emu);
-void snd_emux_dec_count(struct snd_emux *emu);
-int snd_emux_init_virmidi(struct snd_emux *emu, struct snd_card *card);
-int snd_emux_delete_virmidi(struct snd_emux *emu);
-
-/* Prototypes for emux_synth.c */
-void snd_emux_init_voices(struct snd_emux *emu);
-
-void snd_emux_note_on(void *p, int note, int vel, struct snd_midi_channel *chan);
-void snd_emux_note_off(void *p, int note, int vel, struct snd_midi_channel *chan);
-void snd_emux_key_press(void *p, int note, int vel, struct snd_midi_channel *chan);
-void snd_emux_terminate_note(void *p, int note, struct snd_midi_channel *chan);
-void snd_emux_control(void *p, int type, struct snd_midi_channel *chan);
-
-void snd_emux_sounds_off_all(struct snd_emux_port *port);
-void snd_emux_update_channel(struct snd_emux_port *port,
- struct snd_midi_channel *chan, int update);
-void snd_emux_update_port(struct snd_emux_port *port, int update);
-
-void snd_emux_timer_callback(unsigned long data);
-
-/* emux_effect.c */
-#ifdef SNDRV_EMUX_USE_RAW_EFFECT
-void snd_emux_create_effect(struct snd_emux_port *p);
-void snd_emux_delete_effect(struct snd_emux_port *p);
-void snd_emux_clear_effect(struct snd_emux_port *p);
-void snd_emux_setup_effect(struct snd_emux_voice *vp);
-void snd_emux_send_effect_oss(struct snd_emux_port *port,
- struct snd_midi_channel *chan, int type, int val);
-void snd_emux_send_effect(struct snd_emux_port *port,
- struct snd_midi_channel *chan, int type, int val, int mode);
-#endif
-
-/* emux_nrpn.c */
-void snd_emux_sysex(void *private_data, unsigned char *buf, int len,
- int parsed, struct snd_midi_channel_set *chset);
-int snd_emux_xg_control(struct snd_emux_port *port,
- struct snd_midi_channel *chan, int param);
-void snd_emux_nrpn(void *private_data, struct snd_midi_channel *chan,
- struct snd_midi_channel_set *chset);
-
-/* emux_oss.c */
-void snd_emux_init_seq_oss(struct snd_emux *emu);
-void snd_emux_detach_seq_oss(struct snd_emux *emu);
-
-/* emux_proc.c */
-#ifdef CONFIG_PROC_FS
-void snd_emux_proc_init(struct snd_emux *emu, struct snd_card *card, int device);
-void snd_emux_proc_free(struct snd_emux *emu);
-#endif
-
-#define STATE_IS_PLAYING(s) ((s) & SNDRV_EMUX_ST_ON)
-
-/* emux_hwdep.c */
-int snd_emux_init_hwdep(struct snd_emux *emu);
-void snd_emux_delete_hwdep(struct snd_emux *emu);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/synth/emux/soundfont.c b/ANDROID_3.4.5/sound/synth/emux/soundfont.c
deleted file mode 100644
index 1137b85c..00000000
--- a/ANDROID_3.4.5/sound/synth/emux/soundfont.c
+++ /dev/null
@@ -1,1496 +0,0 @@
-/*
- * Soundfont generic routines.
- * It is intended that these should be used by any driver that is willing
- * to accept soundfont patches.
- *
- * Copyright (C) 1999 Steve Ratcliffe
- * Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-/*
- * Deal with reading in of a soundfont. Code follows the OSS way
- * of doing things so that the old sfxload utility can be used.
- * Everything may change when there is an alsa way of doing things.
- */
-#include <asm/uaccess.h>
-#include <linux/slab.h>
-#include <linux/export.h>
-#include <sound/core.h>
-#include <sound/soundfont.h>
-#include <sound/seq_oss_legacy.h>
-
-/* Prototypes for static functions */
-
-static int open_patch(struct snd_sf_list *sflist, const char __user *data,
- int count, int client);
-static struct snd_soundfont *newsf(struct snd_sf_list *sflist, int type, char *name);
-static int is_identical_font(struct snd_soundfont *sf, int type, unsigned char *name);
-static int close_patch(struct snd_sf_list *sflist);
-static int probe_data(struct snd_sf_list *sflist, int sample_id);
-static void set_zone_counter(struct snd_sf_list *sflist,
- struct snd_soundfont *sf, struct snd_sf_zone *zp);
-static struct snd_sf_zone *sf_zone_new(struct snd_sf_list *sflist,
- struct snd_soundfont *sf);
-static void set_sample_counter(struct snd_sf_list *sflist,
- struct snd_soundfont *sf, struct snd_sf_sample *sp);
-static struct snd_sf_sample *sf_sample_new(struct snd_sf_list *sflist,
- struct snd_soundfont *sf);
-static void sf_sample_delete(struct snd_sf_list *sflist,
- struct snd_soundfont *sf, struct snd_sf_sample *sp);
-static int load_map(struct snd_sf_list *sflist, const void __user *data, int count);
-static int load_info(struct snd_sf_list *sflist, const void __user *data, long count);
-static int remove_info(struct snd_sf_list *sflist, struct snd_soundfont *sf,
- int bank, int instr);
-static void init_voice_info(struct soundfont_voice_info *avp);
-static void init_voice_parm(struct soundfont_voice_parm *pp);
-static struct snd_sf_sample *set_sample(struct snd_soundfont *sf,
- struct soundfont_voice_info *avp);
-static struct snd_sf_sample *find_sample(struct snd_soundfont *sf, int sample_id);
-static int load_data(struct snd_sf_list *sflist, const void __user *data, long count);
-static void rebuild_presets(struct snd_sf_list *sflist);
-static void add_preset(struct snd_sf_list *sflist, struct snd_sf_zone *cur);
-static void delete_preset(struct snd_sf_list *sflist, struct snd_sf_zone *zp);
-static struct snd_sf_zone *search_first_zone(struct snd_sf_list *sflist,
- int bank, int preset, int key);
-static int search_zones(struct snd_sf_list *sflist, int *notep, int vel,
- int preset, int bank, struct snd_sf_zone **table,
- int max_layers, int level);
-static int get_index(int bank, int instr, int key);
-static void snd_sf_init(struct snd_sf_list *sflist);
-static void snd_sf_clear(struct snd_sf_list *sflist);
-
-/*
- * lock access to sflist
- */
-static void
-lock_preset(struct snd_sf_list *sflist)
-{
- unsigned long flags;
- mutex_lock(&sflist->presets_mutex);
- spin_lock_irqsave(&sflist->lock, flags);
- sflist->presets_locked = 1;
- spin_unlock_irqrestore(&sflist->lock, flags);
-}
-
-
-/*
- * remove lock
- */
-static void
-unlock_preset(struct snd_sf_list *sflist)
-{
- unsigned long flags;
- spin_lock_irqsave(&sflist->lock, flags);
- sflist->presets_locked = 0;
- spin_unlock_irqrestore(&sflist->lock, flags);
- mutex_unlock(&sflist->presets_mutex);
-}
-
-
-/*
- * close the patch if the patch was opened by this client.
- */
-int
-snd_soundfont_close_check(struct snd_sf_list *sflist, int client)
-{
- unsigned long flags;
- spin_lock_irqsave(&sflist->lock, flags);
- if (sflist->open_client == client) {
- spin_unlock_irqrestore(&sflist->lock, flags);
- return close_patch(sflist);
- }
- spin_unlock_irqrestore(&sflist->lock, flags);
- return 0;
-}
-
-
-/*
- * Deal with a soundfont patch. Any driver could use these routines
- * although it was designed for the AWE64.
- *
- * The sample_write and callargs pararameters allow a callback into
- * the actual driver to write sample data to the board or whatever
- * it wants to do with it.
- */
-int
-snd_soundfont_load(struct snd_sf_list *sflist, const void __user *data,
- long count, int client)
-{
- struct soundfont_patch_info patch;
- unsigned long flags;
- int rc;
-
- if (count < (long)sizeof(patch)) {
- snd_printk(KERN_ERR "patch record too small %ld\n", count);
- return -EINVAL;
- }
- if (copy_from_user(&patch, data, sizeof(patch)))
- return -EFAULT;
-
- count -= sizeof(patch);
- data += sizeof(patch);
-
- if (patch.key != SNDRV_OSS_SOUNDFONT_PATCH) {
- snd_printk(KERN_ERR "The wrong kind of patch %x\n", patch.key);
- return -EINVAL;
- }
- if (count < patch.len) {
- snd_printk(KERN_ERR "Patch too short %ld, need %d\n",
- count, patch.len);
- return -EINVAL;
- }
- if (patch.len < 0) {
- snd_printk(KERN_ERR "poor length %d\n", patch.len);
- return -EINVAL;
- }
-
- if (patch.type == SNDRV_SFNT_OPEN_PATCH) {
- /* grab sflist to open */
- lock_preset(sflist);
- rc = open_patch(sflist, data, count, client);
- unlock_preset(sflist);
- return rc;
- }
-
- /* check if other client already opened patch */
- spin_lock_irqsave(&sflist->lock, flags);
- if (sflist->open_client != client) {
- spin_unlock_irqrestore(&sflist->lock, flags);
- return -EBUSY;
- }
- spin_unlock_irqrestore(&sflist->lock, flags);
-
- lock_preset(sflist);
- rc = -EINVAL;
- switch (patch.type) {
- case SNDRV_SFNT_LOAD_INFO:
- rc = load_info(sflist, data, count);
- break;
- case SNDRV_SFNT_LOAD_DATA:
- rc = load_data(sflist, data, count);
- break;
- case SNDRV_SFNT_CLOSE_PATCH:
- rc = close_patch(sflist);
- break;
- case SNDRV_SFNT_REPLACE_DATA:
- /*rc = replace_data(&patch, data, count);*/
- break;
- case SNDRV_SFNT_MAP_PRESET:
- rc = load_map(sflist, data, count);
- break;
- case SNDRV_SFNT_PROBE_DATA:
- rc = probe_data(sflist, patch.optarg);
- break;
- case SNDRV_SFNT_REMOVE_INFO:
- /* patch must be opened */
- if (!sflist->currsf) {
- snd_printk(KERN_ERR "soundfont: remove_info: "
- "patch not opened\n");
- rc = -EINVAL;
- } else {
- int bank, instr;
- bank = ((unsigned short)patch.optarg >> 8) & 0xff;
- instr = (unsigned short)patch.optarg & 0xff;
- if (! remove_info(sflist, sflist->currsf, bank, instr))
- rc = -EINVAL;
- else
- rc = 0;
- }
- break;
- }
- unlock_preset(sflist);
-
- return rc;
-}
-
-
-/* check if specified type is special font (GUS or preset-alias) */
-static inline int
-is_special_type(int type)
-{
- type &= 0x0f;
- return (type == SNDRV_SFNT_PAT_TYPE_GUS ||
- type == SNDRV_SFNT_PAT_TYPE_MAP);
-}
-
-
-/* open patch; create sf list */
-static int
-open_patch(struct snd_sf_list *sflist, const char __user *data,
- int count, int client)
-{
- struct soundfont_open_parm parm;
- struct snd_soundfont *sf;
- unsigned long flags;
-
- spin_lock_irqsave(&sflist->lock, flags);
- if (sflist->open_client >= 0 || sflist->currsf) {
- spin_unlock_irqrestore(&sflist->lock, flags);
- return -EBUSY;
- }
- spin_unlock_irqrestore(&sflist->lock, flags);
-
- if (copy_from_user(&parm, data, sizeof(parm)))
- return -EFAULT;
-
- if (is_special_type(parm.type)) {
- parm.type |= SNDRV_SFNT_PAT_SHARED;
- sf = newsf(sflist, parm.type, NULL);
- } else
- sf = newsf(sflist, parm.type, parm.name);
- if (sf == NULL) {
- return -ENOMEM;
- }
-
- spin_lock_irqsave(&sflist->lock, flags);
- sflist->open_client = client;
- sflist->currsf = sf;
- spin_unlock_irqrestore(&sflist->lock, flags);
-
- return 0;
-}
-
-/*
- * Allocate a new soundfont structure.
- */
-static struct snd_soundfont *
-newsf(struct snd_sf_list *sflist, int type, char *name)
-{
- struct snd_soundfont *sf;
-
- /* check the shared fonts */
- if (type & SNDRV_SFNT_PAT_SHARED) {
- for (sf = sflist->fonts; sf; sf = sf->next) {
- if (is_identical_font(sf, type, name)) {
- return sf;
- }
- }
- }
-
- /* not found -- create a new one */
- sf = kzalloc(sizeof(*sf), GFP_KERNEL);
- if (sf == NULL)
- return NULL;
- sf->id = sflist->fonts_size;
- sflist->fonts_size++;
-
- /* prepend this record */
- sf->next = sflist->fonts;
- sflist->fonts = sf;
-
- sf->type = type;
- sf->zones = NULL;
- sf->samples = NULL;
- if (name)
- memcpy(sf->name, name, SNDRV_SFNT_PATCH_NAME_LEN);
-
- return sf;
-}
-
-/* check if the given name matches to the existing list */
-static int
-is_identical_font(struct snd_soundfont *sf, int type, unsigned char *name)
-{
- return ((sf->type & SNDRV_SFNT_PAT_SHARED) &&
- (sf->type & 0x0f) == (type & 0x0f) &&
- (name == NULL ||
- memcmp(sf->name, name, SNDRV_SFNT_PATCH_NAME_LEN) == 0));
-}
-
-/*
- * Close the current patch.
- */
-static int
-close_patch(struct snd_sf_list *sflist)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&sflist->lock, flags);
- sflist->currsf = NULL;
- sflist->open_client = -1;
- spin_unlock_irqrestore(&sflist->lock, flags);
-
- rebuild_presets(sflist);
-
- return 0;
-
-}
-
-/* probe sample in the current list -- nothing to be loaded */
-static int
-probe_data(struct snd_sf_list *sflist, int sample_id)
-{
- /* patch must be opened */
- if (sflist->currsf) {
- /* search the specified sample by optarg */
- if (find_sample(sflist->currsf, sample_id))
- return 0;
- }
- return -EINVAL;
-}
-
-/*
- * increment zone counter
- */
-static void
-set_zone_counter(struct snd_sf_list *sflist, struct snd_soundfont *sf,
- struct snd_sf_zone *zp)
-{
- zp->counter = sflist->zone_counter++;
- if (sf->type & SNDRV_SFNT_PAT_LOCKED)
- sflist->zone_locked = sflist->zone_counter;
-}
-
-/*
- * allocate a new zone record
- */
-static struct snd_sf_zone *
-sf_zone_new(struct snd_sf_list *sflist, struct snd_soundfont *sf)
-{
- struct snd_sf_zone *zp;
-
- if ((zp = kzalloc(sizeof(*zp), GFP_KERNEL)) == NULL)
- return NULL;
- zp->next = sf->zones;
- sf->zones = zp;
-
- init_voice_info(&zp->v);
-
- set_zone_counter(sflist, sf, zp);
- return zp;
-}
-
-
-/*
- * increment sample counter
- */
-static void
-set_sample_counter(struct snd_sf_list *sflist, struct snd_soundfont *sf,
- struct snd_sf_sample *sp)
-{
- sp->counter = sflist->sample_counter++;
- if (sf->type & SNDRV_SFNT_PAT_LOCKED)
- sflist->sample_locked = sflist->sample_counter;
-}
-
-/*
- * allocate a new sample list record
- */
-static struct snd_sf_sample *
-sf_sample_new(struct snd_sf_list *sflist, struct snd_soundfont *sf)
-{
- struct snd_sf_sample *sp;
-
- if ((sp = kzalloc(sizeof(*sp), GFP_KERNEL)) == NULL)
- return NULL;
-
- sp->next = sf->samples;
- sf->samples = sp;
-
- set_sample_counter(sflist, sf, sp);
- return sp;
-}
-
-/*
- * delete sample list -- this is an exceptional job.
- * only the last allocated sample can be deleted.
- */
-static void
-sf_sample_delete(struct snd_sf_list *sflist, struct snd_soundfont *sf,
- struct snd_sf_sample *sp)
-{
- /* only last sample is accepted */
- if (sp == sf->samples) {
- sf->samples = sp->next;
- kfree(sp);
- }
-}
-
-
-/* load voice map */
-static int
-load_map(struct snd_sf_list *sflist, const void __user *data, int count)
-{
- struct snd_sf_zone *zp, *prevp;
- struct snd_soundfont *sf;
- struct soundfont_voice_map map;
-
- /* get the link info */
- if (count < (int)sizeof(map))
- return -EINVAL;
- if (copy_from_user(&map, data, sizeof(map)))
- return -EFAULT;
-
- if (map.map_instr < 0 || map.map_instr >= SF_MAX_INSTRUMENTS)
- return -EINVAL;
-
- sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_MAP|SNDRV_SFNT_PAT_SHARED, NULL);
- if (sf == NULL)
- return -ENOMEM;
-
- prevp = NULL;
- for (zp = sf->zones; zp; prevp = zp, zp = zp->next) {
- if (zp->mapped &&
- zp->instr == map.map_instr &&
- zp->bank == map.map_bank &&
- zp->v.low == map.map_key &&
- zp->v.start == map.src_instr &&
- zp->v.end == map.src_bank &&
- zp->v.fixkey == map.src_key) {
- /* the same mapping is already present */
- /* relink this record to the link head */
- if (prevp) {
- prevp->next = zp->next;
- zp->next = sf->zones;
- sf->zones = zp;
- }
- /* update the counter */
- set_zone_counter(sflist, sf, zp);
- return 0;
- }
- }
-
- /* create a new zone */
- if ((zp = sf_zone_new(sflist, sf)) == NULL)
- return -ENOMEM;
-
- zp->bank = map.map_bank;
- zp->instr = map.map_instr;
- zp->mapped = 1;
- if (map.map_key >= 0) {
- zp->v.low = map.map_key;
- zp->v.high = map.map_key;
- }
- zp->v.start = map.src_instr;
- zp->v.end = map.src_bank;
- zp->v.fixkey = map.src_key;
- zp->v.sf_id = sf->id;
-
- add_preset(sflist, zp);
-
- return 0;
-}
-
-
-/* remove the present instrument layers */
-static int
-remove_info(struct snd_sf_list *sflist, struct snd_soundfont *sf,
- int bank, int instr)
-{
- struct snd_sf_zone *prev, *next, *p;
- int removed = 0;
-
- prev = NULL;
- for (p = sf->zones; p; p = next) {
- next = p->next;
- if (! p->mapped &&
- p->bank == bank && p->instr == instr) {
- /* remove this layer */
- if (prev)
- prev->next = next;
- else
- sf->zones = next;
- removed++;
- kfree(p);
- } else
- prev = p;
- }
- if (removed)
- rebuild_presets(sflist);
- return removed;
-}
-
-
-/*
- * Read an info record from the user buffer and save it on the current
- * open soundfont.
- */
-static int
-load_info(struct snd_sf_list *sflist, const void __user *data, long count)
-{
- struct snd_soundfont *sf;
- struct snd_sf_zone *zone;
- struct soundfont_voice_rec_hdr hdr;
- int i;
-
- /* patch must be opened */
- if ((sf = sflist->currsf) == NULL)
- return -EINVAL;
-
- if (is_special_type(sf->type))
- return -EINVAL;
-
- if (count < (long)sizeof(hdr)) {
- printk(KERN_ERR "Soundfont error: invalid patch zone length\n");
- return -EINVAL;
- }
- if (copy_from_user((char*)&hdr, data, sizeof(hdr)))
- return -EFAULT;
-
- data += sizeof(hdr);
- count -= sizeof(hdr);
-
- if (hdr.nvoices <= 0 || hdr.nvoices >= 100) {
- printk(KERN_ERR "Soundfont error: Illegal voice number %d\n",
- hdr.nvoices);
- return -EINVAL;
- }
-
- if (count < (long)sizeof(struct soundfont_voice_info) * hdr.nvoices) {
- printk(KERN_ERR "Soundfont Error: "
- "patch length(%ld) is smaller than nvoices(%d)\n",
- count, hdr.nvoices);
- return -EINVAL;
- }
-
- switch (hdr.write_mode) {
- case SNDRV_SFNT_WR_EXCLUSIVE:
- /* exclusive mode - if the instrument already exists,
- return error */
- for (zone = sf->zones; zone; zone = zone->next) {
- if (!zone->mapped &&
- zone->bank == hdr.bank &&
- zone->instr == hdr.instr)
- return -EINVAL;
- }
- break;
- case SNDRV_SFNT_WR_REPLACE:
- /* replace mode - remove the instrument if it already exists */
- remove_info(sflist, sf, hdr.bank, hdr.instr);
- break;
- }
-
- for (i = 0; i < hdr.nvoices; i++) {
- struct snd_sf_zone tmpzone;
-
- /* copy awe_voice_info parameters */
- if (copy_from_user(&tmpzone.v, data, sizeof(tmpzone.v))) {
- return -EFAULT;
- }
-
- data += sizeof(tmpzone.v);
- count -= sizeof(tmpzone.v);
-
- tmpzone.bank = hdr.bank;
- tmpzone.instr = hdr.instr;
- tmpzone.mapped = 0;
- tmpzone.v.sf_id = sf->id;
- if (tmpzone.v.mode & SNDRV_SFNT_MODE_INIT_PARM)
- init_voice_parm(&tmpzone.v.parm);
-
- /* create a new zone */
- if ((zone = sf_zone_new(sflist, sf)) == NULL) {
- return -ENOMEM;
- }
-
- /* copy the temporary data */
- zone->bank = tmpzone.bank;
- zone->instr = tmpzone.instr;
- zone->v = tmpzone.v;
-
- /* look up the sample */
- zone->sample = set_sample(sf, &zone->v);
- }
-
- return 0;
-}
-
-
-/* initialize voice_info record */
-static void
-init_voice_info(struct soundfont_voice_info *avp)
-{
- memset(avp, 0, sizeof(*avp));
-
- avp->root = 60;
- avp->high = 127;
- avp->velhigh = 127;
- avp->fixkey = -1;
- avp->fixvel = -1;
- avp->fixpan = -1;
- avp->pan = -1;
- avp->amplitude = 127;
- avp->scaleTuning = 100;
-
- init_voice_parm(&avp->parm);
-}
-
-/* initialize voice_parm record:
- * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0.
- * Vibrato and Tremolo effects are zero.
- * Cutoff is maximum.
- * Chorus and Reverb effects are zero.
- */
-static void
-init_voice_parm(struct soundfont_voice_parm *pp)
-{
- memset(pp, 0, sizeof(*pp));
-
- pp->moddelay = 0x8000;
- pp->modatkhld = 0x7f7f;
- pp->moddcysus = 0x7f7f;
- pp->modrelease = 0x807f;
-
- pp->voldelay = 0x8000;
- pp->volatkhld = 0x7f7f;
- pp->voldcysus = 0x7f7f;
- pp->volrelease = 0x807f;
-
- pp->lfo1delay = 0x8000;
- pp->lfo2delay = 0x8000;
-
- pp->cutoff = 0xff;
-}
-
-/* search the specified sample */
-static struct snd_sf_sample *
-set_sample(struct snd_soundfont *sf, struct soundfont_voice_info *avp)
-{
- struct snd_sf_sample *sample;
-
- sample = find_sample(sf, avp->sample);
- if (sample == NULL)
- return NULL;
-
- /* add in the actual sample offsets:
- * The voice_info addresses define only the relative offset
- * from sample pointers. Here we calculate the actual DRAM
- * offset from sample pointers.
- */
- avp->start += sample->v.start;
- avp->end += sample->v.end;
- avp->loopstart += sample->v.loopstart;
- avp->loopend += sample->v.loopend;
-
- /* copy mode flags */
- avp->sample_mode = sample->v.mode_flags;
-
- return sample;
-}
-
-/* find the sample pointer with the given id in the soundfont */
-static struct snd_sf_sample *
-find_sample(struct snd_soundfont *sf, int sample_id)
-{
- struct snd_sf_sample *p;
-
- if (sf == NULL)
- return NULL;
-
- for (p = sf->samples; p; p = p->next) {
- if (p->v.sample == sample_id)
- return p;
- }
- return NULL;
-}
-
-
-/*
- * Load sample information, this can include data to be loaded onto
- * the soundcard. It can also just be a pointer into soundcard ROM.
- * If there is data it will be written to the soundcard via the callback
- * routine.
- */
-static int
-load_data(struct snd_sf_list *sflist, const void __user *data, long count)
-{
- struct snd_soundfont *sf;
- struct soundfont_sample_info sample_info;
- struct snd_sf_sample *sp;
- long off;
-
- /* patch must be opened */
- if ((sf = sflist->currsf) == NULL)
- return -EINVAL;
-
- if (is_special_type(sf->type))
- return -EINVAL;
-
- if (copy_from_user(&sample_info, data, sizeof(sample_info)))
- return -EFAULT;
-
- off = sizeof(sample_info);
-
- if (sample_info.size != (count-off)/2)
- return -EINVAL;
-
- /* Check for dup */
- if (find_sample(sf, sample_info.sample)) {
- /* if shared sample, skip this data */
- if (sf->type & SNDRV_SFNT_PAT_SHARED)
- return 0;
- return -EINVAL;
- }
-
- /* Allocate a new sample structure */
- if ((sp = sf_sample_new(sflist, sf)) == NULL)
- return -ENOMEM;
-
- sp->v = sample_info;
- sp->v.sf_id = sf->id;
- sp->v.dummy = 0;
- sp->v.truesize = sp->v.size;
-
- /*
- * If there is wave data then load it.
- */
- if (sp->v.size > 0) {
- int rc;
- rc = sflist->callback.sample_new
- (sflist->callback.private_data, sp, sflist->memhdr,
- data + off, count - off);
- if (rc < 0) {
- sf_sample_delete(sflist, sf, sp);
- return rc;
- }
- sflist->mem_used += sp->v.truesize;
- }
-
- return count;
-}
-
-
-/* log2_tbl[i] = log2(i+128) * 0x10000 */
-static int log_tbl[129] = {
- 0x70000, 0x702df, 0x705b9, 0x7088e, 0x70b5d, 0x70e26, 0x710eb, 0x713aa,
- 0x71663, 0x71918, 0x71bc8, 0x71e72, 0x72118, 0x723b9, 0x72655, 0x728ed,
- 0x72b80, 0x72e0e, 0x73098, 0x7331d, 0x7359e, 0x7381b, 0x73a93, 0x73d08,
- 0x73f78, 0x741e4, 0x7444c, 0x746b0, 0x74910, 0x74b6c, 0x74dc4, 0x75019,
- 0x75269, 0x754b6, 0x75700, 0x75946, 0x75b88, 0x75dc7, 0x76002, 0x7623a,
- 0x7646e, 0x766a0, 0x768cd, 0x76af8, 0x76d1f, 0x76f43, 0x77164, 0x77382,
- 0x7759d, 0x777b4, 0x779c9, 0x77bdb, 0x77dea, 0x77ff5, 0x781fe, 0x78404,
- 0x78608, 0x78808, 0x78a06, 0x78c01, 0x78df9, 0x78fef, 0x791e2, 0x793d2,
- 0x795c0, 0x797ab, 0x79993, 0x79b79, 0x79d5d, 0x79f3e, 0x7a11d, 0x7a2f9,
- 0x7a4d3, 0x7a6ab, 0x7a880, 0x7aa53, 0x7ac24, 0x7adf2, 0x7afbe, 0x7b188,
- 0x7b350, 0x7b515, 0x7b6d8, 0x7b899, 0x7ba58, 0x7bc15, 0x7bdd0, 0x7bf89,
- 0x7c140, 0x7c2f5, 0x7c4a7, 0x7c658, 0x7c807, 0x7c9b3, 0x7cb5e, 0x7cd07,
- 0x7ceae, 0x7d053, 0x7d1f7, 0x7d398, 0x7d538, 0x7d6d6, 0x7d872, 0x7da0c,
- 0x7dba4, 0x7dd3b, 0x7ded0, 0x7e063, 0x7e1f4, 0x7e384, 0x7e512, 0x7e69f,
- 0x7e829, 0x7e9b3, 0x7eb3a, 0x7ecc0, 0x7ee44, 0x7efc7, 0x7f148, 0x7f2c8,
- 0x7f446, 0x7f5c2, 0x7f73d, 0x7f8b7, 0x7fa2f, 0x7fba5, 0x7fd1a, 0x7fe8d,
- 0x80000,
-};
-
-/* convert from linear to log value
- *
- * conversion: value = log2(amount / base) * ratio
- *
- * argument:
- * amount = linear value (unsigned, 32bit max)
- * offset = base offset (:= log2(base) * 0x10000)
- * ratio = division ratio
- *
- */
-int
-snd_sf_linear_to_log(unsigned int amount, int offset, int ratio)
-{
- int v;
- int s, low, bit;
-
- if (amount < 2)
- return 0;
- for (bit = 0; ! (amount & 0x80000000L); bit++)
- amount <<= 1;
- s = (amount >> 24) & 0x7f;
- low = (amount >> 16) & 0xff;
- /* linear approxmimation by lower 8 bit */
- v = (log_tbl[s + 1] * low + log_tbl[s] * (0x100 - low)) >> 8;
- v -= offset;
- v = (v * ratio) >> 16;
- v += (24 - bit) * ratio;
- return v;
-}
-
-EXPORT_SYMBOL(snd_sf_linear_to_log);
-
-
-#define OFFSET_MSEC 653117 /* base = 1000 */
-#define OFFSET_ABSCENT 851781 /* base = 8176 */
-#define OFFSET_SAMPLERATE 1011119 /* base = 44100 */
-
-#define ABSCENT_RATIO 1200
-#define TIMECENT_RATIO 1200
-#define SAMPLERATE_RATIO 4096
-
-/*
- * mHz to abscent
- * conversion: abscent = log2(MHz / 8176) * 1200
- */
-static int
-freq_to_note(int mhz)
-{
- return snd_sf_linear_to_log(mhz, OFFSET_ABSCENT, ABSCENT_RATIO);
-}
-
-/* convert Hz to AWE32 rate offset:
- * sample pitch offset for the specified sample rate
- * rate=44100 is no offset, each 4096 is 1 octave (twice).
- * eg, when rate is 22050, this offset becomes -4096.
- *
- * conversion: offset = log2(Hz / 44100) * 4096
- */
-static int
-calc_rate_offset(int hz)
-{
- return snd_sf_linear_to_log(hz, OFFSET_SAMPLERATE, SAMPLERATE_RATIO);
-}
-
-
-/* calculate GUS envelope time */
-static int
-calc_gus_envelope_time(int rate, int start, int end)
-{
- int r, p, t;
- r = (3 - ((rate >> 6) & 3)) * 3;
- p = rate & 0x3f;
- t = end - start;
- if (t < 0) t = -t;
- if (13 > r)
- t = t << (13 - r);
- else
- t = t >> (r - 13);
- return (t * 10) / (p * 441);
-}
-
-/* convert envelope time parameter to soundfont parameters */
-
-/* attack & decay/release time table (msec) */
-static short attack_time_tbl[128] = {
-32767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816,
-707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377,
-361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188,
-180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94,
-90, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47,
-45, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23,
-22, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
-11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0,
-};
-
-static short decay_time_tbl[128] = {
-32767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082,
-2828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507,
-1443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722,
-691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361,
-345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180,
-172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90,
-86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45,
-43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22,
-};
-
-/* delay time = 0x8000 - msec/92 */
-int
-snd_sf_calc_parm_hold(int msec)
-{
- int val = (0x7f * 92 - msec) / 92;
- if (val < 1) val = 1;
- if (val >= 126) val = 126;
- return val;
-}
-
-/* search an index for specified time from given time table */
-static int
-calc_parm_search(int msec, short *table)
-{
- int left = 1, right = 127, mid;
- while (left < right) {
- mid = (left + right) / 2;
- if (msec < (int)table[mid])
- left = mid + 1;
- else
- right = mid;
- }
- return left;
-}
-
-/* attack time: search from time table */
-int
-snd_sf_calc_parm_attack(int msec)
-{
- return calc_parm_search(msec, attack_time_tbl);
-}
-
-/* decay/release time: search from time table */
-int
-snd_sf_calc_parm_decay(int msec)
-{
- return calc_parm_search(msec, decay_time_tbl);
-}
-
-int snd_sf_vol_table[128] = {
- 255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49,
- 47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32,
- 31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22,
- 22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16,
- 15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10,
- 10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,
- 6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,
- 2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,
-};
-
-
-#define calc_gus_sustain(val) (0x7f - snd_sf_vol_table[(val)/2])
-#define calc_gus_attenuation(val) snd_sf_vol_table[(val)/2]
-
-/* load GUS patch */
-static int
-load_guspatch(struct snd_sf_list *sflist, const char __user *data,
- long count, int client)
-{
- struct patch_info patch;
- struct snd_soundfont *sf;
- struct snd_sf_zone *zone;
- struct snd_sf_sample *smp;
- int note, sample_id;
- int rc;
-
- if (count < (long)sizeof(patch)) {
- snd_printk(KERN_ERR "patch record too small %ld\n", count);
- return -EINVAL;
- }
- if (copy_from_user(&patch, data, sizeof(patch)))
- return -EFAULT;
-
- count -= sizeof(patch);
- data += sizeof(patch);
-
- sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_GUS|SNDRV_SFNT_PAT_SHARED, NULL);
- if (sf == NULL)
- return -ENOMEM;
- if ((smp = sf_sample_new(sflist, sf)) == NULL)
- return -ENOMEM;
- sample_id = sflist->sample_counter;
- smp->v.sample = sample_id;
- smp->v.start = 0;
- smp->v.end = patch.len;
- smp->v.loopstart = patch.loop_start;
- smp->v.loopend = patch.loop_end;
- smp->v.size = patch.len;
-
- /* set up mode flags */
- smp->v.mode_flags = 0;
- if (!(patch.mode & WAVE_16_BITS))
- smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_8BITS;
- if (patch.mode & WAVE_UNSIGNED)
- smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_UNSIGNED;
- smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_NO_BLANK;
- if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP|WAVE_LOOP_BACK)))
- smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_SINGLESHOT;
- if (patch.mode & WAVE_BIDIR_LOOP)
- smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_BIDIR_LOOP;
- if (patch.mode & WAVE_LOOP_BACK)
- smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_REVERSE_LOOP;
-
- if (patch.mode & WAVE_16_BITS) {
- /* convert to word offsets */
- smp->v.size /= 2;
- smp->v.end /= 2;
- smp->v.loopstart /= 2;
- smp->v.loopend /= 2;
- }
- /*smp->v.loopend++;*/
-
- smp->v.dummy = 0;
- smp->v.truesize = 0;
- smp->v.sf_id = sf->id;
-
- /* set up voice info */
- if ((zone = sf_zone_new(sflist, sf)) == NULL) {
- sf_sample_delete(sflist, sf, smp);
- return -ENOMEM;
- }
-
- /*
- * load wave data
- */
- if (sflist->callback.sample_new) {
- rc = sflist->callback.sample_new
- (sflist->callback.private_data, smp, sflist->memhdr,
- data, count);
- if (rc < 0) {
- sf_sample_delete(sflist, sf, smp);
- return rc;
- }
- /* memory offset is updated after */
- }
-
- /* update the memory offset here */
- sflist->mem_used += smp->v.truesize;
-
- zone->v.sample = sample_id; /* the last sample */
- zone->v.rate_offset = calc_rate_offset(patch.base_freq);
- note = freq_to_note(patch.base_note);
- zone->v.root = note / 100;
- zone->v.tune = -(note % 100);
- zone->v.low = (freq_to_note(patch.low_note) + 99) / 100;
- zone->v.high = freq_to_note(patch.high_note) / 100;
- /* panning position; -128 - 127 => 0-127 */
- zone->v.pan = (patch.panning + 128) / 2;
-#if 0
- snd_printk(KERN_DEBUG
- "gus: basefrq=%d (ofs=%d) root=%d,tune=%d, range:%d-%d\n",
- (int)patch.base_freq, zone->v.rate_offset,
- zone->v.root, zone->v.tune, zone->v.low, zone->v.high);
-#endif
-
- /* detuning is ignored */
- /* 6points volume envelope */
- if (patch.mode & WAVE_ENVELOPES) {
- int attack, hold, decay, release;
- attack = calc_gus_envelope_time
- (patch.env_rate[0], 0, patch.env_offset[0]);
- hold = calc_gus_envelope_time
- (patch.env_rate[1], patch.env_offset[0],
- patch.env_offset[1]);
- decay = calc_gus_envelope_time
- (patch.env_rate[2], patch.env_offset[1],
- patch.env_offset[2]);
- release = calc_gus_envelope_time
- (patch.env_rate[3], patch.env_offset[1],
- patch.env_offset[4]);
- release += calc_gus_envelope_time
- (patch.env_rate[4], patch.env_offset[3],
- patch.env_offset[4]);
- release += calc_gus_envelope_time
- (patch.env_rate[5], patch.env_offset[4],
- patch.env_offset[5]);
- zone->v.parm.volatkhld =
- (snd_sf_calc_parm_hold(hold) << 8) |
- snd_sf_calc_parm_attack(attack);
- zone->v.parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
- snd_sf_calc_parm_decay(decay);
- zone->v.parm.volrelease = 0x8000 | snd_sf_calc_parm_decay(release);
- zone->v.attenuation = calc_gus_attenuation(patch.env_offset[0]);
-#if 0
- snd_printk(KERN_DEBUG
- "gus: atkhld=%x, dcysus=%x, volrel=%x, att=%d\n",
- zone->v.parm.volatkhld,
- zone->v.parm.voldcysus,
- zone->v.parm.volrelease,
- zone->v.attenuation);
-#endif
- }
-
- /* fast release */
- if (patch.mode & WAVE_FAST_RELEASE) {
- zone->v.parm.volrelease = 0x807f;
- }
-
- /* tremolo effect */
- if (patch.mode & WAVE_TREMOLO) {
- int rate = (patch.tremolo_rate * 1000 / 38) / 42;
- zone->v.parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
- }
- /* vibrato effect */
- if (patch.mode & WAVE_VIBRATO) {
- int rate = (patch.vibrato_rate * 1000 / 38) / 42;
- zone->v.parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
- }
-
- /* scale_freq, scale_factor, volume, and fractions not implemented */
-
- if (!(smp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT))
- zone->v.mode = SNDRV_SFNT_MODE_LOOPING;
- else
- zone->v.mode = 0;
-
- /* append to the tail of the list */
- /*zone->bank = ctrls[AWE_MD_GUS_BANK];*/
- zone->bank = 0;
- zone->instr = patch.instr_no;
- zone->mapped = 0;
- zone->v.sf_id = sf->id;
-
- zone->sample = set_sample(sf, &zone->v);
-
- /* rebuild preset now */
- add_preset(sflist, zone);
-
- return 0;
-}
-
-/* load GUS patch */
-int
-snd_soundfont_load_guspatch(struct snd_sf_list *sflist, const char __user *data,
- long count, int client)
-{
- int rc;
- lock_preset(sflist);
- rc = load_guspatch(sflist, data, count, client);
- unlock_preset(sflist);
- return rc;
-}
-
-
-/*
- * Rebuild the preset table. This is like a hash table in that it allows
- * quick access to the zone information. For each preset there are zone
- * structures linked by next_instr and by next_zone. Former is the whole
- * link for this preset, and latter is the link for zone (i.e. instrument/
- * bank/key combination).
- */
-static void
-rebuild_presets(struct snd_sf_list *sflist)
-{
- struct snd_soundfont *sf;
- struct snd_sf_zone *cur;
-
- /* clear preset table */
- memset(sflist->presets, 0, sizeof(sflist->presets));
-
- /* search all fonts and insert each font */
- for (sf = sflist->fonts; sf; sf = sf->next) {
- for (cur = sf->zones; cur; cur = cur->next) {
- if (! cur->mapped && cur->sample == NULL) {
- /* try again to search the corresponding sample */
- cur->sample = set_sample(sf, &cur->v);
- if (cur->sample == NULL)
- continue;
- }
-
- add_preset(sflist, cur);
- }
- }
-}
-
-
-/*
- * add the given zone to preset table
- */
-static void
-add_preset(struct snd_sf_list *sflist, struct snd_sf_zone *cur)
-{
- struct snd_sf_zone *zone;
- int index;
-
- zone = search_first_zone(sflist, cur->bank, cur->instr, cur->v.low);
- if (zone && zone->v.sf_id != cur->v.sf_id) {
- /* different instrument was already defined */
- struct snd_sf_zone *p;
- /* compare the allocated time */
- for (p = zone; p; p = p->next_zone) {
- if (p->counter > cur->counter)
- /* the current is older.. skipped */
- return;
- }
- /* remove old zones */
- delete_preset(sflist, zone);
- zone = NULL; /* do not forget to clear this! */
- }
-
- /* prepend this zone */
- if ((index = get_index(cur->bank, cur->instr, cur->v.low)) < 0)
- return;
- cur->next_zone = zone; /* zone link */
- cur->next_instr = sflist->presets[index]; /* preset table link */
- sflist->presets[index] = cur;
-}
-
-/*
- * delete the given zones from preset_table
- */
-static void
-delete_preset(struct snd_sf_list *sflist, struct snd_sf_zone *zp)
-{
- int index;
- struct snd_sf_zone *p;
-
- if ((index = get_index(zp->bank, zp->instr, zp->v.low)) < 0)
- return;
- for (p = sflist->presets[index]; p; p = p->next_instr) {
- while (p->next_instr == zp) {
- p->next_instr = zp->next_instr;
- zp = zp->next_zone;
- if (zp == NULL)
- return;
- }
- }
-}
-
-
-/*
- * Search matching zones from preset table.
- * The note can be rewritten by preset mapping (alias).
- * The found zones are stored on 'table' array. max_layers defines
- * the maximum number of elements in this array.
- * This function returns the number of found zones. 0 if not found.
- */
-int
-snd_soundfont_search_zone(struct snd_sf_list *sflist, int *notep, int vel,
- int preset, int bank,
- int def_preset, int def_bank,
- struct snd_sf_zone **table, int max_layers)
-{
- int nvoices;
- unsigned long flags;
-
- /* this function is supposed to be called atomically,
- * so we check the lock. if it's busy, just returns 0 to
- * tell the caller the busy state
- */
- spin_lock_irqsave(&sflist->lock, flags);
- if (sflist->presets_locked) {
- spin_unlock_irqrestore(&sflist->lock, flags);
- return 0;
- }
- nvoices = search_zones(sflist, notep, vel, preset, bank,
- table, max_layers, 0);
- if (! nvoices) {
- if (preset != def_preset || bank != def_bank)
- nvoices = search_zones(sflist, notep, vel,
- def_preset, def_bank,
- table, max_layers, 0);
- }
- spin_unlock_irqrestore(&sflist->lock, flags);
- return nvoices;
-}
-
-
-/*
- * search the first matching zone
- */
-static struct snd_sf_zone *
-search_first_zone(struct snd_sf_list *sflist, int bank, int preset, int key)
-{
- int index;
- struct snd_sf_zone *zp;
-
- if ((index = get_index(bank, preset, key)) < 0)
- return NULL;
- for (zp = sflist->presets[index]; zp; zp = zp->next_instr) {
- if (zp->instr == preset && zp->bank == bank)
- return zp;
- }
- return NULL;
-}
-
-
-/*
- * search matching zones from sflist. can be called recursively.
- */
-static int
-search_zones(struct snd_sf_list *sflist, int *notep, int vel,
- int preset, int bank, struct snd_sf_zone **table,
- int max_layers, int level)
-{
- struct snd_sf_zone *zp;
- int nvoices;
-
- zp = search_first_zone(sflist, bank, preset, *notep);
- nvoices = 0;
- for (; zp; zp = zp->next_zone) {
- if (*notep >= zp->v.low && *notep <= zp->v.high &&
- vel >= zp->v.vellow && vel <= zp->v.velhigh) {
- if (zp->mapped) {
- /* search preset mapping (aliasing) */
- int key = zp->v.fixkey;
- preset = zp->v.start;
- bank = zp->v.end;
-
- if (level > 5) /* too deep alias level */
- return 0;
- if (key < 0)
- key = *notep;
- nvoices = search_zones(sflist, &key, vel,
- preset, bank, table,
- max_layers, level + 1);
- if (nvoices > 0)
- *notep = key;
- break;
- }
- table[nvoices++] = zp;
- if (nvoices >= max_layers)
- break;
- }
- }
-
- return nvoices;
-}
-
-
-/* calculate the index of preset table:
- * drums are mapped from 128 to 255 according to its note key.
- * other instruments are mapped from 0 to 127.
- * if the index is out of range, return -1.
- */
-static int
-get_index(int bank, int instr, int key)
-{
- int index;
- if (SF_IS_DRUM_BANK(bank))
- index = key + SF_MAX_INSTRUMENTS;
- else
- index = instr;
- index = index % SF_MAX_PRESETS;
- if (index < 0)
- return -1;
- return index;
-}
-
-/*
- * Initialise the sflist structure.
- */
-static void
-snd_sf_init(struct snd_sf_list *sflist)
-{
- memset(sflist->presets, 0, sizeof(sflist->presets));
-
- sflist->mem_used = 0;
- sflist->currsf = NULL;
- sflist->open_client = -1;
- sflist->fonts = NULL;
- sflist->fonts_size = 0;
- sflist->zone_counter = 0;
- sflist->sample_counter = 0;
- sflist->zone_locked = 0;
- sflist->sample_locked = 0;
-}
-
-/*
- * Release all list records
- */
-static void
-snd_sf_clear(struct snd_sf_list *sflist)
-{
- struct snd_soundfont *sf, *nextsf;
- struct snd_sf_zone *zp, *nextzp;
- struct snd_sf_sample *sp, *nextsp;
-
- for (sf = sflist->fonts; sf; sf = nextsf) {
- nextsf = sf->next;
- for (zp = sf->zones; zp; zp = nextzp) {
- nextzp = zp->next;
- kfree(zp);
- }
- for (sp = sf->samples; sp; sp = nextsp) {
- nextsp = sp->next;
- if (sflist->callback.sample_free)
- sflist->callback.sample_free(sflist->callback.private_data,
- sp, sflist->memhdr);
- kfree(sp);
- }
- kfree(sf);
- }
-
- snd_sf_init(sflist);
-}
-
-
-/*
- * Create a new sflist structure
- */
-struct snd_sf_list *
-snd_sf_new(struct snd_sf_callback *callback, struct snd_util_memhdr *hdr)
-{
- struct snd_sf_list *sflist;
-
- if ((sflist = kzalloc(sizeof(*sflist), GFP_KERNEL)) == NULL)
- return NULL;
-
- mutex_init(&sflist->presets_mutex);
- spin_lock_init(&sflist->lock);
- sflist->memhdr = hdr;
-
- if (callback)
- sflist->callback = *callback;
-
- snd_sf_init(sflist);
- return sflist;
-}
-
-
-/*
- * Free everything allocated off the sflist structure.
- */
-void
-snd_sf_free(struct snd_sf_list *sflist)
-{
- if (sflist == NULL)
- return;
-
- lock_preset(sflist);
- if (sflist->callback.sample_reset)
- sflist->callback.sample_reset(sflist->callback.private_data);
- snd_sf_clear(sflist);
- unlock_preset(sflist);
-
- kfree(sflist);
-}
-
-/*
- * Remove all samples
- * The soundcard should be silet before calling this function.
- */
-int
-snd_soundfont_remove_samples(struct snd_sf_list *sflist)
-{
- lock_preset(sflist);
- if (sflist->callback.sample_reset)
- sflist->callback.sample_reset(sflist->callback.private_data);
- snd_sf_clear(sflist);
- unlock_preset(sflist);
-
- return 0;
-}
-
-/*
- * Remove unlocked samples.
- * The soundcard should be silent before calling this function.
- */
-int
-snd_soundfont_remove_unlocked(struct snd_sf_list *sflist)
-{
- struct snd_soundfont *sf;
- struct snd_sf_zone *zp, *nextzp;
- struct snd_sf_sample *sp, *nextsp;
-
- lock_preset(sflist);
-
- if (sflist->callback.sample_reset)
- sflist->callback.sample_reset(sflist->callback.private_data);
-
- /* to be sure */
- memset(sflist->presets, 0, sizeof(sflist->presets));
-
- for (sf = sflist->fonts; sf; sf = sf->next) {
- for (zp = sf->zones; zp; zp = nextzp) {
- if (zp->counter < sflist->zone_locked)
- break;
- nextzp = zp->next;
- sf->zones = nextzp;
- kfree(zp);
- }
-
- for (sp = sf->samples; sp; sp = nextsp) {
- if (sp->counter < sflist->sample_locked)
- break;
- nextsp = sp->next;
- sf->samples = nextsp;
- sflist->mem_used -= sp->v.truesize;
- if (sflist->callback.sample_free)
- sflist->callback.sample_free(sflist->callback.private_data,
- sp, sflist->memhdr);
- kfree(sp);
- }
- }
-
- sflist->zone_counter = sflist->zone_locked;
- sflist->sample_counter = sflist->sample_locked;
-
- rebuild_presets(sflist);
-
- unlock_preset(sflist);
- return 0;
-}
diff --git a/ANDROID_3.4.5/sound/synth/util_mem.c b/ANDROID_3.4.5/sound/synth/util_mem.c
deleted file mode 100644
index 8e34bc4e..00000000
--- a/ANDROID_3.4.5/sound/synth/util_mem.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
- *
- * Generic memory management routines for soundcard memory allocation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/mutex.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/util_mem.h>
-
-MODULE_AUTHOR("Takashi Iwai");
-MODULE_DESCRIPTION("Generic memory management routines for soundcard memory allocation");
-MODULE_LICENSE("GPL");
-
-#define get_memblk(p) list_entry(p, struct snd_util_memblk, list)
-
-/*
- * create a new memory manager
- */
-struct snd_util_memhdr *
-snd_util_memhdr_new(int memsize)
-{
- struct snd_util_memhdr *hdr;
-
- hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
- if (hdr == NULL)
- return NULL;
- hdr->size = memsize;
- mutex_init(&hdr->block_mutex);
- INIT_LIST_HEAD(&hdr->block);
-
- return hdr;
-}
-
-/*
- * free a memory manager
- */
-void snd_util_memhdr_free(struct snd_util_memhdr *hdr)
-{
- struct list_head *p;
-
- if (!hdr)
- return;
- /* release all blocks */
- while ((p = hdr->block.next) != &hdr->block) {
- list_del(p);
- kfree(get_memblk(p));
- }
- kfree(hdr);
-}
-
-/*
- * allocate a memory block (without mutex)
- */
-struct snd_util_memblk *
-__snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size)
-{
- struct snd_util_memblk *blk;
- unsigned int units, prev_offset;
- struct list_head *p;
-
- if (snd_BUG_ON(!hdr || size <= 0))
- return NULL;
-
- /* word alignment */
- units = size;
- if (units & 1)
- units++;
- if (units > hdr->size)
- return NULL;
-
- /* look for empty block */
- prev_offset = 0;
- list_for_each(p, &hdr->block) {
- blk = get_memblk(p);
- if (blk->offset - prev_offset >= units)
- goto __found;
- prev_offset = blk->offset + blk->size;
- }
- if (hdr->size - prev_offset < units)
- return NULL;
-
-__found:
- return __snd_util_memblk_new(hdr, units, p->prev);
-}
-
-
-/*
- * create a new memory block with the given size
- * the block is linked next to prev
- */
-struct snd_util_memblk *
-__snd_util_memblk_new(struct snd_util_memhdr *hdr, unsigned int units,
- struct list_head *prev)
-{
- struct snd_util_memblk *blk;
-
- blk = kmalloc(sizeof(struct snd_util_memblk) + hdr->block_extra_size,
- GFP_KERNEL);
- if (blk == NULL)
- return NULL;
-
- if (prev == &hdr->block)
- blk->offset = 0;
- else {
- struct snd_util_memblk *p = get_memblk(prev);
- blk->offset = p->offset + p->size;
- }
- blk->size = units;
- list_add(&blk->list, prev);
- hdr->nblocks++;
- hdr->used += units;
- return blk;
-}
-
-
-/*
- * allocate a memory block (with mutex)
- */
-struct snd_util_memblk *
-snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size)
-{
- struct snd_util_memblk *blk;
- mutex_lock(&hdr->block_mutex);
- blk = __snd_util_mem_alloc(hdr, size);
- mutex_unlock(&hdr->block_mutex);
- return blk;
-}
-
-
-/*
- * remove the block from linked-list and free resource
- * (without mutex)
- */
-void
-__snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk)
-{
- list_del(&blk->list);
- hdr->nblocks--;
- hdr->used -= blk->size;
- kfree(blk);
-}
-
-/*
- * free a memory block (with mutex)
- */
-int snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk)
-{
- if (snd_BUG_ON(!hdr || !blk))
- return -EINVAL;
-
- mutex_lock(&hdr->block_mutex);
- __snd_util_mem_free(hdr, blk);
- mutex_unlock(&hdr->block_mutex);
- return 0;
-}
-
-/*
- * return available memory size
- */
-int snd_util_mem_avail(struct snd_util_memhdr *hdr)
-{
- unsigned int size;
- mutex_lock(&hdr->block_mutex);
- size = hdr->size - hdr->used;
- mutex_unlock(&hdr->block_mutex);
- return size;
-}
-
-
-EXPORT_SYMBOL(snd_util_memhdr_new);
-EXPORT_SYMBOL(snd_util_memhdr_free);
-EXPORT_SYMBOL(snd_util_mem_alloc);
-EXPORT_SYMBOL(snd_util_mem_free);
-EXPORT_SYMBOL(snd_util_mem_avail);
-EXPORT_SYMBOL(__snd_util_mem_alloc);
-EXPORT_SYMBOL(__snd_util_mem_free);
-EXPORT_SYMBOL(__snd_util_memblk_new);
-
-/*
- * INIT part
- */
-
-static int __init alsa_util_mem_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_util_mem_exit(void)
-{
-}
-
-module_init(alsa_util_mem_init)
-module_exit(alsa_util_mem_exit)
diff --git a/ANDROID_3.4.5/sound/usb/6fire/Makefile b/ANDROID_3.4.5/sound/usb/6fire/Makefile
deleted file mode 100644
index dfce6ec5..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-snd-usb-6fire-objs += chip.o comm.o midi.o control.o firmware.o pcm.o
-obj-$(CONFIG_SND_USB_6FIRE) += snd-usb-6fire.o
-
diff --git a/ANDROID_3.4.5/sound/usb/6fire/chip.c b/ANDROID_3.4.5/sound/usb/6fire/chip.c
deleted file mode 100644
index fc8cc823..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/chip.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Main routines and module definitions.
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include "chip.h"
-#include "firmware.h"
-#include "pcm.h"
-#include "control.h"
-#include "comm.h"
-#include "midi.h"
-
-#include <linux/moduleparam.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/gfp.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Torsten Schenk <torsten.schenk@zoho.com>");
-MODULE_DESCRIPTION("TerraTec DMX 6Fire USB audio driver");
-MODULE_LICENSE("GPL v2");
-MODULE_SUPPORTED_DEVICE("{{TerraTec, DMX 6Fire USB}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable card */
-static struct sfire_chip *chips[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
-static struct usb_device *devices[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for the 6fire sound device");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for the 6fire sound device.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable the 6fire sound device.");
-
-static DEFINE_MUTEX(register_mutex);
-
-static void usb6fire_chip_abort(struct sfire_chip *chip)
-{
- if (chip) {
- if (chip->pcm)
- usb6fire_pcm_abort(chip);
- if (chip->midi)
- usb6fire_midi_abort(chip);
- if (chip->comm)
- usb6fire_comm_abort(chip);
- if (chip->control)
- usb6fire_control_abort(chip);
- if (chip->card) {
- snd_card_disconnect(chip->card);
- snd_card_free_when_closed(chip->card);
- chip->card = NULL;
- }
- }
-}
-
-static void usb6fire_chip_destroy(struct sfire_chip *chip)
-{
- if (chip) {
- if (chip->pcm)
- usb6fire_pcm_destroy(chip);
- if (chip->midi)
- usb6fire_midi_destroy(chip);
- if (chip->comm)
- usb6fire_comm_destroy(chip);
- if (chip->control)
- usb6fire_control_destroy(chip);
- if (chip->card)
- snd_card_free(chip->card);
- }
-}
-
-static int __devinit usb6fire_chip_probe(struct usb_interface *intf,
- const struct usb_device_id *usb_id)
-{
- int ret;
- int i;
- struct sfire_chip *chip = NULL;
- struct usb_device *device = interface_to_usbdev(intf);
- int regidx = -1; /* index in module parameter array */
- struct snd_card *card = NULL;
-
- /* look if we already serve this card and return if so */
- mutex_lock(&register_mutex);
- for (i = 0; i < SNDRV_CARDS; i++) {
- if (devices[i] == device) {
- if (chips[i])
- chips[i]->intf_count++;
- usb_set_intfdata(intf, chips[i]);
- mutex_unlock(&register_mutex);
- return 0;
- } else if (regidx < 0)
- regidx = i;
- }
- if (regidx < 0) {
- mutex_unlock(&register_mutex);
- snd_printk(KERN_ERR PREFIX "too many cards registered.\n");
- return -ENODEV;
- }
- devices[regidx] = device;
- mutex_unlock(&register_mutex);
-
- /* check, if firmware is present on device, upload it if not */
- ret = usb6fire_fw_init(intf);
- if (ret < 0)
- return ret;
- else if (ret == FW_NOT_READY) /* firmware update performed */
- return 0;
-
- /* if we are here, card can be registered in alsa. */
- if (usb_set_interface(device, 0, 0) != 0) {
- snd_printk(KERN_ERR PREFIX "can't set first interface.\n");
- return -EIO;
- }
- ret = snd_card_create(index[regidx], id[regidx], THIS_MODULE,
- sizeof(struct sfire_chip), &card);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "cannot create alsa card.\n");
- return ret;
- }
- strcpy(card->driver, "6FireUSB");
- strcpy(card->shortname, "TerraTec DMX6FireUSB");
- sprintf(card->longname, "%s at %d:%d", card->shortname,
- device->bus->busnum, device->devnum);
- snd_card_set_dev(card, &intf->dev);
-
- chip = card->private_data;
- chips[regidx] = chip;
- chip->dev = device;
- chip->regidx = regidx;
- chip->intf_count = 1;
- chip->card = card;
-
- ret = usb6fire_comm_init(chip);
- if (ret < 0) {
- usb6fire_chip_destroy(chip);
- return ret;
- }
-
- ret = usb6fire_midi_init(chip);
- if (ret < 0) {
- usb6fire_chip_destroy(chip);
- return ret;
- }
-
- ret = usb6fire_pcm_init(chip);
- if (ret < 0) {
- usb6fire_chip_destroy(chip);
- return ret;
- }
-
- ret = usb6fire_control_init(chip);
- if (ret < 0) {
- usb6fire_chip_destroy(chip);
- return ret;
- }
-
- ret = snd_card_register(card);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "cannot register card.");
- usb6fire_chip_destroy(chip);
- return ret;
- }
- usb_set_intfdata(intf, chip);
- return 0;
-}
-
-static void usb6fire_chip_disconnect(struct usb_interface *intf)
-{
- struct sfire_chip *chip;
- struct snd_card *card;
-
- chip = usb_get_intfdata(intf);
- if (chip) { /* if !chip, fw upload has been performed */
- card = chip->card;
- chip->intf_count--;
- if (!chip->intf_count) {
- mutex_lock(&register_mutex);
- devices[chip->regidx] = NULL;
- chips[chip->regidx] = NULL;
- mutex_unlock(&register_mutex);
-
- chip->shutdown = true;
- usb6fire_chip_abort(chip);
- usb6fire_chip_destroy(chip);
- }
- }
-}
-
-static struct usb_device_id device_table[] = {
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x0ccd,
- .idProduct = 0x0080
- },
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, device_table);
-
-static struct usb_driver usb_driver = {
- .name = "snd-usb-6fire",
- .probe = usb6fire_chip_probe,
- .disconnect = usb6fire_chip_disconnect,
- .id_table = device_table,
-};
-
-module_usb_driver(usb_driver);
diff --git a/ANDROID_3.4.5/sound/usb/6fire/chip.h b/ANDROID_3.4.5/sound/usb/6fire/chip.h
deleted file mode 100644
index bde02d10..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/chip.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-#ifndef USB6FIRE_CHIP_H
-#define USB6FIRE_CHIP_H
-
-#include "common.h"
-
-struct sfire_chip {
- struct usb_device *dev;
- struct snd_card *card;
- int intf_count; /* number of registered interfaces */
- int regidx; /* index in module parameter arrays */
- bool shutdown;
-
- struct midi_runtime *midi;
- struct pcm_runtime *pcm;
- struct control_runtime *control;
- struct comm_runtime *comm;
-};
-#endif /* USB6FIRE_CHIP_H */
-
diff --git a/ANDROID_3.4.5/sound/usb/6fire/comm.c b/ANDROID_3.4.5/sound/usb/6fire/comm.c
deleted file mode 100644
index 6c3d531a..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/comm.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Device communications
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include "comm.h"
-#include "chip.h"
-#include "midi.h"
-
-enum {
- COMM_EP = 1,
- COMM_FPGA_EP = 2
-};
-
-static void usb6fire_comm_init_urb(struct comm_runtime *rt, struct urb *urb,
- u8 *buffer, void *context, void(*handler)(struct urb *urb))
-{
- usb_init_urb(urb);
- urb->transfer_buffer = buffer;
- urb->pipe = usb_sndintpipe(rt->chip->dev, COMM_EP);
- urb->complete = handler;
- urb->context = context;
- urb->interval = 1;
- urb->dev = rt->chip->dev;
-}
-
-static void usb6fire_comm_receiver_handler(struct urb *urb)
-{
- struct comm_runtime *rt = urb->context;
- struct midi_runtime *midi_rt = rt->chip->midi;
-
- if (!urb->status) {
- if (rt->receiver_buffer[0] == 0x10) /* midi in event */
- if (midi_rt)
- midi_rt->in_received(midi_rt,
- rt->receiver_buffer + 2,
- rt->receiver_buffer[1]);
- }
-
- if (!rt->chip->shutdown) {
- urb->status = 0;
- urb->actual_length = 0;
- if (usb_submit_urb(urb, GFP_ATOMIC) < 0)
- snd_printk(KERN_WARNING PREFIX
- "comm data receiver aborted.\n");
- }
-}
-
-static void usb6fire_comm_init_buffer(u8 *buffer, u8 id, u8 request,
- u8 reg, u8 vl, u8 vh)
-{
- buffer[0] = 0x01;
- buffer[2] = request;
- buffer[3] = id;
- switch (request) {
- case 0x02:
- buffer[1] = 0x05; /* length (starting at buffer[2]) */
- buffer[4] = reg;
- buffer[5] = vl;
- buffer[6] = vh;
- break;
-
- case 0x12:
- buffer[1] = 0x0b; /* length (starting at buffer[2]) */
- buffer[4] = 0x00;
- buffer[5] = 0x18;
- buffer[6] = 0x05;
- buffer[7] = 0x00;
- buffer[8] = 0x01;
- buffer[9] = 0x00;
- buffer[10] = 0x9e;
- buffer[11] = reg;
- buffer[12] = vl;
- break;
-
- case 0x20:
- case 0x21:
- case 0x22:
- buffer[1] = 0x04;
- buffer[4] = reg;
- buffer[5] = vl;
- break;
- }
-}
-
-static int usb6fire_comm_send_buffer(u8 *buffer, struct usb_device *dev)
-{
- int ret;
- int actual_len;
-
- ret = usb_interrupt_msg(dev, usb_sndintpipe(dev, COMM_EP),
- buffer, buffer[1] + 2, &actual_len, HZ);
- if (ret < 0)
- return ret;
- else if (actual_len != buffer[1] + 2)
- return -EIO;
- return 0;
-}
-
-static int usb6fire_comm_write8(struct comm_runtime *rt, u8 request,
- u8 reg, u8 value)
-{
- u8 buffer[13]; /* 13: maximum length of message */
-
- usb6fire_comm_init_buffer(buffer, 0x00, request, reg, value, 0x00);
- return usb6fire_comm_send_buffer(buffer, rt->chip->dev);
-}
-
-static int usb6fire_comm_write16(struct comm_runtime *rt, u8 request,
- u8 reg, u8 vl, u8 vh)
-{
- u8 buffer[13]; /* 13: maximum length of message */
-
- usb6fire_comm_init_buffer(buffer, 0x00, request, reg, vl, vh);
- return usb6fire_comm_send_buffer(buffer, rt->chip->dev);
-}
-
-int __devinit usb6fire_comm_init(struct sfire_chip *chip)
-{
- struct comm_runtime *rt = kzalloc(sizeof(struct comm_runtime),
- GFP_KERNEL);
- struct urb *urb = &rt->receiver;
- int ret;
-
- if (!rt)
- return -ENOMEM;
-
- rt->serial = 1;
- rt->chip = chip;
- usb_init_urb(urb);
- rt->init_urb = usb6fire_comm_init_urb;
- rt->write8 = usb6fire_comm_write8;
- rt->write16 = usb6fire_comm_write16;
-
- /* submit an urb that receives communication data from device */
- urb->transfer_buffer = rt->receiver_buffer;
- urb->transfer_buffer_length = COMM_RECEIVER_BUFSIZE;
- urb->pipe = usb_rcvintpipe(chip->dev, COMM_EP);
- urb->dev = chip->dev;
- urb->complete = usb6fire_comm_receiver_handler;
- urb->context = rt;
- urb->interval = 1;
- ret = usb_submit_urb(urb, GFP_KERNEL);
- if (ret < 0) {
- kfree(rt);
- snd_printk(KERN_ERR PREFIX "cannot create comm data receiver.");
- return ret;
- }
- chip->comm = rt;
- return 0;
-}
-
-void usb6fire_comm_abort(struct sfire_chip *chip)
-{
- struct comm_runtime *rt = chip->comm;
-
- if (rt)
- usb_poison_urb(&rt->receiver);
-}
-
-void usb6fire_comm_destroy(struct sfire_chip *chip)
-{
- kfree(chip->comm);
- chip->comm = NULL;
-}
diff --git a/ANDROID_3.4.5/sound/usb/6fire/comm.h b/ANDROID_3.4.5/sound/usb/6fire/comm.h
deleted file mode 100644
index d2af0a5d..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/comm.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-#ifndef USB6FIRE_COMM_H
-#define USB6FIRE_COMM_H
-
-#include "common.h"
-
-enum /* settings for comm */
-{
- COMM_RECEIVER_BUFSIZE = 64,
-};
-
-struct comm_runtime {
- struct sfire_chip *chip;
-
- struct urb receiver;
- u8 receiver_buffer[COMM_RECEIVER_BUFSIZE];
-
- u8 serial; /* urb serial */
-
- void (*init_urb)(struct comm_runtime *rt, struct urb *urb, u8 *buffer,
- void *context, void(*handler)(struct urb *urb));
- /* writes control data to the device */
- int (*write8)(struct comm_runtime *rt, u8 request, u8 reg, u8 value);
- int (*write16)(struct comm_runtime *rt, u8 request, u8 reg,
- u8 vh, u8 vl);
-};
-
-int __devinit usb6fire_comm_init(struct sfire_chip *chip);
-void usb6fire_comm_abort(struct sfire_chip *chip);
-void usb6fire_comm_destroy(struct sfire_chip *chip);
-#endif /* USB6FIRE_COMM_H */
-
diff --git a/ANDROID_3.4.5/sound/usb/6fire/common.h b/ANDROID_3.4.5/sound/usb/6fire/common.h
deleted file mode 100644
index b6eb03ed..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/common.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef USB6FIRE_COMMON_H
-#define USB6FIRE_COMMON_H
-
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <sound/core.h>
-
-#define PREFIX "6fire: "
-
-struct sfire_chip;
-struct midi_runtime;
-struct pcm_runtime;
-struct control_runtime;
-struct comm_runtime;
-#endif /* USB6FIRE_COMMON_H */
-
diff --git a/ANDROID_3.4.5/sound/usb/6fire/control.c b/ANDROID_3.4.5/sound/usb/6fire/control.c
deleted file mode 100644
index 07ed914d..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/control.c
+++ /dev/null
@@ -1,631 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Mixer control
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * Thanks to:
- * - Holger Ruckdeschel: he found out how to control individual channel
- * volumes and introduced mute switch
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/interrupt.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-
-#include "control.h"
-#include "comm.h"
-#include "chip.h"
-
-static char *opt_coax_texts[2] = { "Optical", "Coax" };
-static char *line_phono_texts[2] = { "Line", "Phono" };
-
-/*
- * data that needs to be sent to device. sets up card internal stuff.
- * values dumped from windows driver and filtered by trial'n'error.
- */
-static const struct {
- u8 type;
- u8 reg;
- u8 value;
-}
-init_data[] = {
- { 0x22, 0x00, 0x00 }, { 0x20, 0x00, 0x08 }, { 0x22, 0x01, 0x01 },
- { 0x20, 0x01, 0x08 }, { 0x22, 0x02, 0x00 }, { 0x20, 0x02, 0x08 },
- { 0x22, 0x03, 0x00 }, { 0x20, 0x03, 0x08 }, { 0x22, 0x04, 0x00 },
- { 0x20, 0x04, 0x08 }, { 0x22, 0x05, 0x01 }, { 0x20, 0x05, 0x08 },
- { 0x22, 0x04, 0x01 }, { 0x12, 0x04, 0x00 }, { 0x12, 0x05, 0x00 },
- { 0x12, 0x0d, 0x38 }, { 0x12, 0x21, 0x82 }, { 0x12, 0x22, 0x80 },
- { 0x12, 0x23, 0x00 }, { 0x12, 0x06, 0x02 }, { 0x12, 0x03, 0x00 },
- { 0x12, 0x02, 0x00 }, { 0x22, 0x03, 0x01 },
- { 0 } /* TERMINATING ENTRY */
-};
-
-static const int rates_altsetting[] = { 1, 1, 2, 2, 3, 3 };
-/* values to write to soundcard register for all samplerates */
-static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01};
-static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00};
-
-static DECLARE_TLV_DB_MINMAX(tlv_output, -9000, 0);
-static DECLARE_TLV_DB_MINMAX(tlv_input, -1500, 1500);
-
-enum {
- DIGITAL_THRU_ONLY_SAMPLERATE = 3
-};
-
-static void usb6fire_control_output_vol_update(struct control_runtime *rt)
-{
- struct comm_runtime *comm_rt = rt->chip->comm;
- int i;
-
- if (comm_rt)
- for (i = 0; i < 6; i++)
- if (!(rt->ovol_updated & (1 << i))) {
- comm_rt->write8(comm_rt, 0x12, 0x0f + i,
- 180 - rt->output_vol[i]);
- rt->ovol_updated |= 1 << i;
- }
-}
-
-static void usb6fire_control_output_mute_update(struct control_runtime *rt)
-{
- struct comm_runtime *comm_rt = rt->chip->comm;
-
- if (comm_rt)
- comm_rt->write8(comm_rt, 0x12, 0x0e, ~rt->output_mute);
-}
-
-static void usb6fire_control_input_vol_update(struct control_runtime *rt)
-{
- struct comm_runtime *comm_rt = rt->chip->comm;
- int i;
-
- if (comm_rt)
- for (i = 0; i < 2; i++)
- if (!(rt->ivol_updated & (1 << i))) {
- comm_rt->write8(comm_rt, 0x12, 0x1c + i,
- rt->input_vol[i] & 0x3f);
- rt->ivol_updated |= 1 << i;
- }
-}
-
-static void usb6fire_control_line_phono_update(struct control_runtime *rt)
-{
- struct comm_runtime *comm_rt = rt->chip->comm;
- if (comm_rt) {
- comm_rt->write8(comm_rt, 0x22, 0x02, rt->line_phono_switch);
- comm_rt->write8(comm_rt, 0x21, 0x02, rt->line_phono_switch);
- }
-}
-
-static void usb6fire_control_opt_coax_update(struct control_runtime *rt)
-{
- struct comm_runtime *comm_rt = rt->chip->comm;
- if (comm_rt) {
- comm_rt->write8(comm_rt, 0x22, 0x00, rt->opt_coax_switch);
- comm_rt->write8(comm_rt, 0x21, 0x00, rt->opt_coax_switch);
- }
-}
-
-static int usb6fire_control_set_rate(struct control_runtime *rt, int rate)
-{
- int ret;
- struct usb_device *device = rt->chip->dev;
- struct comm_runtime *comm_rt = rt->chip->comm;
-
- if (rate < 0 || rate >= CONTROL_N_RATES)
- return -EINVAL;
-
- ret = usb_set_interface(device, 1, rates_altsetting[rate]);
- if (ret < 0)
- return ret;
-
- /* set soundcard clock */
- ret = comm_rt->write16(comm_rt, 0x02, 0x01, rates_6fire_vl[rate],
- rates_6fire_vh[rate]);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int usb6fire_control_set_channels(
- struct control_runtime *rt, int n_analog_out,
- int n_analog_in, bool spdif_out, bool spdif_in)
-{
- int ret;
- struct comm_runtime *comm_rt = rt->chip->comm;
-
- /* enable analog inputs and outputs
- * (one bit per stereo-channel) */
- ret = comm_rt->write16(comm_rt, 0x02, 0x02,
- (1 << (n_analog_out / 2)) - 1,
- (1 << (n_analog_in / 2)) - 1);
- if (ret < 0)
- return ret;
-
- /* disable digital inputs and outputs */
- /* TODO: use spdif_x to enable/disable digital channels */
- ret = comm_rt->write16(comm_rt, 0x02, 0x03, 0x00, 0x00);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int usb6fire_control_streaming_update(struct control_runtime *rt)
-{
- struct comm_runtime *comm_rt = rt->chip->comm;
-
- if (comm_rt) {
- if (!rt->usb_streaming && rt->digital_thru_switch)
- usb6fire_control_set_rate(rt,
- DIGITAL_THRU_ONLY_SAMPLERATE);
- return comm_rt->write16(comm_rt, 0x02, 0x00, 0x00,
- (rt->usb_streaming ? 0x01 : 0x00) |
- (rt->digital_thru_switch ? 0x08 : 0x00));
- }
- return -EINVAL;
-}
-
-static int usb6fire_control_output_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 180;
- return 0;
-}
-
-static int usb6fire_control_output_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- unsigned int ch = kcontrol->private_value;
- int changed = 0;
-
- if (ch > 4) {
- snd_printk(KERN_ERR PREFIX "Invalid channel in volume control.");
- return -EINVAL;
- }
-
- if (rt->output_vol[ch] != ucontrol->value.integer.value[0]) {
- rt->output_vol[ch] = ucontrol->value.integer.value[0];
- rt->ovol_updated &= ~(1 << ch);
- changed = 1;
- }
- if (rt->output_vol[ch + 1] != ucontrol->value.integer.value[1]) {
- rt->output_vol[ch + 1] = ucontrol->value.integer.value[1];
- rt->ovol_updated &= ~(2 << ch);
- changed = 1;
- }
-
- if (changed)
- usb6fire_control_output_vol_update(rt);
-
- return changed;
-}
-
-static int usb6fire_control_output_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- unsigned int ch = kcontrol->private_value;
-
- if (ch > 4) {
- snd_printk(KERN_ERR PREFIX "Invalid channel in volume control.");
- return -EINVAL;
- }
-
- ucontrol->value.integer.value[0] = rt->output_vol[ch];
- ucontrol->value.integer.value[1] = rt->output_vol[ch + 1];
- return 0;
-}
-
-static int usb6fire_control_output_mute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- unsigned int ch = kcontrol->private_value;
- u8 old = rt->output_mute;
- u8 value = 0;
-
- if (ch > 4) {
- snd_printk(KERN_ERR PREFIX "Invalid channel in volume control.");
- return -EINVAL;
- }
-
- rt->output_mute &= ~(3 << ch);
- if (ucontrol->value.integer.value[0])
- value |= 1;
- if (ucontrol->value.integer.value[1])
- value |= 2;
- rt->output_mute |= value << ch;
-
- if (rt->output_mute != old)
- usb6fire_control_output_mute_update(rt);
-
- return rt->output_mute != old;
-}
-
-static int usb6fire_control_output_mute_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- unsigned int ch = kcontrol->private_value;
- u8 value = rt->output_mute >> ch;
-
- if (ch > 4) {
- snd_printk(KERN_ERR PREFIX "Invalid channel in volume control.");
- return -EINVAL;
- }
-
- ucontrol->value.integer.value[0] = 1 & value;
- value >>= 1;
- ucontrol->value.integer.value[1] = 1 & value;
-
- return 0;
-}
-
-static int usb6fire_control_input_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 30;
- return 0;
-}
-
-static int usb6fire_control_input_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- int changed = 0;
-
- if (rt->input_vol[0] != ucontrol->value.integer.value[0]) {
- rt->input_vol[0] = ucontrol->value.integer.value[0] - 15;
- rt->ivol_updated &= ~(1 << 0);
- changed = 1;
- }
- if (rt->input_vol[1] != ucontrol->value.integer.value[1]) {
- rt->input_vol[1] = ucontrol->value.integer.value[1] - 15;
- rt->ivol_updated &= ~(1 << 1);
- changed = 1;
- }
-
- if (changed)
- usb6fire_control_input_vol_update(rt);
-
- return changed;
-}
-
-static int usb6fire_control_input_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = rt->input_vol[0] + 15;
- ucontrol->value.integer.value[1] = rt->input_vol[1] + 15;
-
- return 0;
-}
-
-static int usb6fire_control_line_phono_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item > 1)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name,
- line_phono_texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int usb6fire_control_line_phono_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- if (rt->line_phono_switch != ucontrol->value.integer.value[0]) {
- rt->line_phono_switch = ucontrol->value.integer.value[0];
- usb6fire_control_line_phono_update(rt);
- changed = 1;
- }
- return changed;
-}
-
-static int usb6fire_control_line_phono_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = rt->line_phono_switch;
- return 0;
-}
-
-static int usb6fire_control_opt_coax_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item > 1)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name,
- opt_coax_texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int usb6fire_control_opt_coax_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- int changed = 0;
-
- if (rt->opt_coax_switch != ucontrol->value.enumerated.item[0]) {
- rt->opt_coax_switch = ucontrol->value.enumerated.item[0];
- usb6fire_control_opt_coax_update(rt);
- changed = 1;
- }
- return changed;
-}
-
-static int usb6fire_control_opt_coax_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = rt->opt_coax_switch;
- return 0;
-}
-
-static int usb6fire_control_digital_thru_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- int changed = 0;
-
- if (rt->digital_thru_switch != ucontrol->value.integer.value[0]) {
- rt->digital_thru_switch = ucontrol->value.integer.value[0];
- usb6fire_control_streaming_update(rt);
- changed = 1;
- }
- return changed;
-}
-
-static int usb6fire_control_digital_thru_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = rt->digital_thru_switch;
- return 0;
-}
-
-static struct __devinitdata snd_kcontrol_new vol_elements[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Playback Volume",
- .index = 0,
- .private_value = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = usb6fire_control_output_vol_info,
- .get = usb6fire_control_output_vol_get,
- .put = usb6fire_control_output_vol_put,
- .tlv = { .p = tlv_output }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Playback Volume",
- .index = 1,
- .private_value = 2,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = usb6fire_control_output_vol_info,
- .get = usb6fire_control_output_vol_get,
- .put = usb6fire_control_output_vol_put,
- .tlv = { .p = tlv_output }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Playback Volume",
- .index = 2,
- .private_value = 4,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = usb6fire_control_output_vol_info,
- .get = usb6fire_control_output_vol_get,
- .put = usb6fire_control_output_vol_put,
- .tlv = { .p = tlv_output }
- },
- {}
-};
-
-static struct __devinitdata snd_kcontrol_new mute_elements[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Playback Switch",
- .index = 0,
- .private_value = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = snd_ctl_boolean_stereo_info,
- .get = usb6fire_control_output_mute_get,
- .put = usb6fire_control_output_mute_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Playback Switch",
- .index = 1,
- .private_value = 2,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = snd_ctl_boolean_stereo_info,
- .get = usb6fire_control_output_mute_get,
- .put = usb6fire_control_output_mute_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Playback Switch",
- .index = 2,
- .private_value = 4,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = snd_ctl_boolean_stereo_info,
- .get = usb6fire_control_output_mute_get,
- .put = usb6fire_control_output_mute_put,
- },
- {}
-};
-
-static struct __devinitdata snd_kcontrol_new elements[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Line/Phono Capture Route",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = usb6fire_control_line_phono_info,
- .get = usb6fire_control_line_phono_get,
- .put = usb6fire_control_line_phono_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Opt/Coax Capture Route",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = usb6fire_control_opt_coax_info,
- .get = usb6fire_control_opt_coax_get,
- .put = usb6fire_control_opt_coax_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Digital Thru Playback Route",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = snd_ctl_boolean_mono_info,
- .get = usb6fire_control_digital_thru_get,
- .put = usb6fire_control_digital_thru_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Capture Volume",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = usb6fire_control_input_vol_info,
- .get = usb6fire_control_input_vol_get,
- .put = usb6fire_control_input_vol_put,
- .tlv = { .p = tlv_input }
- },
- {}
-};
-
-static int usb6fire_control_add_virtual(
- struct control_runtime *rt,
- struct snd_card *card,
- char *name,
- struct snd_kcontrol_new *elems)
-{
- int ret;
- int i;
- struct snd_kcontrol *vmaster =
- snd_ctl_make_virtual_master(name, tlv_output);
- struct snd_kcontrol *control;
-
- if (!vmaster)
- return -ENOMEM;
- ret = snd_ctl_add(card, vmaster);
- if (ret < 0)
- return ret;
-
- i = 0;
- while (elems[i].name) {
- control = snd_ctl_new1(&elems[i], rt);
- if (!control)
- return -ENOMEM;
- ret = snd_ctl_add(card, control);
- if (ret < 0)
- return ret;
- ret = snd_ctl_add_slave(vmaster, control);
- if (ret < 0)
- return ret;
- i++;
- }
- return 0;
-}
-
-int __devinit usb6fire_control_init(struct sfire_chip *chip)
-{
- int i;
- int ret;
- struct control_runtime *rt = kzalloc(sizeof(struct control_runtime),
- GFP_KERNEL);
- struct comm_runtime *comm_rt = chip->comm;
-
- if (!rt)
- return -ENOMEM;
-
- rt->chip = chip;
- rt->update_streaming = usb6fire_control_streaming_update;
- rt->set_rate = usb6fire_control_set_rate;
- rt->set_channels = usb6fire_control_set_channels;
-
- i = 0;
- while (init_data[i].type) {
- comm_rt->write8(comm_rt, init_data[i].type, init_data[i].reg,
- init_data[i].value);
- i++;
- }
-
- usb6fire_control_opt_coax_update(rt);
- usb6fire_control_line_phono_update(rt);
- usb6fire_control_output_vol_update(rt);
- usb6fire_control_output_mute_update(rt);
- usb6fire_control_input_vol_update(rt);
- usb6fire_control_streaming_update(rt);
-
- ret = usb6fire_control_add_virtual(rt, chip->card,
- "Master Playback Volume", vol_elements);
- if (ret) {
- snd_printk(KERN_ERR PREFIX "cannot add control.\n");
- kfree(rt);
- return ret;
- }
- ret = usb6fire_control_add_virtual(rt, chip->card,
- "Master Playback Switch", mute_elements);
- if (ret) {
- snd_printk(KERN_ERR PREFIX "cannot add control.\n");
- kfree(rt);
- return ret;
- }
-
- i = 0;
- while (elements[i].name) {
- ret = snd_ctl_add(chip->card, snd_ctl_new1(&elements[i], rt));
- if (ret < 0) {
- kfree(rt);
- snd_printk(KERN_ERR PREFIX "cannot add control.\n");
- return ret;
- }
- i++;
- }
-
- chip->control = rt;
- return 0;
-}
-
-void usb6fire_control_abort(struct sfire_chip *chip)
-{}
-
-void usb6fire_control_destroy(struct sfire_chip *chip)
-{
- kfree(chip->control);
- chip->control = NULL;
-}
diff --git a/ANDROID_3.4.5/sound/usb/6fire/control.h b/ANDROID_3.4.5/sound/usb/6fire/control.h
deleted file mode 100644
index 9a596d95..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/control.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef USB6FIRE_CONTROL_H
-#define USB6FIRE_CONTROL_H
-
-#include "common.h"
-
-enum {
- CONTROL_MAX_ELEMENTS = 32
-};
-
-enum {
- CONTROL_RATE_44KHZ,
- CONTROL_RATE_48KHZ,
- CONTROL_RATE_88KHZ,
- CONTROL_RATE_96KHZ,
- CONTROL_RATE_176KHZ,
- CONTROL_RATE_192KHZ,
- CONTROL_N_RATES
-};
-
-struct control_runtime {
- int (*update_streaming)(struct control_runtime *rt);
- int (*set_rate)(struct control_runtime *rt, int rate);
- int (*set_channels)(struct control_runtime *rt, int n_analog_out,
- int n_analog_in, bool spdif_out, bool spdif_in);
-
- struct sfire_chip *chip;
-
- struct snd_kcontrol *element[CONTROL_MAX_ELEMENTS];
- bool opt_coax_switch;
- bool line_phono_switch;
- bool digital_thru_switch;
- bool usb_streaming;
- u8 output_vol[6];
- u8 ovol_updated;
- u8 output_mute;
- s8 input_vol[2];
- u8 ivol_updated;
-};
-
-int __devinit usb6fire_control_init(struct sfire_chip *chip);
-void usb6fire_control_abort(struct sfire_chip *chip);
-void usb6fire_control_destroy(struct sfire_chip *chip);
-#endif /* USB6FIRE_CONTROL_H */
-
diff --git a/ANDROID_3.4.5/sound/usb/6fire/firmware.c b/ANDROID_3.4.5/sound/usb/6fire/firmware.c
deleted file mode 100644
index 6f9715ab..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/firmware.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Firmware loader
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/firmware.h>
-#include <linux/module.h>
-#include <linux/bitrev.h>
-#include <linux/kernel.h>
-
-#include "firmware.h"
-#include "chip.h"
-
-MODULE_FIRMWARE("6fire/dmx6firel2.ihx");
-MODULE_FIRMWARE("6fire/dmx6fireap.ihx");
-MODULE_FIRMWARE("6fire/dmx6firecf.bin");
-
-enum {
- FPGA_BUFSIZE = 512, FPGA_EP = 2
-};
-
-/*
- * wMaxPacketSize of pcm endpoints.
- * keep synced with rates_in_packet_size and rates_out_packet_size in pcm.c
- * fpp: frames per isopacket
- *
- * CAUTION: keep sizeof <= buffer[] in usb6fire_fw_init
- */
-static const u8 ep_w_max_packet_size[] = {
- 0xe4, 0x00, 0xe4, 0x00, /* alt 1: 228 EP2 and EP6 (7 fpp) */
- 0xa4, 0x01, 0xa4, 0x01, /* alt 2: 420 EP2 and EP6 (13 fpp)*/
- 0x94, 0x01, 0x5c, 0x02 /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */
-};
-
-static const u8 known_fw_versions[][4] = {
- { 0x03, 0x01, 0x0b, 0x00 }
-};
-
-struct ihex_record {
- u16 address;
- u8 len;
- u8 data[256];
- char error; /* true if an error occurred parsing this record */
-
- u8 max_len; /* maximum record length in whole ihex */
-
- /* private */
- const char *txt_data;
- unsigned int txt_length;
- unsigned int txt_offset; /* current position in txt_data */
-};
-
-static u8 usb6fire_fw_ihex_hex(const u8 *data, u8 *crc)
-{
- u8 val = 0;
- int hval;
-
- hval = hex_to_bin(data[0]);
- if (hval >= 0)
- val |= (hval << 4);
-
- hval = hex_to_bin(data[1]);
- if (hval >= 0)
- val |= hval;
-
- *crc += val;
- return val;
-}
-
-/*
- * returns true if record is available, false otherwise.
- * iff an error occurred, false will be returned and record->error will be true.
- */
-static bool usb6fire_fw_ihex_next_record(struct ihex_record *record)
-{
- u8 crc = 0;
- u8 type;
- int i;
-
- record->error = false;
-
- /* find begin of record (marked by a colon) */
- while (record->txt_offset < record->txt_length
- && record->txt_data[record->txt_offset] != ':')
- record->txt_offset++;
- if (record->txt_offset == record->txt_length)
- return false;
-
- /* number of characters needed for len, addr and type entries */
- record->txt_offset++;
- if (record->txt_offset + 8 > record->txt_length) {
- record->error = true;
- return false;
- }
-
- record->len = usb6fire_fw_ihex_hex(record->txt_data +
- record->txt_offset, &crc);
- record->txt_offset += 2;
- record->address = usb6fire_fw_ihex_hex(record->txt_data +
- record->txt_offset, &crc) << 8;
- record->txt_offset += 2;
- record->address |= usb6fire_fw_ihex_hex(record->txt_data +
- record->txt_offset, &crc);
- record->txt_offset += 2;
- type = usb6fire_fw_ihex_hex(record->txt_data +
- record->txt_offset, &crc);
- record->txt_offset += 2;
-
- /* number of characters needed for data and crc entries */
- if (record->txt_offset + 2 * (record->len + 1) > record->txt_length) {
- record->error = true;
- return false;
- }
- for (i = 0; i < record->len; i++) {
- record->data[i] = usb6fire_fw_ihex_hex(record->txt_data
- + record->txt_offset, &crc);
- record->txt_offset += 2;
- }
- usb6fire_fw_ihex_hex(record->txt_data + record->txt_offset, &crc);
- if (crc) {
- record->error = true;
- return false;
- }
-
- if (type == 1 || !record->len) /* eof */
- return false;
- else if (type == 0)
- return true;
- else {
- record->error = true;
- return false;
- }
-}
-
-static int usb6fire_fw_ihex_init(const struct firmware *fw,
- struct ihex_record *record)
-{
- record->txt_data = fw->data;
- record->txt_length = fw->size;
- record->txt_offset = 0;
- record->max_len = 0;
- /* read all records, if loop ends, record->error indicates,
- * whether ihex is valid. */
- while (usb6fire_fw_ihex_next_record(record))
- record->max_len = max(record->len, record->max_len);
- if (record->error)
- return -EINVAL;
- record->txt_offset = 0;
- return 0;
-}
-
-static int usb6fire_fw_ezusb_write(struct usb_device *device,
- int type, int value, char *data, int len)
-{
- int ret;
-
- ret = usb_control_msg(device, usb_sndctrlpipe(device, 0), type,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, 0, data, len, HZ);
- if (ret < 0)
- return ret;
- else if (ret != len)
- return -EIO;
- return 0;
-}
-
-static int usb6fire_fw_ezusb_read(struct usb_device *device,
- int type, int value, char *data, int len)
-{
- int ret = usb_control_msg(device, usb_rcvctrlpipe(device, 0), type,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value,
- 0, data, len, HZ);
- if (ret < 0)
- return ret;
- else if (ret != len)
- return -EIO;
- return 0;
-}
-
-static int usb6fire_fw_fpga_write(struct usb_device *device,
- char *data, int len)
-{
- int actual_len;
- int ret;
-
- ret = usb_bulk_msg(device, usb_sndbulkpipe(device, FPGA_EP), data, len,
- &actual_len, HZ);
- if (ret < 0)
- return ret;
- else if (actual_len != len)
- return -EIO;
- return 0;
-}
-
-static int usb6fire_fw_ezusb_upload(
- struct usb_interface *intf, const char *fwname,
- unsigned int postaddr, u8 *postdata, unsigned int postlen)
-{
- int ret;
- u8 data;
- struct usb_device *device = interface_to_usbdev(intf);
- const struct firmware *fw = 0;
- struct ihex_record *rec = kmalloc(sizeof(struct ihex_record),
- GFP_KERNEL);
-
- if (!rec)
- return -ENOMEM;
-
- ret = request_firmware(&fw, fwname, &device->dev);
- if (ret < 0) {
- kfree(rec);
- snd_printk(KERN_ERR PREFIX "error requesting ezusb "
- "firmware %s.\n", fwname);
- return ret;
- }
- ret = usb6fire_fw_ihex_init(fw, rec);
- if (ret < 0) {
- kfree(rec);
- release_firmware(fw);
- snd_printk(KERN_ERR PREFIX "error validating ezusb "
- "firmware %s.\n", fwname);
- return ret;
- }
- /* upload firmware image */
- data = 0x01; /* stop ezusb cpu */
- ret = usb6fire_fw_ezusb_write(device, 0xa0, 0xe600, &data, 1);
- if (ret < 0) {
- kfree(rec);
- release_firmware(fw);
- snd_printk(KERN_ERR PREFIX "unable to upload ezusb "
- "firmware %s: begin message.\n", fwname);
- return ret;
- }
-
- while (usb6fire_fw_ihex_next_record(rec)) { /* write firmware */
- ret = usb6fire_fw_ezusb_write(device, 0xa0, rec->address,
- rec->data, rec->len);
- if (ret < 0) {
- kfree(rec);
- release_firmware(fw);
- snd_printk(KERN_ERR PREFIX "unable to upload ezusb "
- "firmware %s: data urb.\n", fwname);
- return ret;
- }
- }
-
- release_firmware(fw);
- kfree(rec);
- if (postdata) { /* write data after firmware has been uploaded */
- ret = usb6fire_fw_ezusb_write(device, 0xa0, postaddr,
- postdata, postlen);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "unable to upload ezusb "
- "firmware %s: post urb.\n", fwname);
- return ret;
- }
- }
-
- data = 0x00; /* resume ezusb cpu */
- ret = usb6fire_fw_ezusb_write(device, 0xa0, 0xe600, &data, 1);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "unable to upload ezusb "
- "firmware %s: end message.\n", fwname);
- return ret;
- }
- return 0;
-}
-
-static int usb6fire_fw_fpga_upload(
- struct usb_interface *intf, const char *fwname)
-{
- int ret;
- int i;
- struct usb_device *device = interface_to_usbdev(intf);
- u8 *buffer = kmalloc(FPGA_BUFSIZE, GFP_KERNEL);
- const char *c;
- const char *end;
- const struct firmware *fw;
-
- if (!buffer)
- return -ENOMEM;
-
- ret = request_firmware(&fw, fwname, &device->dev);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "unable to get fpga firmware %s.\n",
- fwname);
- kfree(buffer);
- return -EIO;
- }
-
- c = fw->data;
- end = fw->data + fw->size;
-
- ret = usb6fire_fw_ezusb_write(device, 8, 0, NULL, 0);
- if (ret < 0) {
- kfree(buffer);
- release_firmware(fw);
- snd_printk(KERN_ERR PREFIX "unable to upload fpga firmware: "
- "begin urb.\n");
- return ret;
- }
-
- while (c != end) {
- for (i = 0; c != end && i < FPGA_BUFSIZE; i++, c++)
- buffer[i] = byte_rev_table[(u8) *c];
-
- ret = usb6fire_fw_fpga_write(device, buffer, i);
- if (ret < 0) {
- release_firmware(fw);
- kfree(buffer);
- snd_printk(KERN_ERR PREFIX "unable to upload fpga "
- "firmware: fw urb.\n");
- return ret;
- }
- }
- release_firmware(fw);
- kfree(buffer);
-
- ret = usb6fire_fw_ezusb_write(device, 9, 0, NULL, 0);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "unable to upload fpga firmware: "
- "end urb.\n");
- return ret;
- }
- return 0;
-}
-
-/* check, if the firmware version the devices has currently loaded
- * is known by this driver. 'version' needs to have 4 bytes version
- * info data. */
-static int usb6fire_fw_check(u8 *version)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(known_fw_versions); i++)
- if (!memcmp(version, known_fw_versions + i, 4))
- return 0;
-
- snd_printk(KERN_ERR PREFIX "invalid fimware version in device: "
- "%02x %02x %02x %02x. "
- "please reconnect to power. if this failure "
- "still happens, check your firmware installation.",
- version[0], version[1], version[2], version[3]);
- return -EINVAL;
-}
-
-int usb6fire_fw_init(struct usb_interface *intf)
-{
- int i;
- int ret;
- struct usb_device *device = interface_to_usbdev(intf);
- /* buffer: 8 receiving bytes from device and
- * sizeof(EP_W_MAX_PACKET_SIZE) bytes for non-const copy */
- u8 buffer[12];
-
- ret = usb6fire_fw_ezusb_read(device, 1, 0, buffer, 8);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "unable to receive device "
- "firmware state.\n");
- return ret;
- }
- if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55) {
- snd_printk(KERN_ERR PREFIX "unknown device firmware state "
- "received from device: ");
- for (i = 0; i < 8; i++)
- snd_printk("%02x ", buffer[i]);
- snd_printk("\n");
- return -EIO;
- }
- /* do we need fpga loader ezusb firmware? */
- if (buffer[3] == 0x01) {
- ret = usb6fire_fw_ezusb_upload(intf,
- "6fire/dmx6firel2.ihx", 0, NULL, 0);
- if (ret < 0)
- return ret;
- return FW_NOT_READY;
- }
- /* do we need fpga firmware and application ezusb firmware? */
- else if (buffer[3] == 0x02) {
- ret = usb6fire_fw_check(buffer + 4);
- if (ret < 0)
- return ret;
- ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin");
- if (ret < 0)
- return ret;
- memcpy(buffer, ep_w_max_packet_size,
- sizeof(ep_w_max_packet_size));
- ret = usb6fire_fw_ezusb_upload(intf, "6fire/dmx6fireap.ihx",
- 0x0003, buffer, sizeof(ep_w_max_packet_size));
- if (ret < 0)
- return ret;
- return FW_NOT_READY;
- }
- /* all fw loaded? */
- else if (buffer[3] == 0x03)
- return usb6fire_fw_check(buffer + 4);
- /* unknown data? */
- else {
- snd_printk(KERN_ERR PREFIX "unknown device firmware state "
- "received from device: ");
- for (i = 0; i < 8; i++)
- snd_printk("%02x ", buffer[i]);
- snd_printk("\n");
- return -EIO;
- }
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/6fire/firmware.h b/ANDROID_3.4.5/sound/usb/6fire/firmware.h
deleted file mode 100644
index 00856989..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/firmware.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Author: Torsten Schenk
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef USB6FIRE_FIRMWARE_H
-#define USB6FIRE_FIRMWARE_H
-
-#include "common.h"
-
-enum /* firmware state of device */
-{
- FW_READY = 0,
- FW_NOT_READY = 1
-};
-
-int __devinit usb6fire_fw_init(struct usb_interface *intf);
-#endif /* USB6FIRE_FIRMWARE_H */
-
diff --git a/ANDROID_3.4.5/sound/usb/6fire/midi.c b/ANDROID_3.4.5/sound/usb/6fire/midi.c
deleted file mode 100644
index f0e5179b..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/midi.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Rawmidi driver
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <sound/rawmidi.h>
-
-#include "midi.h"
-#include "chip.h"
-#include "comm.h"
-
-static void usb6fire_midi_out_handler(struct urb *urb)
-{
- struct midi_runtime *rt = urb->context;
- int ret;
- unsigned long flags;
-
- spin_lock_irqsave(&rt->out_lock, flags);
-
- if (rt->out) {
- ret = snd_rawmidi_transmit(rt->out, rt->out_buffer + 4,
- MIDI_BUFSIZE - 4);
- if (ret > 0) { /* more data available, send next packet */
- rt->out_buffer[1] = ret + 2;
- rt->out_buffer[3] = rt->out_serial++;
- urb->transfer_buffer_length = ret + 4;
-
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret < 0)
- snd_printk(KERN_ERR PREFIX "midi out urb "
- "submit failed: %d\n", ret);
- } else /* no more data to transmit */
- rt->out = NULL;
- }
- spin_unlock_irqrestore(&rt->out_lock, flags);
-}
-
-static void usb6fire_midi_in_received(
- struct midi_runtime *rt, u8 *data, int length)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&rt->in_lock, flags);
- if (rt->in)
- snd_rawmidi_receive(rt->in, data, length);
- spin_unlock_irqrestore(&rt->in_lock, flags);
-}
-
-static int usb6fire_midi_out_open(struct snd_rawmidi_substream *alsa_sub)
-{
- return 0;
-}
-
-static int usb6fire_midi_out_close(struct snd_rawmidi_substream *alsa_sub)
-{
- return 0;
-}
-
-static void usb6fire_midi_out_trigger(
- struct snd_rawmidi_substream *alsa_sub, int up)
-{
- struct midi_runtime *rt = alsa_sub->rmidi->private_data;
- struct urb *urb = &rt->out_urb;
- __s8 ret;
- unsigned long flags;
-
- spin_lock_irqsave(&rt->out_lock, flags);
- if (up) { /* start transfer */
- if (rt->out) { /* we are already transmitting so just return */
- spin_unlock_irqrestore(&rt->out_lock, flags);
- return;
- }
-
- ret = snd_rawmidi_transmit(alsa_sub, rt->out_buffer + 4,
- MIDI_BUFSIZE - 4);
- if (ret > 0) {
- rt->out_buffer[1] = ret + 2;
- rt->out_buffer[3] = rt->out_serial++;
- urb->transfer_buffer_length = ret + 4;
-
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret < 0)
- snd_printk(KERN_ERR PREFIX "midi out urb "
- "submit failed: %d\n", ret);
- else
- rt->out = alsa_sub;
- }
- } else if (rt->out == alsa_sub)
- rt->out = NULL;
- spin_unlock_irqrestore(&rt->out_lock, flags);
-}
-
-static void usb6fire_midi_out_drain(struct snd_rawmidi_substream *alsa_sub)
-{
- struct midi_runtime *rt = alsa_sub->rmidi->private_data;
- int retry = 0;
-
- while (rt->out && retry++ < 100)
- msleep(10);
-}
-
-static int usb6fire_midi_in_open(struct snd_rawmidi_substream *alsa_sub)
-{
- return 0;
-}
-
-static int usb6fire_midi_in_close(struct snd_rawmidi_substream *alsa_sub)
-{
- return 0;
-}
-
-static void usb6fire_midi_in_trigger(
- struct snd_rawmidi_substream *alsa_sub, int up)
-{
- struct midi_runtime *rt = alsa_sub->rmidi->private_data;
- unsigned long flags;
-
- spin_lock_irqsave(&rt->in_lock, flags);
- if (up)
- rt->in = alsa_sub;
- else
- rt->in = NULL;
- spin_unlock_irqrestore(&rt->in_lock, flags);
-}
-
-static struct snd_rawmidi_ops out_ops = {
- .open = usb6fire_midi_out_open,
- .close = usb6fire_midi_out_close,
- .trigger = usb6fire_midi_out_trigger,
- .drain = usb6fire_midi_out_drain
-};
-
-static struct snd_rawmidi_ops in_ops = {
- .open = usb6fire_midi_in_open,
- .close = usb6fire_midi_in_close,
- .trigger = usb6fire_midi_in_trigger
-};
-
-int __devinit usb6fire_midi_init(struct sfire_chip *chip)
-{
- int ret;
- struct midi_runtime *rt = kzalloc(sizeof(struct midi_runtime),
- GFP_KERNEL);
- struct comm_runtime *comm_rt = chip->comm;
-
- if (!rt)
- return -ENOMEM;
-
- rt->chip = chip;
- rt->in_received = usb6fire_midi_in_received;
- rt->out_buffer[0] = 0x80; /* 'send midi' command */
- rt->out_buffer[1] = 0x00; /* size of data */
- rt->out_buffer[2] = 0x00; /* always 0 */
- spin_lock_init(&rt->in_lock);
- spin_lock_init(&rt->out_lock);
-
- comm_rt->init_urb(comm_rt, &rt->out_urb, rt->out_buffer, rt,
- usb6fire_midi_out_handler);
-
- ret = snd_rawmidi_new(chip->card, "6FireUSB", 0, 1, 1, &rt->instance);
- if (ret < 0) {
- kfree(rt);
- snd_printk(KERN_ERR PREFIX "unable to create midi.\n");
- return ret;
- }
- rt->instance->private_data = rt;
- strcpy(rt->instance->name, "DMX6FireUSB MIDI");
- rt->instance->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
- snd_rawmidi_set_ops(rt->instance, SNDRV_RAWMIDI_STREAM_OUTPUT,
- &out_ops);
- snd_rawmidi_set_ops(rt->instance, SNDRV_RAWMIDI_STREAM_INPUT,
- &in_ops);
-
- chip->midi = rt;
- return 0;
-}
-
-void usb6fire_midi_abort(struct sfire_chip *chip)
-{
- struct midi_runtime *rt = chip->midi;
-
- if (rt)
- usb_poison_urb(&rt->out_urb);
-}
-
-void usb6fire_midi_destroy(struct sfire_chip *chip)
-{
- kfree(chip->midi);
- chip->midi = NULL;
-}
diff --git a/ANDROID_3.4.5/sound/usb/6fire/midi.h b/ANDROID_3.4.5/sound/usb/6fire/midi.h
deleted file mode 100644
index 5114eccc..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/midi.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef USB6FIRE_MIDI_H
-#define USB6FIRE_MIDI_H
-
-#include "common.h"
-
-enum {
- MIDI_BUFSIZE = 64
-};
-
-struct midi_runtime {
- struct sfire_chip *chip;
- struct snd_rawmidi *instance;
-
- struct snd_rawmidi_substream *in;
- char in_active;
-
- spinlock_t in_lock;
- spinlock_t out_lock;
- struct snd_rawmidi_substream *out;
- struct urb out_urb;
- u8 out_serial; /* serial number of out packet */
- u8 out_buffer[MIDI_BUFSIZE];
- int buffer_offset;
-
- void (*in_received)(struct midi_runtime *rt, u8 *data, int length);
-};
-
-int __devinit usb6fire_midi_init(struct sfire_chip *chip);
-void usb6fire_midi_abort(struct sfire_chip *chip);
-void usb6fire_midi_destroy(struct sfire_chip *chip);
-#endif /* USB6FIRE_MIDI_H */
-
diff --git a/ANDROID_3.4.5/sound/usb/6fire/pcm.c b/ANDROID_3.4.5/sound/usb/6fire/pcm.c
deleted file mode 100644
index c97d05f0..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/pcm.c
+++ /dev/null
@@ -1,666 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * PCM driver
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include "pcm.h"
-#include "chip.h"
-#include "comm.h"
-#include "control.h"
-
-enum {
- OUT_N_CHANNELS = 6, IN_N_CHANNELS = 4
-};
-
-/* keep next two synced with
- * FW_EP_W_MAX_PACKET_SIZE[] and RATES_MAX_PACKET_SIZE
- * and CONTROL_RATE_XXX in control.h */
-static const int rates_in_packet_size[] = { 228, 228, 420, 420, 404, 404 };
-static const int rates_out_packet_size[] = { 228, 228, 420, 420, 604, 604 };
-static const int rates[] = { 44100, 48000, 88200, 96000, 176400, 192000 };
-static const int rates_alsaid[] = {
- SNDRV_PCM_RATE_44100, SNDRV_PCM_RATE_48000,
- SNDRV_PCM_RATE_88200, SNDRV_PCM_RATE_96000,
- SNDRV_PCM_RATE_176400, SNDRV_PCM_RATE_192000 };
-
-enum { /* settings for pcm */
- OUT_EP = 6, IN_EP = 2, MAX_BUFSIZE = 128 * 1024
-};
-
-enum { /* pcm streaming states */
- STREAM_DISABLED, /* no pcm streaming */
- STREAM_STARTING, /* pcm streaming requested, waiting to become ready */
- STREAM_RUNNING, /* pcm streaming running */
- STREAM_STOPPING
-};
-
-static const struct snd_pcm_hardware pcm_hw = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BATCH,
-
- .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
-
- .rates = SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000 |
- SNDRV_PCM_RATE_176400 |
- SNDRV_PCM_RATE_192000,
-
- .rate_min = 44100,
- .rate_max = 192000,
- .channels_min = 1,
- .channels_max = 0, /* set in pcm_open, depending on capture/playback */
- .buffer_bytes_max = MAX_BUFSIZE,
- .period_bytes_min = PCM_N_PACKETS_PER_URB * (PCM_MAX_PACKET_SIZE - 4),
- .period_bytes_max = MAX_BUFSIZE,
- .periods_min = 2,
- .periods_max = 1024
-};
-
-static int usb6fire_pcm_set_rate(struct pcm_runtime *rt)
-{
- int ret;
- struct control_runtime *ctrl_rt = rt->chip->control;
-
- ctrl_rt->usb_streaming = false;
- ret = ctrl_rt->update_streaming(ctrl_rt);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "error stopping streaming while "
- "setting samplerate %d.\n", rates[rt->rate]);
- return ret;
- }
-
- ret = ctrl_rt->set_rate(ctrl_rt, rt->rate);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "error setting samplerate %d.\n",
- rates[rt->rate]);
- return ret;
- }
-
- ret = ctrl_rt->set_channels(ctrl_rt, OUT_N_CHANNELS, IN_N_CHANNELS,
- false, false);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "error initializing channels "
- "while setting samplerate %d.\n",
- rates[rt->rate]);
- return ret;
- }
-
- ctrl_rt->usb_streaming = true;
- ret = ctrl_rt->update_streaming(ctrl_rt);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "error starting streaming while "
- "setting samplerate %d.\n", rates[rt->rate]);
- return ret;
- }
-
- rt->in_n_analog = IN_N_CHANNELS;
- rt->out_n_analog = OUT_N_CHANNELS;
- rt->in_packet_size = rates_in_packet_size[rt->rate];
- rt->out_packet_size = rates_out_packet_size[rt->rate];
- return 0;
-}
-
-static struct pcm_substream *usb6fire_pcm_get_substream(
- struct snd_pcm_substream *alsa_sub)
-{
- struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
-
- if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
- return &rt->playback;
- else if (alsa_sub->stream == SNDRV_PCM_STREAM_CAPTURE)
- return &rt->capture;
- snd_printk(KERN_ERR PREFIX "error getting pcm substream slot.\n");
- return NULL;
-}
-
-/* call with stream_mutex locked */
-static void usb6fire_pcm_stream_stop(struct pcm_runtime *rt)
-{
- int i;
- struct control_runtime *ctrl_rt = rt->chip->control;
-
- if (rt->stream_state != STREAM_DISABLED) {
- for (i = 0; i < PCM_N_URBS; i++) {
- usb_kill_urb(&rt->in_urbs[i].instance);
- usb_kill_urb(&rt->out_urbs[i].instance);
- }
- ctrl_rt->usb_streaming = false;
- ctrl_rt->update_streaming(ctrl_rt);
- rt->stream_state = STREAM_DISABLED;
- }
-}
-
-/* call with stream_mutex locked */
-static int usb6fire_pcm_stream_start(struct pcm_runtime *rt)
-{
- int ret;
- int i;
- int k;
- struct usb_iso_packet_descriptor *packet;
-
- if (rt->stream_state == STREAM_DISABLED) {
- /* submit our in urbs */
- rt->stream_wait_cond = false;
- rt->stream_state = STREAM_STARTING;
- for (i = 0; i < PCM_N_URBS; i++) {
- for (k = 0; k < PCM_N_PACKETS_PER_URB; k++) {
- packet = &rt->in_urbs[i].packets[k];
- packet->offset = k * rt->in_packet_size;
- packet->length = rt->in_packet_size;
- packet->actual_length = 0;
- packet->status = 0;
- }
- ret = usb_submit_urb(&rt->in_urbs[i].instance,
- GFP_ATOMIC);
- if (ret) {
- usb6fire_pcm_stream_stop(rt);
- return ret;
- }
- }
-
- /* wait for first out urb to return (sent in in urb handler) */
- wait_event_timeout(rt->stream_wait_queue, rt->stream_wait_cond,
- HZ);
- if (rt->stream_wait_cond)
- rt->stream_state = STREAM_RUNNING;
- else {
- usb6fire_pcm_stream_stop(rt);
- return -EIO;
- }
- }
- return 0;
-}
-
-/* call with substream locked */
-static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb)
-{
- int i;
- int frame;
- int frame_count;
- unsigned int total_length = 0;
- struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance);
- struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
- u32 *src = NULL;
- u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off
- * (alsa_rt->frame_bits >> 3));
- u32 *dest_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size
- * (alsa_rt->frame_bits >> 3));
- int bytes_per_frame = alsa_rt->channels << 2;
-
- for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
- /* at least 4 header bytes for valid packet.
- * after that: 32 bits per sample for analog channels */
- if (urb->packets[i].actual_length > 4)
- frame_count = (urb->packets[i].actual_length - 4)
- / (rt->in_n_analog << 2);
- else
- frame_count = 0;
-
- if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE)
- src = (u32 *) (urb->buffer + total_length);
- else if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE)
- src = (u32 *) (urb->buffer - 1 + total_length);
- else
- return;
- src++; /* skip leading 4 bytes of every packet */
- total_length += urb->packets[i].length;
- for (frame = 0; frame < frame_count; frame++) {
- memcpy(dest, src, bytes_per_frame);
- dest += alsa_rt->channels;
- src += rt->in_n_analog;
- sub->dma_off++;
- sub->period_off++;
- if (dest == dest_end) {
- sub->dma_off = 0;
- dest = (u32 *) alsa_rt->dma_area;
- }
- }
- }
-}
-
-/* call with substream locked */
-static void usb6fire_pcm_playback(struct pcm_substream *sub,
- struct pcm_urb *urb)
-{
- int i;
- int frame;
- int frame_count;
- struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance);
- struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
- u32 *src = (u32 *) (alsa_rt->dma_area + sub->dma_off
- * (alsa_rt->frame_bits >> 3));
- u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size
- * (alsa_rt->frame_bits >> 3));
- u32 *dest;
- int bytes_per_frame = alsa_rt->channels << 2;
-
- if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE)
- dest = (u32 *) (urb->buffer - 1);
- else if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE)
- dest = (u32 *) (urb->buffer);
- else {
- snd_printk(KERN_ERR PREFIX "Unknown sample format.");
- return;
- }
-
- for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
- /* at least 4 header bytes for valid packet.
- * after that: 32 bits per sample for analog channels */
- if (urb->packets[i].length > 4)
- frame_count = (urb->packets[i].length - 4)
- / (rt->out_n_analog << 2);
- else
- frame_count = 0;
- dest++; /* skip leading 4 bytes of every frame */
- for (frame = 0; frame < frame_count; frame++) {
- memcpy(dest, src, bytes_per_frame);
- src += alsa_rt->channels;
- dest += rt->out_n_analog;
- sub->dma_off++;
- sub->period_off++;
- if (src == src_end) {
- src = (u32 *) alsa_rt->dma_area;
- sub->dma_off = 0;
- }
- }
- }
-}
-
-static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
-{
- struct pcm_urb *in_urb = usb_urb->context;
- struct pcm_urb *out_urb = in_urb->peer;
- struct pcm_runtime *rt = in_urb->chip->pcm;
- struct pcm_substream *sub;
- unsigned long flags;
- int total_length = 0;
- int frame_count;
- int frame;
- int channel;
- int i;
- u8 *dest;
-
- if (usb_urb->status || rt->panic || rt->stream_state == STREAM_STOPPING)
- return;
- for (i = 0; i < PCM_N_PACKETS_PER_URB; i++)
- if (in_urb->packets[i].status) {
- rt->panic = true;
- return;
- }
-
- if (rt->stream_state == STREAM_DISABLED) {
- snd_printk(KERN_ERR PREFIX "internal error: "
- "stream disabled in in-urb handler.\n");
- return;
- }
-
- /* receive our capture data */
- sub = &rt->capture;
- spin_lock_irqsave(&sub->lock, flags);
- if (sub->active) {
- usb6fire_pcm_capture(sub, in_urb);
- if (sub->period_off >= sub->instance->runtime->period_size) {
- sub->period_off %= sub->instance->runtime->period_size;
- spin_unlock_irqrestore(&sub->lock, flags);
- snd_pcm_period_elapsed(sub->instance);
- } else
- spin_unlock_irqrestore(&sub->lock, flags);
- } else
- spin_unlock_irqrestore(&sub->lock, flags);
-
- /* setup out urb structure */
- for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
- out_urb->packets[i].offset = total_length;
- out_urb->packets[i].length = (in_urb->packets[i].actual_length
- - 4) / (rt->in_n_analog << 2)
- * (rt->out_n_analog << 2) + 4;
- out_urb->packets[i].status = 0;
- total_length += out_urb->packets[i].length;
- }
- memset(out_urb->buffer, 0, total_length);
-
- /* now send our playback data (if a free out urb was found) */
- sub = &rt->playback;
- spin_lock_irqsave(&sub->lock, flags);
- if (sub->active) {
- usb6fire_pcm_playback(sub, out_urb);
- if (sub->period_off >= sub->instance->runtime->period_size) {
- sub->period_off %= sub->instance->runtime->period_size;
- spin_unlock_irqrestore(&sub->lock, flags);
- snd_pcm_period_elapsed(sub->instance);
- } else
- spin_unlock_irqrestore(&sub->lock, flags);
- } else
- spin_unlock_irqrestore(&sub->lock, flags);
-
- /* setup the 4th byte of each sample (0x40 for analog channels) */
- dest = out_urb->buffer;
- for (i = 0; i < PCM_N_PACKETS_PER_URB; i++)
- if (out_urb->packets[i].length >= 4) {
- frame_count = (out_urb->packets[i].length - 4)
- / (rt->out_n_analog << 2);
- *(dest++) = 0xaa;
- *(dest++) = 0xaa;
- *(dest++) = frame_count;
- *(dest++) = 0x00;
- for (frame = 0; frame < frame_count; frame++)
- for (channel = 0;
- channel < rt->out_n_analog;
- channel++) {
- dest += 3; /* skip sample data */
- *(dest++) = 0x40;
- }
- }
- usb_submit_urb(&out_urb->instance, GFP_ATOMIC);
- usb_submit_urb(&in_urb->instance, GFP_ATOMIC);
-}
-
-static void usb6fire_pcm_out_urb_handler(struct urb *usb_urb)
-{
- struct pcm_urb *urb = usb_urb->context;
- struct pcm_runtime *rt = urb->chip->pcm;
-
- if (rt->stream_state == STREAM_STARTING) {
- rt->stream_wait_cond = true;
- wake_up(&rt->stream_wait_queue);
- }
-}
-
-static int usb6fire_pcm_open(struct snd_pcm_substream *alsa_sub)
-{
- struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
- struct pcm_substream *sub = NULL;
- struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;
-
- if (rt->panic)
- return -EPIPE;
-
- mutex_lock(&rt->stream_mutex);
- alsa_rt->hw = pcm_hw;
-
- if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (rt->rate < ARRAY_SIZE(rates))
- alsa_rt->hw.rates = rates_alsaid[rt->rate];
- alsa_rt->hw.channels_max = OUT_N_CHANNELS;
- sub = &rt->playback;
- } else if (alsa_sub->stream == SNDRV_PCM_STREAM_CAPTURE) {
- if (rt->rate < ARRAY_SIZE(rates))
- alsa_rt->hw.rates = rates_alsaid[rt->rate];
- alsa_rt->hw.channels_max = IN_N_CHANNELS;
- sub = &rt->capture;
- }
-
- if (!sub) {
- mutex_unlock(&rt->stream_mutex);
- snd_printk(KERN_ERR PREFIX "invalid stream type.\n");
- return -EINVAL;
- }
-
- sub->instance = alsa_sub;
- sub->active = false;
- mutex_unlock(&rt->stream_mutex);
- return 0;
-}
-
-static int usb6fire_pcm_close(struct snd_pcm_substream *alsa_sub)
-{
- struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
- struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
- unsigned long flags;
-
- if (rt->panic)
- return 0;
-
- mutex_lock(&rt->stream_mutex);
- if (sub) {
- /* deactivate substream */
- spin_lock_irqsave(&sub->lock, flags);
- sub->instance = NULL;
- sub->active = false;
- spin_unlock_irqrestore(&sub->lock, flags);
-
- /* all substreams closed? if so, stop streaming */
- if (!rt->playback.instance && !rt->capture.instance) {
- usb6fire_pcm_stream_stop(rt);
- rt->rate = ARRAY_SIZE(rates);
- }
- }
- mutex_unlock(&rt->stream_mutex);
- return 0;
-}
-
-static int usb6fire_pcm_hw_params(struct snd_pcm_substream *alsa_sub,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(alsa_sub,
- params_buffer_bytes(hw_params));
-}
-
-static int usb6fire_pcm_hw_free(struct snd_pcm_substream *alsa_sub)
-{
- return snd_pcm_lib_free_pages(alsa_sub);
-}
-
-static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
-{
- struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
- struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
- struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;
- int ret;
-
- if (rt->panic)
- return -EPIPE;
- if (!sub)
- return -ENODEV;
-
- mutex_lock(&rt->stream_mutex);
- sub->dma_off = 0;
- sub->period_off = 0;
-
- if (rt->stream_state == STREAM_DISABLED) {
- for (rt->rate = 0; rt->rate < ARRAY_SIZE(rates); rt->rate++)
- if (alsa_rt->rate == rates[rt->rate])
- break;
- if (rt->rate == ARRAY_SIZE(rates)) {
- mutex_unlock(&rt->stream_mutex);
- snd_printk("invalid rate %d in prepare.\n",
- alsa_rt->rate);
- return -EINVAL;
- }
-
- ret = usb6fire_pcm_set_rate(rt);
- if (ret) {
- mutex_unlock(&rt->stream_mutex);
- return ret;
- }
- ret = usb6fire_pcm_stream_start(rt);
- if (ret) {
- mutex_unlock(&rt->stream_mutex);
- snd_printk(KERN_ERR PREFIX
- "could not start pcm stream.\n");
- return ret;
- }
- }
- mutex_unlock(&rt->stream_mutex);
- return 0;
-}
-
-static int usb6fire_pcm_trigger(struct snd_pcm_substream *alsa_sub, int cmd)
-{
- struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
- struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
- unsigned long flags;
-
- if (rt->panic)
- return -EPIPE;
- if (!sub)
- return -ENODEV;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- spin_lock_irqsave(&sub->lock, flags);
- sub->active = true;
- spin_unlock_irqrestore(&sub->lock, flags);
- return 0;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- spin_lock_irqsave(&sub->lock, flags);
- sub->active = false;
- spin_unlock_irqrestore(&sub->lock, flags);
- return 0;
-
- default:
- return -EINVAL;
- }
-}
-
-static snd_pcm_uframes_t usb6fire_pcm_pointer(
- struct snd_pcm_substream *alsa_sub)
-{
- struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
- struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
- unsigned long flags;
- snd_pcm_uframes_t ret;
-
- if (rt->panic || !sub)
- return SNDRV_PCM_STATE_XRUN;
-
- spin_lock_irqsave(&sub->lock, flags);
- ret = sub->dma_off;
- spin_unlock_irqrestore(&sub->lock, flags);
- return ret;
-}
-
-static struct snd_pcm_ops pcm_ops = {
- .open = usb6fire_pcm_open,
- .close = usb6fire_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = usb6fire_pcm_hw_params,
- .hw_free = usb6fire_pcm_hw_free,
- .prepare = usb6fire_pcm_prepare,
- .trigger = usb6fire_pcm_trigger,
- .pointer = usb6fire_pcm_pointer,
-};
-
-static void __devinit usb6fire_pcm_init_urb(struct pcm_urb *urb,
- struct sfire_chip *chip, bool in, int ep,
- void (*handler)(struct urb *))
-{
- urb->chip = chip;
- usb_init_urb(&urb->instance);
- urb->instance.transfer_buffer = urb->buffer;
- urb->instance.transfer_buffer_length =
- PCM_N_PACKETS_PER_URB * PCM_MAX_PACKET_SIZE;
- urb->instance.dev = chip->dev;
- urb->instance.pipe = in ? usb_rcvisocpipe(chip->dev, ep)
- : usb_sndisocpipe(chip->dev, ep);
- urb->instance.interval = 1;
- urb->instance.transfer_flags = URB_ISO_ASAP;
- urb->instance.complete = handler;
- urb->instance.context = urb;
- urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB;
-}
-
-int __devinit usb6fire_pcm_init(struct sfire_chip *chip)
-{
- int i;
- int ret;
- struct snd_pcm *pcm;
- struct pcm_runtime *rt =
- kzalloc(sizeof(struct pcm_runtime), GFP_KERNEL);
-
- if (!rt)
- return -ENOMEM;
-
- rt->chip = chip;
- rt->stream_state = STREAM_DISABLED;
- rt->rate = ARRAY_SIZE(rates);
- init_waitqueue_head(&rt->stream_wait_queue);
- mutex_init(&rt->stream_mutex);
-
- spin_lock_init(&rt->playback.lock);
- spin_lock_init(&rt->capture.lock);
-
- for (i = 0; i < PCM_N_URBS; i++) {
- usb6fire_pcm_init_urb(&rt->in_urbs[i], chip, true, IN_EP,
- usb6fire_pcm_in_urb_handler);
- usb6fire_pcm_init_urb(&rt->out_urbs[i], chip, false, OUT_EP,
- usb6fire_pcm_out_urb_handler);
-
- rt->in_urbs[i].peer = &rt->out_urbs[i];
- rt->out_urbs[i].peer = &rt->in_urbs[i];
- }
-
- ret = snd_pcm_new(chip->card, "DMX6FireUSB", 0, 1, 1, &pcm);
- if (ret < 0) {
- kfree(rt);
- snd_printk(KERN_ERR PREFIX "cannot create pcm instance.\n");
- return ret;
- }
-
- pcm->private_data = rt;
- strcpy(pcm->name, "DMX 6Fire USB");
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_ops);
-
- ret = snd_pcm_lib_preallocate_pages_for_all(pcm,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- MAX_BUFSIZE, MAX_BUFSIZE);
- if (ret) {
- kfree(rt);
- snd_printk(KERN_ERR PREFIX
- "error preallocating pcm buffers.\n");
- return ret;
- }
- rt->instance = pcm;
-
- chip->pcm = rt;
- return 0;
-}
-
-void usb6fire_pcm_abort(struct sfire_chip *chip)
-{
- struct pcm_runtime *rt = chip->pcm;
- int i;
-
- if (rt) {
- rt->panic = true;
-
- if (rt->playback.instance)
- snd_pcm_stop(rt->playback.instance,
- SNDRV_PCM_STATE_XRUN);
- if (rt->capture.instance)
- snd_pcm_stop(rt->capture.instance,
- SNDRV_PCM_STATE_XRUN);
-
- for (i = 0; i < PCM_N_URBS; i++) {
- usb_poison_urb(&rt->in_urbs[i].instance);
- usb_poison_urb(&rt->out_urbs[i].instance);
- }
-
- }
-}
-
-void usb6fire_pcm_destroy(struct sfire_chip *chip)
-{
- kfree(chip->pcm);
- chip->pcm = NULL;
-}
diff --git a/ANDROID_3.4.5/sound/usb/6fire/pcm.h b/ANDROID_3.4.5/sound/usb/6fire/pcm.h
deleted file mode 100644
index 3104301b..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/pcm.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef USB6FIRE_PCM_H
-#define USB6FIRE_PCM_H
-
-#include <sound/pcm.h>
-#include <linux/mutex.h>
-
-#include "common.h"
-
-enum /* settings for pcm */
-{
- /* maximum of EP_W_MAX_PACKET_SIZE[] (see firmware.c) */
- PCM_N_URBS = 16, PCM_N_PACKETS_PER_URB = 8, PCM_MAX_PACKET_SIZE = 604
-};
-
-struct pcm_urb {
- struct sfire_chip *chip;
-
- /* BEGIN DO NOT SEPARATE */
- struct urb instance;
- struct usb_iso_packet_descriptor packets[PCM_N_PACKETS_PER_URB];
- /* END DO NOT SEPARATE */
- u8 buffer[PCM_N_PACKETS_PER_URB * PCM_MAX_PACKET_SIZE];
-
- struct pcm_urb *peer;
-};
-
-struct pcm_substream {
- spinlock_t lock;
- struct snd_pcm_substream *instance;
-
- bool active;
-
- snd_pcm_uframes_t dma_off; /* current position in alsa dma_area */
- snd_pcm_uframes_t period_off; /* current position in current period */
-};
-
-struct pcm_runtime {
- struct sfire_chip *chip;
- struct snd_pcm *instance;
-
- struct pcm_substream playback;
- struct pcm_substream capture;
- bool panic; /* if set driver won't do anymore pcm on device */
-
- struct pcm_urb in_urbs[PCM_N_URBS];
- struct pcm_urb out_urbs[PCM_N_URBS];
- int in_packet_size;
- int out_packet_size;
- int in_n_analog; /* number of analog channels soundcard sends */
- int out_n_analog; /* number of analog channels soundcard receives */
-
- struct mutex stream_mutex;
- u8 stream_state; /* one of STREAM_XXX (pcm.c) */
- u8 rate; /* one of PCM_RATE_XXX */
- wait_queue_head_t stream_wait_queue;
- bool stream_wait_cond;
-};
-
-int __devinit usb6fire_pcm_init(struct sfire_chip *chip);
-void usb6fire_pcm_abort(struct sfire_chip *chip);
-void usb6fire_pcm_destroy(struct sfire_chip *chip);
-#endif /* USB6FIRE_PCM_H */
diff --git a/ANDROID_3.4.5/sound/usb/Kconfig b/ANDROID_3.4.5/sound/usb/Kconfig
deleted file mode 100644
index ff77b28f..00000000
--- a/ANDROID_3.4.5/sound/usb/Kconfig
+++ /dev/null
@@ -1,119 +0,0 @@
-# ALSA USB drivers
-
-menuconfig SND_USB
- bool "USB sound devices"
- depends on USB
- default y
- help
- Support for sound devices connected via the USB bus.
-
-if SND_USB && USB
-
-config SND_USB_AUDIO
- tristate "USB Audio/MIDI driver"
- select SND_HWDEP
- select SND_RAWMIDI
- select SND_PCM
- help
- Say Y here to include support for USB audio and USB MIDI
- devices.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-usb-audio.
-
-config SND_USB_UA101
- tristate "Edirol UA-101/UA-1000 driver"
- select SND_PCM
- select SND_RAWMIDI
- help
- Say Y here to include support for the Edirol UA-101 and UA-1000
- audio/MIDI interfaces.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-ua101.
-
-config SND_USB_USX2Y
- tristate "Tascam US-122, US-224 and US-428 USB driver"
- depends on X86 || PPC || ALPHA
- select SND_HWDEP
- select SND_RAWMIDI
- select SND_PCM
- help
- Say Y here to include support for Tascam USB Audio/MIDI
- interfaces or controllers US-122, US-224 and US-428.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-usb-usx2y.
-
-config SND_USB_CAIAQ
- tristate "Native Instruments USB audio devices"
- select SND_HWDEP
- select SND_RAWMIDI
- select SND_PCM
- help
- Say Y here to include support for caiaq USB audio interfaces,
- namely:
-
- * Native Instruments RigKontrol2
- * Native Instruments RigKontrol3
- * Native Instruments Kore Controller
- * Native Instruments Kore Controller 2
- * Native Instruments Audio Kontrol 1
- * Native Instruments Audio 2 DJ
- * Native Instruments Audio 4 DJ
- * Native Instruments Audio 8 DJ
- * Native Instruments Traktor Audio 2
- * Native Instruments Guitar Rig Session I/O
- * Native Instruments Guitar Rig mobile
- * Native Instruments Traktor Kontrol X1
- * Native Instruments Traktor Kontrol S4
- * Native Instruments Maschine Controller
-
- To compile this driver as a module, choose M here: the module
- will be called snd-usb-caiaq.
-
-config SND_USB_CAIAQ_INPUT
- bool "enable input device for controllers"
- depends on SND_USB_CAIAQ
- depends on INPUT=y || INPUT=SND_USB_CAIAQ
- help
- Say Y here to support input controllers like buttons, knobs,
- alpha dials and analog pedals on the following products:
-
- * Native Instruments RigKontrol2
- * Native Instruments RigKontrol3
- * Native Instruments Kore Controller
- * Native Instruments Kore Controller 2
- * Native Instruments Audio Kontrol 1
- * Native Instruments Traktor Kontrol S4
- * Native Instruments Maschine Controller
-
-config SND_USB_US122L
- tristate "Tascam US-122L USB driver"
- depends on X86 && EXPERIMENTAL
- select SND_HWDEP
- select SND_RAWMIDI
- help
- Say Y here to include support for Tascam US-122L USB Audio/MIDI
- interfaces.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-usb-us122l.
-
-config SND_USB_6FIRE
- tristate "TerraTec DMX 6Fire USB"
- select FW_LOADER
- select BITREVERSE
- select SND_RAWMIDI
- select SND_PCM
- select SND_VMASTER
- help
- Say Y here to include support for TerraTec 6fire DMX USB interface.
-
- You will need firmware files in order to be able to use the device
- after it has been coldstarted. An install script for the firmware
- and further help can be found at
- http://sixfireusb.sourceforge.net
-
-endif # SND_USB
-
diff --git a/ANDROID_3.4.5/sound/usb/Makefile b/ANDROID_3.4.5/sound/usb/Makefile
deleted file mode 100644
index ac256dc4..00000000
--- a/ANDROID_3.4.5/sound/usb/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Makefile for ALSA
-#
-
-snd-usb-audio-objs := card.o \
- clock.o \
- endpoint.o \
- format.o \
- helper.o \
- mixer.o \
- mixer_quirks.o \
- pcm.o \
- proc.o \
- quirks.o \
- stream.o
-
-snd-usbmidi-lib-objs := midi.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usbmidi-lib.o
-
-obj-$(CONFIG_SND_USB_UA101) += snd-usbmidi-lib.o
-obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o
-obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o
-
-obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 6fire/
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/Makefile b/ANDROID_3.4.5/sound/usb/caiaq/Makefile
deleted file mode 100644
index 38899965..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-snd-usb-caiaq-y := device.o audio.o midi.o control.o
-snd-usb-caiaq-$(CONFIG_SND_USB_CAIAQ_INPUT) += input.o
-
-obj-$(CONFIG_SND_USB_CAIAQ) += snd-usb-caiaq.o
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/audio.c b/ANDROID_3.4.5/sound/usb/caiaq/audio.c
deleted file mode 100644
index fde9a7a2..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/audio.c
+++ /dev/null
@@ -1,889 +0,0 @@
-/*
- * Copyright (c) 2006-2008 Daniel Mack, Karsten Wiese
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/usb.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include "device.h"
-#include "audio.h"
-
-#define N_URBS 32
-#define CLOCK_DRIFT_TOLERANCE 5
-#define FRAMES_PER_URB 8
-#define BYTES_PER_FRAME 512
-#define CHANNELS_PER_STREAM 2
-#define BYTES_PER_SAMPLE 3
-#define BYTES_PER_SAMPLE_USB 4
-#define MAX_BUFFER_SIZE (128*1024)
-#define MAX_ENDPOINT_SIZE 512
-
-#define ENDPOINT_CAPTURE 2
-#define ENDPOINT_PLAYBACK 6
-
-#define MAKE_CHECKBYTE(dev,stream,i) \
- (stream << 1) | (~(i / (dev->n_streams * BYTES_PER_SAMPLE_USB)) & 1)
-
-static struct snd_pcm_hardware snd_usb_caiaq_pcm_hardware = {
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER),
- .formats = SNDRV_PCM_FMTBIT_S24_3BE,
- .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_96000),
- .rate_min = 44100,
- .rate_max = 0, /* will overwrite later */
- .channels_min = CHANNELS_PER_STREAM,
- .channels_max = CHANNELS_PER_STREAM,
- .buffer_bytes_max = MAX_BUFFER_SIZE,
- .period_bytes_min = 128,
- .period_bytes_max = MAX_BUFFER_SIZE,
- .periods_min = 1,
- .periods_max = 1024,
-};
-
-static void
-activate_substream(struct snd_usb_caiaqdev *dev,
- struct snd_pcm_substream *sub)
-{
- spin_lock(&dev->spinlock);
-
- if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dev->sub_playback[sub->number] = sub;
- else
- dev->sub_capture[sub->number] = sub;
-
- spin_unlock(&dev->spinlock);
-}
-
-static void
-deactivate_substream(struct snd_usb_caiaqdev *dev,
- struct snd_pcm_substream *sub)
-{
- unsigned long flags;
- spin_lock_irqsave(&dev->spinlock, flags);
-
- if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dev->sub_playback[sub->number] = NULL;
- else
- dev->sub_capture[sub->number] = NULL;
-
- spin_unlock_irqrestore(&dev->spinlock, flags);
-}
-
-static int
-all_substreams_zero(struct snd_pcm_substream **subs)
-{
- int i;
- for (i = 0; i < MAX_STREAMS; i++)
- if (subs[i] != NULL)
- return 0;
- return 1;
-}
-
-static int stream_start(struct snd_usb_caiaqdev *dev)
-{
- int i, ret;
-
- debug("%s(%p)\n", __func__, dev);
-
- if (dev->streaming)
- return -EINVAL;
-
- memset(dev->sub_playback, 0, sizeof(dev->sub_playback));
- memset(dev->sub_capture, 0, sizeof(dev->sub_capture));
- dev->input_panic = 0;
- dev->output_panic = 0;
- dev->first_packet = 4;
- dev->streaming = 1;
- dev->warned = 0;
-
- for (i = 0; i < N_URBS; i++) {
- ret = usb_submit_urb(dev->data_urbs_in[i], GFP_ATOMIC);
- if (ret) {
- log("unable to trigger read #%d! (ret %d)\n", i, ret);
- dev->streaming = 0;
- return -EPIPE;
- }
- }
-
- return 0;
-}
-
-static void stream_stop(struct snd_usb_caiaqdev *dev)
-{
- int i;
-
- debug("%s(%p)\n", __func__, dev);
- if (!dev->streaming)
- return;
-
- dev->streaming = 0;
-
- for (i = 0; i < N_URBS; i++) {
- usb_kill_urb(dev->data_urbs_in[i]);
-
- if (test_bit(i, &dev->outurb_active_mask))
- usb_kill_urb(dev->data_urbs_out[i]);
- }
-
- dev->outurb_active_mask = 0;
-}
-
-static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream)
-{
- struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream);
- debug("%s(%p)\n", __func__, substream);
- substream->runtime->hw = dev->pcm_info;
- snd_pcm_limit_hw_rates(substream->runtime);
- return 0;
-}
-
-static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream)
-{
- struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream);
-
- debug("%s(%p)\n", __func__, substream);
- if (all_substreams_zero(dev->sub_playback) &&
- all_substreams_zero(dev->sub_capture)) {
- /* when the last client has stopped streaming,
- * all sample rates are allowed again */
- stream_stop(dev);
- dev->pcm_info.rates = dev->samplerates;
- }
-
- return 0;
-}
-
-static int snd_usb_caiaq_pcm_hw_params(struct snd_pcm_substream *sub,
- struct snd_pcm_hw_params *hw_params)
-{
- debug("%s(%p)\n", __func__, sub);
- return snd_pcm_lib_malloc_pages(sub, params_buffer_bytes(hw_params));
-}
-
-static int snd_usb_caiaq_pcm_hw_free(struct snd_pcm_substream *sub)
-{
- struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
- debug("%s(%p)\n", __func__, sub);
- deactivate_substream(dev, sub);
- return snd_pcm_lib_free_pages(sub);
-}
-
-/* this should probably go upstream */
-#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12
-#error "Change this table"
-#endif
-
-static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100,
- 48000, 64000, 88200, 96000, 176400, 192000 };
-
-static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream)
-{
- int bytes_per_sample, bpp, ret, i;
- int index = substream->number;
- struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- debug("%s(%p)\n", __func__, substream);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- int out_pos;
-
- switch (dev->spec.data_alignment) {
- case 0:
- case 2:
- out_pos = BYTES_PER_SAMPLE + 1;
- break;
- case 3:
- default:
- out_pos = 0;
- break;
- }
-
- dev->period_out_count[index] = out_pos;
- dev->audio_out_buf_pos[index] = out_pos;
- } else {
- int in_pos;
-
- switch (dev->spec.data_alignment) {
- case 0:
- in_pos = BYTES_PER_SAMPLE + 2;
- break;
- case 2:
- in_pos = BYTES_PER_SAMPLE;
- break;
- case 3:
- default:
- in_pos = 0;
- break;
- }
-
- dev->period_in_count[index] = in_pos;
- dev->audio_in_buf_pos[index] = in_pos;
- }
-
- if (dev->streaming)
- return 0;
-
- /* the first client that opens a stream defines the sample rate
- * setting for all subsequent calls, until the last client closed. */
- for (i=0; i < ARRAY_SIZE(rates); i++)
- if (runtime->rate == rates[i])
- dev->pcm_info.rates = 1 << i;
-
- snd_pcm_limit_hw_rates(runtime);
-
- bytes_per_sample = BYTES_PER_SAMPLE;
- if (dev->spec.data_alignment >= 2)
- bytes_per_sample++;
-
- bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE)
- * bytes_per_sample * CHANNELS_PER_STREAM * dev->n_streams;
-
- if (bpp > MAX_ENDPOINT_SIZE)
- bpp = MAX_ENDPOINT_SIZE;
-
- ret = snd_usb_caiaq_set_audio_params(dev, runtime->rate,
- runtime->sample_bits, bpp);
- if (ret)
- return ret;
-
- ret = stream_start(dev);
- if (ret)
- return ret;
-
- dev->output_running = 0;
- wait_event_timeout(dev->prepare_wait_queue, dev->output_running, HZ);
- if (!dev->output_running) {
- stream_stop(dev);
- return -EPIPE;
- }
-
- return 0;
-}
-
-static int snd_usb_caiaq_pcm_trigger(struct snd_pcm_substream *sub, int cmd)
-{
- struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
-
- debug("%s(%p) cmd %d\n", __func__, sub, cmd);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- activate_substream(dev, sub);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- deactivate_substream(dev, sub);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static snd_pcm_uframes_t
-snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub)
-{
- int index = sub->number;
- struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
- snd_pcm_uframes_t ptr;
-
- spin_lock(&dev->spinlock);
-
- if (dev->input_panic || dev->output_panic) {
- ptr = SNDRV_PCM_POS_XRUN;
- goto unlock;
- }
-
- if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
- ptr = bytes_to_frames(sub->runtime,
- dev->audio_out_buf_pos[index]);
- else
- ptr = bytes_to_frames(sub->runtime,
- dev->audio_in_buf_pos[index]);
-
-unlock:
- spin_unlock(&dev->spinlock);
- return ptr;
-}
-
-/* operators for both playback and capture */
-static struct snd_pcm_ops snd_usb_caiaq_ops = {
- .open = snd_usb_caiaq_substream_open,
- .close = snd_usb_caiaq_substream_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_usb_caiaq_pcm_hw_params,
- .hw_free = snd_usb_caiaq_pcm_hw_free,
- .prepare = snd_usb_caiaq_pcm_prepare,
- .trigger = snd_usb_caiaq_pcm_trigger,
- .pointer = snd_usb_caiaq_pcm_pointer
-};
-
-static void check_for_elapsed_periods(struct snd_usb_caiaqdev *dev,
- struct snd_pcm_substream **subs)
-{
- int stream, pb, *cnt;
- struct snd_pcm_substream *sub;
-
- for (stream = 0; stream < dev->n_streams; stream++) {
- sub = subs[stream];
- if (!sub)
- continue;
-
- pb = snd_pcm_lib_period_bytes(sub);
- cnt = (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
- &dev->period_out_count[stream] :
- &dev->period_in_count[stream];
-
- if (*cnt >= pb) {
- snd_pcm_period_elapsed(sub);
- *cnt %= pb;
- }
- }
-}
-
-static void read_in_urb_mode0(struct snd_usb_caiaqdev *dev,
- const struct urb *urb,
- const struct usb_iso_packet_descriptor *iso)
-{
- unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
- struct snd_pcm_substream *sub;
- int stream, i;
-
- if (all_substreams_zero(dev->sub_capture))
- return;
-
- for (i = 0; i < iso->actual_length;) {
- for (stream = 0; stream < dev->n_streams; stream++, i++) {
- sub = dev->sub_capture[stream];
- if (sub) {
- struct snd_pcm_runtime *rt = sub->runtime;
- char *audio_buf = rt->dma_area;
- int sz = frames_to_bytes(rt, rt->buffer_size);
- audio_buf[dev->audio_in_buf_pos[stream]++]
- = usb_buf[i];
- dev->period_in_count[stream]++;
- if (dev->audio_in_buf_pos[stream] == sz)
- dev->audio_in_buf_pos[stream] = 0;
- }
- }
- }
-}
-
-static void read_in_urb_mode2(struct snd_usb_caiaqdev *dev,
- const struct urb *urb,
- const struct usb_iso_packet_descriptor *iso)
-{
- unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
- unsigned char check_byte;
- struct snd_pcm_substream *sub;
- int stream, i;
-
- for (i = 0; i < iso->actual_length;) {
- if (i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == 0) {
- for (stream = 0;
- stream < dev->n_streams;
- stream++, i++) {
- if (dev->first_packet)
- continue;
-
- check_byte = MAKE_CHECKBYTE(dev, stream, i);
-
- if ((usb_buf[i] & 0x3f) != check_byte)
- dev->input_panic = 1;
-
- if (usb_buf[i] & 0x80)
- dev->output_panic = 1;
- }
- }
- dev->first_packet = 0;
-
- for (stream = 0; stream < dev->n_streams; stream++, i++) {
- sub = dev->sub_capture[stream];
- if (dev->input_panic)
- usb_buf[i] = 0;
-
- if (sub) {
- struct snd_pcm_runtime *rt = sub->runtime;
- char *audio_buf = rt->dma_area;
- int sz = frames_to_bytes(rt, rt->buffer_size);
- audio_buf[dev->audio_in_buf_pos[stream]++] =
- usb_buf[i];
- dev->period_in_count[stream]++;
- if (dev->audio_in_buf_pos[stream] == sz)
- dev->audio_in_buf_pos[stream] = 0;
- }
- }
- }
-}
-
-static void read_in_urb_mode3(struct snd_usb_caiaqdev *dev,
- const struct urb *urb,
- const struct usb_iso_packet_descriptor *iso)
-{
- unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
- int stream, i;
-
- /* paranoia check */
- if (iso->actual_length % (BYTES_PER_SAMPLE_USB * CHANNELS_PER_STREAM))
- return;
-
- for (i = 0; i < iso->actual_length;) {
- for (stream = 0; stream < dev->n_streams; stream++) {
- struct snd_pcm_substream *sub = dev->sub_capture[stream];
- char *audio_buf = NULL;
- int c, n, sz = 0;
-
- if (sub && !dev->input_panic) {
- struct snd_pcm_runtime *rt = sub->runtime;
- audio_buf = rt->dma_area;
- sz = frames_to_bytes(rt, rt->buffer_size);
- }
-
- for (c = 0; c < CHANNELS_PER_STREAM; c++) {
- /* 3 audio data bytes, followed by 1 check byte */
- if (audio_buf) {
- for (n = 0; n < BYTES_PER_SAMPLE; n++) {
- audio_buf[dev->audio_in_buf_pos[stream]++] = usb_buf[i+n];
-
- if (dev->audio_in_buf_pos[stream] == sz)
- dev->audio_in_buf_pos[stream] = 0;
- }
-
- dev->period_in_count[stream] += BYTES_PER_SAMPLE;
- }
-
- i += BYTES_PER_SAMPLE;
-
- if (usb_buf[i] != ((stream << 1) | c) &&
- !dev->first_packet) {
- if (!dev->input_panic)
- printk(" EXPECTED: %02x got %02x, c %d, stream %d, i %d\n",
- ((stream << 1) | c), usb_buf[i], c, stream, i);
- dev->input_panic = 1;
- }
-
- i++;
- }
- }
- }
-
- if (dev->first_packet > 0)
- dev->first_packet--;
-}
-
-static void read_in_urb(struct snd_usb_caiaqdev *dev,
- const struct urb *urb,
- const struct usb_iso_packet_descriptor *iso)
-{
- if (!dev->streaming)
- return;
-
- if (iso->actual_length < dev->bpp)
- return;
-
- switch (dev->spec.data_alignment) {
- case 0:
- read_in_urb_mode0(dev, urb, iso);
- break;
- case 2:
- read_in_urb_mode2(dev, urb, iso);
- break;
- case 3:
- read_in_urb_mode3(dev, urb, iso);
- break;
- }
-
- if ((dev->input_panic || dev->output_panic) && !dev->warned) {
- debug("streaming error detected %s %s\n",
- dev->input_panic ? "(input)" : "",
- dev->output_panic ? "(output)" : "");
- dev->warned = 1;
- }
-}
-
-static void fill_out_urb_mode_0(struct snd_usb_caiaqdev *dev,
- struct urb *urb,
- const struct usb_iso_packet_descriptor *iso)
-{
- unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
- struct snd_pcm_substream *sub;
- int stream, i;
-
- for (i = 0; i < iso->length;) {
- for (stream = 0; stream < dev->n_streams; stream++, i++) {
- sub = dev->sub_playback[stream];
- if (sub) {
- struct snd_pcm_runtime *rt = sub->runtime;
- char *audio_buf = rt->dma_area;
- int sz = frames_to_bytes(rt, rt->buffer_size);
- usb_buf[i] =
- audio_buf[dev->audio_out_buf_pos[stream]];
- dev->period_out_count[stream]++;
- dev->audio_out_buf_pos[stream]++;
- if (dev->audio_out_buf_pos[stream] == sz)
- dev->audio_out_buf_pos[stream] = 0;
- } else
- usb_buf[i] = 0;
- }
-
- /* fill in the check bytes */
- if (dev->spec.data_alignment == 2 &&
- i % (dev->n_streams * BYTES_PER_SAMPLE_USB) ==
- (dev->n_streams * CHANNELS_PER_STREAM))
- for (stream = 0; stream < dev->n_streams; stream++, i++)
- usb_buf[i] = MAKE_CHECKBYTE(dev, stream, i);
- }
-}
-
-static void fill_out_urb_mode_3(struct snd_usb_caiaqdev *dev,
- struct urb *urb,
- const struct usb_iso_packet_descriptor *iso)
-{
- unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
- int stream, i;
-
- for (i = 0; i < iso->length;) {
- for (stream = 0; stream < dev->n_streams; stream++) {
- struct snd_pcm_substream *sub = dev->sub_playback[stream];
- char *audio_buf = NULL;
- int c, n, sz = 0;
-
- if (sub) {
- struct snd_pcm_runtime *rt = sub->runtime;
- audio_buf = rt->dma_area;
- sz = frames_to_bytes(rt, rt->buffer_size);
- }
-
- for (c = 0; c < CHANNELS_PER_STREAM; c++) {
- for (n = 0; n < BYTES_PER_SAMPLE; n++) {
- if (audio_buf) {
- usb_buf[i+n] = audio_buf[dev->audio_out_buf_pos[stream]++];
-
- if (dev->audio_out_buf_pos[stream] == sz)
- dev->audio_out_buf_pos[stream] = 0;
- } else {
- usb_buf[i+n] = 0;
- }
- }
-
- if (audio_buf)
- dev->period_out_count[stream] += BYTES_PER_SAMPLE;
-
- i += BYTES_PER_SAMPLE;
-
- /* fill in the check byte pattern */
- usb_buf[i++] = (stream << 1) | c;
- }
- }
- }
-}
-
-static inline void fill_out_urb(struct snd_usb_caiaqdev *dev,
- struct urb *urb,
- const struct usb_iso_packet_descriptor *iso)
-{
- switch (dev->spec.data_alignment) {
- case 0:
- case 2:
- fill_out_urb_mode_0(dev, urb, iso);
- break;
- case 3:
- fill_out_urb_mode_3(dev, urb, iso);
- break;
- }
-}
-
-static void read_completed(struct urb *urb)
-{
- struct snd_usb_caiaq_cb_info *info = urb->context;
- struct snd_usb_caiaqdev *dev;
- struct urb *out = NULL;
- int i, frame, len, send_it = 0, outframe = 0;
- size_t offset = 0;
-
- if (urb->status || !info)
- return;
-
- dev = info->dev;
-
- if (!dev->streaming)
- return;
-
- /* find an unused output urb that is unused */
- for (i = 0; i < N_URBS; i++)
- if (test_and_set_bit(i, &dev->outurb_active_mask) == 0) {
- out = dev->data_urbs_out[i];
- break;
- }
-
- if (!out) {
- log("Unable to find an output urb to use\n");
- goto requeue;
- }
-
- /* read the recently received packet and send back one which has
- * the same layout */
- for (frame = 0; frame < FRAMES_PER_URB; frame++) {
- if (urb->iso_frame_desc[frame].status)
- continue;
-
- len = urb->iso_frame_desc[outframe].actual_length;
- out->iso_frame_desc[outframe].length = len;
- out->iso_frame_desc[outframe].actual_length = 0;
- out->iso_frame_desc[outframe].offset = offset;
- offset += len;
-
- if (len > 0) {
- spin_lock(&dev->spinlock);
- fill_out_urb(dev, out, &out->iso_frame_desc[outframe]);
- read_in_urb(dev, urb, &urb->iso_frame_desc[frame]);
- spin_unlock(&dev->spinlock);
- check_for_elapsed_periods(dev, dev->sub_playback);
- check_for_elapsed_periods(dev, dev->sub_capture);
- send_it = 1;
- }
-
- outframe++;
- }
-
- if (send_it) {
- out->number_of_packets = outframe;
- out->transfer_flags = URB_ISO_ASAP;
- usb_submit_urb(out, GFP_ATOMIC);
- } else {
- struct snd_usb_caiaq_cb_info *oinfo = out->context;
- clear_bit(oinfo->index, &dev->outurb_active_mask);
- }
-
-requeue:
- /* re-submit inbound urb */
- for (frame = 0; frame < FRAMES_PER_URB; frame++) {
- urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame;
- urb->iso_frame_desc[frame].length = BYTES_PER_FRAME;
- urb->iso_frame_desc[frame].actual_length = 0;
- }
-
- urb->number_of_packets = FRAMES_PER_URB;
- urb->transfer_flags = URB_ISO_ASAP;
- usb_submit_urb(urb, GFP_ATOMIC);
-}
-
-static void write_completed(struct urb *urb)
-{
- struct snd_usb_caiaq_cb_info *info = urb->context;
- struct snd_usb_caiaqdev *dev = info->dev;
-
- if (!dev->output_running) {
- dev->output_running = 1;
- wake_up(&dev->prepare_wait_queue);
- }
-
- clear_bit(info->index, &dev->outurb_active_mask);
-}
-
-static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret)
-{
- int i, frame;
- struct urb **urbs;
- struct usb_device *usb_dev = dev->chip.dev;
- unsigned int pipe;
-
- pipe = (dir == SNDRV_PCM_STREAM_PLAYBACK) ?
- usb_sndisocpipe(usb_dev, ENDPOINT_PLAYBACK) :
- usb_rcvisocpipe(usb_dev, ENDPOINT_CAPTURE);
-
- urbs = kmalloc(N_URBS * sizeof(*urbs), GFP_KERNEL);
- if (!urbs) {
- log("unable to kmalloc() urbs, OOM!?\n");
- *ret = -ENOMEM;
- return NULL;
- }
-
- for (i = 0; i < N_URBS; i++) {
- urbs[i] = usb_alloc_urb(FRAMES_PER_URB, GFP_KERNEL);
- if (!urbs[i]) {
- log("unable to usb_alloc_urb(), OOM!?\n");
- *ret = -ENOMEM;
- return urbs;
- }
-
- urbs[i]->transfer_buffer =
- kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL);
- if (!urbs[i]->transfer_buffer) {
- log("unable to kmalloc() transfer buffer, OOM!?\n");
- *ret = -ENOMEM;
- return urbs;
- }
-
- for (frame = 0; frame < FRAMES_PER_URB; frame++) {
- struct usb_iso_packet_descriptor *iso =
- &urbs[i]->iso_frame_desc[frame];
-
- iso->offset = BYTES_PER_FRAME * frame;
- iso->length = BYTES_PER_FRAME;
- }
-
- urbs[i]->dev = usb_dev;
- urbs[i]->pipe = pipe;
- urbs[i]->transfer_buffer_length = FRAMES_PER_URB
- * BYTES_PER_FRAME;
- urbs[i]->context = &dev->data_cb_info[i];
- urbs[i]->interval = 1;
- urbs[i]->transfer_flags = URB_ISO_ASAP;
- urbs[i]->number_of_packets = FRAMES_PER_URB;
- urbs[i]->complete = (dir == SNDRV_PCM_STREAM_CAPTURE) ?
- read_completed : write_completed;
- }
-
- *ret = 0;
- return urbs;
-}
-
-static void free_urbs(struct urb **urbs)
-{
- int i;
-
- if (!urbs)
- return;
-
- for (i = 0; i < N_URBS; i++) {
- if (!urbs[i])
- continue;
-
- usb_kill_urb(urbs[i]);
- kfree(urbs[i]->transfer_buffer);
- usb_free_urb(urbs[i]);
- }
-
- kfree(urbs);
-}
-
-int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev)
-{
- int i, ret;
-
- dev->n_audio_in = max(dev->spec.num_analog_audio_in,
- dev->spec.num_digital_audio_in) /
- CHANNELS_PER_STREAM;
- dev->n_audio_out = max(dev->spec.num_analog_audio_out,
- dev->spec.num_digital_audio_out) /
- CHANNELS_PER_STREAM;
- dev->n_streams = max(dev->n_audio_in, dev->n_audio_out);
-
- debug("dev->n_audio_in = %d\n", dev->n_audio_in);
- debug("dev->n_audio_out = %d\n", dev->n_audio_out);
- debug("dev->n_streams = %d\n", dev->n_streams);
-
- if (dev->n_streams > MAX_STREAMS) {
- log("unable to initialize device, too many streams.\n");
- return -EINVAL;
- }
-
- ret = snd_pcm_new(dev->chip.card, dev->product_name, 0,
- dev->n_audio_out, dev->n_audio_in, &dev->pcm);
-
- if (ret < 0) {
- log("snd_pcm_new() returned %d\n", ret);
- return ret;
- }
-
- dev->pcm->private_data = dev;
- strlcpy(dev->pcm->name, dev->product_name, sizeof(dev->pcm->name));
-
- memset(dev->sub_playback, 0, sizeof(dev->sub_playback));
- memset(dev->sub_capture, 0, sizeof(dev->sub_capture));
-
- memcpy(&dev->pcm_info, &snd_usb_caiaq_pcm_hardware,
- sizeof(snd_usb_caiaq_pcm_hardware));
-
- /* setup samplerates */
- dev->samplerates = dev->pcm_info.rates;
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_SESSIONIO):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_GUITARRIGMOBILE):
- dev->samplerates |= SNDRV_PCM_RATE_192000;
- /* fall thru */
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO2DJ):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORAUDIO2):
- dev->samplerates |= SNDRV_PCM_RATE_88200;
- break;
- }
-
- snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_usb_caiaq_ops);
- snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_usb_caiaq_ops);
-
- snd_pcm_lib_preallocate_pages_for_all(dev->pcm,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- MAX_BUFFER_SIZE, MAX_BUFFER_SIZE);
-
- dev->data_cb_info =
- kmalloc(sizeof(struct snd_usb_caiaq_cb_info) * N_URBS,
- GFP_KERNEL);
-
- if (!dev->data_cb_info)
- return -ENOMEM;
-
- dev->outurb_active_mask = 0;
- BUILD_BUG_ON(N_URBS > (sizeof(dev->outurb_active_mask) * 8));
-
- for (i = 0; i < N_URBS; i++) {
- dev->data_cb_info[i].dev = dev;
- dev->data_cb_info[i].index = i;
- }
-
- dev->data_urbs_in = alloc_urbs(dev, SNDRV_PCM_STREAM_CAPTURE, &ret);
- if (ret < 0) {
- kfree(dev->data_cb_info);
- free_urbs(dev->data_urbs_in);
- return ret;
- }
-
- dev->data_urbs_out = alloc_urbs(dev, SNDRV_PCM_STREAM_PLAYBACK, &ret);
- if (ret < 0) {
- kfree(dev->data_cb_info);
- free_urbs(dev->data_urbs_in);
- free_urbs(dev->data_urbs_out);
- return ret;
- }
-
- return 0;
-}
-
-void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *dev)
-{
- debug("%s(%p)\n", __func__, dev);
- stream_stop(dev);
- free_urbs(dev->data_urbs_in);
- free_urbs(dev->data_urbs_out);
- kfree(dev->data_cb_info);
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/audio.h b/ANDROID_3.4.5/sound/usb/caiaq/audio.h
deleted file mode 100644
index 8ab1f8d9..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/audio.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef CAIAQ_AUDIO_H
-#define CAIAQ_AUDIO_H
-
-int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev);
-void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *dev);
-
-#endif /* CAIAQ_AUDIO_H */
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/control.c b/ANDROID_3.4.5/sound/usb/caiaq/control.c
deleted file mode 100644
index 00e5d0a4..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/control.c
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * Copyright (c) 2007 Daniel Mack
- * friendly supported by NI.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/usb.h>
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include "device.h"
-#include "control.h"
-
-#define CNT_INTVAL 0x10000
-
-static int control_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol);
- struct snd_usb_caiaqdev *dev = caiaqdev(chip->card);
- int pos = kcontrol->private_value;
- int is_intval = pos & CNT_INTVAL;
- int maxval = 63;
-
- uinfo->count = 1;
- pos &= ~CNT_INTVAL;
-
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ):
- if (pos == 0) {
- /* current input mode of A8DJ and A4DJ */
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 2;
- return 0;
- }
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
- maxval = 127;
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
- maxval = 31;
- break;
- }
-
- if (is_intval) {
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = maxval;
- } else {
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- }
-
- return 0;
-}
-
-static int control_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol);
- struct snd_usb_caiaqdev *dev = caiaqdev(chip->card);
- int pos = kcontrol->private_value;
-
- if (pos & CNT_INTVAL)
- ucontrol->value.integer.value[0]
- = dev->control_state[pos & ~CNT_INTVAL];
- else
- ucontrol->value.integer.value[0]
- = !!(dev->control_state[pos / 8] & (1 << pos % 8));
-
- return 0;
-}
-
-static int control_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol);
- struct snd_usb_caiaqdev *dev = caiaqdev(chip->card);
- int pos = kcontrol->private_value;
- int v = ucontrol->value.integer.value[0];
- unsigned char cmd = EP1_CMD_WRITE_IO;
-
- if (dev->chip.usb_id ==
- USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1))
- cmd = EP1_CMD_DIMM_LEDS;
-
- if (pos & CNT_INTVAL) {
- int i = pos & ~CNT_INTVAL;
-
- dev->control_state[i] = v;
-
- if (dev->chip.usb_id ==
- USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4)) {
- int actual_len;
-
- dev->ep8_out_buf[0] = i;
- dev->ep8_out_buf[1] = v;
-
- usb_bulk_msg(dev->chip.dev,
- usb_sndbulkpipe(dev->chip.dev, 8),
- dev->ep8_out_buf, sizeof(dev->ep8_out_buf),
- &actual_len, 200);
- } else {
- snd_usb_caiaq_send_command(dev, cmd,
- dev->control_state, sizeof(dev->control_state));
- }
- } else {
- if (v)
- dev->control_state[pos / 8] |= 1 << (pos % 8);
- else
- dev->control_state[pos / 8] &= ~(1 << (pos % 8));
-
- snd_usb_caiaq_send_command(dev, cmd,
- dev->control_state, sizeof(dev->control_state));
- }
-
- return 1;
-}
-
-static struct snd_kcontrol_new kcontrol_template __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_HWDEP,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .index = 0,
- .info = control_info,
- .get = control_get,
- .put = control_put,
- /* name and private_value filled later */
-};
-
-struct caiaq_controller {
- char *name;
- int index;
-};
-
-static struct caiaq_controller ak1_controller[] = {
- { "LED left", 2 },
- { "LED middle", 1 },
- { "LED right", 0 },
- { "LED ring", 3 }
-};
-
-static struct caiaq_controller rk2_controller[] = {
- { "LED 1", 5 },
- { "LED 2", 4 },
- { "LED 3", 3 },
- { "LED 4", 2 },
- { "LED 5", 1 },
- { "LED 6", 0 },
- { "LED pedal", 6 },
- { "LED 7seg_1b", 8 },
- { "LED 7seg_1c", 9 },
- { "LED 7seg_2a", 10 },
- { "LED 7seg_2b", 11 },
- { "LED 7seg_2c", 12 },
- { "LED 7seg_2d", 13 },
- { "LED 7seg_2e", 14 },
- { "LED 7seg_2f", 15 },
- { "LED 7seg_2g", 16 },
- { "LED 7seg_3a", 17 },
- { "LED 7seg_3b", 18 },
- { "LED 7seg_3c", 19 },
- { "LED 7seg_3d", 20 },
- { "LED 7seg_3e", 21 },
- { "LED 7seg_3f", 22 },
- { "LED 7seg_3g", 23 }
-};
-
-static struct caiaq_controller rk3_controller[] = {
- { "LED 7seg_1a", 0 + 0 },
- { "LED 7seg_1b", 0 + 1 },
- { "LED 7seg_1c", 0 + 2 },
- { "LED 7seg_1d", 0 + 3 },
- { "LED 7seg_1e", 0 + 4 },
- { "LED 7seg_1f", 0 + 5 },
- { "LED 7seg_1g", 0 + 6 },
- { "LED 7seg_1p", 0 + 7 },
-
- { "LED 7seg_2a", 8 + 0 },
- { "LED 7seg_2b", 8 + 1 },
- { "LED 7seg_2c", 8 + 2 },
- { "LED 7seg_2d", 8 + 3 },
- { "LED 7seg_2e", 8 + 4 },
- { "LED 7seg_2f", 8 + 5 },
- { "LED 7seg_2g", 8 + 6 },
- { "LED 7seg_2p", 8 + 7 },
-
- { "LED 7seg_3a", 16 + 0 },
- { "LED 7seg_3b", 16 + 1 },
- { "LED 7seg_3c", 16 + 2 },
- { "LED 7seg_3d", 16 + 3 },
- { "LED 7seg_3e", 16 + 4 },
- { "LED 7seg_3f", 16 + 5 },
- { "LED 7seg_3g", 16 + 6 },
- { "LED 7seg_3p", 16 + 7 },
-
- { "LED 7seg_4a", 24 + 0 },
- { "LED 7seg_4b", 24 + 1 },
- { "LED 7seg_4c", 24 + 2 },
- { "LED 7seg_4d", 24 + 3 },
- { "LED 7seg_4e", 24 + 4 },
- { "LED 7seg_4f", 24 + 5 },
- { "LED 7seg_4g", 24 + 6 },
- { "LED 7seg_4p", 24 + 7 },
-
- { "LED 1", 32 + 0 },
- { "LED 2", 32 + 1 },
- { "LED 3", 32 + 2 },
- { "LED 4", 32 + 3 },
- { "LED 5", 32 + 4 },
- { "LED 6", 32 + 5 },
- { "LED 7", 32 + 6 },
- { "LED 8", 32 + 7 },
- { "LED pedal", 32 + 8 }
-};
-
-static struct caiaq_controller kore_controller[] = {
- { "LED F1", 8 | CNT_INTVAL },
- { "LED F2", 12 | CNT_INTVAL },
- { "LED F3", 0 | CNT_INTVAL },
- { "LED F4", 4 | CNT_INTVAL },
- { "LED F5", 11 | CNT_INTVAL },
- { "LED F6", 15 | CNT_INTVAL },
- { "LED F7", 3 | CNT_INTVAL },
- { "LED F8", 7 | CNT_INTVAL },
- { "LED touch1", 10 | CNT_INTVAL },
- { "LED touch2", 14 | CNT_INTVAL },
- { "LED touch3", 2 | CNT_INTVAL },
- { "LED touch4", 6 | CNT_INTVAL },
- { "LED touch5", 9 | CNT_INTVAL },
- { "LED touch6", 13 | CNT_INTVAL },
- { "LED touch7", 1 | CNT_INTVAL },
- { "LED touch8", 5 | CNT_INTVAL },
- { "LED left", 18 | CNT_INTVAL },
- { "LED right", 22 | CNT_INTVAL },
- { "LED up", 16 | CNT_INTVAL },
- { "LED down", 20 | CNT_INTVAL },
- { "LED stop", 23 | CNT_INTVAL },
- { "LED play", 21 | CNT_INTVAL },
- { "LED record", 19 | CNT_INTVAL },
- { "LED listen", 17 | CNT_INTVAL },
- { "LED lcd", 30 | CNT_INTVAL },
- { "LED menu", 28 | CNT_INTVAL },
- { "LED sound", 31 | CNT_INTVAL },
- { "LED esc", 29 | CNT_INTVAL },
- { "LED view", 27 | CNT_INTVAL },
- { "LED enter", 24 | CNT_INTVAL },
- { "LED control", 26 | CNT_INTVAL }
-};
-
-static struct caiaq_controller a8dj_controller[] = {
- { "Current input mode", 0 | CNT_INTVAL },
- { "GND lift for TC Vinyl mode", 24 + 0 },
- { "GND lift for TC CD/Line mode", 24 + 1 },
- { "GND lift for phono mode", 24 + 2 },
- { "Software lock", 40 }
-};
-
-static struct caiaq_controller a4dj_controller[] = {
- { "Current input mode", 0 | CNT_INTVAL }
-};
-
-static struct caiaq_controller kontrolx1_controller[] = {
- { "LED FX A: ON", 7 | CNT_INTVAL },
- { "LED FX A: 1", 6 | CNT_INTVAL },
- { "LED FX A: 2", 5 | CNT_INTVAL },
- { "LED FX A: 3", 4 | CNT_INTVAL },
- { "LED FX B: ON", 3 | CNT_INTVAL },
- { "LED FX B: 1", 2 | CNT_INTVAL },
- { "LED FX B: 2", 1 | CNT_INTVAL },
- { "LED FX B: 3", 0 | CNT_INTVAL },
-
- { "LED Hotcue", 28 | CNT_INTVAL },
- { "LED Shift (white)", 29 | CNT_INTVAL },
- { "LED Shift (green)", 30 | CNT_INTVAL },
-
- { "LED Deck A: FX1", 24 | CNT_INTVAL },
- { "LED Deck A: FX2", 25 | CNT_INTVAL },
- { "LED Deck A: IN", 17 | CNT_INTVAL },
- { "LED Deck A: OUT", 16 | CNT_INTVAL },
- { "LED Deck A: < BEAT", 19 | CNT_INTVAL },
- { "LED Deck A: BEAT >", 18 | CNT_INTVAL },
- { "LED Deck A: CUE/ABS", 21 | CNT_INTVAL },
- { "LED Deck A: CUP/REL", 20 | CNT_INTVAL },
- { "LED Deck A: PLAY", 23 | CNT_INTVAL },
- { "LED Deck A: SYNC", 22 | CNT_INTVAL },
-
- { "LED Deck B: FX1", 26 | CNT_INTVAL },
- { "LED Deck B: FX2", 27 | CNT_INTVAL },
- { "LED Deck B: IN", 15 | CNT_INTVAL },
- { "LED Deck B: OUT", 14 | CNT_INTVAL },
- { "LED Deck B: < BEAT", 13 | CNT_INTVAL },
- { "LED Deck B: BEAT >", 12 | CNT_INTVAL },
- { "LED Deck B: CUE/ABS", 11 | CNT_INTVAL },
- { "LED Deck B: CUP/REL", 10 | CNT_INTVAL },
- { "LED Deck B: PLAY", 9 | CNT_INTVAL },
- { "LED Deck B: SYNC", 8 | CNT_INTVAL },
-};
-
-static struct caiaq_controller kontrols4_controller[] = {
- { "LED: Master: Quant", 10 | CNT_INTVAL },
- { "LED: Master: Headphone", 11 | CNT_INTVAL },
- { "LED: Master: Master", 12 | CNT_INTVAL },
- { "LED: Master: Snap", 14 | CNT_INTVAL },
- { "LED: Master: Warning", 15 | CNT_INTVAL },
- { "LED: Master: Master button", 112 | CNT_INTVAL },
- { "LED: Master: Snap button", 113 | CNT_INTVAL },
- { "LED: Master: Rec", 118 | CNT_INTVAL },
- { "LED: Master: Size", 119 | CNT_INTVAL },
- { "LED: Master: Quant button", 120 | CNT_INTVAL },
- { "LED: Master: Browser button", 121 | CNT_INTVAL },
- { "LED: Master: Play button", 126 | CNT_INTVAL },
- { "LED: Master: Undo button", 127 | CNT_INTVAL },
-
- { "LED: Channel A: >", 4 | CNT_INTVAL },
- { "LED: Channel A: <", 5 | CNT_INTVAL },
- { "LED: Channel A: Meter 1", 97 | CNT_INTVAL },
- { "LED: Channel A: Meter 2", 98 | CNT_INTVAL },
- { "LED: Channel A: Meter 3", 99 | CNT_INTVAL },
- { "LED: Channel A: Meter 4", 100 | CNT_INTVAL },
- { "LED: Channel A: Meter 5", 101 | CNT_INTVAL },
- { "LED: Channel A: Meter 6", 102 | CNT_INTVAL },
- { "LED: Channel A: Meter clip", 103 | CNT_INTVAL },
- { "LED: Channel A: Active", 114 | CNT_INTVAL },
- { "LED: Channel A: Cue", 116 | CNT_INTVAL },
- { "LED: Channel A: FX1", 149 | CNT_INTVAL },
- { "LED: Channel A: FX2", 148 | CNT_INTVAL },
-
- { "LED: Channel B: >", 2 | CNT_INTVAL },
- { "LED: Channel B: <", 3 | CNT_INTVAL },
- { "LED: Channel B: Meter 1", 89 | CNT_INTVAL },
- { "LED: Channel B: Meter 2", 90 | CNT_INTVAL },
- { "LED: Channel B: Meter 3", 91 | CNT_INTVAL },
- { "LED: Channel B: Meter 4", 92 | CNT_INTVAL },
- { "LED: Channel B: Meter 5", 93 | CNT_INTVAL },
- { "LED: Channel B: Meter 6", 94 | CNT_INTVAL },
- { "LED: Channel B: Meter clip", 95 | CNT_INTVAL },
- { "LED: Channel B: Active", 122 | CNT_INTVAL },
- { "LED: Channel B: Cue", 125 | CNT_INTVAL },
- { "LED: Channel B: FX1", 147 | CNT_INTVAL },
- { "LED: Channel B: FX2", 146 | CNT_INTVAL },
-
- { "LED: Channel C: >", 6 | CNT_INTVAL },
- { "LED: Channel C: <", 7 | CNT_INTVAL },
- { "LED: Channel C: Meter 1", 105 | CNT_INTVAL },
- { "LED: Channel C: Meter 2", 106 | CNT_INTVAL },
- { "LED: Channel C: Meter 3", 107 | CNT_INTVAL },
- { "LED: Channel C: Meter 4", 108 | CNT_INTVAL },
- { "LED: Channel C: Meter 5", 109 | CNT_INTVAL },
- { "LED: Channel C: Meter 6", 110 | CNT_INTVAL },
- { "LED: Channel C: Meter clip", 111 | CNT_INTVAL },
- { "LED: Channel C: Active", 115 | CNT_INTVAL },
- { "LED: Channel C: Cue", 117 | CNT_INTVAL },
- { "LED: Channel C: FX1", 151 | CNT_INTVAL },
- { "LED: Channel C: FX2", 150 | CNT_INTVAL },
-
- { "LED: Channel D: >", 0 | CNT_INTVAL },
- { "LED: Channel D: <", 1 | CNT_INTVAL },
- { "LED: Channel D: Meter 1", 81 | CNT_INTVAL },
- { "LED: Channel D: Meter 2", 82 | CNT_INTVAL },
- { "LED: Channel D: Meter 3", 83 | CNT_INTVAL },
- { "LED: Channel D: Meter 4", 84 | CNT_INTVAL },
- { "LED: Channel D: Meter 5", 85 | CNT_INTVAL },
- { "LED: Channel D: Meter 6", 86 | CNT_INTVAL },
- { "LED: Channel D: Meter clip", 87 | CNT_INTVAL },
- { "LED: Channel D: Active", 123 | CNT_INTVAL },
- { "LED: Channel D: Cue", 124 | CNT_INTVAL },
- { "LED: Channel D: FX1", 145 | CNT_INTVAL },
- { "LED: Channel D: FX2", 144 | CNT_INTVAL },
-
- { "LED: Deck A: 1 (blue)", 22 | CNT_INTVAL },
- { "LED: Deck A: 1 (green)", 23 | CNT_INTVAL },
- { "LED: Deck A: 2 (blue)", 20 | CNT_INTVAL },
- { "LED: Deck A: 2 (green)", 21 | CNT_INTVAL },
- { "LED: Deck A: 3 (blue)", 18 | CNT_INTVAL },
- { "LED: Deck A: 3 (green)", 19 | CNT_INTVAL },
- { "LED: Deck A: 4 (blue)", 16 | CNT_INTVAL },
- { "LED: Deck A: 4 (green)", 17 | CNT_INTVAL },
- { "LED: Deck A: Load", 44 | CNT_INTVAL },
- { "LED: Deck A: Deck C button", 45 | CNT_INTVAL },
- { "LED: Deck A: In", 47 | CNT_INTVAL },
- { "LED: Deck A: Out", 46 | CNT_INTVAL },
- { "LED: Deck A: Shift", 24 | CNT_INTVAL },
- { "LED: Deck A: Sync", 27 | CNT_INTVAL },
- { "LED: Deck A: Cue", 26 | CNT_INTVAL },
- { "LED: Deck A: Play", 25 | CNT_INTVAL },
- { "LED: Deck A: Tempo up", 33 | CNT_INTVAL },
- { "LED: Deck A: Tempo down", 32 | CNT_INTVAL },
- { "LED: Deck A: Master", 34 | CNT_INTVAL },
- { "LED: Deck A: Keylock", 35 | CNT_INTVAL },
- { "LED: Deck A: Deck A", 37 | CNT_INTVAL },
- { "LED: Deck A: Deck C", 36 | CNT_INTVAL },
- { "LED: Deck A: Samples", 38 | CNT_INTVAL },
- { "LED: Deck A: On Air", 39 | CNT_INTVAL },
- { "LED: Deck A: Sample 1", 31 | CNT_INTVAL },
- { "LED: Deck A: Sample 2", 30 | CNT_INTVAL },
- { "LED: Deck A: Sample 3", 29 | CNT_INTVAL },
- { "LED: Deck A: Sample 4", 28 | CNT_INTVAL },
- { "LED: Deck A: Digit 1 - A", 55 | CNT_INTVAL },
- { "LED: Deck A: Digit 1 - B", 54 | CNT_INTVAL },
- { "LED: Deck A: Digit 1 - C", 53 | CNT_INTVAL },
- { "LED: Deck A: Digit 1 - D", 52 | CNT_INTVAL },
- { "LED: Deck A: Digit 1 - E", 51 | CNT_INTVAL },
- { "LED: Deck A: Digit 1 - F", 50 | CNT_INTVAL },
- { "LED: Deck A: Digit 1 - G", 49 | CNT_INTVAL },
- { "LED: Deck A: Digit 1 - dot", 48 | CNT_INTVAL },
- { "LED: Deck A: Digit 2 - A", 63 | CNT_INTVAL },
- { "LED: Deck A: Digit 2 - B", 62 | CNT_INTVAL },
- { "LED: Deck A: Digit 2 - C", 61 | CNT_INTVAL },
- { "LED: Deck A: Digit 2 - D", 60 | CNT_INTVAL },
- { "LED: Deck A: Digit 2 - E", 59 | CNT_INTVAL },
- { "LED: Deck A: Digit 2 - F", 58 | CNT_INTVAL },
- { "LED: Deck A: Digit 2 - G", 57 | CNT_INTVAL },
- { "LED: Deck A: Digit 2 - dot", 56 | CNT_INTVAL },
-
- { "LED: Deck B: 1 (blue)", 78 | CNT_INTVAL },
- { "LED: Deck B: 1 (green)", 79 | CNT_INTVAL },
- { "LED: Deck B: 2 (blue)", 76 | CNT_INTVAL },
- { "LED: Deck B: 2 (green)", 77 | CNT_INTVAL },
- { "LED: Deck B: 3 (blue)", 74 | CNT_INTVAL },
- { "LED: Deck B: 3 (green)", 75 | CNT_INTVAL },
- { "LED: Deck B: 4 (blue)", 72 | CNT_INTVAL },
- { "LED: Deck B: 4 (green)", 73 | CNT_INTVAL },
- { "LED: Deck B: Load", 180 | CNT_INTVAL },
- { "LED: Deck B: Deck D button", 181 | CNT_INTVAL },
- { "LED: Deck B: In", 183 | CNT_INTVAL },
- { "LED: Deck B: Out", 182 | CNT_INTVAL },
- { "LED: Deck B: Shift", 64 | CNT_INTVAL },
- { "LED: Deck B: Sync", 67 | CNT_INTVAL },
- { "LED: Deck B: Cue", 66 | CNT_INTVAL },
- { "LED: Deck B: Play", 65 | CNT_INTVAL },
- { "LED: Deck B: Tempo up", 185 | CNT_INTVAL },
- { "LED: Deck B: Tempo down", 184 | CNT_INTVAL },
- { "LED: Deck B: Master", 186 | CNT_INTVAL },
- { "LED: Deck B: Keylock", 187 | CNT_INTVAL },
- { "LED: Deck B: Deck B", 189 | CNT_INTVAL },
- { "LED: Deck B: Deck D", 188 | CNT_INTVAL },
- { "LED: Deck B: Samples", 190 | CNT_INTVAL },
- { "LED: Deck B: On Air", 191 | CNT_INTVAL },
- { "LED: Deck B: Sample 1", 71 | CNT_INTVAL },
- { "LED: Deck B: Sample 2", 70 | CNT_INTVAL },
- { "LED: Deck B: Sample 3", 69 | CNT_INTVAL },
- { "LED: Deck B: Sample 4", 68 | CNT_INTVAL },
- { "LED: Deck B: Digit 1 - A", 175 | CNT_INTVAL },
- { "LED: Deck B: Digit 1 - B", 174 | CNT_INTVAL },
- { "LED: Deck B: Digit 1 - C", 173 | CNT_INTVAL },
- { "LED: Deck B: Digit 1 - D", 172 | CNT_INTVAL },
- { "LED: Deck B: Digit 1 - E", 171 | CNT_INTVAL },
- { "LED: Deck B: Digit 1 - F", 170 | CNT_INTVAL },
- { "LED: Deck B: Digit 1 - G", 169 | CNT_INTVAL },
- { "LED: Deck B: Digit 1 - dot", 168 | CNT_INTVAL },
- { "LED: Deck B: Digit 2 - A", 167 | CNT_INTVAL },
- { "LED: Deck B: Digit 2 - B", 166 | CNT_INTVAL },
- { "LED: Deck B: Digit 2 - C", 165 | CNT_INTVAL },
- { "LED: Deck B: Digit 2 - D", 164 | CNT_INTVAL },
- { "LED: Deck B: Digit 2 - E", 163 | CNT_INTVAL },
- { "LED: Deck B: Digit 2 - F", 162 | CNT_INTVAL },
- { "LED: Deck B: Digit 2 - G", 161 | CNT_INTVAL },
- { "LED: Deck B: Digit 2 - dot", 160 | CNT_INTVAL },
-
- { "LED: FX1: dry/wet", 153 | CNT_INTVAL },
- { "LED: FX1: 1", 154 | CNT_INTVAL },
- { "LED: FX1: 2", 155 | CNT_INTVAL },
- { "LED: FX1: 3", 156 | CNT_INTVAL },
- { "LED: FX1: Mode", 157 | CNT_INTVAL },
- { "LED: FX2: dry/wet", 129 | CNT_INTVAL },
- { "LED: FX2: 1", 130 | CNT_INTVAL },
- { "LED: FX2: 2", 131 | CNT_INTVAL },
- { "LED: FX2: 3", 132 | CNT_INTVAL },
- { "LED: FX2: Mode", 133 | CNT_INTVAL },
-};
-
-static int __devinit add_controls(struct caiaq_controller *c, int num,
- struct snd_usb_caiaqdev *dev)
-{
- int i, ret;
- struct snd_kcontrol *kc;
-
- for (i = 0; i < num; i++, c++) {
- kcontrol_template.name = c->name;
- kcontrol_template.private_value = c->index;
- kc = snd_ctl_new1(&kcontrol_template, dev);
- ret = snd_ctl_add(dev->chip.card, kc);
- if (ret < 0)
- return ret;
- }
-
- return 0;
-}
-
-int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev)
-{
- int ret = 0;
-
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
- ret = add_controls(ak1_controller,
- ARRAY_SIZE(ak1_controller), dev);
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
- ret = add_controls(rk2_controller,
- ARRAY_SIZE(rk2_controller), dev);
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
- ret = add_controls(rk3_controller,
- ARRAY_SIZE(rk3_controller), dev);
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
- ret = add_controls(kore_controller,
- ARRAY_SIZE(kore_controller), dev);
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
- ret = add_controls(a8dj_controller,
- ARRAY_SIZE(a8dj_controller), dev);
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ):
- ret = add_controls(a4dj_controller,
- ARRAY_SIZE(a4dj_controller), dev);
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
- ret = add_controls(kontrolx1_controller,
- ARRAY_SIZE(kontrolx1_controller), dev);
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
- ret = add_controls(kontrols4_controller,
- ARRAY_SIZE(kontrols4_controller), dev);
- break;
- }
-
- return ret;
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/control.h b/ANDROID_3.4.5/sound/usb/caiaq/control.h
deleted file mode 100644
index 2e7ab1aa..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/control.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef CAIAQ_CONTROL_H
-#define CAIAQ_CONTROL_H
-
-int snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev);
-
-#endif /* CAIAQ_CONTROL_H */
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/device.c b/ANDROID_3.4.5/sound/usb/caiaq/device.c
deleted file mode 100644
index 64aed432..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/device.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- * caiaq.c: ALSA driver for caiaq/NativeInstruments devices
- *
- * Copyright (c) 2007 Daniel Mack <daniel@caiaq.de>
- * Karsten Wiese <fzu@wemgehoertderstaat.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <linux/moduleparam.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/gfp.h>
-#include <linux/usb.h>
-#include <sound/initval.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include "device.h"
-#include "audio.h"
-#include "midi.h"
-#include "control.h"
-#include "input.h"
-
-MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
-MODULE_DESCRIPTION("caiaq USB audio");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
- "{Native Instruments, RigKontrol3},"
- "{Native Instruments, Kore Controller},"
- "{Native Instruments, Kore Controller 2},"
- "{Native Instruments, Audio Kontrol 1},"
- "{Native Instruments, Audio 2 DJ},"
- "{Native Instruments, Audio 4 DJ},"
- "{Native Instruments, Audio 8 DJ},"
- "{Native Instruments, Traktor Audio 2},"
- "{Native Instruments, Session I/O},"
- "{Native Instruments, GuitarRig mobile}"
- "{Native Instruments, Traktor Kontrol X1}"
- "{Native Instruments, Traktor Kontrol S4}"
- "{Native Instruments, Maschine Controller}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
-static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int snd_card_used[SNDRV_CARDS];
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for the caiaq sound device");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for the caiaq soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable the caiaq soundcard.");
-
-enum {
- SAMPLERATE_44100 = 0,
- SAMPLERATE_48000 = 1,
- SAMPLERATE_96000 = 2,
- SAMPLERATE_192000 = 3,
- SAMPLERATE_88200 = 4,
- SAMPLERATE_INVALID = 0xff
-};
-
-enum {
- DEPTH_NONE = 0,
- DEPTH_16 = 1,
- DEPTH_24 = 2,
- DEPTH_32 = 3
-};
-
-static struct usb_device_id snd_usb_id_table[] = {
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_RIGKONTROL2
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_RIGKONTROL3
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_KORECONTROLLER
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_KORECONTROLLER2
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_AK1
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_AUDIO8DJ
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_SESSIONIO
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_GUITARRIGMOBILE
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_AUDIO4DJ
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_AUDIO2DJ
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_TRAKTORKONTROLX1
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_TRAKTORKONTROLS4
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_TRAKTORAUDIO2
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_MASCHINECONTROLLER
- },
- { /* terminator */ }
-};
-
-static void usb_ep1_command_reply_dispatch (struct urb* urb)
-{
- int ret;
- struct snd_usb_caiaqdev *dev = urb->context;
- unsigned char *buf = urb->transfer_buffer;
-
- if (urb->status || !dev) {
- log("received EP1 urb->status = %i\n", urb->status);
- return;
- }
-
- switch(buf[0]) {
- case EP1_CMD_GET_DEVICE_INFO:
- memcpy(&dev->spec, buf+1, sizeof(struct caiaq_device_spec));
- dev->spec.fw_version = le16_to_cpu(dev->spec.fw_version);
- debug("device spec (firmware %d): audio: %d in, %d out, "
- "MIDI: %d in, %d out, data alignment %d\n",
- dev->spec.fw_version,
- dev->spec.num_analog_audio_in,
- dev->spec.num_analog_audio_out,
- dev->spec.num_midi_in,
- dev->spec.num_midi_out,
- dev->spec.data_alignment);
-
- dev->spec_received++;
- wake_up(&dev->ep1_wait_queue);
- break;
- case EP1_CMD_AUDIO_PARAMS:
- dev->audio_parm_answer = buf[1];
- wake_up(&dev->ep1_wait_queue);
- break;
- case EP1_CMD_MIDI_READ:
- snd_usb_caiaq_midi_handle_input(dev, buf[1], buf + 3, buf[2]);
- break;
- case EP1_CMD_READ_IO:
- if (dev->chip.usb_id ==
- USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ)) {
- if (urb->actual_length > sizeof(dev->control_state))
- urb->actual_length = sizeof(dev->control_state);
- memcpy(dev->control_state, buf + 1, urb->actual_length);
- wake_up(&dev->ep1_wait_queue);
- break;
- }
-#ifdef CONFIG_SND_USB_CAIAQ_INPUT
- case EP1_CMD_READ_ERP:
- case EP1_CMD_READ_ANALOG:
- snd_usb_caiaq_input_dispatch(dev, buf, urb->actual_length);
-#endif
- break;
- }
-
- dev->ep1_in_urb.actual_length = 0;
- ret = usb_submit_urb(&dev->ep1_in_urb, GFP_ATOMIC);
- if (ret < 0)
- log("unable to submit urb. OOM!?\n");
-}
-
-int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *dev,
- unsigned char command,
- const unsigned char *buffer,
- int len)
-{
- int actual_len;
- struct usb_device *usb_dev = dev->chip.dev;
-
- if (!usb_dev)
- return -EIO;
-
- if (len > EP1_BUFSIZE - 1)
- len = EP1_BUFSIZE - 1;
-
- if (buffer && len > 0)
- memcpy(dev->ep1_out_buf+1, buffer, len);
-
- dev->ep1_out_buf[0] = command;
- return usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, 1),
- dev->ep1_out_buf, len+1, &actual_len, 200);
-}
-
-int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev,
- int rate, int depth, int bpp)
-{
- int ret;
- char tmp[5];
-
- switch (rate) {
- case 44100: tmp[0] = SAMPLERATE_44100; break;
- case 48000: tmp[0] = SAMPLERATE_48000; break;
- case 88200: tmp[0] = SAMPLERATE_88200; break;
- case 96000: tmp[0] = SAMPLERATE_96000; break;
- case 192000: tmp[0] = SAMPLERATE_192000; break;
- default: return -EINVAL;
- }
-
- switch (depth) {
- case 16: tmp[1] = DEPTH_16; break;
- case 24: tmp[1] = DEPTH_24; break;
- default: return -EINVAL;
- }
-
- tmp[2] = bpp & 0xff;
- tmp[3] = bpp >> 8;
- tmp[4] = 1; /* packets per microframe */
-
- debug("setting audio params: %d Hz, %d bits, %d bpp\n",
- rate, depth, bpp);
-
- dev->audio_parm_answer = -1;
- ret = snd_usb_caiaq_send_command(dev, EP1_CMD_AUDIO_PARAMS,
- tmp, sizeof(tmp));
-
- if (ret)
- return ret;
-
- if (!wait_event_timeout(dev->ep1_wait_queue,
- dev->audio_parm_answer >= 0, HZ))
- return -EPIPE;
-
- if (dev->audio_parm_answer != 1)
- debug("unable to set the device's audio params\n");
- else
- dev->bpp = bpp;
-
- return dev->audio_parm_answer == 1 ? 0 : -EINVAL;
-}
-
-int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *dev,
- int digital, int analog, int erp)
-{
- char tmp[3] = { digital, analog, erp };
- return snd_usb_caiaq_send_command(dev, EP1_CMD_AUTO_MSG,
- tmp, sizeof(tmp));
-}
-
-static void __devinit setup_card(struct snd_usb_caiaqdev *dev)
-{
- int ret;
- char val[4];
-
- /* device-specific startup specials */
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
- /* RigKontrol2 - display centered dash ('-') */
- val[0] = 0x00;
- val[1] = 0x00;
- val[2] = 0x01;
- snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, val, 3);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
- /* RigKontrol2 - display two centered dashes ('--') */
- val[0] = 0x00;
- val[1] = 0x40;
- val[2] = 0x40;
- val[3] = 0x00;
- snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, val, 4);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
- /* Audio Kontrol 1 - make USB-LED stop blinking */
- val[0] = 0x00;
- snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, val, 1);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
- /* Audio 8 DJ - trigger read of current settings */
- dev->control_state[0] = 0xff;
- snd_usb_caiaq_set_auto_msg(dev, 1, 0, 0);
- snd_usb_caiaq_send_command(dev, EP1_CMD_READ_IO, NULL, 0);
-
- if (!wait_event_timeout(dev->ep1_wait_queue,
- dev->control_state[0] != 0xff, HZ))
- return;
-
- /* fix up some defaults */
- if ((dev->control_state[1] != 2) ||
- (dev->control_state[2] != 3) ||
- (dev->control_state[4] != 2)) {
- dev->control_state[1] = 2;
- dev->control_state[2] = 3;
- dev->control_state[4] = 2;
- snd_usb_caiaq_send_command(dev,
- EP1_CMD_WRITE_IO, dev->control_state, 6);
- }
-
- break;
- }
-
- if (dev->spec.num_analog_audio_out +
- dev->spec.num_analog_audio_in +
- dev->spec.num_digital_audio_out +
- dev->spec.num_digital_audio_in > 0) {
- ret = snd_usb_caiaq_audio_init(dev);
- if (ret < 0)
- log("Unable to set up audio system (ret=%d)\n", ret);
- }
-
- if (dev->spec.num_midi_in +
- dev->spec.num_midi_out > 0) {
- ret = snd_usb_caiaq_midi_init(dev);
- if (ret < 0)
- log("Unable to set up MIDI system (ret=%d)\n", ret);
- }
-
-#ifdef CONFIG_SND_USB_CAIAQ_INPUT
- ret = snd_usb_caiaq_input_init(dev);
- if (ret < 0)
- log("Unable to set up input system (ret=%d)\n", ret);
-#endif
-
- /* finally, register the card and all its sub-instances */
- ret = snd_card_register(dev->chip.card);
- if (ret < 0) {
- log("snd_card_register() returned %d\n", ret);
- snd_card_free(dev->chip.card);
- }
-
- ret = snd_usb_caiaq_control_init(dev);
- if (ret < 0)
- log("Unable to set up control system (ret=%d)\n", ret);
-}
-
-static int create_card(struct usb_device *usb_dev,
- struct usb_interface *intf,
- struct snd_card **cardp)
-{
- int devnum;
- int err;
- struct snd_card *card;
- struct snd_usb_caiaqdev *dev;
-
- for (devnum = 0; devnum < SNDRV_CARDS; devnum++)
- if (enable[devnum] && !snd_card_used[devnum])
- break;
-
- if (devnum >= SNDRV_CARDS)
- return -ENODEV;
-
- err = snd_card_create(index[devnum], id[devnum], THIS_MODULE,
- sizeof(struct snd_usb_caiaqdev), &card);
- if (err < 0)
- return err;
-
- dev = caiaqdev(card);
- dev->chip.dev = usb_dev;
- dev->chip.card = card;
- dev->chip.usb_id = USB_ID(le16_to_cpu(usb_dev->descriptor.idVendor),
- le16_to_cpu(usb_dev->descriptor.idProduct));
- spin_lock_init(&dev->spinlock);
- snd_card_set_dev(card, &intf->dev);
-
- *cardp = card;
- return 0;
-}
-
-static int __devinit init_card(struct snd_usb_caiaqdev *dev)
-{
- char *c, usbpath[32];
- struct usb_device *usb_dev = dev->chip.dev;
- struct snd_card *card = dev->chip.card;
- int err, len;
-
- if (usb_set_interface(usb_dev, 0, 1) != 0) {
- log("can't set alt interface.\n");
- return -EIO;
- }
-
- usb_init_urb(&dev->ep1_in_urb);
- usb_init_urb(&dev->midi_out_urb);
-
- usb_fill_bulk_urb(&dev->ep1_in_urb, usb_dev,
- usb_rcvbulkpipe(usb_dev, 0x1),
- dev->ep1_in_buf, EP1_BUFSIZE,
- usb_ep1_command_reply_dispatch, dev);
-
- usb_fill_bulk_urb(&dev->midi_out_urb, usb_dev,
- usb_sndbulkpipe(usb_dev, 0x1),
- dev->midi_out_buf, EP1_BUFSIZE,
- snd_usb_caiaq_midi_output_done, dev);
-
- init_waitqueue_head(&dev->ep1_wait_queue);
- init_waitqueue_head(&dev->prepare_wait_queue);
-
- if (usb_submit_urb(&dev->ep1_in_urb, GFP_KERNEL) != 0)
- return -EIO;
-
- err = snd_usb_caiaq_send_command(dev, EP1_CMD_GET_DEVICE_INFO, NULL, 0);
- if (err)
- return err;
-
- if (!wait_event_timeout(dev->ep1_wait_queue, dev->spec_received, HZ))
- return -ENODEV;
-
- usb_string(usb_dev, usb_dev->descriptor.iManufacturer,
- dev->vendor_name, CAIAQ_USB_STR_LEN);
-
- usb_string(usb_dev, usb_dev->descriptor.iProduct,
- dev->product_name, CAIAQ_USB_STR_LEN);
-
- strlcpy(card->driver, MODNAME, sizeof(card->driver));
- strlcpy(card->shortname, dev->product_name, sizeof(card->shortname));
- strlcpy(card->mixername, dev->product_name, sizeof(card->mixername));
-
- /* if the id was not passed as module option, fill it with a shortened
- * version of the product string which does not contain any
- * whitespaces */
-
- if (*card->id == '\0') {
- char id[sizeof(card->id)];
-
- memset(id, 0, sizeof(id));
-
- for (c = card->shortname, len = 0;
- *c && len < sizeof(card->id); c++)
- if (*c != ' ')
- id[len++] = *c;
-
- snd_card_set_id(card, id);
- }
-
- usb_make_path(usb_dev, usbpath, sizeof(usbpath));
- snprintf(card->longname, sizeof(card->longname),
- "%s %s (%s)",
- dev->vendor_name, dev->product_name, usbpath);
-
- setup_card(dev);
- return 0;
-}
-
-static int __devinit snd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- int ret;
- struct snd_card *card;
- struct usb_device *device = interface_to_usbdev(intf);
-
- ret = create_card(device, intf, &card);
-
- if (ret < 0)
- return ret;
-
- usb_set_intfdata(intf, card);
- ret = init_card(caiaqdev(card));
- if (ret < 0) {
- log("unable to init card! (ret=%d)\n", ret);
- snd_card_free(card);
- return ret;
- }
-
- return 0;
-}
-
-static void snd_disconnect(struct usb_interface *intf)
-{
- struct snd_usb_caiaqdev *dev;
- struct snd_card *card = usb_get_intfdata(intf);
-
- debug("%s(%p)\n", __func__, intf);
-
- if (!card)
- return;
-
- dev = caiaqdev(card);
- snd_card_disconnect(card);
-
-#ifdef CONFIG_SND_USB_CAIAQ_INPUT
- snd_usb_caiaq_input_free(dev);
-#endif
- snd_usb_caiaq_audio_free(dev);
-
- usb_kill_urb(&dev->ep1_in_urb);
- usb_kill_urb(&dev->midi_out_urb);
-
- snd_card_free(card);
- usb_reset_device(interface_to_usbdev(intf));
-}
-
-
-MODULE_DEVICE_TABLE(usb, snd_usb_id_table);
-static struct usb_driver snd_usb_driver = {
- .name = MODNAME,
- .probe = snd_probe,
- .disconnect = snd_disconnect,
- .id_table = snd_usb_id_table,
-};
-
-module_usb_driver(snd_usb_driver);
-
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/device.h b/ANDROID_3.4.5/sound/usb/caiaq/device.h
deleted file mode 100644
index 562b0bff..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/device.h
+++ /dev/null
@@ -1,140 +0,0 @@
-#ifndef CAIAQ_DEVICE_H
-#define CAIAQ_DEVICE_H
-
-#include "../usbaudio.h"
-
-#define USB_VID_NATIVEINSTRUMENTS 0x17cc
-
-#define USB_PID_RIGKONTROL2 0x1969
-#define USB_PID_RIGKONTROL3 0x1940
-#define USB_PID_KORECONTROLLER 0x4711
-#define USB_PID_KORECONTROLLER2 0x4712
-#define USB_PID_AK1 0x0815
-#define USB_PID_AUDIO2DJ 0x041c
-#define USB_PID_AUDIO4DJ 0x0839
-#define USB_PID_AUDIO8DJ 0x1978
-#define USB_PID_SESSIONIO 0x1915
-#define USB_PID_GUITARRIGMOBILE 0x0d8d
-#define USB_PID_TRAKTORKONTROLX1 0x2305
-#define USB_PID_TRAKTORKONTROLS4 0xbaff
-#define USB_PID_TRAKTORAUDIO2 0x041d
-#define USB_PID_MASCHINECONTROLLER 0x0808
-
-#define EP1_BUFSIZE 64
-#define EP4_BUFSIZE 512
-#define CAIAQ_USB_STR_LEN 0xff
-#define MAX_STREAMS 32
-
-//#define SND_USB_CAIAQ_DEBUG
-
-#define MODNAME "snd-usb-caiaq"
-#define log(x...) snd_printk(KERN_WARNING MODNAME" log: " x)
-
-#ifdef SND_USB_CAIAQ_DEBUG
-#define debug(x...) snd_printk(KERN_WARNING MODNAME " debug: " x)
-#else
-#define debug(x...) do { } while(0)
-#endif
-
-#define EP1_CMD_GET_DEVICE_INFO 0x1
-#define EP1_CMD_READ_ERP 0x2
-#define EP1_CMD_READ_ANALOG 0x3
-#define EP1_CMD_READ_IO 0x4
-#define EP1_CMD_WRITE_IO 0x5
-#define EP1_CMD_MIDI_READ 0x6
-#define EP1_CMD_MIDI_WRITE 0x7
-#define EP1_CMD_AUDIO_PARAMS 0x9
-#define EP1_CMD_AUTO_MSG 0xb
-#define EP1_CMD_DIMM_LEDS 0xc
-
-struct caiaq_device_spec {
- unsigned short fw_version;
- unsigned char hw_subtype;
- unsigned char num_erp;
- unsigned char num_analog_in;
- unsigned char num_digital_in;
- unsigned char num_digital_out;
- unsigned char num_analog_audio_out;
- unsigned char num_analog_audio_in;
- unsigned char num_digital_audio_out;
- unsigned char num_digital_audio_in;
- unsigned char num_midi_out;
- unsigned char num_midi_in;
- unsigned char data_alignment;
-} __attribute__ ((packed));
-
-struct snd_usb_caiaq_cb_info;
-
-struct snd_usb_caiaqdev {
- struct snd_usb_audio chip;
-
- struct urb ep1_in_urb;
- struct urb midi_out_urb;
- struct urb **data_urbs_in;
- struct urb **data_urbs_out;
- struct snd_usb_caiaq_cb_info *data_cb_info;
-
- unsigned char ep1_in_buf[EP1_BUFSIZE];
- unsigned char ep1_out_buf[EP1_BUFSIZE];
- unsigned char midi_out_buf[EP1_BUFSIZE];
-
- struct caiaq_device_spec spec;
- spinlock_t spinlock;
- wait_queue_head_t ep1_wait_queue;
- wait_queue_head_t prepare_wait_queue;
- int spec_received, audio_parm_answer;
- int midi_out_active;
-
- char vendor_name[CAIAQ_USB_STR_LEN];
- char product_name[CAIAQ_USB_STR_LEN];
-
- int n_streams, n_audio_in, n_audio_out;
- int streaming, first_packet, output_running;
- int audio_in_buf_pos[MAX_STREAMS];
- int audio_out_buf_pos[MAX_STREAMS];
- int period_in_count[MAX_STREAMS];
- int period_out_count[MAX_STREAMS];
- int input_panic, output_panic, warned;
- char *audio_in_buf, *audio_out_buf;
- unsigned int samplerates, bpp;
- unsigned long outurb_active_mask;
-
- struct snd_pcm_substream *sub_playback[MAX_STREAMS];
- struct snd_pcm_substream *sub_capture[MAX_STREAMS];
-
- /* Controls */
- unsigned char control_state[256];
- unsigned char ep8_out_buf[2];
-
- /* Linux input */
-#ifdef CONFIG_SND_USB_CAIAQ_INPUT
- struct input_dev *input_dev;
- char phys[64]; /* physical device path */
- unsigned short keycode[128];
- struct urb *ep4_in_urb;
- unsigned char ep4_in_buf[EP4_BUFSIZE];
-#endif
-
- /* ALSA */
- struct snd_pcm *pcm;
- struct snd_pcm_hardware pcm_info;
- struct snd_rawmidi *rmidi;
- struct snd_rawmidi_substream *midi_receive_substream;
- struct snd_rawmidi_substream *midi_out_substream;
-};
-
-struct snd_usb_caiaq_cb_info {
- struct snd_usb_caiaqdev *dev;
- int index;
-};
-
-#define caiaqdev(c) ((struct snd_usb_caiaqdev*)(c)->private_data)
-
-int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, int rate, int depth, int bbp);
-int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev, int digital, int analog, int erp);
-int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *dev,
- unsigned char command,
- const unsigned char *buffer,
- int len);
-
-#endif /* CAIAQ_DEVICE_H */
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/input.c b/ANDROID_3.4.5/sound/usb/caiaq/input.c
deleted file mode 100644
index 26a121b4..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/input.c
+++ /dev/null
@@ -1,842 +0,0 @@
-/*
- * Copyright (c) 2006,2007 Daniel Mack, Tim Ruetz
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <linux/gfp.h>
-#include <linux/init.h>
-#include <linux/usb.h>
-#include <linux/usb/input.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include "device.h"
-#include "input.h"
-
-static unsigned short keycode_ak1[] = { KEY_C, KEY_B, KEY_A };
-static unsigned short keycode_rk2[] = { KEY_1, KEY_2, KEY_3, KEY_4,
- KEY_5, KEY_6, KEY_7 };
-static unsigned short keycode_rk3[] = { KEY_1, KEY_2, KEY_3, KEY_4,
- KEY_5, KEY_6, KEY_7, KEY_8, KEY_9 };
-
-static unsigned short keycode_kore[] = {
- KEY_FN_F1, /* "menu" */
- KEY_FN_F7, /* "lcd backlight */
- KEY_FN_F2, /* "control" */
- KEY_FN_F3, /* "enter" */
- KEY_FN_F4, /* "view" */
- KEY_FN_F5, /* "esc" */
- KEY_FN_F6, /* "sound" */
- KEY_FN_F8, /* array spacer, never triggered. */
- KEY_RIGHT,
- KEY_DOWN,
- KEY_UP,
- KEY_LEFT,
- KEY_SOUND, /* "listen" */
- KEY_RECORD,
- KEY_PLAYPAUSE,
- KEY_STOP,
- BTN_4, /* 8 softkeys */
- BTN_3,
- BTN_2,
- BTN_1,
- BTN_8,
- BTN_7,
- BTN_6,
- BTN_5,
- KEY_BRL_DOT4, /* touch sensitive knobs */
- KEY_BRL_DOT3,
- KEY_BRL_DOT2,
- KEY_BRL_DOT1,
- KEY_BRL_DOT8,
- KEY_BRL_DOT7,
- KEY_BRL_DOT6,
- KEY_BRL_DOT5
-};
-
-#define MASCHINE_BUTTONS (42)
-#define MASCHINE_BUTTON(X) ((X) + BTN_MISC)
-#define MASCHINE_PADS (16)
-#define MASCHINE_PAD(X) ((X) + ABS_PRESSURE)
-
-static unsigned short keycode_maschine[] = {
- MASCHINE_BUTTON(40), /* mute */
- MASCHINE_BUTTON(39), /* solo */
- MASCHINE_BUTTON(38), /* select */
- MASCHINE_BUTTON(37), /* duplicate */
- MASCHINE_BUTTON(36), /* navigate */
- MASCHINE_BUTTON(35), /* pad mode */
- MASCHINE_BUTTON(34), /* pattern */
- MASCHINE_BUTTON(33), /* scene */
- KEY_RESERVED, /* spacer */
-
- MASCHINE_BUTTON(30), /* rec */
- MASCHINE_BUTTON(31), /* erase */
- MASCHINE_BUTTON(32), /* shift */
- MASCHINE_BUTTON(28), /* grid */
- MASCHINE_BUTTON(27), /* > */
- MASCHINE_BUTTON(26), /* < */
- MASCHINE_BUTTON(25), /* restart */
-
- MASCHINE_BUTTON(21), /* E */
- MASCHINE_BUTTON(22), /* F */
- MASCHINE_BUTTON(23), /* G */
- MASCHINE_BUTTON(24), /* H */
- MASCHINE_BUTTON(20), /* D */
- MASCHINE_BUTTON(19), /* C */
- MASCHINE_BUTTON(18), /* B */
- MASCHINE_BUTTON(17), /* A */
-
- MASCHINE_BUTTON(0), /* control */
- MASCHINE_BUTTON(2), /* browse */
- MASCHINE_BUTTON(4), /* < */
- MASCHINE_BUTTON(6), /* snap */
- MASCHINE_BUTTON(7), /* autowrite */
- MASCHINE_BUTTON(5), /* > */
- MASCHINE_BUTTON(3), /* sampling */
- MASCHINE_BUTTON(1), /* step */
-
- MASCHINE_BUTTON(15), /* 8 softkeys */
- MASCHINE_BUTTON(14),
- MASCHINE_BUTTON(13),
- MASCHINE_BUTTON(12),
- MASCHINE_BUTTON(11),
- MASCHINE_BUTTON(10),
- MASCHINE_BUTTON(9),
- MASCHINE_BUTTON(8),
-
- MASCHINE_BUTTON(16), /* note repeat */
- MASCHINE_BUTTON(29) /* play */
-};
-
-#define KONTROLX1_INPUTS (40)
-#define KONTROLS4_BUTTONS (12 * 8)
-#define KONTROLS4_AXIS (46)
-
-#define KONTROLS4_BUTTON(X) ((X) + BTN_MISC)
-#define KONTROLS4_ABS(X) ((X) + ABS_HAT0X)
-
-#define DEG90 (range / 2)
-#define DEG180 (range)
-#define DEG270 (DEG90 + DEG180)
-#define DEG360 (DEG180 * 2)
-#define HIGH_PEAK (268)
-#define LOW_PEAK (-7)
-
-/* some of these devices have endless rotation potentiometers
- * built in which use two tapers, 90 degrees phase shifted.
- * this algorithm decodes them to one single value, ranging
- * from 0 to 999 */
-static unsigned int decode_erp(unsigned char a, unsigned char b)
-{
- int weight_a, weight_b;
- int pos_a, pos_b;
- int ret;
- int range = HIGH_PEAK - LOW_PEAK;
- int mid_value = (HIGH_PEAK + LOW_PEAK) / 2;
-
- weight_b = abs(mid_value - a) - (range / 2 - 100) / 2;
-
- if (weight_b < 0)
- weight_b = 0;
-
- if (weight_b > 100)
- weight_b = 100;
-
- weight_a = 100 - weight_b;
-
- if (a < mid_value) {
- /* 0..90 and 270..360 degrees */
- pos_b = b - LOW_PEAK + DEG270;
- if (pos_b >= DEG360)
- pos_b -= DEG360;
- } else
- /* 90..270 degrees */
- pos_b = HIGH_PEAK - b + DEG90;
-
-
- if (b > mid_value)
- /* 0..180 degrees */
- pos_a = a - LOW_PEAK;
- else
- /* 180..360 degrees */
- pos_a = HIGH_PEAK - a + DEG180;
-
- /* interpolate both slider values, depending on weight factors */
- /* 0..99 x DEG360 */
- ret = pos_a * weight_a + pos_b * weight_b;
-
- /* normalize to 0..999 */
- ret *= 10;
- ret /= DEG360;
-
- if (ret < 0)
- ret += 1000;
-
- if (ret >= 1000)
- ret -= 1000;
-
- return ret;
-}
-
-#undef DEG90
-#undef DEG180
-#undef DEG270
-#undef DEG360
-#undef HIGH_PEAK
-#undef LOW_PEAK
-
-static inline void snd_caiaq_input_report_abs(struct snd_usb_caiaqdev *dev,
- int axis, const unsigned char *buf,
- int offset)
-{
- input_report_abs(dev->input_dev, axis,
- (buf[offset * 2] << 8) | buf[offset * 2 + 1]);
-}
-
-static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev,
- const unsigned char *buf,
- unsigned int len)
-{
- struct input_dev *input_dev = dev->input_dev;
-
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
- snd_caiaq_input_report_abs(dev, ABS_X, buf, 2);
- snd_caiaq_input_report_abs(dev, ABS_Y, buf, 0);
- snd_caiaq_input_report_abs(dev, ABS_Z, buf, 1);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
- snd_caiaq_input_report_abs(dev, ABS_X, buf, 0);
- snd_caiaq_input_report_abs(dev, ABS_Y, buf, 1);
- snd_caiaq_input_report_abs(dev, ABS_Z, buf, 2);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
- snd_caiaq_input_report_abs(dev, ABS_HAT0X, buf, 4);
- snd_caiaq_input_report_abs(dev, ABS_HAT0Y, buf, 2);
- snd_caiaq_input_report_abs(dev, ABS_HAT1X, buf, 6);
- snd_caiaq_input_report_abs(dev, ABS_HAT1Y, buf, 1);
- snd_caiaq_input_report_abs(dev, ABS_HAT2X, buf, 7);
- snd_caiaq_input_report_abs(dev, ABS_HAT2Y, buf, 0);
- snd_caiaq_input_report_abs(dev, ABS_HAT3X, buf, 5);
- snd_caiaq_input_report_abs(dev, ABS_HAT3Y, buf, 3);
- break;
- }
-
- input_sync(input_dev);
-}
-
-static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev,
- const char *buf, unsigned int len)
-{
- struct input_dev *input_dev = dev->input_dev;
- int i;
-
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
- i = decode_erp(buf[0], buf[1]);
- input_report_abs(input_dev, ABS_X, i);
- input_sync(input_dev);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
- i = decode_erp(buf[7], buf[5]);
- input_report_abs(input_dev, ABS_HAT0X, i);
- i = decode_erp(buf[12], buf[14]);
- input_report_abs(input_dev, ABS_HAT0Y, i);
- i = decode_erp(buf[15], buf[13]);
- input_report_abs(input_dev, ABS_HAT1X, i);
- i = decode_erp(buf[0], buf[2]);
- input_report_abs(input_dev, ABS_HAT1Y, i);
- i = decode_erp(buf[3], buf[1]);
- input_report_abs(input_dev, ABS_HAT2X, i);
- i = decode_erp(buf[8], buf[10]);
- input_report_abs(input_dev, ABS_HAT2Y, i);
- i = decode_erp(buf[11], buf[9]);
- input_report_abs(input_dev, ABS_HAT3X, i);
- i = decode_erp(buf[4], buf[6]);
- input_report_abs(input_dev, ABS_HAT3Y, i);
- input_sync(input_dev);
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
- /* 4 under the left screen */
- input_report_abs(input_dev, ABS_HAT0X, decode_erp(buf[21], buf[20]));
- input_report_abs(input_dev, ABS_HAT0Y, decode_erp(buf[15], buf[14]));
- input_report_abs(input_dev, ABS_HAT1X, decode_erp(buf[9], buf[8]));
- input_report_abs(input_dev, ABS_HAT1Y, decode_erp(buf[3], buf[2]));
-
- /* 4 under the right screen */
- input_report_abs(input_dev, ABS_HAT2X, decode_erp(buf[19], buf[18]));
- input_report_abs(input_dev, ABS_HAT2Y, decode_erp(buf[13], buf[12]));
- input_report_abs(input_dev, ABS_HAT3X, decode_erp(buf[7], buf[6]));
- input_report_abs(input_dev, ABS_HAT3Y, decode_erp(buf[1], buf[0]));
-
- /* volume */
- input_report_abs(input_dev, ABS_RX, decode_erp(buf[17], buf[16]));
- /* tempo */
- input_report_abs(input_dev, ABS_RY, decode_erp(buf[11], buf[10]));
- /* swing */
- input_report_abs(input_dev, ABS_RZ, decode_erp(buf[5], buf[4]));
-
- input_sync(input_dev);
- break;
- }
-}
-
-static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev,
- unsigned char *buf, unsigned int len)
-{
- struct input_dev *input_dev = dev->input_dev;
- unsigned short *keycode = input_dev->keycode;
- int i;
-
- if (!keycode)
- return;
-
- if (input_dev->id.product == USB_PID_RIGKONTROL2)
- for (i = 0; i < len; i++)
- buf[i] = ~buf[i];
-
- for (i = 0; i < input_dev->keycodemax && i < len * 8; i++)
- input_report_key(input_dev, keycode[i],
- buf[i / 8] & (1 << (i % 8)));
-
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
- input_report_abs(dev->input_dev, ABS_MISC, 255 - buf[4]);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
- /* rotary encoders */
- input_report_abs(dev->input_dev, ABS_X, buf[5] & 0xf);
- input_report_abs(dev->input_dev, ABS_Y, buf[5] >> 4);
- input_report_abs(dev->input_dev, ABS_Z, buf[6] & 0xf);
- input_report_abs(dev->input_dev, ABS_MISC, buf[6] >> 4);
- break;
- }
-
- input_sync(input_dev);
-}
-
-#define TKS4_MSGBLOCK_SIZE 16
-
-static void snd_usb_caiaq_tks4_dispatch(struct snd_usb_caiaqdev *dev,
- const unsigned char *buf,
- unsigned int len)
-{
- while (len) {
- unsigned int i, block_id = (buf[0] << 8) | buf[1];
-
- switch (block_id) {
- case 0:
- /* buttons */
- for (i = 0; i < KONTROLS4_BUTTONS; i++)
- input_report_key(dev->input_dev, KONTROLS4_BUTTON(i),
- (buf[4 + (i / 8)] >> (i % 8)) & 1);
- break;
-
- case 1:
- /* left wheel */
- input_report_abs(dev->input_dev, KONTROLS4_ABS(36), buf[9] | ((buf[8] & 0x3) << 8));
- /* right wheel */
- input_report_abs(dev->input_dev, KONTROLS4_ABS(37), buf[13] | ((buf[12] & 0x3) << 8));
-
- /* rotary encoders */
- input_report_abs(dev->input_dev, KONTROLS4_ABS(38), buf[3] & 0xf);
- input_report_abs(dev->input_dev, KONTROLS4_ABS(39), buf[4] >> 4);
- input_report_abs(dev->input_dev, KONTROLS4_ABS(40), buf[4] & 0xf);
- input_report_abs(dev->input_dev, KONTROLS4_ABS(41), buf[5] >> 4);
- input_report_abs(dev->input_dev, KONTROLS4_ABS(42), buf[5] & 0xf);
- input_report_abs(dev->input_dev, KONTROLS4_ABS(43), buf[6] >> 4);
- input_report_abs(dev->input_dev, KONTROLS4_ABS(44), buf[6] & 0xf);
- input_report_abs(dev->input_dev, KONTROLS4_ABS(45), buf[7] >> 4);
- input_report_abs(dev->input_dev, KONTROLS4_ABS(46), buf[7] & 0xf);
-
- break;
- case 2:
- /* Volume Fader Channel D */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(0), buf, 1);
- /* Volume Fader Channel B */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(1), buf, 2);
- /* Volume Fader Channel A */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(2), buf, 3);
- /* Volume Fader Channel C */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(3), buf, 4);
- /* Loop Volume */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(4), buf, 6);
- /* Crossfader */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(7), buf, 7);
-
- break;
-
- case 3:
- /* Tempo Fader R */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(6), buf, 3);
- /* Tempo Fader L */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(5), buf, 4);
- /* Mic Volume */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(8), buf, 6);
- /* Cue Mix */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(9), buf, 7);
-
- break;
-
- case 4:
- /* Wheel distance sensor L */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(10), buf, 1);
- /* Wheel distance sensor R */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(11), buf, 2);
- /* Channel D EQ - Filter */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(12), buf, 3);
- /* Channel D EQ - Low */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(13), buf, 4);
- /* Channel D EQ - Mid */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(14), buf, 5);
- /* Channel D EQ - Hi */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(15), buf, 6);
- /* FX2 - dry/wet */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(16), buf, 7);
-
- break;
-
- case 5:
- /* FX2 - 1 */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(17), buf, 1);
- /* FX2 - 2 */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(18), buf, 2);
- /* FX2 - 3 */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(19), buf, 3);
- /* Channel B EQ - Filter */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(20), buf, 4);
- /* Channel B EQ - Low */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(21), buf, 5);
- /* Channel B EQ - Mid */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(22), buf, 6);
- /* Channel B EQ - Hi */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(23), buf, 7);
-
- break;
-
- case 6:
- /* Channel A EQ - Filter */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(24), buf, 1);
- /* Channel A EQ - Low */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(25), buf, 2);
- /* Channel A EQ - Mid */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(26), buf, 3);
- /* Channel A EQ - Hi */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(27), buf, 4);
- /* Channel C EQ - Filter */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(28), buf, 5);
- /* Channel C EQ - Low */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(29), buf, 6);
- /* Channel C EQ - Mid */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(30), buf, 7);
-
- break;
-
- case 7:
- /* Channel C EQ - Hi */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(31), buf, 1);
- /* FX1 - wet/dry */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(32), buf, 2);
- /* FX1 - 1 */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(33), buf, 3);
- /* FX1 - 2 */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(34), buf, 4);
- /* FX1 - 3 */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(35), buf, 5);
-
- break;
-
- default:
- debug("%s(): bogus block (id %d)\n",
- __func__, block_id);
- return;
- }
-
- len -= TKS4_MSGBLOCK_SIZE;
- buf += TKS4_MSGBLOCK_SIZE;
- }
-
- input_sync(dev->input_dev);
-}
-
-#define MASCHINE_MSGBLOCK_SIZE 2
-
-static void snd_usb_caiaq_maschine_dispatch(struct snd_usb_caiaqdev *dev,
- const unsigned char *buf,
- unsigned int len)
-{
- unsigned int i, pad_id;
- uint16_t pressure;
-
- for (i = 0; i < MASCHINE_PADS; i++) {
- pressure = be16_to_cpu(buf[i * 2] << 8 | buf[(i * 2) + 1]);
- pad_id = pressure >> 12;
-
- input_report_abs(dev->input_dev, MASCHINE_PAD(pad_id), pressure & 0xfff);
- }
-
- input_sync(dev->input_dev);
-}
-
-static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb)
-{
- struct snd_usb_caiaqdev *dev = urb->context;
- unsigned char *buf = urb->transfer_buffer;
- int ret;
-
- if (urb->status || !dev || urb != dev->ep4_in_urb)
- return;
-
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
- if (urb->actual_length < 24)
- goto requeue;
-
- if (buf[0] & 0x3)
- snd_caiaq_input_read_io(dev, buf + 1, 7);
-
- if (buf[0] & 0x4)
- snd_caiaq_input_read_analog(dev, buf + 8, 16);
-
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
- snd_usb_caiaq_tks4_dispatch(dev, buf, urb->actual_length);
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
- if (urb->actual_length < (MASCHINE_PADS * MASCHINE_MSGBLOCK_SIZE))
- goto requeue;
-
- snd_usb_caiaq_maschine_dispatch(dev, buf, urb->actual_length);
- break;
- }
-
-requeue:
- dev->ep4_in_urb->actual_length = 0;
- ret = usb_submit_urb(dev->ep4_in_urb, GFP_ATOMIC);
- if (ret < 0)
- log("unable to submit urb. OOM!?\n");
-}
-
-static int snd_usb_caiaq_input_open(struct input_dev *idev)
-{
- struct snd_usb_caiaqdev *dev = input_get_drvdata(idev);
-
- if (!dev)
- return -EINVAL;
-
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
- if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0)
- return -EIO;
- break;
- }
-
- return 0;
-}
-
-static void snd_usb_caiaq_input_close(struct input_dev *idev)
-{
- struct snd_usb_caiaqdev *dev = input_get_drvdata(idev);
-
- if (!dev)
- return;
-
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
- usb_kill_urb(dev->ep4_in_urb);
- break;
- }
-}
-
-void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev,
- char *buf,
- unsigned int len)
-{
- if (!dev->input_dev || len < 1)
- return;
-
- switch (buf[0]) {
- case EP1_CMD_READ_ANALOG:
- snd_caiaq_input_read_analog(dev, buf + 1, len - 1);
- break;
- case EP1_CMD_READ_ERP:
- snd_caiaq_input_read_erp(dev, buf + 1, len - 1);
- break;
- case EP1_CMD_READ_IO:
- snd_caiaq_input_read_io(dev, buf + 1, len - 1);
- break;
- }
-}
-
-int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
-{
- struct usb_device *usb_dev = dev->chip.dev;
- struct input_dev *input;
- int i, ret = 0;
-
- input = input_allocate_device();
- if (!input)
- return -ENOMEM;
-
- usb_make_path(usb_dev, dev->phys, sizeof(dev->phys));
- strlcat(dev->phys, "/input0", sizeof(dev->phys));
-
- input->name = dev->product_name;
- input->phys = dev->phys;
- usb_to_input_id(usb_dev, &input->id);
- input->dev.parent = &usb_dev->dev;
-
- input_set_drvdata(input, dev);
-
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
- input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
- BIT_MASK(ABS_Z);
- BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_rk2));
- memcpy(dev->keycode, keycode_rk2, sizeof(keycode_rk2));
- input->keycodemax = ARRAY_SIZE(keycode_rk2);
- input_set_abs_params(input, ABS_X, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10);
- snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
- input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
- BIT_MASK(ABS_Z);
- BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_rk3));
- memcpy(dev->keycode, keycode_rk3, sizeof(keycode_rk3));
- input->keycodemax = ARRAY_SIZE(keycode_rk3);
- input_set_abs_params(input, ABS_X, 0, 1024, 0, 10);
- input_set_abs_params(input, ABS_Y, 0, 1024, 0, 10);
- input_set_abs_params(input, ABS_Z, 0, 1024, 0, 10);
- snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
- input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- input->absbit[0] = BIT_MASK(ABS_X);
- BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_ak1));
- memcpy(dev->keycode, keycode_ak1, sizeof(keycode_ak1));
- input->keycodemax = ARRAY_SIZE(keycode_ak1);
- input_set_abs_params(input, ABS_X, 0, 999, 0, 10);
- snd_usb_caiaq_set_auto_msg(dev, 1, 0, 5);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
- input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
- BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) |
- BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) |
- BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) |
- BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
- BIT_MASK(ABS_Z);
- input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
- BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_kore));
- memcpy(dev->keycode, keycode_kore, sizeof(keycode_kore));
- input->keycodemax = ARRAY_SIZE(keycode_kore);
- input_set_abs_params(input, ABS_HAT0X, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT0Y, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT1X, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT1Y, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT2X, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT2Y, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT3X, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT3Y, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_X, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_MISC, 0, 255, 0, 1);
- snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
- input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
- BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) |
- BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) |
- BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) |
- BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
- BIT_MASK(ABS_Z);
- input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
- BUILD_BUG_ON(sizeof(dev->keycode) < KONTROLX1_INPUTS);
- for (i = 0; i < KONTROLX1_INPUTS; i++)
- dev->keycode[i] = BTN_MISC + i;
- input->keycodemax = KONTROLX1_INPUTS;
-
- /* analog potentiometers */
- input_set_abs_params(input, ABS_HAT0X, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_HAT0Y, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_HAT1X, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_HAT1Y, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_HAT2X, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_HAT2Y, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_HAT3X, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_HAT3Y, 0, 4096, 0, 10);
-
- /* rotary encoders */
- input_set_abs_params(input, ABS_X, 0, 0xf, 0, 1);
- input_set_abs_params(input, ABS_Y, 0, 0xf, 0, 1);
- input_set_abs_params(input, ABS_Z, 0, 0xf, 0, 1);
- input_set_abs_params(input, ABS_MISC, 0, 0xf, 0, 1);
-
- dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->ep4_in_urb) {
- ret = -ENOMEM;
- goto exit_free_idev;
- }
-
- usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev,
- usb_rcvbulkpipe(usb_dev, 0x4),
- dev->ep4_in_buf, EP4_BUFSIZE,
- snd_usb_caiaq_ep4_reply_dispatch, dev);
-
- snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
-
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
- input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- BUILD_BUG_ON(sizeof(dev->keycode) < KONTROLS4_BUTTONS);
- for (i = 0; i < KONTROLS4_BUTTONS; i++)
- dev->keycode[i] = KONTROLS4_BUTTON(i);
- input->keycodemax = KONTROLS4_BUTTONS;
-
- for (i = 0; i < KONTROLS4_AXIS; i++) {
- int axis = KONTROLS4_ABS(i);
- input->absbit[BIT_WORD(axis)] |= BIT_MASK(axis);
- }
-
- /* 36 analog potentiometers and faders */
- for (i = 0; i < 36; i++)
- input_set_abs_params(input, KONTROLS4_ABS(i), 0, 0xfff, 0, 10);
-
- /* 2 encoder wheels */
- input_set_abs_params(input, KONTROLS4_ABS(36), 0, 0x3ff, 0, 1);
- input_set_abs_params(input, KONTROLS4_ABS(37), 0, 0x3ff, 0, 1);
-
- /* 9 rotary encoders */
- for (i = 0; i < 9; i++)
- input_set_abs_params(input, KONTROLS4_ABS(38+i), 0, 0xf, 0, 1);
-
- dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->ep4_in_urb) {
- ret = -ENOMEM;
- goto exit_free_idev;
- }
-
- usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev,
- usb_rcvbulkpipe(usb_dev, 0x4),
- dev->ep4_in_buf, EP4_BUFSIZE,
- snd_usb_caiaq_ep4_reply_dispatch, dev);
-
- snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
-
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
- input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
- BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) |
- BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) |
- BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) |
- BIT_MASK(ABS_RX) | BIT_MASK(ABS_RY) |
- BIT_MASK(ABS_RZ);
-
- BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_maschine));
- memcpy(dev->keycode, keycode_maschine, sizeof(keycode_maschine));
- input->keycodemax = ARRAY_SIZE(keycode_maschine);
-
- for (i = 0; i < MASCHINE_PADS; i++) {
- input->absbit[0] |= MASCHINE_PAD(i);
- input_set_abs_params(input, MASCHINE_PAD(i), 0, 0xfff, 5, 10);
- }
-
- input_set_abs_params(input, ABS_HAT0X, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT0Y, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT1X, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT1Y, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT2X, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT2Y, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT3X, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT3Y, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_RX, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_RY, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_RZ, 0, 999, 0, 10);
-
- dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->ep4_in_urb) {
- ret = -ENOMEM;
- goto exit_free_idev;
- }
-
- usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev,
- usb_rcvbulkpipe(usb_dev, 0x4),
- dev->ep4_in_buf, EP4_BUFSIZE,
- snd_usb_caiaq_ep4_reply_dispatch, dev);
-
- snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
- break;
-
- default:
- /* no input methods supported on this device */
- goto exit_free_idev;
- }
-
- input->open = snd_usb_caiaq_input_open;
- input->close = snd_usb_caiaq_input_close;
- input->keycode = dev->keycode;
- input->keycodesize = sizeof(unsigned short);
- for (i = 0; i < input->keycodemax; i++)
- __set_bit(dev->keycode[i], input->keybit);
-
- dev->input_dev = input;
-
- ret = input_register_device(input);
- if (ret < 0)
- goto exit_free_idev;
-
- return 0;
-
-exit_free_idev:
- input_free_device(input);
- dev->input_dev = NULL;
- return ret;
-}
-
-void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev)
-{
- if (!dev || !dev->input_dev)
- return;
-
- usb_kill_urb(dev->ep4_in_urb);
- usb_free_urb(dev->ep4_in_urb);
- dev->ep4_in_urb = NULL;
-
- input_unregister_device(dev->input_dev);
- dev->input_dev = NULL;
-}
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/input.h b/ANDROID_3.4.5/sound/usb/caiaq/input.h
deleted file mode 100644
index ced53557..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/input.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef CAIAQ_INPUT_H
-#define CAIAQ_INPUT_H
-
-void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, char *buf, unsigned int len);
-int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev);
-void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/midi.c b/ANDROID_3.4.5/sound/usb/caiaq/midi.c
deleted file mode 100644
index a1a47088..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/midi.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (c) 2006,2007 Daniel Mack
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <linux/usb.h>
-#include <linux/gfp.h>
-#include <sound/rawmidi.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include "device.h"
-#include "midi.h"
-
-static int snd_usb_caiaq_midi_input_open(struct snd_rawmidi_substream *substream)
-{
- return 0;
-}
-
-static int snd_usb_caiaq_midi_input_close(struct snd_rawmidi_substream *substream)
-{
- return 0;
-}
-
-static void snd_usb_caiaq_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;
-
- if (!dev)
- return;
-
- dev->midi_receive_substream = up ? substream : NULL;
-}
-
-
-static int snd_usb_caiaq_midi_output_open(struct snd_rawmidi_substream *substream)
-{
- return 0;
-}
-
-static int snd_usb_caiaq_midi_output_close(struct snd_rawmidi_substream *substream)
-{
- struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;
- if (dev->midi_out_active) {
- usb_kill_urb(&dev->midi_out_urb);
- dev->midi_out_active = 0;
- }
- return 0;
-}
-
-static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *dev,
- struct snd_rawmidi_substream *substream)
-{
- int len, ret;
-
- dev->midi_out_buf[0] = EP1_CMD_MIDI_WRITE;
- dev->midi_out_buf[1] = 0; /* port */
- len = snd_rawmidi_transmit(substream, dev->midi_out_buf + 3,
- EP1_BUFSIZE - 3);
-
- if (len <= 0)
- return;
-
- dev->midi_out_buf[2] = len;
- dev->midi_out_urb.transfer_buffer_length = len+3;
-
- ret = usb_submit_urb(&dev->midi_out_urb, GFP_ATOMIC);
- if (ret < 0)
- log("snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed,"
- "ret=%d, len=%d\n",
- substream, ret, len);
- else
- dev->midi_out_active = 1;
-}
-
-static void snd_usb_caiaq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;
-
- if (up) {
- dev->midi_out_substream = substream;
- if (!dev->midi_out_active)
- snd_usb_caiaq_midi_send(dev, substream);
- } else {
- dev->midi_out_substream = NULL;
- }
-}
-
-
-static struct snd_rawmidi_ops snd_usb_caiaq_midi_output =
-{
- .open = snd_usb_caiaq_midi_output_open,
- .close = snd_usb_caiaq_midi_output_close,
- .trigger = snd_usb_caiaq_midi_output_trigger,
-};
-
-static struct snd_rawmidi_ops snd_usb_caiaq_midi_input =
-{
- .open = snd_usb_caiaq_midi_input_open,
- .close = snd_usb_caiaq_midi_input_close,
- .trigger = snd_usb_caiaq_midi_input_trigger,
-};
-
-void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev,
- int port, const char *buf, int len)
-{
- if (!dev->midi_receive_substream)
- return;
-
- snd_rawmidi_receive(dev->midi_receive_substream, buf, len);
-}
-
-int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *device)
-{
- int ret;
- struct snd_rawmidi *rmidi;
-
- ret = snd_rawmidi_new(device->chip.card, device->product_name, 0,
- device->spec.num_midi_out,
- device->spec.num_midi_in,
- &rmidi);
-
- if (ret < 0)
- return ret;
-
- strlcpy(rmidi->name, device->product_name, sizeof(rmidi->name));
-
- rmidi->info_flags = SNDRV_RAWMIDI_INFO_DUPLEX;
- rmidi->private_data = device;
-
- if (device->spec.num_midi_out > 0) {
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
- &snd_usb_caiaq_midi_output);
- }
-
- if (device->spec.num_midi_in > 0) {
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
- &snd_usb_caiaq_midi_input);
- }
-
- device->rmidi = rmidi;
-
- return 0;
-}
-
-void snd_usb_caiaq_midi_output_done(struct urb* urb)
-{
- struct snd_usb_caiaqdev *dev = urb->context;
-
- dev->midi_out_active = 0;
- if (urb->status != 0)
- return;
-
- if (!dev->midi_out_substream)
- return;
-
- snd_usb_caiaq_midi_send(dev, dev->midi_out_substream);
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/midi.h b/ANDROID_3.4.5/sound/usb/caiaq/midi.h
deleted file mode 100644
index 380f984b..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/midi.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef CAIAQ_MIDI_H
-#define CAIAQ_MIDI_H
-
-int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *dev);
-void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, int port, const char *buf, int len);
-void snd_usb_caiaq_midi_output_done(struct urb *urb);
-
-#endif /* CAIAQ_MIDI_H */
diff --git a/ANDROID_3.4.5/sound/usb/card.c b/ANDROID_3.4.5/sound/usb/card.c
deleted file mode 100644
index 4a7be7b9..00000000
--- a/ANDROID_3.4.5/sound/usb/card.c
+++ /dev/null
@@ -1,729 +0,0 @@
-/*
- * (Tentative) USB Audio Driver for ALSA
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * Many codes borrowed from audio.c by
- * Alan Cox (alan@lxorguk.ukuu.org.uk)
- * Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
- * NOTES:
- *
- * - async unlink should be used for avoiding the sleep inside lock.
- * 2.4.22 usb-uhci seems buggy for async unlinking and results in
- * oops. in such a cse, pass async_unlink=0 option.
- * - the linked URBs would be preferred but not used so far because of
- * the instability of unlinking.
- * - type II is not supported properly. there is no device which supports
- * this type *correctly*. SB extigy looks as if it supports, but it's
- * indeed an AC3 stream packed in SPDIF frames (i.e. no real AC3 stream).
- */
-
-
-#include <linux/bitops.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/usb.h>
-#include <linux/moduleparam.h>
-#include <linux/mutex.h>
-#include <linux/usb/audio.h>
-#include <linux/usb/audio-v2.h>
-#include <linux/module.h>
-
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-
-#include "usbaudio.h"
-#include "card.h"
-#include "midi.h"
-#include "mixer.h"
-#include "proc.h"
-#include "quirks.h"
-#include "endpoint.h"
-#include "helper.h"
-#include "debug.h"
-#include "pcm.h"
-#include "format.h"
-#include "power.h"
-#include "stream.h"
-
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("USB Audio");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Generic,USB Audio}}");
-
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
-/* Vendor/product IDs for this card */
-static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
-static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
-static int nrpacks = 8; /* max. number of packets per urb */
-static bool async_unlink = 1;
-static int device_setup[SNDRV_CARDS]; /* device parameter for this card */
-static bool ignore_ctl_error;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for the USB audio adapter.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for the USB audio adapter.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable USB audio adapter.");
-module_param_array(vid, int, NULL, 0444);
-MODULE_PARM_DESC(vid, "Vendor ID for the USB audio device.");
-module_param_array(pid, int, NULL, 0444);
-MODULE_PARM_DESC(pid, "Product ID for the USB audio device.");
-module_param(nrpacks, int, 0644);
-MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB.");
-module_param(async_unlink, bool, 0444);
-MODULE_PARM_DESC(async_unlink, "Use async unlink mode.");
-module_param_array(device_setup, int, NULL, 0444);
-MODULE_PARM_DESC(device_setup, "Specific device setup (if needed).");
-module_param(ignore_ctl_error, bool, 0444);
-MODULE_PARM_DESC(ignore_ctl_error,
- "Ignore errors from USB controller for mixer interfaces.");
-
-/*
- * we keep the snd_usb_audio_t instances by ourselves for merging
- * the all interfaces on the same card as one sound device.
- */
-
-static DEFINE_MUTEX(register_mutex);
-static struct snd_usb_audio *usb_chip[SNDRV_CARDS];
-static struct usb_driver usb_audio_driver;
-
-/*
- * disconnect streams
- * called from snd_usb_audio_disconnect()
- */
-static void snd_usb_stream_disconnect(struct list_head *head)
-{
- int idx;
- struct snd_usb_stream *as;
- struct snd_usb_substream *subs;
-
- as = list_entry(head, struct snd_usb_stream, list);
- for (idx = 0; idx < 2; idx++) {
- subs = &as->substream[idx];
- if (!subs->num_formats)
- continue;
- snd_usb_release_substream_urbs(subs, 1);
- subs->interface = -1;
- }
-}
-
-static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int interface)
-{
- struct usb_device *dev = chip->dev;
- struct usb_host_interface *alts;
- struct usb_interface_descriptor *altsd;
- struct usb_interface *iface = usb_ifnum_to_if(dev, interface);
-
- if (!iface) {
- snd_printk(KERN_ERR "%d:%u:%d : does not exist\n",
- dev->devnum, ctrlif, interface);
- return -EINVAL;
- }
-
- if (usb_interface_claimed(iface)) {
- snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n",
- dev->devnum, ctrlif, interface);
- return -EINVAL;
- }
-
- alts = &iface->altsetting[0];
- altsd = get_iface_desc(alts);
- if ((altsd->bInterfaceClass == USB_CLASS_AUDIO ||
- altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) &&
- altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) {
- int err = snd_usbmidi_create(chip->card, iface,
- &chip->midi_list, NULL);
- if (err < 0) {
- snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n",
- dev->devnum, ctrlif, interface);
- return -EINVAL;
- }
- usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
-
- return 0;
- }
-
- if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
- altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
- altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING) {
- snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n",
- dev->devnum, ctrlif, interface, altsd->bInterfaceClass);
- /* skip non-supported classes */
- return -EINVAL;
- }
-
- if (snd_usb_get_speed(dev) == USB_SPEED_LOW) {
- snd_printk(KERN_ERR "low speed audio streaming not supported\n");
- return -EINVAL;
- }
-
- if (! snd_usb_parse_audio_interface(chip, interface)) {
- usb_set_interface(dev, interface, 0); /* reset the current interface */
- usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * parse audio control descriptor and create pcm/midi streams
- */
-static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
-{
- struct usb_device *dev = chip->dev;
- struct usb_host_interface *host_iface;
- struct usb_interface_descriptor *altsd;
- void *control_header;
- int i, protocol;
-
- /* find audiocontrol interface */
- host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0];
- control_header = snd_usb_find_csint_desc(host_iface->extra,
- host_iface->extralen,
- NULL, UAC_HEADER);
- altsd = get_iface_desc(host_iface);
- protocol = altsd->bInterfaceProtocol;
-
- if (!control_header) {
- snd_printk(KERN_ERR "cannot find UAC_HEADER\n");
- return -EINVAL;
- }
-
- switch (protocol) {
- default:
- snd_printdd(KERN_WARNING "unknown interface protocol %#02x, assuming v1\n",
- protocol);
- /* fall through */
-
- case UAC_VERSION_1: {
- struct uac1_ac_header_descriptor *h1 = control_header;
-
- if (!h1->bInCollection) {
- snd_printk(KERN_INFO "skipping empty audio interface (v1)\n");
- return -EINVAL;
- }
-
- if (h1->bLength < sizeof(*h1) + h1->bInCollection) {
- snd_printk(KERN_ERR "invalid UAC_HEADER (v1)\n");
- return -EINVAL;
- }
-
- for (i = 0; i < h1->bInCollection; i++)
- snd_usb_create_stream(chip, ctrlif, h1->baInterfaceNr[i]);
-
- break;
- }
-
- case UAC_VERSION_2: {
- struct usb_interface_assoc_descriptor *assoc =
- usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
-
- if (!assoc) {
- snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association\n");
- return -EINVAL;
- }
-
- for (i = 0; i < assoc->bInterfaceCount; i++) {
- int intf = assoc->bFirstInterface + i;
-
- if (intf != ctrlif)
- snd_usb_create_stream(chip, ctrlif, intf);
- }
-
- break;
- }
- }
-
- return 0;
-}
-
-/*
- * free the chip instance
- *
- * here we have to do not much, since pcm and controls are already freed
- *
- */
-
-static int snd_usb_audio_free(struct snd_usb_audio *chip)
-{
- kfree(chip);
- return 0;
-}
-
-static int snd_usb_audio_dev_free(struct snd_device *device)
-{
- struct snd_usb_audio *chip = device->device_data;
- return snd_usb_audio_free(chip);
-}
-
-static void remove_trailing_spaces(char *str)
-{
- char *p;
-
- if (!*str)
- return;
- for (p = str + strlen(str) - 1; p >= str && isspace(*p); p--)
- *p = 0;
-}
-
-/*
- * create a chip instance and set its names.
- */
-static int snd_usb_audio_create(struct usb_device *dev, int idx,
- const struct snd_usb_audio_quirk *quirk,
- struct snd_usb_audio **rchip)
-{
- struct snd_card *card;
- struct snd_usb_audio *chip;
- int err, len;
- char component[14];
- static struct snd_device_ops ops = {
- .dev_free = snd_usb_audio_dev_free,
- };
-
- *rchip = NULL;
-
- switch (snd_usb_get_speed(dev)) {
- case USB_SPEED_LOW:
- case USB_SPEED_FULL:
- case USB_SPEED_HIGH:
- case USB_SPEED_SUPER:
- break;
- default:
- snd_printk(KERN_ERR "unknown device speed %d\n", snd_usb_get_speed(dev));
- return -ENXIO;
- }
-
- err = snd_card_create(index[idx], id[idx], THIS_MODULE, 0, &card);
- if (err < 0) {
- snd_printk(KERN_ERR "cannot create card instance %d\n", idx);
- return err;
- }
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (! chip) {
- snd_card_free(card);
- return -ENOMEM;
- }
-
- mutex_init(&chip->shutdown_mutex);
- chip->index = idx;
- chip->dev = dev;
- chip->card = card;
- chip->setup = device_setup[idx];
- chip->nrpacks = nrpacks;
- chip->async_unlink = async_unlink;
- chip->probing = 1;
-
- chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
- le16_to_cpu(dev->descriptor.idProduct));
- INIT_LIST_HEAD(&chip->pcm_list);
- INIT_LIST_HEAD(&chip->midi_list);
- INIT_LIST_HEAD(&chip->mixer_list);
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_usb_audio_free(chip);
- snd_card_free(card);
- return err;
- }
-
- strcpy(card->driver, "USB-Audio");
- sprintf(component, "USB%04x:%04x",
- USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id));
- snd_component_add(card, component);
-
- /* retrieve the device string as shortname */
- if (quirk && quirk->product_name && *quirk->product_name) {
- strlcpy(card->shortname, quirk->product_name, sizeof(card->shortname));
- } else {
- if (!dev->descriptor.iProduct ||
- usb_string(dev, dev->descriptor.iProduct,
- card->shortname, sizeof(card->shortname)) <= 0) {
- /* no name available from anywhere, so use ID */
- sprintf(card->shortname, "USB Device %#04x:%#04x",
- USB_ID_VENDOR(chip->usb_id),
- USB_ID_PRODUCT(chip->usb_id));
- }
- }
- remove_trailing_spaces(card->shortname);
-
- /* retrieve the vendor and device strings as longname */
- if (quirk && quirk->vendor_name && *quirk->vendor_name) {
- len = strlcpy(card->longname, quirk->vendor_name, sizeof(card->longname));
- } else {
- if (dev->descriptor.iManufacturer)
- len = usb_string(dev, dev->descriptor.iManufacturer,
- card->longname, sizeof(card->longname));
- else
- len = 0;
- /* we don't really care if there isn't any vendor string */
- }
- if (len > 0) {
- remove_trailing_spaces(card->longname);
- if (*card->longname)
- strlcat(card->longname, " ", sizeof(card->longname));
- }
-
- strlcat(card->longname, card->shortname, sizeof(card->longname));
-
- len = strlcat(card->longname, " at ", sizeof(card->longname));
-
- if (len < sizeof(card->longname))
- usb_make_path(dev, card->longname + len, sizeof(card->longname) - len);
-
- switch (snd_usb_get_speed(dev)) {
- case USB_SPEED_LOW:
- strlcat(card->longname, ", low speed", sizeof(card->longname));
- break;
- case USB_SPEED_FULL:
- strlcat(card->longname, ", full speed", sizeof(card->longname));
- break;
- case USB_SPEED_HIGH:
- strlcat(card->longname, ", high speed", sizeof(card->longname));
- break;
- case USB_SPEED_SUPER:
- strlcat(card->longname, ", super speed", sizeof(card->longname));
- break;
- default:
- break;
- }
-
- snd_usb_audio_create_proc(chip);
-
- *rchip = chip;
- return 0;
-}
-
-/*
- * probe the active usb device
- *
- * note that this can be called multiple times per a device, when it
- * includes multiple audio control interfaces.
- *
- * thus we check the usb device pointer and creates the card instance
- * only at the first time. the successive calls of this function will
- * append the pcm interface to the corresponding card.
- */
-static struct snd_usb_audio *
-snd_usb_audio_probe(struct usb_device *dev,
- struct usb_interface *intf,
- const struct usb_device_id *usb_id)
-{
- const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info;
- int i, err;
- struct snd_usb_audio *chip;
- struct usb_host_interface *alts;
- int ifnum;
- u32 id;
-
- alts = &intf->altsetting[0];
- ifnum = get_iface_desc(alts)->bInterfaceNumber;
- id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
- le16_to_cpu(dev->descriptor.idProduct));
- if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum)
- goto __err_val;
-
- if (snd_usb_apply_boot_quirk(dev, intf, quirk) < 0)
- goto __err_val;
-
- /*
- * found a config. now register to ALSA
- */
-
- /* check whether it's already registered */
- chip = NULL;
- mutex_lock(&register_mutex);
- for (i = 0; i < SNDRV_CARDS; i++) {
- if (usb_chip[i] && usb_chip[i]->dev == dev) {
- if (usb_chip[i]->shutdown) {
- snd_printk(KERN_ERR "USB device is in the shutdown state, cannot create a card instance\n");
- goto __error;
- }
- chip = usb_chip[i];
- chip->probing = 1;
- break;
- }
- }
- if (! chip) {
- /* it's a fresh one.
- * now look for an empty slot and create a new card instance
- */
- for (i = 0; i < SNDRV_CARDS; i++)
- if (enable[i] && ! usb_chip[i] &&
- (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
- (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) {
- if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) {
- goto __error;
- }
- snd_card_set_dev(chip->card, &intf->dev);
- chip->pm_intf = intf;
- break;
- }
- if (!chip) {
- printk(KERN_ERR "no available usb audio device\n");
- goto __error;
- }
- }
-
- /*
- * For devices with more than one control interface, we assume the
- * first contains the audio controls. We might need a more specific
- * check here in the future.
- */
- if (!chip->ctrl_intf)
- chip->ctrl_intf = alts;
-
- chip->txfr_quirk = 0;
- err = 1; /* continue */
- if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) {
- /* need some special handlings */
- if ((err = snd_usb_create_quirk(chip, intf, &usb_audio_driver, quirk)) < 0)
- goto __error;
- }
-
- if (err > 0) {
- /* create normal USB audio interfaces */
- if (snd_usb_create_streams(chip, ifnum) < 0 ||
- snd_usb_create_mixer(chip, ifnum, ignore_ctl_error) < 0) {
- goto __error;
- }
- }
-
- /* we are allowed to call snd_card_register() many times */
- if (snd_card_register(chip->card) < 0) {
- goto __error;
- }
-
- usb_chip[chip->index] = chip;
- chip->num_interfaces++;
- chip->probing = 0;
- mutex_unlock(&register_mutex);
- return chip;
-
- __error:
- if (chip) {
- if (!chip->num_interfaces)
- snd_card_free(chip->card);
- chip->probing = 0;
- }
- mutex_unlock(&register_mutex);
- __err_val:
- return NULL;
-}
-
-/*
- * we need to take care of counter, since disconnection can be called also
- * many times as well as usb_audio_probe().
- */
-static void snd_usb_audio_disconnect(struct usb_device *dev,
- struct snd_usb_audio *chip)
-{
- struct snd_card *card;
- struct list_head *p;
-
- if (chip == (void *)-1L)
- return;
-
- card = chip->card;
- mutex_lock(&register_mutex);
- mutex_lock(&chip->shutdown_mutex);
- chip->shutdown = 1;
- chip->num_interfaces--;
- if (chip->num_interfaces <= 0) {
- snd_card_disconnect(card);
- /* release the pcm resources */
- list_for_each(p, &chip->pcm_list) {
- snd_usb_stream_disconnect(p);
- }
- /* release the midi resources */
- list_for_each(p, &chip->midi_list) {
- snd_usbmidi_disconnect(p);
- }
- /* release mixer resources */
- list_for_each(p, &chip->mixer_list) {
- snd_usb_mixer_disconnect(p);
- }
- usb_chip[chip->index] = NULL;
- mutex_unlock(&chip->shutdown_mutex);
- mutex_unlock(&register_mutex);
- snd_card_free_when_closed(card);
- } else {
- mutex_unlock(&chip->shutdown_mutex);
- mutex_unlock(&register_mutex);
- }
-}
-
-/*
- * new 2.5 USB kernel API
- */
-static int usb_audio_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct snd_usb_audio *chip;
- chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
- if (chip) {
- usb_set_intfdata(intf, chip);
- return 0;
- } else
- return -EIO;
-}
-
-static void usb_audio_disconnect(struct usb_interface *intf)
-{
- snd_usb_audio_disconnect(interface_to_usbdev(intf),
- usb_get_intfdata(intf));
-}
-
-#ifdef CONFIG_PM
-
-int snd_usb_autoresume(struct snd_usb_audio *chip)
-{
- int err = -ENODEV;
-
- if (!chip->shutdown && !chip->probing)
- err = usb_autopm_get_interface(chip->pm_intf);
-
- return err;
-}
-
-void snd_usb_autosuspend(struct snd_usb_audio *chip)
-{
- if (!chip->shutdown && !chip->probing)
- usb_autopm_put_interface(chip->pm_intf);
-}
-
-static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct snd_usb_audio *chip = usb_get_intfdata(intf);
- struct list_head *p;
- struct snd_usb_stream *as;
- struct usb_mixer_interface *mixer;
-
- if (chip == (void *)-1L)
- return 0;
-
- if (!PMSG_IS_AUTO(message)) {
- snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
- if (!chip->num_suspended_intf++) {
- list_for_each(p, &chip->pcm_list) {
- as = list_entry(p, struct snd_usb_stream, list);
- snd_pcm_suspend_all(as->pcm);
- }
- }
- } else {
- /*
- * otherwise we keep the rest of the system in the dark
- * to keep this transparent
- */
- if (!chip->num_suspended_intf++)
- chip->autosuspended = 1;
- }
-
- list_for_each_entry(mixer, &chip->mixer_list, list)
- snd_usb_mixer_inactivate(mixer);
-
- return 0;
-}
-
-static int usb_audio_resume(struct usb_interface *intf)
-{
- struct snd_usb_audio *chip = usb_get_intfdata(intf);
- struct usb_mixer_interface *mixer;
- int err = 0;
-
- if (chip == (void *)-1L)
- return 0;
- if (--chip->num_suspended_intf)
- return 0;
- /*
- * ALSA leaves material resumption to user space
- * we just notify and restart the mixers
- */
- list_for_each_entry(mixer, &chip->mixer_list, list) {
- err = snd_usb_mixer_activate(mixer);
- if (err < 0)
- goto err_out;
- }
-
- if (!chip->autosuspended)
- snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
- chip->autosuspended = 0;
-
-err_out:
- return err;
-}
-#else
-#define usb_audio_suspend NULL
-#define usb_audio_resume NULL
-#endif /* CONFIG_PM */
-
-static struct usb_device_id usb_audio_ids [] = {
-#include "quirks-table.h"
- { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE (usb, usb_audio_ids);
-
-/*
- * entry point for linux usb interface
- */
-
-static struct usb_driver usb_audio_driver = {
- .name = "snd-usb-audio",
- .probe = usb_audio_probe,
- .disconnect = usb_audio_disconnect,
- .suspend = usb_audio_suspend,
- .resume = usb_audio_resume,
- .id_table = usb_audio_ids,
- .supports_autosuspend = 1,
-};
-
-static int __init snd_usb_audio_init(void)
-{
- if (nrpacks < 1 || nrpacks > MAX_PACKS) {
- printk(KERN_WARNING "invalid nrpacks value.\n");
- return -EINVAL;
- }
- return usb_register(&usb_audio_driver);
-}
-
-static void __exit snd_usb_audio_cleanup(void)
-{
- usb_deregister(&usb_audio_driver);
-}
-
-module_init(snd_usb_audio_init);
-module_exit(snd_usb_audio_cleanup);
diff --git a/ANDROID_3.4.5/sound/usb/card.h b/ANDROID_3.4.5/sound/usb/card.h
deleted file mode 100644
index da5fa1ac..00000000
--- a/ANDROID_3.4.5/sound/usb/card.h
+++ /dev/null
@@ -1,111 +0,0 @@
-#ifndef __USBAUDIO_CARD_H
-#define __USBAUDIO_CARD_H
-
-#define MAX_NR_RATES 1024
-#define MAX_PACKS 20
-#define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */
-#define MAX_URBS 8
-#define SYNC_URBS 4 /* always four urbs for sync */
-#define MAX_QUEUE 24 /* try not to exceed this queue length, in ms */
-
-struct audioformat {
- struct list_head list;
- u64 formats; /* ALSA format bits */
- unsigned int channels; /* # channels */
- unsigned int fmt_type; /* USB audio format type (1-3) */
- unsigned int frame_size; /* samples per frame for non-audio */
- int iface; /* interface number */
- unsigned char altsetting; /* corresponding alternate setting */
- unsigned char altset_idx; /* array index of altenate setting */
- unsigned char attributes; /* corresponding attributes of cs endpoint */
- unsigned char endpoint; /* endpoint */
- unsigned char ep_attr; /* endpoint attributes */
- unsigned char datainterval; /* log_2 of data packet interval */
- unsigned int maxpacksize; /* max. packet size */
- unsigned int rates; /* rate bitmasks */
- unsigned int rate_min, rate_max; /* min/max rates */
- unsigned int nr_rates; /* number of rate table entries */
- unsigned int *rate_table; /* rate table */
- unsigned char clock; /* associated clock */
-};
-
-struct snd_usb_substream;
-
-struct snd_urb_ctx {
- struct urb *urb;
- unsigned int buffer_size; /* size of data buffer, if data URB */
- struct snd_usb_substream *subs;
- int index; /* index for urb array */
- int packets; /* number of packets per urb */
-};
-
-struct snd_urb_ops {
- int (*prepare)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
- int (*retire)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
- int (*prepare_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
- int (*retire_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
-};
-
-struct snd_usb_substream {
- struct snd_usb_stream *stream;
- struct usb_device *dev;
- struct snd_pcm_substream *pcm_substream;
- int direction; /* playback or capture */
- int interface; /* current interface */
- int endpoint; /* assigned endpoint */
- struct audioformat *cur_audiofmt; /* current audioformat pointer (for hw_params callback) */
- unsigned int cur_rate; /* current rate (for hw_params callback) */
- unsigned int period_bytes; /* current period bytes (for hw_params callback) */
- unsigned int altset_idx; /* USB data format: index of alternate setting */
- unsigned int datapipe; /* the data i/o pipe */
- unsigned int syncpipe; /* 1 - async out or adaptive in */
- unsigned int datainterval; /* log_2 of data packet interval */
- unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */
- unsigned int freqn; /* nominal sampling rate in fs/fps in Q16.16 format */
- unsigned int freqm; /* momentary sampling rate in fs/fps in Q16.16 format */
- int freqshift; /* how much to shift the feedback value to get Q16.16 */
- unsigned int freqmax; /* maximum sampling rate, used for buffer management */
- unsigned int phase; /* phase accumulator */
- unsigned int maxpacksize; /* max packet size in bytes */
- unsigned int maxframesize; /* max packet size in frames */
- unsigned int curpacksize; /* current packet size in bytes (for capture) */
- unsigned int curframesize; /* current packet size in frames (for capture) */
- unsigned int syncmaxsize; /* sync endpoint packet size */
- unsigned int fill_max: 1; /* fill max packet size always */
- unsigned int txfr_quirk:1; /* allow sub-frame alignment */
- unsigned int fmt_type; /* USB audio format type (1-3) */
-
- unsigned int running: 1; /* running status */
-
- unsigned int hwptr_done; /* processed byte position in the buffer */
- unsigned int transfer_done; /* processed frames since last period update */
- unsigned long active_mask; /* bitmask of active urbs */
- unsigned long unlink_mask; /* bitmask of unlinked urbs */
-
- unsigned int nurbs; /* # urbs */
- struct snd_urb_ctx dataurb[MAX_URBS]; /* data urb table */
- struct snd_urb_ctx syncurb[SYNC_URBS]; /* sync urb table */
- char *syncbuf; /* sync buffer for all sync URBs */
- dma_addr_t sync_dma; /* DMA address of syncbuf */
-
- u64 formats; /* format bitmasks (all or'ed) */
- unsigned int num_formats; /* number of supported audio formats (list) */
- struct list_head fmt_list; /* format list */
- struct snd_pcm_hw_constraint_list rate_list; /* limited rates */
- spinlock_t lock;
-
- struct snd_urb_ops ops; /* callbacks (must be filled at init) */
- int last_frame_number; /* stored frame number */
- int last_delay; /* stored delay */
-};
-
-struct snd_usb_stream {
- struct snd_usb_audio *chip;
- struct snd_pcm *pcm;
- int pcm_index;
- unsigned int fmt_type; /* USB audio format type (1-3) */
- struct snd_usb_substream substream[2];
- struct list_head list;
-};
-
-#endif /* __USBAUDIO_CARD_H */
diff --git a/ANDROID_3.4.5/sound/usb/clock.c b/ANDROID_3.4.5/sound/usb/clock.c
deleted file mode 100644
index 6026e0e1..00000000
--- a/ANDROID_3.4.5/sound/usb/clock.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Clock domain and sample rate management functions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/bitops.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/usb.h>
-#include <linux/usb/audio.h>
-#include <linux/usb/audio-v2.h>
-
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/pcm.h>
-
-#include "usbaudio.h"
-#include "card.h"
-#include "helper.h"
-#include "clock.h"
-
-static struct uac_clock_source_descriptor *
- snd_usb_find_clock_source(struct usb_host_interface *ctrl_iface,
- int clock_id)
-{
- struct uac_clock_source_descriptor *cs = NULL;
-
- while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
- ctrl_iface->extralen,
- cs, UAC2_CLOCK_SOURCE))) {
- if (cs->bClockID == clock_id)
- return cs;
- }
-
- return NULL;
-}
-
-static struct uac_clock_selector_descriptor *
- snd_usb_find_clock_selector(struct usb_host_interface *ctrl_iface,
- int clock_id)
-{
- struct uac_clock_selector_descriptor *cs = NULL;
-
- while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
- ctrl_iface->extralen,
- cs, UAC2_CLOCK_SELECTOR))) {
- if (cs->bClockID == clock_id)
- return cs;
- }
-
- return NULL;
-}
-
-static struct uac_clock_multiplier_descriptor *
- snd_usb_find_clock_multiplier(struct usb_host_interface *ctrl_iface,
- int clock_id)
-{
- struct uac_clock_multiplier_descriptor *cs = NULL;
-
- while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
- ctrl_iface->extralen,
- cs, UAC2_CLOCK_MULTIPLIER))) {
- if (cs->bClockID == clock_id)
- return cs;
- }
-
- return NULL;
-}
-
-static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_id)
-{
- unsigned char buf;
- int ret;
-
- ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0),
- UAC2_CS_CUR,
- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
- UAC2_CX_CLOCK_SELECTOR << 8,
- snd_usb_ctrl_intf(chip) | (selector_id << 8),
- &buf, sizeof(buf));
-
- if (ret < 0)
- return ret;
-
- return buf;
-}
-
-static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
-{
- int err;
- unsigned char data;
- struct usb_device *dev = chip->dev;
- struct uac_clock_source_descriptor *cs_desc =
- snd_usb_find_clock_source(chip->ctrl_intf, source_id);
-
- if (!cs_desc)
- return 0;
-
- /* If a clock source can't tell us whether it's valid, we assume it is */
- if (!uac2_control_is_readable(cs_desc->bmControls, UAC2_CS_CONTROL_CLOCK_VALID))
- return 1;
-
- err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
- UAC2_CS_CONTROL_CLOCK_VALID << 8,
- snd_usb_ctrl_intf(chip) | (source_id << 8),
- &data, sizeof(data));
-
- if (err < 0) {
- snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n",
- __func__, source_id);
- return 0;
- }
-
- return !!data;
-}
-
-static int __uac_clock_find_source(struct snd_usb_audio *chip,
- int entity_id, unsigned long *visited)
-{
- struct uac_clock_source_descriptor *source;
- struct uac_clock_selector_descriptor *selector;
- struct uac_clock_multiplier_descriptor *multiplier;
-
- entity_id &= 0xff;
-
- if (test_and_set_bit(entity_id, visited)) {
- snd_printk(KERN_WARNING
- "%s(): recursive clock topology detected, id %d.\n",
- __func__, entity_id);
- return -EINVAL;
- }
-
- /* first, see if the ID we're looking for is a clock source already */
- source = snd_usb_find_clock_source(chip->ctrl_intf, entity_id);
- if (source)
- return source->bClockID;
-
- selector = snd_usb_find_clock_selector(chip->ctrl_intf, entity_id);
- if (selector) {
- int ret;
-
- /* the entity ID we are looking for is a selector.
- * find out what it currently selects */
- ret = uac_clock_selector_get_val(chip, selector->bClockID);
- if (ret < 0)
- return ret;
-
- /* Selector values are one-based */
-
- if (ret > selector->bNrInPins || ret < 1) {
- printk(KERN_ERR
- "%s(): selector reported illegal value, id %d, ret %d\n",
- __func__, selector->bClockID, ret);
-
- return -EINVAL;
- }
-
- return __uac_clock_find_source(chip, selector->baCSourceID[ret-1],
- visited);
- }
-
- /* FIXME: multipliers only act as pass-thru element for now */
- multiplier = snd_usb_find_clock_multiplier(chip->ctrl_intf, entity_id);
- if (multiplier)
- return __uac_clock_find_source(chip, multiplier->bCSourceID,
- visited);
-
- return -EINVAL;
-}
-
-/*
- * For all kinds of sample rate settings and other device queries,
- * the clock source (end-leaf) must be used. However, clock selectors,
- * clock multipliers and sample rate converters may be specified as
- * clock source input to terminal. This functions walks the clock path
- * to its end and tries to find the source.
- *
- * The 'visited' bitfield is used internally to detect recursive loops.
- *
- * Returns the clock source UnitID (>=0) on success, or an error.
- */
-int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id)
-{
- DECLARE_BITMAP(visited, 256);
- memset(visited, 0, sizeof(visited));
- return __uac_clock_find_source(chip, entity_id, visited);
-}
-
-static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
- struct usb_host_interface *alts,
- struct audioformat *fmt, int rate)
-{
- struct usb_device *dev = chip->dev;
- unsigned int ep;
- unsigned char data[3];
- int err, crate;
-
- ep = get_endpoint(alts, 0)->bEndpointAddress;
-
- /* if endpoint doesn't have sampling rate control, bail out */
- if (!(fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE))
- return 0;
-
- data[0] = rate;
- data[1] = rate >> 8;
- data[2] = rate >> 16;
- if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
- USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,
- UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
- data, sizeof(data))) < 0) {
- snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n",
- dev->devnum, iface, fmt->altsetting, rate, ep);
- //return err; //just not return, otherwise, logitech camera mic,can't use 2013-10-23
- //printk("%s snd_usb_ctl_msg set rate err! \n", __FUNCTION__);
- //return 0;//dbg if application set the rate that usb audio support just return 0! 2013-10-23
- }
-
- if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
- USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN,
- UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
- data, sizeof(data))) < 0) {
- snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n",
- dev->devnum, iface, fmt->altsetting, ep);
- printk("%s snd_usb_ctl_msg get rate err!\n", __FUNCTION__);
- return 0; /* some devices don't support reading */
- }
-
- crate = data[0] | (data[1] << 8) | (data[2] << 16);
- printk("%s snd_usb_ctl_msg get rate 2 :%d!\n", __FUNCTION__, crate);
- if (crate != rate) {
- snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);
- // runtime->rate = crate;
- }
-
- return 0;
-}
-
-static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
- struct usb_host_interface *alts,
- struct audioformat *fmt, int rate)
-{
- struct usb_device *dev = chip->dev;
- unsigned char data[4];
- int err, crate;
- int clock = snd_usb_clock_find_source(chip, fmt->clock);
-
- if (clock < 0)
- return clock;
-
- if (!uac_clock_source_is_valid(chip, clock)) {
- /* TODO: should we try to find valid clock setups by ourself? */
- snd_printk(KERN_ERR "%d:%d:%d: clock source %d is not valid, cannot use\n",
- dev->devnum, iface, fmt->altsetting, clock);
- return -ENXIO;
- }
-
- data[0] = rate;
- data[1] = rate >> 8;
- data[2] = rate >> 16;
- data[3] = rate >> 24;
- if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
- UAC2_CS_CONTROL_SAM_FREQ << 8,
- snd_usb_ctrl_intf(chip) | (clock << 8),
- data, sizeof(data))) < 0) {
- snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n",
- dev->devnum, iface, fmt->altsetting, rate);
- return err;
- }
-
- if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
- UAC2_CS_CONTROL_SAM_FREQ << 8,
- snd_usb_ctrl_intf(chip) | (clock << 8),
- data, sizeof(data))) < 0) {
- snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n",
- dev->devnum, iface, fmt->altsetting);
- return err;
- }
-
- crate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
- if (crate != rate)
- snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);
-
- return 0;
-}
-
-int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
- struct usb_host_interface *alts,
- struct audioformat *fmt, int rate)
-{
- struct usb_interface_descriptor *altsd = get_iface_desc(alts);
-
- switch (altsd->bInterfaceProtocol) {
- case UAC_VERSION_1:
- default:
- return set_sample_rate_v1(chip, iface, alts, fmt, rate);
-
- case UAC_VERSION_2:
- return set_sample_rate_v2(chip, iface, alts, fmt, rate);
- }
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/clock.h b/ANDROID_3.4.5/sound/usb/clock.h
deleted file mode 100644
index 46630936..00000000
--- a/ANDROID_3.4.5/sound/usb/clock.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __USBAUDIO_CLOCK_H
-#define __USBAUDIO_CLOCK_H
-
-int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
- struct usb_host_interface *alts,
- struct audioformat *fmt, int rate);
-
-int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id);
-
-#endif /* __USBAUDIO_CLOCK_H */
diff --git a/ANDROID_3.4.5/sound/usb/debug.h b/ANDROID_3.4.5/sound/usb/debug.h
deleted file mode 100644
index 58030176..00000000
--- a/ANDROID_3.4.5/sound/usb/debug.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef __USBAUDIO_DEBUG_H
-#define __USBAUDIO_DEBUG_H
-
-/*
- * h/w constraints
- */
-
-#ifdef HW_CONST_DEBUG
-#define hwc_debug(fmt, args...) printk(KERN_DEBUG fmt, ##args)
-#else
-#define hwc_debug(fmt, args...) do { } while(0)
-#endif
-
-#endif /* __USBAUDIO_DEBUG_H */
-
diff --git a/ANDROID_3.4.5/sound/usb/endpoint.c b/ANDROID_3.4.5/sound/usb/endpoint.c
deleted file mode 100644
index 08dcce53..00000000
--- a/ANDROID_3.4.5/sound/usb/endpoint.c
+++ /dev/null
@@ -1,966 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/gfp.h>
-#include <linux/init.h>
-#include <linux/ratelimit.h>
-#include <linux/usb.h>
-#include <linux/usb/audio.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include "usbaudio.h"
-#include "helper.h"
-#include "card.h"
-#include "endpoint.h"
-#include "pcm.h"
-
-/*
- * convert a sampling rate into our full speed format (fs/1000 in Q16.16)
- * this will overflow at approx 524 kHz
- */
-static inline unsigned get_usb_full_speed_rate(unsigned int rate)
-{
- return ((rate << 13) + 62) / 125;
-}
-
-/*
- * convert a sampling rate into USB high speed format (fs/8000 in Q16.16)
- * this will overflow at approx 4 MHz
- */
-static inline unsigned get_usb_high_speed_rate(unsigned int rate)
-{
- return ((rate << 10) + 62) / 125;
-}
-
-/*
- * unlink active urbs.
- */
-static int deactivate_urbs(struct snd_usb_substream *subs, int force, int can_sleep)
-{
- struct snd_usb_audio *chip = subs->stream->chip;
- unsigned int i;
- int async;
-
- subs->running = 0;
-
- if (!force && subs->stream->chip->shutdown) /* to be sure... */
- return -EBADFD;
-
- async = !can_sleep && chip->async_unlink;
-
- if (!async && in_interrupt())
- return 0;
-
- for (i = 0; i < subs->nurbs; i++) {
- if (test_bit(i, &subs->active_mask)) {
- if (!test_and_set_bit(i, &subs->unlink_mask)) {
- struct urb *u = subs->dataurb[i].urb;
- if (async)
- usb_unlink_urb(u);
- else
- usb_kill_urb(u);
- }
- }
- }
- if (subs->syncpipe) {
- for (i = 0; i < SYNC_URBS; i++) {
- if (test_bit(i+16, &subs->active_mask)) {
- if (!test_and_set_bit(i+16, &subs->unlink_mask)) {
- struct urb *u = subs->syncurb[i].urb;
- if (async)
- usb_unlink_urb(u);
- else
- usb_kill_urb(u);
- }
- }
- }
- }
- return 0;
-}
-
-
-/*
- * release a urb data
- */
-static void release_urb_ctx(struct snd_urb_ctx *u)
-{
- if (u->urb) {
- if (u->buffer_size)
- usb_free_coherent(u->subs->dev, u->buffer_size,
- u->urb->transfer_buffer,
- u->urb->transfer_dma);
- usb_free_urb(u->urb);
- u->urb = NULL;
- }
-}
-
-/*
- * wait until all urbs are processed.
- */
-static int wait_clear_urbs(struct snd_usb_substream *subs)
-{
- unsigned long end_time = jiffies + msecs_to_jiffies(1000);
- unsigned int i;
- int alive;
-
- do {
- alive = 0;
- for (i = 0; i < subs->nurbs; i++) {
- if (test_bit(i, &subs->active_mask))
- alive++;
- }
- if (subs->syncpipe) {
- for (i = 0; i < SYNC_URBS; i++) {
- if (test_bit(i + 16, &subs->active_mask))
- alive++;
- }
- }
- if (! alive)
- break;
- schedule_timeout_uninterruptible(1);
- } while (time_before(jiffies, end_time));
- if (alive)
- snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
- return 0;
-}
-
-/*
- * release a substream
- */
-void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force)
-{
- int i;
-
- /* stop urbs (to be sure) */
- deactivate_urbs(subs, force, 1);
- wait_clear_urbs(subs);
-
- for (i = 0; i < MAX_URBS; i++)
- release_urb_ctx(&subs->dataurb[i]);
- for (i = 0; i < SYNC_URBS; i++)
- release_urb_ctx(&subs->syncurb[i]);
- usb_free_coherent(subs->dev, SYNC_URBS * 4,
- subs->syncbuf, subs->sync_dma);
- subs->syncbuf = NULL;
- subs->nurbs = 0;
-}
-
-/*
- * complete callback from data urb
- */
-static void snd_complete_urb(struct urb *urb)
-{
- struct snd_urb_ctx *ctx = urb->context;
- struct snd_usb_substream *subs = ctx->subs;
- struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
- int err = 0;
-
- if ((subs->running && subs->ops.retire(subs, substream->runtime, urb)) ||
- !subs->running || /* can be stopped during retire callback */
- (err = subs->ops.prepare(subs, substream->runtime, urb)) < 0 ||
- (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
- clear_bit(ctx->index, &subs->active_mask);
- if (err < 0) {
- snd_printd(KERN_ERR "cannot submit urb (err = %d)\n", err);
- snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
- }
- }
-}
-
-
-/*
- * complete callback from sync urb
- */
-static void snd_complete_sync_urb(struct urb *urb)
-{
- struct snd_urb_ctx *ctx = urb->context;
- struct snd_usb_substream *subs = ctx->subs;
- struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
- int err = 0;
-
- if ((subs->running && subs->ops.retire_sync(subs, substream->runtime, urb)) ||
- !subs->running || /* can be stopped during retire callback */
- (err = subs->ops.prepare_sync(subs, substream->runtime, urb)) < 0 ||
- (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
- clear_bit(ctx->index + 16, &subs->active_mask);
- if (err < 0) {
- snd_printd(KERN_ERR "cannot submit sync urb (err = %d)\n", err);
- snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
- }
- }
-}
-
-
-/*
- * initialize a substream for plaback/capture
- */
-int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
- unsigned int period_bytes,
- unsigned int rate,
- unsigned int frame_bits)
-{
- unsigned int maxsize, i;
- int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
- unsigned int urb_packs, total_packs, packs_per_ms;
- struct snd_usb_audio *chip = subs->stream->chip;
-
- /* calculate the frequency in 16.16 format */
- if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
- subs->freqn = get_usb_full_speed_rate(rate);
- else
- subs->freqn = get_usb_high_speed_rate(rate);
- subs->freqm = subs->freqn;
- subs->freqshift = INT_MIN;
- /* calculate max. frequency */
- if (subs->maxpacksize) {
- /* whatever fits into a max. size packet */
- maxsize = subs->maxpacksize;
- subs->freqmax = (maxsize / (frame_bits >> 3))
- << (16 - subs->datainterval);
- } else {
- /* no max. packet size: just take 25% higher than nominal */
- subs->freqmax = subs->freqn + (subs->freqn >> 2);
- maxsize = ((subs->freqmax + 0xffff) * (frame_bits >> 3))
- >> (16 - subs->datainterval);
- }
- subs->phase = 0;
-
- if (subs->fill_max)
- subs->curpacksize = subs->maxpacksize;
- else
- subs->curpacksize = maxsize;
-
- if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL)
- packs_per_ms = 8 >> subs->datainterval;
- else
- packs_per_ms = 1;
-
- if (is_playback) {
- urb_packs = max(chip->nrpacks, 1);
- urb_packs = min(urb_packs, (unsigned int)MAX_PACKS);
- } else
- urb_packs = 1;
- urb_packs *= packs_per_ms;
- if (subs->syncpipe)
- urb_packs = min(urb_packs, 1U << subs->syncinterval);
-
- /* decide how many packets to be used */
- if (is_playback) {
- unsigned int minsize, maxpacks;
- /* determine how small a packet can be */
- minsize = (subs->freqn >> (16 - subs->datainterval))
- * (frame_bits >> 3);
- /* with sync from device, assume it can be 12% lower */
- if (subs->syncpipe)
- minsize -= minsize >> 3;
- minsize = max(minsize, 1u);
- total_packs = (period_bytes + minsize - 1) / minsize;
- /* we need at least two URBs for queueing */
- if (total_packs < 2) {
- total_packs = 2;
- } else {
- /* and we don't want too long a queue either */
- maxpacks = max(MAX_QUEUE * packs_per_ms, urb_packs * 2);
- total_packs = min(total_packs, maxpacks);
- }
- } else {
- while (urb_packs > 1 && urb_packs * maxsize >= period_bytes)
- urb_packs >>= 1;
- total_packs = MAX_URBS * urb_packs;
- }
- subs->nurbs = (total_packs + urb_packs - 1) / urb_packs;
- if (subs->nurbs > MAX_URBS) {
- /* too much... */
- subs->nurbs = MAX_URBS;
- total_packs = MAX_URBS * urb_packs;
- } else if (subs->nurbs < 2) {
- /* too little - we need at least two packets
- * to ensure contiguous playback/capture
- */
- subs->nurbs = 2;
- }
-
- /* allocate and initialize data urbs */
- for (i = 0; i < subs->nurbs; i++) {
- struct snd_urb_ctx *u = &subs->dataurb[i];
- u->index = i;
- u->subs = subs;
- u->packets = (i + 1) * total_packs / subs->nurbs
- - i * total_packs / subs->nurbs;
- u->buffer_size = maxsize * u->packets;
- if (subs->fmt_type == UAC_FORMAT_TYPE_II)
- u->packets++; /* for transfer delimiter */
- u->urb = usb_alloc_urb(u->packets, GFP_KERNEL);
- if (!u->urb)
- goto out_of_memory;
- u->urb->transfer_buffer =
- usb_alloc_coherent(subs->dev, u->buffer_size,
- GFP_KERNEL, &u->urb->transfer_dma);
- if (!u->urb->transfer_buffer)
- goto out_of_memory;
- u->urb->pipe = subs->datapipe;
- u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
- u->urb->interval = 1 << subs->datainterval;
- u->urb->context = u;
- u->urb->complete = snd_complete_urb;
- }
-
- if (subs->syncpipe) {
- /* allocate and initialize sync urbs */
- subs->syncbuf = usb_alloc_coherent(subs->dev, SYNC_URBS * 4,
- GFP_KERNEL, &subs->sync_dma);
- if (!subs->syncbuf)
- goto out_of_memory;
- for (i = 0; i < SYNC_URBS; i++) {
- struct snd_urb_ctx *u = &subs->syncurb[i];
- u->index = i;
- u->subs = subs;
- u->packets = 1;
- u->urb = usb_alloc_urb(1, GFP_KERNEL);
- if (!u->urb)
- goto out_of_memory;
- u->urb->transfer_buffer = subs->syncbuf + i * 4;
- u->urb->transfer_dma = subs->sync_dma + i * 4;
- u->urb->transfer_buffer_length = 4;
- u->urb->pipe = subs->syncpipe;
- u->urb->transfer_flags = URB_ISO_ASAP |
- URB_NO_TRANSFER_DMA_MAP;
- u->urb->number_of_packets = 1;
- u->urb->interval = 1 << subs->syncinterval;
- u->urb->context = u;
- u->urb->complete = snd_complete_sync_urb;
- }
- }
- return 0;
-
-out_of_memory:
- snd_usb_release_substream_urbs(subs, 0);
- return -ENOMEM;
-}
-
-/*
- * prepare urb for full speed capture sync pipe
- *
- * fill the length and offset of each urb descriptor.
- * the fixed 10.14 frequency is passed through the pipe.
- */
-static int prepare_capture_sync_urb(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- unsigned char *cp = urb->transfer_buffer;
- struct snd_urb_ctx *ctx = urb->context;
-
- urb->dev = ctx->subs->dev; /* we need to set this at each time */
- urb->iso_frame_desc[0].length = 3;
- urb->iso_frame_desc[0].offset = 0;
- cp[0] = subs->freqn >> 2;
- cp[1] = subs->freqn >> 10;
- cp[2] = subs->freqn >> 18;
- return 0;
-}
-
-/*
- * prepare urb for high speed capture sync pipe
- *
- * fill the length and offset of each urb descriptor.
- * the fixed 12.13 frequency is passed as 16.16 through the pipe.
- */
-static int prepare_capture_sync_urb_hs(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- unsigned char *cp = urb->transfer_buffer;
- struct snd_urb_ctx *ctx = urb->context;
-
- urb->dev = ctx->subs->dev; /* we need to set this at each time */
- urb->iso_frame_desc[0].length = 4;
- urb->iso_frame_desc[0].offset = 0;
- cp[0] = subs->freqn;
- cp[1] = subs->freqn >> 8;
- cp[2] = subs->freqn >> 16;
- cp[3] = subs->freqn >> 24;
- return 0;
-}
-
-/*
- * process after capture sync complete
- * - nothing to do
- */
-static int retire_capture_sync_urb(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- return 0;
-}
-
-/*
- * prepare urb for capture data pipe
- *
- * fill the offset and length of each descriptor.
- *
- * we use a temporary buffer to write the captured data.
- * since the length of written data is determined by host, we cannot
- * write onto the pcm buffer directly... the data is thus copied
- * later at complete callback to the global buffer.
- */
-static int prepare_capture_urb(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- int i, offs;
- struct snd_urb_ctx *ctx = urb->context;
-
- offs = 0;
- urb->dev = ctx->subs->dev; /* we need to set this at each time */
- for (i = 0; i < ctx->packets; i++) {
- urb->iso_frame_desc[i].offset = offs;
- urb->iso_frame_desc[i].length = subs->curpacksize;
- offs += subs->curpacksize;
- }
- urb->transfer_buffer_length = offs;
- urb->number_of_packets = ctx->packets;
- return 0;
-}
-
-/*
- * process after capture complete
- *
- * copy the data from each desctiptor to the pcm buffer, and
- * update the current position.
- */
-static int retire_capture_urb(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- unsigned long flags;
- unsigned char *cp;
- int i;
- unsigned int stride, frames, bytes, oldptr;
- int period_elapsed = 0;
-
- stride = runtime->frame_bits >> 3;
-
- for (i = 0; i < urb->number_of_packets; i++) {
- cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
- if (urb->iso_frame_desc[i].status && printk_ratelimit()) {
- snd_printdd("frame %d active: %d\n", i, urb->iso_frame_desc[i].status);
- // continue;
- }
- bytes = urb->iso_frame_desc[i].actual_length;
- frames = bytes / stride;
- if (!subs->txfr_quirk)
- bytes = frames * stride;
- if (bytes % (runtime->sample_bits >> 3) != 0) {
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- int oldbytes = bytes;
-#endif
- bytes = frames * stride;
- snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n",
- oldbytes, bytes);
- }
- /* update the current pointer */
- spin_lock_irqsave(&subs->lock, flags);
- oldptr = subs->hwptr_done;
- subs->hwptr_done += bytes;
- if (subs->hwptr_done >= runtime->buffer_size * stride)
- subs->hwptr_done -= runtime->buffer_size * stride;
- frames = (bytes + (oldptr % stride)) / stride;
- subs->transfer_done += frames;
- if (subs->transfer_done >= runtime->period_size) {
- subs->transfer_done -= runtime->period_size;
- period_elapsed = 1;
- }
- spin_unlock_irqrestore(&subs->lock, flags);
- /* copy a data chunk */
- if (oldptr + bytes > runtime->buffer_size * stride) {
- unsigned int bytes1 =
- runtime->buffer_size * stride - oldptr;
- memcpy(runtime->dma_area + oldptr, cp, bytes1);
- memcpy(runtime->dma_area, cp + bytes1, bytes - bytes1);
- } else {
- memcpy(runtime->dma_area + oldptr, cp, bytes);
- }
- }
- if (period_elapsed)
- snd_pcm_period_elapsed(subs->pcm_substream);
- return 0;
-}
-
-/*
- * Process after capture complete when paused. Nothing to do.
- */
-static int retire_paused_capture_urb(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- return 0;
-}
-
-
-/*
- * prepare urb for playback sync pipe
- *
- * set up the offset and length to receive the current frequency.
- */
-static int prepare_playback_sync_urb(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- struct snd_urb_ctx *ctx = urb->context;
-
- urb->dev = ctx->subs->dev; /* we need to set this at each time */
- urb->iso_frame_desc[0].length = min(4u, ctx->subs->syncmaxsize);
- urb->iso_frame_desc[0].offset = 0;
- return 0;
-}
-
-/*
- * process after playback sync complete
- *
- * Full speed devices report feedback values in 10.14 format as samples per
- * frame, high speed devices in 16.16 format as samples per microframe.
- * Because the Audio Class 1 spec was written before USB 2.0, many high speed
- * devices use a wrong interpretation, some others use an entirely different
- * format. Therefore, we cannot predict what format any particular device uses
- * and must detect it automatically.
- */
-static int retire_playback_sync_urb(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- unsigned int f;
- int shift;
- unsigned long flags;
-
- if (urb->iso_frame_desc[0].status != 0 ||
- urb->iso_frame_desc[0].actual_length < 3)
- return 0;
-
- f = le32_to_cpup(urb->transfer_buffer);
- if (urb->iso_frame_desc[0].actual_length == 3)
- f &= 0x00ffffff;
- else
- f &= 0x0fffffff;
- if (f == 0)
- return 0;
-
- if (unlikely(subs->freqshift == INT_MIN)) {
- /*
- * The first time we see a feedback value, determine its format
- * by shifting it left or right until it matches the nominal
- * frequency value. This assumes that the feedback does not
- * differ from the nominal value more than +50% or -25%.
- */
- shift = 0;
- while (f < subs->freqn - subs->freqn / 4) {
- f <<= 1;
- shift++;
- }
- while (f > subs->freqn + subs->freqn / 2) {
- f >>= 1;
- shift--;
- }
- subs->freqshift = shift;
- }
- else if (subs->freqshift >= 0)
- f <<= subs->freqshift;
- else
- f >>= -subs->freqshift;
-
- if (likely(f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax)) {
- /*
- * If the frequency looks valid, set it.
- * This value is referred to in prepare_playback_urb().
- */
- spin_lock_irqsave(&subs->lock, flags);
- subs->freqm = f;
- spin_unlock_irqrestore(&subs->lock, flags);
- } else {
- /*
- * Out of range; maybe the shift value is wrong.
- * Reset it so that we autodetect again the next time.
- */
- subs->freqshift = INT_MIN;
- }
-
- return 0;
-}
-
-/* determine the number of frames in the next packet */
-static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs)
-{
- if (subs->fill_max)
- return subs->maxframesize;
- else {
- subs->phase = (subs->phase & 0xffff)
- + (subs->freqm << subs->datainterval);
- return min(subs->phase >> 16, subs->maxframesize);
- }
-}
-
-/*
- * Prepare urb for streaming before playback starts or when paused.
- *
- * We don't have any data, so we send silence.
- */
-static int prepare_nodata_playback_urb(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- unsigned int i, offs, counts;
- struct snd_urb_ctx *ctx = urb->context;
- int stride = runtime->frame_bits >> 3;
-
- offs = 0;
- urb->dev = ctx->subs->dev;
- for (i = 0; i < ctx->packets; ++i) {
- counts = snd_usb_audio_next_packet_size(subs);
- urb->iso_frame_desc[i].offset = offs * stride;
- urb->iso_frame_desc[i].length = counts * stride;
- offs += counts;
- }
- urb->number_of_packets = ctx->packets;
- urb->transfer_buffer_length = offs * stride;
- memset(urb->transfer_buffer,
- runtime->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0,
- offs * stride);
- return 0;
-}
-
-/*
- * prepare urb for playback data pipe
- *
- * Since a URB can handle only a single linear buffer, we must use double
- * buffering when the data to be transferred overflows the buffer boundary.
- * To avoid inconsistencies when updating hwptr_done, we use double buffering
- * for all URBs.
- */
-static int prepare_playback_urb(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- int i, stride;
- unsigned int counts, frames, bytes;
- unsigned long flags;
- int period_elapsed = 0;
- struct snd_urb_ctx *ctx = urb->context;
-
- stride = runtime->frame_bits >> 3;
-
- frames = 0;
- urb->dev = ctx->subs->dev; /* we need to set this at each time */
- urb->number_of_packets = 0;
- spin_lock_irqsave(&subs->lock, flags);
- for (i = 0; i < ctx->packets; i++) {
- counts = snd_usb_audio_next_packet_size(subs);
- /* set up descriptor */
- urb->iso_frame_desc[i].offset = frames * stride;
- urb->iso_frame_desc[i].length = counts * stride;
- frames += counts;
- urb->number_of_packets++;
- subs->transfer_done += counts;
- if (subs->transfer_done >= runtime->period_size) {
- subs->transfer_done -= runtime->period_size;
- period_elapsed = 1;
- if (subs->fmt_type == UAC_FORMAT_TYPE_II) {
- if (subs->transfer_done > 0) {
- /* FIXME: fill-max mode is not
- * supported yet */
- frames -= subs->transfer_done;
- counts -= subs->transfer_done;
- urb->iso_frame_desc[i].length =
- counts * stride;
- subs->transfer_done = 0;
- }
- i++;
- if (i < ctx->packets) {
- /* add a transfer delimiter */
- urb->iso_frame_desc[i].offset =
- frames * stride;
- urb->iso_frame_desc[i].length = 0;
- urb->number_of_packets++;
- }
- break;
- }
- }
- if (period_elapsed) /* finish at the period boundary */
- break;
- }
- bytes = frames * stride;
- if (subs->hwptr_done + bytes > runtime->buffer_size * stride) {
- /* err, the transferred area goes over buffer boundary. */
- unsigned int bytes1 =
- runtime->buffer_size * stride - subs->hwptr_done;
- memcpy(urb->transfer_buffer,
- runtime->dma_area + subs->hwptr_done, bytes1);
- memcpy(urb->transfer_buffer + bytes1,
- runtime->dma_area, bytes - bytes1);
- } else {
- memcpy(urb->transfer_buffer,
- runtime->dma_area + subs->hwptr_done, bytes);
- }
- subs->hwptr_done += bytes;
- if (subs->hwptr_done >= runtime->buffer_size * stride)
- subs->hwptr_done -= runtime->buffer_size * stride;
-
- /* update delay with exact number of samples queued */
- runtime->delay = subs->last_delay;
- runtime->delay += frames;
- subs->last_delay = runtime->delay;
-
- /* realign last_frame_number */
- subs->last_frame_number = usb_get_current_frame_number(subs->dev);
- subs->last_frame_number &= 0xFF; /* keep 8 LSBs */
-
- spin_unlock_irqrestore(&subs->lock, flags);
- urb->transfer_buffer_length = bytes;
- if (period_elapsed)
- snd_pcm_period_elapsed(subs->pcm_substream);
- return 0;
-}
-
-/*
- * process after playback data complete
- * - decrease the delay count again
- */
-static int retire_playback_urb(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- unsigned long flags;
- int stride = runtime->frame_bits >> 3;
- int processed = urb->transfer_buffer_length / stride;
- int est_delay;
-
- spin_lock_irqsave(&subs->lock, flags);
-
- est_delay = snd_usb_pcm_delay(subs, runtime->rate);
- /* update delay with exact number of samples played */
- if (processed > subs->last_delay)
- subs->last_delay = 0;
- else
- subs->last_delay -= processed;
- runtime->delay = subs->last_delay;
-
- /*
- * Report when delay estimate is off by more than 2ms.
- * The error should be lower than 2ms since the estimate relies
- * on two reads of a counter updated every ms.
- */
- if (abs(est_delay - subs->last_delay) * 1000 > runtime->rate * 2)
- snd_printk(KERN_DEBUG "delay: estimated %d, actual %d\n",
- est_delay, subs->last_delay);
-
- spin_unlock_irqrestore(&subs->lock, flags);
- return 0;
-}
-
-static const char *usb_error_string(int err)
-{
- switch (err) {
- case -ENODEV:
- return "no device";
- case -ENOENT:
- return "endpoint not enabled";
- case -EPIPE:
- return "endpoint stalled";
- case -ENOSPC:
- return "not enough bandwidth";
- case -ESHUTDOWN:
- return "device disabled";
- case -EHOSTUNREACH:
- return "device suspended";
- case -EINVAL:
- case -EAGAIN:
- case -EFBIG:
- case -EMSGSIZE:
- return "internal error";
- default:
- return "unknown error";
- }
-}
-
-/*
- * set up and start data/sync urbs
- */
-static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime)
-{
- unsigned int i;
- int err;
-
- if (subs->stream->chip->shutdown)
- return -EBADFD;
-
- for (i = 0; i < subs->nurbs; i++) {
- if (snd_BUG_ON(!subs->dataurb[i].urb))
- return -EINVAL;
- if (subs->ops.prepare(subs, runtime, subs->dataurb[i].urb) < 0) {
- snd_printk(KERN_ERR "cannot prepare datapipe for urb %d\n", i);
- goto __error;
- }
- }
- if (subs->syncpipe) {
- for (i = 0; i < SYNC_URBS; i++) {
- if (snd_BUG_ON(!subs->syncurb[i].urb))
- return -EINVAL;
- if (subs->ops.prepare_sync(subs, runtime, subs->syncurb[i].urb) < 0) {
- snd_printk(KERN_ERR "cannot prepare syncpipe for urb %d\n", i);
- goto __error;
- }
- }
- }
-
- subs->active_mask = 0;
- subs->unlink_mask = 0;
- subs->running = 1;
- for (i = 0; i < subs->nurbs; i++) {
- err = usb_submit_urb(subs->dataurb[i].urb, GFP_ATOMIC);
- if (err < 0) {
- snd_printk(KERN_ERR "cannot submit datapipe "
- "for urb %d, error %d: %s\n",
- i, err, usb_error_string(err));
- goto __error;
- }
- set_bit(i, &subs->active_mask);
- }
- if (subs->syncpipe) {
- for (i = 0; i < SYNC_URBS; i++) {
- err = usb_submit_urb(subs->syncurb[i].urb, GFP_ATOMIC);
- if (err < 0) {
- snd_printk(KERN_ERR "cannot submit syncpipe "
- "for urb %d, error %d: %s\n",
- i, err, usb_error_string(err));
- goto __error;
- }
- set_bit(i + 16, &subs->active_mask);
- }
- }
- return 0;
-
- __error:
- // snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
- deactivate_urbs(subs, 0, 0);
- return -EPIPE;
-}
-
-
-/*
- */
-static struct snd_urb_ops audio_urb_ops[2] = {
- {
- .prepare = prepare_nodata_playback_urb,
- .retire = retire_playback_urb,
- .prepare_sync = prepare_playback_sync_urb,
- .retire_sync = retire_playback_sync_urb,
- },
- {
- .prepare = prepare_capture_urb,
- .retire = retire_capture_urb,
- .prepare_sync = prepare_capture_sync_urb,
- .retire_sync = retire_capture_sync_urb,
- },
-};
-
-/*
- * initialize the substream instance.
- */
-
-void snd_usb_init_substream(struct snd_usb_stream *as,
- int stream, struct audioformat *fp)
-{
- struct snd_usb_substream *subs = &as->substream[stream];
-
- INIT_LIST_HEAD(&subs->fmt_list);
- spin_lock_init(&subs->lock);
-
- subs->stream = as;
- subs->direction = stream;
- subs->dev = as->chip->dev;
- subs->txfr_quirk = as->chip->txfr_quirk;
- subs->ops = audio_urb_ops[stream];
- if (snd_usb_get_speed(subs->dev) >= USB_SPEED_HIGH)
- subs->ops.prepare_sync = prepare_capture_sync_urb_hs;
-
- snd_usb_set_pcm_ops(as->pcm, stream);
-
- list_add_tail(&fp->list, &subs->fmt_list);
- subs->formats |= fp->formats;
- subs->endpoint = fp->endpoint;
- subs->num_formats++;
- subs->fmt_type = fp->fmt_type;
-}
-
-int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_usb_substream *subs = substream->runtime->private_data;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- subs->ops.prepare = prepare_playback_urb;
- return 0;
- case SNDRV_PCM_TRIGGER_STOP:
- return deactivate_urbs(subs, 0, 0);
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- subs->ops.prepare = prepare_nodata_playback_urb;
- return 0;
- }
-
- return -EINVAL;
-}
-
-int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_usb_substream *subs = substream->runtime->private_data;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- subs->ops.retire = retire_capture_urb;
- return start_urbs(subs, substream->runtime);
- case SNDRV_PCM_TRIGGER_STOP:
- return deactivate_urbs(subs, 0, 0);
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- subs->ops.retire = retire_paused_capture_urb;
- return 0;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- subs->ops.retire = retire_capture_urb;
- return 0;
- }
-
- return -EINVAL;
-}
-
-int snd_usb_substream_prepare(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime)
-{
- /* clear urbs (to be sure) */
- deactivate_urbs(subs, 0, 1);
- wait_clear_urbs(subs);
-
- /* for playback, submit the URBs now; otherwise, the first hwptr_done
- * updates for all URBs would happen at the same time when starting */
- if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
- subs->ops.prepare = prepare_nodata_playback_urb;
- return start_urbs(subs, runtime);
- }
-
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/endpoint.h b/ANDROID_3.4.5/sound/usb/endpoint.h
deleted file mode 100644
index 88eb63a6..00000000
--- a/ANDROID_3.4.5/sound/usb/endpoint.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef __USBAUDIO_ENDPOINT_H
-#define __USBAUDIO_ENDPOINT_H
-
-void snd_usb_init_substream(struct snd_usb_stream *as,
- int stream,
- struct audioformat *fp);
-
-int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
- unsigned int period_bytes,
- unsigned int rate,
- unsigned int frame_bits);
-
-void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force);
-
-int snd_usb_substream_prepare(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime);
-
-int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd);
-int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd);
-
-#endif /* __USBAUDIO_ENDPOINT_H */
diff --git a/ANDROID_3.4.5/sound/usb/format.c b/ANDROID_3.4.5/sound/usb/format.c
deleted file mode 100644
index ddfef57c..00000000
--- a/ANDROID_3.4.5/sound/usb/format.c
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/usb/audio.h>
-#include <linux/usb/audio-v2.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include "usbaudio.h"
-#include "card.h"
-#include "quirks.h"
-#include "helper.h"
-#include "debug.h"
-#include "clock.h"
-#include "format.h"
-
-/*
- * parse the audio format type I descriptor
- * and returns the corresponding pcm format
- *
- * @dev: usb device
- * @fp: audioformat record
- * @format: the format tag (wFormatTag)
- * @fmt: the format type descriptor
- */
-static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
- struct audioformat *fp,
- int format, void *_fmt,
- int protocol)
-{
- int sample_width, sample_bytes;
- u64 pcm_formats;
-
- switch (protocol) {
- case UAC_VERSION_1:
- default: {
- struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
- sample_width = fmt->bBitResolution;
- sample_bytes = fmt->bSubframeSize;
- format = 1 << format;
- break;
- }
-
- case UAC_VERSION_2: {
- struct uac_format_type_i_ext_descriptor *fmt = _fmt;
- sample_width = fmt->bBitResolution;
- sample_bytes = fmt->bSubslotSize;
- format <<= 1;
- break;
- }
- }
-
- pcm_formats = 0;
-
- if (format == 0 || format == (1 << UAC_FORMAT_TYPE_I_UNDEFINED)) {
- /* some devices don't define this correctly... */
- snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n",
- chip->dev->devnum, fp->iface, fp->altsetting);
- format = 1 << UAC_FORMAT_TYPE_I_PCM;
- }
- if (format & (1 << UAC_FORMAT_TYPE_I_PCM)) {
- if (chip->usb_id == USB_ID(0x0582, 0x0016) /* Edirol SD-90 */ &&
- sample_width == 24 && sample_bytes == 2)
- sample_bytes = 3;
- else if (sample_width > sample_bytes * 8) {
- snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n",
- chip->dev->devnum, fp->iface, fp->altsetting,
- sample_width, sample_bytes);
- }
- /* check the format byte size */
- switch (sample_bytes) {
- case 1:
- pcm_formats |= SNDRV_PCM_FMTBIT_S8;
- break;
- case 2:
- if (snd_usb_is_big_endian_format(chip, fp))
- pcm_formats |= SNDRV_PCM_FMTBIT_S16_BE; /* grrr, big endian!! */
- else
- pcm_formats |= SNDRV_PCM_FMTBIT_S16_LE;
- break;
- case 3:
- if (snd_usb_is_big_endian_format(chip, fp))
- pcm_formats |= SNDRV_PCM_FMTBIT_S24_3BE; /* grrr, big endian!! */
- else
- pcm_formats |= SNDRV_PCM_FMTBIT_S24_3LE;
- break;
- case 4:
- pcm_formats |= SNDRV_PCM_FMTBIT_S32_LE;
- break;
- default:
- snd_printk(KERN_INFO "%d:%u:%d : unsupported sample bitwidth %d in %d bytes\n",
- chip->dev->devnum, fp->iface, fp->altsetting,
- sample_width, sample_bytes);
- break;
- }
- }
- if (format & (1 << UAC_FORMAT_TYPE_I_PCM8)) {
- /* Dallas DS4201 workaround: it advertises U8 format, but really
- supports S8. */
- if (chip->usb_id == USB_ID(0x04fa, 0x4201))
- pcm_formats |= SNDRV_PCM_FMTBIT_S8;
- else
- pcm_formats |= SNDRV_PCM_FMTBIT_U8;
- }
- if (format & (1 << UAC_FORMAT_TYPE_I_IEEE_FLOAT)) {
- pcm_formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
- }
- if (format & (1 << UAC_FORMAT_TYPE_I_ALAW)) {
- pcm_formats |= SNDRV_PCM_FMTBIT_A_LAW;
- }
- if (format & (1 << UAC_FORMAT_TYPE_I_MULAW)) {
- pcm_formats |= SNDRV_PCM_FMTBIT_MU_LAW;
- }
- if (format & ~0x3f) {
- snd_printk(KERN_INFO "%d:%u:%d : unsupported format bits %#x\n",
- chip->dev->devnum, fp->iface, fp->altsetting, format);
- }
- return pcm_formats;
-}
-
-
-/*
- * parse the format descriptor and stores the possible sample rates
- * on the audioformat table (audio class v1).
- *
- * @dev: usb device
- * @fp: audioformat record
- * @fmt: the format descriptor
- * @offset: the start offset of descriptor pointing the rate type
- * (7 for type I and II, 8 for type II)
- */
-static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audioformat *fp,
- unsigned char *fmt, int offset)
-{
- int nr_rates = fmt[offset];
-
- if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) {
- snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
- chip->dev->devnum, fp->iface, fp->altsetting);
- return -1;
- }
-
- if (nr_rates) {
- /*
- * build the rate table and bitmap flags
- */
- int r, idx;
-
- fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
- if (fp->rate_table == NULL) {
- snd_printk(KERN_ERR "cannot malloc\n");
- return -1;
- }
-
- fp->nr_rates = 0;
- fp->rate_min = fp->rate_max = 0;
- for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) {
- unsigned int rate = combine_triple(&fmt[idx]);
- if (!rate)
- continue;
- /* C-Media CM6501 mislabels its 96 kHz altsetting */
- /* Terratec Aureon 7.1 USB C-Media 6206, too */
- if (rate == 48000 && nr_rates == 1 &&
- (chip->usb_id == USB_ID(0x0d8c, 0x0201) ||
- chip->usb_id == USB_ID(0x0d8c, 0x0102) ||
- chip->usb_id == USB_ID(0x0ccd, 0x00b1)) &&
- fp->altsetting == 5 && fp->maxpacksize == 392)
- rate = 96000;
- /* Creative VF0470 Live Cam reports 16 kHz instead of 8kHz */
- if (rate == 16000 && chip->usb_id == USB_ID(0x041e, 0x4068))
- rate = 8000;
-
- fp->rate_table[fp->nr_rates] = rate;
- if (!fp->rate_min || rate < fp->rate_min)
- fp->rate_min = rate;
- if (!fp->rate_max || rate > fp->rate_max)
- fp->rate_max = rate;
- fp->rates |= snd_pcm_rate_to_rate_bit(rate);
- fp->nr_rates++;
- }
- if (!fp->nr_rates) {
- hwc_debug("All rates were zero. Skipping format!\n");
- return -1;
- }
- } else {
- /* continuous rates */
- fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
- fp->rate_min = combine_triple(&fmt[offset + 1]);
- fp->rate_max = combine_triple(&fmt[offset + 4]);
- }
- return 0;
-}
-
-/*
- * Helper function to walk the array of sample rate triplets reported by
- * the device. The problem is that we need to parse whole array first to
- * get to know how many sample rates we have to expect.
- * Then fp->rate_table can be allocated and filled.
- */
-static int parse_uac2_sample_rate_range(struct audioformat *fp, int nr_triplets,
- const unsigned char *data)
-{
- int i, nr_rates = 0;
-
- fp->rates = fp->rate_min = fp->rate_max = 0;
-
- for (i = 0; i < nr_triplets; i++) {
- int min = combine_quad(&data[2 + 12 * i]);
- int max = combine_quad(&data[6 + 12 * i]);
- int res = combine_quad(&data[10 + 12 * i]);
- unsigned int rate;
-
- if ((max < 0) || (min < 0) || (res < 0) || (max < min))
- continue;
-
- /*
- * for ranges with res == 1, we announce a continuous sample
- * rate range, and this function should return 0 for no further
- * parsing.
- */
- if (res == 1) {
- fp->rate_min = min;
- fp->rate_max = max;
- fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
- return 0;
- }
-
- for (rate = min; rate <= max; rate += res) {
- if (fp->rate_table)
- fp->rate_table[nr_rates] = rate;
- if (!fp->rate_min || rate < fp->rate_min)
- fp->rate_min = rate;
- if (!fp->rate_max || rate > fp->rate_max)
- fp->rate_max = rate;
- fp->rates |= snd_pcm_rate_to_rate_bit(rate);
-
- nr_rates++;
- if (nr_rates >= MAX_NR_RATES) {
- snd_printk(KERN_ERR "invalid uac2 rates\n");
- break;
- }
-
- /* avoid endless loop */
- if (res == 0)
- break;
- }
- }
-
- return nr_rates;
-}
-
-/*
- * parse the format descriptor and stores the possible sample rates
- * on the audioformat table (audio class v2).
- */
-static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
- struct audioformat *fp)
-{
- struct usb_device *dev = chip->dev;
- unsigned char tmp[2], *data;
- int nr_triplets, data_size, ret = 0;
- int clock = snd_usb_clock_find_source(chip, fp->clock);
-
- if (clock < 0) {
- snd_printk(KERN_ERR "%s(): unable to find clock source (clock %d)\n",
- __func__, clock);
- goto err;
- }
-
- /* get the number of sample rates first by only fetching 2 bytes */
- ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
- UAC2_CS_CONTROL_SAM_FREQ << 8,
- snd_usb_ctrl_intf(chip) | (clock << 8),
- tmp, sizeof(tmp));
-
- if (ret < 0) {
- snd_printk(KERN_ERR "%s(): unable to retrieve number of sample rates (clock %d)\n",
- __func__, clock);
- goto err;
- }
-
- nr_triplets = (tmp[1] << 8) | tmp[0];
- data_size = 2 + 12 * nr_triplets;
- data = kzalloc(data_size, GFP_KERNEL);
- if (!data) {
- ret = -ENOMEM;
- goto err;
- }
-
- /* now get the full information */
- ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
- UAC2_CS_CONTROL_SAM_FREQ << 8,
- snd_usb_ctrl_intf(chip) | (clock << 8),
- data, data_size);
-
- if (ret < 0) {
- snd_printk(KERN_ERR "%s(): unable to retrieve sample rate range (clock %d)\n",
- __func__, clock);
- ret = -EINVAL;
- goto err_free;
- }
-
- /* Call the triplet parser, and make sure fp->rate_table is NULL.
- * We just use the return value to know how many sample rates we
- * will have to deal with. */
- kfree(fp->rate_table);
- fp->rate_table = NULL;
- fp->nr_rates = parse_uac2_sample_rate_range(fp, nr_triplets, data);
-
- if (fp->nr_rates == 0) {
- /* SNDRV_PCM_RATE_CONTINUOUS */
- ret = 0;
- goto err_free;
- }
-
- fp->rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL);
- if (!fp->rate_table) {
- ret = -ENOMEM;
- goto err_free;
- }
-
- /* Call the triplet parser again, but this time, fp->rate_table is
- * allocated, so the rates will be stored */
- parse_uac2_sample_rate_range(fp, nr_triplets, data);
-
-err_free:
- kfree(data);
-err:
- return ret;
-}
-
-/*
- * parse the format type I and III descriptors
- */
-static int parse_audio_format_i(struct snd_usb_audio *chip,
- struct audioformat *fp, int format,
- struct uac_format_type_i_continuous_descriptor *fmt,
- struct usb_host_interface *iface)
-{
- struct usb_interface_descriptor *altsd = get_iface_desc(iface);
- int protocol = altsd->bInterfaceProtocol;
- int pcm_format, ret;
-
- if (fmt->bFormatType == UAC_FORMAT_TYPE_III) {
- /* FIXME: the format type is really IECxxx
- * but we give normal PCM format to get the existing
- * apps working...
- */
- switch (chip->usb_id) {
-
- case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
- if (chip->setup == 0x00 &&
- fp->altsetting == 6)
- pcm_format = SNDRV_PCM_FORMAT_S16_BE;
- else
- pcm_format = SNDRV_PCM_FORMAT_S16_LE;
- break;
- default:
- pcm_format = SNDRV_PCM_FORMAT_S16_LE;
- }
- fp->formats = 1uLL << pcm_format;
- } else {
- fp->formats = parse_audio_format_i_type(chip, fp, format,
- fmt, protocol);
- if (!fp->formats)
- return -1;
- }
-
- /* gather possible sample rates */
- /* audio class v1 reports possible sample rates as part of the
- * proprietary class specific descriptor.
- * audio class v2 uses class specific EP0 range requests for that.
- */
- switch (protocol) {
- default:
- snd_printdd(KERN_WARNING "%d:%u:%d : invalid protocol version %d, assuming v1\n",
- chip->dev->devnum, fp->iface, fp->altsetting, protocol);
- /* fall through */
- case UAC_VERSION_1:
- fp->channels = fmt->bNrChannels;
- ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7);
- break;
- case UAC_VERSION_2:
- /* fp->channels is already set in this case */
- ret = parse_audio_format_rates_v2(chip, fp);
- break;
- }
-
- if (fp->channels < 1) {
- snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n",
- chip->dev->devnum, fp->iface, fp->altsetting, fp->channels);
- return -1;
- }
-
- return ret;
-}
-
-/*
- * parse the format type II descriptor
- */
-static int parse_audio_format_ii(struct snd_usb_audio *chip,
- struct audioformat *fp,
- int format, void *_fmt,
- struct usb_host_interface *iface)
-{
- int brate, framesize, ret;
- struct usb_interface_descriptor *altsd = get_iface_desc(iface);
- int protocol = altsd->bInterfaceProtocol;
-
- switch (format) {
- case UAC_FORMAT_TYPE_II_AC3:
- /* FIXME: there is no AC3 format defined yet */
- // fp->formats = SNDRV_PCM_FMTBIT_AC3;
- fp->formats = SNDRV_PCM_FMTBIT_U8; /* temporary hack to receive byte streams */
- break;
- case UAC_FORMAT_TYPE_II_MPEG:
- fp->formats = SNDRV_PCM_FMTBIT_MPEG;
- break;
- default:
- snd_printd(KERN_INFO "%d:%u:%d : unknown format tag %#x is detected. processed as MPEG.\n",
- chip->dev->devnum, fp->iface, fp->altsetting, format);
- fp->formats = SNDRV_PCM_FMTBIT_MPEG;
- break;
- }
-
- fp->channels = 1;
-
- switch (protocol) {
- default:
- snd_printdd(KERN_WARNING "%d:%u:%d : invalid protocol version %d, assuming v1\n",
- chip->dev->devnum, fp->iface, fp->altsetting, protocol);
- /* fall through */
- case UAC_VERSION_1: {
- struct uac_format_type_ii_discrete_descriptor *fmt = _fmt;
- brate = le16_to_cpu(fmt->wMaxBitRate);
- framesize = le16_to_cpu(fmt->wSamplesPerFrame);
- snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
- fp->frame_size = framesize;
- ret = parse_audio_format_rates_v1(chip, fp, _fmt, 8); /* fmt[8..] sample rates */
- break;
- }
- case UAC_VERSION_2: {
- struct uac_format_type_ii_ext_descriptor *fmt = _fmt;
- brate = le16_to_cpu(fmt->wMaxBitRate);
- framesize = le16_to_cpu(fmt->wSamplesPerFrame);
- snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
- fp->frame_size = framesize;
- ret = parse_audio_format_rates_v2(chip, fp);
- break;
- }
- }
-
- return ret;
-}
-
-int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp,
- int format, struct uac_format_type_i_continuous_descriptor *fmt,
- int stream, struct usb_host_interface *iface)
-{
- int err;
-
- switch (fmt->bFormatType) {
- case UAC_FORMAT_TYPE_I:
- case UAC_FORMAT_TYPE_III:
- err = parse_audio_format_i(chip, fp, format, fmt, iface);
- break;
- case UAC_FORMAT_TYPE_II:
- err = parse_audio_format_ii(chip, fp, format, fmt, iface);
- break;
- default:
- snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n",
- chip->dev->devnum, fp->iface, fp->altsetting,
- fmt->bFormatType);
- return -ENOTSUPP;
- }
- fp->fmt_type = fmt->bFormatType;
- if (err < 0)
- return err;
-#if 1
- /* FIXME: temporary hack for extigy/audigy 2 nx/zs */
- /* extigy apparently supports sample rates other than 48k
- * but not in ordinary way. so we enable only 48k atm.
- */
- if (chip->usb_id == USB_ID(0x041e, 0x3000) ||
- chip->usb_id == USB_ID(0x041e, 0x3020) ||
- chip->usb_id == USB_ID(0x041e, 0x3061)) {
- if (fmt->bFormatType == UAC_FORMAT_TYPE_I &&
- fp->rates != SNDRV_PCM_RATE_48000 &&
- fp->rates != SNDRV_PCM_RATE_96000)
- return -ENOTSUPP;
- }
-#endif
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/format.h b/ANDROID_3.4.5/sound/usb/format.h
deleted file mode 100644
index 387924f0..00000000
--- a/ANDROID_3.4.5/sound/usb/format.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __USBAUDIO_FORMAT_H
-#define __USBAUDIO_FORMAT_H
-
-int snd_usb_parse_audio_format(struct snd_usb_audio *chip,
- struct audioformat *fp, int format,
- struct uac_format_type_i_continuous_descriptor *fmt,
- int stream, struct usb_host_interface *iface);
-
-#endif /* __USBAUDIO_FORMAT_H */
diff --git a/ANDROID_3.4.5/sound/usb/helper.c b/ANDROID_3.4.5/sound/usb/helper.c
deleted file mode 100644
index 9eed8f40..00000000
--- a/ANDROID_3.4.5/sound/usb/helper.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-
-#include "usbaudio.h"
-#include "helper.h"
-
-/*
- * combine bytes and get an integer value
- */
-unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size)
-{
- switch (size) {
- case 1: return *bytes;
- case 2: return combine_word(bytes);
- case 3: return combine_triple(bytes);
- case 4: return combine_quad(bytes);
- default: return 0;
- }
-}
-
-/*
- * parse descriptor buffer and return the pointer starting the given
- * descriptor type.
- */
-void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype)
-{
- u8 *p, *end, *next;
-
- p = descstart;
- end = p + desclen;
- for (; p < end;) {
- if (p[0] < 2)
- return NULL;
- next = p + p[0];
- if (next > end)
- return NULL;
- if (p[1] == dtype && (!after || (void *)p > after)) {
- return p;
- }
- p = next;
- }
- return NULL;
-}
-
-/*
- * find a class-specified interface descriptor with the given subtype.
- */
-void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype)
-{
- unsigned char *p = after;
-
- while ((p = snd_usb_find_desc(buffer, buflen, p,
- USB_DT_CS_INTERFACE)) != NULL) {
- if (p[0] >= 3 && p[2] == dsubtype)
- return p;
- }
- return NULL;
-}
-
-/*
- * Wrapper for usb_control_msg().
- * Allocates a temp buffer to prevent dmaing from/to the stack.
- */
-int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
- __u8 requesttype, __u16 value, __u16 index, void *data,
- __u16 size)
-{
- int err;
- void *buf = NULL;
-
- if (size > 0) {
- buf = kmemdup(data, size, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
- }
- err = usb_control_msg(dev, pipe, request, requesttype,
- value, index, buf, size, 1000);
- if (size > 0) {
- memcpy(data, buf, size);
- kfree(buf);
- }
- return err;
-}
-
-unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
- struct usb_host_interface *alts)
-{
- switch (snd_usb_get_speed(chip->dev)) {
- case USB_SPEED_HIGH:
- case USB_SPEED_SUPER:
- if (get_endpoint(alts, 0)->bInterval >= 1 &&
- get_endpoint(alts, 0)->bInterval <= 4)
- return get_endpoint(alts, 0)->bInterval - 1;
- break;
- default:
- break;
- }
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/helper.h b/ANDROID_3.4.5/sound/usb/helper.h
deleted file mode 100644
index 805c300d..00000000
--- a/ANDROID_3.4.5/sound/usb/helper.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef __USBAUDIO_HELPER_H
-#define __USBAUDIO_HELPER_H
-
-unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size);
-
-void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype);
-void *snd_usb_find_csint_desc(void *descstart, int desclen, void *after, u8 dsubtype);
-
-int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe,
- __u8 request, __u8 requesttype, __u16 value, __u16 index,
- void *data, __u16 size);
-
-unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
- struct usb_host_interface *alts);
-
-/*
- * retrieve usb_interface descriptor from the host interface
- * (conditional for compatibility with the older API)
- */
-#ifndef get_iface_desc
-#define get_iface_desc(iface) (&(iface)->desc)
-#define get_endpoint(alt,ep) (&(alt)->endpoint[ep].desc)
-#define get_ep_desc(ep) (&(ep)->desc)
-#define get_cfg_desc(cfg) (&(cfg)->desc)
-#endif
-
-#ifndef snd_usb_get_speed
-#define snd_usb_get_speed(dev) ((dev)->speed)
-#endif
-
-static inline int snd_usb_ctrl_intf(struct snd_usb_audio *chip)
-{
- return get_iface_desc(chip->ctrl_intf)->bInterfaceNumber;
-}
-
-#endif /* __USBAUDIO_HELPER_H */
diff --git a/ANDROID_3.4.5/sound/usb/midi.c b/ANDROID_3.4.5/sound/usb/midi.c
deleted file mode 100644
index c83f6143..00000000
--- a/ANDROID_3.4.5/sound/usb/midi.c
+++ /dev/null
@@ -1,2237 +0,0 @@
-/*
- * usbmidi.c - ALSA USB MIDI driver
- *
- * Copyright (c) 2002-2009 Clemens Ladisch
- * All rights reserved.
- *
- * Based on the OSS usb-midi driver by NAGANO Daisuke,
- * NetBSD's umidi driver by Takuya SHIOZAKI,
- * the "USB Device Class Definition for MIDI Devices" by Roland
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed and/or modified under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/bitops.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/timer.h>
-#include <linux/usb.h>
-#include <linux/wait.h>
-#include <linux/usb/audio.h>
-#include <linux/module.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/rawmidi.h>
-#include <sound/asequencer.h>
-#include "usbaudio.h"
-#include "midi.h"
-#include "power.h"
-#include "helper.h"
-
-/*
- * define this to log all USB packets
- */
-/* #define DUMP_PACKETS */
-
-/*
- * how long to wait after some USB errors, so that khubd can disconnect() us
- * without too many spurious errors
- */
-#define ERROR_DELAY_JIFFIES (HZ / 10)
-
-#define OUTPUT_URBS 7
-#define INPUT_URBS 7
-
-
-MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
-MODULE_DESCRIPTION("USB Audio/MIDI helper module");
-MODULE_LICENSE("Dual BSD/GPL");
-
-
-struct usb_ms_header_descriptor {
- __u8 bLength;
- __u8 bDescriptorType;
- __u8 bDescriptorSubtype;
- __u8 bcdMSC[2];
- __le16 wTotalLength;
-} __attribute__ ((packed));
-
-struct usb_ms_endpoint_descriptor {
- __u8 bLength;
- __u8 bDescriptorType;
- __u8 bDescriptorSubtype;
- __u8 bNumEmbMIDIJack;
- __u8 baAssocJackID[0];
-} __attribute__ ((packed));
-
-struct snd_usb_midi_in_endpoint;
-struct snd_usb_midi_out_endpoint;
-struct snd_usb_midi_endpoint;
-
-struct usb_protocol_ops {
- void (*input)(struct snd_usb_midi_in_endpoint*, uint8_t*, int);
- void (*output)(struct snd_usb_midi_out_endpoint *ep, struct urb *urb);
- void (*output_packet)(struct urb*, uint8_t, uint8_t, uint8_t, uint8_t);
- void (*init_out_endpoint)(struct snd_usb_midi_out_endpoint*);
- void (*finish_out_endpoint)(struct snd_usb_midi_out_endpoint*);
-};
-
-struct snd_usb_midi {
- struct usb_device *dev;
- struct snd_card *card;
- struct usb_interface *iface;
- const struct snd_usb_audio_quirk *quirk;
- struct snd_rawmidi *rmidi;
- struct usb_protocol_ops* usb_protocol_ops;
- struct list_head list;
- struct timer_list error_timer;
- spinlock_t disc_lock;
- struct mutex mutex;
- u32 usb_id;
- int next_midi_device;
-
- struct snd_usb_midi_endpoint {
- struct snd_usb_midi_out_endpoint *out;
- struct snd_usb_midi_in_endpoint *in;
- } endpoints[MIDI_MAX_ENDPOINTS];
- unsigned long input_triggered;
- unsigned int opened;
- unsigned char disconnected;
-
- struct snd_kcontrol *roland_load_ctl;
-};
-
-struct snd_usb_midi_out_endpoint {
- struct snd_usb_midi* umidi;
- struct out_urb_context {
- struct urb *urb;
- struct snd_usb_midi_out_endpoint *ep;
- } urbs[OUTPUT_URBS];
- unsigned int active_urbs;
- unsigned int drain_urbs;
- int max_transfer; /* size of urb buffer */
- struct tasklet_struct tasklet;
- unsigned int next_urb;
- spinlock_t buffer_lock;
-
- struct usbmidi_out_port {
- struct snd_usb_midi_out_endpoint* ep;
- struct snd_rawmidi_substream *substream;
- int active;
- uint8_t cable; /* cable number << 4 */
- uint8_t state;
-#define STATE_UNKNOWN 0
-#define STATE_1PARAM 1
-#define STATE_2PARAM_1 2
-#define STATE_2PARAM_2 3
-#define STATE_SYSEX_0 4
-#define STATE_SYSEX_1 5
-#define STATE_SYSEX_2 6
- uint8_t data[2];
- } ports[0x10];
- int current_port;
-
- wait_queue_head_t drain_wait;
-};
-
-struct snd_usb_midi_in_endpoint {
- struct snd_usb_midi* umidi;
- struct urb* urbs[INPUT_URBS];
- struct usbmidi_in_port {
- struct snd_rawmidi_substream *substream;
- u8 running_status_length;
- } ports[0x10];
- u8 seen_f5;
- u8 error_resubmit;
- int current_port;
-};
-
-static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep);
-
-static const uint8_t snd_usbmidi_cin_length[] = {
- 0, 0, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1
-};
-
-/*
- * Submits the URB, with error handling.
- */
-static int snd_usbmidi_submit_urb(struct urb* urb, gfp_t flags)
-{
- int err = usb_submit_urb(urb, flags);
- if (err < 0 && err != -ENODEV)
- snd_printk(KERN_ERR "usb_submit_urb: %d\n", err);
- return err;
-}
-
-/*
- * Error handling for URB completion functions.
- */
-static int snd_usbmidi_urb_error(int status)
-{
- switch (status) {
- /* manually unlinked, or device gone */
- case -ENOENT:
- case -ECONNRESET:
- case -ESHUTDOWN:
- case -ENODEV:
- return -ENODEV;
- /* errors that might occur during unplugging */
- case -EPROTO:
- case -ETIME:
- case -EILSEQ:
- return -EIO;
- default:
- snd_printk(KERN_ERR "urb status %d\n", status);
- return 0; /* continue */
- }
-}
-
-/*
- * Receives a chunk of MIDI data.
- */
-static void snd_usbmidi_input_data(struct snd_usb_midi_in_endpoint* ep, int portidx,
- uint8_t* data, int length)
-{
- struct usbmidi_in_port* port = &ep->ports[portidx];
-
- if (!port->substream) {
- snd_printd("unexpected port %d!\n", portidx);
- return;
- }
- if (!test_bit(port->substream->number, &ep->umidi->input_triggered))
- return;
- snd_rawmidi_receive(port->substream, data, length);
-}
-
-#ifdef DUMP_PACKETS
-static void dump_urb(const char *type, const u8 *data, int length)
-{
- snd_printk(KERN_DEBUG "%s packet: [", type);
- for (; length > 0; ++data, --length)
- printk(" %02x", *data);
- printk(" ]\n");
-}
-#else
-#define dump_urb(type, data, length) /* nothing */
-#endif
-
-/*
- * Processes the data read from the device.
- */
-static void snd_usbmidi_in_urb_complete(struct urb* urb)
-{
- struct snd_usb_midi_in_endpoint* ep = urb->context;
-
- if (urb->status == 0) {
- dump_urb("received", urb->transfer_buffer, urb->actual_length);
- ep->umidi->usb_protocol_ops->input(ep, urb->transfer_buffer,
- urb->actual_length);
- } else {
- int err = snd_usbmidi_urb_error(urb->status);
- if (err < 0) {
- if (err != -ENODEV) {
- ep->error_resubmit = 1;
- mod_timer(&ep->umidi->error_timer,
- jiffies + ERROR_DELAY_JIFFIES);
- }
- return;
- }
- }
-
- urb->dev = ep->umidi->dev;
- snd_usbmidi_submit_urb(urb, GFP_ATOMIC);
-}
-
-static void snd_usbmidi_out_urb_complete(struct urb* urb)
-{
- struct out_urb_context *context = urb->context;
- struct snd_usb_midi_out_endpoint* ep = context->ep;
- unsigned int urb_index;
-
- spin_lock(&ep->buffer_lock);
- urb_index = context - ep->urbs;
- ep->active_urbs &= ~(1 << urb_index);
- if (unlikely(ep->drain_urbs)) {
- ep->drain_urbs &= ~(1 << urb_index);
- wake_up(&ep->drain_wait);
- }
- spin_unlock(&ep->buffer_lock);
- if (urb->status < 0) {
- int err = snd_usbmidi_urb_error(urb->status);
- if (err < 0) {
- if (err != -ENODEV)
- mod_timer(&ep->umidi->error_timer,
- jiffies + ERROR_DELAY_JIFFIES);
- return;
- }
- }
- snd_usbmidi_do_output(ep);
-}
-
-/*
- * This is called when some data should be transferred to the device
- * (from one or more substreams).
- */
-static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep)
-{
- unsigned int urb_index;
- struct urb* urb;
- unsigned long flags;
-
- spin_lock_irqsave(&ep->buffer_lock, flags);
- if (ep->umidi->disconnected) {
- spin_unlock_irqrestore(&ep->buffer_lock, flags);
- return;
- }
-
- urb_index = ep->next_urb;
- for (;;) {
- if (!(ep->active_urbs & (1 << urb_index))) {
- urb = ep->urbs[urb_index].urb;
- urb->transfer_buffer_length = 0;
- ep->umidi->usb_protocol_ops->output(ep, urb);
- if (urb->transfer_buffer_length == 0)
- break;
-
- dump_urb("sending", urb->transfer_buffer,
- urb->transfer_buffer_length);
- urb->dev = ep->umidi->dev;
- if (snd_usbmidi_submit_urb(urb, GFP_ATOMIC) < 0)
- break;
- ep->active_urbs |= 1 << urb_index;
- }
- if (++urb_index >= OUTPUT_URBS)
- urb_index = 0;
- if (urb_index == ep->next_urb)
- break;
- }
- ep->next_urb = urb_index;
- spin_unlock_irqrestore(&ep->buffer_lock, flags);
-}
-
-static void snd_usbmidi_out_tasklet(unsigned long data)
-{
- struct snd_usb_midi_out_endpoint* ep = (struct snd_usb_midi_out_endpoint *) data;
-
- snd_usbmidi_do_output(ep);
-}
-
-/* called after transfers had been interrupted due to some USB error */
-static void snd_usbmidi_error_timer(unsigned long data)
-{
- struct snd_usb_midi *umidi = (struct snd_usb_midi *)data;
- unsigned int i, j;
-
- spin_lock(&umidi->disc_lock);
- if (umidi->disconnected) {
- spin_unlock(&umidi->disc_lock);
- return;
- }
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
- struct snd_usb_midi_in_endpoint *in = umidi->endpoints[i].in;
- if (in && in->error_resubmit) {
- in->error_resubmit = 0;
- for (j = 0; j < INPUT_URBS; ++j) {
- in->urbs[j]->dev = umidi->dev;
- snd_usbmidi_submit_urb(in->urbs[j], GFP_ATOMIC);
- }
- }
- if (umidi->endpoints[i].out)
- snd_usbmidi_do_output(umidi->endpoints[i].out);
- }
- spin_unlock(&umidi->disc_lock);
-}
-
-/* helper function to send static data that may not DMA-able */
-static int send_bulk_static_data(struct snd_usb_midi_out_endpoint* ep,
- const void *data, int len)
-{
- int err = 0;
- void *buf = kmemdup(data, len, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
- dump_urb("sending", buf, len);
- if (ep->urbs[0].urb)
- err = usb_bulk_msg(ep->umidi->dev, ep->urbs[0].urb->pipe,
- buf, len, NULL, 250);
- kfree(buf);
- return err;
-}
-
-/*
- * Standard USB MIDI protocol: see the spec.
- * Midiman protocol: like the standard protocol, but the control byte is the
- * fourth byte in each packet, and uses length instead of CIN.
- */
-
-static void snd_usbmidi_standard_input(struct snd_usb_midi_in_endpoint* ep,
- uint8_t* buffer, int buffer_length)
-{
- int i;
-
- for (i = 0; i + 3 < buffer_length; i += 4)
- if (buffer[i] != 0) {
- int cable = buffer[i] >> 4;
- int length = snd_usbmidi_cin_length[buffer[i] & 0x0f];
- snd_usbmidi_input_data(ep, cable, &buffer[i + 1], length);
- }
-}
-
-static void snd_usbmidi_midiman_input(struct snd_usb_midi_in_endpoint* ep,
- uint8_t* buffer, int buffer_length)
-{
- int i;
-
- for (i = 0; i + 3 < buffer_length; i += 4)
- if (buffer[i + 3] != 0) {
- int port = buffer[i + 3] >> 4;
- int length = buffer[i + 3] & 3;
- snd_usbmidi_input_data(ep, port, &buffer[i], length);
- }
-}
-
-/*
- * Buggy M-Audio device: running status on input results in a packet that has
- * the data bytes but not the status byte and that is marked with CIN 4.
- */
-static void snd_usbmidi_maudio_broken_running_status_input(
- struct snd_usb_midi_in_endpoint* ep,
- uint8_t* buffer, int buffer_length)
-{
- int i;
-
- for (i = 0; i + 3 < buffer_length; i += 4)
- if (buffer[i] != 0) {
- int cable = buffer[i] >> 4;
- u8 cin = buffer[i] & 0x0f;
- struct usbmidi_in_port *port = &ep->ports[cable];
- int length;
-
- length = snd_usbmidi_cin_length[cin];
- if (cin == 0xf && buffer[i + 1] >= 0xf8)
- ; /* realtime msg: no running status change */
- else if (cin >= 0x8 && cin <= 0xe)
- /* channel msg */
- port->running_status_length = length - 1;
- else if (cin == 0x4 &&
- port->running_status_length != 0 &&
- buffer[i + 1] < 0x80)
- /* CIN 4 that is not a SysEx */
- length = port->running_status_length;
- else
- /*
- * All other msgs cannot begin running status.
- * (A channel msg sent as two or three CIN 0xF
- * packets could in theory, but this device
- * doesn't use this format.)
- */
- port->running_status_length = 0;
- snd_usbmidi_input_data(ep, cable, &buffer[i + 1], length);
- }
-}
-
-/*
- * CME protocol: like the standard protocol, but SysEx commands are sent as a
- * single USB packet preceded by a 0x0F byte.
- */
-static void snd_usbmidi_cme_input(struct snd_usb_midi_in_endpoint *ep,
- uint8_t *buffer, int buffer_length)
-{
- if (buffer_length < 2 || (buffer[0] & 0x0f) != 0x0f)
- snd_usbmidi_standard_input(ep, buffer, buffer_length);
- else
- snd_usbmidi_input_data(ep, buffer[0] >> 4,
- &buffer[1], buffer_length - 1);
-}
-
-/*
- * Adds one USB MIDI packet to the output buffer.
- */
-static void snd_usbmidi_output_standard_packet(struct urb* urb, uint8_t p0,
- uint8_t p1, uint8_t p2, uint8_t p3)
-{
-
- uint8_t* buf = (uint8_t*)urb->transfer_buffer + urb->transfer_buffer_length;
- buf[0] = p0;
- buf[1] = p1;
- buf[2] = p2;
- buf[3] = p3;
- urb->transfer_buffer_length += 4;
-}
-
-/*
- * Adds one Midiman packet to the output buffer.
- */
-static void snd_usbmidi_output_midiman_packet(struct urb* urb, uint8_t p0,
- uint8_t p1, uint8_t p2, uint8_t p3)
-{
-
- uint8_t* buf = (uint8_t*)urb->transfer_buffer + urb->transfer_buffer_length;
- buf[0] = p1;
- buf[1] = p2;
- buf[2] = p3;
- buf[3] = (p0 & 0xf0) | snd_usbmidi_cin_length[p0 & 0x0f];
- urb->transfer_buffer_length += 4;
-}
-
-/*
- * Converts MIDI commands to USB MIDI packets.
- */
-static void snd_usbmidi_transmit_byte(struct usbmidi_out_port* port,
- uint8_t b, struct urb* urb)
-{
- uint8_t p0 = port->cable;
- void (*output_packet)(struct urb*, uint8_t, uint8_t, uint8_t, uint8_t) =
- port->ep->umidi->usb_protocol_ops->output_packet;
-
- if (b >= 0xf8) {
- output_packet(urb, p0 | 0x0f, b, 0, 0);
- } else if (b >= 0xf0) {
- switch (b) {
- case 0xf0:
- port->data[0] = b;
- port->state = STATE_SYSEX_1;
- break;
- case 0xf1:
- case 0xf3:
- port->data[0] = b;
- port->state = STATE_1PARAM;
- break;
- case 0xf2:
- port->data[0] = b;
- port->state = STATE_2PARAM_1;
- break;
- case 0xf4:
- case 0xf5:
- port->state = STATE_UNKNOWN;
- break;
- case 0xf6:
- output_packet(urb, p0 | 0x05, 0xf6, 0, 0);
- port->state = STATE_UNKNOWN;
- break;
- case 0xf7:
- switch (port->state) {
- case STATE_SYSEX_0:
- output_packet(urb, p0 | 0x05, 0xf7, 0, 0);
- break;
- case STATE_SYSEX_1:
- output_packet(urb, p0 | 0x06, port->data[0], 0xf7, 0);
- break;
- case STATE_SYSEX_2:
- output_packet(urb, p0 | 0x07, port->data[0], port->data[1], 0xf7);
- break;
- }
- port->state = STATE_UNKNOWN;
- break;
- }
- } else if (b >= 0x80) {
- port->data[0] = b;
- if (b >= 0xc0 && b <= 0xdf)
- port->state = STATE_1PARAM;
- else
- port->state = STATE_2PARAM_1;
- } else { /* b < 0x80 */
- switch (port->state) {
- case STATE_1PARAM:
- if (port->data[0] < 0xf0) {
- p0 |= port->data[0] >> 4;
- } else {
- p0 |= 0x02;
- port->state = STATE_UNKNOWN;
- }
- output_packet(urb, p0, port->data[0], b, 0);
- break;
- case STATE_2PARAM_1:
- port->data[1] = b;
- port->state = STATE_2PARAM_2;
- break;
- case STATE_2PARAM_2:
- if (port->data[0] < 0xf0) {
- p0 |= port->data[0] >> 4;
- port->state = STATE_2PARAM_1;
- } else {
- p0 |= 0x03;
- port->state = STATE_UNKNOWN;
- }
- output_packet(urb, p0, port->data[0], port->data[1], b);
- break;
- case STATE_SYSEX_0:
- port->data[0] = b;
- port->state = STATE_SYSEX_1;
- break;
- case STATE_SYSEX_1:
- port->data[1] = b;
- port->state = STATE_SYSEX_2;
- break;
- case STATE_SYSEX_2:
- output_packet(urb, p0 | 0x04, port->data[0], port->data[1], b);
- port->state = STATE_SYSEX_0;
- break;
- }
- }
-}
-
-static void snd_usbmidi_standard_output(struct snd_usb_midi_out_endpoint* ep,
- struct urb *urb)
-{
- int p;
-
- /* FIXME: lower-numbered ports can starve higher-numbered ports */
- for (p = 0; p < 0x10; ++p) {
- struct usbmidi_out_port* port = &ep->ports[p];
- if (!port->active)
- continue;
- while (urb->transfer_buffer_length + 3 < ep->max_transfer) {
- uint8_t b;
- if (snd_rawmidi_transmit(port->substream, &b, 1) != 1) {
- port->active = 0;
- break;
- }
- snd_usbmidi_transmit_byte(port, b, urb);
- }
- }
-}
-
-static struct usb_protocol_ops snd_usbmidi_standard_ops = {
- .input = snd_usbmidi_standard_input,
- .output = snd_usbmidi_standard_output,
- .output_packet = snd_usbmidi_output_standard_packet,
-};
-
-static struct usb_protocol_ops snd_usbmidi_midiman_ops = {
- .input = snd_usbmidi_midiman_input,
- .output = snd_usbmidi_standard_output,
- .output_packet = snd_usbmidi_output_midiman_packet,
-};
-
-static struct usb_protocol_ops snd_usbmidi_maudio_broken_running_status_ops = {
- .input = snd_usbmidi_maudio_broken_running_status_input,
- .output = snd_usbmidi_standard_output,
- .output_packet = snd_usbmidi_output_standard_packet,
-};
-
-static struct usb_protocol_ops snd_usbmidi_cme_ops = {
- .input = snd_usbmidi_cme_input,
- .output = snd_usbmidi_standard_output,
- .output_packet = snd_usbmidi_output_standard_packet,
-};
-
-/*
- * AKAI MPD16 protocol:
- *
- * For control port (endpoint 1):
- * ==============================
- * One or more chunks consisting of first byte of (0x10 | msg_len) and then a
- * SysEx message (msg_len=9 bytes long).
- *
- * For data port (endpoint 2):
- * ===========================
- * One or more chunks consisting of first byte of (0x20 | msg_len) and then a
- * MIDI message (msg_len bytes long)
- *
- * Messages sent: Active Sense, Note On, Poly Pressure, Control Change.
- */
-static void snd_usbmidi_akai_input(struct snd_usb_midi_in_endpoint *ep,
- uint8_t *buffer, int buffer_length)
-{
- unsigned int pos = 0;
- unsigned int len = (unsigned int)buffer_length;
- while (pos < len) {
- unsigned int port = (buffer[pos] >> 4) - 1;
- unsigned int msg_len = buffer[pos] & 0x0f;
- pos++;
- if (pos + msg_len <= len && port < 2)
- snd_usbmidi_input_data(ep, 0, &buffer[pos], msg_len);
- pos += msg_len;
- }
-}
-
-#define MAX_AKAI_SYSEX_LEN 9
-
-static void snd_usbmidi_akai_output(struct snd_usb_midi_out_endpoint *ep,
- struct urb *urb)
-{
- uint8_t *msg;
- int pos, end, count, buf_end;
- uint8_t tmp[MAX_AKAI_SYSEX_LEN];
- struct snd_rawmidi_substream *substream = ep->ports[0].substream;
-
- if (!ep->ports[0].active)
- return;
-
- msg = urb->transfer_buffer + urb->transfer_buffer_length;
- buf_end = ep->max_transfer - MAX_AKAI_SYSEX_LEN - 1;
-
- /* only try adding more data when there's space for at least 1 SysEx */
- while (urb->transfer_buffer_length < buf_end) {
- count = snd_rawmidi_transmit_peek(substream,
- tmp, MAX_AKAI_SYSEX_LEN);
- if (!count) {
- ep->ports[0].active = 0;
- return;
- }
- /* try to skip non-SysEx data */
- for (pos = 0; pos < count && tmp[pos] != 0xF0; pos++)
- ;
-
- if (pos > 0) {
- snd_rawmidi_transmit_ack(substream, pos);
- continue;
- }
-
- /* look for the start or end marker */
- for (end = 1; end < count && tmp[end] < 0xF0; end++)
- ;
-
- /* next SysEx started before the end of current one */
- if (end < count && tmp[end] == 0xF0) {
- /* it's incomplete - drop it */
- snd_rawmidi_transmit_ack(substream, end);
- continue;
- }
- /* SysEx complete */
- if (end < count && tmp[end] == 0xF7) {
- /* queue it, ack it, and get the next one */
- count = end + 1;
- msg[0] = 0x10 | count;
- memcpy(&msg[1], tmp, count);
- snd_rawmidi_transmit_ack(substream, count);
- urb->transfer_buffer_length += count + 1;
- msg += count + 1;
- continue;
- }
- /* less than 9 bytes and no end byte - wait for more */
- if (count < MAX_AKAI_SYSEX_LEN) {
- ep->ports[0].active = 0;
- return;
- }
- /* 9 bytes and no end marker in sight - malformed, skip it */
- snd_rawmidi_transmit_ack(substream, count);
- }
-}
-
-static struct usb_protocol_ops snd_usbmidi_akai_ops = {
- .input = snd_usbmidi_akai_input,
- .output = snd_usbmidi_akai_output,
-};
-
-/*
- * Novation USB MIDI protocol: number of data bytes is in the first byte
- * (when receiving) (+1!) or in the second byte (when sending); data begins
- * at the third byte.
- */
-
-static void snd_usbmidi_novation_input(struct snd_usb_midi_in_endpoint* ep,
- uint8_t* buffer, int buffer_length)
-{
- if (buffer_length < 2 || !buffer[0] || buffer_length < buffer[0] + 1)
- return;
- snd_usbmidi_input_data(ep, 0, &buffer[2], buffer[0] - 1);
-}
-
-static void snd_usbmidi_novation_output(struct snd_usb_midi_out_endpoint* ep,
- struct urb *urb)
-{
- uint8_t* transfer_buffer;
- int count;
-
- if (!ep->ports[0].active)
- return;
- transfer_buffer = urb->transfer_buffer;
- count = snd_rawmidi_transmit(ep->ports[0].substream,
- &transfer_buffer[2],
- ep->max_transfer - 2);
- if (count < 1) {
- ep->ports[0].active = 0;
- return;
- }
- transfer_buffer[0] = 0;
- transfer_buffer[1] = count;
- urb->transfer_buffer_length = 2 + count;
-}
-
-static struct usb_protocol_ops snd_usbmidi_novation_ops = {
- .input = snd_usbmidi_novation_input,
- .output = snd_usbmidi_novation_output,
-};
-
-/*
- * "raw" protocol: just move raw MIDI bytes from/to the endpoint
- */
-
-static void snd_usbmidi_raw_input(struct snd_usb_midi_in_endpoint* ep,
- uint8_t* buffer, int buffer_length)
-{
- snd_usbmidi_input_data(ep, 0, buffer, buffer_length);
-}
-
-static void snd_usbmidi_raw_output(struct snd_usb_midi_out_endpoint* ep,
- struct urb *urb)
-{
- int count;
-
- if (!ep->ports[0].active)
- return;
- count = snd_rawmidi_transmit(ep->ports[0].substream,
- urb->transfer_buffer,
- ep->max_transfer);
- if (count < 1) {
- ep->ports[0].active = 0;
- return;
- }
- urb->transfer_buffer_length = count;
-}
-
-static struct usb_protocol_ops snd_usbmidi_raw_ops = {
- .input = snd_usbmidi_raw_input,
- .output = snd_usbmidi_raw_output,
-};
-
-/*
- * FTDI protocol: raw MIDI bytes, but input packets have two modem status bytes.
- */
-
-static void snd_usbmidi_ftdi_input(struct snd_usb_midi_in_endpoint* ep,
- uint8_t* buffer, int buffer_length)
-{
- if (buffer_length > 2)
- snd_usbmidi_input_data(ep, 0, buffer + 2, buffer_length - 2);
-}
-
-static struct usb_protocol_ops snd_usbmidi_ftdi_ops = {
- .input = snd_usbmidi_ftdi_input,
- .output = snd_usbmidi_raw_output,
-};
-
-static void snd_usbmidi_us122l_input(struct snd_usb_midi_in_endpoint *ep,
- uint8_t *buffer, int buffer_length)
-{
- if (buffer_length != 9)
- return;
- buffer_length = 8;
- while (buffer_length && buffer[buffer_length - 1] == 0xFD)
- buffer_length--;
- if (buffer_length)
- snd_usbmidi_input_data(ep, 0, buffer, buffer_length);
-}
-
-static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep,
- struct urb *urb)
-{
- int count;
-
- if (!ep->ports[0].active)
- return;
- switch (snd_usb_get_speed(ep->umidi->dev)) {
- case USB_SPEED_HIGH:
- case USB_SPEED_SUPER:
- count = 1;
- break;
- default:
- count = 2;
- }
- count = snd_rawmidi_transmit(ep->ports[0].substream,
- urb->transfer_buffer,
- count);
- if (count < 1) {
- ep->ports[0].active = 0;
- return;
- }
-
- memset(urb->transfer_buffer + count, 0xFD, ep->max_transfer - count);
- urb->transfer_buffer_length = ep->max_transfer;
-}
-
-static struct usb_protocol_ops snd_usbmidi_122l_ops = {
- .input = snd_usbmidi_us122l_input,
- .output = snd_usbmidi_us122l_output,
-};
-
-/*
- * Emagic USB MIDI protocol: raw MIDI with "F5 xx" port switching.
- */
-
-static void snd_usbmidi_emagic_init_out(struct snd_usb_midi_out_endpoint* ep)
-{
- static const u8 init_data[] = {
- /* initialization magic: "get version" */
- 0xf0,
- 0x00, 0x20, 0x31, /* Emagic */
- 0x64, /* Unitor8 */
- 0x0b, /* version number request */
- 0x00, /* command version */
- 0x00, /* EEPROM, box 0 */
- 0xf7
- };
- send_bulk_static_data(ep, init_data, sizeof(init_data));
- /* while we're at it, pour on more magic */
- send_bulk_static_data(ep, init_data, sizeof(init_data));
-}
-
-static void snd_usbmidi_emagic_finish_out(struct snd_usb_midi_out_endpoint* ep)
-{
- static const u8 finish_data[] = {
- /* switch to patch mode with last preset */
- 0xf0,
- 0x00, 0x20, 0x31, /* Emagic */
- 0x64, /* Unitor8 */
- 0x10, /* patch switch command */
- 0x00, /* command version */
- 0x7f, /* to all boxes */
- 0x40, /* last preset in EEPROM */
- 0xf7
- };
- send_bulk_static_data(ep, finish_data, sizeof(finish_data));
-}
-
-static void snd_usbmidi_emagic_input(struct snd_usb_midi_in_endpoint* ep,
- uint8_t* buffer, int buffer_length)
-{
- int i;
-
- /* FF indicates end of valid data */
- for (i = 0; i < buffer_length; ++i)
- if (buffer[i] == 0xff) {
- buffer_length = i;
- break;
- }
-
- /* handle F5 at end of last buffer */
- if (ep->seen_f5)
- goto switch_port;
-
- while (buffer_length > 0) {
- /* determine size of data until next F5 */
- for (i = 0; i < buffer_length; ++i)
- if (buffer[i] == 0xf5)
- break;
- snd_usbmidi_input_data(ep, ep->current_port, buffer, i);
- buffer += i;
- buffer_length -= i;
-
- if (buffer_length <= 0)
- break;
- /* assert(buffer[0] == 0xf5); */
- ep->seen_f5 = 1;
- ++buffer;
- --buffer_length;
-
- switch_port:
- if (buffer_length <= 0)
- break;
- if (buffer[0] < 0x80) {
- ep->current_port = (buffer[0] - 1) & 15;
- ++buffer;
- --buffer_length;
- }
- ep->seen_f5 = 0;
- }
-}
-
-static void snd_usbmidi_emagic_output(struct snd_usb_midi_out_endpoint* ep,
- struct urb *urb)
-{
- int port0 = ep->current_port;
- uint8_t* buf = urb->transfer_buffer;
- int buf_free = ep->max_transfer;
- int length, i;
-
- for (i = 0; i < 0x10; ++i) {
- /* round-robin, starting at the last current port */
- int portnum = (port0 + i) & 15;
- struct usbmidi_out_port* port = &ep->ports[portnum];
-
- if (!port->active)
- continue;
- if (snd_rawmidi_transmit_peek(port->substream, buf, 1) != 1) {
- port->active = 0;
- continue;
- }
-
- if (portnum != ep->current_port) {
- if (buf_free < 2)
- break;
- ep->current_port = portnum;
- buf[0] = 0xf5;
- buf[1] = (portnum + 1) & 15;
- buf += 2;
- buf_free -= 2;
- }
-
- if (buf_free < 1)
- break;
- length = snd_rawmidi_transmit(port->substream, buf, buf_free);
- if (length > 0) {
- buf += length;
- buf_free -= length;
- if (buf_free < 1)
- break;
- }
- }
- if (buf_free < ep->max_transfer && buf_free > 0) {
- *buf = 0xff;
- --buf_free;
- }
- urb->transfer_buffer_length = ep->max_transfer - buf_free;
-}
-
-static struct usb_protocol_ops snd_usbmidi_emagic_ops = {
- .input = snd_usbmidi_emagic_input,
- .output = snd_usbmidi_emagic_output,
- .init_out_endpoint = snd_usbmidi_emagic_init_out,
- .finish_out_endpoint = snd_usbmidi_emagic_finish_out,
-};
-
-
-static void update_roland_altsetting(struct snd_usb_midi* umidi)
-{
- struct usb_interface *intf;
- struct usb_host_interface *hostif;
- struct usb_interface_descriptor *intfd;
- int is_light_load;
-
- intf = umidi->iface;
- is_light_load = intf->cur_altsetting != intf->altsetting;
- if (umidi->roland_load_ctl->private_value == is_light_load)
- return;
- hostif = &intf->altsetting[umidi->roland_load_ctl->private_value];
- intfd = get_iface_desc(hostif);
- snd_usbmidi_input_stop(&umidi->list);
- usb_set_interface(umidi->dev, intfd->bInterfaceNumber,
- intfd->bAlternateSetting);
- snd_usbmidi_input_start(&umidi->list);
-}
-
-static void substream_open(struct snd_rawmidi_substream *substream, int open)
-{
- struct snd_usb_midi* umidi = substream->rmidi->private_data;
- struct snd_kcontrol *ctl;
-
- mutex_lock(&umidi->mutex);
- if (open) {
- if (umidi->opened++ == 0 && umidi->roland_load_ctl) {
- ctl = umidi->roland_load_ctl;
- ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(umidi->card,
- SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
- update_roland_altsetting(umidi);
- }
- } else {
- if (--umidi->opened == 0 && umidi->roland_load_ctl) {
- ctl = umidi->roland_load_ctl;
- ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(umidi->card,
- SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
- }
- }
- mutex_unlock(&umidi->mutex);
-}
-
-static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
-{
- struct snd_usb_midi* umidi = substream->rmidi->private_data;
- struct usbmidi_out_port* port = NULL;
- int i, j;
- int err;
-
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
- if (umidi->endpoints[i].out)
- for (j = 0; j < 0x10; ++j)
- if (umidi->endpoints[i].out->ports[j].substream == substream) {
- port = &umidi->endpoints[i].out->ports[j];
- break;
- }
- if (!port) {
- snd_BUG();
- return -ENXIO;
- }
- err = usb_autopm_get_interface(umidi->iface);
- if (err < 0)
- return -EIO;
- substream->runtime->private_data = port;
- port->state = STATE_UNKNOWN;
- substream_open(substream, 1);
- return 0;
-}
-
-static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream)
-{
- struct snd_usb_midi* umidi = substream->rmidi->private_data;
-
- substream_open(substream, 0);
- usb_autopm_put_interface(umidi->iface);
- return 0;
-}
-
-static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct usbmidi_out_port* port = (struct usbmidi_out_port*)substream->runtime->private_data;
-
- port->active = up;
- if (up) {
- if (port->ep->umidi->disconnected) {
- /* gobble up remaining bytes to prevent wait in
- * snd_rawmidi_drain_output */
- while (!snd_rawmidi_transmit_empty(substream))
- snd_rawmidi_transmit_ack(substream, 1);
- return;
- }
- tasklet_schedule(&port->ep->tasklet);
- }
-}
-
-static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream)
-{
- struct usbmidi_out_port* port = substream->runtime->private_data;
- struct snd_usb_midi_out_endpoint *ep = port->ep;
- unsigned int drain_urbs;
- DEFINE_WAIT(wait);
- long timeout = msecs_to_jiffies(50);
-
- if (ep->umidi->disconnected)
- return;
- /*
- * The substream buffer is empty, but some data might still be in the
- * currently active URBs, so we have to wait for those to complete.
- */
- spin_lock_irq(&ep->buffer_lock);
- drain_urbs = ep->active_urbs;
- if (drain_urbs) {
- ep->drain_urbs |= drain_urbs;
- do {
- prepare_to_wait(&ep->drain_wait, &wait,
- TASK_UNINTERRUPTIBLE);
- spin_unlock_irq(&ep->buffer_lock);
- timeout = schedule_timeout(timeout);
- spin_lock_irq(&ep->buffer_lock);
- drain_urbs &= ep->drain_urbs;
- } while (drain_urbs && timeout);
- finish_wait(&ep->drain_wait, &wait);
- }
- spin_unlock_irq(&ep->buffer_lock);
-}
-
-static int snd_usbmidi_input_open(struct snd_rawmidi_substream *substream)
-{
- substream_open(substream, 1);
- return 0;
-}
-
-static int snd_usbmidi_input_close(struct snd_rawmidi_substream *substream)
-{
- substream_open(substream, 0);
- return 0;
-}
-
-static void snd_usbmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct snd_usb_midi* umidi = substream->rmidi->private_data;
-
- if (up)
- set_bit(substream->number, &umidi->input_triggered);
- else
- clear_bit(substream->number, &umidi->input_triggered);
-}
-
-static struct snd_rawmidi_ops snd_usbmidi_output_ops = {
- .open = snd_usbmidi_output_open,
- .close = snd_usbmidi_output_close,
- .trigger = snd_usbmidi_output_trigger,
- .drain = snd_usbmidi_output_drain,
-};
-
-static struct snd_rawmidi_ops snd_usbmidi_input_ops = {
- .open = snd_usbmidi_input_open,
- .close = snd_usbmidi_input_close,
- .trigger = snd_usbmidi_input_trigger
-};
-
-static void free_urb_and_buffer(struct snd_usb_midi *umidi, struct urb *urb,
- unsigned int buffer_length)
-{
- usb_free_coherent(umidi->dev, buffer_length,
- urb->transfer_buffer, urb->transfer_dma);
- usb_free_urb(urb);
-}
-
-/*
- * Frees an input endpoint.
- * May be called when ep hasn't been initialized completely.
- */
-static void snd_usbmidi_in_endpoint_delete(struct snd_usb_midi_in_endpoint* ep)
-{
- unsigned int i;
-
- for (i = 0; i < INPUT_URBS; ++i)
- if (ep->urbs[i])
- free_urb_and_buffer(ep->umidi, ep->urbs[i],
- ep->urbs[i]->transfer_buffer_length);
- kfree(ep);
-}
-
-/*
- * Creates an input endpoint.
- */
-static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
- struct snd_usb_midi_endpoint_info* ep_info,
- struct snd_usb_midi_endpoint* rep)
-{
- struct snd_usb_midi_in_endpoint* ep;
- void* buffer;
- unsigned int pipe;
- int length;
- unsigned int i;
-
- rep->in = NULL;
- ep = kzalloc(sizeof(*ep), GFP_KERNEL);
- if (!ep)
- return -ENOMEM;
- ep->umidi = umidi;
-
- for (i = 0; i < INPUT_URBS; ++i) {
- ep->urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
- if (!ep->urbs[i]) {
- snd_usbmidi_in_endpoint_delete(ep);
- return -ENOMEM;
- }
- }
- if (ep_info->in_interval)
- pipe = usb_rcvintpipe(umidi->dev, ep_info->in_ep);
- else
- pipe = usb_rcvbulkpipe(umidi->dev, ep_info->in_ep);
- length = usb_maxpacket(umidi->dev, pipe, 0);
- for (i = 0; i < INPUT_URBS; ++i) {
- buffer = usb_alloc_coherent(umidi->dev, length, GFP_KERNEL,
- &ep->urbs[i]->transfer_dma);
- if (!buffer) {
- snd_usbmidi_in_endpoint_delete(ep);
- return -ENOMEM;
- }
- if (ep_info->in_interval)
- usb_fill_int_urb(ep->urbs[i], umidi->dev,
- pipe, buffer, length,
- snd_usbmidi_in_urb_complete,
- ep, ep_info->in_interval);
- else
- usb_fill_bulk_urb(ep->urbs[i], umidi->dev,
- pipe, buffer, length,
- snd_usbmidi_in_urb_complete, ep);
- ep->urbs[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
- }
-
- rep->in = ep;
- return 0;
-}
-
-/*
- * Frees an output endpoint.
- * May be called when ep hasn't been initialized completely.
- */
-static void snd_usbmidi_out_endpoint_clear(struct snd_usb_midi_out_endpoint *ep)
-{
- unsigned int i;
-
- for (i = 0; i < OUTPUT_URBS; ++i)
- if (ep->urbs[i].urb) {
- free_urb_and_buffer(ep->umidi, ep->urbs[i].urb,
- ep->max_transfer);
- ep->urbs[i].urb = NULL;
- }
-}
-
-static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep)
-{
- snd_usbmidi_out_endpoint_clear(ep);
- kfree(ep);
-}
-
-/*
- * Creates an output endpoint, and initializes output ports.
- */
-static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
- struct snd_usb_midi_endpoint_info* ep_info,
- struct snd_usb_midi_endpoint* rep)
-{
- struct snd_usb_midi_out_endpoint* ep;
- unsigned int i;
- unsigned int pipe;
- void* buffer;
-
- rep->out = NULL;
- ep = kzalloc(sizeof(*ep), GFP_KERNEL);
- if (!ep)
- return -ENOMEM;
- ep->umidi = umidi;
-
- for (i = 0; i < OUTPUT_URBS; ++i) {
- ep->urbs[i].urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!ep->urbs[i].urb) {
- snd_usbmidi_out_endpoint_delete(ep);
- return -ENOMEM;
- }
- ep->urbs[i].ep = ep;
- }
- if (ep_info->out_interval)
- pipe = usb_sndintpipe(umidi->dev, ep_info->out_ep);
- else
- pipe = usb_sndbulkpipe(umidi->dev, ep_info->out_ep);
- switch (umidi->usb_id) {
- default:
- ep->max_transfer = usb_maxpacket(umidi->dev, pipe, 1);
- break;
- /*
- * Various chips declare a packet size larger than 4 bytes, but
- * do not actually work with larger packets:
- */
- case USB_ID(0x0a92, 0x1020): /* ESI M4U */
- case USB_ID(0x1430, 0x474b): /* RedOctane GH MIDI INTERFACE */
- case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */
- case USB_ID(0x15ca, 0x1806): /* Textech USB Midi Cable */
- case USB_ID(0x1a86, 0x752d): /* QinHeng CH345 "USB2.0-MIDI" */
- case USB_ID(0xfc08, 0x0101): /* Unknown vendor Cable */
- ep->max_transfer = 4;
- break;
- /*
- * Some devices only work with 9 bytes packet size:
- */
- case USB_ID(0x0644, 0x800E): /* Tascam US-122L */
- case USB_ID(0x0644, 0x800F): /* Tascam US-144 */
- ep->max_transfer = 9;
- break;
- }
- for (i = 0; i < OUTPUT_URBS; ++i) {
- buffer = usb_alloc_coherent(umidi->dev,
- ep->max_transfer, GFP_KERNEL,
- &ep->urbs[i].urb->transfer_dma);
- if (!buffer) {
- snd_usbmidi_out_endpoint_delete(ep);
- return -ENOMEM;
- }
- if (ep_info->out_interval)
- usb_fill_int_urb(ep->urbs[i].urb, umidi->dev,
- pipe, buffer, ep->max_transfer,
- snd_usbmidi_out_urb_complete,
- &ep->urbs[i], ep_info->out_interval);
- else
- usb_fill_bulk_urb(ep->urbs[i].urb, umidi->dev,
- pipe, buffer, ep->max_transfer,
- snd_usbmidi_out_urb_complete,
- &ep->urbs[i]);
- ep->urbs[i].urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
- }
-
- spin_lock_init(&ep->buffer_lock);
- tasklet_init(&ep->tasklet, snd_usbmidi_out_tasklet, (unsigned long)ep);
- init_waitqueue_head(&ep->drain_wait);
-
- for (i = 0; i < 0x10; ++i)
- if (ep_info->out_cables & (1 << i)) {
- ep->ports[i].ep = ep;
- ep->ports[i].cable = i << 4;
- }
-
- if (umidi->usb_protocol_ops->init_out_endpoint)
- umidi->usb_protocol_ops->init_out_endpoint(ep);
-
- rep->out = ep;
- return 0;
-}
-
-/*
- * Frees everything.
- */
-static void snd_usbmidi_free(struct snd_usb_midi* umidi)
-{
- int i;
-
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
- struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i];
- if (ep->out)
- snd_usbmidi_out_endpoint_delete(ep->out);
- if (ep->in)
- snd_usbmidi_in_endpoint_delete(ep->in);
- }
- mutex_destroy(&umidi->mutex);
- kfree(umidi);
-}
-
-/*
- * Unlinks all URBs (must be done before the usb_device is deleted).
- */
-void snd_usbmidi_disconnect(struct list_head* p)
-{
- struct snd_usb_midi* umidi;
- unsigned int i, j;
-
- umidi = list_entry(p, struct snd_usb_midi, list);
- /*
- * an URB's completion handler may start the timer and
- * a timer may submit an URB. To reliably break the cycle
- * a flag under lock must be used
- */
- spin_lock_irq(&umidi->disc_lock);
- umidi->disconnected = 1;
- spin_unlock_irq(&umidi->disc_lock);
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
- struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i];
- if (ep->out)
- tasklet_kill(&ep->out->tasklet);
- if (ep->out) {
- for (j = 0; j < OUTPUT_URBS; ++j)
- usb_kill_urb(ep->out->urbs[j].urb);
- if (umidi->usb_protocol_ops->finish_out_endpoint)
- umidi->usb_protocol_ops->finish_out_endpoint(ep->out);
- ep->out->active_urbs = 0;
- if (ep->out->drain_urbs) {
- ep->out->drain_urbs = 0;
- wake_up(&ep->out->drain_wait);
- }
- }
- if (ep->in)
- for (j = 0; j < INPUT_URBS; ++j)
- usb_kill_urb(ep->in->urbs[j]);
- /* free endpoints here; later call can result in Oops */
- if (ep->out)
- snd_usbmidi_out_endpoint_clear(ep->out);
- if (ep->in) {
- snd_usbmidi_in_endpoint_delete(ep->in);
- ep->in = NULL;
- }
- }
- del_timer_sync(&umidi->error_timer);
-}
-
-static void snd_usbmidi_rawmidi_free(struct snd_rawmidi *rmidi)
-{
- struct snd_usb_midi* umidi = rmidi->private_data;
- snd_usbmidi_free(umidi);
-}
-
-static struct snd_rawmidi_substream *snd_usbmidi_find_substream(struct snd_usb_midi* umidi,
- int stream, int number)
-{
- struct list_head* list;
-
- list_for_each(list, &umidi->rmidi->streams[stream].substreams) {
- struct snd_rawmidi_substream *substream = list_entry(list, struct snd_rawmidi_substream, list);
- if (substream->number == number)
- return substream;
- }
- return NULL;
-}
-
-/*
- * This list specifies names for ports that do not fit into the standard
- * "(product) MIDI (n)" schema because they aren't external MIDI ports,
- * such as internal control or synthesizer ports.
- */
-static struct port_info {
- u32 id;
- short int port;
- short int voices;
- const char *name;
- unsigned int seq_flags;
-} snd_usbmidi_port_info[] = {
-#define PORT_INFO(vendor, product, num, name_, voices_, flags) \
- { .id = USB_ID(vendor, product), \
- .port = num, .voices = voices_, \
- .name = name_, .seq_flags = flags }
-#define EXTERNAL_PORT(vendor, product, num, name) \
- PORT_INFO(vendor, product, num, name, 0, \
- SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | \
- SNDRV_SEQ_PORT_TYPE_HARDWARE | \
- SNDRV_SEQ_PORT_TYPE_PORT)
-#define CONTROL_PORT(vendor, product, num, name) \
- PORT_INFO(vendor, product, num, name, 0, \
- SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | \
- SNDRV_SEQ_PORT_TYPE_HARDWARE)
-#define ROLAND_SYNTH_PORT(vendor, product, num, name, voices) \
- PORT_INFO(vendor, product, num, name, voices, \
- SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | \
- SNDRV_SEQ_PORT_TYPE_MIDI_GM | \
- SNDRV_SEQ_PORT_TYPE_MIDI_GM2 | \
- SNDRV_SEQ_PORT_TYPE_MIDI_GS | \
- SNDRV_SEQ_PORT_TYPE_MIDI_XG | \
- SNDRV_SEQ_PORT_TYPE_HARDWARE | \
- SNDRV_SEQ_PORT_TYPE_SYNTHESIZER)
-#define SOUNDCANVAS_PORT(vendor, product, num, name, voices) \
- PORT_INFO(vendor, product, num, name, voices, \
- SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | \
- SNDRV_SEQ_PORT_TYPE_MIDI_GM | \
- SNDRV_SEQ_PORT_TYPE_MIDI_GM2 | \
- SNDRV_SEQ_PORT_TYPE_MIDI_GS | \
- SNDRV_SEQ_PORT_TYPE_MIDI_XG | \
- SNDRV_SEQ_PORT_TYPE_MIDI_MT32 | \
- SNDRV_SEQ_PORT_TYPE_HARDWARE | \
- SNDRV_SEQ_PORT_TYPE_SYNTHESIZER)
- /* Roland UA-100 */
- CONTROL_PORT(0x0582, 0x0000, 2, "%s Control"),
- /* Roland SC-8850 */
- SOUNDCANVAS_PORT(0x0582, 0x0003, 0, "%s Part A", 128),
- SOUNDCANVAS_PORT(0x0582, 0x0003, 1, "%s Part B", 128),
- SOUNDCANVAS_PORT(0x0582, 0x0003, 2, "%s Part C", 128),
- SOUNDCANVAS_PORT(0x0582, 0x0003, 3, "%s Part D", 128),
- EXTERNAL_PORT(0x0582, 0x0003, 4, "%s MIDI 1"),
- EXTERNAL_PORT(0x0582, 0x0003, 5, "%s MIDI 2"),
- /* Roland U-8 */
- EXTERNAL_PORT(0x0582, 0x0004, 0, "%s MIDI"),
- CONTROL_PORT(0x0582, 0x0004, 1, "%s Control"),
- /* Roland SC-8820 */
- SOUNDCANVAS_PORT(0x0582, 0x0007, 0, "%s Part A", 64),
- SOUNDCANVAS_PORT(0x0582, 0x0007, 1, "%s Part B", 64),
- EXTERNAL_PORT(0x0582, 0x0007, 2, "%s MIDI"),
- /* Roland SK-500 */
- SOUNDCANVAS_PORT(0x0582, 0x000b, 0, "%s Part A", 64),
- SOUNDCANVAS_PORT(0x0582, 0x000b, 1, "%s Part B", 64),
- EXTERNAL_PORT(0x0582, 0x000b, 2, "%s MIDI"),
- /* Roland SC-D70 */
- SOUNDCANVAS_PORT(0x0582, 0x000c, 0, "%s Part A", 64),
- SOUNDCANVAS_PORT(0x0582, 0x000c, 1, "%s Part B", 64),
- EXTERNAL_PORT(0x0582, 0x000c, 2, "%s MIDI"),
- /* Edirol UM-880 */
- CONTROL_PORT(0x0582, 0x0014, 8, "%s Control"),
- /* Edirol SD-90 */
- ROLAND_SYNTH_PORT(0x0582, 0x0016, 0, "%s Part A", 128),
- ROLAND_SYNTH_PORT(0x0582, 0x0016, 1, "%s Part B", 128),
- EXTERNAL_PORT(0x0582, 0x0016, 2, "%s MIDI 1"),
- EXTERNAL_PORT(0x0582, 0x0016, 3, "%s MIDI 2"),
- /* Edirol UM-550 */
- CONTROL_PORT(0x0582, 0x0023, 5, "%s Control"),
- /* Edirol SD-20 */
- ROLAND_SYNTH_PORT(0x0582, 0x0027, 0, "%s Part A", 64),
- ROLAND_SYNTH_PORT(0x0582, 0x0027, 1, "%s Part B", 64),
- EXTERNAL_PORT(0x0582, 0x0027, 2, "%s MIDI"),
- /* Edirol SD-80 */
- ROLAND_SYNTH_PORT(0x0582, 0x0029, 0, "%s Part A", 128),
- ROLAND_SYNTH_PORT(0x0582, 0x0029, 1, "%s Part B", 128),
- EXTERNAL_PORT(0x0582, 0x0029, 2, "%s MIDI 1"),
- EXTERNAL_PORT(0x0582, 0x0029, 3, "%s MIDI 2"),
- /* Edirol UA-700 */
- EXTERNAL_PORT(0x0582, 0x002b, 0, "%s MIDI"),
- CONTROL_PORT(0x0582, 0x002b, 1, "%s Control"),
- /* Roland VariOS */
- EXTERNAL_PORT(0x0582, 0x002f, 0, "%s MIDI"),
- EXTERNAL_PORT(0x0582, 0x002f, 1, "%s External MIDI"),
- EXTERNAL_PORT(0x0582, 0x002f, 2, "%s Sync"),
- /* Edirol PCR */
- EXTERNAL_PORT(0x0582, 0x0033, 0, "%s MIDI"),
- EXTERNAL_PORT(0x0582, 0x0033, 1, "%s 1"),
- EXTERNAL_PORT(0x0582, 0x0033, 2, "%s 2"),
- /* BOSS GS-10 */
- EXTERNAL_PORT(0x0582, 0x003b, 0, "%s MIDI"),
- CONTROL_PORT(0x0582, 0x003b, 1, "%s Control"),
- /* Edirol UA-1000 */
- EXTERNAL_PORT(0x0582, 0x0044, 0, "%s MIDI"),
- CONTROL_PORT(0x0582, 0x0044, 1, "%s Control"),
- /* Edirol UR-80 */
- EXTERNAL_PORT(0x0582, 0x0048, 0, "%s MIDI"),
- EXTERNAL_PORT(0x0582, 0x0048, 1, "%s 1"),
- EXTERNAL_PORT(0x0582, 0x0048, 2, "%s 2"),
- /* Edirol PCR-A */
- EXTERNAL_PORT(0x0582, 0x004d, 0, "%s MIDI"),
- EXTERNAL_PORT(0x0582, 0x004d, 1, "%s 1"),
- EXTERNAL_PORT(0x0582, 0x004d, 2, "%s 2"),
- /* Edirol UM-3EX */
- CONTROL_PORT(0x0582, 0x009a, 3, "%s Control"),
- /* M-Audio MidiSport 8x8 */
- CONTROL_PORT(0x0763, 0x1031, 8, "%s Control"),
- CONTROL_PORT(0x0763, 0x1033, 8, "%s Control"),
- /* MOTU Fastlane */
- EXTERNAL_PORT(0x07fd, 0x0001, 0, "%s MIDI A"),
- EXTERNAL_PORT(0x07fd, 0x0001, 1, "%s MIDI B"),
- /* Emagic Unitor8/AMT8/MT4 */
- EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"),
- EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"),
- EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"),
- /* Akai MPD16 */
- CONTROL_PORT(0x09e8, 0x0062, 0, "%s Control"),
- PORT_INFO(0x09e8, 0x0062, 1, "%s MIDI", 0,
- SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
- SNDRV_SEQ_PORT_TYPE_HARDWARE),
- /* Access Music Virus TI */
- EXTERNAL_PORT(0x133e, 0x0815, 0, "%s MIDI"),
- PORT_INFO(0x133e, 0x0815, 1, "%s Synth", 0,
- SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
- SNDRV_SEQ_PORT_TYPE_HARDWARE |
- SNDRV_SEQ_PORT_TYPE_SYNTHESIZER),
-};
-
-static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(snd_usbmidi_port_info); ++i) {
- if (snd_usbmidi_port_info[i].id == umidi->usb_id &&
- snd_usbmidi_port_info[i].port == number)
- return &snd_usbmidi_port_info[i];
- }
- return NULL;
-}
-
-static void snd_usbmidi_get_port_info(struct snd_rawmidi *rmidi, int number,
- struct snd_seq_port_info *seq_port_info)
-{
- struct snd_usb_midi *umidi = rmidi->private_data;
- struct port_info *port_info;
-
- /* TODO: read port flags from descriptors */
- port_info = find_port_info(umidi, number);
- if (port_info) {
- seq_port_info->type = port_info->seq_flags;
- seq_port_info->midi_voices = port_info->voices;
- }
-}
-
-static void snd_usbmidi_init_substream(struct snd_usb_midi* umidi,
- int stream, int number,
- struct snd_rawmidi_substream ** rsubstream)
-{
- struct port_info *port_info;
- const char *name_format;
-
- struct snd_rawmidi_substream *substream = snd_usbmidi_find_substream(umidi, stream, number);
- if (!substream) {
- snd_printd(KERN_ERR "substream %d:%d not found\n", stream, number);
- return;
- }
-
- /* TODO: read port name from jack descriptor */
- port_info = find_port_info(umidi, number);
- name_format = port_info ? port_info->name : "%s MIDI %d";
- snprintf(substream->name, sizeof(substream->name),
- name_format, umidi->card->shortname, number + 1);
-
- *rsubstream = substream;
-}
-
-/*
- * Creates the endpoints and their ports.
- */
-static int snd_usbmidi_create_endpoints(struct snd_usb_midi* umidi,
- struct snd_usb_midi_endpoint_info* endpoints)
-{
- int i, j, err;
- int out_ports = 0, in_ports = 0;
-
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
- if (endpoints[i].out_cables) {
- err = snd_usbmidi_out_endpoint_create(umidi, &endpoints[i],
- &umidi->endpoints[i]);
- if (err < 0)
- return err;
- }
- if (endpoints[i].in_cables) {
- err = snd_usbmidi_in_endpoint_create(umidi, &endpoints[i],
- &umidi->endpoints[i]);
- if (err < 0)
- return err;
- }
-
- for (j = 0; j < 0x10; ++j) {
- if (endpoints[i].out_cables & (1 << j)) {
- snd_usbmidi_init_substream(umidi, SNDRV_RAWMIDI_STREAM_OUTPUT, out_ports,
- &umidi->endpoints[i].out->ports[j].substream);
- ++out_ports;
- }
- if (endpoints[i].in_cables & (1 << j)) {
- snd_usbmidi_init_substream(umidi, SNDRV_RAWMIDI_STREAM_INPUT, in_ports,
- &umidi->endpoints[i].in->ports[j].substream);
- ++in_ports;
- }
- }
- }
- snd_printdd(KERN_INFO "created %d output and %d input ports\n",
- out_ports, in_ports);
- return 0;
-}
-
-/*
- * Returns MIDIStreaming device capabilities.
- */
-static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
- struct snd_usb_midi_endpoint_info* endpoints)
-{
- struct usb_interface* intf;
- struct usb_host_interface *hostif;
- struct usb_interface_descriptor* intfd;
- struct usb_ms_header_descriptor* ms_header;
- struct usb_host_endpoint *hostep;
- struct usb_endpoint_descriptor* ep;
- struct usb_ms_endpoint_descriptor* ms_ep;
- int i, epidx;
-
- intf = umidi->iface;
- if (!intf)
- return -ENXIO;
- hostif = &intf->altsetting[0];
- intfd = get_iface_desc(hostif);
- ms_header = (struct usb_ms_header_descriptor*)hostif->extra;
- if (hostif->extralen >= 7 &&
- ms_header->bLength >= 7 &&
- ms_header->bDescriptorType == USB_DT_CS_INTERFACE &&
- ms_header->bDescriptorSubtype == UAC_HEADER)
- snd_printdd(KERN_INFO "MIDIStreaming version %02x.%02x\n",
- ms_header->bcdMSC[1], ms_header->bcdMSC[0]);
- else
- snd_printk(KERN_WARNING "MIDIStreaming interface descriptor not found\n");
-
- epidx = 0;
- for (i = 0; i < intfd->bNumEndpoints; ++i) {
- hostep = &hostif->endpoint[i];
- ep = get_ep_desc(hostep);
- if (!usb_endpoint_xfer_bulk(ep) && !usb_endpoint_xfer_int(ep))
- continue;
- ms_ep = (struct usb_ms_endpoint_descriptor*)hostep->extra;
- if (hostep->extralen < 4 ||
- ms_ep->bLength < 4 ||
- ms_ep->bDescriptorType != USB_DT_CS_ENDPOINT ||
- ms_ep->bDescriptorSubtype != UAC_MS_GENERAL)
- continue;
- if (usb_endpoint_dir_out(ep)) {
- if (endpoints[epidx].out_ep) {
- if (++epidx >= MIDI_MAX_ENDPOINTS) {
- snd_printk(KERN_WARNING "too many endpoints\n");
- break;
- }
- }
- endpoints[epidx].out_ep = usb_endpoint_num(ep);
- if (usb_endpoint_xfer_int(ep))
- endpoints[epidx].out_interval = ep->bInterval;
- else if (snd_usb_get_speed(umidi->dev) == USB_SPEED_LOW)
- /*
- * Low speed bulk transfers don't exist, so
- * force interrupt transfers for devices like
- * ESI MIDI Mate that try to use them anyway.
- */
- endpoints[epidx].out_interval = 1;
- endpoints[epidx].out_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1;
- snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n",
- ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack);
- } else {
- if (endpoints[epidx].in_ep) {
- if (++epidx >= MIDI_MAX_ENDPOINTS) {
- snd_printk(KERN_WARNING "too many endpoints\n");
- break;
- }
- }
- endpoints[epidx].in_ep = usb_endpoint_num(ep);
- if (usb_endpoint_xfer_int(ep))
- endpoints[epidx].in_interval = ep->bInterval;
- else if (snd_usb_get_speed(umidi->dev) == USB_SPEED_LOW)
- endpoints[epidx].in_interval = 1;
- endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1;
- snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n",
- ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack);
- }
- }
- return 0;
-}
-
-static int roland_load_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *info)
-{
- static const char *const names[] = { "High Load", "Light Load" };
-
- return snd_ctl_enum_info(info, 1, 2, names);
-}
-
-static int roland_load_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- value->value.enumerated.item[0] = kcontrol->private_value;
- return 0;
-}
-
-static int roland_load_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- struct snd_usb_midi* umidi = kcontrol->private_data;
- int changed;
-
- if (value->value.enumerated.item[0] > 1)
- return -EINVAL;
- mutex_lock(&umidi->mutex);
- changed = value->value.enumerated.item[0] != kcontrol->private_value;
- if (changed)
- kcontrol->private_value = value->value.enumerated.item[0];
- mutex_unlock(&umidi->mutex);
- return changed;
-}
-
-static struct snd_kcontrol_new roland_load_ctl = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "MIDI Input Mode",
- .info = roland_load_info,
- .get = roland_load_get,
- .put = roland_load_put,
- .private_value = 1,
-};
-
-/*
- * On Roland devices, use the second alternate setting to be able to use
- * the interrupt input endpoint.
- */
-static void snd_usbmidi_switch_roland_altsetting(struct snd_usb_midi* umidi)
-{
- struct usb_interface* intf;
- struct usb_host_interface *hostif;
- struct usb_interface_descriptor* intfd;
-
- intf = umidi->iface;
- if (!intf || intf->num_altsetting != 2)
- return;
-
- hostif = &intf->altsetting[1];
- intfd = get_iface_desc(hostif);
- if (intfd->bNumEndpoints != 2 ||
- (get_endpoint(hostif, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK ||
- (get_endpoint(hostif, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
- return;
-
- snd_printdd(KERN_INFO "switching to altsetting %d with int ep\n",
- intfd->bAlternateSetting);
- usb_set_interface(umidi->dev, intfd->bInterfaceNumber,
- intfd->bAlternateSetting);
-
- umidi->roland_load_ctl = snd_ctl_new1(&roland_load_ctl, umidi);
- if (snd_ctl_add(umidi->card, umidi->roland_load_ctl) < 0)
- umidi->roland_load_ctl = NULL;
-}
-
-/*
- * Try to find any usable endpoints in the interface.
- */
-static int snd_usbmidi_detect_endpoints(struct snd_usb_midi* umidi,
- struct snd_usb_midi_endpoint_info* endpoint,
- int max_endpoints)
-{
- struct usb_interface* intf;
- struct usb_host_interface *hostif;
- struct usb_interface_descriptor* intfd;
- struct usb_endpoint_descriptor* epd;
- int i, out_eps = 0, in_eps = 0;
-
- if (USB_ID_VENDOR(umidi->usb_id) == 0x0582)
- snd_usbmidi_switch_roland_altsetting(umidi);
-
- if (endpoint[0].out_ep || endpoint[0].in_ep)
- return 0;
-
- intf = umidi->iface;
- if (!intf || intf->num_altsetting < 1)
- return -ENOENT;
- hostif = intf->cur_altsetting;
- intfd = get_iface_desc(hostif);
-
- for (i = 0; i < intfd->bNumEndpoints; ++i) {
- epd = get_endpoint(hostif, i);
- if (!usb_endpoint_xfer_bulk(epd) &&
- !usb_endpoint_xfer_int(epd))
- continue;
- if (out_eps < max_endpoints &&
- usb_endpoint_dir_out(epd)) {
- endpoint[out_eps].out_ep = usb_endpoint_num(epd);
- if (usb_endpoint_xfer_int(epd))
- endpoint[out_eps].out_interval = epd->bInterval;
- ++out_eps;
- }
- if (in_eps < max_endpoints &&
- usb_endpoint_dir_in(epd)) {
- endpoint[in_eps].in_ep = usb_endpoint_num(epd);
- if (usb_endpoint_xfer_int(epd))
- endpoint[in_eps].in_interval = epd->bInterval;
- ++in_eps;
- }
- }
- return (out_eps || in_eps) ? 0 : -ENOENT;
-}
-
-/*
- * Detects the endpoints for one-port-per-endpoint protocols.
- */
-static int snd_usbmidi_detect_per_port_endpoints(struct snd_usb_midi* umidi,
- struct snd_usb_midi_endpoint_info* endpoints)
-{
- int err, i;
-
- err = snd_usbmidi_detect_endpoints(umidi, endpoints, MIDI_MAX_ENDPOINTS);
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
- if (endpoints[i].out_ep)
- endpoints[i].out_cables = 0x0001;
- if (endpoints[i].in_ep)
- endpoints[i].in_cables = 0x0001;
- }
- return err;
-}
-
-/*
- * Detects the endpoints and ports of Yamaha devices.
- */
-static int snd_usbmidi_detect_yamaha(struct snd_usb_midi* umidi,
- struct snd_usb_midi_endpoint_info* endpoint)
-{
- struct usb_interface* intf;
- struct usb_host_interface *hostif;
- struct usb_interface_descriptor* intfd;
- uint8_t* cs_desc;
-
- intf = umidi->iface;
- if (!intf)
- return -ENOENT;
- hostif = intf->altsetting;
- intfd = get_iface_desc(hostif);
- if (intfd->bNumEndpoints < 1)
- return -ENOENT;
-
- /*
- * For each port there is one MIDI_IN/OUT_JACK descriptor, not
- * necessarily with any useful contents. So simply count 'em.
- */
- for (cs_desc = hostif->extra;
- cs_desc < hostif->extra + hostif->extralen && cs_desc[0] >= 2;
- cs_desc += cs_desc[0]) {
- if (cs_desc[1] == USB_DT_CS_INTERFACE) {
- if (cs_desc[2] == UAC_MIDI_IN_JACK)
- endpoint->in_cables = (endpoint->in_cables << 1) | 1;
- else if (cs_desc[2] == UAC_MIDI_OUT_JACK)
- endpoint->out_cables = (endpoint->out_cables << 1) | 1;
- }
- }
- if (!endpoint->in_cables && !endpoint->out_cables)
- return -ENOENT;
-
- return snd_usbmidi_detect_endpoints(umidi, endpoint, 1);
-}
-
-/*
- * Creates the endpoints and their ports for Midiman devices.
- */
-static int snd_usbmidi_create_endpoints_midiman(struct snd_usb_midi* umidi,
- struct snd_usb_midi_endpoint_info* endpoint)
-{
- struct snd_usb_midi_endpoint_info ep_info;
- struct usb_interface* intf;
- struct usb_host_interface *hostif;
- struct usb_interface_descriptor* intfd;
- struct usb_endpoint_descriptor* epd;
- int cable, err;
-
- intf = umidi->iface;
- if (!intf)
- return -ENOENT;
- hostif = intf->altsetting;
- intfd = get_iface_desc(hostif);
- /*
- * The various MidiSport devices have more or less random endpoint
- * numbers, so we have to identify the endpoints by their index in
- * the descriptor array, like the driver for that other OS does.
- *
- * There is one interrupt input endpoint for all input ports, one
- * bulk output endpoint for even-numbered ports, and one for odd-
- * numbered ports. Both bulk output endpoints have corresponding
- * input bulk endpoints (at indices 1 and 3) which aren't used.
- */
- if (intfd->bNumEndpoints < (endpoint->out_cables > 0x0001 ? 5 : 3)) {
- snd_printdd(KERN_ERR "not enough endpoints\n");
- return -ENOENT;
- }
-
- epd = get_endpoint(hostif, 0);
- if (!usb_endpoint_dir_in(epd) || !usb_endpoint_xfer_int(epd)) {
- snd_printdd(KERN_ERR "endpoint[0] isn't interrupt\n");
- return -ENXIO;
- }
- epd = get_endpoint(hostif, 2);
- if (!usb_endpoint_dir_out(epd) || !usb_endpoint_xfer_bulk(epd)) {
- snd_printdd(KERN_ERR "endpoint[2] isn't bulk output\n");
- return -ENXIO;
- }
- if (endpoint->out_cables > 0x0001) {
- epd = get_endpoint(hostif, 4);
- if (!usb_endpoint_dir_out(epd) ||
- !usb_endpoint_xfer_bulk(epd)) {
- snd_printdd(KERN_ERR "endpoint[4] isn't bulk output\n");
- return -ENXIO;
- }
- }
-
- ep_info.out_ep = get_endpoint(hostif, 2)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
- ep_info.out_interval = 0;
- ep_info.out_cables = endpoint->out_cables & 0x5555;
- err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]);
- if (err < 0)
- return err;
-
- ep_info.in_ep = get_endpoint(hostif, 0)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
- ep_info.in_interval = get_endpoint(hostif, 0)->bInterval;
- ep_info.in_cables = endpoint->in_cables;
- err = snd_usbmidi_in_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]);
- if (err < 0)
- return err;
-
- if (endpoint->out_cables > 0x0001) {
- ep_info.out_ep = get_endpoint(hostif, 4)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
- ep_info.out_cables = endpoint->out_cables & 0xaaaa;
- err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[1]);
- if (err < 0)
- return err;
- }
-
- for (cable = 0; cable < 0x10; ++cable) {
- if (endpoint->out_cables & (1 << cable))
- snd_usbmidi_init_substream(umidi, SNDRV_RAWMIDI_STREAM_OUTPUT, cable,
- &umidi->endpoints[cable & 1].out->ports[cable].substream);
- if (endpoint->in_cables & (1 << cable))
- snd_usbmidi_init_substream(umidi, SNDRV_RAWMIDI_STREAM_INPUT, cable,
- &umidi->endpoints[0].in->ports[cable].substream);
- }
- return 0;
-}
-
-static struct snd_rawmidi_global_ops snd_usbmidi_ops = {
- .get_port_info = snd_usbmidi_get_port_info,
-};
-
-static int snd_usbmidi_create_rawmidi(struct snd_usb_midi* umidi,
- int out_ports, int in_ports)
-{
- struct snd_rawmidi *rmidi;
- int err;
-
- err = snd_rawmidi_new(umidi->card, "USB MIDI",
- umidi->next_midi_device++,
- out_ports, in_ports, &rmidi);
- if (err < 0)
- return err;
- strcpy(rmidi->name, umidi->card->shortname);
- rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
- rmidi->ops = &snd_usbmidi_ops;
- rmidi->private_data = umidi;
- rmidi->private_free = snd_usbmidi_rawmidi_free;
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_usbmidi_output_ops);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_usbmidi_input_ops);
-
- umidi->rmidi = rmidi;
- return 0;
-}
-
-/*
- * Temporarily stop input.
- */
-void snd_usbmidi_input_stop(struct list_head* p)
-{
- struct snd_usb_midi* umidi;
- unsigned int i, j;
-
- umidi = list_entry(p, struct snd_usb_midi, list);
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
- struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i];
- if (ep->in)
- for (j = 0; j < INPUT_URBS; ++j)
- usb_kill_urb(ep->in->urbs[j]);
- }
-}
-
-static void snd_usbmidi_input_start_ep(struct snd_usb_midi_in_endpoint* ep)
-{
- unsigned int i;
-
- if (!ep)
- return;
- for (i = 0; i < INPUT_URBS; ++i) {
- struct urb* urb = ep->urbs[i];
- urb->dev = ep->umidi->dev;
- snd_usbmidi_submit_urb(urb, GFP_KERNEL);
- }
-}
-
-/*
- * Resume input after a call to snd_usbmidi_input_stop().
- */
-void snd_usbmidi_input_start(struct list_head* p)
-{
- struct snd_usb_midi* umidi;
- int i;
-
- umidi = list_entry(p, struct snd_usb_midi, list);
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
- snd_usbmidi_input_start_ep(umidi->endpoints[i].in);
-}
-
-/*
- * Creates and registers everything needed for a MIDI streaming interface.
- */
-int snd_usbmidi_create(struct snd_card *card,
- struct usb_interface* iface,
- struct list_head *midi_list,
- const struct snd_usb_audio_quirk* quirk)
-{
- struct snd_usb_midi* umidi;
- struct snd_usb_midi_endpoint_info endpoints[MIDI_MAX_ENDPOINTS];
- int out_ports, in_ports;
- int i, err;
-
- umidi = kzalloc(sizeof(*umidi), GFP_KERNEL);
- if (!umidi)
- return -ENOMEM;
- umidi->dev = interface_to_usbdev(iface);
- umidi->card = card;
- umidi->iface = iface;
- umidi->quirk = quirk;
- umidi->usb_protocol_ops = &snd_usbmidi_standard_ops;
- init_timer(&umidi->error_timer);
- spin_lock_init(&umidi->disc_lock);
- mutex_init(&umidi->mutex);
- umidi->usb_id = USB_ID(le16_to_cpu(umidi->dev->descriptor.idVendor),
- le16_to_cpu(umidi->dev->descriptor.idProduct));
- umidi->error_timer.function = snd_usbmidi_error_timer;
- umidi->error_timer.data = (unsigned long)umidi;
-
- /* detect the endpoint(s) to use */
- memset(endpoints, 0, sizeof(endpoints));
- switch (quirk ? quirk->type : QUIRK_MIDI_STANDARD_INTERFACE) {
- case QUIRK_MIDI_STANDARD_INTERFACE:
- err = snd_usbmidi_get_ms_info(umidi, endpoints);
- if (umidi->usb_id == USB_ID(0x0763, 0x0150)) /* M-Audio Uno */
- umidi->usb_protocol_ops =
- &snd_usbmidi_maudio_broken_running_status_ops;
- break;
- case QUIRK_MIDI_US122L:
- umidi->usb_protocol_ops = &snd_usbmidi_122l_ops;
- /* fall through */
- case QUIRK_MIDI_FIXED_ENDPOINT:
- memcpy(&endpoints[0], quirk->data,
- sizeof(struct snd_usb_midi_endpoint_info));
- err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
- break;
- case QUIRK_MIDI_YAMAHA:
- err = snd_usbmidi_detect_yamaha(umidi, &endpoints[0]);
- break;
- case QUIRK_MIDI_MIDIMAN:
- umidi->usb_protocol_ops = &snd_usbmidi_midiman_ops;
- memcpy(&endpoints[0], quirk->data,
- sizeof(struct snd_usb_midi_endpoint_info));
- err = 0;
- break;
- case QUIRK_MIDI_NOVATION:
- umidi->usb_protocol_ops = &snd_usbmidi_novation_ops;
- err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
- break;
- case QUIRK_MIDI_RAW_BYTES:
- umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
- /*
- * Interface 1 contains isochronous endpoints, but with the same
- * numbers as in interface 0. Since it is interface 1 that the
- * USB core has most recently seen, these descriptors are now
- * associated with the endpoint numbers. This will foul up our
- * attempts to submit bulk/interrupt URBs to the endpoints in
- * interface 0, so we have to make sure that the USB core looks
- * again at interface 0 by calling usb_set_interface() on it.
- */
- if (umidi->usb_id == USB_ID(0x07fd, 0x0001)) /* MOTU Fastlane */
- usb_set_interface(umidi->dev, 0, 0);
- err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
- break;
- case QUIRK_MIDI_EMAGIC:
- umidi->usb_protocol_ops = &snd_usbmidi_emagic_ops;
- memcpy(&endpoints[0], quirk->data,
- sizeof(struct snd_usb_midi_endpoint_info));
- err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
- break;
- case QUIRK_MIDI_CME:
- umidi->usb_protocol_ops = &snd_usbmidi_cme_ops;
- err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
- break;
- case QUIRK_MIDI_AKAI:
- umidi->usb_protocol_ops = &snd_usbmidi_akai_ops;
- err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
- /* endpoint 1 is input-only */
- endpoints[1].out_cables = 0;
- break;
- case QUIRK_MIDI_FTDI:
- umidi->usb_protocol_ops = &snd_usbmidi_ftdi_ops;
-
- /* set baud rate to 31250 (48 MHz / 16 / 96) */
- err = usb_control_msg(umidi->dev, usb_sndctrlpipe(umidi->dev, 0),
- 3, 0x40, 0x60, 0, NULL, 0, 1000);
- if (err < 0)
- break;
-
- err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
- break;
- default:
- snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
- err = -ENXIO;
- break;
- }
- if (err < 0) {
- kfree(umidi);
- return err;
- }
-
- /* create rawmidi device */
- out_ports = 0;
- in_ports = 0;
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
- out_ports += hweight16(endpoints[i].out_cables);
- in_ports += hweight16(endpoints[i].in_cables);
- }
- err = snd_usbmidi_create_rawmidi(umidi, out_ports, in_ports);
- if (err < 0) {
- kfree(umidi);
- return err;
- }
-
- /* create endpoint/port structures */
- if (quirk && quirk->type == QUIRK_MIDI_MIDIMAN)
- err = snd_usbmidi_create_endpoints_midiman(umidi, &endpoints[0]);
- else
- err = snd_usbmidi_create_endpoints(umidi, endpoints);
- if (err < 0) {
- snd_usbmidi_free(umidi);
- return err;
- }
-
- list_add_tail(&umidi->list, midi_list);
-
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
- snd_usbmidi_input_start_ep(umidi->endpoints[i].in);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_usbmidi_create);
-EXPORT_SYMBOL(snd_usbmidi_input_stop);
-EXPORT_SYMBOL(snd_usbmidi_input_start);
-EXPORT_SYMBOL(snd_usbmidi_disconnect);
diff --git a/ANDROID_3.4.5/sound/usb/midi.h b/ANDROID_3.4.5/sound/usb/midi.h
deleted file mode 100644
index 2fca80b7..00000000
--- a/ANDROID_3.4.5/sound/usb/midi.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef __USBMIDI_H
-#define __USBMIDI_H
-
-/* maximum number of endpoints per interface */
-#define MIDI_MAX_ENDPOINTS 2
-
-/* data for QUIRK_MIDI_FIXED_ENDPOINT */
-struct snd_usb_midi_endpoint_info {
- int8_t out_ep; /* ep number, 0 autodetect */
- uint8_t out_interval; /* interval for interrupt endpoints */
- int8_t in_ep;
- uint8_t in_interval;
- uint16_t out_cables; /* bitmask */
- uint16_t in_cables; /* bitmask */
-};
-
-/* for QUIRK_MIDI_YAMAHA, data is NULL */
-
-/* for QUIRK_MIDI_MIDIMAN, data points to a snd_usb_midi_endpoint_info
- * structure (out_cables and in_cables only) */
-
-/* for QUIRK_COMPOSITE, data points to an array of snd_usb_audio_quirk
- * structures, terminated with .ifnum = -1 */
-
-/* for QUIRK_AUDIO_FIXED_ENDPOINT, data points to an audioformat structure */
-
-/* for QUIRK_AUDIO/MIDI_STANDARD_INTERFACE, data is NULL */
-
-/* for QUIRK_AUDIO_EDIROL_UA700_UA25/UA1000, data is NULL */
-
-/* for QUIRK_IGNORE_INTERFACE, data is NULL */
-
-/* for QUIRK_MIDI_NOVATION and _RAW, data is NULL */
-
-/* for QUIRK_MIDI_EMAGIC, data points to a snd_usb_midi_endpoint_info
- * structure (out_cables and in_cables only) */
-
-/* for QUIRK_MIDI_CME, data is NULL */
-
-/* for QUIRK_MIDI_AKAI, data is NULL */
-
-int snd_usbmidi_create(struct snd_card *card,
- struct usb_interface *iface,
- struct list_head *midi_list,
- const struct snd_usb_audio_quirk *quirk);
-void snd_usbmidi_input_stop(struct list_head* p);
-void snd_usbmidi_input_start(struct list_head* p);
-void snd_usbmidi_disconnect(struct list_head *p);
-
-#endif /* __USBMIDI_H */
diff --git a/ANDROID_3.4.5/sound/usb/misc/Makefile b/ANDROID_3.4.5/sound/usb/misc/Makefile
deleted file mode 100644
index ccefd815..00000000
--- a/ANDROID_3.4.5/sound/usb/misc/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-snd-ua101-objs := ua101.o
-obj-$(CONFIG_SND_USB_UA101) += snd-ua101.o
diff --git a/ANDROID_3.4.5/sound/usb/misc/ua101.c b/ANDROID_3.4.5/sound/usb/misc/ua101.c
deleted file mode 100644
index 8b81cb54..00000000
--- a/ANDROID_3.4.5/sound/usb/misc/ua101.c
+++ /dev/null
@@ -1,1390 +0,0 @@
-/*
- * Edirol UA-101/UA-1000 driver
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- *
- * This driver is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this driver. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/usb/audio.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include "../usbaudio.h"
-#include "../midi.h"
-
-MODULE_DESCRIPTION("Edirol UA-101/1000 driver");
-MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
-MODULE_LICENSE("GPL v2");
-MODULE_SUPPORTED_DEVICE("{{Edirol,UA-101},{Edirol,UA-1000}}");
-
-/*
- * Should not be lower than the minimum scheduling delay of the host
- * controller. Some Intel controllers need more than one frame; as long as
- * that driver doesn't tell us about this, use 1.5 frames just to be sure.
- */
-#define MIN_QUEUE_LENGTH 12
-/* Somewhat random. */
-#define MAX_QUEUE_LENGTH 30
-/*
- * This magic value optimizes memory usage efficiency for the UA-101's packet
- * sizes at all sample rates, taking into account the stupid cache pool sizes
- * that usb_alloc_coherent() uses.
- */
-#define DEFAULT_QUEUE_LENGTH 21
-
-#define MAX_PACKET_SIZE 672 /* hardware specific */
-#define MAX_MEMORY_BUFFERS DIV_ROUND_UP(MAX_QUEUE_LENGTH, \
- PAGE_SIZE / MAX_PACKET_SIZE)
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static unsigned int queue_length = 21;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "card index");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "enable card");
-module_param(queue_length, uint, 0644);
-MODULE_PARM_DESC(queue_length, "USB queue length in microframes, "
- __stringify(MIN_QUEUE_LENGTH)"-"__stringify(MAX_QUEUE_LENGTH));
-
-enum {
- INTF_PLAYBACK,
- INTF_CAPTURE,
- INTF_MIDI,
-
- INTF_COUNT
-};
-
-/* bits in struct ua101::states */
-enum {
- USB_CAPTURE_RUNNING,
- USB_PLAYBACK_RUNNING,
- ALSA_CAPTURE_OPEN,
- ALSA_PLAYBACK_OPEN,
- ALSA_CAPTURE_RUNNING,
- ALSA_PLAYBACK_RUNNING,
- CAPTURE_URB_COMPLETED,
- PLAYBACK_URB_COMPLETED,
- DISCONNECTED,
-};
-
-struct ua101 {
- struct usb_device *dev;
- struct snd_card *card;
- struct usb_interface *intf[INTF_COUNT];
- int card_index;
- struct snd_pcm *pcm;
- struct list_head midi_list;
- u64 format_bit;
- unsigned int rate;
- unsigned int packets_per_second;
- spinlock_t lock;
- struct mutex mutex;
- unsigned long states;
-
- /* FIFO to synchronize playback rate to capture rate */
- unsigned int rate_feedback_start;
- unsigned int rate_feedback_count;
- u8 rate_feedback[MAX_QUEUE_LENGTH];
-
- struct list_head ready_playback_urbs;
- struct tasklet_struct playback_tasklet;
- wait_queue_head_t alsa_capture_wait;
- wait_queue_head_t rate_feedback_wait;
- wait_queue_head_t alsa_playback_wait;
- struct ua101_stream {
- struct snd_pcm_substream *substream;
- unsigned int usb_pipe;
- unsigned int channels;
- unsigned int frame_bytes;
- unsigned int max_packet_bytes;
- unsigned int period_pos;
- unsigned int buffer_pos;
- unsigned int queue_length;
- struct ua101_urb {
- struct urb urb;
- struct usb_iso_packet_descriptor iso_frame_desc[1];
- struct list_head ready_list;
- } *urbs[MAX_QUEUE_LENGTH];
- struct {
- unsigned int size;
- void *addr;
- dma_addr_t dma;
- } buffers[MAX_MEMORY_BUFFERS];
- } capture, playback;
-};
-
-static DEFINE_MUTEX(devices_mutex);
-static unsigned int devices_used;
-static struct usb_driver ua101_driver;
-
-static void abort_alsa_playback(struct ua101 *ua);
-static void abort_alsa_capture(struct ua101 *ua);
-
-static const char *usb_error_string(int err)
-{
- switch (err) {
- case -ENODEV:
- return "no device";
- case -ENOENT:
- return "endpoint not enabled";
- case -EPIPE:
- return "endpoint stalled";
- case -ENOSPC:
- return "not enough bandwidth";
- case -ESHUTDOWN:
- return "device disabled";
- case -EHOSTUNREACH:
- return "device suspended";
- case -EINVAL:
- case -EAGAIN:
- case -EFBIG:
- case -EMSGSIZE:
- return "internal error";
- default:
- return "unknown error";
- }
-}
-
-static void abort_usb_capture(struct ua101 *ua)
-{
- if (test_and_clear_bit(USB_CAPTURE_RUNNING, &ua->states)) {
- wake_up(&ua->alsa_capture_wait);
- wake_up(&ua->rate_feedback_wait);
- }
-}
-
-static void abort_usb_playback(struct ua101 *ua)
-{
- if (test_and_clear_bit(USB_PLAYBACK_RUNNING, &ua->states))
- wake_up(&ua->alsa_playback_wait);
-}
-
-static void playback_urb_complete(struct urb *usb_urb)
-{
- struct ua101_urb *urb = (struct ua101_urb *)usb_urb;
- struct ua101 *ua = urb->urb.context;
- unsigned long flags;
-
- if (unlikely(urb->urb.status == -ENOENT || /* unlinked */
- urb->urb.status == -ENODEV || /* device removed */
- urb->urb.status == -ECONNRESET || /* unlinked */
- urb->urb.status == -ESHUTDOWN)) { /* device disabled */
- abort_usb_playback(ua);
- abort_alsa_playback(ua);
- return;
- }
-
- if (test_bit(USB_PLAYBACK_RUNNING, &ua->states)) {
- /* append URB to FIFO */
- spin_lock_irqsave(&ua->lock, flags);
- list_add_tail(&urb->ready_list, &ua->ready_playback_urbs);
- if (ua->rate_feedback_count > 0)
- tasklet_schedule(&ua->playback_tasklet);
- ua->playback.substream->runtime->delay -=
- urb->urb.iso_frame_desc[0].length /
- ua->playback.frame_bytes;
- spin_unlock_irqrestore(&ua->lock, flags);
- }
-}
-
-static void first_playback_urb_complete(struct urb *urb)
-{
- struct ua101 *ua = urb->context;
-
- urb->complete = playback_urb_complete;
- playback_urb_complete(urb);
-
- set_bit(PLAYBACK_URB_COMPLETED, &ua->states);
- wake_up(&ua->alsa_playback_wait);
-}
-
-/* copy data from the ALSA ring buffer into the URB buffer */
-static bool copy_playback_data(struct ua101_stream *stream, struct urb *urb,
- unsigned int frames)
-{
- struct snd_pcm_runtime *runtime;
- unsigned int frame_bytes, frames1;
- const u8 *source;
-
- runtime = stream->substream->runtime;
- frame_bytes = stream->frame_bytes;
- source = runtime->dma_area + stream->buffer_pos * frame_bytes;
- if (stream->buffer_pos + frames <= runtime->buffer_size) {
- memcpy(urb->transfer_buffer, source, frames * frame_bytes);
- } else {
- /* wrap around at end of ring buffer */
- frames1 = runtime->buffer_size - stream->buffer_pos;
- memcpy(urb->transfer_buffer, source, frames1 * frame_bytes);
- memcpy(urb->transfer_buffer + frames1 * frame_bytes,
- runtime->dma_area, (frames - frames1) * frame_bytes);
- }
-
- stream->buffer_pos += frames;
- if (stream->buffer_pos >= runtime->buffer_size)
- stream->buffer_pos -= runtime->buffer_size;
- stream->period_pos += frames;
- if (stream->period_pos >= runtime->period_size) {
- stream->period_pos -= runtime->period_size;
- return true;
- }
- return false;
-}
-
-static inline void add_with_wraparound(struct ua101 *ua,
- unsigned int *value, unsigned int add)
-{
- *value += add;
- if (*value >= ua->playback.queue_length)
- *value -= ua->playback.queue_length;
-}
-
-static void playback_tasklet(unsigned long data)
-{
- struct ua101 *ua = (void *)data;
- unsigned long flags;
- unsigned int frames;
- struct ua101_urb *urb;
- bool do_period_elapsed = false;
- int err;
-
- if (unlikely(!test_bit(USB_PLAYBACK_RUNNING, &ua->states)))
- return;
-
- /*
- * Synchronizing the playback rate to the capture rate is done by using
- * the same sequence of packet sizes for both streams.
- * Submitting a playback URB therefore requires both a ready URB and
- * the size of the corresponding capture packet, i.e., both playback
- * and capture URBs must have been completed. Since the USB core does
- * not guarantee that playback and capture complete callbacks are
- * called alternately, we use two FIFOs for packet sizes and read URBs;
- * submitting playback URBs is possible as long as both FIFOs are
- * nonempty.
- */
- spin_lock_irqsave(&ua->lock, flags);
- while (ua->rate_feedback_count > 0 &&
- !list_empty(&ua->ready_playback_urbs)) {
- /* take packet size out of FIFO */
- frames = ua->rate_feedback[ua->rate_feedback_start];
- add_with_wraparound(ua, &ua->rate_feedback_start, 1);
- ua->rate_feedback_count--;
-
- /* take URB out of FIFO */
- urb = list_first_entry(&ua->ready_playback_urbs,
- struct ua101_urb, ready_list);
- list_del(&urb->ready_list);
-
- /* fill packet with data or silence */
- urb->urb.iso_frame_desc[0].length =
- frames * ua->playback.frame_bytes;
- if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states))
- do_period_elapsed |= copy_playback_data(&ua->playback,
- &urb->urb,
- frames);
- else
- memset(urb->urb.transfer_buffer, 0,
- urb->urb.iso_frame_desc[0].length);
-
- /* and off you go ... */
- err = usb_submit_urb(&urb->urb, GFP_ATOMIC);
- if (unlikely(err < 0)) {
- spin_unlock_irqrestore(&ua->lock, flags);
- abort_usb_playback(ua);
- abort_alsa_playback(ua);
- dev_err(&ua->dev->dev, "USB request error %d: %s\n",
- err, usb_error_string(err));
- return;
- }
- ua->playback.substream->runtime->delay += frames;
- }
- spin_unlock_irqrestore(&ua->lock, flags);
- if (do_period_elapsed)
- snd_pcm_period_elapsed(ua->playback.substream);
-}
-
-/* copy data from the URB buffer into the ALSA ring buffer */
-static bool copy_capture_data(struct ua101_stream *stream, struct urb *urb,
- unsigned int frames)
-{
- struct snd_pcm_runtime *runtime;
- unsigned int frame_bytes, frames1;
- u8 *dest;
-
- runtime = stream->substream->runtime;
- frame_bytes = stream->frame_bytes;
- dest = runtime->dma_area + stream->buffer_pos * frame_bytes;
- if (stream->buffer_pos + frames <= runtime->buffer_size) {
- memcpy(dest, urb->transfer_buffer, frames * frame_bytes);
- } else {
- /* wrap around at end of ring buffer */
- frames1 = runtime->buffer_size - stream->buffer_pos;
- memcpy(dest, urb->transfer_buffer, frames1 * frame_bytes);
- memcpy(runtime->dma_area,
- urb->transfer_buffer + frames1 * frame_bytes,
- (frames - frames1) * frame_bytes);
- }
-
- stream->buffer_pos += frames;
- if (stream->buffer_pos >= runtime->buffer_size)
- stream->buffer_pos -= runtime->buffer_size;
- stream->period_pos += frames;
- if (stream->period_pos >= runtime->period_size) {
- stream->period_pos -= runtime->period_size;
- return true;
- }
- return false;
-}
-
-static void capture_urb_complete(struct urb *urb)
-{
- struct ua101 *ua = urb->context;
- struct ua101_stream *stream = &ua->capture;
- unsigned long flags;
- unsigned int frames, write_ptr;
- bool do_period_elapsed;
- int err;
-
- if (unlikely(urb->status == -ENOENT || /* unlinked */
- urb->status == -ENODEV || /* device removed */
- urb->status == -ECONNRESET || /* unlinked */
- urb->status == -ESHUTDOWN)) /* device disabled */
- goto stream_stopped;
-
- if (urb->status >= 0 && urb->iso_frame_desc[0].status >= 0)
- frames = urb->iso_frame_desc[0].actual_length /
- stream->frame_bytes;
- else
- frames = 0;
-
- spin_lock_irqsave(&ua->lock, flags);
-
- if (frames > 0 && test_bit(ALSA_CAPTURE_RUNNING, &ua->states))
- do_period_elapsed = copy_capture_data(stream, urb, frames);
- else
- do_period_elapsed = false;
-
- if (test_bit(USB_CAPTURE_RUNNING, &ua->states)) {
- err = usb_submit_urb(urb, GFP_ATOMIC);
- if (unlikely(err < 0)) {
- spin_unlock_irqrestore(&ua->lock, flags);
- dev_err(&ua->dev->dev, "USB request error %d: %s\n",
- err, usb_error_string(err));
- goto stream_stopped;
- }
-
- /* append packet size to FIFO */
- write_ptr = ua->rate_feedback_start;
- add_with_wraparound(ua, &write_ptr, ua->rate_feedback_count);
- ua->rate_feedback[write_ptr] = frames;
- if (ua->rate_feedback_count < ua->playback.queue_length) {
- ua->rate_feedback_count++;
- if (ua->rate_feedback_count ==
- ua->playback.queue_length)
- wake_up(&ua->rate_feedback_wait);
- } else {
- /*
- * Ring buffer overflow; this happens when the playback
- * stream is not running. Throw away the oldest entry,
- * so that the playback stream, when it starts, sees
- * the most recent packet sizes.
- */
- add_with_wraparound(ua, &ua->rate_feedback_start, 1);
- }
- if (test_bit(USB_PLAYBACK_RUNNING, &ua->states) &&
- !list_empty(&ua->ready_playback_urbs))
- tasklet_schedule(&ua->playback_tasklet);
- }
-
- spin_unlock_irqrestore(&ua->lock, flags);
-
- if (do_period_elapsed)
- snd_pcm_period_elapsed(stream->substream);
-
- return;
-
-stream_stopped:
- abort_usb_playback(ua);
- abort_usb_capture(ua);
- abort_alsa_playback(ua);
- abort_alsa_capture(ua);
-}
-
-static void first_capture_urb_complete(struct urb *urb)
-{
- struct ua101 *ua = urb->context;
-
- urb->complete = capture_urb_complete;
- capture_urb_complete(urb);
-
- set_bit(CAPTURE_URB_COMPLETED, &ua->states);
- wake_up(&ua->alsa_capture_wait);
-}
-
-static int submit_stream_urbs(struct ua101 *ua, struct ua101_stream *stream)
-{
- unsigned int i;
-
- for (i = 0; i < stream->queue_length; ++i) {
- int err = usb_submit_urb(&stream->urbs[i]->urb, GFP_KERNEL);
- if (err < 0) {
- dev_err(&ua->dev->dev, "USB request error %d: %s\n",
- err, usb_error_string(err));
- return err;
- }
- }
- return 0;
-}
-
-static void kill_stream_urbs(struct ua101_stream *stream)
-{
- unsigned int i;
-
- for (i = 0; i < stream->queue_length; ++i)
- if (stream->urbs[i])
- usb_kill_urb(&stream->urbs[i]->urb);
-}
-
-static int enable_iso_interface(struct ua101 *ua, unsigned int intf_index)
-{
- struct usb_host_interface *alts;
-
- alts = ua->intf[intf_index]->cur_altsetting;
- if (alts->desc.bAlternateSetting != 1) {
- int err = usb_set_interface(ua->dev,
- alts->desc.bInterfaceNumber, 1);
- if (err < 0) {
- dev_err(&ua->dev->dev,
- "cannot initialize interface; error %d: %s\n",
- err, usb_error_string(err));
- return err;
- }
- }
- return 0;
-}
-
-static void disable_iso_interface(struct ua101 *ua, unsigned int intf_index)
-{
- struct usb_host_interface *alts;
-
- if (!ua->intf[intf_index])
- return;
-
- alts = ua->intf[intf_index]->cur_altsetting;
- if (alts->desc.bAlternateSetting != 0) {
- int err = usb_set_interface(ua->dev,
- alts->desc.bInterfaceNumber, 0);
- if (err < 0 && !test_bit(DISCONNECTED, &ua->states))
- dev_warn(&ua->dev->dev,
- "interface reset failed; error %d: %s\n",
- err, usb_error_string(err));
- }
-}
-
-static void stop_usb_capture(struct ua101 *ua)
-{
- clear_bit(USB_CAPTURE_RUNNING, &ua->states);
-
- kill_stream_urbs(&ua->capture);
-
- disable_iso_interface(ua, INTF_CAPTURE);
-}
-
-static int start_usb_capture(struct ua101 *ua)
-{
- int err;
-
- if (test_bit(DISCONNECTED, &ua->states))
- return -ENODEV;
-
- if (test_bit(USB_CAPTURE_RUNNING, &ua->states))
- return 0;
-
- kill_stream_urbs(&ua->capture);
-
- err = enable_iso_interface(ua, INTF_CAPTURE);
- if (err < 0)
- return err;
-
- clear_bit(CAPTURE_URB_COMPLETED, &ua->states);
- ua->capture.urbs[0]->urb.complete = first_capture_urb_complete;
- ua->rate_feedback_start = 0;
- ua->rate_feedback_count = 0;
-
- set_bit(USB_CAPTURE_RUNNING, &ua->states);
- err = submit_stream_urbs(ua, &ua->capture);
- if (err < 0)
- stop_usb_capture(ua);
- return err;
-}
-
-static void stop_usb_playback(struct ua101 *ua)
-{
- clear_bit(USB_PLAYBACK_RUNNING, &ua->states);
-
- kill_stream_urbs(&ua->playback);
-
- tasklet_kill(&ua->playback_tasklet);
-
- disable_iso_interface(ua, INTF_PLAYBACK);
-}
-
-static int start_usb_playback(struct ua101 *ua)
-{
- unsigned int i, frames;
- struct urb *urb;
- int err = 0;
-
- if (test_bit(DISCONNECTED, &ua->states))
- return -ENODEV;
-
- if (test_bit(USB_PLAYBACK_RUNNING, &ua->states))
- return 0;
-
- kill_stream_urbs(&ua->playback);
- tasklet_kill(&ua->playback_tasklet);
-
- err = enable_iso_interface(ua, INTF_PLAYBACK);
- if (err < 0)
- return err;
-
- clear_bit(PLAYBACK_URB_COMPLETED, &ua->states);
- ua->playback.urbs[0]->urb.complete =
- first_playback_urb_complete;
- spin_lock_irq(&ua->lock);
- INIT_LIST_HEAD(&ua->ready_playback_urbs);
- spin_unlock_irq(&ua->lock);
-
- /*
- * We submit the initial URBs all at once, so we have to wait for the
- * packet size FIFO to be full.
- */
- wait_event(ua->rate_feedback_wait,
- ua->rate_feedback_count >= ua->playback.queue_length ||
- !test_bit(USB_CAPTURE_RUNNING, &ua->states) ||
- test_bit(DISCONNECTED, &ua->states));
- if (test_bit(DISCONNECTED, &ua->states)) {
- stop_usb_playback(ua);
- return -ENODEV;
- }
- if (!test_bit(USB_CAPTURE_RUNNING, &ua->states)) {
- stop_usb_playback(ua);
- return -EIO;
- }
-
- for (i = 0; i < ua->playback.queue_length; ++i) {
- /* all initial URBs contain silence */
- spin_lock_irq(&ua->lock);
- frames = ua->rate_feedback[ua->rate_feedback_start];
- add_with_wraparound(ua, &ua->rate_feedback_start, 1);
- ua->rate_feedback_count--;
- spin_unlock_irq(&ua->lock);
- urb = &ua->playback.urbs[i]->urb;
- urb->iso_frame_desc[0].length =
- frames * ua->playback.frame_bytes;
- memset(urb->transfer_buffer, 0,
- urb->iso_frame_desc[0].length);
- }
-
- set_bit(USB_PLAYBACK_RUNNING, &ua->states);
- err = submit_stream_urbs(ua, &ua->playback);
- if (err < 0)
- stop_usb_playback(ua);
- return err;
-}
-
-static void abort_alsa_capture(struct ua101 *ua)
-{
- if (test_bit(ALSA_CAPTURE_RUNNING, &ua->states))
- snd_pcm_stop(ua->capture.substream, SNDRV_PCM_STATE_XRUN);
-}
-
-static void abort_alsa_playback(struct ua101 *ua)
-{
- if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states))
- snd_pcm_stop(ua->playback.substream, SNDRV_PCM_STATE_XRUN);
-}
-
-static int set_stream_hw(struct ua101 *ua, struct snd_pcm_substream *substream,
- unsigned int channels)
-{
- int err;
-
- substream->runtime->hw.info =
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BATCH |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_FIFO_IN_FRAMES;
- substream->runtime->hw.formats = ua->format_bit;
- substream->runtime->hw.rates = snd_pcm_rate_to_rate_bit(ua->rate);
- substream->runtime->hw.rate_min = ua->rate;
- substream->runtime->hw.rate_max = ua->rate;
- substream->runtime->hw.channels_min = channels;
- substream->runtime->hw.channels_max = channels;
- substream->runtime->hw.buffer_bytes_max = 45000 * 1024;
- substream->runtime->hw.period_bytes_min = 1;
- substream->runtime->hw.period_bytes_max = UINT_MAX;
- substream->runtime->hw.periods_min = 2;
- substream->runtime->hw.periods_max = UINT_MAX;
- err = snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_PERIOD_TIME,
- 1500000 / ua->packets_per_second,
- UINT_MAX);
- if (err < 0)
- return err;
- err = snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
- return err;
-}
-
-static int capture_pcm_open(struct snd_pcm_substream *substream)
-{
- struct ua101 *ua = substream->private_data;
- int err;
-
- ua->capture.substream = substream;
- err = set_stream_hw(ua, substream, ua->capture.channels);
- if (err < 0)
- return err;
- substream->runtime->hw.fifo_size =
- DIV_ROUND_CLOSEST(ua->rate, ua->packets_per_second);
- substream->runtime->delay = substream->runtime->hw.fifo_size;
-
- mutex_lock(&ua->mutex);
- err = start_usb_capture(ua);
- if (err >= 0)
- set_bit(ALSA_CAPTURE_OPEN, &ua->states);
- mutex_unlock(&ua->mutex);
- return err;
-}
-
-static int playback_pcm_open(struct snd_pcm_substream *substream)
-{
- struct ua101 *ua = substream->private_data;
- int err;
-
- ua->playback.substream = substream;
- err = set_stream_hw(ua, substream, ua->playback.channels);
- if (err < 0)
- return err;
- substream->runtime->hw.fifo_size =
- DIV_ROUND_CLOSEST(ua->rate * ua->playback.queue_length,
- ua->packets_per_second);
-
- mutex_lock(&ua->mutex);
- err = start_usb_capture(ua);
- if (err < 0)
- goto error;
- err = start_usb_playback(ua);
- if (err < 0) {
- if (!test_bit(ALSA_CAPTURE_OPEN, &ua->states))
- stop_usb_capture(ua);
- goto error;
- }
- set_bit(ALSA_PLAYBACK_OPEN, &ua->states);
-error:
- mutex_unlock(&ua->mutex);
- return err;
-}
-
-static int capture_pcm_close(struct snd_pcm_substream *substream)
-{
- struct ua101 *ua = substream->private_data;
-
- mutex_lock(&ua->mutex);
- clear_bit(ALSA_CAPTURE_OPEN, &ua->states);
- if (!test_bit(ALSA_PLAYBACK_OPEN, &ua->states))
- stop_usb_capture(ua);
- mutex_unlock(&ua->mutex);
- return 0;
-}
-
-static int playback_pcm_close(struct snd_pcm_substream *substream)
-{
- struct ua101 *ua = substream->private_data;
-
- mutex_lock(&ua->mutex);
- stop_usb_playback(ua);
- clear_bit(ALSA_PLAYBACK_OPEN, &ua->states);
- if (!test_bit(ALSA_CAPTURE_OPEN, &ua->states))
- stop_usb_capture(ua);
- mutex_unlock(&ua->mutex);
- return 0;
-}
-
-static int capture_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct ua101 *ua = substream->private_data;
- int err;
-
- mutex_lock(&ua->mutex);
- err = start_usb_capture(ua);
- mutex_unlock(&ua->mutex);
- if (err < 0)
- return err;
-
- return snd_pcm_lib_alloc_vmalloc_buffer(substream,
- params_buffer_bytes(hw_params));
-}
-
-static int playback_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct ua101 *ua = substream->private_data;
- int err;
-
- mutex_lock(&ua->mutex);
- err = start_usb_capture(ua);
- if (err >= 0)
- err = start_usb_playback(ua);
- mutex_unlock(&ua->mutex);
- if (err < 0)
- return err;
-
- return snd_pcm_lib_alloc_vmalloc_buffer(substream,
- params_buffer_bytes(hw_params));
-}
-
-static int ua101_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_vmalloc_buffer(substream);
-}
-
-static int capture_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct ua101 *ua = substream->private_data;
- int err;
-
- mutex_lock(&ua->mutex);
- err = start_usb_capture(ua);
- mutex_unlock(&ua->mutex);
- if (err < 0)
- return err;
-
- /*
- * The EHCI driver schedules the first packet of an iso stream at 10 ms
- * in the future, i.e., no data is actually captured for that long.
- * Take the wait here so that the stream is known to be actually
- * running when the start trigger has been called.
- */
- wait_event(ua->alsa_capture_wait,
- test_bit(CAPTURE_URB_COMPLETED, &ua->states) ||
- !test_bit(USB_CAPTURE_RUNNING, &ua->states));
- if (test_bit(DISCONNECTED, &ua->states))
- return -ENODEV;
- if (!test_bit(USB_CAPTURE_RUNNING, &ua->states))
- return -EIO;
-
- ua->capture.period_pos = 0;
- ua->capture.buffer_pos = 0;
- return 0;
-}
-
-static int playback_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct ua101 *ua = substream->private_data;
- int err;
-
- mutex_lock(&ua->mutex);
- err = start_usb_capture(ua);
- if (err >= 0)
- err = start_usb_playback(ua);
- mutex_unlock(&ua->mutex);
- if (err < 0)
- return err;
-
- /* see the comment in capture_pcm_prepare() */
- wait_event(ua->alsa_playback_wait,
- test_bit(PLAYBACK_URB_COMPLETED, &ua->states) ||
- !test_bit(USB_PLAYBACK_RUNNING, &ua->states));
- if (test_bit(DISCONNECTED, &ua->states))
- return -ENODEV;
- if (!test_bit(USB_PLAYBACK_RUNNING, &ua->states))
- return -EIO;
-
- substream->runtime->delay = 0;
- ua->playback.period_pos = 0;
- ua->playback.buffer_pos = 0;
- return 0;
-}
-
-static int capture_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct ua101 *ua = substream->private_data;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- if (!test_bit(USB_CAPTURE_RUNNING, &ua->states))
- return -EIO;
- set_bit(ALSA_CAPTURE_RUNNING, &ua->states);
- return 0;
- case SNDRV_PCM_TRIGGER_STOP:
- clear_bit(ALSA_CAPTURE_RUNNING, &ua->states);
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-static int playback_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct ua101 *ua = substream->private_data;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- if (!test_bit(USB_PLAYBACK_RUNNING, &ua->states))
- return -EIO;
- set_bit(ALSA_PLAYBACK_RUNNING, &ua->states);
- return 0;
- case SNDRV_PCM_TRIGGER_STOP:
- clear_bit(ALSA_PLAYBACK_RUNNING, &ua->states);
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-static inline snd_pcm_uframes_t ua101_pcm_pointer(struct ua101 *ua,
- struct ua101_stream *stream)
-{
- unsigned long flags;
- unsigned int pos;
-
- spin_lock_irqsave(&ua->lock, flags);
- pos = stream->buffer_pos;
- spin_unlock_irqrestore(&ua->lock, flags);
- return pos;
-}
-
-static snd_pcm_uframes_t capture_pcm_pointer(struct snd_pcm_substream *subs)
-{
- struct ua101 *ua = subs->private_data;
-
- return ua101_pcm_pointer(ua, &ua->capture);
-}
-
-static snd_pcm_uframes_t playback_pcm_pointer(struct snd_pcm_substream *subs)
-{
- struct ua101 *ua = subs->private_data;
-
- return ua101_pcm_pointer(ua, &ua->playback);
-}
-
-static struct snd_pcm_ops capture_pcm_ops = {
- .open = capture_pcm_open,
- .close = capture_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = capture_pcm_hw_params,
- .hw_free = ua101_pcm_hw_free,
- .prepare = capture_pcm_prepare,
- .trigger = capture_pcm_trigger,
- .pointer = capture_pcm_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
-};
-
-static struct snd_pcm_ops playback_pcm_ops = {
- .open = playback_pcm_open,
- .close = playback_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = playback_pcm_hw_params,
- .hw_free = ua101_pcm_hw_free,
- .prepare = playback_pcm_prepare,
- .trigger = playback_pcm_trigger,
- .pointer = playback_pcm_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
-};
-
-static const struct uac_format_type_i_discrete_descriptor *
-find_format_descriptor(struct usb_interface *interface)
-{
- struct usb_host_interface *alt;
- u8 *extra;
- int extralen;
-
- if (interface->num_altsetting != 2) {
- dev_err(&interface->dev, "invalid num_altsetting\n");
- return NULL;
- }
-
- alt = &interface->altsetting[0];
- if (alt->desc.bNumEndpoints != 0) {
- dev_err(&interface->dev, "invalid bNumEndpoints\n");
- return NULL;
- }
-
- alt = &interface->altsetting[1];
- if (alt->desc.bNumEndpoints != 1) {
- dev_err(&interface->dev, "invalid bNumEndpoints\n");
- return NULL;
- }
-
- extra = alt->extra;
- extralen = alt->extralen;
- while (extralen >= sizeof(struct usb_descriptor_header)) {
- struct uac_format_type_i_discrete_descriptor *desc;
-
- desc = (struct uac_format_type_i_discrete_descriptor *)extra;
- if (desc->bLength > extralen) {
- dev_err(&interface->dev, "descriptor overflow\n");
- return NULL;
- }
- if (desc->bLength == UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1) &&
- desc->bDescriptorType == USB_DT_CS_INTERFACE &&
- desc->bDescriptorSubtype == UAC_FORMAT_TYPE) {
- if (desc->bFormatType != UAC_FORMAT_TYPE_I_PCM ||
- desc->bSamFreqType != 1) {
- dev_err(&interface->dev,
- "invalid format type\n");
- return NULL;
- }
- return desc;
- }
- extralen -= desc->bLength;
- extra += desc->bLength;
- }
- dev_err(&interface->dev, "sample format descriptor not found\n");
- return NULL;
-}
-
-static int detect_usb_format(struct ua101 *ua)
-{
- const struct uac_format_type_i_discrete_descriptor *fmt_capture;
- const struct uac_format_type_i_discrete_descriptor *fmt_playback;
- const struct usb_endpoint_descriptor *epd;
- unsigned int rate2;
-
- fmt_capture = find_format_descriptor(ua->intf[INTF_CAPTURE]);
- fmt_playback = find_format_descriptor(ua->intf[INTF_PLAYBACK]);
- if (!fmt_capture || !fmt_playback)
- return -ENXIO;
-
- switch (fmt_capture->bSubframeSize) {
- case 3:
- ua->format_bit = SNDRV_PCM_FMTBIT_S24_3LE;
- break;
- case 4:
- ua->format_bit = SNDRV_PCM_FMTBIT_S32_LE;
- break;
- default:
- dev_err(&ua->dev->dev, "sample width is not 24 or 32 bits\n");
- return -ENXIO;
- }
- if (fmt_capture->bSubframeSize != fmt_playback->bSubframeSize) {
- dev_err(&ua->dev->dev,
- "playback/capture sample widths do not match\n");
- return -ENXIO;
- }
-
- if (fmt_capture->bBitResolution != 24 ||
- fmt_playback->bBitResolution != 24) {
- dev_err(&ua->dev->dev, "sample width is not 24 bits\n");
- return -ENXIO;
- }
-
- ua->rate = combine_triple(fmt_capture->tSamFreq[0]);
- rate2 = combine_triple(fmt_playback->tSamFreq[0]);
- if (ua->rate != rate2) {
- dev_err(&ua->dev->dev,
- "playback/capture rates do not match: %u/%u\n",
- rate2, ua->rate);
- return -ENXIO;
- }
-
- switch (ua->dev->speed) {
- case USB_SPEED_FULL:
- ua->packets_per_second = 1000;
- break;
- case USB_SPEED_HIGH:
- ua->packets_per_second = 8000;
- break;
- default:
- dev_err(&ua->dev->dev, "unknown device speed\n");
- return -ENXIO;
- }
-
- ua->capture.channels = fmt_capture->bNrChannels;
- ua->playback.channels = fmt_playback->bNrChannels;
- ua->capture.frame_bytes =
- fmt_capture->bSubframeSize * ua->capture.channels;
- ua->playback.frame_bytes =
- fmt_playback->bSubframeSize * ua->playback.channels;
-
- epd = &ua->intf[INTF_CAPTURE]->altsetting[1].endpoint[0].desc;
- if (!usb_endpoint_is_isoc_in(epd)) {
- dev_err(&ua->dev->dev, "invalid capture endpoint\n");
- return -ENXIO;
- }
- ua->capture.usb_pipe = usb_rcvisocpipe(ua->dev, usb_endpoint_num(epd));
- ua->capture.max_packet_bytes = le16_to_cpu(epd->wMaxPacketSize);
-
- epd = &ua->intf[INTF_PLAYBACK]->altsetting[1].endpoint[0].desc;
- if (!usb_endpoint_is_isoc_out(epd)) {
- dev_err(&ua->dev->dev, "invalid playback endpoint\n");
- return -ENXIO;
- }
- ua->playback.usb_pipe = usb_sndisocpipe(ua->dev, usb_endpoint_num(epd));
- ua->playback.max_packet_bytes = le16_to_cpu(epd->wMaxPacketSize);
- return 0;
-}
-
-static int alloc_stream_buffers(struct ua101 *ua, struct ua101_stream *stream)
-{
- unsigned int remaining_packets, packets, packets_per_page, i;
- size_t size;
-
- stream->queue_length = queue_length;
- stream->queue_length = max(stream->queue_length,
- (unsigned int)MIN_QUEUE_LENGTH);
- stream->queue_length = min(stream->queue_length,
- (unsigned int)MAX_QUEUE_LENGTH);
-
- /*
- * The cache pool sizes used by usb_alloc_coherent() (128, 512, 2048) are
- * quite bad when used with the packet sizes of this device (e.g. 280,
- * 520, 624). Therefore, we allocate and subdivide entire pages, using
- * a smaller buffer only for the last chunk.
- */
- remaining_packets = stream->queue_length;
- packets_per_page = PAGE_SIZE / stream->max_packet_bytes;
- for (i = 0; i < ARRAY_SIZE(stream->buffers); ++i) {
- packets = min(remaining_packets, packets_per_page);
- size = packets * stream->max_packet_bytes;
- stream->buffers[i].addr =
- usb_alloc_coherent(ua->dev, size, GFP_KERNEL,
- &stream->buffers[i].dma);
- if (!stream->buffers[i].addr)
- return -ENOMEM;
- stream->buffers[i].size = size;
- remaining_packets -= packets;
- if (!remaining_packets)
- break;
- }
- if (remaining_packets) {
- dev_err(&ua->dev->dev, "too many packets\n");
- return -ENXIO;
- }
- return 0;
-}
-
-static void free_stream_buffers(struct ua101 *ua, struct ua101_stream *stream)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(stream->buffers); ++i)
- usb_free_coherent(ua->dev,
- stream->buffers[i].size,
- stream->buffers[i].addr,
- stream->buffers[i].dma);
-}
-
-static int alloc_stream_urbs(struct ua101 *ua, struct ua101_stream *stream,
- void (*urb_complete)(struct urb *))
-{
- unsigned max_packet_size = stream->max_packet_bytes;
- struct ua101_urb *urb;
- unsigned int b, u = 0;
-
- for (b = 0; b < ARRAY_SIZE(stream->buffers); ++b) {
- unsigned int size = stream->buffers[b].size;
- u8 *addr = stream->buffers[b].addr;
- dma_addr_t dma = stream->buffers[b].dma;
-
- while (size >= max_packet_size) {
- if (u >= stream->queue_length)
- goto bufsize_error;
- urb = kmalloc(sizeof(*urb), GFP_KERNEL);
- if (!urb)
- return -ENOMEM;
- usb_init_urb(&urb->urb);
- urb->urb.dev = ua->dev;
- urb->urb.pipe = stream->usb_pipe;
- urb->urb.transfer_flags = URB_ISO_ASAP |
- URB_NO_TRANSFER_DMA_MAP;
- urb->urb.transfer_buffer = addr;
- urb->urb.transfer_dma = dma;
- urb->urb.transfer_buffer_length = max_packet_size;
- urb->urb.number_of_packets = 1;
- urb->urb.interval = 1;
- urb->urb.context = ua;
- urb->urb.complete = urb_complete;
- urb->urb.iso_frame_desc[0].offset = 0;
- urb->urb.iso_frame_desc[0].length = max_packet_size;
- stream->urbs[u++] = urb;
- size -= max_packet_size;
- addr += max_packet_size;
- dma += max_packet_size;
- }
- }
- if (u == stream->queue_length)
- return 0;
-bufsize_error:
- dev_err(&ua->dev->dev, "internal buffer size error\n");
- return -ENXIO;
-}
-
-static void free_stream_urbs(struct ua101_stream *stream)
-{
- unsigned int i;
-
- for (i = 0; i < stream->queue_length; ++i) {
- kfree(stream->urbs[i]);
- stream->urbs[i] = NULL;
- }
-}
-
-static void free_usb_related_resources(struct ua101 *ua,
- struct usb_interface *interface)
-{
- unsigned int i;
- struct usb_interface *intf;
-
- mutex_lock(&ua->mutex);
- free_stream_urbs(&ua->capture);
- free_stream_urbs(&ua->playback);
- mutex_unlock(&ua->mutex);
- free_stream_buffers(ua, &ua->capture);
- free_stream_buffers(ua, &ua->playback);
-
- for (i = 0; i < ARRAY_SIZE(ua->intf); ++i) {
- mutex_lock(&ua->mutex);
- intf = ua->intf[i];
- ua->intf[i] = NULL;
- mutex_unlock(&ua->mutex);
- if (intf) {
- usb_set_intfdata(intf, NULL);
- if (intf != interface)
- usb_driver_release_interface(&ua101_driver,
- intf);
- }
- }
-}
-
-static void ua101_card_free(struct snd_card *card)
-{
- struct ua101 *ua = card->private_data;
-
- mutex_destroy(&ua->mutex);
-}
-
-static int ua101_probe(struct usb_interface *interface,
- const struct usb_device_id *usb_id)
-{
- static const struct snd_usb_midi_endpoint_info midi_ep = {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- };
- static const struct snd_usb_audio_quirk midi_quirk = {
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = &midi_ep
- };
- static const int intf_numbers[2][3] = {
- { /* UA-101 */
- [INTF_PLAYBACK] = 0,
- [INTF_CAPTURE] = 1,
- [INTF_MIDI] = 2,
- },
- { /* UA-1000 */
- [INTF_CAPTURE] = 1,
- [INTF_PLAYBACK] = 2,
- [INTF_MIDI] = 3,
- },
- };
- struct snd_card *card;
- struct ua101 *ua;
- unsigned int card_index, i;
- int is_ua1000;
- const char *name;
- char usb_path[32];
- int err;
-
- is_ua1000 = usb_id->idProduct == 0x0044;
-
- if (interface->altsetting->desc.bInterfaceNumber !=
- intf_numbers[is_ua1000][0])
- return -ENODEV;
-
- mutex_lock(&devices_mutex);
-
- for (card_index = 0; card_index < SNDRV_CARDS; ++card_index)
- if (enable[card_index] && !(devices_used & (1 << card_index)))
- break;
- if (card_index >= SNDRV_CARDS) {
- mutex_unlock(&devices_mutex);
- return -ENOENT;
- }
- err = snd_card_create(index[card_index], id[card_index], THIS_MODULE,
- sizeof(*ua), &card);
- if (err < 0) {
- mutex_unlock(&devices_mutex);
- return err;
- }
- card->private_free = ua101_card_free;
- ua = card->private_data;
- ua->dev = interface_to_usbdev(interface);
- ua->card = card;
- ua->card_index = card_index;
- INIT_LIST_HEAD(&ua->midi_list);
- spin_lock_init(&ua->lock);
- mutex_init(&ua->mutex);
- INIT_LIST_HEAD(&ua->ready_playback_urbs);
- tasklet_init(&ua->playback_tasklet,
- playback_tasklet, (unsigned long)ua);
- init_waitqueue_head(&ua->alsa_capture_wait);
- init_waitqueue_head(&ua->rate_feedback_wait);
- init_waitqueue_head(&ua->alsa_playback_wait);
-
- ua->intf[0] = interface;
- for (i = 1; i < ARRAY_SIZE(ua->intf); ++i) {
- ua->intf[i] = usb_ifnum_to_if(ua->dev,
- intf_numbers[is_ua1000][i]);
- if (!ua->intf[i]) {
- dev_err(&ua->dev->dev, "interface %u not found\n",
- intf_numbers[is_ua1000][i]);
- err = -ENXIO;
- goto probe_error;
- }
- err = usb_driver_claim_interface(&ua101_driver,
- ua->intf[i], ua);
- if (err < 0) {
- ua->intf[i] = NULL;
- err = -EBUSY;
- goto probe_error;
- }
- }
-
- snd_card_set_dev(card, &interface->dev);
-
- err = detect_usb_format(ua);
- if (err < 0)
- goto probe_error;
-
- name = usb_id->idProduct == 0x0044 ? "UA-1000" : "UA-101";
- strcpy(card->driver, "UA-101");
- strcpy(card->shortname, name);
- usb_make_path(ua->dev, usb_path, sizeof(usb_path));
- snprintf(ua->card->longname, sizeof(ua->card->longname),
- "EDIROL %s (serial %s), %u Hz at %s, %s speed", name,
- ua->dev->serial ? ua->dev->serial : "?", ua->rate, usb_path,
- ua->dev->speed == USB_SPEED_HIGH ? "high" : "full");
-
- err = alloc_stream_buffers(ua, &ua->capture);
- if (err < 0)
- goto probe_error;
- err = alloc_stream_buffers(ua, &ua->playback);
- if (err < 0)
- goto probe_error;
-
- err = alloc_stream_urbs(ua, &ua->capture, capture_urb_complete);
- if (err < 0)
- goto probe_error;
- err = alloc_stream_urbs(ua, &ua->playback, playback_urb_complete);
- if (err < 0)
- goto probe_error;
-
- err = snd_pcm_new(card, name, 0, 1, 1, &ua->pcm);
- if (err < 0)
- goto probe_error;
- ua->pcm->private_data = ua;
- strcpy(ua->pcm->name, name);
- snd_pcm_set_ops(ua->pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_pcm_ops);
- snd_pcm_set_ops(ua->pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_pcm_ops);
-
- err = snd_usbmidi_create(card, ua->intf[INTF_MIDI],
- &ua->midi_list, &midi_quirk);
- if (err < 0)
- goto probe_error;
-
- err = snd_card_register(card);
- if (err < 0)
- goto probe_error;
-
- usb_set_intfdata(interface, ua);
- devices_used |= 1 << card_index;
-
- mutex_unlock(&devices_mutex);
- return 0;
-
-probe_error:
- free_usb_related_resources(ua, interface);
- snd_card_free(card);
- mutex_unlock(&devices_mutex);
- return err;
-}
-
-static void ua101_disconnect(struct usb_interface *interface)
-{
- struct ua101 *ua = usb_get_intfdata(interface);
- struct list_head *midi;
-
- if (!ua)
- return;
-
- mutex_lock(&devices_mutex);
-
- set_bit(DISCONNECTED, &ua->states);
- wake_up(&ua->rate_feedback_wait);
-
- /* make sure that userspace cannot create new requests */
- snd_card_disconnect(ua->card);
-
- /* make sure that there are no pending USB requests */
- __list_for_each(midi, &ua->midi_list)
- snd_usbmidi_disconnect(midi);
- abort_alsa_playback(ua);
- abort_alsa_capture(ua);
- mutex_lock(&ua->mutex);
- stop_usb_playback(ua);
- stop_usb_capture(ua);
- mutex_unlock(&ua->mutex);
-
- free_usb_related_resources(ua, interface);
-
- devices_used &= ~(1 << ua->card_index);
-
- snd_card_free_when_closed(ua->card);
-
- mutex_unlock(&devices_mutex);
-}
-
-static struct usb_device_id ua101_ids[] = {
- { USB_DEVICE(0x0582, 0x0044) }, /* UA-1000 high speed */
- { USB_DEVICE(0x0582, 0x007d) }, /* UA-101 high speed */
- { USB_DEVICE(0x0582, 0x008d) }, /* UA-101 full speed */
- { }
-};
-MODULE_DEVICE_TABLE(usb, ua101_ids);
-
-static struct usb_driver ua101_driver = {
- .name = "snd-ua101",
- .id_table = ua101_ids,
- .probe = ua101_probe,
- .disconnect = ua101_disconnect,
-#if 0
- .suspend = ua101_suspend,
- .resume = ua101_resume,
-#endif
-};
-
-module_usb_driver(ua101_driver);
diff --git a/ANDROID_3.4.5/sound/usb/mixer.c b/ANDROID_3.4.5/sound/usb/mixer.c
deleted file mode 100644
index ab23869c..00000000
--- a/ANDROID_3.4.5/sound/usb/mixer.c
+++ /dev/null
@@ -1,2283 +0,0 @@
-/*
- * (Tentative) USB Audio Driver for ALSA
- *
- * Mixer control part
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * Many codes borrowed from audio.c by
- * Alan Cox (alan@lxorguk.ukuu.org.uk)
- * Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- * TODOs, for both the mixer and the streaming interfaces:
- *
- * - support for UAC2 effect units
- * - support for graphical equalizers
- * - RANGE and MEM set commands (UAC2)
- * - RANGE and MEM interrupt dispatchers (UAC2)
- * - audio channel clustering (UAC2)
- * - audio sample rate converter units (UAC2)
- * - proper handling of clock multipliers (UAC2)
- * - dispatch clock change notifications (UAC2)
- * - stop PCM streams which use a clock that became invalid
- * - stop PCM streams which use a clock selector that has changed
- * - parse available sample rates again when clock sources changed
- */
-
-#include <linux/bitops.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/usb.h>
-#include <linux/usb/audio.h>
-#include <linux/usb/audio-v2.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/hwdep.h>
-#include <sound/info.h>
-#include <sound/tlv.h>
-
-#include "usbaudio.h"
-#include "mixer.h"
-#include "helper.h"
-#include "mixer_quirks.h"
-#include "power.h"
-
-#define MAX_ID_ELEMS 256
-
-struct usb_audio_term {
- int id;
- int type;
- int channels;
- unsigned int chconfig;
- int name;
-};
-
-struct usbmix_name_map;
-
-struct mixer_build {
- struct snd_usb_audio *chip;
- struct usb_mixer_interface *mixer;
- unsigned char *buffer;
- unsigned int buflen;
- DECLARE_BITMAP(unitbitmap, MAX_ID_ELEMS);
- struct usb_audio_term oterm;
- const struct usbmix_name_map *map;
- const struct usbmix_selector_map *selector_map;
-};
-
-/*E-mu 0202/0404/0204 eXtension Unit(XU) control*/
-enum {
- USB_XU_CLOCK_RATE = 0xe301,
- USB_XU_CLOCK_SOURCE = 0xe302,
- USB_XU_DIGITAL_IO_STATUS = 0xe303,
- USB_XU_DEVICE_OPTIONS = 0xe304,
- USB_XU_DIRECT_MONITORING = 0xe305,
- USB_XU_METERING = 0xe306
-};
-enum {
- USB_XU_CLOCK_SOURCE_SELECTOR = 0x02, /* clock source*/
- USB_XU_CLOCK_RATE_SELECTOR = 0x03, /* clock rate */
- USB_XU_DIGITAL_FORMAT_SELECTOR = 0x01, /* the spdif format */
- USB_XU_SOFT_LIMIT_SELECTOR = 0x03 /* soft limiter */
-};
-
-/*
- * manual mapping of mixer names
- * if the mixer topology is too complicated and the parsed names are
- * ambiguous, add the entries in usbmixer_maps.c.
- */
-#include "mixer_maps.c"
-
-static const struct usbmix_name_map *
-find_map(struct mixer_build *state, int unitid, int control)
-{
- const struct usbmix_name_map *p = state->map;
-
- if (!p)
- return NULL;
-
- for (p = state->map; p->id; p++) {
- if (p->id == unitid &&
- (!control || !p->control || control == p->control))
- return p;
- }
- return NULL;
-}
-
-/* get the mapped name if the unit matches */
-static int
-check_mapped_name(const struct usbmix_name_map *p, char *buf, int buflen)
-{
- if (!p || !p->name)
- return 0;
-
- buflen--;
- return strlcpy(buf, p->name, buflen);
-}
-
-/* check whether the control should be ignored */
-static inline int
-check_ignored_ctl(const struct usbmix_name_map *p)
-{
- if (!p || p->name || p->dB)
- return 0;
- return 1;
-}
-
-/* dB mapping */
-static inline void check_mapped_dB(const struct usbmix_name_map *p,
- struct usb_mixer_elem_info *cval)
-{
- if (p && p->dB) {
- cval->dBmin = p->dB->min;
- cval->dBmax = p->dB->max;
- cval->initialized = 1;
- }
-}
-
-/* get the mapped selector source name */
-static int check_mapped_selector_name(struct mixer_build *state, int unitid,
- int index, char *buf, int buflen)
-{
- const struct usbmix_selector_map *p;
-
- if (! state->selector_map)
- return 0;
- for (p = state->selector_map; p->id; p++) {
- if (p->id == unitid && index < p->count)
- return strlcpy(buf, p->names[index], buflen);
- }
- return 0;
-}
-
-/*
- * find an audio control unit with the given unit id
- */
-static void *find_audio_control_unit(struct mixer_build *state, unsigned char unit)
-{
- /* we just parse the header */
- struct uac_feature_unit_descriptor *hdr = NULL;
-
- while ((hdr = snd_usb_find_desc(state->buffer, state->buflen, hdr,
- USB_DT_CS_INTERFACE)) != NULL) {
- if (hdr->bLength >= 4 &&
- hdr->bDescriptorSubtype >= UAC_INPUT_TERMINAL &&
- hdr->bDescriptorSubtype <= UAC2_SAMPLE_RATE_CONVERTER &&
- hdr->bUnitID == unit)
- return hdr;
- }
-
- return NULL;
-}
-
-/*
- * copy a string with the given id
- */
-static int snd_usb_copy_string_desc(struct mixer_build *state, int index, char *buf, int maxlen)
-{
- int len = usb_string(state->chip->dev, index, buf, maxlen - 1);
- buf[len] = 0;
- return len;
-}
-
-/*
- * convert from the byte/word on usb descriptor to the zero-based integer
- */
-static int convert_signed_value(struct usb_mixer_elem_info *cval, int val)
-{
- switch (cval->val_type) {
- case USB_MIXER_BOOLEAN:
- return !!val;
- case USB_MIXER_INV_BOOLEAN:
- return !val;
- case USB_MIXER_U8:
- val &= 0xff;
- break;
- case USB_MIXER_S8:
- val &= 0xff;
- if (val >= 0x80)
- val -= 0x100;
- break;
- case USB_MIXER_U16:
- val &= 0xffff;
- break;
- case USB_MIXER_S16:
- val &= 0xffff;
- if (val >= 0x8000)
- val -= 0x10000;
- break;
- }
- return val;
-}
-
-/*
- * convert from the zero-based int to the byte/word for usb descriptor
- */
-static int convert_bytes_value(struct usb_mixer_elem_info *cval, int val)
-{
- switch (cval->val_type) {
- case USB_MIXER_BOOLEAN:
- return !!val;
- case USB_MIXER_INV_BOOLEAN:
- return !val;
- case USB_MIXER_S8:
- case USB_MIXER_U8:
- return val & 0xff;
- case USB_MIXER_S16:
- case USB_MIXER_U16:
- return val & 0xffff;
- }
- return 0; /* not reached */
-}
-
-static int get_relative_value(struct usb_mixer_elem_info *cval, int val)
-{
- if (! cval->res)
- cval->res = 1;
- if (val < cval->min)
- return 0;
- else if (val >= cval->max)
- return (cval->max - cval->min + cval->res - 1) / cval->res;
- else
- return (val - cval->min) / cval->res;
-}
-
-static int get_abs_value(struct usb_mixer_elem_info *cval, int val)
-{
- if (val < 0)
- return cval->min;
- if (! cval->res)
- cval->res = 1;
- val *= cval->res;
- val += cval->min;
- if (val > cval->max)
- return cval->max;
- return val;
-}
-
-
-/*
- * retrieve a mixer value
- */
-
-static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
-{
- struct snd_usb_audio *chip = cval->mixer->chip;
- unsigned char buf[2];
- int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
- int timeout = 10;
- int err;
-
- err = snd_usb_autoresume(cval->mixer->chip);
- if (err < 0)
- return -EIO;
- while (timeout-- > 0) {
- if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request,
- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
- validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
- buf, val_len) >= val_len) {
- *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
- snd_usb_autosuspend(cval->mixer->chip);
- return 0;
- }
- }
- snd_usb_autosuspend(cval->mixer->chip);
- snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
- request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type);
- return -EINVAL;
-}
-
-static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
-{
- struct snd_usb_audio *chip = cval->mixer->chip;
- unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */
- unsigned char *val;
- int ret, size;
- __u8 bRequest;
-
- if (request == UAC_GET_CUR) {
- bRequest = UAC2_CS_CUR;
- size = sizeof(__u16);
- } else {
- bRequest = UAC2_CS_RANGE;
- size = sizeof(buf);
- }
-
- memset(buf, 0, sizeof(buf));
-
- ret = snd_usb_autoresume(chip) ? -EIO : 0;
- if (ret)
- goto error;
-
- ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
- validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
- buf, size);
- snd_usb_autosuspend(chip);
-
- if (ret < 0) {
-error:
- snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
- request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type);
- return ret;
- }
-
- /* FIXME: how should we handle multiple triplets here? */
-
- switch (request) {
- case UAC_GET_CUR:
- val = buf;
- break;
- case UAC_GET_MIN:
- val = buf + sizeof(__u16);
- break;
- case UAC_GET_MAX:
- val = buf + sizeof(__u16) * 2;
- break;
- case UAC_GET_RES:
- val = buf + sizeof(__u16) * 3;
- break;
- default:
- return -EINVAL;
- }
-
- *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(val, sizeof(__u16)));
-
- return 0;
-}
-
-static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
-{
- return (cval->mixer->protocol == UAC_VERSION_1) ?
- get_ctl_value_v1(cval, request, validx, value_ret) :
- get_ctl_value_v2(cval, request, validx, value_ret);
-}
-
-static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *value)
-{
- return get_ctl_value(cval, UAC_GET_CUR, validx, value);
-}
-
-/* channel = 0: master, 1 = first channel */
-static inline int get_cur_mix_raw(struct usb_mixer_elem_info *cval,
- int channel, int *value)
-{
- return get_ctl_value(cval, UAC_GET_CUR, (cval->control << 8) | channel, value);
-}
-
-static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
- int channel, int index, int *value)
-{
- int err;
-
- if (cval->cached & (1 << channel)) {
- *value = cval->cache_val[index];
- return 0;
- }
- err = get_cur_mix_raw(cval, channel, value);
- if (err < 0) {
- if (!cval->mixer->ignore_ctl_error)
- snd_printd(KERN_ERR "cannot get current value for control %d ch %d: err = %d\n",
- cval->control, channel, err);
- return err;
- }
- cval->cached |= 1 << channel;
- cval->cache_val[index] = *value;
- return 0;
-}
-
-
-/*
- * set a mixer value
- */
-
-int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
- int request, int validx, int value_set)
-{
- struct snd_usb_audio *chip = cval->mixer->chip;
- unsigned char buf[2];
- int val_len, err, timeout = 10;
-
- if (cval->mixer->protocol == UAC_VERSION_1) {
- val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
- } else { /* UAC_VERSION_2 */
- /* audio class v2 controls are always 2 bytes in size */
- val_len = sizeof(__u16);
-
- /* FIXME */
- if (request != UAC_SET_CUR) {
- snd_printdd(KERN_WARNING "RANGE setting not yet supported\n");
- return -EINVAL;
- }
-
- request = UAC2_CS_CUR;
- }
-
- value_set = convert_bytes_value(cval, value_set);
- buf[0] = value_set & 0xff;
- buf[1] = (value_set >> 8) & 0xff;
- err = snd_usb_autoresume(chip);
- if (err < 0)
- return -EIO;
- while (timeout-- > 0)
- if (snd_usb_ctl_msg(chip->dev,
- usb_sndctrlpipe(chip->dev, 0), request,
- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
- validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
- buf, val_len) >= 0) {
- snd_usb_autosuspend(chip);
- return 0;
- }
- snd_usb_autosuspend(chip);
- snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n",
- request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type, buf[0], buf[1]);
- return -EINVAL;
-}
-
-static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value)
-{
- return snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, validx, value);
-}
-
-static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel,
- int index, int value)
-{
- int err;
- unsigned int read_only = (channel == 0) ?
- cval->master_readonly :
- cval->ch_readonly & (1 << (channel - 1));
-
- if (read_only) {
- snd_printdd(KERN_INFO "%s(): channel %d of control %d is read_only\n",
- __func__, channel, cval->control);
- return 0;
- }
-
- err = snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, (cval->control << 8) | channel,
- value);
- if (err < 0)
- return err;
- cval->cached |= 1 << channel;
- cval->cache_val[index] = value;
- return 0;
-}
-
-/*
- * TLV callback for mixer volume controls
- */
-static int mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
- unsigned int size, unsigned int __user *_tlv)
-{
- struct usb_mixer_elem_info *cval = kcontrol->private_data;
- DECLARE_TLV_DB_MINMAX(scale, 0, 0);
-
- if (size < sizeof(scale))
- return -ENOMEM;
- scale[2] = cval->dBmin;
- scale[3] = cval->dBmax;
- if (copy_to_user(_tlv, scale, sizeof(scale)))
- return -EFAULT;
- return 0;
-}
-
-/*
- * parser routines begin here...
- */
-
-static int parse_audio_unit(struct mixer_build *state, int unitid);
-
-
-/*
- * check if the input/output channel routing is enabled on the given bitmap.
- * used for mixer unit parser
- */
-static int check_matrix_bitmap(unsigned char *bmap, int ich, int och, int num_outs)
-{
- int idx = ich * num_outs + och;
- return bmap[idx >> 3] & (0x80 >> (idx & 7));
-}
-
-
-/*
- * add an alsa control element
- * search and increment the index until an empty slot is found.
- *
- * if failed, give up and free the control instance.
- */
-
-int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer,
- struct snd_kcontrol *kctl)
-{
- struct usb_mixer_elem_info *cval = kctl->private_data;
- int err;
-
- while (snd_ctl_find_id(mixer->chip->card, &kctl->id))
- kctl->id.index++;
- if ((err = snd_ctl_add(mixer->chip->card, kctl)) < 0) {
- snd_printd(KERN_ERR "cannot add control (err = %d)\n", err);
- return err;
- }
- cval->elem_id = &kctl->id;
- cval->next_id_elem = mixer->id_elems[cval->id];
- mixer->id_elems[cval->id] = cval;
- return 0;
-}
-
-
-/*
- * get a terminal name string
- */
-
-static struct iterm_name_combo {
- int type;
- char *name;
-} iterm_names[] = {
- { 0x0300, "Output" },
- { 0x0301, "Speaker" },
- { 0x0302, "Headphone" },
- { 0x0303, "HMD Audio" },
- { 0x0304, "Desktop Speaker" },
- { 0x0305, "Room Speaker" },
- { 0x0306, "Com Speaker" },
- { 0x0307, "LFE" },
- { 0x0600, "External In" },
- { 0x0601, "Analog In" },
- { 0x0602, "Digital In" },
- { 0x0603, "Line" },
- { 0x0604, "Legacy In" },
- { 0x0605, "IEC958 In" },
- { 0x0606, "1394 DA Stream" },
- { 0x0607, "1394 DV Stream" },
- { 0x0700, "Embedded" },
- { 0x0701, "Noise Source" },
- { 0x0702, "Equalization Noise" },
- { 0x0703, "CD" },
- { 0x0704, "DAT" },
- { 0x0705, "DCC" },
- { 0x0706, "MiniDisk" },
- { 0x0707, "Analog Tape" },
- { 0x0708, "Phonograph" },
- { 0x0709, "VCR Audio" },
- { 0x070a, "Video Disk Audio" },
- { 0x070b, "DVD Audio" },
- { 0x070c, "TV Tuner Audio" },
- { 0x070d, "Satellite Rec Audio" },
- { 0x070e, "Cable Tuner Audio" },
- { 0x070f, "DSS Audio" },
- { 0x0710, "Radio Receiver" },
- { 0x0711, "Radio Transmitter" },
- { 0x0712, "Multi-Track Recorder" },
- { 0x0713, "Synthesizer" },
- { 0 },
-};
-
-static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm,
- unsigned char *name, int maxlen, int term_only)
-{
- struct iterm_name_combo *names;
-
- if (iterm->name)
- return snd_usb_copy_string_desc(state, iterm->name, name, maxlen);
-
- /* virtual type - not a real terminal */
- if (iterm->type >> 16) {
- if (term_only)
- return 0;
- switch (iterm->type >> 16) {
- case UAC_SELECTOR_UNIT:
- strcpy(name, "Selector"); return 8;
- case UAC1_PROCESSING_UNIT:
- strcpy(name, "Process Unit"); return 12;
- case UAC1_EXTENSION_UNIT:
- strcpy(name, "Ext Unit"); return 8;
- case UAC_MIXER_UNIT:
- strcpy(name, "Mixer"); return 5;
- default:
- return sprintf(name, "Unit %d", iterm->id);
- }
- }
-
- switch (iterm->type & 0xff00) {
- case 0x0100:
- strcpy(name, "PCM"); return 3;
- case 0x0200:
- strcpy(name, "Mic"); return 3;
- case 0x0400:
- strcpy(name, "Headset"); return 7;
- case 0x0500:
- strcpy(name, "Phone"); return 5;
- }
-
- for (names = iterm_names; names->type; names++)
- if (names->type == iterm->type) {
- strcpy(name, names->name);
- return strlen(names->name);
- }
- return 0;
-}
-
-
-/*
- * parse the source unit recursively until it reaches to a terminal
- * or a branched unit.
- */
-static int check_input_term(struct mixer_build *state, int id, struct usb_audio_term *term)
-{
- int err;
- void *p1;
-
- memset(term, 0, sizeof(*term));
- while ((p1 = find_audio_control_unit(state, id)) != NULL) {
- unsigned char *hdr = p1;
- term->id = id;
- switch (hdr[2]) {
- case UAC_INPUT_TERMINAL:
- if (state->mixer->protocol == UAC_VERSION_1) {
- struct uac_input_terminal_descriptor *d = p1;
- term->type = le16_to_cpu(d->wTerminalType);
- term->channels = d->bNrChannels;
- term->chconfig = le16_to_cpu(d->wChannelConfig);
- term->name = d->iTerminal;
- } else { /* UAC_VERSION_2 */
- struct uac2_input_terminal_descriptor *d = p1;
- term->type = le16_to_cpu(d->wTerminalType);
- term->channels = d->bNrChannels;
- term->chconfig = le32_to_cpu(d->bmChannelConfig);
- term->name = d->iTerminal;
-
- /* call recursively to get the clock selectors */
- err = check_input_term(state, d->bCSourceID, term);
- if (err < 0)
- return err;
- }
- return 0;
- case UAC_FEATURE_UNIT: {
- /* the header is the same for v1 and v2 */
- struct uac_feature_unit_descriptor *d = p1;
- id = d->bSourceID;
- break; /* continue to parse */
- }
- case UAC_MIXER_UNIT: {
- struct uac_mixer_unit_descriptor *d = p1;
- term->type = d->bDescriptorSubtype << 16; /* virtual type */
- term->channels = uac_mixer_unit_bNrChannels(d);
- term->chconfig = uac_mixer_unit_wChannelConfig(d, state->mixer->protocol);
- term->name = uac_mixer_unit_iMixer(d);
- return 0;
- }
- case UAC_SELECTOR_UNIT:
- case UAC2_CLOCK_SELECTOR: {
- struct uac_selector_unit_descriptor *d = p1;
- /* call recursively to retrieve the channel info */
- if (check_input_term(state, d->baSourceID[0], term) < 0)
- return -ENODEV;
- term->type = d->bDescriptorSubtype << 16; /* virtual type */
- term->id = id;
- term->name = uac_selector_unit_iSelector(d);
- return 0;
- }
- case UAC1_PROCESSING_UNIT:
- case UAC1_EXTENSION_UNIT: {
- struct uac_processing_unit_descriptor *d = p1;
- if (d->bNrInPins) {
- id = d->baSourceID[0];
- break; /* continue to parse */
- }
- term->type = d->bDescriptorSubtype << 16; /* virtual type */
- term->channels = uac_processing_unit_bNrChannels(d);
- term->chconfig = uac_processing_unit_wChannelConfig(d, state->mixer->protocol);
- term->name = uac_processing_unit_iProcessing(d, state->mixer->protocol);
- return 0;
- }
- case UAC2_CLOCK_SOURCE: {
- struct uac_clock_source_descriptor *d = p1;
- term->type = d->bDescriptorSubtype << 16; /* virtual type */
- term->id = id;
- term->name = d->iClockSource;
- return 0;
- }
- default:
- return -ENODEV;
- }
- }
- return -ENODEV;
-}
-
-
-/*
- * Feature Unit
- */
-
-/* feature unit control information */
-struct usb_feature_control_info {
- const char *name;
- unsigned int type; /* control type (mute, volume, etc.) */
-};
-
-static struct usb_feature_control_info audio_feature_info[] = {
- { "Mute", USB_MIXER_INV_BOOLEAN },
- { "Volume", USB_MIXER_S16 },
- { "Tone Control - Bass", USB_MIXER_S8 },
- { "Tone Control - Mid", USB_MIXER_S8 },
- { "Tone Control - Treble", USB_MIXER_S8 },
- { "Graphic Equalizer", USB_MIXER_S8 }, /* FIXME: not implemeted yet */
- { "Auto Gain Control", USB_MIXER_BOOLEAN },
- { "Delay Control", USB_MIXER_U16 },
- { "Bass Boost", USB_MIXER_BOOLEAN },
- { "Loudness", USB_MIXER_BOOLEAN },
- /* UAC2 specific */
- { "Input Gain Control", USB_MIXER_U16 },
- { "Input Gain Pad Control", USB_MIXER_BOOLEAN },
- { "Phase Inverter Control", USB_MIXER_BOOLEAN },
-};
-
-
-/* private_free callback */
-static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
-{
- kfree(kctl->private_data);
- kctl->private_data = NULL;
-}
-
-
-/*
- * interface to ALSA control for feature/mixer units
- */
-
-/* volume control quirks */
-static void volume_control_quirks(struct usb_mixer_elem_info *cval,
- struct snd_kcontrol *kctl)
-{
- switch (cval->mixer->chip->usb_id) {
- case USB_ID(0x0471, 0x0101):
- case USB_ID(0x0471, 0x0104):
- case USB_ID(0x0471, 0x0105):
- case USB_ID(0x0672, 0x1041):
- /* quirk for UDA1321/N101.
- * note that detection between firmware 2.1.1.7 (N101)
- * and later 2.1.1.21 is not very clear from datasheets.
- * I hope that the min value is -15360 for newer firmware --jk
- */
- if (!strcmp(kctl->id.name, "PCM Playback Volume") &&
- cval->min == -15616) {
- snd_printk(KERN_INFO
- "set volume quirk for UDA1321/N101 chip\n");
- cval->max = -256;
- }
- break;
-
- case USB_ID(0x046d, 0x09a4):
- if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
- snd_printk(KERN_INFO
- "set volume quirk for QuickCam E3500\n");
- cval->min = 6080;
- cval->max = 8768;
- cval->res = 192;
- }
- break;
-
- case USB_ID(0x046d, 0x0808):
- case USB_ID(0x046d, 0x0809):
- case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */
- case USB_ID(0x046d, 0x0991):
- /* Most audio usb devices lie about volume resolution.
- * Most Logitech webcams have res = 384.
- * Proboly there is some logitech magic behind this number --fishor
- */
- if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
- snd_printk(KERN_INFO
- "set resolution quirk: cval->res = 384\n");
- cval->res = 384;
- }
- break;
-
- }
-}
-
-/*
- * retrieve the minimum and maximum values for the specified control
- */
-static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
- int default_min, struct snd_kcontrol *kctl)
-{
- /* for failsafe */
- cval->min = default_min;
- cval->max = cval->min + 1;
- cval->res = 1;
- cval->dBmin = cval->dBmax = 0;
-
- if (cval->val_type == USB_MIXER_BOOLEAN ||
- cval->val_type == USB_MIXER_INV_BOOLEAN) {
- cval->initialized = 1;
- } else {
- int minchn = 0;
- if (cval->cmask) {
- int i;
- for (i = 0; i < MAX_CHANNELS; i++)
- if (cval->cmask & (1 << i)) {
- minchn = i + 1;
- break;
- }
- }
- if (get_ctl_value(cval, UAC_GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 ||
- get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) {
- snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n",
- cval->id, snd_usb_ctrl_intf(cval->mixer->chip), cval->control, cval->id);
- return -EINVAL;
- }
- if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) {
- cval->res = 1;
- } else {
- int last_valid_res = cval->res;
-
- while (cval->res > 1) {
- if (snd_usb_mixer_set_ctl_value(cval, UAC_SET_RES,
- (cval->control << 8) | minchn, cval->res / 2) < 0)
- break;
- cval->res /= 2;
- }
- if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0)
- cval->res = last_valid_res;
- }
- if (cval->res == 0)
- cval->res = 1;
-
- /* Additional checks for the proper resolution
- *
- * Some devices report smaller resolutions than actually
- * reacting. They don't return errors but simply clip
- * to the lower aligned value.
- */
- if (cval->min + cval->res < cval->max) {
- int last_valid_res = cval->res;
- int saved, test, check;
- get_cur_mix_raw(cval, minchn, &saved);
- for (;;) {
- test = saved;
- if (test < cval->max)
- test += cval->res;
- else
- test -= cval->res;
- if (test < cval->min || test > cval->max ||
- set_cur_mix_value(cval, minchn, 0, test) ||
- get_cur_mix_raw(cval, minchn, &check)) {
- cval->res = last_valid_res;
- break;
- }
- if (test == check)
- break;
- cval->res *= 2;
- }
- set_cur_mix_value(cval, minchn, 0, saved);
- }
-
- cval->initialized = 1;
- }
-
- if (kctl)
- volume_control_quirks(cval, kctl);
-
- /* USB descriptions contain the dB scale in 1/256 dB unit
- * while ALSA TLV contains in 1/100 dB unit
- */
- cval->dBmin = (convert_signed_value(cval, cval->min) * 100) / 256;
- cval->dBmax = (convert_signed_value(cval, cval->max) * 100) / 256;
- if (cval->dBmin > cval->dBmax) {
- /* something is wrong; assume it's either from/to 0dB */
- if (cval->dBmin < 0)
- cval->dBmax = 0;
- else if (cval->dBmin > 0)
- cval->dBmin = 0;
- if (cval->dBmin > cval->dBmax) {
- /* totally crap, return an error */
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-#define get_min_max(cval, def) get_min_max_with_quirks(cval, def, NULL)
-
-/* get a feature/mixer unit info */
-static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct usb_mixer_elem_info *cval = kcontrol->private_data;
-
- if (cval->val_type == USB_MIXER_BOOLEAN ||
- cval->val_type == USB_MIXER_INV_BOOLEAN)
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- else
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = cval->channels;
- if (cval->val_type == USB_MIXER_BOOLEAN ||
- cval->val_type == USB_MIXER_INV_BOOLEAN) {
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- } else {
- if (!cval->initialized) {
- get_min_max_with_quirks(cval, 0, kcontrol);
- if (cval->initialized && cval->dBmin >= cval->dBmax) {
- kcontrol->vd[0].access &=
- ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ |
- SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK);
- snd_ctl_notify(cval->mixer->chip->card,
- SNDRV_CTL_EVENT_MASK_INFO,
- &kcontrol->id);
- }
- }
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max =
- (cval->max - cval->min + cval->res - 1) / cval->res;
- }
- return 0;
-}
-
-/* get the current value from feature/mixer unit */
-static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_elem_info *cval = kcontrol->private_data;
- int c, cnt, val, err;
-
- ucontrol->value.integer.value[0] = cval->min;
- if (cval->cmask) {
- cnt = 0;
- for (c = 0; c < MAX_CHANNELS; c++) {
- if (!(cval->cmask & (1 << c)))
- continue;
- err = get_cur_mix_value(cval, c + 1, cnt, &val);
- if (err < 0)
- return cval->mixer->ignore_ctl_error ? 0 : err;
- val = get_relative_value(cval, val);
- ucontrol->value.integer.value[cnt] = val;
- cnt++;
- }
- return 0;
- } else {
- /* master channel */
- err = get_cur_mix_value(cval, 0, 0, &val);
- if (err < 0)
- return cval->mixer->ignore_ctl_error ? 0 : err;
- val = get_relative_value(cval, val);
- ucontrol->value.integer.value[0] = val;
- }
- return 0;
-}
-
-/* put the current value to feature/mixer unit */
-static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_elem_info *cval = kcontrol->private_data;
- int c, cnt, val, oval, err;
- int changed = 0;
-
- if (cval->cmask) {
- cnt = 0;
- for (c = 0; c < MAX_CHANNELS; c++) {
- if (!(cval->cmask & (1 << c)))
- continue;
- err = get_cur_mix_value(cval, c + 1, cnt, &oval);
- if (err < 0)
- return cval->mixer->ignore_ctl_error ? 0 : err;
- val = ucontrol->value.integer.value[cnt];
- val = get_abs_value(cval, val);
- if (oval != val) {
- set_cur_mix_value(cval, c + 1, cnt, val);
- changed = 1;
- }
- cnt++;
- }
- } else {
- /* master channel */
- err = get_cur_mix_value(cval, 0, 0, &oval);
- if (err < 0)
- return cval->mixer->ignore_ctl_error ? 0 : err;
- val = ucontrol->value.integer.value[0];
- val = get_abs_value(cval, val);
- if (val != oval) {
- set_cur_mix_value(cval, 0, 0, val);
- changed = 1;
- }
- }
- return changed;
-}
-
-static struct snd_kcontrol_new usb_feature_unit_ctl = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "", /* will be filled later manually */
- .info = mixer_ctl_feature_info,
- .get = mixer_ctl_feature_get,
- .put = mixer_ctl_feature_put,
-};
-
-/* the read-only variant */
-static struct snd_kcontrol_new usb_feature_unit_ctl_ro = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "", /* will be filled later manually */
- .info = mixer_ctl_feature_info,
- .get = mixer_ctl_feature_get,
- .put = NULL,
-};
-
-/* This symbol is exported in order to allow the mixer quirks to
- * hook up to the standard feature unit control mechanism */
-struct snd_kcontrol_new *snd_usb_feature_unit_ctl = &usb_feature_unit_ctl;
-
-/*
- * build a feature control
- */
-
-static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str)
-{
- return strlcat(kctl->id.name, str, sizeof(kctl->id.name));
-}
-
-static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
- unsigned int ctl_mask, int control,
- struct usb_audio_term *iterm, int unitid,
- int readonly_mask)
-{
- struct uac_feature_unit_descriptor *desc = raw_desc;
- unsigned int len = 0;
- int mapped_name = 0;
- int nameid = uac_feature_unit_iFeature(desc);
- struct snd_kcontrol *kctl;
- struct usb_mixer_elem_info *cval;
- const struct usbmix_name_map *map;
- unsigned int range;
-
- control++; /* change from zero-based to 1-based value */
-
- if (control == UAC_FU_GRAPHIC_EQUALIZER) {
- /* FIXME: not supported yet */
- return;
- }
-
- map = find_map(state, unitid, control);
- if (check_ignored_ctl(map))
- return;
-
- cval = kzalloc(sizeof(*cval), GFP_KERNEL);
- if (! cval) {
- snd_printk(KERN_ERR "cannot malloc kcontrol\n");
- return;
- }
- cval->mixer = state->mixer;
- cval->id = unitid;
- cval->control = control;
- cval->cmask = ctl_mask;
- cval->val_type = audio_feature_info[control-1].type;
- if (ctl_mask == 0) {
- cval->channels = 1; /* master channel */
- cval->master_readonly = readonly_mask;
- } else {
- int i, c = 0;
- for (i = 0; i < 16; i++)
- if (ctl_mask & (1 << i))
- c++;
- cval->channels = c;
- cval->ch_readonly = readonly_mask;
- }
-
- /* if all channels in the mask are marked read-only, make the control
- * read-only. set_cur_mix_value() will check the mask again and won't
- * issue write commands to read-only channels. */
- if (cval->channels == readonly_mask)
- kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval);
- else
- kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
-
- if (! kctl) {
- snd_printk(KERN_ERR "cannot malloc kcontrol\n");
- kfree(cval);
- return;
- }
- kctl->private_free = usb_mixer_elem_free;
-
- len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
- mapped_name = len != 0;
- if (! len && nameid)
- len = snd_usb_copy_string_desc(state, nameid,
- kctl->id.name, sizeof(kctl->id.name));
-
- /* get min/max values */
- get_min_max_with_quirks(cval, 0, kctl);
-
- switch (control) {
- case UAC_FU_MUTE:
- case UAC_FU_VOLUME:
- /* determine the control name. the rule is:
- * - if a name id is given in descriptor, use it.
- * - if the connected input can be determined, then use the name
- * of terminal type.
- * - if the connected output can be determined, use it.
- * - otherwise, anonymous name.
- */
- if (! len) {
- len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 1);
- if (! len)
- len = get_term_name(state, &state->oterm, kctl->id.name, sizeof(kctl->id.name), 1);
- if (! len)
- len = snprintf(kctl->id.name, sizeof(kctl->id.name),
- "Feature %d", unitid);
- }
- /* determine the stream direction:
- * if the connected output is USB stream, then it's likely a
- * capture stream. otherwise it should be playback (hopefully :)
- */
- if (! mapped_name && ! (state->oterm.type >> 16)) {
- if ((state->oterm.type & 0xff00) == 0x0100) {
- len = append_ctl_name(kctl, " Capture");
- } else {
- len = append_ctl_name(kctl, " Playback");
- }
- }
- append_ctl_name(kctl, control == UAC_FU_MUTE ?
- " Switch" : " Volume");
- if (control == UAC_FU_VOLUME) {
- check_mapped_dB(map, cval);
- if (cval->dBmin < cval->dBmax || !cval->initialized) {
- kctl->tlv.c = mixer_vol_tlv;
- kctl->vd[0].access |=
- SNDRV_CTL_ELEM_ACCESS_TLV_READ |
- SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
- }
- }
- break;
-
- default:
- if (! len)
- strlcpy(kctl->id.name, audio_feature_info[control-1].name,
- sizeof(kctl->id.name));
- break;
- }
-
- range = (cval->max - cval->min) / cval->res;
- /* Are there devices with volume range more than 255? I use a bit more
- * to be sure. 384 is a resolution magic number found on Logitech
- * devices. It will definitively catch all buggy Logitech devices.
- */
- if (range > 384) {
- snd_printk(KERN_WARNING "usb_audio: Warning! Unlikely big "
- "volume range (=%u), cval->res is probably wrong.",
- range);
- snd_printk(KERN_WARNING "usb_audio: [%d] FU [%s] ch = %d, "
- "val = %d/%d/%d", cval->id,
- kctl->id.name, cval->channels,
- cval->min, cval->max, cval->res);
- }
-
- snd_printdd(KERN_INFO "[%d] FU [%s] ch = %d, val = %d/%d/%d\n",
- cval->id, kctl->id.name, cval->channels, cval->min, cval->max, cval->res);
- snd_usb_mixer_add_control(state->mixer, kctl);
-}
-
-
-
-/*
- * parse a feature unit
- *
- * most of controls are defined here.
- */
-static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void *_ftr)
-{
- int channels, i, j;
- struct usb_audio_term iterm;
- unsigned int master_bits, first_ch_bits;
- int err, csize;
- struct uac_feature_unit_descriptor *hdr = _ftr;
- __u8 *bmaControls;
-
- if (state->mixer->protocol == UAC_VERSION_1) {
- csize = hdr->bControlSize;
- if (!csize) {
- snd_printdd(KERN_ERR "usbaudio: unit %u: "
- "invalid bControlSize == 0\n", unitid);
- return -EINVAL;
- }
- channels = (hdr->bLength - 7) / csize - 1;
- bmaControls = hdr->bmaControls;
- } else {
- struct uac2_feature_unit_descriptor *ftr = _ftr;
- csize = 4;
- channels = (hdr->bLength - 6) / 4 - 1;
- bmaControls = ftr->bmaControls;
- }
-
- if (hdr->bLength < 7 || !csize || hdr->bLength < 7 + csize) {
- snd_printk(KERN_ERR "usbaudio: unit %u: invalid UAC_FEATURE_UNIT descriptor\n", unitid);
- return -EINVAL;
- }
-
- /* parse the source unit */
- if ((err = parse_audio_unit(state, hdr->bSourceID)) < 0)
- return err;
-
- /* determine the input source type and name */
- if (check_input_term(state, hdr->bSourceID, &iterm) < 0)
- return -EINVAL;
-
- master_bits = snd_usb_combine_bytes(bmaControls, csize);
- /* master configuration quirks */
- switch (state->chip->usb_id) {
- case USB_ID(0x08bb, 0x2702):
- snd_printk(KERN_INFO
- "usbmixer: master volume quirk for PCM2702 chip\n");
- /* disable non-functional volume control */
- master_bits &= ~UAC_CONTROL_BIT(UAC_FU_VOLUME);
- break;
- }
- if (channels > 0)
- first_ch_bits = snd_usb_combine_bytes(bmaControls + csize, csize);
- else
- first_ch_bits = 0;
-
- if (state->mixer->protocol == UAC_VERSION_1) {
- /* check all control types */
- for (i = 0; i < 10; i++) {
- unsigned int ch_bits = 0;
- for (j = 0; j < channels; j++) {
- unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize);
- if (mask & (1 << i))
- ch_bits |= (1 << j);
- }
- /* audio class v1 controls are never read-only */
- if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
- build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, 0);
- if (master_bits & (1 << i))
- build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, 0);
- }
- } else { /* UAC_VERSION_2 */
- for (i = 0; i < ARRAY_SIZE(audio_feature_info); i++) {
- unsigned int ch_bits = 0;
- unsigned int ch_read_only = 0;
-
- for (j = 0; j < channels; j++) {
- unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize);
- if (uac2_control_is_readable(mask, i)) {
- ch_bits |= (1 << j);
- if (!uac2_control_is_writeable(mask, i))
- ch_read_only |= (1 << j);
- }
- }
-
- /* NOTE: build_feature_ctl() will mark the control read-only if all channels
- * are marked read-only in the descriptors. Otherwise, the control will be
- * reported as writeable, but the driver will not actually issue a write
- * command for read-only channels */
- if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
- build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, ch_read_only);
- if (uac2_control_is_readable(master_bits, i))
- build_feature_ctl(state, _ftr, 0, i, &iterm, unitid,
- !uac2_control_is_writeable(master_bits, i));
- }
- }
-
- return 0;
-}
-
-
-/*
- * Mixer Unit
- */
-
-/*
- * build a mixer unit control
- *
- * the callbacks are identical with feature unit.
- * input channel number (zero based) is given in control field instead.
- */
-
-static void build_mixer_unit_ctl(struct mixer_build *state,
- struct uac_mixer_unit_descriptor *desc,
- int in_pin, int in_ch, int unitid,
- struct usb_audio_term *iterm)
-{
- struct usb_mixer_elem_info *cval;
- unsigned int num_outs = uac_mixer_unit_bNrChannels(desc);
- unsigned int i, len;
- struct snd_kcontrol *kctl;
- const struct usbmix_name_map *map;
-
- map = find_map(state, unitid, 0);
- if (check_ignored_ctl(map))
- return;
-
- cval = kzalloc(sizeof(*cval), GFP_KERNEL);
- if (! cval)
- return;
-
- cval->mixer = state->mixer;
- cval->id = unitid;
- cval->control = in_ch + 1; /* based on 1 */
- cval->val_type = USB_MIXER_S16;
- for (i = 0; i < num_outs; i++) {
- if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc, state->mixer->protocol), in_ch, i, num_outs)) {
- cval->cmask |= (1 << i);
- cval->channels++;
- }
- }
-
- /* get min/max values */
- get_min_max(cval, 0);
-
- kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
- if (! kctl) {
- snd_printk(KERN_ERR "cannot malloc kcontrol\n");
- kfree(cval);
- return;
- }
- kctl->private_free = usb_mixer_elem_free;
-
- len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
- if (! len)
- len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0);
- if (! len)
- len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1);
- append_ctl_name(kctl, " Volume");
-
- snd_printdd(KERN_INFO "[%d] MU [%s] ch = %d, val = %d/%d\n",
- cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
- snd_usb_mixer_add_control(state->mixer, kctl);
-}
-
-
-/*
- * parse a mixer unit
- */
-static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, void *raw_desc)
-{
- struct uac_mixer_unit_descriptor *desc = raw_desc;
- struct usb_audio_term iterm;
- int input_pins, num_ins, num_outs;
- int pin, ich, err;
-
- if (desc->bLength < 11 || ! (input_pins = desc->bNrInPins) || ! (num_outs = uac_mixer_unit_bNrChannels(desc))) {
- snd_printk(KERN_ERR "invalid MIXER UNIT descriptor %d\n", unitid);
- return -EINVAL;
- }
- /* no bmControls field (e.g. Maya44) -> ignore */
- if (desc->bLength <= 10 + input_pins) {
- snd_printdd(KERN_INFO "MU %d has no bmControls field\n", unitid);
- return 0;
- }
-
- num_ins = 0;
- ich = 0;
- for (pin = 0; pin < input_pins; pin++) {
- err = parse_audio_unit(state, desc->baSourceID[pin]);
- if (err < 0)
- return err;
- err = check_input_term(state, desc->baSourceID[pin], &iterm);
- if (err < 0)
- return err;
- num_ins += iterm.channels;
- for (; ich < num_ins; ++ich) {
- int och, ich_has_controls = 0;
-
- for (och = 0; och < num_outs; ++och) {
- if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc, state->mixer->protocol),
- ich, och, num_outs)) {
- ich_has_controls = 1;
- break;
- }
- }
- if (ich_has_controls)
- build_mixer_unit_ctl(state, desc, pin, ich,
- unitid, &iterm);
- }
- }
- return 0;
-}
-
-
-/*
- * Processing Unit / Extension Unit
- */
-
-/* get callback for processing/extension unit */
-static int mixer_ctl_procunit_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_elem_info *cval = kcontrol->private_data;
- int err, val;
-
- err = get_cur_ctl_value(cval, cval->control << 8, &val);
- if (err < 0 && cval->mixer->ignore_ctl_error) {
- ucontrol->value.integer.value[0] = cval->min;
- return 0;
- }
- if (err < 0)
- return err;
- val = get_relative_value(cval, val);
- ucontrol->value.integer.value[0] = val;
- return 0;
-}
-
-/* put callback for processing/extension unit */
-static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_elem_info *cval = kcontrol->private_data;
- int val, oval, err;
-
- err = get_cur_ctl_value(cval, cval->control << 8, &oval);
- if (err < 0) {
- if (cval->mixer->ignore_ctl_error)
- return 0;
- return err;
- }
- val = ucontrol->value.integer.value[0];
- val = get_abs_value(cval, val);
- if (val != oval) {
- set_cur_ctl_value(cval, cval->control << 8, val);
- return 1;
- }
- return 0;
-}
-
-/* alsa control interface for processing/extension unit */
-static struct snd_kcontrol_new mixer_procunit_ctl = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "", /* will be filled later */
- .info = mixer_ctl_feature_info,
- .get = mixer_ctl_procunit_get,
- .put = mixer_ctl_procunit_put,
-};
-
-
-/*
- * predefined data for processing units
- */
-struct procunit_value_info {
- int control;
- char *suffix;
- int val_type;
- int min_value;
-};
-
-struct procunit_info {
- int type;
- char *name;
- struct procunit_value_info *values;
-};
-
-static struct procunit_value_info updown_proc_info[] = {
- { UAC_UD_ENABLE, "Switch", USB_MIXER_BOOLEAN },
- { UAC_UD_MODE_SELECT, "Mode Select", USB_MIXER_U8, 1 },
- { 0 }
-};
-static struct procunit_value_info prologic_proc_info[] = {
- { UAC_DP_ENABLE, "Switch", USB_MIXER_BOOLEAN },
- { UAC_DP_MODE_SELECT, "Mode Select", USB_MIXER_U8, 1 },
- { 0 }
-};
-static struct procunit_value_info threed_enh_proc_info[] = {
- { UAC_3D_ENABLE, "Switch", USB_MIXER_BOOLEAN },
- { UAC_3D_SPACE, "Spaciousness", USB_MIXER_U8 },
- { 0 }
-};
-static struct procunit_value_info reverb_proc_info[] = {
- { UAC_REVERB_ENABLE, "Switch", USB_MIXER_BOOLEAN },
- { UAC_REVERB_LEVEL, "Level", USB_MIXER_U8 },
- { UAC_REVERB_TIME, "Time", USB_MIXER_U16 },
- { UAC_REVERB_FEEDBACK, "Feedback", USB_MIXER_U8 },
- { 0 }
-};
-static struct procunit_value_info chorus_proc_info[] = {
- { UAC_CHORUS_ENABLE, "Switch", USB_MIXER_BOOLEAN },
- { UAC_CHORUS_LEVEL, "Level", USB_MIXER_U8 },
- { UAC_CHORUS_RATE, "Rate", USB_MIXER_U16 },
- { UAC_CHORUS_DEPTH, "Depth", USB_MIXER_U16 },
- { 0 }
-};
-static struct procunit_value_info dcr_proc_info[] = {
- { UAC_DCR_ENABLE, "Switch", USB_MIXER_BOOLEAN },
- { UAC_DCR_RATE, "Ratio", USB_MIXER_U16 },
- { UAC_DCR_MAXAMPL, "Max Amp", USB_MIXER_S16 },
- { UAC_DCR_THRESHOLD, "Threshold", USB_MIXER_S16 },
- { UAC_DCR_ATTACK_TIME, "Attack Time", USB_MIXER_U16 },
- { UAC_DCR_RELEASE_TIME, "Release Time", USB_MIXER_U16 },
- { 0 }
-};
-
-static struct procunit_info procunits[] = {
- { UAC_PROCESS_UP_DOWNMIX, "Up Down", updown_proc_info },
- { UAC_PROCESS_DOLBY_PROLOGIC, "Dolby Prologic", prologic_proc_info },
- { UAC_PROCESS_STEREO_EXTENDER, "3D Stereo Extender", threed_enh_proc_info },
- { UAC_PROCESS_REVERB, "Reverb", reverb_proc_info },
- { UAC_PROCESS_CHORUS, "Chorus", chorus_proc_info },
- { UAC_PROCESS_DYN_RANGE_COMP, "DCR", dcr_proc_info },
- { 0 },
-};
-/*
- * predefined data for extension units
- */
-static struct procunit_value_info clock_rate_xu_info[] = {
- { USB_XU_CLOCK_RATE_SELECTOR, "Selector", USB_MIXER_U8, 0 },
- { 0 }
-};
-static struct procunit_value_info clock_source_xu_info[] = {
- { USB_XU_CLOCK_SOURCE_SELECTOR, "External", USB_MIXER_BOOLEAN },
- { 0 }
-};
-static struct procunit_value_info spdif_format_xu_info[] = {
- { USB_XU_DIGITAL_FORMAT_SELECTOR, "SPDIF/AC3", USB_MIXER_BOOLEAN },
- { 0 }
-};
-static struct procunit_value_info soft_limit_xu_info[] = {
- { USB_XU_SOFT_LIMIT_SELECTOR, " ", USB_MIXER_BOOLEAN },
- { 0 }
-};
-static struct procunit_info extunits[] = {
- { USB_XU_CLOCK_RATE, "Clock rate", clock_rate_xu_info },
- { USB_XU_CLOCK_SOURCE, "DigitalIn CLK source", clock_source_xu_info },
- { USB_XU_DIGITAL_IO_STATUS, "DigitalOut format:", spdif_format_xu_info },
- { USB_XU_DEVICE_OPTIONS, "AnalogueIn Soft Limit", soft_limit_xu_info },
- { 0 }
-};
-/*
- * build a processing/extension unit
- */
-static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw_desc, struct procunit_info *list, char *name)
-{
- struct uac_processing_unit_descriptor *desc = raw_desc;
- int num_ins = desc->bNrInPins;
- struct usb_mixer_elem_info *cval;
- struct snd_kcontrol *kctl;
- int i, err, nameid, type, len;
- struct procunit_info *info;
- struct procunit_value_info *valinfo;
- const struct usbmix_name_map *map;
- static struct procunit_value_info default_value_info[] = {
- { 0x01, "Switch", USB_MIXER_BOOLEAN },
- { 0 }
- };
- static struct procunit_info default_info = {
- 0, NULL, default_value_info
- };
-
- if (desc->bLength < 13 || desc->bLength < 13 + num_ins ||
- desc->bLength < num_ins + uac_processing_unit_bControlSize(desc, state->mixer->protocol)) {
- snd_printk(KERN_ERR "invalid %s descriptor (id %d)\n", name, unitid);
- return -EINVAL;
- }
-
- for (i = 0; i < num_ins; i++) {
- if ((err = parse_audio_unit(state, desc->baSourceID[i])) < 0)
- return err;
- }
-
- type = le16_to_cpu(desc->wProcessType);
- for (info = list; info && info->type; info++)
- if (info->type == type)
- break;
- if (! info || ! info->type)
- info = &default_info;
-
- for (valinfo = info->values; valinfo->control; valinfo++) {
- __u8 *controls = uac_processing_unit_bmControls(desc, state->mixer->protocol);
-
- if (! (controls[valinfo->control / 8] & (1 << ((valinfo->control % 8) - 1))))
- continue;
- map = find_map(state, unitid, valinfo->control);
- if (check_ignored_ctl(map))
- continue;
- cval = kzalloc(sizeof(*cval), GFP_KERNEL);
- if (! cval) {
- snd_printk(KERN_ERR "cannot malloc kcontrol\n");
- return -ENOMEM;
- }
- cval->mixer = state->mixer;
- cval->id = unitid;
- cval->control = valinfo->control;
- cval->val_type = valinfo->val_type;
- cval->channels = 1;
-
- /* get min/max values */
- if (type == UAC_PROCESS_UP_DOWNMIX && cval->control == UAC_UD_MODE_SELECT) {
- __u8 *control_spec = uac_processing_unit_specific(desc, state->mixer->protocol);
- /* FIXME: hard-coded */
- cval->min = 1;
- cval->max = control_spec[0];
- cval->res = 1;
- cval->initialized = 1;
- } else {
- if (type == USB_XU_CLOCK_RATE) {
- /* E-Mu USB 0404/0202/TrackerPre/0204
- * samplerate control quirk
- */
- cval->min = 0;
- cval->max = 5;
- cval->res = 1;
- cval->initialized = 1;
- } else
- get_min_max(cval, valinfo->min_value);
- }
-
- kctl = snd_ctl_new1(&mixer_procunit_ctl, cval);
- if (! kctl) {
- snd_printk(KERN_ERR "cannot malloc kcontrol\n");
- kfree(cval);
- return -ENOMEM;
- }
- kctl->private_free = usb_mixer_elem_free;
-
- if (check_mapped_name(map, kctl->id.name,
- sizeof(kctl->id.name)))
- /* nothing */ ;
- else if (info->name)
- strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name));
- else {
- nameid = uac_processing_unit_iProcessing(desc, state->mixer->protocol);
- len = 0;
- if (nameid)
- len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name));
- if (! len)
- strlcpy(kctl->id.name, name, sizeof(kctl->id.name));
- }
- append_ctl_name(kctl, " ");
- append_ctl_name(kctl, valinfo->suffix);
-
- snd_printdd(KERN_INFO "[%d] PU [%s] ch = %d, val = %d/%d\n",
- cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
- if ((err = snd_usb_mixer_add_control(state->mixer, kctl)) < 0)
- return err;
- }
- return 0;
-}
-
-
-static int parse_audio_processing_unit(struct mixer_build *state, int unitid, void *raw_desc)
-{
- return build_audio_procunit(state, unitid, raw_desc, procunits, "Processing Unit");
-}
-
-static int parse_audio_extension_unit(struct mixer_build *state, int unitid, void *raw_desc)
-{
- /* Note that we parse extension units with processing unit descriptors.
- * That's ok as the layout is the same */
- return build_audio_procunit(state, unitid, raw_desc, extunits, "Extension Unit");
-}
-
-
-/*
- * Selector Unit
- */
-
-/* info callback for selector unit
- * use an enumerator type for routing
- */
-static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct usb_mixer_elem_info *cval = kcontrol->private_data;
- const char **itemlist = (const char **)kcontrol->private_value;
-
- if (snd_BUG_ON(!itemlist))
- return -EINVAL;
- return snd_ctl_enum_info(uinfo, 1, cval->max, itemlist);
-}
-
-/* get callback for selector unit */
-static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_elem_info *cval = kcontrol->private_data;
- int val, err;
-
- err = get_cur_ctl_value(cval, cval->control << 8, &val);
- if (err < 0) {
- if (cval->mixer->ignore_ctl_error) {
- ucontrol->value.enumerated.item[0] = 0;
- return 0;
- }
- return err;
- }
- val = get_relative_value(cval, val);
- ucontrol->value.enumerated.item[0] = val;
- return 0;
-}
-
-/* put callback for selector unit */
-static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_elem_info *cval = kcontrol->private_data;
- int val, oval, err;
-
- err = get_cur_ctl_value(cval, cval->control << 8, &oval);
- if (err < 0) {
- if (cval->mixer->ignore_ctl_error)
- return 0;
- return err;
- }
- val = ucontrol->value.enumerated.item[0];
- val = get_abs_value(cval, val);
- if (val != oval) {
- set_cur_ctl_value(cval, cval->control << 8, val);
- return 1;
- }
- return 0;
-}
-
-/* alsa control interface for selector unit */
-static struct snd_kcontrol_new mixer_selectunit_ctl = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "", /* will be filled later */
- .info = mixer_ctl_selector_info,
- .get = mixer_ctl_selector_get,
- .put = mixer_ctl_selector_put,
-};
-
-
-/* private free callback.
- * free both private_data and private_value
- */
-static void usb_mixer_selector_elem_free(struct snd_kcontrol *kctl)
-{
- int i, num_ins = 0;
-
- if (kctl->private_data) {
- struct usb_mixer_elem_info *cval = kctl->private_data;
- num_ins = cval->max;
- kfree(cval);
- kctl->private_data = NULL;
- }
- if (kctl->private_value) {
- char **itemlist = (char **)kctl->private_value;
- for (i = 0; i < num_ins; i++)
- kfree(itemlist[i]);
- kfree(itemlist);
- kctl->private_value = 0;
- }
-}
-
-/*
- * parse a selector unit
- */
-static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void *raw_desc)
-{
- struct uac_selector_unit_descriptor *desc = raw_desc;
- unsigned int i, nameid, len;
- int err;
- struct usb_mixer_elem_info *cval;
- struct snd_kcontrol *kctl;
- const struct usbmix_name_map *map;
- char **namelist;
-
- if (!desc->bNrInPins || desc->bLength < 5 + desc->bNrInPins) {
- snd_printk(KERN_ERR "invalid SELECTOR UNIT descriptor %d\n", unitid);
- return -EINVAL;
- }
-
- for (i = 0; i < desc->bNrInPins; i++) {
- if ((err = parse_audio_unit(state, desc->baSourceID[i])) < 0)
- return err;
- }
-
- if (desc->bNrInPins == 1) /* only one ? nonsense! */
- return 0;
-
- map = find_map(state, unitid, 0);
- if (check_ignored_ctl(map))
- return 0;
-
- cval = kzalloc(sizeof(*cval), GFP_KERNEL);
- if (! cval) {
- snd_printk(KERN_ERR "cannot malloc kcontrol\n");
- return -ENOMEM;
- }
- cval->mixer = state->mixer;
- cval->id = unitid;
- cval->val_type = USB_MIXER_U8;
- cval->channels = 1;
- cval->min = 1;
- cval->max = desc->bNrInPins;
- cval->res = 1;
- cval->initialized = 1;
-
- if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR)
- cval->control = UAC2_CX_CLOCK_SELECTOR;
- else
- cval->control = 0;
-
- namelist = kmalloc(sizeof(char *) * desc->bNrInPins, GFP_KERNEL);
- if (! namelist) {
- snd_printk(KERN_ERR "cannot malloc\n");
- kfree(cval);
- return -ENOMEM;
- }
-#define MAX_ITEM_NAME_LEN 64
- for (i = 0; i < desc->bNrInPins; i++) {
- struct usb_audio_term iterm;
- len = 0;
- namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL);
- if (! namelist[i]) {
- snd_printk(KERN_ERR "cannot malloc\n");
- while (i--)
- kfree(namelist[i]);
- kfree(namelist);
- kfree(cval);
- return -ENOMEM;
- }
- len = check_mapped_selector_name(state, unitid, i, namelist[i],
- MAX_ITEM_NAME_LEN);
- if (! len && check_input_term(state, desc->baSourceID[i], &iterm) >= 0)
- len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0);
- if (! len)
- sprintf(namelist[i], "Input %d", i);
- }
-
- kctl = snd_ctl_new1(&mixer_selectunit_ctl, cval);
- if (! kctl) {
- snd_printk(KERN_ERR "cannot malloc kcontrol\n");
- kfree(namelist);
- kfree(cval);
- return -ENOMEM;
- }
- kctl->private_value = (unsigned long)namelist;
- kctl->private_free = usb_mixer_selector_elem_free;
-
- nameid = uac_selector_unit_iSelector(desc);
- len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
- if (len)
- ;
- else if (nameid)
- snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name));
- else {
- len = get_term_name(state, &state->oterm,
- kctl->id.name, sizeof(kctl->id.name), 0);
- if (! len)
- strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name));
-
- if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR)
- append_ctl_name(kctl, " Clock Source");
- else if ((state->oterm.type & 0xff00) == 0x0100)
- append_ctl_name(kctl, " Capture Source");
- else
- append_ctl_name(kctl, " Playback Source");
- }
-
- snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n",
- cval->id, kctl->id.name, desc->bNrInPins);
- if ((err = snd_usb_mixer_add_control(state->mixer, kctl)) < 0)
- return err;
-
- return 0;
-}
-
-
-/*
- * parse an audio unit recursively
- */
-
-static int parse_audio_unit(struct mixer_build *state, int unitid)
-{
- unsigned char *p1;
-
- if (test_and_set_bit(unitid, state->unitbitmap))
- return 0; /* the unit already visited */
-
- p1 = find_audio_control_unit(state, unitid);
- if (!p1) {
- snd_printk(KERN_ERR "usbaudio: unit %d not found!\n", unitid);
- return -EINVAL;
- }
-
- switch (p1[2]) {
- case UAC_INPUT_TERMINAL:
- case UAC2_CLOCK_SOURCE:
- return 0; /* NOP */
- case UAC_MIXER_UNIT:
- return parse_audio_mixer_unit(state, unitid, p1);
- case UAC_SELECTOR_UNIT:
- case UAC2_CLOCK_SELECTOR:
- return parse_audio_selector_unit(state, unitid, p1);
- case UAC_FEATURE_UNIT:
- return parse_audio_feature_unit(state, unitid, p1);
- case UAC1_PROCESSING_UNIT:
- /* UAC2_EFFECT_UNIT has the same value */
- if (state->mixer->protocol == UAC_VERSION_1)
- return parse_audio_processing_unit(state, unitid, p1);
- else
- return 0; /* FIXME - effect units not implemented yet */
- case UAC1_EXTENSION_UNIT:
- /* UAC2_PROCESSING_UNIT_V2 has the same value */
- if (state->mixer->protocol == UAC_VERSION_1)
- return parse_audio_extension_unit(state, unitid, p1);
- else /* UAC_VERSION_2 */
- return parse_audio_processing_unit(state, unitid, p1);
- default:
- snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
- return -EINVAL;
- }
-}
-
-static void snd_usb_mixer_free(struct usb_mixer_interface *mixer)
-{
- kfree(mixer->id_elems);
- if (mixer->urb) {
- kfree(mixer->urb->transfer_buffer);
- usb_free_urb(mixer->urb);
- }
- usb_free_urb(mixer->rc_urb);
- kfree(mixer->rc_setup_packet);
- kfree(mixer);
-}
-
-static int snd_usb_mixer_dev_free(struct snd_device *device)
-{
- struct usb_mixer_interface *mixer = device->device_data;
- snd_usb_mixer_free(mixer);
- return 0;
-}
-
-/*
- * create mixer controls
- *
- * walk through all UAC_OUTPUT_TERMINAL descriptors to search for mixers
- */
-static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
-{
- struct mixer_build state;
- int err;
- const struct usbmix_ctl_map *map;
- void *p;
-
- memset(&state, 0, sizeof(state));
- state.chip = mixer->chip;
- state.mixer = mixer;
- state.buffer = mixer->hostif->extra;
- state.buflen = mixer->hostif->extralen;
-
- /* check the mapping table */
- for (map = usbmix_ctl_maps; map->id; map++) {
- if (map->id == state.chip->usb_id) {
- state.map = map->map;
- state.selector_map = map->selector_map;
- mixer->ignore_ctl_error = map->ignore_ctl_error;
- break;
- }
- }
-
- p = NULL;
- while ((p = snd_usb_find_csint_desc(mixer->hostif->extra, mixer->hostif->extralen,
- p, UAC_OUTPUT_TERMINAL)) != NULL) {
- if (mixer->protocol == UAC_VERSION_1) {
- struct uac1_output_terminal_descriptor *desc = p;
-
- if (desc->bLength < sizeof(*desc))
- continue; /* invalid descriptor? */
- set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */
- state.oterm.id = desc->bTerminalID;
- state.oterm.type = le16_to_cpu(desc->wTerminalType);
- state.oterm.name = desc->iTerminal;
- err = parse_audio_unit(&state, desc->bSourceID);
- if (err < 0)
- return err;
- } else { /* UAC_VERSION_2 */
- struct uac2_output_terminal_descriptor *desc = p;
-
- if (desc->bLength < sizeof(*desc))
- continue; /* invalid descriptor? */
- set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */
- state.oterm.id = desc->bTerminalID;
- state.oterm.type = le16_to_cpu(desc->wTerminalType);
- state.oterm.name = desc->iTerminal;
- err = parse_audio_unit(&state, desc->bSourceID);
- if (err < 0)
- return err;
-
- /* for UAC2, use the same approach to also add the clock selectors */
- err = parse_audio_unit(&state, desc->bCSourceID);
- if (err < 0)
- return err;
- }
- }
-
- return 0;
-}
-
-void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid)
-{
- struct usb_mixer_elem_info *info;
-
- for (info = mixer->id_elems[unitid]; info; info = info->next_id_elem)
- snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- info->elem_id);
-}
-
-static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer,
- int unitid,
- struct usb_mixer_elem_info *cval)
-{
- static char *val_types[] = {"BOOLEAN", "INV_BOOLEAN",
- "S8", "U8", "S16", "U16"};
- snd_iprintf(buffer, " Unit: %i\n", unitid);
- if (cval->elem_id)
- snd_iprintf(buffer, " Control: name=\"%s\", index=%i\n",
- cval->elem_id->name, cval->elem_id->index);
- snd_iprintf(buffer, " Info: id=%i, control=%i, cmask=0x%x, "
- "channels=%i, type=\"%s\"\n", cval->id,
- cval->control, cval->cmask, cval->channels,
- val_types[cval->val_type]);
- snd_iprintf(buffer, " Volume: min=%i, max=%i, dBmin=%i, dBmax=%i\n",
- cval->min, cval->max, cval->dBmin, cval->dBmax);
-}
-
-static void snd_usb_mixer_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_usb_audio *chip = entry->private_data;
- struct usb_mixer_interface *mixer;
- struct usb_mixer_elem_info *cval;
- int unitid;
-
- list_for_each_entry(mixer, &chip->mixer_list, list) {
- snd_iprintf(buffer,
- "USB Mixer: usb_id=0x%08x, ctrlif=%i, ctlerr=%i\n",
- chip->usb_id, snd_usb_ctrl_intf(chip),
- mixer->ignore_ctl_error);
- snd_iprintf(buffer, "Card: %s\n", chip->card->longname);
- for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) {
- for (cval = mixer->id_elems[unitid]; cval;
- cval = cval->next_id_elem)
- snd_usb_mixer_dump_cval(buffer, unitid, cval);
- }
- }
-}
-
-static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer,
- int attribute, int value, int index)
-{
- struct usb_mixer_elem_info *info;
- __u8 unitid = (index >> 8) & 0xff;
- __u8 control = (value >> 8) & 0xff;
- __u8 channel = value & 0xff;
-
- if (channel >= MAX_CHANNELS) {
- snd_printk(KERN_DEBUG "%s(): bogus channel number %d\n",
- __func__, channel);
- return;
- }
-
- for (info = mixer->id_elems[unitid]; info; info = info->next_id_elem) {
- if (info->control != control)
- continue;
-
- switch (attribute) {
- case UAC2_CS_CUR:
- /* invalidate cache, so the value is read from the device */
- if (channel)
- info->cached &= ~(1 << channel);
- else /* master channel */
- info->cached = 0;
-
- snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- info->elem_id);
- break;
-
- case UAC2_CS_RANGE:
- /* TODO */
- break;
-
- case UAC2_CS_MEM:
- /* TODO */
- break;
-
- default:
- snd_printk(KERN_DEBUG "unknown attribute %d in interrupt\n",
- attribute);
- break;
- } /* switch */
- }
-}
-
-static void snd_usb_mixer_interrupt(struct urb *urb)
-{
- struct usb_mixer_interface *mixer = urb->context;
- int len = urb->actual_length;
- int ustatus = urb->status;
-
- if (ustatus != 0)
- goto requeue;
-
- if (mixer->protocol == UAC_VERSION_1) {
- struct uac1_status_word *status;
-
- for (status = urb->transfer_buffer;
- len >= sizeof(*status);
- len -= sizeof(*status), status++) {
- snd_printd(KERN_DEBUG "status interrupt: %02x %02x\n",
- status->bStatusType,
- status->bOriginator);
-
- /* ignore any notifications not from the control interface */
- if ((status->bStatusType & UAC1_STATUS_TYPE_ORIG_MASK) !=
- UAC1_STATUS_TYPE_ORIG_AUDIO_CONTROL_IF)
- continue;
-
- if (status->bStatusType & UAC1_STATUS_TYPE_MEM_CHANGED)
- snd_usb_mixer_rc_memory_change(mixer, status->bOriginator);
- else
- snd_usb_mixer_notify_id(mixer, status->bOriginator);
- }
- } else { /* UAC_VERSION_2 */
- struct uac2_interrupt_data_msg *msg;
-
- for (msg = urb->transfer_buffer;
- len >= sizeof(*msg);
- len -= sizeof(*msg), msg++) {
- /* drop vendor specific and endpoint requests */
- if ((msg->bInfo & UAC2_INTERRUPT_DATA_MSG_VENDOR) ||
- (msg->bInfo & UAC2_INTERRUPT_DATA_MSG_EP))
- continue;
-
- snd_usb_mixer_interrupt_v2(mixer, msg->bAttribute,
- le16_to_cpu(msg->wValue),
- le16_to_cpu(msg->wIndex));
- }
- }
-
-requeue:
- if (ustatus != -ENOENT && ustatus != -ECONNRESET && ustatus != -ESHUTDOWN) {
- urb->dev = mixer->chip->dev;
- usb_submit_urb(urb, GFP_ATOMIC);
- }
-}
-
-/* stop any bus activity of a mixer */
-void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer)
-{
- usb_kill_urb(mixer->urb);
- usb_kill_urb(mixer->rc_urb);
-}
-
-int snd_usb_mixer_activate(struct usb_mixer_interface *mixer)
-{
- int err;
-
- if (mixer->urb) {
- err = usb_submit_urb(mixer->urb, GFP_NOIO);
- if (err < 0)
- return err;
- }
-
- return 0;
-}
-
-/* create the handler for the optional status interrupt endpoint */
-static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)
-{
- struct usb_endpoint_descriptor *ep;
- void *transfer_buffer;
- int buffer_length;
- unsigned int epnum;
-
- /* we need one interrupt input endpoint */
- if (get_iface_desc(mixer->hostif)->bNumEndpoints < 1)
- return 0;
- ep = get_endpoint(mixer->hostif, 0);
- if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_int(ep))
- return 0;
-
- epnum = usb_endpoint_num(ep);
- buffer_length = le16_to_cpu(ep->wMaxPacketSize);
- transfer_buffer = kmalloc(buffer_length, GFP_KERNEL);
- if (!transfer_buffer)
- return -ENOMEM;
- mixer->urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!mixer->urb) {
- kfree(transfer_buffer);
- return -ENOMEM;
- }
- usb_fill_int_urb(mixer->urb, mixer->chip->dev,
- usb_rcvintpipe(mixer->chip->dev, epnum),
- transfer_buffer, buffer_length,
- snd_usb_mixer_interrupt, mixer, ep->bInterval);
- usb_submit_urb(mixer->urb, GFP_KERNEL);
- return 0;
-}
-
-int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
- int ignore_error)
-{
- static struct snd_device_ops dev_ops = {
- .dev_free = snd_usb_mixer_dev_free
- };
- struct usb_mixer_interface *mixer;
- struct snd_info_entry *entry;
- int err;
-
- strcpy(chip->card->mixername, "USB Mixer");
-
- mixer = kzalloc(sizeof(*mixer), GFP_KERNEL);
- if (!mixer)
- return -ENOMEM;
- mixer->chip = chip;
- mixer->ignore_ctl_error = ignore_error;
- mixer->id_elems = kcalloc(MAX_ID_ELEMS, sizeof(*mixer->id_elems),
- GFP_KERNEL);
- if (!mixer->id_elems) {
- kfree(mixer);
- return -ENOMEM;
- }
-
- mixer->hostif = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0];
- switch (get_iface_desc(mixer->hostif)->bInterfaceProtocol) {
- case UAC_VERSION_1:
- default:
- mixer->protocol = UAC_VERSION_1;
- break;
- case UAC_VERSION_2:
- mixer->protocol = UAC_VERSION_2;
- break;
- }
-
- if ((err = snd_usb_mixer_controls(mixer)) < 0 ||
- (err = snd_usb_mixer_status_create(mixer)) < 0)
- goto _error;
-
- snd_usb_mixer_apply_create_quirk(mixer);
-
- err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops);
- if (err < 0)
- goto _error;
-
- if (list_empty(&chip->mixer_list) &&
- !snd_card_proc_new(chip->card, "usbmixer", &entry))
- snd_info_set_text_ops(entry, chip, snd_usb_mixer_proc_read);
-
- list_add(&mixer->list, &chip->mixer_list);
- return 0;
-
-_error:
- snd_usb_mixer_free(mixer);
- return err;
-}
-
-void snd_usb_mixer_disconnect(struct list_head *p)
-{
- struct usb_mixer_interface *mixer;
-
- mixer = list_entry(p, struct usb_mixer_interface, list);
- usb_kill_urb(mixer->urb);
- usb_kill_urb(mixer->rc_urb);
-}
diff --git a/ANDROID_3.4.5/sound/usb/mixer.h b/ANDROID_3.4.5/sound/usb/mixer.h
deleted file mode 100644
index 81b2d8a3..00000000
--- a/ANDROID_3.4.5/sound/usb/mixer.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef __USBMIXER_H
-#define __USBMIXER_H
-
-struct usb_mixer_interface {
- struct snd_usb_audio *chip;
- struct usb_host_interface *hostif;
- struct list_head list;
- unsigned int ignore_ctl_error;
- struct urb *urb;
- /* array[MAX_ID_ELEMS], indexed by unit id */
- struct usb_mixer_elem_info **id_elems;
-
- /* the usb audio specification version this interface complies to */
- int protocol;
-
- /* Sound Blaster remote control stuff */
- const struct rc_config *rc_cfg;
- u32 rc_code;
- wait_queue_head_t rc_waitq;
- struct urb *rc_urb;
- struct usb_ctrlrequest *rc_setup_packet;
- u8 rc_buffer[6];
-
- u8 audigy2nx_leds[3];
- u8 xonar_u1_status;
-};
-
-#define MAX_CHANNELS 16 /* max logical channels */
-
-enum {
- USB_MIXER_BOOLEAN,
- USB_MIXER_INV_BOOLEAN,
- USB_MIXER_S8,
- USB_MIXER_U8,
- USB_MIXER_S16,
- USB_MIXER_U16,
-};
-
-struct usb_mixer_elem_info {
- struct usb_mixer_interface *mixer;
- struct usb_mixer_elem_info *next_id_elem; /* list of controls with same id */
- struct snd_ctl_elem_id *elem_id;
- unsigned int id;
- unsigned int control; /* CS or ICN (high byte) */
- unsigned int cmask; /* channel mask bitmap: 0 = master */
- unsigned int ch_readonly;
- unsigned int master_readonly;
- int channels;
- int val_type;
- int min, max, res;
- int dBmin, dBmax;
- int cached;
- int cache_val[MAX_CHANNELS];
- u8 initialized;
-};
-
-int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
- int ignore_error);
-void snd_usb_mixer_disconnect(struct list_head *p);
-
-void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid);
-
-int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
- int request, int validx, int value_set);
-void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer);
-int snd_usb_mixer_activate(struct usb_mixer_interface *mixer);
-
-int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer,
- struct snd_kcontrol *kctl);
-
-#endif /* __USBMIXER_H */
diff --git a/ANDROID_3.4.5/sound/usb/mixer_maps.c b/ANDROID_3.4.5/sound/usb/mixer_maps.c
deleted file mode 100644
index f1324c42..00000000
--- a/ANDROID_3.4.5/sound/usb/mixer_maps.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Additional mixer mapping
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-struct usbmix_dB_map {
- u32 min;
- u32 max;
-};
-
-struct usbmix_name_map {
- int id;
- const char *name;
- int control;
- struct usbmix_dB_map *dB;
-};
-
-struct usbmix_selector_map {
- int id;
- int count;
- const char **names;
-};
-
-struct usbmix_ctl_map {
- u32 id;
- const struct usbmix_name_map *map;
- const struct usbmix_selector_map *selector_map;
- int ignore_ctl_error;
-};
-
-/*
- * USB control mappers for SB Exitigy
- */
-
-/*
- * Topology of SB Extigy (see on the wide screen :)
-
-USB_IN[1] --->FU[2]------------------------------+->MU[16]-->PU[17]-+->FU[18]--+->EU[27]--+->EU[21]-->FU[22]--+->FU[23] > Dig_OUT[24]
- ^ | | | |
-USB_IN[3] -+->SU[5]-->FU[6]--+->MU[14] ->PU[15]->+ | | | +->FU[25] > Dig_OUT[26]
- ^ ^ | | | |
-Dig_IN[4] -+ | | | | +->FU[28]---------------------> Spk_OUT[19]
- | | | |
-Lin-IN[7] -+-->FU[8]---------+ | | +----------------------------------------> Hph_OUT[20]
- | | |
-Mic-IN[9] --+->FU[10]----------------------------+ |
- || |
- || +----------------------------------------------------+
- VV V
- ++--+->SU[11]-->FU[12] --------------------------------------------------------------------------------------> USB_OUT[13]
-*/
-
-static struct usbmix_name_map extigy_map[] = {
- /* 1: IT pcm */
- { 2, "PCM Playback" }, /* FU */
- /* 3: IT pcm */
- /* 4: IT digital in */
- { 5, NULL }, /* DISABLED: this seems to be bogus on some firmware */
- { 6, "Digital In" }, /* FU */
- /* 7: IT line */
- { 8, "Line Playback" }, /* FU */
- /* 9: IT mic */
- { 10, "Mic Playback" }, /* FU */
- { 11, "Capture Source" }, /* SU */
- { 12, "Capture" }, /* FU */
- /* 13: OT pcm capture */
- /* 14: MU (w/o controls) */
- /* 15: PU (3D enh) */
- /* 16: MU (w/o controls) */
- { 17, NULL, 1 }, /* DISABLED: PU-switch (any effect?) */
- { 17, "Channel Routing", 2 }, /* PU: mode select */
- { 18, "Tone Control - Bass", UAC_FU_BASS }, /* FU */
- { 18, "Tone Control - Treble", UAC_FU_TREBLE }, /* FU */
- { 18, "Master Playback" }, /* FU; others */
- /* 19: OT speaker */
- /* 20: OT headphone */
- { 21, NULL }, /* DISABLED: EU (for what?) */
- { 22, "Digital Out Playback" }, /* FU */
- { 23, "Digital Out1 Playback" }, /* FU */ /* FIXME: corresponds to 24 */
- /* 24: OT digital out */
- { 25, "IEC958 Optical Playback" }, /* FU */
- { 26, "IEC958 Optical Playback" }, /* OT */
- { 27, NULL }, /* DISABLED: EU (for what?) */
- /* 28: FU speaker (mute) */
- { 29, NULL }, /* Digital Input Playback Source? */
- { 0 } /* terminator */
-};
-
-/* Sound Blaster MP3+ controls mapping
- * The default mixer channels have totally misleading names,
- * e.g. no Master and fake PCM volume
- * Pavel Mihaylov <bin@bash.info>
- */
-static struct usbmix_dB_map mp3plus_dB_1 = {-4781, 0}; /* just guess */
-static struct usbmix_dB_map mp3plus_dB_2 = {-1781, 618}; /* just guess */
-
-static struct usbmix_name_map mp3plus_map[] = {
- /* 1: IT pcm */
- /* 2: IT mic */
- /* 3: IT line */
- /* 4: IT digital in */
- /* 5: OT digital out */
- /* 6: OT speaker */
- /* 7: OT pcm capture */
- { 8, "Capture Source" }, /* FU, default PCM Capture Source */
- /* (Mic, Input 1 = Line input, Input 2 = Optical input) */
- { 9, "Master Playback" }, /* FU, default Speaker 1 */
- /* { 10, "Mic Capture", 1 }, */ /* FU, Mic Capture */
- { 10, /* "Mic Capture", */ NULL, 2, .dB = &mp3plus_dB_2 },
- /* FU, Mic Capture */
- { 10, "Mic Boost", 7 }, /* FU, default Auto Gain Input */
- { 11, "Line Capture", .dB = &mp3plus_dB_2 },
- /* FU, default PCM Capture */
- { 12, "Digital In Playback" }, /* FU, default PCM 1 */
- { 13, /* "Mic Playback", */ .dB = &mp3plus_dB_1 },
- /* FU, default Mic Playback */
- { 14, "Line Playback", .dB = &mp3plus_dB_1 }, /* FU, default Speaker */
- /* 15: MU */
- { 0 } /* terminator */
-};
-
-/* Topology of SB Audigy 2 NX
-
- +----------------------------->EU[27]--+
- | v
- | +----------------------------------->SU[29]---->FU[22]-->Dig_OUT[24]
- | | ^
-USB_IN[1]-+------------+ +->EU[17]->+->FU[11]-+
- | v | v |
-Dig_IN[4]---+->FU[6]-->MU[16]->FU[18]-+->EU[21]->SU[31]----->FU[30]->Hph_OUT[20]
- | ^ | |
-Lin_IN[7]-+--->FU[8]---+ +->EU[23]->FU[28]------------->Spk_OUT[19]
- | | v
- +--->FU[12]------------------------------------->SU[14]--->USB_OUT[15]
- | ^
- +->FU[13]--------------------------------------+
-*/
-static struct usbmix_name_map audigy2nx_map[] = {
- /* 1: IT pcm playback */
- /* 4: IT digital in */
- { 6, "Digital In Playback" }, /* FU */
- /* 7: IT line in */
- { 8, "Line Playback" }, /* FU */
- { 11, "What-U-Hear Capture" }, /* FU */
- { 12, "Line Capture" }, /* FU */
- { 13, "Digital In Capture" }, /* FU */
- { 14, "Capture Source" }, /* SU */
- /* 15: OT pcm capture */
- /* 16: MU w/o controls */
- { 17, NULL }, /* DISABLED: EU (for what?) */
- { 18, "Master Playback" }, /* FU */
- /* 19: OT speaker */
- /* 20: OT headphone */
- { 21, NULL }, /* DISABLED: EU (for what?) */
- { 22, "Digital Out Playback" }, /* FU */
- { 23, NULL }, /* DISABLED: EU (for what?) */
- /* 24: OT digital out */
- { 27, NULL }, /* DISABLED: EU (for what?) */
- { 28, "Speaker Playback" }, /* FU */
- { 29, "Digital Out Source" }, /* SU */
- { 30, "Headphone Playback" }, /* FU */
- { 31, "Headphone Source" }, /* SU */
- { 0 } /* terminator */
-};
-
-static struct usbmix_selector_map audigy2nx_selectors[] = {
- {
- .id = 14, /* Capture Source */
- .count = 3,
- .names = (const char*[]) {"Line", "Digital In", "What-U-Hear"}
- },
- {
- .id = 29, /* Digital Out Source */
- .count = 3,
- .names = (const char*[]) {"Front", "PCM", "Digital In"}
- },
- {
- .id = 31, /* Headphone Source */
- .count = 2,
- .names = (const char*[]) {"Front", "Side"}
- },
- { 0 } /* terminator */
-};
-
-/* Creative SoundBlaster Live! 24-bit External */
-static struct usbmix_name_map live24ext_map[] = {
- /* 2: PCM Playback Volume */
- { 5, "Mic Capture" }, /* FU, default PCM Capture Volume */
- { 0 } /* terminator */
-};
-
-/* LineX FM Transmitter entry - needed to bypass controls bug */
-static struct usbmix_name_map linex_map[] = {
- /* 1: IT pcm */
- /* 2: OT Speaker */
- { 3, "Master" }, /* FU: master volume - left / right / mute */
- { 0 } /* terminator */
-};
-
-static struct usbmix_name_map maya44_map[] = {
- /* 1: IT line */
- { 2, "Line Playback" }, /* FU */
- /* 3: IT line */
- { 4, "Line Playback" }, /* FU */
- /* 5: IT pcm playback */
- /* 6: MU */
- { 7, "Master Playback" }, /* FU */
- /* 8: OT speaker */
- /* 9: IT line */
- { 10, "Line Capture" }, /* FU */
- /* 11: MU */
- /* 12: OT pcm capture */
- { }
-};
-
-/* Section "justlink_map" below added by James Courtier-Dutton <James@superbug.demon.co.uk>
- * sourced from Maplin Electronics (http://www.maplin.co.uk), part number A56AK
- * Part has 2 connectors that act as a single output. (TOSLINK Optical for digital out, and 3.5mm Jack for Analogue out.)
- * The USB Mixer publishes a Microphone and extra Volume controls for it, but none exist on the device,
- * so this map removes all unwanted sliders from alsamixer
- */
-
-static struct usbmix_name_map justlink_map[] = {
- /* 1: IT pcm playback */
- /* 2: Not present */
- { 3, NULL}, /* IT mic (No mic input on device) */
- /* 4: Not present */
- /* 5: OT speacker */
- /* 6: OT pcm capture */
- { 7, "Master Playback" }, /* Mute/volume for speaker */
- { 8, NULL }, /* Capture Switch (No capture inputs on device) */
- { 9, NULL }, /* Capture Mute/volume (No capture inputs on device */
- /* 0xa: Not present */
- /* 0xb: MU (w/o controls) */
- { 0xc, NULL }, /* Mic feedback Mute/volume (No capture inputs on device) */
- { 0 } /* terminator */
-};
-
-/* TerraTec Aureon 5.1 MkII USB */
-static struct usbmix_name_map aureon_51_2_map[] = {
- /* 1: IT USB */
- /* 2: IT Mic */
- /* 3: IT Line */
- /* 4: IT SPDIF */
- /* 5: OT SPDIF */
- /* 6: OT Speaker */
- /* 7: OT USB */
- { 8, "Capture Source" }, /* SU */
- { 9, "Master Playback" }, /* FU */
- { 10, "Mic Capture" }, /* FU */
- { 11, "Line Capture" }, /* FU */
- { 12, "IEC958 In Capture" }, /* FU */
- { 13, "Mic Playback" }, /* FU */
- { 14, "Line Playback" }, /* FU */
- /* 15: MU */
- {} /* terminator */
-};
-
-static struct usbmix_name_map scratch_live_map[] = {
- /* 1: IT Line 1 (USB streaming) */
- /* 2: OT Line 1 (Speaker) */
- /* 3: IT Line 1 (Line connector) */
- { 4, "Line 1 In" }, /* FU */
- /* 5: OT Line 1 (USB streaming) */
- /* 6: IT Line 2 (USB streaming) */
- /* 7: OT Line 2 (Speaker) */
- /* 8: IT Line 2 (Line connector) */
- { 9, "Line 2 In" }, /* FU */
- /* 10: OT Line 2 (USB streaming) */
- /* 11: IT Mic (Line connector) */
- /* 12: OT Mic (USB streaming) */
- { 0 } /* terminator */
-};
-
-/* "Gamesurround Muse Pocket LT" looks same like "Sound Blaster MP3+"
- * most importand difference is SU[8], it should be set to "Capture Source"
- * to make alsamixer and PA working properly.
- * FIXME: or mp3plus_map should use "Capture Source" too,
- * so this maps can be merget
- */
-static struct usbmix_name_map hercules_usb51_map[] = {
- { 8, "Capture Source" }, /* SU, default "PCM Capture Source" */
- { 9, "Master Playback" }, /* FU, default "Speaker Playback" */
- { 10, "Mic Boost", 7 }, /* FU, default "Auto Gain Input" */
- { 11, "Line Capture" }, /* FU, default "PCM Capture" */
- { 13, "Mic Bypass Playback" }, /* FU, default "Mic Playback" */
- { 14, "Line Bypass Playback" }, /* FU, default "Line Playback" */
- { 0 } /* terminator */
-};
-
-/*
- * Control map entries
- */
-
-static struct usbmix_ctl_map usbmix_ctl_maps[] = {
- {
- .id = USB_ID(0x041e, 0x3000),
- .map = extigy_map,
- .ignore_ctl_error = 1,
- },
- {
- .id = USB_ID(0x041e, 0x3010),
- .map = mp3plus_map,
- },
- {
- .id = USB_ID(0x041e, 0x3020),
- .map = audigy2nx_map,
- .selector_map = audigy2nx_selectors,
- },
- {
- .id = USB_ID(0x041e, 0x3040),
- .map = live24ext_map,
- },
- {
- .id = USB_ID(0x041e, 0x3048),
- .map = audigy2nx_map,
- .selector_map = audigy2nx_selectors,
- },
- {
- /* Hercules DJ Console (Windows Edition) */
- .id = USB_ID(0x06f8, 0xb000),
- .ignore_ctl_error = 1,
- },
- {
- /* Hercules DJ Console (Macintosh Edition) */
- .id = USB_ID(0x06f8, 0xd002),
- .ignore_ctl_error = 1,
- },
- {
- /* Hercules Gamesurround Muse Pocket LT
- * (USB 5.1 Channel Audio Adapter)
- */
- .id = USB_ID(0x06f8, 0xc000),
- .map = hercules_usb51_map,
- },
- {
- .id = USB_ID(0x08bb, 0x2702),
- .map = linex_map,
- .ignore_ctl_error = 1,
- },
- {
- .id = USB_ID(0x0a92, 0x0091),
- .map = maya44_map,
- },
- {
- .id = USB_ID(0x0c45, 0x1158),
- .map = justlink_map,
- },
- {
- .id = USB_ID(0x0ccd, 0x0028),
- .map = aureon_51_2_map,
- },
- {
- .id = USB_ID(0x13e5, 0x0001),
- .map = scratch_live_map,
- .ignore_ctl_error = 1,
- },
- { 0 } /* terminator */
-};
-
diff --git a/ANDROID_3.4.5/sound/usb/mixer_quirks.c b/ANDROID_3.4.5/sound/usb/mixer_quirks.c
deleted file mode 100644
index ab125ee0..00000000
--- a/ANDROID_3.4.5/sound/usb/mixer_quirks.c
+++ /dev/null
@@ -1,654 +0,0 @@
-/*
- * USB Audio Driver for ALSA
- *
- * Quirks and vendor-specific extensions for mixer interfaces
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * Many codes borrowed from audio.c by
- * Alan Cox (alan@lxorguk.ukuu.org.uk)
- * Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/usb/audio.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/hwdep.h>
-#include <sound/info.h>
-
-#include "usbaudio.h"
-#include "mixer.h"
-#include "mixer_quirks.h"
-#include "helper.h"
-
-extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl;
-
-/*
- * Sound Blaster remote control configuration
- *
- * format of remote control data:
- * Extigy: xx 00
- * Audigy 2 NX: 06 80 xx 00 00 00
- * Live! 24-bit: 06 80 xx yy 22 83
- */
-static const struct rc_config {
- u32 usb_id;
- u8 offset;
- u8 length;
- u8 packet_length;
- u8 min_packet_length; /* minimum accepted length of the URB result */
- u8 mute_mixer_id;
- u32 mute_code;
-} rc_configs[] = {
- { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */
- { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */
- { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */
- { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 */
- { USB_ID(0x041e, 0x30df), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 Pro */
- { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */
-};
-
-static void snd_usb_soundblaster_remote_complete(struct urb *urb)
-{
- struct usb_mixer_interface *mixer = urb->context;
- const struct rc_config *rc = mixer->rc_cfg;
- u32 code;
-
- if (urb->status < 0 || urb->actual_length < rc->min_packet_length)
- return;
-
- code = mixer->rc_buffer[rc->offset];
- if (rc->length == 2)
- code |= mixer->rc_buffer[rc->offset + 1] << 8;
-
- /* the Mute button actually changes the mixer control */
- if (code == rc->mute_code)
- snd_usb_mixer_notify_id(mixer, rc->mute_mixer_id);
- mixer->rc_code = code;
- wmb();
- wake_up(&mixer->rc_waitq);
-}
-
-static long snd_usb_sbrc_hwdep_read(struct snd_hwdep *hw, char __user *buf,
- long count, loff_t *offset)
-{
- struct usb_mixer_interface *mixer = hw->private_data;
- int err;
- u32 rc_code;
-
- if (count != 1 && count != 4)
- return -EINVAL;
- err = wait_event_interruptible(mixer->rc_waitq,
- (rc_code = xchg(&mixer->rc_code, 0)) != 0);
- if (err == 0) {
- if (count == 1)
- err = put_user(rc_code, buf);
- else
- err = put_user(rc_code, (u32 __user *)buf);
- }
- return err < 0 ? err : count;
-}
-
-static unsigned int snd_usb_sbrc_hwdep_poll(struct snd_hwdep *hw, struct file *file,
- poll_table *wait)
-{
- struct usb_mixer_interface *mixer = hw->private_data;
-
- poll_wait(file, &mixer->rc_waitq, wait);
- return mixer->rc_code ? POLLIN | POLLRDNORM : 0;
-}
-
-static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
-{
- struct snd_hwdep *hwdep;
- int err, len, i;
-
- for (i = 0; i < ARRAY_SIZE(rc_configs); ++i)
- if (rc_configs[i].usb_id == mixer->chip->usb_id)
- break;
- if (i >= ARRAY_SIZE(rc_configs))
- return 0;
- mixer->rc_cfg = &rc_configs[i];
-
- len = mixer->rc_cfg->packet_length;
-
- init_waitqueue_head(&mixer->rc_waitq);
- err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep);
- if (err < 0)
- return err;
- snprintf(hwdep->name, sizeof(hwdep->name),
- "%s remote control", mixer->chip->card->shortname);
- hwdep->iface = SNDRV_HWDEP_IFACE_SB_RC;
- hwdep->private_data = mixer;
- hwdep->ops.read = snd_usb_sbrc_hwdep_read;
- hwdep->ops.poll = snd_usb_sbrc_hwdep_poll;
- hwdep->exclusive = 1;
-
- mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!mixer->rc_urb)
- return -ENOMEM;
- mixer->rc_setup_packet = kmalloc(sizeof(*mixer->rc_setup_packet), GFP_KERNEL);
- if (!mixer->rc_setup_packet) {
- usb_free_urb(mixer->rc_urb);
- mixer->rc_urb = NULL;
- return -ENOMEM;
- }
- mixer->rc_setup_packet->bRequestType =
- USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
- mixer->rc_setup_packet->bRequest = UAC_GET_MEM;
- mixer->rc_setup_packet->wValue = cpu_to_le16(0);
- mixer->rc_setup_packet->wIndex = cpu_to_le16(0);
- mixer->rc_setup_packet->wLength = cpu_to_le16(len);
- usb_fill_control_urb(mixer->rc_urb, mixer->chip->dev,
- usb_rcvctrlpipe(mixer->chip->dev, 0),
- (u8*)mixer->rc_setup_packet, mixer->rc_buffer, len,
- snd_usb_soundblaster_remote_complete, mixer);
- return 0;
-}
-
-#define snd_audigy2nx_led_info snd_ctl_boolean_mono_info
-
-static int snd_audigy2nx_led_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
- int index = kcontrol->private_value;
-
- ucontrol->value.integer.value[0] = mixer->audigy2nx_leds[index];
- return 0;
-}
-
-static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
- int index = kcontrol->private_value;
- int value = ucontrol->value.integer.value[0];
- int err, changed;
-
- if (value > 1)
- return -EINVAL;
- changed = value != mixer->audigy2nx_leds[index];
- if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042))
- err = snd_usb_ctl_msg(mixer->chip->dev,
- usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
- !value, 0, NULL, 0);
- /* USB X-Fi S51 Pro */
- if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df))
- err = snd_usb_ctl_msg(mixer->chip->dev,
- usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
- !value, 0, NULL, 0);
- else
- err = snd_usb_ctl_msg(mixer->chip->dev,
- usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
- value, index + 2, NULL, 0);
- if (err < 0)
- return err;
- mixer->audigy2nx_leds[index] = value;
- return changed;
-}
-
-static struct snd_kcontrol_new snd_audigy2nx_controls[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "CMSS LED Switch",
- .info = snd_audigy2nx_led_info,
- .get = snd_audigy2nx_led_get,
- .put = snd_audigy2nx_led_put,
- .private_value = 0,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Power LED Switch",
- .info = snd_audigy2nx_led_info,
- .get = snd_audigy2nx_led_get,
- .put = snd_audigy2nx_led_put,
- .private_value = 1,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Dolby Digital LED Switch",
- .info = snd_audigy2nx_led_info,
- .get = snd_audigy2nx_led_get,
- .put = snd_audigy2nx_led_put,
- .private_value = 2,
- },
-};
-
-static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
-{
- int i, err;
-
- for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) {
- /* USB X-Fi S51 doesn't have a CMSS LED */
- if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0)
- continue;
- /* USB X-Fi S51 Pro doesn't have one either */
- if ((mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) && i == 0)
- continue;
- if (i > 1 && /* Live24ext has 2 LEDs only */
- (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
- mixer->chip->usb_id == USB_ID(0x041e, 0x3042) ||
- mixer->chip->usb_id == USB_ID(0x041e, 0x30df) ||
- mixer->chip->usb_id == USB_ID(0x041e, 0x3048)))
- break;
- err = snd_ctl_add(mixer->chip->card,
- snd_ctl_new1(&snd_audigy2nx_controls[i], mixer));
- if (err < 0)
- return err;
- }
- mixer->audigy2nx_leds[1] = 1; /* Power LED is on by default */
- return 0;
-}
-
-static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- static const struct sb_jack {
- int unitid;
- const char *name;
- } jacks_audigy2nx[] = {
- {4, "dig in "},
- {7, "line in"},
- {19, "spk out"},
- {20, "hph out"},
- {-1, NULL}
- }, jacks_live24ext[] = {
- {4, "line in"}, /* &1=Line, &2=Mic*/
- {3, "hph out"}, /* headphones */
- {0, "RC "}, /* last command, 6 bytes see rc_config above */
- {-1, NULL}
- };
- const struct sb_jack *jacks;
- struct usb_mixer_interface *mixer = entry->private_data;
- int i, err;
- u8 buf[3];
-
- snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname);
- if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020))
- jacks = jacks_audigy2nx;
- else if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
- mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
- jacks = jacks_live24ext;
- else
- return;
-
- for (i = 0; jacks[i].name; ++i) {
- snd_iprintf(buffer, "%s: ", jacks[i].name);
- err = snd_usb_ctl_msg(mixer->chip->dev,
- usb_rcvctrlpipe(mixer->chip->dev, 0),
- UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
- USB_RECIP_INTERFACE, 0,
- jacks[i].unitid << 8, buf, 3);
- if (err == 3 && (buf[0] == 3 || buf[0] == 6))
- snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
- else
- snd_iprintf(buffer, "?\n");
- }
-}
-
-static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = !!(mixer->xonar_u1_status & 0x02);
- return 0;
-}
-
-static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
- u8 old_status, new_status;
- int err, changed;
-
- old_status = mixer->xonar_u1_status;
- if (ucontrol->value.integer.value[0])
- new_status = old_status | 0x02;
- else
- new_status = old_status & ~0x02;
- changed = new_status != old_status;
- err = snd_usb_ctl_msg(mixer->chip->dev,
- usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
- 50, 0, &new_status, 1);
- if (err < 0)
- return err;
- mixer->xonar_u1_status = new_status;
- return changed;
-}
-
-static struct snd_kcontrol_new snd_xonar_u1_output_switch = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Digital Playback Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = snd_xonar_u1_switch_get,
- .put = snd_xonar_u1_switch_put,
-};
-
-static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
-{
- int err;
-
- err = snd_ctl_add(mixer->chip->card,
- snd_ctl_new1(&snd_xonar_u1_output_switch, mixer));
- if (err < 0)
- return err;
- mixer->xonar_u1_status = 0x05;
- return 0;
-}
-
-/* Native Instruments device quirks */
-
-#define _MAKE_NI_CONTROL(bRequest,wIndex) ((bRequest) << 16 | (wIndex))
-
-static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
- struct usb_device *dev = mixer->chip->dev;
- u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
- u16 wIndex = kcontrol->private_value & 0xffff;
- u8 tmp;
-
- int ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
- 0, cpu_to_le16(wIndex),
- &tmp, sizeof(tmp), 1000);
-
- if (ret < 0) {
- snd_printk(KERN_ERR
- "unable to issue vendor read request (ret = %d)", ret);
- return ret;
- }
-
- ucontrol->value.integer.value[0] = tmp;
-
- return 0;
-}
-
-static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
- struct usb_device *dev = mixer->chip->dev;
- u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
- u16 wIndex = kcontrol->private_value & 0xffff;
- u16 wValue = ucontrol->value.integer.value[0];
-
- int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
- cpu_to_le16(wValue), cpu_to_le16(wIndex),
- NULL, 0, 1000);
-
- if (ret < 0) {
- snd_printk(KERN_ERR
- "unable to issue vendor write request (ret = %d)", ret);
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_kcontrol_new snd_nativeinstruments_ta6_mixers[] = {
- {
- .name = "Direct Thru Channel A",
- .private_value = _MAKE_NI_CONTROL(0x01, 0x03),
- },
- {
- .name = "Direct Thru Channel B",
- .private_value = _MAKE_NI_CONTROL(0x01, 0x05),
- },
- {
- .name = "Phono Input Channel A",
- .private_value = _MAKE_NI_CONTROL(0x02, 0x03),
- },
- {
- .name = "Phono Input Channel B",
- .private_value = _MAKE_NI_CONTROL(0x02, 0x05),
- },
-};
-
-static struct snd_kcontrol_new snd_nativeinstruments_ta10_mixers[] = {
- {
- .name = "Direct Thru Channel A",
- .private_value = _MAKE_NI_CONTROL(0x01, 0x03),
- },
- {
- .name = "Direct Thru Channel B",
- .private_value = _MAKE_NI_CONTROL(0x01, 0x05),
- },
- {
- .name = "Direct Thru Channel C",
- .private_value = _MAKE_NI_CONTROL(0x01, 0x07),
- },
- {
- .name = "Direct Thru Channel D",
- .private_value = _MAKE_NI_CONTROL(0x01, 0x09),
- },
- {
- .name = "Phono Input Channel A",
- .private_value = _MAKE_NI_CONTROL(0x02, 0x03),
- },
- {
- .name = "Phono Input Channel B",
- .private_value = _MAKE_NI_CONTROL(0x02, 0x05),
- },
- {
- .name = "Phono Input Channel C",
- .private_value = _MAKE_NI_CONTROL(0x02, 0x07),
- },
- {
- .name = "Phono Input Channel D",
- .private_value = _MAKE_NI_CONTROL(0x02, 0x09),
- },
-};
-
-static int snd_nativeinstruments_create_mixer(struct usb_mixer_interface *mixer,
- const struct snd_kcontrol_new *kc,
- unsigned int count)
-{
- int i, err = 0;
- struct snd_kcontrol_new template = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .get = snd_nativeinstruments_control_get,
- .put = snd_nativeinstruments_control_put,
- .info = snd_ctl_boolean_mono_info,
- };
-
- for (i = 0; i < count; i++) {
- struct snd_kcontrol *c;
-
- template.name = kc[i].name;
- template.private_value = kc[i].private_value;
-
- c = snd_ctl_new1(&template, mixer);
- err = snd_ctl_add(mixer->chip->card, c);
-
- if (err < 0)
- break;
- }
-
- return err;
-}
-
-/* M-Audio FastTrack Ultra quirks */
-
-/* private_free callback */
-static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
-{
- kfree(kctl->private_data);
- kctl->private_data = NULL;
-}
-
-static int snd_maudio_ftu_create_ctl(struct usb_mixer_interface *mixer,
- int in, int out, const char *name)
-{
- struct usb_mixer_elem_info *cval;
- struct snd_kcontrol *kctl;
-
- cval = kzalloc(sizeof(*cval), GFP_KERNEL);
- if (!cval)
- return -ENOMEM;
-
- cval->id = 5;
- cval->mixer = mixer;
- cval->val_type = USB_MIXER_S16;
- cval->channels = 1;
- cval->control = out + 1;
- cval->cmask = 1 << in;
-
- kctl = snd_ctl_new1(snd_usb_feature_unit_ctl, cval);
- if (!kctl) {
- kfree(cval);
- return -ENOMEM;
- }
-
- snprintf(kctl->id.name, sizeof(kctl->id.name), name);
- kctl->private_free = usb_mixer_elem_free;
- return snd_usb_mixer_add_control(mixer, kctl);
-}
-
-static int snd_maudio_ftu_create_mixer(struct usb_mixer_interface *mixer)
-{
- char name[64];
- int in, out, err;
-
- for (out = 0; out < 8; out++) {
- for (in = 0; in < 8; in++) {
- snprintf(name, sizeof(name),
- "AIn%d - Out%d Capture Volume", in + 1, out + 1);
- err = snd_maudio_ftu_create_ctl(mixer, in, out, name);
- if (err < 0)
- return err;
- }
-
- for (in = 8; in < 16; in++) {
- snprintf(name, sizeof(name),
- "DIn%d - Out%d Playback Volume", in - 7, out + 1);
- err = snd_maudio_ftu_create_ctl(mixer, in, out, name);
- if (err < 0)
- return err;
- }
- }
-
- return 0;
-}
-
-void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
- unsigned char samplerate_id)
-{
- struct usb_mixer_interface *mixer;
- struct usb_mixer_elem_info *cval;
- int unitid = 12; /* SamleRate ExtensionUnit ID */
-
- list_for_each_entry(mixer, &chip->mixer_list, list) {
- cval = mixer->id_elems[unitid];
- if (cval) {
- snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR,
- cval->control << 8,
- samplerate_id);
- snd_usb_mixer_notify_id(mixer, unitid);
- }
- break;
- }
-}
-
-int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
-{
- int err = 0;
- struct snd_info_entry *entry;
-
- if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0)
- return err;
-
- switch (mixer->chip->usb_id) {
- case USB_ID(0x041e, 0x3020):
- case USB_ID(0x041e, 0x3040):
- case USB_ID(0x041e, 0x3042):
- case USB_ID(0x041e, 0x30df):
- case USB_ID(0x041e, 0x3048):
- err = snd_audigy2nx_controls_create(mixer);
- if (err < 0)
- break;
- if (!snd_card_proc_new(mixer->chip->card, "audigy2nx", &entry))
- snd_info_set_text_ops(entry, mixer,
- snd_audigy2nx_proc_read);
- break;
-
- case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */
- case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
- err = snd_maudio_ftu_create_mixer(mixer);
- break;
-
- case USB_ID(0x0b05, 0x1739):
- case USB_ID(0x0b05, 0x1743):
- err = snd_xonar_u1_controls_create(mixer);
- break;
-
- case USB_ID(0x17cc, 0x1011): /* Traktor Audio 6 */
- err = snd_nativeinstruments_create_mixer(mixer,
- snd_nativeinstruments_ta6_mixers,
- ARRAY_SIZE(snd_nativeinstruments_ta6_mixers));
- break;
-
- case USB_ID(0x17cc, 0x1021): /* Traktor Audio 10 */
- err = snd_nativeinstruments_create_mixer(mixer,
- snd_nativeinstruments_ta10_mixers,
- ARRAY_SIZE(snd_nativeinstruments_ta10_mixers));
- break;
- }
-
- return err;
-}
-
-void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
- int unitid)
-{
- if (!mixer->rc_cfg)
- return;
- /* unit ids specific to Extigy/Audigy 2 NX: */
- switch (unitid) {
- case 0: /* remote control */
- mixer->rc_urb->dev = mixer->chip->dev;
- usb_submit_urb(mixer->rc_urb, GFP_ATOMIC);
- break;
- case 4: /* digital in jack */
- case 7: /* line in jacks */
- case 19: /* speaker out jacks */
- case 20: /* headphones out jack */
- break;
- /* live24ext: 4 = line-in jack */
- case 3: /* hp-out jack (may actuate Mute) */
- if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
- mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
- snd_usb_mixer_notify_id(mixer, mixer->rc_cfg->mute_mixer_id);
- break;
- default:
- snd_printd(KERN_DEBUG "memory change in unknown unit %d\n", unitid);
- break;
- }
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/mixer_quirks.h b/ANDROID_3.4.5/sound/usb/mixer_quirks.h
deleted file mode 100644
index bdbfab09..00000000
--- a/ANDROID_3.4.5/sound/usb/mixer_quirks.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef SND_USB_MIXER_QUIRKS_H
-#define SND_USB_MIXER_QUIRKS_H
-
-int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer);
-
-void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
- unsigned char samplerate_id);
-
-void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
- int unitid);
-
-#endif /* SND_USB_MIXER_QUIRKS_H */
-
diff --git a/ANDROID_3.4.5/sound/usb/pcm.c b/ANDROID_3.4.5/sound/usb/pcm.c
deleted file mode 100644
index 67a4d6db..00000000
--- a/ANDROID_3.4.5/sound/usb/pcm.c
+++ /dev/null
@@ -1,911 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/usb/audio.h>
-#include <linux/usb/audio-v2.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-
-#include "usbaudio.h"
-#include "card.h"
-#include "quirks.h"
-#include "debug.h"
-#include "endpoint.h"
-#include "helper.h"
-#include "pcm.h"
-#include "clock.h"
-#include "power.h"
-
-/* return the estimated delay based on USB frame counters */
-snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs,
- unsigned int rate)
-{
- int current_frame_number;
- int frame_diff;
- int est_delay;
-
- current_frame_number = usb_get_current_frame_number(subs->dev);
- /*
- * HCD implementations use different widths, use lower 8 bits.
- * The delay will be managed up to 256ms, which is more than
- * enough
- */
- frame_diff = (current_frame_number - subs->last_frame_number) & 0xff;
-
- /* Approximation based on number of samples per USB frame (ms),
- some truncation for 44.1 but the estimate is good enough */
- est_delay = subs->last_delay - (frame_diff * rate / 1000);
- if (est_delay < 0)
- est_delay = 0;
- return est_delay;
-}
-
-/*
- * return the current pcm pointer. just based on the hwptr_done value.
- */
-static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_usb_substream *subs;
- unsigned int hwptr_done;
-
- subs = (struct snd_usb_substream *)substream->runtime->private_data;
- spin_lock(&subs->lock);
- hwptr_done = subs->hwptr_done;
- substream->runtime->delay = snd_usb_pcm_delay(subs,
- substream->runtime->rate);
- spin_unlock(&subs->lock);
- return hwptr_done / (substream->runtime->frame_bits >> 3);
-}
-
-/*
- * find a matching audio format
- */
-static struct audioformat *find_format(struct snd_usb_substream *subs, unsigned int format,
- unsigned int rate, unsigned int channels)
-{
- struct list_head *p;
- struct audioformat *found = NULL;
- int cur_attr = 0, attr;
-
- list_for_each(p, &subs->fmt_list) {
- struct audioformat *fp;
- fp = list_entry(p, struct audioformat, list);
- if (!(fp->formats & (1uLL << format)))
- continue;
- if (fp->channels != channels)
- continue;
- if (rate < fp->rate_min || rate > fp->rate_max)
- continue;
- if (! (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)) {
- unsigned int i;
- for (i = 0; i < fp->nr_rates; i++)
- if (fp->rate_table[i] == rate)
- break;
- if (i >= fp->nr_rates)
- continue;
- }
- attr = fp->ep_attr & USB_ENDPOINT_SYNCTYPE;
- if (! found) {
- found = fp;
- cur_attr = attr;
- continue;
- }
- /* avoid async out and adaptive in if the other method
- * supports the same format.
- * this is a workaround for the case like
- * M-audio audiophile USB.
- */
- if (attr != cur_attr) {
- if ((attr == USB_ENDPOINT_SYNC_ASYNC &&
- subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
- (attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
- subs->direction == SNDRV_PCM_STREAM_CAPTURE))
- continue;
- if ((cur_attr == USB_ENDPOINT_SYNC_ASYNC &&
- subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
- (cur_attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
- subs->direction == SNDRV_PCM_STREAM_CAPTURE)) {
- found = fp;
- cur_attr = attr;
- continue;
- }
- }
- /* find the format with the largest max. packet size */
- if (fp->maxpacksize > found->maxpacksize) {
- found = fp;
- cur_attr = attr;
- }
- }
- return found;
-}
-
-static int init_pitch_v1(struct snd_usb_audio *chip, int iface,
- struct usb_host_interface *alts,
- struct audioformat *fmt)
-{
- struct usb_device *dev = chip->dev;
- unsigned int ep;
- unsigned char data[1];
- int err;
-
- ep = get_endpoint(alts, 0)->bEndpointAddress;
-
- data[0] = 1;
- if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
- USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
- UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep,
- data, sizeof(data))) < 0) {
- snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n",
- dev->devnum, iface, ep);
- return err;
- }
-
- return 0;
-}
-
-static int init_pitch_v2(struct snd_usb_audio *chip, int iface,
- struct usb_host_interface *alts,
- struct audioformat *fmt)
-{
- struct usb_device *dev = chip->dev;
- unsigned char data[1];
- unsigned int ep;
- int err;
-
- ep = get_endpoint(alts, 0)->bEndpointAddress;
-
- data[0] = 1;
- if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
- USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,
- UAC2_EP_CS_PITCH << 8, 0,
- data, sizeof(data))) < 0) {
- snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH (v2)\n",
- dev->devnum, iface, fmt->altsetting);
- return err;
- }
-
- return 0;
-}
-
-/*
- * initialize the pitch control and sample rate
- */
-int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
- struct usb_host_interface *alts,
- struct audioformat *fmt)
-{
- struct usb_interface_descriptor *altsd = get_iface_desc(alts);
-
- /* if endpoint doesn't have pitch control, bail out */
- if (!(fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL))
- return 0;
-
- switch (altsd->bInterfaceProtocol) {
- case UAC_VERSION_1:
- default:
- return init_pitch_v1(chip, iface, alts, fmt);
-
- case UAC_VERSION_2:
- return init_pitch_v2(chip, iface, alts, fmt);
- }
-}
-
-/*
- * find a matching format and set up the interface
- */
-static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
-{
- struct usb_device *dev = subs->dev;
- struct usb_host_interface *alts;
- struct usb_interface_descriptor *altsd;
- struct usb_interface *iface;
- unsigned int ep, attr;
- int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
- int err;
-
- iface = usb_ifnum_to_if(dev, fmt->iface);
- if (WARN_ON(!iface))
- return -EINVAL;
- alts = &iface->altsetting[fmt->altset_idx];
- altsd = get_iface_desc(alts);
- if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting))
- return -EINVAL;
-
- if (fmt == subs->cur_audiofmt)
- return 0;
-
- /* close the old interface */
- if (subs->interface >= 0 && subs->interface != fmt->iface) {
- if (usb_set_interface(subs->dev, subs->interface, 0) < 0) {
- snd_printk(KERN_ERR "%d:%d:%d: return to setting 0 failed\n",
- dev->devnum, fmt->iface, fmt->altsetting);
- return -EIO;
- }
- subs->interface = -1;
- subs->altset_idx = 0;
- }
-
- /* set interface */
- if (subs->interface != fmt->iface || subs->altset_idx != fmt->altset_idx) {
- if (usb_set_interface(dev, fmt->iface, fmt->altsetting) < 0) {
- snd_printk(KERN_ERR "%d:%d:%d: usb_set_interface failed\n",
- dev->devnum, fmt->iface, fmt->altsetting);
- return -EIO;
- }
- snd_printdd(KERN_INFO "setting usb interface %d:%d\n", fmt->iface, fmt->altsetting);
- subs->interface = fmt->iface;
- subs->altset_idx = fmt->altset_idx;
- }
-
- /* create a data pipe */
- ep = fmt->endpoint & USB_ENDPOINT_NUMBER_MASK;
- if (is_playback)
- subs->datapipe = usb_sndisocpipe(dev, ep);
- else
- subs->datapipe = usb_rcvisocpipe(dev, ep);
- subs->datainterval = fmt->datainterval;
- subs->syncpipe = subs->syncinterval = 0;
- subs->maxpacksize = fmt->maxpacksize;
- subs->syncmaxsize = 0;
- subs->fill_max = 0;
-
- /* we need a sync pipe in async OUT or adaptive IN mode */
- /* check the number of EP, since some devices have broken
- * descriptors which fool us. if it has only one EP,
- * assume it as adaptive-out or sync-in.
- */
- attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
- if (((is_playback && attr == USB_ENDPOINT_SYNC_ASYNC) ||
- (! is_playback && attr == USB_ENDPOINT_SYNC_ADAPTIVE)) &&
- altsd->bNumEndpoints >= 2) {
- /* check sync-pipe endpoint */
- /* ... and check descriptor size before accessing bSynchAddress
- because there is a version of the SB Audigy 2 NX firmware lacking
- the audio fields in the endpoint descriptors */
- if ((get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != 0x01 ||
- (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
- get_endpoint(alts, 1)->bSynchAddress != 0)) {
- snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
- dev->devnum, fmt->iface, fmt->altsetting);
- return -EINVAL;
- }
- ep = get_endpoint(alts, 1)->bEndpointAddress;
- if (get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
- (( is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) ||
- (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) {
- snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
- dev->devnum, fmt->iface, fmt->altsetting);
- return -EINVAL;
- }
- ep &= USB_ENDPOINT_NUMBER_MASK;
- if (is_playback)
- subs->syncpipe = usb_rcvisocpipe(dev, ep);
- else
- subs->syncpipe = usb_sndisocpipe(dev, ep);
- if (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
- get_endpoint(alts, 1)->bRefresh >= 1 &&
- get_endpoint(alts, 1)->bRefresh <= 9)
- subs->syncinterval = get_endpoint(alts, 1)->bRefresh;
- else if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
- subs->syncinterval = 1;
- else if (get_endpoint(alts, 1)->bInterval >= 1 &&
- get_endpoint(alts, 1)->bInterval <= 16)
- subs->syncinterval = get_endpoint(alts, 1)->bInterval - 1;
- else
- subs->syncinterval = 3;
- subs->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize);
- }
-
- /* always fill max packet size */
- if (fmt->attributes & UAC_EP_CS_ATTR_FILL_MAX)
- subs->fill_max = 1;
-
- if ((err = snd_usb_init_pitch(subs->stream->chip, subs->interface, alts, fmt)) < 0)
- return err;
-
- subs->cur_audiofmt = fmt;
-
- snd_usb_set_format_quirk(subs, fmt);
-
-#if 0
- printk(KERN_DEBUG
- "setting done: format = %d, rate = %d..%d, channels = %d\n",
- fmt->format, fmt->rate_min, fmt->rate_max, fmt->channels);
- printk(KERN_DEBUG
- " datapipe = 0x%0x, syncpipe = 0x%0x\n",
- subs->datapipe, subs->syncpipe);
-#endif
-
- return 0;
-}
-
-/*
- * hw_params callback
- *
- * allocate a buffer and set the given audio format.
- *
- * so far we use a physically linear buffer although packetize transfer
- * doesn't need a continuous area.
- * if sg buffer is supported on the later version of alsa, we'll follow
- * that.
- */
-static int snd_usb_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_usb_substream *subs = substream->runtime->private_data;
- struct audioformat *fmt;
- unsigned int channels, rate, format;
- int ret, changed;
-
- ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
- params_buffer_bytes(hw_params));
- if (ret < 0)
- return ret;
-
- format = params_format(hw_params);
- rate = params_rate(hw_params);
- channels = params_channels(hw_params);
- fmt = find_format(subs, format, rate, channels);
- if (!fmt) {
- snd_printd(KERN_DEBUG "cannot set format: format = %#x, rate = %d, channels = %d\n",
- format, rate, channels);
- return -EINVAL;
- }
-
- changed = subs->cur_audiofmt != fmt ||
- subs->period_bytes != params_period_bytes(hw_params) ||
- subs->cur_rate != rate;
- if ((ret = set_format(subs, fmt)) < 0)
- return ret;
-
- if (subs->cur_rate != rate) {
- struct usb_host_interface *alts;
- struct usb_interface *iface;
- iface = usb_ifnum_to_if(subs->dev, fmt->iface);
- alts = &iface->altsetting[fmt->altset_idx];
- ret = snd_usb_init_sample_rate(subs->stream->chip, subs->interface, alts, fmt, rate);
- if (ret < 0)
- return ret;
- subs->cur_rate = rate;
- }
-
- if (changed) {
- mutex_lock(&subs->stream->chip->shutdown_mutex);
- /* format changed */
- snd_usb_release_substream_urbs(subs, 0);
- /* influenced: period_bytes, channels, rate, format, */
- ret = snd_usb_init_substream_urbs(subs, params_period_bytes(hw_params),
- params_rate(hw_params),
- snd_pcm_format_physical_width(params_format(hw_params)) *
- params_channels(hw_params));
- mutex_unlock(&subs->stream->chip->shutdown_mutex);
- }
-
- return ret;
-}
-
-/*
- * hw_free callback
- *
- * reset the audio format and release the buffer
- */
-static int snd_usb_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_usb_substream *subs = substream->runtime->private_data;
-
- subs->cur_audiofmt = NULL;
- subs->cur_rate = 0;
- subs->period_bytes = 0;
- mutex_lock(&subs->stream->chip->shutdown_mutex);
- snd_usb_release_substream_urbs(subs, 0);
- mutex_unlock(&subs->stream->chip->shutdown_mutex);
- return snd_pcm_lib_free_vmalloc_buffer(substream);
-}
-
-/*
- * prepare callback
- *
- * only a few subtle things...
- */
-static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usb_substream *subs = runtime->private_data;
-
- if (! subs->cur_audiofmt) {
- snd_printk(KERN_ERR "usbaudio: no format is specified!\n");
- return -ENXIO;
- }
-
- /* some unit conversions in runtime */
- subs->maxframesize = bytes_to_frames(runtime, subs->maxpacksize);
- subs->curframesize = bytes_to_frames(runtime, subs->curpacksize);
-
- /* reset the pointer */
- subs->hwptr_done = 0;
- subs->transfer_done = 0;
- subs->phase = 0;
- subs->last_delay = 0;
- subs->last_frame_number = 0;
- runtime->delay = 0;
-
- return snd_usb_substream_prepare(subs, runtime);
-}
-
-static struct snd_pcm_hardware snd_usb_hardware =
-{
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BATCH |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_PAUSE,
- .buffer_bytes_max = 1024 * 1024,
- .period_bytes_min = 64,
- .period_bytes_max = 512 * 1024,
- .periods_min = 2,
- .periods_max = 1024,
-};
-
-static int hw_check_valid_format(struct snd_usb_substream *subs,
- struct snd_pcm_hw_params *params,
- struct audioformat *fp)
-{
- struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
- struct snd_interval *ct = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_mask *fmts = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
- struct snd_interval *pt = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
- struct snd_mask check_fmts;
- unsigned int ptime;
-
- /* check the format */
- snd_mask_none(&check_fmts);
- check_fmts.bits[0] = (u32)fp->formats;
- check_fmts.bits[1] = (u32)(fp->formats >> 32);
- snd_mask_intersect(&check_fmts, fmts);
- if (snd_mask_empty(&check_fmts)) {
- hwc_debug(" > check: no supported format %d\n", fp->format);
- return 0;
- }
- /* check the channels */
- if (fp->channels < ct->min || fp->channels > ct->max) {
- hwc_debug(" > check: no valid channels %d (%d/%d)\n", fp->channels, ct->min, ct->max);
- return 0;
- }
- /* check the rate is within the range */
- if (fp->rate_min > it->max || (fp->rate_min == it->max && it->openmax)) {
- hwc_debug(" > check: rate_min %d > max %d\n", fp->rate_min, it->max);
- return 0;
- }
- if (fp->rate_max < it->min || (fp->rate_max == it->min && it->openmin)) {
- hwc_debug(" > check: rate_max %d < min %d\n", fp->rate_max, it->min);
- return 0;
- }
- /* check whether the period time is >= the data packet interval */
- if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) {
- ptime = 125 * (1 << fp->datainterval);
- if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {
- hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max);
- return 0;
- }
- }
- return 1;
-}
-
-static int hw_rule_rate(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_usb_substream *subs = rule->private;
- struct list_head *p;
- struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
- unsigned int rmin, rmax;
- int changed;
-
- hwc_debug("hw_rule_rate: (%d,%d)\n", it->min, it->max);
- changed = 0;
- rmin = rmax = 0;
- list_for_each(p, &subs->fmt_list) {
- struct audioformat *fp;
- fp = list_entry(p, struct audioformat, list);
- if (!hw_check_valid_format(subs, params, fp))
- continue;
- if (changed++) {
- if (rmin > fp->rate_min)
- rmin = fp->rate_min;
- if (rmax < fp->rate_max)
- rmax = fp->rate_max;
- } else {
- rmin = fp->rate_min;
- rmax = fp->rate_max;
- }
- }
-
- if (!changed) {
- hwc_debug(" --> get empty\n");
- it->empty = 1;
- return -EINVAL;
- }
-
- changed = 0;
- if (it->min < rmin) {
- it->min = rmin;
- it->openmin = 0;
- changed = 1;
- }
- if (it->max > rmax) {
- it->max = rmax;
- it->openmax = 0;
- changed = 1;
- }
- if (snd_interval_checkempty(it)) {
- it->empty = 1;
- return -EINVAL;
- }
- hwc_debug(" --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
- return changed;
-}
-
-
-static int hw_rule_channels(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_usb_substream *subs = rule->private;
- struct list_head *p;
- struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- unsigned int rmin, rmax;
- int changed;
-
- hwc_debug("hw_rule_channels: (%d,%d)\n", it->min, it->max);
- changed = 0;
- rmin = rmax = 0;
- list_for_each(p, &subs->fmt_list) {
- struct audioformat *fp;
- fp = list_entry(p, struct audioformat, list);
- if (!hw_check_valid_format(subs, params, fp))
- continue;
- if (changed++) {
- if (rmin > fp->channels)
- rmin = fp->channels;
- if (rmax < fp->channels)
- rmax = fp->channels;
- } else {
- rmin = fp->channels;
- rmax = fp->channels;
- }
- }
-
- if (!changed) {
- hwc_debug(" --> get empty\n");
- it->empty = 1;
- return -EINVAL;
- }
-
- changed = 0;
- if (it->min < rmin) {
- it->min = rmin;
- it->openmin = 0;
- changed = 1;
- }
- if (it->max > rmax) {
- it->max = rmax;
- it->openmax = 0;
- changed = 1;
- }
- if (snd_interval_checkempty(it)) {
- it->empty = 1;
- return -EINVAL;
- }
- hwc_debug(" --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
- return changed;
-}
-
-static int hw_rule_format(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_usb_substream *subs = rule->private;
- struct list_head *p;
- struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
- u64 fbits;
- u32 oldbits[2];
- int changed;
-
- hwc_debug("hw_rule_format: %x:%x\n", fmt->bits[0], fmt->bits[1]);
- fbits = 0;
- list_for_each(p, &subs->fmt_list) {
- struct audioformat *fp;
- fp = list_entry(p, struct audioformat, list);
- if (!hw_check_valid_format(subs, params, fp))
- continue;
- fbits |= fp->formats;
- }
-
- oldbits[0] = fmt->bits[0];
- oldbits[1] = fmt->bits[1];
- fmt->bits[0] &= (u32)fbits;
- fmt->bits[1] &= (u32)(fbits >> 32);
- if (!fmt->bits[0] && !fmt->bits[1]) {
- hwc_debug(" --> get empty\n");
- return -EINVAL;
- }
- changed = (oldbits[0] != fmt->bits[0] || oldbits[1] != fmt->bits[1]);
- hwc_debug(" --> %x:%x (changed = %d)\n", fmt->bits[0], fmt->bits[1], changed);
- return changed;
-}
-
-static int hw_rule_period_time(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_usb_substream *subs = rule->private;
- struct audioformat *fp;
- struct snd_interval *it;
- unsigned char min_datainterval;
- unsigned int pmin;
- int changed;
-
- it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
- hwc_debug("hw_rule_period_time: (%u,%u)\n", it->min, it->max);
- min_datainterval = 0xff;
- list_for_each_entry(fp, &subs->fmt_list, list) {
- if (!hw_check_valid_format(subs, params, fp))
- continue;
- min_datainterval = min(min_datainterval, fp->datainterval);
- }
- if (min_datainterval == 0xff) {
- hwc_debug(" --> get empty\n");
- it->empty = 1;
- return -EINVAL;
- }
- pmin = 125 * (1 << min_datainterval);
- changed = 0;
- if (it->min < pmin) {
- it->min = pmin;
- it->openmin = 0;
- changed = 1;
- }
- if (snd_interval_checkempty(it)) {
- it->empty = 1;
- return -EINVAL;
- }
- hwc_debug(" --> (%u,%u) (changed = %d)\n", it->min, it->max, changed);
- return changed;
-}
-
-/*
- * If the device supports unusual bit rates, does the request meet these?
- */
-static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
- struct snd_usb_substream *subs)
-{
- struct audioformat *fp;
- int *rate_list;
- int count = 0, needs_knot = 0;
- int err;
-
- kfree(subs->rate_list.list);
- subs->rate_list.list = NULL;
-
- list_for_each_entry(fp, &subs->fmt_list, list) {
- if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)
- return 0;
- count += fp->nr_rates;
- if (fp->rates & SNDRV_PCM_RATE_KNOT)
- needs_knot = 1;
- }
- if (!needs_knot)
- return 0;
-
- subs->rate_list.list = rate_list =
- kmalloc(sizeof(int) * count, GFP_KERNEL);
- if (!subs->rate_list.list)
- return -ENOMEM;
- subs->rate_list.count = count;
- subs->rate_list.mask = 0;
- count = 0;
- list_for_each_entry(fp, &subs->fmt_list, list) {
- int i;
- for (i = 0; i < fp->nr_rates; i++)
- rate_list[count++] = fp->rate_table[i];
- }
- err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &subs->rate_list);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-
-/*
- * set up the runtime hardware information.
- */
-
-static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substream *subs)
-{
- struct list_head *p;
- unsigned int pt, ptmin;
- int param_period_time_if_needed;
- int err;
-
- runtime->hw.formats = subs->formats;
-
- runtime->hw.rate_min = 0x7fffffff;
- runtime->hw.rate_max = 0;
- runtime->hw.channels_min = 256;
- runtime->hw.channels_max = 0;
- runtime->hw.rates = 0;
- ptmin = UINT_MAX;
- /* check min/max rates and channels */
- list_for_each(p, &subs->fmt_list) {
- struct audioformat *fp;
- fp = list_entry(p, struct audioformat, list);
- runtime->hw.rates |= fp->rates;
- if (runtime->hw.rate_min > fp->rate_min)
- runtime->hw.rate_min = fp->rate_min;
- if (runtime->hw.rate_max < fp->rate_max)
- runtime->hw.rate_max = fp->rate_max;
- if (runtime->hw.channels_min > fp->channels)
- runtime->hw.channels_min = fp->channels;
- if (runtime->hw.channels_max < fp->channels)
- runtime->hw.channels_max = fp->channels;
- if (fp->fmt_type == UAC_FORMAT_TYPE_II && fp->frame_size > 0) {
- /* FIXME: there might be more than one audio formats... */
- runtime->hw.period_bytes_min = runtime->hw.period_bytes_max =
- fp->frame_size;
- }
- pt = 125 * (1 << fp->datainterval);
- ptmin = min(ptmin, pt);
- }
- err = snd_usb_autoresume(subs->stream->chip);
- if (err < 0)
- return err;
-
- param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
- if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
- /* full speed devices have fixed data packet interval */
- ptmin = 1000;
- if (ptmin == 1000)
- /* if period time doesn't go below 1 ms, no rules needed */
- param_period_time_if_needed = -1;
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME,
- ptmin, UINT_MAX);
-
- if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- hw_rule_rate, subs,
- SNDRV_PCM_HW_PARAM_FORMAT,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- param_period_time_if_needed,
- -1)) < 0)
- goto rep_err;
- if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- hw_rule_channels, subs,
- SNDRV_PCM_HW_PARAM_FORMAT,
- SNDRV_PCM_HW_PARAM_RATE,
- param_period_time_if_needed,
- -1)) < 0)
- goto rep_err;
- if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
- hw_rule_format, subs,
- SNDRV_PCM_HW_PARAM_RATE,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- param_period_time_if_needed,
- -1)) < 0)
- goto rep_err;
- if (param_period_time_if_needed >= 0) {
- err = snd_pcm_hw_rule_add(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_TIME,
- hw_rule_period_time, subs,
- SNDRV_PCM_HW_PARAM_FORMAT,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- SNDRV_PCM_HW_PARAM_RATE,
- -1);
- if (err < 0)
- goto rep_err;
- }
- if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0)
- goto rep_err;
- return 0;
-
-rep_err:
- snd_usb_autosuspend(subs->stream->chip);
- return err;
-}
-
-static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction)
-{
- struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usb_substream *subs = &as->substream[direction];
-
- subs->interface = -1;
- subs->altset_idx = 0;
- runtime->hw = snd_usb_hardware;
- runtime->private_data = subs;
- subs->pcm_substream = substream;
- /* runtime PM is also done there */
- return setup_hw_info(runtime, subs);
-}
-
-static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
-{
- struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
- struct snd_usb_substream *subs = &as->substream[direction];
-
- if (!as->chip->shutdown && subs->interface >= 0) {
- usb_set_interface(subs->dev, subs->interface, 0);
- subs->interface = -1;
- }
- subs->pcm_substream = NULL;
- snd_usb_autosuspend(subs->stream->chip);
- return 0;
-}
-
-static int snd_usb_playback_open(struct snd_pcm_substream *substream)
-{
- return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_PLAYBACK);
-}
-
-static int snd_usb_playback_close(struct snd_pcm_substream *substream)
-{
- return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_PLAYBACK);
-}
-
-static int snd_usb_capture_open(struct snd_pcm_substream *substream)
-{
- return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_CAPTURE);
-}
-
-static int snd_usb_capture_close(struct snd_pcm_substream *substream)
-{
- return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_CAPTURE);
-}
-
-static struct snd_pcm_ops snd_usb_playback_ops = {
- .open = snd_usb_playback_open,
- .close = snd_usb_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_usb_hw_params,
- .hw_free = snd_usb_hw_free,
- .prepare = snd_usb_pcm_prepare,
- .trigger = snd_usb_substream_playback_trigger,
- .pointer = snd_usb_pcm_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
-};
-
-static struct snd_pcm_ops snd_usb_capture_ops = {
- .open = snd_usb_capture_open,
- .close = snd_usb_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_usb_hw_params,
- .hw_free = snd_usb_hw_free,
- .prepare = snd_usb_pcm_prepare,
- .trigger = snd_usb_substream_capture_trigger,
- .pointer = snd_usb_pcm_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
-};
-
-void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream)
-{
- snd_pcm_set_ops(pcm, stream,
- stream == SNDRV_PCM_STREAM_PLAYBACK ?
- &snd_usb_playback_ops : &snd_usb_capture_ops);
-}
diff --git a/ANDROID_3.4.5/sound/usb/pcm.h b/ANDROID_3.4.5/sound/usb/pcm.h
deleted file mode 100644
index df7a0036..00000000
--- a/ANDROID_3.4.5/sound/usb/pcm.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __USBAUDIO_PCM_H
-#define __USBAUDIO_PCM_H
-
-snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs,
- unsigned int rate);
-
-void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream);
-
-int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
- struct usb_host_interface *alts,
- struct audioformat *fmt);
-
-
-#endif /* __USBAUDIO_PCM_H */
diff --git a/ANDROID_3.4.5/sound/usb/power.h b/ANDROID_3.4.5/sound/usb/power.h
deleted file mode 100644
index 48ee51dc..00000000
--- a/ANDROID_3.4.5/sound/usb/power.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __USBAUDIO_POWER_H
-#define __USBAUDIO_POWER_H
-
-#ifdef CONFIG_PM
-int snd_usb_autoresume(struct snd_usb_audio *chip);
-void snd_usb_autosuspend(struct snd_usb_audio *chip);
-#else
-static inline int snd_usb_autoresume(struct snd_usb_audio *chip)
-{
- return 0;
-}
-static inline void snd_usb_autosuspend(struct snd_usb_audio *chip)
-{
-}
-#endif
-
-#endif /* __USBAUDIO_POWER_H */
diff --git a/ANDROID_3.4.5/sound/usb/proc.c b/ANDROID_3.4.5/sound/usb/proc.c
deleted file mode 100644
index 961c9a25..00000000
--- a/ANDROID_3.4.5/sound/usb/proc.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/usb.h>
-
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/pcm.h>
-
-#include "usbaudio.h"
-#include "helper.h"
-#include "card.h"
-#include "proc.h"
-
-/* convert our full speed USB rate into sampling rate in Hz */
-static inline unsigned get_full_speed_hz(unsigned int usb_rate)
-{
- return (usb_rate * 125 + (1 << 12)) >> 13;
-}
-
-/* convert our high speed USB rate into sampling rate in Hz */
-static inline unsigned get_high_speed_hz(unsigned int usb_rate)
-{
- return (usb_rate * 125 + (1 << 9)) >> 10;
-}
-
-/*
- * common proc files to show the usb device info
- */
-static void proc_audio_usbbus_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- struct snd_usb_audio *chip = entry->private_data;
- if (!chip->shutdown)
- snd_iprintf(buffer, "%03d/%03d\n", chip->dev->bus->busnum, chip->dev->devnum);
-}
-
-static void proc_audio_usbid_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- struct snd_usb_audio *chip = entry->private_data;
- if (!chip->shutdown)
- snd_iprintf(buffer, "%04x:%04x\n",
- USB_ID_VENDOR(chip->usb_id),
- USB_ID_PRODUCT(chip->usb_id));
-}
-
-void snd_usb_audio_create_proc(struct snd_usb_audio *chip)
-{
- struct snd_info_entry *entry;
- if (!snd_card_proc_new(chip->card, "usbbus", &entry))
- snd_info_set_text_ops(entry, chip, proc_audio_usbbus_read);
- if (!snd_card_proc_new(chip->card, "usbid", &entry))
- snd_info_set_text_ops(entry, chip, proc_audio_usbid_read);
-}
-
-/*
- * proc interface for list the supported pcm formats
- */
-static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct snd_info_buffer *buffer)
-{
- struct list_head *p;
- static char *sync_types[4] = {
- "NONE", "ASYNC", "ADAPTIVE", "SYNC"
- };
-
- list_for_each(p, &subs->fmt_list) {
- struct audioformat *fp;
- snd_pcm_format_t fmt;
- fp = list_entry(p, struct audioformat, list);
- snd_iprintf(buffer, " Interface %d\n", fp->iface);
- snd_iprintf(buffer, " Altset %d\n", fp->altsetting);
- snd_iprintf(buffer, " Format:");
- for (fmt = 0; fmt <= SNDRV_PCM_FORMAT_LAST; ++fmt)
- if (fp->formats & (1uLL << fmt))
- snd_iprintf(buffer, " %s",
- snd_pcm_format_name(fmt));
- snd_iprintf(buffer, "\n");
- snd_iprintf(buffer, " Channels: %d\n", fp->channels);
- snd_iprintf(buffer, " Endpoint: %d %s (%s)\n",
- fp->endpoint & USB_ENDPOINT_NUMBER_MASK,
- fp->endpoint & USB_DIR_IN ? "IN" : "OUT",
- sync_types[(fp->ep_attr & USB_ENDPOINT_SYNCTYPE) >> 2]);
- if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) {
- snd_iprintf(buffer, " Rates: %d - %d (continuous)\n",
- fp->rate_min, fp->rate_max);
- } else {
- unsigned int i;
- snd_iprintf(buffer, " Rates: ");
- for (i = 0; i < fp->nr_rates; i++) {
- if (i > 0)
- snd_iprintf(buffer, ", ");
- snd_iprintf(buffer, "%d", fp->rate_table[i]);
- }
- snd_iprintf(buffer, "\n");
- }
- if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL)
- snd_iprintf(buffer, " Data packet interval: %d us\n",
- 125 * (1 << fp->datainterval));
- // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize);
- // snd_iprintf(buffer, " EP Attribute = %#x\n", fp->attributes);
- }
-}
-
-static void proc_dump_substream_status(struct snd_usb_substream *subs, struct snd_info_buffer *buffer)
-{
- if (subs->running) {
- unsigned int i;
- snd_iprintf(buffer, " Status: Running\n");
- snd_iprintf(buffer, " Interface = %d\n", subs->interface);
- snd_iprintf(buffer, " Altset = %d\n", subs->altset_idx);
- snd_iprintf(buffer, " URBs = %d [ ", subs->nurbs);
- for (i = 0; i < subs->nurbs; i++)
- snd_iprintf(buffer, "%d ", subs->dataurb[i].packets);
- snd_iprintf(buffer, "]\n");
- snd_iprintf(buffer, " Packet Size = %d\n", subs->curpacksize);
- snd_iprintf(buffer, " Momentary freq = %u Hz (%#x.%04x)\n",
- snd_usb_get_speed(subs->dev) == USB_SPEED_FULL
- ? get_full_speed_hz(subs->freqm)
- : get_high_speed_hz(subs->freqm),
- subs->freqm >> 16, subs->freqm & 0xffff);
- if (subs->freqshift != INT_MIN)
- snd_iprintf(buffer, " Feedback Format = %d.%d\n",
- (subs->syncmaxsize > 3 ? 32 : 24)
- - (16 - subs->freqshift),
- 16 - subs->freqshift);
- } else {
- snd_iprintf(buffer, " Status: Stop\n");
- }
-}
-
-static void proc_pcm_format_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- struct snd_usb_stream *stream = entry->private_data;
-
- snd_iprintf(buffer, "%s : %s\n", stream->chip->card->longname, stream->pcm->name);
-
- if (stream->substream[SNDRV_PCM_STREAM_PLAYBACK].num_formats) {
- snd_iprintf(buffer, "\nPlayback:\n");
- proc_dump_substream_status(&stream->substream[SNDRV_PCM_STREAM_PLAYBACK], buffer);
- proc_dump_substream_formats(&stream->substream[SNDRV_PCM_STREAM_PLAYBACK], buffer);
- }
- if (stream->substream[SNDRV_PCM_STREAM_CAPTURE].num_formats) {
- snd_iprintf(buffer, "\nCapture:\n");
- proc_dump_substream_status(&stream->substream[SNDRV_PCM_STREAM_CAPTURE], buffer);
- proc_dump_substream_formats(&stream->substream[SNDRV_PCM_STREAM_CAPTURE], buffer);
- }
-}
-
-void snd_usb_proc_pcm_format_add(struct snd_usb_stream *stream)
-{
- struct snd_info_entry *entry;
- char name[32];
- struct snd_card *card = stream->chip->card;
-
- sprintf(name, "stream%d", stream->pcm_index);
- if (!snd_card_proc_new(card, name, &entry))
- snd_info_set_text_ops(entry, stream, proc_pcm_format_read);
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/proc.h b/ANDROID_3.4.5/sound/usb/proc.h
deleted file mode 100644
index a45b765e..00000000
--- a/ANDROID_3.4.5/sound/usb/proc.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __USBAUDIO_PROC_H
-#define __USBAUDIO_PROC_H
-
-void snd_usb_audio_create_proc(struct snd_usb_audio *chip);
-void snd_usb_proc_pcm_format_add(struct snd_usb_stream *stream);
-
-#endif /* __USBAUDIO_PROC_H */
-
diff --git a/ANDROID_3.4.5/sound/usb/quirks-table.h b/ANDROID_3.4.5/sound/usb/quirks-table.h
deleted file mode 100644
index d89ab4c7..00000000
--- a/ANDROID_3.4.5/sound/usb/quirks-table.h
+++ /dev/null
@@ -1,2769 +0,0 @@
-/*
- * ALSA USB Audio Driver
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>,
- * Clemens Ladisch <clemens@ladisch.de>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * The contents of this file are part of the driver's id_table.
- *
- * In a perfect world, this file would be empty.
- */
-
-/*
- * Use this for devices where other interfaces are standard compliant,
- * to prevent the quirk being applied to those interfaces. (To work with
- * hotplugging, bDeviceClass must be set to USB_CLASS_PER_INTERFACE.)
- */
-#define USB_DEVICE_VENDOR_SPEC(vend, prod) \
- .match_flags = USB_DEVICE_ID_MATCH_VENDOR | \
- USB_DEVICE_ID_MATCH_PRODUCT | \
- USB_DEVICE_ID_MATCH_INT_CLASS, \
- .idVendor = vend, \
- .idProduct = prod, \
- .bInterfaceClass = USB_CLASS_VENDOR_SPEC
-
-/* FTDI devices */
-{
- USB_DEVICE(0x0403, 0xb8d8),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "STARR LABS", */
- /* .product_name = "Starr Labs MIDI USB device", */
- .ifnum = 0,
- .type = QUIRK_MIDI_FTDI
- }
-},
-
-/* Creative/Toshiba Multimedia Center SB-0500 */
-{
- USB_DEVICE(0x041e, 0x3048),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Toshiba",
- .product_name = "SB-0500",
- .ifnum = QUIRK_NO_INTERFACE
- }
-},
-
-/* Creative/E-Mu devices */
-{
- USB_DEVICE(0x041e, 0x3010),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Creative Labs",
- .product_name = "Sound Blaster MP3+",
- .ifnum = QUIRK_NO_INTERFACE
- }
-},
-{
- /* E-Mu 0202 USB */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x041e,
- .idProduct = 0x3f02,
- .bInterfaceClass = USB_CLASS_AUDIO,
-},
-{
- /* E-Mu 0404 USB */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x041e,
- .idProduct = 0x3f04,
- .bInterfaceClass = USB_CLASS_AUDIO,
-},
-{
- /* E-Mu Tracker Pre */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x041e,
- .idProduct = 0x3f0a,
- .bInterfaceClass = USB_CLASS_AUDIO,
-},
-{
- /* E-Mu 0204 USB */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x041e,
- .idProduct = 0x3f19,
- .bInterfaceClass = USB_CLASS_AUDIO,
-},
-
-/*
- * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface
- * class matches do not take effect without an explicit ID match.
- */
-{
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .idVendor = 0x046d,
- .idProduct = 0x0850,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
-},
-{
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .idVendor = 0x046d,
- .idProduct = 0x08ae,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
-},
-{
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .idVendor = 0x046d,
- .idProduct = 0x08c6,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
-},
-{
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .idVendor = 0x046d,
- .idProduct = 0x08f0,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
-},
-{
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .idVendor = 0x046d,
- .idProduct = 0x08f5,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
-},
-{
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .idVendor = 0x046d,
- .idProduct = 0x08f6,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
-},
-{
- USB_DEVICE(0x046d, 0x0990),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Logitech, Inc.",
- .product_name = "QuickCam Pro 9000",
- .ifnum = QUIRK_NO_INTERFACE
- }
-},
-
-/*
- * Yamaha devices
- */
-
-#define YAMAHA_DEVICE(id, name) { \
- USB_DEVICE(0x0499, id), \
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { \
- .vendor_name = "Yamaha", \
- .product_name = name, \
- .ifnum = QUIRK_ANY_INTERFACE, \
- .type = QUIRK_MIDI_YAMAHA \
- } \
-}
-#define YAMAHA_INTERFACE(id, intf, name) { \
- USB_DEVICE_VENDOR_SPEC(0x0499, id), \
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { \
- .vendor_name = "Yamaha", \
- .product_name = name, \
- .ifnum = intf, \
- .type = QUIRK_MIDI_YAMAHA \
- } \
-}
-YAMAHA_DEVICE(0x1000, "UX256"),
-YAMAHA_DEVICE(0x1001, "MU1000"),
-YAMAHA_DEVICE(0x1002, "MU2000"),
-YAMAHA_DEVICE(0x1003, "MU500"),
-YAMAHA_INTERFACE(0x1004, 3, "UW500"),
-YAMAHA_DEVICE(0x1005, "MOTIF6"),
-YAMAHA_DEVICE(0x1006, "MOTIF7"),
-YAMAHA_DEVICE(0x1007, "MOTIF8"),
-YAMAHA_DEVICE(0x1008, "UX96"),
-YAMAHA_DEVICE(0x1009, "UX16"),
-YAMAHA_INTERFACE(0x100a, 3, "EOS BX"),
-YAMAHA_DEVICE(0x100c, "UC-MX"),
-YAMAHA_DEVICE(0x100d, "UC-KX"),
-YAMAHA_DEVICE(0x100e, "S08"),
-YAMAHA_DEVICE(0x100f, "CLP-150"),
-YAMAHA_DEVICE(0x1010, "CLP-170"),
-YAMAHA_DEVICE(0x1011, "P-250"),
-YAMAHA_DEVICE(0x1012, "TYROS"),
-YAMAHA_DEVICE(0x1013, "PF-500"),
-YAMAHA_DEVICE(0x1014, "S90"),
-YAMAHA_DEVICE(0x1015, "MOTIF-R"),
-YAMAHA_DEVICE(0x1016, "MDP-5"),
-YAMAHA_DEVICE(0x1017, "CVP-204"),
-YAMAHA_DEVICE(0x1018, "CVP-206"),
-YAMAHA_DEVICE(0x1019, "CVP-208"),
-YAMAHA_DEVICE(0x101a, "CVP-210"),
-YAMAHA_DEVICE(0x101b, "PSR-1100"),
-YAMAHA_DEVICE(0x101c, "PSR-2100"),
-YAMAHA_DEVICE(0x101d, "CLP-175"),
-YAMAHA_DEVICE(0x101e, "PSR-K1"),
-YAMAHA_DEVICE(0x101f, "EZ-J24"),
-YAMAHA_DEVICE(0x1020, "EZ-250i"),
-YAMAHA_DEVICE(0x1021, "MOTIF ES 6"),
-YAMAHA_DEVICE(0x1022, "MOTIF ES 7"),
-YAMAHA_DEVICE(0x1023, "MOTIF ES 8"),
-YAMAHA_DEVICE(0x1024, "CVP-301"),
-YAMAHA_DEVICE(0x1025, "CVP-303"),
-YAMAHA_DEVICE(0x1026, "CVP-305"),
-YAMAHA_DEVICE(0x1027, "CVP-307"),
-YAMAHA_DEVICE(0x1028, "CVP-309"),
-YAMAHA_DEVICE(0x1029, "CVP-309GP"),
-YAMAHA_DEVICE(0x102a, "PSR-1500"),
-YAMAHA_DEVICE(0x102b, "PSR-3000"),
-YAMAHA_DEVICE(0x102e, "ELS-01/01C"),
-YAMAHA_DEVICE(0x1030, "PSR-295/293"),
-YAMAHA_DEVICE(0x1031, "DGX-205/203"),
-YAMAHA_DEVICE(0x1032, "DGX-305"),
-YAMAHA_DEVICE(0x1033, "DGX-505"),
-YAMAHA_DEVICE(0x1034, NULL),
-YAMAHA_DEVICE(0x1035, NULL),
-YAMAHA_DEVICE(0x1036, NULL),
-YAMAHA_DEVICE(0x1037, NULL),
-YAMAHA_DEVICE(0x1038, NULL),
-YAMAHA_DEVICE(0x1039, NULL),
-YAMAHA_DEVICE(0x103a, NULL),
-YAMAHA_DEVICE(0x103b, NULL),
-YAMAHA_DEVICE(0x103c, NULL),
-YAMAHA_DEVICE(0x103d, NULL),
-YAMAHA_DEVICE(0x103e, NULL),
-YAMAHA_DEVICE(0x103f, NULL),
-YAMAHA_DEVICE(0x1040, NULL),
-YAMAHA_DEVICE(0x1041, NULL),
-YAMAHA_DEVICE(0x1042, NULL),
-YAMAHA_DEVICE(0x1043, NULL),
-YAMAHA_DEVICE(0x1044, NULL),
-YAMAHA_DEVICE(0x1045, NULL),
-YAMAHA_INTERFACE(0x104e, 0, NULL),
-YAMAHA_DEVICE(0x104f, NULL),
-YAMAHA_DEVICE(0x1050, NULL),
-YAMAHA_DEVICE(0x1051, NULL),
-YAMAHA_DEVICE(0x1052, NULL),
-YAMAHA_INTERFACE(0x1053, 0, NULL),
-YAMAHA_INTERFACE(0x1054, 0, NULL),
-YAMAHA_DEVICE(0x1055, NULL),
-YAMAHA_DEVICE(0x1056, NULL),
-YAMAHA_DEVICE(0x1057, NULL),
-YAMAHA_DEVICE(0x1058, NULL),
-YAMAHA_DEVICE(0x1059, NULL),
-YAMAHA_DEVICE(0x105a, NULL),
-YAMAHA_DEVICE(0x105b, NULL),
-YAMAHA_DEVICE(0x105c, NULL),
-YAMAHA_DEVICE(0x105d, NULL),
-{
- USB_DEVICE(0x0499, 0x1503),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "Yamaha", */
- /* .product_name = "MOX6/MOX8", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 3,
- .type = QUIRK_MIDI_YAMAHA
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-YAMAHA_DEVICE(0x2000, "DGP-7"),
-YAMAHA_DEVICE(0x2001, "DGP-5"),
-YAMAHA_DEVICE(0x2002, NULL),
-YAMAHA_DEVICE(0x2003, NULL),
-YAMAHA_DEVICE(0x5000, "CS1D"),
-YAMAHA_DEVICE(0x5001, "DSP1D"),
-YAMAHA_DEVICE(0x5002, "DME32"),
-YAMAHA_DEVICE(0x5003, "DM2000"),
-YAMAHA_DEVICE(0x5004, "02R96"),
-YAMAHA_DEVICE(0x5005, "ACU16-C"),
-YAMAHA_DEVICE(0x5006, "NHB32-C"),
-YAMAHA_DEVICE(0x5007, "DM1000"),
-YAMAHA_DEVICE(0x5008, "01V96"),
-YAMAHA_DEVICE(0x5009, "SPX2000"),
-YAMAHA_DEVICE(0x500a, "PM5D"),
-YAMAHA_DEVICE(0x500b, "DME64N"),
-YAMAHA_DEVICE(0x500c, "DME24N"),
-YAMAHA_DEVICE(0x500d, NULL),
-YAMAHA_DEVICE(0x500e, NULL),
-YAMAHA_DEVICE(0x500f, NULL),
-YAMAHA_DEVICE(0x7000, "DTX"),
-YAMAHA_DEVICE(0x7010, "UB99"),
-#undef YAMAHA_DEVICE
-#undef YAMAHA_INTERFACE
-
-/*
- * Roland/RolandED/Edirol/BOSS devices
- */
-{
- USB_DEVICE(0x0582, 0x0000),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "UA-100",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = & (const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .channels = 4,
- .iface = 0,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = 0,
- .endpoint = 0x01,
- .ep_attr = 0x09,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 44100,
- .rate_max = 44100,
- }
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = & (const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .channels = 2,
- .iface = 1,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = UAC_EP_CS_ATTR_FILL_MAX,
- .endpoint = 0x81,
- .ep_attr = 0x05,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 44100,
- .rate_max = 44100,
- }
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0007,
- .in_cables = 0x0007
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x0002),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UM-4",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x000f,
- .in_cables = 0x000f
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x0003),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "SC-8850",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x003f,
- .in_cables = 0x003f
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x0004),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "U-8",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0005,
- .in_cables = 0x0005
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* Has ID 0x0099 when not in "Advanced Driver" mode.
- * The UM-2EX has only one input, but we cannot detect this. */
- USB_DEVICE(0x0582, 0x0005),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UM-2",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0003
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x0007),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "SC-8820",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0013,
- .in_cables = 0x0013
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x0008),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "PC-300",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x009d when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0009),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UM-1",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x000b),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "SK-500",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0013,
- .in_cables = 0x0013
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* thanks to Emiliano Grilli <emillo@libero.it>
- * for helping researching this data */
- USB_DEVICE(0x0582, 0x000c),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "SC-D70",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = & (const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S24_3LE,
- .channels = 2,
- .iface = 0,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = 0,
- .endpoint = 0x01,
- .ep_attr = 0x01,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 44100,
- .rate_max = 44100,
- }
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = & (const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S24_3LE,
- .channels = 2,
- .iface = 1,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = 0,
- .endpoint = 0x81,
- .ep_attr = 0x01,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 44100,
- .rate_max = 44100,
- }
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0007,
- .in_cables = 0x0007
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{ /*
- * This quirk is for the "Advanced Driver" mode of the Edirol UA-5.
- * If the advanced mode switch at the back of the unit is off, the
- * UA-5 has ID 0x0582/0x0011 and is standard compliant (no quirks),
- * but offers only 16-bit PCM.
- * In advanced mode, the UA-5 will output S24_3LE samples (two
- * channels) at the rate indicated on the front switch, including
- * the 96kHz sample rate.
- */
- USB_DEVICE(0x0582, 0x0010),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UA-5",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x0013 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0012),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "XV-5050",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- /* has ID 0x0015 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0014),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UM-880",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x01ff,
- .in_cables = 0x01ff
- }
- }
-},
-{
- /* has ID 0x0017 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0016),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "SD-90",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x000f,
- .in_cables = 0x000f
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x001c when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x001b),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "MMP-2",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x001e when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x001d),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "V-SYNTH",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- /* has ID 0x0024 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0023),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UM-550",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x003f,
- .in_cables = 0x003f
- }
- }
-},
-{
- /*
- * This quirk is for the "Advanced Driver" mode. If off, the UA-20
- * has ID 0x0026 and is standard compliant, but has only 16-bit PCM
- * and no MIDI.
- */
- USB_DEVICE(0x0582, 0x0025),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UA-20",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = & (const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S24_3LE,
- .channels = 2,
- .iface = 1,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = 0,
- .endpoint = 0x01,
- .ep_attr = 0x01,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 44100,
- .rate_max = 44100,
- }
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = & (const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S24_3LE,
- .channels = 2,
- .iface = 2,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = 0,
- .endpoint = 0x82,
- .ep_attr = 0x01,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 44100,
- .rate_max = 44100,
- }
- },
- {
- .ifnum = 3,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x0028 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0027),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "SD-20",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0007
- }
- }
-},
-{
- /* has ID 0x002a when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0029),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "SD-80",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x000f,
- .in_cables = 0x000f
- }
- }
-},
-{ /*
- * This quirk is for the "Advanced" modes of the Edirol UA-700.
- * If the sample format switch is not in an advanced setting, the
- * UA-700 has ID 0x0582/0x002c and is standard compliant (no quirks),
- * but offers only 16-bit PCM and no MIDI.
- */
- USB_DEVICE_VENDOR_SPEC(0x0582, 0x002b),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UA-700",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = 3,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x002e when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x002d),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "XV-2020",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- /* has ID 0x0030 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x002f),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "VariOS",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0007,
- .in_cables = 0x0007
- }
- }
-},
-{
- /* has ID 0x0034 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0033),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "PCR",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0007
- }
- }
-},
- /* TODO: add Roland M-1000 support */
-{
- /*
- * Has ID 0x0038 when not in "Advanced Driver" mode;
- * later revisions use IDs 0x0054 and 0x00a2.
- */
- USB_DEVICE(0x0582, 0x0037),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "Digital Piano",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- /*
- * This quirk is for the "Advanced Driver" mode. If off, the GS-10
- * has ID 0x003c and is standard compliant, but has only 16-bit PCM
- * and no MIDI.
- */
- USB_DEVICE_VENDOR_SPEC(0x0582, 0x003b),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "BOSS",
- .product_name = "GS-10",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = & (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 3,
- .type = QUIRK_MIDI_STANDARD_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x0041 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0040),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "GI-20",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- /* has ID 0x0043 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0042),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "RS-70",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- /* has ID 0x0049 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0047),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "EDIROL", */
- /* .product_name = "UR-80", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- /* in the 96 kHz modes, only interface 1 is there */
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x004a when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0048),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "EDIROL", */
- /* .product_name = "UR-80", */
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0007
- }
- }
-},
- /* TODO: add Edirol M-100FX support */
-{
- /* has ID 0x004e when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x004c),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "PCR-A",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x004f when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x004d),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "PCR-A",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0007
- }
- }
-},
-{
- /*
- * This quirk is for the "Advanced Driver" mode. If off, the UA-3FX
- * is standard compliant, but has only 16-bit PCM.
- */
- USB_DEVICE(0x0582, 0x0050),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UA-3FX",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x0052),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UM-1SX",
- .ifnum = 0,
- .type = QUIRK_MIDI_STANDARD_INTERFACE
- }
-},
-{
- USB_DEVICE(0x0582, 0x0060),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "EXR Series",
- .ifnum = 0,
- .type = QUIRK_MIDI_STANDARD_INTERFACE
- }
-},
-{
- /* has ID 0x0066 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0064),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "EDIROL", */
- /* .product_name = "PCR-1", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x0067 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0065),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "EDIROL", */
- /* .product_name = "PCR-1", */
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0003
- }
- }
-},
-{
- /* has ID 0x006b when not in "Advanced Driver" mode */
- USB_DEVICE_VENDOR_SPEC(0x0582, 0x006a),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "SP-606",
- .ifnum = 3,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- /* has ID 0x006e when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x006d),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "FANTOM-X",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{ /*
- * This quirk is for the "Advanced" modes of the Edirol UA-25.
- * If the switch is not in an advanced setting, the UA-25 has
- * ID 0x0582/0x0073 and is standard compliant (no quirks), but
- * offers only 16-bit PCM at 44.1 kHz and no MIDI.
- */
- USB_DEVICE_VENDOR_SPEC(0x0582, 0x0074),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UA-25",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x0076 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0075),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "BOSS",
- .product_name = "DR-880",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- /* has ID 0x007b when not in "Advanced Driver" mode */
- USB_DEVICE_VENDOR_SPEC(0x0582, 0x007a),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- /* "RD" or "RD-700SX"? */
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0003
- }
- }
-},
-{
- /* has ID 0x0081 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0080),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "G-70",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
- /* TODO: add Roland V-SYNTH XT support */
- /* TODO: add BOSS GT-PRO support */
-{
- /* has ID 0x008c when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x008b),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "PC-50",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
- /* TODO: add Edirol PC-80 support */
-{
- USB_DEVICE(0x0582, 0x0096),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UA-1EX",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x009a),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UM-3EX",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x000f,
- .in_cables = 0x000f
- }
- }
-},
-{
- /*
- * This quirk is for the "Advanced Driver" mode. If off, the UA-4FX
- * is standard compliant, but has only 16-bit PCM and no MIDI.
- */
- USB_DEVICE(0x0582, 0x00a3),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UA-4FX",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = -1
- }
- }
- }
-},
- /* TODO: add Edirol MD-P1 support */
-{
- USB_DEVICE(0x582, 0x00a6),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "Juno-G",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- /* Roland SH-201 */
- USB_DEVICE(0x0582, 0x00ad),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "SH-201",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* Roland SonicCell */
- USB_DEVICE(0x0582, 0x00c2),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "SonicCell",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* Edirol M-16DX */
- /* FIXME: This quirk gives a good-working capture stream but the
- * playback seems problematic because of lacking of sync
- * with capture stream. It needs to sync with the capture
- * clock. As now, you'll get frequent sound distortions
- * via the playback.
- */
- USB_DEVICE(0x0582, 0x00c4),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* BOSS GT-10 */
- USB_DEVICE(0x0582, 0x00da),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* Advanced modes of the Edirol UA-25EX.
- * For the standard mode, UA-25EX has ID 0582:00e7, which
- * offers only 16-bit PCM at 44.1 kHz and no MIDI.
- */
- USB_DEVICE_VENDOR_SPEC(0x0582, 0x00e6),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UA-25EX",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x00ea when not in Advanced Driver mode */
- USB_DEVICE_VENDOR_SPEC(0x0582, 0x00e9),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "Roland", */
- /* .product_name = "UA-1G", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0582, 0x0104),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "Roland", */
- /* .product_name = "UM-1G", */
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- /* Edirol UM-3G */
- USB_DEVICE_VENDOR_SPEC(0x0582, 0x0108),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .ifnum = 0,
- .type = QUIRK_MIDI_STANDARD_INTERFACE
- }
-},
-{
- /* Boss JS-8 Jam Station */
- USB_DEVICE(0x0582, 0x0109),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "BOSS", */
- /* .product_name = "JS-8", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_STANDARD_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x0110 when not in Advanced Driver mode */
- USB_DEVICE_VENDOR_SPEC(0x0582, 0x010f),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "Roland", */
- /* .product_name = "A-PRO", */
- .ifnum = 1,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0007
- }
- }
-},
-{
- /* Roland GAIA SH-01 */
- USB_DEVICE(0x0582, 0x0111),
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "GAIA",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = &(const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0003
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x0113),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "BOSS", */
- /* .product_name = "ME-25", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x0127),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "Roland", */
- /* .product_name = "GR-55", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_STANDARD_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* Added support for Roland UM-ONE which differs from UM-1 */
- USB_DEVICE(0x0582, 0x012a),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "ROLAND", */
- /* .product_name = "UM-ONE", */
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0003
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x011e),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "BOSS", */
- /* .product_name = "BR-800", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x0130),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "BOSS", */
- /* .product_name = "MICRO BR-80", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 3,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-
-/* Guillemot devices */
-{
- /*
- * This is for the "Windows Edition" where the external MIDI ports are
- * the only MIDI ports; the control data is reported through HID
- * interfaces. The "Macintosh Edition" has ID 0xd002 and uses standard
- * compliant USB MIDI ports for external MIDI and controls.
- */
- USB_DEVICE_VENDOR_SPEC(0x06f8, 0xb000),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Hercules",
- .product_name = "DJ Console (WE)",
- .ifnum = 4,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-
-/* Midiman/M-Audio devices */
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x1002),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "MidiSport 2x2",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0003
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x1011),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "MidiSport 1x1",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x1015),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "Keystation",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x1021),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "MidiSport 4x4",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x000f,
- .in_cables = 0x000f
- }
- }
-},
-{
- /*
- * For hardware revision 1.05; in the later revisions (1.10 and
- * 1.21), 0x1031 is the ID for the device without firmware.
- * Thanks to Olaf Giesbrecht <Olaf_Giesbrecht@yahoo.de>
- */
- USB_DEVICE_VER(0x0763, 0x1031, 0x0100, 0x0109),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "MidiSport 8x8",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x01ff,
- .in_cables = 0x01ff
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x1033),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "MidiSport 8x8",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x01ff,
- .in_cables = 0x01ff
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x1041),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "MidiSport 2x4",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x000f,
- .in_cables = 0x0003
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x2001),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "Quattro",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = & (const struct snd_usb_audio_quirk[]) {
- /*
- * Interfaces 0-2 are "Windows-compatible", 16-bit only,
- * and share endpoints with the other interfaces.
- * Ignore them. The other interfaces can do 24 bits,
- * but captured samples are big-endian (see usbaudio.c).
- */
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 3,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 4,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 5,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 6,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 7,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 8,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 9,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x2003),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "AudioPhile",
- .ifnum = 6,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x2008),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "Ozone",
- .ifnum = 3,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x200d),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "OmniStudio",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = & (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 3,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 4,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 5,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 6,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 7,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 8,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 9,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0763, 0x2019),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "M-Audio", */
- /* .product_name = "Ozone Academic", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = & (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 3,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x2080),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "M-Audio", */
- /* .product_name = "Fast Track Ultra", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = & (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_MIXER,
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = & (const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S24_3LE,
- .channels = 8,
- .iface = 1,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
- .endpoint = 0x01,
- .ep_attr = 0x09,
- .rates = SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000,
- .rate_min = 44100,
- .rate_max = 96000,
- .nr_rates = 4,
- .rate_table = (unsigned int[]) {
- 44100, 48000, 88200, 96000
- }
- }
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = & (const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S24_3LE,
- .channels = 8,
- .iface = 2,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
- .endpoint = 0x81,
- .ep_attr = 0x05,
- .rates = SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000,
- .rate_min = 44100,
- .rate_max = 96000,
- .nr_rates = 4,
- .rate_table = (unsigned int[]) {
- 44100, 48000, 88200, 96000
- }
- }
- },
- /* interface 3 (MIDI) is standard compliant */
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x2081),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "M-Audio", */
- /* .product_name = "Fast Track Ultra 8R", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = & (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_MIXER,
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = & (const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S24_3LE,
- .channels = 8,
- .iface = 1,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
- .endpoint = 0x01,
- .ep_attr = 0x09,
- .rates = SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000,
- .rate_min = 44100,
- .rate_max = 96000,
- .nr_rates = 4,
- .rate_table = (unsigned int[]) {
- 44100, 48000, 88200, 96000
- }
- }
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = & (const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S24_3LE,
- .channels = 8,
- .iface = 2,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
- .endpoint = 0x81,
- .ep_attr = 0x05,
- .rates = SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000,
- .rate_min = 44100,
- .rate_max = 96000,
- .nr_rates = 4,
- .rate_table = (unsigned int[]) {
- 44100, 48000, 88200, 96000
- }
- }
- },
- /* interface 3 (MIDI) is standard compliant */
- {
- .ifnum = -1
- }
- }
- }
-},
-
-/* Casio devices */
-{
- USB_DEVICE(0x07cf, 0x6801),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Casio",
- .product_name = "PL-40R",
- .ifnum = 0,
- .type = QUIRK_MIDI_YAMAHA
- }
-},
-{
- /* this ID is used by several devices without a product ID */
- USB_DEVICE(0x07cf, 0x6802),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Casio",
- .product_name = "Keyboard",
- .ifnum = 0,
- .type = QUIRK_MIDI_YAMAHA
- }
-},
-
-/* Mark of the Unicorn devices */
-{
- /* thanks to Robert A. Lerche <ral 'at' msbit.com> */
- .match_flags = USB_DEVICE_ID_MATCH_VENDOR |
- USB_DEVICE_ID_MATCH_PRODUCT |
- USB_DEVICE_ID_MATCH_DEV_SUBCLASS,
- .idVendor = 0x07fd,
- .idProduct = 0x0001,
- .bDeviceSubClass = 2,
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "MOTU",
- .product_name = "Fastlane",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = & (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_MIDI_RAW_BYTES
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-
-/* Emagic devices */
-{
- USB_DEVICE(0x086a, 0x0001),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Emagic",
- /* .product_name = "Unitor8", */
- .ifnum = 2,
- .type = QUIRK_MIDI_EMAGIC,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x80ff,
- .in_cables = 0x80ff
- }
- }
-},
-{
- USB_DEVICE(0x086a, 0x0002),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Emagic",
- /* .product_name = "AMT8", */
- .ifnum = 2,
- .type = QUIRK_MIDI_EMAGIC,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x80ff,
- .in_cables = 0x80ff
- }
- }
-},
-{
- USB_DEVICE(0x086a, 0x0003),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Emagic",
- /* .product_name = "MT4", */
- .ifnum = 2,
- .type = QUIRK_MIDI_EMAGIC,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x800f,
- .in_cables = 0x8003
- }
- }
-},
-
-/* KORG devices */
-{
- USB_DEVICE_VENDOR_SPEC(0x0944, 0x0200),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "KORG, Inc.",
- /* .product_name = "PANDORA PX5D", */
- .ifnum = 3,
- .type = QUIRK_MIDI_STANDARD_INTERFACE,
- }
-},
-
-{
- USB_DEVICE_VENDOR_SPEC(0x0944, 0x0201),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "KORG, Inc.",
- /* .product_name = "ToneLab ST", */
- .ifnum = 3,
- .type = QUIRK_MIDI_STANDARD_INTERFACE,
- }
-},
-
-/* AKAI devices */
-{
- USB_DEVICE(0x09e8, 0x0062),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "AKAI",
- .product_name = "MPD16",
- .ifnum = 0,
- .type = QUIRK_MIDI_AKAI,
- }
-},
-
-/* TerraTec devices */
-{
- USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0012),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "TerraTec",
- .product_name = "PHASE 26",
- .ifnum = 3,
- .type = QUIRK_MIDI_STANDARD_INTERFACE
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0013),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "TerraTec",
- .product_name = "PHASE 26",
- .ifnum = 3,
- .type = QUIRK_MIDI_STANDARD_INTERFACE
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0014),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "TerraTec",
- .product_name = "PHASE 26",
- .ifnum = 3,
- .type = QUIRK_MIDI_STANDARD_INTERFACE
- }
-},
-{
- USB_DEVICE(0x0ccd, 0x0028),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "TerraTec",
- .product_name = "Aureon5.1MkII",
- .ifnum = QUIRK_NO_INTERFACE
- }
-},
-{
- USB_DEVICE(0x0ccd, 0x0035),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Miditech",
- .product_name = "Play'n Roll",
- .ifnum = 0,
- .type = QUIRK_MIDI_CME
- }
-},
-
-/* Stanton/N2IT Final Scratch v1 device ('Scratchamp') */
-{
- USB_DEVICE(0x103d, 0x0100),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Stanton",
- .product_name = "ScratchAmp",
- .ifnum = QUIRK_NO_INTERFACE
- }
-},
-{
- USB_DEVICE(0x103d, 0x0101),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Stanton",
- .product_name = "ScratchAmp",
- .ifnum = QUIRK_NO_INTERFACE
- }
-},
-
-/* Novation EMS devices */
-{
- USB_DEVICE_VENDOR_SPEC(0x1235, 0x0001),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Novation",
- .product_name = "ReMOTE Audio/XStation",
- .ifnum = 4,
- .type = QUIRK_MIDI_NOVATION
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x1235, 0x0002),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Novation",
- .product_name = "Speedio",
- .ifnum = 3,
- .type = QUIRK_MIDI_NOVATION
- }
-},
-{
- USB_DEVICE(0x1235, 0x000e),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "Novation", */
- /* .product_name = "Launchpad", */
- .ifnum = 0,
- .type = QUIRK_MIDI_RAW_BYTES
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x1235, 0x4661),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Novation",
- .product_name = "ReMOTE25",
- .ifnum = 0,
- .type = QUIRK_MIDI_NOVATION
- }
-},
-
-/* Access Music devices */
-{
- /* VirusTI Desktop */
- USB_DEVICE_VENDOR_SPEC(0x133e, 0x0815),
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = &(const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 3,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = &(const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0003
- }
- },
- {
- .ifnum = 4,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-
-/* */
-{
- /* aka. Serato Scratch Live DJ Box */
- USB_DEVICE(0x13e5, 0x0001),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Rane",
- .product_name = "SL-1",
- .ifnum = QUIRK_NO_INTERFACE
- }
-},
-
-/* Native Instruments MK2 series */
-{
- /* Komplete Audio 6 */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x17cc,
- .idProduct = 0x1000,
-},
-{
- /* Traktor Audio 6 */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x17cc,
- .idProduct = 0x1010,
-},
-{
- /* Traktor Audio 10 */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x17cc,
- .idProduct = 0x1020,
-},
-
-/* KeithMcMillen Stringport */
-{
- USB_DEVICE(0x1f38, 0x0001),
- .bInterfaceClass = USB_CLASS_AUDIO,
-},
-
-/* Miditech devices */
-{
- USB_DEVICE(0x4752, 0x0011),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Miditech",
- .product_name = "Midistart-2",
- .ifnum = 0,
- .type = QUIRK_MIDI_CME
- }
-},
-
-/* Central Music devices */
-{
- /* this ID used by both Miditech MidiStudio-2 and CME UF-x */
- USB_DEVICE(0x7104, 0x2202),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .ifnum = 0,
- .type = QUIRK_MIDI_CME
- }
-},
-
-/* Hauppauge HVR-950Q and HVR-850 */
-{
- USB_DEVICE_VENDOR_SPEC(0x2040, 0x7200),
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Hauppauge",
- .product_name = "HVR-950Q",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_AUDIO_ALIGN_TRANSFER,
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x2040, 0x7240),
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Hauppauge",
- .product_name = "HVR-850",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_AUDIO_ALIGN_TRANSFER,
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x2040, 0x7210),
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Hauppauge",
- .product_name = "HVR-950Q",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_AUDIO_ALIGN_TRANSFER,
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x2040, 0x7217),
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Hauppauge",
- .product_name = "HVR-950Q",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_AUDIO_ALIGN_TRANSFER,
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x2040, 0x721b),
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Hauppauge",
- .product_name = "HVR-950Q",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_AUDIO_ALIGN_TRANSFER,
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x2040, 0x721e),
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Hauppauge",
- .product_name = "HVR-950Q",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_AUDIO_ALIGN_TRANSFER,
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x2040, 0x721f),
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Hauppauge",
- .product_name = "HVR-950Q",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_AUDIO_ALIGN_TRANSFER,
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x2040, 0x7280),
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Hauppauge",
- .product_name = "HVR-950Q",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_AUDIO_ALIGN_TRANSFER,
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0fd9, 0x0008),
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Hauppauge",
- .product_name = "HVR-950Q",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_AUDIO_ALIGN_TRANSFER,
- }
-},
-
-/* Digidesign Mbox */
-{
- /* Thanks to Clemens Ladisch <clemens@ladisch.de> */
- USB_DEVICE(0x0dba, 0x1000),
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Digidesign",
- .product_name = "MBox",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]){
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE,
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = &(const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S24_3BE,
- .channels = 2,
- .iface = 1,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
- .endpoint = 0x02,
- .ep_attr = 0x01,
- .maxpacksize = 0x130,
- .rates = SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000,
- .rate_min = 44100,
- .rate_max = 48000,
- .nr_rates = 2,
- .rate_table = (unsigned int[]) {
- 44100, 48000
- }
- }
- },
- {
- .ifnum = -1
- }
- }
-
- }
-},
-
-{
- /*
- * Some USB MIDI devices don't have an audio control interface,
- * so we have to grab MIDI streaming interfaces here.
- */
- .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_MIDISTREAMING,
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_MIDI_STANDARD_INTERFACE
- }
-},
-
-#undef USB_DEVICE_VENDOR_SPEC
diff --git a/ANDROID_3.4.5/sound/usb/quirks.c b/ANDROID_3.4.5/sound/usb/quirks.c
deleted file mode 100644
index 27817266..00000000
--- a/ANDROID_3.4.5/sound/usb/quirks.c
+++ /dev/null
@@ -1,763 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/usb/audio.h>
-
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/pcm.h>
-
-#include "usbaudio.h"
-#include "card.h"
-#include "mixer.h"
-#include "mixer_quirks.h"
-#include "midi.h"
-#include "quirks.h"
-#include "helper.h"
-#include "endpoint.h"
-#include "pcm.h"
-#include "clock.h"
-#include "stream.h"
-
-/*
- * handle the quirks for the contained interfaces
- */
-static int create_composite_quirk(struct snd_usb_audio *chip,
- struct usb_interface *iface,
- struct usb_driver *driver,
- const struct snd_usb_audio_quirk *quirk)
-{
- int probed_ifnum = get_iface_desc(iface->altsetting)->bInterfaceNumber;
- int err;
-
- for (quirk = quirk->data; quirk->ifnum >= 0; ++quirk) {
- iface = usb_ifnum_to_if(chip->dev, quirk->ifnum);
- if (!iface)
- continue;
- if (quirk->ifnum != probed_ifnum &&
- usb_interface_claimed(iface))
- continue;
- err = snd_usb_create_quirk(chip, iface, driver, quirk);
- if (err < 0)
- return err;
- if (quirk->ifnum != probed_ifnum)
- usb_driver_claim_interface(driver, iface, (void *)-1L);
- }
- return 0;
-}
-
-static int ignore_interface_quirk(struct snd_usb_audio *chip,
- struct usb_interface *iface,
- struct usb_driver *driver,
- const struct snd_usb_audio_quirk *quirk)
-{
- return 0;
-}
-
-
-/*
- * Allow alignment on audio sub-slot (channel samples) rather than
- * on audio slots (audio frames)
- */
-static int create_align_transfer_quirk(struct snd_usb_audio *chip,
- struct usb_interface *iface,
- struct usb_driver *driver,
- const struct snd_usb_audio_quirk *quirk)
-{
- chip->txfr_quirk = 1;
- return 1; /* Continue with creating streams and mixer */
-}
-
-static int create_any_midi_quirk(struct snd_usb_audio *chip,
- struct usb_interface *intf,
- struct usb_driver *driver,
- const struct snd_usb_audio_quirk *quirk)
-{
- return snd_usbmidi_create(chip->card, intf, &chip->midi_list, quirk);
-}
-
-/*
- * create a stream for an interface with proper descriptors
- */
-static int create_standard_audio_quirk(struct snd_usb_audio *chip,
- struct usb_interface *iface,
- struct usb_driver *driver,
- const struct snd_usb_audio_quirk *quirk)
-{
- struct usb_host_interface *alts;
- struct usb_interface_descriptor *altsd;
- int err;
-
- alts = &iface->altsetting[0];
- altsd = get_iface_desc(alts);
- err = snd_usb_parse_audio_interface(chip, altsd->bInterfaceNumber);
- if (err < 0) {
- snd_printk(KERN_ERR "cannot setup if %d: error %d\n",
- altsd->bInterfaceNumber, err);
- return err;
- }
- /* reset the current interface */
- usb_set_interface(chip->dev, altsd->bInterfaceNumber, 0);
- return 0;
-}
-
-/*
- * create a stream for an endpoint/altsetting without proper descriptors
- */
-static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
- struct usb_interface *iface,
- struct usb_driver *driver,
- const struct snd_usb_audio_quirk *quirk)
-{
- struct audioformat *fp;
- struct usb_host_interface *alts;
- int stream, err;
- unsigned *rate_table = NULL;
-
- fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
- if (!fp) {
- snd_printk(KERN_ERR "cannot memdup\n");
- return -ENOMEM;
- }
- if (fp->nr_rates > MAX_NR_RATES) {
- kfree(fp);
- return -EINVAL;
- }
- if (fp->nr_rates > 0) {
- rate_table = kmemdup(fp->rate_table,
- sizeof(int) * fp->nr_rates, GFP_KERNEL);
- if (!rate_table) {
- kfree(fp);
- return -ENOMEM;
- }
- fp->rate_table = rate_table;
- }
-
- stream = (fp->endpoint & USB_DIR_IN)
- ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
- err = snd_usb_add_audio_stream(chip, stream, fp);
- if (err < 0) {
- kfree(fp);
- kfree(rate_table);
- return err;
- }
- if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber ||
- fp->altset_idx >= iface->num_altsetting) {
- kfree(fp);
- kfree(rate_table);
- return -EINVAL;
- }
- alts = &iface->altsetting[fp->altset_idx];
- fp->datainterval = snd_usb_parse_datainterval(chip, alts);
- fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
- usb_set_interface(chip->dev, fp->iface, 0);
- snd_usb_init_pitch(chip, fp->iface, alts, fp);
- snd_usb_init_sample_rate(chip, fp->iface, alts, fp, fp->rate_max);
- return 0;
-}
-
-/*
- * Create a stream for an Edirol UA-700/UA-25/UA-4FX interface.
- * The only way to detect the sample rate is by looking at wMaxPacketSize.
- */
-static int create_uaxx_quirk(struct snd_usb_audio *chip,
- struct usb_interface *iface,
- struct usb_driver *driver,
- const struct snd_usb_audio_quirk *quirk)
-{
- static const struct audioformat ua_format = {
- .formats = SNDRV_PCM_FMTBIT_S24_3LE,
- .channels = 2,
- .fmt_type = UAC_FORMAT_TYPE_I,
- .altsetting = 1,
- .altset_idx = 1,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- };
- struct usb_host_interface *alts;
- struct usb_interface_descriptor *altsd;
- struct audioformat *fp;
- int stream, err;
-
- /* both PCM and MIDI interfaces have 2 or more altsettings */
- if (iface->num_altsetting < 2)
- return -ENXIO;
- alts = &iface->altsetting[1];
- altsd = get_iface_desc(alts);
-
- if (altsd->bNumEndpoints == 2) {
- static const struct snd_usb_midi_endpoint_info ua700_ep = {
- .out_cables = 0x0003,
- .in_cables = 0x0003
- };
- static const struct snd_usb_audio_quirk ua700_quirk = {
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = &ua700_ep
- };
- static const struct snd_usb_midi_endpoint_info uaxx_ep = {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- };
- static const struct snd_usb_audio_quirk uaxx_quirk = {
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = &uaxx_ep
- };
- const struct snd_usb_audio_quirk *quirk =
- chip->usb_id == USB_ID(0x0582, 0x002b)
- ? &ua700_quirk : &uaxx_quirk;
- return snd_usbmidi_create(chip->card, iface,
- &chip->midi_list, quirk);
- }
-
- if (altsd->bNumEndpoints != 1)
- return -ENXIO;
-
- fp = kmemdup(&ua_format, sizeof(*fp), GFP_KERNEL);
- if (!fp)
- return -ENOMEM;
-
- fp->iface = altsd->bInterfaceNumber;
- fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
- fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
- fp->datainterval = 0;
- fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
-
- switch (fp->maxpacksize) {
- case 0x120:
- fp->rate_max = fp->rate_min = 44100;
- break;
- case 0x138:
- case 0x140:
- fp->rate_max = fp->rate_min = 48000;
- break;
- case 0x258:
- case 0x260:
- fp->rate_max = fp->rate_min = 96000;
- break;
- default:
- snd_printk(KERN_ERR "unknown sample rate\n");
- kfree(fp);
- return -ENXIO;
- }
-
- stream = (fp->endpoint & USB_DIR_IN)
- ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
- err = snd_usb_add_audio_stream(chip, stream, fp);
- if (err < 0) {
- kfree(fp);
- return err;
- }
- usb_set_interface(chip->dev, fp->iface, 0);
- return 0;
-}
-
-/*
- * Create a standard mixer for the specified interface.
- */
-static int create_standard_mixer_quirk(struct snd_usb_audio *chip,
- struct usb_interface *iface,
- struct usb_driver *driver,
- const struct snd_usb_audio_quirk *quirk)
-{
- if (quirk->ifnum < 0)
- return 0;
-
- return snd_usb_create_mixer(chip, quirk->ifnum, 0);
-}
-
-/*
- * audio-interface quirks
- *
- * returns zero if no standard audio/MIDI parsing is needed.
- * returns a positive value if standard audio/midi interfaces are parsed
- * after this.
- * returns a negative value at error.
- */
-int snd_usb_create_quirk(struct snd_usb_audio *chip,
- struct usb_interface *iface,
- struct usb_driver *driver,
- const struct snd_usb_audio_quirk *quirk)
-{
- typedef int (*quirk_func_t)(struct snd_usb_audio *,
- struct usb_interface *,
- struct usb_driver *,
- const struct snd_usb_audio_quirk *);
- static const quirk_func_t quirk_funcs[] = {
- [QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk,
- [QUIRK_COMPOSITE] = create_composite_quirk,
- [QUIRK_MIDI_STANDARD_INTERFACE] = create_any_midi_quirk,
- [QUIRK_MIDI_FIXED_ENDPOINT] = create_any_midi_quirk,
- [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk,
- [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk,
- [QUIRK_MIDI_NOVATION] = create_any_midi_quirk,
- [QUIRK_MIDI_RAW_BYTES] = create_any_midi_quirk,
- [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk,
- [QUIRK_MIDI_CME] = create_any_midi_quirk,
- [QUIRK_MIDI_AKAI] = create_any_midi_quirk,
- [QUIRK_MIDI_FTDI] = create_any_midi_quirk,
- [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
- [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
- [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
- [QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk,
- [QUIRK_AUDIO_STANDARD_MIXER] = create_standard_mixer_quirk,
- };
-
- if (quirk->type < QUIRK_TYPE_COUNT) {
- return quirk_funcs[quirk->type](chip, iface, driver, quirk);
- } else {
- snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
- return -ENXIO;
- }
-}
-
-/*
- * boot quirks
- */
-
-#define EXTIGY_FIRMWARE_SIZE_OLD 794
-#define EXTIGY_FIRMWARE_SIZE_NEW 483
-
-static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interface *intf)
-{
- struct usb_host_config *config = dev->actconfig;
- int err;
-
- if (le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_OLD ||
- le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_NEW) {
- snd_printdd("sending Extigy boot sequence...\n");
- /* Send message to force it to reconnect with full interface. */
- err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0),
- 0x10, 0x43, 0x0001, 0x000a, NULL, 0);
- if (err < 0) snd_printdd("error sending boot message: %d\n", err);
- err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
- &dev->descriptor, sizeof(dev->descriptor));
- config = dev->actconfig;
- if (err < 0) snd_printdd("error usb_get_descriptor: %d\n", err);
- err = usb_reset_configuration(dev);
- if (err < 0) snd_printdd("error usb_reset_configuration: %d\n", err);
- snd_printdd("extigy_boot: new boot length = %d\n",
- le16_to_cpu(get_cfg_desc(config)->wTotalLength));
- return -ENODEV; /* quit this anyway */
- }
- return 0;
-}
-
-static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev)
-{
- u8 buf = 1;
-
- snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
- 0, 0, &buf, 1);
- if (buf == 0) {
- snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
- 1, 2000, NULL, 0);
- return -ENODEV;
- }
- return 0;
-}
-
-static int snd_usb_fasttrackpro_boot_quirk(struct usb_device *dev)
-{
- int err;
-
- if (dev->actconfig->desc.bConfigurationValue == 1) {
- snd_printk(KERN_INFO "usb-audio: "
- "Fast Track Pro switching to config #2\n");
- /* This function has to be available by the usb core module.
- * if it is not avialable the boot quirk has to be left out
- * and the configuration has to be set by udev or hotplug
- * rules
- */
- err = usb_driver_set_configuration(dev, 2);
- if (err < 0) {
- snd_printdd("error usb_driver_set_configuration: %d\n",
- err);
- return -ENODEV;
- }
- } else
- snd_printk(KERN_INFO "usb-audio: Fast Track Pro config OK\n");
-
- return 0;
-}
-
-/*
- * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely
- * documented in the device's data sheet.
- */
-static int snd_usb_cm106_write_int_reg(struct usb_device *dev, int reg, u16 value)
-{
- u8 buf[4];
- buf[0] = 0x20;
- buf[1] = value & 0xff;
- buf[2] = (value >> 8) & 0xff;
- buf[3] = reg;
- return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION,
- USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
- 0, 0, &buf, 4);
-}
-
-static int snd_usb_cm106_boot_quirk(struct usb_device *dev)
-{
- /*
- * Enable line-out driver mode, set headphone source to front
- * channels, enable stereo mic.
- */
- return snd_usb_cm106_write_int_reg(dev, 2, 0x8004);
-}
-
-/*
- * C-Media CM6206 is based on CM106 with two additional
- * registers that are not documented in the data sheet.
- * Values here are chosen based on sniffing USB traffic
- * under Windows.
- */
-static int snd_usb_cm6206_boot_quirk(struct usb_device *dev)
-{
- int err = 0, reg;
- int val[] = {0x2004, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000};
-
- for (reg = 0; reg < ARRAY_SIZE(val); reg++) {
- err = snd_usb_cm106_write_int_reg(dev, reg, val[reg]);
- if (err < 0)
- return err;
- }
-
- return err;
-}
-
-/*
- * This call will put the synth in "USB send" mode, i.e it will send MIDI
- * messages through USB (this is disabled at startup). The synth will
- * acknowledge by sending a sysex on endpoint 0x85 and by displaying a USB
- * sign on its LCD. Values here are chosen based on sniffing USB traffic
- * under Windows.
- */
-static int snd_usb_accessmusic_boot_quirk(struct usb_device *dev)
-{
- int err, actual_length;
-
- /* "midi send" enable */
- static const u8 seq[] = { 0x4e, 0x73, 0x52, 0x01 };
-
- void *buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
- err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x05), buf,
- ARRAY_SIZE(seq), &actual_length, 1000);
- kfree(buf);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-/*
- * Some sound cards from Native Instruments are in fact compliant to the USB
- * audio standard of version 2 and other approved USB standards, even though
- * they come up as vendor-specific device when first connected.
- *
- * However, they can be told to come up with a new set of descriptors
- * upon their next enumeration, and the interfaces announced by the new
- * descriptors will then be handled by the kernel's class drivers. As the
- * product ID will also change, no further checks are required.
- */
-
-static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev)
-{
- int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- 0xaf, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- cpu_to_le16(1), 0, NULL, 0, 1000);
-
- if (ret < 0)
- return ret;
-
- usb_reset_device(dev);
-
- /* return -EAGAIN, so the creation of an audio interface for this
- * temporary device is aborted. The device will reconnect with a
- * new product ID */
- return -EAGAIN;
-}
-
-/*
- * Setup quirks
- */
-#define MAUDIO_SET 0x01 /* parse device_setup */
-#define MAUDIO_SET_COMPATIBLE 0x80 /* use only "win-compatible" interfaces */
-#define MAUDIO_SET_DTS 0x02 /* enable DTS Digital Output */
-#define MAUDIO_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
-#define MAUDIO_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */
-#define MAUDIO_SET_DI 0x10 /* enable Digital Input */
-#define MAUDIO_SET_MASK 0x1f /* bit mask for setup value */
-#define MAUDIO_SET_24B_48K_DI 0x19 /* 24bits+48KHz+Digital Input */
-#define MAUDIO_SET_24B_48K_NOTDI 0x09 /* 24bits+48KHz+No Digital Input */
-#define MAUDIO_SET_16B_48K_DI 0x11 /* 16bits+48KHz+Digital Input */
-#define MAUDIO_SET_16B_48K_NOTDI 0x01 /* 16bits+48KHz+No Digital Input */
-
-static int quattro_skip_setting_quirk(struct snd_usb_audio *chip,
- int iface, int altno)
-{
- /* Reset ALL ifaces to 0 altsetting.
- * Call it for every possible altsetting of every interface.
- */
- usb_set_interface(chip->dev, iface, 0);
- if (chip->setup & MAUDIO_SET) {
- if (chip->setup & MAUDIO_SET_COMPATIBLE) {
- if (iface != 1 && iface != 2)
- return 1; /* skip all interfaces but 1 and 2 */
- } else {
- unsigned int mask;
- if (iface == 1 || iface == 2)
- return 1; /* skip interfaces 1 and 2 */
- if ((chip->setup & MAUDIO_SET_96K) && altno != 1)
- return 1; /* skip this altsetting */
- mask = chip->setup & MAUDIO_SET_MASK;
- if (mask == MAUDIO_SET_24B_48K_DI && altno != 2)
- return 1; /* skip this altsetting */
- if (mask == MAUDIO_SET_24B_48K_NOTDI && altno != 3)
- return 1; /* skip this altsetting */
- if (mask == MAUDIO_SET_16B_48K_NOTDI && altno != 4)
- return 1; /* skip this altsetting */
- }
- }
- snd_printdd(KERN_INFO
- "using altsetting %d for interface %d config %d\n",
- altno, iface, chip->setup);
- return 0; /* keep this altsetting */
-}
-
-static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
- int iface,
- int altno)
-{
- /* Reset ALL ifaces to 0 altsetting.
- * Call it for every possible altsetting of every interface.
- */
- usb_set_interface(chip->dev, iface, 0);
-
- if (chip->setup & MAUDIO_SET) {
- unsigned int mask;
- if ((chip->setup & MAUDIO_SET_DTS) && altno != 6)
- return 1; /* skip this altsetting */
- if ((chip->setup & MAUDIO_SET_96K) && altno != 1)
- return 1; /* skip this altsetting */
- mask = chip->setup & MAUDIO_SET_MASK;
- if (mask == MAUDIO_SET_24B_48K_DI && altno != 2)
- return 1; /* skip this altsetting */
- if (mask == MAUDIO_SET_24B_48K_NOTDI && altno != 3)
- return 1; /* skip this altsetting */
- if (mask == MAUDIO_SET_16B_48K_DI && altno != 4)
- return 1; /* skip this altsetting */
- if (mask == MAUDIO_SET_16B_48K_NOTDI && altno != 5)
- return 1; /* skip this altsetting */
- }
-
- return 0; /* keep this altsetting */
-}
-
-
-static int fasttrackpro_skip_setting_quirk(struct snd_usb_audio *chip,
- int iface, int altno)
-{
- /* Reset ALL ifaces to 0 altsetting.
- * Call it for every possible altsetting of every interface.
- */
- usb_set_interface(chip->dev, iface, 0);
-
- /* possible configuration where both inputs and only one output is
- *used is not supported by the current setup
- */
- if (chip->setup & (MAUDIO_SET | MAUDIO_SET_24B)) {
- if (chip->setup & MAUDIO_SET_96K) {
- if (altno != 3 && altno != 6)
- return 1;
- } else if (chip->setup & MAUDIO_SET_DI) {
- if (iface == 4)
- return 1; /* no analog input */
- if (altno != 2 && altno != 5)
- return 1; /* enable only altsets 2 and 5 */
- } else {
- if (iface == 5)
- return 1; /* disable digialt input */
- if (altno != 2 && altno != 5)
- return 1; /* enalbe only altsets 2 and 5 */
- }
- } else {
- /* keep only 16-Bit mode */
- if (altno != 1)
- return 1;
- }
-
- snd_printdd(KERN_INFO
- "using altsetting %d for interface %d config %d\n",
- altno, iface, chip->setup);
- return 0; /* keep this altsetting */
-}
-
-int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
- int iface,
- int altno)
-{
- /* audiophile usb: skip altsets incompatible with device_setup */
- if (chip->usb_id == USB_ID(0x0763, 0x2003))
- return audiophile_skip_setting_quirk(chip, iface, altno);
- /* quattro usb: skip altsets incompatible with device_setup */
- if (chip->usb_id == USB_ID(0x0763, 0x2001))
- return quattro_skip_setting_quirk(chip, iface, altno);
- /* fasttrackpro usb: skip altsets incompatible with device_setup */
- if (chip->usb_id == USB_ID(0x0763, 0x2012))
- return fasttrackpro_skip_setting_quirk(chip, iface, altno);
-
- return 0;
-}
-
-int snd_usb_apply_boot_quirk(struct usb_device *dev,
- struct usb_interface *intf,
- const struct snd_usb_audio_quirk *quirk)
-{
- u32 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
- le16_to_cpu(dev->descriptor.idProduct));
-
- switch (id) {
- case USB_ID(0x041e, 0x3000):
- /* SB Extigy needs special boot-up sequence */
- /* if more models come, this will go to the quirk list. */
- return snd_usb_extigy_boot_quirk(dev, intf);
-
- case USB_ID(0x041e, 0x3020):
- /* SB Audigy 2 NX needs its own boot-up magic, too */
- return snd_usb_audigy2nx_boot_quirk(dev);
-
- case USB_ID(0x10f5, 0x0200):
- /* C-Media CM106 / Turtle Beach Audio Advantage Roadie */
- return snd_usb_cm106_boot_quirk(dev);
-
- case USB_ID(0x0d8c, 0x0102):
- /* C-Media CM6206 / CM106-Like Sound Device */
- case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */
- return snd_usb_cm6206_boot_quirk(dev);
-
- case USB_ID(0x133e, 0x0815):
- /* Access Music VirusTI Desktop */
- return snd_usb_accessmusic_boot_quirk(dev);
-
- case USB_ID(0x17cc, 0x1000): /* Komplete Audio 6 */
- case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */
- case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */
- return snd_usb_nativeinstruments_boot_quirk(dev);
- case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */
- return snd_usb_fasttrackpro_boot_quirk(dev);
- }
-
- return 0;
-}
-
-/*
- * check if the device uses big-endian samples
- */
-int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp)
-{
- /* it depends on altsetting wether the device is big-endian or not */
- switch (chip->usb_id) {
- case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
- if (fp->altsetting == 2 || fp->altsetting == 3 ||
- fp->altsetting == 5 || fp->altsetting == 6)
- return 1;
- break;
- case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
- if (chip->setup == 0x00 ||
- fp->altsetting == 1 || fp->altsetting == 2 ||
- fp->altsetting == 3)
- return 1;
- break;
- case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro */
- if (fp->altsetting == 2 || fp->altsetting == 3 ||
- fp->altsetting == 5 || fp->altsetting == 6)
- return 1;
- break;
- }
- return 0;
-}
-
-/*
- * For E-Mu 0404USB/0202USB/TrackerPre/0204 sample rate should be set for device,
- * not for interface.
- */
-
-enum {
- EMU_QUIRK_SR_44100HZ = 0,
- EMU_QUIRK_SR_48000HZ,
- EMU_QUIRK_SR_88200HZ,
- EMU_QUIRK_SR_96000HZ,
- EMU_QUIRK_SR_176400HZ,
- EMU_QUIRK_SR_192000HZ
-};
-
-static void set_format_emu_quirk(struct snd_usb_substream *subs,
- struct audioformat *fmt)
-{
- unsigned char emu_samplerate_id = 0;
-
- /* When capture is active
- * sample rate shouldn't be changed
- * by playback substream
- */
- if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
- if (subs->stream->substream[SNDRV_PCM_STREAM_CAPTURE].interface != -1)
- return;
- }
-
- switch (fmt->rate_min) {
- case 48000:
- emu_samplerate_id = EMU_QUIRK_SR_48000HZ;
- break;
- case 88200:
- emu_samplerate_id = EMU_QUIRK_SR_88200HZ;
- break;
- case 96000:
- emu_samplerate_id = EMU_QUIRK_SR_96000HZ;
- break;
- case 176400:
- emu_samplerate_id = EMU_QUIRK_SR_176400HZ;
- break;
- case 192000:
- emu_samplerate_id = EMU_QUIRK_SR_192000HZ;
- break;
- default:
- emu_samplerate_id = EMU_QUIRK_SR_44100HZ;
- break;
- }
- snd_emuusb_set_samplerate(subs->stream->chip, emu_samplerate_id);
-}
-
-void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
- struct audioformat *fmt)
-{
- switch (subs->stream->chip->usb_id) {
- case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
- case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
- case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
- case USB_ID(0x041e, 0x3f19): /* E-Mu 0204 USB */
- set_format_emu_quirk(subs, fmt);
- break;
- }
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/quirks.h b/ANDROID_3.4.5/sound/usb/quirks.h
deleted file mode 100644
index 03e5e940..00000000
--- a/ANDROID_3.4.5/sound/usb/quirks.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef __USBAUDIO_QUIRKS_H
-#define __USBAUDIO_QUIRKS_H
-
-int snd_usb_create_quirk(struct snd_usb_audio *chip,
- struct usb_interface *iface,
- struct usb_driver *driver,
- const struct snd_usb_audio_quirk *quirk);
-
-int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
- int iface,
- int altno);
-
-int snd_usb_apply_boot_quirk(struct usb_device *dev,
- struct usb_interface *intf,
- const struct snd_usb_audio_quirk *quirk);
-
-void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
- struct audioformat *fmt);
-
-int snd_usb_is_big_endian_format(struct snd_usb_audio *chip,
- struct audioformat *fp);
-
-#endif /* __USBAUDIO_QUIRKS_H */
diff --git a/ANDROID_3.4.5/sound/usb/stream.c b/ANDROID_3.4.5/sound/usb/stream.c
deleted file mode 100644
index 5ff8010b..00000000
--- a/ANDROID_3.4.5/sound/usb/stream.c
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/usb/audio.h>
-#include <linux/usb/audio-v2.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include "usbaudio.h"
-#include "card.h"
-#include "proc.h"
-#include "quirks.h"
-#include "endpoint.h"
-#include "pcm.h"
-#include "helper.h"
-#include "format.h"
-#include "clock.h"
-#include "stream.h"
-
-/*
- * free a substream
- */
-static void free_substream(struct snd_usb_substream *subs)
-{
- struct list_head *p, *n;
-
- if (!subs->num_formats)
- return; /* not initialized */
- list_for_each_safe(p, n, &subs->fmt_list) {
- struct audioformat *fp = list_entry(p, struct audioformat, list);
- kfree(fp->rate_table);
- kfree(fp);
- }
- kfree(subs->rate_list.list);
-}
-
-
-/*
- * free a usb stream instance
- */
-static void snd_usb_audio_stream_free(struct snd_usb_stream *stream)
-{
- free_substream(&stream->substream[0]);
- free_substream(&stream->substream[1]);
- list_del(&stream->list);
- kfree(stream);
-}
-
-static void snd_usb_audio_pcm_free(struct snd_pcm *pcm)
-{
- struct snd_usb_stream *stream = pcm->private_data;
- if (stream) {
- stream->pcm = NULL;
- snd_usb_audio_stream_free(stream);
- }
-}
-
-
-/*
- * add this endpoint to the chip instance.
- * if a stream with the same endpoint already exists, append to it.
- * if not, create a new pcm stream.
- */
-int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
- int stream,
- struct audioformat *fp)
-{
- struct list_head *p;
- struct snd_usb_stream *as;
- struct snd_usb_substream *subs;
- struct snd_pcm *pcm;
- int err;
-
- list_for_each(p, &chip->pcm_list) {
- as = list_entry(p, struct snd_usb_stream, list);
- if (as->fmt_type != fp->fmt_type)
- continue;
- subs = &as->substream[stream];
- if (!subs->endpoint)
- continue;
- if (subs->endpoint == fp->endpoint) {
- list_add_tail(&fp->list, &subs->fmt_list);
- subs->num_formats++;
- subs->formats |= fp->formats;
- return 0;
- }
- }
- /* look for an empty stream */
- list_for_each(p, &chip->pcm_list) {
- as = list_entry(p, struct snd_usb_stream, list);
- if (as->fmt_type != fp->fmt_type)
- continue;
- subs = &as->substream[stream];
- if (subs->endpoint)
- continue;
- err = snd_pcm_new_stream(as->pcm, stream, 1);
- if (err < 0)
- return err;
- snd_usb_init_substream(as, stream, fp);
- return 0;
- }
-
- /* create a new pcm */
- as = kzalloc(sizeof(*as), GFP_KERNEL);
- if (!as)
- return -ENOMEM;
- as->pcm_index = chip->pcm_devs;
- as->chip = chip;
- as->fmt_type = fp->fmt_type;
- err = snd_pcm_new(chip->card, "USB Audio", chip->pcm_devs,
- stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0,
- stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1,
- &pcm);
- if (err < 0) {
- kfree(as);
- return err;
- }
- as->pcm = pcm;
- pcm->private_data = as;
- pcm->private_free = snd_usb_audio_pcm_free;
- pcm->info_flags = 0;
- if (chip->pcm_devs > 0)
- sprintf(pcm->name, "USB Audio #%d", chip->pcm_devs);
- else
- strcpy(pcm->name, "USB Audio");
-
- snd_usb_init_substream(as, stream, fp);
-
- list_add(&as->list, &chip->pcm_list);
- chip->pcm_devs++;
-
- snd_usb_proc_pcm_format_add(as);
-
- return 0;
-}
-
-static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip,
- struct usb_host_interface *alts,
- int protocol, int iface_no)
-{
- /* parsed with a v1 header here. that's ok as we only look at the
- * header first which is the same for both versions */
- struct uac_iso_endpoint_descriptor *csep;
- struct usb_interface_descriptor *altsd = get_iface_desc(alts);
- int attributes = 0;
-
- csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT);
-
- /* Creamware Noah has this descriptor after the 2nd endpoint */
- if (!csep && altsd->bNumEndpoints >= 2)
- csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
-
- if (!csep || csep->bLength < 7 ||
- csep->bDescriptorSubtype != UAC_EP_GENERAL) {
- snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
- " class specific endpoint descriptor\n",
- chip->dev->devnum, iface_no,
- altsd->bAlternateSetting);
- return 0;
- }
-
- if (protocol == UAC_VERSION_1) {
- attributes = csep->bmAttributes;
- } else {
- struct uac2_iso_endpoint_descriptor *csep2 =
- (struct uac2_iso_endpoint_descriptor *) csep;
-
- attributes = csep->bmAttributes & UAC_EP_CS_ATTR_FILL_MAX;
-
- /* emulate the endpoint attributes of a v1 device */
- if (csep2->bmControls & UAC2_CONTROL_PITCH)
- attributes |= UAC_EP_CS_ATTR_PITCH_CONTROL;
- }
-
- return attributes;
-}
-
-static struct uac2_input_terminal_descriptor *
- snd_usb_find_input_terminal_descriptor(struct usb_host_interface *ctrl_iface,
- int terminal_id)
-{
- struct uac2_input_terminal_descriptor *term = NULL;
-
- while ((term = snd_usb_find_csint_desc(ctrl_iface->extra,
- ctrl_iface->extralen,
- term, UAC_INPUT_TERMINAL))) {
- if (term->bTerminalID == terminal_id)
- return term;
- }
-
- return NULL;
-}
-
-static struct uac2_output_terminal_descriptor *
- snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface,
- int terminal_id)
-{
- struct uac2_output_terminal_descriptor *term = NULL;
-
- while ((term = snd_usb_find_csint_desc(ctrl_iface->extra,
- ctrl_iface->extralen,
- term, UAC_OUTPUT_TERMINAL))) {
- if (term->bTerminalID == terminal_id)
- return term;
- }
-
- return NULL;
-}
-
-int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
-{
- struct usb_device *dev;
- struct usb_interface *iface;
- struct usb_host_interface *alts;
- struct usb_interface_descriptor *altsd;
- int i, altno, err, stream;
- int format = 0, num_channels = 0;
- struct audioformat *fp = NULL;
- int num, protocol, clock = 0;
- struct uac_format_type_i_continuous_descriptor *fmt;
-
- dev = chip->dev;
-
- /* parse the interface's altsettings */
- iface = usb_ifnum_to_if(dev, iface_no);
-
- num = iface->num_altsetting;
-
- /*
- * Dallas DS4201 workaround: It presents 5 altsettings, but the last
- * one misses syncpipe, and does not produce any sound.
- */
- if (chip->usb_id == USB_ID(0x04fa, 0x4201))
- num = 4;
-
- for (i = 0; i < num; i++) {
- alts = &iface->altsetting[i];
- altsd = get_iface_desc(alts);
- protocol = altsd->bInterfaceProtocol;
- /* skip invalid one */
- if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
- altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
- (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING &&
- altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) ||
- altsd->bNumEndpoints < 1 ||
- le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0)
- continue;
- /* must be isochronous */
- if ((get_endpoint(alts, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
- USB_ENDPOINT_XFER_ISOC)
- continue;
- /* check direction */
- stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ?
- SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
- altno = altsd->bAlternateSetting;
-
- if (snd_usb_apply_interface_quirk(chip, iface_no, altno))
- continue;
-
- /* get audio formats */
- switch (protocol) {
- default:
- snd_printdd(KERN_WARNING "%d:%u:%d: unknown interface protocol %#02x, assuming v1\n",
- dev->devnum, iface_no, altno, protocol);
- protocol = UAC_VERSION_1;
- /* fall through */
-
- case UAC_VERSION_1: {
- struct uac1_as_header_descriptor *as =
- snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
-
- if (!as) {
- snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
- dev->devnum, iface_no, altno);
- continue;
- }
-
- if (as->bLength < sizeof(*as)) {
- snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n",
- dev->devnum, iface_no, altno);
- continue;
- }
-
- format = le16_to_cpu(as->wFormatTag); /* remember the format value */
- break;
- }
-
- case UAC_VERSION_2: {
- struct uac2_input_terminal_descriptor *input_term;
- struct uac2_output_terminal_descriptor *output_term;
- struct uac2_as_header_descriptor *as =
- snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
-
- if (!as) {
- snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
- dev->devnum, iface_no, altno);
- continue;
- }
-
- if (as->bLength < sizeof(*as)) {
- snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n",
- dev->devnum, iface_no, altno);
- continue;
- }
-
- num_channels = as->bNrChannels;
- format = le32_to_cpu(as->bmFormats);
-
- /* lookup the terminal associated to this interface
- * to extract the clock */
- input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
- as->bTerminalLink);
- if (input_term) {
- clock = input_term->bCSourceID;
- break;
- }
-
- output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf,
- as->bTerminalLink);
- if (output_term) {
- clock = output_term->bCSourceID;
- break;
- }
-
- snd_printk(KERN_ERR "%d:%u:%d : bogus bTerminalLink %d\n",
- dev->devnum, iface_no, altno, as->bTerminalLink);
- continue;
- }
- }
-
- /* get format type */
- fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE);
- if (!fmt) {
- snd_printk(KERN_ERR "%d:%u:%d : no UAC_FORMAT_TYPE desc\n",
- dev->devnum, iface_no, altno);
- continue;
- }
- if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) ||
- ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) {
- snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
- dev->devnum, iface_no, altno);
- continue;
- }
-
- /*
- * Blue Microphones workaround: The last altsetting is identical
- * with the previous one, except for a larger packet size, but
- * is actually a mislabeled two-channel setting; ignore it.
- */
- if (fmt->bNrChannels == 1 &&
- fmt->bSubframeSize == 2 &&
- altno == 2 && num == 3 &&
- fp && fp->altsetting == 1 && fp->channels == 1 &&
- fp->formats == SNDRV_PCM_FMTBIT_S16_LE &&
- protocol == UAC_VERSION_1 &&
- le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) ==
- fp->maxpacksize * 2)
- continue;
-
- fp = kzalloc(sizeof(*fp), GFP_KERNEL);
- if (! fp) {
- snd_printk(KERN_ERR "cannot malloc\n");
- return -ENOMEM;
- }
-
- fp->iface = iface_no;
- fp->altsetting = altno;
- fp->altset_idx = i;
- fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
- fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
- fp->datainterval = snd_usb_parse_datainterval(chip, alts);
- fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
- /* num_channels is only set for v2 interfaces */
- fp->channels = num_channels;
- if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
- fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
- * (fp->maxpacksize & 0x7ff);
- fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no);
- fp->clock = clock;
-
- /* some quirks for attributes here */
-
- switch (chip->usb_id) {
- case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */
- /* Optoplay sets the sample rate attribute although
- * it seems not supporting it in fact.
- */
- fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE;
- break;
- case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */
- case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
- /* doesn't set the sample rate attribute, but supports it */
- fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
- break;
- case USB_ID(0x0763, 0x2001): /* M-Audio Quattro USB */
- case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */
- case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
- case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
- an older model 77d:223) */
- /*
- * plantronics headset and Griffin iMic have set adaptive-in
- * although it's really not...
- */
- fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE;
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
- fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE;
- else
- fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC;
- break;
- }
-
- /* ok, let's parse further... */
- if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) {
- kfree(fp->rate_table);
- kfree(fp);
- fp = NULL;
- continue;
- }
-
- snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint %#x\n", dev->devnum, iface_no, altno, fp->endpoint);
- err = snd_usb_add_audio_stream(chip, stream, fp);
- if (err < 0) {
- kfree(fp->rate_table);
- kfree(fp);
- return err;
- }
- /* try to set the interface... */
- usb_set_interface(chip->dev, iface_no, altno);
- snd_usb_init_pitch(chip, iface_no, alts, fp);
- snd_usb_init_sample_rate(chip, iface_no, alts, fp, fp->rate_max);
- }
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/stream.h b/ANDROID_3.4.5/sound/usb/stream.h
deleted file mode 100644
index c97f679f..00000000
--- a/ANDROID_3.4.5/sound/usb/stream.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef __USBAUDIO_STREAM_H
-#define __USBAUDIO_STREAM_H
-
-int snd_usb_parse_audio_interface(struct snd_usb_audio *chip,
- int iface_no);
-
-int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
- int stream,
- struct audioformat *fp);
-
-#endif /* __USBAUDIO_STREAM_H */
-
diff --git a/ANDROID_3.4.5/sound/usb/usbaudio.h b/ANDROID_3.4.5/sound/usb/usbaudio.h
deleted file mode 100644
index 3e2b0357..00000000
--- a/ANDROID_3.4.5/sound/usb/usbaudio.h
+++ /dev/null
@@ -1,105 +0,0 @@
-#ifndef __USBAUDIO_H
-#define __USBAUDIO_H
-/*
- * (Tentative) USB Audio Driver for ALSA
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* handling of USB vendor/product ID pairs as 32-bit numbers */
-#define USB_ID(vendor, product) (((vendor) << 16) | (product))
-#define USB_ID_VENDOR(id) ((id) >> 16)
-#define USB_ID_PRODUCT(id) ((u16)(id))
-
-/*
- *
- */
-
-struct snd_usb_audio {
- int index;
- struct usb_device *dev;
- struct snd_card *card;
- struct usb_interface *pm_intf;
- u32 usb_id;
- struct mutex shutdown_mutex;
- unsigned int shutdown:1;
- unsigned int probing:1;
- unsigned int autosuspended:1;
- unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */
-
- int num_interfaces;
- int num_suspended_intf;
-
- struct list_head pcm_list; /* list of pcm streams */
- int pcm_devs;
-
- struct list_head midi_list; /* list of midi interfaces */
-
- struct list_head mixer_list; /* list of mixer interfaces */
-
- int setup; /* from the 'device_setup' module param */
- int nrpacks; /* from the 'nrpacks' module param */
- int async_unlink; /* from the 'async_unlink' module param */
-
- struct usb_host_interface *ctrl_intf; /* the audio control interface */
-};
-
-/*
- * Information about devices with broken descriptors
- */
-
-/* special values for .ifnum */
-#define QUIRK_NO_INTERFACE -2
-#define QUIRK_ANY_INTERFACE -1
-
-enum quirk_type {
- QUIRK_IGNORE_INTERFACE,
- QUIRK_COMPOSITE,
- QUIRK_MIDI_STANDARD_INTERFACE,
- QUIRK_MIDI_FIXED_ENDPOINT,
- QUIRK_MIDI_YAMAHA,
- QUIRK_MIDI_MIDIMAN,
- QUIRK_MIDI_NOVATION,
- QUIRK_MIDI_RAW_BYTES,
- QUIRK_MIDI_EMAGIC,
- QUIRK_MIDI_CME,
- QUIRK_MIDI_AKAI,
- QUIRK_MIDI_US122L,
- QUIRK_MIDI_FTDI,
- QUIRK_AUDIO_STANDARD_INTERFACE,
- QUIRK_AUDIO_FIXED_ENDPOINT,
- QUIRK_AUDIO_EDIROL_UAXX,
- QUIRK_AUDIO_ALIGN_TRANSFER,
- QUIRK_AUDIO_STANDARD_MIXER,
-
- QUIRK_TYPE_COUNT
-};
-
-struct snd_usb_audio_quirk {
- const char *vendor_name;
- const char *product_name;
- int16_t ifnum;
- uint16_t type;
- const void *data;
-};
-
-#define combine_word(s) ((*(s)) | ((unsigned int)(s)[1] << 8))
-#define combine_triple(s) (combine_word(s) | ((unsigned int)(s)[2] << 16))
-#define combine_quad(s) (combine_triple(s) | ((unsigned int)(s)[3] << 24))
-
-#endif /* __USBAUDIO_H */
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/Makefile b/ANDROID_3.4.5/sound/usb/usx2y/Makefile
deleted file mode 100644
index 74893305..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-snd-usb-usx2y-objs := usbusx2y.o usX2Yhwdep.o usx2yhwdeppcm.o
-snd-usb-us122l-objs := us122l.o
-
-obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-usx2y.o
-obj-$(CONFIG_SND_USB_US122L) += snd-usb-us122l.o
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/us122l.c b/ANDROID_3.4.5/sound/usb/usx2y/us122l.c
deleted file mode 100644
index c4fd3b1d..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/us122l.c
+++ /dev/null
@@ -1,775 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Karsten Wiese <fzu@wemgehoertderstaat.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/usb/audio.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/hwdep.h>
-#include <sound/pcm.h>
-#include <sound/initval.h>
-#define MODNAME "US122L"
-#include "usb_stream.c"
-#include "../usbaudio.h"
-#include "../midi.h"
-#include "us122l.h"
-
-MODULE_AUTHOR("Karsten Wiese <fzu@wemgehoertderstaat.de>");
-MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.5");
-MODULE_LICENSE("GPL");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
- /* Enable this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS".");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for "NAME_ALLCAPS".");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable "NAME_ALLCAPS".");
-
-static int snd_us122l_card_used[SNDRV_CARDS];
-
-
-static int us122l_create_usbmidi(struct snd_card *card)
-{
- static struct snd_usb_midi_endpoint_info quirk_data = {
- .out_ep = 4,
- .in_ep = 3,
- .out_cables = 0x001,
- .in_cables = 0x001
- };
- static struct snd_usb_audio_quirk quirk = {
- .vendor_name = "US122L",
- .product_name = NAME_ALLCAPS,
- .ifnum = 1,
- .type = QUIRK_MIDI_US122L,
- .data = &quirk_data
- };
- struct usb_device *dev = US122L(card)->dev;
- struct usb_interface *iface = usb_ifnum_to_if(dev, 1);
-
- return snd_usbmidi_create(card, iface,
- &US122L(card)->midi_list, &quirk);
-}
-
-static int us144_create_usbmidi(struct snd_card *card)
-{
- static struct snd_usb_midi_endpoint_info quirk_data = {
- .out_ep = 4,
- .in_ep = 3,
- .out_cables = 0x001,
- .in_cables = 0x001
- };
- static struct snd_usb_audio_quirk quirk = {
- .vendor_name = "US144",
- .product_name = NAME_ALLCAPS,
- .ifnum = 0,
- .type = QUIRK_MIDI_US122L,
- .data = &quirk_data
- };
- struct usb_device *dev = US122L(card)->dev;
- struct usb_interface *iface = usb_ifnum_to_if(dev, 0);
-
- return snd_usbmidi_create(card, iface,
- &US122L(card)->midi_list, &quirk);
-}
-
-/*
- * Wrapper for usb_control_msg().
- * Allocates a temp buffer to prevent dmaing from/to the stack.
- */
-static int us122l_ctl_msg(struct usb_device *dev, unsigned int pipe,
- __u8 request, __u8 requesttype,
- __u16 value, __u16 index, void *data,
- __u16 size, int timeout)
-{
- int err;
- void *buf = NULL;
-
- if (size > 0) {
- buf = kmemdup(data, size, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
- }
- err = usb_control_msg(dev, pipe, request, requesttype,
- value, index, buf, size, timeout);
- if (size > 0) {
- memcpy(data, buf, size);
- kfree(buf);
- }
- return err;
-}
-
-static void pt_info_set(struct usb_device *dev, u8 v)
-{
- int ret;
-
- ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- 'I',
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- v, 0, NULL, 0, 1000);
- snd_printdd(KERN_DEBUG "%i\n", ret);
-}
-
-static void usb_stream_hwdep_vm_open(struct vm_area_struct *area)
-{
- struct us122l *us122l = area->vm_private_data;
- atomic_inc(&us122l->mmap_count);
- snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count));
-}
-
-static int usb_stream_hwdep_vm_fault(struct vm_area_struct *area,
- struct vm_fault *vmf)
-{
- unsigned long offset;
- struct page *page;
- void *vaddr;
- struct us122l *us122l = area->vm_private_data;
- struct usb_stream *s;
-
- mutex_lock(&us122l->mutex);
- s = us122l->sk.s;
- if (!s)
- goto unlock;
-
- offset = vmf->pgoff << PAGE_SHIFT;
- if (offset < PAGE_ALIGN(s->read_size))
- vaddr = (char *)s + offset;
- else {
- offset -= PAGE_ALIGN(s->read_size);
- if (offset >= PAGE_ALIGN(s->write_size))
- goto unlock;
-
- vaddr = us122l->sk.write_page + offset;
- }
- page = virt_to_page(vaddr);
-
- get_page(page);
- mutex_unlock(&us122l->mutex);
-
- vmf->page = page;
-
- return 0;
-unlock:
- mutex_unlock(&us122l->mutex);
- return VM_FAULT_SIGBUS;
-}
-
-static void usb_stream_hwdep_vm_close(struct vm_area_struct *area)
-{
- struct us122l *us122l = area->vm_private_data;
- atomic_dec(&us122l->mmap_count);
- snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count));
-}
-
-static const struct vm_operations_struct usb_stream_hwdep_vm_ops = {
- .open = usb_stream_hwdep_vm_open,
- .fault = usb_stream_hwdep_vm_fault,
- .close = usb_stream_hwdep_vm_close,
-};
-
-
-static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file)
-{
- struct us122l *us122l = hw->private_data;
- struct usb_interface *iface;
- snd_printdd(KERN_DEBUG "%p %p\n", hw, file);
- if (hw->used >= 2)
- return -EBUSY;
-
- if (!us122l->first)
- us122l->first = file;
-
- if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
- us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
- iface = usb_ifnum_to_if(us122l->dev, 0);
- usb_autopm_get_interface(iface);
- }
- iface = usb_ifnum_to_if(us122l->dev, 1);
- usb_autopm_get_interface(iface);
- return 0;
-}
-
-static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file)
-{
- struct us122l *us122l = hw->private_data;
- struct usb_interface *iface;
- snd_printdd(KERN_DEBUG "%p %p\n", hw, file);
-
- if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
- us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
- iface = usb_ifnum_to_if(us122l->dev, 0);
- usb_autopm_put_interface(iface);
- }
- iface = usb_ifnum_to_if(us122l->dev, 1);
- usb_autopm_put_interface(iface);
- if (us122l->first == file)
- us122l->first = NULL;
- mutex_lock(&us122l->mutex);
- if (us122l->master == file)
- us122l->master = us122l->slave;
-
- us122l->slave = NULL;
- mutex_unlock(&us122l->mutex);
- return 0;
-}
-
-static int usb_stream_hwdep_mmap(struct snd_hwdep *hw,
- struct file *filp, struct vm_area_struct *area)
-{
- unsigned long size = area->vm_end - area->vm_start;
- struct us122l *us122l = hw->private_data;
- unsigned long offset;
- struct usb_stream *s;
- int err = 0;
- bool read;
-
- offset = area->vm_pgoff << PAGE_SHIFT;
- mutex_lock(&us122l->mutex);
- s = us122l->sk.s;
- read = offset < s->read_size;
- if (read && area->vm_flags & VM_WRITE) {
- err = -EPERM;
- goto out;
- }
- snd_printdd(KERN_DEBUG "%lu %u\n", size,
- read ? s->read_size : s->write_size);
- /* if userspace tries to mmap beyond end of our buffer, fail */
- if (size > PAGE_ALIGN(read ? s->read_size : s->write_size)) {
- snd_printk(KERN_WARNING "%lu > %u\n", size,
- read ? s->read_size : s->write_size);
- err = -EINVAL;
- goto out;
- }
-
- area->vm_ops = &usb_stream_hwdep_vm_ops;
- area->vm_flags |= VM_RESERVED;
- area->vm_private_data = us122l;
- atomic_inc(&us122l->mmap_count);
-out:
- mutex_unlock(&us122l->mutex);
- return err;
-}
-
-static unsigned int usb_stream_hwdep_poll(struct snd_hwdep *hw,
- struct file *file, poll_table *wait)
-{
- struct us122l *us122l = hw->private_data;
- unsigned *polled;
- unsigned int mask;
-
- poll_wait(file, &us122l->sk.sleep, wait);
-
- mask = POLLIN | POLLOUT | POLLWRNORM | POLLERR;
- if (mutex_trylock(&us122l->mutex)) {
- struct usb_stream *s = us122l->sk.s;
- if (s && s->state == usb_stream_ready) {
- if (us122l->first == file)
- polled = &s->periods_polled;
- else
- polled = &us122l->second_periods_polled;
- if (*polled != s->periods_done) {
- *polled = s->periods_done;
- mask = POLLIN | POLLOUT | POLLWRNORM;
- } else
- mask = 0;
- }
- mutex_unlock(&us122l->mutex);
- }
- return mask;
-}
-
-static void us122l_stop(struct us122l *us122l)
-{
- struct list_head *p;
- list_for_each(p, &us122l->midi_list)
- snd_usbmidi_input_stop(p);
-
- usb_stream_stop(&us122l->sk);
- usb_stream_free(&us122l->sk);
-}
-
-static int us122l_set_sample_rate(struct usb_device *dev, int rate)
-{
- unsigned int ep = 0x81;
- unsigned char data[3];
- int err;
-
- data[0] = rate;
- data[1] = rate >> 8;
- data[2] = rate >> 16;
- err = us122l_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
- USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
- UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, data, 3, 1000);
- if (err < 0)
- snd_printk(KERN_ERR "%d: cannot set freq %d to ep 0x%x\n",
- dev->devnum, rate, ep);
- return err;
-}
-
-static bool us122l_start(struct us122l *us122l,
- unsigned rate, unsigned period_frames)
-{
- struct list_head *p;
- int err;
- unsigned use_packsize = 0;
- bool success = false;
-
- if (us122l->dev->speed == USB_SPEED_HIGH) {
- /* The us-122l's descriptor defaults to iso max_packsize 78,
- which isn't needed for samplerates <= 48000.
- Lets save some memory:
- */
- switch (rate) {
- case 44100:
- use_packsize = 36;
- break;
- case 48000:
- use_packsize = 42;
- break;
- case 88200:
- use_packsize = 72;
- break;
- }
- }
- if (!usb_stream_new(&us122l->sk, us122l->dev, 1, 2,
- rate, use_packsize, period_frames, 6))
- goto out;
-
- err = us122l_set_sample_rate(us122l->dev, rate);
- if (err < 0) {
- us122l_stop(us122l);
- snd_printk(KERN_ERR "us122l_set_sample_rate error \n");
- goto out;
- }
- err = usb_stream_start(&us122l->sk);
- if (err < 0) {
- us122l_stop(us122l);
- snd_printk(KERN_ERR "us122l_start error %i \n", err);
- goto out;
- }
- list_for_each(p, &us122l->midi_list)
- snd_usbmidi_input_start(p);
- success = true;
-out:
- return success;
-}
-
-static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
- unsigned cmd, unsigned long arg)
-{
- struct usb_stream_config *cfg;
- struct us122l *us122l = hw->private_data;
- struct usb_stream *s;
- unsigned min_period_frames;
- int err = 0;
- bool high_speed;
-
- if (cmd != SNDRV_USB_STREAM_IOCTL_SET_PARAMS)
- return -ENOTTY;
-
- cfg = memdup_user((void *)arg, sizeof(*cfg));
- if (IS_ERR(cfg))
- return PTR_ERR(cfg);
-
- if (cfg->version != USB_STREAM_INTERFACE_VERSION) {
- err = -ENXIO;
- goto free;
- }
- high_speed = us122l->dev->speed == USB_SPEED_HIGH;
- if ((cfg->sample_rate != 44100 && cfg->sample_rate != 48000 &&
- (!high_speed ||
- (cfg->sample_rate != 88200 && cfg->sample_rate != 96000))) ||
- cfg->frame_size != 6 ||
- cfg->period_frames > 0x3000) {
- err = -EINVAL;
- goto free;
- }
- switch (cfg->sample_rate) {
- case 44100:
- min_period_frames = 48;
- break;
- case 48000:
- min_period_frames = 52;
- break;
- default:
- min_period_frames = 104;
- break;
- }
- if (!high_speed)
- min_period_frames <<= 1;
- if (cfg->period_frames < min_period_frames) {
- err = -EINVAL;
- goto free;
- }
-
- snd_power_wait(hw->card, SNDRV_CTL_POWER_D0);
-
- mutex_lock(&us122l->mutex);
- s = us122l->sk.s;
- if (!us122l->master)
- us122l->master = file;
- else if (us122l->master != file) {
- if (!s || memcmp(cfg, &s->cfg, sizeof(*cfg))) {
- err = -EIO;
- goto unlock;
- }
- us122l->slave = file;
- }
- if (!s || memcmp(cfg, &s->cfg, sizeof(*cfg)) ||
- s->state == usb_stream_xrun) {
- us122l_stop(us122l);
- if (!us122l_start(us122l, cfg->sample_rate, cfg->period_frames))
- err = -EIO;
- else
- err = 1;
- }
-unlock:
- mutex_unlock(&us122l->mutex);
-free:
- kfree(cfg);
- wake_up_all(&us122l->sk.sleep);
- return err;
-}
-
-#define SND_USB_STREAM_ID "USB STREAM"
-static int usb_stream_hwdep_new(struct snd_card *card)
-{
- int err;
- struct snd_hwdep *hw;
- struct usb_device *dev = US122L(card)->dev;
-
- err = snd_hwdep_new(card, SND_USB_STREAM_ID, 0, &hw);
- if (err < 0)
- return err;
-
- hw->iface = SNDRV_HWDEP_IFACE_USB_STREAM;
- hw->private_data = US122L(card);
- hw->ops.open = usb_stream_hwdep_open;
- hw->ops.release = usb_stream_hwdep_release;
- hw->ops.ioctl = usb_stream_hwdep_ioctl;
- hw->ops.ioctl_compat = usb_stream_hwdep_ioctl;
- hw->ops.mmap = usb_stream_hwdep_mmap;
- hw->ops.poll = usb_stream_hwdep_poll;
-
- sprintf(hw->name, "/proc/bus/usb/%03d/%03d/hwdeppcm",
- dev->bus->busnum, dev->devnum);
- return 0;
-}
-
-
-static bool us122l_create_card(struct snd_card *card)
-{
- int err;
- struct us122l *us122l = US122L(card);
-
- if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
- us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
- err = usb_set_interface(us122l->dev, 0, 1);
- if (err) {
- snd_printk(KERN_ERR "usb_set_interface error \n");
- return false;
- }
- }
- err = usb_set_interface(us122l->dev, 1, 1);
- if (err) {
- snd_printk(KERN_ERR "usb_set_interface error \n");
- return false;
- }
-
- pt_info_set(us122l->dev, 0x11);
- pt_info_set(us122l->dev, 0x10);
-
- if (!us122l_start(us122l, 44100, 256))
- return false;
-
- if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
- us122l->dev->descriptor.idProduct == USB_ID_US144MKII)
- err = us144_create_usbmidi(card);
- else
- err = us122l_create_usbmidi(card);
- if (err < 0) {
- snd_printk(KERN_ERR "us122l_create_usbmidi error %i \n", err);
- us122l_stop(us122l);
- return false;
- }
- err = usb_stream_hwdep_new(card);
- if (err < 0) {
-/* release the midi resources */
- struct list_head *p;
- list_for_each(p, &us122l->midi_list)
- snd_usbmidi_disconnect(p);
-
- us122l_stop(us122l);
- return false;
- }
- return true;
-}
-
-static void snd_us122l_free(struct snd_card *card)
-{
- struct us122l *us122l = US122L(card);
- int index = us122l->card_index;
- if (index >= 0 && index < SNDRV_CARDS)
- snd_us122l_card_used[index] = 0;
-}
-
-static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp)
-{
- int dev;
- struct snd_card *card;
- int err;
-
- for (dev = 0; dev < SNDRV_CARDS; ++dev)
- if (enable[dev] && !snd_us122l_card_used[dev])
- break;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct us122l), &card);
- if (err < 0)
- return err;
- snd_us122l_card_used[US122L(card)->card_index = dev] = 1;
- card->private_free = snd_us122l_free;
- US122L(card)->dev = device;
- mutex_init(&US122L(card)->mutex);
- init_waitqueue_head(&US122L(card)->sk.sleep);
- INIT_LIST_HEAD(&US122L(card)->midi_list);
- strcpy(card->driver, "USB "NAME_ALLCAPS"");
- sprintf(card->shortname, "TASCAM "NAME_ALLCAPS"");
- sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)",
- card->shortname,
- le16_to_cpu(device->descriptor.idVendor),
- le16_to_cpu(device->descriptor.idProduct),
- 0,
- US122L(card)->dev->bus->busnum,
- US122L(card)->dev->devnum
- );
- *cardp = card;
- return 0;
-}
-
-static int us122l_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *device_id,
- struct snd_card **cardp)
-{
- struct usb_device *device = interface_to_usbdev(intf);
- struct snd_card *card;
- int err;
-
- err = usx2y_create_card(device, &card);
- if (err < 0)
- return err;
-
- snd_card_set_dev(card, &intf->dev);
- if (!us122l_create_card(card)) {
- snd_card_free(card);
- return -EINVAL;
- }
-
- err = snd_card_register(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- usb_get_intf(usb_ifnum_to_if(device, 0));
- usb_get_dev(device);
- *cardp = card;
- return 0;
-}
-
-static int snd_us122l_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *device = interface_to_usbdev(intf);
- struct snd_card *card;
- int err;
-
- if ((device->descriptor.idProduct == USB_ID_US144 ||
- device->descriptor.idProduct == USB_ID_US144MKII)
- && device->speed == USB_SPEED_HIGH) {
- snd_printk(KERN_ERR "disable ehci-hcd to run US-144 \n");
- return -ENODEV;
- }
-
- snd_printdd(KERN_DEBUG"%p:%i\n",
- intf, intf->cur_altsetting->desc.bInterfaceNumber);
- if (intf->cur_altsetting->desc.bInterfaceNumber != 1)
- return 0;
-
- err = us122l_usb_probe(usb_get_intf(intf), id, &card);
- if (err < 0) {
- usb_put_intf(intf);
- return err;
- }
-
- usb_set_intfdata(intf, card);
- return 0;
-}
-
-static void snd_us122l_disconnect(struct usb_interface *intf)
-{
- struct snd_card *card;
- struct us122l *us122l;
- struct list_head *p;
-
- card = usb_get_intfdata(intf);
- if (!card)
- return;
-
- snd_card_disconnect(card);
-
- us122l = US122L(card);
- mutex_lock(&us122l->mutex);
- us122l_stop(us122l);
- mutex_unlock(&us122l->mutex);
-
-/* release the midi resources */
- list_for_each(p, &us122l->midi_list) {
- snd_usbmidi_disconnect(p);
- }
-
- usb_put_intf(usb_ifnum_to_if(us122l->dev, 0));
- usb_put_intf(usb_ifnum_to_if(us122l->dev, 1));
- usb_put_dev(us122l->dev);
-
- while (atomic_read(&us122l->mmap_count))
- msleep(500);
-
- snd_card_free(card);
-}
-
-static int snd_us122l_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct snd_card *card;
- struct us122l *us122l;
- struct list_head *p;
-
- card = usb_get_intfdata(intf);
- if (!card)
- return 0;
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-
- us122l = US122L(card);
- if (!us122l)
- return 0;
-
- list_for_each(p, &us122l->midi_list)
- snd_usbmidi_input_stop(p);
-
- mutex_lock(&us122l->mutex);
- usb_stream_stop(&us122l->sk);
- mutex_unlock(&us122l->mutex);
-
- return 0;
-}
-
-static int snd_us122l_resume(struct usb_interface *intf)
-{
- struct snd_card *card;
- struct us122l *us122l;
- struct list_head *p;
- int err;
-
- card = usb_get_intfdata(intf);
- if (!card)
- return 0;
-
- us122l = US122L(card);
- if (!us122l)
- return 0;
-
- mutex_lock(&us122l->mutex);
- /* needed, doesn't restart without: */
- if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
- us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
- err = usb_set_interface(us122l->dev, 0, 1);
- if (err) {
- snd_printk(KERN_ERR "usb_set_interface error \n");
- goto unlock;
- }
- }
- err = usb_set_interface(us122l->dev, 1, 1);
- if (err) {
- snd_printk(KERN_ERR "usb_set_interface error \n");
- goto unlock;
- }
-
- pt_info_set(us122l->dev, 0x11);
- pt_info_set(us122l->dev, 0x10);
-
- err = us122l_set_sample_rate(us122l->dev,
- us122l->sk.s->cfg.sample_rate);
- if (err < 0) {
- snd_printk(KERN_ERR "us122l_set_sample_rate error \n");
- goto unlock;
- }
- err = usb_stream_start(&us122l->sk);
- if (err)
- goto unlock;
-
- list_for_each(p, &us122l->midi_list)
- snd_usbmidi_input_start(p);
-unlock:
- mutex_unlock(&us122l->mutex);
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return err;
-}
-
-static struct usb_device_id snd_us122l_usb_id_table[] = {
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x0644,
- .idProduct = USB_ID_US122L
- },
- { /* US-144 only works at USB1.1! Disable module ehci-hcd. */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x0644,
- .idProduct = USB_ID_US144
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x0644,
- .idProduct = USB_ID_US122MKII
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x0644,
- .idProduct = USB_ID_US144MKII
- },
- { /* terminator */ }
-};
-
-MODULE_DEVICE_TABLE(usb, snd_us122l_usb_id_table);
-static struct usb_driver snd_us122l_usb_driver = {
- .name = "snd-usb-us122l",
- .probe = snd_us122l_probe,
- .disconnect = snd_us122l_disconnect,
- .suspend = snd_us122l_suspend,
- .resume = snd_us122l_resume,
- .reset_resume = snd_us122l_resume,
- .id_table = snd_us122l_usb_id_table,
- .supports_autosuspend = 1
-};
-
-module_usb_driver(snd_us122l_usb_driver);
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/us122l.h b/ANDROID_3.4.5/sound/usb/usx2y/us122l.h
deleted file mode 100644
index f263b3f9..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/us122l.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef US122L_H
-#define US122L_H
-
-
-struct us122l {
- struct usb_device *dev;
- int card_index;
- int stride;
- struct usb_stream_kernel sk;
-
- struct mutex mutex;
- struct file *first;
- unsigned second_periods_polled;
- struct file *master;
- struct file *slave;
- struct list_head midi_list;
-
- atomic_t mmap_count;
-};
-
-
-#define US122L(c) ((struct us122l *)(c)->private_data)
-
-#define NAME_ALLCAPS "US-122L"
-
-#define USB_ID_US122L 0x800E
-#define USB_ID_US144 0x800F
-#define USB_ID_US122MKII 0x8021
-#define USB_ID_US144MKII 0x8020
-
-#endif
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usX2Yhwdep.c b/ANDROID_3.4.5/sound/usb/usx2y/usX2Yhwdep.c
deleted file mode 100644
index 04aafb43..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usX2Yhwdep.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Driver for Tascam US-X2Y USB soundcards
- *
- * FPGA Loader + ALSA Startup
- *
- * Copyright (c) 2003 by Karsten Wiese <annabellesgarden@yahoo.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <sound/core.h>
-#include <sound/memalloc.h>
-#include <sound/pcm.h>
-#include <sound/hwdep.h>
-#include "usx2y.h"
-#include "usbusx2y.h"
-#include "usX2Yhwdep.h"
-
-static int snd_us428ctls_vm_fault(struct vm_area_struct *area,
- struct vm_fault *vmf)
-{
- unsigned long offset;
- struct page * page;
- void *vaddr;
-
- snd_printdd("ENTER, start %lXh, pgoff %ld\n",
- area->vm_start,
- vmf->pgoff);
-
- offset = vmf->pgoff << PAGE_SHIFT;
- vaddr = (char*)((struct usX2Ydev *)area->vm_private_data)->us428ctls_sharedmem + offset;
- page = virt_to_page(vaddr);
- get_page(page);
- vmf->page = page;
-
- snd_printdd("vaddr=%p made us428ctls_vm_fault() page %p\n",
- vaddr, page);
-
- return 0;
-}
-
-static const struct vm_operations_struct us428ctls_vm_ops = {
- .fault = snd_us428ctls_vm_fault,
-};
-
-static int snd_us428ctls_mmap(struct snd_hwdep * hw, struct file *filp, struct vm_area_struct *area)
-{
- unsigned long size = (unsigned long)(area->vm_end - area->vm_start);
- struct usX2Ydev *us428 = hw->private_data;
-
- // FIXME this hwdep interface is used twice: fpga download and mmap for controlling Lights etc. Maybe better using 2 hwdep devs?
- // so as long as the device isn't fully initialised yet we return -EBUSY here.
- if (!(us428->chip_status & USX2Y_STAT_CHIP_INIT))
- return -EBUSY;
-
- /* if userspace tries to mmap beyond end of our buffer, fail */
- if (size > PAGE_ALIGN(sizeof(struct us428ctls_sharedmem))) {
- snd_printd( "%lu > %lu\n", size, (unsigned long)sizeof(struct us428ctls_sharedmem));
- return -EINVAL;
- }
-
- if (!us428->us428ctls_sharedmem) {
- init_waitqueue_head(&us428->us428ctls_wait_queue_head);
- if(!(us428->us428ctls_sharedmem = snd_malloc_pages(sizeof(struct us428ctls_sharedmem), GFP_KERNEL)))
- return -ENOMEM;
- memset(us428->us428ctls_sharedmem, -1, sizeof(struct us428ctls_sharedmem));
- us428->us428ctls_sharedmem->CtlSnapShotLast = -2;
- }
- area->vm_ops = &us428ctls_vm_ops;
- area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
- area->vm_private_data = hw->private_data;
- return 0;
-}
-
-static unsigned int snd_us428ctls_poll(struct snd_hwdep *hw, struct file *file, poll_table *wait)
-{
- unsigned int mask = 0;
- struct usX2Ydev *us428 = hw->private_data;
- struct us428ctls_sharedmem *shm = us428->us428ctls_sharedmem;
- if (us428->chip_status & USX2Y_STAT_CHIP_HUP)
- return POLLHUP;
-
- poll_wait(file, &us428->us428ctls_wait_queue_head, wait);
-
- if (shm != NULL && shm->CtlSnapShotLast != shm->CtlSnapShotRed)
- mask |= POLLIN;
-
- return mask;
-}
-
-
-static int snd_usX2Y_hwdep_dsp_status(struct snd_hwdep *hw,
- struct snd_hwdep_dsp_status *info)
-{
- static char *type_ids[USX2Y_TYPE_NUMS] = {
- [USX2Y_TYPE_122] = "us122",
- [USX2Y_TYPE_224] = "us224",
- [USX2Y_TYPE_428] = "us428",
- };
- struct usX2Ydev *us428 = hw->private_data;
- int id = -1;
-
- switch (le16_to_cpu(us428->dev->descriptor.idProduct)) {
- case USB_ID_US122:
- id = USX2Y_TYPE_122;
- break;
- case USB_ID_US224:
- id = USX2Y_TYPE_224;
- break;
- case USB_ID_US428:
- id = USX2Y_TYPE_428;
- break;
- }
- if (0 > id)
- return -ENODEV;
- strcpy(info->id, type_ids[id]);
- info->num_dsps = 2; // 0: Prepad Data, 1: FPGA Code
- if (us428->chip_status & USX2Y_STAT_CHIP_INIT)
- info->chip_ready = 1;
- info->version = USX2Y_DRIVER_VERSION;
- return 0;
-}
-
-
-static int usX2Y_create_usbmidi(struct snd_card *card)
-{
- static struct snd_usb_midi_endpoint_info quirk_data_1 = {
- .out_ep = 0x06,
- .in_ep = 0x06,
- .out_cables = 0x001,
- .in_cables = 0x001
- };
- static struct snd_usb_audio_quirk quirk_1 = {
- .vendor_name = "TASCAM",
- .product_name = NAME_ALLCAPS,
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = &quirk_data_1
- };
- static struct snd_usb_midi_endpoint_info quirk_data_2 = {
- .out_ep = 0x06,
- .in_ep = 0x06,
- .out_cables = 0x003,
- .in_cables = 0x003
- };
- static struct snd_usb_audio_quirk quirk_2 = {
- .vendor_name = "TASCAM",
- .product_name = "US428",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = &quirk_data_2
- };
- struct usb_device *dev = usX2Y(card)->dev;
- struct usb_interface *iface = usb_ifnum_to_if(dev, 0);
- struct snd_usb_audio_quirk *quirk =
- le16_to_cpu(dev->descriptor.idProduct) == USB_ID_US428 ?
- &quirk_2 : &quirk_1;
-
- snd_printdd("usX2Y_create_usbmidi \n");
- return snd_usbmidi_create(card, iface, &usX2Y(card)->midi_list, quirk);
-}
-
-static int usX2Y_create_alsa_devices(struct snd_card *card)
-{
- int err;
-
- do {
- if ((err = usX2Y_create_usbmidi(card)) < 0) {
- snd_printk(KERN_ERR "usX2Y_create_alsa_devices: usX2Y_create_usbmidi error %i \n", err);
- break;
- }
- if ((err = usX2Y_audio_create(card)) < 0)
- break;
- if ((err = usX2Y_hwdep_pcm_new(card)) < 0)
- break;
- if ((err = snd_card_register(card)) < 0)
- break;
- } while (0);
-
- return err;
-}
-
-static int snd_usX2Y_hwdep_dsp_load(struct snd_hwdep *hw,
- struct snd_hwdep_dsp_image *dsp)
-{
- struct usX2Ydev *priv = hw->private_data;
- int lret, err = -EINVAL;
- snd_printdd( "dsp_load %s\n", dsp->name);
-
- if (access_ok(VERIFY_READ, dsp->image, dsp->length)) {
- struct usb_device* dev = priv->dev;
- char *buf;
-
- buf = memdup_user(dsp->image, dsp->length);
- if (IS_ERR(buf))
- return PTR_ERR(buf);
-
- err = usb_set_interface(dev, 0, 1);
- if (err)
- snd_printk(KERN_ERR "usb_set_interface error \n");
- else
- err = usb_bulk_msg(dev, usb_sndbulkpipe(dev, 2), buf, dsp->length, &lret, 6000);
- kfree(buf);
- }
- if (err)
- return err;
- if (dsp->index == 1) {
- msleep(250); // give the device some time
- err = usX2Y_AsyncSeq04_init(priv);
- if (err) {
- snd_printk(KERN_ERR "usX2Y_AsyncSeq04_init error \n");
- return err;
- }
- err = usX2Y_In04_init(priv);
- if (err) {
- snd_printk(KERN_ERR "usX2Y_In04_init error \n");
- return err;
- }
- err = usX2Y_create_alsa_devices(hw->card);
- if (err) {
- snd_printk(KERN_ERR "usX2Y_create_alsa_devices error %i \n", err);
- snd_card_free(hw->card);
- return err;
- }
- priv->chip_status |= USX2Y_STAT_CHIP_INIT;
- snd_printdd("%s: alsa all started\n", hw->name);
- }
- return err;
-}
-
-
-int usX2Y_hwdep_new(struct snd_card *card, struct usb_device* device)
-{
- int err;
- struct snd_hwdep *hw;
-
- if ((err = snd_hwdep_new(card, SND_USX2Y_LOADER_ID, 0, &hw)) < 0)
- return err;
-
- hw->iface = SNDRV_HWDEP_IFACE_USX2Y;
- hw->private_data = usX2Y(card);
- hw->ops.dsp_status = snd_usX2Y_hwdep_dsp_status;
- hw->ops.dsp_load = snd_usX2Y_hwdep_dsp_load;
- hw->ops.mmap = snd_us428ctls_mmap;
- hw->ops.poll = snd_us428ctls_poll;
- hw->exclusive = 1;
- sprintf(hw->name, "/proc/bus/usb/%03d/%03d", device->bus->busnum, device->devnum);
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usX2Yhwdep.h b/ANDROID_3.4.5/sound/usb/usx2y/usX2Yhwdep.h
deleted file mode 100644
index c095d5bf..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usX2Yhwdep.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef USX2YHWDEP_H
-#define USX2YHWDEP_H
-
-int usX2Y_hwdep_new(struct snd_card *card, struct usb_device* device);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usb_stream.c b/ANDROID_3.4.5/sound/usb/usx2y/usb_stream.c
deleted file mode 100644
index 1e7a47a8..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usb_stream.c
+++ /dev/null
@@ -1,754 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Karsten Wiese <fzu@wemgehoertderstaat.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/usb.h>
-#include <linux/gfp.h>
-
-#include "usb_stream.h"
-
-
-/* setup */
-
-static unsigned usb_stream_next_packet_size(struct usb_stream_kernel *sk)
-{
- struct usb_stream *s = sk->s;
- sk->out_phase_peeked = (sk->out_phase & 0xffff) + sk->freqn;
- return (sk->out_phase_peeked >> 16) * s->cfg.frame_size;
-}
-
-static void playback_prep_freqn(struct usb_stream_kernel *sk, struct urb *urb)
-{
- struct usb_stream *s = sk->s;
- int pack, lb = 0;
-
- for (pack = 0; pack < sk->n_o_ps; pack++) {
- int l = usb_stream_next_packet_size(sk);
- if (s->idle_outsize + lb + l > s->period_size)
- goto check;
-
- sk->out_phase = sk->out_phase_peeked;
- urb->iso_frame_desc[pack].offset = lb;
- urb->iso_frame_desc[pack].length = l;
- lb += l;
- }
- snd_printdd(KERN_DEBUG "%i\n", lb);
-
-check:
- urb->number_of_packets = pack;
- urb->transfer_buffer_length = lb;
- s->idle_outsize += lb - s->period_size;
- snd_printdd(KERN_DEBUG "idle=%i ul=%i ps=%i\n", s->idle_outsize,
- lb, s->period_size);
-}
-
-static void init_pipe_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
- struct urb **urbs, char *transfer,
- struct usb_device *dev, int pipe)
-{
- int u, p;
- int maxpacket = use_packsize ?
- use_packsize : usb_maxpacket(dev, pipe, usb_pipeout(pipe));
- int transfer_length = maxpacket * sk->n_o_ps;
-
- for (u = 0; u < USB_STREAM_NURBS;
- ++u, transfer += transfer_length) {
- struct urb *urb = urbs[u];
- struct usb_iso_packet_descriptor *desc;
- urb->transfer_flags = URB_ISO_ASAP;
- urb->transfer_buffer = transfer;
- urb->dev = dev;
- urb->pipe = pipe;
- urb->number_of_packets = sk->n_o_ps;
- urb->context = sk;
- urb->interval = 1;
- if (usb_pipeout(pipe))
- continue;
-
- urb->transfer_buffer_length = transfer_length;
- desc = urb->iso_frame_desc;
- desc->offset = 0;
- desc->length = maxpacket;
- for (p = 1; p < sk->n_o_ps; ++p) {
- desc[p].offset = desc[p - 1].offset + maxpacket;
- desc[p].length = maxpacket;
- }
- }
-}
-
-static void init_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
- struct usb_device *dev, int in_pipe, int out_pipe)
-{
- struct usb_stream *s = sk->s;
- char *indata = (char *)s + sizeof(*s) +
- sizeof(struct usb_stream_packet) *
- s->inpackets;
- int u;
-
- for (u = 0; u < USB_STREAM_NURBS; ++u) {
- sk->inurb[u] = usb_alloc_urb(sk->n_o_ps, GFP_KERNEL);
- sk->outurb[u] = usb_alloc_urb(sk->n_o_ps, GFP_KERNEL);
- }
-
- init_pipe_urbs(sk, use_packsize, sk->inurb, indata, dev, in_pipe);
- init_pipe_urbs(sk, use_packsize, sk->outurb, sk->write_page, dev,
- out_pipe);
-}
-
-
-/*
- * convert a sampling rate into our full speed format (fs/1000 in Q16.16)
- * this will overflow at approx 524 kHz
- */
-static inline unsigned get_usb_full_speed_rate(unsigned rate)
-{
- return ((rate << 13) + 62) / 125;
-}
-
-/*
- * convert a sampling rate into USB high speed format (fs/8000 in Q16.16)
- * this will overflow at approx 4 MHz
- */
-static inline unsigned get_usb_high_speed_rate(unsigned rate)
-{
- return ((rate << 10) + 62) / 125;
-}
-
-void usb_stream_free(struct usb_stream_kernel *sk)
-{
- struct usb_stream *s;
- unsigned u;
-
- for (u = 0; u < USB_STREAM_NURBS; ++u) {
- usb_free_urb(sk->inurb[u]);
- sk->inurb[u] = NULL;
- usb_free_urb(sk->outurb[u]);
- sk->outurb[u] = NULL;
- }
-
- s = sk->s;
- if (!s)
- return;
-
- free_pages((unsigned long)sk->write_page, get_order(s->write_size));
- sk->write_page = NULL;
- free_pages((unsigned long)s, get_order(s->read_size));
- sk->s = NULL;
-}
-
-struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk,
- struct usb_device *dev,
- unsigned in_endpoint, unsigned out_endpoint,
- unsigned sample_rate, unsigned use_packsize,
- unsigned period_frames, unsigned frame_size)
-{
- int packets, max_packsize;
- int in_pipe, out_pipe;
- int read_size = sizeof(struct usb_stream);
- int write_size;
- int usb_frames = dev->speed == USB_SPEED_HIGH ? 8000 : 1000;
- int pg;
-
- in_pipe = usb_rcvisocpipe(dev, in_endpoint);
- out_pipe = usb_sndisocpipe(dev, out_endpoint);
-
- max_packsize = use_packsize ?
- use_packsize : usb_maxpacket(dev, in_pipe, 0);
-
- /*
- t_period = period_frames / sample_rate
- iso_packs = t_period / t_iso_frame
- = (period_frames / sample_rate) * (1 / t_iso_frame)
- */
-
- packets = period_frames * usb_frames / sample_rate + 1;
-
- if (dev->speed == USB_SPEED_HIGH)
- packets = (packets + 7) & ~7;
-
- read_size += packets * USB_STREAM_URBDEPTH *
- (max_packsize + sizeof(struct usb_stream_packet));
-
- max_packsize = usb_maxpacket(dev, out_pipe, 1);
- write_size = max_packsize * packets * USB_STREAM_URBDEPTH;
-
- if (read_size >= 256*PAGE_SIZE || write_size >= 256*PAGE_SIZE) {
- snd_printk(KERN_WARNING "a size exceeds 128*PAGE_SIZE\n");
- goto out;
- }
-
- pg = get_order(read_size);
- sk->s = (void *) __get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO, pg);
- if (!sk->s) {
- snd_printk(KERN_WARNING "couldn't __get_free_pages()\n");
- goto out;
- }
- sk->s->cfg.version = USB_STREAM_INTERFACE_VERSION;
-
- sk->s->read_size = read_size;
-
- sk->s->cfg.sample_rate = sample_rate;
- sk->s->cfg.frame_size = frame_size;
- sk->n_o_ps = packets;
- sk->s->inpackets = packets * USB_STREAM_URBDEPTH;
- sk->s->cfg.period_frames = period_frames;
- sk->s->period_size = frame_size * period_frames;
-
- sk->s->write_size = write_size;
- pg = get_order(write_size);
-
- sk->write_page =
- (void *)__get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO, pg);
- if (!sk->write_page) {
- snd_printk(KERN_WARNING "couldn't __get_free_pages()\n");
- usb_stream_free(sk);
- return NULL;
- }
-
- /* calculate the frequency in 16.16 format */
- if (dev->speed == USB_SPEED_FULL)
- sk->freqn = get_usb_full_speed_rate(sample_rate);
- else
- sk->freqn = get_usb_high_speed_rate(sample_rate);
-
- init_urbs(sk, use_packsize, dev, in_pipe, out_pipe);
- sk->s->state = usb_stream_stopped;
-out:
- return sk->s;
-}
-
-
-/* start */
-
-static bool balance_check(struct usb_stream_kernel *sk, struct urb *urb)
-{
- bool r;
- if (unlikely(urb->status)) {
- if (urb->status != -ESHUTDOWN && urb->status != -ENOENT)
- snd_printk(KERN_WARNING "status=%i\n", urb->status);
- sk->iso_frame_balance = 0x7FFFFFFF;
- return false;
- }
- r = sk->iso_frame_balance == 0;
- if (!r)
- sk->i_urb = urb;
- return r;
-}
-
-static bool balance_playback(struct usb_stream_kernel *sk, struct urb *urb)
-{
- sk->iso_frame_balance += urb->number_of_packets;
- return balance_check(sk, urb);
-}
-
-static bool balance_capture(struct usb_stream_kernel *sk, struct urb *urb)
-{
- sk->iso_frame_balance -= urb->number_of_packets;
- return balance_check(sk, urb);
-}
-
-static void subs_set_complete(struct urb **urbs, void (*complete)(struct urb *))
-{
- int u;
-
- for (u = 0; u < USB_STREAM_NURBS; u++) {
- struct urb *urb = urbs[u];
- urb->complete = complete;
- }
-}
-
-static int usb_stream_prepare_playback(struct usb_stream_kernel *sk,
- struct urb *inurb)
-{
- struct usb_stream *s = sk->s;
- struct urb *io;
- struct usb_iso_packet_descriptor *id, *od;
- int p = 0, lb = 0, l = 0;
-
- io = sk->idle_outurb;
- od = io->iso_frame_desc;
-
- for (; s->sync_packet < 0; ++p, ++s->sync_packet) {
- struct urb *ii = sk->completed_inurb;
- id = ii->iso_frame_desc +
- ii->number_of_packets + s->sync_packet;
- l = id->actual_length;
-
- od[p].length = l;
- od[p].offset = lb;
- lb += l;
- }
-
- for (;
- s->sync_packet < inurb->number_of_packets && p < sk->n_o_ps;
- ++p, ++s->sync_packet) {
- l = inurb->iso_frame_desc[s->sync_packet].actual_length;
-
- if (s->idle_outsize + lb + l > s->period_size)
- goto check_ok;
-
- od[p].length = l;
- od[p].offset = lb;
- lb += l;
- }
-
-check_ok:
- s->sync_packet -= inurb->number_of_packets;
- if (unlikely(s->sync_packet < -2 || s->sync_packet > 0)) {
- snd_printk(KERN_WARNING "invalid sync_packet = %i;"
- " p=%i nop=%i %i %x %x %x > %x\n",
- s->sync_packet, p, inurb->number_of_packets,
- s->idle_outsize + lb + l,
- s->idle_outsize, lb, l,
- s->period_size);
- return -1;
- }
- if (unlikely(lb % s->cfg.frame_size)) {
- snd_printk(KERN_WARNING"invalid outsize = %i\n",
- lb);
- return -1;
- }
- s->idle_outsize += lb - s->period_size;
- io->number_of_packets = p;
- io->transfer_buffer_length = lb;
- if (s->idle_outsize <= 0)
- return 0;
-
- snd_printk(KERN_WARNING "idle=%i\n", s->idle_outsize);
- return -1;
-}
-
-static void prepare_inurb(int number_of_packets, struct urb *iu)
-{
- struct usb_iso_packet_descriptor *id;
- int p;
-
- iu->number_of_packets = number_of_packets;
- id = iu->iso_frame_desc;
- id->offset = 0;
- for (p = 0; p < iu->number_of_packets - 1; ++p)
- id[p + 1].offset = id[p].offset + id[p].length;
-
- iu->transfer_buffer_length =
- id[0].length * iu->number_of_packets;
-}
-
-static int submit_urbs(struct usb_stream_kernel *sk,
- struct urb *inurb, struct urb *outurb)
-{
- int err;
- prepare_inurb(sk->idle_outurb->number_of_packets, sk->idle_inurb);
- err = usb_submit_urb(sk->idle_inurb, GFP_ATOMIC);
- if (err < 0) {
- snd_printk(KERN_ERR "%i\n", err);
- return err;
- }
- sk->idle_inurb = sk->completed_inurb;
- sk->completed_inurb = inurb;
- err = usb_submit_urb(sk->idle_outurb, GFP_ATOMIC);
- if (err < 0) {
- snd_printk(KERN_ERR "%i\n", err);
- return err;
- }
- sk->idle_outurb = sk->completed_outurb;
- sk->completed_outurb = outurb;
- return 0;
-}
-
-#ifdef DEBUG_LOOP_BACK
-/*
- This loop_back() shows how to read/write the period data.
- */
-static void loop_back(struct usb_stream *s)
-{
- char *i, *o;
- int il, ol, l, p;
- struct urb *iu;
- struct usb_iso_packet_descriptor *id;
-
- o = s->playback1st_to;
- ol = s->playback1st_size;
- l = 0;
-
- if (s->insplit_pack >= 0) {
- iu = sk->idle_inurb;
- id = iu->iso_frame_desc;
- p = s->insplit_pack;
- } else
- goto second;
-loop:
- for (; p < iu->number_of_packets && l < s->period_size; ++p) {
- i = iu->transfer_buffer + id[p].offset;
- il = id[p].actual_length;
- if (l + il > s->period_size)
- il = s->period_size - l;
- if (il <= ol) {
- memcpy(o, i, il);
- o += il;
- ol -= il;
- } else {
- memcpy(o, i, ol);
- singen_6pack(o, ol);
- o = s->playback_to;
- memcpy(o, i + ol, il - ol);
- o += il - ol;
- ol = s->period_size - s->playback1st_size;
- }
- l += il;
- }
- if (iu == sk->completed_inurb) {
- if (l != s->period_size)
- printk(KERN_DEBUG"%s:%i %i\n", __func__, __LINE__,
- l/(int)s->cfg.frame_size);
-
- return;
- }
-second:
- iu = sk->completed_inurb;
- id = iu->iso_frame_desc;
- p = 0;
- goto loop;
-
-}
-#else
-static void loop_back(struct usb_stream *s)
-{
-}
-#endif
-
-static void stream_idle(struct usb_stream_kernel *sk,
- struct urb *inurb, struct urb *outurb)
-{
- struct usb_stream *s = sk->s;
- int l, p;
- int insize = s->idle_insize;
- int urb_size = 0;
-
- s->inpacket_split = s->next_inpacket_split;
- s->inpacket_split_at = s->next_inpacket_split_at;
- s->next_inpacket_split = -1;
- s->next_inpacket_split_at = 0;
-
- for (p = 0; p < inurb->number_of_packets; ++p) {
- struct usb_iso_packet_descriptor *id = inurb->iso_frame_desc;
- l = id[p].actual_length;
- if (unlikely(l == 0 || id[p].status)) {
- snd_printk(KERN_WARNING "underrun, status=%u\n",
- id[p].status);
- goto err_out;
- }
- s->inpacket_head++;
- s->inpacket_head %= s->inpackets;
- if (s->inpacket_split == -1)
- s->inpacket_split = s->inpacket_head;
-
- s->inpacket[s->inpacket_head].offset =
- id[p].offset + (inurb->transfer_buffer - (void *)s);
- s->inpacket[s->inpacket_head].length = l;
- if (insize + l > s->period_size &&
- s->next_inpacket_split == -1) {
- s->next_inpacket_split = s->inpacket_head;
- s->next_inpacket_split_at = s->period_size - insize;
- }
- insize += l;
- urb_size += l;
- }
- s->idle_insize += urb_size - s->period_size;
- if (s->idle_insize < 0) {
- snd_printk(KERN_WARNING "%i\n",
- (s->idle_insize)/(int)s->cfg.frame_size);
- goto err_out;
- }
- s->insize_done += urb_size;
-
- l = s->idle_outsize;
- s->outpacket[0].offset = (sk->idle_outurb->transfer_buffer -
- sk->write_page) - l;
-
- if (usb_stream_prepare_playback(sk, inurb) < 0)
- goto err_out;
-
- s->outpacket[0].length = sk->idle_outurb->transfer_buffer_length + l;
- s->outpacket[1].offset = sk->completed_outurb->transfer_buffer -
- sk->write_page;
-
- if (submit_urbs(sk, inurb, outurb) < 0)
- goto err_out;
-
- loop_back(s);
- s->periods_done++;
- wake_up_all(&sk->sleep);
- return;
-err_out:
- s->state = usb_stream_xrun;
- wake_up_all(&sk->sleep);
-}
-
-static void i_capture_idle(struct urb *urb)
-{
- struct usb_stream_kernel *sk = urb->context;
- if (balance_capture(sk, urb))
- stream_idle(sk, urb, sk->i_urb);
-}
-
-static void i_playback_idle(struct urb *urb)
-{
- struct usb_stream_kernel *sk = urb->context;
- if (balance_playback(sk, urb))
- stream_idle(sk, sk->i_urb, urb);
-}
-
-static void stream_start(struct usb_stream_kernel *sk,
- struct urb *inurb, struct urb *outurb)
-{
- struct usb_stream *s = sk->s;
- if (s->state >= usb_stream_sync1) {
- int l, p, max_diff, max_diff_0;
- int urb_size = 0;
- unsigned frames_per_packet, min_frames = 0;
- frames_per_packet = (s->period_size - s->idle_insize);
- frames_per_packet <<= 8;
- frames_per_packet /=
- s->cfg.frame_size * inurb->number_of_packets;
- frames_per_packet++;
-
- max_diff_0 = s->cfg.frame_size;
- if (s->cfg.period_frames >= 256)
- max_diff_0 <<= 1;
- if (s->cfg.period_frames >= 1024)
- max_diff_0 <<= 1;
- max_diff = max_diff_0;
- for (p = 0; p < inurb->number_of_packets; ++p) {
- int diff;
- l = inurb->iso_frame_desc[p].actual_length;
- urb_size += l;
-
- min_frames += frames_per_packet;
- diff = urb_size -
- (min_frames >> 8) * s->cfg.frame_size;
- if (diff < max_diff) {
- snd_printdd(KERN_DEBUG "%i %i %i %i\n",
- s->insize_done,
- urb_size / (int)s->cfg.frame_size,
- inurb->number_of_packets, diff);
- max_diff = diff;
- }
- }
- s->idle_insize -= max_diff - max_diff_0;
- s->idle_insize += urb_size - s->period_size;
- if (s->idle_insize < 0) {
- snd_printk(KERN_WARNING "%i %i %i\n",
- s->idle_insize, urb_size, s->period_size);
- return;
- } else if (s->idle_insize == 0) {
- s->next_inpacket_split =
- (s->inpacket_head + 1) % s->inpackets;
- s->next_inpacket_split_at = 0;
- } else {
- unsigned split = s->inpacket_head;
- l = s->idle_insize;
- while (l > s->inpacket[split].length) {
- l -= s->inpacket[split].length;
- if (split == 0)
- split = s->inpackets - 1;
- else
- split--;
- }
- s->next_inpacket_split = split;
- s->next_inpacket_split_at =
- s->inpacket[split].length - l;
- }
-
- s->insize_done += urb_size;
-
- if (usb_stream_prepare_playback(sk, inurb) < 0)
- return;
-
- } else
- playback_prep_freqn(sk, sk->idle_outurb);
-
- if (submit_urbs(sk, inurb, outurb) < 0)
- return;
-
- if (s->state == usb_stream_sync1 && s->insize_done > 360000) {
- /* just guesswork ^^^^^^ */
- s->state = usb_stream_ready;
- subs_set_complete(sk->inurb, i_capture_idle);
- subs_set_complete(sk->outurb, i_playback_idle);
- }
-}
-
-static void i_capture_start(struct urb *urb)
-{
- struct usb_iso_packet_descriptor *id = urb->iso_frame_desc;
- struct usb_stream_kernel *sk = urb->context;
- struct usb_stream *s = sk->s;
- int p;
- int empty = 0;
-
- if (urb->status) {
- snd_printk(KERN_WARNING "status=%i\n", urb->status);
- return;
- }
-
- for (p = 0; p < urb->number_of_packets; ++p) {
- int l = id[p].actual_length;
- if (l < s->cfg.frame_size) {
- ++empty;
- if (s->state >= usb_stream_sync0) {
- snd_printk(KERN_WARNING "%i\n", l);
- return;
- }
- }
- s->inpacket_head++;
- s->inpacket_head %= s->inpackets;
- s->inpacket[s->inpacket_head].offset =
- id[p].offset + (urb->transfer_buffer - (void *)s);
- s->inpacket[s->inpacket_head].length = l;
- }
-#ifdef SHOW_EMPTY
- if (empty) {
- printk(KERN_DEBUG"%s:%i: %i", __func__, __LINE__,
- urb->iso_frame_desc[0].actual_length);
- for (pack = 1; pack < urb->number_of_packets; ++pack) {
- int l = urb->iso_frame_desc[pack].actual_length;
- printk(" %i", l);
- }
- printk("\n");
- }
-#endif
- if (!empty && s->state < usb_stream_sync1)
- ++s->state;
-
- if (balance_capture(sk, urb))
- stream_start(sk, urb, sk->i_urb);
-}
-
-static void i_playback_start(struct urb *urb)
-{
- struct usb_stream_kernel *sk = urb->context;
- if (balance_playback(sk, urb))
- stream_start(sk, sk->i_urb, urb);
-}
-
-int usb_stream_start(struct usb_stream_kernel *sk)
-{
- struct usb_stream *s = sk->s;
- int frame = 0, iters = 0;
- int u, err;
- int try = 0;
-
- if (s->state != usb_stream_stopped)
- return -EAGAIN;
-
- subs_set_complete(sk->inurb, i_capture_start);
- subs_set_complete(sk->outurb, i_playback_start);
- memset(sk->write_page, 0, s->write_size);
-dotry:
- s->insize_done = 0;
- s->idle_insize = 0;
- s->idle_outsize = 0;
- s->sync_packet = -1;
- s->inpacket_head = -1;
- sk->iso_frame_balance = 0;
- ++try;
- for (u = 0; u < 2; u++) {
- struct urb *inurb = sk->inurb[u];
- struct urb *outurb = sk->outurb[u];
- playback_prep_freqn(sk, outurb);
- inurb->number_of_packets = outurb->number_of_packets;
- inurb->transfer_buffer_length =
- inurb->number_of_packets *
- inurb->iso_frame_desc[0].length;
-
- if (u == 0) {
- int now;
- struct usb_device *dev = inurb->dev;
- frame = usb_get_current_frame_number(dev);
- do {
- now = usb_get_current_frame_number(dev);
- ++iters;
- } while (now > -1 && now == frame);
- }
- err = usb_submit_urb(inurb, GFP_ATOMIC);
- if (err < 0) {
- snd_printk(KERN_ERR"usb_submit_urb(sk->inurb[%i])"
- " returned %i\n", u, err);
- return err;
- }
- err = usb_submit_urb(outurb, GFP_ATOMIC);
- if (err < 0) {
- snd_printk(KERN_ERR"usb_submit_urb(sk->outurb[%i])"
- " returned %i\n", u, err);
- return err;
- }
-
- if (inurb->start_frame != outurb->start_frame) {
- snd_printd(KERN_DEBUG
- "u[%i] start_frames differ in:%u out:%u\n",
- u, inurb->start_frame, outurb->start_frame);
- goto check_retry;
- }
- }
- snd_printdd(KERN_DEBUG "%i %i\n", frame, iters);
- try = 0;
-check_retry:
- if (try) {
- usb_stream_stop(sk);
- if (try < 5) {
- msleep(1500);
- snd_printd(KERN_DEBUG "goto dotry;\n");
- goto dotry;
- }
- snd_printk(KERN_WARNING"couldn't start"
- " all urbs on the same start_frame.\n");
- return -EFAULT;
- }
-
- sk->idle_inurb = sk->inurb[USB_STREAM_NURBS - 2];
- sk->idle_outurb = sk->outurb[USB_STREAM_NURBS - 2];
- sk->completed_inurb = sk->inurb[USB_STREAM_NURBS - 1];
- sk->completed_outurb = sk->outurb[USB_STREAM_NURBS - 1];
-
-/* wait, check */
- {
- int wait_ms = 3000;
- while (s->state != usb_stream_ready && wait_ms > 0) {
- snd_printdd(KERN_DEBUG "%i\n", s->state);
- msleep(200);
- wait_ms -= 200;
- }
- }
-
- return s->state == usb_stream_ready ? 0 : -EFAULT;
-}
-
-
-/* stop */
-
-void usb_stream_stop(struct usb_stream_kernel *sk)
-{
- int u;
- if (!sk->s)
- return;
- for (u = 0; u < USB_STREAM_NURBS; ++u) {
- usb_kill_urb(sk->inurb[u]);
- usb_kill_urb(sk->outurb[u]);
- }
- sk->s->state = usb_stream_stopped;
- msleep(400);
-}
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usb_stream.h b/ANDROID_3.4.5/sound/usb/usx2y/usb_stream.h
deleted file mode 100644
index 4dd74ab1..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usb_stream.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Karsten Wiese <fzu@wemgehoertderstaat.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define USB_STREAM_INTERFACE_VERSION 2
-
-#define SNDRV_USB_STREAM_IOCTL_SET_PARAMS \
- _IOW('H', 0x90, struct usb_stream_config)
-
-struct usb_stream_packet {
- unsigned offset;
- unsigned length;
-};
-
-
-struct usb_stream_config {
- unsigned version;
- unsigned sample_rate;
- unsigned period_frames;
- unsigned frame_size;
-};
-
-struct usb_stream {
- struct usb_stream_config cfg;
- unsigned read_size;
- unsigned write_size;
-
- int period_size;
-
- unsigned state;
-
- int idle_insize;
- int idle_outsize;
- int sync_packet;
- unsigned insize_done;
- unsigned periods_done;
- unsigned periods_polled;
-
- struct usb_stream_packet outpacket[2];
- unsigned inpackets;
- unsigned inpacket_head;
- unsigned inpacket_split;
- unsigned inpacket_split_at;
- unsigned next_inpacket_split;
- unsigned next_inpacket_split_at;
- struct usb_stream_packet inpacket[0];
-};
-
-enum usb_stream_state {
- usb_stream_invalid,
- usb_stream_stopped,
- usb_stream_sync0,
- usb_stream_sync1,
- usb_stream_ready,
- usb_stream_running,
- usb_stream_xrun,
-};
-
-#if __KERNEL__
-
-#define USB_STREAM_NURBS 4
-#define USB_STREAM_URBDEPTH 4
-
-struct usb_stream_kernel {
- struct usb_stream *s;
-
- void *write_page;
-
- unsigned n_o_ps;
-
- struct urb *inurb[USB_STREAM_NURBS];
- struct urb *idle_inurb;
- struct urb *completed_inurb;
- struct urb *outurb[USB_STREAM_NURBS];
- struct urb *idle_outurb;
- struct urb *completed_outurb;
- struct urb *i_urb;
-
- int iso_frame_balance;
-
- wait_queue_head_t sleep;
-
- unsigned out_phase;
- unsigned out_phase_peeked;
- unsigned freqn;
-};
-
-struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk,
- struct usb_device *dev,
- unsigned in_endpoint, unsigned out_endpoint,
- unsigned sample_rate, unsigned use_packsize,
- unsigned period_frames, unsigned frame_size);
-void usb_stream_free(struct usb_stream_kernel *);
-int usb_stream_start(struct usb_stream_kernel *);
-void usb_stream_stop(struct usb_stream_kernel *);
-
-
-#endif
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usbus428ctldefs.h b/ANDROID_3.4.5/sound/usb/usx2y/usbus428ctldefs.h
deleted file mode 100644
index b864e7e2..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usbus428ctldefs.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- *
- * Copyright (c) 2003 by Karsten Wiese <annabellesgarden@yahoo.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-enum E_In84{
- eFader0 = 0,
- eFader1,
- eFader2,
- eFader3,
- eFader4,
- eFader5,
- eFader6,
- eFader7,
- eFaderM,
- eTransport,
- eModifier = 10,
- eFilterSelect,
- eSelect,
- eMute,
-
- eSwitch = 15,
- eWheelGain,
- eWheelFreq,
- eWheelQ,
- eWheelPan,
- eWheel = 20
-};
-
-#define T_RECORD 1
-#define T_PLAY 2
-#define T_STOP 4
-#define T_F_FWD 8
-#define T_REW 0x10
-#define T_SOLO 0x20
-#define T_REC 0x40
-#define T_NULL 0x80
-
-
-struct us428_ctls {
- unsigned char Fader[9];
- unsigned char Transport;
- unsigned char Modifier;
- unsigned char FilterSelect;
- unsigned char Select;
- unsigned char Mute;
- unsigned char UNKNOWN;
- unsigned char Switch;
- unsigned char Wheel[5];
-};
-
-struct us428_setByte {
- unsigned char Offset,
- Value;
-};
-
-enum {
- eLT_Volume = 0,
- eLT_Light
-};
-
-struct usX2Y_volume {
- unsigned char Channel,
- LH,
- LL,
- RH,
- RL;
-};
-
-struct us428_lights {
- struct us428_setByte Light[7];
-};
-
-struct us428_p4out {
- char type;
- union {
- struct usX2Y_volume vol;
- struct us428_lights lights;
- } val;
-};
-
-#define N_us428_ctl_BUFS 16
-#define N_us428_p4out_BUFS 16
-struct us428ctls_sharedmem{
- struct us428_ctls CtlSnapShot[N_us428_ctl_BUFS];
- int CtlSnapShotDiffersAt[N_us428_ctl_BUFS];
- int CtlSnapShotLast, CtlSnapShotRed;
- struct us428_p4out p4out[N_us428_p4out_BUFS];
- int p4outLast, p4outSent;
-};
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usbusx2y.c b/ANDROID_3.4.5/sound/usb/usx2y/usbusx2y.c
deleted file mode 100644
index 9af7c1f1..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usbusx2y.c
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * usbusy2y.c - ALSA USB US-428 Driver
- *
-2005-04-14 Karsten Wiese
- Version 0.8.7.2:
- Call snd_card_free() instead of snd_card_free_in_thread() to prevent oops with dead keyboard symptom.
- Tested ok with kernel 2.6.12-rc2.
-
-2004-12-14 Karsten Wiese
- Version 0.8.7.1:
- snd_pcm_open for rawusb pcm-devices now returns -EBUSY if called without rawusb's hwdep device being open.
-
-2004-12-02 Karsten Wiese
- Version 0.8.7:
- Use macro usb_maxpacket() for portability.
-
-2004-10-26 Karsten Wiese
- Version 0.8.6:
- wake_up() process waiting in usX2Y_urbs_start() on error.
-
-2004-10-21 Karsten Wiese
- Version 0.8.5:
- nrpacks is runtime or compiletime configurable now with tested values from 1 to 4.
-
-2004-10-03 Karsten Wiese
- Version 0.8.2:
- Avoid any possible racing while in prepare callback.
-
-2004-09-30 Karsten Wiese
- Version 0.8.0:
- Simplified things and made ohci work again.
-
-2004-09-20 Karsten Wiese
- Version 0.7.3:
- Use usb_kill_urb() instead of deprecated (kernel 2.6.9) usb_unlink_urb().
-
-2004-07-13 Karsten Wiese
- Version 0.7.1:
- Don't sleep in START/STOP callbacks anymore.
- us428 channels C/D not handled just for this version, sorry.
-
-2004-06-21 Karsten Wiese
- Version 0.6.4:
- Temporarely suspend midi input
- to sanely call usb_set_interface() when setting format.
-
-2004-06-12 Karsten Wiese
- Version 0.6.3:
- Made it thus the following rule is enforced:
- "All pcm substreams of one usX2Y have to operate at the same rate & format."
-
-2004-04-06 Karsten Wiese
- Version 0.6.0:
- Runs on 2.6.5 kernel without any "--with-debug=" things.
- us224 reported running.
-
-2004-01-14 Karsten Wiese
- Version 0.5.1:
- Runs with 2.6.1 kernel.
-
-2003-12-30 Karsten Wiese
- Version 0.4.1:
- Fix 24Bit 4Channel capturing for the us428.
-
-2003-11-27 Karsten Wiese, Martin Langer
- Version 0.4:
- us122 support.
- us224 could be tested by uncommenting the sections containing USB_ID_US224
-
-2003-11-03 Karsten Wiese
- Version 0.3:
- 24Bit support.
- "arecord -D hw:1 -c 2 -r 48000 -M -f S24_3LE|aplay -D hw:1 -c 2 -r 48000 -M -f S24_3LE" works.
-
-2003-08-22 Karsten Wiese
- Version 0.0.8:
- Removed EZUSB Firmware. First Stage Firmwaredownload is now done by tascam-firmware downloader.
- See:
- http://usb-midi-fw.sourceforge.net/tascam-firmware.tar.gz
-
-2003-06-18 Karsten Wiese
- Version 0.0.5:
- changed to compile with kernel 2.4.21 and alsa 0.9.4
-
-2002-10-16 Karsten Wiese
- Version 0.0.4:
- compiles again with alsa-current.
- USB_ISO_ASAP not used anymore (most of the time), instead
- urb->start_frame is calculated here now, some calls inside usb-driver don't need to happen anymore.
-
- To get the best out of this:
- Disable APM-support in the kernel as APM-BIOS calls (once each second) hard disable interrupt for many precious milliseconds.
- This helped me much on my slowish PII 400 & PIII 500.
- ACPI yet untested but might cause the same bad behaviour.
- Use a kernel with lowlatency and preemptiv patches applied.
- To autoload snd-usb-midi append a line
- post-install snd-usb-us428 modprobe snd-usb-midi
- to /etc/modules.conf.
-
- known problems:
- sliders, knobs, lights not yet handled except MASTER Volume slider.
- "pcm -c 2" doesn't work. "pcm -c 2 -m direct_interleaved" does.
- KDE3: "Enable full duplex operation" deadlocks.
-
-
-2002-08-31 Karsten Wiese
- Version 0.0.3: audio also simplex;
- simplifying: iso urbs only 1 packet, melted structs.
- ASYNC_UNLINK not used anymore: no more crashes so far.....
- for alsa 0.9 rc3.
-
-2002-08-09 Karsten Wiese
- Version 0.0.2: midi works with snd-usb-midi, audio (only fullduplex now) with i.e. bristol.
- The firmware has been sniffed from win2k us-428 driver 3.09.
-
- * Copyright (c) 2002 - 2004 Karsten Wiese
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/usb.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-
-#include <sound/rawmidi.h>
-#include "usx2y.h"
-#include "usbusx2y.h"
-#include "usX2Yhwdep.h"
-
-
-
-MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>");
-MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.2");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604), "NAME_ALLCAPS"(0x8001)(0x8005)(0x8007) }}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
-static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS".");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for "NAME_ALLCAPS".");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable "NAME_ALLCAPS".");
-
-
-static int snd_usX2Y_card_used[SNDRV_CARDS];
-
-static void usX2Y_usb_disconnect(struct usb_device* usb_device, void* ptr);
-static void snd_usX2Y_card_private_free(struct snd_card *card);
-
-/*
- * pipe 4 is used for switching the lamps, setting samplerate, volumes ....
- */
-static void i_usX2Y_Out04Int(struct urb *urb)
-{
-#ifdef CONFIG_SND_DEBUG
- if (urb->status) {
- int i;
- struct usX2Ydev *usX2Y = urb->context;
- for (i = 0; i < 10 && usX2Y->AS04.urb[i] != urb; i++);
- snd_printdd("i_usX2Y_Out04Int() urb %i status=%i\n", i, urb->status);
- }
-#endif
-}
-
-static void i_usX2Y_In04Int(struct urb *urb)
-{
- int err = 0;
- struct usX2Ydev *usX2Y = urb->context;
- struct us428ctls_sharedmem *us428ctls = usX2Y->us428ctls_sharedmem;
-
- usX2Y->In04IntCalls++;
-
- if (urb->status) {
- snd_printdd("Interrupt Pipe 4 came back with status=%i\n", urb->status);
- return;
- }
-
- // printk("%i:0x%02X ", 8, (int)((unsigned char*)usX2Y->In04Buf)[8]); Master volume shows 0 here if fader is at max during boot ?!?
- if (us428ctls) {
- int diff = -1;
- if (-2 == us428ctls->CtlSnapShotLast) {
- diff = 0;
- memcpy(usX2Y->In04Last, usX2Y->In04Buf, sizeof(usX2Y->In04Last));
- us428ctls->CtlSnapShotLast = -1;
- } else {
- int i;
- for (i = 0; i < 21; i++) {
- if (usX2Y->In04Last[i] != ((char*)usX2Y->In04Buf)[i]) {
- if (diff < 0)
- diff = i;
- usX2Y->In04Last[i] = ((char*)usX2Y->In04Buf)[i];
- }
- }
- }
- if (0 <= diff) {
- int n = us428ctls->CtlSnapShotLast + 1;
- if (n >= N_us428_ctl_BUFS || n < 0)
- n = 0;
- memcpy(us428ctls->CtlSnapShot + n, usX2Y->In04Buf, sizeof(us428ctls->CtlSnapShot[0]));
- us428ctls->CtlSnapShotDiffersAt[n] = diff;
- us428ctls->CtlSnapShotLast = n;
- wake_up(&usX2Y->us428ctls_wait_queue_head);
- }
- }
-
-
- if (usX2Y->US04) {
- if (0 == usX2Y->US04->submitted)
- do {
- err = usb_submit_urb(usX2Y->US04->urb[usX2Y->US04->submitted++], GFP_ATOMIC);
- } while (!err && usX2Y->US04->submitted < usX2Y->US04->len);
- } else
- if (us428ctls && us428ctls->p4outLast >= 0 && us428ctls->p4outLast < N_us428_p4out_BUFS) {
- if (us428ctls->p4outLast != us428ctls->p4outSent) {
- int j, send = us428ctls->p4outSent + 1;
- if (send >= N_us428_p4out_BUFS)
- send = 0;
- for (j = 0; j < URBS_AsyncSeq && !err; ++j)
- if (0 == usX2Y->AS04.urb[j]->status) {
- struct us428_p4out *p4out = us428ctls->p4out + send; // FIXME if more than 1 p4out is new, 1 gets lost.
- usb_fill_bulk_urb(usX2Y->AS04.urb[j], usX2Y->dev,
- usb_sndbulkpipe(usX2Y->dev, 0x04), &p4out->val.vol,
- p4out->type == eLT_Light ? sizeof(struct us428_lights) : 5,
- i_usX2Y_Out04Int, usX2Y);
- err = usb_submit_urb(usX2Y->AS04.urb[j], GFP_ATOMIC);
- us428ctls->p4outSent = send;
- break;
- }
- }
- }
-
- if (err)
- snd_printk(KERN_ERR "In04Int() usb_submit_urb err=%i\n", err);
-
- urb->dev = usX2Y->dev;
- usb_submit_urb(urb, GFP_ATOMIC);
-}
-
-/*
- * Prepare some urbs
- */
-int usX2Y_AsyncSeq04_init(struct usX2Ydev *usX2Y)
-{
- int err = 0,
- i;
-
- if (NULL == (usX2Y->AS04.buffer = kmalloc(URB_DataLen_AsyncSeq*URBS_AsyncSeq, GFP_KERNEL))) {
- err = -ENOMEM;
- } else
- for (i = 0; i < URBS_AsyncSeq; ++i) {
- if (NULL == (usX2Y->AS04.urb[i] = usb_alloc_urb(0, GFP_KERNEL))) {
- err = -ENOMEM;
- break;
- }
- usb_fill_bulk_urb( usX2Y->AS04.urb[i], usX2Y->dev,
- usb_sndbulkpipe(usX2Y->dev, 0x04),
- usX2Y->AS04.buffer + URB_DataLen_AsyncSeq*i, 0,
- i_usX2Y_Out04Int, usX2Y
- );
- }
- return err;
-}
-
-int usX2Y_In04_init(struct usX2Ydev *usX2Y)
-{
- if (! (usX2Y->In04urb = usb_alloc_urb(0, GFP_KERNEL)))
- return -ENOMEM;
-
- if (! (usX2Y->In04Buf = kmalloc(21, GFP_KERNEL))) {
- usb_free_urb(usX2Y->In04urb);
- return -ENOMEM;
- }
-
- init_waitqueue_head(&usX2Y->In04WaitQueue);
- usb_fill_int_urb(usX2Y->In04urb, usX2Y->dev, usb_rcvintpipe(usX2Y->dev, 0x4),
- usX2Y->In04Buf, 21,
- i_usX2Y_In04Int, usX2Y,
- 10);
- return usb_submit_urb(usX2Y->In04urb, GFP_KERNEL);
-}
-
-static void usX2Y_unlinkSeq(struct snd_usX2Y_AsyncSeq *S)
-{
- int i;
- for (i = 0; i < URBS_AsyncSeq; ++i) {
- if (S[i].urb) {
- usb_kill_urb(S->urb[i]);
- usb_free_urb(S->urb[i]);
- S->urb[i] = NULL;
- }
- }
- kfree(S->buffer);
-}
-
-
-static struct usb_device_id snd_usX2Y_usb_id_table[] = {
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x1604,
- .idProduct = USB_ID_US428
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x1604,
- .idProduct = USB_ID_US122
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x1604,
- .idProduct = USB_ID_US224
- },
- { /* terminator */ }
-};
-
-static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp)
-{
- int dev;
- struct snd_card * card;
- int err;
-
- for (dev = 0; dev < SNDRV_CARDS; ++dev)
- if (enable[dev] && !snd_usX2Y_card_used[dev])
- break;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct usX2Ydev), &card);
- if (err < 0)
- return err;
- snd_usX2Y_card_used[usX2Y(card)->card_index = dev] = 1;
- card->private_free = snd_usX2Y_card_private_free;
- usX2Y(card)->dev = device;
- init_waitqueue_head(&usX2Y(card)->prepare_wait_queue);
- mutex_init(&usX2Y(card)->prepare_mutex);
- INIT_LIST_HEAD(&usX2Y(card)->midi_list);
- strcpy(card->driver, "USB "NAME_ALLCAPS"");
- sprintf(card->shortname, "TASCAM "NAME_ALLCAPS"");
- sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)",
- card->shortname,
- le16_to_cpu(device->descriptor.idVendor),
- le16_to_cpu(device->descriptor.idProduct),
- 0,//us428(card)->usbmidi.ifnum,
- usX2Y(card)->dev->bus->busnum, usX2Y(card)->dev->devnum
- );
- *cardp = card;
- return 0;
-}
-
-
-static int usX2Y_usb_probe(struct usb_device *device,
- struct usb_interface *intf,
- const struct usb_device_id *device_id,
- struct snd_card **cardp)
-{
- int err;
- struct snd_card * card;
-
- *cardp = NULL;
- if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 ||
- (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 &&
- le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 &&
- le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428))
- return -EINVAL;
-
- err = usX2Y_create_card(device, &card);
- if (err < 0)
- return err;
- snd_card_set_dev(card, &intf->dev);
- if ((err = usX2Y_hwdep_new(card, device)) < 0 ||
- (err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- *cardp = card;
- return 0;
-}
-
-/*
- * new 2.5 USB kernel API
- */
-static int snd_usX2Y_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct snd_card *card;
- int err;
-
- err = usX2Y_usb_probe(interface_to_usbdev(intf), intf, id, &card);
- if (err < 0)
- return err;
- dev_set_drvdata(&intf->dev, card);
- return 0;
-}
-
-static void snd_usX2Y_disconnect(struct usb_interface *intf)
-{
- usX2Y_usb_disconnect(interface_to_usbdev(intf),
- usb_get_intfdata(intf));
-}
-
-MODULE_DEVICE_TABLE(usb, snd_usX2Y_usb_id_table);
-static struct usb_driver snd_usX2Y_usb_driver = {
- .name = "snd-usb-usx2y",
- .probe = snd_usX2Y_probe,
- .disconnect = snd_usX2Y_disconnect,
- .id_table = snd_usX2Y_usb_id_table,
-};
-
-static void snd_usX2Y_card_private_free(struct snd_card *card)
-{
- kfree(usX2Y(card)->In04Buf);
- usb_free_urb(usX2Y(card)->In04urb);
- if (usX2Y(card)->us428ctls_sharedmem)
- snd_free_pages(usX2Y(card)->us428ctls_sharedmem, sizeof(*usX2Y(card)->us428ctls_sharedmem));
- if (usX2Y(card)->card_index >= 0 && usX2Y(card)->card_index < SNDRV_CARDS)
- snd_usX2Y_card_used[usX2Y(card)->card_index] = 0;
-}
-
-/*
- * Frees the device.
- */
-static void usX2Y_usb_disconnect(struct usb_device *device, void* ptr)
-{
- if (ptr) {
- struct snd_card *card = ptr;
- struct usX2Ydev *usX2Y = usX2Y(card);
- struct list_head *p;
- usX2Y->chip_status = USX2Y_STAT_CHIP_HUP;
- usX2Y_unlinkSeq(&usX2Y->AS04);
- usb_kill_urb(usX2Y->In04urb);
- snd_card_disconnect(card);
- /* release the midi resources */
- list_for_each(p, &usX2Y->midi_list) {
- snd_usbmidi_disconnect(p);
- }
- if (usX2Y->us428ctls_sharedmem)
- wake_up(&usX2Y->us428ctls_wait_queue_head);
- snd_card_free(card);
- }
-}
-
-module_usb_driver(snd_usX2Y_usb_driver);
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usbusx2y.h b/ANDROID_3.4.5/sound/usb/usx2y/usbusx2y.h
deleted file mode 100644
index e43c0a86..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usbusx2y.h
+++ /dev/null
@@ -1,88 +0,0 @@
-#ifndef USBUSX2Y_H
-#define USBUSX2Y_H
-#include "../usbaudio.h"
-#include "../midi.h"
-#include "usbus428ctldefs.h"
-
-#define NRURBS 2
-
-
-#define URBS_AsyncSeq 10
-#define URB_DataLen_AsyncSeq 32
-struct snd_usX2Y_AsyncSeq {
- struct urb *urb[URBS_AsyncSeq];
- char *buffer;
-};
-
-struct snd_usX2Y_urbSeq {
- int submitted;
- int len;
- struct urb *urb[0];
-};
-
-#include "usx2yhwdeppcm.h"
-
-struct usX2Ydev {
- struct usb_device *dev;
- int card_index;
- int stride;
- struct urb *In04urb;
- void *In04Buf;
- char In04Last[24];
- unsigned In04IntCalls;
- struct snd_usX2Y_urbSeq *US04;
- wait_queue_head_t In04WaitQueue;
- struct snd_usX2Y_AsyncSeq AS04;
- unsigned int rate,
- format;
- int chip_status;
- struct mutex prepare_mutex;
- struct us428ctls_sharedmem *us428ctls_sharedmem;
- int wait_iso_frame;
- wait_queue_head_t us428ctls_wait_queue_head;
- struct snd_usX2Y_hwdep_pcm_shm *hwdep_pcm_shm;
- struct snd_usX2Y_substream *subs[4];
- struct snd_usX2Y_substream * volatile prepare_subs;
- wait_queue_head_t prepare_wait_queue;
- struct list_head midi_list;
- struct list_head pcm_list;
- int pcm_devs;
-};
-
-
-struct snd_usX2Y_substream {
- struct usX2Ydev *usX2Y;
- struct snd_pcm_substream *pcm_substream;
-
- int endpoint;
- unsigned int maxpacksize; /* max packet size in bytes */
-
- atomic_t state;
-#define state_STOPPED 0
-#define state_STARTING1 1
-#define state_STARTING2 2
-#define state_STARTING3 3
-#define state_PREPARED 4
-#define state_PRERUNNING 6
-#define state_RUNNING 8
-
- int hwptr; /* free frame position in the buffer (only for playback) */
- int hwptr_done; /* processed frame position in the buffer */
- int transfer_done; /* processed frames since last period update */
-
- struct urb *urb[NRURBS]; /* data urb table */
- struct urb *completed_urb;
- char *tmpbuf; /* temporary buffer for playback */
-};
-
-
-#define usX2Y(c) ((struct usX2Ydev *)(c)->private_data)
-
-int usX2Y_audio_create(struct snd_card *card);
-
-int usX2Y_AsyncSeq04_init(struct usX2Ydev *usX2Y);
-int usX2Y_In04_init(struct usX2Ydev *usX2Y);
-
-#define NAME_ALLCAPS "US-X2Y"
-
-#endif
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usbusx2yaudio.c b/ANDROID_3.4.5/sound/usb/usx2y/usbusx2yaudio.c
deleted file mode 100644
index 520ef96d..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usbusx2yaudio.c
+++ /dev/null
@@ -1,1028 +0,0 @@
-/*
- * US-X2Y AUDIO
- * Copyright (c) 2002-2004 by Karsten Wiese
- *
- * based on
- *
- * (Tentative) USB Audio Driver for ALSA
- *
- * Main and PCM part
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * Many codes borrowed from audio.c by
- * Alan Cox (alan@lxorguk.ukuu.org.uk)
- * Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/moduleparam.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include "usx2y.h"
-#include "usbusx2y.h"
-
-#define USX2Y_NRPACKS 4 /* Default value used for nr of packs per urb.
- 1 to 4 have been tested ok on uhci.
- To use 3 on ohci, you'd need a patch:
- look for "0000425-linux-2.6.9-rc4-mm1_ohci-hcd.patch.gz" on
- "https://bugtrack.alsa-project.org/alsa-bug/bug_view_page.php?bug_id=0000425"
- .
- 1, 2 and 4 work out of the box on ohci, if I recall correctly.
- Bigger is safer operation,
- smaller gives lower latencies.
- */
-#define USX2Y_NRPACKS_VARIABLE y /* If your system works ok with this module's parameter
- nrpacks set to 1, you might as well comment
- this #define out, and thereby produce smaller, faster code.
- You'd also set USX2Y_NRPACKS to 1 then.
- */
-
-#ifdef USX2Y_NRPACKS_VARIABLE
- static int nrpacks = USX2Y_NRPACKS; /* number of packets per urb */
- #define nr_of_packs() nrpacks
- module_param(nrpacks, int, 0444);
- MODULE_PARM_DESC(nrpacks, "Number of packets per URB.");
-#else
- #define nr_of_packs() USX2Y_NRPACKS
-#endif
-
-
-static int usX2Y_urb_capt_retire(struct snd_usX2Y_substream *subs)
-{
- struct urb *urb = subs->completed_urb;
- struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
- unsigned char *cp;
- int i, len, lens = 0, hwptr_done = subs->hwptr_done;
- struct usX2Ydev *usX2Y = subs->usX2Y;
-
- for (i = 0; i < nr_of_packs(); i++) {
- cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
- if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
- snd_printk(KERN_ERR "active frame status %i. "
- "Most probably some hardware problem.\n",
- urb->iso_frame_desc[i].status);
- return urb->iso_frame_desc[i].status;
- }
- len = urb->iso_frame_desc[i].actual_length / usX2Y->stride;
- if (! len) {
- snd_printd("0 == len ERROR!\n");
- continue;
- }
-
- /* copy a data chunk */
- if ((hwptr_done + len) > runtime->buffer_size) {
- int cnt = runtime->buffer_size - hwptr_done;
- int blen = cnt * usX2Y->stride;
- memcpy(runtime->dma_area + hwptr_done * usX2Y->stride, cp, blen);
- memcpy(runtime->dma_area, cp + blen, len * usX2Y->stride - blen);
- } else {
- memcpy(runtime->dma_area + hwptr_done * usX2Y->stride, cp,
- len * usX2Y->stride);
- }
- lens += len;
- if ((hwptr_done += len) >= runtime->buffer_size)
- hwptr_done -= runtime->buffer_size;
- }
-
- subs->hwptr_done = hwptr_done;
- subs->transfer_done += lens;
- /* update the pointer, call callback if necessary */
- if (subs->transfer_done >= runtime->period_size) {
- subs->transfer_done -= runtime->period_size;
- snd_pcm_period_elapsed(subs->pcm_substream);
- }
- return 0;
-}
-/*
- * prepare urb for playback data pipe
- *
- * we copy the data directly from the pcm buffer.
- * the current position to be copied is held in hwptr field.
- * since a urb can handle only a single linear buffer, if the total
- * transferred area overflows the buffer boundary, we cannot send
- * it directly from the buffer. thus the data is once copied to
- * a temporary buffer and urb points to that.
- */
-static int usX2Y_urb_play_prepare(struct snd_usX2Y_substream *subs,
- struct urb *cap_urb,
- struct urb *urb)
-{
- int count, counts, pack;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
-
- count = 0;
- for (pack = 0; pack < nr_of_packs(); pack++) {
- /* calculate the size of a packet */
- counts = cap_urb->iso_frame_desc[pack].actual_length / usX2Y->stride;
- count += counts;
- if (counts < 43 || counts > 50) {
- snd_printk(KERN_ERR "should not be here with counts=%i\n", counts);
- return -EPIPE;
- }
- /* set up descriptor */
- urb->iso_frame_desc[pack].offset = pack ?
- urb->iso_frame_desc[pack - 1].offset +
- urb->iso_frame_desc[pack - 1].length :
- 0;
- urb->iso_frame_desc[pack].length = cap_urb->iso_frame_desc[pack].actual_length;
- }
- if (atomic_read(&subs->state) >= state_PRERUNNING)
- if (subs->hwptr + count > runtime->buffer_size) {
- /* err, the transferred area goes over buffer boundary.
- * copy the data to the temp buffer.
- */
- int len;
- len = runtime->buffer_size - subs->hwptr;
- urb->transfer_buffer = subs->tmpbuf;
- memcpy(subs->tmpbuf, runtime->dma_area +
- subs->hwptr * usX2Y->stride, len * usX2Y->stride);
- memcpy(subs->tmpbuf + len * usX2Y->stride,
- runtime->dma_area, (count - len) * usX2Y->stride);
- subs->hwptr += count;
- subs->hwptr -= runtime->buffer_size;
- } else {
- /* set the buffer pointer */
- urb->transfer_buffer = runtime->dma_area + subs->hwptr * usX2Y->stride;
- if ((subs->hwptr += count) >= runtime->buffer_size)
- subs->hwptr -= runtime->buffer_size;
- }
- else
- urb->transfer_buffer = subs->tmpbuf;
- urb->transfer_buffer_length = count * usX2Y->stride;
- return 0;
-}
-
-/*
- * process after playback data complete
- *
- * update the current position and call callback if a period is processed.
- */
-static void usX2Y_urb_play_retire(struct snd_usX2Y_substream *subs, struct urb *urb)
-{
- struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
- int len = urb->actual_length / subs->usX2Y->stride;
-
- subs->transfer_done += len;
- subs->hwptr_done += len;
- if (subs->hwptr_done >= runtime->buffer_size)
- subs->hwptr_done -= runtime->buffer_size;
- if (subs->transfer_done >= runtime->period_size) {
- subs->transfer_done -= runtime->period_size;
- snd_pcm_period_elapsed(subs->pcm_substream);
- }
-}
-
-static int usX2Y_urb_submit(struct snd_usX2Y_substream *subs, struct urb *urb, int frame)
-{
- int err;
- if (!urb)
- return -ENODEV;
- urb->start_frame = (frame + NRURBS * nr_of_packs()); // let hcd do rollover sanity checks
- urb->hcpriv = NULL;
- urb->dev = subs->usX2Y->dev; /* we need to set this at each time */
- if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
- snd_printk(KERN_ERR "usb_submit_urb() returned %i\n", err);
- return err;
- }
- return 0;
-}
-
-static inline int usX2Y_usbframe_complete(struct snd_usX2Y_substream *capsubs,
- struct snd_usX2Y_substream *playbacksubs,
- int frame)
-{
- int err, state;
- struct urb *urb = playbacksubs->completed_urb;
-
- state = atomic_read(&playbacksubs->state);
- if (NULL != urb) {
- if (state == state_RUNNING)
- usX2Y_urb_play_retire(playbacksubs, urb);
- else if (state >= state_PRERUNNING)
- atomic_inc(&playbacksubs->state);
- } else {
- switch (state) {
- case state_STARTING1:
- urb = playbacksubs->urb[0];
- atomic_inc(&playbacksubs->state);
- break;
- case state_STARTING2:
- urb = playbacksubs->urb[1];
- atomic_inc(&playbacksubs->state);
- break;
- }
- }
- if (urb) {
- if ((err = usX2Y_urb_play_prepare(playbacksubs, capsubs->completed_urb, urb)) ||
- (err = usX2Y_urb_submit(playbacksubs, urb, frame))) {
- return err;
- }
- }
-
- playbacksubs->completed_urb = NULL;
-
- state = atomic_read(&capsubs->state);
- if (state >= state_PREPARED) {
- if (state == state_RUNNING) {
- if ((err = usX2Y_urb_capt_retire(capsubs)))
- return err;
- } else if (state >= state_PRERUNNING)
- atomic_inc(&capsubs->state);
- if ((err = usX2Y_urb_submit(capsubs, capsubs->completed_urb, frame)))
- return err;
- }
- capsubs->completed_urb = NULL;
- return 0;
-}
-
-
-static void usX2Y_clients_stop(struct usX2Ydev *usX2Y)
-{
- int s, u;
-
- for (s = 0; s < 4; s++) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[s];
- if (subs) {
- snd_printdd("%i %p state=%i\n", s, subs, atomic_read(&subs->state));
- atomic_set(&subs->state, state_STOPPED);
- }
- }
- for (s = 0; s < 4; s++) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[s];
- if (subs) {
- if (atomic_read(&subs->state) >= state_PRERUNNING) {
- snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
- }
- for (u = 0; u < NRURBS; u++) {
- struct urb *urb = subs->urb[u];
- if (NULL != urb)
- snd_printdd("%i status=%i start_frame=%i\n",
- u, urb->status, urb->start_frame);
- }
- }
- }
- usX2Y->prepare_subs = NULL;
- wake_up(&usX2Y->prepare_wait_queue);
-}
-
-static void usX2Y_error_urb_status(struct usX2Ydev *usX2Y,
- struct snd_usX2Y_substream *subs, struct urb *urb)
-{
- snd_printk(KERN_ERR "ep=%i stalled with status=%i\n", subs->endpoint, urb->status);
- urb->status = 0;
- usX2Y_clients_stop(usX2Y);
-}
-
-static void usX2Y_error_sequence(struct usX2Ydev *usX2Y,
- struct snd_usX2Y_substream *subs, struct urb *urb)
-{
- snd_printk(KERN_ERR
-"Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
-"Most probably some urb of usb-frame %i is still missing.\n"
-"Cause could be too long delays in usb-hcd interrupt handling.\n",
- usb_get_current_frame_number(usX2Y->dev),
- subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
- usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame);
- usX2Y_clients_stop(usX2Y);
-}
-
-static void i_usX2Y_urb_complete(struct urb *urb)
-{
- struct snd_usX2Y_substream *subs = urb->context;
- struct usX2Ydev *usX2Y = subs->usX2Y;
-
- if (unlikely(atomic_read(&subs->state) < state_PREPARED)) {
- snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n",
- usb_get_current_frame_number(usX2Y->dev),
- subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
- urb->status, urb->start_frame);
- return;
- }
- if (unlikely(urb->status)) {
- usX2Y_error_urb_status(usX2Y, subs, urb);
- return;
- }
- if (likely((urb->start_frame & 0xFFFF) == (usX2Y->wait_iso_frame & 0xFFFF)))
- subs->completed_urb = urb;
- else {
- usX2Y_error_sequence(usX2Y, subs, urb);
- return;
- }
- {
- struct snd_usX2Y_substream *capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE],
- *playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
- if (capsubs->completed_urb &&
- atomic_read(&capsubs->state) >= state_PREPARED &&
- (playbacksubs->completed_urb ||
- atomic_read(&playbacksubs->state) < state_PREPARED)) {
- if (!usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame))
- usX2Y->wait_iso_frame += nr_of_packs();
- else {
- snd_printdd("\n");
- usX2Y_clients_stop(usX2Y);
- }
- }
- }
-}
-
-static void usX2Y_urbs_set_complete(struct usX2Ydev * usX2Y,
- void (*complete)(struct urb *))
-{
- int s, u;
- for (s = 0; s < 4; s++) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[s];
- if (NULL != subs)
- for (u = 0; u < NRURBS; u++) {
- struct urb * urb = subs->urb[u];
- if (NULL != urb)
- urb->complete = complete;
- }
- }
-}
-
-static void usX2Y_subs_startup_finish(struct usX2Ydev * usX2Y)
-{
- usX2Y_urbs_set_complete(usX2Y, i_usX2Y_urb_complete);
- usX2Y->prepare_subs = NULL;
-}
-
-static void i_usX2Y_subs_startup(struct urb *urb)
-{
- struct snd_usX2Y_substream *subs = urb->context;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- struct snd_usX2Y_substream *prepare_subs = usX2Y->prepare_subs;
- if (NULL != prepare_subs)
- if (urb->start_frame == prepare_subs->urb[0]->start_frame) {
- usX2Y_subs_startup_finish(usX2Y);
- atomic_inc(&prepare_subs->state);
- wake_up(&usX2Y->prepare_wait_queue);
- }
-
- i_usX2Y_urb_complete(urb);
-}
-
-static void usX2Y_subs_prepare(struct snd_usX2Y_substream *subs)
-{
- snd_printdd("usX2Y_substream_prepare(%p) ep=%i urb0=%p urb1=%p\n",
- subs, subs->endpoint, subs->urb[0], subs->urb[1]);
- /* reset the pointer */
- subs->hwptr = 0;
- subs->hwptr_done = 0;
- subs->transfer_done = 0;
-}
-
-
-static void usX2Y_urb_release(struct urb **urb, int free_tb)
-{
- if (*urb) {
- usb_kill_urb(*urb);
- if (free_tb)
- kfree((*urb)->transfer_buffer);
- usb_free_urb(*urb);
- *urb = NULL;
- }
-}
-/*
- * release a substreams urbs
- */
-static void usX2Y_urbs_release(struct snd_usX2Y_substream *subs)
-{
- int i;
- snd_printdd("usX2Y_urbs_release() %i\n", subs->endpoint);
- for (i = 0; i < NRURBS; i++)
- usX2Y_urb_release(subs->urb + i,
- subs != subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]);
-
- kfree(subs->tmpbuf);
- subs->tmpbuf = NULL;
-}
-/*
- * initialize a substream's urbs
- */
-static int usX2Y_urbs_allocate(struct snd_usX2Y_substream *subs)
-{
- int i;
- unsigned int pipe;
- int is_playback = subs == subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
- struct usb_device *dev = subs->usX2Y->dev;
-
- pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) :
- usb_rcvisocpipe(dev, subs->endpoint);
- subs->maxpacksize = usb_maxpacket(dev, pipe, is_playback);
- if (!subs->maxpacksize)
- return -EINVAL;
-
- if (is_playback && NULL == subs->tmpbuf) { /* allocate a temporary buffer for playback */
- subs->tmpbuf = kcalloc(nr_of_packs(), subs->maxpacksize, GFP_KERNEL);
- if (NULL == subs->tmpbuf) {
- snd_printk(KERN_ERR "cannot malloc tmpbuf\n");
- return -ENOMEM;
- }
- }
- /* allocate and initialize data urbs */
- for (i = 0; i < NRURBS; i++) {
- struct urb **purb = subs->urb + i;
- if (*purb) {
- usb_kill_urb(*purb);
- continue;
- }
- *purb = usb_alloc_urb(nr_of_packs(), GFP_KERNEL);
- if (NULL == *purb) {
- usX2Y_urbs_release(subs);
- return -ENOMEM;
- }
- if (!is_playback && !(*purb)->transfer_buffer) {
- /* allocate a capture buffer per urb */
- (*purb)->transfer_buffer = kmalloc(subs->maxpacksize * nr_of_packs(), GFP_KERNEL);
- if (NULL == (*purb)->transfer_buffer) {
- usX2Y_urbs_release(subs);
- return -ENOMEM;
- }
- }
- (*purb)->dev = dev;
- (*purb)->pipe = pipe;
- (*purb)->number_of_packets = nr_of_packs();
- (*purb)->context = subs;
- (*purb)->interval = 1;
- (*purb)->complete = i_usX2Y_subs_startup;
- }
- return 0;
-}
-
-static void usX2Y_subs_startup(struct snd_usX2Y_substream *subs)
-{
- struct usX2Ydev *usX2Y = subs->usX2Y;
- usX2Y->prepare_subs = subs;
- subs->urb[0]->start_frame = -1;
- wmb();
- usX2Y_urbs_set_complete(usX2Y, i_usX2Y_subs_startup);
-}
-
-static int usX2Y_urbs_start(struct snd_usX2Y_substream *subs)
-{
- int i, err;
- struct usX2Ydev *usX2Y = subs->usX2Y;
-
- if ((err = usX2Y_urbs_allocate(subs)) < 0)
- return err;
- subs->completed_urb = NULL;
- for (i = 0; i < 4; i++) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[i];
- if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED)
- goto start;
- }
-
- start:
- usX2Y_subs_startup(subs);
- for (i = 0; i < NRURBS; i++) {
- struct urb *urb = subs->urb[i];
- if (usb_pipein(urb->pipe)) {
- unsigned long pack;
- if (0 == i)
- atomic_set(&subs->state, state_STARTING3);
- urb->dev = usX2Y->dev;
- urb->transfer_flags = URB_ISO_ASAP;
- for (pack = 0; pack < nr_of_packs(); pack++) {
- urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack;
- urb->iso_frame_desc[pack].length = subs->maxpacksize;
- }
- urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs();
- if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
- snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err);
- err = -EPIPE;
- goto cleanup;
- } else
- if (i == 0)
- usX2Y->wait_iso_frame = urb->start_frame;
- urb->transfer_flags = 0;
- } else {
- atomic_set(&subs->state, state_STARTING1);
- break;
- }
- }
- err = 0;
- wait_event(usX2Y->prepare_wait_queue, NULL == usX2Y->prepare_subs);
- if (atomic_read(&subs->state) != state_PREPARED)
- err = -EPIPE;
-
- cleanup:
- if (err) {
- usX2Y_subs_startup_finish(usX2Y);
- usX2Y_clients_stop(usX2Y); // something is completely wroong > stop evrything
- }
- return err;
-}
-
-/*
- * return the current pcm pointer. just return the hwptr_done value.
- */
-static snd_pcm_uframes_t snd_usX2Y_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_usX2Y_substream *subs = substream->runtime->private_data;
- return subs->hwptr_done;
-}
-/*
- * start/stop substream
- */
-static int snd_usX2Y_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_usX2Y_substream *subs = substream->runtime->private_data;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- snd_printdd("snd_usX2Y_pcm_trigger(START)\n");
- if (atomic_read(&subs->state) == state_PREPARED &&
- atomic_read(&subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE]->state) >= state_PREPARED) {
- atomic_set(&subs->state, state_PRERUNNING);
- } else {
- snd_printdd("\n");
- return -EPIPE;
- }
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- snd_printdd("snd_usX2Y_pcm_trigger(STOP)\n");
- if (atomic_read(&subs->state) >= state_PRERUNNING)
- atomic_set(&subs->state, state_PREPARED);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-
-/*
- * allocate a buffer, setup samplerate
- *
- * so far we use a physically linear buffer although packetize transfer
- * doesn't need a continuous area.
- * if sg buffer is supported on the later version of alsa, we'll follow
- * that.
- */
-static struct s_c2
-{
- char c1, c2;
-}
- SetRate44100[] =
-{
- { 0x14, 0x08}, // this line sets 44100, well actually a little less
- { 0x18, 0x40}, // only tascam / frontier design knows the further lines .......
- { 0x18, 0x42},
- { 0x18, 0x45},
- { 0x18, 0x46},
- { 0x18, 0x48},
- { 0x18, 0x4A},
- { 0x18, 0x4C},
- { 0x18, 0x4E},
- { 0x18, 0x50},
- { 0x18, 0x52},
- { 0x18, 0x54},
- { 0x18, 0x56},
- { 0x18, 0x58},
- { 0x18, 0x5A},
- { 0x18, 0x5C},
- { 0x18, 0x5E},
- { 0x18, 0x60},
- { 0x18, 0x62},
- { 0x18, 0x64},
- { 0x18, 0x66},
- { 0x18, 0x68},
- { 0x18, 0x6A},
- { 0x18, 0x6C},
- { 0x18, 0x6E},
- { 0x18, 0x70},
- { 0x18, 0x72},
- { 0x18, 0x74},
- { 0x18, 0x76},
- { 0x18, 0x78},
- { 0x18, 0x7A},
- { 0x18, 0x7C},
- { 0x18, 0x7E}
-};
-static struct s_c2 SetRate48000[] =
-{
- { 0x14, 0x09}, // this line sets 48000, well actually a little less
- { 0x18, 0x40}, // only tascam / frontier design knows the further lines .......
- { 0x18, 0x42},
- { 0x18, 0x45},
- { 0x18, 0x46},
- { 0x18, 0x48},
- { 0x18, 0x4A},
- { 0x18, 0x4C},
- { 0x18, 0x4E},
- { 0x18, 0x50},
- { 0x18, 0x52},
- { 0x18, 0x54},
- { 0x18, 0x56},
- { 0x18, 0x58},
- { 0x18, 0x5A},
- { 0x18, 0x5C},
- { 0x18, 0x5E},
- { 0x18, 0x60},
- { 0x18, 0x62},
- { 0x18, 0x64},
- { 0x18, 0x66},
- { 0x18, 0x68},
- { 0x18, 0x6A},
- { 0x18, 0x6C},
- { 0x18, 0x6E},
- { 0x18, 0x70},
- { 0x18, 0x73},
- { 0x18, 0x74},
- { 0x18, 0x76},
- { 0x18, 0x78},
- { 0x18, 0x7A},
- { 0x18, 0x7C},
- { 0x18, 0x7E}
-};
-#define NOOF_SETRATE_URBS ARRAY_SIZE(SetRate48000)
-
-static void i_usX2Y_04Int(struct urb *urb)
-{
- struct usX2Ydev *usX2Y = urb->context;
-
- if (urb->status)
- snd_printk(KERN_ERR "snd_usX2Y_04Int() urb->status=%i\n", urb->status);
- if (0 == --usX2Y->US04->len)
- wake_up(&usX2Y->In04WaitQueue);
-}
-
-static int usX2Y_rate_set(struct usX2Ydev *usX2Y, int rate)
-{
- int err = 0, i;
- struct snd_usX2Y_urbSeq *us = NULL;
- int *usbdata = NULL;
- struct s_c2 *ra = rate == 48000 ? SetRate48000 : SetRate44100;
-
- if (usX2Y->rate != rate) {
- us = kzalloc(sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS, GFP_KERNEL);
- if (NULL == us) {
- err = -ENOMEM;
- goto cleanup;
- }
- usbdata = kmalloc(sizeof(int) * NOOF_SETRATE_URBS, GFP_KERNEL);
- if (NULL == usbdata) {
- err = -ENOMEM;
- goto cleanup;
- }
- for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
- if (NULL == (us->urb[i] = usb_alloc_urb(0, GFP_KERNEL))) {
- err = -ENOMEM;
- goto cleanup;
- }
- ((char*)(usbdata + i))[0] = ra[i].c1;
- ((char*)(usbdata + i))[1] = ra[i].c2;
- usb_fill_bulk_urb(us->urb[i], usX2Y->dev, usb_sndbulkpipe(usX2Y->dev, 4),
- usbdata + i, 2, i_usX2Y_04Int, usX2Y);
-#ifdef OLD_USB
- us->urb[i]->transfer_flags = USB_QUEUE_BULK;
-#endif
- }
- us->submitted = 0;
- us->len = NOOF_SETRATE_URBS;
- usX2Y->US04 = us;
- wait_event_timeout(usX2Y->In04WaitQueue, 0 == us->len, HZ);
- usX2Y->US04 = NULL;
- if (us->len)
- err = -ENODEV;
- cleanup:
- if (us) {
- us->submitted = 2*NOOF_SETRATE_URBS;
- for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
- struct urb *urb = us->urb[i];
- if (urb->status) {
- if (!err)
- err = -ENODEV;
- usb_kill_urb(urb);
- }
- usb_free_urb(urb);
- }
- usX2Y->US04 = NULL;
- kfree(usbdata);
- kfree(us);
- if (!err)
- usX2Y->rate = rate;
- }
- }
-
- return err;
-}
-
-
-static int usX2Y_format_set(struct usX2Ydev *usX2Y, snd_pcm_format_t format)
-{
- int alternate, err;
- struct list_head* p;
- if (format == SNDRV_PCM_FORMAT_S24_3LE) {
- alternate = 2;
- usX2Y->stride = 6;
- } else {
- alternate = 1;
- usX2Y->stride = 4;
- }
- list_for_each(p, &usX2Y->midi_list) {
- snd_usbmidi_input_stop(p);
- }
- usb_kill_urb(usX2Y->In04urb);
- if ((err = usb_set_interface(usX2Y->dev, 0, alternate))) {
- snd_printk(KERN_ERR "usb_set_interface error \n");
- return err;
- }
- usX2Y->In04urb->dev = usX2Y->dev;
- err = usb_submit_urb(usX2Y->In04urb, GFP_KERNEL);
- list_for_each(p, &usX2Y->midi_list) {
- snd_usbmidi_input_start(p);
- }
- usX2Y->format = format;
- usX2Y->rate = 0;
- return err;
-}
-
-
-static int snd_usX2Y_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- int err = 0;
- unsigned int rate = params_rate(hw_params);
- snd_pcm_format_t format = params_format(hw_params);
- struct snd_card *card = substream->pstr->pcm->card;
- struct list_head *list;
-
- snd_printdd("snd_usX2Y_hw_params(%p, %p)\n", substream, hw_params);
- // all pcm substreams off one usX2Y have to operate at the same rate & format
- list_for_each(list, &card->devices) {
- struct snd_device *dev;
- struct snd_pcm *pcm;
- int s;
- dev = snd_device(list);
- if (dev->type != SNDRV_DEV_PCM)
- continue;
- pcm = dev->device_data;
- for (s = 0; s < 2; ++s) {
- struct snd_pcm_substream *test_substream;
- test_substream = pcm->streams[s].substream;
- if (test_substream && test_substream != substream &&
- test_substream->runtime &&
- ((test_substream->runtime->format &&
- test_substream->runtime->format != format) ||
- (test_substream->runtime->rate &&
- test_substream->runtime->rate != rate)))
- return -EINVAL;
- }
- }
- if (0 > (err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)))) {
- snd_printk(KERN_ERR "snd_pcm_lib_malloc_pages(%p, %i) returned %i\n",
- substream, params_buffer_bytes(hw_params), err);
- return err;
- }
- return 0;
-}
-
-/*
- * free the buffer
- */
-static int snd_usX2Y_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usX2Y_substream *subs = runtime->private_data;
- mutex_lock(&subs->usX2Y->prepare_mutex);
- snd_printdd("snd_usX2Y_hw_free(%p)\n", substream);
-
- if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
- struct snd_usX2Y_substream *cap_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
- atomic_set(&subs->state, state_STOPPED);
- usX2Y_urbs_release(subs);
- if (!cap_subs->pcm_substream ||
- !cap_subs->pcm_substream->runtime ||
- !cap_subs->pcm_substream->runtime->status ||
- cap_subs->pcm_substream->runtime->status->state < SNDRV_PCM_STATE_PREPARED) {
- atomic_set(&cap_subs->state, state_STOPPED);
- usX2Y_urbs_release(cap_subs);
- }
- } else {
- struct snd_usX2Y_substream *playback_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
- if (atomic_read(&playback_subs->state) < state_PREPARED) {
- atomic_set(&subs->state, state_STOPPED);
- usX2Y_urbs_release(subs);
- }
- }
- mutex_unlock(&subs->usX2Y->prepare_mutex);
- return snd_pcm_lib_free_pages(substream);
-}
-/*
- * prepare callback
- *
- * set format and initialize urbs
- */
-static int snd_usX2Y_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usX2Y_substream *subs = runtime->private_data;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- struct snd_usX2Y_substream *capsubs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
- int err = 0;
- snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream);
-
- mutex_lock(&usX2Y->prepare_mutex);
- usX2Y_subs_prepare(subs);
-// Start hardware streams
-// SyncStream first....
- if (atomic_read(&capsubs->state) < state_PREPARED) {
- if (usX2Y->format != runtime->format)
- if ((err = usX2Y_format_set(usX2Y, runtime->format)) < 0)
- goto up_prepare_mutex;
- if (usX2Y->rate != runtime->rate)
- if ((err = usX2Y_rate_set(usX2Y, runtime->rate)) < 0)
- goto up_prepare_mutex;
- snd_printdd("starting capture pipe for %s\n", subs == capsubs ? "self" : "playpipe");
- if (0 > (err = usX2Y_urbs_start(capsubs)))
- goto up_prepare_mutex;
- }
-
- if (subs != capsubs && atomic_read(&subs->state) < state_PREPARED)
- err = usX2Y_urbs_start(subs);
-
- up_prepare_mutex:
- mutex_unlock(&usX2Y->prepare_mutex);
- return err;
-}
-
-static struct snd_pcm_hardware snd_usX2Y_2c =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BATCH),
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE,
- .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
- .rate_min = 44100,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (2*128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 2,
- .periods_max = 1024,
- .fifo_size = 0
-};
-
-
-
-static int snd_usX2Y_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_usX2Y_substream *subs = ((struct snd_usX2Y_substream **)
- snd_pcm_substream_chip(substream))[substream->stream];
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- if (subs->usX2Y->chip_status & USX2Y_STAT_CHIP_MMAP_PCM_URBS)
- return -EBUSY;
-
- runtime->hw = snd_usX2Y_2c;
- runtime->private_data = subs;
- subs->pcm_substream = substream;
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 1000, 200000);
- return 0;
-}
-
-
-
-static int snd_usX2Y_pcm_close(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usX2Y_substream *subs = runtime->private_data;
-
- subs->pcm_substream = NULL;
-
- return 0;
-}
-
-
-static struct snd_pcm_ops snd_usX2Y_pcm_ops =
-{
- .open = snd_usX2Y_pcm_open,
- .close = snd_usX2Y_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_usX2Y_pcm_hw_params,
- .hw_free = snd_usX2Y_pcm_hw_free,
- .prepare = snd_usX2Y_pcm_prepare,
- .trigger = snd_usX2Y_pcm_trigger,
- .pointer = snd_usX2Y_pcm_pointer,
-};
-
-
-/*
- * free a usb stream instance
- */
-static void usX2Y_audio_stream_free(struct snd_usX2Y_substream **usX2Y_substream)
-{
- kfree(usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]);
- usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK] = NULL;
-
- kfree(usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]);
- usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE] = NULL;
-}
-
-static void snd_usX2Y_pcm_private_free(struct snd_pcm *pcm)
-{
- struct snd_usX2Y_substream **usX2Y_stream = pcm->private_data;
- if (usX2Y_stream)
- usX2Y_audio_stream_free(usX2Y_stream);
-}
-
-static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint, int capture_endpoint)
-{
- struct snd_pcm *pcm;
- int err, i;
- struct snd_usX2Y_substream **usX2Y_substream =
- usX2Y(card)->subs + 2 * usX2Y(card)->pcm_devs;
-
- for (i = playback_endpoint ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
- i <= SNDRV_PCM_STREAM_CAPTURE; ++i) {
- usX2Y_substream[i] = kzalloc(sizeof(struct snd_usX2Y_substream), GFP_KERNEL);
- if (NULL == usX2Y_substream[i]) {
- snd_printk(KERN_ERR "cannot malloc\n");
- return -ENOMEM;
- }
- usX2Y_substream[i]->usX2Y = usX2Y(card);
- }
-
- if (playback_endpoint)
- usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]->endpoint = playback_endpoint;
- usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]->endpoint = capture_endpoint;
-
- err = snd_pcm_new(card, NAME_ALLCAPS" Audio", usX2Y(card)->pcm_devs,
- playback_endpoint ? 1 : 0, 1,
- &pcm);
- if (err < 0) {
- usX2Y_audio_stream_free(usX2Y_substream);
- return err;
- }
-
- if (playback_endpoint)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_usX2Y_pcm_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_usX2Y_pcm_ops);
-
- pcm->private_data = usX2Y_substream;
- pcm->private_free = snd_usX2Y_pcm_private_free;
- pcm->info_flags = 0;
-
- sprintf(pcm->name, NAME_ALLCAPS" Audio #%d", usX2Y(card)->pcm_devs);
-
- if ((playback_endpoint &&
- 0 > (err = snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- 64*1024, 128*1024))) ||
- 0 > (err = snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- 64*1024, 128*1024))) {
- snd_usX2Y_pcm_private_free(pcm);
- return err;
- }
- usX2Y(card)->pcm_devs++;
-
- return 0;
-}
-
-/*
- * create a chip instance and set its names.
- */
-int usX2Y_audio_create(struct snd_card *card)
-{
- int err = 0;
-
- INIT_LIST_HEAD(&usX2Y(card)->pcm_list);
-
- if (0 > (err = usX2Y_audio_stream_new(card, 0xA, 0x8)))
- return err;
- if (le16_to_cpu(usX2Y(card)->dev->descriptor.idProduct) == USB_ID_US428)
- if (0 > (err = usX2Y_audio_stream_new(card, 0, 0xA)))
- return err;
- if (le16_to_cpu(usX2Y(card)->dev->descriptor.idProduct) != USB_ID_US122)
- err = usX2Y_rate_set(usX2Y(card), 44100); // Lets us428 recognize output-volume settings, disturbs us122.
- return err;
-}
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usx2y.h b/ANDROID_3.4.5/sound/usb/usx2y/usx2y.h
deleted file mode 100644
index 7e59263d..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usx2y.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Driver for Tascam US-X2Y USB soundcards
- *
- * Copyright (c) 2003 by Karsten Wiese <annabellesgarden@yahoo.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __SOUND_USX2Y_COMMON_H
-#define __SOUND_USX2Y_COMMON_H
-
-
-#define USX2Y_DRIVER_VERSION 0x0100 /* 0.1.0 */
-
-
-/* hwdep id string */
-#define SND_USX2Y_LOADER_ID "USX2Y Loader"
-#define SND_USX2Y_USBPCM_ID "USX2Y USBPCM"
-
-/* hardware type */
-enum {
- USX2Y_TYPE_122,
- USX2Y_TYPE_224,
- USX2Y_TYPE_428,
- USX2Y_TYPE_NUMS
-};
-
-#define USB_ID_US122 0x8007
-#define USB_ID_US224 0x8005
-#define USB_ID_US428 0x8001
-
-/* chip status */
-enum {
- USX2Y_STAT_CHIP_INIT = (1 << 0), /* all operational */
- USX2Y_STAT_CHIP_MMAP_PCM_URBS = (1 << 1), /* pcm transport over mmaped urbs */
- USX2Y_STAT_CHIP_HUP = (1 << 31), /* all operational */
-};
-
-#endif /* __SOUND_USX2Y_COMMON_H */
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usx2yhwdeppcm.c b/ANDROID_3.4.5/sound/usb/usx2y/usx2yhwdeppcm.c
deleted file mode 100644
index 8e40b6e6..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usx2yhwdeppcm.c
+++ /dev/null
@@ -1,794 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* USX2Y "rawusb" aka hwdep_pcm implementation
-
- Its usb's unableness to atomically handle power of 2 period sized data chuncs
- at standard samplerates,
- what led to this part of the usx2y module:
- It provides the alsa kernel half of the usx2y-alsa-jack driver pair.
- The pair uses a hardware dependent alsa-device for mmaped pcm transport.
- Advantage achieved:
- The usb_hc moves pcm data from/into memory via DMA.
- That memory is mmaped by jack's usx2y driver.
- Jack's usx2y driver is the first/last to read/write pcm data.
- Read/write is a combination of power of 2 period shaping and
- float/int conversation.
- Compared to mainline alsa/jack we leave out power of 2 period shaping inside
- snd-usb-usx2y which needs memcpy() and additional buffers.
- As a side effect possible unwanted pcm-data coruption resulting of
- standard alsa's snd-usb-usx2y period shaping scheme falls away.
- Result is sane jack operation at buffering schemes down to 128frames,
- 2 periods.
- plain usx2y alsa mode is able to achieve 64frames, 4periods, but only at the
- cost of easier triggered i.e. aeolus xruns (128 or 256frames,
- 2periods works but is useless cause of crackling).
-
- This is a first "proof of concept" implementation.
- Later, functionalities should migrate to more appropriate places:
- Userland:
- - The jackd could mmap its float-pcm buffers directly from alsa-lib.
- - alsa-lib could provide power of 2 period sized shaping combined with int/float
- conversation.
- Currently the usx2y jack driver provides above 2 services.
- Kernel:
- - rawusb dma pcm buffer transport should go to snd-usb-lib, so also snd-usb-audio
- devices can use it.
- Currently rawusb dma pcm buffer transport (this file) is only available to snd-usb-usx2y.
-*/
-
-#include <linux/delay.h>
-#include <linux/gfp.h>
-#include "usbusx2yaudio.c"
-
-#if defined(USX2Y_NRPACKS_VARIABLE) || USX2Y_NRPACKS == 1
-
-#include <sound/hwdep.h>
-
-
-static int usX2Y_usbpcm_urb_capt_retire(struct snd_usX2Y_substream *subs)
-{
- struct urb *urb = subs->completed_urb;
- struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
- int i, lens = 0, hwptr_done = subs->hwptr_done;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- if (0 > usX2Y->hwdep_pcm_shm->capture_iso_start) { //FIXME
- int head = usX2Y->hwdep_pcm_shm->captured_iso_head + 1;
- if (head >= ARRAY_SIZE(usX2Y->hwdep_pcm_shm->captured_iso))
- head = 0;
- usX2Y->hwdep_pcm_shm->capture_iso_start = head;
- snd_printdd("cap start %i\n", head);
- }
- for (i = 0; i < nr_of_packs(); i++) {
- if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
- snd_printk(KERN_ERR "active frame status %i. Most probably some hardware problem.\n", urb->iso_frame_desc[i].status);
- return urb->iso_frame_desc[i].status;
- }
- lens += urb->iso_frame_desc[i].actual_length / usX2Y->stride;
- }
- if ((hwptr_done += lens) >= runtime->buffer_size)
- hwptr_done -= runtime->buffer_size;
- subs->hwptr_done = hwptr_done;
- subs->transfer_done += lens;
- /* update the pointer, call callback if necessary */
- if (subs->transfer_done >= runtime->period_size) {
- subs->transfer_done -= runtime->period_size;
- snd_pcm_period_elapsed(subs->pcm_substream);
- }
- return 0;
-}
-
-static inline int usX2Y_iso_frames_per_buffer(struct snd_pcm_runtime *runtime,
- struct usX2Ydev * usX2Y)
-{
- return (runtime->buffer_size * 1000) / usX2Y->rate + 1; //FIXME: so far only correct period_size == 2^x ?
-}
-
-/*
- * prepare urb for playback data pipe
- *
- * we copy the data directly from the pcm buffer.
- * the current position to be copied is held in hwptr field.
- * since a urb can handle only a single linear buffer, if the total
- * transferred area overflows the buffer boundary, we cannot send
- * it directly from the buffer. thus the data is once copied to
- * a temporary buffer and urb points to that.
- */
-static int usX2Y_hwdep_urb_play_prepare(struct snd_usX2Y_substream *subs,
- struct urb *urb)
-{
- int count, counts, pack;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- struct snd_usX2Y_hwdep_pcm_shm *shm = usX2Y->hwdep_pcm_shm;
- struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
-
- if (0 > shm->playback_iso_start) {
- shm->playback_iso_start = shm->captured_iso_head -
- usX2Y_iso_frames_per_buffer(runtime, usX2Y);
- if (0 > shm->playback_iso_start)
- shm->playback_iso_start += ARRAY_SIZE(shm->captured_iso);
- shm->playback_iso_head = shm->playback_iso_start;
- }
-
- count = 0;
- for (pack = 0; pack < nr_of_packs(); pack++) {
- /* calculate the size of a packet */
- counts = shm->captured_iso[shm->playback_iso_head].length / usX2Y->stride;
- if (counts < 43 || counts > 50) {
- snd_printk(KERN_ERR "should not be here with counts=%i\n", counts);
- return -EPIPE;
- }
- /* set up descriptor */
- urb->iso_frame_desc[pack].offset = shm->captured_iso[shm->playback_iso_head].offset;
- urb->iso_frame_desc[pack].length = shm->captured_iso[shm->playback_iso_head].length;
- if (atomic_read(&subs->state) != state_RUNNING)
- memset((char *)urb->transfer_buffer + urb->iso_frame_desc[pack].offset, 0,
- urb->iso_frame_desc[pack].length);
- if (++shm->playback_iso_head >= ARRAY_SIZE(shm->captured_iso))
- shm->playback_iso_head = 0;
- count += counts;
- }
- urb->transfer_buffer_length = count * usX2Y->stride;
- return 0;
-}
-
-
-static inline void usX2Y_usbpcm_urb_capt_iso_advance(struct snd_usX2Y_substream *subs,
- struct urb *urb)
-{
- int pack;
- for (pack = 0; pack < nr_of_packs(); ++pack) {
- struct usb_iso_packet_descriptor *desc = urb->iso_frame_desc + pack;
- if (NULL != subs) {
- struct snd_usX2Y_hwdep_pcm_shm *shm = subs->usX2Y->hwdep_pcm_shm;
- int head = shm->captured_iso_head + 1;
- if (head >= ARRAY_SIZE(shm->captured_iso))
- head = 0;
- shm->captured_iso[head].frame = urb->start_frame + pack;
- shm->captured_iso[head].offset = desc->offset;
- shm->captured_iso[head].length = desc->actual_length;
- shm->captured_iso_head = head;
- shm->captured_iso_frames++;
- }
- if ((desc->offset += desc->length * NRURBS*nr_of_packs()) +
- desc->length >= SSS)
- desc->offset -= (SSS - desc->length);
- }
-}
-
-static inline int usX2Y_usbpcm_usbframe_complete(struct snd_usX2Y_substream *capsubs,
- struct snd_usX2Y_substream *capsubs2,
- struct snd_usX2Y_substream *playbacksubs,
- int frame)
-{
- int err, state;
- struct urb *urb = playbacksubs->completed_urb;
-
- state = atomic_read(&playbacksubs->state);
- if (NULL != urb) {
- if (state == state_RUNNING)
- usX2Y_urb_play_retire(playbacksubs, urb);
- else if (state >= state_PRERUNNING)
- atomic_inc(&playbacksubs->state);
- } else {
- switch (state) {
- case state_STARTING1:
- urb = playbacksubs->urb[0];
- atomic_inc(&playbacksubs->state);
- break;
- case state_STARTING2:
- urb = playbacksubs->urb[1];
- atomic_inc(&playbacksubs->state);
- break;
- }
- }
- if (urb) {
- if ((err = usX2Y_hwdep_urb_play_prepare(playbacksubs, urb)) ||
- (err = usX2Y_urb_submit(playbacksubs, urb, frame))) {
- return err;
- }
- }
-
- playbacksubs->completed_urb = NULL;
-
- state = atomic_read(&capsubs->state);
- if (state >= state_PREPARED) {
- if (state == state_RUNNING) {
- if ((err = usX2Y_usbpcm_urb_capt_retire(capsubs)))
- return err;
- } else if (state >= state_PRERUNNING)
- atomic_inc(&capsubs->state);
- usX2Y_usbpcm_urb_capt_iso_advance(capsubs, capsubs->completed_urb);
- if (NULL != capsubs2)
- usX2Y_usbpcm_urb_capt_iso_advance(NULL, capsubs2->completed_urb);
- if ((err = usX2Y_urb_submit(capsubs, capsubs->completed_urb, frame)))
- return err;
- if (NULL != capsubs2)
- if ((err = usX2Y_urb_submit(capsubs2, capsubs2->completed_urb, frame)))
- return err;
- }
- capsubs->completed_urb = NULL;
- if (NULL != capsubs2)
- capsubs2->completed_urb = NULL;
- return 0;
-}
-
-
-static void i_usX2Y_usbpcm_urb_complete(struct urb *urb)
-{
- struct snd_usX2Y_substream *subs = urb->context;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- struct snd_usX2Y_substream *capsubs, *capsubs2, *playbacksubs;
-
- if (unlikely(atomic_read(&subs->state) < state_PREPARED)) {
- snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n",
- usb_get_current_frame_number(usX2Y->dev),
- subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
- urb->status, urb->start_frame);
- return;
- }
- if (unlikely(urb->status)) {
- usX2Y_error_urb_status(usX2Y, subs, urb);
- return;
- }
- if (likely((urb->start_frame & 0xFFFF) == (usX2Y->wait_iso_frame & 0xFFFF)))
- subs->completed_urb = urb;
- else {
- usX2Y_error_sequence(usX2Y, subs, urb);
- return;
- }
-
- capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
- capsubs2 = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
- playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
- if (capsubs->completed_urb && atomic_read(&capsubs->state) >= state_PREPARED &&
- (NULL == capsubs2 || capsubs2->completed_urb) &&
- (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < state_PREPARED)) {
- if (!usX2Y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame))
- usX2Y->wait_iso_frame += nr_of_packs();
- else {
- snd_printdd("\n");
- usX2Y_clients_stop(usX2Y);
- }
- }
-}
-
-
-static void usX2Y_hwdep_urb_release(struct urb **urb)
-{
- usb_kill_urb(*urb);
- usb_free_urb(*urb);
- *urb = NULL;
-}
-
-/*
- * release a substream
- */
-static void usX2Y_usbpcm_urbs_release(struct snd_usX2Y_substream *subs)
-{
- int i;
- snd_printdd("snd_usX2Y_urbs_release() %i\n", subs->endpoint);
- for (i = 0; i < NRURBS; i++)
- usX2Y_hwdep_urb_release(subs->urb + i);
-}
-
-static void usX2Y_usbpcm_subs_startup_finish(struct usX2Ydev * usX2Y)
-{
- usX2Y_urbs_set_complete(usX2Y, i_usX2Y_usbpcm_urb_complete);
- usX2Y->prepare_subs = NULL;
-}
-
-static void i_usX2Y_usbpcm_subs_startup(struct urb *urb)
-{
- struct snd_usX2Y_substream *subs = urb->context;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- struct snd_usX2Y_substream *prepare_subs = usX2Y->prepare_subs;
- if (NULL != prepare_subs &&
- urb->start_frame == prepare_subs->urb[0]->start_frame) {
- atomic_inc(&prepare_subs->state);
- if (prepare_subs == usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE]) {
- struct snd_usX2Y_substream *cap_subs2 = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
- if (cap_subs2 != NULL)
- atomic_inc(&cap_subs2->state);
- }
- usX2Y_usbpcm_subs_startup_finish(usX2Y);
- wake_up(&usX2Y->prepare_wait_queue);
- }
-
- i_usX2Y_usbpcm_urb_complete(urb);
-}
-
-/*
- * initialize a substream's urbs
- */
-static int usX2Y_usbpcm_urbs_allocate(struct snd_usX2Y_substream *subs)
-{
- int i;
- unsigned int pipe;
- int is_playback = subs == subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
- struct usb_device *dev = subs->usX2Y->dev;
-
- pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) :
- usb_rcvisocpipe(dev, subs->endpoint);
- subs->maxpacksize = usb_maxpacket(dev, pipe, is_playback);
- if (!subs->maxpacksize)
- return -EINVAL;
-
- /* allocate and initialize data urbs */
- for (i = 0; i < NRURBS; i++) {
- struct urb **purb = subs->urb + i;
- if (*purb) {
- usb_kill_urb(*purb);
- continue;
- }
- *purb = usb_alloc_urb(nr_of_packs(), GFP_KERNEL);
- if (NULL == *purb) {
- usX2Y_usbpcm_urbs_release(subs);
- return -ENOMEM;
- }
- (*purb)->transfer_buffer = is_playback ?
- subs->usX2Y->hwdep_pcm_shm->playback : (
- subs->endpoint == 0x8 ?
- subs->usX2Y->hwdep_pcm_shm->capture0x8 :
- subs->usX2Y->hwdep_pcm_shm->capture0xA);
-
- (*purb)->dev = dev;
- (*purb)->pipe = pipe;
- (*purb)->number_of_packets = nr_of_packs();
- (*purb)->context = subs;
- (*purb)->interval = 1;
- (*purb)->complete = i_usX2Y_usbpcm_subs_startup;
- }
- return 0;
-}
-
-/*
- * free the buffer
- */
-static int snd_usX2Y_usbpcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usX2Y_substream *subs = runtime->private_data,
- *cap_subs2 = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
- mutex_lock(&subs->usX2Y->prepare_mutex);
- snd_printdd("snd_usX2Y_usbpcm_hw_free(%p)\n", substream);
-
- if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
- struct snd_usX2Y_substream *cap_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
- atomic_set(&subs->state, state_STOPPED);
- usX2Y_usbpcm_urbs_release(subs);
- if (!cap_subs->pcm_substream ||
- !cap_subs->pcm_substream->runtime ||
- !cap_subs->pcm_substream->runtime->status ||
- cap_subs->pcm_substream->runtime->status->state < SNDRV_PCM_STATE_PREPARED) {
- atomic_set(&cap_subs->state, state_STOPPED);
- if (NULL != cap_subs2)
- atomic_set(&cap_subs2->state, state_STOPPED);
- usX2Y_usbpcm_urbs_release(cap_subs);
- if (NULL != cap_subs2)
- usX2Y_usbpcm_urbs_release(cap_subs2);
- }
- } else {
- struct snd_usX2Y_substream *playback_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
- if (atomic_read(&playback_subs->state) < state_PREPARED) {
- atomic_set(&subs->state, state_STOPPED);
- if (NULL != cap_subs2)
- atomic_set(&cap_subs2->state, state_STOPPED);
- usX2Y_usbpcm_urbs_release(subs);
- if (NULL != cap_subs2)
- usX2Y_usbpcm_urbs_release(cap_subs2);
- }
- }
- mutex_unlock(&subs->usX2Y->prepare_mutex);
- return snd_pcm_lib_free_pages(substream);
-}
-
-static void usX2Y_usbpcm_subs_startup(struct snd_usX2Y_substream *subs)
-{
- struct usX2Ydev * usX2Y = subs->usX2Y;
- usX2Y->prepare_subs = subs;
- subs->urb[0]->start_frame = -1;
- smp_wmb(); // Make sure above modifications are seen by i_usX2Y_subs_startup()
- usX2Y_urbs_set_complete(usX2Y, i_usX2Y_usbpcm_subs_startup);
-}
-
-static int usX2Y_usbpcm_urbs_start(struct snd_usX2Y_substream *subs)
-{
- int p, u, err,
- stream = subs->pcm_substream->stream;
- struct usX2Ydev *usX2Y = subs->usX2Y;
-
- if (SNDRV_PCM_STREAM_CAPTURE == stream) {
- usX2Y->hwdep_pcm_shm->captured_iso_head = -1;
- usX2Y->hwdep_pcm_shm->captured_iso_frames = 0;
- }
-
- for (p = 0; 3 >= (stream + p); p += 2) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[stream + p];
- if (subs != NULL) {
- if ((err = usX2Y_usbpcm_urbs_allocate(subs)) < 0)
- return err;
- subs->completed_urb = NULL;
- }
- }
-
- for (p = 0; p < 4; p++) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[p];
- if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED)
- goto start;
- }
-
- start:
- usX2Y_usbpcm_subs_startup(subs);
- for (u = 0; u < NRURBS; u++) {
- for (p = 0; 3 >= (stream + p); p += 2) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[stream + p];
- if (subs != NULL) {
- struct urb *urb = subs->urb[u];
- if (usb_pipein(urb->pipe)) {
- unsigned long pack;
- if (0 == u)
- atomic_set(&subs->state, state_STARTING3);
- urb->dev = usX2Y->dev;
- urb->transfer_flags = URB_ISO_ASAP;
- for (pack = 0; pack < nr_of_packs(); pack++) {
- urb->iso_frame_desc[pack].offset = subs->maxpacksize * (pack + u * nr_of_packs());
- urb->iso_frame_desc[pack].length = subs->maxpacksize;
- }
- urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs();
- if ((err = usb_submit_urb(urb, GFP_KERNEL)) < 0) {
- snd_printk (KERN_ERR "cannot usb_submit_urb() for urb %d, err = %d\n", u, err);
- err = -EPIPE;
- goto cleanup;
- } else {
- snd_printdd("%i\n", urb->start_frame);
- if (u == 0)
- usX2Y->wait_iso_frame = urb->start_frame;
- }
- urb->transfer_flags = 0;
- } else {
- atomic_set(&subs->state, state_STARTING1);
- break;
- }
- }
- }
- }
- err = 0;
- wait_event(usX2Y->prepare_wait_queue, NULL == usX2Y->prepare_subs);
- if (atomic_read(&subs->state) != state_PREPARED)
- err = -EPIPE;
-
- cleanup:
- if (err) {
- usX2Y_subs_startup_finish(usX2Y); // Call it now
- usX2Y_clients_stop(usX2Y); // something is completely wroong > stop evrything
- }
- return err;
-}
-
-/*
- * prepare callback
- *
- * set format and initialize urbs
- */
-static int snd_usX2Y_usbpcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usX2Y_substream *subs = runtime->private_data;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- struct snd_usX2Y_substream *capsubs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
- int err = 0;
- snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream);
-
- if (NULL == usX2Y->hwdep_pcm_shm) {
- if (NULL == (usX2Y->hwdep_pcm_shm = snd_malloc_pages(sizeof(struct snd_usX2Y_hwdep_pcm_shm), GFP_KERNEL)))
- return -ENOMEM;
- memset(usX2Y->hwdep_pcm_shm, 0, sizeof(struct snd_usX2Y_hwdep_pcm_shm));
- }
-
- mutex_lock(&usX2Y->prepare_mutex);
- usX2Y_subs_prepare(subs);
-// Start hardware streams
-// SyncStream first....
- if (atomic_read(&capsubs->state) < state_PREPARED) {
- if (usX2Y->format != runtime->format)
- if ((err = usX2Y_format_set(usX2Y, runtime->format)) < 0)
- goto up_prepare_mutex;
- if (usX2Y->rate != runtime->rate)
- if ((err = usX2Y_rate_set(usX2Y, runtime->rate)) < 0)
- goto up_prepare_mutex;
- snd_printdd("starting capture pipe for %s\n", subs == capsubs ?
- "self" : "playpipe");
- if (0 > (err = usX2Y_usbpcm_urbs_start(capsubs)))
- goto up_prepare_mutex;
- }
-
- if (subs != capsubs) {
- usX2Y->hwdep_pcm_shm->playback_iso_start = -1;
- if (atomic_read(&subs->state) < state_PREPARED) {
- while (usX2Y_iso_frames_per_buffer(runtime, usX2Y) >
- usX2Y->hwdep_pcm_shm->captured_iso_frames) {
- snd_printdd("Wait: iso_frames_per_buffer=%i,"
- "captured_iso_frames=%i\n",
- usX2Y_iso_frames_per_buffer(runtime, usX2Y),
- usX2Y->hwdep_pcm_shm->captured_iso_frames);
- if (msleep_interruptible(10)) {
- err = -ERESTARTSYS;
- goto up_prepare_mutex;
- }
- }
- if (0 > (err = usX2Y_usbpcm_urbs_start(subs)))
- goto up_prepare_mutex;
- }
- snd_printdd("Ready: iso_frames_per_buffer=%i,captured_iso_frames=%i\n",
- usX2Y_iso_frames_per_buffer(runtime, usX2Y),
- usX2Y->hwdep_pcm_shm->captured_iso_frames);
- } else
- usX2Y->hwdep_pcm_shm->capture_iso_start = -1;
-
- up_prepare_mutex:
- mutex_unlock(&usX2Y->prepare_mutex);
- return err;
-}
-
-static struct snd_pcm_hardware snd_usX2Y_4c =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE,
- .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
- .rate_min = 44100,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 4,
- .buffer_bytes_max = (2*128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 2,
- .periods_max = 1024,
- .fifo_size = 0
-};
-
-
-
-static int snd_usX2Y_usbpcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_usX2Y_substream *subs = ((struct snd_usX2Y_substream **)
- snd_pcm_substream_chip(substream))[substream->stream];
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- if (!(subs->usX2Y->chip_status & USX2Y_STAT_CHIP_MMAP_PCM_URBS))
- return -EBUSY;
-
- runtime->hw = SNDRV_PCM_STREAM_PLAYBACK == substream->stream ? snd_usX2Y_2c :
- (subs->usX2Y->subs[3] ? snd_usX2Y_4c : snd_usX2Y_2c);
- runtime->private_data = subs;
- subs->pcm_substream = substream;
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 1000, 200000);
- return 0;
-}
-
-
-static int snd_usX2Y_usbpcm_close(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usX2Y_substream *subs = runtime->private_data;
-
- subs->pcm_substream = NULL;
- return 0;
-}
-
-
-static struct snd_pcm_ops snd_usX2Y_usbpcm_ops =
-{
- .open = snd_usX2Y_usbpcm_open,
- .close = snd_usX2Y_usbpcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_usX2Y_pcm_hw_params,
- .hw_free = snd_usX2Y_usbpcm_hw_free,
- .prepare = snd_usX2Y_usbpcm_prepare,
- .trigger = snd_usX2Y_pcm_trigger,
- .pointer = snd_usX2Y_pcm_pointer,
-};
-
-
-static int usX2Y_pcms_lock_check(struct snd_card *card)
-{
- struct list_head *list;
- struct snd_device *dev;
- struct snd_pcm *pcm;
- int err = 0;
- list_for_each(list, &card->devices) {
- dev = snd_device(list);
- if (dev->type != SNDRV_DEV_PCM)
- continue;
- pcm = dev->device_data;
- mutex_lock(&pcm->open_mutex);
- }
- list_for_each(list, &card->devices) {
- int s;
- dev = snd_device(list);
- if (dev->type != SNDRV_DEV_PCM)
- continue;
- pcm = dev->device_data;
- for (s = 0; s < 2; ++s) {
- struct snd_pcm_substream *substream;
- substream = pcm->streams[s].substream;
- if (substream && SUBSTREAM_BUSY(substream))
- err = -EBUSY;
- }
- }
- return err;
-}
-
-
-static void usX2Y_pcms_unlock(struct snd_card *card)
-{
- struct list_head *list;
- struct snd_device *dev;
- struct snd_pcm *pcm;
- list_for_each(list, &card->devices) {
- dev = snd_device(list);
- if (dev->type != SNDRV_DEV_PCM)
- continue;
- pcm = dev->device_data;
- mutex_unlock(&pcm->open_mutex);
- }
-}
-
-
-static int snd_usX2Y_hwdep_pcm_open(struct snd_hwdep *hw, struct file *file)
-{
- // we need to be the first
- struct snd_card *card = hw->card;
- int err = usX2Y_pcms_lock_check(card);
- if (0 == err)
- usX2Y(card)->chip_status |= USX2Y_STAT_CHIP_MMAP_PCM_URBS;
- usX2Y_pcms_unlock(card);
- return err;
-}
-
-
-static int snd_usX2Y_hwdep_pcm_release(struct snd_hwdep *hw, struct file *file)
-{
- struct snd_card *card = hw->card;
- int err = usX2Y_pcms_lock_check(card);
- if (0 == err)
- usX2Y(hw->card)->chip_status &= ~USX2Y_STAT_CHIP_MMAP_PCM_URBS;
- usX2Y_pcms_unlock(card);
- return err;
-}
-
-
-static void snd_usX2Y_hwdep_pcm_vm_open(struct vm_area_struct *area)
-{
-}
-
-
-static void snd_usX2Y_hwdep_pcm_vm_close(struct vm_area_struct *area)
-{
-}
-
-
-static int snd_usX2Y_hwdep_pcm_vm_fault(struct vm_area_struct *area,
- struct vm_fault *vmf)
-{
- unsigned long offset;
- void *vaddr;
-
- offset = vmf->pgoff << PAGE_SHIFT;
- vaddr = (char*)((struct usX2Ydev *)area->vm_private_data)->hwdep_pcm_shm + offset;
- vmf->page = virt_to_page(vaddr);
- get_page(vmf->page);
- return 0;
-}
-
-
-static const struct vm_operations_struct snd_usX2Y_hwdep_pcm_vm_ops = {
- .open = snd_usX2Y_hwdep_pcm_vm_open,
- .close = snd_usX2Y_hwdep_pcm_vm_close,
- .fault = snd_usX2Y_hwdep_pcm_vm_fault,
-};
-
-
-static int snd_usX2Y_hwdep_pcm_mmap(struct snd_hwdep * hw, struct file *filp, struct vm_area_struct *area)
-{
- unsigned long size = (unsigned long)(area->vm_end - area->vm_start);
- struct usX2Ydev *usX2Y = hw->private_data;
-
- if (!(usX2Y->chip_status & USX2Y_STAT_CHIP_INIT))
- return -EBUSY;
-
- /* if userspace tries to mmap beyond end of our buffer, fail */
- if (size > PAGE_ALIGN(sizeof(struct snd_usX2Y_hwdep_pcm_shm))) {
- snd_printd("%lu > %lu\n", size, (unsigned long)sizeof(struct snd_usX2Y_hwdep_pcm_shm));
- return -EINVAL;
- }
-
- if (!usX2Y->hwdep_pcm_shm) {
- return -ENODEV;
- }
- area->vm_ops = &snd_usX2Y_hwdep_pcm_vm_ops;
- area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
- area->vm_private_data = hw->private_data;
- return 0;
-}
-
-
-static void snd_usX2Y_hwdep_pcm_private_free(struct snd_hwdep *hwdep)
-{
- struct usX2Ydev *usX2Y = hwdep->private_data;
- if (NULL != usX2Y->hwdep_pcm_shm)
- snd_free_pages(usX2Y->hwdep_pcm_shm, sizeof(struct snd_usX2Y_hwdep_pcm_shm));
-}
-
-
-int usX2Y_hwdep_pcm_new(struct snd_card *card)
-{
- int err;
- struct snd_hwdep *hw;
- struct snd_pcm *pcm;
- struct usb_device *dev = usX2Y(card)->dev;
- if (1 != nr_of_packs())
- return 0;
-
- if ((err = snd_hwdep_new(card, SND_USX2Y_USBPCM_ID, 1, &hw)) < 0)
- return err;
-
- hw->iface = SNDRV_HWDEP_IFACE_USX2Y_PCM;
- hw->private_data = usX2Y(card);
- hw->private_free = snd_usX2Y_hwdep_pcm_private_free;
- hw->ops.open = snd_usX2Y_hwdep_pcm_open;
- hw->ops.release = snd_usX2Y_hwdep_pcm_release;
- hw->ops.mmap = snd_usX2Y_hwdep_pcm_mmap;
- hw->exclusive = 1;
- sprintf(hw->name, "/proc/bus/usb/%03d/%03d/hwdeppcm", dev->bus->busnum, dev->devnum);
-
- err = snd_pcm_new(card, NAME_ALLCAPS" hwdep Audio", 2, 1, 1, &pcm);
- if (err < 0) {
- return err;
- }
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_usX2Y_usbpcm_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_usX2Y_usbpcm_ops);
-
- pcm->private_data = usX2Y(card)->subs;
- pcm->info_flags = 0;
-
- sprintf(pcm->name, NAME_ALLCAPS" hwdep Audio");
- if (0 > (err = snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- 64*1024, 128*1024)) ||
- 0 > (err = snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- 64*1024, 128*1024))) {
- return err;
- }
-
-
- return 0;
-}
-
-#else
-
-int usX2Y_hwdep_pcm_new(struct snd_card *card)
-{
- return 0;
-}
-
-#endif
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usx2yhwdeppcm.h b/ANDROID_3.4.5/sound/usb/usx2y/usx2yhwdeppcm.h
deleted file mode 100644
index 9c4fb84b..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usx2yhwdeppcm.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#define MAXPACK 50
-#define MAXBUFFERMS 100
-#define MAXSTRIDE 3
-
-#define SSS (((MAXPACK*MAXBUFFERMS*MAXSTRIDE + 4096) / 4096) * 4096)
-struct snd_usX2Y_hwdep_pcm_shm {
- char playback[SSS];
- char capture0x8[SSS];
- char capture0xA[SSS];
- volatile int playback_iso_head;
- int playback_iso_start;
- struct {
- int frame,
- offset,
- length;
- } captured_iso[128];
- volatile int captured_iso_head;
- volatile unsigned captured_iso_frames;
- int capture_iso_start;
-};
-
-int usX2Y_hwdep_pcm_new(struct snd_card *card);